From f3a996bf3fe2bf4c531a98d58ba222e6752cd4ed Mon Sep 17 00:00:00 2001 From: Roniery Santos Cardoso Date: Tue, 8 Sep 2026 21:59:14 -0300 Subject: [PATCH 01/22] feat(nativedrive): novo motor NativeDrive - RESTDWMemoryTable Novo motor de memtable nativo do REST Dataware (RESTDWMemoryTable), base para o RESTDWMemtable com suporte a Delta/Data. refs r4050, r4083 --- .../Memdataset/uRESTDWABMemDBFilterExpr.pas | 632 +- .../Plugins/Memdataset/uRESTDWExprParser.pas | 1080 +- .../Memdataset/uRESTDWMemAnsiStrings.pas | 2538 ++-- .../Plugins/Memdataset/uRESTDWMemBase.pas | 392 +- .../Plugins/Memdataset/uRESTDWMemCharsets.pas | 138 +- .../Plugins/Memdataset/uRESTDWMemConsts.pas | 42 +- .../Memdataset/uRESTDWMemDBFilterExpr.pas | 478 +- .../Plugins/Memdataset/uRESTDWMemDBUtils.pas | 714 +- .../Plugins/Memdataset/uRESTDWMemDateTime.pas | 1294 +- .../Memdataset/uRESTDWMemExprParser.pas | 1070 +- .../Plugins/Memdataset/uRESTDWMemMath.pas | 468 +- .../Memdataset/uRESTDWMemResources.pas | 34 +- .../Plugins/Memdataset/uRESTDWMemStreams.pas | 2482 ++-- .../uRESTDWMemStringConversions.pas | 1434 +- .../Plugins/Memdataset/uRESTDWMemStrings.pas | 1918 +-- .../Plugins/Memdataset/uRESTDWMemStringsB.pas | 5228 +++---- .../Memdataset/uRESTDWMemTranslateString.pas | 176 +- .../Plugins/Memdataset/uRESTDWMemTypes.pas | 303 +- .../Plugins/Memdataset/uRESTDWMemVCLUtils.pas | 112 +- .../Memdataset/uRESTDWMemWideStrings.pas | 1230 +- .../Memdataset/uRESTDWMemoryDataset.pas | 11756 +++++++--------- .../Memdataset/uRESTDWMemoryDatasetParser.pas | 539 + .../uRESTDWMemoryDatasetParserCore.pas | 2408 ++++ .../uRESTDWMemoryDatasetParserDefs.pas | 1098 ++ .../uRESTDWMemoryDatasetParserSupport.pas | 326 + 25 files changed, 20135 insertions(+), 17755 deletions(-) create mode 100644 CORE/Source/Plugins/Memdataset/uRESTDWMemoryDatasetParser.pas create mode 100644 CORE/Source/Plugins/Memdataset/uRESTDWMemoryDatasetParserCore.pas create mode 100644 CORE/Source/Plugins/Memdataset/uRESTDWMemoryDatasetParserDefs.pas create mode 100644 CORE/Source/Plugins/Memdataset/uRESTDWMemoryDatasetParserSupport.pas diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWABMemDBFilterExpr.pas b/CORE/Source/Plugins/Memdataset/uRESTDWABMemDBFilterExpr.pas index 8638725e7..0539b4785 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWABMemDBFilterExpr.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWABMemDBFilterExpr.pas @@ -1,15 +1,15 @@ -unit uRESTDWABMemDBFilterExpr; +Unit uRESTDWABMemDBFilterExpr; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : @@ -17,32 +17,32 @@ Alberto Brito - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. Roniery - Devel. } -interface -uses +Interface +Uses SysUtils, Classes, Variants, DB{$IFNDEF FPC}, DBCommon, SqlTimSt, Masks {$ENDIF}, FmtBcd; -type - TRDWABExprParser = class(TExprParser) - private +Type + TRDWABExprParser = Class(TExprParser) + Private FDataset:TDataSet; - public - constructor Create(DataSet: TDataSet; const Text: string; + Public + Constructor Create(DataSet: TDataSet; Const Text: string; Options: TFilterOptions); - function Evaluate:boolean; - end; + Function Evaluate:boolean; + End; -implementation +Implementation -const +Const // Field mappings needed for filtering. (What field type should be compared with what internal type). FldTypeMap: TFieldMap = ( ord(DB.ftUnknown) // ftUnknown @@ -133,41 +133,41 @@ implementation { TRDWABExprParser } -constructor TRDWABExprParser.Create(DataSet: TDataSet; - const Text: string; Options: TFilterOptions); -begin -inherited Create(DataSet,Text,Options,[poExtSyntax],'',nil,FldTypeMap); +Constructor TRDWABExprParser.Create(DataSet: TDataSet; + Const Text: string; Options: TFilterOptions); +Begin +Inherited Create(DataSet,Text,Options,[poExtSyntax],'',nil,FldTypeMap); FDataset:=DataSet; -end; +End; -function TRDWABExprParser.Evaluate: boolean; - function VIsNull(AVariant:Variant):Boolean; - begin +Function TRDWABExprParser.Evaluate: boolean; + Function VIsNull(AVariant:Variant):Boolean; + Begin Result:=VarIsNull(AVariant) or VarIsEmpty(AVariant); - end; -var + End; +Var iLiteralStart:Word; format:TFormatSettings; - function GetUnicodeString(pft:PByte) : Utf8String; - var + Function GetUnicodeString(pft:PByte) : Utf8String; + Var len:word; pWords:PWord; pR:Pointer; - begin + Begin pWords:=PWord(pft); len:=pWords^ div 2; inc(pWords); SetLength(Result,len); pR:=pointer(@Result[1]); //Substituir Stringindex 1 pela variavel para android e ARms compiles Move(pWords^,pR^,len * 2); - end; + End; - function ParseNode(pfdStart,pfd:PByte):variant; - var + Function ParseNode(pfdStart,pfd:PByte):variant; + Var b:WordBool; i : Integer; z:nativeint; @@ -197,13 +197,13 @@ function TRDWABExprParser.Evaluate: boolean; PartLength:word; IgnoreCase:word; S1,S2:string; - type + Type PDouble=^Double; PTimeStamp=^TTimeStamp; PComp=^Comp; PWordBool=^WordBool; PBCD=^TBCD; - begin + Begin // Get node class. {$IFNDEF FPC} @@ -221,12 +221,12 @@ function TRDWABExprParser.Evaluate: boolean; //ShowMessage(Format('Class=%d, Operator=%d',[ord(iClass),ord(iOperator)])); // Check class. - case iClass of + Case iClass Of nodeFIELD: - begin - case iOperator of + Begin + Case iOperator Of coFIELD2: - begin + Begin // FieldNo:=PWord(@pfd[0])^ - 1; {$IFNDEF FPC} {$IFDEF DELPHI2010UP} @@ -244,17 +244,17 @@ function TRDWABExprParser.Evaluate: boolean; FieldName:=string(PAnsiChar(pArg1)); {$ENDIF} Result:=FDataset.FieldByName(FieldName).Value; - end; - else + End; + Else raise exception.create('Error %s'+inttostr(ord(iOperator))); - end; - end; + End; + End; nodeCONST: - begin - case iOperator of + Begin + Case iOperator Of coCONST2: - begin + Begin {$IFNDEF FPC} {$IFDEF DELPHI2010UP} DataType:=PWord(@pfd[0])^; @@ -268,7 +268,7 @@ function TRDWABExprParser.Evaluate: boolean; inc(pArg1,DataOfs); // Check type. - case DataType of + Case DataType Of ord(DB.ftSmallInt): Result:=PSmallInt(pArg1)^; ord(DB.ftWord): Result:=PWord(pArg1)^; {$IFNDEF FPC} @@ -335,49 +335,49 @@ function TRDWABExprParser.Evaluate: boolean; Result:=String(AnsiString(PAnsiChar(pArg1))); {$ENDIF} ord(DB.ftDate): - begin + Begin ts.Date:=PInteger(pArg1)^; ts.Time:=0; dt:=TimeStampToDateTime(ts); Result:=dt; - end; + End; ord(DB.ftTime): - begin + Begin ts.Date:=0; ts.Time:=PInteger(pArg1)^;; dt:=TimeStampToDateTime(ts); Result:=dt; - end; + End; ord(DB.ftDateTime): - begin + Begin cdt:=PDouble(pArg1)^; ts:=MSecsToTimeStamp(cdt); dt:=TimeStampToDateTime(ts); Result:=dt; - end; + End; ord(DB.ftBoolean): Result:=PWordBool(pArg1)^; ord(DB.ftTimeStamp): Result:=VarSQLTimeStampCreate(PSQLTimeStamp(pArg1)^); ord(DB.ftBCD), ord(DB.ftFmtBCD): - begin + Begin bcd:=TBCD(PBCD(pArg1)^); BCDToCurr(bcd,Cur); Result:=Cur; - end; + End; $1007: // Midas Unicode. Result:=GetUnicodeString(PByte(pArg1)); - else + Else raise exception.Create('Tipo Campo Desconhecido, '+inttostr(DataType)); - end; - end; - end; - end; + End; + End; + End; + End; nodeUNARY: - begin + Begin pArg1:=pfdStart; {$IFNDEF FPC} {$IFDEF DELPHI2010UP} @@ -386,55 +386,55 @@ function TRDWABExprParser.Evaluate: boolean; {$ELSE} inc(pArg1,CANEXPRSIZE+PWord(@pfd[0])^); {$ENDIF} - case iOperator of + Case iOperator Of coISBLANK,coNOTBLANK: - begin + Begin Arg1:=ParseNode(pfdStart,pArg1); b:=VIsNull(Arg1); - if iOperator=coNOTBLANK then b:=not b; + If iOperator=coNOTBLANK Then b:=not b; Result:=Variant(b); - end; + End; coNOT: - begin + Begin Arg1:=ParseNode(pfdStart,pArg1); - if VIsNull(Arg1) then + If VIsNull(Arg1) Then Result:=Null - else + Else Result:=Variant(not Arg1); - end; + End; coMINUS: - begin + Begin Arg1:=ParseNode(pfdStart,pArg1); - if not VIsNull(Arg1) then + If not VIsNull(Arg1) Then Result:=-Arg1 - else + Else Result:=Null; - end; + End; coUPPER: - begin + Begin Arg1:=ParseNode(pfdStart,pArg1); - if not VIsNull(Arg1) then + If not VIsNull(Arg1) Then Result:=UpperCase(Arg1) - else + Else Result:=Null; - end; + End; coLOWER: - begin + Begin Arg1:=ParseNode(pfdStart,pArg1); - if not VIsNull(Arg1) then + If not VIsNull(Arg1) Then Result:=LowerCase(Arg1) - else + Else Result:=Null; - end; - end; - end; + End; + End; + End; nodeBINARY: - begin + Begin // Get Loper and Roper pointers to buffer. pArg1:=pfdStart; {$IFNDEF FPC} @@ -449,182 +449,182 @@ function TRDWABExprParser.Evaluate: boolean; inc(pArg2,CANEXPRSIZE+PWord(@pfd[2])^); {$ENDIF} // Check operator for what to do. - case iOperator of + Case iOperator Of coEQ: - begin + Begin Arg1:=ParseNode(pfdStart,pArg1); Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg1) or VIsNull(Arg2) then b:=false - else b:=(Arg1 = Arg2); + If VIsNull(Arg1) or VIsNull(Arg2) Then b:=false + Else b:=(Arg1 = Arg2); Result:=Variant(b); exit; - end; + End; coNE: - begin + Begin Arg1:=ParseNode(pfdStart,pArg1); Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg1) or VIsNull(Arg2) then b:=false - else b:=(Arg1 <> Arg2); + If VIsNull(Arg1) or VIsNull(Arg2) Then b:=false + Else b:=(Arg1 <> Arg2); Result:=Variant(b); exit; - end; + End; coGT: - begin + Begin Arg1:=ParseNode(pfdStart,pArg1); Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg1) or VIsNull(Arg2) then b:=false - else b:=(Arg1 > Arg2); + If VIsNull(Arg1) or VIsNull(Arg2) Then b:=false + Else b:=(Arg1 > Arg2); Result:=Variant(b); exit; - end; + End; coGE: - begin + Begin Arg1:=ParseNode(pfdStart,pArg1); Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg1) or VIsNull(Arg2) then b:=false - else b:=(Arg1 >= Arg2); + If VIsNull(Arg1) or VIsNull(Arg2) Then b:=false + Else b:=(Arg1 >= Arg2); Result:=Variant(b); exit; - end; + End; coLT: - begin + Begin Arg1:=ParseNode(pfdStart,pArg1); Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg1) or VIsNull(Arg2) then b:=false - else b:=(Arg1 < Arg2); + If VIsNull(Arg1) or VIsNull(Arg2) Then b:=false + Else b:=(Arg1 < Arg2); Result:=Variant(b); exit; - end; + End; coLE: - begin + Begin Arg1:=ParseNode(pfdStart,pArg1); Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg1) or VIsNull(Arg2) then b:=false - else b:=(Arg1 <= Arg2); + If VIsNull(Arg1) or VIsNull(Arg2) Then b:=false + Else b:=(Arg1 <= Arg2); Result:=Variant(b); exit; - end; + End; coOR: - begin + Begin Arg1:=ParseNode(pfdStart,pArg1); Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg1) or VIsNull(Arg2) then b:=false - else b:=(Arg1 or Arg2); + If VIsNull(Arg1) or VIsNull(Arg2) Then b:=false + Else b:=(Arg1 or Arg2); Result:=Variant(b); exit; - end; + End; coAND: - begin + Begin Arg1:=ParseNode(pfdStart,pArg1); Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg1) or VIsNull(Arg2) then b:=false - else b:=(Arg1 and Arg2); + If VIsNull(Arg1) or VIsNull(Arg2) Then b:=false + Else b:=(Arg1 and Arg2); Result:=Variant(b); exit; - end; + End; coADD: - begin + Begin Arg1:=ParseNode(pfdStart,pArg1); Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg1) or VIsNull(Arg2) then Result:=Null - else Result:=(Arg1 + Arg2); + If VIsNull(Arg1) or VIsNull(Arg2) Then Result:=Null + Else Result:=(Arg1 + Arg2); exit; - end; + End; coSUB: - begin + Begin Arg1:=ParseNode(pfdStart,pArg1); Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg1) or VIsNull(Arg2) then Result:=Null - else Result:=(Arg1 - Arg2); + If VIsNull(Arg1) or VIsNull(Arg2) Then Result:=Null + Else Result:=(Arg1 - Arg2); exit; - end; + End; coMUL: - begin + Begin Arg1:=ParseNode(pfdStart,pArg1); Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg1) or VIsNull(Arg2) then Result:=Null - else Result:=(Arg1 * Arg2); + If VIsNull(Arg1) or VIsNull(Arg2) Then Result:=Null + Else Result:=(Arg1 * Arg2); exit; - end; + End; coDIV: - begin + Begin Arg1:=ParseNode(pfdStart,pArg1); Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg1) or VIsNull(Arg2) then Result:=Null - else Result:=(Arg1 / Arg2); + If VIsNull(Arg1) or VIsNull(Arg2) Then Result:=Null + Else Result:=(Arg1 / Arg2); exit; - end; + End; coMOD,coREM: - begin + Begin Arg1:=ParseNode(pfdStart,pArg1); Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg1) or VIsNull(Arg2) then Result:=Null - else Result:=(Arg1 mod Arg2); + If VIsNull(Arg1) or VIsNull(Arg2) Then Result:=Null + Else Result:=(Arg1 mod Arg2); exit; - end; + End; coIN: - begin + Begin Arg1:=ParseNode(PfdStart,pArg1); Arg2:=ParseNode(PfdStart,pArg2); - if VIsNull(Arg1) or VIsNull(Arg2) then - begin + If VIsNull(Arg1) or VIsNull(Arg2) Then + Begin Result:=false; exit; - end; + End; - if VarIsArray(Arg2) then - begin + If VarIsArray(Arg2) Then + Begin b:=false; - for i:=0 to VarArrayHighBound(Arg2,1) do - begin - if VarIsEmpty(Arg2[i]) then break; + For i:=0 To VarArrayHighBound(Arg2,1) Do + Begin + If VarIsEmpty(Arg2[i]) Then break; b:=(Arg1=Arg2[i]); - if b then break; - end; - end - else + If b Then break; + End; + End + Else b:=(Arg1=Arg2); Result:=Variant(b); exit; - end; + End; coLike: - begin + Begin Arg1:=ParseNode(PfdStart,pArg1); Arg2:=ParseNode(PfdStart,pArg2); - if VIsNull(Arg1) or VIsNull(Arg2) then - begin + If VIsNull(Arg1) or VIsNull(Arg2) Then + Begin Result:=false; exit; - end; + End; pArg1:=PByte(PChar(VarToStr(ParseNode(pfdStart,pArg1)))); pArg2:=PByte(PChar(VarToStr(ParseNode(pfdStart,pArg2)))); sLike := StringReplace(string(PChar(pArg2)), '%', '*', [rfReplaceAll]); b:=MatchesMask(string(PChar(pArg1)), sLike); Result:=Variant(b); exit; - end; + End; - else - raise exception.Create('Operator não suportado '+inttostr(ord(iOperator))); - end; - end; + Else + raise exception.Create('Operator no suportado '+inttostr(ord(iOperator))); + End; + End; nodeCOMPARE: - begin + Begin {$IFNDEF FPC} {$IFDEF DELPHI2010UP} IgnoreCase:=PWord(@pfd[0])^; @@ -640,59 +640,59 @@ function TRDWABExprParser.Evaluate: boolean; {$ENDIF} Arg1:=ParseNode(pfdStart,pArg1); Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg1) or VIsNull(Arg2) then - begin + If VIsNull(Arg1) or VIsNull(Arg2) Then + Begin Result:=false; exit; - end; + End; S1:=Arg1; S2:=Arg2; - if IgnoreCase=1 then - begin + If IgnoreCase=1 Then + Begin S1:=AnsiUpperCase(S1); S2:=AnsiUpperCase(S2); - end; - if PartLength>0 then - begin + End; + If PartLength>0 Then + Begin S1:=Copy(S1,1,PartLength); S2:=Copy(S2,1,PartLength); - end; + End; - case iOperator of + Case iOperator Of coEQ: - begin + Begin b:=(S1 = S2); Result:=Variant(b); exit; - end; + End; coNE: - begin + Begin b:=(S1 <> S2); Result:=Variant(b); exit; - end; + End; coLIKE: - begin + Begin pArg1:=PByte(PChar(VarToStr(ParseNode(pfdStart,pArg1)))); pArg2:=PByte(PChar(VarToStr(ParseNode(pfdStart,pArg2)))); b:=MatchesMask(string(PChar(pArg1)),string(PChar(pArg2))); Result:=Variant(b); exit; - end; + End; - else - raise exception.Create('Operator não suportado '+inttostr(ord(iOperator))); - end; - end; + Else + raise exception.Create('Operator no suportado '+inttostr(ord(iOperator))); + End; + End; nodeFUNC: - begin - case iOperator of + Begin + Case iOperator Of coFUNC2: - begin + Begin pArg1:=pfdStart; {$IFNDEF FPC} {$IFDEF DELPHI2010UP} @@ -714,197 +714,197 @@ function TRDWABExprParser.Evaluate: boolean; {$ELSE} inc(pArg2,CANEXPRSIZE+PWord(@pfd[2])^); // Pointer to Value or Const {$ENDIF} - if sFunc='UPPER' then - begin + If sFunc='UPPER' Then + Begin Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg2) then Result:=Null - else Result:=UpperCase(VarToStr(Arg2)); - end + If VIsNull(Arg2) Then Result:=Null + Else Result:=UpperCase(VarToStr(Arg2)); + End - else if sFunc='LOWER' then - begin + Else If sFunc='LOWER' Then + Begin Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg2) then Result:=Null - else Result:=LowerCase(VarToStr(Arg2)); - end + If VIsNull(Arg2) Then Result:=Null + Else Result:=LowerCase(VarToStr(Arg2)); + End - else if sFunc='SUBSTRING' then - begin + Else If sFunc='SUBSTRING' Then + Begin Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg2) then - begin + If VIsNull(Arg2) Then + Begin Result:=Null; exit; - end; + End; Result:=Arg2; - try + Try {$IFDEF NEXTGEN} pArg1:=PByte(VarToStr(Result[0])); {$ELSE} pArg1:=PByte(AnsiString(VarToStr(Result[0]))); {$ENDIF} - except - on EVariantError do // no Params for "SubString" + Except + on EVariantError Do // no Params for "SubString" raise Exception.CreateFmt('Invalid or missing parameter for function %s',[pArg1]); - end; + End; i:=Result[1]; z:=Result[2]; - if (z=0) then - begin - if (Pos(',',Result[1])>0) then // "From" and "To" entered without space! + If (z=0) Then + Begin + If (Pos(',',Result[1])>0) Then // "From" and "To" entered without space! z:=StrToInt(Copy(Result[1],Pos(',',Result[1])+1,Length(Result[1]))) - else // No "To" entered so use all + Else // No "To" entered so use all z:=Length(PChar(pArg1)); - end; + End; Result:=Copy(PChar(pArg1),i,z); - end + End - else if sFunc='TRIM' then - begin + Else If sFunc='TRIM' Then + Begin Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg2) then Result:=Null - else Result:=Trim(VarToStr(Arg2)); - end + If VIsNull(Arg2) Then Result:=Null + Else Result:=Trim(VarToStr(Arg2)); + End - else if sFunc='TRIMLEFT' then - begin + Else If sFunc='TRIMLEFT' Then + Begin Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg2) then Result:=Null - else Result:=TrimLeft(VarToStr(Arg2)); - end + If VIsNull(Arg2) Then Result:=Null + Else Result:=TrimLeft(VarToStr(Arg2)); + End - else if sFunc='TRIMRIGHT' then - begin + Else If sFunc='TRIMRIGHT' Then + Begin Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg2) then Result:=Null - else Result:=TrimRight(VarToStr(Arg2)); - end + If VIsNull(Arg2) Then Result:=Null + Else Result:=TrimRight(VarToStr(Arg2)); + End - else if sFunc='GETDATE' then + Else If sFunc='GETDATE' Then Result:=Now - else if sFunc='YEAR' then - begin + Else If sFunc='YEAR' Then + Begin Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg2) then Result:=Null - else - begin + If VIsNull(Arg2) Then Result:=Null + Else + Begin DecodeDate(VarToDateTime(Arg2),year,mon,day); Result:=year; - end; - end + End; + End - else if sFunc='MONTH' then - begin + Else If sFunc='MONTH' Then + Begin Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg2) then Result:=Null - else - begin + If VIsNull(Arg2) Then Result:=Null + Else + Begin DecodeDate(VarToDateTime(Arg2),year,mon,day); Result:=mon; - end; - end + End; + End - else if sFunc='DAY' then - begin + Else If sFunc='DAY' Then + Begin Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg2) then Result:=Null - else - begin + If VIsNull(Arg2) Then Result:=Null + Else + Begin DecodeDate(VarToDateTime(Arg2),year,mon,day); Result:=day; - end; - end + End; + End - else if sFunc='HOUR' then - begin + Else If sFunc='HOUR' Then + Begin Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg2) then Result:=Null - else - begin + If VIsNull(Arg2) Then Result:=Null + Else + Begin DecodeTime(VarToDateTime(Arg2),hour,min,sec,msec); Result:=hour; - end; - end + End; + End - else if sFunc='MINUTE' then - begin + Else If sFunc='MINUTE' Then + Begin Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg2) then Result:=Null - else - begin + If VIsNull(Arg2) Then Result:=Null + Else + Begin DecodeTime(VarToDateTime(Arg2),hour,min,sec,msec); Result:=min; - end; - end + End; + End - else if sFunc='SECOND' then - begin + Else If sFunc='SECOND' Then + Begin Arg2:=ParseNode(pfdStart,pArg2); - if VIsNull(Arg2) then Result:=Null - else - begin + If VIsNull(Arg2) Then Result:=Null + Else + Begin DecodeTime(VarToDateTime(Arg2),hour,min,sec,msec); Result:=sec; - end; - end + End; + End - else if sFunc='DATE' then // Format DATE('datestring','formatstring') - begin // or DATE(datevalue) + Else If sFunc='DATE' Then // Format DATE('datestring','formatstring') + Begin // or DATE(datevalue) Result:=ParseNode(pfdStart,pArg2); - if VarIsArray(Result) then - begin - try + If VarIsArray(Result) Then + Begin + Try sArg1:=VarToStr(Result[0]); sArg2:=VarToStr(Result[1]); - except - on EVariantError do // no Params for DATE + Except + on EVariantError Do // no Params for DATE raise Exception.CreateFmt('Invalid or missing parameter for function %s',[sArg1]); - end; + End; format.ShortDateFormat:=sArg2; Result:=StrToDate(sArg1,format); - end - else + End + Else Result:=longint(trunc(VarToDateTime(Result))); - end + End - else if sFunc='TIME' then // Format TIME('timestring','formatstring') - begin // or TIME(datetimevalue) + Else If sFunc='TIME' Then // Format TIME('timestring','formatstring') + Begin // or TIME(datetimevalue) Result:=ParseNode(pfdStart,pArg2); - if VarIsArray(Result) then - begin - try + If VarIsArray(Result) Then + Begin + Try sArg1:=VarToStr(Result[0]); sArg2:=VarToStr(Result[1]); - except - on EVariantError do // no Params for TIME + Except + on EVariantError Do // no Params for TIME raise exception.CreateFmt('Invalid or missing parameter for function %s',[sArg1]); - end; + End; format.ShortTimeFormat:=sArg2; Result:=StrToTime(sArg1,format); - end - else + End + Else Result:=Frac(VarToDateTime(Result)); - end + End - else + Else raise Exception.CreateFmt('Invalid function name %s',[pArg1]); - end; - else - raise Exception.CreateFmt('Operador não suportado (%d).',[ord(iOperator)]); - end; - end; + End; + Else + raise Exception.CreateFmt('Operador no suportado (%d).',[ord(iOperator)]); + End; + End; nodeLISTELEM: - begin - case iOperator of + Begin + Case iOperator Of coLISTELEM2: - begin + Begin Result:=VarArrayCreate([0,50],VarVariant); // Create VarArray for ListElements Values i:=0; pArg1:=pfdStart; @@ -955,27 +955,27 @@ function TRDWABExprParser.Evaluate: boolean; Until NODEClass(PInteger(@pArg1[0])^)<>NodeListElem; {$ENDIF} // Only one or no Value so don't return as VarArray - if i<2 then - begin - if VIsNull(Result[0]) then + If i<2 Then + Begin + If VIsNull(Result[0]) Then Result:=Null - else + Else Result:=VarAsType(Result[0],varString); - end; - end; - else - raise exception.CreateFmt('Operador não suportado (%d).',[ord(iOperator)]); - end; - end; - else + End; + End; + Else + raise exception.CreateFmt('Operador no suportado (%d).',[ord(iOperator)]); + End; + End; + Else raise exception.CreateFmt('Class '+'Fora de intervalo (%d)',[ord(iClass)]); - end; - end; + End; + End; {$WARNINGS ON} -var +Var pfdStart,pfd:PByte; -begin +Begin pfdStart:=@FilterData[0]; pfd:=pfdStart; {$IFNDEF FPC} @@ -991,6 +991,6 @@ function TRDWABExprParser.Evaluate: boolean; format :=FormatSettings; Result :=WordBool(ParseNode(pfdStart,pfd)); {$ENDIF} -end; +End; -end. +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWExprParser.pas b/CORE/Source/Plugins/Memdataset/uRESTDWExprParser.pas index 556c0929d..90fffdfa0 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWExprParser.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWExprParser.pas @@ -1,6 +1,6 @@ -unit uRESTDWExprParser; +Unit uRESTDWExprParser; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . @@ -24,20 +24,20 @@ Fernando Banhos - Refactor Drivers REST Dataware. } -interface +Interface -uses +Uses SysUtils,Contnrs; -type - TOnGetVariableValue = function(Sender: TObject; const VarName: string; - var Value: Variant): Boolean of object; +Type + TOnGetVariableValue = Function(Sender: TObject; Const VarName: string; + Var Value: Variant): Boolean Of object; - TOnExecuteFunction = function(Sender: TObject; const FuncName: string; - const Args: Variant; var ResVal: Variant): Boolean of object; + TOnExecuteFunction = Function(Sender: TObject; Const FuncName: string; + Const Args: Variant; Var ResVal: Variant): Boolean Of object; - TExprParser = class - private + TExprParser = Class + Private FValue: Variant; FParser: TObject; // TParser FScan: TObject; // TScan @@ -47,16 +47,16 @@ TExprParser = class FEnableWildcardMatching: Boolean; FErrorMessage: string; FCaseInsensitive: Boolean; - procedure SetExpression(const Value: string); - function DoGetVariable(const VarName: string; var Value: Variant): Boolean; - function DoExecuteFunction(const FuncName: string; const Args: Variant; var ResVal: Variant): Boolean; - procedure SetCaseInsensitive(const Value: Boolean); - function ConvertDoubleOperators(Value : String) : String; - public - constructor Create(); - destructor Destroy; override; - function Eval: Boolean; overload; - function Eval(const AExpression: string): Boolean; overload; + Procedure SetExpression(Const Value: string); + Function DoGetVariable(Const VarName: string; Var Value: Variant): Boolean; + Function DoExecuteFunction(Const FuncName: string; Const Args: Variant; Var ResVal: Variant): Boolean; + Procedure SetCaseInsensitive(Const Value: Boolean); + Function ConvertDoubleOperators(Value : String) : String; + Public + Constructor Create(); + Destructor Destroy; override; + Function Eval: Boolean; overload; + Function Eval(Const AExpression: string): Boolean; overload; property ErrorMessage: string read FErrorMessage; {published} // ahuser: not a TPersistent derived class property Expression: string read FExpression write SetExpression; @@ -65,18 +65,18 @@ TExprParser = class property Value: Variant read FValue; property EnableWildcardMatching: Boolean read FEnableWildcardMatching write FEnableWildcardMatching; property CaseInsensitive: Boolean read FCaseInsensitive write SetCaseInsensitive; - end; + End; - EExprParserError = class(Exception); + EExprParserError = Class(Exception); {$IFDEF TESTING_PARSER} -var +Var DebugText: string; {$ENDIF TESTING_PARSER} -implementation +Implementation -uses +Uses Classes, Variants, Masks; {$IFDEF DELPHI2009UP} @@ -85,14 +85,14 @@ implementation {$WARN WIDECHAR_REDUCED OFF} {$ENDIF DELPHI2009UP} -const +Const cNumbers = ['0'..'9']; cLetters = ['a'..'z', 'A'..'Z', '_']; cLettersAndNumbers = cLetters + cNumbers; cOperators = [ '+', '-', '/', '*', - '=', '§', // >= + '=', '^', // >= '<', '@', // <= '>', '#', // <> '&', @@ -100,288 +100,288 @@ implementation '!', '~']; -type +Type TToken = (tkNA, tkEOF, tkError, tkLParen, tkRParen, tkComa, tkOperator, tkIdentifier, tkNumber, tkInteger, tkString); - TLex = class - private + TLex = Class + Private FToken: TToken; FChr: Char; FStr: string; FPos: Integer; - public - constructor Create(AToken: TToken; APos: Integer); overload; - constructor Create(AToken: TToken; const AStr: string; APos: Integer); overload; - constructor Create(AToken: TToken; AChr: Char; APos: Integer); overload; - function Debug(): string; + Public + Constructor Create(AToken: TToken; APos: Integer); overload; + Constructor Create(AToken: TToken; Const AStr: string; APos: Integer); overload; + Constructor Create(AToken: TToken; AChr: Char; APos: Integer); overload; + Function Debug(): string; property Token: TToken read FToken; property Chr: Char read FChr; property Str: string read FStr; property Pos: Integer read FPos; - end; + End; - TScan = class(TObjectList) - private + TScan = Class(TObjectList) + Private FErrorMessage: string; - function GetItem(Index: Integer): TLex; - public - constructor Create(); + Function GetItem(Index: Integer): TLex; + Public + Constructor Create(); property Items[Index: Integer]: TLex read GetItem; default; - function Parse(const Str: string): Boolean; + Function Parse(Const Str: string): Boolean; {$IFDEF TESTING_PARSER} - procedure DebugPrint(); + Procedure DebugPrint(); {$ENDIF TESTING_PARSER} property ErrorMessage: string read FErrorMessage; - end; + End; - TParser = class; - TNode = class - private + TParser = Class; + TNode = Class + Private FParser: TParser; - public - constructor Create(Parser: TParser); virtual; + Public + Constructor Create(Parser: TParser); virtual; // Delphi 5 compiler shows hints about a not exported or used symbol // TNode.Eval. This is a compiler bug that is caused by the "abstract" keyword. - function Eval(): Variant; virtual; abstract; - end; + Function Eval(): Variant; virtual; abstract; + End; - EParserError = class(EExprParserError) - public - constructor Create(const Msg: string; Lex: TLex); overload; - end; + EParserError = Class(EExprParserError) + Public + Constructor Create(Const Msg: string; Lex: TLex); overload; + End; - TNodeCValue = class(TNode) - private + TNodeCValue = Class(TNode) + Private FCValue: TLex; - public - constructor Create(AParser: TParser; ACValue: TLex); reintroduce; - function Eval(): Variant; override; - end; + Public + Constructor Create(AParser: TParser; ACValue: TLex); reintroduce; + Function Eval(): Variant; override; + End; - TNodeVariable = class(TNode) - private + TNodeVariable = Class(TNode) + Private FLex: TLex; - public - constructor Create(AParser: TParser; ALex: TLex); reintroduce; - function Eval(): Variant; override; - end; + Public + Constructor Create(AParser: TParser; ALex: TLex); reintroduce; + Function Eval(): Variant; override; + End; - TNodeUnary = class(TNode) - private + TNodeUnary = Class(TNode) + Private FOperator: TLex; FRightNode: TNode; - public - constructor Create(AParser: TParser; AOperator: TLex; ARightNode: TNode); reintroduce; - destructor Destroy; override; - function Eval(): Variant; override; - end; - - TNodeBin = class(TNode) - private + Public + Constructor Create(AParser: TParser; AOperator: TLex; ARightNode: TNode); reintroduce; + Destructor Destroy; override; + Function Eval(): Variant; override; + End; + + TNodeBin = Class(TNode) + Private FOperator: TLex; FLeftNode, FRightNode: TNode; - public - constructor Create(AParser: TParser; AOperator: TLex; ALeftNode, ARightNode: TNode); reintroduce; - destructor Destroy; override; - function Eval(): Variant; override; - end; - - TNodeFunction = class(TNode) - private + Public + Constructor Create(AParser: TParser; AOperator: TLex; ALeftNode, ARightNode: TNode); reintroduce; + Destructor Destroy; override; + Function Eval(): Variant; override; + End; + + TNodeFunction = Class(TNode) + Private FFunc: TLex; FArgs: TObjectList; - public - constructor Create(AParser: TParser; AFunc: TLex); reintroduce; - destructor Destroy; override; - procedure AddArg(Node: TNode); - function Eval(): Variant; override; - end; - - TParser = class - private + Public + Constructor Create(AParser: TParser; AFunc: TLex); reintroduce; + Destructor Destroy; override; + Procedure AddArg(Node: TNode); + Function Eval(): Variant; override; + End; + + TParser = Class + Private FParent: TExprParser; FScan: TScan; FScanIdx: Integer; FRoot: TNode; FErrorMessage: string; FValue: Variant; - public - destructor Destroy; override; - function Parse(): Boolean; - function Execute(): Boolean; - function Expr(): TNode; - function Term(): TNode; - function Factor(): TNode; - function LexC(): TLex; - function LexLook(LookAhead: Integer = 1): TLex; - procedure LexAccept(); + Public + Destructor Destroy; override; + Function Parse(): Boolean; + Function Execute(): Boolean; + Function Expr(): TNode; + Function Term(): TNode; + Function Factor(): TNode; + Function LexC(): TLex; + Function LexLook(LookAhead: Integer = 1): TLex; + Procedure LexAccept(); property Parent: TExprParser read FParent write FParent; property Value: Variant read FValue; property ErrorMessage: string read FErrorMessage; property Scan: TScan read FScan write FScan; - end; + End; -var +Var ELexEOF: TLex; // ahuser: what the... {$IFDEF TESTING_PARSER} -procedure DebugMessage(const msg: string); -begin +Procedure DebugMessage(Const msg: string); +Begin DebugText := DebugText + msg + sLineBreak; -end; +End; {$ENDIF TESTING_PARSER} { TLex } -constructor TLex.Create(AToken: TToken; APos: Integer); -begin +Constructor TLex.Create(AToken: TToken; APos: Integer); +Begin FToken := AToken; FPos := APos; -end; +End; -constructor TLex.Create(AToken: TToken; const AStr: string; APos: Integer); -begin - inherited Create; +Constructor TLex.Create(AToken: TToken; Const AStr: string; APos: Integer); +Begin + Inherited Create; FToken := AToken; FStr := AStr; FPos := APos; -end; +End; -constructor TLex.Create(AToken: TToken; AChr: Char; APos: Integer); -begin +Constructor TLex.Create(AToken: TToken; AChr: Char; APos: Integer); +Begin FToken := AToken; FChr := Char(AChr); FPos := APos; -end; +End; -function TLex.debug: string; -const - TokenStr: array[TToken] of string = +Function TLex.debug: string; +Const + TokenStr: array[TToken] Of string = ('N/A', 'End of expression', 'Error', '(', ')', ',', 'Operator', 'Identifier', 'Number', 'Integer', 'String'); -begin +Begin Result := TokenStr[Token]; - case Token of + Case Token Of tkOperator: Result := Result + ': ' + Chr; tkIdentifier, tkNumber, tkInteger, tkString: Result := Result + ': ' + Str; - end; + End; Result := Result + ' at pos: ' + IntToStr(Pos); -end; +End; { TScan } -constructor TScan.Create; -begin - inherited Create; +Constructor TScan.Create; +Begin + Inherited Create; OwnsObjects := True; FErrorMessage := ''; -end; +End; -function TScan.GetItem(Index: Integer): TLex; -begin - Result := inherited Items[Index] as TLex; -end; +Function TScan.GetItem(Index: Integer): TLex; +Begin + Result := Inherited Items[Index] as TLex; +End; -function TScan.Parse(const Str: string): Boolean; -var +Function TScan.Parse(Const Str: string): Boolean; +Var Idx, StartIdx, Len: Integer; C: Char; S: string; CToken: TToken; -begin +Begin Len := Length(Str); Idx := 1; S := ''; CToken := tkNA; - while Idx <= Len do - begin + While Idx <= Len Do + Begin C := Str[Idx]; StartIdx := Idx; Inc(Idx); CToken := tkNA; - case C of + Case C Of '(': CToken := tkLParen; ')': CToken := tkRParen; ',': CToken := tkComa; ' ', #09: ; - else - if C in cOperators then + Else + If C in cOperators Then CToken := tkOperator - else - if (C = '"') or (C = '''') then - begin + Else + If (C = '"') or (C = '''') Then + Begin CToken := tkString; - while (Idx <= Len) and (Str[Idx] <> C) do - begin + While (Idx <= Len) and (Str[Idx] <> C) Do + Begin S := S + Str[Idx]; // ahuser: performance suicide Inc(Idx); - end; - if (Idx <= Len) and (Str[Idx] = C) then + End; + If (Idx <= Len) and (Str[Idx] = C) Then Inc(Idx) - else - begin + Else + Begin CToken := tkError; FErrorMessage := 'No end of string found'; - end - end - else - if C in cNumbers then - begin + End + End + Else + If C in cNumbers Then + Begin CToken := tkInteger; S := S + C; - while (Idx <= Len) and (Str[Idx] in cNumbers) do - begin + While (Idx <= Len) and (Str[Idx] in cNumbers) Do + Begin S := S + Str[Idx]; // ahuser: performance suicide Inc(Idx); - end; - if ((Idx <= Len) and (Str[Idx] = '.')) then - begin + End; + If ((Idx <= Len) and (Str[Idx] = '.')) Then + Begin CToken := tkNumber; Inc(Idx); S := S + '.'; - while (Idx <= Len) and (Str[Idx] in cNumbers) do - begin + While (Idx <= Len) and (Str[Idx] in cNumbers) Do + Begin S := S + Str[Idx]; // ahuser: performance suicide Inc(Idx); - end; - end; - end - else - if C = '.' then // .55 - begin + End; + End; + End + Else + If C = '.' Then // .55 + Begin CToken := tkNumber; S := S + C; - while (Idx <= Len) and (Str[Idx] in cNumbers) do - begin + While (Idx <= Len) and (Str[Idx] in cNumbers) Do + Begin S := S + Str[Idx]; // ahuser: performance suicide Inc(Idx); - end; - end - else - if C in cLetters then - begin + End; + End + Else + If C in cLetters Then + Begin CToken := tkIdentifier; S := S + C; - while (Idx <= Len) and (Str[Idx] in cLettersAndNumbers) do - begin + While (Idx <= Len) and (Str[Idx] in cLettersAndNumbers) Do + Begin S := S + Str[Idx]; // ahuser: performance suicide Inc(Idx); - end; - end - else - begin + End; + End + Else + Begin CToken := tkError; FErrorMessage := Format('Bad character ''%s''', [string(C)]); - end; - end; - case CToken of + End; + End; + Case CToken Of tkError: break; tkNA: ; // continue tkOperator: Add(TLex.Create(tkOperator, C, StartIdx)); @@ -389,330 +389,330 @@ function TScan.Parse(const Str: string): Boolean; tkNumber, tkInteger, tkString: - begin - if CompareText(S, 'and') = 0 then + Begin + If CompareText(S, 'and') = 0 Then Add(TLex.Create(tkOperator, '&', StartIdx)) - else - if CompareText(S, 'or') = 0 then + Else + If CompareText(S, 'or') = 0 Then Add(TLex.Create(tkOperator, '|', StartIdx)) - else - begin - if CompareText(S, 'like')=0 then + Else + Begin + If CompareText(S, 'like')=0 Then Add(TLex.Create(tkOperator, '~', StartIdx)) - else + Else Add(TLex.Create(CToken, S, StartIdx)); - end; + End; S := ''; - end - else + End + Else Add(TLex.Create(CToken, StartIdx)); - end; - end; + End; + End; Result := CToken <> tkError; ELexEOF := TLex.Create(tkEOF, Idx); Add(ELexEOF); -end; +End; {$IFDEF TESTING_PARSER} -procedure TScan.DebugPrint; -var +Procedure TScan.DebugPrint; +Var I: Integer; -begin - for I := 0 to Count - 1 do +Begin + For I := 0 To Count - 1 Do DebugMessage(Items[I].Debug); -end; +End; {$ENDIF TESTING_PARSER} { TParser } -destructor TParser.Destroy; -begin +Destructor TParser.Destroy; +Begin FRoot.Free; - inherited Destroy; -end; + Inherited Destroy; +End; -function TParser.Parse: Boolean; -begin +Function TParser.Parse: Boolean; +Begin FreeAndNil(FRoot); - try + Try FRoot := Expr(); - if FScanIdx < FScan.Count - 1 then - begin + If FScanIdx < FScan.Count - 1 Then + Begin FreeAndNil(FRoot); raise EParserError.Create('Unexpected ', LexC()); - end; - except - on E: Exception do + End; + Except + on E: Exception Do FErrorMessage := E.Message; - end; + End; Result := FRoot <> nil; -end; +End; -function TParser.Execute: Boolean; -begin +Function TParser.Execute: Boolean; +Begin Result := False; - if FRoot <> nil then - begin - try + If FRoot <> nil Then + Begin + Try FValue := FRoot.Eval(); Result := True; - except - on E: Exception do - begin + Except + on E: Exception Do + Begin FErrorMessage := E.Message; // raise; - end; - end; - end; -end; + End; + End; + End; +End; -procedure TParser.LexAccept; -begin +Procedure TParser.LexAccept; +Begin Inc(FScanIdx); -end; +End; -function TParser.LexC: TLex; -begin +Function TParser.LexC: TLex; +Begin Result := LexLook(0); -end; +End; -function TParser.LexLook(LookAhead: Integer): TLex; -begin - if (FScanIdx + LookAhead) < FScan.Count then +Function TParser.LexLook(LookAhead: Integer): TLex; +Begin + If (FScanIdx + LookAhead) < FScan.Count Then Result := FScan[FScanIdx + LookAhead] - else + Else Result := ELexEOF; -end; +End; -function TParser.Expr: TNode; -var +Function TParser.Expr: TNode; +Var CNode, RightNode: TNode; Lex: TLex; -begin +Begin CNode := nil; - try + Try CNode := Term(); Lex := LexC(); - if Lex.Token = tkOperator then - begin - if Lex.Chr in ['+', '-'] then - begin + If Lex.Token = tkOperator Then + Begin + If Lex.Chr in ['+', '-'] Then + Begin LexAccept(); RightNode := Expr(); - if RightNode = nil then + If RightNode = nil Then raise EParserError.Create('Expression expected after', Lex); CNode := TNodeBin.Create(Self, Lex, CNode, RightNode); - end; - end; - except - on E: Exception do - begin + End; + End; + Except + on E: Exception Do + Begin FreeAndNil(CNode); - if E is EParserError then + If E is EParserError Then raise - else + Else raise EParserError.Create(E.Message); - end; - end; + End; + End; Result := CNode; -end; +End; -function TParser.Term: TNode; -var +Function TParser.Term: TNode; +Var CNode, RightNode: TNode; Lex: TLex; -begin +Begin CNode := nil; - try + Try CNode := Factor(); Lex := LexC(); - if Lex.Token = tkOperator then - begin - if Lex.Chr in ['*', '/', '=', '&', '|', '<', '>', '~', '§', '@', '#'] then - begin + If Lex.Token = tkOperator Then + Begin + If Lex.Chr in ['*', '/', '=', '&', '|', '<', '>', '~', '^', '@', '#'] Then + Begin LexAccept(); RightNode := Expr(); - if RightNode = nil then + If RightNode = nil Then raise EParserError.Create('Expression expected after', Lex); CNode := TNodeBin.Create(Self, Lex, CNode, RightNode); - end; - end; - except - on E: Exception do - begin + End; + End; + Except + on E: Exception Do + Begin FreeAndNil(CNode); - if E is EParserError then + If E is EParserError Then raise - else + Else raise EParserError.Create(E.Message); - end; - end; + End; + End; Result := CNode; -end; +End; -function TParser.Factor: TNode; -var +Function TParser.Factor: TNode; +Var CNode: TNode; fNode: TNodeFunction; Lex: TLex; -begin +Begin CNode := nil; - try + Try Lex := LexC(); - case Lex.token of + Case Lex.token Of tkLParen: - begin + Begin LexAccept(); CNode := Expr(); - if (LexC().Token = tkRParen) then + If (LexC().Token = tkRParen) Then LexAccept() - else + Else raise EParserError.Create('Expected closing parenthesis instead of', LexC()); - end; + End; tkOperator: // unary minus - begin - if Lex.Chr in ['+', '-', '!'] then - begin + Begin + If Lex.Chr in ['+', '-', '!'] Then + Begin LexAccept(); CNode := TNodeUnary.Create(Self, Lex, Factor()); - end - else + End + Else raise EParserError.Create('Unexpected ', Lex); - end; + End; tkNumber, tkInteger, tkString: - begin + Begin CNode := TNodeCValue.Create(Self, Lex); LexAccept(); - end; + End; tkIdentifier: - begin - if LexLook().Token = tkLParen then - begin + Begin + If LexLook().Token = tkLParen Then + Begin // function call LexAccept(); fNode := TNodeFunction.Create(Self, Lex); LexAccept(); CNode := fNode; - if (LexC().token <> tkRParen) then - begin + If (LexC().token <> tkRParen) Then + Begin fNode.AddArg(Expr()); - while LexC().Token = tkComa do - begin + While LexC().Token = tkComa Do + Begin LexAccept(); fNode.AddArg(Expr()); - end; - end; - if (LexC().token = tkRParen) then + End; + End; + If (LexC().token = tkRParen) Then LexAccept() - else + Else raise EParserError.Create('Expected closing parenthesis instead of', LexC()); - end - else - begin + End + Else + Begin CNode := TNodeVariable.Create(Self, Lex); LexAccept(); - end; - end; - else + End; + End; + Else raise EParserError.Create('Unexpected ', Lex); - end; - except - on E: Exception do - begin + End; + Except + on E: Exception Do + Begin FreeAndNil(CNode); - if E is EParserError then + If E is EParserError Then raise - else + Else raise EParserError.Create(E.Message); - end; - end; + End; + End; Result := CNode; -end; +End; { TNode } -constructor TNode.Create(Parser: TParser); -begin - inherited Create; +Constructor TNode.Create(Parser: TParser); +Begin + Inherited Create; FParser := Parser; -end; +End; { TNodeBin } -constructor TNodeBin.Create(AParser: TParser; AOperator: TLex; ALeftNode, ARightNode: TNode); -begin - inherited Create(AParser); +Constructor TNodeBin.Create(AParser: TParser; AOperator: TLex; ALeftNode, ARightNode: TNode); +Begin + Inherited Create(AParser); FOperator := AOperator; FLeftNode := ALeftNode; FRightNode := ARightNode; -end; +End; -destructor TNodeBin.Destroy; -begin +Destructor TNodeBin.Destroy; +Begin FLeftNode.Free; FRightNode.Free; - inherited Destroy; -end; + Inherited Destroy; +End; -function TNodeBin.Eval: Variant; -var +Function TNodeBin.Eval: Variant; +Var LeftValue, RightValue: Variant; - function FixupBoolean(var AVal1: Variant; var AVal2: Variant): Boolean; - begin + Function FixupBoolean(Var AVal1: Variant; Var AVal2: Variant): Boolean; + Begin Result := (TVarData(AVal1).VType = varBoolean) or (TVarData(AVal2).VType = varBoolean); - if Result then - begin - if UpperCase(AVal1) = 'TRUE' then + If Result Then + Begin + If UpperCase(AVal1) = 'TRUE' Then AVal1 := 1 - else + Else AVal1 := 0; - if UpperCase(AVal2) = 'TRUE' then + If UpperCase(AVal2) = 'TRUE' Then AVal2 := 1 - else + Else AVal2 := 0; - end; - end; - function FixupDateTime(var AVal1: Variant; var AVal2: Variant): Boolean; - begin + End; + End; + Function FixupDateTime(Var AVal1: Variant; Var AVal2: Variant): Boolean; + Begin Result := TVarData(AVal1).VType = varDate; - if Result then - begin - if TVarData(AVal2).VType = varString then + If Result Then + Begin + If TVarData(AVal2).VType = varString Then AVal2 := StrToDateTime(AVal2); //convert; - end; - end; - function FixupString(var aVal: Variant): Boolean; - begin + End; + End; + Function FixupString(Var aVal: Variant): Boolean; + Begin Result:=((TVarData(aVal).VType = varString) {$IFDEF UNICODE}or (TVarData(aVal).VType = varUString){$ENDIF UNICODE}) and FParser.Parent.FCaseInsensitive; - if Result then + If Result Then aVal := AnsiUpperCase(aVal); - end; + End; //returns 'True' if a conversion was necessary. - function FixupValues(var AVal1: Variant; var AVal2: Variant): Boolean; - var + Function FixupValues(Var AVal1: Variant; Var AVal2: Variant): Boolean; + Var bChanged: Boolean; - begin + Begin Result := FixupDateTime(AVal1, AVal2); - if not Result then + If not Result Then Result := FixupDateTime(AVal2, AVal1); - if not Result then + If not Result Then Result := FixupBoolean(AVal1, AVal2); - if not Result then //ensure that the 'String' case is the last one - begin + If not Result Then //ensure that the 'String' case is the last one + Begin Result := FixupString(AVal1); bChanged := FixupString(AVal2); Result := Result or bChanged; //ensure that both Fixups are executed regardless of optimisations - end; - end; - function EvalLike: Boolean; - var + End; + End; + Function EvalLike: Boolean; + Var Wildcard1, Wildcard2: Boolean; LeftStr, RightStr: string; - begin - if (LeftValue = Null) or (RightValue = Null) then + Begin + If (LeftValue = Null) or (RightValue = Null) Then Result := (LeftValue = Null) and (RightValue = Null) - else - begin + Else + Begin // Possiblilities: // Left hand contains wildcards -> Match right hand against left hand. // Right hand contains wildcards -> Match left hand against right hand. @@ -721,89 +721,89 @@ function TNodeBin.Eval: Variant; RightStr := RightValue; Wildcard1 := (Pos('*', LeftStr) > 0) or (Pos('?', LeftStr) > 0); Wildcard2 := (Pos('*', RightStr) > 0) or (Pos('?', RightStr) > 0); - if Wildcard1 and not Wildcard2 then + If Wildcard1 and not Wildcard2 Then Result := MatchesMask(RightStr, LeftStr) - else - if Wildcard2 then + Else + If Wildcard2 Then Result := MatchesMask(LeftStr, RightStr) - else + Else Result := LeftValue = RightValue; - end; - end; - function EvalEquality: Boolean; - begin + End; + End; + Function EvalEquality: Boolean; + Begin // Special case, at least one of both is null: - if (LeftValue = Null) or (RightValue = Null) then + If (LeftValue = Null) or (RightValue = Null) Then Result := (LeftValue = Null) and (RightValue = Null) - else - begin - if FParser.Parent.FEnableWildcardMatching and (TVarData(LeftValue).VType<>varDate) then - begin + Else + Begin + If FParser.Parent.FEnableWildcardMatching and (TVarData(LeftValue).VType<>varDate) Then + Begin Result := EvalLike; - end - else + End + Else Result := LeftValue = RightValue; - end; - end; - function EvalLT: Boolean; - begin + End; + End; + Function EvalLT: Boolean; + Begin // Special case, at least one of both is Null: - if (LeftValue = Null) or (RightValue = Null) then + If (LeftValue = Null) or (RightValue = Null) Then // Null is considered to be smaller than any value. Result := LeftValue = Null - else + Else Result := LeftValue < RightValue; - end; - function EvalGT: Boolean; - begin + End; + Function EvalGT: Boolean; + Begin // Special case, at least one of both is Null: - if (LeftValue = Null) or (RightValue = Null) then + If (LeftValue = Null) or (RightValue = Null) Then // Null is considered to be smaller than any value. Result := RightValue = Null - else + Else Result := LeftValue > RightValue; - end; - function EvalLTE: Boolean; - begin + End; + Function EvalLTE: Boolean; + Begin // Special case, at least one of both is Null: - if (LeftValue = Null) or (RightValue = Null) then + If (LeftValue = Null) or (RightValue = Null) Then // Null is considered to be smaller than any value. Result := LeftValue = Null - else + Else Result := LeftValue <= RightValue; - end; - function EvalGTE: Boolean; - begin + End; + Function EvalGTE: Boolean; + Begin // Special case, at least one of both is Null: - if (LeftValue = Null) or (RightValue = Null) then + If (LeftValue = Null) or (RightValue = Null) Then // Null is considered to be smaller than any value. Result := RightValue = Null - else + Else Result := LeftValue >= RightValue; - end; + End; -var +Var LeftStr, RightStr: string; -begin +Begin // Determine values to have them handy. LeftValue := FLeftNode.Eval; RightValue := FRightNode.Eval; FixupValues(LeftValue, RightValue); - case FOperator.Chr of + Case FOperator.Chr Of '+': - begin + Begin // force string concatenation - if (TVarData(LeftValue).VType = varString) or - (TVarData(LeftValue).VType = varOleStr) then - begin + If (TVarData(LeftValue).VType = varString) or + (TVarData(LeftValue).VType = varOleStr) Then + Begin LeftStr := LeftValue; RightStr := RightValue; LeftStr := LeftStr + RightStr; Result := LeftStr; - end - else + End + Else Result := LeftValue + RightValue; - end; + End; '-': Result := LeftValue - RightValue; '*': Result := FLeftNode.Eval * FRightNode.Eval; '/': Result := FLeftNode.Eval / FRightNode.Eval; @@ -813,144 +813,144 @@ function TNodeBin.Eval: Variant; '&': Result := FLeftNode.Eval and FRightNode.Eval; '|': Result := FLeftNode.Eval or FRightNode.Eval; '~': Result := EvalLike; - '§': Result := EvalGTE(); + '^': Result := EvalGTE(); '@': Result := EvalLTE(); '#': Result := not EvalEquality(); - else + Else Result := Null; - end; -end; + End; +End; { TNodeUnary } -constructor TNodeUnary.Create(AParser: TParser; AOperator: TLex; ARightNode: TNode); -begin - inherited Create(AParser); +Constructor TNodeUnary.Create(AParser: TParser; AOperator: TLex; ARightNode: TNode); +Begin + Inherited Create(AParser); FOperator := AOperator; FRightNode := ARightNode; -end; +End; -destructor TNodeUnary.Destroy; -begin +Destructor TNodeUnary.Destroy; +Begin FRightNode.Free; - inherited Destroy; -end; + Inherited Destroy; +End; -function TNodeUnary.Eval: Variant; -begin +Function TNodeUnary.Eval: Variant; +Begin Result := FRightNode.Eval(); - if FOperator.Chr = '-' then + If FOperator.Chr = '-' Then Result := -Result; - if FOperator.Chr = '!' then + If FOperator.Chr = '!' Then Result := not Result; -end; +End; { TNodeCValue } -constructor TNodeCValue.Create(AParser: TParser; ACValue: TLex); -begin - inherited Create(AParser); +Constructor TNodeCValue.Create(AParser: TParser; ACValue: TLex); +Begin + Inherited Create(AParser); FCValue := ACValue; -end; +End; -function TNodeCValue.Eval: Variant; -begin - case FCValue.Token of +Function TNodeCValue.Eval: Variant; +Begin + Case FCValue.Token Of tkNumber: Result := StrToFloat(FCValue.Str); tkInteger: Result := StrToInt(FCValue.Str); tkString: Result := FCValue.Str; - else + Else Result := Null; - end; -end; + End; +End; { TNodeFunction } -constructor TNodeFunction.Create(AParser: TParser; AFunc: TLex); -begin - inherited Create(AParser); +Constructor TNodeFunction.Create(AParser: TParser; AFunc: TLex); +Begin + Inherited Create(AParser); FArgs := TObjectList.Create(True); FFunc := AFunc; -end; +End; -destructor TNodeFunction.Destroy; -begin +Destructor TNodeFunction.Destroy; +Begin FArgs.Free; - inherited Destroy; -end; + Inherited Destroy; +End; -procedure TNodeFunction.AddArg(Node: TNode); -begin +Procedure TNodeFunction.AddArg(Node: TNode); +Begin FArgs.Add(Node); -end; +End; -function TNodeFunction.Eval: Variant; -var +Function TNodeFunction.Eval: Variant; +Var Value: Variant; VArgs: Variant; I: Integer; -begin +Begin VArgs := VarArrayCreate([0, FArgs.Count - 1], varVariant); - for I := 0 to FArgs.Count - 1 do + For I := 0 To FArgs.Count - 1 Do VArgs[I] := TNode(FArgs[I]).Eval(); Value := Null; - if FParser.Parent.DoExecuteFunction(FFunc.Str, VArgs, Value) then + If FParser.Parent.DoExecuteFunction(FFunc.Str, VArgs, Value) Then Result := Value - else + Else raise EParserError.CreateFmt('Function %s could not be executed.', [FFunc.Str]); -end; +End; { TNodeVariable } -constructor TNodeVariable.Create(AParser: TParser; ALex: TLex); -begin - inherited Create(AParser); +Constructor TNodeVariable.Create(AParser: TParser; ALex: TLex); +Begin + Inherited Create(AParser); FLex := ALex; -end; +End; -function TNodeVariable.Eval: Variant; -var +Function TNodeVariable.Eval: Variant; +Var Value: Variant; -begin +Begin Value := Null; - if FParser.Parent.DoGetVariable(FLex.Str, Value) then + If FParser.Parent.DoGetVariable(FLex.Str, Value) Then Result := Value - else + Else raise EParserError.Create('Variable ' + FLex.Str + ' could not be fetched.'); -end; +End; { EParserError } -constructor EParserError.Create(const Msg: string; Lex: TLex); -begin - inherited CreateFmt('%s %s', [Msg, Lex.Debug]); -end; +Constructor EParserError.Create(Const Msg: string; Lex: TLex); +Begin + Inherited CreateFmt('%s %s', [Msg, Lex.Debug]); +End; { TExprParser } -constructor TExprParser.Create; -begin - inherited Create; +Constructor TExprParser.Create; +Begin + Inherited Create; FErrorMessage := ''; -end; +End; -destructor TExprParser.Destroy; -begin +Destructor TExprParser.Destroy; +Begin FParser.Free; FScan.Free; - inherited Destroy; -end; + Inherited Destroy; +End; -function TExprParser.Eval(): Boolean; -var +Function TExprParser.Eval(): Boolean; +Var Parser: TParser; {$IFDEF TESTING_PARSER} Scan: TScan; {$ENDIF TESTING_PARSER} -begin +Begin FErrorMessage := ''; {$IFDEF TESTING_PARSER} DebugText := ''; @@ -958,104 +958,104 @@ function TExprParser.Eval(): Boolean; Scan.DebugPrint(); {$ENDIF TESTING_PARSER} Parser := TParser(FParser); - if Parser.Execute() then - begin + If Parser.Execute() Then + Begin FValue := Parser.Value; Result := True; - end - else - begin + End + Else + Begin FErrorMessage := Parser.ErrorMessage; Result := False; - end -end; + End +End; -function TExprParser.Eval(const AExpression: string): Boolean; -begin +Function TExprParser.Eval(Const AExpression: string): Boolean; +Begin SetExpression(AExpression); Result := Eval(); -end; +End; -procedure TExprParser.SetCaseInsensitive(const Value: Boolean); -begin +Procedure TExprParser.SetCaseInsensitive(Const Value: Boolean); +Begin FCaseInsensitive := Value; -end; +End; -procedure TExprParser.SetExpression(const Value: string); -var +Procedure TExprParser.SetExpression(Const Value: string); +Var nValue : string; -begin +Begin // alguns parses tiveram se ser mudados - // porque o operador é Char + // porque o operador Char nValue := ConvertDoubleOperators(Value); - if nValue <> FExpression then begin + If nValue <> FExpression Then Begin FExpression := nValue; FParser.Free; FScan.Free; FParser := TParser.Create; TParser(FParser).Parent := Self; FScan := TScan.Create; - if not TScan(FScan).Parse(FExpression) then + If not TScan(FScan).Parse(FExpression) Then FErrorMessage := TScan(FScan).ErrorMessage - else - begin + Else + Begin TParser(FParser).Scan := TScan(FScan); TParser(FParser).Parse(); - end; - end; -end; + End; + End; +End; -function TExprParser.DoGetVariable(const VarName: string; var Value: Variant): Boolean; -begin +Function TExprParser.DoGetVariable(Const VarName: string; Var Value: Variant): Boolean; +Begin Result := False; - if Assigned(FOnGetVariable) then + If Assigned(FOnGetVariable) Then Result := FOnGetVariable(Self, VarName, Value); -end; +End; -function TExprParser.DoExecuteFunction(const FuncName: string; const Args: Variant; var ResVal: Variant): Boolean; -begin +Function TExprParser.DoExecuteFunction(Const FuncName: string; Const Args: Variant; Var ResVal: Variant): Boolean; +Begin Result := False; - if Assigned(FOnExecuteFunction) then + If Assigned(FOnExecuteFunction) Then Result := FOnExecuteFunction(Self, FuncName, Args, ResVal); -end; +End; -function TExprParser.ConvertDoubleOperators(Value: String): String; -var +Function TExprParser.ConvertDoubleOperators(Value: String): String; +Var i : integer; bEscapeDoubleQuote, bEscapeQuote : Boolean; sOperator : string; -begin +Begin Result := ''; bEscapeDoubleQuote := False; bEscapeQuote := False; i := 1; - while i <= Length(Value) do begin - if (Value[i] = '"') and (not bEscapeQuote) then begin + While i <= Length(Value) Do Begin + If (Value[i] = '"') and (not bEscapeQuote) Then Begin bEscapeDoubleQuote := not bEscapeDoubleQuote; Result := Result + Value[i]; - end - else if (Value[i] = '''') and (not bEscapeDoubleQuote) then begin + End + Else If (Value[i] = '''') and (not bEscapeDoubleQuote) Then Begin bEscapeQuote := not bEscapeQuote; Result := Result + Value[i]; - end - else if (Value[i] in cOperators) and (not bEscapeQuote) and (not bEscapeDoubleQuote) then begin + End + Else If (Value[i] in cOperators) and (not bEscapeQuote) and (not bEscapeDoubleQuote) Then Begin sOperator := sOperator + Value[i]; - end - else begin - if sOperator <> '' then begin - sOperator := StringReplace(sOperator,'>=','§',[rfReplaceAll]); + End + Else Begin + If sOperator <> '' Then Begin + sOperator := StringReplace(sOperator,'>=','^',[rfReplaceAll]); sOperator := StringReplace(sOperator,'<=','@',[rfReplaceAll]); sOperator := StringReplace(sOperator,'<>','#',[rfReplaceAll]); sOperator := StringReplace(sOperator,'!=','#',[rfReplaceAll]); Result := Result + sOperator; sOperator := ''; - end; + End; Result := Result + Value[i]; - end; + End; i := i + 1; - end; -end; + End; +End; -end. +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemAnsiStrings.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemAnsiStrings.pas index 3c202498b..f958ee71a 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemAnsiStrings.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemAnsiStrings.pas @@ -1,21 +1,21 @@ -unit uRESTDWMemAnsiStrings; +Unit uRESTDWMemAnsiStrings; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -27,8 +27,8 @@ {$ASMMode Intel} {$ENDIF} -interface -uses +Interface +Uses {$IFDEF HAS_UNITSCOPE} {$IFDEF MSWINDOWS} Winapi.Windows, @@ -42,62 +42,62 @@ interface {$ENDIF ~HAS_UNITSCOPE} uRESTDWMemBase, Math, uRESTDWPrototypes; // Ansi types -type +Type {$IFDEF SUPPORTS_UNICODE} - TJclAnsiStringList = class; + TJclAnsiStringList = Class; // Codegear should be the one providing this class, in the DWStrings unit. // It has been requested in QC 65630 but this was closed as "won't do". // So we are providing here a very light implementation that is designed // to provide the basics, and in no way be a "copy/paste" of what is in the RTL. - TJclAnsiStrings = class(TPersistent) - private + TJclAnsiStrings = Class(TPersistent) + Private FDelimiter: DWChar; FNameValueSeparator: DWChar; FStrictDelimiter: Boolean; FQuoteChar: DWChar; FUpdateCount: Integer; - function GetText: DWString; - procedure SetText(const Value: DWString); - function ExtractName(const S: DWString): DWString; - function GetName(Index: Integer): DWString; - function GetValue(const Name: DWString): DWString; - procedure SetValue(const Name, Value: DWString); - function GetValueFromIndex(Index: Integer): DWString; - procedure SetValueFromIndex(Index: Integer; const Value: DWString); - protected - procedure AssignTo(Dest: TPersistent); override; - procedure Error(const Msg: string; Data: Integer); overload; - procedure Error(Msg: PResStringRec; Data: Integer); overload; - function GetString(Index: Integer): DWString; virtual; abstract; - procedure SetString(Index: Integer; const Value: DWString); virtual; abstract; - function GetObject(Index: Integer): TObject; virtual; abstract; - procedure SetObject(Index: Integer; AObject: TObject); virtual; abstract; - function GetCapacity: Integer; virtual; - procedure SetCapacity(const Value: Integer); virtual; - function GetCount: Integer; virtual; abstract; - function CompareStrings(const S1, S2: DWString): Integer; virtual; - procedure SetUpdateState(Updating: Boolean); virtual; + Function GetText: DWString; + Procedure SetText(Const Value: DWString); + Function ExtractName(Const S: DWString): DWString; + Function GetName(Index: Integer): DWString; + Function GetValue(Const Name: DWString): DWString; + Procedure SetValue(Const Name, Value: DWString); + Function GetValueFromIndex(Index: Integer): DWString; + Procedure SetValueFromIndex(Index: Integer; Const Value: DWString); + Protected + Procedure AssignTo(Dest: TPersistent); override; + Procedure Error(Const Msg: string; Data: Integer); overload; + Procedure Error(Msg: PResStringRec; Data: Integer); overload; + Function GetString(Index: Integer): DWString; virtual; abstract; + Procedure SetString(Index: Integer; Const Value: DWString); virtual; abstract; + Function GetObject(Index: Integer): TObject; virtual; abstract; + Procedure SetObject(Index: Integer; AObject: TObject); virtual; abstract; + Function GetCapacity: Integer; virtual; + Procedure SetCapacity(Const Value: Integer); virtual; + Function GetCount: Integer; virtual; abstract; + Function CompareStrings(Const S1, S2: DWString): Integer; virtual; + Procedure SetUpdateState(Updating: Boolean); virtual; property UpdateCount: Integer read FUpdateCount; - public - constructor Create; - procedure Assign(Source: TPersistent); override; - function Add(const S: DWString): Integer; virtual; - function AddObject(const S: DWString; AObject: TObject): Integer; virtual; abstract; - procedure AddStrings(Strings: TJclAnsiStrings); virtual; - procedure Insert(Index: Integer; const S: DWString); virtual; - procedure InsertObject(Index: Integer; const S: DWString; AObject: TObject); virtual; abstract; - procedure Delete(Index: Integer); virtual; abstract; - procedure Clear; virtual; abstract; - procedure LoadFromFile(const FileName: TFileName); virtual; - procedure LoadFromStream(Stream: TStream); virtual; - procedure SaveToFile(const FileName: TFileName); virtual; - procedure SaveToStream(Stream: TStream); virtual; - procedure BeginUpdate; - procedure EndUpdate; - function IndexOf(const S: DWString): Integer; virtual; - function IndexOfName(const Name: DWString): Integer; virtual; - function IndexOfObject(AObject: TObject): Integer; virtual; - procedure Exchange(Index1, Index2: Integer); virtual; + Public + Constructor Create; + Procedure Assign(Source: TPersistent); override; + Function Add(Const S: DWString): Integer; virtual; + Function AddObject(Const S: DWString; AObject: TObject): Integer; virtual; abstract; + Procedure AddStrings(Strings: TJclAnsiStrings); virtual; + Procedure Insert(Index: Integer; Const S: DWString); virtual; + Procedure InsertObject(Index: Integer; Const S: DWString; AObject: TObject); virtual; abstract; + Procedure Delete(Index: Integer); virtual; abstract; + Procedure Clear; virtual; abstract; + Procedure LoadFromFile(Const FileName: TFileName); virtual; + Procedure LoadFromStream(Stream: TStream); virtual; + Procedure SaveToFile(Const FileName: TFileName); virtual; + Procedure SaveToStream(Stream: TStream); virtual; + Procedure BeginUpdate; + Procedure EndUpdate; + Function IndexOf(Const S: DWString): Integer; virtual; + Function IndexOfName(Const Name: DWString): Integer; virtual; + Function IndexOfObject(AObject: TObject): Integer; virtual; + Procedure Exchange(Index1, Index2: Integer); virtual; property Delimiter: DWChar read FDelimiter write FDelimiter; property StrictDelimiter: Boolean read FStrictDelimiter write FStrictDelimiter; property QuoteChar: DWChar read FQuoteChar write FQuoteChar; @@ -107,51 +107,51 @@ TJclAnsiStrings = class(TPersistent) property Count: Integer read GetCount; property Capacity: Integer read GetCapacity write SetCapacity; property Names[Index: Integer]: DWString read GetName; - property Values[const Name: DWString]: DWString read GetValue write SetValue; + property Values[Const Name: DWString]: DWString read GetValue write SetValue; property ValueFromIndex[Index: Integer]: DWString read GetValueFromIndex write SetValueFromIndex; property NameValueSeparator: DWChar read FNameValueSeparator write FNameValueSeparator; - end; - TJclAnsiStringListSortCompare = function(List: TJclAnsiStringList; Index1, Index2: Integer): Integer; - TJclAnsiStringObjectHolder = record + End; + TJclAnsiStringListSortCompare = Function(List: TJclAnsiStringList; Index1, Index2: Integer): Integer; + TJclAnsiStringObjectHolder = Record Str: DWString; Obj: TObject; - end; - TJclAnsiStringList = class(TJclAnsiStrings) - private - FStrings: array of TJclAnsiStringObjectHolder; + End; + TJclAnsiStringList = Class(TJclAnsiStrings) + Private + FStrings: array Of TJclAnsiStringObjectHolder; FCount: Integer; FDuplicates: TDuplicates; FSorted: Boolean; FCaseSensitive: Boolean; FOnChange: TNotifyEvent; FOnChanging: TNotifyEvent; - procedure Grow; - procedure QuickSort(L, R: Integer; SCompare: TJclAnsiStringListSortCompare); - protected - procedure AssignTo(Dest: TPersistent); override; - function GetString(Index: Integer): DWString; override; - function GetObject(Index: Integer): TObject; override; - procedure SetObject(Index: Integer; AObject: TObject); override; - function GetCapacity: Integer; override; - procedure SetCapacity(const Value: Integer); override; - function GetCount: Integer; override; - function CompareStrings(const S1, S2: DWString): Integer; override; - procedure SetUpdateState(Updating: Boolean); override; - procedure Changed; virtual; - procedure Changing; virtual; - public - constructor Create; - destructor Destroy; override; - procedure Assign(Source: TPersistent); override; - procedure InsertObject(Index: Integer; const S: DWString; AObject: TObject); override; - procedure Delete(Index: Integer); override; - function Find(const S: DWString; var Index: Integer): Boolean; virtual; - procedure Clear; override; + Procedure Grow; + Procedure QuickSort(L, R: Integer; SCompare: TJclAnsiStringListSortCompare); + Protected + Procedure AssignTo(Dest: TPersistent); override; + Function GetString(Index: Integer): DWString; override; + Function GetObject(Index: Integer): TObject; override; + Procedure SetObject(Index: Integer; AObject: TObject); override; + Function GetCapacity: Integer; override; + Procedure SetCapacity(Const Value: Integer); override; + Function GetCount: Integer; override; + Function CompareStrings(Const S1, S2: DWString): Integer; override; + Procedure SetUpdateState(Updating: Boolean); override; + Procedure Changed; virtual; + Procedure Changing; virtual; + Public + Constructor Create; + Destructor Destroy; override; + Procedure Assign(Source: TPersistent); override; + Procedure InsertObject(Index: Integer; Const S: DWString; AObject: TObject); override; + Procedure Delete(Index: Integer); override; + Function Find(Const S: DWString; Var Index: Integer): Boolean; virtual; + Procedure Clear; override; property CaseSensitive: Boolean read FCaseSensitive write FCaseSensitive; property Duplicates: TDuplicates read FDuplicates write FDuplicates; property OnChange: TNotifyEvent read FOnChange write FOnChange; property OnChanging: TNotifyEvent read FOnChanging write FOnChanging; - end; + End; {$ELSE ~SUPPORTS_UNICODE} TJclAnsiStrings = Classes.TStrings; TJclAnsiStringList = Classes.TStringList; @@ -159,11 +159,11 @@ TJclAnsiStringList = class(TJclAnsiStrings) TAnsiStrings = TJclAnsiStrings; TAnsiStringList = TJclAnsiStringList; // Exceptions -type - EJclAnsiStringError = class(EJclError); - EJclAnsiStringListError = class(EJclAnsiStringError); +Type + EJclAnsiStringError = Class(EJclError); + EJclAnsiStringListError = Class(EJclAnsiStringError); // Character constants and sets -const +Const // Misc. often used character definitions AnsiNull = DWChar(#0); AnsiSoh = DWChar(#1); @@ -223,7 +223,7 @@ EJclAnsiStringListError = class(EJclAnsiStringError); AnsiOctDigits = ['0'..'7']; AnsiHexDigits = ['0'..'9', 'A'..'F', 'a'..'f']; AnsiValidIdentifierLetters = ['0'..'9', 'A'..'Z', 'a'..'z', '_']; -const +Const // CharType return values C1_UPPER = $0001; // Uppercase C1_LOWER = $0002; // Lowercase @@ -248,141 +248,141 @@ EJclAnsiStringListError = class(EJclAnsiStringError); {$ENDIF SUPPORTS_EXTSYM} {$ENDIF MSWINDOWS} // String Test Routines -function StrContainsChars(const S: DWString; Chars: TSysCharSet; CheckAll: Boolean): Boolean; -function StrIsSubset(const S: DWString; const ValidChars: TSysCharSet): Boolean; -function StrSame(const S1, S2: DWString): Boolean; +Function StrContainsChars(Const S: DWString; Chars: TSysCharSet; CheckAll: Boolean): Boolean; +Function StrIsSubset(Const S: DWString; Const ValidChars: TSysCharSet): Boolean; +Function StrSame(Const S1, S2: DWString): Boolean; // String Transformation Routines -function StrCenter(const S: DWString; L: SizeInt; C: DWChar = ' '): DWString; -function StrCharPosLower(const S: DWString; CharPos: SizeInt): DWString; -function StrCharPosUpper(const S: DWString; CharPos: SizeInt): DWString; -function StrDoubleQuote(const S: DWString): DWString; -function StrEnsureNoPrefix(const Prefix, Text: DWString): DWString; -function StrEnsureNoSuffix(const Suffix, Text: DWString): DWString; -function StrEnsurePrefix(const Prefix, Text: DWString): DWString; -function StrEnsureSuffix(const Suffix, Text: DWString): DWString; -function StrEscapedToString(const S: DWString): DWString; -procedure StrMove(var Dest: DWString; const Source: DWString; const ToIndex, +Function StrCenter(Const S: DWString; L: SizeInt; C: DWChar = ' '): DWString; +Function StrCharPosLower(Const S: DWString; CharPos: SizeInt): DWString; +Function StrCharPosUpper(Const S: DWString; CharPos: SizeInt): DWString; +Function StrDoubleQuote(Const S: DWString): DWString; +Function StrEnsureNoPrefix(Const Prefix, Text: DWString): DWString; +Function StrEnsureNoSuffix(Const Suffix, Text: DWString): DWString; +Function StrEnsurePrefix(Const Prefix, Text: DWString): DWString; +Function StrEnsureSuffix(Const Suffix, Text: DWString): DWString; +Function StrEscapedToString(Const S: DWString): DWString; +Procedure StrMove(Var Dest: DWString; Const Source: DWString; Const ToIndex, FromIndex, Count: SizeInt); -function StrPadLeft(const S: DWString; Len: SizeInt; C: DWChar = AnsiSpace): DWString; -function StrPadRight(const S: DWString; Len: SizeInt; C: DWChar = AnsiSpace): DWString; -function StrProper(const S: DWString): DWString; -function StrQuote(const S: DWString; C: DWChar): DWString; -function StrReplaceChar(const S: DWString; const Source, Replace: DWChar): DWString; -function StrReplaceChars(const S: DWString; const Chars: TSysCharSet; Replace: DWChar): DWString; -function StrReplaceButChars(const S: DWString; const Chars: TSysCharSet; Replace: DWChar): DWString; -function StrSingleQuote(const S: DWString): DWString; -procedure StrSkipChars(const S: DWString; var Index: SizeInt; const Chars: TSysCharSet); overload; -function StrStringToEscaped(const S: DWString): DWString; -function StrToHex(const Source: DWString): DWString; -function StrTrimCharLeft(const S: DWString; C: DWChar): DWString; -function StrTrimCharsLeft(const S: DWString; const Chars: TSysCharSet): DWString; -function StrTrimCharRight(const S: DWString; C: DWChar): DWString; -function StrTrimCharsRight(const S: DWString; const Chars: TSysCharSet): DWString; -function StrTrimQuotes(const S: DWString): DWString; overload; -function StrTrimQuotes(const S: DWString; QuoteChar: DWChar): DWString; overload; +Function StrPadLeft(Const S: DWString; Len: SizeInt; C: DWChar = AnsiSpace): DWString; +Function StrPadRight(Const S: DWString; Len: SizeInt; C: DWChar = AnsiSpace): DWString; +Function StrProper(Const S: DWString): DWString; +Function StrQuote(Const S: DWString; C: DWChar): DWString; +Function StrReplaceChar(Const S: DWString; Const Source, Replace: DWChar): DWString; +Function StrReplaceChars(Const S: DWString; Const Chars: TSysCharSet; Replace: DWChar): DWString; +Function StrReplaceButChars(Const S: DWString; Const Chars: TSysCharSet; Replace: DWChar): DWString; +Function StrSingleQuote(Const S: DWString): DWString; +Procedure StrSkipChars(Const S: DWString; Var Index: SizeInt; Const Chars: TSysCharSet); overload; +Function StrStringToEscaped(Const S: DWString): DWString; +Function StrToHex(Const Source: DWString): DWString; +Function StrTrimCharLeft(Const S: DWString; C: DWChar): DWString; +Function StrTrimCharsLeft(Const S: DWString; Const Chars: TSysCharSet): DWString; +Function StrTrimCharRight(Const S: DWString; C: DWChar): DWString; +Function StrTrimCharsRight(Const S: DWString; Const Chars: TSysCharSet): DWString; +Function StrTrimQuotes(Const S: DWString): DWString; overload; +Function StrTrimQuotes(Const S: DWString; QuoteChar: DWChar): DWString; overload; // String Management -procedure StrDecRef(var S: DWString); -function StrLength(const S: DWString): Longint; -function StrRefCount(const S: DWString): Longint; -procedure StrResetLength(var S: DWString); +Procedure StrDecRef(Var S: DWString); +Function StrLength(Const S: DWString): Longint; +Function StrRefCount(Const S: DWString): Longint; +Procedure StrResetLength(Var S: DWString); // String Search and Replace Routines -function StrCharCount(const S: DWString; C: DWChar): SizeInt; -function StrCharsCount(const S: DWString; Chars: TSysCharSet): SizeInt; -function StrStrCount(const S, SubS: DWString): SizeInt; -function StrCompare(const S1, S2: DWString; CaseSensitive: Boolean = False): SizeInt; -function StrCompareRangeEx(const S1, S2: DWString; Index, Count: SizeInt; CaseSensitive: Boolean = False): SizeInt; -function StrCompareRange(const S1, S2: DWString; Index, Count: SizeInt; CaseSensitive: Boolean = True): SizeInt; -function StrRepeatChar(C: DWChar; Count: SizeInt): DWString; -function StrFind(const Substr, S: DWString; const Index: SizeInt = 1): SizeInt; -function StrHasPrefix(const S: DWString; const Prefixes: array of DWString): Boolean; -function StrHasSuffix(const S: DWString; const Suffixes: array of DWString): Boolean; -function StrIHasPrefix(const S: DWString; const Prefixes: array of DWString): Boolean; -function StrIHasSuffix(const S: DWString; const Suffixes: array of DWString): Boolean; -function StrIndex(const S: DWString; const List: array of DWString; CaseSensitive: Boolean = False): SizeInt; -function StrILastPos(const SubStr, S: DWString): SizeInt; -function StrIPos(const SubStr, S: DWString): SizeInt; -function StrIPrefixIndex(const S: DWString; const Prefixes: array of DWString): SizeInt; -function StrIsOneOf(const S: DWString; const List: array of DWString): Boolean; -function StrISuffixIndex(const S: DWString; const Suffixes: array of DWString): SizeInt; -function StrMatch(const Substr, S: DWString; Index: SizeInt = 1): SizeInt; -function StrNIPos(const S, SubStr: DWString; N: SizeInt): SizeInt; -function StrNPos(const S, SubStr: DWString; N: SizeInt): SizeInt; -function StrPrefixIndex(const S: DWString; const Prefixes: array of DWString): SizeInt; -function StrSuffixIndex(const S: DWString; const Suffixes: array of DWString): SizeInt; +Function StrCharCount(Const S: DWString; C: DWChar): SizeInt; +Function StrCharsCount(Const S: DWString; Chars: TSysCharSet): SizeInt; +Function StrStrCount(Const S, SubS: DWString): SizeInt; +Function StrCompare(Const S1, S2: DWString; CaseSensitive: Boolean = False): SizeInt; +Function StrCompareRangeEx(Const S1, S2: DWString; Index, Count: SizeInt; CaseSensitive: Boolean = False): SizeInt; +Function StrCompareRange(Const S1, S2: DWString; Index, Count: SizeInt; CaseSensitive: Boolean = True): SizeInt; +Function StrRepeatChar(C: DWChar; Count: SizeInt): DWString; +Function StrFind(Const Substr, S: DWString; Const Index: SizeInt = 1): SizeInt; +Function StrHasPrefix(Const S: DWString; Const Prefixes: array Of DWString): Boolean; +Function StrHasSuffix(Const S: DWString; Const Suffixes: array Of DWString): Boolean; +Function StrIHasPrefix(Const S: DWString; Const Prefixes: array Of DWString): Boolean; +Function StrIHasSuffix(Const S: DWString; Const Suffixes: array Of DWString): Boolean; +Function StrIndex(Const S: DWString; Const List: array Of DWString; CaseSensitive: Boolean = False): SizeInt; +Function StrILastPos(Const SubStr, S: DWString): SizeInt; +Function StrIPos(Const SubStr, S: DWString): SizeInt; +Function StrIPrefixIndex(Const S: DWString; Const Prefixes: array Of DWString): SizeInt; +Function StrIsOneOf(Const S: DWString; Const List: array Of DWString): Boolean; +Function StrISuffixIndex(Const S: DWString; Const Suffixes: array Of DWString): SizeInt; +Function StrMatch(Const Substr, S: DWString; Index: SizeInt = 1): SizeInt; +Function StrNIPos(Const S, SubStr: DWString; N: SizeInt): SizeInt; +Function StrNPos(Const S, SubStr: DWString; N: SizeInt): SizeInt; +Function StrPrefixIndex(Const S: DWString; Const Prefixes: array Of DWString): SizeInt; +Function StrSuffixIndex(Const S: DWString; Const Suffixes: array Of DWString): SizeInt; // String Extraction // String Extraction // Returns the String before SubStr -function StrAfter(const SubStr, S: DWString): DWString; +Function StrAfter(Const SubStr, S: DWString): DWString; /// Returns the DWString after SubStr -function StrBefore(const SubStr, S: DWString): DWString; +Function StrBefore(Const SubStr, S: DWString): DWString; /// Splits a DWString at SubStr, returns true when SubStr is found, Left contains the /// DWString before the SubStr and Rigth the DWString behind SubStr -function StrSplit(const SubStr, S: DWString;var Left, Right : DWString): boolean; +Function StrSplit(Const SubStr, S: DWString;Var Left, Right : DWString): boolean; /// Returns the DWString between Start and Stop -function StrBetween(const S: DWString; const Start, Stop: DWChar): DWString; +Function StrBetween(Const S: DWString; Const Start, Stop: DWChar): DWString; /// Returns the left N characters of the DWString -function StrChopRight(const S: DWString; N: SizeInt): DWString; +Function StrChopRight(Const S: DWString; N: SizeInt): DWString; /// Returns the left Count characters of the DWString -function StrLeft(const S: DWString; Count: SizeInt): DWString; +Function StrLeft(Const S: DWString; Count: SizeInt): DWString; /// Returns the DWString starting from position Start for the Count Characters -function StrMid(const S: DWString; Start, Count: SizeInt): DWString; +Function StrMid(Const S: DWString; Start, Count: SizeInt): DWString; /// Returns the DWString starting from position N to the end -function StrRestOf(const S: DWString; N: SizeInt): DWString; +Function StrRestOf(Const S: DWString; N: SizeInt): DWString; /// Returns the right Count characters of the DWString -function StrRight(const S: DWString; Count: SizeInt): DWString; +Function StrRight(Const S: DWString; Count: SizeInt): DWString; // Character Test Routines -function CharIsDelete(const C: DWChar): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsReturn(const C: DWChar): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsValidIdentifierLetter(const C: DWChar): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsWildcard(const C: DWChar): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharType(const C: DWChar): Word; +Function CharIsDelete(Const C: DWChar): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsReturn(Const C: DWChar): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsValidIdentifierLetter(Const C: DWChar): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsWildcard(Const C: DWChar): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharType(Const C: DWChar): Word; // Character Transformation Routines -function CharHex(const C: DWChar): Byte; -function CharLower(const C: DWChar): DWChar; -function CharUpper(const C: DWChar): DWChar; -function CharToggleCase(const C: DWChar): DWChar; +Function CharHex(Const C: DWChar): Byte; +Function CharLower(Const C: DWChar): DWChar; +Function CharUpper(Const C: DWChar): DWChar; +Function CharToggleCase(Const C: DWChar): DWChar; // Character Search and Replace -function CharPos(const S: DWString; const C: DWChar; const Index: SizeInt = 1): SizeInt; -function CharLastPos(const S: DWString; const C: DWChar; const Index: SizeInt = 1): SizeInt; -function CharIPos(const S: DWString; C: DWChar; const Index: SizeInt = 1): SizeInt; +Function CharPos(Const S: DWString; Const C: DWChar; Const Index: SizeInt = 1): SizeInt; +Function CharLastPos(Const S: DWString; Const C: DWChar; Const Index: SizeInt = 1): SizeInt; +Function CharIPos(Const S: DWString; C: DWChar; Const Index: SizeInt = 1): SizeInt; // PCharVector -type +Type PAnsiCharVector = ^PAnsiChar; // MultiSz Routines -type +Type PAnsiMultiSz = PAnsiChar; -procedure AllocateMultiSz(var Dest: PAnsiMultiSz; Len: SizeInt); -procedure FreeMultiSz(var Dest: PAnsiMultiSz); -procedure StrIToStrings(S, Sep: DWString; const List: TJclAnsiStrings; const AllowEmptyString: Boolean = True); -procedure StrToStrings(S, Sep: DWString; const List: TJclAnsiStrings; const AllowEmptyString: Boolean = True); -function StringsToStr(const List: TJclAnsiStrings; const Sep: DWString; const AllowEmptyString: Boolean = True): DWString; -procedure TrimStrings(const List: TJclAnsiStrings; DeleteIfEmpty: Boolean = True); -procedure TrimStringsRight(const List: TJclAnsiStrings; DeleteIfEmpty: Boolean = True); -procedure TrimStringsLeft(const List: TJclAnsiStrings; DeleteIfEmpty: Boolean = True); -function AddStringToStrings(const S: DWString; Strings: TJclAnsiStrings; const Unique: Boolean): Boolean; +Procedure AllocateMultiSz(Var Dest: PAnsiMultiSz; Len: SizeInt); +Procedure FreeMultiSz(Var Dest: PAnsiMultiSz); +Procedure StrIToStrings(S, Sep: DWString; Const List: TJclAnsiStrings; Const AllowEmptyString: Boolean = True); +Procedure StrToStrings(S, Sep: DWString; Const List: TJclAnsiStrings; Const AllowEmptyString: Boolean = True); +Function StringsToStr(Const List: TJclAnsiStrings; Const Sep: DWString; Const AllowEmptyString: Boolean = True): DWString; +Procedure TrimStrings(Const List: TJclAnsiStrings; DeleteIfEmpty: Boolean = True); +Procedure TrimStringsRight(Const List: TJclAnsiStrings; DeleteIfEmpty: Boolean = True); +Procedure TrimStringsLeft(Const List: TJclAnsiStrings; DeleteIfEmpty: Boolean = True); +Function AddStringToStrings(Const S: DWString; Strings: TJclAnsiStrings; Const Unique: Boolean): Boolean; // Miscellaneous // (OF) moved to JclSysUtils //function BooleanToStr(B: Boolean): DWString; -function FileToString(const FileName: TFileName): DWString; -procedure StringToFile(const FileName: TFileName; const Contents: DWString; Append: Boolean = False); -function StrToken(var S: DWString; Separator: DWChar): DWString; +Function FileToString(Const FileName: TFileName): DWString; +Procedure StringToFile(Const FileName: TFileName; Const Contents: DWString; Append: Boolean = False); +Function StrToken(Var S: DWString; Separator: DWChar): DWString; //procedure StrTokenToStrings(S: DWString; Separator: DWChar; const List: TJclAnsiStrings);Overload; //procedure StrTokenToStrings(S: string; Separator: Char; const List: TStrings);Overload; -procedure StrNormIndex(const StrLen: SizeInt; var Index: SizeInt; var Count: SizeInt); overload; -function ArrayOf(List: TJclAnsiStrings): TDynStringArray; overload; +Procedure StrNormIndex(Const StrLen: SizeInt; Var Index: SizeInt; Var Count: SizeInt); overload; +Function ArrayOf(List: TJclAnsiStrings): TDynStringArray; overload; // internal structures published to make function inlining working -const +Const DWCharCount = Ord(High(Char)) + 1; // # of chars in one set AnsiLoOffset = DWCharCount * 0; // offset to lower case chars AnsiUpOffset = DWCharCount * 1; // offset to upper case chars AnsiReOffset = DWCharCount * 2; // offset to reverse case chars AnsiCaseMapSize = DWCharCount * 3; // # of chars is a table -var - AnsiCaseMap: array [0..AnsiCaseMapSize - 1] of DWChar; // case mappings +Var + AnsiCaseMap: array [0..AnsiCaseMapSize - 1] Of DWChar; // case mappings AnsiCaseMapReady: Boolean = False; // true if case map exists - DWCharTypes: array [Char] of Word; -implementation -uses + DWCharTypes: array [Char] Of Word; +Implementation +Uses {$IFDEF HAS_UNIT_LIBC} Libc, {$ENDIF HAS_UNIT_LIBC} @@ -398,21 +398,21 @@ implementation uRESTDWMemResources, uRESTDWMemStreams, uRESTDWMemStringsB; //=== Internal =============================================================== -type - TAnsiStrRec = packed record +Type + TAnsiStrRec = packed Record RefCount: Integer; Length: Integer; - end; + End; PAnsiStrRec = ^TAnsiStrRec; -const +Const AnsiStrRecSize = SizeOf(TAnsiStrRec); // size of the DWString header rec -procedure LoadCharTypes; -var +Procedure LoadCharTypes; +Var CurrChar: DWChar; CurrType: Word; -begin - for CurrChar := Low(DWChar) to High(DWChar) do - begin +Begin + For CurrChar := Low(DWChar) To High(DWChar) Do + Begin {$IFDEF MSWINDOWS} CurrType := 0; GetStringTypeExA(LOCALE_USER_DEFAULT, CT_CTYPE1, @CurrChar, SizeOf(DWChar), CurrType); @@ -420,754 +420,754 @@ procedure LoadCharTypes; {$ENDIF MSWINDOWS} {$IFDEF LINUX} CurrType := 0; - if isupper(Byte(CurrChar)) <> 0 then + If isupper(Byte(CurrChar)) <> 0 Then CurrType := CurrType or C1_UPPER; - if islower(Byte(CurrChar)) <> 0 then + If islower(Byte(CurrChar)) <> 0 Then CurrType := CurrType or C1_LOWER; - if isdigit(Byte(CurrChar)) <> 0 then + If isdigit(Byte(CurrChar)) <> 0 Then CurrType := CurrType or C1_DIGIT; - if isspace(Byte(CurrChar)) <> 0 then + If isspace(Byte(CurrChar)) <> 0 Then CurrType := CurrType or C1_SPACE; - if ispunct(Byte(CurrChar)) <> 0 then + If ispunct(Byte(CurrChar)) <> 0 Then CurrType := CurrType or C1_PUNCT; - if iscntrl(Byte(CurrChar)) <> 0 then + If iscntrl(Byte(CurrChar)) <> 0 Then CurrType := CurrType or C1_CNTRL; - if isblank(Byte(CurrChar)) <> 0 then + If isblank(Byte(CurrChar)) <> 0 Then CurrType := CurrType or C1_BLANK; - if isxdigit(Byte(CurrChar)) <> 0 then + If isxdigit(Byte(CurrChar)) <> 0 Then CurrType := CurrType or C1_XDIGIT; - if isalpha(Byte(CurrChar)) <> 0 then + If isalpha(Byte(CurrChar)) <> 0 Then CurrType := CurrType or C1_ALPHA; {$DEFINE CHAR_TYPES_INITIALIZED} {$ENDIF LINUX} DWCharTypes[CurrChar] := CurrType; - end; -end; + End; +End; {$IFDEF SUPPORTS_UNICODE} //=== { TJclAnsiStrings } ==================================================== -constructor TJclAnsiStrings.Create; -begin - inherited Create; +Constructor TJclAnsiStrings.Create; +Begin + Inherited Create; FDelimiter := ','; FNameValueSeparator := '='; FQuoteChar := '"'; FStrictDelimiter := False; -end; -procedure TJclAnsiStrings.Assign(Source: TPersistent); -var +End; +Procedure TJclAnsiStrings.Assign(Source: TPersistent); +Var StringsSource: TStrings; I: Integer; -begin - if Source is TStrings then - begin +Begin + If Source is TStrings Then + Begin StringsSource := TStrings(Source); BeginUpdate; - try + Try Clear; FDelimiter := DWChar(StringsSource.Delimiter); FNameValueSeparator := DWChar(StringsSource.NameValueSeparator); - for I := 0 to StringsSource.Count - 1 do + For I := 0 To StringsSource.Count - 1 Do AddObject(DWString(StringsSource.Strings[I]), StringsSource.Objects[I]); - finally + Finally EndUpdate; - end; - end - else - inherited Assign(Source); -end; -procedure TJclAnsiStrings.AssignTo(Dest: TPersistent); -var + End; + End + Else + Inherited Assign(Source); +End; +Procedure TJclAnsiStrings.AssignTo(Dest: TPersistent); +Var StringsDest: TStrings; DWStringsDest: TJclAnsiStrings; I: Integer; -begin - if Dest is TStrings then - begin +Begin + If Dest is TStrings Then + Begin StringsDest := TStrings(Dest); StringsDest.BeginUpdate; - try + Try StringsDest.Clear; StringsDest.Delimiter := Char(Delimiter); StringsDest.NameValueSeparator := Char(NameValueSeparator); - for I := 0 to Count - 1 do + For I := 0 To Count - 1 Do StringsDest.AddObject(string(Strings[I]), Objects[I]); - finally + Finally StringsDest.EndUpdate; - end; - end - else - if Dest is TJclAnsiStrings then - begin + End; + End + Else + If Dest is TJclAnsiStrings Then + Begin DWStringsDest := TJclAnsiStrings(Dest); BeginUpdate; - try + Try DWStringsDest.Clear; DWStringsDest.FNameValueSeparator := FNameValueSeparator; DWStringsDest.FDelimiter := FDelimiter; - for I := 0 to Count - 1 do + For I := 0 To Count - 1 Do DWStringsDest.AddObject(Strings[I], Objects[I]); - finally + Finally EndUpdate; - end; - end - else - inherited AssignTo(Dest); -end; -function TJclAnsiStrings.Add(const S: DWString): Integer; -begin + End; + End + Else + Inherited AssignTo(Dest); +End; +Function TJclAnsiStrings.Add(Const S: DWString): Integer; +Begin Result := AddObject(S, nil); -end; -procedure TJclAnsiStrings.AddStrings(Strings: TJclAnsiStrings); -var +End; +Procedure TJclAnsiStrings.AddStrings(Strings: TJclAnsiStrings); +Var I: Integer; -begin - for I := 0 to Strings.Count - 1 do +Begin + For I := 0 To Strings.Count - 1 Do Add(Strings.Strings[I]); -end; -procedure TJclAnsiStrings.Error(const Msg: string; Data: Integer); -begin +End; +Procedure TJclAnsiStrings.Error(Const Msg: string; Data: Integer); +Begin raise EJclAnsiStringListError.CreateFmt(Msg, [Data]); -end; -procedure TJclAnsiStrings.Error(Msg: PResStringRec; Data: Integer); -begin +End; +Procedure TJclAnsiStrings.Error(Msg: PResStringRec; Data: Integer); +Begin Error(LoadResString(Msg), Data); -end; -function TJclAnsiStrings.CompareStrings(const S1, S2: DWString): Integer; -begin +End; +Function TJclAnsiStrings.CompareStrings(Const S1, S2: DWString): Integer; +Begin Result := CompareStr(S1, S2); -end; -procedure TJclAnsiStrings.SetUpdateState(Updating: Boolean); -begin -end; -function TJclAnsiStrings.IndexOf(const S: DWString): Integer; -begin - for Result := 0 to Count - 1 do - if CompareStrings(Strings[Result], S) = 0 then +End; +Procedure TJclAnsiStrings.SetUpdateState(Updating: Boolean); +Begin +End; +Function TJclAnsiStrings.IndexOf(Const S: DWString): Integer; +Begin + For Result := 0 To Count - 1 Do + If CompareStrings(Strings[Result], S) = 0 Then Exit; Result := -1; -end; -function TJclAnsiStrings.IndexOfName(const Name: DWString): Integer; -var +End; +Function TJclAnsiStrings.IndexOfName(Const Name: DWString): Integer; +Var P: Integer; S: DWString; -begin - for Result := 0 to Count - 1 do - begin +Begin + For Result := 0 To Count - 1 Do + Begin S := Strings[Result]; P := AnsiPos(NameValueSeparator, S); - if (P > 0) and (CompareStrings(Copy(S, 1, P - 1), Name) = 0) then + If (P > 0) and (CompareStrings(Copy(S, 1, P - 1), Name) = 0) Then Exit; - end; + End; Result := -1; -end; -function TJclAnsiStrings.IndexOfObject(AObject: TObject): Integer; -begin - for Result := 0 to Count - 1 do - if Objects[Result] = AObject then +End; +Function TJclAnsiStrings.IndexOfObject(AObject: TObject): Integer; +Begin + For Result := 0 To Count - 1 Do + If Objects[Result] = AObject Then Exit; Result := -1; -end; -procedure TJclAnsiStrings.Exchange(Index1, Index2: Integer); -var +End; +Procedure TJclAnsiStrings.Exchange(Index1, Index2: Integer); +Var TempString: DWString; TempObject: TObject; -begin +Begin BeginUpdate; - try + Try TempString := Strings[Index1]; TempObject := Objects[Index1]; Strings[Index1] := Strings[Index2]; Objects[Index1] := Objects[Index2]; Strings[Index2] := TempString; Objects[Index2] := TempObject; - finally + Finally EndUpdate; - end; -end; -procedure TJclAnsiStrings.Insert(Index: Integer; const S: DWString); -begin + End; +End; +Procedure TJclAnsiStrings.Insert(Index: Integer; Const S: DWString); +Begin InsertObject(Index, S, nil); -end; -function TJclAnsiStrings.GetText: DWString; -var +End; +Function TJclAnsiStrings.GetText: DWString; +Var I: Integer; -begin +Begin Result := ''; - for I := 0 to Count - 2 do + For I := 0 To Count - 2 Do Result := Result + Strings[I] + sLineBreak; - if Count > 0 then + If Count > 0 Then Result := Result + Strings[Count - 1] + sLineBreak; -end; -procedure TJclAnsiStrings.SetText(const Value: DWString); -var +End; +Procedure TJclAnsiStrings.SetText(Const Value: DWString); +Var Index, Start, Len: Integer; S: DWString; -begin +Begin Clear; Len := Length(Value); Index := 1; - while Index <= Len do - begin + While Index <= Len Do + Begin Start := Index; - while (Index <= Len) and not CharIsReturn(Value[Index]) do + While (Index <= Len) and not CharIsReturn(Value[Index]) Do Inc(Index); S := Copy(Value, Start, Index - Start); Add(S); - if (Index <= Len) and (Value[Index] = AnsiCarriageReturn) then + If (Index <= Len) and (Value[Index] = AnsiCarriageReturn) Then Inc(Index); - if (Index <= Len) and (Value[Index] = AnsiLineFeed) then + If (Index <= Len) and (Value[Index] = AnsiLineFeed) Then Inc(Index); - end; -end; -function TJclAnsiStrings.GetCapacity: Integer; -begin + End; +End; +Function TJclAnsiStrings.GetCapacity: Integer; +Begin Result := Count; // Might be overridden in derived classes -end; -procedure TJclAnsiStrings.SetCapacity(const Value: Integer); -begin +End; +Procedure TJclAnsiStrings.SetCapacity(Const Value: Integer); +Begin // Nothing at this level -end; -procedure TJclAnsiStrings.BeginUpdate; -begin - if FUpdateCount = 0 then SetUpdateState(True); +End; +Procedure TJclAnsiStrings.BeginUpdate; +Begin + If FUpdateCount = 0 Then SetUpdateState(True); Inc(FUpdateCount); -end; -procedure TJclAnsiStrings.EndUpdate; -begin +End; +Procedure TJclAnsiStrings.EndUpdate; +Begin Dec(FUpdateCount); - if FUpdateCount = 0 then SetUpdateState(False); -end; -procedure TJclAnsiStrings.LoadFromFile(const FileName: TFileName); -var + If FUpdateCount = 0 Then SetUpdateState(False); +End; +Procedure TJclAnsiStrings.LoadFromFile(Const FileName: TFileName); +Var Stream: TStream; -begin +Begin Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); - try + Try LoadFromStream(Stream); - finally + Finally Stream.Free; - end; -end; -procedure TJclAnsiStrings.LoadFromStream(Stream: TStream); -var + End; +End; +Procedure TJclAnsiStrings.LoadFromStream(Stream: TStream); +Var Size: Integer; S: DWString; -begin +Begin BeginUpdate; - try + Try Size := Stream.Size - Stream.Position; System.SetString(S, nil, Size); Stream.Read(PAnsiChar(S)^, Size); SetText(S); - finally + Finally EndUpdate; - end; -end; -procedure TJclAnsiStrings.SaveToFile(const FileName: TFileName); -var + End; +End; +Procedure TJclAnsiStrings.SaveToFile(Const FileName: TFileName); +Var Stream: TStream; -begin +Begin Stream := TFileStream.Create(FileName, fmCreate); - try + Try SaveToStream(Stream); - finally + Finally Stream.Free; - end; -end; -procedure TJclAnsiStrings.SaveToStream(Stream: TStream); -var + End; +End; +Procedure TJclAnsiStrings.SaveToStream(Stream: TStream); +Var S: DWString; -begin +Begin S := GetText; Stream.WriteBuffer(PAnsiChar(S)^, Length(S)); -end; -function TJclAnsiStrings.ExtractName(const S: DWString): DWString; -var +End; +Function TJclAnsiStrings.ExtractName(Const S: DWString): DWString; +Var P: Integer; -begin +Begin Result := S; P := AnsiPos(NameValueSeparator, Result); - if P > 0 then + If P > 0 Then SetLength(Result, P - 1) - else + Else SetLength(Result, 0); -end; -function TJclAnsiStrings.GetName(Index: Integer): DWString; -begin +End; +Function TJclAnsiStrings.GetName(Index: Integer): DWString; +Begin Result := ExtractName(Strings[Index]); -end; -function TJclAnsiStrings.GetValue(const Name: DWString): DWString; -var +End; +Function TJclAnsiStrings.GetValue(Const Name: DWString): DWString; +Var I: Integer; -begin +Begin I := IndexOfName(Name); - if I >= 0 then + If I >= 0 Then Result := Copy(GetString(I), Length(Name) + 2, MaxInt) - else + Else Result := ''; -end; -procedure TJclAnsiStrings.SetValue(const Name, Value: DWString); -var +End; +Procedure TJclAnsiStrings.SetValue(Const Name, Value: DWString); +Var I: Integer; -begin +Begin I := IndexOfName(Name); - if Value <> '' then - begin - if I < 0 then + If Value <> '' Then + Begin + If I < 0 Then I := Add(''); SetString(I, Name + NameValueSeparator + Value); - end - else - begin - if I >= 0 then + End + Else + Begin + If I >= 0 Then Delete(I); - end; -end; -function TJclAnsiStrings.GetValueFromIndex(Index: Integer): DWString; -var + End; +End; +Function TJclAnsiStrings.GetValueFromIndex(Index: Integer): DWString; +Var S: DWString; P: Integer; -begin - if Index >= 0 then - begin +Begin + If Index >= 0 Then + Begin S := Strings[Index]; P := AnsiPos(NameValueSeparator, S); - if P > 0 then + If P > 0 Then Result := Copy(S, P + 1, Length(S) - P) - else + Else Result := ''; - end - else + End + Else Result := ''; -end; -procedure TJclAnsiStrings.SetValueFromIndex(Index: Integer; const Value: DWString); -begin - if Value <> '' then - begin - if Index < 0 then +End; +Procedure TJclAnsiStrings.SetValueFromIndex(Index: Integer; Const Value: DWString); +Begin + If Value <> '' Then + Begin + If Index < 0 Then Index := Add(''); SetString(Index, Names[Index] + NameValueSeparator + Value); - end - else - begin - if Index >= 0 then + End + Else + Begin + If Index >= 0 Then Delete(Index); - end; -end; + End; +End; //=== { TJclAnsiStringList } ================================================= -constructor TJclAnsiStringList.Create; -begin - inherited Create; +Constructor TJclAnsiStringList.Create; +Begin + Inherited Create; FCaseSensitive := True; -end; -destructor TJclAnsiStringList.Destroy; -begin +End; +Destructor TJclAnsiStringList.Destroy; +Begin FOnChange := nil; FOnChanging := nil; - inherited Destroy; -end; -procedure TJclAnsiStringList.Assign(Source: TPersistent); -var + Inherited Destroy; +End; +Procedure TJclAnsiStringList.Assign(Source: TPersistent); +Var StringListSource: TStringList; -begin - if Source is TStringList then - begin +Begin + If Source is TStringList Then + Begin StringListSource := TStringList(Source); FDuplicates := StringListSource.Duplicates; FSorted := StringListSource.Sorted; FCaseSensitive := StringListSource.CaseSensitive; - end; - inherited Assign(Source); -end; -procedure TJclAnsiStringList.AssignTo(Dest: TPersistent); -var + End; + Inherited Assign(Source); +End; +Procedure TJclAnsiStringList.AssignTo(Dest: TPersistent); +Var StringListDest: TStringList; DWStringListDest: TJclAnsiStringList; -begin - if Dest is TStringList then - begin +Begin + If Dest is TStringList Then + Begin StringListDest := TStringList(Dest); StringListDest.Clear; // make following assignments a lot faster StringListDest.Duplicates := FDuplicates; StringListDest.Sorted := FSorted; StringListDest.CaseSensitive := FCaseSensitive; - end - else - if Dest is TJclAnsiStringList then - begin + End + Else + If Dest is TJclAnsiStringList Then + Begin DWStringListDest := TJclAnsiStringList(Dest); DWStringListDest.Clear; DWStringListDest.FDuplicates := FDuplicates; DWStringListDest.FSorted := FSorted; DWStringListDest.FCaseSensitive := FCaseSensitive; - end; - inherited AssignTo(Dest); -end; -function TJclAnsiStringList.CompareStrings(const S1: DWString; const S2: DWString): Integer; -begin - if FCaseSensitive then + End; + Inherited AssignTo(Dest); +End; +Function TJclAnsiStringList.CompareStrings(Const S1: DWString; Const S2: DWString): Integer; +Begin + If FCaseSensitive Then Result := CompareStr(S1, S2) - else + Else Result := CompareText(S1, S2); -end; -procedure TJclAnsiStringList.SetUpdateState(Updating: Boolean); -begin - if Updating then Changing else Changed; -end; -procedure TJclAnsiStringList.Changed; -begin - if (FUpdateCount = 0) and Assigned(FOnChange) then +End; +Procedure TJclAnsiStringList.SetUpdateState(Updating: Boolean); +Begin + If Updating Then Changing Else Changed; +End; +Procedure TJclAnsiStringList.Changed; +Begin + If (FUpdateCount = 0) and Assigned(FOnChange) Then FOnChange(Self); -end; -procedure TJclAnsiStringList.Changing; -begin - if (FUpdateCount = 0) and Assigned(FOnChanging) then +End; +Procedure TJclAnsiStringList.Changing; +Begin + If (FUpdateCount = 0) and Assigned(FOnChanging) Then FOnChanging(Self); -end; -procedure TJclAnsiStringList.Grow; -var +End; +Procedure TJclAnsiStringList.Grow; +Var Delta: Integer; -begin - if Capacity > 64 then +Begin + If Capacity > 64 Then Delta := Capacity div 4 - else if Capacity > 8 then + Else If Capacity > 8 Then Delta := 16 - else + Else Delta := 4; SetCapacity(Capacity + Delta); -end; -function TJclAnsiStringList.GetString(Index: Integer): DWString; -begin - if (Index < 0) or (Index >= FCount) then +End; +Function TJclAnsiStringList.GetString(Index: Integer): DWString; +Begin + If (Index < 0) or (Index >= FCount) Then Error(@SListIndexError, Index); Result := FStrings[Index].Str; -end; -function TJclAnsiStringList.GetObject(Index: Integer): TObject; -begin - if (Index < 0) or (Index >= FCount) then +End; +Function TJclAnsiStringList.GetObject(Index: Integer): TObject; +Begin + If (Index < 0) or (Index >= FCount) Then Error(@SListIndexError, Index); Result := FStrings[Index].Obj; -end; -procedure TJclAnsiStringList.SetObject(Index: Integer; AObject: TObject); -begin - if (Index < 0) or (Index >= FCount) then +End; +Procedure TJclAnsiStringList.SetObject(Index: Integer; AObject: TObject); +Begin + If (Index < 0) or (Index >= FCount) Then Error(@SListIndexError, Index); FStrings[Index].Obj := AObject; -end; -function TJclAnsiStringList.GetCapacity: Integer; -begin +End; +Function TJclAnsiStringList.GetCapacity: Integer; +Begin Result := Length(FStrings); -end; -procedure TJclAnsiStringList.SetCapacity(const Value: Integer); -begin - if (Value < FCount) then +End; +Procedure TJclAnsiStringList.SetCapacity(Const Value: Integer); +Begin + If (Value < FCount) Then Error(@SListCapacityError, Value); - if Value <> Capacity then + If Value <> Capacity Then SetLength(FStrings, Value); -end; -function TJclAnsiStringList.GetCount: Integer; -begin +End; +Function TJclAnsiStringList.GetCount: Integer; +Begin Result := FCount; -end; -procedure TJclAnsiStringList.InsertObject(Index: Integer; const S: DWString; AObject: TObject); -var +End; +Procedure TJclAnsiStringList.InsertObject(Index: Integer; Const S: DWString; AObject: TObject); +Var I: Integer; -begin - if Count = Capacity then +Begin + If Count = Capacity Then Grow; - for I := Count - 1 downto Index do + For I := Count - 1 Downto Index Do FStrings[I + 1] := FStrings[I]; FStrings[Index].Str := S; FStrings[Index].Obj := AObject; Inc(FCount); -end; -procedure TJclAnsiStringList.Delete(Index: Integer); -var +End; +Procedure TJclAnsiStringList.Delete(Index: Integer); +Var I: Integer; -begin - if (Index < 0) or (Index >= FCount) then +Begin + If (Index < 0) or (Index >= FCount) Then Error(@SListIndexError, Index); - for I := Index to Count - 2 do + For I := Index To Count - 2 Do FStrings[I] := FStrings[I + 1]; FStrings[FCount - 1].Str := ''; // the last string is no longer useful Dec(FCount); -end; -procedure TJclAnsiStringList.Clear; -var +End; +Procedure TJclAnsiStringList.Clear; +Var I: Integer; -begin +Begin FCount := 0; - for I := 0 to Length(FStrings) - 1 do - begin + For I := 0 To Length(FStrings) - 1 Do + Begin FStrings[I].Str := ''; FStrings[I].Obj := nil; - end; -end; -function TJclAnsiStringList.Find(const S: DWString; var Index: Integer): Boolean; -var + End; +End; +Function TJclAnsiStringList.Find(Const S: DWString; Var Index: Integer): Boolean; +Var L, H, I, C: Integer; -begin +Begin Result := False; L := 0; H := FCount - 1; - while L <= H do - begin + While L <= H Do + Begin I := (L + H) shr 1; C := CompareStrings(FStrings[I].Str, S); - if C < 0 then + If C < 0 Then L := I + 1 - else - begin + Else + Begin H := I - 1; - if C = 0 then - begin + If C = 0 Then + Begin Result := True; - if Duplicates <> dupAccept then + If Duplicates <> dupAccept Then L := I; - end; - end; - end; + End; + End; + End; Index := L; -end; -function DWStringListCompareStrings(List: TJclAnsiStringList; Index1, Index2: Integer): Integer; -begin +End; +Function DWStringListCompareStrings(List: TJclAnsiStringList; Index1, Index2: Integer): Integer; +Begin Result := List.CompareStrings(List.FStrings[Index1].Str, List.FStrings[Index2].Str); -end; -procedure TJclAnsiStringList.QuickSort(L, R: Integer; SCompare: TJclAnsiStringListSortCompare); -var +End; +Procedure TJclAnsiStringList.QuickSort(L, R: Integer; SCompare: TJclAnsiStringListSortCompare); +Var I, J, P: Integer; -begin - repeat +Begin + Repeat I := L; J := R; P := (L + R) shr 1; - repeat - while SCompare(Self, I, P) < 0 do + Repeat + While SCompare(Self, I, P) < 0 Do Inc(I); - while SCompare(Self, J, P) > 0 do + While SCompare(Self, J, P) > 0 Do Dec(J); - if I <= J then - begin - if I <> J then + If I <= J Then + Begin + If I <> J Then Exchange(I, J); - if P = I then + If P = I Then P := J - else - if P = J then + Else + If P = J Then P := I; Inc(I); Dec(J); - end; - until I > J; - if L < J then + End; + Until I > J; + If L < J Then QuickSort(L, J, SCompare); L := I; - until I >= R; -end; + Until I >= R; +End; {$ENDIF SUPPORTS_UNICODE} -function StrContainsChars(const S: DWString; Chars: TSysCharSet; CheckAll: Boolean): Boolean; -var +Function StrContainsChars(Const S: DWString; Chars: TSysCharSet; CheckAll: Boolean): Boolean; +Var I: SizeInt; C: DWChar; -begin +Begin Result := Chars = []; - if not Result then - begin - if CheckAll then - begin - for I := 1 to Length(S) do - begin + If not Result Then + Begin + If CheckAll Then + Begin + For I := 1 To Length(S) Do + Begin PDWString(@C)^ := Char(S[I]); - if C in Chars then - begin + If C in Chars Then + Begin Chars := Chars - [C]; - if Chars = [] then + If Chars = [] Then Break; - end; - end; + End; + End; Result := (Chars = []); - end - else - begin - for I := 1 to Length(S) do - if S[I] in Chars then - begin + End + Else + Begin + For I := 1 To Length(S) Do + If S[I] in Chars Then + Begin Result := True; Break; - end; - end; - end; -end; -function StrIsSubset(const S: DWString; const ValidChars: TSysCharSet): Boolean; -var + End; + End; + End; +End; +Function StrIsSubset(Const S: DWString; Const ValidChars: TSysCharSet): Boolean; +Var I: SizeInt; -begin - for I := 1 to Length(S) do - begin - if not (S[I] in ValidChars) then - begin +Begin + For I := 1 To Length(S) Do + Begin + If not (S[I] in ValidChars) Then + Begin Result := False; Exit; - end; - end; + End; + End; Result := True and (Length(S) > 0); -end; -function StrSame(const S1, S2: DWString): Boolean; -begin +End; +Function StrSame(Const S1, S2: DWString): Boolean; +Begin Result := StrCompare(S1, S2) = 0; -end; +End; //=== String Transformation Routines ========================================= -function StrCenter(const S: DWString; L: SizeInt; C: DWChar = ' '): DWString; -begin - if Length(S) < L then - begin +Function StrCenter(Const S: DWString; L: SizeInt; C: DWChar = ' '): DWString; +Begin + If Length(S) < L Then + Begin Result := StringOfChar(C, (L - Length(S)) div 2) + S; Result := Result + StringOfChar(C, L - Length(Result)); - end - else + End + Else Result := S; -end; -function StrCharPosLower(const S: DWString; CharPos: SizeInt): DWString; -begin +End; +Function StrCharPosLower(Const S: DWString; CharPos: SizeInt): DWString; +Begin Result := S; - if (CharPos > 0) and (CharPos <= Length(S)) then + If (CharPos > 0) and (CharPos <= Length(S)) Then PDWString(@Result[CharPos])^ := CharLower(Result[CharPos]); -end; -function StrCharPosUpper(const S: DWString; CharPos: SizeInt): DWString; -begin +End; +Function StrCharPosUpper(Const S: DWString; CharPos: SizeInt): DWString; +Begin Result := S; - if (CharPos > 0) and (CharPos <= Length(S)) then + If (CharPos > 0) and (CharPos <= Length(S)) Then PDWString(@Result[CharPos])^ := CharUpper(Result[CharPos]); -end; -function StrDoubleQuote(const S: DWString): DWString; -begin +End; +Function StrDoubleQuote(Const S: DWString): DWString; +Begin Result := AnsiDoubleQuote + S + AnsiDoubleQuote; -end; -function StrEnsureNoPrefix(const Prefix, Text: DWString): DWString; -var +End; +Function StrEnsureNoPrefix(Const Prefix, Text: DWString): DWString; +Var PrefixLen: SizeInt; -begin +Begin PrefixLen := Length(Prefix); - if Copy(Text, 1, PrefixLen) = Prefix then + If Copy(Text, 1, PrefixLen) = Prefix Then Result := Copy(Text, PrefixLen + 1, Length(Text)) - else + Else Result := Text; -end; -function StrEnsureNoSuffix(const Suffix, Text: DWString): DWString; -var +End; +Function StrEnsureNoSuffix(Const Suffix, Text: DWString): DWString; +Var SuffixLen: SizeInt; StrLength: SizeInt; -begin +Begin SuffixLen := Length(Suffix); StrLength := Length(Text); - if Copy(Text, StrLength - SuffixLen + 1, SuffixLen) = Suffix then + If Copy(Text, StrLength - SuffixLen + 1, SuffixLen) = Suffix Then Result := Copy(Text, 1, StrLength - SuffixLen) - else + Else Result := Text; -end; -function StrEnsurePrefix(const Prefix, Text: DWString): DWString; -var +End; +Function StrEnsurePrefix(Const Prefix, Text: DWString): DWString; +Var PrefixLen: SizeInt; -begin +Begin PrefixLen := Length(Prefix); - if Copy(Text, 1, PrefixLen) = Prefix then + If Copy(Text, 1, PrefixLen) = Prefix Then Result := Text - else + Else Result := Prefix + Text; -end; -function StrEnsureSuffix(const Suffix, Text: DWString): DWString; -var +End; +Function StrEnsureSuffix(Const Suffix, Text: DWString): DWString; +Var SuffixLen: SizeInt; -begin +Begin SuffixLen := Length(Suffix); - if Copy(Text, Length(Text) - SuffixLen + 1, SuffixLen) = Suffix then + If Copy(Text, Length(Text) - SuffixLen + 1, SuffixLen) = Suffix Then Result := Text - else + Else Result := Text + Suffix; -end; -function StrEscapedToString(const S: DWString): DWString; - procedure HandleHexEscapeSeq(const S: DWString; var I: SizeInt; Len: SizeInt; var Dest: DWString); - const +End; +Function StrEscapedToString(Const S: DWString): DWString; + Procedure HandleHexEscapeSeq(Const S: DWString; Var I: SizeInt; Len: SizeInt; Var Dest: DWString); + Const HexDigits = DWString('0123456789abcdefABCDEF'); - var + Var StartI, Val, N: SizeInt; - begin + Begin StartI := I; N := Pos(S[I + 1], HexDigits) - 1; - if N < 0 then + If N < 0 Then // '\x' without hex digit following is not escape sequence Dest := Dest + '\x' - else - begin + Else + Begin Inc(I); // Jump over x - if N >= 16 then + If N >= 16 Then N := N - 6; Val := N; // Same for second digit - if I < Len then - begin + If I < Len Then + Begin N := Pos(S[I + 1], HexDigits) - 1; - if N >= 0 then - begin + If N >= 0 Then + Begin Inc(I); // Jump over first digit - if N >= 16 then + If N >= 16 Then N := N - 6; Val := Val * 16 + N; - end; - end; - if Val > Ord(High(DWChar)) then + End; + End; + If Val > Ord(High(DWChar)) Then raise EJclAnsiStringError.CreateResFmt(@RsNumericConstantTooLarge, [Val, StartI]); Dest := Dest + DWChar(Val); - end; - end; - procedure HandleOctEscapeSeq(const S: DWString; var I: SizeInt; Len: SizeInt; var Dest: DWString); - const + End; + End; + Procedure HandleOctEscapeSeq(Const S: DWString; Var I: SizeInt; Len: SizeInt; Var Dest: DWString); + Const OctDigits = DWString('01234567'); - var + Var StartI, Val, N: SizeInt; - begin + Begin StartI := I; // first digit Val := Pos(S[I], OctDigits) - 1; - if I < Len then - begin + If I < Len Then + Begin N := Pos(S[I + 1], OctDigits) - 1; - if N >= 0 then - begin + If N >= 0 Then + Begin Inc(I); Val := Val * 8 + N; - end; - if I < Len then - begin + End; + If I < Len Then + Begin N := Pos(S[I + 1], OctDigits) - 1; - if N >= 0 then - begin + If N >= 0 Then + Begin Inc(I); Val := Val * 8 + N; - end; - end; - end; - if Val > Ord(High(DWChar)) then + End; + End; + End; + If Val > Ord(High(DWChar)) Then raise EJclAnsiStringError.CreateResFmt(@RsNumericConstantTooLarge, [Val, StartI]); Dest := Dest + DWChar(Val); - end; -var + End; +Var I, Len: SizeInt; -begin +Begin Result := ''; I := 1; Len := Length(S); - while I <= Len do - begin - if not ((S[I] = '\') and (I < Len)) then + While I <= Len Do + Begin + If not ((S[I] = '\') and (I < Len)) Then Result := Result + S[I] - else - begin + Else + Begin Inc(I); // Jump over escape character - case S[I] of + Case S[I] Of 'a': Result := Result + AnsiBell; 'b': @@ -1191,126 +1191,126 @@ function StrEscapedToString(const S: DWString): DWString; '?': Result := Result + '?'; // Optionally escaped 'x': - if I < Len then + If I < Len Then // Start of hex escape sequence HandleHexEscapeSeq(S, I, Len, Result) - else + Else // '\x' at end of DWString is not escape sequence Result := Result + '\x'; '0'..'7': // start of octal escape sequence HandleOctEscapeSeq(S, I, Len, Result); - else + Else // no escape sequence Result := Result + '\' + S[I]; - end; - end; + End; + End; Inc(I); - end; -end; -procedure StrMove(var Dest: DWString; const Source: DWString; - const ToIndex, FromIndex, Count: SizeInt); -begin + End; +End; +Procedure StrMove(Var Dest: DWString; Const Source: DWString; + Const ToIndex, FromIndex, Count: SizeInt); +Begin // Check strings - if (Source = '') or (Length(Dest) = 0) then + If (Source = '') or (Length(Dest) = 0) Then Exit; // Check FromIndex - if (FromIndex <= 0) or (FromIndex > Length(Source)) or + If (FromIndex <= 0) or (FromIndex > Length(Source)) or (ToIndex <= 0) or (ToIndex > Length(Dest)) or - ((FromIndex + Count - 1) > Length(Source)) or ((ToIndex + Count - 1) > Length(Dest)) then + ((FromIndex + Count - 1) > Length(Source)) or ((ToIndex + Count - 1) > Length(Dest)) Then { TODO : Is failure without notice the proper thing to do here? } Exit; // Move Move(Source[FromIndex], Dest[ToIndex], Count); -end; -function StrPadLeft(const S: DWString; Len: SizeInt; C: DWChar): DWString; -var +End; +Function StrPadLeft(Const S: DWString; Len: SizeInt; C: DWChar): DWString; +Var L: SizeInt; -begin +Begin L := Length(S); - if L < Len then + If L < Len Then Result := StringOfChar(C, Len - L) + S - else + Else Result := S; -end; -function StrPadRight(const S: DWString; Len: SizeInt; C: DWChar): DWString; -var +End; +Function StrPadRight(Const S: DWString; Len: SizeInt; C: DWChar): DWString; +Var L: SizeInt; -begin +Begin L := Length(S); - if L < Len then + If L < Len Then Result := S + StringOfChar(C, Len - L) - else + Else Result := S; -end; -function StrProper(const S: DWString): DWString; -begin +End; +Function StrProper(Const S: DWString): DWString; +Begin Result := StrLower(S); - if Result <> '' then + If Result <> '' Then Result[1] := UpCase(Result[1]); -end; -function StrQuote(const S: DWString; C: DWChar): DWString; -var +End; +Function StrQuote(Const S: DWString; C: DWChar): DWString; +Var L: SizeInt; -begin +Begin L := Length(S); Result := S; - if L > 0 then - begin - if PDWString(@Result[1])^ <> C then - begin + If L > 0 Then + Begin + If PDWString(@Result[1])^ <> C Then + Begin Result := C + Result; Inc(L); - end; - if PDWString(@Result[L])^ <> C then + End; + If PDWString(@Result[L])^ <> C Then Result := Result + C; - end; -end; -function StrReplaceChar(const S: DWString; const Source, Replace: DWChar): DWString; -var + End; +End; +Function StrReplaceChar(Const S: DWString; Const Source, Replace: DWChar): DWString; +Var I: SizeInt; -begin +Begin Result := S; - for I := 1 to Length(S) do - if PDWString(@Result[I])^ = Source then + For I := 1 To Length(S) Do + If PDWString(@Result[I])^ = Source Then PDWString(@Result[I])^ := Replace; -end; -function StrReplaceChars(const S: DWString; const Chars: TSysCharSet; Replace: DWChar): DWString; -var +End; +Function StrReplaceChars(Const S: DWString; Const Chars: TSysCharSet; Replace: DWChar): DWString; +Var I: SizeInt; -begin +Begin Result := S; - for I := 1 to Length(S) do - if Result[I] in Chars then + For I := 1 To Length(S) Do + If Result[I] in Chars Then PDWString(@Result[I])^ := Replace; -end; -function StrReplaceButChars(const S: DWString; const Chars: TSysCharSet; +End; +Function StrReplaceButChars(Const S: DWString; Const Chars: TSysCharSet; Replace: DWChar): DWString; -var +Var I: SizeInt; -begin +Begin Result := S; - for I := 1 to Length(S) do - if not (Result[I] in Chars) then + For I := 1 To Length(S) Do + If not (Result[I] in Chars) Then PDWString(@Result[I])^ := Replace; -end; -function StrSingleQuote(const S: DWString): DWString; -begin +End; +Function StrSingleQuote(Const S: DWString): DWString; +Begin Result := AnsiSingleQuote + S + AnsiSingleQuote; -end; -procedure StrSkipChars(const S: DWString; var Index: SizeInt; const Chars: TSysCharSet); -begin - while S[Index] in Chars do +End; +Procedure StrSkipChars(Const S: DWString; Var Index: SizeInt; Const Chars: TSysCharSet); +Begin + While S[Index] in Chars Do Inc(Index); -end; -function StrStringToEscaped(const S: DWString): DWString; -var +End; +Function StrStringToEscaped(Const S: DWString): DWString; +Var I: SizeInt; -begin +Begin Result := ''; - for I := 1 to Length(S) do - begin - case S[I] of + For I := 1 To Length(S) Do + Begin + Case S[I] Of AnsiBackspace: Result := Result + '\b'; AnsiBell: @@ -1329,224 +1329,224 @@ function StrStringToEscaped(const S: DWString): DWString; Result := Result + '\\'; '"': Result := Result + '\"'; - else + Else // Characters < ' ' are escaped with hex sequence - if S[I] < #32 then + If S[I] < #32 Then Result := Result + DWString(Format('\x%.2x', [SizeInt(S[I])])) - else + Else Result := Result + S[I]; - end; - end; -end; -function StrToHex(const Source: DWString): DWString; -var + End; + End; +End; +Function StrToHex(Const Source: DWString): DWString; +Var Index: SizeInt; C, L, N: SizeInt; BL, BH: Byte; S: DWString; -begin +Begin Result := ''; - if Source <> '' then - begin + If Source <> '' Then + Begin S := Source; L := Length(S); - if Odd(L) then - begin + If Odd(L) Then + Begin S := '0' + S; Inc(L); - end; + End; Index := 1; SetLength(Result, L div 2); C := 1; N := 1; - while C <= L do - begin + While C <= L Do + Begin BH := CharHex(S[Index]); Inc(Index); BL := CharHex(S[Index]); Inc(Index); Inc(C, 2); - if (BH = $FF) or (BL = $FF) then - begin + If (BH = $FF) or (BL = $FF) Then + Begin Result := ''; Exit; - end; + End; PDWString(@Result[N])^ := DWChar((Cardinal(BH) shl 4) or Cardinal(BL)); Inc(N); - end; - end; -end; -function StrTrimCharLeft(const S: DWString; C: DWChar): DWString; -var + End; + End; +End; +Function StrTrimCharLeft(Const S: DWString; C: DWChar): DWString; +Var I, L: SizeInt; -begin +Begin I := 1; L := Length(S); - while (I <= L) and (PDWString(@S[I])^ = C) do + While (I <= L) and (PDWString(@S[I])^ = C) Do Inc(I); Result := Copy(S, I, L - I + 1); -end; -function StrTrimCharsLeft(const S: DWString; const Chars: TSysCharSet): DWString; -var +End; +Function StrTrimCharsLeft(Const S: DWString; Const Chars: TSysCharSet): DWString; +Var I, L: SizeInt; -begin +Begin I := 1; L := Length(S); - while (I <= L) and (S[I] in Chars) do + While (I <= L) and (S[I] in Chars) Do Inc(I); Result := Copy(S, I, L - I + 1); -end; -function StrTrimCharsRight(const S: DWString; const Chars: TSysCharSet): DWString; -var +End; +Function StrTrimCharsRight(Const S: DWString; Const Chars: TSysCharSet): DWString; +Var I: SizeInt; -begin +Begin I := Length(S); - while (I >= 1) and (S[I] in Chars) do + While (I >= 1) and (S[I] in Chars) Do Dec(I); Result := Copy(S, 1, I); -end; -function StrTrimCharRight(const S: DWString; C: DWChar): DWString; -var +End; +Function StrTrimCharRight(Const S: DWString; C: DWChar): DWString; +Var I: SizeInt; -begin +Begin I := Length(S); - while (I >= 1) and (PDWString(@S[I])^ = C) do + While (I >= 1) and (PDWString(@S[I])^ = C) Do Dec(I); Result := Copy(S, 1, I); -end; -function StrTrimQuotes(const S: DWString): DWString; -var +End; +Function StrTrimQuotes(Const S: DWString): DWString; +Var First, Last: DWChar; L: SizeInt; -begin +Begin L := Length(S); - if L > 1 then - begin + If L > 1 Then + Begin PDWString(@First)^ := S[1]; PDWString(@Last)^ := S[L]; - if (First = Last) and ((First = AnsiSingleQuote) or (First = AnsiDoubleQuote)) then + If (First = Last) and ((First = AnsiSingleQuote) or (First = AnsiDoubleQuote)) Then Result := Copy(S, 2, L - 2) - else + Else Result := S; - end - else + End + Else Result := S; -end; -function StrTrimQuotes(const S: DWString; QuoteChar: DWChar): DWString; -var +End; +Function StrTrimQuotes(Const S: DWString; QuoteChar: DWChar): DWString; +Var First, Last: DWChar; L: SizeInt; -begin +Begin L := Length(S); - if L > 1 then - begin + If L > 1 Then + Begin PDWString(@First)^ := S[1]; PDWString(@Last)^ := S[L]; - if (First = Last) and (First = QuoteChar) then + If (First = Last) and (First = QuoteChar) Then Result := Copy(S, 2, L - 2) - else + Else Result := S; - end - else + End + Else Result := S; -end; -procedure StrDecRef(var S: DWString); -var +End; +Procedure StrDecRef(Var S: DWString); +Var P: PAnsiStrRec; -begin +Begin P := Pointer(S); - if P <> nil then - begin + If P <> nil Then + Begin Dec(P); - case P^.RefCount of + Case P^.RefCount Of -1, 0: { nothing } ; 1: - begin + Begin Finalize(S); Pointer(S) := nil; - end; + End; // else // LockedDec(P^.RefCount); - end; - end; -end; -function StrLength(const S: DWString): Longint; -var + End; + End; +End; +Function StrLength(Const S: DWString): Longint; +Var P: PAnsiStrRec; -begin +Begin Result := 0; P := Pointer(S); - if P <> nil then - begin + If P <> nil Then + Begin Dec(P); Result := P^.Length and (not $80000000 shr 1); - end; -end; -function StrRefCount(const S: DWString): Longint; -var + End; +End; +Function StrRefCount(Const S: DWString): Longint; +Var P: PAnsiStrRec; -begin +Begin Result := 0; P := Pointer(S); - if P <> nil then - begin + If P <> nil Then + Begin Dec(P); Result := P^.RefCount; - end; -end; -procedure StrResetLength(var S: DWString); -var + End; +End; +Procedure StrResetLength(Var S: DWString); +Var I: SizeInt; -begin - for I := 0 to Length(S) - 1 do - if S[I + 1] = #0 then - begin +Begin + For I := 0 To Length(S) - 1 Do + If S[I + 1] = #0 Then + Begin SetLength(S, I); Exit; - end; -end; + End; +End; //=== String Search and Replace Routines ===================================== -function StrCharCount(const S: DWString; C: DWChar): SizeInt; -var +Function StrCharCount(Const S: DWString; C: DWChar): SizeInt; +Var I: SizeInt; -begin +Begin Result := 0; - for I := 1 to Length(S) do - if PDWString(@S[I])^ = C then + For I := 1 To Length(S) Do + If PDWString(@S[I])^ = C Then Inc(Result); -end; -function StrCharsCount(const S: DWString; Chars: TSysCharSet): SizeInt; -var +End; +Function StrCharsCount(Const S: DWString; Chars: TSysCharSet): SizeInt; +Var I: SizeInt; -begin +Begin Result := 0; - for I := 1 to Length(S) do - if S[I] in Chars then + For I := 1 To Length(S) Do + If S[I] in Chars Then Inc(Result); -end; -function StrStrCount(const S, SubS: DWString): SizeInt; -var +End; +Function StrStrCount(Const S, SubS: DWString): SizeInt; +Var I: SizeInt; -begin +Begin Result := 0; - if (Length(SubS) > Length(S)) or (Length(SubS) = 0) or (Length(S) = 0) then + If (Length(SubS) > Length(S)) or (Length(SubS) = 0) or (Length(S) = 0) Then Exit; - if Length(SubS) = 1 then - begin + If Length(SubS) = 1 Then + Begin Result := StrCharCount(S, SubS[1]); Exit; - end; + End; I := StrSearch(SubS, S, 1); - if I > 0 then + If I > 0 Then Inc(Result); - while (I > 0) and (Length(S) > I + Length(SubS)) do - begin + While (I > 0) and (Length(S) > I + Length(SubS)) Do + Begin I := StrSearch(SubS, S, I + 1); - if I > 0 then + If I > 0 Then Inc(Result); - end; -end; + End; +End; (* { 1} Test(StrCompareRange('', '', 1, 5), 0); { 2} Test(StrCompareRange('A', '', 1, 5), -1); @@ -1569,672 +1569,672 @@ function StrStrCount(const S, SubS: DWString): SizeInt; {19} Test(StrCompareRange('Aa', 'A', 1, 2), 0); {20} Test(StrCompareRange('Ba', 'A', 1, 2), 1); *) -function StrCompareRangeEx(const S1, S2: DWString; Index, Count: SizeInt; CaseSensitive: Boolean): SizeInt; -var +Function StrCompareRangeEx(Const S1, S2: DWString; Index, Count: SizeInt; CaseSensitive: Boolean): SizeInt; +Var Len1, Len2: SizeInt; I: SizeInt; C1, C2: DWChar; -begin - if Pointer(S1) = Pointer(S2) then - begin - if (Count <= 0) and (S1 <> '') then +Begin + If Pointer(S1) = Pointer(S2) Then + Begin + If (Count <= 0) and (S1 <> '') Then Result := -2 // no work - else + Else Result := 0; - end - else - if (S1 = '') or (S2 = '') then + End + Else + If (S1 = '') or (S2 = '') Then Result := -1 // null string - else - if Count <= 0 then + Else + If Count <= 0 Then Result := -2 // no work - else - begin + Else + Begin Len1 := Length(S1); Len2 := Length(S2); - if (Index - 1) + Count > Len1 then + If (Index - 1) + Count > Len1 Then Result := -2 - else - begin - if (Index - 1) + Count > Len2 then // strange behaviour, but the assembler code does it + Else + Begin + If (Index - 1) + Count > Len2 Then // strange behaviour, but the assembler code does it Count := Len2 - (Index - 1); - if CaseSensitive then - begin - for I := 0 to Count - 1 do - begin + If CaseSensitive Then + Begin + For I := 0 To Count - 1 Do + Begin PDWString(@C1)^ := S1[Index + I]; PDWString(@C2)^ := S2[Index + I]; - if C1 <> C2 then - begin + If C1 <> C2 Then + Begin Result := Ord(C1) - Ord(C2); Exit; - end; - end; - end - else - begin - for I := 0 to Count - 1 do - begin + End; + End; + End + Else + Begin + For I := 0 To Count - 1 Do + Begin PDWString(@C1)^ := S1[Index + I]; PDWString(@C2)^ := S2[Index + I]; - if C1 <> C2 then - begin + If C1 <> C2 Then + Begin C1 := CharLower(C1); C2 := CharLower(C2); - if C1 <> C2 then - begin + If C1 <> C2 Then + Begin Result := Ord(C1) - Ord(C2); Exit; - end; - end; - end; - end; + End; + End; + End; + End; Result := 0; - end; - end; -end; -function StrCompare(const S1, S2: DWString; CaseSensitive: Boolean): SizeInt; -var + End; + End; +End; +Function StrCompare(Const S1, S2: DWString; CaseSensitive: Boolean): SizeInt; +Var Len1, Len2: SizeInt; -begin - if Pointer(S1) = Pointer(S2) then +Begin + If Pointer(S1) = Pointer(S2) Then Result := 0 - else - begin + Else + Begin Len1 := Length(S1); Len2 := Length(S2); Result := Len1 - Len2; - if Result = 0 then + If Result = 0 Then Result := StrCompareRangeEx(S1, S2, 1, Len1, CaseSensitive); - end; -end; -function StrCompareRange(const S1, S2: DWString; Index, Count: SizeInt; CaseSensitive: Boolean): SizeInt; -begin + End; +End; +Function StrCompareRange(Const S1, S2: DWString; Index, Count: SizeInt; CaseSensitive: Boolean): SizeInt; +Begin Result := StrCompareRangeEx(S1, S2, Index, Count, CaseSensitive); -end; -function StrRepeatChar(C: DWChar; Count: SizeInt): DWString; -begin +End; +Function StrRepeatChar(C: DWChar; Count: SizeInt): DWString; +Begin SetLength(Result, Count); - if Count > 0 then + If Count > 0 Then FillChar(Result[1], Count, C); -end; -function StrFind(const Substr, S: DWString; const Index: SizeInt): SizeInt; -var +End; +Function StrFind(Const Substr, S: DWString; Const Index: SizeInt): SizeInt; +Var pos: SizeInt; -begin - if (SubStr <> '') and (S <> '') then - begin +Begin + If (SubStr <> '') and (S <> '') Then + Begin pos := StrIPos(Substr, Copy(S, Index, Length(S) - Index + 1)); - if pos = 0 then + If pos = 0 Then Result := 0 - else + Else Result := Index + Pos - 1; - end - else + End + Else Result := 0; -end; -function StrHasPrefix(const S: DWString; const Prefixes: array of DWString): Boolean; -begin +End; +Function StrHasPrefix(Const S: DWString; Const Prefixes: array Of DWString): Boolean; +Begin Result := StrPrefixIndex(S, Prefixes) > -1; -end; -function StrHasSuffix(const S: DWString; const Suffixes: array of DWString): Boolean; -begin +End; +Function StrHasSuffix(Const S: DWString; Const Suffixes: array Of DWString): Boolean; +Begin Result := StrSuffixIndex(S, Suffixes) > -1; -end; -function StrIHasPrefix(const S: DWString; const Prefixes: array of DWString): Boolean; -begin +End; +Function StrIHasPrefix(Const S: DWString; Const Prefixes: array Of DWString): Boolean; +Begin Result := StrIPrefixIndex(S, Prefixes) > -1; -end; -function StrIHasSuffix(const S: DWString; const Suffixes: array of DWString): Boolean; -begin +End; +Function StrIHasSuffix(Const S: DWString; Const Suffixes: array Of DWString): Boolean; +Begin Result := StrISuffixIndex(S, Suffixes) > -1; -end; -function StrIndex(const S: DWString; const List: array of DWString; CaseSensitive: Boolean): SizeInt; -var +End; +Function StrIndex(Const S: DWString; Const List: array Of DWString; CaseSensitive: Boolean): SizeInt; +Var I: SizeInt; -begin +Begin Result := -1; - for I := Low(List) to High(List) do - begin - if StrCompare(S, List[I], CaseSensitive) = 0 then - begin + For I := Low(List) To High(List) Do + Begin + If StrCompare(S, List[I], CaseSensitive) = 0 Then + Begin Result := I; Break; - end; - end; -end; -function StrILastPos(const SubStr, S: DWString): SizeInt; -begin + End; + End; +End; +Function StrILastPos(Const SubStr, S: DWString): SizeInt; +Begin Result := StrLastPos(StrUpper(SubStr), StrUpper(S)); -end; -function StrIPos(const SubStr, S: DWString): SizeInt; -begin +End; +Function StrIPos(Const SubStr, S: DWString): SizeInt; +Begin Result := Pos(StrUpper(SubStr), StrUpper(S)); -end; -function StrIPrefixIndex(const S: DWString; const Prefixes: array of DWString): SizeInt; -var +End; +Function StrIPrefixIndex(Const S: DWString; Const Prefixes: array Of DWString): SizeInt; +Var I: SizeInt; Test: DWString; -begin +Begin Result := -1; - for I := Low(Prefixes) to High(Prefixes) do - begin + For I := Low(Prefixes) To High(Prefixes) Do + Begin Test := StrLeft(S, Length(Prefixes[I])); - if CompareText(Test, Prefixes[I]) = 0 then - begin + If CompareText(Test, Prefixes[I]) = 0 Then + Begin Result := I; Break; - end; - end; -end; -function StrIsOneOf(const S: DWString; const List: array of DWString): Boolean; -begin + End; + End; +End; +Function StrIsOneOf(Const S: DWString; Const List: array Of DWString): Boolean; +Begin Result := StrIndex(S, List) > -1; -end; -function StrISuffixIndex(const S: DWString; const Suffixes: array of DWString): SizeInt; -var +End; +Function StrISuffixIndex(Const S: DWString; Const Suffixes: array Of DWString): SizeInt; +Var I: SizeInt; Test: DWString; -begin +Begin Result := -1; - for I := Low(Suffixes) to High(Suffixes) do - begin + For I := Low(Suffixes) To High(Suffixes) Do + Begin Test := StrRight(S, Length(Suffixes[I])); - if CompareText(Test, Suffixes[I]) = 0 then - begin + If CompareText(Test, Suffixes[I]) = 0 Then + Begin Result := I; Break; - end; - end; -end; + End; + End; +End; // IMPORTANT NOTE: The StrMatch function does currently not work with the Asterix (*) // (*) acts like (?) -function StrMatch(const Substr, S: DWString; Index: SizeInt): SizeInt; -var +Function StrMatch(Const Substr, S: DWString; Index: SizeInt): SizeInt; +Var SI, SubI, SLen, SubLen: SizeInt; SubC: DWChar; -begin +Begin SLen := Length(S); SubLen := Length(Substr); Result := 0; - if (Index > SLen) or (SubLen = 0) then + If (Index > SLen) or (SubLen = 0) Then Exit; - while Index <= SLen do - begin + While Index <= SLen Do + Begin SubI := 1; SI := Index; - while (SI <= SLen) and (SubI <= SubLen) do - begin + While (SI <= SLen) and (SubI <= SubLen) Do + Begin PDWString(@SubC)^ := Substr[SubI]; - if (SubC = '*') or (SubC = '?') or (PDWString(@SubC)^ = S[SI]) then - begin + If (SubC = '*') or (SubC = '?') or (PDWString(@SubC)^ = S[SI]) Then + Begin Inc(SI); Inc(SubI); - end - else + End + Else Break; - end; - if SubI > SubLen then - begin + End; + If SubI > SubLen Then + Begin Result := Index; Break; - end; + End; Inc(Index); - end; -end; + End; +End; -function StrNPos(const S, SubStr: DWString; N: SizeInt): SizeInt; -var +Function StrNPos(Const S, SubStr: DWString; N: SizeInt): SizeInt; +Var I, P: SizeInt; -begin - if N < 1 then - begin +Begin + If N < 1 Then + Begin Result := 0; Exit; - end; + End; Result := StrSearch(SubStr, S, 1); I := 1; - while I < N do - begin + While I < N Do + Begin P := StrSearch(SubStr, S, Result + 1); - if P = 0 then - begin + If P = 0 Then + Begin Result := 0; Break; - end - else - begin + End + Else + Begin Result := P; Inc(I); - end; - end; -end; -function StrNIPos(const S, SubStr: DWString; N: SizeInt): SizeInt; -var + End; + End; +End; +Function StrNIPos(Const S, SubStr: DWString; N: SizeInt): SizeInt; +Var I, P: SizeInt; -begin - if N < 1 then - begin +Begin + If N < 1 Then + Begin Result := 0; Exit; - end; + End; Result := StrFind(SubStr, S, 1); I := 1; - while I < N do - begin + While I < N Do + Begin P := StrFind(SubStr, S, Result + 1); - if P = 0 then - begin + If P = 0 Then + Begin Result := 0; Break; - end - else - begin + End + Else + Begin Result := P; Inc(I); - end; - end; -end; -function StrPrefixIndex(const S: DWString; const Prefixes: array of DWString): SizeInt; -var + End; + End; +End; +Function StrPrefixIndex(Const S: DWString; Const Prefixes: array Of DWString): SizeInt; +Var I: SizeInt; Test: DWString; -begin +Begin Result := -1; - for I := Low(Prefixes) to High(Prefixes) do - begin + For I := Low(Prefixes) To High(Prefixes) Do + Begin Test := StrLeft(S, Length(Prefixes[I])); - if CompareStr(Test, Prefixes[I]) = 0 then - begin + If CompareStr(Test, Prefixes[I]) = 0 Then + Begin Result := I; Break; - end; - end; -end; -function StrSuffixIndex(const S: DWString; const Suffixes: array of DWString): SizeInt; -var + End; + End; +End; +Function StrSuffixIndex(Const S: DWString; Const Suffixes: array Of DWString): SizeInt; +Var I: SizeInt; Test: DWString; -begin +Begin Result := -1; - for I := Low(Suffixes) to High(Suffixes) do - begin + For I := Low(Suffixes) To High(Suffixes) Do + Begin Test := StrRight(S, Length(Suffixes[I])); - if CompareStr(Test, Suffixes[I]) = 0 then - begin + If CompareStr(Test, Suffixes[I]) = 0 Then + Begin Result := I; Break; - end; - end; -end; + End; + End; +End; //=== String Extraction ====================================================== -function StrAfter(const SubStr, S: DWString): DWString; -var +Function StrAfter(Const SubStr, S: DWString): DWString; +Var P: SizeInt; -begin +Begin P := StrFind(SubStr, S, 1); // StrFind is case-insensitive pos - if P <= 0 then + If P <= 0 Then Result := '' // substr not found -> nothing after it - else + Else Result := StrRestOf(S, P + Length(SubStr)); -end; -function StrBefore(const SubStr, S: DWString): DWString; -var +End; +Function StrBefore(Const SubStr, S: DWString): DWString; +Var P: SizeInt; -begin +Begin P := StrFind(SubStr, S, 1); - if P <= 0 then + If P <= 0 Then Result := S - else + Else Result := StrLeft(S, P - 1); -end; -function StrSplit(const SubStr, S: DWString;var Left, Right : DWString): boolean; -var +End; +Function StrSplit(Const SubStr, S: DWString;Var Left, Right : DWString): boolean; +Var P: SizeInt; -begin +Begin P := StrFind(SubStr, S, 1); Result:= p > 0; - if Result then - begin + If Result Then + Begin Left := StrLeft(S, P - 1); Right := StrRestOf(S, P + Length(SubStr)); - end - else - begin + End + Else + Begin Left := ''; Right := ''; - end; -end; -function StrBetween(const S: DWString; const Start, Stop: DWChar): DWString; -var + End; +End; +Function StrBetween(Const S: DWString; Const Start, Stop: DWChar): DWString; +Var PosStart, PosEnd: SizeInt; L: SizeInt; -begin +Begin PosStart := Pos(Start, S); PosEnd := StrSearch(Stop, S, PosStart + 1); // PosEnd has to be after PosStart. - if (PosStart > 0) and (PosEnd > PosStart) then - begin + If (PosStart > 0) and (PosEnd > PosStart) Then + Begin L := PosEnd - PosStart; Result := Copy(S, PosStart + 1, L - 1); - end - else + End + Else Result := ''; -end; -function StrChopRight(const S: DWString; N: SizeInt): DWString; -begin +End; +Function StrChopRight(Const S: DWString; N: SizeInt): DWString; +Begin Result := Copy(S, 1, Length(S) - N); -end; -function StrLeft(const S: DWString; Count: SizeInt): DWString; -begin +End; +Function StrLeft(Const S: DWString; Count: SizeInt): DWString; +Begin Result := Copy(S, 1, Count); -end; -function StrMid(const S: DWString; Start, Count: SizeInt): DWString; -begin +End; +Function StrMid(Const S: DWString; Start, Count: SizeInt): DWString; +Begin Result := Copy(S, Start, Count); -end; -function StrRestOf(const S: DWString; N: SizeInt): DWString; -begin +End; +Function StrRestOf(Const S: DWString; N: SizeInt): DWString; +Begin Result := Copy(S, N, (Length(S) - N + 1)); -end; -function StrRight(const S: DWString; Count: SizeInt): DWString; -begin +End; +Function StrRight(Const S: DWString; Count: SizeInt): DWString; +Begin Result := Copy(S, Length(S) - Count + 1, Count); -end; +End; -function CharIsDelete(const C: DWChar): Boolean; -begin +Function CharIsDelete(Const C: DWChar): Boolean; +Begin Result := (C = #8); -end; +End; -function CharIsReturn(const C: DWChar): Boolean; -begin +Function CharIsReturn(Const C: DWChar): Boolean; +Begin Result := (C = AnsiLineFeed) or (C = AnsiCarriageReturn); -end; -function CharIsValidIdentifierLetter(const C: DWChar): Boolean; -begin - case C of +End; +Function CharIsValidIdentifierLetter(Const C: DWChar): Boolean; +Begin + Case C Of '0'..'9', 'A'..'Z', 'a'..'z', '_': Result := True; - else + Else Result := False; - end; -end; -function CharIsWildcard(const C: DWChar): Boolean; -begin - case C of + End; +End; +Function CharIsWildcard(Const C: DWChar): Boolean; +Begin + Case C Of '*', '?': Result := True; - else + Else Result := False; - end; -end; -function CharType(const C: DWChar): Word; -begin + End; +End; +Function CharType(Const C: DWChar): Word; +Begin Result := DWCharTypes[C]; -end; -function PCharVectorCount(Source: PAnsiCharVector): SizeInt; -begin +End; +Function PCharVectorCount(Source: PAnsiCharVector): SizeInt; +Begin Result := 0; - if Source <> nil then - while Source^ <> nil do - begin + If Source <> nil Then + While Source^ <> nil Do + Begin Inc(Source); Inc(Result); - end; -end; + End; +End; //=== Character Transformation Routines ====================================== -function CharHex(const C: DWChar): Byte; -begin - case C of +Function CharHex(Const C: DWChar): Byte; +Begin + Case C Of '0'..'9': Result := Ord(C) - Ord('0'); 'a'..'f': Result := Ord(C) - Ord('a') + 10; 'A'..'F': Result := Ord(C) - Ord('A') + 10; - else + Else Result := $FF; - end; -end; -function CharLower(const C: DWChar): DWChar; -begin + End; +End; +Function CharLower(Const C: DWChar): DWChar; +Begin Result := AnsiCaseMap[Ord(C) + AnsiLoOffset]; -end; -function CharToggleCase(const C: DWChar): DWChar; -begin +End; +Function CharToggleCase(Const C: DWChar): DWChar; +Begin Result := AnsiCaseMap[Ord(C) + AnsiReOffset]; -end; -function CharUpper(const C: DWChar): DWChar; -begin +End; +Function CharUpper(Const C: DWChar): DWChar; +Begin Result := AnsiCaseMap[Ord(C) + AnsiUpOffset]; -end; +End; //=== Character Search and Replace =========================================== -function CharLastPos(const S: DWString; const C: DWChar; const Index: SizeInt): SizeInt; -begin - if (Index > 0) and (Index <= Length(S)) then - for Result := Length(S) downto Index do - if PDWString(@S[Result])^ = C then +Function CharLastPos(Const S: DWString; Const C: DWChar; Const Index: SizeInt): SizeInt; +Begin + If (Index > 0) and (Index <= Length(S)) Then + For Result := Length(S) Downto Index Do + If PDWString(@S[Result])^ = C Then Exit; Result := 0; -end; -function CharPos(const S: DWString; const C: DWChar; const Index: SizeInt): SizeInt; -begin - if (Index > 0) and (Index <= Length(S)) then - for Result := Index to Length(S) do - if PDWString(@S[Result])^ = C then +End; +Function CharPos(Const S: DWString; Const C: DWChar; Const Index: SizeInt): SizeInt; +Begin + If (Index > 0) and (Index <= Length(S)) Then + For Result := Index To Length(S) Do + If PDWString(@S[Result])^ = C Then Exit; Result := 0; -end; -function CharIPos(const S: DWString; C: DWChar; const Index: SizeInt): SizeInt; -begin - if (Index > 0) and (Index <= Length(S)) then - begin +End; +Function CharIPos(Const S: DWString; C: DWChar; Const Index: SizeInt): SizeInt; +Begin + If (Index > 0) and (Index <= Length(S)) Then + Begin C := CharUpper(C); - for Result := Index to Length(S) do - if AnsiCaseMap[Ord(S[Result]) + AnsiUpOffset] = C then + For Result := Index To Length(S) Do + If AnsiCaseMap[Ord(S[Result]) + AnsiUpOffset] = C Then Exit; - end; + End; Result := 0; -end; -procedure AllocateMultiSz(var Dest: PAnsiMultiSz; Len: SizeInt); -begin - if Len > 0 then +End; +Procedure AllocateMultiSz(Var Dest: PAnsiMultiSz; Len: SizeInt); +Begin + If Len > 0 Then GetMem(Dest, Len * SizeOf(DWChar)) - else + Else Dest := nil; -end; -procedure FreeMultiSz(var Dest: PAnsiMultiSz); -begin - if Dest <> nil then +End; +Procedure FreeMultiSz(Var Dest: PAnsiMultiSz); +Begin + If Dest <> nil Then FreeMem(Dest); Dest := nil; -end; +End; //=== TJclAnsiStrings Manipulation =============================================== -procedure StrToStrings(S, Sep: DWString; const List: TJclAnsiStrings; const AllowEmptyString: Boolean = True); -var +Procedure StrToStrings(S, Sep: DWString; Const List: TJclAnsiStrings; Const AllowEmptyString: Boolean = True); +Var I, L: SizeInt; Left: DWString; -begin +Begin Assert(List <> nil); List.BeginUpdate; - try + Try List.Clear; L := Length(Sep); I := Pos(Sep, S); - while I > 0 do - begin + While I > 0 Do + Begin Left := StrLeft(S, I - 1); - if (Left <> '') or AllowEmptyString then + If (Left <> '') or AllowEmptyString Then List.Add(Left); Delete(S, 1, I + L - 1); I := Pos(Sep, S); - end; - if (S <> '') or AllowEmptyString then + End; + If (S <> '') or AllowEmptyString Then List.Add(S); // Ignore empty strings at the end (only if AllowEmptyString = False). - finally + Finally List.EndUpdate; - end; -end; -procedure StrIToStrings(S, Sep: DWString; const List: TJclAnsiStrings; const AllowEmptyString: Boolean = True); -var + End; +End; +Procedure StrIToStrings(S, Sep: DWString; Const List: TJclAnsiStrings; Const AllowEmptyString: Boolean = True); +Var I, L: SizeInt; LowerCaseStr: DWString; Left: DWString; -begin +Begin Assert(List <> nil); LowerCaseStr := StrLower(S); Sep := StrLower(Sep); L := Length(Sep); I := Pos(Sep, LowerCaseStr); List.BeginUpdate; - try + Try List.Clear; - while I > 0 do - begin + While I > 0 Do + Begin Left := StrLeft(S, I - 1); - if (Left <> '') or AllowEmptyString then + If (Left <> '') or AllowEmptyString Then List.Add(Left); Delete(S, 1, I + L - 1); Delete(LowerCaseStr, 1, I + L - 1); I := Pos(Sep, LowerCaseStr); - end; - if (S <> '') or AllowEmptyString then + End; + If (S <> '') or AllowEmptyString Then List.Add(S); // Ignore empty strings at the end (only if AllowEmptyString = False). - finally + Finally List.EndUpdate; - end; -end; -function StringsToStr(const List: TJclAnsiStrings; const Sep: DWString; - const AllowEmptyString: Boolean): DWString; -var + End; +End; +Function StringsToStr(Const List: TJclAnsiStrings; Const Sep: DWString; + Const AllowEmptyString: Boolean): DWString; +Var I, L: SizeInt; -begin +Begin Result := ''; - for I := 0 to List.Count - 1 do - begin - if (List[I] <> '') or AllowEmptyString then - begin + For I := 0 To List.Count - 1 Do + Begin + If (List[I] <> '') or AllowEmptyString Then + Begin // don't combine these into one addition, somehow it hurts performance Result := Result + List[I]; Result := Result + Sep; - end; - end; + End; + End; // remove terminating separator - if List.Count <> 0 then - begin + If List.Count <> 0 Then + Begin L := Length(Sep); Delete(Result, Length(Result) - L + 1, L); - end; -end; -procedure TrimStrings(const List: TJclAnsiStrings; DeleteIfEmpty: Boolean); -var + End; +End; +Procedure TrimStrings(Const List: TJclAnsiStrings; DeleteIfEmpty: Boolean); +Var I: SizeInt; -begin +Begin Assert(List <> nil); List.BeginUpdate; - try - for I := List.Count - 1 downto 0 do - begin + Try + For I := List.Count - 1 Downto 0 Do + Begin List[I] := Trim(List[I]); - if (List[I] = '') and DeleteIfEmpty then + If (List[I] = '') and DeleteIfEmpty Then List.Delete(I); - end; - finally + End; + Finally List.EndUpdate; - end; -end; -procedure TrimStringsRight(const List: TJclAnsiStrings; DeleteIfEmpty: Boolean); -var + End; +End; +Procedure TrimStringsRight(Const List: TJclAnsiStrings; DeleteIfEmpty: Boolean); +Var I: SizeInt; -begin +Begin Assert(List <> nil); List.BeginUpdate; - try - for I := List.Count - 1 downto 0 do - begin + Try + For I := List.Count - 1 Downto 0 Do + Begin List[I] := TrimRight(List[I]); - if (List[I] = '') and DeleteIfEmpty then + If (List[I] = '') and DeleteIfEmpty Then List.Delete(I); - end; - finally + End; + Finally List.EndUpdate; - end; -end; -procedure TrimStringsLeft(const List: TJclAnsiStrings; DeleteIfEmpty: Boolean); -var + End; +End; +Procedure TrimStringsLeft(Const List: TJclAnsiStrings; DeleteIfEmpty: Boolean); +Var I: SizeInt; -begin +Begin Assert(List <> nil); List.BeginUpdate; - try - for I := List.Count - 1 downto 0 do - begin + Try + For I := List.Count - 1 Downto 0 Do + Begin List[I] := TrimLeft(List[I]); - if (List[I] = '') and DeleteIfEmpty then + If (List[I] = '') and DeleteIfEmpty Then List.Delete(I); - end; - finally + End; + Finally List.EndUpdate; - end; -end; -function AddStringToStrings(const S: DWString; Strings: TJclAnsiStrings; const Unique: Boolean): Boolean; -begin + End; +End; +Function AddStringToStrings(Const S: DWString; Strings: TJclAnsiStrings; Const Unique: Boolean): Boolean; +Begin Assert(Strings <> nil); Result := Unique and (Strings.IndexOf(S) <> -1); - if not Result then + If not Result Then Result := Strings.Add(S) > -1; -end; +End; //=== Miscellaneous ========================================================== -function FileToString(const FileName: TFileName): DWString; -var +Function FileToString(Const FileName: TFileName): DWString; +Var FS: TFileStream; Len: SizeInt; -begin +Begin FS := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); - try + Try Len := FS.Size; SetLength(Result, Len); - if Len > 0 then + If Len > 0 Then FS.ReadBuffer(Result[1], Len); - finally + Finally FS.Free; - end; -end; -procedure StringToFile(const FileName: TFileName; const Contents: DWString; Append: Boolean); -var + End; +End; +Procedure StringToFile(Const FileName: TFileName; Const Contents: DWString; Append: Boolean); +Var FS: TFileStream; Len: SizeInt; -begin - if Append and FileExists(FileName) then +Begin + If Append and FileExists(FileName) Then FS := TFileStream.Create(FileName, fmOpenReadWrite or fmShareDenyWrite) - else + Else FS := TFileStream.Create(FileName, fmCreate); - try - if Append then + Try + If Append Then FS.Seek(0, soEnd); // faster than .Position := .Size Len := Length(Contents); - if Len > 0 then + If Len > 0 Then FS.WriteBuffer(Contents[1], Len); - finally + Finally FS.Free; - end; -end; -function StrToken(var S: DWString; Separator: DWChar): DWString; -var + End; +End; +Function StrToken(Var S: DWString; Separator: DWChar): DWString; +Var I: SizeInt; -begin +Begin I := Pos(Separator, S); - if I <> 0 then - begin + If I <> 0 Then + Begin Result := Copy(S, 1, I - 1); Delete(S, 1, I); - end - else - begin + End + Else + Begin Result := S; S := ''; - end; -end; + End; +End; //procedure StrTokenToStrings(S: string; Separator: Char; const List: TStrings); //var @@ -2256,25 +2256,25 @@ function StrToken(var S: DWString; Separator: DWChar): DWString; // end; //end; -procedure StrNormIndex(const StrLen: SizeInt; var Index: SizeInt; var Count: SizeInt); overload; -begin +Procedure StrNormIndex(Const StrLen: SizeInt; Var Index: SizeInt; Var Count: SizeInt); overload; +Begin Index := Max(1, Min(Index, StrLen + 1)); Count := Max(0, Min(Count, StrLen + 1 - Index)); -end; -function ArrayOf(List: TJclAnsiStrings): TDynStringArray; -var +End; +Function ArrayOf(List: TJclAnsiStrings): TDynStringArray; +Var I: SizeInt; -begin - if List <> nil then - begin +Begin + If List <> nil Then + Begin SetLength(Result, List.Count); - for I := 0 to List.Count - 1 do + For I := 0 To List.Count - 1 Do Result[I] := string(List[I]); - end - else + End + Else Result := nil; -end; +End; -initialization - LoadCharTypes; // this table first +Initialization + LoadCharTypes; // this table first End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemBase.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemBase.pas index 62fd01d83..40d58b1b2 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemBase.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemBase.pas @@ -1,29 +1,29 @@ -unit uRESTDWMemBase; -{$I ..\..\Includes\uRESTDW.inc} +Unit uRESTDWMemBase; +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. Roniery - Devel. } -interface -uses +Interface +Uses uRESTDWMemConsts, {$IFDEF HAS_UNITSCOPE} {$IFDEF MSWINDOWS} @@ -38,7 +38,7 @@ interface {$ENDIF ~HAS_UNITSCOPE}, uRESTDWProtoTypes; // Version -const +Const {$IFDEF UNIX} // renamed to DirDelimiter // PathSeparator = '/'; @@ -60,11 +60,11 @@ interface JclVersion = (JclVersionMajor shl 24) or (JclVersionMinor shl 16) or (JclVersionRelease shl 15) or (JclVersionBuild shl 0); // EJclError -type - EJclError = class(Exception); +Type + EJclError = Class(Exception); // EJclInternalError -type - EJclInternalError = class(EJclError); +Type + EJclInternalError = Class(EJclError); // Types Type {$IFDEF FPC} @@ -73,7 +73,7 @@ EJclInternalError = class(EJclError); Float = Single; {$ENDIF} PFloat = ^Float; -type +Type {$IFDEF FPC} Largeint = Int64; SizeInt = Integer; @@ -96,37 +96,37 @@ EJclInternalError = class(EJclError); PWideChar = System.PWideChar; PPWideChar = ^PWideChar; PPAnsiChar = ^PAnsiChar; - PInt64 = type System.PInt64; + PInt64 = Type System.PInt64; {$ENDIF} PPInt64 = ^PInt64; PPPAnsiChar = ^PPAnsiChar; {$IFNDEF FPC} -type +Type PLargeInteger = ^TLargeInteger; TLargeInteger = Int64; {$ENDIF ~FPC} {$IFNDEF COMPILER11_UP} -type - TBytes = array of Byte; +Type + TBytes = array Of Byte; {$ENDIF ~COMPILER11_UP} // Redefinition of PByteArray to avoid range check exceptions. -type - TJclByteArray = array [0..MaxInt div SizeOf(Byte) - 1] of Byte; +Type + TJclByteArray = array [0..MaxInt div SizeOf(Byte) - 1] Of Byte; PJclByteArray = ^TJclByteArray; TJclBytes = Pointer; // under .NET System.pas: TBytes = array of Byte; // Redefinition of ULARGE_INTEGER to relieve dependency on Windows.pas -type +Type {$IFNDEF FPC} PULARGE_INTEGER = ^ULARGE_INTEGER; {$EXTERNALSYM PULARGE_INTEGER} - ULARGE_INTEGER = record - case Integer of + ULARGE_INTEGER = Record + Case Integer Of 0: (LowPart: LongWord; HighPart: LongWord); 1: (QuadPart: Int64); - end; + End; {$EXTERNALSYM ULARGE_INTEGER} {$ENDIF ~FPC} TJclULargeInteger = ULARGE_INTEGER; @@ -136,34 +136,34 @@ ULARGE_INTEGER = record {$EXTERNALSYM LONG} {$ENDIF ~COMPILER16_UP} // Dynamic Array support -type - TDynByteArray = array of Byte; - TDynShortIntArray = array of Shortint; - TDynWordArray = array of Word; - TDynSmallIntArray = array of Smallint; - TDynLongIntArray = array of Longint; - TDynInt64Array = array of Int64; - TDynCardinalArray = array of Cardinal; - TDynIntegerArray = array of Integer; - TDynSizeIntArray = array of SizeInt; - TDynExtendedArray = array of Extended; - TDynDoubleArray = array of Double; - TDynSingleArray = array of Single; - TDynFloatArray = array of Float; - TDynPointerArray = array of Pointer; - TDynStringArray = array of string; - TDynAnsiStringArray = array of DwString; - TDynWideStringArray = array of DwWideString; +Type + TDynByteArray = array Of Byte; + TDynShortIntArray = array Of Shortint; + TDynWordArray = array Of Word; + TDynSmallIntArray = array Of Smallint; + TDynLongIntArray = array Of Longint; + TDynInt64Array = array Of Int64; + TDynCardinalArray = array Of Cardinal; + TDynIntegerArray = array Of Integer; + TDynSizeIntArray = array Of SizeInt; + TDynExtendedArray = array Of Extended; + TDynDoubleArray = array Of Double; + TDynSingleArray = array Of Single; + TDynFloatArray = array Of Float; + TDynPointerArray = array Of Pointer; + TDynStringArray = array Of string; + TDynAnsiStringArray = array Of DwString; + TDynWideStringArray = array Of DwWideString; {$IFDEF SUPPORTS_UNICODE_STRING} - TDynUnicodeStringArray = array of UnicodeString; + TDynUnicodeStringArray = array Of UnicodeString; {$ENDIF SUPPORTS_UNICODE_STRING} - TDynIInterfaceArray = array of IInterface; - TDynObjectArray = array of TObject; - TDynCharArray = array of Char; - TDynAnsiCharArray = array of DwChar; - TDynWideCharArray = array of WideChar; + TDynIInterfaceArray = array Of IInterface; + TDynObjectArray = array Of TObject; + TDynCharArray = array Of Char; + TDynAnsiCharArray = array Of DwChar; + TDynWideCharArray = array Of WideChar; // Cross-Platform Compatibility -const +Const // line delimiters for a version of Delphi/C++Builder NativeLineFeed = Char(#10); NativeCarriageReturn = Char(#13); @@ -197,18 +197,18 @@ ULARGE_INTEGER = record {$IFEND} {$ENDIF} HexFmt = HexPrefix + HexDigitFmt; -const - BOM_UTF16_LSB: array [0..1] of Byte = ($FF,$FE); - BOM_UTF16_MSB: array [0..1] of Byte = ($FE,$FF); - BOM_UTF8: array [0..2] of Byte = ($EF,$BB,$BF); - BOM_UTF32_LSB: array [0..3] of Byte = ($FF,$FE,$00,$00); - BOM_UTF32_MSB: array [0..3] of Byte = ($00,$00,$FE,$FF); +Const + BOM_UTF16_LSB: array [0..1] Of Byte = ($FF,$FE); + BOM_UTF16_MSB: array [0..1] Of Byte = ($FE,$FF); + BOM_UTF8: array [0..2] Of Byte = ($EF,$BB,$BF); + BOM_UTF32_LSB: array [0..3] Of Byte = ($FF,$FE,$00,$00); + BOM_UTF32_MSB: array [0..3] Of Byte = ($00,$00,$FE,$FF); // BOM_UTF7_1: array [0..3] of Byte = ($2B,$2F,$76,$38); // BOM_UTF7_2: array [0..3] of Byte = ($2B,$2F,$76,$39); // BOM_UTF7_3: array [0..3] of Byte = ($2B,$2F,$76,$2B); // BOM_UTF7_4: array [0..3] of Byte = ($2B,$2F,$76,$2F); // BOM_UTF7_5: array [0..3] of Byte = ($2B,$2F,$76,$38,$2D); -type +Type // Unicode transformation formats (UTF) data types PUTF7 = ^UTF7; UTF7 = DwChar; @@ -223,8 +223,8 @@ ULARGE_INTEGER = record UCS4 = Cardinal; PUCS2 = PDWChar; UCS2 = WideChar; - TUCS2Array = array of UCS2; - TUCS4Array = array of UCS4; + TUCS2Array = array Of UCS2; + TUCS4Array = array Of UCS4; // string types TUTF8String = DwString; {$IFDEF SUPPORTS_UNICODE_STRING} @@ -234,9 +234,9 @@ ULARGE_INTEGER = record TUTF16String = DWWideString; TUCS2String = DWWideString; {$ENDIF SUPPORTS_UNICODE_STRING} -var +Var AnsiReplacementCharacter: DwChar; -const +Const UCS4ReplacementCharacter: UCS4 = $0000FFFD; MaximumUCS2: UCS4 = $0000FFFF; MaximumUTF16: UCS4 = $0010FFFF; @@ -246,23 +246,23 @@ ULARGE_INTEGER = record SurrogateLowStart = UCS4($DC00); SurrogateLowEnd = UCS4($DFFF); // basic set types -type - TSetOfAnsiChar = set of DwChar; +Type + TSetOfAnsiChar = set Of DwChar; {$IFNDEF HAS_FMX} -procedure RaiseLastOSError; +Procedure RaiseLastOSError; {$ENDIF ~HAS_FMX} {$IFNDEF RTL230_UP} -procedure CheckOSError(ErrorCode: Cardinal); +Procedure CheckOSError(ErrorCode: Cardinal); {$ENDIF RTL230_UP} -procedure MoveChar(const Source: string; FromIndex: SizeInt; - var Dest: string; ToIndex, Count: SizeInt); overload; // Index: 0..n-1 -function AnsiByteArrayStringLen(Data: TBytes): SizeInt; -function StringToAnsiByteArray(const S: string): TBytes; -function AnsiByteArrayToString(const Data: TBytes; Count: SizeInt): string; -function BytesOf(const Value: DWString): TBytes; overload; +Procedure MoveChar(Const Source: string; FromIndex: SizeInt; + Var Dest: string; ToIndex, Count: SizeInt); overload; // Index: 0..n-1 +Function AnsiByteArrayStringLen(Data: TBytes): SizeInt; +Function StringToAnsiByteArray(Const S: string): TBytes; +Function AnsiByteArrayToString(Const Data: TBytes; Count: SizeInt): string; +Function BytesOf(Const Value: DWString): TBytes; overload; {$IFNDEF FPC} {$IFNDEF COMPILER11_UP} -type // Definitions for 32 Bit Compilers +Type // Definitions for 32 Bit Compilers // From BaseTsd.h INT_PTR = Integer; {$EXTERNALSYM INT_PTR} @@ -273,12 +273,12 @@ function BytesOf(const Value: DWString): TBytes; overload; ULONG_PTR = LongWord; {$EXTERNALSYM DWORD_PTR} {$ENDIF ~COMPILER11_UP} -type +Type DWORD_PTR = LongWord; PDWORD_PTR = ^DWORD_PTR; {$EXTERNALSYM PDWORD_PTR} {$ENDIF ~FPC} -type +Type TJclAddr32 = Cardinal; {$IFDEF FPC} TJclAddr64 = QWord; @@ -299,37 +299,37 @@ function BytesOf(const Value: DWString): TBytes; overload; {$IFEND} {$ENDIF} PJclAddr = ^TJclAddr; - EJclAddr64Exception = class(EJclError); -function Addr64ToAddr32(const Value: TJclAddr64): TJclAddr32; -function Addr32ToAddr64(const Value: TJclAddr32): TJclAddr64; + EJclAddr64Exception = Class(EJclError); +Function Addr64ToAddr32(Const Value: TJclAddr64): TJclAddr32; +Function Addr32ToAddr64(Const Value: TJclAddr32): TJclAddr64; {$IFDEF FPC} -type - HWND = type Windows.HWND; +Type + HWND = Type Windows.HWND; {$ENDIF FPC} {$IFDEF SUPPORTS_GENERICS} //DOM-IGNORE-BEGIN -type - TCompare = function(const Obj1, Obj2: T): Integer; - TEqualityCompare = function(const Obj1, Obj2: T): Boolean; - THashConvert = function(const AItem: T): Integer; - IEqualityComparer = interface - function Equals(A, B: T): Boolean; - function GetHashCode(Obj: T): Integer; - end; - TEquatable = class(TInterfacedObject, IEquatable, IEqualityComparer) - public +Type + TCompare = Function(Const Obj1, Obj2: T): Integer; + TEqualityCompare = Function(Const Obj1, Obj2: T): Boolean; + THashConvert = Function(Const AItem: T): Integer; + IEqualityComparer = Interface + Function Equals(A, B: T): Boolean; + Function GetHashCode(Obj: T): Integer; + End; + TEquatable = Class(TInterfacedObject, IEquatable, IEqualityComparer) + Public { IEquatable } - function TestEquals(Other: T): Boolean; overload; - function IEquatable.Equals = TestEquals; + Function TestEquals(Other: T): Boolean; overload; + Function IEquatable.Equals = TestEquals; { IEqualityComparer } - function TestEquals(A, B: T): Boolean; overload; - function IEqualityComparer.Equals = TestEquals; - function GetHashCode2(Obj: T): Integer; - function IEqualityComparer.GetHashCode = GetHashCode2; - end; + Function TestEquals(A, B: T): Boolean; overload; + Function IEqualityComparer.Equals = TestEquals; + Function GetHashCode2(Obj: T): Integer; + Function IEqualityComparer.GetHashCode = GetHashCode2; + End; //DOM-IGNORE-END {$ENDIF SUPPORTS_GENERICS} -const +Const {$IFDEF SUPPORTS_UNICODE} AWSuffix = 'W'; {$ELSE ~SUPPORTS_UNICODE} @@ -338,185 +338,185 @@ TEquatable = class(TInterfacedObject, IEquatable, IEqualityCompar {$IFDEF FPC} // FPC emits a lot of warning because the first parameter of its internal // GetMem is a var parameter, which is not initialized before the call to GetMem -procedure GetMem(out P; Size: Longint); +Procedure GetMem(out P; Size: Longint); {$ENDIF FPC} -implementation +Implementation -uses +Uses uRESTDWMemResources; {$IFDEF MSWINDOWS} -function IsDirectory(const FileName: string): Boolean; -var +Function IsDirectory(Const FileName: string): Boolean; +Var R: DWORD; -begin +Begin R := GetFileAttributes(PChar(FileName)); Result := (R <> DWORD(-1)) and ((R and FILE_ATTRIBUTE_DIRECTORY) <> 0); -end; +End; {$ENDIF MSWINDOWS} {$IFDEF UNIX} -function IsDirectory(const FileName: string; ResolveSymLinks: Boolean): Boolean; -var +Function IsDirectory(Const FileName: string; ResolveSymLinks: Boolean): Boolean; +Var Buf: TStatBuf64; -begin +Begin Result := False; - if GetFileStatus(FileName, Buf, ResolveSymLinks) = 0 then + If GetFileStatus(FileName, Buf, ResolveSymLinks) = 0 Then Result := S_ISDIR(Buf.st_mode); -end; +End; {$ENDIF UNIX} -procedure MoveChar(const Source: string; FromIndex: SizeInt; - var Dest: string; ToIndex, Count: SizeInt); -begin +Procedure MoveChar(Const Source: string; FromIndex: SizeInt; + Var Dest: string; ToIndex, Count: SizeInt); +Begin Move(Source[FromIndex + 1], Dest[ToIndex + 1], Count * SizeOf(Char)); -end; -function AnsiByteArrayStringLen(Data: TBytes): SizeInt; -var +End; +Function AnsiByteArrayStringLen(Data: TBytes): SizeInt; +Var I: SizeInt; -begin +Begin Result := Length(Data); - for I := 0 to Result - 1 do - if Data[I] = 0 then - begin + For I := 0 To Result - 1 Do + If Data[I] = 0 Then + Begin Result := I + 1; Break; - end; -end; -function StringToAnsiByteArray(const S: string): TBytes; -var + End; +End; +Function StringToAnsiByteArray(Const S: string): TBytes; +Var I: SizeInt; AnsiS: DWString; -begin +Begin AnsiS := DWString(S); // convert to DWString SetLength(Result, Length(AnsiS)); - for I := 0 to High(Result) do + For I := 0 To High(Result) Do Result[I] := Byte(AnsiS[I + 1]); -end; -function AnsiByteArrayToString(const Data: TBytes; Count: SizeInt): string; -var +End; +Function AnsiByteArrayToString(Const Data: TBytes; Count: SizeInt): string; +Var I: SizeInt; AnsiS: DWString; -begin - if Length(Data) < Count then +Begin + If Length(Data) < Count Then Count := Length(Data); SetLength(AnsiS, Count); - for I := 0 to Length(AnsiS) - 1 do + For I := 0 To Length(AnsiS) - 1 Do PDWChar(@AnsiS[I + 1])^ := DWChar(Data[I]); Result := string(AnsiS); // convert to System.String -end; -function BytesOf(const Value: DWString): TBytes; -begin +End; +Function BytesOf(Const Value: DWString): TBytes; +Begin SetLength(Result, Length(Value)); - if Value <> '' then + If Value <> '' Then Move(Pointer(Value)^, Result[0], Length(Value)); -end; -function StringOf(const Bytes: array of Byte): DWString; -begin - if Length(Bytes) > 0 then - begin +End; +Function StringOf(Const Bytes: array Of Byte): DWString; +Begin + If Length(Bytes) > 0 Then + Begin SetLength(Result, Length(Bytes)); Move(Bytes[0], Pointer(Result)^, Length(Bytes)); - end - else + End + Else Result := ''; -end; +End; // Cross Platform Compatibility {$IFNDEF HAS_FMX} -procedure RaiseLastOSError; -begin +Procedure RaiseLastOSError; +Begin {$IFDEF MSWINDOWS} RaiseLastWin32Error; {$ENDIF} -end; +End; {$ENDIF ~HAS_FMX} {$IFNDEF RTL230_UP} -procedure CheckOSError(ErrorCode: Cardinal); -begin - if ErrorCode <> ERROR_SUCCESS then +Procedure CheckOSError(ErrorCode: Cardinal); +Begin + If ErrorCode <> ERROR_SUCCESS Then {$IFDEF RTL170_UP} RaiseLastOSError(ErrorCode); {$ELSE ~RTL170_UP} RaiseLastOSError; {$ENDIF ~RTL170_UP} -end; +End; {$ENDIF RTL230_UP} {$OVERFLOWCHECKS OFF} -function Addr64ToAddr32(const Value: TJclAddr64): TJclAddr32; -begin - if (Value shr 32) = 0 then +Function Addr64ToAddr32(Const Value: TJclAddr64): TJclAddr32; +Begin + If (Value shr 32) = 0 Then Result := Value - else + Else raise EJclAddr64Exception.CreateResFmt(@RsCantConvertAddr64, [HexPrefix, Value]); -end; -function Addr32ToAddr64(const Value: TJclAddr32): TJclAddr64; -begin +End; +Function Addr32ToAddr64(Const Value: TJclAddr32): TJclAddr64; +Begin Result := Value; -end; +End; {$IFDEF OVERFLOWCHECKS_ON} {$OVERFLOWCHECKS ON} {$ENDIF OVERFLOWCHECKS_ON} {$IFDEF SUPPORTS_GENERICS} //DOM-IGNORE-BEGIN //=== { TEquatable } ====================================================== -function TEquatable.TestEquals(Other: T): Boolean; -begin - if Other = nil then +Function TEquatable.TestEquals(Other: T): Boolean; +Begin + If Other = nil Then Result := False - else + Else Result := GetHashCode = Other.GetHashCode; -end; -function TEquatable.TestEquals(A, B: T): Boolean; -begin - if A = nil then +End; +Function TEquatable.TestEquals(A, B: T): Boolean; +Begin + If A = nil Then Result := B = nil - else - if B = nil then + Else + If B = nil Then Result := False - else + Else Result := A.GetHashCode = B.GetHashCode; -end; -function TEquatable.GetHashCode2(Obj: T): Integer; -begin - if Obj = nil then +End; +Function TEquatable.GetHashCode2(Obj: T): Integer; +Begin + If Obj = nil Then Result := 0 - else + Else Result := Obj.GetHashCode; -end; +End; //DOM-IGNORE-END {$ENDIF SUPPORTS_GENERICS} -procedure LoadAnsiReplacementCharacter; +Procedure LoadAnsiReplacementCharacter; {$IFDEF MSWINDOWS} -var +Var CpInfo: TCpInfo; -begin +Begin CpInfo.MaxCharSize := 0; - if GetCPInfo(CP_ACP, CpInfo) then + If GetCPInfo(CP_ACP, CpInfo) Then AnsiReplacementCharacter := DWChar(Chr(CpInfo.DefaultChar[0])) - else + Else raise EJclInternalError.CreateRes(@RsEReplacementChar); -end; +End; {$ELSE ~MSWINDOWS} -begin +Begin AnsiReplacementCharacter := '?'; -end; +End; {$ENDIF ~MSWINDOWS} {$IFDEF FPC} // FPC emits a lot of warning because the first parameter of its internal // GetMem is a var parameter, which is not initialized before the call to GetMem -procedure GetMem(out P; Size: Longint); -begin +Procedure GetMem(out P; Size: Longint); +Begin Pointer(P) := nil; GetMem(Pointer(P), Size); -end; +End; {$ENDIF FPC} -initialization - LoadAnsiReplacementCharacter; - {$IFDEF UNITVERSIONING} - RegisterUnitVersion(HInstance, UnitVersioning); - {$ENDIF UNITVERSIONING} -finalization - {$IFDEF UNITVERSIONING} - UnregisterUnitVersion(HInstance); - {$ENDIF UNITVERSIONING} -end. +Initialization + LoadAnsiReplacementCharacter; +{$IFDEF UNITVERSIONING} + RegisterUnitVersion(HInstance, UnitVersioning); +{$ENDIF UNITVERSIONING} +Finalization +{$IFDEF UNITVERSIONING} + UnregisterUnitVersion(HInstance); +{$ENDIF UNITVERSIONING} +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemCharsets.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemCharsets.pas index 70cbc0b6b..09c5dd540 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemCharsets.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemCharsets.pas @@ -1,41 +1,41 @@ -unit uRESTDWMemCharsets; -{$I ..\..\Includes\uRESTDW.inc} +Unit uRESTDWMemCharsets; +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. Roniery - Devel. } -interface -uses +Interface +Uses uRESTDWMemBase; -type - EJclCharsetError = class(EJclError); -const +Type + EJclCharsetError = Class(EJclError); +Const CP_UTF16LE = 1200; -type - TJclCharsetInfo = record +Type + TJclCharsetInfo = Record Name: string; CodePage: Word; FamilyCodePage: Word; - end; -const JclCharsetInfos: array [0..285] of TJclCharsetInfo = + End; +Const JclCharsetInfos: array [0..285] Of TJclCharsetInfo = (* Arabic (ASMO 708) ASMO-708 708 1256 *) ((Name: 'ASMO-708'; CodePage: 708; FamilyCodePage: 1256), (* Arabic (DOS) DOS-720 720 1256 *) @@ -440,13 +440,13 @@ TJclCharsetInfo = record (Name: 'us'; CodePage: 1252; FamilyCodePage: 1252), (Name: 'us-ascii'; CodePage: 1252; FamilyCodePage: 1252), (Name: 'x-ansi'; CodePage: 1252; FamilyCodePage: 1252) ); -function FamilyCodePageFromCharsetName(const CharsetName: string): Word; -function FamilyCodePageFromCodePage(CodePage: Word): Word; -function CodePageFromCharsetName(const CharsetName: string): Word; -function CharsetInfoFromCharsetName(const CharsetName: string): TJclCharsetInfo; -function CharsetNameFromCodePage(CodePage: Word): string; +Function FamilyCodePageFromCharsetName(Const CharsetName: string): Word; +Function FamilyCodePageFromCodePage(CodePage: Word): Word; +Function CodePageFromCharsetName(Const CharsetName: string): Word; +Function CharsetInfoFromCharsetName(Const CharsetName: string): TJclCharsetInfo; +Function CharsetNameFromCodePage(CodePage: Word): string; {$IFDEF UNITVERSIONING} -const +Const UnitVersioning: TUnitVersionInfo = ( RCSfile: '$URL$'; Revision: '$Revision$'; @@ -456,8 +456,8 @@ function CharsetNameFromCodePage(CodePage: Word): string; Data: nil ); {$ENDIF UNITVERSIONING} -implementation -uses +Implementation +Uses {$IFDEF HAS_UNITSCOPE} System.SysUtils, {$ELSE ~HAS_UNITSCOPE} @@ -465,76 +465,76 @@ implementation {$ENDIF ~HAS_UNITSCOPE} uRESTDWMemResources; -function FamilyCodePageFromCharsetName(const CharsetName: string): Word; -var +Function FamilyCodePageFromCharsetName(Const CharsetName: string): Word; +Var Index: Integer; UpperCharsetName: string; -begin +Begin UpperCharsetName := UpperCase(CharsetName); - for Index := Low(JclCharsetInfos) to High(JclCharsetInfos) do - if CompareStr(UpperCharsetName, UpperCase(JclCharsetInfos[Index].Name)) = 0 then - begin + For Index := Low(JclCharsetInfos) To High(JclCharsetInfos) Do + If CompareStr(UpperCharsetName, UpperCase(JclCharsetInfos[Index].Name)) = 0 Then + Begin Result := JclCharsetInfos[Index].FamilyCodePage; Exit; - end; + End; raise EJclCharsetError.CreateRes(@RsENoCharset); -end; -function CodePageFromCharsetName(const CharsetName: string): Word; -var +End; +Function CodePageFromCharsetName(Const CharsetName: string): Word; +Var Index: Integer; UpperCharsetName: string; -begin +Begin UpperCharsetName := UpperCase(CharsetName); - for Index := Low(JclCharsetInfos) to High(JclCharsetInfos) do - if CompareStr(UpperCharsetName, UpperCase(JclCharsetInfos[Index].Name)) = 0 then - begin + For Index := Low(JclCharsetInfos) To High(JclCharsetInfos) Do + If CompareStr(UpperCharsetName, UpperCase(JclCharsetInfos[Index].Name)) = 0 Then + Begin Result := JclCharsetInfos[Index].CodePage; Exit; - end; + End; raise EJclCharsetError.CreateRes(@RsENoCharset); -end; -function CharsetInfoFromCharsetName(const CharsetName: string): TJclCharsetInfo; -var +End; +Function CharsetInfoFromCharsetName(Const CharsetName: string): TJclCharsetInfo; +Var Index: Integer; UpperCharsetName: string; -begin +Begin UpperCharsetName := UpperCase(CharsetName); - for Index := Low(JclCharsetInfos) to High(JclCharsetInfos) do - if CompareStr(UpperCharsetName, UpperCase(JclCharsetInfos[Index].Name)) = 0 then - begin + For Index := Low(JclCharsetInfos) To High(JclCharsetInfos) Do + If CompareStr(UpperCharsetName, UpperCase(JclCharsetInfos[Index].Name)) = 0 Then + Begin Result := JclCharsetInfos[Index]; Exit; - end; + End; raise EJclCharsetError.CreateRes(@RsENoCharset); -end; -function FamilyCodePageFromCodePage(CodePage: Word): Word; -var +End; +Function FamilyCodePageFromCodePage(CodePage: Word): Word; +Var Index: Integer; -begin - for Index := Low(JclCharsetInfos) to High(JclCharsetInfos) do - if JclCharsetInfos[Index].CodePage = CodePage then - begin +Begin + For Index := Low(JclCharsetInfos) To High(JclCharsetInfos) Do + If JclCharsetInfos[Index].CodePage = CodePage Then + Begin Result := JclCharsetInfos[Index].FamilyCodePage; Exit; - end; + End; raise EJclCharsetError.CreateRes(@RsENoCharset); -end; -function CharsetNameFromCodePage(CodePage: Word): string; -var +End; +Function CharsetNameFromCodePage(CodePage: Word): string; +Var Index: Integer; -begin - for Index := Low(JclCharsetInfos) to High(JclCharsetInfos) do - if JclCharsetInfos[Index].CodePage = CodePage then - begin +Begin + For Index := Low(JclCharsetInfos) To High(JclCharsetInfos) Do + If JclCharsetInfos[Index].CodePage = CodePage Then + Begin Result := JclCharsetInfos[Index].Name; Exit; - end; + End; raise EJclCharsetError.CreateRes(@RsENoCharset); -end; +End; {$IFDEF UNITVERSIONING} -initialization - RegisterUnitVersion(HInstance, UnitVersioning); -finalization - UnregisterUnitVersion(HInstance); +Initialization + RegisterUnitVersion(HInstance, UnitVersioning); +Finalization + UnregisterUnitVersion(HInstance); {$ENDIF UNITVERSIONING} -end. +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemConsts.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemConsts.pas index 4bd7c5fb3..8f831e172 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemConsts.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemConsts.pas @@ -1,32 +1,32 @@ -unit uRESTDWMemConsts; +Unit uRESTDWMemConsts; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. Roniery - Devel. } -interface -uses +Interface +Uses SysUtils, Classes, TypInfo; -const +Const {$IFDEF FPC} CM_BASE = $B000; {$ELSE} @@ -165,9 +165,9 @@ interface Separators: TSysCharSet = [#00, ' ', '-', #13, #10, '.', ',', '/', '\', '#', '"', '''', ':', '+', '%', '*', '(', ')', ';', '=', '{', '}', '[', ']', '<', '>']; DigitChars = ['0'..'9']; -const +Const ROP_DSPDxax = $00E20746; -const +Const FOURCC_ACON = 'ACON'; FOURCC_IART = 'IART'; FOURCC_INAM = 'INAM'; @@ -181,12 +181,12 @@ interface FOURCC_seq = 'seq '; AF_ICON = $00000001; AF_SEQUENCE = $00000002; -const +Const KeyboardShiftStates = [ssShift, ssAlt, ssCtrl]; MouseShiftStates = [ssLeft, ssRight, ssMiddle, ssDouble]; - tkStrings: set of TTypeKind = [tkString, tkLString, {$IFDEF UNICODE} tkUString, {$ENDIF} tkWString]; + tkStrings: set Of TTypeKind = [tkString, tkLString, {$IFDEF UNICODE} tkUString, {$ENDIF} tkWString]; {$IFDEF UNITVERSIONING} -const +Const UnitVersioning: TUnitVersionInfo = ( RCSfile: '$URL$'; Revision: '$Revision$'; @@ -194,11 +194,11 @@ interface LogPath: 'JVCL\run' ); {$ENDIF UNITVERSIONING} -implementation +Implementation {$IFDEF UNITVERSIONING} -initialization - RegisterUnitVersion(HInstance, UnitVersioning); -finalization - UnregisterUnitVersion(HInstance); +Initialization + RegisterUnitVersion(HInstance, UnitVersioning); +Finalization + UnregisterUnitVersion(HInstance); {$ENDIF UNITVERSIONING} -end. +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemDBFilterExpr.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemDBFilterExpr.pas index e053c8b59..e24249cda 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemDBFilterExpr.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemDBFilterExpr.pas @@ -1,62 +1,62 @@ -unit uRESTDWMemDBFilterExpr; -{$I ..\..\Includes\uRESTDW.inc} +Unit uRESTDWMemDBFilterExpr; +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. Roniery - Devel. } -interface -uses +Interface +Uses SysUtils, Classes, Variants, DB{$IFNDEF FPC}, DBCommon {$ENDIF}; -type - TJvDBFilterExpression = class(TObject) - private +Type + TJvDBFilterExpression = Class(TObject) + Private FDataSet: TDataSet; {$IFNDEF FPC} FParser: TExprParser; FRoot: PExprNode; - function EvalOpNode(N: PExprNode): Boolean; - function EvalFuncNode(N: PExprNode): Variant; - function EvaluateNode(N: PExprNode): Variant; + Function EvalOpNode(N: PExprNode): Boolean; + Function EvalFuncNode(N: PExprNode): Variant; + Function EvaluateNode(N: PExprNode): Variant; {$ENDIF} - public - constructor Create(ADataSet: TDataSet; const Filter: string; const FilterOptions: TFilterOptions); - destructor Destroy; override; - function Evaluate: Boolean; - end; -implementation -uses + Public + Constructor Create(ADataSet: TDataSet; Const Filter: string; Const FilterOptions: TFilterOptions); + Destructor Destroy; override; + Function Evaluate: Boolean; + End; +Implementation +Uses {$IFNDEF FPC}SqlTimSt, {$ENDIF}DateUtils, uRESTDWMemResources, uRESTDWBasicTypes, uRESTDWTools; -var +Var FieldTypeMapInitialized: Boolean = False; FieldTypeMap: TFieldMap; -type - TExprParserAccess = class - protected +Type + TExprParserAccess = Class + Protected FDecimalSeparator: {$IFNDEF FPC}{$IF CompilerVersion > 17.0}WideChar{$ELSE}Char{$IFEND}{$ELSE}Char{$ENDIF}; // Delphi 2006+ use WideChar {$IFNDEF FPC} FFilter: TFilterExpr; {$ENDIF} - end; - TFilterExprAccess = class - protected + End; + TFilterExprAccess = Class + Protected FDataSet: TDataSet; FFieldMap: TFieldMap; FOptions: TFilterOptions; @@ -64,213 +64,213 @@ TFilterExprAccess = class FParserOptions: TParserOptions; FNodes: PExprNode; {$ENDIF} - end; + End; {------------------------------------------------------------------------------} -function TrimLeftEx(const S, Blanks: string): string; -var +Function TrimLeftEx(Const S, Blanks: string): string; +Var I, Len: Integer; -begin +Begin Len := Length(S); I := 1; - while (I <= Len) and (Pos(S[I], Blanks) > 0) do + While (I <= Len) and (Pos(S[I], Blanks) > 0) Do Inc(I); Result := Copy(S, I, MaxInt); -end; -function TrimRightEx(const S, Blanks: string): string; -var +End; +Function TrimRightEx(Const S, Blanks: string): string; +Var I: Integer; -begin +Begin I := Length(S); - while (I > 0) and (Pos(S[I], Blanks) > 0) do + While (I > 0) and (Pos(S[I], Blanks) > 0) Do Dec(I); Result := Copy(S, 1, I); -end; -function TrimEx(const S, Blanks: string): string; -var +End; +Function TrimEx(Const S, Blanks: string): string; +Var L, R, Len: Integer; -begin +Begin Len := Length(S); L := 1; - while (L <= Len) and (Pos(S[L], Blanks) > 0) do + While (L <= Len) and (Pos(S[L], Blanks) > 0) Do Inc(L); R := Len; - while (R >= L) and (Pos(S[R], Blanks) > 0) do + While (R >= L) and (Pos(S[R], Blanks) > 0) Do Dec(R); Result := Copy(S, L, R - L + 1); -end; +End; // Derived from "Like" by Michael Winter -function IsLike(const MaskStr, S: string): Boolean; -var +Function IsLike(Const MaskStr, S: string): Boolean; +Var StringPtr: PChar; PatternPtr: PChar; StringRes: PChar; PatternRes: PChar; Index: Integer; -begin - if MaskStr = '' then - begin +Begin + If MaskStr = '' Then + Begin Result := False; Exit; - end; + End; Result := MaskStr = '%'; - if Result or (S = '') then + If Result or (S = '') Then Exit; Index := 1; StringPtr := PChar(S) + Index - 1; PatternPtr := PChar(MaskStr); StringRes := nil; PatternRes := nil; - repeat - repeat - case PatternPtr^ of + Repeat + Repeat + Case PatternPtr^ Of #0: - begin + Begin Result := StringPtr^ = #0; - if Result or (StringRes = nil) or (PatternRes = nil) then + If Result or (StringRes = nil) or (PatternRes = nil) Then Exit; StringPtr := StringRes; PatternPtr := PatternRes; Break; - end; + End; '%': - begin + Begin Inc(PatternPtr); PatternRes := PatternPtr; Break; - end; + End; '_': - begin - if StringPtr^ = #0 then + Begin + If StringPtr^ = #0 Then Exit; Inc(StringPtr); Inc(PatternPtr); - end; - else - begin - if StringPtr^ = #0 then + End; + Else + Begin + If StringPtr^ = #0 Then Exit; - if StringPtr^ <> PatternPtr^ then - begin - if (StringRes = nil) or (PatternRes = nil) then + If StringPtr^ <> PatternPtr^ Then + Begin + If (StringRes = nil) or (PatternRes = nil) Then Exit; StringPtr := StringRes; PatternPtr := PatternRes; Break; - end - else - begin + End + Else + Begin Inc(StringPtr); Inc(PatternPtr); - end; - end; - end; - until False; - repeat - case PatternPtr^ of + End; + End; + End; + Until False; + Repeat + Case PatternPtr^ Of #0: - begin + Begin Result := True; Exit; - end; + End; '%': - begin + Begin Inc(PatternPtr); PatternRes := PatternPtr; - end; + End; '_': - begin - if StringPtr^ = #0 then + Begin + If StringPtr^ = #0 Then Exit; Inc(StringPtr); Inc(PatternPtr); - end; - else - begin - repeat - if StringPtr^ = #0 then + End; + Else + Begin + Repeat + If StringPtr^ = #0 Then Exit; - if StringPtr^ = PatternPtr^ then + If StringPtr^ = PatternPtr^ Then Break; Inc(StringPtr); - until False; + Until False; Inc(StringPtr); StringRes := StringPtr; Inc(PatternPtr); Break; - end; - end; - until False; - until False; -end; + End; + End; + Until False; + Until False; +End; {------------------------------------------------------------------------------} { TJvDBFilterExpression } -constructor TJvDBFilterExpression.Create(ADataSet: TDataSet; const Filter: string; - const FilterOptions: TFilterOptions); -var +Constructor TJvDBFilterExpression.Create(ADataSet: TDataSet; Const Filter: string; + Const FilterOptions: TFilterOptions); +Var FieldType: TFieldType; {$IFNDEF FPC} Nodes: PExprNode; - function NodesContainsLeftRight(Root: PExprNode): Boolean; - var + Function NodesContainsLeftRight(Root: PExprNode): Boolean; + Var Node: PExprNode; - begin + Begin Result := True; Node := Nodes; - while Node <> nil do - begin - if (Node.FLeft = Root) or (Node.FRight = Root) then + While Node <> nil Do + Begin + If (Node.FLeft = Root) or (Node.FRight = Root) Then Exit; Node := Node.FNext; - end; + End; Result := False; - end; + End; {$ENDIF} -begin - inherited Create; +Begin + Inherited Create; FDataSet := ADataSet; - if not FieldTypeMapInitialized then - begin + If not FieldTypeMapInitialized Then + Begin FieldTypeMapInitialized := True; - for FieldType := Low(FieldType) to High(FieldType) do + For FieldType := Low(FieldType) To High(FieldType) Do FieldTypeMap[FieldType] := Ord(FieldType); - end; + End; {$IFNDEF FPC} FParser := TExprParser.Create(ADataSet, Filter, [], [poExtSyntax], '', nil, FieldTypeMap); Nodes := TFilterExprAccess(TExprParserAccess(FParser).FFilter).FNodes; { Find root node because FNodes is the last added node which must not be the root node. The root node is the node which istn't referenced by any other node's Left or Right field. } - if Nodes <> nil then - begin + If Nodes <> nil Then + Begin FRoot := Nodes; - while (FRoot.FNext <> nil) and not ((FRoot.FKind = enOperator) and not NodesContainsLeftRight(FRoot)) do + While (FRoot.FNext <> nil) and not ((FRoot.FKind = enOperator) and not NodesContainsLeftRight(FRoot)) Do FRoot := FRoot.FNext; - end; + End; {$ENDIF} -end; -destructor TJvDBFilterExpression.Destroy; -begin +End; +Destructor TJvDBFilterExpression.Destroy; +Begin {$IFNDEF FPC} FParser.Free; {$ENDIF} - inherited Destroy; -end; + Inherited Destroy; +End; -function TJvDBFilterExpression.Evaluate: Boolean; -begin +Function TJvDBFilterExpression.Evaluate: Boolean; +Begin Result := False; {$IFNDEF FPC} Result := EvalOpNode(FRoot); {$ENDIF} -end; +End; {$IFNDEF FPC} -function TJvDBFilterExpression.EvaluateNode(N: PExprNode): Variant; -begin - if N = nil then +Function TJvDBFilterExpression.EvaluateNode(N: PExprNode): Variant; +Begin + If N = nil Then Result := Unassigned - else - begin - case N.FKind of + Else + Begin + Case N.FKind Of enOperator: Result := EvalOpNode(N); enConst: @@ -279,22 +279,22 @@ function TJvDBFilterExpression.EvaluateNode(N: PExprNode): Variant; Result := FDataSet.FieldByName(N.FData).AsVariant; enFunc: Result := EvalFuncNode(N); - else + Else raise Exception.CreateRes(@RsInvalidFilterNodeKind); - end; - end; -end; -function TJvDBFilterExpression.EvalOpNode(N: PExprNode): Boolean; -var + End; + End; +End; +Function TJvDBFilterExpression.EvalOpNode(N: PExprNode): Boolean; +Var I: Integer; V: Variant; -begin - if N = nil then +Begin + If N = nil Then Result := False - else - begin + Else + Begin Assert(N.FKind = enOperator); - case N.FOperator of + Case N.FOperator Of coEQ: Result := EvaluateNode(N.FLeft) = EvaluateNode(N.FRight); coNE: @@ -320,21 +320,21 @@ function TJvDBFilterExpression.EvalOpNode(N: PExprNode): Boolean; coLIKE: Result := IsLike(EvaluateNode(N.FLeft), EvaluateNode(N.FRight)); coIN: - begin + Begin Result := False; V := EvaluateNode(N.FLeft); - if N.FArgs <> nil then - begin - for I := 0 to N.FArgs.Count - 1 do - begin - if V = EvaluateNode(N.FArgs[I]) then - begin + If N.FArgs <> nil Then + Begin + For I := 0 To N.FArgs.Count - 1 Do + Begin + If V = EvaluateNode(N.FArgs[I]) Then + Begin Result := True; Break; - end; - end; - end; - end; + End; + End; + End; + End; coMINUS: Result := -EvaluateNode(N.FLeft); coADD: @@ -345,114 +345,114 @@ function TJvDBFilterExpression.EvalOpNode(N: PExprNode): Boolean; Result := EvaluateNode(N.FLeft) * EvaluateNode(N.FRight); coDIV: Result := EvaluateNode(N.FLeft) / EvaluateNode(N.FRight); - else + Else raise Exception.CreateRes(@RsUnknownFilterOperation); - end; - end; -end; + End; + End; +End; -function TJvDBFilterExpression.EvalFuncNode(N: PExprNode): Variant; -var +Function TJvDBFilterExpression.EvalFuncNode(N: PExprNode): Variant; +Var V: Variant; -begin - if N = nil then +Begin + If N = nil Then Result := Unassigned - else - begin - if (N.FArgs <> nil) and (N.FArgs.Count > 0) then - begin + Else + Begin + If (N.FArgs <> nil) and (N.FArgs.Count > 0) Then + Begin V := EvaluateNode(N.FArgs[0]); - if CompareText(N.FData, 'UPPER') = 0 then + If CompareText(N.FData, 'UPPER') = 0 Then Result := AnsiUpperCase(V) - else - if CompareText(N.FData, 'LOWER') = 0 then + Else + If CompareText(N.FData, 'LOWER') = 0 Then Result := AnsiLowerCase(V) - else - if CompareText(N.FData, 'TRIM') = 0 then - begin - if N.FArgs.Count = 1 then + Else + If CompareText(N.FData, 'TRIM') = 0 Then + Begin + If N.FArgs.Count = 1 Then Result := Trim(V) - else + Else Result := TrimEx(V, EvaluateNode(N.FArgs[1])); - end - else - if CompareText(N.FData, 'TRIMLEFT') = 0 then - begin - if N.FArgs.Count = 1 then + End + Else + If CompareText(N.FData, 'TRIMLEFT') = 0 Then + Begin + If N.FArgs.Count = 1 Then Result := TrimLeft(V) - else + Else Result := TrimLeftEx(V, EvaluateNode(N.FArgs[1])); - end - else - if CompareText(N.FData, 'TRIMRIGHT') = 0 then - begin - if N.FArgs.Count = 1 then + End + Else + If CompareText(N.FData, 'TRIMRIGHT') = 0 Then + Begin + If N.FArgs.Count = 1 Then Result := TrimRight(V) - else + Else Result := TrimRightEx(V, EvaluateNode(N.FArgs[1])); - end - else - if CompareText(N.FData, 'SUBSTRING') = 0 then - begin - if N.FArgs.Count = 2 then + End + Else + If CompareText(N.FData, 'SUBSTRING') = 0 Then + Begin + If N.FArgs.Count = 2 Then Result := Copy(V, Integer(EvaluateNode(N.FArgs[1])), MaxInt) - else + Else Result := Copy(V, Integer(EvaluateNode(N.FArgs[1])), Integer(EvaluateNode(N.FArgs[2]))); - end - else - if CompareText(N.FData, 'YEAR') = 0 then - begin - if VarIsNullEmpty(V) then Result := -1 else + End + Else + If CompareText(N.FData, 'YEAR') = 0 Then + Begin + If VarIsNullEmpty(V) Then Result := -1 Else Result := YearOf(V); - end - else - if CompareText(N.FData, 'MONTH') = 0 then - begin - if VarIsNullEmpty(V) then Result := -1 else + End + Else + If CompareText(N.FData, 'MONTH') = 0 Then + Begin + If VarIsNullEmpty(V) Then Result := -1 Else Result := MonthOf(V); - end - else - if CompareText(N.FData, 'DAY') = 0 then - begin - if VarIsNullEmpty(V) then Result := -1 else + End + Else + If CompareText(N.FData, 'DAY') = 0 Then + Begin + If VarIsNullEmpty(V) Then Result := -1 Else Result := DayOf(V); - end - else - if CompareText(N.FData, 'HOUR') = 0 then - begin - if VarIsNullEmpty(V) then Result := -1 else + End + Else + If CompareText(N.FData, 'HOUR') = 0 Then + Begin + If VarIsNullEmpty(V) Then Result := -1 Else Result := HourOf(V); - end - else - if CompareText(N.FData, 'MINUTE') = 0 then - begin - if VarIsNullEmpty(V) then Result := -1 else + End + Else + If CompareText(N.FData, 'MINUTE') = 0 Then + Begin + If VarIsNullEmpty(V) Then Result := -1 Else Result := MinuteOf(V); - end - else - if CompareText(N.FData, 'SECOND') = 0 then - begin - if VarIsNullEmpty(V) then Result := -1 else + End + Else + If CompareText(N.FData, 'SECOND') = 0 Then + Begin + If VarIsNullEmpty(V) Then Result := -1 Else Result := SecondOf(V); - end - else - if CompareText(N.FData, 'TIME') = 0 then - begin - if VarIsNullEmpty(V) then Result := NULL else + End + Else + If CompareText(N.FData, 'TIME') = 0 Then + Begin + If VarIsNullEmpty(V) Then Result := NULL Else Result := VarSQLTimeStampCreate(TimeOf(V)); - end - else - if CompareText(N.FData, 'DATE') = 0 then - begin - if VarIsNullEmpty(V) then Result := NULL else + End + Else + If CompareText(N.FData, 'DATE') = 0 Then + Begin + If VarIsNullEmpty(V) Then Result := NULL Else Result := VarSQLTimeStampCreate(DateOf(V)); - end - else + End + Else raise Exception.CreateResFmt(@RsUnknownFilterFunction, [N.FData]); - end - else + End + Else raise Exception.CreateResFmt(@RsMissingFilterFunctionParameters, [N.FData]); - end; -end; + End; +End; {$ENDIF} -end. +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemDBUtils.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemDBUtils.pas index 3b5af4221..6103aa73b 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemDBUtils.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemDBUtils.pas @@ -1,21 +1,21 @@ -unit uRESTDWMemDBUtils; +Unit uRESTDWMemDBUtils; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -28,7 +28,7 @@ {$MODE OBJFPC}{$H+} {$ENDIF} -uses +Uses {$IFDEF MSWINDOWS} Windows, {$ENDIF MSWINDOWS} @@ -43,32 +43,32 @@ Type - TFieldListArray = Array of TField; + TFieldListArray = Array Of TField; -type - IRESTDWDataControl = interface +Type + IRESTDWDataControl = Interface ['{8B6910C8-D5FD-40BA-A427-FC54FE7B85E5}'] - function GetDataLink: TDataLink; - end; - TRESTDWDataLink = class(TDataLink) - protected - procedure FocusControl(Field: TFieldRef); overload; override; - procedure FocusControl(const Field: TField); reintroduce; overload; virtual; - end; + Function GetDataLink: TDataLink; + End; + TRESTDWDataLink = Class(TDataLink) + Protected + Procedure FocusControl(Field: TFieldRef); overload; override; + Procedure FocusControl(Const Field: TField); reintroduce; overload; virtual; + End; TCommit = (ctNone, ctStep, ctAll); - TRESTDWDBProgressEvent = procedure(UserData: Integer; var Cancel: Boolean; Line: Integer) of object; - EJvScriptError = class(Exception) - private + TRESTDWDBProgressEvent = Procedure(UserData: Integer; Var Cancel: Boolean; Line: Integer) Of object; + EJvScriptError = Class(Exception) + Private FErrPos: Integer; - public + Public // The dummy parameter is only there for BCB compatibility so that // when the hpp file gets generated, this constructor generates // a C++ constructor that doesn't already exist - constructor Create(const AMessage: string; AErrPos: Integer; DummyForBCB: Integer = 0); overload; + Constructor Create(Const AMessage: string; AErrPos: Integer; DummyForBCB: Integer = 0); overload; property ErrPos: Integer read FErrPos; - end; - TRESTDWLocateObject = class(TObject) - private + End; + TRESTDWLocateObject = Class(TObject) + Private FDataSet: TDataSet; FLookupField: TField; FLookupValue: string; @@ -76,64 +76,64 @@ TRESTDWLocateObject = class(TObject) FCaseSensitive: Boolean; FBookmark: TBookmark; FIndexSwitch: Boolean; - procedure SetDataSet(Value: TDataSet); - protected - function MatchesLookup(Field: TField): Boolean; - procedure CheckFieldType(Field: TField); virtual; - procedure ActiveChanged; virtual; - function LocateKey: Boolean; virtual; - function LocateFull: Boolean; virtual; - function UseKey: Boolean; virtual; - function FilterApplicable: Boolean; virtual; + Procedure SetDataSet(Value: TDataSet); + Protected + Function MatchesLookup(Field: TField): Boolean; + Procedure CheckFieldType(Field: TField); virtual; + Procedure ActiveChanged; virtual; + Function LocateKey: Boolean; virtual; + Function LocateFull: Boolean; virtual; + Function UseKey: Boolean; virtual; + Function FilterApplicable: Boolean; virtual; property LookupField: TField read FLookupField; property LookupValue: string read FLookupValue; property LookupExact: Boolean read FLookupExact; property CaseSensitive: Boolean read FCaseSensitive; property Bookmark: TBookmark read FBookmark write FBookmark; - public + Public // function Locate(const KeyField, KeyValue: string; Exact, // CaseSensitive: Boolean; DisableControls: Boolean = True; // RightTrimmedLookup: Boolean = False): Boolean; property DataSet: TDataSet read FDataSet write SetDataSet; property IndexSwitch: Boolean read FIndexSwitch write FIndexSwitch; - end; - TCreateLocateObject = function: TRESTDWLocateObject; -var + End; + TCreateLocateObject = Function: TRESTDWLocateObject; +Var CreateLocateObject: TCreateLocateObject = nil; -function CreateLocate(DataSet: TDataSet): TRESTDWLocateObject; +Function CreateLocate(DataSet: TDataSet): TRESTDWLocateObject; { Utility routines } -function IsDataSetEmpty(DataSet: TDataSet): Boolean; -procedure RefreshQuery(Query: TDataSet); -function DataSetSortedSearch(DataSet: TDataSet; - const Value, FieldName: string; CaseInsensitive: Boolean): Boolean; -function DataSetSectionName(DataSet: TDataSet): string; -function DataSetLocateThrough(DataSet: TDataSet; const KeyFields: string; - const KeyValues: Variant; Options: TLocateOptions): Boolean; +Function IsDataSetEmpty(DataSet: TDataSet): Boolean; +Procedure RefreshQuery(Query: TDataSet); +Function DataSetSortedSearch(DataSet: TDataSet; + Const Value, FieldName: string; CaseInsensitive: Boolean): Boolean; +Function DataSetSectionName(DataSet: TDataSet): string; +Function DataSetLocateThrough(DataSet: TDataSet; Const KeyFields: string; + Const KeyValues: Variant; Options: TLocateOptions): Boolean; -procedure AssignRecord(Source, Dest: TDataSet; ByName: Boolean); -procedure CheckRequiredField(Field: TField); -procedure CheckRequiredFields(const Fields: array of TField); -procedure GotoBookmarkEx(DataSet: TDataSet; const Bookmark: TBookmark; Mode: TResyncMode = [rmExact, rmCenter]; ForceScrollEvents: Boolean = False); +Procedure AssignRecord(Source, Dest: TDataSet; ByName: Boolean); +Procedure CheckRequiredField(Field: TField); +Procedure CheckRequiredFields(Const Fields: array Of TField); +Procedure GotoBookmarkEx(DataSet: TDataSet; Const Bookmark: TBookmark; Mode: TResyncMode = [rmExact, rmCenter]; ForceScrollEvents: Boolean = False); { SQL expressions } -function DateToSQL(Value: TDateTime): string; -function FormatSQLDateRange(Date1, Date2: TDateTime; - const FieldName: string): string; -function FormatSQLDateRangeEx(Date1, Date2: TDateTime; - const FieldName: string): string; -function FormatSQLNumericRange(const FieldName: string; +Function DateToSQL(Value: TDateTime): string; +Function FormatSQLDateRange(Date1, Date2: TDateTime; + Const FieldName: string): string; +Function FormatSQLDateRangeEx(Date1, Date2: TDateTime; + Const FieldName: string): string; +Function FormatSQLNumericRange(Const FieldName: string; LowValue, HighValue, LowEmpty, HighEmpty: Double; Inclusive: Boolean): string; -function StrMaskSQL(const Value: string): string; -const +Function StrMaskSQL(Const Value: string): string; +Const TrueExpr = '0=0'; {$NODEFINE TrueExpr} -const +Const { Server Date formats} sdfStandard16 = '''"''mm''/''dd''/''yyyy''"'''; {"mm/dd/yyyy"} sdfStandard32 = '''''''dd/mm/yyyy'''''''; {'dd/mm/yyyy'} sdfOracle = '"TO_DATE(''"dd/mm/yyyy"'', ''DD/MM/YYYY'')"'; sdfInterbase = '"CAST(''"mm"/"dd"/"yyyy"'' AS DATE)"'; sdfMSSQL = '"CONVERT(datetime, ''"mm"/"dd"/"yyyy"'', 103)"'; -const +Const ServerDateFmt: string = sdfStandard16; {.$NODEFINE ftNonTextTypes} (*$HPPEMIT 'namespace JvDBUtils'*) @@ -142,14 +142,14 @@ function StrMaskSQL(const Value: string): string; (*$HPPEMIT ' << ftBytes << ftVarBytes << ftBlob << ftMemo << ftGraphic \'*) (*$HPPEMIT ' << ftFmtMemo << ftParadoxOle << ftDBaseOle << ftTypedBinary << ftCursor )'*) (*$HPPEMIT '}'*) -type +Type Largeint = Longint; {$NODEFINE Largeint} -function NameDelimiter(C: Char): Boolean; -function IsLiteral(C: Char): Boolean; -procedure _DBError(const Msg: string); +Function NameDelimiter(C: Char): Boolean; +Function IsLiteral(C: Char): Boolean; +Procedure _DBError(Const Msg: string); {$IFDEF UNITVERSIONING} -const +Const UnitVersioning: TUnitVersionInfo = ( RCSfile: '$URL$'; Revision: '$Revision$'; @@ -157,8 +157,8 @@ procedure _DBError(const Msg: string); LogPath: 'JVCL\run' ); {$ENDIF UNITVERSIONING} -implementation -uses +Implementation +Uses Math, {$IFDEF HAS_UNIT_SYSTEM_UITYPES} System.UITypes, @@ -171,96 +171,96 @@ implementation uRESTDWConsts; { TRESTDWDataLink } -procedure TRESTDWDataLink.FocusControl(Field: TFieldRef); -begin +Procedure TRESTDWDataLink.FocusControl(Field: TFieldRef); +Begin FocusControl(Field^); -end; -procedure TRESTDWDataLink.FocusControl(const Field: TField); -begin -end; +End; +Procedure TRESTDWDataLink.FocusControl(Const Field: TField); +Begin +End; { Utility routines } -function NameDelimiter(C: Char): Boolean; -begin +Function NameDelimiter(C: Char): Boolean; +Begin Result := RESTDWCharInSet(C, [' ', ',', ';', ')', '.', Cr, Lf]); -end; -function IsLiteral(C: Char): Boolean; -begin +End; +Function IsLiteral(C: Char): Boolean; +Begin Result := RESTDWCharInSet(C, ['''', '"']); -end; -procedure _DBError(const Msg: string); -begin +End; +Procedure _DBError(Const Msg: string); +Begin DatabaseError(Msg); -end; -constructor EJvScriptError.Create(const AMessage: string; AErrPos: Integer; DummyForBCB: Integer); -begin - inherited Create(AMessage); +End; +Constructor EJvScriptError.Create(Const AMessage: string; AErrPos: Integer; DummyForBCB: Integer); +Begin + Inherited Create(AMessage); FErrPos := AErrPos; -end; +End; // (rom) better use Windows dialogs which are localized -function SetToBookmark(ADataSet: TDataSet; ABookmark: TBookmark): Boolean; -begin +Function SetToBookmark(ADataSet: TDataSet; ABookmark: TBookmark): Boolean; +Begin Result := False; - if ADataSet.Active and (ABookmark <> nil) and not (ADataSet.Bof and ADataSet.Eof) and - ADataSet.BookmarkValid(ABookmark) then - try + If ADataSet.Active and (ABookmark <> nil) and not (ADataSet.Bof and ADataSet.Eof) and + ADataSet.BookmarkValid(ABookmark) Then + Try ADataSet.GotoBookmark(ABookmark); Result := True; - except - end; -end; + Except + End; +End; { Refresh Query procedure } -procedure RefreshQuery(Query: TDataSet); -var +Procedure RefreshQuery(Query: TDataSet); +Var BookMk: TBookmark; -begin +Begin Query.DisableControls; - try - if Query.Active then + Try + If Query.Active Then BookMk := Query.GetBookmark - else + Else BookMk := nil; - try + Try Query.Close; Query.Open; SetToBookmark(Query, BookMk); - finally - if BookMk <> nil then + Finally + If BookMk <> nil Then Query.FreeBookmark(BookMk); - end; - finally + End; + Finally Query.EnableControls; - end; -end; -procedure TRESTDWLocateObject.SetDataSet(Value: TDataSet); -begin + End; +End; +Procedure TRESTDWLocateObject.SetDataSet(Value: TDataSet); +Begin ActiveChanged; FDataSet := Value; -end; -function TRESTDWLocateObject.LocateFull: Boolean; -begin +End; +Function TRESTDWLocateObject.LocateFull: Boolean; +Begin Result := False; DataSet.First; - while not DataSet.Eof do - begin - if MatchesLookup(FLookupField) then - begin + While not DataSet.Eof Do + Begin + If MatchesLookup(FLookupField) Then + Begin Result := True; Break; - end; + End; DataSet.Next; - end; -end; -function TRESTDWLocateObject.LocateKey: Boolean; -begin + End; +End; +Function TRESTDWLocateObject.LocateKey: Boolean; +Begin Result := False; -end; -function TRESTDWLocateObject.FilterApplicable: Boolean; -begin +End; +Function TRESTDWLocateObject.FilterApplicable: Boolean; +Begin Result := FLookupField.FieldKind in [fkData, fkInternalCalc]; -end; -procedure TRESTDWLocateObject.CheckFieldType(Field: TField); -begin -end; +End; +Procedure TRESTDWLocateObject.CheckFieldType(Field: TField); +Begin +End; //function TRESTDWLocateObject.Locate(const KeyField, KeyValue: string; // Exact, CaseSensitive: Boolean; DisableControls: Boolean; RightTrimmedLookup: Boolean): Boolean; //var @@ -332,28 +332,28 @@ procedure TRESTDWLocateObject.CheckFieldType(Field: TField); // DataSet.EnableControls; // end; //end; -function TRESTDWLocateObject.UseKey: Boolean; -begin +Function TRESTDWLocateObject.UseKey: Boolean; +Begin Result := False; -end; -procedure TRESTDWLocateObject.ActiveChanged; -begin -end; -function TRESTDWLocateObject.MatchesLookup(Field: TField): Boolean; -var +End; +Procedure TRESTDWLocateObject.ActiveChanged; +Begin +End; +Function TRESTDWLocateObject.MatchesLookup(Field: TField): Boolean; +Var Temp: string; -begin +Begin Temp := Field.AsString; - if not LookupExact then + If not LookupExact Then SetLength(Temp, Min(Length(FLookupValue), Length(Temp))); - if CaseSensitive then + If CaseSensitive Then Result := AnsiSameStr(Temp, LookupValue) - else + Else Result := AnsiSameText(Temp, LookupValue); -end; -function CreateLocate(DataSet: TDataSet): TRESTDWLocateObject; -begin - if Assigned(CreateLocateObject) then +End; +Function CreateLocate(DataSet: TDataSet): TRESTDWLocateObject; +Begin + If Assigned(CreateLocateObject) Then Begin {$IFDEF FPC} Result := CreateLocateObject(); @@ -361,99 +361,99 @@ function CreateLocate(DataSet: TDataSet): TRESTDWLocateObject; Result := CreateLocateObject; {$ENDIF} End - else + Else Result := TRESTDWLocateObject.Create; - if (Result <> nil) and (DataSet <> nil) then + If (Result <> nil) and (DataSet <> nil) Then Result.DataSet := DataSet; -end; +End; { DataSet locate routines } -function DataSetLocateThrough(DataSet: TDataSet; const KeyFields: string; - const KeyValues: Variant; Options: TLocateOptions): Boolean; -var +Function DataSetLocateThrough(DataSet: TDataSet; Const KeyFields: string; + Const KeyValues: Variant; Options: TLocateOptions): Boolean; +Var FieldCount : Integer; Fields : TFieldListArray; Bookmark: TBookmarkType; - function CompareField(Field: TField; const Value: Variant): Boolean; - var + Function CompareField(Field: TField; Const Value: Variant): Boolean; + Var S, A : string; - begin - if Field.DataType in [ftString{$IFDEF UNICODE}, ftWideString{$ENDIF UNICODE}] then - begin - if Value = Null then + Begin + If Field.DataType in [ftString{$IFDEF UNICODE}, ftWideString{$ENDIF UNICODE}] Then + Begin + If Value = Null Then Result := Field.IsNull - else - begin + Else + Begin S := Field.AsString; A := Copy(Value, InitStrPos, Field.Size); - if loPartialKey in Options then + If loPartialKey in Options Then Delete(S, Length(Value) + 1, MaxInt); - if loCaseInsensitive in Options then + If loCaseInsensitive in Options Then Result := Uppercase(S) = Uppercase(A) - else + Else Result := S = A; - end; - end - else + End; + End + Else Result := (Field.Value = Value); - end; - function CompareRecord: Boolean; - var + End; + Function CompareRecord: Boolean; + Var I: Integer; - begin + Begin // Works with the KeyValues variant like TCustomClientDataSet.LocateRecord - if (FieldCount = 1) and not VarIsArray(KeyValues) then + If (FieldCount = 1) and not VarIsArray(KeyValues) Then Result := CompareField(TField(Fields[0]), KeyValues) - else - begin + Else + Begin Result := True; - for I := 0 to FieldCount - 1 do + For I := 0 To FieldCount - 1 Do Result := Result and CompareField(TField(Fields[I]), KeyValues[I]); - end; - end; - procedure GetFieldList(List: TFieldListArray; const FieldNames: string); - var + End; + End; + Procedure GetFieldList(List: TFieldListArray; Const FieldNames: string); + Var I, Len, Pos : Integer; Field : TField; - begin + Begin Len := FieldNames.Length; Pos := 1; I := 0; - while Pos <= Len do - begin + While Pos <= Len Do + Begin Field := DataSet.FieldByName(ExtractFieldName(FieldNames, Pos)); SetLength(Fields, I+1); Fields[I] := Field; Inc(I); - end; + End; End; -begin +Begin Result := False; SetLength(Fields, 0); DataSet.CheckBrowseMode; - if DataSet.IsEmpty then + If DataSet.IsEmpty Then Exit; // Fields := TList.Create; - try + Try GetFieldList(Fields, KeyFields); FieldCount := Length(Fields); Result := CompareRecord; - if Result then + If Result Then Exit; DataSet.DisableControls; - try + Try Bookmark := TBookmarkType(DataSet.Bookmark); - try + Try DataSet.First; - while not DataSet.Eof do - begin + While not DataSet.Eof Do + Begin Result := CompareRecord; - if Result then + If Result Then Break; DataSet.Next; - end; - finally - if not Result and DataSet.BookmarkValid(TBookmark(Bookmark)) then + End; + Finally + If not Result and DataSet.BookmarkValid(TBookmark(Bookmark)) Then Begin {$IFNDEF FPC} {$IF CompilerVersion > 21} @@ -465,239 +465,239 @@ function DataSetLocateThrough(DataSet: TDataSet; const KeyFields: string; DataSet.Bookmark := TBookmark(Bookmark); {$ENDIF} End; - end; - finally + End; + Finally DataSet.EnableControls; - end; - finally + End; + Finally SetLength(Fields, 0); // Fields.Free; - end; -end; + End; +End; { DataSetSortedSearch. Navigate on sorted DataSet routine. } -function DataSetSortedSearch(DataSet: TDataSet; const Value, +Function DataSetSortedSearch(DataSet: TDataSet; Const Value, FieldName: string; CaseInsensitive: Boolean): Boolean; -var +Var L, H, I: Longint; CurrentPos: Longint; CurrentValue: string; BookMk: TBookmark; Field: TField; - function UpStr(const Value: string): string; - begin - if CaseInsensitive then + Function UpStr(Const Value: string): string; + Begin + If CaseInsensitive Then Result := AnsiUpperCase(Value) - else + Else Result := Value; - end; - function GetCurrentStr: string; - begin + End; + Function GetCurrentStr: string; + Begin Result := Field.AsString; - if Length(Result) > Length(Value) then + If Length(Result) > Length(Value) Then SetLength(Result, Length(Value)); Result := UpStr(Result); - end; -begin + End; +Begin Result := False; - if DataSet = nil then + If DataSet = nil Then Exit; Field := DataSet.FindField(FieldName); - if Field = nil then + If Field = nil Then Exit; - if Field.DataType in [ftString{$IFDEF UNICODE}, ftWideString{$ENDIF UNICODE}] then - begin + If Field.DataType in [ftString{$IFDEF UNICODE}, ftWideString{$ENDIF UNICODE}] Then + Begin DataSet.DisableControls; BookMk := DataSet.GetBookmark; - try + Try L := 0; DataSet.First; CurrentPos := 0; H := DataSet.RecordCount - 1; - if Value <> '' then - begin - while L <= H do - begin + If Value <> '' Then + Begin + While L <= H Do + Begin I := (L + H) shr 1; - if I <> CurrentPos then + If I <> CurrentPos Then DataSet.MoveBy(I - CurrentPos); CurrentPos := I; CurrentValue := GetCurrentStr; - if UpStr(Value) > CurrentValue then + If UpStr(Value) > CurrentValue Then L := I + 1 - else - begin + Else + Begin H := I - 1; - if UpStr(Value) = CurrentValue then + If UpStr(Value) = CurrentValue Then Result := True; - end; - end; - if Result then - begin - if L <> CurrentPos then + End; + End; + If Result Then + Begin + If L <> CurrentPos Then DataSet.MoveBy(L - CurrentPos); - while (L < DataSet.RecordCount) and - (UpStr(Value) <> GetCurrentStr) do - begin + While (L < DataSet.RecordCount) and + (UpStr(Value) <> GetCurrentStr) Do + Begin Inc(L); DataSet.MoveBy(1); - end; - end; - end - else + End; + End; + End + Else Result := True; - if not Result then + If not Result Then SetToBookmark(DataSet, BookMk); - finally + Finally DataSet.FreeBookmark(BookMk); DataSet.EnableControls; - end; - end - else + End; + End + Else DatabaseErrorFmt('Field %s TypeMismatch', [Field.DisplayName]); -end; +End; { Save and restore DataSet Fields layout } -function DataSetSectionName(DataSet: TDataSet): string; -begin +Function DataSetSectionName(DataSet: TDataSet): string; +Begin Result := DataSet.Name; -end; -function CheckSection(DataSet: TDataSet; const Section: string): string; -begin +End; +Function CheckSection(DataSet: TDataSet; Const Section: string): string; +Begin Result := Section; - if Result = '' then + If Result = '' Then Result := DataSetSectionName(DataSet); -end; -function IsDataSetEmpty(DataSet: TDataSet): Boolean; -begin +End; +Function IsDataSetEmpty(DataSet: TDataSet): Boolean; +Begin Result := (not DataSet.Active) or (DataSet.Eof and DataSet.Bof); -end; +End; { SQL expressions } -function DateToSQL(Value: TDateTime): string; -begin +Function DateToSQL(Value: TDateTime): string; +Begin Result := IntToStr(Trunc(Value)); -end; -function FormatSQLDateRange(Date1, Date2: TDateTime; - const FieldName: string): string; -begin +End; +Function FormatSQLDateRange(Date1, Date2: TDateTime; + Const FieldName: string): string; +Begin Result := TrueExpr; - if (Date1 = Date2) and (Date1 <> NullDate) then - begin + If (Date1 = Date2) and (Date1 <> NullDate) Then + Begin Result := Format('%s = %s', [FieldName, FormatDateTime(ServerDateFmt, Date1)]); - end - else - if (Date1 <> NullDate) or (Date2 <> NullDate) then - begin - if Date1 = NullDate then + End + Else + If (Date1 <> NullDate) or (Date2 <> NullDate) Then + Begin + If Date1 = NullDate Then Result := Format('%s < %s', [FieldName, FormatDateTime(ServerDateFmt, IncDay(Date2, 1))]) - else - if Date2 = NullDate then + Else + If Date2 = NullDate Then Result := Format('%s > %s', [FieldName, FormatDateTime(ServerDateFmt, IncDay(Date1, -1))]) - else + Else Result := Format('(%s < %s) AND (%s > %s)', [FieldName, FormatDateTime(ServerDateFmt, IncDay(Date2, 1)), FieldName, FormatDateTime(ServerDateFmt, IncDay(Date1, -1))]); - end; -end; -function FormatSQLDateRangeEx(Date1, Date2: TDateTime; - const FieldName: string): string; -begin + End; +End; +Function FormatSQLDateRangeEx(Date1, Date2: TDateTime; + Const FieldName: string): string; +Begin Result := TrueExpr; - if (Date1 <> NullDate) or (Date2 <> NullDate) then - begin - if Date1 = NullDate then + If (Date1 <> NullDate) or (Date2 <> NullDate) Then + Begin + If Date1 = NullDate Then Result := Format('%s < %s', [FieldName, FormatDateTime(ServerDateFmt, IncDay(Date2, 1))]) - else - if Date2 = NullDate then + Else + If Date2 = NullDate Then Result := Format('%s >= %s', [FieldName, FormatDateTime(ServerDateFmt, Date1)]) - else + Else Result := Format('(%s < %s) AND (%s >= %s)', [FieldName, FormatDateTime(ServerDateFmt, IncDay(Date2, 1)), FieldName, FormatDateTime(ServerDateFmt, Date1)]); - end; -end; -function FormatSQLNumericRange(const FieldName: string; + End; +End; +Function FormatSQLNumericRange(Const FieldName: string; LowValue, HighValue, LowEmpty, HighEmpty: Double; Inclusive: Boolean): string; -const - Operators: array[Boolean, 1..2] of string = (('>', '<'), ('>=', '<=')); -begin +Const + Operators: array[Boolean, 1..2] Of string = (('>', '<'), ('>=', '<=')); +Begin Result := TrueExpr; - if (LowValue = HighValue) and (LowValue <> LowEmpty) then + If (LowValue = HighValue) and (LowValue <> LowEmpty) Then Result := Format('%s = %g', [FieldName, LowValue]) - else - if (LowValue <> LowEmpty) or (HighValue <> HighEmpty) then - begin - if LowValue = LowEmpty then + Else + If (LowValue <> LowEmpty) or (HighValue <> HighEmpty) Then + Begin + If LowValue = LowEmpty Then Result := Format('%s %s %g', [FieldName, Operators[Inclusive, 2], HighValue]) - else - if HighValue = HighEmpty then + Else + If HighValue = HighEmpty Then Result := Format('%s %s %g', [FieldName, Operators[Inclusive, 1], LowValue]) - else + Else Result := Format('(%s %s %g) AND (%s %s %g)', [FieldName, Operators[Inclusive, 2], HighValue, FieldName, Operators[Inclusive, 1], LowValue]); - end; -end; -function StrMaskSQL(const Value: string): string; -begin - if (Pos('*', Value) = 0) and (Pos('?', Value) = 0) and (Value <> '') then + End; +End; +Function StrMaskSQL(Const Value: string): string; +Begin + If (Pos('*', Value) = 0) and (Pos('?', Value) = 0) and (Value <> '') Then Result := '*' + Value + '*' - else + Else Result := Value; -end; -procedure CheckRequiredField(Field: TField); -begin - if not Field.ReadOnly and not Field.Calculated and Field.IsNull then - begin +End; +Procedure CheckRequiredField(Field: TField); +Begin + If not Field.ReadOnly and not Field.Calculated and Field.IsNull Then + Begin Field.FocusControl; DatabaseErrorFmt('Field %s Required', [Field.DisplayName]); - end; -end; -procedure CheckRequiredFields(const Fields: array of TField); -var + End; +End; +Procedure CheckRequiredFields(Const Fields: array Of TField); +Var I: Integer; -begin - for I := Low(Fields) to High(Fields) do +Begin + For I := Low(Fields) To High(Fields) Do CheckRequiredField(Fields[I]); -end; -type - TDataSetAccess = class(TDataSet); -procedure GotoBookmarkEx(DataSet: TDataSet; const Bookmark: TBookmark; Mode: TResyncMode; ForceScrollEvents: Boolean); -var +End; +Type + TDataSetAccess = Class(TDataSet); +Procedure GotoBookmarkEx(DataSet: TDataSet; Const Bookmark: TBookmark; Mode: TResyncMode; ForceScrollEvents: Boolean); +Var DS: TDataSetAccess; -begin - if (DataSet <> nil) and (Bookmark <> nil) then - begin +Begin + If (DataSet <> nil) and (Bookmark <> nil) Then + Begin DS := TDataSetAccess(DataSet); DS.CheckBrowseMode; - if ForceScrollEvents or (rmCenter in Mode) then DS.DoBeforeScroll; + If ForceScrollEvents or (rmCenter in Mode) Then DS.DoBeforeScroll; DS.InternalGotoBookmark({$IFNDEF RTL240_UP}Pointer{$ENDIF}(Bookmark)); DS.Resync(Mode); - if ForceScrollEvents or (rmCenter in Mode) then DS.DoAfterScroll; - end; -end; -procedure AssignRecord(Source, Dest: TDataSet; ByName: Boolean); -var + If ForceScrollEvents or (rmCenter in Mode) Then DS.DoAfterScroll; + End; +End; +Procedure AssignRecord(Source, Dest: TDataSet; ByName: Boolean); +Var I: Integer; F, FSrc: TField; -begin - if not (Dest.State in dsEditModes) then +Begin + If not (Dest.State in dsEditModes) Then _DBError('Not Editing'); - if ByName then - begin - for I := 0 to Source.FieldCount - 1 do - begin + If ByName Then + Begin + For I := 0 To Source.FieldCount - 1 Do + Begin F := Dest.FindField(Source.Fields[I].FieldName); FSrc := Source.Fields[i]; - if (F <> nil) and (F.DataType <> ftAutoInc) then - begin - if FSrc.IsNull then + If (F <> nil) and (F.DataType <> ftAutoInc) Then + Begin + If FSrc.IsNull Then F.Value := FSrc.Value - else - case F.DataType of + Else + Case F.DataType Of ftString: F.AsString := FSrc.AsString; ftInteger: F.AsInteger := FSrc.AsInteger; ftBoolean: F.AsBoolean := FSrc.AsBoolean; @@ -705,24 +705,24 @@ procedure AssignRecord(Source, Dest: TDataSet; ByName: Boolean); ftCurrency: F.AsCurrency := FSrc.AsCurrency; ftDate: F.AsDateTime := FSrc.AsDateTime; ftDateTime: F.AsDateTime := FSrc.AsDateTime; - else + Else F.Value := FSrc.Value; - end; - end; - end; - end - else - begin - for I := 0 to Min(Source.FieldDefs.Count - 1, Dest.FieldDefs.Count - 1) do - begin + End; + End; + End; + End + Else + Begin + For I := 0 To Min(Source.FieldDefs.Count - 1, Dest.FieldDefs.Count - 1) Do + Begin F := Dest.FindField(Dest.FieldDefs[I].Name); FSrc := Source.FindField(Source.FieldDefs[I].Name); - if (F <> nil) and (FSrc <> nil) and (F.DataType <> ftAutoInc) then - begin - if FSrc.IsNull then + If (F <> nil) and (FSrc <> nil) and (F.DataType <> ftAutoInc) Then + Begin + If FSrc.IsNull Then F.Value := FSrc.Value - else - case F.DataType of + Else + Case F.DataType Of ftString: F.AsString := FSrc.AsString; ftInteger: F.AsInteger := FSrc.AsInteger; ftBoolean: F.AsBoolean := FSrc.AsBoolean; @@ -730,11 +730,11 @@ procedure AssignRecord(Source, Dest: TDataSet; ByName: Boolean); ftCurrency: F.AsCurrency := FSrc.AsCurrency; ftDate: F.AsDateTime := FSrc.AsDateTime; ftDateTime: F.AsDateTime := FSrc.AsDateTime; - else + Else F.Value := FSrc.Value; - end; - end; - end; - end; -end; -end. + End; + End; + End; + End; +End; +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemDateTime.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemDateTime.pas index eb9c3df47..ce165ceaa 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemDateTime.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemDateTime.pas @@ -1,29 +1,29 @@ -unit uRESTDWMemDateTime; -{$I ..\..\Includes\uRESTDW.inc} +Unit uRESTDWMemDateTime; +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. Roniery - Devel. } -interface -uses +Interface +Uses {$IFDEF UNITVERSIONING} JclUnitVersioning, {$ENDIF UNITVERSIONING} @@ -49,119 +49,119 @@ interface {$ENDIF FPC} {$ENDIF} uRESTDWMemBase, uRESTDWMemResources; -const +Const // 1970-01-01T00:00:00 in TDateTime UnixTimeStart = 25569; { Encode / Decode functions } -function EncodeDate(const Year: Integer; Month, Day: Word): TDateTime; -procedure DecodeDate(Date: TDateTime; out Year, Month, Day: Word); overload; -procedure DecodeDate(Date: TDateTime; out Year: Integer; out Month, Day: Word); overload; -procedure DecodeDate(Date: TDateTime; out Year, Month, Day: Integer); overload; -function CenturyOfDate(const DateTime: TDateTime): Integer; -function CenturyBaseYear(const DateTime: TDateTime): Integer; -function DayOfDate(const DateTime: TDateTime): Integer; -function MonthOfDate(const DateTime: TDateTime): Integer; -function YearOfDate(const DateTime: TDateTime): Integer; -function DayOfTheYear(const DateTime: TDateTime; out Year: Integer): Integer; overload; -function DayOfTheYear(const DateTime: TDateTime): Integer; overload; -function DayOfTheYearToDateTime(const Year, Day: Integer): TDateTime; -function HourOfTime(const DateTime: TDateTime): Integer; -function MinuteOfTime(const DateTime: TDateTime): Integer; -function SecondOfTime(const DateTime: TDateTime): Integer; +Function EncodeDate(Const Year: Integer; Month, Day: Word): TDateTime; +Procedure DecodeDate(Date: TDateTime; out Year, Month, Day: Word); overload; +Procedure DecodeDate(Date: TDateTime; out Year: Integer; out Month, Day: Word); overload; +Procedure DecodeDate(Date: TDateTime; out Year, Month, Day: Integer); overload; +Function CenturyOfDate(Const DateTime: TDateTime): Integer; +Function CenturyBaseYear(Const DateTime: TDateTime): Integer; +Function DayOfDate(Const DateTime: TDateTime): Integer; +Function MonthOfDate(Const DateTime: TDateTime): Integer; +Function YearOfDate(Const DateTime: TDateTime): Integer; +Function DayOfTheYear(Const DateTime: TDateTime; out Year: Integer): Integer; overload; +Function DayOfTheYear(Const DateTime: TDateTime): Integer; overload; +Function DayOfTheYearToDateTime(Const Year, Day: Integer): TDateTime; +Function HourOfTime(Const DateTime: TDateTime): Integer; +Function MinuteOfTime(Const DateTime: TDateTime): Integer; +Function SecondOfTime(Const DateTime: TDateTime): Integer; { ISO 8601 support } -function GetISOYearNumberOfWeeks(const Year: Word): Word; -function IsISOLongYear(const Year: Word): Boolean; overload; -function IsISOLongYear(const DateTime: TDateTime): Boolean; overload; -function ISODayOfWeek(const DateTime: TDateTime): Word; -function ISOWeekNumber(DateTime: TDateTime; out YearOfWeekNumber, WeekDay: Integer): Integer; overload; -function ISOWeekNumber(DateTime: TDateTime; out YearOfWeekNumber: Integer): Integer; overload; -function ISOWeekNumber(DateTime: TDateTime): Integer; overload; -function ISOWeekToDateTime(const Year, Week, Day: Integer): TDateTime; +Function GetISOYearNumberOfWeeks(Const Year: Word): Word; +Function IsISOLongYear(Const Year: Word): Boolean; overload; +Function IsISOLongYear(Const DateTime: TDateTime): Boolean; overload; +Function ISODayOfWeek(Const DateTime: TDateTime): Word; +Function ISOWeekNumber(DateTime: TDateTime; out YearOfWeekNumber, WeekDay: Integer): Integer; overload; +Function ISOWeekNumber(DateTime: TDateTime; out YearOfWeekNumber: Integer): Integer; overload; +Function ISOWeekNumber(DateTime: TDateTime): Integer; overload; +Function ISOWeekToDateTime(Const Year, Week, Day: Integer): TDateTime; { Miscellanous } -function IsLeapYear(const Year: Integer): Boolean; overload; -function IsLeapYear(const DateTime: TDateTime): Boolean; overload; -function DaysInMonth(const DateTime: TDateTime): Integer; -function Make4DigitYear(Year, Pivot: Integer): Integer; -function MakeYear4Digit(Year, WindowsillYear: Integer): Integer; -function EasterSunday(const Year: Integer): TDateTime; -function FormatDateTime(Form: string; DateTime: TDateTime): string; -function FATDatesEqual(const FileTime1, FileTime2: Int64): Boolean; overload; -function FATDatesEqual(const FileTime1, FileTime2: TFileTime): Boolean; overload; +Function IsLeapYear(Const Year: Integer): Boolean; overload; +Function IsLeapYear(Const DateTime: TDateTime): Boolean; overload; +Function DaysInMonth(Const DateTime: TDateTime): Integer; +Function Make4DigitYear(Year, Pivot: Integer): Integer; +Function MakeYear4Digit(Year, WindowsillYear: Integer): Integer; +Function EasterSunday(Const Year: Integer): TDateTime; +Function FormatDateTime(Form: string; DateTime: TDateTime): string; +Function FATDatesEqual(Const FileTime1, FileTime2: Int64): Boolean; overload; +Function FATDatesEqual(Const FileTime1, FileTime2: TFileTime): Boolean; overload; // Conversion -type +Type TDosDateTime = Integer; -function HoursToMSecs(Hours: Integer): Integer; -function MinutesToMSecs(Minutes: Integer): Integer; -function SecondsToMSecs(Seconds: Integer): Integer; -function TimeOfDateTimeToSeconds(DateTime: TDateTime): Integer; -function TimeOfDateTimeToMSecs(DateTime: TDateTime): Integer; -function DateTimeToLocalDateTime(DateTime: TDateTime): TDateTime; -function LocalDateTimeToDateTime(DateTime: TDateTime): TDateTime; +Function HoursToMSecs(Hours: Integer): Integer; +Function MinutesToMSecs(Minutes: Integer): Integer; +Function SecondsToMSecs(Seconds: Integer): Integer; +Function TimeOfDateTimeToSeconds(DateTime: TDateTime): Integer; +Function TimeOfDateTimeToMSecs(DateTime: TDateTime): Integer; +Function DateTimeToLocalDateTime(DateTime: TDateTime): TDateTime; +Function LocalDateTimeToDateTime(DateTime: TDateTime): TDateTime; {$IFDEF MSWINDOWS} -function DateTimeToDosDateTime(const DateTime: TDateTime): TDosDateTime; -function DateTimeToFileTime(DateTime: TDateTime): TFileTime; -function DateTimeToSystemTime(DateTime: TDateTime): TSystemTime; overload; -procedure DateTimeToSystemTime(DateTime: TDateTime; out SysTime: TSystemTime); overload; -function LocalDateTimeToFileTime(DateTime: TDateTime): FileTime; +Function DateTimeToDosDateTime(Const DateTime: TDateTime): TDosDateTime; +Function DateTimeToFileTime(DateTime: TDateTime): TFileTime; +Function DateTimeToSystemTime(DateTime: TDateTime): TSystemTime; overload; +Procedure DateTimeToSystemTime(DateTime: TDateTime; out SysTime: TSystemTime); overload; +Function LocalDateTimeToFileTime(DateTime: TDateTime): FileTime; {$ENDIF MSWINDOWS} -function DosDateTimeToDateTime(const DosTime: TDosDateTime): TDateTime; +Function DosDateTimeToDateTime(Const DosTime: TDosDateTime): TDateTime; {$IFDEF MSWINDOWS} -function DosDateTimeToFileTime(DosTime: TDosDateTime): TFileTime; overload; -procedure DosDateTimeToFileTime(DTH, DTL: Word; FT: TFileTime); overload; -function DosDateTimeToSystemTime(const DosTime: TDosDateTime): TSystemTime; +Function DosDateTimeToFileTime(DosTime: TDosDateTime): TFileTime; overload; +Procedure DosDateTimeToFileTime(DTH, DTL: Word; FT: TFileTime); overload; +Function DosDateTimeToSystemTime(Const DosTime: TDosDateTime): TSystemTime; {$ENDIF MSWINDOWS} -function DosDateTimeToStr(DateTime: Integer): string; -function FileTimeToDateTime(const FileTime: TFileTime): TDateTime; +Function DosDateTimeToStr(DateTime: Integer): string; +Function FileTimeToDateTime(Const FileTime: TFileTime): TDateTime; {$IFDEF MSWINDOWS} -function FileTimeToLocalDateTime(const FileTime: TFileTime): TDateTime; -function FileTimeToDosDateTime(const FileTime: TFileTime): TDosDateTime; overload; -procedure FileTimeToDosDateTime(const FileTime: TFileTime; out Date, Time: Word); overload; -function FileTimeToSystemTime(const FileTime: TFileTime): TSystemTime; overload; -procedure FileTimeToSystemTime(const FileTime: TFileTime; out ST: TSystemTime); overload; +Function FileTimeToLocalDateTime(Const FileTime: TFileTime): TDateTime; +Function FileTimeToDosDateTime(Const FileTime: TFileTime): TDosDateTime; overload; +Procedure FileTimeToDosDateTime(Const FileTime: TFileTime; out Date, Time: Word); overload; +Function FileTimeToSystemTime(Const FileTime: TFileTime): TSystemTime; overload; +Procedure FileTimeToSystemTime(Const FileTime: TFileTime; out ST: TSystemTime); overload; {$ENDIF MSWINDOWS} -function FileTimeToStr(const FileTime: TFileTime): string; +Function FileTimeToStr(Const FileTime: TFileTime): string; {$IFDEF MSWINDOWS} -function SystemTimeToDosDateTime(const SystemTime: TSystemTime): TDosDateTime; -function SystemTimeToFileTime(const SystemTime: TSystemTime): TFileTime; overload; -procedure SystemTimeToFileTime(const SystemTime: TSystemTime; FTime: TFileTime); overload; -function SystemTimeToStr(const SystemTime: TSystemTime): string; +Function SystemTimeToDosDateTime(Const SystemTime: TSystemTime): TDosDateTime; +Function SystemTimeToFileTime(Const SystemTime: TSystemTime): TFileTime; overload; +Procedure SystemTimeToFileTime(Const SystemTime: TSystemTime; FTime: TFileTime); overload; +Function SystemTimeToStr(Const SystemTime: TSystemTime): string; // Filedates -function CreationDateTimeOfFile(const Sr: TSearchRec): TDateTime; -function LastAccessDateTimeOfFile(const Sr: TSearchRec): TDateTime; -function LastWriteDateTimeOfFile(const Sr: TSearchRec): TDateTime; +Function CreationDateTimeOfFile(Const Sr: TSearchRec): TDateTime; +Function LastAccessDateTimeOfFile(Const Sr: TSearchRec): TDateTime; +Function LastWriteDateTimeOfFile(Const Sr: TSearchRec): TDateTime; {$ENDIF MSWINDOWS} -type +Type TJclUnixTime32 = Longword; -function DateTimeToUnixTime(DateTime: TDateTime): TJclUnixTime32; -function UnixTimeToDateTime(const UnixTime: TJclUnixTime32): TDateTime; +Function DateTimeToUnixTime(DateTime: TDateTime): TJclUnixTime32; +Function UnixTimeToDateTime(Const UnixTime: TJclUnixTime32): TDateTime; {$IFDEF MSWINDOWS} -function FileTimeToUnixTime(const AValue: TFileTime): TJclUnixTime32; -function UnixTimeToFileTime(const AValue: TJclUnixTime32): TFileTime; +Function FileTimeToUnixTime(Const AValue: TFileTime): TJclUnixTime32; +Function UnixTimeToFileTime(Const AValue: TJclUnixTime32): TFileTime; {$ENDIF MSWINDOWS} // Time stamps (formerly in JclSchedule) -function NullStamp: TTimeStamp; -function CompareTimeStamps(const Stamp1, Stamp2: TTimeStamp): Int64; -function EqualTimeStamps(const Stamp1, Stamp2: TTimeStamp): Boolean; -function IsNullTimeStamp(const Stamp: TTimeStamp): Boolean; -function TimeStampDOW(const Stamp: TTimeStamp): Integer; +Function NullStamp: TTimeStamp; +Function CompareTimeStamps(Const Stamp1, Stamp2: TTimeStamp): Int64; +Function EqualTimeStamps(Const Stamp1, Stamp2: TTimeStamp): Boolean; +Function IsNullTimeStamp(Const Stamp: TTimeStamp): Boolean; +Function TimeStampDOW(Const Stamp: TTimeStamp): Integer; // Day of week (formerly in JclSchedule) -function FirstWeekDay(const Year, Month: Integer; out DOW: Integer): Integer; overload; -function FirstWeekDay(const Year, Month: Integer): Integer; overload; -function LastWeekDay(const Year, Month: Integer; out DOW: Integer): Integer; overload; -function LastWeekDay(const Year, Month: Integer): Integer; overload; -function IndexedWeekDay(const Year, Month: Integer; Index: Integer): Integer; -function FirstWeekendDay(const Year, Month: Integer; out DOW: Integer): Integer; overload; -function FirstWeekendDay(const Year, Month: Integer): Integer; overload; -function LastWeekendDay(const Year, Month: Integer; out DOW: Integer): Integer; overload; -function LastWeekendDay(const Year, Month: Integer): Integer; overload; -function IndexedWeekendDay(const Year, Month: Integer; Index: Integer): Integer; -function FirstDayOfWeek(const Year, Month, DayOfWeek: Integer): Integer; -function LastDayOfWeek(const Year, Month, DayOfWeek: Integer): Integer; -function IndexedDayOfWeek(const Year, Month, DayOfWeek, Index: Integer): Integer; -type - EJclDateTimeError = class(EJclError); +Function FirstWeekDay(Const Year, Month: Integer; out DOW: Integer): Integer; overload; +Function FirstWeekDay(Const Year, Month: Integer): Integer; overload; +Function LastWeekDay(Const Year, Month: Integer; out DOW: Integer): Integer; overload; +Function LastWeekDay(Const Year, Month: Integer): Integer; overload; +Function IndexedWeekDay(Const Year, Month: Integer; Index: Integer): Integer; +Function FirstWeekendDay(Const Year, Month: Integer; out DOW: Integer): Integer; overload; +Function FirstWeekendDay(Const Year, Month: Integer): Integer; overload; +Function LastWeekendDay(Const Year, Month: Integer; out DOW: Integer): Integer; overload; +Function LastWeekendDay(Const Year, Month: Integer): Integer; overload; +Function IndexedWeekendDay(Const Year, Month: Integer; Index: Integer): Integer; +Function FirstDayOfWeek(Const Year, Month, DayOfWeek: Integer): Integer; +Function LastDayOfWeek(Const Year, Month, DayOfWeek: Integer): Integer; +Function IndexedDayOfWeek(Const Year, Month, DayOfWeek, Index: Integer): Integer; +Type + EJclDateTimeError = Class(EJclError); {$IFDEF UNITVERSIONING} -const +Const UnitVersioning: TUnitVersionInfo = ( RCSfile: '$URL$'; Revision: '$Revision$'; @@ -171,11 +171,11 @@ EJclDateTimeError = class(EJclError); Data: nil ); {$ENDIF UNITVERSIONING} -implementation +Implementation //uses //uRESTDWMemSysUtils; -const - DaysInMonths: array [1..12] of Integer = +Const + DaysInMonths: array [1..12] Of Integer = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); MinutesPerDay = 60 * 24; //SecondsPerMinute = 60; @@ -200,15 +200,15 @@ implementation // 4 : first week has at least four days (according to ISO 8601) // 7 : first full week //ISOFirstWeekMinDays = 4; -function EncodeDate(const Year: Integer; Month, Day: Word): TDateTime; -begin - if (Year > 0) and (Year < EncodeDateMaxYear + 1) then +Function EncodeDate(Const Year: Integer; Month, Day: Word): TDateTime; +Begin + If (Year > 0) and (Year < EncodeDateMaxYear + 1) Then Result := {$IFDEF HAS_UNITSCOPE}System.{$ENDIF}SysUtils.EncodeDate(Year, Month, Day) - else - begin - if Year <= 0 then + Else + Begin + If Year <= 0 Then Result := Year * DaysPerYear + DateTimeBaseDay - else // Year >= 10000 + Else // Year >= 10000 // for some reason year 0 does not exist so we switch from // the last day of year -1 (-693594) to the first days of year 1 Result := (Year-1) * DaysPerYear + DateTimeBaseDay + // BaseDate is 1/1/1 @@ -216,308 +216,308 @@ function EncodeDate(const Year: Integer; Month, Day: Word): TDateTime; Result := Trunc(Result); Result := Result + (Month - 1) * DaysPerMonth; Result := Integer(Round(Result)) + (Day - 1); - end; -end; -procedure DecodeDate(Date: TDateTime; out Year, Month, Day: Word); -begin + End; +End; +Procedure DecodeDate(Date: TDateTime; out Year, Month, Day: Word); +Begin {$IFDEF HAS_UNITSCOPE}System.{$ENDIF}SysUtils.DecodeDate(Date, Year, Month, Day); -end; -procedure DecodeDate(Date: TDateTime; out Year, Month, Day: Integer); -var +End; +Procedure DecodeDate(Date: TDateTime; out Year, Month, Day: Integer); +Var WMonth, WDay: Word; -begin +Begin DecodeDate(Date, Year, WMonth, WDay); Month := WMonth; Day := WDay; -end; -procedure DecodeDate(Date: TDateTime; out Year: Integer; out Month, Day: Word); -var +End; +Procedure DecodeDate(Date: TDateTime; out Year: Integer; out Month, Day: Word); +Var WYear: Word; RDays, RMonths: TDateTime; -begin - if (Date >= DateTimeBaseDay) and (Date < DateTimeMaxDay) then - begin +Begin + If (Date >= DateTimeBaseDay) and (Date < DateTimeMaxDay) Then + Begin {$IFDEF HAS_UNITSCOPE}System.{$ENDIF}SysUtils.DecodeDate(Date, WYear, Month, Day); Year := WYear; - end - else - begin + End + Else + Begin Year := Trunc((Date - DateTimeBaseDay) / DaysPerYear); - if Year <= 0 then + If Year <= 0 Then Year := Year - 1 // for some historical reason year 0 does not exist so we switch from // the last day of year -1 (-693594) to the first days of year 1 - else // Year >= 10000 + Else // Year >= 10000 Date := Date - SolarDifference; // guarantee a smooth transition at 1/1/10000 RDays := Date - DateTimeBaseDay; // Days relative to 1/1/0001 RMonths := RDays / DaysPerMonth; // "Months" relative to 1/1/0001 RMonths := RMonths - Year * 12.0; // 12 "Months" per Year - if RMonths < 0 then // possible truncation glitches - begin + If RMonths < 0 Then // possible truncation glitches + Begin RMonths := 11; Year := Year - 1; - end; + End; Month := Trunc(RMonths); RMonths := Month; Month := Month + 1; RDays := RDays - Year * DaysPerYear; // subtract Base Day ot the year RDays := RDays - RMonths * DaysPerMonth;// subtract Base Day of the month Day := Trunc(RDays)+ 1; - if Year > 0 then // Year >= 10000 + If Year > 0 Then // Year >= 10000 Year := Year + 1; // BaseDate is 1/1/1 - end; -end; -procedure ResultCheck(Val: LongBool); -begin - if not Val then + End; +End; +Procedure ResultCheck(Val: LongBool); +Begin + If not Val Then raise EJclDateTimeError.CreateRes(@RsDateConversion); -end; -function CenturyBaseYear(const DateTime: TDateTime): Integer; -var +End; +Function CenturyBaseYear(Const DateTime: TDateTime): Integer; +Var Y: Integer; -begin +Begin Y := YearOfDate(DateTime); Result := (Y div 100) * 100; - if Y <= 0 then + If Y <= 0 Then Result := Result - 100; -end; -function CenturyOfDate(const DateTime: TDateTime): Integer; -var +End; +Function CenturyOfDate(Const DateTime: TDateTime): Integer; +Var Y: Integer; -begin +Begin Y := YearOfDate(DateTime); - if Y > 0 then + If Y > 0 Then Result := (Y div 100) + 1 - else + Else Result := (Y div 100) - 1; -end; -function DayOfDate(const DateTime: TDateTime): Integer; -var +End; +Function DayOfDate(Const DateTime: TDateTime): Integer; +Var Y: Integer; M, D: Word; -begin +Begin DecodeDate(DateTime, Y, M, D); Result := D; -end; -function MonthOfDate(const DateTime: TDateTime): Integer; -var +End; +Function MonthOfDate(Const DateTime: TDateTime): Integer; +Var Y: Integer; M, D: Word; -begin +Begin DecodeDate(DateTime, Y, M, D); Result := M; -end; -function YearOfDate(const DateTime: TDateTime): Integer; -var +End; +Function YearOfDate(Const DateTime: TDateTime): Integer; +Var M, D: Word; -begin +Begin DecodeDate(DateTime, Result, M, D); -end; -function DayOfTheYear(const DateTime: TDateTime; out Year: Integer): Integer; -var +End; +Function DayOfTheYear(Const DateTime: TDateTime; out Year: Integer): Integer; +Var Month, Day: Word; DT: TDateTime; -begin +Begin DecodeDate(DateTime, Year, Month, Day); DT := EncodeDate(Year, 1, 1); Result := Trunc(DateTime); Result := Result - Trunc(DT) + 1; -end; -function DayOfTheYear(const DateTime: TDateTime): Integer; -var +End; +Function DayOfTheYear(Const DateTime: TDateTime): Integer; +Var Year: Integer; -begin +Begin Result := DayOfTheYear(DateTime, Year); -end; -function DayOfTheYearToDateTime(const Year, Day: Integer): TDateTime; -begin +End; +Function DayOfTheYearToDateTime(Const Year, Day: Integer): TDateTime; +Begin Result := EncodeDate(Year, 1, 1) + Day - 1; -end; -function HourOfTime(const DateTime: TDateTime): Integer; -var +End; +Function HourOfTime(Const DateTime: TDateTime): Integer; +Var H, M, S, MS: Word; -begin +Begin DecodeTime(DateTime, H, M, S, MS); Result := H; -end; -function MinuteOfTime(const DateTime: TDateTime): Integer; -var +End; +Function MinuteOfTime(Const DateTime: TDateTime): Integer; +Var H, M, S, MS: Word; -begin +Begin DecodeTime(DateTime, H, M, S, MS); Result := M; -end; -function SecondOfTime(const DateTime: TDateTime): Integer; -var +End; +Function SecondOfTime(Const DateTime: TDateTime): Integer; +Var H, M, S, MS: Word; -begin +Begin DecodeTime(DateTime, H, M, S, MS); Result := S; -end; -function TimeOfDateTimeToSeconds(DateTime: TDateTime): Integer; -begin +End; +Function TimeOfDateTimeToSeconds(DateTime: TDateTime): Integer; +Begin Result := Round(Frac(DateTime) * SecondsPerDay); -end; -function TimeOfDateTimeToMSecs(DateTime: TDateTime): Integer; -begin +End; +Function TimeOfDateTimeToMSecs(DateTime: TDateTime): Integer; +Begin Result := Round(Frac(DateTime) * MSecsPerDay); -end; -function DaysInMonth(const DateTime: TDateTime): Integer; -var +End; +Function DaysInMonth(Const DateTime: TDateTime): Integer; +Var M: Integer; -begin +Begin M := MonthOfDate(DateTime); Result := DaysInMonths[M]; - if (M = 2) and IsLeapYear(DateTime) then + If (M = 2) and IsLeapYear(DateTime) Then Result := 29; -end; +End; // SysUtils.DayOfWeek returns the day of the week of the given date. The result is an integer between // 1 and 7, corresponding to Sunday through Saturday. ISODayOfWeek on the other hand returns an integer // between 1 and 7 where the first day is a Monday. The forumla for calculation ISODayOfTheWeek is // simply // DayOfWeek(D) - 1 if DayOfWeek(D) > 1 // ISODayOfWeek (D) = 7 if DayOfWeek(D) = 1 -function ISODayOfWeek(const DateTime: TDateTime): Word; -var +Function ISODayOfWeek(Const DateTime: TDateTime): Word; +Var TmpDayOfWeek: Word; -begin +Begin TmpDayOfWeek := {$IFDEF HAS_UNITSCOPE}System.{$ENDIF}SysUtils.DayOfWeek(DateTime); - if TmpDayOfWeek = 1 then + If TmpDayOfWeek = 1 Then Result := 7 - else + Else Result := TmpDayOfWeek - 1; -end; +End; // Determines if the ISO Year is ordinary (52 weeks) or Long (53 weeks). Uses a rule first // suggested by Sven Pran (Norway) and Lars Nordentoft (Denmark) - according to // http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm -function IsISOLongYear(const DateTime: TDateTime): Boolean; -var +Function IsISOLongYear(Const DateTime: TDateTime): Boolean; +Var TmpYear: Word; -begin +Begin TmpYear := YearOfDate(DateTime); Result := IsISOLongYear(TmpYear); -end; -function IsISOLongYear(const Year: Word): Boolean; -var +End; +Function IsISOLongYear(Const Year: Word): Boolean; +Var TmpWeekday: Word; -begin +Begin TmpWeekday := ISODayOfWeek(DayOfTheYearToDateTime(Year, 1)); Result := (IsLeapYear(Year) and ((TmpWeekday = 3) or (TmpWeekday = 4))) or (TmpWeekday = 4); -end; -function GetISOYearNumberOfWeeks(const Year: Word): Word; -begin +End; +Function GetISOYearNumberOfWeeks(Const Year: Word): Word; +Begin Result := 52; - if IsISOLongYear(Year) then + If IsISOLongYear(Year) Then Result := 53; -end; +End; // ISOWeekNumber function returns Integer 1..7 equivalent to Sunday..Saturday. // ISO 8601 weeks start with Monday and the first week of a year is the one which // includes the first Thursday -function ISOWeekNumber(DateTime: TDateTime; out YearOfWeekNumber, WeekDay: Integer): Integer; -var +Function ISOWeekNumber(DateTime: TDateTime; out YearOfWeekNumber, WeekDay: Integer): Integer; +Var TmpYear: Integer; January4th: TDateTime; FirstMonday: TDateTime; -begin +Begin // Applying the rule: The first calender week is the week that includes January, 4th TmpYear := YearOfDate(DateTime); WeekDay := ISODayOfWeek(DateTime); // adjust if we are between 12/29 and 12/31 - if (MonthOfDate(DateTime) = 12) and (DayOfDate(DateTime) >= 29) and - (ISODayOfWeek(DateTime) <= 3) then + If (MonthOfDate(DateTime) = 12) and (DayOfDate(DateTime) >= 29) and + (ISODayOfWeek(DateTime) <= 3) Then TmpYear := TmpYear + 1; January4th := DayOfTheYearToDateTime(TmpYear, 4); FirstMonday := January4th + 1 - ISODayOfWeek(January4th); // If our date is < FirstMonday we are in the last week of the previous year - if DateTime < FirstMonday then - begin + If DateTime < FirstMonday Then + Begin Result := GetISOYearNumberOfWeeks(TmpYear - 1); YearOfWeekNumber := TmpYear - 1; Exit; - end - else - begin + End + Else + Begin YearOfWeekNumber := TmpYear; Result := (Trunc(DateTime - FirstMonday) div 7) + 1; - end; - if Result > GetISOYearNumberOfWeeks(YearOfDate(DateTime)) then + End; + If Result > GetISOYearNumberOfWeeks(YearOfDate(DateTime)) Then Result := GetISOYearNumberOfWeeks(YearOfDate(DateTime)); -end; -function ISOWeekNumber(DateTime: TDateTime; out YearOfWeekNumber: Integer): Integer; -var +End; +Function ISOWeekNumber(DateTime: TDateTime; out YearOfWeekNumber: Integer): Integer; +Var Temp: Integer; -begin +Begin Result := ISOWeekNumber(DateTime, YearOfWeekNumber, Temp); -end; -function ISOWeekNumber(DateTime: TDateTime): Integer; -var +End; +Function ISOWeekNumber(DateTime: TDateTime): Integer; +Var Temp: Integer; -begin +Begin Result := ISOWeekNumber(DateTime, Temp, Temp); -end; -function ISOWeekToDateTime(const Year, Week, Day: Integer): TDateTime; -var +End; +Function ISOWeekToDateTime(Const Year, Week, Day: Integer): TDateTime; +Var January4th: TDateTime; FirstMonday: TDateTime; -begin +Begin January4th := DayOfTheYearToDateTime(Year, 4); FirstMonday := January4th + 1 - ISODayOfWeek(January4th); Result := FirstMonday + (Week - 1) * 7 + (Day - 1); -end; +End; // The original Gregorian rule for all who want to learn it // Result := (Year mod 4 = 0) and ((Year mod 100 <> 0) or (Year mod 400 = 0)); -function IsLeapYear(const Year: Integer): Boolean; -begin +Function IsLeapYear(Const Year: Integer): Boolean; +Begin Result := {$IFDEF HAS_UNITSCOPE}System.{$ENDIF}SysUtils.IsLeapYear(Year); -end; -function IsLeapYear(const DateTime: TDateTime): Boolean; -begin +End; +Function IsLeapYear(Const DateTime: TDateTime): Boolean; +Begin Result := IsLeapYear(YearOfDate(DateTime)); -end; -function Make4DigitYear(Year, Pivot: Integer): Integer; -begin +End; +Function Make4DigitYear(Year, Pivot: Integer): Integer; +Begin { TODO : Make4DigitYear } Assert((Year >= 0) and (Year <= 100) and (Pivot >= 0) and (Pivot <= 100)); - if Year = 100 then + If Year = 100 Then Year := 0; - if Pivot = 100 then + If Pivot = 100 Then Pivot := 0; - if Year < Pivot then + If Year < Pivot Then Result := 2000 + Year - else + Else Result := 1900 + Year; -end; +End; // "window" technique for years to translate 2 digits to 4 digits. // The window is 100 years wide // The windowsill year is the lower edge of the window // A windowsill year of 1900 is equivalent to putting 1900 before every 2-digit year // if WindowsillYear is 1940, then 40 is interpreted as 1940, 00 as 2000 and 39 as 2039 // The system default is 1950 -function MakeYear4Digit(Year, WindowsillYear: Integer): Integer; -var +Function MakeYear4Digit(Year, WindowsillYear: Integer): Integer; +Var CC, Y: Integer; -begin +Begin // have come across this specific problem : y2K read as year 100 - if Year = 100 then + If Year = 100 Then Year := 0; // turn 2 digit years to 4 digits Y := Year mod 100; CC := (WindowsillYear div 100) * 100; Result := Y + CC; // give the result the same century as the windowsill - if Result < WindowsillYear then // cannot be lower than the windowsill + If Result < WindowsillYear Then // cannot be lower than the windowsill Result := Result + 100; - if (Year >= 100) or (Year < 0) then + If (Year >= 100) or (Year < 0) Then Assert(Year = Result); // Assert: no unwanted century translation -end; +End; // Calculates and returns Easter Day for specified year. // Originally from Mark Lussier, AppVision . // Corrected to prevent integer overflow if it is inadvertedly // passed a year of 6554 or greater. -function EasterSunday(const Year: Integer): TDateTime; -var +Function EasterSunday(Const Year: Integer): TDateTime; +Var Month, Day, Moon, Epact, Sunday, Gold, Cent, Corx, Corz: Integer; -begin +Begin { The Golden Number of the year in the 19 year Metonic Cycle: } Gold := Year mod 19 + 1; { Calculate the Century: } @@ -532,54 +532,54 @@ function EasterSunday(const Year: Integer): TDateTime; { ^ To prevent overflow at year 6554} { Set Epact - specifies occurrence of full moon: } Epact := (11 * Gold + 20 + Corz - Corx) mod 30; - if Epact < 0 then + If Epact < 0 Then Epact := Epact + 30; - if ((Epact = 25) and (Gold > 11)) or (Epact = 24) then + If ((Epact = 25) and (Gold > 11)) or (Epact = 24) Then Epact := Epact + 1; { Find Full Moon: } Moon := 44 - Epact; - if Moon < 21 then + If Moon < 21 Then Moon := Moon + 30; { Advance to Sunday: } Moon := Moon + 7 - ((Sunday + Moon) mod 7); - if Moon > 31 then - begin + If Moon > 31 Then + Begin Month := 4; Day := Moon - 31; - end - else - begin + End + Else + Begin Month := 3; Day := Moon; - end; + End; Result := EncodeDate(Year, Month, Day); -end; +End; // Conversion {$IFDEF MSWINDOWS} -function DateTimeToLocalDateTime(DateTime: TDateTime): TDateTime; -var +Function DateTimeToLocalDateTime(DateTime: TDateTime): TDateTime; +Var TimeZoneInfo: TTimeZoneInformation; -begin +Begin // ResetMemory(TimeZoneInfo, SizeOf(TimeZoneInfo)); - case GetTimeZoneInformation(TimeZoneInfo) of + Case GetTimeZoneInformation(TimeZoneInfo) Of TIME_ZONE_ID_STANDARD, TIME_ZONE_ID_UNKNOWN: Result := DateTime - (TimeZoneInfo.Bias + TimeZoneInfo.StandardBias) / MinutesPerDay; TIME_ZONE_ID_DAYLIGHT: Result := DateTime - (TimeZoneInfo.Bias + TimeZoneInfo.DaylightBias) / MinutesPerDay; - else + Else raise EJclDateTimeError.CreateRes(@RsMakeUTCTime); - end; -end; + End; +End; {$ENDIF MSWINDOWS} {$IFDEF UNIX} -function DateTimeToLocalDateTime(DateTime: TDateTime): TDateTime; -var +Function DateTimeToLocalDateTime(DateTime: TDateTime): TDateTime; +Var {$IFDEF LINUX} TimeNow: time_t; Local, UTCTime: TUnixTime; {$ENDIF LINUX} Offset: Double; -begin +Begin {$IFDEF LINUX} TimeNow := __time(nil); UTCTime := gmtime(@TimeNow)^; @@ -589,33 +589,33 @@ function DateTimeToLocalDateTime(DateTime: TDateTime): TDateTime; Offset := -TZSeconds; {$ENDIF ~LINUX} Result := ((DateTime * SecsPerDay) - Offset) / SecsPerDay; -end; +End; {$ENDIF UNIX} {$IFDEF MSWINDOWS} -function LocalDateTimeToDateTime(DateTime: TDateTime): TDateTime; -var +Function LocalDateTimeToDateTime(DateTime: TDateTime): TDateTime; +Var TimeZoneInfo: TTimeZoneInformation; -begin +Begin // ResetMemory(TimeZoneInfo, SizeOf(TimeZoneInfo)); - case GetTimeZoneInformation(TimeZoneInfo) of + Case GetTimeZoneInformation(TimeZoneInfo) Of TIME_ZONE_ID_STANDARD, TIME_ZONE_ID_UNKNOWN: Result := DateTime + (TimeZoneInfo.Bias + TimeZoneInfo.StandardBias) / MinutesPerDay; TIME_ZONE_ID_DAYLIGHT: Result := DateTime + (TimeZoneInfo.Bias + TimeZoneInfo.DaylightBias) / MinutesPerDay; - else + Else raise EJclDateTimeError.CreateRes(@RsMakeUTCTime); - end; -end; + End; +End; {$ENDIF MSWINDOWS} {$IFDEF UNIX} -function LocalDateTimeToDateTime(DateTime: TDateTime): TDateTime; -var +Function LocalDateTimeToDateTime(DateTime: TDateTime): TDateTime; +Var {$IFDEF LINUX} TimeNow: time_t; Local, UTCTime: TUnixTime; {$ENDIF LINUX} Offset: Double; -begin +Begin {$IFDEF LINUX} TimeNow := __time(nil); UTCTime := gmtime(@TimeNow)^; @@ -625,80 +625,80 @@ function LocalDateTimeToDateTime(DateTime: TDateTime): TDateTime; Offset := -TZSeconds; {$ENDIF ~LINUX} Result := ((DateTime * SecsPerDay) + Offset) / SecsPerDay; -end; +End; {$ENDIF UNIX} -function HoursToMSecs(Hours: Integer): Integer; -begin +Function HoursToMSecs(Hours: Integer): Integer; +Begin Assert(Hours < MaxInt / MsecsPerHour); Result := Hours * MsecsPerHour; -end; -function MinutesToMSecs(Minutes: Integer): Integer; -begin +End; +Function MinutesToMSecs(Minutes: Integer): Integer; +Begin Assert(Minutes < MaxInt div MsecsPerMinute); Result := Minutes * MsecsPerMinute; -end; -function SecondsToMSecs(Seconds: Integer): Integer; -begin +End; +Function SecondsToMSecs(Seconds: Integer): Integer; +Begin Assert(Seconds < MaxInt div 1000); Result := Seconds * 1000; -end; +End; // using system calls this can be done like this: // var // SystemTime: TSystemTime; // begin // ResultCheck(FileTimeToSystemTime(FileTime, SystemTime)); // Result := SystemTimeToDateTime(SystemTime); -function FileTimeToDateTime(const FileTime: TFileTime): TDateTime; -begin +Function FileTimeToDateTime(Const FileTime: TFileTime): TDateTime; +Begin Result := Int64(FileTime) / FileTimeStep; Result := Result + FileTimeBase; -end; +End; {$IFDEF MSWINDOWS} -function FileTimeToLocalDateTime(const FileTime: TFileTime): TDateTime; -var +Function FileTimeToLocalDateTime(Const FileTime: TFileTime): TDateTime; +Var LocalFileTime: TFileTime; -begin +Begin LocalFileTime.dwHighDateTime := 0; LocalFileTime.dwLowDateTime := 0; ResultCheck(FileTimeToLocalFileTime(FileTime, LocalFileTime)); Result := FileTimeToDateTime(LocalFileTime); { TODO : daylight saving time } -end; -function LocalDateTimeToFileTime(DateTime: TDateTime): FileTime; -var +End; +Function LocalDateTimeToFileTime(DateTime: TDateTime): FileTime; +Var LocalFileTime: TFileTime; -begin +Begin LocalFileTime := DateTimeToFileTime(DateTime); Result.dwHighDateTime := 0; Result.dwLowDateTime := 0; ResultCheck(LocalFileTimeToFileTime(LocalFileTime, Result)); { TODO : daylight saving time } -end; +End; {$ENDIF MSWINDOWS} -function DateTimeToFileTime(DateTime: TDateTime): TFileTime; -var +Function DateTimeToFileTime(DateTime: TDateTime): TFileTime; +Var E: Extended; F64: Int64; -begin +Begin E := (DateTime - FileTimeBase) * FileTimeStep; F64 := Round(E); Result := TFileTime(F64); -end; +End; {$IFDEF MSWINDOWS} -function DosDateTimeToSystemTime(const DosTime: TDosDateTime): TSystemTime; -var +Function DosDateTimeToSystemTime(Const DosTime: TDosDateTime): TSystemTime; +Var FileTime: TFileTime; -begin +Begin FileTime := DosDateTimeToFileTime(DosTime); Result := FileTimeToSystemTime(FileTime); -end; -function SystemTimeToDosDateTime(const SystemTime: TSystemTime): TDosDateTime; -var +End; +Function SystemTimeToDosDateTime(Const SystemTime: TSystemTime): TDosDateTime; +Var FileTime: TFileTime; -begin +Begin FileTime := SystemTimeToFileTime(SystemTime); Result := FileTimeToDosDateTime(FileTime); -end; +End; {$ENDIF MSWINDOWS} // DosDateTimeToDateTime performs the same action as SysUtils.FileDateToDateTime // not using SysUtils.FileDateToDateTime this can be done like that: @@ -709,10 +709,10 @@ function SystemTimeToDosDateTime(const SystemTime: TSystemTime): TDosDateTime; // ResultCheck(DosDateTimeToFileTime(HiWord(DosTime), LoWord(DosTime), FileTime)); // ResultCheck(FileTimeToSystemTime(FileTime, SystemTime)); // Result := SystemTimeToDateTime(SystemTime); -function DosDateTimeToDateTime(const DosTime: TDosDateTime): TDateTime; -begin +Function DosDateTimeToDateTime(Const DosTime: TDosDateTime): TDateTime; +Begin Result := {$IFDEF HAS_UNITSCOPE}System.{$ENDIF}SysUtils.FileDateToDateTime(DosTime); -end; +End; // DateTimeToDosDateTime performs the same action as SysUtils.DateTimeToFileDate // not using SysUtils.DateTimeToDosDateTime this can be done like that: // var @@ -724,99 +724,99 @@ function DosDateTimeToDateTime(const DosTime: TDosDateTime): TDateTime; // ResultCheck(SystemTimeToFileTime(SystemTime, FileTime)); // ResultCheck(FileTimeToDosDateTime(FileTime, Date, Time)); // Result := (Date shl 16) or Time; -function DateTimeToDosDateTime(const DateTime: TDateTime): TDosDateTime; -begin +Function DateTimeToDosDateTime(Const DateTime: TDateTime): TDosDateTime; +Begin Result := {$IFDEF HAS_UNITSCOPE}System.{$ENDIF}SysUtils.DateTimeToFileDate(DateTime); -end; +End; {$IFDEF MSWINDOWS} -function FileTimeToSystemTime(const FileTime: TFileTime): TSystemTime; overload; -begin +Function FileTimeToSystemTime(Const FileTime: TFileTime): TSystemTime; overload; +Begin ResultCheck({$IFDEF HAS_UNITSCOPE}Winapi.{$ENDIF}Windows.FileTimeToSystemTime(FileTime, Result)); -end; -procedure FileTimeToSystemTime(const FileTime: TFileTime; out ST: TSystemTime); overload; -begin +End; +Procedure FileTimeToSystemTime(Const FileTime: TFileTime; out ST: TSystemTime); overload; +Begin {$IFDEF FPC} ST.Day := 0; {$ENDIF FPC} {$IFDEF HAS_UNITSCOPE}Winapi.{$ENDIF}Windows.FileTimeToSystemTime(FileTime, ST); -end; -function SystemTimeToFileTime(const SystemTime: TSystemTime): TFileTime; overload; -begin +End; +Function SystemTimeToFileTime(Const SystemTime: TSystemTime): TFileTime; overload; +Begin Result.dwHighDateTime := 0; Result.dwLowDateTime := 0; ResultCheck({$IFDEF HAS_UNITSCOPE}Winapi.{$ENDIF}Windows.SystemTimeToFileTime(SystemTime, Result)); -end; -procedure SystemTimeToFileTime(const SystemTime: TSystemTime; FTime: TFileTime); overload; -begin +End; +Procedure SystemTimeToFileTime(Const SystemTime: TSystemTime; FTime: TFileTime); overload; +Begin {$IFDEF HAS_UNITSCOPE}Winapi.{$ENDIF}Windows.SystemTimeToFileTime(SystemTime, FTime); -end; -function DateTimeToSystemTime(DateTime: TDateTime): TSystemTime; overload; -begin +End; +Function DateTimeToSystemTime(DateTime: TDateTime): TSystemTime; overload; +Begin {$IFDEF HAS_UNITSCOPE}System.{$ENDIF}SysUtils.DateTimeToSystemTime(DateTime, Result); -end; -procedure DateTimeToSystemTime(DateTime: TDateTime; out SysTime: TSystemTime); overload; -begin +End; +Procedure DateTimeToSystemTime(DateTime: TDateTime; out SysTime: TSystemTime); overload; +Begin {$IFDEF HAS_UNITSCOPE}System.{$ENDIF}SysUtils.DateTimeToSystemTime(DateTime, SysTime); -end; -function DosDateTimeToFileTime(DosTime: TDosDateTime): TFileTime; overload; -begin +End; +Function DosDateTimeToFileTime(DosTime: TDosDateTime): TFileTime; overload; +Begin Result.dwHighDateTime := 0; Result.dwLowDateTime := 0; ResultCheck({$IFDEF HAS_UNITSCOPE}Winapi.{$ENDIF}Windows.DosDateTimeToFileTime(HIWORD(DosTime), LOWORD(DosTime), Result)); -end; -procedure DosDateTimeToFileTime(DTH, DTL: Word; FT: TFileTime); overload; -begin +End; +Procedure DosDateTimeToFileTime(DTH, DTL: Word; FT: TFileTime); overload; +Begin {$IFDEF HAS_UNITSCOPE}Winapi.{$ENDIF}Windows.DosDateTimeToFileTime(DTH, DTL, FT); -end; -function FileTimeToDosDateTime(const FileTime: TFileTime): TDosDateTime; overload; -var +End; +Function FileTimeToDosDateTime(Const FileTime: TFileTime): TDosDateTime; overload; +Var Date, Time: Word; -begin +Begin Date := 0; Time := 0; ResultCheck({$IFDEF HAS_UNITSCOPE}Winapi.{$ENDIF}Windows.FileTimeToDosDateTime(FileTime, Date, Time)); Result := (Date shl 16) or Time; -end; -procedure FileTimeToDosDateTime(const FileTime: TFileTime; out Date, Time: Word); overload; -begin +End; +Procedure FileTimeToDosDateTime(Const FileTime: TFileTime; out Date, Time: Word); overload; +Begin Date := 0; Time := 0; {$IFDEF HAS_UNITSCOPE}Winapi.{$ENDIF}Windows.FileTimeToDosDateTime(FileTime, Date, Time); -end; +End; {$ENDIF MSWINDOWS} -function FileTimeToStr(const FileTime: TFileTime): string; -var +Function FileTimeToStr(Const FileTime: TFileTime): string; +Var DateTime: TDateTime; -begin +Begin DateTime := FileTimeToDateTime(FileTime); Result := DateTimeToStr(DateTime); -end; -function DosDateTimeToStr(DateTime: Integer): string; -begin +End; +Function DosDateTimeToStr(DateTime: Integer): string; +Begin Result := DateTimeToStr(DosDateTimeToDateTime(DateTime)); -end; +End; {$IFDEF MSWINDOWS} // we can't do this better without copying Borland-owned code from the Delphi VCL, // as the straight forward conversion doing exactly this task is hidden // deeply inside SysUtils.pas. // So the date is converted forth and back to/from Julian date // If someone needs a faster version please take a look at SysUtils.pas->DateTimeToStr. -function SystemTimeToStr(const SystemTime: TSystemTime): string; -begin +Function SystemTimeToStr(Const SystemTime: TSystemTime): string; +Begin Result := DateTimeToStr(SystemTimeToDateTime(SystemTime)); -end; -function CreationDateTimeOfFile(const Sr: TSearchRec): TDateTime; -begin +End; +Function CreationDateTimeOfFile(Const Sr: TSearchRec): TDateTime; +Begin Result := FileTimeToDateTime(Sr.FindData.ftCreationTime); -end; -function LastAccessDateTimeOfFile(const Sr: TSearchRec): TDateTime; -begin +End; +Function LastAccessDateTimeOfFile(Const Sr: TSearchRec): TDateTime; +Begin Result := FileTimeToDateTime(Sr.FindData.ftLastAccessTime); -end; -function LastWriteDateTimeOfFile(const Sr: TSearchRec): TDateTime; -begin +End; +Function LastWriteDateTimeOfFile(Const Sr: TSearchRec): TDateTime; +Begin Result := FileTimeToDateTime(Sr.FindData.ftLastWriteTime); -end; +End; {$ENDIF MSWINDOWS} // Additional format tokens (also available in upper case): // w: Week no according to ISO @@ -826,438 +826,438 @@ function LastWriteDateTimeOfFile(const Sr: TSearchRec): TDateTime; // e: Number of the Day in the ISO-week denoted by w (ISO-Notation 1=Monday...) // f: Number of the Day in the year denoted by y // fff: Number of the Day in the year denoted by y forced three digits -function FormatDateTime(Form: string; DateTime: TDateTime): string; -var +Function FormatDateTime(Form: string; DateTime: TDateTime): string; +Var N: Integer; ISODay, ISOWeek, ISOYear, DayOfYear, YY: Integer; - procedure Digest; - begin - if N > 1 then - begin + Procedure Digest; + Begin + If N > 1 Then + Begin Result := Result + Copy(Form, 1, N - 1); Delete(Form, 1, N - 1); N := 1; - end; - end; -begin + End; + End; +Begin ISOWeek := 0; DayOfYear := 0; Result := ''; N := 1; - while N <= Length(Form) do - begin - case Form[N] of + While N <= Length(Form) Do + Begin + Case Form[N] Of '"': - begin + Begin Inc(N); Digest; N := Pos('"', Form); - if N = 0 then - begin + If N = 0 Then + Begin Result := Result + Form; Form := ''; N := 1; - end - else - begin + End + Else + Begin Inc(N); Digest; - end; - end; + End; + End; '''': - begin + Begin Inc(N); Digest; N := Pos('''', Form); - if N = 0 then - begin + If N = 0 Then + Begin Result := Result + Form; Form := ''; N := 1; - end - else - begin + End + Else + Begin Inc(N); Digest; - end; - end; + End; + End; 'i', 'I': //ISO Week Year - begin + Begin Digest; - if ISOWeek = 0 then + If ISOWeek = 0 Then ISOWeek := ISOWeekNumber(DateTime, ISOYear, ISODay); - if (Length(Form) > 1) and ((Form[2] = 'i') or (Form[2] = 'I')) then - begin // - if (Length(Form) > 2) and ((Form[3] = 'i') or (Form[3] = 'I')) then - begin - if (Length(Form) > 3) and ((Form[4] = 'i') or (Form[4] = 'I')) then - begin // + If (Length(Form) > 1) and ((Form[2] = 'i') or (Form[2] = 'I')) Then + Begin // + If (Length(Form) > 2) and ((Form[3] = 'i') or (Form[3] = 'I')) Then + Begin + If (Length(Form) > 3) and ((Form[4] = 'i') or (Form[4] = 'I')) Then + Begin // Delete(Form, 1, 4); Result := Result + '"' + IntToStr(ISOYear) + '"'; - end - else - begin // + End + Else + Begin // Delete(Form, 1, 3); Result := Result + '"' + IntToStr(ISOYear) + '"'; - end; - end - else - begin // + End; + End + Else + Begin // Delete(Form, 1, 2); Result := Result + '"'; - if ISOYear < 10 then + If ISOYear < 10 Then Result := Result + '0'; YY := ISOYear mod 100; - if YY < 10 then + If YY < 10 Then Result := Result + '0'; Result := Result + IntToStr(YY) + '"'; - end; - end - else - begin // + End; + End + Else + Begin // Delete(Form, 1, 1); Result := Result + '"' + IntToStr(ISOYear) + '"'; - end; - end; + End; + End; 'w', 'W': // ISO Week - begin + Begin Digest; - if ISOWeek = 0 then + If ISOWeek = 0 Then ISOWeek := ISOWeekNumber(DateTime, ISOYear, ISODay); - if (Length(Form) > 1) and ((Form[2] = 'w') or (Form[2] = 'W')) then - begin // + If (Length(Form) > 1) and ((Form[2] = 'w') or (Form[2] = 'W')) Then + Begin // Delete(Form, 1, 2); Result := Result + '"'; - if ISOWeek < 10 then + If ISOWeek < 10 Then Result := Result + '0'; Result := Result + IntToStr(ISOWeek) + '"'; - end - else - begin // + End + Else + Begin // Delete(Form, 1, 1); Result := Result + '"' + IntToStr(ISOWeek) + '"'; - end; - end; + End; + End; 'e', 'E': // ISO Week Day - begin + Begin Digest; - if ISOWeek = 0 then + If ISOWeek = 0 Then ISOWeek := ISOWeekNumber(DateTime, ISOYear, ISODay); Delete(Form, 1, 1); Result := Result + '"' + IntToStr(ISODay) + '"'; - end; + End; 'f', 'F': // Day of the Year - begin + Begin Digest; - if DayOfYear = 0 then + If DayOfYear = 0 Then DayOfYear := DayOfTheYear(DateTime); - if (Length(Form) > 1) and ((Form[2] = 'f') or (Form[2] = 'F')) then - begin - if (Length(Form) > 2) and ((Form[3] = 'f') or (Form[3] = 'F')) then - begin // + If (Length(Form) > 1) and ((Form[2] = 'f') or (Form[2] = 'F')) Then + Begin + If (Length(Form) > 2) and ((Form[3] = 'f') or (Form[3] = 'F')) Then + Begin // Delete(Form, 1, 3); Result := Result + '"'; - if DayOfYear < 10 then + If DayOfYear < 10 Then Result := Result + '0'; - if DayOfYear < 100 then + If DayOfYear < 100 Then Result := Result + '0'; Result := Result + IntToStr(DayOfYear) + '"'; - end - else - begin // + End + Else + Begin // Delete(Form, 1, 2); Result := Result + '"'; - if DayOfYear < 10 then + If DayOfYear < 10 Then Result := Result + '0'; Result := Result + IntToStr(DayOfYear) + '"'; - end; - end - else - begin // + End; + End + Else + Begin // Delete(Form, 1, 1); Result := Result + '"' + IntToStr(DayOfYear) + '"'; - end - end; - else + End + End; + Else Inc(N); - end; - end; + End; + End; Result := {$IFDEF HAS_UNITSCOPE}System.{$ENDIF}SysUtils.FormatDateTime(Result + Form, DateTime); -end; +End; // FAT has a granularity of 2 seconds // The intervals are 1/10 of a second -function FATDatesEqual(const FileTime1, FileTime2: Int64): Boolean; -const +Function FATDatesEqual(Const FileTime1, FileTime2: Int64): Boolean; +Const ALLOWED_FAT_FILE_TIME_VARIATION = 20; -begin +Begin Result := Abs(FileTime1 - FileTime2) <= ALLOWED_FAT_FILE_TIME_VARIATION; -end; -function FATDatesEqual(const FileTime1, FileTime2: TFileTime): Boolean; -begin +End; +Function FATDatesEqual(Const FileTime1, FileTime2: TFileTime): Boolean; +Begin Result := FATDatesEqual(Int64(FileTime1), Int64(FileTime2)); -end; +End; // Conversion Unix time <--> TDateTime -function DateTimeToUnixTime(DateTime: TDateTime): TJclUnixTime32; -begin +Function DateTimeToUnixTime(DateTime: TDateTime): TJclUnixTime32; +Begin Result := Round((DateTime-UnixTimeStart) * SecondsPerDay); -end; -function UnixTimeToDateTime(const UnixTime: TJclUnixTime32): TDateTime; -begin +End; +Function UnixTimeToDateTime(Const UnixTime: TJclUnixTime32): TDateTime; +Begin Result:= UnixTimeStart + (UnixTime / SecondsPerDay); -end; +End; // Conversion Unix time <--> FileTime {$IFDEF MSWINDOWS} -function UnixTimeToFileTime(const AValue: TJclUnixTime32): TFileTime; -begin +Function UnixTimeToFileTime(Const AValue: TJclUnixTime32): TFileTime; +Begin Result := DateTimeToFileTime(UnixTimeToDateTime(AValue)); -end; -function FileTimeToUnixTime(const AValue: TFileTime): TJclUnixTime32; -begin +End; +Function FileTimeToUnixTime(Const AValue: TFileTime): TJclUnixTime32; +Begin Result := DateTimeToUnixTime(FileTimeToDateTime(AValue)); -end; +End; {$ENDIF MSWINDOWS} // Time stamps utilities // Utility functions -function NullStamp: TTimeStamp; -begin +Function NullStamp: TTimeStamp; +Begin Result.Date := 0; Result.Time := -1; -end; -function CompareTimeStamps(const Stamp1, Stamp2: TTimeStamp): Int64; -begin - if Stamp1.Date < Stamp2.Date then +End; +Function CompareTimeStamps(Const Stamp1, Stamp2: TTimeStamp): Int64; +Begin + If Stamp1.Date < Stamp2.Date Then Result := -1 - else - if Stamp1.Date = Stamp2.Date then - begin - if Stamp1.Time < Stamp2.Time then + Else + If Stamp1.Date = Stamp2.Date Then + Begin + If Stamp1.Time < Stamp2.Time Then Result := -1 - else - if Stamp1.Time = Stamp2.Time then + Else + If Stamp1.Time = Stamp2.Time Then Result := 0 - else // If Stamp1.Time > Stamp2.Time then + Else // If Stamp1.Time > Stamp2.Time then Result := 1; - end - else // if Stamp1.Date > Stamp2.Date then + End + Else // if Stamp1.Date > Stamp2.Date then Result := 1; // Result := Int64(Stamp1) - Int64(Stamp2); -end; -function EqualTimeStamps(const Stamp1, Stamp2: TTimeStamp): Boolean; -begin +End; +Function EqualTimeStamps(Const Stamp1, Stamp2: TTimeStamp): Boolean; +Begin Result := CompareTimeStamps(Stamp1, Stamp2) = 0; -end; -function IsNullTimeStamp(const Stamp: TTimeStamp): Boolean; -begin +End; +Function IsNullTimeStamp(Const Stamp: TTimeStamp): Boolean; +Begin Result := CompareTimeStamps(NullStamp, Stamp) = 0; -end; -function TimeStampDOW(const Stamp: TTimeStamp): Integer; -begin +End; +Function TimeStampDOW(Const Stamp: TTimeStamp): Integer; +Begin Result := (Stamp.Date - 1) mod 7 + 1 -end; +End; // day of week utilities -function FirstWeekDay(const Year, Month: Integer; out DOW: Integer): Integer; -begin +Function FirstWeekDay(Const Year, Month: Integer; out DOW: Integer): Integer; +Begin DOW := ISODayOfWeek(EncodeDate(Year, Month, 1)); - if DOW > 5 then - begin + If DOW > 5 Then + Begin Result := 9 - DOW; DOW := 1; - end - else + End + Else Result := 1; -end; -function FirstWeekDay(const Year, Month: Integer): Integer; -var +End; +Function FirstWeekDay(Const Year, Month: Integer): Integer; +Var Dummy: Integer; -begin +Begin Result := FirstWeekDay(Year, Month, Dummy); -end; -function LastWeekDay(const Year, Month: Integer; out DOW: Integer): Integer; -begin +End; +Function LastWeekDay(Const Year, Month: Integer; out DOW: Integer): Integer; +Begin DOW := ISODayOfWeek(EncodeDate(Year, Month, DaysInMonth(EncodeDate(Year, Month, 1)))); - if DOW > 5 then - begin + If DOW > 5 Then + Begin Result := DaysInMonth(EncodeDate(Year, Month, 1)) - (DOW - 5); DOW := 5; - end - else + End + Else Result := DaysInMonth(EncodeDate(Year, Month, 1)); -end; -function LastWeekDay(const Year, Month: Integer): Integer; -var +End; +Function LastWeekDay(Const Year, Month: Integer): Integer; +Var Dummy: Integer; -begin +Begin Result := LastWeekDay(Year, Month, Dummy); -end; -function IndexedWeekDay(const Year, Month: Integer; Index: Integer): Integer; -var +End; +Function IndexedWeekDay(Const Year, Month: Integer; Index: Integer): Integer; +Var DOW: Integer; -begin - if Index > 0 then +Begin + If Index > 0 Then Result := FirstWeekDay(Year, Month, DOW) - else - if Index < 0 then + Else + If Index < 0 Then Result := LastWeekDay(Year, Month, DOW) - else + Else Result := 0; - if Index > 1 then // n-th weekday from start of month - begin + If Index > 1 Then // n-th weekday from start of month + Begin Dec(Index); - if DOW > 1 then // adjust to first monday - begin - if Index < (5 - DOW) then - begin + If DOW > 1 Then // adjust to first monday + Begin + If Index < (5 - DOW) Then + Begin Inc(Result, Index); Index := 0; - end - else - begin + End + Else + Begin Dec(Index, 6 - DOW); Inc(Result, 8 - DOW); - end; - end; + End; + End; Result := Result + (7 * (Index div 5)) + (Index mod 5); - end - else - if Index < -1 then // n-th weekday from end of month - begin + End + Else + If Index < -1 Then // n-th weekday from end of month + Begin Index := Abs(Index) - 1; - if DOW < 5 then // adjust to last friday - begin - if Index < DOW then - begin + If DOW < 5 Then // adjust to last friday + Begin + If Index < DOW Then + Begin Dec(Result, Index); Index := 0; - end - else - begin + End + Else + Begin Dec(Index, DOW); Dec(Result, DOW + 2); - end; - end; + End; + End; Result := Result - (7 * (Index div 5)) - (Index mod 5); - end; - if (Result < 0) or (Result > DaysInMonth(EncodeDate(Year, Month, 1))) then + End; + If (Result < 0) or (Result > DaysInMonth(EncodeDate(Year, Month, 1))) Then Result := 0; -end; -function FirstWeekendDay(const Year, Month: Integer; out DOW: Integer): Integer; -begin +End; +Function FirstWeekendDay(Const Year, Month: Integer; out DOW: Integer): Integer; +Begin DOW := ISODayOfWeek(EncodeDate(Year, Month, 1)); - if DOW < 6 then - begin + If DOW < 6 Then + Begin Result := 7 - DOW; DOW := 6; - end - else + End + Else Result := 1; -end; -function FirstWeekendDay(const Year, Month: Integer): Integer; -var +End; +Function FirstWeekendDay(Const Year, Month: Integer): Integer; +Var Dummy: Integer; -begin +Begin Result := FirstWeekendDay(Year, Month, Dummy); -end; -function LastWeekendDay(const Year, Month: Integer; out DOW: Integer): Integer; -begin +End; +Function LastWeekendDay(Const Year, Month: Integer; out DOW: Integer): Integer; +Begin DOW := ISODayOfWeek(EncodeDate(Year, Month, DaysInMonth(EncodeDate(Year, Month, 1)))); - if DOW < 6 then - begin + If DOW < 6 Then + Begin Result := DaysInMonth(EncodeDate(Year, Month, 1)) - DOW; DOW := 7; - end - else + End + Else Result := DaysInMonth(EncodeDate(Year, Month, 1)); -end; -function LastWeekendDay(const Year, Month: Integer): Integer; -var +End; +Function LastWeekendDay(Const Year, Month: Integer): Integer; +Var Dummy: Integer; -begin +Begin Result := LastWeekendDay(Year, Month, Dummy); -end; -function IndexedWeekendDay(const Year, Month: Integer; Index: Integer): Integer; -var +End; +Function IndexedWeekendDay(Const Year, Month: Integer; Index: Integer): Integer; +Var DOW: Integer; -begin - if Index > 0 then +Begin + If Index > 0 Then Result := FirstWeekendDay(Year, Month, DOW) - else - if Index < 0 then + Else + If Index < 0 Then Result := LastWeekendDay(Year, Month, DOW) - else + Else Result := 0; - if Index > 1 then // n-th weekend day from the start of the month - begin - if (DOW > 6) and not Odd(Index) then // Adjust to first saturday - begin + If Index > 1 Then // n-th weekend day from the start of the month + Begin + If (DOW > 6) and not Odd(Index) Then // Adjust to first saturday + Begin Inc(Result, 6); Dec(Index); - end; - if Index > 1 then - begin + End; + If Index > 1 Then + Begin Dec(Index); Result := Result + (7 * (Index div 2)) + (Index mod 2); - end; - end - else - if Index < -1 then // n-th weekend day from the start of the month - begin + End; + End + Else + If Index < -1 Then // n-th weekend day from the start of the month + Begin Index := Abs(Index); - if (DOW < 7) and not Odd(Index) then // Adjust to last sunday - begin + If (DOW < 7) and not Odd(Index) Then // Adjust to last sunday + Begin Dec(Result, 6); Dec(Index); - end; - if Index > 1 then - begin + End; + If Index > 1 Then + Begin Dec(Index); Result := Result - (7 * (Index div 2)) - (Index mod 2); - end; - end; - if (Result < 0) or (Result > DaysInMonth(EncodeDate(Year, Month, 1))) then + End; + End; + If (Result < 0) or (Result > DaysInMonth(EncodeDate(Year, Month, 1))) Then Result := 0; -end; -function FirstDayOfWeek(const Year, Month, DayOfWeek: Integer): Integer; -var +End; +Function FirstDayOfWeek(Const Year, Month, DayOfWeek: Integer): Integer; +Var DOW: Integer; -begin +Begin DOW := ISODayOfWeek(EncodeDate(Year, Month, 1)); - if DOW > DayOfWeek then + If DOW > DayOfWeek Then Result := 8 + DayOfWeek - DOW - else - if DOW < DayOfWeek then + Else + If DOW < DayOfWeek Then Result := 1 + DayOfWeek - DOW - else + Else Result := 1; -end; -function LastDayOfWeek(const Year, Month, DayOfWeek: Integer): Integer; -var +End; +Function LastDayOfWeek(Const Year, Month, DayOfWeek: Integer): Integer; +Var DOW: Integer; -begin +Begin DOW := ISODayOfWeek(EncodeDate(Year, Month, DaysInMonth(EncodeDate(Year, Month, 1)))); - if DOW > DayOfWeek then + If DOW > DayOfWeek Then Result := DaysInMonth(EncodeDate(Year, Month, 1)) - (DOW - DayOfWeek) - else - if DOW < DayOfWeek then + Else + If DOW < DayOfWeek Then Result := DaysInMonth(EncodeDate(Year, Month, 1)) - (7 - DayOfWeek + DOW) - else + Else Result := DaysInMonth(EncodeDate(Year, Month, 1)); -end; -function IndexedDayOfWeek(const Year, Month, DayOfWeek, Index: Integer): Integer; -begin - if Index > 0 then +End; +Function IndexedDayOfWeek(Const Year, Month, DayOfWeek, Index: Integer): Integer; +Begin + If Index > 0 Then Result := FirstDayOfWeek(Year, Month, DayOfWeek) + 7 * (Index - 1) - else - if Index < 0 then + Else + If Index < 0 Then Result := LastDayOfWeek(Year, Month, DayOfWeek) - 7 * (Abs(Index) - 1) - else + Else Result := 0; - if (Result < 0) or (Result > DaysInMonth(EncodeDate(Year, Month, 1))) then + If (Result < 0) or (Result > DaysInMonth(EncodeDate(Year, Month, 1))) Then Result := 0; -end; +End; {$IFDEF UNITVERSIONING} -initialization - RegisterUnitVersion(HInstance, UnitVersioning); -finalization - UnregisterUnitVersion(HInstance); +Initialization + RegisterUnitVersion(HInstance, UnitVersioning); +Finalization + UnregisterUnitVersion(HInstance); {$ENDIF UNITVERSIONING} -end. +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemExprParser.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemExprParser.pas index 4f18c422f..14af8d9b7 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemExprParser.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemExprParser.pas @@ -1,6 +1,6 @@ -unit uRESTDWMemExprParser; +Unit uRESTDWMemExprParser; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . @@ -23,25 +23,25 @@ Roniery - Devel. } -interface +Interface {$IFDEF FPC} {$MODE OBJFPC}{$H+} {$ENDIF} -uses +Uses SysUtils, Classes; -type +Type TObjectList = Class(TList); - TOnGetVariableValue = function(Sender: TObject; const VarName: string; - var Value: Variant): Boolean of object; + TOnGetVariableValue = Function(Sender: TObject; Const VarName: string; + Var Value: Variant): Boolean Of object; - TOnExecuteFunction = function(Sender: TObject; const FuncName: string; - const Args: Variant; var ResVal: Variant): Boolean of object; + TOnExecuteFunction = Function(Sender: TObject; Const FuncName: string; + Const Args: Variant; Var ResVal: Variant): Boolean Of object; - TExprParser = class - private + TExprParser = Class + Private FValue: Variant; FParser: TObject; // TParser FScan: TObject; // TScan @@ -51,16 +51,16 @@ TExprParser = class FEnableWildcardMatching: Boolean; FErrorMessage: string; FCaseInsensitive: Boolean; - procedure SetExpression(const Value: string); - function DoGetVariable(const VarName: string; var Value: Variant): Boolean; - function DoExecuteFunction(const FuncName: string; const Args: Variant; var ResVal: Variant): Boolean; - procedure SetCaseInsensitive(const Value: Boolean); - function ConvertDoubleOperators(Value : String) : String; - public - constructor Create(); - destructor Destroy; override; - function Eval: Boolean; overload; - function Eval(const AExpression: string): Boolean; overload; + Procedure SetExpression(Const Value: string); + Function DoGetVariable(Const VarName: string; Var Value: Variant): Boolean; + Function DoExecuteFunction(Const FuncName: string; Const Args: Variant; Var ResVal: Variant): Boolean; + Procedure SetCaseInsensitive(Const Value: Boolean); + Function ConvertDoubleOperators(Value : String) : String; + Public + Constructor Create(); + Destructor Destroy; override; + Function Eval: Boolean; overload; + Function Eval(Const AExpression: string): Boolean; overload; property ErrorMessage: string read FErrorMessage; {published} // ahuser: not a TPersistent derived class property Expression: string read FExpression write SetExpression; @@ -69,17 +69,17 @@ TExprParser = class property Value: Variant read FValue; property EnableWildcardMatching: Boolean read FEnableWildcardMatching write FEnableWildcardMatching; property CaseInsensitive: Boolean read FCaseInsensitive write SetCaseInsensitive; - end; + End; - EExprParserError = class(Exception); + EExprParserError = Class(Exception); {$IFDEF TESTING_PARSER} -var +Var DebugText: string; {$ENDIF TESTING_PARSER} -implementation +Implementation -uses +Uses Variants{$IFNDEF FPC}, Masks{$ENDIF}; {$IFDEF COMPILER12_UP} // Our charsets do not contain any char > 127 what makes it safe because the @@ -87,7 +87,7 @@ implementation {$WARN WIDECHAR_REDUCED OFF} {$ENDIF COMPILER12_UP} -const +Const cNumbers = ['0'..'9']; cLetters = ['a'..'z', 'A'..'Z', '_']; cLettersAndNumbers = cLetters + cNumbers; @@ -106,276 +106,276 @@ implementation '!', '~']; -type +Type TToken = (tkNA, tkEOF, tkError, tkLParen, tkRParen, tkComa, tkOperator, tkIdentifier, tkNumber, tkInteger, tkString); - TLex = class - private + TLex = Class + Private FToken: TToken; FChr: Char; FStr: string; FPos: Integer; - public - constructor Create(AToken: TToken; APos: Integer); overload; - constructor Create(AToken: TToken; const AStr: string; APos: Integer); overload; - constructor Create(AToken: TToken; AChr: Char; APos: Integer); overload; - function Debug(): string; + Public + Constructor Create(AToken: TToken; APos: Integer); overload; + Constructor Create(AToken: TToken; Const AStr: string; APos: Integer); overload; + Constructor Create(AToken: TToken; AChr: Char; APos: Integer); overload; + Function Debug(): string; property Token: TToken read FToken; property Chr: Char read FChr; property Str: string read FStr; property Pos: Integer read FPos; - end; + End; - TScan = class(TObjectList) - private + TScan = Class(TObjectList) + Private FErrorMessage: string; - function GetItem(Index: Integer): TLex; - public - constructor Create(); + Function GetItem(Index: Integer): TLex; + Public + Constructor Create(); property Items[Index: Integer]: TLex read GetItem; default; - function Parse(const Str: string): Boolean; + Function Parse(Const Str: string): Boolean; {$IFDEF TESTING_PARSER} - procedure DebugPrint(); + Procedure DebugPrint(); {$ENDIF TESTING_PARSER} property ErrorMessage: string read FErrorMessage; - end; + End; - TParser = class; - TNode = class - private + TParser = Class; + TNode = Class + Private FParser: TParser; - public - constructor Create(Parser: TParser); virtual; + Public + Constructor Create(Parser: TParser); virtual; // Delphi 5 compiler shows hints about a not exported or used symbol // TNode.Eval. This is a compiler bug that is caused by the "abstract" keyword. - function Eval(): Variant; virtual; abstract; - end; + Function Eval(): Variant; virtual; abstract; + End; - EParserError = class(EExprParserError) - public - constructor Create(const Msg: string; Lex: TLex); overload; - end; + EParserError = Class(EExprParserError) + Public + Constructor Create(Const Msg: string; Lex: TLex); overload; + End; - TNodeCValue = class(TNode) - private + TNodeCValue = Class(TNode) + Private FCValue: TLex; - public - constructor Create(AParser: TParser; ACValue: TLex); reintroduce; - function Eval(): Variant; override; - end; + Public + Constructor Create(AParser: TParser; ACValue: TLex); reintroduce; + Function Eval(): Variant; override; + End; - TNodeVariable = class(TNode) - private + TNodeVariable = Class(TNode) + Private FLex: TLex; - public - constructor Create(AParser: TParser; ALex: TLex); reintroduce; - function Eval(): Variant; override; - end; + Public + Constructor Create(AParser: TParser; ALex: TLex); reintroduce; + Function Eval(): Variant; override; + End; - TNodeUnary = class(TNode) - private + TNodeUnary = Class(TNode) + Private FOperator: TLex; FRightNode: TNode; - public - constructor Create(AParser: TParser; AOperator: TLex; ARightNode: TNode); reintroduce; - destructor Destroy; override; - function Eval(): Variant; override; - end; + Public + Constructor Create(AParser: TParser; AOperator: TLex; ARightNode: TNode); reintroduce; + Destructor Destroy; override; + Function Eval(): Variant; override; + End; - TNodeBin = class(TNode) - private + TNodeBin = Class(TNode) + Private FOperator: TLex; FLeftNode, FRightNode: TNode; - public - constructor Create(AParser: TParser; AOperator: TLex; ALeftNode, ARightNode: TNode); reintroduce; - destructor Destroy; override; - function Eval(): Variant; override; - end; + Public + Constructor Create(AParser: TParser; AOperator: TLex; ALeftNode, ARightNode: TNode); reintroduce; + Destructor Destroy; override; + Function Eval(): Variant; override; + End; - TNodeFunction = class(TNode) - private + TNodeFunction = Class(TNode) + Private FFunc: TLex; FArgs: TObjectList; - public - constructor Create(AParser: TParser; AFunc: TLex); reintroduce; - destructor Destroy; override; - procedure AddArg(Node: TNode); - function Eval(): Variant; override; - end; + Public + Constructor Create(AParser: TParser; AFunc: TLex); reintroduce; + Destructor Destroy; override; + Procedure AddArg(Node: TNode); + Function Eval(): Variant; override; + End; - TParser = class - private + TParser = Class + Private FParent: TExprParser; FScan: TScan; FScanIdx: Integer; FRoot: TNode; FErrorMessage: string; FValue: Variant; - public - destructor Destroy; override; - function Parse(): Boolean; - function Execute(): Boolean; - function Expr(): TNode; - function Term(): TNode; - function Factor(): TNode; - function LexC(): TLex; - function LexLook(LookAhead: Integer = 1): TLex; - procedure LexAccept(); + Public + Destructor Destroy; override; + Function Parse(): Boolean; + Function Execute(): Boolean; + Function Expr(): TNode; + Function Term(): TNode; + Function Factor(): TNode; + Function LexC(): TLex; + Function LexLook(LookAhead: Integer = 1): TLex; + Procedure LexAccept(); property Parent: TExprParser read FParent write FParent; property Value: Variant read FValue; property ErrorMessage: string read FErrorMessage; property Scan: TScan read FScan write FScan; - end; -var + End; +Var ELexEOF: TLex; // ahuser: what the... {$IFDEF TESTING_PARSER} -procedure DebugMessage(const msg: string); -begin +Procedure DebugMessage(Const msg: string); +Begin DebugText := DebugText + msg + sLineBreak; -end; +End; {$ENDIF TESTING_PARSER} { TLex } -constructor TLex.Create(AToken: TToken; APos: Integer); -begin +Constructor TLex.Create(AToken: TToken; APos: Integer); +Begin FToken := AToken; FPos := APos; -end; -constructor TLex.Create(AToken: TToken; const AStr: string; APos: Integer); -begin - inherited Create; +End; +Constructor TLex.Create(AToken: TToken; Const AStr: string; APos: Integer); +Begin + Inherited Create; FToken := AToken; FStr := AStr; FPos := APos; -end; -constructor TLex.Create(AToken: TToken; AChr: Char; APos: Integer); -begin +End; +Constructor TLex.Create(AToken: TToken; AChr: Char; APos: Integer); +Begin FToken := AToken; FChr := Char(AChr); FPos := APos; -end; -function TLex.debug: string; -const - TokenStr: array[TToken] of string = +End; +Function TLex.debug: string; +Const + TokenStr: array[TToken] Of string = ('N/A', 'End of expression', 'Error', '(', ')', ',', 'Operator', 'Identifier', 'Number', 'Integer', 'String'); -begin +Begin Result := TokenStr[Token]; - case Token of + Case Token Of tkOperator: Result := Result + ': ' + Chr; tkIdentifier, tkNumber, tkInteger, tkString: Result := Result + ': ' + Str; - end; + End; Result := Result + ' at pos: ' + IntToStr(Pos); -end; +End; { TScan } -constructor TScan.Create; -begin - inherited Create; +Constructor TScan.Create; +Begin + Inherited Create; FErrorMessage := ''; -end; -function TScan.GetItem(Index: Integer): TLex; -begin - Result := TLex(inherited Items[Index]); -end; -function TScan.Parse(const Str: string): Boolean; -var +End; +Function TScan.GetItem(Index: Integer): TLex; +Begin + Result := TLex(Inherited Items[Index]); +End; +Function TScan.Parse(Const Str: string): Boolean; +Var Idx, StartIdx, Len: Integer; C: Char; S: string; CToken: TToken; -begin +Begin Len := Length(Str); Idx := 1; S := ''; CToken := tkNA; - while Idx <= Len do - begin + While Idx <= Len Do + Begin C := Str[Idx]; StartIdx := Idx; Inc(Idx); CToken := tkNA; - case C of + Case C Of '(': CToken := tkLParen; ')': CToken := tkRParen; ',': CToken := tkComa; ' ', #09: ; - else - if C in cOperators then + Else + If C in cOperators Then CToken := tkOperator - else - if (C = '"') or (C = '''') then - begin + Else + If (C = '"') or (C = '''') Then + Begin CToken := tkString; - while (Idx <= Len) and (Str[Idx] <> C) do - begin + While (Idx <= Len) and (Str[Idx] <> C) Do + Begin S := S + Str[Idx]; // ahuser: performance suicide Inc(Idx); - end; - if (Idx <= Len) and (Str[Idx] = C) then + End; + If (Idx <= Len) and (Str[Idx] = C) Then Inc(Idx) - else - begin + Else + Begin CToken := tkError; FErrorMessage := 'No end of string found'; - end - end - else - if C in cNumbers then - begin + End + End + Else + If C in cNumbers Then + Begin CToken := tkInteger; S := S + C; - while (Idx <= Len) and (Str[Idx] in cNumbers) do - begin + While (Idx <= Len) and (Str[Idx] in cNumbers) Do + Begin S := S + Str[Idx]; // ahuser: performance suicide Inc(Idx); - end; - if ((Idx <= Len) and (Str[Idx] = '.')) then - begin + End; + If ((Idx <= Len) and (Str[Idx] = '.')) Then + Begin CToken := tkNumber; Inc(Idx); S := S + '.'; - while (Idx <= Len) and (Str[Idx] in cNumbers) do - begin + While (Idx <= Len) and (Str[Idx] in cNumbers) Do + Begin S := S + Str[Idx]; // ahuser: performance suicide Inc(Idx); - end; - end; - end - else - if C = '.' then // .55 - begin + End; + End; + End + Else + If C = '.' Then // .55 + Begin CToken := tkNumber; S := S + C; - while (Idx <= Len) and (Str[Idx] in cNumbers) do - begin + While (Idx <= Len) and (Str[Idx] in cNumbers) Do + Begin S := S + Str[Idx]; // ahuser: performance suicide Inc(Idx); - end; - end - else - if C in cLetters then - begin + End; + End + Else + If C in cLetters Then + Begin CToken := tkIdentifier; S := S + C; - while (Idx <= Len) and (Str[Idx] in cLettersAndNumbers) do - begin + While (Idx <= Len) and (Str[Idx] in cLettersAndNumbers) Do + Begin S := S + Str[Idx]; // ahuser: performance suicide Inc(Idx); - end; - end - else - begin + End; + End + Else + Begin CToken := tkError; FErrorMessage := Format('Bad character ''%s''', [string(C)]); - end; - end; - case CToken of + End; + End; + Case CToken Of tkError: break; tkNA: ; // continue tkOperator: Add(TLex.Create(tkOperator, C, StartIdx)); @@ -383,314 +383,314 @@ function TScan.Parse(const Str: string): Boolean; tkNumber, tkInteger, tkString: - begin - if CompareText(S, 'and') = 0 then + Begin + If CompareText(S, 'and') = 0 Then Add(TLex.Create(tkOperator, '&', StartIdx)) - else - if CompareText(S, 'or') = 0 then + Else + If CompareText(S, 'or') = 0 Then Add(TLex.Create(tkOperator, '|', StartIdx)) - else - begin - if CompareText(S, 'like')=0 then + Else + Begin + If CompareText(S, 'like')=0 Then Add(TLex.Create(tkOperator, '~', StartIdx)) - else + Else Add(TLex.Create(CToken, S, StartIdx)); - end; + End; S := ''; - end - else + End + Else Add(TLex.Create(CToken, StartIdx)); - end; - end; + End; + End; Result := CToken <> tkError; ELexEOF := TLex.Create(tkEOF, Idx); Add(ELexEOF); -end; +End; {$IFDEF TESTING_PARSER} -procedure TScan.DebugPrint; -var +Procedure TScan.DebugPrint; +Var I: Integer; -begin - for I := 0 to Count - 1 do +Begin + For I := 0 To Count - 1 Do DebugMessage(Items[I].Debug); -end; +End; {$ENDIF TESTING_PARSER} { TParser } -destructor TParser.Destroy; -begin +Destructor TParser.Destroy; +Begin FRoot.Free; - inherited Destroy; -end; -function TParser.Parse: Boolean; -begin + Inherited Destroy; +End; +Function TParser.Parse: Boolean; +Begin FreeAndNil(FRoot); - try + Try FRoot := Expr(); - if FScanIdx < FScan.Count - 1 then - begin + If FScanIdx < FScan.Count - 1 Then + Begin FreeAndNil(FRoot); raise EParserError.Create('Unexpected ', LexC()); - end; - except - on E: Exception do + End; + Except + on E: Exception Do FErrorMessage := E.Message; - end; + End; Result := FRoot <> nil; -end; -function TParser.Execute: Boolean; -begin +End; +Function TParser.Execute: Boolean; +Begin Result := False; - if FRoot <> nil then - begin - try + If FRoot <> nil Then + Begin + Try FValue := FRoot.Eval(); Result := True; - except - on E: Exception do - begin + Except + on E: Exception Do + Begin FErrorMessage := E.Message; // raise; - end; - end; - end; -end; -procedure TParser.LexAccept; -begin + End; + End; + End; +End; +Procedure TParser.LexAccept; +Begin Inc(FScanIdx); -end; -function TParser.LexC: TLex; -begin +End; +Function TParser.LexC: TLex; +Begin Result := LexLook(0); -end; -function TParser.LexLook(LookAhead: Integer): TLex; -begin - if (FScanIdx + LookAhead) < FScan.Count then +End; +Function TParser.LexLook(LookAhead: Integer): TLex; +Begin + If (FScanIdx + LookAhead) < FScan.Count Then Result := FScan[FScanIdx + LookAhead] - else + Else Result := ELexEOF; -end; -function TParser.Expr: TNode; -var +End; +Function TParser.Expr: TNode; +Var CNode, RightNode: TNode; Lex: TLex; -begin +Begin CNode := nil; - try + Try CNode := Term(); Lex := LexC(); - if Lex.Token = tkOperator then - begin - if Lex.Chr in ['+', '-'] then - begin + If Lex.Token = tkOperator Then + Begin + If Lex.Chr in ['+', '-'] Then + Begin LexAccept(); RightNode := Expr(); - if RightNode = nil then + If RightNode = nil Then raise EParserError.Create('Expression expected after', Lex); CNode := TNodeBin.Create(Self, Lex, CNode, RightNode); - end; - end; - except - on E: Exception do - begin + End; + End; + Except + on E: Exception Do + Begin FreeAndNil(CNode); - if E is EParserError then + If E is EParserError Then raise - else + Else raise EParserError.Create(E.Message); - end; - end; + End; + End; Result := CNode; -end; -function TParser.Term: TNode; -var +End; +Function TParser.Term: TNode; +Var CNode, RightNode: TNode; Lex: TLex; -begin +Begin CNode := nil; - try + Try CNode := Factor(); Lex := LexC(); - if Lex.Token = tkOperator then - begin - if Lex.chr in ['*', '/', '=', '&', '|', '<', '>', '~', - {$IFNDEF FPC}{$IFDEF DELPHI2010UP}'�',{$ENDIF}{$ENDIF}'@', '#'] then - begin + If Lex.Token = tkOperator Then + Begin + If Lex.chr in ['*', '/', '=', '&', '|', '<', '>', '~', + {$IFNDEF FPC}{$IFDEF DELPHI2010UP}'�',{$ENDIF}{$ENDIF}'@', '#'] Then + Begin LexAccept(); RightNode := Expr(); - if RightNode = nil then + If RightNode = nil Then raise EParserError.Create('Expression expected after', Lex); CNode := TNodeBin.Create(Self, Lex, CNode, RightNode); - end; - end; - except - on E: Exception do - begin + End; + End; + Except + on E: Exception Do + Begin FreeAndNil(CNode); - if E is EParserError then + If E is EParserError Then raise - else + Else raise EParserError.Create(E.Message); - end; - end; + End; + End; Result := CNode; -end; -function TParser.Factor: TNode; -var +End; +Function TParser.Factor: TNode; +Var CNode: TNode; fNode: TNodeFunction; Lex: TLex; -begin +Begin CNode := nil; - try + Try Lex := LexC(); - case Lex.token of + Case Lex.token Of tkLParen: - begin + Begin LexAccept(); CNode := Expr(); - if (LexC().Token = tkRParen) then + If (LexC().Token = tkRParen) Then LexAccept() - else + Else raise EParserError.Create('Expected closing parenthesis instead of', LexC()); - end; + End; tkOperator: // unary minus - begin - if Lex.Chr in ['+', '-', '!'] then - begin + Begin + If Lex.Chr in ['+', '-', '!'] Then + Begin LexAccept(); CNode := TNodeUnary.Create(Self, Lex, Factor()); - end - else + End + Else raise EParserError.Create('Unexpected ', Lex); - end; + End; tkNumber, tkInteger, tkString: - begin + Begin CNode := TNodeCValue.Create(Self, Lex); LexAccept(); - end; + End; tkIdentifier: - begin - if LexLook().Token = tkLParen then - begin + Begin + If LexLook().Token = tkLParen Then + Begin // function call LexAccept(); fNode := TNodeFunction.Create(Self, Lex); LexAccept(); CNode := fNode; - if (LexC().token <> tkRParen) then - begin + If (LexC().token <> tkRParen) Then + Begin fNode.AddArg(Expr()); - while LexC().Token = tkComa do - begin + While LexC().Token = tkComa Do + Begin LexAccept(); fNode.AddArg(Expr()); - end; - end; - if (LexC().token = tkRParen) then + End; + End; + If (LexC().token = tkRParen) Then LexAccept() - else + Else raise EParserError.Create('Expected closing parenthesis instead of', LexC()); - end - else - begin + End + Else + Begin CNode := TNodeVariable.Create(Self, Lex); LexAccept(); - end; - end; - else + End; + End; + Else raise EParserError.Create('Unexpected ', Lex); - end; - except - on E: Exception do - begin + End; + Except + on E: Exception Do + Begin FreeAndNil(CNode); - if E is EParserError then + If E is EParserError Then raise - else + Else raise EParserError.Create(E.Message); - end; - end; + End; + End; Result := CNode; -end; +End; { TNode } -constructor TNode.Create(Parser: TParser); -begin - inherited Create; +Constructor TNode.Create(Parser: TParser); +Begin + Inherited Create; FParser := Parser; -end; +End; { TNodeBin } -constructor TNodeBin.Create(AParser: TParser; AOperator: TLex; ALeftNode, ARightNode: TNode); -begin - inherited Create(AParser); +Constructor TNodeBin.Create(AParser: TParser; AOperator: TLex; ALeftNode, ARightNode: TNode); +Begin + Inherited Create(AParser); FOperator := AOperator; FLeftNode := ALeftNode; FRightNode := ARightNode; -end; -destructor TNodeBin.Destroy; -begin +End; +Destructor TNodeBin.Destroy; +Begin FLeftNode.Free; FRightNode.Free; - inherited Destroy; -end; -function TNodeBin.Eval: Variant; -var + Inherited Destroy; +End; +Function TNodeBin.Eval: Variant; +Var LeftValue, RightValue: Variant; - function FixupBoolean(var AVal1: Variant; var AVal2: Variant): Boolean; - begin + Function FixupBoolean(Var AVal1: Variant; Var AVal2: Variant): Boolean; + Begin Result := (TVarData(AVal1).VType = varBoolean) or (TVarData(AVal2).VType = varBoolean); - if Result then - begin - if UpperCase(AVal1) = 'TRUE' then + If Result Then + Begin + If UpperCase(AVal1) = 'TRUE' Then AVal1 := 1 - else + Else AVal1 := 0; - if UpperCase(AVal2) = 'TRUE' then + If UpperCase(AVal2) = 'TRUE' Then AVal2 := 1 - else + Else AVal2 := 0; - end; - end; - function FixupDateTime(var AVal1: Variant; var AVal2: Variant): Boolean; - begin + End; + End; + Function FixupDateTime(Var AVal1: Variant; Var AVal2: Variant): Boolean; + Begin Result := TVarData(AVal1).VType = varDate; - if Result then - begin - if TVarData(AVal2).VType = varString then + If Result Then + Begin + If TVarData(AVal2).VType = varString Then AVal2 := StrToDateTime(AVal2); //convert; - end; - end; - function FixupString(var aVal: Variant): Boolean; - begin + End; + End; + Function FixupString(Var aVal: Variant): Boolean; + Begin Result:=((TVarData(aVal).VType = varString) {$IFDEF UNICODE}or (TVarData(aVal).VType = varUString){$ENDIF UNICODE}) and FParser.Parent.FCaseInsensitive; - if Result then + If Result Then aVal := AnsiUpperCase(aVal); - end; + End; //returns 'True' if a conversion was necessary. - function FixupValues(var AVal1: Variant; var AVal2: Variant): Boolean; - var + Function FixupValues(Var AVal1: Variant; Var AVal2: Variant): Boolean; + Var bChanged: Boolean; - begin + Begin Result := FixupDateTime(AVal1, AVal2); - if not Result then + If not Result Then Result := FixupDateTime(AVal2, AVal1); - if not Result then + If not Result Then Result := FixupBoolean(AVal1, AVal2); - if not Result then //ensure that the 'String' case is the last one - begin + If not Result Then //ensure that the 'String' case is the last one + Begin Result := FixupString(AVal1); bChanged := FixupString(AVal2); Result := Result or bChanged; //ensure that both Fixups are executed regardless of optimisations - end; - end; - function EvalLike: Boolean; - var + End; + End; + Function EvalLike: Boolean; + Var Wildcard1, Wildcard2: Boolean; LeftStr, RightStr: string; - begin - if (LeftValue = Null) or (RightValue = Null) then + Begin + If (LeftValue = Null) or (RightValue = Null) Then Result := (LeftValue = Null) and (RightValue = Null) - else - begin + Else + Begin // Possiblilities: // Left hand contains wildcards -> Match right hand against left hand. // Right hand contains wildcards -> Match left hand against right hand. @@ -700,89 +700,89 @@ function TNodeBin.Eval: Variant; Wildcard1 := (Pos('*', LeftStr) > 0) or (Pos('?', LeftStr) > 0); Wildcard2 := (Pos('*', RightStr) > 0) or (Pos('?', RightStr) > 0); {$IFNDEF FPC} - if Wildcard1 and not Wildcard2 then + If Wildcard1 and not Wildcard2 Then Result := MatchesMask(RightStr, LeftStr) - else - if Wildcard2 then + Else + If Wildcard2 Then Result := MatchesMask(LeftStr, RightStr) - else + Else {$ENDIF} Result := LeftValue = RightValue; - end; - end; - function EvalEquality: Boolean; - begin + End; + End; + Function EvalEquality: Boolean; + Begin // Special case, at least one of both is null: - if (LeftValue = Null) or (RightValue = Null) then + If (LeftValue = Null) or (RightValue = Null) Then Result := (LeftValue = Null) and (RightValue = Null) - else - begin - if FParser.Parent.FEnableWildcardMatching and (TVarData(LeftValue).VType<>varDate) then - begin + Else + Begin + If FParser.Parent.FEnableWildcardMatching and (TVarData(LeftValue).VType<>varDate) Then + Begin Result := EvalLike; - end - else + End + Else Result := LeftValue = RightValue; - end; - end; - function EvalLT: Boolean; - begin + End; + End; + Function EvalLT: Boolean; + Begin // Special case, at least one of both is Null: - if (LeftValue = Null) or (RightValue = Null) then + If (LeftValue = Null) or (RightValue = Null) Then // Null is considered to be smaller than any value. Result := LeftValue = Null - else + Else Result := LeftValue < RightValue; - end; - function EvalGT: Boolean; - begin + End; + Function EvalGT: Boolean; + Begin // Special case, at least one of both is Null: - if (LeftValue = Null) or (RightValue = Null) then + If (LeftValue = Null) or (RightValue = Null) Then // Null is considered to be smaller than any value. Result := RightValue = Null - else + Else Result := LeftValue > RightValue; - end; - function EvalLTE: Boolean; - begin + End; + Function EvalLTE: Boolean; + Begin // Special case, at least one of both is Null: - if (LeftValue = Null) or (RightValue = Null) then + If (LeftValue = Null) or (RightValue = Null) Then // Null is considered to be smaller than any value. Result := LeftValue = Null - else + Else Result := LeftValue <= RightValue; - end; - function EvalGTE: Boolean; - begin + End; + Function EvalGTE: Boolean; + Begin // Special case, at least one of both is Null: - if (LeftValue = Null) or (RightValue = Null) then + If (LeftValue = Null) or (RightValue = Null) Then // Null is considered to be smaller than any value. Result := RightValue = Null - else + Else Result := LeftValue >= RightValue; - end; -var + End; +Var LeftStr, RightStr: string; -begin +Begin // Determine values to have them handy. LeftValue := FLeftNode.Eval; RightValue := FRightNode.Eval; FixupValues(LeftValue, RightValue); - case FOperator.Chr of + Case FOperator.Chr Of '+': - begin + Begin // force string concatenation - if (TVarData(LeftValue).VType = varString) or - (TVarData(LeftValue).VType = varOleStr) then - begin + If (TVarData(LeftValue).VType = varString) or + (TVarData(LeftValue).VType = varOleStr) Then + Begin LeftStr := LeftValue; RightStr := RightValue; LeftStr := LeftStr + RightStr; Result := LeftStr; - end - else + End + Else Result := LeftValue + RightValue; - end; + End; '-': Result := LeftValue - RightValue; '*': Result := FLeftNode.Eval * FRightNode.Eval; '/': Result := FLeftNode.Eval / FRightNode.Eval; @@ -799,160 +799,160 @@ function TNodeBin.Eval: Variant; {$ENDIF} '@': Result := EvalLTE(); '#': Result := not EvalEquality(); - else + Else Result := Null; - end; -end; + End; +End; { TNodeUnary } -constructor TNodeUnary.Create(AParser: TParser; AOperator: TLex; ARightNode: TNode); -begin - inherited Create(AParser); +Constructor TNodeUnary.Create(AParser: TParser; AOperator: TLex; ARightNode: TNode); +Begin + Inherited Create(AParser); FOperator := AOperator; FRightNode := ARightNode; -end; -destructor TNodeUnary.Destroy; -begin +End; +Destructor TNodeUnary.Destroy; +Begin FRightNode.Free; - inherited Destroy; -end; -function TNodeUnary.Eval: Variant; -begin + Inherited Destroy; +End; +Function TNodeUnary.Eval: Variant; +Begin Result := FRightNode.Eval(); - if FOperator.Chr = '-' then + If FOperator.Chr = '-' Then Result := -Result; - if FOperator.Chr = '!' then + If FOperator.Chr = '!' Then Result := not Result; -end; +End; { TNodeCValue } -constructor TNodeCValue.Create(AParser: TParser; ACValue: TLex); -begin - inherited Create(AParser); +Constructor TNodeCValue.Create(AParser: TParser; ACValue: TLex); +Begin + Inherited Create(AParser); FCValue := ACValue; -end; -function TNodeCValue.Eval: Variant; -begin - case FCValue.Token of +End; +Function TNodeCValue.Eval: Variant; +Begin + Case FCValue.Token Of tkNumber: Result := StrToFloat(FCValue.Str); tkInteger: Result := StrToInt(FCValue.Str); tkString: Result := FCValue.Str; - else + Else Result := Null; - end; -end; + End; +End; { TNodeFunction } -constructor TNodeFunction.Create(AParser: TParser; AFunc: TLex); -begin - inherited Create(AParser); +Constructor TNodeFunction.Create(AParser: TParser; AFunc: TLex); +Begin + Inherited Create(AParser); FArgs := TObjectList.Create; FFunc := AFunc; -end; -destructor TNodeFunction.Destroy; -begin +End; +Destructor TNodeFunction.Destroy; +Begin FArgs.Free; - inherited Destroy; -end; -procedure TNodeFunction.AddArg(Node: TNode); -begin + Inherited Destroy; +End; +Procedure TNodeFunction.AddArg(Node: TNode); +Begin FArgs.Add(Node); -end; -function TNodeFunction.Eval: Variant; -var +End; +Function TNodeFunction.Eval: Variant; +Var Value: Variant; VArgs: Variant; I: Integer; -begin +Begin VArgs := VarArrayCreate([0, FArgs.Count - 1], varVariant); - for I := 0 to FArgs.Count - 1 do + For I := 0 To FArgs.Count - 1 Do VArgs[I] := TNode(FArgs[I]).Eval(); Value := Null; - if FParser.Parent.DoExecuteFunction(FFunc.Str, VArgs, Value) then + If FParser.Parent.DoExecuteFunction(FFunc.Str, VArgs, Value) Then Result := Value - else + Else raise EParserError.CreateFmt('Function %s could not be executed.', [FFunc.Str]); -end; +End; { TNodeVariable } -constructor TNodeVariable.Create(AParser: TParser; ALex: TLex); -begin - inherited Create(AParser); +Constructor TNodeVariable.Create(AParser: TParser; ALex: TLex); +Begin + Inherited Create(AParser); FLex := ALex; -end; -function TNodeVariable.Eval: Variant; -var +End; +Function TNodeVariable.Eval: Variant; +Var Value: Variant; -begin +Begin Value := Null; - if FParser.Parent.DoGetVariable(FLex.Str, Value) then + If FParser.Parent.DoGetVariable(FLex.Str, Value) Then Result := Value - else + Else raise EParserError.Create('Variable ' + FLex.Str + ' could not be fetched.'); -end; +End; { EParserError } -constructor EParserError.Create(const Msg: string; Lex: TLex); -begin - inherited CreateFmt('%s %s', [Msg, Lex.Debug]); -end; +Constructor EParserError.Create(Const Msg: string; Lex: TLex); +Begin + Inherited CreateFmt('%s %s', [Msg, Lex.Debug]); +End; { TExprParser } -function TExprParser.ConvertDoubleOperators(Value: String): String; -var +Function TExprParser.ConvertDoubleOperators(Value: String): String; +Var i : integer; bEscapeDoubleQuote, bEscapeQuote : Boolean; sOperator : string; -begin +Begin Result := ''; bEscapeDoubleQuote := False; bEscapeQuote := False; i := 1; - while i <= Length(Value) do begin - if (Value[i] = '"') and (not bEscapeQuote) then begin + While i <= Length(Value) Do Begin + If (Value[i] = '"') and (not bEscapeQuote) Then Begin bEscapeDoubleQuote := not bEscapeDoubleQuote; Result := Result + Value[i]; - end - else if (Value[i] = '''') and (not bEscapeDoubleQuote) then begin + End + Else If (Value[i] = '''') and (not bEscapeDoubleQuote) Then Begin bEscapeQuote := not bEscapeQuote; Result := Result + Value[i]; - end - else if (Value[i] in cOperators) and (not bEscapeQuote) and (not bEscapeDoubleQuote) then begin + End + Else If (Value[i] in cOperators) and (not bEscapeQuote) and (not bEscapeDoubleQuote) Then Begin sOperator := sOperator + Value[i]; - end - else begin - if sOperator <> '' then begin + End + Else Begin + If sOperator <> '' Then Begin sOperator := StringReplace(sOperator,'>=','�',[rfReplaceAll]); sOperator := StringReplace(sOperator,'<=','@',[rfReplaceAll]); sOperator := StringReplace(sOperator,'<>','#',[rfReplaceAll]); sOperator := StringReplace(sOperator,'!=','#',[rfReplaceAll]); Result := Result + sOperator; sOperator := ''; - end; + End; Result := Result + Value[i]; - end; + End; i := i + 1; - end; -end; + End; +End; -constructor TExprParser.Create; -begin - inherited Create; +Constructor TExprParser.Create; +Begin + Inherited Create; FErrorMessage := ''; -end; -destructor TExprParser.Destroy; -begin +End; +Destructor TExprParser.Destroy; +Begin FParser.Free; FScan.Free; - inherited Destroy; -end; -function TExprParser.Eval(): Boolean; -var + Inherited Destroy; +End; +Function TExprParser.Eval(): Boolean; +Var Parser: TParser; {$IFDEF TESTING_PARSER} Scan: TScan; {$ENDIF TESTING_PARSER} -begin +Begin FErrorMessage := ''; {$IFDEF TESTING_PARSER} DebugText := ''; @@ -960,58 +960,58 @@ function TExprParser.Eval(): Boolean; Scan.DebugPrint(); {$ENDIF TESTING_PARSER} Parser := TParser(FParser); - if Parser.Execute() then - begin + If Parser.Execute() Then + Begin FValue := Parser.Value; Result := True; - end - else - begin + End + Else + Begin FErrorMessage := Parser.ErrorMessage; Result := False; - end -end; -function TExprParser.Eval(const AExpression: string): Boolean; -begin + End +End; +Function TExprParser.Eval(Const AExpression: string): Boolean; +Begin SetExpression(AExpression); Result := Eval(); -end; -procedure TExprParser.SetCaseInsensitive(const Value: Boolean); -begin +End; +Procedure TExprParser.SetCaseInsensitive(Const Value: Boolean); +Begin FCaseInsensitive := Value; -end; -procedure TExprParser.SetExpression(const Value: string); -var +End; +Procedure TExprParser.SetExpression(Const Value: string); +Var nValue : string; -begin +Begin nValue := ConvertDoubleOperators(Value); - if nValue <> FExpression then - begin + If nValue <> FExpression Then + Begin FExpression := nValue; FParser.Free; FScan.Free; FParser := TParser.Create; TParser(FParser).Parent := Self; FScan := TScan.Create; - if not TScan(FScan).Parse(FExpression) then + If not TScan(FScan).Parse(FExpression) Then FErrorMessage := TScan(FScan).ErrorMessage - else - begin + Else + Begin TParser(FParser).Scan := TScan(FScan); TParser(FParser).Parse(); - end; - end; -end; -function TExprParser.DoGetVariable(const VarName: string; var Value: Variant): Boolean; -begin + End; + End; +End; +Function TExprParser.DoGetVariable(Const VarName: string; Var Value: Variant): Boolean; +Begin Result := False; - if Assigned(FOnGetVariable) then + If Assigned(FOnGetVariable) Then Result := FOnGetVariable(Self, VarName, Value); -end; -function TExprParser.DoExecuteFunction(const FuncName: string; const Args: Variant; var ResVal: Variant): Boolean; -begin +End; +Function TExprParser.DoExecuteFunction(Const FuncName: string; Const Args: Variant; Var ResVal: Variant): Boolean; +Begin Result := False; - if Assigned(FOnExecuteFunction) then + If Assigned(FOnExecuteFunction) Then Result := FOnExecuteFunction(Self, FuncName, Args, ResVal); -end; -end. +End; +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemMath.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemMath.pas index 65953c49c..740b664e2 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemMath.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemMath.pas @@ -1,22 +1,22 @@ -unit uRESTDWMemMath; +Unit uRESTDWMemMath; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -28,8 +28,8 @@ {$ASMMode Intel} {$ENDIF} -interface -uses +Interface +Uses {$IFDEF HAS_UNITSCOPE} System.SysUtils, System.Classes, {$ELSE ~HAS_UNITSCOPE} @@ -38,9 +38,9 @@ interface uRESTDWMemBase; { CRC-16 } -type - TCrc16Table = array [0..255] of Word; -var +Type + TCrc16Table = array [0..255] Of Word; +Var // CRC16Polynom = $1021; Crc16DefaultTable: TCrc16Table = ( $0000, $1021, $2042, $3063, $4084, $50A5, $60C6, $70E7, @@ -77,7 +77,7 @@ interface $6E17, $7E36, $4E55, $5E74, $2E93, $3EB2, $0ED1, $1EF0 ); Crc16DefaultStart: Cardinal = $FFFF; -const +Const Crc16PolynomCCITT = $1021; Crc16PolynomIBM = $8005; Crc16Bits = 16; @@ -85,27 +85,27 @@ interface Crc16HighBit = $8000; NotCrc16HighBit = $7FFF; // for backward compatibility (default polynom = CCITT = $1021) -function Crc16_P(X: PJclByteArray; N: Integer; Crc: Word = 0): Word; overload; -function Crc16(const X: array of Byte; N: Integer; Crc: Word = 0): Word; overload; -function Crc16_A(const X: array of Byte; Crc: Word = 0): Word; overload; -function CheckCrc16_P(X: PJclByteArray; N: Integer; Crc: Word): Integer; overload; -function CheckCrc16(var X: array of Byte; N: Integer; Crc: Word): Integer; overload; -function CheckCrc16_A(var X: array of Byte; Crc: Word): Integer; overload; +Function Crc16_P(X: PJclByteArray; N: Integer; Crc: Word = 0): Word; overload; +Function Crc16(Const X: array Of Byte; N: Integer; Crc: Word = 0): Word; overload; +Function Crc16_A(Const X: array Of Byte; Crc: Word = 0): Word; overload; +Function CheckCrc16_P(X: PJclByteArray; N: Integer; Crc: Word): Integer; overload; +Function CheckCrc16(Var X: array Of Byte; N: Integer; Crc: Word): Integer; overload; +Function CheckCrc16_A(Var X: array Of Byte; Crc: Word): Integer; overload; // change the default polynom -procedure InitCrc16(Polynom, Start: Word); overload; +Procedure InitCrc16(Polynom, Start: Word); overload; // arbitrary polynom -function Crc16_P(const Crc16Table: TCrc16Table; X: PJclByteArray; N: Integer; Crc: Word = 0): Word; overload; -function Crc16(const Crc16Table: TCrc16Table; const X: array of Byte; N: Integer; Crc: Word = 0): Word; overload; -function Crc16_A(const Crc16Table: TCrc16Table; const X: array of Byte; Crc: Word = 0): Word; overload; -function CheckCrc16_P(const Crc16Table: TCrc16Table; X: PJclByteArray; N: Integer; Crc: Word): Integer; overload; -function CheckCrc16(const Crc16Table: TCrc16Table; var X: array of Byte; N: Integer; Crc: Word): Integer; overload; -function CheckCrc16_A(const Crc16Table: TCrc16Table; var X: array of Byte; Crc: Word): Integer; overload; +Function Crc16_P(Const Crc16Table: TCrc16Table; X: PJclByteArray; N: Integer; Crc: Word = 0): Word; overload; +Function Crc16(Const Crc16Table: TCrc16Table; Const X: array Of Byte; N: Integer; Crc: Word = 0): Word; overload; +Function Crc16_A(Const Crc16Table: TCrc16Table; Const X: array Of Byte; Crc: Word = 0): Word; overload; +Function CheckCrc16_P(Const Crc16Table: TCrc16Table; X: PJclByteArray; N: Integer; Crc: Word): Integer; overload; +Function CheckCrc16(Const Crc16Table: TCrc16Table; Var X: array Of Byte; N: Integer; Crc: Word): Integer; overload; +Function CheckCrc16_A(Const Crc16Table: TCrc16Table; Var X: array Of Byte; Crc: Word): Integer; overload; // initialize a table -procedure InitCrc16(Polynom, Start: Word; out Crc16Table: TCrc16Table); overload; +Procedure InitCrc16(Polynom, Start: Word; out Crc16Table: TCrc16Table); overload; { CRC-32 } -type - TCrc32Table = array [0..255] of Cardinal; -var +Type + TCrc32Table = array [0..255] Of Cardinal; +Var // CRC32Polynom = $04C11DB7; Crc32DefaultTable: TCrc32Table = ( $00000000, $04C11DB7, $09823B6E, $0D4326D9, $130476DC, $17C56B6B, $1A864DB2, $1E475005, @@ -142,7 +142,7 @@ procedure InitCrc16(Polynom, Start: Word; out Crc16Table: TCrc16Table); overload $AFB010B1, $AB710D06, $A6322BDF, $A2F33668, $BCB4666D, $B8757BDA, $B5365D03, $B1F740B4 ); Crc32DefaultStart: Cardinal = $FFFFFFFF; -const +Const Crc32PolynomIEEE = $04C11DB7; Crc32PolynomCastagnoli = $1EDC6F41; Crc32Koopman = $741B8CD7; @@ -151,29 +151,29 @@ procedure InitCrc16(Polynom, Start: Word; out Crc16Table: TCrc16Table); overload Crc32HighBit = $80000000; NotCrc32HighBit = $7FFFFFFF; // for backward compatibility (default polynom = IEEE = $04C11DB7) -function Crc32_P(X: PJclByteArray; N: Integer; Crc: Cardinal = 0): Cardinal; overload; -function Crc32(const X: array of Byte; N: Integer; Crc: Cardinal = 0): Cardinal; overload; -function Crc32_A(const X: array of Byte; Crc: Cardinal = 0): Cardinal; overload; -function CheckCrc32_P(X: PJclByteArray; N: Integer; Crc: Cardinal): Integer; overload; -function CheckCrc32(var X: array of Byte; N: Integer; Crc: Cardinal): Integer; overload; -function CheckCrc32_A(var X: array of Byte; Crc: Cardinal): Integer; overload; +Function Crc32_P(X: PJclByteArray; N: Integer; Crc: Cardinal = 0): Cardinal; overload; +Function Crc32(Const X: array Of Byte; N: Integer; Crc: Cardinal = 0): Cardinal; overload; +Function Crc32_A(Const X: array Of Byte; Crc: Cardinal = 0): Cardinal; overload; +Function CheckCrc32_P(X: PJclByteArray; N: Integer; Crc: Cardinal): Integer; overload; +Function CheckCrc32(Var X: array Of Byte; N: Integer; Crc: Cardinal): Integer; overload; +Function CheckCrc32_A(Var X: array Of Byte; Crc: Cardinal): Integer; overload; // change the default polynom -procedure InitCrc32(Polynom, Start: Cardinal); overload; +Procedure InitCrc32(Polynom, Start: Cardinal); overload; // arbitrary polynom -function Crc32_P(const Crc32Table: TCrc32Table; X: PJclByteArray; N: Integer; Crc: Cardinal = 0): Cardinal; overload; -function Crc32(const Crc32Table: TCrc32Table; const X: array of Byte; N: Integer; Crc: Cardinal = 0): Cardinal; overload; -function Crc32_A(const Crc32Table: TCrc32Table; const X: array of Byte; Crc: Cardinal = 0): Cardinal; overload; -function CheckCrc32_P(const Crc32Table: TCrc32Table; X: PJclByteArray; N: Integer; Crc: Cardinal): Integer; overload; -function CheckCrc32(const Crc32Table: TCrc32Table; var X: array of Byte; N: Integer; Crc: Cardinal): Integer; overload; -function CheckCrc32_A(const Crc32Table: TCrc32Table; var X: array of Byte; Crc: Cardinal): Integer; overload; +Function Crc32_P(Const Crc32Table: TCrc32Table; X: PJclByteArray; N: Integer; Crc: Cardinal = 0): Cardinal; overload; +Function Crc32(Const Crc32Table: TCrc32Table; Const X: array Of Byte; N: Integer; Crc: Cardinal = 0): Cardinal; overload; +Function Crc32_A(Const Crc32Table: TCrc32Table; Const X: array Of Byte; Crc: Cardinal = 0): Cardinal; overload; +Function CheckCrc32_P(Const Crc32Table: TCrc32Table; X: PJclByteArray; N: Integer; Crc: Cardinal): Integer; overload; +Function CheckCrc32(Const Crc32Table: TCrc32Table; Var X: array Of Byte; N: Integer; Crc: Cardinal): Integer; overload; +Function CheckCrc32_A(Const Crc32Table: TCrc32Table; Var X: array Of Byte; Crc: Cardinal): Integer; overload; // initialize a table -procedure InitCrc32(Polynom, Start: Cardinal; out Crc32Table: TCrc32Table); overload; +Procedure InitCrc32(Polynom, Start: Cardinal; out Crc32Table: TCrc32Table); overload; -implementation +Implementation {$IFDEF DELPHI64_TEMPORARY} {$DEFINE USE_MATH_UNIT} {$ENDIF DELPHI64_TEMPORARY} -uses +Uses {$IFDEF HAS_UNITSCOPE} {$IFDEF MSWINDOWS} {$IFNDEF FPC} @@ -193,329 +193,329 @@ implementation uRESTDWMemResources; // CRC 16 -function Crc16Corr(const Crc16Table: TCrc16Table; Crc: Word; N: Integer): Integer; -var +Function Crc16Corr(Const Crc16Table: TCrc16Table; Crc: Word; N: Integer): Integer; +Var I: Integer; // CrcX : Cardinal; -begin +Begin // calculate Syndrome // CrcX := CrC; - for I := 1 to Crc16Bytes do + For I := 1 To Crc16Bytes Do // a 16 bit value shr 8 is a Byte, explictit type conversion to Byte adds an ASM instruction Crc := Crc16Table[Crc shr (CRC16Bits - 8)] xor Word(Crc shl 8); I := -1; - repeat + Repeat Inc(I); - if (Crc and 1) <> 0 then + If (Crc and 1) <> 0 Then Crc := ((Crc xor Crc16Table[1]) shr 1) or Crc16HighBit // Crc16Table[1] = Crc16Polynom - else + Else Crc := (Crc shr 1) and NotCrc16HighBit; - until (Crc = Crc16HighBit) or (I = (N + Crc16Bytes) * 8); - if Crc <> Crc16HighBit then + Until (Crc = Crc16HighBit) or (I = (N + Crc16Bytes) * 8); + If Crc <> Crc16HighBit Then Result := -1000 // not correctable - else + Else // I = No. of single faulty bit // (high bit first, // starting from lowest with CRC bits) Result := I - Crc16Bits; // Result < 0 faulty CRC-bit // Result >= 0 No. of faulty data bit -end; -function Crc16_P(const Crc16Table: TCrc16Table; X: PJclByteArray; N: Integer; Crc: Word): Word; -var +End; +Function Crc16_P(Const Crc16Table: TCrc16Table; X: PJclByteArray; N: Integer; Crc: Word): Word; +Var I: Integer; -begin +Begin Result := Crc16DefaultStart; - for I := 0 to N - 1 do // The CRC Bytes are located at the end of the information + For I := 0 To N - 1 Do // The CRC Bytes are located at the end of the information // a 16 bit value shr 8 is a Byte, explictit type conversion to Byte adds an ASM instruction Result := Crc16Table[Result shr (CRC16Bits - 8)] xor Word((Result shl 8)) xor X[I]; - for I := 0 to Crc16Bytes - 1 do - begin + For I := 0 To Crc16Bytes - 1 Do + Begin // a 16 bit value shr 8 is a Byte, explictit type conversion to Byte adds an ASM instruction Result := Crc16Table[Result shr (CRC16Bits-8)] xor Word((Result shl 8)) xor (Crc shr (CRC16Bits-8)); Crc := Word(Crc shl 8); - end; -end; -function Crc16_P(X: PJclByteArray; N: Integer; Crc: Word): Word; -begin + End; +End; +Function Crc16_P(X: PJclByteArray; N: Integer; Crc: Word): Word; +Begin Result := Crc16_P(Crc16DefaultTable, X, N, Crc); -end; -function CheckCrc16_P(const Crc16Table: TCrc16Table; X: PJclByteArray; N: Integer; Crc: Word): Integer; +End; +Function CheckCrc16_P(Const Crc16Table: TCrc16Table; X: PJclByteArray; N: Integer; Crc: Word): Integer; // checks and corrects a single bit in up to 2^15-16 Bit -> 2^12-2 = 4094 Byte -var +Var I, J: Integer; C: Byte; -begin +Begin Crc := Crc16_P(Crc16Table, X, N, Crc); - if Crc = 0 then + If Crc = 0 Then Result := 0 // No CRC-error - else - begin + Else + Begin J := Crc16Corr(Crc16Table, Crc, N); - if J < -(Crc16Bytes * 8 + 1) then + If J < -(Crc16Bytes * 8 + 1) Then Result := -1 // non-correctable error (more than one wrong bit) - else - begin - if J < 0 then + Else + Begin + If J < 0 Then Result := 1 // one faulty Bit in CRC itself - else - begin // Bit J is faulty + Else + Begin // Bit J is faulty I := J and 7; // I <= 7 (faulty Bit in Byte) C := 1 shl I; // C <= 128 I := J shr 3; // I: Index of faulty Byte X[N - 1 - I] := X[N - 1 - I] xor C; // correct faulty bit Result := 1; // Correctable error - end; - end; - end; -end; -function CheckCrc16_P(X: PJclByteArray; N: Integer; Crc: Word): Integer; -begin + End; + End; + End; +End; +Function CheckCrc16_P(X: PJclByteArray; N: Integer; Crc: Word): Integer; +Begin Result := CheckCrc16_P(Crc16DefaultTable, X, N, Crc); -end; -function Crc16(const Crc16Table: TCrc16Table; const X: array of Byte; N: Integer; Crc: Word): Word; -begin +End; +Function Crc16(Const Crc16Table: TCrc16Table; Const X: array Of Byte; N: Integer; Crc: Word): Word; +Begin Result := Crc16_P(Crc16Table, @X, N, Crc); -end; -function Crc16(const X: array of Byte; N: Integer; Crc: Word): Word; -begin +End; +Function Crc16(Const X: array Of Byte; N: Integer; Crc: Word): Word; +Begin Result := Crc16_P(Crc16DefaultTable, @X, N, Crc); -end; -function CheckCrc16(const Crc16Table: TCrc16Table; var X: array of Byte; N: Integer; Crc: Word): Integer; -begin +End; +Function CheckCrc16(Const Crc16Table: TCrc16Table; Var X: array Of Byte; N: Integer; Crc: Word): Integer; +Begin Result := CheckCRC16_P(Crc16Table, @X, N, CRC); -end; -function CheckCrc16(var X: array of Byte; N: Integer; Crc: Word): Integer; -begin +End; +Function CheckCrc16(Var X: array Of Byte; N: Integer; Crc: Word): Integer; +Begin Result := CheckCRC16_P(Crc16DefaultTable, @X, N, CRC); -end; -function Crc16_A(const Crc16Table: TCrc16Table; const X: array of Byte; Crc: Word): Word; -begin +End; +Function Crc16_A(Const Crc16Table: TCrc16Table; Const X: array Of Byte; Crc: Word): Word; +Begin Result := Crc16_P(Crc16Table, @X, Length(X), Crc); -end; -function Crc16_A(const X: array of Byte; Crc: Word): Word; -begin +End; +Function Crc16_A(Const X: array Of Byte; Crc: Word): Word; +Begin Result := Crc16_P(Crc16DefaultTable, @X, Length(X), Crc); -end; -function CheckCrc16_A(const Crc16Table: TCrc16Table; var X: array of Byte; Crc: Word): Integer; -begin +End; +Function CheckCrc16_A(Const Crc16Table: TCrc16Table; Var X: array Of Byte; Crc: Word): Integer; +Begin Result := CheckCrc16_P(Crc16Table, @X, Length(X), Crc); -end; -function CheckCrc16_A(var X: array of Byte; Crc: Word): Integer; -begin +End; +Function CheckCrc16_A(Var X: array Of Byte; Crc: Word): Integer; +Begin Result := CheckCrc16_P(Crc16DefaultTable, @X, Length(X), Crc); -end; +End; // The CRC Table can be generated like this: // const Crc16Start0 = 0; !! -function Crc16_Bitwise(const X: array of Byte; N: Integer; Crc: Word; Polynom: Word): Word; -const +Function Crc16_Bitwise(Const X: array Of Byte; N: Integer; Crc: Word; Polynom: Word): Word; +Const Crc16Start0 = 0; //Generating the table -var +Var I, J: Integer; Sr, SrHighBit: Word; B: Byte; -begin +Begin Sr := Crc16Start0; SrHighBit := 0; - for I := 0 to N - 1 + Crc16Bytes do - begin - if I >= N then - begin + For I := 0 To N - 1 + Crc16Bytes Do + Begin + If I >= N Then + Begin B := Crc shr (Crc16Bits - 8); Crc := Crc shl 8; - end - else + End + Else B := X[I]; - for J := 1 to 8 do - begin - if SrHighBit <> 0 then + For J := 1 To 8 Do + Begin + If SrHighBit <> 0 Then Sr := Sr xor Polynom; SrHighBit := Sr and Crc16HighBit; Sr := (Word (Sr shl 1)) or ((B shr 7) and 1); B := Byte(B shl 1); - end; - end; - if SrHighBit <> 0 then + End; + End; + If SrHighBit <> 0 Then Sr := Sr xor Polynom; Result := Sr; -end; -procedure InitCrc16(Polynom, Start: Word; out Crc16Table: TCrc16Table); -var - X: array [0..0] of Byte; +End; +Procedure InitCrc16(Polynom, Start: Word; out Crc16Table: TCrc16Table); +Var + X: array [0..0] Of Byte; I: Integer; -begin - for I := 0 to 255 do - begin +Begin + For I := 0 To 255 Do + Begin X[0] := I; Crc16Table[I] := Crc16_Bitwise(X, 1, 0, Polynom); { only with crcstart=0 !!!!} - end; + End; Crc16DefaultStart := Start; -end; -procedure InitCrc16(Polynom, Start: Word); -begin +End; +Procedure InitCrc16(Polynom, Start: Word); +Begin InitCrc16(Polynom, Start, Crc16DefaultTable); -end; +End; // CRC 32 -function Crc32Corr(const Crc32Table: TCrc32Table; Crc: Cardinal; N: Integer): Integer; -var +Function Crc32Corr(Const Crc32Table: TCrc32Table; Crc: Cardinal; N: Integer): Integer; +Var I: Integer; -begin +Begin // calculate Syndrome - for I := 1 to Crc32Bytes do + For I := 1 To Crc32Bytes Do Crc := Crc32Table[Crc shr (CRC32Bits - 8)] xor (Crc shl 8); I := -1; - repeat + Repeat Inc(I); - if (Crc and 1) <> 0 then + If (Crc and 1) <> 0 Then Crc := ((Crc xor Crc32Table[1]) shr 1) or Crc32HighBit // Crc32Table[1] = Crc32Polynom - else + Else Crc := (Crc shr 1) and NotCrc32HighBit; - until (Crc = Crc32HighBit) or (I = (N + Crc32Bytes) * 8); - if Crc <> Crc32HighBit then + Until (Crc = Crc32HighBit) or (I = (N + Crc32Bytes) * 8); + If Crc <> Crc32HighBit Then Result := -1000 // not correctable - else + Else // I = No. of single faulty bit // (high bit first, // starting from lowest with CRC bits) Result := I - Crc32Bits; // Result < 0 faulty CRC-bit // Result >= 0 No. of faulty data bit -end; -function Crc32_P(const Crc32Table: TCrc32Table; X: PJclByteArray; N: Integer; Crc: Cardinal): Cardinal; -var +End; +Function Crc32_P(Const Crc32Table: TCrc32Table; X: PJclByteArray; N: Integer; Crc: Cardinal): Cardinal; +Var I: Integer; -begin +Begin Result := Crc32DefaultStart; - for I := 0 to N - 1 do // The CRC Bytes are located at the end of the information + For I := 0 To N - 1 Do // The CRC Bytes are located at the end of the information // a 32 bit value shr 24 is a Byte, explictit type conversion to Byte adds an ASM instruction Result := Crc32Table[Result shr (CRC32Bits-8)] xor (Result shl 8) xor X[I]; - for I := 0 to Crc32Bytes - 1 do - begin + For I := 0 To Crc32Bytes - 1 Do + Begin // a 32 bit value shr 24 is a Byte, explictit type conversion to Byte adds an ASM instruction Result := Crc32Table[Result shr (CRC32Bits-8)] xor (Result shl 8) xor (Crc shr (CRC32Bits-8)); Crc := Crc shl 8; - end; -end; -function Crc32_P(X: PJclByteArray; N: Integer; Crc: Cardinal): Cardinal; -begin + End; +End; +Function Crc32_P(X: PJclByteArray; N: Integer; Crc: Cardinal): Cardinal; +Begin Result := Crc32_P(Crc32DefaultTable, X, N, Crc); -end; -function CheckCrc32_P(const Crc32Table: TCrc32Table; X: PJclByteArray; N: Integer; Crc: Cardinal): Integer; +End; +Function CheckCrc32_P(Const Crc32Table: TCrc32Table; X: PJclByteArray; N: Integer; Crc: Cardinal): Integer; // checks and corrects a single bit in up to 2^31-32 Bit -> 2^28-4 = 268435452 Byte -var +Var I, J: Integer; C: Byte; -begin +Begin Crc := Crc32_P(Crc32Table, X, N, Crc); - if Crc = 0 then + If Crc = 0 Then Result := 0 // No CRC-error - else - begin + Else + Begin J := Crc32Corr(Crc32Table, Crc, N); - if J < -(Crc32Bytes * 8 + 1) then + If J < -(Crc32Bytes * 8 + 1) Then Result := -1 // non-correctable error (more than one wrong bit) - else - begin - if J < 0 then + Else + Begin + If J < 0 Then Result := 1 // one faulty Bit in CRC itself - else - begin // Bit J is faulty + Else + Begin // Bit J is faulty I := J and 7; // I <= 7 (faulty Bit in Byte) C := 1 shl I; // C <= 128 I := J shr 3; // I: Index of faulty Byte X[N - 1 - I] := X[N - 1 - I] xor C; // correct faulty bit Result := 1; // Correctable error - end; - end; - end; -end; -function CheckCrc32_P(X: PJclByteArray; N: Integer; Crc: Cardinal): Integer; -begin + End; + End; + End; +End; +Function CheckCrc32_P(X: PJclByteArray; N: Integer; Crc: Cardinal): Integer; +Begin Result := CheckCrc32_P(Crc32DefaultTable, X, N, Crc); -end; -function Crc32(const Crc32Table: TCrc32Table; const X: array of Byte; N: Integer; Crc: Cardinal): Cardinal; -begin +End; +Function Crc32(Const Crc32Table: TCrc32Table; Const X: array Of Byte; N: Integer; Crc: Cardinal): Cardinal; +Begin Result := Crc32_P(Crc32Table, @X, N, Crc); -end; -function Crc32(const X: array of Byte; N: Integer; Crc: Cardinal): Cardinal; -begin +End; +Function Crc32(Const X: array Of Byte; N: Integer; Crc: Cardinal): Cardinal; +Begin Result := Crc32_P(Crc32DefaultTable, @X, N, Crc); -end; -function CheckCrc32(const Crc32Table: TCrc32Table; var X: array of Byte; N: Integer; Crc: Cardinal): Integer; -begin +End; +Function CheckCrc32(Const Crc32Table: TCrc32Table; Var X: array Of Byte; N: Integer; Crc: Cardinal): Integer; +Begin Result := CheckCRC32_P(Crc32Table, @X, N, CRC); -end; -function CheckCrc32(var X: array of Byte; N: Integer; Crc: Cardinal): Integer; -begin +End; +Function CheckCrc32(Var X: array Of Byte; N: Integer; Crc: Cardinal): Integer; +Begin Result := CheckCRC32_P(Crc32DefaultTable, @X, N, CRC); -end; -function Crc32_A(const Crc32Table: TCrc32Table; const X: array of Byte; Crc: Cardinal): Cardinal; -begin +End; +Function Crc32_A(Const Crc32Table: TCrc32Table; Const X: array Of Byte; Crc: Cardinal): Cardinal; +Begin Result := Crc32_P(Crc32Table, @X, Length(X), Crc); -end; -function Crc32_A(const X: array of Byte; Crc: Cardinal): Cardinal; -begin +End; +Function Crc32_A(Const X: array Of Byte; Crc: Cardinal): Cardinal; +Begin Result := Crc32_P(Crc32DefaultTable, @X, Length(X), Crc); -end; -function CheckCrc32_A(const Crc32Table: TCrc32Table; var X: array of Byte; Crc: Cardinal): Integer; -begin +End; +Function CheckCrc32_A(Const Crc32Table: TCrc32Table; Var X: array Of Byte; Crc: Cardinal): Integer; +Begin Result := CheckCrc32_P(Crc32Table, @X, Length(X), Crc); -end; -function CheckCrc32_A(var X: array of Byte; Crc: Cardinal): Integer; -begin +End; +Function CheckCrc32_A(Var X: array Of Byte; Crc: Cardinal): Integer; +Begin Result := CheckCrc32_P(Crc32DefaultTable, @X, Length(X), Crc); -end; +End; // The CRC Table can be generated like this: // const Crc32Start0 = 0; !! -function Crc32_Bitwise(const X: array of Byte; N: Integer; Crc: Cardinal; Polynom: Cardinal) : Cardinal; -const +Function Crc32_Bitwise(Const X: array Of Byte; N: Integer; Crc: Cardinal; Polynom: Cardinal) : Cardinal; +Const Crc32Start0 = 0; //Generating the table -var +Var I, J: Integer; Sr, SrHighBit: Cardinal; B: Byte; -begin +Begin Sr := Crc32Start0; SrHighBit := 0; - for I := 0 to N - 1 + Crc32Bytes do - begin - if I >= N then - begin + For I := 0 To N - 1 + Crc32Bytes Do + Begin + If I >= N Then + Begin B := Crc shr (Crc32Bits - 8); Crc := Crc shl 8; - end - else + End + Else B := X[I]; - for J := 1 to 8 do - begin - if SrHighBit <> 0 then + For J := 1 To 8 Do + Begin + If SrHighBit <> 0 Then Sr := Sr xor Polynom; SrHighBit := Sr and Crc32HighBit; Sr := (Sr shl 1) or ((B shr 7) and 1); B := Byte(B shl 1); - end - end; - if SrHighBit <> 0 then + End + End; + If SrHighBit <> 0 Then Sr := Sr xor Polynom; Result := Sr; -end; -procedure InitCrc32(Polynom, Start: Cardinal; out Crc32Table: TCrc32Table); -var - X: array [0..0] of Byte; +End; +Procedure InitCrc32(Polynom, Start: Cardinal; out Crc32Table: TCrc32Table); +Var + X: array [0..0] Of Byte; I: Integer; -begin - for I := 0 to 255 do - begin +Begin + For I := 0 To 255 Do + Begin X[0] := I; Crc32Table[I] := Crc32_Bitwise(X, 1, 0, Polynom); - end; + End; Crc32DefaultStart := Start; -end; -procedure InitCrc32(Polynom, Start: Cardinal); -begin +End; +Procedure InitCrc32(Polynom, Start: Cardinal); +Begin InitCrc32(Polynom, Start, Crc32DefaultTable); -end; +End; -end. +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemResources.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemResources.pas index 5f2dc7e2e..94d2f03c2 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemResources.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemResources.pas @@ -1,29 +1,29 @@ -unit uRESTDWMemResources; +Unit uRESTDWMemResources; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. Roniery - Devel. } -interface +Interface //=== used in several files ================================================== resourcestring RsENoCharset = 'No matching charset'; @@ -1476,8 +1476,8 @@ interface //=== JvgXMLSerializer.pas =================================================== resourcestring { RUSSIAN - RsOpenXMLTagNotFound = 'Îòêðûâàþùèé òåã íå íàéäåí: <%s>'; - RsCloseXMLTagNotFound = 'Çàêðûâàþùèé òåã íå íàéäåí: '; + RsOpenXMLTagNotFound = ' : <%s>'; + RsCloseXMLTagNotFound = ' : '; RsUncknownProperty = 'Uncknown property: %s' } RsOpenXMLTagNotFound = 'Open tag not found: <%s>'; @@ -2607,7 +2607,7 @@ interface SExprBadCompare = 'Relational operators require a field and a constant'; } {$IFDEF UNITVERSIONING} -const +Const UnitVersioning: TUnitVersionInfo = ( RCSfile: '$URL$'; Revision: '$Revision$'; @@ -2615,11 +2615,11 @@ interface LogPath: 'JVCL\run' ); {$ENDIF UNITVERSIONING} -implementation +Implementation {$IFDEF UNITVERSIONING} - initialization - RegisterUnitVersion(HInstance, UnitVersioning); - finalization - UnregisterUnitVersion(HInstance); +Initialization + RegisterUnitVersion(HInstance, UnitVersioning); +Finalization + UnregisterUnitVersion(HInstance); {$ENDIF UNITVERSIONING} -end. +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemStreams.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemStreams.pas index 9fcd6fd25..189e2c352 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemStreams.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemStreams.pas @@ -1,20 +1,20 @@ -unit uRESTDWMemStreams; -{$I ..\..\Includes\uRESTDW.inc} +Unit uRESTDWMemStreams; +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -26,8 +26,8 @@ {$ASMMode Intel} {$ENDIF} -interface -uses +Interface +Uses {$IFDEF UNITVERSIONING} JclUnitVersioning, {$ENDIF UNITVERSIONING} @@ -50,41 +50,41 @@ interface uRESTDWMemBase, uRESTDWMemMath, uRESTDWMemStringConversions, uRESTDWPrototypes; -const +Const StreamDefaultBufferSize = 4096; -type - TObjectList = class(Tlist); - EJclStreamError = class(EJclError); +Type + TObjectList = Class(Tlist); + EJclStreamError = Class(EJclError); // abstraction layer to support Delphi 5 and C++Builder 5 streams // 64 bit version of overloaded functions are introduced - TJclStream = class(TStream) - protected - procedure SetSize(NewSize: Longint); overload; override; - procedure SetSize(const NewSize: Int64); overload; override; - public - function Seek(Offset: Longint; Origin: Word): Longint; overload; override; - procedure LoadFromStream(Source: TStream; BufferSize: Longint = StreamDefaultBufferSize); virtual; - procedure LoadFromFile(const FileName: TFileName; BufferSize: Longint = StreamDefaultBufferSize); virtual; - procedure SaveToStream(Dest: TStream; BufferSize: Longint = StreamDefaultBufferSize); virtual; - procedure SaveToFile(const FileName: TFileName; BufferSize: Longint = StreamDefaultBufferSize); virtual; - end; + TJclStream = Class(TStream) + Protected + Procedure SetSize(NewSize: Longint); overload; override; + Procedure SetSize(Const NewSize: Int64); overload; override; + Public + Function Seek(Offset: Longint; Origin: Word): Longint; overload; override; + Procedure LoadFromStream(Source: TStream; BufferSize: Longint = StreamDefaultBufferSize); virtual; + Procedure LoadFromFile(Const FileName: TFileName; BufferSize: Longint = StreamDefaultBufferSize); virtual; + Procedure SaveToStream(Dest: TStream; BufferSize: Longint = StreamDefaultBufferSize); virtual; + Procedure SaveToFile(Const FileName: TFileName; BufferSize: Longint = StreamDefaultBufferSize); virtual; + End; //=== VCL stream replacements === - TJclHandleStream = class(TJclStream) - private + TJclHandleStream = Class(TJclStream) + Private FHandle: THandle; - protected - procedure SetSize(const NewSize: Int64); override; - public - constructor Create(AHandle: THandle); - function Read(var Buffer; Count: Longint): Longint; override; - function Write(const Buffer; Count: Longint): Longint; override; + Protected + Procedure SetSize(Const NewSize: Int64); override; + Public + Constructor Create(AHandle: THandle); + Function Read(Var Buffer; Count: Longint): Longint; override; + Function Write(Const Buffer; Count: Longint): Longint; override; property Handle: THandle read FHandle; - end; - TJclFileStream = class(TJclHandleStream) - public - constructor Create(const FileName: TFileName; Mode: Word; Rights: Cardinal = $666); - destructor Destroy; override; - end; + End; + TJclFileStream = Class(TJclHandleStream) + Public + Constructor Create(Const FileName: TFileName; Mode: Word; Rights: Cardinal = $666); + Destructor Destroy; override; + End; { TJclCustomMemoryStream = class(TJclStream) end; @@ -96,290 +96,290 @@ TJclResourceStream = class(TJclCustomMemoryStream) end; } //=== new stream ideas === - TJclEmptyStream = class(TJclStream) - protected - procedure SetSize(const NewSize: Int64); override; - public - function Read(var Buffer; Count: Longint): Longint; override; - function Write(const Buffer; Count: Longint): Longint; override; - function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; - end; - TJclMultiplexStream = class(TJclStream) - private + TJclEmptyStream = Class(TJclStream) + Protected + Procedure SetSize(Const NewSize: Int64); override; + Public + Function Read(Var Buffer; Count: Longint): Longint; override; + Function Write(Const Buffer; Count: Longint): Longint; override; + Function Seek(Const Offset: Int64; Origin: TSeekOrigin): Int64; override; + End; + TJclMultiplexStream = Class(TJclStream) + Private FStreams: TList; FReadStreamIndex: Integer; - function GetStream(Index: Integer): TStream; - function GetCount: Integer; - procedure SetStream(Index: Integer; const Value: TStream); - function GetReadStream: TStream; - procedure SetReadStream(const Value: TStream); - procedure SetReadStreamIndex(const Value: Integer); - protected - procedure SetSize(const NewSize: Int64); override; - public - constructor Create; - destructor Destroy; override; - function Read(var Buffer; Count: Longint): Longint; override; - function Write(const Buffer; Count: Longint): Longint; override; - function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; - function Add(NewStream: TStream): Integer; - procedure Clear; - function Remove(AStream: TStream): Integer; - procedure Delete(const Index: Integer); + Function GetStream(Index: Integer): TStream; + Function GetCount: Integer; + Procedure SetStream(Index: Integer; Const Value: TStream); + Function GetReadStream: TStream; + Procedure SetReadStream(Const Value: TStream); + Procedure SetReadStreamIndex(Const Value: Integer); + Protected + Procedure SetSize(Const NewSize: Int64); override; + Public + Constructor Create; + Destructor Destroy; override; + Function Read(Var Buffer; Count: Longint): Longint; override; + Function Write(Const Buffer; Count: Longint): Longint; override; + Function Seek(Const Offset: Int64; Origin: TSeekOrigin): Int64; override; + Function Add(NewStream: TStream): Integer; + Procedure Clear; + Function Remove(AStream: TStream): Integer; + Procedure Delete(Const Index: Integer); property Streams[Index: Integer]: TStream read GetStream write SetStream; property ReadStreamIndex: Integer read FReadStreamIndex write SetReadStreamIndex; property ReadStream: TStream read GetReadStream write SetReadStream; property Count: Integer read GetCount; - end; - TJclStreamDecorator = class(TJclStream) - private + End; + TJclStreamDecorator = Class(TJclStream) + Private FAfterStreamChange: TNotifyEvent; FBeforeStreamChange: TNotifyEvent; FOwnsStream: Boolean; FStream: TStream; - procedure SetStream(Value: TStream); - protected - procedure DoAfterStreamChange; virtual; - procedure DoBeforeStreamChange; virtual; - procedure SetSize(const NewSize: Int64); override; - public - constructor Create(AStream: TStream; AOwnsStream: Boolean = False); - destructor Destroy; override; - function Read(var Buffer; Count: Longint): Longint; override; - function Write(const Buffer; Count: Longint): Longint; override; - function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; + Procedure SetStream(Value: TStream); + Protected + Procedure DoAfterStreamChange; virtual; + Procedure DoBeforeStreamChange; virtual; + Procedure SetSize(Const NewSize: Int64); override; + Public + Constructor Create(AStream: TStream; AOwnsStream: Boolean = False); + Destructor Destroy; override; + Function Read(Var Buffer; Count: Longint): Longint; override; + Function Write(Const Buffer; Count: Longint): Longint; override; + Function Seek(Const Offset: Int64; Origin: TSeekOrigin): Int64; override; property AfterStreamChange: TNotifyEvent read FAfterStreamChange write FAfterStreamChange; property BeforeStreamChange: TNotifyEvent read FBeforeStreamChange write FBeforeStreamChange; property OwnsStream: Boolean read FOwnsStream write FOwnsStream; property Stream: TStream read FStream write SetStream; - end; - TJclBufferedStream = class(TJclStreamDecorator) - protected - FBuffer: array of Byte; + End; + TJclBufferedStream = Class(TJclStreamDecorator) + Protected + FBuffer: array Of Byte; FBufferCurrentSize: Longint; FBufferMaxModifiedPos: Longint; FBufferSize: Longint; FBufferStart: Int64; // position of the first byte of the buffer in stream FPosition: Int64; // current position in stream - function BufferHit: Boolean; - function GetCalcedSize: Int64; virtual; - function LoadBuffer: Boolean; virtual; - protected - procedure DoAfterStreamChange; override; - procedure DoBeforeStreamChange; override; - procedure SetSize(const NewSize: Int64); override; - public - constructor Create(AStream: TStream; AOwnsStream: Boolean = False); - destructor Destroy; override; - procedure Flush; virtual; - function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; + Function BufferHit: Boolean; + Function GetCalcedSize: Int64; virtual; + Function LoadBuffer: Boolean; virtual; + Protected + Procedure DoAfterStreamChange; override; + Procedure DoBeforeStreamChange; override; + Procedure SetSize(Const NewSize: Int64); override; + Public + Constructor Create(AStream: TStream; AOwnsStream: Boolean = False); + Destructor Destroy; override; + Procedure Flush; virtual; + Function Seek(Const Offset: Int64; Origin: TSeekOrigin): Int64; override; property BufferSize: Longint read FBufferSize write FBufferSize; - end; - TStreamNotifyEvent = procedure(Sender: TObject; Position: Int64; Size: Int64) of object; - TJclEventStream = class(TJclStreamDecorator) - private + End; + TStreamNotifyEvent = Procedure(Sender: TObject; Position: Int64; Size: Int64) Of object; + TJclEventStream = Class(TJclStreamDecorator) + Private FNotification: TStreamNotifyEvent; - procedure DoNotification; - protected - procedure DoBeforeStreamChange; override; - procedure DoAfterStreamChange; override; - procedure SetSize(const NewSize: Int64); override; - public - constructor Create(AStream: TStream; ANotification: TStreamNotifyEvent = nil; + Procedure DoNotification; + Protected + Procedure DoBeforeStreamChange; override; + Procedure DoAfterStreamChange; override; + Procedure SetSize(Const NewSize: Int64); override; + Public + Constructor Create(AStream: TStream; ANotification: TStreamNotifyEvent = nil; AOwnsStream: Boolean = False); - function Read(var Buffer; Count: Longint): Longint; override; - function Write(const Buffer; Count: Longint): Longint; override; - function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; + Function Read(Var Buffer; Count: Longint): Longint; override; + Function Write(Const Buffer; Count: Longint): Longint; override; + Function Seek(Const Offset: Int64; Origin: TSeekOrigin): Int64; override; property OnNotification: TStreamNotifyEvent read FNotification write FNotification; - end; - TJclEasyStream = class(TJclStreamDecorator) - public - function IsEqual(Stream: TStream): Boolean; - function ReadBoolean: Boolean; - function ReadChar: Char; - function ReadAnsiChar: DWChar; - function ReadWideChar: WideChar; - function ReadByte: Byte; - function ReadCurrency: Currency; - function ReadDateTime: TDateTime; - function ReadExtended: Extended; - function ReadDouble: Double; - function ReadInt64: Int64; - function ReadInteger: Integer; - function ReadCString: string; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} - function ReadCAnsiString: DWString; - function ReadCWideString: DWWideString; - function ReadShortString: string; - function ReadSingle: Single; - function ReadSizedString: string; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} - function ReadSizedAnsiString: DWString; - function ReadSizedWideString: DWWideString; - procedure WriteBoolean(Value: Boolean); - procedure WriteChar(Value: Char); - procedure WriteAnsiChar(Value: DWChar); - procedure WriteWideChar(Value: WideChar); - procedure WriteByte(Value: Byte); - procedure WriteCurrency(const Value: Currency); - procedure WriteDateTime(const Value: TDateTime); - procedure WriteExtended(const Value: Extended); - procedure WriteDouble(const Value: Double); - procedure WriteInt64(Value: Int64); overload; - procedure WriteInteger(Value: Integer); overload; - procedure WriteCString(const Value: string); {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} - procedure WriteCAnsiString(const Value: DWString); - procedure WriteCWideString(const Value: DWWideString); + End; + TJclEasyStream = Class(TJclStreamDecorator) + Public + Function IsEqual(Stream: TStream): Boolean; + Function ReadBoolean: Boolean; + Function ReadChar: Char; + Function ReadAnsiChar: DWChar; + Function ReadWideChar: WideChar; + Function ReadByte: Byte; + Function ReadCurrency: Currency; + Function ReadDateTime: TDateTime; + Function ReadExtended: Extended; + Function ReadDouble: Double; + Function ReadInt64: Int64; + Function ReadInteger: Integer; + Function ReadCString: string; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} + Function ReadCAnsiString: DWString; + Function ReadCWideString: DWWideString; + Function ReadShortString: string; + Function ReadSingle: Single; + Function ReadSizedString: string; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} + Function ReadSizedAnsiString: DWString; + Function ReadSizedWideString: DWWideString; + Procedure WriteBoolean(Value: Boolean); + Procedure WriteChar(Value: Char); + Procedure WriteAnsiChar(Value: DWChar); + Procedure WriteWideChar(Value: WideChar); + Procedure WriteByte(Value: Byte); + Procedure WriteCurrency(Const Value: Currency); + Procedure WriteDateTime(Const Value: TDateTime); + Procedure WriteExtended(Const Value: Extended); + Procedure WriteDouble(Const Value: Double); + Procedure WriteInt64(Value: Int64); overload; + Procedure WriteInteger(Value: Integer); overload; + Procedure WriteCString(Const Value: string); {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} + Procedure WriteCAnsiString(Const Value: DWString); + Procedure WriteCWideString(Const Value: DWWideString); // use WriteCString - procedure WriteSingle(const Value: Single); - procedure WriteSizedString(const Value: string); {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} - procedure WriteSizedAnsiString(const Value: DWString); - procedure WriteSizedWideString(const Value: DWWideString); - end; - TJclScopedStream = class(TJclStream) - private + Procedure WriteSingle(Const Value: Single); + Procedure WriteSizedString(Const Value: string); {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} + Procedure WriteSizedAnsiString(Const Value: DWString); + Procedure WriteSizedWideString(Const Value: DWWideString); + End; + TJclScopedStream = Class(TJclStream) + Private FParentStream: TStream; FStartPos: Int64; FCurrentPos: Int64; FMaxSize: Int64; - protected - procedure SetSize(const NewSize: Int64); override; - public + Protected + Procedure SetSize(Const NewSize: Int64); override; + Public // scopedstream starting at the current position of the ParentStream // if MaxSize is positive or null, read and write operations cannot overrun this size or the ParentStream limitation // if MaxSize is negative, read and write operations are unlimited (up to the ParentStream limitation) - constructor Create(AParentStream: TStream; const AMaxSize: Int64 = -1); overload; - constructor Create(AParentStream: TStream; const AStartPos, AMaxSize: Int64); overload; - function Read(var Buffer; Count: Longint): Longint; override; - function Write(const Buffer; Count: Longint): Longint; override; - function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; + Constructor Create(AParentStream: TStream; Const AMaxSize: Int64 = -1); overload; + Constructor Create(AParentStream: TStream; Const AStartPos, AMaxSize: Int64); overload; + Function Read(Var Buffer; Count: Longint): Longint; override; + Function Write(Const Buffer; Count: Longint): Longint; override; + Function Seek(Const Offset: Int64; Origin: TSeekOrigin): Int64; override; property ParentStream: TStream read FParentStream; property StartPos: Int64 read FStartPos; property MaxSize: Int64 read FMaxSize write FMaxSize; - end; - TJclStreamSeekEvent = function(Sender: TObject; const Offset: Int64; - Origin: TSeekOrigin): Int64 of object; - TJclStreamReadEvent = function(Sender: TObject; var Buffer; Count: Longint): Longint of object; - TJclStreamWriteEvent = function(Sender: TObject; const Buffer;Count: Longint): Longint of object; - TJclStreamSizeEvent = procedure(Sender: TObject; const NewSize: Int64) of object; - TJclDelegatedStream = class(TJclStream) - private + End; + TJclStreamSeekEvent = Function(Sender: TObject; Const Offset: Int64; + Origin: TSeekOrigin): Int64 Of object; + TJclStreamReadEvent = Function(Sender: TObject; Var Buffer; Count: Longint): Longint Of object; + TJclStreamWriteEvent = Function(Sender: TObject; Const Buffer;Count: Longint): Longint Of object; + TJclStreamSizeEvent = Procedure(Sender: TObject; Const NewSize: Int64) Of object; + TJclDelegatedStream = Class(TJclStream) + Private FOnSeek: TJclStreamSeekEvent; FOnRead: TJclStreamReadEvent; FOnWrite: TJclStreamWriteEvent; FOnSize: TJclStreamSizeEvent; - protected - procedure SetSize(const NewSize: Int64); override; - public - function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; - function Read(var Buffer; Count: Longint): Longint; override; - function Write(const Buffer; Count: Longint): Longint; override; + Protected + Procedure SetSize(Const NewSize: Int64); override; + Public + Function Seek(Const Offset: Int64; Origin: TSeekOrigin): Int64; override; + Function Read(Var Buffer; Count: Longint): Longint; override; + Function Write(Const Buffer; Count: Longint): Longint; override; property OnSeek: TJclStreamSeekEvent read FOnSeek write FOnSeek; property OnRead: TJclStreamReadEvent read FOnRead write FOnRead; property OnWrite: TJclStreamWriteEvent read FOnWrite write FOnWrite; property OnSize: TJclStreamSizeEvent read FOnSize write FOnSize; - end; + End; // ancestor classes for streams with checksums and encrypted streams // data are stored in sectors: each BufferSize-d buffer is followed by FSectorOverHead bytes // containing the checksum. In case of an encrypted stream, there is no byte // but sector is encrypted // reusing some code from TJclBufferedStream - TJclSectoredStream = class(TJclBufferedStream) - protected + TJclSectoredStream = Class(TJclBufferedStream) + Protected FSectorOverHead: Longint; - function FlatToSectored(const Position: Int64): Int64; - function SectoredToFlat(const Position: Int64): Int64; - function GetCalcedSize: Int64; override; - function LoadBuffer: Boolean; override; - procedure DoAfterStreamChange; override; - procedure AfterBlockRead; virtual; // override to check protection - procedure BeforeBlockWrite; virtual; // override to compute protection - procedure SetSize(const NewSize: Int64); override; - public - constructor Create(AStorageStream: TStream; AOwnsStream: Boolean = False; + Function FlatToSectored(Const Position: Int64): Int64; + Function SectoredToFlat(Const Position: Int64): Int64; + Function GetCalcedSize: Int64; override; + Function LoadBuffer: Boolean; override; + Procedure DoAfterStreamChange; override; + Procedure AfterBlockRead; virtual; // override to check protection + Procedure BeforeBlockWrite; virtual; // override to compute protection + Procedure SetSize(Const NewSize: Int64); override; + Public + Constructor Create(AStorageStream: TStream; AOwnsStream: Boolean = False; ASectorOverHead: Longint = 0); - procedure Flush; override; - end; - TJclCRC16Stream = class(TJclSectoredStream) - protected - procedure AfterBlockRead; override; - procedure BeforeBlockWrite; override; - public - constructor Create(AStorageStream: TStream; AOwnsStream: Boolean = False); - end; - TJclCRC32Stream = class(TJclSectoredStream) - protected - procedure AfterBlockRead; override; - procedure BeforeBlockWrite; override; - public - constructor Create(AStorageStream: TStream; AOwnsStream: Boolean = False); - end; + Procedure Flush; override; + End; + TJclCRC16Stream = Class(TJclSectoredStream) + Protected + Procedure AfterBlockRead; override; + Procedure BeforeBlockWrite; override; + Public + Constructor Create(AStorageStream: TStream; AOwnsStream: Boolean = False); + End; + TJclCRC32Stream = Class(TJclSectoredStream) + Protected + Procedure AfterBlockRead; override; + Procedure BeforeBlockWrite; override; + Public + Constructor Create(AStorageStream: TStream; AOwnsStream: Boolean = False); + End; {$IFDEF COMPILER7_UP} {$DEFINE SIZE64} {$ENDIF ~COMPILER7_UP} {$IFDEF FPC} {$DEFINE SIZE64} {$ENDIF FPC} - TJclSplitStream = class(TJclStream) - private + TJclSplitStream = Class(TJclStream) + Private FVolume: TStream; FVolumeIndex: Integer; FVolumeMaxSize: Int64; FPosition: Int64; FVolumePosition: Int64; FForcePosition: Boolean; - protected - function GetVolume(Index: Integer): TStream; virtual; abstract; - function GetVolumeMaxSize(Index: Integer): Int64; virtual; abstract; - function GetSize: Int64; {$IFDEF SIZE64}override;{$ENDIF SIZE64} - procedure SetSize(const NewSize: Int64); override; - function InternalLoadVolume(Index: Integer): Boolean; - public - constructor Create(AForcePosition: Boolean = False); - function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; - function Read(var Buffer; Count: Longint): Longint; override; - function Write(const Buffer; Count: Longint): Longint; override; + Protected + Function GetVolume(Index: Integer): TStream; virtual; abstract; + Function GetVolumeMaxSize(Index: Integer): Int64; virtual; abstract; + Function GetSize: Int64; {$IFDEF SIZE64}override;{$ENDIF SIZE64} + Procedure SetSize(Const NewSize: Int64); override; + Function InternalLoadVolume(Index: Integer): Boolean; + Public + Constructor Create(AForcePosition: Boolean = False); + Function Seek(Const Offset: Int64; Origin: TSeekOrigin): Int64; override; + Function Read(Var Buffer; Count: Longint): Longint; override; + Function Write(Const Buffer; Count: Longint): Longint; override; property ForcePosition: Boolean read FForcePosition write FForcePosition; - end; - TJclVolumeEvent = function(Index: Integer): TStream of object; - TJclVolumeMaxSizeEvent = function(Index: Integer): Int64 of object; - TJclDynamicSplitStream = class(TJclSplitStream) - private + End; + TJclVolumeEvent = Function(Index: Integer): TStream Of object; + TJclVolumeMaxSizeEvent = Function(Index: Integer): Int64 Of object; + TJclDynamicSplitStream = Class(TJclSplitStream) + Private FOnVolume: TJclVolumeEvent; FOnVolumeMaxSize: TJclVolumeMaxSizeEvent; - protected - function GetVolume(Index: Integer): TStream; override; - function GetVolumeMaxSize(Index: Integer): Int64; override; - public + Protected + Function GetVolume(Index: Integer): TStream; override; + Function GetVolumeMaxSize(Index: Integer): Int64; override; + Public property OnVolume: TJclVolumeEvent read FOnVolume write FOnVolume; property OnVolumeMaxSize: TJclVolumeMaxSizeEvent read FOnVolumeMaxSize write FOnVolumeMaxSize; - end; - TJclSplitVolume = class - public + End; + TJclSplitVolume = Class + Public MaxSize: Int64; Stream: TStream; OwnStream: Boolean; - end; - TJclStaticSplitStream = class(TJclSplitStream) - private + End; + TJclStaticSplitStream = Class(TJclSplitStream) + Private FVolumes: TObjectList; - function GetVolumeCount: Integer; - protected - function GetVolume(Index: Integer): TStream; override; - function GetVolumeMaxSize(Index: Integer): Int64; override; - public - constructor Create(AForcePosition: Boolean = False); - destructor Destroy; override; - function AddVolume(AStream: TStream; AMaxSize: Int64 = 0; + Function GetVolumeCount: Integer; + Protected + Function GetVolume(Index: Integer): TStream; override; + Function GetVolumeMaxSize(Index: Integer): Int64; override; + Public + Constructor Create(AForcePosition: Boolean = False); + Destructor Destroy; override; + Function AddVolume(AStream: TStream; AMaxSize: Int64 = 0; AOwnStream: Boolean = False): Integer; property VolumeCount: Integer read GetVolumeCount; property Volumes[Index: Integer]: TStream read GetVolume; property VolumeMaxSizes[Index: Integer]: Int64 read GetVolumeMaxSize; - end; - TJclStringStream = class - protected + End; + TJclStringStream = Class + Protected FStream: TStream; FOwnStream: Boolean; - FBOM: array of Byte; + FBOM: array Of Byte; FBufferSize: SizeInt; FStrPosition: Int64; // current position in characters FStrBuffer: TUCS4Array; // buffer for read/write operations @@ -394,198 +394,198 @@ TJclStringStream = class FStrPeekBufferCurrentSize: SizeInt; // numbers of characters available in peek buffer FStrPeekBufferStart: Int64; // position of the first byte of the peek buffer in stream FStrPeekBufferNext: Int64; // position of the next character following the peek buffer in stream - function LoadBuffer: Boolean; - function LoadPeekBuffer: Boolean; - function InternalGetNextChar(S: TStream; out Ch: UCS4): Boolean; virtual; abstract; - function InternalGetNextBuffer(S: TStream; var Buffer: TUCS4Array; Start, Count: SizeInt): Longint; virtual; - function InternalSetNextChar(S: TStream; Ch: UCS4): Boolean; virtual; abstract; - function InternalSetNextBuffer(S: TStream; const Buffer: TUCS4Array; Start, Count: SizeInt): Longint; virtual; - procedure InvalidateBuffers; - public - constructor Create(AStream: TStream; AOwnsStream: Boolean = False); virtual; - destructor Destroy; override; - procedure Flush; virtual; - function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; virtual; - function PeekUCS4(out Buffer: UCS4): Boolean; - function PeekWideChar(out Buffer: WideChar): Boolean; - function ReadUCS4(out Buffer: UCS4): Boolean; - function ReadWideChar(out Buffer: WideChar): Boolean; - function WriteUCS4(Value: UCS4): Boolean; - function WriteWideChar(Value: WideChar): Boolean; - function SkipBOM: LongInt; virtual; - function WriteBOM: Longint; virtual; + Function LoadBuffer: Boolean; + Function LoadPeekBuffer: Boolean; + Function InternalGetNextChar(S: TStream; out Ch: UCS4): Boolean; virtual; abstract; + Function InternalGetNextBuffer(S: TStream; Var Buffer: TUCS4Array; Start, Count: SizeInt): Longint; virtual; + Function InternalSetNextChar(S: TStream; Ch: UCS4): Boolean; virtual; abstract; + Function InternalSetNextBuffer(S: TStream; Const Buffer: TUCS4Array; Start, Count: SizeInt): Longint; virtual; + Procedure InvalidateBuffers; + Public + Constructor Create(AStream: TStream; AOwnsStream: Boolean = False); virtual; + Destructor Destroy; override; + Procedure Flush; virtual; + Function Seek(Const Offset: Int64; Origin: TSeekOrigin): Int64; virtual; + Function PeekUCS4(out Buffer: UCS4): Boolean; + Function PeekWideChar(out Buffer: WideChar): Boolean; + Function ReadUCS4(out Buffer: UCS4): Boolean; + Function ReadWideChar(out Buffer: WideChar): Boolean; + Function WriteUCS4(Value: UCS4): Boolean; + Function WriteWideChar(Value: WideChar): Boolean; + Function SkipBOM: LongInt; virtual; + Function WriteBOM: Longint; virtual; property BufferSize: SizeInt read FBufferSize write FBufferSize; property PeekPosition: Int64 read FStrPeekPosition; property Position: Int64 read FStrPosition; property Stream: TStream read FStream; property OwnStream: Boolean read FOwnStream; - end; - TJclStringStreamClass = class of TJclStringStream; - TJclAnsiStream = class(TJclStringStream) - private + End; + TJclStringStreamClass = Class Of TJclStringStream; + TJclAnsiStream = Class(TJclStringStream) + Private FCodePage: Word; - protected - public - constructor Create(AStream: TStream; AOwnsStream: Boolean = False); override; + Protected + Public + Constructor Create(AStream: TStream; AOwnsStream: Boolean = False); override; property CodePage: Word read FCodePage write FCodePage; - end; - TJclUTF8Stream = class(TJclStringStream) - protected - public - constructor Create(AStream: TStream; AOwnsStream: Boolean = False); override; - end; - TJclUTF16Stream = class(TJclStringStream) - protected - public - constructor Create(AStream: TStream; AOwnsStream: Boolean = False); override; - end; + End; + TJclUTF8Stream = Class(TJclStringStream) + Protected + Public + Constructor Create(AStream: TStream; AOwnsStream: Boolean = False); override; + End; + TJclUTF16Stream = Class(TJclStringStream) + Protected + Public + Constructor Create(AStream: TStream; AOwnsStream: Boolean = False); override; + End; TJclStringEncoding = (seAnsi, seUTF8, seUTF16, seAuto); - TJclAutoStream = class(TJclStringStream) - private + TJclAutoStream = Class(TJclStringStream) + Private FCodePage: Word; FEncoding: TJclStringEncoding; - procedure SetCodePage(Value: Word); - protected - public - constructor Create(AStream: TStream; AOwnsStream: Boolean = False); override; - function SkipBOM: LongInt; override; + Procedure SetCodePage(Value: Word); + Protected + Public + Constructor Create(AStream: TStream; AOwnsStream: Boolean = False); override; + Function SkipBOM: LongInt; override; property CodePage: Word read FCodePage write SetCodePage; property Encoding: TJclStringEncoding read FEncoding; - end; + End; // buffered copy of all available bytes from Source to Dest // returns the number of bytes that were copied -function StreamCopy(Source: TStream; Dest: TStream; BufferSize: Longint = StreamDefaultBufferSize): Int64; -function CompareStreams(A, B : TStream; BufferSize: Longint = StreamDefaultBufferSize): Boolean; +Function StreamCopy(Source: TStream; Dest: TStream; BufferSize: Longint = StreamDefaultBufferSize): Int64; +Function CompareStreams(A, B : TStream; BufferSize: Longint = StreamDefaultBufferSize): Boolean; // compares 2 files for differencies (calling CompareStreams) -function CompareFiles(const FileA, FileB: TFileName; BufferSize: Longint = StreamDefaultBufferSize): Boolean; -implementation -uses +Function CompareFiles(Const FileA, FileB: TFileName; BufferSize: Longint = StreamDefaultBufferSize): Boolean; +Implementation +Uses {$IFDEF HAS_UNITSCOPE} System.Types, {$ENDIF HAS_UNITSCOPE} uRESTDWMemResources, uRESTDWMemCharsets; -function StreamCopy(Source: TStream; Dest: TStream; BufferSize: Longint): Int64; -var - Buffer: array of Byte; +Function StreamCopy(Source: TStream; Dest: TStream; BufferSize: Longint): Int64; +Var + Buffer: array Of Byte; ByteCount: Longint; -begin +Begin Result := 0; SetLength(Buffer, BufferSize); - repeat + Repeat ByteCount := Source.Read(Buffer[0], BufferSize); Result := Result + ByteCount; Dest.WriteBuffer(Buffer[0], ByteCount); - until ByteCount < BufferSize; -end; -function CompareStreams(A, B : TStream; BufferSize: Longint): Boolean; -var - BufferA, BufferB: array of Byte; + Until ByteCount < BufferSize; +End; +Function CompareStreams(A, B : TStream; BufferSize: Longint): Boolean; +Var + BufferA, BufferB: array Of Byte; ByteCountA, ByteCountB: Longint; -begin +Begin SetLength(BufferA, BufferSize); - try + Try SetLength(BufferB, BufferSize); - try - repeat + Try + Repeat ByteCountA := A.Read(BufferA[0], BufferSize); ByteCountB := B.Read(BufferB[0], BufferSize); Result := (ByteCountA = ByteCountB); Result := Result and CompareMem(BufferA, BufferB, ByteCountA); - until (ByteCountA <> BufferSize) or (ByteCountB <> BufferSize) or not Result; - finally + Until (ByteCountA <> BufferSize) or (ByteCountB <> BufferSize) or not Result; + Finally SetLength(BufferB, 0); - end; - finally + End; + Finally SetLength(BufferA, 0); - end; -end; -function CompareFiles(const FileA, FileB: TFileName; BufferSize: Longint): Boolean; -var + End; +End; +Function CompareFiles(Const FileA, FileB: TFileName; BufferSize: Longint): Boolean; +Var A, B: TStream; -begin +Begin A := TFileStream.Create(FileA, fmOpenRead or fmShareDenyWrite); - try + Try B := TFileStream.Create(FileB, fmOpenRead or fmShareDenyWrite); - try + Try Result := CompareStreams(A, B, BufferSize); - finally + Finally B.Free; - end; - finally + End; + Finally A.Free; - end; -end; + End; +End; //=== { TJclStream } ========================================================= -function TJclStream.Seek(Offset: Longint; Origin: Word): Longint; -var +Function TJclStream.Seek(Offset: Longint; Origin: Word): Longint; +Var Result64: Int64; -begin - case Origin of +Begin + Case Origin Of soFromBeginning: Result64 := Seek(Int64(Offset), soBeginning); soFromCurrent: Result64 := Seek(Int64(Offset), soCurrent); soFromEnd: Result64 := Seek(Int64(Offset), soEnd); - else + Else Result64 := -1; - end; - if (Result64 < 0) or (Result64 > High(Longint)) then + End; + If (Result64 < 0) or (Result64 > High(Longint)) Then Result64 := -1; Result := Result64; -end; -procedure TJclStream.LoadFromFile(const FileName: TFileName; +End; +Procedure TJclStream.LoadFromFile(Const FileName: TFileName; BufferSize: Longint = StreamDefaultBufferSize); -var +Var FS: TStream; -begin +Begin FS := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); - try + Try LoadFromStream(FS, BufferSize); - finally + Finally FS.Free; - end; -end; -procedure TJclStream.LoadFromStream(Source: TStream; BufferSize: Longint = StreamDefaultBufferSize); -begin + End; +End; +Procedure TJclStream.LoadFromStream(Source: TStream; BufferSize: Longint = StreamDefaultBufferSize); +Begin StreamCopy(Source, Self, BufferSize); -end; -procedure TJclStream.SaveToFile(const FileName: TFileName; BufferSize: Longint = StreamDefaultBufferSize); -var +End; +Procedure TJclStream.SaveToFile(Const FileName: TFileName; BufferSize: Longint = StreamDefaultBufferSize); +Var FS: TStream; -begin +Begin FS := TFileStream.Create(FileName, fmCreate); - try + Try SaveToStream(FS, BufferSize); - finally + Finally FS.Free; - end; -end; -procedure TJclStream.SaveToStream(Dest: TStream; BufferSize: Longint = StreamDefaultBufferSize); -begin + End; +End; +Procedure TJclStream.SaveToStream(Dest: TStream; BufferSize: Longint = StreamDefaultBufferSize); +Begin StreamCopy(Self, Dest, BufferSize); -end; -procedure TJclStream.SetSize(NewSize: Longint); -begin +End; +Procedure TJclStream.SetSize(NewSize: Longint); +Begin SetSize(Int64(NewSize)); -end; -procedure TJclStream.SetSize(const NewSize: Int64); -begin +End; +Procedure TJclStream.SetSize(Const NewSize: Int64); +Begin // override to customize -end; +End; //=== { TJclHandleStream } =================================================== -constructor TJclHandleStream.Create(AHandle: THandle); -begin - inherited Create; +Constructor TJclHandleStream.Create(AHandle: THandle); +Begin + Inherited Create; FHandle := AHandle; -end; -function TJclHandleStream.Read(var Buffer; Count: Longint): Longint; -begin +End; +Function TJclHandleStream.Read(Var Buffer; Count: Longint): Longint; +Begin Result := 0; {$IFDEF MSWINDOWS} - if (Count <= 0) or not ReadFile(Handle, Buffer, DWORD(Count), DWORD(Result), nil) then + If (Count <= 0) or not ReadFile(Handle, Buffer, DWORD(Count), DWORD(Result), nil) Then Result := 0; {$ENDIF MSWINDOWS} {$IFDEF LINUX} @@ -595,12 +595,12 @@ function TJclHandleStream.Read(var Buffer; Count: Longint): Longint; Result := __read(Handle, Buffer, Count); {$ENDIF} {$ENDIF LINUX} -end; -function TJclHandleStream.Write(const Buffer; Count: Longint): Longint; -begin +End; +Function TJclHandleStream.Write(Const Buffer; Count: Longint): Longint; +Begin Result := 0; {$IFDEF MSWINDOWS} - if (Count <= 0) or not WriteFile(Handle, Buffer, DWORD(Count), DWORD(Result), nil) then + If (Count <= 0) or not WriteFile(Handle, Buffer, DWORD(Count), DWORD(Result), nil) Then Result := 0; {$ENDIF MSWINDOWS} {$IFDEF LINUX} @@ -611,35 +611,35 @@ function TJclHandleStream.Write(const Buffer; Count: Longint): Longint; Result := __write(Handle, Buffer, Count); {$ENDIF} {$ENDIF LINUX} -end; -procedure TJclHandleStream.SetSize(const NewSize: Int64); -begin +End; +Procedure TJclHandleStream.SetSize(Const NewSize: Int64); +Begin Seek(NewSize, soBeginning); {$IFDEF MSWINDOWS} - if not SetEndOfFile(Handle) then + If not SetEndOfFile(Handle) Then RaiseLastOSError; {$ENDIF MSWINDOWS} {$IFDEF LINUX} {$IFDEF RESTDWLINUX} - if ftruncate(Handle, Position) = -1 then + If ftruncate(Handle, Position) = -1 Then raise EJclStreamError.CreateRes(@RsStreamsSetSizeError); {$ELSE} - if ftruncate(Handle, Position) = -1 then + If ftruncate(Handle, Position) = -1 Then raise EJclStreamError.CreateRes(@RsStreamsSetSizeError); {$ENDIF} {$ENDIF LINUX} -end; +End; //=== { TJclFileStream } ===================================================== -constructor TJclFileStream.Create(const FileName: TFileName; Mode: Word; Rights: Cardinal); -var +Constructor TJclFileStream.Create(Const FileName: TFileName; Mode: Word; Rights: Cardinal); +Var H: THandle; {$IFDEF LINUX} -const +Const INVALID_HANDLE_VALUE = -1; {$ENDIF LINUX} -begin - if Mode = fmCreate then - begin +Begin + If Mode = fmCreate Then + Begin {$IFDEF LINUX} {$IFDEF RESTDWLINUX} H := FileCreate(PChar(FileName), Mode, Rights); @@ -652,895 +652,895 @@ constructor TJclFileStream.Create(const FileName: TFileName; Mode: Word; Rights: H := CreateFile(PChar(FileName), GENERIC_READ or GENERIC_WRITE, 0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); {$ENDIF MSWINDOWS} - inherited Create(H); - if Handle = INVALID_HANDLE_VALUE then + Inherited Create(H); + If Handle = INVALID_HANDLE_VALUE Then raise EJclStreamError.CreateResFmt(@RsStreamsCreateError, [FileName]); - end - else - begin + End + Else + Begin H := THandle(FileOpen(FileName, Mode)); - inherited Create(H); - if Handle = INVALID_HANDLE_VALUE then + Inherited Create(H); + If Handle = INVALID_HANDLE_VALUE Then raise EJclStreamError.CreateResFmt(@RsStreamsOpenError, [FileName]); - end; -end; -destructor TJclFileStream.Destroy; -begin + End; +End; +Destructor TJclFileStream.Destroy; +Begin {$IFDEF MSWINDOWS} - if Handle <> INVALID_HANDLE_VALUE then + If Handle <> INVALID_HANDLE_VALUE Then CloseHandle(Handle); {$ENDIF MSWINDOWS} {$IFDEF LINUX} __close(Handle); {$ENDIF LINUX} - inherited Destroy; -end; + Inherited Destroy; +End; //=== { TJclEmptyStream } ==================================================== // a stream which stays empty no matter what you do // so it is a Unix /dev/null equivalent -procedure TJclEmptyStream.SetSize(const NewSize: Int64); -begin +Procedure TJclEmptyStream.SetSize(Const NewSize: Int64); +Begin // nothing -end; -function TJclEmptyStream.Read(var Buffer; Count: Longint): Longint; -begin +End; +Function TJclEmptyStream.Read(Var Buffer; Count: Longint): Longint; +Begin // you cannot read anything Result := 0; -end; -function TJclEmptyStream.Write(const Buffer; Count: Longint): Longint; -begin +End; +Function TJclEmptyStream.Write(Const Buffer; Count: Longint): Longint; +Begin // you cannot write anything Result := 0; -end; -function TJclEmptyStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; -begin - if Offset <> 0 then +End; +Function TJclEmptyStream.Seek(Const Offset: Int64; Origin: TSeekOrigin): Int64; +Begin + If Offset <> 0 Then // seeking to anywhere except the position 0 is an error Result := -1 - else + Else Result := 0; -end; +End; //=== { TJclMultiplexStream } ================================================ -constructor TJclMultiplexStream.Create; -begin - inherited Create; +Constructor TJclMultiplexStream.Create; +Begin + Inherited Create; FStreams := TList.Create; FReadStreamIndex := -1; -end; -destructor TJclMultiplexStream.Destroy; -begin +End; +Destructor TJclMultiplexStream.Destroy; +Begin FStreams.Free; - inherited Destroy; -end; -function TJclMultiplexStream.Add(NewStream: TStream): Integer; -begin + Inherited Destroy; +End; +Function TJclMultiplexStream.Add(NewStream: TStream): Integer; +Begin Result := FStreams.Add(Pointer(NewStream)); -end; -procedure TJclMultiplexStream.Clear; -begin +End; +Procedure TJclMultiplexStream.Clear; +Begin FStreams.Clear; FReadStreamIndex := -1; -end; -procedure TJclMultiplexStream.Delete(const Index: Integer); -begin +End; +Procedure TJclMultiplexStream.Delete(Const Index: Integer); +Begin FStreams.Delete(Index); - if ReadStreamIndex = Index then + If ReadStreamIndex = Index Then FReadStreamIndex := -1 - else - if ReadStreamIndex > Index then + Else + If ReadStreamIndex > Index Then Dec(FReadStreamIndex); -end; -function TJclMultiplexStream.GetReadStream: TStream; -begin - if FReadStreamIndex >= 0 then +End; +Function TJclMultiplexStream.GetReadStream: TStream; +Begin + If FReadStreamIndex >= 0 Then Result := TStream(FStreams.Items[FReadStreamIndex]) - else + Else Result := nil; -end; -function TJclMultiplexStream.GetStream(Index: Integer): TStream; -begin +End; +Function TJclMultiplexStream.GetStream(Index: Integer): TStream; +Begin Result := TStream(FStreams.Items[Index]); -end; -function TJclMultiplexStream.GetCount: Integer; -begin +End; +Function TJclMultiplexStream.GetCount: Integer; +Begin Result := FStreams.Count; -end; -function TJclMultiplexStream.Read(var Buffer; Count: Longint): Longint; -var +End; +Function TJclMultiplexStream.Read(Var Buffer; Count: Longint): Longint; +Var Stream: TStream; -begin +Begin Stream := ReadStream; - if Assigned(Stream) then + If Assigned(Stream) Then Result := Stream.Read(Buffer, Count) - else + Else Result := 0; -end; -function TJclMultiplexStream.Remove(AStream: TStream): Integer; -begin +End; +Function TJclMultiplexStream.Remove(AStream: TStream): Integer; +Begin Result := FStreams.Remove(Pointer(AStream)); - if FReadStreamIndex = Result then + If FReadStreamIndex = Result Then FReadStreamIndex := -1 - else - if FReadStreamIndex > Result then + Else + If FReadStreamIndex > Result Then Dec(FReadStreamIndex); -end; -function TJclMultiplexStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; -begin +End; +Function TJclMultiplexStream.Seek(Const Offset: Int64; Origin: TSeekOrigin): Int64; +Begin // what should this function do? Result := -1; -end; -procedure TJclMultiplexStream.SetReadStream(const Value: TStream); -begin +End; +Procedure TJclMultiplexStream.SetReadStream(Const Value: TStream); +Begin FReadStreamIndex := FStreams.IndexOf(Pointer(Value)); -end; -procedure TJclMultiplexStream.SetReadStreamIndex(const Value: Integer); -begin +End; +Procedure TJclMultiplexStream.SetReadStreamIndex(Const Value: Integer); +Begin FReadStreamIndex := Value; -end; -procedure TJclMultiplexStream.SetSize(const NewSize: Int64); -begin +End; +Procedure TJclMultiplexStream.SetSize(Const NewSize: Int64); +Begin // what should this function do? -end; -procedure TJclMultiplexStream.SetStream(Index: Integer; const Value: TStream); -begin +End; +Procedure TJclMultiplexStream.SetStream(Index: Integer; Const Value: TStream); +Begin FStreams.Items[Index] := Pointer(Value); -end; -function TJclMultiplexStream.Write(const Buffer; Count: Longint): Longint; -var +End; +Function TJclMultiplexStream.Write(Const Buffer; Count: Longint): Longint; +Var Index: Integer; ByteWritten, MinByteWritten: Longint; -begin +Begin MinByteWritten := Count; - for Index := 0 to Self.Count - 1 do - begin + For Index := 0 To Self.Count - 1 Do + Begin ByteWritten := TStream(FStreams.Items[Index]).Write(Buffer, Count); - if ByteWritten < MinByteWritten then + If ByteWritten < MinByteWritten Then MinByteWritten := ByteWritten; - end; + End; Result := MinByteWritten; -end; +End; //=== { TJclStreamDecorator } ================================================ -constructor TJclStreamDecorator.Create(AStream: TStream; AOwnsStream: Boolean = False); -begin - inherited Create; +Constructor TJclStreamDecorator.Create(AStream: TStream; AOwnsStream: Boolean = False); +Begin + Inherited Create; FStream := AStream; FOwnsStream := AOwnsStream; -end; -destructor TJclStreamDecorator.Destroy; -begin - if OwnsStream then +End; +Destructor TJclStreamDecorator.Destroy; +Begin + If OwnsStream Then FStream.Free; - inherited Destroy; -end; -procedure TJclStreamDecorator.DoAfterStreamChange; -begin - if Assigned(FAfterStreamChange) then + Inherited Destroy; +End; +Procedure TJclStreamDecorator.DoAfterStreamChange; +Begin + If Assigned(FAfterStreamChange) Then FAfterStreamChange(Self); -end; -procedure TJclStreamDecorator.DoBeforeStreamChange; -begin - if Assigned(FBeforeStreamChange) then +End; +Procedure TJclStreamDecorator.DoBeforeStreamChange; +Begin + If Assigned(FBeforeStreamChange) Then FBeforeStreamChange(Self); -end; -function TJclStreamDecorator.Read(var Buffer; Count: Longint): Longint; -begin - if Assigned(FStream) then +End; +Function TJclStreamDecorator.Read(Var Buffer; Count: Longint): Longint; +Begin + If Assigned(FStream) Then Result := Stream.Read(Buffer, Count) - else + Else Result := 0; -end; -function TJclStreamDecorator.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; -begin +End; +Function TJclStreamDecorator.Seek(Const Offset: Int64; Origin: TSeekOrigin): Int64; +Begin Result := Stream.Seek(Offset, Origin); -end; -procedure TJclStreamDecorator.SetSize(const NewSize: Int64); -begin - if Assigned(FStream) then +End; +Procedure TJclStreamDecorator.SetSize(Const NewSize: Int64); +Begin + If Assigned(FStream) Then Stream.Size := NewSize; -end; -procedure TJclStreamDecorator.SetStream(Value: TStream); -begin - if Value <> FStream then - try +End; +Procedure TJclStreamDecorator.SetStream(Value: TStream); +Begin + If Value <> FStream Then + Try DoBeforeStreamChange; - finally - if OwnsStream then + Finally + If OwnsStream Then FStream.Free; FStream := Value; DoAfterStreamChange; - end; -end; -function TJclStreamDecorator.Write(const Buffer; Count: Longint): Longint; -begin - if Assigned(FStream) then + End; +End; +Function TJclStreamDecorator.Write(Const Buffer; Count: Longint): Longint; +Begin + If Assigned(FStream) Then Result := Stream.Write(Buffer, Count) - else + Else Result := 0; -end; +End; //=== { TJclBufferedStream } ================================================= -constructor TJclBufferedStream.Create(AStream: TStream; AOwnsStream: Boolean = False); -begin - inherited Create(AStream, AOwnsStream); - if Stream <> nil then +Constructor TJclBufferedStream.Create(AStream: TStream; AOwnsStream: Boolean = False); +Begin + Inherited Create(AStream, AOwnsStream); + If Stream <> nil Then FPosition := Stream.Position; BufferSize := StreamDefaultBufferSize; LoadBuffer; -end; -destructor TJclBufferedStream.Destroy; -begin +End; +Destructor TJclBufferedStream.Destroy; +Begin Flush; - inherited Destroy; -end; -function TJclBufferedStream.BufferHit: Boolean; -begin + Inherited Destroy; +End; +Function TJclBufferedStream.BufferHit: Boolean; +Begin Result := (FBufferStart <= FPosition) and (FPosition < (FBufferStart + FBufferCurrentSize)); -end; -procedure TJclBufferedStream.DoAfterStreamChange; -begin - inherited DoAfterStreamChange; +End; +Procedure TJclBufferedStream.DoAfterStreamChange; +Begin + Inherited DoAfterStreamChange; FBufferCurrentSize := 0; // invalidate buffer after stream is changed FBufferStart := 0; - if Stream <> nil then + If Stream <> nil Then FPosition := Stream.Position; -end; -procedure TJclBufferedStream.DoBeforeStreamChange; -begin - inherited DoBeforeStreamChange; +End; +Procedure TJclBufferedStream.DoBeforeStreamChange; +Begin + Inherited DoBeforeStreamChange; Flush; -end; -procedure TJclBufferedStream.Flush; -begin - if (Stream <> nil) and (FBufferMaxModifiedPos > 0) then - begin +End; +Procedure TJclBufferedStream.Flush; +Begin + If (Stream <> nil) and (FBufferMaxModifiedPos > 0) Then + Begin Stream.Position := FBufferStart; Stream.WriteBuffer(FBuffer[0], FBufferMaxModifiedPos); FBufferMaxModifiedPos := 0; - end; -end; -function TJclBufferedStream.GetCalcedSize: Int64; -begin - if Assigned(Stream) then + End; +End; +Function TJclBufferedStream.GetCalcedSize: Int64; +Begin + If Assigned(Stream) Then Result := Stream.Size - else + Else Result := 0; - if Result < FBufferMaxModifiedPos + FBufferStart then + If Result < FBufferMaxModifiedPos + FBufferStart Then Result := FBufferMaxModifiedPos + FBufferStart; -end; -function TJclBufferedStream.LoadBuffer: Boolean; -begin +End; +Function TJclBufferedStream.LoadBuffer: Boolean; +Begin Flush; - if Length(FBuffer) <> FBufferSize then + If Length(FBuffer) <> FBufferSize Then SetLength(FBuffer, FBufferSize); - if Stream <> nil then - begin + If Stream <> nil Then + Begin Stream.Position := FPosition; FBufferCurrentSize := Stream.Read(FBuffer[0], FBufferSize); - end - else + End + Else FBufferCurrentSize := 0; FBufferStart := FPosition; Result := (FBufferCurrentSize > 0); -end; -function TJclBufferedStream.Seek(const Offset: Int64; +End; +Function TJclBufferedStream.Seek(Const Offset: Int64; Origin: TSeekOrigin): Int64; -var +Var NewPos: Int64; -begin +Begin NewPos := FPosition; - case Origin of + Case Origin Of soBeginning: NewPos := Offset; soCurrent: Inc(NewPos, Offset); soEnd: NewPos := GetCalcedSize + Offset; - else + Else NewPos := -1; - end; - if NewPos < 0 then + End; + If NewPos < 0 Then NewPos := -1 - else + Else FPosition := NewPos; Result := NewPos; -end; -procedure TJclBufferedStream.SetSize(const NewSize: Int64); -begin - inherited SetSize(NewSize); - if NewSize < (FBufferStart + FBufferMaxModifiedPos) then - begin +End; +Procedure TJclBufferedStream.SetSize(Const NewSize: Int64); +Begin + Inherited SetSize(NewSize); + If NewSize < (FBufferStart + FBufferMaxModifiedPos) Then + Begin FBufferMaxModifiedPos := NewSize - FBufferStart; - if FBufferMaxModifiedPos < 0 then + If FBufferMaxModifiedPos < 0 Then FBufferMaxModifiedPos := 0; - end; - if NewSize < (FBufferStart + FBufferCurrentSize) then - begin + End; + If NewSize < (FBufferStart + FBufferCurrentSize) Then + Begin FBufferCurrentSize := NewSize - FBufferStart; - if FBufferCurrentSize < 0 then + If FBufferCurrentSize < 0 Then FBufferCurrentSize := 0; - end; + End; // fix from Marcelo Rocha - if Stream <> nil then + If Stream <> nil Then FPosition := Stream.Position; -end; +End; //=== { TJclEventStream } ==================================================== -constructor TJclEventStream.Create(AStream: TStream; ANotification: +Constructor TJclEventStream.Create(AStream: TStream; ANotification: TStreamNotifyEvent = nil; AOwnsStream: Boolean = False); -begin - inherited Create(AStream, AOwnsStream); +Begin + Inherited Create(AStream, AOwnsStream); FNotification := ANotification; -end; -procedure TJclEventStream.DoAfterStreamChange; -begin - inherited DoAfterStreamChange; - if Stream <> nil then +End; +Procedure TJclEventStream.DoAfterStreamChange; +Begin + Inherited DoAfterStreamChange; + If Stream <> nil Then DoNotification; -end; -procedure TJclEventStream.DoBeforeStreamChange; -begin - inherited DoBeforeStreamChange; - if Stream <> nil then +End; +Procedure TJclEventStream.DoBeforeStreamChange; +Begin + Inherited DoBeforeStreamChange; + If Stream <> nil Then DoNotification; -end; -procedure TJclEventStream.DoNotification; -begin - if Assigned(FNotification) then +End; +Procedure TJclEventStream.DoNotification; +Begin + If Assigned(FNotification) Then FNotification(Self, Stream.Position, Stream.Size); -end; -function TJclEventStream.Read(var Buffer; Count: Longint): Longint; -begin - Result := inherited Read(Buffer, Count); +End; +Function TJclEventStream.Read(Var Buffer; Count: Longint): Longint; +Begin + Result := Inherited Read(Buffer, Count); DoNotification; -end; -function TJclEventStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; -begin - Result := inherited Seek(Offset, Origin); +End; +Function TJclEventStream.Seek(Const Offset: Int64; Origin: TSeekOrigin): Int64; +Begin + Result := Inherited Seek(Offset, Origin); DoNotification; -end; -procedure TJclEventStream.SetSize(const NewSize: Int64); -begin - inherited SetSize(NewSize); +End; +Procedure TJclEventStream.SetSize(Const NewSize: Int64); +Begin + Inherited SetSize(NewSize); DoNotification; -end; -function TJclEventStream.Write(const Buffer; Count: Longint): Longint; -begin - Result := inherited Write(Buffer, Count); +End; +Function TJclEventStream.Write(Const Buffer; Count: Longint): Longint; +Begin + Result := Inherited Write(Buffer, Count); DoNotification; -end; +End; //=== { TJclEasyStream } ===================================================== -function TJclEasyStream.IsEqual(Stream: TStream): Boolean; -var +Function TJclEasyStream.IsEqual(Stream: TStream): Boolean; +Var SavePos, StreamSavePos: Int64; -begin +Begin SavePos := Position; StreamSavePos := Stream.Position; - try + Try Position := 0; Stream.Position := 0; Result := CompareStreams(Self, Stream); - finally + Finally Position := SavePos; Stream.Position := StreamSavePos; - end; -end; -function TJclEasyStream.ReadBoolean: Boolean; -begin + End; +End; +Function TJclEasyStream.ReadBoolean: Boolean; +Begin Result := False; ReadBuffer(Result, SizeOf(Result)); -end; -function TJclEasyStream.ReadChar: Char; -begin +End; +Function TJclEasyStream.ReadChar: Char; +Begin Result := #0; ReadBuffer(Result, SizeOf(Result)); -end; -function TJclEasyStream.ReadAnsiChar: DWChar; -begin +End; +Function TJclEasyStream.ReadAnsiChar: DWChar; +Begin Result := #0; ReadBuffer(Result, SizeOf(Result)); -end; -function TJclEasyStream.ReadWideChar: WideChar; -begin +End; +Function TJclEasyStream.ReadWideChar: WideChar; +Begin Result := #0; ReadBuffer(Result, SizeOf(Result)); -end; -function TJclEasyStream.ReadByte: Byte; -begin +End; +Function TJclEasyStream.ReadByte: Byte; +Begin Result := 0; ReadBuffer(Result, SizeOf(Result)); -end; -function TJclEasyStream.ReadCurrency: Currency; -begin +End; +Function TJclEasyStream.ReadCurrency: Currency; +Begin Result := 0; ReadBuffer(Result, SizeOf(Result)); -end; -function TJclEasyStream.ReadDateTime: TDateTime; -begin +End; +Function TJclEasyStream.ReadDateTime: TDateTime; +Begin Result := 0; ReadBuffer(Result, SizeOf(Result)); -end; -function TJclEasyStream.ReadDouble: Double; -begin +End; +Function TJclEasyStream.ReadDouble: Double; +Begin Result := 0; ReadBuffer(Result, SizeOf(Result)); -end; -function TJclEasyStream.ReadExtended: Extended; -begin +End; +Function TJclEasyStream.ReadExtended: Extended; +Begin Result := 0; ReadBuffer(Result, SizeOf(Result)); -end; -function TJclEasyStream.ReadInt64: Int64; -begin +End; +Function TJclEasyStream.ReadInt64: Int64; +Begin Result := 0; ReadBuffer(Result, SizeOf(Result)); -end; -function TJclEasyStream.ReadInteger: Integer; -begin +End; +Function TJclEasyStream.ReadInteger: Integer; +Begin Result := 0; ReadBuffer(Result, SizeOf(Result)); -end; -function TJclEasyStream.ReadCString: string; -begin +End; +Function TJclEasyStream.ReadCString: string; +Begin {$IFDEF SUPPORTS_UNICODE} Result := ReadCWideString; {$ELSE ~SUPPORTS_UNICODE} Result := ReadCAnsiString; {$ENDIF ~SUPPORTS_UNICODE} -end; -function TJclEasyStream.ReadCAnsiString: DWString; -var +End; +Function TJclEasyStream.ReadCAnsiString: DWString; +Var CurrPos: Longint; StrSize: Integer; -begin +Begin CurrPos := Position; - repeat - until ReadAnsiChar = #0; + Repeat + Until ReadAnsiChar = #0; StrSize := Position - CurrPos; // Get number of bytes SetLength(Result, StrSize div SizeOf(Char) - 1); // Set number of chars without #0 Position := CurrPos; // Seek to start read ReadBuffer(Result[1], StrSize); // Read ansi data and #0 -end; -function TJclEasyStream.ReadCWideString: DWWideString; -var +End; +Function TJclEasyStream.ReadCWideString: DWWideString; +Var CurrPos: Integer; StrSize: Integer; -begin +Begin CurrPos := Position; - repeat - until ReadWideChar = #0; + Repeat + Until ReadWideChar = #0; StrSize := Position - CurrPos; // Get number of bytes SetLength(Result, StrSize div SizeOf(WideChar) - 1); // Set number of chars without #0 Position := CurrPos; // Seek to start read ReadBuffer(Result[1], StrSize); // Read wide data and #0 -end; -function TJclEasyStream.ReadShortString: string; -var +End; +Function TJclEasyStream.ReadShortString: string; +Var StrSize: Integer; -begin +Begin StrSize := Ord(ReadChar); SetString(Result, PChar(nil), StrSize); ReadBuffer(Pointer(Result)^, StrSize); -end; -function TJclEasyStream.ReadSingle: Single; -begin +End; +Function TJclEasyStream.ReadSingle: Single; +Begin Result := 0; ReadBuffer(Result, SizeOf(Result)); -end; -function TJclEasyStream.ReadSizedString: string; -begin +End; +Function TJclEasyStream.ReadSizedString: string; +Begin {$IFDEF SUPPORTS_UNICODE} Result := ReadSizedWideString; {$ELSE ~SUPPORTS_UNICODE} Result := ReadSizedAnsiString; {$ENDIF ~SUPPORTS_UNICODE} -end; -function TJclEasyStream.ReadSizedAnsiString: DWString; -var +End; +Function TJclEasyStream.ReadSizedAnsiString: DWString; +Var StrSize: Integer; -begin +Begin StrSize := ReadInteger; SetLength(Result, StrSize); ReadBuffer(Result[1], StrSize * SizeOf(Result[1])); -end; -function TJclEasyStream.ReadSizedWideString: DWWideString; -var +End; +Function TJclEasyStream.ReadSizedWideString: DWWideString; +Var StrSize: Integer; -begin +Begin StrSize := ReadInteger; SetLength(Result, StrSize); ReadBuffer(Result[1], StrSize * SizeOf(Result[1])); -end; -procedure TJclEasyStream.WriteBoolean(Value: Boolean); -begin +End; +Procedure TJclEasyStream.WriteBoolean(Value: Boolean); +Begin WriteBuffer(Value, SizeOf(Value)); -end; -procedure TJclEasyStream.WriteChar(Value: Char); -begin +End; +Procedure TJclEasyStream.WriteChar(Value: Char); +Begin WriteBuffer(Value, SizeOf(Value)); -end; -procedure TJclEasyStream.WriteAnsiChar(Value: DWChar); -begin +End; +Procedure TJclEasyStream.WriteAnsiChar(Value: DWChar); +Begin WriteBuffer(Value, SizeOf(Value)); -end; -procedure TJclEasyStream.WriteWideChar(Value: WideChar); -begin +End; +Procedure TJclEasyStream.WriteWideChar(Value: WideChar); +Begin WriteBuffer(Value, SizeOf(Value)); -end; -procedure TJclEasyStream.WriteByte(Value: Byte); -begin +End; +Procedure TJclEasyStream.WriteByte(Value: Byte); +Begin WriteBuffer(Value, SizeOf(Value)); -end; -procedure TJclEasyStream.WriteCurrency(const Value: Currency); -begin +End; +Procedure TJclEasyStream.WriteCurrency(Const Value: Currency); +Begin WriteBuffer(Value, SizeOf(Value)); -end; -procedure TJclEasyStream.WriteDateTime(const Value: TDateTime); -begin +End; +Procedure TJclEasyStream.WriteDateTime(Const Value: TDateTime); +Begin WriteBuffer(Value, SizeOf(Value)); -end; -procedure TJclEasyStream.WriteDouble(const Value: Double); -begin +End; +Procedure TJclEasyStream.WriteDouble(Const Value: Double); +Begin WriteBuffer(Value, SizeOf(Value)); -end; -procedure TJclEasyStream.WriteExtended(const Value: Extended); -begin +End; +Procedure TJclEasyStream.WriteExtended(Const Value: Extended); +Begin WriteBuffer(Value, SizeOf(Value)); -end; -procedure TJclEasyStream.WriteInt64(Value: Int64); -begin +End; +Procedure TJclEasyStream.WriteInt64(Value: Int64); +Begin WriteBuffer(Value, SizeOf(Value)); -end; -procedure TJclEasyStream.WriteInteger(Value: Integer); -begin +End; +Procedure TJclEasyStream.WriteInteger(Value: Integer); +Begin WriteBuffer(Value, SizeOf(Value)); -end; -procedure TJclEasyStream.WriteCString(const Value: string); -begin +End; +Procedure TJclEasyStream.WriteCString(Const Value: string); +Begin {$IFDEF SUPPORTS_UNICODE} WriteCWideString(Value); {$ELSE ~SUPPORTS_UNICODE} WriteCAnsiString(Value); {$ENDIF ~SUPPORTS_UNICODE} -end; -procedure TJclEasyStream.WriteCAnsiString(const Value: DWString); -var +End; +Procedure TJclEasyStream.WriteCAnsiString(Const Value: DWString); +Var StrSize: Integer; -begin +Begin StrSize := Length(Value); WriteBuffer(Value[1], (StrSize + 1) * SizeOf(Value[1])); -end; -procedure TJclEasyStream.WriteCWideString(const Value: DWWideString); -var +End; +Procedure TJclEasyStream.WriteCWideString(Const Value: DWWideString); +Var StrSize: Integer; -begin +Begin StrSize := Length(Value); WriteBuffer(Value[1], (StrSize + 1) * SizeOf(Value[1])); -end; -procedure TJclEasyStream.WriteSingle(const Value: Single); -begin +End; +Procedure TJclEasyStream.WriteSingle(Const Value: Single); +Begin WriteBuffer(Value, SizeOf(Value)); -end; -procedure TJclEasyStream.WriteSizedString(const Value: string); -begin +End; +Procedure TJclEasyStream.WriteSizedString(Const Value: string); +Begin {$IFDEF SUPPORTS_UNICODE} WriteSizedWideString(Value); {$ELSE ~SUPPORTS_UNICODE} WriteSizedAnsiString(Value); {$ENDIF ~SUPPORTS_UNICODE} -end; -procedure TJclEasyStream.WriteSizedAnsiString(const Value: DWString); -var +End; +Procedure TJclEasyStream.WriteSizedAnsiString(Const Value: DWString); +Var StrSize: Integer; -begin +Begin StrSize := Length(Value); WriteInteger(StrSize); WriteBuffer(Value[1], StrSize * SizeOf(Value[1])); -end; -procedure TJclEasyStream.WriteSizedWideString(const Value: DWWideString); -var +End; +Procedure TJclEasyStream.WriteSizedWideString(Const Value: DWWideString); +Var StrSize: Integer; -begin +Begin StrSize := Length(Value); WriteInteger(StrSize); WriteBuffer(Value[1], StrSize * SizeOf(Value[1])); -end; +End; //=== { TJclScopedStream } =================================================== -constructor TJclScopedStream.Create(AParentStream: TStream; const AMaxSize: Int64); -begin - inherited Create; +Constructor TJclScopedStream.Create(AParentStream: TStream; Const AMaxSize: Int64); +Begin + Inherited Create; FParentStream := AParentStream; FStartPos := ParentStream.Position; FCurrentPos := 0; FMaxSize := AMaxSize; -end; -constructor TJclScopedStream.Create(AParentStream: TStream; const AStartPos, AMaxSize: Int64); -begin - inherited Create; +End; +Constructor TJclScopedStream.Create(AParentStream: TStream; Const AStartPos, AMaxSize: Int64); +Begin + Inherited Create; FParentStream := AParentStream; FStartPos := AStartPos; FCurrentPos := 0; FMaxSize := AMaxSize; -end; -function TJclScopedStream.Read(var Buffer; Count: Longint): Longint; -begin - if (MaxSize >= 0) and ((FCurrentPos + Count) > MaxSize) then +End; +Function TJclScopedStream.Read(Var Buffer; Count: Longint): Longint; +Begin + If (MaxSize >= 0) and ((FCurrentPos + Count) > MaxSize) Then Count := MaxSize - FCurrentPos; - if (Count > 0) and Assigned(ParentStream) then - begin + If (Count > 0) and Assigned(ParentStream) Then + Begin Result := ParentStream.Read(Buffer, Count); Inc(FCurrentPos, Result); - end - else + End + Else Result := 0; -end; -function TJclScopedStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; -begin - case Origin of +End; +Function TJclScopedStream.Seek(Const Offset: Int64; Origin: TSeekOrigin): Int64; +Begin + Case Origin Of soBeginning: - begin - if (Offset < 0) or ((MaxSize >= 0) and (Offset > MaxSize)) then + Begin + If (Offset < 0) or ((MaxSize >= 0) and (Offset > MaxSize)) Then Result := -1 // low and high bound check - else + Else Result := ParentStream.Seek(StartPos + Offset, soBeginning) - StartPos; - end; + End; soCurrent: - begin - if Offset = 0 then + Begin + If Offset = 0 Then Result := FCurrentPos // speeding the Position property up - else if ((FCurrentPos + Offset) < 0) or ((MaxSize >= 0) - and ((FCurrentPos + Offset) > MaxSize)) then + Else If ((FCurrentPos + Offset) < 0) or ((MaxSize >= 0) + and ((FCurrentPos + Offset) > MaxSize)) Then Result := -1 // low and high bound check - else + Else Result := ParentStream.Seek(Offset, soCurrent) - StartPos; - end; + End; soEnd: - begin - if (MaxSize >= 0) then - begin - if (Offset > 0) or (MaxSize < -Offset) then // low and high bound check + Begin + If (MaxSize >= 0) Then + Begin + If (Offset > 0) or (MaxSize < -Offset) Then // low and high bound check Result := -1 - else + Else Result := ParentStream.Seek(StartPos + MaxSize + Offset, soBeginning) - StartPos; - end - else - begin + End + Else + Begin Result := ParentStream.Seek(Offset, soEnd); - if (Result <> -1) and (Result < StartPos) then // low bound check - begin + If (Result <> -1) and (Result < StartPos) Then // low bound check + Begin Result := -1; ParentStream.Seek(StartPos + FCurrentPos, soBeginning); - end; - end; - end; - else + End; + End; + End; + Else Result := -1; - end; - if Result <> -1 then + End; + If Result <> -1 Then FCurrentPos := Result; -end; -procedure TJclScopedStream.SetSize(const NewSize: Int64); -var +End; +Procedure TJclScopedStream.SetSize(Const NewSize: Int64); +Var ScopedNewSize: Int64; -begin - if (FMaxSize >= 0) and (NewSize >= (FStartPos + FMaxSize)) then +Begin + If (FMaxSize >= 0) and (NewSize >= (FStartPos + FMaxSize)) Then ScopedNewSize := FMaxSize + FStartPos - else + Else ScopedNewSize := NewSize; - inherited SetSize(ScopedNewSize); -end; -function TJclScopedStream.Write(const Buffer; Count: Longint): Longint; -begin - if (MaxSize >= 0) and ((FCurrentPos + Count) > MaxSize) then + Inherited SetSize(ScopedNewSize); +End; +Function TJclScopedStream.Write(Const Buffer; Count: Longint): Longint; +Begin + If (MaxSize >= 0) and ((FCurrentPos + Count) > MaxSize) Then Count := MaxSize - FCurrentPos; - if (Count > 0) and Assigned(ParentStream) then - begin + If (Count > 0) and Assigned(ParentStream) Then + Begin Result := ParentStream.Write(Buffer, Count); Inc(FCurrentPos, Result); - end - else + End + Else Result := 0; -end; +End; //=== { TJclDelegateStream } ================================================= -procedure TJclDelegatedStream.SetSize(const NewSize: Int64); -begin - if Assigned(FOnSize) then +Procedure TJclDelegatedStream.SetSize(Const NewSize: Int64); +Begin + If Assigned(FOnSize) Then FOnSize(Self, NewSize); -end; -function TJclDelegatedStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; -begin - if Assigned(FOnSeek) then +End; +Function TJclDelegatedStream.Seek(Const Offset: Int64; Origin: TSeekOrigin): Int64; +Begin + If Assigned(FOnSeek) Then Result := FOnSeek(Self, Offset, Origin) - else + Else Result := -1; -end; -function TJclDelegatedStream.Read(var Buffer; Count: Longint): Longint; -begin - if Assigned(FOnRead) then +End; +Function TJclDelegatedStream.Read(Var Buffer; Count: Longint): Longint; +Begin + If Assigned(FOnRead) Then Result := FOnRead(Self, Buffer, Count) - else + Else Result := -1; -end; -function TJclDelegatedStream.Write(const Buffer; Count: Longint): Longint; -begin - if Assigned(FOnWrite) then +End; +Function TJclDelegatedStream.Write(Const Buffer; Count: Longint): Longint; +Begin + If Assigned(FOnWrite) Then Result := FOnWrite(Self, Buffer, Count) - else + Else Result := -1; -end; +End; //=== { TJclSectoredStream } ================================================= -procedure TJclSectoredStream.AfterBlockRead; -begin +Procedure TJclSectoredStream.AfterBlockRead; +Begin // override to customize (checks of protection) -end; -procedure TJclSectoredStream.BeforeBlockWrite; -begin +End; +Procedure TJclSectoredStream.BeforeBlockWrite; +Begin // override to customize (computation of protection) -end; -constructor TJclSectoredStream.Create(AStorageStream: TStream; +End; +Constructor TJclSectoredStream.Create(AStorageStream: TStream; AOwnsStream: Boolean = False; ASectorOverHead: Longint = 0); -begin - inherited Create(AStorageStream, AOwnsStream); +Begin + Inherited Create(AStorageStream, AOwnsStream); FSectorOverHead := ASectorOverHead; - if Stream <> nil then + If Stream <> nil Then FPosition := SectoredToFlat(Stream.Position); -end; -procedure TJclSectoredStream.DoAfterStreamChange; -begin - inherited DoAfterStreamChange; - if Stream <> nil then +End; +Procedure TJclSectoredStream.DoAfterStreamChange; +Begin + Inherited DoAfterStreamChange; + If Stream <> nil Then FPosition := SectoredToFlat(Stream.Position); -end; -function TJclSectoredStream.FlatToSectored(const Position: Int64): Int64; -begin +End; +Function TJclSectoredStream.FlatToSectored(Const Position: Int64): Int64; +Begin Result := (Position div BufferSize) * (Int64(BufferSize) + FSectorOverHead) // add overheads of previous buffers + (Position mod BufferSize); // offset in sector -end; -procedure TJclSectoredStream.Flush; -begin - if (Stream <> nil) and (FBufferMaxModifiedPos > 0) then - begin +End; +Procedure TJclSectoredStream.Flush; +Begin + If (Stream <> nil) and (FBufferMaxModifiedPos > 0) Then + Begin BeforeBlockWrite; Stream.Position := FlatToSectored(FBufferStart); Stream.WriteBuffer(FBuffer[0], FBufferCurrentSize + FSectorOverHead); FBufferMaxModifiedPos := 0; - end; -end; -function TJclSectoredStream.GetCalcedSize: Int64; -var + End; +End; +Function TJclSectoredStream.GetCalcedSize: Int64; +Var VirtualSize: Int64; -begin - if Assigned(Stream) then +Begin + If Assigned(Stream) Then Result := SectoredToFlat(Stream.Size) - else + Else Result := 0; VirtualSize := FBufferMaxModifiedPos + FBufferStart; - if Result < VirtualSize then + If Result < VirtualSize Then Result := VirtualSize; -end; -function TJclSectoredStream.LoadBuffer: Boolean; -var +End; +Function TJclSectoredStream.LoadBuffer: Boolean; +Var TotalSectorSize: Longint; -begin +Begin Flush; TotalSectorSize := FBufferSize + FSectorOverHead; - if Length(FBuffer) <> TotalSectorSize then + If Length(FBuffer) <> TotalSectorSize Then SetLength(FBuffer, TotalSectorSize); FBufferStart := (FPosition div BufferSize) * BufferSize; - if Stream <> nil then - begin + If Stream <> nil Then + Begin Stream.Position := FlatToSectored(FBufferStart); FBufferCurrentSize := Stream.Read(FBuffer[0], TotalSectorSize); - if FBufferCurrentSize > 0 then - begin + If FBufferCurrentSize > 0 Then + Begin Dec(FBufferCurrentSize, FSectorOverHead); AfterBlockRead; - end; - end - else + End; + End + Else FBufferCurrentSize := 0; Result := (FBufferCurrentSize > 0); -end; -function TJclSectoredStream.SectoredToFlat(const Position: Int64): Int64; -var +End; +Function TJclSectoredStream.SectoredToFlat(Const Position: Int64): Int64; +Var TotalSectorSize: Int64; -begin +Begin TotalSectorSize := Int64(BufferSize) + FSectorOverHead; Result := (Position div TotalSectorSize) * BufferSize // remove previous overheads + Position mod TotalSectorSize; // offset in sector -end; -procedure TJclSectoredStream.SetSize(const NewSize: Int64); -begin - inherited SetSize(FlatToSectored(NewSize)); -end; +End; +Procedure TJclSectoredStream.SetSize(Const NewSize: Int64); +Begin + Inherited SetSize(FlatToSectored(NewSize)); +End; //=== { TJclCRC16Stream } ==================================================== -procedure TJclCRC16Stream.AfterBlockRead; -var +Procedure TJclCRC16Stream.AfterBlockRead; +Var CRC: Word; -begin +Begin CRC := Word(FBuffer[FBufferCurrentSize]) or (Word(FBuffer[FBufferCurrentSize + 1]) shl 8); - if CheckCrc16(FBuffer, FBufferCurrentSize, CRC) < 0 then + If CheckCrc16(FBuffer, FBufferCurrentSize, CRC) < 0 Then raise EJclStreamError.CreateRes(@RsStreamsCRCError); -end; -procedure TJclCRC16Stream.BeforeBlockWrite; -var +End; +Procedure TJclCRC16Stream.BeforeBlockWrite; +Var CRC: Word; -begin +Begin CRC := Crc16(FBuffer, FBufferCurrentSize); FBuffer[FBufferCurrentSize] := CRC and $FF; FBuffer[FBufferCurrentSize + 1] := CRC shr 8; -end; -constructor TJclCRC16Stream.Create(AStorageStream: TStream; AOwnsStream: Boolean); -begin - inherited Create(AStorageStream, AOwnsStream, 2); -end; +End; +Constructor TJclCRC16Stream.Create(AStorageStream: TStream; AOwnsStream: Boolean); +Begin + Inherited Create(AStorageStream, AOwnsStream, 2); +End; //=== { TJclCRC32Stream } ==================================================== -procedure TJclCRC32Stream.AfterBlockRead; -var +Procedure TJclCRC32Stream.AfterBlockRead; +Var CRC: Cardinal; -begin +Begin CRC := Cardinal(FBuffer[FBufferCurrentSize]) or (Cardinal(FBuffer[FBufferCurrentSize + 1]) shl 8) or (Cardinal(FBuffer[FBufferCurrentSize + 2]) shl 16) or (Cardinal(FBuffer[FBufferCurrentSize + 3]) shl 24); - if CheckCrc32(FBuffer, FBufferCurrentSize, CRC) < 0 then + If CheckCrc32(FBuffer, FBufferCurrentSize, CRC) < 0 Then raise EJclStreamError.CreateRes(@RsStreamsCRCError); -end; -procedure TJclCRC32Stream.BeforeBlockWrite; -var +End; +Procedure TJclCRC32Stream.BeforeBlockWrite; +Var CRC: Cardinal; -begin +Begin CRC := Crc32(FBuffer, FBufferCurrentSize); FBuffer[FBufferCurrentSize] := CRC and $FF; FBuffer[FBufferCurrentSize + 1] := (CRC shr 8) and $FF; FBuffer[FBufferCurrentSize + 2] := (CRC shr 16) and $FF; FBuffer[FBufferCurrentSize + 3] := (CRC shr 24) and $FF; -end; -constructor TJclCRC32Stream.Create(AStorageStream: TStream; +End; +Constructor TJclCRC32Stream.Create(AStorageStream: TStream; AOwnsStream: Boolean); -begin - inherited Create(AStorageStream, AOwnsStream, 4); -end; +Begin + Inherited Create(AStorageStream, AOwnsStream, 4); +End; //=== { TJclSplitStream } ==================================================== -constructor TJclSplitStream.Create(AForcePosition: Boolean); -begin - inherited Create; +Constructor TJclSplitStream.Create(AForcePosition: Boolean); +Begin + Inherited Create; FVolume := nil; FVolumeIndex := -1; FVolumeMaxSize := 0; FPosition := 0; FVolumePosition := 0; FForcePosition := AForcePosition; -end; -function TJclSplitStream.GetSize: Int64; -var +End; +Function TJclSplitStream.GetSize: Int64; +Var OldVolumeIndex: Integer; OldVolumePosition, OldPosition: Int64; -begin +Begin OldVolumeIndex := FVolumeIndex; OldVolumePosition := FVolumePosition; OldPosition := FPosition; Result := 0; - try + Try FVolumeIndex := -1; - repeat - if not InternalLoadVolume(FVolumeIndex + 1) then + Repeat + If not InternalLoadVolume(FVolumeIndex + 1) Then Break; Result := Result + FVolume.Size; - until FVolume.Size = 0; - finally + Until FVolume.Size = 0; + Finally InternalLoadVolume(OldVolumeIndex); FPosition := OldPosition; - if Assigned(FVolume) then + If Assigned(FVolume) Then FVolumePosition := FVolume.Seek(OldVolumePosition, soBeginning); - end; -end; -function TJclSplitStream.InternalLoadVolume(Index: Integer): Boolean; -var + End; +End; +Function TJclSplitStream.InternalLoadVolume(Index: Integer): Boolean; +Var OldVolumeIndex: Integer; OldVolumePosition: Int64; OldVolume: TStream; -begin - if Index = -1 then +Begin + If Index = -1 Then Index := 0; - if Index <> FVolumeIndex then - begin + If Index <> FVolumeIndex Then + Begin // save current pointers OldVolumeIndex := FVolumeIndex; OldVolumePosition := FVolumePosition; @@ -1549,84 +1549,84 @@ function TJclSplitStream.InternalLoadVolume(Index: Integer): Boolean; FVolumePosition := 0; FVolume := GetVolume(Index); Result := Assigned(FVolume); - if Result then begin + If Result Then Begin FVolumeMaxSize := GetVolumeMaxSize(Index); FVolume.Seek(0, soBeginning) - end - else - begin + End + Else + Begin // restore old pointers if volume load failed FVolumeIndex := OldVolumeIndex; FVolumePosition := OldVolumePosition; FVolume := OldVolume; - end; - end - else + End; + End + Else Result := Assigned(FVolume); -end; -function TJclSplitStream.Read(var Buffer; Count: Longint): Longint; -var +End; +Function TJclSplitStream.Read(Var Buffer; Count: Longint): Longint; +Var Data: PByte; Total, LoopRead: Longint; -begin +Begin Result := 0; - if not InternalLoadVolume(FVolumeIndex) then + If not InternalLoadVolume(FVolumeIndex) Then Exit; Data := PByte(@Buffer); Total := Count; - repeat + Repeat // force position - if ForcePosition then + If ForcePosition Then FVolume.Seek(FVolumePosition, soBeginning); // try to read (Count) bytes from current stream LoopRead := FVolume.Read(Data^, Count); FVolumePosition := FVolumePosition + LoopRead; FPosition := FPosition + LoopRead; Inc(Result, LoopRead); - if Result = Total then + If Result = Total Then Break; // with next volume Dec(Count, LoopRead); Inc(Data, LoopRead); - if not InternalLoadVolume(FVolumeIndex + 1) then + If not InternalLoadVolume(FVolumeIndex + 1) Then Break; - until False; -end; -function TJclSplitStream.Seek(const Offset: Int64; + Until False; +End; +Function TJclSplitStream.Seek(Const Offset: Int64; Origin: TSeekOrigin): Int64; -var +Var ExpectedPosition, RemainingOffset: Int64; -begin - case TSeekOrigin(Origin) of +Begin + Case TSeekOrigin(Origin) Of soBeginning: ExpectedPosition := Offset; soCurrent: ExpectedPosition := FPosition + Offset; soEnd: ExpectedPosition := Size + Offset; - else + Else raise EJclStreamError.CreateRes(@RsStreamsSeekError); - end; + End; RemainingOffset := ExpectedPosition - FPosition; Result := FPosition; - repeat - if not InternalLoadVolume(FVolumeIndex) then + Repeat + If not InternalLoadVolume(FVolumeIndex) Then Break; - if RemainingOffset < 0 then - begin + If RemainingOffset < 0 Then + Begin // FPosition > ExpectedPosition, seek backward - if FVolumePosition >= -RemainingOffset then - begin + If FVolumePosition >= -RemainingOffset Then + Begin // seek in current volume FVolumePosition := FVolume.Seek(FVolumePosition + RemainingOffset, soBeginning); Result := Result + RemainingOffset; FPosition := Result; RemainingOffset := 0; - end - else - begin + End + Else + Begin // seek to previous volume - if FVolumeIndex = 0 then + If FVolumeIndex = 0 Then Exit; // seek to the beginning of current volume RemainingOffset := RemainingOffset + FVolumePosition; @@ -1634,165 +1634,165 @@ function TJclSplitStream.Seek(const Offset: Int64; FPosition := Result; FVolumePosition := FVolume.Seek(0, soBeginning); // load previous volume - if not InternalLoadVolume(FVolumeIndex - 1) then + If not InternalLoadVolume(FVolumeIndex - 1) Then Break; Result := Result - FVolume.Size; FPosition := Result; RemainingOffset := RemainingOffset + FVolume.Size; - end; - end - else if RemainingOffset > 0 then - begin + End; + End + Else If RemainingOffset > 0 Then + Begin // FPosition < ExpectedPosition, seek forward - if (FVolumeMaxSize = 0) or ((FVolumePosition + RemainingOffset) < FVolumeMaxSize) then - begin + If (FVolumeMaxSize = 0) or ((FVolumePosition + RemainingOffset) < FVolumeMaxSize) Then + Begin // can seek in current volume FVolumePosition := FVolume.Seek(FVolumePosition + RemainingOffset, soBeginning); Result := Result + RemainingOffset; FPosition := Result; RemainingOffset := 0; - end - else - begin + End + Else + Begin // seek to next volume RemainingOffset := RemainingOffset - FVolumeMaxSize + FVolumePosition; Result := Result + FVolumeMaxSize - FVolumePosition; FPosition := Result; - if not InternalLoadVolume(FVolumeIndex + 1) then begin + If not InternalLoadVolume(FVolumeIndex + 1) Then Begin FVolumePosition := FVolumeMaxSize; Break; - end; - end; - end; - until RemainingOffset = 0; -end; -procedure TJclSplitStream.SetSize(const NewSize: Int64); -var + End; + End; + End; + Until RemainingOffset = 0; +End; +Procedure TJclSplitStream.SetSize(Const NewSize: Int64); +Var OldVolumeIndex: Integer; OldVolumePosition, OldPosition, RemainingSize, VolumeSize: Int64; -begin +Begin OldVolumeIndex := FVolumeIndex; OldVolumePosition := FVolumePosition; OldPosition := FPosition; RemainingSize := NewSize; - try + Try FVolumeIndex := 0; - repeat - if not InternalLoadVolume(FVolumeIndex) then + Repeat + If not InternalLoadVolume(FVolumeIndex) Then Break; - if (FVolumeMaxSize > 0) and (RemainingSize > FVolumeMaxSize) then + If (FVolumeMaxSize > 0) and (RemainingSize > FVolumeMaxSize) Then VolumeSize := FVolumeMaxSize - else + Else VolumeSize := RemainingSize; FVolume.Size := VolumeSize; RemainingSize := RemainingSize - VolumeSize; Inc(FVolumeIndex); - until RemainingSize = 0; - finally + Until RemainingSize = 0; + Finally InternalLoadVolume(OldVolumeIndex); FPosition := OldPosition; - if Assigned(FVolume) then + If Assigned(FVolume) Then FVolumePosition := FVolume.Seek(OldVolumePosition, soBeginning); - end; -end; -function TJclSplitStream.Write(const Buffer; Count: Longint): Longint; -var + End; +End; +Function TJclSplitStream.Write(Const Buffer; Count: Longint): Longint; +Var Data: PByte; Total, LoopWritten: Longint; -begin +Begin Result := 0; - if not InternalLoadVolume(FVolumeIndex) then + If not InternalLoadVolume(FVolumeIndex) Then Exit; Data := PByte(@Buffer); Total := Count; - repeat + Repeat // force position - if ForcePosition then + If ForcePosition Then FVolume.Seek(FVolumePosition, soBeginning); // do not write more than (VolumeMaxSize) bytes in current stream - if (FVolumeMaxSize > 0) and ((Count + FVolumePosition) > FVolumeMaxSize) then + If (FVolumeMaxSize > 0) and ((Count + FVolumePosition) > FVolumeMaxSize) Then LoopWritten := FVolumeMaxSize - FVolumePosition - else + Else LoopWritten := Count; // try to write (Count) bytes from current stream LoopWritten := FVolume.Write(Data^, LoopWritten); FVolumePosition := FVolumePosition + LoopWritten; FPosition := FPosition + LoopWritten; Inc(Result, LoopWritten); - if Result = Total then + If Result = Total Then Break; // with next volume Dec(Count, LoopWritten); Inc(Data, LoopWritten); - if not InternalLoadVolume(FVolumeIndex + 1) then + If not InternalLoadVolume(FVolumeIndex + 1) Then Break; - until False; -end; + Until False; +End; //=== { TJclDynamicSplitStream } ============================================= -function TJclDynamicSplitStream.GetVolume(Index: Integer): TStream; -begin - if Assigned(FOnVolume) then +Function TJclDynamicSplitStream.GetVolume(Index: Integer): TStream; +Begin + If Assigned(FOnVolume) Then Result := FOnVolume(Index) - else + Else Result := nil; -end; -function TJclDynamicSplitStream.GetVolumeMaxSize(Index: Integer): Int64; -begin - if Assigned(FOnVolumeMaxSize) then +End; +Function TJclDynamicSplitStream.GetVolumeMaxSize(Index: Integer): Int64; +Begin + If Assigned(FOnVolumeMaxSize) Then Result := FOnVolumeMaxSize(Index) - else + Else Result := 0; -end; +End; //=== { TJclStaticSplitStream } =========================================== -constructor TJclStaticSplitStream.Create(AForcePosition: Boolean); -begin - inherited Create(AForcePosition); +Constructor TJclStaticSplitStream.Create(AForcePosition: Boolean); +Begin + Inherited Create(AForcePosition); FVolumes := TObjectList.Create; -end; -destructor TJclStaticSplitStream.Destroy; -var +End; +Destructor TJclStaticSplitStream.Destroy; +Var Index: Integer; AVolumeRec: TJclSplitVolume; -begin - if Assigned(FVolumes) then - begin - for Index := 0 to FVolumes.Count - 1 do - begin +Begin + If Assigned(FVolumes) Then + Begin + For Index := 0 To FVolumes.Count - 1 Do + Begin AVolumeRec := TJclSplitVolume(FVolumes.Items[Index]); - if AVolumeRec.OwnStream then + If AVolumeRec.OwnStream Then AVolumeRec.Stream.Free; - end; + End; FVolumes.Free; - end; - inherited Destroy; -end; -function TJclStaticSplitStream.AddVolume(AStream: TStream; AMaxSize: Int64; + End; + Inherited Destroy; +End; +Function TJclStaticSplitStream.AddVolume(AStream: TStream; AMaxSize: Int64; AOwnStream: Boolean): Integer; -var +Var AVolumeRec: TJclSplitVolume; -begin +Begin AVolumeRec := TJclSplitVolume.Create; AVolumeRec.MaxSize := AMaxSize; AVolumeRec.Stream := AStream; AVolumeRec.OwnStream := AOwnStream; Result := FVolumes.Add(AVolumeRec); -end; -function TJclStaticSplitStream.GetVolume(Index: Integer): TStream; -begin +End; +Function TJclStaticSplitStream.GetVolume(Index: Integer): TStream; +Begin Result := TJclSplitVolume(FVolumes.Items[Index]).Stream; -end; -function TJclStaticSplitStream.GetVolumeCount: Integer; -begin +End; +Function TJclStaticSplitStream.GetVolumeCount: Integer; +Begin Result := FVolumes.Count; -end; -function TJclStaticSplitStream.GetVolumeMaxSize(Index: Integer): Int64; -begin +End; +Function TJclStaticSplitStream.GetVolumeMaxSize(Index: Integer): Int64; +Begin Result := TJclSplitVolume(FVolumes.Items[Index]).MaxSize; -end; +End; //=== { TJclStringStream } ==================================================== -constructor TJclStringStream.Create(AStream: TStream; AOwnsStream: Boolean); -begin - inherited Create; +Constructor TJclStringStream.Create(AStream: TStream; AOwnsStream: Boolean); +Begin + Inherited Create; FStream := AStream; FOwnStream := AOwnsStream; FBufferSize := StreamDefaultBufferSize; @@ -1800,63 +1800,63 @@ constructor TJclStringStream.Create(AStream: TStream; AOwnsStream: Boolean); // This is most useful when AStream is not located at position zero // before being used by us. InvalidateBuffers; -end; -destructor TJclStringStream.Destroy; -begin +End; +Destructor TJclStringStream.Destroy; +Begin Flush; - if FOwnStream then + If FOwnStream Then FStream.Free; - inherited; -end; -procedure TJclStringStream.Flush; -begin - if FStrBufferModifiedSize > 0 then - begin + Inherited; +End; +Procedure TJclStringStream.Flush; +Begin + If FStrBufferModifiedSize > 0 Then + Begin FStream.Position := FStrBufferStart; InternalSetNextBuffer(FStream, FStrBuffer, 0, FStrBufferModifiedSize); FStrBufferNext := FStream.Seek(0, soCurrent); FStrBufferModifiedSize := 0; - end; -end; -function TJclStringStream.InternalGetNextBuffer(S: TStream; - var Buffer: TUCS4Array; Start, Count: SizeInt): Longint; -var + End; +End; +Function TJclStringStream.InternalGetNextBuffer(S: TStream; + Var Buffer: TUCS4Array; Start, Count: SizeInt): Longint; +Var Ch: UCS4; -begin +Begin // override to optimize Result := 0; - while Count > 0 do - begin - if InternalGetNextChar(S, Ch) then - begin + While Count > 0 Do + Begin + If InternalGetNextChar(S, Ch) Then + Begin Buffer[Start] := Ch; Inc(Start); Inc(Result); - end - else + End + Else Break; Dec(Count); - end; -end; -function TJclStringStream.InternalSetNextBuffer(S: TStream; - const Buffer: TUCS4Array; Start, Count: SizeInt): Longint; -begin + End; +End; +Function TJclStringStream.InternalSetNextBuffer(S: TStream; + Const Buffer: TUCS4Array; Start, Count: SizeInt): Longint; +Begin // override to optimize Result := 0; - while Count > 0 do - begin - if InternalSetNextChar(S, Buffer[Start]) then - begin + While Count > 0 Do + Begin + If InternalSetNextChar(S, Buffer[Start]) Then + Begin Inc(Start); Inc(Result); - end - else + End + Else Break; Dec(Count); - end; -end; -procedure TJclStringStream.InvalidateBuffers; -begin + End; +End; +Procedure TJclStringStream.InvalidateBuffers; +Begin FStrBufferStart := FStream.Seek(0, soCurrent); FStrBufferNext := FStrBufferStart; FStrBufferPosition := 0; @@ -1866,26 +1866,26 @@ procedure TJclStringStream.InvalidateBuffers; FStrPeekBufferNext := FStrBufferNext; FStrPeekPosition := 0; FStrPeekBufferCurrentSize := 0; -end; -function TJclStringStream.LoadBuffer: Boolean; -begin +End; +Function TJclStringStream.LoadBuffer: Boolean; +Begin Flush; // first test if the peek buffer contains the value - if (FStrBufferNext >= FStrPeekBufferStart) and (FStrBufferNext < FStrPeekBufferNext) then - begin + If (FStrBufferNext >= FStrPeekBufferStart) and (FStrBufferNext < FStrPeekBufferNext) Then + Begin // the requested buffer is already loaded in the peek buffer FStrBufferStart := FStrPeekBufferStart; FStrBufferNext := FStrPeekBufferNext; - if Length(FStrBuffer) <> Length(FStrPeekBuffer) then + If Length(FStrBuffer) <> Length(FStrPeekBuffer) Then SetLength(FStrBuffer, Length(FStrPeekBuffer)); FStrBufferPosition := FStrPeekBufferPosition; FStrBufferCurrentSize := FStrPeekBufferCurrentSize; Move(FStrPeekBuffer[0], FStrBuffer[0], FStrBufferCurrentSize * SizeOf(FStrBuffer[0])); - end - else - begin + End + Else + Begin // load a new buffer - if Length(FStrBuffer) <> FBufferSize then + If Length(FStrBuffer) <> FBufferSize Then SetLength(FStrBuffer, FBufferSize); Inc(FStrBufferPosition, FStrBufferCurrentSize); FStrBufferStart := FStrBufferNext; @@ -1897,99 +1897,99 @@ function TJclStringStream.LoadBuffer: Boolean; FStrPeekBufferCurrentSize := 0; FStrPeekBufferNext := FStrBufferNext; FStrPeekBufferStart := FStrBufferNext; - end; + End; Result := (FStrPosition >= FStrBufferPosition) and (FStrPosition < (FStrBufferPosition + FStrBufferCurrentSize)); -end; -function TJclStringStream.LoadPeekBuffer: Boolean; -begin - if Length(FStrPeekBuffer) <> FBufferSize then +End; +Function TJclStringStream.LoadPeekBuffer: Boolean; +Begin + If Length(FStrPeekBuffer) <> FBufferSize Then SetLength(FStrPeekBuffer, FBufferSize); - if FStrPeekBufferPosition > FStrPeekPosition then - begin + If FStrPeekBufferPosition > FStrPeekPosition Then + Begin // the peek position is rolling back, load the buffer after the read buffer FStrPeekBufferPosition := FStrBufferPosition; FStrPeekBufferCurrentSize := FStrBufferCurrentSize; FStrPeekBufferStart := FStrBufferStart; FStrPeekBufferNext := FStrBufferNext; - end; + End; FStrPeekBufferStart := FStrPeekBufferNext; Inc(FStrPeekBufferPosition, FStrPeekBufferCurrentSize); FStream.Seek(FStrPeekBufferStart, soBeginning); FStrPeekBufferCurrentSize := InternalGetNextBuffer(FStream, FStrPeekBuffer, 0, FBufferSize); FStrPeekBufferNext := FStream.Seek(0, soCurrent); Result := (FStrPeekPosition >= FStrPeekBufferPosition) and (FStrPeekPosition < (FStrPeekBufferPosition + FStrPeekBufferCurrentSize)); -end; -function TJclStringStream.PeekUCS4(out Buffer: UCS4): Boolean; -begin - if (FStrPeekPosition >= FStrPeekBufferPosition) and (FStrPeekPosition < (FStrPeekBufferPosition + FStrPeekBufferCurrentSize)) then - begin +End; +Function TJclStringStream.PeekUCS4(out Buffer: UCS4): Boolean; +Begin + If (FStrPeekPosition >= FStrPeekBufferPosition) and (FStrPeekPosition < (FStrPeekBufferPosition + FStrPeekBufferCurrentSize)) Then + Begin // read from the peek buffer Result := True; Buffer := FStrPeekBuffer[FStrPeekPosition - FStrPeekBufferPosition]; Inc(FStrPeekPosition); - end - else - if (FStrPeekPosition >= FStrBufferPosition) and (FStrPeekPosition < (FStrBufferPosition + FStrBufferCurrentSize)) then - begin + End + Else + If (FStrPeekPosition >= FStrBufferPosition) and (FStrPeekPosition < (FStrBufferPosition + FStrBufferCurrentSize)) Then + Begin // read from the read/write buffer Result := True; Buffer := FStrBuffer[FStrPeekPosition - FStrBufferPosition]; Inc(FStrPeekPosition); - end - else - begin + End + Else + Begin // load a new peek buffer Result := LoadPeekBuffer; - if Result then - begin + If Result Then + Begin Buffer := FStrPeekBuffer[FStrPeekPosition - FStrPeekBufferPosition]; Inc(FStrPeekPosition); - end; - end; -end; -function TJclStringStream.PeekWideChar(out Buffer: WideChar): Boolean; -var + End; + End; +End; +Function TJclStringStream.PeekWideChar(out Buffer: WideChar): Boolean; +Var Ch: UCS4; -begin +Begin Result := PeekUCS4(Ch); - if Result then + If Result Then Buffer := UCS4ToWideChar(Ch); -end; -function TJclStringStream.ReadUCS4(out Buffer: UCS4): Boolean; -begin - if (FStrPosition >= FStrBufferPosition) and (FStrPosition < (FStrBufferPosition + FStrBufferCurrentSize)) then - begin +End; +Function TJclStringStream.ReadUCS4(out Buffer: UCS4): Boolean; +Begin + If (FStrPosition >= FStrBufferPosition) and (FStrPosition < (FStrBufferPosition + FStrBufferCurrentSize)) Then + Begin // load from buffer Result := True; Buffer := FStrBuffer[FStrPosition - FStrBufferPosition]; Inc(FStrPosition); - end - else - begin + End + Else + Begin // load a new buffer Result := LoadBuffer; - if Result then - begin + If Result Then + Begin Buffer := FStrBuffer[FStrPosition - FStrBufferPosition]; Inc(FStrPosition); - end; - end; + End; + End; FStrPeekPosition := FStrPosition; -end; -function TJclStringStream.ReadWideChar(out Buffer: WideChar): Boolean; -var +End; +Function TJclStringStream.ReadWideChar(out Buffer: WideChar): Boolean; +Var Ch: UCS4; -begin +Begin Result := ReadUCS4(Ch); - if Result then + If Result Then Buffer := UCS4ToWideChar(Ch); -end; -function TJclStringStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; -begin - case Origin of +End; +Function TJclStringStream.Seek(Const Offset: Int64; Origin: TSeekOrigin): Int64; +Begin + Case Origin Of soBeginning: - if Offset = 0 then - begin + If Offset = 0 Then + Begin Flush; FStrPosition := 0; FStrBufferPosition := 0; @@ -2000,186 +2000,186 @@ function TJclStringStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; FStrPeekBufferCurrentSize := 0; FStrPeekBufferStart := 0; FStrPeekBufferNext := 0; - end - else + End + Else raise EJclStreamError.CreateRes(@RsStreamsSeekError); soCurrent: - if Offset <> 0 then + If Offset <> 0 Then raise EJclStreamError.CreateRes(@RsStreamsSeekError); soEnd: raise EJclStreamError.CreateRes(@RsStreamsSeekError); - end; + End; Result := FStrPosition; FStrPeekPosition := FStrPosition; -end; -function TJclStringStream.SkipBOM: Longint; -var +End; +Function TJclStringStream.SkipBOM: Longint; +Var Pos: Int64; I: Integer; - BOM: array of Byte; -begin - if Length(FBOM) > 0 then - begin + BOM: array Of Byte; +Begin + If Length(FBOM) > 0 Then + Begin Pos := FStream.Seek(0, soCurrent); SetLength(BOM, Length(FBOM)); Result := FStream.Read(BOM[0], Length(BOM) * SizeOf(BOM[0])); - if Result = Length(FBOM) * SizeOf(FBOM[0]) then - for I := Low(FBOM) to High(FBOM) do - if BOM[I - Low(FBOM)] <> FBOM[I] then + If Result = Length(FBOM) * SizeOf(FBOM[0]) Then + For I := Low(FBOM) To High(FBOM) Do + If BOM[I - Low(FBOM)] <> FBOM[I] Then Result := 0; - if Result <> Length(FBOM) * SizeOf(FBOM[0]) then + If Result <> Length(FBOM) * SizeOf(FBOM[0]) Then FStream.Seek(Pos, soBeginning); - end - else + End + Else Result := 0; InvalidateBuffers; -end; -function TJclStringStream.WriteBOM: Longint; -begin - if Length(FBOM) > 0 then +End; +Function TJclStringStream.WriteBOM: Longint; +Begin + If Length(FBOM) > 0 Then Result := FStream.Write(FBOM[0], Length(FBOM) * SizeOf(FBOM[0])) - else + Else Result := 0; InvalidateBuffers; -end; -function TJclStringStream.WriteUCS4(Value: UCS4): Boolean; -var +End; +Function TJclStringStream.WriteUCS4(Value: UCS4): Boolean; +Var BufferPos: Int64; -begin - if FStrPosition >= (FStrBufferPosition + FBufferSize) then +Begin + If FStrPosition >= (FStrBufferPosition + FBufferSize) Then // load the next buffer first LoadBuffer; // write to current buffer BufferPos := FStrPosition - FStrBufferPosition; Result := True; - if Length(FStrBuffer) <> FBufferSize then + If Length(FStrBuffer) <> FBufferSize Then SetLength(FStrBuffer, FBufferSize); FStrBuffer[BufferPos] := Value; Inc(FStrPosition); Inc(BufferPos); - if FStrBufferModifiedSize < BufferPos then + If FStrBufferModifiedSize < BufferPos Then FStrBufferModifiedSize := BufferPos; - if FStrBufferCurrentSize < BufferPos then + If FStrBufferCurrentSize < BufferPos Then FStrBufferCurrentSize := BufferPos; FStrPeekPosition := FStrPosition; -end; -function TJclStringStream.WriteWideChar(Value: WideChar): Boolean; -begin +End; +Function TJclStringStream.WriteWideChar(Value: WideChar): Boolean; +Begin Result := WriteUCS4(WideCharToUCS4(Value)); -end; +End; //=== { TJclAnsiStream } ====================================================== -constructor TJclAnsiStream.Create(AStream: TStream; AOwnsStream: Boolean); -begin - inherited Create(AStream, AOwnsStream); +Constructor TJclAnsiStream.Create(AStream: TStream; AOwnsStream: Boolean); +Begin + Inherited Create(AStream, AOwnsStream); SetLength(FBOM, 0); FCodePage := CP_ACP; -end; -constructor TJclUTF8Stream.Create(AStream: TStream; AOwnsStream: Boolean); -var +End; +Constructor TJclUTF8Stream.Create(AStream: TStream; AOwnsStream: Boolean); +Var I: Integer; -begin - inherited Create(AStream, AOwnsStream); +Begin + Inherited Create(AStream, AOwnsStream); SetLength(FBOM, Length(BOM_UTF8)); - for I := Low(BOM_UTF8) to High(BOM_UTF8) do + For I := Low(BOM_UTF8) To High(BOM_UTF8) Do FBOM[I - Low(BOM_UTF8)] := BOM_UTF8[I]; -end; +End; //=== { TJclUTF16Stream } ===================================================== -constructor TJclUTF16Stream.Create(AStream: TStream; AOwnsStream: Boolean); -var +Constructor TJclUTF16Stream.Create(AStream: TStream; AOwnsStream: Boolean); +Var I: Integer; -begin - inherited Create(AStream, AOwnsStream); +Begin + Inherited Create(AStream, AOwnsStream); SetLength(FBOM, Length(BOM_UTF16_LSB)); - for I := Low(BOM_UTF16_LSB) to High(BOM_UTF16_LSB) do + For I := Low(BOM_UTF16_LSB) To High(BOM_UTF16_LSB) Do FBOM[I - Low(BOM_UTF16_LSB)] := BOM_UTF16_LSB[I]; -end; -constructor TJclAutoStream.Create(AStream: TStream; AOwnsStream: Boolean); -var +End; +Constructor TJclAutoStream.Create(AStream: TStream; AOwnsStream: Boolean); +Var I, MaxLength, ReadLength: Integer; - BOM: array of Byte; -begin - inherited Create(AStream, AOwnsStream); + BOM: array Of Byte; +Begin + Inherited Create(AStream, AOwnsStream); MaxLength := Length(BOM_UTF8); - if MaxLength < Length(BOM_UTF16_LSB) then + If MaxLength < Length(BOM_UTF16_LSB) Then MaxLength := Length(BOM_UTF16_LSB); SetLength(BOM, MaxLength); ReadLength := FStream.Read(BOM[0], Length(BOM) * SizeOf(BOM[0])) div SizeOf(BOM[0]); FEncoding := seAuto; // try UTF8 BOM - if (FEncoding = seAuto) and (ReadLength >= Length(BOM_UTF8) * SizeOf(BOM_UTF8[0])) then - begin + If (FEncoding = seAuto) and (ReadLength >= Length(BOM_UTF8) * SizeOf(BOM_UTF8[0])) Then + Begin FCodePage := CP_UTF8; FEncoding := seUTF8; - for I := Low(BOM_UTF8) to High(BOM_UTF8) do - if BOM[I - Low(BOM_UTF8)] <> BOM_UTF8[I] then - begin + For I := Low(BOM_UTF8) To High(BOM_UTF8) Do + If BOM[I - Low(BOM_UTF8)] <> BOM_UTF8[I] Then + Begin FEncoding := seAuto; Break; - end; - end; + End; + End; // try UTF16 BOM - if (FEncoding = seAuto) and (ReadLength >= Length(BOM_UTF16_LSB) * SizeOf(BOM_UTF16_LSB[0])) then - begin + If (FEncoding = seAuto) and (ReadLength >= Length(BOM_UTF16_LSB) * SizeOf(BOM_UTF16_LSB[0])) Then + Begin FCodePage := CP_UTF16LE; FEncoding := seUTF16; - for I := Low(BOM_UTF16_LSB) to High(BOM_UTF16_LSB) do - if BOM[I - Low(BOM_UTF8)] <> BOM_UTF16_LSB[I] then - begin + For I := Low(BOM_UTF16_LSB) To High(BOM_UTF16_LSB) Do + If BOM[I - Low(BOM_UTF8)] <> BOM_UTF16_LSB[I] Then + Begin FEncoding := seAuto; Break; - end; - end; - case FEncoding of + End; + End; + Case FEncoding Of seUTF8: - begin + Begin FCodePage := CP_UTF8; SetLength(FBOM, Length(BOM_UTF8)); - for I := Low(BOM_UTF8) to High(BOM_UTF8) do + For I := Low(BOM_UTF8) To High(BOM_UTF8) Do FBOM[I - Low(BOM_UTF8)] := BOM_UTF8[I]; - end; + End; seUTF16: - begin + Begin FCodePage := CP_UTF16LE; SetLength(FBOM, Length(BOM_UTF16_LSB)); - for I := Low(BOM_UTF16_LSB) to High(BOM_UTF16_LSB) do + For I := Low(BOM_UTF16_LSB) To High(BOM_UTF16_LSB) Do FBOM[I - Low(BOM_UTF16_LSB)] := BOM_UTF16_LSB[I]; - end; + End; seAuto, seAnsi: - begin + Begin // defaults to Ansi FCodePage := CP_ACP; FEncoding := seAnsi; SetLength(FBOM, 0); - end; - end; + End; + End; FStream.Seek(Length(FBOM) - ReadLength, soCurrent); InvalidateBuffers; -end; -procedure TJclAutoStream.SetCodePage(Value: Word); -begin - if Value = CP_UTF8 then +End; +Procedure TJclAutoStream.SetCodePage(Value: Word); +Begin + If Value = CP_UTF8 Then FEncoding := seUTF8 - else - if Value = CP_UTF16LE then + Else + If Value = CP_UTF16LE Then FEncoding := seUTF16 - else - if Value = CP_ACP then + Else + If Value = CP_ACP Then FEncoding := seAnsi - else + Else FEncoding := seAuto; FCodePage := Value; -end; -function TJclAutoStream.SkipBOM: LongInt; -begin +End; +Function TJclAutoStream.SkipBOM: LongInt; +Begin // already skipped to determine encoding Result := 0; InvalidateBuffers; -end; +End; {$IFDEF UNITVERSIONING} -initialization - RegisterUnitVersion(HInstance, UnitVersioning); -finalization - UnregisterUnitVersion(HInstance); +Initialization + RegisterUnitVersion(HInstance, UnitVersioning); +Finalization + UnregisterUnitVersion(HInstance); {$ENDIF UNITVERSIONING} -end. +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemStringConversions.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemStringConversions.pas index 981454887..3eb4a3a22 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemStringConversions.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemStringConversions.pas @@ -1,20 +1,20 @@ -unit uRESTDWMemStringConversions; -{$I ..\..\Includes\uRESTDW.inc} +Unit uRESTDWMemStringConversions; +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -26,8 +26,8 @@ {$ASMMode Intel} {$ENDIF} -interface -uses +Interface +Uses {$IFDEF HAS_UNITSCOPE} System.Classes, {$ELSE ~HAS_UNITSCOPE} @@ -35,44 +35,44 @@ interface {$ENDIF ~HAS_UNITSCOPE} uRESTDWMemBase, uRESTDWPrototypes; -type - EJclStringConversionError = class(EJclError); - EJclUnexpectedEOSequenceError = class (EJclStringConversionError) - public - constructor Create; - end; -type - TJclStreamGetNextCharFunc = function(S: TStream; out Ch: UCS4): Boolean; - TJclStreamSkipCharsFunc = function(S: TStream; var NbSeq: SizeInt): Boolean; - TJclStreamSetNextCharFunc = function(S: TStream; Ch: UCS4): Boolean; -function UTF8SetNextChar(var S: TUTF8String; var StrPos: SizeInt; Ch: UCS4): Boolean; -function UTF8SetNextBuffer(var S: TUTF8String; var StrPos: SizeInt; const Buffer: TUCS4Array; var Start: SizeInt; Count: SizeInt): SizeInt; -function UTF8SetNextCharToStream(S: TStream; Ch: UCS4): Boolean; -function UTF8SetNextBufferToStream(S: TStream; const Buffer: TUCS4Array; var Start: SizeInt; Count: SizeInt): SizeInt; -function AnsiSkipChars(const S: DWString; var StrPos: SizeInt; var NbSeq: SizeInt): Boolean; -function AnsiSkipCharsFromStream(S: TStream; var NbSeq: SizeInt): Boolean; -function StringSkipChars(const S: string; var StrPos: SizeInt; var NbSeq: SizeInt): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Type + EJclStringConversionError = Class(EJclError); + EJclUnexpectedEOSequenceError = Class (EJclStringConversionError) + Public + Constructor Create; + End; +Type + TJclStreamGetNextCharFunc = Function(S: TStream; out Ch: UCS4): Boolean; + TJclStreamSkipCharsFunc = Function(S: TStream; Var NbSeq: SizeInt): Boolean; + TJclStreamSetNextCharFunc = Function(S: TStream; Ch: UCS4): Boolean; +Function UTF8SetNextChar(Var S: TUTF8String; Var StrPos: SizeInt; Ch: UCS4): Boolean; +Function UTF8SetNextBuffer(Var S: TUTF8String; Var StrPos: SizeInt; Const Buffer: TUCS4Array; Var Start: SizeInt; Count: SizeInt): SizeInt; +Function UTF8SetNextCharToStream(S: TStream; Ch: UCS4): Boolean; +Function UTF8SetNextBufferToStream(S: TStream; Const Buffer: TUCS4Array; Var Start: SizeInt; Count: SizeInt): SizeInt; +Function AnsiSkipChars(Const S: DWString; Var StrPos: SizeInt; Var NbSeq: SizeInt): Boolean; +Function AnsiSkipCharsFromStream(S: TStream; Var NbSeq: SizeInt): Boolean; +Function StringSkipChars(Const S: string; Var StrPos: SizeInt; Var NbSeq: SizeInt): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} // one shot conversions between DWString and others -function DWStringToUTF16(const S: DWString): TUTF16String; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE} -function UTF16ToAnsiString(const S: TUTF16String): DWString; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE} +Function DWStringToUTF16(Const S: DWString): TUTF16String; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE} +Function UTF16ToAnsiString(Const S: TUTF16String): DWString; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE} // one shot conversions between string and others -function StringToUTF16(const S: string): TUTF16String; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE} -function UTF16ToString(const S: TUTF16String): string; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE} -function TryStringToUTF16(const S: string; out D: TUTF16String): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE} -function TryUTF16ToString(const S: TUTF16String; out D: string): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE} -function UCS4ToUTF8(const S: TUCS4Array): TUTF8String; +Function StringToUTF16(Const S: string): TUTF16String; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE} +Function UTF16ToString(Const S: TUTF16String): string; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE} +Function TryStringToUTF16(Const S: string; out D: TUTF16String): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE} +Function TryUTF16ToString(Const S: TUTF16String; out D: string): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE} +Function UCS4ToUTF8(Const S: TUCS4Array): TUTF8String; // indexed conversions -function UTF8CharCount(const S: TUTF8String): SizeInt; -function UTF16CharCount(const S: TUTF16String): SizeInt; -function UCS2CharCount(const S: TUCS2String): SizeInt; -function UCS4CharCount(const S: TUCS4Array): SizeInt; +Function UTF8CharCount(Const S: TUTF8String): SizeInt; +Function UTF16CharCount(Const S: TUTF16String): SizeInt; +Function UCS2CharCount(Const S: TUCS2String): SizeInt; +Function UCS4CharCount(Const S: TUCS4Array): SizeInt; // returns False if string is too small // if UNICODE_SILENT_FAILURE is not defined and an invalid UTFX sequence is detected, an exception is raised // returns True on success and Value contains UCS4 character that was read -function UCS4ToWideChar(Value: UCS4): WideChar; -function WideCharToUCS4(Value: WideChar): UCS4; -implementation -uses +Function UCS4ToWideChar(Value: UCS4): WideChar; +Function WideCharToUCS4(Value: WideChar): UCS4; +Implementation +Uses {$IFDEF HAS_UNITSCOPE} {$IFDEF MSWINDOWS} Winapi.Windows, @@ -83,728 +83,728 @@ implementation {$ENDIF MSWINDOWS} {$ENDIF ~HAS_UNITSCOPE} uRESTDWMemResources; -const MB_ERR_INVALID_CHARS = 8; -constructor EJclUnexpectedEOSequenceError.Create; -begin - inherited CreateRes(@RsEUnexpectedEOSeq); -end; -function StreamReadByte(S: TStream; out B: Byte): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -begin +Const MB_ERR_INVALID_CHARS = 8; +Constructor EJclUnexpectedEOSequenceError.Create; +Begin + Inherited CreateRes(@RsEUnexpectedEOSeq); +End; +Function StreamReadByte(S: TStream; out B: Byte): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Begin B := 0; Result := S.Read(B, SizeOf(B)) = SizeOf(B); -end; -function StreamWriteByte(S: TStream; B: Byte): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -begin +End; +Function StreamWriteByte(S: TStream; B: Byte): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Begin Result := S.Write(B, SizeOf(B)) = SizeOf(B); -end; -function StreamReadWord(S: TStream; out W: Word): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -begin +End; +Function StreamReadWord(S: TStream; out W: Word): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Begin W := 0; Result := S.Read(W, SizeOf(W)) = SizeOf(W); -end; -function StreamWriteWord(S: TStream; W: Word): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -begin +End; +Function StreamWriteWord(S: TStream; W: Word): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Begin Result := S.Write(W, SizeOf(W)) = SizeOf(W); -end; -procedure FlagInvalidSequence(var StrPos: SizeInt; Increment: SizeInt); overload; -begin +End; +Procedure FlagInvalidSequence(Var StrPos: SizeInt; Increment: SizeInt); overload; +Begin {$IFDEF UNICODE_SILENT_FAILURE} Inc(StrPos, Increment); {$ELSE ~UNICODE_SILENT_FAILURE} StrPos := -1; {$ENDIF ~UNICODE_SILENT_FAILURE} -end; -procedure FlagInvalidSequence(out Ch: UCS4); overload; -begin +End; +Procedure FlagInvalidSequence(out Ch: UCS4); overload; +Begin {$IFDEF UNICODE_SILENT_FAILURE} Ch := UCS4ReplacementCharacter; {$ELSE ~UNICODE_SILENT_FAILURE} raise EJclUnexpectedEOSequenceError.Create; {$ENDIF ~UNICODE_SILENT_FAILURE} -end; -procedure FlagInvalidSequence; overload; -begin +End; +Procedure FlagInvalidSequence; overload; +Begin {$IFNDEF UNICODE_SILENT_FAILURE} raise EJclUnexpectedEOSequenceError.Create; {$ENDIF ~UNICODE_SILENT_FAILURE} -end; -function UTF8GetNextCharFromStream(S: TStream; out Ch: UCS4): Boolean; -var +End; +Function UTF8GetNextCharFromStream(S: TStream; out Ch: UCS4): Boolean; +Var B: Byte; -begin +Begin Result := StreamReadByte(S,B); - if Result then - begin + If Result Then + Begin Ch := UCS4(B); - case Ch of + Case Ch Of $00..$7F: ; // 1 byte to read // nothing to do $C0..$DF: - begin + Begin // 2 bytes to read Result := StreamReadByte(S,B); - if Result then - begin - if (B and $C0) = $80 then + If Result Then + Begin + If (B and $C0) = $80 Then Ch := ((Ch and $1F) shl 6) or (B and $3F) - else + Else FlagInvalidSequence(Ch); - end; - end; + End; + End; $E0..$EF: - begin + Begin // 3 bytes to read Result := StreamReadByte(S,B); - if Result then - begin - if (B and $C0) = $80 then - begin + If Result Then + Begin + If (B and $C0) = $80 Then + Begin Ch := ((Ch and $0F) shl 12) or ((B and $3F) shl 6); Result := StreamReadByte(S,B); - if Result then - begin - if (B and $C0) = $80 then + If Result Then + Begin + If (B and $C0) = $80 Then Ch := Ch or (B and $3F) - else + Else FlagInvalidSequence(Ch); - end; - end - else + End; + End + Else FlagInvalidSequence(Ch); - end; - end; + End; + End; $F0..$F7: - begin + Begin // 4 bytes to read Result := StreamReadByte(S,B); - if Result then - begin - if (B and $C0) = $80 then - begin + If Result Then + Begin + If (B and $C0) = $80 Then + Begin Ch := ((Ch and $07) shl 18) or ((B and $3F) shl 12); Result := StreamReadByte(S,B); - if Result then - begin - if (B and $C0) = $80 then - begin + If Result Then + Begin + If (B and $C0) = $80 Then + Begin Ch := Ch or ((B and $3F) shl 6); Result := StreamReadByte(S,B); - if Result then - begin - if (B and $C0) = $80 then + If Result Then + Begin + If (B and $C0) = $80 Then Ch := Ch or (B and $3F) - else + Else FlagInvalidSequence(Ch); - end; - end - else + End; + End + Else FlagInvalidSequence(Ch); - end; - end - else + End; + End + Else FlagInvalidSequence(Ch); - end; - end; + End; + End; $F8..$FB: - begin + Begin // 5 bytes to read Result := StreamReadByte(S,B); - if Result then - begin - if (B and $C0) = $80 then - begin + If Result Then + Begin + If (B and $C0) = $80 Then + Begin Ch := ((Ch and $03) shl 24) or ((B and $3F) shl 18); Result := StreamReadByte(S,B); - if Result then - begin - if (B and $C0) = $80 then - begin + If Result Then + Begin + If (B and $C0) = $80 Then + Begin Ch := Ch or ((B and $3F) shl 12); Result := StreamReadByte(S,B); - if Result then - begin - if (B and $C0) = $80 then - begin + If Result Then + Begin + If (B and $C0) = $80 Then + Begin Ch := Ch or ((B and $3F) shl 6); Result := StreamReadByte(S,B); - if Result then - begin - if (B and $C0) = $80 then + If Result Then + Begin + If (B and $C0) = $80 Then Ch := Ch or (B and $3F) - else + Else FlagInvalidSequence(Ch); - end; - end - else + End; + End + Else FlagInvalidSequence(Ch); - end; - end - else + End; + End + Else FlagInvalidSequence(Ch); - end; - end - else + End; + End + Else FlagInvalidSequence(Ch); - end; - end; + End; + End; $FC..$FD: - begin + Begin // 6 bytes to read Result := StreamReadByte(S,B); - if Result then - begin - if (B and $C0) = $80 then - begin + If Result Then + Begin + If (B and $C0) = $80 Then + Begin Ch := ((Ch and $01) shl 30) or ((B and $3F) shl 24); Result := StreamReadByte(S,B); - if Result then - begin - if (B and $C0) = $80 then - begin + If Result Then + Begin + If (B and $C0) = $80 Then + Begin Ch := Ch or ((B and $3F) shl 18); Result := StreamReadByte(S,B); - if Result then - begin - if (B and $C0) = $80 then - begin + If Result Then + Begin + If (B and $C0) = $80 Then + Begin Ch := Ch or ((B and $3F) shl 12); Result := StreamReadByte(S,B); - if Result then - begin - if (B and $C0) = $80 then - begin + If Result Then + Begin + If (B and $C0) = $80 Then + Begin Ch := Ch or ((B and $3F) shl 6); Result := StreamReadByte(S,B); - if Result then - begin - if (B and $C0) = $80 then + If Result Then + Begin + If (B and $C0) = $80 Then Ch := Ch or (B and $3F) - else + Else FlagInvalidSequence(Ch); - end; - end - else + End; + End + Else FlagInvalidSequence(Ch); - end; - end - else + End; + End + Else FlagInvalidSequence(Ch); - end; - end - else + End; + End + Else FlagInvalidSequence(Ch); - end; - end - else + End; + End + Else FlagInvalidSequence(Ch); - end; - end; - else + End; + End; + Else FlagInvalidSequence(Ch); - end; - end; -end; -function UTF8GetNextBufferFromStream(S: TStream; var Buffer: TUCS4Array; var Start: SizeInt; Count: SizeInt): SizeInt; -var + End; + End; +End; +Function UTF8GetNextBufferFromStream(S: TStream; Var Buffer: TUCS4Array; Var Start: SizeInt; Count: SizeInt): SizeInt; +Var B: Byte; Ch: UCS4; ReadSuccess: Boolean; -begin +Begin Result := 0; ReadSuccess := True; - while ReadSuccess and (Count > 0) do - begin - if StreamReadByte(S,B) then - begin + While ReadSuccess and (Count > 0) Do + Begin + If StreamReadByte(S,B) Then + Begin Ch := UCS4(B); - case Ch of + Case Ch Of $00..$7F: ; // 1 byte to read // nothing to do $C0..$DF: - begin + Begin // 2 bytes to read - if StreamReadByte(S,B) then - begin - if (B and $C0) = $80 then + If StreamReadByte(S,B) Then + Begin + If (B and $C0) = $80 Then Ch := ((Ch and $1F) shl 6) or (B and $3F) - else + Else FlagInvalidSequence(Ch); - end - else + End + Else ReadSuccess := False; - end; + End; $E0..$EF: - begin + Begin // 3 bytes to read - if StreamReadByte(S,B) then - begin - if (B and $C0) = $80 then - begin + If StreamReadByte(S,B) Then + Begin + If (B and $C0) = $80 Then + Begin Ch := ((Ch and $0F) shl 12) or ((B and $3F) shl 6); - if StreamReadByte(S,B) then - begin - if (B and $C0) = $80 then + If StreamReadByte(S,B) Then + Begin + If (B and $C0) = $80 Then Ch := Ch or (B and $3F) - else + Else FlagInvalidSequence(Ch); - end - else + End + Else ReadSuccess := False; - end - else + End + Else FlagInvalidSequence(Ch); - end - else + End + Else ReadSuccess := False; - end; + End; $F0..$F7: - begin + Begin // 4 bytes to read - if StreamReadByte(S,B) then - begin - if (B and $C0) = $80 then - begin + If StreamReadByte(S,B) Then + Begin + If (B and $C0) = $80 Then + Begin Ch := ((Ch and $07) shl 18) or ((B and $3F) shl 12); - if StreamReadByte(S,B) then - begin - if (B and $C0) = $80 then - begin + If StreamReadByte(S,B) Then + Begin + If (B and $C0) = $80 Then + Begin Ch := Ch or ((B and $3F) shl 6); - if StreamReadByte(S,B) then - begin - if (B and $C0) = $80 then + If StreamReadByte(S,B) Then + Begin + If (B and $C0) = $80 Then Ch := Ch or (B and $3F) - else + Else FlagInvalidSequence(Ch); - end - else + End + Else ReadSuccess := False; - end - else + End + Else FlagInvalidSequence(Ch); - end - else + End + Else ReadSuccess := False; - end - else + End + Else FlagInvalidSequence(Ch); - end - else + End + Else ReadSuccess := False; - end; + End; $F8..$FB: - begin + Begin // 5 bytes to read - if StreamReadByte(S,B) then - begin - if (B and $C0) = $80 then - begin + If StreamReadByte(S,B) Then + Begin + If (B and $C0) = $80 Then + Begin Ch := ((Ch and $03) shl 24) or ((B and $3F) shl 18); - if StreamReadByte(S,B) then - begin - if (B and $C0) = $80 then - begin + If StreamReadByte(S,B) Then + Begin + If (B and $C0) = $80 Then + Begin Ch := Ch or ((B and $3F) shl 12); - if StreamReadByte(S,B) then - begin - if (B and $C0) = $80 then - begin + If StreamReadByte(S,B) Then + Begin + If (B and $C0) = $80 Then + Begin Ch := Ch or ((B and $3F) shl 6); - if StreamReadByte(S,B) then - begin - if (B and $C0) = $80 then + If StreamReadByte(S,B) Then + Begin + If (B and $C0) = $80 Then Ch := Ch or (B and $3F) - else + Else FlagInvalidSequence(Ch); - end - else + End + Else ReadSuccess := False; - end - else + End + Else FlagInvalidSequence(Ch); - end - else + End + Else ReadSuccess := False; - end - else + End + Else FlagInvalidSequence(Ch); - end - else + End + Else ReadSuccess := False; - end - else + End + Else FlagInvalidSequence(Ch); - end - else + End + Else ReadSuccess := False; - end; + End; $FC..$FD: - begin + Begin // 6 bytes to read - if StreamReadByte(S,B) then - begin - if (B and $C0) = $80 then - begin + If StreamReadByte(S,B) Then + Begin + If (B and $C0) = $80 Then + Begin Ch := ((Ch and $01) shl 30) or ((B and $3F) shl 24); - if StreamReadByte(S,B) then - begin - if (B and $C0) = $80 then - begin + If StreamReadByte(S,B) Then + Begin + If (B and $C0) = $80 Then + Begin Ch := Ch or ((B and $3F) shl 18); - if StreamReadByte(S,B) then - begin - if (B and $C0) = $80 then - begin + If StreamReadByte(S,B) Then + Begin + If (B and $C0) = $80 Then + Begin Ch := Ch or ((B and $3F) shl 12); - if StreamReadByte(S,B) then - begin - if (B and $C0) = $80 then - begin + If StreamReadByte(S,B) Then + Begin + If (B and $C0) = $80 Then + Begin Ch := Ch or ((B and $3F) shl 6); - if StreamReadByte(S,B) then - begin - if (B and $C0) = $80 then + If StreamReadByte(S,B) Then + Begin + If (B and $C0) = $80 Then Ch := Ch or (B and $3F) - else + Else FlagInvalidSequence(Ch); - end - else + End + Else ReadSuccess := False; - end - else + End + Else FlagInvalidSequence(Ch); - end - else + End + Else ReadSuccess := False; - end - else + End + Else FlagInvalidSequence(Ch); - end - else + End + Else ReadSuccess := False; - end - else + End + Else FlagInvalidSequence(Ch); - end - else + End + Else ReadSuccess := False; - end - else + End + Else FlagInvalidSequence(Ch); - end - else + End + Else ReadSuccess := False; - end - else + End + Else FlagInvalidSequence(Ch); - end; - if ReadSuccess then - begin + End; + If ReadSuccess Then + Begin Buffer[Start] := Ch; Inc(Start); Inc(Result); - end; - end - else + End; + End + Else ReadSuccess := False; Dec(Count); - end; -end; + End; +End; // returns False if String is too small // if UNICODE_SILENT_FAILURE is not defined StrPos is set to -1 on error (invalid UTF8 sequence) // StrPos will be incremented by the number of ansi chars that were skipped // On return, NbSeq contains the number of UTF8 sequences that were skipped -function UTF8SkipChars(const S: TUTF8String; var StrPos: SizeInt; var NbSeq: SizeInt): Boolean; -var +Function UTF8SkipChars(Const S: TUTF8String; Var StrPos: SizeInt; Var NbSeq: SizeInt): Boolean; +Var StrLength: SizeInt; Ch: UCS4; Index: SizeInt; -begin +Begin Result := True; StrLength := Length(S); Index := 0; - while (Index < NbSeq) and (StrPos > 0) do - begin + While (Index < NbSeq) and (StrPos > 0) Do + Begin Ch := UCS4(S[StrPos]); - case Ch of + Case Ch Of $00..$7F: // 1 byte to skip Inc(StrPos); $C0..$DF: // 2 bytes to skip - if (StrPos >= StrLength) or ((UCS4(S[StrPos + 1]) and $C0) <> $80) then + If (StrPos >= StrLength) or ((UCS4(S[StrPos + 1]) and $C0) <> $80) Then FlagInvalidSequence(StrPos, 1) - else + Else Inc(StrPos, 2); $E0..$EF: // 3 bytes to skip - if ((StrPos + 1) >= StrLength) or ((UCS4(S[StrPos + 1]) and $C0) <> $80) then + If ((StrPos + 1) >= StrLength) or ((UCS4(S[StrPos + 1]) and $C0) <> $80) Then FlagInvalidSequence(StrPos, 1) - else - if (UCS4(S[StrPos + 2]) and $C0) <> $80 then + Else + If (UCS4(S[StrPos + 2]) and $C0) <> $80 Then FlagInvalidSequence(StrPos, 2) - else + Else Inc(StrPos, 3); $F0..$F7: // 4 bytes to skip - if ((StrPos + 2) >= StrLength) or ((UCS4(S[StrPos + 1]) and $C0) <> $80) then + If ((StrPos + 2) >= StrLength) or ((UCS4(S[StrPos + 1]) and $C0) <> $80) Then FlagInvalidSequence(StrPos, 1) - else - if (UCS4(S[StrPos + 2]) and $C0) <> $80 then + Else + If (UCS4(S[StrPos + 2]) and $C0) <> $80 Then FlagInvalidSequence(StrPos, 2) - else - if (UCS4(S[StrPos + 3]) and $C0) <> $80 then + Else + If (UCS4(S[StrPos + 3]) and $C0) <> $80 Then FlagInvalidSequence(StrPos, 3) - else + Else Inc(StrPos, 4); $F8..$FB: // 5 bytes to skip - if ((StrPos + 3) >= StrLength) or ((UCS4(S[StrPos + 1]) and $C0) <> $80) then + If ((StrPos + 3) >= StrLength) or ((UCS4(S[StrPos + 1]) and $C0) <> $80) Then FlagInvalidSequence(StrPos, 1) - else - if (UCS4(S[StrPos + 2]) and $C0) <> $80 then + Else + If (UCS4(S[StrPos + 2]) and $C0) <> $80 Then FlagInvalidSequence(StrPos, 2) - else - if (UCS4(S[StrPos + 3]) and $C0) <> $80 then + Else + If (UCS4(S[StrPos + 3]) and $C0) <> $80 Then FlagInvalidSequence(StrPos, 3) - else - if (UCS4(S[StrPos + 4]) and $C0) <> $80 then + Else + If (UCS4(S[StrPos + 4]) and $C0) <> $80 Then FlagInvalidSequence(StrPos, 4) - else + Else Inc(StrPos, 5); $FC..$FD: // 6 bytes to skip - if ((StrPos + 4) >= StrLength) or ((UCS4(S[StrPos + 1]) and $C0) <> $80) then + If ((StrPos + 4) >= StrLength) or ((UCS4(S[StrPos + 1]) and $C0) <> $80) Then FlagInvalidSequence(StrPos, 1) - else - if (UCS4(S[StrPos + 2]) and $C0) <> $80 then + Else + If (UCS4(S[StrPos + 2]) and $C0) <> $80 Then FlagInvalidSequence(StrPos, 2) - else - if (UCS4(S[StrPos + 3]) and $C0) <> $80 then + Else + If (UCS4(S[StrPos + 3]) and $C0) <> $80 Then FlagInvalidSequence(StrPos, 3) - else - if (UCS4(S[StrPos + 4]) and $C0) <> $80 then + Else + If (UCS4(S[StrPos + 4]) and $C0) <> $80 Then FlagInvalidSequence(StrPos, 4) - else - if (UCS4(S[StrPos + 5]) and $C0) <> $80 then + Else + If (UCS4(S[StrPos + 5]) and $C0) <> $80 Then FlagInvalidSequence(StrPos, 5) - else + Else Inc(StrPos, 6); - else + Else FlagInvalidSequence(StrPos, 1); - end; - if StrPos <> -1 then + End; + If StrPos <> -1 Then Inc(Index); - if (StrPos > StrLength) and (Index < NbSeq) then - begin + If (StrPos > StrLength) and (Index < NbSeq) Then + Begin Result := False; Break; - end; - end; + End; + End; NbSeq := Index; -end; -function UTF8SkipCharsFromStream(S: TStream; var NbSeq: SizeInt): Boolean; -var +End; +Function UTF8SkipCharsFromStream(S: TStream; Var NbSeq: SizeInt): Boolean; +Var B: Byte; Index: SizeInt; -begin +Begin Index := 0; - while (Index < NbSeq) do - begin + While (Index < NbSeq) Do + Begin Result := StreamReadByte(S, B); - if not Result then + If not Result Then Break; - case B of + Case B Of $00..$7F: ; // 1 byte to skip // nothing to do $C0..$DF: // 2 bytes to skip - begin + Begin Result := StreamReadByte(S, B); - if not Result then + If not Result Then Break; - if (B and $C0) <> $80 then + If (B and $C0) <> $80 Then FlagInvalidSequence; - end; + End; $E0..$EF: // 3 bytes to skip - begin + Begin Result := StreamReadByte(S, B); - if not Result then + If not Result Then Break; - if (B and $C0) <> $80 then + If (B and $C0) <> $80 Then FlagInvalidSequence; Result := StreamReadByte(S, B); - if not Result then + If not Result Then Break; - if (B and $C0) <> $80 then + If (B and $C0) <> $80 Then FlagInvalidSequence; - end; + End; $F0..$F7: // 4 bytes to skip - begin + Begin Result := StreamReadByte(S, B); - if not Result then + If not Result Then Break; - if (B and $C0) <> $80 then + If (B and $C0) <> $80 Then FlagInvalidSequence; Result := StreamReadByte(S, B); - if not Result then + If not Result Then Break; - if (B and $C0) <> $80 then + If (B and $C0) <> $80 Then FlagInvalidSequence; Result := StreamReadByte(S, B); - if not Result then + If not Result Then Break; - if (B and $C0) <> $80 then + If (B and $C0) <> $80 Then FlagInvalidSequence; - end; + End; $F8..$FB: // 5 bytes to skip - begin + Begin Result := StreamReadByte(S, B); - if not Result then + If not Result Then Break; - if (B and $C0) <> $80 then + If (B and $C0) <> $80 Then FlagInvalidSequence; Result := StreamReadByte(S, B); - if not Result then + If not Result Then Break; - if (B and $C0) <> $80 then + If (B and $C0) <> $80 Then FlagInvalidSequence; Result := StreamReadByte(S, B); - if not Result then + If not Result Then Break; - if (B and $C0) <> $80 then + If (B and $C0) <> $80 Then FlagInvalidSequence; Result := StreamReadByte(S, B); - if not Result then + If not Result Then Break; - if (B and $C0) <> $80 then + If (B and $C0) <> $80 Then FlagInvalidSequence; - end; + End; $FC..$FD: // 6 bytes to skip - begin + Begin Result := StreamReadByte(S, B); - if not Result then + If not Result Then Break; - if (B and $C0) <> $80 then + If (B and $C0) <> $80 Then FlagInvalidSequence; Result := StreamReadByte(S, B); - if not Result then + If not Result Then Break; - if (B and $C0) <> $80 then + If (B and $C0) <> $80 Then FlagInvalidSequence; Result := StreamReadByte(S, B); - if not Result then + If not Result Then Break; - if (B and $C0) <> $80 then + If (B and $C0) <> $80 Then FlagInvalidSequence; Result := StreamReadByte(S, B); - if not Result then + If not Result Then Break; - if (B and $C0) <> $80 then + If (B and $C0) <> $80 Then FlagInvalidSequence; Result := StreamReadByte(S, B); - if not Result then + If not Result Then Break; - if (B and $C0) <> $80 then + If (B and $C0) <> $80 Then FlagInvalidSequence; - end; - else + End; + Else FlagInvalidSequence; - end; + End; Inc(Index); - end; + End; Result := Index = NbSeq; NbSeq := Index; -end; +End; // returns False on error: // - if an UCS4 character cannot be stored to an UTF-8 string: // - if UNICODE_SILENT_FAILURE is defined, ReplacementCharacter is added // - if UNICODE_SILENT_FAILURE is not defined, StrPos is set to -1 // - StrPos > -1 flags string being too small, caller is responsible for allocating space // StrPos will be incremented by the number of chars that were written -function UTF8SetNextChar(var S: TUTF8String; var StrPos: SizeInt; Ch: UCS4): Boolean; -var +Function UTF8SetNextChar(Var S: TUTF8String; Var StrPos: SizeInt; Ch: UCS4): Boolean; +Var StrLength: SizeInt; -begin +Begin StrLength := Length(S); - if Ch <= $7F then - begin + If Ch <= $7F Then + Begin // 7 bits to store Result := (StrPos > 0) and (StrPos <= StrLength); - if Result then - begin + If Result Then + Begin PDWString(@S[StrPos])^ := DWChar(Ch); Inc(StrPos); - end; - end - else - if Ch <= $7FF then - begin + End; + End + Else + If Ch <= $7FF Then + Begin // 11 bits to store Result := (StrPos > 0) and (StrPos < StrLength); - if Result then - begin + If Result Then + Begin PDWString(@S[StrPos])^ := DWChar($C0 or (Ch shr 6)); // 5 bits PDWString(@S[StrPos + 1])^ := DWChar((Ch and $3F) or $80); // 6 bits Inc(StrPos, 2); - end; - end - else - if Ch <= $FFFF then - begin + End; + End + Else + If Ch <= $FFFF Then + Begin // 16 bits to store Result := (StrPos > 0) and (StrPos < (StrLength - 1)); - if Result then - begin + If Result Then + Begin PDWString(@S[StrPos])^ := DWChar($E0 or (Ch shr 12)); // 4 bits PDWString(@S[StrPos + 1])^ := DWChar(((Ch shr 6) and $3F) or $80); // 6 bits PDWString(@S[StrPos + 2])^ := DWChar((Ch and $3F) or $80); // 6 bits Inc(StrPos, 3); - end; - end - else - if Ch <= $1FFFFF then - begin + End; + End + Else + If Ch <= $1FFFFF Then + Begin // 21 bits to store Result := (StrPos > 0) and (StrPos < (StrLength - 2)); - if Result then - begin + If Result Then + Begin PDWString(@S[StrPos])^ := DWChar($F0 or (Ch shr 18)); // 3 bits PDWString(@S[StrPos + 1])^ := DWChar(((Ch shr 12) and $3F) or $80); // 6 bits PDWString(@S[StrPos + 2])^ := DWChar(((Ch shr 6) and $3F) or $80); // 6 bits PDWString(@S[StrPos + 3])^ := DWChar((Ch and $3F) or $80); // 6 bits Inc(StrPos, 4); - end; - end - else - if Ch <= $3FFFFFF then - begin + End; + End + Else + If Ch <= $3FFFFFF Then + Begin // 26 bits to store Result := (StrPos > 0) and (StrPos < (StrLength - 2)); - if Result then - begin + If Result Then + Begin PDWString(@S[StrPos])^ := DWChar($F8 or (Ch shr 24)); // 2 bits PDWString(@S[StrPos + 1])^ := DWChar(((Ch shr 18) and $3F) or $80); // 6 bits PDWString(@S[StrPos + 2])^ := DWChar(((Ch shr 12) and $3F) or $80); // 6 bits PDWString(@S[StrPos + 3])^ := DWChar(((Ch shr 6) and $3F) or $80); // 6 bits PDWString(@S[StrPos + 4])^ := DWChar((Ch and $3F) or $80); // 6 bits Inc(StrPos, 5); - end; - end - else - if Ch <= MaximumUCS4 then - begin + End; + End + Else + If Ch <= MaximumUCS4 Then + Begin // 31 bits to store Result := (StrPos > 0) and (StrPos < (StrLength - 3)); - if Result then - begin + If Result Then + Begin PDWString(@S[StrPos])^ := DWChar($FC or (Ch shr 30)); // 1 bits PDWString(@S[StrPos + 1])^ := DWChar(((Ch shr 24) and $3F) or $80); // 6 bits PDWString(@S[StrPos + 2])^ := DWChar(((Ch shr 18) and $3F) or $80); // 6 bits @@ -812,113 +812,113 @@ function UTF8SetNextChar(var S: TUTF8String; var StrPos: SizeInt; Ch: UCS4): Boo PDWString(@S[StrPos + 4])^ := DWChar(((Ch shr 6) and $3F) or $80); // 6 bits PDWString(@S[StrPos + 5])^ := DWChar((Ch and $3F) or $80); // 6 bits Inc(StrPos, 6); - end; - end - else - begin + End; + End + Else + Begin {$IFDEF UNICODE_SILENT_FAILURE} // add ReplacementCharacter Result := (StrPos > 0) and (StrPos < (StrLength - 1)); - if Result then - begin + If Result Then + Begin S[StrPos] := DWChar($E0 or (UCS4ReplacementCharacter shr 12)); // 4 bits S[StrPos + 1] := DWChar(((UCS4ReplacementCharacter shr 6) and $3F) or $80); // 6 bits S[StrPos + 2] := DWChar((UCS4ReplacementCharacter and $3F) or $80); // 6 bits Inc(StrPos, 3); - end; + End; {$ELSE ~UNICODE_SILENT_FAILURE} StrPos := -1; Result := False; {$ENDIF ~UNICODE_SILENT_FAILURE} - end; -end; -function UTF8SetNextBuffer(var S: TUTF8String; var StrPos: SizeInt; const Buffer: TUCS4Array; var Start: SizeInt; Count: SizeInt): SizeInt; -var + End; +End; +Function UTF8SetNextBuffer(Var S: TUTF8String; Var StrPos: SizeInt; Const Buffer: TUCS4Array; Var Start: SizeInt; Count: SizeInt): SizeInt; +Var StrLength: SizeInt; Ch: UCS4; Success: Boolean; -begin +Begin StrLength := Length(S); Success := True; Result := 0; - while Success and (Count > 0) do - begin + While Success and (Count > 0) Do + Begin Ch := Buffer[Start]; - if Ch <= $7F then - begin + If Ch <= $7F Then + Begin // 7 bits to store - if (StrPos > 0) and (StrPos <= StrLength) then - begin + If (StrPos > 0) and (StrPos <= StrLength) Then + Begin PDWString(@S[StrPos])^ := DWChar(Ch); Inc(StrPos); - end - else + End + Else Success := False; - end - else - if Ch <= $7FF then - begin + End + Else + If Ch <= $7FF Then + Begin // 11 bits to store - if (StrPos > 0) and (StrPos < StrLength) then - begin + If (StrPos > 0) and (StrPos < StrLength) Then + Begin PDWString(@S[StrPos])^ := DWChar($C0 or (Ch shr 6)); // 5 bits PDWString(@S[StrPos + 1])^ := DWChar((Ch and $3F) or $80); // 6 bits Inc(StrPos, 2); - end - else + End + Else Success := False; - end - else - if Ch <= $FFFF then - begin + End + Else + If Ch <= $FFFF Then + Begin // 16 bits to store - if (StrPos > 0) and (StrPos < (StrLength - 1)) then - begin + If (StrPos > 0) and (StrPos < (StrLength - 1)) Then + Begin PDWString(@S[StrPos])^ := DWChar($E0 or (Ch shr 12)); // 4 bits PDWString(@S[StrPos + 1])^ := DWChar(((Ch shr 6) and $3F) or $80); // 6 bits PDWString(@S[StrPos + 2])^ := DWChar((Ch and $3F) or $80); // 6 bits Inc(StrPos, 3); - end - else + End + Else Success := False; - end - else - if Ch <= $1FFFFF then - begin + End + Else + If Ch <= $1FFFFF Then + Begin // 21 bits to store - if (StrPos > 0) and (StrPos < (StrLength - 2)) then - begin + If (StrPos > 0) and (StrPos < (StrLength - 2)) Then + Begin PDWString(@S[StrPos])^ := DWChar($F0 or (Ch shr 18)); // 3 bits PDWString(@S[StrPos + 1])^ := DWChar(((Ch shr 12) and $3F) or $80); // 6 bits PDWString(@S[StrPos + 2])^ := DWChar(((Ch shr 6) and $3F) or $80); // 6 bits PDWString(@S[StrPos + 3])^ := DWChar((Ch and $3F) or $80); // 6 bits Inc(StrPos, 4); - end - else + End + Else Success := False; - end - else - if Ch <= $3FFFFFF then - begin + End + Else + If Ch <= $3FFFFFF Then + Begin // 26 bits to store - if (StrPos > 0) and (StrPos < (StrLength - 2)) then - begin + If (StrPos > 0) and (StrPos < (StrLength - 2)) Then + Begin PDWString(@S[StrPos])^ := DWChar($F8 or (Ch shr 24)); // 2 bits PDWString(@S[StrPos + 1])^ := DWChar(((Ch shr 18) and $3F) or $80); // 6 bits PDWString(@S[StrPos + 2])^ := DWChar(((Ch shr 12) and $3F) or $80); // 6 bits PDWString(@S[StrPos + 3])^ := DWChar(((Ch shr 6) and $3F) or $80); // 6 bits PDWString(@S[StrPos + 4])^ := DWChar((Ch and $3F) or $80); // 6 bits Inc(StrPos, 5); - end - else + End + Else Success := False; - end - else - if Ch <= MaximumUCS4 then - begin + End + Else + If Ch <= MaximumUCS4 Then + Begin // 31 bits to store - if (StrPos > 0) and (StrPos < (StrLength - 3)) then - begin + If (StrPos > 0) and (StrPos < (StrLength - 3)) Then + Begin PDWString(@S[StrPos])^ := DWChar($FC or (Ch shr 30)); // 1 bits PDWString(@S[StrPos + 1])^ := DWChar(((Ch shr 24) and $3F) or $80); // 6 bits PDWString(@S[StrPos + 2])^ := DWChar(((Ch shr 18) and $3F) or $80); // 6 bits @@ -926,69 +926,69 @@ function UTF8SetNextBuffer(var S: TUTF8String; var StrPos: SizeInt; const Buffer PDWString(@S[StrPos + 4])^ := DWChar(((Ch shr 6) and $3F) or $80); // 6 bits PDWString(@S[StrPos + 5])^ := DWChar((Ch and $3F) or $80); // 6 bits Inc(StrPos, 6); - end - else + End + Else Success := False; - end - else - begin + End + Else + Begin {$IFDEF UNICODE_SILENT_FAILURE} // add ReplacementCharacter - if (StrPos > 0) and (StrPos < (StrLength - 1)) then - begin + If (StrPos > 0) and (StrPos < (StrLength - 1)) Then + Begin S[StrPos] := DWChar($E0 or (UCS4ReplacementCharacter shr 12)); // 4 bits S[StrPos + 1] := DWChar(((UCS4ReplacementCharacter shr 6) and $3F) or $80); // 6 bits S[StrPos + 2] := DWChar((UCS4ReplacementCharacter and $3F) or $80); // 6 bits Inc(StrPos, 3); - end - else + End + Else Success := False; {$ELSE ~UNICODE_SILENT_FAILURE} StrPos := -1; Success := False; {$ENDIF ~UNICODE_SILENT_FAILURE} - end; - if Success then - begin + End; + If Success Then + Begin Inc(Start); Inc(Result); - end; + End; Dec(Count); - end; -end; -function UTF8SetNextCharToStream(S: TStream; Ch: UCS4): Boolean; -begin - if Ch <= $7F then + End; +End; +Function UTF8SetNextCharToStream(S: TStream; Ch: UCS4): Boolean; +Begin + If Ch <= $7F Then // 7 bits to store Result := StreamWriteByte(S,Ch) - else - if Ch <= $7FF then + Else + If Ch <= $7FF Then // 11 bits to store Result := StreamWriteByte(S, $C0 or (Ch shr 6)) and // 5 bits StreamWriteByte(S, (Ch and $3F) or $80) // 6 bits - else - if Ch <= $FFFF then + Else + If Ch <= $FFFF Then // 16 bits to store Result := StreamWriteByte(S, $E0 or (Ch shr 12)) and // 4 bits StreamWriteByte(S, ((Ch shr 6) and $3F) or $80) and // 6 bits StreamWriteByte(S, (Ch and $3F) or $80) // 6 bits - else - if Ch <= $1FFFFF then + Else + If Ch <= $1FFFFF Then // 21 bits to store Result := StreamWriteByte(S, $F0 or (Ch shr 18)) and // 3 bits StreamWriteByte(S, ((Ch shr 12) and $3F) or $80) and // 6 bits StreamWriteByte(S, ((Ch shr 6) and $3F) or $80) and // 6 bits StreamWriteByte(S, (Ch and $3F) or $80) // 6 bits - else - if Ch <= $3FFFFFF then + Else + If Ch <= $3FFFFFF Then // 26 bits to store Result := StreamWriteByte(S, $F8 or (Ch shr 24)) and // 2 bits StreamWriteByte(S, ((Ch shr 18) and $3F) or $80) and // 6 bits StreamWriteByte(S, ((Ch shr 12) and $3F) or $80) and // 6 bits StreamWriteByte(S, ((Ch shr 6) and $3F) or $80) and // 6 bits StreamWriteByte(S, (Ch and $3F) or $80) // 6 bits - else - if Ch <= MaximumUCS4 then + Else + If Ch <= MaximumUCS4 Then // 31 bits to store Result := StreamWriteByte(S, $FC or (Ch shr 30)) and // 1 bits StreamWriteByte(S, ((Ch shr 24) and $3F) or $80) and // 6 bits @@ -996,7 +996,7 @@ function UTF8SetNextCharToStream(S: TStream; Ch: UCS4): Boolean; StreamWriteByte(S, ((Ch shr 12) and $3F) or $80) and // 6 bits StreamWriteByte(S, ((Ch shr 6) and $3F) or $80) and // 6 bits StreamWriteByte(S, (Ch and $3F) or $80) // 6 bits - else + Else {$IFDEF UNICODE_SILENT_FAILURE} // add ReplacementCharacter Result := StreamWriteByte(S, $E0 or (UCS4ReplacementCharacter shr 12)) and // 4 bits @@ -1005,48 +1005,48 @@ function UTF8SetNextCharToStream(S: TStream; Ch: UCS4): Boolean; {$ELSE ~UNICODE_SILENT_FAILURE} Result := False; {$ENDIF ~UNICODE_SILENT_FAILURE} -end; -function UTF8SetNextBufferToStream(S: TStream; const Buffer: TUCS4Array; var Start: SizeInt; Count: SizeInt): SizeInt; -var +End; +Function UTF8SetNextBufferToStream(S: TStream; Const Buffer: TUCS4Array; Var Start: SizeInt; Count: SizeInt): SizeInt; +Var Ch: UCS4; Success: Boolean; -begin +Begin Result := 0; Success := True; - while Success and (Count > 0) do - begin + While Success and (Count > 0) Do + Begin Ch := Buffer[Start]; - if Ch <= $7F then + If Ch <= $7F Then // 7 bits to store Success := StreamWriteByte(S,Ch) - else - if Ch <= $7FF then + Else + If Ch <= $7FF Then // 11 bits to store Success := StreamWriteByte(S, $C0 or (Ch shr 6)) and // 5 bits StreamWriteByte(S, (Ch and $3F) or $80) // 6 bits - else - if Ch <= $FFFF then + Else + If Ch <= $FFFF Then // 16 bits to store Success := StreamWriteByte(S, $E0 or (Ch shr 12)) and // 4 bits StreamWriteByte(S, ((Ch shr 6) and $3F) or $80) and // 6 bits StreamWriteByte(S, (Ch and $3F) or $80) // 6 bits - else - if Ch <= $1FFFFF then + Else + If Ch <= $1FFFFF Then // 21 bits to store Success := StreamWriteByte(S, $F0 or (Ch shr 18)) and // 3 bits StreamWriteByte(S, ((Ch shr 12) and $3F) or $80) and // 6 bits StreamWriteByte(S, ((Ch shr 6) and $3F) or $80) and // 6 bits StreamWriteByte(S, (Ch and $3F) or $80) // 6 bits - else - if Ch <= $3FFFFFF then + Else + If Ch <= $3FFFFFF Then // 26 bits to store Success := StreamWriteByte(S, $F8 or (Ch shr 24)) and // 2 bits StreamWriteByte(S, ((Ch shr 18) and $3F) or $80) and // 6 bits StreamWriteByte(S, ((Ch shr 12) and $3F) or $80) and // 6 bits StreamWriteByte(S, ((Ch shr 6) and $3F) or $80) and // 6 bits StreamWriteByte(S, (Ch and $3F) or $80) // 6 bits - else - if Ch <= MaximumUCS4 then + Else + If Ch <= MaximumUCS4 Then // 31 bits to store Success := StreamWriteByte(S, $FC or (Ch shr 30)) and // 1 bits StreamWriteByte(S, ((Ch shr 24) and $3F) or $80) and // 6 bits @@ -1054,7 +1054,7 @@ function UTF8SetNextBufferToStream(S: TStream; const Buffer: TUCS4Array; var Sta StreamWriteByte(S, ((Ch shr 12) and $3F) or $80) and // 6 bits StreamWriteByte(S, ((Ch shr 6) and $3F) or $80) and // 6 bits StreamWriteByte(S, (Ch and $3F) or $80) // 6 bits - else + Else {$IFDEF UNICODE_SILENT_FAILURE} // add ReplacementCharacter Success := StreamWriteByte(S, $E0 or (UCS4ReplacementCharacter shr 12)) and // 4 bits @@ -1063,280 +1063,280 @@ function UTF8SetNextBufferToStream(S: TStream; const Buffer: TUCS4Array; var Sta {$ELSE ~UNICODE_SILENT_FAILURE} Success := False; {$ENDIF ~UNICODE_SILENT_FAILURE} - if Success then - begin + If Success Then + Begin Inc(Start); Inc(Result); - end; + End; Dec(Count); - end; -end; + End; +End; // if UNICODE_SILENT_FAILURE is defined, invalid sequences will be replaced by ReplacementCharacter -function UTF16SkipChars(const S: TUTF16String; var StrPos: SizeInt; var NbSeq: SizeInt): Boolean; -var +Function UTF16SkipChars(Const S: TUTF16String; Var StrPos: SizeInt; Var NbSeq: SizeInt): Boolean; +Var StrLength, Index: SizeInt; Ch: UCS4; -begin +Begin Result := True; StrLength := Length(S); Index := 0; - if NbSeq >= 0 then - while (Index < NbSeq) and (StrPos > 0) do - begin + If NbSeq >= 0 Then + While (Index < NbSeq) and (StrPos > 0) Do + Begin Ch := UCS4(S[StrPos]); - case Ch of + Case Ch Of SurrogateHighStart..SurrogateHighEnd: // 2 bytes to skip - if StrPos >= StrLength then + If StrPos >= StrLength Then FlagInvalidSequence(StrPos, 1) - else - begin + Else + Begin Ch := UCS4(S[StrPos + 1]); - if (Ch < SurrogateLowStart) or (Ch > SurrogateLowEnd) then + If (Ch < SurrogateLowStart) or (Ch > SurrogateLowEnd) Then FlagInvalidSequence(StrPos, 1) - else + Else Inc(StrPos, 2); - end; + End; SurrogateLowStart..SurrogateLowEnd: // error FlagInvalidSequence(StrPos, 1); - else + Else // 1 byte to skip Inc(StrPos); - end; - if StrPos <> -1 then + End; + If StrPos <> -1 Then Inc(Index); - if (StrPos > StrLength) and (Index < NbSeq) then - begin + If (StrPos > StrLength) and (Index < NbSeq) Then + Begin Result := False; Break; - end; - end - else - while (Index > NbSeq) and (StrPos > 1) do - begin + End; + End + Else + While (Index > NbSeq) and (StrPos > 1) Do + Begin Ch := UCS4(S[StrPos - 1]); - case Ch of + Case Ch Of SurrogateHighStart..SurrogateHighEnd: // error FlagInvalidSequence(StrPos, -1); SurrogateLowStart..SurrogateLowEnd: // 2 bytes to skip - if StrPos <= 2 then + If StrPos <= 2 Then FlagInvalidSequence(StrPos, -1) - else - begin + Else + Begin Ch := UCS4(S[StrPos - 2]); - if (Ch < SurrogateHighStart) or (Ch > SurrogateHighEnd) then + If (Ch < SurrogateHighStart) or (Ch > SurrogateHighEnd) Then FlagInvalidSequence(StrPos, -1) - else + Else Dec(StrPos, 2); - end; - else + End; + Else // 1 byte to skip Dec(StrPos); - end; - if StrPos <> -1 then + End; + If StrPos <> -1 Then Dec(Index); - if (StrPos = 1) and (Index > NbSeq) then - begin + If (StrPos = 1) and (Index > NbSeq) Then + Begin Result := False; Break; - end; - end; + End; + End; NbSeq := Index; -end; -function UTF16SkipCharsFromStream(S: TStream; var NbSeq: SizeInt): Boolean; -var +End; +Function UTF16SkipCharsFromStream(S: TStream; Var NbSeq: SizeInt): Boolean; +Var Index: SizeInt; W: Word; -begin +Begin Index := 0; - while Index < NbSeq do - begin + While Index < NbSeq Do + Begin Result := StreamReadWord(S, W); - if not Result then + If not Result Then Break; - case W of + Case W Of SurrogateHighStart..SurrogateHighEnd: // 2 bytes to skip - begin + Begin Result := StreamReadWord(S, W); - if not Result then + If not Result Then Break; - if (W < SurrogateLowStart) or (W > SurrogateLowEnd) then + If (W < SurrogateLowStart) or (W > SurrogateLowEnd) Then FlagInvalidSequence; - end; + End; SurrogateLowStart..SurrogateLowEnd: // error FlagInvalidSequence; - else + Else // 1 byte to skip // nothing to do - end; + End; Inc(Index); - end; + End; Result := Index = NbSeq; NbSeq := Index; -end; -function AnsiSkipChars(const S: DWString; var StrPos: SizeInt; var NbSeq: SizeInt): Boolean; -var +End; +Function AnsiSkipChars(Const S: DWString; Var StrPos: SizeInt; Var NbSeq: SizeInt): Boolean; +Var StrLen: SizeInt; -begin +Begin StrLen := Length(S); - if StrPos > 0 then - begin - if StrPos + NbSeq > StrLen then - begin + If StrPos > 0 Then + Begin + If StrPos + NbSeq > StrLen Then + Begin NbSeq := StrLen + 1 - StrPos; StrPos := StrLen + 1; Result := False; - end - else - begin + End + Else + Begin // NbSeq := NbSeq; StrPos := StrLen + NbSeq; Result := True; - end; - end - else - begin + End; + End + Else + Begin // previous error NbSeq := 0; // StrPos := -1; Result := False; - end; -end; -function AnsiSkipCharsFromStream(S: TStream; var NbSeq: SizeInt): Boolean; -var + End; +End; +Function AnsiSkipCharsFromStream(S: TStream; Var NbSeq: SizeInt): Boolean; +Var Index: SizeInt; B: Byte; -begin +Begin Index := 0; - while Index < NbSeq do - begin + While Index < NbSeq Do + Begin Result := StreamReadByte(S, B); - if not Result then + If not Result Then Break; Inc(Index); - end; + End; Result := Index = NbSeq; NbSeq := Index; -end; -function StringSkipChars(const S: string; var StrPos: SizeInt; var NbSeq: SizeInt): Boolean; -begin +End; +Function StringSkipChars(Const S: string; Var StrPos: SizeInt; Var NbSeq: SizeInt): Boolean; +Begin Result := AnsiSkipChars(S, StrPos, NbSeq); -end; -function DWStringToUTF16(const S: DWString): TUTF16String; -begin +End; +Function DWStringToUTF16(Const S: DWString): TUTF16String; +Begin Result := TUTF16String(S); -end; -function UTF16ToAnsiString(const S: TUTF16String): DWString; -begin +End; +Function UTF16ToAnsiString(Const S: TUTF16String): DWString; +Begin Result := DWString(S); -end; -function StringToUTF16(const S: string): TUTF16String; -begin +End; +Function StringToUTF16(Const S: string): TUTF16String; +Begin Result := TUTF16String(S); -end; -function TryStringToUTF16(const S: string; out D: TUTF16String): Boolean; -begin +End; +Function TryStringToUTF16(Const S: string; out D: TUTF16String): Boolean; +Begin D := TUTF16String(S); Result := True; -end; -function UTF16ToString(const S: TUTF16String): string; -begin +End; +Function UTF16ToString(Const S: TUTF16String): string; +Begin Result := string(S); -end; -function TryUTF16ToString(const S: TUTF16String; out D: string): Boolean; -begin +End; +Function TryUTF16ToString(Const S: TUTF16String; out D: string): Boolean; +Begin D := string(S); Result := True; -end; -function UCS4ToUTF8(const S: TUCS4Array): TUTF8String; -var +End; +Function UCS4ToUTF8(Const S: TUCS4Array): TUTF8String; +Var SrcIndex, SrcLength, DestIndex: SizeInt; -begin +Begin SrcLength := Length(S); - if Length(S) = 0 then + If Length(S) = 0 Then Result := '' - else - begin + Else + Begin SetLength(Result, SrcLength * 3); // assume worst case DestIndex := 1; - for SrcIndex := 0 to SrcLength - 1 do - begin + For SrcIndex := 0 To SrcLength - 1 Do + Begin UTF8SetNextChar(Result, DestIndex, S[SrcIndex]); - if DestIndex = -1 then + If DestIndex = -1 Then raise EJclUnexpectedEOSequenceError.Create; - end; + End; SetLength(Result, DestIndex - 1); // set to actual length - end; -end; -function TryUCS4ToUTF8(const S: TUCS4Array; out D: TUTF8String): Boolean; -var + End; +End; +Function TryUCS4ToUTF8(Const S: TUCS4Array; out D: TUTF8String): Boolean; +Var SrcIndex, SrcLength, DestIndex: SizeInt; -begin +Begin SrcLength := Length(S); Result := True; - if Length(S) = 0 then + If Length(S) = 0 Then D := '' - else - begin + Else + Begin SetLength(D, SrcLength * 3); // assume worst case DestIndex := 1; - for SrcIndex := 0 to SrcLength - 1 do - begin + For SrcIndex := 0 To SrcLength - 1 Do + Begin UTF8SetNextChar(D, DestIndex, S[SrcIndex]); - if DestIndex = -1 then - begin + If DestIndex = -1 Then + Begin Result := False; Break; - end; - end; - if Result then + End; + End; + If Result Then SetLength(D, DestIndex - 1) // set to actual length - else + Else D := ''; - end; -end; -function UTF8CharCount(const S: TUTF8String): SizeInt; -var + End; +End; +Function UTF8CharCount(Const S: TUTF8String): SizeInt; +Var StrPos: SizeInt; -begin +Begin StrPos := 1; Result := Length(S); UTF8SkipChars(S, StrPos, Result); - if StrPos = -1 then + If StrPos = -1 Then raise EJclUnexpectedEOSequenceError.Create; -end; -function UTF16CharCount(const S: TUTF16String): SizeInt; -var +End; +Function UTF16CharCount(Const S: TUTF16String): SizeInt; +Var StrPos: SizeInt; -begin +Begin StrPos := 1; Result := Length(S); UTF16SkipChars(S, StrPos, Result); - if StrPos = -1 then + If StrPos = -1 Then raise EJclUnexpectedEOSequenceError.Create; -end; -function UCS2CharCount(const S: TUCS2String): SizeInt; -begin +End; +Function UCS2CharCount(Const S: TUCS2String): SizeInt; +Begin Result := Length(S); -end; -function UCS4CharCount(const S: TUCS4Array): SizeInt; -begin +End; +Function UCS4CharCount(Const S: TUCS4Array): SizeInt; +Begin Result := Length(S); -end; -function UCS4ToWideChar(Value: UCS4): WideChar; -begin - if Value <= MaximumUCS2 then +End; +Function UCS4ToWideChar(Value: UCS4): WideChar; +Begin + If Value <= MaximumUCS2 Then Result := WideChar(Value) - else + Else Result := WideChar(UCS4ReplacementCharacter); -end; -function WideCharToUCS4(Value: WideChar): UCS4; -begin +End; +Function WideCharToUCS4(Value: WideChar): UCS4; +Begin Result := UCS4(Value); -end; -end. +End; +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemStrings.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemStrings.pas index c8c0cb283..cf9b39d61 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemStrings.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemStrings.pas @@ -1,80 +1,80 @@ -unit uRESTDWMemStrings; +Unit uRESTDWMemStrings; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. Roniery - Devel. } -interface -uses +Interface +Uses {$IFDEF MSWINDOWS} Windows, {$ENDIF MSWINDOWS} SysUtils, Classes; {regular expressions} {template functions} -function ReplaceFirst(const SourceStr, FindStr, ReplaceStr: string): string; -function ReplaceLast(const SourceStr, FindStr, ReplaceStr: string): string; -function InsertLastBlock(var SourceStr: string; BlockStr: string): Boolean; -function RemoveMasterBlocks(const SourceStr: string): string; -function RemoveFields(const SourceStr: string): string; +Function ReplaceFirst(Const SourceStr, FindStr, ReplaceStr: string): string; +Function ReplaceLast(Const SourceStr, FindStr, ReplaceStr: string): string; +Function InsertLastBlock(Var SourceStr: string; BlockStr: string): Boolean; +Function RemoveMasterBlocks(Const SourceStr: string): string; +Function RemoveFields(Const SourceStr: string): string; {http functions} -function URLEncode(const Value: AnsiString): AnsiString; // Converts string To A URLEncoded string -function URLDecode(const Value: AnsiString): AnsiString; // Converts string From A URLEncoded string +Function URLEncode(Const Value: AnsiString): AnsiString; // Converts string To A URLEncoded string +Function URLDecode(Const Value: AnsiString): AnsiString; // Converts string From A URLEncoded string {set functions} -procedure SplitSet(AText: string; AList: TStringList); -function JoinSet(AList: TStringList): string; -function FirstOfSet(const AText: string): string; -function LastOfSet(const AText: string): string; -function CountOfSet(const AText: string): Integer; -function SetRotateRight(const AText: string): string; -function SetRotateLeft(const AText: string): string; -function SetPick(const AText: string; AIndex: Integer): string; -function SetSort(const AText: string): string; -function SetUnion(const Set1, Set2: string): string; -function SetIntersect(const Set1, Set2: string): string; -function SetExclude(const Set1, Set2: string): string; +Procedure SplitSet(AText: string; AList: TStringList); +Function JoinSet(AList: TStringList): string; +Function FirstOfSet(Const AText: string): string; +Function LastOfSet(Const AText: string): string; +Function CountOfSet(Const AText: string): Integer; +Function SetRotateRight(Const AText: string): string; +Function SetRotateLeft(Const AText: string): string; +Function SetPick(Const AText: string; AIndex: Integer): string; +Function SetSort(Const AText: string): string; +Function SetUnion(Const Set1, Set2: string): string; +Function SetIntersect(Const Set1, Set2: string): string; +Function SetExclude(Const Set1, Set2: string): string; {simple hash, Result can be used in Encrypt} -function Hash(const AText: string): Integer; +Function Hash(Const AText: string): Integer; { Base64 encode and decode a string } -function B64Encode(const S: AnsiString): AnsiString; -function B64Decode(const S: AnsiString): AnsiString; +Function B64Encode(Const S: AnsiString): AnsiString; +Function B64Decode(Const S: AnsiString): AnsiString; {Basic encryption from a Borland Example} -function Encrypt(const InString: AnsiString; StartKey, MultKey, AddKey: Integer): AnsiString; -function Decrypt(const InString: AnsiString; StartKey, MultKey, AddKey: Integer): AnsiString; +Function Encrypt(Const InString: AnsiString; StartKey, MultKey, AddKey: Integer): AnsiString; +Function Decrypt(Const InString: AnsiString; StartKey, MultKey, AddKey: Integer): AnsiString; {Using Encrypt and Decrypt in combination with B64Encode and B64Decode} -function EncryptB64(const InString: AnsiString; StartKey, MultKey, AddKey: Integer): AnsiString; -function DecryptB64(const InString: AnsiString; StartKey, MultKey, AddKey: Integer): AnsiString; -procedure CSVToTags(Src, Dst: TStringList); +Function EncryptB64(Const InString: AnsiString; StartKey, MultKey, AddKey: Integer): AnsiString; +Function DecryptB64(Const InString: AnsiString; StartKey, MultKey, AddKey: Integer): AnsiString; +Procedure CSVToTags(Src, Dst: TStringList); // converts a csv list to a tagged string list -procedure TagsToCSV(Src, Dst: TStringList); +Procedure TagsToCSV(Src, Dst: TStringList); // converts a tagged string list to a csv list // only fieldnames from the first record are scanned ib the other records -procedure ListSelect(Src, Dst: TStringList; const AKey, AValue: string); +Procedure ListSelect(Src, Dst: TStringList; Const AKey, AValue: string); {selects akey=avalue from Src and returns recordset in Dst} -procedure ListFilter(Src: TStringList; const AKey, AValue: string); +Procedure ListFilter(Src: TStringList; Const AKey, AValue: string); {filters Src for akey=avalue} -procedure ListOrderBy(Src: TStringList; const AKey: string; Numeric: Boolean); +Procedure ListOrderBy(Src: TStringList; Const AKey: string; Numeric: Boolean); {orders a tagged Src list by akey} -function PosStr(const FindString, SourceString: string; +Function PosStr(Const FindString, SourceString: string; StartPos: Integer = 1): Integer; { PosStr searches the first occurrence of a substring FindString in a string given by SourceString with case sensitivity (upper and lower case characters @@ -83,10 +83,10 @@ function PosStr(const FindString, SourceString: string; StartPos character index. If a specified substring is not found Q_PosStr returns zero. The author of algorithm is Peter Morris (UK) (Faststrings unit from www.torry.ru). } -function PosStrLast(const FindString, SourceString: string): Integer; +Function PosStrLast(Const FindString, SourceString: string): Integer; {finds the last occurance} -function LastPosChar(const FindChar: Char; SourceString: string): Integer; -function PosText(const FindString, SourceString: string; +Function LastPosChar(Const FindChar: Char; SourceString: string): Integer; +Function PosText(Const FindString, SourceString: string; StartPos: Integer = 1): Integer; { PosText searches the first occurrence of a substring FindString in a string given by SourceString without case sensitivity (upper and lower case @@ -95,455 +95,455 @@ function PosText(const FindString, SourceString: string; string starting with StartPos character index. If a specified substring is not found Q_PosStr returns zero. The author of algorithm is Peter Morris (UK) (Faststrings unit from www.torry.ru). } -function PosTextLast(const FindString, SourceString: string): Integer; +Function PosTextLast(Const FindString, SourceString: string): Integer; {finds the last occurance} -function NameValuesToXML(const AText: string): string; +Function NameValuesToXML(Const AText: string): string; {$IFDEF MSWINDOWS} -procedure LoadResourceFile(AFile: string; MemStream: TMemoryStream); +Procedure LoadResourceFile(AFile: string; MemStream: TMemoryStream); {$ENDIF MSWINDOWS} -procedure DirFiles(const ADir, AMask: string; AFileList: TStringList); -procedure RecurseDirFiles(const ADir: string; var AFileList: TStringList); -procedure RecurseDirProgs(const ADir: string; var AFileList: TStringList); -procedure SaveString(const AFile, AText: string); -function LoadString(const AFile: string): string; -function UppercaseHTMLTags(const AText: string): string; -function LowercaseHTMLTags(const AText: string): string; -procedure GetHTMLAnchors(const AFile: string; AList: TStringList); -function RelativePath(const ASrc, ADst: string): string; -function GetToken(var Start: Integer; const SourceText: string): string; -function PosNonSpace(Start: Integer; const SourceText: string): Integer; -function PosEscaped(Start: Integer; const SourceText, FindText: string; EscapeChar: Char): Integer; -function DeleteEscaped(const SourceText: string; EscapeChar: Char): string; -function BeginOfAttribute(Start: Integer; const SourceText: string): Integer; +Procedure DirFiles(Const ADir, AMask: string; AFileList: TStringList); +Procedure RecurseDirFiles(Const ADir: string; Var AFileList: TStringList); +Procedure RecurseDirProgs(Const ADir: string; Var AFileList: TStringList); +Procedure SaveString(Const AFile, AText: string); +Function LoadString(Const AFile: string): string; +Function UppercaseHTMLTags(Const AText: string): string; +Function LowercaseHTMLTags(Const AText: string): string; +Procedure GetHTMLAnchors(Const AFile: string; AList: TStringList); +Function RelativePath(Const ASrc, ADst: string): string; +Function GetToken(Var Start: Integer; Const SourceText: string): string; +Function PosNonSpace(Start: Integer; Const SourceText: string): Integer; +Function PosEscaped(Start: Integer; Const SourceText, FindText: string; EscapeChar: Char): Integer; +Function DeleteEscaped(Const SourceText: string; EscapeChar: Char): string; +Function BeginOfAttribute(Start: Integer; Const SourceText: string): Integer; // parses the beginning of an attribute: space + alpha character -function ParseAttribute(var Start: Integer; const SourceText: string; var AName, AValue: string): Boolean; +Function ParseAttribute(Var Start: Integer; Const SourceText: string; Var AName, AValue: string): Boolean; // parses a name="value" attribute from Start; returns 0 when not found or else the position behind the attribute -procedure ParseAttributes(const SourceText: string; Attributes: TStrings); +Procedure ParseAttributes(Const SourceText: string; Attributes: TStrings); // parses all name=value attributes to the attributes TStringList -function HasStrValue(const AText, AName: string; var AValue: string): Boolean; +Function HasStrValue(Const AText, AName: string; Var AValue: string): Boolean; // checks if a name="value" pair exists and returns any value -function GetStrValue(const AText, AName, ADefault: string): string; +Function GetStrValue(Const AText, AName, ADefault: string): string; // retrieves string value from a line like: // name="jan verhoeven" email="jan1 dott verhoeven att wxs dott nl" // returns ADefault when not found -function GetIntValue(const AText, AName: string; ADefault: Integer): Integer; +Function GetIntValue(Const AText, AName: string; ADefault: Integer): Integer; // same for an Integer -function GetFloatValue(const AText, AName: string; ADefault: Extended): Extended; +Function GetFloatValue(Const AText, AName: string; ADefault: Extended): Extended; // same for a float -function GetBoolValue(const AText, AName: string): Boolean; +Function GetBoolValue(Const AText, AName: string): Boolean; // same for Boolean but without default -function GetValue(const AText, AName: string): string; +Function GetValue(Const AText, AName: string): string; // retrieves string value from a line like: // name="jan verhoeven" email="jan1 dott verhoeven att wxs dott nl" -procedure SetValue(var AText: string; const AName, AValue: string); +Procedure SetValue(Var AText: string; Const AName, AValue: string); // sets a string value in a line -procedure DeleteValue(var AText: string; const AName: string); +Procedure DeleteValue(Var AText: string; Const AName: string); // deletes a AName="value" pair from AText -procedure GetNames(AText: string; AList: TStringList); +Procedure GetNames(AText: string; AList: TStringList); // get a list of names from a string with name="value" pairs -function BackPosStr(Start: Integer; const FindString, SourceString: string): Integer; +Function BackPosStr(Start: Integer; Const FindString, SourceString: string): Integer; // finds a string backward case sensitive -function BackPosText(Start: Integer; const FindString, SourceString: string): Integer; +Function BackPosText(Start: Integer; Const FindString, SourceString: string): Integer; // finds a string backward case insensitive -function PosRangeStr(Start: Integer; const HeadString, TailString, SourceString: string; - var RangeBegin: Integer; var RangeEnd: Integer): Boolean; +Function PosRangeStr(Start: Integer; Const HeadString, TailString, SourceString: string; + Var RangeBegin: Integer; Var RangeEnd: Integer): Boolean; // finds a text range, e.g. .... case sensitive -function PosRangeText(Start: Integer; const HeadString, TailString, SourceString: string; - var RangeBegin: Integer; var RangeEnd: Integer): Boolean; +Function PosRangeText(Start: Integer; Const HeadString, TailString, SourceString: string; + Var RangeBegin: Integer; Var RangeEnd: Integer): Boolean; // finds a text range, e.g. .... case insensitive -function BackPosRangeStr(Start: Integer; const HeadString, TailString, SourceString: string; - var RangeBegin: Integer; var RangeEnd: Integer): Boolean; +Function BackPosRangeStr(Start: Integer; Const HeadString, TailString, SourceString: string; + Var RangeBegin: Integer; Var RangeEnd: Integer): Boolean; // finds a text range backward, e.g. .... case sensitive -function BackPosRangeText(Start: Integer; const HeadString, TailString, SourceString: string; - var RangeBegin: Integer; var RangeEnd: Integer): Boolean; +Function BackPosRangeText(Start: Integer; Const HeadString, TailString, SourceString: string; + Var RangeBegin: Integer; Var RangeEnd: Integer): Boolean; // finds a text range backward, e.g. .... case insensitive -function PosTag(Start: Integer; SourceString: string; var RangeBegin: Integer; - var RangeEnd: Integer): Boolean; +Function PosTag(Start: Integer; SourceString: string; Var RangeBegin: Integer; + Var RangeEnd: Integer): Boolean; // finds a HTML or XML tag: <....> -function InnerTag(Start: Integer; const HeadString, TailString, SourceString: string; - var RangeBegin: Integer; var RangeEnd: Integer): Boolean; +Function InnerTag(Start: Integer; Const HeadString, TailString, SourceString: string; + Var RangeBegin: Integer; Var RangeEnd: Integer): Boolean; // finds the innertext between opening and closing tags -function Easter(NYear: Integer): TDateTime; +Function Easter(NYear: Integer): TDateTime; // returns the easter date of a year. -function GetWeekNumber(Today: TDateTime): string; +Function GetWeekNumber(Today: TDateTime): string; //gets a datecode. Returns year and weeknumber in format: YYWW -function ParseNumber(const S: string): Integer; +Function ParseNumber(Const S: string): Integer; // parse number returns the last position, starting from 1 -function ParseDate(const S: string): Integer; +Function ParseDate(Const S: string): Integer; // parse a SQL style data string from positions 1, // starts and ends with # -implementation -uses +Implementation +Uses {$IFDEF RTL200_UP} AnsiStrings, {$ENDIF RTL200_UP} uRESTDWMemConsts, uRESTDWMemResources, uRESTDWMemTypes; -const +Const B64Table: AnsiString = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; ValidURLChars: AnsiString = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$-_@.&+-!*"''(),;/#?:'; -procedure SaveString(const AFile, AText: string); -begin - with TFileStream.Create(AFile, fmCreate) do - try +Procedure SaveString(Const AFile, AText: string); +Begin + With TFileStream.Create(AFile, fmCreate) Do + Try WriteBuffer(AText[1], Length(AText)); - finally + Finally Free; - end; -end; -function LoadString(const AFile: string): string; -var + End; +End; +Function LoadString(Const AFile: string): string; +Var S: string; -begin - with TFileStream.Create(AFile, fmOpenRead) do - try +Begin + With TFileStream.Create(AFile, fmOpenRead) Do + Try SetLength(S, Size); ReadBuffer(S[1], Size); - finally + Finally Free; - end; + End; Result := S; -end; -procedure DeleteValue(var AText: string; const AName: string); -var +End; +Procedure DeleteValue(Var AText: string; Const AName: string); +Var P, P2, L: Integer; -begin +Begin L := Length(AName) + 2; P := PosText(AName + '="', AText); - if P = 0 then + If P = 0 Then Exit; P2 := PosStr('"', AText, P + L); - if P2 = 0 then + If P2 = 0 Then Exit; - if P > 1 then + If P > 1 Then Dec(P); // include the preceding space if not the first one Delete(AText, P, P2 - P + 1); -end; -function GetValue(const AText, AName: string): string; -var +End; +Function GetValue(Const AText, AName: string): string; +Var P, P2, L: Integer; -begin +Begin Result := ''; L := Length(AName) + 2; P := PosText(AName + '="', AText); - if P = 0 then + If P = 0 Then Exit; P2 := PosStr('"', AText, P + L); - if P2 = 0 then + If P2 = 0 Then Exit; Result := Copy(AText, P + L, P2 - (P + L)); Result := SysUtils.StringReplace(Result, '~~', Cr, [rfReplaceAll]); -end; -function HasStrValue(const AText, AName: string; var AValue: string): Boolean; -var +End; +Function HasStrValue(Const AText, AName: string; Var AValue: string): Boolean; +Var P, P2, L: Integer; S: string; -begin +Begin Result := False; L := Length(AName) + 2; P := PosText(AName + '="', AText); - if P = 0 then + If P = 0 Then Exit; P2 := PosStr('"', AText, P + L); - if P2 = 0 then + If P2 = 0 Then Exit; S := Copy(AText, P + L, P2 - (P + L)); AValue := SysUtils.StringReplace(S, '~~', Cr, [rfReplaceAll]); Result := True; -end; -function GetStrValue(const AText, AName, ADefault: string): string; -var +End; +Function GetStrValue(Const AText, AName, ADefault: string): string; +Var S: string; -begin +Begin S := ''; - if HasStrValue(AText, AName, S) then + If HasStrValue(AText, AName, S) Then Result := S - else + Else Result := ADefault; -end; -function GetIntValue(const AText, AName: string; ADefault: Integer): Integer; -var +End; +Function GetIntValue(Const AText, AName: string; ADefault: Integer): Integer; +Var S: string; -begin +Begin S := GetValue(AText, AName); - try + Try Result := StrToInt(S); - except + Except Result := ADefault; - end; -end; -function GetFloatValue(const AText, AName: string; ADefault: Extended): Extended; -var + End; +End; +Function GetFloatValue(Const AText, AName: string; ADefault: Extended): Extended; +Var S: string; -begin +Begin S := ''; - if HasStrValue(AText, AName, S) then - try + If HasStrValue(AText, AName, S) Then + Try Result := StrToFloat(S); - except + Except Result := ADefault; - end - else + End + Else Result := ADefault; -end; -procedure SetValue(var AText: string; const AName, AValue: string); -var +End; +Procedure SetValue(Var AText: string; Const AName, AValue: string); +Var P, P2, L: Integer; -begin +Begin L := Length(AName) + 2; - if AText = '' then + If AText = '' Then AText := AName + '="' + AValue + '"' - else - begin + Else + Begin P := PosText(AName + '="', AText); - if P = 0 then + If P = 0 Then AText := AText + ' ' + AName + '="' + AValue + '"' - else - begin + Else + Begin P2 := PosStr('"', AText, P + L); - if P2 = 0 then + If P2 = 0 Then Exit; Delete(AText, P + L, P2 - (P + L)); Insert(AValue, AText, P + L); - end; - end; -end; -function BackPosStr(Start: Integer; const FindString, SourceString: string): Integer; -var + End; + End; +End; +Function BackPosStr(Start: Integer; Const FindString, SourceString: string): Integer; +Var P, L: Integer; -begin +Begin Result := 0; L := Length(FindString); - if (L = 0) or (SourceString = '') or (Start < 2) then + If (L = 0) or (SourceString = '') or (Start < 2) Then Exit; Start := Start - L; - if Start < 1 then + If Start < 1 Then Exit; - repeat + Repeat P := PosStr(FindString, SourceString, Start); - if P < Start then - begin + If P < Start Then + Begin Result := P; Exit; - end; + End; Start := Start - L; - until Start < 1; -end; -function BackPosText(Start: Integer; const FindString, SourceString: string): Integer; -var + Until Start < 1; +End; +Function BackPosText(Start: Integer; Const FindString, SourceString: string): Integer; +Var P, L, From: Integer; -begin +Begin Result := 0; L := Length(FindString); - if (L = 0) or (SourceString = '') or (Start < 2) then + If (L = 0) or (SourceString = '') or (Start < 2) Then Exit; From := Start - L; - if From < 1 then + If From < 1 Then Exit; - repeat + Repeat P := PosText(FindString, SourceString, From); - if P < Start then - begin + If P < Start Then + Begin Result := P; Exit; - end; + End; From := From - L; - until From < 1; -end; -function PosRangeStr(Start: Integer; const HeadString, TailString, SourceString: string; - var RangeBegin: Integer; var RangeEnd: Integer): Boolean; -begin + Until From < 1; +End; +Function PosRangeStr(Start: Integer; Const HeadString, TailString, SourceString: string; + Var RangeBegin: Integer; Var RangeEnd: Integer): Boolean; +Begin Result := False; RangeBegin := PosStr(HeadString, SourceString, Start); - if RangeBegin = 0 then + If RangeBegin = 0 Then Exit; RangeEnd := PosStr(TailString, SourceString, RangeBegin + Length(HeadString)); - if RangeEnd = 0 then + If RangeEnd = 0 Then Exit; RangeEnd := RangeEnd + Length(TailString) - 1; Result := True; -end; -function PosRangeText(Start: Integer; const HeadString, TailString, SourceString: string; - var RangeBegin: Integer; var RangeEnd: Integer): Boolean; -begin +End; +Function PosRangeText(Start: Integer; Const HeadString, TailString, SourceString: string; + Var RangeBegin: Integer; Var RangeEnd: Integer): Boolean; +Begin Result := False; RangeBegin := PosText(HeadString, SourceString, Start); - if RangeBegin = 0 then + If RangeBegin = 0 Then Exit; RangeEnd := PosText(TailString, SourceString, RangeBegin + Length(HeadString)); - if RangeEnd = 0 then + If RangeEnd = 0 Then Exit; RangeEnd := RangeEnd + Length(TailString) - 1; Result := True; -end; -function InnerTag(Start: Integer; const HeadString, TailString, SourceString: string; - var RangeBegin: Integer; var RangeEnd: Integer): Boolean; -begin +End; +Function InnerTag(Start: Integer; Const HeadString, TailString, SourceString: string; + Var RangeBegin: Integer; Var RangeEnd: Integer): Boolean; +Begin Result := False; RangeBegin := PosText(HeadString, SourceString, Start); - if RangeBegin = 0 then + If RangeBegin = 0 Then Exit; RangeBegin := RangeBegin + Length(HeadString); RangeEnd := PosText(TailString, SourceString, RangeBegin + Length(HeadString)); - if RangeEnd = 0 then + If RangeEnd = 0 Then Exit; RangeEnd := RangeEnd - 1; Result := True; -end; -function PosTag(Start: Integer; SourceString: string; var RangeBegin: Integer; var RangeEnd: Integer): Boolean; -begin +End; +Function PosTag(Start: Integer; SourceString: string; Var RangeBegin: Integer; Var RangeEnd: Integer): Boolean; +Begin Result := PosRangeStr(Start, '<', '>', SourceString, RangeBegin, RangeEnd); -end; -function BackPosRangeStr(Start: Integer; const HeadString, TailString, SourceString: string; - var RangeBegin: Integer; var RangeEnd: Integer): Boolean; -var +End; +Function BackPosRangeStr(Start: Integer; Const HeadString, TailString, SourceString: string; + Var RangeBegin: Integer; Var RangeEnd: Integer): Boolean; +Var L: Integer; -begin +Begin // finds a text range backward, e.g. .... case sensitive Result := False; L := Length(HeadString); - if (L = 0) or (Start < 2) then + If (L = 0) or (Start < 2) Then Exit; Start := Start - L; - if Start < 1 then + If Start < 1 Then Exit; - repeat - if not PosRangeStr(Start, HeadString, TailString, SourceString, RangeBegin, RangeEnd) then + Repeat + If not PosRangeStr(Start, HeadString, TailString, SourceString, RangeBegin, RangeEnd) Then Exit; - if RangeBegin < Start then - begin + If RangeBegin < Start Then + Begin Result := True; Exit; - end; + End; Start := Start - L; - until Start < 1; -end; -function BackPosRangeText(Start: Integer; const HeadString, TailString, SourceString: string; - var RangeBegin: Integer; var RangeEnd: Integer): Boolean; -var + Until Start < 1; +End; +Function BackPosRangeText(Start: Integer; Const HeadString, TailString, SourceString: string; + Var RangeBegin: Integer; Var RangeEnd: Integer): Boolean; +Var L: Integer; -begin +Begin // finds a text range backward, e.g. .... case insensitive Result := False; L := Length(HeadString); - if (L = 0) or (Start < 2) then + If (L = 0) or (Start < 2) Then Exit; Start := Start - L; - if Start < 1 then + If Start < 1 Then Exit; - repeat - if not PosRangeText(Start, HeadString, TailString, SourceString, RangeBegin, RangeEnd) then + Repeat + If not PosRangeText(Start, HeadString, TailString, SourceString, RangeBegin, RangeEnd) Then Exit; - if RangeBegin < Start then - begin + If RangeBegin < Start Then + Begin Result := True; Exit; - end; + End; Start := Start - L; - until Start < 1; -end; -function PosNonSpace(Start: Integer; const SourceText: string): Integer; -var + Until Start < 1; +End; +Function PosNonSpace(Start: Integer; Const SourceText: string): Integer; +Var P, L: Integer; -begin +Begin Result := 0; L := Length(SourceText); P := Start; - if L = 0 then + If L = 0 Then Exit; - while (P < L) and (SourceText[P] = ' ') do + While (P < L) and (SourceText[P] = ' ') Do Inc(P); - if SourceText[P] <> ' ' then + If SourceText[P] <> ' ' Then Result := P; -end; -function BeginOfAttribute(Start: Integer; const SourceText: string): Integer; -var +End; +Function BeginOfAttribute(Start: Integer; Const SourceText: string): Integer; +Var P, L: Integer; -begin +Begin // parses the beginning of an attribute: space + alpha character Result := 0; L := Length(SourceText); - if L = 0 then + If L = 0 Then Exit; P := PosStr(' ', SourceText, Start); - if P = 0 then + If P = 0 Then Exit; P := PosNonSpace(P, SourceText); - if P = 0 then + If P = 0 Then Exit; - if (SourceText[P] in ['a'..'z', 'A'..'Z']) then + If (SourceText[P] in ['a'..'z', 'A'..'Z']) Then Result := P; -end; -function ParseAttribute(var Start: Integer; const SourceText: string; - var AName, AValue: string): Boolean; -var +End; +Function ParseAttribute(Var Start: Integer; Const SourceText: string; + Var AName, AValue: string): Boolean; +Var PN, PV, P: Integer; -begin +Begin // parses a name="value" attribute from Start; returns 0 when not found or else the position behind the attribute Result := False; PN := BeginOfAttribute(Start, SourceText); - if PN = 0 then + If PN = 0 Then Exit; P := PosStr('="', SourceText, PN); - if P = 0 then + If P = 0 Then Exit; AName := Trim(Copy(SourceText, PN, P - PN)); PV := P + 2; P := PosStr('"', SourceText, PV); - if P = 0 then + If P = 0 Then Exit; AValue := Copy(SourceText, PV, P - PV); Start := P + 1; Result := True; -end; -procedure ParseAttributes(const SourceText: string; Attributes: TStrings); -var +End; +Procedure ParseAttributes(Const SourceText: string; Attributes: TStrings); +Var Name, Value: string; Start: Integer; -begin +Begin Attributes.BeginUpdate; - try + Try Attributes.Clear; Start := 1; - while ParseAttribute(Start, SourceText, Name, Value) do + While ParseAttribute(Start, SourceText, Name, Value) Do Attributes.Add(Name + '=' + Value); - finally + Finally Attributes.EndUpdate; - end; -end; -function GetToken(var Start: Integer; const SourceText: string): string; -var + End; +End; +Function GetToken(Var Start: Integer; Const SourceText: string): string; +Var P1, P2: Integer; -begin +Begin Result := ''; - if Start > Length(SourceText) then + If Start > Length(SourceText) Then Exit; P1 := PosNonSpace(Start, SourceText); - if P1 = 0 then + If P1 = 0 Then Exit; - if SourceText[P1] = '"' then - begin // quoted token + If SourceText[P1] = '"' Then + Begin // quoted token P2 := PosStr('"', SourceText, P1 + 1); - if P2 = 0 then + If P2 = 0 Then Exit; Result := Copy(SourceText, P1 + 1, P2 - P1 - 1); Start := P2 + 1; - end - else - begin + End + Else + Begin P2 := PosStr(' ', SourceText, P1 + 1); - if P2 = 0 then + If P2 = 0 Then P2 := Length(SourceText) + 1; Result := Copy(SourceText, P1, P2 - P1); Start := P2; - end; -end; -function Easter(NYear: Integer): TDateTime; -var + End; +End; +Function Easter(NYear: Integer): TDateTime; +Var NMonth, NDay, NMoon, NEpact, NSunday, NGold, NCent, NCorX, NCorZ: Integer; -begin +Begin { The Golden Number of the year in the 19 year Metonic Cycle } NGold := ((NYear mod 19) + 1); { Calculate the Century } @@ -557,41 +557,41 @@ function Easter(NYear: Integer): TDateTime; NSunday := ((5 * NYear) div 4 - NCorX - 10); { Set Epact (specifies occurance of full moon } NEpact := ((11 * NGold + 20 + NCorZ - NCorX) mod 30); - if (NEpact < 0) then + If (NEpact < 0) Then NEpact := NEpact + 30; - if ((NEpact = 25) and (NGold > 11)) or (NEpact = 24) then + If ((NEpact = 25) and (NGold > 11)) or (NEpact = 24) Then NEpact := NEpact + 1; { Find Full Moon } NMoon := 44 - NEpact; - if (NMoon < 21) then + If (NMoon < 21) Then NMoon := NMoon + 30; { Advance to Sunday } NMoon := (NMoon + 7 - ((NSunday + NMoon) mod 7)); - if (NMoon > 31) then - begin + If (NMoon > 31) Then + Begin NMonth := 4; NDay := (NMoon - 31); - end - else - begin + End + Else + Begin NMonth := 3; NDay := NMoon; - end; + End; Result := EncodeDate(NYear, NMonth, NDay); -end; +End; //gets a datecode. Returns year and weeknumber in format: YYWW {DayOfWeek function returns Integer 1..7 equivalent to Sunday..Saturday. ISO 8601 weeks Start with Monday and the first week of a year is the one which includes the first Thursday - Fiddle takes care of all this} -function GetWeekNumber(Today: TDateTime): string; -const - Fiddle: array [1..7] of Byte = (6, 7, 8, 9, 10, 4, 5); -var +Function GetWeekNumber(Today: TDateTime): string; +Const + Fiddle: array [1..7] Of Byte = (6, 7, 8, 9, 10, 4, 5); +Var Present, StartOfYear: TDateTime; FirstDayOfYear, WeekNumber, NumberOfDays: Integer; Year, Month, Day: Word; YearNumber: string; -begin +Begin Present := Trunc(Today); //truncate to remove hours, mins and secs DecodeDate(Present, Year, Month, Day); //decode to find year StartOfYear := EncodeDate(Year, 1, 1); //encode 1st Jan of the year @@ -604,1091 +604,1091 @@ function GetWeekNumber(Today: TDateTime): string; //Format year, needed to prevent millenium bug and keep the Fluffy Spangle happy YearNumber := FormatDateTime('yyyy', Present); YearNumber := YearNumber + 'W'; - if WeekNumber < 10 then + If WeekNumber < 10 Then YearNumber := YearNumber + '0'; //add leading zero for week //create datecode string Result := YearNumber + IntToStr(WeekNumber); - if WeekNumber = 0 then //recursive call for year begin/end... + If WeekNumber = 0 Then //recursive call for year begin/end... //see if previous year end was week 52 or 53 Result := GetWeekNumber(EncodeDate(Year - 1, 12, 31)) - else - if WeekNumber = 53 then + Else + If WeekNumber = 53 Then //if 31st December less than Thursday then must be week 01 of next year - if DayOfWeek(EncodeDate(Year, 12, 31)) < 5 then - begin + If DayOfWeek(EncodeDate(Year, 12, 31)) < 5 Then + Begin YearNumber := FormatDateTime('yyyy', EncodeDate(Year + 1, 1, 1)); Result := YearNumber + 'W01'; - end; -end; -function RelativePath(const ASrc, ADst: string): string; -var + End; +End; +Function RelativePath(Const ASrc, ADst: string): string; +Var Doc, SDoc, ParDoc, Img, SImg, ParImg, Rel: string; PDoc, PImg: Integer; -begin +Begin Doc := ASrc; Img := ADst; - repeat + Repeat PDoc := Pos('\', Doc); - if PDoc > 0 then - begin + If PDoc > 0 Then + Begin ParDoc := Copy(Doc, 1, PDoc); ParDoc[Length(ParDoc)] := '/'; SDoc := SDoc + ParDoc; Delete(Doc, 1, PDoc); - end; + End; PImg := Pos('\', Img); - if PImg > 0 then - begin + If PImg > 0 Then + Begin ParImg := Copy(Img, 1, PImg); ParImg[Length(ParImg)] := '/'; SImg := SImg + ParImg; Delete(Img, 1, PImg); - end; - if (PDoc > 0) and (PImg > 0) and (SDoc <> SImg) then + End; + If (PDoc > 0) and (PImg > 0) and (SDoc <> SImg) Then Rel := '../' + Rel + ParImg; - if (PDoc = 0) and (PImg <> 0) then - begin + If (PDoc = 0) and (PImg <> 0) Then + Begin Rel := Rel + ParImg + Img; - if Pos(':', Rel) > 0 then + If Pos(':', Rel) > 0 Then Rel := ''; Result := Rel; Exit; - end; - if (PDoc > 0) and (PImg = 0) then - begin + End; + If (PDoc > 0) and (PImg = 0) Then + Begin Rel := '../' + Rel; - end; - until (PDoc = 0) and (PImg = 0); + End; + Until (PDoc = 0) and (PImg = 0); Rel := Rel + SysUtils.ExtractFileName(Img); - if Pos(':', Rel) > 0 then + If Pos(':', Rel) > 0 Then Rel := ''; Result := Rel; -end; -procedure GetHTMLAnchors(const AFile: string; AList: TStringList); -var +End; +Procedure GetHTMLAnchors(Const AFile: string; AList: TStringList); +Var S, SA: string; P1, P2: Integer; -begin +Begin S := LoadString(AFile); P1 := 1; - repeat + Repeat P1 := PosText(' 0 then - begin + If P2 <> 0 Then + Begin SA := Copy(S, P1 + 9, P2 - P1 - 9); AList.Add(SA); P1 := P2; - end - else + End + Else P1 := 0; - end; - until P1 = 0; -end; -function UppercaseHTMLTags(const AText: string): string; -var + End; + Until P1 = 0; +End; +Function UppercaseHTMLTags(Const AText: string): string; +Var P, P2: Integer; -begin +Begin Result := ''; P2 := 1; - repeat + Repeat P := PosStr('<', AText, P2); - if P > 0 then - begin + If P > 0 Then + Begin Result := Result + Copy(AText, P2, P - P2); P2 := P; - if Copy(AText, P, 4) = '', AText, P); - if P > 0 then - begin + If P > 0 Then + Begin Result := Result + Copy(AText, P2, P + 3 - P2); P2 := P + 3; - end - else + End + Else Result := Result + Copy(AText, P2, Length(AText)); - end - else - begin + End + Else + Begin P := PosStr('>', AText, P); - if P > 0 then - begin + If P > 0 Then + Begin Result := Result + UpperCase(Copy(AText, P2, P - P2 + 1)); P2 := P + 1; - end - else + End + Else Result := Result + Copy(AText, P2, Length(AText)); - end; - end - else - begin + End; + End + Else + Begin Result := Result + Copy(AText, P2, Length(AText)); - end; - until P = 0; -end; -function LowercaseHTMLTags(const AText: string): string; -var + End; + Until P = 0; +End; +Function LowercaseHTMLTags(Const AText: string): string; +Var P, P2: Integer; -begin +Begin Result := ''; P2 := 1; - repeat + Repeat P := PosStr('<', AText, P2); - if P > 0 then - begin + If P > 0 Then + Begin Result := Result + Copy(AText, P2, P - P2); P2 := P; // now check for comments - if Copy(AText, P, 4) = '', AText, P); - if P > 0 then - begin + If P > 0 Then + Begin Result := Result + Copy(AText, P2, P + 3 - P2); P2 := P + 3; - end - else + End + Else Result := Result + Copy(AText, P2, Length(AText)); - end - else - begin + End + Else + Begin P := PosStr('>', AText, P); - if P > 0 then - begin + If P > 0 Then + Begin Result := Result + LowerCase(Copy(AText, P2, P - P2 + 1)); P2 := P + 1; - end - else + End + Else Result := Result + Copy(AText, P2, Length(AText)); - end; - end - else - begin + End; + End + Else + Begin Result := Result + Copy(AText, P2, Length(AText)); - end; - until P = 0; -end; -function PosEscaped(Start: Integer; const SourceText, FindText: string; EscapeChar: Char): Integer; -begin + End; + Until P = 0; +End; +Function PosEscaped(Start: Integer; Const SourceText, FindText: string; EscapeChar: Char): Integer; +Begin Result := PosText(FindText, SourceText, Start); - if Result = 0 then + If Result = 0 Then Exit; - if Result = 1 then + If Result = 1 Then Exit; - if SourceText[Result - 1] <> EscapeChar then + If SourceText[Result - 1] <> EscapeChar Then Exit; - repeat + Repeat Result := PosText(FindText, SourceText, Result + 1); - if Result = 0 then + If Result = 0 Then Exit; - until SourceText[Result - 1] <> EscapeChar; -end; -function DeleteEscaped(const SourceText: string; EscapeChar: Char): string; -var + Until SourceText[Result - 1] <> EscapeChar; +End; +Function DeleteEscaped(Const SourceText: string; EscapeChar: Char): string; +Var I: Integer; RealLen: Integer; -begin +Begin RealLen := 0; SetLength(Result, Length(SourceText)); - for I := 1 to Length(SourceText) do - if SourceText[I] <> EscapeChar then - begin + For I := 1 To Length(SourceText) Do + If SourceText[I] <> EscapeChar Then + Begin Inc(RealLen); Result[RealLen] := SourceText[I]; - end; + End; SetLength(Result, RealLen); -end; -procedure RecurseDirFiles(const ADir: string; var AFileList: TStringList); -var +End; +Procedure RecurseDirFiles(Const ADir: string; Var AFileList: TStringList); +Var SR: TSearchRec; FileAttrs: Integer; -begin +Begin FileAttrs := faAnyFile or faDirectory; - if FindFirst(ADir + PathDelim + AllFilePattern, FileAttrs, SR) = 0 then - while FindNext(SR) = 0 do - if (SR.Attr and faDirectory) <> 0 then - begin - if (SR.Name <> '.') and (SR.Name <> '..') then + If FindFirst(ADir + PathDelim + AllFilePattern, FileAttrs, SR) = 0 Then + While FindNext(SR) = 0 Do + If (SR.Attr and faDirectory) <> 0 Then + Begin + If (SR.Name <> '.') and (SR.Name <> '..') Then RecurseDirFiles(ADir + PathDelim + SR.Name, AFileList); - end - else + End + Else AFileList.Add(ADir + PathDelim + SR.Name); FindClose(SR); -end; -procedure RecurseDirProgs(const ADir: string; var AFileList: TStringList); -var +End; +Procedure RecurseDirProgs(Const ADir: string; Var AFileList: TStringList); +Var SR: TSearchRec; FileAttrs: Integer; E: string; {$IFDEF UNIX} ST: TStatBuf; {$ENDIF UNIX} -begin +Begin FileAttrs := faAnyFile or faDirectory; - if FindFirst(ADir + PathDelim + AllFilePattern, FileAttrs, SR) = 0 then - while FindNext(SR) = 0 do - begin - if (SR.Attr and faDirectory) <> 0 then - begin - if (SR.Name <> '.') and (SR.Name <> '..') then + If FindFirst(ADir + PathDelim + AllFilePattern, FileAttrs, SR) = 0 Then + While FindNext(SR) = 0 Do + Begin + If (SR.Attr and faDirectory) <> 0 Then + Begin + If (SR.Name <> '.') and (SR.Name <> '..') Then RecurseDirProgs(ADir + PathDelim + SR.Name, AFileList); - end + End {$IFDEF MSWINDOWS} - else - begin + Else + Begin E := SysUtils.LowerCase(SysUtils.ExtractFileExt(SR.Name)); - if E = '.exe' then + If E = '.exe' Then AFileList.Add(ADir + PathDelim + SR.Name); - end; + End; {$ENDIF MSWINDOWS} {$IFDEF UNIX} - else - begin - if stat(PChar(ADir + PathDelim + SR.Name), ST) = 0 then - begin - if ST.st_mode and (S_IXUSR or S_IXGRP or S_IXOTH) <> 0 then + Else + Begin + If stat(PChar(ADir + PathDelim + SR.Name), ST) = 0 Then + Begin + If ST.st_mode and (S_IXUSR or S_IXGRP or S_IXOTH) <> 0 Then AFileList.Add(ADir + PathDelim + SR.Name); - end; - end; + End; + End; {$ENDIF UNIX} - end; + End; FindClose(SR); -end; -procedure LoadResourceFile(AFile: string; MemStream: TMemoryStream); -var +End; +Procedure LoadResourceFile(AFile: string; MemStream: TMemoryStream); +Var ResStream: TResourceStream; Ext: string; -begin +Begin Ext := SysUtils.UpperCase(SysUtils.ExtractFileExt(AFile)); Ext := Copy(Ext, 2, Length(Ext)); - if Ext = 'HTM' then + If Ext = 'HTM' Then Ext := 'HTML'; AFile := SysUtils.ChangeFileExt(AFile, ''); ResStream := TResourceStream.Create(HInstance, PChar(AFile), PChar(Ext)); - try + Try MemStream.CopyFrom(ResStream, ResStream.Size); - finally + Finally ResStream.Free; - end; -end; -procedure GetNames(AText: string; AList: TStringList); -var + End; +End; +Procedure GetNames(AText: string; AList: TStringList); +Var P: Integer; S: string; -begin +Begin AList.Clear; - repeat + Repeat AText := Trim(AText); P := Pos('="', AText); - if P > 0 then - begin + If P > 0 Then + Begin S := Copy(AText, 1, P - 1); AList.Add(S); Delete(AText, 1, P + 1); P := Pos('"', AText); - if P > 0 then + If P > 0 Then Delete(AText, 1, P); - end; - until P = 0; -end; -function NameValuesToXML(const AText: string): string; -var + End; + Until P = 0; +End; +Function NameValuesToXML(Const AText: string): string; +Var AList: TStringList; I, C: Integer; IName, IValue, Xml: string; -begin +Begin Result := ''; - if AText = '' then + If AText = '' Then Exit; AList := TStringList.Create; GetNames(AText, AList); C := AList.Count; - if C = 0 then - begin + If C = 0 Then + Begin AList.Free; Exit - end; + End; Xml := '' + Cr; - for I := 0 to C - 1 do - begin + For I := 0 To C - 1 Do + Begin IName := AList[I]; IValue := GetValue(AText, IName); IValue := SysUtils.StringReplace(IValue, '~~', Cr, [rfReplaceAll]); Xml := Xml + '<' + IName + '>' + Cr; Xml := Xml + ' ' + IValue + Cr; Xml := Xml + '' + Cr; - end; + End; Xml := Xml + '' + Cr; AList.Free; Result := Xml; -end; -function LastPosChar(const FindChar: Char; SourceString: string): Integer; -var +End; +Function LastPosChar(Const FindChar: Char; SourceString: string): Integer; +Var I: Integer; -begin +Begin I := Length(SourceString); - while (I > 0) and (SourceString[I] <> FindChar) do + While (I > 0) and (SourceString[I] <> FindChar) Do Dec(I); Result := I; -end; -function PosStr(const FindString, SourceString: string; StartPos: Integer): Integer; -var +End; +Function PosStr(Const FindString, SourceString: string; StartPos: Integer): Integer; +Var P: PChar; -begin +Begin Result := 0; - if (FindString <> '') and (SourceString <> '') and (StartPos <= Length(SourceString)) then - begin + If (FindString <> '') and (SourceString <> '') and (StartPos <= Length(SourceString)) Then + Begin P := StrPos(PChar(SourceString) + StartPos - 1, PChar(FindString)); - if P <> nil then + If P <> nil Then Result := P - PChar(SourceString) + 1; - end; -end; -function PosText(const FindString, SourceString: string; StartPos: Integer): Integer; -begin + End; +End; +Function PosText(Const FindString, SourceString: string; StartPos: Integer): Integer; +Begin // Not the fastest implementation but the JCL doesn't have a better one, either. Result := Pos(UpperCase(FindString), UpperCase(Copy(SourceString, StartPos, MaxInt))); - if Result <> 0 then + If Result <> 0 Then Result := Result + StartPos - 1; -end; -function GetBoolValue(const AText, AName: string): Boolean; -begin +End; +Function GetBoolValue(Const AText, AName: string): Boolean; +Begin Result := CompareText(GetValue(AText, AName), 'yes') = 0; -end; -procedure ListSelect(Src, Dst: TStringList; const AKey, AValue: string); -var +End; +Procedure ListSelect(Src, Dst: TStringList; Const AKey, AValue: string); +Var I: Integer; -begin +Begin Dst.Clear; - for I := 0 to Src.Count - 1 do - begin - if GetValue(Src[I], AKey) = AValue then + For I := 0 To Src.Count - 1 Do + Begin + If GetValue(Src[I], AKey) = AValue Then Dst.Add(Src[I]); - end; -end; -procedure ListFilter(Src: TStringList; const AKey, AValue: string); -var + End; +End; +Procedure ListFilter(Src: TStringList; Const AKey, AValue: string); +Var I: Integer; Dst: TStringList; -begin +Begin Dst := TStringList.Create; - for I := 0 to Src.Count - 1 do - begin - if GetValue(Src[I], AKey) = AValue then + For I := 0 To Src.Count - 1 Do + Begin + If GetValue(Src[I], AKey) = AValue Then Dst.Add(Src[I]); - end; + End; Src.Assign(Dst); Dst.Free; -end; -procedure ListOrderBy(Src: TStringList; const AKey: string; Numeric: Boolean); -var +End; +Procedure ListOrderBy(Src: TStringList; Const AKey: string; Numeric: Boolean); +Var I, Index: Integer; Lit, Dst: TStringList; S: string; IValue: Integer; -begin - if Src.Count < 2 then +Begin + If Src.Count < 2 Then Exit; // nothing to sort Lit := TStringList.Create; Dst := TStringList.Create; - for I := 0 to Src.Count - 1 do - begin + For I := 0 To Src.Count - 1 Do + Begin S := GetValue(Src[I], AKey); - if Numeric then - try + If Numeric Then + Try IValue := StrToInt(S); // format to 5 decimal places for correct string sorting // e.g. 5 becomes 00005 S := Format('%5.5d', [IValue]); - except + Except // just use the unformatted value - end; + End; {$IFNDEF FPC} Lit.AddObject(S, TObject(I)); {$ELSE} Lit.AddObject(S, TObject(@I)); {$ENDIF} - end; + End; Lit.Sort; - for I := 0 to Src.Count - 1 do - begin + For I := 0 To Src.Count - 1 Do + Begin {$IFNDEF FPC} Index := Integer(Lit.Objects[I]); {$ELSE} Index := PInteger(Lit.Objects[I])^; {$ENDIF} Dst.Add(Src[Index]); - end; + End; Lit.Free; Src.Assign(Dst); Dst.Free; -end; +End; // converts a csv list to a tagged string list -procedure CSVToTags(Src, Dst: TStringList); -var +Procedure CSVToTags(Src, Dst: TStringList); +Var I, FI, FC: Integer; Names: TStringList; Rec: TStringList; S: string; -begin +Begin Dst.Clear; - if Src.Count < 2 then + If Src.Count < 2 Then Exit; Names := TStringList.Create; Rec := TStringList.Create; - try + Try Names.CommaText := Src[0]; FC := Names.Count; - if FC > 0 then - for I := 1 to Src.Count - 1 do - begin + If FC > 0 Then + For I := 1 To Src.Count - 1 Do + Begin Rec.CommaText := Src[I]; S := ''; - for FI := 0 to FC - 1 do + For FI := 0 To FC - 1 Do S := S + Names[FI] + '="' + Rec[FI] + '" '; Dst.Add(S); - end; - finally + End; + Finally Rec.Free; Names.Free; - end; -end; + End; +End; // converts a tagged string list to a csv list // only fieldnames from the first record are scanned ib the other records -procedure TagsToCSV(Src, Dst: TStringList); -var +Procedure TagsToCSV(Src, Dst: TStringList); +Var I, FI, FC: Integer; Names: TStringList; Rec: TStringList; S: string; -begin +Begin Dst.Clear; - if Src.Count < 1 then + If Src.Count < 1 Then Exit; Names := TStringList.Create; Rec := TStringList.Create; - try + Try GetNames(Src[0], Names); FC := Names.Count; - if FC > 0 then - begin + If FC > 0 Then + Begin Dst.Add(Names.CommaText); - for I := 0 to Src.Count - 1 do - begin + For I := 0 To Src.Count - 1 Do + Begin S := ''; Rec.Clear; - for FI := 0 to FC - 1 do + For FI := 0 To FC - 1 Do Rec.Add(GetValue(Src[I], Names[FI])); Dst.Add(Rec.CommaText); - end; - end; - finally + End; + End; + Finally Rec.Free; Names.Free; - end; -end; -function B64Encode(const S: AnsiString): AnsiString; -var + End; +End; +Function B64Encode(Const S: AnsiString): AnsiString; +Var I: Integer; - InBuf: array [0..2] of Byte; - OutBuf: array [0..3] of AnsiChar; -begin + InBuf: array [0..2] Of Byte; + OutBuf: array [0..3] Of AnsiChar; +Begin SetLength(Result, ((Length(S) + 2) div 3) * 4); - for I := 1 to ((Length(S) + 2) div 3) do - begin - if Length(S) < (I * 3) then + For I := 1 To ((Length(S) + 2) div 3) Do + Begin + If Length(S) < (I * 3) Then Move(S[(I - 1) * 3 + 1], InBuf, Length(S) - (I - 1) * 3) - else + Else Move(S[(I - 1) * 3 + 1], InBuf, 3); OutBuf[0] := B64Table[((InBuf[0] and $FC) shr 2) + 1]; OutBuf[1] := B64Table[(((InBuf[0] and $03) shl 4) or ((InBuf[1] and $F0) shr 4)) + 1]; OutBuf[2] := B64Table[(((InBuf[1] and $0F) shl 2) or ((InBuf[2] and $C0) shr 6)) + 1]; OutBuf[3] := B64Table[(InBuf[2] and $3F) + 1]; Move(OutBuf, Result[(I - 1) * 4 + 1], 4); - end; - if (Length(S) mod 3) = 1 then - begin + End; + If (Length(S) mod 3) = 1 Then + Begin Result[Length(Result) - 1] := '='; Result[Length(Result)] := '='; - end - else - if (Length(S) mod 3) = 2 then + End + Else + If (Length(S) mod 3) = 2 Then Result[Length(Result)] := '='; -end; -function B64Decode(const S: AnsiString): AnsiString; -var +End; +Function B64Decode(Const S: AnsiString): AnsiString; +Var I: Integer; - InBuf: array [0..3] of Byte; - OutBuf: array [0..2] of Byte; + InBuf: array [0..3] Of Byte; + OutBuf: array [0..2] Of Byte; RetValue: AnsiString; -begin - if ((Length(S) mod 4) <> 0) or (S = '') then +Begin + If ((Length(S) mod 4) <> 0) or (S = '') Then raise EJVCLException.CreateRes({$IFNDEF CLR}@{$ENDIF}RsEIncorrectStringFormat); SetLength(RetValue, ((Length(S) div 4) - 1) * 3); - for I := 1 to ((Length(S) div 4) - 1) do - begin + For I := 1 To ((Length(S) div 4) - 1) Do + Begin Move(S[(I - 1) * 4 + 1], InBuf, 4); - if (InBuf[0] > 64) and (InBuf[0] < 91) then + If (InBuf[0] > 64) and (InBuf[0] < 91) Then Dec(InBuf[0], 65) - else - if (InBuf[0] > 96) and (InBuf[0] < 123) then + Else + If (InBuf[0] > 96) and (InBuf[0] < 123) Then Dec(InBuf[0], 71) - else - if (InBuf[0] > 47) and (InBuf[0] < 58) then + Else + If (InBuf[0] > 47) and (InBuf[0] < 58) Then Inc(InBuf[0], 4) - else - if InBuf[0] = 43 then + Else + If InBuf[0] = 43 Then InBuf[0] := 62 - else + Else InBuf[0] := 63; - if (InBuf[1] > 64) and (InBuf[1] < 91) then + If (InBuf[1] > 64) and (InBuf[1] < 91) Then Dec(InBuf[1], 65) - else - if (InBuf[1] > 96) and (InBuf[1] < 123) then + Else + If (InBuf[1] > 96) and (InBuf[1] < 123) Then Dec(InBuf[1], 71) - else - if (InBuf[1] > 47) and (InBuf[1] < 58) then + Else + If (InBuf[1] > 47) and (InBuf[1] < 58) Then Inc(InBuf[1], 4) - else - if InBuf[1] = 43 then + Else + If InBuf[1] = 43 Then InBuf[1] := 62 - else + Else InBuf[1] := 63; - if (InBuf[2] > 64) and (InBuf[2] < 91) then + If (InBuf[2] > 64) and (InBuf[2] < 91) Then Dec(InBuf[2], 65) - else - if (InBuf[2] > 96) and (InBuf[2] < 123) then + Else + If (InBuf[2] > 96) and (InBuf[2] < 123) Then Dec(InBuf[2], 71) - else - if (InBuf[2] > 47) and (InBuf[2] < 58) then + Else + If (InBuf[2] > 47) and (InBuf[2] < 58) Then Inc(InBuf[2], 4) - else - if InBuf[2] = 43 then + Else + If InBuf[2] = 43 Then InBuf[2] := 62 - else + Else InBuf[2] := 63; - if (InBuf[3] > 64) and (InBuf[3] < 91) then + If (InBuf[3] > 64) and (InBuf[3] < 91) Then Dec(InBuf[3], 65) - else - if (InBuf[3] > 96) and (InBuf[3] < 123) then + Else + If (InBuf[3] > 96) and (InBuf[3] < 123) Then Dec(InBuf[3], 71) - else - if (InBuf[3] > 47) and (InBuf[3] < 58) then + Else + If (InBuf[3] > 47) and (InBuf[3] < 58) Then Inc(InBuf[3], 4) - else - if InBuf[3] = 43 then + Else + If InBuf[3] = 43 Then InBuf[3] := 62 - else + Else InBuf[3] := 63; OutBuf[0] := (InBuf[0] shl 2) or ((InBuf[1] shr 4) and $03); OutBuf[1] := (InBuf[1] shl 4) or ((InBuf[2] shr 2) and $0F); OutBuf[2] := (InBuf[2] shl 6) or (InBuf[3] and $3F); Move(OutBuf, RetValue[(I - 1) * 3 + 1], 3); - end; - if S <> '' then - begin + End; + If S <> '' Then + Begin Move(S[Length(S) - 3], InBuf, 4); - if InBuf[2] = 61 then - begin - if (InBuf[0] > 64) and (InBuf[0] < 91) then + If InBuf[2] = 61 Then + Begin + If (InBuf[0] > 64) and (InBuf[0] < 91) Then Dec(InBuf[0], 65) - else - if (InBuf[0] > 96) and (InBuf[0] < 123) then + Else + If (InBuf[0] > 96) and (InBuf[0] < 123) Then Dec(InBuf[0], 71) - else - if (InBuf[0] > 47) and (InBuf[0] < 58) then + Else + If (InBuf[0] > 47) and (InBuf[0] < 58) Then Inc(InBuf[0], 4) - else - if InBuf[0] = 43 then + Else + If InBuf[0] = 43 Then InBuf[0] := 62 - else + Else InBuf[0] := 63; - if (InBuf[1] > 64) and (InBuf[1] < 91) then + If (InBuf[1] > 64) and (InBuf[1] < 91) Then Dec(InBuf[1], 65) - else - if (InBuf[1] > 96) and (InBuf[1] < 123) then + Else + If (InBuf[1] > 96) and (InBuf[1] < 123) Then Dec(InBuf[1], 71) - else - if (InBuf[1] > 47) and (InBuf[1] < 58) then + Else + If (InBuf[1] > 47) and (InBuf[1] < 58) Then Inc(InBuf[1], 4) - else - if InBuf[1] = 43 then + Else + If InBuf[1] = 43 Then InBuf[1] := 62 - else + Else InBuf[1] := 63; OutBuf[0] := (InBuf[0] shl 2) or ((InBuf[1] shr 4) and $03); RetValue := RetValue + AnsiChar(OutBuf[0]); - end - else - if InBuf[3] = 61 then - begin - if (InBuf[0] > 64) and (InBuf[0] < 91) then + End + Else + If InBuf[3] = 61 Then + Begin + If (InBuf[0] > 64) and (InBuf[0] < 91) Then Dec(InBuf[0], 65) - else - if (InBuf[0] > 96) and (InBuf[0] < 123) then + Else + If (InBuf[0] > 96) and (InBuf[0] < 123) Then Dec(InBuf[0], 71) - else - if (InBuf[0] > 47) and (InBuf[0] < 58) then + Else + If (InBuf[0] > 47) and (InBuf[0] < 58) Then Inc(InBuf[0], 4) - else - if InBuf[0] = 43 then + Else + If InBuf[0] = 43 Then InBuf[0] := 62 - else + Else InBuf[0] := 63; - if (InBuf[1] > 64) and (InBuf[1] < 91) then + If (InBuf[1] > 64) and (InBuf[1] < 91) Then Dec(InBuf[1], 65) - else - if (InBuf[1] > 96) and (InBuf[1] < 123) then + Else + If (InBuf[1] > 96) and (InBuf[1] < 123) Then Dec(InBuf[1], 71) - else - if (InBuf[1] > 47) and (InBuf[1] < 58) then + Else + If (InBuf[1] > 47) and (InBuf[1] < 58) Then Inc(InBuf[1], 4) - else - if InBuf[1] = 43 then + Else + If InBuf[1] = 43 Then InBuf[1] := 62 - else + Else InBuf[1] := 63; - if (InBuf[2] > 64) and (InBuf[2] < 91) then + If (InBuf[2] > 64) and (InBuf[2] < 91) Then Dec(InBuf[2], 65) - else - if (InBuf[2] > 96) and (InBuf[2] < 123) then + Else + If (InBuf[2] > 96) and (InBuf[2] < 123) Then Dec(InBuf[2], 71) - else - if (InBuf[2] > 47) and (InBuf[2] < 58) then + Else + If (InBuf[2] > 47) and (InBuf[2] < 58) Then Inc(InBuf[2], 4) - else - if InBuf[2] = 43 then + Else + If InBuf[2] = 43 Then InBuf[2] := 62 - else + Else InBuf[2] := 63; OutBuf[0] := (InBuf[0] shl 2) or ((InBuf[1] shr 4) and $03); OutBuf[1] := (InBuf[1] shl 4) or ((InBuf[2] shr 2) and $0F); RetValue := RetValue + AnsiChar(OutBuf[0]) + AnsiChar(OutBuf[1]); - end - else - begin - if (InBuf[0] > 64) and (InBuf[0] < 91) then + End + Else + Begin + If (InBuf[0] > 64) and (InBuf[0] < 91) Then Dec(InBuf[0], 65) - else - if (InBuf[0] > 96) and (InBuf[0] < 123) then + Else + If (InBuf[0] > 96) and (InBuf[0] < 123) Then Dec(InBuf[0], 71) - else - if (InBuf[0] > 47) and (InBuf[0] < 58) then + Else + If (InBuf[0] > 47) and (InBuf[0] < 58) Then Inc(InBuf[0], 4) - else - if InBuf[0] = 43 then + Else + If InBuf[0] = 43 Then InBuf[0] := 62 - else + Else InBuf[0] := 63; - if (InBuf[1] > 64) and (InBuf[1] < 91) then + If (InBuf[1] > 64) and (InBuf[1] < 91) Then Dec(InBuf[1], 65) - else - if (InBuf[1] > 96) and (InBuf[1] < 123) then + Else + If (InBuf[1] > 96) and (InBuf[1] < 123) Then Dec(InBuf[1], 71) - else - if (InBuf[1] > 47) and (InBuf[1] < 58) then + Else + If (InBuf[1] > 47) and (InBuf[1] < 58) Then Inc(InBuf[1], 4) - else - if InBuf[1] = 43 then + Else + If InBuf[1] = 43 Then InBuf[1] := 62 - else + Else InBuf[1] := 63; - if (InBuf[2] > 64) and (InBuf[2] < 91) then + If (InBuf[2] > 64) and (InBuf[2] < 91) Then Dec(InBuf[2], 65) - else - if (InBuf[2] > 96) and (InBuf[2] < 123) then + Else + If (InBuf[2] > 96) and (InBuf[2] < 123) Then Dec(InBuf[2], 71) - else - if (InBuf[2] > 47) and (InBuf[2] < 58) then + Else + If (InBuf[2] > 47) and (InBuf[2] < 58) Then Inc(InBuf[2], 4) - else - if InBuf[2] = 43 then + Else + If InBuf[2] = 43 Then InBuf[2] := 62 - else + Else InBuf[2] := 63; - if (InBuf[3] > 64) and (InBuf[3] < 91) then + If (InBuf[3] > 64) and (InBuf[3] < 91) Then Dec(InBuf[3], 65) - else - if (InBuf[3] > 96) and (InBuf[3] < 123) then + Else + If (InBuf[3] > 96) and (InBuf[3] < 123) Then Dec(InBuf[3], 71) - else - if (InBuf[3] > 47) and (InBuf[3] < 58) then + Else + If (InBuf[3] > 47) and (InBuf[3] < 58) Then Inc(InBuf[3], 4) - else - if InBuf[3] = 43 then + Else + If InBuf[3] = 43 Then InBuf[3] := 62 - else + Else InBuf[3] := 63; OutBuf[0] := (InBuf[0] shl 2) or ((InBuf[1] shr 4) and $03); OutBuf[1] := (InBuf[1] shl 4) or ((InBuf[2] shr 2) and $0F); OutBuf[2] := (InBuf[2] shl 6) or (InBuf[3] and $3F); RetValue := RetValue + AnsiChar(OutBuf[0]) + AnsiChar(OutBuf[1]) + AnsiChar(OutBuf[2]); - end; - end; + End; + End; Result := RetValue; -end; +End; {******************************************************* * Standard Encryption algorithm - Copied from Borland * *******************************************************} -function Encrypt(const InString: AnsiString; StartKey, MultKey, AddKey: Integer): AnsiString; -var +Function Encrypt(Const InString: AnsiString; StartKey, MultKey, AddKey: Integer): AnsiString; +Var I: Integer; -begin +Begin Result := ''; - for I := 1 to Length(InString) do - begin + For I := 1 To Length(InString) Do + Begin Result := Result + AnsiChar(Byte(InString[I]) xor (StartKey shr 8)); StartKey := (Byte(Result[I]) + StartKey) * MultKey + AddKey; - end; -end; + End; +End; {******************************************************* * Standard Decryption algorithm - Copied from Borland * *******************************************************} -function Decrypt(const InString: AnsiString; StartKey, MultKey, AddKey: Integer): AnsiString; -var +Function Decrypt(Const InString: AnsiString; StartKey, MultKey, AddKey: Integer): AnsiString; +Var I: Integer; -begin +Begin Result := ''; - for I := 1 to Length(InString) do - begin + For I := 1 To Length(InString) Do + Begin Result := Result + AnsiChar(Byte(InString[I]) xor (StartKey shr 8)); StartKey := (Byte(InString[I]) + StartKey) * MultKey + AddKey; - end; -end; -function EncryptB64(const InString: AnsiString; StartKey, MultKey, AddKey: Integer): AnsiString; -begin + End; +End; +Function EncryptB64(Const InString: AnsiString; StartKey, MultKey, AddKey: Integer): AnsiString; +Begin Result := B64Encode(Encrypt(InString, StartKey, MultKey, AddKey)); -end; -function DecryptB64(const InString: AnsiString; StartKey, MultKey, AddKey: Integer): AnsiString; -begin +End; +Function DecryptB64(Const InString: AnsiString; StartKey, MultKey, AddKey: Integer): AnsiString; +Begin Result := Decrypt(B64Decode(InString), StartKey, MultKey, AddKey); -end; -function Hash(const AText: string): Integer; -var +End; +Function Hash(Const AText: string): Integer; +Var I: Integer; -begin +Begin Result := 0; - if AText = '' then + If AText = '' Then Exit; Result := Ord(AText[1]); - for I := 2 to Length(AText) do + For I := 2 To Length(AText) Do Result := (Result * Ord(AText[I])) xor Result; -end; +End; -function FirstOfSet(const AText: string): string; -var +Function FirstOfSet(Const AText: string): string; +Var P: Integer; -begin +Begin Result := Trim(AText); - if Result = '' then + If Result = '' Then Exit; - if Result[1] = '"' then - begin + If Result[1] = '"' Then + Begin P := PosStr('"', Result, 2); Result := Copy(Result, 2, P - 2); - end - else - begin + End + Else + Begin P := Pos(' ', Result); Result := Copy(Result, 1, P - 1); - end; -end; -function LastOfSet(const AText: string): string; -var + End; +End; +Function LastOfSet(Const AText: string): string; +Var C: Integer; -begin +Begin Result := Trim(AText); - if Result = '' then + If Result = '' Then Exit; C := Length(Result); - if Result[C] = '"' then - begin - while (C > 1) and (Result[C - 1] <> '"') do + If Result[C] = '"' Then + Begin + While (C > 1) and (Result[C - 1] <> '"') Do Dec(C); Result := Copy(Result, C, Length(Result) - C); - end - else - begin - while (C > 1) and (Result[C - 1] <> ' ') do + End + Else + Begin + While (C > 1) and (Result[C - 1] <> ' ') Do Dec(C); Result := Copy(Result, C, Length(Result)); - end; -end; -function CountOfSet(const AText: string): Integer; -var + End; +End; +Function CountOfSet(Const AText: string): Integer; +Var Lit: TStringList; -begin +Begin Lit := TStringList.Create; SplitSet(AText, Lit); Result := Lit.Count; Lit.Free; -end; -function SetRotateRight(const AText: string): string; -var +End; +Function SetRotateRight(Const AText: string): string; +Var Lit: TStringList; C: Integer; -begin +Begin Lit := TStringList.Create; SplitSet(AText, Lit); C := Lit.Count; - if C > 0 then - begin + If C > 0 Then + Begin Lit.Move(C - 1, 0); Result := JoinSet(Lit); - end - else + End + Else Result := ''; Lit.Free; -end; -function SetRotateLeft(const AText: string): string; -var +End; +Function SetRotateLeft(Const AText: string): string; +Var Lit: TStringList; C: Integer; -begin +Begin Lit := TStringList.Create; SplitSet(AText, Lit); C := Lit.Count; - if C > 0 then - begin + If C > 0 Then + Begin Lit.Move(0, C - 1); Result := JoinSet(Lit); - end - else + End + Else Result := ''; Lit.Free; -end; -procedure SplitSet(AText: string; AList: TStringList); -var +End; +Procedure SplitSet(AText: string; AList: TStringList); +Var P: Integer; -begin +Begin AList.Clear; - if AText = '' then + If AText = '' Then Exit; AText := Trim(AText); - while AText <> '' do - begin - if AText[1] = '"' then - begin + While AText <> '' Do + Begin + If AText[1] = '"' Then + Begin Delete(AText, 1, 1); P := Pos('"', AText); - if P <> 0 then - begin + If P <> 0 Then + Begin AList.Add(Copy(AText, 1, P - 1)); Delete(AText, 1, P); - end; - end - else - begin + End; + End + Else + Begin P := Pos(' ', AText); - if P = 0 then - begin + If P = 0 Then + Begin AList.Add(AText); AText := ''; - end - else - begin + End + Else + Begin AList.Add(Copy(AText, 1, P - 1)); Delete(AText, 1, P); - end; - end; + End; + End; AText := Trim(AText); - end; -end; -function JoinSet(AList: TStringList): string; -var + End; +End; +Function JoinSet(AList: TStringList): string; +Var I: Integer; -begin +Begin Result := ''; - for I := 0 to AList.Count - 1 do + For I := 0 To AList.Count - 1 Do Result := Result + AList[I] + ' '; Delete(Result, Length(Result), 1); -end; -function SetPick(const AText: string; AIndex: Integer): string; -var +End; +Function SetPick(Const AText: string; AIndex: Integer): string; +Var Lit: TStringList; C: Integer; -begin +Begin Lit := TStringList.Create; SplitSet(AText, Lit); C := Lit.Count; - if (C > 0) and (AIndex < C) then + If (C > 0) and (AIndex < C) Then Result := Lit[AIndex] - else + Else Result := ''; Lit.Free; -end; -function SetSort(const AText: string): string; -var +End; +Function SetSort(Const AText: string): string; +Var Lit: TStringList; -begin +Begin Lit := TStringList.Create; SplitSet(AText, Lit); - if Lit.Count > 0 then - begin + If Lit.Count > 0 Then + Begin Lit.Sort; Result := JoinSet(Lit); - end - else + End + Else Result := ''; Lit.Free; -end; -function SetUnion(const Set1, Set2: string): string; -var +End; +Function SetUnion(Const Set1, Set2: string): string; +Var Lit1, Lit2, Lit3: TStringList; I, C: Integer; -begin +Begin Lit1 := TStringList.Create; Lit2 := TStringList.Create; Lit3 := TStringList.Create; SplitSet(Set1, Lit1); SplitSet(Set2, Lit2); C := Lit2.Count; - if C <> 0 then - begin + If C <> 0 Then + Begin Lit2.Addstrings(Lit1); - for I := 0 to Lit2.Count - 1 do - if Lit3.IndexOf(Lit2[I]) = -1 then + For I := 0 To Lit2.Count - 1 Do + If Lit3.IndexOf(Lit2[I]) = -1 Then Lit3.Add(Lit2[I]); Result := JoinSet(Lit3); - end - else - begin + End + Else + Begin Result := JoinSet(Lit1); - end; + End; Lit1.Free; Lit2.Free; Lit3.Free; -end; -function SetIntersect(const Set1, Set2: string): string; -var +End; +Function SetIntersect(Const Set1, Set2: string): string; +Var Lit1, Lit2, Lit3: TStringList; I: Integer; -begin +Begin Lit1 := TStringList.Create; Lit2 := TStringList.Create; Lit3 := TStringList.Create; SplitSet(Set1, Lit1); SplitSet(Set2, Lit2); - if Lit2.Count <> 0 then - begin - for I := 0 to Lit2.Count - 1 do - if Lit1.IndexOf(Lit2[I]) <> -1 then + If Lit2.Count <> 0 Then + Begin + For I := 0 To Lit2.Count - 1 Do + If Lit1.IndexOf(Lit2[I]) <> -1 Then Lit3.Add(Lit2[I]); Result := JoinSet(Lit3); - end - else + End + Else Result := ''; Lit1.Free; Lit2.Free; Lit3.Free; -end; -function SetExclude(const Set1, Set2: string): string; -var +End; +Function SetExclude(Const Set1, Set2: string): string; +Var Lit1, Lit2: TStringList; I, Index: Integer; -begin +Begin Lit1 := TStringList.Create; Lit2 := TStringList.Create; SplitSet(Set1, Lit1); SplitSet(Set2, Lit2); - if Lit2.Count <> 0 then - begin - for I := 0 to Lit2.Count - 1 do - begin + If Lit2.Count <> 0 Then + Begin + For I := 0 To Lit2.Count - 1 Do + Begin Index := Lit1.IndexOf(Lit2[I]); - if Index <> -1 then + If Index <> -1 Then Lit1.Delete(Index); - end; + End; Result := JoinSet(Lit1); - end - else + End + Else Result := JoinSet(Lit1); Lit1.Free; Lit2.Free; -end; +End; // This function converts a string into a RFC 1630 compliant URL -function URLEncode(const Value: AnsiString): AnsiString; -var +Function URLEncode(Const Value: AnsiString): AnsiString; +Var I: Integer; -begin +Begin Result := ''; - for I := 1 to Length(Value) do - if Pos(UpperCase(Value[I]), ValidURLChars) > 0 then + For I := 1 To Length(Value) Do + If Pos(UpperCase(Value[I]), ValidURLChars) > 0 Then Result := Result + Value[I] - else - begin - if Value[I] = ' ' then + Else + Begin + If Value[I] = ' ' Then Result := Result + '+' - else - begin + Else + Begin Result := Result + '%'; Result := Result + AnsiString(IntToHex(Byte(Value[I]), 2)); - end; - end; -end; -function URLDecode(const Value: AnsiString): AnsiString; -const + End; + End; +End; +Function URLDecode(Const Value: AnsiString): AnsiString; +Const HexChars: AnsiString = '0123456789ABCDEF'; -var +Var I: Integer; Ch, H1, H2: AnsiChar; Len: Integer; -begin +Begin Result := ''; Len := Length(Value); I := 1; - while I <= Len do - begin + While I <= Len Do + Begin Ch := Value[I]; - case Ch of + Case Ch Of '%': - begin + Begin H1 := Value[I + 1]; H2 := Value[I + 2]; Inc(I, 2); Result := Result + AnsiChar(Chr((({$IFDEF SUPPORTS_UNICODE}AnsiPos{$ELSE}Pos{$ENDIF SUPPORTS_UNICODE}(H1, HexChars) - 1) * 16) + ({$IFDEF SUPPORTS_UNICODE}AnsiPos{$ELSE}Pos{$ENDIF SUPPORTS_UNICODE}(H2, HexChars) - 1))); - end; + End; '+': Result := Result + ' '; '&': Result := Result + CrLf; - else + Else Result := Result + Ch; - end; + End; Inc(I); - end; -end; + End; +End; {template functions} -function ReplaceFirst(const SourceStr, FindStr, ReplaceStr: string): string; -var +Function ReplaceFirst(Const SourceStr, FindStr, ReplaceStr: string): string; +Var P: Integer; -begin +Begin Result := SourceStr; P := PosText(FindStr, SourceStr, 1); - if P <> 0 then + If P <> 0 Then Result := Copy(SourceStr, 1, P - 1) + ReplaceStr + Copy(SourceStr, P + Length(FindStr), Length(SourceStr)); -end; -function ReplaceLast(const SourceStr, FindStr, ReplaceStr: string): string; -var +End; +Function ReplaceLast(Const SourceStr, FindStr, ReplaceStr: string): string; +Var P: Integer; -begin +Begin Result := SourceStr; P := PosTextLast(FindStr, SourceStr); - if P <> 0 then + If P <> 0 Then Result := Copy(SourceStr, 1, P - 1) + ReplaceStr + Copy(SourceStr, P + Length(FindStr), Length(SourceStr)); -end; +End; // insert a block template // the last occurance of {block:aBlockname} // the block template is marked with {begin:aBlockname} and {end:aBlockname} -function InsertLastBlock(var SourceStr: string; BlockStr: string): Boolean; -var +Function InsertLastBlock(Var SourceStr: string; BlockStr: string): Boolean; +Var // phead: Integer; PBlock, PE, PB: Integer; SBB, SBE, SB, SBR: string; SBBL, SBEL: Integer; -begin +Begin Result := False; // phead:= PosStr('',SourceStr,1); // If phead = 0 Then Exit; @@ -1700,173 +1700,173 @@ function InsertLastBlock(var SourceStr: string; BlockStr: string): Boolean; SBE := '{end:' + BlockStr + '}'; SBEL := Length(SBE); PBlock := PosTextLast(SB, SourceStr); - if PBlock = 0 then + If PBlock = 0 Then Exit; PB := PosText(SBB, SourceStr, 1); - if PB = 0 then + If PB = 0 Then Exit; PE := PosText(SBE, SourceStr, PB); - if PE = 0 then + If PE = 0 Then Exit; PE := PE + SBEL - 1; // now replace SBR := Copy(SourceStr, PB + SBBL, PE - PB - SBBL - SBEL + 1); SourceStr := Copy(SourceStr, 1, PBlock - 1) + SBR + Copy(SourceStr, PBlock, Length(SourceStr)); Result := True; -end; +End; // removes all {begin:somefield} to {end:somefield} from ASource -function RemoveMasterBlocks(const SourceStr: string): string; -var +Function RemoveMasterBlocks(Const SourceStr: string): string; +Var S, Src: string; PB: Integer; PE: Integer; PEE: Integer; -begin +Begin S := ''; Src := SourceStr; - repeat + Repeat PB := PosText('{begin:', Src); - if PB > 0 then - begin + If PB > 0 Then + Begin PE := PosText('{end:', Src, PB); - if PE > 0 then - begin + If PE > 0 Then + Begin PEE := PosStr('}', Src, PE); - if PEE > 0 then - begin + If PEE > 0 Then + Begin S := S + Copy(Src, 1, PB - 1); Delete(Src, 1, PEE); - end; - end; - end; - until PB = 0; + End; + End; + End; + Until PB = 0; Result := S + Src; -end; +End; // removes all {field} entries in a template -function RemoveFields(const SourceStr: string): string; -var +Function RemoveFields(Const SourceStr: string): string; +Var Src, S: string; PB: Integer; PE: Integer; -begin +Begin S := ''; Src := SourceStr; - repeat + Repeat PB := Pos('{', Src); - if PB > 0 then - begin + If PB > 0 Then + Begin PE := Pos('}', Src); - if PE > 0 then - begin + If PE > 0 Then + Begin S := S + Copy(Src, 1, PB - 1); Delete(Src, 1, PE); - end; - end; - until PB = 0; + End; + End; + Until PB = 0; Result := S + Src; -end; +End; {finds the last occurance} -function PosStrLast(const FindString, SourceString: string): Integer; -var +Function PosStrLast(Const FindString, SourceString: string): Integer; +Var I, L: Integer; -begin +Begin Result := 0; L := Length(FindString); - if L = 0 then + If L = 0 Then Exit; I := Length(SourceString); - if I = 0 then + If I = 0 Then Exit; I := I - L + 1; - while I > 0 do - begin + While I > 0 Do + Begin Result := PosStr(FindString, SourceString, I); - if Result > 0 then + If Result > 0 Then Exit; I := I - L; - end; -end; + End; +End; {finds the last occurance} -function PosTextLast(const FindString, SourceString: string): Integer; -var +Function PosTextLast(Const FindString, SourceString: string): Integer; +Var I, L: Integer; -begin +Begin Result := 0; L := Length(FindString); - if L = 0 then + If L = 0 Then Exit; I := Length(SourceString); - if I = 0 then + If I = 0 Then Exit; I := I - L + 1; - while I > 0 do - begin + While I > 0 Do + Begin Result := PosText(FindString, SourceString, I); - if Result > 0 then + If Result > 0 Then Exit; I := I - L; - end; -end; -procedure DirFiles(const ADir, AMask: string; AFileList: TStringList); -var + End; +End; +Procedure DirFiles(Const ADir, AMask: string; AFileList: TStringList); +Var SR: TSearchRec; FileAttrs: Integer; -begin +Begin FileAttrs := faArchive + faDirectory; - if FindFirst(ADir + AMask, FileAttrs, SR) = 0 then - while FindNext(SR) = 0 do - if (SR.Attr and faArchive) <> 0 then + If FindFirst(ADir + AMask, FileAttrs, SR) = 0 Then + While FindNext(SR) = 0 Do + If (SR.Attr and faArchive) <> 0 Then AFileList.Add(ADir + SR.Name); FindClose(SR); -end; +End; // parse number returns the last position, starting from 1 -function ParseNumber(const S: string): Integer; -var +Function ParseNumber(Const S: string): Integer; +Var I, E, E2, C: Integer; -begin +Begin Result := 0; I := 0; C := Length(S); - if C = 0 then + If C = 0 Then Exit; - while (I + 1 <= C) and (S[I + 1] in DigitChars + [',', '.']) do + While (I + 1 <= C) and (S[I + 1] in DigitChars + [',', '.']) Do Inc(I); - if (I + 1 <= C) and (S[I + 1] in ['e', 'E']) then - begin + If (I + 1 <= C) and (S[I + 1] in ['e', 'E']) Then + Begin E := I; Inc(I); - if (I + 1 <= C) and (S[I + 1] in ['+', '-']) then + If (I + 1 <= C) and (S[I + 1] in ['+', '-']) Then Inc(I); E2 := I; - while (I + 1 <= C) and (S[I + 1] in DigitChars) do + While (I + 1 <= C) and (S[I + 1] in DigitChars) Do Inc(I); - if I = E2 then + If I = E2 Then I := E; - end; + End; Result := I; -end; +End; // parse a SQL style data string from positions 1, // starts and ends with # -function ParseDate(const S: string): Integer; -var +Function ParseDate(Const S: string): Integer; +Var P: Integer; -begin +Begin Result := 0; - if Length(S) < 2 then + If Length(S) < 2 Then Exit; P := PosStr('#', S, 2); - if P <> 0 then - try + If P <> 0 Then + Try StrToDate(Copy(S, 2, P - 2)); Result := P; - except + Except Result := 0; - end; -end; + End; +End; {$IFDEF UNITVERSIONING} -initialization - RegisterUnitVersion(HInstance, UnitVersioning); -finalization - UnregisterUnitVersion(HInstance); +Initialization + RegisterUnitVersion(HInstance, UnitVersioning); +Finalization + UnregisterUnitVersion(HInstance); {$ENDIF UNITVERSIONING} -end. +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemStringsB.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemStringsB.pas index 4290c055a..e43558fd3 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemStringsB.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemStringsB.pas @@ -1,20 +1,20 @@ -unit uRESTDWMemStringsB; -{$I ..\..\Includes\uRESTDW.inc} +Unit uRESTDWMemStringsB; +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -26,8 +26,8 @@ {$ASMMode Intel} {$ENDIF} -interface -uses +Interface +Uses {$IFDEF HAS_UNITSCOPE} {$IFDEF MSWINDOWS} Winapi.Windows, @@ -50,10 +50,10 @@ interface uRESTDWMemBase, Math, uRESTDWPrototypes; // Exceptions -type - EJclStringError = class(EJclError); +Type + EJclStringError = Class(EJclError); // Character constants and sets -const +Const // Misc. often used character definitions NativeNull = Char(#0); NativeSoh = Char(#1); @@ -95,7 +95,7 @@ EJclStringError = class(EJclError); NativeDoubleQuote = Char('"'); NativeSingleQuote = Char(''''); NativeLineBreak = sLineBreak; -const +Const // CharType return values C1_UPPER = $0001; // Uppercase C1_LOWER = $0002; // Lowercase @@ -119,173 +119,173 @@ EJclStringError = class(EJclError); {$EXTERNALSYM C1_ALPHA} {$ENDIF SUPPORTS_EXTSYM} {$ENDIF MSWINDOWS} -type - TCharValidator = function(const C: Char): Boolean; -function ArrayContainsChar(const Chars: array of Char; const C: Char): Boolean; overload; -function ArrayContainsChar(const Chars: array of Char; const C: Char; out Index: SizeInt): Boolean; overload; +Type + TCharValidator = Function(Const C: Char): Boolean; +Function ArrayContainsChar(Const Chars: array Of Char; Const C: Char): Boolean; overload; +Function ArrayContainsChar(Const Chars: array Of Char; Const C: Char; out Index: SizeInt): Boolean; overload; // String Test Routines -function StrIsAlpha(const S: string): Boolean; -function StrIsAlphaNum(const S: string): Boolean; -function StrIsAlphaNumUnderscore(const S: string): Boolean; -function StrContainsChars(const S: string; const Chars: TCharValidator; CheckAll: Boolean): Boolean; overload; -function StrContainsChars(const S: string; const Chars: array of Char; CheckAll: Boolean): Boolean; overload; -function StrConsistsOfNumberChars(const S: string): Boolean; -function StrIsDigit(const S: string): Boolean; -function StrIsSubset(const S: string; const ValidChars: TCharValidator): Boolean; overload; -function StrIsSubset(const S: string; const ValidChars: array of Char): Boolean; overload; -function StrSame(const S1, S2: string; CaseSensitive: Boolean = False): Boolean; +Function StrIsAlpha(Const S: string): Boolean; +Function StrIsAlphaNum(Const S: string): Boolean; +Function StrIsAlphaNumUnderscore(Const S: string): Boolean; +Function StrContainsChars(Const S: string; Const Chars: TCharValidator; CheckAll: Boolean): Boolean; overload; +Function StrContainsChars(Const S: string; Const Chars: array Of Char; CheckAll: Boolean): Boolean; overload; +Function StrConsistsOfNumberChars(Const S: string): Boolean; +Function StrIsDigit(Const S: string): Boolean; +Function StrIsSubset(Const S: string; Const ValidChars: TCharValidator): Boolean; overload; +Function StrIsSubset(Const S: string; Const ValidChars: array Of Char): Boolean; overload; +Function StrSame(Const S1, S2: string; CaseSensitive: Boolean = False): Boolean; // String Transformation Routines -function StrCenter(const S: string; L: SizeInt; C: Char = ' '): string; -function StrCharPosLower(const S: string; CharPos: SizeInt): string; -function StrCharPosUpper(const S: string; CharPos: SizeInt): string; -function StrDoubleQuote(const S: string): string; -function StrEnsureNoPrefix(const Prefix, Text: string): string; -function StrEnsureNoSuffix(const Suffix, Text: string): string; -function StrEnsurePrefix(const Prefix, Text: string): string; -function StrEnsureSuffix(const Suffix, Text: string): string; -function StrEscapedToString(const S: string): string; -function StrLower(const S: string): string; -procedure StrLowerInPlace(var S: string); -procedure StrLowerBuff(S: PChar); -procedure StrMove(var Dest: string; const Source: string; const ToIndex, +Function StrCenter(Const S: string; L: SizeInt; C: Char = ' '): string; +Function StrCharPosLower(Const S: string; CharPos: SizeInt): string; +Function StrCharPosUpper(Const S: string; CharPos: SizeInt): string; +Function StrDoubleQuote(Const S: string): string; +Function StrEnsureNoPrefix(Const Prefix, Text: string): string; +Function StrEnsureNoSuffix(Const Suffix, Text: string): string; +Function StrEnsurePrefix(Const Prefix, Text: string): string; +Function StrEnsureSuffix(Const Suffix, Text: string): string; +Function StrEscapedToString(Const S: string): string; +Function StrLower(Const S: string): string; +Procedure StrLowerInPlace(Var S: string); +Procedure StrLowerBuff(S: PChar); +Procedure StrMove(Var Dest: string; Const Source: string; Const ToIndex, FromIndex, Count: SizeInt); -function StrPadLeft(const S: string; Len: SizeInt; C: Char = NativeSpace): string; -function StrPadRight(const S: string; Len: SizeInt; C: Char = NativeSpace): string; -function StrProper(const S: string): string; -procedure StrProperBuff(S: PChar); -function StrQuote(const S: string; C: Char): string; -function StrRemoveChars(const S: string; const Chars: TCharValidator): string; overload; -function StrRemoveChars(const S: string; const Chars: array of Char): string; overload; -function StrRemoveLeadingChars(const S: string; const Chars: TCharValidator): string; overload; -function StrRemoveLeadingChars(const S: string; const Chars: array of Char): string; overload; -function StrRemoveEndChars(const S: string; const Chars: TCharValidator): string; overload; -function StrRemoveEndChars(const S: string; const Chars: array of Char): string; overload; -function StrKeepChars(const S: string; const Chars: TCharValidator): string; overload; -function StrKeepChars(const S: string; const Chars: array of Char): string; overload; -procedure StrReplace(var S: string; const Search, Replace: string; Flags: TReplaceFlags = []); -function StrReplaceChar(const S: string; const Source, Replace: Char): string; -function StrReplaceChars(const S: string; const Chars: TCharValidator; Replace: Char): string; overload; -function StrReplaceChars(const S: string; const Chars: array of Char; Replace: Char): string; overload; -function StrReplaceButChars(const S: string; const Chars: TCharValidator; Replace: Char): string; overload; -function StrReplaceButChars(const S: string; const Chars: array of Char; Replace: Char): string; overload; -function StrRepeat(const S: string; Count: SizeInt): string; -function StrReverse(const S: string): string; -procedure StrReverseInPlace(var S: string); -function StrSingleQuote(const S: string): string; -procedure StrSkipChars(var S: PChar; const Chars: TCharValidator); overload; -procedure StrSkipChars(var S: PChar; const Chars: array of Char); overload; -procedure StrSkipChars(const S: string; var Index: SizeInt; const Chars: TCharValidator); overload; -procedure StrSkipChars(const S: string; var Index: SizeInt; const Chars: array of Char); overload; -function StrSmartCase(const S: string; const Delimiters: TCharValidator): string; overload; -function StrSmartCase(const S: string; const Delimiters: array of Char): string; overload; -function StrStringToEscaped(const S: string): string; -function StrStripNonNumberChars(const S: string): string; -function StrToHex(const Source: string): string; -function StrTrimCharLeft(const S: string; C: Char): string; -function StrTrimCharsLeft(const S: string; const Chars: TCharValidator): string; overload; -function StrTrimCharsLeft(const S: string; const Chars: array of Char): string; overload; -function StrTrimCharRight(const S: string; C: Char): string; -function StrTrimCharsRight(const S: string; const Chars: TCharValidator): string; overload; -function StrTrimCharsRight(const S: string; const Chars: array of Char): string; overload; -function StrTrimQuotes(const S: string): string; -function StrUpper(const S: string): string; -procedure StrUpperInPlace(var S: string); -procedure StrUpperBuff(S: PChar); +Function StrPadLeft(Const S: string; Len: SizeInt; C: Char = NativeSpace): string; +Function StrPadRight(Const S: string; Len: SizeInt; C: Char = NativeSpace): string; +Function StrProper(Const S: string): string; +Procedure StrProperBuff(S: PChar); +Function StrQuote(Const S: string; C: Char): string; +Function StrRemoveChars(Const S: string; Const Chars: TCharValidator): string; overload; +Function StrRemoveChars(Const S: string; Const Chars: array Of Char): string; overload; +Function StrRemoveLeadingChars(Const S: string; Const Chars: TCharValidator): string; overload; +Function StrRemoveLeadingChars(Const S: string; Const Chars: array Of Char): string; overload; +Function StrRemoveEndChars(Const S: string; Const Chars: TCharValidator): string; overload; +Function StrRemoveEndChars(Const S: string; Const Chars: array Of Char): string; overload; +Function StrKeepChars(Const S: string; Const Chars: TCharValidator): string; overload; +Function StrKeepChars(Const S: string; Const Chars: array Of Char): string; overload; +Procedure StrReplace(Var S: string; Const Search, Replace: string; Flags: TReplaceFlags = []); +Function StrReplaceChar(Const S: string; Const Source, Replace: Char): string; +Function StrReplaceChars(Const S: string; Const Chars: TCharValidator; Replace: Char): string; overload; +Function StrReplaceChars(Const S: string; Const Chars: array Of Char; Replace: Char): string; overload; +Function StrReplaceButChars(Const S: string; Const Chars: TCharValidator; Replace: Char): string; overload; +Function StrReplaceButChars(Const S: string; Const Chars: array Of Char; Replace: Char): string; overload; +Function StrRepeat(Const S: string; Count: SizeInt): string; +Function StrReverse(Const S: string): string; +Procedure StrReverseInPlace(Var S: string); +Function StrSingleQuote(Const S: string): string; +Procedure StrSkipChars(Var S: PChar; Const Chars: TCharValidator); overload; +Procedure StrSkipChars(Var S: PChar; Const Chars: array Of Char); overload; +Procedure StrSkipChars(Const S: string; Var Index: SizeInt; Const Chars: TCharValidator); overload; +Procedure StrSkipChars(Const S: string; Var Index: SizeInt; Const Chars: array Of Char); overload; +Function StrSmartCase(Const S: string; Const Delimiters: TCharValidator): string; overload; +Function StrSmartCase(Const S: string; Const Delimiters: array Of Char): string; overload; +Function StrStringToEscaped(Const S: string): string; +Function StrStripNonNumberChars(Const S: string): string; +Function StrToHex(Const Source: string): string; +Function StrTrimCharLeft(Const S: string; C: Char): string; +Function StrTrimCharsLeft(Const S: string; Const Chars: TCharValidator): string; overload; +Function StrTrimCharsLeft(Const S: string; Const Chars: array Of Char): string; overload; +Function StrTrimCharRight(Const S: string; C: Char): string; +Function StrTrimCharsRight(Const S: string; Const Chars: TCharValidator): string; overload; +Function StrTrimCharsRight(Const S: string; Const Chars: array Of Char): string; overload; +Function StrTrimQuotes(Const S: string): string; +Function StrUpper(Const S: string): string; +Procedure StrUpperInPlace(Var S: string); +Procedure StrUpperBuff(S: PChar); // String Management -procedure StrAddRef(var S: string); -procedure StrDecRef(var S: string); -function StrLength(const S: string): SizeInt; -function StrRefCount(const S: string): SizeInt; +Procedure StrAddRef(Var S: string); +Procedure StrDecRef(Var S: string); +Function StrLength(Const S: string): SizeInt; +Function StrRefCount(Const S: string): SizeInt; // String Search and Replace Routines -function StrCharCount(const S: string; C: Char): SizeInt; overload; -function StrCharsCount(const S: string; const Chars: TCharValidator): SizeInt; overload; -function StrCharsCount(const S: string; const Chars: array of Char): SizeInt; overload; -function StrStrCount(const S, SubS: string): SizeInt; -function StrCompare(const S1, S2: string; CaseSensitive: Boolean = False): SizeInt; -function StrCompareRange(const S1, S2: string; Index, Count: SizeInt; CaseSensitive: Boolean = True): SizeInt; -function StrCompareRangeEx(const S1, S2: string; Index, Count: SizeInt; CaseSensitive: Boolean): SizeInt; -procedure StrFillChar(var S; Count: SizeInt; C: Char); -function StrRepeatChar(C: Char; Count: SizeInt): string; -function StrFind(const Substr, S: string; const Index: SizeInt = 1): SizeInt; -function StrHasPrefix(const S: string; const Prefixes: array of string): Boolean; -function StrHasSuffix(const S: string; const Suffixes: array of string): Boolean; -function StrIndex(const S: string; const List: array of string; CaseSensitive: Boolean = False): SizeInt; -function StrIHasPrefix(const S: string; const Prefixes: array of string): Boolean; -function StrIHasSuffix(const S: string; const Suffixes: array of string): Boolean; -function StrILastPos(const SubStr, S: string): SizeInt; -function StrIPos(const SubStr, S: string): SizeInt; -function StrIPrefixIndex(const S: string; const Prefixes: array of string): SizeInt; -function StrIsOneOf(const S: string; const List: array of string): Boolean; -function StrISuffixIndex(const S: string; const Suffixes: array of string): SizeInt; -function StrLastPos(const SubStr, S: string): SizeInt; -function StrMatch(const Substr, S: string; Index: SizeInt = 1): SizeInt; -function StrMatches(const Substr, S: string; const Index: SizeInt = 1): Boolean; -function StrNIPos(const S, SubStr: string; N: SizeInt): SizeInt; -function StrNPos(const S, SubStr: string; N: SizeInt): SizeInt; -function StrPrefixIndex(const S: string; const Prefixes: array of string): SizeInt; -function StrSearch(const Substr, S: string; const Index: SizeInt = 1): SizeInt; -function StrSuffixIndex(const S: string; const Suffixes: array of string): SizeInt; +Function StrCharCount(Const S: string; C: Char): SizeInt; overload; +Function StrCharsCount(Const S: string; Const Chars: TCharValidator): SizeInt; overload; +Function StrCharsCount(Const S: string; Const Chars: array Of Char): SizeInt; overload; +Function StrStrCount(Const S, SubS: string): SizeInt; +Function StrCompare(Const S1, S2: string; CaseSensitive: Boolean = False): SizeInt; +Function StrCompareRange(Const S1, S2: string; Index, Count: SizeInt; CaseSensitive: Boolean = True): SizeInt; +Function StrCompareRangeEx(Const S1, S2: string; Index, Count: SizeInt; CaseSensitive: Boolean): SizeInt; +Procedure StrFillChar(Var S; Count: SizeInt; C: Char); +Function StrRepeatChar(C: Char; Count: SizeInt): string; +Function StrFind(Const Substr, S: string; Const Index: SizeInt = 1): SizeInt; +Function StrHasPrefix(Const S: string; Const Prefixes: array Of string): Boolean; +Function StrHasSuffix(Const S: string; Const Suffixes: array Of string): Boolean; +Function StrIndex(Const S: string; Const List: array Of string; CaseSensitive: Boolean = False): SizeInt; +Function StrIHasPrefix(Const S: string; Const Prefixes: array Of string): Boolean; +Function StrIHasSuffix(Const S: string; Const Suffixes: array Of string): Boolean; +Function StrILastPos(Const SubStr, S: string): SizeInt; +Function StrIPos(Const SubStr, S: string): SizeInt; +Function StrIPrefixIndex(Const S: string; Const Prefixes: array Of string): SizeInt; +Function StrIsOneOf(Const S: string; Const List: array Of string): Boolean; +Function StrISuffixIndex(Const S: string; Const Suffixes: array Of string): SizeInt; +Function StrLastPos(Const SubStr, S: string): SizeInt; +Function StrMatch(Const Substr, S: string; Index: SizeInt = 1): SizeInt; +Function StrMatches(Const Substr, S: string; Const Index: SizeInt = 1): Boolean; +Function StrNIPos(Const S, SubStr: string; N: SizeInt): SizeInt; +Function StrNPos(Const S, SubStr: string; N: SizeInt): SizeInt; +Function StrPrefixIndex(Const S: string; Const Prefixes: array Of string): SizeInt; +Function StrSearch(Const Substr, S: string; Const Index: SizeInt = 1): SizeInt; +Function StrSuffixIndex(Const S: string; Const Suffixes: array Of string): SizeInt; // String Extraction /// Returns the string after SubStr -function StrAfter(const SubStr, S: string): string; +Function StrAfter(Const SubStr, S: string): string; /// Returns the String before SubStr -function StrBefore(const SubStr, S: string): string; +Function StrBefore(Const SubStr, S: string): string; /// Splits a string at SubStr, returns true when SubStr is found, Left contains the /// string before the SubStr and Right the string behind SubStr -function StrSplit(const SubStr, S: string;var Left, Right : string): boolean; +Function StrSplit(Const SubStr, S: string;Var Left, Right : string): boolean; /// Returns the string between Start and Stop -function StrBetween(const S: string; const Start, Stop: Char): string; +Function StrBetween(Const S: string; Const Start, Stop: Char): string; /// Returns all but rightmost N characters of the string -function StrChopRight(const S: string; N: SizeInt): string;{$IFDEF SUPPORTS_INLINE} {$IFDEF COMPILER16_UP} inline; {$ENDIF} {$ENDIF} +Function StrChopRight(Const S: string; N: SizeInt): string;{$IFDEF SUPPORTS_INLINE} {$IFDEF COMPILER16_UP} inline; {$ENDIF} {$ENDIF} /// Returns the left Count characters of the string -function StrLeft(const S: string; Count: SizeInt): string; {$IFDEF SUPPORTS_INLINE} {$IFDEF COMPILER16_UP} inline; {$ENDIF} {$ENDIF} +Function StrLeft(Const S: string; Count: SizeInt): string; {$IFDEF SUPPORTS_INLINE} {$IFDEF COMPILER16_UP} inline; {$ENDIF} {$ENDIF} /// Returns the string starting from position Start for the Count Characters -function StrMid(const S: string; Start, Count: SizeInt): string; {$IFDEF SUPPORTS_INLINE} {$IFDEF COMPILER16_UP} inline; {$ENDIF} {$ENDIF} +Function StrMid(Const S: string; Start, Count: SizeInt): string; {$IFDEF SUPPORTS_INLINE} {$IFDEF COMPILER16_UP} inline; {$ENDIF} {$ENDIF} /// Returns the string starting from position N to the end -function StrRestOf(const S: string; N: SizeInt): string;{$IFDEF SUPPORTS_INLINE} {$IFDEF COMPILER16_UP} inline; {$ENDIF} {$ENDIF} +Function StrRestOf(Const S: string; N: SizeInt): string;{$IFDEF SUPPORTS_INLINE} {$IFDEF COMPILER16_UP} inline; {$ENDIF} {$ENDIF} /// Returns the right Count characters of the string -function StrRight(const S: string; Count: SizeInt): string;{$IFDEF SUPPORTS_INLINE} {$IFDEF COMPILER16_UP} inline; {$ENDIF} {$ENDIF} +Function StrRight(Const S: string; Count: SizeInt): string;{$IFDEF SUPPORTS_INLINE} {$IFDEF COMPILER16_UP} inline; {$ENDIF} {$ENDIF} // Character Test Routines -function CharEqualNoCase(const C1, C2: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsAlpha(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsAlphaNum(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsBlank(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsControl(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsDelete(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsDigit(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsFracDigit(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsHexDigit(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsLower(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsNumberChar(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} {$IFDEF COMPILER16_UP} inline; {$ENDIF} {$ENDIF} -function CharIsNumber(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} {$IFDEF COMPILER16_UP} inline; {$ENDIF} {$ENDIF} -function CharIsPrintable(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsPunctuation(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsReturn(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsSpace(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsUpper(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsValidIdentifierLetter(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsWhiteSpace(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharIsWildcard(const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharType(const C: Char): Word; +Function CharEqualNoCase(Const C1, C2: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsAlpha(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsAlphaNum(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsBlank(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsControl(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsDelete(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsDigit(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsFracDigit(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsHexDigit(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsLower(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsNumberChar(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} {$IFDEF COMPILER16_UP} inline; {$ENDIF} {$ENDIF} +Function CharIsNumber(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} {$IFDEF COMPILER16_UP} inline; {$ENDIF} {$ENDIF} +Function CharIsPrintable(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsPunctuation(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsReturn(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsSpace(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsUpper(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsValidIdentifierLetter(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsWhiteSpace(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharIsWildcard(Const C: Char): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharType(Const C: Char): Word; // Character Transformation Routines -function CharHex(const C: Char): Byte; -function CharLower(const C: Char): Char; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharUpper(const C: Char): Char; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -function CharToggleCase(const C: Char): Char; +Function CharHex(Const C: Char): Byte; +Function CharLower(Const C: Char): Char; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharUpper(Const C: Char): Char; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Function CharToggleCase(Const C: Char): Char; // Character Search and Replace -function CharPos(const S: string; const C: Char; const Index: SizeInt = 1): SizeInt; -function CharLastPos(const S: string; const C: Char; const Index: SizeInt = 1): SizeInt; -function CharIPos(const S: string; C: Char; const Index: SizeInt = 1): SizeInt; -function CharReplace(var S: string; const Search, Replace: Char): SizeInt; +Function CharPos(Const S: string; Const C: Char; Const Index: SizeInt = 1): SizeInt; +Function CharLastPos(Const S: string; Const C: Char; Const Index: SizeInt = 1): SizeInt; +Function CharIPos(Const S: string; C: Char; Const Index: SizeInt = 1): SizeInt; +Function CharReplace(Var S: string; Const Search, Replace: Char): SizeInt; // PCharVector -type +Type PCharVector = ^PChar; -function StringsToPCharVector(var Dest: PCharVector; const Source: TStrings): PCharVector; -function PCharVectorCount(Source: PCharVector): SizeInt; -procedure PCharVectorToStrings(const Dest: TStrings; Source: PCharVector); -procedure FreePCharVector(var Dest: PCharVector); +Function StringsToPCharVector(Var Dest: PCharVector; Const Source: TStrings): PCharVector; +Function PCharVectorCount(Source: PCharVector): SizeInt; +Procedure PCharVectorToStrings(Const Dest: TStrings; Source: PCharVector); +Procedure FreePCharVector(Var Dest: PCharVector); // MultiSz Routines -type +Type PMultiSz = PChar; PAnsiMultiSz = uRESTDWMemAnsiStrings.PAnsiMultiSz; PWideMultiSz = uRESTDWMemWideStrings.PWideMultiSz; @@ -293,183 +293,183 @@ procedure FreePCharVector(var Dest: PCharVector); TWideStrings = uRESTDWMemWideStrings.TJclWideStrings; TAnsiStringList = uRESTDWMemAnsiStrings.TJclAnsiStringList; TWideStringList = uRESTDWMemWideStrings.TJclWideStringList; -function StringsToMultiSz(var Dest: PMultiSz; const Source: TStrings): PMultiSz; -procedure MultiSzToStrings(const Dest: TStrings; const Source: PMultiSz); -function MultiSzLength(const Source: PMultiSz): SizeInt; -procedure AllocateMultiSz(var Dest: PMultiSz; Len: SizeInt); -procedure FreeMultiSz(var Dest: PMultiSz); -function MultiSzDup(const Source: PMultiSz): PMultiSz; +Function StringsToMultiSz(Var Dest: PMultiSz; Const Source: TStrings): PMultiSz; +Procedure MultiSzToStrings(Const Dest: TStrings; Const Source: PMultiSz); +Function MultiSzLength(Const Source: PMultiSz): SizeInt; +Procedure AllocateMultiSz(Var Dest: PMultiSz; Len: SizeInt); +Procedure FreeMultiSz(Var Dest: PMultiSz); +Function MultiSzDup(Const Source: PMultiSz): PMultiSz; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -procedure AllocateAnsiMultiSz(var Dest: PAnsiMultiSz; Len: SizeInt); {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -procedure FreeAnsiMultiSz(var Dest: PAnsiMultiSz); {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -procedure AllocateWideMultiSz(var Dest: PWideMultiSz; Len: SizeInt); {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} -procedure FreeWideMultiSz(var Dest: PWideMultiSz); {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Procedure AllocateAnsiMultiSz(Var Dest: PAnsiMultiSz; Len: SizeInt); {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Procedure FreeAnsiMultiSz(Var Dest: PAnsiMultiSz); {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Procedure AllocateWideMultiSz(Var Dest: PWideMultiSz; Len: SizeInt); {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +Procedure FreeWideMultiSz(Var Dest: PWideMultiSz); {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} // TStrings Manipulation -procedure StrIToStrings(S, Sep: string; const List: TStrings; const AllowEmptyString: Boolean = True); -procedure StrToStrings(S, Sep: string; const List: TStrings; const AllowEmptyString: Boolean = True); -function StringsToStr(const List: TStrings; const Sep: string; const AllowEmptyString: Boolean = True): string; overload; -function StringsToStr(const List: TStrings; const Sep: string; const NumberOfItems: SizeInt; const AllowEmptyString: +Procedure StrIToStrings(S, Sep: string; Const List: TStrings; Const AllowEmptyString: Boolean = True); +Procedure StrToStrings(S, Sep: string; Const List: TStrings; Const AllowEmptyString: Boolean = True); +Function StringsToStr(Const List: TStrings; Const Sep: string; Const AllowEmptyString: Boolean = True): string; overload; +Function StringsToStr(Const List: TStrings; Const Sep: string; Const NumberOfItems: SizeInt; Const AllowEmptyString: Boolean = True): string; overload; -procedure TrimStrings(const List: TStrings; DeleteIfEmpty: Boolean = True); -procedure TrimStringsRight(const List: TStrings; DeleteIfEmpty: Boolean = True); -procedure TrimStringsLeft(const List: TStrings; DeleteIfEmpty: Boolean = True); -function AddStringToStrings(const S: string; Strings: TStrings; const Unique: Boolean): Boolean; +Procedure TrimStrings(Const List: TStrings; DeleteIfEmpty: Boolean = True); +Procedure TrimStringsRight(Const List: TStrings; DeleteIfEmpty: Boolean = True); +Procedure TrimStringsLeft(Const List: TStrings; DeleteIfEmpty: Boolean = True); +Function AddStringToStrings(Const S: string; Strings: TStrings; Const Unique: Boolean): Boolean; // Miscellaneous // (OF) moved to JclSysUtils // function BooleanToStr(B: Boolean): string; // DWString here because it is binary data -function FileToString(const FileName: string): {$IFDEF COMPILER12_UP}RawByteString{$ELSE}DWString{$ENDIF}; -procedure StringToFile(const FileName: string; const Contents: {$IFDEF COMPILER12_UP}RawByteString{$ELSE}DWString{$ENDIF}; +Function FileToString(Const FileName: string): {$IFDEF COMPILER12_UP}RawByteString{$ELSE}DWString{$ENDIF}; +Procedure StringToFile(Const FileName: string; Const Contents: {$IFDEF COMPILER12_UP}RawByteString{$ELSE}DWString{$ENDIF}; Append: Boolean = False); -function StrToken(var S: string; Separator: Char): string; -procedure StrTokens(const S: string; const List: TStrings); -procedure StrTokenToStrings(S: string; Separator: Char; const List: TStrings); -function StrWord(const S: string; var Index: SizeInt; out Word: string): Boolean; overload; -function StrWord(var S: PChar; out Word: string): Boolean; overload; -function StrIdent(const S: string; var Index: SizeInt; out Ident: string): Boolean; overload; -function StrIdent(var S: PChar; out Ident: string): Boolean; overload; -function StrToFloatSafe(const S: string): Float; -function StrToIntSafe(const S: string): Integer; -procedure StrNormIndex(const StrLen: SizeInt; var Index: SizeInt; var Count: SizeInt); overload; -function ArrayOf(List: TStrings): TDynStringArray; overload; -type - FormatException = class(EJclError); - ArgumentException = class(EJclError); - ArgumentNullException = class(EJclError); - ArgumentOutOfRangeException = class(EJclError); - IToString = interface +Function StrToken(Var S: string; Separator: Char): string; +Procedure StrTokens(Const S: string; Const List: TStrings); +Procedure StrTokenToStrings(S: string; Separator: Char; Const List: TStrings); +Function StrWord(Const S: string; Var Index: SizeInt; out Word: string): Boolean; overload; +Function StrWord(Var S: PChar; out Word: string): Boolean; overload; +Function StrIdent(Const S: string; Var Index: SizeInt; out Ident: string): Boolean; overload; +Function StrIdent(Var S: PChar; out Ident: string): Boolean; overload; +Function StrToFloatSafe(Const S: string): Float; +Function StrToIntSafe(Const S: string): Integer; +Procedure StrNormIndex(Const StrLen: SizeInt; Var Index: SizeInt; Var Count: SizeInt); overload; +Function ArrayOf(List: TStrings): TDynStringArray; overload; +Type + FormatException = Class(EJclError); + ArgumentException = Class(EJclError); + ArgumentNullException = Class(EJclError); + ArgumentOutOfRangeException = Class(EJclError); + IToString = Interface ['{C4ABABB4-1029-46E7-B5FA-99800F130C05}'] - function ToString: string; - end; - TCharDynArray = array of Char; + Function ToString: string; + End; + TCharDynArray = array Of Char; // The TStringBuilder class is a Delphi implementation of the .NET // System.Text.StringBuilder. // It is zero based and the methods that have a TObject argument (Append, Insert, // AppendFormat) are limited to IToString implementors or Delphi 2009+ RTL. // This class is not threadsafe. Any instance of TStringBuilder should not // be used in different threads at the same time. - TJclStringBuilder = class(TInterfacedObject, IToString) - private + TJclStringBuilder = Class(TInterfacedObject, IToString) + Private FChars: TCharDynArray; FLength: SizeInt; FMaxCapacity: SizeInt; - function GetCapacity: SizeInt; - procedure SetCapacity(const Value: SizeInt); - function GetChars(Index: SizeInt): Char; - procedure SetChars(Index: SizeInt; const Value: Char); - procedure Set_Length(const Value: SizeInt); - protected - function AppendPChar(Value: PChar; Count: SizeInt; RepeatCount: SizeInt = 1): TJclStringBuilder; - function InsertPChar(Index: SizeInt; Value: PChar; Count: SizeInt; RepeatCount: SizeInt = 1): TJclStringBuilder; - public - constructor Create(const Value: string; Capacity: SizeInt = 16); overload; - constructor Create(Capacity: SizeInt = 16; MaxCapacity: SizeInt = MaxInt); overload; - constructor Create(const Value: string; StartIndex, Length, Capacity: SizeInt); overload; - function Append(const Value: string): TJclStringBuilder; overload; - function Append(const Value: string; StartIndex, Length: SizeInt): TJclStringBuilder; overload; - function Append(Value: Boolean): TJclStringBuilder; overload; - function Append(Value: Char; RepeatCount: SizeInt = 1): TJclStringBuilder; overload; - function Append(const Value: array of Char): TJclStringBuilder; overload; - function Append(const Value: array of Char; StartIndex, Length: SizeInt): TJclStringBuilder; overload; - function Append(Value: Cardinal): TJclStringBuilder; overload; - function Append(Value: Integer): TJclStringBuilder; overload; - function Append(Value: Double): TJclStringBuilder; overload; - function Append(Value: Int64): TJclStringBuilder; overload; - function Append(Obj: TObject): TJclStringBuilder; overload; - function AppendFormat(const Fmt: string; const Args: array of const): TJclStringBuilder; overload; - function AppendFormat(const Fmt: string; Arg0: Variant): TJclStringBuilder; overload; - function AppendFormat(const Fmt: string; Arg0, Arg1: Variant): TJclStringBuilder; overload; - function AppendFormat(const Fmt: string; Arg0, Arg1, Arg2: Variant): TJclStringBuilder; overload; - function Insert(Index: SizeInt; const Value: string; Count: SizeInt = 1): TJclStringBuilder; overload; - function Insert(Index: SizeInt; Value: Boolean): TJclStringBuilder; overload; - function Insert(Index: SizeInt; const Value: array of Char): TJclStringBuilder; overload; - function Insert(Index: SizeInt; const Value: array of Char; StartIndex, Length: SizeInt): TJclStringBuilder; + Function GetCapacity: SizeInt; + Procedure SetCapacity(Const Value: SizeInt); + Function GetChars(Index: SizeInt): Char; + Procedure SetChars(Index: SizeInt; Const Value: Char); + Procedure Set_Length(Const Value: SizeInt); + Protected + Function AppendPChar(Value: PChar; Count: SizeInt; RepeatCount: SizeInt = 1): TJclStringBuilder; + Function InsertPChar(Index: SizeInt; Value: PChar; Count: SizeInt; RepeatCount: SizeInt = 1): TJclStringBuilder; + Public + Constructor Create(Const Value: string; Capacity: SizeInt = 16); overload; + Constructor Create(Capacity: SizeInt = 16; MaxCapacity: SizeInt = MaxInt); overload; + Constructor Create(Const Value: string; StartIndex, Length, Capacity: SizeInt); overload; + Function Append(Const Value: string): TJclStringBuilder; overload; + Function Append(Const Value: string; StartIndex, Length: SizeInt): TJclStringBuilder; overload; + Function Append(Value: Boolean): TJclStringBuilder; overload; + Function Append(Value: Char; RepeatCount: SizeInt = 1): TJclStringBuilder; overload; + Function Append(Const Value: array Of Char): TJclStringBuilder; overload; + Function Append(Const Value: array Of Char; StartIndex, Length: SizeInt): TJclStringBuilder; overload; + Function Append(Value: Cardinal): TJclStringBuilder; overload; + Function Append(Value: Integer): TJclStringBuilder; overload; + Function Append(Value: Double): TJclStringBuilder; overload; + Function Append(Value: Int64): TJclStringBuilder; overload; + Function Append(Obj: TObject): TJclStringBuilder; overload; + Function AppendFormat(Const Fmt: string; Const Args: array Of Const): TJclStringBuilder; overload; + Function AppendFormat(Const Fmt: string; Arg0: Variant): TJclStringBuilder; overload; + Function AppendFormat(Const Fmt: string; Arg0, Arg1: Variant): TJclStringBuilder; overload; + Function AppendFormat(Const Fmt: string; Arg0, Arg1, Arg2: Variant): TJclStringBuilder; overload; + Function Insert(Index: SizeInt; Const Value: string; Count: SizeInt = 1): TJclStringBuilder; overload; + Function Insert(Index: SizeInt; Value: Boolean): TJclStringBuilder; overload; + Function Insert(Index: SizeInt; Const Value: array Of Char): TJclStringBuilder; overload; + Function Insert(Index: SizeInt; Const Value: array Of Char; StartIndex, Length: SizeInt): TJclStringBuilder; overload; - function Insert(Index: SizeInt; Value: Cardinal): TJclStringBuilder; overload; - function Insert(Index: SizeInt; Value: Integer): TJclStringBuilder; overload; - function Insert(Index: SizeInt; Value: Double): TJclStringBuilder; overload; - function Insert(Index: SizeInt; Value: Int64): TJclStringBuilder; overload; - function Insert(Index: SizeInt; Obj: TObject): TJclStringBuilder; overload; - function Replace(OldChar, NewChar: Char; StartIndex: SizeInt = 0; Count: SizeInt = -1): TJclStringBuilder; + Function Insert(Index: SizeInt; Value: Cardinal): TJclStringBuilder; overload; + Function Insert(Index: SizeInt; Value: Integer): TJclStringBuilder; overload; + Function Insert(Index: SizeInt; Value: Double): TJclStringBuilder; overload; + Function Insert(Index: SizeInt; Value: Int64): TJclStringBuilder; overload; + Function Insert(Index: SizeInt; Obj: TObject): TJclStringBuilder; overload; + Function Replace(OldChar, NewChar: Char; StartIndex: SizeInt = 0; Count: SizeInt = -1): TJclStringBuilder; overload; - function Replace(OldValue, NewValue: string; StartIndex: SizeInt = 0; Count: SizeInt = -1): TJclStringBuilder; + Function Replace(OldValue, NewValue: string; StartIndex: SizeInt = 0; Count: SizeInt = -1): TJclStringBuilder; overload; - function Remove(StartIndex, Length: SizeInt): TJclStringBuilder; - function EnsureCapacity(Capacity: SizeInt): SizeInt; - procedure Clear; + Function Remove(StartIndex, Length: SizeInt): TJclStringBuilder; + Function EnsureCapacity(Capacity: SizeInt): SizeInt; + Procedure Clear; { IToString } - function ToString: string; {$IFDEF RTL200_UP} override; {$ENDIF RTL200_UP} + Function ToString: string; {$IFDEF RTL200_UP} override; {$ENDIF RTL200_UP} property __Chars__[Index: SizeInt]: Char read GetChars write SetChars; default; property Chars: TCharDynArray read FChars; property Length: SizeInt read FLength write Set_Length; property Capacity: SizeInt read GetCapacity write SetCapacity; property MaxCapacity: SizeInt read FMaxCapacity; - end; + End; {$IFDEF RTL200_UP} TStringBuilder = {$IFDEF HAS_UNITSCOPE}System.{$ENDIF}SysUtils.TStringBuilder; {$ELSE ~RTL200_UP} TStringBuilder = TJclStringBuilder; {$ENDIF ~RTL200_UP} // DotNetFormat() uses the .NET format style: "{argX}" -function DotNetFormat(const Fmt: string; const Args: array of const): string; overload; -function DotNetFormat(const Fmt: string; const Arg0: Variant): string; overload; -function DotNetFormat(const Fmt: string; const Arg0, Arg1: Variant): string; overload; -function DotNetFormat(const Fmt: string; const Arg0, Arg1, Arg2: Variant): string; overload; +Function DotNetFormat(Const Fmt: string; Const Args: array Of Const): string; overload; +Function DotNetFormat(Const Fmt: string; Const Arg0: Variant): string; overload; +Function DotNetFormat(Const Fmt: string; Const Arg0, Arg1: Variant): string; overload; +Function DotNetFormat(Const Fmt: string; Const Arg0, Arg1, Arg2: Variant): string; overload; // TJclTabSet -type - TJclTabSet = class (TInterfacedObject, IToString) - private +Type + TJclTabSet = Class (TInterfacedObject, IToString) + Private FData: TObject; - function GetCount: SizeInt; - function GetStops(Index: SizeInt): SizeInt; - function GetTabWidth: SizeInt; - function GetZeroBased: Boolean; - procedure SetStops(Index, Value: SizeInt); - procedure SetTabWidth(Value: SizeInt); - procedure SetZeroBased(Value: Boolean); - protected - function FindStop(Column: SizeInt): SizeInt; - function InternalTabStops: TDynSizeIntArray; - function InternalTabWidth: SizeInt; - procedure RemoveAt(Index: SizeInt); - public - constructor Create; overload; - constructor Create(Data: TObject); overload; - constructor Create(TabWidth: SizeInt); overload; - constructor Create(const Tabstops: array of SizeInt; ZeroBased: Boolean); overload; - constructor Create(const Tabstops: array of SizeInt; ZeroBased: Boolean; TabWidth: SizeInt); overload; - destructor Destroy; override; + Function GetCount: SizeInt; + Function GetStops(Index: SizeInt): SizeInt; + Function GetTabWidth: SizeInt; + Function GetZeroBased: Boolean; + Procedure SetStops(Index, Value: SizeInt); + Procedure SetTabWidth(Value: SizeInt); + Procedure SetZeroBased(Value: Boolean); + Protected + Function FindStop(Column: SizeInt): SizeInt; + Function InternalTabStops: TDynSizeIntArray; + Function InternalTabWidth: SizeInt; + Procedure RemoveAt(Index: SizeInt); + Public + Constructor Create; overload; + Constructor Create(Data: TObject); overload; + Constructor Create(TabWidth: SizeInt); overload; + Constructor Create(Const Tabstops: array Of SizeInt; ZeroBased: Boolean); overload; + Constructor Create(Const Tabstops: array Of SizeInt; ZeroBased: Boolean; TabWidth: SizeInt); overload; + Destructor Destroy; override; // cloning and referencing - function Clone: TJclTabSet; - function NewReference: TJclTabSet; + Function Clone: TJclTabSet; + Function NewReference: TJclTabSet; // Tab stops manipulation - function Add(Column: SizeInt): SizeInt; - function Delete(Column: SizeInt): SizeInt; + Function Add(Column: SizeInt): SizeInt; + Function Delete(Column: SizeInt): SizeInt; // Usage - function Expand(const S: string): string; overload; - function Expand(const S: string; Column: SizeInt): string; overload; - procedure OptimalFillInfo(StartColumn, TargetColumn: SizeInt; out TabsNeeded, SpacesNeeded: SizeInt); - function Optimize(const S: string): string; overload; - function Optimize(const S: string; Column: SizeInt): string; overload; - function StartColumn: SizeInt; - function TabFrom(Column: SizeInt): SizeInt; - function UpdatePosition(const S: string): SizeInt; overload; - function UpdatePosition(const S: string; Column: SizeInt): SizeInt; overload; - function UpdatePosition(const S: string; var Column, Line: SizeInt): SizeInt; overload; + Function Expand(Const S: string): string; overload; + Function Expand(Const S: string; Column: SizeInt): string; overload; + Procedure OptimalFillInfo(StartColumn, TargetColumn: SizeInt; out TabsNeeded, SpacesNeeded: SizeInt); + Function Optimize(Const S: string): string; overload; + Function Optimize(Const S: string; Column: SizeInt): string; overload; + Function StartColumn: SizeInt; + Function TabFrom(Column: SizeInt): SizeInt; + Function UpdatePosition(Const S: string): SizeInt; overload; + Function UpdatePosition(Const S: string; Column: SizeInt): SizeInt; overload; + Function UpdatePosition(Const S: string; Var Column, Line: SizeInt): SizeInt; overload; { IToString } - function ToString: string; overload; {$IFDEF RTL200_UP} override; {$ENDIF RTL200_UP} + Function ToString: string; overload; {$IFDEF RTL200_UP} override; {$ENDIF RTL200_UP} // Conversions - function ToString(FormattingOptions: SizeInt): string; {$IFDEF RTL200_UP} reintroduce; {$ENDIF RTL200_UP} overload; - class function FromString(const S: string): TJclTabSet; {$IFDEF SUPPORTS_STATIC} static; {$ENDIF SUPPORTS_STATIC} + Function ToString(FormattingOptions: SizeInt): string; {$IFDEF RTL200_UP} reintroduce; {$ENDIF RTL200_UP} overload; + Class Function FromString(Const S: string): TJclTabSet; {$IFDEF SUPPORTS_STATIC} static; {$ENDIF SUPPORTS_STATIC} // Properties property ActualTabWidth: SizeInt read InternalTabWidth; property Count: SizeInt read GetCount; property TabStops[Index: SizeInt]: SizeInt read GetStops write SetStops; default; property TabWidth: SizeInt read GetTabWidth write SetTabWidth; property ZeroBased: Boolean read GetZeroBased write SetZeroBased; - end; + End; // Formatting constants -const +Const TabSetFormatting_SurroundStopsWithBrackets = 1; TabSetFormatting_EmptyBracketsIfNoStops = 2; TabSetFormatting_NoTabStops = 4; @@ -485,36 +485,36 @@ TJclTabSet = class (TInterfacedObject, IToString) TabSetFormatting_TabWidthOnly = TabSetFormatting_NoTabStops; TabSetFormatting_StopsWithoutBracketsAndTabWidth = TabSetFormatting_Default; // Tab expansion routines -function StrExpandTabs(S: string): string; {$IFDEF SUPPORTS_INLINE}inline; {$ENDIF} overload; -function StrExpandTabs(S: string; TabWidth: SizeInt): string; {$IFDEF SUPPORTS_INLINE}inline; {$ENDIF} overload; -function StrExpandTabs(S: string; TabSet: TJclTabSet): string; {$IFDEF SUPPORTS_INLINE}inline; {$ENDIF} overload; +Function StrExpandTabs(S: string): string; {$IFDEF SUPPORTS_INLINE}inline; {$ENDIF} overload; +Function StrExpandTabs(S: string; TabWidth: SizeInt): string; {$IFDEF SUPPORTS_INLINE}inline; {$ENDIF} overload; +Function StrExpandTabs(S: string; TabSet: TJclTabSet): string; {$IFDEF SUPPORTS_INLINE}inline; {$ENDIF} overload; // Tab optimization routines -function StrOptimizeTabs(S: string): string; {$IFDEF SUPPORTS_INLINE}inline; {$ENDIF} overload; -function StrOptimizeTabs(S: string; TabWidth: SizeInt): string; {$IFDEF SUPPORTS_INLINE}inline; {$ENDIF} overload; -function StrOptimizeTabs(S: string; TabSet: TJclTabSet): string; {$IFDEF SUPPORTS_INLINE}inline; {$ENDIF} overload; +Function StrOptimizeTabs(S: string): string; {$IFDEF SUPPORTS_INLINE}inline; {$ENDIF} overload; +Function StrOptimizeTabs(S: string; TabWidth: SizeInt): string; {$IFDEF SUPPORTS_INLINE}inline; {$ENDIF} overload; +Function StrOptimizeTabs(S: string; TabSet: TJclTabSet): string; {$IFDEF SUPPORTS_INLINE}inline; {$ENDIF} overload; // move to JclBase? -type - NullReferenceException = class(EJclError) - public - constructor Create; overload; - end; -procedure StrResetLength(var S: DWString); overload; +Type + NullReferenceException = Class(EJclError) + Public + Constructor Create; overload; + End; +Procedure StrResetLength(Var S: DWString); overload; // natural comparison functions {$IFNDEF UNICODE_RTL_DATABASE} // internal structures published to make function inlining working -const +Const MaxStrCharCount = Ord(High(Char)) + 1; // # of chars in one set StrLoOffset = MaxStrCharCount * 0; // offset to lower case chars StrUpOffset = MaxStrCharCount * 1; // offset to upper case chars StrReOffset = MaxStrCharCount * 2; // offset to reverse case chars StrCaseMapSize = MaxStrCharCount * 3; // # of chars is a table -var - StrCaseMap: array [0..StrCaseMapSize - 1] of Char; // case mappings +Var + StrCaseMap: array [0..StrCaseMapSize - 1] Of Char; // case mappings StrCaseMapReady: Boolean = False; // true if case map exists - StrCharTypes: array [Char] of Word; + StrCharTypes: array [Char] Of Word; {$ENDIF ~UNICODE_RTL_DATABASE} -implementation -uses +Implementation +Uses {$IFDEF HAS_UNIT_LIBC} Libc, {$ENDIF HAS_UNIT_LIBC} @@ -527,20 +527,20 @@ implementation {$ENDIF SUPPORTS_UNICODE} uRESTDWMemResources, uRESTDWMemStreams, uRESTDWBasicTypes; //=== Internal =============================================================== -type - TStrRec = packed record +Type + TStrRec = packed Record RefCount: Integer; Length: Integer; - end; + End; PStrRec = ^TStrRec; {$IFNDEF UNICODE_RTL_DATABASE} -procedure LoadCharTypes; -var +Procedure LoadCharTypes; +Var CurrChar: Char; CurrType: Word; -begin - for CurrChar := Low(CurrChar) to High(CurrChar) do - begin +Begin + For CurrChar := Low(CurrChar) To High(CurrChar) Do + Begin {$IFDEF MSWINDOWS} CurrType := 0; GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, @CurrChar, 1, CurrType); @@ -548,37 +548,37 @@ procedure LoadCharTypes; {$ENDIF MSWINDOWS} {$IFDEF LINUX} CurrType := 0; - if isupper(Byte(CurrChar)) <> 0 then + If isupper(Byte(CurrChar)) <> 0 Then CurrType := CurrType or C1_UPPER; - if islower(Byte(CurrChar)) <> 0 then + If islower(Byte(CurrChar)) <> 0 Then CurrType := CurrType or C1_LOWER; - if isdigit(Byte(CurrChar)) <> 0 then + If isdigit(Byte(CurrChar)) <> 0 Then CurrType := CurrType or C1_DIGIT; - if isspace(Byte(CurrChar)) <> 0 then + If isspace(Byte(CurrChar)) <> 0 Then CurrType := CurrType or C1_SPACE; - if ispunct(Byte(CurrChar)) <> 0 then + If ispunct(Byte(CurrChar)) <> 0 Then CurrType := CurrType or C1_PUNCT; - if iscntrl(Byte(CurrChar)) <> 0 then + If iscntrl(Byte(CurrChar)) <> 0 Then CurrType := CurrType or C1_CNTRL; - if isblank(Byte(CurrChar)) <> 0 then + If isblank(Byte(CurrChar)) <> 0 Then CurrType := CurrType or C1_BLANK; - if isxdigit(Byte(CurrChar)) <> 0 then + If isxdigit(Byte(CurrChar)) <> 0 Then CurrType := CurrType or C1_XDIGIT; - if isalpha(Byte(CurrChar)) <> 0 then + If isalpha(Byte(CurrChar)) <> 0 Then CurrType := CurrType or C1_ALPHA; {$DEFINE CHAR_TYPES_INITIALIZED} {$ENDIF LINUX} StrCharTypes[CurrChar] := CurrType; - end; -end; -procedure LoadCaseMap; -var + End; +End; +Procedure LoadCaseMap; +Var CurrChar, UpCaseChar, LoCaseChar, ReCaseChar: Char; -begin - if not StrCaseMapReady then - begin - for CurrChar := Low(Char) to High(Char) do - begin +Begin + If not StrCaseMapReady Then + Begin + For CurrChar := Low(Char) To High(Char) Do + Begin {$IFDEF MSWINDOWS} LoCaseChar := CurrChar; UpCaseChar := CurrChar; @@ -591,69 +591,69 @@ procedure LoadCaseMap; UpCaseChar := Char(toupper(Byte(CurrChar))); {$DEFINE CASE_MAP_INITIALIZED} {$ENDIF LINUX} - if CharIsUpper(CurrChar) then + If CharIsUpper(CurrChar) Then ReCaseChar := LoCaseChar - else - if CharIsLower(CurrChar) then + Else + If CharIsLower(CurrChar) Then ReCaseChar := UpCaseChar - else + Else ReCaseChar := CurrChar; StrCaseMap[Ord(CurrChar) + StrLoOffset] := LoCaseChar; StrCaseMap[Ord(CurrChar) + StrUpOffset] := UpCaseChar; StrCaseMap[Ord(CurrChar) + StrReOffset] := ReCaseChar; - end; + End; StrCaseMapReady := True; - end; -end; + End; +End; // Uppercases or Lowercases a give string depending on the // passed offset. (UpOffset or LoOffset) -procedure StrCase(var Str: string; const Offset: SizeInt); -var +Procedure StrCase(Var Str: string; Const Offset: SizeInt); +Var P: PChar; I, L: SizeInt; -begin +Begin L := Length(Str); - if L > 0 then - begin + If L > 0 Then + Begin UniqueString(Str); P := PChar(Str); - for I := 1 to L do - begin + For I := 1 To L Do + Begin P^ := StrCaseMap[Offset + Ord(P^)]; Inc(P); - end; - end; -end; + End; + End; +End; // Internal utility function // Uppercases or Lowercases a give null terminated string depending on the // passed offset. (UpOffset or LoOffset) -procedure StrCaseBuff(S: PChar; const Offset: SizeInt); -var +Procedure StrCaseBuff(S: PChar; Const Offset: SizeInt); +Var C: Char; -begin - if S <> nil then - begin - repeat +Begin + If S <> nil Then + Begin + Repeat C := S^; S^ := StrCaseMap[Offset + Ord(C)]; Inc(S); - until C = #0; - end; -end; + Until C = #0; + End; +End; {$ENDIF ~UNICODE_RTL_DATABASE} -function StrEndW(Str: PWideChar): PWideChar; -begin +Function StrEndW(Str: PWideChar): PWideChar; +Begin Result := Str; - while Result^ <> #0 do + While Result^ <> #0 Do Inc(Result); -end; -function ArrayContainsChar(const Chars: array of Char; const C: Char): Boolean; -var +End; +Function ArrayContainsChar(Const Chars: array Of Char; Const C: Char): Boolean; +Var idx: SizeInt; -begin +Begin Result := ArrayContainsChar(Chars, C, idx); -end; -function ArrayContainsChar(const Chars: array of Char; const C: Char; out Index: SizeInt): Boolean; +End; +Function ArrayContainsChar(Const Chars: array Of Char; Const C: Char; out Index: SizeInt): Boolean; { optimized version for sorted arrays var I, L, H: SizeInt; @@ -677,315 +677,315 @@ function ArrayContainsChar(const Chars: array of Char; const C: Char; out Index: end; Result := False; end;} -begin +Begin Index := High(Chars); - while (Index >= Low(Chars)) and (Chars[Index] <> C) do + While (Index >= Low(Chars)) and (Chars[Index] <> C) Do Dec(Index); Result := Index >= Low(Chars); -end; +End; // String Test Routines -function StrIsAlpha(const S: string): Boolean; -var +Function StrIsAlpha(Const S: string): Boolean; +Var I: SizeInt; -begin +Begin Result := S <> ''; - for I := 1 to Length(S) do - begin - if not CharIsAlpha(S[I]) then - begin + For I := 1 To Length(S) Do + Begin + If not CharIsAlpha(S[I]) Then + Begin Result := False; Exit; - end; - end; -end; -function StrIsAlphaNum(const S: string): Boolean; -var + End; + End; +End; +Function StrIsAlphaNum(Const S: string): Boolean; +Var I: SizeInt; -begin +Begin Result := S <> ''; - for I := 1 to Length(S) do - begin - if not CharIsAlphaNum(S[I]) then - begin + For I := 1 To Length(S) Do + Begin + If not CharIsAlphaNum(S[I]) Then + Begin Result := False; Exit; - end; - end; -end; -function StrConsistsofNumberChars(const S: string): Boolean; -var + End; + End; +End; +Function StrConsistsofNumberChars(Const S: string): Boolean; +Var I: SizeInt; -begin +Begin Result := S <> ''; - for I := 1 to Length(S) do - begin - if not CharIsNumberChar(S[I]) then - begin + For I := 1 To Length(S) Do + Begin + If not CharIsNumberChar(S[I]) Then + Begin Result := False; Exit; - end; - end; -end; -function StrContainsChars(const S: string; const Chars: TCharValidator; CheckAll: Boolean): Boolean; -var + End; + End; +End; +Function StrContainsChars(Const S: string; Const Chars: TCharValidator; CheckAll: Boolean): Boolean; +Var I: SizeInt; -begin +Begin Result := False; - if CheckAll then - begin + If CheckAll Then + Begin // this will not work with the current definition of the validator. The validator would need to check each character // it requires against the string (which is currently not provided to the Validator). The current implementation of // CheckAll will check if all characters in S will be accepted by the provided Validator, which is wrong and incon- // sistent with the documentation and the array-based overload. - for I := 1 to Length(S) do - begin + For I := 1 To Length(S) Do + Begin Result := Chars(S[I]); - if not Result then + If not Result Then Break; - end; - end - else - begin - for I := 1 to Length(S) do - begin + End; + End + Else + Begin + For I := 1 To Length(S) Do + Begin Result := Chars(S[I]); - if Result then + If Result Then Break; - end; - end; -end; -function StrContainsChars(const S: string; const Chars: array of Char; CheckAll: Boolean): Boolean; -var + End; + End; +End; +Function StrContainsChars(Const S: string; Const Chars: array Of Char; CheckAll: Boolean): Boolean; +Var I: SizeInt; -begin - if CheckAll then - begin +Begin + If CheckAll Then + Begin Result := True; I := High(Chars); - while (I >= 0) and Result do - begin + While (I >= 0) and Result Do + Begin Result := CharPos(S, Chars[I]) > 0; Dec(I); - end; - end - else - begin + End; + End + Else + Begin Result := False; - for I := 1 to Length(S) do - begin + For I := 1 To Length(S) Do + Begin Result := ArrayContainsChar(Chars, S[I]); - if Result then + If Result Then Break; - end; - end; -end; -function StrIsAlphaNumUnderscore(const S: string): Boolean; -var + End; + End; +End; +Function StrIsAlphaNumUnderscore(Const S: string): Boolean; +Var I: SizeInt; C: Char; -begin - for I := 1 to Length(S) do - begin +Begin + For I := 1 To Length(S) Do + Begin C := S[I]; - if not (CharIsAlphaNum(C) or (C = '_')) then - begin + If not (CharIsAlphaNum(C) or (C = '_')) Then + Begin Result := False; Exit; - end; - end; + End; + End; Result := Length(S) > 0; -end; -function StrIsDigit(const S: string): Boolean; -var +End; +Function StrIsDigit(Const S: string): Boolean; +Var I: SizeInt; -begin +Begin Result := S <> ''; - for I := 1 to Length(S) do - begin - if not CharIsDigit(S[I]) then - begin + For I := 1 To Length(S) Do + Begin + If not CharIsDigit(S[I]) Then + Begin Result := False; Exit; - end; - end; -end; -function StrIsSubset(const S: string; const ValidChars: TCharValidator): Boolean; -var + End; + End; +End; +Function StrIsSubset(Const S: string; Const ValidChars: TCharValidator): Boolean; +Var I: SizeInt; -begin - for I := 1 to Length(S) do - begin +Begin + For I := 1 To Length(S) Do + Begin Result := ValidChars(S[I]); - if not Result then + If not Result Then Exit; - end; + End; Result := Length(S) > 0; -end; -function StrIsSubset(const S: string; const ValidChars: array of Char): Boolean; -var +End; +Function StrIsSubset(Const S: string; Const ValidChars: array Of Char): Boolean; +Var I: SizeInt; -begin - for I := 1 to Length(S) do - begin +Begin + For I := 1 To Length(S) Do + Begin Result := ArrayContainsChar(ValidChars, S[I]); - if not Result then + If not Result Then Exit; - end; + End; Result := Length(S) > 0; -end; -function StrSame(const S1, S2: string; CaseSensitive: Boolean): Boolean; -begin +End; +Function StrSame(Const S1, S2: string; CaseSensitive: Boolean): Boolean; +Begin Result := StrCompare(S1, S2, CaseSensitive) = 0; -end; +End; //=== String Transformation Routines ========================================= -function StrCenter(const S: string; L: SizeInt; C: Char = ' '): string; -begin - if Length(S) < L then - begin +Function StrCenter(Const S: string; L: SizeInt; C: Char = ' '): string; +Begin + If Length(S) < L Then + Begin Result := StringOfChar(C, (L - Length(S)) div 2) + S; Result := Result + StringOfChar(C, L - Length(Result)); - end - else + End + Else Result := S; -end; -function StrCharPosLower(const S: string; CharPos: SizeInt): string; -begin +End; +Function StrCharPosLower(Const S: string; CharPos: SizeInt): string; +Begin Result := S; - if (CharPos > 0) and (CharPos <= Length(S)) then + If (CharPos > 0) and (CharPos <= Length(S)) Then Result[CharPos] := CharLower(Result[CharPos]); -end; -function StrCharPosUpper(const S: string; CharPos: SizeInt): string; -begin +End; +Function StrCharPosUpper(Const S: string; CharPos: SizeInt): string; +Begin Result := S; - if (CharPos > 0) and (CharPos <= Length(S)) then + If (CharPos > 0) and (CharPos <= Length(S)) Then Result[CharPos] := CharUpper(Result[CharPos]); -end; -function StrDoubleQuote(const S: string): string; -begin +End; +Function StrDoubleQuote(Const S: string): string; +Begin Result := NativeDoubleQuote + S + NativeDoubleQuote; -end; -function StrEnsureNoPrefix(const Prefix, Text: string): string; -var +End; +Function StrEnsureNoPrefix(Const Prefix, Text: string): string; +Var PrefixLen: SizeInt; -begin +Begin PrefixLen := Length(Prefix); - if Copy(Text, 1, PrefixLen) = Prefix then + If Copy(Text, 1, PrefixLen) = Prefix Then Result := Copy(Text, PrefixLen + 1, Length(Text)) - else + Else Result := Text; -end; -function StrEnsureNoSuffix(const Suffix, Text: string): string; -var +End; +Function StrEnsureNoSuffix(Const Suffix, Text: string): string; +Var SuffixLen: SizeInt; StrLength: SizeInt; -begin +Begin SuffixLen := Length(Suffix); StrLength := Length(Text); - if Copy(Text, StrLength - SuffixLen + 1, SuffixLen) = Suffix then + If Copy(Text, StrLength - SuffixLen + 1, SuffixLen) = Suffix Then Result := Copy(Text, 1, StrLength - SuffixLen) - else + Else Result := Text; -end; -function StrEnsurePrefix(const Prefix, Text: string): string; -var +End; +Function StrEnsurePrefix(Const Prefix, Text: string): string; +Var PrefixLen: SizeInt; -begin +Begin PrefixLen := Length(Prefix); - if Copy(Text, 1, PrefixLen) = Prefix then + If Copy(Text, 1, PrefixLen) = Prefix Then Result := Text - else + Else Result := Prefix + Text; -end; -function StrEnsureSuffix(const Suffix, Text: string): string; -var +End; +Function StrEnsureSuffix(Const Suffix, Text: string): string; +Var SuffixLen: SizeInt; -begin +Begin SuffixLen := Length(Suffix); - if Copy(Text, Length(Text) - SuffixLen + 1, SuffixLen) = Suffix then + If Copy(Text, Length(Text) - SuffixLen + 1, SuffixLen) = Suffix Then Result := Text - else + Else Result := Text + Suffix; -end; -function StrEscapedToString(const S: string): string; - procedure HandleHexEscapeSeq(const S: string; var I: SizeInt; Len: SizeInt; var Dest: string); - const +End; +Function StrEscapedToString(Const S: string): string; + Procedure HandleHexEscapeSeq(Const S: string; Var I: SizeInt; Len: SizeInt; Var Dest: string); + Const HexDigits = string('0123456789abcdefABCDEF'); - var + Var StartI, Val, N: SizeInt; - begin + Begin StartI := I; N := Pos(S[I + 1], HexDigits) - 1; - if N < 0 then + If N < 0 Then // '\x' without hex digit following is not escape sequence Dest := Dest + '\x' - else - begin + Else + Begin Inc(I); // Jump over x - if N >= 16 then + If N >= 16 Then N := N - 6; Val := N; // Same for second digit - if I < Len then - begin + If I < Len Then + Begin N := Pos(S[I + 1], HexDigits) - 1; - if N >= 0 then - begin + If N >= 0 Then + Begin Inc(I); // Jump over first digit - if N >= 16 then + If N >= 16 Then N := N - 6; Val := Val * 16 + N; - end; - end; - if Val > Ord(High(Char)) then + End; + End; + If Val > Ord(High(Char)) Then raise EJclStringError.CreateResFmt(@RsNumericConstantTooLarge, [Val, StartI]); Dest := Dest + Char(Val); - end; - end; - procedure HandleOctEscapeSeq(const S: string; var I: SizeInt; Len: SizeInt; var Dest: string); - const + End; + End; + Procedure HandleOctEscapeSeq(Const S: string; Var I: SizeInt; Len: SizeInt; Var Dest: string); + Const OctDigits = string('01234567'); - var + Var StartI, Val, N: SizeInt; - begin + Begin StartI := I; // first digit Val := Pos(S[I], OctDigits) - 1; - if I < Len then - begin + If I < Len Then + Begin N := Pos(S[I + 1], OctDigits) - 1; - if N >= 0 then - begin + If N >= 0 Then + Begin Inc(I); Val := Val * 8 + N; - end; - if I < Len then - begin + End; + If I < Len Then + Begin N := Pos(S[I + 1], OctDigits) - 1; - if N >= 0 then - begin + If N >= 0 Then + Begin Inc(I); Val := Val * 8 + N; - end; - end; - end; - if Val > Ord(High(Char)) then + End; + End; + End; + If Val > Ord(High(Char)) Then raise EJclStringError.CreateResFmt(@RsNumericConstantTooLarge, [Val, StartI]); Dest := Dest + Char(Val); - end; -var + End; +Var I, Len: SizeInt; -begin +Begin Result := ''; I := 1; Len := Length(S); - while I <= Len do - begin - if not ((S[I] = '\') and (I < Len)) then + While I <= Len Do + Begin + If not ((S[I] = '\') and (I < Len)) Then Result := Result + S[I] - else - begin + Else + Begin Inc(I); // Jump over escape character - case S[I] of + Case S[I] Of 'a': Result := Result + NativeBell; 'b': @@ -1009,273 +1009,273 @@ function StrEscapedToString(const S: string): string; '?': Result := Result + '?'; // Optionally escaped 'x': - if I < Len then + If I < Len Then // Start of hex escape sequence HandleHexEscapeSeq(S, I, Len, Result) - else + Else // '\x' at end of string is not escape sequence Result := Result + '\x'; '0'..'7': // start of octal escape sequence HandleOctEscapeSeq(S, I, Len, Result); - else + Else // no escape sequence Result := Result + '\' + S[I]; - end; - end; + End; + End; Inc(I); - end; -end; -function StrLower(const S: string): string; -begin + End; +End; +Function StrLower(Const S: string): string; +Begin Result := S; StrLowerInPlace(Result); -end; -procedure StrLowerInPlace(var S: string); +End; +Procedure StrLowerInPlace(Var S: string); {$IFDEF UNICODE_RTL_DATABASE} -var +Var P: PChar; I, L: SizeInt; -begin +Begin L := Length(S); - if L > 0 then - begin + If L > 0 Then + Begin UniqueString(S); P := PChar(S); - for I := 1 to L do - begin + For I := 1 To L Do + Begin P^ := TCharacter.ToLower(P^); Inc(P); - end; - end; -end; + End; + End; +End; {$ELSE ~UNICODE_RTL_DATABASE} -begin +Begin StrCase(S, StrLoOffset); -end; +End; {$ENDIF ~UNICODE_RTL_DATABASE} -procedure StrLowerBuff(S: PChar); -begin +Procedure StrLowerBuff(S: PChar); +Begin {$IFDEF UNICODE_RTL_DATABASE} - if S <> nil then - begin - repeat + If S <> nil Then + Begin + Repeat S^ := TCharacter.ToLower(S^); Inc(S); - until S^ = #0; - end; + Until S^ = #0; + End; {$ELSE ~UNICODE_RTL_DATABASE} StrCaseBuff(S, StrLoOffset); {$ENDIF ~UNICODE_RTL_DATABASE} -end; -procedure StrMove(var Dest: string; const Source: string; - const ToIndex, FromIndex, Count: SizeInt); -begin +End; +Procedure StrMove(Var Dest: string; Const Source: string; + Const ToIndex, FromIndex, Count: SizeInt); +Begin // Check strings - if (Source = '') or (Length(Dest) = 0) then + If (Source = '') or (Length(Dest) = 0) Then Exit; // Check FromIndex - if (FromIndex <= 0) or (FromIndex > Length(Source)) or + If (FromIndex <= 0) or (FromIndex > Length(Source)) or (ToIndex <= 0) or (ToIndex > Length(Dest)) or - ((FromIndex + Count - 1) > Length(Source)) or ((ToIndex + Count - 1) > Length(Dest)) then + ((FromIndex + Count - 1) > Length(Source)) or ((ToIndex + Count - 1) > Length(Dest)) Then { TODO : Is failure without notice the proper thing to do here? } Exit; // Move Move(Source[FromIndex], Dest[ToIndex], Count * SizeOf(Char)); -end; -function StrPadLeft(const S: string; Len: SizeInt; C: Char): string; -var +End; +Function StrPadLeft(Const S: string; Len: SizeInt; C: Char): string; +Var L: SizeInt; -begin +Begin L := Length(S); - if L < Len then + If L < Len Then Result := StringOfChar(C, Len - L) + S - else + Else Result := S; -end; -function StrPadRight(const S: string; Len: SizeInt; C: Char): string; -var +End; +Function StrPadRight(Const S: string; Len: SizeInt; C: Char): string; +Var L: SizeInt; -begin +Begin L := Length(S); - if L < Len then + If L < Len Then Result := S + StringOfChar(C, Len - L) - else + Else Result := S; -end; -function StrProper(const S: string): string; -begin +End; +Function StrProper(Const S: string): string; +Begin Result := StrLower(S); - if Result <> '' then + If Result <> '' Then Result[1] := UpCase(Result[1]); -end; -procedure StrProperBuff(S: PChar); -begin - if (S <> nil) and (S^ <> #0) then - begin +End; +Procedure StrProperBuff(S: PChar); +Begin + If (S <> nil) and (S^ <> #0) Then + Begin StrLowerBuff(S); S^ := CharUpper(S^); - end; -end; -function StrQuote(const S: string; C: Char): string; -var + End; +End; +Function StrQuote(Const S: string; C: Char): string; +Var L: SizeInt; -begin +Begin L := Length(S); Result := S; - if L > 0 then - begin - if Result[1] <> C then - begin + If L > 0 Then + Begin + If Result[1] <> C Then + Begin Result := C + Result; Inc(L); - end; - if Result[L] <> C then + End; + If Result[L] <> C Then Result := Result + C; - end; -end; -function StrRemoveChars(const S: string; const Chars: TCharValidator): string; -var + End; +End; +Function StrRemoveChars(Const S: string; Const Chars: TCharValidator): string; +Var Source, Dest: PChar; Len, Index: SizeInt; -begin +Begin Len := Length(S); SetLength(Result, Len); UniqueString(Result); Source := PChar(S); Dest := PChar(Result); - for Index := 0 to Len - 1 do - begin - if not Chars(Source^) then - begin + For Index := 0 To Len - 1 Do + Begin + If not Chars(Source^) Then + Begin Dest^ := Source^; Inc(Dest); - end; + End; Inc(Source); - end; + End; SetLength(Result, Dest - PChar(Result)); -end; -function StrRemoveChars(const S: string; const Chars: array of Char): string; -var +End; +Function StrRemoveChars(Const S: string; Const Chars: array Of Char): string; +Var Source, Dest: PChar; Len, Index: SizeInt; -begin +Begin Len := Length(S); SetLength(Result, Len); UniqueString(Result); Source := PChar(S); Dest := PChar(Result); - for Index := 0 to Len - 1 do - begin - if not ArrayContainsChar(Chars, Source^) then - begin + For Index := 0 To Len - 1 Do + Begin + If not ArrayContainsChar(Chars, Source^) Then + Begin Dest^ := Source^; Inc(Dest); - end; + End; Inc(Source); - end; + End; SetLength(Result, Dest - PChar(Result)); -end; -function StrRemoveLeadingChars(const S: string; const Chars: TCharValidator): string; -var +End; +Function StrRemoveLeadingChars(Const S: string; Const Chars: TCharValidator): string; +Var Len : SizeInt; I: SizeInt; -begin +Begin Len := Length(S); I := 1; - while (I <= Len) and Chars(s[I]) do + While (I <= Len) and Chars(s[I]) Do Inc(I); Result := Copy (s, I, Len-I+1); -end; -function StrRemoveLeadingChars(const S: string; const Chars: array of Char): string; -var +End; +Function StrRemoveLeadingChars(Const S: string; Const Chars: array Of Char): string; +Var Len : SizeInt; I: SizeInt; -begin +Begin Len := Length(S); I := 1; - while (I <= Len) and ArrayContainsChar(Chars, s[I]) do + While (I <= Len) and ArrayContainsChar(Chars, s[I]) Do Inc(I); Result := Copy (s, I, Len-I+1); -end; -function StrRemoveEndChars(const S: string; const Chars: TCharValidator): string; -var +End; +Function StrRemoveEndChars(Const S: string; Const Chars: TCharValidator): string; +Var Len : SizeInt; -begin +Begin Len := Length(S); - while (Len > 0) and Chars(s[Len]) do + While (Len > 0) and Chars(s[Len]) Do Dec(Len); Result := Copy (s, 1, Len); -end; -function StrRemoveEndChars(const S: string; const Chars: array of Char): string; -var +End; +Function StrRemoveEndChars(Const S: string; Const Chars: array Of Char): string; +Var Len : SizeInt; -begin +Begin Len := Length(S); - while (Len > 0) and ArrayContainsChar(Chars, s[Len]) do + While (Len > 0) and ArrayContainsChar(Chars, s[Len]) Do Dec(Len); Result := Copy (s, 1, Len); -end; -function StrKeepChars(const S: string; const Chars: TCharValidator): string; -var +End; +Function StrKeepChars(Const S: string; Const Chars: TCharValidator): string; +Var Source, Dest: PChar; Len, Index: SizeInt; -begin +Begin Len := Length(S); SetLength(Result, Len); UniqueString(Result); Source := PChar(S); Dest := PChar(Result); - for Index := 0 to Len - 1 do - begin - if Chars(Source^) then - begin + For Index := 0 To Len - 1 Do + Begin + If Chars(Source^) Then + Begin Dest^ := Source^; Inc(Dest); - end; + End; Inc(Source); - end; + End; SetLength(Result, Dest - PChar(Result)); -end; -function StrKeepChars(const S: string; const Chars: array of Char): string; -var +End; +Function StrKeepChars(Const S: string; Const Chars: array Of Char): string; +Var Source, Dest: PChar; Len, Index: SizeInt; -begin +Begin Len := Length(S); SetLength(Result, Len); UniqueString(Result); Source := PChar(S); Dest := PChar(Result); - for Index := 0 to Len - 1 do - begin - if ArrayContainsChar(Chars, Source^) then - begin + For Index := 0 To Len - 1 Do + Begin + If ArrayContainsChar(Chars, Source^) Then + Begin Dest^ := Source^; Inc(Dest); - end; + End; Inc(Source); - end; + End; SetLength(Result, Dest - PChar(Result)); -end; -function StrRepeat(const S: string; Count: SizeInt): string; -var +End; +Function StrRepeat(Const S: string; Count: SizeInt): string; +Var Len, Index: SizeInt; Dest, Source: PChar; -begin +Begin Len := Length(S); SetLength(Result, Count * Len); Dest := PChar(Result); Source := PChar(S); - if Dest <> nil then - for Index := 0 to Count - 1 do - begin + If Dest <> nil Then + For Index := 0 To Count - 1 Do + Begin Move(Source^, Dest^, Len * SizeOf(Char)); Inc(Dest, Len); - end; -end; -procedure StrReplace(var S: string; const Search, Replace: string; Flags: TReplaceFlags); -var + End; +End; +Procedure StrReplace(Var S: string; Const Search, Replace: string; Flags: TReplaceFlags); +Var SearchStr: string; ResultStr: string; { result string } SourcePtr: PChar; { pointer into S of character under examination } @@ -1289,23 +1289,23 @@ procedure StrReplace(var S: string; const Search, Replace: string; Flags: TRepla ResultLength: SizeInt; { length of result string } C: Char; { first character of search string } IgnoreCase: Boolean; -begin - if Search = '' then - begin - if S = '' then - begin +Begin + If Search = '' Then + Begin + If S = '' Then + Begin S := Replace; Exit; - end - else + End + Else raise EJclStringError.CreateRes(@RsBlankSearchString); - end; - if S <> '' then - begin + End; + If S <> '' Then + Begin IgnoreCase := rfIgnoreCase in Flags; - if IgnoreCase then + If IgnoreCase Then SearchStr := StrUpper(Search) - else + Else SearchStr := Search; { avoid having to call Length() within the loop } SearchLength := Length(Search); @@ -1318,244 +1318,244 @@ procedure StrReplace(var S: string; const Search, Replace: string; Flags: TRepla SourcePtr := PChar(S); C := SearchStr[1]; { while we haven't reached the end of the string } - while True do - begin + While True Do + Begin { copy characters until we find the first character of the search string } - if IgnoreCase then - while (CharUpper(SourcePtr^) <> C) and (SourcePtr^ <> #0) do - begin + If IgnoreCase Then + While (CharUpper(SourcePtr^) <> C) and (SourcePtr^ <> #0) Do + Begin ResultPtr^ := SourcePtr^; Inc(ResultPtr); Inc(SourcePtr); - end - else - while (SourcePtr^ <> C) and (SourcePtr^ <> #0) do - begin + End + Else + While (SourcePtr^ <> C) and (SourcePtr^ <> #0) Do + Begin ResultPtr^ := SourcePtr^; Inc(ResultPtr); Inc(SourcePtr); - end; + End; { did we find that first character or did we hit the end of the string? } - if SourcePtr^ = #0 then + If SourcePtr^ = #0 Then Break - else - begin + Else + Begin { continue comparing, +1 because first character was matched already } SourceMatchPtr := SourcePtr + 1; SearchMatchPtr := PChar(SearchStr) + 1; - if IgnoreCase then - while (CharUpper(SourceMatchPtr^) = SearchMatchPtr^) and (SearchMatchPtr^ <> #0) do - begin + If IgnoreCase Then + While (CharUpper(SourceMatchPtr^) = SearchMatchPtr^) and (SearchMatchPtr^ <> #0) Do + Begin Inc(SourceMatchPtr); Inc(SearchMatchPtr); - end - else - while (SourceMatchPtr^ = SearchMatchPtr^) and (SearchMatchPtr^ <> #0) do - begin + End + Else + While (SourceMatchPtr^ = SearchMatchPtr^) and (SearchMatchPtr^ <> #0) Do + Begin Inc(SourceMatchPtr); Inc(SearchMatchPtr); - end; + End; { did we find a complete match? } - if SearchMatchPtr^ = #0 then - begin + If SearchMatchPtr^ = #0 Then + Begin // keep track of result length Inc(ResultLength, ReplaceLength - SearchLength); - if ReplaceLength > 0 then - begin + If ReplaceLength > 0 Then + Begin // increase buffer size if required - if ResultLength > BufferLength then - begin + If ResultLength > BufferLength Then + Begin BufferLength := ResultLength * 2; ResultIndex := ResultPtr - PChar(ResultStr) + 1; SetLength(ResultStr, BufferLength); ResultPtr := @ResultStr[ResultIndex]; - end; + End; { append replace to result and move past the search string in source } Move((@Replace[1])^, ResultPtr^, ReplaceLength * SizeOf(Char)); - end; + End; Inc(SourcePtr, SearchLength); Inc(ResultPtr, ReplaceLength); { replace all instances or just one? } - if not (rfReplaceAll in Flags) then - begin + If not (rfReplaceAll in Flags) Then + Begin { just one, copy until end of source and break out of loop } - while SourcePtr^ <> #0 do - begin + While SourcePtr^ <> #0 Do + Begin ResultPtr^ := SourcePtr^; Inc(ResultPtr); Inc(SourcePtr); - end; + End; Break; - end; - end - else - begin + End; + End + Else + Begin { copy current character and start over with the next } ResultPtr^ := SourcePtr^; Inc(ResultPtr); Inc(SourcePtr); - end; - end; - end; + End; + End; + End; { set result length and copy result into S } SetLength(ResultStr, ResultLength); S := ResultStr; - end; -end; -function StrReplaceChar(const S: string; const Source, Replace: Char): string; -var + End; +End; +Function StrReplaceChar(Const S: string; Const Source, Replace: Char): string; +Var I: SizeInt; -begin +Begin Result := S; - for I := 1 to Length(S) do - if Result[I] = Source then + For I := 1 To Length(S) Do + If Result[I] = Source Then Result[I] := Replace; -end; -function StrReplaceChars(const S: string; const Chars: TCharValidator; Replace: Char): string; -var +End; +Function StrReplaceChars(Const S: string; Const Chars: TCharValidator; Replace: Char): string; +Var I: SizeInt; -begin +Begin Result := S; - for I := 1 to Length(S) do - if Chars(Result[I]) then + For I := 1 To Length(S) Do + If Chars(Result[I]) Then Result[I] := Replace; -end; -function StrReplaceChars(const S: string; const Chars: array of Char; Replace: Char): string; -var +End; +Function StrReplaceChars(Const S: string; Const Chars: array Of Char; Replace: Char): string; +Var I: SizeInt; -begin +Begin Result := S; - for I := 1 to Length(S) do - if ArrayContainsChar(Chars, Result[I]) then + For I := 1 To Length(S) Do + If ArrayContainsChar(Chars, Result[I]) Then Result[I] := Replace; -end; -function StrReplaceButChars(const S: string; const Chars: TCharValidator; +End; +Function StrReplaceButChars(Const S: string; Const Chars: TCharValidator; Replace: Char): string; -var +Var I: SizeInt; -begin +Begin Result := S; - for I := 1 to Length(S) do - if not Chars(Result[I]) then + For I := 1 To Length(S) Do + If not Chars(Result[I]) Then Result[I] := Replace; -end; -function StrReplaceButChars(const S: string; const Chars: array of Char; Replace: Char): string; -var +End; +Function StrReplaceButChars(Const S: string; Const Chars: array Of Char; Replace: Char): string; +Var I: SizeInt; -begin +Begin Result := S; - for I := 1 to Length(S) do - if not ArrayContainsChar(Chars, Result[I]) then + For I := 1 To Length(S) Do + If not ArrayContainsChar(Chars, Result[I]) Then Result[I] := Replace; -end; -function StrReverse(const S: string): string; -begin +End; +Function StrReverse(Const S: string): string; +Begin Result := S; StrReverseInplace(Result); -end; -procedure StrReverseInPlace(var S: string); +End; +Procedure StrReverseInPlace(Var S: string); { TODO -oahuser : Warning: This is dangerous for unicode surrogates } -var +Var P1, P2: PChar; C: Char; -begin +Begin UniqueString(S); P1 := PChar(S); P2 := P1 + (Length(S) - 1); - while P1 < P2 do - begin + While P1 < P2 Do + Begin C := P1^; P1^ := P2^; P2^ := C; Inc(P1); Dec(P2); - end; -end; -function StrSingleQuote(const S: string): string; -begin + End; +End; +Function StrSingleQuote(Const S: string): string; +Begin Result := NativeSingleQuote + S + NativeSingleQuote; -end; -procedure StrSkipChars(var S: PChar; const Chars: TCharValidator); -begin - while Chars(S^) do +End; +Procedure StrSkipChars(Var S: PChar; Const Chars: TCharValidator); +Begin + While Chars(S^) Do Inc(S); -end; -procedure StrSkipChars(var S: PChar; const Chars: array of Char); -begin - while ArrayContainsChar(Chars, S^) do +End; +Procedure StrSkipChars(Var S: PChar; Const Chars: array Of Char); +Begin + While ArrayContainsChar(Chars, S^) Do Inc(S); -end; -procedure StrSkipChars(const S: string; var Index: SizeInt; const Chars: TCharValidator); -begin - while Chars(S[Index]) do +End; +Procedure StrSkipChars(Const S: string; Var Index: SizeInt; Const Chars: TCharValidator); +Begin + While Chars(S[Index]) Do Inc(Index); -end; -procedure StrSkipChars(const S: string; var Index: SizeInt; const Chars: array of Char); -begin - while ArrayContainsChar(Chars, S[Index]) do +End; +Procedure StrSkipChars(Const S: string; Var Index: SizeInt; Const Chars: array Of Char); +Begin + While ArrayContainsChar(Chars, S[Index]) Do Inc(Index); -end; -function StrSmartCase(const S: string; const Delimiters: TCharValidator): string; -var +End; +Function StrSmartCase(Const S: string; Const Delimiters: TCharValidator): string; +Var Source, Dest: PChar; Index, Len: SizeInt; InternalDelimiters: TCharValidator; -begin +Begin Result := ''; - if Assigned(Delimiters) then + If Assigned(Delimiters) Then InternalDelimiters := Delimiters - else + Else InternalDelimiters := CharIsSpace; - if S <> '' then - begin + If S <> '' Then + Begin Result := S; UniqueString(Result); Len := Length(S); Source := PChar(S); Dest := PChar(Result); Inc(Dest); - for Index := 2 to Len do - begin - if InternalDelimiters(Source^) and not InternalDelimiters(Dest^) then + For Index := 2 To Len Do + Begin + If InternalDelimiters(Source^) and not InternalDelimiters(Dest^) Then Dest^ := CharUpper(Dest^); Inc(Dest); Inc(Source); - end; + End; Result[1] := CharUpper(Result[1]); - end; -end; -function StrSmartCase(const S: string; const Delimiters: array of Char): string; -var + End; +End; +Function StrSmartCase(Const S: string; Const Delimiters: array Of Char): string; +Var Source, Dest: PChar; Index, Len: SizeInt; -begin +Begin Result := ''; - if S <> '' then - begin + If S <> '' Then + Begin Result := S; UniqueString(Result); Len := Length(S); Source := PChar(S); Dest := PChar(Result); Inc(Dest); - for Index := 2 to Len do - begin - if ArrayContainsChar(Delimiters, Source^) and not ArrayContainsChar(Delimiters, Dest^) then + For Index := 2 To Len Do + Begin + If ArrayContainsChar(Delimiters, Source^) and not ArrayContainsChar(Delimiters, Dest^) Then Dest^ := CharUpper(Dest^); Inc(Dest); Inc(Source); - end; + End; Result[1] := CharUpper(Result[1]); - end; -end; -function StrStringToEscaped(const S: string): string; -var + End; +End; +Function StrStringToEscaped(Const S: string): string; +Var I: SizeInt; -begin +Begin Result := ''; - for I := 1 to Length(S) do - begin - case S[I] of + For I := 1 To Length(S) Do + Begin + Case S[I] Of NativeBackspace: Result := Result + '\b'; NativeBell: @@ -1574,299 +1574,299 @@ function StrStringToEscaped(const S: string): string; Result := Result + '\\'; NativeDoubleQuote: Result := Result + '\"'; - else + Else // Characters < ' ' are escaped with hex sequence - if S[I] < #32 then + If S[I] < #32 Then Result := Result + Format('\x%.2x', [SizeInt(S[I])]) - else + Else Result := Result + S[I]; - end; - end; -end; -function StrStripNonNumberChars(const S: string): string; -var + End; + End; +End; +Function StrStripNonNumberChars(Const S: string): string; +Var I: SizeInt; C: Char; -begin +Begin Result := ''; - for I := 1 to Length(S) do - begin + For I := 1 To Length(S) Do + Begin C := S[I]; - if CharIsNumberChar(C) then + If CharIsNumberChar(C) Then Result := Result + C; - end; -end; -function StrToHex(const Source: string): string; -var + End; +End; +Function StrToHex(Const Source: string): string; +Var Index: SizeInt; C, L, N: SizeInt; BL, BH: Byte; S: string; -begin +Begin Result := ''; - if Source <> '' then - begin + If Source <> '' Then + Begin S := Source; L := Length(S); - if Odd(L) then - begin + If Odd(L) Then + Begin S := '0' + S; Inc(L); - end; + End; Index := 1; SetLength(Result, L div 2); C := 1; N := 1; - while C <= L do - begin + While C <= L Do + Begin BH := CharHex(S[Index]); Inc(Index); BL := CharHex(S[Index]); Inc(Index); Inc(C, 2); - if (BH = $FF) or (BL = $FF) then - begin + If (BH = $FF) or (BL = $FF) Then + Begin Result := ''; Exit; - end; + End; Result[N] := Char((BH shl 4) or BL); Inc(N); - end; - end; -end; -function StrTrimCharLeft(const S: string; C: Char): string; -var + End; + End; +End; +Function StrTrimCharLeft(Const S: string; C: Char): string; +Var I, L: SizeInt; -begin +Begin I := 1; L := Length(S); - while (I <= L) and (S[I] = C) do + While (I <= L) and (S[I] = C) Do Inc(I); Result := Copy(S, I, L - I + 1); -end; -function StrTrimCharsLeft(const S: string; const Chars: TCharValidator): string; -var +End; +Function StrTrimCharsLeft(Const S: string; Const Chars: TCharValidator): string; +Var I, L: SizeInt; -begin +Begin I := 1; L := Length(S); - while (I <= L) and Chars(S[I]) do + While (I <= L) and Chars(S[I]) Do Inc(I); Result := Copy(S, I, L - I + 1); -end; -function StrTrimCharsLeft(const S: string; const Chars: array of Char): string; -var +End; +Function StrTrimCharsLeft(Const S: string; Const Chars: array Of Char): string; +Var I, L: SizeInt; -begin +Begin I := 1; L := Length(S); - while (I <= L) and ArrayContainsChar(Chars, S[I]) do + While (I <= L) and ArrayContainsChar(Chars, S[I]) Do Inc(I); Result := Copy(S, I, L - I + 1); -end; -function StrTrimCharRight(const S: string; C: Char): string; -var +End; +Function StrTrimCharRight(Const S: string; C: Char): string; +Var I: SizeInt; -begin +Begin I := Length(S); - while (I >= 1) and (S[I] = C) do + While (I >= 1) and (S[I] = C) Do Dec(I); Result := Copy(S, 1, I); -end; -function StrTrimCharsRight(const S: string; const Chars: TCharValidator): string; -var +End; +Function StrTrimCharsRight(Const S: string; Const Chars: TCharValidator): string; +Var I: SizeInt; -begin +Begin I := Length(S); - while (I >= 1) and Chars(S[I]) do + While (I >= 1) and Chars(S[I]) Do Dec(I); Result := Copy(S, 1, I); -end; -function StrTrimCharsRight(const S: string; const Chars: array of Char): string; -var +End; +Function StrTrimCharsRight(Const S: string; Const Chars: array Of Char): string; +Var I: SizeInt; -begin +Begin I := Length(S); - while (I >= 1) and ArrayContainsChar(Chars, S[I]) do + While (I >= 1) and ArrayContainsChar(Chars, S[I]) Do Dec(I); Result := Copy(S, 1, I); -end; -function StrTrimQuotes(const S: string): string; -var +End; +Function StrTrimQuotes(Const S: string): string; +Var First, Last: Char; L: SizeInt; -begin +Begin L := Length(S); - if L > 1 then - begin + If L > 1 Then + Begin First := S[1]; Last := S[L]; - if (First = Last) and ((First = NativeSingleQuote) or (First = NativeDoubleQuote)) then + If (First = Last) and ((First = NativeSingleQuote) or (First = NativeDoubleQuote)) Then Result := Copy(S, 2, L - 2) - else + Else Result := S; - end - else + End + Else Result := S; -end; -function StrUpper(const S: string): string; -begin +End; +Function StrUpper(Const S: string): string; +Begin Result := S; StrUpperInPlace(Result); -end; -procedure StrUpperInPlace(var S: string); +End; +Procedure StrUpperInPlace(Var S: string); {$IFDEF UNICODE_RTL_DATABASE} -var +Var P: PChar; I, L: SizeInt; -begin +Begin L := Length(S); - if L > 0 then - begin + If L > 0 Then + Begin UniqueString(S); P := PChar(S); - for I := 1 to L do - begin + For I := 1 To L Do + Begin P^ := TCharacter.ToUpper(P^); Inc(P); - end; - end; -end; + End; + End; +End; {$ELSE ~UNICODE_RTL_DATABASE} -begin +Begin StrCase(S, StrUpOffset); -end; +End; {$ENDIF ~UNICODE_RTL_DATABASE} -procedure StrUpperBuff(S: PChar); -begin +Procedure StrUpperBuff(S: PChar); +Begin {$IFDEF UNICODE_RTL_DATABASE} - if S <> nil then - begin - repeat + If S <> nil Then + Begin + Repeat S^ := TCharacter.ToUpper(S^); Inc(S); - until S^ = #0; - end; + Until S^ = #0; + End; {$ELSE ~UNICODE_RTL_DATABASE} StrCaseBuff(S, StrUpOffset); {$ENDIF ~UNICODE_RTL_DATABASE} -end; +End; //=== String Management ====================================================== -procedure StrAddRef(var S: string); -var +Procedure StrAddRef(Var S: string); +Var P: PStrRec; -begin +Begin P := Pointer(S); - if P <> nil then - begin + If P <> nil Then + Begin Dec(P); - if P^.RefCount = -1 then + If P^.RefCount = -1 Then UniqueString(S); - end; -end; -procedure StrDecRef(var S: string); -var + End; +End; +Procedure StrDecRef(Var S: string); +Var P: PStrRec; -begin +Begin P := Pointer(S); - if P <> nil then - begin + If P <> nil Then + Begin Dec(P); - case P^.RefCount of + Case P^.RefCount Of -1, 0: { nothing } ; 1: - begin + Begin Finalize(S); Pointer(S) := nil; - end; - end; - end; -end; -function StrLength(const S: string): SizeInt; -var + End; + End; + End; +End; +Function StrLength(Const S: string): SizeInt; +Var P: PStrRec; -begin +Begin Result := 0; P := Pointer(S); - if P <> nil then - begin + If P <> nil Then + Begin Dec(P); Result := P^.Length and (not $80000000 shr 1); - end; -end; -function StrRefCount(const S: string): SizeInt; -var + End; +End; +Function StrRefCount(Const S: string): SizeInt; +Var P: PStrRec; -begin +Begin Result := 0; P := Pointer(S); - if P <> nil then - begin + If P <> nil Then + Begin Dec(P); Result := P^.RefCount; - end; -end; -procedure StrResetLength(var S: DWString); -var + End; +End; +Procedure StrResetLength(Var S: DWString); +Var I: SizeInt; -begin - for I := 0 to Length(S) - 1 do - if S[I + 1] = #0 then - begin +Begin + For I := 0 To Length(S) - 1 Do + If S[I + 1] = #0 Then + Begin SetLength(S, I); Exit; - end; -end; + End; +End; //=== String Search and Replace Routines ===================================== -function StrCharCount(const S: string; C: Char): SizeInt; -var +Function StrCharCount(Const S: string; C: Char): SizeInt; +Var I: SizeInt; -begin +Begin Result := 0; - for I := 1 to Length(S) do - if S[I] = C then + For I := 1 To Length(S) Do + If S[I] = C Then Inc(Result); -end; -function StrCharsCount(const S: string; const Chars: TCharValidator): SizeInt; -var +End; +Function StrCharsCount(Const S: string; Const Chars: TCharValidator): SizeInt; +Var I: SizeInt; -begin +Begin Result := 0; - for I := 1 to Length(S) do - if Chars(S[I]) then + For I := 1 To Length(S) Do + If Chars(S[I]) Then Inc(Result); -end; -function StrCharsCount(const S: string; const Chars: array of Char): SizeInt; -var +End; +Function StrCharsCount(Const S: string; Const Chars: array Of Char): SizeInt; +Var I: SizeInt; -begin +Begin Result := 0; - for I := 1 to Length(S) do - if ArrayContainsChar(Chars, S[I]) then + For I := 1 To Length(S) Do + If ArrayContainsChar(Chars, S[I]) Then Inc(Result); -end; -function StrStrCount(const S, SubS: string): SizeInt; -var +End; +Function StrStrCount(Const S, SubS: string): SizeInt; +Var I: SizeInt; -begin +Begin Result := 0; - if (Length(SubS) > Length(S)) or (Length(SubS) = 0) or (Length(S) = 0) then + If (Length(SubS) > Length(S)) or (Length(SubS) = 0) or (Length(S) = 0) Then Exit; - if Length(SubS) = 1 then - begin + If Length(SubS) = 1 Then + Begin Result := StrCharCount(S, SubS[1]); Exit; - end; + End; I := StrSearch(SubS, S, 1); - if I > 0 then + If I > 0 Then Inc(Result); - while (I > 0) and (Length(S) > I + Length(SubS)) do - begin + While (I > 0) and (Length(S) > I + Length(SubS)) Do + Begin I := StrSearch(SubS, S, I + 1); - if I > 0 then + If I > 0 Then Inc(Result); - end; -end; + End; +End; (* { 1} Test(StrCompareRange('', '', 1, 5), 0); { 2} Test(StrCompareRange('A', '', 1, 5), -1); @@ -1889,641 +1889,641 @@ function StrStrCount(const S, SubS: string): SizeInt; {19} Test(StrCompareRange('Aa', 'A', 1, 2), 0); {20} Test(StrCompareRange('Ba', 'A', 1, 2), 1); *) -function StrCompareRangeEx(const S1, S2: string; Index, Count: SizeInt; CaseSensitive: Boolean): SizeInt; -var +Function StrCompareRangeEx(Const S1, S2: string; Index, Count: SizeInt; CaseSensitive: Boolean): SizeInt; +Var Len1, Len2: SizeInt; I: SizeInt; C1, C2: Char; -begin - if Pointer(S1) = Pointer(S2) then - begin - if (Count <= 0) and (S1 <> '') then +Begin + If Pointer(S1) = Pointer(S2) Then + Begin + If (Count <= 0) and (S1 <> '') Then Result := -2 // no work - else + Else Result := 0; - end - else - if (S1 = '') or (S2 = '') then + End + Else + If (S1 = '') or (S2 = '') Then Result := -1 // null string - else - if Count <= 0 then + Else + If Count <= 0 Then Result := -2 // no work - else - begin + Else + Begin Len1 := Length(S1); Len2 := Length(S2); - if (Index - 1) + Count > Len1 then + If (Index - 1) + Count > Len1 Then Result := -2 - else - begin - if (Index - 1) + Count > Len2 then // strange behaviour, but the assembler code does it + Else + Begin + If (Index - 1) + Count > Len2 Then // strange behaviour, but the assembler code does it Count := Len2 - (Index - 1); - if CaseSensitive then - begin - for I := 0 to Count - 1 do - begin + If CaseSensitive Then + Begin + For I := 0 To Count - 1 Do + Begin C1 := S1[Index + I]; C2 := S2[Index + I]; - if C1 <> C2 then - begin + If C1 <> C2 Then + Begin Result := Ord(C1) - Ord(C2); Exit; - end; - end; - end - else - begin - for I := 0 to Count - 1 do - begin + End; + End; + End + Else + Begin + For I := 0 To Count - 1 Do + Begin C1 := S1[Index + I]; C2 := S2[Index + I]; - if C1 <> C2 then - begin + If C1 <> C2 Then + Begin C1 := CharLower(C1); C2 := CharLower(C2); - if C1 <> C2 then - begin + If C1 <> C2 Then + Begin Result := Ord(C1) - Ord(C2); Exit; - end; - end; - end; - end; + End; + End; + End; + End; Result := 0; - end; - end; -end; -function StrCompare(const S1, S2: string; CaseSensitive: Boolean): SizeInt; -var + End; + End; +End; +Function StrCompare(Const S1, S2: string; CaseSensitive: Boolean): SizeInt; +Var Len1, Len2: SizeInt; -begin - if Pointer(S1) = Pointer(S2) then +Begin + If Pointer(S1) = Pointer(S2) Then Result := 0 - else - begin + Else + Begin Len1 := Length(S1); Len2 := Length(S2); Result := Len1 - Len2; - if Result = 0 then + If Result = 0 Then Result := StrCompareRangeEx(S1, S2, 1, Len1, CaseSensitive); - end; -end; -function StrCompareRange(const S1, S2: string; Index, Count: SizeInt; CaseSensitive: Boolean): SizeInt; -begin + End; +End; +Function StrCompareRange(Const S1, S2: string; Index, Count: SizeInt; CaseSensitive: Boolean): SizeInt; +Begin Result := StrCompareRangeEx(S1, S2, Index, Count, CaseSensitive); -end; -procedure StrFillChar(var S; Count: SizeInt; C: Char); -begin - if Count > 0 then +End; +Procedure StrFillChar(Var S; Count: SizeInt; C: Char); +Begin + If Count > 0 Then FillChar(S, Count, C); -end; -function StrRepeatChar(C: Char; Count: SizeInt): string; -begin +End; +Function StrRepeatChar(C: Char; Count: SizeInt): string; +Begin SetLength(Result, Count); - if Count > 0 then + If Count > 0 Then StrFillChar(Result[1], Count, C); -end; -function StrFind(const Substr, S: string; const Index: SizeInt): SizeInt; -var +End; +Function StrFind(Const Substr, S: string; Const Index: SizeInt): SizeInt; +Var pos: SizeInt; -begin - if (SubStr <> '') and (S <> '') then - begin +Begin + If (SubStr <> '') and (S <> '') Then + Begin pos := StrIPos(Substr, Copy(S, Index, Length(S) - Index + 1)); - if pos = 0 then + If pos = 0 Then Result := 0 - else + Else Result := Index + Pos - 1; - end - else + End + Else Result := 0; -end; -function StrHasPrefix(const S: string; const Prefixes: array of string): Boolean; -begin +End; +Function StrHasPrefix(Const S: string; Const Prefixes: array Of string): Boolean; +Begin Result := StrPrefixIndex(S, Prefixes) > -1; -end; -function StrHasSuffix(const S: string; const Suffixes: array of string): Boolean; -begin +End; +Function StrHasSuffix(Const S: string; Const Suffixes: array Of string): Boolean; +Begin Result := StrSuffixIndex(S, Suffixes) > -1; -end; -function StrIndex(const S: string; const List: array of string; CaseSensitive: Boolean): SizeInt; -var +End; +Function StrIndex(Const S: string; Const List: array Of string; CaseSensitive: Boolean): SizeInt; +Var I: SizeInt; -begin +Begin Result := -1; - for I := Low(List) to High(List) do - begin - if StrCompare(S, List[I], CaseSensitive) = 0 then - begin + For I := Low(List) To High(List) Do + Begin + If StrCompare(S, List[I], CaseSensitive) = 0 Then + Begin Result := I; Break; - end; - end; -end; -function StrIHasPrefix(const S: string; const Prefixes: array of string): Boolean; -begin + End; + End; +End; +Function StrIHasPrefix(Const S: string; Const Prefixes: array Of string): Boolean; +Begin Result := StrIPrefixIndex(S, Prefixes) > -1; -end; -function StrIHasSuffix(const S: string; const Suffixes: array of string): Boolean; -begin +End; +Function StrIHasSuffix(Const S: string; Const Suffixes: array Of string): Boolean; +Begin Result := StrISuffixIndex(S, Suffixes) > -1; -end; -function StrILastPos(const SubStr, S: string): SizeInt; -begin +End; +Function StrILastPos(Const SubStr, S: string): SizeInt; +Begin Result := StrLastPos(StrUpper(SubStr), StrUpper(S)); -end; -function StrIPos(const SubStr, S: string): SizeInt; -begin +End; +Function StrIPos(Const SubStr, S: string): SizeInt; +Begin Result := Pos(StrUpper(SubStr), StrUpper(S)); -end; -function StrIPrefixIndex(const S: string; const Prefixes: array of string): SizeInt; -var +End; +Function StrIPrefixIndex(Const S: string; Const Prefixes: array Of string): SizeInt; +Var I: SizeInt; Test: string; -begin +Begin Result := -1; - for I := Low(Prefixes) to High(Prefixes) do - begin + For I := Low(Prefixes) To High(Prefixes) Do + Begin Test := StrLeft(S, Length(Prefixes[I])); - if CompareText(Test, Prefixes[I]) = 0 then - begin + If CompareText(Test, Prefixes[I]) = 0 Then + Begin Result := I; Break; - end; - end; -end; -function StrIsOneOf(const S: string; const List: array of string): Boolean; -begin + End; + End; +End; +Function StrIsOneOf(Const S: string; Const List: array Of string): Boolean; +Begin Result := StrIndex(S, List) > -1; -end; -function StrISuffixIndex(const S: string; const Suffixes: array of string): SizeInt; -var +End; +Function StrISuffixIndex(Const S: string; Const Suffixes: array Of string): SizeInt; +Var I: SizeInt; Test: string; -begin +Begin Result := -1; - for I := Low(Suffixes) to High(Suffixes) do - begin + For I := Low(Suffixes) To High(Suffixes) Do + Begin Test := StrRight(S, Length(Suffixes[I])); - if CompareText(Test, Suffixes[I]) = 0 then - begin + If CompareText(Test, Suffixes[I]) = 0 Then + Begin Result := I; Break; - end; - end; -end; -function StrLastPos(const SubStr, S: string): SizeInt; -var + End; + End; +End; +Function StrLastPos(Const SubStr, S: string): SizeInt; +Var Last, Current: PChar; -begin +Begin Result := 0; Last := nil; Current := PChar(S); - while (Current <> nil) and (Current^ <> #0) do - begin + While (Current <> nil) and (Current^ <> #0) Do + Begin Current := StrPos(PChar(Current), PChar(SubStr)); - if Current <> nil then - begin + If Current <> nil Then + Begin Last := Current; Inc(Current); - end; - end; - if Last <> nil then + End; + End; + If Last <> nil Then Result := Abs(PChar(S) - Last) + 1; -end; +End; // IMPORTANT NOTE: The StrMatch function does currently not work with the Asterix (*) // (*) acts like (?) -function StrMatch(const Substr, S: string; Index: SizeInt): SizeInt; -var +Function StrMatch(Const Substr, S: string; Index: SizeInt): SizeInt; +Var SI, SubI, SLen, SubLen: SizeInt; SubC: Char; -begin +Begin SLen := Length(S); SubLen := Length(Substr); Result := 0; - if (Index > SLen) or (SubLen = 0) then + If (Index > SLen) or (SubLen = 0) Then Exit; - while Index <= SLen do - begin + While Index <= SLen Do + Begin SubI := 1; SI := Index; - while (SI <= SLen) and (SubI <= SubLen) do - begin + While (SI <= SLen) and (SubI <= SubLen) Do + Begin SubC := Substr[SubI]; - if (SubC = '*') or (SubC = '?') or (SubC = S[SI]) then - begin + If (SubC = '*') or (SubC = '?') or (SubC = S[SI]) Then + Begin Inc(SI); Inc(SubI); - end - else + End + Else Break; - end; - if SubI > SubLen then - begin + End; + If SubI > SubLen Then + Begin Result := Index; Break; - end; + End; Inc(Index); - end; -end; + End; +End; // Derived from "Like" by Michael Winter -function StrMatches(const Substr, S: string; const Index: SizeInt): Boolean; -var +Function StrMatches(Const Substr, S: string; Const Index: SizeInt): Boolean; +Var StringPtr: PChar; PatternPtr: PChar; StringRes: PChar; PatternRes: PChar; -begin - if SubStr = '' then +Begin + If SubStr = '' Then raise EJclStringError.CreateRes(@RsBlankSearchString); Result := SubStr = '*'; - if Result or (S = '') then + If Result or (S = '') Then Exit; - if (Index <= 0) or (Index > Length(S)) then + If (Index <= 0) or (Index > Length(S)) Then raise EJclStringError.CreateRes(@RsArgumentOutOfRange); StringPtr := PChar(@S[Index]); PatternPtr := PChar(SubStr); StringRes := nil; PatternRes := nil; - repeat - repeat - case PatternPtr^ of + Repeat + Repeat + Case PatternPtr^ Of #0: - begin + Begin Result := StringPtr^ = #0; - if Result or (StringRes = nil) or (PatternRes = nil) then + If Result or (StringRes = nil) or (PatternRes = nil) Then Exit; StringPtr := StringRes; PatternPtr := PatternRes; Break; - end; + End; '*': - begin + Begin Inc(PatternPtr); PatternRes := PatternPtr; Break; - end; + End; '?': - begin - if StringPtr^ = #0 then + Begin + If StringPtr^ = #0 Then Exit; Inc(StringPtr); Inc(PatternPtr); - end; - else - begin - if StringPtr^ = #0 then + End; + Else + Begin + If StringPtr^ = #0 Then Exit; - if StringPtr^ <> PatternPtr^ then - begin - if (StringRes = nil) or (PatternRes = nil) then + If StringPtr^ <> PatternPtr^ Then + Begin + If (StringRes = nil) or (PatternRes = nil) Then Exit; StringPtr := StringRes; PatternPtr := PatternRes; Break; - end - else - begin + End + Else + Begin Inc(StringPtr); Inc(PatternPtr); - end; - end; - end; - until False; - repeat - case PatternPtr^ of + End; + End; + End; + Until False; + Repeat + Case PatternPtr^ Of #0: - begin + Begin Result := True; Exit; - end; + End; '*': - begin + Begin Inc(PatternPtr); PatternRes := PatternPtr; - end; + End; '?': - begin - if StringPtr^ = #0 then + Begin + If StringPtr^ = #0 Then Exit; Inc(StringPtr); Inc(PatternPtr); - end; - else - begin - repeat - if StringPtr^ = #0 then + End; + Else + Begin + Repeat + If StringPtr^ = #0 Then Exit; - if StringPtr^ = PatternPtr^ then + If StringPtr^ = PatternPtr^ Then Break; Inc(StringPtr); - until False; + Until False; Inc(StringPtr); StringRes := StringPtr; Inc(PatternPtr); Break; - end; - end; - until False; - until False; -end; -function StrNPos(const S, SubStr: string; N: SizeInt): SizeInt; -var + End; + End; + Until False; + Until False; +End; +Function StrNPos(Const S, SubStr: string; N: SizeInt): SizeInt; +Var I, P: SizeInt; -begin - if N < 1 then - begin +Begin + If N < 1 Then + Begin Result := 0; Exit; - end; + End; Result := StrSearch(SubStr, S, 1); I := 1; - while I < N do - begin + While I < N Do + Begin P := StrSearch(SubStr, S, Result + 1); - if P = 0 then - begin + If P = 0 Then + Begin Result := 0; Break; - end - else - begin + End + Else + Begin Result := P; Inc(I); - end; - end; -end; -function StrNIPos(const S, SubStr: string; N: SizeInt): SizeInt; -var + End; + End; +End; +Function StrNIPos(Const S, SubStr: string; N: SizeInt): SizeInt; +Var I, P: SizeInt; -begin - if N < 1 then - begin +Begin + If N < 1 Then + Begin Result := 0; Exit; - end; + End; Result := StrFind(SubStr, S, 1); I := 1; - while I < N do - begin + While I < N Do + Begin P := StrFind(SubStr, S, Result + 1); - if P = 0 then - begin + If P = 0 Then + Begin Result := 0; Break; - end - else - begin + End + Else + Begin Result := P; Inc(I); - end; - end; -end; -function StrPrefixIndex(const S: string; const Prefixes: array of string): SizeInt; -var + End; + End; +End; +Function StrPrefixIndex(Const S: string; Const Prefixes: array Of string): SizeInt; +Var I: SizeInt; Test: string; -begin +Begin Result := -1; - for I := Low(Prefixes) to High(Prefixes) do - begin + For I := Low(Prefixes) To High(Prefixes) Do + Begin Test := StrLeft(S, Length(Prefixes[I])); - if CompareStr(Test, Prefixes[I]) = 0 then - begin + If CompareStr(Test, Prefixes[I]) = 0 Then + Begin Result := I; Break; - end; - end; -end; -function StrSearch(const Substr, S: string; const Index: SizeInt): SizeInt; -var + End; + End; +End; +Function StrSearch(Const Substr, S: string; Const Index: SizeInt): SizeInt; +Var SP, SPI, SubP: PChar; SLen: SizeInt; -begin +Begin SLen := Length(S); - if Index <= SLen then - begin + If Index <= SLen Then + Begin SP := PChar(S); SubP := PChar(Substr); SPI := SP; Inc(SPI, Index); Dec(SPI); SPI := StrPos(SPI, SubP); - if SPI <> nil then + If SPI <> nil Then Result := SPI - SP + 1 - else + Else Result := 0; - end - else + End + Else Result := 0; -end; -function StrSuffixIndex(const S: string; const Suffixes: array of string): SizeInt; -var +End; +Function StrSuffixIndex(Const S: string; Const Suffixes: array Of string): SizeInt; +Var I: SizeInt; Test: string; -begin +Begin Result := -1; - for I := Low(Suffixes) to High(Suffixes) do - begin + For I := Low(Suffixes) To High(Suffixes) Do + Begin Test := StrRight(S, Length(Suffixes[I])); - if CompareStr(Test, Suffixes[I]) = 0 then - begin + If CompareStr(Test, Suffixes[I]) = 0 Then + Begin Result := I; Break; - end; - end; -end; + End; + End; +End; //=== String Extraction ====================================================== -function StrAfter(const SubStr, S: string): string; -var +Function StrAfter(Const SubStr, S: string): string; +Var P: SizeInt; -begin +Begin P := StrFind(SubStr, S, 1); // StrFind is case-insensitive pos - if P <= 0 then + If P <= 0 Then Result := '' // substr not found -> nothing after it - else + Else Result := StrRestOf(S, P + Length(SubStr)); -end; -function StrBefore(const SubStr, S: string): string; -var +End; +Function StrBefore(Const SubStr, S: string): string; +Var P: SizeInt; -begin +Begin P := StrFind(SubStr, S, 1); - if P <= 0 then + If P <= 0 Then Result := S - else + Else Result := StrLeft(S, P - 1); -end; -function StrSplit(const SubStr, S: string;var Left, Right : string): boolean; -var +End; +Function StrSplit(Const SubStr, S: string;Var Left, Right : string): boolean; +Var P: SizeInt; -begin +Begin P := StrFind(SubStr, S, 1); Result:= p > 0; - if Result then - begin + If Result Then + Begin Left := StrLeft(S, P - 1); Right := StrRestOf(S, P + Length(SubStr)); - end - else - begin + End + Else + Begin Left := ''; Right := ''; - end; -end; -function StrBetween(const S: string; const Start, Stop: Char): string; -var + End; +End; +Function StrBetween(Const S: string; Const Start, Stop: Char): string; +Var PosStart, PosEnd: SizeInt; L: SizeInt; -begin +Begin PosStart := Pos(Start, S); PosEnd := StrSearch(Stop, S, PosStart + 1); // PosEnd has to be after PosStart. - if (PosStart > 0) and (PosEnd > PosStart) then - begin + If (PosStart > 0) and (PosEnd > PosStart) Then + Begin L := PosEnd - PosStart; Result := Copy(S, PosStart + 1, L - 1); - end - else + End + Else Result := ''; -end; -function StrChopRight(const S: string; N: SizeInt): string; -begin +End; +Function StrChopRight(Const S: string; N: SizeInt): string; +Begin Result := Copy(S, 1, Length(S) - N); -end; -function StrLeft(const S: string; Count: SizeInt): string; -begin +End; +Function StrLeft(Const S: string; Count: SizeInt): string; +Begin Result := Copy(S, 1, Count); -end; -function StrMid(const S: string; Start, Count: SizeInt): string; -begin +End; +Function StrMid(Const S: string; Start, Count: SizeInt): string; +Begin Result := Copy(S, Start, Count); -end; -function StrRestOf(const S: string; N: SizeInt): string; -begin +End; +Function StrRestOf(Const S: string; N: SizeInt): string; +Begin Result := Copy(S, N, (Length(S) - N + 1)); -end; -function StrRight(const S: string; Count: SizeInt): string; -begin +End; +Function StrRight(Const S: string; Count: SizeInt): string; +Begin Result := Copy(S, Length(S) - Count + 1, Count); -end; +End; //=== Character (do we have it ;) ============================================ -function CharEqualNoCase(const C1, C2: Char): Boolean; -begin +Function CharEqualNoCase(Const C1, C2: Char): Boolean; +Begin //if they are not equal chars, may be same letter different case Result := (C1 = C2) or (CharIsAlpha(C1) and CharIsAlpha(C2) and (CharLower(C1) = CharLower(C2))); -end; +End; -function CharIsAlpha(const C: Char): Boolean; -begin +Function CharIsAlpha(Const C: Char): Boolean; +Begin {$IFDEF UNICODE_RTL_DATABASE} Result := TCharacter.IsLetter(C); {$ELSE ~UNICODE_RTL_DATABASE} Result := (StrCharTypes[C] and C1_ALPHA) <> 0; {$ENDIF ~UNICODE_RTL_DATABASE} -end; -function CharIsAlphaNum(const C: Char): Boolean; -begin +End; +Function CharIsAlphaNum(Const C: Char): Boolean; +Begin {$IFDEF UNICODE_RTL_DATABASE} Result := TCharacter.IsLetterOrDigit(C); {$ELSE ~UNICODE_RTL_DATABASE} Result := ((StrCharTypes[C] and C1_ALPHA) <> 0) or ((StrCharTypes[C] and C1_DIGIT) <> 0); {$ENDIF ~UNICODE_RTL_DATABASE} -end; -function CharIsBlank(const C: Char): Boolean; -begin +End; +Function CharIsBlank(Const C: Char): Boolean; +Begin {$IFDEF UNICODE_RTL_DATABASE} //http://blogs.msdn.com/b/michkap/archive/2007/06/11/3230072.aspx Result := (C = ' ') or (C = #$0009) or (C = #$00A0) or (C = #$3000); {$ELSE ~UNICODE_RTL_DATABASE} Result := ((StrCharTypes[C] and C1_BLANK) <> 0); {$ENDIF ~UNICODE_RTL_DATABASE} -end; -function CharIsControl(const C: Char): Boolean; -begin +End; +Function CharIsControl(Const C: Char): Boolean; +Begin {$IFDEF UNICODE_RTL_DATABASE} Result := TCharacter.IsControl(C); {$ELSE ~UNICODE_RTL_DATABASE} Result := (StrCharTypes[C] and C1_CNTRL) <> 0; {$ENDIF ~UNICODE_RTL_DATABASE} -end; -function CharIsDelete(const C: Char): Boolean; -begin +End; +Function CharIsDelete(Const C: Char): Boolean; +Begin Result := (C = #8); -end; -function CharIsDigit(const C: Char): Boolean; -begin +End; +Function CharIsDigit(Const C: Char): Boolean; +Begin {$IFDEF UNICODE_RTL_DATABASE} Result := TCharacter.IsDigit(C); {$ELSE ~UNICODE_RTL_DATABASE} Result := (StrCharTypes[C] and C1_DIGIT) <> 0; {$ENDIF ~UNICODE_RTL_DATABASE} -end; -function CharIsFracDigit(const C: Char): Boolean; -begin +End; +Function CharIsFracDigit(Const C: Char): Boolean; +Begin Result := (C = '.') or CharIsDigit(C); -end; -function CharIsHexDigit(const C: Char): Boolean; -begin - case C of +End; +Function CharIsHexDigit(Const C: Char): Boolean; +Begin + Case C Of 'A'..'F', 'a'..'f': Result := True; - else + Else Result := CharIsDigit(C); - end; -end; -function CharIsLower(const C: Char): Boolean; -begin + End; +End; +Function CharIsLower(Const C: Char): Boolean; +Begin {$IFDEF UNICODE_RTL_DATABASE} Result := TCharacter.IsLower(C); {$ELSE ~UNICODE_RTL_DATABASE} Result := (StrCharTypes[C] and C1_LOWER) <> 0; {$ENDIF ~UNICODE_RTL_DATABASE} -end; -function CharIsNumberChar(const C: Char): Boolean; -begin +End; +Function CharIsNumberChar(Const C: Char): Boolean; +Begin Result := CharIsDigit(C) or (C = '+') or (C = '-') or (C = RESTDWDecimalSeparator); -end; -function CharIsNumber(const C: Char): Boolean; -begin +End; +Function CharIsNumber(Const C: Char): Boolean; +Begin Result := CharIsDigit(C) or (C = RESTDWDecimalSeparator); -end; -function CharIsPrintable(const C: Char): Boolean; -begin +End; +Function CharIsPrintable(Const C: Char): Boolean; +Begin Result := not CharIsControl(C); -end; -function CharIsPunctuation(const C: Char): Boolean; -begin +End; +Function CharIsPunctuation(Const C: Char): Boolean; +Begin {$IFDEF UNICODE_RTL_DATABASE} Result := TCharacter.IsPunctuation(C); {$ELSE ~UNICODE_RTL_DATABASE} Result := ((StrCharTypes[C] and C1_PUNCT) <> 0); {$ENDIF ~UNICODE_RTL_DATABASE} -end; -function CharIsReturn(const C: Char): Boolean; -begin +End; +Function CharIsReturn(Const C: Char): Boolean; +Begin Result := (C = NativeLineFeed) or (C = NativeCarriageReturn); -end; -function CharIsSpace(const C: Char): Boolean; -begin +End; +Function CharIsSpace(Const C: Char): Boolean; +Begin {$IFDEF UNICODE_RTL_DATABASE} Result := TCharacter.IsWhiteSpace(C); {$ELSE ~UNICODE_RTL_DATABASE} Result := (StrCharTypes[C] and C1_SPACE) <> 0; {$ENDIF ~UNICODE_RTL_DATABASE} -end; -function CharIsUpper(const C: Char): Boolean; -begin +End; +Function CharIsUpper(Const C: Char): Boolean; +Begin {$IFDEF UNICODE_RTL_DATABASE} Result := TCharacter.IsUpper(C); {$ELSE ~UNICODE_RTL_DATABASE} Result := (StrCharTypes[C] and C1_UPPER) <> 0; {$ENDIF ~UNICODE_RTL_DATABASE} -end; -function CharIsValidIdentifierLetter(const C: Char): Boolean; -begin - case C of +End; +Function CharIsValidIdentifierLetter(Const C: Char): Boolean; +Begin + Case C Of {$IFDEF SUPPORTS_UNICODE} // from XML specifications #$00C0..#$00D6, #$00D8..#$00F6, #$00F8..#$02FF, #$0370..#$037D, @@ -2533,13 +2533,13 @@ function CharIsValidIdentifierLetter(const C: Char): Boolean; {$ENDIF SUPPORTS_UNICODE} '0'..'9', 'A'..'Z', 'a'..'z', '_': Result := True; - else + Else Result := False; - end; -end; -function CharIsWhiteSpace(const C: Char): Boolean; -begin - case C of + End; +End; +Function CharIsWhiteSpace(Const C: Char): Boolean; +Begin + Case C Of NativeTab, NativeLineFeed, NativeVerticalTab, @@ -2547,746 +2547,746 @@ function CharIsWhiteSpace(const C: Char): Boolean; NativeCarriageReturn, NativeSpace: Result := True; - else + Else Result := False; - end; -end; -function CharIsWildcard(const C: Char): Boolean; -begin - case C of + End; +End; +Function CharIsWildcard(Const C: Char): Boolean; +Begin + Case C Of '*', '?': Result := True; - else + Else Result := False; - end; -end; -function CharType(const C: Char): Word; -begin + End; +End; +Function CharType(Const C: Char): Word; +Begin {$IFDEF UNICODE_RTL_DATABASE} GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, @C, 1, Result); {$ELSE ~UNICODE_RTL_DATABASE} Result := StrCharTypes[C]; {$ENDIF ~UNICODE_RTL_DATABASE} -end; +End; //=== PCharVector ============================================================ -function StringsToPCharVector(var Dest: PCharVector; const Source: TStrings): PCharVector; -var +Function StringsToPCharVector(Var Dest: PCharVector; Const Source: TStrings): PCharVector; +Var I: SizeInt; S: string; - List: array of PChar; -begin + List: array Of PChar; +Begin Assert(Source <> nil); Dest := AllocMem((Source.Count + SizeOf(Char)) * SizeOf(PChar)); SetLength(List, Source.Count + SizeOf(Char)); - for I := 0 to Source.Count - 1 do - begin + For I := 0 To Source.Count - 1 Do + Begin S := Source[I]; List[I] := StrAlloc(Length(S) + SizeOf(Char)); StrPCopy(List[I], S); - end; + End; List[Source.Count] := nil; Move(List[0], Dest^, (Source.Count + 1) * SizeOf(PChar)); Result := Dest; -end; -function PCharVectorCount(Source: PCharVector): SizeInt; -begin +End; +Function PCharVectorCount(Source: PCharVector): SizeInt; +Begin Result := 0; - if Source <> nil then - begin - while Source^ <> nil do - begin + If Source <> nil Then + Begin + While Source^ <> nil Do + Begin Inc(Source); Inc(Result); - end; - end; -end; -procedure PCharVectorToStrings(const Dest: TStrings; Source: PCharVector); -var + End; + End; +End; +Procedure PCharVectorToStrings(Const Dest: TStrings; Source: PCharVector); +Var I, Count: SizeInt; - List: array of PChar; -begin + List: array Of PChar; +Begin Assert(Dest <> nil); - if Source <> nil then - begin + If Source <> nil Then + Begin Count := PCharVectorCount(Source); SetLength(List, Count); Move(Source^, List[0], Count * SizeOf(PChar)); Dest.BeginUpdate; - try + Try Dest.Clear; - for I := 0 to Count - 1 do + For I := 0 To Count - 1 Do Dest.Add(List[I]); - finally + Finally Dest.EndUpdate; - end; - end; -end; -procedure FreePCharVector(var Dest: PCharVector); -var + End; + End; +End; +Procedure FreePCharVector(Var Dest: PCharVector); +Var I, Count: SizeInt; - List: array of PChar; -begin - if Dest <> nil then - begin + List: array Of PChar; +Begin + If Dest <> nil Then + Begin Count := PCharVectorCount(Dest); SetLength(List, Count); Move(Dest^, List[0], Count * SizeOf(PChar)); - for I := 0 to Count - 1 do + For I := 0 To Count - 1 Do StrDispose(List[I]); FreeMem(Dest, (Count + 1) * SizeOf(PChar)); Dest := nil; - end; -end; + End; +End; //=== Character Transformation Routines ====================================== -function CharHex(const C: Char): Byte; -begin - case C of +Function CharHex(Const C: Char): Byte; +Begin + Case C Of '0'..'9': Result := Ord(C) - Ord('0'); 'a'..'f': Result := Ord(C) - Ord('a') + 10; 'A'..'F': Result := Ord(C) - Ord('A') + 10; - else + Else Result := $FF; - end; -end; -function CharLower(const C: Char): Char; -begin + End; +End; +Function CharLower(Const C: Char): Char; +Begin {$IFDEF UNICODE_RTL_DATABASE} Result := TCharacter.ToLower(C); {$ELSE ~UNICODE_RTL_DATABASE} Result := StrCaseMap[Ord(C) + StrLoOffset]; {$ENDIF ~UNICODE_RTL_DATABASE} -end; -function CharToggleCase(const C: Char): Char; -begin +End; +Function CharToggleCase(Const C: Char): Char; +Begin {$IFDEF UNICODE_RTL_DATABASE} - if CharIsLower(C) then + If CharIsLower(C) Then Result := CharUpper(C) - else if CharIsUpper(C) then + Else If CharIsUpper(C) Then Result := CharLower(C) - else + Else Result := C; {$ELSE ~UNICODE_RTL_DATABASE} Result := StrCaseMap[Ord(C) + StrReOffset]; {$ENDIF ~UNICODE_RTL_DATABASE} -end; -function CharUpper(const C: Char): Char; -begin +End; +Function CharUpper(Const C: Char): Char; +Begin {$IFDEF UNICODE_RTL_DATABASE} Result := TCharacter.ToUpper(C); {$ELSE ~UNICODE_RTL_DATABASE} Result := StrCaseMap[Ord(C) + StrUpOffset]; {$ENDIF ~UNICODE_RTL_DATABASE} -end; +End; //=== Character Search and Replace =========================================== -function CharLastPos(const S: string; const C: Char; const Index: SizeInt): SizeInt; -begin - if (Index > 0) and (Index <= Length(S)) then - begin - for Result := Length(S) downto Index do - if S[Result] = C then +Function CharLastPos(Const S: string; Const C: Char; Const Index: SizeInt): SizeInt; +Begin + If (Index > 0) and (Index <= Length(S)) Then + Begin + For Result := Length(S) Downto Index Do + If S[Result] = C Then Exit; - end; + End; Result := 0; -end; -function CharPos(const S: string; const C: Char; const Index: SizeInt): SizeInt; -begin - if (Index > 0) and (Index <= Length(S)) then - begin - for Result := Index to Length(S) do - if S[Result] = C then +End; +Function CharPos(Const S: string; Const C: Char; Const Index: SizeInt): SizeInt; +Begin + If (Index > 0) and (Index <= Length(S)) Then + Begin + For Result := Index To Length(S) Do + If S[Result] = C Then Exit; - end; + End; Result := 0; -end; -function CharIPos(const S: string; C: Char; const Index: SizeInt): SizeInt; -begin - if (Index > 0) and (Index <= Length(S)) then - begin +End; +Function CharIPos(Const S: string; C: Char; Const Index: SizeInt): SizeInt; +Begin + If (Index > 0) and (Index <= Length(S)) Then + Begin C := CharUpper(C); - for Result := Index to Length(S) do - if CharUpper(S[Result]) = C then + For Result := Index To Length(S) Do + If CharUpper(S[Result]) = C Then Exit; - end; + End; Result := 0; -end; -function CharReplace(var S: string; const Search, Replace: Char): SizeInt; -var +End; +Function CharReplace(Var S: string; Const Search, Replace: Char): SizeInt; +Var P: PChar; Index, Len: SizeInt; -begin +Begin Result := 0; - if Search <> Replace then - begin + If Search <> Replace Then + Begin UniqueString(S); P := PChar(S); Len := Length(S); - for Index := 0 to Len - 1 do - begin - if P^ = Search then - begin + For Index := 0 To Len - 1 Do + Begin + If P^ = Search Then + Begin P^ := Replace; Inc(Result); - end; + End; Inc(P); - end; - end; -end; + End; + End; +End; //=== MultiSz ================================================================ -function StringsToMultiSz(var Dest: PMultiSz; const Source: TStrings): PMultiSz; -var +Function StringsToMultiSz(Var Dest: PMultiSz; Const Source: TStrings): PMultiSz; +Var I, TotalLength: SizeInt; P: PMultiSz; -begin +Begin Assert(Source <> nil); TotalLength := 1; - for I := 0 to Source.Count - 1 do - if Source[I] = '' then + For I := 0 To Source.Count - 1 Do + If Source[I] = '' Then raise EJclStringError.CreateRes(@RsInvalidEmptyStringItem) - else + Else Inc(TotalLength, StrLen(PChar(Source[I])) + 1); AllocateMultiSz(Dest, TotalLength); P := Dest; - for I := 0 to Source.Count - 1 do - begin + For I := 0 To Source.Count - 1 Do + Begin P := StrECopy(P, PChar(Source[I])); Inc(P); - end; + End; P^ := #0; Result := Dest; -end; -procedure MultiSzToStrings(const Dest: TStrings; const Source: PMultiSz); -var +End; +Procedure MultiSzToStrings(Const Dest: TStrings; Const Source: PMultiSz); +Var P: PMultiSz; -begin +Begin Assert(Dest <> nil); Dest.BeginUpdate; - try + Try Dest.Clear; - if Source <> nil then - begin + If Source <> nil Then + Begin P := Source; - while P^ <> #0 do - begin + While P^ <> #0 Do + Begin Dest.Add(P); P := StrEnd(P); Inc(P); - end; - end; - finally + End; + End; + Finally Dest.EndUpdate; - end; -end; -function MultiSzLength(const Source: PMultiSz): SizeInt; -var + End; +End; +Function MultiSzLength(Const Source: PMultiSz): SizeInt; +Var P: PMultiSz; -begin +Begin Result := 0; - if Source <> nil then - begin + If Source <> nil Then + Begin P := Source; - repeat + Repeat Inc(Result, StrLen(P) + 1); P := StrEnd(P); Inc(P); - until P^ = #0; + Until P^ = #0; Inc(Result); - end; -end; -procedure AllocateMultiSz(var Dest: PMultiSz; Len: SizeInt); -begin - if Len > 0 then + End; +End; +Procedure AllocateMultiSz(Var Dest: PMultiSz; Len: SizeInt); +Begin + If Len > 0 Then GetMem(Dest, Len * SizeOf(Char)) - else + Else Dest := nil; -end; -procedure FreeMultiSz(var Dest: PMultiSz); -begin - if Dest <> nil then +End; +Procedure FreeMultiSz(Var Dest: PMultiSz); +Begin + If Dest <> nil Then FreeMem(Dest); Dest := nil; -end; -function MultiSzDup(const Source: PMultiSz): PMultiSz; -var +End; +Function MultiSzDup(Const Source: PMultiSz): PMultiSz; +Var Len: SizeInt; -begin - if Source <> nil then - begin +Begin + If Source <> nil Then + Begin Len := MultiSzLength(Source); Result := nil; AllocateMultiSz(Result, Len); Move(Source^, Result^, Len * SizeOf(Char)); - end - else + End + Else Result := nil; -end; -procedure AllocateAnsiMultiSz(var Dest: PAnsiMultiSz; Len: SizeInt); -begin +End; +Procedure AllocateAnsiMultiSz(Var Dest: PAnsiMultiSz; Len: SizeInt); +Begin uRESTDWMemAnsiStrings.AllocateMultiSz(Dest, Len); -end; -procedure FreeAnsiMultiSz(var Dest: PAnsiMultiSz); -begin +End; +Procedure FreeAnsiMultiSz(Var Dest: PAnsiMultiSz); +Begin uRESTDWMemAnsiStrings.FreeMultiSz(Dest); -end; -procedure AllocateWideMultiSz(var Dest: PWideMultiSz; Len: SizeInt); -begin +End; +Procedure AllocateWideMultiSz(Var Dest: PWideMultiSz; Len: SizeInt); +Begin uRESTDWMemWideStrings.AllocateMultiSz(Dest, Len); -end; -procedure FreeWideMultiSz(var Dest: PWideMultiSz); -begin +End; +Procedure FreeWideMultiSz(Var Dest: PWideMultiSz); +Begin uRESTDWMemWideStrings.FreeMultiSz(Dest); -end; +End; //=== TStrings Manipulation ================================================== -procedure StrToStrings(S, Sep: string; const List: TStrings; const AllowEmptyString: Boolean = True); -var +Procedure StrToStrings(S, Sep: string; Const List: TStrings; Const AllowEmptyString: Boolean = True); +Var I, L: SizeInt; Left: string; -begin +Begin Assert(List <> nil); List.BeginUpdate; - try + Try List.Clear; L := Length(Sep); I := Pos(Sep, S); - while I > 0 do - begin + While I > 0 Do + Begin Left := StrLeft(S, I - 1); - if (Left <> '') or AllowEmptyString then + If (Left <> '') or AllowEmptyString Then List.Add(Left); Delete(S, 1, I + L - 1); I := Pos(Sep, S); - end; - if (S <> '') or AllowEmptyString then + End; + If (S <> '') or AllowEmptyString Then List.Add(S); // Ignore empty strings at the end (only if AllowEmptyString = False). - finally + Finally List.EndUpdate; - end; -end; -procedure StrIToStrings(S, Sep: string; const List: TStrings; const AllowEmptyString: Boolean = True); -var + End; +End; +Procedure StrIToStrings(S, Sep: string; Const List: TStrings; Const AllowEmptyString: Boolean = True); +Var I, L: SizeInt; LowerCaseStr: string; Left: string; -begin +Begin Assert(List <> nil); LowerCaseStr := StrLower(S); Sep := StrLower(Sep); L := Length(Sep); I := Pos(Sep, LowerCaseStr); List.BeginUpdate; - try + Try List.Clear; - while I > 0 do - begin + While I > 0 Do + Begin Left := StrLeft(S, I - 1); - if (Left <> '') or AllowEmptyString then + If (Left <> '') or AllowEmptyString Then List.Add(Left); Delete(S, 1, I + L - 1); Delete(LowerCaseStr, 1, I + L - 1); I := Pos(Sep, LowerCaseStr); - end; - if (S <> '') or AllowEmptyString then + End; + If (S <> '') or AllowEmptyString Then List.Add(S); // Ignore empty strings at the end (only if AllowEmptyString = False). - finally + Finally List.EndUpdate; - end; -end; -function StringsToStr(const List: TStrings; const Sep: string; const AllowEmptyString: Boolean = True): string; -var + End; +End; +Function StringsToStr(Const List: TStrings; Const Sep: string; Const AllowEmptyString: Boolean = True): string; +Var I, L: SizeInt; -begin +Begin Result := ''; - for I := 0 to List.Count - 1 do - begin - if (List[I] <> '') or AllowEmptyString then - begin + For I := 0 To List.Count - 1 Do + Begin + If (List[I] <> '') or AllowEmptyString Then + Begin // don't combine these into one addition, somehow it hurts performance Result := Result + List[I]; Result := Result + Sep; - end; - end; + End; + End; // remove terminating separator - if List.Count > 0 then - begin + If List.Count > 0 Then + Begin L := Length(Sep); Delete(Result, Length(Result) - L + 1, L); - end; -end; -function StringsToStr(const List: TStrings; const Sep: string; const NumberOfItems: SizeInt; const AllowEmptyString: + End; +End; +Function StringsToStr(Const List: TStrings; Const Sep: string; Const NumberOfItems: SizeInt; Const AllowEmptyString: Boolean = True): string; -var +Var I, L, N: SizeInt; -begin +Begin Result := ''; - if List.Count > NumberOfItems then + If List.Count > NumberOfItems Then N := NumberOfItems - else + Else N := List.Count; - for I := 0 to N - 1 do - begin - if (List[I] <> '') or AllowEmptyString then - begin + For I := 0 To N - 1 Do + Begin + If (List[I] <> '') or AllowEmptyString Then + Begin // don't combine these into one addition, somehow it hurts performance Result := Result + List[I]; Result := Result + Sep; - end; - end; + End; + End; // remove terminating separator - if N > 0 then - begin + If N > 0 Then + Begin L := Length(Sep); Delete(Result, Length(Result) - L + 1, L); - end; -end; -procedure TrimStrings(const List: TStrings; DeleteIfEmpty: Boolean); -var + End; +End; +Procedure TrimStrings(Const List: TStrings; DeleteIfEmpty: Boolean); +Var I: SizeInt; -begin +Begin Assert(List <> nil); List.BeginUpdate; - try - for I := List.Count - 1 downto 0 do - begin + Try + For I := List.Count - 1 Downto 0 Do + Begin List[I] := Trim(List[I]); - if (List[I] = '') and DeleteIfEmpty then + If (List[I] = '') and DeleteIfEmpty Then List.Delete(I); - end; - finally + End; + Finally List.EndUpdate; - end; -end; -procedure TrimStringsRight(const List: TStrings; DeleteIfEmpty: Boolean); -var + End; +End; +Procedure TrimStringsRight(Const List: TStrings; DeleteIfEmpty: Boolean); +Var I: SizeInt; -begin +Begin Assert(List <> nil); List.BeginUpdate; - try - for I := List.Count - 1 downto 0 do - begin + Try + For I := List.Count - 1 Downto 0 Do + Begin List[I] := TrimRight(List[I]); - if (List[I] = '') and DeleteIfEmpty then + If (List[I] = '') and DeleteIfEmpty Then List.Delete(I); - end; - finally + End; + Finally List.EndUpdate; - end; -end; -procedure TrimStringsLeft(const List: TStrings; DeleteIfEmpty: Boolean); -var + End; +End; +Procedure TrimStringsLeft(Const List: TStrings; DeleteIfEmpty: Boolean); +Var I: SizeInt; -begin +Begin Assert(List <> nil); List.BeginUpdate; - try - for I := List.Count - 1 downto 0 do - begin + Try + For I := List.Count - 1 Downto 0 Do + Begin List[I] := TrimLeft(List[I]); - if (List[I] = '') and DeleteIfEmpty then + If (List[I] = '') and DeleteIfEmpty Then List.Delete(I); - end; - finally + End; + Finally List.EndUpdate; - end; -end; -function AddStringToStrings(const S: string; Strings: TStrings; const Unique: Boolean): Boolean; -begin + End; +End; +Function AddStringToStrings(Const S: string; Strings: TStrings; Const Unique: Boolean): Boolean; +Begin Assert(Strings <> nil); Result := Unique and (Strings.IndexOf(S) <> -1); - if not Result then + If not Result Then Result := Strings.Add(S) > -1; -end; +End; //=== Miscellaneous ========================================================== -function FileToString(const FileName: string): {$IFDEF COMPILER12_UP}RawByteString{$ELSE}DWString{$ENDIF}; -var +Function FileToString(Const FileName: string): {$IFDEF COMPILER12_UP}RawByteString{$ELSE}DWString{$ENDIF}; +Var fs: TFileStream; Len: SizeInt; -begin +Begin fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); - try + Try Len := fs.Size; SetLength(Result, Len); - if Len > 0 then + If Len > 0 Then fs.ReadBuffer(Result[1], Len); - finally + Finally fs.Free; - end; -end; -procedure StringToFile(const FileName: string; const Contents: {$IFDEF COMPILER12_UP}RawByteString{$ELSE}DWString{$ENDIF}; + End; +End; +Procedure StringToFile(Const FileName: string; Const Contents: {$IFDEF COMPILER12_UP}RawByteString{$ELSE}DWString{$ENDIF}; Append: Boolean); -var +Var FS: TFileStream; Len: SizeInt; -begin - if Append and FileExists(filename) then +Begin + If Append and FileExists(filename) Then FS := TFileStream.Create(FileName, fmOpenReadWrite or fmShareDenyWrite) - else + Else FS := TFileStream.Create(FileName, fmCreate); - try - if Append then + Try + If Append Then FS.Seek(0, soEnd); // faster than .Position := .Size Len := Length(Contents); - if Len > 0 then + If Len > 0 Then FS.WriteBuffer(Contents[1], Len); - finally + Finally FS.Free; - end; -end; -function StrToken(var S: string; Separator: Char): string; -var + End; +End; +Function StrToken(Var S: string; Separator: Char): string; +Var I: SizeInt; -begin +Begin I := Pos(Separator, S); - if I <> 0 then - begin + If I <> 0 Then + Begin Result := Copy(S, 1, I - 1); Delete(S, 1, I); - end - else - begin + End + Else + Begin Result := S; S := ''; - end; -end; -procedure StrTokens(const S: string; const List: TStrings); -var + End; +End; +Procedure StrTokens(Const S: string; Const List: TStrings); +Var Start: PChar; Token: string; Done: Boolean; -begin +Begin Assert(List <> nil); - if List = nil then + If List = nil Then Exit; List.BeginUpdate; - try + Try List.Clear; Start := Pointer(S); - repeat + Repeat Done := StrWord(Start, Token); - if Token <> '' then + If Token <> '' Then List.Add(Token); - until Done; - finally + Until Done; + Finally List.EndUpdate; - end; -end; -function StrWord(const S: string; var Index: SizeInt; out Word: string): Boolean; -var + End; +End; +Function StrWord(Const S: string; Var Index: SizeInt; out Word: string): Boolean; +Var Start: SizeInt; C: Char; -begin +Begin Word := ''; - if (S = '') then - begin + If (S = '') Then + Begin Result := True; Exit; - end; + End; Start := Index; Result := False; - while True do - begin + While True Do + Begin C := S[Index]; - case C of + Case C Of #0: - begin - if Start <> 0 then + Begin + If Start <> 0 Then Word := Copy(S, Start, Index - Start); Result := True; Exit; - end; + End; NativeSpace, NativeLineFeed, NativeCarriageReturn: - begin - if Start <> 0 then - begin + Begin + If Start <> 0 Then + Begin Word := Copy(S, Start, Index - Start); Exit; - end - else - begin - while CharIsWhiteSpace(C) do - begin + End + Else + Begin + While CharIsWhiteSpace(C) Do + Begin Inc(Index); C := S[Index]; - end; - end; - end; - else - if Start = 0 then + End; + End; + End; + Else + If Start = 0 Then Start := Index; Inc(Index); - end; - end; -end; -function StrWord(var S: PChar; out Word: string): Boolean; -var + End; + End; +End; +Function StrWord(Var S: PChar; out Word: string): Boolean; +Var Start: PChar; -begin +Begin Word := ''; - if S = nil then - begin + If S = nil Then + Begin Result := True; Exit; - end; + End; Start := nil; Result := False; - while True do - begin - case S^ of + While True Do + Begin + Case S^ Of #0: - begin - if Start <> nil then + Begin + If Start <> nil Then SetString(Word, Start, S - Start); Result := True; Exit; - end; + End; NativeSpace, NativeLineFeed, NativeCarriageReturn: - begin - if Start <> nil then - begin + Begin + If Start <> nil Then + Begin SetString(Word, Start, S - Start); Exit; - end - else - while CharIsWhiteSpace(S^) do + End + Else + While CharIsWhiteSpace(S^) Do Inc(S); - end; - else - if Start = nil then + End; + Else + If Start = nil Then Start := S; Inc(S); - end; - end; -end; -function StrIdent(const S: string; var Index: SizeInt; out Ident: string): Boolean; -var + End; + End; +End; +Function StrIdent(Const S: string; Var Index: SizeInt; out Ident: string): Boolean; +Var Start: SizeInt; C: Char; -begin +Begin Ident := ''; - if (S = '') then - begin + If (S = '') Then + Begin Result := True; Exit; - end; + End; Start := Index; Result := False; - while True do - begin + While True Do + Begin C := S[Index]; - if CharIsValidIdentifierLetter(C) then - begin - if Start = 0 then + If CharIsValidIdentifierLetter(C) Then + Begin + If Start = 0 Then Start := Index; - end - else - if C = #0 then - begin - if Start <> 0 then + End + Else + If C = #0 Then + Begin + If Start <> 0 Then Ident := Copy(S, Start, Index - Start); Result := True; Exit; - end - else - begin - if Start <> 0 then - begin + End + Else + Begin + If Start <> 0 Then + Begin Ident := Copy(S, Start, Index - Start); Exit; - end; - end; + End; + End; Inc(Index); - end; -end; -function StrIdent(var S: PChar; out Ident: string): Boolean; -var + End; +End; +Function StrIdent(Var S: PChar; out Ident: string): Boolean; +Var Start: PChar; C: Char; -begin +Begin Ident := ''; - if S = nil then - begin + If S = nil Then + Begin Result := True; Exit; - end; + End; Start := nil; Result := False; - while True do - begin + While True Do + Begin C := S^; - if CharIsValidIdentifierLetter(C) then - begin - if Start = nil then + If CharIsValidIdentifierLetter(C) Then + Begin + If Start = nil Then Start := S; - end - else - if C = #0 then - begin - if Start <> nil then + End + Else + If C = #0 Then + Begin + If Start <> nil Then SetString(Ident, Start, S - Start); Result := True; Exit; - end - else - begin - if Start <> nil then - begin + End + Else + Begin + If Start <> nil Then + Begin SetString(Ident, Start, S - Start); Exit; - end - end; + End + End; Inc(S); - end; -end; -procedure StrTokenToStrings(S: string; Separator: Char; const List: TStrings); -var + End; +End; +Procedure StrTokenToStrings(S: string; Separator: Char; Const List: TStrings); +Var Token: string; -begin +Begin Assert(List <> nil); - if List = nil then + If List = nil Then Exit; List.BeginUpdate; - try + Try List.Clear; - while S <> '' do - begin + While S <> '' Do + Begin Token := StrToken(S, Separator); List.Add(Token); - end; - finally + End; + Finally List.EndUpdate; - end; -end; -function StrToFloatSafe(const S: string): Float; -var + End; +End; +Function StrToFloatSafe(Const S: string): Float; +Var Temp: string; I, J, K: SizeInt; SwapSeparators, IsNegative: Boolean; DecSep, ThouSep, C: Char; -begin +Begin DecSep := {$IFDEF RTL220_UP}FormatSettings.{$ENDIF}DecimalSeparator; ThouSep := {$IFDEF RTL220_UP}FormatSettings.{$ENDIF}ThousandSeparator; Temp := S; SwapSeparators := False; IsNegative := False; J := 0; - for I := 1 to Length(Temp) do - begin + For I := 1 To Length(Temp) Do + Begin C := Temp[I]; - if C = '-' then + If C = '-' Then IsNegative := not IsNegative - else - if (C <> ' ') and (C <> '(') and (C <> '+') then - begin + Else + If (C <> ' ') and (C <> '(') and (C <> '+') Then + Begin // if it appears prior to any digit, it has to be a decimal separator SwapSeparators := Temp[I] = ThouSep; J := I; Break; - end; - end; - if not SwapSeparators then - begin + End; + End; + If not SwapSeparators Then + Begin K := CharPos(Temp, DecSep); SwapSeparators := // if it appears prior to any digit, it has to be a decimal separator @@ -3295,105 +3295,105 @@ function StrToFloatSafe(const S: string): Float; ((StrCharCount(Temp, DecSep) > 1) or // we assume (consistent with Windows Platform SDK documentation), // that thousand separators appear only to the left of the decimal - (K < CharPos(Temp, ThouSep))); - end; - if SwapSeparators then - begin + (K < CharPos(Temp, ThouSep))); + End; + If SwapSeparators Then + Begin // assume a numerical string from a different locale, // where DecimalSeparator and ThousandSeparator are exchanged - for I := 1 to Length(Temp) do - if Temp[I] = DecSep then + For I := 1 To Length(Temp) Do + If Temp[I] = DecSep Then Temp[I] := ThouSep - else - if Temp[I] = ThouSep then + Else + If Temp[I] = ThouSep Then Temp[I] := DecSep; - end; + End; Temp := StrKeepChars(Temp, CharIsNumber); - if Length(Temp) > 0 then - begin - if Temp[1] = DecSep then + If Length(Temp) > 0 Then + Begin + If Temp[1] = DecSep Then Temp := '0' + Temp; - if Temp[Length(Temp)] = DecSep then + If Temp[Length(Temp)] = DecSep Then Temp := Temp + '0'; Result := StrToFloat(Temp); - if IsNegative then + If IsNegative Then Result := -Result; - end - else + End + Else Result := 0.0; -end; -function StrToIntSafe(const S: string): Integer; -begin +End; +Function StrToIntSafe(Const S: string): Integer; +Begin Result := Trunc(StrToFloatSafe(S)); -end; -procedure StrNormIndex(const StrLen: SizeInt; var Index: SizeInt; var Count: SizeInt); overload; -begin +End; +Procedure StrNormIndex(Const StrLen: SizeInt; Var Index: SizeInt; Var Count: SizeInt); overload; +Begin Index := Max(1, Min(Index, StrLen + 1)); Count := Max(0, Min(Count, StrLen + 1 - Index)); -end; -function ArrayOf(List: TStrings): TDynStringArray; -var +End; +Function ArrayOf(List: TStrings): TDynStringArray; +Var I: SizeInt; -begin - if List <> nil then - begin +Begin + If List <> nil Then + Begin SetLength(Result, List.Count); - for I := 0 to List.Count - 1 do + For I := 0 To List.Count - 1 Do Result[I] := List[I]; - end - else + End + Else Result := nil; -end; -const - BoolToStr: array [Boolean] of string = ('false', 'true'); -type - TInterfacedObjectAccess = class(TInterfacedObject); -procedure MoveChar(const Source; var Dest; Count: SizeInt); -begin - if Count > 0 then +End; +Const + BoolToStr: array [Boolean] Of string = ('false', 'true'); +Type + TInterfacedObjectAccess = Class(TInterfacedObject); +Procedure MoveChar(Const Source; Var Dest; Count: SizeInt); +Begin + If Count > 0 Then Move(Source, Dest, Count * SizeOf(Char)); -end; -function DotNetFormat(const Fmt: string; const Arg0: Variant): string; -begin +End; +Function DotNetFormat(Const Fmt: string; Const Arg0: Variant): string; +Begin Result := DotNetFormat(Fmt, [Arg0]); -end; -function DotNetFormat(const Fmt: string; const Arg0, Arg1: Variant): string; -begin +End; +Function DotNetFormat(Const Fmt: string; Const Arg0, Arg1: Variant): string; +Begin Result := DotNetFormat(Fmt, [Arg0, Arg1]); -end; -function DotNetFormat(const Fmt: string; const Arg0, Arg1, Arg2: Variant): string; -begin +End; +Function DotNetFormat(Const Fmt: string; Const Arg0, Arg1, Arg2: Variant): string; +Begin Result := DotNetFormat(Fmt, [Arg0, Arg1, Arg2]); -end; -function DotNetFormat(const Fmt: string; const Args: array of const): string; -var +End; +Function DotNetFormat(Const Fmt: string; Const Args: array Of Const): string; +Var F, P: PChar; Len, Capacity, Count: SizeInt; Index: SizeInt; ErrorCode: Integer; S: string; - procedure Grow(Count: SizeInt); - begin - if Len + Count > Capacity then - begin + Procedure Grow(Count: SizeInt); + Begin + If Len + Count > Capacity Then + Begin Capacity := Capacity * 5 div 3 + Count; SetLength(Result, Capacity); - end; - end; - function InheritsFrom(AClass: TClass; const ClassName: string): Boolean; - begin + End; + End; + Function InheritsFrom(AClass: TClass; Const ClassName: string): Boolean; + Begin Result := True; - while AClass <> nil do - begin - if CompareText(AClass.ClassName, ClassName) = 0 then + While AClass <> nil Do + Begin + If CompareText(AClass.ClassName, ClassName) = 0 Then Exit; AClass := AClass.ClassParent; - end; + End; Result := False; - end; - function GetStringOf(const V: TVarData; Index: SizeInt): string; overload; - begin - case V.VType of + End; + Function GetStringOf(Const V: TVarData; Index: SizeInt): string; overload; + Begin + Case V.VType Of varEmpty, varNull: raise ArgumentNullException.CreateRes(@RsArgumentIsNull); varSmallInt: @@ -3434,21 +3434,21 @@ function DotNetFormat(const Fmt: string; const Args: array of const): string; varUnknown, varAny, varByRef:} - else + Else raise ArgumentNullException.CreateResFmt(@RsDotNetFormatArgumentNotSupported, [Index]); - end; - end; - function GetStringOf(Index: SizeInt): string; overload; - var + End; + End; + Function GetStringOf(Index: SizeInt): string; overload; + Var V: TVarRec; Intf: IToString; - begin + Begin V := Args[Index]; - if (V.VInteger = 0) and + If (V.VInteger = 0) and (V.VType in [vtExtended, vtString, vtObject, vtClass, vtCurrency, - vtInterface, vtInt64]) then + vtInterface, vtInt64]) Then raise ArgumentNullException.CreateResFmt(@RsArgumentIsNull, [Index]); - case V.VType of + Case V.VType Of vtInteger: Result := IntToStr(V.VInteger); vtBoolean: @@ -3479,9 +3479,9 @@ function DotNetFormat(const Fmt: string; const Args: array of const): string; vtVariant: Result := GetStringOf(TVarData(V.VVariant^), Index); vtInterface: - if IInterface(V.VInterface).QueryInterface(IToString, Intf) = 0 then + If IInterface(V.VInterface).QueryInterface(IToString, Intf) = 0 Then Result := IToString(Intf).ToString - else + Else raise ArgumentNullException.CreateResFmt(@RsDotNetFormatArgumentNotSupported, [Index]); vtWideString: Result := DWWideString(V.VWideString); @@ -3491,867 +3491,867 @@ function DotNetFormat(const Fmt: string; const Args: array of const): string; vtUnicodeString: Result := UnicodeString(V.VUnicodeString); {$ENDIF SUPPORTS_UNICODE_STRING} - else + Else raise ArgumentNullException.CreateResFmt(@RsDotNetFormatArgumentNotSupported, [Index]); - end; - end; -begin - if Length(Args) = 0 then - begin + End; + End; +Begin + If Length(Args) = 0 Then + Begin Result := Fmt; Exit; - end; + End; Len := 0; Capacity := Length(Fmt); SetLength(Result, Capacity); - if Capacity = 0 then + If Capacity = 0 Then raise ArgumentNullException.CreateRes(@RsDotNetFormatNullFormat); P := Pointer(Fmt); F := P; - while True do - begin - if (P[0] = #0) or (P[0] = '{') then - begin + While True Do + Begin + If (P[0] = #0) or (P[0] = '{') Then + Begin Count := P - F; Inc(P); - if (P[-1] <> #0) and (P[0] = '{') then + If (P[-1] <> #0) and (P[0] = '{') Then Inc(Count); // include '{' - if Count > 0 then - begin + If Count > 0 Then + Begin Grow(Count); MoveChar(F[0], Result[Len + 1], Count); Inc(Len, Count); - end; - if P[-1] = #0 then + End; + If P[-1] = #0 Then Break; - if P[0] <> '{' then - begin + If P[0] <> '{' Then + Begin F := P; Inc(P); - while (P[0] <> #0) and (P[0] <> '}') do + While (P[0] <> #0) and (P[0] <> '}') Do Inc(P); SetString(S, F, P - F); Val(S, Index, ErrorCode); - if ErrorCode <> 0 then + If ErrorCode <> 0 Then raise FormatException.CreateRes(@RsFormatException); - if (Index < 0) or (Index > High(Args)) then + If (Index < 0) or (Index > High(Args)) Then raise FormatException.CreateRes(@RsFormatException); S := GetStringOf(Index); - if S <> '' then - begin + If S <> '' Then + Begin Grow(Length(S)); MoveChar(S[1], Result[Len + 1], Length(S)); Inc(Len, Length(S)); - end; - if P[0] = #0 then + End; + If P[0] = #0 Then Break; - end; + End; F := P + 1; - end - else - if (P[0] = '}') and (P[1] = '}') then - begin + End + Else + If (P[0] = '}') and (P[1] = '}') Then + Begin Count := P - F + 1; Inc(P); // skip next '}' Grow(Count); MoveChar(F[0], Result[Len + 1], Count); Inc(Len, Count); F := P + 1; - end; + End; Inc(P); - end; + End; SetLength(Result, Len); -end; +End; //=== { TJclStringBuilder } ===================================================== -constructor TJclStringBuilder.Create(Capacity: SizeInt; MaxCapacity: SizeInt); -begin - inherited Create; +Constructor TJclStringBuilder.Create(Capacity: SizeInt; MaxCapacity: SizeInt); +Begin + Inherited Create; SetLength(FChars, Capacity); FMaxCapacity := MaxCapacity; -end; -constructor TJclStringBuilder.Create(const Value: string; Capacity: SizeInt); -begin +End; +Constructor TJclStringBuilder.Create(Const Value: string; Capacity: SizeInt); +Begin Create(Capacity); Append(Value); -end; -constructor TJclStringBuilder.Create(const Value: string; StartIndex, Length, Capacity: SizeInt); -begin +End; +Constructor TJclStringBuilder.Create(Const Value: string; StartIndex, Length, Capacity: SizeInt); +Begin Create(Capacity); Append(Value, StartIndex + 1, Length); -end; -function TJclStringBuilder.ToString: string; -begin - if FLength > 0 then +End; +Function TJclStringBuilder.ToString: string; +Begin + If FLength > 0 Then SetString(Result, PChar(@FChars[0]), FLength) - else + Else Result := ''; -end; -function TJclStringBuilder.EnsureCapacity(Capacity: SizeInt): SizeInt; -begin - if System.Length(FChars) < Capacity then +End; +Function TJclStringBuilder.EnsureCapacity(Capacity: SizeInt): SizeInt; +Begin + If System.Length(FChars) < Capacity Then SetCapacity(Capacity); Result := System.Length(FChars); -end; -procedure TJclStringBuilder.Clear; -begin +End; +Procedure TJclStringBuilder.Clear; +Begin Length := 0; -end; -procedure TJclStringBuilder.SetCapacity(const Value: SizeInt); -begin - if Value <> System.Length(FChars) then - begin +End; +Procedure TJclStringBuilder.SetCapacity(Const Value: SizeInt); +Begin + If Value <> System.Length(FChars) Then + Begin SetLength(FChars, Value); - if Value < FLength then + If Value < FLength Then FLength := Value; - end; -end; -function TJclStringBuilder.GetChars(Index: SizeInt): Char; -begin + End; +End; +Function TJclStringBuilder.GetChars(Index: SizeInt): Char; +Begin Result := FChars[Index]; -end; -procedure TJclStringBuilder.SetChars(Index: SizeInt; const Value: Char); -begin +End; +Procedure TJclStringBuilder.SetChars(Index: SizeInt; Const Value: Char); +Begin FChars[Index] := Value; -end; -procedure TJclStringBuilder.Set_Length(const Value: SizeInt); -begin +End; +Procedure TJclStringBuilder.Set_Length(Const Value: SizeInt); +Begin FLength := Value; -end; -function TJclStringBuilder.GetCapacity: SizeInt; -begin +End; +Function TJclStringBuilder.GetCapacity: SizeInt; +Begin Result := System.Length(FChars); -end; -function TJclStringBuilder.AppendPChar(Value: PChar; Count: SizeInt; RepeatCount: SizeInt): TJclStringBuilder; -var +End; +Function TJclStringBuilder.AppendPChar(Value: PChar; Count: SizeInt; RepeatCount: SizeInt): TJclStringBuilder; +Var Capacity: SizeInt; -begin - if (Count > 0) and (RepeatCount > 0) then - begin - repeat +Begin + If (Count > 0) and (RepeatCount > 0) Then + Begin + Repeat Capacity := System.Length(FChars); - if Capacity + Count > MaxCapacity then + If Capacity + Count > MaxCapacity Then raise ArgumentOutOfRangeException.CreateRes(@RsArgumentOutOfRange); - if Capacity < FLength + Count then + If Capacity < FLength + Count Then SetLength(FChars, Capacity * 5 div 3 + Count); - if Count = 1 then + If Count = 1 Then FChars[FLength] := Value[0] - else + Else MoveChar(Value[0], FChars[FLength], Count); Inc(FLength, Count); Dec(RepeatCount); - until RepeatCount <= 0; - end; + Until RepeatCount <= 0; + End; Result := Self; -end; -function TJclStringBuilder.InsertPChar(Index: SizeInt; Value: PChar; Count, +End; +Function TJclStringBuilder.InsertPChar(Index: SizeInt; Value: PChar; Count, RepeatCount: SizeInt): TJclStringBuilder; -var +Var Capacity: SizeInt; -begin - if (Index < 0) or (Index > FLength) then +Begin + If (Index < 0) or (Index > FLength) Then raise ArgumentOutOfRangeException.CreateRes(@RsArgumentOutOfRange); - if Index = FLength then + If Index = FLength Then AppendPChar(Value, Count, RepeatCount) - else - if (Count > 0) and (RepeatCount > 0) then - begin - repeat + Else + If (Count > 0) and (RepeatCount > 0) Then + Begin + Repeat Capacity := System.Length(FChars); - if Capacity + Count > MaxCapacity then + If Capacity + Count > MaxCapacity Then raise ArgumentOutOfRangeException.CreateRes(@RsArgumentOutOfRange); - if Capacity < FLength + Count then + If Capacity < FLength + Count Then SetLength(FChars, Capacity * 5 div 3 + Count); MoveChar(FChars[Index], FChars[Index + Count], FLength - Index); - if Count = 1 then + If Count = 1 Then FChars[Index] := Value[0] - else + Else MoveChar(Value[0], FChars[Index], Count); Inc(FLength, Count); Dec(RepeatCount); Inc(Index, Count); // little optimization - until RepeatCount <= 0; - end; + Until RepeatCount <= 0; + End; Result := Self; -end; -function TJclStringBuilder.Append(const Value: array of Char): TJclStringBuilder; -var +End; +Function TJclStringBuilder.Append(Const Value: array Of Char): TJclStringBuilder; +Var Len: SizeInt; -begin +Begin Len := System.Length(Value); - if Len > 0 then + If Len > 0 Then AppendPChar(@Value[0], Len); Result := Self; -end; -function TJclStringBuilder.Append(const Value: array of Char; StartIndex, Length: SizeInt): TJclStringBuilder; -var +End; +Function TJclStringBuilder.Append(Const Value: array Of Char; StartIndex, Length: SizeInt): TJclStringBuilder; +Var Len: SizeInt; -begin +Begin Len := System.Length(Value); - if (Length > 0) and (StartIndex < Len) then - begin - if StartIndex + Length > Len then + If (Length > 0) and (StartIndex < Len) Then + Begin + If StartIndex + Length > Len Then Length := Len - StartIndex; AppendPChar(PChar(@Value[0]) + StartIndex, Length); - end; + End; Result := Self; -end; -function TJclStringBuilder.Append(Value: Char; RepeatCount: SizeInt = 1): TJclStringBuilder; -begin +End; +Function TJclStringBuilder.Append(Value: Char; RepeatCount: SizeInt = 1): TJclStringBuilder; +Begin Result := AppendPChar(@Value, 1, RepeatCount); -end; -function TJclStringBuilder.Append(const Value: string): TJclStringBuilder; -var +End; +Function TJclStringBuilder.Append(Const Value: string): TJclStringBuilder; +Var Len: SizeInt; -begin +Begin Len := System.Length(Value); - if Len > 0 then + If Len > 0 Then AppendPChar(Pointer(Value), Len); Result := Self; -end; -function TJclStringBuilder.Append(const Value: string; StartIndex, Length: SizeInt): TJclStringBuilder; -var +End; +Function TJclStringBuilder.Append(Const Value: string; StartIndex, Length: SizeInt): TJclStringBuilder; +Var Len: SizeInt; -begin +Begin Len := System.Length(Value); - if (Length > 0) and (StartIndex < Len) then - begin - if StartIndex + Length > Len then + If (Length > 0) and (StartIndex < Len) Then + Begin + If StartIndex + Length > Len Then Length := Len - StartIndex; AppendPChar(PChar(Pointer(Value)) + StartIndex, Length); - end; + End; Result := Self; -end; -function TJclStringBuilder.Append(Value: Boolean): TJclStringBuilder; -begin +End; +Function TJclStringBuilder.Append(Value: Boolean): TJclStringBuilder; +Begin Result := Append(BoolToStr[Value]); -end; -function TJclStringBuilder.Append(Value: Cardinal): TJclStringBuilder; -begin +End; +Function TJclStringBuilder.Append(Value: Cardinal): TJclStringBuilder; +Begin Result := Append(IntToStr(Value)); -end; -function TJclStringBuilder.Append(Value: Integer): TJclStringBuilder; -begin +End; +Function TJclStringBuilder.Append(Value: Integer): TJclStringBuilder; +Begin Result := Append(IntToStr(Value)); -end; -function TJclStringBuilder.Append(Value: Double): TJclStringBuilder; -begin +End; +Function TJclStringBuilder.Append(Value: Double): TJclStringBuilder; +Begin Result := Append(FloatToStr(Value)); -end; -function TJclStringBuilder.Append(Value: Int64): TJclStringBuilder; -begin +End; +Function TJclStringBuilder.Append(Value: Int64): TJclStringBuilder; +Begin Result := Append(IntToStr(Value)); -end; -function TJclStringBuilder.Append(Obj: TObject): TJclStringBuilder; -begin +End; +Function TJclStringBuilder.Append(Obj: TObject): TJclStringBuilder; +Begin Result := Append(DotNetFormat('{0}', [Obj])); -end; -function TJclStringBuilder.AppendFormat(const Fmt: string; Arg0: Variant): TJclStringBuilder; -begin +End; +Function TJclStringBuilder.AppendFormat(Const Fmt: string; Arg0: Variant): TJclStringBuilder; +Begin Result := Append(DotNetFormat(Fmt, [Arg0])); -end; -function TJclStringBuilder.AppendFormat(const Fmt: string; Arg0, Arg1: Variant): TJclStringBuilder; -begin +End; +Function TJclStringBuilder.AppendFormat(Const Fmt: string; Arg0, Arg1: Variant): TJclStringBuilder; +Begin Result := Append(DotNetFormat(Fmt, [Arg0, Arg1])); -end; -function TJclStringBuilder.AppendFormat(const Fmt: string; Arg0, Arg1, Arg2: Variant): TJclStringBuilder; -begin +End; +Function TJclStringBuilder.AppendFormat(Const Fmt: string; Arg0, Arg1, Arg2: Variant): TJclStringBuilder; +Begin Result := Append(DotNetFormat(Fmt, [Arg0, Arg1, Arg2])); -end; -function TJclStringBuilder.AppendFormat(const Fmt: string; const Args: array of const): TJclStringBuilder; -begin +End; +Function TJclStringBuilder.AppendFormat(Const Fmt: string; Const Args: array Of Const): TJclStringBuilder; +Begin Result := Append(DotNetFormat(Fmt, Args)); -end; -function TJclStringBuilder.Insert(Index: SizeInt; const Value: array of Char): TJclStringBuilder; -var +End; +Function TJclStringBuilder.Insert(Index: SizeInt; Const Value: array Of Char): TJclStringBuilder; +Var Len: SizeInt; -begin +Begin Len := System.Length(Value); - if Len > 0 then + If Len > 0 Then InsertPChar(Index, @Value[0], Len); Result := Self; -end; -function TJclStringBuilder.Insert(Index: SizeInt; const Value: string; Count: SizeInt): TJclStringBuilder; -var +End; +Function TJclStringBuilder.Insert(Index: SizeInt; Const Value: string; Count: SizeInt): TJclStringBuilder; +Var Len: SizeInt; -begin +Begin Len := System.Length(Value); - if Len > 0 then + If Len > 0 Then InsertPChar(Index, Pointer(Value), Len, Count); Result := Self; -end; -function TJclStringBuilder.Insert(Index: SizeInt; Value: Boolean): TJclStringBuilder; -begin +End; +Function TJclStringBuilder.Insert(Index: SizeInt; Value: Boolean): TJclStringBuilder; +Begin Result := Insert(Index, BoolToStr[Value]); -end; -function TJclStringBuilder.Insert(Index: SizeInt; const Value: array of Char; +End; +Function TJclStringBuilder.Insert(Index: SizeInt; Const Value: array Of Char; StartIndex, Length: SizeInt): TJclStringBuilder; -var +Var Len: SizeInt; -begin +Begin Len := System.Length(Value); - if (Length > 0) and (StartIndex < Len) then - begin - if StartIndex + Length > Len then + If (Length > 0) and (StartIndex < Len) Then + Begin + If StartIndex + Length > Len Then Length := Len - StartIndex; InsertPChar(Index, PChar(@Value[0]) + StartIndex, Length); - end; + End; Result := Self; -end; -function TJclStringBuilder.Insert(Index: SizeInt; Value: Double): TJclStringBuilder; -begin +End; +Function TJclStringBuilder.Insert(Index: SizeInt; Value: Double): TJclStringBuilder; +Begin Result := Insert(Index, FloatToStr(Value)); -end; -function TJclStringBuilder.Insert(Index: SizeInt; Value: Int64): TJclStringBuilder; -begin +End; +Function TJclStringBuilder.Insert(Index: SizeInt; Value: Int64): TJclStringBuilder; +Begin Result := Insert(Index, IntToStr(Value)); -end; -function TJclStringBuilder.Insert(Index: SizeInt; Value: Cardinal): TJclStringBuilder; -begin +End; +Function TJclStringBuilder.Insert(Index: SizeInt; Value: Cardinal): TJclStringBuilder; +Begin Result := Insert(Index, IntToStr(Value)); -end; -function TJclStringBuilder.Insert(Index: SizeInt; Value: Integer): TJclStringBuilder; -begin +End; +Function TJclStringBuilder.Insert(Index: SizeInt; Value: Integer): TJclStringBuilder; +Begin Result := Insert(Index, IntToStr(Value)); -end; -function TJclStringBuilder.Insert(Index: SizeInt; Obj: TObject): TJclStringBuilder; -begin +End; +Function TJclStringBuilder.Insert(Index: SizeInt; Obj: TObject): TJclStringBuilder; +Begin Result := Insert(Index, DotNetFormat('{0}', [Obj])); -end; -function TJclStringBuilder.Remove(StartIndex, Length: SizeInt): TJclStringBuilder; -begin - if (StartIndex < 0) or (Length < 0) or (StartIndex + Length >= FLength) then +End; +Function TJclStringBuilder.Remove(StartIndex, Length: SizeInt): TJclStringBuilder; +Begin + If (StartIndex < 0) or (Length < 0) or (StartIndex + Length >= FLength) Then raise ArgumentOutOfRangeException.CreateRes(@RsArgumentOutOfRange); - if Length > 0 then - begin + If Length > 0 Then + Begin MoveChar(FChars[StartIndex + Length], FChars[StartIndex], FLength - (StartIndex + Length)); Dec(FLength, Length); - end; + End; Result := Self; -end; -function TJclStringBuilder.Replace(OldChar, NewChar: Char; StartIndex, +End; +Function TJclStringBuilder.Replace(OldChar, NewChar: Char; StartIndex, Count: SizeInt): TJclStringBuilder; -var +Var I: SizeInt; -begin - if Count = -1 then +Begin + If Count = -1 Then Count := FLength; - if (StartIndex < 0) or (Count < 0) or (StartIndex + Count > FLength) then + If (StartIndex < 0) or (Count < 0) or (StartIndex + Count > FLength) Then raise ArgumentOutOfRangeException.CreateRes(@RsArgumentOutOfRange); - if (Count > 0) and (OldChar <> NewChar) then - begin - for I := StartIndex to StartIndex + Length - 1 do - if FChars[I] = OldChar then + If (Count > 0) and (OldChar <> NewChar) Then + Begin + For I := StartIndex To StartIndex + Length - 1 Do + If FChars[I] = OldChar Then FChars[I] := NewChar; - end; + End; Result := Self; -end; -function TJclStringBuilder.Replace(OldValue, NewValue: string; StartIndex, Count: SizeInt): TJclStringBuilder; -var +End; +Function TJclStringBuilder.Replace(OldValue, NewValue: string; StartIndex, Count: SizeInt): TJclStringBuilder; +Var I: SizeInt; Offset: SizeInt; NewLen, OldLen, Capacity: SizeInt; -begin - if Count = -1 then +Begin + If Count = -1 Then Count := FLength; - if (StartIndex < 0) or (Count < 0) or (StartIndex + Count > FLength) then + If (StartIndex < 0) or (Count < 0) or (StartIndex + Count > FLength) Then raise ArgumentOutOfRangeException.CreateRes(@RsArgumentOutOfRange); - if OldValue = '' then + If OldValue = '' Then raise ArgumentException.CreateResFmt(@RsArgumentIsNull, [0]); - if (Count > 0) and (OldValue <> NewValue) then - begin + If (Count > 0) and (OldValue <> NewValue) Then + Begin OldLen := System.Length(OldValue); NewLen := System.Length(NewValue); Offset := NewLen - OldLen; Capacity := System.Length(FChars); - for I := StartIndex to StartIndex + Length - 1 do - if FChars[I] = OldValue[1] then - begin - if OldLen > 1 then - if StrLComp(@FChars[I + 1], PChar(OldValue) + 1, OldLen - 1) <> 0 then + For I := StartIndex To StartIndex + Length - 1 Do + If FChars[I] = OldValue[1] Then + Begin + If OldLen > 1 Then + If StrLComp(@FChars[I + 1], PChar(OldValue) + 1, OldLen - 1) <> 0 Then Continue; - if Offset <> 0 then - begin - if FLength - OldLen + NewLen > MaxCurrency then + If Offset <> 0 Then + Begin + If FLength - OldLen + NewLen > MaxCurrency Then raise ArgumentOutOfRangeException.CreateRes(@RsArgumentOutOfRange); - if Capacity < FLength + Offset then - begin + If Capacity < FLength + Offset Then + Begin Capacity := Capacity * 5 div 3 + Offset; SetLength(FChars, Capacity); - end; - if Offset < 0 then + End; + If Offset < 0 Then MoveChar(FChars[I - Offset], FChars[I], FLength - I) - else + Else MoveChar(FChars[I + OldLen], FChars[I + OldLen + Offset], FLength - OldLen - I); Inc(FLength, Offset); - end; - if NewLen > 0 then - begin - if (OldLen = 1) and (NewLen = 1) then + End; + If NewLen > 0 Then + Begin + If (OldLen = 1) and (NewLen = 1) Then FChars[I] := NewValue[1] - else + Else MoveChar(NewValue[1], FChars[I], NewLen); - end; - end; - end; + End; + End; + End; Result := Self; -end; -function StrExpandTabs(S: string): string; -begin +End; +Function StrExpandTabs(S: string): string; +Begin // use an empty tab set, which will default to a tab width of 2 Result := TJclTabSet(nil).Expand(s); -end; -function StrExpandTabs(S: string; TabWidth: SizeInt): string; -var +End; +Function StrExpandTabs(S: string; TabWidth: SizeInt): string; +Var TabSet: TJclTabSet; -begin +Begin // create a tab set with no tab stops and the given tab width TabSet := TJclTabSet.Create(TabWidth); - try + Try Result := TabSet.Expand(S); - finally + Finally TabSet.Free; - end; -end; -function StrExpandTabs(S: string; TabSet: TJclTabSet): string; -begin + End; +End; +Function StrExpandTabs(S: string; TabSet: TJclTabSet): string; +Begin // use the provided tab set to perform the expansion Result := TabSet.Expand(S); -end; -function StrOptimizeTabs(S: string): string; -begin +End; +Function StrOptimizeTabs(S: string): string; +Begin // use an empty tab set, which will default to a tab width of 2 Result := TJclTabSet(nil).Optimize(s); -end; -function StrOptimizeTabs(S: string; TabWidth: SizeInt): string; -var +End; +Function StrOptimizeTabs(S: string; TabWidth: SizeInt): string; +Var TabSet: TJclTabSet; -begin +Begin // create a tab set with no tab stops and the given tab width TabSet := TJclTabSet.Create(TabWidth); - try + Try Result := TabSet.Optimize(S); - finally + Finally TabSet.Free; - end; -end; -function StrOptimizeTabs(S: string; TabSet: TJclTabSet): string; -begin + End; +End; +Function StrOptimizeTabs(S: string; TabSet: TJclTabSet): string; +Begin // use the provided tab set to perform the optimization Result := TabSet.Optimize(S); -end; +End; // === { TTabSetData } =================================================== -type - TTabSetData = class - public +Type + TTabSetData = Class + Public FStops: TDynSizeIntArray; FRealWidth: SizeInt; FRefCount: SizeInt; FWidth: SizeInt; FZeroBased: Boolean; - constructor Create(TabStops: array of SizeInt; ZeroBased: Boolean; TabWidth: SizeInt); - function Add(Column: SizeInt): SizeInt; - function AddRef: SizeInt; - procedure CalcRealWidth; - function FindStop(Column: SizeInt): SizeInt; - function ReleaseRef: SizeInt; - procedure RemoveAt(Index: SizeInt); - procedure SetStops(Index, Value: SizeInt); - end; -constructor TTabSetData.Create(TabStops: array of SizeInt; ZeroBased: Boolean; TabWidth: SizeInt); -var + Constructor Create(TabStops: array Of SizeInt; ZeroBased: Boolean; TabWidth: SizeInt); + Function Add(Column: SizeInt): SizeInt; + Function AddRef: SizeInt; + Procedure CalcRealWidth; + Function FindStop(Column: SizeInt): SizeInt; + Function ReleaseRef: SizeInt; + Procedure RemoveAt(Index: SizeInt); + Procedure SetStops(Index, Value: SizeInt); + End; +Constructor TTabSetData.Create(TabStops: array Of SizeInt; ZeroBased: Boolean; TabWidth: SizeInt); +Var idx: SizeInt; -begin - inherited Create; +Begin + Inherited Create; FRefCount := 1; - for idx := 0 to High(Tabstops) do + For idx := 0 To High(Tabstops) Do Add(Tabstops[idx]); FWidth := TabWidth; FZeroBased := ZeroBased; CalcRealWidth; -end; -function TTabSetData.Add(Column: SizeInt): SizeInt; -var +End; +Function TTabSetData.Add(Column: SizeInt): SizeInt; +Var I: SizeInt; -begin - if Column < Ord(FZeroBased) then +Begin + If Column < Ord(FZeroBased) Then raise ArgumentOutOfRangeException.Create('Column'); Result := FindStop(Column); - if Result < 0 then - begin + If Result < 0 Then + Begin // the column doesn't exist; invert the result of FindStop to get the correct index position Result := not Result; // increase the tab stop array SetLength(FStops, Length(FStops) + 1); // shift rooms after the insert position - for I := High(FStops) - 1 downto Result do + For I := High(FStops) - 1 Downto Result Do FStops[I + 1] := FStops[I]; // add the tab stop at the correct location FStops[Result] := Column; CalcRealWidth; - end - else - begin + End + Else + Begin raise EJclStringError.CreateRes(@RsTabs_DuplicatesNotAllowed); - end; -end; -function TTabSetData.AddRef: SizeInt; -begin -end; -procedure TTabSetData.CalcRealWidth; -begin - if FWidth < 1 then - begin - if Length(FStops) > 1 then + End; +End; +Function TTabSetData.AddRef: SizeInt; +Begin +End; +Procedure TTabSetData.CalcRealWidth; +Begin + If FWidth < 1 Then + Begin + If Length(FStops) > 1 Then FRealWidth := FStops[High(FStops)] - FStops[Pred(High(FStops))] - else - if Length(FStops) = 1 then + Else + If Length(FStops) = 1 Then FRealWidth := FStops[0] - else + Else FRealWidth := 2; - end - else + End + Else FRealWidth := FWidth; -end; -function TTabSetData.FindStop(Column: SizeInt): SizeInt; -begin +End; +Function TTabSetData.FindStop(Column: SizeInt): SizeInt; +Begin Result := High(FStops); - while (Result >= 0) and (FStops[Result] > Column) do + While (Result >= 0) and (FStops[Result] > Column) Do Dec(Result); - if (Result >= 0) and (FStops[Result] <> Column) then + If (Result >= 0) and (FStops[Result] <> Column) Then Result := not Succ(Result); -end; -function TTabSetData.ReleaseRef: SizeInt; -begin -end; -procedure TTabSetData.RemoveAt(Index: SizeInt); -var +End; +Function TTabSetData.ReleaseRef: SizeInt; +Begin +End; +Procedure TTabSetData.RemoveAt(Index: SizeInt); +Var I: SizeInt; -begin - for I := Index to High(FStops) - 1 do +Begin + For I := Index To High(FStops) - 1 Do FStops[I] := FStops[I + 1]; SetLength(FStops, High(FStops)); CalcRealWidth; -end; -procedure TTabSetData.SetStops(Index, Value: SizeInt); -var +End; +Procedure TTabSetData.SetStops(Index, Value: SizeInt); +Var temp: SizeInt; -begin - if (Index < 0) or (Index >= Length(FStops)) then - begin +Begin + If (Index < 0) or (Index >= Length(FStops)) Then + Begin raise ArgumentOutOfRangeException.CreateRes(@RsArgumentOutOfRange); - end - else - begin + End + Else + Begin temp := FindStop(Value); - if temp < 0 then - begin + If temp < 0 Then + Begin // remove existing tab stop... RemoveAt(Index); // now add the new tab stop Add(Value); - end - else - if temp <> Index then - begin + End + Else + If temp <> Index Then + Begin // new tab stop already present at another index raise EJclStringError.CreateRes(@RsTabs_DuplicatesNotAllowed); - end; - end; -end; + End; + End; +End; //=== { TJclTabSet } ===================================================== -constructor TJclTabSet.Create; -begin +Constructor TJclTabSet.Create; +Begin // no tab stops, tab width set to auto Create([], True, 0); -end; -constructor TJclTabSet.Create(TabWidth: SizeInt); -begin +End; +Constructor TJclTabSet.Create(TabWidth: SizeInt); +Begin // no tab stops, specified tab width Create([], True, TabWidth); -end; -constructor TJclTabSet.Create(const Tabstops: array of SizeInt; ZeroBased: Boolean); -begin +End; +Constructor TJclTabSet.Create(Const Tabstops: array Of SizeInt; ZeroBased: Boolean); +Begin // specified tab stops, tab width equal to distance between last two tab stops Create(Tabstops, ZeroBased, 0); -end; -constructor TJclTabSet.Create(const Tabstops: array of SizeInt; ZeroBased: Boolean; TabWidth: SizeInt); -begin - inherited Create; +End; +Constructor TJclTabSet.Create(Const Tabstops: array Of SizeInt; ZeroBased: Boolean; TabWidth: SizeInt); +Begin + Inherited Create; FData := TTabSetData.Create(Tabstops, ZeroBased, TabWidth); -end; -constructor TJclTabSet.Create(Data: TObject); -begin - inherited Create; +End; +Constructor TJclTabSet.Create(Data: TObject); +Begin + Inherited Create; // add a reference to the data TTabSetData(Data).AddRef; // assign the data to this instance FData := TTabSetData(Data); -end; -destructor TJclTabSet.Destroy; -begin +End; +Destructor TJclTabSet.Destroy; +Begin // release the reference to the tab set data TTabSetData(FData).ReleaseRef; // make sure we won't accidentally refer to it later, just in case something goes wrong during destruction FData := nil; // really destroy the instance - inherited Destroy; -end; -function TJclTabSet.Add(Column: SizeInt): SizeInt; -begin - if Self = nil then + Inherited Destroy; +End; +Function TJclTabSet.Add(Column: SizeInt): SizeInt; +Begin + If Self = nil Then raise NullReferenceException.Create; Result := TTabSetData(FData).Add(Column); -end; -function TJclTabSet.Clone: TJclTabSet; -begin - if Self <> nil then +End; +Function TJclTabSet.Clone: TJclTabSet; +Begin + If Self <> nil Then Result := TJclTabSet.Create(TTabSetData(FData).FStops, TTabSetData(FData).FZeroBased, TTabSetData(FData).FWidth) - else + Else Result := nil; -end; -function TJclTabSet.Delete(Column: SizeInt): SizeInt; -begin +End; +Function TJclTabSet.Delete(Column: SizeInt): SizeInt; +Begin Result := TTabSetData(FData).FindStop(Column); - if Result >= 0 then + If Result >= 0 Then TTabSetData(FData).RemoveAt(Result); -end; -function TJclTabSet.Expand(const S: string): string; -begin +End; +Function TJclTabSet.Expand(Const S: string): string; +Begin Result := Expand(s, StartColumn); -end; -function TJclTabSet.Expand(const S: string; Column: SizeInt): string; -var +End; +Function TJclTabSet.Expand(Const S: string; Column: SizeInt): string; +Var sb: TJclStringBuilder; head: PChar; cur: PChar; -begin - if Column < StartColumn then +Begin + If Column < StartColumn Then raise ArgumentOutOfRangeException.Create('Column'); sb := TJclStringBuilder.Create(Length(S)); - try + Try cur := PChar(S); - while cur^ <> #0 do - begin + While cur^ <> #0 Do + Begin head := cur; - while (cur^ <> #0) and (cur^ <> #9) do - begin - if CharIsReturn(cur^) then + While (cur^ <> #0) and (cur^ <> #9) Do + Begin + If CharIsReturn(cur^) Then Column := StartColumn - else + Else Inc(Column); Inc(cur); - end; - if cur > head then + End; + If cur > head Then sb.Append(head, 0, cur - head); - if cur^ = #9 then - begin + If cur^ = #9 Then + Begin sb.Append(' ', TabFrom(Column) - Column); Column := TabFrom(Column); Inc(cur); - end; - end; + End; + End; Result := sb.ToString; - finally + Finally sb.Free; - end; -end; -function TJclTabSet.FindStop(Column: SizeInt): SizeInt; -begin - if Self <> nil then + End; +End; +Function TJclTabSet.FindStop(Column: SizeInt): SizeInt; +Begin + If Self <> nil Then Result := TTabSetData(FData).FindStop(Column) - else + Else Result := -1; -end; -class function TJclTabSet.FromString(const S: string): TJclTabSet; -var +End; +Class Function TJclTabSet.FromString(Const S: string): TJclTabSet; +Var cur: PChar; - function ParseNumber: Integer; - var + Function ParseNumber: Integer; + Var head: PChar; - begin + Begin StrSkipChars(cur, CharIsWhiteSpace); head := cur; - while CharIsDigit(cur^) do + While CharIsDigit(cur^) Do Inc(cur); Result := -1; - if (cur <= head) or not TryStrToInt(Copy(head, 1, cur - head), Result) then + If (cur <= head) or not TryStrToInt(Copy(head, 1, cur - head), Result) Then Result := -1; - end; - procedure ParseStops; - var + End; + Procedure ParseStops; + Var openBracket, hadComma: Boolean; num: SizeInt; - begin + Begin StrSkipChars(cur, CharIsWhiteSpace); openBracket := cur^ = '['; hadComma := False; - if openBracket then + If openBracket Then Inc(cur); - repeat + Repeat num := ParseNumber; - if (num < 0) and hadComma then + If (num < 0) and hadComma Then raise EJclStringError.CreateRes(@RsTabs_StopExpected) - else - if num >= 0 then + Else + If num >= 0 Then Result.Add(num); StrSkipChars(cur, CharIsWhiteSpace); hadComma := cur^ = ','; - if hadComma then + If hadComma Then Inc(cur); - until (cur^ = #0) or (cur^ = '+') or (cur^ = ']'); - if hadComma then + Until (cur^ = #0) or (cur^ = '+') or (cur^ = ']'); + If hadComma Then raise EJclStringError.CreateRes(@RsTabs_StopExpected) - else - if openBracket and (cur^ <> ']') then + Else + If openBracket and (cur^ <> ']') Then raise EJclStringError.CreateRes(@RsTabs_CloseBracketExpected); - end; - procedure ParseTabWidth; - var + End; + Procedure ParseTabWidth; + Var num: SizeInt; - begin + Begin StrSkipChars(cur, CharIsWhiteSpace); - if cur^ = '+' then - begin + If cur^ = '+' Then + Begin Inc(cur); StrSkipChars(cur, CharIsWhiteSpace); num := ParseNumber; - if (num < 0) then + If (num < 0) Then raise EJclStringError.CreateRes(@RsTabs_TabWidthExpected) - else + Else Result.TabWidth := num; - end; - end; - procedure ParseZeroBasedFlag; - begin + End; + End; + Procedure ParseZeroBasedFlag; + Begin StrSkipChars(cur, CharIsWhiteSpace); - if cur^ = '0' then - begin + If cur^ = '0' Then + Begin Inc(cur); - if CharIsWhiteSpace(cur^) or (cur^ = #0) or (cur^ = '[') then - begin + If CharIsWhiteSpace(cur^) or (cur^ = #0) or (cur^ = '[') Then + Begin Result.ZeroBased := True; StrSkipChars(cur, CharIsWhiteSpace); - end - else + End + Else Dec(cur); - end; - end; -begin + End; + End; +Begin Result := TJclTabSet.Create; - try + Try Result.ZeroBased := False; cur := PChar(S); ParseZeroBasedFlag; ParseStops; ParseTabWidth; - except + Except // clean up the partially complete instance (to avoid memory leaks)... Result.Free; // ... and re-raise the exception raise; - end; -end; -function TJclTabSet.GetCount: SizeInt; -begin - if Self <> nil then + End; +End; +Function TJclTabSet.GetCount: SizeInt; +Begin + If Self <> nil Then Result := Length(TTabSetData(FData).FStops) - else + Else Result := 0; -end; -function TJclTabSet.GetStops(Index: SizeInt): SizeInt; -begin - if Self <> nil then - begin - if (Index < 0) or (Index >= Length(TTabSetData(FData).FStops)) then - begin +End; +Function TJclTabSet.GetStops(Index: SizeInt): SizeInt; +Begin + If Self <> nil Then + Begin + If (Index < 0) or (Index >= Length(TTabSetData(FData).FStops)) Then + Begin raise EJclStringError.CreateRes(@RsArgumentOutOfRange); - end - else + End + Else Result := TTabSetData(FData).FStops[Index]; - end - else - begin + End + Else + Begin raise EJclStringError.CreateRes(@RsArgumentOutOfRange); - end; -end; -function TJclTabSet.GetTabWidth: SizeInt; -begin - if Self <> nil then + End; +End; +Function TJclTabSet.GetTabWidth: SizeInt; +Begin + If Self <> nil Then Result := TTabSetData(FData).FWidth - else + Else Result := 0; -end; -function TJclTabSet.GetZeroBased: Boolean; -begin +End; +Function TJclTabSet.GetZeroBased: Boolean; +Begin Result := (Self = nil) or TTabSetData(FData).FZeroBased; -end; -procedure TJclTabSet.OptimalFillInfo(StartColumn, TargetColumn: SizeInt; out TabsNeeded, SpacesNeeded: SizeInt); -var +End; +Procedure TJclTabSet.OptimalFillInfo(StartColumn, TargetColumn: SizeInt; out TabsNeeded, SpacesNeeded: SizeInt); +Var nextTab: SizeInt; -begin - if StartColumn < Self.StartColumn then // starting column less than 1 or 0 (depending on ZeroBased state) +Begin + If StartColumn < Self.StartColumn Then // starting column less than 1 or 0 (depending on ZeroBased state) raise ArgumentOutOfRangeException.Create('StartColumn'); - if (TargetColumn < StartColumn) then // target lies before the starting column + If (TargetColumn < StartColumn) Then // target lies before the starting column raise ArgumentOutOfRangeException.Create('TargetColumn'); TabsNeeded := 0; - repeat + Repeat nextTab := TabFrom(StartColumn); - if nextTab <= TargetColumn then - begin + If nextTab <= TargetColumn Then + Begin Inc(TabsNeeded); StartColumn := nextTab; - end; - until nextTab > TargetColumn; + End; + Until nextTab > TargetColumn; SpacesNeeded := TargetColumn - StartColumn; -end; -function TJclTabSet.Optimize(const S: string): string; -begin +End; +Function TJclTabSet.Optimize(Const S: string): string; +Begin Result := Optimize(S, StartColumn); -end; -function TJclTabSet.Optimize(const S: string; Column: SizeInt): string; -var +End; +Function TJclTabSet.Optimize(Const S: string; Column: SizeInt): string; +Var sb: TJclStringBuilder; head: PChar; cur: PChar; tgt: SizeInt; - procedure AppendOptimalWhiteSpace(Target: SizeInt); - var + Procedure AppendOptimalWhiteSpace(Target: SizeInt); + Var tabCount: SizeInt; spaceCount: SizeInt; - begin - if cur > head then - begin + Begin + If cur > head Then + Begin OptimalFillInfo(Column, Target, tabCount, spaceCount); - if tabCount > 0 then + If tabCount > 0 Then sb.Append(#9, tabCount); - if spaceCount > 0 then + If spaceCount > 0 Then sb.Append(' ', spaceCount); - end; - end; -begin - if Column < StartColumn then + End; + End; +Begin + If Column < StartColumn Then raise ArgumentOutOfRangeException.Create('Column'); sb := TJclStringBuilder.Create(Length(S)); - try + Try cur := PChar(s); - while cur^ <> #0 do - begin + While cur^ <> #0 Do + Begin // locate first whitespace character head := cur; - while (cur^ <> #0) and not CharIsWhiteSpace(cur^) do + While (cur^ <> #0) and not CharIsWhiteSpace(cur^) Do Inc(cur); // output non whitespace characters - if cur > head then + If cur > head Then sb.Append(head, 0, cur - head); // advance column Inc(Column, cur - head); // initialize target column indexer tgt := Column; // locate end of whitespace sequence - while CharIsWhiteSpace(cur^) do - begin - if CharIsReturn(cur^) then - begin + While CharIsWhiteSpace(cur^) Do + Begin + If CharIsReturn(cur^) Then + Begin // append optimized whitespace sequence... AppendOptimalWhiteSpace(tgt); // ...set the column back to the start of the line... @@ -4360,218 +4360,218 @@ function TJclTabSet.Optimize(const S: string; Column: SizeInt): string; tgt := Column; // ...add the line break character... sb.Append(cur^); - end - else - if cur^ = #9 then + End + Else + If cur^ = #9 Then tgt := TabFrom(tgt) // expand the tab - else + Else Inc(tgt); // a normal whitespace; taking up 1 column Inc(cur); - end; + End; AppendOptimalWhiteSpace(tgt); // append optimized whitespace sequence... Column := tgt; // ...and memorize the column for the next iteration - end; + End; Result := sb.ToString; // convert result to a string - finally + Finally sb.Free; - end; -end; -procedure TJclTabSet.RemoveAt(Index: SizeInt); -begin - if Self <> nil then + End; +End; +Procedure TJclTabSet.RemoveAt(Index: SizeInt); +Begin + If Self <> nil Then TTabSetData(FData).RemoveAt(Index) - else + Else raise NullReferenceException.Create; -end; -procedure TJclTabSet.SetStops(Index, Value: SizeInt); -begin - if Self <> nil then +End; +Procedure TJclTabSet.SetStops(Index, Value: SizeInt); +Begin + If Self <> nil Then TTabSetData(FData).SetStops(Index, Value) - else + Else raise NullReferenceException.Create; -end; -procedure TJclTabSet.SetTabWidth(Value: SizeInt); -begin - if Self <> nil then - begin +End; +Procedure TJclTabSet.SetTabWidth(Value: SizeInt); +Begin + If Self <> nil Then + Begin TTabSetData(FData).FWidth := Value; TTabSetData(FData).CalcRealWidth; - end - else + End + Else raise NullReferenceException.Create; -end; -procedure TJclTabSet.SetZeroBased(Value: Boolean); -var +End; +Procedure TJclTabSet.SetZeroBased(Value: Boolean); +Var shift: SizeInt; idx: SizeInt; -begin - if Self <> nil then - begin - if Value <> TTabSetData(FData).FZeroBased then - begin +Begin + If Self <> nil Then + Begin + If Value <> TTabSetData(FData).FZeroBased Then + Begin TTabSetData(FData).FZeroBased := Value; - if Value then + If Value Then shift := -1 - else + Else shift := 1; - for idx := 0 to High(TTabSetData(FData).FStops) do + For idx := 0 To High(TTabSetData(FData).FStops) Do TTabSetData(FData).FStops[idx] := TTabSetData(FData).FStops[idx] + shift; - end; - end - else + End; + End + Else raise NullReferenceException.Create; -end; -function TJclTabSet.InternalTabStops: TDynSizeIntArray; -begin - if Self <> nil then +End; +Function TJclTabSet.InternalTabStops: TDynSizeIntArray; +Begin + If Self <> nil Then Result := TTabSetData(FData).FStops - else + Else Result := nil; -end; -function TJclTabSet.InternalTabWidth: SizeInt; -begin - if Self <> nil then +End; +Function TJclTabSet.InternalTabWidth: SizeInt; +Begin + If Self <> nil Then Result := TTabSetData(FData).FRealWidth - else + Else Result := 2; -end; -function TJclTabSet.NewReference: TJclTabSet; -begin - if Self <> nil then +End; +Function TJclTabSet.NewReference: TJclTabSet; +Begin + If Self <> nil Then Result := TJclTabSet.Create(FData) - else + Else Result := nil; -end; -function TJclTabSet.StartColumn: SizeInt; -begin - if GetZeroBased then +End; +Function TJclTabSet.StartColumn: SizeInt; +Begin + If GetZeroBased Then Result := 0 - else + Else Result := 1; -end; -function TJclTabSet.TabFrom(Column: SizeInt): SizeInt; -begin - if Column < StartColumn then +End; +Function TJclTabSet.TabFrom(Column: SizeInt): SizeInt; +Begin + If Column < StartColumn Then raise ArgumentOutOfRangeException.Create('Column'); Result := FindStop(Column); - if Result < 0 then + If Result < 0 Then Result := not Result - else + Else Inc(Result); - if Result >= GetCount then - begin - if GetCount > 0 then + If Result >= GetCount Then + Begin + If GetCount > 0 Then Result := TTabSetData(FData).FStops[High(TTabSetData(FData).FStops)] - else + Else Result := StartColumn; - while Result <= Column do + While Result <= Column Do Inc(Result, ActualTabWidth); - end - else + End + Else Result := TTabSetData(FData).FStops[Result]; -end; -function TJclTabSet.ToString: string; -begin +End; +Function TJclTabSet.ToString: string; +Begin Result := ToString(TabSetFormatting_Full); -end; -function TJclTabSet.ToString(FormattingOptions: SizeInt): string; -var +End; +Function TJclTabSet.ToString(FormattingOptions: SizeInt): string; +Var sb: TJclStringBuilder; idx: SizeInt; - function WantBrackets: Boolean; - begin + Function WantBrackets: Boolean; + Begin Result := (TabSetFormatting_SurroundStopsWithBrackets and FormattingOptions) <> 0; - end; - function EmptyBrackets: Boolean; - begin + End; + Function EmptyBrackets: Boolean; + Begin Result := (TabSetFormatting_EmptyBracketsIfNoStops and FormattingOptions) <> 0; - end; - function IncludeAutoWidth: Boolean; - begin + End; + Function IncludeAutoWidth: Boolean; + Begin Result := (TabSetFormatting_AutoTabWidth and FormattingOptions) <> 0; - end; - function IncludeTabWidth: Boolean; - begin + End; + Function IncludeTabWidth: Boolean; + Begin Result := (TabSetFormatting_NoTabWidth and FormattingOptions) = 0; - end; - function IncludeStops: Boolean; - begin + End; + Function IncludeStops: Boolean; + Begin Result := (TabSetFormatting_NoTabStops and FormattingOptions) = 0; - end; -begin + End; +Begin sb := TJclStringBuilder.Create; - try + Try // output the fixed tabulation positions if requested... - if IncludeStops then - begin + If IncludeStops Then + Begin // output each individual tabulation position - for idx := 0 to GetCount - 1 do - begin + For idx := 0 To GetCount - 1 Do + Begin sb.Append(TabStops[idx]); sb.Append(','); - end; + End; // remove the final comma if any tabulation positions where outputted - if sb.Length <> 0 then + If sb.Length <> 0 Then sb.Remove(sb.Length - 1, 1); // bracket the tabulation positions if requested - if WantBrackets and (EmptyBrackets or (sb.Length > 0)) then - begin + If WantBrackets and (EmptyBrackets or (sb.Length > 0)) Then + Begin sb.Insert(0, '['); sb.Append(']'); - end; - end; + End; + End; // output the tab width if requested.... - if IncludeTabWidth and (IncludeAutoWidth or (TabWidth > 0)) then - begin + If IncludeTabWidth and (IncludeAutoWidth or (TabWidth > 0)) Then + Begin // separate the tab width from any outputted tabulation positions with a whitespace - if sb.Length > 0 then + If sb.Length > 0 Then sb.Append(' '); // flag tab width sb.Append('+'); // finally, output the tab width sb.Append(ActualTabWidth); - end; + End; // flag zero-based tabset by outputting a 0 (zero) as the first character. - if ZeroBased then + If ZeroBased Then sb.Insert(0, string('0 ')); Result := StrTrimCharRight(sb.ToString, ' '); - finally + Finally sb.Free; - end; -end; -function TJclTabSet.UpdatePosition(const S: string): SizeInt; -var + End; +End; +Function TJclTabSet.UpdatePosition(Const S: string): SizeInt; +Var Line: SizeInt; -begin +Begin Result := StartColumn; Line := -1; UpdatePosition(S, Result, Line); -end; -function TJclTabSet.UpdatePosition(const S: string; Column: SizeInt): SizeInt; -var +End; +Function TJclTabSet.UpdatePosition(Const S: string; Column: SizeInt): SizeInt; +Var Line: SizeInt; -begin - if Column < StartColumn then +Begin + If Column < StartColumn Then raise ArgumentOutOfRangeException.Create('Column'); Result := Column; Line := -1; UpdatePosition(S, Result, Line); -end; -function TJclTabSet.UpdatePosition(const S: string; var Column, Line: SizeInt): SizeInt; -var +End; +Function TJclTabSet.UpdatePosition(Const S: string; Var Column, Line: SizeInt): SizeInt; +Var prevChar: Char; cur: PChar; -begin - if Column < StartColumn then +Begin + If Column < StartColumn Then raise ArgumentOutOfRangeException.Create('Column'); // initialize loop cur := PChar(S); // iterate until end of string (the Null-character) - while cur^ <> #0 do - begin + While cur^ <> #0 Do + Begin // check for line-breaking characters - if CharIsReturn(cur^) then - begin + If CharIsReturn(cur^) Then + Begin // Column moves back all the way to the left Column := StartColumn; // If this is the first line-break character or the same line-break character, increment the Line parameter @@ -4580,156 +4580,156 @@ function TJclTabSet.UpdatePosition(const S: string; var Column, Line: SizeInt): prevChar := cur^; Inc(cur); // if it isn't a two-character line-break, undo the previous advancement - if (cur^ = prevChar) or not CharIsReturn(cur^) then + If (cur^ = prevChar) or not CharIsReturn(cur^) Then Dec(cur); - end - else // check for tab character and expand it - if cur^ = #9 then + End + Else // check for tab character and expand it + If cur^ = #9 Then Column := TabFrom(Column) - else // a normal character; increment column + Else // a normal character; increment column Inc(Column); // advance pointer Inc(cur); - end; + End; // set the result to the newly calculated column Result := Column; -end; +End; //=== { NullReferenceException } ============================================= -constructor NullReferenceException.Create; -begin +Constructor NullReferenceException.Create; +Begin CreateRes(@RsArg_NullReferenceException); -end; -function CompareNatural(const S1, S2: string; CaseInsensitive: Boolean): SizeInt; -var +End; +Function CompareNatural(Const S1, S2: string; CaseInsensitive: Boolean): SizeInt; +Var Cur1, Len1, Cur2, Len2: SizeInt; - function IsRealNumberChar(ch: Char): Boolean; - begin + Function IsRealNumberChar(ch: Char): Boolean; + Begin Result := ((ch >= '0') and (ch <= '9')) or (ch = '-') or (ch = '+'); - end; - procedure NumberCompare; - var + End; + Procedure NumberCompare; + Var IsReallyNumber: Boolean; FirstDiffBreaks: Boolean; Val1, Val2: SizeInt; - begin + Begin Result := 0; IsReallyNumber := False; // count leading spaces in S1 - while (Cur1 <= Len1) and CharIsWhiteSpace(S1[Cur1]) do - begin + While (Cur1 <= Len1) and CharIsWhiteSpace(S1[Cur1]) Do + Begin Dec(Result); Inc(Cur1); - end; + End; // count leading spaces in S2 (canceling them out against the ones in S1) - while (Cur2 <= Len2) and CharIsWhiteSpace(S2[Cur2]) do - begin + While (Cur2 <= Len2) and CharIsWhiteSpace(S2[Cur2]) Do + Begin Inc(Result); Inc(Cur2); - end; + End; // if spaces match, or both strings are actually followed by a numeric character, continue the checks - if (Result = 0) or ((Cur1 <= Len1) and CharIsNumberChar(S1[Cur1]) and (Cur2 <= Len2) and CharIsNumberChar(S2[Cur2])) then - begin + If (Result = 0) or ((Cur1 <= Len1) and CharIsNumberChar(S1[Cur1]) and (Cur2 <= Len2) and CharIsNumberChar(S2[Cur2])) Then + Begin // Check signed number - if (Cur1 <= Len1) and (S1[Cur1] = '-') and ((Cur2 > Len2) or (S2[Cur2] <> '-')) then + If (Cur1 <= Len1) and (S1[Cur1] = '-') and ((Cur2 > Len2) or (S2[Cur2] <> '-')) Then Result := 1 - else - if (Cur2 <= Len2) and (S2[Cur2] = '-') and ((Cur1 > Len1) or (S1[Cur1] <> '-')) then + Else + If (Cur2 <= Len2) and (S2[Cur2] = '-') and ((Cur1 > Len1) or (S1[Cur1] <> '-')) Then Result := -1 - else + Else Result := 0; - if (Cur1 <= Len1) and ((S1[Cur1] = '-') or (S1[Cur1] = '+')) then + If (Cur1 <= Len1) and ((S1[Cur1] = '-') or (S1[Cur1] = '+')) Then Inc(Cur1); - if (Cur2 <= Len2) and ((S2[Cur2] = '-') or (S2[Cur2] = '+')) then + If (Cur2 <= Len2) and ((S2[Cur2] = '-') or (S2[Cur2] = '+')) Then Inc(Cur2); FirstDiffBreaks := (Cur1 <= Len1) and (S1[Cur1] = '0') or (Cur2 <= Len2) and (S2[Cur2] = '0'); - while (Cur1 <= Len1) and CharIsDigit(S1[Cur1]) and (Cur2 <= Len2) and CharIsDigit(S2[Cur2]) do - begin + While (Cur1 <= Len1) and CharIsDigit(S1[Cur1]) and (Cur2 <= Len2) and CharIsDigit(S2[Cur2]) Do + Begin IsReallyNumber := True; Val1 := StrToInt(S1[Cur1]); Val2 := StrToInt(S2[Cur2]); - if (Result = 0) and (Val1 < Val2) then + If (Result = 0) and (Val1 < Val2) Then Result := -1 - else - if (Result = 0) and (Val1 > Val2) then + Else + If (Result = 0) and (Val1 > Val2) Then Result := 1; - if FirstDiffBreaks and (Result <> 0) then + If FirstDiffBreaks and (Result <> 0) Then Break; Inc(Cur1); Inc(Cur2); - end; - if IsReallyNumber then - begin - if not FirstDiffBreaks then - begin - if (Cur1 <= Len1) and CharIsDigit(S1[Cur1]) then + End; + If IsReallyNumber Then + Begin + If not FirstDiffBreaks Then + Begin + If (Cur1 <= Len1) and CharIsDigit(S1[Cur1]) Then Result := 1 - else - if (Cur2 <= Len2) and CharIsDigit(S2[Cur2]) then + Else + If (Cur2 <= Len2) and CharIsDigit(S2[Cur2]) Then Result := -1; - end; - end; - end; - end; - procedure SetByCompareLength; - var + End; + End; + End; + End; + Procedure SetByCompareLength; + Var Remain1: SizeInt; Remain2: SizeInt; - begin + Begin // base result on relative compare length (spaces could be ignored, so even if S1 is longer than S2, they could be // completely equal, or S2 could be longer) Remain1 := Len1 - Cur1 + 1; Remain2 := Len2 - Cur2 + 1; - if Remain1 < 0 then + If Remain1 < 0 Then Remain1 := 0; - if Remain2 < 0 then + If Remain2 < 0 Then Remain2 := 0; - if Remain1 < Remain2 then + If Remain1 < Remain2 Then Result := -1 - else - if Remain1 > Remain2 then + Else + If Remain1 > Remain2 Then Result := 1; - end; -begin + End; +Begin Cur1 := 1; Len1 := Length(S1); Cur2 := 1; Len2 := Length(S2); Result := 0; - while (Result = 0) do - begin - if (Cur1 > Len1) or (Cur2 > Len2) then - begin + While (Result = 0) Do + Begin + If (Cur1 > Len1) or (Cur2 > Len2) Then + Begin SetByCompareLength; Break; - end - else - if (Cur1 <= Len1) and (Cur2 > Len2) then + End + Else + If (Cur1 <= Len1) and (Cur2 > Len2) Then Result := 1 - else - if (S1[Cur1] = '-') and IsRealNumberChar(S2[Cur2]) and (S2[Cur2] <> '-') then + Else + If (S1[Cur1] = '-') and IsRealNumberChar(S2[Cur2]) and (S2[Cur2] <> '-') Then Result := -1 - else - if (S2[Cur2] = '-') and IsRealNumberChar(S1[Cur1]) and (S1[Cur1] <> '-') then + Else + If (S2[Cur2] = '-') and IsRealNumberChar(S1[Cur1]) and (S1[Cur1] <> '-') Then Result := 1 - else - if (IsRealNumberChar(S1[Cur1]) or CharIsWhiteSpace(S1[Cur1])) and (IsRealNumberChar(S2[Cur2]) or CharIsWhiteSpace(S2[Cur2])) then + Else + If (IsRealNumberChar(S1[Cur1]) or CharIsWhiteSpace(S1[Cur1])) and (IsRealNumberChar(S2[Cur2]) or CharIsWhiteSpace(S2[Cur2])) Then NumberCompare - else - begin - if CaseInsensitive then + Else + Begin + If CaseInsensitive Then Result := StrLIComp(PChar(@S1[Cur1]), PChar(@S2[Cur2]), 1) - else + Else Result := StrLComp(PChar(@S1[Cur1]), PChar(@S2[Cur2]), 1); Inc(Cur1); Inc(Cur2); - end; - end; -end; + End; + End; +End; -initialization - {$IFNDEF UNICODE_RTL_DATABASE} - LoadCharTypes; // this table first - LoadCaseMap; // or this function does not work - {$ENDIF ~UNICODE_RTL_DATABASE} -end. +Initialization +{$IFNDEF UNICODE_RTL_DATABASE} + LoadCharTypes; // this table first + LoadCaseMap; // or this function does not work +{$ENDIF ~UNICODE_RTL_DATABASE} +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemTranslateString.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemTranslateString.pas index 38bb76252..a2c4b0966 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemTranslateString.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemTranslateString.pas @@ -1,31 +1,31 @@ -unit uRESTDWMemTranslateString; -{$I ..\..\Source\Includes\uRESTDWPlataform.inc} +Unit uRESTDWMemTranslateString; +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. Roniery - Devel. } -interface -uses +Interface +Uses Classes, uRESTDWBasic, uRESTDWMemResources; -type +Type /// This component is for string-replacement. All replacements are based on /// delimiter-encapsulated words. The delimiters can be freely defined. The default /// is : "%" @@ -45,13 +45,13 @@ interface /// PRODUCTVERSION : Product version of the application out of the File-Version-Information /// SCREENSIZE : Size of the screen in format widthxheight /// DESKTOPSIZE : Size of the desktop in format widthxheight - TProcessCommandEvent = procedure(Sender: TObject; const Command: string; - var CommandResult: string; var Changed: Boolean) of object; + TProcessCommandEvent = Procedure(Sender: TObject; Const Command: string; + Var CommandResult: string; Var Changed: Boolean) Of object; {$IFDEF RTL230_UP} [ComponentPlatformsAttribute(pidWin32 or pidWin64 or pidOSX32)] {$ENDIF RTL230_UP} - TJvTranslateString = class(TJvComponent) - private + TJvTranslateString = Class(TJvComponent) + Private FAppNameHandled: Boolean; FAppName: string; FCompanyNameHandled: Boolean; @@ -68,14 +68,14 @@ TJvTranslateString = class(TJvComponent) FRightDelimiter: string; FTimeFormat: string; FOnProcessCommand: TProcessCommandEvent; - procedure SetDateFormat(const Value: string); - procedure SetDateTimeFormat(const Value: string); - procedure SetTimeFormat(const Value: string); - public - constructor Create(AOwner: TComponent); override; - function TranslateString(InString: string; var Changed: Boolean): string; overload; - function TranslateString(InString: string): string; overload; - published + Procedure SetDateFormat(Const Value: string); + Procedure SetDateTimeFormat(Const Value: string); + Procedure SetTimeFormat(Const Value: string); + Public + Constructor Create(AOwner: TComponent); override; + Function TranslateString(InString: string; Var Changed: Boolean): string; overload; + Function TranslateString(InString: string): string; overload; + Published property DateFormat: string read FDateFormat write SetDateFormat; property DateSeparator: Char read FDateSeparator write FDateSeparator; property DateTimeFormat: string read FDateTimeFormat write SetDateTimeFormat; @@ -84,15 +84,15 @@ TJvTranslateString = class(TJvComponent) property TimeFormat: string read FTimeFormat write SetTimeFormat; property TimeSeparator: Char read FTimeSeparator write FTimeSeparator; property OnProcessCommand: TProcessCommandEvent read FOnProcessCommand write FOnProcessCommand; - end; -implementation -uses + End; +Implementation +Uses {$IFDEF HAS_UNIT_SYSTEM_UITYPES} System.UITypes, {$ENDIF} SysUtils, Types; -const +Const cAppNameMask = 'APPL_NAME'; cCompanyNameMask = 'COMPANY_NAME'; cDateMask = 'DATE'; @@ -110,9 +110,9 @@ implementation cDefaultAppName = 'MyJVCLApplication'; cDefaultCompanyName = 'MyCompany'; cDefaultVersion = '0.0.0.0'; -constructor TJvTranslateString.Create(AOwner: TComponent); -begin - inherited Create(AOwner); +Constructor TJvTranslateString.Create(AOwner: TComponent); +Begin + Inherited Create(AOwner); FAppNameHandled := False; FCompanyNameHandled := False; FLeftDelimiter := '%'; @@ -124,57 +124,57 @@ constructor TJvTranslateString.Create(AOwner: TComponent); FTimeSeparator := chr(255); FProductVersionHandled := False; FFileVersionHandled := False; -end; -procedure TJvTranslateString.SetDateFormat(const Value: string); -var i : Integer; -begin +End; +Procedure TJvTranslateString.SetDateFormat(Const Value: string); +Var i : Integer; +Begin FDateFormat := Value; - if DateSeparator = chr(255) then - for i := 1 to Length(Value) do - if not (Value[i] in ['0'..'9']) then - begin + If DateSeparator = chr(255) Then + For i := 1 To Length(Value) Do + If not (Value[i] in ['0'..'9']) Then + Begin DateSeparator:= Value[i]; Exit; - end; -end; -procedure TJvTranslateString.SetDateTimeFormat(const Value: string); -begin + End; +End; +Procedure TJvTranslateString.SetDateTimeFormat(Const Value: string); +Begin FDateTimeFormat := Value; -end; -procedure TJvTranslateString.SetTimeFormat(const Value: string); -var i : Integer; -begin +End; +Procedure TJvTranslateString.SetTimeFormat(Const Value: string); +Var i : Integer; +Begin FTimeFormat := Value; - if TimeSeparator = chr(255) then - for i := 1 to Length(Value) do - if not (Value[i] in ['0'..'9']) then - begin + If TimeSeparator = chr(255) Then + For i := 1 To Length(Value) Do + If not (Value[i] in ['0'..'9']) Then + Begin TimeSeparator:= Value[i]; Exit; - end; -end; -function TJvTranslateString.TranslateString(InString: string): string; -var + End; +End; +Function TJvTranslateString.TranslateString(InString: string): string; +Var I, J: Integer; Command: string; CommandResult: string; -begin +Begin Result := ''; - while InString <> '' do - begin + While InString <> '' Do + Begin I := Pos(LeftDelimiter, InString); - if I = 0 then - begin + If I = 0 Then + Begin Result := Result + InString; InString := ''; - end - else - begin + End + Else + Begin Result := Result + Copy(InString, 1, I-1); Delete(InString, 1, i); J := Pos(RightDelimiter, InString); - if J > 0 then - begin + If J > 0 Then + Begin Command := Copy(InString, 1, J-1); //TODO XyberX // if ProcessCommand(Command, CommandResult) then @@ -187,33 +187,33 @@ function TJvTranslateString.TranslateString(InString: string): string; Result := Result + Copy(InString, 1, J-1); Delete(InString, 1, J-1); // end; - end - else - begin + End + Else + Begin Result := Result + LeftDelimiter + InString; InString := ''; - end - end; - end; -end; -function TJvTranslateString.TranslateString(InString: string; var Changed: Boolean): string; -var + End + End; + End; +End; +Function TJvTranslateString.TranslateString(InString: string; Var Changed: Boolean): string; +Var I, J: Integer; Command: string; CommandResult: string; -begin +Begin Result := ''; Changed := False; - while InString <> '' do - begin + While InString <> '' Do + Begin I := Pos(LeftDelimiter, InString); - if I = 0 then - begin + If I = 0 Then + Begin Result := Result + InString; InString := ''; - end - else - begin + End + Else + Begin Result := Result + Copy(InString, 1, I-1); Delete(InString, 1, I); J := Pos(RightDelimiter, InString); @@ -230,13 +230,13 @@ function TJvTranslateString.TranslateString(InString: string; var Changed: Boole Result := Result + Copy(InString, 1, J-1); Delete(InString, 1, J-1); // end; - end; - end; -end; + End; + End; +End; {$IFDEF UNITVERSIONING} -initialization - RegisterUnitVersion(HInstance, UnitVersioning); -finalization - UnregisterUnitVersion(HInstance); +Initialization + RegisterUnitVersion(HInstance, UnitVersioning); +Finalization + UnregisterUnitVersion(HInstance); {$ENDIF UNITVERSIONING} -end. +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemTypes.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemTypes.pas index 0a520b1d8..880c04016 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemTypes.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemTypes.pas @@ -1,22 +1,22 @@ -unit uRESTDWMemTypes; +Unit uRESTDWMemTypes; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -29,10 +29,10 @@ {$MODE OBJFPC}{$H+} {$ENDIF} -uses +Uses SysUtils, Classes, uRESTDWMemResources; -const +Const MaxPixelCount = 32767; {$IFNDEF COMPILER12_UP} {$HPPEMIT '#ifndef TDate'} @@ -40,10 +40,10 @@ {$HPPEMIT '#define TTime Controls::TTime'} {$HPPEMIT '#endif'} {$ENDIF !COMPILER12_UP} -type +Type TRESTDWBytes = Pointer; IntPtr = Pointer; -type +Type {$IFNDEF FPC} {$IF (CompilerVersion >= 26) And (CompilerVersion <= 29)} {$IF Defined(HAS_FMX)} @@ -80,92 +80,92 @@ THintStringList = TStringList; { JvExVCL classes } TInputKey = (ikAll, ikArrows, ikChars, ikButton, ikTabs, ikEdit, ikNative{, ikNav, ikEsc}); - TInputKeys = set of TInputKey; - TRESTDWRGBTriple = packed record + TInputKeys = set Of TInputKey; + TRESTDWRGBTriple = packed Record rgbBlue: Byte; rgbGreen: Byte; rgbRed: Byte; - end; -const + End; +Const NullHandle = 0; // (rom) deleted fbs constants. They are already in JvConsts.pas. -type - TTimerProc = procedure(hwnd: THandle; Msg: Cardinal; idEvent: Cardinal; dwTime: Cardinal); -type +Type + TTimerProc = Procedure(hwnd: THandle; Msg: Cardinal; idEvent: Cardinal; dwTime: Cardinal); +Type // Base class for persistent properties that can show events. // By default, Delphi and BCB don't show the events of a class // derived from TPersistent unless it also derives from // TComponent. // The design time editor associated with TRESTDWPersistent will display // the events, thus mimicking a Sub Component. - TRESTDWPersistent = class(TComponent) - private + TRESTDWPersistent = Class(TComponent) + Private FOwner: TPersistent; - function _GetOwner: TPersistent; - protected - function GetOwner: TPersistent; override; - public - constructor Create(AOwner: TPersistent); reintroduce; virtual; - function GetNamePath: string; {$IFNDEF FPC}override;{$ENDIF} + Function _GetOwner: TPersistent; + Protected + Function GetOwner: TPersistent; override; + Public + Constructor Create(AOwner: TPersistent); reintroduce; virtual; + Function GetNamePath: string; {$IFNDEF FPC}override;{$ENDIF} property Owner: TPersistent read _GetOwner; - end; + End; // Added by dejoy (2005-04-20) // A lot of TRESTDWxxx control persistent properties used TPersistent, // So and a TRESTDWPersistentProperty to do this job. make to support batch-update mode // and property change notify. - TRESTDWPropertyChangeEvent = procedure(Sender: TObject; const PropName: string) of object; - TRESTDWPersistentProperty = class(TRESTDWPersistent)//TPersistent => TRESTDWPersistent - private + TRESTDWPropertyChangeEvent = Procedure(Sender: TObject; Const PropName: string) Of object; + TRESTDWPersistentProperty = Class(TRESTDWPersistent)//TPersistent => TRESTDWPersistent + Private FUpdateCount: Integer; FOnChanging: TNotifyEvent; FOnChanged: TNotifyEvent; FOnChangingProperty: TRESTDWPropertyChangeEvent; FOnChangedProperty: TRESTDWPropertyChangeEvent; - protected - procedure Changed; virtual; - procedure Changing; virtual; - procedure ChangedProperty(const PropName: string); virtual; - procedure ChangingProperty(const PropName: string); virtual; + Protected + Procedure Changed; virtual; + Procedure Changing; virtual; + Procedure ChangedProperty(Const PropName: string); virtual; + Procedure ChangingProperty(Const PropName: string); virtual; property UpdateCount: Integer read FUpdateCount; - public - procedure BeginUpdate; virtual; - procedure EndUpdate; virtual; + Public + Procedure BeginUpdate; virtual; + Procedure EndUpdate; virtual; property OnChanged: TNotifyEvent read FOnChanged write FOnChanged; property OnChanging: TNotifyEvent read FOnChanging write FOnChanging; property OnChangedProperty: TRESTDWPropertyChangeEvent read FOnChangedProperty write FOnChangedProperty; property OnChangingProperty: TRESTDWPropertyChangeEvent read FOnChangingProperty write FOnChangingProperty; - end; + End; TRESTDWRegKey = (hkClassesRoot, hkCurrentUser, hkLocalMachine, hkUsers, hkPerformanceData, hkCurrentConfig, hkDynData); - TRESTDWRegKeys = set of TRESTDWRegKey; + TRESTDWRegKeys = set Of TRESTDWRegKey; // base JVCL Exception class to derive from - EJVCLException = class(Exception); - TRESTDWLinkClickEvent = procedure(Sender: TObject; Link: string) of object; + EJVCLException = Class(Exception); + TRESTDWLinkClickEvent = Procedure(Sender: TObject; Link: string) Of object; // TOnRegistryChangeKey = procedure(Sender: TObject; RootKey: HKEY; Path: string) of object; // TAngle = 0..360; TRESTDWOutputMode = (omFile, omStream); // TLabelDirection = (sdLeftToRight, sdRightToLeft); // JvScrollingLabel - TRESTDWDoneFileEvent = procedure(Sender: TObject; FileName: string; FileSize: Integer; Url: string) of object; - TRESTDWDoneStreamEvent = procedure(Sender: TObject; Stream: TStream; StreamSize: Integer; Url: string) of object; - TRESTDWHTTPProgressEvent = procedure(Sender: TObject; UserData, Position: Integer; TotalSize: Integer; Url: string; var Continue: Boolean) of object; - TRESTDWFTPProgressEvent = procedure(Sender: TObject; Position: Integer; Url: string) of object; - TRESTDWErrorEvent = procedure(Sender: TObject; ErrorMsg: string) of object; + TRESTDWDoneFileEvent = Procedure(Sender: TObject; FileName: string; FileSize: Integer; Url: string) Of object; + TRESTDWDoneStreamEvent = Procedure(Sender: TObject; Stream: TStream; StreamSize: Integer; Url: string) Of object; + TRESTDWHTTPProgressEvent = Procedure(Sender: TObject; UserData, Position: Integer; TotalSize: Integer; Url: string; Var Continue: Boolean) Of object; + TRESTDWFTPProgressEvent = Procedure(Sender: TObject; Position: Integer; Url: string) Of object; + TRESTDWErrorEvent = Procedure(Sender: TObject; ErrorMsg: string) Of object; TRESTDWWaveLocation = (frFile, frResource, frRAM); TRESTDWPopupPosition = (ppNone, ppForm, ppApplication); - TRESTDWProgressEvent = procedure(Sender: TObject; Current, Total: Integer) of object; - TRESTDWNextPageEvent = procedure(Sender: TObject; PageNumber: Integer) of object; + TRESTDWProgressEvent = Procedure(Sender: TObject; Current, Total: Integer) Of object; + TRESTDWNextPageEvent = Procedure(Sender: TObject; PageNumber: Integer) Of object; TRESTDWBitmapStyle = (bsNormal, bsCentered, bsStretched); TRESTDWGradientStyle = (grFilled, grEllipse, grHorizontal, grVertical, grPyramid, grMount); - TRESTDWParentEvent = procedure(Sender: TObject; ParentWindow: THandle) of object; + TRESTDWParentEvent = Procedure(Sender: TObject; ParentWindow: THandle) Of object; TRESTDWDiskRes = (dsSuccess, dsCancel, dsSkipfile, dsError); TRESTDWDiskStyle = (idfCheckFirst, idfNoBeep, idfNoBrowse, idfNoCompressed, idfNoDetails, idfNoForeground, idfNoSkip, idfOemDisk, idfWarnIfSkip); - TRESTDWDiskStyles = set of TRESTDWDiskStyle; + TRESTDWDiskStyles = set Of TRESTDWDiskStyle; TRESTDWDeleteStyle = (idNoBeep, idNoForeground); - TRESTDWDeleteStyles = set of TRESTDWDeleteStyle; - TRESTDWNotifyParamsEvent = procedure(Sender: TObject; Params: Pointer) of object; + TRESTDWDeleteStyles = set Of TRESTDWDeleteStyle; + TRESTDWNotifyParamsEvent = Procedure(Sender: TObject; Params: Pointer) Of object; TRESTDWAnimation = (anLeftRight, anRightLeft, anRightAndLeft, anLeftVumeter, anRightVumeter); - TRESTDWAnimations = set of TRESTDWAnimation; + TRESTDWAnimations = set Of TRESTDWAnimation; // TOnFound = procedure(Sender: TObject; Path: string) of object; // JvSearchFile // TOnChangedDir = procedure(Sender: TObject; Directory: string) of object; // JvSearchFile // TOnAlarm = procedure(Sender: TObject; Keyword: string) of object; // JvAlarm @@ -178,13 +178,13 @@ { TAlarm = record TRESTDWTriggerKind = (tkOneShot, tkEachSecond, tkEachMinute, tkEachHour, tkEachDay, tkEachMonth, tkEachYear); // End of Bianconi - TRESTDWFourCC = array [0..3] of DWChar; + TRESTDWFourCC = array [0..3] Of DWChar; PJvAniTag = ^TRESTDWAniTag; - TRESTDWAniTag = packed record + TRESTDWAniTag = packed Record ckID: TRESTDWFourCC; ckSize: Longint; - end; - TRESTDWAniHeader = packed record + End; + TRESTDWAniHeader = packed Record dwSizeof: Longint; dwFrames: Longint; dwSteps: Longint; @@ -194,7 +194,7 @@ { TAlarm = record dwPlanes: Longint; dwJIFRate: Longint; dwFlags: Longint; - end; + End; TRESTDWLayout = (lTop, lCenter, lBottom); TRESTDWBevelStyle = (bsShape, bsLowered, bsRaised); // JvJCLUtils @@ -204,17 +204,17 @@ { TAlarm = record TCharSet = TSysCharSet; TDateOrder = (doMDY, doDMY, doYMD); TDayOfWeekName = (Sun, Mon, Tue, Wed, Thu, Fri, Sat); - TDaysOfWeek = set of TDayOfWeekName; -const + TDaysOfWeek = set Of TDayOfWeekName; +Const DefaultDateOrder = doDMY; CenturyOffset: Byte = 60; NullDate: TDateTime = 0; {-693594} -type +Type // JvDriveCtrls / JvLookOut TRESTDWImageSize = (isSmall, isLarge); TRESTDWImageAlign = (iaLeft, iaCentered); TRESTDWDriveType = (dtUnknown, dtRemovable, dtFixed, dtRemote, dtCDROM, dtRamDisk); - TRESTDWDriveTypes = set of TRESTDWDriveType; + TRESTDWDriveTypes = set Of TRESTDWDriveType; // Defines how a property (like a HotTrackFont) follows changes in the component's normal Font TRESTDWTrackFontOption = ( hoFollowFont, // makes HotTrackFont follow changes to the normal Font @@ -231,21 +231,21 @@ { TAlarm = record , hoPreserveQuality // don't change HotTrackFont.Quality {$ENDIF COMPILER15_UP} ); - TRESTDWTrackFontOptions = set of TRESTDWTrackFontOption; -const + TRESTDWTrackFontOptions = set Of TRESTDWTrackFontOption; +Const DefaultTrackFontOptions = [hoFollowFont, hoPreserveColor, hoPreserveStyle]; DefaultHotTrackColor = $00D2BDB6; DefaultHotTrackFrameColor = $006A240A; -type +Type // from JvListView.pas TRESTDWSortMethod = (smAutomatic, smAlphabetic, smNonCaseSensitive, smNumeric, smDate, smTime, smDateTime, smCurrency); - TRESTDWListViewColumnSortEvent = procedure(Sender: TObject; Column: Integer; var AMethod: TRESTDWSortMethod) of object; + TRESTDWListViewColumnSortEvent = Procedure(Sender: TObject; Column: Integer; Var AMethod: TRESTDWSortMethod) Of object; TRESTDWClickColorType = (cctColors, cctNoneColor, cctDefaultColor, cctCustomColor, cctAddInControl, cctNone); TRESTDWColorQuadLayOut = (cqlNone, cqlLeft, cqlRight, cqlClient); // from JvColorProvider.pas TColorType = (ctStandard, ctSystem, ctCustom); -const +Const ColCount = 20; StandardColCount = 40; SysColCount = 30; @@ -254,19 +254,19 @@ { TAlarm = record {$MESSAGE ERROR 'You do not have Delphi 6 Runtime Library Update 2 installed. Please install it before installing the JVCL. http://downloads.codegear.com/default.aspx?productid=300'} {$IFEND} {$ENDIF COMPILER6} -type - TRESTDWCustomThread = class(TThread) - private +Type + TRESTDWCustomThread = Class(TThread) + Private FThreadName: String; - function GetThreadName: String; virtual; - procedure SetThreadName(const Value: String); virtual; - public + Function GetThreadName: String; virtual; + Procedure SetThreadName(Const Value: String); virtual; + Public {$IFNDEF DELPHI2009UP} - procedure NameThreadForDebugging(AThreadName: DWString; AThreadID: LongWord = $FFFFFFFF); + Procedure NameThreadForDebugging(AThreadName: DWString; AThreadID: LongWord = $FFFFFFFF); {$ENDIF} - procedure NameThread(AThreadName: DWString; AThreadID: LongWord = $FFFFFFFF); {$IFDEF SUPPORTS_UNICODE_STRING} overload; {$ENDIF} virtual; + Procedure NameThread(AThreadName: DWString; AThreadID: LongWord = $FFFFFFFF); {$IFDEF SUPPORTS_UNICODE_STRING} overload; {$ENDIF} virtual; property ThreadName: String read GetThreadName write SetThreadName; - end; + End; // Using this variable you can enhance the NameThread procedure system wide by inserting a procedure // which executes for example a MadExcept TraceOut to enhance the MadExcept call stack results. // The procedure for MadExcept could look like: @@ -281,10 +281,10 @@ TRESTDWCustomThread = class(TThread) // initialization // JvTypes.JvCustomThreadNamingProc := NameThreadMadExcept; // -var - JvCustomThreadNamingProc: procedure (AThreadName: DWString; AThreadID: LongWord); +Var + JvCustomThreadNamingProc: Procedure (AThreadName: DWString; AThreadID: LongWord); {$IFDEF UNITVERSIONING} -const +Const UnitVersioning: TUnitVersionInfo = ( RCSfile: '$URL$'; Revision: '$Revision$'; @@ -292,88 +292,88 @@ TRESTDWCustomThread = class(TThread) LogPath: 'JVCL\run' ); {$ENDIF UNITVERSIONING} -implementation +Implementation { TRESTDWPersistent } -constructor TRESTDWPersistent.Create(AOwner: TPersistent); -begin - if AOwner is TComponent then - inherited Create(AOwner as TComponent) - else - inherited Create(nil); +Constructor TRESTDWPersistent.Create(AOwner: TPersistent); +Begin + If AOwner is TComponent Then + Inherited Create(AOwner as TComponent) + Else + Inherited Create(nil); SetSubComponent(True); FOwner := AOwner; -end; -type - TPersistentAccessProtected = class(TPersistent); -function TRESTDWPersistent.GetNamePath: string; -var +End; +Type + TPersistentAccessProtected = Class(TPersistent); +Function TRESTDWPersistent.GetNamePath: string; +Var S: string; lOwner: TPersistent; -begin - Result := inherited GetNamePath; +Begin + Result := Inherited GetNamePath; lOwner := GetOwner; //Resturn Nested NamePath - if (lOwner <> nil) + If (lOwner <> nil) and ( (csSubComponent in TComponent(lOwner).ComponentStyle) or (TPersistentAccessProtected(lOwner).GetOwner <> nil) ) - then - begin + Then + Begin S := lOwner.GetNamePath; - if S <> '' then + If S <> '' Then Result := S + '.' + Result; - end; -end; -function TRESTDWPersistent.GetOwner: TPersistent; -begin + End; +End; +Function TRESTDWPersistent.GetOwner: TPersistent; +Begin Result := FOwner; -end; -function TRESTDWPersistent._GetOwner: TPersistent; -begin +End; +Function TRESTDWPersistent._GetOwner: TPersistent; +Begin Result := GetOwner; -end; +End; { TRESTDWPersistentProperty } -procedure TRESTDWPersistentProperty.BeginUpdate; -begin +Procedure TRESTDWPersistentProperty.BeginUpdate; +Begin Inc(FUpdateCount); -end; -procedure TRESTDWPersistentProperty.Changed; -begin - if (FUpdateCount = 0) and Assigned(FOnChanged) then +End; +Procedure TRESTDWPersistentProperty.Changed; +Begin + If (FUpdateCount = 0) and Assigned(FOnChanged) Then FOnChanged(Self); -end; -procedure TRESTDWPersistentProperty.ChangedProperty(const PropName: string); -begin - if Assigned(FOnChangedProperty) then +End; +Procedure TRESTDWPersistentProperty.ChangedProperty(Const PropName: string); +Begin + If Assigned(FOnChangedProperty) Then FOnChangedProperty(Self, PropName); -end; -procedure TRESTDWPersistentProperty.Changing; -begin - if (FUpdateCount = 0) and Assigned(FOnChanging) then +End; +Procedure TRESTDWPersistentProperty.Changing; +Begin + If (FUpdateCount = 0) and Assigned(FOnChanging) Then FOnChanging(Self); -end; -procedure TRESTDWPersistentProperty.ChangingProperty(const PropName: string); -begin - if Assigned(FOnChangingProperty) then +End; +Procedure TRESTDWPersistentProperty.ChangingProperty(Const PropName: string); +Begin + If Assigned(FOnChangingProperty) Then FOnChangingProperty(Self, PropName); -end; -procedure TRESTDWPersistentProperty.EndUpdate; -begin +End; +Procedure TRESTDWPersistentProperty.EndUpdate; +Begin Dec(FUpdateCount); -end; +End; {$IFNDEF DELPHI2009UP} -procedure TRESTDWCustomThread.NameThreadForDebugging(AThreadName: DWString; AThreadID: LongWord = $FFFFFFFF); -type - TThreadNameInfo = record +Procedure TRESTDWCustomThread.NameThreadForDebugging(AThreadName: DWString; AThreadID: LongWord = $FFFFFFFF); +Type + TThreadNameInfo = Record FType: LongWord; // must be 0x1000 FName: PAnsiChar; // pointer to name (in user address space) FThreadID: LongWord; // thread ID (-1 indicates caller thread) FFlags: LongWord; // reserved for future use, must be zero - end; -var + End; +Var ThreadNameInfo: TThreadNameInfo; -begin +Begin //if IsDebuggerPresent then - begin + Begin ThreadNameInfo.FType := $1000; ThreadNameInfo.FName := PAnsiChar(AThreadName); ThreadNameInfo.FThreadID := AThreadID; @@ -382,29 +382,28 @@ TThreadNameInfo = record // RaiseException($406D1388, 0, SizeOf(ThreadNameInfo) div SizeOf(LongWord), @ThreadNameInfo); //except //end; - end; -end; + End; +End; {$ENDIF DELPHI2009UP} -function TRESTDWCustomThread.GetThreadName: String; -begin - if FThreadName = '' then +Function TRESTDWCustomThread.GetThreadName: String; +Begin + If FThreadName = '' Then Result := ClassName - else + Else Result := FThreadName+' {'+ClassName+'}'; -end; -procedure TRESTDWCustomThread.NameThread(AThreadName: DWString; AThreadID: LongWord = $FFFFFFFF); -begin - if AThreadID = $FFFFFFFF then +End; +Procedure TRESTDWCustomThread.NameThread(AThreadName: DWString; AThreadID: LongWord = $FFFFFFFF); +Begin + If AThreadID = $FFFFFFFF Then AThreadID := ThreadID; NameThreadForDebugging(aThreadName, AThreadID); - if Assigned(JvCustomThreadNamingProc) then + If Assigned(JvCustomThreadNamingProc) Then JvCustomThreadNamingProc(aThreadName, AThreadID); -end; +End; -procedure TRESTDWCustomThread.SetThreadName(const Value: String); -begin +Procedure TRESTDWCustomThread.SetThreadName(Const Value: String); +Begin FThreadName := Value; -end; - -end. +End; +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemVCLUtils.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemVCLUtils.pas index eb7bee29a..24b9cadfe 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemVCLUtils.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemVCLUtils.pas @@ -1,29 +1,29 @@ -unit uRESTDWMemVCLUtils; -{$I ..\..\Includes\uRESTDW.inc} +Unit uRESTDWMemVCLUtils; +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. Roniery - Devel. } -interface +Interface -uses +Uses Variants, {$IFDEF MSWINDOWS} Windows, Messages, @@ -37,7 +37,7 @@ interface uRESTDWMemBase, uRESTDWMemTypes; -const +Const MB_OK = $00000000; MB_OKCANCEL = $00000001; MB_ABORTRETRYIGNORE = $00000002; @@ -55,84 +55,84 @@ interface MB_ICONSTOP = MB_ICONHAND; -function MsgBox(Handle: THandle; const Caption, Text: string; Flags: Integer): Integer; overload; +Function MsgBox(Handle: THandle; Const Caption, Text: string; Flags: Integer): Integer; overload; // returns True if user clicked Yes -function MsgYesNo(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Boolean; +Function MsgYesNo(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0): Boolean; // returns True if user clicked Retry -function MsgRetryCancel(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Boolean; +Function MsgRetryCancel(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0): Boolean; // returns IDABORT, IDRETRY or IDIGNORE -function MsgAbortRetryIgnore(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Integer; +Function MsgAbortRetryIgnore(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0): Integer; // returns IDYES, IDNO or IDCANCEL -function MsgYesNoCancel(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Integer; +Function MsgYesNoCancel(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0): Integer; // returns True if user clicked OK -function MsgOKCancel(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Boolean; +Function MsgOKCancel(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0): Boolean; // dialog without icon -procedure MsgOK(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0); +Procedure MsgOK(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0); // dialog with info icon -procedure MsgInfo(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0); +Procedure MsgInfo(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0); // dialog with warning icon -procedure MsgWarn(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0); +Procedure MsgWarn(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0); // dialog with question icon -procedure MsgQuestion(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0); +Procedure MsgQuestion(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0); // dialog with error icon -procedure MsgError(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0); +Procedure MsgError(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0); -implementation +Implementation -function MsgBox(Handle: THandle; const Caption, Text: string; Flags: Integer): Integer; -begin +Function MsgBox(Handle: THandle; Const Caption, Text: string; Flags: Integer): Integer; +Begin {$IFDEF MSWINDOWS} Result := Windows.MessageBox(Handle, PChar(Text), PChar(Caption), Flags); {$ENDIF MSWINDOWS} {$IFDEF UNIX} Result := MsgBox(Caption, Text, Flags); {$ENDIF UNIX} -end; -function MsgYesNo(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Boolean; -begin +End; +Function MsgYesNo(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0): Boolean; +Begin {$IFNDEF LINUX} Result := MsgBox(Handle, Caption, Msg, MB_YESNO or Flags) = IDYES; {$ENDIF} -end; -function MsgRetryCancel(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Boolean; -begin +End; +Function MsgRetryCancel(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0): Boolean; +Begin {$IFNDEF LINUX} Result := MsgBox(Handle, Caption, Msg, MB_RETRYCANCEL or Flags) = IDRETRY; {$ENDIF} -end; -function MsgAbortRetryIgnore(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Integer; -begin +End; +Function MsgAbortRetryIgnore(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0): Integer; +Begin Result := MsgBox(Handle, Caption, Msg, MB_ABORTRETRYIGNORE or Flags); -end; -function MsgYesNoCancel(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Integer; -begin +End; +Function MsgYesNoCancel(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0): Integer; +Begin Result := MsgBox(Handle, Caption, Msg, MB_YESNOCANCEL or Flags); -end; -function MsgOKCancel(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Boolean; -begin +End; +Function MsgOKCancel(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0): Boolean; +Begin {$IFNDEF LINUX} Result := MsgBox(Handle, Caption, Msg, MB_OKCANCEL or Flags) = IDOK; {$ENDIF} -end; -procedure MsgOK(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0); -begin +End; +Procedure MsgOK(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0); +Begin MsgBox(Handle, Caption, Msg, MB_OK or Flags); -end; -procedure MsgInfo(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0); -begin +End; +Procedure MsgInfo(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0); +Begin MsgOK(Handle, Msg, Caption, MB_ICONINFORMATION or Flags); -end; -procedure MsgWarn(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0); -begin +End; +Procedure MsgWarn(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0); +Begin MsgOK(Handle, Msg, Caption, MB_ICONWARNING or Flags); -end; -procedure MsgQuestion(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0); -begin +End; +Procedure MsgQuestion(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0); +Begin MsgOK(Handle, Msg, Caption, MB_ICONQUESTION or Flags); -end; -procedure MsgError(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0); -begin +End; +Procedure MsgError(Handle: Integer; Const Msg, Caption: string; Flags: DWORD = 0); +Begin MsgOK(Handle, Msg, Caption, MB_ICONERROR or Flags); -end; +End; -end. +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemWideStrings.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemWideStrings.pas index 1290342f8..e8d4e278e 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemWideStrings.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemWideStrings.pas @@ -1,21 +1,21 @@ -unit uRESTDWMemWideStrings; +Unit uRESTDWMemWideStrings; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -27,8 +27,8 @@ {$ASMMode Intel} {$ENDIF} -interface -uses +Interface +Uses {$IFDEF UNITVERSIONING} JclUnitVersioning, {$ENDIF UNITVERSIONING} @@ -40,9 +40,9 @@ interface uRESTDWMemBase, uRESTDWProtoTypes; // Exceptions -type - EJclWideStringError = class(EJclError); -const +Type + EJclWideStringError = Class(EJclError); +Const // definitions of often used characters: // Note: Use them only for tests of a certain character not to determine character // classes (like white spaces) as in Unicode are often many code points defined @@ -69,7 +69,7 @@ EJclWideStringError = class(EJclError); {$ENDIF UNIX} BOM_LSB_FIRST = DWChar($FEFF); BOM_MSB_FIRST = DWChar($FFFE); -type +Type {$IFDEF SUPPORTS_UNICODE} TJclWideStrings = {$IFDEF HAS_UNITSCOPE}System.{$ENDIF}Classes.TStrings; TJclWideStringList = {$IFDEF HAS_UNITSCOPE}System.{$ENDIF}Classes.TStringList; @@ -79,7 +79,7 @@ EJclWideStringError = class(EJclError); foAnsiFile, // loads/writes an ANSI file foUnicodeLB // reads/writes BOM_LSB_FIRST/BOM_MSB_FIRST ); - TWideFileOptions = set of TWideFileOptionsType; + TWideFileOptions = set Of TWideFileOptionsType; TSearchFlag = ( sfCaseSensitive, // match letter case sfIgnoreNonSpacing, // ignore non-spacing characters in search @@ -87,61 +87,61 @@ EJclWideStringError = class(EJclError); // (this applies to the pattern as well as the search text) sfWholeWordOnly // match only text at end/start and/or surrounded by white spaces ); - TSearchFlags = set of TSearchFlag; - TJclWideStrings = class; - TJclWideStringList = class; - TJclWideStringListSortCompare = function(List: TJclWideStringList; Index1, Index2: Integer): Integer; - TJclWideStrings = class(TPersistent) - private + TSearchFlags = set Of TSearchFlag; + TJclWideStrings = Class; + TJclWideStringList = Class; + TJclWideStringListSortCompare = Function(List: TJclWideStringList; Index1, Index2: Integer): Integer; + TJclWideStrings = Class(TPersistent) + Private FDelimiter: Char; FQuoteChar: Char; FNameValueSeparator: Char; FLineSeparator: DWWideString; FUpdateCount: Integer; - procedure ReadData(Reader: TReader); - procedure WriteData(Writer: TWriter); - protected - procedure DefineProperties(Filer: TFiler); override; - function GetP(Index: Integer): PString; virtual; abstract; - function Get(Index: Integer): DWWideString; - function GetCapacity: Integer; virtual; - function GetCount: Integer; virtual; abstract; - function GetObject(Index: Integer): TObject; virtual; - function GetTextStr: DWWideString; virtual; - procedure Put(Index: Integer; const S: DWWideString); virtual; abstract; - procedure PutObject(Index: Integer; AObject: TObject); virtual; abstract; - procedure SetCapacity(NewCapacity: Integer); virtual; - procedure SetTextStr(const Value: DWWideString); virtual; - procedure SetUpdateState(Updating: Boolean); virtual; + Procedure ReadData(Reader: TReader); + Procedure WriteData(Writer: TWriter); + Protected + Procedure DefineProperties(Filer: TFiler); override; + Function GetP(Index: Integer): PString; virtual; abstract; + Function Get(Index: Integer): DWWideString; + Function GetCapacity: Integer; virtual; + Function GetCount: Integer; virtual; abstract; + Function GetObject(Index: Integer): TObject; virtual; + Function GetTextStr: DWWideString; virtual; + Procedure Put(Index: Integer; Const S: DWWideString); virtual; abstract; + Procedure PutObject(Index: Integer; AObject: TObject); virtual; abstract; + Procedure SetCapacity(NewCapacity: Integer); virtual; + Procedure SetTextStr(Const Value: DWWideString); virtual; + Procedure SetUpdateState(Updating: Boolean); virtual; property UpdateCount: Integer read FUpdateCount; - procedure AssignTo(Dest: TPersistent); override; - public - constructor Create; - function Add(const S: DWWideString): Integer; virtual; - function AddObject(const S: DWWideString; AObject: TObject): Integer; virtual; - procedure Append(const S: DWWideString); - procedure AddStrings(Strings: TJclWideStrings); overload; virtual; - procedure AddStrings(Strings: TStrings); overload; virtual; - procedure Assign(Source: TPersistent); override; - function CreateAnsiStringList: TStrings; - procedure AddStringsTo(Dest: TStrings); virtual; - procedure BeginUpdate; - procedure Clear; virtual; abstract; - procedure Delete(Index: Integer); virtual; abstract; - procedure EndUpdate; - function Equals(Strings: TJclWideStrings): Boolean; {$IFDEF RTL200_UP}reintroduce; {$ENDIF RTL200_UP}overload; - function Equals(Strings: TStrings): Boolean; {$IFDEF RTL200_UP}reintroduce; {$ENDIF RTL200_UP}overload; - procedure Exchange(Index1, Index2: Integer); virtual; - function IndexOfObject(AObject: TObject): Integer; virtual; - procedure Insert(Index: Integer; const S: DWWideString); virtual; - procedure InsertObject(Index: Integer; const S: DWWideString; + Procedure AssignTo(Dest: TPersistent); override; + Public + Constructor Create; + Function Add(Const S: DWWideString): Integer; virtual; + Function AddObject(Const S: DWWideString; AObject: TObject): Integer; virtual; + Procedure Append(Const S: DWWideString); + Procedure AddStrings(Strings: TJclWideStrings); overload; virtual; + Procedure AddStrings(Strings: TStrings); overload; virtual; + Procedure Assign(Source: TPersistent); override; + Function CreateAnsiStringList: TStrings; + Procedure AddStringsTo(Dest: TStrings); virtual; + Procedure BeginUpdate; + Procedure Clear; virtual; abstract; + Procedure Delete(Index: Integer); virtual; abstract; + Procedure EndUpdate; + Function Equals(Strings: TJclWideStrings): Boolean; {$IFDEF RTL200_UP}reintroduce; {$ENDIF RTL200_UP}overload; + Function Equals(Strings: TStrings): Boolean; {$IFDEF RTL200_UP}reintroduce; {$ENDIF RTL200_UP}overload; + Procedure Exchange(Index1, Index2: Integer); virtual; + Function IndexOfObject(AObject: TObject): Integer; virtual; + Procedure Insert(Index: Integer; Const S: DWWideString); virtual; + Procedure InsertObject(Index: Integer; Const S: DWWideString; AObject: TObject); virtual; - procedure Move(CurIndex, NewIndex: Integer); virtual; - procedure SaveToFile(const FileName: TFileName; + Procedure Move(CurIndex, NewIndex: Integer); virtual; + Procedure SaveToFile(Const FileName: TFileName; WideFileOptions: TWideFileOptions = []); virtual; - procedure SaveToStream(Stream: TStream; + Procedure SaveToStream(Stream: TStream; WideFileOptions: TWideFileOptions = []); virtual; - procedure SetText(Text: PDWChar); virtual; + Procedure SetText(Text: PDWChar); virtual; property Capacity: Integer read GetCapacity write SetCapacity; property Count: Integer read GetCount; property Delimiter: Char read FDelimiter write FDelimiter; @@ -152,47 +152,47 @@ TJclWideStrings = class(TPersistent) property PStrings[Index: Integer]: PString read GetP; property Strings[Index: Integer]: DWWideString read Get write Put; default; property Text: DWWideString read GetTextStr write SetTextStr; - end; + End; // do not replace by JclUnicode.TWideStringList (speed and size issue) PWStringItem = ^TWStringItem; - TWStringItem = record + TWStringItem = Record FString: DWWideString; FObject: TObject; - end; - TJclWideStringList = class(TJclWideStrings) - private + End; + TJclWideStringList = Class(TJclWideStrings) + Private FList: TList; FSorted: Boolean; FDuplicates: TDuplicates; FCaseSensitive: Boolean; FOnChange: TNotifyEvent; FOnChanging: TNotifyEvent; - protected - function GetItem(Index: Integer): PWStringItem; - procedure Changed; virtual; - procedure Changing; virtual; - function GetP(Index: Integer): PString; override; - function GetCapacity: Integer; override; - function GetCount: Integer; override; - function GetObject(Index: Integer): TObject; override; - procedure Put(Index: Integer; const Value: DWWideString); override; - procedure PutObject(Index: Integer; AObject: TObject); override; - procedure SetCapacity(NewCapacity: Integer); override; - procedure SetUpdateState(Updating: Boolean); override; - public - constructor Create; - destructor Destroy; override; - procedure Clear; override; - procedure Delete(Index: Integer); override; - procedure Exchange(Index1, Index2: Integer); override; + Protected + Function GetItem(Index: Integer): PWStringItem; + Procedure Changed; virtual; + Procedure Changing; virtual; + Function GetP(Index: Integer): PString; override; + Function GetCapacity: Integer; override; + Function GetCount: Integer; override; + Function GetObject(Index: Integer): TObject; override; + Procedure Put(Index: Integer; Const Value: DWWideString); override; + Procedure PutObject(Index: Integer; AObject: TObject); override; + Procedure SetCapacity(NewCapacity: Integer); override; + Procedure SetUpdateState(Updating: Boolean); override; + Public + Constructor Create; + Destructor Destroy; override; + Procedure Clear; override; + Procedure Delete(Index: Integer); override; + Procedure Exchange(Index1, Index2: Integer); override; // Find() also works with unsorted lists - procedure InsertObject(Index: Integer; const S: DWWideString; + Procedure InsertObject(Index: Integer; Const S: DWWideString; AObject: TObject); override; - procedure CustomSort(Compare: TJclWideStringListSortCompare); virtual; + Procedure CustomSort(Compare: TJclWideStringListSortCompare); virtual; property Duplicates: TDuplicates read FDuplicates write FDuplicates; property OnChange: TNotifyEvent read FOnChange write FOnChange; property OnChanging: TNotifyEvent read FOnChanging write FOnChanging; - end; + End; {$ENDIF ~SUPPORTS_UNICODE} TWideStringList = TJclWideStringList; TWideStrings = TJclWideStrings; @@ -202,41 +202,41 @@ TJclWideStringList = class(TJclWideStrings) TWStringList = TJclWideStringList; TWStrings = TJclWideStrings; // DWChar functions -function CharToWideChar(Ch: DWChar): DWChar; -function DWCharToChar(Ch: DWChar): DWChar; +Function CharToWideChar(Ch: DWChar): DWChar; +Function DWCharToChar(Ch: DWChar): DWChar; // PDWChar functions -procedure MoveWideChar(const Source; var Dest; Count: SizeInt); -function StrEndW(const Str: PDWChar): PDWChar; -function StrMoveW(Dest: PDWChar; const Source: PDWChar; Count: SizeInt): PDWChar; -function StrCopyW(Dest: PDWChar; const Source: PDWChar): PDWChar; -function StrECopyW(Dest: PDWChar; const Source: PDWChar): PDWChar; -function StrLCopyW(Dest: PDWChar; const Source: PDWChar; MaxLen: SizeInt): PDWChar; -function StrPCopyWW(Dest: PDWChar; const Source: DWWideString): PDWChar; -function StrPLCopyWW(Dest: PDWChar; const Source: DWWideString; MaxLen: SizeInt): PDWChar; -function StrCatW(Dest: PDWChar; const Source: PDWChar): PDWChar; -function StrLCatW(Dest: PDWChar; const Source: PDWChar; MaxLen: SizeInt): PDWChar; -function StrScanW(const Str: PDWChar; Ch: DWChar): PDWChar; overload; -function StrScanW(Str: PDWChar; Chr: DWChar; StrLen: SizeInt): PDWChar; overload; -function StrRScanW(const Str: PDWChar; Chr: DWChar): PDWChar; -function StrAllocW(WideSize: SizeInt): PDWChar; -function StrBufSizeW(const Str: PDWChar): SizeInt; -procedure StrDisposeW(Str: PDWChar); -procedure StrDisposeAndNilW(var Str: PDWChar); +Procedure MoveWideChar(Const Source; Var Dest; Count: SizeInt); +Function StrEndW(Const Str: PDWChar): PDWChar; +Function StrMoveW(Dest: PDWChar; Const Source: PDWChar; Count: SizeInt): PDWChar; +Function StrCopyW(Dest: PDWChar; Const Source: PDWChar): PDWChar; +Function StrECopyW(Dest: PDWChar; Const Source: PDWChar): PDWChar; +Function StrLCopyW(Dest: PDWChar; Const Source: PDWChar; MaxLen: SizeInt): PDWChar; +Function StrPCopyWW(Dest: PDWChar; Const Source: DWWideString): PDWChar; +Function StrPLCopyWW(Dest: PDWChar; Const Source: DWWideString; MaxLen: SizeInt): PDWChar; +Function StrCatW(Dest: PDWChar; Const Source: PDWChar): PDWChar; +Function StrLCatW(Dest: PDWChar; Const Source: PDWChar; MaxLen: SizeInt): PDWChar; +Function StrScanW(Const Str: PDWChar; Ch: DWChar): PDWChar; overload; +Function StrScanW(Str: PDWChar; Chr: DWChar; StrLen: SizeInt): PDWChar; overload; +Function StrRScanW(Const Str: PDWChar; Chr: DWChar): PDWChar; +Function StrAllocW(WideSize: SizeInt): PDWChar; +Function StrBufSizeW(Const Str: PDWChar): SizeInt; +Procedure StrDisposeW(Str: PDWChar); +Procedure StrDisposeAndNilW(Var Str: PDWChar); // DWWideString functions -function WideUpperCase(const S: DWWideString): DWWideString; -function WideLowerCase(const S: DWWideString): DWWideString; -function TrimW(const S: DWWideString): DWWideString; -function TrimLeftW(const S: DWWideString): DWWideString; -function TrimRightW(const S: DWWideString): DWWideString; -function TrimLeftLengthW(const S: DWWideString): SizeInt; -function TrimRightLengthW(const S: DWWideString): SizeInt; +Function WideUpperCase(Const S: DWWideString): DWWideString; +Function WideLowerCase(Const S: DWWideString): DWWideString; +Function TrimW(Const S: DWWideString): DWWideString; +Function TrimLeftW(Const S: DWWideString): DWWideString; +Function TrimRightW(Const S: DWWideString): DWWideString; +Function TrimLeftLengthW(Const S: DWWideString): SizeInt; +Function TrimRightLengthW(Const S: DWWideString): SizeInt; // MultiSz Routines -type +Type PWideMultiSz = PDWChar; -procedure AllocateMultiSz(var Dest: PWideMultiSz; Len: SizeInt); -procedure FreeMultiSz(var Dest: PWideMultiSz); -implementation -uses +Procedure AllocateMultiSz(Var Dest: PWideMultiSz; Len: SizeInt); +Procedure FreeMultiSz(Var Dest: PWideMultiSz); +Implementation +Uses {$IFDEF HAS_UNITSCOPE} {$IFDEF HAS_UNIT_RTLCONSTS} System.RTLConsts, @@ -257,78 +257,78 @@ implementation uRESTDWMemResources, uRESTDWConsts; -procedure SwapWordByteOrder(P: PDWChar; Len: SizeInt); -begin - while Len > 0 do - begin +Procedure SwapWordByteOrder(P: PDWChar; Len: SizeInt); +Begin + While Len > 0 Do + Begin Dec(Len); P^ := DWChar((Word(P^) shr 8) or (Word(P^) shl 8)); Inc(P); - end; -end; + End; +End; //=== DWChar functions ===================================================== -function CharToWideChar(Ch: DWChar): DWChar; -var +Function CharToWideChar(Ch: DWChar): DWChar; +Var WS: DWWideString; -begin +Begin WS := DWChar(Ch); Result := DWChar(WS[1]); -end; -function DWCharToChar(Ch: DWChar): DWChar; -var +End; +Function DWCharToChar(Ch: DWChar): DWChar; +Var S: DWWideString; -begin +Begin S := Ch; Result := DWChar(S[1]); -end; +End; //=== PDWChar functions ==================================================== -procedure MoveWideChar(const Source; var Dest; Count: SizeInt); -begin +Procedure MoveWideChar(Const Source; Var Dest; Count: SizeInt); +Begin Move(Source, Dest, Count * SizeOf(WideChar)); -end; -function StrAllocW(WideSize: SizeInt): PDWChar; -begin +End; +Function StrAllocW(WideSize: SizeInt): PDWChar; +Begin WideSize := SizeOf(WideChar) * WideSize + SizeOf(SizeInt); Result := AllocMem(WideSize); SizeInt(Pointer(Result)^) := WideSize; Inc(Result, SizeOf(SizeInt) div SizeOf(WideChar)); -end; -procedure StrDisposeW(Str: PDWChar); +End; +Procedure StrDisposeW(Str: PDWChar); // releases a string allocated with StrNewW or StrAllocW -begin - if Str <> nil then - begin +Begin + If Str <> nil Then + Begin Dec(Str, SizeOf(SizeInt) div SizeOf(WideChar)); FreeMem(Str); - end; -end; -procedure StrDisposeAndNilW(var Str: PDWChar); -var + End; +End; +Procedure StrDisposeAndNilW(Var Str: PDWChar); +Var Buff: PDWChar; -begin +Begin Buff := Str; Str := nil; StrDisposeW(Buff); -end; -const +End; +Const // data used to bring UTF-16 coded strings into correct UTF-32 order for correct comparation - UTF16Fixup: array [0..31] of Word = ( + UTF16Fixup: array [0..31] Of Word = ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, $2000, $F800, $F800, $F800, $F800 ); -function StrLCompW(const Str1, Str2: PDWChar; MaxLen: SizeInt): SizeInt; +Function StrLCompW(Const Str1, Str2: PDWChar; MaxLen: SizeInt): SizeInt; // compares strings up to MaxLen code points // see also StrCompW -var +Var S1, S2: PDWChar; C1, C2: Word; -begin - if MaxLen > 0 then - begin +Begin + If MaxLen > 0 Then + Begin S1 := Str1; S2 := Str2; - repeat + Repeat C1 := Word(S1^); C1 := Word(C1 or UTF16Fixup[C1 shr 11]); C2 := Word(S2^); @@ -337,260 +337,260 @@ function StrLCompW(const Str1, Str2: PDWChar; MaxLen: SizeInt): SizeInt; { TODO : surrogates take up 2 words and are counted twice here, count them only once } Result := SizeInt(C1) - SizeInt(C2); Dec(MaxLen); - if(Result <> 0) or (C1 = 0) or (C2 = 0) or (MaxLen = 0) then + If(Result <> 0) or (C1 = 0) or (C2 = 0) or (MaxLen = 0) Then Break; Inc(S1); Inc(S2); - until False; - end - else + Until False; + End + Else Result := 0; -end; -function StrScanW(const Str: PDWChar; Ch: DWChar): PDWChar; -begin +End; +Function StrScanW(Const Str: PDWChar; Ch: DWChar): PDWChar; +Begin Result := Str; - if Result <> nil then - begin - while (Result^ <> #0) and (Result^ <> Ch) do + If Result <> nil Then + Begin + While (Result^ <> #0) and (Result^ <> Ch) Do Inc(Result); - if (Result^ = #0) and (Ch <> #0) then + If (Result^ = #0) and (Ch <> #0) Then Result := nil; - end; -end; -function StrEndW(const Str: PDWChar): PDWChar; -begin + End; +End; +Function StrEndW(Const Str: PDWChar): PDWChar; +Begin Result := Str; - if Result <> nil then - while Result^ <> #0 do + If Result <> nil Then + While Result^ <> #0 Do Inc(Result); -end; -function StrCopyW(Dest: PDWChar; const Source: PDWChar): PDWChar; -var +End; +Function StrCopyW(Dest: PDWChar; Const Source: PDWChar): PDWChar; +Var Src: PDWChar; -begin +Begin Result := Dest; - if Dest <> nil then - begin + If Dest <> nil Then + Begin Src := Source; - if Src <> nil then - while Src^ <> #0 do - begin + If Src <> nil Then + While Src^ <> #0 Do + Begin Dest^ := Src^; Inc(Src); Inc(Dest); - end; + End; Dest^ := #0; - end; -end; -function StrECopyW(Dest: PDWChar; const Source: PDWChar): PDWChar; -var + End; +End; +Function StrECopyW(Dest: PDWChar; Const Source: PDWChar): PDWChar; +Var Src: PDWChar; -begin - if Dest <> nil then - begin +Begin + If Dest <> nil Then + Begin Src := Source; - if Src <> nil then - while Src^ <> #0 do - begin + If Src <> nil Then + While Src^ <> #0 Do + Begin Dest^ := Src^; Inc(Src); Inc(Dest); - end; + End; Dest^ := #0; - end; + End; Result := Dest; -end; -function StrLCopyW(Dest: PDWChar; const Source: PDWChar; MaxLen: SizeInt): PDWChar; -var +End; +Function StrLCopyW(Dest: PDWChar; Const Source: PDWChar; MaxLen: SizeInt): PDWChar; +Var Src: PDWChar; -begin +Begin Result := Dest; - if (Dest <> nil) and (MaxLen > 0) then - begin + If (Dest <> nil) and (MaxLen > 0) Then + Begin Src := Source; - if Src <> nil then - while (MaxLen > 0) and (Src^ <> #0) do - begin + If Src <> nil Then + While (MaxLen > 0) and (Src^ <> #0) Do + Begin Dest^ := Src^; Inc(Src); Inc(Dest); Dec(MaxLen); - end; + End; Dest^ := #0; - end; -end; -function StrCatW(Dest: PDWChar; const Source: PDWChar): PDWChar; -begin + End; +End; +Function StrCatW(Dest: PDWChar; Const Source: PDWChar): PDWChar; +Begin Result := Dest; StrCopyW(StrEndW(Dest), Source); -end; -function StrLCatW(Dest: PDWChar; const Source: PDWChar; MaxLen: SizeInt): PDWChar; -begin +End; +Function StrLCatW(Dest: PDWChar; Const Source: PDWChar; MaxLen: SizeInt): PDWChar; +Begin Result := Dest; StrLCopyW(StrEndW(Dest), Source, MaxLen); -end; -function StrMoveW(Dest: PDWChar; const Source: PDWChar; Count: SizeInt): PDWChar; -begin +End; +Function StrMoveW(Dest: PDWChar; Const Source: PDWChar; Count: SizeInt): PDWChar; +Begin Result := Dest; - if Count > 0 then + If Count > 0 Then Move(Source^, Dest^, Count * SizeOf(WideChar)); -end; -function StrPCopyWW(Dest: PDWChar; const Source: DWWideString): PDWChar; -begin +End; +Function StrPCopyWW(Dest: PDWChar; Const Source: DWWideString): PDWChar; +Begin Result := StrLCopyW(Dest, PDWChar(Source), Length(Source)); -end; -function StrPLCopyWW(Dest: PDWChar; const Source: DWWideString; MaxLen: SizeInt): PDWChar; -begin +End; +Function StrPLCopyWW(Dest: PDWChar; Const Source: DWWideString; MaxLen: SizeInt): PDWChar; +Begin Result := StrLCopyW(Dest, PDWChar(Source), MaxLen); -end; -function StrRScanW(const Str: PDWChar; Chr: DWChar): PDWChar; -var +End; +Function StrRScanW(Const Str: PDWChar; Chr: DWChar): PDWChar; +Var P: PDWChar; -begin +Begin Result := nil; - if Str <> nil then - begin + If Str <> nil Then + Begin P := Str; - repeat - if P^ = Chr then + Repeat + If P^ = Chr Then Result := P; Inc(P); - until P^ = #0; - end; -end; + Until P^ = #0; + End; +End; // Returns a pointer to first occurrence of a specified character in a string // or nil if not found. // Note: this is just a binary search for the specified character and there's no // check for a terminating null. Instead at most StrLen characters are // searched. This makes this function extremly fast. // -function StrScanW(Str: PDWChar; Chr: DWChar; StrLen: SizeInt): PDWChar; -begin +Function StrScanW(Str: PDWChar; Chr: DWChar; StrLen: SizeInt): PDWChar; +Begin Result := Str; - while StrLen > 0 do - begin - if Result^ = Chr then + While StrLen > 0 Do + Begin + If Result^ = Chr Then Exit; Inc(Result); - end; + End; Result := nil; -end; -function StrBufSizeW(const Str: PDWChar): SizeInt; +End; +Function StrBufSizeW(Const Str: PDWChar): SizeInt; // Returns max number of wide characters that can be stored in a buffer // allocated by StrAllocW. -var +Var P: PDWChar; -begin - if Str <> nil then - begin +Begin + If Str <> nil Then + Begin P := Str; Dec(P, SizeOf(SizeInt) div SizeOf(WideChar)); Result := (PSizeInt(P)^ - SizeOf(SizeInt)) div SizeOf(WideChar); - end - else + End + Else Result := 0; -end; +End; -function TrimW(const S: DWWideString): DWWideString; +Function TrimW(Const S: DWWideString): DWWideString; // available from Delphi 7 up {$IFDEF RTL150_UP} -begin +Begin Result := Trim(S); -end; +End; {$ELSE ~RTL150_UP} -var +Var I, L: SizeInt; -begin +Begin L := Length(S); I := 1; - while (I <= L) and (S[I] <= ' ') do + While (I <= L) and (S[I] <= ' ') Do Inc(I); - if I > L then + If I > L Then Result := '' - else - begin - while S[L] <= ' ' do + Else + Begin + While S[L] <= ' ' Do Dec(L); Result := Copy(S, I, L - I + 1); - end; -end; + End; +End; {$ENDIF ~RTL150_UP} -function TrimLeftW(const S: DWWideString): DWWideString; +Function TrimLeftW(Const S: DWWideString): DWWideString; // available from Delphi 7 up {$IFDEF RTL150_UP} -begin +Begin Result := TrimLeft(S); -end; +End; {$ELSE ~RTL150_UP} -var +Var I, L: SizeInt; -begin +Begin L := Length(S); I := 1; - while (I <= L) and (S[I] <= ' ') do + While (I <= L) and (S[I] <= ' ') Do Inc(I); Result := Copy(S, I, Maxint); -end; +End; {$ENDIF ~RTL150_UP} -function TrimRightW(const S: DWWideString): DWWideString; +Function TrimRightW(Const S: DWWideString): DWWideString; // available from Delphi 7 up {$IFDEF RTL150_UP} -begin +Begin Result := TrimRight(S); -end; +End; {$ELSE ~RTL150_UP} -var +Var I: SizeInt; -begin +Begin I := Length(S); - while (I > 0) and (S[I] <= ' ') do + While (I > 0) and (S[I] <= ' ') Do Dec(I); Result := Copy(S, 1, I); -end; +End; {$ENDIF ~RTL150_UP} -function WideUpperCase(const S: DWWideString): DWWideString; -begin +Function WideUpperCase(Const S: DWWideString): DWWideString; +Begin Result := S; - if Result <> '' then + If Result <> '' Then {$IFDEF MSWINDOWS} CharUpperBuffW(Pointer(Result), Length(Result)); {$ELSE ~MSWINDOWS} { TODO : Don't cheat here } Result := UpperCase(Result); {$ENDIF ~MSWINDOWS} -end; -function WideLowerCase(const S: DWWideString): DWWideString; -begin +End; +Function WideLowerCase(Const S: DWWideString): DWWideString; +Begin Result := S; - if Result <> '' then + If Result <> '' Then {$IFDEF MSWINDOWS} CharLowerBuffW(Pointer(Result), Length(Result)); {$ELSE ~MSWINDOWS} { TODO : Don't cheat here } Result := LowerCase(Result); {$ENDIF ~MSWINDOWS} -end; -function TrimLeftLengthW(const S: DWWideString): SizeInt; -var +End; +Function TrimLeftLengthW(Const S: DWWideString): SizeInt; +Var Len: SizeInt; -begin +Begin Len := Length(S); Result := 1; - while (Result <= Len) and (S[Result] <= #32) do + While (Result <= Len) and (S[Result] <= #32) Do Inc(Result); Result := Len - Result + 1; -end; -function TrimRightLengthW(const S: DWWideString): SizeInt; -begin +End; +Function TrimRightLengthW(Const S: DWWideString): SizeInt; +Begin Result := Length(S); - while (Result > 0) and (S[Result] <= #32) do + While (Result > 0) and (S[Result] <= #32) Do Dec(Result); -end; +End; {$IFNDEF SUPPORTS_UNICODE} //=== { TJclWideStrings } ========================================================== -constructor TJclWideStrings.Create; -begin - inherited Create; +Constructor TJclWideStrings.Create; +Begin + Inherited Create; // FLineSeparator := DWChar($2028); {$IFDEF MSWINDOWS} FLineSeparator := DWChar(13) + '' + DWChar(10); // compiler wants it this way @@ -601,61 +601,61 @@ constructor TJclWideStrings.Create; FNameValueSeparator := '='; FDelimiter := ','; FQuoteChar := '"'; -end; -function TJclWideStrings.Add(const S: DWWideString): Integer; -begin +End; +Function TJclWideStrings.Add(Const S: DWWideString): Integer; +Begin Result := AddObject(S, nil); -end; -function TJclWideStrings.AddObject(const S: DWWideString; AObject: TObject): Integer; -begin +End; +Function TJclWideStrings.AddObject(Const S: DWWideString; AObject: TObject): Integer; +Begin Result := Count; InsertObject(Result, S, AObject); -end; -procedure TJclWideStrings.AddStrings(Strings: TJclWideStrings); -var +End; +Procedure TJclWideStrings.AddStrings(Strings: TJclWideStrings); +Var I: Integer; -begin - for I := 0 to Strings.Count - 1 do +Begin + For I := 0 To Strings.Count - 1 Do AddObject(Strings.GetP(I)^, Strings.Objects[I]); -end; -procedure TJclWideStrings.AddStrings(Strings: TStrings); -var +End; +Procedure TJclWideStrings.AddStrings(Strings: TStrings); +Var I: Integer; -begin - for I := 0 to Strings.Count - 1 do +Begin + For I := 0 To Strings.Count - 1 Do AddObject(Strings.Strings[I], Strings.Objects[I]); -end; -procedure TJclWideStrings.AddStringsTo(Dest: TStrings); -var +End; +Procedure TJclWideStrings.AddStringsTo(Dest: TStrings); +Var I: Integer; -begin - for I := 0 to Count - 1 do +Begin + For I := 0 To Count - 1 Do Dest.AddObject(GetP(I)^, Objects[I]); -end; -procedure TJclWideStrings.Append(const S: DWWideString); -begin +End; +Procedure TJclWideStrings.Append(Const S: DWWideString); +Begin Add(S); -end; -procedure TJclWideStrings.Assign(Source: TPersistent); -begin - if Source is TJclWideStrings then - begin +End; +Procedure TJclWideStrings.Assign(Source: TPersistent); +Begin + If Source is TJclWideStrings Then + Begin BeginUpdate; - try + Try Clear; FDelimiter := TJclWideStrings(Source).FDelimiter; FNameValueSeparator := TJclWideStrings(Source).FNameValueSeparator; FQuoteChar := TJclWideStrings(Source).FQuoteChar; AddStrings(TJclWideStrings(Source)); - finally + Finally EndUpdate; - end; - end - else - if Source is TStrings then - begin + End; + End + Else + If Source is TStrings Then + Begin BeginUpdate; - try + Try Clear; {$IFDEF RTL190_UP} FNameValueSeparator := TStrings(Source).NameValueSeparator; @@ -669,21 +669,21 @@ procedure TJclWideStrings.Assign(Source: TPersistent); FDelimiter := CharToWideChar(TStrings(Source).Delimiter); {$ENDIF ~RTL190_UP} AddStrings(TStrings(Source)); - finally + Finally EndUpdate; - end; - end - else - inherited Assign(Source); -end; -procedure TJclWideStrings.AssignTo(Dest: TPersistent); -var + End; + End + Else + Inherited Assign(Source); +End; +Procedure TJclWideStrings.AssignTo(Dest: TPersistent); +Var I: Integer; -begin - if Dest is TStrings then - begin +Begin + If Dest is TStrings Then + Begin TStrings(Dest).BeginUpdate; - try + Try TStrings(Dest).Clear; {$IFDEF RTL190_UP} TStrings(Dest).NameValueSeparator := NameValueSeparator; @@ -696,456 +696,456 @@ procedure TJclWideStrings.AssignTo(Dest: TPersistent); TStrings(Dest).QuoteChar := DWCharToChar(QuoteChar); TStrings(Dest).Delimiter := DWCharToChar(Delimiter); {$ENDIF ~RTL190_UP} - for I := 0 to Count - 1 do + For I := 0 To Count - 1 Do TStrings(Dest).AddObject(GetP(I)^, Objects[I]); - finally + Finally TStrings(Dest).EndUpdate; - end; - end - else - inherited AssignTo(Dest); -end; -procedure TJclWideStrings.BeginUpdate; -begin - if FUpdateCount = 0 then + End; + End + Else + Inherited AssignTo(Dest); +End; +Procedure TJclWideStrings.BeginUpdate; +Begin + If FUpdateCount = 0 Then SetUpdateState(True); Inc(FUpdateCount); -end; -function TJclWideStrings.CreateAnsiStringList: TStrings; -var +End; +Function TJclWideStrings.CreateAnsiStringList: TStrings; +Var I: Integer; -begin +Begin Result := TStringList.Create; - try + Try Result.BeginUpdate; - for I := 0 to Count - 1 do + For I := 0 To Count - 1 Do Result.AddObject(GetP(I)^, Objects[I]); Result.EndUpdate; - except + Except Result.Free; raise; - end; -end; -procedure TJclWideStrings.DefineProperties(Filer: TFiler); - function DoWrite: Boolean; - begin - if Filer.Ancestor <> nil then - begin + End; +End; +Procedure TJclWideStrings.DefineProperties(Filer: TFiler); + Function DoWrite: Boolean; + Begin + If Filer.Ancestor <> nil Then + Begin Result := True; - if Filer.Ancestor is TJclWideStrings then + If Filer.Ancestor is TJclWideStrings Then Result := not Equals(TJclWideStrings(Filer.Ancestor)) - end - else + End + Else Result := Count > 0; - end; -begin + End; +Begin Filer.DefineProperty('Strings', ReadData, WriteData, DoWrite); -end; -procedure TJclWideStrings.EndUpdate; -begin +End; +Procedure TJclWideStrings.EndUpdate; +Begin Dec(FUpdateCount); - if FUpdateCount = 0 then + If FUpdateCount = 0 Then SetUpdateState(False); -end; -function TJclWideStrings.Equals(Strings: TStrings): Boolean; -var +End; +Function TJclWideStrings.Equals(Strings: TStrings): Boolean; +Var I: Integer; -begin +Begin Result := False; - if Strings.Count = Count then - begin - for I := 0 to Count - 1 do - if Strings[I] <> PStrings[I]^ then + If Strings.Count = Count Then + Begin + For I := 0 To Count - 1 Do + If Strings[I] <> PStrings[I]^ Then Exit; Result := True; - end; -end; -function TJclWideStrings.Equals(Strings: TJclWideStrings): Boolean; -var + End; +End; +Function TJclWideStrings.Equals(Strings: TJclWideStrings): Boolean; +Var I: Integer; -begin +Begin Result := False; - if Strings.Count = Count then - begin - for I := 0 to Count - 1 do - if Strings[I] <> PStrings[I]^ then + If Strings.Count = Count Then + Begin + For I := 0 To Count - 1 Do + If Strings[I] <> PStrings[I]^ Then Exit; Result := True; - end; -end; -procedure TJclWideStrings.Exchange(Index1, Index2: Integer); -var + End; +End; +Procedure TJclWideStrings.Exchange(Index1, Index2: Integer); +Var TempObject: TObject; TempString: DWWideString; -begin +Begin BeginUpdate; - try + Try TempString := PStrings[Index1]^; TempObject := Objects[Index1]; PStrings[Index1]^ := PStrings[Index2]^; Objects[Index1] := Objects[Index2]; PStrings[Index2]^ := TempString; Objects[Index2] := TempObject; - finally + Finally EndUpdate; - end; -end; -function TJclWideStrings.Get(Index: Integer): DWWideString; -begin + End; +End; +Function TJclWideStrings.Get(Index: Integer): DWWideString; +Begin Result := GetP(Index)^; -end; -function TJclWideStrings.GetCapacity: Integer; -begin +End; +Function TJclWideStrings.GetCapacity: Integer; +Begin Result := Count; -end; -function TJclWideStrings.GetObject(Index: Integer): TObject; -begin +End; +Function TJclWideStrings.GetObject(Index: Integer): TObject; +Begin Result := nil; -end; -function TJclWideStrings.GetTextStr: DWWideString; -var +End; +Function TJclWideStrings.GetTextStr: DWWideString; +Var I: Integer; Len, LL: Integer; P: PDWChar; W: PString; -begin +Begin Len := 0; LL := Length(LineSeparator); - for I := 0 to Count - 1 do + For I := 0 To Count - 1 Do Inc(Len, Length(GetP(I)^) + LL); SetLength(Result, Len); P := PDWChar(Result); - for I := 0 to Count - 1 do - begin + For I := 0 To Count - 1 Do + Begin W := GetP(I); Len := Length(W^); - if Len > 0 then - begin + If Len > 0 Then + Begin MoveWideChar(W^[1], P^, Len); Inc(P, Len); - end; - if LL > 0 then - begin + End; + If LL > 0 Then + Begin MoveWideChar(FLineSeparator[1], P^, LL); Inc(P, LL); - end; - end; -end; -function TJclWideStrings.IndexOfObject(AObject: TObject): Integer; -begin - for Result := 0 to Count - 1 do - if Objects[Result] = AObject then + End; + End; +End; +Function TJclWideStrings.IndexOfObject(AObject: TObject): Integer; +Begin + For Result := 0 To Count - 1 Do + If Objects[Result] = AObject Then Exit; Result := -1; -end; -procedure TJclWideStrings.Insert(Index: Integer; const S: DWWideString); -begin +End; +Procedure TJclWideStrings.Insert(Index: Integer; Const S: DWWideString); +Begin InsertObject(Index, S, nil); -end; -procedure TJclWideStrings.InsertObject(Index: Integer; const S: DWWideString; AObject: TObject); -begin -end; -procedure TJclWideStrings.Move(CurIndex, NewIndex: Integer); -var +End; +Procedure TJclWideStrings.InsertObject(Index: Integer; Const S: DWWideString; AObject: TObject); +Begin +End; +Procedure TJclWideStrings.Move(CurIndex, NewIndex: Integer); +Var TempObject: TObject; TempString: DWWideString; -begin - if CurIndex <> NewIndex then - begin +Begin + If CurIndex <> NewIndex Then + Begin BeginUpdate; - try + Try TempString := GetP(CurIndex)^; TempObject := GetObject(CurIndex); Delete(CurIndex); InsertObject(NewIndex, TempString, TempObject); - finally + Finally EndUpdate; - end; - end; -end; -procedure TJclWideStrings.ReadData(Reader: TReader); -begin + End; + End; +End; +Procedure TJclWideStrings.ReadData(Reader: TReader); +Begin BeginUpdate; - try + Try Clear; Reader.ReadListBegin; - while not Reader.EndOfList do - if Reader.NextValue in [vaLString, vaString] then + While not Reader.EndOfList Do + If Reader.NextValue in [vaLString, vaString] Then Add(Reader.ReadString) - else + Else Add(Reader.ReadString); Reader.ReadListEnd; - finally + Finally EndUpdate; - end; -end; -procedure TJclWideStrings.SaveToFile(const FileName: TFileName; WideFileOptions: TWideFileOptions = []); -var + End; +End; +Procedure TJclWideStrings.SaveToFile(Const FileName: TFileName; WideFileOptions: TWideFileOptions = []); +Var Stream: TFileStream; -begin +Begin Stream := TFileStream.Create(FileName, fmCreate); - try + Try SaveToStream(Stream, WideFileOptions); - finally + Finally Stream.Free; - end; -end; -procedure TJclWideStrings.SaveToStream(Stream: TStream; WideFileOptions: TWideFileOptions = []); -var + End; +End; +Procedure TJclWideStrings.SaveToStream(Stream: TStream; WideFileOptions: TWideFileOptions = []); +Var AnsiS: String; WideS: DWWideString; WC: DWChar; -begin - if foAnsiFile in WideFileOptions then - begin +Begin + If foAnsiFile in WideFileOptions Then + Begin AnsiS := String(GetTextStr); // explicit Unicode conversion Stream.Write(AnsiS[1], Length(AnsiS) * SizeOf(Char)); - end - else - begin - if foUnicodeLB in WideFileOptions then - begin + End + Else + Begin + If foUnicodeLB in WideFileOptions Then + Begin WC := BOM_LSB_FIRST; Stream.Write(WC, SizeOf(WC)); - end; + End; WideS := GetTextStr; Stream.Write(WideS[1], Length(WideS) * SizeOf(WideChar)); - end; -end; -procedure TJclWideStrings.SetCapacity(NewCapacity: Integer); -begin -end; -procedure TJclWideStrings.SetText(Text: PDWChar); -begin + End; +End; +Procedure TJclWideStrings.SetCapacity(NewCapacity: Integer); +Begin +End; +Procedure TJclWideStrings.SetText(Text: PDWChar); +Begin SetTextStr(DWString(Text^)); -end; -procedure TJclWideStrings.SetTextStr(const Value: DWWideString); -var +End; +Procedure TJclWideStrings.SetTextStr(Const Value: DWWideString); +Var P, Start: PDWWideString; S: String; Len: Integer; -begin +Begin BeginUpdate; - try + Try Clear; - if Value <> '' then - begin + If Value <> '' Then + Begin P := @Value; - if P <> nil then - begin - while P^[InitStrPos] <> DWChar(0) do - begin + If P <> nil Then + Begin + While P^[InitStrPos] <> DWChar(0) Do + Begin Start := P; - while True do - begin - case P^[InitStrPos] of + While True Do + Begin + Case P^[InitStrPos] Of DWChar(0), DWChar(10), DWChar(13): Break; - end; + End; Inc(P); - end; + End; Len := Length(P^) - Length(Start^); - if Len > 0 then - begin + If Len > 0 Then + Begin SetString(S, PChar(@Start), Len); AddObject(S, nil); // consumes most time - end - else + End + Else AddObject('', nil); - if P^[InitStrPos] = DWChar(13) then + If P^[InitStrPos] = DWChar(13) Then Inc(P); - if P^[InitStrPos] = DWChar(10) then + If P^[InitStrPos] = DWChar(10) Then Inc(P); - end; - end; - end; - finally + End; + End; + End; + Finally EndUpdate; - end; -end; -procedure TJclWideStrings.SetUpdateState(Updating: Boolean); -begin -end; -procedure TJclWideStrings.WriteData(Writer: TWriter); -var + End; +End; +Procedure TJclWideStrings.SetUpdateState(Updating: Boolean); +Begin +End; +Procedure TJclWideStrings.WriteData(Writer: TWriter); +Var I: Integer; -begin +Begin Writer.WriteListBegin; - for I := 0 to Count - 1 do + For I := 0 To Count - 1 Do Writer.WriteString(GetP(I)^); Writer.WriteListEnd; -end; +End; //=== { TJclWideStringList } ======================================================= -constructor TJclWideStringList.Create; -begin - inherited Create; +Constructor TJclWideStringList.Create; +Begin + Inherited Create; FList := TList.Create; -end; -destructor TJclWideStringList.Destroy; -begin +End; +Destructor TJclWideStringList.Destroy; +Begin FOnChange := nil; FOnChanging := nil; Inc(FUpdateCount); // do not call unnecessary functions Clear; FList.Free; - inherited Destroy; -end; -procedure TJclWideStringList.Changed; -begin - if Assigned(FOnChange) then + Inherited Destroy; +End; +Procedure TJclWideStringList.Changed; +Begin + If Assigned(FOnChange) Then FOnChange(Self); -end; -procedure TJclWideStringList.Changing; -begin - if Assigned(FOnChanging) then +End; +Procedure TJclWideStringList.Changing; +Begin + If Assigned(FOnChanging) Then FOnChanging(Self); -end; -procedure TJclWideStringList.Clear; -var +End; +Procedure TJclWideStringList.Clear; +Var I: Integer; Item: PWStringItem; -begin - if FUpdateCount = 0 then +Begin + If FUpdateCount = 0 Then Changing; - for I := 0 to Count - 1 do - begin + For I := 0 To Count - 1 Do + Begin Item := PWStringItem(FList[I]); Item.FString := ''; FreeMem(Item); - end; + End; FList.Clear; - if FUpdateCount = 0 then + If FUpdateCount = 0 Then Changed; -end; +End; threadvar CustomSortList: TJclWideStringList; CustomSortCompare: TJclWideStringListSortCompare; -function WStringListCustomSort(Item1, Item2: Pointer): Integer; -begin +Function WStringListCustomSort(Item1, Item2: Pointer): Integer; +Begin Result := CustomSortCompare(CustomSortList, CustomSortList.FList.IndexOf(Item1), CustomSortList.FList.IndexOf(Item2)); -end; -procedure TJclWideStringList.CustomSort(Compare: TJclWideStringListSortCompare); -var +End; +Procedure TJclWideStringList.CustomSort(Compare: TJclWideStringListSortCompare); +Var TempList: TJclWideStringList; TempCompare: TJclWideStringListSortCompare; -begin +Begin TempList := CustomSortList; TempCompare := CustomSortCompare; CustomSortList := Self; CustomSortCompare := Compare; - try + Try Changing; FList.Sort(WStringListCustomSort); Changed; - finally + Finally CustomSortList := TempList; CustomSortCompare := TempCompare; - end; -end; -procedure TJclWideStringList.Delete(Index: Integer); -var + End; +End; +Procedure TJclWideStringList.Delete(Index: Integer); +Var Item: PWStringItem; -begin - if FUpdateCount = 0 then +Begin + If FUpdateCount = 0 Then Changing; Item := PWStringItem(FList[Index]); FList.Delete(Index); Item.FString := ''; FreeMem(Item); - if FUpdateCount = 0 then + If FUpdateCount = 0 Then Changed; -end; -procedure TJclWideStringList.Exchange(Index1, Index2: Integer); -begin - if FUpdateCount = 0 then +End; +Procedure TJclWideStringList.Exchange(Index1, Index2: Integer); +Begin + If FUpdateCount = 0 Then Changing; FList.Exchange(Index1, Index2); - if FUpdateCount = 0 then + If FUpdateCount = 0 Then Changed; -end; -function TJclWideStringList.GetCapacity: Integer; -begin +End; +Function TJclWideStringList.GetCapacity: Integer; +Begin Result := FList.Capacity; -end; -function TJclWideStringList.GetCount: Integer; -begin +End; +Function TJclWideStringList.GetCount: Integer; +Begin Result := FList.Count; -end; -function TJclWideStringList.GetItem(Index: Integer): PWStringItem; -begin +End; +Function TJclWideStringList.GetItem(Index: Integer): PWStringItem; +Begin Result := FList[Index]; -end; -function TJclWideStringList.GetObject(Index: Integer): TObject; -begin +End; +Function TJclWideStringList.GetObject(Index: Integer): TObject; +Begin Result := GetItem(Index).FObject; -end; -function TJclWideStringList.GetP(Index: Integer): PString; -begin +End; +Function TJclWideStringList.GetP(Index: Integer): PString; +Begin Result := Addr(GetItem(Index).FString); -end; -procedure TJclWideStringList.InsertObject(Index: Integer; const S: DWWideString; +End; +Procedure TJclWideStringList.InsertObject(Index: Integer; Const S: DWWideString; AObject: TObject); -var +Var P: PWStringItem; -begin - if FUpdateCount = 0 then +Begin + If FUpdateCount = 0 Then Changing; FList.Insert(Index, nil); // error check P := AllocMem(SizeOf(TWStringItem)); FList[Index] := P; Put(Index, S); - if AObject <> nil then + If AObject <> nil Then PutObject(Index, AObject); - if FUpdateCount = 0 then + If FUpdateCount = 0 Then Changed; -end; -procedure TJclWideStringList.Put(Index: Integer; const Value: DWWideString); -begin - if FUpdateCount = 0 then +End; +Procedure TJclWideStringList.Put(Index: Integer; Const Value: DWWideString); +Begin + If FUpdateCount = 0 Then Changing; GetItem(Index).FString := Value; - if FUpdateCount = 0 then + If FUpdateCount = 0 Then Changed; -end; -procedure TJclWideStringList.PutObject(Index: Integer; AObject: TObject); -begin - if FUpdateCount = 0 then +End; +Procedure TJclWideStringList.PutObject(Index: Integer; AObject: TObject); +Begin + If FUpdateCount = 0 Then Changing; GetItem(Index).FObject := AObject; - if FUpdateCount = 0 then + If FUpdateCount = 0 Then Changed; -end; -procedure TJclWideStringList.SetCapacity(NewCapacity: Integer); -begin +End; +Procedure TJclWideStringList.SetCapacity(NewCapacity: Integer); +Begin FList.Capacity := NewCapacity; -end; -procedure TJclWideStringList.SetUpdateState(Updating: Boolean); -begin - if Updating then +End; +Procedure TJclWideStringList.SetUpdateState(Updating: Boolean); +Begin + If Updating Then Changing - else + Else Changed; -end; +End; {$ENDIF ~SUPPORTS_UNICODE} -procedure AllocateMultiSz(var Dest: PWideMultiSz; Len: SizeInt); -begin - if Len > 0 then +Procedure AllocateMultiSz(Var Dest: PWideMultiSz; Len: SizeInt); +Begin + If Len > 0 Then GetMem(Dest, Len * SizeOf(WideChar)) - else + Else Dest := nil; -end; -procedure FreeMultiSz(var Dest: PWideMultiSz); -begin - if Dest <> nil then +End; +Procedure FreeMultiSz(Var Dest: PWideMultiSz); +Begin + If Dest <> nil Then FreeMem(Dest); Dest := nil; -end; +End; {$IFDEF UNITVERSIONING} -initialization - RegisterUnitVersion(HInstance, UnitVersioning); -finalization - UnregisterUnitVersion(HInstance); +Initialization + RegisterUnitVersion(HInstance, UnitVersioning); +Finalization + UnregisterUnitVersion(HInstance); {$ENDIF UNITVERSIONING} -end. +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemoryDataset.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemoryDataset.pas index ed85c3e70..18a9da11b 100644 --- a/CORE/Source/Plugins/Memdataset/uRESTDWMemoryDataset.pas +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemoryDataset.pas @@ -1,7998 +1,6008 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 1999-2014 by Joost van der Sluis and other members of the + Free Pascal development team + + MemoryDataset implementation + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} + Unit uRESTDWMemoryDataset; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} -{ - REST Dataware . - Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON - de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo leVar componentes compatíveis entre o Delphi e outros Compiladores - Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. - - Membros do Grupo : - - XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. - Alberto Brito - Admin - Administrador do desenvolvimento - Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. - Mobius One - Devel, Tester and Admin. - Gustavo - Criptografia and Devel. - Eloy - Devel. - Roniery - Devel. -} +{$IFDEF FPC} +{$MODE OBJFPC} +{$ENDIF} +{$h+} Interface +Uses Classes,SysUtils,DB,Variants, +{$IFNDEF FPC}SqlTimSt,{$ENDIF} +uRESTDWMemoryDatasetParser, uRESTDWTools, uRESTDWProtoTypes, uRESTDWConsts; + +{$IFNDEF FPC} +resourcestring + SInvPacketRecordsValue = 'PacketRecords has to be larger than 0'; + SInvPacketRecordsValueFieldNames = 'PacketRecords must be -1 if IndexFieldNames is set'; + SInvPacketRecordsValueUniDirectional = 'PacketRecords must not be -1 on an unidirectional dataset'; + SNoIndexFieldNameGiven = 'Cannot create index "%s": No fields available.'; + SErrNoDataset = 'Missing (compatible) underlying dataset, can not open'; + SErrIndexBasedOnInvField = 'Field "%s" has an invalid field type (%s) to base index on.'; + SMaxIndexes = 'The maximum amount of indexes is reached'; + SMinIndexes = 'The minimum amount of indexes is 1'; + SUnsupportedFieldType = 'Fieldtype %s is not supported'; + SReadOnlyField = 'Field %s cannot be modified, it is read-only.'; + SNoSuchRecord = 'Could not find the requested record.'; + SStreamNotRecognised = 'The data-stream format is not recognized'; + SFieldIsNull = 'The field is null'; + SNoReaderClassRegistered = 'There is no TDatapacketReaderClass registered for this kind of data-stream'; + SErrNoFieldsDefined = 'Can not create a dataset when there are no fielddefinitions or fields defined'; + SErrApplyUpdBeforeRefresh = 'Must apply updates before refreshing data'; + SInvalidBookmark = 'Invalid bookmark'; + SUniDirectional = 'Operation cannot be performed on an unidirectional dataset'; +{$ENDIF} + +Type {$IFDEF FPC} - {$MODE OBJFPC}{$H+} + TRESTDWPtrInt = PtrInt; +{$ELSE} + TRESTDWPtrInt = NativeInt; +{$ENDIF} + TRESTDWMemBytes = array Of Byte; + TRESTDWQWord = UInt64; + PRESTDWQWord = ^TRESTDWQWord; +{$IFNDEF FPC} + PLargeInt = ^LargeInt; {$ENDIF} -uses - SysUtils, Classes, DB, Variants, uRESTDWProtoTypes, uRESTDWMemDBUtils, - uRESTDWMemExprParser, {$IFNDEF FPC}uRESTDWABMemDBFilterExpr,{$ENDIF} - uRESTDWAbout, uRESTDWConsts, uRESTDWBasicDbTypes; + TRESTDWCustomMemTable = Class; -Const - ftBlobTypes = [ftBlob, ftMemo, ftGraphic, ftFmtMemo, ftParadoxOle, ftDBaseOle, - ftTypedBinary, ftOraBlob, ftOraClob - {$IF DEFINED(FPC) OR DEFINED(DELPHI10_0UP)}, ftWideMemo{$IFEND}]; - ftSupported = [ftString, ftSmallint, ftInteger, ftWord, ftBoolean, ftFloat, ftCurrency, - ftDate, ftTime, ftDateTime, ftAutoInc, ftBCD, ftFMTBCD, ftTimestamp, - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - ftOraTimestamp, ftFixedWideChar, ftTimeStampOffset, - ftLongWord, ftShortint, ftByte, ftSingle, ftExtended, - {$IFEND} - {$ELSE} - ftFixedWideChar, - {$ENDIF FPC} - ftBytes, ftVarBytes, ftADT, ftFixedChar, ftWideString, ftLargeint, ftVariant, ftGuid] + ftBlobTypes; - fkStoredFields = [fkData]; - SDefaultIndex = 'DEFAULT_ORDER'; - SCustomIndex = 'CUSTOM_ORDER'; - Desc = ' DESC'; //leading space is important - LenDesc : Integer = Length(Desc); - Limiter = ';'; - SNoIndexFieldNameGiven = 'Cannot create index "%s": No fields available.'; - SErrIndexBasedOnInvField = 'Field "%s" has an invalid field type (%s) to base index on.'; - SMinIndexes = 'The minimum amount of indexes is 1'; - SIndexNotFound = 'Index ''%s'' not found'; - SUniDirectional = 'Operation cannot be performed on an unidirectional dataset'; - SFieldRequired = 'Field ''%s'' must have a value'; - - Type - TCompareFunc = Function(subValue, - aValue : Pointer; - size : Integer; - options : TLocateOptions) : Int64; - TDBCompareRec = Record - CompareFunc : TCompareFunc; - Off : Int64; - NullBOff : Int64; - FieldInd : longint; - Size : integer; - Options : TLocateOptions; - Desc : Boolean; - End; - TDBCompareStruct = array of TDBCompareRec; + TRESTDWMemDataReferenceKind = (drData, drDelta); -Type - {$IFNDEF FPC} - {$IF Defined(HAS_FMX)} - {$IF CompilerVersion < 21} - TRecordBuffer = PChar; - {$ELSE} - TRecordBuffer = PByte; - {$IFEND} - {$ELSE} - {$IF CompilerVersion < 20} - TRecordBuffer = PChar; - {$IFEND} - {$IFEND} - {$ENDIF} - TPVariant = ^Variant; - TApplyMode = (amNone, amAppend, amMerge); - TApplyEvent = Procedure(Dataset : TDataset; - Rows : Integer) Of Object; - TRecordStatus = (rsOriginal, rsUpdated, rsInserted, rsDeleted); - TApplyRecordEvent = Procedure(Dataset : TDataset; - RecStatus : TRecordStatus; - FoundApply : Boolean) Of Object; - TLoadMode = (lmCopy, lmAppend); - TSaveLoadState = (slsNone, slsLoading, slsSaving); - TCompareRecords = Function(Item1, Item2 : TRESTDWMTMemoryRecord) : Integer Of Object; - TIntArray = Array Of Integer; - TRESTDWMTBookmarkData = Integer; - PBlobBuffer = ^TBlobBuffer; - TBlobBuffer = Packed Record - FieldNo, - OrgBufID : Integer; - Buffer : Pointer; - Size : Int64; - End; - PRESTDWBlobField = ^TRESTDWBlobField; - TRESTDWBlobField = Packed Record - ConnBlobBuffer : Array[0..11] Of Byte; // DB specific data is stored here - BlobBuffer : PBlobBuffer; - End; - PRESTDWRecLinkItem = ^TRESTDWRecLinkItem; - TRESTDWRecLinkItem = Packed Record - Prior : PRESTDWRecLinkItem; - Next : PRESTDWRecLinkItem; - End; - PRESTDWBookmark = ^TRESTDWBookmark; - TRESTDWBookmark = Packed Record - BookmarkData : PRESTDWRecLinkItem; - BookmarkInt : Integer; // Was used by TArrayBufIndex - BookmarkFlag : TBookmarkFlag; - End; - TRESTDWMemTable = Class; - PRecordList = ^TRecordList; - TRecordList = Class(TList) + TRESTDWMemDataReference = Class(TObject) Private - Function GetRec(Index : Integer) : TRESTDWMTMemoryRecord; Overload; - Procedure PutRec(Index : Integer; - Item : TRESTDWMTMemoryRecord); Overload; - Procedure ClearAll; - Protected + FDataSet : TRESTDWCustomMemTable; + FKind : TRESTDWMemDataReferenceKind; Public - Destructor Destroy; Override; - Procedure Delete(Index : Integer); Overload; - Function Add (Item : TRESTDWMTMemoryRecord): Integer; Overload; - Property Items [Index : Integer] : TRESTDWMTMemoryRecord Read GetRec Write PutRec; Default; + Constructor Create(ADataSet: TRESTDWCustomMemTable; AKind: TRESTDWMemDataReferenceKind); + Procedure AssignTo(ADataSet: TRESTDWCustomMemTable); + Property DataSet : TRESTDWCustomMemTable Read FDataSet; + Property Kind : TRESTDWMemDataReferenceKind Read FKind; + End; + + { TRESTDWMemBlobBuffer } + + PRESTDWMemBlobBuffer = ^TRESTDWMemBlobBuffer; + TRESTDWMemBlobBuffer = Record + FieldNo : integer; + OrgBufID: integer; + Buffer : pointer; + Size : TRESTDWPtrInt; + End; + + PRESTDWMemBlobField = ^TRESTDWMemBlobField; + TRESTDWMemBlobField = Record + ConnBlobBuffer : array[0..11] Of byte; // DB specific data is stored here + BlobBuffer : PRESTDWMemBlobBuffer; End; - TIndexType = (itNormal,itDefault,itCustom); - TRESTDWIndex = Class(TObject) + + { TRESTDWMemBlobStream } + + TRESTDWMemBlobStream = Class(TStream) Private - FDataset : TRESTDWMemtable; + FField : TBlobField; + FDataSet : TRESTDWCustomMemTable; + FBlobBuffer : PRESTDWMemBlobBuffer; + FPosition : TRESTDWPtrInt; + FModified : boolean; Protected - Function GetBookmarkSize : integer; Virtual; Abstract; - Function GetCurrentBuffer : Pointer; Virtual; Abstract; - Function GetCurrentRecord : TRecordBuffer; Virtual; Abstract; - Function GetIsInitialized : boolean; Virtual; Abstract; - Function GetSpareBuffer : TRecordBuffer; Virtual; Abstract; - Function GetSpareRecord : TRecordBuffer; Virtual; Abstract; - Function GetRecNo : Longint; Virtual; Abstract; - Procedure SetRecNo(ARecNo : Longint); Virtual; Abstract; + Function Seek(Offset: Longint; Origin: Word): Longint; override; + Function Read(Var Buffer; Count: Longint): Longint; override; + Function Write(Const Buffer; Count: Longint): Longint; override; Public - DBCompareStruct : TDBCompareStruct; - Name, - FieldsName, - CaseinsFields, - DescFields : String; - Options : TIndexOptions; - IndNr : Integer; - Constructor Create(const ADataset : TRESTDWMemtable); Virtual; - Function ScrollBackward : TGetResult; Virtual; Abstract; - Function ScrollForward : TGetResult; Virtual; Abstract; - Function GetCurrent : TGetResult; Virtual; Abstract; - Function ScrollFirst : TGetResult; Virtual; Abstract; - Procedure ScrollLast; Virtual; Abstract; - // Gets prior/next record relative to given bookmark; does not change current record - Function GetRecord(ABookmark : PRESTDWBookmark; - GetMode : TGetMode): TGetResult; Virtual; - Procedure SetToFirstRecord; Virtual; Abstract; - Procedure SetToLastRecord; Virtual; Abstract; - Procedure StoreCurrentRecord; Virtual; Abstract; - Procedure RestoreCurrentRecord; Virtual; Abstract; - Function CanScrollForward : Boolean; Virtual; Abstract; - Procedure DoScrollForward; Virtual; Abstract; - Procedure StoreCurrentRecIntoBookmark(Const ABookmark : PRESTDWBookmark); Virtual; Abstract; - Procedure StoreSpareRecIntoBookmark (Const ABookmark : PRESTDWBookmark); Virtual; Abstract; - Procedure GotoBookmark (Const ABookmark : PRESTDWBookmark); Virtual; Abstract; - Function BookmarkValid (Const ABookmark : PRESTDWBookmark) : Boolean; Virtual; - Function CompareBookmarks (Const ABookmark1, - ABookmark2 : PRESTDWBookmark) : Integer; Virtual; - Function SameBookmarks (Const ABookmark1, - ABookmark2 : PRESTDWBookmark) : Boolean; Virtual; - Procedure InitialiseIndex; Virtual; Abstract; - Procedure InitialiseSpareRecord(Const ASpareRecord : TRecordBuffer); Virtual; Abstract; - Procedure ReleaseSpareRecord; Virtual; Abstract; - Procedure BeginUpdate; Virtual; Abstract; - // Adds a record to the end of the index as the new last record (spare record) - // Normally only used in GetNextPacket - Procedure AddRecord; Virtual; Abstract; - // Inserts a record before the current record, or if the record is sorted, - // inserts it in the proper position - Procedure InsertRecordBeforeCurrentRecord(Const ARecord : TRecordBuffer); Virtual; Abstract; - Procedure RemoveRecordFromIndex (Const ABookmark : TRESTDWBookmark); Virtual; Abstract; - Procedure OrderCurrentRecord; Virtual; Abstract; - Procedure EndUpdate; Virtual; Abstract; - Property SpareRecord : TRecordBuffer Read GetSpareRecord; - Property SpareBuffer : TRecordBuffer Read GetSpareBuffer; - Property CurrentRecord : TRecordBuffer Read GetCurrentRecord; - Property CurrentBuffer : Pointer Read GetCurrentBuffer; - Property IsInitialized : boolean Read GetIsInitialized; - Property BookmarkSize : integer Read GetBookmarkSize; - Property RecNo : Longint Read GetRecNo Write SetRecNo; + Constructor Create(Field: TBlobField; Mode: TBlobStreamMode); + Destructor Destroy; override; + End; + + + PRESTDWMemRecLinkItem = ^TRESTDWMemRecLinkItem; + TRESTDWMemRecLinkItem = Record + prior : PRESTDWMemRecLinkItem; + next : PRESTDWMemRecLinkItem; + End; + + PRESTDWMemBookmark = ^TRESTDWMemBookmark; + TRESTDWMemBookmark = Record + BookmarkData : PRESTDWMemRecLinkItem; + BookmarkInt : integer; // was used by TRESTDWMemArrayIndex + BookmarkFlag : TBookmarkFlag; + End; + + TRESTDWMemRecUpdateBuffer = Record + UpdateKind : TUpdateKind; +{ BookMarkData: + - Is -1 if the update has canceled out. For example: an appended record has been deleted again + - If UpdateKind is ukInsert, it contains a bookmark to the newly created record + - If UpdateKind is ukModify, it contains a bookmark to the record with the new data + - If UpdateKind is ukDelete, it contains a bookmark to the deleted record (ie: the record is still there) +} + BookmarkData : TRESTDWMemBookmark; +{ NextBookMarkData: + - If UpdateKind is ukDelete, it contains a bookmark to the record just after the deleted record +} + NextBookmarkData : TRESTDWMemBookmark; +{ OldValuesBuffer: + - If UpdateKind is ukModify, it contains a record buffer which contains the old data + - If UpdateKind is ukDelete, it contains a record buffer with the data of the deleted record +} + OldValuesBuffer : TRecordBuffer; End; - TUniDirectionalBufIndex = Class(TRESTDWIndex) + TRESTDWMemRecordsUpdateBuffer = array Of TRESTDWMemRecUpdateBuffer; + + TRESTDWMemCompareFunc = Function(subValue, aValue: pointer; size: integer; options: TLocateOptions): int64; + + TRESTDWMemCompareRec = Record + CompareFunc : TRESTDWMemCompareFunc; + Off : TRESTDWPtrInt; + NullBOff : TRESTDWPtrInt; + FieldInd : longint; + Size : integer; + Options : TLocateOptions; + Desc : Boolean; + End; + TRESTDWMemCompareStruct = array Of TRESTDWMemCompareRec; + + { TRESTDWMemInternalIndex } + + TRESTDWMemInternalIndex = Class(TObject) Private - FSPareBuffer : TRecordBuffer; + FDataset : TRESTDWCustomMemTable; Protected - Function GetBookmarkSize : Integer; Override; - Function GetCurrentBuffer : Pointer; Override; - Function GetCurrentRecord : TRecordBuffer; Override; - Function GetIsInitialized : Boolean; Override; - Function GetSpareBuffer : TRecordBuffer; Override; - Function GetSpareRecord : TRecordBuffer; Override; - Function GetRecNo : Longint; Override; - Procedure SetRecNo(ARecNo : Longint); Override; + Function GetBookmarkSize: integer; virtual; abstract; + Function GetCurrentBuffer: Pointer; virtual; abstract; + Function GetCurrentRecord: TRecordBuffer; virtual; abstract; + Function GetIsInitialized: boolean; virtual; abstract; + Function GetSpareBuffer: TRecordBuffer; virtual; abstract; + Function GetSpareRecord: TRecordBuffer; virtual; abstract; + Function GetRecNo: Longint; virtual; abstract; + Procedure SetRecNo(ARecNo: Longint); virtual; abstract; Public - Function ScrollBackward : TGetResult; Override; - Function ScrollForward : TGetResult; Override; - Function GetCurrent : TGetResult; Override; - Function ScrollFirst : TGetResult; Override; - Procedure ScrollLast; Override; - Procedure SetToFirstRecord; Override; - Procedure SetToLastRecord; Override; - Procedure StoreCurrentRecord; Override; - Procedure RestoreCurrentRecord; Override; - Function CanScrollForward : Boolean; Override; - Procedure DoScrollForward; Override; - Procedure StoreCurrentRecIntoBookmark(Const ABookmark : PRESTDWBookmark); Override; - Procedure StoreSpareRecIntoBookmark (Const ABookmark : PRESTDWBookmark); Override; - Procedure GotoBookmark (Const ABookmark : PRESTDWBookmark); Override; - Procedure InitialiseIndex; Override; - Procedure InitialiseSpareRecord (Const ASpareRecord : TRecordBuffer); Override; - Procedure ReleaseSpareRecord; Override; - Procedure BeginUpdate; Override; - Procedure AddRecord; Override; - Procedure InsertRecordBeforeCurrentRecord(Const ARecord : TRecordBuffer); Override; - Procedure RemoveRecordFromIndex (const ABookmark : TRESTDWBookmark); Override; - Procedure OrderCurrentRecord; Override; - Procedure EndUpdate; Override; + DBCompareStruct : TRESTDWMemCompareStruct; + Name : String; + FieldsName : String; + CaseinsFields : String; + DescFields : String; + Options : TIndexOptions; + IndNr : integer; + + Constructor Create(Const ADataset : TRESTDWCustomMemTable); virtual; + Function ScrollBackward : TGetResult; virtual; abstract; + Function ScrollForward : TGetResult; virtual; abstract; + Function GetCurrent : TGetResult; virtual; abstract; + Function ScrollFirst : TGetResult; virtual; abstract; + Procedure ScrollLast; virtual; abstract; + // Gets prior/next record relative to given bookmark; does not change current record + Function GetRecord(ABookmark: PRESTDWMemBookmark; GetMode: TGetMode): TGetResult; virtual; + + Procedure SetToFirstRecord; virtual; abstract; + Procedure SetToLastRecord; virtual; abstract; + + Procedure StoreCurrentRecord; virtual; abstract; + Procedure RestoreCurrentRecord; virtual; abstract; + + Function CanScrollForward : Boolean; virtual; abstract; + Procedure DoScrollForward; virtual; abstract; + + Procedure StoreCurrentRecIntoBookmark(Const ABookmark: PRESTDWMemBookmark); virtual; abstract; + Procedure StoreSpareRecIntoBookmark(Const ABookmark: PRESTDWMemBookmark); virtual; abstract; + Procedure GotoBookmark(Const ABookmark : PRESTDWMemBookmark); virtual; abstract; + Function BookmarkValid(Const ABookmark: PRESTDWMemBookmark): boolean; virtual; + Function CompareBookmarks(Const ABookmark1, ABookmark2 : PRESTDWMemBookmark) : integer; virtual; + Function SameBookmarks(Const ABookmark1, ABookmark2 : PRESTDWMemBookmark) : boolean; virtual; + + Procedure InitialiseIndex; virtual; abstract; + + Procedure InitialiseSpareRecord(Const ASpareRecord : TRecordBuffer); virtual; abstract; + Procedure ReleaseSpareRecord; virtual; abstract; + + Procedure BeginUpdate; virtual; abstract; + // Adds a record to the end of the index as the new last record (spare record) + // Normally only used in GetNextPacket + Procedure AddRecord; virtual; abstract; + // Inserts a record before the current record, or if the record is sorted, + // inserts it in the proper position + Procedure InsertRecordBeforeCurrentRecord(Const ARecord : TRecordBuffer); virtual; abstract; + Procedure RemoveRecordFromIndex(Const ABookmark : TRESTDWMemBookmark); virtual; abstract; + Procedure OrderCurrentRecord; virtual; abstract; + Procedure EndUpdate; virtual; abstract; + + property SpareRecord : TRecordBuffer read GetSpareRecord; + property SpareBuffer : TRecordBuffer read GetSpareBuffer; + property CurrentRecord : TRecordBuffer read GetCurrentRecord; + property CurrentBuffer : Pointer read GetCurrentBuffer; + property IsInitialized : boolean read GetIsInitialized; + property BookmarkSize : integer read GetBookmarkSize; + property RecNo : Longint read GetRecNo write SetRecNo; End; - TDoubleLinkedBufIndex = class(TRESTDWIndex) + + { TRESTDWMemDoubleLinkedIndex } + + TRESTDWMemDoubleLinkedIndex = Class(TRESTDWMemInternalIndex) Private - FCursOnFirstRec : Boolean; - FStoredRecBuf : PRESTDWRecLinkItem; - FCurrentRecBuf : PRESTDWRecLinkItem; + FCursOnFirstRec : boolean; + + FStoredRecBuf : PRESTDWMemRecLinkItem; + FCurrentRecBuf : PRESTDWMemRecLinkItem; Protected - Function GetBookmarkSize : Integer; Override; - Function GetCurrentBuffer : Pointer; Override; - Function GetCurrentRecord : TRecordBuffer; Override; - Function GetIsInitialized : Boolean; Override; - Function GetSpareBuffer : TRecordBuffer; Override; - Function GetSpareRecord : TRecordBuffer; Override; - Function GetRecNo : Longint; Override; - Procedure SetRecNo(ARecNo : Longint); Override; + Function GetBookmarkSize: integer; override; + Function GetCurrentBuffer: Pointer; override; + Function GetCurrentRecord: TRecordBuffer; override; + Function GetIsInitialized: boolean; override; + Function GetSpareBuffer: TRecordBuffer; override; + Function GetSpareRecord: TRecordBuffer; override; + Function GetRecNo: Longint; override; + Procedure SetRecNo(ARecNo: Longint); override; Public - FLastRecBuf : PRESTDWRecLinkItem; - FFirstRecBuf : PRESTDWRecLinkItem; - FNeedScroll : Boolean; - Function ScrollBackward : TGetResult; Override; - Function ScrollForward : TGetResult; Override; - Function GetCurrent : TGetResult; Override; - Function ScrollFirst : TGetResult; Override; - Procedure ScrollLast; Override; - Function GetRecord(ABookmark : PRESTDWBookmark; - GetMode : TGetMode): TGetResult; Override; - Procedure SetToFirstRecord; Override; - Procedure SetToLastRecord; Override; - Procedure StoreCurrentRecord; Override; - procedure RestoreCurrentRecord; Override; - Function CanScrollForward : Boolean; Override; - Procedure DoScrollForward; Override; - Procedure StoreCurrentRecIntoBookmark(Const ABookmark : PRESTDWBookmark); Override; - Procedure StoreSpareRecIntoBookmark (Const ABookmark : PRESTDWBookmark); Override; - Procedure GotoBookmark (Const ABookmark : PRESTDWBookmark); Override; - Function CompareBookmarks (Const ABookmark1, - ABookmark2 : PRESTDWBookmark) : Integer; Override; - Function SameBookmarks (Const ABookmark1, - ABookmark2 : PRESTDWBookmark) : Boolean; Override; - Procedure InitialiseIndex; Override; - Procedure InitialiseSpareRecord (Const ASpareRecord : TRecordBuffer); Override; - Procedure ReleaseSpareRecord; Override; - Procedure BeginUpdate; Override; - Procedure AddRecord; Override; - Procedure InsertRecordBeforeCurrentRecord(Const ARecord : TRecordBuffer); Override; - Procedure RemoveRecordFromIndex (Const ABookmark : TRESTDWBookmark); Override; - Procedure OrderCurrentRecord; Override; - Procedure EndUpdate; Override; + FLastRecBuf : PRESTDWMemRecLinkItem; + FFirstRecBuf : PRESTDWMemRecLinkItem; + FNeedScroll : Boolean; + + Function ScrollBackward : TGetResult; override; + Function ScrollForward : TGetResult; override; + Function GetCurrent : TGetResult; override; + Function ScrollFirst : TGetResult; override; + Procedure ScrollLast; override; + Function GetRecord(ABookmark: PRESTDWMemBookmark; GetMode: TGetMode): TGetResult; override; + + Procedure SetToFirstRecord; override; + Procedure SetToLastRecord; override; + + Procedure StoreCurrentRecord; override; + Procedure RestoreCurrentRecord; override; + + Function CanScrollForward : Boolean; override; + Procedure DoScrollForward; override; + + Procedure StoreCurrentRecIntoBookmark(Const ABookmark: PRESTDWMemBookmark); override; + Procedure StoreSpareRecIntoBookmark(Const ABookmark: PRESTDWMemBookmark); override; + Procedure GotoBookmark(Const ABookmark : PRESTDWMemBookmark); override; + Function CompareBookmarks(Const ABookmark1, ABookmark2: PRESTDWMemBookmark): integer; override; + Function SameBookmarks(Const ABookmark1, ABookmark2 : PRESTDWMemBookmark) : boolean; override; + Procedure InitialiseIndex; override; + + Procedure InitialiseSpareRecord(Const ASpareRecord : TRecordBuffer); override; + Procedure ReleaseSpareRecord; override; + + Procedure BeginUpdate; override; + Procedure AddRecord; override; + Procedure InsertRecordBeforeCurrentRecord(Const ARecord : TRecordBuffer); override; + Procedure RemoveRecordFromIndex(Const ABookmark : TRESTDWMemBookmark); override; + Procedure OrderCurrentRecord; override; + Procedure EndUpdate; override; End; - TRESTDWDatasetIndex = Class(TIndexDef) + + { TRESTDWMemUniDirectionalIndex } + + TRESTDWMemUniDirectionalIndex = Class(TRESTDWMemInternalIndex) Private - FBufferIndex : TRESTDWIndex; - FDiscardOnClose : Boolean; - FIndexType : TIndexType; + FSPareBuffer: TRecordBuffer; + Protected + Function GetBookmarkSize: integer; override; + Function GetCurrentBuffer: Pointer; override; + Function GetCurrentRecord: TRecordBuffer; override; + Function GetIsInitialized: boolean; override; + Function GetSpareBuffer: TRecordBuffer; override; + Function GetSpareRecord: TRecordBuffer; override; + Function GetRecNo: Longint; override; + Procedure SetRecNo(ARecNo: Longint); override; Public - Destructor Destroy; Override; - // Free FBufferIndex; - Procedure Clearindex; - // Set TIndexDef properties on FBufferIndex; - Procedure SetIndexProperties; - // Return true if the buffer must be built. - // Default buffer must not be built, custom only when it is not the current. - Function MustBuild (aCurrent : TRESTDWDatasetIndex) : Boolean; - // Return true if the buffer must be updated - // This are all indexes except custom, unless it is the active index - Function IsActiveIndex(aCurrent : TRESTDWDatasetIndex) : Boolean; - // The actual buffer. - Property BufferIndex : TRESTDWIndex Read FBufferIndex Write FBufferIndex; - // If the Index is created after Open, then it will be discarded on close. - Property DiscardOnClose : Boolean Read FDiscardOnClose; - // Skip build of this index - Property IndexType : TIndexType Read FIndexType Write FIndexType; + Function ScrollBackward : TGetResult; override; + Function ScrollForward : TGetResult; override; + Function GetCurrent : TGetResult; override; + Function ScrollFirst : TGetResult; override; + Procedure ScrollLast; override; + + Procedure SetToFirstRecord; override; + Procedure SetToLastRecord; override; + + Procedure StoreCurrentRecord; override; + Procedure RestoreCurrentRecord; override; + + Function CanScrollForward : Boolean; override; + Procedure DoScrollForward; override; + + Procedure StoreCurrentRecIntoBookmark(Const ABookmark: PRESTDWMemBookmark); override; + Procedure StoreSpareRecIntoBookmark(Const ABookmark: PRESTDWMemBookmark); override; + Procedure GotoBookmark(Const ABookmark : PRESTDWMemBookmark); override; + + Procedure InitialiseIndex; override; + Procedure InitialiseSpareRecord(Const ASpareRecord : TRecordBuffer); override; + Procedure ReleaseSpareRecord; override; + + Procedure BeginUpdate; override; + Procedure AddRecord; override; + Procedure InsertRecordBeforeCurrentRecord(Const ARecord : TRecordBuffer); override; + Procedure RemoveRecordFromIndex(Const ABookmark : TRESTDWMemBookmark); override; + Procedure OrderCurrentRecord; override; + Procedure EndUpdate; override; End; - TRESTDWDatasetIndexDefs = Class(TIndexDefs) + + + { TRESTDWMemArrayIndex } + + TRESTDWMemArrayIndex = Class(TRESTDWMemInternalIndex) Private - Function GetBufDatasetIndex(AIndex : Integer) : TRESTDWDatasetIndex; - Function GetBufferIndex(AIndex : Integer) : TRESTDWIndex; + FStoredRecBuf : integer; + + FInitialBuffers, + FGrowBuffer : integer; + Function GetRecordFromBookmark(ABookmark: TRESTDWMemBookmark) : integer; + Protected + Function GetBookmarkSize: integer; override; + Function GetCurrentBuffer: Pointer; override; + Function GetCurrentRecord: TRecordBuffer; override; + Function GetIsInitialized: boolean; override; + Function GetSpareBuffer: TRecordBuffer; override; + Function GetSpareRecord: TRecordBuffer; override; + Function GetRecNo: Longint; override; + Procedure SetRecNo(ARecNo: Longint); override; Public - Constructor Create(aDataset : TDataset); {$IFNDEF FPC} - {$IF CompilerVersion > 21} - Override; - {$IFEND} - {$ELSE} - Override; - {$ENDIF} - // Does not raise an exception if not found. - Function FindIndex(const IndexName: string) : TRESTDWDatasetIndex; - Property Indexdefs [AIndex : Integer] : TRESTDWDatasetIndex Read GetBufDatasetIndex; - Property Indexes [AIndex : Integer] : TRESTDWIndex Read GetBufferIndex; + FRecordArray : array Of Pointer; + FCurrentRecInd : integer; + FLastRecInd : integer; + FNeedScroll : Boolean; + Constructor Create(Const ADataset: TRESTDWCustomMemTable); override; + Function ScrollBackward : TGetResult; override; + Function ScrollForward : TGetResult; override; + Function GetCurrent : TGetResult; override; + Function ScrollFirst : TGetResult; override; + Procedure ScrollLast; override; + + Procedure SetToFirstRecord; override; + Procedure SetToLastRecord; override; + + Procedure StoreCurrentRecord; override; + Procedure RestoreCurrentRecord; override; + + Function CanScrollForward : Boolean; override; + Procedure DoScrollForward; override; + + Procedure StoreCurrentRecIntoBookmark(Const ABookmark: PRESTDWMemBookmark); override; + Procedure StoreSpareRecIntoBookmark(Const ABookmark: PRESTDWMemBookmark); override; + Procedure GotoBookmark(Const ABookmark : PRESTDWMemBookmark); override; + + Procedure InitialiseIndex; override; + + Procedure InitialiseSpareRecord(Const ASpareRecord : TRecordBuffer); override; + Procedure ReleaseSpareRecord; override; + + Procedure BeginUpdate; override; + Procedure AddRecord; override; + Procedure InsertRecordBeforeCurrentRecord(Const ARecord : TRecordBuffer); override; + Procedure RemoveRecordFromIndex(Const ABookmark : TRESTDWMemBookmark); override; + Procedure EndUpdate; override; End; - { TRESTDWMemTable } - TRESTDWMemTable = Class(TDataset, IRESTDWMemTable) - Private - FSaveLoadState : TSaveLoadState; - aFilterRecs, - FMaxIndexesCount, - FPacketRecords, - FRecordFilterPos, - FRecordPos, - FRecordSize, - FBookmarkOfs, - FBlobOfs, - FRecBufSize, - FRowsOriginal, - FRowsChanged, - FRowsAffected : Integer; - FOffsets : TIntArray; - FAutoInc : Longint; - FDeletedValues, - FIndexList : TList; - FSrcAutoIncField : TField; - FDataSet : TDataset; - FFieldAttrs : TFieldAttrs; - FFetch, - FAllPacketsFetched, - FRefreshing, - FClearing, - FTrimEmptyString, - FExactApply, - FAutoIncAsInteger, - FOneValueInArray, - FActive, - FCaseInsensitiveSort, - FDescendingSort, - FDataSetClosed, - FLoadStructure, - FLoadRecords : Boolean; - FDsgnFieldName, - FIndexFieldNames, - FIndexName, - FStatusName, - FKeyFieldNames : String; - FApplyMode : TApplyMode; - FBeforeApply, - FAfterApply : TApplyEvent; - FBeforeApplyRecord, - FAfterApplyRecord : TApplyRecordEvent; - FFieldName : Array Of String; - FNullmaskSize : Byte; - FFilterParser : TExprParser; - FStorageDataType : TRESTDWStorageBase; - FIndexes : TRESTDWDataSetIndexDefs; - FDefaultIndex, - FCurrentIndexDef : TRESTDWDatasetIndex; - FFieldDefClass : TFieldClass; - Procedure CalcOffSets; - Function AddRecord : TRESTDWMTMemoryRecord; - Function InsertRecord(Index : Integer) : TRESTDWMTMemoryRecord; - Function FindRecordID(ID : Integer) : TRESTDWMTMemoryRecord; - Procedure CreateIndexList(Const FieldNames : DWWideString); - Procedure FreeIndexList; - Procedure QuickSort (L, R : Integer; - Compare : TCompareRecords); - Procedure Sort; - Function CalcRecordSize : Integer; - Function GetCapacity : Integer; - Function RecordFilter : Boolean; - Procedure SetCapacity(Value : Integer); - Procedure ClearRecords; - Procedure InitBufferPointers(GetProps : Boolean); - Procedure CheckStructure (UseAutoIncAsInteger : Boolean = False); - Procedure AddStatusField; - Procedure HideStatusField; - Function CopyFromDataSet: Integer; - Procedure ClearChanges; - Function GetFieldData (FieldNo : Integer; - Var Buffer : TValueBuffer): Boolean; overload;{$IFNDEF FPC}override;{$ENDIF} - {$IFDEF FPC} - Function GetFieldData (Field : TField; - Buffer : Pointer; - NativeFormat : Boolean): Boolean; Overload; Override; - {$ENDIF} - Procedure DoBeforeApply (ADataset : TDataset; - RowsPending : Integer); - Procedure DoAfterApply (ADataset : TDataset; - RowsApplied : Integer); - Procedure DoBeforeApplyRecord (ADataset : TDataset; - RS : TRecordStatus; - aFound : Boolean); - Procedure DoAfterApplyRecord (ADataset : TDataset; - RS : TRecordStatus; - aApply : Boolean); - Procedure InternalGotoBookmarkData(BookmarkData : TRESTDWMTBookmarkData); - Procedure InternalSetFieldData (Field : TField; - Buffer : Pointer; - Const ValidateBuffer : TRESTDWMTValueBuffer); - {$IFDEF FPC} - Procedure SetProviderFlags; - {$ENDIF} + + { TRESTDWMemTableReader } + + TRESTDWMemRowStateValue = (rsvOriginal, rsvDeleted, rsvInserted, rsvUpdated, rsvDetailUpdates); + TRESTDWMemRowState = set Of TRESTDWMemRowStateValue; + + + { TRESTDWMemDataPacketReader } + + TRESTDWMemDataPacketFormat = (dfBinary,dfXML,dfXMLUTF8,dfAny,dfDefault); + + TRESTDWMemDataPacketReader = Class; + TRESTDWMemDataPacketReaderClass = Class Of TRESTDWMemDataPacketReader; + TRESTDWMemDataPacketReader = Class(TObject) + FDataSet: TRESTDWCustomMemTable; + FStream : TStream; Protected - Function IsLookup (Index : Integer) : Boolean; - Function GetFieldDef (Index : Integer) : Integer; - Function GetFieldIndex (Const aName : String) : Integer; - Function FindFieldIndex (Field : TField) : Integer; - Function FindFieldData (Buffer : Pointer; - Field : TField) : Pointer; - Function CompareFields (Data1, - Data2 : Pointer; - FieldType : TFieldType; - CaseInsensitive : Boolean) : Integer; Virtual; - Function GetFieldClass (FieldType : TFieldType) : TFieldClass; Override; - Procedure DesignNotify (Const AFieldName : String; - Dummy : Integer); - - // Delphi 2006+ has support for DWWideString - {$IF DEFINED(FPC) OR DEFINED(RESTDWVCL)} - Procedure DataConvert (Field : TField; - Source, - Dest : Pointer; - ToNative : Boolean); Override; - {$IFEND} -// Procedure DefChanged (Sender : TObject); Override; - Procedure AssignMemoryRecord (Rec : TRESTDWMTMemoryRecord; - Buffer : PRESTDWMTMemBuffer); - Function GetActiveRecBuf (Var RecBuf : PRESTDWMTMemBuffer) : Boolean;Virtual; - Procedure InitFieldDefsFromFields; - Procedure InitFieldDefsFromFieldsInternal; - Procedure RecordToBuffer (Rec : TRESTDWMTMemoryRecord; - Buffer : PRESTDWMTMemBuffer); - Procedure SetAutoIncFields (Buffer : PRESTDWMTMemBuffer); Virtual; - Function CompareRecords (Item1, - Item2 : TRESTDWMTMemoryRecord): Integer;Virtual; - Function GetBlobData (Field : TField; - Buffer : PRESTDWMTMemBuffer) : TMemBlobData; - Procedure SetBlobData (Field : TField; - Buffer : PRESTDWMTMemBuffer; - Value : TMemBlobData); - {$IFDEF NEXTGEN} - Function AllocRecBuf : TRecBuf; override; - Procedure FreeRecBuf (Var Buffer : TRecBuf); Override; - {$ENDIF NEXTGEN} - Procedure InternalInitRecord (Buffer :{$IFDEF NEXTGEN}TRecBuf{$ELSE}TRecordBuffer{$ENDIF}); Override; - Function GetRecord (Buffer :{$IFDEF NEXTGEN}TRecBuf{$ELSE}TRecordBuffer{$ENDIF}; - GetMode : TGetMode; - DoCheck : Boolean) : TGetResult; Overload; Override; - Procedure GetBookmarkData (Buffer :{$IFDEF NEXTGEN}TRecBuf{$ELSE}TRecordBuffer{$ENDIF}; - Data : TRESTDWMTBookmark); Overload;Override; - Function GetBookmarkFlag (Buffer :{$IFDEF NEXTGEN}TRecBuf{$ELSE}TRecordBuffer{$ENDIF}) : TBookmarkFlag;Overload;Override; - Procedure InternalSetToRecord(Buffer :{$IFDEF NEXTGEN}TRecBuf{$ELSE}TRecordBuffer{$ENDIF}); Overload;Override; - Procedure SetBookmarkFlag (Buffer :{$IFDEF NEXTGEN}TRecBuf{$ELSE}TRecordBuffer{$ENDIF}; - Value : TBookmarkFlag);Overload; Override; - Procedure SetBookmarkData (Buffer :{$IFDEF NEXTGEN}TRecBuf{$ELSE}TRecordBuffer{$ENDIF}; - Data : TRESTDWMTBookmark); Overload;Override; - Procedure InitRecord (Buffer :{$IFDEF NEXTGEN}TRecBuf{$ELSE}TRecordBuffer{$ENDIF}); Overload;Override; - Function GetCurrentRecord (Buffer :{$IFDEF NEXTGEN}TRecBuf{$ELSE}TRecordBuffer{$ENDIF}): Boolean; Overload;Override; - Procedure ClearCalcFields (Buffer :{$IFDEF NEXTGEN}NativeInt{$ELSE}TRecordBuffer{$ENDIF}); Override; - Function GetRecordSize : Word; Override; - Procedure SetFiltered (Value : Boolean); Overload; Override; - Procedure SetOnFilterRecord(Const Value : TFilterRecordEvent); Override; - Procedure SetFieldData (Field : TField; - Buffer : TRESTDWMTValueBuffer);Overload;Override; - {$IFNDEF NEXTGEN} - {$IFDEF RTL240_UP} - Procedure SetFieldData (Field : TField; - Buffer : Pointer);Overload;Override; - Procedure GetBookmarkData (Buffer : TRecordBuffer; - Data : Pointer);Overload;Override; - Procedure InternalGotoBookmark(Bookmark : Pointer);Overload;Override; - Procedure SetBookmarkData (Buffer : TRecordBuffer; - Data : Pointer);Overload;Override; - {$ENDIF RTL240_UP} - {$ENDIF ~NEXTGEN} - Procedure CloseBlob (Field : TField);Override; - Procedure InternalGotoBookmark(aBookmark : TRESTDWMTBookmark);Overload;Override; - Function GetIsIndexField (Field : TField): Boolean;Override; - Procedure CreateFields; Override; - Procedure InternalFirst; Override; - Procedure InternalLast; Override; - Procedure InternalDelete; Override; - Procedure InternalPost; Override; - Procedure InternalClose; Override; - procedure CheckRequiredFields; - Procedure InternalHandleException; Override; - Procedure InternalInitFieldDefs; Override; - Procedure InternalOpen; Override; - Procedure OpenCursor(InfoQuery : Boolean);Overload;Override; - Function IsCursorOpen : Boolean; Override; - Function GetRecNo : Integer; Override; - Procedure SetRecNo (Value : Integer);Override; - Procedure DoAfterOpen; Override; - Procedure SetFilterText(Const Value : String);{$IFNDEF FPC}Override;{$ENDIF} - Function ParserGetVariableValue(Sender : TObject; - Const VarName : String; - Var Value : Variant) : Boolean;Virtual; - Procedure Notification (AComponent : TComponent; - Operation : TOperation);Override; - Function GetBlobRec (Field : TField; - Rec : TRESTDWMTMemoryRecord) : TMemBlobData; - procedure ClearIndexes; - Function GetDataset : TDataset; - Procedure SetIndexName(AValue : String); + Class Function RowStateToByte(Const ARowState : TRESTDWMemRowState) : byte; + Class Function ByteToRowState(Const AByte : Byte) : TRESTDWMemRowState; + Procedure RestoreBlobField(AField: TField; ASource: pointer; ASize: integer); + property DataSet: TRESTDWCustomMemTable read FDataSet; + property Stream: TStream read FStream; Public - FLastID : Integer; - FBlobs : TMemBlobArray; - FRecords : TRecordList; - {$IFNDEF FPC} - FFilterExpression : TRDWABExprParser; - {$ENDIF} - Constructor Create(AOwner : TComponent);Override; - Destructor Destroy;Override; - Function AllocRecordBuffer : TRecordBuffer;{$IFNDEF NEXTGEN}Override;{$ENDIF} - Procedure FreeRecordBuffer (Var Buffer : TRecordBuffer);{$IFNDEF NEXTGEN}Override;{$ENDIF} - Function GetMemoryRecord (Index : Integer) : TRESTDWMTMemoryRecord; - Procedure InternalAddRecord (Buffer : {$IFDEF FPC}Pointer{$ELSE} - {$IFDEF RESTDWANDROID}TRecBuf{$ELSE} - {$IF CompilerVersion >22}Pointer{$ELSE}TRecordBuffer{$IFEND}{$ENDIF}{$ENDIF}; - aAppend : Boolean); Overload; - Function DataTypeSuported (datatype : TFieldType) : Boolean; - Function DataTypeIsBlobTypes (datatype : TFieldType) : Boolean; - Function GetCalcFieldLen (FieldType : TFieldType; - Size : Word) : Word; - Function InternalGetFieldData(Field : TField; - Var Buffer : TRESTDWMTValueBuffer; - cSize : Integer = 0) : Boolean; - Function GetOffSets (aField : TField) : Word;Overload; - Function GetOffSets (Index : Integer) : Word;Overload; - Function GetOffSetsBlobs : Word; - Procedure SetMemoryRecordData (Buffer : PRESTDWMTMemBuffer; - Pos : Integer); Virtual; - Function GetRecordCount : Integer; Override; - Function BookmarkValid (aBookmark : TBookmark) : Boolean;Override; - Function CompareBookmarks(aBookmark1, - aBookmark2 : TBookmark) : Integer;Override; - Function CreateBlobStream(Field : TField; - Mode : TBlobStreamMode) : TStream;Override; - Procedure FixReadOnlyFields (MakeReadOnly : Boolean); - Procedure ClearBuffer; - Function GetBlob (aRecNo, - Index : Integer) : PMemBlobData; - Procedure GetFieldList(List: TList; const FieldNames: string); overload; - Function GetFieldData (Field : TField; - {$IFNDEF FPC} - {$IF CompilerVersion > 21}Var{$IFEND} - Buffer : TRESTDWMTValueBuffer - {$ELSE} - Buffer : Pointer - {$ENDIF}) : Boolean;Override; - {$IFNDEF NEXTGEN} - {$IFDEF RTL240_UP} - Function GetFieldData (Field : TField; - Buffer : Pointer) : Boolean;Overload;Override; - {$ENDIF RTL240_UP} - {$ENDIF ~NEXTGEN} - {$IFDEF FPC} - Procedure SetFieldValues(const FieldName: string; Value: Variant); Override; - {$ENDIF} - Function IsSequenced : Boolean; Override; - Function Locate(Const KeyFields : String; - Const KeyValues : Variant; - Options : TLocateOptions) : Boolean;{$IFNDEF FPC}Override;{$ENDIF} - Function Lookup(Const KeyFields : String; - Const KeyValues : Variant; - Const ResultFields : String) : Variant;{$IFNDEF FPC}Override;{$ENDIF} - Procedure SortOnFields(Const FieldNames : String = ''; - CaseInsensitive : Boolean = True; - Descending : Boolean = False); - Procedure SwapRecords (Idx1 : Integer; - Idx2 : Integer); - Procedure EmptyTable; - Procedure CopyStructure (Source : TDataset; - UseAutoIncAsInteger : Boolean = False); - Function LoadFromDataSet(Source : TDataset; - aRecordCount : Integer; - Mode : TLoadMode; - DisableAllControls : Boolean = True) : Integer; - Function SaveToDataSet (Dest : TDataset; - aRecordCount : Integer; - DisableAllControls : Boolean = True) : Integer; - Function GetValues (FldNames : String = '') : Variant; - Function FindDeleted (KeyValues : Variant) : Integer; - Procedure AfterLoad; - Function IsDeleted (out Index : Integer) : Boolean; - Function IsInserted : Boolean; - Function IsUpdated : Boolean; - Function IsOriginal : Boolean; - Procedure CancelChanges; - Function ApplyChanges : Boolean; - Function IsLoading : Boolean; - Function IsSaving : Boolean; - Procedure SaveToStream (Var stream : TStream); - Procedure LoadFromStream(stream : TStream); - Procedure Assign (Source : TPersistent);Reintroduce;Overload;Override; - Function GetCurrentIndexBuf : TRESTDWIndex; - Procedure SetIndexDefs(Value : TIndexDefs); - Function GetIndexDefs : TIndexDefs; - Function GetIndexName : String; - Function GetIndexFieldNames : String; - Function getnextpacket : Integer; - Function DefaultBufferIndex : TRESTDWIndex; - Function DefaultIndex : TRESTDWDatasetIndex; - Procedure BuildIndexes; - Function GetNewBlobBuffer : PBlobBuffer; - Function LoadField (FieldDef : TFieldDef; - buffer : Pointer; - out CreateBlob : boolean) : Boolean; - Function Fetch : Boolean;Virtual; - Procedure LoadBlobIntoBuffer(FieldDef : TFieldDef; - ABlobBuf : PRESTDWBlobField); Virtual; Abstract; - Function LoadBuffer (Buffer : TRecordBuffer) : TGetResult; - Procedure BuildIndex (AIndex : TRESTDWIndex); - Procedure FetchAll; - Function IntAllocRecordBuffer : TRecordBuffer; - Procedure SetIndexFieldNames (Const AValue : String); - Procedure InternalCreateIndex(F : TRESTDWDataSetIndex); - Function InternalAddIndex (Const AName, - AFields : String; - AOptions : TIndexOptions; - Const ADescFields : String; - Const ACaseInsFields : String) : TRESTDWDatasetIndex; - Function BufferOffset : Integer; - Procedure ProcessFieldsToCompareStruct(Const AFields, - ADescFields, - ACInsFields : TList; - Const AIndexOptions : TIndexOptions; - Const ALocateOptions : TLocateOptions; - out ACompareStruct : TDBCompareStruct); - Procedure InitDefaultIndexes; - Procedure BuildCustomIndex; - Procedure SetMaxIndexesCount (Const AValue : Integer); - Function GetBufIndex (Aindex : Integer) : TRESTDWIndex; - Function GetBufIndexDef (Aindex : Integer) : TRESTDWDatasetIndex; - Property SaveLoadState : TSaveLoadState Read FSaveLoadState; - Property RowsOriginal : Integer Read FRowsOriginal; - Property RowsChanged : Integer Read FRowsChanged; - Property RowsAffected : Integer Read FRowsAffected; - Property Refreshing : Boolean Read FRefreshing; - Property StorageDataType : TRESTDWStorageBase Read FStorageDataType Write FStorageDataType; - Property RESTDWIndexes [Aindex : Integer] : TRESTDWIndex Read GetBufIndex; - Property RESTDWIndexDefs[Aindex : Integer] : TRESTDWDatasetIndex Read GetBufIndexDef; - Property FieldAttrs : TFieldAttrs Read FFieldAttrs Write FFieldAttrs; - Property BlobFieldCount; - Property Records [Index : Integer] : TRESTDWMTMemoryRecord Read GetMemoryRecord; - published - Property Capacity : Integer Read GetCapacity Write SetCapacity Default 0; - Property Active; - Property AutoCalcFields; - Property Filtered; - Property FilterOptions; - Property FieldDefs; - {$IFNDEF FPC} - Property ObjectView default False; - {$ENDIF} - Property DatasetClosed : Boolean Read FDataSetClosed Write FDataSetClosed Default False; - Property KeyFieldNames : String Read FKeyFieldNames Write FKeyFieldNames; - Property LoadStructure : Boolean Read FLoadStructure Write FLoadStructure Default False; - Property LoadRecords : Boolean Read FLoadRecords Write FLoadRecords Default False; - Property ApplyMode : TApplyMode Read FApplyMode Write FApplyMode Default amNone; - Property ExactApply : Boolean Read FExactApply Write FExactApply Default False; - Property AutoIncAsInteger : Boolean Read FAutoIncAsInteger Write FAutoIncAsInteger Default False; - Property OneValueInArray : Boolean Read FOneValueInArray Write FOneValueInArray Default True; - Property TrimEmptyString : Boolean Read FTrimEmptyString Write FTrimEmptyString Default True; - Property BeforeApply : TApplyEvent Read FBeforeApply Write FBeforeApply; - Property AfterApply : TApplyEvent Read FAfterApply Write FAfterApply; - Property BeforeApplyRecord : TApplyRecordEvent Read FBeforeApplyRecord Write FBeforeApplyRecord; - Property AfterApplyRecord : TApplyRecordEvent Read FAfterApplyRecord Write FAfterApplyRecord; - Property IndexDefs : TIndexDefs Read GetIndexDefs Write SetIndexDefs; - Property IndexName : String Read GetIndexName Write SetIndexName; - Property IndexFieldNames : String Read GetIndexFieldNames Write SetIndexFieldNames; - Property MaxIndexesCount : Integer Read FMaxIndexesCount Write SetMaxIndexesCount default 2; - Property Filter; - Property BeforeOpen; - Property AfterOpen; - Property BeforeClose; - Property AfterClose; - Property BeforeInsert; - Property AfterInsert; - Property BeforeEdit; - Property AfterEdit; - Property BeforePost; - Property AfterPost; - Property BeforeCancel; - Property AfterCancel; - Property BeforeDelete; - Property AfterDelete; - Property BeforeScroll; - Property AfterScroll; - Property OnCalcFields; - Property OnDeleteError; - Property OnEditError; - Property OnFilterRecord; - Property OnNewRecord; - Property OnPostError; + Constructor Create(ADataSet: TRESTDWCustomMemTable; AStream : TStream); virtual; + // Load a dataset from stream: + // Load the field definitions from a stream. + Procedure LoadFieldDefs(Var AnAutoIncValue : integer); virtual; abstract; + // Is called before the records are loaded + Procedure InitLoadRecords; virtual; abstract; + // Returns if there is at least one more record available in the stream + Function GetCurrentRecord : boolean; virtual; abstract; + // Return the RowState of the current record, and the order of the update + Function GetRecordRowState(out AUpdOrder : Integer) : TRESTDWMemRowState; virtual; abstract; + // Store a record from stream in the current record buffer + Procedure RestoreRecord; virtual; abstract; + // Move the stream to the next record + Procedure GotoNextRecord; virtual; abstract; + + // Store a dataset to stream: + // Save the field definitions to a stream. + Procedure StoreFieldDefs(AnAutoIncValue : integer); virtual; abstract; + // Save a record from the current record buffer to the stream + Procedure StoreRecord(ARowState : TRESTDWMemRowState; AUpdOrder : integer = 0); virtual; abstract; + // Is called after all records are stored + Procedure FinalizeStoreRecords; virtual; abstract; + // Checks if the provided stream is of the right format for this class + Class Function RecognizeStream(AStream : TStream) : boolean; virtual; abstract; End; - TBlobStream = class(TMemoryStream) - private - FFieldIndex: Integer; - FRecNo: Integer; - FDataSet: TRESTDWMemtable; - public - destructor Destroy; Override; - end; - TStreamField = Class(TBlobField) + + { TRESTDWTBinaryDatapacketReader } + + { Data layout: + Header section: + Identification: 16 bytes: 'BinRESTDWDataSet' + Version: 1 byte + Columns section: + Number of Fields: 2 bytes + For each FieldDef: Name, DisplayName, Size: 2 bytes, DataType: 2 bytes, ReadOnlyAttr: 1 byte + Parameter section: + AutoInc Value: 4 bytes + Rows section: + Row header: each row begins with $fe: 1 byte + row state: 1 byte (original, deleted, inserted, modified) + update order: 4 bytes + null bitmap: 1 byte per each 8 fields (if field is null corresponding bit is 1) + Row data: variable length data are prefixed with 4 byte length indicator + null fields are not stored (see: null bitmap) + } + + TRESTDWTBinaryDatapacketReader = Class(TRESTDWMemDataPacketReader) Private - FStream : TStream; - Function GetAsStream : TStream; + Const + RESTDWBinaryIdent = 'BinRESTDWDataSet'; + StringFieldTypes = [ftString,ftFixedChar,ftWideString,ftFixedWideChar]; + BlobFieldTypes = [ftBlob,ftMemo,ftGraphic,ftWideMemo]; + VarLenFieldTypes = StringFieldTypes + BlobFieldTypes + [ftBytes,ftVarBytes]; + Var + FNullBitmapSize: integer; + FNullBitmap: TRESTDWMemBytes; + FWireFieldTypes: Array Of Byte; + Function ReadByteValue: Byte; + Function ReadWordValue: Word; + Function ReadDWordValue: LongWord; + Function ReadAnsiStringValue: AnsiString; + Function GetFixedWireSize(AWireType: Byte; AField: TField): Cardinal; + Procedure WriteByteValue(AValue: Byte); + Procedure WriteWordValue(AValue: Word); + Procedure WriteDWordValue(AValue: LongWord); + Procedure WriteAnsiStringValue(Const AValue: AnsiString); + Protected + Var + FVersion: byte; Public - Constructor Create(AOwner : TComponent); Override; - Destructor Destroy; Override; - Procedure Put; - Property Value : TStream Read GetAsStream; + Constructor Create(ADataSet: TRESTDWCustomMemTable; AStream : TStream); override; + Procedure LoadFieldDefs(Var AnAutoIncValue : integer); override; + Procedure StoreFieldDefs(AnAutoIncValue : integer); override; + Procedure InitLoadRecords; override; + Function GetCurrentRecord : boolean; override; + Function GetRecordRowState(out AUpdOrder : Integer) : TRESTDWMemRowState; override; + Procedure RestoreRecord; override; + Procedure GotoNextRecord; override; + Procedure StoreRecord(ARowState : TRESTDWMemRowState; AUpdOrder : integer = 0); override; + Procedure FinalizeStoreRecords; override; + Class Function RecognizeStream(AStream : TStream) : boolean; override; End; - TRESTDWMTMemBlobStream = Class(TStream) - Private - FField : TBlobField; - FDataSet : TRESTDWMemTable; - FBuffer : PRESTDWMTMemBuffer; - FActualBlob : Pointer; - FMode : TBlobStreamMode; - FCached, - FOpened, - FModified : Boolean; - FPosition : Longint; - Function GetBlobSize : Longint; - Function GetBlobFromRecord(Field : TField) : TMemBlobData; - {$IFDEF FPC} - Procedure SetBlobFromRecord(Field : TField; - Value : TMemBlobData); - {$ENDIF} - Public - Constructor Create(Field : TBlobField; - Mode : TBlobStreamMode); - Destructor Destroy; override; - Function Read (Var Buffer; - Count : Longint) : Longint;Overload;Override; - Function Write (Const Buffer; - Count : Longint) : Longint;Override; - Function Seek (Offset: Longint; - Origin: Word) : Longint;Override; - Procedure Truncate; + + TRESTDWBinaryFieldDef = Record + Name: String; + DisplayName: String; + Size: Word; + DataType: TFieldType; + ReadOnly: Boolean; End; - TSortOrder = (soAsc, soDesc); - //Possible sorting case sensitivity values - // sensitive sorting - insensitive sorting - TSortCaseSens = (scYes, scNo); - TRESTDWMemTableEx = Class(TRESTDWMemTable) + + TRESTDWBinaryPacketWriter = Class Private - fSortFields : String; - fSortOrder : TSortOrder; - fSortCaseSens : TSortCaseSens; - fAutoSortOnOpen, - fAutoRefreshOnFilterChanged : Boolean; - fFilteredRecordCount : Integer; - Function GetFilteredRecordCount : Integer; - Protected - Procedure SetFiltered (Value : Boolean); Override; - Procedure SetOnFilterRecord (Const Value : TFilterRecordEvent); Override; - Procedure InternalRefresh; Overload;Override; - {$IF Defined(MSWINDOWS) or Defined(WIN32) or Defined(WIN64) or Defined(WINDOWS)} - Procedure InternalAddRecord (Buffer : Pointer; - {$IFDEF FPC}aAppend : Boolean{$ELSE}Append : Boolean{$ENDIF});Overload; - {$IFEND} - Procedure InternalDelete; Overload;Override; - Procedure InternalPost; Overload;Override; - Procedure RefreshFilteredRecordCount; + FStream: TStream; + FFields: array Of TRESTDWBinaryFieldDef; + FNullBitmap: TRESTDWMemBytes; + FNullBitmapSize: Integer; + FNullBitmapPosition: Int64; +{$IFDEF RESTDWLAZARUS} + FDatabaseCharSet : TDatabaseCharSet; +{$ENDIF} + Procedure WriteAnsiString(Const AValue: AnsiString); + Class Function IsStringField(AType: TFieldType): Boolean; + Class Function IsVariableField(AType: TFieldType): Boolean; Public - Constructor Create (AOwner : TComponent);Override; - Procedure ReSortOnFields (pSortOrder : TSortOrder; - {$IFDEF FPC}afields : String{$ELSE}fields: String{$ENDIF}); - Function LoadFromDataSet (Source : TDataSet; - {$IFDEF FPC}aRecordCount : Integer;{$ELSE}RecordCount : Integer;{$ENDIF} - Mode : TLoadMode) : Integer; - Procedure EmptyTable; - Procedure CopyStructure (Source : TDataSet); - Function IsSortField (field : TField) : Boolean; - Published - Property SortOrder : TSortOrder Read fSortOrder Write fSortOrder; - Property SortCaseSens : TSortCaseSens Read fSortCaseSens Write fSortCaseSens; - Property SortFields : String Read fSortFields Write fSortFields nodefault; - Property AutoSortOnOpen : Boolean Read fAutoSortOnOpen Write fAutoSortOnOpen; - Property AutoRefreshOnFilterChanged : Boolean Read fAutoRefreshOnFilterChanged Write fAutoRefreshOnFilterChanged; - Property RecordCount : Integer Read GetFilteredRecordCount; + Constructor Create(AStream: TStream); + Procedure ClearFieldDefs; + Procedure AddFieldDef(Const AName, ADisplayName: String; ASize: Word; + ADataType: TFieldType; AReadOnly: Boolean); + Procedure StoreFieldDefs(AnAutoIncValue: Integer); + Procedure BeginRecord; + Procedure StoreNull(AFieldIndex: Integer); + Procedure StoreField(AFieldIndex: Integer; ABuffer: Pointer; ASize: LongWord); + Procedure EndRecord; +{$IFDEF RESTDWLAZARUS} + Property DatabaseCharSet : TDatabaseCharSet Read FDatabaseCharSet Write FDatabaseCharSet; +{$ENDIF} End; - Type - {$IFNDEF FPC} - {$IF CompilerVersion > 24} - TRESTDWNumericField = Class(TNumericField) - Protected - Function GetAsExtended : Extended; - Function GetAsString : String; Override; - Function GetAsVariant : Variant; Override; - Procedure SetAsExtended(Const AValue : Extended); - Procedure SetAsString (Const AValue : String); Override; - Procedure SetVarValue (Const AValue : Variant); Override; - Procedure SetAsFloat (AValue: Double); Override; - Function GetAsFloat : Double;Override; - Private - vSize, - vPrecision : Integer; - Public - Constructor Create(AOwner: TComponent); override; - {$IFNDEF SUPPORTS_CLASS_HELPERS} - Property AsExtended : Extended Read GetAsExtended Write SetAsExtended; - {$ENDIF} - Property Value : Extended Read GetAsExtended Write SetAsExtended; - Published - Property Size : Integer Read vSize Write vSize; - Property Precision : Integer Read vPrecision Write vPrecision; - End; - {$ELSE} - TRESTDWNumericField = Class(TNumericField) - Protected - {$IFDEF COMPILER17_UP} - Function GetAsExtended : Extended; Override; - {$ENDIF} - Function GetAsVariant : Variant; Override; - End; - {$IFEND} - {$ELSE} - TRESTDWNumericField = Class(TNumericField) + + { TRESTDWCustomMemTable } + +{$IFDEF FPC} + TRESTDWDBDataSet = TDBDataSet; +{$ELSE} + TRESTDWDBDataSet = TDataSet; +{$ENDIF} + + TRESTDWCustomMemTable = Class(TRESTDWDBDataSet) + Private + Type + + { TRESTDWMemTableIndex } + TRESTDWMemIndexType = (itNormal,itDefault,itCustom); + TRESTDWMemTableIndex = Class(TIndexDef) + Private + FBufferIndex: TRESTDWMemInternalIndex; + FDiscardOnClose: Boolean; + FIndexType : TRESTDWMemIndexType; + Public + Destructor Destroy; override; + // Free FBufferIndex; + Procedure Clearindex; + // Set TIndexDef properties on FBufferIndex; + Procedure SetIndexProperties; + // Return true if the buffer must be built. + // Default buffer must not be built, custom only when it is not the current. + Function MustBuild(aCurrent : TRESTDWMemTableIndex) : Boolean; + // Return true if the buffer must be updated + // This are all indexes except custom, unless it is the active index + Function IsActiveIndex(aCurrent : TRESTDWMemTableIndex) : Boolean; + // The actual buffer. + Property BufferIndex : TRESTDWMemInternalIndex Read FBufferIndex Write FBufferIndex; + // If the Index is created after Open, then it will be discarded on close. + Property DiscardOnClose : Boolean Read FDiscardOnClose; + // Skip build of this index + Property IndexType : TRESTDWMemIndexType Read FIndexType Write FIndexType; + End; + + { TRESTDWMemTableIndexDefs } + TRESTDWMemTableIndexDefs = Class(TIndexDefs) + Private + Function GetMemDatasetIndex(AIndex : Integer): TRESTDWMemTableIndex; + Function GetBufferIndex(AIndex : Integer): TRESTDWMemInternalIndex; + Public + Constructor Create(aDataset : TDataset); override; + // Does not raise an exception if not found. + Function FindIndex(Const IndexName: string): TRESTDWMemTableIndex; + Function AddMemTableIndexDef : TRESTDWMemTableIndex; + Property BufIndexdefs [AIndex : Integer] : TRESTDWMemTableIndex Read GetMemDatasetIndex; + Property BufIndexes [AIndex : Integer] : TRESTDWMemInternalIndex Read GetBufferIndex; + End; + + Procedure BuildCustomIndex; + Function GetBufIndex(Aindex : Integer): TRESTDWMemInternalIndex; + Function GetBufIndexDef(Aindex : Integer): TRESTDWMemTableIndex; + Function GetCurrentIndexBuf: TRESTDWMemInternalIndex; + Procedure InitUserIndexes; Private - vSize, - vPrecision : Integer; - Procedure SetAsExtended(Const AValue : Extended); + FFileName: TFileName; + FReadFromFile : boolean; + FFileStream : TFileStream; + FDatasetReader : TRESTDWMemDataPacketReader; + FMaxIndexesCount: integer; + FDefaultIndex, + FCurrentIndexDef : TRESTDWMemTableIndex; + FFilterBuffer : TRecordBuffer; + FBRecordCount : integer; + FReadOnly : Boolean; + FSavedState : TDatasetState; + FPacketRecords : integer; + FRecordSize : Integer; + FIndexFieldNames : String; + FIndexName : String; + FNullmaskSize : byte; + FOpen : Boolean; + FUpdateBuffer : TRESTDWMemRecordsUpdateBuffer; + FDataReference : TRESTDWMemDataReference; + FDeltaReference : TRESTDWMemDataReference; + FCurrentUpdateBuffer : integer; +{$IFDEF FPC} + FAutoIncValue : Longint; +{$ELSE} + FAutoIncValue : Integer; +{$ENDIF} + FAutoIncField : TAutoIncField; + FIndexes : TRESTDWMemTableIndexDefs; + FRuntimeIndexes : TRESTDWMemTableIndexDefs; + FParser : TRESTDWMemParser; + FFieldBufPositions : array Of longint; + FAllPacketsFetched : boolean; +{$IFDEF RESTDWLAZARUS} + FDatabaseCharSet : TDatabaseCharSet; +{$ENDIF} + + FBlobBuffers : array Of PRESTDWMemBlobBuffer; + FUpdateBlobBuffers: array Of PRESTDWMemBlobBuffer; + FRefreshing : Boolean; + + Procedure ProcessFieldsToCompareStruct(Const AFields, ADescFields, ACInsFields: TList; + Const AIndexOptions: TIndexOptions; Const ALocateOptions: TLocateOptions; out ACompareStruct: TRESTDWMemCompareStruct); + Function BufferOffset: integer; + Function GetFieldSize(FieldDef : TFieldDef) : longint; + Procedure CalcRecordSize; + Function IntAllocRecordBuffer: TRecordBuffer; + Procedure InitFieldDefsFromPersistentFields; +{$IFDEF FPC} + Procedure NormalizeNumericFieldRanges; + Procedure NormalizeFieldDisplayWidths; +{$ENDIF} + Procedure IntLoadFieldDefsFromFile; + Procedure IntLoadRecordsFromFile; + Function GetCurrentBuffer: TRecordBuffer; + Procedure CurrentRecordToBuffer(Buffer: TRecordBuffer); + Function LoadBuffer(Buffer : TRecordBuffer): TGetResult; + Procedure FetchAll; + Function GetRecordUpdateBuffer(Const ABookmark : TRESTDWMemBookmark; IncludePrior : boolean = false; AFindNext : boolean = false) : boolean; + Function GetRecordUpdateBufferCached(Const ABookmark : TRESTDWMemBookmark; IncludePrior : boolean = false) : boolean; + Function GetActiveRecordUpdateBuffer : boolean; + Procedure CancelRecordUpdateBuffer(AUpdateBufferIndex: integer; Var ABookmark: TRESTDWMemBookmark); + Procedure ParseFilter(Const AFilter: string); + Procedure RemoveUnnamedFields; + + Function GetDataReference: TRESTDWMemDataReference; + Function GetDeltaReference: TRESTDWMemDataReference; + Procedure SetDataReference(AValue: TRESTDWMemDataReference); + Procedure SaveDeltaToStream(AStream: TStream); + Function GetBufUniDirectional: boolean; + // indexes handling + Procedure SetMaxIndexesCount(Const AValue: Integer); + Procedure SetBufUniDirectional(Const AValue: boolean); + Function DefaultIndex : TRESTDWMemTableIndex; + Function DefaultBufferIndex : TRESTDWMemInternalIndex; + Procedure InitDefaultIndexes; + Procedure BuildIndex(AIndex : TRESTDWMemInternalIndex); + Procedure BuildIndexes; + Procedure RemoveRecordFromIndexes(Const ABookmark : TRESTDWMemBookmark); + Procedure InternalCreateIndex(F: TRESTDWMemTableIndex); virtual; + Property CurrentIndexBuf : TRESTDWMemInternalIndex Read GetCurrentIndexBuf; + Property CurrentIndexDef : TRESTDWMemTableIndex Read FCurrentIndexDef; + Property BufIndexDefs[Aindex : Integer] : TRESTDWMemTableIndex Read GetBufIndexDef; + Property BufIndexes[Aindex : Integer] : TRESTDWMemInternalIndex Read GetBufIndex; Protected - Function GetAsString : String; Override; - Procedure SetAsString (Const AValue : String); Override; - Procedure SetAsFloat (AValue: Double); Override; - Function GetAsFloat : Double; Override; - Procedure SetVarValue (Const AValue : Variant); Override; - Function GetAsVariant : Variant; Override; + // abstract & virtual methods of TDataset + Class Function DefaultReadFileFormat : TRESTDWMemDataPacketFormat; virtual; + Class Function DefaultWriteFileFormat : TRESTDWMemDataPacketFormat; virtual; + Class Function DefaultPacketClass : TRESTDWMemDataPacketReaderClass ; virtual; + Function CreateDefaultPacketReader(aStream : TStream): TRESTDWMemDataPacketReader ; virtual; + Procedure SetPacketRecords(aValue : integer); virtual; +{$IFDEF FPC} + Procedure SetRecNo(Value: Longint); override; + Function GetRecNo: Longint; override; +{$ELSE} + Procedure SetRecNo(Value: Integer); override; + Function GetRecNo: Integer; override; +{$ENDIF} + Function GetChangeCount: integer; virtual; + Function AllocRecordBuffer: TRecordBuffer; override; + Procedure FreeRecordBuffer(Var Buffer: TRecordBuffer); override; + Procedure ClearCalcFields(Buffer: TRecordBuffer); override; + Procedure InternalInitRecord(Buffer: TRecordBuffer); override; + Function GetCanModify: Boolean; override; + Function GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode; DoCheck: Boolean): TGetResult; override; + Procedure DoBeforeClose; override; + Procedure InternalInitFieldDefs; override; + Procedure InternalOpen; override; + Procedure InternalClose; override; + Function GetRecordSize: Word; override; + Procedure InternalPost; override; + Procedure InternalCancel; Override; + Procedure InternalDelete; override; + Procedure InternalFirst; override; + Procedure InternalLast; override; + Procedure InternalSetToRecord(Buffer: TRecordBuffer); override; + Procedure InternalGotoBookmark(ABookmark: Pointer); override; + Procedure SetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); override; + Procedure SetBookmarkFlag(Buffer: TRecordBuffer; Value: TBookmarkFlag); override; + Procedure GetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); override; + Function GetBookmarkFlag(Buffer: TRecordBuffer): TBookmarkFlag; override; + Function IsCursorOpen: Boolean; override; +{$IFDEF FPC} + Function GetRecordCount: Longint; override; +{$ELSE} + Function GetRecordCount: Integer; override; +{$ENDIF} + Procedure SetFilterText(Const Value: String); override; {virtual;} + Procedure SetFiltered(Value: Boolean); override; {virtual;} + Procedure InternalRefresh; override; +{$IFNDEF FPC} + Procedure InternalHandleException; override; +{$ENDIF} + Procedure DataEvent(Event: TDataEvent; Info: TRESTDWPtrInt); override; + // virtual or methods, which can be used by descendants + Function GetNewBlobBuffer : PRESTDWMemBlobBuffer; + Function GetNewWriteBlobBuffer : PRESTDWMemBlobBuffer; + Procedure FreeBlobBuffer(Var ABlobBuffer: PRESTDWMemBlobBuffer); + Function InternalAddIndex(Const AName, AFields : string; AOptions : TIndexOptions; Const ADescFields: string; + Const ACaseInsFields: string) : TRESTDWMemTableIndex; virtual; + Procedure BeforeRefreshOpenCursor; virtual; + Procedure DoFilterRecord(out Acceptable: Boolean); virtual; + Procedure SetReadOnly(AValue: Boolean); virtual; + Function IsReadFromPacket : Boolean; + Function getnextpacket : integer; + Function GetPacketReader(Const Format: TRESTDWMemDataPacketFormat; Const AStream: TStream): TRESTDWMemDataPacketReader; virtual; + // abstracts, must be overidden by descendents + Function Fetch : boolean; virtual; + Function LoadField(FieldDef : TFieldDef;buffer : pointer; out CreateBlob : boolean) : boolean; virtual; + Procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PRESTDWMemBlobField); virtual; + Function DoLocate(Const KeyFields: string; Const KeyValues: Variant; Options: TLocateOptions; DoEvents : Boolean) : boolean; + Property Refreshing : Boolean Read FRefreshing; Public - Constructor Create(AOwner: TComponent); override; + Function GetIndexDefs : TIndexDefs; + Procedure SetIndexDefs(Value : TIndexDefs); + Function GetIndexFieldNames : String; + Function GetIndexName : String; + Procedure SetIndexFieldNames(Const AValue : String); + Procedure SetIndexName(AValue : String); + Function IsSequenced : Boolean; Override; + Constructor Create(AOwner: TComponent); override; + Function GetFieldDataPtr(Field: TField; Buffer: Pointer): Boolean; + Procedure SetFieldDataPtr(Field: TField; Buffer: Pointer); +{$IFDEF FPC} + Function GetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean): Boolean; override; + Function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override; + Procedure SetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean); override; + Procedure SetFieldData(Field: TField; Buffer: Pointer); override; +{$ELSE} + {$IFDEF DELPHIXEUP} + Function GetFieldData(Field: TField; Var Buffer: TValueBuffer): Boolean; overload; override; + Procedure SetFieldData(Field: TField; Buffer: TValueBuffer); overload; override; + {$IFDEF RTL240_UP} + Function GetFieldData(Field: TField; Buffer: Pointer): Boolean; overload; override; + Procedure SetFieldData(Field: TField; Buffer: Pointer); overload; override; + {$ENDIF} + {$ELSE} + Function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override; + Procedure SetFieldData(Field: TField; Buffer: Pointer); override; + {$ENDIF} +{$ENDIF} + Procedure MergeChangeLog; + Procedure RevertRecord; + Procedure CancelUpdates; virtual; + Procedure EmptyTable; + Destructor Destroy; override; + Function Locate(Const KeyFields: string; Const KeyValues: Variant; Options: TLocateOptions) : boolean; override; + Function Lookup(Const KeyFields: string; Const KeyValues: Variant; Const ResultFields: string): Variant; override; + Function UpdateStatus: TUpdateStatus; override; + Function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; override; + Procedure AddIndex(Const AName, AFields : string; AOptions : TIndexOptions; Const ADescFields: string = ''; + Const ACaseInsFields: string = ''); virtual; + Procedure ClearIndexes; + + Procedure SetDatasetPacket(AReader : TRESTDWMemDataPacketReader); + Procedure GetDatasetPacket(AWriter : TRESTDWMemDataPacketReader); + Procedure LoadFromStream(AStream : TStream; Format: TRESTDWMemDataPacketFormat = dfDefault); + Procedure SaveToStream(AStream : TStream; Format: TRESTDWMemDataPacketFormat = dfDefault); + Procedure LoadFromFile(AFileName: string = ''; Format: TRESTDWMemDataPacketFormat = dfDefault); + Procedure SaveToFile(AFileName: string = ''; Format: TRESTDWMemDataPacketFormat = dfBinary); + Procedure CreateDataset; + Property Data : TRESTDWMemDataReference Read GetDataReference Write SetDataReference; + Property Delta : TRESTDWMemDataReference Read GetDeltaReference; + Procedure Clear; // Will close and remove all field definitions. + Function BookmarkValid(ABookmark: TBookmark): Boolean; override; +{$IFDEF FPC} + Function CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Longint; override; +{$ELSE} + Function CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Integer; override; +{$ENDIF} + Procedure CopyFromDataset(DataSet : TDataSet;CopyData : Boolean=True); + property ChangeCount : Integer read GetChangeCount; + property MaxIndexesCount : Integer read FMaxIndexesCount write SetMaxIndexesCount default 2; + property ReadOnly : Boolean read FReadOnly write SetReadOnly default false; Published - Property Size : Integer Read vSize Write vSize; - Property Precision : Integer Read vPrecision Write vPrecision; + property FileName : TFileName read FFileName write FFileName; + property PacketRecords : Integer read FPacketRecords write SetPacketRecords default 10; + property IndexDefs : TIndexDefs read GetIndexDefs write SetIndexDefs; + property IndexName : String read GetIndexName write SetIndexName; + property IndexFieldNames : String read GetIndexFieldNames write SetIndexFieldNames; + property UniDirectional: boolean read GetBufUniDirectional write SetBufUniDirectional default False; +{$IFDEF RESTDWLAZARUS} + Property DatabaseCharSet : TDatabaseCharSet Read FDatabaseCharSet Write FDatabaseCharSet Default csUndefined; +{$ENDIF} End; - {$ENDIF} - {$IFNDEF FPC} - TRESTDWSQLTimeStampOffsetField = Class(TSQLTimeStampField) - Protected - {$IF CompilerVersion < 25} - Procedure GetText (Var Text : String; - DisplayText : Boolean); Override; - {$IFEND} - {$IFDEF FPC} - Procedure SetAsString(const Value: string); override; - {$ELSE} - {$IF CompilerVersion < 25} - Procedure SetAsString(const Value: string); override; - {$ELSE} - Procedure SetAsString(Const AValue : String); Override; - {$IFEND} - {$ENDIF} - Public - Constructor Create(AOwner: TComponent); override; - End; - {$ENDIF} - Type - TStringFieldRESTDW = Class(TStringField) - Protected - Function CopyToNull(aValue : String) : String;Overload; - Function CopyToNull(aValue : TRESTDWBytes) : TRESTDWBytes;Overload; - Function GetAsString : String; Override; - {$IFNDEF FPC} - {$IFNDEF NEXTGEN} - Function GetValue(var aValue: AnsiString): Boolean; - Function GetAsAnsiString : AnsiString; override; - {$ELSE} - Function GetValue(var aValue: String): Boolean; - {$ENDIF !NEXTGEN} - {$ELSE} - Function GetAsAnsiString : AnsiString; override; - Function GetValue(var aValue: String): Boolean; - {$ENDIF} - Function GetAsVariant : Variant; Override; -// Procedure GetText (Var Text : String; -// DisplayText : Boolean); Override; - Procedure SetAsAnsiString(const AValue: AnsiString); override; - Procedure SetAsString (Const AValue : String); Override; - Public - Constructor Create(AOwner: TComponent); override; - End; -{$IFDEF SUPPORTS_CLASS_HELPERS} - TStringFieldHelper = Class helper For TStringField - Protected - Function GetAsString : String; - {$IFNDEF NEXTGEN} - Function GetAsAnsiString : AnsiString; - {$ENDIF !NEXTGEN} - Function GetAsVariant : Variant; - Procedure SetAsAnsiString(const AValue: AnsiString); - Procedure SetAsString (Const AValue : String); - End; + TRESTDWMemTable = Class(TRESTDWCustomMemTable) + Published + Property FileName; + Property PacketRecords; + Property IndexDefs; + Property IndexName; + Property IndexFieldNames; + Property UniDirectional; +{$IFDEF RESTDWLAZARUS} + Property DatabaseCharSet; {$ENDIF} + Property MaxIndexesCount; + Property FieldDefs; + Property Active; + Property AutoCalcFields; + Property Filter; + Property Filtered; + Property FilterOptions; +{$IFNDEF FPC} + Property ObjectView Default False; +{$ENDIF} + Property ReadOnly; + Property AfterCancel; + Property AfterClose; + Property AfterDelete; + Property AfterEdit; + Property AfterInsert; + Property AfterOpen; + Property AfterPost; + Property AfterScroll; + Property BeforeCancel; + Property BeforeClose; + Property BeforeDelete; + Property BeforeEdit; + Property BeforeInsert; + Property BeforeOpen; + Property BeforePost; + Property BeforeScroll; + Property OnCalcFields; + Property OnDeleteError; + Property OnEditError; + Property OnFilterRecord; + Property OnNewRecord; + Property OnPostError; + End; -Var - DefaultFieldClasses : Array[TFieldType] Of TFieldClass = (nil, { ftUnknown } - TStringFieldRESTDW, { ftString } - TSmallintField, { ftSmallint } - TIntegerField, { ftInteger } - TWordField, { ftWord } - TBooleanField, { ftBoolean } - TFloatField, { ftFloat } - TCurrencyField, { ftCurrency } - TBCDField, { ftBCD } - TDateField, { ftDate } - TTimeField, { ftTime } - TDateTimeField, { ftDateTime } - TBytesField, { ftBytes } - TVarBytesField, { ftVarBytes } - TAutoIncField, { ftAutoInc } - TBlobField, { ftBlob } - TMemoField, { ftMemo } - TGraphicField, { ftGraphic } - TBlobField, { ftFmtMemo } - TBlobField, { ftParadoxOle } - TBlobField, { ftDBaseOle } - TBlobField, { ftTypedBinary } - nil, { ftCursor } - TStringFieldRESTDW, { ftFixedChar } - TWideStringField, { ftWideString } - TLargeIntField, { ftLargeInt } - {$IFNDEF FPC}TADTField,{ ftADT }{$ELSE}Nil,{$ENDIF} - {$IFNDEF FPC}TArrayField,{ ftArray }{$ELSE}Nil,{$ENDIF} - {$IFNDEF FPC}TReferenceField,{ ftReference }{$ELSE}Nil,{$ENDIF} - {$IFNDEF FPC}TDataSetField,{ ftDataSet }{$ELSE}Nil,{$ENDIF} - TStreamField, //TBlobField, { ftOraBlob } - TStreamField, //TMemoField, { ftOraClob } - TVariantField, { ftVariant } - {$IFNDEF FPC}TInterfaceField,{ ftInterface }{$ELSE}Nil,{$ENDIF} - {$IFNDEF FPC}TIDispatchField,{ ftIDispatch }{$ELSE}Nil,{$ENDIF} - TGuidField,{ ftGuid } - {$IFNDEF FPC}TSQLTimeStampField, { ftTimeStamp }{$ELSE}Nil,{$ENDIF} - TRESTDWNumericField{ ftFMTBcd } -// {$IFNDEF FPC}TFMTBcdField{$ELSE}TExtendedField{$ENDIF}{ ftFMTBcd } - {$IFNDEF FPC} - {$IFDEF DELPHI2010UP}, - TWideStringField, { ftFixedWideChar } - TStreamField, //TWideMemoField, { ftWideMemo } - TSQLTimeStampField, { ftOraTimeStamp } - TStringFieldRESTDW { ftOraInterval } - {$ENDIF} - {$ELSE}, - TStringFieldRESTDW { ftOraInterval } - {$ENDIF} - {$IFNDEF FPC} - {$IFDEF DELPHIXEUP}, - TLongWordField, { ftLongWord } - TShortintField, { ftShortint } - TByteField, { ftByte } - TRESTDWNumericField, - nil, { ftConnection } - nil, { ftParams } - TStreamField //TBlobField { ftStream } - {$ENDIF} - {$ELSE}, - TStreamField //TBlobField { ftStream } - {$ENDIF} - {$IFDEF DELPHIXE2UP}, - TSQLTimeStampOffsetField, { ftTimeStampOffset } - nil, { ftObject } - TSingleField { ftSingle } - {$ENDIF} - {$IFDEF DELPHI2025UP}, - TLargeIntField - {$ENDIF}); - - - - Procedure CalcDataSize(FieldDef : TFieldDef; Var DataSize: Integer);Overload; - Procedure CalcDataSize(Field : TField; Var DataSize: Integer);Overload; + +Procedure RegisterDatapacketReader(ADatapacketReaderClass : TRESTDWMemDataPacketReaderClass; AFormat : TRESTDWMemDataPacketFormat); Implementation Uses - Types, Math, DateUtils, - {$IFDEF RTL240_UP} - System.Generics.Collections, - {$ENDIF RTL240_UP} - FMTBcd, - {$IFDEF RESTDWVCL}uRESTDWMemVCLUtils,{$ENDIF} - uRESTDWMemResources, - uRESTDWTools, uRESTDWStorageBin - {$IFNDEF FPC}, SqlTimSt{$ENDIF}, - uRESTDWBasicTypes; - -Const - GuidSize = 38; - STATUSNAME = 'C67F70Z90'; (* Magic *) - -Type - PMemBookmarkInfo = ^TMemBookmarkInfo; - TMemBookmarkInfo = record - BookmarkData: TRESTDWMTBookmarkData; - BookmarkFlag: TBookmarkFlag; -End; +{$IFDEF FPC} + dbconst, +{$ELSE} + DBConsts, +{$ENDIF} + FmtBCD, strutils, uRESTDWStorageBin; -Function IsNullData(DataList : TRESTDWBytes) : Boolean; +{$IFNDEF FPC} +Procedure RESTDWSetFieldValues(ADataSet : TDataSet; Const KeyFields : String; Const KeyValues : Variant); Var + L : TList; I : Integer; Begin - Result := True; - For I := 0 to Length(DataList) -1 Do - Begin - If DataList[I] <> 0 Then - Begin - Result := False; - Break; - End; - End; -End; - -Function ExtractFieldNameEx(Const Fields : {$IFDEF COMPILER10_UP}DWWideString{$ELSE}String{$ENDIF}; - Var Pos : Integer) : String; -Begin - Result := ExtractFieldName(Fields, Pos); + L := TList.Create; + Try + ADataSet.GetFieldList(L, KeyFields); + If VarIsArray(KeyValues) Then + For I := 0 To L.Count - 1 Do + TField(L[I]).Value := KeyValues[I] + Else If L.Count > 0 Then + TField(L[0]).Value := KeyValues; + Finally + L.Free; End; - -Procedure AppHandleException(Sender: TObject); -Begin - If Assigned(ApplicationHandleException) then - ApplicationHandleException(Sender); End; -Procedure CopyFieldValue(DestField, SourceField: TField); -Begin - If SourceField.IsNull then - DestField.Clear - Else If DestField.ClassType = SourceField.ClassType then - Begin - Case DestField.datatype Of - ftInteger, - ftSmallint, - ftWord : DestField.AsInteger := SourceField.AsInteger; - ftBCD, - ftCurrency : DestField.AsCurrency := SourceField.AsCurrency; - ftFMTBCD : DestField.AsBCD := SourceField.AsBCD; - ftString : DestField.AsString := SourceField.AsString; - {$IF DEFINED(FPC) OR DEFINED(COMPILER10_UP)} - ftWideString : DestField.AsWideString := SourceField.AsWideString; - ftFixedWideChar : DestField.AsWideString := SourceField.AsWideString; - {$IFEND} - ftFloat - {$IFNDEF FPC} - {$IFDEF DELPHI10_0UP} - , ftSingle - {$ENDIF DELPHI10_0UP} - {$ENDIF}: DestField.AsFloat := SourceField.AsFloat; - ftDateTime : DestField.AsDateTime := SourceField.AsDateTime; - Else DestField.Assign(SourceField); - End; - End - Else - DestField.Assign(SourceField); -End; +{$ENDIF} -Function CalcFieldLen(FieldType : TFieldType; - Size : Word) : Word; +Function RESTDWWordCount(Const S : String; Const Delimiters : TSysCharSet) : Integer; Var - vDWFieldType : Byte; -Begin - vDWFieldType := 0; - If Not(FieldType In ftSupported) Then - Result := 0 - Else If FieldType In ftBlobTypes Then - Result := SizeOf(Pointer) - Else - Begin - Result := Size; - vDWFieldType := FieldTypeToDWFieldType(FieldType); //Gledston - Alterei a partir deste ponto - Case vDWFieldType of - dwftString : Begin -// Inc(Result, Size); //2 Bytes de Boolean - Exit; - End; - dwftSmallint : Result := SizeOf(Smallint); - dwftInteger : Result := SizeOf(Integer); - dwftWord : Result := SizeOf(Word); - dwftBoolean : Result := SizeOf(Wordbool); - dwftFloat - {$IFDEF FPC} - , 45 //Extended - {$ENDIF} : Result := SizeOf(Double); -// {$IFNDEF FPC} -// {$IF CompilerVersion > 21} -// dwftSingle : Result := SizeOf(Single); // + 5; -// {$IFEND} -// {$ELSE} -// dwftSingle : Result := SizeOf(Double); -// {$ENDIF} - dwftCurrency : Result := SizeOf(Currency); - dwftDate, - dwftTime : Result := SizeOf(LongInt) + 8; - dwftDateTime, - dwftTimeStamp : Begin - Result := {$IFDEF FPC}SizeOf(Double);{$ELSE}SizeOf(TSQLTimeStamp);{$ENDIF} - End; - dwftAutoInc : Result := SizeOf(Longint); - dwftLargeint : Result := SizeOf(Longint); //{$IFDEF FPC}8{$ELSE}{$IF CompilerVersion <= 22}8{$ELSE}64{$IFEND}{$ENDIF}; //Field Size é 64 Bits - dwftBCD, //Result := SizeOf(TBcd); - dwftFMTBCD : Result := SizeOf(Currency); - dwftTimeStampOffset : Begin - Inc(Result, SizeOf(Double)); - Inc(Result, SizeOf(Byte)); - Inc(Result, SizeOf(Byte)); - End; - {$IFDEF COMPILER10_UP} - dwftOraTimestamp : Result := SizeOf(TSQLTimeStamp); - dwftFixedWideChar : Result := (Result + 1) * SizeOf(WideChar); - {$ENDIF COMPILER10_UP} - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - dwftLongWord : Result := SizeOf(LongWord); - dwftShortint : Result := SizeOf(Shortint); - dwftByte : Result := SizeOf(Byte); - {$IFEND} - {$ENDIF} - {$IFNDEF FPC} - dwftExtended : Begin - Result := SizeOf(DWLongDouble); - If Result < Size Then - Begin - Result := Size; - Exit; - End; - End; - {$ENDIF} - dwftADT : Result := 0; - dwftFixedChar : Inc(Result); - dwftWideString : Begin - Result := Result * SizeOf(WideChar); - Exit; - End; - dwftVariant : Result := SizeOf(Variant); - dwftGuid : Result := GuidSize; - dwftWideMemo, - dwftBlob, - dwftMemo, - dwftBytes, - dwftVarBytes, - dwftFmtMemo, - dwftOraBlob, - dwftOraClob : Result := SizeOf(Pointer); - End; - End; - If vDWFieldType In FieldGroupVariant Then - Result := SizeOf(Variant); - If Result > 0 Then - Result := Result + SizeOf(Boolean); -End; - -Procedure CalcDataSize(FieldDef: TFieldDef; Var DataSize: Integer);Overload; -Begin - If FieldDef.datatype in ftSupported - ftBlobTypes then - Inc(DataSize, CalcFieldLen(FieldDef.datatype, FieldDef.Size)); - If FieldDef.datatype in ftBlobTypes then - Inc(DataSize, CalcFieldLen(FieldDef.datatype, FieldDef.Size)); -// {$IFNDEF FPC} -// For I := 0 to FieldDef.ChildDefs.Count - 1 do -// CalcDataSize(FieldDef.ChildDefs[I], DataSize); -// {$ENDIF} -End; - -Procedure CalcDataSize(Field: TField; Var DataSize: Integer);Overload; + I : Integer; + InWord : Boolean; Begin - If Field.datatype in ftSupported - ftBlobTypes then + Result := 0; + InWord := False; + For I := 1 To Length(S) Do + If S[I] In Delimiters Then + InWord := False + Else If Not InWord Then Begin - If Field is TRESTDWNumericField Then - Inc(DataSize, CalcFieldLen(Field.datatype, TRESTDWNumericField(Field).Size)) - Else - Inc(DataSize, CalcFieldLen(Field.datatype, Field.Size)); + Inc(Result); + InWord := True; End; - If Field.datatype in ftBlobTypes then - Inc(DataSize, CalcFieldLen(Field.datatype, Field.Size)); End; -Procedure Error(const Msg: string); -Begin - DatabaseError(Msg); -End; - -Function RPos(Const Substr, S: String) : Integer; +Function RESTDWExtractDelimited(N : Integer; Const S : String; Const Delimiters : TSysCharSet) : String; Var I, - X, - Len : Integer; + W, + StartPos : Integer; + InWord : Boolean; Begin - Len := Length(SubStr); - I := Length(S) - Len + 1; - if (I <= 0) or (Len = 0) then - Begin - RPos := 0; - Exit; - End - Else + Result := ''; + W := 0; + InWord := False; + StartPos := 0; + For I := 1 To Length(S) + 1 Do Begin - While I > 0 Do + If (I > Length(S)) Or ((I <= Length(S)) And (S[I] In Delimiters)) Then Begin - If S[I] = SubStr[InitStrPos] Then + If InWord Then Begin - X := InitStrPos; - While (X < Len) and (S[I + X] = SubStr[X + 1]) Do - Inc(X); - If (X = Len) Then + Inc(W); + If W = N Then Begin - RPos := I; + Result := Copy(S, StartPos, I - StartPos); Exit; End; + InWord := False; End; - Dec(I); + End + Else If Not InWord Then + Begin + StartPos := I; + InWord := True; End; - RPos := 0; End; End; -Procedure ErrorFmt(const Msg: string; const Args: array of const); -Begin - DatabaseErrorFmt(Msg, Args); -End; -{$IFNDEF FPC} -{$IF CompilerVersion > 24} -Function TRESTDWNumericField.GetAsExtended: Extended; -Var - x : DWLongDouble; - pData : TRESTDWMTValueBuffer; -Begin - {$IFNDEF FPC} - {$IF Defined(HAS_FMX)} - SetLength(pData, SizeOf(Extended)); - If not GetData(pData, True) then - Result := NaN - Else - Result := TBitConverter.InTo(pData); - {$ELSE} - //TODO Internal - x := 0; - If TRESTDWMemtable(Dataset).RecNo > 0 Then - Begin - SetLength(pData, SizeOf(x) +1); - If Not TRESTDWMemtable(Dataset).InternalGetFieldData(Self, pData, Length(pData)) then - Result := NaN - Else - Begin - Move(pData[0], Pointer(@x)^, SizeOf(x)); - Result := x; - End; - SetLength(pData, 0); - End; - {$IFEND} - {$ELSE} - If not GetData(@Result, True) then - Result := NaN; - {$ENDIF} -End; +Const + SDefaultIndex = 'DEFAULT_ORDER'; + SCustomIndex = 'CUSTOM_ORDER'; + Desc=' DESC'; //leading space is important + LenDesc : integer = Length(Desc); + Limiter=';'; -Function TRESTDWNumericField.GetAsFloat : Double; -Begin - Result := GetAsExtended; -// Result := _RealSupportManager._VarFromReal(GetAsExtended); -End; +Type + TRESTDWMemDataPacketReaderRegistration = Record + ReaderClass : TRESTDWMemDataPacketReaderClass; + Format : TRESTDWMemDataPacketFormat; + End; -Procedure TRESTDWNumericField.SetAsExtended(Const AValue : Extended); Var - pData : TRESTDWMTValueBuffer; - x : DWLongDouble; -Begin - {$IFNDEF FPC} - {$IF Defined(HAS_FMX)} - {$IF Defined(HAS_UTF8)} - SetData(TValueBuffer(@AValue), True); - {$ELSE} - SetData(@AValue, True); - {$IFEND} - {$ELSE} - SetLength(pData, SizeOf(x)); - x := aValue; - Move(Pointer(@x)^, pData[0], SizeOf(x)); - TRESTDWMemtable(Dataset).InternalSetFieldData(Self, pData, TRESTDWMTValueBuffer(Pointer(@pData)^)); -// SetData(TValueBuffer(@AValue), True); - {$IFEND} - {$ELSE} - SetData(@AValue, True); - {$ENDIF} -End; + RegisteredDatapacketReaders : Array Of TRESTDWMemDataPacketReaderRegistration; -{$IFDEF SUPPORTS_CLASS_HELPERS} -Function TStringFieldHelper.GetAsAnsiString : AnsiString; -Var - Data : TValueBuffer; -Begin - SetLength(Data, Size); - If GetData(Data, True) then - Result := Copy(BytesToString(TRESTDWBytes(Data)), InitStrPos, Size); - SetLength(Data, 0); -End; +Procedure RegisterDatapacketReader(ADatapacketReaderClass : TRESTDWMemDataPacketReaderClass; AFormat : TRESTDWMemDataPacketFormat); -Function TStringFieldHelper.GetAsVariant : Variant; Begin - Result := GetAsString; + setlength(RegisteredDatapacketReaders,length(RegisteredDatapacketReaders)+1); + With RegisteredDatapacketReaders[length(RegisteredDatapacketReaders)-1] Do + Begin + Readerclass := ADatapacketReaderClass; + Format := AFormat; + End; End; -Function TStringFieldHelper.GetAsString : String; +Function GetRegisterDatapacketReader(AStream : TStream; AFormat : TRESTDWMemDataPacketFormat; out ADataReaderClass : TRESTDWMemDataPacketReaderRegistration) : boolean; + Var - Data : TValueBuffer; -Begin - SetLength(Data, Size); - If GetData(Data, True) then - Result := Copy(BytesToString(TRESTDWBytes(Data)), InitStrPos, Size); - SetLength(Data, 0); -End; - -Procedure TStringFieldHelper.SetAsAnsiString(const AValue: AnsiString); -Begin - {$IFNDEF FPC} - {$IF Defined(HAS_FMX)} - {$IF Defined(HAS_UTF8)} - SetData(TValueBuffer(@AValue), True); - {$ELSE} - SetData(@AValue, True); - {$IFEND} - {$ELSE} - SetData(@AValue, True); - {$IFEND} - {$ELSE} - SetData(@AValue, True); - {$ENDIF} -End; + i : integer; -Procedure TStringFieldHelper.SetAsString(Const AValue : String); Begin - {$IFNDEF FPC} - {$IF Defined(HAS_FMX)} - {$IF Defined(HAS_UTF8)} - SetData(TValueBuffer(@AValue), True); - {$ELSE} - SetData(@AValue, True); - {$IFEND} - {$ELSE} - SetData(@AValue, True); - {$IFEND} - {$ELSE} - SetData(@AValue, True); - {$ENDIF} + Result := False; + For i := 0 To length(RegisteredDatapacketReaders)-1 Do + If ((AFormat=dfAny) or (AFormat=RegisteredDatapacketReaders[i].Format)) Then + Begin + If (AStream=nil) or (RegisteredDatapacketReaders[i].ReaderClass.RecognizeStream(AStream)) Then + Begin + ADataReaderClass := RegisteredDatapacketReaders[i]; + Result := True; + If (AStream <> nil) Then + AStream.Seek(0,soFromBeginning); + Break; + End; + AStream.Seek(0,soFromBeginning); + End; End; -{$ENDIF} -Procedure TRESTDWNumericField.SetAsString(Const AValue : String); -Var - x : Extended; +Function DBCompareText(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; + Begin - If AValue = '' Then - Clear + If [loCaseInsensitive,loPartialKey]=options Then + Result := AnsiStrLIComp(pchar(subValue),pchar(aValue),length(pchar(subValue))) + Else If [loPartialKey] = options Then + Result := AnsiStrLComp(pchar(subValue),pchar(aValue),length(pchar(subValue))) + Else If [loCaseInsensitive] = options Then + Result := AnsiCompareText(pchar(subValue),pchar(aValue)) Else - Begin - x := StrToFloat(AValue); - SetAsExtended(x); - End; + Result := AnsiCompareStr(pchar(subValue),pchar(aValue)); End; -{$ELSE} -Function TRESTDWNumericField.GetAsVariant : Variant; -Begin - Result := Extended(Value);//_RealSupportManager._VarFromReal(Value); -End; -{$IFEND} -{$ENDIF} +Function DBCompareWideText(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; -Function TRESTDWNumericField.GetAsVariant : Variant; Begin - Result := {$IFDEF FPC}GetAsFloat{$ELSE}GetAsExtended{$ENDIF}; + If [loCaseInsensitive,loPartialKey]=options Then + Result := WideCompareText(pwidechar(subValue),LeftStr(pwidechar(aValue), Length(pwidechar(subValue)))) + Else If [loPartialKey] = options Then + Result := WideCompareStr(pwidechar(subValue),LeftStr(pwidechar(aValue), Length(pwidechar(subValue)))) + Else If [loCaseInsensitive] = options Then + Result := WideCompareText(pwidechar(subValue),pwidechar(aValue)) + Else + Result := WideCompareStr(pwidechar(subValue),pwidechar(aValue)); End; -Procedure TRESTDWNumericField.SetVarValue(Const AValue : Variant); +Function DBCompareByte(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; + Begin - SetAsExtended(AValue); + Result := PByte(subValue)^-PByte(aValue)^; End; -Procedure TRESTDWNumericField.SetAsFloat (AValue: Double); +Function DBCompareSmallInt(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; + Begin - SetAsExtended(AValue); + Result := PSmallInt(subValue)^-PSmallInt(aValue)^; End; -Constructor TRESTDWNumericField.Create(AOwner: TComponent); +Function DBCompareInt(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; + Begin - Inherited; - {$IFNDEF FPC} - SetDataType(ftExtended); - {$ELSE} - SetDataType(ftFMTBcd); - {$ENDIF} - vSize := 19; - vPrecision := 8; + Result := PInteger(subValue)^-PInteger(aValue)^; End; -Function TStringfieldRESTDW.GetAsAnsiString : AnsiString; -Var - Data : TValueBuffer; +Function DBCompareLargeInt(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; + Begin - {$IFNDEF FPC} - SetLength(Data, Size); - If GetData(Data, True) then - Result := BytesToString(TRESTDWBytes(Data)); - SetLength(Data, 0); - {$ELSE} - Result := GetAsString; - {$ENDIF} + // A simple subtraction doesn't work, since it could be that the result + // doesn't fit into a LargeInt + If PLargeInt(subValue)^ < PLargeInt(aValue)^ Then + result := -1 + Else If PLargeInt(subValue)^ > PLargeInt(aValue)^ Then + result := 1 + Else + result := 0; End; -Function TStringfieldRESTDW.GetAsVariant : Variant; +Function DBCompareWord(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; + Begin - Result := GetAsString; + Result := PWord(subValue)^-PWord(aValue)^; End; -{$IFNDEF FPC} - {$IFNDEF NEXTGEN} - Function TStringfieldRESTDW.GetValue(var aValue: AnsiString): Boolean; - {$ELSE} - Function TStringfieldRESTDW.GetValue(var aValue: String): Boolean; - {$ENDIF !NEXTGEN} -{$ELSE} -Function TStringfieldRESTDW.GetValue(var aValue: String): Boolean; -{$ENDIF} +Function DBCompareQWord(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; + Begin - Result := False; - Try - aValue := GetAsString; - Result := True; - Except + // A simple subtraction doesn't work, since it could be that the result + // doesn't fit into a LargeInt + If PRESTDWQWord(subValue)^ < PRESTDWQWord(aValue)^ Then + result := -1 + Else If PRESTDWQWord(subValue)^ > PRESTDWQWord(aValue)^ Then + result := 1 + Else + result := 0; +End; - End; +Function DBCompareDouble(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; +Begin + // A simple subtraction doesn't work, since it could be that the result + // doesn't fit into a LargeInt + If PDouble(subValue)^ < PDouble(aValue)^ Then + result := -1 + Else If PDouble(subValue)^ > PDouble(aValue)^ Then + result := 1 + Else + result := 0; End; -Function TStringfieldRESTDW.CopyToNull(aValue : TRESTDWBytes) : TRESTDWBytes; -Var - I : Integer; +{$IFDEF DELPHI2010UP} +Function DBCompareSingle(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; Begin - SetLength(Result, 0); - For I := 0 To Length(aValue) - 1 Do - Begin - If aValue[I] <> 0 Then - Begin - SetLength(Result, Length(Result) +1); - Result[I] := aValue[I]; - End - Else - Break; - End; + If PSingle(subValue)^ < PSingle(aValue)^ Then + Result := -1 + Else If PSingle(subValue)^ > PSingle(aValue)^ Then + Result := 1 + Else + Result := 0; End; -Function TStringfieldRESTDW.CopyToNull(aValue : String) : String; -Var - I : Integer; +Function DBCompareExtended(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; Begin - Result := ''; - For I := InitStrPos To Length(aValue) - FinalStrPos Do + If PExtended(subValue)^ < PExtended(aValue)^ Then + Result := -1 + Else If PExtended(subValue)^ > PExtended(aValue)^ Then + Result := 1 + Else + Result := 0; +End; +{$ENDIF} + +Function DBCompareBCD(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; +Begin + result:=BCDCompare(PBCD(subValue)^, PBCD(aValue)^); +End; + +Function RESTDWCompareByte(A, B: Pointer; ASize: Integer): Integer; +Var I: Integer; PA, PB: PByte; +Begin + PA := A; + PB := B; + For I := 0 To ASize - 1 Do Begin - If aValue[I] <> #0 Then - Result := Result + aValue[I]; + If PA^ < PB^ Then + Begin + Result := -1; + Exit; + End; + If PA^ > PB^ Then + Begin + Result := 1; + Exit; + End; + Inc(PA); + Inc(PB); End; + Result := 0; End; -Function TStringfieldRESTDW.GetAsString : String; -Var - aData, - bData : TRESTDWBytes; +Function DBCompareBytes(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; Begin - Try - SetLength(aData, Size); - If TRESTDWMemtable(Dataset).InternalGetFieldData(Self, TRESTDWMTValueBuffer(aData), Size) then - Begin - bData := CopyToNull(aData); - Result := BytesToString(bData); - SetLength(bData, 0); - End; - SetLength(aData, 0); - Finally - End; + Result := RESTDWCompareByte(subValue, aValue, size); End; -Procedure TStringfieldRESTDW.SetAsAnsiString(const AValue: AnsiString); -Var - pData : TRESTDWBytes; - X : String; - I : Integer; -Begin - {$IFNDEF FPC} - {$IF Defined(HAS_FMX)} - {$IF Defined(HAS_UTF8)} - SetData(TValueBuffer(@AValue), True); - {$ELSE} - SetData(@AValue, True); - {$IFEND} - {$ELSE} - SetData(@AValue, True); - {$IFEND} - {$ELSE} - Inherited SetAsString(AValue); -{ - SetLength(pData, Size); - x := aValue; - I := Length(X); - Move(Pointer(@x)^, pData[0], I); - TRESTDWMemtable(Dataset).InternalSetFieldData(Self, @pData, TRESTDWMTValueBuffer(Pointer(@pData)^)); -} - {$ENDIF} +Function DBCompareVarBytes(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; +Var len1, len2: LongInt; +Begin + len1 := PWord(subValue)^; + len2 := PWord(aValue)^; + subValue := Pointer(TRESTDWPtrInt(subValue) + SizeOf(Word)); + aValue := Pointer(TRESTDWPtrInt(aValue) + SizeOf(Word)); + If len1 > len2 Then + Result := RESTDWCompareByte(subValue, aValue, len2) + Else + Result := RESTDWCompareByte(subValue, aValue, len1); + If Result = 0 Then + Result := len1 - len2; End; -Constructor TStringfieldRESTDW.Create(AOwner: TComponent); +Procedure unSetFieldIsNull(NullMask : pbyte;x : longint); //inline; Begin - Inherited; - SetDataType(ftString); + NullMask[x div 8] := (NullMask[x div 8]) and not (1 shl (x mod 8)); End; -Procedure TStringfieldRESTDW.SetAsString(Const AValue : String); -Var - ValueBuffer : TRESTDWBytes; -Begin - {$IFNDEF FPC} - {$IF Defined(HAS_FMX)} - {$IF Defined(HAS_UTF8)} - SetData(TValueBuffer(@AValue), True); - {$ELSE} - SetData(@AValue, True); - {$IFEND} - {$ELSE} - ValueBuffer := StringToBytes(AValue); - SetData(ValueBuffer, True); - SetLength(ValueBuffer, 0); - {$IFEND} - {$ELSE} - SetAsAnsiString(AValue); - {$ENDIF} +Procedure SetFieldIsNull(NullMask : pbyte;x : longint); //inline; +Begin + NullMask[x div 8] := (NullMask[x div 8]) or (1 shl (x mod 8)); End; -{$IFDEF FPC} -Procedure TRESTDWNumericField.SetAsExtended(Const AValue : Extended); +Function GetFieldIsNull(NullMask : pbyte;x : longint) : boolean; //inline; Begin - SetData(@AValue, True); + result := ord(NullMask[x div 8]) and (1 shl (x mod 8)) > 0 End; -Procedure TRESTDWNumericField.SetAsString(Const AValue : String); -Var - x : Extended; +Function IndexCompareRecords(Rec1,Rec2 : pointer; ADBCompareRecs : TRESTDWMemCompareStruct) : LargeInt; +Var IndexFieldNr : Integer; + IsNull1, IsNull2 : boolean; Begin - If AValue = '' Then - Clear - Else + For IndexFieldNr:=0 To length(ADBCompareRecs)-1 Do With ADBCompareRecs[IndexFieldNr] Do Begin - x := StrToFloat(AValue); - SetAsExtended(x); + IsNull1:=GetFieldIsNull(PByte(TRESTDWPtrInt(rec1)+NullBOff),FieldInd); + IsNull2:=GetFieldIsNull(PByte(TRESTDWPtrInt(rec2)+NullBOff),FieldInd); + If IsNull1 and IsNull2 Then + Result := 0 + Else If IsNull1 Then + Result := -1 + Else If IsNull2 Then + Result := 1 + Else + Result := CompareFunc(Pointer(TRESTDWPtrInt(Rec1)+Off), Pointer(TRESTDWPtrInt(Rec2)+Off), Size, Options); + + If Result <> 0 Then + Begin + If Desc Then + Result := -Result; + Break; + End; End; End; -{$ENDIF} -{$IFDEF FPC} -Function TRESTDWNumericField.GetAsFloat : Double; +{ TRESTDWCustomMemTable.TRESTDWMemTableIndex } + +Destructor TRESTDWCustomMemTable.TRESTDWMemTableIndex.Destroy; Begin - If not GetData(@Result, True) then - Result := NaN; + ClearIndex; + Inherited Destroy; End; -{$ENDIF} -Function TRESTDWNumericField.GetAsString: string; - Function BuildMask(Value : Double; - aPrecision : Integer) : String; - Var - I : Integer; - vString : String; - Begin - vString := '#0.'; - For I := 0 To aPrecision -1 Do - vString := vString + '0'; - If aPrecision = 0 Then - vString := vString + '0'; - Result := FormatFloat(vString, Value); - End; -Var - x : DWLongDouble; +Procedure TRESTDWCustomMemTable.TRESTDWMemTableIndex.Clearindex; Begin -{$IFDEF FPC} - x := GetAsFloat; -{$ELSE} - x := GetAsExtended; -{$ENDIF} - If Not isNull then - Begin - If (Length(FloatToStr(x)) > vSize) Then - Result := FloatToStrF(x, ffGeneral, vSize, vPrecision) - Else If (Length(FloatToStr(Frac(x))) > vPrecision) Then - Result := BuildMask(x, vPrecision) - Else - Result := FloatToStr(X); - If Trim(displayformat) <> '' Then - Result := FormatFloat(displayformat, x); - End - Else - Result := ''; + FreeAndNil(FBufferIndex); End; -{$IFNDEF FPC} -{$IF CompilerVersion < 25} -Procedure TRESTDWSQLTimeStampOffsetField.GetText(var Text: string; - DisplayText: Boolean); -Var - S : String; - D : TSQLTimeStamp; +Procedure TRESTDWCustomMemTable.TRESTDWMemTableIndex.SetIndexProperties; Begin - If GetData(@D, False) then - Begin - If DisplayText and (DisplayFormat <> '') Then - S := DisplayFormat - Else - S := ''; - Text := SQLTimeStampToStr(S, D); - End - Else - Text := ''; + If not Assigned(FBufferIndex) Then + Exit; + FBufferIndex.IndNr:=Index; + FBufferIndex.Name:=Name; + FBufferIndex.FieldsName:=Fields; + FBufferIndex.DescFields:=DescFields; + FBufferIndex.CaseinsFields:=CaseInsFields; + FBufferIndex.Options:=Options; End; -{$IFEND} -{$ENDIF} -{$IFNDEF FPC} -Constructor TRESTDWSQLTimeStampOffsetField.Create(AOwner: TComponent); +Function TRESTDWCustomMemTable.TRESTDWMemTableIndex.MustBuild(aCurrent: TRESTDWMemTableIndex): Boolean; Begin - Inherited; - {$IFNDEF FPC} - SetDataType(ftTimeStampOffset); - {$ELSE} - SetDataType(ftTimeStamp); - {$ENDIF} + Result:=(FIndexType<>itDefault) and IsActiveIndex(aCurrent); End; -{$IF CompilerVersion < 25} -Procedure TRESTDWSQLTimeStampOffsetField.SetAsString(Const Value: string); -{$ELSE} -Procedure TRESTDWSQLTimeStampOffsetField.SetAsString(Const AValue: string); -{$IFEND} -Var - S : String; - P : Integer; + +Function TRESTDWCustomMemTable.TRESTDWMemTableIndex.IsActiveIndex(aCurrent: TRESTDWMemTableIndex): Boolean; Begin - {$IF CompilerVersion < 25} - S := Value; - {$ELSE} - S := AValue; - {$IFEND} - P := RPos(' ', S); - If (P < 8) or (P = Length(S)) Then Exit; - If (Pos(S[P + 1], '-+') > 0) Then - SetLength(S, P - 1); - Inherited SetAsString(S); + Result:=(FIndexType<>itCustom) or (Self=aCurrent); End; -{$ENDIF} -// === { TRESTDWMemTable } ====================================================== -// Function TRESTDWMemTable.FieldByName(const FieldName: string): TField; -// Begin -// -// End; -// -// Function FindField(const FieldName: string): TField; -// Begin -// -// End; +{ TRESTDWCustomMemTable.TRESTDWMemTableIndexDefs } -constructor TRESTDWMemTable.Create(AOwner: TComponent); +Function TRESTDWCustomMemTable.TRESTDWMemTableIndexDefs.GetMemDatasetIndex(AIndex : Integer): TRESTDWMemTableIndex; Begin - Inherited Create(AOwner); - SetLength(FFieldAttrs, 0); - FRecordPos := -1; - FRecordFilterPos := -1; - aFilterRecs := FRecordFilterPos; - FLastID := Low(Integer); - FAutoInc := 1; - FRecords := TRecordList.Create; - FStatusName := STATUSNAME; - FDeletedValues := TList.Create; - FRowsOriginal := 0; - FRowsChanged := 0; - FRowsAffected := 0; - FPacketRecords := 10; - FMaxIndexesCount := 2; - FSaveLoadState := slsNone; - FOneValueInArray := True; - FDataSetClosed := False; - FRefreshing := False; - FTrimEmptyString := True; - FStorageDataType := Nil; - FIndexes := TRESTDWDatasetIndexDefs.Create(Self); - FAllPacketsFetched := False; - FFetch := False; -End; - -Destructor TRESTDWMemTable.Destroy; -var - I : Integer; - PFValues : TPVariant; -Begin - If Active then - Close; - If FFilterParser <> nil then - FreeAndNil(FFilterParser); - {$IFNDEF FPC} - If FFilterExpression <> nil then - FreeAndNil(FFilterExpression); - {$ENDIF} - If Assigned(FDeletedValues) then - Begin - If FDeletedValues.Count > 0 then - For I := 0 to (FDeletedValues.Count - 1) do - Begin - PFValues := FDeletedValues[I]; - If PFValues <> nil then - Dispose(PFValues); - FDeletedValues[I] := nil; - End; - FreeAndNil(FDeletedValues); - End; - FreeIndexList; - // ClearRecords; - ClearIndexes; - FreeAndNil(FIndexes); - FRecords.Free; - SetLength(FOffsets, 0); - //FreeFieldBuffers; - FActive := False; - //FBlobOfs := 0; - If Assigned(FDataSet) Then - FreeAndNil(FDataSet); - Inherited Destroy; + Result:=Items[Aindex] as TRESTDWMemTableIndex; End; -function TRESTDWMemTable.CompareFields(Data1, Data2: Pointer; - FieldType: TFieldType; CaseInsensitive: Boolean): Integer; -Var - vData1, - vData2 : String; +Function TRESTDWCustomMemTable.TRESTDWMemTableIndexDefs.GetBufferIndex(AIndex : Integer): TRESTDWMemInternalIndex; +Begin + Result:=BufIndexdefs[AIndex].BufferIndex; +End; + +Constructor TRESTDWCustomMemTable.TRESTDWMemTableIndexDefs.Create(aDataset: TDataset); Begin - Result := 0; - case FieldType of - ftString : Begin - vData1 := StrPas(PAnsiChar(Data1)); - vData2 := StrPas(PAnsiChar(Data2)); - If CaseInsensitive then - Result := AnsiCompareText(vData1, vData2) - Else - Result := AnsiCompareStr(PDWString(@vData1)^, PDWString(@vData2)^); - End; - ftSmallint: - If Smallint(Data1^) > Smallint(Data2^) then - Result := 1 - Else If Smallint(Data1^) < Smallint(Data2^) then - Result := -1; - ftInteger, ftDate, ftTime, ftAutoInc: - If Longint(Data1^) > Longint(Data2^) then - Result := 1 - Else If Longint(Data1^) < Longint(Data2^) then - Result := -1; - ftWord: - If Word(Data1^) > Word(Data2^) then - Result := 1 - Else If Word(Data1^) < Word(Data2^) then - Result := -1; - ftBoolean: - If Wordbool(Data1^) and not Wordbool(Data2^) then - Result := 1 - Else If not Wordbool(Data1^) and Wordbool(Data2^) then - Result := -1; - ftFloat, ftCurrency - {$IFNDEF FPC} - {$IFDEF DELPHI10_0UP} - , ftSingle - {$ENDIF DELPHI10_0UP} - {$ENDIF}: - If Double(Data1^) > Double(Data2^) then - Result := 1 - Else If Double(Data1^) < Double(Data2^) then - Result := -1; {$IFDEF FPC} - ftFMTBCD: - Result := BcdCompare(TBCD(Data1^), TBCD(Data2^)); - ftBCD: - If Double(Data1^) > Double(Data2^) then - Result := 1 - Else If Double(Data1^) < Double(Data2^) then - Result := -1; + Inherited Create(aDataset,aDataset,TRESTDWMemTableIndex); {$ELSE} - ftFMTBCD, ftBCD: - Result := BcdCompare(TBCD(Data1^), TBCD(Data2^)); + Inherited Create(aDataset); {$ENDIF} - ftDateTime: - If TDateTime(Data1^) > TDateTime(Data2^) then - Result := 1 - Else If TDateTime(Data1^) < TDateTime(Data2^) then - Result := -1; - ftFixedChar : Begin - vData1 := StrPas(PAnsiChar(Data1)); - vData2 := StrPas(PAnsiChar(Data2)); - If CaseInsensitive then - Result := AnsiCompareText(vData1, vData2) - Else - Result := AnsiCompareStr (vData1, vData2); - End; -{$IF DEFINED(FPC) OR DEFINED(COMPILER10_UP)} - ftFixedWideChar: - If CaseInsensitive then - Result := AnsiCompareText(WideCharToString(PWideChar(Data1)), - WideCharToString(PWideChar(Data2))) - Else - Result := AnsiCompareStr(WideCharToString(PWideChar(Data1)), - WideCharToString(PWideChar(Data2))); - ftWideString: - If CaseInsensitive then - Result := AnsiCompareText(WideCharToString(PWideChar(Data1)), - WideCharToString(PWideChar(Data2))) - Else - Result := AnsiCompareStr(WideCharToString(PWideChar(Data1)), - WideCharToString(PWideChar(Data2))); -{$IFEND} - ftLargeint: - If Int64(Data1^) > Int64(Data2^) then - Result := 1 - Else If Int64(Data1^) < Int64(Data2^) then - Result := -1; - ftVariant: - Result := 0; - ftGuid : Begin - vData1 := StrPas(PAnsiChar(Data1)); - vData2 := StrPas(PAnsiChar(Data2)); - Result := CompareText(vData1, vData2); - End; - End; End; -function TRESTDWMemTable.GetCapacity: Integer; +Function TRESTDWCustomMemTable.TRESTDWMemTableIndexDefs.FindIndex(Const IndexName: string): TRESTDWMemTableIndex; + +Var + I: Integer; + Begin - If FRecords <> nil then - Result := FRecords.Capacity - Else - Result := 0; + I:=IndexOf(IndexName); + If I<>-1 Then + Result:=BufIndexdefs[I] + Else + Result:=Nil; End; -procedure TRESTDWMemTable.SetCapacity(Value: Integer); +Function TRESTDWCustomMemTable.TRESTDWMemTableIndexDefs.AddMemTableIndexDef : TRESTDWMemTableIndex; Begin - If FRecords <> nil then - FRecords.Capacity := Value; +{$IFDEF FPC} + Result:=Inherited AddIndexDef as TRESTDWMemTableIndex; +{$ELSE} + Result:=TRESTDWMemTableIndex.Create(Self,'','',[]); +{$ENDIF} End; -function TRESTDWMemTable.AddRecord: TRESTDWMTMemoryRecord; +{ --------------------------------------------------------------------- + TRESTDWCustomMemTable + ---------------------------------------------------------------------} + +Constructor TRESTDWCustomMemTable.Create(AOwner : TComponent); Begin - Result := TRESTDWMTMemoryRecord.Create(TRESTDWMemTableAE(Self)); + Inherited Create(AOwner); + FMaxIndexesCount:=2; + FIndexes:=TRESTDWMemTableIndexDefs.Create(Self); + FRuntimeIndexes:=TRESTDWMemTableIndexDefs.Create(Self); + FAutoIncValue:=-1; + SetLength(FUpdateBuffer,0); + SetLength(FBlobBuffers,0); + SetLength(FUpdateBlobBuffers,0); + FParser := nil; + FPacketRecords := 10; +{$IFDEF RESTDWLAZARUS} + FDatabaseCharSet := csUndefined; +{$ENDIF} End; -function TRESTDWMemTable.FindRecordID(ID: Integer): TRESTDWMTMemoryRecord; -var - I: Integer; +Procedure TRESTDWCustomMemTable.SetPacketRecords(aValue : integer); Begin - for I := 0 to FRecords.Count - 1 do + If (aValue = -1) or (aValue > 0) Then Begin - Result := TRESTDWMTMemoryRecord(FRecords[I]); - If Result <> Nil Then - If Result.ID = ID then - Exit; - End; - Result := nil; + If (IndexFieldNames<>'') and (aValue<>-1) Then + DatabaseError(SInvPacketRecordsValueFieldNames) + Else + If UniDirectional and (aValue=-1) Then + DatabaseError(SInvPacketRecordsValueUniDirectional) + Else + FPacketRecords := aValue + End + Else + DatabaseError(SInvPacketRecordsValue); End; -function TRESTDWMemTable.InsertRecord(Index: Integer): TRESTDWMTMemoryRecord; +Destructor TRESTDWCustomMemTable.Destroy; + Begin - Result := AddRecord; - Result.Index := Index; + FreeAndNil(FDataReference); + FreeAndNil(FDeltaReference); + If Active Then + Close; + SetLength(FUpdateBuffer,0); + SetLength(FBlobBuffers,0); + SetLength(FUpdateBlobBuffers,0); + ClearIndexes; + FreeAndNil(FRuntimeIndexes); + FreeAndNil(FIndexes); + Inherited destroy; End; -function TRESTDWMemTable.GetMemoryRecord(Index: Integer): TRESTDWMTMemoryRecord; +Procedure TRESTDWCustomMemTable.FetchAll; Begin - Result := TRESTDWMTMemoryRecord(FRecords[Index]); + Repeat + Until (getnextpacket < FPacketRecords) or (FPacketRecords = -1); End; -Procedure TRESTDWMemTable.CalcOffSets; -Var - I, Offset : Integer; - vFieldType : TFieldType; - FieldDefsUpdated : Boolean; - FieldLen : Word; -Begin - Offset := 0; - {$IFNDEF FPC} - If Fields.Count > 0 Then - Begin - SetLength(FOffsets, Fields.Count); - Try - For I := 0 to Fields.Count - 1 do +{ +// Code to dump raw dataset data, including indexes information, useful for debugging + Procedure DumpRawMem(const Data: pointer; ALength: TRESTDWPtrInt); + Var + b: integer; + s1,s2: string; + Begin + s1 := ''; + s2 := ''; + For b := 0 to ALength-1 do + Begin + s1 := s1 + ' ' + hexStr(pbyte(Data)[b],2); + If pchar(Data)[b] in ['a'..'z','A'..'Z','1'..'9',' '..'/',':'..'@'] then + s2 := s2 + pchar(Data)[b] + Else + s2 := s2 + '.'; + If length(s2)=16 then Begin - FOffsets[I] := Offset; - If Fields[I].datatype in ftSupported - ftBlobTypes then - Begin - FieldLen := CalcFieldLen(Fields[I].datatype, Fields[I].Size); - Inc(Offset, FieldLen); - End; + write(' ',s1,' '); + writeln(s2); + s1 := ''; + s2 := ''; End; - Finally End; - End - Else - Begin - {$ENDIF} - SetLength(FOffsets, FieldDefs.Count); - FieldDefs.Update; - FieldDefsUpdated := FieldDefs.Updated; - Try - FieldDefs.Updated := True; - // Performance optimization: FieldDefList.Updated returns False is FieldDefs.Updated is False - For I := 0 to FieldDefs.Count - 1 do - Begin - FOffsets[I] := Offset; - If FieldDefs[I].datatype in ftSupported - ftBlobTypes then - Begin - FieldLen := CalcFieldLen(FieldDefs[I].datatype, FieldDefs[I].Size); - Inc(Offset, FieldLen); - vFieldType := FieldDefs[I].DataType; - If vFieldType in [ftFloat, ftBCD, ftFMTBcd] then - Begin - If FieldDefs[I].Precision < 16 Then - FieldDefs[I].Precision := 16; - End; - End; - End; - Finally - FieldDefs.Updated := FieldDefsUpdated; + write(' ',s1,' '); + writeln(s2); + End; + + Procedure DumpRecord(Dataset: TRESTDWCustomMemTable; RecBuf: PRESTDWMemRecLinkItem; RawData: boolean = false); + Var ptr: pointer; + NullMask: pointer; + FieldData: pointer; + NullMaskSize: integer; + i: integer; + Begin + If RawData then + DumpRawMem(RecBuf,Dataset.RecordSize) + Else + Begin + ptr := RecBuf; + NullMask:= ptr + (sizeof(TRESTDWMemRecLinkItem)*Dataset.MaxIndexesCount); + NullMaskSize := 1+(Dataset.Fields.Count-1) div 8; + FieldData:= ptr + (sizeof(TRESTDWMemRecLinkItem)*Dataset.MaxIndexesCount) +NullMaskSize; + write('record: $',hexstr(ptr),' nullmask: $'); + For i := 0 to NullMaskSize-1 do + write(hexStr(byte((NullMask+i)^),2)); + write('='); + For i := 0 to NullMaskSize-1 do + write(binStr(byte((NullMask+i)^),8)); + writeln('%'); + For i := 0 to Dataset.MaxIndexesCount-1 do + writeln(' ','Index ',inttostr(i),' Prior rec: ' + hexstr(pointer((ptr+(i*2)*sizeof(ptr))^)) + ' Next rec: ' + hexstr(pointer((ptr+((i*2)+1)*sizeof(ptr))^))); + DumpRawMem(FieldData,Dataset.RecordSize-((sizeof(TRESTDWMemRecLinkItem)*Dataset.MaxIndexesCount) +NullMaskSize)); End; - {$IFNDEF FPC} - End; - {$ENDIF} -End; + End; -Procedure TRESTDWMemTable.InitFieldDefsFromFieldsInternal; -Var - vFDef : TFieldDef; - I : Integer; - Function FindDef(aName : String) : Boolean; - Var - I : Integer; + Procedure DumpDataset(AIndex: TRESTDWMemInternalIndex;RawData: boolean = false); + Var RecBuf: PRESTDWMemRecLinkItem; Begin - Result := False; - For I := 0 To FieldDefs.Count -1 Do + writeln('Dump records, order based on index ',AIndex.IndNr); + writeln('Current record:',hexstr(AIndex.CurrentRecord)); + + RecBuf:=(AIndex as TRESTDWMemDoubleLinkedIndex).FFirstRecBuf; + While RecBuf<>(AIndex as TRESTDWMemDoubleLinkedIndex).FLastRecBuf do Begin - Result := Lowercase(FieldDefs[I].Name) = Lowercase(aName); - If Result Then - Break; + DumpRecord(AIndex.FDataset,RecBuf,RawData); + RecBuf:=RecBuf[(AIndex as TRESTDWMemDoubleLinkedIndex).IndNr].next; + End; + End; +} + +Procedure TRESTDWCustomMemTable.BuildIndex(AIndex: TRESTDWMemInternalIndex); + +Var PCurRecLinkItem : PRESTDWMemRecLinkItem; + p,l,q : PRESTDWMemRecLinkItem; + i,k,psize,qsize : integer; + myIdx,defIdx : Integer; + MergeAmount : integer; + PlaceQRec : boolean; + + IndexFields : TList; + DescIndexFields : TList; + CInsIndexFields : TList; + + Index0, + DblLinkIndex : TRESTDWMemDoubleLinkedIndex; + + Procedure PlaceNewRec(Var e: PRESTDWMemRecLinkItem; Var esize: integer); + Begin + If DblLinkIndex.FFirstRecBuf=nil Then + Begin + DblLinkIndex.FFirstRecBuf:=e; + e[myIdx].prior:=nil; + l:=e; + End + Else + Begin + l[myIdx].next:=e; + e[myIdx].prior:=l; + l:=e; End; + e := e[myIdx].next; + dec(esize); End; + Begin - For I := 0 To Fields.Count -1 Do + // Build the DBCompareStructure + // One AS is enough, and makes debugging easier. + DblLinkIndex:=(AIndex as TRESTDWMemDoubleLinkedIndex); + Index0:=DefaultIndex.BufferIndex as TRESTDWMemDoubleLinkedIndex; + myIdx:=DblLinkIndex.IndNr; + defIdx:=Index0.IndNr; + With DblLinkIndex Do Begin - If Not FindDef(Fields[I].FieldName) Then - Begin - If Integer(Fields[I].DataType) = {$IFDEF FPC}45{$ELSE}dwftExtended{$ENDIF} Then - Begin - FieldDefs.Add(Fields[I].FieldName, DWFieldTypeToFieldType(Integer(Fields[I].DataType))); - VFDef := FieldDefs[FieldDefs.Count -1]; - End - Else - Begin - VFDef := FieldDefs.AddFieldDef; - VFDef.Name := Fields[I].FieldName; - VFDef.DataType := DWFieldTypeToFieldType(Integer(Fields[I].DataType)); - End; - If Integer(Fields[I].DataType) <> dwftExtended Then - VFDef.Size := Fields[I].Size; - VFDef.Required := Fields[I].Required; - Case Integer(Fields[I].DataType) of - dwftFloat, - dwftCurrency : VFDef.Precision := TRESTDWNumericField(Fields[I]).Precision; - dwftBCD, - dwftFMTBcd : Begin - {$IFNDEF FPC} - VFDef.Size := 0; - VFDef.Precision := 0; - {$ELSE} - VFDef.Precision := TRESTDWNumericField(Fields[I]).Precision; - {$ENDIF} - End; - { - dwftWideString : Begin - If VFDef.Size > 7100 Then - Begin - VFDef.Size := 7100; - FFieldSize[Index] := VFDef.Size; - End; - End; - } - End; - End; + IndexFields := TList.Create; + DescIndexFields := TList.Create; + CInsIndexFields := TList.Create; + Try + GetFieldList(IndexFields,FieldsName); + GetFieldList(DescIndexFields,DescFields); + GetFieldList(CInsIndexFields,CaseinsFields); + If IndexFields.Count=0 Then + DatabaseErrorFmt(SNoIndexFieldNameGiven,[DblLinkIndex.Name],Self); + ProcessFieldsToCompareStruct(IndexFields, DescIndexFields, CInsIndexFields, Options, [], DBCompareStruct); + Finally + CInsIndexFields.Free; + DescIndexFields.Free; + IndexFields.Free; End; End; -procedure TRESTDWMemTable.InitFieldDefsFromFields; -Var - I : Integer; - Field : TField; -Begin - If FieldDefs.Count = 0 then + // This simply copies the index... + PCurRecLinkItem:=Index0.FFirstRecBuf; + PCurRecLinkItem[myIdx].next := PCurRecLinkItem[defIdx].next; + PCurRecLinkItem[myIdx].prior := PCurRecLinkItem[defIdx].prior; + + If PCurRecLinkItem <> Index0.FLastRecBuf Then Begin - For I := 0 to FieldCount - 1 do + While PCurRecLinkItem[defIdx].next<>Index0.FLastRecBuf Do Begin - Field := Fields[I]; - If (Field.FieldKind in fkStoredFields) and not(Field.datatype in ftSupported) then - ErrorFmt('Field ''%s'' is of unknown type', [Field.DisplayName]); + PCurRecLinkItem:=PCurRecLinkItem[defIdx].next; + + PCurRecLinkItem[myIdx].next := PCurRecLinkItem[defIdx].next; + PCurRecLinkItem[myIdx].prior := PCurRecLinkItem[defIdx].prior; End; - FreeIndexList; - End; - {$IFDEF FPC} - SetLength(FOffsets, 0); - { Calculate fields offsets } - CalcOffSets; - {$ENDIF} - InitFieldDefsFromFieldsInternal; -// Inherited InitFieldDefsFromFields; -End; - -function TRESTDWMemTable.FindFieldIndex(Field: TField): Integer; -Var - I : Integer; -Begin - REsult := -1; - For I := 0 To Fields.Count -1 Do + End + Else + // Empty dataset + Exit; + + // Set FirstRecBuf and FCurrentRecBuf + DblLinkIndex.FFirstRecBuf:=Index0.FFirstRecBuf; + DblLinkIndex.FCurrentRecBuf:=DblLinkIndex.FFirstRecBuf; + // Link in the FLastRecBuf that belongs to this index + PCurRecLinkItem[myIdx].next:=DblLinkIndex.FLastRecBuf; + DblLinkIndex.FLastRecBuf[myIdx].prior:=PCurRecLinkItem; + + // Mergesort. Used the algorithm as described here by Simon Tatham + // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html + // The comments in the code are from this website. + + // In each pass, we are merging lists of size K into lists of size 2K. + // (Initially K equals 1.) + k:=1; + + Repeat + + // So we start by pointing a temporary pointer p at the head of the list, + // and also preparing an empty list L which we will add elements to the end + // of as we finish dealing with them. + p := DblLinkIndex.FFirstRecBuf; + DblLinkIndex.FFirstRecBuf := nil; + q := p; + MergeAmount := 0; + + // Then: + // * If p is null, terminate this pass. + While p <> DblLinkIndex.FLastRecBuf Do Begin - If Fields[I] = Field Then + + // * Otherwise, there is at least one element in the next pair of length-K + // lists, so increment the number of merges performed in this pass. + inc(MergeAmount); + + // * Point another temporary pointer, q, at the same place as p. Step q along + // the list by K places, or until the end of the list, whichever comes + // first. Let psize be the number of elements you managed to step q past. + i:=0; + While (iDblLinkIndex.FLastRecBuf) Do Begin - Result := I; - Break; + inc(i); + q := q[myIDx].next; + End; + psize :=i; + + // * Let qsize equal K. Now we need to merge a list starting at p, of length + // psize, with a list starting at q of length at most qsize. + qsize:=k; + + // * So, as long as either the p-list is non-empty (psize > 0) or the q-list + // is non-empty (qsize > 0 and q points to something non-null): + While (psize>0) or ((qsize>0) and (q <> DblLinkIndex.FLastRecBuf)) Do + Begin + // * Choose which list to take the next element from. If either list + // is empty, we must choose from the other one. (By assumption, at + // least one is non-empty at this point.) If both lists are + // non-empty, compare the first element of each and choose the lower + // one. If the first elements compare equal, choose from the p-list. + // (This ensures that any two elements which compare equal are never + // swapped, so stability is guaranteed.) + If (psize=0) Then + PlaceQRec := true + Else If (qsize=0) or (q = DblLinkIndex.FLastRecBuf) Then + PlaceQRec := False + Else If IndexCompareRecords(p,q,DblLinkIndex.DBCompareStruct) <= 0 Then + PlaceQRec := False + Else + PlaceQRec := True; + + // * Remove that element, e, from the start of its list, by advancing + // p or q to the next element along, and decrementing psize or qsize. + // * Add e to the end of the list L we are building up. + If PlaceQRec Then + PlaceNewRec(q,qsize) + Else + PlaceNewRec(p,psize); End; + + // * Now we have advanced p until it is where q started out, and we have + // advanced q until it is pointing at the next pair of length-K lists to + // merge. So set p to the value of q, and go back to the start of this loop. + p:=q; End; + + // As soon as a pass like this is performed and only needs to do one merge, the + // algorithm terminates, and the output list L is sorted. Otherwise, double the + // value of K, and go back to the beginning. + + l[myIdx].next:=DblLinkIndex.FLastRecBuf; + + k:=k*2; + + Until MergeAmount = 1; + DblLinkIndex.FLastRecBuf[myIdx].next:=DblLinkIndex.FFirstRecBuf; + DblLinkIndex.FLastRecBuf[myIdx].prior:=l; End; -function TRESTDWMemTable.FindFieldData(Buffer: Pointer; Field: TField): Pointer; -var - Index : Integer; - datatype : TFieldType; +Procedure TRESTDWCustomMemTable.BuildIndexes; + +Var + i: integer; + Begin - Result := Nil; - // Index := Field.FieldNo - 1; - // If Index < 0 Then - Index := FindFieldIndex(Field); - // FieldDefList index (-1 and 0 become less than zero => ignored) - If (Index >= 0) And - (Buffer <> Nil) Then + For i:=0 To FIndexes.Count-1 Do + If BufIndexDefs[i].MustBuild(FCurrentIndexDef) Then + BuildIndex(BufIndexes[i]); +End; + +Procedure TRESTDWCustomMemTable.ClearIndexes; + +Var + i:integer; + +Begin + CheckInactive; + For I:=0 To FIndexes.Count-1 Do + BufIndexDefs[i].Clearindex; +End; + +Procedure TRESTDWCustomMemTable.RemoveRecordFromIndexes(Const ABookmark: TRESTDWMemBookmark); + +Var + i: integer; + F : TRESTDWMemTableIndex; + +Begin + For i:=0 To FIndexes.Count-1 Do Begin - datatype := Field.datatype; - If datatype in ftSupported then - If datatype in ftBlobTypes then - Begin - {$IFDEF FPC} - Result := Pointer(GetBlobData(Field, Buffer)); - {$ELSE} - {$IF CompilerVersion <= 22} - Result := Pointer(@FBlobs[Field.Offset]); - {$ELSE} - Result := Pointer(GetBlobData(Field, Buffer)); - {$IFEND} - {$ENDIF} - End - Else - Result := Pointer(PRESTDWMTMemBuffer(Buffer) + FOffsets[Index]); + F:=BufIndexDefs[i]; + If F.IsActiveIndex(FCurrentIndexDef) Then + F.BufferIndex.RemoveRecordFromIndex(ABookmark); End; End; -function TRESTDWMemTable.CalcRecordSize: Integer; +Function TRESTDWCustomMemTable.GetIndexDefs : TIndexDefs; +Begin + If Active Then + Result := FRuntimeIndexes + Else + Result := FIndexes; +End; + +Procedure TRESTDWCustomMemTable.SetIndexDefs(Value : TIndexDefs); Var - I : Integer; + I : Integer; + vIndexDef : TIndexDef; Begin - Result := 0; - For I := 0 to Fields.Count - 1 do - CalcDataSize(Fields[I], Result); + If Value = GetIndexDefs Then + Exit; + If Active Then + Begin + FRuntimeIndexes.Clear; + For I := 0 To Value.Count - 1 Do + Begin + FRuntimeIndexes.Add(Value[I].Name, + Value[I].Fields, + Value[I].Options); + vIndexDef:=FRuntimeIndexes[FRuntimeIndexes.Count-1]; + vIndexDef.DescFields:=Value[I].DescFields; + vIndexDef.Expression:=Value[I].Expression; + vIndexDef.Source:=Value[I].Source; +{$IFNDEF FPC} + vIndexDef.GroupingLevel:=Value[I].GroupingLevel; +{$ENDIF} + End; + Exit; + End; + FIndexes.Clear; + For I := 0 To Value.Count - 1 Do + Begin + If FIndexes.IndexOf(Value[I].Name) = -1 Then + Begin + vIndexDef := FIndexes.AddMemTableIndexDef; + vIndexDef.Name := Value[I].Name; + vIndexDef.Fields := Value[I].Fields; + vIndexDef.DescFields := Value[I].DescFields; + vIndexDef.Expression := Value[I].Expression; + vIndexDef.Options := Value[I].Options; + vIndexDef.Source := Value[I].Source; +{$IFNDEF FPC} + vIndexDef.GroupingLevel := Value[I].GroupingLevel; +{$ENDIF} + End; + End; End; -procedure TRESTDWMemTable.InitBufferPointers(GetProps: Boolean); +Function TRESTDWCustomMemTable.GetCanModify: Boolean; Begin - If GetProps then - FRecordSize := CalcRecordSize; - FBookmarkOfs := FRecordSize + sizeof(int64); //o int64 para adicionar o size do blob. o calcfieldssize vem zero //CalcFieldsSize; - FBlobOfs := FBookmarkOfs + SizeOf(TMemBookmarkInfo); - FRecBufSize := FBlobOfs + BlobFieldCount * SizeOf(Pointer); + Result:=not (UniDirectional or ReadOnly); End; -procedure TRESTDWMemTable.ClearRecords; +Function TRESTDWCustomMemTable.BufferOffset: integer; Begin - Try - FClearing := True; - FRecords.ClearAll; - Finally - FClearing := False; - End; - FLastID := Low(Integer); - FRecordPos := -1; - FRecordFilterPos := FRecordPos; - aFilterRecs := FRecordFilterPos; + // Returns the offset of data buffer in MemoryDataset record + Result := sizeof(TRESTDWMemRecLinkItem) * FMaxIndexesCount; End; -function TRESTDWMemTable.AllocRecordBuffer: TRecordBuffer; +Function TRESTDWCustomMemTable.IntAllocRecordBuffer: TRecordBuffer; Begin - {$IFDEF FPC} - GetMem(Result, FRecBufSize); - {$ELSE} - {$IFDEF DELPHI10_0UP} - GetMem(Result, FRecBufSize); - {$ELSE} - Result := StrAlloc(FRecBufSize); - {$ENDIF DELPHI10_0UP} - {$ENDIF} - SetLength(FBlobs, 0); - If BlobFieldCount > 0 Then - SetLength(FBlobs, BlobFieldCount); + // Note: Only the internal buffers of TDataset provide bookmark information + result := AllocMem(FRecordSize+BufferOffset); End; -procedure TRESTDWMemTable.FreeRecordBuffer(var Buffer: TRecordBuffer); +Function TRESTDWCustomMemTable.AllocRecordBuffer: TRecordBuffer; Begin - If BlobFieldCount > 0 Then - SetLength(FBlobs, 0); - {$IFDEF FPC} - FreeMem(Buffer); - {$ELSE} - {$IFDEF DELPHI10_0UP} -// FreeMem(Buffer, 0); - ReallocMem(Buffer, 0); - {$ELSE} - StrDispose(Buffer); - {$ENDIF DELPHI10_0UP} - {$ENDIF} - Inherited FreeRecordBuffer(Buffer); - Buffer := Nil; + result := AllocMem(FRecordSize + BookmarkSize + CalcFieldsSize); + // The records are initialised, or else the fields of an empty, just-opened dataset + // are not null + InitRecord(result); End; -procedure TRESTDWMemTable.ClearCalcFields(Buffer: TRecordBuffer); +Procedure TRESTDWCustomMemTable.FreeRecordBuffer(Var Buffer: TRecordBuffer); Begin -//{$IFNDEF NEXTGEN} -// FillChar(Buffer[FRecordSize], CalcFieldsSize, 0); -//{$ENDIF !NEXTGEN} + ReAllocMem(Buffer,0); End; -{$IFDEF NEXTGEN} -Function TRESTDWMemTable.AllocRecBuf: TRecBuf; +Procedure TRESTDWCustomMemTable.ClearCalcFields(Buffer: TRecordBuffer); Begin - Result := TRecBuf(AllocRecordBuffer); + If CalcFieldsSize > 0 Then + FillChar((Buffer+RecordSize)^,CalcFieldsSize,0); End; -Procedure TRESTDWMemTable.FreeRecBuf(Var Buffer: TRecBuf); +Procedure TRESTDWCustomMemTable.InternalInitFieldDefs; Begin - FreeRecordBuffer(TRecordBuffer(Buffer)); + If FileName<>'' Then + Begin + IntLoadFieldDefsFromFile; + FreeAndNil(FDatasetReader); + FreeAndNil(FFileStream); + End; End; -{$ENDIF} -procedure TRESTDWMemTable.InternalInitRecord(Buffer: TRecordBuffer); +Procedure TRESTDWCustomMemTable.InitUserIndexes; + +Var + i : integer; + Begin -// {$IFDEF NEXTGEN} -// FillChar(PChar(Buffer), FBlobOfs, 0); -// {$ELSE} -// FillChar(Buffer^, FBlobOfs, 0); -// {$ENDIF} + For I:=0 To FIndexes.Count-1 Do + If BufIndexDefs[i].IndexType=itNormal Then + InternalCreateIndex(BufIndexDefs[i]); End; -procedure TRESTDWMemTable.InitRecord(Buffer: TRecordBuffer); +Procedure TRESTDWCustomMemTable.InternalOpen; + Var - vBoolean : Boolean; - PActualRecord : PRESTDWMTMemBuffer; - PData : {$IFDEF FPC}PAnsiChar{$ELSE}PByte{$ENDIF}; - aFieldCount, - I, aIndex, - cLen : Integer; - aDataType : TFieldType; - aFields : TFields; - Fld : TField; // Else BAD mem leak on 'Field.asString' -Begin - vBoolean := True; - {$IFDEF NEXTGEN} - Inherited InitRecord({$IFDEF RTL250_UP}TRecBuf{$ENDIF}(Buffer)); - {$ELSE} - // in non-NEXTGEN InitRecord(TRectBuf) calls InitRecord(TRecordBuffer) => Endless recursion - {$WARN SYMBOL_DEPRECATED OFF} // XE4 - Inherited InitRecord({$IFDEF RTL250_UP}TRecordBuffer{$ENDIF}(Buffer)); - {$WARN SYMBOL_DEPRECATED ON} - {$ENDIF NEXTGEN} - With PMemBookmarkInfo(Buffer + FBookmarkOfs)^ do + IndexNr : Integer; + I : Integer; + +Begin + If Assigned(FDatasetReader) or (FileName<>'') Then + IntLoadFieldDefsFromFile; + + If (Fields.Count>0) and (FieldDefs.Count=0) Then Begin - BookmarkData := Low(Integer); - BookmarkFlag := bfInserted; + InitFieldDefsFromPersistentFields; + BindFields(True); End; - PActualRecord := PRESTDWMTMemBuffer(Buffer); - aFields := Fields; - Try - aFieldCount := aFields.Count; - For I := 0 To aFieldCount - 1 Do - Begin - PData := Nil; - Fld := aFields[I]; - aDataType := Fld.datatype; - aIndex := I; - If DataTypeSuported(aDataType) Then + If (Fields.Count=0) or (FieldDefs.Count=0) Then + DatabaseError(SErrNoDataset); + +{$IFDEF FPC} + NormalizeNumericFieldRanges; + NormalizeFieldDisplayWidths; +{$ENDIF} + + FAutoIncField:=Nil; + If FAutoIncValue>-1 Then + Begin + For I:=0 To Fields.Count-1 Do + If Fields[I] is TAutoIncField Then Begin - If Not DataTypeIsBlobTypes(aDataType) Then - PData := Pointer(PActualRecord + GetOffSets(aIndex)) - Else If Length(FBlobs) > 0 Then - PData := Pointer(@FBlobs[Fld.Offset]); - If (PData <> Nil) Then - Begin - Case FieldTypeToDWFieldType(aDataType) Of - dwftFixedChar, - dwftString, - dwftWideString, - dwftFixedWideChar : Begin - If Fld <> Nil Then - Begin - cLen := GetCalcFieldLen(aDataType, Fld.Size); - {$IFDEF FPC} - FillChar(PData^, cLen, #0); - {$ELSE} - FillChar(PData^, cLen, 0); - {$ENDIF} - End; - End; - dwftByte, - dwftShortint, - dwftSmallint, - dwftWord, - dwftInteger, - dwftAutoInc, - dwftLargeint, - dwftDate, - dwftTime, - dwftDateTime, - dwftTimeStamp, -// dwftSingle, - dwftTimeStampOffset, - dwftFloat, - dwftFMTBcd, - dwftCurrency, - dwftBCD : Begin - vBoolean := False; - If Not(FieldTypeToDWFieldType(aDataType) in [dwftByte, dwftShortint]) then - Begin - Move(vBoolean, pData^, SizeOf(Boolean)); - Inc(pData^); - End; - {$IFDEF FPC} - FillChar(PData^, 1, #0); - {$ELSE} - FillChar(PData^, 1, 0); - {$ENDIF} - End; - dwftStream, - dwftBlob, - dwftBytes, - dwftMemo, - dwftWideMemo, - dwftFmtMemo : SetLength(PRESTDWBytes(PData)^, 0); - End; - End; + FAutoIncField:=TAutoIncField(Fields[I]); + Break; End; - End; - Finally - End; -End; + End; -function TRESTDWMemTable.GetCurrentRecord(Buffer: TRecordBuffer): Boolean; -Begin - Result := False; - If not IsEmpty and (GetBookmarkFlag(ActiveBuffer) = bfCurrent) Then + InitDefaultIndexes; + InitUserIndexes; + + FRuntimeIndexes.Clear; + For IndexNr:=0 To FIndexes.Count-1 Do + If BufIndexDefs[IndexNr].IndexType=itNormal Then Begin - UpdateCursorPos; - New(Buffer); - If (FRecordPos >= 0) and (FRecordPos < RecordCount) then + FRuntimeIndexes.Add(BufIndexDefs[IndexNr].Name, + BufIndexDefs[IndexNr].Fields, + BufIndexDefs[IndexNr].Options); + With FRuntimeIndexes[FRuntimeIndexes.Count-1] Do Begin - Move(Records[FRecordPos].Data^, - {$IFDEF NEXTGEN}PChar(Buffer)^ - {$ELSE}Buffer^ - {$ENDIF}, - FRecordSize); - Result := True; + DescFields:=BufIndexDefs[IndexNr].DescFields; + Expression:=BufIndexDefs[IndexNr].Expression; + Source:=BufIndexDefs[IndexNr].Source; +{$IFNDEF FPC} + GroupingLevel:=BufIndexDefs[IndexNr].GroupingLevel; +{$ENDIF} End; End; -End; -function TRESTDWMemTable.GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode; - DoCheck: Boolean): TGetResult; -var - Accept: Boolean; -Begin - Result := grOk; - Accept := True; - case GetMode of - gmPrior : Begin - If FRecordPos <= 0 then - Begin - Result := grBOF; - FRecordPos := -1; - FRecordFilterPos := FRecordPos; - End - Else - Begin -// aFilterRecs := RecordCount; - Repeat - Dec(FRecordPos); - If Filtered then - Begin - Accept := RecordFilter; - If Accept Then - Dec(aFilterRecs); - End - Else - FRecordFilterPos := FRecordPos; - Until Accept Or (FRecordPos < 0); - If Not Accept Then - Begin - Result := grBOF; - FRecordPos := -1; - End; - FRecordFilterPos := aFilterRecs; - End; - End; - gmCurrent : Begin - If (FRecordPos < 0) or (FRecordPos >= FRecords.Count) then - Result := grError - Else If Filtered Then - Begin - If Not RecordFilter Then - Result := grError; - End; - End; - gmNext : Begin - If FRecordPos >= FRecords.Count - 1 Then - Result := grEOF - Else - Begin - Repeat - Inc(FRecordPos); - If Filtered Then - Begin - Accept := RecordFilter; - If Accept Then - Inc(aFilterRecs); - End; - Until Accept or (FRecordPos > FRecords.Count - 1); - If Not Accept Then - Begin - Result := grEOF; - FRecordPos := RecordCount - 1; - End; - FRecordFilterPos := aFilterRecs; - End; - End; - End; - If (Result = grOk) Then - RecordToBuffer(Records[FRecordPos], PRESTDWMTMemBuffer(Buffer)) - Else If (Result = grError) and DoCheck then - Error(RsEMemNoRecords); -End; + CalcRecordSize; -procedure TRESTDWMemTable.GetBookmarkData(Buffer: TRecordBuffer; - Data: TRESTDWMTBookmark); -Begin - Move(PMemBookmarkInfo(Buffer + FBookmarkOfs)^.BookmarkData, - TRESTDWMTBookmarkData({$IFDEF RTL240_UP}Pointer(@Data[0]){$ELSE}Data{$ENDIF RTL240_UP}^), - SizeOf(TRESTDWMTBookmarkData)); -End; + FBRecordCount:=0; -procedure TRESTDWMemTable.SetBookmarkData(Buffer: TRecordBuffer; - Data: TRESTDWMTBookmark); -Begin - Move({$IFDEF RTL240_UP}Pointer(@Data[0]){$ELSE}Data{$ENDIF RTL240_UP}^, - PMemBookmarkInfo(Buffer + FBookmarkOfs)^.BookmarkData, SizeOf(TRESTDWMTBookmarkData)); -End; + For IndexNr:=0 To FIndexes.Count-1 Do + If Assigned(BufIndexDefs[IndexNr]) Then + With BufIndexes[IndexNr] Do + InitialiseSpareRecord(IntAllocRecordBuffer); -function TRESTDWMemTable.GetBookmarkFlag(Buffer: TRecordBuffer): TBookmarkFlag; -Begin - Result := PMemBookmarkInfo(Buffer + FBookmarkOfs)^.BookmarkFlag; -End; + FAllPacketsFetched:=False; + FOpen:=True; -procedure TRESTDWMemTable.SetBookmarkFlag(Buffer: TRecordBuffer; - Value: TBookmarkFlag); -Begin - PMemBookmarkInfo(Buffer + FBookmarkOfs)^.BookmarkFlag := Value; -End; + ParseFilter(Filter); -procedure TRESTDWMemTable.InternalSetToRecord(Buffer: TRecordBuffer); -Begin - InternalGotoBookmarkData(PMemBookmarkInfo(Buffer + FBookmarkOfs)^.BookmarkData); + If Assigned(FDatasetReader) Then + IntLoadRecordsFromFile; + + If FIndexName<>'' Then + SetIndexName(FIndexName) + Else If FIndexFieldNames<>'' Then + BuildCustomIndex; End; -procedure TRESTDWMemTable.InternalAddRecord(Buffer : {$IFDEF FPC}Pointer{$ELSE} - {$IFDEF RESTDWANDROID}TRecBuf{$ELSE} - {$IF CompilerVersion >22}Pointer{$ELSE}TRecordBuffer{$IFEND}{$ENDIF}{$ENDIF}; - aAppend : Boolean); -var - RecPos: Integer; - Rec: TRESTDWMTMemoryRecord; +Procedure TRESTDWCustomMemTable.DoBeforeClose; Begin - If aAppend then - Begin - Rec := AddRecord; - FRecordPos := FRecords.Count - 1; - End - Else - Begin - If FRecordPos = -1 then - RecPos := 0 - Else - RecPos := FRecordPos; - Rec := InsertRecord(RecPos); - FRecordPos := RecPos; - End; - SetAutoIncFields({$IFDEF RESTDWANDROID}PRESTDWMTMemBuffer(Buffer){$ELSE}Buffer{$ENDIF}); - SetMemoryRecordData({$IFDEF RESTDWANDROID}PRESTDWMTMemBuffer(Buffer){$ELSE}Buffer{$ENDIF}, Rec.Index); + Inherited DoBeforeClose; + If (FFileName<>'') Then + SaveToFile(FFileName,dfDefault); End; -procedure TRESTDWMemTable.RecordToBuffer(Rec : TRESTDWMTMemoryRecord; - Buffer : PRESTDWMTMemBuffer); +Procedure TRESTDWCustomMemTable.RemoveUnnamedFields; + Var - I : Integer; - PActualRecord : PRESTDWMTMemBuffer; -Begin - Move(Rec.Data^, - {$IFDEF NEXTGEN}PChar(Buffer)^ - {$ELSE}Buffer^{$ENDIF}, - FRecordSize); - with PMemBookmarkInfo(Buffer + FBookmarkOfs)^ do - Begin - BookmarkData := Rec.ID; - BookmarkFlag := bfCurrent; - End; - // For I := 0 to BlobFieldCount - 1 do - // PMemBlobArray(Rec.FBlobs)^[I] := PMemBlobArray(Buffer)^[I]; - For I := 0 To BlobFieldCount - 1 Do - Begin - If Length(FBlobs) < Length(Rec.FBlobs) Then - SetLength(FBlobs, Length(Rec.FBlobs)); - FBlobs[I] := Rec.FBlobs[I]; - End; -// GetActiveRecBuf(PActualRecord); -// CalculateFields(PActualRecord); -// CalculateFields({$IFDEF NEXTGEN}TRecBuf{$ELSE}TRecordBuffer{$ENDIF}(Buffer)); - GetCalcFields({$IFNDEF FPC} - {$IFDEF NEXTGEN}TRecBuf{$ELSE} - {$IF CompilerVersion <= 22}Pointer - {$ELSE}TRecBuf{$IFEND} - {$ENDIF} - {$ELSE} - TRecordBuffer - {$ENDIF}(Buffer^)); -End; - -function TRESTDWMemTable.GetRecordSize: Word; -Begin - Result := FRecordSize; -End; - -Function TRESTDWMemTable.GetActiveRecBuf(Var RecBuf : PRESTDWMTMemBuffer): Boolean; -Begin - case State of - dsBrowse: - If IsEmpty then - RecBuf := nil - Else - RecBuf := PRESTDWMTMemBuffer(ActiveBuffer); - dsEdit, dsInsert: - RecBuf := PRESTDWMTMemBuffer(ActiveBuffer); - dsCalcFields: - RecBuf := PRESTDWMTMemBuffer(TempBuffer);//PRESTDWMTMemBuffer(ActiveBuffer);//PRESTDWMTMemBuffer(CalcBuffer); - dsFilter: - RecBuf := PRESTDWMTMemBuffer(TempBuffer); - {$IFDEF FPC} - dsBlockRead : RecBuf := PRESTDWMTMemBuffer(ActiveBuffer); - {$ENDIF} - Else - RecBuf := nil; - End; - Result := RecBuf <> nil; + I : Integer; + +Begin + For I := Fields.Count - 1 Downto 0 Do + If Trim(Fields[I].Name) = '' Then + Fields[I].Free; End; -Function TRESTDWMemTable.InternalGetFieldData(Field : TField; - Var Buffer : TRESTDWMTValueBuffer; - cSize : Integer = 0) : Boolean; +Procedure TRESTDWCustomMemTable.InternalClose; + Var - aNullData : Boolean; - RecBuf : PRESTDWMTMemBuffer; - Data : PByte; - VarData : Variant; - cLen : Integer; - aDataBytes, - aBytes : TRESTDWBytes; - pBytes : PRESTDWBytes; - {$IFDEF FPC} - vSingle : DWSingle; - vDataType : Byte; - vBCD : TBCD; - vBCDA : DWLongDouble; - {$ENDIF} - vDouble : DWFloat; - vLongDouble : DWLongDouble; - vTimeStamp : TSQLTimeStamp; - vTimeStampV : TTimeStamp; - vDateTimeInt : DWInteger; - vDateTimeRec : TDateTimeRec; - vDWFieldType : Byte; - Function CountToNull(Const aBytes : TRESTDWBytes) : Integer; - Var - I : Integer; - Begin - Result := 0; - For I := 0 To Length(aBytes) -1 Do - Begin - If aBytes[I] <> 0 Then - Inc(Result) - Else - Break; - End; - End; + i,r : integer; + iGetResult : TGetResult; + pc : TRecordBuffer; + CurBufIndex: TRESTDWMemTableIndex; + Begin - Result := False; - If Not GetActiveRecBuf(RecBuf) Then - Exit; - If Not IsEmpty And - ((Field.FieldNo > 0) Or - (Field.FieldKind in [fkCalculated, fkLookup])) Then - Begin - Data := FindFieldData(RecBuf, Field); - If (Data <> nil) Or (Field is TBlobField) then + FOpen:=False; + FReadFromFile:=False; + FBRecordCount:=0; + + If (FIndexName<>'') and + (FRuntimeIndexes.IndexOf(FIndexName)<>-1) Then + FIndexName:=''; + FIndexFieldNames:=''; + FRuntimeIndexes.Clear; + + If (FIndexes.Count>0) Then + With DefaultBufferIndex Do + If IsInitialized Then Begin - Result := (Field is TBlobField); - If Not Result Then - Result := Data <> Nil; - If (cSize > 0) Then - cLen := cSize - Else - cLen := GetCalcFieldLen(Field.datatype, Field.Size); - {$IFNDEF FPC} - {$IF CompilerVersion >= 22} - If Field.datatype = ftSingle Then - cLen := SizeOf(Single) + 1; - {$IFEND} - {$ENDIF} - Case Field.datatype Of - ftGuid, - ftString, - ftFixedChar - {$IF DEFINED(FPC) OR DEFINED(DELPHI10_0UP)} - , ftFixedWideChar - , ftWideString - {$IFEND} : Begin - If Field.datatype = ftGuid Then - cLen := cLen -1; - SetLength(aDataBytes, cLen); - Move(Data^, aDataBytes[0], cLen); - Result := Result and (not (Char(aDataBytes[0]) = #0)); - aNullData := Not Result; - {$IFNDEF FPC} - If Not(State in [dsEdit, dsInsert]) Then - Begin - If aNullData Then - Begin - If Length(TRESTDWBytes(Buffer)) > 0 Then - Begin - If (Not (Char(TRESTDWBytes(Buffer)[0]) = #0)) Then - Begin - Move(TRESTDWBytes(Buffer)[0], aDataBytes[0], cLen); - Result := (not (Char(TRESTDWBytes(Buffer)[0]) = #0)); - aNullData := Not Result; - End; - End; - End; - End; - {$ENDIF} - End; - ftBoolean : Begin - {$IFNDEF FPC} - {$IF CompilerVersion > 21} - If Not (Field.datatype in [ftByte, ftShortint]) then - Begin - Result := False; - If Not(Result) then - Begin - cLen := SizeOf(Boolean); - aNullData := False; - SetLength(aDataBytes, cLen); - Move(Data^, aDataBytes[0], cLen); -// Move(aDataBytes[0], Pointer(@aNullData)^, SizeOf(Boolean)); - Result := Not(aNullData); - End; - End - Else - {$IFEND} - Result := Not((Result) and({$IFNDEF FPC}{$IF CompilerVersion <= 22}Char(Data^){$ELSE}Chr(Data[0]){$IFEND}{$ELSE}Char(Data^){$ENDIF} = 'S')); - {$ELSE} - Result := Not(Result); - If Not(Result) then - Begin - aNullData := False; - SetLength(aDataBytes, cLen); - Move(Data^, aDataBytes[0], cLen); - Move(aDataBytes[0], Pointer(@aNullData)^, SizeOf(Boolean)); - Result := Not(aNullData); - End; - {$ENDIF} - End; - ftWord, - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - ftByte, - ftShortint, - ftLongWord, - ftExtended, - ftSingle, - {$IFEND} - {$ENDIF} - ftAutoInc, - ftLargeint, - ftInteger, - ftSmallint, - ftFloat, - ftFMTBCD, - ftBCD, - ftCurrency, - ftTimestamp, - ftDate, - ftTime, - ftDateTime : Begin - //TODO XyberX O dado DateTime deve ser convertido em DateTimeREC no ponteiro TODO Internal - aNullData := False; - SetLength(aDataBytes, SizeOf(Boolean)); - Move(Data^, aDataBytes[0], SizeOf(Boolean)); -// Move(aDataBytes[0], aNullData, 1); - If State in [dsEdit, dsInsert] Then - aNullData := aDataBytes[0] > 1; - If Not aNullData Then - Begin - aNullData := IsNullData(aDataBytes); - Result := Not aNullData; - End; - If Not aNullData then - Begin - SetLength(aDataBytes, cLen); - Move(Data^, aDataBytes[0], cLen); - Move(aDataBytes[0], Pointer(@aNullData)^, SizeOf(Boolean)); - Result := aNullData; - aNullData := False; - End - Else - Begin - Result := Not aNullData; - aNullData := Result; - End; - End; - End; - If Result Then - Begin - If Field.datatype = ftVariant Then - Begin - VarData := PVariant(Data)^; - PVariant(Buffer)^ := VarData; - End - Else If DataTypeIsBlobTypes(Field.datatype) Then - Begin - // Novo Codigo - If State in [dsBrowse] Then - Begin - aBytes := Records[RecNo - 1].Blobs[Field.Offset]; - If Length(aBytes) > 0 Then - Begin - {$IFNDEF FPC} - {$IF CompilerVersion <= 22} - SetLength(TRESTDWBytes(Buffer), Length(aBytes)); - Move(aBytes[0], Buffer^, Length(aBytes)); - {$ELSE} - SetLength(Buffer, Length(aBytes)); - Move(aBytes[0], Buffer[0], Length(aBytes)); - {$IFEND} - {$ELSE} - SetLength(TRESTDWBytes(Buffer), Length(aBytes)); - Move(aBytes[0], Buffer^, Length(aBytes)); - {$ENDIF} - End - Else - Result := False; - End - Else If State in [dsEdit] Then - Begin - Result := True; - aBytes := Records[RecNo - 1].Blobs[Field.Offset]; - If Length(TRESTDWBytes(Buffer)) > 0 Then - Begin - pBytes := Pointer(@PMemBlobArray(Records[RecNo - 1].Blobs[Field.Offset])); - If Length(pBytes^) = 0 Then - Begin - SetLength(pBytes^, 0); - SetLength(pBytes^, Length(aBytes)); - End; - Move(aBytes[0], pBytes^, Length(aBytes)); - End - Else If Length(aBytes) > 0 Then - Begin - {$IFNDEF FPC} - {$IF CompilerVersion <= 22} - SetLength(TRESTDWBytes(Buffer), Length(aBytes)); - Move(aBytes[0], Buffer^, Length(aBytes)); - {$ELSE} - SetLength(Buffer, Length(aBytes)); - Move(aBytes[0], Buffer[0], Length(aBytes)); - {$IFEND} - {$ELSE} - SetLength(TRESTDWBytes(Buffer), Length(aBytes)); - Move(aBytes[0], Buffer^, Length(aBytes)); - {$ENDIF} - End - Else - Result := False; - End - Else If State in [dsInsert] Then - Result := False; - SetLength(aBytes, 0); - End - Else - Begin - If (cSize > 0) Then - cLen := cSize - Else If cLen = 0 Then - cLen := GetCalcFieldLen(Field.datatype, Field.Size); - {$IFNDEF FPC} - {$IF CompilerVersion <= 22} - If Result Then - If Not (Field.datatype in [ftBoolean]) then - Result := ((Not(aNullData)) and Not(VarIsNull(Data^))); - If (Field.datatype In [ftLargeint, ftInteger, ftSmallint, ftFloat, - ftFMTBCD, ftBCD, ftCurrency, ftDate, ftTime]) Then - Result := PRESTDWBytes(@Data)^[1] > 0; - If (Field.datatype In [ftAutoInc, ftLargeint, ftInteger, ftSmallint, ftFloat, - ftFMTBCD, ftBCD, ftCurrency]) Then - Begin - If Length(TRESTDWBytes(Buffer)) = 0 Then - SetLength(TRESTDWBytes(Buffer), cLen); - Move(PRESTDWBytes(@Data)^[1], Pointer(Buffer)^, cLen-1); - End - Else If (Field.datatype In [ftDateTime, ftTimestamp, ftDate, ftTime]) Then - Begin - If Length(TRESTDWBytes(Buffer)) = 0 Then - SetLength(TRESTDWBytes(Buffer), cLen); - cLen := SizeOf(TDateTimeRec); - Move(PRESTDWBytes(@Data)^[1], Pointer(@vDouble)^, SizeOf(DWDouble)); - Case Field.datatype Of - ftTime : Begin - vDateTimeRec.Time := DateTimeToTimeStamp(vDouble).Time; - Move(Pointer(@vDateTimeRec)^, Pointer(Buffer)^, cLen); - End; - ftDate : Begin - vDateTimeRec.Date := Round(vDouble); - Move(Pointer(@vDateTimeRec)^, Pointer(Buffer)^, cLen); - End; - ftDateTime : Begin - vDateTimeRec.DateTime := TimeStampToMSecs(DateTimeToTimeStamp(vDouble)); - Move(Pointer(@vDateTimeRec)^, Pointer(Buffer)^, cLen); - End; - Else - Begin - vTimeStamp := DateTimeToSQLTimeStamp(vDouble); - cLen := SizeOf(vTimeStamp); - Move(Pointer(@vTimeStamp)^, Pointer(Buffer)^, cLen); - End; - End; - End - Else If Field.datatype = ftExtended Then - Begin - If Length(TRESTDWBytes(Buffer)) = 0 Then - SetLength(TRESTDWBytes(Pointer(@Buffer)^), SizeOf(DwLongDouble)); - Move(aDataBytes[1], vLongDouble, SizeOf(vLongDouble)); - Move(vLongDouble, Pointer(Buffer)^, cLen-1); - End - Else - Begin - If Length(TRESTDWBytes(Buffer)) = 0 Then - SetLength(TRESTDWBytes(Buffer), cLen); - If Field.datatype = ftGuid Then - Move(PRESTDWBytes(@Data)^[0], Pointer(Buffer)^, cLen -1) - Else - Move(PRESTDWBytes(@Data)^[0], Pointer(Buffer)^, cLen); - End; - {$ELSE} - If Not (Field.datatype in [ftBoolean{$IFNDEF FPC} - {$IF CompilerVersion > 21} - , ftByte, ftShortint - {$IFEND} - {$ENDIF}]) then - Result := ((Not(aNullData)) and Not(VarIsNull(Data^))); - If (Field.datatype In [ftAutoInc, ftLargeint, ftInteger, ftSmallint, ftFloat, ftSingle, - ftFMTBCD, ftBCD, ftCurrency]) Then - Begin - If Length(TRESTDWBytes(Buffer)) = 0 Then - SetLength(TRESTDWBytes(Buffer), cLen); - If Field.datatype = ftSingle Then - Move(aDataBytes[1], Pointer(Buffer)^, SizeOf(Single)) - Else - Move(aDataBytes[1], Pointer(Buffer)^, cLen-1); - End - Else If (Field.datatype In [ftDateTime, ftTimestamp, ftDate, ftTime]) Then - Begin - If Length(TRESTDWBytes(Buffer)) = 0 Then - SetLength(TRESTDWBytes(Buffer), cLen); - cLen := SizeOf(TDateTimeRec); - Move(aDataBytes[1], Pointer(@vDouble)^, SizeOf(DWDouble)); - Case Field.datatype Of - ftTime : Begin - vDateTimeRec.Time := DateTimeToTimeStamp(vDouble).Time; - Move(Pointer(@vDateTimeRec)^, Pointer(Buffer)^, cLen); - End; - ftDate : Begin - vDateTimeRec.Date := Round(vDouble); - Move(Pointer(@vDateTimeRec)^, Pointer(Buffer)^, cLen); - End; - ftDateTime : Begin - vDateTimeRec.DateTime := TimeStampToMSecs(DateTimeToTimeStamp(vDouble)); - Move(Pointer(@vDateTimeRec)^, Pointer(Buffer)^, cLen); - End; - Else - Begin - vTimeStamp := TSQLTimeStamp(DateTimeToSQLTimeStamp(vDouble)); - cLen := SizeOf(vTimeStamp); - Move(Pointer(@vTimeStamp)^, Pointer(Buffer)^, cLen); - End; - End; - End - Else If Field.datatype = ftExtended Then - Begin - If Length(TRESTDWBytes(Buffer)) = 0 Then - SetLength(TRESTDWBytes(Pointer(@Buffer)^), SizeOf(vLongDouble)); - Move(aDataBytes[1], vLongDouble, SizeOf(vLongDouble)); - Move(Pointer(@vLongDouble)^, Pointer(Buffer)^, SizeOf(vLongDouble)); - End - Else - Begin -// If Field.datatype in [ftString, ftFixedChar -// {$IF DEFINED(FPC) OR DEFINED(DELPHI10_0UP)} -// , ftFixedWideChar , ftWideString{$IFEND}] Then -// Begin -// cLen := CountToNull(aDataBytes); -// If Length(TRESTDWBytes(Buffer)) > cLen Then -// Begin -// SetLength(TRESTDWBytes(Buffer), 0); -// SetLength(TRESTDWBytes(Buffer), cLen); -// End; -// End -// Else -// Begin - If Length(TRESTDWBytes(Buffer)) = 0 Then - SetLength(TRESTDWBytes(Buffer), cLen); -// End; - If Field.datatype = ftGuid Then - Move(PRESTDWBytes(@Data)^[0], Pointer(Buffer)^, cLen -1) - Else - Move(aDataBytes[0], Pointer(Buffer)^, cLen); - End; - {$IFEND} - {$ELSE} - If Length(TRESTDWBytes(Buffer)) = 0 Then - SetLength(TRESTDWBytes(Buffer), cLen); - If Not (Field.datatype in [ftBoolean]) then - Result := ((Not(aNullData)) and Not(VarIsNull(Data^))); - If (Field.datatype In [ftAutoInc, ftLargeint, ftInteger, ftSmallint, ftFloat, - ftFMTBCD, ftBCD, ftCurrency]) Then - Begin - vDataType := FieldTypeToDWFieldType(Field.DataType); - If vDataType = dwftBCD Then - Begin - Move(aDataBytes[1], Pointer(@vLongDouble)^, SizeOf(vLongDouble)); - cLen := SizeOf(vLongDouble); - Move(Pointer(@vLongDouble)^, Pointer(Buffer)^, cLen); - End - Else If vDataType = 45 Then - Begin - If Length(TRESTDWBytes(Buffer)) = 0 Then - SetLength(TRESTDWBytes(Pointer(@Buffer)^), SizeOf(DwLongDouble)); - Move(aDataBytes[1], vLongDouble, SizeOf(vLongDouble)); - Move(vLongDouble, Pointer(Buffer)^, cLen-1); - End - Else - Move(aDataBytes[1], Pointer(Buffer)^, cLen-1); - End - Else If (Field.datatype In [ftDateTime, ftTimestamp, ftDate, ftTime]) Then - Begin - vDouble := 0; - If Length(TRESTDWBytes(Buffer)) = 0 Then - SetLength(TRESTDWBytes(Buffer), cLen); - cLen := SizeOf(TDateTimeRec); - Move(aDataBytes[1], Pointer(@vDouble)^, SizeOf(DWDouble)); - vDataType := FieldTypeToDWFieldType(Field.DataType); - //Em Lazarus é assim - Move(Pointer(@vDouble)^, Pointer(Buffer)^, cLen); - { - //Em Delphi eh diferente - Case Field.datatype Of - ftTime : Begin - vDateTimeRec.Time := DateTimeToTimeStamp(vDouble).Time; - Move(Pointer(@vDateTimeRec)^, Pointer(Buffer)^, cLen); - End; - ftDate : Begin - vDateTimeRec.Date := Round(vDouble); - Move(Pointer(@vDateTimeRec)^, Pointer(Buffer)^, cLen); - End; - ftDateTime : Begin - vDateTimeRec.DateTime := TimeStampToMSecs(DateTimeToTimeStamp(vDouble)); - Move(Pointer(@vDateTimeRec)^, Pointer(Buffer)^, cLen); - End; - Else - Begin - vTimeStamp := DateTimeToSQLTimeStamp(vDouble); - cLen := SizeOf(vTimeStamp); - Move(Pointer(@vTimeStamp)^, Pointer(Buffer)^, cLen); - End; - End; - } - End - Else If vDataType = dwftExtended Then - Begin - If Length(TRESTDWBytes(Buffer)) = 0 Then - SetLength(TRESTDWBytes(Pointer(@Buffer)^), SizeOf(DwLongDouble)); - Move(aDataBytes[1], vLongDouble, SizeOf(vLongDouble)); - Move(vLongDouble, Pointer(Buffer)^, cLen-1); - End - Else - Begin - If Length(TRESTDWBytes(Buffer)) = 0 Then - SetLength(TRESTDWBytes(Buffer), cLen); - If Field.datatype = ftGuid Then - Move(aDataBytes[0], Pointer(Buffer)^, cLen -1) - Else - Move(aDataBytes[0], Pointer(Buffer)^, cLen); - End; - {$ENDIF} - SetLength(aDataBytes, 0); - End; - End - Else + iGetResult:=ScrollFirst; + While iGetResult = grOK Do Begin - If (Length(TRESTDWBytes(Buffer)) = 0) And - (cLen > 0) Then - SetLength(TRESTDWBytes(Buffer), cLen); - Result := False; + pc:=pointer(CurrentRecord); + iGetResult:=ScrollForward; + FreeRecordBuffer(pc); End; End; - End - Else + + For r := 0 To FIndexes.Count-1 Do + With FIndexes.BufIndexes[r] Do + If IsInitialized Then + Begin + pc:=SpareRecord; + ReleaseSpareRecord; + FreeRecordBuffer(pc); + End; + + If Length(FUpdateBuffer) > 0 Then Begin - If State in [dsBrowse, dsEdit, dsInsert, dsCalcFields, dsfilter] Then + For r := 0 To length(FUpdateBuffer)-1 Do With FUpdateBuffer[r] Do Begin - If Not DataTypeIsBlobTypes(Field.datatype) Then - Begin - Data := FindFieldData(RecBuf, Field); - cLen := GetCalcFieldLen(Field.datatype, Field.Size); - SetLength(aDataBytes, cLen); - Move(Data^, aDataBytes[0], cLen); - Result := ((Not(aNullData)) and Not(VarIsNull(Data^))); - If (Field.datatype In [ftAutoInc, ftLargeint, ftInteger, ftSmallint, ftFloat - {$IFNDEF FPC}{$IFDEF DELPHI10_0UP} - , ftSingle - {$ENDIF DELPHI10_0UP}{$ENDIF}, - ftFMTBCD, ftBCD, ftCurrency, ftDate, - ftTime, ftDateTime, ftTimestamp]) Then - Move(aDataBytes[1], Pointer(Buffer)^, cLen-1) - Else - Move(aDataBytes[0], Pointer(Buffer)^, cLen); - SetLength(aDataBytes, 0); - End - Else - Begin - Inc(RecBuf, FRecordSize + Field.Offset); - Result := Byte(RecBuf[0]) <> 0; - If Result Then - Begin - {$IFNDEF FPC} - {$IF CompilerVersion <= 22} - Move(RecBuf[1], Buffer^, Field.DataSize); - {$ELSE} - Move(RecBuf[1], Buffer[0], Field.DataSize); - {$IFEND} - {$ELSE} - Move(RecBuf[1], Buffer^, Field.DataSize); - {$ENDIF} - End; - End; + If assigned(OldValuesBuffer) Then + FreeRecordBuffer(OldValuesBuffer); + If (UpdateKind = ukDelete) and assigned(BookmarkData.BookmarkData) Then + FreeRecordBuffer(TRecordBuffer(BookmarkData.BookmarkData)); End; End; + SetLength(FUpdateBuffer,0); + + For r := 0 To High(FBlobBuffers) Do + FreeBlobBuffer(FBlobBuffers[r]); + For r := 0 To High(FUpdateBlobBuffers) Do + FreeBlobBuffer(FUpdateBlobBuffers[r]); + SetLength(FBlobBuffers,0); + SetLength(FUpdateBlobBuffers,0); + SetLength(FFieldBufPositions,0); + If FAutoIncValue>-1 Then + FAutoIncValue:=1; + If assigned(FParser) Then + FreeAndNil(FParser); + For I:=FIndexes.Count-1 Downto 0 Do + Begin + CurBufIndex:=BufIndexDefs[i]; + If (CurBufIndex.IndexType in [itDefault,itCustom]) or (CurBufIndex.DiscardOnClose) Then + Begin + If FCurrentIndexDef=CurBufIndex Then + FCurrentIndexDef:=nil; + CurBufIndex.Free; + End + Else + FreeAndNil(CurBufIndex.FBufferIndex); + End; + RemoveUnnamedFields; End; -{$IFNDEF NEXTGEN} - {$IFDEF RTL240_UP} -Function TRESTDWMemTable.GetFieldData(Field: TField; Buffer: Pointer): Boolean; -{$IFNDEF FPC} - {$IF CompilerVersion < 21} - Type - PValueBuffer = ^TValueBuffer; - TValueBuffer = Array of Byte; - Var - aPointer: Pointer; - aDummyVar: PValueBuffer; - aEnterpointer: Boolean; - {$IFEND} -{$ENDIF} +Procedure TRESTDWCustomMemTable.InternalFirst; + Begin -{$IFNDEF FPC} - {$IF CompilerVersion < 21} - aEnterpointer := False; - If Not Assigned(Buffer) Then - Begin - aEnterpointer := True; - aDummyVar := AllocMem(SizeOf(TValueBuffer)); - aPointer := @aDummyVar; - End - Else - aPointer := @Buffer; - Result := InternalGetFieldData(Field, TRESTDWMTValueBuffer(aPointer^)); - If aEnterpointer Then - Begin - SetLength(aDummyVar^, 0); - FreeMem(aDummyVar); - End; - {$ELSE} - Result := InternalGetFieldData(Field, TRESTDWMTValueBuffer(Buffer), Field.Size); - {$IFEND} - {$ELSE} - Result := InternalGetFieldData(Field, TRESTDWMTValueBuffer(Buffer)); -{$ENDIF} + With CurrentIndexBuf Do + // if FCurrentRecBuf = FLastRecBuf then the dataset is just opened and empty + // in which case InternalFirst should do nothing (bug 7211) + SetToFirstRecord; End; - {$ENDIF RTL240_UP} -{$ENDIF ~NEXTGEN} -{$IFDEF FPC} -Procedure TRESTDWMemTable.SetFieldValues(const FieldName: string; Value: Variant); -Var - vFieldType : TFieldType; - vField : TField; +Procedure TRESTDWCustomMemTable.InternalLast; Begin - vField := FindField(FieldName); - vFieldType := vField.DataType; - If vFieldType = ftBCD Then - Begin - If TBcdField(vField).MinValue = 0 Then - TBcdField(vField).MinValue := -999999999999; - If TBcdField(vField).MaxValue = 0 Then - TBcdField(vField).MaxValue := 9999999999999; - End - Else If vFieldType = ftFloat Then - Begin - If TFloatField(vField).MinValue = 0 Then - TFloatField(vField).MinValue := -999999999999; - If TFloatField(vField).MaxValue = 0 Then - TFloatField(vField).MaxValue := 9999999999999; - End - Else If vFieldType = ftFMTBcd Then - Begin - If TFMTBcdField(vField).MinValue = '0' Then - TFMTBcdField(vField).MinValue := '-99999999999999'; - If TFMTBcdField(vField).MaxValue = '0' Then - TFMTBcdField(vField).MaxValue := '99999999999999'; - End; - inherited SetFieldValues(FieldName, Value); + FetchAll; + With CurrentIndexBuf Do + SetToLastRecord; End; -{$ENDIF} -Function TRESTDWMemTable.GetFieldIndex(Const aName : String) : Integer; +Procedure TRESTDWCustomMemTable.CopyFromDataset(DataSet: TDataSet; CopyData: Boolean); + +Const + UseStreams = [ftBlob,ftMemo,ftGraphic,ftWideMemo]; + Var - L : Integer; + I : Integer; + F,F1,F2 : TField; + L1,L2 : TList; + N : String; + OriginalPosition: TBookMark; + S : TMemoryStream; + Begin - L := Length(Name); - For Result := 0 to FieldCount - 1 do + Close; + Fields.Clear; + FieldDefs.Clear; + For I:=0 To Dataset.FieldCount-1 Do Begin - If (Length(FFieldName[Result]) = L) and - (AnsiCompareText(FFieldName[Result], Name) = 0) Then - Exit; + F:=Dataset.Fields[I]; + TFieldDef.Create(FieldDefs,F.FieldName,F.DataType,F.Size,F.Required,F.FieldNo); + End; + CreateDataset; + L1:=Nil; + L2:=Nil; + S:=Nil; + If CopyData Then + Try + L1:=TList.Create; + L2:=TList.Create; + Open; + For I:=0 To FieldDefs.Count-1 Do + Begin + N:=FieldDefs[I].Name; + F1:=FieldByName(N); + F2:=DataSet.FieldByName(N); + L1.Add(F1); + L2.Add(F2); + If (FieldDefs[I].DataType in UseStreams) and (S=Nil) Then + S:=TMemoryStream.Create; + End; + DisableControls; + Dataset.DisableControls; + OriginalPosition:=Dataset.GetBookmark; + Try + Dataset.Open; + Dataset.First; + While not Dataset.EOF Do + Begin + Append; + For I:=0 To L1.Count-1 Do + Begin + F1:=TField(L1[i]); + F2:=TField(L2[I]); + If Not F2.IsNull Then + Case F1.DataType Of + ftFixedChar, + ftString : F1.AsString:=F2.AsString; + ftFixedWideChar, + ftWideString : F1.AsWideString:=F2.AsWideString; + ftBoolean : F1.AsBoolean:=F2.AsBoolean; + ftFloat : F1.AsFloat:=F2.AsFloat; + ftAutoInc, + ftSmallInt, + ftInteger : F1.AsInteger:=F2.AsInteger; + ftLargeInt : F1.AsLargeInt:=F2.AsLargeInt; + ftDate : F1.AsDateTime:=F2.AsDateTime; + ftTime : F1.AsDateTime:=F2.AsDateTime; + ftTimestamp, + ftDateTime : F1.AsDateTime:=F2.AsDateTime; + ftCurrency : F1.AsCurrency:=F2.AsCurrency; + ftBCD, + ftFmtBCD : F1.AsBCD:=F2.AsBCD; + Else + If (F1.DataType in UseStreams) Then + Begin + S.Clear; + TBlobField(F2).SaveToStream(S); + S.Position:=0; + TBlobField(F1).LoadFromStream(S); + End + Else + F1.AsString:=F2.AsString; + End; + End; + Try + Post; + Except + Cancel; + Raise; +End; + Dataset.Next; + End; + Finally + DataSet.GotoBookmark(OriginalPosition); //Return to original record + Dataset.EnableControls; + EnableControls; + End; + Finally + L2.Free; + l1.Free; + S.Free; End; - Result := -1 End; -Function TRESTDWMemTable.GetFieldDef(Index: Integer): Integer; -begin - Result := -1; - If Fields.Count > 0 Then - Result := Integer(Fields[Index].DataType); -end; +{ TRESTDWMemInternalIndex } -Function TRESTDWMemTable.GetFieldClass(FieldType : TFieldType): TFieldClass; -Var - I : Integer; +Constructor TRESTDWMemInternalIndex.Create(Const ADataset: TRESTDWCustomMemTable); Begin - If (csDesigning in ComponentState) and (FDsgnFieldName <> '') Then - Begin - Result := Nil; - I := GetFieldIndex(FDsgnFieldName); - If I >= 0 Then - Begin - Case GetFieldDef(I) of - dwftStream : Result := TStreamField; - dwftExtended : Result := TRESTDWNumericField; - dwftString : Result := TStringFieldRESTDW; - {$IFNDEF FPC} - dwftTimeStampOffset : Result := TRESTDWSQLTimeStampOffsetField; - {$ENDIF} -// dwftColor : Result := TColorField; - End; - If Result <> nil then - Exit; - End; - end; - If FFieldDefClass = Nil then - Result := DefaultFieldClasses[FieldType] - Else - Result := FFieldDefClass; + Inherited create; + FDataset := ADataset; End; -Function TRESTDWMemTable.GetFieldData(Field : TField; - {$IFNDEF FPC} - {$IF CompilerVersion > 21}Var{$IFEND} - Buffer : TRESTDWMTValueBuffer - {$ELSE} - Buffer : Pointer - {$ENDIF}): Boolean; -Var - vResult : Boolean; - aDataSize : Integer; - aPointer : Pointer; -Begin - aDataSize := CalcFieldLen(Field.datatype, Field.Size); - {$IFNDEF FPC} -// SetLength(Buffer, aDataSize); -//// {$ELSE} - If Length(Buffer) = 0 Then - SetLength(TRESTDWBytes(Buffer), aDataSize); - {$ENDIF} - aPointer := @Buffer; - vResult := False; - Try - vResult := InternalGetFieldData(Field, TRESTDWMTValueBuffer(aPointer^)); - Finally - Result := vResult; - End; +Function TRESTDWMemInternalIndex.BookmarkValid(Const ABookmark: PRESTDWMemBookmark): boolean; +Begin + Result := assigned(ABookmark) and assigned(ABookmark^.BookmarkData); End; -procedure TRESTDWMemTable.InternalSetFieldData(Field : TField; - Buffer : Pointer; - Const ValidateBuffer : TRESTDWMTValueBuffer); -Var - PActualRecord : PRESTDWMTMemBuffer; - aState : TDataSetState; - Data : {$IFDEF FPC}PAnsiChar{$ELSE}PByte{$ENDIF}; - aBytes : TRESTDWBytes; - pBytes : PRESTDWBytes; - VarData : Variant; - aResult, - vBoolean, - IsData : Boolean; - aIndex, - cLen : Integer; - vDateTimeInt : DWInteger; - vDateFloat : DWFloat; - vDateLongDouble : DWLongDouble; - vDateTimeStamp : TTimeStamp; - {$IFNDEF FPC} - vDateSQLTimeStamp : TSQLTimeStamp; - {$ENDIF} - vDateTime : TDateTime; - vDateTimeRec : TDateTimeRec; - aDataType : TFieldType; - Procedure GetDataValue; - Begin - // The non-NEXTGEN Pointer version has "TArray := Pointer" in it what interprets an untypes pointer as dyn. array. Not good. - If Field.FieldKind <> fkInternalCalc Then - Begin - aIndex := FindFieldIndex(Field); - Data := FindFieldData(PActualRecord, Field); - If (Data <> Nil) Or (Field Is TBlobField) Then - Begin - aResult := (Field is TBlobField); - If Data <> Nil Then - Begin - If Not aResult Then - aResult := Data <> Nil; - End; - If aResult Then - Begin - If Field.datatype = ftVariant Then - Begin - VarData := PVariant(Buffer)^; - PVariant(Data)^ := VarData; - End - Else If DataTypeIsBlobTypes(Field.datatype) Then - Begin - SetLength(aBytes, Length(TRESTDWBytes(Buffer))); - {$IFNDEF FPC} - {$IF CompilerVersion <= 22} - Move(Buffer^, aBytes[0], Length(aBytes)); - {$ELSE} - Move(TRESTDWBytes(Buffer)[0], aBytes[0], Length(aBytes)); - {$IFEND} - {$ELSE} - Move(Buffer^, aBytes[0], Length(aBytes)); - {$ENDIF} - If Length(aBytes) > 0 Then - Begin - pBytes := Pointer(@PMemBlobArray(Records[RecNo - 1].Blobs)^[Field.Offset]); - If Length(pBytes^) = 0 Then - Begin - SetLength(pBytes^, 0); - SetLength(pBytes^, Length(aBytes)); - End; - Move(aBytes[0], pBytes^, Length(aBytes)); - End; - End - Else - Begin - If Length(TRESTDWBytes(ValidateBuffer)) = 0 Then - Begin - If Field.datatype in [ftWord, ftAutoInc, - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - ftByte, ftShortint, ftLongWord, ftExtended, ftSingle, - {$IFEND} - {$ENDIF} - ftLargeint, ftInteger, ftSmallint, ftFloat, ftFMTBCD, - ftBCD, ftCurrency, ftDate, ftTime, ftDateTime, ftTimestamp] Then - Begin - {$IFNDEF FPC} - {$IF CompilerVersion > 21} - If Not (Field.datatype in [ftByte, ftShortint]) then - Begin - Move(vBoolean, Data^, SizeOf(Boolean)); - Inc(Data^); - End; - {$IFEND} - {$ELSE} - Move(vBoolean, Data^, SizeOf(Boolean)); - Inc(Data^); - {$ENDIF} - FillChar(Data^, 1, 'S'); - End; - End - Else - Begin - cLen := GetCalcFieldLen(Field.datatype, Field.Size); - Case FieldTypeToDWFieldType(Field.datatype) of - dwftWideString, - dwftFixedWideChar, - dwftFixedChar, - dwftString : Begin - {$IFDEF FPC} - FillChar(Data^, cLen, #0); - {$ELSE} - FillChar(Data^, cLen, 0); - {$ENDIF} - If Length(TRESTDWBytes(ValidateBuffer)) > 0 Then - Move(TRESTDWBytes(ValidateBuffer)[0], data^, cLen); - End; - dwftWord, - dwftAutoInc, - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - dwftByte, dwftShortint, dwftLongWord, //dwftSingle, - {$IFEND} - {$ENDIF} - dwftExtended, - dwftLargeint, - dwftInteger, - dwftSmallint, - dwftFloat, - {$IFNDEF FPC} - dwftFMTBCD, - {$ELSE} - 45, - {$ENDIF} - dwftBCD, - dwftCurrency, - dwftBoolean : Begin -// vBoolean := Length(TRESTDWBytes(Buffer)) > 0; - {$IFNDEF FPC} - {$IF CompilerVersion > 21} - If Not (Field.datatype in [ftByte, ftShortint]) then - Begin - {$IFEND} - {$ENDIF} - SetLength(aBytes, cLen); - Move(vBoolean, aBytes[0], SizeOf(Boolean)); - Move(TRESTDWBytes(Buffer)[0], aBytes[1], cLen-1); - Move(aBytes[0], data^, cLen); - SetLength(aBytes, 0); - {$IFNDEF FPC} - {$IF CompilerVersion > 21} - End - Else - Move(buffer^, data^, cLen); - {$IFEND} - {$ENDIF} - End; - dwftDate, - dwftTime, - dwftDateTime, - dwftTimestamp : Begin -// vBoolean := Length(TRESTDWBytes(Buffer)) = 0; - SetLength(aBytes, SizeOf(DWFloat) + 1); - If aDataType in [ftDate, ftTime] Then - Begin - Move(vBoolean, aBytes[0], SizeOf(Boolean)); - Move(TRESTDWBytes(Buffer)[0], Pointer(@vDateTimeInt)^, SizeOf(DWInteger)); - If aDataType = ftDate Then - Begin - vDateTimeStamp.Date := vDateTimeInt; - vDateFloat := TimeStampToDateTime(vDateTimeStamp); - vDateFloat := vDateTimeInt; - End - Else - Begin - vDateTime := 0; - vDateTime := IncMillisecond(vDateTime, vDateTimeInt); - vDateFloat := vDateTime; - End; - Move(Pointer(@vDateFloat)^, aBytes[1], SizeOf(DWFloat)); - End - Else - Begin - Move(vBoolean, aBytes[0], SizeOf(Boolean)); -// prevBuffer := Copy(TValueBuffer(Buffer)); - {$IFDEF FPC} - Move(TRESTDWBytes(Buffer)[0], Pointer(@vDateFloat)^, SizeOf(vDateFloat)); - vDateTimeStamp.Date := Trunc(vDateFloat / msecsperday); - vDateFloat := vDateFloat - comp(vDateTimeStamp.Date) * msecsperday; - vDateTimeStamp.Time := Round(vDateFloat); - vDateFloat := TimeStampToDateTime(vDateTimeStamp); - {$ELSE} - Move(TRESTDWBytes(Buffer)[0], Pointer(@vDateSQLTimeStamp)^, SizeOf(vDateSQLTimeStamp)); - vDateFloat := SQLTimeStampToDateTime(vDateSQLTimeStamp); -// vDateTimeStamp := MSecsToTimeStamp(vDateFloat); - {$ENDIF} - Move(Pointer(@vDateFloat)^, aBytes[1], SizeOf(DWFloat)); - End; - Move(aBytes[0], data^, Length(aBytes)); - SetLength(aBytes, 0); - End; - Else - Move(buffer^, data^, cLen); - End; - End; - End; - End; - End; - End; - End; +Function TRESTDWMemInternalIndex.CompareBookmarks(Const ABookmark1, ABookmark2: PRESTDWMemBookmark): integer; Begin - IsData := False; - vBoolean := True; - aState := State; - If Not (Field.FieldKind in [fkCalculated, fkLookup]) Then - Begin - If Not(State in dsWriteModes) Then - Error('Not Editing...'); - GetActiveRecBuf(PActualRecord); - aResult := False; - If Field.FieldNo > 0 then - Begin - aDataType := Field.datatype; - If State In [dsCalcFields, dsFilter] Then - Error('Not Editing...'); - If Field.ReadOnly And Not(State In [dsSetKey, dsFilter]) Then - ErrorFmt('The Field %s is readonly...', [Field.DisplayName]); - Field.Validate(ValidateBuffer); - GetDataValue; - End; - End - Else { fkCalculated, fkLookup } - Begin - aState := dsCalcFields; - GetActiveRecBuf(PActualRecord); - If Field.FieldNo > 0 then - Field.Validate(ValidateBuffer); - GetDataValue; - End; - If Not(aState In [dsCalcFields, dsFilter, dsNewValue]) Then - DataEvent(deFieldChange, NativeInt(Field)); -End; - -procedure TRESTDWMemTable.GetFieldList(List: TList; const FieldNames: string); -var - Pos: Integer; - Field: TField; - Len: Integer; -begin - Len := FieldNames.Length; - Pos := 1; - while Pos <= Len do - begin - Field := FieldByName(ExtractFieldName(FieldNames, Pos)); - if Assigned(List) then List.Add(Field); - end; -end; - -function TRESTDWMemTable.GetBlob(aRecNo, Index: Integer): PMemBlobData; -Begin - Result := Nil; - If aRecNo > 0 Then - Begin - If State in [dsEdit, dsBrowse] then - Begin - If Length(frecords[arecNo -1].fblobs) > 0 Then - Result := @frecords[arecNo -1].fblobs[Index] - Else If Length(fblobs) > Index Then - Result := @fblobs[Index]; - End - Else If State in [dsInsert] then - If Length(fblobs) > Index Then - Result := @fblobs[Index]; - End - Else If Length(fblobs) > Index Then - Result := @fblobs[Index]; + Result := 0; End; -Procedure TRESTDWMemTable.SetFieldData(Field : TField; - Buffer : TRESTDWMTValueBuffer); +Function TRESTDWMemInternalIndex.SameBookmarks(Const ABookmark1, ABookmark2: PRESTDWMemBookmark): boolean; Begin - {$IFNDEF FPC} - {$IF CompilerVersion <= 22} - If Length(TRESTDWBytes(Buffer)) > 0 Then - InternalSetFieldData(Field, {$IFDEF RTL240_UP}PByte(@Buffer[0]){$ELSE}Buffer{$ENDIF RTL240_UP}, Buffer) - Else - InternalSetFieldData(Field, {$IFDEF RTL240_UP}PByte(@Buffer){$ELSE}Buffer{$ENDIF RTL240_UP}, Buffer); - {$ELSE} - If Length(Buffer) > 0 Then - InternalSetFieldData(Field, {$IFDEF RTL240_UP}PByte(@Buffer[0]){$ELSE}Buffer{$ENDIF RTL240_UP}, TRESTDWMTValueBuffer(Pointer(@Buffer)^)) - Else - InternalSetFieldData(Field, {$IFDEF RTL240_UP}PByte(@Buffer){$ELSE}Buffer{$ENDIF RTL240_UP}, Buffer); - {$IFEND} - {$ELSE} - If Length(TRESTDWBytes(Buffer)) > 0 Then - InternalSetFieldData(Field, Buffer, TRESTDWMTValueBuffer(Pointer(@Buffer)^)) - Else - InternalSetFieldData(Field, Buffer, Buffer); - {$ENDIF} + Result := Assigned(ABookmark1) and Assigned(ABookmark2) and (CompareBookmarks(ABookmark1, ABookmark2) = 0); End; -{$IFNDEF NEXTGEN} -{$IFDEF RTL240_UP} -Procedure TRESTDWMemTable.SetFieldData(Field: TField; Buffer: Pointer); -var - ValidateBuffer: TRESTDWMTValueBuffer; +Function TRESTDWMemInternalIndex.GetRecord(ABookmark: PRESTDWMemBookmark; GetMode: TGetMode): TGetResult; Begin - If (Buffer <> nil) and (Field.FieldNo > 0) and (Field.DataSize > 0) then - Begin - SetLength(ValidateBuffer, Field.DataSize); - Move(Buffer^, ValidateBuffer[0], Length(TValueBuffer(Buffer))); //;Field.DataSize); - End - Else - ValidateBuffer := nil; - InternalSetFieldData(Field, Buffer, ValidateBuffer); + Result := grError; End; -{$ENDIF RTL240_UP} -{$ENDIF ~NEXTGEN} -procedure TRESTDWMemTable.SetFiltered(Value: Boolean); +{ TRESTDWMemDoubleLinkedIndex } + +Function TRESTDWMemDoubleLinkedIndex.GetBookmarkSize: integer; Begin - If Active then - Begin - CheckBrowseMode; - aFilterRecs := 0; - If Filtered <> Value then - inherited SetFiltered(Value); - First; - End - Else - inherited SetFiltered(Value); + Result:=sizeof(TRESTDWMemBookmark); End; -procedure TRESTDWMemTable.SetOnFilterRecord(const Value: TFilterRecordEvent); +Function TRESTDWMemDoubleLinkedIndex.GetCurrentBuffer: Pointer; Begin - If Active then - Begin - CheckBrowseMode; - inherited SetOnFilterRecord(Value); - If Filtered then - First; - End - Else - inherited SetOnFilterRecord(Value); + Result := Pointer(TRESTDWPtrInt(FCurrentRecBuf) + FDataset.BufferOffset); End; -function TRESTDWMemTable.RecordFilter: Boolean; -var - SaveState: TDataSetState; +Function TRESTDWMemDoubleLinkedIndex.GetCurrentRecord: TRecordBuffer; Begin - Result := True; - If Assigned(OnFilterRecord) or (FFilterParser <> nil){$IFNDEF FPC} or - (FFilterExpression <> nil){$ENDIF} then - Begin - If (FRecordPos >= 0) and (FRecordPos < RecordCount) then - Begin - SaveState := SetTempState(dsFilter); - Try - RecordToBuffer(Records[FRecordPos], PRESTDWMTMemBuffer(TempBuffer)); - {$IFDEF FPC} - If (FFilterParser <> nil) and FFilterParser.Eval() then - Begin - FFilterParser.EnableWildcardMatching := - not(foNoPartialCompare in FilterOptions); - FFilterParser.CaseInsensitive := foCaseInsensitive in FilterOptions; - Result := FFilterParser.Value; - End; - {$ELSE} - If FFilterExpression <> nil then - Result := FFilterExpression.Evaluate(); - {$ENDIF} - If Assigned(OnFilterRecord) then - OnFilterRecord(Self, Result); - Except - AppHandleException(Self); - End; - RestoreState(SaveState); - End - Else - Result := False; - End; + Result := TRecordBuffer(FCurrentRecBuf); End; -function TRESTDWMemTable.GetBlobData(Field: TField; Buffer: PRESTDWMTMemBuffer - ): TMemBlobData; -Var - vElemSize : Integer; +Function TRESTDWMemDoubleLinkedIndex.GetIsInitialized: boolean; +Begin + Result := (FFirstRecBuf<>nil); +End; + +Function TRESTDWMemDoubleLinkedIndex.GetSpareBuffer: TRecordBuffer; +Begin + Result := Pointer(TRESTDWPtrInt(FLastRecBuf) + FDataset.BufferOffset); +End; + +Function TRESTDWMemDoubleLinkedIndex.GetSpareRecord: TRecordBuffer; +Begin + Result := TRecordBuffer(FLastRecBuf); +End; + +Function TRESTDWMemDoubleLinkedIndex.ScrollBackward: TGetResult; Begin - If frecords.Count > 0 Then + If not assigned(FCurrentRecBuf[IndNr].prior) Then Begin - If frecords.Count > recNo Then - Begin - If Length(frecords[recNo -1].fblobs) > 0 Then - Result := frecords[recNo -1].fblobs[Field.Offset] - Else - Result := fblobs[Field.Offset]; - End - Else - Begin - vElemSize := Length(fblobs); - If (Field.Offset +1) > vElemSize Then - SetLength(fblobs, Field.Offset +1); - Result := fblobs[Field.Offset]; - End; + Result := grBOF; End Else - Result := FBlobs[Field.Offset]; + Begin + Result := grOK; + FCurrentRecBuf := FCurrentRecBuf[IndNr].prior; + End; End; -procedure TRESTDWMemTable.SetBlobData(Field : TField; - Buffer : PRESTDWMTMemBuffer; - Value : TMemBlobData); +Function TRESTDWMemDoubleLinkedIndex.ScrollForward: TGetResult; Begin - If Buffer = PRESTDWMTMemBuffer(ActiveBuffer) then + If (FCurrentRecBuf = FLastRecBuf) or // just opened + (FCurrentRecBuf[IndNr].next = FLastRecBuf) Then + result := grEOF + Else Begin - If State = dsFilter then - Error('Not Editing...'); - If frecords.Count > recNo Then - Begin - If Length(frecords[recNo -1].fblobs) > 0 Then - Begin - frecords[recNo -1].fblobs[Field.Offset] := Value; - If Field.Offset > Length(fblobs) Then - SetLength(fblobs, Field.Offset+1); - fblobs[Field.Offset] := Value; - End - Else - fblobs[Field.Offset] := Value; - End - Else - fblobs[Field.Offset] := Value; + FCurrentRecBuf := FCurrentRecBuf[IndNr].next; + Result := grOK; End; End; -procedure TRESTDWMemTable.CloseBlob(Field: TField); +Function TRESTDWMemDoubleLinkedIndex.GetCurrent: TGetResult; Begin -// If (FRecordPos >= 0) and (FRecordPos < FRecords.Count) and (State = dsEdit) then -// Begin -// SetLength(Records[FRecordPos].FBlobs[Field.Offset], 0); -// SetLength(FBlobs[Field.Offset], 0); -// End - If Length(FBlobs) > Field.Offset +1 Then - SetLength(FBlobs[Field.Offset], 0); + If FFirstRecBuf = FLastRecBuf Then + Result := grError + Else + Begin + Result := grOK; + If FCurrentRecBuf = FLastRecBuf Then + FCurrentRecBuf:=FLastRecBuf[IndNr].prior; + End; End; -function TRESTDWMemTable.CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; +Function TRESTDWMemDoubleLinkedIndex.ScrollFirst: TGetResult; Begin - Result := TRESTDWMTMemBlobStream.Create(Field as TBlobField, Mode); + FCurrentRecBuf:=FFirstRecBuf; + If (FCurrentRecBuf = FLastRecBuf) Then + result := grEOF + Else + result := grOK; End; -Function TRESTDWMemTable.BookmarkValid(aBookmark: TBookmark): Boolean; +Procedure TRESTDWMemDoubleLinkedIndex.ScrollLast; Begin - Result := (aBookmark <> Nil) And - (FActive) And - (FindRecordID({$IFDEF FPC}NativeInt(@aBookmark[0]) - {$ELSE}TRESTDWMTBookmarkData({$IFDEF RTL200_UP}Pointer(@aBookmark[0]) - {$ELSE}aBookmark - {$ENDIF RTL200_UP}^) - {$ENDIF}) <> Nil); + FCurrentRecBuf:=FLastRecBuf; End; -Function TRESTDWMemTable.CompareBookmarks(aBookmark1, aBookmark2: TBookmark): Integer; +Function TRESTDWMemDoubleLinkedIndex.GetRecord(ABookmark: PRESTDWMemBookmark; GetMode: TGetMode): TGetResult; +Var ARecord : PRESTDWMemRecLinkItem; Begin - If (aBookmark1 = nil) and (aBookmark2 = nil) then - Result := 0 - Else If (aBookmark1 <> nil) and (aBookmark2 = nil) then - Result := 1 - Else If (aBookmark1 = nil) and (aBookmark2 <> nil) then - Result := -1 - Else If TRESTDWMTBookmarkData({$IFDEF FPC}NativeInt(@aBookmark1[0]){$ELSE}TRESTDWMTBookmarkData - ({$IFDEF RTL200_UP}Pointer(@aBookmark1[0] - ){$ELSE}aBookmark1{$ENDIF RTL200_UP}^){$ENDIF}) > - TRESTDWMTBookmarkData({$IFDEF FPC}NativeInt(@aBookmark2[0]){$ELSE}TRESTDWMTBookmarkData - ({$IFDEF RTL200_UP}Pointer(@aBookmark2[0] - ){$ELSE}aBookmark2{$ENDIF RTL200_UP}^){$ENDIF}) then - Result := 1 - Else If TRESTDWMTBookmarkData({$IFDEF FPC}NativeInt(@aBookmark1[0]){$ELSE}TRESTDWMTBookmarkData - ({$IFDEF RTL200_UP}Pointer(@aBookmark1[0] - ){$ELSE}aBookmark1{$ENDIF RTL200_UP}^){$ENDIF}) < - TRESTDWMTBookmarkData({$IFDEF FPC}NativeInt(@aBookmark2[0]){$ELSE}TRESTDWMTBookmarkData - ({$IFDEF RTL200_UP}Pointer(@aBookmark2[0] - ){$ELSE}aBookmark2{$ENDIF RTL200_UP}^){$ENDIF}) then - Result := -1 + Result := grOK; + Case GetMode Of + gmPrior: + Begin + If assigned(ABookmark^.BookmarkData) Then + ARecord := ABookmark^.BookmarkData[IndNr].prior + Else + ARecord := nil; + If not assigned(ARecord) Then + Result := grBOF; + End; + gmNext: + Begin + If assigned(ABookmark^.BookmarkData) Then + ARecord := ABookmark^.BookmarkData[IndNr].next + Else + ARecord := FFirstRecBuf; + End; Else - Result := 0; + Result := grError; +End; + + If ARecord = FLastRecBuf Then + Result := grEOF; + // store into BookmarkData pointer to prior/next record + ABookmark^.BookmarkData:=ARecord; End; -{$IFNDEF NEXTGEN} -{$IFDEF RTL240_UP} +Procedure TRESTDWMemDoubleLinkedIndex.SetToFirstRecord; +Begin + FLastRecBuf[IndNr].next:=FFirstRecBuf; + FCurrentRecBuf := FLastRecBuf; +End; -Procedure TRESTDWMemTable.GetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); -var - Bookmark: TBookmark; +Procedure TRESTDWMemDoubleLinkedIndex.SetToLastRecord; Begin - SetLength(Bookmark, SizeOf(TRESTDWMTBookmarkData)); - GetBookmarkData(Buffer, Bookmark); - Move(Bookmark[0], Data^, SizeOf(TRESTDWMTBookmarkData)); + If FLastRecBuf <> FFirstRecBuf Then + FCurrentRecBuf := FLastRecBuf; End; -Procedure TRESTDWMemTable.SetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); +Procedure TRESTDWMemDoubleLinkedIndex.StoreCurrentRecord; Begin - Move(Data^, PMemBookmarkInfo(Buffer + FBookmarkOfs)^.BookmarkData, - SizeOf(TRESTDWMTBookmarkData)); + FStoredRecBuf:=FCurrentRecBuf; End; -{$ENDIF RTL240_UP} -{$ENDIF !NEXTGEN} -procedure TRESTDWMemTable.InternalGotoBookmarkData( - BookmarkData: TRESTDWMTBookmarkData); -var - Rec: TRESTDWMTMemoryRecord; - SavePos: Integer; - Accept: Boolean; +Procedure TRESTDWMemDoubleLinkedIndex.RestoreCurrentRecord; Begin - Rec := FindRecordID(BookmarkData); - If Rec <> nil then - Begin - Accept := True; - SavePos := FRecordPos; - Try - FRecordPos := Rec.Index; - If Filtered then - Accept := RecordFilter; - Finally - If not Accept then - FRecordPos := SavePos; - End; - End; + FCurrentRecBuf:=FStoredRecBuf; End; -procedure TRESTDWMemTable.InternalGotoBookmark(aBookmark: TRESTDWMTBookmark); +Procedure TRESTDWMemDoubleLinkedIndex.DoScrollForward; Begin - InternalGotoBookmarkData(TRESTDWMTBookmarkData({$IFDEF RTL240_UP}Pointer(@aBookmark[0] - ){$ELSE}aBookmark{$ENDIF RTL240_UP}^)); + FCurrentRecBuf := FCurrentRecBuf[IndNr].next; End; -{$IFNDEF NEXTGEN} -{$IFDEF RTL240_UP} -Procedure TRESTDWMemTable.InternalGotoBookmark(Bookmark: Pointer); +Procedure TRESTDWMemDoubleLinkedIndex.StoreCurrentRecIntoBookmark(Const ABookmark: PRESTDWMemBookmark); Begin - InternalGotoBookmarkData(TRESTDWMTBookmarkData(Bookmark^)); + ABookmark^.BookmarkData:=FCurrentRecBuf; End; -{$ENDIF RTL240_UP} -{$ENDIF !NEXTGEN} -procedure TRESTDWMemTable.InternalFirst; -Var - PActualRecord : PRESTDWMTMemBuffer; - Data : {$IFDEF FPC}PAnsiChar{$ELSE}PByte{$ENDIF}; +Procedure TRESTDWMemDoubleLinkedIndex.StoreSpareRecIntoBookmark( + Const ABookmark: PRESTDWMemBookmark); Begin - FRecordPos := -1; - FRecordFilterPos := 0; - aFilterRecs := FRecordFilterPos; - If RecordCount > 0 Then - Begin - GetActiveRecBuf(PActualRecord); - CalculateFields({$IFDEF NEXTGEN}TRecBuf{$ELSE}TRecordBuffer{$ENDIF}(PActualRecord)); - End; + ABookmark^.BookmarkData:=FLastRecBuf; End; -procedure TRESTDWMemTable.InternalLast; +Procedure TRESTDWMemDoubleLinkedIndex.GotoBookmark(Const ABookmark : PRESTDWMemBookmark); Begin - FRecordPos := FRecords.Count; - FRecordFilterPos := RecordCount; - aFilterRecs := FRecordFilterPos; + FCurrentRecBuf := ABookmark^.BookmarkData; End; -function TRESTDWMemTable.GetDataset: TDataset; +Function TRESTDWMemDoubleLinkedIndex.CompareBookmarks(Const ABookmark1,ABookmark2: PRESTDWMemBookmark): integer; +Var ARecord1, ARecord2 : PRESTDWMemRecLinkItem; Begin - Result := TDataset(Self); + // valid bookmarks expected + // estimate result using memory addresses of records + Result := ABookmark1^.BookmarkData - ABookmark2^.BookmarkData; + If Result = 0 Then + Exit + Else If Result < 0 Then + Begin + Result := -1; + ARecord1 := ABookmark1^.BookmarkData; + ARecord2 := ABookmark2^.BookmarkData; + End + Else + Begin + Result := +1; + ARecord1 := ABookmark2^.BookmarkData; + ARecord2 := ABookmark1^.BookmarkData; + End; + // if we need relative position of records with given bookmarks we must + // traverse through index until we reach lower bookmark or 1st record + While assigned(ARecord2) and (ARecord2 <> ARecord1) and (ARecord2 <> FFirstRecBuf) Do + ARecord2 := ARecord2[IndNr].prior; + // if we found lower bookmark as first, then estimated position is correct + If ARecord1 <> ARecord2 Then + Result := -Result; End; -procedure TRESTDWMemTable.ClearIndexes; -Var - i : integer; +Function TRESTDWMemDoubleLinkedIndex.SameBookmarks(Const ABookmark1, ABookmark2: PRESTDWMemBookmark): boolean; Begin - CheckInactive; - For I:=0 to FIndexes.Count-1 do - RESTDWIndexDefs[i].Clearindex; + Result := Assigned(ABookmark1) and Assigned(ABookmark2) and (ABookmark1^.BookmarkData = ABookmark2^.BookmarkData); End; -function TRESTDWMemTable.GetCalcFieldLen(FieldType: TFieldType; Size: Word - ): Word; +Procedure TRESTDWMemDoubleLinkedIndex.InitialiseIndex; Begin - Result := CalcFieldLen(FieldType, Size); + // Do nothing End; -function TRESTDWMemTable.GetBlobRec(Field: TField; Rec: TRESTDWMTMemoryRecord - ): TMemBlobData; +Function TRESTDWMemDoubleLinkedIndex.CanScrollForward: Boolean; Begin - Result := PMemBlobArray(Rec.FBlobs)^[Field.Offset]; + If (FCurrentRecBuf[IndNr].next = FLastRecBuf) Then + Result := False + Else + Result := True; End; -function TRESTDWMemTable.GetOffSets(aField: TField): Word; +Procedure TRESTDWMemDoubleLinkedIndex.InitialiseSpareRecord(Const ASpareRecord : TRecordBuffer); Begin - Result := FOffsets[FindFieldIndex(aField)];//FOffsets[index]; + FFirstRecBuf := pointer(ASpareRecord); + FLastRecBuf := FFirstRecBuf; + FLastRecBuf[IndNr].prior:=nil; + FLastRecBuf[IndNr].next:=FLastRecBuf; + FCurrentRecBuf := FLastRecBuf; End; -function TRESTDWMemTable.GetOffSets(Index: Integer): Word; +Procedure TRESTDWMemDoubleLinkedIndex.ReleaseSpareRecord; Begin - Result := FOffsets[index]; + FFirstRecBuf:= nil; End; -function TRESTDWMemTable.GetOffSetsBlobs: Word; +Function TRESTDWMemDoubleLinkedIndex.GetRecNo: Longint; +Var ARecord : PRESTDWMemRecLinkItem; Begin - Result := FBlobOfs; + ARecord := FCurrentRecBuf; + Result := 1; + While ARecord <> FFirstRecBuf Do + Begin + inc(Result); + ARecord := ARecord[IndNr].prior; + End; End; -function TRESTDWMemTable.DataTypeIsBlobTypes(datatype: TFieldType): Boolean; +Procedure TRESTDWMemDoubleLinkedIndex.SetRecNo(ARecNo: Longint); +Var ARecord : PRESTDWMemRecLinkItem; Begin - Result := datatype in ftBlobTypes; + ARecord := FFirstRecBuf; + While (ARecNo > 1) and (ARecord <> FLastRecBuf) Do + Begin + dec(ARecNo); + ARecord := ARecord[IndNr].next; + End; + FCurrentRecBuf := ARecord; End; -function TRESTDWMemTable.DataTypeSuported(datatype: TFieldType): Boolean; +Procedure TRESTDWMemDoubleLinkedIndex.BeginUpdate; Begin - Result := datatype in ftSupported; + If FCurrentRecBuf = FLastRecBuf Then + FCursOnFirstRec := True + Else + FCursOnFirstRec := False; End; -{$IFNDEF FPC} -{$IFDEF RESTDWVCL} -// Delphi 2006+ has support for DWWideString -Procedure TRESTDWMemTable.DataConvert(Field: TField; Source, Dest: Pointer; - ToNative: Boolean); +Procedure TRESTDWMemDoubleLinkedIndex.AddRecord; +Var ARecord: TRecordBuffer; Begin - If Field.datatype = ftWideString then - Begin - If ToNative then - Begin - Word(Dest^) := Length(PWideString(Source)^) * SizeOf(WideChar); - Move(PWideChar(Source^)^, (PWideChar(Dest) + 1)^, Word(Dest^)); - End - Else - SetString(WideString(Dest^), PWideChar(PWideChar(Source) + 1), - Word(Source^) div SizeOf(WideChar)); - End - Else - inherited DataConvert(Field, Source, Dest, ToNative); + ARecord := FDataset.IntAllocRecordBuffer; + FLastRecBuf[IndNr].next := pointer(ARecord); + FLastRecBuf[IndNr].next[IndNr].prior := FLastRecBuf; + + FLastRecBuf := FLastRecBuf[IndNr].next; End; -{$ENDIF ~COMPILER10_UP} -{$ELSE} -procedure TRESTDWMemTable.DataConvert(Field: TField; Source, Dest: Pointer; - ToNative: Boolean); +Procedure TRESTDWMemDoubleLinkedIndex.InsertRecordBeforeCurrentRecord(Const ARecord: TRecordBuffer); +Var ANewRecord : PRESTDWMemRecLinkItem; Begin - If Field.datatype = ftFixedWideChar then + ANewRecord:=PRESTDWMemRecLinkItem(ARecord); + ANewRecord[IndNr].prior:=FCurrentRecBuf[IndNr].prior; + ANewRecord[IndNr].Next:=FCurrentRecBuf; + + If FCurrentRecBuf=FFirstRecBuf Then Begin - StrCopy(PWideChar(Dest), PWideChar(Source)); + FFirstRecBuf:=ANewRecord; + ANewRecord[IndNr].prior:=nil; End - Else - inherited DataConvert(Field, Source, Dest, ToNative); + Else + ANewRecord[IndNr].Prior[IndNr].next:=ANewRecord; + ANewRecord[IndNr].next[IndNr].prior:=ANewRecord; End; -{$ENDIF} -function TRESTDWMemTable.GetIndexFieldNames: String; -Var - i, - p : Integer; - s : String; - IndexBuf : TRESTDWIndex; -Begin - Result := FIndexFieldNames; - IndexBuf := GetCurrentIndexBuf; - If (IndexBuf = Nil) then - Exit; - Result:=''; - For I := 1 to WordCount(IndexBuf.FieldsName, [Limiter]) Do +Procedure TRESTDWMemDoubleLinkedIndex.RemoveRecordFromIndex(Const ABookmark : TRESTDWMemBookmark); +Var ARecord : PRESTDWMemRecLinkItem; +Begin + ARecord := ABookmark.BookmarkData; + If ARecord = FCurrentRecBuf Then + DoScrollForward; + If ARecord <> FFirstRecBuf Then + ARecord[IndNr].prior[IndNr].next := ARecord[IndNr].next + Else Begin - s := ExtractDelimited(i, IndexBuf.FieldsName, [Limiter]); - p := Pos(s, IndexBuf.DescFields); - If p > 0 Then - s := s + Desc; - Result := Result + Limiter + s; + FFirstRecBuf := ARecord[IndNr].next; + FLastRecBuf[IndNr].next := FFirstRecBuf; End; - If (Length(Result) > 0) And - (Result[1] = Limiter) Then - system.Delete(Result, 1, 1); + ARecord[IndNr].next[IndNr].prior := ARecord[IndNr].prior; End; -function TRESTDWMemTable.DefaultIndex: TRESTDWDatasetIndex; -Begin - Result := FDefaultIndex; - If Result = Nil then - If FIndexes <> Nil Then - Result:=FIndexes.FindIndex(SDefaultIndex); -end; - -function TRESTDWMemTable.DefaultBufferIndex: TRESTDWIndex; +Procedure TRESTDWMemDoubleLinkedIndex.OrderCurrentRecord; +Var ARecord: PRESTDWMemRecLinkItem; + ABookmark: TRESTDWMemBookmark; Begin - If DefaultIndex <> Nil Then - Result := DefaultIndex.BufferIndex + // all records except current are already sorted + // check prior records + ARecord := FCurrentRecBuf; + Repeat + ARecord := ARecord[IndNr].prior; + Until not assigned(ARecord) or (IndexCompareRecords(ARecord, FCurrentRecBuf, DBCompareStruct) <= 0); + If assigned(ARecord) Then + ARecord := ARecord[IndNr].next Else - Result := Nil; + ARecord := FFirstRecBuf; + If ARecord = FCurrentRecBuf Then + Begin + // prior record is less equal than current + // check next records + Repeat + ARecord := ARecord[IndNr].next; + Until (ARecord=FLastRecBuf) or (IndexCompareRecords(ARecord, FCurrentRecBuf, DBCompareStruct) >= 0); + If ARecord = FCurrentRecBuf[IndNr].next Then + Exit; // current record is on proper position + End; + StoreCurrentRecIntoBookmark(@ABookmark); + RemoveRecordFromIndex(ABookmark); + FCurrentRecBuf := ARecord; + InsertRecordBeforeCurrentRecord(TRecordBuffer(ABookmark.BookmarkData)); + GotoBookmark(@ABookmark); End; -function TRESTDWMemTable.Fetch: Boolean; +Procedure TRESTDWMemDoubleLinkedIndex.EndUpdate; Begin - Result := FFetch; + FLastRecBuf[IndNr].next := FFirstRecBuf; + If FCursOnFirstRec Then + FCurrentRecBuf:=FLastRecBuf; End; -Function DBCompareText(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; -Begin - If [loCaseInsensitive,loPartialKey] = options Then - Result := AnsiStrLIComp(pchar(subValue),pchar(aValue),length(pchar(subValue))) - Else If [loPartialKey] = options Then - Result := AnsiStrLComp(pchar(subValue),pchar(aValue),length(pchar(subValue))) - Else If [loCaseInsensitive] = options then - Result := AnsiCompareText(pchar(subValue),pchar(aValue)) - Else - Result := AnsiCompareStr(pchar(subValue),pchar(aValue)); -end; - -Function DBCompareWideText(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; +Procedure TRESTDWCustomMemTable.CurrentRecordToBuffer(Buffer: TRecordBuffer); +Var ABookMark : PRESTDWMemBookmark; Begin - If [loCaseInsensitive, loPartialKey] = options Then - Result := WideCompareText(pwidechar(subValue), LeftStr(pwidechar(aValue), Length(pwidechar(subValue)))) - Else If [loPartialKey] = options Then - Result := WideCompareStr(pwidechar(subValue),LeftStr(pwidechar(aValue), Length(pwidechar(subValue)))) - Else If [loCaseInsensitive] = options Then - Result := WideCompareText(pwidechar(subValue),pwidechar(aValue)) - Else - Result := WideCompareStr(pwidechar(subValue),pwidechar(aValue)); -End; + With CurrentIndexBuf Do + Begin + move(CurrentBuffer^,buffer^,FRecordSize); + ABookMark:=PRESTDWMemBookmark(Buffer + FRecordSize); + ABookmark^.BookmarkFlag:=bfCurrent; + StoreCurrentRecIntoBookmark(ABookMark); + End; -Function DBCompareByte(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; -Begin - Result := PByte(subValue)^-PByte(aValue)^; + GetCalcFields(Buffer); End; -Function DBCompareSmallInt(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; +Procedure TRESTDWCustomMemTable.SetBufUniDirectional(Const AValue: boolean); Begin - Result := PSmallInt(subValue)^-PSmallInt(aValue)^; + CheckInactive; + If (AValue<>IsUniDirectional) Then + Begin + SetUniDirectional(AValue); + ClearIndexes; + FPacketRecords := 1; // temporary + End; End; -Function DBCompareInt(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; +Function TRESTDWCustomMemTable.DefaultIndex: TRESTDWMemTableIndex; Begin - Result := PInteger(subValue)^-PInteger(aValue)^; + Result:=FDefaultIndex; + If Result=Nil Then + Result:=FIndexes.FindIndex(SDefaultIndex); End; -Function DBCompareLargeInt(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; +Function TRESTDWCustomMemTable.DefaultBufferIndex: TRESTDWMemInternalIndex; Begin - // A simple subtraction doesn't work, since it could be that the result - // doesn't fit into a LargeInt - If PInt64(subValue)^ < PInt64(aValue)^ Then - Result := -1 - Else If PInt64(subValue)^ > PInt64(aValue)^ Then - Result := 1 + If DefaultIndex <> Nil Then + Result:=DefaultIndex.BufferIndex Else - Result := 0; + Result:=Nil; End; -Function DBCompareWord(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; +Procedure TRESTDWCustomMemTable.SetReadOnly(AValue: Boolean); Begin - Result := PWord(subValue)^-PWord(aValue)^; + FReadOnly:=AValue; End; -Function DBCompareQWord(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; +Function TRESTDWCustomMemTable.GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode; DoCheck: Boolean): TGetResult; + +Var Acceptable : Boolean; + SavedState : TDataSetState; + Begin -// // A simple subtraction doesn't work, since it could be that the result -// // doesn't fit into a LargeInt -// If PQWord(subValue)^ < PQWord(aValue)^ Then -// Result := -1 -// Else If PQWord(subValue)^ > PQWord(aValue)^ Then -// Result := 1 -// Else -// Result := 0; - Raise Exception.Create('Unsupported QWord Type...'); + Result := grOK; + With CurrentIndexBuf Do + Repeat + Acceptable := True; + Case GetMode Of + gmPrior : Result := ScrollBackward; + gmCurrent : Result := GetCurrent; + gmNext : Begin + If not CanScrollForward and (getnextpacket = 0) Then + Result := grEOF + Else + Begin + Result := grOK; + DoScrollForward; + End; End; + End; -Function DBCompareDouble(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; -Begin - // A simple subtraction doesn't work, since it could be that the result - // doesn't fit into a LargeInt - If PDouble(subValue)^ < PDouble(aValue)^ Then - Result := -1 - Else If PDouble(subValue)^ > PDouble(aValue)^ Then - Result := 1 - Else - Result := 0; + If Result = grOK Then + Begin + CurrentRecordToBuffer(Buffer); + + If Filtered Then + Begin + FFilterBuffer := Buffer; + SavedState := SetTempState(dsFilter); + DoFilterRecord(Acceptable); + If (GetMode = gmCurrent) and not Acceptable Then + Begin + Acceptable := True; + Result := grError; + End; + RestoreState(SavedState); + End; + End + Else If (Result = grError) and DoCheck Then + DatabaseError('No record'); + Until Acceptable; End; -Function DBCompareBCD(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; -Begin - Result := BCDCompare(PBCD(subValue)^, PBCD(aValue)^); -end; +Function TRESTDWCustomMemTable.GetActiveRecordUpdateBuffer : boolean; + +Var ABookmark : TRESTDWMemBookmark; -Function DBCompareBytes(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; Begin - Result := CompareByte(subValue^, aValue^, size); + GetBookmarkData(TRecordBuffer(ActiveBuffer),@ABookmark); + result := GetRecordUpdateBufferCached(ABookmark); End; -function DBCompareVarBytes(subValue, aValue: pointer; size: integer; options: TLocateOptions): LargeInt; -Var - len1, - len2 : LongInt; +Function TRESTDWCustomMemTable.GetCurrentIndexBuf: TRESTDWMemInternalIndex; Begin - len1 := PWord(subValue)^; - len2 := PWord(aValue)^; - subValue := Pointer(Integer(subValue) + Sizeof(Word)); - aValue := Pointer(Integer(aValue) + Sizeof(Word)); -// Inc(subValue, Sizeof(Word)); -// Inc(aValue, Sizeof(Word)); - If len1 > len2 then - Result := CompareByte(subValue^, aValue^, len2) + If Assigned(FCurrentIndexDef) Then + Result:=FCurrentIndexDef.BufferIndex Else - Result := CompareByte(subValue^, aValue^, len1); - If Result = 0 then - Result := len1 - len2; + Result:=Nil; End; -function TRESTDWMemTable.BufferOffset: Integer; +Function TRESTDWCustomMemTable.GetBufIndex(Aindex : Integer): TRESTDWMemInternalIndex; Begin - // Returns the offset of data buffer in bufdataset record - Result := Sizeof(TRESTDWRecLinkItem) * FMaxIndexesCount; + Result:=FIndexes.BufIndexes[AIndex] End; -procedure TRESTDWMemTable.ProcessFieldsToCompareStruct(const AFields, - ADescFields, ACInsFields: TList; const AIndexOptions: TIndexOptions; - const ALocateOptions: TLocateOptions; out ACompareStruct: TDBCompareStruct); -Var - i, - vDataSize : Integer; - AField : TField; - ACompareRec : TDBCompareRec; +Function TRESTDWCustomMemTable.GetBufIndexDef(Aindex : Integer): TRESTDWMemTableIndex; +Begin + Result:=FIndexes.BufIndexdefs[AIndex] +End; + +Procedure TRESTDWCustomMemTable.ProcessFieldsToCompareStruct(Const AFields, ADescFields, ACInsFields: TList; + Const AIndexOptions: TIndexOptions; Const ALocateOptions: TLocateOptions; out ACompareStruct: TRESTDWMemCompareStruct); +Var i: integer; + AField: TField; + ACompareRec: TRESTDWMemCompareRec; Begin - vDataSize := 0; SetLength(ACompareStruct, AFields.Count); - For i := 0 To high(ACompareStruct) Do + For i:=0 To high(ACompareStruct) Do Begin AField := TField(AFields[i]); - Case AField.DataType of - ftString, - ftFixedChar, - ftGuid : ACompareRec.CompareFunc := @DBCompareText; - ftWideString - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - , ftFixedWideChar - {$IFEND} - {$ELSE} - , ftFixedWideChar - {$ENDIF FPC} : ACompareRec.CompareFunc := @DBCompareWideText; - ftSmallint : ACompareRec.CompareFunc := @DBCompareSmallInt; - ftInteger, - ftAutoInc : ACompareRec.CompareFunc := @DBCompareInt; - ftLargeint, - ftBCD : ACompareRec.CompareFunc := @DBCompareLargeInt; - ftWord : ACompareRec.CompareFunc := @DBCompareWord; - ftBoolean : ACompareRec.CompareFunc := @DBCompareByte; - ftDate, - ftTime, - ftDateTime, - ftFloat, - ftCurrency : ACompareRec.CompareFunc := @DBCompareDouble; - ftFmtBCD : ACompareRec.CompareFunc := @DBCompareBCD; - ftVarBytes : ACompareRec.CompareFunc := @DBCompareVarBytes; - ftBytes : ACompareRec.CompareFunc := @DBCompareBytes; - Else - DatabaseErrorFmt(SErrIndexBasedOnInvField, [AField.FieldName, - Fieldtypenames[AField.DataType]]); - End; - ACompareRec.Off := FOffsets[FindFieldIndex(aField)]; - ACompareRec.NullBOff := BufferOffset; - ACompareRec.FieldInd := AField.FieldNo-1; - CalcDataSize(AField, vDataSize); - ACompareRec.Size := vDataSize; -// GetFieldSize(FieldDefs[ACompareRec.FieldInd]); - ACompareRec.Desc := ixDescending in AIndexOptions; - If Assigned(ADescFields) Then - ACompareRec.Desc := ACompareRec.Desc or (ADescFields.IndexOf(AField)>-1); - ACompareRec.Options := ALocateOptions; - If Assigned(ACInsFields) And - (ACInsFields.IndexOf(AField)>-1) then - ACompareRec.Options := ACompareRec.Options + [loCaseInsensitive]; - ACompareStruct[i] := ACompareRec; + + Case AField.DataType Of + ftString, ftFixedChar, ftGuid: + ACompareRec.CompareFunc := @DBCompareText; + ftWideString, ftFixedWideChar: + ACompareRec.CompareFunc := @DBCompareWideText; + ftSmallint: + ACompareRec.CompareFunc := @DBCompareSmallInt; + ftInteger, ftAutoInc: + ACompareRec.CompareFunc := @DBCompareInt; + ftLargeint, ftBCD: + ACompareRec.CompareFunc := @DBCompareLargeInt; + ftWord: + ACompareRec.CompareFunc := @DBCompareWord; + ftBoolean: + ACompareRec.CompareFunc := @DBCompareByte; + ftDate, ftTime, ftDateTime, + ftFloat, ftCurrency: + ACompareRec.CompareFunc := @DBCompareDouble; +{$IFDEF DELPHI2010UP} + ftSingle: + ACompareRec.CompareFunc := @DBCompareSingle; + ftExtended: + ACompareRec.CompareFunc := @DBCompareExtended; +{$ENDIF} + ftFmtBCD: + ACompareRec.CompareFunc := @DBCompareBCD; + ftVarBytes: + ACompareRec.CompareFunc := @DBCompareVarBytes; + ftBytes: + ACompareRec.CompareFunc := @DBCompareBytes; + Else + DatabaseErrorFmt(SErrIndexBasedOnInvField, [AField.FieldName,Fieldtypenames[AField.DataType]]); End; -End; -Function GetFieldIsNull(NullMask : pbyte; - x : longint) : boolean; //inline; -Begin - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - Result := ord(NullMask[x Div 8]) And (1 Shl (x Mod 8)) > 0 - {$ELSE} - Result := ord(TRESTDWBytes(NullMask)[x Div 8]) And (1 Shl (x Mod 8)) > 0 - {$IFEND} - {$ELSE} - Result := ord(NullMask[x Div 8]) And (1 Shl (x Mod 8)) > 0 - {$ENDIF} + ACompareRec.Off:=BufferOffset + FFieldBufPositions[AField.FieldNo-1]; + ACompareRec.NullBOff:=BufferOffset; + + ACompareRec.FieldInd:=AField.FieldNo-1; + ACompareRec.Size:=GetFieldSize(FieldDefs[ACompareRec.FieldInd]); + + ACompareRec.Desc := ixDescending in AIndexOptions; + If assigned(ADescFields) Then + ACompareRec.Desc := ACompareRec.Desc or (ADescFields.IndexOf(AField)>-1); + + ACompareRec.Options := ALocateOptions; + If (ixCaseInsensitive in AIndexOptions) or + (assigned(ACInsFields) and (ACInsFields.IndexOf(AField)>-1)) Then + ACompareRec.Options := ACompareRec.Options + [loCaseInsensitive]; + + ACompareStruct[i] := ACompareRec; End; +End; + + +Procedure TRESTDWCustomMemTable.InitDefaultIndexes; + +{ + This procedure makes sure there are 2 default indexes: + DEFAULT_ORDER, which is simply the order in which the server records arrived. + CUSTOM_ORDER, which is an internal index to accomodate the 'IndexFieldNames' property. +} -Function IndexCompareRecords(Rec1, - Rec2 : Pointer; - ADBCompareRecs : TDBCompareStruct) : LargeInt; Var - IndexFieldNr : Integer; - IsNull1, - IsNull2 : Boolean; + FD,FC : TRESTDWMemTableIndex; + Begin - For IndexFieldNr := 0 To length(ADBCompareRecs)-1 Do + // Default index + FD:=FIndexes.FindIndex(SDefaultIndex); + If (FD=Nil) Then + Begin + FD:=InternalAddIndex(SDefaultIndex,'',[],'',''); + FD.IndexType:=itDefault; + FD.FDiscardOnClose:=True; + End +// Not sure about this. For the moment we leave it in comment +{ else if FD.BufferIndex=Nil then + InternalCreateIndex(FD)} + ; + + FCurrentIndexDef:=FD; + // Custom index + If not IsUniDirectional Then Begin - With ADBCompareRecs[IndexFieldNr] Do + FC:=Findexes.FindIndex(SCustomIndex); + If (FC=Nil) Then Begin - IsNull1 := GetFieldIsNull(pbyte(Integer(rec1) + NullBOff), FieldInd); - IsNull2 := GetFieldIsNull(pbyte(Integer(rec2) + NullBOff), FieldInd); - If IsNull1 And IsNull2 Then - Result := 0 - Else If IsNull1 then - Result := -1 - Else if IsNull2 then - Result := 1 - Else - Result := CompareFunc(Pointer(Integer(Rec1) + Off), Pointer(Integer(Rec2) + Off), Size, Options); - If Result <> 0 Then - Begin - If Desc Then - Result := -Result; - Break; - End; - End; + FC:=InternalAddIndex(SCustomIndex,'',[],'',''); + FC.IndexType:=itCustom; + FC.FDiscardOnClose:=True; + End + // Not sure about this. For the moment we leave it in comment +{ else if FD.BufferIndex=Nil then + InternalCreateIndex(FD)} + ; End; + BookmarkSize:=CurrentIndexBuf.BookmarkSize; End; -procedure TRESTDWMemTable.BuildIndex(AIndex: TRESTDWIndex); +Procedure TRESTDWCustomMemTable.AddIndex(Const AName, AFields : string; AOptions : TIndexOptions; Const ADescFields: string = ''; + Const ACaseInsFields: string = ''); + Var - PCurRecLinkItem : PRESTDWRecLinkItem; - p,l,q : PRESTDWRecLinkItem; - i,k,psize,qsize, - myIdx,defIdx, - MergeAmount : Integer; - PlaceQRec : Boolean; - IndexFields, - DescIndexFields, - CInsIndexFields : TList; - Index0, - DblLinkIndex : TDoubleLinkedBufIndex; - Procedure PlaceNewRec(Var e : PRESTDWRecLinkItem; - Var esize : Integer); - Begin - If DblLinkIndex.FFirstRecBuf = Nil Then - Begin - DblLinkIndex.FFirstRecBuf := e; - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - e[myIdx].prior := Nil; - {$ELSE} - e.prior := Nil; - {$IFEND} - {$ELSE} - e[myIdx].prior := Nil; - {$ENDIF} - l := e; - End - Else - Begin - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - l[myIdx].next := e; - e[myIdx].prior := l; - {$ELSE} - l.next := e; - e.prior := l; - {$IFEND} - {$ELSE} - l[myIdx].next := e; - e[myIdx].prior := l; - {$ENDIF} - l := e; - End; - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - e := e[myIdx].next; - {$ELSE} - e := e.next; - {$IFEND} - {$ELSE} - e := e[myIdx].next; - {$ENDIF} - dec(esize); - End; + F : TRESTDWMemTableIndex; + D : TIndexDef; + I : Integer; + Begin - // Build the DBCompareStructure - // One AS is enough, and makes debugging easier. - DblLinkIndex := (AIndex as TDoubleLinkedBufIndex); - Index0 := DefaultIndex.BufferIndex as TDoubleLinkedBufIndex; - myIdx := DblLinkIndex.IndNr; - defIdx := Index0.IndNr; - With DblLinkIndex Do - Begin - IndexFields := TList.Create; - DescIndexFields := TList.Create; - CInsIndexFields := TList.Create; - try - GetFieldList(IndexFields,FieldsName); - GetFieldList(DescIndexFields,DescFields); - GetFieldList(CInsIndexFields,CaseinsFields); - If IndexFields.Count = 0 Then - DatabaseErrorFmt(SNoIndexFieldNameGiven,[DblLinkIndex.Name],Self); - ProcessFieldsToCompareStruct(IndexFields, DescIndexFields, CInsIndexFields, Options, [], DBCompareStruct); - Finally - CInsIndexFields.Free; - DescIndexFields.Free; - IndexFields.Free; - End; - End; - // This simply copies the index... - PCurRecLinkItem := Index0.FFirstRecBuf; - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - PCurRecLinkItem[myIdx].next := PCurRecLinkItem[defIdx].next; - PCurRecLinkItem[myIdx].prior := PCurRecLinkItem[defIdx].prior; - {$ELSE} - //TODO XyberX - PCurRecLinkItem.next := DblLinkIndex.FFirstRecBuf.next; - PCurRecLinkItem.prior := DblLinkIndex.FFirstRecBuf.prior; - {$IFEND} - {$ELSE} - PCurRecLinkItem[myIdx].next := PCurRecLinkItem[defIdx].next; - PCurRecLinkItem[myIdx].prior := PCurRecLinkItem[defIdx].prior; - {$ENDIF} - If PCurRecLinkItem <> Index0.FLastRecBuf Then + CheckBiDirectional; + If (AFields='') Then + DatabaseError(SNoIndexFieldNameGiven,Self); + If Active Then Begin - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - While PCurRecLinkItem[defIdx].next <> Index0.FLastRecBuf do - Begin - PCurRecLinkItem:=PCurRecLinkItem[defIdx].next; - PCurRecLinkItem[myIdx].next := PCurRecLinkItem[defIdx].next; - PCurRecLinkItem[myIdx].prior := PCurRecLinkItem[defIdx].prior; - End; - {$ELSE} - While PCurRecLinkItem.next <> Index0.FLastRecBuf do - Begin - //TODO XyberX - PCurRecLinkItem := PCurRecLinkItem.next; - PCurRecLinkItem.next := Index0.FLastRecBuf.next; - PCurRecLinkItem.prior := Index0.FLastRecBuf.prior; - End; - {$IFEND} - {$ELSE} - While PCurRecLinkItem[defIdx].next <> Index0.FLastRecBuf do - Begin - PCurRecLinkItem:=PCurRecLinkItem[defIdx].next; - PCurRecLinkItem[myIdx].next := PCurRecLinkItem[defIdx].next; - PCurRecLinkItem[myIdx].prior := PCurRecLinkItem[defIdx].prior; - End; - {$ENDIF} - End - Else // Empty dataset - Exit; - // Set FirstRecBuf and FCurrentRecBuf - DblLinkIndex.FFirstRecBuf:=Index0.FFirstRecBuf; - DblLinkIndex.FCurrentRecBuf:=DblLinkIndex.FFirstRecBuf; - // Link in the FLastRecBuf that belongs to this index - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - PCurRecLinkItem[myIdx].next:=DblLinkIndex.FLastRecBuf; - DblLinkIndex.FLastRecBuf[myIdx].prior:=PCurRecLinkItem; - {$ELSE} - //TODO XyberX - PCurRecLinkItem.next:=DblLinkIndex.FLastRecBuf; - DblLinkIndex.FLastRecBuf.prior:=PCurRecLinkItem; - {$IFEND} - {$ELSE} - PCurRecLinkItem[myIdx].next:=DblLinkIndex.FLastRecBuf; - DblLinkIndex.FLastRecBuf[myIdx].prior:=PCurRecLinkItem; - {$ENDIF} - // Mergesort. Used the algorithm as described here by Simon Tatham - // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html - // The comments in the code are from this website. - // In each pass, we are merging lists of size K into lists of size 2K. - // (Initially K equals 1.) - k := 1; - Repeat - // So we start by pointing a temporary pointer p at the head of the list, - // and also preparing an empty list L which we will add elements to the end - // of as we finish dealing with them. - p := DblLinkIndex.FFirstRecBuf; - DblLinkIndex.FFirstRecBuf := nil; - q := p; - MergeAmount := 0; - // Then: - // * If p is null, terminate this pass. - While p <> DblLinkIndex.FLastRecBuf Do - Begin - // * Otherwise, there is at least one element in the next pair of length-K - // lists, so increment the number of merges performed in this pass. - Inc(MergeAmount); - // * Point another temporary pointer, q, at the same place as p. Step q along - // the list by K places, or until the end of the list, whichever comes - // first. Let psize be the number of elements you managed to step q past. - i := 0; - While (iDblLinkIndex.FLastRecBuf) Do - Begin - inc(i); - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - q := q[myIDx].next; - {$ELSE} - //TODO XyberX - q := q.next; - {$IFEND} - {$ELSE} - q := q[myIDx].next; - {$ENDIF} - End; - psize := i; - // * Let qsize equal K. Now we need to merge a list starting at p, of length - // psize, with a list starting at q of length at most qsize. - qsize := k; - // * So, as long as either the p-list is non-empty (psize > 0) or the q-list - // is non-empty (qsize > 0 and q points to something non-null): - While (psize > 0) Or - ((qsize > 0) And - (q <> DblLinkIndex.FLastRecBuf)) Do - Begin - // * Choose which list to take the next element from. If either list - // is empty, we must choose from the other one. (By assumption, at - // least one is non-empty at this point.) If both lists are - // non-empty, compare the first element of each and choose the lower - // one. If the first elements compare equal, choose from the p-list. - // (This ensures that any two elements which compare equal are never - // swapped, so stability is guaranteed.) - If (psize = 0) Then - PlaceQRec := true - Else If (qsize = 0) Or - (q = DblLinkIndex.FLastRecBuf) Then - PlaceQRec := False - Else If IndexCompareRecords(p,q,DblLinkIndex.DBCompareStruct) <= 0 Then - PlaceQRec := False - Else - PlaceQRec := True; - // * Remove that element, e, from the start of its list, by advancing - // p or q to the next element along, and decrementing psize or qsize. - // * Add e to the end of the list L we are building up. - If PlaceQRec Then - PlaceNewRec(q, qsize) - Else - PlaceNewRec(p, psize); - End; - // * Now we have advanced p until it is where q started out, and we have - // advanced q until it is pointing at the next pair of length-K lists to - // merge. So set p to the value of q, and go back to the start of this loop. - p := q; - End; - // As soon as a pass like this is performed and only needs to do one merge, the - // algorithm terminates, and the output list L is sorted. Otherwise, double the - // value of K, and go back to the beginning. - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - l[myIdx].next:=DblLinkIndex.FLastRecBuf; - {$ELSE} - //TODO XyberX - l.next:=DblLinkIndex.FLastRecBuf; - {$IFEND} - {$ELSE} - l[myIdx].next:=DblLinkIndex.FLastRecBuf; - {$ENDIF} - k:=k*2; - Until MergeAmount = 1; - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - DblLinkIndex.FLastRecBuf[myIdx].next:=DblLinkIndex.FFirstRecBuf; - DblLinkIndex.FLastRecBuf[myIdx].prior:=l; - {$ELSE} - //TODO XyberX - DblLinkIndex.FLastRecBuf.next := DblLinkIndex.FFirstRecBuf; - DblLinkIndex.FLastRecBuf.prior := l; - {$IFEND} - {$ELSE} - DblLinkIndex.FLastRecBuf[myIdx].next := DblLinkIndex.FFirstRecBuf; - DblLinkIndex.FLastRecBuf[myIdx].prior := l; - {$ENDIF} + I:=FRuntimeIndexes.IndexOf(AName); + If I=-1 Then + Begin + FRuntimeIndexes.Add(AName,AFields,AOptions); + D:=FRuntimeIndexes[FRuntimeIndexes.Count-1]; + End + Else + D:=FRuntimeIndexes[I]; + D.Name:=AName; + D.Fields:=AFields; + D.Options:=AOptions; + D.DescFields:=ADescFields; + Exit; + End; + // If not all packets are fetched, you can not sort properly. + FPacketRecords:=-1; + F:=InternalAddIndex(AName,AFields,AOptions,ADescFields,ACaseInsFields); + F.FDiscardOnClose:=False; End; -procedure TRESTDWMemTable.BuildIndexes; +Function TRESTDWCustomMemTable.InternalAddIndex(Const AName, AFields : string; AOptions : TIndexOptions; Const ADescFields: string; + Const ACaseInsFields: string) : TRESTDWMemTableIndex; + Var - i : Integer; + F : TRESTDWMemTableIndex; + Begin - For i := 0 To FIndexes.Count -1 Do - If RESTDWIndexDefs[i].MustBuild(FCurrentIndexDef) Then - If Assigned(RESTDWIndexes[i]) Then - BuildIndex(RESTDWIndexes[i]) - Else If RESTDWIndexDefs[i].Fields <> '' Then - InternalAddIndex(SCustomIndex, RESTDWIndexDefs[i].Fields, [], '', ''); + F:=FIndexes.AddMemTableIndexDef; + F.Name:=AName; + F.Fields:=AFields; + F.Options:=AOptions; + F.DescFields:=ADescFields; + F.CaseInsFields:=ACaseInsFields; + InternalCreateIndex(F); + Result:=F; End; -function TRESTDWMemTable.LoadField(FieldDef: TFieldDef; buffer: Pointer; out - CreateBlob: boolean): Boolean; +Procedure TRESTDWCustomMemTable.InternalCreateIndex(F : TRESTDWMemTableIndex); + +Var + B : TRESTDWMemInternalIndex; Begin - // Empty procedure to make it possible to use TCustomBufDataset as a memory dataset - CreateBlob := False; - Result := False; + If Active and not Refreshing Then + FetchAll; + If IsUniDirectional Then + B:=TRESTDWMemUniDirectionalIndex.Create(self) + Else + B:=TRESTDWMemDoubleLinkedIndex.Create(self); + F.FBufferIndex:=B; + With B Do + Begin + InitialiseIndex; + F.SetIndexProperties; + End; + If Active Then + Begin + If not Refreshing Then + B.InitialiseSpareRecord(IntAllocRecordBuffer); + If (F.Fields<>'') Then + BuildIndex(B); + End + Else + If (FIndexes.Count+2>FMaxIndexesCount) Then + FMaxIndexesCount:=FIndexes.Count+2; // Custom+Default order End; -Procedure SetFieldIsNull(NullMask : pbyte;x : longint); //inline; +Class Function TRESTDWCustomMemTable.DefaultReadFileFormat: TRESTDWMemDataPacketFormat; Begin - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - NullMask[x div 8] := (NullMask[x div 8]) or (1 shl (x mod 8)); - {$ELSE} - //TODO XyberX - TRESTDWBytes(NullMask)[x div 8] := (TRESTDWBytes(NullMask)[x div 8]) or (1 shl (x mod 8)); - {$IFEND} - {$ELSE} - NullMask[x div 8] := (NullMask[x div 8]) or (1 shl (x mod 8)); - {$ENDIF} + Result:=dfAny; End; -function TRESTDWMemTable.GetNewBlobBuffer: PBlobBuffer; -Var - ABlobBuffer : PBlobBuffer; +Class Function TRESTDWCustomMemTable.DefaultWriteFileFormat: TRESTDWMemDataPacketFormat; Begin - setlength(FBlobs, Length(FBlobs) +1); - New(ABlobBuffer); -// Fillbyte(ABlobBuffer^, Sizeof(ABlobBuffer^), 0); - ABlobBuffer^.OrgBufID := High(FBlobs); - ABlobBuffer^.Buffer := @FBlobs[high(FBlobs)]; - Result := ABlobBuffer; + Result:=dfBinary; End; -function TRESTDWMemTable.LoadBuffer(Buffer: TRecordBuffer): TGetResult; -Var - vFieldSize : Integer; - NullMask : pbyte; - x : longint; - CreateBlobField : Boolean; - BufBlob : PRESTDWBlobField; -Begin - vFieldSize := 0; - If Not Fetch Then +Class Function TRESTDWCustomMemTable.DefaultPacketClass: TRESTDWMemDataPacketReaderClass; +Begin + Result:=TRESTDWTBinaryDatapacketReader; +End; + +Function TRESTDWCustomMemTable.CreateDefaultPacketReader(aStream : TStream): TRESTDWMemDataPacketReader; +Begin + Result:=DefaultPacketClass.Create(Self,aStream); +End; + + +Procedure TRESTDWCustomMemTable.SetIndexFieldNames(Const AValue: String); + +Begin + FIndexFieldNames:=AValue; + If (AValue='') Then Begin - Result := grEOF; - FAllPacketsFetched := True; - // This code has to be placed elsewhere. At least it should also run when - // the datapacket is loaded from file ... see IntLoadRecordsFromFile - BuildIndexes; + FCurrentIndexDef:=FIndexes.FindIndex(SDefaultIndex); Exit; End; - NullMask := Pointer(buffer); - Fillchar(Nullmask^, FNullmaskSize, 0); - Inc (buffer, FNullmaskSize); - For x := 0 To Fields.Count-1 Do + If Active Then + BuildCustomIndex; +End; + +Procedure TRESTDWCustomMemTable.BuildCustomIndex; + +Var + i, p: integer; + s: string; + SortFields, DescFields: string; + F : TRESTDWMemTableIndex; + +Begin + F:=FIndexes.FindIndex(SCustomIndex); + If (F=Nil) Then + InitDefaultIndexes; + F:=FIndexes.FindIndex(SCustomIndex); + SortFields := ''; + DescFields := ''; + For i := 1 To RESTDWWordCount(FIndexFieldNames, [Limiter]) Do Begin - If Not LoadField(FieldDefs[x], buffer, CreateBlobField) Then - SetFieldIsNull(NullMask, x) - Else If CreateBlobField Then + s := RESTDWExtractDelimited(i, FIndexFieldNames, [Limiter]); + p := Pos(Desc, s); + If p>0 Then Begin - BufBlob := PRESTDWBlobField(Buffer); - BufBlob^.BlobBuffer := GetNewBlobBuffer; - LoadBlobIntoBuffer(FieldDefs[x],BufBlob); + system.Delete(s, p, LenDesc); + DescFields := DescFields + Limiter + s; End; - CalcDataSize(Fields[X], vFieldSize); - Inc(buffer, vFieldSize); + SortFields := SortFields + Limiter + s; End; - Result := grOK; + If (Length(SortFields)>0) and (SortFields[1]=Limiter) Then + system.Delete(SortFields,1,1); + If (Length(DescFields)>0) and (DescFields[1]=Limiter) Then + system.Delete(DescFields,1,1); + F.Fields:=SortFields; + F.Options:=[]; + F.DescFields:=DescFields; + FCurrentIndexDef:=F; + F.SetIndexProperties; + If Active Then + Begin + FetchAll; + BuildIndex(F.BufferIndex); + Resync([rmCenter]); + End; + FPacketRecords:=-1; End; -function TRESTDWMemTable.getnextpacket: Integer; +Procedure TRESTDWCustomMemTable.SetIndexName(AValue: String); + Var - i : Integer; - pb : TRecordBuffer; - T : TRESTDWIndex; + F : TRESTDWMemTableIndex; + C : TRESTDWMemTableIndex; + D : TIndexDef; + B : TRESTDWMemDoubleLinkedIndex; + N : String; + I : Integer; + Begin - Result := 0; - If FAllPacketsFetched Then + N:=AValue; + If (N='') Then + N:=SDefaultIndex; + F:=FIndexes.FindIndex(N); + D:=Nil; + If (F=Nil) and Active and (AValue<>'') Then Begin - Result := 0; - Exit; + I:=FRuntimeIndexes.IndexOf(N); + If I<>-1 Then + D:=FRuntimeIndexes[I]; End; - T := GetCurrentIndexBuf; - If T <> Nil Then + If (F=Nil) and (D=Nil) and (AValue<>'') and not (csLoading in ComponentState) Then + DatabaseErrorFmt(SIndexNotFound,[AValue],Self); + FIndexName:=AValue; + If Assigned(D) Then Begin - T.BeginUpdate; - I := 0; - pb := DefaultBufferIndex.SpareBuffer; - While ((i < FPacketRecords) or (FPacketRecords = -1)) and (LoadBuffer(pb) = grOk) do + C:=FIndexes.FindIndex(SCustomIndex); + If C=Nil Then Begin - With DefaultBufferIndex Do - Begin - AddRecord; - pb := SpareBuffer; - End; - Inc(i); + InitDefaultIndexes; + C:=FIndexes.FindIndex(SCustomIndex); End; - T.EndUpdate; - // FBRecordCount := FBRecordCount + i; //Todo XyberX - Result := i; + C.Fields:=D.Fields; + C.Options:=D.Options; + C.DescFields:=D.DescFields; + C.SetIndexProperties; + FCurrentIndexDef:=C; + FetchAll; + BuildIndex(C.BufferIndex); + Resync([rmCenter]); + Exit; End; + If Assigned(F) Then + Begin + If Assigned(F.BufferIndex) Then + Begin + B:=TRESTDWMemDoubleLinkedIndex(F.BufferIndex); + If Assigned(CurrentIndexBuf) and + (CurrentIndexBuf is TRESTDWMemDoubleLinkedIndex) Then + B.FCurrentRecBuf:=TRESTDWMemDoubleLinkedIndex(CurrentIndexBuf).FCurrentRecBuf; + End; + FCurrentIndexDef:=F; + If Active Then + Resync([rmCenter]); + End + Else + FCurrentIndexDef:=Nil; End; -procedure TRESTDWMemTable.FetchAll; +Procedure TRESTDWCustomMemTable.SetMaxIndexesCount(Const AValue: Integer); Begin - Repeat - Until (getnextpacket < FPacketRecords) or (FPacketRecords = -1); + CheckInactive; + If AValue > 1 Then + FMaxIndexesCount:=AValue + Else + DatabaseError(SMinIndexes,Self); End; -Function TUniDirectionalBufIndex.GetCurrentBuffer: Pointer; +Procedure TRESTDWCustomMemTable.InternalSetToRecord(Buffer: TRecordBuffer); Begin - Result := FSPareBuffer; + CurrentIndexBuf.GotoBookmark(PRESTDWMemBookmark(Buffer+FRecordSize)); End; -Function TUniDirectionalBufIndex.GetCurrentRecord: TRecordBuffer; +Procedure TRESTDWCustomMemTable.SetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); Begin - Result := Nil; - // Result:=inherited GetCurrentRecord; + PRESTDWMemBookmark(Buffer + FRecordSize)^ := PRESTDWMemBookmark(Data)^; End; -Function TUniDirectionalBufIndex.GetIsInitialized: boolean; +Procedure TRESTDWCustomMemTable.SetBookmarkFlag(Buffer: TRecordBuffer; Value: TBookmarkFlag); Begin - Result := Assigned(FSPareBuffer); + PRESTDWMemBookmark(Buffer + FRecordSize)^.BookmarkFlag := Value; End; -Function TUniDirectionalBufIndex.GetSpareBuffer: TRecordBuffer; +Procedure TRESTDWCustomMemTable.GetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); Begin - Result := FSPareBuffer; + PRESTDWMemBookmark(Data)^ := PRESTDWMemBookmark(Buffer + FRecordSize)^; End; -Function TUniDirectionalBufIndex.GetSpareRecord: TRecordBuffer; +Function TRESTDWCustomMemTable.GetBookmarkFlag(Buffer: TRecordBuffer): TBookmarkFlag; Begin - Result := FSPareBuffer; + Result := PRESTDWMemBookmark(Buffer + FRecordSize)^.BookmarkFlag; End; -Function TUniDirectionalBufIndex.ScrollBackward: TGetResult; +Procedure TRESTDWCustomMemTable.InternalGotoBookmark(ABookmark: Pointer); Begin - Result := grError; + // note that ABookMark should be a PRESTDWMemBookmark. But this way it can also be + // a pointer to a TRESTDWMemRecLinkItem + CurrentIndexBuf.GotoBookmark(ABookmark); End; -Function TUniDirectionalBufIndex.ScrollForward: TGetResult; -Begin - Result := grOk; -End; +Function TRESTDWCustomMemTable.getnextpacket : integer; + +Var i : integer; + pb : TRecordBuffer; + T : TRESTDWMemInternalIndex; -Function TUniDirectionalBufIndex.GetCurrent: TGetResult; Begin - Result := grOk; + If FAllPacketsFetched Then + Begin + result := 0; + Exit; + End; + T:=CurrentIndexBuf; + T.BeginUpdate; + + i := 0; + pb := DefaultBufferIndex.SpareBuffer; + While ((i < FPacketRecords) or (FPacketRecords = -1)) and (LoadBuffer(pb) = grOk) Do + Begin + With DefaultBufferIndex Do + Begin + AddRecord; + pb := SpareBuffer; + End; + inc(i); + End; + + T.EndUpdate; + FBRecordCount := FBRecordCount + i; + result := i; End; -Function TUniDirectionalBufIndex.ScrollFirst: TGetResult; +Function TRESTDWCustomMemTable.GetFieldSize(FieldDef : TFieldDef) : longint; + Begin - Result := grError; + Case FieldDef.DataType Of + ftUnknown : result := 0; + ftString, + ftGuid, + ftFixedChar: +{$IFDEF FPC} + result := FieldDef.Size*FieldDef.CharSize + 1; +{$ELSE} + result := FieldDef.Size*SizeOf(AnsiChar) + 1; +{$ENDIF} + ftFixedWideChar, + ftWideString: +{$IFDEF FPC} + result := (FieldDef.Size + 1)*FieldDef.CharSize; +{$ELSE} + result := (FieldDef.Size + 1)*SizeOf(WideChar); +{$ENDIF} + ftSmallint, + ftInteger, + ftAutoInc, + ftword : result := sizeof(longint); + ftBoolean : result := sizeof(wordbool); + ftBCD : result := sizeof(currency); + ftFmtBCD : result := sizeof(TBCD); + ftFloat, + ftCurrency : result := sizeof(double); + ftLargeInt : result := sizeof(largeint); +{$IFDEF DELPHI2010UP} + ftLongWord : result := sizeof(Cardinal); + ftShortint : result := sizeof(ShortInt); + ftByte : result := sizeof(Byte); + ftSingle : result := sizeof(Single); + ftExtended : result := sizeof(Extended); +{$ENDIF} + ftTime, + ftDate, + ftDateTime : result := sizeof(TDateTime); + ftTimeStamp : +{$IFDEF FPC} + result := sizeof(Double); +{$ELSE} + result := sizeof(TSQLTimeStamp); +{$ENDIF} + ftBytes : result := FieldDef.Size; + ftVarBytes : result := FieldDef.Size + 2; + ftVariant : result := sizeof(variant); + ftBlob, + ftMemo, + ftGraphic, + ftFmtMemo, + ftParadoxOle, + ftDBaseOle, + ftTypedBinary, + ftOraBlob, + ftOraClob, + ftWideMemo : result := sizeof(TRESTDWMemBlobField) + Else + DatabaseErrorFmt(SUnsupportedFieldType,[Fieldtypenames[FieldDef.DataType]]); +End; +{$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT} + result:=Align(result,4); +{$ENDIF} End; -Procedure TUniDirectionalBufIndex.ScrollLast; +Function TRESTDWCustomMemTable.GetRecordUpdateBuffer(Const ABookmark : TRESTDWMemBookmark; IncludePrior : boolean = false; AFindNext : boolean = false): boolean; + +Var x : integer; + StartBuf : integer; + Begin - DatabaseError(SUniDirectional); + If AFindNext Then + StartBuf := FCurrentUpdateBuffer + 1 + Else + StartBuf := 0; + Result := False; + For x := StartBuf To high(FUpdateBuffer) Do + If CurrentIndexBuf.SameBookmarks(@FUpdateBuffer[x].BookmarkData,@ABookmark) or + (IncludePrior and (FUpdateBuffer[x].UpdateKind=ukDelete) and CurrentIndexBuf.SameBookmarks(@FUpdateBuffer[x].NextBookmarkData,@ABookmark)) Then + Begin + FCurrentUpdateBuffer := x; + Result := True; + Break; + End; End; -Procedure TUniDirectionalBufIndex.SetToFirstRecord; +Function TRESTDWCustomMemTable.GetRecordUpdateBufferCached(Const ABookmark: TRESTDWMemBookmark; + IncludePrior: boolean): boolean; Begin - // for UniDirectional datasets should be [Internal]First valid method call - // do nothing + // if the current update buffer matches, immediately return true + If (FCurrentUpdateBuffer < length(FUpdateBuffer)) and ( + CurrentIndexBuf.SameBookmarks(@FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData,@ABookmark) or + (IncludePrior + and (FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind=ukDelete) + and CurrentIndexBuf.SameBookmarks(@FUpdateBuffer[FCurrentUpdateBuffer].NextBookmarkData,@ABookmark))) Then + Begin + Result := True; + End + Else + Result := GetRecordUpdateBuffer(ABookmark,IncludePrior); End; -Procedure TUniDirectionalBufIndex.SetToLastRecord; +Function TRESTDWCustomMemTable.LoadBuffer(Buffer : TRecordBuffer): TGetResult; + +Var NullMask : pbyte; + x : longint; + CreateBlobField : boolean; + BufBlob : PRESTDWMemBlobField; + Begin - DatabaseError(SUniDirectional); + If not Fetch Then + Begin + Result := grEOF; + FAllPacketsFetched := True; + // This code has to be placed elsewhere. At least it should also run when + // the datapacket is loaded from file ... see IntLoadRecordsFromFile + BuildIndexes; + Exit; + End; + + NullMask := pointer(buffer); + fillchar(Nullmask^,FNullmaskSize,0); + buffer := Pointer(TRESTDWPtrInt(buffer) + FNullmaskSize); + + For x := 0 To FieldDefs.Count-1 Do + Begin + If not LoadField(FieldDefs[x],buffer,CreateBlobField) Then + SetFieldIsNull(NullMask,x) + Else If CreateBlobField Then + Begin + BufBlob := PRESTDWMemBlobField(Buffer); + BufBlob^.BlobBuffer := GetNewBlobBuffer; + LoadBlobIntoBuffer(FieldDefs[x],BufBlob); + End; + buffer := Pointer(TRESTDWPtrInt(buffer) + GetFieldSize(FieldDefs[x])); + End; + Result := grOK; End; -Procedure TUniDirectionalBufIndex.StoreCurrentRecord; +Function TRESTDWCustomMemTable.GetCurrentBuffer: TRecordBuffer; Begin - DatabaseError(SUniDirectional); + Case State Of + dsFilter: Result := FFilterBuffer; + dsCalcFields: Result := TRecordBuffer(CalcBuffer); +{$IFDEF FPC} + dsRefreshFields: Result := CurrentIndexBuf.CurrentBuffer; +{$ENDIF} + Else Result := TRecordBuffer(ActiveBuffer); End; +End; + + +Function TRESTDWCustomMemTable.GetFieldDataPtr(Field: TField; Buffer: Pointer): Boolean; + +Var + CurrBuff : TRecordBuffer; -Procedure TUniDirectionalBufIndex.RestoreCurrentRecord; Begin - DatabaseError(SUniDirectional); + Result := False; + If State = dsOldValue Then + Begin + If FSavedState = dsInsert Then + CurrBuff := nil // old values = null + Else If GetActiveRecordUpdateBuffer Then + CurrBuff := FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer + Else + // There is no UpdateBuffer for ActiveRecord, so there are no explicit old values available + // then we can assume, that old values = current values + CurrBuff := CurrentIndexBuf.CurrentBuffer; + End + Else + CurrBuff := GetCurrentBuffer; + + If not assigned(CurrBuff) Then Exit; //Null value + + If Field.FieldNo > 0 Then // If =-1, then calculated/lookup field or =0 unbound field + Begin + If GetFieldIsNull(pbyte(CurrBuff),Field.FieldNo-1) Then + Exit; + If assigned(Buffer) Then + Begin + CurrBuff := Pointer(TRESTDWPtrInt(CurrBuff) + FFieldBufPositions[Field.FieldNo-1]); + If Field.IsBlob Then // we need GetFieldSize for BLOB but Field.DataSize for others - #36747 + Move(CurrBuff^, Buffer^, GetFieldSize(FieldDefs[Field.FieldNo-1])) + Else + Move(CurrBuff^, Buffer^, Field.DataSize); + End; + Result := True; + End + Else + Begin + CurrBuff := Pointer(TRESTDWPtrInt(CurrBuff) + GetRecordSize + Field.Offset); + Result := Boolean(CurrBuff^); + If Result and assigned(Buffer) Then + Begin + CurrBuff := Pointer(TRESTDWPtrInt(CurrBuff) + 1); + Move(CurrBuff^, Buffer^, Field.DataSize); + End; + End; End; -Function TUniDirectionalBufIndex.CanScrollForward: Boolean; +Procedure TRESTDWCustomMemTable.SetFieldDataPtr(Field: TField; Buffer: Pointer); + +Var CurrBuff : pointer; + NullMask : pbyte; + Begin - // should return true if next record is already fetched - Result := false; + If not (State in dsWriteModes) Then + DatabaseErrorFmt(SNotEditing, [Name], Self); + CurrBuff := GetCurrentBuffer; + If Field.FieldNo > 0 Then // If =-1, then calculated/lookup field or =0 unbound field + Begin + {$IFDEF FPC} + If Field.ReadOnly and not (State in [dsSetKey, dsFilter, dsRefreshFields]) Then +{$ELSE} + If Field.ReadOnly and not (State in [dsSetKey, dsFilter]) Then +{$ENDIF} + DatabaseErrorFmt(SReadOnlyField, [Field.DisplayName]); + If State in [dsEdit, dsInsert, dsNewValue] Then + Field.Validate(Buffer); + NullMask := CurrBuff; + + CurrBuff := Pointer(TRESTDWPtrInt(CurrBuff) + FFieldBufPositions[Field.FieldNo-1]); + If assigned(buffer) Then + Begin + If Field.IsBlob Then // we need GetFieldSize for BLOB but Field.DataSize for others - #36747 + Move(Buffer^, CurrBuff^, GetFieldSize(FieldDefs[Field.FieldNo-1])) + Else + Move(Buffer^, CurrBuff^, Field.DataSize); + unSetFieldIsNull(NullMask,Field.FieldNo-1); + End + Else + SetFieldIsNull(NullMask,Field.FieldNo-1); + End + Else + Begin + CurrBuff := Pointer(TRESTDWPtrInt(CurrBuff) + GetRecordSize + Field.Offset); + Boolean(CurrBuff^) := Buffer <> nil; + CurrBuff := Pointer(TRESTDWPtrInt(CurrBuff) + 1); + If assigned(Buffer) Then + Move(Buffer^, CurrBuff^, Field.DataSize); + End; + If not (State in [dsCalcFields, dsFilter, dsNewValue]) Then + DataEvent(deFieldChange, TRESTDWPtrInt(Field)); End; -Procedure TUniDirectionalBufIndex.DoScrollForward; +{$IFDEF FPC} +Function TRESTDWCustomMemTable.GetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean): Boolean; Begin - // do nothing + Result := GetFieldDataPtr(Field, Buffer); End; - -Procedure TUniDirectionalBufIndex.StoreCurrentRecIntoBookmark(const ABookmark: PRESTDWBookmark); +Function TRESTDWCustomMemTable.GetFieldData(Field: TField; Buffer: Pointer): Boolean; Begin - // do nothing + Result := GetFieldDataPtr(Field, Buffer); End; - -Procedure TUniDirectionalBufIndex.StoreSpareRecIntoBookmark(const ABookmark: PRESTDWBookmark); +Procedure TRESTDWCustomMemTable.SetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean); Begin - // do nothing + SetFieldDataPtr(Field, Buffer); End; - -Procedure TUniDirectionalBufIndex.GotoBookmark(const ABookmark: PRESTDWBookmark); +Procedure TRESTDWCustomMemTable.SetFieldData(Field: TField; Buffer: Pointer); Begin - DatabaseError(SUniDirectional); + SetFieldDataPtr(Field, Buffer); End; - -Procedure TUniDirectionalBufIndex.InitialiseIndex; +{$ELSE} + {$IFDEF DELPHIXEUP} +Function TRESTDWCustomMemTable.GetFieldData(Field: TField; Var Buffer: TValueBuffer): Boolean; +Var P: Pointer; Begin - // do nothing + If Length(Buffer) < Field.DataSize Then + SetLength(Buffer, Field.DataSize); + If Length(Buffer) > 0 Then P := @Buffer[0] Else P := nil; + Result := GetFieldDataPtr(Field, P); End; - -Procedure TUniDirectionalBufIndex.InitialiseSpareRecord(const ASpareRecord: TRecordBuffer); +Procedure TRESTDWCustomMemTable.SetFieldData(Field: TField; Buffer: TValueBuffer); +Var P: Pointer; Begin - FSPareBuffer := ASpareRecord; + If Length(Buffer) > 0 Then P := @Buffer[0] Else P := nil; + SetFieldDataPtr(Field, P); End; - -Procedure TUniDirectionalBufIndex.ReleaseSpareRecord; + {$IFDEF RTL240_UP} +Function TRESTDWCustomMemTable.GetFieldData(Field: TField; Buffer: Pointer): Boolean; Begin - FSPareBuffer := Nil; + Result := GetFieldDataPtr(Field, Buffer); End; - -Function TUniDirectionalBufIndex.GetRecNo: Longint; +Procedure TRESTDWCustomMemTable.SetFieldData(Field: TField; Buffer: Pointer); Begin - Result := -1; + SetFieldDataPtr(Field, Buffer); End; - -Procedure TUniDirectionalBufIndex.SetRecNo(ARecNo: Longint); + {$ENDIF} + {$ELSE} +Function TRESTDWCustomMemTable.GetFieldData(Field: TField; Buffer: Pointer): Boolean; Begin - DatabaseError(SUniDirectional); + Result := GetFieldDataPtr(Field, Buffer); End; - -Procedure TUniDirectionalBufIndex.BeginUpdate; +Procedure TRESTDWCustomMemTable.SetFieldData(Field: TField; Buffer: Pointer); Begin - // Do nothing + SetFieldDataPtr(Field, Buffer); End; - -Function TUniDirectionalBufIndex.GetBookmarkSize : Integer; + {$ENDIF} +{$ENDIF} +Function TRESTDWCustomMemTable.IsSequenced : Boolean; Begin - // In principle there are no bookmarks, and the size should be 0. - // But there is quite some code in TCustomBufDataset that relies on - // an existing bookmark of the TBufBookmark type. - // This code could be moved to the TBufIndex but that would make things - // more complicated and probably slower. So use a 'fake' bookmark of - // size TBufBookmark. - // When there are other TBufIndexes which also need special bookmark code - // this can be adapted. - Result := Sizeof(TRESTDWBookmark); + Result := Not Filtered; End; -Procedure TUniDirectionalBufIndex.AddRecord; +Procedure TRESTDWCustomMemTable.InternalDelete; + Var RemRec : pointer; + RemRecBookmrk : TRESTDWMemBookmark; + Begin + InternalSetToRecord(TRecordBuffer(ActiveBuffer)); + // Remove the record from all active indexes + CurrentIndexBuf.StoreCurrentRecIntoBookmark(@RemRecBookmrk); + RemRec := CurrentIndexBuf.CurrentBuffer; + RemoveRecordFromIndexes(RemRecBookmrk); + + If not GetActiveRecordUpdateBuffer Then + Begin + FCurrentUpdateBuffer := length(FUpdateBuffer); + SetLength(FUpdateBuffer,FCurrentUpdateBuffer+1); + FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := IntAllocRecordBuffer; + move(RemRec^, FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer^,FRecordSize); + End + Else + Begin + If FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind <> ukModify Then + Begin + FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := nil; //this 'disables' the updatebuffer + // Do NOT release record buffer (pointed to by RemRecBookmrk.BookmarkData) here + // - When record is inserted and deleted (and memory released) and again inserted then the same memory block can be returned + // which leads to confusion, because we get the same BookmarkData for distinct records + // - In CancelUpdates when records are restored, it is expected that deleted records still exist in memory + // There also could be record(s) in the update buffer that is linked to this record. + End; + End; + CurrentIndexBuf.StoreCurrentRecIntoBookmark(@FUpdateBuffer[FCurrentUpdateBuffer].NextBookmarkData); + FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData := RemRecBookmrk; + FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind := ukDelete; + dec(FBRecordCount); + End; + + +Procedure TRESTDWCustomMemTable.CancelRecordUpdateBuffer(AUpdateBufferIndex: integer; Var ABookmark: TRESTDWMemBookmark); Var - h, i : Integer; +ARecordBuffer: TRecordBuffer; +NBookmark : TRESTDWMemBookmark; +i : integer; Begin - // Release unneeded blob buffers, in order to save memory - // TDataSet has own buffer of records, so do not release blobs until they can be referenced - With TRESTDWMemtable(FDataSet) Do + With FUpdateBuffer[AUpdateBufferIndex] Do + If Assigned(BookmarkData.BookmarkData) Then // this is used to exclude buffers which are already handled + Begin + Case UpdateKind Of + ukModify: Begin - h := Length(FBlobs); - If h > 0 Then //Free in batches, starting with oldest (at beginning) + CurrentIndexBuf.GotoBookmark(@BookmarkData); + move(TRecordBuffer(OldValuesBuffer)^, TRecordBuffer(CurrentIndexBuf.CurrentBuffer)^, FRecordSize); + FreeRecordBuffer(OldValuesBuffer); + End; + ukDelete: + If (assigned(OldValuesBuffer)) Then + Begin + CurrentIndexBuf.GotoBookmark(@NextBookmarkData); + CurrentIndexBuf.InsertRecordBeforeCurrentRecord(TRecordBuffer(BookmarkData.BookmarkData)); + CurrentIndexBuf.ScrollBackward; + move(TRecordBuffer(OldValuesBuffer)^, TRecordBuffer(CurrentIndexBuf.CurrentBuffer)^, FRecordSize); + FreeRecordBuffer(OldValuesBuffer); + inc(FBRecordCount); + End; + ukInsert: + Begin + CurrentIndexBuf.GotoBookmark(@BookmarkData); + ARecordBuffer := CurrentIndexBuf.CurrentRecord; + + // Find next record's bookmark + CurrentIndexBuf.DoScrollForward; + CurrentIndexBuf.StoreCurrentRecIntoBookmark(@NBookmark); + // Process (re-link) all update buffers linked to this record before this record is removed + // Modified record #1, which is later deleted can be linked to another inserted record #2. In this case deleted record #1 precedes inserted #2 in update buffer. + // Deleted records, which are deleted after this record is inserted are in update buffer after this record. + // if we need revert inserted record which is linked from another deleted records, then we must re-link these records + For i:=0 To high(FUpdateBuffer) Do + If (FUpdateBuffer[i].UpdateKind = ukDelete) and + (FUpdateBuffer[i].NextBookmarkData.BookmarkData = BookmarkData.BookmarkData) Then + FUpdateBuffer[i].NextBookmarkData := NBookmark; + + // ReSync won't work if the CurrentBuffer is freed ... so in this case move to next/prior record + If CurrentIndexBuf.SameBookmarks(@BookmarkData,@ABookmark) Then + With CurrentIndexBuf Do Begin - For i := 0 To h Do - SetLength(FBlobs[i], 0); -// FBlobs[i] := Copy(FBlobBuffers, h+1, high(FBlobBuffers)-h); //Todo XyberX + GotoBookmark(@ABookmark); + If ScrollForward = grEOF Then + If ScrollBackward = grBOF Then + ScrollLast; // last record will be removed from index, so move to spare record + StoreCurrentRecIntoBookmark(@ABookmark); End; + + RemoveRecordFromIndexes(BookmarkData); + FreeRecordBuffer(ARecordBuffer); + dec(FBRecordCount); End; + End; + BookmarkData.BookmarkData := nil; End; + End; -Procedure TUniDirectionalBufIndex.InsertRecordBeforeCurrentRecord(const ARecord: TRecordBuffer); +Procedure TRESTDWCustomMemTable.RevertRecord; +Var +ABookmark : TRESTDWMemBookmark; Begin - // Do nothing + CheckBrowseMode; + + If GetActiveRecordUpdateBuffer Then + Begin + CurrentIndexBuf.StoreCurrentRecIntoBookmark(@ABookmark); + + CancelRecordUpdateBuffer(FCurrentUpdateBuffer, ABookmark); + + // remove update record of current record from update-buffer array + Move(FUpdateBuffer[FCurrentUpdateBuffer+1], FUpdateBuffer[FCurrentUpdateBuffer], (High(FUpdateBuffer)-FCurrentUpdateBuffer)*SizeOf(TRESTDWMemRecUpdateBuffer)); + SetLength(FUpdateBuffer, High(FUpdateBuffer)); + + CurrentIndexBuf.GotoBookmark(@ABookmark); + + Resync([]); + End; End; -Procedure TUniDirectionalBufIndex.RemoveRecordFromIndex(const ABookmark: TRESTDWBookmark); +Procedure TRESTDWCustomMemTable.CancelUpdates; +Var +ABookmark : TRESTDWMemBookmark; +r : Integer; Begin - DatabaseError(SUniDirectional); + CheckBrowseMode; + + If Length(FUpdateBuffer) > 0 Then + Begin + CurrentIndexBuf.StoreCurrentRecIntoBookmark(@ABookmark); + + For r := High(FUpdateBuffer) Downto 0 Do + CancelRecordUpdateBuffer(r, ABookmark); + SetLength(FUpdateBuffer, 0); + + CurrentIndexBuf.GotoBookmark(@ABookmark); + + Resync([]); + End; +End; + +Procedure TRESTDWCustomMemTable.EmptyTable; +Var +AFileName : TFileName; +ADatasetReader : TRESTDWMemDataPacketReader; +Begin + If not Active Then + Exit; + + CheckBrowseMode; + AFileName := FFileName; + ADatasetReader := FDatasetReader; + FFileName := ''; + FDatasetReader := nil; + DisableControls; + Try + FreeFieldBuffers; + ClearBuffers; + InternalClose; + InternalOpen; + FAllPacketsFetched := True; + Finally + FDatasetReader := ADatasetReader; + FFileName := AFileName; + EnableControls; End; +DataEvent(deDataSetChange, 0); + End; + +Procedure TRESTDWCustomMemTable.MergeChangeLog; + +Var r : Integer; -Procedure TUniDirectionalBufIndex.OrderCurrentRecord; Begin - // Do nothing -End; + For r:=0 To length(FUpdateBuffer)-1 Do + If assigned(FUpdateBuffer[r].OldValuesBuffer) Then + FreeMem(FUpdateBuffer[r].OldValuesBuffer); + SetLength(FUpdateBuffer,0); -Procedure TUniDirectionalBufIndex.EndUpdate; -Begin - // Do nothing + If assigned(FUpdateBlobBuffers) Then For r:=0 To length(FUpdateBlobBuffers)-1 Do + If assigned(FUpdateBlobBuffers[r]) Then + Begin + // update blob buffer is already referenced from record buffer (see InternalPost) + If FUpdateBlobBuffers[r]^.OrgBufID >= 0 Then + Begin + FreeBlobBuffer(FBlobBuffers[FUpdateBlobBuffers[r]^.OrgBufID]); + FBlobBuffers[FUpdateBlobBuffers[r]^.OrgBufID] := FUpdateBlobBuffers[r]; + End + Else + Begin + setlength(FBlobBuffers,length(FBlobBuffers)+1); + FUpdateBlobBuffers[r]^.OrgBufID := high(FBlobBuffers); + FBlobBuffers[high(FBlobBuffers)] := FUpdateBlobBuffers[r]; + End; + End; + SetLength(FUpdateBlobBuffers,0); End; -Function TDoubleLinkedBufIndex.GetBookmarkSize : integer; -Begin - Result := SizeOf(TRESTDWBookmark); -End; -Function TDoubleLinkedBufIndex.GetCurrentBuffer: Pointer; -Begin -// pointer(FLastRecBuf) + FDataset.BufferOffset; - Result := Pointer(TRESTDWMemtable(FDataSet).ActiveBuffer); //Todo XyberX -End; +Procedure TRESTDWCustomMemTable.InternalCancel; -Function TDoubleLinkedBufIndex.GetCurrentRecord : TRecordBuffer; -Begin - Result := TRecordBuffer(FCurrentRecBuf); -End; +Var i : integer; -Function TDoubleLinkedBufIndex.GetIsInitialized : Boolean; Begin - Result := (FFirstRecBuf<>nil); + If assigned(FUpdateBlobBuffers) Then For i:=0 To high(FUpdateBlobBuffers) Do + If assigned(FUpdateBlobBuffers[i]) and (FUpdateBlobBuffers[i]^.FieldNo>0) Then + FreeBlobBuffer(FUpdateBlobBuffers[i]); End; -Function TDoubleLinkedBufIndex.GetSpareBuffer : TRecordBuffer; -Begin -// Pointer(FLastRecBuf) + FDataset.BufferOffset; - Result := Pointer(TRESTDWMemtable(FDataSet).ActiveBuffer); //Todo XyberX -End; +Procedure TRESTDWCustomMemTable.InternalPost; -Function TDoubleLinkedBufIndex.GetSpareRecord : TRecordBuffer; -Begin - Result := TRecordBuffer(FLastRecBuf); -End; +Var ABuff : TRecordBuffer; +i : integer; +ABookmark : PRESTDWMemBookmark; -Function TDoubleLinkedBufIndex.ScrollBackward: TGetResult; Begin - If Not assigned({$IFNDEF FPC} - {$IF CompilerVersion >= 20} - FCurrentRecBuf[IndNr] - {$ELSE} - //TODO XyberX - FCurrentRecBuf - {$IFEND} - {$ELSE} - FCurrentRecBuf[IndNr] - {$ENDIF}.prior) Then + Inherited InternalPost; + + If assigned(FUpdateBlobBuffers) Then For i:=0 To high(FUpdateBlobBuffers) Do + If assigned(FUpdateBlobBuffers[i]) and (FUpdateBlobBuffers[i]^.FieldNo>0) Then + FUpdateBlobBuffers[i]^.FieldNo := -1; + + If State = dsInsert Then Begin - Result := grBOF; + If assigned(FAutoIncField) Then + Begin + FAutoIncField.AsInteger := FAutoIncValue; + inc(FAutoIncValue); + End; + // The active buffer is the newly created TDataSet record, + // from which the bookmark is set to the record where the new record should be + // inserted + ABookmark := PRESTDWMemBookmark(TRESTDWPtrInt(ActiveBuffer) + FRecordSize); + // Create the new record buffer + ABuff := IntAllocRecordBuffer; + + // Add new record to all active indexes + For i := 0 To FIndexes.Count-1 Do + If BufIndexdefs[i].IsActiveIndex(FCurrentIndexDef) Then + Begin + If (FBRecordCount = 0) Or + (ABookmark^.BookmarkFlag = bfEOF) Or + (Not Assigned(ABookmark^.BookmarkData)) Then + // append at end + BufIndexes[i].ScrollLast + Else + // insert (before current record) + BufIndexes[i].GotoBookmark(ABookmark); + +// insert new record before current record + BufIndexes[i].InsertRecordBeforeCurrentRecord(ABuff); +// newly inserted record becomes current record + BufIndexes[i].ScrollBackward; + End; + + // Link the newly created record buffer to the newly created TDataSet record + CurrentIndexBuf.StoreCurrentRecIntoBookmark(ABookmark); + ABookmark^.BookmarkFlag := bfInserted; + + inc(FBRecordCount); End Else + InternalSetToRecord(TRecordBuffer(ActiveBuffer)); + + // If there is no updatebuffer already, add one + If not GetActiveRecordUpdateBuffer Then Begin - Result := grOK; - FCurrentRecBuf := {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - FCurrentRecBuf[IndNr] - {$ELSE} - //TODO XyberX - FCurrentRecBuf - {$IFEND} - {$ELSE} - FCurrentRecBuf[IndNr] - {$ENDIF}.prior; + // Add a new updatebuffer + FCurrentUpdateBuffer := length(FUpdateBuffer); + SetLength(FUpdateBuffer,FCurrentUpdateBuffer+1); + + // Store a bookmark of the current record into the updatebuffer's bookmark + CurrentIndexBuf.StoreCurrentRecIntoBookmark(@FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData); + + If State = dsEdit Then + Begin + // Create an OldValues buffer with the old values of the record + FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind := ukModify; + FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := IntAllocRecordBuffer; + // Move only the real data + move(CurrentIndexBuf.CurrentBuffer^, FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer^, FRecordSize); + End + Else + Begin + FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind := ukInsert; + FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := nil; + End; End; + + Move(TRecordBuffer(ActiveBuffer)^, CurrentIndexBuf.CurrentBuffer^, FRecordSize); + + // new data are now in current record so reorder current record if needed + For i := 0 To FIndexes.Count-1 Do + If BufIndexDefs[i].MustBuild(FCurrentIndexDef) Then + BufIndexes[i].OrderCurrentRecord; End; -Function TDoubleLinkedBufIndex.ScrollForward : TGetResult; +Procedure TRESTDWCustomMemTable.CalcRecordSize; + +Var x : longint; + Begin - If (FCurrentRecBuf = FLastRecBuf) Or // just opened - ({$IFNDEF FPC} - {$IF CompilerVersion >= 20} - FCurrentRecBuf[IndNr] - {$ELSE} - //TODO XyberX - FCurrentRecBuf - {$IFEND} - {$ELSE} - FCurrentRecBuf[IndNr] - {$ENDIF}.next = FLastRecBuf) Then - Result := grEOF - Else + FNullmaskSize := (FieldDefs.Count+7) div 8; +{$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT} + FNullmaskSize:=Align(FNullmaskSize,4); +{$ENDIF} + FRecordSize := FNullmaskSize; + SetLength(FFieldBufPositions,FieldDefs.count); + For x := 0 To FieldDefs.count-1 Do Begin - FCurrentRecBuf := {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - FCurrentRecBuf[IndNr] - {$ELSE} - //TODO XyberX - FCurrentRecBuf - {$IFEND} - {$ELSE} - FCurrentRecBuf[IndNr] - {$ENDIF}.next; - Result := grOK; + FFieldBufPositions[x] := FRecordSize; + inc(FRecordSize, GetFieldSize(FieldDefs[x])); End; End; -Function TDoubleLinkedBufIndex.GetCurrent : TGetResult; +Function TRESTDWCustomMemTable.GetIndexFieldNames: String; + +Var +i, p: integer; +s: string; +IndexBuf: TRESTDWMemInternalIndex; + Begin - If FFirstRecBuf = FLastRecBuf Then - Result := grError - Else + Result := FIndexFieldNames; + IndexBuf:=CurrentIndexBuf; + If (IndexBuf=Nil) Then + Exit; + Result:=''; + For i := 1 To RESTDWWordCount(IndexBuf.FieldsName, [Limiter]) Do Begin - Result := grOK; - If FCurrentRecBuf = FLastRecBuf Then - FCurrentRecBuf := {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - FCurrentRecBuf[IndNr] - {$ELSE} - //TODO XyberX - FCurrentRecBuf - {$IFEND} - {$ELSE} - FCurrentRecBuf[IndNr] - {$ENDIF}.prior; + s := RESTDWExtractDelimited(i, IndexBuf.FieldsName, [Limiter]); + p := Pos(s, IndexBuf.DescFields); + If p>0 Then + s := s + Desc; + Result := Result + Limiter + s; End; + If (Length(Result)>0) and (Result[1]=Limiter) Then + system.Delete(Result, 1, 1); End; -Function TDoubleLinkedBufIndex.ScrollFirst : TGetResult; +Function TRESTDWCustomMemTable.GetIndexName: String; + Begin - FCurrentRecBuf:=FFirstRecBuf; - If (FCurrentRecBuf = FLastRecBuf) Then - Result := grEOF + If FIndexName<>'' Then + Result:=FIndexName + Else If (FIndexes.Count>0) and (CurrentIndexBuf<>Nil) Then + Result:=CurrentIndexBuf.Name Else - Result := grOK; + Result:=''; End; -Procedure TDoubleLinkedBufIndex.ScrollLast; +Function TRESTDWCustomMemTable.GetBufUniDirectional: boolean; Begin - FCurrentRecBuf := FLastRecBuf; + result := IsUniDirectional; End; -Function TDoubleLinkedBufIndex.GetRecord(ABookmark : PRESTDWBookmark; - GetMode : TGetMode) : TGetResult; +Function TRESTDWCustomMemTable.GetPacketReader(Const Format: TRESTDWMemDataPacketFormat; Const AStream: TStream): TRESTDWMemDataPacketReader; + Var - ARecord : PRESTDWRecLinkItem; -Begin - Result := grOK; - Case GetMode Of - gmPrior : Begin - If assigned(ABookmark^.BookmarkData) Then - ARecord := {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - ABookmark^.BookmarkData[IndNr] - {$ELSE} - //TODO XyberX - ABookmark^.BookmarkData - {$IFEND} - {$ELSE} - ABookmark^.BookmarkData[IndNr] - {$ENDIF}.prior - Else - ARecord := Nil; - If not assigned(ARecord) Then - Result := grBOF; - End; - gmNext : Begin - If assigned(ABookmark^.BookmarkData) Then - ARecord := {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - ABookmark^.BookmarkData[IndNr] - {$ELSE} - //TODO XyberX - ABookmark^.BookmarkData - {$IFEND} - {$ELSE} - ABookmark^.BookmarkData[IndNr] - {$ENDIF}.next - Else - ARecord := FFirstRecBuf; - End; - Else Result := grError; - End; - If ARecord = FLastRecBuf then - Result := grEOF; - // store into BookmarkData pointer to prior/next record - ABookmark^.BookmarkData:=ARecord; +APacketReader: TRESTDWMemDataPacketReader; +APacketReaderReg: TRESTDWMemDataPacketReaderRegistration; +Fmt : TRESTDWMemDataPacketFormat; +Begin + fmt:=Format; + If (Fmt=dfDefault) Then + fmt:=DefaultReadFileFormat; + If fmt=dfDefault Then + APacketReader := CreateDefaultPacketReader(AStream) + Else If GetRegisterDatapacketReader(AStream, fmt, APacketReaderReg) Then + APacketReader := APacketReaderReg.ReaderClass.Create(Self, AStream) + Else If TRESTDWTBinaryDatapacketReader.RecognizeStream(AStream) Then + Begin + AStream.Seek(0, soFromBeginning); + APacketReader := TRESTDWTBinaryDatapacketReader.Create(Self, AStream) + End + Else + DatabaseError(SStreamNotRecognised,Self); + Result:=APacketReader; End; -Procedure TDoubleLinkedBufIndex.SetToFirstRecord; -Begin - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - FLastRecBuf[IndNr] - {$ELSE} - //TODO XyberX - FLastRecBuf - {$IFEND} - {$ELSE} - FLastRecBuf[IndNr] - {$ENDIF}.next:=FFirstRecBuf; - FCurrentRecBuf := FLastRecBuf; -End; +Function TRESTDWCustomMemTable.GetRecordSize : Word; -Procedure TDoubleLinkedBufIndex.SetToLastRecord; Begin - If FLastRecBuf <> FFirstRecBuf Then - FCurrentRecBuf := FLastRecBuf; + result := FRecordSize + BookmarkSize; End; -Procedure TDoubleLinkedBufIndex.StoreCurrentRecord; -Begin - FStoredRecBuf:=FCurrentRecBuf; -End; +Function TRESTDWCustomMemTable.GetChangeCount: integer; -Procedure TDoubleLinkedBufIndex.RestoreCurrentRecord; Begin - FCurrentRecBuf:=FStoredRecBuf; + result := length(FUpdateBuffer); End; -Procedure TDoubleLinkedBufIndex.DoScrollForward; -Begin - FCurrentRecBuf := {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - FCurrentRecBuf[IndNr] - {$ELSE} - //TODO XyberX - FCurrentRecBuf - {$IFEND} - {$ELSE} - FCurrentRecBuf[IndNr] - {$ENDIF}.next; -End; -Procedure TDoubleLinkedBufIndex.StoreCurrentRecIntoBookmark(const ABookmark: PRESTDWBookmark); -Begin - ABookmark^.BookmarkData := FCurrentRecBuf; -End; +Procedure TRESTDWCustomMemTable.InternalInitRecord(Buffer: TRecordBuffer); -Procedure TDoubleLinkedBufIndex.StoreSpareRecIntoBookmark(Const ABookmark : PRESTDWBookmark); Begin - ABookmark^.BookmarkData := FLastRecBuf; + FillChar(Buffer^, FRecordSize, #0); + + fillchar(Buffer^,FNullmaskSize,255); End; -Procedure TDoubleLinkedBufIndex.GotoBookmark(const ABookmark : PRESTDWBookmark); +{$IFDEF FPC} +Procedure TRESTDWCustomMemTable.SetRecNo(Value: Longint); +{$ELSE} +Procedure TRESTDWCustomMemTable.SetRecNo(Value: Integer); +{$ENDIF} + +Var ABookmark : TRESTDWMemBookmark; + Begin - FCurrentRecBuf := ABookmark^.BookmarkData; + CheckBrowseMode; + If Value > RecordCount Then + Repeat Until (getnextpacket < FPacketRecords) or (Value <= RecordCount) or (FPacketRecords = -1); + + If (Value > RecordCount) or (Value < 1) Then + Begin + DatabaseError(SNoSuchRecord, Self); + Exit; + End; + + CurrentIndexBuf.RecNo:=Value; + CurrentIndexBuf.StoreCurrentRecIntoBookmark(@ABookmark); + InternalGotoBookmark(@ABookmark); End; -Function TDoubleLinkedBufIndex.CompareBookmarks(const ABookmark1,ABookmark2: PRESTDWBookmark) : Integer; -Var - ARecord1, - ARecord2 : PRESTDWRecLinkItem; +{$IFDEF FPC} +Function TRESTDWCustomMemTable.GetRecNo: Longint; +{$ELSE} +Function TRESTDWCustomMemTable.GetRecNo: Integer; +{$ENDIF} + Begin - // valid bookmarks expected - // estimate result using memory addresses of records - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - Result := ABookmark1^.BookmarkData - ABookmark2^.BookmarkData; - {$ELSE} - //TODO XyberX - Result := 0; - {$IFEND} - {$ELSE} - Result := ABookmark1^.BookmarkData - ABookmark2^.BookmarkData; - {$ENDIF} - If Result = 0 Then - Exit - Else If Result < 0 Then - Begin - Result := -1; - ARecord1 := ABookmark1^.BookmarkData; - ARecord2 := ABookmark2^.BookmarkData; - End + If IsUniDirectional Then + Result := -1 + Else If (FBRecordCount = 0) or (State = dsInsert) Then + Result := 0 Else Begin - Result := +1; - ARecord1 := ABookmark2^.BookmarkData; - ARecord2 := ABookmark1^.BookmarkData; + UpdateCursorPos; + Result := CurrentIndexBuf.RecNo; End; - // if we need relative position of records with given bookmarks we must - // traverse through index until we reach lower bookmark or 1st record - While Assigned(ARecord2) And - (ARecord2 <> ARecord1) And - (ARecord2 <> FFirstRecBuf) Do - ARecord2 := {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - ARecord2[IndNr] - {$ELSE} - //TODO XyberX - ARecord2 - {$IFEND} - {$ELSE} - ARecord2[IndNr] - {$ENDIF}.prior; - // if we found lower bookmark as first, then estimated position is correct - If ARecord1 <> ARecord2 Then - Result := -Result; End; -Function TDoubleLinkedBufIndex.SameBookmarks(const ABookmark1, ABookmark2: PRESTDWBookmark) : Boolean; -Begin - Result := Assigned(ABookmark1) And - Assigned(ABookmark2) And - (ABookmark1^.BookmarkData = ABookmark2^.BookmarkData); -End; +Function TRESTDWCustomMemTable.IsCursorOpen: Boolean; -Procedure TDoubleLinkedBufIndex.InitialiseIndex; Begin - // Do nothing + Result := FOpen; End; -Function TDoubleLinkedBufIndex.CanScrollForward: Boolean; +{$IFDEF FPC} +Function TRESTDWCustomMemTable.GetRecordCount: Longint; +{$ELSE} +Function TRESTDWCustomMemTable.GetRecordCount: Integer; +{$ENDIF} Begin - If ({$IFNDEF FPC} - {$IF CompilerVersion >= 20} - FCurrentRecBuf[IndNr] - {$ELSE} - //TODO XyberX - FCurrentRecBuf - {$IFEND} - {$ELSE} - FCurrentRecBuf[IndNr] - {$ENDIF}.next = FLastRecBuf) then - Result := False + If Active Then + Result := FBRecordCount Else - Result := True; + Result:=0; End; -Procedure TDoubleLinkedBufIndex.InitialiseSpareRecord(const ASpareRecord : TRecordBuffer); +Function TRESTDWCustomMemTable.UpdateStatus: TUpdateStatus; + Begin - FFirstRecBuf := Pointer(ASpareRecord); - FLastRecBuf := FFirstRecBuf; - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - FLastRecBuf[IndNr].prior := Nil; - FLastRecBuf[IndNr].next := FLastRecBuf; - {$ELSE} - //TODO XyberX - FLastRecBuf.prior := Nil; - FLastRecBuf.next := FLastRecBuf; - {$IFEND} - {$ELSE} - FLastRecBuf[IndNr].prior := Nil; - FLastRecBuf[IndNr].next := FLastRecBuf; - {$ENDIF} - FCurrentRecBuf := FLastRecBuf; + Result:=usUnmodified; + If GetActiveRecordUpdateBuffer Then + Case FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind Of + ukModify : Result := usModified; + ukInsert : Result := usInserted; + ukDelete : Result := usDeleted; End; + End; + +Function TRESTDWCustomMemTable.GetNewBlobBuffer : PRESTDWMemBlobBuffer; + +Var ABlobBuffer : PRESTDWMemBlobBuffer; -Procedure TDoubleLinkedBufIndex.ReleaseSpareRecord; Begin - FFirstRecBuf := Nil; + setlength(FBlobBuffers,length(FBlobBuffers)+1); + new(ABlobBuffer); + FillChar(ABlobBuffer^,SizeOf(ABlobBuffer^),0); + ABlobBuffer^.OrgBufID := high(FBlobBuffers); + FBlobBuffers[high(FBlobBuffers)] := ABlobBuffer; + result := ABlobBuffer; End; -Function TDoubleLinkedBufIndex.GetRecNo : Longint; -Var - ARecord : PRESTDWRecLinkItem; +Function TRESTDWCustomMemTable.GetNewWriteBlobBuffer : PRESTDWMemBlobBuffer; + +Var ABlobBuffer : PRESTDWMemBlobBuffer; + Begin - ARecord := FCurrentRecBuf; - Result := 1; - While ARecord <> FFirstRecBuf do - Begin - Inc(Result); - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - ARecord := ARecord[IndNr].prior; - {$ELSE} - //TODO XyberX - ARecord := ARecord.prior; - {$IFEND} - {$ELSE} - ARecord := ARecord[IndNr].prior; - {$ENDIF} - End; + setlength(FUpdateBlobBuffers,length(FUpdateBlobBuffers)+1); + new(ABlobBuffer); + FillChar(ABlobBuffer^,SizeOf(ABlobBuffer^),0); + FUpdateBlobBuffers[high(FUpdateBlobBuffers)] := ABlobBuffer; + result := ABlobBuffer; End; -Procedure TDoubleLinkedBufIndex.SetRecNo(ARecNo: Longint); -Var - ARecord : PRESTDWRecLinkItem; +Procedure TRESTDWCustomMemTable.FreeBlobBuffer(Var ABlobBuffer: PRESTDWMemBlobBuffer); + Begin - ARecord := FFirstRecBuf; - While (ARecNo > 1) And - (ARecord <> FLastRecBuf) Do - Begin - dec(ARecNo); - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - ARecord := ARecord[IndNr].next; - {$ELSE} - //TODO XyberX - ARecord := ARecord.next; - {$IFEND} - {$ELSE} - ARecord := ARecord[IndNr].next; - {$ENDIF} - End; - FCurrentRecBuf := ARecord; + If not Assigned(ABlobBuffer) Then + Exit; + FreeMem(ABlobBuffer^.Buffer, ABlobBuffer^.Size); + Dispose(ABlobBuffer); + ABlobBuffer := Nil; End; -Procedure TDoubleLinkedBufIndex.BeginUpdate; +{ TRESTDWMemBlobStream } + +Function TRESTDWMemBlobStream.Seek(Offset: Longint; Origin: Word): Longint; + Begin - If FCurrentRecBuf = FLastRecBuf Then - FCursOnFirstRec := True - Else - FCursOnFirstRec := False; + Case Origin Of + soFromBeginning : FPosition:=Offset; + soFromEnd : FPosition:=FBlobBuffer^.Size+Offset; + soFromCurrent : FPosition:=FPosition+Offset; End; +Result:=FPosition; + End; -Procedure TDoubleLinkedBufIndex.AddRecord; -Var - ARecord : TRecordBuffer; -Begin - ARecord := TRESTDWMemtable(FDataSet).IntAllocRecordBuffer; - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - FLastRecBuf[IndNr].next := Pointer(ARecord); - FLastRecBuf[IndNr].next[IndNr].prior := FLastRecBuf; - FLastRecBuf := FLastRecBuf[IndNr].next; - {$ELSE} - //TODO XyberX - FLastRecBuf.next := Pointer(ARecord); - FLastRecBuf.next.prior := FLastRecBuf; - FLastRecBuf := FLastRecBuf.next; - {$IFEND} - {$ELSE} - FLastRecBuf[IndNr].next := Pointer(ARecord); - FLastRecBuf[IndNr].next[IndNr].prior := FLastRecBuf; - FLastRecBuf := FLastRecBuf[IndNr].next; - {$ENDIF} + +Function TRESTDWMemBlobStream.Read(Var Buffer; Count: Longint): Longint; + +Var ptr : pointer; + +Begin + If FPosition + Count > FBlobBuffer^.Size Then + Count := FBlobBuffer^.Size-FPosition; + ptr := Pointer(TRESTDWPtrInt(FBlobBuffer^.Buffer)+FPosition); + move(ptr^, Buffer, Count); + inc(FPosition, Count); + result := Count; End; -Procedure TDoubleLinkedBufIndex.InsertRecordBeforeCurrentRecord(Const ARecord : TRecordBuffer); -Var - ANewRecord : PRESTDWRecLinkItem; -Begin - ANewRecord := PRESTDWRecLinkItem(ARecord); - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - ANewRecord[IndNr].prior := FCurrentRecBuf[IndNr].prior; - ANewRecord[IndNr].Next := FCurrentRecBuf; - If FCurrentRecBuf=FFirstRecBuf Then - Begin - FFirstRecBuf:=ANewRecord; - ANewRecord[IndNr].prior:=nil; - End - Else - ANewRecord[IndNr].Prior[IndNr].next:=ANewRecord; - ANewRecord[IndNr].next[IndNr].prior:=ANewRecord; - {$ELSE} - //TODO XyberX - ANewRecord.prior := FCurrentRecBuf.prior; - ANewRecord.Next := FCurrentRecBuf; - If FCurrentRecBuf=FFirstRecBuf Then - Begin - FFirstRecBuf:=ANewRecord; - ANewRecord.prior:=nil; - End - Else - ANewRecord.Prior.next:=ANewRecord; - ANewRecord.next.prior:=ANewRecord; - {$IFEND} - {$ELSE} - ANewRecord[IndNr].prior := FCurrentRecBuf[IndNr].prior; - ANewRecord[IndNr].Next := FCurrentRecBuf; - If FCurrentRecBuf=FFirstRecBuf Then - Begin - FFirstRecBuf:=ANewRecord; - ANewRecord[IndNr].prior:=nil; - End - Else - ANewRecord[IndNr].Prior[IndNr].next:=ANewRecord; - ANewRecord[IndNr].next[IndNr].prior:=ANewRecord; - {$ENDIF} +Function TRESTDWMemBlobStream.Write(Const Buffer; Count: Longint): Longint; + +Var ptr : pointer; + +Begin + ReAllocMem(FBlobBuffer^.Buffer, FPosition+Count); + ptr := Pointer(TRESTDWPtrInt(FBlobBuffer^.Buffer)+FPosition); + move(buffer, ptr^, Count); + inc(FBlobBuffer^.Size, Count); + inc(FPosition, Count); + FModified := True; + Result := Count; End; -procedure TDoubleLinkedBufIndex.RemoveRecordFromIndex(const ABookmark : TRESTDWBookmark); -Var - ARecord : PRESTDWRecLinkItem; +Constructor TRESTDWMemDataReference.Create(ADataSet: TRESTDWCustomMemTable; + AKind: TRESTDWMemDataReferenceKind); Begin - ARecord := ABookmark.BookmarkData; - If ARecord = FCurrentRecBuf Then DoScrollForward; - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - If ARecord <> FFirstRecBuf Then - ARecord[IndNr].prior[IndNr].next := ARecord[IndNr].next - Else - Begin - FFirstRecBuf := ARecord[IndNr].next; - FLastRecBuf[IndNr].next := FFirstRecBuf; - End; - ARecord[IndNr].next[IndNr].prior := ARecord[IndNr].prior; - {$ELSE} - //TODO XyberX - If ARecord <> FFirstRecBuf Then - ARecord.prior.next := ARecord.next - Else - Begin - FFirstRecBuf := ARecord.next; - FLastRecBuf.next := FFirstRecBuf; - End; - ARecord.next.prior := ARecord.prior; - {$IFEND} - {$ELSE} - If ARecord <> FFirstRecBuf Then - ARecord[IndNr].prior[IndNr].next := ARecord[IndNr].next - Else - Begin - FFirstRecBuf := ARecord[IndNr].next; - FLastRecBuf[IndNr].next := FFirstRecBuf; - End; - ARecord[IndNr].next[IndNr].prior := ARecord[IndNr].prior; - {$ENDIF} + Inherited Create; + FDataSet := ADataSet; + FKind := AKind; End; -Procedure TDoubleLinkedBufIndex.OrderCurrentRecord; +Procedure TRESTDWMemDataReference.AssignTo(ADataSet: TRESTDWCustomMemTable); Var - ARecord : PRESTDWRecLinkItem; - ABookmark : TRESTDWBookmark; + AStream : TMemoryStream; Begin - // all records except current are already sorted - // check prior records - ARecord := FCurrentRecBuf; - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - Repeat - ARecord := ARecord[IndNr].prior; - Until Not Assigned(ARecord) Or - (IndexCompareRecords(ARecord, FCurrentRecBuf, DBCompareStruct) <= 0); - If assigned(ARecord) Then - ARecord := ARecord[IndNr].next - Else - ARecord := FFirstRecBuf; - If ARecord = FCurrentRecBuf Then - Begin - // prior record is less equal than current - // check next records - Repeat - ARecord := ARecord[IndNr].next; - Until (ARecord=FLastRecBuf) Or - (IndexCompareRecords(ARecord, FCurrentRecBuf, DBCompareStruct) >= 0); - If ARecord = FCurrentRecBuf[IndNr].next Then - Exit; // current record is on proper position - End; - {$ELSE} - //TODO XyberX - Repeat - ARecord := ARecord.prior; - Until Not Assigned(ARecord) Or - (IndexCompareRecords(ARecord, FCurrentRecBuf, DBCompareStruct) <= 0); - If assigned(ARecord) Then - ARecord := ARecord.next - Else - ARecord := FFirstRecBuf; - If ARecord = FCurrentRecBuf Then - Begin - // prior record is less equal than current - // check next records - Repeat - ARecord := ARecord.next; - Until (ARecord=FLastRecBuf) Or - (IndexCompareRecords(ARecord, FCurrentRecBuf, DBCompareStruct) >= 0); - If ARecord = FCurrentRecBuf.next Then - Exit; // current record is on proper position - End; - {$IFEND} - {$ELSE} - Repeat - ARecord := ARecord[IndNr].prior; - Until Not Assigned(ARecord) Or - (IndexCompareRecords(ARecord, FCurrentRecBuf, DBCompareStruct) <= 0); - If assigned(ARecord) Then - ARecord := ARecord[IndNr].next + If not Assigned(ADataSet) or not Assigned(FDataSet) Then + Exit; + If ADataSet = FDataSet Then + Exit; + If ADataSet.Active Then + DatabaseError('DataSet must be inactive', ADataSet); + AStream := TMemoryStream.Create; + Try + If FKind = drDelta Then + FDataSet.SaveDeltaToStream(AStream) Else - ARecord := FFirstRecBuf; - If ARecord = FCurrentRecBuf Then - Begin - // prior record is less equal than current - // check next records - Repeat - ARecord := ARecord[IndNr].next; - Until (ARecord=FLastRecBuf) Or - (IndexCompareRecords(ARecord, FCurrentRecBuf, DBCompareStruct) >= 0); - If ARecord = FCurrentRecBuf[IndNr].next Then - Exit; // current record is on proper position - End; - {$ENDIF} - StoreCurrentRecIntoBookmark(@ABookmark); - RemoveRecordFromIndex(ABookmark); - FCurrentRecBuf := ARecord; - InsertRecordBeforeCurrentRecord(TRecordBuffer(ABookmark.BookmarkData)); - GotoBookmark(@ABookmark); + FDataSet.SaveToStream(AStream, dfBinary); + AStream.Position := 0; + ADataSet.LoadFromStream(AStream, dfBinary); + Finally + AStream.Free; + End; End; -Procedure TDoubleLinkedBufIndex.EndUpdate; -Begin - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - FLastRecBuf[IndNr].next := FFirstRecBuf; - {$ELSE} - //TODO XyberX - FLastRecBuf.next := FFirstRecBuf; - {$IFEND} - {$ELSE} - FLastRecBuf[IndNr].next := FFirstRecBuf; - {$ENDIF} - If FCursOnFirstRec Then - FCurrentRecBuf := FLastRecBuf; -End; +Constructor TRESTDWMemBlobStream.Create(Field: TBlobField; Mode: TBlobStreamMode); + +Var bufblob : TRESTDWMemBlobField; +CurrBuff : TRecordBuffer; -Procedure TRESTDWDatasetIndex.Clearindex; Begin - FreeAndNil(FBufferIndex); + FField := Field; + FDataSet := Field.DataSet as TRESTDWCustomMemTable; + With FDataSet Do + If Mode = bmRead Then + Begin + If not Field.GetData(@bufblob) Then + DatabaseError(SFieldIsNull); + If not assigned(bufblob.BlobBuffer) Then + Begin + bufblob.BlobBuffer := GetNewBlobBuffer; + LoadBlobIntoBuffer(FieldDefs[Field.FieldNo-1], @bufblob); + End; + FBlobBuffer := bufblob.BlobBuffer; + End + Else If Mode=bmWrite Then + Begin + FBlobBuffer := GetNewWriteBlobBuffer; + FBlobBuffer^.FieldNo := Field.FieldNo; + If Field.GetData(@bufblob) and assigned(bufblob.BlobBuffer) Then + FBlobBuffer^.OrgBufID := bufblob.BlobBuffer^.OrgBufID + Else + FBlobBuffer^.OrgBufID := -1; + bufblob.BlobBuffer := FBlobBuffer; + + CurrBuff := GetCurrentBuffer; +// unset null flag for blob field + unSetFieldIsNull(PByte(CurrBuff), Field.FieldNo-1); +// redirect pointer in current record buffer to new write blob buffer + CurrBuff := Pointer(TRESTDWPtrInt(CurrBuff) + FDataSet.FFieldBufPositions[Field.FieldNo-1]); + Move(bufblob, CurrBuff^, FDataSet.GetFieldSize(FDataSet.FieldDefs[Field.FieldNo-1])); + FModified := True; + End; End; -Destructor TRESTDWDatasetIndex.Destroy; +Destructor TRESTDWMemBlobStream.Destroy; Begin - ClearIndex; + If FModified Then + Begin + // if TRESTDWMemBlobStream was requested, but no data was written, then Size = 0; + // used by TBlobField.Clear, so in this case set Field to null + //FField.Modified := True; // should be set to True, but TBlobField.Modified is never reset + + If not (FDataSet.State in [dsFilter, dsCalcFields, dsNewValue]) Then + Begin + If FBlobBuffer^.Size = 0 Then // empty blob = IsNull + // blob stream should be destroyed while DataSet is in write state + SetFieldIsNull(PByte(FDataSet.GetCurrentBuffer), FField.FieldNo-1); + FDataSet.DataEvent(deFieldChange, TRESTDWPtrInt(FField)); + End; + End; Inherited Destroy; End; -Procedure TRESTDWDatasetIndex.SetIndexProperties; -Begin - If Not Assigned(FBufferIndex) Then - Exit; - FBufferIndex.IndNr := Index; - FBufferIndex.Name := Name; - FBufferIndex.FieldsName := Fields; - FBufferIndex.DescFields := DescFields; - FBufferIndex.CaseinsFields := CaseInsFields; - FBufferIndex.Options := Options; -End; +Function TRESTDWCustomMemTable.CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; -Function TRESTDWDatasetIndex.MustBuild(aCurrent : TRESTDWDatasetIndex) : Boolean; -Begin - Result := (FIndexType<>itDefault) And IsActiveIndex(aCurrent); -End; +Var bufblob : TRESTDWMemBlobField; -Function TRESTDWDatasetIndex.IsActiveIndex(aCurrent: TRESTDWDatasetIndex) : Boolean; Begin - Result := (FIndexType<>itCustom) Or (Self=aCurrent); + Result := nil; + Case Mode Of + bmRead: + If not Field.GetData(@bufblob) Then + Exit; + bmWrite: + Begin + If not (State in [dsEdit, dsInsert, dsFilter, dsCalcFields]) Then + DatabaseErrorFmt(SNotEditing, [Name], Self); + If Field.ReadOnly and not (State in [dsSetKey, dsFilter]) Then + DatabaseErrorFmt(SReadOnlyField, [Field.DisplayName]); + End; End; +Result := TRESTDWMemBlobStream.Create(Field as TBlobField, Mode); + End; -Function TRESTDWDatasetIndexDefs.GetBufDatasetIndex(AIndex : Integer): TRESTDWDatasetIndex; +Function TRESTDWCustomMemTable.GetDataReference: TRESTDWMemDataReference; Begin - Result := TRESTDWDatasetIndex(Items[Aindex]); + If not Assigned(FDataReference) Then + FDataReference := TRESTDWMemDataReference.Create(Self, drData); + Result := FDataReference; End; -Function TRESTDWDatasetIndexDefs.GetBufferIndex(AIndex : Integer) : TRESTDWIndex; +Function TRESTDWCustomMemTable.GetDeltaReference: TRESTDWMemDataReference; Begin - Result := Indexdefs[AIndex].BufferIndex; + If not Assigned(FDeltaReference) Then + FDeltaReference := TRESTDWMemDataReference.Create(Self, drDelta); + Result := FDeltaReference; End; -Constructor TRESTDWDatasetIndexDefs.Create(aDataset : TDataset); +Procedure TRESTDWCustomMemTable.SetDataReference(AValue: TRESTDWMemDataReference); Begin - Inherited Create(aDataset); + If not Assigned(AValue) Then + Exit; + AValue.AssignTo(Self); End; -Function TRESTDWDatasetIndexDefs.FindIndex(const IndexName: string): TRESTDWDatasetIndex; +Procedure TRESTDWCustomMemTable.SaveDeltaToStream(AStream: TStream); Var - I : Integer; -Begin - I := IndexOf(IndexName); - If I <> -1 Then - Result := Indexdefs[I] - Else - Result := Nil; + AWriter : TRESTDWTBinaryDatapacketReader; + ASavedState : TDataSetState; + ASavedBuffer : TRecordBuffer; + ASavedUpdIndex : Integer; + I : Integer; +Begin + CheckBiDirectional; + AWriter := TRESTDWTBinaryDatapacketReader.Create(Self, AStream); + ASavedState := SetTempState(dsFilter); + ASavedBuffer := FFilterBuffer; + ASavedUpdIndex := FCurrentUpdateBuffer; + Try + AWriter.StoreFieldDefs(FAutoIncValue); + For I := 0 To High(FUpdateBuffer) Do + Begin + If Assigned(FUpdateBuffer[I].BookmarkData.BookmarkData) Then + Begin + FCurrentUpdateBuffer := I; + Case FUpdateBuffer[I].UpdateKind Of + ukModify: + Begin + If Assigned(FUpdateBuffer[I].OldValuesBuffer) Then + Begin + FFilterBuffer := FUpdateBuffer[I].OldValuesBuffer; + AWriter.StoreRecord([rsvOriginal], I); + End; + CurrentIndexBuf.GotoBookmark(@FUpdateBuffer[I].BookmarkData); + FFilterBuffer := CurrentIndexBuf.CurrentBuffer; + AWriter.StoreRecord([rsvUpdated], I); + End; + ukInsert: + Begin + CurrentIndexBuf.GotoBookmark(@FUpdateBuffer[I].BookmarkData); + FFilterBuffer := CurrentIndexBuf.CurrentBuffer; + AWriter.StoreRecord([rsvInserted], I); + End; + ukDelete: + Begin + If Assigned(FUpdateBuffer[I].OldValuesBuffer) Then + Begin + FFilterBuffer := FUpdateBuffer[I].OldValuesBuffer; + AWriter.StoreRecord([rsvDeleted], I); + End; + End; + End; + End; + End; + AWriter.FinalizeStoreRecords; + Finally + FCurrentUpdateBuffer := ASavedUpdIndex; + FFilterBuffer := ASavedBuffer; + RestoreState(ASavedState); + AWriter.Free; + End; End; -function TRESTDWMemTable.IntAllocRecordBuffer: TRecordBuffer; +Procedure TRESTDWCustomMemTable.SetDatasetPacket(AReader: TRESTDWMemDataPacketReader); Var - I, DataSize : Integer; + ADefaultFields : Boolean; Begin - // Note: Only the internal buffers of TDataset provide bookmark information - New(Result); - DataSize := 0; - For I := 0 to Fields.Count - 1 do - CalcDataSize(Fields[I], DataSize); - ReallocMem(Result, DataSize); + ADefaultFields := DefaultFields; + If Active Then + Close; + If ADefaultFields Then + Fields.Clear; + FieldDefs.Clear; + FDatasetReader := AReader; + Try + Open; + Finally + FDatasetReader := nil; + End; End; -procedure TRESTDWMemTable.InternalCreateIndex(F : TRESTDWDataSetIndex); -Var - B : TRESTDWIndex; -Begin - If Active and Not Refreshing then - FetchAll; - if IsUniDirectional then - B := TUniDirectionalBufIndex.Create(Nil) - else - B := TDoubleLinkedBufIndex.Create(Nil); - F.FBufferIndex:=B; - with B do - begin - InitialiseIndex; - F.SetIndexProperties; - end; - if Active then - begin - if not Refreshing then - B.InitialiseSpareRecord(IntAllocRecordBuffer); - if (F.Fields<>'') then - BuildIndex(B); - end - else - if (FIndexes.Count+2>FMaxIndexesCount) then - FMaxIndexesCount:=FIndexes.Count+2; // Custom+Default order -end; - -function TRESTDWMemTable.InternalAddIndex(const AName, AFields: String; - AOptions: TIndexOptions; const ADescFields: String; - const ACaseInsFields: String): TRESTDWDatasetIndex; -Var - F : TRESTDWDatasetIndex; +Procedure TRESTDWCustomMemTable.GetDatasetPacket(AWriter: TRESTDWMemDataPacketReader); + +Procedure StoreUpdateBuffer(AUpdBuffer : TRESTDWMemRecUpdateBuffer; Var ARowState: TRESTDWMemRowState); +Var AThisRowState : TRESTDWMemRowState; + AStoreUpdBuf : Integer; Begin - F := TRESTDWDatasetIndex(FIndexes.AddIndexDef); - F.Name:=AName; - F.Fields:=AFields; - F.Options:=AOptions; - F.DescFields:=ADescFields; - F.CaseInsFields:=ACaseInsFields; -// BuildIndexes; -// InitDefaultIndexes; - Result := F; - InternalCreateIndex(F); + If AUpdBuffer.UpdateKind = ukModify Then + Begin + AThisRowState := [rsvOriginal]; + ARowState:=[rsvUpdated]; + End + Else If AUpdBuffer.UpdateKind = ukDelete Then + Begin + AStoreUpdBuf:=FCurrentUpdateBuffer; + If GetRecordUpdateBuffer(AUpdBuffer.BookmarkData,True,False) Then + Repeat + If CurrentIndexBuf.SameBookmarks(@FUpdateBuffer[FCurrentUpdateBuffer].NextBookmarkData, @AUpdBuffer.BookmarkData) Then + StoreUpdateBuffer(FUpdateBuffer[FCurrentUpdateBuffer], ARowState); + Until not GetRecordUpdateBuffer(AUpdBuffer.BookmarkData,True,True); + FCurrentUpdateBuffer:=AStoreUpdBuf; + AThisRowState := [rsvDeleted]; + End + Else // ie: UpdateKind = ukInsert + ARowState := [rsvInserted]; + + FFilterBuffer:=AUpdBuffer.OldValuesBuffer; +// OldValuesBuffer is nil if the record is either inserted or inserted and then deleted + If assigned(FFilterBuffer) Then + FDatasetReader.StoreRecord(AThisRowState,FCurrentUpdateBuffer); End; -procedure TRESTDWMemTable.InitDefaultIndexes; -{ - This procedure makes sure there are 2 default indexes: - DEFAULT_ORDER, which is simply the order in which the server records arrived. - CUSTOM_ORDER, which is an internal index to accomodate the 'IndexFieldNames' property. -} -Var - FD, - FC : TRESTDWDatasetIndex; +Procedure HandleUpdateBuffersFromRecord(AFindNext : boolean; ARecBookmark : TRESTDWMemBookmark; Var ARowState: TRESTDWMemRowState); +Var StoreUpdBuf1,StoreUpdBuf2 : Integer; Begin - // Default index - FD := FIndexes.FindIndex(SDefaultIndex); - If (FD = Nil) Then - Begin - FD := InternalAddIndex(SDefaultIndex,'',[],'',''); - FD.IndexType:=itDefault; - FD.FDiscardOnClose:=True; - End; -// Not sure about this. For the moment we leave it in comment -{ else if FD.BufferIndex=Nil then - InternalCreateIndex(FD)} - FCurrentIndexDef:=FD; - // Custom index - If not IsUniDirectional Then + If not AFindNext Then + ARowState:=[]; + If GetRecordUpdateBuffer(ARecBookmark,True,AFindNext) Then Begin - FC := Findexes.FindIndex(SCustomIndex); - If (FC = Nil) Then + If FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind=ukDelete Then Begin - FC := InternalAddIndex(SCustomIndex,'',[],'',''); - FC.IndexType:=itCustom; - FC.FDiscardOnClose:=True; + StoreUpdBuf1:=FCurrentUpdateBuffer; + HandleUpdateBuffersFromRecord(True,ARecBookmark,ARowState); + StoreUpdBuf2:=FCurrentUpdateBuffer; + FCurrentUpdateBuffer:=StoreUpdBuf1; + StoreUpdateBuffer(FUpdateBuffer[StoreUpdBuf1], ARowState); + FCurrentUpdateBuffer:=StoreUpdBuf2; + End + Else + Begin + StoreUpdateBuffer(FUpdateBuffer[FCurrentUpdateBuffer], ARowState); + HandleUpdateBuffersFromRecord(True,ARecBookmark,ARowState); End; - // Not sure about this. For the moment we leave it in comment -{ else if FD.BufferIndex=Nil then - InternalCreateIndex(FD)} - End; - BookmarkSize := GetCurrentIndexBuf.BookmarkSize; + End End; -procedure TRESTDWMemTable.SetMaxIndexesCount(const AValue: Integer); -Begin - CheckInactive; - If AValue > 1 Then - FMaxIndexesCount := AValue - Else - DatabaseError(SMinIndexes, Self); -End; +Var ScrollResult : TGetResult; +SavedState : TDataSetState; +ABookMark : PRESTDWMemBookmark; +ATBookmark : TRESTDWMemBookmark; +RowState : TRESTDWMemRowState; -function TRESTDWMemTable.GetBufIndex(Aindex: Integer): TRESTDWIndex; Begin - Result := FIndexes.Indexes[AIndex] -End; + FDatasetReader := AWriter; + Try +// CheckActive; + ABookMark:=@ATBookmark; + FDatasetReader.StoreFieldDefs(FAutoIncValue); -function TRESTDWMemTable.GetBufIndexDef(Aindex: Integer): TRESTDWDatasetIndex; -Begin - Result := FIndexes.Indexdefs[AIndex]; + SavedState:=SetTempState(dsFilter); + ScrollResult:=CurrentIndexBuf.ScrollFirst; + While ScrollResult=grOK Do + Begin + RowState:=[]; + CurrentIndexBuf.StoreCurrentRecIntoBookmark(ABookmark); + // updates related to current record are stored first + HandleUpdateBuffersFromRecord(False,ABookmark^,RowState); + // now store current record + FFilterBuffer:=CurrentIndexBuf.CurrentBuffer; + If RowState=[] Then + FDatasetReader.StoreRecord([]) + Else + FDatasetReader.StoreRecord(RowState,FCurrentUpdateBuffer); + + ScrollResult:=CurrentIndexBuf.ScrollForward; + If ScrollResult<>grOK Then + Begin + If getnextpacket>0 Then + ScrollResult := CurrentIndexBuf.ScrollForward; + End; + End; +// There could be an update buffer linked to the last (spare) record + CurrentIndexBuf.StoreSpareRecIntoBookmark(ABookmark); + HandleUpdateBuffersFromRecord(False,ABookmark^,RowState); + + RestoreState(SavedState); + + FDatasetReader.FinalizeStoreRecords; + Finally + FDatasetReader := nil; End; + End; -procedure TRESTDWMemTable.BuildCustomIndex; +Procedure TRESTDWCustomMemTable.LoadFromStream(AStream : TStream; + Format : TRESTDWMemDataPacketFormat); Var - i, - p : Integer; - s, - SortFields, - DescFields : String; - F : TRESTDWDatasetIndex; -Begin - F :=FIndexes.FindIndex(SCustomIndex); - If (F = Nil) Then - InitDefaultIndexes; - F:=FIndexes.FindIndex(SCustomIndex); - SortFields := ''; - DescFields := ''; - for i := 1 to WordCount(FIndexFieldNames, [Limiter]) do - begin - s := ExtractDelimited(i, FIndexFieldNames, [Limiter]); - p := Pos(Desc, s); - if p>0 then - begin - system.Delete(s, p, LenDesc); - DescFields := DescFields + Limiter + s; - end; - SortFields := SortFields + Limiter + s; - end; - if (Length(SortFields)>0) and (SortFields[1]=Limiter) then - system.Delete(SortFields,1,1); - if (Length(DescFields)>0) and (DescFields[1]=Limiter) then - system.Delete(DescFields,1,1); - F.Fields:=SortFields; - F.Options:=[ixCaseInsensitive]; - F.DescFields:=DescFields; - FCurrentIndexDef:=F; - F.SetIndexProperties; - FAllPacketsFetched := False; - FFetch := True; - If Active Then - Begin - FetchAll; - BuildIndex(F.BufferIndex); - Resync([rmCenter]); + APacketReader : TRESTDWMemDataPacketReader; + AStorage : TRESTDWStorageBin; + APosition : Int64; +Begin + CheckBiDirectional; + If Format = dfDefault Then + Begin + APosition := AStream.Position; + AStream.Position := 0; + If TRESTDWTBinaryDatapacketReader.RecognizeStream(AStream) Then + Begin + AStream.Position := 0; + APacketReader := TRESTDWTBinaryDatapacketReader.Create(Self,AStream); + Try + SetDatasetPacket(APacketReader); + Finally + APacketReader.Free; + End; + Exit; + End; + AStream.Position := APosition; + AStorage := TRESTDWStorageBin.Create(Nil); + Try + AStorage.LoadDWMemFromStream(Self,AStream); + Finally + AStorage.Free; End; - FPacketRecords := -1; - FFetch := False; -end; + Exit; + End; + APacketReader := GetPacketReader(Format,AStream); + Try + SetDatasetPacket(APacketReader); + Finally + APacketReader.Free; + End; +End; -procedure TRESTDWMemTable.SetIndexFieldNames(const AValue: String); +Procedure TRESTDWCustomMemTable.SaveToStream(AStream : TStream; + Format : TRESTDWMemDataPacketFormat); +Var + APacketReaderReg : TRESTDWMemDataPacketReaderRegistration; + APacketWriter : TRESTDWMemDataPacketReader; + AStorage : TRESTDWStorageBin; + Fmt : TRESTDWMemDataPacketFormat; Begin - FIndexFieldNames := AValue; - If (AValue='') then + CheckBiDirectional; + If Format = dfDefault Then Begin - FCurrentIndexDef:=FIndexes.FindIndex(SDefaultIndex); + AStorage := TRESTDWStorageBin.Create(Nil); + Try + AStorage.SaveDWMemToStream(Self,AStream); + Finally + AStorage.Free; + End; Exit; End; - If Active then - BuildCustomIndex; + Fmt := Format; + If GetRegisterDatapacketReader(Nil,Fmt,APacketReaderReg) Then + APacketWriter := APacketReaderReg.ReaderClass.Create(Self,AStream) + Else If Fmt = dfBinary Then + APacketWriter := TRESTDWTBinaryDatapacketReader.Create(Self,AStream) + Else + DatabaseError(SNoReaderClassRegistered,Self); + Try + GetDatasetPacket(APacketWriter); + Finally + APacketWriter.Free; + End; End; -function TRESTDWMemTable.GetIndexName: String; +Procedure TRESTDWCustomMemTable.LoadFromFile(AFileName: string; Format: TRESTDWMemDataPacketFormat); + +Var + AFileStream : TFileStream; + Begin - If (FIndexes.Count > 0) And - (GetCurrentIndexBuf <> Nil) Then - Result := GetCurrentIndexBuf.Name - Else - Result := FIndexName; -end; + If AFileName='' Then + AFileName := FFileName; + AFileStream := TFileStream.Create(AFileName,fmOpenRead); + Try + LoadFromStream(AFileStream, Format); + Finally + AFileStream.Free; +End; +End; + +Procedure TRESTDWCustomMemTable.SaveToFile(AFileName: string; Format: TRESTDWMemDataPacketFormat); -procedure TRESTDWMemTable.SetIndexName(AValue: String); Var - F : TRESTDWDatasetIndex; - B : TDoubleLinkedBufIndex; - N : String; -begin - N:=AValue; - If (N='') then - N:=SDefaultIndex; - F:=FIndexes.FindIndex(N); - if (F=Nil) and (AValue<>'') and not (csLoading in ComponentState) then - DatabaseErrorFmt(SIndexNotFound,[AValue],Self); - FIndexName:=AValue; - if Assigned(F) then - Begin - SortOnFields(F.Fields, ixCaseInsensitive in F.Options, ixDescending in F.Options); - B:=F.BufferIndex as TDoubleLinkedBufIndex; - if GetCurrentIndexBuf <> Nil then - B.FCurrentRecBuf:=(GetCurrentIndexBuf as TDoubleLinkedBufIndex).FCurrentRecBuf; - FCurrentIndexDef:=F; - if Active then - Resync([rmCenter]); - End - Else - FCurrentIndexDef:=Nil; -end; + AFileStream : TFileStream; -function TRESTDWMemTable.GetCurrentIndexBuf: TRESTDWIndex; Begin - If Assigned(FCurrentIndexDef) Then - Result := FCurrentIndexDef.BufferIndex - Else - Result := Nil; + If AFileName='' Then + AFileName := FFileName; + AFileStream := TFileStream.Create(AFileName,fmCreate); + Try + SaveToStream(AFileStream, Format); + Finally + AFileStream.Free; +End; End; -procedure TRESTDWMemTable.SetIndexDefs(Value: TIndexDefs); +Procedure TRESTDWCustomMemTable.CreateDataset; + Var - I : Integer; - vIndexDef : TIndexDef; + AStoreFileName : String; + I : Integer; + J : Integer; + Begin - FIndexes.Clear; - For I := 0 To Value.Count -1 Do + CheckInactive; + If ((Fields.Count = 0) Or (FieldDefs.Count = 0)) Then Begin - If FIndexes.IndexOf(Value[I].Name) = -1 Then + If (FieldDefs.Count > 0) Then Begin - vIndexDef := FIndexes.AddIndexDef; - vIndexDef.Name := Value[I].Name; - vIndexDef.Fields := Value[I].Fields; - vIndexDef.DescFields := Value[I].DescFields; - vIndexDef.Expression := Value[I].Expression; - vIndexDef.Options := Value[I].Options; - vIndexDef.Source := Value[I].Source; - {$IFNDEF FPC} - vIndexDef.GroupingLevel := Value[I].GroupingLevel; - {$ENDIF} - End; + CreateFields; + For I := 0 To Fields.Count - 1 Do + For J := 0 To FieldDefs.Count - 1 Do + If SameText(Fields[I].FieldName, FieldDefs[J].Name) Then + Begin + Case Fields[I].DataType Of + ftString, + ftFixedChar, + ftWideString, + ftFixedWideChar, + ftBytes, + ftVarBytes: + If FieldDefs[J].Size > 0 Then + Begin + If Fields[I].DataSize <= 0 Then + Fields[I].Size := 1; + If Fields[I].Size <> FieldDefs[J].Size Then + Fields[I].Size := FieldDefs[J].Size; + End; + End; + Break; + End; + BindFields(True); + End + Else If (Fields.Count > 0) Then + Begin + InitFieldDefsFromPersistentFields; + BindFields(True); + End + Else + Raise Exception.Create(SErrNoFieldsDefined); End; + If FAutoIncValue < 0 Then + FAutoIncValue := 1; + AStoreFileName := FFileName; + FFileName := ''; + Try + Open; + Finally + FFileName := AStoreFileName; + End; End; -function TRESTDWMemTable.GetIndexDefs: TIndexDefs; +Procedure TRESTDWCustomMemTable.Clear; Begin - Result := FIndexes; + Close; + FieldDefs.Clear; + Fields.Clear; End; -procedure TRESTDWMemTable.Assign(Source: TPersistent); +Function TRESTDWCustomMemTable.BookmarkValid(ABookmark: TBookmark): Boolean; Begin - If Source is TDataset then - LoadFromDataSet(TDataset(Source), -1, lmCopy) - Else - inherited Assign(Source); + Result:=Assigned(CurrentIndexBuf) and CurrentIndexBuf.BookmarkValid(pointer(ABookmark)); End; -//Procedure TRESTDWMemTable.DefChanged(Sender : TObject); -//Begin -// Inherited; -//End; - -procedure TRESTDWMemTable.AssignMemoryRecord(Rec : TRESTDWMTMemoryRecord; - Buffer : PRESTDWMTMemBuffer); -var - I : Integer; +{$IFDEF FPC} +Function TRESTDWCustomMemTable.CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Longint; +{$ELSE} +Function TRESTDWCustomMemTable.CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Integer; +{$ENDIF} Begin - Move(Buffer^, Rec.Data^, FRecordSize); - For I := 0 to BlobFieldCount - 1 Do - Begin - If Assigned(FBlobs[I]) Then - Rec.FBlobs[I] := FBlobs[I]; - End; + If Bookmark1 = Bookmark2 Then + Result := 0 + Else If not assigned(Bookmark1) Then + Result := 1 + Else If not assigned(Bookmark2) Then + Result := -1 + Else If assigned(CurrentIndexBuf) Then + Result := CurrentIndexBuf.CompareBookmarks(pointer(Bookmark1),pointer(Bookmark2)) + Else + Result := -1; End; -procedure TRESTDWMemTable.SetMemoryRecordData(Buffer : PRESTDWMTMemBuffer; - Pos : Integer); -var - Rec: TRESTDWMTMemoryRecord; -Begin - If State = dsFilter then - Error('Not Editing...'); - Rec := Records[Pos]; - AssignMemoryRecord(Rec, Buffer); -End; +Procedure TRESTDWCustomMemTable.InitFieldDefsFromPersistentFields; -procedure TRESTDWMemTable.SetAutoIncFields(Buffer: PRESTDWMTMemBuffer); -var - I, Count: Integer; - Data: PByte; -Begin - Count := 0; - for I := 0 to FieldCount - 1 do - If (Fields[I].FieldKind in fkStoredFields) and (Fields[I].datatype = ftAutoInc) then - Begin - Data := FindFieldData(Buffer, Fields[I]); - If Data <> nil then - Begin - Data^ := Ord(True); - Inc(Data); - Move(FAutoInc, Data^, SizeOf(Longint)); - Inc(Count); - End; - End; - If Count > 0 then - Inc(FAutoInc); -End; +Var + I : Integer; + F : TField; -procedure TRESTDWMemTable.InternalDelete; -var - Accept: Boolean; - Status: TRecordStatus; - PFValues: TPVariant; Begin - Status := rsOriginal; // Disable warnings - PFValues := nil; - If FApplyMode <> amNone then + FieldDefs.Clear; + For I := 0 To Fields.Count - 1 Do Begin - Status := TRecordStatus(FieldByName(FStatusName).AsInteger); - If Status <> rsInserted then - Begin - If FApplyMode = amAppend then - Begin - Cancel; - Exit; - End - Else - Begin - New(PFValues); - PFValues^ := GetValues; - End; - End; + F := Fields[I]; + If F.FieldKind = fkData Then + TFieldDef.Create(FieldDefs, + F.FieldName, + F.DataType, + F.Size, + F.Required, + F.FieldNo); End; - If FRecordPos >= FRecords.Count then - Dec(FRecordPos); -// Records[FRecordPos].Free; - FRecords.Delete(FRecordPos); - Accept := True; - If Filtered then - Begin - repeat - Accept := RecordFilter; - If not Accept then - Dec(FRecordPos); - until Accept or (FRecordPos < 0); - End - Else +End; + +{$IFDEF FPC} +Procedure TRESTDWCustomMemTable.NormalizeNumericFieldRanges; + +Var + I : Integer; + Precision : Integer; + Scale : Integer; + IntDigits : Integer; + SMin : String; + SMax : String; + S : String; + V : Extended; + CMin : Currency; + CMax : Currency; + F : TField; + + Function IsZeroValue(Const AValue : String) : Boolean; + Var + Z : String; + Begin + Z:=Trim(AValue); + If Z='' Then Begin - If FRecordPos >= 0 then - Dec(FRecordPos); + Result:=True; + Exit; End; - If FRecords.Count = 0 then - FLastID := Low(Integer); - If FApplyMode <> amNone then - Begin - If Status = rsInserted then - Dec(FRowsChanged) - Else - FDeletedValues.Add(PFValues); - If Status = rsOriginal then - Inc(FRowsChanged); - End; -End; + Z:=StringReplace(Z,'.',DecimalSeparator,[rfReplaceAll]); + Z:=StringReplace(Z,',',DecimalSeparator,[rfReplaceAll]); + Result:=TryStrToFloat(Z,V) and (V=0); + End; + + Function BuildFMTBCDMax(AField : TFMTBCDField) : String; + Begin + Precision:=AField.Precision; + If Precision<=0 Then + Precision:=32; + If Precision>32 Then + Precision:=32; + Scale:=AField.Size; + If Scale<0 Then + Scale:=0; + If Scale>Precision Then + Scale:=Precision; + IntDigits:=Precision-Scale; + If IntDigits>0 Then + Result:=StringOfChar('9',IntDigits) + Else + Result:='0'; + If Scale>0 Then + Result:=Result+DecimalSeparator+StringOfChar('9',Scale); + End; -procedure TRESTDWMemTable.CheckRequiredFields; -var - I: Integer; -begin - for I := 0 to Fields.Count - 1 do - if Fields[I].Required and not Fields[I].ReadOnly and (Fields[I].FieldKind = fkData) and Fields[I].IsNull then - begin - Fields[I].FocusControl; - DatabaseErrorFmt(SFieldRequired, [Fields[I].DisplayName]); - end; -end; - -procedure TRESTDWMemTable.InternalPost; -var - RecPos: Integer; - Index: Integer; - Status: TRecordStatus; - NewChange: Boolean; Begin - Inherited InternalPost; - NewChange := False; - If (FApplyMode <> amNone) and not IsLoading then + For I:=0 To Fields.Count-1 Do Begin - Status := TRecordStatus(FieldByName(FStatusName).AsInteger); - If (State = dsEdit) and (Status In [rsInserted, rsUpdated]) Then - NewChange := False - Else If (State = dsEdit) and (Status = rsOriginal) then + F:=Fields[I]; + If F.FieldKind<>fkData Then + Continue; + + If F is TFMTBCDField Then Begin - If FApplyMode = amAppend then + SMin:=TFMTBCDField(F).MinValue; + SMax:=TFMTBCDField(F).MaxValue; + If IsZeroValue(SMin) and IsZeroValue(SMax) Then Begin - Cancel; - Exit; - End - Else + SMax:=BuildFMTBCDMax(TFMTBCDField(F)); + TFMTBCDField(F).MaxValue:=SMax; + TFMTBCDField(F).MinValue:='-'+SMax; + End; + End + Else If F is TBCDField Then + Begin + If (TBCDField(F).MinValue=0) and + (TBCDField(F).MaxValue=0) Then Begin - NewChange := True; - FieldByName(FStatusName).AsInteger := Integer(rsUpdated); + S:='922337203685477'+DecimalSeparator+'5807'; + CMax:=StrToCurr(S); + CMin:=-CMax; + TBCDField(F).MinValue:=CMin; + TBCDField(F).MaxValue:=CMax; End; - End; - If State = dsInsert then + End + Else If F is TCurrencyField Then Begin - If IsDeleted(Index) then + If (TCurrencyField(F).MinValue=0) and + (TCurrencyField(F).MaxValue=0) Then Begin - FDeletedValues[Index] := nil; - FDeletedValues.Delete(Index); - If FApplyMode = amAppend then - FieldByName(FStatusName).AsInteger := Integer(rsInserted) - Else - FieldByName(FStatusName).AsInteger := Integer(rsUpdated); - End - Else + S:='922337203685477'+DecimalSeparator+'5807'; + CMax:=StrToCurr(S); + CMin:=-CMax; + TCurrencyField(F).MinValue:=CMin; + TCurrencyField(F).MaxValue:=CMax; + End; + End + Else If F is TFloatField Then + Begin + If (TFloatField(F).MinValue=0) and + (TFloatField(F).MaxValue=0) Then Begin - NewChange := True; - FieldByName(FStatusName).AsInteger := Integer(rsInserted); + TFloatField(F).MinValue:=-1.7976931348623157E308; + TFloatField(F).MaxValue:=1.7976931348623157E308; End; - End; - End; - If State = dsEdit then - SetMemoryRecordData(PRESTDWMTMemBuffer(ActiveBuffer), FRecordPos) - Else - Begin - If State in [dsInsert] then - SetAutoIncFields(PRESTDWMTMemBuffer(ActiveBuffer)); - If FRecordPos >= FRecords.Count then + End + Else If F is TLargeintField Then Begin - AddRecord; - FRecordPos := FRecords.Count - 1; - SetMemoryRecordData(PRESTDWMTMemBuffer(ActiveBuffer), FRecordPos); + If (TLargeintField(F).MinValue=0) and + (TLargeintField(F).MaxValue=0) Then + Begin + TLargeintField(F).MinValue:=-9223372036854775808; + TLargeintField(F).MaxValue:=9223372036854775807; + End; End - Else + Else If F is TLongintField Then Begin - If FRecordPos = -1 then - RecPos := 0 - Else - RecPos := FRecordPos; - SetMemoryRecordData(PRESTDWMTMemBuffer(ActiveBuffer), InsertRecord(RecPos).Index); - FRecordPos := RecPos; + If (TLongintField(F).MinValue=0) and + (TLongintField(F).MaxValue=0) Then + Begin + Case F.DataType Of + ftSmallint: + Begin + TLongintField(F).MinValue:=-32768; + TLongintField(F).MaxValue:=32767; + End; + ftWord: + Begin + TLongintField(F).MinValue:=0; + TLongintField(F).MaxValue:=65535; + End; + Else + Begin + TLongintField(F).MinValue:=Low(LongInt); + TLongintField(F).MaxValue:=High(LongInt); + End; + End; + End; End; End; - If NewChange then - Inc(FRowsChanged); -End; - -Procedure TRESTDWMemTable.OpenCursor(InfoQuery: Boolean); -Begin - Try - If FDataSet <> nil then - Begin - If FLoadStructure then - CopyStructure(FDataSet, FAutoIncAsInteger) - Else If FApplyMode <> amNone then - Begin - AddStatusField; - HideStatusField; - End; - End; - Except - SysUtils.Abort; - Exit; - End; - If not InfoQuery then - Begin - If FieldCount > 0 then - FieldDefs.Clear; - InitFieldDefsFromFieldsInternal; - SetLength(FOffsets, 0); - { Calculate fields offsets } - CalcOffSets; -// Inherited InitFieldDefsFromFields; - End; - FActive := True; - Inherited OpenCursor(InfoQuery); - {$IFDEF FPC} - If Not DefaultFields then - If (csDesigning in ComponentState) Then - SetProviderFlags; - {$ENDIF} End; +{$ENDIF} {$IFDEF FPC} -Procedure TRESTDWMemTable.SetProviderFlags; +Procedure TRESTDWCustomMemTable.NormalizeFieldDisplayWidths; + +Const + CMaxDisplayWidth = 255; + Var I : Integer; + F : TField; + Begin - If (Length(FFieldAttrs) > 0) And (Fields.Count > 0) Then + For I:=0 To Fields.Count-1 Do Begin - For I := 0 To Length(FFieldAttrs) -1 Do - Begin - If (Fields.Count > I) Then - Begin - Fields[I].ProviderFlags := []; - If FFieldAttrs[I] And 2 > 0 Then - Fields[I].ProviderFlags := Fields[I].ProviderFlags + [pfInUpdate]; - If FFieldAttrs[I] And 4 > 0 Then - Fields[I].ProviderFlags := Fields[I].ProviderFlags + [pfInWhere]; - If FFieldAttrs[I] And 8 > 0 Then - Fields[I].ProviderFlags := Fields[I].ProviderFlags + [pfInKey]; - If FFieldAttrs[I] And 16 > 0 Then - Fields[I].ProviderFlags := Fields[I].ProviderFlags + [pfHidden]; - {$IFDEF RESTDWLAZARUS} - If FFieldAttrs[I] And 32 > 0 Then - Fields[I].ProviderFlags := Fields[I].ProviderFlags + [pfRefreshOnInsert]; - If FFieldAttrs[I] And 64 > 0 Then - Fields[I].ProviderFlags := Fields[I].ProviderFlags + [pfRefreshOnUpdate]; - {$ENDIF} - End; - End; + F:=Fields[I]; + If F.FieldKind<>fkData Then + Continue; + Case F.DataType Of + ftString, + ftFixedChar, + ftWideString, + ftFixedWideChar, + ftMemo, + ftWideMemo: + Begin + If F.DisplayWidth>CMaxDisplayWidth Then + F.DisplayWidth:=CMaxDisplayWidth; + End; + End; End; End; {$ENDIF} -procedure TRESTDWMemTable.InternalOpen; +Procedure TRESTDWCustomMemTable.IntLoadFieldDefsFromFile; + Begin - BookmarkSize := SizeOf(TRESTDWMTBookmarkData); - FieldDefs.Updated := False; - FieldDefs.Update; - {$IFNDEF FPC} - FieldDefList.Update; - {$ENDIF} - If DefaultFields then - CreateFields - {$IFDEF FPC} - Else If (csDesigning in ComponentState) Then - SetProviderFlags - {$ENDIF}; - {$IFDEF FPC} - CalcOffSets; - {$ENDIF} - InitBufferPointers(True); - BindFields(True); - InternalFirst; - FAllPacketsFetched := False; + FReadFromFile := True; + If not assigned(FDatasetReader) Then + Begin + FFileStream := TFileStream.Create(FileName, fmOpenRead); + FDatasetReader := GetPacketReader(dfDefault, FFileStream); + End; + + FieldDefs.Clear; + FDatasetReader.LoadFieldDefs(FAutoIncValue); + If (FieldDefs.Count = 0) and (Fields.Count > 0) Then + InitFieldDefsFromPersistentFields; + If DefaultFields Then + Begin + CreateFields; +{$IFNDEF FPC} + BindFields(True); +{$ENDIF} + End + Else + BindFields(True); End; -Procedure TRESTDWMemTable.CreateFields; +Procedure TRESTDWCustomMemTable.IntLoadRecordsFromFile; + Var - I : Integer; - Field : TField; + SavedState : TDataSetState; + ARowState : TRESTDWMemRowState; + AUpdOrder : integer; + i : integer; + DefIdx : TRESTDWMemInternalIndex; + Begin -// Inherited CreateFields; - For I := 0 To FieldDefs.Count -1 Do + CheckBiDirectional; + DefIdx:=DefaultBufferIndex; + FDatasetReader.InitLoadRecords; + SavedState:=SetTempState(dsFilter); + + While FDatasetReader.GetCurrentRecord Do Begin - If FieldDefs[I].DataType = {$IFNDEF FPC}ftExtended{$ELSE}ftFMTBcd{$ENDIF} Then - Field := TRESTDWNumericField.Create(Self) - Else If FieldDefs[I].DataType = {$IFNDEF FPC}ftString{$ELSE}ftFixedChar{$ENDIF} Then + ARowState := FDatasetReader.GetRecordRowState(AUpdOrder); + If rsvOriginal in ARowState Then Begin - Field := TStringFieldRESTDW.Create(Self); - Field.Size := FieldDefs[I].Size; + If length(FUpdateBuffer) < (AUpdOrder+1) Then + SetLength(FUpdateBuffer,AUpdOrder+1); + + FCurrentUpdateBuffer:=AUpdOrder; + + FFilterBuffer:=IntAllocRecordBuffer; + fillchar(FFilterBuffer^,FNullmaskSize,0); + FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := FFilterBuffer; + FDatasetReader.RestoreRecord; + + FDatasetReader.GotoNextRecord; + If not FDatasetReader.GetCurrentRecord Then + DatabaseError(SStreamNotRecognised,Self); + ARowState := FDatasetReader.GetRecordRowState(AUpdOrder); + If rsvUpdated in ARowState Then + FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind:= ukModify + Else + DatabaseError(SStreamNotRecognised,Self); + + FFilterBuffer:=DefIdx.SpareBuffer; + DefIdx.StoreSpareRecIntoBookmark(@FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData); + fillchar(FFilterBuffer^,FNullmaskSize,0); + + FDatasetReader.RestoreRecord; + DefIdx.AddRecord; + inc(FBRecordCount); End - Else If FieldDefs[I].DataType in [{$IFNDEF FPC}ftStream, {$ENDIF}ftBlob, ftMemo, ftWideMemo] Then + Else If rsvDeleted in ARowState Then Begin - Field := TStreamField.Create(Self); -// Field.Size := FieldDefs[I].Size; + If length(FUpdateBuffer) < (AUpdOrder+1) Then + SetLength(FUpdateBuffer,AUpdOrder+1); + + FCurrentUpdateBuffer:=AUpdOrder; + + FFilterBuffer:=IntAllocRecordBuffer; + fillchar(FFilterBuffer^,FNullmaskSize,0); + + FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := FFilterBuffer; + FDatasetReader.RestoreRecord; + + FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind:= ukDelete; + DefIdx.StoreSpareRecIntoBookmark(@FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData); + DefIdx.AddRecord; + DefIdx.RemoveRecordFromIndex(FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData); + DefIdx.StoreSpareRecIntoBookmark(@FUpdateBuffer[FCurrentUpdateBuffer].NextBookmarkData); + + For i := FCurrentUpdateBuffer+1 To high(FUpdateBuffer) Do + If DefIdx.SameBookmarks(@FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData, @FUpdateBuffer[i].NextBookmarkData) Then + DefIdx.StoreSpareRecIntoBookmark(@FUpdateBuffer[i].NextBookmarkData); End Else Begin - {$IFNDEF FPC} - Field := FieldDefs[I].CreateField(Self, Nil, FieldDefs[I].Name); - SetFieldProps(Field, FieldDefs[I]); - {$ELSE} - Field := FieldDefs[I].CreateField(Self); - Field.SetFieldType(FieldDefs[I].DataType); - {$ENDIF} - End; - Field.FieldName := FieldDefs[I].Name; - Field.DisplayLabel := FieldDefs[I].Name; - Field.DataSet := Self; - If Length(FFieldAttrs) > I Then - Begin - Field.ProviderFlags := []; - If FFieldAttrs[I] And 2 > 0 Then - Field.ProviderFlags := Field.ProviderFlags + [pfInUpdate]; - If FFieldAttrs[I] And 4 > 0 Then - Field.ProviderFlags := Field.ProviderFlags + [pfInWhere]; - If FFieldAttrs[I] And 8 > 0 Then - Field.ProviderFlags := Field.ProviderFlags + [pfInKey]; - If FFieldAttrs[I] And 16 > 0 Then - Field.ProviderFlags := Field.ProviderFlags + [pfHidden]; - {$IFDEF RESTDWLAZARUS} - If FFieldAttrs[I] And 32 > 0 Then - Field.ProviderFlags := Field.ProviderFlags + [pfRefreshOnInsert]; - If FFieldAttrs[I] And 64 > 0 Then - Field.ProviderFlags := Field.ProviderFlags + [pfRefreshOnUpdate]; - {$ENDIF} + FFilterBuffer:=DefIdx.SpareBuffer; + fillchar(FFilterBuffer^,FNullmaskSize,0); + FDatasetReader.RestoreRecord; + If rsvInserted in ARowState Then + Begin + If length(FUpdateBuffer) < (AUpdOrder+1) Then + SetLength(FUpdateBuffer,AUpdOrder+1); + FCurrentUpdateBuffer:=AUpdOrder; + FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind:= ukInsert; + DefIdx.StoreSpareRecIntoBookmark(@FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData); + End; + + DefIdx.AddRecord; + inc(FBRecordCount); End; + + FDatasetReader.GotoNextRecord; End; - SetLength(FFieldName, 0); - SetLength(FFieldName, Fields.Count); - For I := 0 To Fields.Count -1 Do + + RestoreState(SavedState); + DefIdx.SetToFirstRecord; + FAllPacketsFetched:=True; + If assigned(FFileStream) Then Begin - FFieldName[I] := Fields[I].FieldName; - {$IFNDEF FPC} - {$IF CompilerVersion >= 20} - If Fields[I].datatype = ftSingle Then - TFloatField(Fields[I]).Precision := 17; - {$IFEND} - {$ENDIF} + FreeAndNil(FFileStream); + FreeAndNil(FDatasetReader); End; + + // rebuild indexes + BuildIndexes; End; -procedure TRESTDWMemTable.DoAfterOpen; +Procedure TRESTDWCustomMemTable.DoFilterRecord(out Acceptable: Boolean); Begin - If (FDataSet <> nil) and FLoadRecords then - Begin - If not FDataSet.Active then - FDataSet.Open; - FRowsOriginal := CopyFromDataSet; - If FRowsOriginal > 0 then - Begin - SortOnFields(); - If FApplyMode = amAppend then - Last - Else - First; - End; - If FDataSet.Active and FDataSetClosed then - FDataSet.Close; - End - Else If Not IsEmpty then - SortOnFields(); - Inherited DoAfterOpen; -End; + Acceptable := true; + // check user filter + If Assigned(OnFilterRecord) Then + OnFilterRecord(Self, Acceptable); -procedure TRESTDWMemTable.SetFilterText(const Value: String); - Procedure UpdateFilter; - Begin - FreeAndNil(FFilterParser); -{$IFNDEF FPC} - FreeAndNil(FFilterExpression); -{$ENDIF} - If Filter <> '' then - Begin -{$IFNDEF FPC} -// // If UseDataSetFilter then - // FFilterExpression := TRESTDWMTDBFilterExpression.Create(Self, Value, FilterOptions) - FFilterExpression:=TRDWABExprParser.Create(self,Value,FilterOptions); -// Else -// Begin -{$ELSE} - FFilterParser := TExprParser.Create; -{$ENDIF} -{$IFNDEF FPC} - //FFilterParser.OnGetVariable := ParserGetVariableValue; -{$ELSE} - FFilterParser.OnGetVariable := @ParserGetVariableValue; -{$ENDIF} -{$IFDEF FPC} - If foCaseInsensitive in FilterOptions then - FFilterParser.Expression := AnsiUpperCase(Filter) - Else - FFilterParser.Expression := Filter; -{$ENDIF} -{$IFNDEF FPC} - // End; -{$ENDIF} - End; - End; + // check filtertext + If Acceptable and (Length(Filter) > 0) Then + Acceptable := Boolean((FParser.ExtractFromBuffer(GetCurrentBuffer))^); +End; +Procedure TRESTDWCustomMemTable.SetFilterText(Const Value: String); Begin - If Active then - Begin - CheckBrowseMode; - inherited SetFilterText(Value); - UpdateFilter; - If Filtered then - First; - End - Else - Begin - inherited SetFilterText(Value); - UpdateFilter; - End; + If Value = Filter Then + Exit; + + // parse + ParseFilter(Value); + + // call dataset method + Inherited; + + // refilter dataset if filtered + If IsCursorOpen and Filtered Then + Resync([]); End; -function TRESTDWMemTable.ParserGetVariableValue(Sender: TObject; - const VarName: String; var Value: Variant): Boolean; -var - Field: TField; +Procedure TRESTDWCustomMemTable.SetFiltered(Value: Boolean); {override;} Begin - Field := FieldByName(VarName); - If Assigned(Field) then - Begin - Value := Field.Value; - Result := True; - End - Else - Result := False; + If Value = Filtered Then + Exit; + + // pass on to ancestor + Inherited; + + // only refresh if active + If IsCursorOpen Then + Resync([]); End; -procedure TRESTDWMemTable.InternalClose; +Procedure TRESTDWCustomMemTable.InternalRefresh; + +Var + StoreDefaultFields: boolean; + Begin - ClearBuffer; -// SetLength(FFieldAttrs, 0); - BindFields(False); - FAutoInc := 1; - If DefaultFields then - DestroyFields; + If length(FUpdateBuffer)>0 Then + DatabaseError(SErrApplyUpdBeforeRefresh,Self); + FRefreshing:=True; + Try + StoreDefaultFields:=DefaultFields; + SetDefaultFields(False); FreeFieldBuffers; - FActive := False; - FBlobOfs := 0; - FDataSetClosed := True; - DataEvent(deUpdateRecord, 0); - If Assigned(FDataSet) Then - FreeAndNil(FDataSet); + ClearBuffers; + InternalClose; + BeforeRefreshOpenCursor; + InternalOpen; + SetDefaultFields(StoreDefaultFields); + Finally + FRefreshing:=False; +End; End; -procedure TRESTDWMemTable.InternalHandleException; +Procedure TRESTDWCustomMemTable.BeforeRefreshOpenCursor; Begin - AppHandleException(Self); + // Do nothing End; -procedure TRESTDWMemTable.InternalInitFieldDefs; +Procedure TRESTDWCustomMemTable.DataEvent(Event: TDataEvent; Info: TRESTDWPtrInt); Begin - If (csDesigning in ComponentState) - {$IFNDEF FPC}and Assigned(Designer){$ENDIF} Then - DesignNotify('', 102); - InitFieldDefsFromFieldsInternal; -// Inherited InitFieldDefsFromFields; + If Event = deUpdateState Then + // Save DataSet.State set by DataSet.SetState (filter out State set by DataSet.SetTempState) + FSavedState := State; + Inherited; End; -Function TRESTDWMemTable.IsLookup(Index: Integer): Boolean; +Function TRESTDWCustomMemTable.Fetch: boolean; Begin - Result := Fields[Index].FieldKind in [fkCalculated, fkLookup]; + // Empty procedure to make it possible to use TRESTDWCustomMemTable as a memory dataset + Result := False; End; -Procedure TRESTDWMemTable.DesignNotify(const AFieldName: string; Dummy: Integer); -var - Field: TField; -begin - If not (csDesigning in ComponentState) then Exit; - Case Dummy of - 104 : Begin - If IsLookup(GetFieldIndex(AFieldName)) Then - Begin - Field := FieldByName(AFieldName); - Field.FieldKind := fkLookup; - End; - End; - 106 : Begin - Try - InternalInitFieldDefs; - Except - End; - End; - Else FDsgnFieldName := AFieldName; - End; +Procedure TRESTDWCustomMemTable.LoadBlobIntoBuffer(FieldDef: TFieldDef; + ABlobBuf: PRESTDWMemBlobField); +Begin End; -function TRESTDWMemTable.IsCursorOpen: Boolean; +{$IFNDEF FPC} +Procedure TRESTDWCustomMemTable.InternalHandleException; Begin - Result := FActive; + If ExceptObject Is Exception Then + Raise Exception.Create(Exception(ExceptObject).Message); End; +{$ENDIF} -function TRESTDWMemTable.GetRecordCount: Integer; +Function TRESTDWCustomMemTable.LoadField(FieldDef: TFieldDef; buffer: pointer; out + CreateBlob: boolean): boolean; Begin - Result := 0; - If State <> dsInactive then - Result := FRecords.Count; + // Empty procedure to make it possible to use TRESTDWCustomMemTable as a memory dataset + CreateBlob := False; + Result := False; End; -function TRESTDWMemTable.GetRecNo: Integer; +Function TRESTDWCustomMemTable.IsReadFromPacket: Boolean; Begin - CheckActive; - UpdateCursorPos; - If (filtered) And - (TRESTDWMemTableEx(Self).GetFilteredRecordCount > 0) Then - Begin - If (FRecordFilterPos = -1) Then - Result := 1 - Else - Result := FRecordFilterPos; - End - Else If (FRecordPos = -1) and (RecordCount > 0) then - Result := 1 - Else - Result := FRecordPos + 1; + Result := (FDatasetReader<>nil) or (FFileName<>'') or FReadFromFile; End; -procedure TRESTDWMemTable.SetRecNo(Value: Integer); +Procedure TRESTDWCustomMemTable.ParseFilter(Const AFilter: string); Begin - If (Value > 0) and (Value <= FRecords.Count) then + // parser created? + If Length(AFilter) > 0 Then Begin - DoBeforeScroll; - FRecordPos := Value - 1; - Resync([]); - DoAfterScroll; + If (FParser = nil) and IsCursorOpen Then + Begin + FParser := TRESTDWMemParser.Create(Self); + End; + // is there a parser now? + If FParser <> nil Then + Begin + // set options + FParser.PartialMatch := not (foNoPartialCompare in FilterOptions); + FParser.CaseInsensitive := foCaseInsensitive in FilterOptions; + // parse expression + FParser.ParseExpression(AFilter); + End; End; End; -function TRESTDWMemTable.IsSequenced: Boolean; -Begin - Result := not Filtered; -End; +Function TRESTDWCustomMemTable.Locate(Const KeyFields: string; Const KeyValues: Variant; Options: TLocateOptions): boolean; -function TRESTDWMemTable.Locate(const KeyFields: String; - const KeyValues: Variant; Options: TLocateOptions): Boolean; Begin - DoBeforeScroll; - Result := DataSetLocateThrough(Self, KeyFields, KeyValues, Options); - If Result then - Begin - DataEvent(deDataSetChange, 0); - DoAfterScroll; - End; + Result:=DoLocate(keyfields,KeyValues,Options,True); End; -function TRESTDWMemTable.Lookup(const KeyFields: String; - const KeyValues: Variant; const ResultFields: String): Variant; -Var - aFieldCount : Integer; - {$IFNDEF FPC} - aFields: TList{$IFDEF RTL240_UP}{$ENDIF RTL240_UP}; - {$ELSE} - aFields: TFields; - {$ENDIF} - Fld : TField; - SaveState : TDataSetState; - I : Integer; - Matched : Boolean; - aPointer : Pointer; - aKeyFieldName : String; - Function CompareField(Field : TField; - Value : Variant): Boolean; - Var - S : string; - Begin - If Field.datatype in [ftString{$IFDEF UNICODE}, ftWideString, ftFixedWideChar{$ENDIF}] Then - Begin - If Value = Null then - Result := Field.IsNull - Else - Begin - S := Field.AsString; - Result := AnsiSameStr(S, Value); - End; - End - Else - Result := (Field.Value = Value); - End; - Function CompareRecord(KeyFieldnames : String) : Boolean; - Var - A : Integer; - aTemFields, - aFieldName : String; - Begin - aTemFields := KeyFieldnames; - While aTemFields <> '' Do - Begin - If Pos(';', aTemFields) > 0 Then - Begin - aFieldName := Trim(Copy(aTemFields, 1, Pos(';', aTemFields)-1)); - DeleteStr(aTemFields, 1, Pos(';', aTemFields)); - End - Else - Begin - aFieldName := Trim(Copy(aTemFields, 1, Length(aTemFields))); - aTemFields := ''; - End; - If aFieldCount = 1 then - Begin - Fld := TField(Fields.FindField(aFieldName)); - Result := CompareField(Fld, KeyValues); - End - Else - Begin - Result := True; - For A := 0 to Length(KeyValues) -1 do - Begin - Fld := TField(Fields.FindField(aFieldName)); - Result := Result and CompareField(Fld, KeyValues[A]); - End; - End; - End; - End; +Function TRESTDWCustomMemTable.DoLocate(Const KeyFields: string; Const KeyValues: Variant; Options: TLocateOptions; DoEvents : Boolean) : boolean; + + +Var SearchFields : TList; + DBCompareStruct : TRESTDWMemCompareStruct; + ABookmark : TRESTDWMemBookmark; + SavedState : TDataSetState; + FilterRecord : TRecordBuffer; + FilterAcceptable: boolean; + Begin - CheckBrowseMode; - aPointer := @Result; + // Call inherited to make sure the dataset is bi-directional + Result := Inherited Locate(KeyFields,KeyValues,Options); + CheckActive; If IsEmpty Then - Exit; - {$IFNDEF FPC} - aFields := TList{$IFDEF RTL240_UP}{$ENDIF RTL240_UP}.Create; - {$ELSE} - aFields := TFields.Create(Nil); - {$ENDIF} - Try - {$IFNDEF FPC} - GetFieldList(aFields, KeyFields); - {$ELSE} - GetFieldList(TList(aFields), KeyFields); - {$ENDIF} - aFieldCount := aFields.Count; - For I := 0 To aFieldCount -1 Do + exit; + + // Build the DBCompare structure + SearchFields := TList.Create; + Try + GetFieldList(SearchFields,KeyFields); + If SearchFields.Count=0 Then + exit; + ProcessFieldsToCompareStruct(SearchFields, nil, nil, [], Options, DBCompareStruct); + Finally + SearchFields.Free; +End; + + // Set the filter buffer + SavedState:=SetTempState(dsFilter); + FilterRecord:=IntAllocRecordBuffer; + FFilterBuffer:=FilterRecord + BufferOffset; +{$IFDEF FPC} + SetFieldValues(KeyFields,KeyValues); +{$ELSE} + RESTDWSetFieldValues(Self, KeyFields, KeyValues); +{$ENDIF} + + // Iterate through the records until a match is found + ABookmark.BookmarkData:=nil; + While true Do + Begin + // try get next record + If CurrentIndexBuf.GetRecord(@ABookmark, gmNext) <> grOK Then + // for grEOF ABookmark points to SpareRecord, which is used for storing next record(s) + If getnextpacket = 0 Then + Break; + If IndexCompareRecords(FilterRecord, ABookmark.BookmarkData, DBCompareStruct) = 0 Then Begin - If I = 0 Then + If Filtered Then Begin - aKeyFieldName := {$IFNDEF FPC} - {$IF CompilerVersion > 21} - aFields[I].FieldName; - {$ELSE} - TField(aFields.Items[I]).FieldName; - {$IFEND} - {$ELSE} - aFields[I].FieldName; - {$ENDIF} + FFilterBuffer:=Pointer(TRESTDWPtrInt(ABookmark.BookmarkData) + BufferOffset); + // The dataset state is still dsFilter at this point, so we don't have to set it. + DoFilterRecord(FilterAcceptable); + If FilterAcceptable Then + Begin + Result := True; + Break; + End; End Else - aKeyFieldName := aKeyFieldName + ';' + {$IFNDEF FPC} - {$IF CompilerVersion > 21} - aFields[I].FieldName; - {$ELSE} - TField(aFields.Items[I]).FieldName; - {$IFEND} - {$ELSE} - aFields[I].FieldName; - {$ENDIF}; + Begin + Result := True; + Break; + End; End; - Matched := CompareRecord(aKeyFieldName); - If Matched Then - Variant(aPointer^) := FieldValues[ResultFields] + End; + + RestoreState(SavedState); + FreeRecordBuffer(FilterRecord); + + // If a match is found, jump to the found record + If Result Then + Begin + ABookmark.BookmarkFlag := bfCurrent; + If DoEvents Then + Begin + InternalGotoBookmark(@ABookmark); + Resync([rmExact,rmCenter]); + End Else Begin - SaveState := SetTempState(dsCalcFields); - Try - Try - For I := 0 To RecordCount - 1 Do - Begin - RecordToBuffer(Records[I], PRESTDWMTMemBuffer(TempBuffer)); - CalculateFields(TempBuffer); - Matched := CompareRecord(aKeyFieldName); - If Matched Then - Break; - End; - Finally - If Matched Then - Variant(aPointer^) := FieldValues[ResultFields]; - End; - Finally - RestoreState(SaveState); - End; + InternalGotoBookMark(@ABookmark); + Resync([rmExact,rmCenter]); End; - Finally - FreeAndNil(aFields); End; End; -procedure TRESTDWMemTable.AfterLoad; +Function TRESTDWCustomMemTable.Lookup(Const KeyFields: string; + Const KeyValues: Variant; Const ResultFields: string): Variant; +Var + bm:TBookmark; Begin - Try - SetState(dsInactive); - Finally - SetState(dsBrowse); - End; + result:=Null; + If IsEmpty Then + Exit; + bm:=GetBookmark; + DisableControls; + Try + If DoLocate(KeyFields,KeyValues,[],False) Then + Begin + // CalculateFields(ActiveBuffer); // not needed, done by Locate more than once + result:=FieldValues[ResultFields]; + End; + InternalGotoBookMark(pointer(bm)); + Resync([rmExact,rmCenter]); + FreeBookmark(bm); + Finally + EnableControls; +End; End; -procedure TRESTDWMemTable.Notification(AComponent: TComponent; - Operation: TOperation); +{ TRESTDWMemArrayIndex } + +Function TRESTDWMemArrayIndex.GetBookmarkSize: integer; Begin - inherited Notification(AComponent, Operation); + Result:=Sizeof(TRESTDWMemBookmark); End; -procedure TRESTDWMemTable.EmptyTable; +Function TRESTDWMemArrayIndex.GetCurrentBuffer: Pointer; Begin - If Active then - Begin - CheckBrowseMode; - ClearRecords; - ClearBuffers; - DataEvent(deDataSetChange, 0); - End; + Result:=TRecordBuffer(FRecordArray[FCurrentRecInd]); +End; + +Function TRESTDWMemArrayIndex.GetCurrentRecord: TRecordBuffer; +Begin + Result:=GetCurrentBuffer; +End; + +Function TRESTDWMemArrayIndex.GetIsInitialized: boolean; +Begin + Result:=Length(FRecordArray)>0; +End; + +Function TRESTDWMemArrayIndex.GetSpareBuffer: TRecordBuffer; +Begin + If FLastRecInd>-1 Then + Result:= TRecordBuffer(FRecordArray[FLastRecInd]) + Else + Result := nil; +End; + +Function TRESTDWMemArrayIndex.GetSpareRecord: TRecordBuffer; +Begin + Result := GetSpareBuffer; +End; + +Constructor TRESTDWMemArrayIndex.Create(Const ADataset: TRESTDWCustomMemTable); +Begin + Inherited create(ADataset); + FInitialBuffers:=10000; + FGrowBuffer:=1000; End; -procedure TRESTDWMemTable.AddStatusField; +Function TRESTDWMemArrayIndex.ScrollBackward: TGetResult; Begin - // Check If FieldStatus not exists in FieldDefs - If (FieldDefs.Count > 0) and not(FieldDefs[FieldDefs.Count - 1].Name = FStatusName) then - FieldDefs.Add(FStatusName, ftSmallint); + If FCurrentRecInd>0 Then + Begin + dec(FCurrentRecInd); + Result := grOK; + End + Else + Result := grBOF; End; -procedure TRESTDWMemTable.HideStatusField; +Function TRESTDWMemArrayIndex.ScrollForward: TGetResult; Begin - // Check If FieldStatus already exists in FieldDefs - If (FieldDefs.Count > 0) and (FieldDefs[FieldDefs.Count - 1].Name = FStatusName) then + If FCurrentRecInd = FLastRecInd-1 Then + result := grEOF + Else Begin - FieldDefs[FieldDefs.Count - 1].Attributes := [faHiddenCol]; // Hide in FieldDefs - // Check If FieldStatus not exists in Fields - If not(Fields[Fields.Count - 1].FieldName = FStatusName) then - FieldDefs[FieldDefs.Count - 1].CreateField(Self); - Fields[Fields.Count - 1].Visible := False; // Hide in Fields + Result:=grOK; + inc(FCurrentRecInd); End; End; -procedure TRESTDWMemTable.CheckStructure(UseAutoIncAsInteger: Boolean); - Procedure CheckDataTypes(FieldDefs: TFieldDefs); - var - J: Integer; +Function TRESTDWMemArrayIndex.GetCurrent: TGetResult; +Begin + If FLastRecInd=0 Then + Result := grError + Else Begin - for J := FieldDefs.Count - 1 downto 0 do - Begin - If (FieldDefs.Items[J].datatype = ftAutoInc) and UseAutoIncAsInteger then - FieldDefs.Items[J].datatype := ftInteger; - If not(FieldDefs.Items[J].datatype in ftSupported) then - FieldDefs.Items[J].Free; - End; + Result := grOK; + If FCurrentRecInd = FLastRecInd Then + dec(FCurrentRecInd); End; +End; -var - I: Integer; +Function TRESTDWMemArrayIndex.ScrollFirst: TGetResult; Begin - CheckDataTypes(FieldDefs); - for I := 0 to FieldDefs.Count - 1 do - If (csDesigning in ComponentState) and (Owner <> nil) then - FieldDefs.Items[I].CreateField(Owner) - Else - FieldDefs.Items[I].CreateField(Self); + FCurrentRecInd:=0; + If (FCurrentRecInd = FLastRecInd) Then + result := grEOF + Else + result := grOk; End; -procedure TRESTDWMemTable.ClearBuffer; +Procedure TRESTDWMemArrayIndex.ScrollLast; Begin - ClearRecords; - ClearBuffers; - DataEvent(deDataSetChange, 0); + FCurrentRecInd:=FLastRecInd; End; -procedure TRESTDWMemTable.FixReadOnlyFields(MakeReadOnly: Boolean); -var - I: Integer; +Procedure TRESTDWMemArrayIndex.SetToFirstRecord; Begin - If MakeReadOnly then - for I := 0 to FieldCount - 1 do - Fields[I].ReadOnly := (Fields[I].Tag = 1) - Else - for I := 0 to FieldCount - 1 do - Begin - Fields[I].Tag := Ord(Fields[I].ReadOnly); - Fields[I].ReadOnly := False; - End; + // if FCurrentRecBuf = FLastRecBuf then the dataset is just opened and empty + // in which case InternalFirst should do nothing (bug 7211) + If FCurrentRecInd <> FLastRecInd Then + FCurrentRecInd := -1; End; -procedure TRESTDWMemTable.CopyStructure(Source: TDataset; - UseAutoIncAsInteger: Boolean); -var - I: Integer; +Procedure TRESTDWMemArrayIndex.SetToLastRecord; Begin - If Source = nil then - Exit; - CheckInactive; - for I := FieldCount - 1 downto 0 do - Fields[I].Free; - Source.FieldDefs.Update; - FieldDefs := Source.FieldDefs; - If FApplyMode <> amNone then - AddStatusField; - CheckStructure(UseAutoIncAsInteger); - If FApplyMode <> amNone then - HideStatusField; -End; - -function TRESTDWMemTable.LoadFromDataSet(Source: TDataset; - aRecordCount: Integer; Mode: TLoadMode; DisableAllControls: Boolean): Integer; -var - MovedCount, I, FinalAutoInc: Integer; - SB, DB: TBookmark; + If FLastRecInd <> 0 Then + FCurrentRecInd := FLastRecInd; +End; + +Procedure TRESTDWMemArrayIndex.StoreCurrentRecord; Begin - Result := 0; - If Source = Self then - Exit; - FSaveLoadState := slsLoading; - // ********** Source ********* - If DisableAllControls then - Source.DisableControls; - If not Source.Active then - Source.Open - Else - Source.CheckBrowseMode; - Source.UpdateCursorPos; - SB := Source.GetBookmark; - // *************************** - Try - // ********** Dest (self) *********** - If DisableAllControls then - DisableControls; - Filtered := False; - If Mode = lmCopy then - Begin - Close; - CopyStructure(Source, FAutoIncAsInteger); - End; - FreeIndexList; - If not Active then - Open - Else - CheckBrowseMode; - DB := GetBookmark; - // ********************************** - Try - If aRecordCount > 0 then - MovedCount := aRecordCount - Else - Begin - Source.First; - MovedCount := MaxInt; - End; - FinalAutoInc := 0; - FixReadOnlyFields(False); - // find first source autoinc field - FSrcAutoIncField := nil; - If Mode = lmCopy then - for I := 0 to Source.FieldCount - 1 do - If Source.Fields[I].datatype = ftAutoInc then - Begin - FSrcAutoIncField := Source.Fields[I]; - Break; - End; - Try - while not Source.EOF do - Begin - AppEnd; - AssignRecord(Source, Self, True); - // assign AutoInc value manually (make user keep largest If source isn't sorted by autoinc field) - If FSrcAutoIncField <> nil then - Begin - FinalAutoInc := Max(FinalAutoInc, FSrcAutoIncField.AsInteger); - FAutoInc := FSrcAutoIncField.AsInteger; - End; - If (Mode = lmCopy) and (FApplyMode <> amNone) then - FieldByName(FStatusName).AsInteger := Integer(rsOriginal); - Post; - Inc(Result); - If Result >= MovedCount then - Break; - Source.Next; - End; - Finally - If (Mode = lmCopy) and (FApplyMode <> amNone) then - Begin - FRowsOriginal := Result; - FRowsChanged := 0; - FRowsAffected := 0; - End; - FixReadOnlyFields(True); - If Mode = lmCopy then - FAutoInc := FinalAutoInc + 1; - FSrcAutoIncField := nil; - First; - End; - Finally - // ********** Dest (self) *********** - // move back to where we started from - If (DB <> nil) and BookmarkValid(DB) then - Begin - GotoBookmark(DB); - FreeBookmark(DB); - End; - If DisableAllControls then - EnableControls; - // ********************************** - End; - Finally - // ************** Source ************** - // move back to where we started from - If (SB <> nil) and Source.BookmarkValid(SB) and not Source.IsEmpty then - Begin - Source.GotoBookmark(SB); - Source.FreeBookmark(SB); - End; - //If Source.Active and FDataSetClosed then - // Source.Close; - If DisableAllControls then - Source.EnableControls; - // ************************************ - FSaveLoadState := slsNone; - End; + FStoredRecBuf := FCurrentRecInd; +End; + +Procedure TRESTDWMemArrayIndex.RestoreCurrentRecord; +Begin + FCurrentRecInd := FStoredRecBuf; End; -procedure TRESTDWMemTable.LoadFromStream(stream: TStream); -var - stor: TRESTDWStorageBin; +Function TRESTDWMemArrayIndex.CanScrollForward: Boolean; Begin - If FStorageDataType = nil then - Begin - stor := TRESTDWStorageBin.Create(nil); - Try - //stream.Seek( 0, TSeekOrigin.soBeginning ); - //stream.Position := 0; - stor.LoadFromStream(Self, stream); - Finally - stor.Free; - //stream := Nil; - //stream.Free; - End; - End - Else + Result := (FCurrentRecInd < FLastRecInd-1); +End; + +Procedure TRESTDWMemArrayIndex.DoScrollForward; +Begin + inc(FCurrentRecInd); +End; + +Procedure TRESTDWMemArrayIndex.StoreCurrentRecIntoBookmark(Const ABookmark: PRESTDWMemBookmark); +Begin + With ABookmark^ Do Begin - FStorageDataType.LoadFromStream(Self, stream); + BookmarkInt := FCurrentRecInd; + BookmarkData := FRecordArray[FCurrentRecInd]; End; End; -function TRESTDWMemTable.SaveToDataSet(Dest: TDataset; aRecordCount: Integer; - DisableAllControls: Boolean): Integer; -var - MovedCount: Integer; - SB, DB: TBookmark; - Status: TRecordStatus; +Procedure TRESTDWMemArrayIndex.StoreSpareRecIntoBookmark(Const ABookmark: PRESTDWMemBookmark + ); Begin - Result := 0; - FRowsAffected := Result; - If Dest = Self then - Exit; - FSaveLoadState := slsSaving; - // *********** Dest ************ - If DisableAllControls then - Dest.DisableControls; - If not Dest.Active then - Dest.Open - Else - Dest.CheckBrowseMode; - Dest.UpdateCursorPos; - DB := Dest.GetBookmark; - SB := nil; - // ***************************** - Try - // *********** Source (self) ************ - If DisableAllControls then - DisableControls; - CheckBrowseMode; - If FApplyMode <> amNone then - Begin - FRowsChanged := Self.RecordCount; - DoBeforeApply(Dest, FRowsChanged); - End - Else - Begin - SB := GetBookmark; - End; - // ************************************** - Try - If aRecordCount > 0 then - MovedCount := aRecordCount - Else - Begin - First; - MovedCount := MaxInt; - End; - Status := rsOriginal; // Disable warnings - Try - while not EOF do - Begin - If FApplyMode <> amNone then - Begin - Status := TRecordStatus(FieldByName(FStatusName).AsInteger); - DoBeforeApplyRecord(Dest, Status, True); - End; - Dest.AppEnd; - AssignRecord(Self, Dest, True); - Dest.Post; - Inc(Result); - If FApplyMode <> amNone then - DoAfterApplyRecord(Dest, Status, True); - If Result >= MovedCount then - Break; - Next; - End; - Finally - If FApplyMode <> amNone then - Begin - FRowsAffected := Result; - DoAfterApply(Dest, FRowsAffected); - If Result > 0 then - ClearChanges; - FRowsAffected := 0; - FRowsChanged := 0; - End - End; - Finally - // *********** Source (self) ************ - If (FApplyMode = amNone) and (SB <> nil) and BookmarkValid(SB) then - Begin - GotoBookmark(SB); - FreeBookmark(SB); - End; - If DisableAllControls then - EnableControls; - // ************************************** - End; - Finally - // ******************* Dest ******************* - // move back to where we started from - If (DB <> nil) and Dest.BookmarkValid(DB) and not Dest.IsEmpty then - Begin - Dest.GotoBookmark(DB); - Dest.FreeBookmark(DB); - End; - If Dest.Active and FDataSetClosed then - Dest.Close; - If DisableAllControls then - Dest.EnableControls; - // ******************************************** - FSaveLoadState := slsNone; + With ABookmark^ Do + Begin + BookmarkInt := FLastRecInd; + BookmarkData := FRecordArray[FLastRecInd]; End; End; -procedure TRESTDWMemTable.SaveToStream(var stream: TStream); -var - stor: TRESTDWStorageBin; +Function TRESTDWMemArrayIndex.GetRecordFromBookmark(ABookmark: TRESTDWMemBookmark): integer; Begin - If FStorageDataType = Nil then + // ABookmark.BookMarkBuf is nil if SetRecNo calls GotoBookmark + If (ABookmark.BookmarkData<>nil) and (FRecordArray[ABookmark.BookmarkInt]<>ABookmark.BookmarkData) Then Begin - stor := TRESTDWStorageBin.Create(nil); - Try - stor.SaveToStream(Self, stream); - Finally - stor.Free; + // Start searching two records before the expected record + If ABookmark.BookmarkInt > 2 Then + Result := ABookmark.BookmarkInt-2 + Else + Result := 0; + + While (Result '' then - CreateIndexList(FieldNames) - Else If FKeyFieldNames <> '' then - CreateIndexList(FKeyFieldNames) - Else - Exit; - FCaseInsensitiveSort := CaseInsensitive; - FDescendingSort := Descending; - Try - Sort; - Except - FreeIndexList; - raise; - End; + FCurrentRecInd:=GetRecordFromBookmark(ABookmark^); End; -procedure TRESTDWMemTable.SwapRecords(Idx1: Integer; Idx2: Integer); +Procedure TRESTDWMemArrayIndex.InitialiseIndex; Begin - FRecords.Exchange(Idx1, Idx2); + // FRecordArray:=nil; + setlength(FRecordArray,FInitialBuffers); + FCurrentRecInd:=-1; + FLastRecInd:=-1; End; -procedure TRESTDWMemTable.Sort; -var - Pos: {$IFDEF FPC}TBookmark -{$ELSE} -{$IFDEF DELPHI10_0UP}DB.TBookmark{$ELSE}TBookmarkStr{$ENDIF DELPHI10_0UP} -{$ENDIF}; +Procedure TRESTDWMemArrayIndex.InitialiseSpareRecord(Const ASpareRecord: TRecordBuffer); Begin - If Active and (FRecords <> nil) and (FRecords.Count > 0) then - Begin - Pos := Bookmark; - Try - {$IFDEF FPC} - QuickSort(0, FRecords.Count - 1, @CompareRecords); - {$ELSE} - QuickSort(0, FRecords.Count - 1, CompareRecords); - {$ENDIF} - SetBufListSize(0); - InitBufferPointers(False); - Try - SetBufListSize(BufferCount + 1); - Except - SetState(dsInactive); - CloseCursor; - raise; - End; - Finally - Bookmark := Pos; - End; - Resync([]); - End; + FLastRecInd := 0; + // FCurrentRecInd := 0; + FRecordArray[0] := ASpareRecord; End; -procedure TRESTDWMemTable.QuickSort(L, R: Integer; Compare: TCompareRecords); -var - I, J: Integer; - P: TRESTDWMTMemoryRecord; -Begin - repeat - I := L; - J := R; - P := TRESTDWMTMemoryRecord(FRecords[(L + R) shr 1]); -// PRESTDWMTMemBuffer(@Records[(L + R) shr 1]); - repeat - while Compare(Records[I], P) < 0 do - Inc(I); - while Compare(Records[J], P) > 0 do - Dec(J); - If I <= J then - Begin - FRecords.Exchange(I, J); - Inc(I); - Dec(J); - End; - until I > J; - If L < J then - QuickSort(L, J, Compare); - L := I; - until I >= R; -End; - -function TRESTDWMemTable.CompareRecords(Item1, Item2: TRESTDWMTMemoryRecord - ): Integer; -var - Data1, Data2: PByte; - CData1, CData2, - Buffer1, Buffer2: array [0 .. dsMaxStringSize] of Byte; - F: TField; - I: Integer; +Procedure TRESTDWMemArrayIndex.ReleaseSpareRecord; Begin - Result := 0; - If FIndexList <> nil then - Begin - for I := 0 to FIndexList.Count - 1 do - Begin - F := TField(FIndexList[I]); - If F.FieldKind = fkData then - Begin - Data1 := FindFieldData(Item1.Data, F); - If Data1 <> nil then - Begin - Data2 := FindFieldData(Item2.Data, F); - If Data2 <> nil then - Begin - If Boolean(Data1^) and Boolean(Data2^) then - Begin -// Inc(Data1); -// Inc(Data2); - Result := CompareFields(Data1, Data2, F.datatype, FCaseInsensitiveSort); - End - Else If Boolean(Data1^) then - Result := 1 - Else If Boolean(Data2^) then - Result := -1; - If FDescendingSort then - Result := -Result; - End; - End; - If Result <> 0 then - Exit; - End - Else - Begin - FillChar(Buffer1, dsMaxStringSize, 0); - FillChar(Buffer2, dsMaxStringSize, 0); - RecordToBuffer(Item1, @Buffer1[0]); - RecordToBuffer(Item2, @Buffer2[0]); - Move(Buffer1[1 + FRecordSize + F.Offset], CData1, F.DataSize); - If CData1[0] <> 0 then - Begin - Move(Buffer2[1 + FRecordSize + F.Offset], CData2, F.DataSize); - If CData2[0] <> 0 then - Begin - If Boolean(CData1[0]) and Boolean(CData2[0]) then - Result := CompareFields(@CData1, @CData2, F.datatype, FCaseInsensitiveSort) - Else If Boolean(CData1[0]) then - Result := 1 - Else If Boolean(CData2[0]) then - Result := -1; - If FDescendingSort then - Result := -Result; - End; - End; - If Result <> 0 then - Exit; - End; - End; - End; - If Result = 0 then - Begin - If Item1.ID > Item2.ID then - Result := 1 - Else If Item1.ID < Item2.ID then - Result := -1; - If FDescendingSort then - Result := -Result; - End; + SetLength(FRecordArray,FInitialBuffers); End; -function TRESTDWMemTable.GetIsIndexField(Field: TField): Boolean; +Function TRESTDWMemArrayIndex.GetRecNo: Longint; Begin - If FIndexList <> nil then - Result := FIndexList.IndexOf(Field) >= 0 - Else - Result := False; + Result := FCurrentRecInd+1; End; -procedure TRESTDWMemTable.CreateIndexList(const FieldNames: DWWideString); -type - TFieldTypeSet = set of TFieldType; - Function GetSetFieldNames(const FieldTypeSet: TFieldTypeSet): string; - var - FieldType: TFieldType; - Begin - for FieldType := Low(TFieldType) to High(TFieldType) do - If FieldType in FieldTypeSet then - Result := Result + FieldTypeNames[FieldType] + ', '; - Result := Copy(Result, 1, Length(Result) - 2); - End; - -var - Pos: Integer; - F: TField; +Procedure TRESTDWMemArrayIndex.SetRecNo(ARecNo: Longint); Begin - If FIndexList = Nil Then - FIndexList := TList.Create; -// Else -// FIndexList.Clear; - Pos := 1; - While Pos <= Length(FieldNames) Do - Begin - F := FieldByName(ExtractFieldNameEx(FieldNames, Pos)); - If FIndexList.IndexOf(F) = -1 Then - Begin - If (F.FieldKind = fkData) And (F.datatype in ftSupported - ftBlobTypes) then - FIndexList.Add(F) - Else - ErrorFmt('Type mismatch for field %s, expecting: %s actual %s', - [F.DisplayName, GetSetFieldNames(ftSupported - ftBlobTypes), - FieldTypeNames[F.datatype]]); - End; - End; + FCurrentRecInd := ARecNo-1; End; -procedure TRESTDWMemTable.FreeIndexList; +Procedure TRESTDWMemArrayIndex.InsertRecordBeforeCurrentRecord(Const ARecord: TRecordBuffer); Begin - If Assigned(FIndexList) Then - FreeAndNil(FIndexList); + inc(FLastRecInd); + If FLastRecInd >= length(FRecordArray) Then + SetLength(FRecordArray,length(FRecordArray)+FGrowBuffer); + + Move(FRecordArray[FCurrentRecInd],FRecordArray[FCurrentRecInd+1],sizeof(Pointer)*(FLastRecInd-FCurrentRecInd)); + FRecordArray[FCurrentRecInd]:=ARecord; + inc(FCurrentRecInd); End; -function TRESTDWMemTable.GetValues(FldNames: String): Variant; -var - I: Integer; - List: TList{$IFDEF RTL240_UP}{$ENDIF RTL240_UP}; +Procedure TRESTDWMemArrayIndex.RemoveRecordFromIndex(Const ABookmark : TRESTDWMemBookmark); +Var ARecordInd : integer; Begin - Result := Null; - If FldNames = '' then - FldNames := FKeyFieldNames; - If FldNames = '' then - Exit; - // Mantis 3610: If there is only one field in the dataset, return a - // variant array with only one element. This seems to be required for - // ADO, DBIsam, DBX and others to work. - If Pos(';', FldNames) > 0 then - Begin - List := TList{$IFDEF RTL240_UP}{$ENDIF RTL240_UP}.Create; - GetFieldList(List, FldNames); - Result := VarArrayCreate([0, List.Count - 1], varVariant); - for I := 0 to List.Count - 1 do - Result[I] := TField(List[I]).Value; - FreeAndNil(List); - End - Else If FOneValueInArray then - Begin - Result := VarArrayCreate([0, 0], varVariant); - Result[0] := FieldByName(FldNames).Value; - End - Else - Result := FieldByName(FldNames).Value; + ARecordInd:=GetRecordFromBookmark(ABookmark); + Move(FRecordArray[ARecordInd+1],FRecordArray[ARecordInd],sizeof(Pointer)*(FLastRecInd-ARecordInd)); + dec(FLastRecInd); End; -function TRESTDWMemTable.CopyFromDataSet: Integer; -var - I, Len, FinalAutoInc: Integer; - Original, StatusField: TField; - OriginalFields: array of TField; - FieldReadOnly: Boolean; +Procedure TRESTDWMemArrayIndex.BeginUpdate; Begin - Result := 0; - If FDataSet = nil then - Exit; - If FApplyMode <> amNone then - Len := FieldDefs.Count - 1 - Else - Len := FieldDefs.Count; - If Len < 2 then - Exit; - Try - If not FDataSet.Active then - FDataSet.Open; - Except - Exit; - End; - If FDataSet.IsEmpty then - Begin - If FDataSet.Active and FDataSetClosed then - FDataSet.Close; - Exit; - End; - FinalAutoInc := 0; - FDataSet.DisableControls; - DisableControls; - FSaveLoadState := slsLoading; - Try - SetLength(OriginalFields, Fields.Count); - for I := 0 to Fields.Count - 1 do - Begin - If Fields[I].FieldKind <> fkCalculated then - OriginalFields[I] := FDataSet.FindField(Fields[I].FieldName); - End; - StatusField := nil; - If FApplyMode <> amNone then - StatusField := FieldByName(FStatusName); - // find first source autoinc field - FSrcAutoIncField := nil; - for I := 0 to FDataSet.FieldCount - 1 do - If FDataSet.Fields[I].datatype = ftAutoInc then - Begin - FSrcAutoIncField := FDataSet.Fields[I]; - Break; - End; - FDataSet.First; - while not FDataSet.EOF do - Begin - AppEnd; - for I := 0 to Fields.Count - 1 do - Begin - If Fields[I].FieldKind <> fkCalculated then - Begin - Original := OriginalFields[I]; - If Original <> nil then - Begin - FieldReadOnly := Fields[I].ReadOnly; - If FieldReadOnly then - Fields[I].ReadOnly := False; - Try - CopyFieldValue(Fields[I], Original); - Finally - If FieldReadOnly then - Fields[I].ReadOnly := True; - End; - End; - End; - End; - // assign AutoInc value manually (make user keep largest If source isn't sorted by autoinc field) - If FSrcAutoIncField <> nil then - Begin - FinalAutoInc := Max(FinalAutoInc, FSrcAutoIncField.AsInteger); - FAutoInc := FSrcAutoIncField.AsInteger; - End; - If FApplyMode <> amNone then - StatusField.AsInteger := Integer(rsOriginal); - Post; - Inc(Result); - FDataSet.Next; - End; - FRowsChanged := 0; - FRowsAffected := 0; - Finally - FAutoInc := FinalAutoInc + 1; - FSaveLoadState := slsNone; - EnableControls; - FDataSet.EnableControls; - If FDataSet.Active and FDataSetClosed then - FDataSet.Close; - End; + // inherited BeginUpdate; End; -Function TRESTDWIndex.BookmarkValid(const ABookmark : PRESTDWBookmark) : Boolean; +Procedure TRESTDWMemArrayIndex.AddRecord; +Var ARecord: TRecordBuffer; Begin - Result := assigned(ABookmark) and assigned(ABookmark^.BookmarkData); + ARecord := FDataset.IntAllocRecordBuffer; + inc(FLastRecInd); + If FLastRecInd >= length(FRecordArray) Then + SetLength(FRecordArray,length(FRecordArray)+FGrowBuffer); + FRecordArray[FLastRecInd]:=ARecord; End; -Function TRESTDWIndex.CompareBookmarks(const ABookmark1, - ABookmark2 : PRESTDWBookmark) : Integer; +Procedure TRESTDWMemArrayIndex.EndUpdate; Begin - Result := 0; + // inherited EndUpdate; End; -Function TRESTDWIndex.SameBookmarks(const ABookmark1, - ABookmark2 : PRESTDWBookmark) : Boolean; + +{ TRESTDWMemDataPacketReader } + +Class Function TRESTDWMemDataPacketReader.RowStateToByte(Const ARowState: TRESTDWMemRowState + ): byte; +Var RowStateInt : Byte; Begin - Result := Assigned(ABookmark1) and Assigned(ABookmark2) and (CompareBookmarks(ABookmark1, ABookmark2) = 0); + RowStateInt:=0; + If rsvOriginal in ARowState Then + RowStateInt := RowStateInt+1; + If rsvDeleted in ARowState Then + RowStateInt := RowStateInt+2; + If rsvInserted in ARowState Then + RowStateInt := RowStateInt+4; + If rsvUpdated in ARowState Then + RowStateInt := RowStateInt+8; + Result := RowStateInt; End; -Function TRESTDWIndex.GetRecord(ABookmark : PRESTDWBookmark; - GetMode : TGetMode) : TGetResult; +Class Function TRESTDWMemDataPacketReader.ByteToRowState(Const AByte: Byte): TRESTDWMemRowState; Begin - Result := grError; + result := []; + If (AByte and 1)=1 Then + Result := Result+[rsvOriginal]; + If (AByte and 2)=2 Then + Result := Result+[rsvDeleted]; + If (AByte and 4)=4 Then + Result := Result+[rsvInserted]; + If (AByte and 8)=8 Then + Result := Result+[rsvUpdated]; End; -constructor TRESTDWIndex.Create(const ADataset: TRESTDWMemtable); +Procedure TRESTDWMemDataPacketReader.RestoreBlobField(AField: TField; ASource: pointer; ASize: integer); +Var + ABufBlobField: TRESTDWMemBlobField; Begin - Inherited Create; - FDataset := TRESTDWMemtable(ADataset); + ABufBlobField.BlobBuffer:=FDataSet.GetNewBlobBuffer; + ABufBlobField.BlobBuffer^.Size:=ASize; + ReAllocMem(ABufBlobField.BlobBuffer^.Buffer, ASize); + move(ASource^, ABufBlobField.BlobBuffer^.Buffer^, ASize); + AField.SetData(@ABufBlobField); End; -{$IFDEF FPC} -Function TRESTDWMemTable.GetFieldData(Field : TField; - Buffer : Pointer; - NativeFormat : Boolean): Boolean; +Constructor TRESTDWMemDataPacketReader.Create(ADataSet: TRESTDWCustomMemTable; AStream: TStream); Begin - Result := InternalGetFieldData(Field, TRESTDWMTValueBuffer(Buffer)); + FDataSet := ADataSet; + FStream := AStream; End; -{$ENDIF} -Function TRESTDWMemTable.GetFieldData(FieldNo : Integer; - Var Buffer : TValueBuffer): Boolean; + +{ TRESTDWBinaryPacketWriter } + +Constructor TRESTDWBinaryPacketWriter.Create(AStream: TStream); Begin -{$IFDEF FPC} - Result := InternalGetFieldData(Fields[FieldNo], TRESTDWMTValueBuffer(Buffer)); //Inherited GetFieldData(Fields[FieldNo], Pointer(@Buffer)); -{$ELSE} - Inherited GetFieldData(FieldNo, Buffer); + Inherited Create; + FStream := AStream; +{$IFDEF RESTDWLAZARUS} + FDatabaseCharSet := csUndefined; {$ENDIF} End; -procedure TRESTDWMemTable.DoBeforeApply(ADataset: TDataset; RowsPending: Integer); +Procedure TRESTDWBinaryPacketWriter.ClearFieldDefs; Begin - If Assigned(FBeforeApply) then - FBeforeApply(ADataset, RowsPending); + SetLength(FFields, 0); + SetLength(FNullBitmap, 0); + FNullBitmapSize := 0; End; -procedure TRESTDWMemTable.DoAfterApply(ADataset: TDataset; RowsApplied: Integer - ); -Begin - If Assigned(FAfterApply) then - FAfterApply(ADataset, RowsApplied); +Procedure TRESTDWBinaryPacketWriter.AddFieldDef(Const AName, ADisplayName: String; + ASize: Word; ADataType: TFieldType; AReadOnly: Boolean); +Var + I: Integer; +Begin + I := Length(FFields); + SetLength(FFields, I + 1); + FFields[I].Name := AName; + FFields[I].DisplayName := ADisplayName; + FFields[I].Size := ASize; + If FieldTypeToDWFieldType(ADataType) In [dwftTimeStamp, dwftOraTimeStamp, + dwftTimeStampOffset] Then + FFields[I].DataType := ftDateTime + Else + FFields[I].DataType := ADataType; + FFields[I].ReadOnly := AReadOnly; End; -procedure TRESTDWMemTable.DoBeforeApplyRecord(ADataset: TDataset; - RS: TRecordStatus; aFound: Boolean); +Procedure TRESTDWBinaryPacketWriter.WriteAnsiString(Const AValue: AnsiString); +Var + L: LongWord; Begin - If Assigned(FBeforeApplyRecord) then - FBeforeApplyRecord(ADataset, RS, Found); + L := Length(AValue); + FStream.WriteBuffer(L, SizeOf(L)); + If L > 0 Then + FStream.WriteBuffer(AValue[1], L); End; -procedure TRESTDWMemTable.DoAfterApplyRecord(ADataset: TDataset; - RS: TRecordStatus; aApply: Boolean); +Class Function TRESTDWBinaryPacketWriter.IsStringField(AType: TFieldType): Boolean; Begin - If Assigned(FAfterApplyRecord) then - FAfterApplyRecord(ADataset, RS, aApply); + Result := AType in [ftString, ftFixedChar, ftWideString, ftFixedWideChar]; End; -procedure TRESTDWMemTable.ClearChanges; -var - I: Integer; - PFValues: TPVariant; +Class Function TRESTDWBinaryPacketWriter.IsVariableField(AType: TFieldType): Boolean; Begin - If FDeletedValues.Count > 0 then + Result := IsStringField(AType) or + (AType in [ftBlob, ftMemo, ftGraphic, ftWideMemo, ftBytes, ftVarBytes]); +End; + +Procedure TRESTDWBinaryPacketWriter.StoreFieldDefs(AnAutoIncValue: Integer); +Const + Ident: AnsiString = 'BinRESTDWDataSet'; +Var + I: Integer; + W: Word; + B: Byte; +Begin + FStream.WriteBuffer(Ident[1], Length(Ident)); + B := 20; + FStream.WriteBuffer(B, SizeOf(B)); + W := Length(FFields); + FStream.WriteBuffer(W, SizeOf(W)); + For I := 0 To Length(FFields) - 1 Do Begin - for I := 0 to (FDeletedValues.Count - 1) do - Begin - PFValues := FDeletedValues[I]; - If PFValues <> nil then - Dispose(PFValues); - FDeletedValues[I] := nil; - End; - FDeletedValues.Clear; + WriteAnsiString(AnsiString(FFields[I].Name)); + WriteAnsiString(AnsiString(FFields[I].DisplayName)); + FStream.WriteBuffer(FFields[I].Size, SizeOf(Word)); + B := 0; + W := FieldTypeToDWFieldType(FFields[I].DataType); + Case W Of + dwftTimeStamp, + dwftOraTimeStamp, + dwftTimeStampOffset: W := dwftDateTime; + End; + FStream.WriteBuffer(W, SizeOf(W)); + If FFields[I].ReadOnly Then + B := 1; + FStream.WriteBuffer(B, SizeOf(B)); End; - EmptyTable; - If FLoadRecords then + FStream.WriteBuffer(AnAutoIncValue, SizeOf(AnAutoIncValue)); + FNullBitmapSize := (Length(FFields) + 7) div 8; + SetLength(FNullBitmap, FNullBitmapSize); +End; + +Procedure TRESTDWBinaryPacketWriter.BeginRecord; +Var + B: Byte; +Begin + B := $FE; + FStream.WriteBuffer(B, SizeOf(B)); + B := 0; + FStream.WriteBuffer(B, SizeOf(B)); + If FNullBitmapSize > 0 Then Begin - FRowsOriginal := CopyFromDataSet; - If FRowsOriginal > 0 then - Begin - If FKeyFieldNames <> '' then - SortOnFields(); - If FApplyMode = amAppend then - Last - Else - First; - End; + FillChar(FNullBitmap[0], FNullBitmapSize, 0); + FNullBitmapPosition := FStream.Position; + FStream.WriteBuffer(FNullBitmap[0], FNullBitmapSize); End; End; -procedure TRESTDWMemTable.CancelChanges; +Procedure TRESTDWBinaryPacketWriter.StoreNull(AFieldIndex: Integer); Begin - CheckBrowseMode; - ClearChanges; - FRowsChanged := 0; - FRowsAffected := 0; + If (AFieldIndex >= 0) and (AFieldIndex < Length(FFields)) and + (FNullBitmapSize > 0) Then + FNullBitmap[AFieldIndex div 8] := FNullBitmap[AFieldIndex div 8] or + Byte(1 shl (AFieldIndex mod 8)); End; -function TRESTDWMemTable.ApplyChanges: Boolean; -var - xKey: Variant; - PxKey: TPVariant; - Len, Row: Integer; - Status: TRecordStatus; - bFound, bApply: Boolean; - FOriginal, FClient: TField; - Function WriteFields: Boolean; - var - J: Integer; +Procedure TRESTDWBinaryPacketWriter.StoreField(AFieldIndex: Integer; + ABuffer: Pointer; ASize: LongWord); +Var + L: LongWord; +{$IFDEF RESTDWLAZARUS} + S: AnsiString; +{$ENDIF} +Begin + If (AFieldIndex < 0) or (AFieldIndex >= Length(FFields)) Then + Exit; +{$IFDEF RESTDWLAZARUS} + If FFields[AFieldIndex].DataType In [ftString, ftFixedChar, ftWideString, ftFixedWideChar, ftMemo, ftWideMemo] Then Begin - Try - for J := 0 to Len do - Begin - If (Fields[J].FieldKind = fkData) then - Begin - FClient := Fields[J]; - FOriginal := FDataSet.FindField(FClient.FieldName); - If (FOriginal <> nil) and (FClient <> nil) and not FClient.ReadOnly then - Begin - If FClient.IsNull then - FOriginal.Clear - Else - FDataSet.FieldByName(FOriginal.FieldName).Value := FClient.Value; - End; - End; - End; - Result := True; - Except - Result := False; - End; + SetLength(S, ASize); + If (ASize > 0) And (ABuffer <> Nil) Then + Move(ABuffer^, S[1], ASize); + S := AnsiString(GetStringEncode(String(S), FDatabaseCharSet)); + ASize := Length(S); + If ASize > 0 Then + ABuffer := @S[1] + Else + ABuffer := Nil; End; - - Function InsertRec: Boolean; +{$ENDIF} + If IsVariableField(FFields[AFieldIndex].DataType) Then Begin - Try - FDataSet.AppEnd; - WriteFields; - FDataSet.Post; - Result := True; - Except - Result := False; - End; + L := ASize; + FStream.WriteBuffer(L, SizeOf(L)); End; + If (ASize > 0) and (ABuffer <> nil) Then + FStream.WriteBuffer(ABuffer^, ASize); +End; - Function UpdateRec: Boolean; - Begin - Try - FDataSet.Edit; - WriteFields; - FDataSet.Post; - Result := True; - Except - Result := False; - End; - End; +Procedure TRESTDWBinaryPacketWriter.EndRecord; +Var + P: Int64; +Begin + If FNullBitmapSize = 0 Then + Exit; + P := FStream.Position; + FStream.Position := FNullBitmapPosition; + FStream.WriteBuffer(FNullBitmap[0], FNullBitmapSize); + FStream.Position := P; +End; - Function DeleteRec: Boolean; - Begin - Try - FDataSet.Delete; - Result := True; - Except - Result := False; - End; - End; - Function SaveChanges: Integer; - var - I: Integer; - Begin - Result := 0; - FDataSet.DisableControls; - DisableControls; - Row := RecNo; - FSaveLoadState := slsSaving; - Try - If not IsEmpty then - First; - while not EOF do - Begin - Status := TRecordStatus(FieldByName(FStatusName).AsInteger); - If (Status <> rsOriginal) then - Begin - xKey := GetValues; - bFound := FDataSet.Locate(FKeyFieldNames, xKey, []); - DoBeforeApplyRecord(FDataSet, Status, bFound); - bApply := False; - (* ******************** New Record ********************** *) - If IsInserted then - Begin - If not bFound then // Not Exists in Original - Begin - If InsertRec then - Begin - Inc(Result); - bApply := True; - End - Else If FExactApply then - Begin - Error(RsEInsertError); - Break; - End - Else If (FDataSet.State in dsEditModes) then - FDataSet.Cancel; - End - Else If FApplyMode = amMerge then // Exists in Original - Begin - If UpdateRec then - Begin - Inc(Result); - bApply := True; - End - Else If FExactApply then - Begin - Error(RsEUpdateError); - Break; - End - Else If (FDataSet.State in dsEditModes) then - FDataSet.Cancel; - End - Else If FExactApply then - Begin - Error(RsERecordDuplicate); - Break; - End; - End; - (* ********************** Modified Record *********************** *) - If IsUpdated then - Begin - If bFound then // Exists in Original - Begin - If UpdateRec then - Begin - Inc(Result); - bApply := True; - End - Else If FExactApply then - Begin - Error(RsEUpdateError); - Break; - End - Else If (FDataSet.State in dsEditModes) then - FDataSet.Cancel; - End - Else If FApplyMode = amMerge then // Not exists in Original - Begin - If InsertRec then - Begin - Inc(Result); - bApply := True; - End - Else If FExactApply then - Begin - Error(RsEInsertError); - Break; - End - Else If FDataSet.State in dsEditModes then - FDataSet.Cancel; - End - Else If FExactApply then - Begin - Error(RsERecordInexistent); - Break; - End; - End; - DoAfterApplyRecord(FDataSet, Status, bApply); - End; - Next; - End; - (* ********************** Deleted Records ************************* *) - If (FApplyMode = amMerge) then - Begin - for I := 0 to FDeletedValues.Count - 1 do - Begin - Status := rsDeleted; - PxKey := FDeletedValues[I]; - // Mantis #3974 : "FDeletedValues" is a List of Pointers, and each item have two - // possible values... PxKey (a Variant) or NIL. The list counter is incremented - // with the ADD() method and decremented with the DELETE() method - If PxKey <> nil then // ONLY If FDeletedValues[I] have a value <> NIL - Begin - xKey := PxKey^; - bFound := FDataSet.Locate(FKeyFieldNames, xKey, []); - DoBeforeApplyRecord(FDataSet, Status, bFound); - bApply := False; - If bFound then // Exists in Original - Begin - If DeleteRec then - Begin - Inc(Result); - bApply := True; - End - Else If FExactApply then - Begin - Error(RsEDeleteError); - Break; - End; - End - Else If FExactApply then // Not exists in Original - Begin - Error(RsERecordInexistent); - Break; - End - Else - Begin - Inc(Result); - bApply := True; - End; - DoAfterApplyRecord(FDataSet, Status, bApply); - End; - End; - End; - Finally - FSaveLoadState := slsNone; - RecNo := Row; - EnableControls; - FDataSet.EnableControls; - End; - End; +{ TRESTDWTBinaryDatapacketReader } +Function TRESTDWTBinaryDatapacketReader.ReadByteValue: Byte; Begin - Result := False; - If (FDataSet = nil) or (FApplyMode = amNone) then - Exit; - If (FApplyMode <> amNone) and (FKeyFieldNames = '') then - Exit; - Len := FieldDefs.Count - 2; - If (Len < 1) then - Exit; - Try - If not FDataSet.Active then - FDataSet.Open; - Except - Exit; - End; - CheckBrowseMode; - DoBeforeApply(FDataSet, FRowsChanged); - FSaveLoadState := slsSaving; - If (FRowsChanged < 1) or (IsEmpty and (FDeletedValues.Count < 1)) then - Begin - FRowsAffected := 0; - Result := (FRowsAffected = FRowsChanged); - End - Else - Begin - FRowsAffected := SaveChanges; - Result := (FRowsAffected = FRowsChanged) or - ((FRowsAffected > 0) and (FRowsAffected < FRowsChanged) and not FExactApply); - End; - FSaveLoadState := slsNone; - DoAfterApply(FDataSet, FRowsAffected); - If Result then - ClearChanges; - FRowsAffected := 0; - FRowsChanged := 0; - If FDataSet.Active and FDataSetClosed then - FDataSet.Close; -End; - -function TRESTDWMemTable.FindDeleted(KeyValues: Variant): Integer; -var - I, J, Len, aEquals: Integer; - PxKey: TPVariant; - xKey, ValRow, ValDel: Variant; + Stream.ReadBuffer(Result, SizeOf(Result)); +End; +Function TRESTDWTBinaryDatapacketReader.ReadWordValue: Word; +Begin + Stream.ReadBuffer(Result, SizeOf(Result)); +End; + +Function TRESTDWTBinaryDatapacketReader.ReadDWordValue: LongWord; +Begin + Stream.ReadBuffer(Result, SizeOf(Result)); +End; + +Function TRESTDWTBinaryDatapacketReader.ReadAnsiStringValue: AnsiString; +Var + L : LongWord; + LRemaining: Int64; +Begin + L := ReadDWordValue; + LRemaining := Stream.Size - Stream.Position; + If Int64(L) > LRemaining Then + Raise Exception.Create('Invalid binary packet string length ' + IntToStr(L) + + ' at position ' + IntToStr(Stream.Position - SizeOf(L)) + + ', remaining ' + IntToStr(LRemaining)); + SetLength(Result,L); + If L > 0 Then + Stream.ReadBuffer(Result[1],L); +End; +Function TRESTDWTBinaryDatapacketReader.GetFixedWireSize(AWireType: Byte; AField: TField): Cardinal; +Begin + Case AWireType Of + dwftSmallint: Result := SizeOf(SmallInt); + dwftInteger: Result := SizeOf(Integer); + dwftWord: Result := SizeOf(Word); + dwftBoolean: Result := SizeOf(WordBool); + dwftFloat: Result := SizeOf(Double); + dwftCurrency, + dwftBCD: Result := SizeOf(Currency); + dwftDate, + dwftTime: Result := SizeOf(Integer); + dwftDateTime, + dwftTimeStamp, + dwftOraTimeStamp, + dwftTimeStampOffset: Result := SizeOf(TDateTime); + dwftLargeint, + dwftAutoInc: Result := SizeOf(Int64); + dwftExtended: Result := SizeOf(Double); + dwftFMTBcd: Result := SizeOf(TBcd); + dwftGuid: Result := SizeOf(TGUID); + Else + Result := AField.DataSize; + End; +End; +Procedure TRESTDWTBinaryDatapacketReader.WriteByteValue(AValue: Byte); +Begin + Stream.WriteBuffer(AValue, SizeOf(AValue)); +End; +Procedure TRESTDWTBinaryDatapacketReader.WriteWordValue(AValue: Word); +Begin + Stream.WriteBuffer(AValue, SizeOf(AValue)); +End; +Procedure TRESTDWTBinaryDatapacketReader.WriteDWordValue(AValue: LongWord); +Begin + Stream.WriteBuffer(AValue, SizeOf(AValue)); +End; +Procedure TRESTDWTBinaryDatapacketReader.WriteAnsiStringValue(Const AValue: AnsiString); +Var L: LongWord; +Begin + L := Length(AValue); + WriteDWordValue(L); + If L > 0 Then + Stream.WriteBuffer(AValue[1], L); +End; + +Constructor TRESTDWTBinaryDatapacketReader.Create(ADataSet: TRESTDWCustomMemTable; AStream: TStream); +Begin + Inherited; + FVersion := 20; // default version 2.0 +End; + +Procedure TRESTDWTBinaryDatapacketReader.LoadFieldDefs(Var AnAutoIncValue: integer); + +Var FldCount : word; +i : integer; +W : Word; +s : AnsiString; +{$IFNDEF FPC} +AFieldDef : TFieldDef; +{$ENDIF} + Begin - Result := -1; - If VarIsNull(KeyValues) then - Exit; - PxKey := nil; - Len := VarArrayHighBound(KeyValues, 1); - Try - for I := 0 to FDeletedValues.Count - 1 do + // Identify version + SetLength(s, Length(RESTDWBinaryIdent)); + If (Stream.Read(s[1], Length(RESTDWBinaryIdent)) = Length(RESTDWBinaryIdent)) And + (s = RESTDWBinaryIdent) Then + FVersion := ReadByteValue + Else + DatabaseError(SStreamNotRecognised,Self.FDataset); + + // Read FieldDefs + FldCount := ReadWordValue; + If (Stream.Size - Stream.Position) < (Int64(FldCount) * 13 + SizeOf(Integer)) Then + Raise Exception.Create('Invalid binary packet field count ' + IntToStr(FldCount) + + ' at position ' + IntToStr(Stream.Position - SizeOf(FldCount)) + + ', remaining ' + IntToStr(Stream.Size - Stream.Position)); + DataSet.FieldDefs.Clear; + SetLength(FWireFieldTypes, FldCount); + For i := 0 To FldCount - 1 Do + Begin +{$IFDEF FPC} + With DataSet.FieldDefs.AddFieldDef Do +{$ELSE} + AFieldDef := TFieldDef.Create(DataSet.FieldDefs,'',ftUnknown,0,False,i + 1); + With AFieldDef Do +{$ENDIF} Begin - PxKey := FDeletedValues[I]; - // Mantis #3974 : "FDeletedValues" is a List of Pointers, and each item have two - // possible value... PxKey (a Variant) or NIL. The list counter is incremented - // with the ADD() method and decremented with the DELETE() method - If PxKey <> nil then // ONLY If FDeletedValues[I] have a value <> NIL - Begin - xKey := PxKey^; - aEquals := -1; - for J := 0 to Len - 1 do + Name := ReadAnsiStringValue; + Displayname := ReadAnsiStringValue; + Size := ReadWordValue; + W := ReadWordValue; + If W > 255 Then + Raise Exception.Create('Invalid binary packet field type ' + IntToStr(W) + + ' at position ' + IntToStr(Stream.Position - SizeOf(W))); + FWireFieldTypes[I] := Byte(W); + Case FWireFieldTypes[I] Of + dwftTimeStamp, + dwftOraTimeStamp, + dwftTimeStampOffset: DataType := ftDateTime; + Else + DataType := DWFieldTypeToFieldType(FWireFieldTypes[I]); + End; +{$IFNDEF FPC} + Case DataType Of + ftBCD: Begin - ValRow := KeyValues[J]; - ValDel := xKey[J]; - If VarCompareValue(ValRow, ValDel) = vrEqual then - Begin - Inc(aEquals); - If aEquals = (Len - 1) then - Break; - End; + Precision := 18; End; - If aEquals = (Len - 1) then + ftFMTBcd: Begin - Result := I; - Break; + Precision := 32; End; End; +{$ENDIF} + + If ReadByteValue = 1 Then + Attributes := Attributes + [faReadonly]; End; - Finally - If PxKey <> nil then - Dispose(PxKey); End; -End; + Stream.ReadBuffer(i,sizeof(i)); + AnAutoIncValue := i; -function TRESTDWMemTable.IsDeleted(out Index: Integer): Boolean; -Begin - Index := FindDeleted(GetValues()); - Result := Index > -1; + FNullBitmapSize := (FldCount + 7) div 8; + SetLength(FNullBitmap, FNullBitmapSize); End; -function TRESTDWMemTable.IsInserted: Boolean; +Procedure TRESTDWTBinaryDatapacketReader.StoreFieldDefs(AnAutoIncValue: integer); +Var i : integer; Begin - Result := TRecordStatus(FieldByName(FStatusName).AsInteger) = rsInserted; + Stream.Write(RESTDWBinaryIdent[1], Length(RESTDWBinaryIdent)); + WriteByteValue(FVersion); + + WriteWordValue(DataSet.FieldDefs.Count); + SetLength(FWireFieldTypes, DataSet.FieldDefs.Count); + For i := 0 To DataSet.FieldDefs.Count - 1 Do With DataSet.FieldDefs[i] Do + Begin + WriteAnsiStringValue(Name); + WriteAnsiStringValue(DisplayName); + WriteWordValue(Size); + FWireFieldTypes[I] := FieldTypeToDWFieldType(DataType); + Case FWireFieldTypes[I] Of + dwftTimeStamp, + dwftOraTimeStamp, + dwftTimeStampOffset: FWireFieldTypes[I] := dwftDateTime; + End; + WriteWordValue(FWireFieldTypes[I]); + + If faReadonly in Attributes Then + WriteByteValue(1) + Else + WriteByteValue(0); + End; + i := AnAutoIncValue; + Stream.WriteBuffer(i,sizeof(i)); + + FNullBitmapSize := (DataSet.FieldDefs.Count + 7) div 8; + SetLength(FNullBitmap, FNullBitmapSize); End; -function TRESTDWMemTable.IsUpdated: Boolean; +Procedure TRESTDWTBinaryDatapacketReader.InitLoadRecords; Begin - Result := TRecordStatus(FieldByName(FStatusName).AsInteger) = rsUpdated; + // Do nothing End; -function TRESTDWMemTable.IsOriginal: Boolean; +Function TRESTDWTBinaryDatapacketReader.GetCurrentRecord: boolean; +Var + Buf : Byte; + ReadSize : Integer; Begin - Result := TRecordStatus(FieldByName(FStatusName).AsInteger) = rsOriginal; + ReadSize := Stream.Read(Buf, 1); + Result := ReadSize = 1; + If Not Result Then + Exit; + If Buf <> $FE Then + Raise Exception.Create('Invalid binary packet record marker ' + IntToStr(Buf) + + ' at position ' + IntToStr(Stream.Position - 1) + + ', remaining ' + IntToStr(Stream.Size - Stream.Position)); End; -function TRESTDWMemTable.IsLoading: Boolean; +Function TRESTDWTBinaryDatapacketReader.GetRecordRowState(out AUpdOrder : Integer) : TRESTDWMemRowState; +Var Buf : byte; Begin - Result := FSaveLoadState = slsLoading; + Stream.Read(Buf,1); + Result := ByteToRowState(Buf); + If Result<>[] Then + Stream.ReadBuffer(AUpdOrder,sizeof(integer)) + Else + AUpdOrder := 0; End; -function TRESTDWMemTable.IsSaving: Boolean; +Procedure TRESTDWTBinaryDatapacketReader.GotoNextRecord; Begin - Result := FSaveLoadState = slsSaving; + // Do Nothing End; -// === { TRESTDWMTMemBlobStream } =================================================== -constructor TRESTDWMTMemBlobStream.Create(Field: TBlobField; Mode: TBlobStreamMode); +Procedure TRESTDWTBinaryDatapacketReader.RestoreRecord; + Var - vPointer : Pointer; -Begin - // (rom) added inherited Create; - inherited Create; - FActualBlob := Nil; - FMode := Mode; - FField := Field; - FDataSet := FField.Dataset as TRESTDWMemTable; - If Not FDataSet.GetActiveRecBuf(FBuffer) then - Exit; - If not FField.Modified and (Mode <> bmRead) then - Begin - If FField.ReadOnly then - ErrorFmt('The Field %s is ReadOnly', [FField.DisplayName]); - If not(FDataSet.State in [dsEdit, dsInsert]) then - Error('Not Editing...'); - FCached := True; - End - Else - FCached := (FBuffer = PRESTDWMTMemBuffer(FDataSet.ActiveBuffer)); - vPointer := FDataSet.GetBlob(FField.Dataset.RecNo, FField.Offset); - FActualBlob := vPointer; - If (FCached) And (FDataSet.State = dsBrowse) Then - TRESTDWBytes(vPointer^) := GetBlobFromRecord(FField); - FOpened := True; - If Mode = bmWrite then - Truncate; -End; - -destructor TRESTDWMTMemBlobStream.Destroy; -Begin - If FOpened and FModified then - FField.Modified := True; - If FModified then - Try - FDataSet.DataEvent(deFieldChange, NativeInt(FField)); - Except - AppHandleException(Self); - End; - FDataSet := Nil; - //FDataSet.Free; - inherited Destroy; -End; + AField : TField; + I : Integer; + J : Integer; + L : Cardinal; + B : TRESTDWMemBytes; + VDateTime : TDateTime; + VDouble : Double; + VCurrency : Currency; + VBcd : TBcd; +{$IFDEF FPC} + VWireValue : Integer; +{$ENDIF} +{$IFDEF DELPHI2010UP} + VTimeStamp : TSQLTimeStamp; + VTimeStampOffset : TSQLTimeStampOffset; +{$ENDIF} +{$IFDEF RESTDWLAZARUS} + SText : AnsiString; +{$ENDIF} -Function TRESTDWMTMemBlobStream.GetBlobFromRecord(Field: TField): TMemBlobData; -var - Rec: TRESTDWMTMemoryRecord; - Pos: Integer; Begin - SetLength(Result, 0); - Try - Pos := FDataSet.RecNo -1; - If (Pos >= 0) And (Pos < FDataSet.RecordCount) Then + With DataSet Do + Case FVersion Of + 10: + Stream.ReadBuffer(GetCurrentBuffer^, FRecordSize); + 20: Begin - Rec := FDataSet.Records[Pos]; - If Rec <> nil Then - Result := TMemBlobData(Rec.FBlobs[FField.Offset]); + Stream.ReadBuffer(FNullBitmap[0], FNullBitmapSize); + For I:=0 To FieldDefs.Count-1 Do + Begin + AField:=Fields.FieldByNumber(FieldDefs[I].FieldNo); + If AField=Nil Then + Continue; + If GetFieldIsNull(PByte(FNullBitmap),I) Then + SetFieldDataPtr(AField,Nil) + Else If AField.DataType in StringFieldTypes Then +{$IFDEF RESTDWLAZARUS} + AField.AsString:=GetStringEncode(String(ReadAnsiStringValue),DatabaseCharSet) +{$ELSE} + AField.AsString:=ReadAnsiStringValue +{$ENDIF} + Else If (I(Stream.Size-Stream.Position) Then + Raise Exception.Create('Invalid binary packet field size '+IntToStr(L)+ + ' at position '+IntToStr(Stream.Position)+ + ', remaining '+IntToStr(Stream.Size-Stream.Position)); + SetLength(B,L); + If L>0 Then + Stream.ReadBuffer(B[0],L); + If AField.DataType in BlobFieldTypes Then + Begin +{$IFDEF RESTDWLAZARUS} + If AField.DataType in [ftMemo,ftWideMemo] Then + Begin + SetLength(SText,L); + If L>0 Then + Move(B[0],SText[1],L); + SText:=AnsiString(GetStringEncode(String(SText),DatabaseCharSet)); + If Length(SText)>0 Then + RestoreBlobField(AField,@SText[1],Length(SText)) + Else + RestoreBlobField(AField,Nil,0); + End + Else +{$ENDIF} + If L>0 Then + RestoreBlobField(AField,@B[0],L) + Else + RestoreBlobField(AField,Nil,0); + End + Else If L>0 Then + SetFieldDataPtr(AField,@B[0]) + Else + SetFieldDataPtr(AField,Nil); + End; + End; End; - Except - End; End; -{$IFDEF FPC} -Procedure TRESTDWMTMemBlobStream.SetBlobFromRecord(Field: TField; Value: TMemBlobData); +Procedure TRESTDWTBinaryDatapacketReader.StoreRecord(ARowState : TRESTDWMemRowState; AUpdOrder : Integer); Var - Rec: TRESTDWMTMemoryRecord; - Pos: Integer; - FBlobs: Pointer; +AField : TField; +I : Integer; +L : Cardinal; +B : TRESTDWMemBytes; +VDateTime : TDateTime; +VDouble : Double; +VCurrency : Currency; +VBcd : TBcd; +{$IFDEF FPC} +VWireValue : Integer; +VDateStamp : TTimeStamp; +{$ENDIF} +{$IFDEF RESTDWLAZARUS} +SText : AnsiString; +{$ENDIF} Begin - Try - Pos := FDataSet.RecNo - 1; - If (Pos >= 0) And (Pos < FDataSet.RecordCount) Then + WriteByteValue($FE); + WriteByteValue(RowStateToByte(ARowState)); + If ARowState <> [] Then + Stream.WriteBuffer(AUpdOrder, SizeOf(Integer)); + + With DataSet Do + Case FVersion Of + 10 : Stream.WriteBuffer(GetCurrentBuffer^, FRecordSize); + 20 : Begin + FillChar(FNullBitmap[0], FNullBitmapSize, 0); + For I := 0 To FieldDefs.Count - 1 Do + Begin + AField := Fields.FieldByNumber(FieldDefs[I].FieldNo); + If Assigned(AField) And AField.IsNull Then + SetFieldIsNull(PByte(FNullBitmap), I); + End; + Stream.WriteBuffer(FNullBitmap[0], FNullBitmapSize); + + For I := 0 To FieldDefs.Count - 1 Do + Begin + AField := Fields.FieldByNumber(FieldDefs[I].FieldNo); + If Not Assigned(AField) Or AField.IsNull Then + Continue; + If AField.DataType In StringFieldTypes Then +{$IFDEF RESTDWLAZARUS} + WriteAnsiStringValue(AnsiString(GetStringEncode(AField.AsString, DatabaseCharSet))) +{$ELSE} + WriteAnsiStringValue(AField.AsString) +{$ENDIF} + Else If (I < Length(FWireFieldTypes)) And + (FWireFieldTypes[I] = dwftBCD) Then + Begin + VCurrency := AField.AsCurrency; + Stream.WriteBuffer(VCurrency, SizeOf(VCurrency)); + End + Else If (I < Length(FWireFieldTypes)) And + (FWireFieldTypes[I] = dwftFMTBcd) Then + Begin + VBcd := AField.AsBCD; + Stream.WriteBuffer(VBcd, SizeOf(VBcd)); + End +{$IFDEF FPC} + Else If (I < Length(FWireFieldTypes)) And + (FWireFieldTypes[I] = dwftDate) Then + Begin + VWireValue := Trunc(AField.AsDateTime) + 693594; + Stream.WriteBuffer(VWireValue, SizeOf(VWireValue)); + End + Else If (I < Length(FWireFieldTypes)) And + (FWireFieldTypes[I] = dwftTime) Then + Begin + VDateStamp := DateTimeToTimeStamp(AField.AsDateTime); + VWireValue := VDateStamp.Time; + Stream.WriteBuffer(VWireValue, SizeOf(VWireValue)); + End +{$ENDIF} + + Else If (I < Length(FWireFieldTypes)) And + (FWireFieldTypes[I] = dwftExtended) Then + Begin +{$IFDEF FPC} + VDouble := AField.AsFloat; +{$ELSE} + {$IFDEF DELPHI2010UP} + If AField.DataType = ftExtended Then + VDouble := AField.AsExtended + Else + {$ENDIF} + VDouble := AField.AsFloat; +{$ENDIF} + Stream.WriteBuffer(VDouble, SizeOf(VDouble)); + End + Else If (I < Length(FWireFieldTypes)) And + (FWireFieldTypes[I] = dwftDateTime) Then + Begin + VDateTime := AField.AsDateTime; + Stream.WriteBuffer(VDateTime, SizeOf(VDateTime)); + End + Else Begin - Rec := FDataSet.Records[Pos]; - If Rec <> nil Then + L := Length(AField.AsBytes); + SetLength(B, L); + If L > 0 Then + Move(AField.AsBytes[0], B[0], L); +{$IFDEF RESTDWLAZARUS} + If AField.DataType In [ftMemo, ftWideMemo] Then Begin - FBlobs := Pointer(@Rec.FBlobs[FField.Offset]); - SetLength(TRESTDWBytes(FBlobs^), Length(TRESTDWBytes(FBlobs^)) + Length(Value)); - Move(Value[0], TRESTDWBytes(FBlobs^)[FPosition], Length(Value)); + SetLength(SText, L); + If L > 0 Then + Move(B[0], SText[1], L); + SText := AnsiString(GetStringEncode(String(SText), DatabaseCharSet)); + L := Length(SText); + SetLength(B, L); + If L > 0 Then + Move(SText[1], B[0], L); End; +{$ENDIF} + If AField.DataType In VarLenFieldTypes Then + WriteDWordValue(L); + If L > 0 Then + Stream.WriteBuffer(B[0], L); End; - Except - End; End; -{$ENDIF} + End; + End; -Function TRESTDWMTMemBlobStream.Read(Var Buffer; Count: Longint): Longint; -Var - aBytes: TRESTDWBytes; +Procedure TRESTDWTBinaryDatapacketReader.FinalizeStoreRecords; Begin - Result := 0; - If FOpened then - Begin - If Not Assigned(FActualBlob) Then - FActualBlob := FDataSet.GetBlob(FDataSet.RecNo, FField.Offset); - If Count > (Size - FPosition) Then - Result := Size - FPosition - Else - Result := Count; - If Result > 0 then - Begin - Try - If Not Assigned(FActualBlob) Then - Exit; - Except - Exit; - End; - If Not Assigned(PRESTDWBytes(FActualBlob)^) Then - Exit; - If Result > Length(PRESTDWBytes(FActualBlob)^) Then - Begin - Result := 0; - SetLength(aBytes, Result); - TRESTDWBytes(Buffer) := aBytes; - End - Else If (Length(PRESTDWBytes(FActualBlob)^) > 0) Then - Begin - SetLength(aBytes, Result); - Try - Move(PRESTDWBytes(FActualBlob)^[FPosition], aBytes[0], Result); - Finally - Move(aBytes[0], Buffer, Result); - SetLength(aBytes, 0); - End; - End; - Inc(FPosition, Result); - End - End; + // Do nothing End; -Function TRESTDWMTMemBlobStream.Write(const Buffer; Count: Longint): Longint; +Class Function TRESTDWTBinaryDatapacketReader.RecognizeStream(AStream: TStream): boolean; Var - Temp : TMemBlobData; + s : AnsiString; + APosition : Int64; Begin - Result := 0; - If FOpened and FCached and (FMode <> bmRead) then - Begin - Temp := FDataSet.GetBlobData(FField, FBuffer); - If Length(Temp) < FPosition + Count then - SetLength(Temp, FPosition + Count); - Move(Buffer, PRESTDWMTMemBuffer(Temp)[FPosition], Count); - //SetBlobFromRecord(FField, Temp); - FDataSet.SetBlobData(FField, FBuffer, Temp); - Inc(FPosition, Count); - Result := Count; - FModified := True; - SetLength(Temp, 0); - End; + Result := False; + APosition := AStream.Position; + Try + SetLength(s, Length(RESTDWBinaryIdent)); + If AStream.Read(s[1], Length(RESTDWBinaryIdent)) = Length(RESTDWBinaryIdent) Then + Result := s = RESTDWBinaryIdent; + Finally + AStream.Position := APosition; + End; End; -Function TRESTDWMTMemBlobStream.Seek(Offset: Longint; Origin: Word): Longint; +{ TRESTDWMemUniDirectionalIndex } + +Function TRESTDWMemUniDirectionalIndex.GetBookmarkSize: integer; Begin - case Origin of - soFromBeginning: - FPosition := Offset; - soFromCurrent: - Inc(FPosition, Offset); - soFromEnd: - FPosition := GetBlobSize + Offset; - End; - Result := FPosition; + // In principle there are no bookmarks, and the size should be 0. + // But there is quite some code in TRESTDWCustomMemTable that relies on + // an existing bookmark of the TRESTDWMemBookmark type. + // This code could be moved to the TRESTDWMemInternalIndex but that would make things + // more complicated and probably slower. So use a 'fake' bookmark of + // size TRESTDWMemBookmark. + // When there are other TRESTDWMemIndexes which also need special bookmark code + // this can be adapted. + Result:=sizeof(TRESTDWMemBookmark); End; -Procedure TRESTDWMTMemBlobStream.Truncate; -Var - aBytes: TRESTDWBytes; +Function TRESTDWMemUniDirectionalIndex.GetCurrentBuffer: Pointer; Begin - If FOpened and FCached and (FMode <> bmRead) then - Begin - FDataSet.SetBlobData(FField, FBuffer, aBytes); - FModified := True; - End; + result := FSPareBuffer; End; -Function TRESTDWMTMemBlobStream.GetBlobSize: Longint; +Function TRESTDWMemUniDirectionalIndex.GetCurrentRecord: TRecordBuffer; Begin - Result := 0; - If FOpened then - Begin - If FDataSet.State = dsBrowse then - Result := Length(GetBlobFromRecord(FField)) - Else - Result := Length(TRESTDWBytes(FActualBlob^)); - End; + Result:=Nil; + // Result:=inherited GetCurrentRecord; End; -Destructor TBlobStream.Destroy; -begin -// If Assigned(FDataSet) Then -// FDataSet.SetBlobStream(Self); - Inherited Destroy; -end; - -Constructor TStreamField.Create(AOwner: TComponent); +Function TRESTDWMemUniDirectionalIndex.GetIsInitialized: boolean; Begin - Inherited Create(AOwner); - FStream := TBlobStream.Create; - TBlobStream(FStream).FDataSet := TRESTDWMemtable(AOwner); + Result := Assigned(FSPareBuffer); End; -Destructor TStreamField.Destroy; +Function TRESTDWMemUniDirectionalIndex.GetSpareBuffer: TRecordBuffer; Begin - TBlobStream(FStream).FDataSet := Nil; - FStream.Free; - Inherited Destroy; + result := FSPareBuffer; End; -Procedure TStreamField.Put; -Var - Field : TField; +Function TRESTDWMemUniDirectionalIndex.GetSpareRecord: TRecordBuffer; Begin - If Not DataSet.IsEmpty Then - Begin - With (DataSet as TRESTDWMemtable), TBlobStream(FStream) do - Begin - Field := DataSet.FindField(FieldName); - FFieldIndex := Field.Offset; - FRecNo := RecNo; -// SetBlobStream(FStream); - End; - End; + result := FSPareBuffer; End; -Function TStreamField.GetAsStream: TStream; -Var - aBytes : TRESTDWBytes; - Field : TField; - {$IFDEF FPC} - vStream : TStream; - {$ENDIF} -begin - If Not DataSet.IsEmpty then - Begin - Result := FStream; - With (DataSet as TRESTDWMemTable), TBlobStream(FStream) do - Begin - Clear; - Field := DataSet.FindField(FieldName); - FFieldIndex := Field.Offset; - FRecNo := RecNo; - {$IFDEF FPC} - vStream := DataSet.CreateBlobStream(Field, bmRead); - If Assigned(vStream) Then - Begin - vStream.Position := 0; - SetLength(aBytes, vStream.Size); - vStream.Read(aBytes, Length(aBytes)); - vStream.Free; - End; - {$ELSE} - DataSet.GetBlobFieldData(Field.Offset, TBlobByteData(aBytes)); - {$ENDIF} - If Not Assigned(Result) Then - Result := TBlobStream.Create; - TBlobStream(Result).Clear; - If Length(aBytes) > 0 Then - TBlobStream(Result).Write(aBytes, Length(aBytes)); - End; - Result.Position := 0; - End - Else - Result := nil; -end; - -Destructor TRecordList.Destroy; +Function TRESTDWMemUniDirectionalIndex.ScrollBackward: TGetResult; Begin - ClearAll; - Inherited; + result := grError; End; -Function TRecordList.GetRec(Index: Integer): TRESTDWMTMemoryRecord; +Function TRESTDWMemUniDirectionalIndex.ScrollForward: TGetResult; Begin - Result := Nil; - If (Index < Self.Count) And (Index > -1) Then - Result := TRESTDWMTMemoryRecord(Inherited Items[Index]^); + result := grOk; End; -Procedure TRecordList.PutRec(Index: Integer; Item: TRESTDWMTMemoryRecord); +Function TRESTDWMemUniDirectionalIndex.GetCurrent: TGetResult; Begin - If (Index < Self.Count) And (Index > -1) Then - TRESTDWMTMemoryRecord(Inherited Items[Index]^) := Item; + result := grOk; End; -Function TRecordList.Add(Item: TRESTDWMTMemoryRecord): Integer; -Var - vItem: PRESTDWMTMemoryRecord; +Function TRESTDWMemUniDirectionalIndex.ScrollFirst: TGetResult; Begin - New(vItem); - vItem^ := Item; - Result := Inherited Add(vItem); - vItem^.Index := Result; + Result:=grError; End; -Procedure TRecordList.Delete(Index: Integer); -Var - vItem : PRESTDWMTMemoryRecord; +Procedure TRESTDWMemUniDirectionalIndex.ScrollLast; Begin - If (Index > -1) Then - Begin - Try - If Assigned(TList(Self).Items[Index]) Then - Begin - If Assigned(TRESTDWMTMemoryRecord(TList(Self).Items[Index]^)) Then - Begin - vItem := TList(Self).Items[Index]; - vItem^.Free; - Dispose(vItem); - vItem := Nil; - End; - End; - Except - End; - Inherited Delete(Index); - End; + DatabaseError(SUniDirectional); End; -Procedure TRecordList.ClearAll; -Var - I : Integer; +Procedure TRESTDWMemUniDirectionalIndex.SetToFirstRecord; Begin - Try - For I := Count - 1 Downto 0 Do - Delete(I); - Finally - Self.Clear; - End; - Inherited Clear; + // for UniDirectional datasets should be [Internal]First valid method call + // do nothing End; -{ TRESTDWMemTableEx } - -Procedure TRESTDWMemTableEx.CopyStructure(Source: TDataSet); +Procedure TRESTDWMemUniDirectionalIndex.SetToLastRecord; Begin - inherited CopyStructure(source); - RefreshFilteredRecordCount; + DatabaseError(SUniDirectional); End; -constructor TRESTDWMemTableEx.Create(AOwner: TComponent); +Procedure TRESTDWMemUniDirectionalIndex.StoreCurrentRecord; Begin - inherited; - fSortOrder := soAsc; - fSortCaseSens := scYes; - fAutoSortOnOpen := true; - fAutoRefreshOnFilterChanged := True; - fFilteredRecordCount := 0; + DatabaseError(SUniDirectional); End; -Procedure TRESTDWMemTableEx.EmptyTable; +Procedure TRESTDWMemUniDirectionalIndex.RestoreCurrentRecord; Begin - inherited EmptyTable; - RefreshFilteredRecordCount(); + DatabaseError(SUniDirectional); End; -Function TRESTDWMemTableEx.GetFilteredRecordCount: Integer; +Function TRESTDWMemUniDirectionalIndex.CanScrollForward: Boolean; Begin - If Filtered and Active then - Result := fFilteredRecordCount - Else - result := inherited GetRecordCount; + // should return true if next record is already fetched + result := false; End; -{$IF Defined(MSWINDOWS) or Defined(WIN32) or Defined(WIN64) or Defined(WINDOWS)} -Procedure TRESTDWMemTableEx.InternalAddRecord(Buffer: Pointer; - {$IFDEF FPC}aAppend: Boolean{$ELSE}Append: Boolean{$ENDIF}); +Procedure TRESTDWMemUniDirectionalIndex.DoScrollForward; Begin - inherited InternalAddRecord(buffer, {$IFDEF FPC}aAppend{$ELSE}Append{$ENDIF}); - If Active and Filtered then - inc(fFilteredRecordCount); + // do nothing End; -{$IFEND} -Procedure TRESTDWMemTableEx.InternalDelete; +Procedure TRESTDWMemUniDirectionalIndex.StoreCurrentRecIntoBookmark(Const ABookmark: PRESTDWMemBookmark); Begin - inherited InternalDelete; - If Active and Filtered then - Dec(fFilteredRecordCount); + // do nothing End; -Procedure TRESTDWMemTableEx.InternalPost; -Var accept: Boolean; +Procedure TRESTDWMemUniDirectionalIndex.StoreSpareRecIntoBookmark(Const ABookmark: PRESTDWMemBookmark); Begin - inherited InternalPost; - If Active and Filtered then - Begin - accept := true; - - If assigned(OnFilterRecord) then - Begin - OnFilterRecord(self, accept); - If not accept then - Dec(fFilteredRecordCount); - End - End + // do nothing End; -Procedure TRESTDWMemTableEx.InternalRefresh; +Procedure TRESTDWMemUniDirectionalIndex.GotoBookmark(Const ABookmark: PRESTDWMemBookmark); Begin - inherited InternalRefresh; - If Active and Filtered then - Begin - RefreshFilteredRecordCount; - First; - End; + DatabaseError(SUniDirectional); End; -Function TRESTDWMemTableEx.IsSortField(field: TField): Boolean; -var - s, whatToSearch: string; - fieldNameEnd: Boolean; - i: integer; +Procedure TRESTDWMemUniDirectionalIndex.InitialiseIndex; Begin - Result := False; - whatToSearch := LowerCase(Trim(field.FieldName)); - fieldNameEnd := false; - i := 1; s := ''; - while (i <= Length(fSortFields)) do - Begin - case fSortFields[i] of - ';': - Begin - fieldNameEnd := true; - End; - ' ': ; - Else - s := s + fSortFields[i]; - End; - If ((i + 1) > length(fSortFields)) or fieldNameEnd then - Begin - {s = s.strip(HString::both).to_lower();} - If s <> '' then - Begin - If LowerCase(s) = whatToSearch then - Begin - Result := True; - exit; - End - End; - fieldNameEnd := false; - s := ''; ; - End; - Inc(i); - End + // do nothing End; -//Function TRESTDWMemTable.Loaded; -//Begin -// Inherited Loaded; -//End; +Procedure TRESTDWMemUniDirectionalIndex.InitialiseSpareRecord(Const ASpareRecord: TRecordBuffer); +Begin + FSPareBuffer:=ASpareRecord; +End; -Function TRESTDWMemTableEx.LoadFromDataSet(Source: TDataSet; - {$IFDEF FPC}aRecordCount: Integer; {$ELSE}RecordCount: Integer; {$ENDIF}Mode: TLoadMode): Integer; -Var wasFiltered: boolean; +Procedure TRESTDWMemUniDirectionalIndex.ReleaseSpareRecord; Begin - wasFiltered := Filtered; - result := inherited LoadFromDataSet(source, {$IFDEF FPC}aRecordCount{$ELSE}RecordCount{$ENDIF}, mode); + FSPareBuffer:=nil; +End; - Filtered := wasFiltered; +Function TRESTDWMemUniDirectionalIndex.GetRecNo: Longint; +Begin + Result := -1; +End; - If fAutoSortOnOpen then - ReSortOnFields(fSortOrder, fSortFields); - RefreshFilteredRecordCount(); - First(); +Procedure TRESTDWMemUniDirectionalIndex.SetRecNo(ARecNo: Longint); +Begin + DatabaseError(SUniDirectional); End; -Procedure TRESTDWMemTableEx.RefreshFilteredRecordCount; -var - t: TDataSetState; - savePlace: TBookmark; - i: integer; - _afterScroll, _beforeScroll: TDataSetNotifyEvent; - dsCountingFilteredRecordCount: TDataSetState; +Procedure TRESTDWMemUniDirectionalIndex.BeginUpdate; Begin -//#define dsCountingFilteredRecordCount ((TDataSetState)(dsOpening+1)) -//type TDataSetState = (dsInactive, dsBrowse, dsEdit, dsInsert, dsSetKey, dsCalcFields, dsFilter, dsNewValue, dsOldValue, dsCurValue, dsBlockRead, dsInternalCalc, dsOpening); - fFilteredRecordCount := 0; + // Do nothing +End; - If Filtered and Active then +Procedure TRESTDWMemUniDirectionalIndex.AddRecord; +Var +h,i: integer; +Begin + // Release unneeded blob buffers, in order to save memory + // TDataSet has own buffer of records, so do not release blobs until they can be referenced + With FDataSet Do Begin - - i := 0; - - savePlace := GetBookmark(); - _afterScroll := AfterScroll; - _beforeScroll := BeforeScroll; - dsCountingFilteredRecordCount := TDataSetState(Ord(dsOpening) + 1); - {store last state} - t := SetTempState(dsCountingFilteredRecordCount); - - Try - AfterScroll := nil; - BeforeScroll := nil; - DisableControls; - First; - while not Eof do - Begin - inc(i); - Next(); - End; - fFilteredRecordCount := i; - - Finally - aFilterRecs := 0; - If (fFilteredRecordCount > 0) and assigned(savePlace) and BookmarkValid(savePlace) then - GotoBookmark(savePlace); - FreeBookmark(savePlace); - AfterScroll := _afterScroll; - BeforeScroll := _beforeScroll; - {restore state here} - RestoreState(t); - EnableControls; - End; + h := high(FBlobBuffers) - BufferCount*BlobFieldCount; + If h > 10 Then //Free in batches, starting with oldest (at beginning) + Begin + For i := 0 To h Do + FreeBlobBuffer(FBlobBuffers[i]); + FBlobBuffers := Copy(FBlobBuffers, h+1, high(FBlobBuffers)-h); + End; End; End; -Procedure TRESTDWMemTableEx.ReSortOnFields(pSortOrder: TSortOrder; - {$IFDEF FPC}afields: string{$ELSE}fields: string{$ENDIF}); -var - sAfterScroll: TDataSetNotifyEvent; - savePlace: TBookmark; - b: boolean; - oldSortFiels: string; +Procedure TRESTDWMemUniDirectionalIndex.InsertRecordBeforeCurrentRecord(Const ARecord: TRecordBuffer); Begin - If {$IFDEF FPC}afields{$ELSE}fields{$ENDIF} = '' then - {$IFDEF FPC}afields{$ELSE}fields{$ENDIF} := sortFields; - - fSortOrder := pSortOrder; // new sort order - oldSortFiels := fSortFields; - fSortFields := {$IFDEF FPC}afields{$ELSE}fields{$ENDIF}; - - sAfterScroll := AfterScroll; - AfterScroll := nil; - DisableControls(); - Try - savePlace := GetBookmark(); - b := not boolean(fSortCaseSens); - SortOnFields(fSortFields, b, fSortOrder = soDesc); + // Do nothing +End; - If assigned(savePlace) then - GotoBookmark(savePlace); - FreeBookmark(savePlace); - Finally - fSortFields := oldSortFiels; - EnableControls(); - AfterScroll := sAfterScroll; - End; +Procedure TRESTDWMemUniDirectionalIndex.RemoveRecordFromIndex(Const ABookmark: TRESTDWMemBookmark); +Begin + DatabaseError(SUniDirectional); End; -Procedure TRESTDWMemTableEx.SetFiltered(Value: Boolean); +Procedure TRESTDWMemUniDirectionalIndex.OrderCurrentRecord; Begin - inherited SetFiltered(Value); - If (Active and (fAutoRefreshOnFilterChanged)) then - // Refresh() - //Else - RefreshFilteredRecordCount(); + // Do nothing End; -Procedure TRESTDWMemTableEx.SetOnFilterRecord( - const Value: TFilterRecordEvent); +Procedure TRESTDWMemUniDirectionalIndex.EndUpdate; Begin - inherited SetOnFilterRecord(value); - If (fAutoRefreshOnFilterChanged) then - InternalRefresh() - Else - RefreshFilteredRecordCount(); + // Do nothing End; -end. +Initialization + setlength(RegisteredDatapacketReaders,0); +Finalization + setlength(RegisteredDatapacketReaders,0); +End. \ No newline at end of file diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemoryDatasetParser.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemoryDatasetParser.pas new file mode 100644 index 000000000..8b244f843 --- /dev/null +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemoryDatasetParser.pas @@ -0,0 +1,539 @@ +Unit uRESTDWMemoryDatasetParser; + +Interface + +Uses + SysUtils, + Classes, + db, + uRESTDWMemoryDatasetParserCore, + uRESTDWMemoryDatasetParserDefs; + +Type + + TRESTDWMemParser = Class(TRESTDWMemCustomExpressionParser) + Private + FDataset: TDataSet; + FFieldVarList: TStringList; + FResultLen: Integer; + FIsExpression: Boolean; // expression or simple field? + FFieldType: TRESTDWMemExpressionType; + FCaseInsensitive: Boolean; + FPartialMatch: boolean; + + Protected + FCurrentExpression: string; + + Procedure FillExpressList; override; + Procedure HandleUnknownVariable(VarName: string); override; + Function GetVariableInfo(VarName: string): TField; + Function CurrentExpression: string; override; + Function GetResultType: TRESTDWMemExpressionType; override; + + Procedure SetCaseInsensitive(NewInsensitive: Boolean); + Procedure SetPartialMatch(NewPartialMatch: boolean); + Public + Constructor Create(ADataset: TDataset); + Destructor Destroy; override; + + Procedure ClearExpressions; override; + + Procedure ParseExpression(AExpression: string); virtual; + Function ExtractFromBuffer(Buffer: TRecordBuffer): PChar; virtual; + + property Dataset: TDataSet read FDataset; // write FDataset; + property Expression: string read FCurrentExpression; + property ResultLen: Integer read FResultLen; + + property CaseInsensitive: Boolean read FCaseInsensitive write SetCaseInsensitive; + property PartialMatch: boolean read FPartialMatch write SetPartialMatch; + End; + +Implementation + +Uses + {$IFDEF FPC}dbconst{$ELSE}DBConsts{$ENDIF}; + +{$IFNDEF FPC} +Const + SErrIndexBasedOnUnkField = 'Index based on unknown field %s'; + SErrIndexBasedOnInvField = 'Index based on invalid field %s (%s)'; + SErrIndexResultTooLong = 'Index expression %s result is too long (%d)'; +{$ENDIF} + +Type +{$IFNDEF FPC} + TStringFieldBuffer = array[0..dsMaxStringSize] Of AnsiChar; +{$ENDIF} + +// TRESTDWMemFieldVar aids in retrieving field values from records +// in their proper type + + TRESTDWMemFieldVar = Class(TObject) + Private + FField: TField; + FFieldName: string; + FExprWord: TRESTDWMemExprWord; + Protected + Function GetFieldVal: Pointer; virtual; abstract; + Function GetFieldType: TRESTDWMemExpressionType; virtual; abstract; + Public + Constructor Create(UseField: TField); + + Procedure Refresh(Buffer: TRecordBuffer); virtual; abstract; + + property FieldVal: Pointer read GetFieldVal; + property FieldDef: TField read FField; + property FieldType: TRESTDWMemExpressionType read GetFieldType; + property FieldName: string read FFieldName; + End; + + TRESTDWMemStringFieldVar = Class(TRESTDWMemFieldVar) + Protected + FFieldVal: {$IFDEF FPC}PChar{$ELSE}PAnsiChar{$ENDIF}; + + Function GetFieldVal: Pointer; override; + Function GetFieldType: TRESTDWMemExpressionType; override; + Public + Constructor Create(UseField: TField); + Destructor Destroy; override; + + Procedure Refresh(Buffer: TRecordBuffer); override; + End; + + TRESTDWMemFloatFieldVar = Class(TRESTDWMemFieldVar) + Private + FFieldVal: Double; + Protected + Function GetFieldVal: Pointer; override; + Function GetFieldType: TRESTDWMemExpressionType; override; + Public + Procedure Refresh(Buffer: TRecordBuffer); override; + End; + + TRESTDWMemIntegerFieldVar = Class(TRESTDWMemFieldVar) + Private + FFieldVal: Integer; + Protected + Function GetFieldVal: Pointer; override; + Function GetFieldType: TRESTDWMemExpressionType; override; + Public + Procedure Refresh(Buffer: TRecordBuffer); override; + End; + + TRESTDWMemLargeIntFieldVar = Class(TRESTDWMemFieldVar) + Private + FFieldVal: Int64; + Protected + Function GetFieldVal: Pointer; override; + Function GetFieldType: TRESTDWMemExpressionType; override; + Public + Procedure Refresh(Buffer: TRecordBuffer); override; + End; + + TRESTDWMemDateTimeFieldVar = Class(TRESTDWMemFieldVar) + Private + FFieldVal: TDateTime; + Function GetFieldType: TRESTDWMemExpressionType; override; + Protected + Function GetFieldVal: Pointer; override; + Public + Procedure Refresh(Buffer: TRecordBuffer); override; + End; + + TRESTDWMemBooleanFieldVar = Class(TRESTDWMemFieldVar) + Private + FFieldVal: wordbool; + Function GetFieldType: TRESTDWMemExpressionType; override; + Protected + Function GetFieldVal: Pointer; override; + Public + Procedure Refresh(Buffer: TRecordBuffer); override; + End; + + TRESTDWMemBCDFieldVar = Class(TRESTDWMemFloatFieldVar) + Public + Procedure Refresh(Buffer: TRecordBuffer); override; + End; + + +//--TRESTDWMemFieldVar---------------------------------------------------------------- +Constructor TRESTDWMemFieldVar.Create(UseField: TField); +Begin + Inherited Create; + + // store field + //FDataset := ADataset; + FField := UseField; + FFieldName := UseField.FieldName; +End; + +//--TRESTDWMemStringFieldVar------------------------------------------------------------- +Function TRESTDWMemStringFieldVar.GetFieldVal: Pointer; +Begin + Result := @FFieldVal; +End; + +Function TRESTDWMemStringFieldVar.GetFieldType: TRESTDWMemExpressionType; +Begin + Result := etString; +End; + +Constructor TRESTDWMemStringFieldVar.Create(UseField: TField); +Begin + Inherited; + + GetMem(FFieldVal, dsMaxStringSize+1); +End; + +Destructor TRESTDWMemStringFieldVar.Destroy; +Begin + FreeMem(FFieldVal); + + Inherited; +End; + +Procedure TRESTDWMemStringFieldVar.Refresh(Buffer: TRecordBuffer); +Var Fieldbuf : TStringFieldBuffer; +Begin + If not FField.DataSet.GetFieldData(FField,@Fieldbuf) Then + FFieldVal^:=#0 + Else + strcopy(FFieldVal,@Fieldbuf[0]); +End; + +//--TRESTDWMemFloatFieldVar----------------------------------------------------------- +Function TRESTDWMemFloatFieldVar.GetFieldVal: Pointer; +Begin + Result := @FFieldVal; +End; + +Function TRESTDWMemFloatFieldVar.GetFieldType: TRESTDWMemExpressionType; +Begin + Result := etFloat; +End; + +Procedure TRESTDWMemFloatFieldVar.Refresh(Buffer: TRecordBuffer); +Begin + If not FField.DataSet.GetFieldData(FField,@FFieldVal) Then + FFieldVal := 0; +End; + +//--TRESTDWMemIntegerFieldVar---------------------------------------------------------- +Function TRESTDWMemIntegerFieldVar.GetFieldVal: Pointer; +Begin + Result := @FFieldVal; +End; + +Function TRESTDWMemIntegerFieldVar.GetFieldType: TRESTDWMemExpressionType; +Begin + Result := etInteger; +End; + +Procedure TRESTDWMemIntegerFieldVar.Refresh(Buffer: TRecordBuffer); +Begin + If not FField.DataSet.GetFieldData(FField,@FFieldVal) Then + FFieldVal := 0; +End; + +//--TRESTDWMemLargeIntFieldVar---------------------------------------------------------- +Function TRESTDWMemLargeIntFieldVar.GetFieldVal: Pointer; +Begin + Result := @FFieldVal; +End; + +Function TRESTDWMemLargeIntFieldVar.GetFieldType: TRESTDWMemExpressionType; +Begin + Result := etLargeInt; +End; + +Procedure TRESTDWMemLargeIntFieldVar.Refresh(Buffer: TRecordBuffer); +Begin + If not FField.DataSet.GetFieldData(FField,@FFieldVal) Then + FFieldVal := 0; +End; + +//--TRESTDWMemDateTimeFieldVar--------------------------------------------------------- +Function TRESTDWMemDateTimeFieldVar.GetFieldVal: Pointer; +Begin + Result := @FFieldVal; +End; + +Function TRESTDWMemDateTimeFieldVar.GetFieldType: TRESTDWMemExpressionType; +Begin + Result := etDateTime; +End; + +Procedure TRESTDWMemDateTimeFieldVar.Refresh(Buffer:TRecordBuffer ); +Begin + If not FField.DataSet.GetFieldData(FField,@FFieldVal) Then + FFieldVal := 0; +End; + +//--TRESTDWMemBooleanFieldVar--------------------------------------------------------- +Function TRESTDWMemBooleanFieldVar.GetFieldVal: Pointer; +Begin + Result := @FFieldVal; +End; + +Function TRESTDWMemBooleanFieldVar.GetFieldType: TRESTDWMemExpressionType; +Begin + Result := etBoolean; +End; + +Procedure TRESTDWMemBooleanFieldVar.Refresh(Buffer: TRecordBuffer); +Begin + If not FField.DataSet.GetFieldData(FField,@FFieldVal) Then + FFieldVal := False; +End; + +Procedure TRESTDWMemBCDFieldVar.Refresh(Buffer: TRecordBuffer); +Var c: currency; +Begin + If FField.DataSet.GetFieldData(FField,@c) Then + FFieldVal := c + Else + FFieldVal := 0; +End; + + +//--TRESTDWMemParser--------------------------------------------------------------- + +Constructor TRESTDWMemParser.Create(Adataset: TDataSet); +Begin + FDataset := Adataset; + FFieldVarList := TStringList.Create; + FCaseInsensitive := true; + Inherited Create; +End; + +Destructor TRESTDWMemParser.Destroy; +Begin + ClearExpressions; + Inherited; + FreeAndNil(FFieldVarList); +End; + +Function TRESTDWMemParser.GetResultType: TRESTDWMemExpressionType; +Begin + // if not a real expression, return type ourself + If FIsExpression Then + Result := Inherited GetResultType + Else + Result := FFieldType; +End; + +Procedure TRESTDWMemParser.SetCaseInsensitive(NewInsensitive: Boolean); +Begin + If FCaseInsensitive <> NewInsensitive Then + Begin + // clear and regenerate functions + FCaseInsensitive := NewInsensitive; + FillExpressList; + End; +End; + +Procedure TRESTDWMemParser.SetPartialMatch(NewPartialMatch: boolean); +Begin + If FPartialMatch <> NewPartialMatch Then + Begin + // refill function list + FPartialMatch := NewPartialMatch; + FillExpressList; + End; +End; + +Procedure TRESTDWMemParser.FillExpressList; +Var + lExpression: string; +Begin + lExpression := FCurrentExpression; + ClearExpressions; + FWordsList.FreeAll; + FWordsList.AddList(DbfWordsGeneralList, 0, DbfWordsGeneralList.Count - 1); + If FCaseInsensitive Then + Begin + FWordsList.AddList(DbfWordsInsensGeneralList, 0, DbfWordsInsensGeneralList.Count - 1); + If FPartialMatch Then + Begin + FWordsList.AddList(DbfWordsInsensPartialList, 0, DbfWordsInsensPartialList.Count - 1); + End Else Begin + FWordsList.AddList(DbfWordsInsensNoPartialList, 0, DbfWordsInsensNoPartialList.Count - 1); + End; +End Else Begin + FWordsList.AddList(DbfWordsSensGeneralList, 0, DbfWordsSensGeneralList.Count - 1); + If FPartialMatch Then + Begin + FWordsList.AddList(DbfWordsSensPartialList, 0, DbfWordsSensPartialList.Count - 1); + End Else Begin + FWordsList.AddList(DbfWordsSensNoPartialList, 0, DbfWordsSensNoPartialList.Count - 1); + End; + End; + If Length(lExpression) > 0 Then + ParseExpression(lExpression); +End; + +Function TRESTDWMemParser.GetVariableInfo(VarName: string): TField; +Begin + Result := FDataset.FindField(VarName); +End; + +Function TRESTDWMemParser.CurrentExpression: string; +Begin + Result := FCurrentExpression; +End; + +Procedure TRESTDWMemParser.HandleUnknownVariable(VarName: string); +Var + FieldInfo: TField; + TempFieldVar: TRESTDWMemFieldVar; +Begin + // is this variable a fieldname? + FieldInfo := GetVariableInfo(VarName); + If FieldInfo = nil Then + raise EDatabaseError.CreateFmt(SErrIndexBasedOnUnkField, [VarName]); + + // define field in parser + Case FieldInfo.DataType Of + ftString, ftFixedChar: + Begin + TempFieldVar := TRESTDWMemStringFieldVar.Create(FieldInfo); + TempFieldVar.FExprWord := DefineStringVariable(VarName, TempFieldVar.FieldVal); + TempFieldVar.FExprWord.fixedlen := Fieldinfo.Size; + End; + ftBoolean: + Begin + TempFieldVar := TRESTDWMemBooleanFieldVar.Create(FieldInfo); + TempFieldVar.FExprWord := DefineBooleanVariable(VarName, TempFieldVar.FieldVal); + End; + ftFloat: + Begin + TempFieldVar := TRESTDWMemFloatFieldVar.Create(FieldInfo); + TempFieldVar.FExprWord := DefineFloatVariable(VarName, TempFieldVar.FieldVal); + End; + ftAutoInc, ftInteger, ftSmallInt, ftWord: + Begin + TempFieldVar := TRESTDWMemIntegerFieldVar.Create(FieldInfo); + TempFieldVar.FExprWord := DefineIntegerVariable(VarName, TempFieldVar.FieldVal); + End; + ftLargeInt: + Begin + TempFieldVar := TRESTDWMemLargeIntFieldVar.Create(FieldInfo); + TempFieldVar.FExprWord := DefineLargeIntVariable(VarName, TempFieldVar.FieldVal); + End; + ftDate, ftDateTime: + Begin + TempFieldVar := TRESTDWMemDateTimeFieldVar.Create(FieldInfo); + TempFieldVar.FExprWord := DefineDateTimeVariable(VarName, TempFieldVar.FieldVal); + End; + ftBCD: + Begin + TempFieldVar := TRESTDWMemBCDFieldVar.Create(FieldInfo); + TempFieldVar.FExprWord := DefineFloatVariable(VarName, TempFieldVar.FieldVal); + End; + Else + raise EDatabaseError.CreateFmt(SErrIndexBasedOnInvField, [VarName,Fieldtypenames[FieldInfo.DataType]]); +End; + + // add to our own list + FFieldVarList.AddObject(VarName, TempFieldVar); +End; + +Procedure TRESTDWMemParser.ClearExpressions; +Var + I: Integer; +Begin + Inherited; + + // test if already freed + If FFieldVarList <> nil Then + Begin + // free field list + For I := 0 To FFieldVarList.Count - 1 Do + Begin + // replacing with nil = undefining variable + FWordsList.DoFree(TRESTDWMemFieldVar(FFieldVarList.Objects[I]).FExprWord); + TRESTDWMemFieldVar(FFieldVarList.Objects[I]).Free; + End; + FFieldVarList.Clear; + End; + + // clear expression + FCurrentExpression := EmptyStr; +End; + +Procedure TRESTDWMemParser.ParseExpression(AExpression: string); +Var + TempBuffer: TRecordBuffer; +Begin + // clear any current expression + ClearExpressions; + + // is this a simple field or complex expression? + FIsExpression := GetVariableInfo(AExpression) = nil; + If FIsExpression Then + Begin + // parse requested + CompileExpression(AExpression); + + // determine length of string length expressions + If ResultType = etString Then + Begin + // make empty record + GetMem(TempBuffer, FDataset.RecordSize); + Try + FillChar(TempBuffer^, FDataset.RecordSize, #0); + FResultLen := StrLen(ExtractFromBuffer(TempBuffer)); + Finally + FreeMem(TempBuffer); + End; + End; +End Else Begin + // simple field, create field variable for it + HandleUnknownVariable(AExpression); + FFieldType := TRESTDWMemFieldVar(FFieldVarList.Objects[0]).FieldType; + // set result len of variable length fields + If FFieldType = etString Then + FResultLen := TRESTDWMemFieldVar(FFieldVarList.Objects[0]).FieldDef.Size + End; + + // set result len for fixed length expressions / fields + Case ResultType Of + etBoolean: FResultLen := 1; + etInteger: FResultLen := 4; + etFloat: FResultLen := 8; + etDateTime: FResultLen := 8; + End; + + // check if expression not too long + If FResultLen > 100 Then + raise EDatabaseError.CreateFmt(SErrIndexResultTooLong, [AExpression, FResultLen]); + + // if no errors, assign current expression + FCurrentExpression := AExpression; +End; + +Function TRESTDWMemParser.ExtractFromBuffer(Buffer: TRecordBuffer): PChar; +Var + I: Integer; +Begin + // prepare all field variables + For I := 0 To FFieldVarList.Count - 1 Do + TRESTDWMemFieldVar(FFieldVarList.Objects[I]).Refresh(Buffer); + + // complex expression? + If FIsExpression Then + Begin + // execute expression + EvaluateCurrent; + Result := ExpResult; + End Else Begin + // simple field, get field result + Result := TRESTDWMemFieldVar(FFieldVarList.Objects[0]).FieldVal; + // if string then dereference + If FFieldType = etString Then + Result := PPChar(Result)^; +End; +End; + +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemoryDatasetParserCore.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemoryDatasetParserCore.pas new file mode 100644 index 000000000..bbdb8ed53 --- /dev/null +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemoryDatasetParserCore.pas @@ -0,0 +1,2408 @@ +Unit uRESTDWMemoryDatasetParserCore; + +{-------------------------------------------------------------- +| TRESTDWMemCustomExpressionParser +| +| - contains core expression parser +| +| This code is based on code from: +| +| Original author: Egbert van Nes +| With contributions of: John Bultena and Ralf Junker +| Homepage: http://www.slm.wau.nl/wkao/parseexpr.html +| +| see also: http://www.datalog.ro/delphi/parser.html +| (Renate Schaaf (schaaf at math.usu.edu), 1993 +| Alin Flaider (aflaidar at datalog.ro), 1996 +| Version 9-10: Stefan Hoffmeister, 1996-1997) +| +|---------------------------------------------------------------} + +Interface + +{$I uRESTDW.inc} +{$DEFINE RESTDW_SUPPORT_INT64} + +Uses + SysUtils, + Classes, + Db, + uRESTDWMemoryDatasetParserSupport, + uRESTDWMemoryDatasetParserDefs; + +{$define ENG_NUMBERS} + +// ENG_NUMBERS will force the use of English style numbers 8.1 instead of 8,1 +// (if the comma is your decimal separator) +// The advantage is that arguments can be separated with a comma which is +// fairly common, otherwise there is ambiguity: what does 'var1,8,4,4,5' mean? +// If you don't define ENG_NUMBERS and DecimalSeparator is a comma then +// the argument separator will be a semicolon ';' + +Type + + TRESTDWMemCustomExpressionParser = Class(TObject) + Private + FHexChar: Char; + FArgSeparator: Char; + FDecimalSeparator: Char; + FOptimize: Boolean; + FConstantsList: TRESTDWMemOCollection; + FLastRec: PRESTDWMemExpressionRec; + FCurrentRec: PRESTDWMemExpressionRec; + FExpResult: PChar; + FExpResultPos: PChar; + FExpResultSize: Integer; + + Procedure ParseString(AnExpression: string; DestCollection: TRESTDWMemExprCollection); + Function MakeTree(Expr: TRESTDWMemExprCollection; FirstItem, LastItem: Integer): PRESTDWMemExpressionRec; + Procedure MakeLinkedList(Var ExprRec: PRESTDWMemExpressionRec; Memory: PPChar; + MemoryPos: PPChar; MemSize: PInteger); + Procedure Check(AnExprList: TRESTDWMemExprCollection); + Procedure CheckArguments(ExprRec: PRESTDWMemExpressionRec); + Procedure RemoveConstants(Var ExprRec: PRESTDWMemExpressionRec); + Function ResultCanVary(ExprRec: PRESTDWMemExpressionRec): Boolean; + Protected + FWordsList: TRESTDWMemSortedCollection; + + Function MakeRec: PRESTDWMemExpressionRec; virtual; + Procedure FillExpressList; virtual; abstract; + Procedure HandleUnknownVariable(VarName: string); virtual; abstract; + + Procedure CompileExpression(AnExpression: string); + Procedure EvaluateCurrent; + Procedure DisposeList(ARec: PRESTDWMemExpressionRec); + Procedure DisposeTree(ExprRec: PRESTDWMemExpressionRec); + Function CurrentExpression: string; virtual; abstract; + Function GetResultType: TRESTDWMemExpressionType; virtual; + + property CurrentRec: PRESTDWMemExpressionRec read FCurrentRec write FCurrentRec; + property LastRec: PRESTDWMemExpressionRec read FLastRec write FLastRec; + property ExpResult: PChar read FExpResult; + property ExpResultPos: PChar read FExpResultPos write FExpResultPos; + + Public + Constructor Create; + Destructor Destroy; override; + + Function DefineFloatVariable(AVarName: string; AValue: PDouble): TRESTDWMemExprWord; + Function DefineIntegerVariable(AVarName: string; AValue: PInteger): TRESTDWMemExprWord; +// procedure DefineSmallIntVariable(AVarName: string; AValue: PSmallInt); +{$IFDEF RESTDW_SUPPORT_INT64} + Function DefineLargeIntVariable(AVarName: string; AValue: PRESTDWMemLargeInt): TRESTDWMemExprWord; +{$ENDIF} + Function DefineDateTimeVariable(AVarName: string; AValue: PRESTDWMemDateTimeRec): TRESTDWMemExprWord; + Function DefineBooleanVariable(AVarName: string; AValue: PBoolean): TRESTDWMemExprWord; + Function DefineStringVariable(AVarName: string; AValue: PPChar): TRESTDWMemExprWord; + Function DefineFunction(AFunctName, AShortName, ADescription, ATypeSpec: string; + AMinFunctionArg: Integer; AResultType: TRESTDWMemExpressionType; AFuncAddress: TRESTDWMemExprFunc): TRESTDWMemExprWord; + Procedure Evaluate(AnExpression: string); + Function AddExpression(AnExpression: string): Integer; + Procedure ClearExpressions; virtual; +// procedure GetGeneratedVars(AList: TList); + Procedure GetFunctionNames(AList: TStrings); + Function GetFunctionDescription(AFunction: string): string; + property HexChar: Char read FHexChar write FHexChar; + property ArgSeparator: Char read FArgSeparator write FArgSeparator; + property Optimize: Boolean read FOptimize write FOptimize; + property ResultType: TRESTDWMemExpressionType read GetResultType; + + //If optimize is selected, the code tries to remove constant expressions + //Examples: 4*4*x is evaluated as 16*x and exp(1)-4*x is replaced by 2.17 -4*x + End; + + +//--Expression functions----------------------------------------------------- +//I: Integer; L: Large Integer (Int64); F: Double; S: String; B: Boolean + +Procedure FuncFloatToStr(Param: PRESTDWMemExpressionRec); +Procedure FuncIntToStr_Gen(Param: PRESTDWMemExpressionRec; Val: {$IFDEF RESTDW_SUPPORT_INT64}Int64{$else}Integer{$ENDIF}); +Procedure FuncIntToStr(Param: PRESTDWMemExpressionRec); +{$IFDEF RESTDW_SUPPORT_INT64} +Procedure FuncInt64ToStr(Param: PRESTDWMemExpressionRec); +{$ENDIF} +Procedure FuncDateToStr(Param: PRESTDWMemExpressionRec); +Procedure FuncSubString(Param: PRESTDWMemExpressionRec); +Procedure FuncUppercase(Param: PRESTDWMemExpressionRec); +Procedure FuncLowercase(Param: PRESTDWMemExpressionRec); +Procedure FuncNegative_F_F(Param: PRESTDWMemExpressionRec); +Procedure FuncNegative_I_I(Param: PRESTDWMemExpressionRec); +{$IFDEF RESTDW_SUPPORT_INT64} +Procedure FuncNegative_L_L(Param: PRESTDWMemExpressionRec); +{$ENDIF} +Procedure FuncAdd_F_FF(Param: PRESTDWMemExpressionRec); +Procedure FuncAdd_F_FI(Param: PRESTDWMemExpressionRec); +Procedure FuncAdd_F_II(Param: PRESTDWMemExpressionRec); +Procedure FuncAdd_F_IF(Param: PRESTDWMemExpressionRec); +{$IFDEF RESTDW_SUPPORT_INT64} +Procedure FuncAdd_F_FL(Param: PRESTDWMemExpressionRec); +Procedure FuncAdd_F_IL(Param: PRESTDWMemExpressionRec); +Procedure FuncAdd_F_LL(Param: PRESTDWMemExpressionRec); +Procedure FuncAdd_F_LF(Param: PRESTDWMemExpressionRec); +Procedure FuncAdd_F_LI(Param: PRESTDWMemExpressionRec); +{$ENDIF} +Procedure FuncSub_F_FF(Param: PRESTDWMemExpressionRec); +Procedure FuncSub_F_FI(Param: PRESTDWMemExpressionRec); +Procedure FuncSub_F_II(Param: PRESTDWMemExpressionRec); +Procedure FuncSub_F_IF(Param: PRESTDWMemExpressionRec); +{$IFDEF RESTDW_SUPPORT_INT64} +Procedure FuncSub_F_FL(Param: PRESTDWMemExpressionRec); +Procedure FuncSub_F_IL(Param: PRESTDWMemExpressionRec); +Procedure FuncSub_F_LL(Param: PRESTDWMemExpressionRec); +Procedure FuncSub_F_LF(Param: PRESTDWMemExpressionRec); +Procedure FuncSub_F_LI(Param: PRESTDWMemExpressionRec); +{$ENDIF} +Procedure FuncMul_F_FF(Param: PRESTDWMemExpressionRec); +Procedure FuncMul_F_FI(Param: PRESTDWMemExpressionRec); +Procedure FuncMul_F_II(Param: PRESTDWMemExpressionRec); +Procedure FuncMul_F_IF(Param: PRESTDWMemExpressionRec); +{$IFDEF RESTDW_SUPPORT_INT64} +Procedure FuncMul_F_FL(Param: PRESTDWMemExpressionRec); +Procedure FuncMul_F_IL(Param: PRESTDWMemExpressionRec); +Procedure FuncMul_F_LL(Param: PRESTDWMemExpressionRec); +Procedure FuncMul_F_LF(Param: PRESTDWMemExpressionRec); +Procedure FuncMul_F_LI(Param: PRESTDWMemExpressionRec); +{$ENDIF} +Procedure FuncDiv_F_FF(Param: PRESTDWMemExpressionRec); +Procedure FuncDiv_F_FI(Param: PRESTDWMemExpressionRec); +Procedure FuncDiv_F_II(Param: PRESTDWMemExpressionRec); +Procedure FuncDiv_F_IF(Param: PRESTDWMemExpressionRec); +{$IFDEF RESTDW_SUPPORT_INT64} +Procedure FuncDiv_F_FL(Param: PRESTDWMemExpressionRec); +Procedure FuncDiv_F_IL(Param: PRESTDWMemExpressionRec); +Procedure FuncDiv_F_LL(Param: PRESTDWMemExpressionRec); +Procedure FuncDiv_F_LF(Param: PRESTDWMemExpressionRec); +Procedure FuncDiv_F_LI(Param: PRESTDWMemExpressionRec); +{$ENDIF} +Procedure FuncStrI_EQ(Param: PRESTDWMemExpressionRec); +Procedure FuncStrI_NEQ(Param: PRESTDWMemExpressionRec); +Procedure FuncStrI_LT(Param: PRESTDWMemExpressionRec); +Procedure FuncStrI_GT(Param: PRESTDWMemExpressionRec); +Procedure FuncStrI_LTE(Param: PRESTDWMemExpressionRec); +Procedure FuncStrI_GTE(Param: PRESTDWMemExpressionRec); +Procedure FuncStrIP_EQ(Param: PRESTDWMemExpressionRec); +Procedure FuncStrP_EQ(Param: PRESTDWMemExpressionRec); +Procedure FuncStr_EQ(Param: PRESTDWMemExpressionRec); +Procedure FuncStr_NEQ(Param: PRESTDWMemExpressionRec); +Procedure FuncStr_LT(Param: PRESTDWMemExpressionRec); +Procedure FuncStr_GT(Param: PRESTDWMemExpressionRec); +Procedure FuncStr_LTE(Param: PRESTDWMemExpressionRec); +Procedure FuncStr_GTE(Param: PRESTDWMemExpressionRec); +Procedure Func_FF_EQ(Param: PRESTDWMemExpressionRec); +Procedure Func_FF_NEQ(Param: PRESTDWMemExpressionRec); +Procedure Func_FF_LT(Param: PRESTDWMemExpressionRec); +Procedure Func_FF_GT(Param: PRESTDWMemExpressionRec); +Procedure Func_FF_LTE(Param: PRESTDWMemExpressionRec); +Procedure Func_FF_GTE(Param: PRESTDWMemExpressionRec); +Procedure Func_FI_EQ(Param: PRESTDWMemExpressionRec); +Procedure Func_FI_NEQ(Param: PRESTDWMemExpressionRec); +Procedure Func_FI_LT(Param: PRESTDWMemExpressionRec); +Procedure Func_FI_GT(Param: PRESTDWMemExpressionRec); +Procedure Func_FI_LTE(Param: PRESTDWMemExpressionRec); +Procedure Func_FI_GTE(Param: PRESTDWMemExpressionRec); +Procedure Func_II_EQ(Param: PRESTDWMemExpressionRec); +Procedure Func_II_NEQ(Param: PRESTDWMemExpressionRec); +Procedure Func_II_LT(Param: PRESTDWMemExpressionRec); +Procedure Func_II_GT(Param: PRESTDWMemExpressionRec); +Procedure Func_II_LTE(Param: PRESTDWMemExpressionRec); +Procedure Func_II_GTE(Param: PRESTDWMemExpressionRec); +Procedure Func_IF_EQ(Param: PRESTDWMemExpressionRec); +Procedure Func_IF_NEQ(Param: PRESTDWMemExpressionRec); +Procedure Func_IF_LT(Param: PRESTDWMemExpressionRec); +Procedure Func_IF_GT(Param: PRESTDWMemExpressionRec); +Procedure Func_IF_LTE(Param: PRESTDWMemExpressionRec); +Procedure Func_IF_GTE(Param: PRESTDWMemExpressionRec); +{$IFDEF RESTDW_SUPPORT_INT64} +Procedure Func_LL_EQ(Param: PRESTDWMemExpressionRec); +Procedure Func_LL_NEQ(Param: PRESTDWMemExpressionRec); +Procedure Func_LL_LT(Param: PRESTDWMemExpressionRec); +Procedure Func_LL_GT(Param: PRESTDWMemExpressionRec); +Procedure Func_LL_LTE(Param: PRESTDWMemExpressionRec); +Procedure Func_LL_GTE(Param: PRESTDWMemExpressionRec); +Procedure Func_LF_EQ(Param: PRESTDWMemExpressionRec); +Procedure Func_LF_NEQ(Param: PRESTDWMemExpressionRec); +Procedure Func_LF_LT(Param: PRESTDWMemExpressionRec); +Procedure Func_LF_GT(Param: PRESTDWMemExpressionRec); +Procedure Func_LF_LTE(Param: PRESTDWMemExpressionRec); +Procedure Func_LF_GTE(Param: PRESTDWMemExpressionRec); +Procedure Func_FL_EQ(Param: PRESTDWMemExpressionRec); +Procedure Func_FL_NEQ(Param: PRESTDWMemExpressionRec); +Procedure Func_FL_LT(Param: PRESTDWMemExpressionRec); +Procedure Func_FL_GT(Param: PRESTDWMemExpressionRec); +Procedure Func_FL_LTE(Param: PRESTDWMemExpressionRec); +Procedure Func_FL_GTE(Param: PRESTDWMemExpressionRec); +Procedure Func_LI_EQ(Param: PRESTDWMemExpressionRec); +Procedure Func_LI_NEQ(Param: PRESTDWMemExpressionRec); +Procedure Func_LI_LT(Param: PRESTDWMemExpressionRec); +Procedure Func_LI_GT(Param: PRESTDWMemExpressionRec); +Procedure Func_LI_LTE(Param: PRESTDWMemExpressionRec); +Procedure Func_LI_GTE(Param: PRESTDWMemExpressionRec); +Procedure Func_IL_EQ(Param: PRESTDWMemExpressionRec); +Procedure Func_IL_NEQ(Param: PRESTDWMemExpressionRec); +Procedure Func_IL_LT(Param: PRESTDWMemExpressionRec); +Procedure Func_IL_GT(Param: PRESTDWMemExpressionRec); +Procedure Func_IL_LTE(Param: PRESTDWMemExpressionRec); +Procedure Func_IL_GTE(Param: PRESTDWMemExpressionRec); +{$ENDIF} +Procedure Func_AND(Param: PRESTDWMemExpressionRec); +Procedure Func_OR(Param: PRESTDWMemExpressionRec); +Procedure Func_NOT(Param: PRESTDWMemExpressionRec); + +Var + DbfWordsSensGeneralList, DbfWordsInsensGeneralList: TRESTDWMemExpressList; //case sensitive and case insensitive + DbfWordsSensPartialList, DbfWordsInsensPartialList: TRESTDWMemExpressList; //for partial matches + DbfWordsSensNoPartialList, DbfWordsInsensNoPartialList: TRESTDWMemExpressList; //no partial match allowed + DbfWordsGeneralList: TRESTDWMemExpressList; + +Implementation + +Procedure LinkVariable(ExprRec: PRESTDWMemExpressionRec); +Begin + With ExprRec^ Do + Begin + If ExprWord.IsVariable Then + Begin + // copy pointer to variable + Args[0] := ExprWord.AsPointer; + // store length as second parameter + Args[1] := PChar(ExprWord.LenAsPointer); + End; + End; +End; + +Procedure LinkVariables(ExprRec: PRESTDWMemExpressionRec); +Var + I: integer; +Begin + With ExprRec^ Do + Begin + I := 0; + While (I < MaxArg) and (ArgList[I] <> nil) Do + Begin + LinkVariables(ArgList[I]); + Inc(I); + End; + End; + LinkVariable(ExprRec); +End; + +{ TRESTDWMemCustomExpressionParser } + +Constructor TRESTDWMemCustomExpressionParser.Create; +Begin + Inherited; + + FHexChar := '$'; +{$IFDEF ENG_NUMBERS} + FDecimalSeparator := '.'; + FArgSeparator := ','; +{$ELSE} + FDecimalSeparator := DecimalSeparator; + If DecimalSeparator = ',' Then + FArgSeparator := ';' + Else + FArgSeparator := ','; +{$ENDIF} + FConstantsList := TRESTDWMemOCollection.Create; + FWordsList := TRESTDWMemExpressList.Create; + GetMem(FExpResult, ArgAllocSize); + FExpResultPos := FExpResult; + FExpResultSize := ArgAllocSize; + FOptimize := true; + FillExpressList; +End; + +Destructor TRESTDWMemCustomExpressionParser.Destroy; +Begin + ClearExpressions; + FreeMem(FExpResult); + FConstantsList.Free; + FWordsList.Free; + + Inherited; +End; + +Procedure TRESTDWMemCustomExpressionParser.CompileExpression(AnExpression: string); +Var + ExpColl: TRESTDWMemExprCollection; + ExprTree: PRESTDWMemExpressionRec; +Begin + If Length(AnExpression) > 0 Then + Begin + ExprTree := nil; + ExpColl := TRESTDWMemExprCollection.Create; + Try + FConstantsList.FreeAll; + // FCurrentExpression := anExpression; + ParseString(AnExpression, ExpColl); + Check(ExpColl); + ExprTree := MakeTree(ExpColl, 0, ExpColl.Count - 1); + FCurrentRec := nil; + CheckArguments(ExprTree); + LinkVariables(ExprTree); + If Optimize Then + RemoveConstants(ExprTree); + // all constant expressions are evaluated and replaced by variables + FCurrentRec := nil; + FExpResultPos := FExpResult; + MakeLinkedList(ExprTree, @FExpResult, @FExpResultPos, @FExpResultSize); + Except + on E: Exception Do + Begin + DisposeTree(ExprTree); + ExpColl.Free; + raise; + End; + End; + ExpColl.Free; +End; +End; + +Procedure TRESTDWMemCustomExpressionParser.CheckArguments(ExprRec: PRESTDWMemExpressionRec); +Var + TempExprWord: TRESTDWMemExprWord; + I, error, firstFuncIndex, funcIndex: Integer; + foundAltFunc: Boolean; + + Procedure FindAlternate; + Begin + // see if we can find another function + If funcIndex < 0 Then + Begin + firstFuncIndex := FWordsList.IndexOf(ExprRec^.ExprWord); + funcIndex := firstFuncIndex; + End; + // check if not last function + If (0 <= funcIndex) and (funcIndex < FWordsList.Count - 1) Then + Begin + inc(funcIndex); + TempExprWord := TRESTDWMemExprWord(FWordsList.Items[funcIndex]); + If FWordsList.Compare(FWordsList.KeyOf(ExprRec^.ExprWord), FWordsList.KeyOf(TempExprWord)) = 0 Then + Begin + ExprRec^.ExprWord := TempExprWord; + ExprRec^.Oper := ExprRec^.ExprWord.ExprFunc; + foundAltFunc := true; + End; + End; + End; + + Procedure InternalCheckArguments; + Begin + I := 0; + error := 0; + foundAltFunc := false; + With ExprRec^ Do + Begin + If WantsFunction <> (ExprWord.IsFunction and not ExprWord.IsOperator) Then + Begin + error := 4; + Exit; + End; + + While (I < ExprWord.MaxFunctionArg) and (ArgList[I] <> nil) and (error = 0) Do + Begin + // test subarguments first + CheckArguments(ArgList[I]); + + // test if correct type + If (ArgList[I]^.ExprWord.ResultType <> ExprCharToExprType(ExprWord.TypeSpec[I+1])) Then + error := 2; + + // goto next argument + Inc(I); + End; + + // test if enough parameters passed; I = num args user passed + If (error = 0) and (I < ExprWord.MinFunctionArg) Then + error := 1; + + // test if too many parameters passed + If (error = 0) and (I > ExprWord.MaxFunctionArg) Then + error := 3; + End; + End; + +Begin + funcIndex := -1; + Repeat + InternalCheckArguments; + + // error occurred? + If error <> 0 Then + FindAlternate; + Until (error = 0) or not foundAltFunc; + + // maybe it's an undefined variable + If (error <> 0) and not ExprRec^.WantsFunction and (firstFuncIndex >= 0) Then + Begin + HandleUnknownVariable(ExprRec^.ExprWord.Name); + { must not add variable as first function in this set of duplicates, + otherwise following searches will not find it } + FWordsList.Exchange(firstFuncIndex, firstFuncIndex+1); + ExprRec^.ExprWord := TRESTDWMemExprWord(FWordsList.Items[firstFuncIndex+1]); + ExprRec^.Oper := ExprRec^.ExprWord.ExprFunc; + InternalCheckArguments; + End; + + // fatal error? + Case error Of + 1: raise ERESTDWMemParserException.Create('Function or operand has too few arguments'); + 2: raise ERESTDWMemParserException.Create('Argument type mismatch'); + 3: raise ERESTDWMemParserException.Create('Function or operand has too many arguments'); + 4: raise ERESTDWMemParserException.Create('No function with this name, remove brackets for variable'); +End; +End; + +Function TRESTDWMemCustomExpressionParser.ResultCanVary(ExprRec: PRESTDWMemExpressionRec): + Boolean; +Var + I: Integer; +Begin + With ExprRec^ Do + Begin + Result := ExprWord.CanVary; + If not Result Then + For I := 0 To ExprWord.MaxFunctionArg - 1 Do + If (ArgList[I] <> nil) and ResultCanVary(ArgList[I]) Then + Begin + Result := true; + Exit; + End + End; +End; + +Procedure TRESTDWMemCustomExpressionParser.RemoveConstants(Var ExprRec: PRESTDWMemExpressionRec); +Var + I: Integer; +Begin + If not ResultCanVary(ExprRec) Then + Begin + If not ExprRec^.ExprWord.IsVariable Then + Begin + // reset current record so that make list generates new + FCurrentRec := nil; + FExpResultPos := FExpResult; + MakeLinkedList(ExprRec, @FExpResult, @FExpResultPos, @FExpResultSize); + + Try + // compute result + EvaluateCurrent; + + // make new record to store constant in + ExprRec := MakeRec; + + // check result type + With ExprRec^ Do + Begin + Case ResultType Of + etBoolean: ExprWord := TRESTDWMemBooleanConstant.Create(EmptyStr, PBoolean(FExpResult)^); + etFloat: ExprWord := TRESTDWMemFloatConstant.CreateAsDouble(EmptyStr, PDouble(FExpResult)^); + etInteger: ExprWord := TRESTDWMemIntegerConstant.Create(PInteger(FExpResult)^); + {$IFDEF RESTDW_SUPPORT_INT64} + etLargeInt:ExprWord := TRESTDWMemLargeIntConstant.Create(PInt64(FExpResult)^); + {$ENDIF} + etString: ExprWord := TRESTDWMemStringConstant.Create(FExpResult); + Else raise ERESTDWMemParserException.CreateFmt('No support for resulttype %d. Please fix the TDBF code.',[Ord(ResultType)]); + End; + + // fill in structure + Oper := ExprWord.ExprFunc; + Args[0] := ExprWord.AsPointer; + FConstantsList.Add(ExprWord); + End; + Finally + DisposeList(FCurrentRec); + FCurrentRec := nil; + End; +End; + End Else + With ExprRec^ Do + Begin + For I := 0 To ExprWord.MaxFunctionArg - 1 Do + If ArgList[I] <> nil Then + RemoveConstants(ArgList[I]); + End; +End; + +Procedure TRESTDWMemCustomExpressionParser.DisposeTree(ExprRec: PRESTDWMemExpressionRec); +Var + I: Integer; +Begin + If ExprRec <> nil Then + Begin + With ExprRec^ Do + Begin + If ExprWord <> nil Then + For I := 0 To ExprWord.MaxFunctionArg - 1 Do + DisposeTree(ArgList[I]); + If Res <> nil Then + Res.Free; + End; + Dispose(ExprRec); + End; +End; + +Procedure TRESTDWMemCustomExpressionParser.DisposeList(ARec: PRESTDWMemExpressionRec); +Var + TheNext: PRESTDWMemExpressionRec; + I: Integer; +Begin + If ARec <> nil Then + Repeat + TheNext := ARec^.Next; + If ARec^.Res <> nil Then + ARec^.Res.Free; + I := 0; + While ARec^.ArgList[I] <> nil Do + Begin + FreeMem(ARec^.Args[I]); + Inc(I); + End; + Dispose(ARec); + ARec := TheNext; + Until ARec = nil; +End; + +Procedure TRESTDWMemCustomExpressionParser.MakeLinkedList(Var ExprRec: PRESTDWMemExpressionRec; + Memory: PPChar; MemoryPos: PPChar; MemSize: PInteger); +Var + I: Integer; +Begin + // test function type + If @ExprRec^.ExprWord.ExprFunc = nil Then + Begin + // special 'no function' function + // indicates no function is present -> we can concatenate all instances + // we don't create new arguments...these 'fall' through + // use destination as we got it + I := 0; + While ExprRec^.ArgList[I] <> nil Do + Begin + // convert arguments to list + MakeLinkedList(ExprRec^.ArgList[I], Memory, MemoryPos, MemSize); + // goto next argument + Inc(I); + End; + // don't need this record anymore + Dispose(ExprRec); + ExprRec := nil; + End Else Begin + // inc memory pointer so we know if we are first + ExprRec^.ResetDest := MemoryPos^ = Memory^; + Inc(MemoryPos^); + // convert arguments to list + I := 0; + While ExprRec^.ArgList[I] <> nil Do + Begin + // save variable type for easy access + ExprRec^.ArgsType[I] := ExprRec^.ArgList[I]^.ExprWord.ResultType; + // check if we need to copy argument: variables in general do not + // need copying, except for fixed len strings which are not + // null-terminated + // if ExprRec^.ArgList[I].ExprWord.NeedsCopy then + // begin + // get memory for argument + GetMem(ExprRec^.Args[I], ArgAllocSize); + ExprRec^.ArgsPos[I] := ExprRec^.Args[I]; + ExprRec^.ArgsSize[I] := ArgAllocSize; + MakeLinkedList(ExprRec^.ArgList[I], @ExprRec^.Args[I], @ExprRec^.ArgsPos[I], + @ExprRec^.ArgsSize[I]); + // end else begin + // copy reference + // ExprRec^.Args[I] := ExprRec^.ArgList[I].Args[0]; + // ExprRec^.ArgsPos[I] := ExprRec^.Args[I]; + // ExprRec^.ArgsSize[I] := 0; + // FreeMem(ExprRec^.ArgList[I]); + // ExprRec^.ArgList[I] := nil; + // end; + + // goto next argument + Inc(I); + End; + + // link result to target argument + ExprRec^.Res := TRESTDWMemDynamicType.Create(Memory, MemoryPos, MemSize); + + // link to next operation + If FCurrentRec = nil Then + Begin + FCurrentRec := ExprRec; + FLastRec := ExprRec; + End Else Begin + FLastRec^.Next := ExprRec; + FLastRec := ExprRec; +End; + End; +End; + +Function TRESTDWMemCustomExpressionParser.MakeTree(Expr: TRESTDWMemExprCollection; + FirstItem, LastItem: Integer): PRESTDWMemExpressionRec; + +{ +- This is the most complex routine, it breaks down the expression and makes + a linked tree which is used for fast function evaluations +- it is implemented recursively +} + +Var + I, IArg, IStart, IEnd, lPrec, brCount: Integer; + ExprWord: TRESTDWMemExprWord; +Begin + // remove redundant brackets + brCount := 0; + While (FirstItem+brCount < LastItem) and (TRESTDWMemExprWord( + Expr.Items[FirstItem+brCount]).ResultType = etLeftBracket) Do + Inc(brCount); + I := LastItem; + While (I > FirstItem) and (TRESTDWMemExprWord( + Expr.Items[I]).ResultType = etRightBracket) Do + Dec(I); + // test max of start and ending brackets + If brCount > (LastItem-I) Then + brCount := LastItem-I; + // count number of bracket pairs completely open from start to end + // IArg is min.brCount + I := FirstItem + brCount; + IArg := brCount; + While (I <= LastItem - brCount) and (brCount > 0) Do + Begin + Case TRESTDWMemExprWord(Expr.Items[I]).ResultType Of + etLeftBracket: Inc(brCount); + etRightBracket: + Begin + Dec(brCount); + If brCount < IArg Then + IArg := brCount; + End; + End; + Inc(I); +End; + // useful pair bracket count, is in minimum, is IArg + brCount := IArg; + // check if subexpression closed within (bracket level will be zero) + If brCount > 0 Then + Begin + Inc(FirstItem, brCount); + Dec(LastItem, brCount); + End; + + // check for empty range + If LastItem < FirstItem Then + Begin + Result := nil; + Exit; + End; + + // get new record + Result := MakeRec; + + // simple constant, variable or function? + If LastItem = FirstItem Then + Begin + Result^.ExprWord := TRESTDWMemExprWord(Expr.Items[FirstItem]); + Result^.Oper := Result^.ExprWord.ExprFunc; + Exit; + End; + + // no...more complex, find operator with lowest precedence + brCount := 0; + IArg := 0; + IEnd := FirstItem-1; + lPrec := -1; + For I := FirstItem To LastItem Do + Begin + ExprWord := TRESTDWMemExprWord(Expr.Items[I]); + If (brCount = 0) and ExprWord.IsOperator and (TRESTDWMemFunction(ExprWord).OperPrec > lPrec) Then + Begin + IEnd := I; + lPrec := TRESTDWMemFunction(ExprWord).OperPrec; + End; + Case ExprWord.ResultType Of + etLeftBracket: Inc(brCount); + etRightBracket: Dec(brCount); + End; + End; + + // operator found ? + If IEnd >= FirstItem Then + Begin + // save operator + Result^.ExprWord := TRESTDWMemExprWord(Expr.Items[IEnd]); + Result^.Oper := Result^.ExprWord.ExprFunc; + // recurse into left part if present + If IEnd > FirstItem Then + Begin + Result^.ArgList[IArg] := MakeTree(Expr, FirstItem, IEnd-1); + Inc(IArg); + End; + // recurse into right part if present + If IEnd < LastItem Then + Result^.ArgList[IArg] := MakeTree(Expr, IEnd+1, LastItem); + End Else + If TRESTDWMemExprWord(Expr.Items[FirstItem]).IsFunction Then + Begin + // save function + Result^.ExprWord := TRESTDWMemExprWord(Expr.Items[FirstItem]); + Result^.Oper := Result^.ExprWord.ExprFunc; + Result^.WantsFunction := true; + // parse function arguments + IEnd := FirstItem + 1; + IStart := IEnd; + brCount := 0; + If TRESTDWMemExprWord(Expr.Items[IEnd]).ResultType = etLeftBracket Then + Begin + // opening bracket found, first argument expression starts at next index + Inc(brCount); + Inc(IStart); + While (IEnd < LastItem) and (brCount <> 0) Do + Begin + Inc(IEnd); + Case TRESTDWMemExprWord(Expr.Items[IEnd]).ResultType Of + etLeftBracket: Inc(brCount); + etComma: + If brCount = 1 Then + Begin + // argument separation found, build tree of argument expression + Result^.ArgList[IArg] := MakeTree(Expr, IStart, IEnd-1); + Inc(IArg); + IStart := IEnd + 1; + End; + etRightBracket: Dec(brCount); + End; + End; + + // parse last argument + Result^.ArgList[IArg] := MakeTree(Expr, IStart, IEnd-1); + End; + End Else + raise ERESTDWMemParserException.Create('Operator/function missing'); +End; + +Procedure TRESTDWMemCustomExpressionParser.ParseString(AnExpression: string; DestCollection: TRESTDWMemExprCollection); +Var + isConstant: Boolean; + I, I1, I2, Len, DecSep: Integer; + W, S: string; + TempWord: TRESTDWMemExprWord; + + Procedure ReadConstant(AnExpr: string; isHex: Boolean); + Begin + isConstant := true; + While (I2 <= Len) and ((AnExpr[I2] in ['0'..'9']) or + (isHex and (AnExpr[I2] in ['a'..'f', 'A'..'F']))) Do + Inc(I2); + If I2 <= Len Then + Begin + If AnExpr[I2] = FDecimalSeparator Then + Begin + Inc(I2); + While (I2 <= Len) and (AnExpr[I2] in ['0'..'9']) Do + Inc(I2); + End; + If (I2 <= Len) and (AnExpr[I2] = 'e') Then + Begin + Inc(I2); + If (I2 <= Len) and (AnExpr[I2] in ['+', '-']) Then + Inc(I2); + While (I2 <= Len) and (AnExpr[I2] in ['0'..'9']) Do + Inc(I2); + End; + End; + End; + + Procedure ReadWord(AnExpr: string); + Var + OldI2: Integer; + constChar: Char; + Begin + isConstant := false; + I1 := I2; + While (I1 < Len) and (AnExpr[I1] = ' ') Do + Inc(I1); + I2 := I1; + If I1 <= Len Then + Begin + If AnExpr[I2] = HexChar Then + Begin + Inc(I2); + OldI2 := I2; + ReadConstant(AnExpr, true); + If I2 = OldI2 Then + Begin + isConstant := false; + While (I2 <= Len) and (AnExpr[I2] in ['a'..'z', 'A'..'Z', '_', '0'..'9']) Do + Inc(I2); + End; + End + Else If AnExpr[I2] = FDecimalSeparator Then + ReadConstant(AnExpr, false) + Else + // String constants can be delimited by ' or " + // but need not be - see below + // To use a delimiter inside the string, double it up to escape it + Case AnExpr[I2] Of + '''', '"': + Begin + isConstant := true; + constChar := AnExpr[I2]; + Inc(I2); + While (I2 <= Len) Do + Begin + // Regular character? + If (AnExpr[I2] <> constChar) Then + Inc(I2) + Else // we do have a const, now check for escaped consts + If (I2+1 <= Len) and + (AnExpr[I2+1]=constChar) Then + Inc(I2,2) //skip past, deal with duplicates later + Else //at the trailing delimiter + Begin + Inc(I2); //move past delimiter + Break; + End; + End; + End; + // However string constants can also appear without delimiters + 'a'..'z', 'A'..'Z', '_': + Begin + While (I2 <= Len) and (AnExpr[I2] in ['a'..'z', 'A'..'Z', '_', '0'..'9']) Do + Inc(I2); + End; + '>', '<': + Begin + If (I2 <= Len) Then + Inc(I2); + If AnExpr[I2] in ['=', '<', '>'] Then + Inc(I2); + End; + '=': + Begin + If (I2 <= Len) Then + Inc(I2); + If AnExpr[I2] in ['<', '>', '='] Then + Inc(I2); + End; + '&': + Begin + If (I2 <= Len) Then + Inc(I2); + If AnExpr[I2] in ['&'] Then + Inc(I2); + End; + '|': + Begin + If (I2 <= Len) Then + Inc(I2); + If AnExpr[I2] in ['|'] Then + Inc(I2); + End; + ':': + Begin + If (I2 <= Len) Then + Inc(I2); + If AnExpr[I2] = '=' Then + Inc(I2); + End; + '!': + Begin + If (I2 <= Len) Then + Inc(I2); + If AnExpr[I2] = '=' Then //support for != + Inc(I2); + End; + '+': + Begin + Inc(I2); + If (AnExpr[I2] = '+') and FWordsList.Search(PChar('++'), I) Then + Inc(I2); + End; + '-': + Begin + Inc(I2); + If (AnExpr[I2] = '-') and FWordsList.Search(PChar('--'), I) Then + Inc(I2); + End; + '^', '/', '\', '*', '(', ')', '%', '~', '$': + Inc(I2); + '0'..'9': + ReadConstant(AnExpr, false); + Else + Begin + Inc(I2); + End; + End; + End; + End; + +Begin + I2 := 1; + S := Trim(AnExpression); + Len := Length(S); + Repeat + ReadWord(S); + W := Trim(Copy(S, I1, I2 - I1)); + If isConstant Then + Begin + If W[1] = HexChar Then + Begin + // convert hexadecimal to decimal + W[1] := '$'; + W := IntToStr(StrToInt(W)); + End; + If (W[1] = '''') or (W[1] = '"') Then + Begin + // StringConstant will handle any escaped quotes + TempWord := TRESTDWMemStringConstant.Create(W); + End + Else + Begin + DecSep := Pos(FDecimalSeparator, W); + If (DecSep > 0) Then + Begin + {$IFDEF ENG_NUMBERS} + // we'll have to convert FDecimalSeparator into DecimalSeparator + // otherwise the OS will not understand what we mean + {$IFDEF FPC} + W[DecSep] := DefaultFormatSettings.DecimalSeparator; + {$ELSE} + {$IFDEF RTL240_UP} + W[DecSep] := FormatSettings.DecimalSeparator; + {$ELSE} + W[DecSep] := DecimalSeparator; + {$ENDIF} + {$ENDIF} + {$ENDIF} + TempWord := TRESTDWMemFloatConstant.Create(W, W) + End Else Begin + TempWord := TRESTDWMemIntegerConstant.Create(StrToInt(W)); + End; + End; + DestCollection.Add(TempWord); + FConstantsList.Add(TempWord); +End + Else If Length(W) > 0 Then + If FWordsList.Search(PChar(W), I) Then + Begin + DestCollection.Add(FWordsList.Items[I]) + End Else Begin + // unknown variable -> fire event + HandleUnknownVariable(W); + // try to search again + If FWordsList.Search(PChar(W), I) Then + Begin + DestCollection.Add(FWordsList.Items[I]) + End Else Begin + raise ERESTDWMemParserException.Create('Unknown variable '''+W+''' found.'); + End; + End; + Until I2 > Len; +End; + +Procedure TRESTDWMemCustomExpressionParser.Check(AnExprList: TRESTDWMemExprCollection); +Var + I, J, K, L: Integer; +Begin + AnExprList.Check; + With AnExprList Do + Begin + I := 0; + While I < Count Do + Begin + {----CHECK ON DOUBLE MINUS OR DOUBLE PLUS----} + If ((TRESTDWMemExprWord(Items[I]).Name = '-') or + (TRESTDWMemExprWord(Items[I]).Name = '+')) + and ((I = 0) or + (TRESTDWMemExprWord(Items[I - 1]).ResultType = etComma) or + (TRESTDWMemExprWord(Items[I - 1]).ResultType = etLeftBracket) or + (TRESTDWMemExprWord(Items[I - 1]).IsOperator and (TRESTDWMemExprWord(Items[I - 1]).MaxFunctionArg + = 2))) Then + Begin + {replace e.g. ----1 with +1} + If TRESTDWMemExprWord(Items[I]).Name = '-' Then + K := -1 + Else + K := 1; + L := 1; + While (I + L < Count) and ((TRESTDWMemExprWord(Items[I + L]).Name = '-') + or (TRESTDWMemExprWord(Items[I + L]).Name = '+')) and ((I + L = 0) or + (TRESTDWMemExprWord(Items[I + L - 1]).ResultType = etComma) or + (TRESTDWMemExprWord(Items[I + L - 1]).ResultType = etLeftBracket) or + (TRESTDWMemExprWord(Items[I + L - 1]).IsOperator and (TRESTDWMemExprWord(Items[I + L - + 1]).MaxFunctionArg = 2))) Do + Begin + If TRESTDWMemExprWord(Items[I + L]).Name = '-' Then + K := -1 * K; + Inc(L); + End; + If L > 0 Then + Begin + Dec(L); + For J := I + 1 To Count - 1 - L Do + Items[J] := Items[J + L]; + Count := Count - L; + End; + If K = -1 Then + Begin + If FWordsList.Search(pchar('-@'), J) Then + Items[I] := FWordsList.Items[J]; + End + Else If FWordsList.Search(pchar('+@'), J) Then + Items[I] := FWordsList.Items[J]; + End; + {----CHECK ON DOUBLE NOT----} + If (TRESTDWMemExprWord(Items[I]).Name = 'not') + and ((I = 0) or + (TRESTDWMemExprWord(Items[I - 1]).ResultType = etLeftBracket) or + TRESTDWMemExprWord(Items[I - 1]).IsOperator) Then + Begin + {replace e.g. not not 1 with 1} + K := -1; + L := 1; + While (I + L < Count) and (TRESTDWMemExprWord(Items[I + L]).Name = 'not') and ((I + + L = 0) or + (TRESTDWMemExprWord(Items[I + L - 1]).ResultType = etLeftBracket) or + TRESTDWMemExprWord(Items[I + L - 1]).IsOperator) Do + Begin + K := -K; + Inc(L); + End; + If L > 0 Then + Begin + If K = 1 Then + Begin + //remove all + For J := I To Count - 1 - L Do + Items[J] := Items[J + L]; + Count := Count - L; + End + Else + Begin + //keep one + Dec(L); + For J := I + 1 To Count - 1 - L Do + Items[J] := Items[J + L]; + Count := Count - L; + End + End; + End; + {-----MISC CHECKS-----} + If (TRESTDWMemExprWord(Items[I]).IsVariable) and ((I < Count - 1) and + (TRESTDWMemExprWord(Items[I + 1]).IsVariable)) Then + raise ERESTDWMemParserException.Create('Missing operator between '''+TRESTDWMemExprWord(Items[I]).Name+''' and '''+TRESTDWMemExprWord(Items[I]).Name+''''); + If (TRESTDWMemExprWord(Items[I]).ResultType = etLeftBracket) and (I >= Count - 1) Then + raise ERESTDWMemParserException.Create('Missing closing bracket'); + If (TRESTDWMemExprWord(Items[I]).ResultType = etRightBracket) and ((I < Count - 1) and + (TRESTDWMemExprWord(Items[I + 1]).ResultType = etLeftBracket)) Then + raise ERESTDWMemParserException.Create('Missing operator between )('); + If (TRESTDWMemExprWord(Items[I]).ResultType = etRightBracket) and ((I < Count - 1) and + (TRESTDWMemExprWord(Items[I + 1]).IsVariable)) Then + raise ERESTDWMemParserException.Create('Missing operator between ) and constant/variable'); + If (TRESTDWMemExprWord(Items[I]).ResultType = etLeftBracket) and ((I > 0) and + (TRESTDWMemExprWord(Items[I - 1]).IsVariable)) Then + raise ERESTDWMemParserException.Create('Missing operator between constant/variable and ('); + + {-----CHECK ON INTPOWER------} + If (TRESTDWMemExprWord(Items[I]).Name = '^') and ((I < Count - 1) and + (TRESTDWMemExprWord(Items[I + 1]).ClassType = TRESTDWMemIntegerConstant)) Then + If FWordsList.Search(PChar('^@'), J) Then + Items[I] := FWordsList.Items[J]; //use the faster intPower if possible + Inc(I); + End; + End; +End; + +Procedure TRESTDWMemCustomExpressionParser.EvaluateCurrent; +Var + TempRec: PRESTDWMemExpressionRec; +Begin + If FCurrentRec <> nil Then + Begin + // get current record + TempRec := FCurrentRec; + // execute list + Repeat + With TempRec^ Do + Begin + // do we need to reset pointer? + If ResetDest Then + Res.MemoryPos^ := Res.Memory^; + + Oper(TempRec); + + // goto next + TempRec := Next; + End; + Until TempRec = nil; + End; +End; + +Function TRESTDWMemCustomExpressionParser.DefineFunction(AFunctName, AShortName, ADescription, ATypeSpec: string; + AMinFunctionArg: Integer; AResultType: TRESTDWMemExpressionType; AFuncAddress: TRESTDWMemExprFunc): TRESTDWMemExprWord; +Begin + Result := TRESTDWMemFunction.Create(AFunctName, AShortName, ATypeSpec, AMinFunctionArg, AResultType, AFuncAddress, ADescription); + FWordsList.Add(Result); +End; + +Function TRESTDWMemCustomExpressionParser.DefineIntegerVariable(AVarName: string; AValue: PInteger): TRESTDWMemExprWord; +Begin + Result := TRESTDWMemIntegerVariable.Create(AVarName, AValue); + FWordsList.Add(Result); +End; + +{$IFDEF RESTDW_SUPPORT_INT64} + +Function TRESTDWMemCustomExpressionParser.DefineLargeIntVariable(AVarName: string; AValue: PRESTDWMemLargeInt): TRESTDWMemExprWord; +Begin + Result := TRESTDWMemLargeIntVariable.Create(AVarName, AValue); + FWordsList.Add(Result); +End; + +{$ENDIF} + +Function TRESTDWMemCustomExpressionParser.DefineDateTimeVariable(AVarName: string; AValue: PRESTDWMemDateTimeRec): TRESTDWMemExprWord; +Begin + Result := TRESTDWMemDateTimeVariable.Create(AVarName, AValue); + FWordsList.Add(Result); +End; + +Function TRESTDWMemCustomExpressionParser.DefineBooleanVariable(AVarName: string; AValue: PBoolean): TRESTDWMemExprWord; +Begin + Result := TRESTDWMemBooleanVariable.Create(AVarName, AValue); + FWordsList.Add(Result); +End; + +Function TRESTDWMemCustomExpressionParser.DefineFloatVariable(AVarName: string; AValue: PDouble): TRESTDWMemExprWord; +Begin + Result := TRESTDWMemFloatVariable.Create(AVarName, AValue); + FWordsList.Add(Result); +End; + +Function TRESTDWMemCustomExpressionParser.DefineStringVariable(AVarName: string; AValue: PPChar): TRESTDWMemExprWord; +Begin + Result := TRESTDWMemStringVariable.Create(AVarName, AValue); + FWordsList.Add(Result); +End; + +{ +Procedure TRESTDWMemCustomExpressionParser.GetGeneratedVars(AList: TList); +Var + I: Integer; +Begin + AList.Clear; + With FWordsList do + For I := 0 to Count - 1 do + Begin + If TObject(Items[I]).ClassType = TGeneratedVariable then + AList.Add(Items[I]); + End; +End; +} + +Function TRESTDWMemCustomExpressionParser.GetResultType: TRESTDWMemExpressionType; +Begin + Result := etUnknown; + If FCurrentRec <> nil Then + Begin + //LAST operand should be boolean -otherwise If(,,) doesn't work + While (FLastRec^.Next <> nil) Do + FLastRec := FLastRec^.Next; + If FLastRec^.ExprWord <> nil Then + Result := FLastRec^.ExprWord.ResultType; + End; +End; + +Function TRESTDWMemCustomExpressionParser.MakeRec: PRESTDWMemExpressionRec; +Var + I: Integer; +Begin + New(Result); + Result^.Oper := nil; + Result^.AuxData := nil; + Result^.WantsFunction := false; + For I := 0 To MaxArg - 1 Do + Begin + Result^.Args[I] := nil; + Result^.ArgsPos[I] := nil; + Result^.ArgsSize[I] := 0; + Result^.ArgsType[I] := etUnknown; + Result^.ArgList[I] := nil; + End; + Result^.Res := nil; + Result^.Next := nil; + Result^.ExprWord := nil; + Result^.ResetDest := false; +End; + +Procedure TRESTDWMemCustomExpressionParser.Evaluate(AnExpression: string); +Begin + If Length(AnExpression) > 0 Then + Begin + AddExpression(AnExpression); + EvaluateCurrent; + End; +End; + +Function TRESTDWMemCustomExpressionParser.AddExpression(AnExpression: string): Integer; +Begin + If Length(AnExpression) > 0 Then + Begin + Result := 0; + CompileExpression(AnExpression); + End Else + Result := -1; + //CurrentIndex := Result; +End; + +Procedure TRESTDWMemCustomExpressionParser.ClearExpressions; +Begin + DisposeList(FCurrentRec); + FCurrentRec := nil; + FLastRec := nil; +End; + +Function TRESTDWMemCustomExpressionParser.GetFunctionDescription(AFunction: string): + string; +Var + S: string; + p, I: Integer; +Begin + S := AFunction; + p := Pos('(', S); + If p > 0 Then + S := Copy(S, 1, p - 1); + If FWordsList.Search(pchar(S), I) Then + Result := TRESTDWMemExprWord(FWordsList.Items[I]).Description + Else + Result := EmptyStr; +End; + +Procedure TRESTDWMemCustomExpressionParser.GetFunctionNames(AList: TStrings); +Var + I, J: Integer; + S: string; +Begin + With FWordsList Do + For I := 0 To Count - 1 Do + With TRESTDWMemExprWord(FWordsList.Items[I]) Do + If Length(Description) > 0 Then + Begin + S := Name; + If MaxFunctionArg > 0 Then + Begin + S := S + '('; + For J := 0 To MaxFunctionArg - 2 Do + S := S + ArgSeparator; + S := S + ')'; + End; + AList.Add(S); + End; +End; + + +//--Expression functions----------------------------------------------------- + +Procedure FuncFloatToStr(Param: PRESTDWMemExpressionRec); +Var + width, numDigits, resWidth: Integer; + extVal: Extended; +Begin + With Param^ Do + Begin + // get params; + numDigits := 0; + If Args[1] <> nil Then + width := PInteger(Args[1])^ + Else + width := 18; + If Args[2] <> nil Then + numDigits := PInteger(Args[2])^; + // convert to string + Res.AssureSpace(width); + extVal := PDouble(Args[0])^; + resWidth := FloatToText(Res.MemoryPos^, extVal, {$ifndef FPC_VERSION}fvExtended,{$ENDIF} ffFixed, 18, numDigits); + // always use dot as decimal separator + If numDigits > 0 Then + Res.MemoryPos^[resWidth-numDigits-1] := '.'; + // result width smaller than requested width? -> add space to compensate + If (Args[1] <> nil) and (resWidth < width) Then + Begin + // move string so that it's right-aligned + Move(Res.MemoryPos^^, (Res.MemoryPos^)[width-resWidth], resWidth); + // fill gap with spaces + FillChar(Res.MemoryPos^^, width-resWidth, ' '); + // resWidth has been padded, update + resWidth := width; + End Else If resWidth > width Then Begin + // result width more than requested width, cut + resWidth := width; + End; + // advance pointer + Inc(Res.MemoryPos^, resWidth); + // null-terminate + Res.MemoryPos^^ := #0; +End; +End; + +Procedure FuncIntToStr_Gen(Param: PRESTDWMemExpressionRec; Val: {$IFDEF RESTDW_SUPPORT_INT64}Int64{$else}Integer{$ENDIF}); +Var + width: Integer; +Begin + With Param^ Do + Begin + // width specified? + If Args[1] <> nil Then + Begin + // convert to string + width := PInteger(Args[1])^; + {$IFDEF RESTDW_SUPPORT_INT64} + GetStrFromInt64_Width + {$else} + GetStrFromInt_Width + {$ENDIF} + (Val, width, Res.MemoryPos^, #32); + // advance pointer + Inc(Res.MemoryPos^, width); + // need to add decimal? + If Args[2] <> nil Then + Begin + // get number of digits + width := PInteger(Args[2])^; + // add decimal dot + Res.MemoryPos^^ := '.'; + Inc(Res.MemoryPos^); + // add zeroes + FillChar(Res.MemoryPos^^, width, '0'); + // go to end + Inc(Res.MemoryPos^, width); + End; + End Else Begin + // convert to string + width := + {$IFDEF RESTDW_SUPPORT_INT64} + GetStrFromInt64 + {$else} + GetStrFromInt + {$ENDIF} + (Val, Res.MemoryPos^); + // advance pointer + Inc(Param^.Res.MemoryPos^, width); + End; + // null-terminate + Res.MemoryPos^^ := #0; +End; +End; + +Procedure FuncIntToStr(Param: PRESTDWMemExpressionRec); +Begin + FuncIntToStr_Gen(Param, PInteger(Param^.Args[0])^); +End; + +{$IFDEF RESTDW_SUPPORT_INT64} + +Procedure FuncInt64ToStr(Param: PRESTDWMemExpressionRec); +Begin + FuncIntToStr_Gen(Param, PInt64(Param^.Args[0])^); +End; + +{$ENDIF} + +Procedure FuncDateToStr(Param: PRESTDWMemExpressionRec); +Var + TempStr: string; +Begin + With Param^ Do + Begin + // create in temporary string + DateTimeToString(TempStr, 'yyyymmdd', PRESTDWMemDateTimeRec(Args[0])^.DateTime); + // copy to buffer + Res.Append(PChar(TempStr), Length(TempStr)); + End; +End; + +Procedure FuncSubString(Param: PRESTDWMemExpressionRec); +Var + srcLen, index, count: Integer; +Begin + With Param^ Do + Begin + srcLen := StrLen(Args[0]); + index := PInteger(Args[1])^ - 1; + If Args[2] <> nil Then + Begin + count := PInteger(Args[2])^; + If index + count > srcLen Then + count := srcLen - index; + End Else + count := srcLen - index; + Res.Append(Args[0]+index, count) + End; +End; + +Procedure FuncLeft(Param: PRESTDWMemExpressionRec); +Var + srcLen, count: Integer; +Begin + srcLen := StrLen(Param^.Args[0]); + count := PInteger(Param^.Args[1])^; + If count > srcLen Then + count := srcLen; + Param^.Res.Append(Param^.Args[0], count) +End; + +Procedure FuncUppercase(Param: PRESTDWMemExpressionRec); +Var + dest: PChar; +Begin + With Param^ Do + Begin + // first copy + dest := (Res.MemoryPos)^; + Res.Append(Args[0], StrLen(Args[0])); + // make uppercase + AnsiStrUpper(dest); + End; +End; + +Procedure FuncLowercase(Param: PRESTDWMemExpressionRec); +Var + dest: PChar; +Begin + With Param^ Do + Begin + // first copy + dest := (Res.MemoryPos)^; + Res.Append(Args[0], StrLen(Args[0])); + // make lowercase + AnsiStrLower(dest); + End; +End; + +Procedure FuncNegative_F_F(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := -PDouble(Args[0])^; +End; + +Procedure FuncNegative_I_I(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInteger(Res.MemoryPos^)^ := -PInteger(Args[0])^; +End; + +{$IFDEF RESTDW_SUPPORT_INT64} +Procedure FuncNegative_L_L(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInt64(Res.MemoryPos^)^ := -PInt64(Args[0])^; +End; +{$ENDIF} + +Procedure FuncAdd_F_FF(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ + PDouble(Args[1])^; +End; + +Procedure FuncAdd_F_FI(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ + PInteger(Args[1])^; +End; + +Procedure FuncAdd_F_II(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ + PInteger(Args[1])^; +End; + +Procedure FuncAdd_F_IF(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ + PDouble(Args[1])^; +End; + +{$IFDEF RESTDW_SUPPORT_INT64} + +Procedure FuncAdd_F_FL(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ + PInt64(Args[1])^; +End; + +Procedure FuncAdd_F_IL(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ + PInt64(Args[1])^; +End; + +Procedure FuncAdd_F_LL(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ + PInt64(Args[1])^; +End; + +Procedure FuncAdd_F_LF(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ + PDouble(Args[1])^; +End; + +Procedure FuncAdd_F_LI(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ + PInteger(Args[1])^; +End; + +{$ENDIF} + +Procedure FuncSub_F_FF(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ - PDouble(Args[1])^; +End; + +Procedure FuncSub_F_FI(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ - PInteger(Args[1])^; +End; + +Procedure FuncSub_F_II(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ - PInteger(Args[1])^; +End; + +Procedure FuncSub_F_IF(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ - PDouble(Args[1])^; +End; + +{$IFDEF RESTDW_SUPPORT_INT64} + +Procedure FuncSub_F_FL(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ - PInt64(Args[1])^; +End; + +Procedure FuncSub_F_IL(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ - PInt64(Args[1])^; +End; + +Procedure FuncSub_F_LL(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ - PInt64(Args[1])^; +End; + +Procedure FuncSub_F_LF(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ - PDouble(Args[1])^; +End; + +Procedure FuncSub_F_LI(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ - PInteger(Args[1])^; +End; + +{$ENDIF} + +Procedure FuncMul_F_FF(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ * PDouble(Args[1])^; +End; + +Procedure FuncMul_F_FI(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ * PInteger(Args[1])^; +End; + +Procedure FuncMul_F_II(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ * PInteger(Args[1])^; +End; + +Procedure FuncMul_F_IF(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ * PDouble(Args[1])^; +End; + +{$IFDEF RESTDW_SUPPORT_INT64} + +Procedure FuncMul_F_FL(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ * PInt64(Args[1])^; +End; + +Procedure FuncMul_F_IL(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ * PInt64(Args[1])^; +End; + +Procedure FuncMul_F_LL(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ * PInt64(Args[1])^; +End; + +Procedure FuncMul_F_LF(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ * PDouble(Args[1])^; +End; + +Procedure FuncMul_F_LI(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ * PInteger(Args[1])^; +End; + +{$ENDIF} + +Procedure FuncDiv_F_FF(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ / PDouble(Args[1])^; +End; + +Procedure FuncDiv_F_FI(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ / PInteger(Args[1])^; +End; + +Procedure FuncDiv_F_II(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ div PInteger(Args[1])^; +End; + +Procedure FuncDiv_F_IF(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ / PDouble(Args[1])^; +End; + +{$IFDEF RESTDW_SUPPORT_INT64} + +Procedure FuncDiv_F_FL(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ / PInt64(Args[1])^; +End; + +Procedure FuncDiv_F_IL(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ div PInt64(Args[1])^; +End; + +Procedure FuncDiv_F_LL(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ div PInt64(Args[1])^; +End; + +Procedure FuncDiv_F_LF(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ / PDouble(Args[1])^; +End; + +Procedure FuncDiv_F_LI(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ div PInteger(Args[1])^; +End; + +{$ENDIF} + +Procedure FuncStrI_EQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) = 0); +End; + +Procedure FuncStrIP_EQ(Param: PRESTDWMemExpressionRec); +Var + arg0len, arg1len: integer; + match: boolean; + str0, str1: string; +Begin + With Param^ Do + Begin + arg1len := StrLen(Args[1]); + If Args[1][0] = '*' Then + Begin + If Args[1][arg1len-1] = '*' Then + Begin + str0 := AnsiStrUpper(Args[0]); + str1 := AnsiStrUpper(Args[1]+1); + setlength(str1, arg1len-2); + match := AnsiPos(str1, str0) <> 0; + End Else Begin + arg0len := StrLen(Args[0]); + // at least length without asterisk + match := arg0len >= arg1len - 1; + If match Then + match := AnsiStrLIComp(Args[0]+(arg0len-arg1len+1), Args[1]+1, arg1len-1) = 0; + End; + End Else + If Args[1][arg1len-1] = '*' Then + Begin + arg0len := StrLen(Args[0]); + match := arg0len >= arg1len - 1; + If match Then + match := AnsiStrLIComp(Args[0], Args[1], arg1len-1) = 0; + End Else Begin + match := AnsiStrIComp(Args[0], Args[1]) = 0; +End; + Res.MemoryPos^^ := Char(match); + End; +End; + +Procedure FuncStrI_NEQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) <> 0); +End; + +Procedure FuncStrI_LT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) < 0); +End; + +Procedure FuncStrI_GT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) > 0); +End; + +Procedure FuncStrI_LTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) <= 0); +End; + +Procedure FuncStrI_GTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) >= 0); +End; + +Procedure FuncStrP_EQ(Param: PRESTDWMemExpressionRec); +Var + arg0len, arg1len: integer; + match: boolean; +Begin + With Param^ Do + Begin + arg1len := StrLen(Args[1]); + If Args[1][0] = '*' Then + Begin + If Args[1][arg1len-1] = '*' Then + Begin + Args[1][arg1len-1] := #0; + match := AnsiStrPos(Args[0], Args[1]+1) <> nil; + Args[1][arg1len-1] := '*'; + End Else Begin + arg0len := StrLen(Args[0]); + // at least length without asterisk + match := arg0len >= arg1len - 1; + If match Then + match := AnsiStrLComp(Args[0]+(arg0len-arg1len+1), Args[1]+1, arg1len-1) = 0; + End; + End Else + If Args[1][arg1len-1] = '*' Then + Begin + arg0len := StrLen(Args[0]); + match := arg0len >= arg1len - 1; + If match Then + match := AnsiStrLComp(Args[0], Args[1], arg1len-1) = 0; + End Else Begin + match := AnsiStrComp(Args[0], Args[1]) = 0; +End; + Res.MemoryPos^^ := Char(match); + End; +End; + +Procedure FuncStr_EQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) = 0); +End; + +Procedure FuncStr_NEQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) <> 0); +End; + +Procedure FuncStr_LT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) < 0); +End; + +Procedure FuncStr_GT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) > 0); +End; + +Procedure FuncStr_LTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) <= 0); +End; + +Procedure FuncStr_GTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) >= 0); +End; + +Procedure Func_FF_EQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ = PDouble(Args[1])^); +End; + +Procedure Func_FF_NEQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ <> PDouble(Args[1])^); +End; + +Procedure Func_FF_LT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ < PDouble(Args[1])^); +End; + +Procedure Func_FF_GT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ > PDouble(Args[1])^); +End; + +Procedure Func_FF_LTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ <= PDouble(Args[1])^); +End; + +Procedure Func_FF_GTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ >= PDouble(Args[1])^); +End; + +Procedure Func_FI_EQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ = PInteger(Args[1])^); +End; + +Procedure Func_FI_NEQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ <> PInteger(Args[1])^); +End; + +Procedure Func_FI_LT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ < PInteger(Args[1])^); +End; + +Procedure Func_FI_GT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ > PInteger(Args[1])^); +End; + +Procedure Func_FI_LTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ <= PInteger(Args[1])^); +End; + +Procedure Func_FI_GTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ >= PInteger(Args[1])^); +End; + +Procedure Func_II_EQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PInteger(Args[1])^); +End; + +Procedure Func_II_NEQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ <> PInteger(Args[1])^); +End; + +Procedure Func_II_LT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ < PInteger(Args[1])^); +End; + +Procedure Func_II_GT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ > PInteger(Args[1])^); +End; + +Procedure Func_II_LTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ <= PInteger(Args[1])^); +End; + +Procedure Func_II_GTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ >= PInteger(Args[1])^); +End; + +Procedure Func_IF_EQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PDouble(Args[1])^); +End; + +Procedure Func_IF_NEQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ <> PDouble(Args[1])^); +End; + +Procedure Func_IF_LT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ < PDouble(Args[1])^); +End; + +Procedure Func_IF_GT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ > PDouble(Args[1])^); +End; + +Procedure Func_IF_LTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ <= PDouble(Args[1])^); +End; + +Procedure Func_IF_GTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ >= PDouble(Args[1])^); +End; + +{$IFDEF RESTDW_SUPPORT_INT64} + +Procedure Func_LL_EQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ = PInt64(Args[1])^); +End; + +Procedure Func_LL_NEQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ <> PInt64(Args[1])^); +End; + +Procedure Func_LL_LT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ < PInt64(Args[1])^); +End; + +Procedure Func_LL_GT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ > PInt64(Args[1])^); +End; + +Procedure Func_LL_LTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ <= PInt64(Args[1])^); +End; + +Procedure Func_LL_GTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ >= PInt64(Args[1])^); +End; + +Procedure Func_LF_EQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ = PDouble(Args[1])^); +End; + +Procedure Func_LF_NEQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ <> PDouble(Args[1])^); +End; + +Procedure Func_LF_LT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ < PDouble(Args[1])^); +End; + +Procedure Func_LF_GT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ > PDouble(Args[1])^); +End; + +Procedure Func_LF_LTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ <= PDouble(Args[1])^); +End; + +Procedure Func_LF_GTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ >= PDouble(Args[1])^); +End; + +Procedure Func_FL_EQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ = PInt64(Args[1])^); +End; + +Procedure Func_FL_NEQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ <> PInt64(Args[1])^); +End; + +Procedure Func_FL_LT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ < PInt64(Args[1])^); +End; + +Procedure Func_FL_GT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ > PInt64(Args[1])^); +End; + +Procedure Func_FL_LTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ <= PInt64(Args[1])^); +End; + +Procedure Func_FL_GTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ >= PInt64(Args[1])^); +End; + +Procedure Func_LI_EQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ = PInteger(Args[1])^); +End; + +Procedure Func_LI_NEQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ <> PInteger(Args[1])^); +End; + +Procedure Func_LI_LT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ < PInteger(Args[1])^); +End; + +Procedure Func_LI_GT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ > PInteger(Args[1])^); +End; + +Procedure Func_LI_LTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ <= PInteger(Args[1])^); +End; + +Procedure Func_LI_GTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ >= PInteger(Args[1])^); +End; + +Procedure Func_IL_EQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PInt64(Args[1])^); +End; + +Procedure Func_IL_NEQ(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ <> PInt64(Args[1])^); +End; + +Procedure Func_IL_LT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ < PInt64(Args[1])^); +End; + +Procedure Func_IL_GT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ > PInt64(Args[1])^); +End; + +Procedure Func_IL_LTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ <= PInt64(Args[1])^); +End; + +Procedure Func_IL_GTE(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ >= PInt64(Args[1])^); +End; + +{$ENDIF} + +Procedure Func_AND(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(Boolean(Args[0]^) and Boolean(Args[1]^)); +End; + +Procedure Func_OR(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(Boolean(Args[0]^) or Boolean(Args[1]^)); +End; + +Procedure Func_NOT(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.MemoryPos^^ := Char(not Boolean(Args[0]^)); +End; + +Initialization + + DbfWordsGeneralList := TRESTDWMemExpressList.Create; + DbfWordsInsensGeneralList := TRESTDWMemExpressList.Create; + DbfWordsInsensNoPartialList := TRESTDWMemExpressList.Create; + DbfWordsInsensPartialList := TRESTDWMemExpressList.Create; + DbfWordsSensGeneralList := TRESTDWMemExpressList.Create; + DbfWordsSensNoPartialList := TRESTDWMemExpressList.Create; + DbfWordsSensPartialList := TRESTDWMemExpressList.Create; + + With DbfWordsGeneralList Do + Begin + // basic function functionality + Add(TRESTDWMemLeftBracket.Create('(', nil)); + Add(TRESTDWMemRightBracket.Create(')', nil)); + Add(TRESTDWMemComma.Create(',', nil)); + + // operators - name, param types, result type, func addr, precedence + // note that the parameter types in the second column must match with + // the function signature in the function address + Add(TRESTDWMemFunction.CreateOper('-@', 'I', etInteger, TRESTDWMemExprFunc(@FuncNegative_I_I), 20)); + Add(TRESTDWMemFunction.CreateOper('-@', 'F', etFloat, TRESTDWMemExprFunc(@FuncNegative_F_F), 20)); + {$IFDEF RESTDW_SUPPORT_INT64} + Add(TRESTDWMemFunction.CreateOper('-@', 'L', etLargeInt, TRESTDWMemExprFunc(@FuncNegative_L_L), 20)); + {$ENDIF} + Add(TRESTDWMemFunction.CreateOper('+', 'SS', etString, nil, 40)); + Add(TRESTDWMemFunction.CreateOper('+', 'FF', etFloat, TRESTDWMemExprFunc(@FuncAdd_F_FF), 40)); + Add(TRESTDWMemFunction.CreateOper('+', 'FI', etFloat, TRESTDWMemExprFunc(@FuncAdd_F_FI), 40)); + Add(TRESTDWMemFunction.CreateOper('+', 'IF', etFloat, TRESTDWMemExprFunc(@FuncAdd_F_IF), 40)); + Add(TRESTDWMemFunction.CreateOper('+', 'II', etInteger, TRESTDWMemExprFunc(@FuncAdd_F_II), 40)); + {$IFDEF RESTDW_SUPPORT_INT64} + Add(TRESTDWMemFunction.CreateOper('+', 'FL', etFloat, TRESTDWMemExprFunc(@FuncAdd_F_FL), 40)); + Add(TRESTDWMemFunction.CreateOper('+', 'IL', etLargeInt, TRESTDWMemExprFunc(@FuncAdd_F_IL), 40)); + Add(TRESTDWMemFunction.CreateOper('+', 'LF', etFloat, TRESTDWMemExprFunc(@FuncAdd_F_LF), 40)); + Add(TRESTDWMemFunction.CreateOper('+', 'LL', etLargeInt, TRESTDWMemExprFunc(@FuncAdd_F_LL), 40)); + Add(TRESTDWMemFunction.CreateOper('+', 'LI', etLargeInt, TRESTDWMemExprFunc(@FuncAdd_F_LI), 40)); + {$ENDIF} + Add(TRESTDWMemFunction.CreateOper('-', 'FF', etFloat, TRESTDWMemExprFunc(@FuncSub_F_FF), 40)); + Add(TRESTDWMemFunction.CreateOper('-', 'FI', etFloat, TRESTDWMemExprFunc(@FuncSub_F_FI), 40)); + Add(TRESTDWMemFunction.CreateOper('-', 'IF', etFloat, TRESTDWMemExprFunc(@FuncSub_F_IF), 40)); + Add(TRESTDWMemFunction.CreateOper('-', 'II', etInteger, TRESTDWMemExprFunc(@FuncSub_F_II), 40)); + {$IFDEF RESTDW_SUPPORT_INT64} + Add(TRESTDWMemFunction.CreateOper('-', 'FL', etFloat, TRESTDWMemExprFunc(@FuncSub_F_FL), 40)); + Add(TRESTDWMemFunction.CreateOper('-', 'IL', etLargeInt, TRESTDWMemExprFunc(@FuncSub_F_IL), 40)); + Add(TRESTDWMemFunction.CreateOper('-', 'LF', etFloat, TRESTDWMemExprFunc(@FuncSub_F_LF), 40)); + Add(TRESTDWMemFunction.CreateOper('-', 'LL', etLargeInt, TRESTDWMemExprFunc(@FuncSub_F_LL), 40)); + Add(TRESTDWMemFunction.CreateOper('-', 'LI', etLargeInt, TRESTDWMemExprFunc(@FuncSub_F_LI), 40)); + {$ENDIF} + Add(TRESTDWMemFunction.CreateOper('*', 'FF', etFloat, TRESTDWMemExprFunc(@FuncMul_F_FF), 40)); + Add(TRESTDWMemFunction.CreateOper('*', 'FI', etFloat, TRESTDWMemExprFunc(@FuncMul_F_FI), 40)); + Add(TRESTDWMemFunction.CreateOper('*', 'IF', etFloat, TRESTDWMemExprFunc(@FuncMul_F_IF), 40)); + Add(TRESTDWMemFunction.CreateOper('*', 'II', etInteger, TRESTDWMemExprFunc(@FuncMul_F_II), 40)); + {$IFDEF RESTDW_SUPPORT_INT64} + Add(TRESTDWMemFunction.CreateOper('*', 'FL', etFloat, TRESTDWMemExprFunc(@FuncMul_F_FL), 40)); + Add(TRESTDWMemFunction.CreateOper('*', 'IL', etLargeInt, TRESTDWMemExprFunc(@FuncMul_F_IL), 40)); + Add(TRESTDWMemFunction.CreateOper('*', 'LF', etFloat, TRESTDWMemExprFunc(@FuncMul_F_LF), 40)); + Add(TRESTDWMemFunction.CreateOper('*', 'LL', etLargeInt, TRESTDWMemExprFunc(@FuncMul_F_LL), 40)); + Add(TRESTDWMemFunction.CreateOper('*', 'LI', etLargeInt, TRESTDWMemExprFunc(@FuncMul_F_LI), 40)); + {$ENDIF} + Add(TRESTDWMemFunction.CreateOper('/', 'FF', etFloat, TRESTDWMemExprFunc(@FuncDiv_F_FF), 40)); + Add(TRESTDWMemFunction.CreateOper('/', 'FI', etFloat, TRESTDWMemExprFunc(@FuncDiv_F_FI), 40)); + Add(TRESTDWMemFunction.CreateOper('/', 'IF', etFloat, TRESTDWMemExprFunc(@FuncDiv_F_IF), 40)); + Add(TRESTDWMemFunction.CreateOper('/', 'II', etInteger, TRESTDWMemExprFunc(@FuncDiv_F_II), 40)); + {$IFDEF RESTDW_SUPPORT_INT64} + Add(TRESTDWMemFunction.CreateOper('/', 'FL', etFloat, TRESTDWMemExprFunc(@FuncDiv_F_FL), 40)); + Add(TRESTDWMemFunction.CreateOper('/', 'IL', etLargeInt, TRESTDWMemExprFunc(@FuncDiv_F_IL), 40)); + Add(TRESTDWMemFunction.CreateOper('/', 'LF', etFloat, TRESTDWMemExprFunc(@FuncDiv_F_LF), 40)); + Add(TRESTDWMemFunction.CreateOper('/', 'LL', etLargeInt, TRESTDWMemExprFunc(@FuncDiv_F_LL), 40)); + Add(TRESTDWMemFunction.CreateOper('/', 'LI', etLargeInt, TRESTDWMemExprFunc(@FuncDiv_F_LI), 40)); + {$ENDIF} + + Add(TRESTDWMemFunction.CreateOper('=', 'FF', etBoolean, TRESTDWMemExprFunc(@Func_FF_EQ) , 80)); + Add(TRESTDWMemFunction.CreateOper('<', 'FF', etBoolean, TRESTDWMemExprFunc(@Func_FF_LT) , 80)); + Add(TRESTDWMemFunction.CreateOper('>', 'FF', etBoolean, TRESTDWMemExprFunc(@Func_FF_GT) , 80)); + Add(TRESTDWMemFunction.CreateOper('<=','FF', etBoolean, TRESTDWMemExprFunc(@Func_FF_LTE), 80)); + Add(TRESTDWMemFunction.CreateOper('>=','FF', etBoolean, TRESTDWMemExprFunc(@Func_FF_GTE), 80)); + Add(TRESTDWMemFunction.CreateOper('<>','FF', etBoolean, TRESTDWMemExprFunc(@Func_FF_NEQ), 80)); + Add(TRESTDWMemFunction.CreateOper('=', 'FI', etBoolean, TRESTDWMemExprFunc(@Func_FI_EQ) , 80)); + Add(TRESTDWMemFunction.CreateOper('<', 'FI', etBoolean, TRESTDWMemExprFunc(@Func_FI_LT) , 80)); + Add(TRESTDWMemFunction.CreateOper('>', 'FI', etBoolean, TRESTDWMemExprFunc(@Func_FI_GT) , 80)); + Add(TRESTDWMemFunction.CreateOper('<=','FI', etBoolean, TRESTDWMemExprFunc(@Func_FI_LTE), 80)); + Add(TRESTDWMemFunction.CreateOper('>=','FI', etBoolean, TRESTDWMemExprFunc(@Func_FI_GTE), 80)); + Add(TRESTDWMemFunction.CreateOper('<>','FI', etBoolean, TRESTDWMemExprFunc(@Func_FI_NEQ), 80)); + Add(TRESTDWMemFunction.CreateOper('=', 'II', etBoolean, TRESTDWMemExprFunc(@Func_II_EQ) , 80)); + Add(TRESTDWMemFunction.CreateOper('<', 'II', etBoolean, TRESTDWMemExprFunc(@Func_II_LT) , 80)); + Add(TRESTDWMemFunction.CreateOper('>', 'II', etBoolean, TRESTDWMemExprFunc(@Func_II_GT) , 80)); + Add(TRESTDWMemFunction.CreateOper('<=','II', etBoolean, TRESTDWMemExprFunc(@Func_II_LTE), 80)); + Add(TRESTDWMemFunction.CreateOper('>=','II', etBoolean, TRESTDWMemExprFunc(@Func_II_GTE), 80)); + Add(TRESTDWMemFunction.CreateOper('<>','II', etBoolean, TRESTDWMemExprFunc(@Func_II_NEQ), 80)); + Add(TRESTDWMemFunction.CreateOper('=', 'IF', etBoolean, TRESTDWMemExprFunc(@Func_IF_EQ) , 80)); + Add(TRESTDWMemFunction.CreateOper('<', 'IF', etBoolean, TRESTDWMemExprFunc(@Func_IF_LT) , 80)); + Add(TRESTDWMemFunction.CreateOper('>', 'IF', etBoolean, TRESTDWMemExprFunc(@Func_IF_GT) , 80)); + Add(TRESTDWMemFunction.CreateOper('<=','IF', etBoolean, TRESTDWMemExprFunc(@Func_IF_LTE), 80)); + Add(TRESTDWMemFunction.CreateOper('>=','IF', etBoolean, TRESTDWMemExprFunc(@Func_IF_GTE), 80)); + Add(TRESTDWMemFunction.CreateOper('<>','IF', etBoolean, TRESTDWMemExprFunc(@Func_IF_NEQ), 80)); + {$IFDEF RESTDW_SUPPORT_INT64} + Add(TRESTDWMemFunction.CreateOper('=', 'LL', etBoolean, TRESTDWMemExprFunc(@Func_LL_EQ) , 80)); + Add(TRESTDWMemFunction.CreateOper('<', 'LL', etBoolean, TRESTDWMemExprFunc(@Func_LL_LT) , 80)); + Add(TRESTDWMemFunction.CreateOper('>', 'LL', etBoolean, TRESTDWMemExprFunc(@Func_LL_GT) , 80)); + Add(TRESTDWMemFunction.CreateOper('<=','LL', etBoolean, TRESTDWMemExprFunc(@Func_LL_LTE), 80)); + Add(TRESTDWMemFunction.CreateOper('>=','LL', etBoolean, TRESTDWMemExprFunc(@Func_LL_GTE), 80)); + Add(TRESTDWMemFunction.CreateOper('<>','LL', etBoolean, TRESTDWMemExprFunc(@Func_LL_NEQ), 80)); + Add(TRESTDWMemFunction.CreateOper('=', 'LF', etBoolean, TRESTDWMemExprFunc(@Func_LF_EQ) , 80)); + Add(TRESTDWMemFunction.CreateOper('<', 'LF', etBoolean, TRESTDWMemExprFunc(@Func_LF_LT) , 80)); + Add(TRESTDWMemFunction.CreateOper('>', 'LF', etBoolean, TRESTDWMemExprFunc(@Func_LF_GT) , 80)); + Add(TRESTDWMemFunction.CreateOper('<=','LF', etBoolean, TRESTDWMemExprFunc(@Func_LF_LTE), 80)); + Add(TRESTDWMemFunction.CreateOper('>=','LF', etBoolean, TRESTDWMemExprFunc(@Func_LF_GTE), 80)); + Add(TRESTDWMemFunction.CreateOper('<>','LF', etBoolean, TRESTDWMemExprFunc(@Func_LF_NEQ), 80)); + Add(TRESTDWMemFunction.CreateOper('=', 'LI', etBoolean, TRESTDWMemExprFunc(@Func_LI_EQ) , 80)); + Add(TRESTDWMemFunction.CreateOper('<', 'LI', etBoolean, TRESTDWMemExprFunc(@Func_LI_LT) , 80)); + Add(TRESTDWMemFunction.CreateOper('>', 'LI', etBoolean, TRESTDWMemExprFunc(@Func_LI_GT) , 80)); + Add(TRESTDWMemFunction.CreateOper('<=','LI', etBoolean, TRESTDWMemExprFunc(@Func_LI_LTE), 80)); + Add(TRESTDWMemFunction.CreateOper('>=','LI', etBoolean, TRESTDWMemExprFunc(@Func_LI_GTE), 80)); + Add(TRESTDWMemFunction.CreateOper('<>','LI', etBoolean, TRESTDWMemExprFunc(@Func_LI_NEQ), 80)); + Add(TRESTDWMemFunction.CreateOper('=', 'FL', etBoolean, TRESTDWMemExprFunc(@Func_FL_EQ) , 80)); + Add(TRESTDWMemFunction.CreateOper('<', 'FL', etBoolean, TRESTDWMemExprFunc(@Func_FL_LT) , 80)); + Add(TRESTDWMemFunction.CreateOper('>', 'FL', etBoolean, TRESTDWMemExprFunc(@Func_FL_GT) , 80)); + Add(TRESTDWMemFunction.CreateOper('<=','FL', etBoolean, TRESTDWMemExprFunc(@Func_FL_LTE), 80)); + Add(TRESTDWMemFunction.CreateOper('>=','FL', etBoolean, TRESTDWMemExprFunc(@Func_FL_GTE), 80)); + Add(TRESTDWMemFunction.CreateOper('<>','FL', etBoolean, TRESTDWMemExprFunc(@Func_FL_NEQ), 80)); + Add(TRESTDWMemFunction.CreateOper('=', 'IL', etBoolean, TRESTDWMemExprFunc(@Func_IL_EQ) , 80)); + Add(TRESTDWMemFunction.CreateOper('<', 'IL', etBoolean, TRESTDWMemExprFunc(@Func_IL_LT) , 80)); + Add(TRESTDWMemFunction.CreateOper('>', 'IL', etBoolean, TRESTDWMemExprFunc(@Func_IL_GT) , 80)); + Add(TRESTDWMemFunction.CreateOper('<=','IL', etBoolean, TRESTDWMemExprFunc(@Func_IL_LTE), 80)); + Add(TRESTDWMemFunction.CreateOper('>=','IL', etBoolean, TRESTDWMemExprFunc(@Func_IL_GTE), 80)); + Add(TRESTDWMemFunction.CreateOper('<>','IL', etBoolean, TRESTDWMemExprFunc(@Func_IL_NEQ), 80)); + {$ENDIF} + + Add(TRESTDWMemFunction.CreateOper('NOT', 'B', etBoolean, TRESTDWMemExprFunc(@Func_NOT), 85)); + Add(TRESTDWMemFunction.CreateOper('AND', 'BB', etBoolean, TRESTDWMemExprFunc(@Func_AND), 90)); + Add(TRESTDWMemFunction.CreateOper('OR', 'BB', etBoolean, TRESTDWMemExprFunc(@Func_OR), 100)); + + // Functions - name, description, param types, min params, result type, Func addr + Add(TRESTDWMemFunction.Create('STR', '', 'FII', 1, etString, TRESTDWMemExprFunc(@FuncFloatToStr), '')); + Add(TRESTDWMemFunction.Create('STR', '', 'III', 1, etString, TRESTDWMemExprFunc(@FuncIntToStr), '')); + {$IFDEF RESTDW_SUPPORT_INT64} + Add(TRESTDWMemFunction.Create('STR', '', 'LII', 1, etString, TRESTDWMemExprFunc(@FuncInt64ToStr), '')); + {$ENDIF} + Add(TRESTDWMemFunction.Create('LEFT', '', 'SI', 2, etString, TRESTDWMemExprFunc(@FuncLeft), '')); + Add(TRESTDWMemFunction.Create('DTOS', '', 'D', 1, etString, TRESTDWMemExprFunc(@FuncDateToStr), '')); + Add(TRESTDWMemFunction.Create('SUBSTR', 'SUBS', 'SII', 3, etString, TRESTDWMemExprFunc(@FuncSubString), '')); + Add(TRESTDWMemFunction.Create('UPPERCASE', 'UPPER', 'S', 1, etString, TRESTDWMemExprFunc(@FuncUppercase), '')); + Add(TRESTDWMemFunction.Create('LOWERCASE', 'LOWER', 'S', 1, etString, TRESTDWMemExprFunc(@FuncLowercase), '')); + End; + + With DbfWordsInsensGeneralList Do + Begin + Add(TRESTDWMemFunction.CreateOper('<', 'SS', etBoolean, TRESTDWMemExprFunc(@FuncStrI_LT) , 80)); + Add(TRESTDWMemFunction.CreateOper('>', 'SS', etBoolean, TRESTDWMemExprFunc(@FuncStrI_GT) , 80)); + Add(TRESTDWMemFunction.CreateOper('<=','SS', etBoolean, TRESTDWMemExprFunc(@FuncStrI_LTE), 80)); + Add(TRESTDWMemFunction.CreateOper('>=','SS', etBoolean, TRESTDWMemExprFunc(@FuncStrI_GTE), 80)); + Add(TRESTDWMemFunction.CreateOper('<>','SS', etBoolean, TRESTDWMemExprFunc(@FuncStrI_NEQ), 80)); + End; + + With DbfWordsInsensNoPartialList Do + Add(TRESTDWMemFunction.CreateOper('=', 'SS', etBoolean, TRESTDWMemExprFunc(@FuncStrI_EQ) , 80)); + + With DbfWordsInsensPartialList Do + Add(TRESTDWMemFunction.CreateOper('=', 'SS', etBoolean, TRESTDWMemExprFunc(@FuncStrIP_EQ), 80)); + + With DbfWordsSensGeneralList Do + Begin + Add(TRESTDWMemFunction.CreateOper('<', 'SS', etBoolean, TRESTDWMemExprFunc(@FuncStr_LT) , 80)); + Add(TRESTDWMemFunction.CreateOper('>', 'SS', etBoolean, TRESTDWMemExprFunc(@FuncStr_GT) , 80)); + Add(TRESTDWMemFunction.CreateOper('<=','SS', etBoolean, TRESTDWMemExprFunc(@FuncStr_LTE), 80)); + Add(TRESTDWMemFunction.CreateOper('>=','SS', etBoolean, TRESTDWMemExprFunc(@FuncStr_GTE), 80)); + Add(TRESTDWMemFunction.CreateOper('<>','SS', etBoolean, TRESTDWMemExprFunc(@FuncStr_NEQ), 80)); + End; + + With DbfWordsSensNoPartialList Do + Add(TRESTDWMemFunction.CreateOper('=', 'SS', etBoolean, TRESTDWMemExprFunc(@FuncStr_EQ) , 80)); + + With DbfWordsSensPartialList Do + Add(TRESTDWMemFunction.CreateOper('=', 'SS', etBoolean, TRESTDWMemExprFunc(@FuncStrP_EQ) , 80)); + +Finalization + + DbfWordsGeneralList.Free; + DbfWordsInsensGeneralList.Free; + DbfWordsInsensNoPartialList.Free; + DbfWordsInsensPartialList.Free; + DbfWordsSensGeneralList.Free; + DbfWordsSensNoPartialList.Free; + DbfWordsSensPartialList.Free; +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemoryDatasetParserDefs.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemoryDatasetParserDefs.pas new file mode 100644 index 000000000..4149a3f13 --- /dev/null +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemoryDatasetParserDefs.pas @@ -0,0 +1,1098 @@ +Unit uRESTDWMemoryDatasetParserDefs; + +Interface + +{$I uRESTDW.inc} +{$DEFINE RESTDW_SUPPORT_INT64} + +Uses + SysUtils, + Classes, + Db, + uRESTDWMemoryDatasetParserSupport; + +Const + MaxArg = 6; + ArgAllocSize = 32; + +Type + TRESTDWMemExpressionType = (etInteger, etString, etBoolean, etLargeInt, etFloat, etDateTime, + etLeftBracket, etRightBracket, etComma, etUnknown); + + ERESTDWMemParserException = Class(Exception); + PRESTDWMemExpressionRec = ^TRESTDWMemExpressionRec; + PRESTDWMemDynamicType = ^TRESTDWMemDynamicType; + PRESTDWMemDateTimeRec = ^TDateTimeRec; +{$IFDEF RESTDW_SUPPORT_INT64} + PRESTDWMemLargeInt = ^Int64; +{$ENDIF} + + TRESTDWMemExprWord = Class; + + TRESTDWMemExprFunc = Procedure(Expr: PRESTDWMemExpressionRec); + +//----- + + TRESTDWMemDynamicType = Class(TObject) + Private + FMemory: PPChar; + FMemoryPos: PPChar; + FSize: PInteger; + Public + Constructor Create(DestMem, DestPos: PPChar; ASize: PInteger); + + Procedure AssureSpace(ASize: Integer); + Procedure Resize(NewSize: Integer; Exact: Boolean); + Procedure Rewind; + Procedure Append(Source: PChar; Length: Integer); + Procedure AppendInteger(Source: Integer); + + property Memory: PPChar read FMemory; + property MemoryPos: PPChar read FMemoryPos; + property Size: PInteger read FSize; + End; + + TRESTDWMemExpressionRec = Record + //used both as linked tree and linked list for maximum evaluation efficiency + Oper: TRESTDWMemExprFunc; + Next: PRESTDWMemExpressionRec; + Res: TRESTDWMemDynamicType; + ExprWord: TRESTDWMemExprWord; + AuxData: pointer; + ResetDest: boolean; + WantsFunction: boolean; + Args: array[0..MaxArg-1] Of PChar; + ArgsPos: array[0..MaxArg-1] Of PChar; + ArgsSize: array[0..MaxArg-1] Of Integer; + ArgsType: array[0..MaxArg-1] Of TRESTDWMemExpressionType; + ArgList: array[0..MaxArg-1] Of PRESTDWMemExpressionRec; + End; + + TRESTDWMemExprCollection = Class(TRESTDWMemNoOwnerCollection) + Public + Procedure Check; + Procedure EraseExtraBrackets; + End; + + TRESTDWMemExprWordRec = Record + Name: PChar; + ShortName: PChar; + IsOperator: Boolean; + IsVariable: Boolean; + IsFunction: Boolean; + NeedsCopy: Boolean; + FixedLen: Boolean; + CanVary: Boolean; + ResultType: TRESTDWMemExpressionType; + MinArg: Integer; + MaxArg: Integer; + TypeSpec: PChar; + Description: PChar; + ExprFunc: TRESTDWMemExprFunc; + End; + + TRESTDWMemExprWord = Class(TObject) + Private + FName: string; + FExprFunc: TRESTDWMemExprFunc; + Protected + FRefCount: Cardinal; + + Function GetIsOperator: Boolean; virtual; + Function GetIsVariable: Boolean; + Function GetNeedsCopy: Boolean; + Function GetFixedLen: Integer; virtual; + Function GetCanVary: Boolean; virtual; + Function GetResultType: TRESTDWMemExpressionType; virtual; + Function GetMinFunctionArg: Integer; virtual; + Function GetMaxFunctionArg: Integer; virtual; + Function GetDescription: string; virtual; + Function GetTypeSpec: string; virtual; + Function GetShortName: string; virtual; + Procedure SetFixedLen(NewLen: integer); virtual; + Public + Constructor Create(AName: string; AExprFunc: TRESTDWMemExprFunc); + + Function LenAsPointer: PInteger; virtual; + Function AsPointer: PChar; virtual; + Function IsFunction: Boolean; virtual; + + property ExprFunc: TRESTDWMemExprFunc read FExprFunc; + property IsOperator: Boolean read GetIsOperator; + property CanVary: Boolean read GetCanVary; + property IsVariable: Boolean read GetIsVariable; + property NeedsCopy: Boolean read GetNeedsCopy; + property FixedLen: Integer read GetFixedLen write SetFixedLen; + property ResultType: TRESTDWMemExpressionType read GetResultType; + property MinFunctionArg: Integer read GetMinFunctionArg; + property MaxFunctionArg: Integer read GetMaxFunctionArg; + property Name: string read FName; + property ShortName: string read GetShortName; + property Description: string read GetDescription; + property TypeSpec: string read GetTypeSpec; + End; + + TRESTDWMemExpressShortList = Class(TRESTDWMemSortedCollection) + Public + Function KeyOf(Item: Pointer): Pointer; override; + Function Compare(Key1, Key2: Pointer): Integer; override; + Procedure FreeItem(Item: Pointer); override; + End; + + TRESTDWMemExpressList = Class(TRESTDWMemSortedCollection) + Private + FShortList: TRESTDWMemExpressShortList; + Public + Constructor Create; + Destructor Destroy; override; + Procedure Add(Item: Pointer); override; + Function KeyOf(Item: Pointer): Pointer; override; + Function Compare(Key1, Key2: Pointer): Integer; override; + Function Search(Key: Pointer; Var Index: Integer): Boolean; override; + Procedure FreeItem(Item: Pointer); override; + End; + + TRESTDWMemConstant = Class(TRESTDWMemExprWord) + Private + FResultType: TRESTDWMemExpressionType; + Protected + Function GetResultType: TRESTDWMemExpressionType; override; + Public + Constructor Create(AName: string; AVarType: TRESTDWMemExpressionType; AExprFunc: TRESTDWMemExprFunc); + End; + + TRESTDWMemFloatConstant = Class(TRESTDWMemConstant) + Private + FValue: Double; + Public + // not overloaded to support older Delphi versions + Constructor Create(AName: string; AValue: string); + Constructor CreateAsDouble(AName: string; AValue: Double); + + Function AsPointer: PChar; override; + + property Value: Double read FValue write FValue; + End; + + TRESTDWMemUserConstant = Class(TRESTDWMemFloatConstant) + Private + FDescription: string; + Protected + Function GetDescription: string; override; + Public + Constructor CreateAsDouble(AName, Descr: string; AValue: Double); + End; + + TRESTDWMemStringConstant = Class(TRESTDWMemConstant) + Private + FValue: string; + Public + // Allow undelimited, delimited by single quotes, delimited by double quotes + // If delimited, allow escaping inside string with double delimiters + Constructor Create(AValue: string); + + Function AsPointer: PChar; override; + End; + + TRESTDWMemIntegerConstant = Class(TRESTDWMemConstant) + Private + FValue: Integer; + Public + Constructor Create(AValue: Integer); + + Function AsPointer: PChar; override; + End; + +{$IFDEF RESTDW_SUPPORT_INT64} + TRESTDWMemLargeIntConstant = Class(TRESTDWMemConstant) + Private + FValue: Int64; + Public + Constructor Create(AValue: Int64); + + Function AsPointer: PChar; override; + End; +{$ENDIF} + + TRESTDWMemBooleanConstant = Class(TRESTDWMemConstant) + Private + FValue: Boolean; + Public + // not overloaded to support older Delphi versions + Constructor Create(AName: string; AValue: Boolean); + + Function AsPointer: PChar; override; + + property Value: Boolean read FValue write FValue; + End; + + TRESTDWMemVariable = Class(TRESTDWMemExprWord) + Private + FResultType: TRESTDWMemExpressionType; + Protected + Function GetCanVary: Boolean; override; + Function GetResultType: TRESTDWMemExpressionType; override; + Public + Constructor Create(AName: string; AVarType: TRESTDWMemExpressionType; AExprFunc: TRESTDWMemExprFunc); + End; + + TRESTDWMemFloatVariable = Class(TRESTDWMemVariable) + Private + FValue: PDouble; + Public + Constructor Create(AName: string; AValue: PDouble); + + Function AsPointer: PChar; override; + End; + + TRESTDWMemStringVariable = Class(TRESTDWMemVariable) + Private + FValue: PPChar; + FFixedLen: Integer; + Protected + Function GetFixedLen: Integer; override; + Procedure SetFixedLen(NewLen: integer); override; + Public + Constructor Create(AName: string; AValue: PPChar); + + Function LenAsPointer: PInteger; override; + Function AsPointer: PChar; override; + + property FixedLen: Integer read FFixedLen; + End; + + TRESTDWMemDateTimeVariable = Class(TRESTDWMemVariable) + Private + FValue: PRESTDWMemDateTimeRec; + Public + Constructor Create(AName: string; AValue: PRESTDWMemDateTimeRec); + + Function AsPointer: PChar; override; + End; + + TRESTDWMemIntegerVariable = Class(TRESTDWMemVariable) + Private + FValue: PInteger; + Public + Constructor Create(AName: string; AValue: PInteger); + + Function AsPointer: PChar; override; + End; + +{$IFDEF RESTDW_SUPPORT_INT64} + + TRESTDWMemLargeIntVariable = Class(TRESTDWMemVariable) + Private + FValue: PRESTDWMemLargeInt; + Public + Constructor Create(AName: string; AValue: PRESTDWMemLargeInt); + + Function AsPointer: PChar; override; + End; + +{$ENDIF} + + TRESTDWMemBooleanVariable = Class(TRESTDWMemVariable) + Private + FValue: PBoolean; + Public + Constructor Create(AName: string; AValue: PBoolean); + + Function AsPointer: PChar; override; + End; + + TRESTDWMemLeftBracket = Class(TRESTDWMemExprWord) + Function GetResultType: TRESTDWMemExpressionType; override; + End; + + TRESTDWMemRightBracket = Class(TRESTDWMemExprWord) + Protected + Function GetResultType: TRESTDWMemExpressionType; override; + End; + + TRESTDWMemComma = Class(TRESTDWMemExprWord) + Protected + Function GetResultType: TRESTDWMemExpressionType; override; + End; + + TRESTDWMemFunction = Class(TRESTDWMemExprWord) + Private + FIsOperator: Boolean; + FOperPrec: Integer; + FMinFunctionArg: Integer; + FMaxFunctionArg: Integer; + FDescription: string; + FTypeSpec: string; + FShortName: string; + FResultType: TRESTDWMemExpressionType; + Protected + Function GetDescription: string; override; + Function GetIsOperator: Boolean; override; + Function GetMinFunctionArg: Integer; override; + Function GetMaxFunctionArg: Integer; override; + Function GetResultType: TRESTDWMemExpressionType; override; + Function GetTypeSpec: string; override; + Function GetShortName: string; override; + + Procedure InternalCreate(AName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TRESTDWMemExpressionType; + AExprFunc: TRESTDWMemExprFunc; AIsOperator: Boolean; AOperPrec: Integer); + Public + Constructor Create(AName, AShortName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TRESTDWMemExpressionType; AExprFunc: TRESTDWMemExprFunc; Descr: string); + // Create operator: name, param types used, result type, func addr, operator precedence + Constructor CreateOper(AName, ATypeSpec: string; AResultType: TRESTDWMemExpressionType; AExprFunc: TRESTDWMemExprFunc; AOperPrec: Integer); + + Function IsFunction: Boolean; override; + + property OperPrec: Integer read FOperPrec; + property TypeSpec: string read FTypeSpec; + End; + + TRESTDWMemVaryingFunction = Class(TRESTDWMemFunction) + // Functions that can vary e.g. random generators + // should be TRESTDWMemVaryingFunction to ensure that they are + // always evaluated + Protected + Function GetCanVary: Boolean; override; + End; + +Const + ListChar = ','; {the delimiter used with the 'in' operator: e.g., + ('a' in 'a,b') =True + ('c' in 'a,b') =False} + +Function ExprCharToExprType(ExprChar: Char): TRESTDWMemExpressionType; + +Implementation + +Function ExprCharToExprType(ExprChar: Char): TRESTDWMemExpressionType; +Begin + Case ExprChar Of + 'B': Result := etBoolean; + 'I': Result := etInteger; + 'L': Result := etLargeInt; + 'F': Result := etFloat; + 'D': Result := etDateTime; + 'S': Result := etString; + Else + Result := etUnknown; +End; +End; + +Procedure _FloatVariable(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^; +End; + +Procedure _BooleanVariable(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PBoolean(Res.MemoryPos^)^ := PBoolean(Args[0])^; +End; + +Procedure _StringConstant(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + Res.Append(Args[0], StrLen(Args[0])); +End; + +Procedure _StringVariable(Param: PRESTDWMemExpressionRec); +Var + length: integer; +Begin + With Param^ Do + Begin + length := PInteger(Args[1])^; + If length = -1 Then + length := StrLen(PPChar(Args[0])^); + Res.Append(PPChar(Args[0])^, length); + End; +End; + +Procedure _DateTimeVariable(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PRESTDWMemDateTimeRec(Res.MemoryPos^)^ := PRESTDWMemDateTimeRec(Args[0])^; +End; + +Procedure _IntegerVariable(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^; +End; + +{ +Procedure _SmallIntVariable(Param: PRESTDWMemExpressionRec); +Begin + With Param^ do + PSmallInt(Res.MemoryPos^)^ := PSmallInt(Args[0])^; +End; +} + +{$IFDEF RESTDW_SUPPORT_INT64} + +Procedure _LargeIntVariable(Param: PRESTDWMemExpressionRec); +Begin + With Param^ Do + PRESTDWMemLargeInt(Res.MemoryPos^)^ := PRESTDWMemLargeInt(Args[0])^; +End; + +{$ENDIF} + +{ TExpressionWord } + +Constructor TRESTDWMemExprWord.Create(AName: string; AExprFunc: TRESTDWMemExprFunc); +Begin + FName := AName; + FExprFunc := AExprFunc; +End; + +Function TRESTDWMemExprWord.GetCanVary: Boolean; +Begin + Result := False; +End; + +Function TRESTDWMemExprWord.GetDescription: string; +Begin + Result := EmptyStr; +End; + +Function TRESTDWMemExprWord.GetShortName: string; +Begin + Result := EmptyStr; +End; + +Function TRESTDWMemExprWord.GetIsOperator: Boolean; +Begin + Result := False; +End; + +Function TRESTDWMemExprWord.GetIsVariable: Boolean; +Begin +{$IFDEF FPC} + Result := (Pointer(FExprFunc) = Pointer(@_StringVariable)) Or + (Pointer(FExprFunc) = Pointer(@_StringConstant)) Or + (Pointer(FExprFunc) = Pointer(@_FloatVariable)) Or + (Pointer(FExprFunc) = Pointer(@_IntegerVariable)) Or +{$IFDEF RESTDW_SUPPORT_INT64} + (Pointer(FExprFunc) = Pointer(@_LargeIntVariable)) Or +{$ENDIF} + (Pointer(FExprFunc) = Pointer(@_DateTimeVariable)) Or + (Pointer(FExprFunc) = Pointer(@_BooleanVariable)); +{$ELSE} + Result := (@FExprFunc = @_StringVariable) Or + (@FExprFunc = @_StringConstant) Or + (@FExprFunc = @_FloatVariable) Or + (@FExprFunc = @_IntegerVariable) Or +{$IFDEF RESTDW_SUPPORT_INT64} + (@FExprFunc = @_LargeIntVariable) Or +{$ENDIF} + (@FExprFunc = @_DateTimeVariable) Or + (@FExprFunc = @_BooleanVariable); +{$ENDIF} +End; + +Function TRESTDWMemExprWord.GetNeedsCopy: Boolean; +Begin +{$IFDEF FPC} + Result := (Pointer(FExprFunc) <> Pointer(@_StringConstant)) And + (Pointer(FExprFunc) <> Pointer(@_FloatVariable)) And + (Pointer(FExprFunc) <> Pointer(@_IntegerVariable)) And +{$IFDEF RESTDW_SUPPORT_INT64} + (Pointer(FExprFunc) <> Pointer(@_LargeIntVariable)) And +{$ENDIF} + (Pointer(FExprFunc) <> Pointer(@_DateTimeVariable)) And + (Pointer(FExprFunc) <> Pointer(@_BooleanVariable)); +{$ELSE} + Result := (@FExprFunc <> @_StringConstant) And + (@FExprFunc <> @_FloatVariable) And + (@FExprFunc <> @_IntegerVariable) And +{$IFDEF RESTDW_SUPPORT_INT64} + (@FExprFunc <> @_LargeIntVariable) And +{$ENDIF} + (@FExprFunc <> @_DateTimeVariable) And + (@FExprFunc <> @_BooleanVariable); +{$ENDIF} +End; + +Function TRESTDWMemExprWord.GetFixedLen: Integer; +Begin + // -1 means variable, non-fixed length + Result := -1; +End; + +Function TRESTDWMemExprWord.GetMinFunctionArg: Integer; +Begin + Result := 0; +End; + +Function TRESTDWMemExprWord.GetMaxFunctionArg: Integer; +Begin + Result := 0; +End; + +Function TRESTDWMemExprWord.GetResultType: TRESTDWMemExpressionType; +Begin + Result := etUnknown; +End; + +Function TRESTDWMemExprWord.GetTypeSpec: string; +Begin + Result := EmptyStr; +End; + +Function TRESTDWMemExprWord.AsPointer: PChar; +Begin + Result := nil; +End; + +Function TRESTDWMemExprWord.LenAsPointer: PInteger; +Begin + Result := nil; +End; + +Function TRESTDWMemExprWord.IsFunction: Boolean; +Begin + Result := False; +End; + +Procedure TRESTDWMemExprWord.SetFixedLen(NewLen: integer); +Begin +End; + +{ TRESTDWMemConstant } + +Constructor TRESTDWMemConstant.Create(AName: string; AVarType: TRESTDWMemExpressionType; AExprFunc: TRESTDWMemExprFunc); +Begin + Inherited Create(AName, AExprFunc); + + FResultType := AVarType; +End; + +Function TRESTDWMemConstant.GetResultType: TRESTDWMemExpressionType; +Begin + Result := FResultType; +End; + +{ TRESTDWMemFloatConstant } + +Constructor TRESTDWMemFloatConstant.Create(AName, AValue: string); +Begin + Inherited Create(AName, etFloat, {$IFDEF FPC}@{$ENDIF}_FloatVariable); + + If Length(AValue) > 0 Then + FValue := StrToFloat(AValue) + Else + FValue := 0.0; +End; + +Constructor TRESTDWMemFloatConstant.CreateAsDouble(AName: string; AValue: Double); +Begin + Inherited Create(AName, etFloat, {$IFDEF FPC}@{$ENDIF}_FloatVariable); + + FValue := AValue; +End; + +Function TRESTDWMemFloatConstant.AsPointer: PChar; +Begin + Result := PChar(@FValue); +End; + +{ TRESTDWMemUserConstant } + +Constructor TRESTDWMemUserConstant.CreateAsDouble(AName, Descr: string; AValue: Double); +Begin + FDescription := Descr; + + Inherited CreateAsDouble(AName, AValue); +End; + +Function TRESTDWMemUserConstant.GetDescription: string; +Begin + Result := FDescription; +End; + +{ TRESTDWMemStringConstant } + +Constructor TRESTDWMemStringConstant.Create(AValue: string); +Var + firstChar, lastChar: Char; +Begin + Inherited Create(AValue, etString, {$IFDEF FPC}@{$ENDIF}_StringConstant); + + firstChar := AValue[1]; + lastChar := AValue[Length(AValue)]; + If (firstChar = lastChar) and ((firstChar = '''') or (firstChar = '"')) Then + Begin + FValue := Copy(AValue, 2, Length(AValue) - 2); + FValue := StringReplace(FValue, firstChar+FirstChar, firstChar, [rfReplaceAll,rfIgnoreCase]) + End + Else + FValue := AValue; +End; + +Function TRESTDWMemStringConstant.AsPointer: PChar; +Begin + Result := PChar(FValue); +End; + +{ TRESTDWMemBooleanConstant } + +Constructor TRESTDWMemBooleanConstant.Create(AName: string; AValue: Boolean); +Begin + Inherited Create(AName, etBoolean, {$IFDEF FPC}@{$ENDIF}_BooleanVariable); + + FValue := AValue; +End; + +Function TRESTDWMemBooleanConstant.AsPointer: PChar; +Begin + Result := PChar(@FValue); +End; + +{ TRESTDWMemIntegerConstant } + +Constructor TRESTDWMemIntegerConstant.Create(AValue: Integer); +Begin + Inherited Create(IntToStr(AValue), etInteger, {$IFDEF FPC}@{$ENDIF}_IntegerVariable); + + FValue := AValue; +End; + +Function TRESTDWMemIntegerConstant.AsPointer: PChar; +Begin + Result := PChar(@FValue); +End; + +{$IFDEF RESTDW_SUPPORT_INT64} +{ TRESTDWMemLargeIntConstant } + +Constructor TRESTDWMemLargeIntConstant.Create(AValue: Int64); +Begin + Inherited Create(IntToStr(AValue), etLargeInt, {$IFDEF FPC}@{$ENDIF}_LargeIntVariable); + + FValue := AValue; +End; + +Function TRESTDWMemLargeIntConstant.AsPointer: PChar; +Begin + Result := PChar(@FValue); +End; +{$ENDIF} + +{ TRESTDWMemVariable } + +Constructor TRESTDWMemVariable.Create(AName: string; AVarType: TRESTDWMemExpressionType; AExprFunc: TRESTDWMemExprFunc); +Begin + Inherited Create(AName, AExprFunc); + + FResultType := AVarType; +End; + +Function TRESTDWMemVariable.GetCanVary: Boolean; +Begin + Result := True; +End; + +Function TRESTDWMemVariable.GetResultType: TRESTDWMemExpressionType; +Begin + Result := FResultType; +End; + +{ TRESTDWMemFloatVariable } + +Constructor TRESTDWMemFloatVariable.Create(AName: string; AValue: PDouble); +Begin + Inherited Create(AName, etFloat, {$IFDEF FPC}@{$ENDIF}_FloatVariable); + FValue := AValue; +End; + +Function TRESTDWMemFloatVariable.AsPointer: PChar; +Begin + Result := PChar(FValue); +End; + +{ TRESTDWMemStringVariable } + +Constructor TRESTDWMemStringVariable.Create(AName: string; AValue: PPChar); +Begin + // variable or fixed length? + Inherited Create(AName, etString, {$IFDEF FPC}@{$ENDIF}_StringVariable); + + // store pointer to string + FValue := AValue; + FFixedLen := -1; +End; + +Function TRESTDWMemStringVariable.AsPointer: PChar; +Begin + Result := PChar(FValue); +End; + +Function TRESTDWMemStringVariable.GetFixedLen: Integer; +Begin + Result := FFixedLen; +End; + +Function TRESTDWMemStringVariable.LenAsPointer: PInteger; +Begin + Result := @FFixedLen; +End; + +Procedure TRESTDWMemStringVariable.SetFixedLen(NewLen: integer); +Begin + FFixedLen := NewLen; +End; + +{ TRESTDWMemDateTimeVariable } + +Constructor TRESTDWMemDateTimeVariable.Create(AName: string; AValue: PRESTDWMemDateTimeRec); +Begin + Inherited Create(AName, etDateTime, {$IFDEF FPC}@{$ENDIF}_DateTimeVariable); + FValue := AValue; +End; + +Function TRESTDWMemDateTimeVariable.AsPointer: PChar; +Begin + Result := PChar(FValue); +End; + +{ TRESTDWMemIntegerVariable } + +Constructor TRESTDWMemIntegerVariable.Create(AName: string; AValue: PInteger); +Begin + Inherited Create(AName, etInteger, {$IFDEF FPC}@{$ENDIF}_IntegerVariable); + FValue := AValue; +End; + +Function TRESTDWMemIntegerVariable.AsPointer: PChar; +Begin + Result := PChar(FValue); +End; + +{$IFDEF RESTDW_SUPPORT_INT64} + +{ TRESTDWMemLargeIntVariable } + +Constructor TRESTDWMemLargeIntVariable.Create(AName: string; AValue: PRESTDWMemLargeInt); +Begin + Inherited Create(AName, etLargeInt, {$IFDEF FPC}@{$ENDIF}_LargeIntVariable); + FValue := AValue; +End; + +Function TRESTDWMemLargeIntVariable.AsPointer: PChar; +Begin + Result := PChar(FValue); +End; + +{$ENDIF} + +{ TRESTDWMemBooleanVariable } + +Constructor TRESTDWMemBooleanVariable.Create(AName: string; AValue: PBoolean); +Begin + Inherited Create(AName, etBoolean, {$IFDEF FPC}@{$ENDIF}_BooleanVariable); + FValue := AValue; +End; + +Function TRESTDWMemBooleanVariable.AsPointer: PChar; +Begin + Result := PChar(FValue); +End; + +{ TRESTDWMemLeftBracket } + +Function TRESTDWMemLeftBracket.GetResultType: TRESTDWMemExpressionType; +Begin + Result := etLeftBracket; +End; + +{ TRESTDWMemRightBracket } + +Function TRESTDWMemRightBracket.GetResultType: TRESTDWMemExpressionType; +Begin + Result := etRightBracket; +End; + +{ TRESTDWMemComma } + +Function TRESTDWMemComma.GetResultType: TRESTDWMemExpressionType; +Begin + Result := etComma; +End; + +{ TRESTDWMemExpressList } + +Constructor TRESTDWMemExpressList.Create; +Begin + Inherited; + + FShortList := TRESTDWMemExpressShortList.Create; +End; + +Destructor TRESTDWMemExpressList.Destroy; +Begin + Inherited; + FShortList.Free; +End; + +Procedure TRESTDWMemExpressList.Add(Item: Pointer); +Var + I: Integer; +Begin + Inherited; + + { remember we reference the object } + Inc(TRESTDWMemExprWord(Item).FRefCount); + + { also add ShortName as reference } + If Length(TRESTDWMemExprWord(Item).ShortName) > 0 Then + Begin + FShortList.Search(FShortList.KeyOf(Item), I); + FShortList.Insert(I, Item); + End; +End; + +Function TRESTDWMemExpressList.Compare(Key1, Key2: Pointer): Integer; +Begin + Result := StrIComp(PChar(Key1), PChar(Key2)); +End; + +Function TRESTDWMemExpressList.KeyOf(Item: Pointer): Pointer; +Begin + Result := PChar(TRESTDWMemExprWord(Item).Name); +End; + +Procedure TRESTDWMemExpressList.FreeItem(Item: Pointer); +Begin + Dec(TRESTDWMemExprWord(Item).FRefCount); + FShortList.Remove(Item); + If TRESTDWMemExprWord(Item).FRefCount = 0 Then + Inherited; +End; + +Function TRESTDWMemExpressList.Search(Key: Pointer; Var Index: Integer): Boolean; +Var + SecIndex: Integer; +Begin + Result := Inherited Search(Key, Index); + If not Result Then + Begin + Result := FShortList.Search(Key, SecIndex); + If Result Then + Index := IndexOf(FShortList.Items[SecIndex]); + End; +End; + +Function TRESTDWMemExpressShortList.Compare(Key1, Key2: Pointer): Integer; +Begin + Result := StrIComp(PChar(Key1), PChar(Key2)); +End; + +Function TRESTDWMemExpressShortList.KeyOf(Item: Pointer): Pointer; +Begin + Result := PChar(TRESTDWMemExprWord(Item).ShortName); +End; + +Procedure TRESTDWMemExpressShortList.FreeItem(Item: Pointer); +Begin +End; + +{ TRESTDWMemExprCollection } + +Procedure TRESTDWMemExprCollection.Check; +Var + brCount, I: Integer; +Begin + brCount := 0; + For I := 0 To Count - 1 Do + Begin + Case TRESTDWMemExprWord(Items[I]).ResultType Of + etLeftBracket: Inc(brCount); + etRightBracket: Dec(brCount); + End; +End; + If brCount <> 0 Then + raise ERESTDWMemParserException.Create('Unequal brackets'); +End; + +Procedure TRESTDWMemExprCollection.EraseExtraBrackets; +Var + I: Integer; + brCount: Integer; +Begin + If (TRESTDWMemExprWord(Items[0]).ResultType = etLeftBracket) Then + Begin + brCount := 1; + I := 1; + While (I < Count) and (brCount > 0) Do + Begin + Case TRESTDWMemExprWord(Items[I]).ResultType Of + etLeftBracket: Inc(brCount); + etRightBracket: Dec(brCount); + End; + Inc(I); + End; + If (brCount = 0) and (I = Count) and (TRESTDWMemExprWord(Items[I - 1]).ResultType = + etRightBracket) Then + Begin + For I := 0 To Count - 3 Do + Items[I] := Items[I + 1]; + Count := Count - 2; + EraseExtraBrackets; //Check if there are still too many brackets + End; +End; +End; + +{ TRESTDWMemFunction } + +Constructor TRESTDWMemFunction.Create(AName, AShortName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TRESTDWMemExpressionType; + AExprFunc: TRESTDWMemExprFunc; Descr: string); +Begin + //to increase compatibility don't use default parameters + FDescription := Descr; + FShortName := AShortName; + InternalCreate(AName, ATypeSpec, AMinFuncArg, AResultType, AExprFunc, false, 0); +End; + +Constructor TRESTDWMemFunction.CreateOper(AName, ATypeSpec: string; AResultType: TRESTDWMemExpressionType; + AExprFunc: TRESTDWMemExprFunc; AOperPrec: Integer); +Begin + InternalCreate(AName, ATypeSpec, -1, AResultType, AExprFunc, true, AOperPrec); +End; + +Procedure TRESTDWMemFunction.InternalCreate(AName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TRESTDWMemExpressionType; + AExprFunc: TRESTDWMemExprFunc; AIsOperator: Boolean; AOperPrec: Integer); +Begin + Inherited Create(AName, AExprFunc); + + FMaxFunctionArg := Length(ATypeSpec); + FMinFunctionArg := AMinFuncArg; + If AMinFuncArg = -1 Then + FMinFunctionArg := FMaxFunctionArg; + FIsOperator := AIsOperator; + FOperPrec := AOperPrec; + FTypeSpec := ATypeSpec; + FResultType := AResultType; + + // check correctness + If FMaxFunctionArg > MaxArg Then + raise ERESTDWMemParserException.Create('Too many arguments'); +End; + +Function TRESTDWMemFunction.GetDescription: string; +Begin + Result := FDescription; +End; + +Function TRESTDWMemFunction.GetIsOperator: Boolean; +Begin + Result := FIsOperator; +End; + +Function TRESTDWMemFunction.GetMinFunctionArg: Integer; +Begin + Result := FMinFunctionArg; +End; + +Function TRESTDWMemFunction.GetMaxFunctionArg: Integer; +Begin + Result := FMaxFunctionArg; +End; + +Function TRESTDWMemFunction.GetResultType: TRESTDWMemExpressionType; +Begin + Result := FResultType; +End; + +Function TRESTDWMemFunction.GetShortName: string; +Begin + Result := FShortName; +End; + +Function TRESTDWMemFunction.GetTypeSpec: string; +Begin + Result := FTypeSpec; +End; + +Function TRESTDWMemFunction.IsFunction: Boolean; +Begin + Result := True; +End; + +{ TRESTDWMemVaryingFunction } + +Function TRESTDWMemVaryingFunction.GetCanVary: Boolean; +Begin + Result := True; +End; + +{ TRESTDWMemDynamicType } + +Constructor TRESTDWMemDynamicType.Create(DestMem, DestPos: PPChar; ASize: PInteger); +Begin + Inherited Create; + + FMemory := DestMem; + FMemoryPos := DestPos; + FSize := ASize; +End; + +Procedure TRESTDWMemDynamicType.Rewind; +Begin + FMemoryPos^ := FMemory^; +End; + +Procedure TRESTDWMemDynamicType.AssureSpace(ASize: Integer); +Begin + // need more memory? + If ((FMemoryPos^) - (FMemory^) + ASize) > (FSize^) Then + Resize((FMemoryPos^) - (FMemory^) + ASize, False); +End; + +Procedure TRESTDWMemDynamicType.Resize(NewSize: Integer; Exact: Boolean); +Var + tempBuf: PChar; + bytesCopy, pos: Integer; +Begin + // if not exact requested make newlength a multiple of ArgAllocSize + If not Exact Then + NewSize := NewSize div ArgAllocSize * ArgAllocSize + ArgAllocSize; + // create new buffer + GetMem(tempBuf, NewSize); + // copy memory + bytesCopy := FSize^; + If bytesCopy > NewSize Then + bytesCopy := NewSize; + Move(FMemory^^, tempBuf^, bytesCopy); + // save position in string + pos := FMemoryPos^ - FMemory^; + // delete old mem + FreeMem(FMemory^); + // assign new + FMemory^ := tempBuf; + FSize^ := NewSize; + // assign position + FMemoryPos^ := FMemory^ + pos; +End; + +Procedure TRESTDWMemDynamicType.Append(Source: PChar; Length: Integer); +Begin + // make room for string plus null-terminator + AssureSpace(Length+4); + // copy + Move(Source^, FMemoryPos^^, Length); + Inc(FMemoryPos^, Length); + // null-terminate + FMemoryPos^^ := #0; +End; + +Procedure TRESTDWMemDynamicType.AppendInteger(Source: Integer); +Begin + // make room for number + AssureSpace(12); + Inc(FMemoryPos^, GetStrFromInt(Source, FMemoryPos^)); + FMemoryPos^^ := #0; +End; + +End. diff --git a/CORE/Source/Plugins/Memdataset/uRESTDWMemoryDatasetParserSupport.pas b/CORE/Source/Plugins/Memdataset/uRESTDWMemoryDatasetParserSupport.pas new file mode 100644 index 000000000..5f39ae16e --- /dev/null +++ b/CORE/Source/Plugins/Memdataset/uRESTDWMemoryDatasetParserSupport.pas @@ -0,0 +1,326 @@ +Unit uRESTDWMemoryDatasetParserSupport; + +// parse support + +{$I uRESTDW.inc} +{$DEFINE RESTDW_SUPPORT_INT64} + +Interface + +Uses + Classes; + +Type + + {TRESTDWMemOCollection interfaces between OWL TCollection and VCL TList} + + TRESTDWMemOCollection = Class(TList) + Public + Procedure AtFree(Index: Integer); + Procedure FreeAll; + Procedure DoFree(Item: Pointer); + Procedure FreeItem(Item: Pointer); virtual; + Destructor Destroy; override; + End; + + TRESTDWMemNoOwnerCollection = Class(TRESTDWMemOCollection) + Public + Procedure FreeItem(Item: Pointer); override; + End; + + { TRESTDWMemSortedCollection object } + + TRESTDWMemSortedCollection = Class(TRESTDWMemOCollection) + Public + Function Compare(Key1, Key2: Pointer): Integer; virtual; abstract; + Function IndexOf(Item: Pointer): Integer; virtual; + Procedure Add(Item: Pointer); virtual; + Procedure AddReplace(Item: Pointer); virtual; + Procedure AddList(Source: TList; FromIndex, ToIndex: Integer); + {if duplicate then replace the duplicate else add} + Function KeyOf(Item: Pointer): Pointer; virtual; + Function Search(Key: Pointer; Var Index: Integer): Boolean; virtual; + End; + + { TRESTDWMemStrCollection object } + + TRESTDWMemStrCollection = Class(TRESTDWMemSortedCollection) + Public + Function Compare(Key1, Key2: Pointer): Integer; override; + Procedure FreeItem(Item: Pointer); override; + End; + +Function GetStrFromInt(Val: Integer; Const Dst: PChar): Integer; +Procedure GetStrFromInt_Width(Val: Integer; Const Width: Integer; Const Dst: PChar; Const PadChar: Char); +{$IFDEF RESTDW_SUPPORT_INT64} +Function GetStrFromInt64(Val: Int64; Const Dst: PChar): Integer; +Procedure GetStrFromInt64_Width(Val: Int64; Const Width: Integer; Const Dst: PChar; Const PadChar: Char); +{$ENDIF} + +Implementation + +Uses SysUtils; + +Destructor TRESTDWMemOCollection.Destroy; +Begin + FreeAll; + Inherited Destroy; +End; + +Procedure TRESTDWMemOCollection.AtFree(Index: Integer); +Var + Item: Pointer; +Begin + Item := Items[Index]; + Delete(Index); + FreeItem(Item); +End; + + +Procedure TRESTDWMemOCollection.FreeAll; +Var + I: Integer; +Begin + Try + For I := 0 To Count - 1 Do + FreeItem(Items[I]); + Finally + Count := 0; +End; +End; + +Procedure TRESTDWMemOCollection.DoFree(Item: Pointer); +Begin + AtFree(IndexOf(Item)); +End; + +Procedure TRESTDWMemOCollection.FreeItem(Item: Pointer); +Begin + If (Item <> nil) Then + With TObject(Item) as TObject Do + Free; +End; + +{----------------------------------------------------------------virtual; + Implementing TRESTDWMemNoOwnerCollection + -----------------------------------------------------------------} + +Procedure TRESTDWMemNoOwnerCollection.FreeItem(Item: Pointer); +Begin +End; + +{ TRESTDWMemSortedCollection } + +Function TRESTDWMemSortedCollection.IndexOf(Item: Pointer): Integer; +Var + I: Integer; +Begin + IndexOf := -1; + If Search(KeyOf(Item), I) Then + Begin + While (I < Count) and (Item <> Items[I]) Do + Inc(I); + If I < Count Then + IndexOf := I; + End; +End; + +Procedure TRESTDWMemSortedCollection.AddReplace(Item: Pointer); +Var + Index: Integer; +Begin + If Search(KeyOf(Item), Index) Then + Delete(Index); + Add(Item); +End; + +Procedure TRESTDWMemSortedCollection.Add(Item: Pointer); +Var + I: Integer; +Begin + Search(KeyOf(Item), I); + Insert(I, Item); +End; + +Procedure TRESTDWMemSortedCollection.AddList(Source: TList; FromIndex, ToIndex: Integer); +Var + I: Integer; +Begin + For I := FromIndex To ToIndex Do + Add(Source.Items[I]); +End; + +Function TRESTDWMemSortedCollection.KeyOf(Item: Pointer): Pointer; +Begin + Result := Item; +End; + +Function TRESTDWMemSortedCollection.Search(Key: Pointer; Var Index: Integer): Boolean; +Var + L, H, I, C: Integer; +Begin + Result := false; + L := 0; + H := Count - 1; + While L <= H Do + Begin + I := (L + H) div 2; + C := Compare(KeyOf(Items[I]), Key); + If C < 0 Then + L := I + 1 + Else Begin + H := I - 1; + Result := C = 0; + End; +End; + Index := L; +End; + +{ TRESTDWMemStrCollection } + +Function TRESTDWMemStrCollection.Compare(Key1, Key2: Pointer): Integer; +Begin + Compare := StrComp(PChar(Key1), PChar(Key2)); +End; + +Procedure TRESTDWMemStrCollection.FreeItem(Item: Pointer); +Begin + StrDispose(PChar(Item)); +End; + +// it seems there is no pascal function to convert an integer into a PChar??? + + +Function GetStrFromInt(Val: Integer; Const Dst: PChar): Integer; +Var + Temp: array[0..10] Of Char; + I, J: Integer; +Begin + Val := Abs(Val); + // we'll have to store characters backwards first + I := 0; + J := 0; + Repeat + Temp[I] := Chr((Val mod 10) + Ord('0')); + Val := Val div 10; + Inc(I); + Until Val = 0; + + // remember number of digits + Result := I; + // copy value, remember: stored backwards + Repeat + Dst[J] := Temp[I-1]; + Inc(J); + Dec(I); + Until I = 0; + // done! +End; + +// it seems there is no pascal function to convert an integer into a PChar??? + +Procedure GetStrFromInt_Width(Val: Integer; Const Width: Integer; Const Dst: PChar; Const PadChar: Char); +Var + Temp: array[0..10] Of Char; + I, J: Integer; + NegSign: boolean; +Begin + NegSign := Val < 0; + If NegSign Then + Val := -Val; + + I := 0; + Repeat + Temp[I] := Chr((Val mod 10) + Ord('0')); + Val := Val div 10; + Inc(I); + Until Val = 0; + + J := 0; + While J < Width - I - Ord(NegSign) Do + Begin + Dst[J] := PadChar; + Inc(J); + End; + + If NegSign Then + Begin + Dst[J] := '-'; + Inc(J); + End; + + Repeat + Dst[J] := Temp[I - 1]; + Inc(J); + Dec(I); + Until I = 0; +End; + +{$IFDEF RESTDW_SUPPORT_INT64} + +Procedure GetStrFromInt64_Width(Val: Int64; Const Width: Integer; Const Dst: PChar; Const PadChar: Char); +Var + Temp: array[0..19] Of Char; + I, J: Integer; + NegSign: boolean; +Begin + NegSign := Val < 0; + If NegSign Then + Val := -Val; + + I := 0; + Repeat + Temp[I] := Chr((Val mod 10) + Ord('0')); + Val := Val div 10; + Inc(I); + Until Val = 0; + + J := 0; + While J < Width - I - Ord(NegSign) Do + Begin + Dst[J] := PadChar; + Inc(J); + End; + + If NegSign Then + Begin + Dst[J] := '-'; + Inc(J); + End; + + Repeat + Dst[J] := Temp[I - 1]; + Inc(J); + Dec(I); + Until I = 0; +End; + +Function GetStrFromInt64(Val: Int64; Const Dst: PChar): Integer; +Var + Temp: array[0..19] Of Char; + I, J: Integer; +Begin + Val := Abs(Val); + // we'll have to store characters backwards first + I := 0; + J := 0; + Repeat + Temp[I] := Chr((Val mod 10) + Ord('0')); + Val := Val div 10; + Inc(I); + Until Val = 0; + + // remember number of digits + Result := I; + // copy value, remember: stored backwards + Repeat + Dst[J] := Temp[I-1]; + inc(J); + dec(I); + Until I = 0; + // done! +End; + +{$ENDIF} + +End. From be2b11af11791b61c1fe484a30775774b62bca2f Mon Sep 17 00:00:00 2001 From: Roniery Santos Cardoso Date: Tue, 8 Sep 2026 21:59:29 -0300 Subject: [PATCH 02/22] feat(drivers): novos drivers nativos ADO, DBExpress e SQLDB Adiciona os PhysicDrivers e NativeLinks nativos para ADO, DBExpress e SQLDB, alem de correcoes de compilacao, mecanica do NativeDrive, suporte a campos Extended/BCD, sessao de conexao com sqldb, leitura/ transporte de tipos de dados, pacotes de dados, otimizacao de Dataset e compilacao Android/iOS. Inclui tambem as correcoes dos drivers Zeos (Physic, Direct, NativeLink e ZDbcResultSet). refs r4052, r4054-r4057, r4062-r4063, r4066, r4068-r4069, r4071, r4073-r4079, r4081-r4082 --- .../ADOPhysLink/uRESTDWADOPhysLink.pas | 136 ++ .../uRESTDWDBExpressPhysLink.pas | 136 ++ .../FireDACPhysLink/FireDAC.Phys.RESTDW.pas | 2 +- .../FireDAC.Phys.RESTDWBase.pas | 116 +- .../NativeLinks/ADO/uRESTDWNativeLinkADO.pas | 564 +++++++ .../DBExpress/uRESTDWNativeLinkDBExpress.pas | 520 +++++++ .../FireDAC/uRESTDWNativeLinkFD.pas | 583 +++++++ .../SQLDB/uRESTDWNativeLinkSQLDB.lrs | 44 + .../SQLDB/uRESTDWNativeLinkSQLDB.pas | 589 +++++++ .../Zeos/uRESTDWNativeLinkZeos.lrs | 43 + .../Zeos/uRESTDWNativeLinkZeos.pas | 515 +++++++ .../SQLDBPhysLink/uRESTDWSQLDBPhysLink.pas | 404 +++++ .../uRESTDWSQLDBPhysRegister.pas | 18 + .../ZeosPhysLink/uRESTDWZAnalyser.pas | 2 +- .../ZeosPhysLink/uRESTDWZDbc.pas | 102 +- .../ZeosPhysLink/uRESTDWZDbcMetadata.pas | 2 +- .../ZeosPhysLink/uRESTDWZDbcResultSet.pas | 1361 +++++++++-------- .../ZeosPhysLink/uRESTDWZDbcStatement.pas | 56 +- .../ZeosPhysLink/uRESTDWZPlainDriver.pas | 2 +- .../ZeosPhysLink/uRESTDWZToken.pas | 2 +- .../ZeosPhysLink/uRESTDWZeosPhysLink.pas | 89 +- .../Database_Drivers/uRESTDWADODriver.pas | 348 +++++ .../Database_Drivers/uRESTDWADOPhysDriver.pas | 23 + .../Database_Drivers/uRESTDWAnyDACDriver.pas | 23 +- .../uRESTDWApolloDBDriver.pas | 22 +- .../uRESTDWDBExpressDriver.pas | 386 +++++ .../uRESTDWDBExpressPhysDriver.pas | 23 + .../Database_Drivers/uRESTDWDriverBase.pas | 132 +- .../Database_Drivers/uRESTDWFireDACDriver.pas | 22 +- .../Database_Drivers/uRESTDWIBDACDriver.pas | 20 +- .../uRESTDWInterbaseDriver.pas | 22 +- .../Database_Drivers/uRESTDWLazarusDriver.pas | 165 +- .../Database_Drivers/uRESTDWMyDACDriver.pas | 20 +- .../Database_Drivers/uRESTDWNativeDriver.lrs | 47 + .../Database_Drivers/uRESTDWNativeDriver.pas | 315 ++++ .../uRESTDWSQLDBPhysDriver.pas | 18 + .../Database_Drivers/uRESTDWUniDACDriver.pas | 22 +- .../Database_Drivers/uRESTDWZeosDriver.pas | 958 ++++++++---- 38 files changed, 6731 insertions(+), 1121 deletions(-) create mode 100644 CORE/Source/Database_Drivers/ADOPhysLink/uRESTDWADOPhysLink.pas create mode 100644 CORE/Source/Database_Drivers/DBExpressPhysLink/uRESTDWDBExpressPhysLink.pas create mode 100644 CORE/Source/Database_Drivers/Native/NativeLinks/ADO/uRESTDWNativeLinkADO.pas create mode 100644 CORE/Source/Database_Drivers/Native/NativeLinks/DBExpress/uRESTDWNativeLinkDBExpress.pas create mode 100644 CORE/Source/Database_Drivers/Native/NativeLinks/FireDAC/uRESTDWNativeLinkFD.pas create mode 100644 CORE/Source/Database_Drivers/Native/NativeLinks/SQLDB/uRESTDWNativeLinkSQLDB.lrs create mode 100644 CORE/Source/Database_Drivers/Native/NativeLinks/SQLDB/uRESTDWNativeLinkSQLDB.pas create mode 100644 CORE/Source/Database_Drivers/Native/NativeLinks/Zeos/uRESTDWNativeLinkZeos.lrs create mode 100644 CORE/Source/Database_Drivers/Native/NativeLinks/Zeos/uRESTDWNativeLinkZeos.pas create mode 100644 CORE/Source/Database_Drivers/SQLDBPhysLink/uRESTDWSQLDBPhysLink.pas create mode 100644 CORE/Source/Database_Drivers/SQLDBPhysLink/uRESTDWSQLDBPhysRegister.pas create mode 100644 CORE/Source/Database_Drivers/uRESTDWADODriver.pas create mode 100644 CORE/Source/Database_Drivers/uRESTDWADOPhysDriver.pas create mode 100644 CORE/Source/Database_Drivers/uRESTDWDBExpressDriver.pas create mode 100644 CORE/Source/Database_Drivers/uRESTDWDBExpressPhysDriver.pas create mode 100644 CORE/Source/Database_Drivers/uRESTDWNativeDriver.lrs create mode 100644 CORE/Source/Database_Drivers/uRESTDWNativeDriver.pas create mode 100644 CORE/Source/Database_Drivers/uRESTDWSQLDBPhysDriver.pas diff --git a/CORE/Source/Database_Drivers/ADOPhysLink/uRESTDWADOPhysLink.pas b/CORE/Source/Database_Drivers/ADOPhysLink/uRESTDWADOPhysLink.pas new file mode 100644 index 000000000..ba0f329f7 --- /dev/null +++ b/CORE/Source/Database_Drivers/ADOPhysLink/uRESTDWADOPhysLink.pas @@ -0,0 +1,136 @@ +Unit uRESTDWADOPhysLink; + +{$I uRESTDW.inc} + +Interface + +{$IFNDEF FPC} + +Uses +{$IFDEF DELPHIXE2UP} + System.Classes, System.SysUtils, Data.DB, Data.Win.ADODB, +{$ELSE} + Classes, SysUtils, DB, ADODB, +{$ENDIF} + uRESTDWAbout, uRESTDWBasicDB, uRESTDWConsts; + +Type + TRESTDWADOPhysLink = Class(TRESTDWComponent) + Private + FADOConnection : TADOConnection; + FDatabase : TRESTDWDatabasebaseBase; + FOldBeforeConnect : TNotifyEvent; + FOldAfterDisconnect : TNotifyEvent; + Procedure SetADOConnection(Const Value : TADOConnection); + Procedure SetDatabase(Const Value : TRESTDWDatabasebaseBase); + Protected + Procedure Notification(AComponent : TComponent; Operation : TOperation); Override; + Procedure RESTDWBeforeConnect(Sender : TObject); + Procedure RESTDWAfterDisconnect(Sender : TObject); + Public + Destructor Destroy; Override; + Published + Property ADOConnection : TADOConnection Read FADOConnection Write SetADOConnection; + Property Database : TRESTDWDatabasebaseBase Read FDatabase Write SetDatabase; + End; + +{$ENDIF} + +Implementation + +{$IFNDEF FPC} + +Procedure TRESTDWADOPhysLink.Notification(AComponent : TComponent; Operation : TOperation); +Begin + Inherited Notification(AComponent, Operation); + If Operation = opRemove Then + Begin + If AComponent = FADOConnection Then + Begin + FADOConnection := Nil; + FOldBeforeConnect := Nil; + FOldAfterDisconnect := Nil; + End; + If AComponent = FDatabase Then + Begin + FDatabase := Nil; + End; + End; +End; + +Destructor TRESTDWADOPhysLink.Destroy; +Begin + SetADOConnection(Nil); + SetDatabase(Nil); + Inherited Destroy; +End; + +Procedure TRESTDWADOPhysLink.RESTDWBeforeConnect(Sender : TObject); +Begin + If Assigned(FOldBeforeConnect) Then + Begin + FOldBeforeConnect(Sender); + End; + If FDatabase = Nil Then + Begin + Raise Exception.Create(cErrorDatabaseNotFound); + End; + FDatabase.Active := True; +End; + +Procedure TRESTDWADOPhysLink.RESTDWAfterDisconnect(Sender : TObject); +Begin + If FDatabase <> Nil Then + Begin + FDatabase.Active := False; + End; + If Assigned(FOldAfterDisconnect) Then + Begin + FOldAfterDisconnect(Sender); + End; +End; + +Procedure TRESTDWADOPhysLink.SetADOConnection(Const Value : TADOConnection); +Begin + If FADOConnection = Value Then + Begin + Exit; + End; + If FADOConnection <> Nil Then + Begin + FADOConnection.BeforeConnect := FOldBeforeConnect; + FADOConnection.AfterDisconnect := FOldAfterDisconnect; + FADOConnection.RemoveFreeNotification(Self); + End; + FADOConnection := Value; + FOldBeforeConnect := Nil; + FOldAfterDisconnect := Nil; + If FADOConnection <> Nil Then + Begin + FADOConnection.FreeNotification(Self); + FOldBeforeConnect := FADOConnection.BeforeConnect; + FOldAfterDisconnect := FADOConnection.AfterDisconnect; + FADOConnection.BeforeConnect := RESTDWBeforeConnect; + FADOConnection.AfterDisconnect := RESTDWAfterDisconnect; + End; +End; + +Procedure TRESTDWADOPhysLink.SetDatabase(Const Value : TRESTDWDatabasebaseBase); +Begin + If FDatabase = Value Then + Begin + Exit; + End; + If FDatabase <> Nil Then + Begin + FDatabase.RemoveFreeNotification(Self); + End; + FDatabase := Value; + If FDatabase <> Nil Then + Begin + FDatabase.FreeNotification(Self); + End; +End; + +{$ENDIF} +End. diff --git a/CORE/Source/Database_Drivers/DBExpressPhysLink/uRESTDWDBExpressPhysLink.pas b/CORE/Source/Database_Drivers/DBExpressPhysLink/uRESTDWDBExpressPhysLink.pas new file mode 100644 index 000000000..198c38f1c --- /dev/null +++ b/CORE/Source/Database_Drivers/DBExpressPhysLink/uRESTDWDBExpressPhysLink.pas @@ -0,0 +1,136 @@ +Unit uRESTDWDBExpressPhysLink; + +{$I uRESTDW.inc} + +Interface + +{$IFNDEF FPC} + +Uses +{$IFDEF DELPHIXE2UP} + System.Classes, System.SysUtils, Data.DB, Data.SqlExpr, +{$ELSE} + Classes, SysUtils, DB, SqlExpr, +{$ENDIF} + uRESTDWAbout, uRESTDWBasicDB, uRESTDWConsts; + +Type + TRESTDWDBExpressPhysLink = Class(TRESTDWComponent) + Private + FSQLConnection : TSQLConnection; + FDatabase : TRESTDWDatabasebaseBase; + FOldBeforeConnect : TNotifyEvent; + FOldAfterDisconnect : TNotifyEvent; + Procedure SetSQLConnection(Const Value : TSQLConnection); + Procedure SetDatabase(Const Value : TRESTDWDatabasebaseBase); + Protected + Procedure Notification(AComponent : TComponent; Operation : TOperation); Override; + Procedure RESTDWBeforeConnect(Sender : TObject); + Procedure RESTDWAfterDisconnect(Sender : TObject); + Public + Destructor Destroy; Override; + Published + Property SQLConnection : TSQLConnection Read FSQLConnection Write SetSQLConnection; + Property Database : TRESTDWDatabasebaseBase Read FDatabase Write SetDatabase; + End; + +{$ENDIF} + +Implementation + +{$IFNDEF FPC} + +Procedure TRESTDWDBExpressPhysLink.Notification(AComponent : TComponent; Operation : TOperation); +Begin + Inherited Notification(AComponent, Operation); + If Operation = opRemove Then + Begin + If AComponent = FSQLConnection Then + Begin + FSQLConnection := Nil; + FOldBeforeConnect := Nil; + FOldAfterDisconnect := Nil; + End; + If AComponent = FDatabase Then + Begin + FDatabase := Nil; + End; + End; +End; + +Destructor TRESTDWDBExpressPhysLink.Destroy; +Begin + SetSQLConnection(Nil); + SetDatabase(Nil); + Inherited Destroy; +End; + +Procedure TRESTDWDBExpressPhysLink.RESTDWBeforeConnect(Sender : TObject); +Begin + If Assigned(FOldBeforeConnect) Then + Begin + FOldBeforeConnect(Sender); + End; + If FDatabase = Nil Then + Begin + Raise Exception.Create(cErrorDatabaseNotFound); + End; + FDatabase.Active := True; +End; + +Procedure TRESTDWDBExpressPhysLink.RESTDWAfterDisconnect(Sender : TObject); +Begin + If FDatabase <> Nil Then + Begin + FDatabase.Active := False; + End; + If Assigned(FOldAfterDisconnect) Then + Begin + FOldAfterDisconnect(Sender); + End; +End; + +Procedure TRESTDWDBExpressPhysLink.SetSQLConnection(Const Value : TSQLConnection); +Begin + If FSQLConnection = Value Then + Begin + Exit; + End; + If FSQLConnection <> Nil Then + Begin + FSQLConnection.BeforeConnect := FOldBeforeConnect; + FSQLConnection.AfterDisconnect := FOldAfterDisconnect; + FSQLConnection.RemoveFreeNotification(Self); + End; + FSQLConnection := Value; + FOldBeforeConnect := Nil; + FOldAfterDisconnect := Nil; + If FSQLConnection <> Nil Then + Begin + FSQLConnection.FreeNotification(Self); + FOldBeforeConnect := FSQLConnection.BeforeConnect; + FOldAfterDisconnect := FSQLConnection.AfterDisconnect; + FSQLConnection.BeforeConnect := RESTDWBeforeConnect; + FSQLConnection.AfterDisconnect := RESTDWAfterDisconnect; + End; +End; + +Procedure TRESTDWDBExpressPhysLink.SetDatabase(Const Value : TRESTDWDatabasebaseBase); +Begin + If FDatabase = Value Then + Begin + Exit; + End; + If FDatabase <> Nil Then + Begin + FDatabase.RemoveFreeNotification(Self); + End; + FDatabase := Value; + If FDatabase <> Nil Then + Begin + FDatabase.FreeNotification(Self); + End; +End; + +{$ENDIF} +End. diff --git a/CORE/Source/Database_Drivers/FireDACPhysLink/FireDAC.Phys.RESTDW.pas b/CORE/Source/Database_Drivers/FireDACPhysLink/FireDAC.Phys.RESTDW.pas index d60e760e1..bd3900ad0 100644 --- a/CORE/Source/Database_Drivers/FireDACPhysLink/FireDAC.Phys.RESTDW.pas +++ b/CORE/Source/Database_Drivers/FireDACPhysLink/FireDAC.Phys.RESTDW.pas @@ -1,6 +1,6 @@ unit FireDAC.Phys.RESTDW; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . diff --git a/CORE/Source/Database_Drivers/FireDACPhysLink/FireDAC.Phys.RESTDWBase.pas b/CORE/Source/Database_Drivers/FireDACPhysLink/FireDAC.Phys.RESTDWBase.pas index 82df6c6af..a9813dc9e 100644 --- a/CORE/Source/Database_Drivers/FireDACPhysLink/FireDAC.Phys.RESTDWBase.pas +++ b/CORE/Source/Database_Drivers/FireDACPhysLink/FireDAC.Phys.RESTDWBase.pas @@ -1,6 +1,6 @@ unit FireDAC.Phys.RESTDWBase; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . @@ -26,7 +26,7 @@ interface uses Classes, SysUtils, FireDAC.Phys, FireDAC.Stan.Intf, FireDAC.Phys.Intf, FireDAC.Phys.SQLGenerator, FireDAC.Stan.Util, FireDAC.Stan.Param, - FireDAC.DatS, FireDAC.Stan.Option, Variants, uRESTDWProtoTypes, + FireDAC.DatS, FireDAC.Stan.Option, FireDAC.Comp.Client, Variants, uRESTDWProtoTypes, uRESTDWBasicDB, DB, uRESTDWPoolermethod, FireDAC.Phys.RESTDWMeta, uRESTDWBasicTypes, FireDAC.Stan.Error, FireDAC.Stan.Consts, uRESTDWMassiveBuffer; @@ -100,6 +100,7 @@ TFDPhysRDWTransaction = class(TFDPhysTransaction) TFDPhysRDWCommand = class(TFDPhysCommand) private FStream: TMemoryStream; + FDataSet: TFDMemTable; FColumnIndex: integer; FEncodeStrs: Boolean; FFieldCount: integer; @@ -314,12 +315,14 @@ constructor TFDPhysRDWCommand.Create(AConnection: TFDPhysConnection); begin inherited Create(AConnection); FStream := TMemoryStream.Create; + FDataSet := TFDMemTable.Create(nil); FInfoMetada := TStringList.Create; end; destructor TFDPhysRDWCommand.Destroy; begin FInfoMetada.Free; + FDataSet.Free; FStream.Free; inherited; end; @@ -433,39 +436,57 @@ procedure TFDPhysRDWCommand.FetchRow(ATable: TFDDatSTable; procedure TFDPhysRDWCommand.InternalClose; begin FStream.Size := 0; + FDataSet.Close; FInfoMetada.Clear; end; function TFDPhysRDWCommand.InternalColInfoGet(var AColInfo : TFDPhysDataColumnInfo): Boolean; var - vBoolean : Boolean; + oFieldDef: TFieldDef; + datType: TFDDataType; + datSize: LongWord; + datPrec: integer; + datScale: integer; + datAttrs: TFDDataAttributes; + oFmtOpts: TFDFormatOptions; begin + Result := False; if GetMetaInfoKind <> mkNone then - begin - Result := False; Exit; - end; - if FStream.Size = 0 then - begin - Result := False; + if not FDataSet.Active then Exit; - end; - if FFieldCount = -1 then - begin - FStream.Position := 0; - FStream.Read(FFieldCount, SizeOf(integer)); - SetLength(FFieldTypes, FFieldCount); - FStream.Read(vBoolean, SizeOf(vBoolean)); - FEncodeStrs := vBoolean; - end; - if FColumnIndex >= FFieldCount then - begin - Result := False; + if FColumnIndex >= FDataSet.FieldDefs.Count then Exit; - end; - AColInfo := readFieldStream; - FColumnIndex := FColumnIndex + 1; + + oFieldDef := FDataSet.FieldDefs[FColumnIndex]; + oFmtOpts := FOptions.FormatOptions; + oFmtOpts.FieldDef2ColumnDef(oFieldDef.DataType, oFieldDef.Size, + oFieldDef.Precision, 0, datType, datSize, datPrec, datScale, datAttrs); + + AColInfo.FSourceID := FColumnIndex; + AColInfo.FSourceName := oFieldDef.Name; + AColInfo.FOriginColName := oFieldDef.Name; + AColInfo.FSourceType := datType; + AColInfo.FType := datType; + AColInfo.FLen := datSize; + AColInfo.FPrec := datPrec; + AColInfo.FScale := datScale; + AColInfo.FAttrs := datAttrs + [caBase]; + if not (faRequired in oFieldDef.Attributes) then + AColInfo.FAttrs := AColInfo.FAttrs + [caAllowNull]; + if oFieldDef.DataType in [ftBlob, ftMemo, ftGraphic, ftWideMemo, ftOraBlob, ftOraClob] then + AColInfo.FAttrs := AColInfo.FAttrs + [caBlobData] + else + AColInfo.FAttrs := AColInfo.FAttrs + [caSearchable]; + if oFieldDef.DataType in [ftFixedChar, ftFixedWideChar] then + AColInfo.FAttrs := AColInfo.FAttrs + [caFixedLen]; + AColInfo.FForceRemOpts := [coReadOnly]; + AColInfo.FForceAddOpts := AColInfo.FForceAddOpts - [coReadOnly]; + if not (faRequired in oFieldDef.Attributes) then + AColInfo.FForceAddOpts := AColInfo.FForceAddOpts + [coAllowNull]; + + Inc(FColumnIndex); Result := True; end; @@ -501,6 +522,8 @@ function TFDPhysRDWCommand.InternalFetchRowSet(ATable: TFDDatSTable; AParentRow: TFDDatSRow; ARowsetSize: LongWord): LongWord; var i: LongWord; + j: integer; + oRow: TFDDatSRow; begin Result := 0; if GetMetaInfoKind in [mkTables, mkTableFields, mkPrimaryKeyFields] then @@ -510,25 +533,33 @@ function TFDPhysRDWCommand.InternalFetchRowSet(ATable: TFDDatSTable; begin FetchMetaRow(ATable, AParentRow, i - 1); Inc(Result); - end + end; end else if GetMetaInfoKind = mkNone then begin - if FRecordCount = -1 then - begin - if FStream.Position = 0 then - readStreamFields; - FStream.Read(FRecordCount, SizeOf(int64)); - end; + if not FDataSet.Active then + Exit; for i := 1 to ARowsetSize do begin - if FStream.Position = FStream.Size then - FStream.Size := 0; - if FStream.Size = 0 then + if FDataSet.Eof then Break; - FetchRow(ATable, AParentRow); + oRow := ATable.NewRow(True); + try + for j := 0 to FDataSet.FieldCount - 1 do + begin + if FDataSet.Fields[j].IsNull then + oRow.SetData(j, Null) + else + oRow.SetData(j, FDataSet.Fields[j].Value); + end; + ATable.Rows.Add(oRow); + except + FDFree(oRow); + raise; + end; + FDataSet.Next; Inc(Result); - end + end; end; end; @@ -665,11 +696,22 @@ function TFDPhysRDWCommand.RDWExecuteComand(exec: Boolean): Longint; try vRESTDataBase.ExecuteCommand(vPoolermethod, vSQL, vParams, vError, vMessageError, vDataSetList, vRowsAffected, exec, (not exec), - (not exec), False, vRESTDataBase.RESTClientPooler); + False, False, vRESTDataBase.RESTClientPooler); FStream.Size := 0; if (vDataSetList <> nil) and (not vDataSetList.IsNull) then + begin vDataSetList.SaveToStream(FStream); + if not exec then + begin + FStream.Position := 0; + FDataSet.Close; + FDataSet.LoadFromStream(FStream, sfBinary); + FDataSet.First; + FFieldCount := FDataSet.FieldDefs.Count; + FRecordCount := FDataSet.RecordCount; + end; + end; finally FreeAndNil(vDataSetList); vSQL.Free; diff --git a/CORE/Source/Database_Drivers/Native/NativeLinks/ADO/uRESTDWNativeLinkADO.pas b/CORE/Source/Database_Drivers/Native/NativeLinks/ADO/uRESTDWNativeLinkADO.pas new file mode 100644 index 000000000..30c21e28f --- /dev/null +++ b/CORE/Source/Database_Drivers/Native/NativeLinks/ADO/uRESTDWNativeLinkADO.pas @@ -0,0 +1,564 @@ +Unit uRESTDWNativeLinkADO; + +{$I uRESTDW.inc} + +Interface + +Uses +{$IFDEF DELPHIXE2UP} + System.Classes, System.SysUtils, System.Variants, Data.DB, Data.FMTBcd, + Data.Win.ADODB, Winapi.ADOInt, +{$ELSE} + Classes, SysUtils, Variants, DB, FMTBcd, ADODB, ADOInt, +{$ENDIF} + uRESTDWNativeDriver, uRESTDWDriverBase, uRESTDWParams, uRESTDWMemoryDataset; + +Type + TRESTDWNativeLinkADO = Class(TRESTDWNativeLink) + Private + FConnection : TADOConnection; + Procedure SetConnection(AValue : TADOConnection); + Protected + Procedure Notification(AComponent : TComponent; Operation : TOperation); Override; + Function GetConnection : TComponent; Override; + Public + Function GetQuery : TRESTDWDrvQuery; Override; + Function IsConnected : Boolean; Override; + Procedure Connect; Override; + Procedure Disconnect; Override; + Procedure ExecuteSelect(Const ASQL : String; AParams : TRESTDWParams; + AOutput : TStream; ACompress : Boolean); Override; + Function ExecuteCommand(Const ASQL : String; AParams : TRESTDWParams) : Int64; Override; + Published + Property Connection : TADOConnection Read FConnection Write SetConnection; + End; + +Procedure Register; + +Implementation + +Type + TRESTDWNativeADOQuery = Class(TRESTDWDrvQuery) + Private + FRowsAffected : Int64; + Public + Procedure ExecSQL; Override; + Procedure Prepare; Override; + Function ParamCount : Integer; Override; + Function RowsAffected : Int64; Override; + Function getParamDataType(IParam : Integer) : TFieldType; Override; + Function getParamName(IParam : Integer) : String; Override; + Function getParamSize(IParam : Integer) : Integer; Override; + Function getParamValue(IParam : Integer) : Variant; Override; + Procedure setParamDataType(IParam : Integer; AValue : TFieldType); Override; + Procedure setParamValue(IParam : Integer; AValue : Variant); Override; + Procedure LoadFromStreamParam(IParam : Integer; Stream : TStream; BlobType : TBlobType); Override; + End; + +Type + TDirectField = Record + Name : String; + DisplayName : String; + Size : Word; + DataType : TFieldType; + ADOType : DataTypeEnum; + Precision : Byte; + Scale : Byte; + ReadOnly : Boolean; + End; + + TDirectFields = Array Of TDirectField; + +Function MapADODataType(AType : DataTypeEnum; APrecision, AScale : Integer) : TFieldType; +Begin + Case AType Of + adTinyInt, + adSmallInt: Result := ftSmallint; + adInteger: Result := ftInteger; + adUnsignedInt, + adUnsignedBigInt: Result := ftLargeint; + adBigInt: Result := ftLargeint; + adUnsignedTinyInt, + adUnsignedSmallInt: Result := ftWord; + adSingle, + adDouble: Result := ftFloat; + adCurrency: Result := ftBCD; + adDecimal, + adNumeric, + adVarNumeric: + Begin + If (AScale > 4) Or (APrecision > 19) Then + Begin + Result := ftFMTBcd + End + Else + Begin + Result := ftBCD; + End; + End; + adBoolean: Result := ftBoolean; + adDBDate: Result := ftDate; + adDBTime: Result := ftTime; + adDate, + adDBTimeStamp: Result := ftDateTime; + adChar: Result := ftFixedChar; + adVarChar: Result := ftString; + adWChar: +{$IFDEF DELPHIXEUP} + Result := ftFixedWideChar; +{$ELSE} + Result := ftWideString; +{$ENDIF} + adBSTR, + adVarWChar: Result := ftWideString; + adLongVarChar: Result := ftMemo; + adLongVarWChar: +{$IFDEF DELPHIXEUP} + Result := ftWideMemo; +{$ELSE} + Result := ftMemo; +{$ENDIF} + adLongVarBinary: Result := ftBlob; + adBinary: Result := ftBytes; + adVarBinary: Result := ftVarBytes; + adGUID: Result := ftGuid; + Else + Begin + Result := ftUnknown; + End; + End; +End; + +Procedure VariantToBytes(Const AValue : OleVariant; Var ABytes : TRESTDWMemBytes); +Var + L, I, LowB, HighB : Integer; +Begin + SetLength(ABytes, 0); + If Not VarIsArray(AValue) Then + Begin + Exit; + End; + LowB := VarArrayLowBound(AValue, 1); + HighB := VarArrayHighBound(AValue, 1); + L := HighB - LowB + 1; + If L <= 0 Then + Begin + Exit; + End; + SetLength(ABytes, L); + For I := 0 To L - 1 Do + Begin + ABytes[I] := Byte(AValue[LowB + I]); + End; +End; + +Procedure StoreADOValue(AWriter : TRESTDWBinaryPacketWriter; AFieldIndex : Integer; + Const AField : TDirectField; Const AValue : OleVariant); +Var + S : AnsiString; + VSmall : SmallInt; + VWord : Word; + VInt : Integer; + VInt64 : Int64; + VDouble : Double; + VCurrency : Currency; + VBcd : TBcd; + VDateTime : TDateTime; + VBool : WordBool; + VGuid : TGUID; + B : TRESTDWMemBytes; +Begin + If VarIsNull(AValue) Or VarIsEmpty(AValue) Then + Begin + AWriter.StoreNull(AFieldIndex); + Exit; + End; + Case AField.DataType Of + ftString, + ftFixedChar, + ftWideString, +{$IFDEF DELPHIXEUP} + ftFixedWideChar, +{$ENDIF} + ftMemo +{$IFDEF DELPHIXEUP} + , ftWideMemo +{$ENDIF} + : + Begin + S := AnsiString(VarToStr(AValue)); + If Length(S) = 0 Then + Begin + AWriter.StoreField(AFieldIndex, Nil, 0) + End + Else + Begin + AWriter.StoreField(AFieldIndex, @S[1], Length(S)); + End; + End; + ftSmallint: + Begin + VSmall := AValue; + AWriter.StoreField(AFieldIndex, @VSmall, SizeOf(VSmall)); + End; + ftInteger: + Begin + VInt := AValue; + AWriter.StoreField(AFieldIndex, @VInt, SizeOf(VInt)); + End; + ftWord: + Begin + VWord := AValue; + AWriter.StoreField(AFieldIndex, @VWord, SizeOf(VWord)); + End; + ftLargeint: + Begin + VInt64 := AValue; + AWriter.StoreField(AFieldIndex, @VInt64, SizeOf(VInt64)); + End; + ftBoolean: + Begin + VBool := AValue; + AWriter.StoreField(AFieldIndex, @VBool, SizeOf(VBool)); + End; + ftFloat: + Begin + VDouble := AValue; + AWriter.StoreField(AFieldIndex, @VDouble, SizeOf(VDouble)); + End; + ftCurrency, + ftBCD: + Begin + VCurrency := AValue; + AWriter.StoreField(AFieldIndex, @VCurrency, SizeOf(VCurrency)); + End; + ftFMTBcd: + Begin + VBcd := StrToBcd(VarToStr(AValue)); + AWriter.StoreField(AFieldIndex, @VBcd, SizeOf(VBcd)); + End; + ftDate: + Begin + VDateTime := VarToDateTime(AValue); + VInt := DateTimeToTimeStamp(VDateTime).Date; + AWriter.StoreField(AFieldIndex, @VInt, SizeOf(VInt)); + End; + ftTime: + Begin + VDateTime := VarToDateTime(AValue); + VInt := DateTimeToTimeStamp(VDateTime).Time; + AWriter.StoreField(AFieldIndex, @VInt, SizeOf(VInt)); + End; + ftDateTime: + Begin + VDateTime := VarToDateTime(AValue); + AWriter.StoreField(AFieldIndex, @VDateTime, SizeOf(VDateTime)); + End; + ftGuid: + Begin + VGuid := StringToGUID(VarToStr(AValue)); + AWriter.StoreField(AFieldIndex, @VGuid, SizeOf(VGuid)); + End; + ftBytes, + ftVarBytes, + ftBlob: + Begin + VariantToBytes(AValue, B); + If Length(B) = 0 Then + Begin + AWriter.StoreField(AFieldIndex, Nil, 0) + End + Else + Begin + AWriter.StoreField(AFieldIndex, @B[0], Length(B)); + End; + End; + Else + Begin + DatabaseError('ADO data type is not representable by the RESTDW DataSet binary contract'); + End; + End; +End; + +Procedure BindADOParams(ACommand : TADOCommand; AParams : TRESTDWParams); +Var + I : Integer; + P : TRESTDWJSONParam; + AP : TParameter; +Begin + If (ACommand = Nil) Or (AParams = Nil) Then + Begin + Exit; + End; + ACommand.Parameters.Refresh; + For I := 0 To AParams.Count - 1 Do + Begin + P := AParams[I]; + If P = Nil Then + Begin + Continue; + End; + AP := ACommand.Parameters.FindParam(P.ParamName); + If AP <> Nil Then + Begin + AP.Value := P.Value; + End; + End; +End; + +Procedure TRESTDWNativeADOQuery.ExecSQL; +Begin + Inherited ExecSQL; + FRowsAffected:=TADOQuery(Self.Owner).ExecSQL; +End; + +Procedure TRESTDWNativeADOQuery.Prepare; +Begin + Inherited Prepare; + TADOQuery(Self.Owner).Prepared:=True; +End; + +Function TRESTDWNativeADOQuery.ParamCount : Integer; +Begin + Result:=TADOQuery(Self.Owner).Parameters.Count; + If (Result=0) and (Pos(':',SQL.Text)>0) Then + Begin + Prepare; + Result:=TADOQuery(Self.Owner).Parameters.Count; + End; +End; + +Function TRESTDWNativeADOQuery.RowsAffected : Int64; +Begin + Result:=FRowsAffected; +End; + +Function TRESTDWNativeADOQuery.getParamDataType(IParam : Integer) : TFieldType; +Begin + Result:=TADOQuery(Self.Owner).Parameters[IParam].DataType; +End; + +Function TRESTDWNativeADOQuery.getParamName(IParam : Integer) : String; +Begin + Result:=TADOQuery(Self.Owner).Parameters[IParam].Name; +End; + +Function TRESTDWNativeADOQuery.getParamSize(IParam : Integer) : Integer; +Begin + Result:=TADOQuery(Self.Owner).Parameters[IParam].Size; +End; + +Function TRESTDWNativeADOQuery.getParamValue(IParam : Integer) : Variant; +Begin + Result:=TADOQuery(Self.Owner).Parameters[IParam].Value; +End; + +Procedure TRESTDWNativeADOQuery.setParamDataType(IParam : Integer; AValue : TFieldType); +Begin + TADOQuery(Self.Owner).Parameters[IParam].DataType:=AValue; +End; + +Procedure TRESTDWNativeADOQuery.setParamValue(IParam : Integer; AValue : Variant); +Begin + TADOQuery(Self.Owner).Parameters[IParam].Value:=AValue; +End; + +Procedure TRESTDWNativeADOQuery.LoadFromStreamParam(IParam : Integer; Stream : TStream; + BlobType : TBlobType); +Begin + TADOQuery(Self.Owner).Parameters[IParam].LoadFromStream(Stream,TFieldType(BlobType)); +End; + +Function TRESTDWNativeLinkADO.GetConnection : TComponent; +Begin + Result := FConnection; +End; + +Function TRESTDWNativeLinkADO.GetQuery : TRESTDWDrvQuery; +Var + Query : TADOQuery; +Begin + Result := Nil; + If FConnection = Nil Then + Exit; + Query := TADOQuery.Create(Self); + Query.Connection := FConnection; + Query.ParamCheck := True; + Result := TRESTDWNativeADOQuery.Create(Query); +End; + +Procedure TRESTDWNativeLinkADO.SetConnection(AValue : TADOConnection); +Begin + If FConnection = AValue Then + Begin + Exit; + End; + If FConnection <> Nil Then + Begin + FConnection.RemoveFreeNotification(Self); + End; + FConnection := AValue; + If FConnection <> Nil Then + Begin + FConnection.FreeNotification(Self); + End; +End; + +Procedure TRESTDWNativeLinkADO.Notification(AComponent : TComponent; Operation : TOperation); +Begin + Inherited Notification(AComponent, Operation); + If (Operation = opRemove) And (AComponent = FConnection) Then + Begin + FConnection := Nil; + End; +End; + +Function TRESTDWNativeLinkADO.IsConnected : Boolean; +Begin + Result := (FConnection <> Nil) And FConnection.Connected; +End; + +Procedure TRESTDWNativeLinkADO.Connect; +Begin + If FConnection = Nil Then + Begin + DatabaseError('ADO Connection not assigned'); + End; + If Not FConnection.Connected Then + Begin + FConnection.Connected := True; + End; +End; + +Procedure TRESTDWNativeLinkADO.Disconnect; +Begin + If (FConnection <> Nil) And FConnection.Connected Then + Begin + FConnection.Connected := False; + End; +End; + +Procedure TRESTDWNativeLinkADO.ExecuteSelect(Const ASQL : String; AParams : TRESTDWParams; + AOutput : TStream; ACompress : Boolean); +Var + Cmd : TADOCommand; + RS : _Recordset; + Writer : TRESTDWBinaryPacketWriter; + Fields : TDirectFields; + F : Field; + I : Integer; + C : Integer; + LSize : Integer; + LWordSize : Word; + LType : TFieldType; +Begin + If FConnection = Nil Then + Begin + DatabaseError('ADO Connection not assigned'); + End; + If Not FConnection.Connected Then + Begin + FConnection.Connected := True; + End; + Cmd := TADOCommand.Create(Nil); + RS := Nil; + Writer := TRESTDWBinaryPacketWriter.Create(AOutput); + Try + Cmd.Connection := FConnection; + Cmd.CommandType := cmdText; + Cmd.CommandText := ASQL; + BindADOParams(Cmd, AParams); + RS := Cmd.Execute; + C := RS.Fields.Count; + SetLength(Fields, C); + Writer.ClearFieldDefs; + For I := 0 To C - 1 Do + Begin + F := RS.Fields.Item[I]; + Fields[I].Name := String(F.Name); + Fields[I].DisplayName := String(F.Name); + Fields[I].ADOType := F.Type_; + Fields[I].Precision := F.Precision; + Fields[I].Scale := F.NumericScale; + LType := MapADODataType(F.Type_, F.Precision, F.NumericScale); + Fields[I].DataType := LType; + If LType = ftUnknown Then + Begin + DatabaseError('ADO data type is not representable by the RESTDW DataSet binary contract: ' + + IntToStr(Ord(F.Type_))); + End; + If LType In [ftBCD, ftFMTBcd] Then + LSize := F.NumericScale + Else + LSize := F.DefinedSize; + If LSize < 0 Then + Begin + LSize := -LSize; + End; + If LType = ftGuid Then + Begin + LSize := 38; + End; + If LSize > High(Word) Then + Begin + LWordSize := High(Word) + End + Else + Begin + LWordSize := Word(LSize); + End; + Fields[I].Size := LWordSize; + Fields[I].ReadOnly := (F.Attributes And adFldUpdatable) = 0; + Writer.AddFieldDef(Fields[I].Name, Fields[I].DisplayName, Fields[I].Size, + Fields[I].DataType, Fields[I].ReadOnly); + End; + Writer.StoreFieldDefs(0); + While Not RS.EOF Do + Begin + Writer.BeginRecord; + For I := 0 To C - 1 Do + Begin + StoreADOValue(Writer, I, Fields[I], RS.Fields.Item[I].Value); + End; + Writer.EndRecord; + RS.MoveNext; + End; + Finally + Writer.Free; + RS := Nil; + Cmd.Free; + End; +End; + +Function TRESTDWNativeLinkADO.ExecuteCommand(Const ASQL : String; AParams : TRESTDWParams) : Int64; +Var + Cmd : TADOCommand; + Affected : Integer; +Begin + If FConnection = Nil Then + Begin + DatabaseError('ADO Connection not assigned'); + End; + If Not FConnection.Connected Then + Begin + FConnection.Connected := True; + End; + Cmd := TADOCommand.Create(Nil); + Try + Cmd.Connection := FConnection; + Cmd.CommandType := cmdText; + Cmd.CommandText := ASQL; + BindADOParams(Cmd, AParams); + Affected := 0; + Cmd.Execute(Affected, EmptyParam); + Result := Affected; + Finally + Cmd.Free; + End; +End; + +Procedure Register; +Begin + RegisterComponents('REST Dataware - Drivers', [TRESTDWNativeLinkADO]); +End; +End. diff --git a/CORE/Source/Database_Drivers/Native/NativeLinks/DBExpress/uRESTDWNativeLinkDBExpress.pas b/CORE/Source/Database_Drivers/Native/NativeLinks/DBExpress/uRESTDWNativeLinkDBExpress.pas new file mode 100644 index 000000000..2d689962a --- /dev/null +++ b/CORE/Source/Database_Drivers/Native/NativeLinks/DBExpress/uRESTDWNativeLinkDBExpress.pas @@ -0,0 +1,520 @@ +Unit uRESTDWNativeLinkDBExpress; + +{$I uRESTDW.inc} + +Interface + +Uses +{$IFDEF DELPHIXE2UP} + System.Classes, System.SysUtils, System.Variants, Data.DB, Data.FMTBcd, Data.SqlTimSt, + Data.SqlExpr, Data.DBXCommon, +{$ELSE} + Classes, SysUtils, Variants, DB, FMTBcd, SqlTimSt, SqlExpr, DBXCommon, +{$ENDIF} + uRESTDWNativeDriver, uRESTDWDriverBase, uRESTDWParams, uRESTDWMemoryDataset; + +Type + TRESTDWNativeLinkDBExpress = Class(TRESTDWNativeLink) + Private + FConnection : TSQLConnection; + Procedure SetConnection(AValue : TSQLConnection); + Protected + Procedure Notification(AComponent : TComponent; Operation : TOperation); Override; + Function GetConnection : TComponent; Override; + Public + Function GetQuery : TRESTDWDrvQuery; Override; + Function IsConnected : Boolean; Override; + Procedure Connect; Override; + Procedure Disconnect; Override; + Procedure ExecuteSelect(Const ASQL : String; AParams : TRESTDWParams; + AOutput : TStream; ACompress : Boolean); Override; + Function ExecuteCommand(Const ASQL : String; AParams : TRESTDWParams) : Int64; Override; + Published + Property Connection : TSQLConnection Read FConnection Write SetConnection; + End; + +Procedure Register; + +Implementation + +Type + TRESTDWNativeDBExpressQuery = Class(TRESTDWDrvQuery) + Private + FRowsAffected : Int64; + Public + Procedure ExecSQL; Override; + Procedure Prepare; Override; + Function ParamCount : Integer; Override; + Function RowsAffected : Int64; Override; + Function getParamDataType(IParam : Integer) : TFieldType; Override; + Function getParamName(IParam : Integer) : String; Override; + Function getParamSize(IParam : Integer) : Integer; Override; + Function getParamValue(IParam : Integer) : Variant; Override; + Procedure setParamDataType(IParam : Integer; AValue : TFieldType); Override; + Procedure setParamValue(IParam : Integer; AValue : Variant); Override; + Procedure LoadFromStreamParam(IParam : Integer; Stream : TStream; BlobType : TBlobType); Override; + End; + +Type + TDirectField = Record + Name : String; + DisplayName : String; + Size : Word; + DataType : TFieldType; + DBXType : Integer; + ReadOnly : Boolean; + End; + + TDirectFields = Array Of TDirectField; + +Function MapDBXDataType(AType : Integer) : TFieldType; +Begin + Case AType Of + TDBXDataTypes.BooleanType: Result := ftBoolean; + TDBXDataTypes.Int8Type, + TDBXDataTypes.Int16Type: Result := ftSmallint; + TDBXDataTypes.UInt8Type, + TDBXDataTypes.UInt16Type: Result := ftWord; + TDBXDataTypes.Int32Type: Result := ftInteger; + TDBXDataTypes.UInt32Type, + TDBXDataTypes.Int64Type, + TDBXDataTypes.UInt64Type: Result := ftLargeint; + TDBXDataTypes.SingleType, + TDBXDataTypes.DoubleType: Result := ftFloat; + TDBXDataTypes.CurrencyType: Result := ftBCD; + TDBXDataTypes.BcdType: Result := ftFMTBcd; + TDBXDataTypes.DateType: Result := ftDate; + TDBXDataTypes.TimeType: Result := ftTime; + TDBXDataTypes.DateTimeType, + TDBXDataTypes.TimeStampType, + TDBXDataTypes.TimeStampOffsetType: Result := ftDateTime; + TDBXDataTypes.AnsiStringType: Result := ftString; + TDBXDataTypes.WideStringType: Result := ftWideString; + TDBXDataTypes.BytesType, + TDBXDataTypes.VarBytesType: Result := ftVarBytes; + TDBXDataTypes.BlobType, + TDBXDataTypes.BinaryBlobType: Result := ftBlob; + Else + Begin + Result := ftUnknown; + End; + End; +End; + +Procedure BindDBXParams(ACommand : TDBXCommand; AParams : TRESTDWParams); +Var + I : Integer; + P : TRESTDWJSONParam; + DP : TDBXParameter; +Begin + If (ACommand = Nil) Or (AParams = Nil) Then + Begin + Exit; + End; + ACommand.Prepare; + For I := 0 To AParams.Count - 1 Do + Begin + P := AParams[I]; + If P = Nil Then + Begin + Continue; + End; + DP := ACommand.Parameters[P.ParamName]; + If DP <> Nil Then + Begin + DP.Value.AsVariant := P.Value; + End; + End; +End; + +Procedure StoreDBXValue(AWriter : TRESTDWBinaryPacketWriter; AFieldIndex : Integer; + ADBXType : Integer; AValue : TDBXValue); +Var + S : AnsiString; + VSmall : SmallInt; + VWord : Word; + VInt : Integer; + VInt64 : Int64; + VDouble : Double; + VCurrency : Currency; + VBcd : TBcd; + VDateTime : TDateTime; + VBool : WordBool; + Stm : TStream; + B : TRESTDWMemBytes; + L : Integer; +Begin + If (AValue = Nil) Or AValue.IsNull Then + Begin + AWriter.StoreNull(AFieldIndex); + Exit; + End; + Case ADBXType Of + TDBXDataTypes.AnsiStringType, + TDBXDataTypes.WideStringType: + Begin + S := AnsiString(AValue.AsString); + If Length(S) = 0 Then + Begin + AWriter.StoreField(AFieldIndex, Nil, 0) + End + Else + Begin + AWriter.StoreField(AFieldIndex, @S[1], Length(S)); + End; + End; + TDBXDataTypes.BooleanType: + Begin + VBool := AValue.AsBoolean; + AWriter.StoreField(AFieldIndex, @VBool, SizeOf(VBool)); + End; + TDBXDataTypes.Int8Type, + TDBXDataTypes.Int16Type: + Begin + VSmall := AValue.AsInt16; + AWriter.StoreField(AFieldIndex, @VSmall, SizeOf(VSmall)); + End; + TDBXDataTypes.UInt8Type, + TDBXDataTypes.UInt16Type: + Begin + VWord := AValue.AsUInt16; + AWriter.StoreField(AFieldIndex, @VWord, SizeOf(VWord)); + End; + TDBXDataTypes.Int32Type: + Begin + VInt := AValue.AsInt32; + AWriter.StoreField(AFieldIndex, @VInt, SizeOf(VInt)); + End; + TDBXDataTypes.UInt32Type, + TDBXDataTypes.Int64Type, + TDBXDataTypes.UInt64Type: + Begin + VInt64 := AValue.AsInt64; + AWriter.StoreField(AFieldIndex, @VInt64, SizeOf(VInt64)); + End; + TDBXDataTypes.SingleType, + TDBXDataTypes.DoubleType: + Begin + VDouble := AValue.AsDouble; + AWriter.StoreField(AFieldIndex, @VDouble, SizeOf(VDouble)); + End; + TDBXDataTypes.CurrencyType: + Begin + VCurrency := AValue.AsVariant; + AWriter.StoreField(AFieldIndex, @VCurrency, SizeOf(VCurrency)); + End; + TDBXDataTypes.BcdType: + Begin + VBcd := AValue.AsBcd; + AWriter.StoreField(AFieldIndex, @VBcd, SizeOf(VBcd)); + End; + TDBXDataTypes.DateType: + Begin + VDateTime := AValue.AsDateTime; + VInt := DateTimeToTimeStamp(VDateTime).Date; + AWriter.StoreField(AFieldIndex, @VInt, SizeOf(VInt)); + End; + TDBXDataTypes.TimeType: + Begin + VDateTime := AValue.AsDateTime; + VInt := DateTimeToTimeStamp(VDateTime).Time; + AWriter.StoreField(AFieldIndex, @VInt, SizeOf(VInt)); + End; + TDBXDataTypes.DateTimeType, + TDBXDataTypes.TimeStampType, + TDBXDataTypes.TimeStampOffsetType: + Begin + VDateTime := AValue.AsDateTime; + AWriter.StoreField(AFieldIndex, @VDateTime, SizeOf(VDateTime)); + End; + TDBXDataTypes.BytesType, + TDBXDataTypes.VarBytesType, + TDBXDataTypes.BlobType, + TDBXDataTypes.BinaryBlobType: + Begin + Stm := AValue.AsStream; + Try + If Stm = Nil Then + Begin + AWriter.StoreField(AFieldIndex, Nil, 0) + End + Else + Begin + Stm.Position := 0; + L := Stm.Size; + SetLength(B, L); + If L > 0 Then + Begin + Stm.ReadBuffer(B[0], L); + AWriter.StoreField(AFieldIndex, @B[0], L); + End + Else + Begin + AWriter.StoreField(AFieldIndex, Nil, 0); + End; + End; + Finally + Stm.Free; + End; + End; + Else + Begin + DatabaseError('dbExpress data type is not representable by the RESTDW DataSet binary contract: ' + + IntToStr(ADBXType)); + End; + End; +End; + +Procedure TRESTDWNativeDBExpressQuery.ExecSQL; +Begin + Inherited ExecSQL; + FRowsAffected:=TSQLQuery(Self.Owner).ExecSQL; +End; + +Procedure TRESTDWNativeDBExpressQuery.Prepare; +Begin + Inherited Prepare; + TSQLQuery(Self.Owner).Prepared:=True; +End; + +Function TRESTDWNativeDBExpressQuery.ParamCount : Integer; +Begin + Result:=TSQLQuery(Self.Owner).Params.Count; + If (Result=0) and (Pos(':',SQL.Text)>0) Then + Begin + Prepare; + Result:=TSQLQuery(Self.Owner).Params.Count; + End; +End; + +Function TRESTDWNativeDBExpressQuery.RowsAffected : Int64; +Begin + Result:=FRowsAffected; +End; + +Function TRESTDWNativeDBExpressQuery.getParamDataType(IParam : Integer) : TFieldType; +Begin + Result:=TSQLQuery(Self.Owner).Params[IParam].DataType; +End; + +Function TRESTDWNativeDBExpressQuery.getParamName(IParam : Integer) : String; +Begin + Result:=TSQLQuery(Self.Owner).Params[IParam].Name; +End; + +Function TRESTDWNativeDBExpressQuery.getParamSize(IParam : Integer) : Integer; +Begin + Result:=TSQLQuery(Self.Owner).Params[IParam].Size; +End; + +Function TRESTDWNativeDBExpressQuery.getParamValue(IParam : Integer) : Variant; +Begin + Result:=TSQLQuery(Self.Owner).Params[IParam].Value; +End; + +Procedure TRESTDWNativeDBExpressQuery.setParamDataType(IParam : Integer; AValue : TFieldType); +Begin + TSQLQuery(Self.Owner).Params[IParam].DataType:=AValue; +End; + +Procedure TRESTDWNativeDBExpressQuery.setParamValue(IParam : Integer; AValue : Variant); +Begin + TSQLQuery(Self.Owner).Params[IParam].Value:=AValue; +End; + +Procedure TRESTDWNativeDBExpressQuery.LoadFromStreamParam(IParam : Integer; Stream : TStream; + BlobType : TBlobType); +Begin + TSQLQuery(Self.Owner).Params[IParam].LoadFromStream(Stream,BlobType); +End; + +Function TRESTDWNativeLinkDBExpress.GetConnection : TComponent; +Begin + Result := FConnection; +End; + +Function TRESTDWNativeLinkDBExpress.GetQuery : TRESTDWDrvQuery; +Var + Query : TSQLQuery; +Begin + Result := Nil; + If FConnection = Nil Then + Exit; + Query := TSQLQuery.Create(Self); + Query.SQLConnection := FConnection; + Query.ParamCheck := True; + Result := TRESTDWNativeDBExpressQuery.Create(Query); +End; + +Procedure TRESTDWNativeLinkDBExpress.SetConnection(AValue : TSQLConnection); +Begin + If FConnection = AValue Then + Begin + Exit; + End; + If FConnection <> Nil Then + Begin + FConnection.RemoveFreeNotification(Self); + End; + FConnection := AValue; + If FConnection <> Nil Then + Begin + FConnection.FreeNotification(Self); + End; +End; + +Procedure TRESTDWNativeLinkDBExpress.Notification(AComponent : TComponent; Operation : TOperation); +Begin + Inherited Notification(AComponent, Operation); + If (Operation = opRemove) And (AComponent = FConnection) Then + Begin + FConnection := Nil; + End; +End; + +Function TRESTDWNativeLinkDBExpress.IsConnected : Boolean; +Begin + Result := (FConnection <> Nil) And FConnection.Connected; +End; + +Procedure TRESTDWNativeLinkDBExpress.Connect; +Begin + If FConnection = Nil Then + Begin + DatabaseError('dbExpress Connection not assigned'); + End; + If Not FConnection.Connected Then + Begin + FConnection.Connected := True; + End; +End; + +Procedure TRESTDWNativeLinkDBExpress.Disconnect; +Begin + If (FConnection <> Nil) And FConnection.Connected Then + Begin + FConnection.Connected := False; + End; +End; + +Procedure TRESTDWNativeLinkDBExpress.ExecuteSelect(Const ASQL : String; AParams : TRESTDWParams; + AOutput : TStream; ACompress : Boolean); +Var + Cmd : TDBXCommand; + Reader : TDBXReader; + Writer : TRESTDWBinaryPacketWriter; + Fields : TDirectFields; + VT : TDBXValueType; + I : Integer; + C : Integer; + LSize : Int64; + LWordSize : Word; + LType : TFieldType; +Begin + If FConnection = Nil Then + Begin + DatabaseError('dbExpress Connection not assigned'); + End; + If Not FConnection.Connected Then + Begin + FConnection.Connected := True; + End; + If FConnection.DBXConnection = Nil Then + Begin + DatabaseError('dbExpress native DBXConnection not available'); + End; + Cmd := FConnection.DBXConnection.CreateCommand; + Reader := Nil; + Writer := TRESTDWBinaryPacketWriter.Create(AOutput); + Try + Cmd.CommandType := TDBXCommandTypes.DbxSQL; + Cmd.Text := ASQL; + Cmd.RowSetSize := 1000; + BindDBXParams(Cmd, AParams); + Reader := Cmd.ExecuteQuery; + C := Reader.ColumnCount; + SetLength(Fields, C); + Writer.ClearFieldDefs; + For I := 0 To C - 1 Do + Begin + VT := Reader.ValueType[I]; + Fields[I].Name := VT.Name; + Fields[I].DisplayName := VT.DisplayName; + Fields[I].DBXType := VT.DataType; + Fields[I].DataType := MapDBXDataType(VT.DataType); + Fields[I].ReadOnly := False; + If Fields[I].DataType = ftUnknown Then + Begin + DatabaseError('dbExpress data type is not representable by the RESTDW DataSet binary contract: ' + + IntToStr(VT.DataType)); + End; + If VT.DataType In [TDBXDataTypes.CurrencyType, TDBXDataTypes.BcdType] Then + LSize := VT.Scale + Else + LSize := VT.Size; + If LSize < 0 Then + Begin + LSize := -LSize; + End; + If LSize > High(Word) Then + Begin + LWordSize := High(Word) + End + Else + Begin + LWordSize := Word(LSize); + End; + Fields[I].Size := LWordSize; + Writer.AddFieldDef(Fields[I].Name, Fields[I].DisplayName, Fields[I].Size, + Fields[I].DataType, Fields[I].ReadOnly); + End; + Writer.StoreFieldDefs(0); + While Reader.Next Do + Begin + Writer.BeginRecord; + For I := 0 To C - 1 Do + Begin + StoreDBXValue(Writer, I, Fields[I].DBXType, Reader.Value[I]); + End; + Writer.EndRecord; + End; + Finally + Writer.Free; + Reader.Free; + Cmd.Free; + End; +End; + +Function TRESTDWNativeLinkDBExpress.ExecuteCommand(Const ASQL : String; AParams : TRESTDWParams) : Int64; +Var + Cmd : TDBXCommand; +Begin + If FConnection = Nil Then + Begin + DatabaseError('dbExpress Connection not assigned'); + End; + If Not FConnection.Connected Then + Begin + FConnection.Connected := True; + End; + If FConnection.DBXConnection = Nil Then + Begin + DatabaseError('dbExpress native DBXConnection not available'); + End; + Cmd := FConnection.DBXConnection.CreateCommand; + Try + Cmd.CommandType := TDBXCommandTypes.DbxSQL; + Cmd.Text := ASQL; + BindDBXParams(Cmd, AParams); + Cmd.ExecuteUpdate; + Result := Cmd.RowsAffected; + Finally + Cmd.Free; + End; +End; + +Procedure Register; +Begin + RegisterComponents('REST Dataware - Drivers', [TRESTDWNativeLinkDBExpress]); +End; +End. diff --git a/CORE/Source/Database_Drivers/Native/NativeLinks/FireDAC/uRESTDWNativeLinkFD.pas b/CORE/Source/Database_Drivers/Native/NativeLinks/FireDAC/uRESTDWNativeLinkFD.pas new file mode 100644 index 000000000..80ec6cc3c --- /dev/null +++ b/CORE/Source/Database_Drivers/Native/NativeLinks/FireDAC/uRESTDWNativeLinkFD.pas @@ -0,0 +1,583 @@ +Unit uRESTDWNativeLinkFD; + +{$I uRESTDW.inc} + +Interface + +Uses + Classes, SysUtils, Variants, DB, FMTBcd, SqlTimSt, + FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param, FireDAC.Stan.Util, FireDAC.DatS, + FireDAC.Phys.Intf, FireDAC.Phys, FireDAC.Comp.Client, + uRESTDWNativeDriver, uRESTDWDriverBase, uRESTDWParams, uRESTDWMemoryDataset; + +Type + TRESTDWNativeLinkFD = Class(TRESTDWNativeLink) + Private + FConnection : TFDConnection; + Procedure SetConnection(AValue : TFDConnection); + Protected + Procedure Notification(AComponent : TComponent; Operation : TOperation); Override; + Function GetConnection : TComponent; Override; + Public + Function GetQuery : TRESTDWDrvQuery; Override; + Function IsConnected : Boolean; Override; + Procedure Connect; Override; + Procedure Disconnect; Override; + Procedure ExecuteSelect(Const ASQL : String; AParams : TRESTDWParams; + AOutput : TStream; ACompress : Boolean); Overload; Override; + Procedure ExecuteSelect(Const ASQL : String; AParams : TRESTDWParams; + AOutput : TStream; ACompress : Boolean; + ABinaryCompatibleMode : Boolean); Overload; Override; + Function ExecuteCommand(Const ASQL : String; AParams : TRESTDWParams) : Int64; Override; + Published + Property Connection : TFDConnection Read FConnection Write SetConnection; + End; + +Procedure Register; + +Implementation + +Type + TRESTDWNativeFDQuery = Class(TRESTDWDrvQuery) + Public + Procedure ExecSQL; Override; + Procedure Prepare; Override; + Function ParamCount : Integer; Override; + Function RowsAffected : Int64; Override; + Function getParamDataType(IParam : Integer) : TFieldType; Override; + Function getParamName(IParam : Integer) : String; Override; + Function getParamSize(IParam : Integer) : Integer; Override; + Function getParamValue(IParam : Integer) : Variant; Override; + Procedure setParamDataType(IParam : Integer; AValue : TFieldType); Override; + Procedure setParamValue(IParam : Integer; AValue : Variant); Override; + Procedure LoadFromStreamParam(IParam : Integer; Stream : TStream; BlobType : TBlobType); Override; + End; + + TFDConnectionAccess = Class(TFDConnection); + PRESTDWUInt64 = ^UInt64; + + TDirectField = Record + Name : String; + DisplayName : String; + Size : Word; + DataType : TFieldType; + FDType : TFDDataType; + ReadOnly : Boolean; + End; + + TDirectFields = Array Of TDirectField; + +Function MapDataType(AType : TFDDataType) : TFieldType; +Begin + Case AType Of + dtBoolean: Result := ftBoolean; + dtSByte, + dtInt16: Result := ftSmallint; + dtInt32: Result := ftInteger; + dtInt64: Result := ftLargeint; + dtByte, + dtUInt16: Result := ftWord; + dtUInt32, + dtUInt64: Result := ftLargeint; + dtSingle: Result := ftFloat; + dtDouble, + dtExtended: Result := ftFloat; + dtCurrency: Result := ftBCD; + dtBCD: Result := ftBCD; + dtFmtBCD: Result := ftFMTBcd; + dtDate: Result := ftDate; + dtTime: Result := ftTime; + dtDateTime: Result := ftDateTime; + dtDateTimeStamp: Result := ftDateTime; +{$IFDEF DELPHI10_4UP} + dtDateTimeStampOff: Result := ftDateTime; +{$ENDIF} + dtAnsiString: Result := ftString; + dtWideString: Result := ftWideString; + dtByteString: Result := ftVarBytes; + dtBlob, + dtHBlob, + dtHBFile: Result := ftBlob; + dtMemo, + dtHMemo, + dtXML: Result := ftMemo; + dtWideMemo, + dtWideHMemo: Result := ftWideMemo; + dtGUID: Result := ftGuid; + Else + Result := ftUnknown; + End; +End; + +Procedure StoreFireDACValue(AWriter : TRESTDWBinaryPacketWriter; + AFieldIndex : Integer; AFDType : TFDDataType; + ABuffer : Pointer; ADataLen : LongWord); +Var + S : AnsiString; + WS : WideString; + VSmall : SmallInt; + VWord : Word; + VInt : Integer; + VInt64 : Int64; + VSingle : Single; + VDouble : Double; + VCurrency : Currency; + VBcd : TBcd; + VDateTime : TDateTime; +{$IFDEF DELPHI10_4UP} + VTimeStampOffset : TSQLTimeStampOffset; +{$ENDIF} + VBool : WordBool; + VGuid : TGUID; +Begin + If ABuffer = Nil Then + Begin + AWriter.StoreNull(AFieldIndex); + Exit; + End; + Case AFDType Of + dtAnsiString: + AWriter.StoreField(AFieldIndex, ABuffer, ADataLen); + dtWideString: + Begin + SetLength(WS, ADataLen); + If ADataLen > 0 Then + Move(ABuffer^, WS[1], ADataLen * SizeOf(WideChar)); + S := AnsiString(String(WS)); + AWriter.StoreField(AFieldIndex, Pointer(S), Length(S)); + End; + dtByteString, + dtBlob, + dtHBlob, + dtHBFile, + dtMemo, + dtHMemo, + dtXML: AWriter.StoreField(AFieldIndex, ABuffer, ADataLen); + dtWideMemo, + dtWideHMemo: AWriter.StoreField(AFieldIndex, ABuffer, ADataLen * SizeOf(WideChar)); + dtBoolean: + Begin + VBool := PWordBool(ABuffer)^; + AWriter.StoreField(AFieldIndex, @VBool, SizeOf(VBool)); + End; + dtSByte: + Begin + VSmall := PShortInt(ABuffer)^; + AWriter.StoreField(AFieldIndex, @VSmall, SizeOf(VSmall)); + End; + dtInt16: AWriter.StoreField(AFieldIndex, ABuffer, SizeOf(SmallInt)); + dtInt32: AWriter.StoreField(AFieldIndex, ABuffer, SizeOf(Integer)); + dtInt64: AWriter.StoreField(AFieldIndex, ABuffer, SizeOf(Int64)); + dtByte: + Begin + VWord := PByte(ABuffer)^; + AWriter.StoreField(AFieldIndex, @VWord, SizeOf(VWord)); + End; + dtUInt16: AWriter.StoreField(AFieldIndex, ABuffer, SizeOf(Word)); + dtUInt32: + Begin + VInt64 := PCardinal(ABuffer)^; + AWriter.StoreField(AFieldIndex, @VInt64, SizeOf(VInt64)); + End; + dtUInt64: + Begin + If PRESTDWUInt64(ABuffer)^ > UInt64(High(Int64)) Then + DatabaseError('FireDAC UInt64 value exceeds RESTDW DataSet ftLargeInt range'); + VInt64 := Int64(PRESTDWUInt64(ABuffer)^); + AWriter.StoreField(AFieldIndex, @VInt64, SizeOf(VInt64)); + End; + dtSingle: + Begin + VDouble := PSingle(ABuffer)^; + AWriter.StoreField(AFieldIndex, @VDouble, SizeOf(VDouble)); + End; + dtDouble: + Begin + VDouble := PDouble(ABuffer)^; + AWriter.StoreField(AFieldIndex, @VDouble, SizeOf(VDouble)); + End; + dtExtended: + Begin + VDouble := PExtended(ABuffer)^; + AWriter.StoreField(AFieldIndex, @VDouble, SizeOf(VDouble)); + End; + dtCurrency: + Begin + VCurrency := PCurrency(ABuffer)^; + AWriter.StoreField(AFieldIndex, @VCurrency, SizeOf(VCurrency)); + End; + dtBCD: + Begin + VBcd := PBcd(ABuffer)^; + If Not BcdToCurr(VBcd, VCurrency) Then + DatabaseError('FireDAC BCD value cannot be represented by RESTDW DataSet ftBCD'); + AWriter.StoreField(AFieldIndex, @VCurrency, SizeOf(VCurrency)); + End; + dtFmtBCD: + Begin + VBcd := PBcd(ABuffer)^; + AWriter.StoreField(AFieldIndex, @VBcd, SizeOf(VBcd)); + End; + dtDate: + Begin + VInt := PInteger(ABuffer)^; + AWriter.StoreField(AFieldIndex, @VInt, SizeOf(VInt)); + End; + dtTime: + Begin + VDateTime := FDTime2DateTime(PInteger(ABuffer)^); + VInt := DateTimeToTimeStamp(VDateTime).Time; + AWriter.StoreField(AFieldIndex, @VInt, SizeOf(VInt)); + End; + dtDateTime: + Begin + VDateTime := FDMSecs2DateTime(PDateTimeRec(ABuffer)^.DateTime); + AWriter.StoreField(AFieldIndex, @VDateTime, SizeOf(VDateTime)); + End; + dtDateTimeStamp: + Begin + VDateTime := SQLTimeStampToDateTime(PSQLTimeStamp(ABuffer)^); + AWriter.StoreField(AFieldIndex, @VDateTime, SizeOf(VDateTime)); + End; +{$IFDEF DELPHI10_4UP} + dtDateTimeStampOff: + Begin + Move(ABuffer^, VTimeStampOffset, SizeOf(VTimeStampOffset)); + VDateTime := SQLTimeStampOffsetToDateTime(VTimeStampOffset); + AWriter.StoreField(AFieldIndex, @VDateTime, SizeOf(VDateTime)); + End; +{$ENDIF} + dtGUID: + Begin + VGuid := PGUID(ABuffer)^; + AWriter.StoreField(AFieldIndex, @VGuid, SizeOf(VGuid)); + End; + Else + AWriter.StoreField(AFieldIndex, ABuffer, ADataLen); + End; +End; + +Procedure BindParams(ACmd : IFDPhysCommand; AParams : TRESTDWParams); +Var + I : Integer; + P : TRESTDWJSONParam; + FP : TFDParam; +Begin + If (AParams = Nil) Or (ACmd = Nil) Then + Exit; + For I := 0 To AParams.Count - 1 Do + Begin + P := AParams[I]; + If P = Nil Then + Continue; + FP := ACmd.Params.FindParam(P.ParamName); + If FP <> Nil Then + FP.Value := P.Value; + End; +End; + +Procedure TRESTDWNativeFDQuery.ExecSQL; +Begin + Inherited ExecSQL; + TFDQuery(Self.Owner).ExecSQL; +End; + +Procedure TRESTDWNativeFDQuery.Prepare; +Begin + Inherited Prepare; + TFDQuery(Self.Owner).Prepare; +End; + +Function TRESTDWNativeFDQuery.ParamCount : Integer; +Begin + Result:=TFDQuery(Self.Owner).Params.Count; + If (Result=0) and (Pos(':',SQL.Text)>0) Then + Begin + Prepare; + Result:=TFDQuery(Self.Owner).Params.Count; + End; +End; + +Function TRESTDWNativeFDQuery.RowsAffected : Int64; +Begin + Result:=TFDQuery(Self.Owner).RowsAffected; +End; + +Function TRESTDWNativeFDQuery.getParamDataType(IParam : Integer) : TFieldType; +Begin + Result:=TFDQuery(Self.Owner).Params[IParam].DataType; +End; + +Function TRESTDWNativeFDQuery.getParamName(IParam : Integer) : String; +Begin + Result:=TFDQuery(Self.Owner).Params[IParam].Name; +End; + +Function TRESTDWNativeFDQuery.getParamSize(IParam : Integer) : Integer; +Begin + Result:=TFDQuery(Self.Owner).Params[IParam].Size; +End; + +Function TRESTDWNativeFDQuery.getParamValue(IParam : Integer) : Variant; +Begin + Result:=TFDQuery(Self.Owner).Params[IParam].Value; +End; + +Procedure TRESTDWNativeFDQuery.setParamDataType(IParam : Integer; AValue : TFieldType); +Begin + TFDQuery(Self.Owner).Params[IParam].DataType:=AValue; +End; + +Procedure TRESTDWNativeFDQuery.setParamValue(IParam : Integer; AValue : Variant); +Begin + TFDQuery(Self.Owner).Params[IParam].Value:=AValue; +End; + +Procedure TRESTDWNativeFDQuery.LoadFromStreamParam(IParam : Integer; Stream : TStream; + BlobType : TBlobType); +Begin + TFDQuery(Self.Owner).Params[IParam].LoadFromStream(Stream,BlobType); +End; + +Function TRESTDWNativeLinkFD.GetConnection : TComponent; +Begin + Result := FConnection; +End; + +Function TRESTDWNativeLinkFD.GetQuery : TRESTDWDrvQuery; +Var + Query : TFDQuery; +Begin + Result := Nil; + If FConnection = Nil Then + Exit; + Query := TFDQuery.Create(Self); + Query.Connection := FConnection; + Query.ResourceOptions.ParamCreate := True; + Query.ResourceOptions.StoreItems := [siMeta, siData, siDelta]; + Query.FetchOptions.Mode := fmAll; + Result := TRESTDWNativeFDQuery.Create(Query); +End; + +Procedure TRESTDWNativeLinkFD.SetConnection(AValue : TFDConnection); +Begin + If FConnection = AValue Then + Exit; + If FConnection <> Nil Then + FConnection.RemoveFreeNotification(Self); + FConnection := AValue; + If FConnection <> Nil Then + FConnection.FreeNotification(Self); +End; + +Procedure TRESTDWNativeLinkFD.Notification(AComponent : TComponent; Operation : TOperation); +Begin + Inherited Notification(AComponent, Operation); + If (Operation = opRemove) And (AComponent = FConnection) Then + FConnection := Nil; +End; + +Function TRESTDWNativeLinkFD.IsConnected : Boolean; +Begin + Result := (FConnection <> Nil) And FConnection.Connected; +End; + +Procedure TRESTDWNativeLinkFD.Connect; +Begin + If FConnection = Nil Then + DatabaseError('FireDAC Connection not assigned'); + If Not FConnection.Connected Then + FConnection.Connected := True; +End; + +Procedure TRESTDWNativeLinkFD.Disconnect; +Begin + If (FConnection <> Nil) And FConnection.Connected Then + FConnection.Connected := False; +End; + +Procedure TRESTDWNativeLinkFD.ExecuteSelect(Const ASQL : String; AParams : TRESTDWParams; + AOutput : TStream; ACompress : Boolean; + ABinaryCompatibleMode : Boolean); +Var + Query : TFDQuery; + Param : TRESTDWJSONParam; + I : Integer; +Begin + If ABinaryCompatibleMode Then + Begin + ExecuteSelect(ASQL, AParams, AOutput, ACompress); + Exit; + End; + If FConnection = Nil Then + DatabaseError('FireDAC Connection not assigned'); + If Not FConnection.Connected Then + FConnection.Connected := True; + Query := TFDQuery.Create(Nil); + Try + Query.Connection := FConnection; + Query.SQL.Text := ASQL; + If AParams <> Nil Then + Begin + For I := 0 To AParams.Count - 1 Do + Begin + Param := AParams[I]; + If (Param <> Nil) And (Query.Params.FindParam(Param.ParamName) <> Nil) Then + Query.Params.ParamByName(Param.ParamName).Value := Param.Value; + End; + End; + Query.Open; + AOutput.Position := 0; + AOutput.Size := 0; + Query.SaveToStream(AOutput, sfBinary); + AOutput.Position := 0; + Finally + Query.Free; + End; +End; + +Procedure TRESTDWNativeLinkFD.ExecuteSelect(Const ASQL : String; AParams : TRESTDWParams; + AOutput : TStream; ACompress : Boolean); +Var + P : IFDPhysConnection; + Cmd : IFDPhysCommand; + Tab : TFDDatSTable; + Row : TFDDatSRow; + Col : TFDDatSColumn; + Writer : TRESTDWBinaryPacketWriter; + Fields : TDirectFields; + A, I : Integer; + Data : Pointer; + DataLen : LongWord; + LSize : LongWord; + LWordSize : Word; + LType : TFieldType; + VTimeStamp : TSQLTimeStamp; + VDateTime : TDateTime; +Begin + If FConnection = Nil Then + DatabaseError('FireDAC Connection not assigned'); + If Not FConnection.Connected Then + FConnection.Connected := True; + P := TFDConnectionAccess(FConnection).ConnectionIntf; + P.CreateCommand(Cmd); + Cmd.CommandText := ASQL; + Cmd.Options.FetchOptions.RowsetSize := 1000; + Cmd.Prepare; + BindParams(Cmd, AParams); + Tab := Cmd.Define; + SetLength(Fields, Tab.Columns.Count); + Writer := TRESTDWBinaryPacketWriter.Create(AOutput); + Try + Writer.ClearFieldDefs; + For I := 0 To Tab.Columns.Count - 1 Do + Begin + Col := Tab.Columns.ItemsI[I]; + Fields[I].Name := Col.Name; + Fields[I].DisplayName := Col.Name; + Fields[I].FDType := Col.DataType; + LType := MapDataType(Col.DataType); + Fields[I].DataType := LType; + If LType = ftUnknown Then + DatabaseError('FireDAC data type is not representable by the RESTDW DataSet binary contract: ' + + IntToStr(Ord(Col.DataType))); + LSize := Col.Size; + If Col.DataType = dtCurrency Then + Begin + LSize := Col.Scale; + If LSize < 0 Then + LSize := -LSize; + End; + If LType = ftGuid Then + LSize := 38; + If LSize > High(Word) Then + LWordSize := High(Word) + Else + LWordSize := Word(LSize); + Fields[I].Size := LWordSize; + Fields[I].ReadOnly := caReadOnly in Col.Attributes; + Writer.AddFieldDef(Fields[I].Name, Fields[I].DisplayName, Fields[I].Size, + Fields[I].DataType, Fields[I].ReadOnly); + End; + Writer.StoreFieldDefs(0); + Cmd.Open; + Repeat + Tab.Clear; + Cmd.Fetch(Tab, False, False); + If Tab.Rows.Count = 0 Then + Break; + For A := 0 To Tab.Rows.Count - 1 Do + Begin + Row := Tab.Rows.ItemsI[A]; + Writer.BeginRecord; + For I := 0 To Tab.Columns.Count - 1 Do + Begin + If Fields[I].FDType = dtDateTimeStamp Then + Begin + FillChar(VTimeStamp, SizeOf(VTimeStamp), 0); + Data := @VTimeStamp; + DataLen := 0; + If Row.GetData(I, rvDefault, Data, SizeOf(VTimeStamp), DataLen, True) Then + Begin + VDateTime := SQLTimeStampToDateTime(VTimeStamp); + Writer.StoreField(I, @VDateTime, SizeOf(VDateTime)); + End + Else + Writer.StoreNull(I); + End + Else + Begin + Data := Nil; + DataLen := 0; + If Row.GetData(I, rvDefault, Data, 0, DataLen, False) Then + StoreFireDACValue(Writer, I, Fields[I].FDType, Data, DataLen) + Else + Writer.StoreNull(I); + End; + End; + Writer.EndRecord; + End; + Until False; + Finally + Writer.Free; + Cmd := Nil; + End; +End; + +Function TRESTDWNativeLinkFD.ExecuteCommand(Const ASQL : String; AParams : TRESTDWParams) : Int64; +Var + Q : TFDQuery; + I : Integer; + P : TRESTDWJSONParam; + FP : TFDParam; +Begin + If FConnection = Nil Then + DatabaseError('FireDAC Connection not assigned'); + Q := TFDQuery.Create(Nil); + Try + Q.Connection := FConnection; + Q.SQL.Text := ASQL; + Q.Prepare; + If AParams <> Nil Then + For I := 0 To AParams.Count - 1 Do + Begin + P := AParams[I]; + If P = Nil Then + Continue; + FP := Q.Params.FindParam(P.ParamName); + If FP <> Nil Then + FP.Value := P.Value; + End; + Q.ExecSQL; + Result := Q.RowsAffected; + Finally + Q.Free; + End; +End; + +Procedure Register; +Begin + RegisterComponents('REST Dataware - Drivers', [TRESTDWNativeLinkFD]); +End; + +End. diff --git a/CORE/Source/Database_Drivers/Native/NativeLinks/SQLDB/uRESTDWNativeLinkSQLDB.lrs b/CORE/Source/Database_Drivers/Native/NativeLinks/SQLDB/uRESTDWNativeLinkSQLDB.lrs new file mode 100644 index 000000000..11c014c14 --- /dev/null +++ b/CORE/Source/Database_Drivers/Native/NativeLinks/SQLDB/uRESTDWNativeLinkSQLDB.lrs @@ -0,0 +1,44 @@ +LazarusResources.Add('TRESTDWNativeLinkSQLDB','PNG',[ + #137#80#78#71#13#10#26#10#0#0#0#13#73#72#68#82#0#0#0#24#0#0#0#24#8#6#0#0#0#224#119#61#248#0#0#4#193#73#68#65 + +#84#120#218#189#150#109#136#156#213#21#199#127#231#222#103#102#119#102#55#201#100#179#217#221#236#102#99#108 + +#197#53#182#214#90#65#41#66#19#69#33#20#66#84#8#10#214#15#162#136#210#126#81#66#177#138#21#81#66#173#138#253 + +#80#16#173#84#20#65#49#95#196#55#180#145#168#209#88#76#86#227#162#134#68#178#113#223#223#102#178#47#51#179 + +#179#207#51#207#189#247#248#65#179#238#6#215#15#162#222#47#247#112#225#222#31#255#115#238#159#115#224#103#92 + +#242#83#220#149#37#187#102#225#220#157#191#187#244#158#182#213#77#205#81#72#131#21#17#49#96#8#224#21#15#16#60 + +#137#162#214#16#197#131#147#147#79#78#141#239#33#142#135#78#191#113#38#32#2#80#85#126#221#210#213#189#115#235 + +#165#7#238#222#253#231#246#166#254#65#136#171#80#91#128#56#1#239#193#8#24#3#40#193#59#76#188#128#235#237#167 + +#35#214#43#255#189#49#221#118#234#196#232#168#124#7#36#2#16#17#253#109#161#229#154#155#175#218#214#222#116 + +#240#131#196#191#182#47#178#153#8#95#75#32#117#160#10#33#96#157#3#231#49#137#163#94#156#34#219#245#11#191#189 + +#177#240#203#71#191#252#244#60#129#145#93#96#247#242#181#208#101#0#0#151#201#4#119#114#88#233#59#98#21#172#87 + +#65#27#34#200#24#68#3#36#41#222#27#196#7#40#207#35#34#248#177#17#137#27#87#135#85#226#211#249#21#106#96#78#7 + +#249#200#96#196#8#26#161#137#7#31#144#160#24#231#192#57#112#1#19#59#152#173#16#68#72#107#49#117#155#161#33 + +#155#49#77#186#114#145#205#210#192#10#80#119#72#173#134#12#143#34#195#99#80#75#144#137#18#76#76#161#67#131 + +#104#219#122#220#191#254#73#217#5#234#193#16#82#197#125#207#247#90#76#81#26#2#88#3#65#33#50#112#253#117#48#87 + +#65#94#216#11#219#175#66#186#55#226#79#28#199#79#87#97#93#1#181#134#224#3#169#19#226#239#1#44#42#8#33#96#156 + +#135#137#41#248#235#93#176#177#27#6#250#145#75#46#65#255#116#3#245#82#9#217#179#135#120#205#42#64#49#86#113 + +#36#164#145#128#71#86#242#194#183#0#239#209#36#6#205#192#91#7#96#243#38#52#159#71#47#255#61#110#255#126#42#79 + +#61#65#122#240#255#36#193#225#203#85#102#211#58#137#4#50#153#8#219#216#152#0#250#249#249#187#236#210#55#151 + +#165#40#178#22#17#3#54#66#15#188#79#189#247#48#153#255#62#78#253#112#47#116#116#146#221#180#25#218#214#51#63 + +#63#79#46#151#99#60#19#209#180#16#83#78#199#72#226#248#108#224#200#209#163#123#23#150#26#119#25#192#154#8#108 + +#4#229#50#110#251#54#162#139#47#196#189#242#26#245#199#255#67#116#215#110#178#143#60#132#89#87#32#30#30#103 + +#182#239#8#197#238#46#6#83#111#250#175#188#142#158#205#91#158#78#231#211#61#211#125#135#247#203#27#79#222#123 + +#2#70#190#81#18#22#165#92#212#222#254#151#147#183#222#166#186#233#87#105#69#10#90#89#221#173#21#89#173#149 + +#236#90#157#145#102#157#140#10#90#121#254#121#253#248#220#30#125#175#125#131#78#220#114#187#142#221#241#144 + +#222#248#161#106#215#187#170#27#254#167#186#246#117#175#249#157#127#59#182#189#185#121#61#170#178#220#104#46 + +#168#175#86#32#142#209#92#22#245#117#124#62#143#243#1#215#216#64#221#5#230#238#188#151#19#51#19#116#191#244 + +#58#45#13#13#188#172#29#76#90#79#179#120#29#170#67#90#18#111#42#133#158#222#164#186#9#145#226#50#128#87#159 + +#205#57#66#226#82#141#147#4#31#69#248#160#132#160#164#42#212#0#55#62#202#16#158#94#219#202#195#237#91#200#86 + +#161#181#226#41#79#169#140#126#118#138#228#200#120#20#6#138#65#248#214#26#139#128#25#23#31#61#244#229#136#185 + +#230#156#139#76#227#39#125#78#141#197#169#39#88#37#66#177#234#201#68#22#149#96#142#15#207#153#247#106#129#233 + +#57#129#89#11#3#14#6#42#80#153#35#202#214#13#25#132#116#9#224#62#48#247#151#107#111#254#99#224#216#3#165#124 + +#231#157#173#157#173#77#94#13#105#80#64#200#202#215#119#242#146#114#172#86#229#172#214#38#214#165#37#122#203 + +#117#70#138#74#181#90#68#87#77#163#109#29#136#111#215#166#126#180#184#84#193#253#223#84#251#80#113#242#239 + +#135#90#202#79#220#241#199#29#55#229#178#13#45#222#7#175#22#177#81#164#214#230#179#146#139#134#15#188#220#119 + +#89#79#174#121#135#237#106#229#55#153#89#91#88#27#248#188#208#73#185#216#66#24#116#106#230#51#146#228#137#152 + +#59#35#69#139#74#166#23#70#31#123#238#197#7#87#178#126#103#225#130#218#88#217#94#253#177#51#9#199#87#41#167 + +#18#161#84#131#89#27#136#93#166#145#146#239#92#215#88#28#159#139#87#108#117#230#190#173#91#205#153#135#227#61 + +#61#2#31#49#243#161#107#123#167#227#15#207#206#95#176#227#138#122#246#28#66#45#135#206#149#97#226#11#178#35 + +#251#74#27#210#143#118#15#28#59#248#204#105#31#200#15#232#189#170#32#103#173#89#115#109#189#227#252#109#11 + +#228#186#45#97#65#103#78#190#189#197#15#189#250#193#41#198#86#106#159#63#210#112#176#203#254#156#147#10#95#1 + +#128#228#104#186#72#214#27#229#0#0#0#0#73#69#78#68#174#66#96#130 +]); diff --git a/CORE/Source/Database_Drivers/Native/NativeLinks/SQLDB/uRESTDWNativeLinkSQLDB.pas b/CORE/Source/Database_Drivers/Native/NativeLinks/SQLDB/uRESTDWNativeLinkSQLDB.pas new file mode 100644 index 000000000..cb73bd20b --- /dev/null +++ b/CORE/Source/Database_Drivers/Native/NativeLinks/SQLDB/uRESTDWNativeLinkSQLDB.pas @@ -0,0 +1,589 @@ +Unit uRESTDWNativeLinkSQLDB; + +{$I uRESTDW.inc} + +Interface + +{$IFDEF FPC} + +Uses + {$IFDEF FPC} + LResources, +{$ENDIF} + Classes, SysUtils, DB, SQLDB, FMTBcd, + uRESTDWNativeDriver, uRESTDWDriverBase, uRESTDWParams, uRESTDWMemoryDataset; + +Type + TRESTDWNativeLinkSQLDB = Class(TRESTDWNativeLink) + Private + FConnection : TSQLConnection; + FTransaction : TSQLTransaction; + Procedure SetConnection(AValue : TSQLConnection); + Procedure SetTransaction(AValue : TSQLTransaction); + Protected + Procedure Notification(AComponent : TComponent; Operation : TOperation); Override; + Function GetConnection : TComponent; Override; + Public + Function GetQuery : TRESTDWDrvQuery; Override; + Function IsConnected : Boolean; Override; + Procedure Connect; Override; + Procedure Disconnect; Override; + Procedure ExecuteSelect(Const ASQL : String; AParams : TRESTDWParams; + AOutput : TStream; ACompress : Boolean); Overload; Override; + Procedure ExecuteSelect(Const ASQL : String; AParams : TRESTDWParams; + AOutput : TStream; ACompress : Boolean; + ABinaryCompatibleMode : Boolean); Overload; Override; + Function ExecuteCommand(Const ASQL : String; AParams : TRESTDWParams) : Int64; Override; + Published + Property Connection : TSQLConnection Read FConnection Write SetConnection; + Property Transaction : TSQLTransaction Read FTransaction Write SetTransaction; + End; + +Procedure Register; + +{$ENDIF} + +Implementation + +{$IFDEF FPC} + +Type + TRESTDWNativeSQLDBQuery = Class(TRESTDWDrvQuery) + Public + Procedure ExecSQL; Override; + Procedure Prepare; Override; + Function ParamCount : Integer; Override; + Function RowsAffected : Int64; Override; + Function getParamDataType(IParam : Integer) : TFieldType; Override; + Function getParamName(IParam : Integer) : String; Override; + Function getParamSize(IParam : Integer) : Integer; Override; + Function getParamValue(IParam : Integer) : Variant; Override; + Procedure setParamDataType(IParam : Integer; AValue : TFieldType); Override; + Procedure setParamValue(IParam : Integer; AValue : Variant); Override; + Procedure LoadFromStreamParam(IParam : Integer; Stream : TStream; BlobType : TBlobType); Override; + End; + + TSQLConnectionAccess = Class(TSQLConnection) + Public + Function NativeAllocateCursor : TSQLCursor; + Procedure NativeDeAllocateCursor(Var ACursor : TSQLCursor); + Procedure NativePrepare(ACursor : TSQLCursor; ATransaction : TSQLTransaction; + Const ASQL : String; AParams : TParams); + Procedure NativeExecute(ACursor : TSQLCursor; ATransaction : TSQLTransaction; + AParams : TParams); + Function NativeFetch(ACursor : TSQLCursor) : Boolean; + Procedure NativeAddFieldDefs(ACursor : TSQLCursor; AFieldDefs : TFieldDefs); + Function NativeLoadField(ACursor : TSQLCursor; AFieldDef : TFieldDef; + ABuffer : Pointer; Out ACreateBlob : Boolean) : Boolean; + Procedure NativeUnPrepare(ACursor : TSQLCursor); + Function NativeRowsAffected(ACursor : TSQLCursor) : Int64; + End; + +Function TSQLConnectionAccess.NativeAllocateCursor : TSQLCursor; +Begin + Result := AllocateCursorHandle; +End; + +Procedure TSQLConnectionAccess.NativeDeAllocateCursor(Var ACursor : TSQLCursor); +Begin + DeAllocateCursorHandle(ACursor); +End; + +Procedure TSQLConnectionAccess.NativePrepare(ACursor : TSQLCursor; + ATransaction : TSQLTransaction; + Const ASQL : String; AParams : TParams); +Begin + PrepareStatement(ACursor, ATransaction, ASQL, AParams); +End; + +Procedure TSQLConnectionAccess.NativeExecute(ACursor : TSQLCursor; + ATransaction : TSQLTransaction; + AParams : TParams); +Begin + Execute(ACursor, ATransaction, AParams); +End; + +Function TSQLConnectionAccess.NativeFetch(ACursor : TSQLCursor) : Boolean; +Begin + Result := Fetch(ACursor); +End; + +Procedure TSQLConnectionAccess.NativeAddFieldDefs(ACursor : TSQLCursor; + AFieldDefs : TFieldDefs); +Begin + AddFieldDefs(ACursor, AFieldDefs); +End; + +Function TSQLConnectionAccess.NativeLoadField(ACursor : TSQLCursor; + AFieldDef : TFieldDef; + ABuffer : Pointer; + Out ACreateBlob : Boolean) : Boolean; +Begin + Result := LoadField(ACursor, AFieldDef, ABuffer, ACreateBlob); +End; + +Procedure TSQLConnectionAccess.NativeUnPrepare(ACursor : TSQLCursor); +Begin + UnPrepareStatement(ACursor); +End; + +Function TSQLConnectionAccess.NativeRowsAffected(ACursor : TSQLCursor) : Int64; +Begin + Result := RowsAffected(ACursor); +End; + +Procedure StoreSQLDBValue(AWriter : TRESTDWBinaryPacketWriter; AFieldIndex : Integer; + AFieldDef : TFieldDef; ABuffer : Pointer); +Var + LSize : Integer; + VDateTime : TDateTime; + VWireValue : Integer; + VTimeStamp : TTimeStamp; +Begin + LSize := AFieldDef.Size; + Case AFieldDef.DataType Of + ftString, + ftFixedChar, + ftWideString, + ftFixedWideChar: + Begin + If LSize < 1 Then + Begin + LSize := 1; + End; + AWriter.StoreField(AFieldIndex, ABuffer, StrLen(PChar(ABuffer))); + End; + ftSmallint: AWriter.StoreField(AFieldIndex, ABuffer, SizeOf(SmallInt)); + ftInteger: AWriter.StoreField(AFieldIndex, ABuffer, SizeOf(Integer)); + ftAutoInc: AWriter.StoreField(AFieldIndex, ABuffer, SizeOf(Int64)); + ftWord: AWriter.StoreField(AFieldIndex, ABuffer, SizeOf(Word)); + ftLargeint: AWriter.StoreField(AFieldIndex, ABuffer, SizeOf(Int64)); + ftBoolean: AWriter.StoreField(AFieldIndex, ABuffer, SizeOf(WordBool)); + ftFloat: AWriter.StoreField(AFieldIndex, ABuffer, SizeOf(Double)); + ftCurrency, + ftBCD: AWriter.StoreField(AFieldIndex, ABuffer, SizeOf(Currency)); + ftFMTBcd: AWriter.StoreField(AFieldIndex, ABuffer, SizeOf(TBcd)); + ftDate: + Begin + Move(ABuffer^, VDateTime, SizeOf(VDateTime)); + VWireValue := Trunc(VDateTime) + 693594; + AWriter.StoreField(AFieldIndex, @VWireValue, SizeOf(VWireValue)); + End; + ftTime: + Begin + Move(ABuffer^, VDateTime, SizeOf(VDateTime)); + VTimeStamp := DateTimeToTimeStamp(VDateTime); + VWireValue := VTimeStamp.Time; + AWriter.StoreField(AFieldIndex, @VWireValue, SizeOf(VWireValue)); + End; + ftDateTime, + ftTimeStamp: + Begin + Move(ABuffer^, VDateTime, SizeOf(VDateTime)); + AWriter.StoreField(AFieldIndex, @VDateTime, SizeOf(VDateTime)); + End; + Else + Begin + AWriter.StoreField(AFieldIndex, ABuffer, LSize); + End; + End; +End; + +Procedure BindParams(AParams : TRESTDWParams; ADBParams : TParams); +Var + I : Integer; + P : TRESTDWJSONParam; +Begin + If (AParams = Nil) Or (ADBParams = Nil) Then + Begin + Exit; + End; + For I := 0 To AParams.Count - 1 Do + Begin + P := AParams[I]; + If P = Nil Then + Begin + Continue; + End; + If I < ADBParams.Count Then + Begin + ADBParams[I].Value := P.Value; + End; + End; +End; + +Procedure TRESTDWNativeSQLDBQuery.ExecSQL; +Begin + Inherited ExecSQL; + TSQLQuery(Self.Owner).ExecSQL; +End; + +Procedure TRESTDWNativeSQLDBQuery.Prepare; +Begin + Inherited Prepare; + TSQLQuery(Self.Owner).Prepare; +End; + +Function TRESTDWNativeSQLDBQuery.ParamCount : Integer; +Begin + Result:=TSQLQuery(Self.Owner).Params.Count; + If (Result=0) and (Pos(':',SQL.Text)>0) Then + Begin + Prepare; + Result:=TSQLQuery(Self.Owner).Params.Count; + End; +End; + +Function TRESTDWNativeSQLDBQuery.RowsAffected : Int64; +Begin + Result:=TSQLQuery(Self.Owner).RowsAffected; +End; + +Function TRESTDWNativeSQLDBQuery.getParamDataType(IParam : Integer) : TFieldType; +Begin + Result:=TSQLQuery(Self.Owner).Params[IParam].DataType; +End; + +Function TRESTDWNativeSQLDBQuery.getParamName(IParam : Integer) : String; +Begin + Result:=TSQLQuery(Self.Owner).Params[IParam].Name; +End; + +Function TRESTDWNativeSQLDBQuery.getParamSize(IParam : Integer) : Integer; +Begin + Result:=TSQLQuery(Self.Owner).Params[IParam].Size; +End; + +Function TRESTDWNativeSQLDBQuery.getParamValue(IParam : Integer) : Variant; +Begin + Result:=TSQLQuery(Self.Owner).Params[IParam].Value; +End; + +Procedure TRESTDWNativeSQLDBQuery.setParamDataType(IParam : Integer; AValue : TFieldType); +Begin + TSQLQuery(Self.Owner).Params[IParam].DataType:=AValue; +End; + +Procedure TRESTDWNativeSQLDBQuery.setParamValue(IParam : Integer; AValue : Variant); +Begin + TSQLQuery(Self.Owner).Params[IParam].Value:=AValue; +End; + +Procedure TRESTDWNativeSQLDBQuery.LoadFromStreamParam(IParam : Integer; Stream : TStream; + BlobType : TBlobType); +Begin + TSQLQuery(Self.Owner).Params[IParam].LoadFromStream(Stream,BlobType); +End; + +Function TRESTDWNativeLinkSQLDB.GetConnection : TComponent; +Begin + Result := FConnection; +End; + +Function TRESTDWNativeLinkSQLDB.GetQuery : TRESTDWDrvQuery; +Var + Query : TSQLQuery; + LTransaction : TSQLTransaction; +Begin + Result := Nil; + If FConnection = Nil Then + Exit; + LTransaction := FTransaction; + If LTransaction = Nil Then + Begin + LTransaction := FConnection.Transaction; + End; + Query := TSQLQuery.Create(Self); + Query.SQLConnection := FConnection; + Query.Transaction := LTransaction; + Result := TRESTDWNativeSQLDBQuery.Create(Query); +End; + +Procedure TRESTDWNativeLinkSQLDB.SetConnection(AValue : TSQLConnection); +Begin + If FConnection = AValue Then + Begin + Exit; + End; + If FConnection <> Nil Then + Begin + FConnection.RemoveFreeNotification(Self); + End; + FConnection := AValue; + If FConnection <> Nil Then + Begin + FConnection.FreeNotification(Self); + End; +End; + +Procedure TRESTDWNativeLinkSQLDB.SetTransaction(AValue : TSQLTransaction); +Begin + If FTransaction = AValue Then + Begin + Exit; + End; + If FTransaction <> Nil Then + Begin + FTransaction.RemoveFreeNotification(Self); + End; + FTransaction := AValue; + If FTransaction <> Nil Then + Begin + FTransaction.FreeNotification(Self); + End; +End; + +Procedure TRESTDWNativeLinkSQLDB.Notification(AComponent : TComponent; + Operation : TOperation); +Begin + Inherited Notification(AComponent, Operation); + If Operation = opRemove Then + Begin + If AComponent = FConnection Then + Begin + FConnection := Nil; + End; + If AComponent = FTransaction Then + Begin + FTransaction := Nil; + End; + End; +End; + +Function TRESTDWNativeLinkSQLDB.IsConnected : Boolean; +Begin + Result := (FConnection <> Nil) And FConnection.Connected; +End; + +Procedure TRESTDWNativeLinkSQLDB.Connect; +Begin + If FConnection = Nil Then + Begin + DatabaseError('SQLDB Connection not assigned'); + End; + If Not FConnection.Connected Then + Begin + FConnection.Connected := True; + End; +End; + +Procedure TRESTDWNativeLinkSQLDB.Disconnect; +Begin +End; + +Procedure TRESTDWNativeLinkSQLDB.ExecuteSelect(Const ASQL : String; + AParams : TRESTDWParams; + AOutput : TStream; + ACompress : Boolean; + ABinaryCompatibleMode : Boolean); +Var + Query : TSQLQuery; + LTransaction : TSQLTransaction; +Begin + If ABinaryCompatibleMode Then + Begin + ExecuteSelect(ASQL, AParams, AOutput, ACompress); + Exit; + End; + If FConnection = Nil Then + Begin + DatabaseError('SQLDB Connection not assigned'); + End; + LTransaction := FTransaction; + If LTransaction = Nil Then + Begin + LTransaction := FConnection.Transaction; + End; + If LTransaction = Nil Then + Begin + DatabaseError('SQLDB Transaction not assigned'); + End; + If LTransaction.Database <> FConnection Then + Begin + LTransaction.Database := FConnection; + End; + If Not FConnection.Connected Then + Begin + FConnection.Connected := True; + End; + If Not LTransaction.Active Then + Begin + LTransaction.StartTransaction; + End; + Query := TSQLQuery.Create(Nil); + Try + Query.Database := FConnection; + Query.Transaction := LTransaction; + Query.SQL.Text := ASQL; + BindParams(AParams, Query.Params); + Query.Open; + AOutput.Position := 0; + AOutput.Size := 0; + Query.SaveToStream(AOutput); + AOutput.Position := 0; + Finally + Query.Free; + End; +End; + +Procedure TRESTDWNativeLinkSQLDB.ExecuteSelect(Const ASQL : String; + AParams : TRESTDWParams; + AOutput : TStream; + ACompress : Boolean); +Var + C : TSQLConnectionAccess; + Cursor : TSQLCursor; + Params : TParams; + FieldDefs : TFieldDefs; + Writer : TRESTDWBinaryPacketWriter; + I : Integer; + Buffer : Pointer; + BufferSize : Integer; + CreateBlob : Boolean; + LTransaction : TSQLTransaction; +Begin + If FConnection = Nil Then + Begin + DatabaseError('SQLDB Connection not assigned'); + End; + LTransaction := FTransaction; + If LTransaction = Nil Then + Begin + LTransaction := FConnection.Transaction; + End; + If LTransaction = Nil Then + Begin + DatabaseError('SQLDB Transaction not assigned'); + End; + If Not FConnection.Connected Then + Begin + FConnection.Connected := True; + End; + If Not LTransaction.Active Then + Begin + LTransaction.StartTransaction; + End; + C := TSQLConnectionAccess(FConnection); + Cursor := C.NativeAllocateCursor; + Params := TParams.Create(Nil); + FieldDefs := TFieldDefs.Create(Nil); + AOutput.Position := 0; + AOutput.Size := 0; + Writer := TRESTDWBinaryPacketWriter.Create(AOutput); +{$IFDEF RESTDWLAZARUS} + Writer.DatabaseCharSet := DatabaseCharSet; +{$ENDIF} + Try + C.NativePrepare(Cursor, LTransaction, ASQL, Params); + BindParams(AParams, Params); + C.NativeExecute(Cursor, LTransaction, Params); + C.NativeAddFieldDefs(Cursor, FieldDefs); + Writer.ClearFieldDefs; + For I := 0 To FieldDefs.Count - 1 Do + Begin + Writer.AddFieldDef(FieldDefs[I].Name, FieldDefs[I].DisplayName, + FieldDefs[I].Size, FieldDefs[I].DataType, + False); + End; + Writer.StoreFieldDefs(1); + While C.NativeFetch(Cursor) Do + Begin + Writer.BeginRecord; + For I := 0 To FieldDefs.Count - 1 Do + Begin + BufferSize := FieldDefs[I].Size; + If BufferSize < 32 Then + Begin + BufferSize := 32; + End; + If FieldDefs[I].DataType In ftBlobTypes Then + Begin + BufferSize := SizeOf(Pointer) * 4; + End; + GetMem(Buffer, BufferSize + 8); + Try + FillChar(Buffer^, BufferSize + 8, 0); + CreateBlob := False; + If C.NativeLoadField(Cursor, FieldDefs[I], Buffer, CreateBlob) Then + Begin + StoreSQLDBValue(Writer, I, FieldDefs[I], Buffer) + End + Else + Begin + Writer.StoreNull(I); + End; + Finally + FreeMem(Buffer); + End; + End; + Writer.EndRecord; + End; + Finally + Writer.Free; + FieldDefs.Free; + Params.Free; + C.NativeUnPrepare(Cursor); + C.NativeDeAllocateCursor(Cursor); + End; + AOutput.Position := 0; +End; + +Function TRESTDWNativeLinkSQLDB.ExecuteCommand(Const ASQL : String; + AParams : TRESTDWParams) : Int64; +Var + C : TSQLConnectionAccess; + Cursor : TSQLCursor; + Params : TParams; + LTransaction : TSQLTransaction; +Begin + If FConnection = Nil Then + Begin + DatabaseError('SQLDB Connection not assigned'); + End; + LTransaction := FTransaction; + If LTransaction = Nil Then + Begin + LTransaction := FConnection.Transaction; + End; + If LTransaction = Nil Then + Begin + DatabaseError('SQLDB Transaction not assigned'); + End; + If Not FConnection.Connected Then + Begin + FConnection.Connected := True; + End; + If Not LTransaction.Active Then + Begin + LTransaction.StartTransaction; + End; + C := TSQLConnectionAccess(FConnection); + Cursor := C.NativeAllocateCursor; + Params := TParams.Create(Nil); + Try + C.NativePrepare(Cursor, LTransaction, ASQL, Params); + BindParams(AParams, Params); + C.NativeExecute(Cursor, LTransaction, Params); + Result := C.NativeRowsAffected(Cursor); + Finally + Params.Free; + C.NativeUnPrepare(Cursor); + C.NativeDeAllocateCursor(Cursor); + End; +End; + +Procedure Register; +Begin + RegisterComponents('REST Dataware - Drivers', [TRESTDWNativeLinkSQLDB]); +End; + +{$ENDIF} + +Initialization +{$IFDEF FPC} + {$I uRESTDWNativeLinkSQLDB.lrs} +{$ENDIF} +{$IFDEF FPC} + +{$ENDIF} +End. diff --git a/CORE/Source/Database_Drivers/Native/NativeLinks/Zeos/uRESTDWNativeLinkZeos.lrs b/CORE/Source/Database_Drivers/Native/NativeLinks/Zeos/uRESTDWNativeLinkZeos.lrs new file mode 100644 index 000000000..7b05cfa96 --- /dev/null +++ b/CORE/Source/Database_Drivers/Native/NativeLinks/Zeos/uRESTDWNativeLinkZeos.lrs @@ -0,0 +1,43 @@ +LazarusResources.Add('TRESTDWNativeLinkZeos','PNG',[ + #137#80#78#71#13#10#26#10#0#0#0#13#73#72#68#82#0#0#0#24#0#0#0#24#8#6#0#0#0#224#119#61#248#0#0#4#185#73#68#65 + +#84#120#218#213#86#91#108#84#85#20#93#231#220#59#119#230#118#58#157#86#160#20#43#143#64#169#64#140#69#65#1#13 + +#143#166#8#70#80#129#216#24#8#1#68#129#24#197#4#127#244#3#173#141#38#198#68#124#166#196#248#8#34#26#9#81#212 + +#10#38#96#195#180#42#248#8#86#160#118#40#148#87#153#150#182#51#204#76#167#119#94#247#113#206#246#131#162#165 + +#45#40#126#152#184#191#78#114#178#215#58#123#237#189#118#14#240#127#15#54#240#60#115#102#165#39#20#250#245 + +#197#188#60#239#205#92#85#109#0#140#132#5#1#128#65#1#73#1#33#4#56#49#130#226#210#140#180#209#88#224#211#95#10 + +#6#131#54#0#186#22#129#10#192#225#46#215#138#69#171#30#255#100#250#202#13#56#23#142#129#43#12#144#18#156#113 + +#128#1#25#75#192#113#28#48#14#196#146#12#245#111#111#129#211#188#119#177#0#246#2#80#0#8#12#0#189#34#164#109 + +#235#169#177#83#172#15#181#41#86#200#188#224#114#67#130#75#135#171#32#46#210#73#120#221#26#28#41#97#146#131 + +#222#31#142#218#60#210#229#241#231#229#137#120#111#239#144#18#13#34#40#44#24#158#110#220#253#169#150#62#112 + +#88#35#91#194#34#2#99#4#35#28#198#202#213#75#209#56#122#6#206#199#146#176#126#63#227#40#223#190#227#209#227 + +#199#106#118#239#183#234#202#203#25#31#248#250#33#229#170#220#180#69#247#231#228#174#243#1#155#10#60#218#211 + +#99#134#223#240#40#128#189#75#23#63#64#235#15#180#9#229#149#131#164#172#221#238#160#120#1#229#234#121#129#109 + +#219#2#158#190#92#246#111#7#161#228#174#153#179#78#111#220#215#42#240#218#17#169#108#252#76#176#241#15#146 + +#158#147#31#156#54#127#154#191#79#119#229#122#65#93#187#118#85#42#0#10#75#199#79#104#219#252#229#79#148#187 + +#181#89#40#207#5#36#110#219#64#174#156#194#246#59#42#42#74#175#200#32#98#67#17#13#85#22#171#170#170#98#59#67 + +#105#175#241#245#142#186#71#94#223#118#231#71#86#137#232#234#142#43#84#95#39#189#77#59#37#162#39#238#73#152 + +#102#203#104#96#162#23#112#82#64#91#8#184#208#15#147#174#70#112#249#21#142#91#85#183#111#218#242#222#170#218 + +#220#25#78#176#237#130#234#110#106#132#185#231#13#148#77#240#59#165#21#75#206#167#135#21#221#152#213#11#60#41 + +#211#68#52#212#150#200#156#104#110#212#154#191#127#245#76#252#226#55#3#73#6#77#149#2#246#230#198#103#171#105 + +#206#206#86#11#155#235#200#189#162#134#80#48#133#138#70#142#164#149#239#239#161#249#205#68#101#71#137#70#255 + +#76#82#15#144#116#239#35#242#215#10#242#173#173#161#73#69#227#230#94#130#170#84#0#128#247#3#231#0#28#0#107 + +#151#175#123#242#169#246#89#107#156#239#78#68#84#181#179#29#230#231#53#184#125#98#62#202#238#91#133#201#75#22 + +#65#101#66#42#166#77#110#75#48#159#116#24#119#76#50#36#55#83#249#179#17#138#165#167#94#130#11#179#254#62#80#0 + +#8#5#120#104#193#253#203#62#72#45#124#66#124#113#48#168#168#76#50#189#53#128#226#178#2#120#135#13#195#169#174 + +#40#166#165#37#38#101#4#159#204#25#98#210#70#135#97#227#200#41#139#153#205#29#10#90#142#195#241#112#11#214#0 + +#73#170#170#2#172#186#186#28#139#86#175#159#225#127#248#25#218#113#172#71#168#94#55#23#233#36#185#238#93#3 + +#215#136#17#232#78#102#144#221#255#49#251#37#236#160#174#85#3#143#2#212#9#80#212#0#122#18#64#79#20#76#26#128 + +#157#237#235#107#195#95#4#245#243#230#1#213#192#241#233#143#181#158#10#132#24#226#29#46#135#49#6#43#139#88 + +#168#19#49#126#26#48#12#140#53#123#48#182#183#7#197#189#18#137#184#138#76#70#1#100#18#112#39#33#139#189#96 + +#182#11#66#14#209#212#134#114#70#0#112#254#249#101#227#220#170#63#43#1#147#49#166#50#16#152#194#193#20#78#148 + +#138#187#148#91#166#186#99#250#112#76#189#41#1#89#104#35#98#17#218#83#62#68#194#62#80#183#3#166#251#160#112#5 + +#14#0#96#46#128#134#63#123#32#0#96#225#236#49#47#119#157#109#219#234#214#76#33#164#206#114#244#28#72#143#135 + +#121#132#38#50#158#201#254#56#244#250#18#31#138#14#117#104#20#238#85#89#172#71#194#12#71#225#49#82#32#197#11 + +#147#8#144#105#26#36#209#229#168#173#61#100#0#48#174#226#238#174#73#21#203#146#29#26#151#6#87#81#232#177#153 + +#166#73#196#117#55#18#105#14#179#27#82#198#37#145#150#175#193#204#12#170#160#191#209#6#154#132#161#170#10#149 + +#193#160#250#99#203#57#118#248#108#154#159#204#230#216#104#119#73#196#211#12#17#133#96#72#192#182#53#87#166#9 + +#121#110#251#183#139#6#0#52#16#174#99#3#114#34#162#137#163#70#205#57#55#166#252#45#126#247#154#91#201#83#10 + +#39#171#130#197#34#96#157#39#193#218#246#119#122#187#106#95#72#36#46#190#219#231#41#137#235#92#177#12#0#5#0 + +#117#121#110#238#210#164#191#180#36#175#104#252#116#35#30#105#65#164#233#116#177#17#251#170#5#136#94#107#77 + +#252#163#74#254#230#94#249#207#127#21#127#0#141#98#48#122#246#84#87#213#0#0#0#0#73#69#78#68#174#66#96#130 +]); diff --git a/CORE/Source/Database_Drivers/Native/NativeLinks/Zeos/uRESTDWNativeLinkZeos.pas b/CORE/Source/Database_Drivers/Native/NativeLinks/Zeos/uRESTDWNativeLinkZeos.pas new file mode 100644 index 000000000..c9b6f6d9e --- /dev/null +++ b/CORE/Source/Database_Drivers/Native/NativeLinks/Zeos/uRESTDWNativeLinkZeos.pas @@ -0,0 +1,515 @@ +Unit uRESTDWNativeLinkZeos; + +{$I uRESTDW.inc} + +Interface + +Uses + {$IFDEF FPC} + LResources, +{$ENDIF} + Classes, SysUtils, Variants, DB, FMTBcd, ZConnection, ZAbstractConnection, ZDbcIntfs, + ZCompatibility, ZSysUtils, ZDataset, ZMemTable, + uRESTDWNativeDriver, uRESTDWDriverBase, uRESTDWParams, uRESTDWMemoryDataset; + +Type + TRESTDWNativeLinkZeos = Class(TRESTDWNativeLink) + Private + FConnection : TZConnection; + Procedure SetConnection(AValue : TZConnection); + Protected + Procedure Notification(AComponent : TComponent; Operation : TOperation); Override; + Function GetConnection : TComponent; Override; + Public + Function GetQuery : TRESTDWDrvQuery; Override; + Function IsConnected : Boolean; Override; + Procedure Connect; Override; + Procedure Disconnect; Override; + Procedure ExecuteSelect(Const ASQL : String; AParams : TRESTDWParams; + AOutput : TStream; ACompress : Boolean); Overload; Override; + Procedure ExecuteSelect(Const ASQL : String; AParams : TRESTDWParams; + AOutput : TStream; ACompress : Boolean; + ABinaryCompatibleMode : Boolean); Overload; Override; + Function ExecuteCommand(Const ASQL : String; AParams : TRESTDWParams) : Int64; Override; + Published + Property Connection : TZConnection Read FConnection Write SetConnection; + End; + +Procedure Register; + +Implementation + +Type + TRESTDWNativeZeosQuery = Class(TRESTDWDrvQuery) + Public + Procedure ExecSQL; Override; + Procedure Prepare; Override; + Function ParamCount : Integer; Override; + Function RowsAffected : Int64; Override; + Function getParamDataType(IParam : Integer) : TFieldType; Override; + Function getParamName(IParam : Integer) : String; Override; + Function getParamSize(IParam : Integer) : Integer; Override; + Function getParamValue(IParam : Integer) : Variant; Override; + Procedure setParamDataType(IParam : Integer; AValue : TFieldType); Override; + Procedure setParamValue(IParam : Integer; AValue : Variant); Override; + Procedure LoadFromStreamParam(IParam : Integer; Stream : TStream; BlobType : TBlobType); Override; + End; + + TDirectField = Record + Name : String; + DisplayName : String; + Size : Word; + DataType : TFieldType; + ZType : TZSQLType; + ReadOnly : Boolean; + End; + + TDirectFields = Array Of TDirectField; + +Function MapDataType(AType : TZSQLType) : TFieldType; +Begin + Case AType Of + stBoolean: Result := ftBoolean; + stByte, + stShort, + stSmall: Result := ftSmallint; + stWord: Result := ftWord; + stLongWord, + stInteger: Result := ftInteger; + stULong, + stLong: Result := ftLargeint; + stFloat, + stDouble: Result := ftFloat; + stCurrency: Result := ftBCD; + stBigDecimal: Result := ftFMTBcd; + stDate: Result := ftDate; + stTime: Result := ftTime; + stTimestamp: Result := ftDateTime; + stGUID: Result := ftGuid; + stString: Result := ftString; + stUnicodeString: Result := ftWideString; + stBytes: Result := ftVarBytes; + stAsciiStream: Result := ftMemo; + stUnicodeStream: Result := ftWideMemo; + stBinaryStream: Result := ftBlob; + Else + Result := ftUnknown; + End; +End; + +Procedure StoreValue(AWriter : TRESTDWBinaryPacketWriter; AResultSet : IZResultSet; + AFieldIndex, AColumnIndex : Integer; AType : TZSQLType); +Var + S : AnsiString; + WS : WideString; + B : TBytes; + VBool : WordBool; + VSmall : SmallInt; + VWord : Word; + VInt : Integer; + VInt64 : Int64; + VDouble : Double; + VCurrency : Currency; + VBcd : TBcd; + VDateTime : TDateTime; +{$IFDEF ZEOS80UP} + VZTimeStamp : TZTimeStamp; +{$ENDIF} + VGuid : TGUID; + P : Pointer; + L : Integer; +Begin + If AResultSet.IsNull(AColumnIndex) Then + Begin + AWriter.StoreNull(AFieldIndex); + Exit; + End; + Case AType Of + stBoolean: + Begin + VBool := AResultSet.GetBoolean(AColumnIndex); + AWriter.StoreField(AFieldIndex, @VBool, SizeOf(VBool)); + End; + stByte, + stShort, + stSmall: + Begin + VSmall := AResultSet.GetInt(AColumnIndex); + AWriter.StoreField(AFieldIndex, @VSmall, SizeOf(VSmall)); + End; + stWord: + Begin + VWord := AResultSet.GetInt(AColumnIndex); + AWriter.StoreField(AFieldIndex, @VWord, SizeOf(VWord)); + End; + stLongWord, + stInteger: + Begin + VInt := AResultSet.GetInt(AColumnIndex); + AWriter.StoreField(AFieldIndex, @VInt, SizeOf(VInt)); + End; + stULong, + stLong: + Begin + VInt64 := AResultSet.GetLong(AColumnIndex); + AWriter.StoreField(AFieldIndex, @VInt64, SizeOf(VInt64)); + End; + stFloat, + stDouble: + Begin + VDouble := AResultSet.GetDouble(AColumnIndex); + AWriter.StoreField(AFieldIndex, @VDouble, SizeOf(VDouble)); + End; + stCurrency: + Begin + VCurrency := AResultSet.GetDouble(AColumnIndex); + AWriter.StoreField(AFieldIndex, @VCurrency, SizeOf(VCurrency)); + End; + stBigDecimal: + Begin + FillChar(VBcd, SizeOf(VBcd), 0); + AResultSet.GetBigDecimal(AColumnIndex, VBcd); + AWriter.StoreField(AFieldIndex, @VBcd, SizeOf(VBcd)); + End; + stDate: + Begin + VDateTime := AResultSet.GetDate(AColumnIndex); + VInt := DateTimeToTimeStamp(VDateTime).Date; + AWriter.StoreField(AFieldIndex, @VInt, SizeOf(VInt)); + End; + stTime: + Begin + VDateTime := AResultSet.GetTime(AColumnIndex); + VInt := DateTimeToTimeStamp(VDateTime).Time; + AWriter.StoreField(AFieldIndex, @VInt, SizeOf(VInt)); + End; + stTimestamp: + Begin +{$IFDEF ZEOS80UP} + FillChar(VZTimeStamp, SizeOf(VZTimeStamp), 0); + AResultSet.GetTimestamp(AColumnIndex, VZTimeStamp); + If Not TryTimeStampToDateTime(VZTimeStamp, VDateTime) Then + DatabaseError('Invalid Zeos timestamp value'); +{$ELSE} + VDateTime := AResultSet.GetTimestamp(AColumnIndex); +{$ENDIF} + AWriter.StoreField(AFieldIndex, @VDateTime, SizeOf(VDateTime)); + End; + stGUID: + Begin + FillChar(VGuid, SizeOf(VGuid), 0); + S := AnsiString(AResultSet.GetString(AColumnIndex)); + If Length(S) > 0 Then + VGuid := StringToGUID(String(S)); + AWriter.StoreField(AFieldIndex, @VGuid, SizeOf(VGuid)); + End; + stString: + Begin + S := AResultSet.GetRawByteString(AColumnIndex); + If Length(S) = 0 Then + P := Nil + Else + P := @S[1]; + AWriter.StoreField(AFieldIndex, P, Length(S)); + End; + stUnicodeString: + Begin + WS := AResultSet.GetUnicodeString(AColumnIndex); + S := AnsiString(String(WS)); + If Length(S) = 0 Then + P := Nil + Else + P := @S[1]; + AWriter.StoreField(AFieldIndex, P, Length(S)); + End; + stBytes, + stAsciiStream, + stUnicodeStream, + stBinaryStream: + Begin + B := AResultSet.GetBytes(AColumnIndex); + L := Length(B); + If L = 0 Then + P := Nil + Else + P := @B[0]; + AWriter.StoreField(AFieldIndex, P, L); + End; + Else + DatabaseError('Zeos data type is not representable by the RESTDW DataSet binary contract: ' + + IntToStr(Ord(AType))); + End; +End; + +Procedure BindParams(AStatement : IZPreparedStatement; AParams : TRESTDWParams); +Var + I : Integer; + P : TRESTDWJSONParam; +Begin + If (AStatement = Nil) Or (AParams = Nil) Then + Exit; + For I := 0 To AParams.Count - 1 Do + Begin + P := AParams[I]; + If P = Nil Then + Continue; + If VarIsNull(P.Value) Or VarIsEmpty(P.Value) Then + AStatement.SetNull(I + FirstDbcIndex, stString) + Else + AStatement.SetString(I + FirstDbcIndex, VarToStr(P.Value)); + End; +End; + +Procedure TRESTDWNativeZeosQuery.ExecSQL; +Begin + Inherited ExecSQL; + TZQuery(Self.Owner).ExecSQL; +End; + +Procedure TRESTDWNativeZeosQuery.Prepare; +Begin + Inherited Prepare; + TZQuery(Self.Owner).Prepare; +End; + +Function TRESTDWNativeZeosQuery.ParamCount : Integer; +Begin + Result:=TZQuery(Self.Owner).Params.Count; + If (Result=0) and (Pos(':',SQL.Text)>0) Then + Begin + Prepare; + Result:=TZQuery(Self.Owner).Params.Count; + End; +End; + +Function TRESTDWNativeZeosQuery.RowsAffected : Int64; +Begin + Result:=TZQuery(Self.Owner).RowsAffected; +End; + +Function TRESTDWNativeZeosQuery.getParamDataType(IParam : Integer) : TFieldType; +Begin + Result:=TZQuery(Self.Owner).Params[IParam].DataType; +End; + +Function TRESTDWNativeZeosQuery.getParamName(IParam : Integer) : String; +Begin + Result:=TZQuery(Self.Owner).Params[IParam].Name; +End; + +Function TRESTDWNativeZeosQuery.getParamSize(IParam : Integer) : Integer; +Begin + Result:=TZQuery(Self.Owner).Params[IParam].Size; +End; + +Function TRESTDWNativeZeosQuery.getParamValue(IParam : Integer) : Variant; +Begin + Result:=TZQuery(Self.Owner).Params[IParam].Value; +End; + +Procedure TRESTDWNativeZeosQuery.setParamDataType(IParam : Integer; AValue : TFieldType); +Begin + TZQuery(Self.Owner).Params[IParam].DataType:=AValue; +End; + +Procedure TRESTDWNativeZeosQuery.setParamValue(IParam : Integer; AValue : Variant); +Begin + TZQuery(Self.Owner).Params[IParam].Value:=AValue; +End; + +Procedure TRESTDWNativeZeosQuery.LoadFromStreamParam(IParam : Integer; Stream : TStream; + BlobType : TBlobType); +Begin + TZQuery(Self.Owner).Params[IParam].LoadFromStream(Stream,BlobType); +End; + +Function TRESTDWNativeLinkZeos.GetConnection : TComponent; +Begin + Result := FConnection; +End; + +Function TRESTDWNativeLinkZeos.GetQuery : TRESTDWDrvQuery; +Var + Query : TZQuery; +Begin + Result := Nil; + If FConnection = Nil Then + Exit; + Query := TZQuery.Create(Self); + Query.Connection := FConnection; + Result := TRESTDWNativeZeosQuery.Create(Query); +End; + +Procedure TRESTDWNativeLinkZeos.SetConnection(AValue : TZConnection); +Begin + If FConnection = AValue Then + Exit; + If FConnection <> Nil Then + FConnection.RemoveFreeNotification(Self); + FConnection := AValue; + If FConnection <> Nil Then + FConnection.FreeNotification(Self); +End; + +Procedure TRESTDWNativeLinkZeos.Notification(AComponent : TComponent; Operation : TOperation); +Begin + Inherited Notification(AComponent, Operation); + If (Operation = opRemove) And (AComponent = FConnection) Then + FConnection := Nil; +End; + +Function TRESTDWNativeLinkZeos.IsConnected : Boolean; +Begin + Result := (FConnection <> Nil) And FConnection.Connected; +End; + +Procedure TRESTDWNativeLinkZeos.Connect; +Begin + If FConnection = Nil Then + DatabaseError('Zeos Connection not assigned'); + If Not FConnection.Connected Then + FConnection.Connected := True; +End; + +Procedure TRESTDWNativeLinkZeos.Disconnect; +Begin + If (FConnection <> Nil) And FConnection.Connected Then + FConnection.Connected := False; +End; + +Procedure TRESTDWNativeLinkZeos.ExecuteSelect(Const ASQL : String; AParams : TRESTDWParams; + AOutput : TStream; ACompress : Boolean; + ABinaryCompatibleMode : Boolean); +Var + Query : TZQuery; + MemTable : TZMemTable; + I : Integer; +Begin + If ABinaryCompatibleMode Then + Begin + ExecuteSelect(ASQL, AParams, AOutput, ACompress); + Exit; + End; + If FConnection = Nil Then + DatabaseError('Zeos Connection not assigned'); + If Not FConnection.Connected Then + FConnection.Connect; + Query := TZQuery.Create(Nil); + MemTable := TZMemTable.Create(Nil); + Try + Query.Connection := FConnection; + Query.SQL.Text := ASQL; + If AParams <> Nil Then + Begin + For I := 0 To AParams.Count - 1 Do + Begin + If Query.Params.FindParam(AParams[I].ParamName) <> Nil Then + Query.Params.ParamByName(AParams[I].ParamName).Value := AParams[I].Value; + End; + End; + Query.Open; + MemTable.AssignDataFrom(Query); + AOutput.Position := 0; + AOutput.Size := 0; + MemTable.SaveToStream(AOutput); + AOutput.Position := 0; + Finally + MemTable.Free; + Query.Free; + End; +End; + +Procedure TRESTDWNativeLinkZeos.ExecuteSelect(Const ASQL : String; AParams : TRESTDWParams; + AOutput : TStream; ACompress : Boolean); +Var + Statement : IZPreparedStatement; + ResultSet : IZResultSet; + Metadata : IZResultSetMetadata; + Writer : TRESTDWBinaryPacketWriter; + Fields : TDirectFields; + I : Integer; + C : Integer; + LSize : Integer; + LWordSize : Word; + LType : TFieldType; +Begin + If FConnection = Nil Then + DatabaseError('Zeos Connection not assigned'); + If Not FConnection.Connected Then + FConnection.Connected := True; + Statement := FConnection.DbcConnection.PrepareStatement(ASQL); + BindParams(Statement, AParams); + ResultSet := Statement.ExecuteQueryPrepared; + Metadata := ResultSet.GetMetadata; + C := ResultSet.GetColumnCount; + SetLength(Fields, C); + Writer := TRESTDWBinaryPacketWriter.Create(AOutput); +{$IFDEF RESTDWLAZARUS} + Writer.DatabaseCharSet := DatabaseCharSet; +{$ENDIF} + Try + Writer.ClearFieldDefs; + For I := 0 To C - 1 Do + Begin + Fields[I].Name := Metadata.GetColumnName(I + FirstDbcIndex); + Fields[I].DisplayName := Metadata.GetColumnLabel(I + FirstDbcIndex); + Fields[I].ZType := Metadata.GetColumnType(I + FirstDbcIndex); + Fields[I].DataType := MapDataType(Fields[I].ZType); + Fields[I].ReadOnly := Metadata.IsReadOnly(I + FirstDbcIndex); + If Fields[I].DataType = ftUnknown Then + DatabaseError('Zeos data type is not representable by the RESTDW DataSet binary contract: ' + + IntToStr(Ord(Fields[I].ZType))); + If Fields[I].ZType In [stCurrency, stBigDecimal] Then + LSize := Metadata.GetScale(I + FirstDbcIndex) + Else + LSize := Metadata.GetPrecision(I + FirstDbcIndex); + If LSize < 0 Then + LSize := -LSize; + If LSize > High(Word) Then + LWordSize := High(Word) + Else + LWordSize := Word(LSize); + Fields[I].Size := LWordSize; + Writer.AddFieldDef(Fields[I].Name, Fields[I].DisplayName, Fields[I].Size, + Fields[I].DataType, Fields[I].ReadOnly); + End; + Writer.StoreFieldDefs(0); + While ResultSet.Next Do + Begin + Writer.BeginRecord; + For I := 0 To C - 1 Do + StoreValue(Writer, ResultSet, I, I + FirstDbcIndex, Fields[I].ZType); + Writer.EndRecord; + End; + Finally + Writer.Free; + ResultSet := Nil; + Statement := Nil; + End; +End; + +Function TRESTDWNativeLinkZeos.ExecuteCommand(Const ASQL : String; AParams : TRESTDWParams) : Int64; +Var + Statement : IZPreparedStatement; +Begin + If FConnection = Nil Then + DatabaseError('Zeos Connection not assigned'); + If Not FConnection.Connected Then + FConnection.Connected := True; + Statement := FConnection.DbcConnection.PrepareStatement(ASQL); + BindParams(Statement, AParams); + Result := Statement.ExecuteUpdatePrepared; + Statement := Nil; +End; + +Procedure Register; +Begin + RegisterComponents('REST Dataware - Drivers', [TRESTDWNativeLinkZeos]); +End; + +Initialization +{$IFDEF FPC} + {$I uRESTDWNativeLinkZeos.lrs} +{$ENDIF} + +End. diff --git a/CORE/Source/Database_Drivers/SQLDBPhysLink/uRESTDWSQLDBPhysLink.pas b/CORE/Source/Database_Drivers/SQLDBPhysLink/uRESTDWSQLDBPhysLink.pas new file mode 100644 index 000000000..d6e583908 --- /dev/null +++ b/CORE/Source/Database_Drivers/SQLDBPhysLink/uRESTDWSQLDBPhysLink.pas @@ -0,0 +1,404 @@ +Unit uRESTDWSQLDBPhysLink; + +{$I uRESTDW.inc} + +Interface + +{$IFDEF FPC} + +{$MODE DELPHI} +{$H+} + +Uses + LResources, Classes, SysUtils, DB, SQLDB, uRESTDWAbout, uRESTDWBasicDB, uRESTDWConsts, + uRESTDWSQLDBConnection; + +Type + TRESTDWSQLDBQueryBinding = Class + Public + Query : TSQLQuery; + Database : TDatabase; + Transaction : TDBTransaction; + BeforeOpen : TDataSetNotifyEvent; + End; + + TRESTDWSQLDBPhysLink = Class(TRESTDWComponent) + Private + FSQLConnection : TSQLConnection; + FDatabase : TRESTDWDatabasebaseBase; + FRESTConnection : TRESTDWSQLDBConnection; + FRESTTransaction : TSQLTransaction; + FBindings : TList; + Procedure SetSQLConnection(Const Value : TSQLConnection); + Procedure SetDatabase(Const Value : TRESTDWDatabasebaseBase); + Procedure BindSQLDBDataSets; + Procedure RestoreSQLDBDataSets; + Procedure BindQuery(AQuery : TSQLQuery); + Function FindBinding(AQuery : TSQLQuery) : TRESTDWSQLDBQueryBinding; + Procedure RESTDWQueryBeforeOpen(DataSet : TDataSet); + Function GetConnected : Boolean; + Protected + Procedure Notification(AComponent : TComponent; Operation : TOperation); Override; + Procedure Loaded; Override; + Public + Constructor Create(AOwner : TComponent); Override; + Destructor Destroy; Override; + Function RESTDWConnect : Boolean; + Procedure RESTDWDisconnect; + Property Connected : Boolean Read GetConnected; + Published + Property SQLConnection : TSQLConnection Read FSQLConnection Write SetSQLConnection; + Property Database : TRESTDWDatabasebaseBase Read FDatabase Write SetDatabase; + End; + +{$ENDIF} + +Procedure Register; + +Implementation + +{$IFDEF FPC} + +Constructor TRESTDWSQLDBPhysLink.Create(AOwner : TComponent); +Begin + Inherited Create(AOwner); + FBindings := TList.Create; + FRESTConnection := TRESTDWSQLDBConnection.Create(Self); + FRESTConnection.RESTDWDatabase := FDatabase; + FRESTConnection.LoginPrompt := False; + FRESTConnection.DatabaseName := 'RESTDW'; + FRESTTransaction := TSQLTransaction.Create(Self); + FRESTTransaction.Database := FRESTConnection; + FRESTConnection.Transaction := FRESTTransaction; +End; + +Destructor TRESTDWSQLDBPhysLink.Destroy; +Begin + RestoreSQLDBDataSets; + SetSQLConnection(Nil); + SetDatabase(Nil); + FBindings.Free; + Inherited Destroy; +End; + +Procedure TRESTDWSQLDBPhysLink.Loaded; +Begin + Inherited Loaded; + BindSQLDBDataSets; +End; + +Function TRESTDWSQLDBPhysLink.FindBinding(AQuery : TSQLQuery) : TRESTDWSQLDBQueryBinding; +Var + I : Integer; +Begin + Result := Nil; + If (AQuery = Nil) Or (FBindings = Nil) Then + Begin + Exit; + End; + For I := 0 To FBindings.Count - 1 Do + Begin + If TRESTDWSQLDBQueryBinding(FBindings[I]).Query = AQuery Then + Begin + Result := TRESTDWSQLDBQueryBinding(FBindings[I]); + Exit; + End; + End; +End; + +Procedure TRESTDWSQLDBPhysLink.BindQuery(AQuery : TSQLQuery); +Var + LBinding : TRESTDWSQLDBQueryBinding; +Begin + If (AQuery = Nil) Or (FSQLConnection = Nil) Then + Begin + Exit; + End; + If FindBinding(AQuery) <> Nil Then + Begin + Exit; + End; + If AQuery.Database <> FSQLConnection Then + Begin + Exit; + End; + LBinding := TRESTDWSQLDBQueryBinding.Create; + LBinding.Query := AQuery; + LBinding.Database := AQuery.Database; + LBinding.Transaction := AQuery.Transaction; + LBinding.BeforeOpen := AQuery.BeforeOpen; + FBindings.Add(LBinding); + AQuery.FreeNotification(Self); + If LBinding.Database <> Nil Then + Begin + LBinding.Database.FreeNotification(Self); + End; + If LBinding.Transaction <> Nil Then + Begin + LBinding.Transaction.FreeNotification(Self); + End; + AQuery.BeforeOpen := RESTDWQueryBeforeOpen; + AQuery.Database := FRESTConnection; + AQuery.Transaction := FRESTTransaction; +End; + +Procedure TRESTDWSQLDBPhysLink.RESTDWQueryBeforeOpen(DataSet : TDataSet); +Var + LQuery : TSQLQuery; + LBinding : TRESTDWSQLDBQueryBinding; +Begin + If Not (DataSet Is TSQLQuery) Then + Begin + Exit; + End; + LQuery := TSQLQuery(DataSet); + LBinding := FindBinding(LQuery); + If LBinding = Nil Then + Begin + Exit; + End; + If Not RESTDWConnect Then + Begin + Raise Exception.Create(cErrorDatabaseNotFound); + End; + LQuery.Database := FRESTConnection; + LQuery.Transaction := FRESTTransaction; + If Assigned(LBinding.BeforeOpen) Then + Begin + LBinding.BeforeOpen(DataSet); + End; +End; + +Function TRESTDWSQLDBPhysLink.GetConnected : Boolean; +Begin + Result := False; + If FDatabase = Nil Then + Begin + Exit; + End; + If FRESTConnection = Nil Then + Begin + Exit; + End; + Result := FDatabase.Active And FRESTConnection.Connected; +End; + +Function TRESTDWSQLDBPhysLink.RESTDWConnect : Boolean; +Begin + Result := False; + If FDatabase = Nil Then + Begin + Exit; + End; + If FRESTConnection = Nil Then + Begin + Exit; + End; + FRESTConnection.RESTDWDatabase := FDatabase; + If Not FDatabase.Active Then + Begin + FDatabase.Active := True; + End; + If Not FDatabase.Active Then + Begin + Exit; + End; + FRESTConnection.DatabaseName := 'RESTDW'; + FRESTConnection.LoginPrompt := False; + If Not FRESTConnection.Connected Then + Begin + FRESTConnection.Connected := True; + End; + Result := FRESTConnection.Connected; +End; + +Procedure TRESTDWSQLDBPhysLink.RESTDWDisconnect; +Begin + If FRESTConnection <> Nil Then + Begin + If FRESTConnection.Connected Then + Begin + FRESTConnection.Connected := False; + End; + End; +End; + +Procedure TRESTDWSQLDBPhysLink.Notification(AComponent : TComponent; Operation : TOperation); +Var + I : Integer; + LBinding : TRESTDWSQLDBQueryBinding; +Begin + Inherited Notification(AComponent, Operation); + If Operation = opRemove Then + Begin + If FBindings <> Nil Then + Begin + For I := FBindings.Count - 1 DownTo 0 Do + Begin + LBinding := TRESTDWSQLDBQueryBinding(FBindings[I]); + If LBinding.Query = AComponent Then + Begin + LBinding.Query := Nil; + LBinding.Free; + FBindings.Delete(I); + End + Else + Begin + If LBinding.Database = AComponent Then + Begin + LBinding.Database := Nil; + End; + If LBinding.Transaction = AComponent Then + Begin + LBinding.Transaction := Nil; + End; + End; + End; + End; + If AComponent = FSQLConnection Then + Begin + FSQLConnection := Nil; + End; + If AComponent = FDatabase Then + Begin + FDatabase := Nil; + If FRESTConnection <> Nil Then + Begin + FRESTConnection.RESTDWDatabase := Nil; + End; + End; + End; +End; + +Procedure TRESTDWSQLDBPhysLink.RestoreSQLDBDataSets; +Var + I : Integer; + LBinding : TRESTDWSQLDBQueryBinding; +Begin + If FBindings = Nil Then + Begin + Exit; + End; + For I := FBindings.Count - 1 DownTo 0 Do + Begin + LBinding := TRESTDWSQLDBQueryBinding(FBindings[I]); + If LBinding.Query <> Nil Then + Begin + If LBinding.Query.Active Then + Begin + LBinding.Query.Close; + End; + LBinding.Query.BeforeOpen := LBinding.BeforeOpen; + LBinding.Query.Transaction := LBinding.Transaction; + LBinding.Query.Database := LBinding.Database; + LBinding.Query.RemoveFreeNotification(Self); + End; + If LBinding.Database <> Nil Then + Begin + LBinding.Database.RemoveFreeNotification(Self); + End; + If LBinding.Transaction <> Nil Then + Begin + LBinding.Transaction.RemoveFreeNotification(Self); + End; + LBinding.Free; + End; + FBindings.Clear; + If FRESTConnection <> Nil Then + Begin + If FRESTConnection.Connected Then + Begin + FRESTConnection.Connected := False; + End; + End; +End; + +Procedure TRESTDWSQLDBPhysLink.BindSQLDBDataSets; +Var + I : Integer; + LDataSet : TDataSet; + LComponent : TComponent; +Begin + If csDesigning In ComponentState Then + Begin + Exit; + End; + If (FSQLConnection = Nil) Or (FRESTConnection = Nil) Or (FRESTTransaction = Nil) Then + Begin + Exit; + End; + FRESTConnection.RESTDWDatabase := FDatabase; + For I := 0 To FSQLConnection.DataSetCount - 1 Do + Begin + LDataSet := FSQLConnection.DataSets[I]; + If LDataSet Is TSQLQuery Then + Begin + BindQuery(TSQLQuery(LDataSet)); + End; + End; + If Owner <> Nil Then + Begin + For I := 0 To Owner.ComponentCount - 1 Do + Begin + LComponent := Owner.Components[I]; + If LComponent Is TSQLQuery Then + Begin + BindQuery(TSQLQuery(LComponent)); + End; + End; + End; +End; + +Procedure TRESTDWSQLDBPhysLink.SetSQLConnection(Const Value : TSQLConnection); +Begin + If FSQLConnection = Value Then + Begin + Exit; + End; + RestoreSQLDBDataSets; + If FSQLConnection <> Nil Then + Begin + FSQLConnection.RemoveFreeNotification(Self); + End; + FSQLConnection := Value; + If FSQLConnection <> Nil Then + Begin + FSQLConnection.FreeNotification(Self); + End; + BindSQLDBDataSets; +End; + +Procedure TRESTDWSQLDBPhysLink.SetDatabase(Const Value : TRESTDWDatabasebaseBase); +Begin + If FDatabase = Value Then + Begin + Exit; + End; + If FDatabase <> Nil Then + Begin + FDatabase.RemoveFreeNotification(Self); + End; + FDatabase := Value; + If FRESTConnection <> Nil Then + Begin + FRESTConnection.RESTDWDatabase := FDatabase; + End; + If FDatabase <> Nil Then + Begin + FDatabase.FreeNotification(Self); + End; + BindSQLDBDataSets; +End; + +Procedure Register; +Begin + RegisterComponents('REST Dataware - PhysLink', [TRESTDWSQLDBPhysLink]); +End; + +{$ENDIF} + +Initialization +{$IFDEF FPC} + {$I uRESTDWSQLDBPhysLink.lrs} +{$ENDIF} +End. diff --git a/CORE/Source/Database_Drivers/SQLDBPhysLink/uRESTDWSQLDBPhysRegister.pas b/CORE/Source/Database_Drivers/SQLDBPhysLink/uRESTDWSQLDBPhysRegister.pas new file mode 100644 index 000000000..c6f93f1ec --- /dev/null +++ b/CORE/Source/Database_Drivers/SQLDBPhysLink/uRESTDWSQLDBPhysRegister.pas @@ -0,0 +1,18 @@ +Unit uRESTDWSQLDBPhysRegister; + +{$I uRESTDW.inc} + +Interface + +Uses + Classes, uRESTDWSQLDBPhysLink; + +Procedure Register; + +Implementation + +Procedure Register; +Begin + RegisterComponents('REST Dataware - PhysLink', [TRESTDWSQLDBPhysLink]); + End; +End. diff --git a/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZAnalyser.pas b/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZAnalyser.pas index ade227ee8..fc332d16a 100644 --- a/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZAnalyser.pas +++ b/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZAnalyser.pas @@ -1,6 +1,6 @@ unit uRESTDWZAnalyser; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} {$IFNDEF FPC} {$I ZDbc.inc} diff --git a/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZDbc.pas b/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZDbc.pas index 9655c1848..fd7226740 100644 --- a/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZDbc.pas +++ b/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZDbc.pas @@ -1,6 +1,6 @@ -unit uRESTDWZDbc; +unit uRESTDWZDbc; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} {$IFNDEF FPC} {$I ZDbc.inc} {$ELSE} @@ -33,10 +33,12 @@ interface {$IFNDEF ZEOS_DISABLE_RDW} //if set we have an empty unit uses {$IFNDEF ZEOS80UP}ZURL,{$ENDIF} - Classes, SysUtils, + Classes, SysUtils, DB, ZDbcIntfs, ZDbcLogging, ZTokenizer, ZPlainDriver, ZGenericSqlAnalyser, ZCompatibility, ZDbcConnection, - uRESTDWZPlainDriver, uRESTDWBasicDB, uRESTDWConsts; + uRESTDWZPlainDriver, uRESTDWBasicDB, uRESTDWConsts, uRESTDWMassiveBuffer; + +procedure SetRESTDWDriverDatabase(Value : TRESTDWDatabasebaseBase); type TZRESTDWDriver = class(TZAbstractDriver) @@ -58,6 +60,8 @@ TZRESTDWDriver = class(TZAbstractDriver) ['{A4B797A9-7CF7-4DE9-A5BB-693DD32D07D3}'] function GetPlainDriver : IZPlainDriver; function GetDatabase : TRESTDWDatabasebaseBase; + function GetInTransaction : Boolean; + procedure AddMassiveCommand(Const ASQL : String; AParams : TParams); end; { TZRESTDWConnection } @@ -70,12 +74,17 @@ TZRESTDWConnection = class(TZAbstractConnection, IZRESTDWConnection) private FCatalog: string; FPlainDriver: TZRESTDWPlainDriver; + FMassiveSQL : TRESTDWMassiveSQLCache; + FInTransaction : Boolean; + FDatabase : TRESTDWDatabasebaseBase; protected procedure InternalClose; override; {$IFNDEF ZEOS80UP} procedure InternalCreate; override; {$ENDIF} public + constructor Create(Const AUrl : TZURL; ADatabase : TRESTDWDatabasebaseBase); + destructor Destroy; override; function GetPlainDriver: IZPlainDriver; procedure Commit; {$IFNDEF ZEOS80UP} override; {$ENDIF} @@ -98,6 +107,8 @@ TZRESTDWConnection = class(TZAbstractConnection, IZRESTDWConnection) function GetTokenizer: IZTokenizer; function GetStatementAnalyser: IZStatementAnalyser; function GetDatabase : TRESTDWDatabasebaseBase; + function GetInTransaction : Boolean; + procedure AddMassiveCommand(Const ASQL : String; AParams : TParams); {$IFDEF ZEOS80UP} function GetServerProvider: TZServerProvider; override; {$ENDIF} @@ -108,6 +119,7 @@ TZRESTDWConnection = class(TZAbstractConnection, IZRESTDWConnection) var RDWDriver: IZDriver; + RDWDriverObject : TZRESTDWDriver; {$ENDIF ZEOS_DISABLE_RDW} //if set we have an empty unit implementation @@ -151,7 +163,7 @@ function TZRESTDWDriver.GetTokenizer: IZTokenizer; function TZRESTDWDriver.Connect(const Url: TZURL): IZConnection; begin - Result := TZRESTDWConnection.Create(Url); + Result := TZRESTDWConnection.Create(Url, FDatabase); end; { TZRESTDWConnection } @@ -165,10 +177,50 @@ procedure TZRESTDWConnection.AfterConstruction; end; {$ENDIF} -procedure TZRESTDWConnection.Commit; -begin +constructor TZRESTDWConnection.Create(Const AUrl : TZURL; ADatabase : TRESTDWDatabasebaseBase); +Begin + Inherited Create(AUrl); + FDatabase := ADatabase; + FMassiveSQL := TRESTDWMassiveSQLCache.Create(Nil); + FInTransaction := False; +End; + +destructor TZRESTDWConnection.Destroy; +Begin + FMassiveSQL.Free; + Inherited; +End; + +procedure TZRESTDWConnection.AddMassiveCommand(Const ASQL : String; AParams : TParams); +Var + VMassiveCache : TRESTDWMassiveCacheSQLValue; +Begin + VMassiveCache := TRESTDWMassiveCacheSQLValue(FMassiveSQL.CachedList.Add); + VMassiveCache.SQL.Text := ASQL; + VMassiveCache.Params.Assign(AParams); +End; + +function TZRESTDWConnection.GetInTransaction : Boolean; +Begin + Result := FInTransaction; +End; -end; +procedure TZRESTDWConnection.Commit; +Var + VError : Boolean; + VMessageError : String; +Begin + If Not FInTransaction Then + Exit; + VError := False; + VMessageError := ''; + If FMassiveSQL.MassiveCount > 0 Then + GetDatabase.ProcessMassiveSQLCache(FMassiveSQL, VError, VMessageError); + If VError Then + Raise Exception.Create(VMessageError); + FMassiveSQL.Clear; + FInTransaction := False; +End; {$IFNDEF ZEOS80UP} function TZRESTDWConnection.CreatePreparedStatement(const SQL: string; @@ -224,9 +276,9 @@ function TZRESTDWConnection.GetStatementAnalyser: IZStatementAnalyser; end; function TZRESTDWConnection.GetDatabase : TRESTDWDatabasebaseBase; -begin - Result := TZRESTDWDriver(GetDriver).Database; -end; +Begin + Result := FDatabase; +End; function TZRESTDWConnection.GetTokenizer: IZTokenizer; begin @@ -283,23 +335,37 @@ procedure TZRESTDWConnection.Open; {$ENDIF} procedure TZRESTDWConnection.Rollback; -begin - -end; +Begin + FMassiveSQL.Clear; + FInTransaction := False; +End; function TZRESTDWConnection.StartTransaction: Integer; -begin - -end; +Begin + If Not FInTransaction Then + Begin + FMassiveSQL.Clear; + FInTransaction := True; + End; + Result := 1; +End; + +procedure SetRESTDWDriverDatabase(Value : TRESTDWDatabasebaseBase); +Begin + If RDWDriverObject <> Nil Then + RDWDriverObject.Database := Value; +End; initialization - RDWDriver := TZRESTDWDriver.Create; + RDWDriverObject := TZRESTDWDriver.Create; + RDWDriver := RDWDriverObject; DriverManager.RegisterDriver(RDWDriver); finalization if DriverManager <> nil then DriverManager.DeregisterDriver(RDWDriver); RDWDriver := nil; + RDWDriverObject := Nil; {$ENDIF ZEOS_DISABLE_RDW} //if set we have an empty unit diff --git a/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZDbcMetadata.pas b/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZDbcMetadata.pas index 35a5c95d5..55e7186b2 100644 --- a/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZDbcMetadata.pas +++ b/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZDbcMetadata.pas @@ -1,6 +1,6 @@ unit uRESTDWZDbcMetadata; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} {$IFNDEF FPC} {$I ZDbc.inc} diff --git a/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZDbcResultSet.pas b/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZDbcResultSet.pas index dbdbf686c..cf3e842b4 100644 --- a/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZDbcResultSet.pas +++ b/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZDbcResultSet.pas @@ -1,6 +1,12 @@ unit uRESTDWZDbcResultSet; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} + +{$IFDEF FPC} + {$DEFINE GENERIC_INDEX} +{$ENDIF} + +{$DEFINE ZEOS80UP} {$IFNDEF FPC} {$I ZDbc.inc} @@ -17,444 +23,446 @@ Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. - Membros do Grupo : + Membros Do Grupo : - XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. - Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. - Mobius One - Devel, Tester and Admin. - Gustavo - Criptografia and Devel. + XyberX (Gilberto Rocha) - Admin - Criador e Administrador Do pacote. + Alexandre Abbade - Admin - Administrador Do desenvolvimento de DEMOS, coordenador Do Grupo. + Flávio Motta - Member Tester And DEMO Developer. + Mobius One - Devel, Tester And Admin. + Gustavo - Criptografia And Devel. Eloy - Devel. Roniery - Devel. Fernando Banhos - Refactor Drivers REST Dataware. } -interface +Interface {$IFNDEF ZEOS_DISABLE_RESTDW} //if set we have an empty unit -uses +Uses Classes, SysUtils, Types, Contnrs, FmtBCD, ZSysUtils, ZDbcIntfs, ZDbcResultSet, ZDbcResultSetMetadata, ZCompatibility, ZDbcCache, ZDbcCachedResultSet, ZDbcGenericResolver, Variants, ZDbcMetadata, ZSelectSchema, ZDatasetUtils, - uRESTDWZDbc, uRESTDWZPlainDriver, DB, uRESTDWConsts, uRESTDWTools; + uRESTDWZDbc, uRESTDWZPlainDriver, DB, uRESTDWConsts, uRESTDWTools, + ZDataset, ZMemTable; -type - TZRESTDWResultSetMetadata = class(TZAbstractResultSetMetadata) - protected - procedure ClearColumn(ColumnInfo: TZColumnInfo); override; - end; +Type + TZRESTDWResultSetMetadata = Class(TZAbstractResultSetMetadata) + Protected + Procedure ClearColumn(ColumnInfo : TZColumnInfo); Override; +End; {** Implements RESTDW ResultSet. } +{$IFDEF ZEOS80UP} + TZRESTDWResultSet = Class(TZAbstractReadOnlyResultSet, IZResultSet) + {$ELSE} + TZRESTDWResultSet = Class(TZAbstractResultSet) + {$ENDIF} + Private + FRESTDWConnection : IZRESTDWConnection; + + FStream : TStream; + FEncodeStrs : Boolean; + FFieldCount : Integer; + FRecordPos : Int64; + FRecordCount : Int64; + FFieldTypes : Array Of Byte; + FVariantTable : Array Of Array Of Variant; + + FFirstRow : Boolean; + Protected + Procedure Open; Override; + Procedure streamToArray; + Public + Constructor Create(Const AStatement : IZStatement; + Const SQL : String; + Stream : TStream); + + Procedure ResetCursor; Override; + + Function IsNull(ColumnIndex : Integer) : Boolean; {$IFNDEF ZEOS80UP} Override; {$ENDIF} + Function GetPAnsiChar(ColumnIndex : Integer; Out Len : NativeUInt) : PAnsiChar; {$IFDEF ZEOS80UP} Overload {$ELSE} Override {$ENDIF}; + Function GetPWideChar(ColumnIndex : Integer; + Out Len : NativeUInt) : PWideChar; {$IFDEF ZEOS80UP} Overload {$ELSE} Override {$ENDIF}; + {$IFNDEF NO_UTF8STRING} + Function GetUTF8String(ColumnIndex : Integer) : UTF8String; {$IFNDEF ZEOS80UP} Override; {$ENDIF} + {$ENDIF} + {$IFNDEF NO_ANSISTRING} + Function GetAnsiString(ColumnIndex : Integer) : AnsiString; {$IFNDEF ZEOS80UP} Override; {$ENDIF} + {$ENDIF} + Function GetBoolean(ColumnIndex : Integer) : Boolean; {$IFNDEF ZEOS80UP} Override; {$ENDIF} + Function GetInt(ColumnIndex : Integer) : Integer; {$IFNDEF ZEOS80UP} Override; {$ENDIF} + Function GetUInt(ColumnIndex : Integer) : Cardinal; {$IFNDEF ZEOS80UP} Override; {$ENDIF} + Function GetLong(ColumnIndex : Integer) : Int64; {$IFNDEF ZEOS80UP} Override; {$ENDIF} + Function GetULong(ColumnIndex : Integer) : UInt64; {$IFNDEF ZEOS80UP} Override; {$ENDIF} + Function GetFloat(ColumnIndex : Integer) : Single; {$IFNDEF ZEOS80UP} Override; {$ENDIF} + Function GetDouble(ColumnIndex : Integer) : Double; {$IFNDEF ZEOS80UP} Override; {$ENDIF} + Function GetCurrency(ColumnIndex : Integer) : Currency; {$IFNDEF ZEOS80UP} Override; {$ENDIF} {$IFDEF ZEOS80UP} - TZRESTDWResultSet = class(TZAbstractReadOnlyResultSet, IZResultSet) + Procedure GetBigDecimal(ColumnIndex : Integer; Var Result : TBCD); + Function GetBytes(ColumnIndex : Integer; Out Len : NativeUInt) : PByte; Overload; {$ELSE} - TZRESTDWResultSet = class(TZAbstractResultSet) + Function GetBigDecimal(ColumnIndex : Integer) : Extended; Override; + Function GetBytes(ColumnIndex : Integer) : TBytes; Override; + {$ENDIF} + Procedure GetGUID(ColumnIndex : Integer; Var Result : TGUID); + {$IFDEF ZEOS80UP} + Procedure GetDate(ColumnIndex : Integer; Var Result : TZDate); Reintroduce; Overload; + Procedure GetTime(ColumnIndex : Integer; Var Result : TZTime); Reintroduce; Overload; + Procedure GetTimestamp(ColumnIndex : Integer; Var Result : TZTimeStamp); Reintroduce; Overload; + Function GetBlob(ColumnIndex : Integer; LobStreamMode : TZLobStreamMode = lsmRead) : IZBlob; + {$ELSE} + Function GetDate(ColumnIndex : Integer) : TDateTime; Override; + Function GetTime(ColumnIndex : Integer) : TDateTime; Override; + Function GetTimestamp(ColumnIndex : Integer) : TDateTime; Override; + Function GetBlob(ColumnIndex : Integer) : IZBlob; Override; {$ENDIF} - private - FRESTDWConnection : IZRESTDWConnection; - - FStream : TStream; - FEncodeStrs : boolean; - FFieldCount : integer; - FRecordPos : int64; - FRecordCount : int64; - FFieldTypes : array of byte; - FVariantTable : array of array of Variant; - - FFirstRow : boolean; - protected - procedure Open; override; - procedure streamToArray; - public - constructor Create(const Statement: IZStatement; const SQL: string; Stream : TStream); - - procedure ResetCursor; override; - - function IsNull(ColumnIndex: Integer): Boolean; {$IFNDEF ZEOS80UP} override; {$ENDIF} - function GetPAnsiChar(ColumnIndex: Integer; out Len: NativeUInt): PAnsiChar; {$IFDEF ZEOS80UP} overload {$ELSE} override {$ENDIF}; - function GetPWideChar(ColumnIndex: Integer; out Len: NativeUInt): PWideChar; {$IFDEF ZEOS80UP} overload {$ELSE} override {$ENDIF}; - {$IFNDEF NO_UTF8STRING} - function GetUTF8String(ColumnIndex: Integer): UTF8String; {$IFNDEF ZEOS80UP} override; {$ENDIF} - {$ENDIF} - {$IFNDEF NO_ANSISTRING} - function GetAnsiString(ColumnIndex: Integer): AnsiString; {$IFNDEF ZEOS80UP} override; {$ENDIF} - {$ENDIF} - function GetBoolean(ColumnIndex: Integer): Boolean; {$IFNDEF ZEOS80UP} override; {$ENDIF} - function GetInt(ColumnIndex: Integer): Integer; {$IFNDEF ZEOS80UP} override; {$ENDIF} - function GetUInt(ColumnIndex: Integer): Cardinal; {$IFNDEF ZEOS80UP} override; {$ENDIF} - function GetLong(ColumnIndex: Integer): Int64; {$IFNDEF ZEOS80UP} override; {$ENDIF} - function GetULong(ColumnIndex: Integer): UInt64; {$IFNDEF ZEOS80UP} override; {$ENDIF} - function GetFloat(ColumnIndex: Integer): Single; {$IFNDEF ZEOS80UP} override; {$ENDIF} - function GetDouble(ColumnIndex: Integer): Double; {$IFNDEF ZEOS80UP} override; {$ENDIF} - function GetCurrency(ColumnIndex: Integer): Currency; {$IFNDEF ZEOS80UP} override; {$ENDIF} - {$IFDEF ZEOS80UP} - procedure GetBigDecimal(ColumnIndex: Integer; var Result: TBCD); - function GetBytes(ColumnIndex: Integer; out Len: NativeUInt): PByte; overload; - {$ELSE} - function GetBigDecimal(ColumnIndex: Integer) : Extended; override; - function GetBytes(ColumnIndex: Integer): TBytes; override; - {$ENDIF} - procedure GetGUID(ColumnIndex: Integer; var Result: TGUID); - {$IFDEF ZEOS80UP} - procedure GetDate(ColumnIndex: Integer; Var Result: TZDate); reintroduce; overload; - procedure GetTime(ColumnIndex: Integer; var Result: TZTime); reintroduce; overload; - procedure GetTimestamp(ColumnIndex: Integer; Var Result: TZTimeStamp); reintroduce; overload; - function GetBlob(ColumnIndex: Integer; LobStreamMode: TZLobStreamMode = lsmRead): IZBlob; - {$ELSE} - function GetDate(ColumnIndex: Integer): TDateTime; override; - function GetTime(ColumnIndex: Integer): TDateTime; override; - function GetTimestamp(ColumnIndex: Integer): TDateTime; override; - function GetBlob(ColumnIndex: Integer): IZBlob; override; - {$ENDIF} - function Next: Boolean; {$IFDEF ZEOS80UP} reintroduce {$ELSE} override {$ENDIF}; - {$IFDEF WITH_COLUMNS_TO_JSON} - procedure ColumnsToJSON(ResultsWriter: {$IFDEF MORMOT2}TResultsWriter{$ELSE}TJSONWriter{$ENDIF}; JSONComposeOptions: TZJSONComposeOptions); - {$ENDIF WITH_COLUMNS_TO_JSON} - end; + Function Next : Boolean; {$IFDEF ZEOS80UP} Reintroduce {$ELSE} Override {$ENDIF}; + {$IFDEF WITH_COLUMNS_TO_JSON} + Procedure ColumnsToJSON(ResultsWriter : {$IFDEF MORMOT2}TResultsWriter{$ELSE}TJSONWriter{$ENDIF}; + JSONComposeOptions : TZJSONComposeOptions); + {$ENDIF WITH_COLUMNS_TO_JSON} +End; - {** Implements a cached resolver with RESTDW specific functionality. } - {$IFDEF ZEOS80UP} - TZRESTDWCachedResolver = class (TZGenerateSQLCachedResolver, IZCachedResolver) + {** Implements a cached resolver With RESTDW specific functionality. } +{$IFDEF ZEOS80UP} + TZRESTDWCachedResolver = Class (TZGenerateSQLCachedResolver, IZCachedResolver) {$ELSE} - TZRESTDWCachedResolver = class (TZGenericCachedResolver, IZCachedResolver) + TZRESTDWCachedResolver = Class (TZGenericCachedResolver, IZCachedResolver) {$ENDIF} - private - FPlainDriver: TZRESTDWPlainDriver; - FAutoColumnIndex: Integer; - public - constructor Create(const Statement: IZStatement; const Metadata: IZResultSetMetadata); - - {$IFDEF ZEOS80UP} - procedure PostUpdates(const Sender: IZCachedResultSet; UpdateType: TZRowUpdateType; - const OldRowAccessor, NewRowAccessor: TZRowAccessor); override; - {$ELSE} - procedure PostUpdates(Sender: IZCachedResultSet; UpdateType: TZRowUpdateType; - OldRowAccessor, NewRowAccessor: TZRowAccessor); override; - {$ENDIF} + Private + FPlainDriver : TZRESTDWPlainDriver; + FAutoColumnIndex : Integer; + Public + Constructor Create(Const AStatement : IZStatement; Const AMetadata : IZResultSetMetadata); - function CheckKeyColumn(ColumnIndex: Integer): Boolean; override; + {$IFDEF ZEOS80UP} + Procedure PostUpdates(Const Sender : IZCachedResultSet; UpdateType : TZRowUpdateType; + Const OldRowAccessor, NewRowAccessor : TZRowAccessor); Override; + {$ELSE} + Procedure PostUpdates(Sender : IZCachedResultSet; UpdateType : TZRowUpdateType; + OldRowAccessor, NewRowAccessor : TZRowAccessor); Override; + {$ENDIF} - {$IFDEF ZEOS80UP} - procedure UpdateAutoIncrementFields(const Sender: IZCachedResultSet; - UpdateType: TZRowUpdateType; const OldRowAccessor, NewRowAccessor: TZRowAccessor; - const Resolver: IZCachedResolver); override; - {$ELSE} - procedure UpdateAutoIncrementFields(Sender: IZCachedResultSet; UpdateType: TZRowUpdateType; - OldRowAccessor, NewRowAccessor: TZRowAccessor; Resolver: IZCachedResolver); override; - {$ENDIF} - end; + Function CheckKeyColumn(ColumnIndex : Integer) : Boolean; Override; {$IFDEF ZEOS80UP} + Procedure UpdateAutoIncrementFields(Const Sender : IZCachedResultSet; + UpdateType : TZRowUpdateType; Const OldRowAccessor, NewRowAccessor : TZRowAccessor; + Const Resolver : IZCachedResolver); Override; + {$ELSE} + Procedure UpdateAutoIncrementFields(Sender : IZCachedResultSet; UpdateType : TZRowUpdateType; + OldRowAccessor, NewRowAccessor : TZRowAccessor; Resolver : IZCachedResolver); Override; + {$ENDIF} +End; + +{$IFDEF ZEOS80UP} { TZRESTDWCachedResultSet } - TZRESTDWCachedResultSet = Class(TZCachedResultSet) - protected - class function GetRowAccessorClass: TZRowAccessorClass; override; - end; + TZRESTDWCachedResultSet = Class(TZCachedResultSet) + Protected + Class Function GetRowAccessorClass : TZRowAccessorClass; Override; +End; { TZRESTDWRowAccessor } - TZRESTDWRowAccessor = class(TZRowAccessor) - protected - class function MetadataToAccessorType(ColumnInfo: TZColumnInfo; - ConSettings: PZConSettings; Var ColumnCodePage: Word): TZSQLType; override; - end; - {$ENDIF} + TZRESTDWRowAccessor = Class(TZRowAccessor) + Protected + Class Function MetadataToAccessorType(AColumnInfo : TZColumnInfo; + AConSettings : PZConSettings; Var AColumnCodePage : Word) : TZSQLType; Override; +End; +{$ENDIF} {$ENDIF ZEOS_DISABLE_RESTDW} //if set we have an empty unit -implementation +Implementation {$IFNDEF ZEOS_DISABLE_RESTDW} //if set we have an empty unit -uses +Uses ZMessages, ZTokenizer, ZVariant, ZEncoding, ZFastCode, ZGenericSqlAnalyser, uRESTDWProtoTypes {$IFNDEF FPC}, SqlTimSt {$ENDIF}; { TZRESTDWCachedResultSet } {$IFDEF ZEOS80UP} - class function TZRESTDWCachedResultSet.GetRowAccessorClass: TZRowAccessorClass; - begin - Result := TZRESTDWRowAccessor; - end; +Class Function TZRESTDWCachedResultSet.GetRowAccessorClass : TZRowAccessorClass; +Begin + Result := TZRESTDWRowAccessor; +End; {$ENDIF} { TZRESTDWRowAccessor } {$IFDEF ZEOS80UP} - {$IFDEF FPC} {$PUSH} {$WARN 5024 off : Parameter "ConSettings" not used} {$ENDIF} - class function TZRESTDWRowAccessor.MetadataToAccessorType( - ColumnInfo: TZColumnInfo; ConSettings: PZConSettings; Var ColumnCodePage: Word): TZSQLType; - begin - Result := ColumnInfo.ColumnType; - if Result in [stAsciiStream, stUnicodeStream, stBinaryStream] then begin - Result := TZSQLType(Byte(Result)-3); // no streams 4 RESTDW - ColumnInfo.Precision := 0; - end; - if Result = stUnicodeString then - Result := stString; // no national chars in RESTDW - end; + {$IFDEF FPC} {$PUSH} {$WARN 5024 off : Parameter "AConSettings" not used} {$ENDIF} +Class Function TZRESTDWRowAccessor.MetadataToAccessorType( + AColumnInfo : TZColumnInfo; AConSettings : PZConSettings; Var AColumnCodePage : Word) : TZSQLType; +Begin + Result := AColumnInfo.ColumnType; + If Result in [stAsciiStream, stUnicodeStream, stBinaryStream] Then + Begin + Result := TZSQLType(Byte(Result)-3); // no streams 4 RESTDW + AColumnInfo.Precision := 0; + End; + If Result = stUnicodeString Then + Result := stString; // no national chars in RESTDW +End; {$IFDEF FPC} {$POP} {$ENDIF} {$ENDIF} { TZRESTDWResultSet } {$IFDEF WITH_COLUMNS_TO_JSON} -procedure TZRESTDWResultSet.ColumnsToJSON(ResultsWriter: {$IFDEF MORMOT2}TResultsWriter{$ELSE}TJSONWriter{$ENDIF}; - JSONComposeOptions: TZJSONComposeOptions); -begin +Procedure TZRESTDWResultSet.ColumnsToJSON(ResultsWriter : {$IFDEF MORMOT2}TResultsWriter{$ELSE}TJSONWriter{$ENDIF}; + JSONComposeOptions : TZJSONComposeOptions); +Begin -end; +End; {$ENDIF WITH_COLUMNS_TO_JSON} -constructor TZRESTDWResultSet.Create(const Statement: IZStatement; - const SQL: string; Stream : TStream); -var - Metadata: TContainedObject; -begin - FRESTDWConnection := TZRESTDWConnection(Statement.GetConnection); +Constructor TZRESTDWResultSet.Create(Const AStatement : IZStatement; + Const SQL : String; + Stream : TStream); +Var + Metadata : TContainedObject; +Begin + FRESTDWConnection := AStatement.GetConnection As IZRESTDWConnection; + If FRESTDWConnection = Nil Then + Raise Exception.Create(cErrorDatabaseNotFound); Metadata := TZRESTDWResultSetMetadata.Create(FRESTDWConnection.GetMetadata,SQL,Self); - inherited Create(Statement, SQL, MetaData, Statement.GetConnection.GetConSettings); + Inherited Create(AStatement, SQL, MetaData, AStatement.GetConnection.GetConSettings); FFirstRow := True; FStream := Stream; + If FStream = Nil Then + Raise Exception.Create('Zeos PhysLink dataset stream not assigned'); + If FStream.Size = 0 Then + Raise Exception.Create('Zeos PhysLink dataset stream is empty'); FStream.Position := 0; FRecordPos := 0; ResultSetConcurrency := rcReadOnly; Open; -end; - -procedure TZRESTDWResultSet.Open; -var - ColumnInfo: TZColumnInfo; - - i, j : int64; - vFieldKind : TFieldKind; - - vBoolean : boolean; - vString : utf8string; - vInt : integer; - vInt64 : int64; - vDWFielType : Byte; - vFieldType : TFieldType; - vFieldSize : integer; - vFieldPrecision : integer; - vByte : Byte; -begin +End; + +Procedure TZRESTDWResultSet.Open; +Var + MemTable : TZMemTable; + ColumnInfo : TZColumnInfo; + Field : TField; + I : Integer; + J : Integer; +Begin LastRowNo := 0; ColumnsInfo.Clear; + MemTable := TZMemTable.Create(Nil); + Try + FStream.Position := 0; + MemTable.LoadFromStream(FStream); + FFieldCount := MemTable.FieldCount; + If FFieldCount < 1 Then + Raise Exception.Create('Zeos PhysLink native stream has no fields'); + FRecordCount := MemTable.RecordCount; + SetLength(FVariantTable, FRecordCount); + SetLength(FFieldTypes, FFieldCount); + + For I := 0 To FFieldCount - 1 Do + Begin + Field := MemTable.Fields[I]; + ColumnInfo := TZColumnInfo.Create; + ColumnInfo.ColumnName := Field.FieldName; + ColumnInfo.ColumnLabel := Field.DisplayName; + ColumnInfo.TableName := ''; + ColumnInfo.CatalogName := ''; + ColumnInfo.ReadOnly := Field.ReadOnly; + ColumnInfo.ColumnType := ConvertDatasetToDbcType(Field.DataType); + FFieldTypes[I] := FieldTypeToDWFieldType(Field.DataType); + ColumnInfo.Precision := Field.Size; + ColumnInfo.Scale := 0; + ColumnInfo.Writable := Not Field.ReadOnly; + ColumnInfo.DefinitelyWritable := Not Field.ReadOnly; + ColumnInfo.Signed := True; + ColumnInfo.Searchable := True; + If Field.Required Then + ColumnInfo.Nullable := ntNoNulls + Else + ColumnInfo.Nullable := ntNullable; + If ColumnInfo.ColumnType in [stString, stAsciiStream] Then + ColumnInfo.ColumnCodePage := zCP_UTF8; + ColumnsInfo.Add(ColumnInfo); + End; + + MemTable.First; + I := 0; + While Not MemTable.Eof Do + Begin + SetLength(FVariantTable[I], FFieldCount); + For J := 0 To FFieldCount - 1 Do + Begin + If MemTable.Fields[J].IsNull Then + FVariantTable[I, J] := Null + Else + FVariantTable[I, J] := MemTable.Fields[J].Value; + End; + Inc(I); + MemTable.Next; + End; + Finally + MemTable.Free; + End; + FStream.Size := 0; + Inherited Open; +{$IFDEF ZEOS80UP} + FCursorLocation := rctServer; +{$ENDIF} +End; - // field count - FStream.Read(FFieldCount,SizeOf(integer)); - SetLength(FFieldTypes,FFieldCount); - - // encodestrs - FStream.Read(vBoolean, Sizeof(vBoolean)); - FEncodeStrs := vBoolean; - - i := 0; - while i < FFieldCount do begin - ColumnInfo := TZColumnInfo.Create; - with ColumnInfo do begin - // field kind - FStream.Read(vByte,SizeOf(vByte)); - vFieldKind := TFieldKind(vByte); - - // field name - FStream.Read(vByte,SizeOf(vByte)); - SetLength(vString,vByte); - FStream.Read(vString[InitStrPos],vByte); - - ColumnName := vString; - ColumnLabel := vString; - TableName := ''; - CatalogName := ''; - - ReadOnly := False; - - // field type - FStream.Read(vDWFielType,SizeOf(vDWFielType)); - vFieldType := DWFieldTypeToFieldType(vDWFielType); - FFieldTypes[i] := vDWFielType; - - ColumnType := ConvertDatasetToDbcType(vFieldType); - - // field size - FStream.Read(vFieldSize,SizeOf(Integer)); - - // field precision - FStream.Read(vFieldPrecision,SizeOf(Integer)); - - // required + provider flags - FStream.Read(vByte,SizeOf(Byte)); - - if ColumnType in [stString, stAsciiStream] then begin - ColumnCodePage := zCP_UTF8; - if ColumnType = stString then - CharOctedLength := vFieldPrecision shl 2; - end else if ColumnType = stBytes then - CharOctedLength := vFieldPrecision; - AutoIncrement := False; - Precision := vFieldSize; - Scale := vFieldPrecision; - Writable := True; - DefinitelyWritable := True; - Signed := True; - Searchable := True; - - Nullable := ntNoNulls; - if vByte and 1 = 0 then - Nullable := ntNullable; - end; - - ColumnsInfo.Add(ColumnInfo); - i := i + 1; - end; - - FStream.Read(FRecordCount,SizeOf(FRecordCount)); - FRecordPos := FStream.Position; - - streamToArray; - - FStream.Size := 0; - - inherited Open; - {$IFDEF ZEOS80UP} - FCursorLocation := rctServer; - {$ENDIF} -end; - -procedure TZRESTDWResultSet.ResetCursor; -begin - FFirstRow := True; // zeos7 - if not Closed then begin - FStream.Position := 0; - inherited ResetCursor; - end; -end; - -procedure TZRESTDWResultSet.streamToArray; -var - i : int64; - j : integer; - vString : DWString; - vInt64 : Int64; - vInt : Integer; - vByte : Byte; - vBoolean : Boolean; - vWord : Word; - vSingle : Single; - vDouble : Double; - VTimeZone : Double; - vCurrency : Currency; - vStringStream : TStringStream; +Procedure TZRESTDWResultSet.ResetCursor; +Begin + FFirstRow := True; + RowNo := 0; + LastRowNo := 0; + If Not Closed Then + Inherited ResetCursor; +End; + +Procedure TZRESTDWResultSet.streamToArray; +Var + i : Int64; + j : Integer; + vString : DWString; + vInt64 : Int64; + vInt : Integer; + vByte : Byte; + vBoolean : Boolean; + vWord : Word; + vSingle : Single; + vDouble : Double; + VTimeZone : Double; + vCurrency : Currency; + vStringStream : TStringStream; {$IFDEF DELPHIXEUP} vTimeStampOffset : TSQLTimeStampOffset; {$ENDIF} -begin +Begin + vBoolean := False; + vInt64 := 0; + vByte := 0; + vWord := 0; + vInt := 0; + vSingle := 0; + vDouble := 0; + vCurrency := 0; SetLength(FVariantTable,FRecordCount); i := 0; - while i <= FRecordCount-1 do begin + While i <= FRecordCount-1 Do + Begin SetLength(FVariantTable[i],FFieldCount); - for j := 0 to FFieldCount-1 do begin + For j := 0 To FFieldCount-1 Do + Begin FStream.Read(vBoolean,SizeOf(vBoolean)); - if Not vBoolean then begin + If Not vBoolean Then + Begin FVariantTable[i,j] := variants.null; Continue; - end; + End; // N - Bytes - if (FFieldTypes[j] in [dwftFixedChar,dwftString]) then begin + If (FFieldTypes[j] In [dwftFixedChar,dwftString]) Then + Begin FStream.Read(vInt64, Sizeof(vInt64)); vString := ''; - if vInt64 > 0 then begin + If vInt64 > 0 Then + Begin SetLength(vString, vInt64); {$IFDEF FPC} FStream.Read(Pointer(vString)^, vInt64); - if FEncodeStrs then + If FEncodeStrs Then vString := DecodeStrings(vString, csUndefined); vString := GetStringEncode(vString, csUTF8); {$ELSE} FStream.Read(vString[InitStrPos], vInt64); - if FEncodeStrs then + If FEncodeStrs Then vString := DecodeStrings(vString); {$ENDIF} - end; - if System.Pos(#0,vString) > 0 then + End; + If System.Pos(#0,vString) > 0 Then vString := StringReplace(vString, #0, '', [rfReplaceAll]); FVariantTable[i,j] := vString; - end + End // N - Bytes Wide - else if (FFieldTypes[j] in [dwftWideString,dwftFixedWideChar]) then begin + Else If (FFieldTypes[j] In [dwftWideString,dwftFixedWideChar]) Then + Begin FStream.Read(vInt64, Sizeof(vInt64)); vString := ''; - if vInt64 > 0 then begin + If vInt64 > 0 Then + Begin SetLength(vString, vInt64); {$IFDEF FPC} FStream.Read(Pointer(vString)^, vInt64); - if FEncodeStrs then + If FEncodeStrs Then vString := DecodeStrings(vString, csUndefined); vString := GetStringEncode(vString, csUTF8); {$ELSE} FStream.Read(vString[InitStrPos], vInt64); - if FEncodeStrs then + If FEncodeStrs Then vString := DecodeStrings(vString); {$ENDIF} - end; - if System.Pos(#0,vString) > 0 then + End; + If System.Pos(#0,vString) > 0 Then vString := StringReplace(vString, #0, '', [rfReplaceAll]); FVariantTable[i,j] := vString; - end + End // 1 - Byte - Inteiros - else if (FFieldTypes[j] in [dwftByte,dwftShortint]) then - begin + Else If (FFieldTypes[j] In [dwftByte,dwftShortint]) Then + Begin FStream.Read(vByte, Sizeof(vByte)); FVariantTable[i,j] := vByte; - end + End // 1 - Byte - Boolean - else if (FFieldTypes[j] in [dwftBoolean]) then - begin + Else If (FFieldTypes[j] In [dwftBoolean]) Then + Begin FStream.Read(vBoolean, Sizeof(vBoolean)); FVariantTable[i,j] := vBoolean; - end + End // 2 - Bytes - else if (FFieldTypes[j] in [dwftSmallint,dwftWord]) then begin + Else If (FFieldTypes[j] In [dwftSmallint,dwftWord]) Then + Begin FStream.Read(vWord, Sizeof(vWord)); FVariantTable[i,j] := vWord; - end + End // 4 - Bytes - Inteiros - else if (FFieldTypes[j] in [dwftInteger]) then - begin + Else If (FFieldTypes[j] In [dwftInteger]) Then + Begin FStream.Read(vInt, Sizeof(vInt)); FVariantTable[i,j] := vInt; - end + End // 4 - Bytes - Flutuantes - else if (FFieldTypes[j] in [dwftSingle]) then - begin + Else If (FFieldTypes[j] In [dwftSingle]) Then + Begin FStream.Read(vSingle, Sizeof(vSingle)); FVariantTable[i,j] := vSingle; - end + End // 8 - Bytes - Inteiros - else if (FFieldTypes[j] in [dwftLargeint,dwftAutoInc,dwftLongWord]) then - begin + Else If (FFieldTypes[j] In [dwftLargeint,dwftAutoInc,dwftLongWord]) Then + Begin FStream.Read(vInt64, Sizeof(vInt64)); FVariantTable[i,j] := vInt64; - end + End // 8 - Bytes - Flutuantes - else if (FFieldTypes[j] in [dwftFloat,dwftExtended]) then - begin + Else If (FFieldTypes[j] In [dwftFloat,dwftExtended]) Then + Begin FStream.Read(vDouble, Sizeof(vDouble)); FVariantTable[i,j] := vDouble; - end + End // 8 - Bytes - Date, Time, DateTime, TimeStamp - else if (FFieldTypes[j] in [dwftDate,dwftTime,dwftDateTime,dwftTimeStamp]) then - begin + Else If (FFieldTypes[j] In [dwftDate,dwftTime,dwftDateTime,dwftTimeStamp]) Then + Begin FStream.Read(vDouble, Sizeof(vDouble)); FVariantTable[i,j] := vDouble; - end + End // TimeStampOffSet To Double - 8 Bytes // + TimeZone - 2 Bytes - else if (FFieldTypes[j] in [dwftTimeStampOffset]) then begin + Else If (FFieldTypes[j] In [dwftTimeStampOffset]) Then + Begin {$IFDEF DELPHIXEUP} FStream.Read(vDouble, Sizeof(vDouble)); @@ -474,45 +482,49 @@ procedure TZRESTDWResultSet.streamToArray; vTimeZone := (vByte - 12) / 24; FStream.Read(vByte, SizeOf(vByte)); - if vTimeZone > 0 then + If vTimeZone > 0 Then vTimeZone := vTimeZone + (vByte / 60 / 24) - else + Else vTimeZone := vTimeZone - (vByte / 60 / 24); vDouble := vDouble - vTimeZone; FVariantTable[i,j] := vDouble; {$ENDIF} - end + End // 8 - Bytes - Currency - else if (FFieldTypes[j] in [dwftCurrency,dwftBCD,dwftFMTBcd]) then - begin + Else If (FFieldTypes[j] In [dwftCurrency,dwftBCD,dwftFMTBcd]) Then + Begin FStream.Read(vCurrency, Sizeof(vCurrency)); FVariantTable[i,j] := vCurrency; - end + End // N Bytes - Wide Memos - else if (FFieldTypes[j] in [dwftMemo,dwftWideMemo,dwftFmtMemo]) then begin + Else If (FFieldTypes[j] In [dwftMemo,dwftWideMemo,dwftFmtMemo]) Then + Begin FStream.Read(vInt64, Sizeof(vInt64)); - if vInt64 > 0 then Begin + If vInt64 > 0 Then + Begin vStringStream := TStringStream.Create(''); - try + Try vStringStream.CopyFrom(FStream, vInt64); vStringStream.Position := 0; // Result := TEncoding.Unicode.GetString(vStringStream.Bytes); vString := vStringStream.DataString; - if System.Pos(#0,vString) > 0 then + If System.Pos(#0,vString) > 0 Then vString := StringReplace(vString, #0, '', [rfReplaceAll]); - finally + Finally vStringStream.Free; - end; + End; FVariantTable[i,j] := vString; - end; - end + End; + End // N Bytes - Memos e Blobs - else if (FFieldTypes[j] in [dwftStream,dwftBlob,dwftBytes]) then begin + Else If (FFieldTypes[j] In [dwftStream,dwftBlob,dwftBytes]) Then + Begin FStream.Read(vInt64, Sizeof(vInt64)); - if vInt64 > 0 then Begin + If vInt64 > 0 Then + Begin vStringStream := TStringStream.Create(''); - try + Try vStringStream.CopyFrom(FStream, vInt64); vStringStream.Position := 0; {$IFNDEF FPC} @@ -524,510 +536,587 @@ procedure TZRESTDWResultSet.streamToArray; {$ELSE} FVariantTable[i,j] := vStringStream.Bytes; {$ENDIF} - finally + Finally vStringStream.Free; - end; - end; - end - else begin + End; + End; + End + Else + Begin FStream.Read(vInt64, Sizeof(vInt64)); vString := ''; - if vInt64 > 0 then begin + If vInt64 > 0 Then + Begin SetLength(vString, vInt64); {$IFDEF FPC} FStream.Read(Pointer(vString)^, vInt64); - if FEncodeStrs then + If FEncodeStrs Then vString := DecodeStrings(vString, csUndefined); vString := GetStringEncode(vString, csUTF8); {$ELSE} FStream.Read(vString[InitStrPos], vInt64); - if FEncodeStrs then + If FEncodeStrs Then vString := DecodeStrings(vString); {$ENDIF} - end; - if System.Pos(#0,vString) > 0 then + End; + If System.Pos(#0,vString) > 0 Then vString := StringReplace(vString, #0, '', [rfReplaceAll]); FVariantTable[i,j] := vString; - end; - end; + End; + End; Inc(i); - end; -end; + End; +End; -function TZRESTDWResultSet.IsNull(ColumnIndex: Integer): Boolean; -begin +Function TZRESTDWResultSet.IsNull(ColumnIndex : Integer) : Boolean; +Begin {$IFNDEF GENERIC_INDEX} - ColumnIndex := ColumnIndex -1; + ColumnIndex := ColumnIndex - 1; {$ENDIF} - Result := FVariantTable[RowNo-1,ColumnIndex] = Null; -end; - -function TZRESTDWResultSet.GetPAnsiChar(ColumnIndex: Integer; out Len: NativeUInt): PAnsiChar; -var - vInt64 : int64; - vString : ansistring; -begin + If (ColumnIndex < 0) Or + (ColumnIndex >= FFieldCount) Then + Raise Exception.CreateFmt('Zeos PhysLink invalid column index %d. FieldCount=%d', + [ColumnIndex, FFieldCount]); + If (RowNo < 1) Or + (RowNo > FRecordCount) Then + Raise Exception.CreateFmt('Zeos PhysLink invalid row %d. RecordCount=%d', + [RowNo, FRecordCount]); + Result := VarIsNull(FVariantTable[RowNo-1,ColumnIndex]); +End; + +Function TZRESTDWResultSet.GetPAnsiChar(ColumnIndex : Integer; Out Len : NativeUInt) : PAnsiChar; +Var + vString : AnsiString; +Begin Result := PAnsiChar(''); LastWasNull := IsNull(ColumnIndex); {$IFNDEF GENERIC_INDEX} - ColumnIndex := ColumnIndex -1; + ColumnIndex := ColumnIndex - 1; {$ENDIF} + If (ColumnIndex < 0) Or + (ColumnIndex >= FFieldCount) Then + Raise Exception.CreateFmt('Zeos PhysLink invalid column index %d. FieldCount=%d', + [ColumnIndex, FFieldCount]); - if not LastWasNull then begin + If Not LastWasNull Then + Begin vString := FVariantTable[RowNo-1,ColumnIndex]; Len := Length(vString)+1; Result := PAnsiChar(vString); - end; -end; + End; +End; -function TZRESTDWResultSet.GetPWideChar(ColumnIndex: Integer; - out Len: NativeUInt): PWideChar; -var +Function TZRESTDWResultSet.GetPWideChar(ColumnIndex : Integer; + Out Len : NativeUInt) : PWideChar; +Var P : PAnsiChar; S : AnsiString; W : WideString; -begin +Begin + S := ''; P := GetPAnsiChar(ColumnIndex, Len); SetLength(S,Len); S := P; W := S; Result := PWideChar(W); Len := Length(Result); -end; +End; {$IFNDEF NO_UTF8STRING} -function TZRESTDWResultSet.GetUTF8String(ColumnIndex: Integer): UTF8String; -var - P: PAnsiChar; - Len: NativeUint; -begin +Function TZRESTDWResultSet.GetUTF8String(ColumnIndex : Integer) : UTF8String; +Var + P : PAnsiChar; + Len : NativeUint; +Begin P := GetPAnsiChar(ColumnIndex, Len); {$IFDEF RESTDWLAZARUS} Result := ''; {$ENDIF} - if P <> nil + If P <> Nil {$IFDEF MISS_RBS_SETSTRING_OVERLOAD} - then ZSetString(P, Len, result) + Then ZSetString(P, Len, result) {$ELSE} - then System.SetString(Result, P, Len) + Then System.SetString(Result, P, Len) {$ENDIF} {$IFNDEF WITH_VAR_INIT_WARNING} - else Result := ''; + Else {$ENDIF} -end; +End; {$ENDIF} -function TZRESTDWResultSet.GetBoolean(ColumnIndex: Integer): Boolean; -var +Function TZRESTDWResultSet.GetBoolean(ColumnIndex : Integer) : Boolean; +Var vBoolean : Boolean; -begin +Begin Result := False; LastWasNull := IsNull(ColumnIndex); {$IFNDEF GENERIC_INDEX} - ColumnIndex := ColumnIndex -1; + ColumnIndex := ColumnIndex - 1; {$ENDIF} + If (ColumnIndex < 0) Or + (ColumnIndex >= FFieldCount) Then + Raise Exception.CreateFmt('Zeos PhysLink invalid column index %d. FieldCount=%d', + [ColumnIndex, FFieldCount]); - if not LastWasNull then begin + If Not LastWasNull Then + Begin vBoolean := FVariantTable[RowNo-1,ColumnIndex]; Result := vBoolean; - end; -end; + End; +End; {$IFDEF ZEOS80UP} - function TZRESTDWResultSet.GetBytes(ColumnIndex: Integer; - out Len: NativeUInt): PByte; - var - vBytes : TBytes; - begin - LastWasNull := IsNull(ColumnIndex); - if not LastWasNull then begin - vBytes := TBytes(FVariantTable[RowNo-1,ColumnIndex]); - Result := PByte(vBytes); - Len := Length(vBytes); - end; - end; +Function TZRESTDWResultSet.GetBytes(ColumnIndex : Integer; + Out Len : NativeUInt) : PByte; +Var + vBytes : TBytes; +Begin + Result := Nil; + Len := 0; + LastWasNull := IsNull(ColumnIndex); + + {$IFNDEF GENERIC_INDEX} + ColumnIndex := ColumnIndex - 1; + {$ENDIF} + + If (ColumnIndex < 0) Or + (ColumnIndex >= FFieldCount) Then + Raise Exception.CreateFmt('Zeos PhysLink invalid column index %d. FieldCount=%d', + [ColumnIndex, FFieldCount]); + + If Not LastWasNull Then + Begin + vBytes := TBytes(FVariantTable[RowNo-1,ColumnIndex]); + If Length(vBytes) > 0 Then + Result := @vBytes[0]; + Len := Length(vBytes); + End; +End; {$ELSE} - function TZRESTDWResultSet.GetBytes(ColumnIndex: Integer): TBytes; - var - vBytes : TBytes; - begin - LastWasNull := IsNull(ColumnIndex); +Function TZRESTDWResultSet.GetBytes(ColumnIndex : Integer) : TBytes; +Var + vBytes : TBytes; +Begin + LastWasNull := IsNull(ColumnIndex); {$IFNDEF GENERIC_INDEX} - ColumnIndex := ColumnIndex -1; + ColumnIndex := ColumnIndex -1; {$ENDIF} - if not LastWasNull then begin - vBytes := TBytes(FVariantTable[RowNo-1,ColumnIndex]); - Result := vBytes; - end; - end; + If Not LastWasNull Then + Begin + vBytes := TBytes(FVariantTable[RowNo-1,ColumnIndex]); + Result := vBytes; + End; +End; {$ENDIF} -function TZRESTDWResultSet.GetInt(ColumnIndex: Integer): Integer; -var - vInt : integer; -begin +Function TZRESTDWResultSet.GetInt(ColumnIndex : Integer) : Integer; +Var + vInt : Integer; +Begin Result := -1; LastWasNull := IsNull(ColumnIndex); {$IFNDEF GENERIC_INDEX} - ColumnIndex := ColumnIndex -1; + ColumnIndex := ColumnIndex - 1; {$ENDIF} + If (ColumnIndex < 0) Or + (ColumnIndex >= FFieldCount) Then + Raise Exception.CreateFmt('Zeos PhysLink invalid column index %d. FieldCount=%d', + [ColumnIndex, FFieldCount]); - if not LastWasNull then begin + If Not LastWasNull Then + Begin vInt := FVariantTable[RowNo-1,ColumnIndex]; Result := vInt; - end; -end; + End; +End; -function TZRESTDWResultSet.GetLong(ColumnIndex: Integer): Int64; -var +Function TZRESTDWResultSet.GetLong(ColumnIndex : Integer) : Int64; +Var vInt64 : Int64; -begin +Begin Result := -1; LastWasNull := IsNull(ColumnIndex); {$IFNDEF GENERIC_INDEX} - ColumnIndex := ColumnIndex -1; + ColumnIndex := ColumnIndex - 1; {$ENDIF} + If (ColumnIndex < 0) Or + (ColumnIndex >= FFieldCount) Then + Raise Exception.CreateFmt('Zeos PhysLink invalid column index %d. FieldCount=%d', + [ColumnIndex, FFieldCount]); - if not LastWasNull then begin + If Not LastWasNull Then + Begin vInt64 := FVariantTable[RowNo-1,ColumnIndex]; Result := vInt64; - end; -end; + End; +End; -function TZRESTDWResultSet.GetUInt(ColumnIndex: Integer): Cardinal; -begin +Function TZRESTDWResultSet.GetUInt(ColumnIndex : Integer) : Cardinal; +Begin Result := GetLong(ColumnIndex); -end; +End; {$IF Defined(RangeCheckEnabled) AND Defined(WITH_UINT64_C1118_ERROR)}{$R-}{$IFEND} -function TZRESTDWResultSet.GetULong(ColumnIndex: Integer): System.UInt64; -var +Function TZRESTDWResultSet.GetULong(ColumnIndex : Integer) : System.UInt64; +Var vInt64 : UInt64; -begin +Begin Result := 0; LastWasNull := IsNull(ColumnIndex); {$IFNDEF GENERIC_INDEX} - ColumnIndex := ColumnIndex -1; + ColumnIndex := ColumnIndex - 1; {$ENDIF} + If (ColumnIndex < 0) Or + (ColumnIndex >= FFieldCount) Then + Raise Exception.CreateFmt('Zeos PhysLink invalid column index %d. FieldCount=%d', + [ColumnIndex, FFieldCount]); - if not LastWasNull then begin + If Not LastWasNull Then + Begin vInt64 := FVariantTable[RowNo-1,ColumnIndex]; Result := vInt64; - end; -end; + End; +End; {$IF Defined(RangeCheckEnabled) AND Defined(WITH_UINT64_C1118_ERROR)}{$R+}{$IFEND} -function TZRESTDWResultSet.GetFloat(ColumnIndex: Integer): Single; -begin +Function TZRESTDWResultSet.GetFloat(ColumnIndex : Integer) : Single; +Begin Result := GetDouble(ColumnIndex); -end; +End; -procedure TZRESTDWResultSet.GetGUID(ColumnIndex: Integer; var Result: TGUID); -var - vString : string; -begin +Procedure TZRESTDWResultSet.GetGUID(ColumnIndex : Integer; Var Result : TGUID); +Var + vString : String; +Begin vString := GetString(ColumnIndex); - if not LastWasNull then - Result := StringToGUID(vString); -end; + If Not LastWasNull Then + Result := StringToGUID(vString); +End; -function TZRESTDWResultSet.GetDouble(ColumnIndex: Integer): Double; -var +Function TZRESTDWResultSet.GetDouble(ColumnIndex : Integer) : Double; +Var vDouble : Double; -begin +Begin Result := -1; LastWasNull := IsNull(ColumnIndex); {$IFNDEF GENERIC_INDEX} - ColumnIndex := ColumnIndex -1; + ColumnIndex := ColumnIndex - 1; {$ENDIF} + If (ColumnIndex < 0) Or + (ColumnIndex >= FFieldCount) Then + Raise Exception.CreateFmt('Zeos PhysLink invalid column index %d. FieldCount=%d', + [ColumnIndex, FFieldCount]); - if not LastWasNull then begin + If Not LastWasNull Then + Begin vDouble := FVariantTable[RowNo-1,ColumnIndex]; Result := vDouble; - end; -end; + End; +End; {$IFNDEF NO_ANSISTRING} -function TZRESTDWResultSet.GetAnsiString(ColumnIndex: Integer): AnsiString; -var - P: PAnsiChar; - L: NativeUInt; -begin +Function TZRESTDWResultSet.GetAnsiString(ColumnIndex : Integer) : AnsiString; +Var + P : PAnsiChar; + L : NativeUInt; +Begin P := GetPAnsiChar(ColumnIndex, L); Result := ''; - if not LastWasNull then begin + If Not LastWasNull Then + Begin FUniTemp := PRawToUnicode(P, ZFastCode.StrLen(P), zCP_UTF8); Result := ZUnicodeToRaw(FUniTemp, ZOSCodePage); - end -end; + End +End; {$ENDIF} {$IFDEF ZEOS80UP} - procedure TZRESTDWResultSet.GetBigDecimal(ColumnIndex: Integer; var Result: TBCD); - var - vCurrency : Currency; - begin - vCurrency := GetCurrency(ColumnIndex); +Procedure TZRESTDWResultSet.GetBigDecimal(ColumnIndex : Integer; Var Result : TBCD); +Var + vCurrency : Currency; +Begin + vCurrency := GetCurrency(ColumnIndex); {$IFNDEF FPC} - if not LastWasNull then - Result := CurrencyToBcd(vCurrency); + If Not LastWasNull Then + Result := CurrencyToBcd(vCurrency); {$ELSE} - if not LastWasNull then - Result := DoubleToBCD(vCurrency); + If Not LastWasNull Then + Result := DoubleToBCD(vCurrency); {$ENDIF} - end; +End; {$ELSE} - function TZRESTDWResultSet.GetBigDecimal(ColumnIndex: Integer) : Extended; - var - vCurrency : Currency; - begin - vCurrency := GetCurrency(ColumnIndex); +Function TZRESTDWResultSet.GetBigDecimal(ColumnIndex : Integer) : Extended; +Var + vCurrency : Currency; +Begin + vCurrency := GetCurrency(ColumnIndex); {$IFNDEF GENERIC_INDEX} - ColumnIndex := ColumnIndex -1; + ColumnIndex := ColumnIndex -1; {$ENDIF} - if not LastWasNull then - Result := vCurrency; - end; + If Not LastWasNull Then + Result := vCurrency; +End; {$ENDIF} -function TZRESTDWResultSet.GetCurrency(ColumnIndex: Integer): Currency; -var +Function TZRESTDWResultSet.GetCurrency(ColumnIndex : Integer) : Currency; +Var vCurrency : Currency; -begin +Begin Result := -1; LastWasNull := IsNull(ColumnIndex); {$IFNDEF GENERIC_INDEX} - ColumnIndex := ColumnIndex -1; + ColumnIndex := ColumnIndex - 1; {$ENDIF} + If (ColumnIndex < 0) Or + (ColumnIndex >= FFieldCount) Then + Raise Exception.CreateFmt('Zeos PhysLink invalid column index %d. FieldCount=%d', + [ColumnIndex, FFieldCount]); - if not LastWasNull then begin + If Not LastWasNull Then + Begin vCurrency := FVariantTable[RowNo-1,ColumnIndex]; Result := vCurrency; - end; -end; + End; +End; {$IFDEF ZEOS80UP} - procedure TZRESTDWResultSet.GetDate(ColumnIndex: Integer; var Result: TZDate); - var - vDouble : Double; - begin - vDouble := GetDouble(ColumnIndex); - if not LastWasNull then - Result := TZAnyValue.CreateWithDouble(vDouble).GetDate; - end; +Procedure TZRESTDWResultSet.GetDate(ColumnIndex : Integer; Var Result : TZDate); +Var + vDouble : Double; +Begin + vDouble := GetDouble(ColumnIndex); + If Not LastWasNull Then + Result := TZAnyValue.CreateWithDouble(vDouble).GetDate; +End; {$ELSE} - function TZRESTDWResultSet.GetDate(ColumnIndex: Integer) : TDateTime; - var - vDouble : Double; - begin - vDouble := GetDouble(ColumnIndex); - if not LastWasNull then - Result := TDateTime(vDouble); - end; +Function TZRESTDWResultSet.GetDate(ColumnIndex : Integer) : TDateTime; +Var + vDouble : Double; +Begin + vDouble := GetDouble(ColumnIndex); + If Not LastWasNull Then + Result := TDateTime(vDouble); +End; {$ENDIF} {$IFDEF ZEOS80UP} - procedure TZRESTDWResultSet.GetTime(ColumnIndex: Integer; var Result: TZTime); - var - vDouble : Double; - begin - vDouble := GetDouble(ColumnIndex); - if not LastWasNull then - Result := TZAnyValue.CreateWithDouble(vDouble).GetTime; - end; +Procedure TZRESTDWResultSet.GetTime(ColumnIndex : Integer; Var Result : TZTime); +Var + vDouble : Double; +Begin + vDouble := GetDouble(ColumnIndex); + If Not LastWasNull Then + Result := TZAnyValue.CreateWithDouble(vDouble).GetTime; +End; {$ELSE} - function TZRESTDWResultSet.GetTime(ColumnIndex: Integer) : TDateTime; - var - vDouble : Double; - begin - vDouble := GetDouble(ColumnIndex); - if not LastWasNull then - Result := TDateTime(vDouble); - end; +Function TZRESTDWResultSet.GetTime(ColumnIndex : Integer) : TDateTime; +Var + vDouble : Double; +Begin + vDouble := GetDouble(ColumnIndex); + If Not LastWasNull Then + Result := TDateTime(vDouble); +End; {$ENDIF} {$IFDEF ZEOS80UP} - procedure TZRESTDWResultSet.GetTimestamp(ColumnIndex: Integer; var Result: TZTimeStamp); - var - vDouble : Double; - begin - vDouble := GetDouble(ColumnIndex); - if not LastWasNull then - Result := TZAnyValue.CreateWithDouble(vDouble).GetTimeStamp; - end; +Procedure TZRESTDWResultSet.GetTimestamp(ColumnIndex : Integer; Var Result : TZTimeStamp); +Var + vDouble : Double; +Begin + vDouble := GetDouble(ColumnIndex); + If Not LastWasNull Then + Result := TZAnyValue.CreateWithDouble(vDouble).GetTimeStamp; +End; {$ELSE} - function TZRESTDWResultSet.GetTimestamp(ColumnIndex: Integer) : TDateTime; - var - vDouble : Double; - begin - vDouble := GetDouble(ColumnIndex); - if not LastWasNull then - Result := TDateTime(vDouble); - end; +Function TZRESTDWResultSet.GetTimestamp(ColumnIndex : Integer) : TDateTime; +Var + vDouble : Double; +Begin + vDouble := GetDouble(ColumnIndex); + If Not LastWasNull Then + Result := TDateTime(vDouble); +End; {$ENDIF} {$IFDEF ZEOS80UP} - function TZRESTDWResultSet.GetBlob(ColumnIndex: Integer; - LobStreamMode: TZLobStreamMode = lsmRead): IZBlob; - begin - LastWasNull := IsNull(ColumnIndex); - if not LastWasNull then - Result.SetBytes(TBytes(FVariantTable[RowNo-1,ColumnIndex])) - end; +Function TZRESTDWResultSet.GetBlob(ColumnIndex : Integer; + LobStreamMode : TZLobStreamMode = lsmRead) : IZBlob; +Begin + LastWasNull := IsNull(ColumnIndex); + + {$IFNDEF GENERIC_INDEX} + ColumnIndex := ColumnIndex - 1; + {$ENDIF} + + If (ColumnIndex < 0) Or + (ColumnIndex >= FFieldCount) Then + Raise Exception.CreateFmt('Zeos PhysLink invalid column index %d. FieldCount=%d', + [ColumnIndex, FFieldCount]); + + If Not LastWasNull Then + Result.SetBytes(TBytes(FVariantTable[RowNo-1,ColumnIndex])); +End; {$ELSE} - function TZRESTDWResultSet.GetBlob(ColumnIndex: Integer) : IZBlob; - var - sStr : TStringStream; - begin - LastWasNull := IsNull(ColumnIndex); +Function TZRESTDWResultSet.GetBlob(ColumnIndex : Integer) : IZBlob; +Var + sStr : TStringStream; +Begin + LastWasNull := IsNull(ColumnIndex); {$IFNDEF GENERIC_INDEX} - ColumnIndex := ColumnIndex -1; + ColumnIndex := ColumnIndex -1; {$ENDIF} - if not LastWasNull then begin - if FFieldTypes[ColumnIndex] in [dwftMemo,dwftWideMemo,dwftFmtMemo] then begin - sStr := TStringStream.Create(String(FVariantTable[RowNo-1,ColumnIndex])); - try - sStr.Position := 0; - Result := TZAbstractCLob.CreateWithStream(sStr,zCP_UTF8,ConSettings); - finally - sStr.Free; - end; - end - else begin + If Not LastWasNull Then + Begin + If FFieldTypes[ColumnIndex] in [dwftMemo,dwftWideMemo,dwftFmtMemo] Then + Begin + sStr := TStringStream.Create(String(FVariantTable[RowNo-1,ColumnIndex])); + Try + sStr.Position := 0; + Result := TZAbstractCLob.CreateWithStream(sStr,zCP_UTF8,ConSettings); + Finally + sStr.Free; + End; + End + Else + Begin {$IFNDEF FPC} {$IFDEF DELPHI2010UP} - sStr := TStringStream.Create(TBytes(FVariantTable[RowNo-1,ColumnIndex])); + sStr := TStringStream.Create(TBytes(FVariantTable[RowNo-1,ColumnIndex])); {$ELSE} - sStr := TStringStream.Create(BytesToString(TRESTDWBytes(FVariantTable[RowNo-1,ColumnIndex]))); + sStr := TStringStream.Create(BytesToString(TRESTDWBytes(FVariantTable[RowNo-1,ColumnIndex]))); {$ENDIF} {$ELSE} - sStr := TStringStream.Create(TBytes(FVariantTable[RowNo-1,ColumnIndex])); + sStr := TStringStream.Create(TBytes(FVariantTable[RowNo-1,ColumnIndex])); {$ENDIF} - try - sStr.Position := 0; - Result := TZAbstractBlob.CreateWithStream(sStr); - finally - sStr.Free; - end; - end; - end; - end; + Try + sStr.Position := 0; + Result := TZAbstractBlob.CreateWithStream(sStr); + Finally + sStr.Free; + End; + End; + End; +End; {$ENDIF} -function TZRESTDWResultSet.Next: Boolean; -begin +Function TZRESTDWResultSet.Next : Boolean; +Begin Result := False; - if Closed then - Exit; + If Closed Then + Exit; - if ((MaxRows > 0) and (RowNo >= MaxRows)) or (RowNo > FRecordCount-1) then begin - if RowNo <= LastRowNo then - RowNo := LastRowNo + 1; - Exit; - end; + If FRecordCount <= 0 Then + Exit; - if FFirstRow then begin + If FFirstRow Then + Begin FFirstRow := False; - Result := True; RowNo := 1; - LastRowNo := 1; - end - else begin - RowNo := RowNo + 1; + End + Else + RowNo := RowNo + 1; + + If ((MaxRows > 0) And (RowNo > MaxRows)) Or + (RowNo > FRecordCount) Then + Begin LastRowNo := RowNo; - Result := True; - end; -end; + Exit; + End; + + LastRowNo := RowNo; + Result := True; +End; -function TZRESTDWCachedResolver.CheckKeyColumn(ColumnIndex: Integer): Boolean; -begin +Function TZRESTDWCachedResolver.CheckKeyColumn(ColumnIndex : Integer) : Boolean; +Begin Result := (Metadata.GetTableName(ColumnIndex) <> '') - and (Metadata.GetColumnName(ColumnIndex) <> '') - and Metadata.IsSearchable(ColumnIndex) - and not (Metadata.GetColumnType(ColumnIndex) in [stUnknown, stBinaryStream]); -end; - -constructor TZRESTDWCachedResolver.Create(const Statement: IZStatement; const Metadata: IZResultSetMetadata); -var - I: Integer; -begin - inherited Create(Statement, Metadata); + And (Metadata.GetColumnName(ColumnIndex) <> '') + And Metadata.IsSearchable(ColumnIndex) + And Not (Metadata.GetColumnType(ColumnIndex) in [stUnknown, stBinaryStream]); +End; + +Constructor TZRESTDWCachedResolver.Create(Const AStatement : IZStatement; Const AMetadata : IZResultSetMetadata); +Var + I : Integer; +Begin + Inherited Create(AStatement, AMetadata); {$IFDEF ZEOS80UP} - FPlainDriver := TZRESTDWPlainDriver(Statement.GetConnection.GetIZPlainDriver.GetInstance); + FPlainDriver := TZRESTDWPlainDriver(AStatement.GetConnection.GetIZPlainDriver.GetInstance); {$ELSE} - FPlainDriver := TZRESTDWPlainDriver(Statement.GetConnection.GetIZPlainDriver); + FPlainDriver := TZRESTDWPlainDriver(AStatement.GetConnection.GetIZPlainDriver); {$ENDIF} - { Defines an index of autoincrement field. } + { Defines an index Of autoincrement field. } FAutoColumnIndex := 0; - for I := FirstDbcIndex to Metadata.GetColumnCount{$IFDEF GENERIC_INDEX} - 1{$ENDIF} do - if Metadata.IsAutoIncrement(I) and - (Metadata.GetColumnType(I) in [stByte, stShort, stSmall, stLongWord, - stInteger, stUlong, stLong]) then - begin - FAutoColumnIndex := I; - Break; - end; -end; + For I := FirstDbcIndex To AMetadata.GetColumnCount{$IFDEF GENERIC_INDEX} - 1{$ENDIF} Do + If AMetadata.IsAutoIncrement(I) And + (AMetadata.GetColumnType(I) in [stByte, stShort, stSmall, stLongWord, + stInteger, stUlong, stLong]) Then + Begin + FAutoColumnIndex := I; + Break; + End; +End; {$IFDEF ZEOS80UP} - procedure TZRESTDWCachedResolver.PostUpdates(const Sender: IZCachedResultSet; - UpdateType: TZRowUpdateType; const OldRowAccessor, NewRowAccessor: TZRowAccessor); - begin - inherited PostUpdates(Sender, UpdateType, OldRowAccessor, NewRowAccessor); - - if (UpdateType = utInserted) then - UpdateAutoIncrementFields(Sender, UpdateType, OldRowAccessor, NewRowAccessor, Self); - end; +Procedure TZRESTDWCachedResolver.PostUpdates(Const Sender : IZCachedResultSet; + UpdateType : TZRowUpdateType; Const OldRowAccessor, NewRowAccessor : TZRowAccessor); +Begin + Inherited PostUpdates(Sender, UpdateType, OldRowAccessor, NewRowAccessor); + + If (UpdateType = utInserted) Then + UpdateAutoIncrementFields(Sender, UpdateType, OldRowAccessor, NewRowAccessor, Self); +End; {$ELSE} - procedure TZRESTDWCachedResolver.PostUpdates(Sender: IZCachedResultSet; UpdateType: TZRowUpdateType; - OldRowAccessor, NewRowAccessor: TZRowAccessor); - begin - inherited PostUpdates(Sender, UpdateType, OldRowAccessor, NewRowAccessor); - - if (UpdateType = utInserted) then - UpdateAutoIncrementFields(Sender, UpdateType, OldRowAccessor, NewRowAccessor, Self); - end; +Procedure TZRESTDWCachedResolver.PostUpdates(Sender : IZCachedResultSet; UpdateType : TZRowUpdateType; + OldRowAccessor, NewRowAccessor : TZRowAccessor); +Begin + Inherited PostUpdates(Sender, UpdateType, OldRowAccessor, NewRowAccessor); + + If (UpdateType = utInserted) Then + UpdateAutoIncrementFields(Sender, UpdateType, OldRowAccessor, NewRowAccessor, Self); +End; {$ENDIF} {$IFDEF ZEOS80UP} - procedure TZRESTDWCachedResolver.UpdateAutoIncrementFields( - const Sender: IZCachedResultSet; UpdateType: TZRowUpdateType; const - OldRowAccessor, NewRowAccessor: TZRowAccessor; const Resolver: IZCachedResolver); - begin - inherited; - end; +Procedure TZRESTDWCachedResolver.UpdateAutoIncrementFields( + Const Sender : IZCachedResultSet; UpdateType : TZRowUpdateType; Const + OldRowAccessor, NewRowAccessor : TZRowAccessor; Const Resolver : IZCachedResolver); +Begin + Inherited; +End; {$ELSE} - procedure TZRESTDWCachedResolver.UpdateAutoIncrementFields(Sender: IZCachedResultSet; - UpdateType: TZRowUpdateType; OldRowAccessor, NewRowAccessor: TZRowAccessor; - Resolver: IZCachedResolver); - begin - inherited; - end; +Procedure TZRESTDWCachedResolver.UpdateAutoIncrementFields(Sender : IZCachedResultSet; + UpdateType : TZRowUpdateType; OldRowAccessor, NewRowAccessor : TZRowAccessor; + Resolver : IZCachedResolver); +Begin + Inherited; +End; {$ENDIF} { TZRESTDWResultSetMetadata } -procedure TZRESTDWResultSetMetadata.ClearColumn(ColumnInfo: TZColumnInfo); -begin - inherited; +Procedure TZRESTDWResultSetMetadata.ClearColumn(ColumnInfo : TZColumnInfo); +Begin + Inherited; ColumnInfo.ReadOnly := False; ColumnInfo.Writable := True; ColumnInfo.DefinitelyWritable := True; -end; +End; {$ENDIF ZEOS_DISABLE_RESTDW} //if set we have an empty unit -end. +End. diff --git a/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZDbcStatement.pas b/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZDbcStatement.pas index 45410d56e..fa569f8b4 100644 --- a/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZDbcStatement.pas +++ b/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZDbcStatement.pas @@ -1,6 +1,10 @@ unit uRESTDWZDbcStatement; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} + +{$IFDEF FPC} + {$DEFINE GENERIC_INDEX} +{$ENDIF} {$IFNDEF FPC} {$I ZDbc.inc} @@ -156,29 +160,32 @@ function TZAbstractRESTDWPreparedStatement.ExecuteQueryPrepared: IZResultSet; if Assigned(FOpenResultSet) then IZResultSet(FOpenResultSet).Close; - NativeResultSet := TZRESTDWResultSet.Create(Self,FDWSQL,FStream); - - NativeResultSet.SetConcurrency(rcReadOnly); + NativeResultSet := TZRESTDWResultSet.Create(Self, FDWSQL, FStream); + NativeResultSet.SetConcurrency(GetResultSetConcurrency); - if (GetResultSetConcurrency = rcUpdatable) or - (GetResultSetType <> rtForwardOnly) then - begin - { Creates a cached result set. } - CachedResolver := TZRESTDWCachedResolver.Create(Self,NativeResultSet.GetMetaData); + If GetResultSetConcurrency = rcUpdatable Then + Begin + CachedResolver := TZRESTDWCachedResolver.Create(Self, NativeResultSet.GetMetaData); {$IFDEF ZEOS80UP} - CachedResultSet := TZRESTDWCachedResultSet.Create(NativeResultSet, FDWSQL, - CachedResolver,GetConnection.GetConSettings); + CachedResultSet := TZRESTDWCachedResultSet.Create(NativeResultSet, + FDWSQL, + CachedResolver, + GetConnection.GetConSettings); {$ELSE} - CachedResultSet := TZCachedResultSet.Create(NativeResultSet, FDWSQL, - CachedResolver,GetConnection.GetConSettings); + CachedResultSet := TZCachedResultSet.Create(NativeResultSet, + FDWSQL, + CachedResolver, + GetConnection.GetConSettings); {$ENDIF} CachedResultSet.SetType(rtScrollInsensitive); CachedResultSet.SetConcurrency(GetResultSetConcurrency); - Result := CachedResultSet; - end - else + End + Else + Begin + NativeResultSet.SetType(rtForwardOnly); Result := NativeResultSet; + End; FOpenResultSet := Pointer(Result); @@ -196,6 +203,7 @@ function TZAbstractRESTDWPreparedStatement.RDWExecuteComand( exec: boolean): Integer; var vRESTDataBase : TRESTDWDatabasebaseBase; + vRESTDWConnection : IZRESTDWConnection; vParams : TParams; vError : boolean; vMessageError : string; @@ -357,7 +365,12 @@ function TZAbstractRESTDWPreparedStatement.RDWExecuteComand( BindInParameters; Prepare; - vRESTDataBase := IZRESTDWConnection(Connection).GetDatabase; + vRESTDWConnection := Connection as IZRESTDWConnection; + If vRESTDWConnection = Nil Then + Raise Exception.Create(cErrorDatabaseNotFound); + vRESTDataBase := vRESTDWConnection.GetDatabase; + If vRESTDataBase = Nil Then + Raise Exception.Create(cErrorDatabaseNotFound); vSQL := TStringList.Create; FDWSQL := getSQLWithParams; vSQL.Text := FDWSQL; @@ -370,11 +383,16 @@ function TZAbstractRESTDWPreparedStatement.RDWExecuteComand( try vRESTDataBase.ExecuteCommand(vPoolermethod, vSQL, vParams, vError, vMessageError, vDataSetList, vRowsAffected, - exec, (not exec), (not exec), False, + exec, (not exec), False, False, vRESTDataBase.RESTClientPooler); FStream.Size := 0; - if (vDataSetList <> nil) and (not vDataSetList.IsNull) then + If (vDataSetList <> Nil) And (Not vDataSetList.IsNull) Then + Begin vDataSetList.SaveToStream(FStream); + FStream.Position := 0; + End; + If (Not exec) And (FStream.Size = 0) Then + Raise Exception.Create('Zeos PhysLink returned an empty dataset stream'); finally vDataSetList.Free; end; diff --git a/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZPlainDriver.pas b/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZPlainDriver.pas index be6eb9775..7b9f390c7 100644 --- a/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZPlainDriver.pas +++ b/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZPlainDriver.pas @@ -1,6 +1,6 @@ unit uRESTDWZPlainDriver; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} {$IFNDEF FPC} {$I ZDbc.inc} diff --git a/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZToken.pas b/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZToken.pas index 7f44c9561..633df0b3a 100644 --- a/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZToken.pas +++ b/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZToken.pas @@ -1,6 +1,6 @@ unit uRESTDWZToken; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} {$IFNDEF FPC} {$I ZDbc.inc} diff --git a/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZeosPhysLink.pas b/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZeosPhysLink.pas index bfc10a034..6b2ff7cb4 100644 --- a/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZeosPhysLink.pas +++ b/CORE/Source/Database_Drivers/ZeosPhysLink/uRESTDWZeosPhysLink.pas @@ -1,6 +1,6 @@ -unit uRESTDWZeosPhysLink; +unit uRESTDWZeosPhysLink; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . @@ -32,7 +32,7 @@ interface {$ENDIF} uses - Classes, SysUtils, ZConnection, uRESTDWAbout, uRESTDWBasicDB, uRESTDWZDbc; + Classes, SysUtils, ZConnection, uRESTDWAbout, uRESTDWBasicDB, uRESTDWConsts, uRESTDWZDbc; type TRESTDWZeosPhysLink = class(TRESTDWComponent) @@ -41,32 +41,83 @@ TRESTDWZeosPhysLink = class(TRESTDWComponent) FDatabase : TRESTDWDatabasebaseBase; FOldZeosBeforeConnect : TNotifyEvent; procedure setZConnection(const Value: TZConnection); + procedure SetDatabase(Const Value : TRESTDWDatabasebaseBase); protected + procedure Notification(AComponent : TComponent; Operation : TOperation); override; procedure OnRESTDWZeosBeforeConnect(Sender : TObject); + public + Destructor Destroy; Override; published property ZConnection : TZConnection read FZConnection write setZConnection; - property Database : TRESTDWDatabasebaseBase read FDatabase write FDatabase; + property Database : TRESTDWDatabasebaseBase read FDatabase write SetDatabase; end; implementation { TRESTDWZeosPhysLink } -procedure TRESTDWZeosPhysLink.OnRESTDWZeosBeforeConnect(Sender: TObject); -begin - if Assigned(FOldZeosBeforeConnect) then - FOldZeosBeforeConnect(FZConnection); - TZRESTDWDriver(FZConnection.DbcDriver).Database := FDatabase; -end; - -procedure TRESTDWZeosPhysLink.setZConnection(const Value: TZConnection); -begin - FZConnection := Value; - FOldZeosBeforeConnect := nil; - if (FZConnection <> nil) and (ZConnection.Protocol = 'restdw') then begin - FOldZeosBeforeConnect := FZConnection.BeforeConnect; +Destructor TRESTDWZeosPhysLink.Destroy; +Begin + setZConnection(Nil); + SetDatabase(Nil); + Inherited Destroy; +End; + +procedure TRESTDWZeosPhysLink.Notification(AComponent : TComponent; Operation : TOperation); +Begin + Inherited Notification(AComponent, Operation); + If Operation = opRemove Then + Begin + If AComponent = FZConnection Then + Begin + FZConnection := Nil; + FOldZeosBeforeConnect := Nil; + End; + If AComponent = FDatabase Then + FDatabase := Nil; + End; +End; + +procedure TRESTDWZeosPhysLink.OnRESTDWZeosBeforeConnect(Sender : TObject); +Begin + If Assigned(FOldZeosBeforeConnect) Then + FOldZeosBeforeConnect(Sender); + If FDatabase = Nil Then + Raise Exception.Create(cErrorDatabaseNotFound); + If (FZConnection = Nil) Or (LowerCase(FZConnection.Protocol) <> 'restdw') Then + Exit; + SetRESTDWDriverDatabase(FDatabase); +End; + +procedure TRESTDWZeosPhysLink.SetDatabase(Const Value : TRESTDWDatabasebaseBase); +Begin + If FDatabase = Value Then + Exit; + If FDatabase <> Nil Then + FDatabase.RemoveFreeNotification(Self); + FDatabase := Value; + If FDatabase <> Nil Then + FDatabase.FreeNotification(Self); +End; + +procedure TRESTDWZeosPhysLink.setZConnection(Const Value : TZConnection); +Begin + If FZConnection = Value Then + Exit; + If FZConnection <> Nil Then + Begin + FZConnection.BeforeConnect := FOldZeosBeforeConnect; + FZConnection.RemoveFreeNotification(Self); + End; + FZConnection := Value; + FOldZeosBeforeConnect := Nil; + If FZConnection <> Nil Then + Begin + FZConnection.FreeNotification(Self); + FOldZeosBeforeConnect := FZConnection.BeforeConnect; + FZConnection.Protocol := 'restdw'; FZConnection.BeforeConnect := {$IFDEF FPC}@{$ENDIF}OnRESTDWZeosBeforeConnect; - end; -end; + End; +End; end. diff --git a/CORE/Source/Database_Drivers/uRESTDWADODriver.pas b/CORE/Source/Database_Drivers/uRESTDWADODriver.pas new file mode 100644 index 000000000..6da882085 --- /dev/null +++ b/CORE/Source/Database_Drivers/uRESTDWADODriver.pas @@ -0,0 +1,348 @@ +Unit uRESTDWADODriver; + +{$I uRESTDW.inc} + +Interface + +Uses +{$IFDEF DELPHIXE2UP} + System.Classes, System.SysUtils, Data.DB, Data.Win.ADODB, +{$ELSE} + Classes, SysUtils, DB, ADODB, +{$ENDIF} + uRESTDWDriverBase, uRESTDWBasicDbTypes, uRESTDWProtoTypes, + uRESTDWMemoryDataset; + +Type + TRESTDWADOStoreProc = Class(TRESTDWDrvStoreProc) + Public + Procedure ExecProc; Override; + Procedure Prepare; Override; + End; + + TRESTDWADOTable = Class(TRESTDWDrvTable) + Public + Procedure SaveToStream(Stream : TStream); Override; + End; + + TRESTDWADOQuery = Class(TRESTDWDrvQuery) + Private + FRowsAffected : Int64; + Public + Procedure ExecSQL; Override; + Procedure Prepare; Override; + Procedure SaveToStream(Stream : TStream); Override; + + Function RowsAffected : Int64; Override; + Function ParamCount : Integer; Override; + Function getParamDataType(IParam : Integer) : TFieldType; Override; + Function getParamName(IParam : Integer) : String; Override; + Function getParamSize(IParam : Integer) : Integer; Override; + Function getParamValue(IParam : Integer) : Variant; Override; + + Procedure setParamDataType(IParam : Integer; AValue : TFieldType); Override; + Procedure setParamValue(IParam : Integer; AValue : Variant); Override; + Procedure LoadFromStreamParam(IParam : Integer; Stream : TStream; + BlobType : TBlobType); Override; + End; + + TRESTDWADODriver = Class(TRESTDWDriverBase) + Protected + Function getConnectionType : TRESTDWDatabaseType; Override; + Function compConnIsValid(Comp : TComponent) : Boolean; Override; + Public + Function getQuery : TRESTDWDrvQuery; Override; + Function getQuery(AUnidir : Boolean) : TRESTDWDrvQuery; Override; + Function getTable : TRESTDWDrvTable; Override; + Function getStoreProc : TRESTDWDrvStoreProc; Override; + + Procedure Connect; Override; + Procedure Disconect; Override; + + Function isConnected : Boolean; Override; + Function connInTransaction : Boolean; Override; + Procedure connStartTransaction; Override; + Procedure connRollback; Override; + Procedure connCommit; Override; + + Class Procedure CreateConnection(Const AConnectionDefs : TConnectionDefs; + Var AConnection : TComponent); Override; + End; + +Procedure Register; + +Implementation + +Procedure Register; +Begin + RegisterComponents('REST Dataware - Drivers', [TRESTDWADODriver]); +End; + +Procedure TRESTDWADOStoreProc.ExecProc; +Begin + Inherited ExecProc; + TADOStoredProc(Self.Owner).ExecProc; +End; + +Procedure TRESTDWADOStoreProc.Prepare; +Begin + Inherited Prepare; + TADOStoredProc(Self.Owner).Prepared := True; +End; + +Procedure TRESTDWADOTable.SaveToStream(Stream : TStream); +Var + DataSet : TADOTable; + MemTable : TRESTDWMemtable; +Begin + DataSet := TADOTable(Self.Owner); + MemTable := TRESTDWMemtable.Create(Nil); + Try + MemTable.Assign(DataSet); + MemTable.SaveToStream(Stream); + Stream.Position := 0; + Finally + FreeAndNil(MemTable); + End; +End; + +Procedure TRESTDWADOQuery.ExecSQL; +Begin + Inherited ExecSQL; + FRowsAffected := TADOQuery(Self.Owner).ExecSQL; +End; + +Procedure TRESTDWADOQuery.Prepare; +Begin + Inherited Prepare; + TADOQuery(Self.Owner).Prepared := True; +End; + +Procedure TRESTDWADOQuery.SaveToStream(Stream : TStream); +Var + DataSet : TADOQuery; + MemTable : TRESTDWMemtable; +Begin + DataSet := TADOQuery(Self.Owner); + MemTable := TRESTDWMemtable.Create(Nil); + Try + MemTable.Assign(DataSet); + MemTable.SaveToStream(Stream); + Stream.Position := 0; + Finally + FreeAndNil(MemTable); + End; +End; + +Function TRESTDWADOQuery.RowsAffected : Int64; +Begin + Result := FRowsAffected; +End; + +Function TRESTDWADOQuery.ParamCount : Integer; +Begin + Result:=TADOQuery(Self.Owner).Parameters.Count; + If (Result=0) and (Pos(':',SQL.Text)>0) Then + Begin + Prepare; + Result:=TADOQuery(Self.Owner).Parameters.Count; + End; +End; + +Function TRESTDWADOQuery.getParamDataType(IParam : Integer) : TFieldType; +Begin + Result := TADOQuery(Self.Owner).Parameters[IParam].DataType; +End; + +Function TRESTDWADOQuery.getParamName(IParam : Integer) : String; +Begin + Result := TADOQuery(Self.Owner).Parameters[IParam].Name; +End; + +Function TRESTDWADOQuery.getParamSize(IParam : Integer) : Integer; +Begin + Result := TADOQuery(Self.Owner).Parameters[IParam].Size; +End; + +Function TRESTDWADOQuery.getParamValue(IParam : Integer) : Variant; +Begin + Result := TADOQuery(Self.Owner).Parameters[IParam].Value; +End; + +Procedure TRESTDWADOQuery.setParamDataType(IParam : Integer; AValue : TFieldType); +Begin + TADOQuery(Self.Owner).Parameters[IParam].DataType := AValue; +End; + +Procedure TRESTDWADOQuery.setParamValue(IParam : Integer; AValue : Variant); +Begin + TADOQuery(Self.Owner).Parameters[IParam].Value := AValue; +End; + +Procedure TRESTDWADOQuery.LoadFromStreamParam(IParam : Integer; Stream : TStream; + BlobType : TBlobType); +Begin + TADOQuery(Self.Owner).Parameters[IParam].LoadFromStream(Stream, TFieldType(BlobType)); +End; + +Function TRESTDWADODriver.getConnectionType : TRESTDWDatabaseType; +Begin + Result := dbtAdo; +End; + +Function TRESTDWADODriver.compConnIsValid(Comp : TComponent) : Boolean; +Begin + Result := Comp.InheritsFrom(TADOConnection); +End; + +Function TRESTDWADODriver.getQuery : TRESTDWDrvQuery; +Var + Query : TADOQuery; +Begin + Query := TADOQuery.Create(Self); + Query.Connection := TADOConnection(Connection); + Query.ParamCheck := True; + Result := TRESTDWADOQuery.Create(Query); +End; + +Function TRESTDWADODriver.getQuery(AUnidir : Boolean) : TRESTDWDrvQuery; +Begin + Result := getQuery; +End; + +Function TRESTDWADODriver.getTable : TRESTDWDrvTable; +Var + Table : TADOTable; +Begin + Table := TADOTable.Create(Self); + Table.Connection := TADOConnection(Connection); + Result := TRESTDWADOTable.Create(Table); +End; + +Function TRESTDWADODriver.getStoreProc : TRESTDWDrvStoreProc; +Var + StoreProc : TADOStoredProc; +Begin + StoreProc := TADOStoredProc.Create(Self); + StoreProc.Connection := TADOConnection(Connection); + Result := TRESTDWADOStoreProc.Create(StoreProc); +End; + +Procedure TRESTDWADODriver.Connect; +Begin + If Assigned(Connection) Then + Begin + TADOConnection(Connection).Connected := True; + End; + Inherited Connect; +End; + +Procedure TRESTDWADODriver.Disconect; +Begin + If Assigned(Connection) Then + Begin + TADOConnection(Connection).Connected := False; + End; + Inherited Disconect; +End; + +Function TRESTDWADODriver.isConnected : Boolean; +Begin + Result := Inherited isConnected; + If Assigned(Connection) Then + Begin + Result := TADOConnection(Connection).Connected; + End; +End; + +Function TRESTDWADODriver.connInTransaction : Boolean; +Begin + Result := Inherited connInTransaction; + If Assigned(Connection) Then + Begin + Result := TADOConnection(Connection).InTransaction; + End; +End; + +Procedure TRESTDWADODriver.connStartTransaction; +Begin + Inherited connStartTransaction; + If Assigned(Connection) And (Not TADOConnection(Connection).InTransaction) Then + Begin + TADOConnection(Connection).BeginTrans; + End; +End; + +Procedure TRESTDWADODriver.connRollback; +Begin + Inherited connRollback; + If Assigned(Connection) And TADOConnection(Connection).InTransaction Then + Begin + TADOConnection(Connection).RollbackTrans; + End; +End; + +Procedure TRESTDWADODriver.connCommit; +Begin + Inherited connCommit; + If Assigned(Connection) And TADOConnection(Connection).InTransaction Then + Begin + TADOConnection(Connection).CommitTrans; + End; +End; + +Class Procedure TRESTDWADODriver.CreateConnection(Const AConnectionDefs : TConnectionDefs; + Var AConnection : TComponent); +Var + Conn : TADOConnection; + ConnString : String; +Begin + Inherited CreateConnection(AConnectionDefs, AConnection); + If (Not Assigned(AConnectionDefs)) Or (Not Assigned(AConnection)) Then + Begin + Exit; + End; + Conn := TADOConnection(AConnection); + If Conn.Connected Then + Begin + Exit; + End; + Conn.LoginPrompt := False; + If Trim(AConnectionDefs.OtherDetails) <> '' Then + Begin + ConnString := AConnectionDefs.OtherDetails + End + Else + Begin + ConnString := ''; + If Trim(AConnectionDefs.DataSource) <> '' Then + Begin + ConnString := 'Data Source=' + AConnectionDefs.DataSource + ';'; + End; + If Trim(AConnectionDefs.DatabaseName) <> '' Then + Begin + ConnString := ConnString + 'Initial Catalog=' + AConnectionDefs.DatabaseName + ';'; + End; + If Trim(AConnectionDefs.Username) <> '' Then + Begin + ConnString := ConnString + 'User ID=' + AConnectionDefs.Username + ';'; + End; + If Trim(AConnectionDefs.Password) <> '' Then + Begin + ConnString := ConnString + 'Password=' + AConnectionDefs.Password + ';'; + End; + End; + If Trim(ConnString) <> '' Then + Begin + Conn.ConnectionString := ConnString; + End; +End; + +Initialization + RegisterClass(TRESTDWADODriver); + RegisterRESTDWDriverClass(TRESTDWADODriver); + +Finalization + UnregisterRESTDWDriverClass(TRESTDWADODriver); + UnRegisterClass(TRESTDWADODriver); +End. diff --git a/CORE/Source/Database_Drivers/uRESTDWADOPhysDriver.pas b/CORE/Source/Database_Drivers/uRESTDWADOPhysDriver.pas new file mode 100644 index 000000000..ae72cbd98 --- /dev/null +++ b/CORE/Source/Database_Drivers/uRESTDWADOPhysDriver.pas @@ -0,0 +1,23 @@ +Unit uRESTDWADOPhysDriver; + +{$I uRESTDW.inc} + +Interface + +Uses +{$IFDEF DELPHIXE2UP} + System.Classes, +{$ELSE} + Classes, +{$ENDIF} + uRESTDWADOPhysLink; + +Procedure Register; + +Implementation + +Procedure Register; +Begin + RegisterComponents('REST Dataware - PhysLink', [TRESTDWADOPhysLink]); +End; +End. diff --git a/CORE/Source/Database_Drivers/uRESTDWAnyDACDriver.pas b/CORE/Source/Database_Drivers/uRESTDWAnyDACDriver.pas index a1f6bc67a..d69e9fe04 100644 --- a/CORE/Source/Database_Drivers/uRESTDWAnyDACDriver.pas +++ b/CORE/Source/Database_Drivers/uRESTDWAnyDACDriver.pas @@ -1,6 +1,6 @@ unit uRESTDWAnyDACDriver; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . @@ -188,6 +188,7 @@ function TRESTDWAnyDACDriver.getQuery : TRESTDWDrvQuery; qry.FormatOptions.StrsTrim := StrsTrim; qry.FormatOptions.StrsEmpty2Null := StrsEmpty2Null; qry.FormatOptions.StrsTrim2Len := StrsTrim2Len; + qry.ResourceOptions.ParamCreate := True; Result := TRESTDWAnyDACQuery.Create(qry); end; @@ -447,12 +448,14 @@ procedure TRESTDWAnyDACQuery.LoadFromStreamParam(IParam: integer; qry.Params[IParam].LoadFromStream(stream,blobtype); end; -function TRESTDWAnyDACQuery.ParamCount: Integer; -var - qry : TADQuery; +function TRESTDWAnyDACQuery.ParamCount : Integer; begin - qry := TADQuery(Self.Owner); - Result := qry.ParamCount; + Result:=TADQuery(Self.Owner).ParamCount; + If (Result=0) and (Pos(':',SQL.Text)>0) Then + Begin + Prepare; + Result:=TADQuery(Self.Owner).ParamCount; + End; end; procedure TRESTDWAnyDACQuery.Prepare; @@ -530,4 +533,12 @@ procedure TRESTDWAnyDACTable.SaveToStream(stream: TStream); stream.Position := 0; end; +Initialization + RegisterClass(TRESTDWAnyDACDriver); + RegisterRESTDWDriverClass(TRESTDWAnyDACDriver); + +Finalization + UnregisterRESTDWDriverClass(TRESTDWAnyDACDriver); + UnRegisterClass(TRESTDWAnyDACDriver); + end. diff --git a/CORE/Source/Database_Drivers/uRESTDWApolloDBDriver.pas b/CORE/Source/Database_Drivers/uRESTDWApolloDBDriver.pas index bd69ebb63..988384306 100644 --- a/CORE/Source/Database_Drivers/uRESTDWApolloDBDriver.pas +++ b/CORE/Source/Database_Drivers/uRESTDWApolloDBDriver.pas @@ -1,6 +1,6 @@ unit uRESTDWApolloDBDriver; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . @@ -378,12 +378,14 @@ procedure TRESTDWApolloDBQuery.LoadFromStreamParam(IParam: integer; qry.Params[IParam].LoadFromStream(stream,blobtype); end; -function TRESTDWApolloDBQuery.ParamCount: Integer; -var - qry : TApolloQuery; +function TRESTDWApolloDBQuery.ParamCount : Integer; begin - qry := TApolloQuery(Self.Owner); - Result := qry.ParamCount; + Result:=TApolloQuery(Self.Owner).ParamCount; + If (Result=0) and (Pos(':',SQL.Text)>0) Then + Begin + Prepare; + Result:=TApolloQuery(Self.Owner).ParamCount; + End; end; procedure TRESTDWApolloDBQuery.Prepare; @@ -453,5 +455,13 @@ procedure TRESTDWApolloDBTable.SaveToStream(stream: TStream); end; end; +Initialization + RegisterClass(TRESTDWApolloDBDriver); + RegisterRESTDWDriverClass(TRESTDWApolloDBDriver); + +Finalization + UnregisterRESTDWDriverClass(TRESTDWApolloDBDriver); + UnRegisterClass(TRESTDWApolloDBDriver); + end. diff --git a/CORE/Source/Database_Drivers/uRESTDWDBExpressDriver.pas b/CORE/Source/Database_Drivers/uRESTDWDBExpressDriver.pas new file mode 100644 index 000000000..244e51be4 --- /dev/null +++ b/CORE/Source/Database_Drivers/uRESTDWDBExpressDriver.pas @@ -0,0 +1,386 @@ +Unit uRESTDWDBExpressDriver; + +{$I uRESTDW.inc} + +Interface + +Uses +{$IFDEF DELPHIXE2UP} + System.Classes, System.SysUtils, Data.DB, Data.SqlExpr, +{$ELSE} + Classes, SysUtils, DB, SqlExpr, +{$ENDIF} + uRESTDWDriverBase, uRESTDWBasicDbTypes, uRESTDWProtoTypes, + uRESTDWMemoryDataset; + +Type + TRESTDWDBExpressStoreProc = Class(TRESTDWDrvStoreProc) + Public + Procedure ExecProc; Override; + Procedure Prepare; Override; + End; + + TRESTDWDBExpressTable = Class(TRESTDWDrvTable) + Public + Procedure SaveToStream(Stream : TStream); Override; + End; + + TRESTDWDBExpressQuery = Class(TRESTDWDrvQuery) + Private + FRowsAffected : Int64; + Public + Procedure ExecSQL; Override; + Procedure Prepare; Override; + Procedure SaveToStream(Stream : TStream); Override; + + Function RowsAffected : Int64; Override; + Function ParamCount : Integer; Override; + Function getParamDataType(IParam : Integer) : TFieldType; Override; + Function getParamName(IParam : Integer) : String; Override; + Function getParamSize(IParam : Integer) : Integer; Override; + Function getParamValue(IParam : Integer) : Variant; Override; + + Procedure setParamDataType(IParam : Integer; AValue : TFieldType); Override; + Procedure setParamValue(IParam : Integer; AValue : Variant); Override; + Procedure LoadFromStreamParam(IParam : Integer; Stream : TStream; + BlobType : TBlobType); Override; + End; + + TRESTDWDBExpressDriver = Class(TRESTDWDriverBase) + Private + FTransaction : TTransactionDesc; + Protected + Function getConnectionType : TRESTDWDatabaseType; Override; + Function compConnIsValid(Comp : TComponent) : Boolean; Override; + Public + Constructor Create(AOwner : TComponent); Override; + + Function getQuery : TRESTDWDrvQuery; Override; + Function getQuery(AUnidir : Boolean) : TRESTDWDrvQuery; Override; + Function getTable : TRESTDWDrvTable; Override; + Function getStoreProc : TRESTDWDrvStoreProc; Override; + + Procedure Connect; Override; + Procedure Disconect; Override; + + Function isConnected : Boolean; Override; + Function connInTransaction : Boolean; Override; + Procedure connStartTransaction; Override; + Procedure connRollback; Override; + Procedure connCommit; Override; + + Class Procedure CreateConnection(Const AConnectionDefs : TConnectionDefs; + Var AConnection : TComponent); Override; + End; + +Procedure Register; + +Implementation + +Procedure Register; +Begin + RegisterComponents('REST Dataware - Drivers', [TRESTDWDBExpressDriver]); +End; + +Procedure TRESTDWDBExpressStoreProc.ExecProc; +Begin + Inherited ExecProc; + TSQLStoredProc(Self.Owner).ExecProc; +End; + +Procedure TRESTDWDBExpressStoreProc.Prepare; +Begin + Inherited Prepare; + TSQLStoredProc(Self.Owner).Prepared := True; +End; + +Procedure TRESTDWDBExpressTable.SaveToStream(Stream : TStream); +Var + DataSet : TSQLTable; + MemTable : TRESTDWMemtable; +Begin + DataSet := TSQLTable(Self.Owner); + MemTable := TRESTDWMemtable.Create(Nil); + Try + MemTable.Assign(DataSet); + MemTable.SaveToStream(Stream); + Stream.Position := 0; + Finally + FreeAndNil(MemTable); + End; +End; + +Procedure TRESTDWDBExpressQuery.ExecSQL; +Begin + Inherited ExecSQL; + FRowsAffected := TSQLQuery(Self.Owner).ExecSQL; +End; + +Procedure TRESTDWDBExpressQuery.Prepare; +Begin + Inherited Prepare; + TSQLQuery(Self.Owner).Prepared := True; +End; + +Procedure TRESTDWDBExpressQuery.SaveToStream(Stream : TStream); +Var + DataSet : TSQLQuery; + MemTable : TRESTDWMemtable; +Begin + DataSet := TSQLQuery(Self.Owner); + MemTable := TRESTDWMemtable.Create(Nil); + Try + MemTable.Assign(DataSet); + MemTable.SaveToStream(Stream); + Stream.Position := 0; + Finally + FreeAndNil(MemTable); + End; +End; + +Function TRESTDWDBExpressQuery.RowsAffected : Int64; +Begin + Result := FRowsAffected; +End; + +Function TRESTDWDBExpressQuery.ParamCount : Integer; +Begin + Result:=TSQLQuery(Self.Owner).Params.Count; + If (Result=0) and (Pos(':',SQL.Text)>0) Then + Begin + Prepare; + Result:=TSQLQuery(Self.Owner).Params.Count; + End; +End; + +Function TRESTDWDBExpressQuery.getParamDataType(IParam : Integer) : TFieldType; +Begin + Result := TSQLQuery(Self.Owner).Params[IParam].DataType; +End; + +Function TRESTDWDBExpressQuery.getParamName(IParam : Integer) : String; +Begin + Result := TSQLQuery(Self.Owner).Params[IParam].Name; +End; + +Function TRESTDWDBExpressQuery.getParamSize(IParam : Integer) : Integer; +Begin + Result := TSQLQuery(Self.Owner).Params[IParam].Size; +End; + +Function TRESTDWDBExpressQuery.getParamValue(IParam : Integer) : Variant; +Begin + Result := TSQLQuery(Self.Owner).Params[IParam].Value; +End; + +Procedure TRESTDWDBExpressQuery.setParamDataType(IParam : Integer; AValue : TFieldType); +Begin + TSQLQuery(Self.Owner).Params[IParam].DataType := AValue; +End; + +Procedure TRESTDWDBExpressQuery.setParamValue(IParam : Integer; AValue : Variant); +Begin + TSQLQuery(Self.Owner).Params[IParam].Value := AValue; +End; + +Procedure TRESTDWDBExpressQuery.LoadFromStreamParam(IParam : Integer; Stream : TStream; + BlobType : TBlobType); +Begin + TSQLQuery(Self.Owner).Params[IParam].LoadFromStream(Stream, BlobType); +End; + +Constructor TRESTDWDBExpressDriver.Create(AOwner : TComponent); +Begin + Inherited Create(AOwner); + FillChar(FTransaction, SizeOf(FTransaction), 0); + FTransaction.TransactionID := 1; + FTransaction.IsolationLevel := xilREADCOMMITTED; +End; + +Function TRESTDWDBExpressDriver.getConnectionType : TRESTDWDatabaseType; +Var + DriverName : String; +Begin + Result := Inherited getConnectionType; + If (Result <> dbtUndefined) or (Not Assigned(Connection)) Then + Begin + Exit; + End; + DriverName := LowerCase(TSQLConnection(Connection).DriverName); + If Pos('firebird', DriverName) > 0 Then + Begin + Result := dbtFirebird + End + Else If Pos('interbase', DriverName) > 0 Then + Result := dbtInterbase + Else If Pos('mysql', DriverName) > 0 Then + Result := dbtMySQL + Else If Pos('oracle', DriverName) > 0 Then + Result := dbtOracle + Else If (Pos('mssql', DriverName) > 0) or (Pos('sqlserver', DriverName) > 0) Then + Result := dbtMsSQL + Else If Pos('odbc', DriverName) > 0 Then + Result := dbtODBC; +End; + +Function TRESTDWDBExpressDriver.compConnIsValid(Comp : TComponent) : Boolean; +Begin + Result := Comp.InheritsFrom(TSQLConnection); +End; + +Function TRESTDWDBExpressDriver.getQuery : TRESTDWDrvQuery; +Var + Query : TSQLQuery; +Begin + Query := TSQLQuery.Create(Self); + Query.SQLConnection := TSQLConnection(Connection); + Query.ParamCheck := True; + Result := TRESTDWDBExpressQuery.Create(Query); +End; + +Function TRESTDWDBExpressDriver.getQuery(AUnidir : Boolean) : TRESTDWDrvQuery; +Var + Query : TSQLQuery; +Begin + Query := TSQLQuery.Create(Self); + Query.SQLConnection := TSQLConnection(Connection); + Query.ParamCheck := True; + Query.GetMetadata := False; + Result := TRESTDWDBExpressQuery.Create(Query); +End; + +Function TRESTDWDBExpressDriver.getTable : TRESTDWDrvTable; +Var + Table : TSQLTable; +Begin + Table := TSQLTable.Create(Self); + Table.SQLConnection := TSQLConnection(Connection); + Result := TRESTDWDBExpressTable.Create(Table); +End; + +Function TRESTDWDBExpressDriver.getStoreProc : TRESTDWDrvStoreProc; +Var + StoreProc : TSQLStoredProc; +Begin + StoreProc := TSQLStoredProc.Create(Self); + StoreProc.SQLConnection := TSQLConnection(Connection); + Result := TRESTDWDBExpressStoreProc.Create(StoreProc); +End; + +Procedure TRESTDWDBExpressDriver.Connect; +Begin + If Assigned(Connection) Then + Begin + TSQLConnection(Connection).Connected := True; + End; + Inherited Connect; +End; + +Procedure TRESTDWDBExpressDriver.Disconect; +Begin + If Assigned(Connection) Then + Begin + TSQLConnection(Connection).Connected := False; + End; + Inherited Disconect; +End; + +Function TRESTDWDBExpressDriver.isConnected : Boolean; +Begin + Result := Inherited isConnected; + If Assigned(Connection) Then + Begin + Result := TSQLConnection(Connection).Connected; + End; +End; + +Function TRESTDWDBExpressDriver.connInTransaction : Boolean; +Begin + Result := Inherited connInTransaction; + If Assigned(Connection) Then + Begin + Result := TSQLConnection(Connection).InTransaction; + End; +End; + +Procedure TRESTDWDBExpressDriver.connStartTransaction; +Begin + Inherited connStartTransaction; + If Assigned(Connection) And (Not TSQLConnection(Connection).InTransaction) Then + Begin + TSQLConnection(Connection).StartTransaction(FTransaction); + End; +End; + +Procedure TRESTDWDBExpressDriver.connRollback; +Begin + Inherited connRollback; + If Assigned(Connection) And TSQLConnection(Connection).InTransaction Then + Begin + TSQLConnection(Connection).Rollback(FTransaction); + End; +End; + +Procedure TRESTDWDBExpressDriver.connCommit; +Begin + Inherited connCommit; + If Assigned(Connection) And TSQLConnection(Connection).InTransaction Then + Begin + TSQLConnection(Connection).Commit(FTransaction); + End; +End; + +Class Procedure TRESTDWDBExpressDriver.CreateConnection(Const AConnectionDefs : TConnectionDefs; + Var AConnection : TComponent); +Var + Conn : TSQLConnection; +Begin + Inherited CreateConnection(AConnectionDefs, AConnection); + If (Not Assigned(AConnectionDefs)) or (Not Assigned(AConnection)) Then + Begin + Exit; + End; + Conn := TSQLConnection(AConnection); + If Conn.Connected Then + Begin + Exit; + End; + Conn.LoginPrompt := False; + If Trim(AConnectionDefs.DriverID) <> '' Then + Begin + Conn.DriverName := AConnectionDefs.DriverID; + End; + If Trim(AConnectionDefs.DatabaseName) <> '' Then + Begin + Conn.Params.Values['Database'] := AConnectionDefs.DatabaseName; + End; + If Trim(AConnectionDefs.HostName) <> '' Then + Begin + Conn.Params.Values['HostName'] := AConnectionDefs.HostName; + End; + If Trim(AConnectionDefs.Username) <> '' Then + Begin + Conn.Params.Values['User_Name'] := AConnectionDefs.Username; + End; + If Trim(AConnectionDefs.Password) <> '' Then + Begin + Conn.Params.Values['Password'] := AConnectionDefs.Password; + End; + If Trim(AConnectionDefs.Charset) <> '' Then + Begin + Conn.Params.Values['ServerCharSet'] := AConnectionDefs.Charset; + End; + If Trim(AConnectionDefs.OtherDetails) <> '' Then + Begin + Conn.Params.Text := Conn.Params.Text + AConnectionDefs.OtherDetails; + End; +End; + +Initialization + RegisterClass(TRESTDWDBExpressDriver); + RegisterRESTDWDriverClass(TRESTDWDBExpressDriver); + +Finalization + UnregisterRESTDWDriverClass(TRESTDWDBExpressDriver); + UnRegisterClass(TRESTDWDBExpressDriver); +End. diff --git a/CORE/Source/Database_Drivers/uRESTDWDBExpressPhysDriver.pas b/CORE/Source/Database_Drivers/uRESTDWDBExpressPhysDriver.pas new file mode 100644 index 000000000..4059df726 --- /dev/null +++ b/CORE/Source/Database_Drivers/uRESTDWDBExpressPhysDriver.pas @@ -0,0 +1,23 @@ +Unit uRESTDWDBExpressPhysDriver; + +{$I uRESTDW.inc} + +Interface + +Uses +{$IFDEF DELPHIXE2UP} + System.Classes, +{$ELSE} + Classes, +{$ENDIF} + uRESTDWDBExpressPhysLink; + +Procedure Register; + +Implementation + +Procedure Register; +Begin + RegisterComponents('REST Dataware - PhysLink', [TRESTDWDBExpressPhysLink]); +End; +End. diff --git a/CORE/Source/Database_Drivers/uRESTDWDriverBase.pas b/CORE/Source/Database_Drivers/uRESTDWDriverBase.pas index a70fb8ad7..47c136fd3 100644 --- a/CORE/Source/Database_Drivers/uRESTDWDriverBase.pas +++ b/CORE/Source/Database_Drivers/uRESTDWDriverBase.pas @@ -1,6 +1,6 @@ unit uRESTDWDriverBase; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . @@ -198,6 +198,9 @@ TRDWDrvParam = class(TObject) Property SQL : TStrings Read getSQL; End; { TRESTDWDriverBase } + TRESTDWDriverBase = Class; + TRESTDWDriverBaseClass = Class Of TRESTDWDriverBase; + TRESTDWDriverBase = Class(TRESTDWComponent) Private FConnection : TComponent; @@ -424,11 +427,62 @@ TRDWDrvParam = class(TObject) Property OnQueryException : TOnQueryException Read vOnQueryException Write vOnQueryException; End; +Procedure RegisterRESTDWDriverClass(AClass : TRESTDWDriverBaseClass); +Procedure UnregisterRESTDWDriverClass(AClass : TRESTDWDriverBaseClass); +Function FindRESTDWDriverClass(AConnection : TComponent) : TRESTDWDriverBaseClass; + Implementation Uses uRESTDWBasicDB; +Var + GRESTDWDriverClasses : TList; + +Procedure RegisterRESTDWDriverClass(AClass : TRESTDWDriverBaseClass); +Begin + If AClass = Nil Then + Exit; + If GRESTDWDriverClasses = Nil Then + GRESTDWDriverClasses := TList.Create; + If GRESTDWDriverClasses.IndexOf(Pointer(AClass)) < 0 Then + GRESTDWDriverClasses.Add(Pointer(AClass)); +End; + +Procedure UnregisterRESTDWDriverClass(AClass : TRESTDWDriverBaseClass); +Begin + If (GRESTDWDriverClasses = Nil) Or (AClass = Nil) Then + Exit; + GRESTDWDriverClasses.Remove(Pointer(AClass)); +End; + +Function FindRESTDWDriverClass(AConnection : TComponent) : TRESTDWDriverBaseClass; +Var + I : Integer; + D : TRESTDWDriverBase; + C : TRESTDWDriverBaseClass; +Begin + Result := Nil; + If AConnection = Nil Then + Exit; + If GRESTDWDriverClasses = Nil Then + Exit; + For I := 0 To GRESTDWDriverClasses.Count - 1 Do + Begin + C := TRESTDWDriverBaseClass(GRESTDWDriverClasses[I]); + D := C.Create(Nil); + Try + If D.compConnIsValid(AConnection) Then + Begin + Result := C; + Exit; + End; + Finally + D.Free; + End; + End; +End; + { TRESTDWDrvStoreProc } Function FixFieldName(FieldName : String) : String; @@ -725,27 +779,22 @@ procedure TRESTDWDrvDataset.ExecProc; End; -procedure TRESTDWDrvDataset.SaveToStreamCompatibleMode(stream: TStream); -var - qry : TDataSet; - stor : TRESTDWStorageBin; -begin - qry := TDataSet(Self.Owner); - if FStorageDataType = nil then begin - stor := TRESTDWStorageBin.Create(nil); - {$IFDEF FPC} - stor.DatabaseCharSet := DatabaseCharSet; - {$ENDIF} - try - stor.EncodeStrs := False; - stor.SaveToStream(qry, stream); - finally - stor.Free; - end; - end - else - FStorageDataType.SaveToStream(qry,stream); -end; +Procedure TRESTDWDrvDataset.SaveToStreamCompatibleMode(Stream : TStream); +Var + Query : TDataSet; + Storage : TRESTDWStorageBin; +Begin + Query := TDataSet(Self.Owner); + Storage := TRESTDWStorageBin.Create(Nil); + {$IFDEF FPC} + Storage.DatabaseCharSet := DatabaseCharSet; + {$ENDIF} + Try + Storage.SaveDatasetToStream(Query, Stream); + Finally + Storage.Free; + End; +End; procedure TRESTDWDrvDataset.setParamDataType(IParam: integer; AValue: TFieldType); @@ -2884,7 +2933,6 @@ procedure TRESTDWDriverBase.GetTableNames(var TableNames : TStringList; var Erro Begin If Not Assigned(TableNames) Then TableNames := TStringList.Create; - TableNames.Sorted := True; vSchema := ''; { @@ -2948,6 +2996,8 @@ procedure TRESTDWDriverBase.GetTableNames(var TableNames : TStringList; var Erro End; End; + If Not Assigned(qry) Then + Exit; While Not qry.Eof Do Begin vTable := Trim(qry.Fields[fdPos].AsString); @@ -2956,7 +3006,8 @@ procedure TRESTDWDriverBase.GetTableNames(var TableNames : TStringList; var Erro qry.Next; End; Finally - FreeAndNil(qry); + If Assigned(qry) Then + FreeAndNil(qry); End; If Not vStateResource Then Disconect; @@ -3045,6 +3096,8 @@ procedure TRESTDWDriverBase.GetFieldNames(TableName : String; var FieldNames : T qry.Open; End; End; + If Not Assigned(qry) Then + Exit; While Not qry.Eof Do Begin sFields := Trim(qry.Fields[fPos].AsString); @@ -3215,7 +3268,8 @@ procedure TRESTDWDriverBase.GetKeyFieldNames(TableName : String; var FieldNames end; End; Finally - FreeAndNil(qry); + If Assigned(qry) Then + FreeAndNil(qry); End; If Not vStateResource Then Disconect; @@ -3289,6 +3343,8 @@ procedure TRESTDWDriverBase.GetProcNames(var ProcNames : TStringList; var Error qry.Open; End; End; + If Not Assigned(qry) Then + Exit; While Not qry.Eof Do Begin sProcs := Trim(qry.Fields[fPos].AsString); @@ -3297,7 +3353,8 @@ procedure TRESTDWDriverBase.GetProcNames(var ProcNames : TStringList; var Error qry.Next; End; Finally - FreeAndNil(qry); + If Assigned(qry) Then + FreeAndNil(qry); End; If Not vStateResource Then Disconect; @@ -3643,7 +3700,8 @@ procedure TRESTDWDriverBase.GetProcParams(ProcName : String; var ParamNames : TS End; End; Finally - FreeAndNil(qry); + If Assigned(qry) Then + FreeAndNil(qry); End; If Not vStateResource Then Disconect; @@ -3861,7 +3919,7 @@ function TRESTDWDriverBase.OpenDatasets( Error := False; BufferInStream := TRESTDWBufferBase.Create; BufferOutStream := TRESTDWBufferBase.Create; - vTempQuery := getQuery(True); + vTempQuery := getQuery(False); Try BufferInStream.LoadToStream(DatapackStream); vStateResource := isConnected; @@ -3902,10 +3960,15 @@ function TRESTDWDriverBase.OpenDatasets( vTempQuery.Open; vStream := TMemoryStream.Create; Try - {$IFDEF FPC} - vTempQuery.DatabaseCharSet := DatabaseCharSet; - {$ENDIF} - vTempQuery.SaveToStreamCompatibleMode(vStream); + If Not aBinaryCompatibleMode Then + vTempQuery.SaveToStream(vStream) + Else + Begin + {$IFDEF FPC} + vTempQuery.DatabaseCharSet := DatabaseCharSet; + {$ENDIF} + vTempQuery.SaveToStreamCompatibleMode(vStream); + End; vStream.Position := 0; BufferOutStream.InputStream(vStream); Finally @@ -5186,4 +5249,9 @@ procedure TRDWDrvParam.setValue(const AValue: Variant); FDrvDataset.setParamValue(FIdxParam,AValue); end; +Initialization + +Finalization + FreeAndNil(GRESTDWDriverClasses); + end. diff --git a/CORE/Source/Database_Drivers/uRESTDWFireDACDriver.pas b/CORE/Source/Database_Drivers/uRESTDWFireDACDriver.pas index 6dba2ec39..4ba4257e4 100644 --- a/CORE/Source/Database_Drivers/uRESTDWFireDACDriver.pas +++ b/CORE/Source/Database_Drivers/uRESTDWFireDACDriver.pas @@ -1,6 +1,6 @@ unit uRESTDWFireDACDriver; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . @@ -469,12 +469,14 @@ procedure TRESTDWFireDACQuery.LoadFromStreamParam(IParam: integer; qry.Params[IParam].LoadFromStream(stream,blobtype); end; -function TRESTDWFireDACQuery.ParamCount: Integer; -var - qry : TFDQuery; +function TRESTDWFireDACQuery.ParamCount : Integer; begin - qry := TFDQuery(Self.Owner); - Result := qry.ParamCount; + Result:=TFDQuery(Self.Owner).ParamCount; + If (Result=0) and (Pos(':',SQL.Text)>0) Then + Begin + Prepare; + Result:=TFDQuery(Self.Owner).ParamCount; + End; end; procedure TRESTDWFireDACQuery.Prepare; @@ -550,5 +552,13 @@ procedure TRESTDWFireDACTable.SaveToStream(stream: TStream); stream.Position := 0; end; +Initialization + RegisterClass(TRESTDWFireDACDriver); + RegisterRESTDWDriverClass(TRESTDWFireDACDriver); + +Finalization + UnregisterRESTDWDriverClass(TRESTDWFireDACDriver); + UnRegisterClass(TRESTDWFireDACDriver); + end. diff --git a/CORE/Source/Database_Drivers/uRESTDWIBDACDriver.pas b/CORE/Source/Database_Drivers/uRESTDWIBDACDriver.pas index 10c4f18d1..24babc388 100644 --- a/CORE/Source/Database_Drivers/uRESTDWIBDACDriver.pas +++ b/CORE/Source/Database_Drivers/uRESTDWIBDACDriver.pas @@ -1,6 +1,6 @@ unit uRESTDWIBDACDriver; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . @@ -337,11 +337,13 @@ function TRESTDWIBDACQuery.RowsAffected : Int64; end; function TRESTDWIBDACQuery.ParamCount : Integer; -var - qry : TIbcQuery; begin - qry := TIbcQuery(Self.Owner); - Result := qry.ParamCount; + Result:=TIbcQuery(Self.Owner).ParamCount; + If (Result=0) and (Pos(':',SQL.Text)>0) Then + Begin + Prepare; + Result:=TIbcQuery(Self.Owner).ParamCount; + End; end; function TRESTDWIBDACQuery.getParamDataType(IParam : integer) : TFieldType; @@ -450,5 +452,13 @@ initialization {$I ..\RESTDWLazarusDrivers.lrs} {$ENDIF} +Initialization + RegisterClass(TRESTDWIBDACDriver); + RegisterRESTDWDriverClass(TRESTDWIBDACDriver); + +Finalization + UnregisterRESTDWDriverClass(TRESTDWIBDACDriver); + UnRegisterClass(TRESTDWIBDACDriver); + end. diff --git a/CORE/Source/Database_Drivers/uRESTDWInterbaseDriver.pas b/CORE/Source/Database_Drivers/uRESTDWInterbaseDriver.pas index 55d86b5dd..4df8345c9 100644 --- a/CORE/Source/Database_Drivers/uRESTDWInterbaseDriver.pas +++ b/CORE/Source/Database_Drivers/uRESTDWInterbaseDriver.pas @@ -1,6 +1,6 @@ unit uRESTDWInterbaseDriver; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . @@ -186,12 +186,14 @@ procedure TRESTDWInterbaseQuery.LoadFromStreamParam(IParam: integer; qry.Params[IParam].LoadFromStream(stream,blobtype); end; -function TRESTDWInterbaseQuery.ParamCount: Integer; -var - qry : TIBQuery; +function TRESTDWInterbaseQuery.ParamCount : Integer; begin - qry := TIBQuery(Self.Owner); - Result := qry.ParamCount; + Result:=TIBQuery(Self.Owner).ParamCount; + If (Result=0) and (Pos(':',SQL.Text)>0) Then + Begin + Prepare; + Result:=TIBQuery(Self.Owner).ParamCount; + End; end; procedure TRESTDWInterbaseQuery.Prepare; @@ -442,5 +444,13 @@ procedure TRESTDWInterbaseTable.SaveToStream(stream: TStream); end; end; +Initialization + RegisterClass(TRESTDWInterbaseDriver); + RegisterRESTDWDriverClass(TRESTDWInterbaseDriver); + +Finalization + UnregisterRESTDWDriverClass(TRESTDWInterbaseDriver); + UnRegisterClass(TRESTDWInterbaseDriver); + end. diff --git a/CORE/Source/Database_Drivers/uRESTDWLazarusDriver.pas b/CORE/Source/Database_Drivers/uRESTDWLazarusDriver.pas index d248e1e6d..032138558 100644 --- a/CORE/Source/Database_Drivers/uRESTDWLazarusDriver.pas +++ b/CORE/Source/Database_Drivers/uRESTDWLazarusDriver.pas @@ -166,11 +166,13 @@ function TRESTDWLazSQLQuery.RowsAffected: Int64; end; function TRESTDWLazSQLQuery.ParamCount : Integer; -var - qry : TSQLQuery; begin - qry := TSQLQuery(Self.Owner); - Result := qry.Params.Count; + Result:=TSQLQuery(Self.Owner).Params.Count; + If (Result=0) and (Pos(':',SQL.Text)>0) Then + Begin + Prepare; + Result:=TSQLQuery(Self.Owner).Params.Count; + End; end; function TRESTDWLazSQLQuery.getParamDataType(IParam : integer) : TFieldType; @@ -266,15 +268,26 @@ function TRESTDWLazarusDriver.getConnectionType: TRESTDWDatabaseType; end; function TRESTDWLazarusDriver.getQuery : TRESTDWDrvQuery; -var - qry : TSQLQuery; -begin - qry := TSQLQuery.Create(Self); - qry.SQLConnection := TSQLConnection(Connection); - qry.Transaction := FTransaction; - - Result := TRESTDWLazSQLQuery.Create(qry); -end; +Var + Query : TSQLQuery; + LConnection : TSQLConnection; + LTransaction : TSQLTransaction; +Begin + LConnection := TSQLConnection(Connection); + LTransaction := Nil; + If LConnection <> Nil Then + Begin + LTransaction := LConnection.Transaction; + End; + If LTransaction = Nil Then + Begin + LTransaction := FTransaction; + End; + Query := TSQLQuery.Create(Self); + Query.SQLConnection := LConnection; + Query.Transaction := LTransaction; + Result := TRESTDWLazSQLQuery.Create(Query); +End; procedure TRESTDWLazarusDriver.Connect; begin @@ -284,11 +297,27 @@ procedure TRESTDWLazarusDriver.Connect; end; procedure TRESTDWLazarusDriver.Disconect; -begin - if Assigned(Connection) then - TSQLConnection(Connection).Close; - inherited Disconect; -end; +Var + LTransaction : TSQLTransaction; +Begin + LTransaction := Nil; + If Assigned(Connection) Then + Begin + LTransaction := TSQLConnection(Connection).Transaction; + End; + If LTransaction = Nil Then + Begin + LTransaction := FTransaction; + End; + If LTransaction <> Nil Then + Begin + If LTransaction.Active Then + Begin + LTransaction.Rollback; + End; + End; + Inherited Disconect; +End; constructor TRESTDWLazarusDriver.Create(AOwner : TComponent); begin @@ -311,19 +340,68 @@ function TRESTDWLazarusDriver.isConnected: boolean; end; function TRESTDWLazarusDriver.connInTransaction: boolean; -begin - Result := FTransaction.Active; -end; +Var + LTransaction : TSQLTransaction; +Begin + Result := False; + LTransaction := Nil; + If Assigned(Connection) Then + Begin + LTransaction := TSQLConnection(Connection).Transaction; + End; + If LTransaction = Nil Then + Begin + LTransaction := FTransaction; + End; + If LTransaction <> Nil Then + Begin + Result := LTransaction.Active; + End; +End; procedure TRESTDWLazarusDriver.connStartTransaction; -begin - FTransaction.StartTransaction; -end; +Var + LTransaction : TSQLTransaction; +Begin + LTransaction := Nil; + If Assigned(Connection) Then + Begin + LTransaction := TSQLConnection(Connection).Transaction; + End; + If LTransaction = Nil Then + Begin + LTransaction := FTransaction; + End; + If LTransaction <> Nil Then + Begin + If Not LTransaction.Active Then + Begin + LTransaction.StartTransaction; + End; + End; +End; procedure TRESTDWLazarusDriver.connRollback; -begin - FTransaction.Rollback; -end; +Var + LTransaction : TSQLTransaction; +Begin + LTransaction := Nil; + If Assigned(Connection) Then + Begin + LTransaction := TSQLConnection(Connection).Transaction; + End; + If LTransaction = Nil Then + Begin + LTransaction := FTransaction; + End; + If LTransaction <> Nil Then + Begin + If LTransaction.Active Then + Begin + LTransaction.Rollback; + End; + End; +End; function TRESTDWLazarusDriver.compConnIsValid(comp: TComponent): boolean; begin @@ -331,9 +409,26 @@ function TRESTDWLazarusDriver.compConnIsValid(comp: TComponent): boolean; end; procedure TRESTDWLazarusDriver.connCommit; -begin - FTransaction.Commit; -end; +Var + LTransaction : TSQLTransaction; +Begin + LTransaction := Nil; + If Assigned(Connection) Then + Begin + LTransaction := TSQLConnection(Connection).Transaction; + End; + If LTransaction = Nil Then + Begin + LTransaction := FTransaction; + End; + If LTransaction <> Nil Then + Begin + If LTransaction.Active Then + Begin + LTransaction.Commit; + End; + End; +End; class procedure TRESTDWLazarusDriver.CreateConnection(const AConnectionDefs: TConnectionDefs; var AConnection: TComponent); @@ -416,8 +511,14 @@ class procedure TRESTDWLazarusDriver.CreateConnection(const AConnectionDefs: TCo end; end; -initialization -{$I ..\RESTDWLazarusDrivers.lrs} +Initialization +{$I ..\..\Packages\Lazarus\Drivers\RESTDWLazarusDrivers.lrs} + RegisterClass(TRESTDWLazarusDriver); + RegisterRESTDWDriverClass(TRESTDWLazarusDriver); + +Finalization + UnregisterRESTDWDriverClass(TRESTDWLazarusDriver); + UnRegisterClass(TRESTDWLazarusDriver); end. diff --git a/CORE/Source/Database_Drivers/uRESTDWMyDACDriver.pas b/CORE/Source/Database_Drivers/uRESTDWMyDACDriver.pas index 043b34f3c..168b20f44 100644 --- a/CORE/Source/Database_Drivers/uRESTDWMyDACDriver.pas +++ b/CORE/Source/Database_Drivers/uRESTDWMyDACDriver.pas @@ -1,6 +1,6 @@ unit uRESTDWMyDACDriver; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . @@ -334,11 +334,13 @@ function TRESTDWMyDACQuery.RowsAffected : Int64; end; function TRESTDWMyDACQuery.ParamCount : Integer; -var - qry : TMyQuery; begin - qry := TMyQuery(Self.Owner); - Result := qry.ParamCount; + Result:=TMyQuery(Self.Owner).ParamCount; + If (Result=0) and (Pos(':',SQL.Text)>0) Then + Begin + Prepare; + Result:=TMyQuery(Self.Owner).ParamCount; + End; end; function TRESTDWMyDACQuery.getParamDataType(IParam : integer) : TFieldType; @@ -447,5 +449,13 @@ initialization {$I ..\RESTDWLazarusDrivers.lrs} {$ENDIF} +Initialization + RegisterClass(TRESTDWMyDACDriver); + RegisterRESTDWDriverClass(TRESTDWMyDACDriver); + +Finalization + UnregisterRESTDWDriverClass(TRESTDWMyDACDriver); + UnRegisterClass(TRESTDWMyDACDriver); + end. diff --git a/CORE/Source/Database_Drivers/uRESTDWNativeDriver.lrs b/CORE/Source/Database_Drivers/uRESTDWNativeDriver.lrs new file mode 100644 index 000000000..9a8f8c92e --- /dev/null +++ b/CORE/Source/Database_Drivers/uRESTDWNativeDriver.lrs @@ -0,0 +1,47 @@ +LazarusResources.Add('TRESTDWNativeDriver','PNG',[ + #137#80#78#71#13#10#26#10#0#0#0#13#73#72#68#82#0#0#0#24#0#0#0#24#8#6#0#0#0#224#119#61#248#0#0#5#20#73#68#65 + +#84#120#218#213#86#91#108#84#69#24#254#102#206#217#115#118#183#221#45#108#43#189#110#183#181#180#148#133#80 + +#109#165#4#21#10#148#84#170#144#16#77#193#164#138#137#98#99#20#77#140#65#120#168#20#30#84#8#241#65#13#42#137 + +#137#33#193#11#160#177#53#21#9#18#17#138#37#180#22#90#148#26#232#5#122#219#237#46#221#109#247#118#206#217#203 + +#153#241#129#210#84#210#2#190#152#56#201#36#147#73#102#190#255#251#231#255#191#111#128#255#251#16#102#216#35 + +#64#141#224#116#34#169#120#217#154#195#198#156#146#215#222#219#185#237#203#62#141#238#78#90#92#185#127#142 + +#168#180#228#90#197#92#199#170#77#223#107#162#173#208#105#183#157#113#187#221#4#0#255#183#160#25#91#246#29 + +#230#5#239#116#115#80#227#142#130#93#159#117#217#14#134#57#48#127#231#210#202#117#77#85#205#156#163#232#149 + +#225#127#6#118#47#6#101#101#134#134#186#175#112#166#245#219#69#249#57#142#189#148#210#34#223#149#243#220#172 + +#14#85#201#156#167#211#161#30#102#26#239#89#27#19#18#5#62#183#23#162#167#131#88#165#136#33#167#168#184#103 + +#172#168#78#69#30#40#6#6#24#102#65#157#162#185#252#177#149#215#87#237#58#152#215#169#153#152#74#40#229#82#18 + +#167#137#56#244#40#35#81#152#161#132#21#8#193#49#104#154#200#70#58#46#83#156#172#63#18#242#247#62#59#19#3#113 + +#250#229#149#85#85#117#35#99#222#21#25#203#86#219#191#75#41#214#175#13#106#2#168#8#36#18#4#190#113#96#34#0 + +#104#35#128#53#25#16#211#0#191#78#16#48#37#230#202#242#147#37#27#54#30#240#245#186#126#30#254#171#173#17#0#5 + +#192#48#185#0#0#158#34#35#79#91#176#250#160#92#123#228#57#87#194#72#85#133#9#116#184#11#226#175#77#16#218#207 + +#2#193#49#192#175#2#94#5#226#165#159#32#186#218#64#69#129#128#66#100#25#78#139#119#197#39#175#186#34#230#183 + +#0#0#53#71#201#29#12#56#89#110#79#245#183#182#156#105#14#54#93#88#179#172#186#216#200#40#37#108#60#0#102#205 + +#67#250#194#5#168#113#80#148#62#96#192#190#111#130#184#22#212#65#92#227#64#65#24#48#201#136#250#60#145#224 + +#167#219#46#155#34#195#63#42#0#112#108#211#84#69#77#50#32#252#68#175#63#24#236#60#177#161#116#162#113#59#53 + +#27#169#168#67#135#98#64#118#90#14#206#63#45#226#227#245#50#182#148#11#56#85#111#70#117#129#10#230#19#96#16 + +#84#14#22#209#45#18#137#238#216#40#108#81#124#189#123#29#21#21#198#233#37#43#2#0#231#156#20#22#22#74#243#156 + +#143#124#20#54#90#170#163#68#230#130#6#10#164#224#249#82#25#249#153#70#184#20#32#160#49#196#96#194#198#154 + +#114#92#232#62#142#128#26#38#80#71#4#109#124#192#118#252#119#203#135#73#182#236#83#19#127#246#8#41#142#146 + +#207#3#3#93#19#83#0#132#16#94#0#204#243#47#175#169#243#102#175#69#106#184#157#171#42#8#110#184#48#135#230#35 + +#198#1#53#202#160#196#57#70#38#116#196#164#20#64#180#48#221#231#37#150#209#223#218#179#230#8#111#222#84#208 + +#25#241#143#40#0#0#159#11#119#164#8#232#229#124#228#250#233#31#182#250#63#168#109#148#88#20#122#20#28#76#195 + +#217#126#134#56#99#16#40#16#86#56#230#38#9#184#216#54#8#223#160#135#200#158#75#228#225#12#182#245#106#95#95 + +#171#187#163#89#153#169#76#111#3#80#66#8#203#198#205#182#37#25#116#76#55#72#224#50#56#36#21#167#59#135#240 + +#122#19#195#185#27#20#55#35#34#26#219#52#120#220#163#64#98#136#112#8#112#13#244#232#183#26#182#129#222#173#15 + +#152#17#176#47#120#234#229#203#182#146#149#248#229#98#27#11#41#160#200#201#129#22#188#130#47#14#244#227#139 + +#212#44#88#12#12#161#139#173#64#104#16#88#92#9#22#233#134#168#185#41#0#29#13#160#216#51#59#0#74#237#169#122 + +#215#80#200#239#185#122#222#150#238#96#132#251#117#192#98#135#37#77#6#149#7#160#105#189#136#120#71#97#156#111 + +#66#220#82#13#221#86#8#218#214#2#57#51#151#163#223#51#171#176#77#117#114#235#144#207#53#47#120#104#105#166#26 + +#120#38#102#175#127#159#17#1#224#105#130#150#244#32#132#197#143#50#61#20#162#130#206#192#136#164#179#80#136 + +#66#229#132#152#211#33#89#165#187#42#231#109#0#14#128#120#3#129#126#0#251#147#207#53#63#129#97#107#37#13#41 + +#44#6#70#145#96#20#49#13#160#18#32#152#5#196#227#32#9#32#30#106#225#190#34#51#185#27#192#244#135#225#147#234 + +#42#46#76#51#108#182#156#126#251#141#252#210#20#93#178#36#51#219#149#119#175#89#157#134#40#45#43#215#141#93 + +#245#167#76#89#225#62#67#177#25#70#223#57#98#180#175#214#0#8#216#211#77#38#53#141#204#6#0#0#58#0#214#222#222 + +#238#43#47#95#119#200#219#235#17#17#14#210#98#171#173#22#113#249#18#25#29#18#68#99#242#110#46#165#158#68#56 + +#128#236#130#69#170#123#240#143#162#91#231#142#233#147#65#222#151#241#208#134#134#6#49#55#53#165#50#55#43#125 + +#61#0#100#39#25#150#100#165#89#55#195#233#148#210#128#76#51#80#242#208#227#107#156#166#236#162#175#169#109 + +#254#75#152#235#204#133#173#214#138#212#23#45#184#151#11#205#108#163#51#71#86#225#112#24#59#194#236#5#206#244 + +#188#4#53#231#113#34#140#197#198#180#237#192#128#118#31#247#214#8#183#230#237#116#86#76#247#15#122#103#138 + +#235#234#202#12#71#143#214#8#255#233#175#226#111#217#161#36#207#101#67#234#63#0#0#0#0#73#69#78#68#174#66#96 + +#130 +]); diff --git a/CORE/Source/Database_Drivers/uRESTDWNativeDriver.pas b/CORE/Source/Database_Drivers/uRESTDWNativeDriver.pas new file mode 100644 index 000000000..4aebb4b2e --- /dev/null +++ b/CORE/Source/Database_Drivers/uRESTDWNativeDriver.pas @@ -0,0 +1,315 @@ +Unit uRESTDWNativeDriver; + +{$I uRESTDW.inc} + +{$IFDEF FPC} + {$MODE OBJFPC}{$H+} +{$ENDIF} + +Interface + +Uses + Classes, DB, SysUtils, +{$IFDEF FPC} + LResources, +{$ENDIF} +uRESTDWDriverBase, uRESTDWBasicDbTypes, + uRESTDWParams, uRESTDWJSONInterface, uRESTDWTools, uRESTDWProtoTypes, uRESTDWConsts; + +Type + TRESTDWNativeLink = Class(TComponent) +{$IFDEF RESTDWLAZARUS} + Private + FDatabaseCharSet : TDatabaseCharSet; +{$ENDIF} + Protected + Function GetConnection : TComponent; Virtual; Abstract; + Public + Function GetQuery : TRESTDWDrvQuery; Virtual; + Function IsConnected : Boolean; Virtual; Abstract; + Procedure Connect; Virtual; Abstract; + Procedure Disconnect; Virtual; Abstract; + Procedure ExecuteSelect(Const ASQL : String; AParams : TRESTDWParams; + AOutput : TStream; ACompress : Boolean); Overload; Virtual; Abstract; + Procedure ExecuteSelect(Const ASQL : String; AParams : TRESTDWParams; + AOutput : TStream; ACompress : Boolean; + ABinaryCompatibleMode : Boolean); Overload; Virtual; + Function ExecuteCommand(Const ASQL : String; AParams : TRESTDWParams) : Int64; Virtual; Abstract; + Property Connection : TComponent Read GetConnection; +{$IFDEF RESTDWLAZARUS} + Published + Property DatabaseCharSet : TDatabaseCharSet Read FDatabaseCharSet Write FDatabaseCharSet Default csUndefined; +{$ENDIF} + End; + + TRESTDWNativeDriver = Class(TRESTDWDriverBase) + Private + FBlobCompression : Boolean; + FNativeLink : TRESTDWNativeLink; + Procedure SetNativeLink(AValue : TRESTDWNativeLink); + Protected + Property Connection; + Procedure Notification(AComponent : TComponent; Operation : TOperation); Override; + Public + Constructor Create(AOwner : TComponent); Override; + Function getConnectionType : TRESTDWDatabaseType; Override; + Function getQuery : TRESTDWDrvQuery; Override; + Function getQuery(AUnidir : Boolean) : TRESTDWDrvQuery; Override; + Function getTable : TRESTDWDrvTable; Override; + Function getStoreProc : TRESTDWDrvStoreProc; Override; + Function compConnIsValid(AConnection : TComponent) : Boolean; Override; + Function ConnectionSet : Boolean; Override; + Function isConnected : Boolean; Override; + Procedure Connect; Override; + Procedure Disconect; Override; + Function connInTransaction : Boolean; Override; + Procedure connStartTransaction; Override; + Procedure connCommit; Override; + Procedure connRollback; Override; + Function ExecuteCommand(SQL : String; Var Error : Boolean; Var MessageError : String; + Var BinaryBlob : TMemoryStream; Var RowsAffected : Integer; Execute : Boolean = False; + BinaryEvent : Boolean = False; MetaData : Boolean = False; + BinaryCompatibleMode : Boolean = False) : String; Overload; Override; + Function ExecuteCommand(SQL : String; Params : TRESTDWParams; Var Error : Boolean; + Var MessageError : String; Var BinaryBlob : TMemoryStream; Var RowsAffected : Integer; + Execute : Boolean = False; BinaryEvent : Boolean = False; MetaData : Boolean = False; + BinaryCompatibleMode : Boolean = False) : String; Overload; Override; + Procedure ExecuteNativeSelect(Const ASQL : String; AParams : TRESTDWParams; Var AStream : TStream); Virtual; + Function ExecuteNativeCommand(Const ASQL : String; AParams : TRESTDWParams) : Int64; Virtual; + Published + Property ConnectionType; + Property NativeLink : TRESTDWNativeLink Read FNativeLink Write SetNativeLink; + Property BlobCompression : Boolean Read FBlobCompression Write FBlobCompression; + End; + +Procedure Register; + +Implementation + +Function TRESTDWNativeLink.GetQuery : TRESTDWDrvQuery; +Begin + Result := Nil; +End; + +Procedure TRESTDWNativeLink.ExecuteSelect(Const ASQL : String; AParams : TRESTDWParams; + AOutput : TStream; ACompress : Boolean; + ABinaryCompatibleMode : Boolean); +Begin + ExecuteSelect(ASQL, AParams, AOutput, ACompress); +End; + +Constructor TRESTDWNativeDriver.Create(AOwner : TComponent); +Begin + Inherited Create(AOwner); + FBlobCompression := False; + FNativeLink := Nil; +End; + +Procedure TRESTDWNativeDriver.SetNativeLink(AValue : TRESTDWNativeLink); +Begin + If FNativeLink = AValue Then + Exit; + If FNativeLink <> Nil Then + FNativeLink.RemoveFreeNotification(Self); + FNativeLink := AValue; + If FNativeLink <> Nil Then + Begin + FNativeLink.FreeNotification(Self); + {$IFDEF RESTDWLAZARUS} + FNativeLink.DatabaseCharSet := DatabaseCharSet; + {$ENDIF} + End; +End; + +Procedure TRESTDWNativeDriver.Notification(AComponent : TComponent; Operation : TOperation); +Begin + Inherited Notification(AComponent, Operation); + If (Operation = opRemove) And (AComponent = FNativeLink) Then + FNativeLink := Nil; +End; + +Function TRESTDWNativeDriver.getConnectionType : TRESTDWDatabaseType; +Begin + Result := Inherited getConnectionType; +End; + +Function TRESTDWNativeDriver.getQuery : TRESTDWDrvQuery; +Begin + Result := Nil; + If FNativeLink <> Nil Then + Result := FNativeLink.GetQuery; +End; + +Function TRESTDWNativeDriver.getQuery(AUnidir : Boolean) : TRESTDWDrvQuery; +Begin + Result := Nil; + If FNativeLink <> Nil Then + Result := FNativeLink.GetQuery; +End; + +Function TRESTDWNativeDriver.getTable : TRESTDWDrvTable; +Begin + Result := Nil; +End; + +Function TRESTDWNativeDriver.getStoreProc : TRESTDWDrvStoreProc; +Begin + Result := Nil; +End; + +Function TRESTDWNativeDriver.compConnIsValid(AConnection : TComponent) : Boolean; +Begin + Result := (FNativeLink <> Nil) And + (AConnection <> Nil) And + (FNativeLink.Connection = AConnection); +End; + +Function TRESTDWNativeDriver.ConnectionSet : Boolean; +Begin + Result := (FNativeLink <> Nil) And + (FNativeLink.Connection <> Nil); +End; + +Function TRESTDWNativeDriver.isConnected : Boolean; +Begin + Result := (FNativeLink <> Nil) And FNativeLink.IsConnected; +End; + +Procedure TRESTDWNativeDriver.Connect; +Begin + If FNativeLink <> Nil Then + Begin + {$IFDEF RESTDWLAZARUS} + FNativeLink.DatabaseCharSet := DatabaseCharSet; + {$ENDIF} + FNativeLink.Connect; + End; +End; + +Procedure TRESTDWNativeDriver.Disconect; +Begin + If FNativeLink <> Nil Then + FNativeLink.Disconnect; +End; + +Function TRESTDWNativeDriver.connInTransaction : Boolean; +Begin + Result := False; +End; + +Procedure TRESTDWNativeDriver.connStartTransaction; +Begin +End; + +Procedure TRESTDWNativeDriver.connCommit; +Begin +End; + +Procedure TRESTDWNativeDriver.connRollback; +Begin +End; + +Function TRESTDWNativeDriver.ExecuteCommand(SQL : String; Var Error : Boolean; + Var MessageError : String; Var BinaryBlob : TMemoryStream; + Var RowsAffected : Integer; Execute : Boolean; + BinaryEvent : Boolean; MetaData : Boolean; + BinaryCompatibleMode : Boolean) : String; +Begin + Result := ExecuteCommand(SQL, Nil, Error, MessageError, BinaryBlob, RowsAffected, + Execute, BinaryEvent, MetaData, BinaryCompatibleMode); +End; + +Function TRESTDWNativeDriver.ExecuteCommand(SQL : String; Params : TRESTDWParams; + Var Error : Boolean; Var MessageError : String; + Var BinaryBlob : TMemoryStream; Var RowsAffected : Integer; + Execute : Boolean; BinaryEvent : Boolean; MetaData : Boolean; + BinaryCompatibleMode : Boolean) : String; +Var + S : TStream; + EventDataSet : TDataSet; +Begin + Result := ''; + Error := False; + MessageError := ''; + RowsAffected := 0; + EventDataSet := Nil; + Try + If FNativeLink = Nil Then + DatabaseError('NativeLink not assigned'); + {$IFDEF RESTDWLAZARUS} + FNativeLink.DatabaseCharSet := DatabaseCharSet; + {$ENDIF} + If Not FNativeLink.IsConnected Then + FNativeLink.Connect; + If Assigned(Self.OnQueryBeforeOpen) Then + Self.OnQueryBeforeOpen(EventDataSet, Params); + If Execute Then + Begin + RowsAffected := Integer(FNativeLink.ExecuteCommand(SQL, Params)); + Result := '{"COMMANDOK":true}'; + End + Else If BinaryEvent Then + Begin + If BinaryBlob = Nil Then + BinaryBlob := TMemoryStream.Create + Else + Begin + BinaryBlob.Position := 0; + BinaryBlob.Size := 0; + End; + BinaryBlob.Position := 0; + S := BinaryBlob; + FNativeLink.ExecuteSelect(SQL, Params, S, FBlobCompression Or Compression, BinaryCompatibleMode); + BinaryBlob.Position := 0; + End + Else + DatabaseError('Native SELECT requires binary transport'); + Except + On E : Exception Do + Begin + Error := True; + MessageError := E.Message; + If Assigned(Self.OnQueryException) Then + Self.OnQueryException(EventDataSet, Params, E.Message); + Result := GetPairJSONStr('NOK', MessageError); + End; + End; +End; + +Procedure TRESTDWNativeDriver.ExecuteNativeSelect(Const ASQL : String; AParams : TRESTDWParams; Var AStream : TStream); +Begin + If FNativeLink = Nil Then + DatabaseError('NativeLink not assigned'); + {$IFDEF RESTDWLAZARUS} + FNativeLink.DatabaseCharSet := DatabaseCharSet; + {$ENDIF} + If Not FNativeLink.IsConnected Then + FNativeLink.Connect; + FNativeLink.ExecuteSelect(ASQL, AParams, AStream, FBlobCompression Or Compression); +End; + +Function TRESTDWNativeDriver.ExecuteNativeCommand(Const ASQL : String; AParams : TRESTDWParams) : Int64; +Begin + If FNativeLink = Nil Then + DatabaseError('NativeLink not assigned'); + {$IFDEF RESTDWLAZARUS} + FNativeLink.DatabaseCharSet := DatabaseCharSet; + {$ENDIF} + If Not FNativeLink.IsConnected Then + FNativeLink.Connect; + Result := FNativeLink.ExecuteCommand(ASQL, AParams); +End; + +Procedure Register; +Begin + {$IFNDEF RESTDWFPC} + RegisterComponents('REST Dataware - Drivers', [TRESTDWNativeDriver]); + {$ENDIF} +End; + +Initialization +{$IFDEF FPC} + {$I uRESTDWNativeDriver.lrs} +{$ENDIF} + +End. diff --git a/CORE/Source/Database_Drivers/uRESTDWSQLDBPhysDriver.pas b/CORE/Source/Database_Drivers/uRESTDWSQLDBPhysDriver.pas new file mode 100644 index 000000000..5f896285e --- /dev/null +++ b/CORE/Source/Database_Drivers/uRESTDWSQLDBPhysDriver.pas @@ -0,0 +1,18 @@ +Unit uRESTDWSQLDBPhysDriver; + +{$I uRESTDW.inc} + +Interface + +Uses + Classes, uRESTDWSQLDBPhysLink; + +Procedure Register; + +Implementation + +Procedure Register; +Begin + RegisterComponents('REST Dataware - PhysLink', [TRESTDWSQLDBPhysLink]); +End; +End. diff --git a/CORE/Source/Database_Drivers/uRESTDWUniDACDriver.pas b/CORE/Source/Database_Drivers/uRESTDWUniDACDriver.pas index f73a0bd45..410cba136 100644 --- a/CORE/Source/Database_Drivers/uRESTDWUniDACDriver.pas +++ b/CORE/Source/Database_Drivers/uRESTDWUniDACDriver.pas @@ -1,6 +1,6 @@ unit uRESTDWUniDACDriver; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . @@ -29,7 +29,7 @@ interface {$IFDEF RESTDWLAZARUS} LResources, {$ENDIF} - Classes, SysUtils, DB, + Classes, SysUtils, DB, uRESTDWBasicdbTypes, MemDS, DBAccess, Uni, VirtualTable, uRESTDWDriverBase, uRESTDWBasicTypes, uRESTDWProtoTypes; @@ -389,11 +389,13 @@ function TRESTDWUniDACQuery.RowsAffected : Int64; end; function TRESTDWUniDACQuery.ParamCount : Integer; -var - qry : TUniQuery; begin - qry := TUniQuery(Self.Owner); - Result := qry.ParamCount; + Result:=TUniQuery(Self.Owner).ParamCount; + If (Result=0) and (Pos(':',SQL.Text)>0) Then + Begin + Prepare; + Result:=TUniQuery(Self.Owner).ParamCount; + End; end; function TRESTDWUniDACQuery.getParamDataType(IParam : integer) : TFieldType; @@ -500,5 +502,13 @@ initialization {$I ..\RESTDWLazarusDrivers.lrs} {$ENDIF} +Initialization + RegisterClass(TRESTDWUniDACDriver); + RegisterRESTDWDriverClass(TRESTDWUniDACDriver); + +Finalization + UnregisterRESTDWDriverClass(TRESTDWUniDACDriver); + UnRegisterClass(TRESTDWUniDACDriver); + end. diff --git a/CORE/Source/Database_Drivers/uRESTDWZeosDriver.pas b/CORE/Source/Database_Drivers/uRESTDWZeosDriver.pas index dcfe615af..1a742d12b 100644 --- a/CORE/Source/Database_Drivers/uRESTDWZeosDriver.pas +++ b/CORE/Source/Database_Drivers/uRESTDWZeosDriver.pas @@ -1,6 +1,6 @@ unit uRESTDWZeosDriver; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . @@ -23,10 +23,9 @@ Fernando Banhos - Refactor Drivers REST Dataware. } -{$IFNDEF RESTDWLAZARUS} - {$IFDEF FPC} - {$MODE OBJFPC}{$H+} - {$ENDIF} +{$IFDEF FPC} + {$MODE DELPHI} + {$H+} {$ENDIF} interface @@ -35,111 +34,321 @@ interface {$IFDEF RESTDWLAZARUS} LResources, {$ENDIF} - - {$IFDEF ZMEMTABLE_ENABLE_STREAM_EXPORT_IMPORT} - ZMemTable, - {$ELSE} - uRESTDWMemoryDataset, - {$ENDIF} - Classes, SysUtils, DB, Variants, + ZMemTable, + Classes, SysUtils, DB, Variants, FmtBCD, ZConnection, ZDataset, ZSequence, ZDbcIntfs, ZAbstractRODataset, ZAbstractDataset, ZStoredProcedure, ZEncoding, ZDatasetUtils, - uRESTDWDriverBase, uRESTDWBasicDbTypes, uRESTDWProtoTypes, uRESTDWZeosPhysLink - ; + {$IFDEF ZEOS80UP} + ZDatasetParam, + {$ENDIF} + uRESTDWDriverBase, uRESTDWBasicDbTypes, uRESTDWProtoTypes, uRESTDWZeosPhysLink, + uRESTDWMemoryDataset; const - rdwZeosProtocols : array[0..16] of string = (('ado'),('asa'),('asa_capi'), - ('firebird'),('interbase'),('mssql'),('mysql'),('odbc_a'), - ('odbc_w'),('oledb'),('oracle'),('pooled'),('postgresql'), - ('sqlite'),('sybase'),('webserviceproxy'),('mariadb')); + rdwZeosProtocols: array[0..16] of string = ('ado','asa','asa_capi', + 'firebird','interbase','mssql','mysql','odbc_a', + 'odbc_w','oledb','oracle','pooled','postgresql', + 'sqlite','sybase','webserviceproxy','mariadb' + ); - rdwZeosDbType : array[0..16] of TRESTDWDatabaseType = ((dbtAdo),(dbtUndefined), - (dbtUndefined),(dbtFirebird),(dbtInterbase),(dbtMsSQL),(dbtMySQL), - (dbtODBC),(dbtODBC),(dbtUndefined),(dbtOracle),(dbtUndefined), - (dbtPostgreSQL),(dbtSQLLite),(dbtUndefined),(dbtUndefined), - (dbtMySQL)); + rdwZeosDbType: array[0..16] of TRESTDWDatabaseType = (dbtAdo,dbtUndefined, dbtUndefined, dbtFirebird, dbtInterbase, dbtMsSQL, dbtMySQL, + dbtODBC,dbtODBC,dbtUndefined,dbtOracle,dbtUndefined,dbtPostgreSQL, + dbtSQLLite,dbtUndefined,dbtUndefined,dbtMySQL + ); type { TRESTDWZeosStoreProc } - TRESTDWZeosStoreProc = class(TRESTDWDrvStoreProc) public procedure ExecProc; override; procedure Prepare; override; end; + { TRESTDWZeosTable } TRESTDWZeosTable = class(TRESTDWDrvTable) public - procedure SaveToStream(stream : TStream); override; - procedure LoadFromStreamParam(IParam : integer; stream : TStream; blobtype : TBlobType); override; + procedure SaveToStream(stream: TStream); override; + procedure SaveToStreamCompatibleMode(stream: TStream); override; + procedure LoadFromStreamParam(IParam: integer; stream: TStream; blobtype: TBlobType); override; procedure FetchAll; override; end; { TRESTDWZeosQuery } - TRESTDWZeosQuery = class(TRESTDWDrvQuery) private - FSequence : TZSequence; + FSequence: TZSequence; protected - procedure createSequencedField(seqname, field : string); override; + procedure createSequencedField(seqname, field: string); override; public - procedure SaveToStream(stream : TStream); override; + procedure SaveToStream(stream: TStream); override; + procedure SaveToStreamCompatibleMode(stream: TStream); override; procedure ExecSQL; override; procedure Prepare; override; procedure FetchAll; override; - destructor Destroy; override; - - function RowsAffected : Int64; override; - function ParamCount : Integer; override; - - function getParamDataType(IParam : integer) : TFieldType; override; - function getParamName(IParam : integer) : string; override; - function getParamSize(IParam : integer) : integer; override; - function getParamValue(IParam : integer) : variant; override; - - procedure setParamDataType(IParam : integer; AValue : TFieldType); override; - procedure setParamValue(IParam : integer; AValue : variant); override; - - procedure LoadFromStreamParam(IParam : integer; stream : TStream; blobtype : TBlobType); override; + function RowsAffected: Int64; override; + function ParamCount: Integer; override; + function getParamDataType(IParam: integer): TFieldType; override; + function getParamName(IParam: integer): string; override; + function getParamSize(IParam: integer): integer; override; + function getParamValue(IParam: integer): variant; override; + procedure setParamDataType(IParam: integer; AValue: TFieldType); override; + procedure setParamValue(IParam: integer; AValue: variant); override; + procedure LoadFromStreamParam(IParam: integer; stream: TStream; blobtype: TBlobType); override; end; { TRESTDWZeosDriver } - TRESTDWZeosDriver = class(TRESTDWDriverBase) - private protected procedure setConnection(AValue: TComponent); override; - - function getConnectionType : TRESTDWDatabaseType; override; - Function compConnIsValid(comp : TComponent) : boolean; override; - Procedure zAfterPost(DataSet: TDataSet); + function getConnectionType: TRESTDWDatabaseType; override; + function compConnIsValid(comp: TComponent): boolean; override; + procedure zAfterPost(DataSet: TDataSet); + procedure zAfterOpen(DataSet: TDataSet); + procedure zOnNewRecord(DataSet: TDataSet); public - constructor Create(AOwner : TComponent); override; destructor Destroy; override; - - function getQuery : TRESTDWDrvQuery; override; - function getQuery(AUnidir : boolean) : TRESTDWDrvQuery; override; - function getTable : TRESTDWDrvTable; override; - function getStoreProc : TRESTDWDrvStoreProc; override; - + function getQuery: TRESTDWDrvQuery; override; + function getQuery(AUnidir: boolean): TRESTDWDrvQuery; override; + function getTable: TRESTDWDrvTable; override; + function getStoreProc: TRESTDWDrvStoreProc; override; procedure Connect; override; procedure Disconect; override; - - function isConnected : boolean; override; - function connInTransaction : boolean; override; + function isConnected: boolean; override; + function connInTransaction: boolean; override; procedure connStartTransaction; override; procedure connRollback; override; procedure connCommit; override; - - class procedure CreateConnection(Const AConnectionDefs : TConnectionDefs; - var AConnection : TComponent); override; + class procedure CreateConnection(const AConnectionDefs: TConnectionDefs; var AConnection: TComponent); override; end; procedure Register; implementation +Procedure SaveZeosDatasetToDWMEM(ADataset: TDataSet; AStream: TStream); +Var + I : Integer; + L : Integer; + Field : TField; + Writer : TRESTDWBinaryPacketWriter; + Bookmark : TBookmark; + HasBookmark : Boolean; + S : AnsiString; + Bytes : TRESTDWMemBytes; +{$IFDEF DELPHI2009UP} + FieldBytes : TBytes; +{$ENDIF} + BlobStream : TStream; + VBool : WordBool; + VSmall : SmallInt; + VWord : Word; + VInt : Integer; + VInt64 : Int64; + VDouble : Double; + VCurrency : Currency; + VBcd : TBcd; + VDateTime : TDateTime; + VGuid : TGUID; + Buffer : Pointer; +Begin + If Not Assigned(ADataset) Or Not Assigned(AStream) Then + Exit; + If Not ADataset.Active Then + ADataset.Open + Else + ADataset.CheckBrowseMode; + AStream.Size := 0; + AStream.Position := 0; + Writer := TRESTDWBinaryPacketWriter.Create(AStream); + Try + Writer.ClearFieldDefs; + For I := 0 To ADataset.FieldCount - 1 Do + Begin + Field := ADataset.Fields[I]; + Writer.AddFieldDef(Field.FieldName, + Field.DisplayName, + Field.Size, + Field.DataType, + Field.ReadOnly); + End; + Writer.StoreFieldDefs(1); + HasBookmark := False; + If Not ADataset.IsUniDirectional Then + Begin + Bookmark := ADataset.GetBookmark; + HasBookmark := True; + ADataset.First; + End; + ADataset.DisableControls; + Try + While Not ADataset.Eof Do + Begin + Writer.BeginRecord; + For I := 0 To ADataset.FieldCount - 1 Do + Begin + Field := ADataset.Fields[I]; + If Field.IsNull Then + Begin + Writer.StoreNull(I); + Continue; + End; + Case Field.DataType Of + ftString, + ftFixedChar, + ftWideString +{$IFDEF DELPHI2010UP} + ,ftFixedWideChar +{$ENDIF} + : + Begin + S := AnsiString(Field.AsString); + If Length(S) > 0 Then + Buffer := @S[1] + Else + Buffer := Nil; + Writer.StoreField(I, Buffer, Length(S)); + End; + ftSmallint: + Begin + VSmall := SmallInt(Field.AsInteger); + Writer.StoreField(I, @VSmall, SizeOf(VSmall)); + End; + ftInteger: + Begin + VInt := Field.AsInteger; + Writer.StoreField(I, @VInt, SizeOf(VInt)); + End; + ftWord: + Begin + VWord := Word(Field.AsInteger); + Writer.StoreField(I, @VWord, SizeOf(VWord)); + End; + ftBoolean: + Begin + VBool := Field.AsBoolean; + Writer.StoreField(I, @VBool, SizeOf(VBool)); + End; + ftFloat: + Begin + VDouble := Field.AsFloat; + Writer.StoreField(I, @VDouble, SizeOf(VDouble)); + End; + ftCurrency, + ftBCD: + Begin + VCurrency := Field.AsCurrency; + Writer.StoreField(I, @VCurrency, SizeOf(VCurrency)); + End; + ftDate: + Begin + VDateTime := Field.AsDateTime; + VInt := DateTimeToTimeStamp(VDateTime).Date; + Writer.StoreField(I, @VInt, SizeOf(VInt)); + End; + ftTime: + Begin + VDateTime := Field.AsDateTime; + VInt := DateTimeToTimeStamp(VDateTime).Time; + Writer.StoreField(I, @VInt, SizeOf(VInt)); + End; + ftDateTime, + ftTimeStamp +{$IFDEF DELPHI2010UP} + ,ftOraTimeStamp, + ftTimeStampOffset +{$ENDIF} + : + Begin + VDateTime := Field.AsDateTime; + Writer.StoreField(I, @VDateTime, SizeOf(VDateTime)); + End; + ftLargeint, + ftAutoInc: + Begin + VInt64 := Field.AsLargeInt; + Writer.StoreField(I, @VInt64, SizeOf(VInt64)); + End; + ftFMTBcd: + Begin + FillChar(VBcd, SizeOf(VBcd), 0); + VBcd := StrToBcd(Field.AsString); + Writer.StoreField(I, @VBcd, SizeOf(VBcd)); + End; + ftGuid: + Begin + FillChar(VGuid, SizeOf(VGuid), 0); + If Field.AsString <> '' Then + VGuid := StringToGUID(Field.AsString); + Writer.StoreField(I, @VGuid, SizeOf(VGuid)); + End; + ftBlob, + ftMemo, + ftGraphic +{$IFDEF DELPHI2010UP} + ,ftWideMemo +{$ENDIF} + : + Begin + BlobStream := ADataset.CreateBlobStream(Field, bmRead); + Try + L := BlobStream.Size; + SetLength(Bytes, L); + BlobStream.Position := 0; + If L > 0 Then + Begin + BlobStream.ReadBuffer(Bytes[0], L); + Buffer := @Bytes[0]; + End + Else + Buffer := Nil; + Writer.StoreField(I, Buffer, L); + Finally + BlobStream.Free; + End; + End; + ftBytes, + ftVarBytes: + Begin +{$IFDEF DELPHI2009UP} + FieldBytes := Field.AsBytes; + L := Length(FieldBytes); + SetLength(Bytes, L); + If L > 0 Then + Move(FieldBytes[0], Bytes[0], L); +{$ELSE} + Bytes := Field.AsBytes; + L := Length(Bytes); +{$ENDIF} + If L > 0 Then + Buffer := @Bytes[0] + Else + Buffer := Nil; + Writer.StoreField(I, Buffer, L); + End; + Else + DatabaseError('Zeos field type is not representable by the RESTDW DataSet binary contract: ' + + IntToStr(Ord(Field.DataType))); + End; + End; + Writer.EndRecord; + ADataset.Next; + End; + Finally + If HasBookmark Then + Begin + If ADataset.BookmarkValid(Bookmark) Then + ADataset.GotoBookmark(Bookmark); + ADataset.FreeBookmark(Bookmark); + End; + ADataset.EnableControls; + End; + Finally + Writer.Free; + End; + AStream.Position := 0; +End; + procedure Register; begin RegisterComponents('REST Dataware - Drivers', [TRESTDWZeosDriver]); @@ -149,19 +358,15 @@ procedure Register; { TRESTDWZeosStoreProc } procedure TRESTDWZeosStoreProc.ExecProc; -var - qry : TZStoredProc; begin - qry := TZStoredProc(Self.Owner); - qry.ExecProc; + if Assigned(Owner) and (Owner is TZStoredProc) then + TZStoredProc(Owner).ExecProc; end; procedure TRESTDWZeosStoreProc.Prepare; -var - qry : TZStoredProc; begin - qry := TZStoredProc(Self.Owner); - qry.Prepare; + if Assigned(Owner) and (Owner is TZStoredProc) then + TZStoredProc(Owner).Prepare; end; { TRESTDWZeosDriver } @@ -171,41 +376,41 @@ procedure TRESTDWZeosDriver.setConnection(AValue: TComponent); inherited setConnection(AValue); end; -Function TRESTDWZeosDriver.getConnectionType: TRESTDWDatabaseType; -Var - prot : String; - i : integer; -Begin - Result:=inherited getConnectionType; - If Not Assigned(Connection) Then - Exit; - If Result = dbtUndefined Then - Begin - prot := LowerCase(TZConnection(Connection).Protocol); - i := 0; - While i < Length(rdwZeosProtocols) Do - Begin - If Pos(rdwZeosProtocols[i],prot) > 0 Then - Begin - Result := rdwZeosDbType[i]; - Break; - End; - i := i + 1; - End; - End; -End; +function TRESTDWZeosDriver.getConnectionType: TRESTDWDatabaseType; +var + LProtocol : string; + I : integer; +begin + Result := inherited getConnectionType; + if not Assigned(Connection) then + Exit; + + if Result = dbtUndefined then + begin + LProtocol := LowerCase(TZConnection(Connection).Protocol); + + for I := Low(rdwZeosProtocols) to High(rdwZeosProtocols) do + if Pos(rdwZeosProtocols[I], LProtocol) > 0 then + begin + Result := rdwZeosDbType[I]; + Break; + end; + end; +end; function TRESTDWZeosDriver.getQuery(AUnidir: boolean): TRESTDWDrvQuery; var - qry : TZReadOnlyQuery; + qry: TZReadOnlyQuery; begin - if AUnidir then begin + if AUnidir then + begin qry := TZReadOnlyQuery.Create(Self); qry.IsUniDirectional := True; qry.Connection := TZConnection(Connection); Result := TRESTDWZeosQuery.Create(qry); end - else begin + else + begin Result := inherited getQuery(AUnidir); end; end; @@ -215,37 +420,68 @@ destructor TRESTDWZeosDriver.Destroy; inherited Destroy; end; -Procedure TRESTDWZeosDriver.zAfterPost(DataSet: TDataSet); -Begin -// TZQuery(DataSet).RefreshCurrentRow(True); -End; +procedure TRESTDWZeosDriver.zAfterPost(DataSet: TDataSet); +begin + if DataSet is TZQuery then + TZQuery(DataSet).RefreshCurrentRow(True); +end; + +procedure TRESTDWZeosDriver.zAfterOpen(DataSet: TDataSet); +var + I : integer; +begin + for I := 0 to DataSet.FieldCount - 1 do + {$IFDEF FPC} + if DataSet.Fields[I].DataType in [ftInteger, ftLargeint, ftAutoInc] then + {$ELSE} + if (DataSet.Fields[I].DataType in [ftInteger, ftLargeint, ftAutoInc]) and + (DataSet.Fields[I].AutoGenerateValue = arAutoInc) then + {$ENDIF} + begin + DataSet.Fields[I].Required := False; + DataSet.Fields[I].ReadOnly := False; + DataSet.Fields[I].ProviderFlags := [pfInUpdate, pfInWhere, pfInKey]; + end; +end; + +procedure TRESTDWZeosDriver.zOnNewRecord(DataSet: TDataSet); +var + I : integer; +begin + for I := 0 to DataSet.FieldCount - 1 do + {$IFDEF FPC} + if DataSet.Fields[I].DataType = ftAutoInc then + {$ELSE} + if (DataSet.Fields[I].DataType in [ftInteger, ftLargeint, ftAutoInc]) and + (DataSet.Fields[I].AutoGenerateValue = arAutoInc) then + {$ENDIF} + DataSet.Fields[I].Clear; +end; function TRESTDWZeosDriver.getQuery: TRESTDWDrvQuery; -var - qry : TZQuery; +var + qry : TZQuery; begin qry := TZQuery.Create(Self); qry.Connection := TZConnection(Connection); - {$IFNDEF FPC} - qry.AfterPost := zAfterPost; - {$ELSE} - qry.AfterPost := @zAfterPost; - {$ENDIF} + qry.AfterPost := zAfterPost; + qry.AfterOpen := zAfterOpen; + Result := TRESTDWZeosQuery.Create(qry); end; -function TRESTDWZeosDriver.getTable : TRESTDWDrvTable; -var - qry : TZTable; +function TRESTDWZeosDriver.getTable: TRESTDWDrvTable; +var + qry : TZTable; begin qry := TZTable.Create(Self); qry.Connection := TZConnection(Connection); Result := TRESTDWZeosTable.Create(qry); end; -function TRESTDWZeosDriver.getStoreProc : TRESTDWDrvStoreProc; -var - qry : TZStoredProc; +function TRESTDWZeosDriver.getStoreProc: TRESTDWDrvStoreProc; +var + qry : TZStoredProc; begin qry := TZStoredProc.Create(Self); qry.Connection := TZConnection(Connection); @@ -255,12 +491,24 @@ function TRESTDWZeosDriver.getStoreProc : TRESTDWDrvStoreProc; procedure TRESTDWZeosDriver.Connect; begin if Assigned(Connection) and (not TZConnection(Connection).Connected) then - TZConnection(Connection).Connected := True; + TZConnection(Connection).Connected := True; inherited Connect; end; procedure TRESTDWZeosDriver.Disconect; -begin +var + I : Integer; + DataSet : TZAbstractRODataset; +begin + for I := ComponentCount - 1 downto 0 do + begin + if Components[I] is TZAbstractRODataset then + begin + DataSet := TZAbstractRODataset(Components[I]); + if DataSet.Active then + DataSet.Close; + end; + end; if Assigned(Connection) and (TZConnection(Connection).Connected) then TZConnection(Connection).Connected := False; inherited Disconect; @@ -296,244 +544,355 @@ procedure TRESTDWZeosDriver.connRollback; function TRESTDWZeosDriver.compConnIsValid(comp: TComponent): boolean; begin - Result := comp.InheritsFrom(TZConnection) + Result := comp.InheritsFrom(TZConnection); end; procedure TRESTDWZeosDriver.connCommit; begin - if TZConnection(Connection).AutoCommit then + inherited connCommit; + if Assigned(Connection) and (not TZConnection(Connection).AutoCommit) then TZConnection(Connection).Commit; end; -constructor TRESTDWZeosDriver.Create(AOwner: TComponent); -begin - inherited Create(AOwner); -end; - class procedure TRESTDWZeosDriver.CreateConnection( const AConnectionDefs: TConnectionDefs; var AConnection: TComponent); +var + LConn : TZConnection; begin inherited CreateConnection(AConnectionDefs, AConnection); - if Assigned(AConnectionDefs) then begin - case AConnectionDefs.DriverType Of - dbtUndefined : TZConnection(AConnection).Protocol := ''; - dbtAccess : TZConnection(AConnection).Protocol := ''; - dbtDbase : TZConnection(AConnection).Protocol := ''; - dbtParadox : TZConnection(AConnection).Protocol := ''; - dbtFirebird : TZConnection(AConnection).Protocol := 'firebird'; - dbtInterbase : TZConnection(AConnection).Protocol := 'interbase'; - dbtMySQL : TZConnection(AConnection).Protocol := 'mysql'; - dbtSQLLite : TZConnection(AConnection).Protocol := 'sqlite'; - dbtOracle : TZConnection(AConnection).Protocol := 'oracle'; - dbtMsSQL : TZConnection(AConnection).Protocol := 'mssql'; - dbtODBC : TZConnection(AConnection).Protocol := 'odbc_a'; - dbtPostgreSQL : TZConnection(AConnection).Protocol := 'postgresql'; - dbtAdo : TZConnection(AConnection).Protocol := 'ado'; - end; - end; + + if not (Assigned(AConnectionDefs) and Assigned(AConnection)) then + Exit; - with TZConnection(AConnection) do begin - HostName := AConnectionDefs.HostName; - Database := AConnectionDefs.DatabaseName; - User := AConnectionDefs.Username; - Password := AConnectionDefs.Password; - Port := AConnectionDefs.DBPort; + LConn := TZConnection(AConnection); + + case AConnectionDefs.DriverType of + dbtUndefined, dbtAccess, dbtDbase, dbtParadox: LConn.Protocol := ''; + dbtFirebird: LConn.Protocol := 'firebird'; + dbtInterbase: LConn.Protocol := 'interbase'; + dbtMySQL: LConn.Protocol := 'mysql'; + dbtSQLLite: LConn.Protocol := 'sqlite'; + dbtOracle: LConn.Protocol := 'oracle'; + dbtMsSQL: LConn.Protocol := 'mssql'; + dbtODBC: LConn.Protocol := 'odbc_a'; + dbtPostgreSQL: LConn.Protocol := 'postgresql'; + dbtAdo: LConn.Protocol := 'ado'; end; -end; -{ TRESTDWZeosQuery } + LConn.HostName := AConnectionDefs.HostName; + LConn.Database := AConnectionDefs.DatabaseName; + LConn.User := AConnectionDefs.Username; + LConn.Password := AConnectionDefs.Password; + LConn.Port := AConnectionDefs.DBPort; -procedure TRESTDWZeosQuery.createSequencedField(seqname, field : string); -var - qry : TZAbstractRODataset; -begin - if Trim(seqname) = '' then - Exit; - - if FSequence = nil then - FSequence := TZSequence.Create(Self); + // AJUSTES ZEOS 8 + FIREBIRD 3.0+ (IDENTITY E DEFAULTS) + LConn.Properties.Add('AutoParamRefreshes=True'); + LConn.Properties.Add('GetIdentityAfterInsert=True'); + LConn.Properties.Add('SupportIdentityColumns=True'); + LConn.Properties.Add('AutoRefresh=True'); + LConn.Properties.Add('RefreshAfterPost=True'); + +end; - qry := TZAbstractRODataset(Self.Owner); - if qry is TZQuery then begin - FSequence.SequenceName := seqname; +{ TRESTDWZeosQuery } - TZQuery(qry).Sequence := FSequence; - TZQuery(qry).SequenceField := field; +procedure TRESTDWZeosQuery.createSequencedField(seqname, field: string); +var + LQuery : TZQuery; + LSequence : TZSequence; + varField : TField; +begin + if Assigned(Self.Owner) and (Self.Owner is TZQuery) then + begin + LQuery := TZQuery(Self.Owner); + varField := LQuery.FindField(field); + + if Assigned(varField) then + begin + varField.Required := False; + {$IFDEF FPC} + // Lazarus não possui AutoGenerateValue + if varField.DataType in [ftInteger, ftLargeint] then + varField.ReadOnly := False; + {$ELSE} + varField.AutoGenerateValue := arAutoInc; + {$ENDIF} + + if LQuery.Sequence = nil then + begin + LSequence := TZSequence.Create(LQuery); + LSequence.Connection := LQuery.Connection; + LSequence.SequenceName := ''; + LQuery.Sequence := LSequence; + LQuery.SequenceField := field; + end; + end; end; end; procedure TRESTDWZeosQuery.ExecSQL; var - qry : TZAbstractRODataset; + qry : TZAbstractRODataset; + I : Integer; + LParam : TZParam; + LField : TField; begin - qry := TZAbstractRODataset(Self.Owner); - qry.ExecSQL; + if Assigned(Self.Owner) and (Self.Owner is TZAbstractRODataset) then + begin + qry := TZAbstractRODataset(Self.Owner); + + if qry is TZQuery then + begin + for I := 0 to TZQuery(qry).Params.Count - 1 do + begin + LParam := TZQuery(qry).Params[I]; + if (LParam.DataType in [ftInteger, ftLargeint, ftAutoInc]) and (LParam.Value = 0) then + begin + LField := TZQuery(qry).FindField(LParam.Name); + {$IFDEF FPC} + if (LField.DataType in [ftAutoInc, ftInteger, ftLargeint]) and + (pfInKey in LField.ProviderFlags) then + LParam.Clear; + {$ELSE} + if (LField.AutoGenerateValue = arAutoInc) and + (pfInKey in LField.ProviderFlags) then + LParam.Clear; + {$ENDIF} + begin + LParam.Clear; + end; + end; + end; + end; + + qry.ExecSQL; + end; + end; procedure TRESTDWZeosQuery.FetchAll; -var - qry : TZTable; begin - qry := TZTable(Self.Owner); - qry.FetchAll; + if Assigned(Self.Owner) and (Self.Owner is TZTable) then + TZTable(Self.Owner).FetchAll; end; -procedure TRESTDWZeosQuery.LoadFromStreamParam(IParam: integer; stream: TStream; - blobtype: TBlobType); +procedure TRESTDWZeosQuery.LoadFromStreamParam( + IParam: Integer; + Stream: TStream; + BlobType: TBlobType); var - qry : TZAbstractRODataset; - {$IFDEF ZEOS80UP} - cp : Word; - {$ENDIF} + qry: TZAbstractRODataset; + +{$IFDEF ZEOS80UP} + cp: Word; + LParams: TZParams; +{$ENDIF} + begin + if not Assigned(Self.Owner) then + Exit; + qry := TZAbstractRODataset(Self.Owner); - {$IFDEF ZEOS80UP} - if qry is TZQuery then begin - if BlobType in [ftWideString{$IFDEF WITH_WIDEMEMO}, ftFixedWideChar, ftWideMemo{$ENDIF}] then - TZQuery(qry).Params[IParam].LoadTextFromStream(Stream, zCP_UTF16) - else if BlobType in [ftBlob, ftGraphic, ftTypedBinary, ftOraBlob] then - TZQuery(qry).Params[IParam].LoadBinaryFromStream(Stream) - else if BlobType in [ftMemo, ftParadoxOle, ftDBaseOle, ftOraClob] then begin - cp := qry.Connection.RawCharacterTransliterateOptions.GetRawTransliterateCodePage(ttParam); - TZQuery(qry).Params[IParam].LoadTextFromStream(Stream, cp); - end; - end - else if qry is TZReadOnlyQuery then begin - if BlobType in [ftWideString{$IFDEF WITH_WIDEMEMO}, ftFixedWideChar, ftWideMemo{$ENDIF}] then - TZReadOnlyQuery(qry).Params[IParam].LoadTextFromStream(Stream, zCP_UTF16) - else if BlobType in [ftBlob, ftGraphic, ftTypedBinary, ftOraBlob] then - TZReadOnlyQuery(qry).Params[IParam].LoadBinaryFromStream(Stream) - else if BlobType in [ftMemo, ftParadoxOle, ftDBaseOle, ftOraClob] then begin - cp := qry.Connection.RawCharacterTransliterateOptions.GetRawTransliterateCodePage(ttParam); - TZReadOnlyQuery(qry).Params[IParam].LoadTextFromStream(Stream, cp); - end; + +{$IFDEF ZEOS80UP} + + LParams := nil; + + if qry is TZQuery then + LParams := TZQuery(qry).Params + else if qry is TZReadOnlyQuery then + LParams := TZReadOnlyQuery(qry).Params; + + if Assigned(LParams) then + begin + {$IFNDEF FPC} + // Delphi + Zeos 8 + if BlobType in + [ftWideString{$IFDEF WITH_WIDEMEMO}, ftFixedWideChar, ftWideMemo{$ENDIF}] then + LParams[IParam].LoadTextFromStream(Stream, zCP_UTF16) + else if BlobType in + [ftBlob, ftGraphic, ftTypedBinary, ftOraBlob] then + LParams[IParam].LoadBinaryFromStream(Stream) + else if BlobType in + [ftMemo, ftParadoxOle, ftDBaseOle, ftOraClob] then + begin + cp := qry.Connection.RawCharacterTransliterateOptions + .GetRawTransliterateCodePage(ttParam); + LParams[IParam].LoadTextFromStream(Stream, cp); end; {$ELSE} - if qry is TZQuery then - TZQuery(qry).Params[IParam].LoadFromStream(stream,blobtype) - else if qry is TZReadOnlyQuery then - TZReadOnlyQuery(qry).Params[IParam].LoadFromStream(stream,blobtype) + // Lazarus + Zeos 8 + LParams[IParam].LoadFromStream(Stream, BlobType); {$ENDIF} + end; + {$ELSE} + if qry is TZQuery then + TZQuery(qry).Params[IParam].LoadFromStream(Stream, BlobType) + else if qry is TZReadOnlyQuery then + TZReadOnlyQuery(qry).Params[IParam].LoadFromStream(Stream, BlobType); + {$ENDIF} + end; procedure TRESTDWZeosQuery.Prepare; -var - qry : TZAbstractRODataset; +var + qry : TZAbstractRODataset; + I : integer; + LParam : TZParam; + LParamName : string; begin inherited Prepare; - qry := TZAbstractRODataset(Self.Owner); - qry.Prepare; + if Assigned(Self.Owner) and (Self.Owner is TZAbstractRODataset) then + begin + qry := TZAbstractRODataset(Self.Owner); + + if qry is TZQuery then + begin + for I := 0 to TZQuery(qry).Params.Count - 1 do + begin + LParam := TZQuery(qry).Params[I]; + if (LParam.DataType in [ftInteger, ftLargeint, ftAutoInc]) and (LParam.Value = 0) then + begin + LParamName := LowerCase(LParam.Name); + if (LParamName = 'id') or (LParamName.StartsWith('cod')) or (LParamName.EndsWith('id')) then + LParam.Clear; + end; + end; + end; + + qry.Prepare; + end; end; destructor TRESTDWZeosQuery.Destroy; begin - if FSequence <> nil then + if Assigned(FSequence) then FreeAndNil(FSequence); inherited Destroy; end; function TRESTDWZeosQuery.RowsAffected: Int64; -var - qry : TZAbstractRODataset; begin - qry := TZAbstractRODataset(Self.Owner); - Result := qry.RowsAffected; + Result := 0; + if Assigned(Self.Owner) and (Self.Owner is TZAbstractRODataset) then + Result := TZAbstractRODataset(Self.Owner).RowsAffected; end; -function TRESTDWZeosQuery.ParamCount : Integer; +// REFATORAÇÃO: Otimização drástica e unificação no acesso aos parâmetros do Zeos +function TRESTDWZeosQuery.ParamCount: Integer; var - qry : TZAbstractRODataset; + qry : TZAbstractRODataset; + begin - Result := 0; - qry := TZAbstractRODataset(Self.Owner); - if qry is TZQuery then - Result := TZQuery(qry).Params.Count - else if qry is TZReadOnlyQuery then - Result := TZReadOnlyQuery(qry).Params.Count; + Result:=0; + If not Assigned(Self.Owner) Then + Exit; + qry:=TZAbstractRODataset(Self.Owner); + If qry is TZQuery Then + Result:=TZQuery(qry).Params.Count + Else If qry is TZReadOnlyQuery Then + Result:=TZReadOnlyQuery(qry).Params.Count; + If (Result=0) and (Pos(':',SQL.Text)>0) Then + Begin + Prepare; + If qry is TZQuery Then + Result:=TZQuery(qry).Params.Count + Else If qry is TZReadOnlyQuery Then + Result:=TZReadOnlyQuery(qry).Params.Count; + End; end; -function TRESTDWZeosQuery.getParamDataType(IParam : integer) : TFieldType; -var - qry : TZAbstractRODataset; + +function TRESTDWZeosQuery.getParamDataType(IParam: integer): TFieldType; +var + qry : TZAbstractRODataset; begin Result := ftUnknown; + if not Assigned(Self.Owner) then Exit; + qry := TZAbstractRODataset(Self.Owner); - if qry is TZQuery then - Result := TZQuery(qry).Params[IParam].DataType - else if qry is TZReadOnlyQuery then - Result := TZReadOnlyQuery(qry).Params[IParam].DataType; + if qry is TZQuery then Result := TZQuery(qry).Params[IParam].DataType + else if qry is TZReadOnlyQuery then Result := TZReadOnlyQuery(qry).Params[IParam].DataType; end; -function TRESTDWZeosQuery.getParamName(IParam : integer) : string; -var - qry : TZAbstractRODataset; +function TRESTDWZeosQuery.getParamName(IParam: integer): string; +var + qry : TZAbstractRODataset; begin Result := ''; + if not Assigned(Self.Owner) then Exit; + qry := TZAbstractRODataset(Self.Owner); - if qry is TZQuery then - Result := TZQuery(qry).Params[IParam].Name - else if qry is TZReadOnlyQuery then - Result := TZReadOnlyQuery(qry).Params[IParam].Name; + if qry is TZQuery then Result := TZQuery(qry).Params[IParam].Name + else if qry is TZReadOnlyQuery then Result := TZReadOnlyQuery(qry).Params[IParam].Name; end; -function TRESTDWZeosQuery.getParamSize(IParam : integer) : integer; -var - qry : TZAbstractRODataset; +function TRESTDWZeosQuery.getParamSize(IParam: integer): integer; +var + qry : TZAbstractRODataset; begin Result := 0; + if not Assigned(Self.Owner) then Exit; + qry := TZAbstractRODataset(Self.Owner); - if qry is TZQuery then - Result := TZQuery(qry).Params[IParam].Size - else if qry is TZReadOnlyQuery then - Result := TZReadOnlyQuery(qry).Params[IParam].Size; + if qry is TZQuery then Result := TZQuery(qry).Params[IParam].Size + else if qry is TZReadOnlyQuery then Result := TZReadOnlyQuery(qry).Params[IParam].Size; end; -function TRESTDWZeosQuery.getParamValue(IParam : integer) : variant; -var - qry : TZAbstractRODataset; +function TRESTDWZeosQuery.getParamValue(IParam: integer): variant; +var + qry : TZAbstractRODataset; begin - Result := null; + Result := Null; + if not Assigned(Self.Owner) then Exit; + qry := TZAbstractRODataset(Self.Owner); - if qry is TZQuery then - Result := TZQuery(qry).Params[IParam].Value - else if qry is TZReadOnlyQuery then - Result := TZReadOnlyQuery(qry).Params[IParam].Value; + if qry is TZQuery then Result := TZQuery(qry).Params[IParam].Value + else if qry is TZReadOnlyQuery then Result := TZReadOnlyQuery(qry).Params[IParam].Value; end; -procedure TRESTDWZeosQuery.setParamDataType(IParam : integer; AValue : TFieldType); -var - qry : TZAbstractRODataset; +procedure TRESTDWZeosQuery.setParamDataType(IParam: integer; AValue: TFieldType); +var + qry : TZAbstractRODataset; begin + if not Assigned(Self.Owner) then Exit; + qry := TZAbstractRODataset(Self.Owner); - if qry is TZQuery then - TZQuery(qry).Params[IParam].DataType := AValue - else if qry is TZReadOnlyQuery then - TZReadOnlyQuery(qry).Params[IParam].DataType := AValue; + if qry is TZQuery then TZQuery(qry).Params[IParam].DataType := AValue + else if qry is TZReadOnlyQuery then TZReadOnlyQuery(qry).Params[IParam].DataType := AValue; end; -procedure TRESTDWZeosQuery.setParamValue(IParam : integer; AValue : variant); +procedure TRESTDWZeosQuery.setParamValue(IParam: integer; AValue: variant); var qry : TZAbstractRODataset; begin - qry := TZAbstractRODataset(Self.Owner); + if not Assigned(Self.Owner) then Exit; + qry := TZAbstractRODataset(Self.Owner); if qry is TZQuery then TZQuery(qry).Params[IParam].Value := AValue else if qry is TZReadOnlyQuery then TZReadOnlyQuery(qry).Params[IParam].Value := AValue; end; +procedure TRESTDWZeosQuery.SaveToStreamCompatibleMode(stream: TStream); +Begin + If Assigned(Self.Owner) And (Self.Owner Is TDataSet) Then + SaveZeosDatasetToDWMEM(TDataSet(Self.Owner), stream); +End; + procedure TRESTDWZeosQuery.SaveToStream(stream: TStream); -var - qry : TZAbstractRODataset; - memtable : TZMemTable; +var + qry : TZQuery; + memtable : TZMemTable; begin + if not (Assigned(Self.Owner) and Assigned(stream)) then Exit; + qry := TZQuery(Self.Owner); memtable := TZMemTable.Create(nil); try - memtable.AssignDataFrom(qry); - //TODO SaveTostream - memtable.SaveToStream(stream); - stream.Position := 0; + memtable.AssignDataFrom(qry); + memtable.SaveToStream(stream); + stream.Position := 0; finally FreeAndNil(memtable); end; @@ -542,51 +901,84 @@ procedure TRESTDWZeosQuery.SaveToStream(stream: TStream); { TRESTDWZeosTable } procedure TRESTDWZeosTable.FetchAll; -var - qry : TZTable; begin - qry := TZTable(Self.Owner); - qry.FetchAll; + if Assigned(Self.Owner) and (Self.Owner is TZTable) then + TZTable(Self.Owner).FetchAll; end; -procedure TRESTDWZeosTable.LoadFromStreamParam(IParam: integer; stream: TStream; - blobtype: TBlobType); +procedure TRESTDWZeosTable.LoadFromStreamParam(IParam: integer; stream: TStream; blobtype: TBlobType); var - qry : TZTable; - pname : string; - cp : Word; + qry : TZAbstractRODataset; + LParams : TZParams; + cp : word; begin - pname := Self.Params[IParam].Name; - qry := TZTable(Self.Owner); + if not Assigned(Self.Owner) then Exit; + + qry := TZAbstractRODataset(Self.Owner); + {$IFDEF ZEOS80UP} - if BlobType in [ftWideString{$IFDEF WITH_WIDEMEMO}, ftFixedWideChar, ftWideMemo{$ENDIF}] then - qry.ParamByName(pname).LoadTextFromStream(Stream, zCP_UTF16) - else if BlobType in [ftBlob, ftGraphic, ftTypedBinary, ftOraBlob] then - qry.ParamByName(pname).LoadBinaryFromStream(Stream) - else if BlobType in [ftMemo, ftParadoxOle, ftDBaseOle, ftOraClob] then begin - cp := qry.Connection.RawCharacterTransliterateOptions.GetRawTransliterateCodePage(ttParam); - qry.ParamByName(pname).LoadTextFromStream(Stream, cp); + // Deixando a variável estritamente dentro da diretiva + LParams := nil; + + if qry is TZQuery then + LParams := TZQuery(qry).Params + else if qry is TZReadOnlyQuery then + LParams := TZReadOnlyQuery(qry).Params; + + if Assigned(LParams) then + begin + if BlobType in [ftWideString{$IFDEF WITH_WIDEMEMO}, ftFixedWideChar, ftWideMemo{$ENDIF}] then + LParams[IParam].LoadTextFromStream(Stream, zCP_UTF16) + else if BlobType in [ftBlob, ftGraphic, ftTypedBinary, ftOraBlob] then + LParams[IParam].LoadBinaryFromStream(Stream) + else if BlobType in [ftMemo, ftParadoxOle, ftDBaseOle, ftOraClob] then + begin + cp := qry.Connection.RawCharacterTransliterateOptions.GetRawTransliterateCodePage(ttParam); + LParams[IParam].LoadTextFromStream(Stream, cp); + end; end; {$ELSE} - qry.ParamByName(pname).LoadFromStream(stream,blobtype); + if qry is TZQuery then + TZQuery(qry).Params[IParam].LoadFromStream(stream, blobtype) + else if qry is TZReadOnlyQuery then + TZReadOnlyQuery(qry).Params[IParam].LoadFromStream(stream, blobtype); {$ENDIF} end; +procedure TRESTDWZeosTable.SaveToStreamCompatibleMode(stream: TStream); +Begin + If Assigned(Self.Owner) And (Self.Owner Is TDataSet) Then + SaveZeosDatasetToDWMEM(TDataSet(Self.Owner), stream); +End; + procedure TRESTDWZeosTable.SaveToStream(stream: TStream); var - qry : TZTable; + qry : TZAbstractRODataset; memtable : TZMemTable; begin + if not (Assigned(Self.Owner) and Assigned(stream)) then + Exit; + + // REFATORAÇÃO: Instanciação com escopo inline seguro qry := TZTable.Create(Self.Owner); memtable := TZMemTable.Create(nil); try memtable.Assign(qry); - memtable .SaveToStream(stream); + memtable.SaveToStream(stream); stream.Position := 0; finally + // CORREÇÃO: qry adicionado ao bloco de liberação para eliminar o Memory Leak + FreeAndNil(qry); FreeAndNil(memtable); end; end; -end. +Initialization + RegisterClass(TRESTDWZeosDriver); + RegisterRESTDWDriverClass(TRESTDWZeosDriver); + +Finalization + UnregisterRESTDWDriverClass(TRESTDWZeosDriver); + UnRegisterClass(TRESTDWZeosDriver); +end. \ No newline at end of file From 421b887f3e4abbafcc00d927397a6ce410d0d713 Mon Sep 17 00:00:00 2001 From: Roniery Santos Cardoso Date: Tue, 8 Sep 2026 21:59:39 -0300 Subject: [PATCH 03/22] fix(core): correcoes de ClientSQL, dataset e save no RESTDW Basic Correcao para RESTDWClientSQL Add Fields, OpenDataset/CreateDataset, indices para post/edit/insert/delete, ordem por IndexDefs, setvalues e save geral de dados. refs r4017, r4020, r4080, r4084-r4089 --- CORE/Source/Basic/Crypto/DWDCPbase64.pas | 10 +- CORE/Source/Basic/Crypto/DWDCPcast256.pas | 10 +- CORE/Source/Basic/Crypto/DWDCPcrypt2.pas | 10 +- CORE/Source/Basic/Crypto/DWDCPrijndael.pas | 10 +- CORE/Source/Basic/Crypto/DWDCPsha256.pas | 2 +- CORE/Source/Basic/Crypto/DWDCPtypes.pas | 10 +- CORE/Source/Basic/Dialogs/uRESTDWAbout.pas | 10 +- .../Source/Basic/Dialogs/uRESTDWAboutForm.pas | 2 +- .../Basic/Mechanics/uRESTDWAttachment.pas | 10 +- .../Basic/Mechanics/uRESTDWAttachmentFile.pas | 10 +- .../Basic/Mechanics/uRESTDWAuthenticators.pas | 2 +- CORE/Source/Basic/Mechanics/uRESTDWBuffer.pas | 10 +- CORE/Source/Basic/Mechanics/uRESTDWCoder.pas | 10 +- .../Basic/Mechanics/uRESTDWCoder3to4.pas | 10 +- .../Basic/Mechanics/uRESTDWCoderBinHex4.pas | 10 +- .../Basic/Mechanics/uRESTDWCoderHeader.pas | 10 +- .../Basic/Mechanics/uRESTDWCoderMIME.pas | 10 +- .../Mechanics/uRESTDWCoderQuotedPrintable.pas | 10 +- .../Basic/Mechanics/uRESTDWDataUtils.pas | 16 +- .../Basic/Mechanics/uRESTDWException.pas | 10 +- .../Mechanics/uRESTDWHeaderCoderBase.pas | 10 +- .../Basic/Mechanics/uRESTDWHeaderList.pas | 10 +- .../Basic/Mechanics/uRESTDWIOHandler.pas | 10 +- .../Mechanics/uRESTDWIOHandlerStream.pas | 10 +- .../Source/Basic/Mechanics/uRESTDWMessage.pas | 10 +- .../Basic/Mechanics/uRESTDWMessageClient.pas | 10 +- .../Basic/Mechanics/uRESTDWMessageCoder.pas | 10 +- .../Mechanics/uRESTDWMessageCoderBinHex4.pas | 10 +- .../Mechanics/uRESTDWMessageCoderMIME.pas | 10 +- .../uRESTDWMessageCoderQuotedPrintable.pas | 10 +- .../Basic/Mechanics/uRESTDWMessageParts.pas | 10 +- CORE/Source/Basic/uRESTDWBasic.pas | 8 +- CORE/Source/Basic/uRESTDWBasicClass.pas | 18 +- CORE/Source/Basic/uRESTDWBasicDB.pas | 25 +- CORE/Source/Basic/uRESTDWBasicDbTypes.pas | 197 +- CORE/Source/Basic/uRESTDWBasicTypes.pas | 16 +- CORE/Source/Basic/uRESTDWBufferBase.pas | 10 +- CORE/Source/Basic/uRESTDWBufferDb.pas | 12 +- CORE/Source/Basic/uRESTDWComponentEvents.pas | 10 +- CORE/Source/Basic/uRESTDWDesignReg.pas | 155 +- CORE/Source/Basic/uRESTDWFileBuffer.pas | 10 +- CORE/Source/Basic/uRESTDWMasterDetailData.pas | 14 +- CORE/Source/Basic/uRESTDWParams.pas | 265 +- CORE/Source/Basic/uRESTDWPoolermethod.pas | 20 +- CORE/Source/Basic/uRESTDWPropertyPersist.pas | 2 +- CORE/Source/Basic/uRESTDWProtoTypes.pas | 351 ++- .../Basic/uRESTDWResponseTranslator.pas | 10 +- CORE/Source/Basic/uRESTDWServerContext.pas | 10 +- CORE/Source/Basic/uRESTDWServerEvents.pas | 10 +- .../Source/Basic/uRESTDWServerMethodClass.pas | 2 +- CORE/Source/Basic/uRESTDWServerRoutes.pas | 10 +- CORE/Source/Basic/uRESTDWStorageBin.pas | 2282 +++-------------- CORE/Source/Basic/uRESTDWZlib.pas | 322 +++ 53 files changed, 1609 insertions(+), 2442 deletions(-) create mode 100644 CORE/Source/Basic/uRESTDWZlib.pas diff --git a/CORE/Source/Basic/Crypto/DWDCPbase64.pas b/CORE/Source/Basic/Crypto/DWDCPbase64.pas index 4f6c21db3..e3bcd4df3 100644 --- a/CORE/Source/Basic/Crypto/DWDCPbase64.pas +++ b/CORE/Source/Basic/Crypto/DWDCPbase64.pas @@ -1,21 +1,21 @@ unit DWDCPbase64; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Crypto/DWDCPcast256.pas b/CORE/Source/Basic/Crypto/DWDCPcast256.pas index 44e2815a8..3bb91e5a1 100644 --- a/CORE/Source/Basic/Crypto/DWDCPcast256.pas +++ b/CORE/Source/Basic/Crypto/DWDCPcast256.pas @@ -1,21 +1,21 @@ unit DWDCPcast256; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Crypto/DWDCPcrypt2.pas b/CORE/Source/Basic/Crypto/DWDCPcrypt2.pas index cd2caf3f5..3bbced29d 100644 --- a/CORE/Source/Basic/Crypto/DWDCPcrypt2.pas +++ b/CORE/Source/Basic/Crypto/DWDCPcrypt2.pas @@ -1,21 +1,21 @@ unit DWDCPcrypt2; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Crypto/DWDCPrijndael.pas b/CORE/Source/Basic/Crypto/DWDCPrijndael.pas index 7a984f94f..7005401ad 100644 --- a/CORE/Source/Basic/Crypto/DWDCPrijndael.pas +++ b/CORE/Source/Basic/Crypto/DWDCPrijndael.pas @@ -1,21 +1,21 @@ unit DWDCPrijndael; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Crypto/DWDCPsha256.pas b/CORE/Source/Basic/Crypto/DWDCPsha256.pas index 6d941cfd8..2c8bf6486 100644 --- a/CORE/Source/Basic/Crypto/DWDCPsha256.pas +++ b/CORE/Source/Basic/Crypto/DWDCPsha256.pas @@ -24,7 +24,7 @@ {******************************************************************************} unit DWDCPsha256; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} interface diff --git a/CORE/Source/Basic/Crypto/DWDCPtypes.pas b/CORE/Source/Basic/Crypto/DWDCPtypes.pas index 18d1e71e4..9cb56628f 100644 --- a/CORE/Source/Basic/Crypto/DWDCPtypes.pas +++ b/CORE/Source/Basic/Crypto/DWDCPtypes.pas @@ -1,21 +1,21 @@ unit DWDCPtypes; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Dialogs/uRESTDWAbout.pas b/CORE/Source/Basic/Dialogs/uRESTDWAbout.pas index e6f6af98b..c31207a0e 100644 --- a/CORE/Source/Basic/Dialogs/uRESTDWAbout.pas +++ b/CORE/Source/Basic/Dialogs/uRESTDWAbout.pas @@ -1,21 +1,21 @@ unit uRESTDWAbout; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Dialogs/uRESTDWAboutForm.pas b/CORE/Source/Basic/Dialogs/uRESTDWAboutForm.pas index 12fbab39a..91ec756cd 100644 --- a/CORE/Source/Basic/Dialogs/uRESTDWAboutForm.pas +++ b/CORE/Source/Basic/Dialogs/uRESTDWAboutForm.pas @@ -1,6 +1,6 @@ unit uRESTDWAboutForm; -{$I ..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} interface diff --git a/CORE/Source/Basic/Mechanics/uRESTDWAttachment.pas b/CORE/Source/Basic/Mechanics/uRESTDWAttachment.pas index 7534b5d9c..e2c7e18b1 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWAttachment.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWAttachment.pas @@ -1,21 +1,21 @@ Unit uRESTDWAttachment; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWAttachmentFile.pas b/CORE/Source/Basic/Mechanics/uRESTDWAttachmentFile.pas index d57ab1d5c..a1705e983 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWAttachmentFile.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWAttachmentFile.pas @@ -1,21 +1,21 @@ unit uRESTDWAttachmentFile; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWAuthenticators.pas b/CORE/Source/Basic/Mechanics/uRESTDWAuthenticators.pas index 60c9097de..40cf24659 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWAuthenticators.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWAuthenticators.pas @@ -1,6 +1,6 @@ unit uRESTDWAuthenticators; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . diff --git a/CORE/Source/Basic/Mechanics/uRESTDWBuffer.pas b/CORE/Source/Basic/Mechanics/uRESTDWBuffer.pas index 0984ebc40..7f93049b2 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWBuffer.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWBuffer.pas @@ -1,21 +1,21 @@ unit uRESTDWBuffer; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWCoder.pas b/CORE/Source/Basic/Mechanics/uRESTDWCoder.pas index 398dad8ba..1c08c3bd6 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWCoder.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWCoder.pas @@ -1,21 +1,21 @@ unit uRESTDWCoder; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWCoder3to4.pas b/CORE/Source/Basic/Mechanics/uRESTDWCoder3to4.pas index 308f6a6ba..facf00c51 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWCoder3to4.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWCoder3to4.pas @@ -1,21 +1,21 @@ unit uRESTDWCoder3to4; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWCoderBinHex4.pas b/CORE/Source/Basic/Mechanics/uRESTDWCoderBinHex4.pas index 4cc4501b7..75d0d7470 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWCoderBinHex4.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWCoderBinHex4.pas @@ -1,21 +1,21 @@ unit uRESTDWCoderBinHex4; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWCoderHeader.pas b/CORE/Source/Basic/Mechanics/uRESTDWCoderHeader.pas index 8f0840c6e..4a7856780 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWCoderHeader.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWCoderHeader.pas @@ -1,21 +1,21 @@ unit uRESTDWCoderHeader; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWCoderMIME.pas b/CORE/Source/Basic/Mechanics/uRESTDWCoderMIME.pas index 7a75ecd8c..bbb5b1d01 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWCoderMIME.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWCoderMIME.pas @@ -1,21 +1,21 @@ Unit uRESTDWCoderMIME; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWCoderQuotedPrintable.pas b/CORE/Source/Basic/Mechanics/uRESTDWCoderQuotedPrintable.pas index b5cda7b85..cfa565645 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWCoderQuotedPrintable.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWCoderQuotedPrintable.pas @@ -1,21 +1,21 @@ unit uRESTDWCoderQuotedPrintable; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWDataUtils.pas b/CORE/Source/Basic/Mechanics/uRESTDWDataUtils.pas index dcd3feac2..1381b596a 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWDataUtils.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWDataUtils.pas @@ -1,21 +1,21 @@ unit uRESTDWDataUtils; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -723,7 +723,7 @@ implementation If trim(vServerSignature) <> '' Then viss := Format('"iss":"%s", ', [vServerSignature]); vBuildData := ''; - //Por enquanto igual mais no futuro haverá diferenças + //Por enquanto igual mais no futuro haver diferenas Case vRDWTokenType Of rdwTS, rdwPersonal : Begin @@ -992,7 +992,7 @@ implementation vHeader := ''; vBody := ''; vStringComparer := ''; - Value := StringReplace(Value, ' ', '+', [rfReplaceAll]); //Remove espaços na Token e add os caracteres "+" em seu lugar + Value := StringReplace(Value, ' ', '+', [rfReplaceAll]); //Remove espaos na Token e add os caracteres "+" em seu lugar vHeader := Copy(Value, InitStrPos, Pos('.', Value) -1); Delete(Value, InitStrPos, Pos('.', Value)); vBody := Copy(Value, InitStrPos, Pos('.', Value) -1); @@ -2023,7 +2023,7 @@ implementation vParams.Text := StringReplace(Cmd, '&', sLineBreak, [rfReplaceAll]); If vParams.count = 0 Then If Trim(Cmd) <> '' Then - vParams.DelimitedText := StringReplace(Cmd, sLineBreak, '&', [rfReplaceAll]); //Alterações enviadas por "joaoantonio19" + vParams.DelimitedText := StringReplace(Cmd, sLineBreak, '&', [rfReplaceAll]); //Alteraes enviadas por "joaoantonio19" Finally encodestrings := False; For I := 0 To vParams.Count - 1 Do diff --git a/CORE/Source/Basic/Mechanics/uRESTDWException.pas b/CORE/Source/Basic/Mechanics/uRESTDWException.pas index f3d04fb2f..c12ca367e 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWException.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWException.pas @@ -1,21 +1,21 @@ unit uRESTDWException; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWHeaderCoderBase.pas b/CORE/Source/Basic/Mechanics/uRESTDWHeaderCoderBase.pas index 81fa2d436..140a24000 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWHeaderCoderBase.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWHeaderCoderBase.pas @@ -1,21 +1,21 @@ unit uRESTDWHeaderCoderBase; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWHeaderList.pas b/CORE/Source/Basic/Mechanics/uRESTDWHeaderList.pas index cca9e659a..33a659b5e 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWHeaderList.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWHeaderList.pas @@ -1,21 +1,21 @@ unit uRESTDWHeaderList; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWIOHandler.pas b/CORE/Source/Basic/Mechanics/uRESTDWIOHandler.pas index 2ba3ee72b..1bfffaf3c 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWIOHandler.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWIOHandler.pas @@ -1,21 +1,21 @@ unit uRESTDWIOHandler; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWIOHandlerStream.pas b/CORE/Source/Basic/Mechanics/uRESTDWIOHandlerStream.pas index 97fc9ef06..886b46be0 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWIOHandlerStream.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWIOHandlerStream.pas @@ -1,21 +1,21 @@ unit uRESTDWIOHandlerStream; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWMessage.pas b/CORE/Source/Basic/Mechanics/uRESTDWMessage.pas index a042f18d9..c7be3fe5b 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWMessage.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWMessage.pas @@ -1,21 +1,21 @@ unit uRESTDWMessage; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWMessageClient.pas b/CORE/Source/Basic/Mechanics/uRESTDWMessageClient.pas index a6ad7c8cc..5d0475b47 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWMessageClient.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWMessageClient.pas @@ -1,21 +1,21 @@ unit uRESTDWMessageClient; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWMessageCoder.pas b/CORE/Source/Basic/Mechanics/uRESTDWMessageCoder.pas index d5dc584c3..1dd966211 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWMessageCoder.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWMessageCoder.pas @@ -1,21 +1,21 @@ unit uRESTDWMessageCoder; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWMessageCoderBinHex4.pas b/CORE/Source/Basic/Mechanics/uRESTDWMessageCoderBinHex4.pas index f3aece74b..1a16638bb 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWMessageCoderBinHex4.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWMessageCoderBinHex4.pas @@ -1,21 +1,21 @@ unit uRESTDWMessageCoderBinHex4; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWMessageCoderMIME.pas b/CORE/Source/Basic/Mechanics/uRESTDWMessageCoderMIME.pas index 67e2152bf..fc0f08a82 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWMessageCoderMIME.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWMessageCoderMIME.pas @@ -1,21 +1,21 @@ Unit uRESTDWMessageCoderMIME; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWMessageCoderQuotedPrintable.pas b/CORE/Source/Basic/Mechanics/uRESTDWMessageCoderQuotedPrintable.pas index 3b0304f62..e05b4a039 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWMessageCoderQuotedPrintable.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWMessageCoderQuotedPrintable.pas @@ -1,21 +1,21 @@ unit uRESTDWMessageCoderQuotedPrintable; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/Mechanics/uRESTDWMessageParts.pas b/CORE/Source/Basic/Mechanics/uRESTDWMessageParts.pas index 91eabb1e6..e85d4501b 100644 --- a/CORE/Source/Basic/Mechanics/uRESTDWMessageParts.pas +++ b/CORE/Source/Basic/Mechanics/uRESTDWMessageParts.pas @@ -1,21 +1,21 @@ unit uRESTDWMessageParts; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/uRESTDWBasic.pas b/CORE/Source/Basic/uRESTDWBasic.pas index 5bb9b0673..345b8f7d5 100644 --- a/CORE/Source/Basic/uRESTDWBasic.pas +++ b/CORE/Source/Basic/uRESTDWBasic.pas @@ -1,6 +1,6 @@ unit uRESTDWBasic; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . @@ -5788,7 +5788,8 @@ procedure TRESTDWBasicReceptor.SetAuthenticator( vMessageError, BinaryBlob, vRowsAffected, - vExecute, BinaryEvent, Metadata); + vExecute, BinaryEvent, Metadata, + BinaryCompatibleMode); Except On E : Exception Do Begin @@ -5898,7 +5899,8 @@ procedure TRESTDWBasicReceptor.SetAuthenticator( vMessageError, BinaryBlob, vRowsAffected, - BinaryEvent, Metadata); + BinaryEvent, Metadata, + BinaryCompatibleMode); Except On E : Exception Do Begin diff --git a/CORE/Source/Basic/uRESTDWBasicClass.pas b/CORE/Source/Basic/uRESTDWBasicClass.pas index 1f14aeccb..f81b34b89 100644 --- a/CORE/Source/Basic/uRESTDWBasicClass.pas +++ b/CORE/Source/Basic/uRESTDWBasicClass.pas @@ -1,21 +1,21 @@ unit uRESTDWBasicClass; -{$I ..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -34,9 +34,9 @@ interface uRESTDWBasicTypes; Type - TRESTDWClientRESTBase = Class(TRESTDWComponent) //Novo Componente de Acesso a Requisições REST para o Servidores Diversos + TRESTDWClientRESTBase = Class(TRESTDWComponent) //Novo Componente de Acesso a Requisies REST para o Servidores Diversos Private - //Variáveis, Procedures e Funções Privadas + //Variveis, Procedures e Funes Privadas vRSCharset : TEncodeSelect; vLastErrorCode, vRedirectMaximum : Integer; @@ -227,9 +227,9 @@ interface End; Type - TRESTDWClientHttpBase = Class(TRESTDWComponent) //Novo Componente de Acesso a Requisições REST para o Servidores Diversos + TRESTDWClientHttpBase = Class(TRESTDWComponent) //Novo Componente de Acesso a Requisies REST para o Servidores Diversos Private - //Variáveis, Procedures e Funções Privadas + //Variveis, Procedures e Funes Privadas vRSCharset : TEncodeSelect; vLastErrorCode, vRedirectMaximum : Integer; diff --git a/CORE/Source/Basic/uRESTDWBasicDB.pas b/CORE/Source/Basic/uRESTDWBasicDB.pas index b76bcee38..1f514cc81 100644 --- a/CORE/Source/Basic/uRESTDWBasicDB.pas +++ b/CORE/Source/Basic/uRESTDWBasicDB.pas @@ -1,6 +1,6 @@ unit uRESTDWBasicDB; -{$I ..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . @@ -835,7 +835,7 @@ interface Procedure Open (strSQL : String);Overload; Virtual;//Método Open que será utilizado no Componente Procedure ExecOrOpen; //Método Open que será utilizado no Componente Procedure Close; Virtual; //Método Close que será utilizado no Componente - Procedure CreateDataSet; + Procedure CreateDataSet (Const aDataset : TDataset); Class Procedure CreateEmptyDataset(Const Dataset : TDataset); Procedure CreateDatasetFromList; Procedure ExecSQL;Overload; //Método ExecSQL que será utilizado no Componente @@ -1086,7 +1086,7 @@ interface Function FieldExist (Value : String) : TField; Procedure Open; Overload; //Virtual; //Método Open que será utilizado no Componente Procedure Close; Virtual; //Método Close que será utilizado no Componente - Procedure CreateDataSet; + Procedure CreateDataSet (Const aDataset : TDataset); Class Procedure CreateEmptyDataset(Const Dataset : TDataset); Procedure CreateDatasetFromList; Function ParamByName (Value : String) : TParam; //Retorna o Parametro de Acordo com seu nome @@ -5858,14 +5858,17 @@ procedure TRESTDWClientSQL.SetMasterDataSet(Value: TRESTDWClientSQL); End; {$IFDEF FPC} -function TRESTDWClientSQL.GetDatabaseCharSet: TDatabaseCharSet; +Function TRESTDWClientSQL.GetDatabaseCharSet: TDatabaseCharSet; Begin Result := vDatabaseCharSet; End; -procedure TRESTDWClientSQL.SetDatabaseCharSet(Value: TDatabaseCharSet); +Procedure TRESTDWClientSQL.SetDatabaseCharSet(Value: TDatabaseCharSet); Begin vDatabaseCharSet := Value; + {$IFDEF RESTDWMEMTABLE} + TRESTDWMemTable(Self).DatabaseCharSet := Value; + {$ENDIF} End; {$ENDIF} @@ -8419,7 +8422,7 @@ procedure TRESTDWClientSQL.SetSQL(Value: TStringList); vSQL.Add(Value[I]); End; -Procedure TRESTDWTable.CreateDataSet; +Procedure TRESTDWTable.CreateDataSet(Const aDataset : TDataset); Begin vCreateDS := True; SetInBlockEvents(True); @@ -8459,13 +8462,14 @@ procedure TRESTDWClientSQL.SetSQL(Value: TStringList); vInactive := Value; End; -Procedure TRESTDWClientSQL.CreateDataSet; +Procedure TRESTDWClientSQL.CreateDataSet(Const aDataset : TDataset); Begin vCreateDS := True; SetInBlockEvents(True); Try {$IFDEF RESTDWMEMTABLE} EmptyTable; + TRESTDWMemTable(aDataset).CreateDataset; {$ENDIF} vCreateDS := False; vActive := Not vCreateDS; @@ -8562,7 +8566,7 @@ procedure TRESTDWClientSQL.SetSQL(Value: TStringList); Else FieldDef.Required := vFieldsList[I].Required; End; - CreateDataset; + CreateDataset(TDataset(Self)); End; Procedure TRESTDWClientSQL.CreateDatasetFromList; @@ -8614,7 +8618,7 @@ procedure TRESTDWClientSQL.SetSQL(Value: TStringList); Else FieldDef.Required := vFieldsList[I].Required; End; - CreateDataset; + CreateDataset(TDataset(Self)); End; procedure TRESTDWTable.CleanFieldList; @@ -10669,7 +10673,7 @@ procedure TRESTDWTable.SetDatabaseCharSet(Value: TDatabaseCharSet); Begin For J := 0 To vTempDS.Fields.Count - 1 Do Begin - vFieldDefinition.FieldName := vTempDS.Fields[J].Name; + vFieldDefinition.FieldName := vTempDS.Fields[J].FieldName; vFieldDefinition.DataType := vTempDS.Fields[J].DataType; If (vFieldDefinition.DataType <> ftFloat) Then vFieldDefinition.Size := vTempDS.Fields[J].Size @@ -10684,6 +10688,7 @@ procedure TRESTDWTable.SetDatabaseCharSet(Value: TDatabaseCharSet); vFieldDefinition.Required := vTempDS.Fields[J].Required; NewDataField(vFieldDefinition); End; + End; End; Finally diff --git a/CORE/Source/Basic/uRESTDWBasicDbTypes.pas b/CORE/Source/Basic/uRESTDWBasicDbTypes.pas index cc4f08040..550a93f17 100644 --- a/CORE/Source/Basic/uRESTDWBasicDbTypes.pas +++ b/CORE/Source/Basic/uRESTDWBasicDbTypes.pas @@ -1,22 +1,22 @@ unit uRESTDWBasicDbTypes; -{$I ..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -32,101 +32,9 @@ Interface Uses - {$IFNDEF FPC} - {$IF CompilerVersion < 21} - DbTables, - {$IFEND} - {$ENDIF} - SysUtils, Classes, Db, FMTBcd, + SysUtils, Classes, Db, uRESTDWAbout, uRESTDWProtoTypes, uRESTDWConsts, uRESTDWTools; - Type - TRESTDWMemTableAE = Class - End; - TFieldAttrs = Array of Byte; - TMemBlobData = TRESTDWBytes; - TMemBlobArray = Array Of TMemBlobData; - PMemBlobArray = ^TMemBlobArray; - - {$IFNDEF FPC} - {$IF CompilerVersion > 21} - PRESTDWMTMemBuffer = PByte; - TRESTDWMTBookmark = TBookmark; - TRESTDWMTValueBuffer = TValueBuffer; - TRESTDWMTRecordBuffer = TRecordBuffer; - {$ELSE} - {$IFDEF UNICODE} - PRESTDWMTMemBuffer = PByte; - {$ELSE} - PRESTDWMTMemBuffer = PAnsiChar; - {$ENDIF UNICODE} - TRESTDWMTBookmark = Pointer; - TRESTDWMTValueBuffer = Pointer; - TRESTDWMTRecordBuffer = Pointer; - {$IFEND} - {$ELSE} - TValueBuffer = Array of Byte; - PRESTDWMTMemBuffer = PByte; - TRESTDWMTBookmark = Pointer; - TRESTDWMTValueBuffer = Pointer; - TRESTDWMTRecordBuffer = TRecordBuffer; - {$ENDIF} - PMemBlobData = ^TRESTDWBytes; - Type - PRESTDWMTMemoryRecord = ^TRESTDWMTMemoryRecord; - TRESTDWMTMemoryRecord = Class(TPersistent) - Private - FMemoryData : TRESTDWMemTableAE; - FIndex, - FID : Integer; - FData : Pointer; - FIsNull : Boolean; - Function GetIndex : Integer; - Procedure SetMemoryData(Value : TRESTDWMemTableAE; - UpdateParent : Boolean); - Protected - Procedure SetIndex (Value : Integer); Virtual; - Public - FBlobs : TMemBlobArray; - Constructor Create (MemoryData : TRESTDWMemTableAE); Virtual; - Constructor CreateEx (MemoryData : TRESTDWMemTableAE; - UpdateParent : Boolean); Virtual; - Destructor Destroy;Override; - Property MemoryData : TRESTDWMemTableAE Read FMemoryData; - Property ID : Integer Read FID Write FID; - Property Index : Integer Read GetIndex Write SetIndex; - Property Data : Pointer Read FData Write FData; - Property Blobs : TMemBlobArray Read FBlobs Write FBlobs; - Property IsNull : Boolean Read FIsNull Write FIsNull; - End; - Type - IRESTDWMemTable = Interface - Function GetRecordCount : Integer; - Function GetMemoryRecord (Index : Integer) : TRESTDWMTMemoryRecord; - Function GetOffSets (aField : TField) : Word;Overload; - Function GetOffSets (Index : Integer) : Word;Overload; - Function GetOffSetsBlobs : Word; - Function DataTypeSuported(datatype : TFieldType) : Boolean; // new - Function DataTypeIsBlobTypes(datatype : TFieldType) : Boolean; // new - Function GetBlobRec (Field : TField; - Rec : TRESTDWMTMemoryRecord) : TMemBlobData; - Function CreateBlobStream (Field : TField; - Mode : TBlobStreamMode) : TStream; - Function GetCalcFieldLen (FieldType: TFieldType; - Size : Word) : Word; - Procedure InternalAddRecord (Buffer : {$IFDEF FPC}Pointer{$ELSE} - {$IFDEF RESTDWANDROID}TRecBuf{$ELSE} - {$IF CompilerVersion >22}Pointer{$ELSE}TRecordBuffer{$IFEND}{$ENDIF}{$ENDIF}; - aAppend : Boolean); - Procedure InitRecord (Buffer : {$IFDEF NEXTGEN}TRecBuf{$ELSE}TRecordBuffer{$ENDIF}); - Function AllocRecordBuffer : TRecordBuffer; - Procedure SetMemoryRecordData(Buffer : PRESTDWMTMemBuffer; - Pos : Integer); - Procedure AfterLoad; - Function GetDataset : TDataset; - Function GetBlob (RecNo, Index : Integer) : PMemBlobData; - Procedure Loaded; - End; Type TConnectionDefs = Class(TPersistent) Private @@ -201,7 +109,7 @@ TRESTDWStorageBase = class(TRESTDWComponent) implementation -Uses uRESTDWMemoryDataset, uRESTDWDataJSON, uRESTDWJSONInterface; +Uses uRESTDWJSONInterface; constructor TRESTDWStorageBase.Create(AOwner: TComponent); Begin @@ -237,7 +145,7 @@ constructor TRESTDWStorageBase.Create(AOwner: TComponent); Procedure TRESTDWStorageBase.LoadFromStream(Dataset: TDataset; stream: TStream); Begin - LoadDWMemFromStream(TRESTDWMemtable(Dataset), stream); + LoadDatasetFromStream(Dataset, stream); End; Procedure TRESTDWStorageBase.SaveDatasetToStream(Dataset: TDataset; Var stream: TStream); @@ -400,91 +308,4 @@ constructor TRESTDWStorageBase.Create(AOwner: TComponent); End; End; -// === { TRESTDWMTMemoryRecord } ==================================================== -Constructor TRESTDWMTMemoryRecord.Create(MemoryData: TRESTDWMemTableAE); -Begin - FIsNull := True; - FIndex := -1; - CreateEx(MemoryData, True); -End; - -Constructor TRESTDWMTMemoryRecord.CreateEx(MemoryData: TRESTDWMemTableAE; UpdateParent: Boolean); -Begin - Inherited Create; - SetMemoryData(MemoryData, UpdateParent); -End; - -Destructor TRESTDWMTMemoryRecord.Destroy; -Begin - SetMemoryData(Nil, False); -// Finalize(FBlobs); -// SetLength(FBlobs, 0); - Inherited Destroy; -End; - -Function TRESTDWMTMemoryRecord.GetIndex: Integer; -Begin -// If FMemoryData <> Nil then -// Result := FMemoryData.FRecords.IndexOf(Self) -// Else - Result := FIndex; -End; - -Procedure TRESTDWMTMemoryRecord.SetMemoryData(Value: TRESTDWMemTableAE; UpdateParent: Boolean); -var - I, DataSize: Integer; -Begin - If FMemoryData <> Value then - Begin - If FMemoryData <> nil then - Begin - If TRESTDWMemTable(FMemoryData).BlobFieldCount > 0 Then - Begin -// {$IFDEF FPC} - SetLength(FBlobs, 0); //Finalize(FBlobs, FMemoryData.BlobFieldCount); -// {$ELSE} -// Finalize(FBlobs); -// {$ENDIF} - End; - TRESTDWMemTable(FMemoryData).FRecords.Remove(Self); - {$IFDEF FPC} - ReallocMem(FData, 0); - {$ELSE} - FreeMem(FData, SizeOf(FData)); -// ReallocMem(FData, 0); - {$ENDIF} - FMemoryData := Nil; - End; - If Value <> Nil then - Begin - If UpdateParent then - Begin - TRESTDWMemTable(Value).FRecords.Add(Self); - Inc(TRESTDWMemTable(Value).FLastID); - FID := TRESTDWMemTable(Value).FLastID; - End; - FMemoryData := Value; - If TRESTDWMemTable(Value).BlobFieldCount > 0 then - Begin - SetLength(FBlobs, 0); - SetLength(FBlobs, TRESTDWMemTable(Value).BlobFieldCount); - End; - DataSize := 0; - For I := 0 to TRESTDWMemTable(Value).Fields.Count - 1 do - CalcDataSize(TRESTDWMemTable(Value).Fields[I], DataSize); - ReallocMem(FData, DataSize); - End; - End; -End; - -Procedure TRESTDWMTMemoryRecord.SetIndex(Value: Integer); -var - CurIndex: Integer; -Begin - CurIndex := GetIndex; - If (CurIndex >= 0) and (CurIndex <> Value) then - TRESTDWMemTable(FMemoryData).FRecords.Move(CurIndex, Value); - FIndex := Value; -End; - end. diff --git a/CORE/Source/Basic/uRESTDWBasicTypes.pas b/CORE/Source/Basic/uRESTDWBasicTypes.pas index 20b16d411..5a7c8fb6b 100644 --- a/CORE/Source/Basic/uRESTDWBasicTypes.pas +++ b/CORE/Source/Basic/uRESTDWBasicTypes.pas @@ -1,22 +1,22 @@ unit uRESTDWBasicTypes; -{$I ..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -230,7 +230,7 @@ TRESTDWClientSQLBase = Class(TZMemTable) {$ENDIF} {$IFDEF RESTDWMEMTABLE} - TRESTDWClientSQLBase = Class(TRESTDWMemTableEx) //Classe com as funcionalidades de um DBQuery + TRESTDWClientSQLBase = Class(TRESTDWMemTable) //Classe com as funcionalidades de um DBQuery {$ENDIF} {$ELSE} {$IFDEF UNIDACMEM} @@ -243,7 +243,7 @@ TRESTDWClientSQLBase = Class(TFDMemtable) //Classe com as funcionalidades de um DBQuery {$ENDIF} {$IFDEF RESTDWMEMTABLE} - TRESTDWClientSQLBase = Class(TRESTDWMemTableEx) //Classe com as funcionalidades de um DBQuery + TRESTDWClientSQLBase = Class(TRESTDWMemTable) //Classe com as funcionalidades de um DBQuery {$ENDIF} {$ENDIF} Private diff --git a/CORE/Source/Basic/uRESTDWBufferBase.pas b/CORE/Source/Basic/uRESTDWBufferBase.pas index 614129bb9..ce21e74ea 100644 --- a/CORE/Source/Basic/uRESTDWBufferBase.pas +++ b/CORE/Source/Basic/uRESTDWBufferBase.pas @@ -1,22 +1,22 @@ unit uRESTDWBufferBase; -{$I ..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. A. Brito - Admin - Administrador do desenvolvimento. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/uRESTDWBufferDb.pas b/CORE/Source/Basic/uRESTDWBufferDb.pas index 0597632c6..aacb3d4ef 100644 --- a/CORE/Source/Basic/uRESTDWBufferDb.pas +++ b/CORE/Source/Basic/uRESTDWBufferDb.pas @@ -1,21 +1,21 @@ unit uRESTDWBufferDb; -{$I ..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -602,7 +602,7 @@ interface vFieldsImport.ItemAdd(FieldImport); End; End; - Procedure CreateFields(Value : String); //Carrega os campos a partir da Variável + Procedure CreateFields(Value : String); //Carrega os campos a partir da Varivel Var I : Integer; vFieldName : String; diff --git a/CORE/Source/Basic/uRESTDWComponentEvents.pas b/CORE/Source/Basic/uRESTDWComponentEvents.pas index f3bda322c..6c6b18cbb 100644 --- a/CORE/Source/Basic/uRESTDWComponentEvents.pas +++ b/CORE/Source/Basic/uRESTDWComponentEvents.pas @@ -1,21 +1,21 @@ unit uRESTDWComponentEvents; -{$I ..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/uRESTDWDesignReg.pas b/CORE/Source/Basic/uRESTDWDesignReg.pas index a51c986b1..55cef24a4 100644 --- a/CORE/Source/Basic/uRESTDWDesignReg.pas +++ b/CORE/Source/Basic/uRESTDWDesignReg.pas @@ -1,22 +1,22 @@ unit uRESTDWDesignReg; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -37,7 +37,7 @@ interface fpWeb, TypInfo, {$ELSE} {$IFNDEF RESTDWLAMW} - Windows, + Windows, Forms, Controls, StdCtrls, ExtCtrls, Dialogs, {$IFDEF DELPHIXE2UP} vcl.Graphics, {$ELSE} @@ -58,7 +58,11 @@ interface uRESTDWBasicClass, uRESTDWDatamodule, uRESTDWServerEvents, uRESTDWBasicDB, uRESTDWServerContext, uRESTDWServerRoutes, uRESTDWMassiveBuffer, uRESTDWMemoryDataset, uRESTDWBufferDb, uRESTDWAbout, uRESTDWDriverBase, - uRESTDWAuthenticators; + uRESTDWAuthenticators, uRESTDWHTMLEditor, + {$IFNDEF RESTDWLAZARUS} + uRESTDWFMXHTMLEditor, + {$ENDIF} + uRESTDWHTMLDesigner; {$IFNDEF RESTDWDELPHINET} Const @@ -198,6 +202,23 @@ TDriverConnectionListProperty = class(TComponentProperty) Function GetVerb (Index : Integer): String; Override; Procedure ExecuteVerb(Index : Integer); Override; End; + +Type + TRESTDWHTMLEditorComponentEditor = Class(TComponentEditor) + Public + Function GetVerbCount : Integer; Override; + Function GetVerb (Index : Integer): String; Override; + Procedure ExecuteVerb(Index : Integer); Override; + End; + + {$IFNDEF RESTDWLAZARUS} + TRESTDWFMXHTMLEditorComponentEditor = Class(TComponentEditor) + Public + Function GetVerbCount : Integer; Override; + Function GetVerb (Index : Integer): String; Override; + Procedure ExecuteVerb(Index : Integer); Override; + End; + {$ENDIF} {$ENDIF} {$IFDEF RESTDWLAZARUS} @@ -449,15 +470,15 @@ procedure UnregisterAboutBox; Procedure TRESTDWDesigner.EndUpdateFieldDefs; Begin Inherited; - If TRESTDWClientSQL(DataSet).Active Then - TRESTDWClientSQL(DataSet).Close; + //If TRESTDWClientSQL(DataSet).Active Then corrido addfields para novos campos + // TRESTDWClientSQL(DataSet).Close; End; Procedure TRESTDWDesigner.InitializeMenu(Menu: TPopupMenu); Begin Inherited; // Ao clicar duas vezes no componente RESTDWClientSQL - // ou ao selecionar no popup menu opção "Fields Editor". + // ou ao selecionar no popup menu opo "Fields Editor". End; Procedure TRESTDWDesigner.UpdateMenus(Menu: TPopupMenu; EditState: TEditState); @@ -724,6 +745,7 @@ procedure TRESTDWServerContextEditor.ExecuteVerb(Index: Integer); End; end; + procedure TRESTDWContextRulesEditor.ExecuteVerb(Index: Integer); Begin Case Index of @@ -732,6 +754,10 @@ procedure TRESTDWContextRulesEditor.ExecuteVerb(Index: Integer); {$ELSE} TCollectionPropertyEditor.ShowCollectionEditor(TRESTDWContextRules(Component).Items, Component, 'Items'); {$ENDIF} + 1 : Begin + If RESTDWExecuteContextRulesHTMLDesigner(TRESTDWContextRules(Component)) Then + Designer.Modified; + End; End; end; @@ -746,6 +772,7 @@ procedure TRESTDWContextRulesEditor.ExecuteVerb(Index: Integer); Begin Case Index of 0 : Result := '&ContextRules Editor'; + 1 : Result := 'Web Site Designer...'; End; End; @@ -756,7 +783,7 @@ procedure TRESTDWContextRulesEditor.ExecuteVerb(Index: Integer); Function TRESTDWContextRulesEditor.GetVerbCount: Integer; Begin - Result := 1; + Result := 2; End; {$ENDIF} @@ -786,21 +813,12 @@ procedure TRESTDWContextRulesEditor.ExecuteVerb(Index: Integer); Procedure Register; Begin {$IFDEF FPC} -// RegFields(DefaultFieldClasses); - RegField(TRESTDWNumericField); - RegField(TStringFieldRESTDW); - RegField(TStreamField); -// RegField(TRESTDWSQLTimeStampOffsetField); - {$ELSE} - {$IFDEF RESTDWMEMTABLE} - RegisterFields([TStringFieldRESTDW]); - RegisterFields([TRESTDWNumericField]); - RegisterFields([TStreamField]); + {$IFDEF RESTDWLAMW} + {$I RESTDataWareComponents_LAMW.lrs} + {$ELSE} + {$I RESTDataWareComponents.lrs} {$ENDIF} {$ENDIF} - {$IFDEF FPC} - {$I RESTDataWareComponents_LAMW.lrs} - {$ENDIF} {$IFNDEF RESTDWLAZARUS} {$IFNDEF RESTDWLAMW} RegisterNoIcon([TServerMethodDataModule]); @@ -824,7 +842,10 @@ procedure TRESTDWContextRulesEditor.ExecuteVerb(Index: Integer); TRESTDWServerRoutes, TRESTDWContextRules]); {$IFNDEF RESTDWLAMW} - RegisterComponents('REST Dataware - Tools', [TRESTDWResponseTranslator, TRESTDWBufferDB]); + RegisterComponents('REST Dataware - Tools', [TRESTDWResponseTranslator, TRESTDWBufferDB, TRESTDWHTMLEditor]); + {$IFNDEF RESTDWLAZARUS} + RegisterComponents('REST Dataware - FMX', [TRESTDWFMXHTMLEditor]); + {$ENDIF} {$ENDIF} RegisterComponents('REST Dataware - DB', [TRESTDWPoolerDB, TRESTDWMemTable, TRESTDWClientSQL, TRESTDWTable, TRESTDWUpdateSQL, TRESTDWMassiveSQLCache, @@ -856,16 +877,92 @@ procedure TRESTDWContextRulesEditor.ExecuteVerb(Index: Integer); RegisterPropertyEditor (TypeInfo(TRESTDWComponent), TRESTDWResponseTranslator, 'ClientREST', TRESTDWClientRESTList); RegisterComponentEditor(TRESTDWServerContext, TComponentEditorClass(TRESTDWServerContextEditor)); RegisterComponentEditor(TRESTDWContextRules, TComponentEditorClass(TRESTDWContextRulesEditor)); + RegisterComponentEditor(TRESTDWHTMLEditor, TComponentEditorClass(TRESTDWHTMLEditorComponentEditor)); + {$IFNDEF RESTDWLAZARUS} + RegisterComponentEditor(TRESTDWFMXHTMLEditor, TComponentEditorClass(TRESTDWFMXHTMLEditorComponentEditor)); + {$ENDIF} {$ENDIF} {$IFNDEF RESTDWLAZARUS} {$IFNDEF RESTDWLAMW} RegisterComponentEditor(TRESTDWClientSQL, TRESTDWClientSQLEditor); RegisterComponentEditor(TRESTDWServerContext, TRESTDWServerContextEditor); RegisterComponentEditor(TRESTDWContextRules, TRESTDWContextRulesEditor); + RegisterComponentEditor(TRESTDWHTMLEditor, TRESTDWHTMLEditorComponentEditor); + RegisterComponentEditor(TRESTDWFMXHTMLEditor, TRESTDWFMXHTMLEditorComponentEditor); {$ENDIF} {$ENDIF} End; + +Function TRESTDWHTMLEditorComponentEditor.GetVerbCount : Integer; +Begin + Result := 1; +End; + +Function TRESTDWHTMLEditorComponentEditor.GetVerb(Index : Integer) : String; +Begin + Result := '&HTML Designer'; +End; + +Procedure TRESTDWHTMLEditorComponentEditor.ExecuteVerb(Index : Integer); +Var + LContext : TRESTDWContextRules; +Begin + If Index <> 0 Then + Exit; + + LContext := TRESTDWContextRules.Create(Nil); + Try + LContext.MasterHtml.Assign(TRESTDWHTMLEditor(Component).HTML); + If RESTDWExecuteContextRulesHTMLDesigner( + LContext, + TRESTDWHTMLEditor(Component).EditorTitle + ) Then + Begin + TRESTDWHTMLEditor(Component).HTML.Assign(LContext.MasterHtml); + Designer.Modified; + End; + Finally + LContext.Free; + End; +End; + +{$IFNDEF RESTDWLAZARUS} +Function TRESTDWFMXHTMLEditorComponentEditor.GetVerbCount : Integer; +Begin + Result := 1; +End; + +Function TRESTDWFMXHTMLEditorComponentEditor.GetVerb(Index : Integer) : String; +Begin + Result := '&HTML Designer'; +End; + +Procedure TRESTDWFMXHTMLEditorComponentEditor.ExecuteVerb(Index : Integer); +Var + LContext : TRESTDWContextRules; +Begin + If Index <> 0 Then + Exit; + + LContext := TRESTDWContextRules.Create(Nil); + Try + LContext.MasterHtml.Assign(TRESTDWFMXHTMLEditor(Component).HTML); + + If RESTDWExecuteContextRulesHTMLDesigner( + LContext, + TRESTDWFMXHTMLEditor(Component).EditorTitle + ) Then + Begin + TRESTDWFMXHTMLEditor(Component).HTML.Assign(LContext.MasterHtml); + Designer.Modified; + End; + Finally + LContext.Free; + End; +End; +{$ENDIF} + { TRESTDWServerEventsEditor } {$IFNDEF RESTDWLAMW} procedure TRESTDWServerEventsEditor.ExecuteVerb(Index: Integer); @@ -910,6 +1007,8 @@ function TRESTDWServerEventsEditor.GetVerbCount: Integer; End; End; +{$ENDIF} + Function TRESTDWClientEventsEditor.GetVerb(Index: Integer): string; Begin Case Index of @@ -992,6 +1091,9 @@ procedure TServerEventsList.GetValues(Proc: TGetStrProc); vConnection.CriptOptions.Use := vRESTClientPooler.CriptOptions.Use; vConnection.CriptOptions.Key := vRESTClientPooler.CriptOptions.Key; vConnection.DataRoute := vRESTClientPooler.DataRoute; + vConnection.TypeRequest := vRESTClientPooler.TypeRequest; + vConnection.SSLMethod := vRESTClientPooler.SSLMethod; + vConnection.SSLVersions := vRESTClientPooler.SSLVersions; vConnection.AuthenticationOptions.Assign(vRESTClientPooler.AuthenticationOptions); Result := TStringList.Create; Try @@ -1072,7 +1174,6 @@ procedure TRESTDWFieldsList.GetValues(Proc: TGetStrProc); End; End; End; -{$ENDIF} {$IFDEF RESTDWLAZARUS} Procedure UnlistPublishedProperty (ComponentClass:TPersistentClass; const PropertyName:String); diff --git a/CORE/Source/Basic/uRESTDWFileBuffer.pas b/CORE/Source/Basic/uRESTDWFileBuffer.pas index c854983c2..a8878a45d 100644 --- a/CORE/Source/Basic/uRESTDWFileBuffer.pas +++ b/CORE/Source/Basic/uRESTDWFileBuffer.pas @@ -1,21 +1,21 @@ unit uRESTDWFileBuffer; -{$I ..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/uRESTDWMasterDetailData.pas b/CORE/Source/Basic/uRESTDWMasterDetailData.pas index 8e4820979..29ae75445 100644 --- a/CORE/Source/Basic/uRESTDWMasterDetailData.pas +++ b/CORE/Source/Basic/uRESTDWMasterDetailData.pas @@ -1,26 +1,26 @@ unit uRESTDWMasterDetailData; -{$I ..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Ivan Cesar - Admin - Administrador do pacote. - Joanan Mendonça Jr. (jlmj) - Admin - Administrador do pacote. + Joanan Mendona Jr. (jlmj) - Admin - Administrador do pacote. Giovani da Cruz - Admin - Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Alexandre Souza - Admin - Administrador do Grupo de Organização. + Alexandre Souza - Admin - Administrador do Grupo de Organizao. Mizael Rocha - Member Tester and DEMO Developer. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Itamar Gaucho - Member Tester and DEMO Developer. Ico Menezes - Member Tester and DEMO Developer. } diff --git a/CORE/Source/Basic/uRESTDWParams.pas b/CORE/Source/Basic/uRESTDWParams.pas index 7162215d1..a24ed05e1 100644 --- a/CORE/Source/Basic/uRESTDWParams.pas +++ b/CORE/Source/Basic/uRESTDWParams.pas @@ -1,21 +1,21 @@ unit uRESTDWParams; -{$I ..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -47,6 +47,7 @@ interface Type TDWParamExpType = (tdwpxt_All, tdwpxt_IN, tdwpxt_OUT, tdwpxt_INOUT); TProcedureEvent = Procedure Of Object; + TProcedureDbEvent = Procedure(Const aDataset : TDataset) Of Object; TNewDataField = Procedure (FieldDefinition : TFieldDefinition) Of Object; TFieldExist = Function (Const Dataset : TDataset; Value : String) : TField Of Object; @@ -62,7 +63,7 @@ interface TRESTDWJSONValue = Class Private vFieldExist : TFieldExist; - vCreateDataset, + vCreateDataset : TProcedureDbEvent; vNewFieldList : TProcedureEvent; vNewDataField : TNewDataField; vSetInitDataset : TSetInitDataset; @@ -120,8 +121,8 @@ interface Function GetFieldExist : TFieldExist; Function aFieldExist (Const Dataset : TDataset; Value : String) : TField; - Function GetCreateDataSet : TProcedureEvent; - Procedure aCreateDataSet; + Function GetCreateDataSet : TProcedureDbEvent; + Procedure aCreateDataSet (Const aDataset : TDataset); Procedure aSetInitDataset (Const Value : Boolean); Function GetSetInitDataset : TSetInitDataset; Procedure aSetRecordCount (aJsonCount, @@ -221,7 +222,7 @@ interface Property ServerFieldList : TFieldsList Read vFieldsList Write SetFieldsList; Property NewFieldList : TProcedureEvent Read GetNewFieldList Write vNewFieldList; Property FieldExist : TFieldExist Read GetFieldExist Write vFieldExist; - Property CreateDataset : TProcedureEvent Read GetCreateDataSet Write vCreateDataset; + Property CreateDataset : TProcedureDbEvent Read GetCreateDataSet Write vCreateDataset; Property NewDataField : TNewDataField Read GetNewDataField Write vNewDataField; Property SetInitDataset : TSetInitDataset Read GetSetInitDataset Write vSetInitDataset; Property SetRecordCount : TSetRecordCount Read GetSetRecordCount Write vSetRecordCount; @@ -422,7 +423,7 @@ interface // Propriedades Novas Property Value : Variant Read GetVariantValue Write SetVariantValue; Property DefaultValue : Variant Read vDefaultValue Write vDefaultValue; - // Novas definições por tipo + // Novas definies por tipo Property AsBCD : Currency Read GetAsBCD Write SetAsBCD; Property AsFMTBCD : Currency Read GetAsFMTBCD Write SetAsFMTBCD; Property AsBoolean : Boolean Read GetAsBoolean Write SetAsBoolean; @@ -1061,105 +1062,116 @@ procedure TRESTDWParamsMethods.PutRecName(Index: String; Item: TRESTDWParamMetho End; End; -Function TRESTDWJSONValue.FormatValue(bValue : String) : String; +Function TRESTDWJSONValue.FormatValue(bValue : String) : String; //corrigida by Gledston 06/08/2026 Var - aResult : String; - vInsertTag : Boolean; + aResult : String; + vInsertTag : Boolean; Begin - aResult := bValue; - vInsertTag := vObjectValue In [ovDate, ovTime, ovDateTime, - ovTimestamp]; - If Trim(aResult) <> '' Then + aResult := bValue; + vInsertTag := vObjectValue In [ovDate, ovTime, ovDateTime, ovTimestamp]; + + If Trim(aResult) <> '' Then Begin - If (aResult[InitStrPos] = '"') And - (aResult[Length(aResult) - FinalStrPos] = '"') Then + If (Length(aResult) >= 2) And + (aResult[InitStrPos] = '"') And + (aResult[Length(aResult) - FinalStrPos] = '"') Then Begin - Delete(aResult, 1, 1); - Delete(aResult, Length(aResult), 1); + Delete(aResult, 1, 1); + Delete(aResult, Length(aResult), 1); End; End; - If Not vEncoded Then + + // SANITIZAO: Remove sujeiras de fechamento de JSON (']', '}') anexadas ao Base64/bValue + aResult := Trim(aResult); + If vObjectValue In [ovBlob, ovStream, ovGraphic, ovOraBlob, ovOraClob] Then Begin - If Trim(aResult) <> '' Then - If Not(((Pos('{', aResult) > 0) And (Pos('}', aResult) > 0)) Or - ((Pos('[', aResult) > 0) And (Pos(']', aResult) > 0))) Then - If Not(vObjectValue In [ovStream, ovBlob, ovGraphic, ovOraBlob, ovOraClob]) Then - aResult := StringToJsonString(aResult); + While (Length(aResult) > 0) And (aResult[Length(aResult)] In [']', '}', '"', #10, #13, ' ']) Do + Delete(aResult, Length(aResult), 1); End; - If vNullValue Then - aResult := cNullvalue - Else If ((Trim(aResult) = '') or (Trim(bValue) = cNullvalueTag)) And vInsertTag Then - aResult := cBlankStringJSON; - If DataMode = dmDataware Then + + If Not vEncoded Then Begin - If (vTypeObject = toDataset) Then - Result := Format(TValueFormatJSON, ['ObjectType', GetObjectName(vTypeObject), 'Direction', - GetDirectionName(vObjectDirection), 'Encoded', - EncodedString, 'ValueType', GetValueType(vObjectValue), - vtagName, GetValueJSON(aResult)]) - Else If (vObjectValue = ovObject) And (vEncoded) Then - Result := Format(TValueFormatJSONValueS, ['ObjectType', GetObjectName(vTypeObject), 'Direction', - GetDirectionName(vObjectDirection), 'Encoded', - EncodedString, 'ValueType', GetValueType(vObjectValue), - vtagName, GetValueJSON(aResult)]) //TValueFormatJSON - Else If (vObjectValue = ovObject) Then - Result := Format(TValueFormatJSONValue, ['ObjectType', GetObjectName(vTypeObject), 'Direction', - GetDirectionName(vObjectDirection), 'Encoded', - EncodedString, 'ValueType', GetValueType(vObjectValue), - vtagName, GetValueJSON(aResult)]) //TValueFormatJSON - Else - Begin - If vNullValue Then - Result := Format(TValueFormatJSONValue, ['ObjectType', GetObjectName(vTypeObject), 'Direction', - GetDirectionName(vObjectDirection), 'Encoded', - EncodedString, 'ValueType', GetValueType(vObjectValue), - vtagName, GetValueJSON(aResult)]) - Else If (vObjectValue in [ovString, ovGuid, ovWideString, ovMemo, - ovWideMemo, ovFmtMemo, ovFixedChar]) Or (vInsertTag) Then - Result := Format(TValueFormatJSONValueS, ['ObjectType', GetObjectName(vTypeObject), 'Direction', - GetDirectionName(vObjectDirection), 'Encoded', - EncodedString, 'ValueType', GetValueType(vObjectValue), + If Trim(aResult) <> '' Then + If Not ((aResult.StartsWith('{') and aResult.EndsWith('}')) Or + (aResult.StartsWith('[') and aResult.EndsWith(']'))) Then + If Not (vObjectValue In [ovStream, ovBlob, ovGraphic, ovOraBlob, ovOraClob]) Then + aResult := StringToJsonString(aResult); + End; + + If vNullValue Then + aResult := cNullvalue + Else If ((Trim(aResult) = '') Or (Trim(bValue) = cNullvalueTag)) And vInsertTag Then + aResult := cBlankStringJSON; + + If DataMode = dmDataware Then + Begin + If (vTypeObject = toDataset) Then + Result := Format(TValueFormatJSON, ['ObjectType', GetObjectName(vTypeObject), + 'Direction', GetDirectionName(vObjectDirection), + 'Encoded', EncodedString, + 'ValueType', GetValueType(vObjectValue), + vtagName, GetValueJSON(aResult)]) + Else If (vObjectValue = ovObject) And (vEncoded) Then + Result := Format(TValueFormatJSONValueS, ['ObjectType', GetObjectName(vTypeObject), + 'Direction', GetDirectionName(vObjectDirection), + 'Encoded', EncodedString, + 'ValueType', GetValueType(vObjectValue), vtagName, GetValueJSON(aResult)]) - Else If (vObjectValue In [ovFloat, ovCurrency, ovBCD, ovFMTBcd, ovExtended]) Then + Else If (vObjectValue = ovObject) Then + Result := Format(TValueFormatJSONValue, ['ObjectType', GetObjectName(vTypeObject), + 'Direction', GetDirectionName(vObjectDirection), + 'Encoded', EncodedString, + 'ValueType', GetValueType(vObjectValue), + vtagName, GetValueJSON(aResult)]) + Else + Begin + If vNullValue Then + Result := Format(TValueFormatJSONValue, ['ObjectType', GetObjectName(vTypeObject), + 'Direction', GetDirectionName(vObjectDirection), + 'Encoded', EncodedString, + 'ValueType', GetValueType(vObjectValue), + vtagName, GetValueJSON(aResult)]) + Else If (vObjectValue In [ovString, ovGuid, ovWideString, ovMemo, + ovWideMemo, ovFmtMemo, ovFixedChar, + ovBlob, ovStream, ovGraphic, ovOraBlob, ovOraClob]) Or (vInsertTag) Then Begin - Result := Format(TValueFormatJSONValueS, ['ObjectType', GetObjectName(vTypeObject), 'Direction', - GetDirectionName(vObjectDirection), 'Encoded', - EncodedString, 'ValueType', GetValueType(vObjectValue), - vtagName, GetValueJSON(BuildStringFloat(aResult, DataMode, vFloatDecimalFormat))]); + If (Trim(bValue) = cNullvalueTag) Or (aResult = cBlankStringJSON) Then + aResult := ''; + + Result := Format(TValueFormatJSONValueS, ['ObjectType', GetObjectName(vTypeObject), + 'Direction', GetDirectionName(vObjectDirection), + 'Encoded', EncodedString, + 'ValueType', GetValueType(vObjectValue), + vtagName, GetValueJSON(aResult)]); End - Else + Else If (vObjectValue In [ovFloat, ovCurrency, ovBCD, ovFMTBcd, ovExtended]) Then Begin - If (vObjectValue In [ovBlob, ovStream, ovGraphic, ovOraBlob, ovOraClob]) Then - Begin - If aResult <> '' Then - Begin - If (((((aResult <> cBlankStringJSON) And - Not((aResult[InitStrPos] = '"') And - (aResult[Length(aResult) - FinalStrPos] = '"')))) And - (vEncoded)) Or (Not(vEncoded) And (aResult = ''))) Or - (Pos('"', aResult) = 0) Then - aResult := '"' + aResult + '"' - Else If (aResult = '') Then - aResult := cBlankStringJSON; - End - Else - aResult := cBlankStringJSON; - End; - If (Trim(bValue) = cNullvalueTag) Then - Result := Format(TValueFormatJSONValue, ['ObjectType', GetObjectName(vTypeObject), 'Direction', - GetDirectionName(vObjectDirection), 'Encoded', - EncodedString, 'ValueType', GetValueType(vObjectValue), - vtagName, GetValueJSON(Trim(bValue))]) - Else - Result := Format(TValueFormatJSONValue, ['ObjectType', GetObjectName(vTypeObject), 'Direction', - GetDirectionName(vObjectDirection), 'Encoded', - EncodedString, 'ValueType', GetValueType(vObjectValue), - vtagName, GetValueJSON(aResult)]); + aResult := StringReplace(BuildStringFloat(aResult, DataMode, vFloatDecimalFormat), ',', '.', [rfReplaceAll]); + Result := Format(TValueFormatJSONValue, ['ObjectType', GetObjectName(vTypeObject), + 'Direction', GetDirectionName(vObjectDirection), + 'Encoded', EncodedString, + 'ValueType', GetValueType(vObjectValue), + vtagName, GetValueJSON(aResult)]); + End + Else + Begin + If (Trim(bValue) = cNullvalueTag) Then + Result := Format(TValueFormatJSONValue, ['ObjectType', GetObjectName(vTypeObject), + 'Direction', GetDirectionName(vObjectDirection), + 'Encoded', EncodedString, + 'ValueType', GetValueType(vObjectValue), + vtagName, GetValueJSON(Trim(bValue))]) + Else + Result := Format(TValueFormatJSONValue, ['ObjectType', GetObjectName(vTypeObject), + 'Direction', GetDirectionName(vObjectDirection), + 'Encoded', EncodedString, + 'ValueType', GetValueType(vObjectValue), + vtagName, GetValueJSON(aResult)]); End; End; End - Else - Result := aResult; + Else + Result := aResult; End; Function TRESTDWJSONValue.GetValueJSON(bValue : String): String; @@ -1444,7 +1456,7 @@ procedure TRESTDWParamsMethods.PutRecName(Index: String; Item: TRESTDWParamMetho {$IFDEF DELPHIXEUP}ftWideMemo,{$ENDIF} ftFmtMemo, ftFixedChar] Then Begin - If bValue.Fields[i].IsNull Then + If (bValue.Fields[i].IsNull) Then vTempValue := Format('%s%s', [vTempField, cNullvalue]) Else Begin @@ -1760,7 +1772,7 @@ procedure TRESTDWParamsMethods.PutRecName(Index: String; Item: TRESTDWParamMetho End; End; -Function TRESTDWJSONValue.GetCreateDataSet : TProcedureEvent; +Function TRESTDWJSONValue.GetCreateDataSet : TProcedureDbEvent; Begin Result := Nil; If Assigned(vCreateDataset) Then @@ -1779,7 +1791,7 @@ procedure TRESTDWParamsMethods.PutRecName(Index: String; Item: TRESTDWParamMetho End; End; -Procedure TRESTDWJSONValue.aCreateDataSet; +Procedure TRESTDWJSONValue.aCreateDataSet(Const aDataset : TDataset); Begin End; @@ -2127,7 +2139,7 @@ procedure TRESTDWParamsMethods.PutRecName(Index: String; Item: TRESTDWParamMetho vSizeChar : Integer; {$ENDIF} Begin - // Recebe o parametro "DataType" para fazer a tipagem na função que gera a linha "GenerateLine" + // Recebe o parametro "DataType" para fazer a tipagem na funo que gera a linha "GenerateLine" // Tiago Istuque - Por Nemi Vieira - 29/01/2019 vDataType := DataType; vTypeObject := toDataset; @@ -2192,7 +2204,7 @@ procedure TRESTDWParamsMethods.PutRecName(Index: String; Item: TRESTDWParamMetho vSizeChar : Integer; {$ENDIF} Begin - // Recebe o parametro "DataType" para fazer a tipagem na função que gera a linha "GenerateLine" + // Recebe o parametro "DataType" para fazer a tipagem na funo que gera a linha "GenerateLine" // Tiago Istuque - Por Nemi Vieira - 29/01/2019 vDataType := DataType; vTypeObject := toDataset; @@ -2902,8 +2914,8 @@ procedure TRESTDWJSONValue.WriteToDataset(JSONValue: String; const DestDS: TData vLocFieldExist : TFieldExist; vLocSetRecordCount : TSetRecordCount; vLocSetInitDataset : TSetInitDataset; - vLocNewFieldList, - vLocCreateDataset : TProcedureEvent; + vLocNewFieldList : TProcedureEvent; + vLocCreateDataset : TProcedureDbEvent; vLocFieldListCount : TFieldListCount; Function ReadFieldDefs(Var vResult : String; JSONObject, @@ -2966,7 +2978,12 @@ procedure TRESTDWJSONValue.WriteToDataset(JSONValue: String; const DestDS: TData ((bJsonValueB.PairCount > 0) And (I <= bJsonValueB.PairCount)) Do Begin vStringData := bJsonValueB.Pairs[I].Value; - FreeAndNil(bJsonValueB); + {$IFNDEF FPC} + bJsonValueB.DisposeOf; + {$ELSE} + bJsonValueB.Free; + {$ENDIF} + bJsonValueB := Nil; If (vStringData[InitStrPos] = '{') Or (vStringData[InitStrPos] = '[') Then bJsonValueB := TRESTDWJSONInterfaceObject.Create(vStringData) @@ -2979,7 +2996,13 @@ procedure TRESTDWJSONValue.WriteToDataset(JSONValue: String; const DestDS: TData Inc(I); End; If Assigned(bJsonValueB) Then - bJsonValueB.Free; + Begin + {$IFNDEF FPC} + bJsonValueB.DisposeOf; + {$ELSE} + bJsonValueB.Free; + {$ENDIF} + End; vResult := vStringDataTemp; End; // vResult := vStringDataB; @@ -3009,9 +3032,9 @@ procedure TRESTDWJSONValue.WriteToDataset(JSONValue: String; const DestDS: TData vDWFieldDef.ElementName := bJsonValue.pairs[A].Name; vDWFieldDef.ElementIndex := A; vDWFieldDef.FieldName := vDWFieldDef.ElementName; - vDWFieldDef.FieldSize := Length(bJsonValue.pairs[A].Value); - If vDWFieldDef.FieldSize = 0 Then - vDWFieldDef.FieldSize := 100; + vDWFieldDef.FieldSize := 255; + If Length(bJsonValue.pairs[A].Value) > vDWFieldDef.FieldSize Then + vDWFieldDef.FieldSize := Length(bJsonValue.pairs[A].Value); vDWFieldDef.DataType := ovString; End; End; @@ -3078,7 +3101,7 @@ procedure TRESTDWJSONValue.WriteToDataset(JSONValue: String; const DestDS: TData vFieldDefinition := TFieldDefinition.Create; If DestDS.Fields.Count = 0 Then DestDS.FieldDefs.Clear; - //Removendo campos inválidos + //Removendo campos invlidos For J := DestDS.Fields.Count - 1 DownTo 0 Do Begin If DestDS.Fields[J].FieldKind = fkData Then @@ -3114,10 +3137,10 @@ procedure TRESTDWJSONValue.WriteToDataset(JSONValue: String; const DestDS: TData Begin vFieldDefinition.FieldName := vTempValue; vFieldDefinition.DataType := ObjectValueToFieldType(ResponseTranslator.FieldDefs[J].DataType); - If (vFieldDefinition.DataType <> ftFloat) Then - vFieldDefinition.Size := ResponseTranslator.FieldDefs[J].FieldSize - Else - vFieldDefinition.Size := 0; + If Not(vFieldDefinition.DataType in [ftInteger, ftFloat]) Then + vFieldDefinition.Size := ResponseTranslator.FieldDefs[J].FieldSize; +// Else +// vFieldDefinition.Size := 0; If (vFieldDefinition.DataType In [ftFloat, ftCurrency, ftBCD, {$IFDEF DELPHIXEUP}ftExtended, ftSingle,{$ENDIF} ftFMTBcd]) Then @@ -3141,13 +3164,16 @@ procedure TRESTDWJSONValue.WriteToDataset(JSONValue: String; const DestDS: TData // FieldDef.Name := vTempValue; FieldDef.DataType := ObjectValueToFieldType(ResponseTranslator.FieldDefs[J].DataType); If FieldDef.DataType in [ftString, ftWideString] Then - FieldDef.Size := 255; + IF ResponseTranslator.FieldDefs[J].FieldSize <= 0 Then + FieldDef.Size := 255 + Else + FieldDef.Size := ResponseTranslator.FieldDefs[J].FieldSize; If Not (FieldDef.DataType in [ftFloat,ftCurrency {$IFDEF DELPHIXEUP},ftExtended,ftSingle{$ENDIF}]) Then Begin If (FieldDef.Size > ResponseTranslator.FieldDefs[J].FieldSize) then // ajuste em 20/12/2018 Thiago Pedro ResponseTranslator.FieldDefs[J].FieldSize := FieldDef.Size - Else + Else If Not(vFieldDefinition.DataType In [ftInteger]) Then FieldDef.Size := ResponseTranslator.FieldDefs[J].FieldSize; If FieldDef.DataType in [ftString, ftWideString] Then If FieldDef.Size > 4000 Then @@ -3170,7 +3196,7 @@ procedure TRESTDWJSONValue.WriteToDataset(JSONValue: String; const DestDS: TData vLocSetInBlockEvents(True); Inactive := True; If Assigned(vLocCreateDataSet) Then - vLocCreateDataSet(); + vLocCreateDataSet(DestDS); If Not DestDS.Active Then DestDS.Open; If Not DestDS.Active Then @@ -3508,8 +3534,8 @@ procedure TRESTDWJSONValue.WriteToDataset(JSONValue: String; const DestDS: TData vLocFieldExist : TFieldExist; vLocSetRecordCount : TSetRecordCount; vLocSetInitDataset : TSetInitDataset; - vLocNewFieldList, - vLocCreateDataSet : TProcedureEvent; + vLocNewFieldList : TProcedureEvent; + vLocCreateDataSet : TProcedureDbEvent; vLocFieldListCount : TFieldListCount; vLocGetInDesignEvents : TGetInDesignEvents; Function FieldIndex(FieldName: String): Integer; @@ -3673,7 +3699,7 @@ procedure TRESTDWJSONValue.WriteToDataset(JSONValue: String; const DestDS: TData vLocSetInBlockEvents(True); Inactive := True; If Assigned(vLocCreateDataSet) Then - vLocCreateDataSet(); + vLocCreateDataSet(Nil); If Not DestDS.Active Then DestDS.Open; If Not DestDS.Active Then @@ -4246,7 +4272,7 @@ procedure TRESTDWJSONValue.WriteToDataset(JSONValue: String; const DestDS: TData SizeOfString := Length(aValue); vTempValue := ''; SetString(vTempValue, PChar(@aValue[0]), SizeOfString); -{ //Comentado deleção de nulos +{ //Comentado deleo de nulos While pos(#0, vTempValue) > 0 Do Delete(vTempValue, pos(#0, vTempValue), 1); } @@ -4256,7 +4282,7 @@ procedure TRESTDWJSONValue.WriteToDataset(JSONValue: String; const DestDS: TData {$ENDIF} // Delphi 2010 pra cima End; {$ENDIF} - If Not(Pos('"TAGJSON":}', vTempValue) > 0) Then + If Not(Pos('"TAGJSON":"}', vTempValue) > 0) Then Result := vTempValue; End; @@ -4385,7 +4411,7 @@ procedure TRESTDWJSONValue.WriteToDataset(JSONValue: String; const DestDS: TData vObjectValue := ovString; vtagName := 'TAGJSON'; vBinary := True; - vUtf8SpecialChars := True; //Adicionado por padrão para special Chars + vUtf8SpecialChars := True; //Adicionado por padro para special Chars vNullValue := vBinary; vDataMode := dmDataware; vOnWriterProcess := Nil; @@ -6694,3 +6720,4 @@ procedure TRESTDWJSONParam.SetParamContentType(const bValue: String); End; end. + diff --git a/CORE/Source/Basic/uRESTDWPoolermethod.pas b/CORE/Source/Basic/uRESTDWPoolermethod.pas index cadf5e029..ab947b9a9 100644 --- a/CORE/Source/Basic/uRESTDWPoolermethod.pas +++ b/CORE/Source/Basic/uRESTDWPoolermethod.pas @@ -1,21 +1,21 @@ unit uRESTDWPoolermethod; -{$I ..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -85,8 +85,8 @@ Function RenewToken (Var Params : TRESTDWParams; Var Error : Boolean; Var MessageError : String) : String; -{ TODO: Criar uma função base para executar todos os comandos e remover as - redundâncias dessa unit. +{ TODO: Criar uma funo base para executar todos os comandos e remover as + redundncias dessa unit. Function ExecuteAction(aAction: string; Method_Prefix: string; Pooler: string = ''; @@ -370,7 +370,7 @@ Property PoolerURL : String Read vPoolerURL Write vPoolerURL; Property Host : String Read vHost Write vHost; Property Port : Integer Read vPort Write vPort; - Property RequestTimeOut : Integer Read vTimeOut Write vTimeOut; //Timeout da Requisição + Property RequestTimeOut : Integer Read vTimeOut Write vTimeOut; //Timeout da Requisio Property ConnectTimeOut : Integer Read vConnectTimeOut Write vConnectTimeOut; Property WelcomeMessage : String Read vWelcomeMessage Write vWelcomeMessage; Property OnWork : TOnWork Read vOnWork Write SetOnWork; @@ -824,7 +824,7 @@ implementation FreeAndNil(RESTClientPoolerExec); End; Begin - //Atualização de Token na autenticação + //Atualizao de Token na autenticao Result := ''; RESTClientPoolerExec := Nil; vConnection := TRESTDWPoolerMethodClient.Create(Nil); @@ -3180,6 +3180,8 @@ implementation // RESTClientPoolerExec.CriptOptions.Key:= vCripto.Key; RESTClientPoolerExec.DataRoute := DataRoute; RESTClientPoolerExec.UserAgent := vUserAgent; + RESTClientPoolerExec.SSLMethod := SSLMethod; + RESTClientPoolerExec.SSLVersions := SSLVersions; RESTClientPoolerExec.SetAccessTag(vAccessTag); TokenValidade; {$IFDEF FPC} diff --git a/CORE/Source/Basic/uRESTDWPropertyPersist.pas b/CORE/Source/Basic/uRESTDWPropertyPersist.pas index 1826fd1c2..02a404c94 100644 --- a/CORE/Source/Basic/uRESTDWPropertyPersist.pas +++ b/CORE/Source/Basic/uRESTDWPropertyPersist.pas @@ -1,6 +1,6 @@ unit uRESTDWPropertyPersist; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} interface diff --git a/CORE/Source/Basic/uRESTDWProtoTypes.pas b/CORE/Source/Basic/uRESTDWProtoTypes.pas index 7baf778c8..408e18cd8 100644 --- a/CORE/Source/Basic/uRESTDWProtoTypes.pas +++ b/CORE/Source/Basic/uRESTDWProtoTypes.pas @@ -1,19 +1,19 @@ unit uRESTDWProtoTypes; -{$I ..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Anderson Fiori - Admin - Gerencia de Organização dos Projetos - Flávio Motta - Member Tester and DEMO Developer. + Anderson Fiori - Admin - Gerencia de Organizao dos Projetos + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -28,9 +28,9 @@ interface uses {$IFNDEF FPC} - {$IF CompilerVersion < 21} + {$IFNDEF DELPHI2010UP} DbTables, - {$IFEND} + {$ENDIF} {$ENDIF} SysUtils, Classes, Db, FMTBcd; Const @@ -92,7 +92,11 @@ interface dwftLongWord = Integer(42); dwftShortint = Integer(43); dwftByte = Integer(44); + {$IFDEF FPC} + dwftExtended = Integer(45); + {$ELSE} dwftExtended = Integer(ftFMTBcd); + {$ENDIF} dwftStream = Integer(48); dwftTimeStampOffset = Integer(49); // dwftSingle = Integer(51); @@ -299,6 +303,337 @@ interface {$ELSE} TRESTDWStreamSize = DWInt32; {$ENDIF} + +const + RESTDW_NATIVE_SIGNATURE_0 = Ord('R'); + RESTDW_NATIVE_SIGNATURE_1 = Ord('E'); + RESTDW_NATIVE_SIGNATURE_2 = Ord('S'); + RESTDW_NATIVE_SIGNATURE_3 = Ord('T'); + RESTDW_NATIVE_SIGNATURE_4 = Ord('D'); + RESTDW_NATIVE_SIGNATURE_5 = Ord('W'); + RESTDW_NATIVE_FORMAT = Ord('N'); + RESTDW_NATIVE_VERSION = 2; + RESTDW_NATIVE_NULL_SIZE = -1; + RESTDW_NATIVE_FLAG_COMPRESSED = 1; + + RESTDW_COMPILER_OLDDELPHI = Ord('O'); + RESTDW_COMPILER_NEWDELPHI = Ord('N'); + RESTDW_COMPILER_LAZARUS = Ord('L'); + RESTDW_COMPILER_FPC = Ord('F'); + + RESTDW_ARCH_UNKNOWN = 0; + RESTDW_ARCH_32 = 32; + RESTDW_ARCH_64 = 64; + + RESTDW_PLATFORM_UNKNOWN = 0; + RESTDW_PLATFORM_WINDOWS = 1; + RESTDW_PLATFORM_LINUX = 2; + RESTDW_PLATFORM_MACOS = 3; + RESTDW_PLATFORM_FREEBSD = 4; + RESTDW_PLATFORM_ANDROID = 5; + RESTDW_PLATFORM_IOS = 6; + + RESTDW_TYPE_UNKNOWN = 0; + RESTDW_TYPE_STRING = 1; + RESTDW_TYPE_SMALLINT = 2; + RESTDW_TYPE_INTEGER = 3; + RESTDW_TYPE_WORD = 4; + RESTDW_TYPE_BOOLEAN = 5; + RESTDW_TYPE_FLOAT = 6; + RESTDW_TYPE_CURRENCY = 7; + RESTDW_TYPE_BCD = 8; + RESTDW_TYPE_DATE = 9; + RESTDW_TYPE_TIME = 10; + RESTDW_TYPE_DATETIME = 11; + RESTDW_TYPE_BYTES = 12; + RESTDW_TYPE_VARBYTES = 13; + RESTDW_TYPE_AUTOINC = 14; + RESTDW_TYPE_BLOB = 15; + RESTDW_TYPE_MEMO = 16; + RESTDW_TYPE_GRAPHIC = 17; + RESTDW_TYPE_FMTMEMO = 18; + RESTDW_TYPE_PARADOXOLE = 19; + RESTDW_TYPE_DBASEOLE = 20; + RESTDW_TYPE_TYPEDBINARY = 21; + RESTDW_TYPE_CURSOR = 22; + RESTDW_TYPE_FIXEDCHAR = 23; + RESTDW_TYPE_WIDESTRING = 24; + RESTDW_TYPE_LARGEINT = 25; + RESTDW_TYPE_ADT = 26; + RESTDW_TYPE_ARRAY = 27; + RESTDW_TYPE_REFERENCE = 28; + RESTDW_TYPE_DATASET = 29; + RESTDW_TYPE_ORABLOB = 30; + RESTDW_TYPE_ORACLOB = 31; + RESTDW_TYPE_VARIANT = 32; + RESTDW_TYPE_INTERFACE = 33; + RESTDW_TYPE_IDISPATCH = 34; + RESTDW_TYPE_GUID = 35; + RESTDW_TYPE_TIMESTAMP = 36; + RESTDW_TYPE_FMTBCD = 37; + RESTDW_TYPE_FIXEDWIDECHAR = 38; + RESTDW_TYPE_WIDEMEMO = 39; + RESTDW_TYPE_ORATIMESTAMP = 40; + RESTDW_TYPE_ORAINTERVAL = 41; + RESTDW_TYPE_LONGWORD = 42; + RESTDW_TYPE_SHORTINT = 43; + RESTDW_TYPE_BYTE = 44; + RESTDW_TYPE_EXTENDED = 45; + RESTDW_TYPE_SINGLE = 46; + RESTDW_TYPE_TIMESTAMPOS = 47; + +Type + TRESTDWNativeHeader = Packed Record + Signature : Array[0..5] Of Byte; + FormatType : Byte; + Version : Byte; + CompilerType : Byte; + PlatformType : Byte; + Architecture : Byte; + Flags : Byte; + End; + + TRESTDWNativeValueHeader = Packed Record + DataType : Byte; + DataSize : Longint; + End; + +Function RESTDWNativeCompilerType : Byte; +Function RESTDWNativePlatformType : Byte; +Function RESTDWNativeArchitecture : Byte; +Function RESTDWNativeDataType(AFieldType : TFieldType) : Byte; +Procedure RESTDWInitNativeHeader(Var AHeader : TRESTDWNativeHeader); +Function RESTDWIsNativeHeader(Const AHeader : TRESTDWNativeHeader) : Boolean; +Function RESTDWNativeHeaderCompatible(Const AHeader : TRESTDWNativeHeader) : Boolean; +Function RESTDWStreamHasNativeHeader(AStream : TStream) : Boolean; +Procedure RESTDWWriteNativePayload(ASource, ADest : TStream; ACompress : Boolean); +Function RESTDWReadNativePayload(ASource, ADest : TStream; Var AHeader : TRESTDWNativeHeader) : Boolean; + implementation + +Uses + uRESTDWZlib; + +Function RESTDWNativeCompilerType : Byte; +Begin + {$IFDEF RESTDWLAZARUS} + Result := RESTDW_COMPILER_LAZARUS; + {$ELSE} + {$IFDEF FPC} + Result := RESTDW_COMPILER_FPC; + {$ELSE} + {$IFDEF DELPHI2009UP} + Result := RESTDW_COMPILER_NEWDELPHI; + {$ELSE} + Result := RESTDW_COMPILER_OLDDELPHI; + {$ENDIF} + {$ENDIF} + {$ENDIF} +End; + +Function RESTDWNativePlatformType : Byte; +Begin + Result := RESTDW_PLATFORM_UNKNOWN; + {$IFDEF RESTDWWINDOWS} + Result := RESTDW_PLATFORM_WINDOWS; + {$ENDIF} + {$IFDEF RESTDWLINUX} + Result := RESTDW_PLATFORM_LINUX; + {$ENDIF} + {$IFDEF RESTDWMACOS} + Result := RESTDW_PLATFORM_MACOS; + {$ENDIF} + {$IFDEF RESTDWFREEBSD} + Result := RESTDW_PLATFORM_FREEBSD; + {$ENDIF} + {$IFDEF RESTDWANDROID} + Result := RESTDW_PLATFORM_ANDROID; + {$ENDIF} + {$IFDEF RESTDWIOS} + Result := RESTDW_PLATFORM_IOS; + {$ENDIF} +End; + +Function RESTDWNativeArchitecture : Byte; +Begin + {$IFDEF CPU64} + Result := RESTDW_ARCH_64; + {$ELSE} + {$IFDEF CPUX64} + Result := RESTDW_ARCH_64; + {$ELSE} + Result := RESTDW_ARCH_32; + {$ENDIF} + {$ENDIF} +End; + +Function RESTDWNativeDataType(AFieldType : TFieldType) : Byte; +Begin + Case Integer(AFieldType) Of + dwftString : Result := RESTDW_TYPE_STRING; + dwftSmallint : Result := RESTDW_TYPE_SMALLINT; + dwftInteger : Result := RESTDW_TYPE_INTEGER; + dwftWord : Result := RESTDW_TYPE_WORD; + dwftBoolean : Result := RESTDW_TYPE_BOOLEAN; + dwftFloat : Result := RESTDW_TYPE_FLOAT; + dwftCurrency : Result := RESTDW_TYPE_CURRENCY; + dwftBCD : Result := RESTDW_TYPE_BCD; + dwftDate : Result := RESTDW_TYPE_DATE; + dwftTime : Result := RESTDW_TYPE_TIME; + dwftDateTime : Result := RESTDW_TYPE_DATETIME; + dwftBytes : Result := RESTDW_TYPE_BYTES; + dwftVarBytes : Result := RESTDW_TYPE_VARBYTES; + dwftAutoInc : Result := RESTDW_TYPE_AUTOINC; + dwftBlob : Result := RESTDW_TYPE_BLOB; + dwftMemo : Result := RESTDW_TYPE_MEMO; + dwftGraphic : Result := RESTDW_TYPE_GRAPHIC; + dwftFmtMemo : Result := RESTDW_TYPE_FMTMEMO; + dwftParadoxOle : Result := RESTDW_TYPE_PARADOXOLE; + dwftDBaseOle : Result := RESTDW_TYPE_DBASEOLE; + dwftTypedBinary : Result := RESTDW_TYPE_TYPEDBINARY; + dwftFixedChar : Result := RESTDW_TYPE_FIXEDCHAR; + dwftWideString : Result := RESTDW_TYPE_WIDESTRING; + dwftLargeint : Result := RESTDW_TYPE_LARGEINT; + dwftOraBlob : Result := RESTDW_TYPE_ORABLOB; + dwftOraClob : Result := RESTDW_TYPE_ORACLOB; + dwftVariant : Result := RESTDW_TYPE_VARIANT; + dwftInterface : Result := RESTDW_TYPE_INTERFACE; + dwftIDispatch : Result := RESTDW_TYPE_IDISPATCH; + dwftGuid : Result := RESTDW_TYPE_GUID; + dwftTimeStamp : Result := RESTDW_TYPE_TIMESTAMP; + dwftFMTBcd : Result := RESTDW_TYPE_FMTBCD; + dwftFixedWideChar : Result := RESTDW_TYPE_FIXEDWIDECHAR; + dwftWideMemo : Result := RESTDW_TYPE_WIDEMEMO; + dwftOraTimeStamp : Result := RESTDW_TYPE_ORATIMESTAMP; + dwftOraInterval : Result := RESTDW_TYPE_ORAINTERVAL; + dwftLongWord : Result := RESTDW_TYPE_LONGWORD; + dwftShortint : Result := RESTDW_TYPE_SHORTINT; + dwftByte : Result := RESTDW_TYPE_BYTE; + {$IFDEF DELPHI2010UP} + dwftExtended : Result := RESTDW_TYPE_EXTENDED; + {$ENDIF} + dwftTimeStampOffset : Result := RESTDW_TYPE_TIMESTAMPOS; + Else + Result := RESTDW_TYPE_UNKNOWN; + End; +End; + +Procedure RESTDWInitNativeHeader(Var AHeader : TRESTDWNativeHeader); +Begin + FillChar(AHeader, SizeOf(AHeader), 0); + AHeader.Signature[0] := RESTDW_NATIVE_SIGNATURE_0; + AHeader.Signature[1] := RESTDW_NATIVE_SIGNATURE_1; + AHeader.Signature[2] := RESTDW_NATIVE_SIGNATURE_2; + AHeader.Signature[3] := RESTDW_NATIVE_SIGNATURE_3; + AHeader.Signature[4] := RESTDW_NATIVE_SIGNATURE_4; + AHeader.Signature[5] := RESTDW_NATIVE_SIGNATURE_5; + AHeader.FormatType := RESTDW_NATIVE_FORMAT; + AHeader.Version := RESTDW_NATIVE_VERSION; + AHeader.CompilerType := RESTDWNativeCompilerType; + AHeader.PlatformType := RESTDWNativePlatformType; + AHeader.Architecture := RESTDWNativeArchitecture; +End; + +Function RESTDWIsNativeHeader(Const AHeader : TRESTDWNativeHeader) : Boolean; +Begin + Result := (AHeader.Signature[0] = RESTDW_NATIVE_SIGNATURE_0) And + (AHeader.Signature[1] = RESTDW_NATIVE_SIGNATURE_1) And + (AHeader.Signature[2] = RESTDW_NATIVE_SIGNATURE_2) And + (AHeader.Signature[3] = RESTDW_NATIVE_SIGNATURE_3) And + (AHeader.Signature[4] = RESTDW_NATIVE_SIGNATURE_4) And + (AHeader.Signature[5] = RESTDW_NATIVE_SIGNATURE_5) And + (AHeader.FormatType = RESTDW_NATIVE_FORMAT) And + (AHeader.Version = RESTDW_NATIVE_VERSION); +End; + +Function RESTDWNativeHeaderCompatible(Const AHeader : TRESTDWNativeHeader) : Boolean; +Begin + Result := RESTDWIsNativeHeader(AHeader) And + (AHeader.CompilerType = RESTDWNativeCompilerType) And + (AHeader.PlatformType = RESTDWNativePlatformType) And + (AHeader.Architecture = RESTDWNativeArchitecture); +End; + +Function RESTDWStreamHasNativeHeader(AStream : TStream) : Boolean; +Var + LHeader : TRESTDWNativeHeader; + LPos : Int64; +Begin + Result := False; + If (AStream = Nil) Or (AStream.Size < SizeOf(LHeader)) Then + Exit; + LPos := AStream.Position; + Try + AStream.Position := 0; + If AStream.Read(LHeader, SizeOf(LHeader)) = SizeOf(LHeader) Then + Result := RESTDWIsNativeHeader(LHeader); + Finally + AStream.Position := LPos; + End; +End; + +Procedure RESTDWWriteNativePayload(ASource, ADest : TStream; ACompress : Boolean); +Var + LHeader : TRESTDWNativeHeader; + LTemp : TMemoryStream; +Begin + If (ASource = Nil) Or (ADest = Nil) Then + Exit; + RESTDWInitNativeHeader(LHeader); + If ACompress Then + LHeader.Flags := LHeader.Flags Or RESTDW_NATIVE_FLAG_COMPRESSED; + ADest.Size := 0; + ADest.Position := 0; + ADest.WriteBuffer(LHeader, SizeOf(LHeader)); + ASource.Position := 0; + If ACompress Then + Begin + LTemp := TMemoryStream.Create; + Try + ZCompressStream(ASource, LTemp); + LTemp.Position := 0; + ADest.CopyFrom(LTemp, LTemp.Size); + Finally + LTemp.Free; + End; + End + Else + ADest.CopyFrom(ASource, ASource.Size); + ADest.Position := 0; +End; + +Function RESTDWReadNativePayload(ASource, ADest : TStream; Var AHeader : TRESTDWNativeHeader) : Boolean; +Var + LTemp : TMemoryStream; +Begin + Result := False; + If (ASource = Nil) Or (ADest = Nil) Or (ASource.Size < SizeOf(AHeader)) Then + Exit; + ASource.Position := 0; + If ASource.Read(AHeader, SizeOf(AHeader)) <> SizeOf(AHeader) Then + Exit; + If Not RESTDWIsNativeHeader(AHeader) Then + Begin + ASource.Position := 0; + Exit; + End; + ADest.Size := 0; + If (AHeader.Flags And RESTDW_NATIVE_FLAG_COMPRESSED) <> 0 Then + Begin + LTemp := TMemoryStream.Create; + Try + LTemp.CopyFrom(ASource, ASource.Size - ASource.Position); + LTemp.Position := 0; + ZDecompressStream(LTemp, ADest); + Finally + LTemp.Free; + End; + End + Else + ADest.CopyFrom(ASource, ASource.Size - ASource.Position); + ADest.Position := 0; + Result := True; +End; + end. diff --git a/CORE/Source/Basic/uRESTDWResponseTranslator.pas b/CORE/Source/Basic/uRESTDWResponseTranslator.pas index 7c3a28ebd..d764fba0a 100644 --- a/CORE/Source/Basic/uRESTDWResponseTranslator.pas +++ b/CORE/Source/Basic/uRESTDWResponseTranslator.pas @@ -1,21 +1,21 @@ unit uRESTDWResponseTranslator; -{$I ..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Basic/uRESTDWServerContext.pas b/CORE/Source/Basic/uRESTDWServerContext.pas index 69c655511..febb218ff 100644 --- a/CORE/Source/Basic/uRESTDWServerContext.pas +++ b/CORE/Source/Basic/uRESTDWServerContext.pas @@ -1,17 +1,17 @@ unit uRESTDWServerContext; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilberto Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. - Maiores informações: + Maiores informaes: https://github.com/OpenSourceCommunityBrasil/REST-DataWare } diff --git a/CORE/Source/Basic/uRESTDWServerEvents.pas b/CORE/Source/Basic/uRESTDWServerEvents.pas index 73a8b5adf..854b3c67f 100644 --- a/CORE/Source/Basic/uRESTDWServerEvents.pas +++ b/CORE/Source/Basic/uRESTDWServerEvents.pas @@ -1,17 +1,17 @@ unit uRESTDWServerEvents; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilberto Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. - Maiores informações: + Maiores informaes: https://github.com/OpenSourceCommunityBrasil/REST-DataWare } diff --git a/CORE/Source/Basic/uRESTDWServerMethodClass.pas b/CORE/Source/Basic/uRESTDWServerMethodClass.pas index 1e4fda0e3..b7296bc05 100644 --- a/CORE/Source/Basic/uRESTDWServerMethodClass.pas +++ b/CORE/Source/Basic/uRESTDWServerMethodClass.pas @@ -1,6 +1,6 @@ unit uRESTDWServerMethodClass; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . diff --git a/CORE/Source/Basic/uRESTDWServerRoutes.pas b/CORE/Source/Basic/uRESTDWServerRoutes.pas index da83a1957..c5ec2600f 100644 --- a/CORE/Source/Basic/uRESTDWServerRoutes.pas +++ b/CORE/Source/Basic/uRESTDWServerRoutes.pas @@ -1,17 +1,17 @@ unit uRESTDWServerRoutes; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilberto Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. - Maiores informações: + Maiores informaes: https://github.com/OpenSourceCommunityBrasil/REST-DataWare } diff --git a/CORE/Source/Basic/uRESTDWStorageBin.pas b/CORE/Source/Basic/uRESTDWStorageBin.pas index 78a443b9c..728dbce29 100644 --- a/CORE/Source/Basic/uRESTDWStorageBin.pas +++ b/CORE/Source/Basic/uRESTDWStorageBin.pas @@ -1,6 +1,6 @@ unit uRESTDWStorageBin; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . @@ -31,1946 +31,498 @@ interface {$MODE OBJFPC}{$H+} {$ENDIF} -uses - {$IFNDEF RESTDWLAZARUS}{$IFNDEF RESTDWFPC}SqlTimSt, {$ENDIF}{$ENDIF} - FmtBcd, DB, Variants, Classes, SysUtils, uRESTDWBasicDbTypes, - {$IFDEF UNIDACMEM} - DADump, UniDump, VirtualTable, MemDS, - {$ENDIF} - {$IFDEF ZEOSMEM} - ZAbstractRODataset, ZAbstractDataset, ZMemTable, ZDataset, - {$ENDIF} - {$IFNDEF FPC} - {$IF CompilerVersion > 22} // Delphi 2010 pra cima - {$IFDEF RESTFDMEMTABLE} - FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param, - FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf, - FireDAC.Comp.DataSet, FireDAC.Comp.Client, - {$IFNDEF FPC} - {$IF CompilerVersion > 26} // Delphi XE6 pra cima - FireDAC.Stan.StorageBin, - {$IFEND} - {$ENDIF} - {$ENDIF} - {$IFEND} - {$ENDIF} - uRESTDWMemoryDataset, - uRESTDWConsts, uRESTDWTools, uRESTDWBasicTypes; +Uses + Classes, SysUtils, DB, FmtBcd, uRESTDWBasicDbTypes, uRESTDWProtoTypes, + uRESTDWMemoryDataset, uRESTDWTools; - Type - TRESTDWStorageBin = Class(TRESTDWStorageBase) +Type + TRESTDWStorageBin = Class(TRESTDWStorageBase) Private - FFieldKind : Array of TFieldKind; - FFieldNames : Array of String; - FFieldSize, - FFieldPrecision : Array of Integer; - FFieldTypes, - FFieldAttrs : TFieldAttrs; - FFieldExists : Array of Boolean; - Procedure SaveRecordToStream (ADataset : TDataset; - Var AStream : TStream); - Procedure LoadRecordFromStream (ADataset : TDataset; - AStream : TStream); - Function SaveRecordDWMemToStream (Dataset : TRESTDWMemTable; - stream : TStream) : Longint; - Procedure LoadRecordDWMemFromStream(Dataset : TRESTDWMemTable; - Stream : TStream); + Function ReadByte(AStream : TStream) : Byte; + Function ReadWord(AStream : TStream) : Word; + Function ReadDWord(AStream : TStream) : LongWord; + Function ReadAnsiString(AStream : TStream) : AnsiString; + Function IsStringField(AFieldType : TFieldType) : Boolean; + Function IsBlobField(AFieldType : TFieldType) : Boolean; + Function IsVariableField(AFieldType : TFieldType) : Boolean; + Function GetFixedWireSize(AWireType : Byte; + AField : TField) : LongWord; + Procedure SaveRecordToStream(ADataset : TDataset; + AWriter : TRESTDWBinaryPacketWriter); + Procedure LoadRecordFromStream(ADataset : TDataset; + AStream : TStream; + AWireFieldTypes: Array Of Byte; + ANullBitmapSize: Integer); Public - Procedure SaveDWMemToStream (IDataset : TDataset; - Var AStream : TStream); Override; - Procedure LoadDWMemFromStream (IDataset : TDataset; - AStream : TStream); Override; - Procedure SaveDatasetToStream (ADataset : TDataset; - Var AStream : TStream); Override; - Procedure LoadDatasetFromStream (ADataset : TDataset; - AStream : TStream); Override; + Procedure SaveDWMemToStream(IDataset : TDataset; + Var AStream : TStream); Override; + Procedure LoadDWMemFromStream(IDataset : TDataset; + AStream : TStream); Override; + Procedure SaveDatasetToStream(ADataset : TDataset; + Var AStream : TStream); Override; + Procedure LoadDatasetFromStream(ADataset : TDataset; + AStream : TStream); Override; End; - {$IFDEF FPC} - Function DateTimeToSQLTimeStamp(Const DateTime : TDateTime) : TSQLTimeStamp; - Function SQLTimeStampToDateTime(Const DateTime : TSQLTimeStamp) : TDateTime; - {$ENDIF} - Implementation -Uses - uRESTDWProtoTypes, - uRESTDWBufferBase; - -{ TRESTDWStorageBin } - +Function TRESTDWStorageBin.ReadByte(AStream : TStream) : Byte; +Begin + AStream.ReadBuffer(Result, SizeOf(Result)); +End; -{$IFDEF FPC} -Function DateTimeToSQLTimeStamp(Const DateTime : TDateTime) : TSQLTimeStamp; -Var - aFractions : Word; +Function TRESTDWStorageBin.ReadWord(AStream : TStream) : Word; Begin - DecodeDate(DateTime, Result.Year, Result.Month, Result.Day); - DecodeTime(DateTime, Result.Hour, Result.Minute, Result.Second, aFractions); - Result.Fractions := aFractions; + AStream.ReadBuffer(Result, SizeOf(Result)); End; -Function SQLTimeStampToDateTime(Const DateTime : TSQLTimeStamp) : TDateTime; - Function IsSQLTimeStampBlank (Const TimeStamp : TSQLTimeStamp) : Boolean; - Begin - Result := (TimeStamp.Year = 0) And - (TimeStamp.Month = 0) And - (TimeStamp.Day = 0) And - (TimeStamp.Hour = 0) And - (TimeStamp.Minute = 0) And - (TimeStamp.Second = 0) And - (TimeStamp.Fractions = 0); - End; +Function TRESTDWStorageBin.ReadDWord(AStream : TStream) : LongWord; Begin - If IsSQLTimeStampBlank(DateTime) Then - Result := 0 - Else - Begin - Result := EncodeDate(DateTime.Year, DateTime.Month, DateTime.Day); - If Result >= 0 Then - Result := Result + EncodeTime(DateTime.Hour, DateTime.Minute, DateTime.Second, DateTime.Fractions) - Else - Result := Result - EncodeTime(DateTime.Hour, DateTime.Minute, DateTime.Second, DateTime.Fractions); - End; + AStream.ReadBuffer(Result, SizeOf(Result)); End; -{$ENDIF} -Procedure TRESTDWStorageBin.LoadDatasetFromStream(ADataset : TDataset; - AStream : TStream); +Function TRESTDWStorageBin.ReadAnsiString(AStream : TStream) : AnsiString; Var - vFieldKind : TFieldKind; - r, i, - vRecordCount : DWInteger; - vInt, - vFieldsCount : DWInt64; - vString : DWString; - vFieldType : Byte; - vBoolean : Boolean; - vByte : Byte; - vFieldDef : TFieldDef; - vFieldAttrs : Array of Byte; - vField : TField; + L : LongWord; Begin - AStream.Position := 0; - // field count - AStream.Read(vFieldsCount,SizeOf(Integer)); - SetLength(FFieldKind, vFieldsCount); - SetLength(FFieldTypes, vFieldsCount); - SetLength(vFieldAttrs, vFieldsCount); - SetLength(FFieldNames, vFieldsCount); - SetLength(FFieldSize, vFieldsCount); - SetLength(FFieldPrecision, vFieldsCount); - // encodestr - AStream.Read(vBoolean, Sizeof(vBoolean)); - EncodeStrs := vBoolean; - ADataset.Close; - ADataset.FieldDefs.Clear; - For I := 0 To vFieldsCount-1 Do - Begin - // field kind - AStream.Read(vByte, SizeOf(vByte)); - FFieldKind[I] := TFieldKind(vByte); - vFieldDef := ADataset.FieldDefs.AddFieldDef; - // fieldname - AStream.Read(vByte, SizeOf(vByte)); - SetLength(vString, vByte); - AStream.Read(vString[InitStrPos], vByte); - vFieldDef.Name := vString; - FFieldNames[I] := vString; - // field type - AStream.Read(vFieldType, SizeOf(vFieldType)); - vFieldDef.DataType := DWFieldTypeToFieldType(vFieldType); - FFieldTypes[I] := vFieldType; + L := ReadDWord(AStream); + If Int64(L) > AStream.Size - AStream.Position Then + Raise Exception.Create('Invalid binary packet string length ' + IntToStr(L)); + SetLength(Result, L); + If L > 0 Then + AStream.ReadBuffer(Result[1], L); +End; - If vFieldType in [{$IFDEF FPC}45, {$ENDIF}dwftExtended] Then - FFieldTypes[I] := {$IFDEF FPC}Integer(ftFMTBcd){$ELSE}Integer(ftExtended){$ENDIF} - Else - FFieldTypes[I] := vFieldType; - // field size - AStream.Read(vInt, SizeOf(vInt)); - If vFieldType = dwftVarBytes Then //Max Array Size - Begin - FFieldTypes[I] := Integer(ftString); - FFieldSize[I] := 255; - vInt := FFieldSize[I]; - End - Else - FFieldSize[I] := vInt; - vFieldDef.Size := vInt; - // field precision - AStream.Read(vInt, SizeOf(vInt)); - FFieldPrecision[I] := vInt; - If (FFieldTypes[I] In [dwftFloat, dwftCurrency, dwftExtended]) Then - vFieldDef.Precision := FFieldPrecision[I] - Else If (vFieldType In [dwftBCD, dwftFMTBcd]) Then - Begin - {$IFDEF FPC} - vFieldDef.Size := 0; - vFieldDef.Precision := FFieldPrecision[I]; - {$ELSE} - vFieldDef.Size := 0; - vFieldDef.Precision := 0; - {$ENDIF} - End; - // field required + provider flag - AStream.Read(vByte, SizeOf(Byte)); - vFieldAttrs[I] := vByte; - vFieldDef.Required := vFieldAttrs[I] and 1 > 0; - End; - // provider flags deve ser recolocado depois dos fields criados - For I := 0 To vFieldsCount-1 Do - Begin - vField := ADataset.FindField(FFieldNames[I]); - If vField <> Nil Then - Begin - vField.ProviderFlags := []; - If vFieldAttrs[I] And 2 > 0 Then - vField.ProviderFlags := vField.ProviderFlags + [pfInUpdate]; - If vFieldAttrs[I] And 4 > 0 Then - vField.ProviderFlags := vField.ProviderFlags + [pfInWhere]; - If vFieldAttrs[I] And 8 > 0 Then - vField.ProviderFlags := vField.ProviderFlags + [pfInKey]; - If vFieldAttrs[I] And 16 > 0 Then - vField.ProviderFlags := vField.ProviderFlags + [pfHidden]; - {$IFDEF RESTDWLAZARUS} - If vFieldAttrs[I] And 32 > 0 Then - vField.ProviderFlags := vField.ProviderFlags + [pfRefreshOnInsert]; - If vFieldAttrs[I] And 64 > 0 Then - vField.ProviderFlags := vField.ProviderFlags + [pfRefreshOnUpdate]; - {$ENDIF} - End; - End; - AStream.Read(vRecordCount, SizeOf(vRecordCount)); - ADataset.Open; - ADataset.DisableControls; - Try - r := 0; - While r <= vRecordCount Do //Anderson - Begin - ADataset.Append; - LoadRecordFromStream(ADataset, AStream); - ADataset.Post; - Inc(r); - End; - Finally - ADataset.EnableControls; - End; +Function TRESTDWStorageBin.IsStringField(AFieldType : TFieldType) : Boolean; +Begin + Result := AFieldType In [ftString, ftFixedChar, ftWideString + {$IFDEF DELPHIXEUP}, ftFixedWideChar{$ENDIF}]; End; -Procedure TRESTDWStorageBin.LoadDWMemFromStream(IDataset : TDataset; - AStream : TStream); - Procedure CreateFieldDefs(DataSet : TDataSet; - Index : Integer); - Var - vFDef : TFieldDef; - Function FindDef(aName : String) : Boolean; - Var - I : Integer; - Begin - Result := False; - For I := 0 To DataSet.FieldDefs.Count -1 Do - Begin - Result := Lowercase(DataSet.FieldDefs[I].Name) = Lowercase(aName); - If Result Then - Break; - End; - End; - Begin - If Trim(FFieldNames[Index]) <> '' Then - Begin - If (Not (Assigned(DataSet.FindField(FFieldNames[Index]))) And - Not(FindDef(FFieldNames[Index]))) Then - Begin - If FFieldTypes[Index] = {$IFDEF FPC}45{$ELSE}dwftExtended{$ENDIF} Then - Begin - DataSet.FieldDefs.Add(FFieldNames[Index], DWFieldTypeToFieldType(FFieldTypes[Index])); - VFDef := DataSet.FieldDefs[DataSet.FieldDefs.Count -1]; - End - Else - Begin - VFDef := DataSet.FieldDefs.AddFieldDef; - VFDef.Name := FFieldNames[Index]; - VFDef.DataType := DWFieldTypeToFieldType(FFieldTypes[Index]); - End; - If FFieldTypes[Index] <> dwftExtended Then - VFDef.Size := FFieldSize[Index]; - VFDef.Required := FFieldAttrs[Index] and 1 > 0; - Case FFieldTypes[Index] of - dwftFloat, - dwftCurrency : VFDef.Precision := FFieldPrecision[Index]; - dwftBCD, - dwftFMTBcd : Begin - {$IFNDEF FPC} - VFDef.Size := 0; - VFDef.Precision := 0; - {$ELSE} - VFDef.Precision := FFieldPrecision[Index]; - {$ENDIF} - End; -{ - dwftWideString : Begin - If VFDef.Size > 7100 Then - Begin - VFDef.Size := 7100; - FFieldSize[Index] := VFDef.Size; - End; - End; -} - End; - End; - End; - End; -Var - ADataSet : {$IFDEF UNIDACMEM} - TVirtualTable - {$ENDIF} - {$IFDEF ZEOSMEM} - TZMemTable - {$ENDIF} - {$IFDEF RESTFDMEMTABLE} - TFDMemtable - {$ENDIF} - {$IFDEF RESTDWMEMTABLE} - TRESTDWMemtable - {$ENDIF}; - I, - vFieldsCount : DWInteger; - vFieldSize, - vFieldPrecision : DWInt16; - vFieldName : DWString; - vBoolean, - vNoFields : Boolean; - vByte, - vFieldKind, - vFieldType, - vFieldProviderFlags : Byte; - vFieldDef : TFieldDef; - vField : TField; +Function TRESTDWStorageBin.IsBlobField(AFieldType : TFieldType) : Boolean; Begin - ADataSet := {$IFDEF UNIDACMEM} - TVirtualTable - {$ENDIF} - {$IFDEF ZEOSMEM} - TZMemTable - {$ENDIF} - {$IFDEF RESTFDMEMTABLE} - TFDMemtable - {$ENDIF} - {$IFDEF RESTDWMEMTABLE} - TRESTDWMemtable - {$ENDIF}(IDataset); - // field count - AStream.Position := 0; - AStream.Read(vFieldsCount, SizeOf(vFieldsCount)); - SetLength(FFieldKind, vFieldsCount); - SetLength(FFieldTypes, vFieldsCount); - SetLength(FFieldAttrs, vFieldsCount); - SetLength(FFieldNames, vFieldsCount); - SetLength(FFieldSize, vFieldsCount); - SetLength(FFieldPrecision, vFieldsCount); - SetLength(FFieldExists, vFieldsCount); - // encodestrs - AStream.Read(vBoolean, Sizeof(vBoolean)); - EncodeStrs := vBoolean; - vNoFields := (ADataSet.Fields.Count = 0); - ADataSet.Close; - If vNoFields Then - ADataSet.FieldDefs.Clear; - For I := 0 To vFieldsCount-1 Do - Begin - // field kind - AStream.Read(vFieldKind, SizeOf(vFieldKind)); - FFieldKind[I] := TFieldKind(vFieldKind); - // field name - AStream.Read(vByte, SizeOf(vByte)); - SetLength(vFieldName, vByte); - AStream.Read(vFieldName[InitStrPos], vByte); - FFieldNames[I] := vFieldName; - // field type - AStream.Read(vFieldType, SizeOf(vFieldType)); - If vFieldType in [Integer(ftFloat), {$IFDEF FPC}45, {$ENDIF}dwftExtended] Then - FFieldTypes[I] := {$IFDEF FPC}Integer(ftFMTBcd){$ELSE}Integer(ftExtended){$ENDIF} - Else - FFieldTypes[I] := vFieldType; - // field size - AStream.Read(vFieldSize, SizeOf(vFieldSize)); - If vFieldType = dwftVarBytes Then //Max Array Size - Begin - FFieldTypes[I] := Integer(ftString); - FFieldSize[I] := 255; - End - Else - FFieldSize[I] := vFieldSize; - // field precision - AStream.Read(vFieldPrecision, SizeOf(vFieldPrecision)); - {$IFDEF FPC} - If vFieldType in [dwftFloat, dwftFMTBcd, dwftBCD] Then - Begin - If (vFieldPrecision < 12) Or - (FFieldPrecision[I] = 0) Then - FFieldPrecision[I] := 12; - End; - {$ELSE} - FFieldPrecision[I] := vFieldPrecision; - If vFieldType in [dwftSingle] Then - If vFieldPrecision < 12 Then - FFieldPrecision[I] := 12; - {$ENDIF} - // required + provider flags - AStream.Read(vFieldProviderFlags, SizeOf(Byte)); - FFieldAttrs[I] := vFieldProviderFlags; - // field is persistent or no fields persistet - FFieldExists[I] := (ADataSet.FindField(FFieldNames[I]) <> nil); // or (vNoFields); - // create fieldsDefs like fields persistent -// If ((vNoFields) Or (Not FFieldExists[I])) Then - {$IFDEF RESTDWMEMTABLE} - TRESTDWMemTable(ADataSet).FieldAttrs := FFieldAttrs; - {$ENDIF} - CreateFieldDefs(ADataSet, I); - End; - ADataSet.Open; - // provider flags deve ser recolocado depois dos fields criados se nao existiam - If (vNoFields) Then - Begin - For I := 0 to vFieldsCount-1 do - Begin - vField := ADataSet.FindField(FFieldNames[I]); - If vField <> Nil Then - Begin - vField.ProviderFlags := []; - If FFieldAttrs[I] And 2 > 0 Then - vField.ProviderFlags := vField.ProviderFlags + [pfInUpdate]; - If FFieldAttrs[I] And 4 > 0 Then - vField.ProviderFlags := vField.ProviderFlags + [pfInWhere]; - If FFieldAttrs[I] And 8 > 0 Then - vField.ProviderFlags := vField.ProviderFlags + [pfInKey]; - If FFieldAttrs[I] And 16 > 0 Then - vField.ProviderFlags := vField.ProviderFlags + [pfHidden]; - {$IFDEF RESTDWLAZARUS} - If FFieldAttrs[I] And 32 > 0 Then - vField.ProviderFlags := vField.ProviderFlags + [pfRefreshOnInsert]; - If FFieldAttrs[I] And 64 > 0 Then - vField.ProviderFlags := vField.ProviderFlags + [pfRefreshOnUpdate]; - {$ENDIF} - End; - End; - End; - ADataSet.DisableControls; - Try - LoadRecordDWMemFromStream(TRESTDWMemtable(IDataset), AStream); - Finally - ADataSet.EnableControls; - AStream := Nil; - AStream.Free; - End; + Result := AFieldType In [ftBlob, ftMemo, ftGraphic + {$IFDEF DELPHIXEUP}, ftWideMemo{$ENDIF}]; End; -Procedure TRESTDWStorageBin.LoadRecordDWMemFromStream(Dataset : TRESTDWMemTable; - stream : TStream); -Var - I, B, - vFieldCount : DWInteger; - vRecCount : DWInt64; - vVarBytes : TRESTDWBytes; - aField : TField; - aIndex : Integer; - vDataset : {$IFDEF UNIDACMEM} - TVirtualTable - {$ENDIF} - {$IFDEF ZEOSMEM} - TZMemTable - {$ENDIF} - {$IFDEF RESTFDMEMTABLE} - TFDMemtable - {$ENDIF} - {$IFDEF RESTDWMEMTABLE} - TRESTDWMemtable - {$ENDIF}; - vActualRecord : TRESTDWMTMemoryRecord; - vDataType : TFieldType; - vDWFieldType : Byte; - pData : {$IFDEF FPC} PAnsiChar {$ELSE} PByte {$ENDIF}; - pActualRecord : PRESTDWMTMemBuffer; - V6 : DWFloat; - S : DWString; - vString : DWString; - vWideString : DWWideString; -// vDWWideString : DWWideString; - vInt : DWInteger; - vLength : DWWord; - vBoolean : Boolean; - vInt64 : DWInt64; - vSingle : DWSingle; - vDouble : DWDouble; - vExtended : DWLongDouble; - vWord : DWWord; - vCurrency : DWCurrency; - vTimeStamp : {$IFDEF FPC} TTimeStamp {$ELSE} TSQLTimeStamp {$ENDIF}; - {$IFDEF FPC} - vTimeStampLaz : TDateTime; - {$ELSE} - vTimeStampDelphi : TDateTime; - {$ENDIF} - vBCD : DWBcd; - vBytes : TRESTDWBytes; - vTimeZone : DWDouble; - vDateTimeRec : TDateTimeRec; - vByte : Byte; - {$IFNDEF FPC} - {$IF CompilerVersion >= 21} - vTimeStampOffset: TSQLTimeStampOffset; - {$IFEND} - {$ENDIF} - Procedure tratarNulos; - Begin - If aField = nil Then - Exit; - If (vDWFieldType In [dwftFixedWideChar, - dwftWideString, - dwftFixedChar, - dwftString]) Then -// dwftOraClob, -// dwftWideMemo, -// dwftFmtMemo, -// dwftMemo]) Then - Begin - vLength := TRESTDWMemtable(Dataset).GetCalcFieldLen(aField.DataType, aField.Size); - {$IFDEF FPC} - FillChar(PData^, vLength, #0); - {$ELSE} - FillChar(pData^, vLength, 0); - {$ENDIF} - End - Else If (vDWFieldType In [dwftLongWord, - dwftByte, - dwftShortint, - dwftSmallint, - dwftWord, - dwftInteger, -// dwftSingle, - dwftExtended, - dwftFloat, - dwftOraTimeStamp, - dwftBCD, -// dwftFMTBcd, - dwftCurrency, - dwftDate, - dwftTime, - dwftDateTime, - dwftTimeStampOffset, - dwftAutoInc, - dwftLargeint, - dwftTimeStamp]) Then - Begin - If Not (vDWFieldType In [dwftByte, - dwftShortint]) Then - Begin - vLength := Dataset.GetCalcFieldLen(aField.DataType, aField.Size); - {$IFDEF FPC} - FillChar(PData^, vLength, #0); - Move(vBoolean, pData^, SizeOf(Boolean)); - {$ELSE} - {$IF CompilerVersion <= 22} - FillChar(PData^, vLength, #0); - {$IFEND} - Move(vBoolean, pData^, SizeOf(Boolean)); - {$ENDIF} - End - Else If vBoolean Then - FillChar(pData^, 1, 'S'); - End - Else If (vDWFieldType In [dwftBoolean]) Then - FillChar(pData^, 2, 0); - End; +Function TRESTDWStorageBin.IsVariableField(AFieldType : TFieldType) : Boolean; Begin - pActualRecord := Nil; - vDataset := {$IFDEF UNIDACMEM} - TVirtualTable - {$ENDIF} - {$IFDEF ZEOSMEM} - TZMemTable - {$ENDIF} - {$IFDEF RESTFDMEMTABLE} - TFDMemtable - {$ENDIF} - {$IFDEF RESTDWMEMTABLE} - TRESTDWMemtable - {$ENDIF}(Dataset); - stream.Read(vRecCount, SizeOf(vRecCount)); - vRecCount := vRecCount - 1; - vFieldCount := Length(FFieldNames); - vFieldCount := vFieldCount - 1; - For i := 0 To vRecCount Do - Begin - pActualRecord := PRESTDWMTMemBuffer(TRESTDWMemtable(vDataset).AllocRecordBuffer); - {$IFDEF RESTDWANDROID} - TRESTDWMemtable(vDataset).InternalAddRecord(nativeint(pActualRecord), True); - {$ELSE} - TRESTDWMemtable(vDataset).InternalAddRecord(pActualRecord, True); - {$ENDIF} - vActualRecord := TRESTDWMemtable(vDataset).GetMemoryRecord(i); - For b := 0 To vFieldCount Do - Begin - vBoolean := False; - stream.Read(vBoolean, SizeOf(boolean)); - SetLength(vVarBytes, 0); - aField := vDataset.FindField(FFieldNames[b]); - If aField <> Nil Then - Begin - aIndex := aField.FieldNo - 1; - If (aIndex < 0) Then - Continue; - vDataType := aField.DataType; - End - Else - vDataType := DWFieldTypeToFieldType(FFieldTypes[b]); - vDWFieldType := FFieldTypes[b]; - pData := nil; - If (pActualRecord <> Nil) Then - Begin - If aField <> Nil Then - Begin - If Dataset.DataTypeSuported(vDataType) Then - Begin - If Dataset.DataTypeIsBlobTypes(vDataType) Then - pData := Pointer(Dataset.GetBlob(-1, aField.Offset)) - Else - pData := Pointer(pActualRecord + Dataset.GetOffSets(aField)); - End; - End; - If vDWFieldType <> dwftBoolean Then - Begin - tratarNulos; - If Not vBoolean Then - Continue; - End; - If (pData <> Nil) Or (aField = Nil) Then - Begin - // N Bytes - WideString - case vDWFieldType Of - dwftWideString, - dwftFixedWideChar :Begin - stream.Read(vInt64, SizeOf(vInt64)); - vWideString := ''; - If vInt64 > 0 Then - Begin - SetLength(vWideString, vInt64); - {$IFDEF FPC} - stream.Read(Pointer(vString)^, vInt64); - If EncodeStrs Then - vString := DecodeStrings(vString, csUndefined); - vString := GetStringEncode(vString, csUndefined); - vInt64 := (Length(vString) + 1) * SizeOf(WideChar); - If aField <> Nil Then - Move(Pointer(WideString(vString))^, PData^, vInt64); - {$ELSE} - stream.Read(vWideString[InitStrPos], vInt64); - If EncodeStrs Then - vString := DecodeStrings(vWideString) - Else - vString := Trim(vWideString); -// vInt64 := (Length(vString) + 1);// * SizeOf(WideChar); - If aField <> Nil Then - Move(vString[InitStrPos], pData^, Length(vString)); - {$ENDIF} - End; - End; - // N Bytes - Strings - dwftVarBytes, - dwftFixedChar, - dwftString : Begin - SetLength(vString, 0); - stream.Read(vInt64, SizeOf(vInt64)); - vString := ''; - If vInt64 > 0 Then - Begin - SetLength(vString, vInt64); -// FillChar(Pointer(@vString)^, vInt64, 0); - {$IFDEF FPC} - stream.Read(Pointer(vString)^, vInt64); - If EncodeStrs Then - vString := DecodeStrings(vString, csUndefined); - vString := GetStringEncode(vString, csUndefined); - If aField <> Nil Then - Move(Pointer(vString)^, pData^, vInt64); - {$ELSE} - stream.Read(vString[InitStrPos], vInt64); - If EncodeStrs Then - vString := DecodeStrings(vString); - If aField <> Nil Then - Begin -// FillChar(pData^, vInt64, 0); - Move(Pointer(vString)^, pData^, vInt64); - End; - {$ENDIF} - End; - End; - // 1 - Byte - Inteiro - dwftByte, - dwftShortint :Begin - stream.Read(vByte, SizeOf(vByte)); - If aField <> Nil Then - Move(vByte, PData^, Sizeof(vByte)); - End; - // 1 - Byte - Boolean - dwftBoolean :Begin - setlength(vVarBytes, 0); - setlength(vVarBytes, Sizeof(Boolean)); -// Move(vBoolean, vVarBytes[0], Sizeof(Boolean)); -// stream.Read(vBoolean, SizeOf(vBoolean)); - Move(vBoolean, vVarBytes[0], Sizeof(Boolean)); -// Move(vBoolean, vVarBytes[1], Sizeof(Boolean)); - If aField <> Nil Then - Move(vVarBytes[0], PData^, Sizeof(vBoolean)); - End; - // 2 - Bytes - dwftSmallint, - dwftWord :Begin - stream.Read(vWord, SizeOf(vWord)); - If aField <> Nil Then - Begin - SetLength(vVarBytes, Sizeof(Boolean) + Sizeof(vWord)); - //Move Null para Bytes - Move(vBoolean, vVarBytes[0], Sizeof(Boolean)); - //Move Bytes do Dado para Bytes - Move(vWord, vVarBytes[1], Sizeof(vWord)); - //Move Bytes para Buffer - Move(vVarBytes[0], PData^, Sizeof(Boolean) + Sizeof(vWord)); - End; - End; - // 4 - Bytes - Inteiros - dwftInteger :Begin - stream.Read(vInt, SizeOf(vInt)); - If aField <> Nil Then - Begin - SetLength(vVarBytes, Sizeof(Boolean) + Sizeof(vInt)); - //Move Null para Bytes - Move(vBoolean, vVarBytes[0], Sizeof(Boolean)); - //Move Bytes do Dado para Bytes - Move(vInt, vVarBytes[1], Sizeof(vInt)); - //Move Bytes para Buffer - Move(vVarBytes[0], PData^, Sizeof(Boolean) + Sizeof(vInt)); - End; - End; -// // 4 - Bytes - Flutuantes -// dwftSingle :Begin // Gledston -// vLength := SizeOf(vDouble); -// stream.Read(vDouble, vLength); -// If aField <> Nil Then -// Begin -// //Move(vSingle,PData^,Sizeof(vSingle)); -// SetLength(vVarBytes, Sizeof(Boolean) + Sizeof(vDouble)); -// //Move Null para Bytes -// Move(vBoolean, vVarBytes[0], Sizeof(Boolean)); -// //Move Bytes do Dado para Bytes -// Move(vDouble, vVarBytes[1], Sizeof(vDouble)); -// //Move Bytes para Buffer -// Move(vVarBytes[0], PData^, Length(vVarBytes)); -// End; -// End; - // 8 - Bytes - Inteiros - dwftLargeint, - dwftAutoInc, - dwftLongWord :Begin - stream.Read(vInt64, SizeOf(vInt64)); - If aField <> Nil Then - Begin - SetLength(vVarBytes, Sizeof(Boolean) + Sizeof(vInt64)); - //Move Null para Bytes - Move(vBoolean, vVarBytes[0], Sizeof(Boolean)); - //Move Bytes do Dado para Bytes - Move(vInt64, vVarBytes[1], Sizeof(vInt64)); - //Move Bytes para Buffer - Move(vVarBytes[0], PData^, Length(vVarBytes)); - End; - End; - // 8 - Bytes - Flutuantes - dwftFloat - {$IFDEF FPC} - , 45 //Extended - {$ENDIF} - , dwftExtended + Result := IsStringField(AFieldType) Or + IsBlobField(AFieldType) Or + (AFieldType In [ftBytes, ftVarBytes]); +End; - :Begin - vDouble := 0; - stream.Read(vDouble, SizeOf(vDouble)); - If aField <> Nil Then - Begin - SetLength(vVarBytes, Sizeof(Boolean) + Sizeof(vExtended)); - //Move Null para Bytes - Move(vBoolean, vVarBytes[0], Sizeof(Boolean)); - //Move Bytes do Dado para Bytes - vExtended := vDouble; - Move(vExtended, vVarBytes[1], Sizeof(vExtended)); - //Move Bytes para Buffer - Move(vVarBytes[0], PData^, Length(vVarBytes)); - End; - End; -// dwftExtended :Begin -// stream.Read(vExtended, SizeOf(vExtended)); -// If aField <> Nil Then -// Begin -// SetLength(vVarBytes, Sizeof(Boolean) + Sizeof(vExtended)); -// //Move Null para Bytes -// Move(vBoolean, vVarBytes[0], Sizeof(Boolean)); -// //Move Bytes do Dado para Bytes -// Move(vExtended, vVarBytes[1], Sizeof(vExtended)); -// //Move Bytes para Buffer -// {$IFDEF FPC} -// PRESTDWBytes(pData)^ := vVarBytes; -// {$ELSE} -// Move(vVarBytes[0], PData^, Sizeof(Boolean) + Sizeof(vExtended)); -// {$ENDIF} -// End; -// End; - // 8 - Bytes - Date, Time, DateTime, TimeStamp - dwftDate, - dwftTime, - dwftDateTime, - dwftTimeStamp : Begin - stream.Read(vDouble, SizeOf(vDouble)); - If aField <> Nil Then - Begin - SetLength(vVarBytes, Sizeof(Boolean) + Sizeof(vDouble)); - //Move Null para Bytes - Move(vBoolean, vVarBytes[0], Sizeof(Boolean)); - //Move Bytes do Dado para Bytes - Case vDataType Of - ftDate : vDouble := DateTimeToTimeStamp(vDouble).Date; -// ftTimeStamp : vDouble := TimeStampToMSecs(DateTimeToTimeStamp(vDouble)); - End; - Move(vDouble, vVarBytes[1], Sizeof(vDouble)); - //Move Bytes para Buffer - Move(vVarBytes[0], PData^, Length(vVarBytes)); - End; - End; - // TimeStampOffSet To Double - 8 Bytes - // + TimeZone - 2 Bytes - dwftTimeStampOffset :Begin - {$IF (NOT DEFINED(FPC)) AND (CompilerVersion >= 21)} - stream.Read(vDouble, SizeOf(vDouble)); - {$IFDEF RESTDWMEMTABLE} - vTimeStampOffSet := DateTimeToSQLTimeStampOffset(vDouble); - {$ENDIF} - stream.Read(vByte, SizeOf(vByte)); - vTimeStampOffSet.TimeZoneHour := vByte - 12; - stream.Read(vByte, SizeOf(vByte)); - vTimeStampOffSet.TimeZoneMinute := vByte; - If aField <> Nil Then - Move(vTimeStampOffSet, PData^, Sizeof(vTimeStampOffSet)); - {$ELSE} - // field foi transformado em tdatetime - stream.Read(vDouble, SizeOf(vDouble)); - stream.Read(vByte, SizeOf(vByte)); - vTimeZone := (vByte - 12) / 24; - stream.Read(vByte, SizeOf(vByte)); - If vTimeZone > 0 Then - vTimeZone := vTimeZone + (vByte / 60 / 24) - Else - vTimeZone := vTimeZone - (vByte / 60 / 24); - vDouble := vDouble - vTimeZone; - If aField <> Nil Then - Begin - {$IFDEF FPC} - vDateTimeRec := DateTimeToDateTimeRec(vDataType, TDateTime(vDouble)); - Move(vDateTimeRec, PData^, SizeOf(vDateTimeRec)); - {$ELSE} - Case vDataType Of - ftDate : vDateTimeRec.Date := DateTimeToTimeStamp(vDouble).Date; - ftTime : vDateTimeRec.Time := DateTimeToTimeStamp(vDouble).Time; - Else vDateTimeRec.DateTime := TimeStampToMSecs(DateTimeToTimeStamp(vDouble)); - End; - Move(vDateTimeRec, pData^, SizeOf(vDateTimeRec)); - {$ENDIF} - End; - {$IFEND} - End; - // 8 - Bytes - Currency - dwftCurrency :Begin - stream.Read(vCurrency, SizeOf(vCurrency)); - If aField <> Nil Then - Begin - SetLength(vVarBytes, Sizeof(Boolean) + Sizeof(vCurrency)); - //Move Null para Bytes - Move(vBoolean, vVarBytes[0], Sizeof(Boolean)); - vString := CurrToStr(vCurrency); //Gledston acresentei estas linhas - V6 := StrtoFloat(vString); - //Move Bytes do Dado para Bytes - Move(V6, vVarBytes[1], Sizeof(V6)); - //Move Bytes para Buffer - Move(vVarBytes[0], PData^, Length(vVarBytes)); - End; - End; - // 8 - Bytes - Currency - dwftBCD :Begin - stream.Read(vCurrency, SizeOf(vCurrency)); - If aField <> Nil Then - Begin - {$IFDEF FPC} - SetLength(vVarBytes, Sizeof(Boolean) + Sizeof(vCurrency)); - //Move Null para Bytes - Move(vBoolean, vVarBytes[0], Sizeof(Boolean)); - //Move Bytes do Dado para Bytes - Move(vCurrency, vVarBytes[1], Sizeof(vCurrency)); - //Move Bytes para Buffer - Move(vVarBytes[0], PData^, Length(vVarBytes)); - {$ELSE} - {$IF CompilerVersion <= 21} - CurrToBCD(vCurrency, vBCD); - {$ELSE} - vBCD := CurrencyToBcd(vCurrency); - {$IFEND} - SetLength(vVarBytes, Sizeof(Boolean) + Sizeof(vBCD)); - //Move Null para Bytes - Move(vBoolean, vVarBytes[0], Sizeof(Boolean)); - //Move Bytes do Dado para Bytes - Move(vBCD, vVarBytes[1], Sizeof(vBCD)); - //Move Bytes para Buffer - Move(vVarBytes[0], PData^, Sizeof(Boolean) + Sizeof(vBCD)); - {$ENDIF} - End; - End; - // 8 - Bytes - Currency - {$IFNDEF FPC}dwftFMTBcd : Begin - stream.Read(vCurrency, SizeOf(vCurrency)); - {$IFDEF FPC} - vBCD := CurrToBcd(vCurrency); - {$ELSE} - {$IF CompilerVersion <= 21} - CurrToBCD(vCurrency, vBCD); - {$ELSE} - vBCD := CurrencyToBcd(vCurrency); - {$IFEND} - {$ENDIF} - SetLength(vVarBytes, Sizeof(Boolean) + Sizeof(vBCD)); - //Move Null para Bytes - Move(vBoolean, vVarBytes[0], Sizeof(Boolean)); - //Move Bytes do Dado para Bytes - Move(vBCD, vVarBytes[1], Sizeof(vBCD)); - //Move Bytes para Buffer - Move(vVarBytes[0], PData^, Sizeof(Boolean) + Sizeof(vBCD)); - End; - {$ENDIF} - //N Bytes - String Blobs - dwftWideMemo, - dwftFmtMemo, - dwftOraClob, - dwftMemo, -// dwftMemo :Begin -// stream.Read(vInt64, SizeOf(vInt64)); -// vString := ''; -// If vInt64 > 0 Then -// Begin -// SetLength(vString, vInt64); -// {$IFDEF FPC} -// stream.Read(Pointer(vString)^, vInt64); -// If EncodeStrs Then -// vString := DecodeStrings(vString, csUndefined); -// vString := GetStringEncode(vString, csUndefined); -// {$ELSE} -// stream.Read(vString[InitStrPos], vInt64); -// If EncodeStrs Then -// vString := DecodeStrings(vString); -// {$ENDIF} -// vInt64 := Length(vString) + 1; -// Try -// SetLength(vBytes, vInt64); -// Move(vString[InitStrPos], vBytes[0], vInt64); -// If aField <> Nil Then -// PRESTDWBytes(pData)^ := vBytes; -// Finally -// SetLength(vBytes, 0); -// End; -// End; -// End; - // N Bytes - Others Blobs - dwftStream, - dwftOraBlob, - dwftBlob, - dwftBytes : Begin - SetLength(vBytes, 0); - stream.Read(vInt64, SizeOf(DWInt64)); - If vInt64 > 0 Then - Begin - // Actual TODO XyberX - SetLength(vBytes, vInt64); - stream.Read(vBytes[0], vInt64); - End; - Try - If Length(vBytes) > 0 Then - Begin - If aField <> Nil Then - PRESTDWBytes(pData)^ := vBytes; - End; - Finally - SetLength(vBytes, 0); - End; - End; - // N Bytes - Others - Else - Begin - stream.Read(vInt64, SizeOf(vInt64)); - vString := ''; - If vInt64 > 0 Then - Begin - SetLength(vString, vInt64); - {$IFDEF FPC} - stream.Read(Pointer(vString)^, vInt64); - If EncodeStrs Then - vString := DecodeStrings(vString, csUndefined); - vString := GetStringEncode(vString, csUndefined); - If aField <> Nil Then - Move(Pointer(vString)^, PData^, Length(vString)); - {$ELSE} - stream.Read(vString[InitStrPos], vInt64); - If EncodeStrs Then - vString := DecodeStrings(vString); - If aField <> Nil Then - Move(vString[InitStrPos], pData^, Length(vString)); - {$ENDIF} - End; - End; - End; - End; - End; - SetLength(vVarBytes, 0); - End; - Try - Dataset.SetMemoryRecordData(pActualRecord, i); - Finally - Reallocmem(pActualRecord, 0); -// Dispose(pActualRecord);//FreeMem(PRESTDWMTMemBuffer(@PActualRecord)); - End; - End; +Function TRESTDWStorageBin.GetFixedWireSize(AWireType : Byte; + AField : TField) : LongWord; +Begin + Case AWireType Of + dwftSmallint : Result := SizeOf(SmallInt); + dwftInteger : Result := SizeOf(Integer); + dwftWord : Result := SizeOf(Word); + dwftBoolean : Result := SizeOf(WordBool); + dwftFloat : Result := SizeOf(Double); + dwftCurrency, + dwftBCD : Result := SizeOf(Currency); + dwftDate, + dwftTime : Result := SizeOf(Integer); + dwftDateTime, + dwftTimeStamp, + dwftOraTimeStamp, + dwftTimeStampOffset : Result := SizeOf(TDateTime); + dwftLargeint, + dwftAutoInc : Result := SizeOf(Int64); + dwftExtended : Result := SizeOf(Double); + dwftFMTBcd : Result := SizeOf(TBcd); + dwftGuid : Result := SizeOf(TGUID); + Else + Result := AField.DataSize; + End; End; -Procedure TRESTDWStorageBin.LoadRecordFromStream(ADataset : TDataset; - AStream : TStream); +Procedure TRESTDWStorageBin.SaveRecordToStream(ADataset : TDataset; + AWriter : TRESTDWBinaryPacketWriter); Var - vField : TField; - vString : DWString; - vInt64 : DWInt64; - I, - vInt : DWInteger; - vDouble, - vTimeZone : DWDouble; - vSingle : DWSingle; - vSmallint : DWSmallint; - vCurrency : DWCurrency; - vMemoryAStream : TMemoryStream; - vBoolean : Boolean; - vByte : Byte; - {$IFDEF DELPHIXEUP} - vTimeStampOffset : TSQLTimeStampOffset; - {$ENDIF} + I : Integer; + J : Integer; + L : LongWord; + AField : TField; + ABytes : TRESTDWMemBytes; + AString : AnsiString; + ADateTime : TDateTime; + ADouble : Double; + ACurrency : Currency; + ABcd : TBcd; + ATimeStamp : TTimeStamp; + AWireValue : Integer; Begin - For I := 0 To Length(FFieldTypes) -1 Do + AWriter.BeginRecord; + For I := 0 To ADataset.FieldCount - 1 Do Begin - vField := ADataset.Fields[i]; - vField.Clear; - AStream.Read(vBoolean, Sizeof(Byte)); - If FFieldTypes[i] <> dwftBoolean Then + AField := ADataset.Fields[I]; + If AField.IsNull Then Begin - If Not vBoolean Then + AWriter.StoreNull(I); Continue; End; - // N - Bytes - If (FFieldTypes[i] In [dwftFixedChar, - dwftWideString, - dwftString, - dwftVarBytes, - dwftFixedWideChar]) Then - Begin - AStream.Read(vInt64, Sizeof(vInt64)); - vString := ''; - If vInt64 > 0 Then - Begin - SetLength(vString, vInt64); - {$IFDEF FPC} - AStream.Read(Pointer(vString)^, vInt64); - If EncodeStrs Then - vString := DecodeStrings (vString, csUndefined); - vString := GetStringEncode(vString, csUndefined); - {$ELSE} - AStream.Read(vString[InitStrPos], vInt64); - If EncodeStrs Then - vString := DecodeStrings(vString); - {$ENDIF} - End; - vField.AsString := vString; - End - // 1 - Byte - Inteiro - Else If (FFieldTypes[i] In [dwftByte, - dwftShortint]) Then - Begin - AStream.Read(vByte, Sizeof(vByte)); - vField.AsInteger := vByte; - End - // 1 - Byte - Boolean - Else If (FFieldTypes[i] In [dwftBoolean]) Then - Begin - AStream.Read(vBoolean, Sizeof(vBoolean)); - vField.AsBoolean := vBoolean; - End - // 2 - Bytes - Else If (FFieldTypes[i] In [dwftSmallint, - dwftWord]) Then - Begin - AStream.Read(vSmallint, Sizeof(vSmallint)); - vField.AsInteger := vSmallint; - End - // 4 - Bytes - Inteiros - Else If (FFieldTypes[i] In [dwftInteger]) Then - Begin - AStream.Read(vInt, Sizeof(vInt)); - vField.AsInteger := vInt; - End - // 4 - Bytes - Flutuantes - Else If (FFieldTypes[i] In [dwftSingle]) Then - Begin - AStream.Read(vSingle, Sizeof(vSingle)); - {$IFDEF DELPHIXEUP} - vField.AsSingle := vSingle; - {$ELSE} - vField.AsFloat := vSingle; - {$ENDIF} - End - // 8 - Bytes - Inteiros - Else If (FFieldTypes[i] In [dwftLargeint, - dwftAutoInc, - dwftLongWord]) Then - Begin - AStream.Read(vInt64, Sizeof(vInt64)); - {$IFDEF DELPHIXEUP} - vField.AsLargeInt := vInt64; - {$ELSE} - vField.AsInteger := vInt64; - {$ENDIF} - End - // 8 - Bytes - Flutuantes - Else If (FFieldTypes[i] In [dwftFloat, - dwftExtended]) Then + If IsStringField(AField.DataType) Then Begin - AStream.Read(vDouble, Sizeof(vDouble)); - vField.AsFloat := vDouble; - End - // 8 - Bytes - Date, Time, DateTime - Else If (FFieldTypes[i] In [dwftDate, - dwftTime, - dwftDateTime]) Then + AString := AnsiString(AField.AsString); + If Length(AString) > 0 Then + AWriter.StoreField(I, @AString[1], Length(AString)) + Else + AWriter.StoreField(I, Nil, 0); + Continue; + End; + If FieldTypeToDWFieldType(AField.DataType) = dwftDate Then Begin - AStream.Read(vDouble, Sizeof(vDouble)); - vField.AsDateTime := vDouble; - End - // TimeStamp To Double - 8 Bytes - Else If (FFieldTypes[i] In [dwftTimeStamp]) Then + AWireValue := Trunc(AField.AsDateTime) + 693594; + AWriter.StoreField(I, @AWireValue, SizeOf(AWireValue)); + Continue; + End; + If FieldTypeToDWFieldType(AField.DataType) = dwftTime Then Begin - AStream.Read(vDouble, Sizeof(vDouble)); - vField.AsDateTime := vDouble; - End - // TimeStampOffSet To Double - 8 Bytes - // + TimeZone - 2 Bytes - Else If (FFieldTypes[i] In [dwftTimeStampOffset]) Then + ATimeStamp := DateTimeToTimeStamp(AField.AsDateTime); + AWireValue := ATimeStamp.Time; + AWriter.StoreField(I, @AWireValue, SizeOf(AWireValue)); + Continue; + End; + If FieldTypeToDWFieldType(AField.DataType) = dwftBCD Then Begin - {$IFDEF DELPHIXEUP} - AStream.Read(vDouble, Sizeof(vDouble)); - {$IFDEF RESTDWMEMTABLE} - vTimeStampOffset := DateTimeToSQLTimeStampOffset(vDouble); - {$ENDIF} - AStream.Read(vByte, Sizeof(vByte)); - vTimeStampOffset.TimeZoneHour := vByte - 12; - AStream.Read(vByte, Sizeof(vByte)); - vTimeStampOffset.TimeZoneMinute := vByte; - {$IFDEF RESTDWMEMTABLE} - vField.AsSQLTimeStampOffset := vTimeStampOffset; - {$ENDIF} - {$ELSE} - // field foi transformado em datetime - AStream.Read(vDouble, Sizeof(vDouble)); - AStream.Read(vByte, SizeOf(vByte)); - vTimeZone := (vByte - 12) / 24; - AStream.Read(vByte, SizeOf(vByte)); - If vTimeZone > 0 Then - vTimeZone := vTimeZone + (vByte / 60 / 24) - Else - vTimeZone := vTimeZone - (vByte / 60 / 24); - vDouble := vDouble - vTimeZone; - vField.AsDateTime := vDouble; - {$ENDIF} - End - // 8 - Bytes - Currency - Else If (FFieldTypes[i] In [dwftCurrency, - dwftBCD, - dwftFMTBcd]) Then + ACurrency := AField.AsCurrency; + AWriter.StoreField(I, @ACurrency, SizeOf(ACurrency)); + Continue; + End; + If FieldTypeToDWFieldType(AField.DataType) = dwftFMTBcd Then Begin - AStream.Read(vCurrency, Sizeof(vCurrency)); - vField.AsCurrency := vCurrency; - End - // N Bytes - Blobs - Else If (FFieldTypes[i] In [dwftStream, - dwftBlob, - dwftOraBlob, - dwftBytes, - dwftMemo, - dwftWideMemo, - dwftOraClob, - dwftFmtMemo]) Then + ABcd := AField.AsBCD; + AWriter.StoreField(I, @ABcd, SizeOf(ABcd)); + Continue; + End; + If FieldTypeToDWFieldType(AField.DataType) = dwftExtended Then Begin - AStream.Read(vInt64, Sizeof(vInt64)); - If vInt64 > 0 Then - Begin - vMemoryAStream := TMemoryStream.Create; - Try - vMemoryAStream.CopyFrom(AStream, vInt64); - vMemoryAStream.Position := 0; - TBlobField(vField).LoadFromStream(vMemoryAStream); - Finally - FreeAndNil(vMemoryAStream); - End; - End; - End - // N Bytes - Others - Else +{$IFDEF FPC} + ADouble := AField.AsFloat; +{$ELSE} + {$IFDEF DELPHI2010UP} + If AField.DataType = ftExtended Then + ADouble := AField.AsExtended + Else + {$ENDIF} + ADouble := AField.AsFloat; +{$ENDIF} + AWriter.StoreField(I, @ADouble, SizeOf(ADouble)); + Continue; + End; + If FieldTypeToDWFieldType(AField.DataType) In [dwftDateTime, + dwftTimeStamp, + dwftOraTimeStamp, + dwftTimeStampOffset] Then Begin - AStream.Read(vInt64, Sizeof(vInt64)); - vString := ''; - If vInt64 > 0 Then - Begin - SetLength(vString, vInt64); - {$IFDEF FPC} - AStream.Read(Pointer(vString)^, vInt64); - If EncodeStrs Then - vString := DecodeStrings(vString, csUndefined); - vString := GetStringEncode(vString, csUndefined); - {$ELSE} - AStream.Read(vString[InitStrPos], vInt64); - If EncodeStrs Then - vString := DecodeStrings(vString); - {$ENDIF} - End; - vField.AsString := vString; + ADateTime := AField.AsDateTime; + AWriter.StoreField(I, @ADateTime, SizeOf(ADateTime)); + Continue; End; + L := Length(AField.AsBytes); + SetLength(ABytes, L); + For J := 0 To Integer(L) - 1 Do + ABytes[J] := AField.AsBytes[J]; + If L > 0 Then + AWriter.StoreField(I, @ABytes[0], L) + Else + AWriter.StoreField(I, Nil, 0); End; + AWriter.EndRecord; End; Procedure TRESTDWStorageBin.SaveDatasetToStream(ADataset : TDataset; Var AStream : TStream); Var - i : DWInteger; - vRecordCount : DWInt64; - vString : DWString; - vInt : DWInt16; - vBoolean : Boolean; - vByte : Byte; - vBookMark : TBookmark; + I : Integer; + AField : TField; + AWriter : TRESTDWBinaryPacketWriter; + ABookmark : TBookmark; + AHasBookmark : Boolean; Begin - // AStream.Size := 0; // TBufferedFileStream nao funciona no lazarus - AStream.Seek(0,soBeginning); If Not ADataset.Active Then ADataset.Open Else ADataset.CheckBrowseMode; - ADataset.UpdateCursorPos; - // fields cound - I := ADataset.FieldCount; - AStream.Write(i, SizeOf(I)); - // encodestr - vBoolean := EncodeStrs; - AStream.Write(vBoolean, SizeOf(vBoolean)); - I := 0; - While i < ADataset.FieldCount Do - Begin - // field kind - vByte := Ord(ADataset.Fields[i].FieldKind); - AStream.Write(vByte, SizeOf(vByte)); - // field name - vString := ADataset.Fields[i].DisplayName; - vByte := Length(vString); - AStream.Write(vByte, SizeOf(vByte)); - AStream.Write(vString[InitStrPos], vByte); - // datatype - vByte := FieldTypeToDWFieldType(ADataset.Fields[i].DataType); - Case vByte Of - dwftFixedWideChar, - dwftWideString : vByte := FieldTypeToDWFieldType(ftString); - dwftSingle : vByte := FieldTypeToDWFieldType(ftFloat); + AStream.Size := 0; + AStream.Position := 0; + AWriter := TRESTDWBinaryPacketWriter.Create(AStream); + Try +{$IFDEF RESTDWLAZARUS} + AWriter.DatabaseCharSet := DatabaseCharSet; +{$ENDIF} + AWriter.ClearFieldDefs; + For I := 0 To ADataset.FieldCount - 1 Do + Begin + AField := ADataset.Fields[I]; + AWriter.AddFieldDef(AField.FieldName, + AField.DisplayName, + AField.Size, + AField.DataType, + AField.ReadOnly); End; - AStream.Write(vByte, SizeOf(vByte)); - // field size - vInt := ADataset.Fields[i].Size; - AStream.Write(vInt, SizeOf(vInt)); - // field precision - vInt := 0; - If ADataset.Fields[i].InheritsFrom(TFloatField) Then - vInt := TFloatField(ADataset.Fields[i]).Precision; - AStream.Write(vInt, SizeOf(vInt)); - // requeired + provider flags - vByte := 0; - If ADataset.Fields[i].Required Then - vByte := vByte + 1; - If pfInUpdate In ADataset.Fields[i].ProviderFlags Then - vByte := vByte + 2; - If pfInWhere In ADataset.Fields[i].ProviderFlags Then - vByte := vByte + 4; - If pfInKey In ADataset.Fields[i].ProviderFlags Then - vByte := vByte + 8; - If pfHidden In ADataset.Fields[i].ProviderFlags Then - vByte := vByte + 16; - {$IFDEF RESTDWLAZARUS} - If pfRefreshOnInsert In ADataset.Fields[i].ProviderFlags Then - vByte := vByte + 32; - If pfRefreshOnUpdate in ADataset.Fields[i].ProviderFlags Then - vByte := vByte + 64; - {$ENDIF} - AStream.Write(vByte, SizeOf(vByte)); - I := I + 1; - End; - I := AStream.Position; - // marcando position do recordcount = 0 - vRecordCount := 0; - AStream.WriteBuffer(vRecordCount, SizeOf(vRecordCount)); - If Not ADataset.IsUniDirectional Then - vBookMark := ADataset.GetBookmark; - ADataset.DisableControls; - If Not ADataset.IsUniDirectional Then - ADataset.First; - vRecordCount := 0; - While Not ADataset.Eof Do - Begin - Try - SaveRecordToStream(ADataset,AStream); - Except + AWriter.StoreFieldDefs(1); + AHasBookmark := False; + If Not ADataset.IsUniDirectional Then + Begin + ABookmark := ADataset.GetBookmark; + AHasBookmark := True; End; - ADataset.Next; - vRecordCount := vRecordCount + 1; - End; - If Not ADataset.IsUniDirectional Then - Begin - ADataset.GotoBookmark(vBookMark); - ADataset.FreeBookmark(vBookMark); + ADataset.DisableControls; + Try + If Not ADataset.IsUniDirectional Then + ADataset.First; + While Not ADataset.Eof Do + Begin + SaveRecordToStream(ADataset, AWriter); + ADataset.Next; + End; + Finally + If AHasBookmark Then + Begin + If ADataset.BookmarkValid(ABookmark) Then + ADataset.GotoBookmark(ABookmark); + ADataset.FreeBookmark(ABookmark); + End; + ADataset.EnableControls; End; - ADataset.EnableControls; - // marcando novo valor de recordcount - AStream.Position := i; - AStream.WriteBuffer(vRecordCount,SizeOf(vRecordCount)); + Finally + AWriter.Free; + End; AStream.Position := 0; End; Procedure TRESTDWStorageBin.SaveDWMemToStream(IDataset : TDataset; Var AStream : TStream); -Var - ADataset : {$IFDEF UNIDACMEM} - TVirtualTable - {$ENDIF} - {$IFDEF ZEOSMEM} - TZMemTable - {$ENDIF} - {$IFDEF RESTFDMEMTABLE} - TFDMemtable - {$ENDIF} - {$IFDEF RESTDWMEMTABLE} - TRESTDWMemtable - {$ENDIF}; - I : DWInteger; - vRecordCount : DWInt64; - vString : DWString; - vInt : DWInt16; - vBoolean : Boolean; - vByte : Byte; - vBookMark : TBookmark; Begin - ADataSet := {$IFDEF UNIDACMEM} - TVirtualTable - {$ENDIF} - {$IFDEF ZEOSMEM} - TZMemTable - {$ENDIF} - {$IFDEF RESTFDMEMTABLE} - TFDMemtable - {$ENDIF} - {$IFDEF RESTDWMEMTABLE} - TRESTDWMemtable - {$ENDIF}(IDataset); - AStream.Size := 0; - If not ADataset.Active Then - ADataset.Open - Else - ADataset.CheckBrowseMode; - ADataset.UpdateCursorPos; - // field count - i := ADataset.FieldCount; - AStream.Write(i, SizeOf(I)); - // encode str - vBoolean := EncodeStrs; - AStream.Write(vBoolean, SizeOf(vBoolean)); - I := 0; - While I < ADataset.FieldCount Do - Begin - // fieldkind - vByte := Ord(ADataset.Fields[i].FieldKind); - AStream.Write(vByte, SizeOf(vByte)); - // fieldname - vString := ADataset.Fields[i].DisplayName; - vByte := Length(vString); - AStream.Write(vByte, SizeOf(vByte)); - AStream.Write(vString[InitStrPos], vByte); - // datatype - vByte := FieldTypeToDWFieldType(ADataset.Fields[i].DataType); - Case vByte Of - dwftFixedWideChar, - dwftWideString : vByte := FieldTypeToDWFieldType(ftString); - dwftSingle : vByte := FieldTypeToDWFieldType(ftFloat); - End; - AStream.Write(vByte, SizeOf(vByte)); - // fieldsize - vInt := ADataset.Fields[i].Size; - AStream.Write(vInt, SizeOf(vInt)); - // field precision - vInt := 0; - If ADataset.Fields[i].InheritsFrom(TFloatField) Then - vInt := TFloatField(ADataset.Fields[i]).Precision; - AStream.Write(vInt, SizeOf(vInt)); - // required + provider flags - vByte := 0; - If ADataset.Fields[i].Required Then - vByte := vByte + 1; - If pfInUpdate In ADataset.Fields[i].ProviderFlags Then - vByte := vByte + 2; - If pfInWhere in ADataset.Fields[i].ProviderFlags Then - vByte := vByte + 4; - If pfInKey In ADataset.Fields[i].ProviderFlags Then - vByte := vByte + 8; - If pfHidden In ADataset.Fields[i].ProviderFlags Then - vByte := vByte + 16; - {$IFDEF RESTDWLAZARUS} - If pfRefreshOnInsert In ADataset.Fields[i].ProviderFlags Then - vByte := vByte + 32; - If pfRefreshOnUpdate In ADataset.Fields[i].ProviderFlags Then - vByte := vByte + 64; - {$ENDIF} - AStream.Write(vByte, SizeOf(vByte)); - i := i + 1; - End; - I := AStream.Position; - // marcando position recordcount = 0 - vRecordCount := 0; - AStream.WriteBuffer(vRecordCount, SizeOf(vRecordCount)); - vRecordCount := SaveRecordDWMemToStream(TRESTDWMemtable(IDataSet), AStream); - // salvando novo valor de recordcount - AStream.Position := i; - AStream.WriteBuffer(vRecordCount, SizeOf(vRecordCount)); - AStream.Position := 0; + SaveDatasetToStream(IDataset, AStream); End; -Function TRESTDWStorageBin.SaveRecordDWMemToStream(Dataset : TRESTDWMemTable; - stream : TStream) : Longint; +Procedure TRESTDWStorageBin.LoadRecordFromStream(ADataset : TDataset; + AStream : TStream; + AWireFieldTypes : Array Of Byte; + ANullBitmapSize : Integer); Var - vDataSet : {$IFDEF UNIDACMEM} - TVirtualTable - {$ENDIF} - {$IFDEF ZEOSMEM} - TZMemTable - {$ENDIF} - {$IFDEF RESTFDMEMTABLE} - TFDMemtable - {$ENDIF} - {$IFDEF RESTDWMEMTABLE} - TRESTDWMemtable - {$ENDIF}; - I, B, aIndex : DWInteger; - vActualRecord : TRESTDWMTMemoryRecord; - PActualRecord : PRESTDWMTMemBuffer; - PData : {$IFDEF FPC}PAnsiChar{$ELSE}PByte{$ENDIF}; - vDataType : TFieldType; - vDWFieldType : Byte; - vFieldCount : DWInteger; - vString : DWString; - vInt64 : DWInt64; - vCardinal : DWCardinal; - vInt : DWInteger; - vByte : Byte; - vWord : Word; - vSingle : DWSingle; - vDouble : DWDouble; - vCurrency : DWCurrency; - vExtended : DWLongDouble; - vBCD : DWBCD; - vMemoryStream : TMemoryStream; - vBoolean : Boolean; - vRESTDWBytes : TRESTDWBytes; - vTimeStamp : {$IFDEF FPC} TTimeStamp {$ELSE} TSQLTimeStamp {$ENDIF}; - {$IFNDEF FPC} - {$IF CompilerVersion >= 21} - vTimeStampOffSet : TSQLTimeStampOffset; - {$IFEND} - {$ENDIF} + I : Integer; + L : LongWord; + AField : TField; + ANullBitmap : Array Of Byte; + ABuffer : Array Of Byte; + AString : AnsiString; + ADateTime : TDateTime; + ADouble : Double; + ACurrency : Currency; + ABcd : TBcd; +{$IFDEF FPC} + ATimeStamp : TTimeStamp; + AWireValue : Integer; +{$ENDIF} + ABlobStream : TMemoryStream; Begin - vDataSet := {$IFDEF UNIDACMEM} - TVirtualTable - {$ENDIF} - {$IFDEF ZEOSMEM} - TZMemTable - {$ENDIF} - {$IFDEF RESTFDMEMTABLE} - TFDMemtable - {$ENDIF} - {$IFDEF RESTDWMEMTABLE} - TRESTDWMemtable - {$ENDIF}(dataset); - vFieldCount := vDataSet.Fields.Count - 1; - Result := TRESTDWMemtable(DataSet).GetRecordCount - 1; - For I := 0 To Result Do + SetLength(ANullBitmap, ANullBitmapSize); + If ANullBitmapSize > 0 Then + AStream.ReadBuffer(ANullBitmap[0], ANullBitmapSize); + For I := 0 To ADataset.FieldCount - 1 Do Begin - vActualRecord := Dataset.GetMemoryRecord(I); - {$IFDEF RESTDWMEMTABLE} - pActualRecord := PRESTDWMTMemBuffer(vActualRecord.Data); - {$ENDIF} - vBoolean := False; - For B := 0 To vFieldCount Do + AField := ADataset.Fields[I]; + If (ANullBitmapSize > 0) And + ((ANullBitmap[I Div 8] And Byte(1 Shl (I Mod 8))) <> 0) Then Begin - aIndex := vDataSet.Fields[B].FieldNo - 1; - If (aIndex >= 0) And (PActualRecord <> Nil) Then - Begin - vDataType := vDataSet.FieldDefs[aIndex].DataType; - If vDataType <> ftBoolean Then - Begin - {$IFNDEF FPC} - {$IF compilerversion < 21} - vBoolean := vDataSet.Fields[B].Size > 0; - {$ELSE} - vBoolean := vDataSet.Fields[B].IsNull; - {$IFEND} - {$ELSE} - vBoolean := vDataSet.Fields[B].IsNull; - {$ENDIF} - vBoolean := Not vBoolean; - Stream.Write(vBoolean, SizeOf(boolean)); - If Not vBoolean Then - Continue; - End; - If Dataset.DataTypeSuported(vDataType) Then - Begin - {$IFDEF RESTDWMEMTABLE} - If Dataset.DataTypeIsBlobTypes(vDataType) Then - PData := Pointer(@PMemBlobArray(PActualRecord + TRESTDWMemtable(DataSet).GetOffSetsBlobs)^[vDataSet.Fields[B].Offset]) - Else - PData := Pointer(PActualRecord + dataset.GetOffSets(vDataSet.Fields[B])); - {$ENDIF} - End; - vDWFieldType := FieldTypeToDWFieldType(vDataType); - // N Bytes - Case vDWFieldType Of - dwftFixedChar, - dwftWideString, - dwftFixedWideChar : Begin - {$IFDEF RESTDWANDROID} - vString := MarshaledAString(PData); - {$ELSE} - SetLength(vRESTDWBytes, vDataSet.Fields[B].Size); - Try - Move(PRESTDWBytes(@Pdata)^[0], vRESTDWBytes[0], vDataSet.Fields[B].Size); - vString := StringReplace(BytesToString(vRESTDWBytes, false), #0, '', [rfReplaceAll]); - Finally - SetLength(vRESTDWBytes, 0); - End; - {$ENDIF} - If EncodeStrs Then - vString := EncodeStrings(vString{$IFDEF FPC}, csUndefined{$ENDIF}); - vInt64 := Length(vString)* SizeOf(vString[1]); - Stream.Write(vInt64, Sizeof(vInt64)); - {$IFNDEF FPC} - If vInt64 <> 0 Then - Stream.Write(vString[InitStrPos], vInt64); - {$ELSE} - If vInt64 <> 0 Then - Stream.Write(vString[1], vInt64); - {$ENDIF} - End; - dwftVarBytes, - dwftString : Begin - {$IFDEF RESTDWANDROID} - vString := MarshaledAString(PData); - {$ELSE} - SetLength(vRESTDWBytes, vDataSet.Fields[B].Size); - Try - Move(PRESTDWBytes(@Pdata)^[0], vRESTDWBytes[0], vDataSet.Fields[B].Size); - vString := StringReplace(BytesToString(vRESTDWBytes, false), #0, '', [rfReplaceAll]); - Finally - SetLength(vRESTDWBytes, 0); - End; - {$ENDIF} - If EncodeStrs Then - vString := EncodeStrings(vString{$IFDEF FPC}, csUndefined{$ENDIF}); - vInt64 := Length(vString); - Stream.Write(vInt64, Sizeof(vInt64)); - {$IFNDEF FPC} - If vInt64 <> 0 Then - Stream.Write(vString[InitStrPos], vInt64); - {$ELSE} - If vInt64 <> 0 Then - Stream.Write(vString[1], vInt64); - {$ENDIF} - End; - // 1 - Byte - dwftByte, - dwftShortint, - dwftBoolean : Begin - Move(PData^, vByte, Sizeof(vByte)); - Stream.Write(vByte, Sizeof(vByte)); - End; - // 2 - Bytes - dwftSmallint, - dwftWord : Begin - Move(PData^, vWord, Sizeof(vWord)); - Stream.Write(vWord, Sizeof(vWord)); - End; - // 4 - Bytes - Inteiros - dwftInteger : Begin - Move(PData^, vInt, Sizeof(vInt)); - Stream.Write(vByte, Sizeof(vInt)); - End; -// // 4 - Bytes - Flutuantes -// dwftSingle : Begin -// Move(PData^, vDouble, Sizeof(vDouble)); -// Stream.Write(vDouble, Sizeof(vDouble)); -// End; - // 8 - Bytes - Inteiros - dwftLargeint, - dwftAutoInc, - dwftLongWord : Begin - Move(PData^, vInt64, Sizeof(vInt64)); - Stream.Write(vInt64, Sizeof(vInt64)); - End; - // 8 - Bytes - Flutuantes - dwftFloat, - dwftDate, - dwftTime : Begin - Move(PData^, vDouble, Sizeof(vDouble)); - Stream.Write(vDouble, Sizeof(vDouble)); - End; - // TimeStamp To Double - 8 Bytes - dwftDateTime, - dwftTimeStamp : Begin - SetLength(vRESTDWBytes, Sizeof(vTimeStamp)); - Try - Move(PRESTDWBytes(@Pdata)^[0], vRESTDWBytes[0], Sizeof(vTimeStamp)); - Stream.Write(vRESTDWBytes, Length(vRESTDWBytes)); - Finally - SetLength(vRESTDWBytes, 0); - End; - End; - {$IFNDEF FPC} - {$IF CompilerVersion >= 21} - // TimeStampOffSet To Double - 8 Bytes - // + TimeZone - 2 Bytes - dwftTimeStampOffset : Begin - Move(PData^, vTimeStampOffSet, Sizeof(vTimeStampOffSet)); - {$IFDEF RESTDWMEMTABLE} - vDouble := SQLTimeStampOffsetToDateTime(vTimeStampOffSet); - {$ENDIF} - Stream.Write(vDouble, Sizeof(vDouble)); - vByte := vTimeStampOffSet.TimeZoneHour + 12; - Stream.Write(vByte, Sizeof(vByte)); - vByte := vTimeStampOffSet.TimeZoneMinute; - Stream.Write(vByte, Sizeof(vByte)); - End; - {$IFEND} - {$ENDIF} - // 8 - Bytes - Currency - dwftCurrency : Begin - Move(PData^, vCurrency, Sizeof(vCurrency)); - Stream.Write(vCurrency, Sizeof(vCurrency)); - End; - dwftExtended : Begin - Move(PData^, vDouble, Sizeof(vDouble)); - Stream.Write(vDouble, Sizeof(vDouble)); - End; - // 8 - Bytes - Currency - dwftBCD : Begin - {$IFDEF FPC} - Move(PData^,vCurrency,Sizeof(vCurrency)); - {$ELSE} - Move(PData^,vBCD,Sizeof(vBCD)); - {$IF CompilerVersion <= 21} - BCDToCurr(vBCD, vCurrency); - {$ELSE} - vCurrency := BCDToCurrency(vBCD); - {$IFEND} - {$ENDIF} - Stream.Write(vCurrency, Sizeof(vCurrency)); - End; - {$IFNDEF FPC} - // 8 - Bytes - Currency - dwftFMTBcd : Begin - Move(PData^, vBCD, Sizeof(vBCD)); - {$IFDEF FPC} - vCurrency := BCDToDouble(vBCD); - {$ELSE} - {$IF CompilerVersion <= 21} - BCDToCurr(vBCD, vCurrency); - {$ELSE} - vCurrency := BCDToCurrency(vBCD); - {$IFEND} - {$ENDIF} - Stream.Write(vCurrency, Sizeof(vCurrency)); - End; - {$ENDIF} - // N Bytes - Blobs -// dwftWideMemo, -// dwftFmtMemo, -// dwftMemo, - dwftStream, - dwftBlob, - dwftOraBlob, - dwftBytes, - dwftOraClob, - dwftMemo, - dwftWideMemo, - dwftFmtMemo : Begin - vMemoryStream := TMemoryStream.Create; - Try - {$IFDEF RESTDWANDROID} - vString := MarshaledAString(PData); - {$ELSE} - vString := Pansichar(PData); - {$ENDIF} - vInt64 := Length(vString); - Stream.Write(vInt64, Sizeof(vInt64)); - vMemoryStream.Position := 0; - Stream.CopyFrom(vMemoryStream, vInt64); - Finally - FreeAndNil(vMemoryStream); - End; - End; - // N Bytes - Others - Else - Begin - {$IFDEF RESTDWANDROID} - vString := MarshaledAString(PData); - {$ELSE} - vString := Pansichar(PData); - {$ENDIF} - If EncodeStrs Then - vString := EncodeStrings(vString{$IFDEF FPC}, csUndefined{$ENDIF}); - vInt64 := Length(vString); - Stream.Write(vInt64, Sizeof(vInt64)); - {$IFNDEF FPC} - If vInt64 <> 0 Then - Stream.Write(vString[InitStrPos], vInt64); - {$ELSE} - If vInt64 <> 0 Then - Stream.Write(vString[1], vInt64); - {$ENDIF} - End; - End; - End; + AField.Clear; + Continue; + End; + If IsStringField(AField.DataType) Then + Begin + AString := ReadAnsiString(AStream); + AField.AsString := String(AString); + Continue; End; +{$IFDEF FPC} + If (I < Length(AWireFieldTypes)) And + (AWireFieldTypes[I] = dwftDate) Then + Begin + AStream.ReadBuffer(AWireValue, SizeOf(AWireValue)); + AField.AsDateTime := TDateTime(AWireValue - 693594); + Continue; + End; + If (I < Length(AWireFieldTypes)) And + (AWireFieldTypes[I] = dwftTime) Then + Begin + AStream.ReadBuffer(AWireValue, SizeOf(AWireValue)); + AField.AsDateTime := AWireValue / 86400000.0; + Continue; + End; + If (I < Length(AWireFieldTypes)) And + (AWireFieldTypes[I] = dwftBCD) Then + Begin + AStream.ReadBuffer(ACurrency, SizeOf(ACurrency)); + AField.AsCurrency := ACurrency; + Continue; + End; + If (I < Length(AWireFieldTypes)) And + (AWireFieldTypes[I] = dwftFMTBcd) Then + Begin + AStream.ReadBuffer(ABcd, SizeOf(ABcd)); + AField.AsBCD := ABcd; + Continue; + End; +{$ENDIF} + + If (I < Length(AWireFieldTypes)) And + (AWireFieldTypes[I] = dwftExtended) Then + Begin + AStream.ReadBuffer(ADouble, SizeOf(ADouble)); +{$IFDEF FPC} + AField.AsFloat := ADouble; +{$ELSE} + {$IFDEF DELPHI2010UP} + If AField.DataType = ftExtended Then + AField.AsExtended := ADouble + Else + {$ENDIF} + AField.AsFloat := ADouble; +{$ENDIF} + Continue; + End; + If (I < Length(AWireFieldTypes)) And + (AWireFieldTypes[I] In [dwftDateTime, + dwftTimeStamp, + dwftOraTimeStamp, + dwftTimeStampOffset]) Then + Begin + AStream.ReadBuffer(ADateTime, SizeOf(ADateTime)); + AField.AsDateTime := ADateTime; + Continue; + End; + If IsVariableField(AField.DataType) Then + L := ReadDWord(AStream) + Else + L := GetFixedWireSize(AWireFieldTypes[I], AField); + If Int64(L) > AStream.Size - AStream.Position Then + Raise Exception.Create('Invalid binary packet field size ' + IntToStr(L)); + SetLength(ABuffer, L); + If L > 0 Then + AStream.ReadBuffer(ABuffer[0], L); + If IsBlobField(AField.DataType) Then + Begin + ABlobStream := TMemoryStream.Create; + Try + If L > 0 Then + ABlobStream.WriteBuffer(ABuffer[0], L); + ABlobStream.Position := 0; + TBlobField(AField).LoadFromStream(ABlobStream); + Finally + ABlobStream.Free; + End; + End + Else If L > 0 Then + AField.SetData(@ABuffer[0]) + Else + AField.Clear; End; - Result := Result + 1; End; -Procedure TRESTDWStorageBin.SaveRecordToStream(ADataset : TDataset; - Var AStream : TStream); +Procedure TRESTDWStorageBin.LoadDatasetFromStream(ADataset : TDataset; + AStream : TStream); +Const + RESTDWBinaryIdent : AnsiString = 'BinRESTDWDataSet'; Var - I : DWInteger; - vDWFieldType, - vByte : Byte; - vBytes : TRESTDWBytes; - vString : DWString; - vWideString : DWWideString; - vInt64 : DWInt64; - vInt : DWInteger; - vDouble : DWDouble; - vWord : DWWord; - vExtended : DWLongDouble; - vSingle : DWSingle; - vCurrency : DWCurrency; - vMemoryStream : TMemoryStream; - vBoolean : Boolean; - vRESTDWBytes : TRESTDWBytes; - vTimeStamp : {$IFDEF FPC} TTimeStamp {$ELSE} TSQLTimeStamp {$ENDIF}; - {$IFDEF DELPHIXEUP} - vTimeStampOffset : TSQLTimeStampOffset; - {$ENDIF} + I : Integer; + AAutoIncValue : Integer; + AFieldCount : Word; + AFieldSize : Word; + AWireType : Word; + AReadOnly : Byte; + ARecordMarker : Byte; + ARowState : Byte; + AUpdateOrder : Integer; + ANullBitmapSize : Integer; + AIdent : AnsiString; + AName : AnsiString; + ADisplayName : AnsiString; + AFieldDef : TFieldDef; + AField : TField; + AWireFieldTypes : Array Of Byte; Begin - vMemoryStream := nil; - For i := 0 To ADataset.FieldCount - 1 Do + AStream.Position := 0; + SetLength(AIdent, Length(RESTDWBinaryIdent)); + If Length(AIdent) > 0 Then + AStream.ReadBuffer(AIdent[1], Length(AIdent)); + If AIdent <> RESTDWBinaryIdent Then + Raise Exception.Create('The data stream format is unrecognized'); + If ReadByte(AStream) <> 20 Then + Raise Exception.Create('The data stream format is unrecognized'); + AFieldCount := ReadWord(AStream); + SetLength(AWireFieldTypes, AFieldCount); + ADataset.Close; + ADataset.FieldDefs.Clear; + For I := 0 To AFieldCount - 1 Do Begin - vBoolean := True; - If ADataset.Fields[i].DataType <> ftBoolean Then - Begin - vBoolean := ADataset.Fields[i].IsNull; - vBoolean := Not vBoolean; - AStream.Write(vBoolean, SizeOf(boolean)); - If Not vBoolean Then - Continue; - End; - vDWFieldType := FieldTypeToDWFieldType(ADataset.Fields[i].DataType); - // N - Bytes - Case vDWFieldType Of - dwftFixedChar, - dwftWideString, - dwftFixedWideChar : Begin - vString := ADataset.Fields[i].AsString; - If EncodeStrs Then - vString := EncodeStrings(vString{$IFDEF FPC}, DatabaseCharSet{$ENDIF}); - {$IFDEF FPC} - If DatabaseCharSet <> csUndefined Then - vString := GetStringDecode(vString, DatabaseCharSet); - {$ENDIF} - vInt64 := Length(vString);//Length(vWideString)* sizeof(vWideString[1]); - AStream.Write(vInt64, SizeOf(vInt64)); - If vInt64 <> 0 Then - AStream.Write(vString[InitStrPos], vInt64); - End; - // N - Bytes - dwftVarBytes, - dwftString : Begin - vString := ADataset.Fields[i].AsString; - If EncodeStrs Then - vString := EncodeStrings(vString{$IFDEF FPC}, DatabaseCharSet{$ENDIF}); - {$IFDEF FPC} - If DatabaseCharSet <> csUndefined Then - vString := GetStringDecode(vString, DatabaseCharSet); - {$ENDIF} - vInt64 := Length(vString); - AStream.Write(vInt64, SizeOf(vInt64)); - If vInt64 <> 0 Then - AStream.Write(vString[InitStrPos], vInt64); - End; - // 1 - Byte - Inteiros - dwftByte, - dwftShortint : Begin - vByte := ADataset.Fields[i].AsInteger; - AStream.Write(vByte, Sizeof(vByte)); - End; - // 1 - Byte - Boolean - dwftBoolean : Begin - vBoolean := ADataset.Fields[i].AsBoolean; - AStream.Write(vBoolean, Sizeof(vBoolean)); - End; - // 2 - Bytes - dwftSmallint, - dwftWord : Begin - vWord := ADataset.Fields[i].AsInteger; - AStream.Write(vWord, Sizeof(vWord)); - End; - // 4 - Bytes - Inteiros - dwftInteger : Begin - vInt := ADataset.Fields[i].AsInteger; - AStream.Write(vInt, Sizeof(vInt)); - End; - // 4 - Bytes - Flutuantes -// dwftSingle : Begin -// vSingle := ADataset.Fields[i].Value; -// AStream.Write(vSingle, SizeOf(vSingle)); -// End; - // 8 - Bytes - Inteiros - dwftLargeint, - dwftAutoInc, - dwftLongWord : Begin - {$IFDEF DELPHIXEUP} - vInt64 := ADataset.Fields[i].AsLargeInt; - {$ELSE} - vInt64 := ADataset.Fields[i].AsInteger; - {$ENDIF} - AStream.Write(vInt64, Sizeof(vInt64)); - End; - // 8 - Bytes - Flutuantes - dwftFloat - {$IFDEF FPC} - , 45, dwftExtended - {$ENDIF} : Begin - vDouble := ADataset.Fields[i].AsFloat; - AStream.Write(vDouble, Sizeof(vDouble)); - End; - {$IFNDEF FPC} - dwftExtended : Begin - vDouble := ADataset.Fields[i]{$IFNDEF FPC}.AsExtended{$ELSE}.AsFloat{$ENDIF}; - AStream.Write(vDouble, Sizeof(vDouble)); - End; - {$ENDIF} - // 8 - Bytes - Date, Time, DateTime, TimeStamp - dwftDate, - dwftTime, - dwftDateTime, - dwftTimeStamp : Begin - vDouble := ADataset.Fields[i].AsDateTime; - AStream.Write(vDouble, Sizeof(vDouble)); - End; - {$IFDEF DELPHIXEUP} - // TimeStampOffSet To Double - 8 Bytes - // + TimeZone - 2 Bytes - dwftTimeStampOffset : Begin - {$IFDEF RESTDWMEMTABLE} - vTimeStampOffSet := ADataset.Fields[i].AsSQLTimeStampOffset; - vDouble := SQLTimeStampOffsetToDateTime(vTimeStampOffSet); - {$ENDIF} - AStream.Write(vDouble, Sizeof(vDouble)); - vByte := vTimeStampOffSet.TimeZoneHour + 12; - AStream.Write(vByte, Sizeof(vByte)); - vByte := vTimeStampOffSet.TimeZoneMinute; - AStream.Write(vByte, Sizeof(vByte)); - End; - {$ENDIF} - // 8 - Bytes - Currency - dwftCurrency, - dwftBCD - {$IFNDEF FPC} - , dwftFMTBcd - {$ENDIF} : Begin - {$IFDEF FPC} - If ADataset.Fields[i].Isnull Then - vCurrency := 0 - Else - vCurrency := StrToFloat(ADataset.Fields[i].AsString); - {$ELSE} - vCurrency := ADataset.Fields[i].AsCurrency; - {$ENDIF} - AStream.Write(vCurrency, Sizeof(vCurrency)); - End; - // N Bytes - Blobs - dwftStream, - dwftBlob, - dwftOraBlob, - dwftBytes, - dwftOraClob, - dwftMemo, - dwftWideMemo, - dwftFmtMemo : Begin - vMemoryStream := TMemoryStream.Create; - Try - TBlobField(ADataset.Fields[i]).SaveToStream(vMemoryStream); - vInt64 := vMemoryStream.Size; - AStream.Write(vInt64, SizeOf(vInt64)); - SetLength(vBytes, vInt64); - if vInt64 > 0 then - begin - Try - vMemoryStream.Position := 0; - vMemoryStream.Read(vBytes[0], vInt64); - Except - End; - AStream.Write(vBytes[0], vInt64); - end; - Finally - SetLength(vBytes, 0); - FreeAndNil(vMemoryStream); - End; - End; - // N Bytes - Others + AName := ReadAnsiString(AStream); + ADisplayName := ReadAnsiString(AStream); + AFieldSize := ReadWord(AStream); + AWireType := ReadWord(AStream); + If AWireType > 255 Then + Raise Exception.Create('Invalid binary packet field type ' + IntToStr(AWireType)); + AWireFieldTypes[I] := Byte(AWireType); + AFieldDef := ADataset.FieldDefs.AddFieldDef; + AFieldDef.Name := String(AName); + AFieldDef.DisplayName := String(ADisplayName); + AFieldDef.Size := AFieldSize; + Case AWireFieldTypes[I] Of + dwftTimeStamp, + dwftOraTimeStamp, + dwftTimeStampOffset : AFieldDef.DataType := ftDateTime; Else - Begin - vString := ADataset.Fields[i].AsString; - If EncodeStrs Then - vString := EncodeStrings(vString{$IFDEF FPC}, csUndefined{$ENDIF}); - vInt64 := Length(vString); - AStream.Write(vInt64, SizeOf(vInt64)); - If vInt64 <> 0 Then - AStream.Write(vString[InitStrPos], vInt64); - End; + AFieldDef.DataType := DWFieldTypeToFieldType(AWireFieldTypes[I]); End; + AReadOnly := ReadByte(AStream); + If AReadOnly = 1 Then + AFieldDef.Attributes := AFieldDef.Attributes + [faReadonly]; End; + AStream.ReadBuffer(AAutoIncValue, SizeOf(AAutoIncValue)); + ANullBitmapSize := (AFieldCount + 7) Div 8; + ADataset.Open; + For I := 0 To ADataset.FieldCount - 1 Do + Begin + AField := ADataset.Fields[I]; + If I < AFieldCount Then + AField.ReadOnly := False; + End; + ADataset.DisableControls; + Try + While AStream.Position < AStream.Size Do + Begin + ARecordMarker := ReadByte(AStream); + If ARecordMarker <> $FE Then + Raise Exception.Create('Invalid binary packet record marker ' + IntToStr(ARecordMarker)); + ARowState := ReadByte(AStream); + If ARowState <> 0 Then + AStream.ReadBuffer(AUpdateOrder, SizeOf(AUpdateOrder)); + ADataset.Append; + Try + LoadRecordFromStream(ADataset, + AStream, + AWireFieldTypes, + ANullBitmapSize); + ADataset.Post; + Except + ADataset.Cancel; + Raise; + End; + End; + Finally + ADataset.EnableControls; + End; +End; + +Procedure TRESTDWStorageBin.LoadDWMemFromStream(IDataset : TDataset; + AStream : TStream); +Begin + LoadDatasetFromStream(IDataset, AStream); End; End. diff --git a/CORE/Source/Basic/uRESTDWZlib.pas b/CORE/Source/Basic/uRESTDWZlib.pas new file mode 100644 index 000000000..086dbcb51 --- /dev/null +++ b/CORE/Source/Basic/uRESTDWZlib.pas @@ -0,0 +1,322 @@ +unit uRESTDWZlib; + +{$I uRESTDW.inc} + +{ + REST Dataware . + Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON + de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores + Pascal e com compatibilidade entre sistemas operacionais. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. + + Membros do Grupo : + + XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. + Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. + Flvio Motta - Member Tester and DEMO Developer. + Mobius One - Devel, Tester and Admin. + Gustavo - Criptografia and Devel. + Eloy - Devel. + Roniery - Devel. +} + +Interface + +{$IFDEF FPC} + {$MODE OBJFPC}{$H+} +{$ENDIF} + +Uses + {$IFDEF RESTDWLAZARUS} + zstream, base64, + {$ELSE} + {$IFDEF FPC} + zstream, base64, + {$ENDIF} + {$ENDIF} + + SysUtils, Classes, zlib, + uRESTDWDataUtils, uRESTDWConsts, uRESTDWTools; + +// Funes de Compresso e descompresso de Stream com ZLib +Procedure ZCompressStream(inStream, outStream: TStream; + CompressionLevel: TCompressionLevel = clDefault); +Procedure ZDecompressStream(inStream, outStream: TStream); +Function ZDecompressStreamNew(Const S: TStream): TStream; +Function ZDecompressStr(Const S: String; Var Value: String): Boolean; +Function ZDecompressStreamD(Const S: TStringStream; + Var Value: TStringStream): Boolean; +Function ZCompressStreamNew(Const S: String): TStream; +Function ZCompressStreamSS(Const S: String): TStringStream; +Function ZCompressStr(Const S: String; Var Value: String): Boolean; +Function ZCompressStreamD(S: TStream; Var Value: TStream): Boolean; + +implementation + +Procedure ZCompressStream(inStream, outStream: TStream; + CompressionLevel: TCompressionLevel = clDefault); +Var + DS: TCompressionStream; + Size: DWInt64; +Begin + inStream.Position := 0; // Goto Start of input stream + DS := TCompressionStream.Create(CompressionLevel, outStream); + Try + Size := inStream.Size; + inStream.Position := 0; + DS.Write(Size, SizeOf(DWInt64)); + DS.CopyFrom(inStream, inStream.Size); + Finally + DS.Free; + End; +End; + +Procedure ZDecompressStream(inStream, outStream: TStream); +Var + D: TDecompressionstream; + B: Array [1 .. CompressBuffer] of Byte; + R: Integer; + Size: DWInt64; +Begin + D := TDecompressionstream.Create(inStream); + D.Read(Size, SizeOf(DWInt64)); + + {$IFDEF RESTDWLAZARUS} + While True Do + Begin + R := D.Read(B, SizeOf(B)); + If R <> 0 Then + outStream.WriteBuffer(B, R) + Else + Break; + End; + outStream.Position := 0; + FreeAndNil(D); + {$ELSE} + inStream.Position := SizeOf(Size); + Try + Repeat + If ((Size - outStream.Size) > CompressBuffer) Then + R := D.Read(B, SizeOf(B)) + Else + R := D.Read(B, (Size - outStream.Size)); + If R > 0 then + outStream.Write(B, R); + Until R < SizeOf(B); + Finally + outStream.Position := 0; + D.Free; + End; + {$ENDIF} +End; + +Function ZCompressStreamD(S: TStream; Var Value: TStream): Boolean; +Var + Utf8Stream: TStream; +Begin + Result := False; + Try + Utf8Stream := TMemoryStream.Create; + {$IF Defined(RESTDWLAZARUS) OR Defined(DELPHIXE4UP)} + Utf8Stream.CopyFrom(S, S.Size); + {$ELSE} + Utf8Stream.Write(AnsiString(TStringStream(S).Datastring) + [InitStrPos], S.Size); + {$IFEND} + Value := TMemoryStream.Create; + Try + ZCompressStream(Utf8Stream, Value, cCompressionLevel); + Value.Position := 0; + Result := True; + Finally + + End; + Finally + {$IFNDEF RESTDWLAZARUS}Utf8Stream.Size := 0; {$ENDIF} + Utf8Stream.Free; + If Value.Size = 0 Then + Begin + Result := False; + Value.Size := 0; + FreeAndNil(Value); + End; + End; +End; + +Function ZCompressStreamSS(Const S: String): TStringStream; +Var + Utf8Stream: TStringStream; +Begin + {$IF Defined(RESTDWLAZARUS)} + Utf8Stream := TStringStream.Create(S); + {$ELSEIF Defined(DELPHIXEUP)} + Utf8Stream := TStringStream.Create(S, TEncoding.UTF8); + {$ELSE} + Utf8Stream := TStringStream.Create(''); + Utf8Stream.Write(AnsiString(S)[1], Length(AnsiString(S))); + {$IFEND} + Result := TStringStream.Create(''{$IFDEF DELPHIXEUP}, TEncoding.UTF8{$ENDIF}); + Try + ZCompressStream(Utf8Stream, Result, cCompressionLevel); + Result.Position := 0; + Finally + {$IFNDEF FPC}Utf8Stream.Size := 0; {$ENDIF} + Utf8Stream.Free; + If Result.Size = 0 Then + FreeAndNil(Result); + End; +End; + +Function ZCompressStreamNew(Const S: String): TStream; +Var + Utf8Stream: TStream; +Begin + + {$IF Defined(RESTDWLAZARUS) OR not Defined(DELPHIXEUP) OR Defined(RESTDWWINDOWS)} + Utf8Stream := TMemoryStream.Create; + Utf8Stream.Write(AnsiString(S)[1], Length(AnsiString(S))); + {$ELSE} + {$IF Defined(RESTDWLINUX)} + Utf8Stream:= Tstringstream.Create(S, TEncoding.UTF8); + {$ELSE} + Utf8Stream.Write(S[1], Length(S)); + {$IFEND} + {$IFEND} + Result := TMemoryStream.Create; + Try + ZCompressStream(Utf8Stream, Result, cCompressionLevel); + Result.Position := 0; + Finally + {$IFNDEF RESTDWLAZARUS}Utf8Stream.Size := 0; {$ENDIF} + Utf8Stream.Free; + If Result.Size = 0 Then + FreeAndNil(Result); + End; +End; + +Function ZCompressStr(Const S: String; Var Value: String): Boolean; +Var + Utf8Stream: TStringStream; + Compressed: TMemoryStream; +Begin + Result := False; + {$IF Defined(DELPHIXEUP)} + Utf8Stream := TStringStream.Create(S, TEncoding.UTF8); + {$ELSEIF Defined(RESTDWLAZARUS)} + Utf8Stream := TStringStream.Create(S); + {$ELSE} + Utf8Stream := TStringStream.Create(''); + Utf8Stream.Write(AnsiString(S)[1], Length(AnsiString(S))); + {$IFEND} + Try + Compressed := TMemoryStream.Create; + Try + ZCompressStream(Utf8Stream, Compressed, cCompressionLevel); + Compressed.Position := 0; + Try + Value := StreamToHex(Compressed, False); + Result := True; + Finally + End; + Finally + Compressed := nil; + Compressed.Free; + End; + Finally + {$IFDEF DELPHIXEUP}Utf8Stream.Clear;{$ENDIF} + FreeAndNil(Utf8Stream); + End; +End; + +Function ZDecompressStreamD(Const S: TStringStream; + Var Value: TStringStream): Boolean; +Var + Utf8Stream, Base64Stream: TStringStream; + {$IFDEF RESTDWLAZARUS} + Encoder: TBase64DecodingStream; + {$ENDIF} +Begin + Base64Stream := TStringStream.Create(''{$IFDEF DELPHIXEUP}, TEncoding.UTF8{$ENDIF}); + S.Position := 0; + Base64Stream.CopyFrom(S, S.Size); + Base64Stream.Position := 0; + Try + Value := TStringStream.Create(''{$IFDEF DELPHIXEUP}, TEncoding.UTF8{$ENDIF}); + Try + Try + Utf8Stream := TStringStream.Create(''{$IFDEF DELPHIXEUP}, TEncoding.UTF8{$ENDIF}); + HexToStream(Base64Stream.Datastring, Utf8Stream); + Utf8Stream.Position := 0; + ZDecompressStream(Utf8Stream, Value); + Value.Position := 0; + Result := True; + Except + Result := False; + End; + Finally + {$IFNDEF RESTDWLAZARUS}Utf8Stream.Size := 0; {$ENDIF} + FreeAndNil(Utf8Stream); + End; + Finally + {$IFNDEF RESTDWLAZARUS}Base64Stream.Size := 0; {$ENDIF} + FreeAndNil(Base64Stream); + End; +End; + +Function ZDecompressStreamNew(Const S: TStream): TStream; +Begin + Result := TMemoryStream.Create; + S.Position := 0; + ZDecompressStream(S, Result); + Result.Position := 0; +End; + +Function ZDecompressStr(Const S: String; Var Value: String): Boolean; +Var + Utf8Stream, Compressed, Base64Stream: TStringStream; + {$IFDEF RESTDWLAZARUS} + Encoder: TBase64DecodingStream; + {$ENDIF} +Begin + Result := False; + {$IFDEF DELPHIXEUP} + Base64Stream := TStringStream.Create(S, TEncoding.ANSI); + {$ELSE} + Base64Stream := TStringStream.Create(S); + {$ENDIF} + Try + Compressed := TStringStream.Create(''); + Try + {$IFDEF RESTDWLAZARUS} + Utf8Stream := TStringStream.Create(''); + Encoder := TBase64DecodingStream.Create(Base64Stream); + Utf8Stream.CopyFrom(Encoder, Encoder.Size); + Utf8Stream.Position := 0; + FreeAndNil(Encoder); + Compressed.Position := 0; + ZDecompressStream(Utf8Stream, Compressed); + {$ELSE} + Utf8Stream := TStringStream.Create(''{$IFDEF DELPHIXEUP}, TEncoding.UTF8{$ENDIF}); + ZDecompressStream(Base64Stream, Compressed); + Compressed.Position := 0; + {$ENDIF} + Try + Value := Compressed.Datastring; + Result := True; + Finally + {$IFNDEF RESTDWLAZARUS}Utf8Stream.Size := 0; {$ENDIF} + FreeAndNil(Utf8Stream); + End; + Finally + {$IFNDEF RESTDWLAZARUS}Compressed.Size := 0; {$ENDIF} + FreeAndNil(Compressed); + End; + Finally + {$IFNDEF RESTDWLAZARUS}Base64Stream.Size := 0; {$ENDIF} + FreeAndNil(Base64Stream); + End; +End; + +end. From 4de071a0f69089153ccc8c4701f25344a79464e8 Mon Sep 17 00:00:00 2001 From: Roniery Santos Cardoso Date: Tue, 8 Sep 2026 21:59:51 -0300 Subject: [PATCH 04/22] fix(json): correcoes em JSON, params e utilitarios SSL/OpenSSL Corrige erro ao gravar numeros decimais em uRESTDWJSONObject, ajuste de tipo Boolean com MSSQL e formato do Json em uRESTDWParams, alem de correcao de transporte JSON e atualizacao dos utilitarios de SSL/ OpenSSL (Bson, OAuth2, DateUtils, SysUtils, System). refs r4018, r4022, r4064 --- CORE/Source/utils/JSON/uRESTDWDataJSON.pas | 2 +- .../utils/JSON/uRESTDWJSONInterface.pas | 1263 +++--- CORE/Source/utils/JSON/uRESTDWSerialize.pas | 2 +- CORE/Source/utils/SSL/OpenSSL.Api_11.pas | 20 +- CORE/Source/utils/SSL/RESTDWRootCA.pem | 3892 +++++++++++++++++ CORE/Source/utils/StringBuilderUnit.pas | 2 +- CORE/Source/utils/uRESTDWBase64.pas | 10 +- CORE/Source/utils/uRESTDWDynamic.pas | 2 +- CORE/Source/utils/uRESTDWJSONObject.pas | 6 +- CORE/Source/utils/uRESTDWMassiveBuffer.pas | 18 +- CORE/Source/utils/uRESTDWMimeTypes.pas | 12 +- CORE/Source/utils/uRESTDWOpenSslLib.pas | 22 +- CORE/Source/utils/uRESTDWTools.pas | 48 +- CORE/Source/utils/uRESTDWZlib.pas | 322 -- 14 files changed, 4552 insertions(+), 1069 deletions(-) create mode 100644 CORE/Source/utils/SSL/RESTDWRootCA.pem delete mode 100644 CORE/Source/utils/uRESTDWZlib.pas diff --git a/CORE/Source/utils/JSON/uRESTDWDataJSON.pas b/CORE/Source/utils/JSON/uRESTDWDataJSON.pas index 8bab51514..48ad31503 100644 --- a/CORE/Source/utils/JSON/uRESTDWDataJSON.pas +++ b/CORE/Source/utils/JSON/uRESTDWDataJSON.pas @@ -1,6 +1,6 @@ unit uRESTDWDataJSON; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} Interface diff --git a/CORE/Source/utils/JSON/uRESTDWJSONInterface.pas b/CORE/Source/utils/JSON/uRESTDWJSONInterface.pas index 76e6dfbff..77a25b60a 100644 --- a/CORE/Source/utils/JSON/uRESTDWJSONInterface.pas +++ b/CORE/Source/utils/JSON/uRESTDWJSONInterface.pas @@ -1,43 +1,38 @@ unit uRESTDWJSONInterface; -{$I ..\..\Includes\uRESTDW.inc} -{ - REST Dataware . - Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON - de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores - Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. - - Membros do Grupo : - - XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. - Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. - Mobius One - Devel, Tester and Admin. - Gustavo - Criptografia and Devel. - Eloy - Devel. - Roniery - Devel. -} +{$I uRESTDW.inc} interface {$IFDEF FPC} {$MODE OBJFPC}{$H+} {$ENDIF} + +{$IFDEF FPC} + {$DEFINE RESTDWLEGACYJSON} +{$ENDIF} +{$IFNDEF FPC} + {$IFNDEF DELPHIXE7UP} + {$DEFINE RESTDWLEGACYJSON} + {$ENDIF} +{$ENDIF} + Uses SysUtils, Classes, Variants, - {$IFNDEF FPC} system.json, {$ELSE} uRESTDWJSON, {$ENDIF} + {$IFDEF RESTDWLEGACYJSON} + uRESTDWJSON, + {$ELSE} + System.JSON, + {$ENDIF} uRESTDWConsts; Type TElementType = (etObject, etArray, etString, etNumeric, etBoolean); - TJSONBaseClass = class - end; + TJSONBaseClass = Class + End; - TJSONBaseObjectClass = class + TJSONBaseObjectClass = Class Private vJSONObject: TJSONBaseClass; Function GetObject: TJSONObject; @@ -65,7 +60,6 @@ TJSONBaseObjectClass = class End; TRESTDWJSONInterfaceBase = Class(TJSONBaseObjectClass) - Private Public Constructor Create(ParentJSON: TJSONBaseClass); Destructor Destroy; Override; @@ -86,7 +80,7 @@ TJSONBaseObjectClass = class Function GetObject(Index: Integer): TRESTDWJSONInterfaceBase; Function ToJSON: String; Constructor Create; - Destructor Destroy; Override; + Destructor Destroy; Override; End; TRESTDWJSONInterfaceObject = Class(TJSONBaseObjectClass) @@ -97,767 +91,688 @@ TJSONBaseObjectClass = class Procedure PutPairN(Index: String; Item: TRESTDWJSONPair); Overload; Public Constructor Create(JSONValue: String); Overload; - Destructor Destroy; Override; + Destructor Destroy; Override; Function PairCount: Integer; Function ToJSON: String; Function ClassType: TClass; - Function OpenArray(key: String): TRESTDWJSONInterfaceArray; Overload; + Function OpenArray(Key: String): TRESTDWJSONInterfaceArray; Overload; Function OpenArray(Index: Integer): TRESTDWJSONInterfaceArray; Overload; Property Pairs[Index: Integer]: TRESTDWJSONPair Read GetPair Write PutPair; - Property PairByName[Index: String]: TRESTDWJSONPair Read GetPairN - Write PutPairN; + Property PairByName[Index: String]: TRESTDWJSONPair Read GetPairN Write PutPairN; End; implementation -Function removestr(Astr: string; Asubstr: string): string; +Function EmptyPair: TRESTDWJSONPair; Begin - result := stringreplace(Astr, Asubstr, '', [rfReplaceAll, rfIgnoreCase]); + Result.isnull := True; + Result.ClassName := ''; + Result.Name := ''; + Result.Value := ''; End; -{$IFNDEF FPC} -Function GetElementJSON(bArray: TJSONObject; Value: String): String; +Function FirstJSONChar(Const Value: String): Char; Var I: Integer; - aJSONObject: TJSONObject; -Begin - result := ''; - For I := 0 To bArray.Count - 1 do - Begin - aJSONObject := TJSONObject.ParseJSONValue(bArray.Get(I).ToJSON) - as TJSONObject; - If Uppercase(Value) = Uppercase - (removestr(aJSONObject.Pairs[0].JsonString.Value, '"')) Then - Begin - result := aJSONObject.Pairs[0].JSONValue.ToJSON; - Break; - End; - FreeAndNil(aJSONObject); - End; +Begin + Result := #0; + For I := 1 To Length(Value) Do + Begin + If Value[I] > ' ' Then + Begin + Result := Value[I]; + Exit; + End; + End; +End; + +{$IFDEF RESTDWLEGACYJSON} + +Function LegacyValueToJSON(Value: TZAbstractObject): String; +Begin + Result := ''; + If Value = Nil Then + Exit; + Result := Value.toString; +End; + +Function LegacyValueIsNull(Value: TZAbstractObject): Boolean; +Begin + Result := (Value = Nil) Or (Value = CNULL) Or (Value is NULL); End; -{$ENDIF} -Function TRESTDWJSONInterfaceObject.OpenArray(key: String) : TRESTDWJSONInterfaceArray; +Function LegacyCloneValue(Value: TZAbstractObject): TJSONBaseClass; Var - {$IFNDEF FPC} - vEIndex: Integer; - aJSONObject: TJSONObject; - {$ENDIF} - cJSON : String; - aJSONArray : TJSONArray; + S: String; + C: Char; +Begin + Result := Nil; + If LegacyValueIsNull(Value) Then + Exit; + S := Value.toString; + C := FirstJSONChar(S); + If C = '{' Then + Result := TJSONBaseClass(TJSONObject.Create(S)) + Else If C = '[' Then + Result := TJSONBaseClass(TJSONArray.Create(S)) + Else If Value is _String Then + Result := TJSONBaseClass(_String(Value).Clone) + Else + Result := TJSONBaseClass(Value.Clone); +End; + +Function LegacyObjectNameAt(AObject: TJSONObject; Index: Integer): String; +Var + Names: TJSONArray; +Begin + Result := ''; + If (AObject = Nil) Or (Index < 0) Then + Exit; + Names := AObject.names; + Try + If (Names <> Nil) And (Index < Names.length) Then + Result := Names.Get(Index).toString; + Finally + Names.Free; + End; +End; + +Function LegacyPairFromValue(Const AName: String; + Value: TZAbstractObject): TRESTDWJSONPair; Begin - result := TRESTDWJSONInterfaceArray.Create; - {$IFNDEF FPC} - If TJSONObject(JSONObject).ClassName = 'TJSONObject' Then + Result := EmptyPair; + Result.Name := AName; + If LegacyValueIsNull(Value) Then Begin - aJSONObject := TJSONObject.ParseJSONValue(TJSONObject(JSONObject).ToJSON) as TJSONObject; - aJSONArray := TJSONObject.ParseJSONValue(TJSONObject(aJSONObject).Get(key).JSONValue.ToJSON) as TJSONArray; - result.vJSONObject := TJSONBaseClass(aJSONArray); - FreeAndNil(aJSONObject); - End + Result.ClassName := 'TJSONValue'; + Exit; + End; + Result.ClassName := Value.ClassName; + Result.Value := LegacyValueToJSON(Value); + Result.isnull := False; +End; + +{$ELSE} + +Function NativeValueIsNull(Value: TJSONValue): Boolean; +Begin + Result := (Value = Nil) Or (Value is TJSONNull); +End; + +Function NativeValueText(Value: TJSONValue): String; +Begin + Result := ''; + If Value = Nil Then + Exit; + If (Value is TJSONObject) Or (Value is TJSONArray) Then + Result := Value.ToJSON + Else If Value is TJSONNull Then + Result := '' Else + Result := Value.Value; +End; + +Function NativeCloneValue(Value: TJSONValue): TJSONBaseClass; +Var + Parsed: TJSONValue; +Begin + Result := Nil; + If NativeValueIsNull(Value) Then + Exit; + Parsed := TJSONObject.ParseJSONValue(Value.ToJSON); + If Parsed <> Nil Then + Result := TJSONBaseClass(Parsed); +End; + +Function NativePairFromValue(Const AName: String; + Value: TJSONValue): TRESTDWJSONPair; +Begin + Result := EmptyPair; + Result.Name := AName; + If NativeValueIsNull(Value) Then Begin - aJSONArray := TJSONObject.ParseJSONValue(GetElementJSON(TJSONObject(JSONObject), key)) as TJSONArray; - result.vJSONObject := TJSONBaseClass(aJSONArray); - // (Key).ToJSON) as TJSONArray); + Result.ClassName := 'TJSONValue'; + Exit; End; - {$ELSE} - If Assigned(result.vJSONObject) Then - FreeAndNil(result.vJSONObject); - cJSON := TJSONObject(vJSONObject).getString(key); - result.vJSONObject := TJSONBaseClass(TJSONArray.create(cJSON)); - {$ENDIF} + Result.ClassName := Value.ClassName; + Result.Value := NativeValueText(Value); + Result.isnull := False; End; -Function TRESTDWJSONInterfaceObject.OpenArray(Index: Integer) - : TRESTDWJSONInterfaceArray; -{$IFNDEF FPC} +{$ENDIF} + +Constructor TJSONBaseObjectClass.Create; +Begin + Inherited Create; + vJSONObject := Nil; +End; + +Destructor TJSONBaseObjectClass.Destroy; +Begin + If vJSONObject <> Nil Then + FreeAndNil(vJSONObject); + Inherited; +End; + +Function TJSONBaseObjectClass.GetObject: TJSONObject; +Begin + Result := TJSONObject(vJSONObject); +End; + +Procedure TJSONBaseObjectClass.SetObject(Value: TJSONObject); +Begin + If Pointer(vJSONObject) = Pointer(Value) Then + Exit; + If vJSONObject <> Nil Then + FreeAndNil(vJSONObject); + vJSONObject := TJSONBaseClass(Value); +End; + +Constructor TJSONBaseArrayClass.Create; +Begin + Inherited Create; + vJSONObject := Nil; +End; + +Destructor TJSONBaseArrayClass.Destroy; +Begin + If vJSONObject <> Nil Then + FreeAndNil(vJSONObject); + Inherited; +End; + +Function TJSONBaseArrayClass.GetObject: TJSONArray; +Begin + Result := TJSONArray(vJSONObject); +End; + +Procedure TJSONBaseArrayClass.SetObject(Value: TJSONArray); +Begin + If Pointer(vJSONObject) = Pointer(Value) Then + Exit; + If vJSONObject <> Nil Then + FreeAndNil(vJSONObject); + vJSONObject := TJSONBaseClass(Value); +End; + +Constructor TRESTDWJSONInterfaceBase.Create(ParentJSON: TJSONBaseClass); +Begin + Inherited Create; + vJSONObject := ParentJSON; +End; + +Destructor TRESTDWJSONInterfaceBase.Destroy; +Begin + Inherited; +End; + +Function TRESTDWJSONInterfaceBase.PairCount: Integer; +{$IFDEF RESTDWLEGACYJSON} Var - vEIndex: Integer; - aJSONObject: TJSONObject; - aJSONArray: TJSONArray; - {$ENDIF} + Names: TJSONArray; +{$ENDIF} Begin - result := TRESTDWJSONInterfaceArray.Create; - If Assigned(vJSONObject) Then - FreeAndNil(vJSONObject); - {$IFNDEF FPC} - If TJSONObject(JSONObject).ClassName = 'TJSONObject' Then - Begin - aJSONObject := TJSONObject.ParseJSONValue(TJSONObject(JSONObject).ToJSON) - as TJSONObject; - aJSONArray := TJSONObject.ParseJSONValue(TJSONObject(aJSONObject) - .Pairs[Index].JSONValue.ToJSON) as TJSONArray; - result.vJSONObject := TJSONBaseClass(aJSONArray); - FreeAndNil(aJSONObject); - End + Result := 0; + If vJSONObject = Nil Then + Exit; +{$IFDEF RESTDWLEGACYJSON} + If TObject(vJSONObject) is TJSONObject Then + Begin + Names := TJSONObject(vJSONObject).names; + Try + If Names <> Nil Then + Result := Names.length; + Finally + Names.Free; + End; + End + Else If TObject(vJSONObject) is TJSONArray Then + Result := TJSONArray(vJSONObject).length Else - Begin - aJSONArray := TJSONObject.ParseJSONValue(TJSONObject(aJSONObject) - .Pairs[Index].JSONValue.ToJSON) as TJSONArray; - result.vJSONObject := TJSONBaseClass(aJSONArray); - // (Key).ToJSON) as TJSONArray); - End; - {$ELSE} - If TJSONObject(JSONObject).ClassName = 'TJSONObject' Then - result.vJSONObject := TJSONBaseClass(TJSONObject(vJSONObject) - .opt(TJSONObject(vJSONObject).names.Get(Index).toString)) - Else If TJSONObject(JSONObject).ClassName = 'TJSONArray' Then - result.vJSONObject := TJSONBaseClass(TJSONArray(vJSONObject).Get(Index)); - {$ENDIF} + Result := 1; +{$ELSE} + If TObject(vJSONObject) is TJSONObject Then + Result := TJSONObject(vJSONObject).Count + Else If TObject(vJSONObject) is TJSONArray Then + Result := TJSONArray(vJSONObject).Size + Else + Result := 1; +{$ENDIF} End; Constructor TRESTDWJSONInterfaceArray.Create; Begin - Inherited Create; - vJSONObject := Nil; + Inherited Create; End; Destructor TRESTDWJSONInterfaceArray.Destroy; Begin - If Assigned(vJSONObject) Then - FreeAndNil(vJSONObject); - inherited; + Inherited; End; Function TRESTDWJSONInterfaceArray.ElementCount: Integer; Begin - result := 0; - If vJSONObject = Nil then + Result := 0; + If vJSONObject = Nil Then Exit; - {$IFNDEF FPC} - result := TJSONArray(vJSONObject).Size; - {$ELSE} - If TJSONObject(vJSONObject).ClassName = 'TJSONObject' Then - Begin - If TJSONObject(vJSONObject).names <> Nil Then - result := TJSONObject(vJSONObject).names.length; - End - Else If TJSONObject(vJSONObject).ClassName = 'TJSONArray' Then - result := TJSONArray(vJSONObject).length; - {$ENDIF} +{$IFDEF RESTDWLEGACYJSON} + If TObject(vJSONObject) is TJSONArray Then + Result := TJSONArray(vJSONObject).length + Else If TObject(vJSONObject) is TJSONObject Then + Result := TJSONObject(vJSONObject).length; +{$ELSE} + If TObject(vJSONObject) is TJSONArray Then + Result := TJSONArray(vJSONObject).Size + Else If TObject(vJSONObject) is TJSONObject Then + Result := TJSONObject(vJSONObject).Count; +{$ENDIF} End; -Function TRESTDWJSONInterfaceArray.GetObject(Index: Integer) - : TRESTDWJSONInterfaceBase; +Function TRESTDWJSONInterfaceArray.GetObject(Index: Integer): TRESTDWJSONInterfaceBase; +{$IFDEF RESTDWLEGACYJSON} Var - {$IFNDEF FPC} - aJSONObject : TJSONArray; - aJSONValue : TJSONValue; - {$ELSE} - cNames : TJSONArray; - {$ENDIF} - vJsonString, - vClassName : String; + Value: TZAbstractObject; + Name: String; +{$ELSE} +Var + Value: TJSONValue; +{$ENDIF} Begin - result := TRESTDWJSONInterfaceBase.Create(Nil); - vClassName := TJSONObject(vJSONObject).ClassName; - If (Uppercase(TJSONObject(vJSONObject).ClassName) = Uppercase('TJSONArray')) Then + Result := TRESTDWJSONInterfaceBase.Create(Nil); + If (vJSONObject = Nil) Or (Index < 0) Then + Exit; +{$IFDEF RESTDWLEGACYJSON} + If TObject(vJSONObject) is TJSONArray Then Begin - {$IFNDEF FPC} - aJSONValue := TJSONObject.ParseJSONValue(TJSONObject(JSONObject).Get(Index).ToJSON); - If aJSONValue is TJSONObject Then - result.vJSONObject := TJSONBaseClass(aJSONValue as TJSONObject) - Else - result.vJSONObject := TJSONBaseClass(aJSONValue); - {$ELSE} - If TJSONArray(vJSONObject).isnull(Index) Then - result.vJSONObject := Nil - Else - Begin - If TJSONArray(vJSONObject).optJSONArray(Index) = Nil Then - Begin - vJsonString := TJSONArray(vJSONObject).optString(Index); - If vJsonString <> '' Then - Begin - If vJsonString[InitStrPos] = '[' Then - result.vJSONObject := TJSONBaseClass(TJSONArray.create(vJsonString)) - Else If vJsonString[InitStrPos] = '{' Then - result.vJSONObject := TJSONBaseClass(TJSONObject.create(vJsonString)) - Else - result.vJSONObject := TJSONBaseClass(TJSONObject.create(Format('{"%d"="%s"}', [Index, vJsonString]))); - End - Else - result.vJSONObject := Nil; - End - Else - result.vJSONObject := TJSONBaseClass(TJSONArray.create(TJSONArray(vJSONObject).optJSONArray(Index).toString)); - End; - {$ENDIF} + If Index >= TJSONArray(vJSONObject).length Then + Exit; + Value := TJSONArray(vJSONObject).opt(Index); + Result.vJSONObject := LegacyCloneValue(Value); End - Else If (Uppercase(TJSONObject(vJSONObject).ClassName) - = Uppercase('TJSONObject')) Then + Else If TObject(vJSONObject) is TJSONObject Then Begin - {$IFNDEF FPC} - result.vJSONObject := TJSONBaseClass - (TJSONObject.ParseJSONValue(TJSONObject(vJSONObject).Get(Index) - .JSONValue.ToJSON) as TJSONArray); - {$ELSE} - cNames := TJSONObject(vJSONObject).names; - vJsonString := TJSONObject(vJSONObject).opt(cNames.Get(Index).toString).toString; - If vJsonString[InitStrPos] = '[' Then - result.vJSONObject := TJSONBaseClass(TJSONArray.create(vJsonString)) - Else If vJsonString[InitStrPos] = '{' Then - result.vJSONObject := TJSONBaseClass(TJSONObject.create(vJsonString)) - Else - result.vJSONObject := Nil; - If Assigned(cNames) Then - FreeAndNil(cNames); - {$ENDIF} + If Index >= TJSONObject(vJSONObject).length Then + Exit; + Name := LegacyObjectNameAt(TJSONObject(vJSONObject), Index); + If Name = '' Then + Exit; + Value := TJSONObject(vJSONObject).opt(Name); + Result.vJSONObject := LegacyCloneValue(Value); + End; +{$ELSE} + If TObject(vJSONObject) is TJSONArray Then + Begin + If Index >= TJSONArray(vJSONObject).Size Then + Exit; + Value := TJSONArray(vJSONObject).Get(Index); + Result.vJSONObject := NativeCloneValue(Value); End - Else - result.vJSONObject := TJSONBaseClass(TJSONObject(vJSONObject)); + Else If TObject(vJSONObject) is TJSONObject Then + Begin + If Index >= TJSONObject(vJSONObject).Count Then + Exit; + Value := TJSONObject(vJSONObject).Pairs[Index].JSONValue; + Result.vJSONObject := NativeCloneValue(Value); + End; +{$ENDIF} End; Function TRESTDWJSONInterfaceArray.ToJSON: String; Begin - result := TJSONObject(Self).toString; + Result := ''; + If vJSONObject = Nil Then + Exit; +{$IFDEF RESTDWLEGACYJSON} + Result := TZAbstractObject(vJSONObject).toString; +{$ELSE} + Result := TJSONValue(vJSONObject).ToJSON; +{$ENDIF} End; Constructor TRESTDWJSONInterfaceObject.Create(JSONValue: String); +{$IFNDEF RESTDWLEGACYJSON} +Var + Parsed: TJSONValue; +{$ENDIF} Begin Inherited Create; - If JSONValue <> '' Then - Begin - If Assigned(vJSONObject) Then - FreeAndNil(vJSONObject); - {$IFNDEF FPC} - If JSONValue[InitStrPos] = '[' then - vJSONObject := TJSONBaseClass(TJSONObject.ParseJSONValue(JSONValue) as TJSONArray) - Else If JSONValue[InitStrPos] = '{' then - vJSONObject := TJSONBaseClass(TJSONObject.ParseJSONValue(JSONValue) as TJSONObject) - Else - vJSONObject := TJSONBaseClass(TJSONObject.ParseJSONValue('{}') as TJSONObject) - {$ELSE} - If JSONValue[InitStrPos] = '[' then - vJSONObject := TJSONBaseClass(TJSONArray.Create(JSONValue)) - Else If JSONValue[InitStrPos] = '{' then - vJSONObject := TJSONBaseClass(TJSONObject.Create(JSONValue)) - Else - vJSONObject := TJSONBaseClass(TJSONObject.Create('{}')) - {$ENDIF} - End; + If Trim(JSONValue) = '' Then + Exit; +{$IFDEF RESTDWLEGACYJSON} + If FirstJSONChar(JSONValue) = '[' Then + vJSONObject := TJSONBaseClass(TJSONArray.Create(JSONValue)) + Else If FirstJSONChar(JSONValue) = '{' Then + vJSONObject := TJSONBaseClass(TJSONObject.Create(JSONValue)) + Else + vJSONObject := TJSONBaseClass(TJSONObject.Create('{}')); +{$ELSE} + Parsed := TJSONObject.ParseJSONValue(JSONValue); + If Parsed <> Nil Then + vJSONObject := TJSONBaseClass(Parsed) + Else + vJSONObject := TJSONBaseClass(TJSONObject.ParseJSONValue('{}')); +{$ENDIF} End; Destructor TRESTDWJSONInterfaceObject.Destroy; Begin - If Assigned(vJSONObject) Then - FreeAndNil(vJSONObject); - Inherited; + Inherited; End; -Function TRESTDWJSONInterfaceObject.GetPairN(Index: String): TRESTDWJSONPair; -Var - I: Integer; - vElementName, vClassName: String; - {$IFNDEF FPC} - aJSONObject: TJSONObject; - vValueJSON: String; - {$ELSE} - cNames : TJSONArray; - {$ENDIF} +Function TRESTDWJSONInterfaceObject.PairCount: Integer; Begin - result.isnull := False; - result.Value := 'null'; + Result := 0; If vJSONObject = Nil Then - Begin - result.isnull := True; Exit; - End; - vClassName := TJSONObject(vJSONObject).ClassName; - {$IFNDEF FPC} - If (Uppercase(vClassName) = Uppercase('TRESTDWJSONInterfaceObject')) Or - (Uppercase(vClassName) = Uppercase('TJSONObject')) Or - (Uppercase(vClassName) = Uppercase('TRESTDWJSONInterfaceBase')) Then - Begin - If vClassName <> '_String' Then - Begin - For I := 0 To TJSONObject(vJSONObject).Count - 1 Do - Begin - result.Name := removestr(TJSONObject(vJSONObject) - .Pairs[I].JsonString.Value, '"'); - If LowerCase(result.Name) <> LowerCase(Index) Then - Begin - result.Name := ''; - Continue; - End; - If TJSONObject(vJSONObject).Pairs[I].JSONValue is TJSONObject Then - Begin - result.ClassName := 'TJSONObject'; - vValueJSON := TJSONObject(vJSONObject).Pairs[I].JSONValue.toString; - If (vValueJSON = '') Or (Trim(vValueJSON) = '""') then - result.Value := TJSONObject(vJSONObject).Pairs[I].JSONValue.Value - Else - result.Value := vValueJSON; - End - Else - Begin - result.ClassName := TJSONObject(vJSONObject).Pairs[I] - .JSONValue.ClassName; - vValueJSON := TJSONObject(vJSONObject).Pairs[I].JSONValue.Value; - If (vValueJSON = '') Or (Trim(vValueJSON) = '""') then - result.Value := TJSONObject(vJSONObject).Pairs[I].JSONValue.toString - Else - result.Value := vValueJSON; - End; - Break; - End; - End; - End - Else If Uppercase(vClassName) = Uppercase('TJSONArray') Then - Begin - For I := 0 To TJSONObject(vJSONObject).Count - 1 Do - Begin - aJSONObject := TJSONObject.ParseJSONValue(TJSONObject(vJSONObject).Get(I) - .ToJSON) as TJSONObject; - result.Name := removestr(aJSONObject.Value, '"'); - If LowerCase(result.Name) <> LowerCase(Index) Then - Begin - FreeAndNil(aJSONObject); - result.Name := ''; - Continue; - End; - If (aJSONObject.toString = '') Or (Trim(aJSONObject.toString) = '""') then - result.Value := '' - Else - result.Value := aJSONObject.toString; - result.ClassName := 'TJSONArray'; - FreeAndNil(aJSONObject); - Break; - End; - End; - {$ELSE} - If (Uppercase(vClassName) = Uppercase('TRESTDWJSONInterfaceObject')) Or - (Uppercase(vClassName) = Uppercase('TJSONObject')) Or - (Uppercase(vClassName) = Uppercase('TRESTDWJSONInterfaceBase')) Then - Begin - If vClassName <> '_String' Then - Begin - cNames := TJSONObject(vJSONObject).names; - For I := 0 To cNames.length - 1 Do - Begin - If LowerCase(cNames.Get(I).toString) <> - LowerCase(Index) Then - Continue; - result.Name := cNames.Get(I).toString; - result.Value := TJSONObject(vJSONObject).Get(result.Name).toString; - result.ClassName := TJSONObject(vJSONObject).Get(result.Name).ClassName; - Break; - End; - If Assigned(cNames) Then - FreeAndNil(cNames); - End; - End - Else If Uppercase(vClassName) = Uppercase('TJSONArray') Then - Begin - For I := 0 To TJSONArray(vJSONObject).length - 1 Do - Begin - If LowerCase(TJSONArray(vJSONObject).Get(I).ClassName) <> - LowerCase('_String') Then - Begin - vClassName := TJSONArray(vJSONObject).optJSONObject(I).ClassName; - result.ClassName := 'TJSONArray'; - cNames := TJSONArray(vJSONObject).optJSONObject(I).names; - If ((cNames.length > 0) - And (Uppercase(vClassName) = Uppercase('TJSONArray'))) Then - Begin - If (TJSONObject(TJSONArray(vJSONObject).optJSONObject(I)) - .names.length > I) Then - Begin - If LowerCase(TJSONObject(TJSONArray(vJSONObject).optJSONObject(I)) - .names.Get(0).toString) <> LowerCase(Index) Then - Begin - result.ClassName := ''; - Continue; - End; - result.Name := TJSONObject(TJSONArray(vJSONObject).optJSONObject(I)) - .names.Get(0).toString; - result.Value := TJSONObject(TJSONArray(vJSONObject).optJSONObject(I) - ).Get(result.Name).toString; - Break; - End; - End - Else - Begin - result.Name := TJSONArray(vJSONObject).Get(I).toString; - If LowerCase(result.Name) <> LowerCase(Index) Then - Begin - result.Name := ''; - Continue; - End; - If (Trim(result.Name) = '') Or - ((Pos('{', result.Name) > 0) Or (Pos('[', result.Name) > 0)) Then - result.Name := 'arrayobj' + IntToStr(I); - result.Value := TJSONArray(vJSONObject).opt(I).toString; - Break; - End; - if Assigned(cNames) then - FreeAndNil(cNames) - End; - End; - End; - {$ENDIF} - If Trim(result.ClassName) = '' Then - result.ClassName := vClassName; - // Correção para null value - result.isnull := (result.Value = 'null'); // or (Result.Value = ''); - If result.isnull Then - result.Value := ''; +{$IFDEF RESTDWLEGACYJSON} + If TObject(vJSONObject) is TJSONObject Then + Result := TJSONObject(vJSONObject).length + Else If TObject(vJSONObject) is TJSONArray Then + Result := TJSONArray(vJSONObject).length + Else + Result := 1; +{$ELSE} + If TObject(vJSONObject) is TJSONObject Then + Result := TJSONObject(vJSONObject).Count + Else If TObject(vJSONObject) is TJSONArray Then + Result := TJSONArray(vJSONObject).Size + Else + Result := 1; +{$ENDIF} End; Function TRESTDWJSONInterfaceObject.GetPair(Index: Integer): TRESTDWJSONPair; +{$IFDEF RESTDWLEGACYJSON} Var - vElementName, vClassName: String; - {$IFNDEF FPC} - aJSONObject: TJSONObject; - vValueJSON: String; - {$ELSE} - cNames : TJSONArray; - {$ENDIF} + Name: String; + Value: TZAbstractObject; +{$ELSE} +Var + Value: TJSONValue; +{$ENDIF} Begin - result.isnull := False; - result.Value := 'null'; - If vJSONObject = Nil Then - Begin - result.isnull := True; - Exit; - End; - vClassName := TJSONObject(vJSONObject).ClassName; - {$IFNDEF FPC} - If (Uppercase(vClassName) = Uppercase('TRESTDWJSONInterfaceObject')) Or - (Uppercase(vClassName) = Uppercase('TJSONObject')) Or - (Uppercase(vClassName) = Uppercase('TRESTDWJSONInterfaceBase')) Then + Result := EmptyPair; + If (vJSONObject = Nil) Or (Index < 0) Then + Exit; +{$IFDEF RESTDWLEGACYJSON} + If TObject(vJSONObject) is TJSONObject Then Begin - If vClassName <> '_String' Then - Begin - If (TJSONObject(vJSONObject).Count > index) Then - Begin - result.Name := removestr(TJSONObject(vJSONObject).Pairs[index].JsonString.Value, '"'); - If TJSONObject(vJSONObject).Pairs[index].JSONValue is TJSONObject Then - Begin - result.ClassName := 'TJSONObject'; - vValueJSON := TJSONObject(vJSONObject).Pairs[index] - .JSONValue.toString; - // removestr(TJSONObject(vJSONObject).Pairs[index].JsonValue.tostring, '"'); - If (vValueJSON = '') Or (Trim(vValueJSON) = '""') then - result.Value := TJSONObject(vJSONObject).Pairs[index].JSONValue.Value - else - result.Value := vValueJSON; - End - Else - Begin - result.ClassName := TJSONObject(vJSONObject).Pairs[index] - .JSONValue.ClassName; - vValueJSON := TJSONObject(vJSONObject).Pairs[index].JSONValue.Value; - If (vValueJSON = '') Or (Trim(vValueJSON) = '""') then - result.Value := TJSONObject(vJSONObject).Pairs[index] - .JSONValue.toString - else - result.Value := vValueJSON; - End; - End; - End - Else - Begin - result.Value := TJSONObject(vJSONObject).Pairs[index].JSONValue.Value; - // removestr(TJSONObject(vJSONObject).Pairs[index].JsonValue.tostring, '"'); - result.ClassName := TJSONObject(vJSONObject).Pairs[index].JSONValue.ClassName; - End; + If Index >= TJSONObject(vJSONObject).length Then + Exit; + Name := LegacyObjectNameAt(TJSONObject(vJSONObject), Index); + If Name = '' Then + Exit; + Value := TJSONObject(vJSONObject).opt(Name); + Result := LegacyPairFromValue(Name, Value); End - Else If Uppercase(vClassName) = Uppercase('TJSONArray') Then + Else If TObject(vJSONObject) is TJSONArray Then Begin - vClassName := TJSONObject(vJSONObject).Get(index).classname; - If Uppercase(vClassName) = Uppercase('TJSONArray') Then - Begin - aJSONObject := TJSONObject.ParseJSONValue(TJSONObject(vJSONObject).Get(index).ToJSON) as TJSONObject; - result.Name := removestr(aJSONObject.Value, '"'); - If (aJSONObject.toString = '') Or (Trim(aJSONObject.toString) = '""') then - result.Value := '' - Else - result.Value := aJSONObject.toString; - result.ClassName := 'TJSONArray'; - FreeAndNil(aJSONObject); - End - Else - Begin - result.Name := ''; - vValueJSON := TJSONObject(vJSONObject).Get(index).tostring; - result.Value := removestr(vValueJSON, '""'); - If vClassName = 'NULL' Then - result.ClassName := 'TJSONValue' - Else - result.ClassName := vClassName; - End; + If Index >= TJSONArray(vJSONObject).length Then + Exit; + Value := TJSONArray(vJSONObject).opt(Index); + Result := LegacyPairFromValue('arrayobj' + IntToStr(Index), Value); End Else + Result := LegacyPairFromValue('', TZAbstractObject(vJSONObject)); +{$ELSE} + If TObject(vJSONObject) is TJSONObject Then Begin - result.Name := ''; - result.Value := TJSONValue(vJSONObject).Value; - If (result.Value = '') Or (Trim(result.Value) = '""') then - result.Value := removestr(TJSONObject(vJSONObject).ToJSON, '"'); - If vClassName = 'NULL' Then - result.ClassName := 'TJSONValue' - Else - result.ClassName := vClassName; - End; - {$ELSE} - If (Uppercase(vClassName) = Uppercase('TRESTDWJSONInterfaceObject')) Or - (Uppercase(vClassName) = Uppercase('TJSONObject')) Or - (Uppercase(vClassName) = Uppercase('TRESTDWJSONInterfaceBase')) Then - Begin - If vClassName <> '_String' Then - Begin - cNames := TJSONObject(vJSONObject).names; - If cNames.length > 0 Then - Begin - If (cNames.length > index) Then - Begin - result.Name := cNames.Get(index).toString; - Try - IF (TJSONObject(vJSONObject).Get(result.Name) <> Nil) And - (TJSONObject(vJSONObject).Get(result.Name) <> CNULL) Then - result.Value := TJSONObject(vJSONObject).Get(result.Name).toString; - Except - result.Value := ''; - End; - result.ClassName := cNames.Get(index).ClassName; - End; - End - Else - Begin - result.Value := TJSONObject(vJSONObject).toString; - result.ClassName := TJSONObject(vJSONObject).ClassName; - End; - If cNames <> Nil Then - FreeAndNil(cNames); - End - Else - Begin - result.Value := TJSONObject(vJSONObject).toString; - result.ClassName := TJSONObject(vJSONObject).ClassName; - End; - End - Else If Uppercase(vClassName) = Uppercase('TJSONArray') Then - Begin - If LowerCase(TJSONArray(vJSONObject).Get(index).ClassName) = LowerCase('_String') Then - Begin - result.ClassName := '_String'; - result.Name := 'arrayobj' + IntToStr(Index); - result.Value := TJSONArray(vJSONObject).Get(index).toString; - End - Else If LowerCase(TJSONArray(vJSONObject).Get(index).ClassName) = LowerCase('_Integer') Then - Begin - result.ClassName := '_Integer'; - result.Name := 'arrayobj' + IntToStr(Index); - result.Value := TJSONArray(vJSONObject).Get(index).toString; - End - Else If LowerCase(TJSONArray(vJSONObject).Get(index).ClassName) = LowerCase('_Double') Then - Begin - result.ClassName := '_Double'; - result.Name := 'arrayobj' + IntToStr(Index); - result.Value := TJSONArray(vJSONObject).Get(index).toString; - End - Else - Begin - If Not Assigned(TJSONArray(vJSONObject).optJSONObject(index)) Then - Begin - vClassName := TJSONArray(vJSONObject).get(index).ClassName; - If vClassName = 'NULL' Then - result.ClassName := 'tjsonstring'; - result.Name := TJSONArray(vJSONObject).Get(index).toString; - If (Trim(result.Name) = '') Or (UpperCase(Trim(result.Name)) = 'NULL') Or - ((Pos('{', result.Name) > 0) Or (Pos('[', result.Name) > 0)) Then - result.Name := 'arrayobj' + IntToStr(Index); - result.Value := TJSONArray(vJSONObject).opt(Index).toString; - End - Else - Begin - vClassName := TJSONArray(vJSONObject).optJSONObject(index).ClassName; - result.ClassName := 'TJSONArray'; - cNames := TJSONObject(TJSONArray(vJSONObject).optJSONObject(index)).names; - If (cNames.length > 0) And (Uppercase(vClassName) = Uppercase('TJSONArray')) Then - Begin - If (cNames.length > index) Then - Begin - result.Name := cNames.Get(index).toString; - result.Value := TJSONObject(TJSONArray(vJSONObject).optJSONObject(index)).Get(result.Name).toString; - End; - End - Else - Begin - result.Name := TJSONArray(vJSONObject).Get(index).toString; - If (Trim(result.Name) = '') Or - ((Pos('{', result.Name) > 0) Or (Pos('[', result.Name) > 0)) Then - result.Name := 'arrayobj' + IntToStr(Index); - result.Value := TJSONArray(vJSONObject).opt(Index).toString; - End; - If Assigned(cNames) Then - FreeAndNil(cNames); - End; - End; - End + If Index >= TJSONObject(vJSONObject).Count Then + Exit; + Value := TJSONObject(vJSONObject).Pairs[Index].JSONValue; + Result := NativePairFromValue(TJSONObject(vJSONObject).Pairs[Index].JsonString.Value, Value); + End + Else If TObject(vJSONObject) is TJSONArray Then + Begin + If Index >= TJSONArray(vJSONObject).Size Then + Exit; + Value := TJSONArray(vJSONObject).Get(Index); + Result := NativePairFromValue('arrayobj' + IntToStr(Index), Value); + End Else - Begin - result.Value := TJSONObject(vJSONObject).toString; - result.ClassName := TJSONObject(vJSONObject).ClassName; - End; - {$ENDIF} - If Trim(result.ClassName) = '' Then - result.ClassName := vClassName; - // Correção para null value - result.isnull := ((result.Value = 'null') or (Result.Value = '')); - If result.isnull Then - result.Value := ''; + Result := NativePairFromValue('', TJSONValue(vJSONObject)); +{$ENDIF} End; -Function TRESTDWJSONInterfaceObject.PairCount: Integer; -{$IFNDEF RESTDWFMX} +Function TRESTDWJSONInterfaceObject.GetPairN(Index: String): TRESTDWJSONPair; +{$IFDEF RESTDWLEGACYJSON} +Var + I: Integer; + Name: String; + Value: TZAbstractObject; +{$ELSE} Var - cNames : TJSONArray; + I: Integer; {$ENDIF} Begin - result := 0; - If vJSONObject = Nil Then + Result := EmptyPair; + If (vJSONObject = Nil) Or (Trim(Index) = '') Then Exit; - {$IFNDEF FPC} - If vJSONObject <> Nil Then - result := TJSONObject(vJSONObject).Count; - {$ELSE} - If TJSONObject(vJSONObject).ClassName = 'TJSONObject' Then +{$IFDEF RESTDWLEGACYJSON} + If TObject(vJSONObject) is TJSONObject Then Begin - cNames := TJSONObject(vJSONObject).names; - If cNames <> Nil Then + For I := 0 To TJSONObject(vJSONObject).length - 1 Do Begin - result := cNames.length; - FreeAndNil(cNames); + Name := LegacyObjectNameAt(TJSONObject(vJSONObject), I); + If SameText(Name, Index) Then + Begin + Value := TJSONObject(vJSONObject).opt(Name); + Result := LegacyPairFromValue(Name, Value); + Exit; + End; End; End - Else - result := TJSONArray(vJSONObject).length; - {$ENDIF} -End; - -Procedure TRESTDWJSONInterfaceObject.PutPairN(Index: String; - Item: TRESTDWJSONPair); -Begin - + Else If TObject(vJSONObject) is TJSONArray Then + Begin + For I := 0 To TJSONArray(vJSONObject).length - 1 Do + Begin + Value := TJSONArray(vJSONObject).opt(I); + If Value is TJSONObject Then + Begin + Name := LegacyObjectNameAt(TJSONObject(Value), 0); + If SameText(Name, Index) Then + Begin + Result := LegacyPairFromValue(Name, TJSONObject(Value).opt(Name)); + Exit; + End; + End; + End; + End; +{$ELSE} + If TObject(vJSONObject) is TJSONObject Then + Begin + For I := 0 To TJSONObject(vJSONObject).Count - 1 Do + Begin + If SameText(TJSONObject(vJSONObject).Pairs[I].JsonString.Value, Index) Then + Begin + Result := NativePairFromValue( + TJSONObject(vJSONObject).Pairs[I].JsonString.Value, + TJSONObject(vJSONObject).Pairs[I].JSONValue); + Exit; + End; + End; + End + Else If TObject(vJSONObject) is TJSONArray Then + Begin + For I := 0 To TJSONArray(vJSONObject).Size - 1 Do + Begin + If TJSONArray(vJSONObject).Get(I) is TJSONObject Then + Begin + If TJSONObject(TJSONArray(vJSONObject).Get(I)).Count > 0 Then + Begin + If SameText(TJSONObject(TJSONArray(vJSONObject).Get(I)).Pairs[0].JsonString.Value, Index) Then + Begin + Result := NativePairFromValue( + TJSONObject(TJSONArray(vJSONObject).Get(I)).Pairs[0].JsonString.Value, + TJSONObject(TJSONArray(vJSONObject).Get(I)).Pairs[0].JSONValue); + Exit; + End; + End; + End; + End; + End; +{$ENDIF} End; -Procedure TRESTDWJSONInterfaceObject.PutPair(Index: Integer; - Item: TRESTDWJSONPair); +Procedure TRESTDWJSONInterfaceObject.PutPair(Index: Integer; Item: TRESTDWJSONPair); +Var + Current: TRESTDWJSONPair; Begin - + Current := GetPair(Index); + If Current.Name <> '' Then + PutPairN(Current.Name, Item); End; -Function TRESTDWJSONInterfaceObject.ClassType: TClass; +Procedure TRESTDWJSONInterfaceObject.PutPairN(Index: String; Item: TRESTDWJSONPair); +{$IFDEF RESTDWLEGACYJSON} +Var + OldValue: TZAbstractObject; +{$ELSE} +Var + OldPair: TJSONPair; + NewValue: TJSONValue; +{$ENDIF} Begin - If TJSONObject(vJSONObject).ClassType = TJSONObject Then - result := TRESTDWJSONInterfaceObject - Else If TJSONObject(vJSONObject).ClassType = TJSONArray Then - result := TRESTDWJSONInterfaceArray - Else If TJSONObject(vJSONObject).ClassType = TRESTDWJSONInterfaceBase Then - result := TRESTDWJSONInterfaceBase + If (vJSONObject = Nil) Or (Trim(Index) = '') Then + Exit; + If Not (TObject(vJSONObject) is TJSONObject) Then + Exit; +{$IFDEF RESTDWLEGACYJSON} + OldValue := TJSONObject(vJSONObject).remove(Index); + If (OldValue <> Nil) And (OldValue <> CNULL) Then + OldValue.Free; + If Item.isnull Then + TJSONObject(vJSONObject).put(Index, CNULL) + Else + TJSONObject(vJSONObject).put(Index, Item.Value); +{$ELSE} + OldPair := TJSONObject(vJSONObject).RemovePair(Index); + OldPair.Free; + If Item.isnull Then + NewValue := TJSONNull.Create Else - result := TJSONObject(vJSONObject).ClassType; + NewValue := TJSONString.Create(Item.Value); + TJSONObject(vJSONObject).AddPair(Index, NewValue); +{$ENDIF} End; -Function TRESTDWJSONInterfaceObject.ToJSON: String; +Function TRESTDWJSONInterfaceObject.OpenArray(Key: String): TRESTDWJSONInterfaceArray; +{$IFDEF RESTDWLEGACYJSON} +Var + Value: TZAbstractObject; +{$ELSE} +Var + Value: TJSONValue; +{$ENDIF} Begin - result := TJSONObject(vJSONObject).toString; + Result := TRESTDWJSONInterfaceArray.Create; + If (vJSONObject = Nil) Or (Trim(Key) = '') Then + Exit; + If Not (TObject(vJSONObject) is TJSONObject) Then + Exit; +{$IFDEF RESTDWLEGACYJSON} + Value := TJSONObject(vJSONObject).opt(Key); + If Value is TJSONArray Then + Result.vJSONObject := LegacyCloneValue(Value); +{$ELSE} + Value := TJSONObject(vJSONObject).GetValue(Key); + If Value is TJSONArray Then + Result.vJSONObject := NativeCloneValue(Value); +{$ENDIF} End; -{ TRESTDWJSONValueInterface } - -Function TRESTDWJSONValueInterface.GetPair(Index: Integer): TRESTDWJSONPair; +Function TRESTDWJSONInterfaceObject.OpenArray(Index: Integer): TRESTDWJSONInterfaceArray; +{$IFDEF RESTDWLEGACYJSON} +Var + Name: String; + Value: TZAbstractObject; +{$ELSE} +Var + Value: TJSONValue; +{$ENDIF} Begin - result.Name := TJSONObject(Self).toString; - result.Value := TJSONObject(Self).toString; - result.ClassName := TJSONObject(Self).ClassName; + Result := TRESTDWJSONInterfaceArray.Create; + If (vJSONObject = Nil) Or (Index < 0) Then + Exit; +{$IFDEF RESTDWLEGACYJSON} + If TObject(vJSONObject) is TJSONObject Then + Begin + If Index >= TJSONObject(vJSONObject).length Then + Exit; + Name := LegacyObjectNameAt(TJSONObject(vJSONObject), Index); + If Name = '' Then + Exit; + Value := TJSONObject(vJSONObject).opt(Name); + End + Else If TObject(vJSONObject) is TJSONArray Then + Begin + If Index >= TJSONArray(vJSONObject).length Then + Exit; + Value := TJSONArray(vJSONObject).opt(Index); + End + Else + Exit; + If Value is TJSONArray Then + Result.vJSONObject := LegacyCloneValue(Value); +{$ELSE} + If TObject(vJSONObject) is TJSONObject Then + Begin + If Index >= TJSONObject(vJSONObject).Count Then + Exit; + Value := TJSONObject(vJSONObject).Pairs[Index].JSONValue; + End + Else If TObject(vJSONObject) is TJSONArray Then + Begin + If Index >= TJSONArray(vJSONObject).Size Then + Exit; + Value := TJSONArray(vJSONObject).Get(Index); + End + Else + Exit; + If Value is TJSONArray Then + Result.vJSONObject := NativeCloneValue(Value); +{$ENDIF} End; -procedure TRESTDWJSONValueInterface.PutPair(Index: Integer; Value: TRESTDWJSONPair); -begin - -end; - -constructor TJSONBaseArrayClass.Create; -begin - If Assigned(vJSONObject) Then - FreeAndNil(vJSONObject); - inherited; -end; - -destructor TJSONBaseArrayClass.Destroy; -begin - If Assigned(vJSONObject) Then - FreeAndNil(vJSONObject); - inherited; -end; - -Function TJSONBaseArrayClass.GetObject: TJSONArray; +Function TRESTDWJSONInterfaceObject.ClassType: TClass; Begin - result := TJSONArray(vJSONObject); + Result := TRESTDWJSONInterfaceBase; + If vJSONObject = Nil Then + Exit; + If TObject(vJSONObject) is TJSONObject Then + Result := TRESTDWJSONInterfaceObject + Else If TObject(vJSONObject) is TJSONArray Then + Result := TRESTDWJSONInterfaceArray + Else + Result := TObject(vJSONObject).ClassType; End; -procedure TJSONBaseArrayClass.SetObject(Value: TJSONArray); -begin - If Assigned(Value) then - vJSONObject := TJSONBaseClass(Value); -end; - -{ TJSONBaseObjectClass } - -constructor TJSONBaseObjectClass.Create; -begin - Inherited Create; - vJSONObject := Nil; -end; - -destructor TJSONBaseObjectClass.Destroy; -begin - If Assigned(vJSONObject) Then - FreeAndNil(vJSONObject); - Inherited; -end; - -Function TJSONBaseObjectClass.GetObject: TJSONObject; +Function TRESTDWJSONInterfaceObject.ToJSON: String; Begin - result := TJSONObject(vJSONObject); + Result := ''; + If vJSONObject = Nil Then + Exit; +{$IFDEF RESTDWLEGACYJSON} + Result := TZAbstractObject(vJSONObject).toString; +{$ELSE} + Result := TJSONValue(vJSONObject).ToJSON; +{$ENDIF} End; -Procedure TJSONBaseObjectClass.SetObject(Value: TJSONObject); +Function TRESTDWJSONValueInterface.GetPair(Index: Integer): TRESTDWJSONPair; Begin - vJSONObject := TJSONBaseClass(Value); + Result := EmptyPair; + If vJSONObject = Nil Then + Exit; +{$IFDEF RESTDWLEGACYJSON} + Result := LegacyPairFromValue('', TZAbstractObject(vJSONObject)); +{$ELSE} + Result := NativePairFromValue('', TJSONValue(vJSONObject)); +{$ENDIF} End; -{ TRESTDWJSONInterfaceBase } - -constructor TRESTDWJSONInterfaceBase.Create(ParentJSON: TJSONBaseClass); -begin - Inherited Create; - vJSONObject := ParentJSON; -end; - -Destructor TRESTDWJSONInterfaceBase.Destroy; +Procedure TRESTDWJSONValueInterface.PutPair(Index: Integer; Value: TRESTDWJSONPair); Begin - If Assigned(vJSONObject) Then - FreeAndNil(vJSONObject); - inherited; End; -function TRESTDWJSONInterfaceBase.PairCount: Integer; -{$IFDEF FPC} -Var - cNames : TJSONArray; -{$ENDIF} -begin - {$IFNDEF FPC} - result := TJSONObject(vJSONObject).Count; - {$ELSE} - cNames := TJSONObject(vJSONObject).names; - result := cNames.length; - FreeAndNil(cNames); - {$ENDIF} -end; - end. diff --git a/CORE/Source/utils/JSON/uRESTDWSerialize.pas b/CORE/Source/utils/JSON/uRESTDWSerialize.pas index 5536bc8c3..2799609fd 100644 --- a/CORE/Source/utils/JSON/uRESTDWSerialize.pas +++ b/CORE/Source/utils/JSON/uRESTDWSerialize.pas @@ -1,6 +1,6 @@ Unit uRESTDWSerialize; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} Interface diff --git a/CORE/Source/utils/SSL/OpenSSL.Api_11.pas b/CORE/Source/utils/SSL/OpenSSL.Api_11.pas index 6287a6618..8fd115f48 100644 --- a/CORE/Source/utils/SSL/OpenSSL.Api_11.pas +++ b/CORE/Source/utils/SSL/OpenSSL.Api_11.pas @@ -28,27 +28,27 @@ interface LIB_CRYPTO = 'libcrypto-1_1-x64.dll'; LIB_SSL = 'libssl-1_1-x64.dll'; _PU = ''; - {$ELSEIF Defined(ANDROID64)} + {$ELSEIF Defined(ANDROID64) or (Defined(CPUAARCH64) and Defined(ANDROID))} LIB_CRYPTO = 'libcrypto-android64.a'; LIB_SSL = 'libssl-android64.a'; _PU = ''; - {$ELSEIF Defined(ANDROID32)} + {$ELSEIF Defined(ANDROID32) or (Defined(CPUARM) and Defined(ANDROID))} LIB_CRYPTO = 'libcrypto-android32.a'; LIB_SSL = 'libssl-android32.a'; _PU = ''; - {$ELSEIF Defined(IOS)} + {$ELSEIF Defined(IOS) or Defined(IOS64) or Defined(DCCIOS32) or Defined(DCCIOS64)} LIB_CRYPTO = 'libcrypto-ios.a'; LIB_SSL = 'libssl-ios.a'; _PU = ''; - {$ELSEIF Defined(MACOS32)} + {$ELSEIF Defined(MACOS32) or (Defined(CPUI386) and Defined(DARWIN))} LIB_CRYPTO = 'libssl-merged-osx32.dylib'; { We unify LibSsl and LibCrypto into a common shared library on macOS } LIB_SSL = 'libssl-merged-osx32.dylib'; _PU = '_'; - {$ELSEIF Defined(MACOS64)} + {$ELSEIF Defined(MACOS64) or (Defined(CPUX86_64) and Defined(DARWIN)) or (Defined(CPUAARCH64) and Defined(DARWIN))} LIB_CRYPTO = 'libcrypto-osx64.a'; LIB_SSL = 'libssl-osx64.a'; _PU = ''; - {$ELSEIF Defined(LINUX)} + {$ELSEIF Defined(LINUX) or Defined(FREEBSD)} LIB_CRYPTO = 'libcrypto.so'; LIB_SSL = 'libssl.so'; _PU = ''; @@ -19023,7 +19023,7 @@ function X509_VERIFY_PARAM_set_inh_flags(param: PX509_VERIFY_PARAM; flags: {$IFN function X509_VERIFY_PARAM_get_inh_flags(param: PX509_VERIFY_PARAM): {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt32{$ELSE}LongInt{$IFEND}{$ELSE}UInt32{$ENDIF}; cdecl; external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_get_inh_flags'; -function X509_VERIFY_PARAM_set1_host(param: PX509_VERIFY_PARAM; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; namelen: NativeUInt): Integer; cdecl; +function X509_VERIFY_PARAM_set1_host(param: PX509_VERIFY_PARAM; name: PAnsiChar; namelen: NativeUInt): Integer; cdecl; external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_set1_host'; function X509_VERIFY_PARAM_add1_host(param: PX509_VERIFY_PARAM; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; namelen: NativeUInt): Integer; cdecl; @@ -26354,10 +26354,10 @@ function SSL_CTX_set_trust(ctx: PSSL_CTX; trust: Integer): Integer; cdecl; function SSL_set_trust(ssl: PSSL; trust: Integer): Integer; cdecl; external LIB_SSL name _PU + 'SSL_set_trust'; -function SSL_set1_host(s: PSSL; hostname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; +function SSL_set1_host(s: PSSL; hostname: PAnsiChar): Integer; cdecl; external LIB_SSL name _PU + 'SSL_set1_host'; -function SSL_add1_host(s: PSSL; hostname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; +function SSL_add1_host(s: PSSL; hostname: PAnsiChar): Integer; cdecl; external LIB_SSL name _PU + 'SSL_add1_host'; function SSL_get0_peername(s: PSSL): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; @@ -26720,7 +26720,7 @@ function SSL_CTX_set_default_verify_dir(ctx: PSSL_CTX): Integer; cdecl; function SSL_CTX_set_default_verify_file(ctx: PSSL_CTX): Integer; cdecl; external LIB_SSL name _PU + 'SSL_CTX_set_default_verify_file'; -function SSL_CTX_load_verify_locations(ctx: PSSL_CTX; CAfile: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; CApath: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; +function SSL_CTX_load_verify_locations(ctx: PSSL_CTX; CAfile: PAnsiChar; CApath: PAnsiChar): Integer; cdecl; external LIB_SSL name _PU + 'SSL_CTX_load_verify_locations'; function SSL_get_session(ssl: PSSL): PSSL_SESSION; cdecl; diff --git a/CORE/Source/utils/SSL/RESTDWRootCA.pem b/CORE/Source/utils/SSL/RESTDWRootCA.pem new file mode 100644 index 000000000..6faad41ce --- /dev/null +++ b/CORE/Source/utils/SSL/RESTDWRootCA.pem @@ -0,0 +1,3892 @@ + +# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Label: "COMODO ECC Certification Authority" +# Serial: 41578283867086692638256921589707938090 +# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23 +# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11 +# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7 +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +# Issuer: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Subject: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Label: "NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny" +# Serial: 80544274841616 +# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88 +# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91 +# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98 +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F +uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 +XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Label: "Microsec e-Szigno Root CA 2009" +# Serial: 14014712776195784473 +# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1 +# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e +# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78 +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G +CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y +OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx +FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp +Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP +kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc +cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U +fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 +N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC +xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 ++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM +Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG +SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h +mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk +ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c +2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t +HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Label: "GlobalSign Root CA - R3" +# Serial: 4835703278459759426209954 +# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 +# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad +# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- + +# Issuer: CN=Izenpe.com O=IZENPE S.A. +# Subject: CN=Izenpe.com O=IZENPE S.A. +# Label: "Izenpe.com" +# Serial: 917563065490389241595536686991402621 +# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73 +# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19 +# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 +MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 +ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD +VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j +b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq +scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO +xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H +LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX +uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD +yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+ +JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q +rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN +BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L +hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB +QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+ +HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu +Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg +QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB +BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA +A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb +laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56 +awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo +JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw +LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT +VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk +LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb +UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/ +QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+ +naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls +QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- + +# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Label: "Go Daddy Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01 +# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b +# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96 +# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e +# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5 +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Services Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2 +# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f +# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5 +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA" +# Serial: 279744 +# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78 +# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e +# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Label: "TWCA Root Certification Authority" +# Serial: 1 +# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79 +# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48 +# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44 +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Label: "Security Communication RootCA2" +# Serial: 0 +# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43 +# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74 +# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX +DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy +dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj +YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV +OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr +zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM +VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ +hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO +ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw +awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs +OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF +coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc +okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 +t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy +1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ +SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Label: "Actalis Authentication Root CA" +# Serial: 6271844772424770508 +# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6 +# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac +# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66 +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE +BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w +MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC +SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 +ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv +UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX +4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 +KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ +gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb +rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ +51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F +be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe +KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F +v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn +fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 +jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz +ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL +e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 +jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz +WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V +SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j +pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX +X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok +fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R +K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU +ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU +LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT +LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 2 Root CA" +# Serial: 2 +# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29 +# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99 +# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48 +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr +6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV +L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 +1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx +MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ +QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB +arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr +Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi +FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS +P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN +9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz +uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h +9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t +OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo ++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 +KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 +DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us +H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ +I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 +5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h +3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz +Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 3 Root CA" +# Serial: 2 +# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec +# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57 +# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y +ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E +N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 +tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX +0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c +/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X +KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY +zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS +O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D +34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP +K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv +Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj +QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS +IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 +HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa +O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv +033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u +dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE +kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 +3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD +u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq +4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 3" +# Serial: 1 +# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef +# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1 +# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 2009" +# Serial: 623603 +# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f +# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0 +# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1 +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha +ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM +HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 +UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 +tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R +ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM +lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp +/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G +A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy +MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl +cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js +L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL +BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni +acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K +zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 +PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y +Johw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 EV 2009" +# Serial: 623604 +# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6 +# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83 +# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81 +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw +NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV +BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn +ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 +3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z +qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR +p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 +HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw +ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea +HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw +Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh +c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E +RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt +dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku +Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp +3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF +CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na +xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX +KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +# Issuer: CN=CA Disig Root R2 O=Disig a.s. +# Subject: CN=CA Disig Root R2 O=Disig a.s. +# Label: "CA Disig Root R2" +# Serial: 10572350602393338211 +# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03 +# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71 +# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03 +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy +MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe +NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH +PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I +x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe +QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR +yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO +QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 +H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ +QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD +i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs +nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 +rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI +hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf +GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb +lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka ++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal +TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i +nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 +gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr +G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os +zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x +L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Label: "ACCVRAIZ1" +# Serial: 6828503384748696800 +# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02 +# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17 +# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13 +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE +AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw +CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ +BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND +VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb +qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY +HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo +G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA +lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr +IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ +0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH +k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 +4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO +m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa +cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl +uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI +KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls +ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG +AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT +VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG +CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA +cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA +QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA +7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA +cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA +QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA +czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu +aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt +aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud +DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF +BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp +D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU +JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m +AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD +vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms +tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH +7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA +h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF +d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H +pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Label: "TWCA Global Root CA" +# Serial: 3262 +# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96 +# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65 +# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 2" +# Serial: 1 +# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a +# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9 +# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52 +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP +BSeOE6Fuwg== +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot 2011 O=Atos +# Subject: CN=Atos TrustedRoot 2011 O=Atos +# Label: "Atos TrustedRoot 2011" +# Serial: 6643877497813316402 +# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56 +# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21 +# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE +AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG +EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM +FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC +REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp +Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM +VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ +SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ +4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L +cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi +eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG +A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 +DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j +vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP +DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc +maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D +lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv +KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 1 G3" +# Serial: 687049649626669250736271037606554624078720034195 +# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab +# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67 +# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh +4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2 G3" +# Serial: 390156079458959257446133169266079962026824725800 +# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06 +# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36 +# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3 G3" +# Serial: 268090761170461462463995952157327242137089239581 +# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7 +# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d +# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G2" +# Serial: 15385348160840213938643033620894905419 +# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d +# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f +# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85 +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G3" +# Serial: 15459312981008553731928384953135426796 +# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb +# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89 +# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2 +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G2" +# Serial: 4293743540046975378534879503202253541 +# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44 +# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4 +# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G3" +# Serial: 7089244469030293291760083333884364146 +# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca +# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e +# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0 +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Trusted Root G4" +# Serial: 7451500558977370777930084869016614236 +# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49 +# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4 +# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88 +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- + +# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Label: "COMODO RSA Certification Authority" +# Serial: 101909084537582093308941363524873193117 +# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18 +# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4 +# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34 +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Label: "USERTrust RSA Certification Authority" +# Serial: 2645093764781058787591871645665788717 +# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5 +# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e +# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2 +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Label: "USERTrust ECC Certification Authority" +# Serial: 123013823720199481456569720443997572134 +# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1 +# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0 +# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Label: "GlobalSign ECC Root CA - R5" +# Serial: 32785792099990507226680698011560947931244 +# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08 +# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa +# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24 +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc +8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke +hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI +KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg +515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO +xwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Label: "IdenTrust Commercial Root CA 1" +# Serial: 13298821034946342390520003877796839426 +# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7 +# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25 +# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Label: "IdenTrust Public Sector Root CA 1" +# Serial: 13298821034946342390521976156843933698 +# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba +# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd +# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority +# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority +# Label: "CFCA EV ROOT" +# Serial: 407555286 +# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30 +# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83 +# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GB CA" +# Serial: 157768595616588414422159278966750757568 +# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d +# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed +# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6 +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Label: "SZAFIR ROOT CA2" +# Serial: 357043034767186914217277344587386743377558296292 +# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99 +# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de +# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 +ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw +NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg +Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN +QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT +3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw +3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 +3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 +BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN +XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF +AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw +8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG +nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP +oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy +d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg +LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA 2" +# Serial: 44979900017204383099463764357512596969 +# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2 +# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92 +# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04 +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi +DrW5viSP +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce +# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6 +# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36 +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef +# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66 +# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33 +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X1 O=Internet Security Research Group +# Subject: CN=ISRG Root X1 O=Internet Security Research Group +# Label: "ISRG Root X1" +# Serial: 172886928669790476064670243504169061120 +# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e +# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8 +# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6 +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- + +# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Label: "AC RAIZ FNMT-RCM" +# Serial: 485876308206448804701554682760554759 +# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d +# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20 +# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 1 O=Amazon +# Subject: CN=Amazon Root CA 1 O=Amazon +# Label: "Amazon Root CA 1" +# Serial: 143266978916655856878034712317230054538369994 +# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6 +# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16 +# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy +rqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 2 O=Amazon +# Subject: CN=Amazon Root CA 2 O=Amazon +# Label: "Amazon Root CA 2" +# Serial: 143266982885963551818349160658925006970653239 +# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66 +# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a +# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4 +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK +gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ +W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg +1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K +8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r +2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me +z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR +8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj +mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz +7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 ++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI +0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm +UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 +LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS +k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl +7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm +btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl +urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ +fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 +n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE +76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H +9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT +4PsJYGw= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 3 O=Amazon +# Subject: CN=Amazon Root CA 3 O=Amazon +# Label: "Amazon Root CA 3" +# Serial: 143266986699090766294700635381230934788665930 +# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87 +# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e +# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4 +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl +ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr +ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr +BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM +YyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 4 O=Amazon +# Subject: CN=Amazon Root CA 4 O=Amazon +# Label: "Amazon Root CA 4" +# Serial: 143266989758080763974105200630763877849284878 +# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd +# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be +# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92 +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi +9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk +M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB +MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw +CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW +1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- + +# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" +# Serial: 1 +# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49 +# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca +# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16 +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx +GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp +bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w +KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 +BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy +dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG +EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll +IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU +QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT +TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg +LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 +a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr +LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr +N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X +YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ +iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f +AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH +V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf +IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 +lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c +8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf +lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- + +# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Label: "GDCA TrustAUTH R5 ROOT" +# Serial: 9009899650740120186 +# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4 +# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4 +# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93 +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE +BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 +MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w +HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj +Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj +TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u +KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj +qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm +MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 +ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP +zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk +L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC +jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA +HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC +AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm +DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 +COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry +L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf +JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg +IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io +2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV +09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ +XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq +T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe +MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Label: "SSL.com Root Certification Authority RSA" +# Serial: 8875640296558310041 +# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29 +# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb +# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69 +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE +BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK +DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz +OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R +xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX +qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC +C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 +6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh +/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF +YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E +JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc +US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 +ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm ++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi +M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G +A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV +cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc +Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs +PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ +q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 +cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr +a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I +H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y +K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu +nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf +oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY +Ic2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com Root Certification Authority ECC" +# Serial: 8495723813297216424 +# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e +# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a +# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65 +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority RSA R2" +# Serial: 6248227494352943350 +# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95 +# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a +# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV +BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE +CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy +MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G +A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD +DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq +M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf +OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa +4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 +HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR +aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA +b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ +Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV +PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO +pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu +UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY +MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 +9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW +s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 +Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg +cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM +79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz +/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt +ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm +Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK +QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ +w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi +S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 +mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority ECC" +# Serial: 3182246526754555285 +# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90 +# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d +# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8 +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx +NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv +bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA +VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku +WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX +5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ +ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg +h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 +# Label: "GlobalSign Root CA - R6" +# Serial: 1417766617973444989252670301619537 +# MD5 Fingerprint: 4f:dd:07:e4:d4:22:64:39:1e:0c:37:42:ea:d1:c6:ae +# SHA1 Fingerprint: 80:94:64:0e:b5:a7:a1:ca:11:9c:1f:dd:d5:9f:81:02:63:a7:fb:d1 +# SHA256 Fingerprint: 2c:ab:ea:fe:37:d0:6c:a2:2a:ba:73:91:c0:03:3d:25:98:29:52:c4:53:64:73:49:76:3a:3a:b5:ad:6c:cf:69 +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg +MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx +MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET +MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI +xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k +ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD +aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw +LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw +1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX +k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 +SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h +bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n +WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY +rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce +MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu +bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN +nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt +Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 +55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj +vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf +cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz +oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp +nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs +pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v +JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R +8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 +5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GC CA" +# Serial: 44084345621038548146064804565436152554 +# MD5 Fingerprint: a9:d6:b9:2d:2f:93:64:f8:a5:69:ca:91:e9:68:07:23 +# SHA1 Fingerprint: e0:11:84:5e:34:de:be:88:81:b9:9c:f6:16:26:d1:96:1f:c3:b9:31 +# SHA256 Fingerprint: 85:60:f9:1c:36:24:da:ba:95:70:b5:fe:a0:db:e3:6f:f1:1a:83:23:be:94:86:85:4f:b3:f3:4a:55:71:19:8d +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw +CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 +bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg +Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ +BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu +ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS +b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni +eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W +p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T +rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV +57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg +Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- + +# Issuer: CN=UCA Global G2 Root O=UniTrust +# Subject: CN=UCA Global G2 Root O=UniTrust +# Label: "UCA Global G2 Root" +# Serial: 124779693093741543919145257850076631279 +# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8 +# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a +# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH +bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x +CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds +b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr +b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 +kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm +VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R +VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc +C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj +tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY +D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv +j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl +NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 +iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP +O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV +ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj +L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl +1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU +b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV +PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj +y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb +EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg +DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI ++Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy +YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX +UB+K+wb1whnw0A== +-----END CERTIFICATE----- + +# Issuer: CN=UCA Extended Validation Root O=UniTrust +# Subject: CN=UCA Extended Validation Root O=UniTrust +# Label: "UCA Extended Validation Root" +# Serial: 106100277556486529736699587978573607008 +# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2 +# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a +# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF +eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx +MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV +BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog +D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS +sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop +O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk +sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi +c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj +VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz +KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ +TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G +sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs +1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD +fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN +l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ +VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 +c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp +4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s +t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj +2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO +vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C +xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx +cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM +fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax +-----END CERTIFICATE----- + +# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Label: "Certigna Root CA" +# Serial: 269714418870597844693661054334862075617 +# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77 +# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43 +# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68 +-----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw +WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw +MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x +MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD +VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX +BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO +ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M +CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu +I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm +TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh +C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf +ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz +IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT +Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k +JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 +hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB +GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov +L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo +dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr +aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq +hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L +6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG +HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 +0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB +lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi +o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 +gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v +faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 +Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh +jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw +3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign Root CA - G1" +# Serial: 235931866688319308814040 +# MD5 Fingerprint: 9c:42:84:57:dd:cb:0b:a7:2e:95:ad:b6:f3:da:bc:ac +# SHA1 Fingerprint: 8a:c7:ad:8f:73:ac:4e:c1:b5:75:4d:a5:40:f4:fc:cf:7c:b5:8e:8c +# SHA256 Fingerprint: 40:f6:af:03:46:a9:9a:a1:cd:1d:55:5a:4e:9c:ce:62:c7:f9:63:46:03:ee:40:66:15:83:3d:c8:c8:d0:03:67 +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD +VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU +ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH +MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO +MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv +Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz +f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO +8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq +d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM +tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt +Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB +o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x +PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM +wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d +GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH +6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby +RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- + +# Issuer: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign ECC Root CA - G3" +# Serial: 287880440101571086945156 +# MD5 Fingerprint: ce:0b:72:d1:9f:88:8e:d0:50:03:e8:e3:b8:8b:67:40 +# SHA1 Fingerprint: 30:43:fa:4f:f2:57:dc:a0:c3:80:ee:2e:58:ea:78:b2:3f:e6:bb:c1 +# SHA256 Fingerprint: 86:a1:ec:ba:08:9c:4a:8d:3b:be:27:34:c6:12:ba:34:1d:81:3e:04:3c:f9:e8:a8:62:cd:5c:57:a3:6b:be:6b +-----BEGIN CERTIFICATE----- +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG +EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo +bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g +RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ +TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s +b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 +WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS +fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB +zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq +hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB +CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD ++JbNR6iC8hZVdyR+EhCVBCyj +-----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI +# Subject: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI +# Label: "emSign Root CA - C1" +# Serial: 825510296613316004955058 +# MD5 Fingerprint: d8:e3:5d:01:21:fa:78:5a:b0:df:ba:d2:ee:2a:5f:68 +# SHA1 Fingerprint: e7:2e:f1:df:fc:b2:09:28:cf:5d:d4:d5:67:37:b1:51:cb:86:4f:01 +# SHA256 Fingerprint: 12:56:09:aa:30:1d:a0:a2:49:b9:7a:82:39:cb:6a:34:21:6f:44:dc:ac:9f:39:54:b1:42:92:f2:e8:c8:60:8f +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG +A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg +SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v +dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ +BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ +HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH +3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH +GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c +xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 +aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq +TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 +/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 +kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG +YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT ++xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo +WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= +-----END CERTIFICATE----- + +# Issuer: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI +# Subject: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI +# Label: "emSign ECC Root CA - C3" +# Serial: 582948710642506000014504 +# MD5 Fingerprint: 3e:53:b3:a3:81:ee:d7:10:f8:d3:b0:1d:17:92:f5:d5 +# SHA1 Fingerprint: b6:af:43:c2:9b:81:53:7d:f6:ef:6b:c3:1f:1f:60:15:0c:ee:48:66 +# SHA256 Fingerprint: bc:4d:80:9b:15:18:9d:78:db:3e:1d:8c:f4:f9:72:6a:79:5d:a1:64:3c:a5:f1:35:8e:1d:db:0e:dc:0d:7e:b3 +-----BEGIN CERTIFICATE----- +MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG +EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx +IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND +IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci +MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti +sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O +BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB +Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c +3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J +0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== +-----END CERTIFICATE----- + +# Issuer: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Subject: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Label: "Hongkong Post Root CA 3" +# Serial: 46170865288971385588281144162979347873371282084 +# MD5 Fingerprint: 11:fc:9f:bd:73:30:02:8a:fd:3f:f3:58:b9:cb:20:f0 +# SHA1 Fingerprint: 58:a2:d0:ec:20:52:81:5b:c1:f3:f8:64:02:24:4e:c2:8e:02:4b:02 +# SHA256 Fingerprint: 5a:2f:c0:3f:0c:83:b0:90:bb:fa:40:60:4b:09:88:44:6c:76:36:18:3d:f9:84:6e:17:10:1a:44:7f:b8:ef:d6 +-----BEGIN CERTIFICATE----- +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 +mpv0 +-----END CERTIFICATE----- + +# Issuer: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation +# Subject: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation +# Label: "Microsoft ECC Root Certificate Authority 2017" +# Serial: 136839042543790627607696632466672567020 +# MD5 Fingerprint: dd:a1:03:e6:4a:93:10:d1:bf:f0:19:42:cb:fe:ed:67 +# SHA1 Fingerprint: 99:9a:64:c3:7f:f4:7d:9f:ab:95:f1:47:69:89:14:60:ee:c4:c3:c5 +# SHA256 Fingerprint: 35:8d:f3:9d:76:4a:f9:e1:b7:66:e9:c9:72:df:35:2e:e1:5c:fa:c2:27:af:6a:d1:d7:0e:8e:4a:6e:dc:ba:02 +-----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD +VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw +MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy +b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR +ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb +hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 +FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV +L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB +iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- + +# Issuer: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation +# Subject: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation +# Label: "Microsoft RSA Root Certificate Authority 2017" +# Serial: 40975477897264996090493496164228220339 +# MD5 Fingerprint: 10:ff:00:ff:cf:c9:f8:c7:7a:c0:ee:35:8e:c9:0f:47 +# SHA1 Fingerprint: 73:a5:e6:4a:3b:ff:83:16:ff:0e:dc:cc:61:8a:90:6e:4e:ae:4d:74 +# SHA256 Fingerprint: c7:41:f7:0f:4b:2a:8d:88:bf:2e:71:c1:41:22:ef:53:ef:10:eb:a0:cf:a5:e6:4c:fa:20:f4:18:85:30:73:e0 +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl +MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N +aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ +Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 +ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 +HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm +gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ +jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc +aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG +YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 +W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K +UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH ++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q +W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC +LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC +gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 +tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh +SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 +TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 +pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR +xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp +GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 +dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN +AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB +RA+GsCyRxj3qrg+E +-----END CERTIFICATE----- + +# Issuer: CN=e-Szigno Root CA 2017 O=Microsec Ltd. +# Subject: CN=e-Szigno Root CA 2017 O=Microsec Ltd. +# Label: "e-Szigno Root CA 2017" +# Serial: 411379200276854331539784714 +# MD5 Fingerprint: de:1f:f6:9e:84:ae:a7:b4:21:ce:1e:58:7d:d1:84:98 +# SHA1 Fingerprint: 89:d4:83:03:4f:9e:9a:48:80:5f:72:37:d4:a9:a6:ef:cb:7c:1f:d1 +# SHA256 Fingerprint: be:b0:0b:30:83:9b:9b:c3:2c:32:e4:44:79:05:95:06:41:f2:64:21:b1:5e:d0:89:19:8b:51:8a:e2:ea:1b:99 +-----BEGIN CERTIFICATE----- +MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV +BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk +LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv +b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ +BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg +THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v +IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv +xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H +Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB +eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo +jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ ++efcMQ== +-----END CERTIFICATE----- + +# Issuer: O=CERTSIGN SA OU=certSIGN ROOT CA G2 +# Subject: O=CERTSIGN SA OU=certSIGN ROOT CA G2 +# Label: "certSIGN Root CA G2" +# Serial: 313609486401300475190 +# MD5 Fingerprint: 8c:f1:75:8a:c6:19:cf:94:b7:f7:65:20:87:c3:97:c7 +# SHA1 Fingerprint: 26:f9:93:b4:ed:3d:28:27:b0:b9:4b:a7:e9:15:1d:a3:8d:92:e5:32 +# SHA256 Fingerprint: 65:7c:fe:2f:a7:3f:aa:38:46:25:71:f3:32:a2:36:3a:46:fc:e7:02:09:51:71:07:02:cd:fb:b6:ee:da:33:05 +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV +BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g +Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ +BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ +R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF +dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw +vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ +uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp +n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs +cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW +xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P +rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF +DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx +DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy +LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C +eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ +d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq +kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC +b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl +qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 +OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c +NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk +ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO +pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj +03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk +PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE +1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX +QRBdJ3NghVdJIgc= +-----END CERTIFICATE----- + +# Issuer: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. +# Subject: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. +# Label: "NAVER Global Root Certification Authority" +# Serial: 9013692873798656336226253319739695165984492813 +# MD5 Fingerprint: c8:7e:41:f6:25:3b:f5:09:b3:17:e8:46:3d:bf:d0:9b +# SHA1 Fingerprint: 8f:6b:f2:a9:27:4a:da:14:a0:c4:f4:8e:61:27:f9:c0:1e:78:5d:d1 +# SHA256 Fingerprint: 88:f4:38:dc:f8:ff:d1:fa:8f:42:91:15:ff:e5:f8:2a:e1:e0:6e:0c:70:c3:75:fa:ad:71:7b:34:a4:9e:72:65 +-----BEGIN CERTIFICATE----- +MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM +BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG +T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx +CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD +b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA +iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH +38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE +HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz +kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP +szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq +vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf +nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG +YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo +0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a +CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K +AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I +36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN +qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj +cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm ++LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL +hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe +lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 +p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 +piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR +LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX +5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO +dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul +9XXeifdy +-----END CERTIFICATE----- + +# Issuer: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres +# Subject: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres +# Label: "AC RAIZ FNMT-RCM SERVIDORES SEGUROS" +# Serial: 131542671362353147877283741781055151509 +# MD5 Fingerprint: 19:36:9c:52:03:2f:d2:d1:bb:23:cc:dd:1e:12:55:bb +# SHA1 Fingerprint: 62:ff:d9:9e:c0:65:0d:03:ce:75:93:d2:ed:3f:2d:32:c9:e3:e5:4a +# SHA256 Fingerprint: 55:41:53:b1:3d:2c:f9:dd:b7:53:bf:be:1a:4e:0a:e0:8d:0a:a4:18:70:58:fe:60:a2:b8:62:b2:e4:b8:7b:cb +-----BEGIN CERTIFICATE----- +MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw +CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw +FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S +Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5 +MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL +DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS +QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH +sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK +Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu +SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC +MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy +v+c= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign Root R46 O=GlobalSign nv-sa +# Subject: CN=GlobalSign Root R46 O=GlobalSign nv-sa +# Label: "GlobalSign Root R46" +# Serial: 1552617688466950547958867513931858518042577 +# MD5 Fingerprint: c4:14:30:e4:fa:66:43:94:2a:6a:1b:24:5f:19:d0:ef +# SHA1 Fingerprint: 53:a2:b0:4b:ca:6b:d6:45:e6:39:8a:8e:c4:0d:d2:bf:77:c3:a2:90 +# SHA256 Fingerprint: 4f:a3:12:6d:8d:3a:11:d1:c4:85:5a:4f:80:7c:ba:d6:cf:91:9d:3a:5a:88:b0:3b:ea:2c:63:72:d9:3c:40:c9 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA +MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD +VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy +MDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt +c2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ +OaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG +vGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud +316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo +0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE +y132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF +zXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE ++cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN +I/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs +x2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa +ByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC +4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4 +7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg +JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti +2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk +pnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF +FRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt +rWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk +ZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5 +u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP +4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6 +N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3 +vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6 +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign Root E46 O=GlobalSign nv-sa +# Subject: CN=GlobalSign Root E46 O=GlobalSign nv-sa +# Label: "GlobalSign Root E46" +# Serial: 1552617690338932563915843282459653771421763 +# MD5 Fingerprint: b5:b8:66:ed:de:08:83:e3:c9:e2:01:34:06:ac:51:6f +# SHA1 Fingerprint: 39:b4:6c:d5:fe:80:06:eb:e2:2f:4a:bb:08:33:a0:af:db:b9:dd:84 +# SHA256 Fingerprint: cb:b9:c4:4d:84:b8:04:3e:10:50:ea:31:a6:9f:51:49:55:d7:bf:d2:e2:c6:b4:93:01:01:9a:d6:1d:9f:50:58 +-----BEGIN CERTIFICATE----- +MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx +CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD +ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw +MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex +HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq +R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd +yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ +7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8 ++RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A= +-----END CERTIFICATE----- + +# Issuer: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz +# Subject: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz +# Label: "ANF Secure Server Root CA" +# Serial: 996390341000653745 +# MD5 Fingerprint: 26:a6:44:5a:d9:af:4e:2f:b2:1d:b6:65:b0:4e:e8:96 +# SHA1 Fingerprint: 5b:6e:68:d0:cc:15:b6:a0:5f:1e:c1:5f:ae:02:fc:6b:2f:5d:6f:74 +# SHA256 Fingerprint: fb:8f:ec:75:91:69:b9:10:6b:1e:51:16:44:c6:18:c5:13:04:37:3f:6c:06:43:08:8d:8b:ef:fd:1b:99:75:99 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Subject: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Label: "Certum EC-384 CA" +# Serial: 160250656287871593594747141429395092468 +# MD5 Fingerprint: b6:65:b3:96:60:97:12:a1:ec:4e:e1:3d:a3:c6:c9:f1 +# SHA1 Fingerprint: f3:3e:78:3c:ac:df:f4:a2:cc:ac:67:55:69:56:d7:e5:16:3c:e1:ed +# SHA256 Fingerprint: 6b:32:80:85:62:53:18:aa:50:d1:73:c9:8d:8b:da:09:d5:7e:27:41:3d:11:4c:f7:87:a0:f5:d0:6c:03:0c:f6 +-----BEGIN CERTIFICATE----- +MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw +CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw +JQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT +EENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2MDcyNDU0WhcNNDMwMzI2MDcyNDU0 +WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBT +LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAX +BgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATE +KI6rGFtqvm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7Tm +Fy8as10CW4kjPMIRBSqniBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68Kj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8 +EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J +UG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn +nvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k= +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Root CA" +# Serial: 40870380103424195783807378461123655149 +# MD5 Fingerprint: 51:e1:c2:e7:fe:4c:84:af:59:0e:2f:f4:54:6f:ea:29 +# SHA1 Fingerprint: c8:83:44:c0:18:ae:9f:cc:f1:87:b7:8f:22:d1:c5:d7:45:84:ba:e5 +# SHA256 Fingerprint: fe:76:96:57:38:55:77:3e:37:a9:5e:7a:d4:d9:cc:96:c3:01:57:c1:5d:31:76:5b:a9:b1:57:04:e1:ae:78:fd +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique +# Subject: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique +# Label: "TunTrust Root CA" +# Serial: 108534058042236574382096126452369648152337120275 +# MD5 Fingerprint: 85:13:b9:90:5b:36:5c:b6:5e:b8:5a:f8:e0:31:57:b4 +# SHA1 Fingerprint: cf:e9:70:84:0f:e0:73:0f:9d:f6:0c:7f:2c:4b:ee:20:46:34:9c:bb +# SHA256 Fingerprint: 2e:44:10:2a:b5:8c:b8:54:19:45:1c:8e:19:d9:ac:f3:66:2c:af:bc:61:4b:6a:53:96:0a:30:f7:d0:e2:eb:41 +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL +BQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg +Q2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv +b3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQwNDI2MDg1NzU2WjBhMQswCQYDVQQG +EwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBDZXJ0aWZpY2F0aW9u +IEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZ +n56eY+hz2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd +2JQDoOw05TDENX37Jk0bbjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgF +VwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZ +GoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAdgjH8KcwAWJeRTIAAHDOF +li/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViWVSHbhlnU +r8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2 +eY8fTpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIb +MlEsPvLfe/ZdeikZjuXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISg +jwBUFfyRbVinljvrS5YnzWuioYasDXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB +7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwSVXAkPcvCFDVDXSdOvsC9qnyW +5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI04Y+oXNZtPdE +ITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0 +90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+z +xiD2BkewhpMl0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYu +QEkHDVneixCwSQXi/5E/S7fdAo74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4 +FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRYYdZ2vyJ/0Adqp2RT8JeNnYA/u8EH +22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJpadbGNjHh/PqAulxP +xOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65xxBzn +dFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5 +Xc0yGYuPjCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7b +nV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ +CvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH +u/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj +d9qDRIueVSjAi1jTkD5OGwDxFa2DK5o= +-----END CERTIFICATE----- + +# Issuer: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Subject: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Label: "HARICA TLS RSA Root CA 2021" +# Serial: 76817823531813593706434026085292783742 +# MD5 Fingerprint: 65:47:9b:58:86:dd:2c:f0:fc:a2:84:1f:1e:96:c4:91 +# SHA1 Fingerprint: 02:2d:05:82:fa:88:ce:14:0c:06:79:de:7f:14:10:e9:45:d7:a5:6d +# SHA256 Fingerprint: d9:5d:0e:8e:da:79:52:5b:f9:be:b1:1b:14:d2:10:0d:32:94:98:5f:0c:62:d9:fa:bd:9c:d9:99:ec:cb:7b:1d +-----BEGIN CERTIFICATE----- +MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBs +MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0Eg +Um9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUzOFoXDTQ1MDIxMzEwNTUzN1owbDEL +MAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl +YXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNBIFJv +b3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569l +mwVnlskNJLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE +4VGC/6zStGndLuwRo0Xua2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uv +a9of08WRiFukiZLRgeaMOVig1mlDqa2YUlhu2wr7a89o+uOkXjpFc5gH6l8Cct4M +pbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K5FrZx40d/JiZ+yykgmvw +Kh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEvdmn8kN3b +LW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcY +AuUR0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqB +AGMUuTNe3QvboEUHGjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYq +E613TBoYm5EPWNgGVMWX+Ko/IIqmhaZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHr +W2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQCPxrvrNQKlr9qEgYRtaQQJKQ +CoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAU +X15QvWiWkKQUEapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3 +f5Z2EMVGpdAgS1D0NTsY9FVqQRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxaja +H6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxDQpSbIPDRzbLrLFPCU3hKTwSUQZqP +JzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcRj88YxeMn/ibvBZ3P +zzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5vZSt +jBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0 +/L5H9MG0qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pT +BGIBnfHAT+7hOtSLIBD6Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79 +aPib8qXPMThcFarmlwDB31qlpzmq6YR/PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YW +xw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnnkf3/W9b3raYvAwtt41dU +63ZTGI0RmLo= +-----END CERTIFICATE----- + +# Issuer: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Subject: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Label: "HARICA TLS ECC Root CA 2021" +# Serial: 137515985548005187474074462014555733966 +# MD5 Fingerprint: ae:f7:4c:e5:66:35:d1:b7:9b:8c:22:93:74:d3:4b:b0 +# SHA1 Fingerprint: bc:b0:c1:9d:e9:98:92:70:19:38:57:e9:8d:a7:b4:5d:6e:ee:01:48 +# SHA256 Fingerprint: 3f:99:cc:47:4a:cf:ce:4d:fe:d5:87:94:66:5e:47:8d:15:47:73:9f:2e:78:0f:1b:b4:ca:9b:13:30:97:d4:01 +-----BEGIN CERTIFICATE----- +MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw +CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh +cmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v +dCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoXDTQ1MDIxMzExMDEwOVowbDELMAkG +A1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj +aCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJvb3Qg +Q0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7 +KKrxcm1lAEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9Y +STHMmE5gEYd103KUkE+bECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD +AgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw +SaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN +nxS2PFOiTAZpffpskcYqSUXm7LcT4Tps +-----END CERTIFICATE----- + +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" +# Serial: 1977337328857672817 +# MD5 Fingerprint: 4e:6e:9b:54:4c:ca:b7:fa:48:e4:90:b1:15:4b:1c:a3 +# SHA1 Fingerprint: 0b:be:c2:27:22:49:cb:39:aa:db:35:5c:53:e3:8c:ae:78:ff:b6:fe +# SHA256 Fingerprint: 57:de:05:83:ef:d2:b2:6e:03:61:da:99:da:9d:f4:64:8d:ef:7e:e8:44:1c:3b:72:8a:fa:9b:cd:e0:f9:b2:6a +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1 +MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc +tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd +IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j +b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC +AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw +ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m +iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF +Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ +hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P +Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE +EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV +1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t +CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR +5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw +f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9 +ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK +GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV +-----END CERTIFICATE----- + +# Issuer: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. +# Subject: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. +# Label: "vTrus ECC Root CA" +# Serial: 630369271402956006249506845124680065938238527194 +# MD5 Fingerprint: de:4b:c1:f5:52:8c:9b:43:e1:3e:8f:55:54:17:8d:85 +# SHA1 Fingerprint: f6:9c:db:b0:fc:f6:02:13:b6:52:32:a6:a3:91:3f:16:70:da:c3:e1 +# SHA256 Fingerprint: 30:fb:ba:2c:32:23:8e:2a:98:54:7a:f9:79:31:e5:50:42:8b:9b:3f:1c:8e:eb:66:33:dc:fa:86:c5:b2:7d:d3 +-----BEGIN CERTIFICATE----- +MIICDzCCAZWgAwIBAgIUbmq8WapTvpg5Z6LSa6Q75m0c1towCgYIKoZIzj0EAwMw +RzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAY +BgNVBAMTEXZUcnVzIEVDQyBSb290IENBMB4XDTE4MDczMTA3MjY0NFoXDTQzMDcz +MTA3MjY0NFowRzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28u +LEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBSb290IENBMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAEZVBKrox5lkqqHAjDo6LN/llWQXf9JpRCux3NCNtzslt188+cToL0 +v/hhJoVs1oVbcnDS/dtitN9Ti72xRFhiQgnH+n9bEOf+QP3A2MMrMudwpremIFUd +e4BdS49nTPEQo0IwQDAdBgNVHQ4EFgQUmDnNvtiyjPeyq+GtJK97fKHbH88wDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDaAAwZQIw +V53dVvHH4+m4SVBrm2nDb+zDfSXkV5UTQJtS0zvzQBm8JsctBp61ezaf9SXUY2sA +AjEA6dPGnlaaKsyh2j/IZivTWJwghfqrkYpwcBE4YGQLYgmRWAD5Tfs0aNoJrSEG +GJTO +-----END CERTIFICATE----- + +# Issuer: CN=vTrus Root CA O=iTrusChina Co.,Ltd. +# Subject: CN=vTrus Root CA O=iTrusChina Co.,Ltd. +# Label: "vTrus Root CA" +# Serial: 387574501246983434957692974888460947164905180485 +# MD5 Fingerprint: b8:c9:37:df:fa:6b:31:84:64:c5:ea:11:6a:1b:75:fc +# SHA1 Fingerprint: 84:1a:69:fb:f5:cd:1a:25:34:13:3d:e3:f8:fc:b8:99:d0:c9:14:b7 +# SHA256 Fingerprint: 8a:71:de:65:59:33:6f:42:6c:26:e5:38:80:d0:0d:88:a1:8d:a4:c6:a9:1f:0d:cb:61:94:e2:06:c5:c9:63:87 +-----BEGIN CERTIFICATE----- +MIIFVjCCAz6gAwIBAgIUQ+NxE9izWRRdt86M/TX9b7wFjUUwDQYJKoZIhvcNAQEL +BQAwQzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4x +FjAUBgNVBAMTDXZUcnVzIFJvb3QgQ0EwHhcNMTgwNzMxMDcyNDA1WhcNNDMwNzMx +MDcyNDA1WjBDMQswCQYDVQQGEwJDTjEcMBoGA1UEChMTaVRydXNDaGluYSBDby4s +THRkLjEWMBQGA1UEAxMNdlRydXMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAL1VfGHTuB0EYgWgrmy3cLRB6ksDXhA/kFocizuwZotsSKYc +IrrVQJLuM7IjWcmOvFjai57QGfIvWcaMY1q6n6MLsLOaXLoRuBLpDLvPbmyAhykU +AyyNJJrIZIO1aqwTLDPxn9wsYTwaP3BVm60AUn/PBLn+NvqcwBauYv6WTEN+VRS+ +GrPSbcKvdmaVayqwlHeFXgQPYh1jdfdr58tbmnDsPmcF8P4HCIDPKNsFxhQnL4Z9 +8Cfe/+Z+M0jnCx5Y0ScrUw5XSmXX+6KAYPxMvDVTAWqXcoKv8R1w6Jz1717CbMdH +flqUhSZNO7rrTOiwCcJlwp2dCZtOtZcFrPUGoPc2BX70kLJrxLT5ZOrpGgrIDajt +J8nU57O5q4IikCc9Kuh8kO+8T/3iCiSn3mUkpF3qwHYw03dQ+A0Em5Q2AXPKBlim +0zvc+gRGE1WKyURHuFE5Gi7oNOJ5y1lKCn+8pu8fA2dqWSslYpPZUxlmPCdiKYZN +pGvu/9ROutW04o5IWgAZCfEF2c6Rsffr6TlP9m8EQ5pV9T4FFL2/s1m02I4zhKOQ +UqqzApVg+QxMaPnu1RcN+HFXtSXkKe5lXa/R7jwXC1pDxaWG6iSe4gUH3DRCEpHW +OXSuTEGC2/KmSNGzm/MzqvOmwMVO9fSddmPmAsYiS8GVP1BkLFTltvA8Kc9XAgMB +AAGjQjBAMB0GA1UdDgQWBBRUYnBj8XWEQ1iO0RYgscasGrz2iTAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAKbqSSaet +8PFww+SX8J+pJdVrnjT+5hpk9jprUrIQeBqfTNqK2uwcN1LgQkv7bHbKJAs5EhWd +nxEt/Hlk3ODg9d3gV8mlsnZwUKT+twpw1aA08XXXTUm6EdGz2OyC/+sOxL9kLX1j +bhd47F18iMjrjld22VkE+rxSH0Ws8HqA7Oxvdq6R2xCOBNyS36D25q5J08FsEhvM +Kar5CKXiNxTKsbhm7xqC5PD48acWabfbqWE8n/Uxy+QARsIvdLGx14HuqCaVvIiv +TDUHKgLKeBRtRytAVunLKmChZwOgzoy8sHJnxDHO2zTlJQNgJXtxmOTAGytfdELS +S8VZCAeHvsXDf+eW2eHcKJfWjwXj9ZtOyh1QRwVTsMo554WgicEFOwE30z9J4nfr +I8iIZjs9OXYhRvHsXyO466JmdXTBQPfYaJqT4i2pLr0cox7IdMakLXogqzu4sEb9 +b91fUlV1YvCXoHzXOP0l382gmxDPi7g4Xl7FtKYCNqEeXxzP4padKar9mK5S4fNB +UvupLnKWnyfjqnN9+BojZns7q2WwMgFLFT49ok8MKzWixtlnEjUwzXYuFrOZnk1P +Ti07NEPhmg4NpGaXutIcSkwsKouLgU9xGqndXHt7CMUADTdA43x7VF8vhV929ven +sBxXVsFy6K2ir40zSbofitzmdHxghm+Hl3s= +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X2 O=Internet Security Research Group +# Subject: CN=ISRG Root X2 O=Internet Security Research Group +# Label: "ISRG Root X2" +# Serial: 87493402998870891108772069816698636114 +# MD5 Fingerprint: d3:9e:c4:1e:23:3c:a6:df:cf:a3:7e:6d:e0:14:e6:e5 +# SHA1 Fingerprint: bd:b1:b9:3c:d5:97:8d:45:c6:26:14:55:f8:db:95:c7:5a:d1:53:af +# SHA256 Fingerprint: 69:72:9b:8e:15:a8:6e:fc:17:7a:57:af:b7:17:1d:fc:64:ad:d2:8c:2f:ca:8c:f1:50:7e:34:45:3c:cb:14:70 +-----BEGIN CERTIFICATE----- +MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw +CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg +R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00 +MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT +ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw +EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW ++1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9 +ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI +zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW +tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1 +/q4AaOeMSQ+2b1tbFfLn +-----END CERTIFICATE----- + +# Issuer: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. +# Subject: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. +# Label: "HiPKI Root CA - G1" +# Serial: 60966262342023497858655262305426234976 +# MD5 Fingerprint: 69:45:df:16:65:4b:e8:68:9a:8f:76:5f:ff:80:9e:d3 +# SHA1 Fingerprint: 6a:92:e4:a8:ee:1b:ec:96:45:37:e3:29:57:49:cd:96:e3:e5:d2:60 +# SHA256 Fingerprint: f0:15:ce:3c:c2:39:bf:ef:06:4b:e9:f1:d2:c4:17:e1:a0:26:4a:0a:94:be:1f:0c:8d:12:18:64:eb:69:49:cc +-----BEGIN CERTIFICATE----- +MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBP +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xGzAZBgNVBAMMEkhpUEtJIFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRa +Fw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3 +YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kgUm9vdCBDQSAtIEcx +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0o9Qw +qNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twv +Vcg3Px+kwJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6 +lZgRZq2XNdZ1AYDgr/SEYYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnz +Qs7ZngyzsHeXZJzA9KMuH5UHsBffMNsAGJZMoYFL3QRtU6M9/Aes1MU3guvklQgZ +KILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfdhSi8MEyr48KxRURHH+CK +FgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj1jOXTyFj +HluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDr +y+K49a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ +/W3c1pzAtH2lsN0/Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgM +a/aOEmem8rJY5AIJEzypuxC00jBF8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6 +fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQDAgGGMA0GCSqG +SIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi +7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqc +SE5XCV0vrPSltJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6Fza +ZsT0pPBWGTMpWmWSBUdGSquEwx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9Tc +XzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07QJNBAsNB1CI69aO4I1258EHBGG3zg +iLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv5wiZqAxeJoBF1Pho +L5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+GpzjLrF +Ne85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wr +kkVbbiVghUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+ +vhV4nYWBSipX3tUZQ9rbyltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQU +YDksswBVLuT1sw5XxJFBAJw/6KXf6vb/yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Label: "GlobalSign ECC Root CA - R4" +# Serial: 159662223612894884239637590694 +# MD5 Fingerprint: 26:29:f8:6d:e1:88:bf:a2:65:7f:aa:c4:cd:0f:7f:fc +# SHA1 Fingerprint: 6b:a0:b0:98:e1:71:ef:5a:ad:fe:48:15:80:77:10:f4:bd:6f:0b:28 +# SHA256 Fingerprint: b0:85:d7:0b:96:4f:19:1a:73:e4:af:0d:54:ae:7a:0e:07:aa:fd:af:9b:71:dd:08:62:13:8a:b7:32:5a:24:a2 +-----BEGIN CERTIFICATE----- +MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD +VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw +MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g +UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx +uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV +HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/ ++wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147 +bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R1 O=Google Trust Services LLC +# Subject: CN=GTS Root R1 O=Google Trust Services LLC +# Label: "GTS Root R1" +# Serial: 159662320309726417404178440727 +# MD5 Fingerprint: 05:fe:d0:bf:71:a8:a3:76:63:da:01:e0:d8:52:dc:40 +# SHA1 Fingerprint: e5:8c:1c:c4:91:3b:38:63:4b:e9:10:6e:e3:ad:8e:6b:9d:d9:81:4a +# SHA256 Fingerprint: d9:47:43:2a:bd:e7:b7:fa:90:fc:2e:6b:59:10:1b:12:80:e0:e1:c7:e4:e4:0f:a3:c6:88:7f:ff:57:a7:f4:cf +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R3 O=Google Trust Services LLC +# Subject: CN=GTS Root R3 O=Google Trust Services LLC +# Label: "GTS Root R3" +# Serial: 159662495401136852707857743206 +# MD5 Fingerprint: 3e:e7:9d:58:02:94:46:51:94:e5:e0:22:4a:8b:e7:73 +# SHA1 Fingerprint: ed:e5:71:80:2b:c8:92:b9:5b:83:3c:d2:32:68:3f:09:cd:a0:1e:46 +# SHA256 Fingerprint: 34:d8:a7:3e:e2:08:d9:bc:db:0d:95:65:20:93:4b:4e:40:e6:94:82:59:6e:8b:6f:73:c8:42:6b:01:0a:6f:48 +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG +A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G +jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2 +4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7 +VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm +ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R4 O=Google Trust Services LLC +# Subject: CN=GTS Root R4 O=Google Trust Services LLC +# Label: "GTS Root R4" +# Serial: 159662532700760215368942768210 +# MD5 Fingerprint: 43:96:83:77:19:4d:76:b3:9d:65:52:e4:1d:22:a5:e8 +# SHA1 Fingerprint: 77:d3:03:67:b5:e0:0c:15:f6:0c:38:61:df:7c:e1:3b:92:46:4d:47 +# SHA256 Fingerprint: 34:9d:fa:40:58:c5:e2:63:12:3b:39:8a:e7:95:57:3c:4e:13:13:c8:3f:e6:8f:93:55:6c:d5:e8:03:1b:3c:7d +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG +A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi +QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR +HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D +9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8 +p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD +-----END CERTIFICATE----- + +# Issuer: CN=Telia Root CA v2 O=Telia Finland Oyj +# Subject: CN=Telia Root CA v2 O=Telia Finland Oyj +# Label: "Telia Root CA v2" +# Serial: 7288924052977061235122729490515358 +# MD5 Fingerprint: 0e:8f:ac:aa:82:df:85:b1:f4:dc:10:1c:fc:99:d9:48 +# SHA1 Fingerprint: b9:99:cd:d1:73:50:8a:c4:47:05:08:9c:8c:88:fb:be:a0:2b:40:cd +# SHA256 Fingerprint: 24:2b:69:74:2f:cb:1e:5b:2a:bf:98:89:8b:94:57:21:87:54:4e:5b:4d:99:11:78:65:73:62:1f:6a:74:b8:2c +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx +CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE +AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1 +NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZ +MBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ76zBq +AMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9 +vVYiQJ3q9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9 +lRdU2HhE8Qx3FZLgmEKnpNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTOD +n3WhUidhOPFZPY5Q4L15POdslv5e2QJltI5c0BE0312/UqeBAMN/mUWZFdUXyApT +7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW5olWK8jjfN7j/4nlNW4o +6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNrRBH0pUPC +TEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6 +WT0EBXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63R +DolUK5X6wK0dmBR4M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZI +pEYslOqodmJHixBTB0hXbOKSTbauBcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGj +YzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7Wxy+G2CQ5MB0GA1UdDgQWBBRy +rOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ +8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi +0f6X+J8wfBj5tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMM +A8iZGok1GTzTyVR8qPAs5m4HeW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBS +SRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+Cy748fdHif64W1lZYudogsYMVoe+K +TTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygCQMez2P2ccGrGKMOF +6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15h2Er +3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMt +Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT +VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW +ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA +rBPuUBQemMc= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH +# Subject: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH +# Label: "D-TRUST BR Root CA 1 2020" +# Serial: 165870826978392376648679885835942448534 +# MD5 Fingerprint: b5:aa:4b:d5:ed:f7:e3:55:2e:8f:72:0a:f3:75:b8:ed +# SHA1 Fingerprint: 1f:5b:98:f0:e3:b5:f7:74:3c:ed:e6:b0:36:7d:32:cd:f4:09:41:67 +# SHA256 Fingerprint: e5:9a:aa:81:60:09:c2:2b:ff:5b:25:ba:d3:7d:f3:06:f0:49:79:7c:1f:81:d8:5a:b0:89:e6:57:bd:8f:00:44 +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQsw +CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS +VVNUIEJSIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5 +NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG +A1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB +BAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7dPYS +zuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0 +QVK5buXuQqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/ +VbNafAkl1bK6CKBrqx9tMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g +PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2JyX3Jvb3Rf +Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l +dC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 +c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO +PQQDAwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFW +wKrY7RjEsK70PvomAjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHV +dWNbFJWcHwHP2NVypw87 +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH +# Subject: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH +# Label: "D-TRUST EV Root CA 1 2020" +# Serial: 126288379621884218666039612629459926992 +# MD5 Fingerprint: 8c:2d:9d:70:9f:48:99:11:06:11:fb:e9:cb:30:c0:6e +# SHA1 Fingerprint: 61:db:8c:21:59:69:03:90:d8:7c:9c:12:86:54:cf:9d:3d:f4:dd:07 +# SHA256 Fingerprint: 08:17:0d:1a:a3:64:53:90:1a:2f:95:92:45:e3:47:db:0c:8d:37:ab:aa:bc:56:b8:1a:a1:00:dc:95:89:70:db +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQsw +CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS +VVNUIEVWIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5 +NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG +A1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB +BAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8ZRCC +/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rD +wpdhQntJraOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3 +OqQo5FD4pPfsazK2/umLMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g +PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2V2X3Jvb3Rf +Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l +dC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 +c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO +PQQDAwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CA +y/m0sRtW9XLS/BnRAjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJb +gfM0agPnIjhQW+0ZT0MW +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. +# Subject: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. +# Label: "DigiCert TLS ECC P384 Root G5" +# Serial: 13129116028163249804115411775095713523 +# MD5 Fingerprint: d3:71:04:6a:43:1c:db:a6:59:e1:a8:a3:aa:c5:71:ed +# SHA1 Fingerprint: 17:f3:de:5e:9f:0f:19:e9:8e:f6:1f:32:26:6e:20:c4:07:ae:30:ee +# SHA256 Fingerprint: 01:8e:13:f0:77:25:32:cf:80:9b:d1:b1:72:81:86:72:83:fc:48:c6:e1:3b:e9:c6:98:12:85:4a:49:0c:1b:05 +-----BEGIN CERTIFICATE----- +MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp +Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2 +MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ +bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS +7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp +0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS +B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 +BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ +LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4 +DXZDjC5Ty3zfDBeWUA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. +# Subject: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. +# Label: "DigiCert TLS RSA4096 Root G5" +# Serial: 11930366277458970227240571539258396554 +# MD5 Fingerprint: ac:fe:f7:34:96:a9:f2:b3:b4:12:4b:e4:27:41:6f:e1 +# SHA1 Fingerprint: a7:88:49:dc:5d:7c:75:8c:8c:de:39:98:56:b3:aa:d0:b2:a5:71:35 +# SHA256 Fingerprint: 37:1a:00:dc:05:33:b3:72:1a:7e:eb:40:e8:41:9e:70:79:9d:2b:0a:0f:2c:1d:80:69:31:65:f7:ce:c4:ad:75 +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN +MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT +HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN +NDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs +IEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS87IE+ +ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG0 +2C+JFvuUAT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgp +wgscONyfMXdcvyej/Cestyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZM +pG2T6T867jp8nVid9E6P/DsjyG244gXazOvswzH016cpVIDPRFtMbzCe88zdH5RD +nU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnVDdXifBBiqmvwPXbzP6Po +sMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9qTXeXAaDx +Zre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cd +Lvvyz6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvX +KyY//SovcfXWJL5/MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNe +XoVPzthwiHvOAbWWl9fNff2C+MIkwcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPL +tgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4EFgQUUTMc7TZArxfTJc1paPKv +TiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN +AQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw +GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7H +PNtQOa27PShNlnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLF +O4uJ+DQtpBflF+aZfTCIITfNMBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQ +REtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/u4cnYiWB39yhL/btp/96j1EuMPik +AdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9GOUrYU9DzLjtxpdRv +/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh47a+ +p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw +MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF +qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK +ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+ +-----END CERTIFICATE----- + +# Issuer: CN=Certainly Root R1 O=Certainly +# Subject: CN=Certainly Root R1 O=Certainly +# Label: "Certainly Root R1" +# Serial: 188833316161142517227353805653483829216 +# MD5 Fingerprint: 07:70:d4:3e:82:87:a0:fa:33:36:13:f4:fa:33:e7:12 +# SHA1 Fingerprint: a0:50:ee:0f:28:71:f4:27:b2:12:6d:6f:50:96:25:ba:cc:86:42:af +# SHA256 Fingerprint: 77:b8:2c:d8:64:4c:43:05:f7:ac:c5:cb:15:6b:45:67:50:04:03:3d:51:c6:0c:62:02:a8:e0:c3:34:67:d3:a0 +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw +PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy +dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9 +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0 +YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANA2 +1B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O5MQT +vqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbed +aFySpvXl8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b0 +1C7jcvk2xusVtyWMOvwlDbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5 +r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGIXsXwClTNSaa/ApzSRKft43jvRl5tcdF5 +cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkNKPl6I7ENPT2a/Z2B7yyQ +wHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQAjeZjOVJ +6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA +2CnbrlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyH +Wyf5QBGenDPBt+U1VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMR +eiFPCyEQtkA6qyI6BJyLm4SGcprSp6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB +/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTgqj8ljZ9EXME66C6u +d0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAszHQNTVfSVcOQr +PbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d +8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi +1wrykXprOQ4vMMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrd +rRT90+7iIgXr0PK3aBLXWopBGsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9di +taY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+gjwN/KUD+nsa2UUeYNrEjvn8K8l7 +lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgHJBu6haEaBQmAupVj +yTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7fpYn +Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy +yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n +wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6 +OV+KmalBWQewLK8= +-----END CERTIFICATE----- + +# Issuer: CN=Certainly Root E1 O=Certainly +# Subject: CN=Certainly Root E1 O=Certainly +# Label: "Certainly Root E1" +# Serial: 8168531406727139161245376702891150584 +# MD5 Fingerprint: 0a:9e:ca:cd:3e:52:50:c6:36:f3:4b:a3:ed:a7:53:e9 +# SHA1 Fingerprint: f9:e1:6d:dc:01:89:cf:d5:82:45:63:3e:c5:37:7d:c2:eb:93:6f:2b +# SHA256 Fingerprint: b4:58:5f:22:e4:ac:75:6a:4e:86:12:a1:36:1c:5d:9d:03:1a:93:fd:84:fe:bb:77:8f:a3:06:8b:0f:c4:2d:c2 +-----BEGIN CERTIFICATE----- +MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw +CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu +bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ +BgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlubHkxGjAYBgNVBAMTEUNlcnRhaW5s +eSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4fxzf7flHh4axpMCK ++IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9YBk2 +QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4 +hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm +ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG +BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR +-----END CERTIFICATE----- + +# Issuer: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. +# Subject: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. +# Label: "Security Communication ECC RootCA1" +# Serial: 15446673492073852651 +# MD5 Fingerprint: 7e:43:b0:92:68:ec:05:43:4c:98:ab:5d:35:2e:7e:86 +# SHA1 Fingerprint: b8:0e:26:a9:bf:d2:b2:3b:c0:ef:46:c9:ba:c7:bb:f6:1d:0d:41:41 +# SHA256 Fingerprint: e7:4f:bd:a5:5b:d5:64:c4:73:a3:6b:44:1a:a7:99:c8:a6:8e:07:74:40:e8:28:8b:9f:a1:e5:0e:4b:ba:ca:11 +-----BEGIN CERTIFICATE----- +MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYT +AkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYD +VQQDEyJTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYx +NjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTELMAkGA1UEBhMCSlAxJTAjBgNVBAoT +HFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNVBAMTIlNlY3VyaXR5 +IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+Cnnfdl +dB9sELLo5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpK +ULGjQjBAMB0GA1UdDgQWBBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu +9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3LsnNdo4gIxwwCMQDAqy0O +be0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70eN9k= +-----END CERTIFICATE----- + +# Issuer: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY +# Subject: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY +# Label: "BJCA Global Root CA1" +# Serial: 113562791157148395269083148143378328608 +# MD5 Fingerprint: 42:32:99:76:43:33:36:24:35:07:82:9b:28:f9:d0:90 +# SHA1 Fingerprint: d5:ec:8d:7b:4c:ba:79:f4:e7:e8:cb:9d:6b:ae:77:83:10:03:21:6a +# SHA256 Fingerprint: f3:89:6f:88:fe:7c:0a:88:27:66:a7:fa:6a:d2:74:9f:b5:7a:7f:3e:98:fb:76:9c:1f:a7:b0:9c:2c:44:d5:ae +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBU +MQswCQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRI +T1JJVFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAz +MTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJF +SUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2Jh +bCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFmCL3Z +xRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZ +spDyRhySsTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O5 +58dnJCNPYwpj9mZ9S1WnP3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgR +at7GGPZHOiJBhyL8xIkoVNiMpTAK+BcWyqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll +5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRjeulumijWML3mG90Vr4Tq +nMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNnMoH1V6XK +V0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/ +pj+bOT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZO +z2nxbkRs1CTqjSShGL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXn +jSXWgXSHRtQpdaJCbPdzied9v3pKH9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+ +WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMBAAGjQjBAMB0GA1UdDgQWBBTF +7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4 +YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3Kli +awLwQ8hOnThJdMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u ++2D2/VnGKhs/I0qUJDAnyIm860Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88 +X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuhTaRjAv04l5U/BXCga99igUOLtFkN +SoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW4AB+dAb/OMRyHdOo +P2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmpGQrI ++pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRz +znfSxqxx4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9 +eVzYH6Eze9mCUAyTF6ps3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2 +YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4SSPfSKcOYKMryMguTjClPPGAyzQWWYezy +r/6zcCwupvI= +-----END CERTIFICATE----- + +# Issuer: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY +# Subject: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY +# Label: "BJCA Global Root CA2" +# Serial: 58605626836079930195615843123109055211 +# MD5 Fingerprint: 5e:0a:f6:47:5f:a6:14:e8:11:01:95:3f:4d:01:eb:3c +# SHA1 Fingerprint: f4:27:86:eb:6e:b8:6d:88:31:67:02:fb:ba:66:a4:53:00:aa:7a:a6 +# SHA256 Fingerprint: 57:4d:f6:93:1e:27:80:39:66:7b:72:0a:fd:c1:60:0f:c2:7e:b6:6d:d3:09:29:79:fb:73:85:64:87:21:28:82 +-----BEGIN CERTIFICATE----- +MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQsw +CQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJ +VFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgy +MVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJ +TkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2JhbCBS +b290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jlSR9B +IgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK+ ++kpRuDCK/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJK +sVF/BvDRgh9Obl+rg/xI1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA +94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8gUXOQwKhbYdDFUDn9hf7B +43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== +-----END CERTIFICATE----- + +# Issuer: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited +# Subject: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited +# Label: "Sectigo Public Server Authentication Root E46" +# Serial: 88989738453351742415770396670917916916 +# MD5 Fingerprint: 28:23:f8:b2:98:5c:37:16:3b:3e:46:13:4e:b0:b3:01 +# SHA1 Fingerprint: ec:8a:39:6c:40:f0:2e:bc:42:75:d4:9f:ab:1c:1a:5b:67:be:d2:9a +# SHA256 Fingerprint: c9:0f:26:f0:fb:1b:40:18:b2:22:27:51:9b:5c:a2:b5:3e:2c:a5:b3:be:5c:f1:8e:fe:1b:ef:47:38:0c:53:83 +-----BEGIN CERTIFICATE----- +MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw +CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T +ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN +MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG +A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT +ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC +WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+ +6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B +Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa +qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q +4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw== +-----END CERTIFICATE----- + +# Issuer: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited +# Subject: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited +# Label: "Sectigo Public Server Authentication Root R46" +# Serial: 156256931880233212765902055439220583700 +# MD5 Fingerprint: 32:10:09:52:00:d5:7e:6c:43:df:15:c0:b1:16:93:e5 +# SHA1 Fingerprint: ad:98:f9:f3:e4:7d:75:3b:65:d4:82:b3:a4:52:17:bb:6e:f5:e4:38 +# SHA256 Fingerprint: 7b:b6:47:a6:2a:ee:ac:88:bf:25:7a:a5:22:d0:1f:fe:a3:95:e0:ab:45:c7:3f:93:f6:56:54:ec:38:f2:5a:06 +-----BEGIN CERTIFICATE----- +MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD +Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw +HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY +MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp +YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa +ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz +SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf +iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X +ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3 +IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS +VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE +SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu ++Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt +8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L +HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt +zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P +AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c +mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ +YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52 +gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA +Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB +JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX +DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui +TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5 +dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65 +LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp +0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY +QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation +# Subject: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation +# Label: "SSL.com TLS RSA Root CA 2022" +# Serial: 148535279242832292258835760425842727825 +# MD5 Fingerprint: d8:4e:c6:59:30:d8:fe:a0:d6:7a:5a:2c:2c:69:78:da +# SHA1 Fingerprint: ec:2c:83:40:72:af:26:95:10:ff:0e:f2:03:ee:31:70:f6:78:9d:ca +# SHA256 Fingerprint: 8f:af:7d:2e:2c:b4:70:9b:b8:e0:b3:36:66:bf:75:a5:dd:45:b5:de:48:0f:8e:a8:d4:bf:e6:be:bc:17:f2:ed +-----BEGIN CERTIFICATE----- +MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO +MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD +DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX +DTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jw +b3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJvb3QgQ0EgMjAyMjCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u9nTP +L3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OY +t6/wNr/y7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0ins +S657Lb85/bRi3pZ7QcacoOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3 +PnxEX4MN8/HdIGkWCVDi1FW24IBydm5MR7d1VVm0U3TZlMZBrViKMWYPHqIbKUBO +L9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDGD6C1vBdOSHtRwvzpXGk3 +R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEWTO6Af77w +dr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS ++YCk8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYS +d66UNHsef8JmAOSqg+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoG +AtUjHBPW6dvbxrB6y3snm/vg1UYk7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2f +gTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j +BBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsuN+7jhHonLs0Z +NbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt +hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsM +QtfhWsSWTVTNj8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvf +R4iyrT7gJ4eLSYwfqUdYe5byiB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJ +DPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjUo3KUQyxi4U5cMj29TH0ZR6LDSeeW +P4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqoENjwuSfr98t67wVy +lrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7EgkaibMOlq +bLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2w +AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q +r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji +Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU +98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation +# Subject: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation +# Label: "SSL.com TLS ECC Root CA 2022" +# Serial: 26605119622390491762507526719404364228 +# MD5 Fingerprint: 99:d7:5c:f1:51:36:cc:e9:ce:d9:19:2e:77:71:56:c5 +# SHA1 Fingerprint: 9f:5f:d9:1a:54:6d:f5:0c:71:f0:ee:7a:bd:17:49:98:84:73:e2:39 +# SHA256 Fingerprint: c3:2f:fd:9f:46:f9:36:d1:6c:36:73:99:09:59:43:4b:9a:d6:0a:af:bb:9e:7c:f3:36:54:f1:44:cc:1b:a1:43 +-----BEGIN CERTIFICATE----- +MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQsw +CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxT +U0wuY29tIFRMUyBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2 +MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3Jh +dGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3QgQ0EgMjAyMjB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWyJGYm +acCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFN +SeR7T5v15wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME +GDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW +uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp +15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeN +b0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g== +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos +# Subject: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos +# Label: "Atos TrustedRoot Root CA ECC TLS 2021" +# Serial: 81873346711060652204712539181482831616 +# MD5 Fingerprint: 16:9f:ad:f1:70:ad:79:d6:ed:29:b4:d1:c5:79:70:a8 +# SHA1 Fingerprint: 9e:bc:75:10:42:b3:02:f3:81:f4:f7:30:62:d4:8f:c3:a7:51:b2:dd +# SHA256 Fingerprint: b2:fa:e5:3e:14:cc:d7:ab:92:12:06:47:01:ae:27:9c:1d:89:88:fa:cb:77:5f:a8:a0:08:91:4e:66:39:88:a8 +-----BEGIN CERTIFICATE----- +MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4w +LAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0w +CwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0 +MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBF +Q0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMHYwEAYHKoZI +zj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6KDP/X +tXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4 +AjJn8ZQSb+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2 +KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD +aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtu +CCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo +9H1/IISpQuQo +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos +# Subject: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos +# Label: "Atos TrustedRoot Root CA RSA TLS 2021" +# Serial: 111436099570196163832749341232207667876 +# MD5 Fingerprint: d4:d3:46:b8:9a:c0:9c:76:5d:9e:3a:c3:b9:99:31:d2 +# SHA1 Fingerprint: 18:52:3b:0d:06:37:e4:d6:3a:df:23:e4:98:fb:5b:16:fb:86:74:48 +# SHA256 Fingerprint: 81:a9:08:8e:a5:9f:b3:64:c5:48:a6:f8:55:59:09:9b:6f:04:05:ef:bf:18:e5:32:4e:c9:f4:57:ba:00:11:2f +-----BEGIN CERTIFICATE----- +MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBM +MS4wLAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIx +MQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00 +MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBD +QSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BBl01Z +4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYv +Ye+W/CBGvevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZ +kmGbzSoXfduP9LVq6hdKZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDs +GY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt0xU6kGpn8bRrZtkh68rZYnxGEFzedUln +nkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVKPNe0OwANwI8f4UDErmwh +3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMYsluMWuPD +0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzy +geBYBr3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8 +ANSbhqRAvNncTFd+rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezB +c6eUWsuSZIKmAMFwoW4sKeFYV+xafJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lI +pw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +dEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +DAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS +4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPs +o0UvFJ/1TCplQ3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJ +qM7F78PRreBrAwA0JrRUITWXAdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuyw +xfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9GslA9hGCZcbUztVdF5kJHdWoOsAgM +rr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2VktafcxBPTy+av5EzH4 +AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9qTFsR +0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuY +o7Ey7Nmj1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5 +dDTedk+SKlOxJTnbPP/lPqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcE +oji2jbDwN/zIIX8/syQbPYtuzE2wFg2WHYMfRsCbvUOZ58SWLs5fyQ== +-----END CERTIFICATE----- + +# Issuer: CN=TrustAsia Global Root CA G3 O=TrustAsia Technologies, Inc. +# Subject: CN=TrustAsia Global Root CA G3 O=TrustAsia Technologies, Inc. +# Label: "TrustAsia Global Root CA G3" +# Serial: 576386314500428537169965010905813481816650257167 +# MD5 Fingerprint: 30:42:1b:b7:bb:81:75:35:e4:16:4f:53:d2:94:de:04 +# SHA1 Fingerprint: 63:cf:b6:c1:27:2b:56:e4:88:8e:1c:23:9a:b6:2e:81:47:24:c3:c7 +# SHA256 Fingerprint: e0:d3:22:6a:eb:11:63:c2:e4:8f:f9:be:3b:50:b4:c6:43:1b:e7:bb:1e:ac:c5:c3:6b:5d:5e:c5:09:03:9a:08 +-----BEGIN CERTIFICATE----- +MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEM +BQAwWjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dp +ZXMsIEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAe +Fw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEwMTlaMFoxCzAJBgNVBAYTAkNOMSUw +IwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtU +cnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNS +T1QY4SxzlZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqK +AtCWHwDNBSHvBm3dIZwZQ0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1 +nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/VP68czH5GX6zfZBCK70bwkPAPLfSIC7Ep +qq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1AgdB4SQXMeJNnKziyhWTXA +yB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm9WAPzJMs +hH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gX +zhqcD0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAv +kV34PmVACxmZySYgWmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msT +f9FkPz2ccEblooV7WIQn3MSAPmeamseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jA +uPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCFTIcQcf+eQxuulXUtgQIDAQAB +o2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj7zjKsK5Xf/Ih +MBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E +BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4 +wM8zAQLpw6o1D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2 +XFNFV1pF1AWZLy4jVe5jaN/TG3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1 +JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNjduMNhXJEIlU/HHzp/LgV6FL6qj6j +ITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstlcHboCoWASzY9M/eV +VHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys+TIx +xHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1on +AX1daBli2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d +7XB4tmBZrOFdRWOPyN9yaFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2Ntjj +gKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsASZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV ++Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFRJQJ6+N1rZdVtTTDIZbpo +FGWsJwt0ivKH +-----END CERTIFICATE----- + +# Issuer: CN=TrustAsia Global Root CA G4 O=TrustAsia Technologies, Inc. +# Subject: CN=TrustAsia Global Root CA G4 O=TrustAsia Technologies, Inc. +# Label: "TrustAsia Global Root CA G4" +# Serial: 451799571007117016466790293371524403291602933463 +# MD5 Fingerprint: 54:dd:b2:d7:5f:d8:3e:ed:7c:e0:0b:2e:cc:ed:eb:eb +# SHA1 Fingerprint: 57:73:a5:61:5d:80:b2:e6:ac:38:82:fc:68:07:31:ac:9f:b5:92:5a +# SHA256 Fingerprint: be:4b:56:cb:50:56:c0:13:6a:52:6d:f4:44:50:8d:aa:36:a0:b5:4f:42:e4:ac:38:f7:2a:f4:70:e4:79:65:4c +-----BEGIN CERTIFICATE----- +MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMw +WjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs +IEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0y +MTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJaMFoxCzAJBgNVBAYTAkNOMSUwIwYD +VQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtUcnVz +dEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATx +s8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbw +LxYI+hW8m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJij +YzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mD +pm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/pDHel4NZg6ZvccveMA4GA1UdDwEB/wQE +AwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AAbbd+NvBNEU/zy4k6LHiR +UKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xkdUfFVZDj +/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA== +-----END CERTIFICATE----- + +# Issuer: CN=Telekom Security TLS ECC Root 2020 O=Deutsche Telekom Security GmbH +# Subject: CN=Telekom Security TLS ECC Root 2020 O=Deutsche Telekom Security GmbH +# Label: "Telekom Security TLS ECC Root 2020" +# Serial: 72082518505882327255703894282316633856 +# MD5 Fingerprint: c1:ab:fe:6a:10:2c:03:8d:bc:1c:22:32:c0:85:a7:fd +# SHA1 Fingerprint: c0:f8:96:c5:a9:3b:01:06:21:07:da:18:42:48:bc:e9:9d:88:d5:ec +# SHA256 Fingerprint: 57:8a:f4:de:d0:85:3f:4e:59:98:db:4a:ea:f9:cb:ea:8d:94:5f:60:b6:20:a3:8d:1a:3c:13:b2:bc:7b:a8:e1 +-----BEGIN CERTIFICATE----- +MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQsw +CQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBH +bWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIw +MB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIzNTk1OVowYzELMAkGA1UEBhMCREUx +JzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkGA1UE +AwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/O +tdKPD/M12kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDP +f8iAC8GXs7s1J8nCG6NCMEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6f +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2cA +MGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZMo7k+5Dck2TOrbRBR2Di +z6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdUga/sf+Rn +27iQ7t0l +-----END CERTIFICATE----- + +# Issuer: CN=Telekom Security TLS RSA Root 2023 O=Deutsche Telekom Security GmbH +# Subject: CN=Telekom Security TLS RSA Root 2023 O=Deutsche Telekom Security GmbH +# Label: "Telekom Security TLS RSA Root 2023" +# Serial: 44676229530606711399881795178081572759 +# MD5 Fingerprint: bf:5b:eb:54:40:cd:48:71:c4:20:8d:7d:de:0a:42:f2 +# SHA1 Fingerprint: 54:d3:ac:b3:bd:57:56:f6:85:9d:ce:e5:c3:21:e2:d4:ad:83:d0:93 +# SHA256 Fingerprint: ef:c6:5c:ad:bb:59:ad:b6:ef:e8:4d:a2:23:11:b3:56:24:b7:1b:3b:1e:a0:da:8b:66:55:17:4e:c8:97:86:46 +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBj +MQswCQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0 +eSBHbWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAy +MDIzMB4XDTIzMDMyODEyMTY0NVoXDTQ4MDMyNzIzNTk1OVowYzELMAkGA1UEBhMC +REUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkG +A1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgUlNBIFJvb3QgMjAyMzCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAO01oYGA88tKaVvC+1GDrib94W7zgRJ9 +cUD/h3VCKSHtgVIs3xLBGYSJwb3FKNXVS2xE1kzbB5ZKVXrKNoIENqil/Cf2SfHV +cp6R+SPWcHu79ZvB7JPPGeplfohwoHP89v+1VmLhc2o0mD6CuKyVU/QBoCcHcqMA +U6DksquDOFczJZSfvkgdmOGjup5czQRxUX11eKvzWarE4GC+j4NSuHUaQTXtvPM6 +Y+mpFEXX5lLRbtLevOP1Czvm4MS9Q2QTps70mDdsipWol8hHD/BeEIvnHRz+sTug +BTNoBUGCwQMrAcjnj02r6LX2zWtEtefdi+zqJbQAIldNsLGyMcEWzv/9FIS3R/qy +8XDe24tsNlikfLMR0cN3f1+2JeANxdKz+bi4d9s3cXFH42AYTyS2dTd4uaNir73J +co4vzLuu2+QVUhkHM/tqty1LkCiCc/4YizWN26cEar7qwU02OxY2kTLvtkCJkUPg +8qKrBC7m8kwOFjQgrIfBLX7JZkcXFBGk8/ehJImr2BrIoVyxo/eMbcgByU/J7MT8 +rFEz0ciD0cmfHdRHNCk+y7AO+oMLKFjlKdw/fKifybYKu6boRhYPluV75Gp6SG12 +mAWl3G0eQh5C2hrgUve1g8Aae3g1LDj1H/1Joy7SWWO/gLCMk3PLNaaZlSJhZQNg ++y+TS/qanIA7AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtqeX +gj10hZv3PJ+TmpV5dVKMbUcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS2 +p5eCPXSFm/c8n5OalXl1UoxtRzANBgkqhkiG9w0BAQwFAAOCAgEAqMxhpr51nhVQ +pGv7qHBFfLp+sVr8WyP6Cnf4mHGCDG3gXkaqk/QeoMPhk9tLrbKmXauw1GLLXrtm +9S3ul0A8Yute1hTWjOKWi0FpkzXmuZlrYrShF2Y0pmtjxrlO8iLpWA1WQdH6DErw +M807u20hOq6OcrXDSvvpfeWxm4bu4uB9tPcy/SKE8YXJN3nptT+/XOR0so8RYgDd +GGah2XsjX/GO1WfoVNpbOms2b/mBsTNHM3dA+VKq3dSDz4V4mZqTuXNnQkYRIer+ +CqkbGmVps4+uFrb2S1ayLfmlyOw7YqPta9BO1UAJpB+Y1zqlklkg5LB9zVtzaL1t +xKITDmcZuI1CfmwMmm6gJC3VRRvcxAIU/oVbZZfKTpBQCHpCNfnqwmbU+AGuHrS+ +w6jv/naaoqYfRvaE7fzbzsQCzndILIyy7MMAo+wsVRjBfhnu4S/yrYObnqsZ38aK +L4x35bcF7DvB7L6Gs4a8wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+lj +X273CXE2whJdV/LItM3z7gLfEdxquVeEHVlNjM7IDiPCtyaaEBRx/pOyiriA8A4Q +ntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0o82bNSQ3+pCTE4FCxpgm +dTdmQRCsu/WU48IxK63nI1bMNSWSs1A= +-----END CERTIFICATE----- + +# Issuer: CN=TWCA CYBER Root CA O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA CYBER Root CA O=TAIWAN-CA OU=Root CA +# Label: "TWCA CYBER Root CA" +# Serial: 85076849864375384482682434040119489222 +# MD5 Fingerprint: 0b:33:a0:97:52:95:d4:a9:fd:bb:db:6e:a3:55:5b:51 +# SHA1 Fingerprint: f6:b1:1c:1a:83:38:e9:7b:db:b3:a8:c8:33:24:e0:2d:9c:7f:26:66 +# SHA256 Fingerprint: 3f:63:bb:28:14:be:17:4e:c8:b6:43:9c:f0:8d:6d:56:f0:b7:c4:05:88:3a:56:48:a3:34:42:4d:6b:3e:c5:58 +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQ +MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290 +IENBMRswGQYDVQQDExJUV0NBIENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5 +WhcNNDcxMTIyMTU1OTU5WjBQMQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FO +LUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NBIENZQkVSIFJvb3Qg +Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDG+Moe2Qkgfh1sTs6P +40czRJzHyWmqOlt47nDSkvgEs1JSHWdyKKHfi12VCv7qze33Kc7wb3+szT3vsxxF +avcokPFhV8UMxKNQXd7UtcsZyoC5dc4pztKFIuwCY8xEMCDa6pFbVuYdHNWdZsc/ +34bKS1PE2Y2yHer43CdTo0fhYcx9tbD47nORxc5zb87uEB8aBs/pJ2DFTxnk684i +JkXXYJndzk834H/nY62wuFm40AZoNWDTNq5xQwTxaWV4fPMf88oon1oglWa0zbfu +j3ikRRjpJi+NmykosaS3Om251Bw4ckVYsV7r8Cibt4LK/c/WMw+f+5eesRycnupf +Xtuq3VTpMCEobY5583WSjCb+3MX2w7DfRFlDo7YDKPYIMKoNM+HvnKkHIuNZW0CP +2oi3aQiotyMuRAlZN1vH4xfyIutuOVLF3lSnmMlLIJXcRolftBL5hSmO68gnFSDA +S9TMfAxsNAwmmyYxpjyn9tnQS6Jk/zuZQXLB4HCX8SS7K8R0IrGsayIyJNN4KsDA +oS/xUgXJP+92ZuJF2A09rZXIx4kmyA+upwMu+8Ff+iDhcK2wZSA3M2Cw1a/XDBzC +kHDXShi8fgGwsOsVHkQGzaRP6AzRwyAQ4VRlnrZR0Bp2a0JaWHY06rc3Ga4udfmW +5cFZ95RXKSWNOkyrTZpB0F8mAwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSdhWEUfMFib5do5E83QOGt4A1WNzAd +BgNVHQ4EFgQUnYVhFHzBYm+XaORPN0DhreANVjcwDQYJKoZIhvcNAQEMBQADggIB +AGSPesRiDrWIzLjHhg6hShbNcAu3p4ULs3a2D6f/CIsLJc+o1IN1KriWiLb73y0t +tGlTITVX1olNc79pj3CjYcya2x6a4CD4bLubIp1dhDGaLIrdaqHXKGnK/nZVekZn +68xDiBaiA9a5F/gZbG0jAn/xX9AKKSM70aoK7akXJlQKTcKlTfjF/biBzysseKNn +TKkHmvPfXvt89YnNdJdhEGoHK4Fa0o635yDRIG4kqIQnoVesqlVYL9zZyvpoBJ7t +RCT5dEA7IzOrg1oYJkK2bVS1FmAwbLGg+LhBoF1JSdJlBTrq/p1hvIbZv97Tujqx +f36SNI7JAG7cmL3c7IAFrQI932XtCwP39xaEBDG6k5TY8hL4iuO/Qq+n1M0RFxbI +Qh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY73NxW0Qz +8ppy6rBePm6pUlvscG21h483XjyMnM7k8M4MZ0HMzvaAq07MTFb1wWFZk7Q+ptq4 +NxKfKjLji7gh7MMrZQzvIt6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzX +xeSDwWrruoBa3lwtcHb4yOWHh8qgnaHlIhInD0Q9HWzq1MKLL295q39QpsQZp6F6 +t5b5wR9iWqJDB0BeJsas7a5wFsWqynKKTbDPAYsDP27X +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign Root CA12 O=Cybertrust Japan Co., Ltd. +# Subject: CN=SecureSign Root CA12 O=Cybertrust Japan Co., Ltd. +# Label: "SecureSign Root CA12" +# Serial: 587887345431707215246142177076162061960426065942 +# MD5 Fingerprint: c6:89:ca:64:42:9b:62:08:49:0b:1e:7f:e9:07:3d:e8 +# SHA1 Fingerprint: 7a:22:1e:3d:de:1b:06:ac:9e:c8:47:70:16:8e:3c:e5:f7:6b:06:f4 +# SHA256 Fingerprint: 3f:03:4b:b5:70:4d:44:b2:d0:85:45:a0:20:57:de:93:eb:f3:90:5f:ce:72:1a:cb:c7:30:c0:6d:da:ee:90:4e +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUZvnHwa/swlG07VOX5uaCwysckBYwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28u +LCBMdGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExMjAeFw0yMDA0MDgw +NTM2NDZaFw00MDA0MDgwNTM2NDZaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpD +eWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBS +b290IENBMTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6OcE3emhF +KxS06+QT61d1I02PJC0W6K6OyX2kVzsqdiUzg2zqMoqUm048luT9Ub+ZyZN+v/mt +p7JIKwccJ/VMvHASd6SFVLX9kHrko+RRWAPNEHl57muTH2SOa2SroxPjcf59q5zd +J1M3s6oYwlkm7Fsf0uZlfO+TvdhYXAvA42VvPMfKWeP+bl+sg779XSVOKik71gur +FzJ4pOE+lEa+Ym6b3kaosRbnhW70CEBFEaCeVESE99g2zvVQR9wsMJvuwPWW0v4J +hscGWa5Pro4RmHvzC1KqYiaqId+OJTN5lxZJjfU+1UefNzFJM3IFTQy2VYzxV4+K +h9GtxRESOaCtAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBRXNPN0zwRL1SXm8UC2LEzZLemgrTANBgkqhkiG9w0BAQsF +AAOCAQEAPrvbFxbS8hQBICw4g0utvsqFepq2m2um4fylOqyttCg6r9cBg0krY6Ld +mmQOmFxv3Y67ilQiLUoT865AQ9tPkbeGGuwAtEGBpE/6aouIs3YIcipJQMPTw4WJ +mBClnW8Zt7vPemVV2zfrPIpyMpcemik+rY3moxtt9XUa5rBouVui7mlHJzWhhpmA +8zNL4WukJsPvdFlseqJkth5Ew1DgDzk9qTPxpfPSvWKErI4cqc1avTc7bgoitPQV +55FYxTpE05Uo2cBl6XLK0A+9H7MV2anjpEcJnuDLN/v9vZfVvhgaaaI5gdka9at/ +yOPiZwud9AzqVN/Ssq+xIvEg37xEHA== +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign Root CA14 O=Cybertrust Japan Co., Ltd. +# Subject: CN=SecureSign Root CA14 O=Cybertrust Japan Co., Ltd. +# Label: "SecureSign Root CA14" +# Serial: 575790784512929437950770173562378038616896959179 +# MD5 Fingerprint: 71:0d:72:fa:92:19:65:5e:89:04:ac:16:33:f0:bc:d5 +# SHA1 Fingerprint: dd:50:c0:f7:79:b3:64:2e:74:a2:b8:9d:9f:d3:40:dd:bb:f0:f2:4f +# SHA256 Fingerprint: 4b:00:9c:10:34:49:4f:9a:b5:6b:ba:3b:a1:d6:27:31:fc:4d:20:d8:95:5a:dc:ec:10:a9:25:60:72:61:e3:38 +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIUZNtaDCBO6Ncpd8hQJ6JaJ90t8sswDQYJKoZIhvcNAQEM +BQAwUTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28u +LCBMdGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNDAeFw0yMDA0MDgw +NzA2MTlaFw00NTA0MDgwNzA2MTlaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpD +eWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBS +b290IENBMTQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDF0nqh1oq/ +FjHQmNE6lPxauG4iwWL3pwon71D2LrGeaBLwbCRjOfHw3xDG3rdSINVSW0KZnvOg +vlIfX8xnbacuUKLBl422+JX1sLrcneC+y9/3OPJH9aaakpUqYllQC6KxNedlsmGy +6pJxaeQp8E+BgQQ8sqVb1MWoWWd7VRxJq3qdwudzTe/NCcLEVxLbAQ4jeQkHO6Lo +/IrPj8BGJJw4J+CDnRugv3gVEOuGTgpa/d/aLIJ+7sr2KeH6caH3iGicnPCNvg9J +kdjqOvn90Ghx2+m1K06Ckm9mH+Dw3EzsytHqunQG+bOEkJTRX45zGRBdAuVwpcAQ +0BB8b8VYSbSwbprafZX1zNoCr7gsfXmPvkPx+SgojQlD+Ajda8iLLCSxjVIHvXib +y8posqTdDEx5YMaZ0ZPxMBoH064iwurO8YQJzOAUbn8/ftKChazcqRZOhaBgy/ac +18izju3Gm5h1DVXoX+WViwKkrkMpKBGk5hIwAUt1ax5mnXkvpXYvHUC0bcl9eQjs +0Wq2XSqypWa9a4X0dFbD9ed1Uigspf9mR6XU/v6eVL9lfgHWMI+lNpyiUBzuOIAB +SMbHdPTGrMNASRZhdCyvjG817XsYAFs2PJxQDcqSMxDxJklt33UkN4Ii1+iW/RVL +ApY+B3KVfqs9TC7XyvDf4Fg/LS8EmjijAQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUBpOjCl4oaTeqYR3r6/wtbyPk +86AwDQYJKoZIhvcNAQEMBQADggIBAJaAcgkGfpzMkwQWu6A6jZJOtxEaCnFxEM0E +rX+lRVAQZk5KQaID2RFPeje5S+LGjzJmdSX7684/AykmjbgWHfYfM25I5uj4V7Ib +ed87hwriZLoAymzvftAj63iP/2SbNDefNWWipAA9EiOWWF3KY4fGoweITedpdopT +zfFP7ELyk+OZpDc8h7hi2/DsHzc/N19DzFGdtfCXwreFamgLRB7lUe6TzktuhsHS +DCRZNhqfLJGP4xjblJUK7ZGqDpncllPjYYPGFrojutzdfhrGe0K22VoF3Jpf1d+4 +2kd92jjbrDnVHmtsKheMYc2xbXIBw8MgAGJoFjHVdqqGuw6qnsb58Nn4DSEC5MUo +FlkRudlpcyqSeLiSV5sI8jrlL5WwWLdrIBRtFO8KvH7YVdiI2i/6GaX7i+B/OfVy +K4XELKzvGUWSTLNhB9xNH27SgRNcmvMSZ4PPmz+Ln52kuaiWA3rF7iDeM9ovnhp6 +dB7h7sxaOgTdsxoEqBRjrLdHEoOabPXm6RUVkRqEGQ6UROcSjiVbgGcZ3GOTEAtl +Lor6CZpO2oYofaphNdgOpygau1LgePhsumywbrmHXumZNTfxPWQrqaA0k89jL9WB +365jJ6UeTo3cKXhZ+PmhIIynJkBugnLNeLLIjzwec+fBH7/PzqUqm9tEZDKgu39c +JRNItX+S +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign Root CA15 O=Cybertrust Japan Co., Ltd. +# Subject: CN=SecureSign Root CA15 O=Cybertrust Japan Co., Ltd. +# Label: "SecureSign Root CA15" +# Serial: 126083514594751269499665114766174399806381178503 +# MD5 Fingerprint: 13:30:fc:c4:62:a6:a9:de:b5:c1:68:af:b5:d2:31:47 +# SHA1 Fingerprint: cb:ba:83:c8:c1:5a:5d:f1:f9:73:6f:ca:d7:ef:28:13:06:4a:07:7d +# SHA256 Fingerprint: e7:78:f0:f0:95:fe:84:37:29:cd:1a:00:82:17:9e:53:14:a9:c2:91:44:28:05:e1:fb:1d:8f:b6:b8:88:6c:3a +-----BEGIN CERTIFICATE----- +MIICIzCCAamgAwIBAgIUFhXHw9hJp75pDIqI7fBw+d23PocwCgYIKoZIzj0EAwMw +UTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBM +dGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNTAeFw0yMDA0MDgwODMy +NTZaFw00NTA0MDgwODMyNTZaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpDeWJl +cnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBSb290 +IENBMTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQLUHSNZDKZmbPSYAi4Io5GdCx4 +wCtELW1fHcmuS1Iggz24FG1Th2CeX2yF2wYUleDHKP+dX+Sq8bOLbe1PL0vJSpSR +ZHX+AezB2Ot6lHhWGENfa4HL9rzatAy2KZMIaY+jQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTrQciu/NWeUUj1vYv0hyCTQSvT +9DAKBggqhkjOPQQDAwNoADBlAjEA2S6Jfl5OpBEHvVnCB96rMjhTKkZEBhd6zlHp +4P9mLQlO4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJSwdLZrWeqrqgHkHZAXQ6 +bkU6iYAZezKYVWOr62Nuk22rGwlgMU4= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST BR Root CA 2 2023 O=D-Trust GmbH +# Subject: CN=D-TRUST BR Root CA 2 2023 O=D-Trust GmbH +# Label: "D-TRUST BR Root CA 2 2023" +# Serial: 153168538924886464690566649552453098598 +# MD5 Fingerprint: e1:09:ed:d3:60:d4:56:1b:47:1f:b7:0c:5f:1b:5f:85 +# SHA1 Fingerprint: 2d:b0:70:ee:71:94:af:69:68:17:db:79:ce:58:9f:a0:6b:96:f7:87 +# SHA256 Fingerprint: 05:52:e6:f8:3f:df:65:e8:fa:96:70:e6:66:df:28:a4:e2:13:40:b5:10:cb:e5:25:66:f9:7c:4f:b9:4b:2b:d1 +-----BEGIN CERTIFICATE----- +MIIFqTCCA5GgAwIBAgIQczswBEhb2U14LnNLyaHcZjANBgkqhkiG9w0BAQ0FADBI +MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlE +LVRSVVNUIEJSIFJvb3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA4NTYzMVoXDTM4MDUw +OTA4NTYzMFowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEi +MCAGA1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAK7/CVmRgApKaOYkP7in5Mg6CjoWzckjYaCTcfKr +i3OPoGdlYNJUa2NRb0kz4HIHE304zQaSBylSa053bATTlfrdTIzZXcFhfUvnKLNE +gXtRr90zsWh81k5M/itoucpmacTsXld/9w3HnDY25QdgrMBM6ghs7wZ8T1soegj8 +k12b9py0i4a6Ibn08OhZWiihNIQaJZG2tY/vsvmA+vk9PBFy2OMvhnbFeSzBqZCT +Rphny4NqoFAjpzv2gTng7fC5v2Xx2Mt6++9zA84A9H3X4F07ZrjcjrqDy4d2A/wl +2ecjbwb9Z/Pg/4S8R7+1FhhGaRTMBffb00msa8yr5LULQyReS2tNZ9/WtT5PeB+U +cSTq3nD88ZP+npNa5JRal1QMNXtfbO4AHyTsA7oC9Xb0n9Sa7YUsOCIvx9gvdhFP +/Wxc6PWOJ4d/GUohR5AdeY0cW/jPSoXk7bNbjb7EZChdQcRurDhaTyN0dKkSw/bS +uREVMweR2Ds3OmMwBtHFIjYoYiMQ4EbMl6zWK11kJNXuHA7e+whadSr2Y23OC0K+ +0bpwHJwh5Q8xaRfX/Aq03u2AnMuStIv13lmiWAmlY0cL4UEyNEHZmrHZqLAbWt4N +DfTisl01gLmB1IRpkQLLddCNxbU9CZEJjxShFHR5PtbJFR2kWVki3PaKRT08EtY+ +XTIvAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUZ5Dw1t61 +GNVGKX5cq/ieCLxklRAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG +OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfYnJfcm9vdF9jYV8y +XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQA097N3U9swFrktpSHxQCF16+tI +FoE9c+CeJyrrd6kTpGoKWloUMz1oH4Guaf2Mn2VsNELZLdB/eBaxOqwjMa1ef67n +riv6uvw8l5VAk1/DLQOj7aRvU9f6QA4w9QAgLABMjDu0ox+2v5Eyq6+SmNMW5tTR +VFxDWy6u71cqqLRvpO8NVhTaIasgdp4D/Ca4nj8+AybmTNudX0KEPUUDAxxZiMrc +LmEkWqTqJwtzEr5SswrPMhfiHocaFpVIbVrg0M8JkiZmkdijYQ6qgYF/6FKC0ULn +4B0Y+qSFNueG4A3rvNTJ1jxD8V1Jbn6Bm2m1iWKPiFLY1/4nwSPFyysCu7Ff/vtD +hQNGvl3GyiEm/9cCnnRK3PgTFbGBVzbLZVzRHTF36SXDw7IyN9XxmAnkbWOACKsG +koHU6XCPpz+y7YaMgmo1yEJagtFSGkUPFaUA8JR7ZSdXOUPPfH/mvTWze/EZTN46 +ls/pdu4D58JDUjxqgejBWoC9EV2Ta/vH5mQ/u2kc6d0li690yVRAysuTEwrt+2aS +Ecr1wPrYg1UDfNPFIkZ1cGt5SAYqgpq/5usWDiJFAbzdNpQ0qTUmiteXue4Icr80 +knCDgKs4qllo3UCkGJCy89UDyibK79XH4I9TjvAA46jtn/mtd+ArY0+ew+43u3gJ +hJ65bvspmZDogNOfJA== +-----END CERTIFICATE----- + +# Issuer: CN=TrustAsia TLS ECC Root CA O=TrustAsia Technologies, Inc. +# Subject: CN=TrustAsia TLS ECC Root CA O=TrustAsia Technologies, Inc. +# Label: "TrustAsia TLS ECC Root CA" +# Serial: 310892014698942880364840003424242768478804666567 +# MD5 Fingerprint: 09:48:04:77:d2:fc:65:93:71:66:b1:11:95:4f:06:8c +# SHA1 Fingerprint: b5:ec:39:f3:a1:66:37:ae:c3:05:94:57:e2:be:11:be:b7:a1:7f:36 +# SHA256 Fingerprint: c0:07:6b:9e:f0:53:1f:b1:a6:56:d6:7c:4e:be:97:cd:5d:ba:a4:1e:f4:45:98:ac:c2:48:98:78:c9:2d:87:11 +-----BEGIN CERTIFICATE----- +MIICMTCCAbegAwIBAgIUNnThTXxlE8msg1UloD5Sfi9QaMcwCgYIKoZIzj0EAwMw +WDELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs +IEluYy4xIjAgBgNVBAMTGVRydXN0QXNpYSBUTFMgRUNDIFJvb3QgQ0EwHhcNMjQw +NTE1MDU0MTU2WhcNNDQwNTE1MDU0MTU1WjBYMQswCQYDVQQGEwJDTjElMCMGA1UE +ChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywgSW5jLjEiMCAGA1UEAxMZVHJ1c3RB +c2lhIFRMUyBFQ0MgUm9vdCBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLh/pVs/ +AT598IhtrimY4ZtcU5nb9wj/1WrgjstEpvDBjL1P1M7UiFPoXlfXTr4sP/MSpwDp +guMqWzJ8S5sUKZ74LYO1644xST0mYekdcouJtgq7nDM1D9rs3qlKH8kzsaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQULIVTu7FDzTLqnqOH/qKYqKaT6RAw +DgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gAMGUCMFRH18MtYYZI9HlaVQ01 +L18N9mdsd0AaRuf4aFtOJx24mH1/k78ITcTaRTChD15KeAIxAKORh/IRM4PDwYqR +OkwrULG9IpRdNYlzg8WbGf60oenUoWa2AaU2+dhoYSi3dOGiMQ== +-----END CERTIFICATE----- + +# Issuer: CN=TrustAsia TLS RSA Root CA O=TrustAsia Technologies, Inc. +# Subject: CN=TrustAsia TLS RSA Root CA O=TrustAsia Technologies, Inc. +# Label: "TrustAsia TLS RSA Root CA" +# Serial: 160405846464868906657516898462547310235378010780 +# MD5 Fingerprint: 3b:9e:c3:86:0f:34:3c:6b:c5:46:c4:8e:1d:e7:19:12 +# SHA1 Fingerprint: a5:46:50:c5:62:ea:95:9a:1a:a7:04:6f:17:58:c7:29:53:3d:03:fa +# SHA256 Fingerprint: 06:c0:8d:7d:af:d8:76:97:1e:b1:12:4f:e6:7f:84:7e:c0:c7:a1:58:d3:ea:53:cb:e9:40:e2:ea:97:91:f4:c3 +-----BEGIN CERTIFICATE----- +MIIFgDCCA2igAwIBAgIUHBjYz+VTPyI1RlNUJDxsR9FcSpwwDQYJKoZIhvcNAQEM +BQAwWDELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dp +ZXMsIEluYy4xIjAgBgNVBAMTGVRydXN0QXNpYSBUTFMgUlNBIFJvb3QgQ0EwHhcN +MjQwNTE1MDU0MTU3WhcNNDQwNTE1MDU0MTU2WjBYMQswCQYDVQQGEwJDTjElMCMG +A1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywgSW5jLjEiMCAGA1UEAxMZVHJ1 +c3RBc2lhIFRMUyBSU0EgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC +AgoCggIBAMMWuBtqpERz5dZO9LnPWwvB0ZqB9WOwj0PBuwhaGnrhB3YmH49pVr7+ +NmDQDIPNlOrnxS1cLwUWAp4KqC/lYCZUlviYQB2srp10Zy9U+5RjmOMmSoPGlbYJ +Q1DNDX3eRA5gEk9bNb2/mThtfWza4mhzH/kxpRkQcwUqwzIZheo0qt1CHjCNP561 +HmHVb70AcnKtEj+qpklz8oYVlQwQX1Fkzv93uMltrOXVmPGZLmzjyUT5tUMnCE32 +ft5EebuyjBza00tsLtbDeLdM1aTk2tyKjg7/D8OmYCYozza/+lcK7Fs/6TAWe8Tb +xNRkoDD75f0dcZLdKY9BWN4ArTr9PXwaqLEX8E40eFgl1oUh63kd0Nyrz2I8sMeX +i9bQn9P+PN7F4/w6g3CEIR0JwqH8uyghZVNgepBtljhb//HXeltt08lwSUq6HTrQ +UNoyIBnkiz/r1RYmNzz7dZ6wB3C4FGB33PYPXFIKvF1tjVEK2sUYyJtt3LCDs3+j +TnhMmCWr8n4uIF6CFabW2I+s5c0yhsj55NqJ4js+k8UTav/H9xj8Z7XvGCxUq0DT +bE3txci3OE9kxJRMT6DNrqXGJyV1J23G2pyOsAWZ1SgRxSHUuPzHlqtKZFlhaxP8 +S8ySpg+kUb8OWJDZgoM5pl+z+m6Ss80zDoWo8SnTq1mt1tve1CuBAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLgHkXlcBvRG/XtZylomkadFK/hT +MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQwFAAOCAgEAIZtqBSBdGBanEqT3 +Rz/NyjuujsCCztxIJXgXbODgcMTWltnZ9r96nBO7U5WS/8+S4PPFJzVXqDuiGev4 +iqME3mmL5Dw8veWv0BIb5Ylrc5tvJQJLkIKvQMKtuppgJFqBTQUYo+IzeXoLH5Pt +7DlK9RME7I10nYEKqG/odv6LTytpEoYKNDbdgptvT+Bz3Ul/KD7JO6NXBNiT2Twp +2xIQaOHEibgGIOcberyxk2GaGUARtWqFVwHxtlotJnMnlvm5P1vQiJ3koP26TpUJ +g3933FEFlJ0gcXax7PqJtZwuhfG5WyRasQmr2soaB82G39tp27RIGAAtvKLEiUUj +pQ7hRGU+isFqMB3iYPg6qocJQrmBktwliJiJ8Xw18WLK7nn4GS/+X/jbh87qqA8M +pugLoDzga5SYnH+tBuYc6kIQX+ImFTw3OffXvO645e8D7r0i+yiGNFjEWn9hongP +XvPKnbwbPKfILfanIhHKA9jnZwqKDss1jjQ52MjqjZ9k4DewbNfFj8GQYSbbJIwe +SsCI3zWQzj8C9GRh3sfIB5XeMhg6j6JCQCTl1jNdfK7vsU1P1FeQNWrcrgSXSYk0 +ly4wBOeY99sLAZDBHwo/+ML+TvrbmnNzFrwFuHnYWa8G5z9nODmxfKuU4CkUpijy +323imttUQ/hHWKNddBWcwauwxzQ= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST EV Root CA 2 2023 O=D-Trust GmbH +# Subject: CN=D-TRUST EV Root CA 2 2023 O=D-Trust GmbH +# Label: "D-TRUST EV Root CA 2 2023" +# Serial: 139766439402180512324132425437959641711 +# MD5 Fingerprint: 96:b4:78:09:f0:09:cb:77:eb:bb:1b:4d:6f:36:bc:b6 +# SHA1 Fingerprint: a5:5b:d8:47:6c:8f:19:f7:4c:f4:6d:6b:b6:c2:79:82:22:df:54:8b +# SHA256 Fingerprint: 8e:82:21:b2:e7:d4:00:78:36:a1:67:2f:0d:cc:29:9c:33:bc:07:d3:16:f1:32:fa:1a:20:6d:58:71:50:f1:ce +-----BEGIN CERTIFICATE----- +MIIFqTCCA5GgAwIBAgIQaSYJfoBLTKCnjHhiU19abzANBgkqhkiG9w0BAQ0FADBI +MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlE +LVRSVVNUIEVWIFJvb3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA5MTAzM1oXDTM4MDUw +OTA5MTAzMlowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEi +MCAGA1UEAxMZRC1UUlVTVCBFViBSb290IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBANiOo4mAC7JXUtypU0w3uX9jFxPvp1sjW2l1sJkK +F8GLxNuo4MwxusLyzV3pt/gdr2rElYfXR8mV2IIEUD2BCP/kPbOx1sWy/YgJ25yE +7CUXFId/MHibaljJtnMoPDT3mfd/06b4HEV8rSyMlD/YZxBTfiLNTiVR8CUkNRFe +EMbsh2aJgWi6zCudR3Mfvc2RpHJqnKIbGKBv7FD0fUDCqDDPvXPIEysQEx6Lmqg6 +lHPTGGkKSv/BAQP/eX+1SH977ugpbzZMlWGG2Pmic4ruri+W7mjNPU0oQvlFKzIb +RlUWaqZLKfm7lVa/Rh3sHZMdwGWyH6FDrlaeoLGPaxK3YG14C8qKXO0elg6DpkiV +jTujIcSuWMYAsoS0I6SWhjW42J7YrDRJmGOVxcttSEfi8i4YHtAxq9107PncjLgc +jmgjutDzUNzPZY9zOjLHfP7KgiJPvo5iR2blzYfi6NUPGJ/lBHJLRjwQ8kTCZFZx +TnXonMkmdMV9WdEKWw9t/p51HBjGGjp82A0EzM23RWV6sY+4roRIPrN6TagD4uJ+ +ARZZaBhDM7DS3LAaQzXupdqpRlyuhoFBAUp0JuyfBr/CBTdkdXgpaP3F9ev+R/nk +hbDhezGdpn9yo7nELC7MmVcOIQxFAZRl62UJxmMiCzNJkkg8/M3OsD6Onov4/knF +NXJHAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUqvyREBuH +kV8Wub9PS5FeAByxMoAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG +OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfZXZfcm9vdF9jYV8y +XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQCTy6UfmRHsmg1fLBWTxj++EI14 +QvBukEdHjqOSMo1wj/Zbjb6JzkcBahsgIIlbyIIQbODnmaprxiqgYzWRaoUlrRc4 +pZt+UPJ26oUFKidBK7GB0aL2QHWpDsvxVUjY7NHss+jOFKE17MJeNRqrphYBBo7q +3C+jisosketSjl8MmxfPy3MHGcRqwnNU73xDUmPBEcrCRbH0O1P1aa4846XerOhU +t7KR/aypH/KH5BfGSah82ApB9PI+53c0BFLd6IHyTS9URZ0V4U/M5d40VxDJI3IX +cI1QcB9WbMy5/zpaT2N6w25lBx2Eof+pDGOJbbJAiDnXH3dotfyc1dZnaVuodNv8 +ifYbMvekJKZ2t0dT741Jj6m2g1qllpBFYfXeA08mD6iL8AOWsKwV0HFaanuU5nCT +2vFp4LJiTZ6P/4mdm13NRemUAiKN4DV/6PEEeXFsVIP4M7kFMhtYVRFP0OUnR3Hs +7dpn1mKmS00PaaLJvOwiS5THaJQXfuKOKD62xur1NGyfN4gHONuGcfrNlUhDbqNP +gofXNJhuS5N5YHVpD/Aa1VP6IQzCP+k/HxiMkl14p3ZnGbuy6n/pcAlWVqOwDAst +Nl7F6cTVg8uGF5csbBNvh1qvSaYd2804BC5f4ko1Di1L+KIkBI3Y4WNeApI02phh +XBxvWHZks/wCuPWdCg== +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign RSA TLS Root CA 2022 - 1 O=SwissSign AG +# Subject: CN=SwissSign RSA TLS Root CA 2022 - 1 O=SwissSign AG +# Label: "SwissSign RSA TLS Root CA 2022 - 1" +# Serial: 388078645722908516278762308316089881486363258315 +# MD5 Fingerprint: 16:2e:e4:19:76:81:85:ba:8e:91:58:f1:15:ef:72:39 +# SHA1 Fingerprint: 81:34:0a:be:4c:cd:ce:cc:e7:7d:cc:8a:d4:57:e2:45:a0:77:5d:ce +# SHA256 Fingerprint: 19:31:44:f4:31:e0:fd:db:74:07:17:d4:de:92:6a:57:11:33:88:4b:43:60:d3:0e:27:29:13:cb:e6:60:ce:41 +-----BEGIN CERTIFICATE----- +MIIFkzCCA3ugAwIBAgIUQ/oMX04bgBhE79G0TzUfRPSA7cswDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzErMCkGA1UE +AxMiU3dpc3NTaWduIFJTQSBUTFMgUm9vdCBDQSAyMDIyIC0gMTAeFw0yMjA2MDgx +MTA4MjJaFw00NzA2MDgxMTA4MjJaMFExCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxT +d2lzc1NpZ24gQUcxKzApBgNVBAMTIlN3aXNzU2lnbiBSU0EgVExTIFJvb3QgQ0Eg +MjAyMiAtIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDLKmjiC8NX +vDVjvHClO/OMPE5Xlm7DTjak9gLKHqquuN6orx122ro10JFwB9+zBvKK8i5VUXu7 +LCTLf5ImgKO0lPaCoaTo+nUdWfMHamFk4saMla+ju45vVs9xzF6BYQ1t8qsCLqSX +5XH8irCRIFucdFJtrhUnWXjyCcplDn/L9Ovn3KlMd/YrFgSVrpxxpT8q2kFC5zyE +EPThPYxr4iuRR1VPuFa+Rd4iUU1OKNlfGUEGjw5NBuBwQCMBauTLE5tzrE0USJIt +/m2n+IdreXXhvhCxqohAWVTXz8TQm0SzOGlkjIHRI36qOTw7D59Ke4LKa2/KIj4x +0LDQKhySio/YGZxH5D4MucLNvkEM+KRHBdvBFzA4OmnczcNpI/2aDwLOEGrOyvi5 +KaM2iYauC8BPY7kGWUleDsFpswrzd34unYyzJ5jSmY0lpx+Gs6ZUcDj8fV3oT4MM +0ZPlEuRU2j7yrTrePjxF8CgPBrnh25d7mUWe3f6VWQQvdT/TromZhqwUtKiE+shd +OxtYk8EXlFXIC+OCeYSf8wCENO7cMdWP8vpPlkwGqnj73mSiI80fPsWMvDdUDrta +clXvyFu1cvh43zcgTFeRc5JzrBh3Q4IgaezprClG5QtO+DdziZaKHG29777YtvTK +wP1H8K4LWCDFyB02rpeNUIMmJCn3nTsPBQIDAQABo2MwYTAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBRvjmKLk0Ow4UD2p8P98Q+4 +DxU4pTAdBgNVHQ4EFgQUb45ii5NDsOFA9qfD/fEPuA8VOKUwDQYJKoZIhvcNAQEL +BQADggIBAKwsKUF9+lz1GpUYvyypiqkkVHX1uECry6gkUSsYP2OprphWKwVDIqO3 +10aewCoSPY6WlkDfDDOLazeROpW7OSltwAJsipQLBwJNGD77+3v1dj2b9l4wBlgz +Hqp41eZUBDqyggmNzhYzWUUo8aWjlw5DI/0LIICQ/+Mmz7hkkeUFjxOgdg3XNwwQ +iJb0Pr6VvfHDffCjw3lHC1ySFWPtUnWK50Zpy1FVCypM9fJkT6lc/2cyjlUtMoIc +gC9qkfjLvH4YoiaoLqNTKIftV+Vlek4ASltOU8liNr3CjlvrzG4ngRhZi0Rjn9UM +ZfQpZX+RLOV/fuiJz48gy20HQhFRJjKKLjpHE7iNvUcNCfAWpO2Whi4Z2L6MOuhF +LhG6rlrnub+xzI/goP+4s9GFe3lmozm1O2bYQL7Pt2eLSMkZJVX8vY3PXtpOpvJp +zv1/THfQwUY1mFwjmwJFQ5Ra3bxHrSL+ul4vkSkphnsh3m5kt8sNjzdbowhq6/Td +Ao9QAwKxuDdollDruF/UKIqlIgyKhPBZLtU30WHlQnNYKoH3dtvi4k0NX/a3vgW0 +rk4N3hY9A4GzJl5LuEsAz/+MF7psYC0nhzck5npgL7XTgwSqT0N1osGDsieYK7EO +gLrAhV5Cud+xYJHT6xh+cHiudoO+cVrQkOPKwRYlZ0rwtnu64ZzZ +-----END CERTIFICATE----- + +# Issuer: CN=OISTE Server Root ECC G1 O=OISTE Foundation +# Subject: CN=OISTE Server Root ECC G1 O=OISTE Foundation +# Label: "OISTE Server Root ECC G1" +# Serial: 47819833811561661340092227008453318557 +# MD5 Fingerprint: 42:a7:d2:35:ae:02:92:db:19:76:08:de:2f:05:b4:d4 +# SHA1 Fingerprint: 3b:f6:8b:09:ae:2a:92:7b:ba:e3:8d:3f:11:95:d9:e6:44:0c:45:e2 +# SHA256 Fingerprint: ee:c9:97:c0:c3:0f:21:6f:7e:3b:8b:30:7d:2b:ae:42:41:2d:75:3f:c8:21:9d:af:d1:52:0b:25:72:85:0f:49 +-----BEGIN CERTIFICATE----- +MIICNTCCAbqgAwIBAgIQI/nD1jWvjyhLH/BU6n6XnTAKBggqhkjOPQQDAzBLMQsw +CQYDVQQGEwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UEAwwY +T0lTVEUgU2VydmVyIFJvb3QgRUNDIEcxMB4XDTIzMDUzMTE0NDIyOFoXDTQ4MDUy +NDE0NDIyN1owSzELMAkGA1UEBhMCQ0gxGTAXBgNVBAoMEE9JU1RFIEZvdW5kYXRp +b24xITAfBgNVBAMMGE9JU1RFIFNlcnZlciBSb290IEVDQyBHMTB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABBcv+hK8rBjzCvRE1nZCnrPoH7d5qVi2+GXROiFPqOujvqQy +cvO2Ackr/XeFblPdreqqLiWStukhEaivtUwL85Zgmjvn6hp4LrQ95SjeHIC6XG4N +2xml4z+cKrhAS93mT6NjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBQ3 +TYhlz/w9itWj8UnATgwQb0K0nDAdBgNVHQ4EFgQUN02IZc/8PYrVo/FJwE4MEG9C +tJwwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2kAMGYCMQCpKjAd0MKfkFFR +QD6VVCHNFmb3U2wIFjnQEnx/Yxvf4zgAOdktUyBFCxxgZzFDJe0CMQCSia7pXGKD +YmH5LVerVrkR3SW+ak5KGoJr3M/TvEqzPNcum9v4KGm8ay3sMaE641c= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE Server Root RSA G1 O=OISTE Foundation +# Subject: CN=OISTE Server Root RSA G1 O=OISTE Foundation +# Label: "OISTE Server Root RSA G1" +# Serial: 113845518112613905024960613408179309848 +# MD5 Fingerprint: 23:a7:9e:d4:70:b8:b9:14:57:41:8a:7e:44:59:e2:68 +# SHA1 Fingerprint: f7:00:34:25:94:88:68:31:e4:34:87:3f:70:fe:86:b3:86:9f:f0:6e +# SHA256 Fingerprint: 9a:e3:62:32:a5:18:9f:fd:db:35:3d:fd:26:52:0c:01:53:95:d2:27:77:da:c5:9d:b5:7b:98:c0:89:a6:51:e6 +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIQVaXZZ5Qoxu0M+ifdWwFNGDANBgkqhkiG9w0BAQwFADBL +MQswCQYDVQQGEwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UE +AwwYT0lTVEUgU2VydmVyIFJvb3QgUlNBIEcxMB4XDTIzMDUzMTE0MzcxNloXDTQ4 +MDUyNDE0MzcxNVowSzELMAkGA1UEBhMCQ0gxGTAXBgNVBAoMEE9JU1RFIEZvdW5k +YXRpb24xITAfBgNVBAMMGE9JU1RFIFNlcnZlciBSb290IFJTQSBHMTCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAKqu9KuCz/vlNwvn1ZatkOhLKdxVYOPM +vLO8LZK55KN68YG0nnJyQ98/qwsmtO57Gmn7KNByXEptaZnwYx4M0rH/1ow00O7b +rEi56rAUjtgHqSSY3ekJvqgiG1k50SeH3BzN+Puz6+mTeO0Pzjd8JnduodgsIUzk +ik/HEzxux9UTl7Ko2yRpg1bTacuCErudG/L4NPKYKyqOBGf244ehHa1uzjZ0Dl4z +O8vbUZeUapU8zhhabkvG/AePLhq5SvdkNCncpo1Q4Y2LS+VIG24ugBA/5J8bZT8R +tOpXaZ+0AOuFJJkk9SGdl6r7NH8CaxWQrbueWhl/pIzY+m0o/DjH40ytas7ZTpOS +jswMZ78LS5bOZmdTaMsXEY5Z96ycG7mOaES3GK/m5Q9l3JUJsJMStR8+lKXHiHUh +sd4JJCpM4rzsTGdHwimIuQq6+cF0zowYJmXa92/GjHtoXAvuY8BeS/FOzJ8vD+Ho +mnqT8eDI278n5mUpezbgMxVz8p1rhAhoKzYHKyfMeNhqhw5HdPSqoBNdZH702xSu ++zrkL8Fl47l6QGzwBrd7KJvX4V84c5Ss2XCTLdyEr0YconosP4EmQufU2MVshGYR +i3drVByjtdgQ8K4p92cIiBdcuJd5z+orKu5YM+Vt6SmqZQENghPsJQtdLEByFSnT +kCz3GkPVavBpAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU +8snBDw1jALvsRQ5KH7WxszbNDo0wHQYDVR0OBBYEFPLJwQ8NYwC77EUOSh+1sbM2 +zQ6NMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQwFAAOCAgEANGd5sjrG5T33 +I3K5Ce+SrScfoE4KsvXaFwyihdJ+klH9FWXXXGtkFu6KRcoMQzZENdl//nk6HOjG +5D1rd9QhEOP28yBOqb6J8xycqd+8MDoX0TJD0KqKchxRKEzdNsjkLWd9kYccnbz8 +qyiWXmFcuCIzGEgWUOrKL+mlSdx/PKQZvDatkuK59EvV6wit53j+F8Bdh3foZ3dP +AGav9LEDOr4SfEE15fSmG0eLy3n31r8Xbk5l8PjaV8GUgeV6Vg27Rn9vkf195hfk +gSe7BYhW3SCl95gtkRlpMV+bMPKZrXJAlszYd2abtNUOshD+FKrDgHGdPY3ofRRs +YWSGRqbXVMW215AWRqWFyp464+YTFrYVI8ypKVL9AMb2kI5Wj4kI3Zaq5tNqqYY1 +9tVFeEJKRvwDyF7YZvZFZSS0vod7VSCd9521Kvy5YhnLbDuv0204bKt7ph6N/Ome +/msVuduCmsuY33OhkKCgxeDoAaijFJzIwZqsFVAzje18KotzlUBDJvyBpCpfOZC3 +J8tRd/iWkx7P8nd9H0aTolkelUTFLXVksNb54Dxp6gS1HAviRkRNQzuXSXERvSS2 +wq1yVAb+axj5d9spLFKebXd7Yv0PTY6YMjAwcRLWJTXjn/hvnLXrahut6hDTlhZy +BiElxky8j3C7DOReIoMt0r7+hVu05L0= +-----END CERTIFICATE----- + +# Issuer: CN=e-Szigno TLS Root CA 2023 O=Microsec Ltd. +# Subject: CN=e-Szigno TLS Root CA 2023 O=Microsec Ltd. +# Label: "e-Szigno TLS Root CA 2023" +# Serial: 71934828665710877219916191754 +# MD5 Fingerprint: 6a:e9:99:74:a5:da:5e:f1:d9:2e:f2:c8:d1:86:8b:71 +# SHA1 Fingerprint: 6f:9a:d5:d5:df:e8:2c:eb:be:37:07:ee:4f:4f:52:58:29:41:d1:fe +# SHA256 Fingerprint: b4:91:41:50:2d:00:66:3d:74:0f:2e:7e:c3:40:c5:28:00:96:26:66:12:1a:36:d0:9c:f7:dd:2b:90:38:4f:b4 +-----BEGIN CERTIFICATE----- +MIICzzCCAjGgAwIBAgINAOhvGHvWOWuYSkmYCjAKBggqhkjOPQQDBDB1MQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xFzAVBgNVBGEMDlZBVEhVLTIzNTg0NDk3MSIwIAYDVQQDDBllLVN6aWdubyBU +TFMgUm9vdCBDQSAyMDIzMB4XDTIzMDcxNzE0MDAwMFoXDTM4MDcxNzE0MDAwMFow +dTELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRYwFAYDVQQKDA1NaWNy +b3NlYyBMdGQuMRcwFQYDVQRhDA5WQVRIVS0yMzU4NDQ5NzEiMCAGA1UEAwwZZS1T +emlnbm8gVExTIFJvb3QgQ0EgMjAyMzCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAE +AGgP36J8PKp0iGEKjcJMpQEiFNT3YHdCnAo4YKGMZz6zY+n6kbCLS+Y53wLCMAFS +AL/fjO1ZrTJlqwlZULUZwmgcAOAFX9pQJhzDrAQixTpN7+lXWDajwRlTEArRzT/v +SzUaQ49CE0y5LBqcvjC2xN7cS53kpDzLLtmt3999Cd8ukv+ho2MwYTAPBgNVHRMB +Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUWYQCYlpGePVd3I8K +ECgj3NXW+0UwHwYDVR0jBBgwFoAUWYQCYlpGePVd3I8KECgj3NXW+0UwCgYIKoZI +zj0EAwQDgYsAMIGHAkIBLdqu9S54tma4n7Zwf2Z0z+yOfP7AAXmazlIC58PRDHpt +y7Ve7hekm9sEdu4pKeiv+62sUvTXK9Z3hBC9xdIoaDQCQTV2WnXzkoYI9bIeCvZl +C9p2x1L/Cx6AcCIwwzPbGO2E14vs7dOoY4G1VnxHx1YwlGhza9IuqbnZLBwpvQy6 +uWWL +-----END CERTIFICATE----- diff --git a/CORE/Source/utils/StringBuilderUnit.pas b/CORE/Source/utils/StringBuilderUnit.pas index 37105e0ac..7a1ab659f 100644 --- a/CORE/Source/utils/StringBuilderUnit.pas +++ b/CORE/Source/utils/StringBuilderUnit.pas @@ -1,6 +1,6 @@ unit StringBuilderUnit; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . diff --git a/CORE/Source/utils/uRESTDWBase64.pas b/CORE/Source/utils/uRESTDWBase64.pas index a7ada4fbb..c7eb4d26c 100644 --- a/CORE/Source/utils/uRESTDWBase64.pas +++ b/CORE/Source/utils/uRESTDWBase64.pas @@ -1,21 +1,21 @@ unit uRESTDWBase64; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/utils/uRESTDWDynamic.pas b/CORE/Source/utils/uRESTDWDynamic.pas index c952b6466..5e1195e46 100644 --- a/CORE/Source/utils/uRESTDWDynamic.pas +++ b/CORE/Source/utils/uRESTDWDynamic.pas @@ -1,6 +1,6 @@ unit uRESTDWDynamic; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . diff --git a/CORE/Source/utils/uRESTDWJSONObject.pas b/CORE/Source/utils/uRESTDWJSONObject.pas index 18b53c664..d9361eb4b 100644 --- a/CORE/Source/utils/uRESTDWJSONObject.pas +++ b/CORE/Source/utils/uRESTDWJSONObject.pas @@ -1,6 +1,6 @@ -Unit uRESTDWJSONObject; +Unit uRESTDWJSONObject; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . @@ -4342,7 +4342,7 @@ procedure TRESTDWJSONValue.WriteToDataset2(JSONValue: String; DestDS: TDataset); Else aValue := StringToBytes(Format(TJsonStringValue, [vTempString])); {$ELSE} - aValue := StringToBytes(Format(TJsonStringValue, [IntToStr(bValue)])); + aValue := StringToBytes(Format(TJsonStringValue, [string(bValue)])); {$ENDIF} End Else diff --git a/CORE/Source/utils/uRESTDWMassiveBuffer.pas b/CORE/Source/utils/uRESTDWMassiveBuffer.pas index 6847600f9..0ab6473d5 100644 --- a/CORE/Source/utils/uRESTDWMassiveBuffer.pas +++ b/CORE/Source/utils/uRESTDWMassiveBuffer.pas @@ -1,21 +1,21 @@ unit uRESTDWMassiveBuffer; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -2075,7 +2075,7 @@ implementation Begin MassiveLineBuff.ClearAll; MassiveLineBuff.vMassiveMode := MassiveModeData; - NewLineBuffer(MassiveLineBuff, MassiveModeData, ExecTag); //Sempre se assume mmInsert como padrão + NewLineBuffer(MassiveLineBuff, MassiveModeData, ExecTag); //Sempre se assume mmInsert como padro End; Procedure TMassiveDatasetBuffer.NewBuffer(Var Dataset : TRESTDWClientSQLBase; @@ -2085,8 +2085,8 @@ implementation vMassiveLine.ClearAll; vMassiveLine.vMassiveMode := MassiveModeData; MassiveCheck(Dataset); - NewLineBuffer(vMassiveLine, MassiveModeData, ExecTag); //Sempre se assume mmInsert como padrão - //BuildLine(Dataset, MassiveModeData, vMassiveLine);//Sempre se assume mmInsert como padrão + NewLineBuffer(vMassiveLine, MassiveModeData, ExecTag); //Sempre se assume mmInsert como padro + //BuildLine(Dataset, MassiveModeData, vMassiveLine);//Sempre se assume mmInsert como padro End; Procedure TMassiveDatasetBuffer.NewBuffer(MassiveModeData : TMassiveMode; @@ -2094,7 +2094,7 @@ implementation Begin vMassiveLine.ClearAll; vMassiveLine.vMassiveMode := MassiveModeData; - NewLineBuffer(vMassiveLine, MassiveModeData, ExecTag); //Sempre se assume mmInsert como padrão + NewLineBuffer(vMassiveLine, MassiveModeData, ExecTag); //Sempre se assume mmInsert como padro End; Procedure TMassiveDatasetBuffer.Next; diff --git a/CORE/Source/utils/uRESTDWMimeTypes.pas b/CORE/Source/utils/uRESTDWMimeTypes.pas index 5fdb9eb38..c734c433b 100644 --- a/CORE/Source/utils/uRESTDWMimeTypes.pas +++ b/CORE/Source/utils/uRESTDWMimeTypes.pas @@ -1,21 +1,21 @@ unit uRESTDWMimeTypes; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -135,7 +135,7 @@ procedure TRESTDWMIMEType.FillMIMETable(const AMIMEList: TStringList; GetMIMETableFromOS(AMIMEList); AMIMEList.BeginUpdate; - // adição dos MIMETypes básicos do RDW + // adio dos MIMETypes bsicos do RDW AMIMEList.Add('.323' + '=' + 'text/h323'); AMIMEList.Add('.3g2' + '=' + 'video/3gpp2'); AMIMEList.Add('.3gp' + '=' + 'video/3gpp'); diff --git a/CORE/Source/utils/uRESTDWOpenSslLib.pas b/CORE/Source/utils/uRESTDWOpenSslLib.pas index 60dd24f71..6f470ab61 100644 --- a/CORE/Source/utils/uRESTDWOpenSslLib.pas +++ b/CORE/Source/utils/uRESTDWOpenSslLib.pas @@ -2,22 +2,22 @@ { Cross-platform unified OpenSSL 1.1.1 import and helper library unit for OpenSSL } -{$I ..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -50,42 +50,42 @@ interface LIB_CRYPTO_300 = 'libcrypto-3-x64.dll'; LIB_SSL_300 = 'libssl-3-x64.dll'; _PU = ''; - {$ELSEIF Defined(ANDROID64)} + {$ELSEIF Defined(ANDROID64) or (Defined(CPUAARCH64) and Defined(ANDROID))} LIB_CRYPTO_110 = 'libcrypto-android64.a'; LIB_SSL_110 = 'libssl-android64.a'; LIB_CRYPTO_300 = 'libcrypto-android64.a'; LIB_SSL_300 = 'libssl-android64.a'; _PU = ''; - {$ELSEIF Defined(ANDROID32)} + {$ELSEIF Defined(ANDROID32) or (Defined(CPUARM) and Defined(ANDROID))} LIB_CRYPTO_110 = 'libcrypto-android32.a'; LIB_SSL_110 = 'libssl-android32.a'; LIB_CRYPTO_300 = 'libcrypto-android32.a'; LIB_SSL_300 = 'libssl-android32.a'; _PU = ''; - {$ELSEIF Defined(IOS)} + {$ELSEIF Defined(IOS) or Defined(IOS64) or Defined(DCCIOS32) or Defined(DCCIOSARM64)} LIB_CRYPTO_110 = 'libcrypto-ios.a'; LIB_SSL_110 = 'libssl-ios.a'; LIB_CRYPTO_300 = 'libcrypto-ios.a'; LIB_SSL_300 = 'libssl-ios.a'; _PU = ''; - {$ELSEIF Defined(MACOS32)} + {$ELSEIF Defined(MACOS32) or (Defined(CPUI386) and Defined(DARWIN))} LIB_CRYPTO_110 = 'libssl-merged-osx32.dylib'; LIB_SSL_110 = 'libssl-merged-osx32.dylib'; LIB_CRYPTO_300 = 'libssl-merged-osx32.dylib'; LIB_SSL_300 = 'libssl-merged-osx32.dylib'; _PU = '_'; - {$ELSEIF Defined(MACOS64)} + {$ELSEIF Defined(MACOS64) or (Defined(CPUX86_64) and Defined(DARWIN)) or (Defined(CPUAARCH64) and Defined(DARWIN))} LIB_CRYPTO_110 = 'libcrypto-osx64.a'; LIB_SSL_110 = 'libssl-osx64.a'; LIB_CRYPTO_300 = 'libcrypto-osx64.a'; LIB_SSL_300 = 'libssl-osx64.a'; _PU = ''; - {$ELSEIF Defined(LINUX)} + {$ELSEIF Defined(LINUX) or Defined(FREEBSD)} LIB_CRYPTO_110 = 'libcrypto.so'; LIB_SSL_110 = 'libssl.so'; diff --git a/CORE/Source/utils/uRESTDWTools.pas b/CORE/Source/utils/uRESTDWTools.pas index 1674012f8..ecf4f07bb 100644 --- a/CORE/Source/utils/uRESTDWTools.pas +++ b/CORE/Source/utils/uRESTDWTools.pas @@ -1,19 +1,19 @@ unit uRESTDWTools; -{$I ..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -552,8 +552,8 @@ interface Begin Result := ftUnknown; {$IFDEF FPC} - If DWFieldType = 45 Then //Extended come from Delphi - Result := ftFMTBcd + If DWFieldType = dwftExtended Then + Result := ftFloat Else Begin {$ENDIF} @@ -592,10 +592,8 @@ interface dwftIDispatch : Result := ftIDispatch; dwftGuid : Result := ftGuid; dwftBCD : Result := ftBCD; - dwftExtended : Result := {$IFDEF FPC}ftFMTBcd{$ELSE}ftExtended{$ENDIF}; - {$IFNDEF FPC} - dwftFMTBcd : Result := ftFMTBcd; - {$ENDIF} + dwftExtended : Result := {$IFDEF FPC}ftFloat{$ELSE}ftExtended{$ENDIF}; + dwftFMTBcd : Result := ftFMTBcd; {$IFDEF DELPHI2010UP} dwftTimeStamp : Result := ftTimeStamp; dwftWideString : Result := ftWideString; @@ -678,7 +676,7 @@ interface ftIDispatch : Result := dwftIDispatch; ftGuid : Result := dwftGuid; ftTimeStamp : Result := dwftTimeStamp; - ftFMTBcd : Result := {$IFDEF FPC}45{$ELSE}dwftExtended{$ENDIF}; + ftFMTBcd : Result := dwftFMTBcd; {$IFDEF DELPHI2010UP} // Delphi 2010 acima ftFixedWideChar : Result := dwftFixedWideChar; ftWideMemo : Result := dwftWideMemo; @@ -2338,15 +2336,15 @@ procedure WriteStringToStream(AStream : TStream; (TimeZone:'G'; Offset:'+0700'), // Golf Time Zone - Military {do not localize} (TimeZone:'GMT'; Offset:'+0000'), // Greenwich Mean Time - Europe {do not localize} (TimeZone:'H'; Offset:'+0800'), // Hotel Time Zone - Military {do not localize} - (TimeZone:'HAA'; Offset:'-0300'), // Heure Avancée de l'Atlantique - North America {do not localize} - (TimeZone:'HAC'; Offset:'-0500'), // Heure Avancée du Centre - North America {do not localize} + (TimeZone:'HAA'; Offset:'-0300'), // Heure Avance de l'Atlantique - North America {do not localize} + (TimeZone:'HAC'; Offset:'-0500'), // Heure Avance du Centre - North America {do not localize} (TimeZone:'HADT'; Offset:'-0900'), // Hawaii-Aleutian Daylight Time - North America {do not localize} - (TimeZone:'HAE'; Offset:'-0400'), // Heure Avancée de l'Est - North America {do not localize} - (TimeZone:'HAP'; Offset:'-0700'), // Heure Avancée du Pacifique - North America {do not localize} - (TimeZone:'HAR'; Offset:'-0600'), // Heure Avancée des Rocheuses - North America {do not localize} + (TimeZone:'HAE'; Offset:'-0400'), // Heure Avance de l'Est - North America {do not localize} + (TimeZone:'HAP'; Offset:'-0700'), // Heure Avance du Pacifique - North America {do not localize} + (TimeZone:'HAR'; Offset:'-0600'), // Heure Avance des Rocheuses - North America {do not localize} (TimeZone:'HAST'; Offset:'-1000'), // Hawaii-Aleutian Standard Time - North America {do not localize} - (TimeZone:'HAT'; Offset:'-0230'), // Heure Avancée de Terre-Neuve - North America {do not localize} - (TimeZone:'HAY'; Offset:'-0800'), // Heure Avancée du Yukon - North America {do not localize} + (TimeZone:'HAT'; Offset:'-0230'), // Heure Avance de Terre-Neuve - North America {do not localize} + (TimeZone:'HAY'; Offset:'-0800'), // Heure Avance du Yukon - North America {do not localize} (TimeZone:'HNA'; Offset:'-0400'), // Heure Normale de l'Atlantique - North America {do not localize} (TimeZone:'HNC'; Offset:'-0600'), // Heure Normale du Centre - North America {do not localize} (TimeZone:'HNE'; Offset:'-0500'), // Heure Normale de l'Est - North America {do not localize} @@ -2360,9 +2358,9 @@ procedure WriteStringToStream(AStream : TStream; (TimeZone:'L'; Offset:'+1100'), // Lima Time Zone - Military {do not localize} (TimeZone:'M'; Offset:'+1200'), // Mike Time Zone - Military {do not localize} (TimeZone:'MDT'; Offset:'-0600'), // Mountain Daylight Time - North America {do not localize} - (TimeZone:'MEHSZ';Offset:'+0300'), // Mitteleuropäische Hochsommerzeit - Europe {do not localize} - (TimeZone:'MESZ'; Offset:'+0200'), // Mitteleuroäische Sommerzeit - Europe {do not localize} - (TimeZone:'MEZ'; Offset:'+0100'), // Mitteleuropäische Zeit - Europe {do not localize} + (TimeZone:'MEHSZ';Offset:'+0300'), // Mitteleuropische Hochsommerzeit - Europe {do not localize} + (TimeZone:'MESZ'; Offset:'+0200'), // Mitteleuroische Sommerzeit - Europe {do not localize} + (TimeZone:'MEZ'; Offset:'+0100'), // Mitteleuropische Zeit - Europe {do not localize} (TimeZone:'MSD'; Offset:'+0400'), // Moscow Daylight Time - Europe {do not localize} (TimeZone:'MSK'; Offset:'+0300'), // Moscow Standard Time - Europe {do not localize} (TimeZone:'MST'; Offset:'-0700'), // Mountain Standard Time - North America {do not localize} @@ -4261,9 +4259,9 @@ function abbintohexstring(stream: Tstream):string; Const MaxBufSize = $F000; Begin - { ** Criando a instância do objeto TMemoryStream para retorno do método ** } + { ** Criando a instncia do objeto TMemoryStream para retorno do mtodo ** } Dest := TMemoryStream.Create; - { ** Reposicionando o stream para o seu início ** } + { ** Reposicionando o stream para o seu incio ** } source.Seek(0, soBeginning); source.Position := 0; GetMem(Buffer, MaxBufSize); @@ -4273,7 +4271,7 @@ function abbintohexstring(stream: Tstream):string; If BytesRead > 0 then Dest.WriteBuffer(Buffer^, BytesRead); Until MaxBufSize > BytesRead; - { ** Reposicionando o stream de retorno para o seu início ** } + { ** Reposicionando o stream de retorno para o seu incio ** } Dest.Seek(0, soBeginning); End; diff --git a/CORE/Source/utils/uRESTDWZlib.pas b/CORE/Source/utils/uRESTDWZlib.pas deleted file mode 100644 index e227b11d6..000000000 --- a/CORE/Source/utils/uRESTDWZlib.pas +++ /dev/null @@ -1,322 +0,0 @@ -unit uRESTDWZlib; - -{$I ..\Includes\uRESTDW.inc} - -{ - REST Dataware . - Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON - de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores - Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. - - Membros do Grupo : - - XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. - Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. - Mobius One - Devel, Tester and Admin. - Gustavo - Criptografia and Devel. - Eloy - Devel. - Roniery - Devel. -} - -Interface - -{$IFDEF FPC} - {$MODE OBJFPC}{$H+} -{$ENDIF} - -Uses - {$IFDEF RESTDWLAZARUS} - zstream, base64, - {$ELSE} - {$IFDEF FPC} - zstream, base64, - {$ENDIF} - {$ENDIF} - - SysUtils, Classes, zlib, - uRESTDWDataUtils, uRESTDWConsts, uRESTDWTools; - -// Funções de Compressão e descompressão de Stream com ZLib -Procedure ZCompressStream(inStream, outStream: TStream; - CompressionLevel: TCompressionLevel = clDefault); -Procedure ZDecompressStream(inStream, outStream: TStream); -Function ZDecompressStreamNew(Const S: TStream): TStream; -Function ZDecompressStr(Const S: String; Var Value: String): Boolean; -Function ZDecompressStreamD(Const S: TStringStream; - Var Value: TStringStream): Boolean; -Function ZCompressStreamNew(Const S: String): TStream; -Function ZCompressStreamSS(Const S: String): TStringStream; -Function ZCompressStr(Const S: String; Var Value: String): Boolean; -Function ZCompressStreamD(S: TStream; Var Value: TStream): Boolean; - -implementation - -Procedure ZCompressStream(inStream, outStream: TStream; - CompressionLevel: TCompressionLevel = clDefault); -Var - DS: TCompressionStream; - Size: DWInt64; -Begin - inStream.Position := 0; // Goto Start of input stream - DS := TCompressionStream.Create(CompressionLevel, outStream); - Try - Size := inStream.Size; - inStream.Position := 0; - DS.Write(Size, SizeOf(DWInt64)); - DS.CopyFrom(inStream, inStream.Size); - Finally - DS.Free; - End; -End; - -Procedure ZDecompressStream(inStream, outStream: TStream); -Var - D: TDecompressionstream; - B: Array [1 .. CompressBuffer] of Byte; - R: Integer; - Size: DWInt64; -Begin - D := TDecompressionstream.Create(inStream); - D.Read(Size, SizeOf(DWInt64)); - - {$IFDEF RESTDWLAZARUS} - While True Do - Begin - R := D.Read(B, SizeOf(B)); - If R <> 0 Then - outStream.WriteBuffer(B, R) - Else - Break; - End; - outStream.Position := 0; - FreeAndNil(D); - {$ELSE} - inStream.Position := SizeOf(Size); - Try - Repeat - If ((Size - outStream.Size) > CompressBuffer) Then - R := D.Read(B, SizeOf(B)) - Else - R := D.Read(B, (Size - outStream.Size)); - If R > 0 then - outStream.Write(B, R); - Until R < SizeOf(B); - Finally - outStream.Position := 0; - D.Free; - End; - {$ENDIF} -End; - -Function ZCompressStreamD(S: TStream; Var Value: TStream): Boolean; -Var - Utf8Stream: TStream; -Begin - Result := False; - Try - Utf8Stream := TMemoryStream.Create; - {$IF Defined(RESTDWLAZARUS) OR Defined(DELPHIXE4UP)} - Utf8Stream.CopyFrom(S, S.Size); - {$ELSE} - Utf8Stream.Write(AnsiString(TStringStream(S).Datastring) - [InitStrPos], S.Size); - {$IFEND} - Value := TMemoryStream.Create; - Try - ZCompressStream(Utf8Stream, Value, cCompressionLevel); - Value.Position := 0; - Result := True; - Finally - - End; - Finally - {$IFNDEF RESTDWLAZARUS}Utf8Stream.Size := 0; {$ENDIF} - Utf8Stream.Free; - If Value.Size = 0 Then - Begin - Result := False; - Value.Size := 0; - FreeAndNil(Value); - End; - End; -End; - -Function ZCompressStreamSS(Const S: String): TStringStream; -Var - Utf8Stream: TStringStream; -Begin - {$IF Defined(RESTDWLAZARUS)} - Utf8Stream := TStringStream.Create(S); - {$ELSEIF Defined(DELPHIXEUP)} - Utf8Stream := TStringStream.Create(S, TEncoding.UTF8); - {$ELSE} - Utf8Stream := TStringStream.Create(''); - Utf8Stream.Write(AnsiString(S)[1], Length(AnsiString(S))); - {$IFEND} - Result := TStringStream.Create(''{$IFDEF DELPHIXEUP}, TEncoding.UTF8{$ENDIF}); - Try - ZCompressStream(Utf8Stream, Result, cCompressionLevel); - Result.Position := 0; - Finally - {$IFNDEF FPC}Utf8Stream.Size := 0; {$ENDIF} - Utf8Stream.Free; - If Result.Size = 0 Then - FreeAndNil(Result); - End; -End; - -Function ZCompressStreamNew(Const S: String): TStream; -Var - Utf8Stream: TStream; -Begin - - {$IF Defined(RESTDWLAZARUS) OR not Defined(DELPHIXEUP) OR Defined(RESTDWWINDOWS)} - Utf8Stream := TMemoryStream.Create; - Utf8Stream.Write(AnsiString(S)[1], Length(AnsiString(S))); - {$ELSE} - {$IF Defined(RESTDWLINUX)} - Utf8Stream:= Tstringstream.Create(S, TEncoding.UTF8); - {$ELSE} - Utf8Stream.Write(S[1], Length(S)); - {$IFEND} - {$IFEND} - Result := TMemoryStream.Create; - Try - ZCompressStream(Utf8Stream, Result, cCompressionLevel); - Result.Position := 0; - Finally - {$IFNDEF RESTDWLAZARUS}Utf8Stream.Size := 0; {$ENDIF} - Utf8Stream.Free; - If Result.Size = 0 Then - FreeAndNil(Result); - End; -End; - -Function ZCompressStr(Const S: String; Var Value: String): Boolean; -Var - Utf8Stream: TStringStream; - Compressed: TMemoryStream; -Begin - Result := False; - {$IF Defined(DELPHIXEUP)} - Utf8Stream := TStringStream.Create(S, TEncoding.UTF8); - {$ELSEIF Defined(RESTDWLAZARUS)} - Utf8Stream := TStringStream.Create(S); - {$ELSE} - Utf8Stream := TStringStream.Create(''); - Utf8Stream.Write(AnsiString(S)[1], Length(AnsiString(S))); - {$IFEND} - Try - Compressed := TMemoryStream.Create; - Try - ZCompressStream(Utf8Stream, Compressed, cCompressionLevel); - Compressed.Position := 0; - Try - Value := StreamToHex(Compressed, False); - Result := True; - Finally - End; - Finally - Compressed := nil; - Compressed.Free; - End; - Finally - {$IFDEF DELPHIXEUP}Utf8Stream.Clear;{$ENDIF} - FreeAndNil(Utf8Stream); - End; -End; - -Function ZDecompressStreamD(Const S: TStringStream; - Var Value: TStringStream): Boolean; -Var - Utf8Stream, Base64Stream: TStringStream; - {$IFDEF RESTDWLAZARUS} - Encoder: TBase64DecodingStream; - {$ENDIF} -Begin - Base64Stream := TStringStream.Create(''{$IFDEF DELPHIXEUP}, TEncoding.UTF8{$ENDIF}); - S.Position := 0; - Base64Stream.CopyFrom(S, S.Size); - Base64Stream.Position := 0; - Try - Value := TStringStream.Create(''{$IFDEF DELPHIXEUP}, TEncoding.UTF8{$ENDIF}); - Try - Try - Utf8Stream := TStringStream.Create(''{$IFDEF DELPHIXEUP}, TEncoding.UTF8{$ENDIF}); - HexToStream(Base64Stream.Datastring, Utf8Stream); - Utf8Stream.Position := 0; - ZDecompressStream(Utf8Stream, Value); - Value.Position := 0; - Result := True; - Except - Result := False; - End; - Finally - {$IFNDEF RESTDWLAZARUS}Utf8Stream.Size := 0; {$ENDIF} - FreeAndNil(Utf8Stream); - End; - Finally - {$IFNDEF RESTDWLAZARUS}Base64Stream.Size := 0; {$ENDIF} - FreeAndNil(Base64Stream); - End; -End; - -Function ZDecompressStreamNew(Const S: TStream): TStream; -Begin - Result := TMemoryStream.Create; - S.Position := 0; - ZDecompressStream(S, Result); - Result.Position := 0; -End; - -Function ZDecompressStr(Const S: String; Var Value: String): Boolean; -Var - Utf8Stream, Compressed, Base64Stream: TStringStream; - {$IFDEF RESTDWLAZARUS} - Encoder: TBase64DecodingStream; - {$ENDIF} -Begin - Result := False; - {$IFDEF DELPHIXEUP} - Base64Stream := TStringStream.Create(S, TEncoding.ANSI); - {$ELSE} - Base64Stream := TStringStream.Create(S); - {$ENDIF} - Try - Compressed := TStringStream.Create(''); - Try - {$IFDEF RESTDWLAZARUS} - Utf8Stream := TStringStream.Create(''); - Encoder := TBase64DecodingStream.Create(Base64Stream); - Utf8Stream.CopyFrom(Encoder, Encoder.Size); - Utf8Stream.Position := 0; - FreeAndNil(Encoder); - Compressed.Position := 0; - ZDecompressStream(Utf8Stream, Compressed); - {$ELSE} - Utf8Stream := TStringStream.Create(''{$IFDEF DELPHIXEUP}, TEncoding.UTF8{$ENDIF}); - ZDecompressStream(Base64Stream, Compressed); - Compressed.Position := 0; - {$ENDIF} - Try - Value := Compressed.Datastring; - Result := True; - Finally - {$IFNDEF RESTDWLAZARUS}Utf8Stream.Size := 0; {$ENDIF} - FreeAndNil(Utf8Stream); - End; - Finally - {$IFNDEF RESTDWLAZARUS}Compressed.Size := 0; {$ENDIF} - FreeAndNil(Compressed); - End; - Finally - {$IFNDEF RESTDWLAZARUS}Base64Stream.Size := 0; {$ENDIF} - FreeAndNil(Base64Stream); - End; -End; - -end. From 613e61afb545ba271987ac990ed0c958adc13b5d Mon Sep 17 00:00:00 2001 From: Roniery Santos Cardoso Date: Tue, 8 Sep 2026 22:00:11 -0300 Subject: [PATCH 05/22] feat(fcm): adiciona Firebase Cloud Messaging (fbHTTP/fpHTTP) Novo suporte a Firebase Cloud Messaging para os clients fbHTTP e fpHTTP, incluindo checkin, crypto, OAuth, transporte MCS/WebPush e integracao com o JClient_LAMW (Android). refs r4033, r4036 --- .../JClient_LAMW/uRESTDWjClientLAMWBase.pas | 12 +- .../uRESTDWjClientLAMWFCMTransport.pas | 86 + ...ESTDWjClientLAMWFirebaseCloudMessaging.pas | 34 + .../JClient_LAMW/uRESTDWjClientLAMWReg.pas | 14 +- CORE/Source/Sockets/README_FCM.txt | 36 + CORE/Source/Sockets/uRESTDWFCMCheckin.pas | 352 + CORE/Source/Sockets/uRESTDWFCMCompat.pas | 612 + CORE/Source/Sockets/uRESTDWFCMCrypto.pas | 433 + CORE/Source/Sockets/uRESTDWFCMFIS.pas | 163 + CORE/Source/Sockets/uRESTDWFCMJSON.pas | 1955 ++ CORE/Source/Sockets/uRESTDWFCMMCS.pas | 659 + CORE/Source/Sockets/uRESTDWFCMMessage.pas | 583 + CORE/Source/Sockets/uRESTDWFCMOAuth.pas | 214 + CORE/Source/Sockets/uRESTDWFCMOpenSSLApi.pas | 27920 ++++++++++++++++ CORE/Source/Sockets/uRESTDWFCMOpenSSLHTTP.pas | 490 + .../Sockets/uRESTDWFCMOpenSSLStream.pas | 278 + CORE/Source/Sockets/uRESTDWFCMProto.pas | 231 + .../Source/Sockets/uRESTDWFCMRegistration.pas | 256 + CORE/Source/Sockets/uRESTDWFCMTLS.pas | 184 + CORE/Source/Sockets/uRESTDWFCMTransport.pas | 54 + CORE/Source/Sockets/uRESTDWFCMTypes.pas | 52 + CORE/Source/Sockets/uRESTDWFCMValue.pas | 255 + CORE/Source/Sockets/uRESTDWFCMWebPush.pas | 144 + .../Sockets/uRESTDWFirebaseCloudMessaging.pas | 1341 + 24 files changed, 36345 insertions(+), 13 deletions(-) create mode 100644 CORE/Source/Sockets/JClient_LAMW/uRESTDWjClientLAMWFCMTransport.pas create mode 100644 CORE/Source/Sockets/JClient_LAMW/uRESTDWjClientLAMWFirebaseCloudMessaging.pas create mode 100644 CORE/Source/Sockets/README_FCM.txt create mode 100644 CORE/Source/Sockets/uRESTDWFCMCheckin.pas create mode 100644 CORE/Source/Sockets/uRESTDWFCMCompat.pas create mode 100644 CORE/Source/Sockets/uRESTDWFCMCrypto.pas create mode 100644 CORE/Source/Sockets/uRESTDWFCMFIS.pas create mode 100644 CORE/Source/Sockets/uRESTDWFCMJSON.pas create mode 100644 CORE/Source/Sockets/uRESTDWFCMMCS.pas create mode 100644 CORE/Source/Sockets/uRESTDWFCMMessage.pas create mode 100644 CORE/Source/Sockets/uRESTDWFCMOAuth.pas create mode 100644 CORE/Source/Sockets/uRESTDWFCMOpenSSLApi.pas create mode 100644 CORE/Source/Sockets/uRESTDWFCMOpenSSLHTTP.pas create mode 100644 CORE/Source/Sockets/uRESTDWFCMOpenSSLStream.pas create mode 100644 CORE/Source/Sockets/uRESTDWFCMProto.pas create mode 100644 CORE/Source/Sockets/uRESTDWFCMRegistration.pas create mode 100644 CORE/Source/Sockets/uRESTDWFCMTLS.pas create mode 100644 CORE/Source/Sockets/uRESTDWFCMTransport.pas create mode 100644 CORE/Source/Sockets/uRESTDWFCMTypes.pas create mode 100644 CORE/Source/Sockets/uRESTDWFCMValue.pas create mode 100644 CORE/Source/Sockets/uRESTDWFCMWebPush.pas create mode 100644 CORE/Source/Sockets/uRESTDWFirebaseCloudMessaging.pas diff --git a/CORE/Source/Sockets/JClient_LAMW/uRESTDWjClientLAMWBase.pas b/CORE/Source/Sockets/JClient_LAMW/uRESTDWjClientLAMWBase.pas index be6468721..ba758af2f 100644 --- a/CORE/Source/Sockets/JClient_LAMW/uRESTDWjClientLAMWBase.pas +++ b/CORE/Source/Sockets/JClient_LAMW/uRESTDWjClientLAMWBase.pas @@ -1,22 +1,22 @@ unit uRESTDWjClientLAMWBase; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. A. Brito - Admin - Administrador do desenvolvimento. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -948,7 +948,7 @@ function TRESTDWjClientLAMWClientPooler.IsServerLive(Aip: String; Aport: Integer ResultJSON := InputValue; If Pos(', "RESULT":[', InputValue) = 0 Then Begin - If (Encoding = esUtf8) Then //NativeResult Correções aqui + If (Encoding = esUtf8) Then //NativeResult Correes aqui Begin {$IF Defined(DELPHIXEUP)} //ResultJSON := PWidechar(UTF8Decode(InputValue)); diff --git a/CORE/Source/Sockets/JClient_LAMW/uRESTDWjClientLAMWFCMTransport.pas b/CORE/Source/Sockets/JClient_LAMW/uRESTDWjClientLAMWFCMTransport.pas new file mode 100644 index 000000000..e059b6862 --- /dev/null +++ b/CORE/Source/Sockets/JClient_LAMW/uRESTDWjClientLAMWFCMTransport.pas @@ -0,0 +1,86 @@ +Unit uRESTDWjClientLAMWFCMTransport; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + uRESTDWFCMTransport; + +Type + TRESTDWjClientLAMWFCMHTTPTransport = Class(TRESTDWFCMHTTPTransport) + Public + Function Post(Const AURL : String; + AHeaders : TStrings; + ABody : TStream; + AResponse : TStream; + AResponseError : TStream) : Integer; Override; + End; + + TRESTDWjClientLAMWFCMStreamTransport = Class(TRESTDWFCMStreamTransport) + Public + Procedure Connect(Const AHost : String; + APort : Integer); Override; + Procedure Disconnect; Override; + Function Connected : Boolean; Override; + Function ReadByte : Byte; Override; + Procedure ReadBuffer(Var ABuffer; ACount : Integer); Override; + Procedure WriteBuffer(Const ABuffer; ACount : Integer); Override; + End; + +Implementation + +Function TRESTDWjClientLAMWFCMHTTPTransport.Post(Const AURL : String; + AHeaders : TStrings; + ABody : TStream; + AResponse : TStream; + AResponseError : TStream) : Integer; +Begin + Raise Exception.Create( + 'RESTDW JClient/LAMW FCM transport: TODO para o motor REST Dataware nativo' + ); +End; + +Procedure TRESTDWjClientLAMWFCMStreamTransport.Connect(Const AHost : String; + APort : Integer); +Begin + Raise Exception.Create( + 'RESTDW JClient/LAMW FCM stream: TODO para o motor REST Dataware nativo' + ); +End; + +Procedure TRESTDWjClientLAMWFCMStreamTransport.Disconnect; +Begin +End; + +Function TRESTDWjClientLAMWFCMStreamTransport.Connected : Boolean; +Begin + Result := False; +End; + +Function TRESTDWjClientLAMWFCMStreamTransport.ReadByte : Byte; +Begin + Raise Exception.Create( + 'RESTDW JClient/LAMW FCM stream: TODO para o motor REST Dataware nativo' + ); +End; + +Procedure TRESTDWjClientLAMWFCMStreamTransport.ReadBuffer(Var ABuffer; + ACount : Integer); +Begin + Raise Exception.Create( + 'RESTDW JClient/LAMW FCM stream: TODO para o motor REST Dataware nativo' + ); +End; + +Procedure TRESTDWjClientLAMWFCMStreamTransport.WriteBuffer(Const ABuffer; + ACount : Integer); +Begin + Raise Exception.Create( + 'RESTDW JClient/LAMW FCM stream: TODO para o motor REST Dataware nativo' + ); +End; + +End. diff --git a/CORE/Source/Sockets/JClient_LAMW/uRESTDWjClientLAMWFirebaseCloudMessaging.pas b/CORE/Source/Sockets/JClient_LAMW/uRESTDWjClientLAMWFirebaseCloudMessaging.pas new file mode 100644 index 000000000..3bdabc4f8 --- /dev/null +++ b/CORE/Source/Sockets/JClient_LAMW/uRESTDWjClientLAMWFirebaseCloudMessaging.pas @@ -0,0 +1,34 @@ +Unit uRESTDWjClientLAMWFirebaseCloudMessaging; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + uRESTDWFirebaseCloudMessaging, + uRESTDWFCMTransport; + +Type + TRESTDWjClientLAMWFirebaseCloudMessaging = Class(TRESTDWFirebaseCloudMessaging) + Protected + Function CreateHTTPTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMHTTPTransport; Override; + Function CreateMCSStreamTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMStreamTransport; Override; + End; + +Implementation + +Uses + uRESTDWjClientLAMWFCMTransport; + +Function TRESTDWjClientLAMWFirebaseCloudMessaging.CreateHTTPTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMHTTPTransport; +Begin + Result := TRESTDWjClientLAMWFCMHTTPTransport.Create; +End; + +Function TRESTDWjClientLAMWFirebaseCloudMessaging.CreateMCSStreamTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMStreamTransport; +Begin + Result := TRESTDWjClientLAMWFCMStreamTransport.Create; +End; + +End. diff --git a/CORE/Source/Sockets/JClient_LAMW/uRESTDWjClientLAMWReg.pas b/CORE/Source/Sockets/JClient_LAMW/uRESTDWjClientLAMWReg.pas index cb7bd0383..d8befea3b 100644 --- a/CORE/Source/Sockets/JClient_LAMW/uRESTDWjClientLAMWReg.pas +++ b/CORE/Source/Sockets/JClient_LAMW/uRESTDWjClientLAMWReg.pas @@ -1,21 +1,21 @@ unit uRESTDWjClientLAMWReg; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. A. Brito - Admin - Administrador do desenvolvimento. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -26,7 +26,7 @@ interface uses StdCtrls, ComCtrls, Forms, ExtCtrls, DBCtrls, DBGrids, Dialogs, Controls, - LResources, LazFileUtils, Classes, uRESTDWjClientLAMWBase; + LResources, LazFileUtils, Classes, uRESTDWjClientLAMWBase, uRESTDWjClientLAMWFirebaseCloudMessaging; {$IFNDEF RESTDWLAMW} Type @@ -82,7 +82,7 @@ interface Procedure Register; Begin {$I restdwjClientLAMW.lrs} - RegisterComponents ('REST Dataware - Client', [TRESTDWjClientLAMWClientREST, TRESTDWjClientLAMWClientPooler]); + RegisterComponents ('REST Dataware - Client', [TRESTDWjClientLAMWClientREST, TRESTDWjClientLAMWClientPooler, TRESTDWjClientLAMWFirebaseCloudMessaging]); RegisterComponents ('REST Dataware - DB', [TRESTDWjClientLAMWDatabase]); {$IFNDEF RESTDWLAMW} RegisterPropertyEditor(TypeInfo(String), TRESTDWjClientLAMWDatabase, 'PoolerName', TPoolersList); diff --git a/CORE/Source/Sockets/README_FCM.txt b/CORE/Source/Sockets/README_FCM.txt new file mode 100644 index 000000000..be5fb19b2 --- /dev/null +++ b/CORE/Source/Sockets/README_FCM.txt @@ -0,0 +1,36 @@ +REST Dataware 2.1 - Firebase Cloud Messaging + +Fontes comuns FCM: +Sockets + +Fontes especficos: +Sockets\Indy +Sockets\Ics +Sockets\Fphttp +Sockets\HttpDef +Sockets\JClient_LAMW + +Nenhuma pasta adicional e nenhum novo Library Path/Search Path so necessrios. + +Os componentes so registrados pelos Reg.pas j existentes dos motores. +No existem units FirebaseCloudMessagingReg separadas. + +Configurao pblica: +ProjectID +AppID +APIKey +VAPIDKey +ClientEmail +PrivateKey +Connection +Receive +Notification + +LoadGoogleServices importa ProjectID, AppID e APIKey. +LoadServiceAccountConfig importa ProjectID, ClientEmail e PrivateKey. + +Correo JSONInterface: +utils\JSON\uRESTDWJSONInterface.pas + +CA bundle: +utils\SSL\RESTDWRootCA.pem diff --git a/CORE/Source/Sockets/uRESTDWFCMCheckin.pas b/CORE/Source/Sockets/uRESTDWFCMCheckin.pas new file mode 100644 index 000000000..671d18d03 --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFCMCheckin.pas @@ -0,0 +1,352 @@ +Unit uRESTDWFCMCheckin; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + uRESTDWFCMCompat, + uRESTDWFCMTransport, + SysUtils, + uRESTDWFCMTypes, + uRESTDWFCMProto; + +Type + TRESTDWGCMCheckin = Class + Private + FHTTP : TRESTDWFCMHTTPTransport; + + Function BuildRequest(Const ACredentials : TRESTDWFCMCredentials) : TRESTDWFCMBytes; + Function ReadFixed64(AStream : TStream) : TRESTDWFCMUInt64; + + Procedure ReadSetting(Const AData : TRESTDWFCMBytes; + Var ACredentials : TRESTDWFCMCredentials); + + Procedure ParseResponse(Const AResponse : TRESTDWFCMBytes; + Var ACredentials : TRESTDWFCMCredentials); + + Procedure SendCheckin(Var ACredentials : TRESTDWFCMCredentials); + Public + Constructor Create(AHTTP : TRESTDWFCMHTTPTransport); + Destructor Destroy; Override; + + Procedure Execute(Var ACredentials : TRESTDWFCMCredentials); + End; + +Implementation + +Constructor TRESTDWGCMCheckin.Create(AHTTP : TRESTDWFCMHTTPTransport); +Begin + Inherited Create; + FHTTP := AHTTP; +End; + +Destructor TRESTDWGCMCheckin.Destroy; +Begin + Inherited Destroy; +End; + +Function TRESTDWGCMCheckin.BuildRequest(Const ACredentials : TRESTDWFCMCredentials) : TRESTDWFCMBytes; +Var + LRequestStream : TMemoryStream; + LCheckinStream : TMemoryStream; + LChromeStream : TMemoryStream; + LCheckinBytes : TRESTDWFCMBytes; + LChromeBytes : TRESTDWFCMBytes; +Begin + LRequestStream := TMemoryStream.Create; + LCheckinStream := TMemoryStream.Create; + LChromeStream := TMemoryStream.Create; + Try + { Identidade de protocolo REST Dataware. + O valor abaixo faz parte somente do wire format usado no check-in. + Ele e fixo e nao representa nem consulta o SysOp onde o componente + esta executando. A mesma identidade e usada em Desktop e Mobile. } + TRESTDWProto.FieldVarInt(LChromeStream, 1, 1); + + TRESTDWProto.FieldString(LChromeStream, 2, '127.0.6533.73'); + + { CHANNEL_STABLE = 1 } + TRESTDWProto.FieldVarInt(LChromeStream, 3, 1); + + SetLength(LChromeBytes, LChromeStream.Size); + LChromeStream.Position := 0; + + If LChromeStream.Size > 0 Then + LChromeStream.ReadBuffer( + LChromeBytes[0], + LChromeStream.Size + ); + + { Wire device type usado pela identidade de protocolo REST Dataware. } + TRESTDWProto.FieldVarInt(LCheckinStream, 12, 3); + TRESTDWProto.FieldBytes(LCheckinStream, 13, LChromeBytes); + + SetLength(LCheckinBytes, LCheckinStream.Size); + LCheckinStream.Position := 0; + + If LCheckinStream.Size > 0 Then + LCheckinStream.ReadBuffer( + LCheckinBytes[0], + LCheckinStream.Size + ); + + { Wire format do endpoint de check-in utilizado pelo REST Dataware. + id = field 2, int64 / varint + checkin = field 4 + security_token = field 13, fixed64 + version = field 14 + user serial = field 22 } + If ACredentials.DeviceID <> 0 Then + TRESTDWProto.FieldVarInt( + LRequestStream, + 2, + TRESTDWFCMUInt64(ACredentials.DeviceID) + ); + + TRESTDWProto.FieldBytes( + LRequestStream, + 4, + LCheckinBytes + ); + + If ACredentials.SecurityToken <> 0 Then + TRESTDWProto.FieldFixed64( + LRequestStream, + 13, + ACredentials.SecurityToken + ); + + TRESTDWProto.FieldVarInt(LRequestStream, 14, 3); + TRESTDWProto.FieldVarInt(LRequestStream, 22, 0); + + SetLength(Result, LRequestStream.Size); + LRequestStream.Position := 0; + + If LRequestStream.Size > 0 Then + LRequestStream.ReadBuffer( + Result[0], + LRequestStream.Size + ); + Finally + LChromeStream.Free; + LCheckinStream.Free; + LRequestStream.Free; + End; +End; + +Function TRESTDWGCMCheckin.ReadFixed64(AStream : TStream) : TRESTDWFCMUInt64; +Var + LBytes : Array[0..7] Of Byte; + LIndex : Integer; +Begin + Result := 0; + + AStream.ReadBuffer( + LBytes[0], + SizeOf(LBytes) + ); + + For LIndex := 0 To 7 Do + Result := Result Or + (TRESTDWFCMUInt64(LBytes[LIndex]) Shl (LIndex * 8)); +End; + +Procedure TRESTDWGCMCheckin.ReadSetting(Const AData : TRESTDWFCMBytes; + Var ACredentials : TRESTDWFCMCredentials); +Var + LStream : TRESTDWFCMBytesStream; + LKey : TRESTDWFCMUInt64; + LField : TRESTDWFCMUInt64; + LWireType : TRESTDWFCMUInt64; + LData : TRESTDWFCMBytes; + LName : String; + LValue : String; +Begin + LName := ''; + LValue := ''; + + LStream := TRESTDWFCMBytesStream.Create(AData); + Try + While LStream.Position < LStream.Size Do + Begin + LKey := TRESTDWProto.ReadVarInt(LStream); + LField := LKey Shr 3; + LWireType := LKey And 7; + + Case LWireType Of + 0: + TRESTDWProto.ReadVarInt(LStream); + + 1: + Begin + If (LStream.Size - LStream.Position) < 8 Then + Raise Exception.Create('Checkin protobuf fixed64 truncado'); + + LStream.Seek(8, soCurrent); + End; + + 2: + Begin + LData := TRESTDWProto.ReadLengthDelimited(LStream); + + If LField = 1 Then + LName := RESTDWFCMBytesToString(LData) + Else + If LField = 2 Then + LValue := RESTDWFCMBytesToString(LData); + End; + + 5: + Begin + If (LStream.Size - LStream.Position) < 4 Then + Raise Exception.Create('Checkin protobuf fixed32 truncado'); + + LStream.Seek(4, soCurrent); + End; + Else + Raise Exception.Create( + 'Setting do Checkin com protobuf inesperado' + ); + End; + End; + Finally + LStream.Free; + End; + + If SameText(LName, 'gcm_registration_url') Then + ACredentials.RegistrationURL := LValue; +End; + +Procedure TRESTDWGCMCheckin.ParseResponse(Const AResponse : TRESTDWFCMBytes; + Var ACredentials : TRESTDWFCMCredentials); +Var + LStream : TRESTDWFCMBytesStream; + LData : TRESTDWFCMBytes; + LKey : TRESTDWFCMUInt64; + LField : TRESTDWFCMUInt64; + LWireType : TRESTDWFCMUInt64; + LValue : TRESTDWFCMUInt64; +Begin + LStream := TRESTDWFCMBytesStream.Create(AResponse); + Try + While LStream.Position < LStream.Size Do + Begin + LKey := TRESTDWProto.ReadVarInt(LStream); + LField := LKey Shr 3; + LWireType := LKey And 7; + + Case LWireType Of + 0: + TRESTDWProto.ReadVarInt(LStream); + + 1: + Begin + LValue := ReadFixed64(LStream); + + If LField = 7 Then + ACredentials.DeviceID := LValue + Else + If LField = 8 Then + ACredentials.SecurityToken := LValue; + End; + + 2: + Begin + LData := TRESTDWProto.ReadLengthDelimited(LStream); + + If LField = 5 Then + ReadSetting( + LData, + ACredentials + ); + End; + + 5: + Begin + If (LStream.Size - LStream.Position) < 4 Then + Raise Exception.Create('Checkin protobuf fixed32 truncado'); + + LStream.Seek(4, soCurrent); + End; + Else + Raise Exception.Create( + 'Checkin protobuf inesperado' + ); + End; + End; + Finally + LStream.Free; + End; +End; + +Procedure TRESTDWGCMCheckin.SendCheckin(Var ACredentials : TRESTDWFCMCredentials); +Var + LRequest : TRESTDWFCMBytes; + LResponseBytes : TRESTDWFCMBytes; + LRequestStream : TRESTDWFCMBytesStream; + LResponse : TMemoryStream; + LError : TMemoryStream; + LHeaders : TStringList; + LCode : Integer; +Begin + LRequest := BuildRequest(ACredentials); + LRequestStream := TRESTDWFCMBytesStream.Create(LRequest); + LResponse := TMemoryStream.Create; + LError := TMemoryStream.Create; + LHeaders := TStringList.Create; + Try + LHeaders.Values['Content-Type'] := 'application/x-protobuf'; + LCode := FHTTP.Post('https://android.clients.google.com/checkin', + LHeaders, + LRequestStream, + LResponse, + LError); + If LCode = 401 Then + Raise Exception.Create('GCM Checkin autenticado recusou DeviceID/SecurityToken'); + If (LCode Div 100) <> 2 Then + Raise Exception.Create('GCM Checkin HTTP ' + IntToStr(LCode)); + + SetLength(LResponseBytes, LResponse.Size); + LResponse.Position := 0; + If Length(LResponseBytes) > 0 Then + LResponse.ReadBuffer(LResponseBytes[0], Length(LResponseBytes)); + Finally + LHeaders.Free; + LError.Free; + LResponse.Free; + LRequestStream.Free; + End; + + ParseResponse(LResponseBytes, ACredentials); + If (ACredentials.DeviceID = 0) Or + (ACredentials.SecurityToken = 0) Then + Raise Exception.Create('GCM Checkin nao retornou DeviceID/SecurityToken'); +End; + +Procedure TRESTDWGCMCheckin.Execute(Var ACredentials : TRESTDWFCMCredentials); +Var + LBootstrap : Boolean; +Begin + LBootstrap := (ACredentials.DeviceID = 0) Or + (ACredentials.SecurityToken = 0); + + If LBootstrap Then + Begin + ACredentials.DeviceID := 0; + ACredentials.SecurityToken := 0; + + { Primeiro check-in: exatamente como Chromium. Ele cria o par + AndroidID/SecurityToken. Nao repetimos imediatamente um segundo + check-in autenticado antes do register3. } + SendCheckin(ACredentials); + End + Else + Begin + { Credenciais ja persistidas: valida o par existente. } + SendCheckin(ACredentials); + End; +End; + +End. diff --git a/CORE/Source/Sockets/uRESTDWFCMCompat.pas b/CORE/Source/Sockets/uRESTDWFCMCompat.pas new file mode 100644 index 000000000..ba4ac10e9 --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFCMCompat.pas @@ -0,0 +1,612 @@ +Unit uRESTDWFCMCompat; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + {$IFDEF RESTDWWINDOWS} + Windows, + {$ELSE} + {$IFDEF FPC} + DateUtils, + {$ELSE} + {$IFDEF DELPHI2010UP} + DateUtils, + {$ENDIF} + {$ENDIF} + {$ENDIF} + uRESTDWProtoTypes, + uRESTDWTools; + +Type + TRESTDWFCMBytes = TRESTDWBytes; + TRESTDWFCMUInt64 = TRESTDWUInt64; + + TRESTDWFCMBytesStream = Class(TMemoryStream) + Public + Constructor Create(Const AData : TRESTDWFCMBytes); + End; + + TRESTDWFCMUTF8Stream = Class(TMemoryStream) + Public + Constructor Create(Const AValue : String); + Function AsString : String; + End; + +Function RESTDWFCMBytesToString(Const AData : TRESTDWFCMBytes) : String; +Function RESTDWFCMStringToBytes(Const AValue : String) : TRESTDWFCMBytes; + +Function RESTDWFCMBase64URL(Const AData : TRESTDWFCMBytes) : String; +Function RESTDWFCMBase64URLDecode(Const AValue : String) : TRESTDWFCMBytes; + +Function RESTDWFCMJSONValue(Const AJSON, + AName : String) : String; + +Function RESTDWFCMURLEncode(Const AValue : String) : String; + +Function RESTDWFCMUIntToStr(AValue : TRESTDWFCMUInt64) : String; + +Function RESTDWFCMStrToUInt64Def(Const AValue : String; + ADefault : TRESTDWFCMUInt64) : TRESTDWFCMUInt64; + +Function RESTDWFCMUnixNow : Int64; + +Function RESTDWFCMPtrOffset(APointer : Pointer; + AOffset : Integer) : Pointer; +Procedure RESTDWFCMWriteUTF8(AStream : TStream; + Const AValue : String); +Procedure RESTDWFCMSleep(AMilliseconds : Cardinal); + +Implementation + +Constructor TRESTDWFCMUTF8Stream.Create(Const AValue : String); +Var + LUTF8 : UTF8String; +Begin + Inherited Create; + + LUTF8 := UTF8Encode(AValue); + + If Length(LUTF8) > 0 Then + WriteBuffer( + LUTF8[1], + Length(LUTF8) + ); + + Position := 0; +End; + +Function TRESTDWFCMUTF8Stream.AsString : String; +Var + LUTF8 : UTF8String; +Begin + SetLength(LUTF8, Size); + + Position := 0; + + If Size > 0 Then + ReadBuffer( + LUTF8[1], + Size + ); + + {$IFDEF DELPHI2009UP} + Result := UTF8ToString(LUTF8); + {$ELSE} + {$IFDEF FPC} + Result := UTF8ToString(LUTF8); + {$ELSE} + Result := String(UTF8Decode(LUTF8)); + {$ENDIF} + {$ENDIF} + + Position := 0; +End; + +Constructor TRESTDWFCMBytesStream.Create(Const AData : TRESTDWFCMBytes); +Begin + Inherited Create; + + If Length(AData) > 0 Then + WriteBuffer( + AData[0], + Length(AData) + ); + + Position := 0; +End; + +Function RESTDWFCMBytesToString(Const AData : TRESTDWFCMBytes) : String; +Var + I : Integer; + LUTF8 : UTF8String; +Begin + SetLength(LUTF8, Length(AData)); + + For I := 0 To Length(AData) - 1 Do + LUTF8[I + 1] := AnsiChar(AData[I]); + + {$IFDEF DELPHI2009UP} + Result := UTF8ToString(LUTF8); + {$ELSE} + {$IFDEF FPC} + Result := UTF8ToString(LUTF8); + {$ELSE} + Result := String(UTF8Decode(LUTF8)); + {$ENDIF} + {$ENDIF} +End; + +Function RESTDWFCMStringToBytes(Const AValue : String) : TRESTDWFCMBytes; +Var + I : Integer; + LUTF8 : UTF8String; +Begin + {$IFDEF DELPHI2009UP} + LUTF8 := UTF8Encode(AValue); + {$ELSE} + {$IFDEF FPC} + LUTF8 := UTF8Encode(AValue); + {$ELSE} + LUTF8 := UTF8Encode(WideString(AValue)); + {$ENDIF} + {$ENDIF} + + SetLength(Result, Length(LUTF8)); + + For I := 1 To Length(LUTF8) Do + Result[I - 1] := Byte(LUTF8[I]); +End; + +Function RESTDWFCMBase64URL(Const AData : TRESTDWFCMBytes) : String; +Const + CTable : String = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'; +Var + I, + LRemaining : Integer; + B0, + B1, + B2 : Byte; +Begin + Result := ''; + I := 0; + + While I < Length(AData) Do + Begin + LRemaining := Length(AData) - I; + + B0 := AData[I]; + + If LRemaining > 1 Then + B1 := AData[I + 1] + Else + B1 := 0; + + If LRemaining > 2 Then + B2 := AData[I + 2] + Else + B2 := 0; + + Result := + Result + + CTable[(B0 Shr 2) + 1] + + CTable[(((B0 And $03) Shl 4) Or (B1 Shr 4)) + 1]; + + If LRemaining > 1 Then + Result := + Result + + CTable[(((B1 And $0F) Shl 2) Or (B2 Shr 6)) + 1]; + + If LRemaining > 2 Then + Result := + Result + + CTable[(B2 And $3F) + 1]; + + Inc(I, 3); + End; +End; + +Function RESTDWFCMBase64URLDecode(Const AValue : String) : TRESTDWFCMBytes; + + Function DecodeChar(AChar : Char) : Integer; + Begin + If (AChar >= 'A') And (AChar <= 'Z') Then + Result := Ord(AChar) - Ord('A') + Else + If (AChar >= 'a') And (AChar <= 'z') Then + Result := Ord(AChar) - Ord('a') + 26 + Else + If (AChar >= '0') And (AChar <= '9') Then + Result := Ord(AChar) - Ord('0') + 52 + Else + If (AChar = '-') Or (AChar = '+') Then + Result := 62 + Else + If (AChar = '_') Or (AChar = '/') Then + Result := 63 + Else + Result := -1; + End; + +Var + S : String; + I, + LOut, + LCount, + V0, + V1, + V2, + V3 : Integer; +Begin + S := Trim(AValue); + + While (Length(S) > 0) And + (S[Length(S)] = '=') Do + Delete(S, Length(S), 1); + + If (Length(S) Mod 4) = 1 Then + Raise Exception.Create('FCM Base64URL invalido'); + + SetLength(Result, ((Length(S) * 3) Div 4) + 3); + + I := 1; + LOut := 0; + + While I <= Length(S) Do + Begin + LCount := Length(S) - I + 1; + + V0 := DecodeChar(S[I]); + + If LCount > 1 Then + V1 := DecodeChar(S[I + 1]) + Else + V1 := -1; + + If LCount > 2 Then + V2 := DecodeChar(S[I + 2]) + Else + V2 := -1; + + If LCount > 3 Then + V3 := DecodeChar(S[I + 3]) + Else + V3 := -1; + + If (V0 < 0) Or (V1 < 0) Then + Raise Exception.Create('FCM Base64URL invalido'); + + Result[LOut] := Byte((V0 Shl 2) Or (V1 Shr 4)); + Inc(LOut); + + If LCount > 2 Then + Begin + If V2 < 0 Then + Raise Exception.Create('FCM Base64URL invalido'); + + Result[LOut] := + Byte( + ((V1 And $0F) Shl 4) Or + (V2 Shr 2) + ); + Inc(LOut); + End; + + If LCount > 3 Then + Begin + If V3 < 0 Then + Raise Exception.Create('FCM Base64URL invalido'); + + Result[LOut] := + Byte( + ((V2 And $03) Shl 6) Or + V3 + ); + Inc(LOut); + End; + + Inc(I, 4); + End; + + SetLength(Result, LOut); +End; + +Function RESTDWFCMJSONValue(Const AJSON, + AName : String) : String; +Var + I, + LStart, + LNameStart : Integer; + LKey : String; + LEscaped : Boolean; +Begin + Result := ''; + I := 1; + + While I <= Length(AJSON) Do + Begin + If AJSON[I] <> '"' Then + Begin + Inc(I); + Continue; + End; + + Inc(I); + LNameStart := I; + LEscaped := False; + + While I <= Length(AJSON) Do + Begin + If AJSON[I] = '\' Then + Begin + LEscaped := Not LEscaped; + Inc(I); + Continue; + End; + + If (AJSON[I] = '"') And + Not LEscaped Then + Break; + + LEscaped := False; + Inc(I); + End; + + If I > Length(AJSON) Then + Exit; + + LKey := Copy(AJSON, LNameStart, I - LNameStart); + Inc(I); + + While (I <= Length(AJSON)) And + (AJSON[I] <= ' ') Do + Inc(I); + + If (I > Length(AJSON)) Or + (AJSON[I] <> ':') Then + Continue; + + Inc(I); + + While (I <= Length(AJSON)) And + (AJSON[I] <= ' ') Do + Inc(I); + + If Not SameText(LKey, AName) Then + Continue; + + If I > Length(AJSON) Then + Exit; + + If AJSON[I] = '"' Then + Begin + Inc(I); + LStart := I; + LEscaped := False; + + While I <= Length(AJSON) Do + Begin + If AJSON[I] = '\' Then + Begin + LEscaped := Not LEscaped; + Inc(I); + Continue; + End; + + If (AJSON[I] = '"') And + Not LEscaped Then + Break; + + LEscaped := False; + Inc(I); + End; + + Result := Copy(AJSON, LStart, I - LStart); + Exit; + End; + + LStart := I; + + While (I <= Length(AJSON)) And + (AJSON[I] <> ',') And + (AJSON[I] <> '}') And + (AJSON[I] <> ']') Do + Inc(I); + + Result := Trim(Copy(AJSON, LStart, I - LStart)); + Exit; + End; +End; + +Function RESTDWFCMURLEncode(Const AValue : String) : String; +Const + CHex : String = '0123456789ABCDEF'; +Var + I : Integer; + C : Byte; + LBytes : TRESTDWFCMBytes; +Begin + Result := ''; + LBytes := RESTDWFCMStringToBytes(AValue); + + For I := 0 To Length(LBytes) - 1 Do + Begin + C := LBytes[I]; + + If ((C >= Ord('a')) And + (C <= Ord('z'))) Or + ((C >= Ord('A')) And + (C <= Ord('Z'))) Or + ((C >= Ord('0')) And + (C <= Ord('9'))) Or + (C = Ord('-')) Or + (C = Ord('_')) Or + (C = Ord('.')) Or + (C = Ord('~')) Then + Result := Result + Char(C) + Else + Result := + Result + + '%' + + CHex[(C Shr 4) + 1] + + CHex[(C And $0F) + 1]; + End; +End; + +Function RESTDWFCMUIntToStr(AValue : TRESTDWFCMUInt64) : String; +Var + LDigit : Byte; +Begin + If AValue = 0 Then + Begin + Result := '0'; + Exit; + End; + + Result := ''; + + While AValue > 0 Do + Begin + LDigit := AValue Mod 10; + + Result := + Char(Ord('0') + LDigit) + + Result; + + AValue := AValue Div 10; + End; +End; + +Function RESTDWFCMStrToUInt64Def(Const AValue : String; + ADefault : TRESTDWFCMUInt64) : TRESTDWFCMUInt64; +Var + I : Integer; + LDigit : Integer; + LValue : TRESTDWFCMUInt64; +Begin + If AValue = '' Then + Begin + Result := ADefault; + Exit; + End; + + LValue := 0; + + For I := 1 To Length(AValue) Do + Begin + If (AValue[I] < '0') Or + (AValue[I] > '9') Then + Begin + Result := ADefault; + Exit; + End; + + LDigit := + Ord(AValue[I]) - + Ord('0'); + + LValue := + (LValue * 10) + + TRESTDWFCMUInt64(LDigit); + End; + + Result := LValue; +End; + +Function RESTDWFCMUnixNow : Int64; +Var + LUTC : TDateTime; +{$IFDEF RESTDWWINDOWS} + LSystemTime : TSystemTime; +{$ENDIF} +Begin + {$IFDEF RESTDWWINDOWS} + GetSystemTime(LSystemTime); + + LUTC := + EncodeDate( + LSystemTime.wYear, + LSystemTime.wMonth, + LSystemTime.wDay + ) + + EncodeTime( + LSystemTime.wHour, + LSystemTime.wMinute, + LSystemTime.wSecond, + LSystemTime.wMilliseconds + ); + {$ELSE} + {$IFDEF FPC} + LUTC := + LocalTimeToUniversal( + Now + ); + {$ELSE} + {$IFDEF DELPHI2010UP} + LUTC := + TTimeZone.Local.ToUniversalTime( + Now + ); + {$ELSE} + LUTC := Now; + {$ENDIF} + {$ENDIF} + {$ENDIF} + + Result := + Trunc( + (LUTC - + EncodeDate(1970, 1, 1)) * + 86400 + ); +End; + +Procedure RESTDWFCMSleep(AMilliseconds : Cardinal); +Begin + {$IFDEF RESTDWWINDOWS} + Windows.Sleep(AMilliseconds); + {$ELSE} + Sleep(AMilliseconds); + {$ENDIF} +End; + +Procedure RESTDWFCMWriteUTF8(AStream : TStream; + Const AValue : String); +Var + LBytes : TRESTDWFCMBytes; +Begin + If AStream = Nil Then + Exit; + + LBytes := RESTDWFCMStringToBytes(AValue); + + If Length(LBytes) > 0 Then + AStream.WriteBuffer( + LBytes[0], + Length(LBytes) + ); +End; + +Function RESTDWFCMPtrOffset(APointer : Pointer; + AOffset : Integer) : Pointer; +Begin + {$IFDEF CPU64} + Result := + Pointer( + NativeUInt(APointer) + + NativeUInt(AOffset) + ); + {$ELSE} + Result := + Pointer( + Cardinal(APointer) + + Cardinal(AOffset) + ); + {$ENDIF} +End; + +End. diff --git a/CORE/Source/Sockets/uRESTDWFCMCrypto.pas b/CORE/Source/Sockets/uRESTDWFCMCrypto.pas new file mode 100644 index 000000000..dc6943a5c --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFCMCrypto.pas @@ -0,0 +1,433 @@ +Unit uRESTDWFCMCrypto; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + uRESTDWFCMCompat; + +Type + TRESTDWWebPushCrypto = Class + Private + Class Function HMACSHA256(Const AKey, + AData : TRESTDWFCMBytes) : TRESTDWFCMBytes; + Class Function HKDF(Const AIKM, + ASalt, + AInfo : TRESTDWFCMBytes; + ALength : Integer) : TRESTDWFCMBytes; + Class Function ECDHSecret(Const APrivateRaw, + APeerPublicRaw : TRESTDWFCMBytes) : TRESTDWFCMBytes; + Class Function AESGCMDecrypt(Const AKey, + ANonce, + ACipherAndTag : TRESTDWFCMBytes) : TRESTDWFCMBytes; + Class Function Concat(Const A, + B : TRESTDWFCMBytes) : TRESTDWFCMBytes; Overload; + Class Function Concat(Const A, + B, + C : TRESTDWFCMBytes) : TRESTDWFCMBytes; Overload; + Class Function BytesOf(Const S : AnsiString) : TRESTDWFCMBytes; + Class Function BuildContext(Const AReceiverPublic, + ASenderPublic : TRESTDWFCMBytes) : TRESTDWFCMBytes; + Class Function ParseHeaderParam(Const AHeader, + AName : String) : String; + Class Function ParseRecordSize(Const AEncryptionHeader : String) : Integer; + Class Function NonceForCounter(Const ABaseNonce : TRESTDWFCMBytes; + ACounter : TRESTDWFCMUInt64) : TRESTDWFCMBytes; + Public + Class Function DecryptAESGCM(Const APrivateKeyB64, + APublicKeyB64, + AAuthB64, + ACryptoKeyHeader, + AEncryptionHeader : String; + Const ARawData : TRESTDWFCMBytes) : TRESTDWFCMBytes; + End; + +Implementation + +Uses + uRESTDWOpenSslLib; + +Class Function TRESTDWWebPushCrypto.BytesOf(Const S : AnsiString) : TRESTDWFCMBytes; +Begin + SetLength(Result, Length(S)); + If Length(S) > 0 Then + Move(S[1], Result[0], Length(S)); +End; + +Class Function TRESTDWWebPushCrypto.Concat(Const A, + B : TRESTDWFCMBytes) : TRESTDWFCMBytes; +Begin + SetLength(Result, Length(A) + Length(B)); + If Length(A) > 0 Then + Move(A[0], Result[0], Length(A)); + If Length(B) > 0 Then + Move(B[0], Result[Length(A)], Length(B)); +End; + +Class Function TRESTDWWebPushCrypto.Concat(Const A, + B, + C : TRESTDWFCMBytes) : TRESTDWFCMBytes; +Begin + Result := Concat(Concat(A, B), C); +End; + +Class Function TRESTDWWebPushCrypto.HMACSHA256(Const AKey, + AData : TRESTDWFCMBytes) : TRESTDWFCMBytes; +Var + LSize : Cardinal; + LKeyPtr, + LDataPtr : Pointer; +Begin + SetLength(Result, 32); + LSize := 0; + If Length(AKey) > 0 Then + LKeyPtr := @AKey[0] + Else + LKeyPtr := Nil; + If Length(AData) > 0 Then + LDataPtr := @AData[0] + Else + LDataPtr := Nil; + If HMAC(EVP_sha256, LKeyPtr, Length(AKey), PByte(LDataPtr), Length(AData), + @Result[0], LSize) = Nil Then + Raise Exception.Create('FCM HMAC-SHA256 falhou'); + SetLength(Result, LSize); +End; + +Class Function TRESTDWWebPushCrypto.HKDF(Const AIKM, + ASalt, + AInfo : TRESTDWFCMBytes; + ALength : Integer) : TRESTDWFCMBytes; +Var + LPRK, + LT, + LInput : TRESTDWFCMBytes; +Begin + If ALength <= 0 Then + Begin + SetLength(Result, 0); + Exit; + End; + If ALength > 32 Then + Raise Exception.Create('FCM HKDF: comprimento acima de 32 nao suportado'); + + LPRK := HMACSHA256(ASalt, AIKM); + SetLength(LInput, Length(AInfo) + 1); + If Length(AInfo) > 0 Then + Move(AInfo[0], LInput[0], Length(AInfo)); + LInput[High(LInput)] := 1; + LT := HMACSHA256(LPRK, LInput); + SetLength(Result, ALength); + Move(LT[0], Result[0], ALength); +End; + +Class Function TRESTDWWebPushCrypto.ECDHSecret(Const APrivateRaw, + APeerPublicRaw : TRESTDWFCMBytes) : TRESTDWFCMBytes; +Var + LKey : PEC_KEY; + LGroup : PEC_GROUP; + LPrivateBN : PBIGNUM; + LOwnPublic, + LPeerPoint : PEC_POINT; + LSize : Integer; +Begin + If Length(APrivateRaw) <> 32 Then + Raise Exception.Create('FCM ECDH: chave privada P-256 invalida'); + If (Length(APeerPublicRaw) <> 65) Or (APeerPublicRaw[0] <> $04) Then + Raise Exception.Create('FCM ECDH: chave publica remota invalida'); + + LKey := EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + If LKey = Nil Then + Raise Exception.Create('FCM ECDH: EC_KEY_new_by_curve_name falhou'); + Try + LGroup := EC_KEY_get0_group(LKey); + LPrivateBN := BN_bin2bn(@APrivateRaw[0], Length(APrivateRaw), Nil); + If LPrivateBN = Nil Then + Raise Exception.Create('FCM ECDH: BN_bin2bn falhou'); + Try + If EC_KEY_set_private_key(LKey, LPrivateBN) <> 1 Then + Raise Exception.Create('FCM ECDH: set private falhou'); + + LOwnPublic := EC_POINT_new(LGroup); + If LOwnPublic = Nil Then + Raise Exception.Create('FCM ECDH: EC_POINT_new falhou'); + Try + If EC_POINT_mul(LGroup, LOwnPublic, LPrivateBN, Nil, Nil, Nil) <> 1 Then + Raise Exception.Create('FCM ECDH: public point falhou'); + If EC_KEY_set_public_key(LKey, LOwnPublic) <> 1 Then + Raise Exception.Create('FCM ECDH: set public falhou'); + Finally + EC_POINT_free(LOwnPublic); + End; + + LPeerPoint := EC_POINT_new(LGroup); + If LPeerPoint = Nil Then + Raise Exception.Create('FCM ECDH: peer point falhou'); + Try + If EC_POINT_oct2point(LGroup, LPeerPoint, @APeerPublicRaw[0], + Length(APeerPublicRaw), Nil) <> 1 Then + Raise Exception.Create('FCM ECDH: chave publica remota invalida'); + SetLength(Result, 32); + LSize := ECDH_compute_key(@Result[0], Length(Result), LPeerPoint, LKey, Nil); + If LSize <= 0 Then + Raise Exception.Create('FCM ECDH_compute_key falhou'); + SetLength(Result, LSize); + Finally + EC_POINT_free(LPeerPoint); + End; + Finally + BN_free(LPrivateBN); + End; + Finally + EC_KEY_free(LKey); + End; +End; + +Class Function TRESTDWWebPushCrypto.AESGCMDecrypt(Const AKey, + ANonce, + ACipherAndTag : TRESTDWFCMBytes) : TRESTDWFCMBytes; +Var + LCtx : PEVP_CIPHER_CTX; + LCipher, + LTag : TRESTDWFCMBytes; + LLen, + LFinal, + LOut : Integer; +Begin + If Length(ACipherAndTag) < 16 Then + Raise Exception.Create('FCM AES-GCM: ciphertext curto'); + SetLength(LCipher, Length(ACipherAndTag) - 16); + SetLength(LTag, 16); + If Length(LCipher) > 0 Then + Move(ACipherAndTag[0], LCipher[0], Length(LCipher)); + Move(ACipherAndTag[Length(LCipher)], LTag[0], 16); + + LCtx := EVP_CIPHER_CTX_new; + If LCtx = Nil Then + Raise Exception.Create('FCM AES-GCM: contexto invalido'); + Try + If EVP_DecryptInit_ex(LCtx, EVP_aes_128_gcm, Nil, Nil, Nil) <> 1 Then + Raise Exception.Create('FCM AES-GCM: init falhou'); + If EVP_CIPHER_CTX_ctrl(LCtx, EVP_CTRL_GCM_SET_IVLEN, Length(ANonce), Nil) <> 1 Then + Raise Exception.Create('FCM AES-GCM: nonce invalido'); + If EVP_DecryptInit_ex(LCtx, Nil, Nil, @AKey[0], @ANonce[0]) <> 1 Then + Raise Exception.Create('FCM AES-GCM: key init falhou'); + + SetLength(Result, Length(LCipher) + 16); + LOut := 0; + If Length(LCipher) > 0 Then + Begin + LLen := 0; + If EVP_DecryptUpdate(LCtx, @Result[0], @LLen, @LCipher[0], Length(LCipher)) <> 1 Then + Raise Exception.Create('FCM AES-GCM: decrypt falhou'); + LOut := LLen; + End; + + If EVP_CIPHER_CTX_ctrl(LCtx, EVP_CTRL_GCM_SET_TAG, Length(LTag), @LTag[0]) <> 1 Then + Raise Exception.Create('FCM AES-GCM: tag invalida'); + LFinal := 0; + If EVP_DecryptFinal_ex(LCtx, @Result[LOut], @LFinal) <> 1 Then + Raise Exception.Create('FCM AES-GCM: autenticacao falhou'); + Inc(LOut, LFinal); + SetLength(Result, LOut); + Finally + EVP_CIPHER_CTX_free(LCtx); + End; +End; + +Class Function TRESTDWWebPushCrypto.BuildContext(Const AReceiverPublic, + ASenderPublic : TRESTDWFCMBytes) : TRESTDWFCMBytes; +Var + LPrefix : TRESTDWFCMBytes; + P : Integer; + L : Word; +Begin + LPrefix := BytesOf('P-256'#0); + SetLength(Result, Length(LPrefix) + 2 + Length(AReceiverPublic) + 2 + Length(ASenderPublic)); + P := 0; + If Length(LPrefix) > 0 Then + Begin + Move(LPrefix[0], Result[P], Length(LPrefix)); + Inc(P, Length(LPrefix)); + End; + L := Length(AReceiverPublic); + Result[P] := Byte(L Shr 8); + Result[P + 1] := Byte(L); + Inc(P, 2); + Move(AReceiverPublic[0], Result[P], Length(AReceiverPublic)); + Inc(P, Length(AReceiverPublic)); + L := Length(ASenderPublic); + Result[P] := Byte(L Shr 8); + Result[P + 1] := Byte(L); + Inc(P, 2); + Move(ASenderPublic[0], Result[P], Length(ASenderPublic)); +End; + +Class Function TRESTDWWebPushCrypto.ParseHeaderParam(Const AHeader, + AName : String) : String; +Var + S, + LPart, + LName : String; + P, + LSep, + LSemi, + LComma : Integer; +Begin + Result := ''; + LName := LowerCase(AName) + '='; + S := AHeader; + While S <> '' Do + Begin + LSemi := Pos(';', S); + LComma := Pos(',', S); + If (LSemi > 0) And (LComma > 0) Then + Begin + If LSemi < LComma Then + LSep := LSemi + Else + LSep := LComma; + End + Else + If LSemi > 0 Then + LSep := LSemi + Else + LSep := LComma; + + If LSep > 0 Then + Begin + LPart := Trim(Copy(S, 1, LSep - 1)); + Delete(S, 1, LSep); + End + Else + Begin + LPart := Trim(S); + S := ''; + End; + + P := Pos(LName, LowerCase(LPart)); + If P = 1 Then + Begin + Result := Copy(LPart, Length(LName) + 1, MaxInt); + Exit; + End; + End; +End; + +Class Function TRESTDWWebPushCrypto.ParseRecordSize(Const AEncryptionHeader : String) : Integer; +Var + S : String; +Begin + S := ParseHeaderParam(AEncryptionHeader, 'rs'); + If S = '' Then + Result := 4096 + Else + Result := StrToIntDef(S, 4096); + If Result < 3 Then + Result := 4096; +End; + +Class Function TRESTDWWebPushCrypto.NonceForCounter(Const ABaseNonce : TRESTDWFCMBytes; + ACounter : TRESTDWFCMUInt64) : TRESTDWFCMBytes; +Var + I : Integer; +Begin + Result := Copy(ABaseNonce, 0, Length(ABaseNonce)); + If Length(Result) <> 12 Then + Raise Exception.Create('FCM nonce base invalido'); + For I := 0 To 7 Do + Result[11 - I] := Result[11 - I] Xor Byte(ACounter Shr (I * 8)); +End; + +Class Function TRESTDWWebPushCrypto.DecryptAESGCM(Const APrivateKeyB64, + APublicKeyB64, + AAuthB64, + ACryptoKeyHeader, + AEncryptionHeader : String; + Const ARawData : TRESTDWFCMBytes) : TRESTDWFCMBytes; +Var + LSenderKey, + LSaltText : String; + LPrivate, + LReceiverPublic, + LSenderPublic, + LAuth, + LSalt, + LShared, + LContext, + LAuthInfo, + LSecret, + LKeyInfo, + LNonceInfo, + LKey, + LNonce, + LEncrypted, + LPlain, + LOne : TRESTDWFCMBytes; + LChunk, + LRecordSize, + LPosition, + LTake, + LPadding, + I : Integer; + LCounter : TRESTDWFCMUInt64; +Begin + LSenderKey := ParseHeaderParam(ACryptoKeyHeader, 'dh'); + LSaltText := ParseHeaderParam(AEncryptionHeader, 'salt'); + If LSenderKey = '' Then + Raise Exception.Create('FCM crypto-key/dh ausente'); + If LSaltText = '' Then + Raise Exception.Create('FCM encryption/salt ausente'); + + LPrivate := RESTDWFCMBase64URLDecode(APrivateKeyB64); + LReceiverPublic := RESTDWFCMBase64URLDecode(APublicKeyB64); + LSenderPublic := RESTDWFCMBase64URLDecode(LSenderKey); + LAuth := RESTDWFCMBase64URLDecode(AAuthB64); + LSalt := RESTDWFCMBase64URLDecode(LSaltText); + If Length(LSalt) <> 16 Then + Raise Exception.Create('FCM salt invalido'); + + LShared := ECDHSecret(LPrivate, LSenderPublic); + LContext := BuildContext(LReceiverPublic, LSenderPublic); + LAuthInfo := BytesOf('Content-Encoding: auth'#0); + LSecret := HKDF(LShared, LAuth, LAuthInfo, 32); + LKeyInfo := Concat(BytesOf('Content-Encoding: aesgcm'#0), LContext); + LNonceInfo := Concat(BytesOf('Content-Encoding: nonce'#0), LContext); + LKey := HKDF(LSecret, LSalt, LKeyInfo, 16); + LNonce := HKDF(LSecret, LSalt, LNonceInfo, 12); + + LRecordSize := ParseRecordSize(AEncryptionHeader); + LChunk := LRecordSize + 16; + LPosition := 0; + LCounter := 0; + SetLength(Result, 0); + + While LPosition < Length(ARawData) Do + Begin + LTake := LChunk; + If LPosition + LTake > Length(ARawData) Then + LTake := Length(ARawData) - LPosition; + SetLength(LEncrypted, LTake); + Move(ARawData[LPosition], LEncrypted[0], LTake); + LPlain := AESGCMDecrypt(LKey, NonceForCounter(LNonce, LCounter), LEncrypted); + If Length(LPlain) < 2 Then + Raise Exception.Create('FCM payload sem padding'); + LPadding := (Integer(LPlain[0]) Shl 8) Or Integer(LPlain[1]); + If 2 + LPadding > Length(LPlain) Then + Raise Exception.Create('FCM padding invalido'); + For I := 0 To LPadding - 1 Do + If LPlain[2 + I] <> 0 Then + Raise Exception.Create('FCM padding nao-zero'); + SetLength(LOne, Length(LPlain) - 2 - LPadding); + If Length(LOne) > 0 Then + Move(LPlain[2 + LPadding], LOne[0], Length(LOne)); + Result := Concat(Result, LOne); + Inc(LPosition, LTake); + Inc(LCounter); + End; +End; + +End. diff --git a/CORE/Source/Sockets/uRESTDWFCMFIS.pas b/CORE/Source/Sockets/uRESTDWFCMFIS.pas new file mode 100644 index 000000000..2e25150f5 --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFCMFIS.pas @@ -0,0 +1,163 @@ +Unit uRESTDWFCMFIS; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + uRESTDWFCMTypes, + uRESTDWFCMTransport; + +Type + TRESTDWFirebaseInstallations = Class + Private + FConfig : TRESTDWFCMConfig; + FHTTP : TRESTDWFCMHTTPTransport; + Function NewFID : String; + Function Post(Const AURL, + ABody : String; + AHeaders : TStrings; + Var AResponse : String) : Integer; + Public + Constructor Create(Const AConfig : TRESTDWFCMConfig; + AHTTP : TRESTDWFCMHTTPTransport); + Procedure CreateInstallation(Var ACredentials : TRESTDWFCMCredentials); + Procedure RefreshAuthToken(Var ACredentials : TRESTDWFCMCredentials); + End; + +Implementation + +Uses + uRESTDWFCMCompat, + uRESTDWOpenSslLib; + +Constructor TRESTDWFirebaseInstallations.Create(Const AConfig : TRESTDWFCMConfig; + AHTTP : TRESTDWFCMHTTPTransport); +Begin + Inherited Create; + FConfig := AConfig; + FHTTP := AHTTP; +End; + +Function TRESTDWFirebaseInstallations.Post(Const AURL, + ABody : String; + AHeaders : TStrings; + Var AResponse : String) : Integer; +Var + LBody, + LResponse, + LError : TRESTDWFCMUTF8Stream; +Begin + LBody := TRESTDWFCMUTF8Stream.Create(ABody); + LResponse := TRESTDWFCMUTF8Stream.Create(''); + LError := TRESTDWFCMUTF8Stream.Create(''); + Try + Result := FHTTP.Post(AURL, AHeaders, LBody, LResponse, LError); + If LResponse.Size > 0 Then + AResponse := LResponse.AsString + Else + AResponse := LError.AsString; + Finally + LError.Free; + LResponse.Free; + LBody.Free; + End; +End; + +Function TRESTDWFirebaseInstallations.NewFID : String; +Var + LBytes : TRESTDWFCMBytes; +Begin + SetLength(LBytes, 17); + + If RAND_bytes( + @LBytes[0], + Length(LBytes) + ) <> 1 Then + Raise Exception.Create('FIS: RAND_bytes falhou'); + + LBytes[0] := (LBytes[0] And $0F) Or $70; + Result := RESTDWFCMBase64URL(LBytes); + If Length(Result) > 22 Then + SetLength(Result, 22); +End; + +Procedure TRESTDWFirebaseInstallations.CreateInstallation(Var ACredentials : TRESTDWFCMCredentials); +Var + LURL, + LBody, + LResponse : String; + LHeaders : TStringList; + LCode : Integer; +Begin + If ACredentials.FID = '' Then + ACredentials.FID := NewFID; + + LURL := 'https://firebaseinstallations.googleapis.com/v1/projects/' + + FConfig.ProjectID + '/installations'; + + LBody := '{"fid":"' + ACredentials.FID + + '","appId":"' + FConfig.AppID + + '","authVersion":"FIS_v2","sdkVersion":"a:16.3.1"}'; + + LHeaders := TStringList.Create; + Try + LHeaders.Values['x-goog-api-key'] := FConfig.APIKey; + LHeaders.Values['Content-Type'] := 'application/json'; + LHeaders.Values['Accept'] := 'application/json'; + + LCode := Post(LURL, LBody, LHeaders, LResponse); + If (LCode Div 100) <> 2 Then + Raise Exception.Create('FIS CreateInstallation HTTP ' + + IntToStr(LCode) + ': ' + LResponse); + Finally + LHeaders.Free; + End; + + ACredentials.FID := RESTDWFCMJSONValue(LResponse, 'fid'); + ACredentials.FISRefreshToken := RESTDWFCMJSONValue(LResponse, 'refreshToken'); + ACredentials.FISAuthToken := RESTDWFCMJSONValue(LResponse, 'token'); + + If (ACredentials.FID = '') Or + (ACredentials.FISRefreshToken = '') Then + Raise Exception.Create('FIS CreateInstallation retornou dados invalidos'); +End; + +Procedure TRESTDWFirebaseInstallations.RefreshAuthToken(Var ACredentials : TRESTDWFCMCredentials); +Var + LURL, + LBody, + LResponse : String; + LHeaders : TStringList; + LCode : Integer; +Begin + LURL := 'https://firebaseinstallations.googleapis.com/v1/projects/' + + FConfig.ProjectID + '/installations/' + + ACredentials.FID + '/authTokens:generate'; + + LBody := '{"installation":{"appId":"' + FConfig.AppID + + '","sdkVersion":"a:16.3.1"}}'; + + LHeaders := TStringList.Create; + Try + LHeaders.Values['x-goog-api-key'] := FConfig.APIKey; + LHeaders.Values['Authorization'] := 'FIS_v2 ' + ACredentials.FISRefreshToken; + LHeaders.Values['Content-Type'] := 'application/json'; + LHeaders.Values['Accept'] := 'application/json'; + + LCode := Post(LURL, LBody, LHeaders, LResponse); + If (LCode Div 100) <> 2 Then + Raise Exception.Create('FIS RefreshAuthToken HTTP ' + + IntToStr(LCode) + ': ' + LResponse); + Finally + LHeaders.Free; + End; + + ACredentials.FISAuthToken := RESTDWFCMJSONValue(LResponse, 'token'); + If ACredentials.FISAuthToken = '' Then + Raise Exception.Create('FIS RefreshAuthToken retornou token vazio'); +End; + +End. diff --git a/CORE/Source/Sockets/uRESTDWFCMJSON.pas b/CORE/Source/Sockets/uRESTDWFCMJSON.pas new file mode 100644 index 000000000..d45b91308 --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFCMJSON.pas @@ -0,0 +1,1955 @@ +Unit uRESTDWFCMJSON; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + uRESTDWFCMMessage, + uRESTDWFCMValue; + +Function RESTDWFCMMessageToJSON(Const ADeviceToken : String; + AMessage : TRESTDWFCMMessage) : String; + +Function RESTDWFCMMessageToJSONTarget(Const ATargetName, + ATargetValue : String; + AMessage : TRESTDWFCMMessage; + AValidateOnly : Boolean) : String; + +Procedure RESTDWFCMJSONToMessage(Const AJSON : String; + AMessage : TRESTDWFCMMessage); + +Procedure RESTDWFCMJSONToData(Const AJSON : String; + AData : TStrings); + +Implementation + +Uses + uRESTDWFCMCompat; + +Function JSONEscape(Const AValue : String) : String; +Const + CHex : String = '0123456789ABCDEF'; +Var + I : Integer; + C : Char; +Begin + Result := ''; + + For I := 1 To Length(AValue) Do + Begin + C := AValue[I]; + + Case C Of + '"' : + Result := Result + '\"'; + + '\' : + Result := Result + '\\'; + + #8 : + Result := Result + '\b'; + + #9 : + Result := Result + '\t'; + + #10 : + Result := Result + '\n'; + + #12 : + Result := Result + '\f'; + + #13 : + Result := Result + '\r'; + Else + Begin + If Ord(C) < 32 Then + Result := + Result + + '\u00' + + CHex[(Ord(C) Shr 4) + 1] + + CHex[(Ord(C) And $0F) + 1] + Else + Result := Result + C; + End; + End; + End; +End; + +Function JSONHexValue(AChar : Char) : Integer; +Begin + If (AChar >= '0') And + (AChar <= '9') Then + Result := Ord(AChar) - Ord('0') + Else + If (AChar >= 'A') And + (AChar <= 'F') Then + Result := Ord(AChar) - Ord('A') + 10 + Else + If (AChar >= 'a') And + (AChar <= 'f') Then + Result := Ord(AChar) - Ord('a') + 10 + Else + Result := -1; +End; + +Function JSONCodePointToString(ACodePoint : Cardinal) : String; +Var + LBytes : TRESTDWFCMBytes; +Begin + If ACodePoint <= $7F Then + Begin + SetLength(LBytes, 1); + LBytes[0] := Byte(ACodePoint); + End + Else + If ACodePoint <= $7FF Then + Begin + SetLength(LBytes, 2); + LBytes[0] := Byte($C0 Or (ACodePoint Shr 6)); + LBytes[1] := Byte($80 Or (ACodePoint And $3F)); + End + Else + If ACodePoint <= $FFFF Then + Begin + SetLength(LBytes, 3); + LBytes[0] := Byte($E0 Or (ACodePoint Shr 12)); + LBytes[1] := Byte($80 Or ((ACodePoint Shr 6) And $3F)); + LBytes[2] := Byte($80 Or (ACodePoint And $3F)); + End + Else + Begin + If ACodePoint > $10FFFF Then + ACodePoint := $FFFD; + + SetLength(LBytes, 4); + LBytes[0] := Byte($F0 Or (ACodePoint Shr 18)); + LBytes[1] := Byte($80 Or ((ACodePoint Shr 12) And $3F)); + LBytes[2] := Byte($80 Or ((ACodePoint Shr 6) And $3F)); + LBytes[3] := Byte($80 Or (ACodePoint And $3F)); + End; + + Result := RESTDWFCMBytesToString(LBytes); +End; + +Function JSONReadHex4(Const AValue : String; + APosition : Integer; + Var ACode : Cardinal) : Boolean; +Var + I, + LHex : Integer; +Begin + Result := False; + ACode := 0; + + If APosition + 3 > Length(AValue) Then + Exit; + + For I := 0 To 3 Do + Begin + LHex := JSONHexValue(AValue[APosition + I]); + + If LHex < 0 Then + Exit; + + ACode := (ACode Shl 4) Or Cardinal(LHex); + End; + + Result := True; +End; + +Function JSONUnescape(Const AValue : String) : String; +Var + I : Integer; + C : Char; + LCode, + LLow, + LCodePoint : Cardinal; +Begin + Result := ''; + I := 1; + + While I <= Length(AValue) Do + Begin + If (AValue[I] = '\') And + (I < Length(AValue)) Then + Begin + Inc(I); + C := AValue[I]; + + Case C Of + '"' : Result := Result + '"'; + '\' : Result := Result + '\'; + '/' : Result := Result + '/'; + 'b' : Result := Result + #8; + 'f' : Result := Result + #12; + 'n' : Result := Result + #10; + 'r' : Result := Result + #13; + 't' : Result := Result + #9; + + 'u': + Begin + If JSONReadHex4(AValue, I + 1, LCode) Then + Begin + Inc(I, 4); + + If (LCode >= $D800) And + (LCode <= $DBFF) And + (I + 6 <= Length(AValue)) And + (AValue[I + 1] = '\') And + (AValue[I + 2] = 'u') And + JSONReadHex4(AValue, I + 3, LLow) And + (LLow >= $DC00) And + (LLow <= $DFFF) Then + Begin + LCodePoint := + $10000 + + ((LCode - $D800) Shl 10) + + (LLow - $DC00); + + Inc(I, 6); + Result := Result + JSONCodePointToString(LCodePoint); + End + Else + Result := Result + JSONCodePointToString(LCode); + End + Else + Result := Result + '\u'; + End; + Else + Result := Result + C; + End; + End + Else + Result := Result + AValue[I]; + + Inc(I); + End; +End; + +Procedure AddComma(Var AJSON : String; + Var AFirst : Boolean); +Begin + If Not AFirst Then + AJSON := AJSON + ','; + + AFirst := False; +End; + +Procedure AddString(Var AJSON : String; + Var AFirst : Boolean; + Const AName, + AValue : String); +Begin + If AValue = '' Then + Exit; + + AddComma(AJSON, AFirst); + + AJSON := + AJSON + + '"' + AName + '":"' + + JSONEscape(AValue) + + '"'; +End; + +Procedure AddBoolean(Var AJSON : String; + Var AFirst : Boolean; + Const AName : String; + AValue : Boolean); +Begin + If Not AValue Then + Exit; + + AddComma(AJSON, AFirst); + + AJSON := + AJSON + + '"' + AName + '":true'; +End; + +Procedure AddInteger(Var AJSON : String; + Var AFirst : Boolean; + Const AName : String; + AValue, + AMinimum : Integer); +Begin + If AValue < AMinimum Then + Exit; + + AddComma(AJSON, AFirst); + + AJSON := + AJSON + + '"' + AName + '":' + + IntToStr(AValue); +End; + +Procedure AddNumberText(Var AJSON : String; + Var AFirst : Boolean; + Const AName, + AValue : String); +Begin + If AValue = '' Then + Exit; + + AddComma(AJSON, AFirst); + + AJSON := + AJSON + + '"' + AName + '":' + + AValue; +End; + +Function StringListObject(AList : TStrings) : String; +Var + I : Integer; + LFirst : Boolean; +Begin + Result := '{'; + LFirst := True; + + For I := 0 To AList.Count - 1 Do + If AList.Names[I] <> '' Then + AddString( + Result, + LFirst, + AList.Names[I], + AList.ValueFromIndex[I] + ); + + Result := Result + '}'; +End; + +Function StringListArray(AList : TStrings) : String; +Var + I : Integer; +Begin + Result := '['; + + For I := 0 To AList.Count - 1 Do + Begin + If I > 0 Then + Result := Result + ','; + + Result := + Result + + '"' + + JSONEscape(AList[I]) + + '"'; + End; + + Result := Result + ']'; +End; + +Function HexDigit(AChar : Char) : Integer; +Begin + AChar := UpCase(AChar); + + If (AChar >= '0') And + (AChar <= '9') Then + Result := Ord(AChar) - Ord('0') + Else + If (AChar >= 'A') And + (AChar <= 'F') Then + Result := Ord(AChar) - Ord('A') + 10 + Else + Result := 0; +End; + +Function HexByte(Const AValue : String; + APosition : Integer) : Integer; +Begin + Result := + (HexDigit(AValue[APosition]) Shl 4) Or + HexDigit(AValue[APosition + 1]); +End; + +Function ColorPartJSON(AValue : Integer) : String; +Var + LValue : Integer; + LText : String; +Begin + If AValue <= 0 Then + Begin + Result := '0'; + Exit; + End; + + If AValue >= 255 Then + Begin + Result := '1'; + Exit; + End; + + LValue := + (AValue * 1000000) Div 255; + + LText := IntToStr(LValue); + + While Length(LText) < 6 Do + LText := '0' + LText; + + Result := '0.' + LText; + + While (Length(Result) > 1) And + (Result[Length(Result)] = '0') Do + Delete( + Result, + Length(Result), + 1 + ); +End; + +Function WebPushActionsJSON(Actions : TRESTDWFCMWebPushActions) : String; +Var + I : Integer; + LFirst : Boolean; + LItem : TRESTDWFCMWebPushAction; + LJSON : String; +Begin + Result := '['; + + For I := 0 To Actions.Count - 1 Do + Begin + LItem := Actions[I]; + + If I > 0 Then + Result := Result + ','; + + LJSON := '{'; + LFirst := True; + + AddString( + LJSON, + LFirst, + 'action', + LItem.Action + ); + + AddString( + LJSON, + LFirst, + 'title', + LItem.Title + ); + + AddString( + LJSON, + LFirst, + 'icon', + LItem.Icon + ); + + LJSON := LJSON + '}'; + Result := Result + LJSON; + End; + + Result := Result + ']'; +End; + +Function FCMValueJSON(AValue : TRESTDWFCMValue) : String; +Var + I : Integer; + LFirst : Boolean; + LItem : TRESTDWFCMValue; +Begin + If AValue = Nil Then + Begin + Result := 'null'; + Exit; + End; + + Case AValue.Kind Of + fvkNull: + Result := 'null'; + + fvkString: + Result := '"' + JSONEscape(AValue.StringValue) + '"'; + + fvkNumber: + Begin + If AValue.NumberValue = '' Then + Result := '0' + Else + Result := AValue.NumberValue; + End; + + fvkBoolean: + Begin + If AValue.BooleanValue Then + Result := 'true' + Else + Result := 'false'; + End; + + fvkObject: + Begin + Result := '{'; + LFirst := True; + + For I := 0 To AValue.Count - 1 Do + Begin + LItem := AValue[I]; + + If LItem.Name <> '' Then + Begin + AddComma(Result, LFirst); + + Result := + Result + + '"' + JSONEscape(LItem.Name) + '":' + + FCMValueJSON(LItem); + End; + End; + + Result := Result + '}'; + End; + + fvkArray: + Begin + Result := '['; + + For I := 0 To AValue.Count - 1 Do + Begin + If I > 0 Then + Result := Result + ','; + + Result := + Result + + FCMValueJSON(AValue[I]); + End; + + Result := Result + ']'; + End; + Else + Result := 'null'; + End; +End; + +Procedure AddFCMValueItems(Var AJSON : String; + Var AFirst : Boolean; + AObject : TRESTDWFCMValue); +Var + I : Integer; + LItem : TRESTDWFCMValue; +Begin + If AObject = Nil Then + Exit; + + If AObject.Kind <> fvkObject Then + Exit; + + For I := 0 To AObject.Count - 1 Do + Begin + LItem := AObject[I]; + + If LItem.Name <> '' Then + Begin + AddComma(AJSON, AFirst); + + AJSON := + AJSON + + '"' + JSONEscape(LItem.Name) + '":' + + FCMValueJSON(LItem); + End; + End; +End; + +Function AndroidJSON(AMessage : TRESTDWFCMMessage) : String; +Var + LFirst, + LNotificationFirst, + LLightFirst : Boolean; + LNotification, + LLight : String; + I : Integer; +Begin + Result := '{'; + LFirst := True; + + AddString( + Result, + LFirst, + 'collapse_key', + AMessage.Android.CollapseKey + ); + + AddString( + Result, + LFirst, + 'priority', + AMessage.Android.Priority + ); + + AddString( + Result, + LFirst, + 'ttl', + AMessage.Android.TTL + ); + + AddString( + Result, + LFirst, + 'restricted_package_name', + AMessage.Android.RestrictedPackageName + ); + + AddBoolean( + Result, + LFirst, + 'direct_boot_ok', + AMessage.Android.DirectBootOK + ); + + AddBoolean( + Result, + LFirst, + 'bandwidth_constrained_ok', + AMessage.Android.BandwidthConstrainedOK + ); + + AddBoolean( + Result, + LFirst, + 'restricted_satellite_ok', + AMessage.Android.RestrictedSatelliteOK + ); + + If AMessage.Android.Data.Count > 0 Then + Begin + AddComma(Result, LFirst); + + Result := + Result + + '"data":' + + StringListObject(AMessage.Android.Data); + End; + + LNotification := '{'; + LNotificationFirst := True; + + AddString( + LNotification, + LNotificationFirst, + 'title', + AMessage.Android.Title + ); + + AddString( + LNotification, + LNotificationFirst, + 'body', + AMessage.Android.Body + ); + + AddString( + LNotification, + LNotificationFirst, + 'icon', + AMessage.Android.Icon + ); + + AddString( + LNotification, + LNotificationFirst, + 'color', + AMessage.Android.Color + ); + + AddString( + LNotification, + LNotificationFirst, + 'sound', + AMessage.Android.Sound + ); + + AddString( + LNotification, + LNotificationFirst, + 'tag', + AMessage.Android.Tag + ); + + AddString( + LNotification, + LNotificationFirst, + 'click_action', + AMessage.Android.ClickAction + ); + + AddString( + LNotification, + LNotificationFirst, + 'body_loc_key', + AMessage.Android.BodyLocKey + ); + + If AMessage.Android.BodyLocArgs.Count > 0 Then + Begin + AddComma( + LNotification, + LNotificationFirst + ); + + LNotification := + LNotification + + '"body_loc_args":' + + StringListArray(AMessage.Android.BodyLocArgs); + End; + + AddString( + LNotification, + LNotificationFirst, + 'title_loc_key', + AMessage.Android.TitleLocKey + ); + + If AMessage.Android.TitleLocArgs.Count > 0 Then + Begin + AddComma( + LNotification, + LNotificationFirst + ); + + LNotification := + LNotification + + '"title_loc_args":' + + StringListArray(AMessage.Android.TitleLocArgs); + End; + + AddString( + LNotification, + LNotificationFirst, + 'channel_id', + AMessage.Android.ChannelID + ); + + AddString( + LNotification, + LNotificationFirst, + 'image', + AMessage.Android.ImageURL + ); + + AddString( + LNotification, + LNotificationFirst, + 'proxy', + AMessage.Android.Proxy + ); + + AddString( + LNotification, + LNotificationFirst, + 'ticker', + AMessage.Android.Ticker + ); + + AddBoolean( + LNotification, + LNotificationFirst, + 'sticky', + AMessage.Android.Sticky + ); + + AddString( + LNotification, + LNotificationFirst, + 'event_time', + AMessage.Android.EventTime + ); + + AddBoolean( + LNotification, + LNotificationFirst, + 'local_only', + AMessage.Android.LocalOnly + ); + + AddString( + LNotification, + LNotificationFirst, + 'notification_priority', + AMessage.Android.NotificationPriority + ); + + AddBoolean( + LNotification, + LNotificationFirst, + 'default_sound', + AMessage.Android.DefaultSound + ); + + AddBoolean( + LNotification, + LNotificationFirst, + 'default_vibrate_timings', + AMessage.Android.DefaultVibrateTimings + ); + + AddBoolean( + LNotification, + LNotificationFirst, + 'default_light_settings', + AMessage.Android.DefaultLightSettings + ); + + If AMessage.Android.VibrateTimings.Count > 0 Then + Begin + AddComma( + LNotification, + LNotificationFirst + ); + + LNotification := + LNotification + + '"vibrate_timings":' + + StringListArray(AMessage.Android.VibrateTimings); + End; + + AddString( + LNotification, + LNotificationFirst, + 'visibility', + AMessage.Android.Visibility + ); + + AddInteger( + LNotification, + LNotificationFirst, + 'notification_count', + AMessage.Android.NotificationCount, + 0 + ); + + LLight := '{'; + LLightFirst := True; + + If (Length(AMessage.Android.LightColor) = 7) And + (AMessage.Android.LightColor[1] = '#') Then + Begin + AddComma( + LLight, + LLightFirst + ); + + LLight := + LLight + + '"color":{' + + '"red":' + + ColorPartJSON( + HexByte( + AMessage.Android.LightColor, + 2 + ) + ) + + ',"green":' + + ColorPartJSON( + HexByte( + AMessage.Android.LightColor, + 4 + ) + ) + + ',"blue":' + + ColorPartJSON( + HexByte( + AMessage.Android.LightColor, + 6 + ) + ) + + ',"alpha":1}'; + End; + + AddString( + LLight, + LLightFirst, + 'light_on_duration', + AMessage.Android.LightOnDuration + ); + + AddString( + LLight, + LLightFirst, + 'light_off_duration', + AMessage.Android.LightOffDuration + ); + + LLight := LLight + '}'; + + If Not LLightFirst Then + Begin + AddComma( + LNotification, + LNotificationFirst + ); + + LNotification := + LNotification + + '"light_settings":' + + LLight; + End; + + For I := 0 To AMessage.Android.Extra.Count - 1 Do + If AMessage.Android.Extra.Names[I] <> '' Then + AddString( + LNotification, + LNotificationFirst, + AMessage.Android.Extra.Names[I], + AMessage.Android.Extra.ValueFromIndex[I] + ); + + LNotification := LNotification + '}'; + + If Not LNotificationFirst Then + Begin + AddComma( + Result, + LFirst + ); + + Result := + Result + + '"notification":' + + LNotification; + End; + + If AMessage.Android.AnalyticsLabel <> '' Then + Begin + AddComma( + Result, + LFirst + ); + + Result := + Result + + '"fcm_options":{"analytics_label":"' + + JSONEscape(AMessage.Android.AnalyticsLabel) + + '"}'; + End; + + Result := Result + '}'; + + If LFirst Then + Result := ''; +End; + +Function APNSJSON(AMessage : TRESTDWFCMMessage) : String; +Var + LFirst, + LPayloadFirst, + LAPSFirst, + LAlertFirst, + LOptionsFirst : Boolean; + LPayload, + LAPS, + LAlert, + LOptions : String; + I : Integer; +Begin + Result := '{'; + LFirst := True; + + If AMessage.APNS.Headers.Count > 0 Then + Begin + AddComma( + Result, + LFirst + ); + + Result := + Result + + '"headers":' + + StringListObject(AMessage.APNS.Headers); + End; + + LPayload := '{'; + LPayloadFirst := True; + + LAPS := '{'; + LAPSFirst := True; + + LAlert := '{'; + LAlertFirst := True; + + AddString( + LAlert, + LAlertFirst, + 'title', + AMessage.APNS.Title + ); + + AddString( + LAlert, + LAlertFirst, + 'subtitle', + AMessage.APNS.Subtitle + ); + + AddString( + LAlert, + LAlertFirst, + 'body', + AMessage.APNS.Body + ); + + AddString( + LAlert, + LAlertFirst, + 'title-loc-key', + AMessage.APNS.TitleLocKey + ); + + If AMessage.APNS.TitleLocArgs.Count > 0 Then + Begin + AddComma( + LAlert, + LAlertFirst + ); + + LAlert := + LAlert + + '"title-loc-args":' + + StringListArray(AMessage.APNS.TitleLocArgs); + End; + + AddString( + LAlert, + LAlertFirst, + 'subtitle-loc-key', + AMessage.APNS.SubtitleLocKey + ); + + If AMessage.APNS.SubtitleLocArgs.Count > 0 Then + Begin + AddComma( + LAlert, + LAlertFirst + ); + + LAlert := + LAlert + + '"subtitle-loc-args":' + + StringListArray(AMessage.APNS.SubtitleLocArgs); + End; + + AddString( + LAlert, + LAlertFirst, + 'loc-key', + AMessage.APNS.BodyLocKey + ); + + If AMessage.APNS.BodyLocArgs.Count > 0 Then + Begin + AddComma( + LAlert, + LAlertFirst + ); + + LAlert := + LAlert + + '"loc-args":' + + StringListArray(AMessage.APNS.BodyLocArgs); + End; + + AddString( + LAlert, + LAlertFirst, + 'launch-image', + AMessage.APNS.LaunchImage + ); + + LAlert := LAlert + '}'; + + If Not LAlertFirst Then + Begin + AddComma( + LAPS, + LAPSFirst + ); + + LAPS := + LAPS + + '"alert":' + + LAlert; + End; + + AddString( + LAPS, + LAPSFirst, + 'sound', + AMessage.APNS.Sound + ); + + AddInteger( + LAPS, + LAPSFirst, + 'badge', + AMessage.APNS.Badge, + 0 + ); + + AddString( + LAPS, + LAPSFirst, + 'category', + AMessage.APNS.Category + ); + + AddString( + LAPS, + LAPSFirst, + 'thread-id', + AMessage.APNS.ThreadID + ); + + If AMessage.APNS.ContentAvailable Then + Begin + AddComma( + LAPS, + LAPSFirst + ); + + LAPS := + LAPS + + '"content-available":1'; + End; + + If AMessage.APNS.MutableContent Then + Begin + AddComma( + LAPS, + LAPSFirst + ); + + LAPS := + LAPS + + '"mutable-content":1'; + End; + + AddString( + LAPS, + LAPSFirst, + 'target-content-id', + AMessage.APNS.TargetContentID + ); + + AddString( + LAPS, + LAPSFirst, + 'interruption-level', + AMessage.APNS.InterruptionLevel + ); + + AddNumberText( + LAPS, + LAPSFirst, + 'relevance-score', + AMessage.APNS.RelevanceScore + ); + + AddString( + LAPS, + LAPSFirst, + 'filter-criteria', + AMessage.APNS.FilterCriteria + ); + + AddNumberText( + LAPS, + LAPSFirst, + 'stale-date', + AMessage.APNS.StaleDate + ); + + AddNumberText( + LAPS, + LAPSFirst, + 'timestamp', + AMessage.APNS.LiveActivityTimestamp + ); + + AddString( + LAPS, + LAPSFirst, + 'event', + AMessage.APNS.LiveActivityEvent + ); + + AddNumberText( + LAPS, + LAPSFirst, + 'dismissal-date', + AMessage.APNS.LiveActivityDismissalDate + ); + + If AMessage.APNS.ContentState.Count > 0 Then + Begin + AddComma( + LAPS, + LAPSFirst + ); + + LAPS := + LAPS + + '"content-state":' + + FCMValueJSON( + AMessage.APNS.ContentState + ); + End; + + AddString( + LAPS, + LAPSFirst, + 'attributes-type', + AMessage.APNS.LiveActivityAttributesType + ); + + If AMessage.APNS.Attributes.Count > 0 Then + Begin + AddComma( + LAPS, + LAPSFirst + ); + + LAPS := + LAPS + + '"attributes":' + + FCMValueJSON( + AMessage.APNS.Attributes + ); + End; + + AddFCMValueItems( + LAPS, + LAPSFirst, + AMessage.APNS.APSExtra + ); + + LAPS := LAPS + '}'; + + If Not LAPSFirst Then + Begin + AddComma( + LPayload, + LPayloadFirst + ); + + LPayload := + LPayload + + '"aps":' + + LAPS; + End; + + For I := 0 To AMessage.APNS.CustomData.Count - 1 Do + If AMessage.APNS.CustomData.Names[I] <> '' Then + AddString( + LPayload, + LPayloadFirst, + AMessage.APNS.CustomData.Names[I], + AMessage.APNS.CustomData.ValueFromIndex[I] + ); + + AddFCMValueItems( + LPayload, + LPayloadFirst, + AMessage.APNS.PayloadExtra + ); + + LPayload := LPayload + '}'; + + If Not LPayloadFirst Then + Begin + AddComma( + Result, + LFirst + ); + + Result := + Result + + '"payload":' + + LPayload; + End; + + If AMessage.APNS.LiveActivityToken <> '' Then + Begin + AddComma( + Result, + LFirst + ); + + Result := + Result + + '"live_activity_token":"' + + JSONEscape(AMessage.APNS.LiveActivityToken) + + '"'; + End; + + LOptions := '{'; + LOptionsFirst := True; + + AddString( + LOptions, + LOptionsFirst, + 'image', + AMessage.APNS.ImageURL + ); + + AddString( + LOptions, + LOptionsFirst, + 'analytics_label', + AMessage.APNS.AnalyticsLabel + ); + + LOptions := LOptions + '}'; + + If Not LOptionsFirst Then + Begin + AddComma( + Result, + LFirst + ); + + Result := + Result + + '"fcm_options":' + + LOptions; + End; + + Result := Result + '}'; + + If LFirst Then + Result := ''; +End; + +Function WebPushJSON(AMessage : TRESTDWFCMMessage) : String; +Var + LFirst, + LNotificationFirst, + LOptionsFirst : Boolean; + LNotification, + LOptions : String; + I : Integer; +Begin + Result := '{'; + LFirst := True; + + If AMessage.WebPush.Headers.Count > 0 Then + Begin + AddComma( + Result, + LFirst + ); + + Result := + Result + + '"headers":' + + StringListObject(AMessage.WebPush.Headers); + End; + + If AMessage.WebPush.Data.Count > 0 Then + Begin + AddComma( + Result, + LFirst + ); + + Result := + Result + + '"data":' + + StringListObject(AMessage.WebPush.Data); + End; + + LNotification := '{'; + LNotificationFirst := True; + + AddString( + LNotification, + LNotificationFirst, + 'title', + AMessage.WebPush.Title + ); + + AddString( + LNotification, + LNotificationFirst, + 'body', + AMessage.WebPush.Body + ); + + AddString( + LNotification, + LNotificationFirst, + 'icon', + AMessage.WebPush.Icon + ); + + AddString( + LNotification, + LNotificationFirst, + 'image', + AMessage.WebPush.ImageURL + ); + + AddString( + LNotification, + LNotificationFirst, + 'badge', + AMessage.WebPush.Badge + ); + + AddString( + LNotification, + LNotificationFirst, + 'tag', + AMessage.WebPush.Tag + ); + + AddString( + LNotification, + LNotificationFirst, + 'lang', + AMessage.WebPush.Language + ); + + AddString( + LNotification, + LNotificationFirst, + 'dir', + AMessage.WebPush.Direction + ); + + AddBoolean( + LNotification, + LNotificationFirst, + 'renotify', + AMessage.WebPush.Renotify + ); + + AddBoolean( + LNotification, + LNotificationFirst, + 'requireInteraction', + AMessage.WebPush.RequireInteraction + ); + + AddBoolean( + LNotification, + LNotificationFirst, + 'silent', + AMessage.WebPush.Silent + ); + + AddNumberText( + LNotification, + LNotificationFirst, + 'timestamp', + AMessage.WebPush.Timestamp + ); + + If AMessage.WebPush.Vibrate.Count > 0 Then + Begin + AddComma( + LNotification, + LNotificationFirst + ); + + LNotification := + LNotification + + '"vibrate":['; + + For I := 0 To AMessage.WebPush.Vibrate.Count - 1 Do + Begin + If I > 0 Then + LNotification := LNotification + ','; + + LNotification := + LNotification + + AMessage.WebPush.Vibrate[I]; + End; + + LNotification := + LNotification + + ']'; + End; + + If AMessage.WebPush.Actions.Count > 0 Then + Begin + AddComma( + LNotification, + LNotificationFirst + ); + + LNotification := + LNotification + + '"actions":' + + WebPushActionsJSON( + AMessage.WebPush.Actions + ); + End; + + AddFCMValueItems( + LNotification, + LNotificationFirst, + AMessage.WebPush.NotificationExtra + ); + + For I := 0 To AMessage.WebPush.Extra.Count - 1 Do + If AMessage.WebPush.Extra.Names[I] <> '' Then + AddString( + LNotification, + LNotificationFirst, + AMessage.WebPush.Extra.Names[I], + AMessage.WebPush.Extra.ValueFromIndex[I] + ); + + LNotification := LNotification + '}'; + + If Not LNotificationFirst Then + Begin + AddComma( + Result, + LFirst + ); + + Result := + Result + + '"notification":' + + LNotification; + End; + + LOptions := '{'; + LOptionsFirst := True; + + AddString( + LOptions, + LOptionsFirst, + 'link', + AMessage.WebPush.Link + ); + + AddString( + LOptions, + LOptionsFirst, + 'analytics_label', + AMessage.WebPush.AnalyticsLabel + ); + + LOptions := LOptions + '}'; + + If Not LOptionsFirst Then + Begin + AddComma( + Result, + LFirst + ); + + Result := + Result + + '"fcm_options":' + + LOptions; + End; + + Result := Result + '}'; + + If LFirst Then + Result := ''; +End; + +Function RESTDWFCMMessageToJSONTarget(Const ATargetName, + ATargetValue : String; + AMessage : TRESTDWFCMMessage; + AValidateOnly : Boolean) : String; +Var + LMessage, + LNotification, + LValue : String; + LFirst, + LNotificationFirst : Boolean; +Begin + LMessage := '{'; + LFirst := True; + + AddString( + LMessage, + LFirst, + ATargetName, + ATargetValue + ); + + If AMessage.Data.Count > 0 Then + Begin + AddComma( + LMessage, + LFirst + ); + + LMessage := + LMessage + + '"data":' + + StringListObject(AMessage.Data); + End; + + If (AMessage.Title <> '') Or + (AMessage.Body <> '') Or + (AMessage.ImageURL <> '') Then + Begin + LNotification := '{'; + LNotificationFirst := True; + + AddString( + LNotification, + LNotificationFirst, + 'title', + AMessage.Title + ); + + AddString( + LNotification, + LNotificationFirst, + 'body', + AMessage.Body + ); + + AddString( + LNotification, + LNotificationFirst, + 'image', + AMessage.ImageURL + ); + + LNotification := LNotification + '}'; + + AddComma( + LMessage, + LFirst + ); + + LMessage := + LMessage + + '"notification":' + + LNotification; + End; + + LValue := AndroidJSON(AMessage); + + If LValue <> '' Then + Begin + AddComma( + LMessage, + LFirst + ); + + LMessage := + LMessage + + '"android":' + + LValue; + End; + + LValue := APNSJSON(AMessage); + + If LValue <> '' Then + Begin + AddComma( + LMessage, + LFirst + ); + + LMessage := + LMessage + + '"apns":' + + LValue; + End; + + LValue := WebPushJSON(AMessage); + + If LValue <> '' Then + Begin + AddComma( + LMessage, + LFirst + ); + + LMessage := + LMessage + + '"webpush":' + + LValue; + End; + + If AMessage.AnalyticsLabel <> '' Then + Begin + AddComma( + LMessage, + LFirst + ); + + LMessage := + LMessage + + '"fcm_options":{"analytics_label":"' + + JSONEscape(AMessage.AnalyticsLabel) + + '"}'; + End; + + LMessage := LMessage + '}'; + + Result := + '{"message":' + + LMessage; + + If AValidateOnly Then + Result := + Result + + ',"validate_only":true'; + + Result := + Result + + '}'; +End; + +Function RESTDWFCMMessageToJSON(Const ADeviceToken : String; + AMessage : TRESTDWFCMMessage) : String; +Begin + Result := + RESTDWFCMMessageToJSONTarget( + 'token', + ADeviceToken, + AMessage, + False + ); +End; + +Procedure RESTDWFCMJSONToData(Const AJSON : String; + AData : TStrings); + + Procedure SkipSpaces(Var APos : Integer); + Begin + While (APos <= Length(AJSON)) And + (AJSON[APos] <= ' ') Do + Inc(APos); + End; + + Function ReadJSONString(Var APos : Integer) : String; + Var + LStart : Integer; + LEscaped : Boolean; + Begin + Result := ''; + + If (APos > Length(AJSON)) Or + (AJSON[APos] <> '"') Then + Exit; + + Inc(APos); + LStart := APos; + LEscaped := False; + + While APos <= Length(AJSON) Do + Begin + If AJSON[APos] = '\' Then + Begin + LEscaped := Not LEscaped; + Inc(APos); + Continue; + End; + + If (AJSON[APos] = '"') And + Not LEscaped Then + Break; + + LEscaped := False; + Inc(APos); + End; + + Result := + JSONUnescape( + Copy( + AJSON, + LStart, + APos - LStart + ) + ); + + If (APos <= Length(AJSON)) And + (AJSON[APos] = '"') Then + Inc(APos); + End; + + Function ReadJSONValue(Var APos : Integer) : String; + Var + LStart, + LObjectDepth, + LArrayDepth : Integer; + LInString, + LEscaped : Boolean; + Begin + Result := ''; + SkipSpaces(APos); + + If APos > Length(AJSON) Then + Exit; + + If AJSON[APos] = '"' Then + Begin + Result := ReadJSONString(APos); + Exit; + End; + + LStart := APos; + LObjectDepth := 0; + LArrayDepth := 0; + LInString := False; + LEscaped := False; + + While APos <= Length(AJSON) Do + Begin + If LInString Then + Begin + If AJSON[APos] = '\' Then + Begin + LEscaped := Not LEscaped; + Inc(APos); + Continue; + End; + + If (AJSON[APos] = '"') And + Not LEscaped Then + LInString := False; + + LEscaped := False; + Inc(APos); + Continue; + End; + + Case AJSON[APos] Of + '"': + LInString := True; + + '{': + Inc(LObjectDepth); + + '}': + Begin + If LObjectDepth = 0 Then + Break; + + Dec(LObjectDepth); + End; + + '[': + Inc(LArrayDepth); + + ']': + Begin + If LArrayDepth > 0 Then + Dec(LArrayDepth); + End; + + ',': + If (LObjectDepth = 0) And + (LArrayDepth = 0) Then + Break; + End; + + Inc(APos); + End; + + Result := + Trim( + Copy( + AJSON, + LStart, + APos - LStart + ) + ); + End; + +Var + I : Integer; + LName, + LValue : String; +Begin + If AData = Nil Then + Exit; + + I := 1; + SkipSpaces(I); + + If (I > Length(AJSON)) Or + (AJSON[I] <> '{') Then + Exit; + + Inc(I); + + While I <= Length(AJSON) Do + Begin + SkipSpaces(I); + + If (I > Length(AJSON)) Or + (AJSON[I] = '}') Then + Break; + + LName := ReadJSONString(I); + + If LName = '' Then + Break; + + SkipSpaces(I); + + If (I > Length(AJSON)) Or + (AJSON[I] <> ':') Then + Break; + + Inc(I); + LValue := ReadJSONValue(I); + + AData.Values[LName] := LValue; + + SkipSpaces(I); + + If (I <= Length(AJSON)) And + (AJSON[I] = ',') Then + Begin + Inc(I); + Continue; + End; + + Break; + End; +End; + +Procedure RESTDWFCMJSONToMessage(Const AJSON : String; + AMessage : TRESTDWFCMMessage); +Begin + AMessage.Raw := AJSON; + + AMessage.Title := + JSONUnescape( + RESTDWFCMJSONValue( + AJSON, + 'title' + ) + ); + + AMessage.Body := + JSONUnescape( + RESTDWFCMJSONValue( + AJSON, + 'body' + ) + ); + + AMessage.ImageURL := + JSONUnescape( + RESTDWFCMJSONValue( + AJSON, + 'image' + ) + ); +End; + +End. diff --git a/CORE/Source/Sockets/uRESTDWFCMMCS.pas b/CORE/Source/Sockets/uRESTDWFCMMCS.pas new file mode 100644 index 000000000..3d12d1a96 --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFCMMCS.pas @@ -0,0 +1,659 @@ +Unit uRESTDWFCMMCS; + +interface + +{$I uRESTDW.inc} + +uses + Classes, + uRESTDWFCMCompat, + uRESTDWFCMTransport, + SysUtils, + uRESTDWFCMTypes, + uRESTDWFCMProto, + uRESTDWFCMCrypto; + +type + TRESTDWMCSDataEvent = procedure(Sender: TObject; + const APersistentID, AMessageData, ARaw: string) of object; + + TRESTDWMCSClient = class + private + FTransport : TRESTDWFCMStreamTransport; + FCredentials: TRESTDWFCMCredentials; + FOnData: TRESTDWMCSDataEvent; + FStop: Boolean; + FStreamID: Integer; + FLastStreamIDReported: Integer; + + function BuildLogin: TRESTDWFCMBytes; + function BuildHeartbeatAck: TRESTDWFCMBytes; + Function BuildSelectiveAck(Const APersistentID : String) : TRESTDWFCMBytes; + function ReadVarIntIO: TRESTDWFCMUInt64; + + procedure SendFrame(ATag: Byte; + const AData: TRESTDWFCMBytes; + AIncludeVersion: Boolean = False); + + function ParseLoginResponseError(const AData: TRESTDWFCMBytes): string; + procedure ParseDataMessage(const AData: TRESTDWFCMBytes); + public + Constructor Create(Const ACredentials : TRESTDWFCMCredentials; + ATransport : TRESTDWFCMStreamTransport); + destructor Destroy; override; + + procedure Connect; + procedure Run; + Procedure Stop; + Procedure Ack(Const APersistentID : String); + + property OnData: TRESTDWMCSDataEvent read FOnData write FOnData; + end; + +implementation + +Constructor TRESTDWMCSClient.Create(Const ACredentials : TRESTDWFCMCredentials; + ATransport : TRESTDWFCMStreamTransport); +Begin + Inherited Create; + FCredentials := ACredentials; + FTransport := ATransport; + FStop := False; + FStreamID := 0; + FLastStreamIDReported := -1; +End; + +Destructor TRESTDWMCSClient.Destroy; +Begin + Stop; + Inherited Destroy; +End; + +function TRESTDWMCSClient.BuildLogin: TRESTDWFCMBytes; +var + LStream: TMemoryStream; + LSettingsStream: TMemoryStream; + LBytes: TRESTDWFCMBytes; + LDeviceID: string; + LHexID: string; +begin + LDeviceID := RESTDWFCMUIntToStr(FCredentials.DeviceID); + LHexID := LowerCase(IntToHex(Int64(FCredentials.DeviceID), 1)); + + LStream := TMemoryStream.Create; + LSettingsStream := TMemoryStream.Create; + try + TRESTDWProto.FieldString( + LStream, + 1, + 'chrome-63.0.3234.0' + ); + + TRESTDWProto.FieldString( + LStream, + 2, + 'mcs.android.com' + ); + + TRESTDWProto.FieldString( + LStream, + 3, + LDeviceID + ); + + TRESTDWProto.FieldString( + LStream, + 4, + LDeviceID + ); + + TRESTDWProto.FieldString( + LStream, + 5, + RESTDWFCMUIntToStr(FCredentials.SecurityToken) + ); + + TRESTDWProto.FieldString( + LStream, + 6, + 'android-' + LHexID + ); + + TRESTDWProto.FieldString( + LSettingsStream, + 1, + 'new_vc' + ); + + TRESTDWProto.FieldString( + LSettingsStream, + 2, + '1' + ); + + SetLength(LBytes, LSettingsStream.Size); + LSettingsStream.Position := 0; + + if LSettingsStream.Size > 0 then + LSettingsStream.ReadBuffer( + LBytes[0], + LSettingsStream.Size + ); + + TRESTDWProto.FieldBytes(LStream, 8, LBytes); + + { LoginRequest exatamente conforme BuildLoginRequest do Chromium. + Nao enviar last_rmq_id/account_id em uma sessao nova. } + + { adaptive_heartbeat = false - field 12 } + TRESTDWProto.FieldBool(LStream, 12, False); + + { use_rmq2 = true - field 14 } + TRESTDWProto.FieldBool(LStream, 14, True); + + { auth_service = ANDROID_ID = 2 - field 16 } + TRESTDWProto.FieldVarInt(LStream, 16, 2); + + { network_type = WIFI = 1 - field 17 } + TRESTDWProto.FieldVarInt(LStream, 17, 1); + + SetLength(Result, LStream.Size); + LStream.Position := 0; + + if LStream.Size > 0 then + LStream.ReadBuffer(Result[0], LStream.Size); + finally + LSettingsStream.Free; + LStream.Free; + end; +end; + +function TRESTDWMCSClient.BuildHeartbeatAck: TRESTDWFCMBytes; +var + LStream: TMemoryStream; +begin + LStream := TMemoryStream.Create; + try + if FStreamID > FLastStreamIDReported then + begin + TRESTDWProto.FieldVarInt( + LStream, + 2, + TRESTDWFCMUInt64(FStreamID) + ); + + FLastStreamIDReported := FStreamID; + end; + + SetLength(Result, LStream.Size); + LStream.Position := 0; + + if LStream.Size > 0 then + LStream.ReadBuffer( + Result[0], + LStream.Size + ); + finally + LStream.Free; + end; +end; + +Function TRESTDWMCSClient.BuildSelectiveAck(Const APersistentID : String) : TRESTDWFCMBytes; +Var + LIQStream : TMemoryStream; + LExtensionStream : TMemoryStream; + LAckStream : TMemoryStream; + LAckData : TRESTDWFCMBytes; + LExtensionData : TRESTDWFCMBytes; +Begin + LIQStream := TMemoryStream.Create; + LExtensionStream := TMemoryStream.Create; + LAckStream := TMemoryStream.Create; + Try + TRESTDWProto.FieldString(LAckStream, + 1, + APersistentID); + + SetLength(LAckData, LAckStream.Size); + LAckStream.Position := 0; + If LAckStream.Size > 0 Then + LAckStream.ReadBuffer(LAckData[0], + LAckStream.Size); + + TRESTDWProto.FieldVarInt(LExtensionStream, + 1, + 12); + TRESTDWProto.FieldBytes(LExtensionStream, + 2, + LAckData); + + SetLength(LExtensionData, LExtensionStream.Size); + LExtensionStream.Position := 0; + If LExtensionStream.Size > 0 Then + LExtensionStream.ReadBuffer(LExtensionData[0], + LExtensionStream.Size); + + TRESTDWProto.FieldVarInt(LIQStream, + 2, + 1); + TRESTDWProto.FieldString(LIQStream, + 3, + ''); + TRESTDWProto.FieldBytes(LIQStream, + 7, + LExtensionData); + + SetLength(Result, LIQStream.Size); + LIQStream.Position := 0; + If LIQStream.Size > 0 Then + LIQStream.ReadBuffer(Result[0], + LIQStream.Size); + Finally + LAckStream.Free; + LExtensionStream.Free; + LIQStream.Free; + End; +End; + + +procedure TRESTDWMCSClient.SendFrame( + ATag: Byte; + const AData: TRESTDWFCMBytes; + AIncludeVersion: Boolean); +var + LStream: TMemoryStream; + LVersion: Byte; +begin + LStream := TMemoryStream.Create; + try + if AIncludeVersion then + begin + LVersion := 41; + LStream.WriteBuffer(LVersion, 1); + end; + + LStream.WriteBuffer(ATag, 1); + TRESTDWProto.WriteVarInt( + LStream, + Length(AData) + ); + + if Length(AData) > 0 then + LStream.WriteBuffer( + AData[0], + Length(AData) + ); + + LStream.Position := 0; + If LStream.Size > 0 Then + FTransport.WriteBuffer(LStream.Memory^, LStream.Size); + finally + LStream.Free; + end; +end; + +function TRESTDWMCSClient.ReadVarIntIO: TRESTDWFCMUInt64; +var + LByte: Byte; + LShift: Integer; +begin + Result := 0; + LShift := 0; + + repeat + LByte := FTransport.ReadByte; + + If (LShift = 63) And + ((LByte And $FE) <> 0) Then + Raise Exception.Create( + 'MCS varint excede UInt64' + ); + + Result := + Result Or + (TRESTDWFCMUInt64(LByte And $7F) Shl LShift); + + If (LByte And $80) = 0 Then + Break; + + Inc(LShift, 7); + + If LShift > 63 Then + Raise Exception.Create( + 'MCS varint invalido' + ); + until False; +end; + +procedure TRESTDWMCSClient.Connect; +var + LLogin: TRESTDWFCMBytes; +begin + FStop := False; + FStreamID := 0; + FLastStreamIDReported := -1; + + FTransport.Connect('mtalk.google.com', 5228); + + LLogin := BuildLogin; + SendFrame( + 2, + LLogin, + True + ); +end; + +function TRESTDWMCSClient.ParseLoginResponseError(const AData: TRESTDWFCMBytes): string; +var + S, E: TRESTDWFCMBytesStream; + K, F, W, EK, EF, EW, Code: TRESTDWFCMUInt64; + B: TRESTDWFCMBytes; + Msg, Typ: string; +begin + Result := ''; + S := TRESTDWFCMBytesStream.Create(AData); + try + while S.Position < S.Size do + begin + K := TRESTDWProto.ReadVarInt(S); + F := K shr 3; + W := K and 7; + if W = 2 then + begin + B := TRESTDWProto.ReadLengthDelimited(S); + if F = 3 then + begin + Code := 0; Msg := ''; Typ := ''; + E := TRESTDWFCMBytesStream.Create(B); + try + while E.Position < E.Size do + begin + EK := TRESTDWProto.ReadVarInt(E); + EF := EK shr 3; + EW := EK and 7; + if EW = 0 then + begin + if EF = 1 then Code := TRESTDWProto.ReadVarInt(E) + else TRESTDWProto.ReadVarInt(E); + end + else if EW = 2 then + begin + B := TRESTDWProto.ReadLengthDelimited(E); + if EF = 2 then Msg := RESTDWFCMBytesToString(B) + else if EF = 3 then Typ := RESTDWFCMBytesToString(B); + end + else if EW = 1 then + begin + If (E.Size - E.Position) < 8 Then + Raise Exception.Create('MCS login fixed64 truncado'); + E.Seek(8, soCurrent); + end + else if EW = 5 then + begin + If (E.Size - E.Position) < 4 Then + Raise Exception.Create('MCS login fixed32 truncado'); + E.Seek(4, soCurrent); + end + else Break; + end; + finally + E.Free; + end; + Result := Format('MCS login recusado code=%d type=%s message=%s', + [Code, Typ, Msg]); + Exit; + end; + end + else if W = 0 then TRESTDWProto.ReadVarInt(S) + else if W = 1 then + begin + If (S.Size - S.Position) < 8 Then + Raise Exception.Create('MCS login fixed64 truncado'); + S.Seek(8, soCurrent); + end + else if W = 5 then + begin + If (S.Size - S.Position) < 4 Then + Raise Exception.Create('MCS login fixed32 truncado'); + S.Seek(4, soCurrent); + end + else Break; + end; + finally + S.Free; + end; +end; + +procedure TRESTDWMCSClient.ParseDataMessage( + const AData: TRESTDWFCMBytes); +var + LStream: TRESTDWFCMBytesStream; + LSubStream: TRESTDWFCMBytesStream; + LKey, LField, LWireType: TRESTDWFCMUInt64; + LSubKey, LSubField, LSubWireType: TRESTDWFCMUInt64; + LBytes, LRawData, LDecrypted: TRESTDWFCMBytes; + LKeyName, LValue: string; + LPersistentID, LMessageData, LRaw: string; + LCryptoKey, LEncryption, LDecryptedText, LTrimmedText: string; +begin + LPersistentID := ''; + LMessageData := ''; + LRaw := ''; + LCryptoKey := ''; + LEncryption := ''; + SetLength(LRawData, 0); + + LStream := TRESTDWFCMBytesStream.Create(AData); + try + while LStream.Position < LStream.Size do + begin + LKey := TRESTDWProto.ReadVarInt(LStream); + LField := LKey shr 3; + LWireType := LKey and 7; + case LWireType of + 0: TRESTDWProto.ReadVarInt(LStream); + 1: + Begin + If (LStream.Size - LStream.Position) < 8 Then + Raise Exception.Create('MCS data fixed64 truncado'); + LStream.Seek(8, soCurrent); + End; + 2: + begin + LBytes := TRESTDWProto.ReadLengthDelimited(LStream); + if LField = 7 then + begin + LSubStream := TRESTDWFCMBytesStream.Create(LBytes); + try + LKeyName := ''; + LValue := ''; + while LSubStream.Position < LSubStream.Size do + begin + LSubKey := TRESTDWProto.ReadVarInt(LSubStream); + LSubField := LSubKey shr 3; + LSubWireType := LSubKey and 7; + if LSubWireType = 2 then + begin + LBytes := TRESTDWProto.ReadLengthDelimited(LSubStream); + if LSubField = 1 then LKeyName := RESTDWFCMBytesToString(LBytes) + else if LSubField = 2 then LValue := RESTDWFCMBytesToString(LBytes); + end + else if LSubWireType = 0 then TRESTDWProto.ReadVarInt(LSubStream) + else if LSubWireType = 1 then + begin + If (LSubStream.Size - LSubStream.Position) < 8 Then + Raise Exception.Create('MCS app_data fixed64 truncado'); + LSubStream.Seek(8, soCurrent); + end + else if LSubWireType = 5 then + begin + If (LSubStream.Size - LSubStream.Position) < 4 Then + Raise Exception.Create('MCS app_data fixed32 truncado'); + LSubStream.Seek(4, soCurrent); + end + else Break; + end; + + if SameText(LKeyName, 'messagedata') then LMessageData := LValue; + if SameText(LKeyName, 'crypto-key') then LCryptoKey := LValue; + if SameText(LKeyName, 'encryption') then LEncryption := LValue; + + if LRaw <> '' then LRaw := LRaw + ','; + LRaw := LRaw + '"' + StringReplace(LKeyName, '"', '\"', [rfReplaceAll]) + + '":"' + StringReplace(LValue, '"', '\"', [rfReplaceAll]) + '"'; + finally + LSubStream.Free; + end; + end + else if LField = 9 then + LPersistentID := RESTDWFCMBytesToString(LBytes) + else if LField = 21 then + LRawData := Copy(LBytes, 0, Length(LBytes)); + end; + 5: + Begin + If (LStream.Size - LStream.Position) < 4 Then + Raise Exception.Create('MCS data fixed32 truncado'); + LStream.Seek(4, soCurrent); + End; + else + raise Exception.Create('MCS wire type inesperado'); + end; + end; + finally + LStream.Free; + end; + + LRaw := '{' + LRaw + '}'; + + { Tokens obtidos pela API fcmregistrations sao WebPush. Nesse fluxo o + DataMessageStanza traz crypto-key/encryption em app_data e o payload real + criptografado em raw_data (protobuf field 21). } + if (LMessageData = '') and (Length(LRawData) > 0) and + (LCryptoKey <> '') and (LEncryption <> '') then + begin + LDecrypted := TRESTDWWebPushCrypto.DecryptAESGCM( + FCredentials.PushPrivateKey, + FCredentials.PushPublicKey, + FCredentials.PushAuth, + LCryptoKey, + LEncryption, + LRawData + ); + LDecryptedText := RESTDWFCMBytesToString(LDecrypted); + LRaw := LDecryptedText; + LMessageData := RESTDWFCMJSONValue(LDecryptedText, 'messagedata'); + + { Mantem compatibilidade caso algum emissor mande apenas texto no payload. } + LTrimmedText := Trim(LDecryptedText); + If (LMessageData = '') And + (LTrimmedText <> '') And + (LTrimmedText[1] <> '{') Then + LMessageData := LDecryptedText; + end; + + If Assigned(FOnData) Then + FOnData(Self, + LPersistentID, + LMessageData, + LRaw); +end; + +Procedure TRESTDWMCSClient.Ack(Const APersistentID : String); +Var + LSelectiveAck : TRESTDWFCMBytes; +Begin + If APersistentID = '' Then + Exit; + LSelectiveAck := BuildSelectiveAck(APersistentID); + SendFrame(7, LSelectiveAck, False); +End; + +procedure TRESTDWMCSClient.Run; +var + LVersion: Byte; + LTag: Byte; + LLength: TRESTDWFCMUInt64; + LData: TRESTDWFCMBytes; + LFirstFrame: Boolean; + LAck: TRESTDWFCMBytes; + LRaw: string; +begin + LFirstFrame := True; + + While (Not FStop) And FTransport.Connected Do + begin + if LFirstFrame then + begin + LVersion := FTransport.ReadByte; + + if LVersion <> 41 then + raise Exception.CreateFmt( + 'MCS versao %d inesperada', + [LVersion] + ); + + LFirstFrame := False; + end; + + LTag := FTransport.ReadByte; + LLength := ReadVarIntIO; + + { Protege contra frame corrompido/malicioso e contra overflow + na conversao UInt64 -> Integer em compiladores antigos. } + If LLength > 16 * 1024 * 1024 Then + Raise Exception.Create( + 'MCS frame acima do limite de 16 MB' + ); + + SetLength(LData, Integer(LLength)); + + if LLength > 0 then + begin + FTransport.ReadBuffer(LData[0], Integer(LLength)); + end; + + Inc(FStreamID); + + case LTag of + 0: + begin + LAck := BuildHeartbeatAck; + SendFrame( + 1, + LAck, + False + ); + end; + + 1: + ; + + 3: + begin + LRaw := ParseLoginResponseError(LData); + if LRaw <> '' then + raise Exception.Create(LRaw); + end; + + 4: + FStop := True; + + 7: + ; + + 8: + ParseDataMessage(LData); + end; + end; +end; + +procedure TRESTDWMCSClient.Stop; +begin + FStop := True; + + If FTransport.Connected Then + FTransport.Disconnect; +end; + +end. diff --git a/CORE/Source/Sockets/uRESTDWFCMMessage.pas b/CORE/Source/Sockets/uRESTDWFCMMessage.pas new file mode 100644 index 000000000..729be9ea7 --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFCMMessage.pas @@ -0,0 +1,583 @@ +Unit uRESTDWFCMMessage; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + uRESTDWFCMValue; + +Type + TRESTDWFCMAndroid = Class(TPersistent) + Private + FCollapseKey : String; + FPriority : String; + FTTL : String; + FRestrictedPackageName : String; + FDirectBootOK : Boolean; + FBandwidthConstrainedOK : Boolean; + FRestrictedSatelliteOK : Boolean; + FTitle : String; + FBody : String; + FIcon : String; + FColor : String; + FSound : String; + FTag : String; + FClickAction : String; + FBodyLocKey : String; + FBodyLocArgs : TStringList; + FTitleLocKey : String; + FTitleLocArgs : TStringList; + FChannelID : String; + FImageURL : String; + FProxy : String; + FTicker : String; + FSticky : Boolean; + FEventTime : String; + FLocalOnly : Boolean; + FNotificationPriority : String; + FVibrateTimings : TStringList; + FDefaultVibrateTimings : Boolean; + FDefaultSound : Boolean; + FLightColor : String; + FLightOnDuration : String; + FLightOffDuration : String; + FDefaultLightSettings : Boolean; + FVisibility : String; + FNotificationCount : Integer; + FAnalyticsLabel : String; + FData : TStringList; + FExtra : TStringList; + Public + Constructor Create; + Destructor Destroy; Override; + Procedure Assign(Source : TPersistent); Override; + + Property BodyLocArgs : TStringList Read FBodyLocArgs; + Property TitleLocArgs : TStringList Read FTitleLocArgs; + Property VibrateTimings : TStringList Read FVibrateTimings; + Property Data : TStringList Read FData; + Property Extra : TStringList Read FExtra; + Published + Property CollapseKey : String Read FCollapseKey Write FCollapseKey; + Property Priority : String Read FPriority Write FPriority; + Property TTL : String Read FTTL Write FTTL; + Property RestrictedPackageName : String Read FRestrictedPackageName Write FRestrictedPackageName; + Property DirectBootOK : Boolean Read FDirectBootOK Write FDirectBootOK; + Property BandwidthConstrainedOK: Boolean Read FBandwidthConstrainedOK Write FBandwidthConstrainedOK; + Property RestrictedSatelliteOK : Boolean Read FRestrictedSatelliteOK Write FRestrictedSatelliteOK; + + Property Title : String Read FTitle Write FTitle; + Property Body : String Read FBody Write FBody; + Property Icon : String Read FIcon Write FIcon; + Property Color : String Read FColor Write FColor; + Property Sound : String Read FSound Write FSound; + Property Tag : String Read FTag Write FTag; + Property ClickAction : String Read FClickAction Write FClickAction; + Property BodyLocKey : String Read FBodyLocKey Write FBodyLocKey; + Property TitleLocKey : String Read FTitleLocKey Write FTitleLocKey; + Property ChannelID : String Read FChannelID Write FChannelID; + Property ImageURL : String Read FImageURL Write FImageURL; + Property Proxy : String Read FProxy Write FProxy; + Property Ticker : String Read FTicker Write FTicker; + Property Sticky : Boolean Read FSticky Write FSticky; + Property EventTime : String Read FEventTime Write FEventTime; + Property LocalOnly : Boolean Read FLocalOnly Write FLocalOnly; + + Property NotificationPriority : String Read FNotificationPriority Write FNotificationPriority; + Property DefaultVibrateTimings : Boolean Read FDefaultVibrateTimings Write FDefaultVibrateTimings; + Property DefaultSound : Boolean Read FDefaultSound Write FDefaultSound; + Property LightColor : String Read FLightColor Write FLightColor; + Property LightOnDuration : String Read FLightOnDuration Write FLightOnDuration; + Property LightOffDuration : String Read FLightOffDuration Write FLightOffDuration; + Property DefaultLightSettings : Boolean Read FDefaultLightSettings Write FDefaultLightSettings; + Property Visibility : String Read FVisibility Write FVisibility; + Property NotificationCount : Integer Read FNotificationCount Write FNotificationCount; + Property AnalyticsLabel : String Read FAnalyticsLabel Write FAnalyticsLabel; + End; + + TRESTDWFCMAPNS = Class(TPersistent) + Private + FHeaders : TStringList; + FCustomData : TStringList; + FAPSExtra : TRESTDWFCMValue; + FPayloadExtra : TRESTDWFCMValue; + FTitle : String; + FSubtitle : String; + FBody : String; + FTitleLocKey : String; + FTitleLocArgs : TStringList; + FSubtitleLocKey : String; + FSubtitleLocArgs : TStringList; + FBodyLocKey : String; + FBodyLocArgs : TStringList; + FLaunchImage : String; + FSound : String; + FBadge : Integer; + FCategory : String; + FThreadID : String; + FContentAvailable : Boolean; + FMutableContent : Boolean; + FTargetContentID : String; + FInterruptionLevel: String; + FRelevanceScore : String; + FFilterCriteria : String; + FStaleDate : String; + FContentState : TRESTDWFCMValue; + FAttributes : TRESTDWFCMValue; + FLiveActivityTimestamp : String; + FLiveActivityEvent : String; + FLiveActivityDismissalDate : String; + FLiveActivityAttributesType : String; + FImageURL : String; + FAnalyticsLabel : String; + FLiveActivityToken : String; + Public + Constructor Create; + Destructor Destroy; Override; + Procedure Assign(Source : TPersistent); Override; + + Property Headers : TStringList Read FHeaders; + Property CustomData : TStringList Read FCustomData; + Property APSExtra : TRESTDWFCMValue Read FAPSExtra; + Property PayloadExtra : TRESTDWFCMValue Read FPayloadExtra; + Property TitleLocArgs : TStringList Read FTitleLocArgs; + Property SubtitleLocArgs : TStringList Read FSubtitleLocArgs; + Property BodyLocArgs : TStringList Read FBodyLocArgs; + Property ContentState : TRESTDWFCMValue Read FContentState; + Property Attributes : TRESTDWFCMValue Read FAttributes; + Published + Property Title : String Read FTitle Write FTitle; + Property Subtitle : String Read FSubtitle Write FSubtitle; + Property Body : String Read FBody Write FBody; + Property TitleLocKey : String Read FTitleLocKey Write FTitleLocKey; + Property SubtitleLocKey : String Read FSubtitleLocKey Write FSubtitleLocKey; + Property BodyLocKey : String Read FBodyLocKey Write FBodyLocKey; + Property LaunchImage : String Read FLaunchImage Write FLaunchImage; + Property Sound : String Read FSound Write FSound; + Property Badge : Integer Read FBadge Write FBadge; + Property Category : String Read FCategory Write FCategory; + Property ThreadID : String Read FThreadID Write FThreadID; + Property ContentAvailable : Boolean Read FContentAvailable Write FContentAvailable; + Property MutableContent : Boolean Read FMutableContent Write FMutableContent; + Property TargetContentID : String Read FTargetContentID Write FTargetContentID; + Property InterruptionLevel : String Read FInterruptionLevel Write FInterruptionLevel; + Property RelevanceScore : String Read FRelevanceScore Write FRelevanceScore; + Property FilterCriteria : String Read FFilterCriteria Write FFilterCriteria; + Property StaleDate : String Read FStaleDate Write FStaleDate; + Property LiveActivityTimestamp : String Read FLiveActivityTimestamp Write FLiveActivityTimestamp; + Property LiveActivityEvent : String Read FLiveActivityEvent Write FLiveActivityEvent; + Property LiveActivityDismissalDate : String Read FLiveActivityDismissalDate Write FLiveActivityDismissalDate; + Property LiveActivityAttributesType : String Read FLiveActivityAttributesType Write FLiveActivityAttributesType; + Property ImageURL : String Read FImageURL Write FImageURL; + Property AnalyticsLabel : String Read FAnalyticsLabel Write FAnalyticsLabel; + Property LiveActivityToken : String Read FLiveActivityToken Write FLiveActivityToken; + End; + + TRESTDWFCMWebPushAction = Class(TCollectionItem) + Private + FAction : String; + FTitle : String; + FIcon : String; + Published + Property Action : String Read FAction Write FAction; + Property Title : String Read FTitle Write FTitle; + Property Icon : String Read FIcon Write FIcon; + End; + + TRESTDWFCMWebPushActions = Class(TCollection) + Public + Constructor Create; + Function Add : TRESTDWFCMWebPushAction; + Function GetItem(AIndex : Integer) : TRESTDWFCMWebPushAction; + Property Items[AIndex : Integer] : TRESTDWFCMWebPushAction Read GetItem; Default; + End; + + TRESTDWFCMWebPush = Class(TPersistent) + Private + FHeaders : TStringList; + FData : TStringList; + FActions : TRESTDWFCMWebPushActions; + FExtra : TStringList; + FNotificationExtra : TRESTDWFCMValue; + FTitle : String; + FBody : String; + FIcon : String; + FImageURL : String; + FBadge : String; + FTag : String; + FLanguage : String; + FDirection : String; + FRenotify : Boolean; + FRequireInteraction : Boolean; + FSilent : Boolean; + FTimestamp : String; + FVibrate : TStringList; + FLink : String; + FAnalyticsLabel : String; + Public + Constructor Create; + Destructor Destroy; Override; + Procedure Assign(Source : TPersistent); Override; + + Property Headers : TStringList Read FHeaders; + Property Data : TStringList Read FData; + Property Actions : TRESTDWFCMWebPushActions Read FActions; + Property Extra : TStringList Read FExtra; + Property NotificationExtra : TRESTDWFCMValue Read FNotificationExtra; + Property Vibrate : TStringList Read FVibrate; + Published + Property Title : String Read FTitle Write FTitle; + Property Body : String Read FBody Write FBody; + Property Icon : String Read FIcon Write FIcon; + Property ImageURL : String Read FImageURL Write FImageURL; + Property Badge : String Read FBadge Write FBadge; + Property Tag : String Read FTag Write FTag; + Property Language : String Read FLanguage Write FLanguage; + Property Direction : String Read FDirection Write FDirection; + Property Renotify : Boolean Read FRenotify Write FRenotify; + Property RequireInteraction : Boolean Read FRequireInteraction Write FRequireInteraction; + Property Silent : Boolean Read FSilent Write FSilent; + Property Timestamp : String Read FTimestamp Write FTimestamp; + Property Link : String Read FLink Write FLink; + Property AnalyticsLabel : String Read FAnalyticsLabel Write FAnalyticsLabel; + End; + + TRESTDWFCMMessage = Class(TPersistent) + Private + FTitle : String; + FBody : String; + FImageURL : String; + FAnalyticsLabel : String; + FData : TStringList; + FAndroid : TRESTDWFCMAndroid; + FAPNS : TRESTDWFCMAPNS; + FWebPush : TRESTDWFCMWebPush; + FRaw : String; + Public + Constructor Create; + Destructor Destroy; Override; + Procedure Assign(Source : TPersistent); Override; + Function Clone : TRESTDWFCMMessage; + Procedure Clear; + + Property Data : TStringList Read FData; + Property Android : TRESTDWFCMAndroid Read FAndroid; + Property APNS : TRESTDWFCMAPNS Read FAPNS; + Property WebPush : TRESTDWFCMWebPush Read FWebPush; + Property Raw : String Read FRaw Write FRaw; + Published + Property Title : String Read FTitle Write FTitle; + Property Body : String Read FBody Write FBody; + Property ImageURL : String Read FImageURL Write FImageURL; + Property AnalyticsLabel : String Read FAnalyticsLabel Write FAnalyticsLabel; + End; + +Implementation + +Constructor TRESTDWFCMAndroid.Create; +Begin + Inherited Create; + FNotificationCount := -1; + FBodyLocArgs := TStringList.Create; + FTitleLocArgs := TStringList.Create; + FVibrateTimings := TStringList.Create; + FData := TStringList.Create; + FExtra := TStringList.Create; +End; + +Destructor TRESTDWFCMAndroid.Destroy; +Begin + FExtra.Free; + FData.Free; + FVibrateTimings.Free; + FTitleLocArgs.Free; + FBodyLocArgs.Free; + Inherited Destroy; +End; + +Procedure TRESTDWFCMAndroid.Assign(Source : TPersistent); +Var + LSource : TRESTDWFCMAndroid; +Begin + If Source Is TRESTDWFCMAndroid Then + Begin + LSource := TRESTDWFCMAndroid(Source); + + FCollapseKey := LSource.CollapseKey; + FPriority := LSource.Priority; + FTTL := LSource.TTL; + FRestrictedPackageName := LSource.RestrictedPackageName; + FDirectBootOK := LSource.DirectBootOK; + FBandwidthConstrainedOK := LSource.BandwidthConstrainedOK; + FRestrictedSatelliteOK := LSource.RestrictedSatelliteOK; + + FTitle := LSource.Title; + FBody := LSource.Body; + FIcon := LSource.Icon; + FColor := LSource.Color; + FSound := LSource.Sound; + FTag := LSource.Tag; + FClickAction := LSource.ClickAction; + FBodyLocKey := LSource.BodyLocKey; + FTitleLocKey := LSource.TitleLocKey; + FChannelID := LSource.ChannelID; + FImageURL := LSource.ImageURL; + FProxy := LSource.Proxy; + FTicker := LSource.Ticker; + FSticky := LSource.Sticky; + FEventTime := LSource.EventTime; + FLocalOnly := LSource.LocalOnly; + FNotificationPriority := LSource.NotificationPriority; + FDefaultVibrateTimings := LSource.DefaultVibrateTimings; + FDefaultSound := LSource.DefaultSound; + FLightColor := LSource.LightColor; + FLightOnDuration := LSource.LightOnDuration; + FLightOffDuration := LSource.LightOffDuration; + FDefaultLightSettings := LSource.DefaultLightSettings; + FVisibility := LSource.Visibility; + FNotificationCount := LSource.NotificationCount; + FAnalyticsLabel := LSource.AnalyticsLabel; + + FBodyLocArgs.Assign(LSource.BodyLocArgs); + FTitleLocArgs.Assign(LSource.TitleLocArgs); + FVibrateTimings.Assign(LSource.VibrateTimings); + FData.Assign(LSource.Data); + FExtra.Assign(LSource.Extra); + End + Else + Inherited Assign(Source); +End; + +Constructor TRESTDWFCMAPNS.Create; +Begin + Inherited Create; + + FBadge := -1; + + FHeaders := TStringList.Create; + FCustomData := TStringList.Create; + FAPSExtra := TRESTDWFCMValue.Create; + FPayloadExtra := TRESTDWFCMValue.Create; + FContentState := TRESTDWFCMValue.Create; + FAttributes := TRESTDWFCMValue.Create; + FTitleLocArgs := TStringList.Create; + FSubtitleLocArgs := TStringList.Create; + FBodyLocArgs := TStringList.Create; +End; + +Destructor TRESTDWFCMAPNS.Destroy; +Begin + FBodyLocArgs.Free; + FSubtitleLocArgs.Free; + FTitleLocArgs.Free; + FAttributes.Free; + FContentState.Free; + FPayloadExtra.Free; + FAPSExtra.Free; + FCustomData.Free; + FHeaders.Free; + + Inherited Destroy; +End; + +Procedure TRESTDWFCMAPNS.Assign(Source : TPersistent); +Var + LSource : TRESTDWFCMAPNS; +Begin + If Source Is TRESTDWFCMAPNS Then + Begin + LSource := TRESTDWFCMAPNS(Source); + + FHeaders.Assign(LSource.Headers); + FCustomData.Assign(LSource.CustomData); + FAPSExtra.Assign(LSource.APSExtra); + FPayloadExtra.Assign(LSource.PayloadExtra); + FContentState.Assign(LSource.ContentState); + FAttributes.Assign(LSource.Attributes); + FTitleLocArgs.Assign(LSource.TitleLocArgs); + FSubtitleLocArgs.Assign(LSource.SubtitleLocArgs); + FBodyLocArgs.Assign(LSource.BodyLocArgs); + + FTitle := LSource.Title; + FSubtitle := LSource.Subtitle; + FBody := LSource.Body; + FTitleLocKey := LSource.TitleLocKey; + FSubtitleLocKey := LSource.SubtitleLocKey; + FBodyLocKey := LSource.BodyLocKey; + FLaunchImage := LSource.LaunchImage; + FSound := LSource.Sound; + FBadge := LSource.Badge; + FCategory := LSource.Category; + FThreadID := LSource.ThreadID; + FContentAvailable := LSource.ContentAvailable; + FMutableContent := LSource.MutableContent; + FTargetContentID := LSource.TargetContentID; + FInterruptionLevel := LSource.InterruptionLevel; + FRelevanceScore := LSource.RelevanceScore; + FFilterCriteria := LSource.FilterCriteria; + FStaleDate := LSource.StaleDate; + FLiveActivityTimestamp := LSource.LiveActivityTimestamp; + FLiveActivityEvent := LSource.LiveActivityEvent; + FLiveActivityDismissalDate := LSource.LiveActivityDismissalDate; + FLiveActivityAttributesType := LSource.LiveActivityAttributesType; + FImageURL := LSource.ImageURL; + FAnalyticsLabel := LSource.AnalyticsLabel; + FLiveActivityToken := LSource.LiveActivityToken; + End + Else + Inherited Assign(Source); +End; + +Constructor TRESTDWFCMWebPushActions.Create; +Begin + Inherited Create(TRESTDWFCMWebPushAction); +End; + +Function TRESTDWFCMWebPushActions.Add : TRESTDWFCMWebPushAction; +Begin + Result := TRESTDWFCMWebPushAction(Inherited Add); +End; + +Function TRESTDWFCMWebPushActions.GetItem(AIndex : Integer) : TRESTDWFCMWebPushAction; +Begin + Result := TRESTDWFCMWebPushAction(Inherited Items[AIndex]); +End; + +Constructor TRESTDWFCMWebPush.Create; +Begin + Inherited Create; + + FHeaders := TStringList.Create; + FData := TStringList.Create; + FActions := TRESTDWFCMWebPushActions.Create; + FExtra := TStringList.Create; + FNotificationExtra := TRESTDWFCMValue.Create; + FVibrate := TStringList.Create; +End; + +Destructor TRESTDWFCMWebPush.Destroy; +Begin + FVibrate.Free; + FNotificationExtra.Free; + FExtra.Free; + FActions.Free; + FData.Free; + FHeaders.Free; + + Inherited Destroy; +End; + +Procedure TRESTDWFCMWebPush.Assign(Source : TPersistent); +Var + LSource : TRESTDWFCMWebPush; +Begin + If Source Is TRESTDWFCMWebPush Then + Begin + LSource := TRESTDWFCMWebPush(Source); + + FHeaders.Assign(LSource.Headers); + FData.Assign(LSource.Data); + FActions.Assign(LSource.Actions); + FExtra.Assign(LSource.Extra); + FNotificationExtra.Assign(LSource.NotificationExtra); + FVibrate.Assign(LSource.Vibrate); + + FTitle := LSource.Title; + FBody := LSource.Body; + FIcon := LSource.Icon; + FImageURL := LSource.ImageURL; + FBadge := LSource.Badge; + FTag := LSource.Tag; + FLanguage := LSource.Language; + FDirection := LSource.Direction; + FRenotify := LSource.Renotify; + FRequireInteraction := LSource.RequireInteraction; + FSilent := LSource.Silent; + FTimestamp := LSource.Timestamp; + FLink := LSource.Link; + FAnalyticsLabel := LSource.AnalyticsLabel; + End + Else + Inherited Assign(Source); +End; + +Constructor TRESTDWFCMMessage.Create; +Begin + Inherited Create; + + FData := TStringList.Create; + FAndroid := TRESTDWFCMAndroid.Create; + FAPNS := TRESTDWFCMAPNS.Create; + FWebPush := TRESTDWFCMWebPush.Create; +End; + +Destructor TRESTDWFCMMessage.Destroy; +Begin + FWebPush.Free; + FAPNS.Free; + FAndroid.Free; + FData.Free; + + Inherited Destroy; +End; + +Procedure TRESTDWFCMMessage.Assign(Source : TPersistent); +Var + LSource : TRESTDWFCMMessage; +Begin + If Source Is TRESTDWFCMMessage Then + Begin + LSource := TRESTDWFCMMessage(Source); + + FTitle := LSource.Title; + FBody := LSource.Body; + FImageURL := LSource.ImageURL; + FAnalyticsLabel := LSource.AnalyticsLabel; + FRaw := LSource.Raw; + + FData.Assign(LSource.Data); + FAndroid.Assign(LSource.Android); + FAPNS.Assign(LSource.APNS); + FWebPush.Assign(LSource.WebPush); + End + Else + Inherited Assign(Source); +End; + +Function TRESTDWFCMMessage.Clone : TRESTDWFCMMessage; +Begin + Result := TRESTDWFCMMessage.Create; + Result.Assign(Self); +End; + +Procedure TRESTDWFCMMessage.Clear; +Var + LEmptyAndroid : TRESTDWFCMAndroid; + LEmptyAPNS : TRESTDWFCMAPNS; + LEmptyWebPush : TRESTDWFCMWebPush; +Begin + FTitle := ''; + FBody := ''; + FImageURL := ''; + FAnalyticsLabel := ''; + FRaw := ''; + FData.Clear; + + LEmptyAndroid := TRESTDWFCMAndroid.Create; + LEmptyAPNS := TRESTDWFCMAPNS.Create; + LEmptyWebPush := TRESTDWFCMWebPush.Create; + Try + FAndroid.Assign(LEmptyAndroid); + FAPNS.Assign(LEmptyAPNS); + FWebPush.Assign(LEmptyWebPush); + Finally + LEmptyWebPush.Free; + LEmptyAPNS.Free; + LEmptyAndroid.Free; + End; +End; + +End. diff --git a/CORE/Source/Sockets/uRESTDWFCMOAuth.pas b/CORE/Source/Sockets/uRESTDWFCMOAuth.pas new file mode 100644 index 000000000..bc2402a11 --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFCMOAuth.pas @@ -0,0 +1,214 @@ +Unit uRESTDWFCMOAuth; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + uRESTDWFCMTransport; + +Type + TRESTDWFCMOAuth = Class + Private + FHTTP : TRESTDWFCMHTTPTransport; + FEmail : String; + FPrivateKey : String; + FAccessToken : String; + FExpires : TDateTime; + Function Sign(Const AData : String) : String; + Function Post(Const AURL, + ABody : String; + AHeaders : TStrings; + Var AResponse : String) : Integer; + Public + Constructor Create(AHTTP : TRESTDWFCMHTTPTransport); + Property HTTPTransport : TRESTDWFCMHTTPTransport Read FHTTP Write FHTTP; + Function AccessToken(Const AEmail, + APrivateKey : String) : String; + End; + +Implementation + +Uses + uRESTDWOpenSslLib, + uRESTDWFCMCompat; + +Function JSONEscape(Const S : String) : String; +Begin + Result := StringReplace(S, '\', '\\', [rfReplaceAll]); + Result := StringReplace(Result, #13, '\r', [rfReplaceAll]); + Result := StringReplace(Result, #10, '\n', [rfReplaceAll]); + Result := StringReplace(Result, '"', '\"', [rfReplaceAll]); +End; + +Constructor TRESTDWFCMOAuth.Create(AHTTP : TRESTDWFCMHTTPTransport); +Begin + Inherited Create; + FHTTP := AHTTP; +End; + +Function TRESTDWFCMOAuth.Post(Const AURL, + ABody : String; + AHeaders : TStrings; + Var AResponse : String) : Integer; +Var + LBody, + LResponse, + LError : TRESTDWFCMUTF8Stream; +Begin + LBody := TRESTDWFCMUTF8Stream.Create(ABody); + LResponse := TRESTDWFCMUTF8Stream.Create(''); + LError := TRESTDWFCMUTF8Stream.Create(''); + Try + Result := FHTTP.Post(AURL, AHeaders, LBody, LResponse, LError); + If LResponse.Size > 0 Then + AResponse := LResponse.AsString + Else + AResponse := LError.AsString; + Finally + LError.Free; + LResponse.Free; + LBody.Free; + End; +End; + +Function TRESTDWFCMOAuth.Sign(Const AData : String) : String; +Var + LData, + LKey, + LSignature : TRESTDWFCMBytes; + LBIO : PBIO; + LPKey : PEVP_PKEY; + LCtx : PEVP_MD_CTX; + {$IFDEF FPC} + LSize : NativeUInt; + {$ELSE} + {$IFDEF DELPHI2009UP} + LSize : NativeUInt; + {$ELSE} + LSize : Cardinal; + {$ENDIF} + {$ENDIF} +Begin + LData := RESTDWFCMStringToBytes(AData); + LKey := RESTDWFCMStringToBytes( + StringReplace(FPrivateKey, '\n', #13#10, [rfReplaceAll]) + ); + + If (Length(LData) = 0) Or (Length(LKey) = 0) Then + Raise Exception.Create('FCM OAuth2: dados de assinatura invalidos'); + + LBIO := BIO_new_mem_buf(@LKey[0], Length(LKey)); + If LBIO = Nil Then + Raise Exception.Create('FCM OAuth2: BIO da chave privada falhou'); + Try + LPKey := PEM_read_bio_PrivateKey(LBIO, Nil, Nil, Nil); + If LPKey = Nil Then + Raise Exception.Create('FCM OAuth2: chave privada PEM invalida'); + Try + LCtx := EVP_MD_CTX_new; + If LCtx = Nil Then + Raise Exception.Create('FCM OAuth2: contexto RS256 falhou'); + Try + If EVP_DigestSignInit(LCtx, Nil, EVP_sha256, Nil, LPKey) <= 0 Then + Raise Exception.Create('FCM OAuth2: DigestSignInit falhou'); + If EVP_DigestUpdate(LCtx, @LData[0], Length(LData)) <= 0 Then + Raise Exception.Create('FCM OAuth2: DigestUpdate falhou'); + LSize := 0; + If EVP_DigestSignFinal(LCtx, Nil, LSize) <= 0 Then + Raise Exception.Create('FCM OAuth2: tamanho da assinatura falhou'); + SetLength(LSignature, LSize); + If EVP_DigestSignFinal(LCtx, @LSignature[0], LSize) <= 0 Then + Raise Exception.Create('FCM OAuth2: assinatura RS256 falhou'); + SetLength(LSignature, LSize); + Finally + EVP_MD_CTX_free(LCtx); + End; + Finally + EVP_PKEY_free(LPKey); + End; + Finally + BIO_free(LBIO); + End; + + Result := RESTDWFCMBase64URL(LSignature); +End; + +Function TRESTDWFCMOAuth.AccessToken(Const AEmail, + APrivateKey : String) : String; +Var + LHeader, + LPayload, + LData, + LJWT, + LBody, + LResponse : String; + LHeaders : TStringList; + LNowUnix : Int64; + LCode : Integer; +Begin + If (FAccessToken <> '') And + (Now < FExpires) And + (FEmail = AEmail) And + (FPrivateKey = APrivateKey) Then + Begin + Result := FAccessToken; + Exit; + End; + + FEmail := AEmail; + FPrivateKey := APrivateKey; + LNowUnix := RESTDWFCMUnixNow; + + LHeader := RESTDWFCMBase64URL( + RESTDWFCMStringToBytes('{"alg":"RS256","typ":"JWT"}') + ); + + LPayload := + '{"iss":"' + JSONEscape(FEmail) + + '","scope":"https://www.googleapis.com/auth/firebase.messaging"' + + ',"aud":"https://oauth2.googleapis.com/token"' + + ',"iat":' + + RESTDWFCMUIntToStr( + TRESTDWFCMUInt64(LNowUnix) + ) + + ',"exp":' + + RESTDWFCMUIntToStr( + TRESTDWFCMUInt64(LNowUnix + 3600) + ) + '}'; + + LPayload := RESTDWFCMBase64URL(RESTDWFCMStringToBytes(LPayload)); + LData := LHeader + '.' + LPayload; + LJWT := LData + '.' + Sign(LData); + + LBody := + 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer' + + '&assertion=' + RESTDWFCMURLEncode(LJWT); + + LHeaders := TStringList.Create; + Try + LHeaders.Values['Content-Type'] := 'application/x-www-form-urlencoded'; + LHeaders.Values['Accept'] := 'application/json'; + LCode := Post('https://oauth2.googleapis.com/token', + LBody, + LHeaders, + LResponse); + Finally + LHeaders.Free; + End; + + If LCode <> 200 Then + Raise Exception.Create('FCM OAuth2 HTTP ' + + IntToStr(LCode) + ': ' + LResponse); + + FAccessToken := RESTDWFCMJSONValue(LResponse, 'access_token'); + If FAccessToken = '' Then + Raise Exception.Create('FCM OAuth2 retornou token vazio'); + + FExpires := Now + (50 / 1440); + Result := FAccessToken; +End; + +End. diff --git a/CORE/Source/Sockets/uRESTDWFCMOpenSSLApi.pas b/CORE/Source/Sockets/uRESTDWFCMOpenSSLApi.pas new file mode 100644 index 000000000..7416a107a --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFCMOpenSSLApi.pas @@ -0,0 +1,27920 @@ +Unit uRESTDWFCMOpenSSLApi; +{ Cross-platform unified OpenSSL 1.1.1 import and helper library unit for OpenSSL } + +{$MINENUMSIZE 4} + +interface + +uses +{$IFNDEF FPC} + {$IF CompilerVersion > 21} + System.Types, + System.SysUtils; + {$ELSE} + Types, + SysUtils; + {$IFEND} +{$ELSE} + Types, + SysUtils; +{$ENDIF} + +const + {$IF Defined(WIN32)} + LIB_CRYPTO = 'libcrypto-1_1.dll'; + LIB_SSL = 'libssl-1_1.dll'; + _PU = ''; + {$ELSEIF Defined(WIN64)} + LIB_CRYPTO = 'libcrypto-3-x64.dll'; + LIB_SSL = 'libssl-3-x64.dll'; + _PU = ''; + {$ELSEIF Defined(ANDROID64) or (Defined(CPUAARCH64) and Defined(ANDROID))} + LIB_CRYPTO = 'libcrypto-android64.a'; + LIB_SSL = 'libssl-android64.a'; + _PU = ''; + {$ELSEIF Defined(ANDROID32) or (Defined(CPUARM) and Defined(ANDROID))} + LIB_CRYPTO = 'libcrypto-android32.a'; + LIB_SSL = 'libssl-android32.a'; + _PU = ''; + {$ELSEIF Defined(IOS) or Defined(IOS64) or Defined(DCCIOS32) or Defined(DCCIOS64)} + LIB_CRYPTO = 'libcrypto-ios.a'; + LIB_SSL = 'libssl-ios.a'; + _PU = ''; + {$ELSEIF Defined(MACOS32) or (Defined(CPUI386) and Defined(DARWIN))} + LIB_CRYPTO = 'libssl-merged-osx32.dylib'; { We unify LibSsl and LibCrypto into a common shared library on macOS } + LIB_SSL = 'libssl-merged-osx32.dylib'; + _PU = '_'; + {$ELSEIF Defined(MACOS64) or (Defined(CPUX86_64) and Defined(DARWIN)) or (Defined(CPUAARCH64) and Defined(DARWIN))} + LIB_CRYPTO = 'libssl-merged-osx64.dylib'; + LIB_SSL = 'libssl-merged-osx64.dylib'; + _PU = ''; + {$ELSEIF Defined(LINUX) or Defined(FREEBSD)} + LIB_CRYPTO = 'libcrypto.so'; + LIB_SSL = 'libssl.so'; + _PU = ''; + {$ELSE} + {$IF CompilerVersion > 21} + {$MESSAGE Error 'Unsupported platform'} + {$IFEND} + {$IFEND} + +const + OPENSSL_VER_1100 = $1010000f; // 1.1.0 + OPENSSL_VER_1101 = $10101000; // 1.1.1 + OPENSSL_VERSION_NUMBER = $1010107f; + OPENSSL_VERSION_TEXT = 'OpenSSL 1.1.1g 21 Apr 2020'; + SHLIB_VERSION_HISTORY = ''; + SHLIB_VERSION_NUMBER = '1.1'; + OPENSSL_SYS_WIN32 = 1; + OPENSSL_MIN_API = 0; + OPENSSL_API_COMPAT = OPENSSL_MIN_API; + _AES_ENCRYPT = 1; + _AES_DECRYPT = 0; + AES_MAXNR = 14; + AES_BLOCK_SIZE = 16; + _I64_MAX = 9223372036854775807; + OSSL_SSIZE_MAX = _I64_MAX; + CRYPTO_F_CMAC_CTX_NEW = 120; + CRYPTO_F_CRYPTO_DUP_EX_DATA = 110; + CRYPTO_F_CRYPTO_FREE_EX_DATA = 111; + CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX = 100; + CRYPTO_F_CRYPTO_MEMDUP = 115; + CRYPTO_F_CRYPTO_NEW_EX_DATA = 112; + CRYPTO_F_CRYPTO_OCB128_COPY_CTX = 121; + CRYPTO_F_CRYPTO_OCB128_INIT = 122; + CRYPTO_F_CRYPTO_SET_EX_DATA = 102; + CRYPTO_F_FIPS_MODE_SET = 109; + CRYPTO_F_GET_AND_LOCK = 113; + CRYPTO_F_OPENSSL_ATEXIT = 114; + CRYPTO_F_OPENSSL_BUF2HEXSTR = 117; + CRYPTO_F_OPENSSL_FOPEN = 119; + CRYPTO_F_OPENSSL_HEXSTR2BUF = 118; + CRYPTO_F_OPENSSL_INIT_CRYPTO = 116; + CRYPTO_F_OPENSSL_LH_NEW = 126; + CRYPTO_F_OPENSSL_SK_DEEP_COPY = 127; + CRYPTO_F_OPENSSL_SK_DUP = 128; + CRYPTO_F_PKEY_HMAC_INIT = 123; + CRYPTO_F_PKEY_POLY1305_INIT = 124; + CRYPTO_F_PKEY_SIPHASH_INIT = 125; + CRYPTO_F_SK_RESERVE = 129; + CRYPTO_R_FIPS_MODE_NOT_SUPPORTED = 101; + CRYPTO_R_ILLEGAL_HEX_DIGIT = 102; + CRYPTO_R_ODD_NUMBER_OF_DIGITS = 103; + SSLEAY_VERSION_NUMBER = OPENSSL_VERSION_NUMBER; + //OPENSSL_VERSION = 0; + OPENSSL_CFLAGS = 1; + SSLEAY_CFLAGS = OPENSSL_CFLAGS; + OPENSSL_BUILT_ON = 2; + SSLEAY_BUILT_ON = OPENSSL_BUILT_ON; + OPENSSL_PLATFORM = 3; + SSLEAY_PLATFORM = OPENSSL_PLATFORM; + OPENSSL_DIR = 4; + SSLEAY_DIR = OPENSSL_DIR; + CRYPTO_MEM_CHECK_OFF = $0; + CRYPTO_MEM_CHECK_ON = $1; + CRYPTO_MEM_CHECK_ENABLE = $2; + CRYPTO_MEM_CHECK_DISABLE = $3; + CRYPTO_EX_INDEX_SSL = 0; + CRYPTO_EX_INDEX_SSL_CTX = 1; + CRYPTO_EX_INDEX_SSL_SESSION = 2; + CRYPTO_EX_INDEX_X509 = 3; + CRYPTO_EX_INDEX_X509_STORE = 4; + CRYPTO_EX_INDEX_X509_STORE_CTX = 5; + CRYPTO_EX_INDEX_DH = 6; + CRYPTO_EX_INDEX_DSA = 7; + CRYPTO_EX_INDEX_EC_KEY = 8; + CRYPTO_EX_INDEX_RSA = 9; + CRYPTO_EX_INDEX_ENGINE = 10; + CRYPTO_EX_INDEX_UI = 11; + CRYPTO_EX_INDEX_BIO = 12; + CRYPTO_EX_INDEX_APP = 13; + CRYPTO_EX_INDEX_UI_METHOD = 14; + CRYPTO_EX_INDEX_DRBG = 15; + CRYPTO_EX_INDEX__COUNT = 16; + OPENSSL_ENGINES_DIR = 5; + CRYPTO_LOCK = 1; + CRYPTO_UNLOCK = 2; + CRYPTO_READ = 4; + CRYPTO_WRITE = 8; + OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS = $00000001; + OPENSSL_INIT_LOAD_CRYPTO_STRINGS = $00000002; + OPENSSL_INIT_ADD_ALL_CIPHERS = $00000004; + OPENSSL_INIT_ADD_ALL_DIGESTS = $00000008; + OPENSSL_INIT_NO_ADD_ALL_CIPHERS = $00000010; + OPENSSL_INIT_NO_ADD_ALL_DIGESTS = $00000020; + OPENSSL_INIT_LOAD_CONFIG = $00000040; + OPENSSL_INIT_NO_LOAD_CONFIG = $00000080; + OPENSSL_INIT_ASYNC = $00000100; + OPENSSL_INIT_ENGINE_RDRAND = $00000200; + OPENSSL_INIT_ENGINE_DYNAMIC = $00000400; + OPENSSL_INIT_ENGINE_OPENSSL = $00000800; + OPENSSL_INIT_ENGINE_CRYPTODEV = $00001000; + OPENSSL_INIT_ENGINE_CAPI = $00002000; + OPENSSL_INIT_ENGINE_PADLOCK = $00004000; + OPENSSL_INIT_ENGINE_AFALG = $00008000; + OPENSSL_INIT_ATFORK = $00020000; + OPENSSL_INIT_NO_ATEXIT = $00080000; + OPENSSL_INIT_ENGINE_ALL_BUILTIN = (OPENSSL_INIT_ENGINE_RDRAND or OPENSSL_INIT_ENGINE_DYNAMIC or OPENSSL_INIT_ENGINE_CRYPTODEV or OPENSSL_INIT_ENGINE_CAPI or OPENSSL_INIT_ENGINE_PADLOCK); + CRYPTO_ONCE_STATIC_INIT = 0; + BIO_F_ACPT_STATE = 100; + BIO_F_ADDRINFO_WRAP = 148; + BIO_F_ADDR_STRINGS = 134; + BIO_F_BIO_ACCEPT = 101; + BIO_F_BIO_ACCEPT_EX = 137; + BIO_F_BIO_ACCEPT_NEW = 152; + BIO_F_BIO_ADDR_NEW = 144; + BIO_F_BIO_BIND = 147; + BIO_F_BIO_CALLBACK_CTRL = 131; + BIO_F_BIO_CONNECT = 138; + BIO_F_BIO_CONNECT_NEW = 153; + BIO_F_BIO_CTRL = 103; + BIO_F_BIO_GETS = 104; + BIO_F_BIO_GET_HOST_IP = 106; + BIO_F_BIO_GET_NEW_INDEX = 102; + BIO_F_BIO_GET_PORT = 107; + BIO_F_BIO_LISTEN = 139; + BIO_F_BIO_LOOKUP = 135; + BIO_F_BIO_LOOKUP_EX = 143; + BIO_F_BIO_MAKE_PAIR = 121; + BIO_F_BIO_METH_NEW = 146; + BIO_F_BIO_NEW = 108; + BIO_F_BIO_NEW_DGRAM_SCTP = 145; + BIO_F_BIO_NEW_FILE = 109; + BIO_F_BIO_NEW_MEM_BUF = 126; + BIO_F_BIO_NREAD = 123; + BIO_F_BIO_NREAD0 = 124; + BIO_F_BIO_NWRITE = 125; + BIO_F_BIO_NWRITE0 = 122; + BIO_F_BIO_PARSE_HOSTSERV = 136; + BIO_F_BIO_PUTS = 110; + BIO_F_BIO_READ = 111; + BIO_F_BIO_READ_EX = 105; + BIO_F_BIO_READ_INTERN = 120; + BIO_F_BIO_SOCKET = 140; + BIO_F_BIO_SOCKET_NBIO = 142; + BIO_F_BIO_SOCK_INFO = 141; + BIO_F_BIO_SOCK_INIT = 112; + BIO_F_BIO_WRITE = 113; + BIO_F_BIO_WRITE_EX = 119; + BIO_F_BIO_WRITE_INTERN = 128; + BIO_F_BUFFER_CTRL = 114; + BIO_F_CONN_CTRL = 127; + BIO_F_CONN_STATE = 115; + BIO_F_DGRAM_SCTP_NEW = 149; + BIO_F_DGRAM_SCTP_READ = 132; + BIO_F_DGRAM_SCTP_WRITE = 133; + BIO_F_DOAPR_OUTCH = 150; + BIO_F_FILE_CTRL = 116; + BIO_F_FILE_READ = 130; + BIO_F_LINEBUFFER_CTRL = 129; + BIO_F_LINEBUFFER_NEW = 151; + BIO_F_MEM_WRITE = 117; + BIO_F_NBIOF_NEW = 154; + BIO_F_SLG_WRITE = 155; + BIO_F_SSL_NEW = 118; + BIO_R_ACCEPT_ERROR = 100; + BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET = 141; + BIO_R_AMBIGUOUS_HOST_OR_SERVICE = 129; + BIO_R_BAD_FOPEN_MODE = 101; + BIO_R_BROKEN_PIPE = 124; + BIO_R_CONNECT_ERROR = 103; + BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET = 107; + BIO_R_GETSOCKNAME_ERROR = 132; + BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS = 133; + BIO_R_GETTING_SOCKTYPE = 134; + BIO_R_INVALID_ARGUMENT = 125; + BIO_R_INVALID_SOCKET = 135; + BIO_R_IN_USE = 123; + BIO_R_LENGTH_TOO_LONG = 102; + BIO_R_LISTEN_V6_ONLY = 136; + BIO_R_LOOKUP_RETURNED_NOTHING = 142; + BIO_R_MALFORMED_HOST_OR_SERVICE = 130; + BIO_R_NBIO_CONNECT_ERROR = 110; + BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED = 143; + BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED = 144; + BIO_R_NO_PORT_DEFINED = 113; + BIO_R_NO_SUCH_FILE = 128; + BIO_R_NULL_PARAMETER = 115; + BIO_R_UNABLE_TO_BIND_SOCKET = 117; + BIO_R_UNABLE_TO_CREATE_SOCKET = 118; + BIO_R_UNABLE_TO_KEEPALIVE = 137; + BIO_R_UNABLE_TO_LISTEN_SOCKET = 119; + BIO_R_UNABLE_TO_NODELAY = 138; + BIO_R_UNABLE_TO_REUSEADDR = 139; + BIO_R_UNAVAILABLE_IP_FAMILY = 145; + BIO_R_UNINITIALIZED = 120; + BIO_R_UNKNOWN_INFO_TYPE = 140; + BIO_R_UNSUPPORTED_IP_FAMILY = 146; + BIO_R_UNSUPPORTED_METHOD = 121; + BIO_R_UNSUPPORTED_PROTOCOL_FAMILY = 131; + BIO_R_WRITE_TO_READ_ONLY_BIO = 126; + BIO_R_WSASTARTUP = 122; + BIO_TYPE_DESCRIPTOR = $0100; + BIO_TYPE_FILTER = $0200; + BIO_TYPE_SOURCE_SINK = $0400; + BIO_TYPE_NONE = 0; + BIO_TYPE_MEM = (1 or BIO_TYPE_SOURCE_SINK); + BIO_TYPE_FILE = (2 or BIO_TYPE_SOURCE_SINK); + BIO_TYPE_FD = (4 or BIO_TYPE_SOURCE_SINK or BIO_TYPE_DESCRIPTOR); + BIO_TYPE_SOCKET = (5 or BIO_TYPE_SOURCE_SINK or BIO_TYPE_DESCRIPTOR); + BIO_TYPE_NULL = (6 or BIO_TYPE_SOURCE_SINK); + BIO_TYPE_SSL = (7 or BIO_TYPE_FILTER); + BIO_TYPE_MD = (8 or BIO_TYPE_FILTER); + BIO_TYPE_BUFFER = (9 or BIO_TYPE_FILTER); + BIO_TYPE_CIPHER = (10 or BIO_TYPE_FILTER); + BIO_TYPE_BASE64 = (11 or BIO_TYPE_FILTER); + BIO_TYPE_CONNECT = (12 or BIO_TYPE_SOURCE_SINK or BIO_TYPE_DESCRIPTOR); + BIO_TYPE_ACCEPT = (13 or BIO_TYPE_SOURCE_SINK or BIO_TYPE_DESCRIPTOR); + BIO_TYPE_NBIO_TEST = (16 or BIO_TYPE_FILTER); + BIO_TYPE_NULL_FILTER = (17 or BIO_TYPE_FILTER); + BIO_TYPE_BIO = (19 or BIO_TYPE_SOURCE_SINK); + BIO_TYPE_LINEBUFFER = (20 or BIO_TYPE_FILTER); + BIO_TYPE_DGRAM = (21 or BIO_TYPE_SOURCE_SINK or BIO_TYPE_DESCRIPTOR); + BIO_TYPE_ASN1 = (22 or BIO_TYPE_FILTER); + BIO_TYPE_COMP = (23 or BIO_TYPE_FILTER); + BIO_TYPE_START = 128; + BIO_NOCLOSE = $00; + BIO_CLOSE = $01; + BIO_CTRL_RESET = 1; + BIO_CTRL_EOF = 2; + BIO_CTRL_INFO = 3; + BIO_CTRL_SET = 4; + BIO_CTRL_GET = 5; + BIO_CTRL_PUSH = 6; + BIO_CTRL_POP = 7; + BIO_CTRL_GET_CLOSE = 8; + BIO_CTRL_SET_CLOSE = 9; + _BIO_CTRL_PENDING = 10; + BIO_CTRL_FLUSH = 11; + BIO_CTRL_DUP = 12; + _BIO_CTRL_WPENDING = 13; + BIO_CTRL_SET_CALLBACK = 14; + BIO_CTRL_GET_CALLBACK = 15; + BIO_CTRL_PEEK = 29; + BIO_CTRL_SET_FILENAME = 30; + BIO_CTRL_DGRAM_CONNECT = 31; + BIO_CTRL_DGRAM_SET_CONNECTED = 32; + BIO_CTRL_DGRAM_SET_RECV_TIMEOUT = 33; + BIO_CTRL_DGRAM_GET_RECV_TIMEOUT = 34; + BIO_CTRL_DGRAM_SET_SEND_TIMEOUT = 35; + BIO_CTRL_DGRAM_GET_SEND_TIMEOUT = 36; + BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP = 37; + BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP = 38; + BIO_CTRL_DGRAM_MTU_DISCOVER = 39; + BIO_CTRL_DGRAM_QUERY_MTU = 40; + BIO_CTRL_DGRAM_GET_FALLBACK_MTU = 47; + BIO_CTRL_DGRAM_GET_MTU = 41; + BIO_CTRL_DGRAM_SET_MTU = 42; + BIO_CTRL_DGRAM_MTU_EXCEEDED = 43; + BIO_CTRL_DGRAM_GET_PEER = 46; + BIO_CTRL_DGRAM_SET_PEER = 44; + BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT = 45; + BIO_CTRL_DGRAM_SET_DONT_FRAG = 48; + BIO_CTRL_DGRAM_GET_MTU_OVERHEAD = 49; + BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE = 50; + BIO_CTRL_DGRAM_SET_PEEK_MODE = 71; + BIO_FP_READ = $02; + BIO_FP_WRITE = $04; + BIO_FP_APPEND = $08; + BIO_FP_TEXT = $10; + BIO_FLAGS_READ = $01; + BIO_FLAGS_WRITE = $02; + BIO_FLAGS_IO_SPECIAL = $04; + BIO_FLAGS_RWS = (BIO_FLAGS_READ or BIO_FLAGS_WRITE or BIO_FLAGS_IO_SPECIAL); + BIO_FLAGS_SHOULD_RETRY = $08; + BIO_FLAGS_UPLINK = 0; + BIO_FLAGS_BASE64_NO_NL = $100; + BIO_FLAGS_MEM_RDONLY = $200; + BIO_FLAGS_NONCLEAR_RST = $400; + BIO_FLAGS_IN_EOF = $800; + BIO_RR_SSL_X509_LOOKUP = $01; + BIO_RR_CONNECT = $02; + BIO_RR_ACCEPT = $03; + BIO_CB_FREE = $01; + BIO_CB_READ = $02; + BIO_CB_WRITE = $03; + BIO_CB_PUTS = $04; + BIO_CB_GETS = $05; + BIO_CB_CTRL = $06; + BIO_CB_RETURN = $80; + BIO_C_SET_CONNECT = 100; + BIO_C_DO_STATE_MACHINE = 101; + BIO_C_SET_NBIO = 102; + BIO_C_SET_FD = 104; + BIO_C_GET_FD = 105; + BIO_C_SET_FILE_PTR = 106; + BIO_C_GET_FILE_PTR = 107; + BIO_C_SET_FILENAME = 108; + BIO_C_SET_SSL = 109; + BIO_C_GET_SSL = 110; + BIO_C_SET_MD = 111; + BIO_C_GET_MD = 112; + BIO_C_GET_CIPHER_STATUS = 113; + BIO_C_SET_BUF_MEM = 114; + BIO_C_GET_BUF_MEM_PTR = 115; + BIO_C_GET_BUFF_NUM_LINES = 116; + BIO_C_SET_BUFF_SIZE = 117; + BIO_C_SET_ACCEPT = 118; + BIO_C_SSL_MODE = 119; + BIO_C_GET_MD_CTX = 120; + BIO_C_SET_BUFF_READ_DATA = 122; + BIO_C_GET_CONNECT = 123; + BIO_C_GET_ACCEPT = 124; + BIO_C_SET_SSL_RENEGOTIATE_BYTES = 125; + BIO_C_GET_SSL_NUM_RENEGOTIATES = 126; + BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT = 127; + BIO_C_FILE_SEEK = 128; + BIO_C_GET_CIPHER_CTX = 129; + BIO_C_SET_BUF_MEM_EOF_RETURN = 130; + BIO_C_SET_BIND_MODE = 131; + BIO_C_GET_BIND_MODE = 132; + BIO_C_FILE_TELL = 133; + BIO_C_GET_SOCKS = 134; + BIO_C_SET_SOCKS = 135; + BIO_C_SET_WRITE_BUF_SIZE = 136; + BIO_C_GET_WRITE_BUF_SIZE = 137; + BIO_C_MAKE_BIO_PAIR = 138; + BIO_C_DESTROY_BIO_PAIR = 139; + BIO_C_GET_WRITE_GUARANTEE = 140; + BIO_C_GET_READ_REQUEST = 141; + BIO_C_SHUTDOWN_WR = 142; + BIO_C_NREAD0 = 143; + BIO_C_NREAD = 144; + BIO_C_NWRITE0 = 145; + BIO_C_NWRITE = 146; + BIO_C_RESET_READ_REQUEST = 147; + BIO_C_SET_MD_CTX = 148; + BIO_C_SET_PREFIX = 149; + BIO_C_GET_PREFIX = 150; + BIO_C_SET_SUFFIX = 151; + BIO_C_GET_SUFFIX = 152; + BIO_C_SET_EX_ARG = 153; + BIO_C_GET_EX_ARG = 154; + BIO_C_SET_CONNECT_MODE = 155; + BIO_FAMILY_IPV4 = 4; + BIO_FAMILY_IPV6 = 6; + BIO_FAMILY_IPANY = 256; + BIO_BIND_NORMAL = 0; + BIO_SOCK_REUSEADDR = $01; + BIO_BIND_REUSEADDR = BIO_SOCK_REUSEADDR; + BIO_BIND_REUSEADDR_IF_UNUSED = BIO_SOCK_REUSEADDR; + BIO_SOCK_V6_ONLY = $02; + BIO_SOCK_KEEPALIVE = $04; + BIO_SOCK_NONBLOCK = $08; + BIO_SOCK_NODELAY = $10; + ASN1_F_A2D_ASN1_OBJECT = 100; + ASN1_F_A2I_ASN1_INTEGER = 102; + ASN1_F_A2I_ASN1_STRING = 103; + ASN1_F_APPEND_EXP = 176; + ASN1_F_ASN1_BIO_INIT = 113; + ASN1_F_ASN1_BIT_STRING_SET_BIT = 183; + ASN1_F_ASN1_CB = 177; + ASN1_F_ASN1_CHECK_TLEN = 104; + ASN1_F_ASN1_COLLECT = 106; + ASN1_F_ASN1_D2I_EX_PRIMITIVE = 108; + ASN1_F_ASN1_D2I_FP = 109; + ASN1_F_ASN1_D2I_READ_BIO = 107; + ASN1_F_ASN1_DIGEST = 184; + ASN1_F_ASN1_DO_ADB = 110; + ASN1_F_ASN1_DO_LOCK = 233; + ASN1_F_ASN1_DUP = 111; + ASN1_F_ASN1_ENC_SAVE = 115; + ASN1_F_ASN1_EX_C2I = 204; + ASN1_F_ASN1_FIND_END = 190; + ASN1_F_ASN1_GENERALIZEDTIME_ADJ = 216; + ASN1_F_ASN1_GENERATE_V3 = 178; + ASN1_F_ASN1_GET_INT64 = 224; + ASN1_F_ASN1_GET_OBJECT = 114; + ASN1_F_ASN1_GET_UINT64 = 225; + ASN1_F_ASN1_I2D_BIO = 116; + ASN1_F_ASN1_I2D_FP = 117; + ASN1_F_ASN1_ITEM_D2I_FP = 206; + ASN1_F_ASN1_ITEM_DUP = 191; + ASN1_F_ASN1_ITEM_EMBED_D2I = 120; + ASN1_F_ASN1_ITEM_EMBED_NEW = 121; + ASN1_F_ASN1_ITEM_FLAGS_I2D = 118; + ASN1_F_ASN1_ITEM_I2D_BIO = 192; + ASN1_F_ASN1_ITEM_I2D_FP = 193; + ASN1_F_ASN1_ITEM_PACK = 198; + ASN1_F_ASN1_ITEM_SIGN = 195; + ASN1_F_ASN1_ITEM_SIGN_CTX = 220; + ASN1_F_ASN1_ITEM_UNPACK = 199; + ASN1_F_ASN1_ITEM_VERIFY = 197; + ASN1_F_ASN1_MBSTRING_NCOPY = 122; + ASN1_F_ASN1_OBJECT_NEW = 123; + ASN1_F_ASN1_OUTPUT_DATA = 214; + ASN1_F_ASN1_PCTX_NEW = 205; + ASN1_F_ASN1_PRIMITIVE_NEW = 119; + ASN1_F_ASN1_SCTX_NEW = 221; + ASN1_F_ASN1_SIGN = 128; + ASN1_F_ASN1_STR2TYPE = 179; + ASN1_F_ASN1_STRING_GET_INT64 = 227; + ASN1_F_ASN1_STRING_GET_UINT64 = 230; + ASN1_F_ASN1_STRING_SET = 186; + ASN1_F_ASN1_STRING_TABLE_ADD = 129; + ASN1_F_ASN1_STRING_TO_BN = 228; + ASN1_F_ASN1_STRING_TYPE_NEW = 130; + ASN1_F_ASN1_TEMPLATE_EX_D2I = 132; + ASN1_F_ASN1_TEMPLATE_NEW = 133; + ASN1_F_ASN1_TEMPLATE_NOEXP_D2I = 131; + ASN1_F_ASN1_TIME_ADJ = 217; + ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING = 134; + ASN1_F_ASN1_TYPE_GET_OCTETSTRING = 135; + ASN1_F_ASN1_UTCTIME_ADJ = 218; + ASN1_F_ASN1_VERIFY = 137; + ASN1_F_B64_READ_ASN1 = 209; + ASN1_F_B64_WRITE_ASN1 = 210; + ASN1_F_BIO_NEW_NDEF = 208; + ASN1_F_BITSTR_CB = 180; + ASN1_F_BN_TO_ASN1_STRING = 229; + ASN1_F_C2I_ASN1_BIT_STRING = 189; + ASN1_F_C2I_ASN1_INTEGER = 194; + ASN1_F_C2I_ASN1_OBJECT = 196; + ASN1_F_C2I_IBUF = 226; + ASN1_F_C2I_UINT64_INT = 101; + ASN1_F_COLLECT_DATA = 140; + ASN1_F_D2I_ASN1_OBJECT = 147; + ASN1_F_D2I_ASN1_UINTEGER = 150; + ASN1_F_D2I_AUTOPRIVATEKEY = 207; + ASN1_F_D2I_PRIVATEKEY = 154; + ASN1_F_D2I_PUBLICKEY = 155; + ASN1_F_DO_BUF = 142; + ASN1_F_DO_CREATE = 124; + ASN1_F_DO_DUMP = 125; + ASN1_F_DO_TCREATE = 222; + ASN1_F_I2A_ASN1_OBJECT = 126; + ASN1_F_I2D_ASN1_BIO_STREAM = 211; + ASN1_F_I2D_ASN1_OBJECT = 143; + ASN1_F_I2D_DSA_PUBKEY = 161; + ASN1_F_I2D_EC_PUBKEY = 181; + ASN1_F_I2D_PRIVATEKEY = 163; + ASN1_F_I2D_PUBLICKEY = 164; + ASN1_F_I2D_RSA_PUBKEY = 165; + ASN1_F_LONG_C2I = 166; + ASN1_F_NDEF_PREFIX = 127; + ASN1_F_NDEF_SUFFIX = 136; + ASN1_F_OID_MODULE_INIT = 174; + ASN1_F_PARSE_TAGGING = 182; + ASN1_F_PKCS5_PBE2_SET_IV = 167; + ASN1_F_PKCS5_PBE2_SET_SCRYPT = 231; + ASN1_F_PKCS5_PBE_SET = 202; + ASN1_F_PKCS5_PBE_SET0_ALGOR = 215; + ASN1_F_PKCS5_PBKDF2_SET = 219; + ASN1_F_PKCS5_SCRYPT_SET = 232; + ASN1_F_SMIME_READ_ASN1 = 212; + ASN1_F_SMIME_TEXT = 213; + ASN1_F_STABLE_GET = 138; + ASN1_F_STBL_MODULE_INIT = 223; + ASN1_F_UINT32_C2I = 105; + ASN1_F_UINT32_NEW = 139; + ASN1_F_UINT64_C2I = 112; + ASN1_F_UINT64_NEW = 141; + ASN1_F_X509_CRL_ADD0_REVOKED = 169; + ASN1_F_X509_INFO_NEW = 170; + ASN1_F_X509_NAME_ENCODE = 203; + ASN1_F_X509_NAME_EX_D2I = 158; + ASN1_F_X509_NAME_EX_NEW = 171; + ASN1_F_X509_PKEY_NEW = 173; + ASN1_R_ADDING_OBJECT = 171; + ASN1_R_ASN1_PARSE_ERROR = 203; + ASN1_R_ASN1_SIG_PARSE_ERROR = 204; + ASN1_R_AUX_ERROR = 100; + ASN1_R_BAD_OBJECT_HEADER = 102; + ASN1_R_BMPSTRING_IS_WRONG_LENGTH = 214; + ASN1_R_BN_LIB = 105; + ASN1_R_BOOLEAN_IS_WRONG_LENGTH = 106; + ASN1_R_BUFFER_TOO_SMALL = 107; + ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER = 108; + ASN1_R_CONTEXT_NOT_INITIALISED = 217; + ASN1_R_DATA_IS_WRONG = 109; + ASN1_R_DECODE_ERROR = 110; + ASN1_R_DEPTH_EXCEEDED = 174; + ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED = 198; + ASN1_R_ENCODE_ERROR = 112; + ASN1_R_ERROR_GETTING_TIME = 173; + ASN1_R_ERROR_LOADING_SECTION = 172; + ASN1_R_ERROR_SETTING_CIPHER_PARAMS = 114; + ASN1_R_EXPECTING_AN_INTEGER = 115; + ASN1_R_EXPECTING_AN_OBJECT = 116; + ASN1_R_EXPLICIT_LENGTH_MISMATCH = 119; + ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED = 120; + ASN1_R_FIELD_MISSING = 121; + ASN1_R_FIRST_NUM_TOO_LARGE = 122; + ASN1_R_HEADER_TOO_LONG = 123; + ASN1_R_ILLEGAL_BITSTRING_FORMAT = 175; + ASN1_R_ILLEGAL_BOOLEAN = 176; + ASN1_R_ILLEGAL_CHARACTERS = 124; + ASN1_R_ILLEGAL_FORMAT = 177; + ASN1_R_ILLEGAL_HEX = 178; + ASN1_R_ILLEGAL_IMPLICIT_TAG = 179; + ASN1_R_ILLEGAL_INTEGER = 180; + ASN1_R_ILLEGAL_NEGATIVE_VALUE = 226; + ASN1_R_ILLEGAL_NESTED_TAGGING = 181; + ASN1_R_ILLEGAL_NULL = 125; + ASN1_R_ILLEGAL_NULL_VALUE = 182; + ASN1_R_ILLEGAL_OBJECT = 183; + ASN1_R_ILLEGAL_OPTIONAL_ANY = 126; + ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE = 170; + ASN1_R_ILLEGAL_PADDING = 221; + ASN1_R_ILLEGAL_TAGGED_ANY = 127; + ASN1_R_ILLEGAL_TIME_VALUE = 184; + ASN1_R_ILLEGAL_ZERO_CONTENT = 222; + ASN1_R_INTEGER_NOT_ASCII_FORMAT = 185; + ASN1_R_INTEGER_TOO_LARGE_FOR_LONG = 128; + ASN1_R_INVALID_BIT_STRING_BITS_LEFT = 220; + ASN1_R_INVALID_BMPSTRING_LENGTH = 129; + ASN1_R_INVALID_DIGIT = 130; + ASN1_R_INVALID_MIME_TYPE = 205; + ASN1_R_INVALID_MODIFIER = 186; + ASN1_R_INVALID_NUMBER = 187; + ASN1_R_INVALID_OBJECT_ENCODING = 216; + ASN1_R_INVALID_SCRYPT_PARAMETERS = 227; + ASN1_R_INVALID_SEPARATOR = 131; + ASN1_R_INVALID_STRING_TABLE_VALUE = 218; + ASN1_R_INVALID_UNIVERSALSTRING_LENGTH = 133; + ASN1_R_INVALID_UTF8STRING = 134; + ASN1_R_INVALID_VALUE = 219; + ASN1_R_LIST_ERROR = 188; + ASN1_R_MIME_NO_CONTENT_TYPE = 206; + ASN1_R_MIME_PARSE_ERROR = 207; + ASN1_R_MIME_SIG_PARSE_ERROR = 208; + ASN1_R_MISSING_EOC = 137; + ASN1_R_MISSING_SECOND_NUMBER = 138; + ASN1_R_MISSING_VALUE = 189; + ASN1_R_MSTRING_NOT_UNIVERSAL = 139; + ASN1_R_MSTRING_WRONG_TAG = 140; + ASN1_R_NESTED_ASN1_STRING = 197; + ASN1_R_NESTED_TOO_DEEP = 201; + ASN1_R_NON_HEX_CHARACTERS = 141; + ASN1_R_NOT_ASCII_FORMAT = 190; + ASN1_R_NOT_ENOUGH_DATA = 142; + ASN1_R_NO_CONTENT_TYPE = 209; + ASN1_R_NO_MATCHING_CHOICE_TYPE = 143; + ASN1_R_NO_MULTIPART_BODY_FAILURE = 210; + ASN1_R_NO_MULTIPART_BOUNDARY = 211; + ASN1_R_NO_SIG_CONTENT_TYPE = 212; + ASN1_R_NULL_IS_WRONG_LENGTH = 144; + ASN1_R_OBJECT_NOT_ASCII_FORMAT = 191; + ASN1_R_ODD_NUMBER_OF_CHARS = 145; + ASN1_R_SECOND_NUMBER_TOO_LARGE = 147; + ASN1_R_SEQUENCE_LENGTH_MISMATCH = 148; + ASN1_R_SEQUENCE_NOT_CONSTRUCTED = 149; + ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG = 192; + ASN1_R_SHORT_LINE = 150; + ASN1_R_SIG_INVALID_MIME_TYPE = 213; + ASN1_R_STREAMING_NOT_SUPPORTED = 202; + ASN1_R_STRING_TOO_LONG = 151; + ASN1_R_STRING_TOO_SHORT = 152; + ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD = 154; + ASN1_R_TIME_NOT_ASCII_FORMAT = 193; + ASN1_R_TOO_LARGE = 223; + ASN1_R_TOO_LONG = 155; + ASN1_R_TOO_SMALL = 224; + ASN1_R_TYPE_NOT_CONSTRUCTED = 156; + ASN1_R_TYPE_NOT_PRIMITIVE = 195; + ASN1_R_UNEXPECTED_EOC = 159; + ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH = 215; + ASN1_R_UNKNOWN_FORMAT = 160; + ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM = 161; + ASN1_R_UNKNOWN_OBJECT_TYPE = 162; + ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE = 163; + ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM = 199; + ASN1_R_UNKNOWN_TAG = 194; + ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE = 164; + ASN1_R_UNSUPPORTED_CIPHER = 228; + ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE = 167; + ASN1_R_UNSUPPORTED_TYPE = 196; + ASN1_R_WRONG_INTEGER_TYPE = 225; + ASN1_R_WRONG_PUBLIC_KEY_TYPE = 200; + ASN1_R_WRONG_TAG = 168; + BN_F_BNRAND = 127; + BN_F_BNRAND_RANGE = 138; + BN_F_BN_BLINDING_CONVERT_EX = 100; + BN_F_BN_BLINDING_CREATE_PARAM = 128; + BN_F_BN_BLINDING_INVERT_EX = 101; + BN_F_BN_BLINDING_NEW = 102; + BN_F_BN_BLINDING_UPDATE = 103; + BN_F_BN_BN2DEC = 104; + BN_F_BN_BN2HEX = 105; + BN_F_BN_COMPUTE_WNAF = 142; + BN_F_BN_CTX_GET = 116; + BN_F_BN_CTX_NEW = 106; + BN_F_BN_CTX_START = 129; + BN_F_BN_DIV = 107; + BN_F_BN_DIV_RECP = 130; + BN_F_BN_EXP = 123; + BN_F_BN_EXPAND_INTERNAL = 120; + BN_F_BN_GENCB_NEW = 143; + BN_F_BN_GENERATE_DSA_NONCE = 140; + BN_F_BN_GENERATE_PRIME_EX = 141; + BN_F_BN_GF2M_MOD = 131; + BN_F_BN_GF2M_MOD_EXP = 132; + BN_F_BN_GF2M_MOD_MUL = 133; + BN_F_BN_GF2M_MOD_SOLVE_QUAD = 134; + BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR = 135; + BN_F_BN_GF2M_MOD_SQR = 136; + BN_F_BN_GF2M_MOD_SQRT = 137; + BN_F_BN_LSHIFT = 145; + BN_F_BN_MOD_EXP2_MONT = 118; + BN_F_BN_MOD_EXP_MONT = 109; + BN_F_BN_MOD_EXP_MONT_CONSTTIME = 124; + BN_F_BN_MOD_EXP_MONT_WORD = 117; + BN_F_BN_MOD_EXP_RECP = 125; + BN_F_BN_MOD_EXP_SIMPLE = 126; + BN_F_BN_MOD_INVERSE = 110; + BN_F_BN_MOD_INVERSE_NO_BRANCH = 139; + BN_F_BN_MOD_LSHIFT_QUICK = 119; + BN_F_BN_MOD_SQRT = 121; + BN_F_BN_MONT_CTX_NEW = 149; + BN_F_BN_MPI2BN = 112; + BN_F_BN_NEW = 113; + BN_F_BN_POOL_GET = 147; + BN_F_BN_RAND = 114; + BN_F_BN_RAND_RANGE = 122; + BN_F_BN_RECP_CTX_NEW = 150; + BN_F_BN_RSHIFT = 146; + BN_F_BN_SET_WORDS = 144; + BN_F_BN_STACK_PUSH = 148; + BN_F_BN_USUB = 115; + BN_R_ARG2_LT_ARG3 = 100; + BN_R_BAD_RECIPROCAL = 101; + BN_R_BIGNUM_TOO_LONG = 114; + BN_R_BITS_TOO_SMALL = 118; + BN_R_CALLED_WITH_EVEN_MODULUS = 102; + BN_R_DIV_BY_ZERO = 103; + BN_R_ENCODING_ERROR = 104; + BN_R_EXPAND_ON_STATIC_BIGNUM_DATA = 105; + BN_R_INPUT_NOT_REDUCED = 110; + BN_R_INVALID_LENGTH = 106; + BN_R_INVALID_RANGE = 115; + BN_R_INVALID_SHIFT = 119; + BN_R_NOT_A_SQUARE = 111; + BN_R_NOT_INITIALIZED = 107; + BN_R_NO_INVERSE = 108; + BN_R_NO_SOLUTION = 116; + BN_R_PRIVATE_KEY_TOO_LARGE = 117; + BN_R_P_IS_NOT_PRIME = 112; + BN_R_TOO_MANY_ITERATIONS = 113; + BN_R_TOO_MANY_TEMPORARY_VARIABLES = 109; + BN_BYTES = 4; + BN_BITS2 = (BN_BYTES*8); + BN_BITS = (BN_BITS2*2); + BN_FLG_MALLOCED = $01; + BN_FLG_STATIC_DATA = $02; + BN_FLG_CONSTTIME = $04; + BN_FLG_SECURE = $08; + BN_FLG_EXP_CONSTTIME = BN_FLG_CONSTTIME; + BN_FLG_FREE = $8000; + BN_RAND_TOP_ANY = -1; + BN_RAND_TOP_ONE = 0; + BN_RAND_TOP_TWO = 1; + BN_RAND_BOTTOM_ANY = 0; + BN_RAND_BOTTOM_ODD = 1; + BN_prime_checks = 0; + BN_BLINDING_NO_UPDATE = $00000001; + BN_BLINDING_NO_RECREATE = $00000002; + V_ASN1_UNIVERSAL = $00; + V_ASN1_APPLICATION = $40; + V_ASN1_CONTEXT_SPECIFIC = $80; + V_ASN1_PRIVATE = $c0; + V_ASN1_CONSTRUCTED = $20; + V_ASN1_PRIMITIVE_TAG = $1f; + V_ASN1_PRIMATIVE_TAG = V_ASN1_PRIMITIVE_TAG; // *compat* + V_ASN1_APP_CHOOSE = -2; + V_ASN1_OTHER = -3; + V_ASN1_ANY = -4; + V_ASN1_UNDEF = -1; + V_ASN1_EOC = 0; + V_ASN1_BOOLEAN = 1; + V_ASN1_INTEGER = 2; + V_ASN1_BIT_STRING = 3; + V_ASN1_OCTET_STRING = 4; + V_ASN1_NULL = 5; + V_ASN1_OBJECT = 6; + V_ASN1_OBJECT_DESCRIPTOR = 7; + V_ASN1_EXTERNAL = 8; + V_ASN1_REAL = 9; + V_ASN1_ENUMERATED = 10; + V_ASN1_UTF8STRING = 12; + V_ASN1_SEQUENCE = 16; + V_ASN1_SET = 17; + V_ASN1_NUMERICSTRING = 18; + V_ASN1_PRINTABLESTRING = 19; + V_ASN1_T61STRING = 20; + V_ASN1_TELETEXSTRING = 20; + V_ASN1_VIDEOTEXSTRING = 21; + V_ASN1_IA5STRING = 22; + V_ASN1_UTCTIME = 23; + V_ASN1_GENERALIZEDTIME = 24; + V_ASN1_GRAPHICSTRING = 25; + V_ASN1_ISO64STRING = 26; + V_ASN1_VISIBLESTRING = 26; + V_ASN1_GENERALSTRING = 27; + V_ASN1_UNIVERSALSTRING = 28; + V_ASN1_BMPSTRING = 30; + V_ASN1_NEG = $100; + V_ASN1_NEG_INTEGER = (2 or V_ASN1_NEG); + V_ASN1_NEG_ENUMERATED = (10 or V_ASN1_NEG); + B_ASN1_NUMERICSTRING = $0001; + B_ASN1_PRINTABLESTRING = $0002; + B_ASN1_T61STRING = $0004; + B_ASN1_TELETEXSTRING = $0004; + B_ASN1_VIDEOTEXSTRING = $0008; + B_ASN1_IA5STRING = $0010; + B_ASN1_GRAPHICSTRING = $0020; + B_ASN1_ISO64STRING = $0040; + B_ASN1_VISIBLESTRING = $0040; + B_ASN1_GENERALSTRING = $0080; + B_ASN1_UNIVERSALSTRING = $0100; + B_ASN1_OCTET_STRING = $0200; + B_ASN1_BIT_STRING = $0400; + B_ASN1_BMPSTRING = $0800; + B_ASN1_UNKNOWN = $1000; + B_ASN1_UTF8STRING = $2000; + B_ASN1_UTCTIME = $4000; + B_ASN1_GENERALIZEDTIME = $8000; + B_ASN1_SEQUENCE = $10000; + MBSTRING_FLAG = $1000; + MBSTRING_UTF8 = (MBSTRING_FLAG); + MBSTRING_ASC = (MBSTRING_FLAG or 1); + MBSTRING_BMP = (MBSTRING_FLAG or 2); + MBSTRING_UNIV = (MBSTRING_FLAG or 4); + SMIME_OLDMIME = $400; + SMIME_CRLFEOL = $800; + SMIME_STREAM = $1000; + ASN1_STRING_FLAG_BITS_LEFT = $08; + ASN1_STRING_FLAG_NDEF = $010; + ASN1_STRING_FLAG_CONT = $020; + ASN1_STRING_FLAG_MSTRING = $040; + ASN1_STRING_FLAG_EMBED = $080; + ASN1_STRING_FLAG_X509_TIME = $100; + ASN1_LONG_UNDEF = $7fffffff; + STABLE_FLAGS_MALLOC = $01; + STABLE_FLAGS_CLEAR = STABLE_FLAGS_MALLOC; + STABLE_NO_MASK = $02; + DIRSTRING_TYPE = (B_ASN1_PRINTABLESTRING or B_ASN1_T61STRING or B_ASN1_BMPSTRING or B_ASN1_UTF8STRING); + PKCS9STRING_TYPE = (DIRSTRING_TYPE or B_ASN1_IA5STRING); + ASN1_STRFLGS_ESC_2253 = 1; + ASN1_STRFLGS_ESC_CTRL = 2; + ASN1_STRFLGS_ESC_MSB = 4; + ASN1_STRFLGS_ESC_QUOTE = 8; + CHARTYPE_PRINTABLESTRING = $10; + CHARTYPE_FIRST_ESC_2253 = $20; + CHARTYPE_LAST_ESC_2253 = $40; + ASN1_STRFLGS_UTF8_CONVERT = $10; + ASN1_STRFLGS_IGNORE_TYPE = $20; + ASN1_STRFLGS_SHOW_TYPE = $40; + ASN1_STRFLGS_DUMP_ALL = $80; + ASN1_STRFLGS_DUMP_UNKNOWN = $100; + ASN1_STRFLGS_DUMP_DER = $200; + ASN1_STRFLGS_ESC_2254 = $400; + ASN1_STRFLGS_RFC2253 = (ASN1_STRFLGS_ESC_2253 or ASN1_STRFLGS_ESC_CTRL or ASN1_STRFLGS_ESC_MSB or ASN1_STRFLGS_UTF8_CONVERT or ASN1_STRFLGS_DUMP_UNKNOWN or ASN1_STRFLGS_DUMP_DER); + B_ASN1_TIME = B_ASN1_UTCTIME or B_ASN1_GENERALIZEDTIME; + B_ASN1_PRINTABLE = B_ASN1_NUMERICSTRING or B_ASN1_PRINTABLESTRING or B_ASN1_T61STRING or B_ASN1_IA5STRING or B_ASN1_BIT_STRING or B_ASN1_UNIVERSALSTRING or B_ASN1_BMPSTRING or B_ASN1_UTF8STRING or B_ASN1_SEQUENCE or B_ASN1_UNKNOWN; + B_ASN1_DIRECTORYSTRING = B_ASN1_PRINTABLESTRING or B_ASN1_TELETEXSTRING or B_ASN1_BMPSTRING or B_ASN1_UNIVERSALSTRING or B_ASN1_UTF8STRING; + B_ASN1_DISPLAYTEXT = B_ASN1_IA5STRING or B_ASN1_VISIBLESTRING or B_ASN1_BMPSTRING or B_ASN1_UTF8STRING; + ASN1_PCTX_FLAGS_SHOW_ABSENT = $001; + ASN1_PCTX_FLAGS_SHOW_SEQUENCE = $002; + ASN1_PCTX_FLAGS_SHOW_SSOF = $004; + ASN1_PCTX_FLAGS_SHOW_TYPE = $008; + ASN1_PCTX_FLAGS_NO_ANY_TYPE = $010; + ASN1_PCTX_FLAGS_NO_MSTRING_TYPE = $020; + ASN1_PCTX_FLAGS_NO_FIELD_NAME = $040; + ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME = $080; + ASN1_PCTX_FLAGS_NO_STRUCT_NAME = $100; + ASN1_TFLG_OPTIONAL = ($1); + ASN1_TFLG_SET_OF = ($1 shl 1); + ASN1_TFLG_SEQUENCE_OF = ($2 shl 1); + ASN1_TFLG_SET_ORDER = ($3 shl 1); + ASN1_TFLG_SK_MASK = ($3 shl 1); + ASN1_TFLG_IMPTAG = ($1 shl 3); + ASN1_TFLG_EXPTAG = ($2 shl 3); + ASN1_TFLG_TAG_MASK = ($3 shl 3); + ASN1_TFLG_CONTEXT = ($2 shl 6); + ASN1_TFLG_IMPLICIT = (ASN1_TFLG_IMPTAG or ASN1_TFLG_CONTEXT); + ASN1_TFLG_EXPLICIT = (ASN1_TFLG_EXPTAG or ASN1_TFLG_CONTEXT); + ASN1_TFLG_UNIVERSAL = ($0 shl 6); + ASN1_TFLG_APPLICATION = ($1 shl 6); + ASN1_TFLG_PRIVATE = ($3 shl 6); + ASN1_TFLG_TAG_CLASS = ($3 shl 6); + ASN1_TFLG_ADB_MASK = ($3 shl 8); + ASN1_TFLG_ADB_OID = ($1 shl 8); + ASN1_TFLG_ADB_INT = ($1 shl 9); + ASN1_TFLG_NDEF = ($1 shl 11); + ASN1_TFLG_EMBED = ($1 shl 12); + ASN1_ITYPE_PRIMITIVE = $0; + ASN1_ITYPE_SEQUENCE = $1; + ASN1_ITYPE_CHOICE = $2; + ASN1_ITYPE_EXTERN = $4; + ASN1_ITYPE_MSTRING = $5; + ASN1_ITYPE_NDEF_SEQUENCE = $6; + ASN1_AFLG_REFCOUNT = 1; + ASN1_AFLG_ENCODING = 2; + ASN1_AFLG_BROKEN = 4; + ASN1_OP_NEW_PRE = 0; + ASN1_OP_NEW_POST = 1; + ASN1_OP_FREE_PRE = 2; + ASN1_OP_FREE_POST = 3; + ASN1_OP_D2I_PRE = 4; + ASN1_OP_D2I_POST = 5; + ASN1_OP_I2D_PRE = 6; + ASN1_OP_I2D_POST = 7; + ASN1_OP_PRINT_PRE = 8; + ASN1_OP_PRINT_POST = 9; + ASN1_OP_STREAM_PRE = 10; + ASN1_OP_STREAM_POST = 11; + ASN1_OP_DETACHED_PRE = 12; + ASN1_OP_DETACHED_POST = 13; + ASYNC_F_ASYNC_CTX_NEW = 100; + ASYNC_F_ASYNC_INIT_THREAD = 101; + ASYNC_F_ASYNC_JOB_NEW = 102; + ASYNC_F_ASYNC_PAUSE_JOB = 103; + ASYNC_F_ASYNC_START_FUNC = 104; + ASYNC_F_ASYNC_START_JOB = 105; + ASYNC_F_ASYNC_WAIT_CTX_SET_WAIT_FD = 106; + ASYNC_R_FAILED_TO_SET_POOL = 101; + ASYNC_R_FAILED_TO_SWAP_CONTEXT = 102; + ASYNC_R_INIT_FAILED = 105; + ASYNC_R_INVALID_POOL_SIZE = 103; + ASYNC_ERR = 0; + ASYNC_NO_JOBS = 1; + ASYNC_PAUSE = 2; + ASYNC_FINISH = 3; + _BF_ENCRYPT = 1; + _BF_DECRYPT = 0; + BF_ROUNDS = 16; + BF_BLOCK = 8; + BUF_F_BUF_MEM_GROW = 100; + BUF_F_BUF_MEM_GROW_CLEAN = 105; + BUF_F_BUF_MEM_NEW = 101; + BUF_MEM_FLAG_SECURE = $01; + _CAMELLIA_ENCRYPT = 1; + _CAMELLIA_DECRYPT = 0; + CAMELLIA_BLOCK_SIZE = 16; + CAMELLIA_TABLE_BYTE_LEN = 272; + CAMELLIA_TABLE_WORD_LEN = (CAMELLIA_TABLE_BYTE_LEN div 4); + _CAST_ENCRYPT = 1; + _CAST_DECRYPT = 0; + CAST_BLOCK = 8; + CAST_KEY_LENGTH = 16; + EVP_F_AESNI_INIT_KEY = 165; + EVP_F_AESNI_XTS_INIT_KEY = 207; + EVP_F_AES_GCM_CTRL = 196; + EVP_F_AES_INIT_KEY = 133; + EVP_F_AES_OCB_CIPHER = 169; + EVP_F_AES_T4_INIT_KEY = 178; + EVP_F_AES_T4_XTS_INIT_KEY = 208; + EVP_F_AES_WRAP_CIPHER = 170; + EVP_F_AES_XTS_INIT_KEY = 209; + EVP_F_ALG_MODULE_INIT = 177; + EVP_F_ARIA_CCM_INIT_KEY = 175; + EVP_F_ARIA_GCM_CTRL = 197; + EVP_F_ARIA_GCM_INIT_KEY = 176; + EVP_F_ARIA_INIT_KEY = 185; + EVP_F_B64_NEW = 198; + EVP_F_CAMELLIA_INIT_KEY = 159; + EVP_F_CHACHA20_POLY1305_CTRL = 182; + EVP_F_CMLL_T4_INIT_KEY = 179; + EVP_F_DES_EDE3_WRAP_CIPHER = 171; + EVP_F_DO_SIGVER_INIT = 161; + EVP_F_ENC_NEW = 199; + EVP_F_EVP_CIPHERINIT_EX = 123; + EVP_F_EVP_CIPHER_ASN1_TO_PARAM = 204; + EVP_F_EVP_CIPHER_CTX_COPY = 163; + EVP_F_EVP_CIPHER_CTX_CTRL = 124; + EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH = 122; + EVP_F_EVP_CIPHER_PARAM_TO_ASN1 = 205; + EVP_F_EVP_DECRYPTFINAL_EX = 101; + EVP_F_EVP_DECRYPTUPDATE = 166; + EVP_F_EVP_DIGESTFINALXOF = 174; + EVP_F_EVP_DIGESTINIT_EX = 128; + EVP_F_EVP_ENCRYPTDECRYPTUPDATE = 219; + EVP_F_EVP_ENCRYPTFINAL_EX = 127; + EVP_F_EVP_ENCRYPTUPDATE = 167; + EVP_F_EVP_MD_CTX_COPY_EX = 110; + EVP_F_EVP_MD_SIZE = 162; + EVP_F_EVP_OPENINIT = 102; + EVP_F_EVP_PBE_ALG_ADD = 115; + EVP_F_EVP_PBE_ALG_ADD_TYPE = 160; + EVP_F_EVP_PBE_CIPHERINIT = 116; + EVP_F_EVP_PBE_SCRYPT = 181; + EVP_F_EVP_PKCS82PKEY = 111; + EVP_F_EVP_PKEY2PKCS8 = 113; + EVP_F_EVP_PKEY_ASN1_ADD0 = 188; + EVP_F_EVP_PKEY_CHECK = 186; + EVP_F_EVP_PKEY_COPY_PARAMETERS = 103; + EVP_F_EVP_PKEY_CTX_CTRL = 137; + EVP_F_EVP_PKEY_CTX_CTRL_STR = 150; + EVP_F_EVP_PKEY_CTX_DUP = 156; + EVP_F_EVP_PKEY_CTX_MD = 168; + EVP_F_EVP_PKEY_DECRYPT = 104; + EVP_F_EVP_PKEY_DECRYPT_INIT = 138; + EVP_F_EVP_PKEY_DECRYPT_OLD = 151; + EVP_F_EVP_PKEY_DERIVE = 153; + EVP_F_EVP_PKEY_DERIVE_INIT = 154; + EVP_F_EVP_PKEY_DERIVE_SET_PEER = 155; + EVP_F_EVP_PKEY_ENCRYPT = 105; + EVP_F_EVP_PKEY_ENCRYPT_INIT = 139; + EVP_F_EVP_PKEY_ENCRYPT_OLD = 152; + EVP_F_EVP_PKEY_GET0_DH = 119; + EVP_F_EVP_PKEY_GET0_DSA = 120; + EVP_F_EVP_PKEY_GET0_EC_KEY = 131; + EVP_F_EVP_PKEY_GET0_HMAC = 183; + EVP_F_EVP_PKEY_GET0_POLY1305 = 184; + EVP_F_EVP_PKEY_GET0_RSA = 121; + EVP_F_EVP_PKEY_GET0_SIPHASH = 172; + EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY = 202; + EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY = 203; + EVP_F_EVP_PKEY_KEYGEN = 146; + EVP_F_EVP_PKEY_KEYGEN_INIT = 147; + EVP_F_EVP_PKEY_METH_ADD0 = 194; + EVP_F_EVP_PKEY_METH_NEW = 195; + EVP_F_EVP_PKEY_NEW = 106; + EVP_F_EVP_PKEY_NEW_CMAC_KEY = 193; + EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY = 191; + EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY = 192; + EVP_F_EVP_PKEY_PARAMGEN = 148; + EVP_F_EVP_PKEY_PARAMGEN_INIT = 149; + EVP_F_EVP_PKEY_PARAM_CHECK = 189; + EVP_F_EVP_PKEY_PUBLIC_CHECK = 190; + EVP_F_EVP_PKEY_SET1_ENGINE = 187; + EVP_F_EVP_PKEY_SET_ALIAS_TYPE = 206; + EVP_F_EVP_PKEY_SIGN = 140; + EVP_F_EVP_PKEY_SIGN_INIT = 141; + EVP_F_EVP_PKEY_VERIFY = 142; + EVP_F_EVP_PKEY_VERIFY_INIT = 143; + EVP_F_EVP_PKEY_VERIFY_RECOVER = 144; + EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT = 145; + EVP_F_EVP_SIGNFINAL = 107; + EVP_F_EVP_VERIFYFINAL = 108; + EVP_F_INT_CTX_NEW = 157; + EVP_F_OK_NEW = 200; + EVP_F_PKCS5_PBE_KEYIVGEN = 117; + EVP_F_PKCS5_V2_PBE_KEYIVGEN = 118; + EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN = 164; + EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN = 180; + EVP_F_PKEY_SET_TYPE = 158; + EVP_F_RC2_MAGIC_TO_METH = 109; + EVP_F_RC5_CTRL = 125; + EVP_F_R_32_12_16_INIT_KEY = 242; + EVP_F_S390X_AES_GCM_CTRL = 201; + EVP_F_UPDATE = 173; + EVP_R_AES_KEY_SETUP_FAILED = 143; + EVP_R_ARIA_KEY_SETUP_FAILED = 176; + EVP_R_BAD_DECRYPT = 100; + EVP_R_BAD_KEY_LENGTH = 195; + EVP_R_BUFFER_TOO_SMALL = 155; + EVP_R_CAMELLIA_KEY_SETUP_FAILED = 157; + EVP_R_CIPHER_PARAMETER_ERROR = 122; + EVP_R_COMMAND_NOT_SUPPORTED = 147; + EVP_R_COPY_ERROR = 173; + EVP_R_CTRL_NOT_IMPLEMENTED = 132; + EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED = 133; + EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH = 138; + EVP_R_DECODE_ERROR = 114; + EVP_R_DIFFERENT_KEY_TYPES = 101; + EVP_R_DIFFERENT_PARAMETERS = 153; + EVP_R_ERROR_LOADING_SECTION = 165; + EVP_R_ERROR_SETTING_FIPS_MODE = 166; + EVP_R_EXPECTING_AN_HMAC_KEY = 174; + EVP_R_EXPECTING_AN_RSA_KEY = 127; + EVP_R_EXPECTING_A_DH_KEY = 128; + EVP_R_EXPECTING_A_DSA_KEY = 129; + EVP_R_EXPECTING_A_EC_KEY = 142; + EVP_R_EXPECTING_A_POLY1305_KEY = 164; + EVP_R_EXPECTING_A_SIPHASH_KEY = 175; + EVP_R_FIPS_MODE_NOT_SUPPORTED = 167; + EVP_R_GET_RAW_KEY_FAILED = 182; + EVP_R_ILLEGAL_SCRYPT_PARAMETERS = 171; + EVP_R_INITIALIZATION_ERROR = 134; + EVP_R_INPUT_NOT_INITIALIZED = 111; + EVP_R_INVALID_DIGEST = 152; + EVP_R_INVALID_FIPS_MODE = 168; + EVP_R_INVALID_IV_LENGTH = 194; + EVP_R_INVALID_KEY = 163; + EVP_R_INVALID_KEY_LENGTH = 130; + EVP_R_INVALID_OPERATION = 148; + EVP_R_KEYGEN_FAILURE = 120; + EVP_R_KEY_SETUP_FAILED = 180; + EVP_R_MEMORY_LIMIT_EXCEEDED = 172; + EVP_R_MESSAGE_DIGEST_IS_NULL = 159; + EVP_R_METHOD_NOT_SUPPORTED = 144; + EVP_R_MISSING_PARAMETERS = 103; + EVP_R_NOT_XOF_OR_INVALID_LENGTH = 178; + EVP_R_NO_CIPHER_SET = 131; + EVP_R_NO_DEFAULT_DIGEST = 158; + EVP_R_NO_DIGEST_SET = 139; + EVP_R_NO_KEY_SET = 154; + EVP_R_NO_OPERATION_SET = 149; + EVP_R_ONLY_ONESHOT_SUPPORTED = 177; + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE = 150; + EVP_R_OPERATON_NOT_INITIALIZED = 151; + EVP_R_PARTIALLY_OVERLAPPING = 162; + EVP_R_PBKDF2_ERROR = 181; + EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED = 179; + EVP_R_PRIVATE_KEY_DECODE_ERROR = 145; + EVP_R_PRIVATE_KEY_ENCODE_ERROR = 146; + EVP_R_PUBLIC_KEY_NOT_RSA = 106; + EVP_R_UNKNOWN_CIPHER = 160; + EVP_R_UNKNOWN_DIGEST = 161; + EVP_R_UNKNOWN_OPTION = 169; + EVP_R_UNKNOWN_PBE_ALGORITHM = 121; + EVP_R_UNSUPPORTED_ALGORITHM = 156; + EVP_R_UNSUPPORTED_CIPHER = 107; + EVP_R_UNSUPPORTED_KEYLENGTH = 123; + EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION = 124; + EVP_R_UNSUPPORTED_KEY_SIZE = 108; + EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS = 135; + EVP_R_UNSUPPORTED_PRF = 125; + EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM = 118; + EVP_R_UNSUPPORTED_SALT_TYPE = 126; + EVP_R_WRAP_MODE_NOT_ALLOWED = 170; + EVP_R_WRONG_FINAL_BLOCK_LENGTH = 109; + EVP_R_XTS_DUPLICATED_KEYS = 183; + EVP_MAX_MD_SIZE = 64; + EVP_MAX_KEY_LENGTH = 64; + EVP_MAX_IV_LENGTH = 16; + EVP_MAX_BLOCK_LENGTH = 32; + PKCS5_SALT_LEN = 8; + PKCS5_DEFAULT_ITER = 2048; + SN_undef = 'UNDEF'; + LN_undef = 'undefined'; + NID_undef = 0; + OBJ_undef = 0; + SN_itu_t = 'ITU-T'; + LN_itu_t = 'itu-t'; + NID_itu_t = 645; + OBJ_itu_t = 0; + NID_ccitt = 404; + OBJ_ccitt = OBJ_itu_t; + SN_iso = 'ISO'; + LN_iso = 'iso'; + NID_iso = 181; + OBJ_iso = 1; + SN_joint_iso_itu_t = 'JOINT-ISO-ITU-T'; + LN_joint_iso_itu_t = 'joint-iso-itu-t'; + NID_joint_iso_itu_t = 646; + OBJ_joint_iso_itu_t = 2; + NID_joint_iso_ccitt = 393; + OBJ_joint_iso_ccitt = OBJ_joint_iso_itu_t; + SN_member_body = 'member-body'; + LN_member_body = 'ISO Member Body'; + NID_member_body = 182; + SN_identified_organization = 'identified-organization'; + NID_identified_organization = 676; + SN_hmac_md5 = 'HMAC-MD5'; + LN_hmac_md5 = 'hmac-md5'; + NID_hmac_md5 = 780; + SN_hmac_sha1 = 'HMAC-SHA1'; + LN_hmac_sha1 = 'hmac-sha1'; + NID_hmac_sha1 = 781; + SN_x509ExtAdmission = 'x509ExtAdmission'; + LN_x509ExtAdmission = 'Professional Information or basis for Admission'; + NID_x509ExtAdmission = 1093; + SN_certicom_arc = 'certicom-arc'; + NID_certicom_arc = 677; + SN_ieee = 'ieee'; + NID_ieee = 1170; + SN_ieee_siswg = 'ieee-siswg'; + LN_ieee_siswg = 'IEEE Security in Storage Working Group'; + NID_ieee_siswg = 1171; + SN_international_organizations = 'international-organizations'; + LN_international_organizations = 'International Organizations'; + NID_international_organizations = 647; + SN_wap = 'wap'; + NID_wap = 678; + SN_wap_wsg = 'wap-wsg'; + NID_wap_wsg = 679; + SN_selected_attribute_types = 'selected-attribute-types'; + LN_selected_attribute_types = 'Selected Attribute Types'; + NID_selected_attribute_types = 394; + SN_clearance = 'clearance'; + NID_clearance = 395; + SN_ISO_US = 'ISO-US'; + LN_ISO_US = 'ISO US Member Body'; + NID_ISO_US = 183; + SN_X9_57 = 'X9-57'; + LN_X9_57 = 'X9.57'; + NID_X9_57 = 184; + SN_X9cm = 'X9cm'; + LN_X9cm = 'X9.57 CM ?'; + NID_X9cm = 185; + SN_ISO_CN = 'ISO-CN'; + LN_ISO_CN = 'ISO CN Member Body'; + NID_ISO_CN = 1140; + SN_oscca = 'oscca'; + NID_oscca = 1141; + SN_sm_scheme = 'sm-scheme'; + NID_sm_scheme = 1142; + SN_dsa = 'DSA'; + LN_dsa = 'dsaEncryption'; + NID_dsa = 116; + SN_dsaWithSHA1 = 'DSA-SHA1'; + LN_dsaWithSHA1 = 'dsaWithSHA1'; + NID_dsaWithSHA1 = 113; + SN_ansi_X9_62 = 'ansi-X9-62'; + LN_ansi_X9_62 = 'ANSI X9.62'; + NID_ansi_X9_62 = 405; + SN_X9_62_prime_field = 'prime-field'; + NID_X9_62_prime_field = 406; + SN_X9_62_characteristic_two_field = 'characteristic-two-field'; + NID_X9_62_characteristic_two_field = 407; + SN_X9_62_id_characteristic_two_basis = 'id-characteristic-two-basis'; + NID_X9_62_id_characteristic_two_basis = 680; + SN_X9_62_onBasis = 'onBasis'; + NID_X9_62_onBasis = 681; + SN_X9_62_tpBasis = 'tpBasis'; + NID_X9_62_tpBasis = 682; + SN_X9_62_ppBasis = 'ppBasis'; + NID_X9_62_ppBasis = 683; + SN_X9_62_id_ecPublicKey = 'id-ecPublicKey'; + NID_X9_62_id_ecPublicKey = 408; + SN_X9_62_c2pnb163v1 = 'c2pnb163v1'; + NID_X9_62_c2pnb163v1 = 684; + SN_X9_62_c2pnb163v2 = 'c2pnb163v2'; + NID_X9_62_c2pnb163v2 = 685; + SN_X9_62_c2pnb163v3 = 'c2pnb163v3'; + NID_X9_62_c2pnb163v3 = 686; + SN_X9_62_c2pnb176v1 = 'c2pnb176v1'; + NID_X9_62_c2pnb176v1 = 687; + SN_X9_62_c2tnb191v1 = 'c2tnb191v1'; + NID_X9_62_c2tnb191v1 = 688; + SN_X9_62_c2tnb191v2 = 'c2tnb191v2'; + NID_X9_62_c2tnb191v2 = 689; + SN_X9_62_c2tnb191v3 = 'c2tnb191v3'; + NID_X9_62_c2tnb191v3 = 690; + SN_X9_62_c2onb191v4 = 'c2onb191v4'; + NID_X9_62_c2onb191v4 = 691; + SN_X9_62_c2onb191v5 = 'c2onb191v5'; + NID_X9_62_c2onb191v5 = 692; + SN_X9_62_c2pnb208w1 = 'c2pnb208w1'; + NID_X9_62_c2pnb208w1 = 693; + SN_X9_62_c2tnb239v1 = 'c2tnb239v1'; + NID_X9_62_c2tnb239v1 = 694; + SN_X9_62_c2tnb239v2 = 'c2tnb239v2'; + NID_X9_62_c2tnb239v2 = 695; + SN_X9_62_c2tnb239v3 = 'c2tnb239v3'; + NID_X9_62_c2tnb239v3 = 696; + SN_X9_62_c2onb239v4 = 'c2onb239v4'; + NID_X9_62_c2onb239v4 = 697; + SN_X9_62_c2onb239v5 = 'c2onb239v5'; + NID_X9_62_c2onb239v5 = 698; + SN_X9_62_c2pnb272w1 = 'c2pnb272w1'; + NID_X9_62_c2pnb272w1 = 699; + SN_X9_62_c2pnb304w1 = 'c2pnb304w1'; + NID_X9_62_c2pnb304w1 = 700; + SN_X9_62_c2tnb359v1 = 'c2tnb359v1'; + NID_X9_62_c2tnb359v1 = 701; + SN_X9_62_c2pnb368w1 = 'c2pnb368w1'; + NID_X9_62_c2pnb368w1 = 702; + SN_X9_62_c2tnb431r1 = 'c2tnb431r1'; + NID_X9_62_c2tnb431r1 = 703; + SN_X9_62_prime192v1 = 'prime192v1'; + NID_X9_62_prime192v1 = 409; + SN_X9_62_prime192v2 = 'prime192v2'; + NID_X9_62_prime192v2 = 410; + SN_X9_62_prime192v3 = 'prime192v3'; + NID_X9_62_prime192v3 = 411; + SN_X9_62_prime239v1 = 'prime239v1'; + NID_X9_62_prime239v1 = 412; + SN_X9_62_prime239v2 = 'prime239v2'; + NID_X9_62_prime239v2 = 413; + SN_X9_62_prime239v3 = 'prime239v3'; + NID_X9_62_prime239v3 = 414; + SN_X9_62_prime256v1 = 'prime256v1'; + NID_X9_62_prime256v1 = 415; + SN_ecdsa_with_SHA1 = 'ecdsa-with-SHA1'; + NID_ecdsa_with_SHA1 = 416; + SN_ecdsa_with_Recommended = 'ecdsa-with-Recommended'; + NID_ecdsa_with_Recommended = 791; + SN_ecdsa_with_Specified = 'ecdsa-with-Specified'; + NID_ecdsa_with_Specified = 792; + SN_ecdsa_with_SHA224 = 'ecdsa-with-SHA224'; + NID_ecdsa_with_SHA224 = 793; + SN_ecdsa_with_SHA256 = 'ecdsa-with-SHA256'; + NID_ecdsa_with_SHA256 = 794; + SN_ecdsa_with_SHA384 = 'ecdsa-with-SHA384'; + NID_ecdsa_with_SHA384 = 795; + SN_ecdsa_with_SHA512 = 'ecdsa-with-SHA512'; + NID_ecdsa_with_SHA512 = 796; + SN_secp112r1 = 'secp112r1'; + NID_secp112r1 = 704; + SN_secp112r2 = 'secp112r2'; + NID_secp112r2 = 705; + SN_secp128r1 = 'secp128r1'; + NID_secp128r1 = 706; + SN_secp128r2 = 'secp128r2'; + NID_secp128r2 = 707; + SN_secp160k1 = 'secp160k1'; + NID_secp160k1 = 708; + SN_secp160r1 = 'secp160r1'; + NID_secp160r1 = 709; + SN_secp160r2 = 'secp160r2'; + NID_secp160r2 = 710; + SN_secp192k1 = 'secp192k1'; + NID_secp192k1 = 711; + SN_secp224k1 = 'secp224k1'; + NID_secp224k1 = 712; + SN_secp224r1 = 'secp224r1'; + NID_secp224r1 = 713; + SN_secp256k1 = 'secp256k1'; + NID_secp256k1 = 714; + SN_secp384r1 = 'secp384r1'; + NID_secp384r1 = 715; + SN_secp521r1 = 'secp521r1'; + NID_secp521r1 = 716; + SN_sect113r1 = 'sect113r1'; + NID_sect113r1 = 717; + SN_sect113r2 = 'sect113r2'; + NID_sect113r2 = 718; + SN_sect131r1 = 'sect131r1'; + NID_sect131r1 = 719; + SN_sect131r2 = 'sect131r2'; + NID_sect131r2 = 720; + SN_sect163k1 = 'sect163k1'; + NID_sect163k1 = 721; + SN_sect163r1 = 'sect163r1'; + NID_sect163r1 = 722; + SN_sect163r2 = 'sect163r2'; + NID_sect163r2 = 723; + SN_sect193r1 = 'sect193r1'; + NID_sect193r1 = 724; + SN_sect193r2 = 'sect193r2'; + NID_sect193r2 = 725; + SN_sect233k1 = 'sect233k1'; + NID_sect233k1 = 726; + SN_sect233r1 = 'sect233r1'; + NID_sect233r1 = 727; + SN_sect239k1 = 'sect239k1'; + NID_sect239k1 = 728; + SN_sect283k1 = 'sect283k1'; + NID_sect283k1 = 729; + SN_sect283r1 = 'sect283r1'; + NID_sect283r1 = 730; + SN_sect409k1 = 'sect409k1'; + NID_sect409k1 = 731; + SN_sect409r1 = 'sect409r1'; + NID_sect409r1 = 732; + SN_sect571k1 = 'sect571k1'; + NID_sect571k1 = 733; + SN_sect571r1 = 'sect571r1'; + NID_sect571r1 = 734; + SN_wap_wsg_idm_ecid_wtls1 = 'wap-wsg-idm-ecid-wtls1'; + NID_wap_wsg_idm_ecid_wtls1 = 735; + SN_wap_wsg_idm_ecid_wtls3 = 'wap-wsg-idm-ecid-wtls3'; + NID_wap_wsg_idm_ecid_wtls3 = 736; + SN_wap_wsg_idm_ecid_wtls4 = 'wap-wsg-idm-ecid-wtls4'; + NID_wap_wsg_idm_ecid_wtls4 = 737; + SN_wap_wsg_idm_ecid_wtls5 = 'wap-wsg-idm-ecid-wtls5'; + NID_wap_wsg_idm_ecid_wtls5 = 738; + SN_wap_wsg_idm_ecid_wtls6 = 'wap-wsg-idm-ecid-wtls6'; + NID_wap_wsg_idm_ecid_wtls6 = 739; + SN_wap_wsg_idm_ecid_wtls7 = 'wap-wsg-idm-ecid-wtls7'; + NID_wap_wsg_idm_ecid_wtls7 = 740; + SN_wap_wsg_idm_ecid_wtls8 = 'wap-wsg-idm-ecid-wtls8'; + NID_wap_wsg_idm_ecid_wtls8 = 741; + SN_wap_wsg_idm_ecid_wtls9 = 'wap-wsg-idm-ecid-wtls9'; + NID_wap_wsg_idm_ecid_wtls9 = 742; + SN_wap_wsg_idm_ecid_wtls10 = 'wap-wsg-idm-ecid-wtls10'; + NID_wap_wsg_idm_ecid_wtls10 = 743; + SN_wap_wsg_idm_ecid_wtls11 = 'wap-wsg-idm-ecid-wtls11'; + NID_wap_wsg_idm_ecid_wtls11 = 744; + SN_wap_wsg_idm_ecid_wtls12 = 'wap-wsg-idm-ecid-wtls12'; + NID_wap_wsg_idm_ecid_wtls12 = 745; + SN_cast5_cbc = 'CAST5-CBC'; + LN_cast5_cbc = 'cast5-cbc'; + NID_cast5_cbc = 108; + SN_cast5_ecb = 'CAST5-ECB'; + LN_cast5_ecb = 'cast5-ecb'; + NID_cast5_ecb = 109; + SN_cast5_cfb64 = 'CAST5-CFB'; + LN_cast5_cfb64 = 'cast5-cfb'; + NID_cast5_cfb64 = 110; + SN_cast5_ofb64 = 'CAST5-OFB'; + LN_cast5_ofb64 = 'cast5-ofb'; + NID_cast5_ofb64 = 111; + LN_pbeWithMD5AndCast5_CBC = 'pbeWithMD5AndCast5CBC'; + NID_pbeWithMD5AndCast5_CBC = 112; + SN_id_PasswordBasedMAC = 'id-PasswordBasedMAC'; + LN_id_PasswordBasedMAC = 'password based MAC'; + NID_id_PasswordBasedMAC = 782; + SN_id_DHBasedMac = 'id-DHBasedMac'; + LN_id_DHBasedMac = 'Diffie-Hellman based MAC'; + NID_id_DHBasedMac = 783; + SN_rsadsi = 'rsadsi'; + LN_rsadsi = 'RSA Data Security, Inc.'; + NID_rsadsi = 1; + SN_pkcs = 'pkcs'; + LN_pkcs = 'RSA Data Security, Inc. PKCS'; + NID_pkcs = 2; + SN_pkcs1 = 'pkcs1'; + NID_pkcs1 = 186; + LN_rsaEncryption = 'rsaEncryption'; + NID_rsaEncryption = 6; + SN_md2WithRSAEncryption = 'RSA-MD2'; + LN_md2WithRSAEncryption = 'md2WithRSAEncryption'; + NID_md2WithRSAEncryption = 7; + SN_md4WithRSAEncryption = 'RSA-MD4'; + LN_md4WithRSAEncryption = 'md4WithRSAEncryption'; + NID_md4WithRSAEncryption = 396; + SN_md5WithRSAEncryption = 'RSA-MD5'; + LN_md5WithRSAEncryption = 'md5WithRSAEncryption'; + NID_md5WithRSAEncryption = 8; + SN_sha1WithRSAEncryption = 'RSA-SHA1'; + LN_sha1WithRSAEncryption = 'sha1WithRSAEncryption'; + NID_sha1WithRSAEncryption = 65; + SN_rsaesOaep = 'RSAES-OAEP'; + LN_rsaesOaep = 'rsaesOaep'; + NID_rsaesOaep = 919; + SN_mgf1 = 'MGF1'; + LN_mgf1 = 'mgf1'; + NID_mgf1 = 911; + SN_pSpecified = 'PSPECIFIED'; + LN_pSpecified = 'pSpecified'; + NID_pSpecified = 935; + SN_rsassaPss = 'RSASSA-PSS'; + LN_rsassaPss = 'rsassaPss'; + NID_rsassaPss = 912; + SN_sha256WithRSAEncryption = 'RSA-SHA256'; + LN_sha256WithRSAEncryption = 'sha256WithRSAEncryption'; + NID_sha256WithRSAEncryption = 668; + SN_sha384WithRSAEncryption = 'RSA-SHA384'; + LN_sha384WithRSAEncryption = 'sha384WithRSAEncryption'; + NID_sha384WithRSAEncryption = 669; + SN_sha512WithRSAEncryption = 'RSA-SHA512'; + LN_sha512WithRSAEncryption = 'sha512WithRSAEncryption'; + NID_sha512WithRSAEncryption = 670; + SN_sha224WithRSAEncryption = 'RSA-SHA224'; + LN_sha224WithRSAEncryption = 'sha224WithRSAEncryption'; + NID_sha224WithRSAEncryption = 671; + SN_sha512_224WithRSAEncryption = 'RSA-SHA512/224'; + LN_sha512_224WithRSAEncryption = 'sha512-224WithRSAEncryption'; + NID_sha512_224WithRSAEncryption = 1145; + SN_sha512_256WithRSAEncryption = 'RSA-SHA512/256'; + LN_sha512_256WithRSAEncryption = 'sha512-256WithRSAEncryption'; + NID_sha512_256WithRSAEncryption = 1146; + SN_pkcs3 = 'pkcs3'; + NID_pkcs3 = 27; + LN_dhKeyAgreement = 'dhKeyAgreement'; + NID_dhKeyAgreement = 28; + SN_pkcs5 = 'pkcs5'; + NID_pkcs5 = 187; + SN_pbeWithMD2AndDES_CBC = 'PBE-MD2-DES'; + LN_pbeWithMD2AndDES_CBC = 'pbeWithMD2AndDES-CBC'; + NID_pbeWithMD2AndDES_CBC = 9; + SN_pbeWithMD5AndDES_CBC = 'PBE-MD5-DES'; + LN_pbeWithMD5AndDES_CBC = 'pbeWithMD5AndDES-CBC'; + NID_pbeWithMD5AndDES_CBC = 10; + SN_pbeWithMD2AndRC2_CBC = 'PBE-MD2-RC2-64'; + LN_pbeWithMD2AndRC2_CBC = 'pbeWithMD2AndRC2-CBC'; + NID_pbeWithMD2AndRC2_CBC = 168; + SN_pbeWithMD5AndRC2_CBC = 'PBE-MD5-RC2-64'; + LN_pbeWithMD5AndRC2_CBC = 'pbeWithMD5AndRC2-CBC'; + NID_pbeWithMD5AndRC2_CBC = 169; + SN_pbeWithSHA1AndDES_CBC = 'PBE-SHA1-DES'; + LN_pbeWithSHA1AndDES_CBC = 'pbeWithSHA1AndDES-CBC'; + NID_pbeWithSHA1AndDES_CBC = 170; + SN_pbeWithSHA1AndRC2_CBC = 'PBE-SHA1-RC2-64'; + LN_pbeWithSHA1AndRC2_CBC = 'pbeWithSHA1AndRC2-CBC'; + NID_pbeWithSHA1AndRC2_CBC = 68; + LN_id_pbkdf2 = 'PBKDF2'; + NID_id_pbkdf2 = 69; + LN_pbes2 = 'PBES2'; + NID_pbes2 = 161; + LN_pbmac1 = 'PBMAC1'; + NID_pbmac1 = 162; + SN_pkcs7 = 'pkcs7'; + NID_pkcs7 = 20; + LN_pkcs7_data = 'pkcs7-data'; + NID_pkcs7_data = 21; + LN_pkcs7_signed = 'pkcs7-signedData'; + NID_pkcs7_signed = 22; + LN_pkcs7_enveloped = 'pkcs7-envelopedData'; + NID_pkcs7_enveloped = 23; + LN_pkcs7_signedAndEnveloped = 'pkcs7-signedAndEnvelopedData'; + NID_pkcs7_signedAndEnveloped = 24; + LN_pkcs7_digest = 'pkcs7-digestData'; + NID_pkcs7_digest = 25; + LN_pkcs7_encrypted = 'pkcs7-encryptedData'; + NID_pkcs7_encrypted = 26; + SN_pkcs9 = 'pkcs9'; + NID_pkcs9 = 47; + LN_pkcs9_emailAddress = 'emailAddress'; + NID_pkcs9_emailAddress = 48; + LN_pkcs9_unstructuredName = 'unstructuredName'; + NID_pkcs9_unstructuredName = 49; + LN_pkcs9_contentType = 'contentType'; + NID_pkcs9_contentType = 50; + LN_pkcs9_messageDigest = 'messageDigest'; + NID_pkcs9_messageDigest = 51; + LN_pkcs9_signingTime = 'signingTime'; + NID_pkcs9_signingTime = 52; + LN_pkcs9_countersignature = 'countersignature'; + NID_pkcs9_countersignature = 53; + LN_pkcs9_challengePassword = 'challengePassword'; + NID_pkcs9_challengePassword = 54; + LN_pkcs9_unstructuredAddress = 'unstructuredAddress'; + NID_pkcs9_unstructuredAddress = 55; + LN_pkcs9_extCertAttributes = 'extendedCertificateAttributes'; + NID_pkcs9_extCertAttributes = 56; + SN_ext_req = 'extReq'; + LN_ext_req = 'Extension Request'; + NID_ext_req = 172; + SN_SMIMECapabilities = 'SMIME-CAPS'; + LN_SMIMECapabilities = 'S/MIME Capabilities'; + NID_SMIMECapabilities = 167; + SN_SMIME = 'SMIME'; + LN_SMIME = 'S/MIME'; + NID_SMIME = 188; + SN_id_smime_mod = 'id-smime-mod'; + NID_id_smime_mod = 189; + SN_id_smime_ct = 'id-smime-ct'; + NID_id_smime_ct = 190; + SN_id_smime_aa = 'id-smime-aa'; + NID_id_smime_aa = 191; + SN_id_smime_alg = 'id-smime-alg'; + NID_id_smime_alg = 192; + SN_id_smime_cd = 'id-smime-cd'; + NID_id_smime_cd = 193; + SN_id_smime_spq = 'id-smime-spq'; + NID_id_smime_spq = 194; + SN_id_smime_cti = 'id-smime-cti'; + NID_id_smime_cti = 195; + SN_id_smime_mod_cms = 'id-smime-mod-cms'; + NID_id_smime_mod_cms = 196; + SN_id_smime_mod_ess = 'id-smime-mod-ess'; + NID_id_smime_mod_ess = 197; + SN_id_smime_mod_oid = 'id-smime-mod-oid'; + NID_id_smime_mod_oid = 198; + SN_id_smime_mod_msg_v3 = 'id-smime-mod-msg-v3'; + NID_id_smime_mod_msg_v3 = 199; + SN_id_smime_mod_ets_eSignature_88 = 'id-smime-mod-ets-eSignature-88'; + NID_id_smime_mod_ets_eSignature_88 = 200; + SN_id_smime_mod_ets_eSignature_97 = 'id-smime-mod-ets-eSignature-97'; + NID_id_smime_mod_ets_eSignature_97 = 201; + SN_id_smime_mod_ets_eSigPolicy_88 = 'id-smime-mod-ets-eSigPolicy-88'; + NID_id_smime_mod_ets_eSigPolicy_88 = 202; + SN_id_smime_mod_ets_eSigPolicy_97 = 'id-smime-mod-ets-eSigPolicy-97'; + NID_id_smime_mod_ets_eSigPolicy_97 = 203; + SN_id_smime_ct_receipt = 'id-smime-ct-receipt'; + NID_id_smime_ct_receipt = 204; + SN_id_smime_ct_authData = 'id-smime-ct-authData'; + NID_id_smime_ct_authData = 205; + SN_id_smime_ct_publishCert = 'id-smime-ct-publishCert'; + NID_id_smime_ct_publishCert = 206; + SN_id_smime_ct_TSTInfo = 'id-smime-ct-TSTInfo'; + NID_id_smime_ct_TSTInfo = 207; + SN_id_smime_ct_TDTInfo = 'id-smime-ct-TDTInfo'; + NID_id_smime_ct_TDTInfo = 208; + SN_id_smime_ct_contentInfo = 'id-smime-ct-contentInfo'; + NID_id_smime_ct_contentInfo = 209; + SN_id_smime_ct_DVCSRequestData = 'id-smime-ct-DVCSRequestData'; + NID_id_smime_ct_DVCSRequestData = 210; + SN_id_smime_ct_DVCSResponseData = 'id-smime-ct-DVCSResponseData'; + NID_id_smime_ct_DVCSResponseData = 211; + SN_id_smime_ct_compressedData = 'id-smime-ct-compressedData'; + NID_id_smime_ct_compressedData = 786; + SN_id_smime_ct_contentCollection = 'id-smime-ct-contentCollection'; + NID_id_smime_ct_contentCollection = 1058; + SN_id_smime_ct_authEnvelopedData = 'id-smime-ct-authEnvelopedData'; + NID_id_smime_ct_authEnvelopedData = 1059; + SN_id_ct_asciiTextWithCRLF = 'id-ct-asciiTextWithCRLF'; + NID_id_ct_asciiTextWithCRLF = 787; + SN_id_ct_xml = 'id-ct-xml'; + NID_id_ct_xml = 1060; + SN_id_smime_aa_receiptRequest = 'id-smime-aa-receiptRequest'; + NID_id_smime_aa_receiptRequest = 212; + SN_id_smime_aa_securityLabel = 'id-smime-aa-securityLabel'; + NID_id_smime_aa_securityLabel = 213; + SN_id_smime_aa_mlExpandHistory = 'id-smime-aa-mlExpandHistory'; + NID_id_smime_aa_mlExpandHistory = 214; + SN_id_smime_aa_contentHint = 'id-smime-aa-contentHint'; + NID_id_smime_aa_contentHint = 215; + SN_id_smime_aa_msgSigDigest = 'id-smime-aa-msgSigDigest'; + NID_id_smime_aa_msgSigDigest = 216; + SN_id_smime_aa_encapContentType = 'id-smime-aa-encapContentType'; + NID_id_smime_aa_encapContentType = 217; + SN_id_smime_aa_contentIdentifier = 'id-smime-aa-contentIdentifier'; + NID_id_smime_aa_contentIdentifier = 218; + SN_id_smime_aa_macValue = 'id-smime-aa-macValue'; + NID_id_smime_aa_macValue = 219; + SN_id_smime_aa_equivalentLabels = 'id-smime-aa-equivalentLabels'; + NID_id_smime_aa_equivalentLabels = 220; + SN_id_smime_aa_contentReference = 'id-smime-aa-contentReference'; + NID_id_smime_aa_contentReference = 221; + SN_id_smime_aa_encrypKeyPref = 'id-smime-aa-encrypKeyPref'; + NID_id_smime_aa_encrypKeyPref = 222; + SN_id_smime_aa_signingCertificate = 'id-smime-aa-signingCertificate'; + NID_id_smime_aa_signingCertificate = 223; + SN_id_smime_aa_smimeEncryptCerts = 'id-smime-aa-smimeEncryptCerts'; + NID_id_smime_aa_smimeEncryptCerts = 224; + SN_id_smime_aa_timeStampToken = 'id-smime-aa-timeStampToken'; + NID_id_smime_aa_timeStampToken = 225; + SN_id_smime_aa_ets_sigPolicyId = 'id-smime-aa-ets-sigPolicyId'; + NID_id_smime_aa_ets_sigPolicyId = 226; + SN_id_smime_aa_ets_commitmentType = 'id-smime-aa-ets-commitmentType'; + NID_id_smime_aa_ets_commitmentType = 227; + SN_id_smime_aa_ets_signerLocation = 'id-smime-aa-ets-signerLocation'; + NID_id_smime_aa_ets_signerLocation = 228; + SN_id_smime_aa_ets_signerAttr = 'id-smime-aa-ets-signerAttr'; + NID_id_smime_aa_ets_signerAttr = 229; + SN_id_smime_aa_ets_otherSigCert = 'id-smime-aa-ets-otherSigCert'; + NID_id_smime_aa_ets_otherSigCert = 230; + SN_id_smime_aa_ets_contentTimestamp = 'id-smime-aa-ets-contentTimestamp'; + NID_id_smime_aa_ets_contentTimestamp = 231; + SN_id_smime_aa_ets_CertificateRefs = 'id-smime-aa-ets-CertificateRefs'; + NID_id_smime_aa_ets_CertificateRefs = 232; + SN_id_smime_aa_ets_RevocationRefs = 'id-smime-aa-ets-RevocationRefs'; + NID_id_smime_aa_ets_RevocationRefs = 233; + SN_id_smime_aa_ets_certValues = 'id-smime-aa-ets-certValues'; + NID_id_smime_aa_ets_certValues = 234; + SN_id_smime_aa_ets_revocationValues = 'id-smime-aa-ets-revocationValues'; + NID_id_smime_aa_ets_revocationValues = 235; + SN_id_smime_aa_ets_escTimeStamp = 'id-smime-aa-ets-escTimeStamp'; + NID_id_smime_aa_ets_escTimeStamp = 236; + SN_id_smime_aa_ets_certCRLTimestamp = 'id-smime-aa-ets-certCRLTimestamp'; + NID_id_smime_aa_ets_certCRLTimestamp = 237; + SN_id_smime_aa_ets_archiveTimeStamp = 'id-smime-aa-ets-archiveTimeStamp'; + NID_id_smime_aa_ets_archiveTimeStamp = 238; + SN_id_smime_aa_signatureType = 'id-smime-aa-signatureType'; + NID_id_smime_aa_signatureType = 239; + SN_id_smime_aa_dvcs_dvc = 'id-smime-aa-dvcs-dvc'; + NID_id_smime_aa_dvcs_dvc = 240; + SN_id_smime_aa_signingCertificateV2 = 'id-smime-aa-signingCertificateV2'; + NID_id_smime_aa_signingCertificateV2 = 1086; + SN_id_smime_alg_ESDHwith3DES = 'id-smime-alg-ESDHwith3DES'; + NID_id_smime_alg_ESDHwith3DES = 241; + SN_id_smime_alg_ESDHwithRC2 = 'id-smime-alg-ESDHwithRC2'; + NID_id_smime_alg_ESDHwithRC2 = 242; + SN_id_smime_alg_3DESwrap = 'id-smime-alg-3DESwrap'; + NID_id_smime_alg_3DESwrap = 243; + SN_id_smime_alg_RC2wrap = 'id-smime-alg-RC2wrap'; + NID_id_smime_alg_RC2wrap = 244; + SN_id_smime_alg_ESDH = 'id-smime-alg-ESDH'; + NID_id_smime_alg_ESDH = 245; + SN_id_smime_alg_CMS3DESwrap = 'id-smime-alg-CMS3DESwrap'; + NID_id_smime_alg_CMS3DESwrap = 246; + SN_id_smime_alg_CMSRC2wrap = 'id-smime-alg-CMSRC2wrap'; + NID_id_smime_alg_CMSRC2wrap = 247; + SN_id_alg_PWRI_KEK = 'id-alg-PWRI-KEK'; + NID_id_alg_PWRI_KEK = 893; + SN_id_smime_cd_ldap = 'id-smime-cd-ldap'; + NID_id_smime_cd_ldap = 248; + SN_id_smime_spq_ets_sqt_uri = 'id-smime-spq-ets-sqt-uri'; + NID_id_smime_spq_ets_sqt_uri = 249; + SN_id_smime_spq_ets_sqt_unotice = 'id-smime-spq-ets-sqt-unotice'; + NID_id_smime_spq_ets_sqt_unotice = 250; + SN_id_smime_cti_ets_proofOfOrigin = 'id-smime-cti-ets-proofOfOrigin'; + NID_id_smime_cti_ets_proofOfOrigin = 251; + SN_id_smime_cti_ets_proofOfReceipt = 'id-smime-cti-ets-proofOfReceipt'; + NID_id_smime_cti_ets_proofOfReceipt = 252; + SN_id_smime_cti_ets_proofOfDelivery = 'id-smime-cti-ets-proofOfDelivery'; + NID_id_smime_cti_ets_proofOfDelivery = 253; + SN_id_smime_cti_ets_proofOfSender = 'id-smime-cti-ets-proofOfSender'; + NID_id_smime_cti_ets_proofOfSender = 254; + SN_id_smime_cti_ets_proofOfApproval = 'id-smime-cti-ets-proofOfApproval'; + NID_id_smime_cti_ets_proofOfApproval = 255; + SN_id_smime_cti_ets_proofOfCreation = 'id-smime-cti-ets-proofOfCreation'; + NID_id_smime_cti_ets_proofOfCreation = 256; + LN_friendlyName = 'friendlyName'; + NID_friendlyName = 156; + LN_localKeyID = 'localKeyID'; + NID_localKeyID = 157; + SN_ms_csp_name = 'CSPName'; + LN_ms_csp_name = 'Microsoft CSP Name'; + NID_ms_csp_name = 417; + SN_LocalKeySet = 'LocalKeySet'; + LN_LocalKeySet = 'Microsoft Local Key set'; + NID_LocalKeySet = 856; + LN_x509Certificate = 'x509Certificate'; + NID_x509Certificate = 158; + LN_sdsiCertificate = 'sdsiCertificate'; + NID_sdsiCertificate = 159; + LN_x509Crl = 'x509Crl'; + NID_x509Crl = 160; + SN_pbe_WithSHA1And128BitRC4 = 'PBE-SHA1-RC4-128'; + LN_pbe_WithSHA1And128BitRC4 = 'pbeWithSHA1And128BitRC4'; + NID_pbe_WithSHA1And128BitRC4 = 144; + SN_pbe_WithSHA1And40BitRC4 = 'PBE-SHA1-RC4-40'; + LN_pbe_WithSHA1And40BitRC4 = 'pbeWithSHA1And40BitRC4'; + NID_pbe_WithSHA1And40BitRC4 = 145; + SN_pbe_WithSHA1And3_Key_TripleDES_CBC = 'PBE-SHA1-3DES'; + LN_pbe_WithSHA1And3_Key_TripleDES_CBC = 'pbeWithSHA1And3-KeyTripleDES-CBC'; + NID_pbe_WithSHA1And3_Key_TripleDES_CBC = 146; + SN_pbe_WithSHA1And2_Key_TripleDES_CBC = 'PBE-SHA1-2DES'; + LN_pbe_WithSHA1And2_Key_TripleDES_CBC = 'pbeWithSHA1And2-KeyTripleDES-CBC'; + NID_pbe_WithSHA1And2_Key_TripleDES_CBC = 147; + SN_pbe_WithSHA1And128BitRC2_CBC = 'PBE-SHA1-RC2-128'; + LN_pbe_WithSHA1And128BitRC2_CBC = 'pbeWithSHA1And128BitRC2-CBC'; + NID_pbe_WithSHA1And128BitRC2_CBC = 148; + SN_pbe_WithSHA1And40BitRC2_CBC = 'PBE-SHA1-RC2-40'; + LN_pbe_WithSHA1And40BitRC2_CBC = 'pbeWithSHA1And40BitRC2-CBC'; + NID_pbe_WithSHA1And40BitRC2_CBC = 149; + LN_keyBag = 'keyBag'; + NID_keyBag = 150; + LN_pkcs8ShroudedKeyBag = 'pkcs8ShroudedKeyBag'; + NID_pkcs8ShroudedKeyBag = 151; + LN_certBag = 'certBag'; + NID_certBag = 152; + LN_crlBag = 'crlBag'; + NID_crlBag = 153; + LN_secretBag = 'secretBag'; + NID_secretBag = 154; + LN_safeContentsBag = 'safeContentsBag'; + NID_safeContentsBag = 155; + SN_md2 = 'MD2'; + LN_md2 = 'md2'; + NID_md2 = 3; + SN_md4 = 'MD4'; + LN_md4 = 'md4'; + NID_md4 = 257; + SN_md5 = 'MD5'; + LN_md5 = 'md5'; + NID_md5 = 4; + SN_md5_sha1 = 'MD5-SHA1'; + LN_md5_sha1 = 'md5-sha1'; + NID_md5_sha1 = 114; + LN_hmacWithMD5 = 'hmacWithMD5'; + NID_hmacWithMD5 = 797; + LN_hmacWithSHA1 = 'hmacWithSHA1'; + NID_hmacWithSHA1 = 163; + SN_sm2 = 'SM2'; + LN_sm2 = 'sm2'; + NID_sm2 = 1172; + SN_sm3 = 'SM3'; + LN_sm3 = 'sm3'; + NID_sm3 = 1143; + SN_sm3WithRSAEncryption = 'RSA-SM3'; + LN_sm3WithRSAEncryption = 'sm3WithRSAEncryption'; + NID_sm3WithRSAEncryption = 1144; + LN_hmacWithSHA224 = 'hmacWithSHA224'; + NID_hmacWithSHA224 = 798; + LN_hmacWithSHA256 = 'hmacWithSHA256'; + NID_hmacWithSHA256 = 799; + LN_hmacWithSHA384 = 'hmacWithSHA384'; + NID_hmacWithSHA384 = 800; + LN_hmacWithSHA512 = 'hmacWithSHA512'; + NID_hmacWithSHA512 = 801; + LN_hmacWithSHA512_224 = 'hmacWithSHA512-224'; + NID_hmacWithSHA512_224 = 1193; + LN_hmacWithSHA512_256 = 'hmacWithSHA512-256'; + NID_hmacWithSHA512_256 = 1194; + SN_rc2_cbc = 'RC2-CBC'; + LN_rc2_cbc = 'rc2-cbc'; + NID_rc2_cbc = 37; + SN_rc2_ecb = 'RC2-ECB'; + LN_rc2_ecb = 'rc2-ecb'; + NID_rc2_ecb = 38; + SN_rc2_cfb64 = 'RC2-CFB'; + LN_rc2_cfb64 = 'rc2-cfb'; + NID_rc2_cfb64 = 39; + SN_rc2_ofb64 = 'RC2-OFB'; + LN_rc2_ofb64 = 'rc2-ofb'; + NID_rc2_ofb64 = 40; + SN_rc2_40_cbc = 'RC2-40-CBC'; + LN_rc2_40_cbc = 'rc2-40-cbc'; + NID_rc2_40_cbc = 98; + SN_rc2_64_cbc = 'RC2-64-CBC'; + LN_rc2_64_cbc = 'rc2-64-cbc'; + NID_rc2_64_cbc = 166; + SN_rc4 = 'RC4'; + LN_rc4 = 'rc4'; + NID_rc4 = 5; + SN_rc4_40 = 'RC4-40'; + LN_rc4_40 = 'rc4-40'; + NID_rc4_40 = 97; + SN_des_ede3_cbc = 'DES-EDE3-CBC'; + LN_des_ede3_cbc = 'des-ede3-cbc'; + NID_des_ede3_cbc = 44; + SN_rc5_cbc = 'RC5-CBC'; + LN_rc5_cbc = 'rc5-cbc'; + NID_rc5_cbc = 120; + SN_rc5_ecb = 'RC5-ECB'; + LN_rc5_ecb = 'rc5-ecb'; + NID_rc5_ecb = 121; + SN_rc5_cfb64 = 'RC5-CFB'; + LN_rc5_cfb64 = 'rc5-cfb'; + NID_rc5_cfb64 = 122; + SN_rc5_ofb64 = 'RC5-OFB'; + LN_rc5_ofb64 = 'rc5-ofb'; + NID_rc5_ofb64 = 123; + SN_ms_ext_req = 'msExtReq'; + LN_ms_ext_req = 'Microsoft Extension Request'; + NID_ms_ext_req = 171; + SN_ms_code_ind = 'msCodeInd'; + LN_ms_code_ind = 'Microsoft Individual Code Signing'; + NID_ms_code_ind = 134; + SN_ms_code_com = 'msCodeCom'; + LN_ms_code_com = 'Microsoft Commercial Code Signing'; + NID_ms_code_com = 135; + SN_ms_ctl_sign = 'msCTLSign'; + LN_ms_ctl_sign = 'Microsoft Trust List Signing'; + NID_ms_ctl_sign = 136; + SN_ms_sgc = 'msSGC'; + LN_ms_sgc = 'Microsoft Server Gated Crypto'; + NID_ms_sgc = 137; + SN_ms_efs = 'msEFS'; + LN_ms_efs = 'Microsoft Encrypted File System'; + NID_ms_efs = 138; + SN_ms_smartcard_login = 'msSmartcardLogin'; + LN_ms_smartcard_login = 'Microsoft Smartcard Login'; + NID_ms_smartcard_login = 648; + SN_ms_upn = 'msUPN'; + LN_ms_upn = 'Microsoft User Principal Name'; + NID_ms_upn = 649; + SN_idea_cbc = 'IDEA-CBC'; + LN_idea_cbc = 'idea-cbc'; + NID_idea_cbc = 34; + SN_idea_ecb = 'IDEA-ECB'; + LN_idea_ecb = 'idea-ecb'; + NID_idea_ecb = 36; + SN_idea_cfb64 = 'IDEA-CFB'; + LN_idea_cfb64 = 'idea-cfb'; + NID_idea_cfb64 = 35; + SN_idea_ofb64 = 'IDEA-OFB'; + LN_idea_ofb64 = 'idea-ofb'; + NID_idea_ofb64 = 46; + SN_bf_cbc = 'BF-CBC'; + LN_bf_cbc = 'bf-cbc'; + NID_bf_cbc = 91; + SN_bf_ecb = 'BF-ECB'; + LN_bf_ecb = 'bf-ecb'; + NID_bf_ecb = 92; + SN_bf_cfb64 = 'BF-CFB'; + LN_bf_cfb64 = 'bf-cfb'; + NID_bf_cfb64 = 93; + SN_bf_ofb64 = 'BF-OFB'; + LN_bf_ofb64 = 'bf-ofb'; + NID_bf_ofb64 = 94; + SN_id_pkix = 'PKIX'; + NID_id_pkix = 127; + SN_id_pkix_mod = 'id-pkix-mod'; + NID_id_pkix_mod = 258; + SN_id_pe = 'id-pe'; + NID_id_pe = 175; + SN_id_qt = 'id-qt'; + NID_id_qt = 259; + SN_id_kp = 'id-kp'; + NID_id_kp = 128; + SN_id_it = 'id-it'; + NID_id_it = 260; + SN_id_pkip = 'id-pkip'; + NID_id_pkip = 261; + SN_id_alg = 'id-alg'; + NID_id_alg = 262; + SN_id_cmc = 'id-cmc'; + NID_id_cmc = 263; + SN_id_on = 'id-on'; + NID_id_on = 264; + SN_id_pda = 'id-pda'; + NID_id_pda = 265; + SN_id_aca = 'id-aca'; + NID_id_aca = 266; + SN_id_qcs = 'id-qcs'; + NID_id_qcs = 267; + SN_id_cct = 'id-cct'; + NID_id_cct = 268; + SN_id_ppl = 'id-ppl'; + NID_id_ppl = 662; + SN_id_ad = 'id-ad'; + NID_id_ad = 176; + SN_id_pkix1_explicit_88 = 'id-pkix1-explicit-88'; + NID_id_pkix1_explicit_88 = 269; + SN_id_pkix1_implicit_88 = 'id-pkix1-implicit-88'; + NID_id_pkix1_implicit_88 = 270; + SN_id_pkix1_explicit_93 = 'id-pkix1-explicit-93'; + NID_id_pkix1_explicit_93 = 271; + SN_id_pkix1_implicit_93 = 'id-pkix1-implicit-93'; + NID_id_pkix1_implicit_93 = 272; + SN_id_mod_crmf = 'id-mod-crmf'; + NID_id_mod_crmf = 273; + SN_id_mod_cmc = 'id-mod-cmc'; + NID_id_mod_cmc = 274; + SN_id_mod_kea_profile_88 = 'id-mod-kea-profile-88'; + NID_id_mod_kea_profile_88 = 275; + SN_id_mod_kea_profile_93 = 'id-mod-kea-profile-93'; + NID_id_mod_kea_profile_93 = 276; + SN_id_mod_cmp = 'id-mod-cmp'; + NID_id_mod_cmp = 277; + SN_id_mod_qualified_cert_88 = 'id-mod-qualified-cert-88'; + NID_id_mod_qualified_cert_88 = 278; + SN_id_mod_qualified_cert_93 = 'id-mod-qualified-cert-93'; + NID_id_mod_qualified_cert_93 = 279; + SN_id_mod_attribute_cert = 'id-mod-attribute-cert'; + NID_id_mod_attribute_cert = 280; + SN_id_mod_timestamp_protocol = 'id-mod-timestamp-protocol'; + NID_id_mod_timestamp_protocol = 281; + SN_id_mod_ocsp = 'id-mod-ocsp'; + NID_id_mod_ocsp = 282; + SN_id_mod_dvcs = 'id-mod-dvcs'; + NID_id_mod_dvcs = 283; + SN_id_mod_cmp2000 = 'id-mod-cmp2000'; + NID_id_mod_cmp2000 = 284; + SN_info_access = 'authorityInfoAccess'; + LN_info_access = 'Authority Information Access'; + NID_info_access = 177; + SN_biometricInfo = 'biometricInfo'; + LN_biometricInfo = 'Biometric Info'; + NID_biometricInfo = 285; + SN_qcStatements = 'qcStatements'; + NID_qcStatements = 286; + SN_ac_auditEntity = 'ac-auditEntity'; + NID_ac_auditEntity = 287; + SN_ac_targeting = 'ac-targeting'; + NID_ac_targeting = 288; + SN_aaControls = 'aaControls'; + NID_aaControls = 289; + SN_sbgp_ipAddrBlock = 'sbgp-ipAddrBlock'; + NID_sbgp_ipAddrBlock = 290; + SN_sbgp_autonomousSysNum = 'sbgp-autonomousSysNum'; + NID_sbgp_autonomousSysNum = 291; + SN_sbgp_routerIdentifier = 'sbgp-routerIdentifier'; + NID_sbgp_routerIdentifier = 292; + SN_ac_proxying = 'ac-proxying'; + NID_ac_proxying = 397; + SN_sinfo_access = 'subjectInfoAccess'; + LN_sinfo_access = 'Subject Information Access'; + NID_sinfo_access = 398; + SN_proxyCertInfo = 'proxyCertInfo'; + LN_proxyCertInfo = 'Proxy Certificate Information'; + NID_proxyCertInfo = 663; + SN_tlsfeature = 'tlsfeature'; + LN_tlsfeature = 'TLS Feature'; + NID_tlsfeature = 1020; + SN_id_qt_cps = 'id-qt-cps'; + LN_id_qt_cps = 'Policy Qualifier CPS'; + NID_id_qt_cps = 164; + SN_id_qt_unotice = 'id-qt-unotice'; + LN_id_qt_unotice = 'Policy Qualifier User Notice'; + NID_id_qt_unotice = 165; + SN_textNotice = 'textNotice'; + NID_textNotice = 293; + SN_server_auth = 'serverAuth'; + LN_server_auth = 'TLS Web Server Authentication'; + NID_server_auth = 129; + SN_client_auth = 'clientAuth'; + LN_client_auth = 'TLS Web Client Authentication'; + NID_client_auth = 130; + SN_code_sign = 'codeSigning'; + LN_code_sign = 'Code Signing'; + NID_code_sign = 131; + SN_email_protect = 'emailProtection'; + LN_email_protect = 'E-mail Protection'; + NID_email_protect = 132; + SN_ipsecEndSystem = 'ipsecEndSystem'; + LN_ipsecEndSystem = 'IPSec End System'; + NID_ipsecEndSystem = 294; + SN_ipsecTunnel = 'ipsecTunnel'; + LN_ipsecTunnel = 'IPSec Tunnel'; + NID_ipsecTunnel = 295; + SN_ipsecUser = 'ipsecUser'; + LN_ipsecUser = 'IPSec User'; + NID_ipsecUser = 296; + SN_time_stamp = 'timeStamping'; + LN_time_stamp = 'Time Stamping'; + NID_time_stamp = 133; + SN_OCSP_sign = 'OCSPSigning'; + LN_OCSP_sign = 'OCSP Signing'; + NID_OCSP_sign = 180; + SN_dvcs = 'DVCS'; + LN_dvcs = 'dvcs'; + NID_dvcs = 297; + SN_ipsec_IKE = 'ipsecIKE'; + LN_ipsec_IKE = 'ipsec Internet Key Exchange'; + NID_ipsec_IKE = 1022; + SN_capwapAC = 'capwapAC'; + LN_capwapAC = 'Ctrl/provision WAP Access'; + NID_capwapAC = 1023; + SN_capwapWTP = 'capwapWTP'; + LN_capwapWTP = 'Ctrl/Provision WAP Termination'; + NID_capwapWTP = 1024; + SN_sshClient = 'secureShellClient'; + LN_sshClient = 'SSH Client'; + NID_sshClient = 1025; + SN_sshServer = 'secureShellServer'; + LN_sshServer = 'SSH Server'; + NID_sshServer = 1026; + SN_sendRouter = 'sendRouter'; + LN_sendRouter = 'Send Router'; + NID_sendRouter = 1027; + SN_sendProxiedRouter = 'sendProxiedRouter'; + LN_sendProxiedRouter = 'Send Proxied Router'; + NID_sendProxiedRouter = 1028; + SN_sendOwner = 'sendOwner'; + LN_sendOwner = 'Send Owner'; + NID_sendOwner = 1029; + SN_sendProxiedOwner = 'sendProxiedOwner'; + LN_sendProxiedOwner = 'Send Proxied Owner'; + NID_sendProxiedOwner = 1030; + SN_cmcCA = 'cmcCA'; + LN_cmcCA = 'CMC Certificate Authority'; + NID_cmcCA = 1131; + SN_cmcRA = 'cmcRA'; + LN_cmcRA = 'CMC Registration Authority'; + NID_cmcRA = 1132; + SN_id_it_caProtEncCert = 'id-it-caProtEncCert'; + NID_id_it_caProtEncCert = 298; + SN_id_it_signKeyPairTypes = 'id-it-signKeyPairTypes'; + NID_id_it_signKeyPairTypes = 299; + SN_id_it_encKeyPairTypes = 'id-it-encKeyPairTypes'; + NID_id_it_encKeyPairTypes = 300; + SN_id_it_preferredSymmAlg = 'id-it-preferredSymmAlg'; + NID_id_it_preferredSymmAlg = 301; + SN_id_it_caKeyUpdateInfo = 'id-it-caKeyUpdateInfo'; + NID_id_it_caKeyUpdateInfo = 302; + SN_id_it_currentCRL = 'id-it-currentCRL'; + NID_id_it_currentCRL = 303; + SN_id_it_unsupportedOIDs = 'id-it-unsupportedOIDs'; + NID_id_it_unsupportedOIDs = 304; + SN_id_it_subscriptionRequest = 'id-it-subscriptionRequest'; + NID_id_it_subscriptionRequest = 305; + SN_id_it_subscriptionResponse = 'id-it-subscriptionResponse'; + NID_id_it_subscriptionResponse = 306; + SN_id_it_keyPairParamReq = 'id-it-keyPairParamReq'; + NID_id_it_keyPairParamReq = 307; + SN_id_it_keyPairParamRep = 'id-it-keyPairParamRep'; + NID_id_it_keyPairParamRep = 308; + SN_id_it_revPassphrase = 'id-it-revPassphrase'; + NID_id_it_revPassphrase = 309; + SN_id_it_implicitConfirm = 'id-it-implicitConfirm'; + NID_id_it_implicitConfirm = 310; + SN_id_it_confirmWaitTime = 'id-it-confirmWaitTime'; + NID_id_it_confirmWaitTime = 311; + SN_id_it_origPKIMessage = 'id-it-origPKIMessage'; + NID_id_it_origPKIMessage = 312; + SN_id_it_suppLangTags = 'id-it-suppLangTags'; + NID_id_it_suppLangTags = 784; + SN_id_regCtrl = 'id-regCtrl'; + NID_id_regCtrl = 313; + SN_id_regInfo = 'id-regInfo'; + NID_id_regInfo = 314; + SN_id_regCtrl_regToken = 'id-regCtrl-regToken'; + NID_id_regCtrl_regToken = 315; + SN_id_regCtrl_authenticator = 'id-regCtrl-authenticator'; + NID_id_regCtrl_authenticator = 316; + SN_id_regCtrl_pkiPublicationInfo = 'id-regCtrl-pkiPublicationInfo'; + NID_id_regCtrl_pkiPublicationInfo = 317; + SN_id_regCtrl_pkiArchiveOptions = 'id-regCtrl-pkiArchiveOptions'; + NID_id_regCtrl_pkiArchiveOptions = 318; + SN_id_regCtrl_oldCertID = 'id-regCtrl-oldCertID'; + NID_id_regCtrl_oldCertID = 319; + SN_id_regCtrl_protocolEncrKey = 'id-regCtrl-protocolEncrKey'; + NID_id_regCtrl_protocolEncrKey = 320; + SN_id_regInfo_utf8Pairs = 'id-regInfo-utf8Pairs'; + NID_id_regInfo_utf8Pairs = 321; + SN_id_regInfo_certReq = 'id-regInfo-certReq'; + NID_id_regInfo_certReq = 322; + SN_id_alg_des40 = 'id-alg-des40'; + NID_id_alg_des40 = 323; + SN_id_alg_noSignature = 'id-alg-noSignature'; + NID_id_alg_noSignature = 324; + SN_id_alg_dh_sig_hmac_sha1 = 'id-alg-dh-sig-hmac-sha1'; + NID_id_alg_dh_sig_hmac_sha1 = 325; + SN_id_alg_dh_pop = 'id-alg-dh-pop'; + NID_id_alg_dh_pop = 326; + SN_id_cmc_statusInfo = 'id-cmc-statusInfo'; + NID_id_cmc_statusInfo = 327; + SN_id_cmc_identification = 'id-cmc-identification'; + NID_id_cmc_identification = 328; + SN_id_cmc_identityProof = 'id-cmc-identityProof'; + NID_id_cmc_identityProof = 329; + SN_id_cmc_dataReturn = 'id-cmc-dataReturn'; + NID_id_cmc_dataReturn = 330; + SN_id_cmc_transactionId = 'id-cmc-transactionId'; + NID_id_cmc_transactionId = 331; + SN_id_cmc_senderNonce = 'id-cmc-senderNonce'; + NID_id_cmc_senderNonce = 332; + SN_id_cmc_recipientNonce = 'id-cmc-recipientNonce'; + NID_id_cmc_recipientNonce = 333; + SN_id_cmc_addExtensions = 'id-cmc-addExtensions'; + NID_id_cmc_addExtensions = 334; + SN_id_cmc_encryptedPOP = 'id-cmc-encryptedPOP'; + NID_id_cmc_encryptedPOP = 335; + SN_id_cmc_decryptedPOP = 'id-cmc-decryptedPOP'; + NID_id_cmc_decryptedPOP = 336; + SN_id_cmc_lraPOPWitness = 'id-cmc-lraPOPWitness'; + NID_id_cmc_lraPOPWitness = 337; + SN_id_cmc_getCert = 'id-cmc-getCert'; + NID_id_cmc_getCert = 338; + SN_id_cmc_getCRL = 'id-cmc-getCRL'; + NID_id_cmc_getCRL = 339; + SN_id_cmc_revokeRequest = 'id-cmc-revokeRequest'; + NID_id_cmc_revokeRequest = 340; + SN_id_cmc_regInfo = 'id-cmc-regInfo'; + NID_id_cmc_regInfo = 341; + SN_id_cmc_responseInfo = 'id-cmc-responseInfo'; + NID_id_cmc_responseInfo = 342; + SN_id_cmc_queryPending = 'id-cmc-queryPending'; + NID_id_cmc_queryPending = 343; + SN_id_cmc_popLinkRandom = 'id-cmc-popLinkRandom'; + NID_id_cmc_popLinkRandom = 344; + SN_id_cmc_popLinkWitness = 'id-cmc-popLinkWitness'; + NID_id_cmc_popLinkWitness = 345; + SN_id_cmc_confirmCertAcceptance = 'id-cmc-confirmCertAcceptance'; + NID_id_cmc_confirmCertAcceptance = 346; + SN_id_on_personalData = 'id-on-personalData'; + NID_id_on_personalData = 347; + SN_id_on_permanentIdentifier = 'id-on-permanentIdentifier'; + LN_id_on_permanentIdentifier = 'Permanent Identifier'; + NID_id_on_permanentIdentifier = 858; + SN_id_pda_dateOfBirth = 'id-pda-dateOfBirth'; + NID_id_pda_dateOfBirth = 348; + SN_id_pda_placeOfBirth = 'id-pda-placeOfBirth'; + NID_id_pda_placeOfBirth = 349; + SN_id_pda_gender = 'id-pda-gender'; + NID_id_pda_gender = 351; + SN_id_pda_countryOfCitizenship = 'id-pda-countryOfCitizenship'; + NID_id_pda_countryOfCitizenship = 352; + SN_id_pda_countryOfResidence = 'id-pda-countryOfResidence'; + NID_id_pda_countryOfResidence = 353; + SN_id_aca_authenticationInfo = 'id-aca-authenticationInfo'; + NID_id_aca_authenticationInfo = 354; + SN_id_aca_accessIdentity = 'id-aca-accessIdentity'; + NID_id_aca_accessIdentity = 355; + SN_id_aca_chargingIdentity = 'id-aca-chargingIdentity'; + NID_id_aca_chargingIdentity = 356; + SN_id_aca_group = 'id-aca-group'; + NID_id_aca_group = 357; + SN_id_aca_role = 'id-aca-role'; + NID_id_aca_role = 358; + SN_id_aca_encAttrs = 'id-aca-encAttrs'; + NID_id_aca_encAttrs = 399; + SN_id_qcs_pkixQCSyntax_v1 = 'id-qcs-pkixQCSyntax-v1'; + NID_id_qcs_pkixQCSyntax_v1 = 359; + SN_id_cct_crs = 'id-cct-crs'; + NID_id_cct_crs = 360; + SN_id_cct_PKIData = 'id-cct-PKIData'; + NID_id_cct_PKIData = 361; + SN_id_cct_PKIResponse = 'id-cct-PKIResponse'; + NID_id_cct_PKIResponse = 362; + SN_id_ppl_anyLanguage = 'id-ppl-anyLanguage'; + LN_id_ppl_anyLanguage = 'Any language'; + NID_id_ppl_anyLanguage = 664; + SN_id_ppl_inheritAll = 'id-ppl-inheritAll'; + LN_id_ppl_inheritAll = 'Inherit all'; + NID_id_ppl_inheritAll = 665; + SN_Independent = 'id-ppl-independent'; + LN_Independent = 'Independent'; + NID_Independent = 667; + SN_ad_OCSP = 'OCSP'; + LN_ad_OCSP = 'OCSP'; + NID_ad_OCSP = 178; + SN_ad_ca_issuers = 'caIssuers'; + LN_ad_ca_issuers = 'CA Issuers'; + NID_ad_ca_issuers = 179; + SN_ad_timeStamping = 'ad_timestamping'; + LN_ad_timeStamping = 'AD Time Stamping'; + NID_ad_timeStamping = 363; + SN_ad_dvcs = 'AD_DVCS'; + LN_ad_dvcs = 'ad dvcs'; + NID_ad_dvcs = 364; + SN_caRepository = 'caRepository'; + LN_caRepository = 'CA Repository'; + NID_caRepository = 785; + SN_id_pkix_OCSP_basic = 'basicOCSPResponse'; + LN_id_pkix_OCSP_basic = 'Basic OCSP Response'; + NID_id_pkix_OCSP_basic = 365; + SN_id_pkix_OCSP_Nonce = 'Nonce'; + LN_id_pkix_OCSP_Nonce = 'OCSP Nonce'; + NID_id_pkix_OCSP_Nonce = 366; + SN_id_pkix_OCSP_CrlID = 'CrlID'; + LN_id_pkix_OCSP_CrlID = 'OCSP CRL ID'; + NID_id_pkix_OCSP_CrlID = 367; + SN_id_pkix_OCSP_acceptableResponses = 'acceptableResponses'; + LN_id_pkix_OCSP_acceptableResponses = 'Acceptable OCSP Responses'; + NID_id_pkix_OCSP_acceptableResponses = 368; + SN_id_pkix_OCSP_noCheck = 'noCheck'; + LN_id_pkix_OCSP_noCheck = 'OCSP No Check'; + NID_id_pkix_OCSP_noCheck = 369; + SN_id_pkix_OCSP_archiveCutoff = 'archiveCutoff'; + LN_id_pkix_OCSP_archiveCutoff = 'OCSP Archive Cutoff'; + NID_id_pkix_OCSP_archiveCutoff = 370; + SN_id_pkix_OCSP_serviceLocator = 'serviceLocator'; + LN_id_pkix_OCSP_serviceLocator = 'OCSP Service Locator'; + NID_id_pkix_OCSP_serviceLocator = 371; + SN_id_pkix_OCSP_extendedStatus = 'extendedStatus'; + LN_id_pkix_OCSP_extendedStatus = 'Extended OCSP Status'; + NID_id_pkix_OCSP_extendedStatus = 372; + SN_id_pkix_OCSP_valid = 'valid'; + NID_id_pkix_OCSP_valid = 373; + SN_id_pkix_OCSP_path = 'path'; + NID_id_pkix_OCSP_path = 374; + SN_id_pkix_OCSP_trustRoot = 'trustRoot'; + LN_id_pkix_OCSP_trustRoot = 'Trust Root'; + NID_id_pkix_OCSP_trustRoot = 375; + SN_algorithm = 'algorithm'; + LN_algorithm = 'algorithm'; + NID_algorithm = 376; + SN_md5WithRSA = 'RSA-NP-MD5'; + LN_md5WithRSA = 'md5WithRSA'; + NID_md5WithRSA = 104; + SN_des_ecb = 'DES-ECB'; + LN_des_ecb = 'des-ecb'; + NID_des_ecb = 29; + SN_des_cbc = 'DES-CBC'; + LN_des_cbc = 'des-cbc'; + NID_des_cbc = 31; + SN_des_ofb64 = 'DES-OFB'; + LN_des_ofb64 = 'des-ofb'; + NID_des_ofb64 = 45; + SN_des_cfb64 = 'DES-CFB'; + LN_des_cfb64 = 'des-cfb'; + NID_des_cfb64 = 30; + SN_rsaSignature = 'rsaSignature'; + NID_rsaSignature = 377; + SN_dsa_2 = 'DSA-old'; + LN_dsa_2 = 'dsaEncryption-old'; + NID_dsa_2 = 67; + SN_dsaWithSHA = 'DSA-SHA'; + LN_dsaWithSHA = 'dsaWithSHA'; + NID_dsaWithSHA = 66; + SN_shaWithRSAEncryption = 'RSA-SHA'; + LN_shaWithRSAEncryption = 'shaWithRSAEncryption'; + NID_shaWithRSAEncryption = 42; + SN_des_ede_ecb = 'DES-EDE'; + LN_des_ede_ecb = 'des-ede'; + NID_des_ede_ecb = 32; + SN_des_ede3_ecb = 'DES-EDE3'; + LN_des_ede3_ecb = 'des-ede3'; + NID_des_ede3_ecb = 33; + SN_des_ede_cbc = 'DES-EDE-CBC'; + LN_des_ede_cbc = 'des-ede-cbc'; + NID_des_ede_cbc = 43; + SN_des_ede_cfb64 = 'DES-EDE-CFB'; + LN_des_ede_cfb64 = 'des-ede-cfb'; + NID_des_ede_cfb64 = 60; + SN_des_ede3_cfb64 = 'DES-EDE3-CFB'; + LN_des_ede3_cfb64 = 'des-ede3-cfb'; + NID_des_ede3_cfb64 = 61; + SN_des_ede_ofb64 = 'DES-EDE-OFB'; + LN_des_ede_ofb64 = 'des-ede-ofb'; + NID_des_ede_ofb64 = 62; + SN_des_ede3_ofb64 = 'DES-EDE3-OFB'; + LN_des_ede3_ofb64 = 'des-ede3-ofb'; + NID_des_ede3_ofb64 = 63; + SN_desx_cbc = 'DESX-CBC'; + LN_desx_cbc = 'desx-cbc'; + NID_desx_cbc = 80; + SN_sha = 'SHA'; + LN_sha = 'sha'; + NID_sha = 41; + SN_sha1 = 'SHA1'; + LN_sha1 = 'sha1'; + NID_sha1 = 64; + SN_dsaWithSHA1_2 = 'DSA-SHA1-old'; + LN_dsaWithSHA1_2 = 'dsaWithSHA1-old'; + NID_dsaWithSHA1_2 = 70; + SN_sha1WithRSA = 'RSA-SHA1-2'; + LN_sha1WithRSA = 'sha1WithRSA'; + NID_sha1WithRSA = 115; + SN_ripemd160 = 'RIPEMD160'; + LN_ripemd160 = 'ripemd160'; + NID_ripemd160 = 117; + SN_ripemd160WithRSA = 'RSA-RIPEMD160'; + LN_ripemd160WithRSA = 'ripemd160WithRSA'; + NID_ripemd160WithRSA = 119; + SN_blake2b512 = 'BLAKE2b512'; + LN_blake2b512 = 'blake2b512'; + NID_blake2b512 = 1056; + SN_blake2s256 = 'BLAKE2s256'; + LN_blake2s256 = 'blake2s256'; + NID_blake2s256 = 1057; + SN_sxnet = 'SXNetID'; + LN_sxnet = 'Strong Extranet ID'; + NID_sxnet = 143; + SN_X500 = 'X500'; + LN_X500 = 'directory services (X.500)'; + NID_X500 = 11; + SN_X509 = 'X509'; + NID_X509 = 12; + SN_commonName = 'CN'; + LN_commonName = 'commonName'; + NID_commonName = 13; + SN_surname = 'SN'; + LN_surname = 'surname'; + NID_surname = 100; + LN_serialNumber = 'serialNumber'; + NID_serialNumber = 105; + SN_countryName = 'C'; + LN_countryName = 'countryName'; + NID_countryName = 14; + SN_localityName = 'L'; + LN_localityName = 'localityName'; + NID_localityName = 15; + SN_stateOrProvinceName = 'ST'; + LN_stateOrProvinceName = 'stateOrProvinceName'; + NID_stateOrProvinceName = 16; + SN_streetAddress = 'street'; + LN_streetAddress = 'streetAddress'; + NID_streetAddress = 660; + SN_organizationName = 'O'; + LN_organizationName = 'organizationName'; + NID_organizationName = 17; + SN_organizationalUnitName = 'OU'; + LN_organizationalUnitName = 'organizationalUnitName'; + NID_organizationalUnitName = 18; + SN_title = 'title'; + LN_title = 'title'; + NID_title = 106; + LN_description = 'description'; + NID_description = 107; + LN_searchGuide = 'searchGuide'; + NID_searchGuide = 859; + LN_businessCategory = 'businessCategory'; + NID_businessCategory = 860; + LN_postalAddress = 'postalAddress'; + NID_postalAddress = 861; + LN_postalCode = 'postalCode'; + NID_postalCode = 661; + LN_postOfficeBox = 'postOfficeBox'; + NID_postOfficeBox = 862; + LN_physicalDeliveryOfficeName = 'physicalDeliveryOfficeName'; + NID_physicalDeliveryOfficeName = 863; + LN_telephoneNumber = 'telephoneNumber'; + NID_telephoneNumber = 864; + LN_telexNumber = 'telexNumber'; + NID_telexNumber = 865; + LN_teletexTerminalIdentifier = 'teletexTerminalIdentifier'; + NID_teletexTerminalIdentifier = 866; + LN_facsimileTelephoneNumber = 'facsimileTelephoneNumber'; + NID_facsimileTelephoneNumber = 867; + LN_x121Address = 'x121Address'; + NID_x121Address = 868; + LN_internationaliSDNNumber = 'internationaliSDNNumber'; + NID_internationaliSDNNumber = 869; + LN_registeredAddress = 'registeredAddress'; + NID_registeredAddress = 870; + LN_destinationIndicator = 'destinationIndicator'; + NID_destinationIndicator = 871; + LN_preferredDeliveryMethod = 'preferredDeliveryMethod'; + NID_preferredDeliveryMethod = 872; + LN_presentationAddress = 'presentationAddress'; + NID_presentationAddress = 873; + LN_supportedApplicationContext = 'supportedApplicationContext'; + NID_supportedApplicationContext = 874; + SN_member = 'member'; + NID_member = 875; + SN_owner = 'owner'; + NID_owner = 876; + LN_roleOccupant = 'roleOccupant'; + NID_roleOccupant = 877; + SN_seeAlso = 'seeAlso'; + NID_seeAlso = 878; + LN_userPassword = 'userPassword'; + NID_userPassword = 879; + LN_userCertificate = 'userCertificate'; + NID_userCertificate = 880; + LN_cACertificate = 'cACertificate'; + NID_cACertificate = 881; + LN_authorityRevocationList = 'authorityRevocationList'; + NID_authorityRevocationList = 882; + LN_certificateRevocationList = 'certificateRevocationList'; + NID_certificateRevocationList = 883; + LN_crossCertificatePair = 'crossCertificatePair'; + NID_crossCertificatePair = 884; + SN_name = 'name'; + LN_name = 'name'; + NID_name = 173; + SN_givenName = 'GN'; + LN_givenName = 'givenName'; + NID_givenName = 99; + SN_initials = 'initials'; + LN_initials = 'initials'; + NID_initials = 101; + LN_generationQualifier = 'generationQualifier'; + NID_generationQualifier = 509; + LN_x500UniqueIdentifier = 'x500UniqueIdentifier'; + NID_x500UniqueIdentifier = 503; + SN_dnQualifier = 'dnQualifier'; + LN_dnQualifier = 'dnQualifier'; + NID_dnQualifier = 174; + LN_enhancedSearchGuide = 'enhancedSearchGuide'; + NID_enhancedSearchGuide = 885; + LN_protocolInformation = 'protocolInformation'; + NID_protocolInformation = 886; + LN_distinguishedName = 'distinguishedName'; + NID_distinguishedName = 887; + LN_uniqueMember = 'uniqueMember'; + NID_uniqueMember = 888; + LN_houseIdentifier = 'houseIdentifier'; + NID_houseIdentifier = 889; + LN_supportedAlgorithms = 'supportedAlgorithms'; + NID_supportedAlgorithms = 890; + LN_deltaRevocationList = 'deltaRevocationList'; + NID_deltaRevocationList = 891; + SN_dmdName = 'dmdName'; + NID_dmdName = 892; + LN_pseudonym = 'pseudonym'; + NID_pseudonym = 510; + SN_role = 'role'; + LN_role = 'role'; + NID_role = 400; + LN_organizationIdentifier = 'organizationIdentifier'; + NID_organizationIdentifier = 1089; + SN_countryCode3c = 'c3'; + LN_countryCode3c = 'countryCode3c'; + NID_countryCode3c = 1090; + SN_countryCode3n = 'n3'; + LN_countryCode3n = 'countryCode3n'; + NID_countryCode3n = 1091; + LN_dnsName = 'dnsName'; + NID_dnsName = 1092; + SN_X500algorithms = 'X500algorithms'; + LN_X500algorithms = 'directory services - algorithms'; + NID_X500algorithms = 378; + SN_rsa = 'RSA'; + LN_rsa = 'rsa'; + NID_rsa = 19; + SN_mdc2WithRSA = 'RSA-MDC2'; + LN_mdc2WithRSA = 'mdc2WithRSA'; + NID_mdc2WithRSA = 96; + SN_mdc2 = 'MDC2'; + LN_mdc2 = 'mdc2'; + NID_mdc2 = 95; + SN_id_ce = 'id-ce'; + NID_id_ce = 81; + SN_subject_directory_attributes = 'subjectDirectoryAttributes'; + LN_subject_directory_attributes = 'X509v3 Subject Directory Attributes'; + NID_subject_directory_attributes = 769; + SN_subject_key_identifier = 'subjectKeyIdentifier'; + LN_subject_key_identifier = 'X509v3 Subject Key Identifier'; + NID_subject_key_identifier = 82; + SN_key_usage = 'keyUsage'; + LN_key_usage = 'X509v3 Key Usage'; + NID_key_usage = 83; + SN_private_key_usage_period = 'privateKeyUsagePeriod'; + LN_private_key_usage_period = 'X509v3 Private Key Usage Period'; + NID_private_key_usage_period = 84; + SN_subject_alt_name = 'subjectAltName'; + LN_subject_alt_name = 'X509v3 Subject Alternative Name'; + NID_subject_alt_name = 85; + SN_issuer_alt_name = 'issuerAltName'; + LN_issuer_alt_name = 'X509v3 Issuer Alternative Name'; + NID_issuer_alt_name = 86; + SN_basic_constraints = 'basicConstraints'; + LN_basic_constraints = 'X509v3 Basic Constraints'; + NID_basic_constraints = 87; + SN_crl_number = 'crlNumber'; + LN_crl_number = 'X509v3 CRL Number'; + NID_crl_number = 88; + SN_crl_reason = 'CRLReason'; + LN_crl_reason = 'X509v3 CRL Reason Code'; + NID_crl_reason = 141; + SN_invalidity_date = 'invalidityDate'; + LN_invalidity_date = 'Invalidity Date'; + NID_invalidity_date = 142; + SN_delta_crl = 'deltaCRL'; + LN_delta_crl = 'X509v3 Delta CRL Indicator'; + NID_delta_crl = 140; + SN_issuing_distribution_point = 'issuingDistributionPoint'; + LN_issuing_distribution_point = 'X509v3 Issuing Distribution Point'; + NID_issuing_distribution_point = 770; + SN_certificate_issuer = 'certificateIssuer'; + LN_certificate_issuer = 'X509v3 Certificate Issuer'; + NID_certificate_issuer = 771; + SN_name_constraints = 'nameConstraints'; + LN_name_constraints = 'X509v3 Name Constraints'; + NID_name_constraints = 666; + SN_crl_distribution_points = 'crlDistributionPoints'; + LN_crl_distribution_points = 'X509v3 CRL Distribution Points'; + NID_crl_distribution_points = 103; + SN_certificate_policies = 'certificatePolicies'; + LN_certificate_policies = 'X509v3 Certificate Policies'; + NID_certificate_policies = 89; + SN_any_policy = 'anyPolicy'; + LN_any_policy = 'X509v3 Any Policy'; + NID_any_policy = 746; + SN_policy_mappings = 'policyMappings'; + LN_policy_mappings = 'X509v3 Policy Mappings'; + NID_policy_mappings = 747; + SN_authority_key_identifier = 'authorityKeyIdentifier'; + LN_authority_key_identifier = 'X509v3 Authority Key Identifier'; + NID_authority_key_identifier = 90; + SN_policy_constraints = 'policyConstraints'; + LN_policy_constraints = 'X509v3 Policy Constraints'; + NID_policy_constraints = 401; + SN_ext_key_usage = 'extendedKeyUsage'; + LN_ext_key_usage = 'X509v3 Extended Key Usage'; + NID_ext_key_usage = 126; + SN_freshest_crl = 'freshestCRL'; + LN_freshest_crl = 'X509v3 Freshest CRL'; + NID_freshest_crl = 857; + SN_inhibit_any_policy = 'inhibitAnyPolicy'; + LN_inhibit_any_policy = 'X509v3 Inhibit Any Policy'; + NID_inhibit_any_policy = 748; + SN_target_information = 'targetInformation'; + LN_target_information = 'X509v3 AC Targeting'; + NID_target_information = 402; + SN_no_rev_avail = 'noRevAvail'; + LN_no_rev_avail = 'X509v3 No Revocation Available'; + NID_no_rev_avail = 403; + SN_anyExtendedKeyUsage = 'anyExtendedKeyUsage'; + LN_anyExtendedKeyUsage = 'Any Extended Key Usage'; + NID_anyExtendedKeyUsage = 910; + SN_netscape = 'Netscape'; + LN_netscape = 'Netscape Communications Corp.'; + NID_netscape = 57; + SN_netscape_cert_extension = 'nsCertExt'; + LN_netscape_cert_extension = 'Netscape Certificate Extension'; + NID_netscape_cert_extension = 58; + SN_netscape_data_type = 'nsDataType'; + LN_netscape_data_type = 'Netscape Data Type'; + NID_netscape_data_type = 59; + SN_netscape_cert_type = 'nsCertType'; + LN_netscape_cert_type = 'Netscape Cert Type'; + NID_netscape_cert_type = 71; + SN_netscape_base_url = 'nsBaseUrl'; + LN_netscape_base_url = 'Netscape Base Url'; + NID_netscape_base_url = 72; + SN_netscape_revocation_url = 'nsRevocationUrl'; + LN_netscape_revocation_url = 'Netscape Revocation Url'; + NID_netscape_revocation_url = 73; + SN_netscape_ca_revocation_url = 'nsCaRevocationUrl'; + LN_netscape_ca_revocation_url = 'Netscape CA Revocation Url'; + NID_netscape_ca_revocation_url = 74; + SN_netscape_renewal_url = 'nsRenewalUrl'; + LN_netscape_renewal_url = 'Netscape Renewal Url'; + NID_netscape_renewal_url = 75; + SN_netscape_ca_policy_url = 'nsCaPolicyUrl'; + LN_netscape_ca_policy_url = 'Netscape CA Policy Url'; + NID_netscape_ca_policy_url = 76; + SN_netscape_ssl_server_name = 'nsSslServerName'; + LN_netscape_ssl_server_name = 'Netscape SSL Server Name'; + NID_netscape_ssl_server_name = 77; + SN_netscape_comment = 'nsComment'; + LN_netscape_comment = 'Netscape Comment'; + NID_netscape_comment = 78; + SN_netscape_cert_sequence = 'nsCertSequence'; + LN_netscape_cert_sequence = 'Netscape Certificate Sequence'; + NID_netscape_cert_sequence = 79; + SN_ns_sgc = 'nsSGC'; + LN_ns_sgc = 'Netscape Server Gated Crypto'; + NID_ns_sgc = 139; + SN_org = 'ORG'; + LN_org = 'org'; + NID_org = 379; + SN_dod = 'DOD'; + LN_dod = 'dod'; + NID_dod = 380; + SN_iana = 'IANA'; + LN_iana = 'iana'; + NID_iana = 381; + SN_Directory = 'directory'; + LN_Directory = 'Directory'; + NID_Directory = 382; + SN_Management = 'mgmt'; + LN_Management = 'Management'; + NID_Management = 383; + SN_Experimental = 'experimental'; + LN_Experimental = 'Experimental'; + NID_Experimental = 384; + SN_Private = 'private'; + LN_Private = 'Private'; + NID_Private = 385; + SN_Security = 'security'; + LN_Security = 'Security'; + NID_Security = 386; + SN_SNMPv2 = 'snmpv2'; + LN_SNMPv2 = 'SNMPv2'; + NID_SNMPv2 = 387; + LN_Mail = 'Mail'; + NID_Mail = 388; + SN_Enterprises = 'enterprises'; + LN_Enterprises = 'Enterprises'; + NID_Enterprises = 389; + SN_dcObject = 'dcobject'; + LN_dcObject = 'dcObject'; + NID_dcObject = 390; + SN_mime_mhs = 'mime-mhs'; + LN_mime_mhs = 'MIME MHS'; + NID_mime_mhs = 504; + SN_mime_mhs_headings = 'mime-mhs-headings'; + LN_mime_mhs_headings = 'mime-mhs-headings'; + NID_mime_mhs_headings = 505; + SN_mime_mhs_bodies = 'mime-mhs-bodies'; + LN_mime_mhs_bodies = 'mime-mhs-bodies'; + NID_mime_mhs_bodies = 506; + SN_id_hex_partial_message = 'id-hex-partial-message'; + LN_id_hex_partial_message = 'id-hex-partial-message'; + NID_id_hex_partial_message = 507; + SN_id_hex_multipart_message = 'id-hex-multipart-message'; + LN_id_hex_multipart_message = 'id-hex-multipart-message'; + NID_id_hex_multipart_message = 508; + SN_zlib_compression = 'ZLIB'; + LN_zlib_compression = 'zlib compression'; + NID_zlib_compression = 125; + SN_aes_128_ecb = 'AES-128-ECB'; + LN_aes_128_ecb = 'aes-128-ecb'; + NID_aes_128_ecb = 418; + SN_aes_128_cbc = 'AES-128-CBC'; + LN_aes_128_cbc = 'aes-128-cbc'; + NID_aes_128_cbc = 419; + SN_aes_128_ofb128 = 'AES-128-OFB'; + LN_aes_128_ofb128 = 'aes-128-ofb'; + NID_aes_128_ofb128 = 420; + SN_aes_128_cfb128 = 'AES-128-CFB'; + LN_aes_128_cfb128 = 'aes-128-cfb'; + NID_aes_128_cfb128 = 421; + SN_id_aes128_wrap = 'id-aes128-wrap'; + NID_id_aes128_wrap = 788; + SN_aes_128_gcm = 'id-aes128-GCM'; + LN_aes_128_gcm = 'aes-128-gcm'; + NID_aes_128_gcm = 895; + SN_aes_128_ccm = 'id-aes128-CCM'; + LN_aes_128_ccm = 'aes-128-ccm'; + NID_aes_128_ccm = 896; + SN_id_aes128_wrap_pad = 'id-aes128-wrap-pad'; + NID_id_aes128_wrap_pad = 897; + SN_aes_192_ecb = 'AES-192-ECB'; + LN_aes_192_ecb = 'aes-192-ecb'; + NID_aes_192_ecb = 422; + SN_aes_192_cbc = 'AES-192-CBC'; + LN_aes_192_cbc = 'aes-192-cbc'; + NID_aes_192_cbc = 423; + SN_aes_192_ofb128 = 'AES-192-OFB'; + LN_aes_192_ofb128 = 'aes-192-ofb'; + NID_aes_192_ofb128 = 424; + SN_aes_192_cfb128 = 'AES-192-CFB'; + LN_aes_192_cfb128 = 'aes-192-cfb'; + NID_aes_192_cfb128 = 425; + SN_id_aes192_wrap = 'id-aes192-wrap'; + NID_id_aes192_wrap = 789; + SN_aes_192_gcm = 'id-aes192-GCM'; + LN_aes_192_gcm = 'aes-192-gcm'; + NID_aes_192_gcm = 898; + SN_aes_192_ccm = 'id-aes192-CCM'; + LN_aes_192_ccm = 'aes-192-ccm'; + NID_aes_192_ccm = 899; + SN_id_aes192_wrap_pad = 'id-aes192-wrap-pad'; + NID_id_aes192_wrap_pad = 900; + SN_aes_256_ecb = 'AES-256-ECB'; + LN_aes_256_ecb = 'aes-256-ecb'; + NID_aes_256_ecb = 426; + SN_aes_256_cbc = 'AES-256-CBC'; + LN_aes_256_cbc = 'aes-256-cbc'; + NID_aes_256_cbc = 427; + SN_aes_256_ofb128 = 'AES-256-OFB'; + LN_aes_256_ofb128 = 'aes-256-ofb'; + NID_aes_256_ofb128 = 428; + SN_aes_256_cfb128 = 'AES-256-CFB'; + LN_aes_256_cfb128 = 'aes-256-cfb'; + NID_aes_256_cfb128 = 429; + SN_id_aes256_wrap = 'id-aes256-wrap'; + NID_id_aes256_wrap = 790; + SN_aes_256_gcm = 'id-aes256-GCM'; + LN_aes_256_gcm = 'aes-256-gcm'; + NID_aes_256_gcm = 901; + SN_aes_256_ccm = 'id-aes256-CCM'; + LN_aes_256_ccm = 'aes-256-ccm'; + NID_aes_256_ccm = 902; + SN_id_aes256_wrap_pad = 'id-aes256-wrap-pad'; + NID_id_aes256_wrap_pad = 903; + SN_aes_128_xts = 'AES-128-XTS'; + LN_aes_128_xts = 'aes-128-xts'; + NID_aes_128_xts = 913; + SN_aes_256_xts = 'AES-256-XTS'; + LN_aes_256_xts = 'aes-256-xts'; + NID_aes_256_xts = 914; + SN_aes_128_cfb1 = 'AES-128-CFB1'; + LN_aes_128_cfb1 = 'aes-128-cfb1'; + NID_aes_128_cfb1 = 650; + SN_aes_192_cfb1 = 'AES-192-CFB1'; + LN_aes_192_cfb1 = 'aes-192-cfb1'; + NID_aes_192_cfb1 = 651; + SN_aes_256_cfb1 = 'AES-256-CFB1'; + LN_aes_256_cfb1 = 'aes-256-cfb1'; + NID_aes_256_cfb1 = 652; + SN_aes_128_cfb8 = 'AES-128-CFB8'; + LN_aes_128_cfb8 = 'aes-128-cfb8'; + NID_aes_128_cfb8 = 653; + SN_aes_192_cfb8 = 'AES-192-CFB8'; + LN_aes_192_cfb8 = 'aes-192-cfb8'; + NID_aes_192_cfb8 = 654; + SN_aes_256_cfb8 = 'AES-256-CFB8'; + LN_aes_256_cfb8 = 'aes-256-cfb8'; + NID_aes_256_cfb8 = 655; + SN_aes_128_ctr = 'AES-128-CTR'; + LN_aes_128_ctr = 'aes-128-ctr'; + NID_aes_128_ctr = 904; + SN_aes_192_ctr = 'AES-192-CTR'; + LN_aes_192_ctr = 'aes-192-ctr'; + NID_aes_192_ctr = 905; + SN_aes_256_ctr = 'AES-256-CTR'; + LN_aes_256_ctr = 'aes-256-ctr'; + NID_aes_256_ctr = 906; + SN_aes_128_ocb = 'AES-128-OCB'; + LN_aes_128_ocb = 'aes-128-ocb'; + NID_aes_128_ocb = 958; + SN_aes_192_ocb = 'AES-192-OCB'; + LN_aes_192_ocb = 'aes-192-ocb'; + NID_aes_192_ocb = 959; + SN_aes_256_ocb = 'AES-256-OCB'; + LN_aes_256_ocb = 'aes-256-ocb'; + NID_aes_256_ocb = 960; + SN_des_cfb1 = 'DES-CFB1'; + LN_des_cfb1 = 'des-cfb1'; + NID_des_cfb1 = 656; + SN_des_cfb8 = 'DES-CFB8'; + LN_des_cfb8 = 'des-cfb8'; + NID_des_cfb8 = 657; + SN_des_ede3_cfb1 = 'DES-EDE3-CFB1'; + LN_des_ede3_cfb1 = 'des-ede3-cfb1'; + NID_des_ede3_cfb1 = 658; + SN_des_ede3_cfb8 = 'DES-EDE3-CFB8'; + LN_des_ede3_cfb8 = 'des-ede3-cfb8'; + NID_des_ede3_cfb8 = 659; + SN_sha256 = 'SHA256'; + LN_sha256 = 'sha256'; + NID_sha256 = 672; + SN_sha384 = 'SHA384'; + LN_sha384 = 'sha384'; + NID_sha384 = 673; + SN_sha512 = 'SHA512'; + LN_sha512 = 'sha512'; + NID_sha512 = 674; + SN_sha224 = 'SHA224'; + LN_sha224 = 'sha224'; + NID_sha224 = 675; + SN_sha512_224 = 'SHA512-224'; + LN_sha512_224 = 'sha512-224'; + NID_sha512_224 = 1094; + SN_sha512_256 = 'SHA512-256'; + LN_sha512_256 = 'sha512-256'; + NID_sha512_256 = 1095; + SN_sha3_224 = 'SHA3-224'; + LN_sha3_224 = 'sha3-224'; + NID_sha3_224 = 1096; + SN_sha3_256 = 'SHA3-256'; + LN_sha3_256 = 'sha3-256'; + NID_sha3_256 = 1097; + SN_sha3_384 = 'SHA3-384'; + LN_sha3_384 = 'sha3-384'; + NID_sha3_384 = 1098; + SN_sha3_512 = 'SHA3-512'; + LN_sha3_512 = 'sha3-512'; + NID_sha3_512 = 1099; + SN_shake128 = 'SHAKE128'; + LN_shake128 = 'shake128'; + NID_shake128 = 1100; + SN_shake256 = 'SHAKE256'; + LN_shake256 = 'shake256'; + NID_shake256 = 1101; + SN_hmac_sha3_224 = 'id-hmacWithSHA3-224'; + LN_hmac_sha3_224 = 'hmac-sha3-224'; + NID_hmac_sha3_224 = 1102; + SN_hmac_sha3_256 = 'id-hmacWithSHA3-256'; + LN_hmac_sha3_256 = 'hmac-sha3-256'; + NID_hmac_sha3_256 = 1103; + SN_hmac_sha3_384 = 'id-hmacWithSHA3-384'; + LN_hmac_sha3_384 = 'hmac-sha3-384'; + NID_hmac_sha3_384 = 1104; + SN_hmac_sha3_512 = 'id-hmacWithSHA3-512'; + LN_hmac_sha3_512 = 'hmac-sha3-512'; + NID_hmac_sha3_512 = 1105; + SN_dsa_with_SHA224 = 'dsa_with_SHA224'; + NID_dsa_with_SHA224 = 802; + SN_dsa_with_SHA256 = 'dsa_with_SHA256'; + NID_dsa_with_SHA256 = 803; + SN_dsa_with_SHA384 = 'id-dsa-with-sha384'; + LN_dsa_with_SHA384 = 'dsa_with_SHA384'; + NID_dsa_with_SHA384 = 1106; + SN_dsa_with_SHA512 = 'id-dsa-with-sha512'; + LN_dsa_with_SHA512 = 'dsa_with_SHA512'; + NID_dsa_with_SHA512 = 1107; + SN_dsa_with_SHA3_224 = 'id-dsa-with-sha3-224'; + LN_dsa_with_SHA3_224 = 'dsa_with_SHA3-224'; + NID_dsa_with_SHA3_224 = 1108; + SN_dsa_with_SHA3_256 = 'id-dsa-with-sha3-256'; + LN_dsa_with_SHA3_256 = 'dsa_with_SHA3-256'; + NID_dsa_with_SHA3_256 = 1109; + SN_dsa_with_SHA3_384 = 'id-dsa-with-sha3-384'; + LN_dsa_with_SHA3_384 = 'dsa_with_SHA3-384'; + NID_dsa_with_SHA3_384 = 1110; + SN_dsa_with_SHA3_512 = 'id-dsa-with-sha3-512'; + LN_dsa_with_SHA3_512 = 'dsa_with_SHA3-512'; + NID_dsa_with_SHA3_512 = 1111; + SN_ecdsa_with_SHA3_224 = 'id-ecdsa-with-sha3-224'; + LN_ecdsa_with_SHA3_224 = 'ecdsa_with_SHA3-224'; + NID_ecdsa_with_SHA3_224 = 1112; + SN_ecdsa_with_SHA3_256 = 'id-ecdsa-with-sha3-256'; + LN_ecdsa_with_SHA3_256 = 'ecdsa_with_SHA3-256'; + NID_ecdsa_with_SHA3_256 = 1113; + SN_ecdsa_with_SHA3_384 = 'id-ecdsa-with-sha3-384'; + LN_ecdsa_with_SHA3_384 = 'ecdsa_with_SHA3-384'; + NID_ecdsa_with_SHA3_384 = 1114; + SN_ecdsa_with_SHA3_512 = 'id-ecdsa-with-sha3-512'; + LN_ecdsa_with_SHA3_512 = 'ecdsa_with_SHA3-512'; + NID_ecdsa_with_SHA3_512 = 1115; + SN_RSA_SHA3_224 = 'id-rsassa-pkcs1-v1_5-with-sha3-224'; + LN_RSA_SHA3_224 = 'RSA-SHA3-224'; + NID_RSA_SHA3_224 = 1116; + SN_RSA_SHA3_256 = 'id-rsassa-pkcs1-v1_5-with-sha3-256'; + LN_RSA_SHA3_256 = 'RSA-SHA3-256'; + NID_RSA_SHA3_256 = 1117; + SN_RSA_SHA3_384 = 'id-rsassa-pkcs1-v1_5-with-sha3-384'; + LN_RSA_SHA3_384 = 'RSA-SHA3-384'; + NID_RSA_SHA3_384 = 1118; + SN_RSA_SHA3_512 = 'id-rsassa-pkcs1-v1_5-with-sha3-512'; + LN_RSA_SHA3_512 = 'RSA-SHA3-512'; + NID_RSA_SHA3_512 = 1119; + SN_hold_instruction_code = 'holdInstructionCode'; + LN_hold_instruction_code = 'Hold Instruction Code'; + NID_hold_instruction_code = 430; + SN_hold_instruction_none = 'holdInstructionNone'; + LN_hold_instruction_none = 'Hold Instruction None'; + NID_hold_instruction_none = 431; + SN_hold_instruction_call_issuer = 'holdInstructionCallIssuer'; + LN_hold_instruction_call_issuer = 'Hold Instruction Call Issuer'; + NID_hold_instruction_call_issuer = 432; + SN_hold_instruction_reject = 'holdInstructionReject'; + LN_hold_instruction_reject = 'Hold Instruction Reject'; + NID_hold_instruction_reject = 433; + SN_data = 'data'; + NID_data = 434; + SN_pss = 'pss'; + NID_pss = 435; + SN_ucl = 'ucl'; + NID_ucl = 436; + SN_pilot = 'pilot'; + NID_pilot = 437; + LN_pilotAttributeType = 'pilotAttributeType'; + NID_pilotAttributeType = 438; + LN_pilotAttributeSyntax = 'pilotAttributeSyntax'; + NID_pilotAttributeSyntax = 439; + LN_pilotObjectClass = 'pilotObjectClass'; + NID_pilotObjectClass = 440; + LN_pilotGroups = 'pilotGroups'; + NID_pilotGroups = 441; + LN_iA5StringSyntax = 'iA5StringSyntax'; + NID_iA5StringSyntax = 442; + LN_caseIgnoreIA5StringSyntax = 'caseIgnoreIA5StringSyntax'; + NID_caseIgnoreIA5StringSyntax = 443; + LN_pilotObject = 'pilotObject'; + NID_pilotObject = 444; + LN_pilotPerson = 'pilotPerson'; + NID_pilotPerson = 445; + SN_account = 'account'; + NID_account = 446; + SN_document = 'document'; + NID_document = 447; + SN_room = 'room'; + NID_room = 448; + LN_documentSeries = 'documentSeries'; + NID_documentSeries = 449; + SN_Domain = 'domain'; + LN_Domain = 'Domain'; + NID_Domain = 392; + LN_rFC822localPart = 'rFC822localPart'; + NID_rFC822localPart = 450; + LN_dNSDomain = 'dNSDomain'; + NID_dNSDomain = 451; + LN_domainRelatedObject = 'domainRelatedObject'; + NID_domainRelatedObject = 452; + LN_friendlyCountry = 'friendlyCountry'; + NID_friendlyCountry = 453; + LN_simpleSecurityObject = 'simpleSecurityObject'; + NID_simpleSecurityObject = 454; + LN_pilotOrganization = 'pilotOrganization'; + NID_pilotOrganization = 455; + LN_pilotDSA = 'pilotDSA'; + NID_pilotDSA = 456; + LN_qualityLabelledData = 'qualityLabelledData'; + NID_qualityLabelledData = 457; + SN_userId = 'UID'; + LN_userId = 'userId'; + NID_userId = 458; + LN_textEncodedORAddress = 'textEncodedORAddress'; + NID_textEncodedORAddress = 459; + SN_rfc822Mailbox = 'mail'; + LN_rfc822Mailbox = 'rfc822Mailbox'; + NID_rfc822Mailbox = 460; + SN_info = 'info'; + NID_info = 461; + LN_favouriteDrink = 'favouriteDrink'; + NID_favouriteDrink = 462; + LN_roomNumber = 'roomNumber'; + NID_roomNumber = 463; + SN_photo = 'photo'; + NID_photo = 464; + LN_userClass = 'userClass'; + NID_userClass = 465; + SN_host = 'host'; + NID_host = 466; + SN_manager = 'manager'; + NID_manager = 467; + LN_documentIdentifier = 'documentIdentifier'; + NID_documentIdentifier = 468; + LN_documentTitle = 'documentTitle'; + NID_documentTitle = 469; + LN_documentVersion = 'documentVersion'; + NID_documentVersion = 470; + LN_documentAuthor = 'documentAuthor'; + NID_documentAuthor = 471; + LN_documentLocation = 'documentLocation'; + NID_documentLocation = 472; + LN_homeTelephoneNumber = 'homeTelephoneNumber'; + NID_homeTelephoneNumber = 473; + SN_secretary = 'secretary'; + NID_secretary = 474; + LN_otherMailbox = 'otherMailbox'; + NID_otherMailbox = 475; + LN_lastModifiedTime = 'lastModifiedTime'; + NID_lastModifiedTime = 476; + LN_lastModifiedBy = 'lastModifiedBy'; + NID_lastModifiedBy = 477; + SN_domainComponent = 'DC'; + LN_domainComponent = 'domainComponent'; + NID_domainComponent = 391; + LN_aRecord = 'aRecord'; + NID_aRecord = 478; + LN_pilotAttributeType27 = 'pilotAttributeType27'; + NID_pilotAttributeType27 = 479; + LN_mXRecord = 'mXRecord'; + NID_mXRecord = 480; + LN_nSRecord = 'nSRecord'; + NID_nSRecord = 481; + LN_sOARecord = 'sOARecord'; + NID_sOARecord = 482; + LN_cNAMERecord = 'cNAMERecord'; + NID_cNAMERecord = 483; + LN_associatedDomain = 'associatedDomain'; + NID_associatedDomain = 484; + LN_associatedName = 'associatedName'; + NID_associatedName = 485; + LN_homePostalAddress = 'homePostalAddress'; + NID_homePostalAddress = 486; + LN_personalTitle = 'personalTitle'; + NID_personalTitle = 487; + LN_mobileTelephoneNumber = 'mobileTelephoneNumber'; + NID_mobileTelephoneNumber = 488; + LN_pagerTelephoneNumber = 'pagerTelephoneNumber'; + NID_pagerTelephoneNumber = 489; + LN_friendlyCountryName = 'friendlyCountryName'; + NID_friendlyCountryName = 490; + SN_uniqueIdentifier = 'uid'; + LN_uniqueIdentifier = 'uniqueIdentifier'; + NID_uniqueIdentifier = 102; + LN_organizationalStatus = 'organizationalStatus'; + NID_organizationalStatus = 491; + LN_janetMailbox = 'janetMailbox'; + NID_janetMailbox = 492; + LN_mailPreferenceOption = 'mailPreferenceOption'; + NID_mailPreferenceOption = 493; + LN_buildingName = 'buildingName'; + NID_buildingName = 494; + LN_dSAQuality = 'dSAQuality'; + NID_dSAQuality = 495; + LN_singleLevelQuality = 'singleLevelQuality'; + NID_singleLevelQuality = 496; + LN_subtreeMinimumQuality = 'subtreeMinimumQuality'; + NID_subtreeMinimumQuality = 497; + LN_subtreeMaximumQuality = 'subtreeMaximumQuality'; + NID_subtreeMaximumQuality = 498; + LN_personalSignature = 'personalSignature'; + NID_personalSignature = 499; + LN_dITRedirect = 'dITRedirect'; + NID_dITRedirect = 500; + SN_audio = 'audio'; + NID_audio = 501; + LN_documentPublisher = 'documentPublisher'; + NID_documentPublisher = 502; + SN_id_set = 'id-set'; + LN_id_set = 'Secure Electronic Transactions'; + NID_id_set = 512; + SN_set_ctype = 'set-ctype'; + LN_set_ctype = 'content types'; + NID_set_ctype = 513; + SN_set_msgExt = 'set-msgExt'; + LN_set_msgExt = 'message extensions'; + NID_set_msgExt = 514; + SN_set_attr = 'set-attr'; + NID_set_attr = 515; + SN_set_policy = 'set-policy'; + NID_set_policy = 516; + SN_set_certExt = 'set-certExt'; + LN_set_certExt = 'certificate extensions'; + NID_set_certExt = 517; + SN_set_brand = 'set-brand'; + NID_set_brand = 518; + SN_setct_PANData = 'setct-PANData'; + NID_setct_PANData = 519; + SN_setct_PANToken = 'setct-PANToken'; + NID_setct_PANToken = 520; + SN_setct_PANOnly = 'setct-PANOnly'; + NID_setct_PANOnly = 521; + SN_setct_OIData = 'setct-OIData'; + NID_setct_OIData = 522; + SN_setct_PI = 'setct-PI'; + NID_setct_PI = 523; + SN_setct_PIData = 'setct-PIData'; + NID_setct_PIData = 524; + SN_setct_PIDataUnsigned = 'setct-PIDataUnsigned'; + NID_setct_PIDataUnsigned = 525; + SN_setct_HODInput = 'setct-HODInput'; + NID_setct_HODInput = 526; + SN_setct_AuthResBaggage = 'setct-AuthResBaggage'; + NID_setct_AuthResBaggage = 527; + SN_setct_AuthRevReqBaggage = 'setct-AuthRevReqBaggage'; + NID_setct_AuthRevReqBaggage = 528; + SN_setct_AuthRevResBaggage = 'setct-AuthRevResBaggage'; + NID_setct_AuthRevResBaggage = 529; + SN_setct_CapTokenSeq = 'setct-CapTokenSeq'; + NID_setct_CapTokenSeq = 530; + SN_setct_PInitResData = 'setct-PInitResData'; + NID_setct_PInitResData = 531; + SN_setct_PI_TBS = 'setct-PI-TBS'; + NID_setct_PI_TBS = 532; + SN_setct_PResData = 'setct-PResData'; + NID_setct_PResData = 533; + SN_setct_AuthReqTBS = 'setct-AuthReqTBS'; + NID_setct_AuthReqTBS = 534; + SN_setct_AuthResTBS = 'setct-AuthResTBS'; + NID_setct_AuthResTBS = 535; + SN_setct_AuthResTBSX = 'setct-AuthResTBSX'; + NID_setct_AuthResTBSX = 536; + SN_setct_AuthTokenTBS = 'setct-AuthTokenTBS'; + NID_setct_AuthTokenTBS = 537; + SN_setct_CapTokenData = 'setct-CapTokenData'; + NID_setct_CapTokenData = 538; + SN_setct_CapTokenTBS = 'setct-CapTokenTBS'; + NID_setct_CapTokenTBS = 539; + SN_setct_AcqCardCodeMsg = 'setct-AcqCardCodeMsg'; + NID_setct_AcqCardCodeMsg = 540; + SN_setct_AuthRevReqTBS = 'setct-AuthRevReqTBS'; + NID_setct_AuthRevReqTBS = 541; + SN_setct_AuthRevResData = 'setct-AuthRevResData'; + NID_setct_AuthRevResData = 542; + SN_setct_AuthRevResTBS = 'setct-AuthRevResTBS'; + NID_setct_AuthRevResTBS = 543; + SN_setct_CapReqTBS = 'setct-CapReqTBS'; + NID_setct_CapReqTBS = 544; + SN_setct_CapReqTBSX = 'setct-CapReqTBSX'; + NID_setct_CapReqTBSX = 545; + SN_setct_CapResData = 'setct-CapResData'; + NID_setct_CapResData = 546; + SN_setct_CapRevReqTBS = 'setct-CapRevReqTBS'; + NID_setct_CapRevReqTBS = 547; + SN_setct_CapRevReqTBSX = 'setct-CapRevReqTBSX'; + NID_setct_CapRevReqTBSX = 548; + SN_setct_CapRevResData = 'setct-CapRevResData'; + NID_setct_CapRevResData = 549; + SN_setct_CredReqTBS = 'setct-CredReqTBS'; + NID_setct_CredReqTBS = 550; + SN_setct_CredReqTBSX = 'setct-CredReqTBSX'; + NID_setct_CredReqTBSX = 551; + SN_setct_CredResData = 'setct-CredResData'; + NID_setct_CredResData = 552; + SN_setct_CredRevReqTBS = 'setct-CredRevReqTBS'; + NID_setct_CredRevReqTBS = 553; + SN_setct_CredRevReqTBSX = 'setct-CredRevReqTBSX'; + NID_setct_CredRevReqTBSX = 554; + SN_setct_CredRevResData = 'setct-CredRevResData'; + NID_setct_CredRevResData = 555; + SN_setct_PCertReqData = 'setct-PCertReqData'; + NID_setct_PCertReqData = 556; + SN_setct_PCertResTBS = 'setct-PCertResTBS'; + NID_setct_PCertResTBS = 557; + SN_setct_BatchAdminReqData = 'setct-BatchAdminReqData'; + NID_setct_BatchAdminReqData = 558; + SN_setct_BatchAdminResData = 'setct-BatchAdminResData'; + NID_setct_BatchAdminResData = 559; + SN_setct_CardCInitResTBS = 'setct-CardCInitResTBS'; + NID_setct_CardCInitResTBS = 560; + SN_setct_MeAqCInitResTBS = 'setct-MeAqCInitResTBS'; + NID_setct_MeAqCInitResTBS = 561; + SN_setct_RegFormResTBS = 'setct-RegFormResTBS'; + NID_setct_RegFormResTBS = 562; + SN_setct_CertReqData = 'setct-CertReqData'; + NID_setct_CertReqData = 563; + SN_setct_CertReqTBS = 'setct-CertReqTBS'; + NID_setct_CertReqTBS = 564; + SN_setct_CertResData = 'setct-CertResData'; + NID_setct_CertResData = 565; + SN_setct_CertInqReqTBS = 'setct-CertInqReqTBS'; + NID_setct_CertInqReqTBS = 566; + SN_setct_ErrorTBS = 'setct-ErrorTBS'; + NID_setct_ErrorTBS = 567; + SN_setct_PIDualSignedTBE = 'setct-PIDualSignedTBE'; + NID_setct_PIDualSignedTBE = 568; + SN_setct_PIUnsignedTBE = 'setct-PIUnsignedTBE'; + NID_setct_PIUnsignedTBE = 569; + SN_setct_AuthReqTBE = 'setct-AuthReqTBE'; + NID_setct_AuthReqTBE = 570; + SN_setct_AuthResTBE = 'setct-AuthResTBE'; + NID_setct_AuthResTBE = 571; + SN_setct_AuthResTBEX = 'setct-AuthResTBEX'; + NID_setct_AuthResTBEX = 572; + SN_setct_AuthTokenTBE = 'setct-AuthTokenTBE'; + NID_setct_AuthTokenTBE = 573; + SN_setct_CapTokenTBE = 'setct-CapTokenTBE'; + NID_setct_CapTokenTBE = 574; + SN_setct_CapTokenTBEX = 'setct-CapTokenTBEX'; + NID_setct_CapTokenTBEX = 575; + SN_setct_AcqCardCodeMsgTBE = 'setct-AcqCardCodeMsgTBE'; + NID_setct_AcqCardCodeMsgTBE = 576; + SN_setct_AuthRevReqTBE = 'setct-AuthRevReqTBE'; + NID_setct_AuthRevReqTBE = 577; + SN_setct_AuthRevResTBE = 'setct-AuthRevResTBE'; + NID_setct_AuthRevResTBE = 578; + SN_setct_AuthRevResTBEB = 'setct-AuthRevResTBEB'; + NID_setct_AuthRevResTBEB = 579; + SN_setct_CapReqTBE = 'setct-CapReqTBE'; + NID_setct_CapReqTBE = 580; + SN_setct_CapReqTBEX = 'setct-CapReqTBEX'; + NID_setct_CapReqTBEX = 581; + SN_setct_CapResTBE = 'setct-CapResTBE'; + NID_setct_CapResTBE = 582; + SN_setct_CapRevReqTBE = 'setct-CapRevReqTBE'; + NID_setct_CapRevReqTBE = 583; + SN_setct_CapRevReqTBEX = 'setct-CapRevReqTBEX'; + NID_setct_CapRevReqTBEX = 584; + SN_setct_CapRevResTBE = 'setct-CapRevResTBE'; + NID_setct_CapRevResTBE = 585; + SN_setct_CredReqTBE = 'setct-CredReqTBE'; + NID_setct_CredReqTBE = 586; + SN_setct_CredReqTBEX = 'setct-CredReqTBEX'; + NID_setct_CredReqTBEX = 587; + SN_setct_CredResTBE = 'setct-CredResTBE'; + NID_setct_CredResTBE = 588; + SN_setct_CredRevReqTBE = 'setct-CredRevReqTBE'; + NID_setct_CredRevReqTBE = 589; + SN_setct_CredRevReqTBEX = 'setct-CredRevReqTBEX'; + NID_setct_CredRevReqTBEX = 590; + SN_setct_CredRevResTBE = 'setct-CredRevResTBE'; + NID_setct_CredRevResTBE = 591; + SN_setct_BatchAdminReqTBE = 'setct-BatchAdminReqTBE'; + NID_setct_BatchAdminReqTBE = 592; + SN_setct_BatchAdminResTBE = 'setct-BatchAdminResTBE'; + NID_setct_BatchAdminResTBE = 593; + SN_setct_RegFormReqTBE = 'setct-RegFormReqTBE'; + NID_setct_RegFormReqTBE = 594; + SN_setct_CertReqTBE = 'setct-CertReqTBE'; + NID_setct_CertReqTBE = 595; + SN_setct_CertReqTBEX = 'setct-CertReqTBEX'; + NID_setct_CertReqTBEX = 596; + SN_setct_CertResTBE = 'setct-CertResTBE'; + NID_setct_CertResTBE = 597; + SN_setct_CRLNotificationTBS = 'setct-CRLNotificationTBS'; + NID_setct_CRLNotificationTBS = 598; + SN_setct_CRLNotificationResTBS = 'setct-CRLNotificationResTBS'; + NID_setct_CRLNotificationResTBS = 599; + SN_setct_BCIDistributionTBS = 'setct-BCIDistributionTBS'; + NID_setct_BCIDistributionTBS = 600; + SN_setext_genCrypt = 'setext-genCrypt'; + LN_setext_genCrypt = 'generic cryptogram'; + NID_setext_genCrypt = 601; + SN_setext_miAuth = 'setext-miAuth'; + LN_setext_miAuth = 'merchant initiated auth'; + NID_setext_miAuth = 602; + SN_setext_pinSecure = 'setext-pinSecure'; + NID_setext_pinSecure = 603; + SN_setext_pinAny = 'setext-pinAny'; + NID_setext_pinAny = 604; + SN_setext_track2 = 'setext-track2'; + NID_setext_track2 = 605; + SN_setext_cv = 'setext-cv'; + LN_setext_cv = 'additional verification'; + NID_setext_cv = 606; + SN_set_policy_root = 'set-policy-root'; + NID_set_policy_root = 607; + SN_setCext_hashedRoot = 'setCext-hashedRoot'; + NID_setCext_hashedRoot = 608; + SN_setCext_certType = 'setCext-certType'; + NID_setCext_certType = 609; + SN_setCext_merchData = 'setCext-merchData'; + NID_setCext_merchData = 610; + SN_setCext_cCertRequired = 'setCext-cCertRequired'; + NID_setCext_cCertRequired = 611; + SN_setCext_tunneling = 'setCext-tunneling'; + NID_setCext_tunneling = 612; + SN_setCext_setExt = 'setCext-setExt'; + NID_setCext_setExt = 613; + SN_setCext_setQualf = 'setCext-setQualf'; + NID_setCext_setQualf = 614; + SN_setCext_PGWYcapabilities = 'setCext-PGWYcapabilities'; + NID_setCext_PGWYcapabilities = 615; + SN_setCext_TokenIdentifier = 'setCext-TokenIdentifier'; + NID_setCext_TokenIdentifier = 616; + SN_setCext_Track2Data = 'setCext-Track2Data'; + NID_setCext_Track2Data = 617; + SN_setCext_TokenType = 'setCext-TokenType'; + NID_setCext_TokenType = 618; + SN_setCext_IssuerCapabilities = 'setCext-IssuerCapabilities'; + NID_setCext_IssuerCapabilities = 619; + SN_setAttr_Cert = 'setAttr-Cert'; + NID_setAttr_Cert = 620; + SN_setAttr_PGWYcap = 'setAttr-PGWYcap'; + LN_setAttr_PGWYcap = 'payment gateway capabilities'; + NID_setAttr_PGWYcap = 621; + SN_setAttr_TokenType = 'setAttr-TokenType'; + NID_setAttr_TokenType = 622; + SN_setAttr_IssCap = 'setAttr-IssCap'; + LN_setAttr_IssCap = 'issuer capabilities'; + NID_setAttr_IssCap = 623; + SN_set_rootKeyThumb = 'set-rootKeyThumb'; + NID_set_rootKeyThumb = 624; + SN_set_addPolicy = 'set-addPolicy'; + NID_set_addPolicy = 625; + SN_setAttr_Token_EMV = 'setAttr-Token-EMV'; + NID_setAttr_Token_EMV = 626; + SN_setAttr_Token_B0Prime = 'setAttr-Token-B0Prime'; + NID_setAttr_Token_B0Prime = 627; + SN_setAttr_IssCap_CVM = 'setAttr-IssCap-CVM'; + NID_setAttr_IssCap_CVM = 628; + SN_setAttr_IssCap_T2 = 'setAttr-IssCap-T2'; + NID_setAttr_IssCap_T2 = 629; + SN_setAttr_IssCap_Sig = 'setAttr-IssCap-Sig'; + NID_setAttr_IssCap_Sig = 630; + SN_setAttr_GenCryptgrm = 'setAttr-GenCryptgrm'; + LN_setAttr_GenCryptgrm = 'generate cryptogram'; + NID_setAttr_GenCryptgrm = 631; + SN_setAttr_T2Enc = 'setAttr-T2Enc'; + LN_setAttr_T2Enc = 'encrypted track 2'; + NID_setAttr_T2Enc = 632; + SN_setAttr_T2cleartxt = 'setAttr-T2cleartxt'; + LN_setAttr_T2cleartxt = 'cleartext track 2'; + NID_setAttr_T2cleartxt = 633; + SN_setAttr_TokICCsig = 'setAttr-TokICCsig'; + LN_setAttr_TokICCsig = 'ICC or token signature'; + NID_setAttr_TokICCsig = 634; + SN_setAttr_SecDevSig = 'setAttr-SecDevSig'; + LN_setAttr_SecDevSig = 'secure device signature'; + NID_setAttr_SecDevSig = 635; + SN_set_brand_IATA_ATA = 'set-brand-IATA-ATA'; + NID_set_brand_IATA_ATA = 636; + SN_set_brand_Diners = 'set-brand-Diners'; + NID_set_brand_Diners = 637; + SN_set_brand_AmericanExpress = 'set-brand-AmericanExpress'; + NID_set_brand_AmericanExpress = 638; + SN_set_brand_JCB = 'set-brand-JCB'; + NID_set_brand_JCB = 639; + SN_set_brand_Visa = 'set-brand-Visa'; + NID_set_brand_Visa = 640; + SN_set_brand_MasterCard = 'set-brand-MasterCard'; + NID_set_brand_MasterCard = 641; + SN_set_brand_Novus = 'set-brand-Novus'; + NID_set_brand_Novus = 642; + SN_des_cdmf = 'DES-CDMF'; + LN_des_cdmf = 'des-cdmf'; + NID_des_cdmf = 643; + SN_rsaOAEPEncryptionSET = 'rsaOAEPEncryptionSET'; + NID_rsaOAEPEncryptionSET = 644; + SN_ipsec3 = 'Oakley-EC2N-3'; + LN_ipsec3 = 'ipsec3'; + NID_ipsec3 = 749; + SN_ipsec4 = 'Oakley-EC2N-4'; + LN_ipsec4 = 'ipsec4'; + NID_ipsec4 = 750; + SN_whirlpool = 'whirlpool'; + NID_whirlpool = 804; + SN_cryptopro = 'cryptopro'; + NID_cryptopro = 805; + SN_cryptocom = 'cryptocom'; + NID_cryptocom = 806; + SN_id_tc26 = 'id-tc26'; + NID_id_tc26 = 974; + SN_id_GostR3411_94_with_GostR3410_2001 = 'id-GostR3411-94-with-GostR3410-2001'; + LN_id_GostR3411_94_with_GostR3410_2001 = 'GOST R 34.11-94 with GOST R 34.10-2001'; + NID_id_GostR3411_94_with_GostR3410_2001 = 807; + SN_id_GostR3411_94_with_GostR3410_94 = 'id-GostR3411-94-with-GostR3410-94'; + LN_id_GostR3411_94_with_GostR3410_94 = 'GOST R 34.11-94 with GOST R 34.10-94'; + NID_id_GostR3411_94_with_GostR3410_94 = 808; + SN_id_GostR3411_94 = 'md_gost94'; + LN_id_GostR3411_94 = 'GOST R 34.11-94'; + NID_id_GostR3411_94 = 809; + SN_id_HMACGostR3411_94 = 'id-HMACGostR3411-94'; + LN_id_HMACGostR3411_94 = 'HMAC GOST 34.11-94'; + NID_id_HMACGostR3411_94 = 810; + SN_id_GostR3410_2001 = 'gost2001'; + LN_id_GostR3410_2001 = 'GOST R 34.10-2001'; + NID_id_GostR3410_2001 = 811; + SN_id_GostR3410_94 = 'gost94'; + LN_id_GostR3410_94 = 'GOST R 34.10-94'; + NID_id_GostR3410_94 = 812; + SN_id_Gost28147_89 = 'gost89'; + LN_id_Gost28147_89 = 'GOST 28147-89'; + NID_id_Gost28147_89 = 813; + SN_gost89_cnt = 'gost89-cnt'; + NID_gost89_cnt = 814; + SN_gost89_cnt_12 = 'gost89-cnt-12'; + NID_gost89_cnt_12 = 975; + SN_gost89_cbc = 'gost89-cbc'; + NID_gost89_cbc = 1009; + SN_gost89_ecb = 'gost89-ecb'; + NID_gost89_ecb = 1010; + SN_gost89_ctr = 'gost89-ctr'; + NID_gost89_ctr = 1011; + SN_id_Gost28147_89_MAC = 'gost-mac'; + LN_id_Gost28147_89_MAC = 'GOST 28147-89 MAC'; + NID_id_Gost28147_89_MAC = 815; + SN_gost_mac_12 = 'gost-mac-12'; + NID_gost_mac_12 = 976; + SN_id_GostR3411_94_prf = 'prf-gostr3411-94'; + LN_id_GostR3411_94_prf = 'GOST R 34.11-94 PRF'; + NID_id_GostR3411_94_prf = 816; + SN_id_GostR3410_2001DH = 'id-GostR3410-2001DH'; + LN_id_GostR3410_2001DH = 'GOST R 34.10-2001 DH'; + NID_id_GostR3410_2001DH = 817; + SN_id_GostR3410_94DH = 'id-GostR3410-94DH'; + LN_id_GostR3410_94DH = 'GOST R 34.10-94 DH'; + NID_id_GostR3410_94DH = 818; + SN_id_Gost28147_89_CryptoPro_KeyMeshing = 'id-Gost28147-89-CryptoPro-KeyMeshing'; + NID_id_Gost28147_89_CryptoPro_KeyMeshing = 819; + SN_id_Gost28147_89_None_KeyMeshing = 'id-Gost28147-89-None-KeyMeshing'; + NID_id_Gost28147_89_None_KeyMeshing = 820; + SN_id_GostR3411_94_TestParamSet = 'id-GostR3411-94-TestParamSet'; + NID_id_GostR3411_94_TestParamSet = 821; + SN_id_GostR3411_94_CryptoProParamSet = 'id-GostR3411-94-CryptoProParamSet'; + NID_id_GostR3411_94_CryptoProParamSet = 822; + SN_id_Gost28147_89_TestParamSet = 'id-Gost28147-89-TestParamSet'; + NID_id_Gost28147_89_TestParamSet = 823; + SN_id_Gost28147_89_CryptoPro_A_ParamSet = 'id-Gost28147-89-CryptoPro-A-ParamSet'; + NID_id_Gost28147_89_CryptoPro_A_ParamSet = 824; + SN_id_Gost28147_89_CryptoPro_B_ParamSet = 'id-Gost28147-89-CryptoPro-B-ParamSet'; + NID_id_Gost28147_89_CryptoPro_B_ParamSet = 825; + SN_id_Gost28147_89_CryptoPro_C_ParamSet = 'id-Gost28147-89-CryptoPro-C-ParamSet'; + NID_id_Gost28147_89_CryptoPro_C_ParamSet = 826; + SN_id_Gost28147_89_CryptoPro_D_ParamSet = 'id-Gost28147-89-CryptoPro-D-ParamSet'; + NID_id_Gost28147_89_CryptoPro_D_ParamSet = 827; + SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet = 'id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet'; + NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet = 828; + SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet = 'id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet'; + NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet = 829; + SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet = 'id-Gost28147-89-CryptoPro-RIC-1-ParamSet'; + NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet = 830; + SN_id_GostR3410_94_TestParamSet = 'id-GostR3410-94-TestParamSet'; + NID_id_GostR3410_94_TestParamSet = 831; + SN_id_GostR3410_94_CryptoPro_A_ParamSet = 'id-GostR3410-94-CryptoPro-A-ParamSet'; + NID_id_GostR3410_94_CryptoPro_A_ParamSet = 832; + SN_id_GostR3410_94_CryptoPro_B_ParamSet = 'id-GostR3410-94-CryptoPro-B-ParamSet'; + NID_id_GostR3410_94_CryptoPro_B_ParamSet = 833; + SN_id_GostR3410_94_CryptoPro_C_ParamSet = 'id-GostR3410-94-CryptoPro-C-ParamSet'; + NID_id_GostR3410_94_CryptoPro_C_ParamSet = 834; + SN_id_GostR3410_94_CryptoPro_D_ParamSet = 'id-GostR3410-94-CryptoPro-D-ParamSet'; + NID_id_GostR3410_94_CryptoPro_D_ParamSet = 835; + SN_id_GostR3410_94_CryptoPro_XchA_ParamSet = 'id-GostR3410-94-CryptoPro-XchA-ParamSet'; + NID_id_GostR3410_94_CryptoPro_XchA_ParamSet = 836; + SN_id_GostR3410_94_CryptoPro_XchB_ParamSet = 'id-GostR3410-94-CryptoPro-XchB-ParamSet'; + NID_id_GostR3410_94_CryptoPro_XchB_ParamSet = 837; + SN_id_GostR3410_94_CryptoPro_XchC_ParamSet = 'id-GostR3410-94-CryptoPro-XchC-ParamSet'; + NID_id_GostR3410_94_CryptoPro_XchC_ParamSet = 838; + SN_id_GostR3410_2001_TestParamSet = 'id-GostR3410-2001-TestParamSet'; + NID_id_GostR3410_2001_TestParamSet = 839; + SN_id_GostR3410_2001_CryptoPro_A_ParamSet = 'id-GostR3410-2001-CryptoPro-A-ParamSet'; + NID_id_GostR3410_2001_CryptoPro_A_ParamSet = 840; + SN_id_GostR3410_2001_CryptoPro_B_ParamSet = 'id-GostR3410-2001-CryptoPro-B-ParamSet'; + NID_id_GostR3410_2001_CryptoPro_B_ParamSet = 841; + SN_id_GostR3410_2001_CryptoPro_C_ParamSet = 'id-GostR3410-2001-CryptoPro-C-ParamSet'; + NID_id_GostR3410_2001_CryptoPro_C_ParamSet = 842; + SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet = 'id-GostR3410-2001-CryptoPro-XchA-ParamSet'; + NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet = 843; + SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet = 'id-GostR3410-2001-CryptoPro-XchB-ParamSet'; + NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet = 844; + SN_id_GostR3410_94_a = 'id-GostR3410-94-a'; + NID_id_GostR3410_94_a = 845; + SN_id_GostR3410_94_aBis = 'id-GostR3410-94-aBis'; + NID_id_GostR3410_94_aBis = 846; + SN_id_GostR3410_94_b = 'id-GostR3410-94-b'; + NID_id_GostR3410_94_b = 847; + SN_id_GostR3410_94_bBis = 'id-GostR3410-94-bBis'; + NID_id_GostR3410_94_bBis = 848; + SN_id_Gost28147_89_cc = 'id-Gost28147-89-cc'; + LN_id_Gost28147_89_cc = 'GOST 28147-89 Cryptocom ParamSet'; + NID_id_Gost28147_89_cc = 849; + SN_id_GostR3410_94_cc = 'gost94cc'; + LN_id_GostR3410_94_cc = 'GOST 34.10-94 Cryptocom'; + NID_id_GostR3410_94_cc = 850; + SN_id_GostR3410_2001_cc = 'gost2001cc'; + LN_id_GostR3410_2001_cc = 'GOST 34.10-2001 Cryptocom'; + NID_id_GostR3410_2001_cc = 851; + SN_id_GostR3411_94_with_GostR3410_94_cc = 'id-GostR3411-94-with-GostR3410-94-cc'; + LN_id_GostR3411_94_with_GostR3410_94_cc = 'GOST R 34.11-94 with GOST R 34.10-94 Cryptocom'; + NID_id_GostR3411_94_with_GostR3410_94_cc = 852; + SN_id_GostR3411_94_with_GostR3410_2001_cc = 'id-GostR3411-94-with-GostR3410-2001-cc'; + LN_id_GostR3411_94_with_GostR3410_2001_cc = 'GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom'; + NID_id_GostR3411_94_with_GostR3410_2001_cc = 853; + SN_id_GostR3410_2001_ParamSet_cc = 'id-GostR3410-2001-ParamSet-cc'; + LN_id_GostR3410_2001_ParamSet_cc = 'GOST R 3410-2001 Parameter Set Cryptocom'; + NID_id_GostR3410_2001_ParamSet_cc = 854; + SN_id_tc26_algorithms = 'id-tc26-algorithms'; + NID_id_tc26_algorithms = 977; + SN_id_tc26_sign = 'id-tc26-sign'; + NID_id_tc26_sign = 978; + SN_id_GostR3410_2012_256 = 'gost2012_256'; + LN_id_GostR3410_2012_256 = 'GOST R 34.10-2012 with 256 bit modulus'; + NID_id_GostR3410_2012_256 = 979; + SN_id_GostR3410_2012_512 = 'gost2012_512'; + LN_id_GostR3410_2012_512 = 'GOST R 34.10-2012 with 512 bit modulus'; + NID_id_GostR3410_2012_512 = 980; + SN_id_tc26_digest = 'id-tc26-digest'; + NID_id_tc26_digest = 981; + SN_id_GostR3411_2012_256 = 'md_gost12_256'; + LN_id_GostR3411_2012_256 = 'GOST R 34.11-2012 with 256 bit hash'; + NID_id_GostR3411_2012_256 = 982; + SN_id_GostR3411_2012_512 = 'md_gost12_512'; + LN_id_GostR3411_2012_512 = 'GOST R 34.11-2012 with 512 bit hash'; + NID_id_GostR3411_2012_512 = 983; + SN_id_tc26_signwithdigest = 'id-tc26-signwithdigest'; + NID_id_tc26_signwithdigest = 984; + SN_id_tc26_signwithdigest_gost3410_2012_256 = 'id-tc26-signwithdigest-gost3410-2012-256'; + LN_id_tc26_signwithdigest_gost3410_2012_256 = 'GOST R 34.10-2012 with GOST R 34.11-2012 (256 bit)'; + NID_id_tc26_signwithdigest_gost3410_2012_256 = 985; + SN_id_tc26_signwithdigest_gost3410_2012_512 = 'id-tc26-signwithdigest-gost3410-2012-512'; + LN_id_tc26_signwithdigest_gost3410_2012_512 = 'GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)'; + NID_id_tc26_signwithdigest_gost3410_2012_512 = 986; + SN_id_tc26_mac = 'id-tc26-mac'; + NID_id_tc26_mac = 987; + SN_id_tc26_hmac_gost_3411_2012_256 = 'id-tc26-hmac-gost-3411-2012-256'; + LN_id_tc26_hmac_gost_3411_2012_256 = 'HMAC GOST 34.11-2012 256 bit'; + NID_id_tc26_hmac_gost_3411_2012_256 = 988; + SN_id_tc26_hmac_gost_3411_2012_512 = 'id-tc26-hmac-gost-3411-2012-512'; + LN_id_tc26_hmac_gost_3411_2012_512 = 'HMAC GOST 34.11-2012 512 bit'; + NID_id_tc26_hmac_gost_3411_2012_512 = 989; + SN_id_tc26_cipher = 'id-tc26-cipher'; + NID_id_tc26_cipher = 990; + SN_id_tc26_cipher_gostr3412_2015_magma = 'id-tc26-cipher-gostr3412-2015-magma'; + NID_id_tc26_cipher_gostr3412_2015_magma = 1173; + SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm = 'id-tc26-cipher-gostr3412-2015-magma-ctracpkm'; + NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm = 1174; + SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac = 'id-tc26-cipher-gostr3412-2015-magma-ctracpkm-omac'; + NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac = 1175; + SN_id_tc26_cipher_gostr3412_2015_kuznyechik = 'id-tc26-cipher-gostr3412-2015-kuznyechik'; + NID_id_tc26_cipher_gostr3412_2015_kuznyechik = 1176; + SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm = 'id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm'; + NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm = 1177; + SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac = 'id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm-omac'; + NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac = 1178; + SN_id_tc26_agreement = 'id-tc26-agreement'; + NID_id_tc26_agreement = 991; + SN_id_tc26_agreement_gost_3410_2012_256 = 'id-tc26-agreement-gost-3410-2012-256'; + NID_id_tc26_agreement_gost_3410_2012_256 = 992; + SN_id_tc26_agreement_gost_3410_2012_512 = 'id-tc26-agreement-gost-3410-2012-512'; + NID_id_tc26_agreement_gost_3410_2012_512 = 993; + SN_id_tc26_wrap = 'id-tc26-wrap'; + NID_id_tc26_wrap = 1179; + SN_id_tc26_wrap_gostr3412_2015_magma = 'id-tc26-wrap-gostr3412-2015-magma'; + NID_id_tc26_wrap_gostr3412_2015_magma = 1180; + SN_id_tc26_wrap_gostr3412_2015_magma_kexp15 = 'id-tc26-wrap-gostr3412-2015-magma-kexp15'; + NID_id_tc26_wrap_gostr3412_2015_magma_kexp15 = 1181; + SN_id_tc26_wrap_gostr3412_2015_kuznyechik = 'id-tc26-wrap-gostr3412-2015-kuznyechik'; + NID_id_tc26_wrap_gostr3412_2015_kuznyechik = 1182; + SN_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 = 'id-tc26-wrap-gostr3412-2015-kuznyechik-kexp15'; + NID_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 = 1183; + SN_id_tc26_constants = 'id-tc26-constants'; + NID_id_tc26_constants = 994; + SN_id_tc26_sign_constants = 'id-tc26-sign-constants'; + NID_id_tc26_sign_constants = 995; + SN_id_tc26_gost_3410_2012_256_constants = 'id-tc26-gost-3410-2012-256-constants'; + NID_id_tc26_gost_3410_2012_256_constants = 1147; + SN_id_tc26_gost_3410_2012_256_paramSetA = 'id-tc26-gost-3410-2012-256-paramSetA'; + LN_id_tc26_gost_3410_2012_256_paramSetA = 'GOST R 34.10-2012 (256 bit) ParamSet A'; + NID_id_tc26_gost_3410_2012_256_paramSetA = 1148; + SN_id_tc26_gost_3410_2012_256_paramSetB = 'id-tc26-gost-3410-2012-256-paramSetB'; + LN_id_tc26_gost_3410_2012_256_paramSetB = 'GOST R 34.10-2012 (256 bit) ParamSet B'; + NID_id_tc26_gost_3410_2012_256_paramSetB = 1184; + SN_id_tc26_gost_3410_2012_256_paramSetC = 'id-tc26-gost-3410-2012-256-paramSetC'; + LN_id_tc26_gost_3410_2012_256_paramSetC = 'GOST R 34.10-2012 (256 bit) ParamSet C'; + NID_id_tc26_gost_3410_2012_256_paramSetC = 1185; + SN_id_tc26_gost_3410_2012_256_paramSetD = 'id-tc26-gost-3410-2012-256-paramSetD'; + LN_id_tc26_gost_3410_2012_256_paramSetD = 'GOST R 34.10-2012 (256 bit) ParamSet D'; + NID_id_tc26_gost_3410_2012_256_paramSetD = 1186; + SN_id_tc26_gost_3410_2012_512_constants = 'id-tc26-gost-3410-2012-512-constants'; + NID_id_tc26_gost_3410_2012_512_constants = 996; + SN_id_tc26_gost_3410_2012_512_paramSetTest = 'id-tc26-gost-3410-2012-512-paramSetTest'; + LN_id_tc26_gost_3410_2012_512_paramSetTest = 'GOST R 34.10-2012 (512 bit) testing parameter set'; + NID_id_tc26_gost_3410_2012_512_paramSetTest = 997; + SN_id_tc26_gost_3410_2012_512_paramSetA = 'id-tc26-gost-3410-2012-512-paramSetA'; + LN_id_tc26_gost_3410_2012_512_paramSetA = 'GOST R 34.10-2012 (512 bit) ParamSet A'; + NID_id_tc26_gost_3410_2012_512_paramSetA = 998; + SN_id_tc26_gost_3410_2012_512_paramSetB = 'id-tc26-gost-3410-2012-512-paramSetB'; + LN_id_tc26_gost_3410_2012_512_paramSetB = 'GOST R 34.10-2012 (512 bit) ParamSet B'; + NID_id_tc26_gost_3410_2012_512_paramSetB = 999; + SN_id_tc26_gost_3410_2012_512_paramSetC = 'id-tc26-gost-3410-2012-512-paramSetC'; + LN_id_tc26_gost_3410_2012_512_paramSetC = 'GOST R 34.10-2012 (512 bit) ParamSet C'; + NID_id_tc26_gost_3410_2012_512_paramSetC = 1149; + SN_id_tc26_digest_constants = 'id-tc26-digest-constants'; + NID_id_tc26_digest_constants = 1000; + SN_id_tc26_cipher_constants = 'id-tc26-cipher-constants'; + NID_id_tc26_cipher_constants = 1001; + SN_id_tc26_gost_28147_constants = 'id-tc26-gost-28147-constants'; + NID_id_tc26_gost_28147_constants = 1002; + SN_id_tc26_gost_28147_param_Z = 'id-tc26-gost-28147-param-Z'; + LN_id_tc26_gost_28147_param_Z = 'GOST 28147-89 TC26 parameter set'; + NID_id_tc26_gost_28147_param_Z = 1003; + SN_INN = 'INN'; + LN_INN = 'INN'; + NID_INN = 1004; + SN_OGRN = 'OGRN'; + LN_OGRN = 'OGRN'; + NID_OGRN = 1005; + SN_SNILS = 'SNILS'; + LN_SNILS = 'SNILS'; + NID_SNILS = 1006; + SN_subjectSignTool = 'subjectSignTool'; + LN_subjectSignTool = 'Signing Tool of Subject'; + NID_subjectSignTool = 1007; + SN_issuerSignTool = 'issuerSignTool'; + LN_issuerSignTool = 'Signing Tool of Issuer'; + NID_issuerSignTool = 1008; + SN_grasshopper_ecb = 'grasshopper-ecb'; + NID_grasshopper_ecb = 1012; + SN_grasshopper_ctr = 'grasshopper-ctr'; + NID_grasshopper_ctr = 1013; + SN_grasshopper_ofb = 'grasshopper-ofb'; + NID_grasshopper_ofb = 1014; + SN_grasshopper_cbc = 'grasshopper-cbc'; + NID_grasshopper_cbc = 1015; + SN_grasshopper_cfb = 'grasshopper-cfb'; + NID_grasshopper_cfb = 1016; + SN_grasshopper_mac = 'grasshopper-mac'; + NID_grasshopper_mac = 1017; + SN_magma_ecb = 'magma-ecb'; + NID_magma_ecb = 1187; + SN_magma_ctr = 'magma-ctr'; + NID_magma_ctr = 1188; + SN_magma_ofb = 'magma-ofb'; + NID_magma_ofb = 1189; + SN_magma_cbc = 'magma-cbc'; + NID_magma_cbc = 1190; + SN_magma_cfb = 'magma-cfb'; + NID_magma_cfb = 1191; + SN_magma_mac = 'magma-mac'; + NID_magma_mac = 1192; + SN_camellia_128_cbc = 'CAMELLIA-128-CBC'; + LN_camellia_128_cbc = 'camellia-128-cbc'; + NID_camellia_128_cbc = 751; + SN_camellia_192_cbc = 'CAMELLIA-192-CBC'; + LN_camellia_192_cbc = 'camellia-192-cbc'; + NID_camellia_192_cbc = 752; + SN_camellia_256_cbc = 'CAMELLIA-256-CBC'; + LN_camellia_256_cbc = 'camellia-256-cbc'; + NID_camellia_256_cbc = 753; + SN_id_camellia128_wrap = 'id-camellia128-wrap'; + NID_id_camellia128_wrap = 907; + SN_id_camellia192_wrap = 'id-camellia192-wrap'; + NID_id_camellia192_wrap = 908; + SN_id_camellia256_wrap = 'id-camellia256-wrap'; + NID_id_camellia256_wrap = 909; + SN_camellia_128_ecb = 'CAMELLIA-128-ECB'; + LN_camellia_128_ecb = 'camellia-128-ecb'; + NID_camellia_128_ecb = 754; + SN_camellia_128_ofb128 = 'CAMELLIA-128-OFB'; + LN_camellia_128_ofb128 = 'camellia-128-ofb'; + NID_camellia_128_ofb128 = 766; + SN_camellia_128_cfb128 = 'CAMELLIA-128-CFB'; + LN_camellia_128_cfb128 = 'camellia-128-cfb'; + NID_camellia_128_cfb128 = 757; + SN_camellia_128_gcm = 'CAMELLIA-128-GCM'; + LN_camellia_128_gcm = 'camellia-128-gcm'; + NID_camellia_128_gcm = 961; + SN_camellia_128_ccm = 'CAMELLIA-128-CCM'; + LN_camellia_128_ccm = 'camellia-128-ccm'; + NID_camellia_128_ccm = 962; + SN_camellia_128_ctr = 'CAMELLIA-128-CTR'; + LN_camellia_128_ctr = 'camellia-128-ctr'; + NID_camellia_128_ctr = 963; + SN_camellia_128_cmac = 'CAMELLIA-128-CMAC'; + LN_camellia_128_cmac = 'camellia-128-cmac'; + NID_camellia_128_cmac = 964; + SN_camellia_192_ecb = 'CAMELLIA-192-ECB'; + LN_camellia_192_ecb = 'camellia-192-ecb'; + NID_camellia_192_ecb = 755; + SN_camellia_192_ofb128 = 'CAMELLIA-192-OFB'; + LN_camellia_192_ofb128 = 'camellia-192-ofb'; + NID_camellia_192_ofb128 = 767; + SN_camellia_192_cfb128 = 'CAMELLIA-192-CFB'; + LN_camellia_192_cfb128 = 'camellia-192-cfb'; + NID_camellia_192_cfb128 = 758; + SN_camellia_192_gcm = 'CAMELLIA-192-GCM'; + LN_camellia_192_gcm = 'camellia-192-gcm'; + NID_camellia_192_gcm = 965; + SN_camellia_192_ccm = 'CAMELLIA-192-CCM'; + LN_camellia_192_ccm = 'camellia-192-ccm'; + NID_camellia_192_ccm = 966; + SN_camellia_192_ctr = 'CAMELLIA-192-CTR'; + LN_camellia_192_ctr = 'camellia-192-ctr'; + NID_camellia_192_ctr = 967; + SN_camellia_192_cmac = 'CAMELLIA-192-CMAC'; + LN_camellia_192_cmac = 'camellia-192-cmac'; + NID_camellia_192_cmac = 968; + SN_camellia_256_ecb = 'CAMELLIA-256-ECB'; + LN_camellia_256_ecb = 'camellia-256-ecb'; + NID_camellia_256_ecb = 756; + SN_camellia_256_ofb128 = 'CAMELLIA-256-OFB'; + LN_camellia_256_ofb128 = 'camellia-256-ofb'; + NID_camellia_256_ofb128 = 768; + SN_camellia_256_cfb128 = 'CAMELLIA-256-CFB'; + LN_camellia_256_cfb128 = 'camellia-256-cfb'; + NID_camellia_256_cfb128 = 759; + SN_camellia_256_gcm = 'CAMELLIA-256-GCM'; + LN_camellia_256_gcm = 'camellia-256-gcm'; + NID_camellia_256_gcm = 969; + SN_camellia_256_ccm = 'CAMELLIA-256-CCM'; + LN_camellia_256_ccm = 'camellia-256-ccm'; + NID_camellia_256_ccm = 970; + SN_camellia_256_ctr = 'CAMELLIA-256-CTR'; + LN_camellia_256_ctr = 'camellia-256-ctr'; + NID_camellia_256_ctr = 971; + SN_camellia_256_cmac = 'CAMELLIA-256-CMAC'; + LN_camellia_256_cmac = 'camellia-256-cmac'; + NID_camellia_256_cmac = 972; + SN_camellia_128_cfb1 = 'CAMELLIA-128-CFB1'; + LN_camellia_128_cfb1 = 'camellia-128-cfb1'; + NID_camellia_128_cfb1 = 760; + SN_camellia_192_cfb1 = 'CAMELLIA-192-CFB1'; + LN_camellia_192_cfb1 = 'camellia-192-cfb1'; + NID_camellia_192_cfb1 = 761; + SN_camellia_256_cfb1 = 'CAMELLIA-256-CFB1'; + LN_camellia_256_cfb1 = 'camellia-256-cfb1'; + NID_camellia_256_cfb1 = 762; + SN_camellia_128_cfb8 = 'CAMELLIA-128-CFB8'; + LN_camellia_128_cfb8 = 'camellia-128-cfb8'; + NID_camellia_128_cfb8 = 763; + SN_camellia_192_cfb8 = 'CAMELLIA-192-CFB8'; + LN_camellia_192_cfb8 = 'camellia-192-cfb8'; + NID_camellia_192_cfb8 = 764; + SN_camellia_256_cfb8 = 'CAMELLIA-256-CFB8'; + LN_camellia_256_cfb8 = 'camellia-256-cfb8'; + NID_camellia_256_cfb8 = 765; + SN_aria_128_ecb = 'ARIA-128-ECB'; + LN_aria_128_ecb = 'aria-128-ecb'; + NID_aria_128_ecb = 1065; + SN_aria_128_cbc = 'ARIA-128-CBC'; + LN_aria_128_cbc = 'aria-128-cbc'; + NID_aria_128_cbc = 1066; + SN_aria_128_cfb128 = 'ARIA-128-CFB'; + LN_aria_128_cfb128 = 'aria-128-cfb'; + NID_aria_128_cfb128 = 1067; + SN_aria_128_ofb128 = 'ARIA-128-OFB'; + LN_aria_128_ofb128 = 'aria-128-ofb'; + NID_aria_128_ofb128 = 1068; + SN_aria_128_ctr = 'ARIA-128-CTR'; + LN_aria_128_ctr = 'aria-128-ctr'; + NID_aria_128_ctr = 1069; + SN_aria_192_ecb = 'ARIA-192-ECB'; + LN_aria_192_ecb = 'aria-192-ecb'; + NID_aria_192_ecb = 1070; + SN_aria_192_cbc = 'ARIA-192-CBC'; + LN_aria_192_cbc = 'aria-192-cbc'; + NID_aria_192_cbc = 1071; + SN_aria_192_cfb128 = 'ARIA-192-CFB'; + LN_aria_192_cfb128 = 'aria-192-cfb'; + NID_aria_192_cfb128 = 1072; + SN_aria_192_ofb128 = 'ARIA-192-OFB'; + LN_aria_192_ofb128 = 'aria-192-ofb'; + NID_aria_192_ofb128 = 1073; + SN_aria_192_ctr = 'ARIA-192-CTR'; + LN_aria_192_ctr = 'aria-192-ctr'; + NID_aria_192_ctr = 1074; + SN_aria_256_ecb = 'ARIA-256-ECB'; + LN_aria_256_ecb = 'aria-256-ecb'; + NID_aria_256_ecb = 1075; + SN_aria_256_cbc = 'ARIA-256-CBC'; + LN_aria_256_cbc = 'aria-256-cbc'; + NID_aria_256_cbc = 1076; + SN_aria_256_cfb128 = 'ARIA-256-CFB'; + LN_aria_256_cfb128 = 'aria-256-cfb'; + NID_aria_256_cfb128 = 1077; + SN_aria_256_ofb128 = 'ARIA-256-OFB'; + LN_aria_256_ofb128 = 'aria-256-ofb'; + NID_aria_256_ofb128 = 1078; + SN_aria_256_ctr = 'ARIA-256-CTR'; + LN_aria_256_ctr = 'aria-256-ctr'; + NID_aria_256_ctr = 1079; + SN_aria_128_cfb1 = 'ARIA-128-CFB1'; + LN_aria_128_cfb1 = 'aria-128-cfb1'; + NID_aria_128_cfb1 = 1080; + SN_aria_192_cfb1 = 'ARIA-192-CFB1'; + LN_aria_192_cfb1 = 'aria-192-cfb1'; + NID_aria_192_cfb1 = 1081; + SN_aria_256_cfb1 = 'ARIA-256-CFB1'; + LN_aria_256_cfb1 = 'aria-256-cfb1'; + NID_aria_256_cfb1 = 1082; + SN_aria_128_cfb8 = 'ARIA-128-CFB8'; + LN_aria_128_cfb8 = 'aria-128-cfb8'; + NID_aria_128_cfb8 = 1083; + SN_aria_192_cfb8 = 'ARIA-192-CFB8'; + LN_aria_192_cfb8 = 'aria-192-cfb8'; + NID_aria_192_cfb8 = 1084; + SN_aria_256_cfb8 = 'ARIA-256-CFB8'; + LN_aria_256_cfb8 = 'aria-256-cfb8'; + NID_aria_256_cfb8 = 1085; + SN_aria_128_ccm = 'ARIA-128-CCM'; + LN_aria_128_ccm = 'aria-128-ccm'; + NID_aria_128_ccm = 1120; + SN_aria_192_ccm = 'ARIA-192-CCM'; + LN_aria_192_ccm = 'aria-192-ccm'; + NID_aria_192_ccm = 1121; + SN_aria_256_ccm = 'ARIA-256-CCM'; + LN_aria_256_ccm = 'aria-256-ccm'; + NID_aria_256_ccm = 1122; + SN_aria_128_gcm = 'ARIA-128-GCM'; + LN_aria_128_gcm = 'aria-128-gcm'; + NID_aria_128_gcm = 1123; + SN_aria_192_gcm = 'ARIA-192-GCM'; + LN_aria_192_gcm = 'aria-192-gcm'; + NID_aria_192_gcm = 1124; + SN_aria_256_gcm = 'ARIA-256-GCM'; + LN_aria_256_gcm = 'aria-256-gcm'; + NID_aria_256_gcm = 1125; + SN_kisa = 'KISA'; + LN_kisa = 'kisa'; + NID_kisa = 773; + SN_seed_ecb = 'SEED-ECB'; + LN_seed_ecb = 'seed-ecb'; + NID_seed_ecb = 776; + SN_seed_cbc = 'SEED-CBC'; + LN_seed_cbc = 'seed-cbc'; + NID_seed_cbc = 777; + SN_seed_cfb128 = 'SEED-CFB'; + LN_seed_cfb128 = 'seed-cfb'; + NID_seed_cfb128 = 779; + SN_seed_ofb128 = 'SEED-OFB'; + LN_seed_ofb128 = 'seed-ofb'; + NID_seed_ofb128 = 778; + SN_sm4_ecb = 'SM4-ECB'; + LN_sm4_ecb = 'sm4-ecb'; + NID_sm4_ecb = 1133; + SN_sm4_cbc = 'SM4-CBC'; + LN_sm4_cbc = 'sm4-cbc'; + NID_sm4_cbc = 1134; + SN_sm4_ofb128 = 'SM4-OFB'; + LN_sm4_ofb128 = 'sm4-ofb'; + NID_sm4_ofb128 = 1135; + SN_sm4_cfb128 = 'SM4-CFB'; + LN_sm4_cfb128 = 'sm4-cfb'; + NID_sm4_cfb128 = 1137; + SN_sm4_cfb1 = 'SM4-CFB1'; + LN_sm4_cfb1 = 'sm4-cfb1'; + NID_sm4_cfb1 = 1136; + SN_sm4_cfb8 = 'SM4-CFB8'; + LN_sm4_cfb8 = 'sm4-cfb8'; + NID_sm4_cfb8 = 1138; + SN_sm4_ctr = 'SM4-CTR'; + LN_sm4_ctr = 'sm4-ctr'; + NID_sm4_ctr = 1139; + SN_hmac = 'HMAC'; + LN_hmac = 'hmac'; + NID_hmac = 855; + SN_cmac = 'CMAC'; + LN_cmac = 'cmac'; + NID_cmac = 894; + SN_rc4_hmac_md5 = 'RC4-HMAC-MD5'; + LN_rc4_hmac_md5 = 'rc4-hmac-md5'; + NID_rc4_hmac_md5 = 915; + SN_aes_128_cbc_hmac_sha1 = 'AES-128-CBC-HMAC-SHA1'; + LN_aes_128_cbc_hmac_sha1 = 'aes-128-cbc-hmac-sha1'; + NID_aes_128_cbc_hmac_sha1 = 916; + SN_aes_192_cbc_hmac_sha1 = 'AES-192-CBC-HMAC-SHA1'; + LN_aes_192_cbc_hmac_sha1 = 'aes-192-cbc-hmac-sha1'; + NID_aes_192_cbc_hmac_sha1 = 917; + SN_aes_256_cbc_hmac_sha1 = 'AES-256-CBC-HMAC-SHA1'; + LN_aes_256_cbc_hmac_sha1 = 'aes-256-cbc-hmac-sha1'; + NID_aes_256_cbc_hmac_sha1 = 918; + SN_aes_128_cbc_hmac_sha256 = 'AES-128-CBC-HMAC-SHA256'; + LN_aes_128_cbc_hmac_sha256 = 'aes-128-cbc-hmac-sha256'; + NID_aes_128_cbc_hmac_sha256 = 948; + SN_aes_192_cbc_hmac_sha256 = 'AES-192-CBC-HMAC-SHA256'; + LN_aes_192_cbc_hmac_sha256 = 'aes-192-cbc-hmac-sha256'; + NID_aes_192_cbc_hmac_sha256 = 949; + SN_aes_256_cbc_hmac_sha256 = 'AES-256-CBC-HMAC-SHA256'; + LN_aes_256_cbc_hmac_sha256 = 'aes-256-cbc-hmac-sha256'; + NID_aes_256_cbc_hmac_sha256 = 950; + SN_chacha20_poly1305 = 'ChaCha20-Poly1305'; + LN_chacha20_poly1305 = 'chacha20-poly1305'; + NID_chacha20_poly1305 = 1018; + SN_chacha20 = 'ChaCha20'; + LN_chacha20 = 'chacha20'; + NID_chacha20 = 1019; + SN_dhpublicnumber = 'dhpublicnumber'; + LN_dhpublicnumber = 'X9.42 DH'; + NID_dhpublicnumber = 920; + SN_brainpoolP160r1 = 'brainpoolP160r1'; + NID_brainpoolP160r1 = 921; + SN_brainpoolP160t1 = 'brainpoolP160t1'; + NID_brainpoolP160t1 = 922; + SN_brainpoolP192r1 = 'brainpoolP192r1'; + NID_brainpoolP192r1 = 923; + SN_brainpoolP192t1 = 'brainpoolP192t1'; + NID_brainpoolP192t1 = 924; + SN_brainpoolP224r1 = 'brainpoolP224r1'; + NID_brainpoolP224r1 = 925; + SN_brainpoolP224t1 = 'brainpoolP224t1'; + NID_brainpoolP224t1 = 926; + SN_brainpoolP256r1 = 'brainpoolP256r1'; + NID_brainpoolP256r1 = 927; + SN_brainpoolP256t1 = 'brainpoolP256t1'; + NID_brainpoolP256t1 = 928; + SN_brainpoolP320r1 = 'brainpoolP320r1'; + NID_brainpoolP320r1 = 929; + SN_brainpoolP320t1 = 'brainpoolP320t1'; + NID_brainpoolP320t1 = 930; + SN_brainpoolP384r1 = 'brainpoolP384r1'; + NID_brainpoolP384r1 = 931; + SN_brainpoolP384t1 = 'brainpoolP384t1'; + NID_brainpoolP384t1 = 932; + SN_brainpoolP512r1 = 'brainpoolP512r1'; + NID_brainpoolP512r1 = 933; + SN_brainpoolP512t1 = 'brainpoolP512t1'; + NID_brainpoolP512t1 = 934; + SN_dhSinglePass_stdDH_sha1kdf_scheme = 'dhSinglePass-stdDH-sha1kdf-scheme'; + NID_dhSinglePass_stdDH_sha1kdf_scheme = 936; + SN_dhSinglePass_stdDH_sha224kdf_scheme = 'dhSinglePass-stdDH-sha224kdf-scheme'; + NID_dhSinglePass_stdDH_sha224kdf_scheme = 937; + SN_dhSinglePass_stdDH_sha256kdf_scheme = 'dhSinglePass-stdDH-sha256kdf-scheme'; + NID_dhSinglePass_stdDH_sha256kdf_scheme = 938; + SN_dhSinglePass_stdDH_sha384kdf_scheme = 'dhSinglePass-stdDH-sha384kdf-scheme'; + NID_dhSinglePass_stdDH_sha384kdf_scheme = 939; + SN_dhSinglePass_stdDH_sha512kdf_scheme = 'dhSinglePass-stdDH-sha512kdf-scheme'; + NID_dhSinglePass_stdDH_sha512kdf_scheme = 940; + SN_dhSinglePass_cofactorDH_sha1kdf_scheme = 'dhSinglePass-cofactorDH-sha1kdf-scheme'; + NID_dhSinglePass_cofactorDH_sha1kdf_scheme = 941; + SN_dhSinglePass_cofactorDH_sha224kdf_scheme = 'dhSinglePass-cofactorDH-sha224kdf-scheme'; + NID_dhSinglePass_cofactorDH_sha224kdf_scheme = 942; + SN_dhSinglePass_cofactorDH_sha256kdf_scheme = 'dhSinglePass-cofactorDH-sha256kdf-scheme'; + NID_dhSinglePass_cofactorDH_sha256kdf_scheme = 943; + SN_dhSinglePass_cofactorDH_sha384kdf_scheme = 'dhSinglePass-cofactorDH-sha384kdf-scheme'; + NID_dhSinglePass_cofactorDH_sha384kdf_scheme = 944; + SN_dhSinglePass_cofactorDH_sha512kdf_scheme = 'dhSinglePass-cofactorDH-sha512kdf-scheme'; + NID_dhSinglePass_cofactorDH_sha512kdf_scheme = 945; + SN_dh_std_kdf = 'dh-std-kdf'; + NID_dh_std_kdf = 946; + SN_dh_cofactor_kdf = 'dh-cofactor-kdf'; + NID_dh_cofactor_kdf = 947; + SN_ct_precert_scts = 'ct_precert_scts'; + LN_ct_precert_scts = 'CT Precertificate SCTs'; + NID_ct_precert_scts = 951; + SN_ct_precert_poison = 'ct_precert_poison'; + LN_ct_precert_poison = 'CT Precertificate Poison'; + NID_ct_precert_poison = 952; + SN_ct_precert_signer = 'ct_precert_signer'; + LN_ct_precert_signer = 'CT Precertificate Signer'; + NID_ct_precert_signer = 953; + SN_ct_cert_scts = 'ct_cert_scts'; + LN_ct_cert_scts = 'CT Certificate SCTs'; + NID_ct_cert_scts = 954; + SN_jurisdictionLocalityName = 'jurisdictionL'; + LN_jurisdictionLocalityName = 'jurisdictionLocalityName'; + NID_jurisdictionLocalityName = 955; + SN_jurisdictionStateOrProvinceName = 'jurisdictionST'; + LN_jurisdictionStateOrProvinceName = 'jurisdictionStateOrProvinceName'; + NID_jurisdictionStateOrProvinceName = 956; + SN_jurisdictionCountryName = 'jurisdictionC'; + LN_jurisdictionCountryName = 'jurisdictionCountryName'; + NID_jurisdictionCountryName = 957; + SN_id_scrypt = 'id-scrypt'; + LN_id_scrypt = 'scrypt'; + NID_id_scrypt = 973; + SN_tls1_prf = 'TLS1-PRF'; + LN_tls1_prf = 'tls1-prf'; + NID_tls1_prf = 1021; + SN_hkdf = 'HKDF'; + LN_hkdf = 'hkdf'; + NID_hkdf = 1036; + SN_id_pkinit = 'id-pkinit'; + NID_id_pkinit = 1031; + SN_pkInitClientAuth = 'pkInitClientAuth'; + LN_pkInitClientAuth = 'PKINIT Client Auth'; + NID_pkInitClientAuth = 1032; + SN_pkInitKDC = 'pkInitKDC'; + LN_pkInitKDC = 'Signing KDC Response'; + NID_pkInitKDC = 1033; + SN_X25519 = 'X25519'; + NID_X25519 = 1034; + SN_X448 = 'X448'; + NID_X448 = 1035; + SN_ED25519 = 'ED25519'; + NID_ED25519 = 1087; + SN_ED448 = 'ED448'; + NID_ED448 = 1088; + SN_kx_rsa = 'KxRSA'; + LN_kx_rsa = 'kx-rsa'; + NID_kx_rsa = 1037; + SN_kx_ecdhe = 'KxECDHE'; + LN_kx_ecdhe = 'kx-ecdhe'; + NID_kx_ecdhe = 1038; + SN_kx_dhe = 'KxDHE'; + LN_kx_dhe = 'kx-dhe'; + NID_kx_dhe = 1039; + SN_kx_ecdhe_psk = 'KxECDHE-PSK'; + LN_kx_ecdhe_psk = 'kx-ecdhe-psk'; + NID_kx_ecdhe_psk = 1040; + SN_kx_dhe_psk = 'KxDHE-PSK'; + LN_kx_dhe_psk = 'kx-dhe-psk'; + NID_kx_dhe_psk = 1041; + SN_kx_rsa_psk = 'KxRSA_PSK'; + LN_kx_rsa_psk = 'kx-rsa-psk'; + NID_kx_rsa_psk = 1042; + SN_kx_psk = 'KxPSK'; + LN_kx_psk = 'kx-psk'; + NID_kx_psk = 1043; + SN_kx_srp = 'KxSRP'; + LN_kx_srp = 'kx-srp'; + NID_kx_srp = 1044; + SN_kx_gost = 'KxGOST'; + LN_kx_gost = 'kx-gost'; + NID_kx_gost = 1045; + SN_kx_any = 'KxANY'; + LN_kx_any = 'kx-any'; + NID_kx_any = 1063; + SN_auth_rsa = 'AuthRSA'; + LN_auth_rsa = 'auth-rsa'; + NID_auth_rsa = 1046; + SN_auth_ecdsa = 'AuthECDSA'; + LN_auth_ecdsa = 'auth-ecdsa'; + NID_auth_ecdsa = 1047; + SN_auth_psk = 'AuthPSK'; + LN_auth_psk = 'auth-psk'; + NID_auth_psk = 1048; + SN_auth_dss = 'AuthDSS'; + LN_auth_dss = 'auth-dss'; + NID_auth_dss = 1049; + SN_auth_gost01 = 'AuthGOST01'; + LN_auth_gost01 = 'auth-gost01'; + NID_auth_gost01 = 1050; + SN_auth_gost12 = 'AuthGOST12'; + LN_auth_gost12 = 'auth-gost12'; + NID_auth_gost12 = 1051; + SN_auth_srp = 'AuthSRP'; + LN_auth_srp = 'auth-srp'; + NID_auth_srp = 1052; + SN_auth_null = 'AuthNULL'; + LN_auth_null = 'auth-null'; + NID_auth_null = 1053; + SN_auth_any = 'AuthANY'; + LN_auth_any = 'auth-any'; + NID_auth_any = 1064; + SN_poly1305 = 'Poly1305'; + LN_poly1305 = 'poly1305'; + NID_poly1305 = 1061; + SN_siphash = 'SipHash'; + LN_siphash = 'siphash'; + NID_siphash = 1062; + SN_ffdhe2048 = 'ffdhe2048'; + NID_ffdhe2048 = 1126; + SN_ffdhe3072 = 'ffdhe3072'; + NID_ffdhe3072 = 1127; + SN_ffdhe4096 = 'ffdhe4096'; + NID_ffdhe4096 = 1128; + SN_ffdhe6144 = 'ffdhe6144'; + NID_ffdhe6144 = 1129; + SN_ffdhe8192 = 'ffdhe8192'; + NID_ffdhe8192 = 1130; + SN_ISO_UA = 'ISO-UA'; + NID_ISO_UA = 1150; + SN_ua_pki = 'ua-pki'; + NID_ua_pki = 1151; + SN_dstu28147 = 'dstu28147'; + LN_dstu28147 = 'DSTU Gost 28147-2009'; + NID_dstu28147 = 1152; + SN_dstu28147_ofb = 'dstu28147-ofb'; + LN_dstu28147_ofb = 'DSTU Gost 28147-2009 OFB mode'; + NID_dstu28147_ofb = 1153; + SN_dstu28147_cfb = 'dstu28147-cfb'; + LN_dstu28147_cfb = 'DSTU Gost 28147-2009 CFB mode'; + NID_dstu28147_cfb = 1154; + SN_dstu28147_wrap = 'dstu28147-wrap'; + LN_dstu28147_wrap = 'DSTU Gost 28147-2009 key wrap'; + NID_dstu28147_wrap = 1155; + SN_hmacWithDstu34311 = 'hmacWithDstu34311'; + LN_hmacWithDstu34311 = 'HMAC DSTU Gost 34311-95'; + NID_hmacWithDstu34311 = 1156; + SN_dstu34311 = 'dstu34311'; + LN_dstu34311 = 'DSTU Gost 34311-95'; + NID_dstu34311 = 1157; + SN_dstu4145le = 'dstu4145le'; + LN_dstu4145le = 'DSTU 4145-2002 little endian'; + NID_dstu4145le = 1158; + SN_dstu4145be = 'dstu4145be'; + LN_dstu4145be = 'DSTU 4145-2002 big endian'; + NID_dstu4145be = 1159; + SN_uacurve0 = 'uacurve0'; + LN_uacurve0 = 'DSTU curve 0'; + NID_uacurve0 = 1160; + SN_uacurve1 = 'uacurve1'; + LN_uacurve1 = 'DSTU curve 1'; + NID_uacurve1 = 1161; + SN_uacurve2 = 'uacurve2'; + LN_uacurve2 = 'DSTU curve 2'; + NID_uacurve2 = 1162; + SN_uacurve3 = 'uacurve3'; + LN_uacurve3 = 'DSTU curve 3'; + NID_uacurve3 = 1163; + SN_uacurve4 = 'uacurve4'; + LN_uacurve4 = 'DSTU curve 4'; + NID_uacurve4 = 1164; + SN_uacurve5 = 'uacurve5'; + LN_uacurve5 = 'DSTU curve 5'; + NID_uacurve5 = 1165; + SN_uacurve6 = 'uacurve6'; + LN_uacurve6 = 'DSTU curve 6'; + NID_uacurve6 = 1166; + SN_uacurve7 = 'uacurve7'; + LN_uacurve7 = 'DSTU curve 7'; + NID_uacurve7 = 1167; + SN_uacurve8 = 'uacurve8'; + LN_uacurve8 = 'DSTU curve 8'; + NID_uacurve8 = 1168; + SN_uacurve9 = 'uacurve9'; + LN_uacurve9 = 'DSTU curve 9'; + NID_uacurve9 = 1169; + OBJ_F_OBJ_ADD_OBJECT = 105; + OBJ_F_OBJ_ADD_SIGID = 107; + OBJ_F_OBJ_CREATE = 100; + OBJ_F_OBJ_DUP = 101; + OBJ_F_OBJ_NAME_NEW_INDEX = 106; + OBJ_F_OBJ_NID2LN = 102; + OBJ_F_OBJ_NID2OBJ = 103; + OBJ_F_OBJ_NID2SN = 104; + OBJ_F_OBJ_TXT2OBJ = 108; + OBJ_R_OID_EXISTS = 102; + OBJ_R_UNKNOWN_NID = 101; + OBJ_NAME_TYPE_UNDEF = $00; + OBJ_NAME_TYPE_MD_METH = $01; + OBJ_NAME_TYPE_CIPHER_METH = $02; + OBJ_NAME_TYPE_PKEY_METH = $03; + OBJ_NAME_TYPE_COMP_METH = $04; + OBJ_NAME_TYPE_NUM = $05; + OBJ_NAME_ALIAS = $8000; + OBJ_BSEARCH_VALUE_ON_NOMATCH = $01; + OBJ_BSEARCH_FIRST_VALUE_ON_MATCH = $02; + EVP_PK_RSA = $0001; + EVP_PK_DSA = $0002; + EVP_PK_DH = $0004; + EVP_PK_EC = $0008; + EVP_PKT_SIGN = $0010; + EVP_PKT_ENC = $0020; + EVP_PKT_EXCH = $0040; + EVP_PKS_RSA = $0100; + EVP_PKS_DSA = $0200; + EVP_PKS_EC = $0400; + EVP_PKEY_NONE = NID_undef; + EVP_PKEY_RSA = NID_rsaEncryption; + EVP_PKEY_RSA2 = NID_rsa; + EVP_PKEY_RSA_PSS = NID_rsassaPss; + EVP_PKEY_DSA = NID_dsa; + EVP_PKEY_DSA1 = NID_dsa_2; + EVP_PKEY_DSA2 = NID_dsaWithSHA; + EVP_PKEY_DSA3 = NID_dsaWithSHA1; + EVP_PKEY_DSA4 = NID_dsaWithSHA1_2; + EVP_PKEY_DH = NID_dhKeyAgreement; + EVP_PKEY_DHX = NID_dhpublicnumber; + EVP_PKEY_EC = NID_X9_62_id_ecPublicKey; + EVP_PKEY_SM2 = NID_sm2; + EVP_PKEY_HMAC = NID_hmac; + EVP_PKEY_CMAC = NID_cmac; + EVP_PKEY_SCRYPT = NID_id_scrypt; + EVP_PKEY_TLS1_PRF = NID_tls1_prf; + EVP_PKEY_HKDF = NID_hkdf; + EVP_PKEY_POLY1305 = NID_poly1305; + EVP_PKEY_SIPHASH = NID_siphash; + EVP_PKEY_X25519 = NID_X25519; + EVP_PKEY_ED25519 = NID_ED25519; + EVP_PKEY_X448 = NID_X448; + EVP_PKEY_ED448 = NID_ED448; + EVP_PKEY_MO_SIGN = $0001; + EVP_PKEY_MO_VERIFY = $0002; + EVP_PKEY_MO_ENCRYPT = $0004; + EVP_PKEY_MO_DECRYPT = $0008; + EVP_MD_FLAG_ONESHOT = $0001; + EVP_MD_FLAG_XOF = $0002; + EVP_MD_FLAG_DIGALGID_MASK = $0018; + EVP_MD_FLAG_DIGALGID_NULL = $0000; + EVP_MD_FLAG_DIGALGID_ABSENT = $0008; + EVP_MD_FLAG_DIGALGID_CUSTOM = $0018; + EVP_MD_FLAG_FIPS = $0400; + EVP_MD_CTRL_DIGALGID = $1; + EVP_MD_CTRL_MICALG = $2; + EVP_MD_CTRL_XOF_LEN = $3; + EVP_MD_CTRL_ALG_CTRL = $1000; + EVP_MD_CTX_FLAG_ONESHOT = $0001; + EVP_MD_CTX_FLAG_CLEANED = $0002; + EVP_MD_CTX_FLAG_REUSE = $0004; + EVP_MD_CTX_FLAG_NON_FIPS_ALLOW = $0008; + EVP_MD_CTX_FLAG_PAD_MASK = $F0; + EVP_MD_CTX_FLAG_PAD_PKCS1 = $00; + EVP_MD_CTX_FLAG_PAD_X931 = $10; + EVP_MD_CTX_FLAG_PAD_PSS = $20; + EVP_MD_CTX_FLAG_NO_INIT = $0100; + EVP_MD_CTX_FLAG_FINALISE = $0200; + EVP_CIPH_STREAM_CIPHER = $0; + EVP_CIPH_ECB_MODE = $1; + EVP_CIPH_CBC_MODE = $2; + EVP_CIPH_CFB_MODE = $3; + EVP_CIPH_OFB_MODE = $4; + EVP_CIPH_CTR_MODE = $5; + EVP_CIPH_GCM_MODE = $6; + EVP_CIPH_CCM_MODE = $7; + EVP_CIPH_XTS_MODE = $10001; + EVP_CIPH_WRAP_MODE = $10002; + EVP_CIPH_OCB_MODE = $10003; + EVP_CIPH_MODE = $F0007; + EVP_CIPH_VARIABLE_LENGTH = $8; + EVP_CIPH_CUSTOM_IV = $10; + EVP_CIPH_ALWAYS_CALL_INIT = $20; + EVP_CIPH_CTRL_INIT = $40; + EVP_CIPH_CUSTOM_KEY_LENGTH = $80; + EVP_CIPH_NO_PADDING = $100; + EVP_CIPH_RAND_KEY = $200; + EVP_CIPH_CUSTOM_COPY = $400; + EVP_CIPH_CUSTOM_IV_LENGTH = $800; + EVP_CIPH_FLAG_DEFAULT_ASN1 = $1000; + EVP_CIPH_FLAG_LENGTH_BITS = $2000; + EVP_CIPH_FLAG_FIPS = $4000; + EVP_CIPH_FLAG_NON_FIPS_ALLOW = $8000; + EVP_CIPH_FLAG_CUSTOM_CIPHER = $100000; + EVP_CIPH_FLAG_AEAD_CIPHER = $200000; + EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK = $400000; + EVP_CIPH_FLAG_PIPELINE = $800000; + EVP_CIPHER_CTX_FLAG_WRAP_ALLOW = $1; + EVP_CTRL_INIT = $0; + EVP_CTRL_SET_KEY_LENGTH = $1; + EVP_CTRL_GET_RC2_KEY_BITS = $2; + EVP_CTRL_SET_RC2_KEY_BITS = $3; + EVP_CTRL_GET_RC5_ROUNDS = $4; + EVP_CTRL_SET_RC5_ROUNDS = $5; + EVP_CTRL_RAND_KEY = $6; + EVP_CTRL_PBE_PRF_NID = $7; + EVP_CTRL_COPY = $8; + EVP_CTRL_AEAD_SET_IVLEN = $9; + EVP_CTRL_AEAD_GET_TAG = $10; + EVP_CTRL_AEAD_SET_TAG = $11; + EVP_CTRL_AEAD_SET_IV_FIXED = $12; + EVP_CTRL_GCM_SET_IVLEN = EVP_CTRL_AEAD_SET_IVLEN; + EVP_CTRL_GCM_GET_TAG = EVP_CTRL_AEAD_GET_TAG; + EVP_CTRL_GCM_SET_TAG = EVP_CTRL_AEAD_SET_TAG; + EVP_CTRL_GCM_SET_IV_FIXED = EVP_CTRL_AEAD_SET_IV_FIXED; + EVP_CTRL_GCM_IV_GEN = $13; + EVP_CTRL_CCM_SET_IVLEN = EVP_CTRL_AEAD_SET_IVLEN; + EVP_CTRL_CCM_GET_TAG = EVP_CTRL_AEAD_GET_TAG; + EVP_CTRL_CCM_SET_TAG = EVP_CTRL_AEAD_SET_TAG; + EVP_CTRL_CCM_SET_IV_FIXED = EVP_CTRL_AEAD_SET_IV_FIXED; + EVP_CTRL_CCM_SET_L = $14; + EVP_CTRL_CCM_SET_MSGLEN = $15; + EVP_CTRL_AEAD_TLS1_AAD = $16; + EVP_CTRL_AEAD_SET_MAC_KEY = $17; + EVP_CTRL_GCM_SET_IV_INV = $18; + EVP_CTRL_TLS1_1_MULTIBLOCK_AAD = $19; + EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT = $1a; + EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT = $1b; + EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE = $1c; + EVP_CTRL_SSL3_MASTER_SECRET = $1d; + EVP_CTRL_SET_SBOX = $1e; + EVP_CTRL_SBOX_USED = $1f; + EVP_CTRL_KEY_MESH = $20; + EVP_CTRL_BLOCK_PADDING_MODE = $21; + EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS = $22; + EVP_CTRL_SET_PIPELINE_INPUT_BUFS = $23; + EVP_CTRL_SET_PIPELINE_INPUT_LENS = $24; + EVP_CTRL_GET_IVLEN = $25; + EVP_PADDING_PKCS7 = 1; + EVP_PADDING_ISO7816_4 = 2; + EVP_PADDING_ANSI923 = 3; + EVP_PADDING_ISO10126 = 4; + EVP_PADDING_ZERO = 5; + EVP_AEAD_TLS1_AAD_LEN = 13; + EVP_GCM_TLS_FIXED_IV_LEN = 4; + EVP_GCM_TLS_EXPLICIT_IV_LEN = 8; + EVP_GCM_TLS_TAG_LEN = 16; + EVP_CCM_TLS_FIXED_IV_LEN = 4; + EVP_CCM_TLS_EXPLICIT_IV_LEN = 8; + EVP_CCM_TLS_IV_LEN = 12; + EVP_CCM_TLS_TAG_LEN = 16; + EVP_CCM8_TLS_TAG_LEN = 8; + EVP_CHACHAPOLY_TLS_TAG_LEN = 16; + EVP_PBE_TYPE_OUTER = $0; + EVP_PBE_TYPE_PRF = $1; + EVP_PBE_TYPE_KDF = $2; + ASN1_PKEY_ALIAS = $1; + ASN1_PKEY_DYNAMIC = $2; + ASN1_PKEY_SIGPARAM_NULL = $4; + ASN1_PKEY_CTRL_PKCS7_SIGN = $1; + ASN1_PKEY_CTRL_PKCS7_ENCRYPT = $2; + ASN1_PKEY_CTRL_DEFAULT_MD_NID = $3; + ASN1_PKEY_CTRL_CMS_SIGN = $5; + ASN1_PKEY_CTRL_CMS_ENVELOPE = $7; + ASN1_PKEY_CTRL_CMS_RI_TYPE = $8; + ASN1_PKEY_CTRL_SET1_TLS_ENCPT = $9; + ASN1_PKEY_CTRL_GET1_TLS_ENCPT = $a; + EVP_PKEY_OP_UNDEFINED = 0; + EVP_PKEY_OP_PARAMGEN = (1 shl 1); + EVP_PKEY_OP_KEYGEN = (1 shl 2); + EVP_PKEY_OP_SIGN = (1 shl 3); + EVP_PKEY_OP_VERIFY = (1 shl 4); + EVP_PKEY_OP_VERIFYRECOVER = (1 shl 5); + EVP_PKEY_OP_SIGNCTX = (1 shl 6); + EVP_PKEY_OP_VERIFYCTX = (1 shl 7); + EVP_PKEY_OP_ENCRYPT = (1 shl 8); + EVP_PKEY_OP_DECRYPT = (1 shl 9); + EVP_PKEY_OP_DERIVE = (1 shl 10); + EVP_PKEY_OP_TYPE_SIG = (EVP_PKEY_OP_SIGN or EVP_PKEY_OP_VERIFY or EVP_PKEY_OP_VERIFYRECOVER or EVP_PKEY_OP_SIGNCTX or EVP_PKEY_OP_VERIFYCTX); + EVP_PKEY_OP_TYPE_CRYPT = (EVP_PKEY_OP_ENCRYPT or EVP_PKEY_OP_DECRYPT); + EVP_PKEY_OP_TYPE_NOGEN = (EVP_PKEY_OP_TYPE_SIG or EVP_PKEY_OP_TYPE_CRYPT or EVP_PKEY_OP_DERIVE); + EVP_PKEY_OP_TYPE_GEN = (EVP_PKEY_OP_PARAMGEN or EVP_PKEY_OP_KEYGEN); + EVP_PKEY_CTRL_MD = 1; + EVP_PKEY_CTRL_PEER_KEY = 2; + EVP_PKEY_CTRL_PKCS7_ENCRYPT = 3; + EVP_PKEY_CTRL_PKCS7_DECRYPT = 4; + EVP_PKEY_CTRL_PKCS7_SIGN = 5; + EVP_PKEY_CTRL_SET_MAC_KEY = 6; + EVP_PKEY_CTRL_DIGESTINIT = 7; + EVP_PKEY_CTRL_SET_IV = 8; + EVP_PKEY_CTRL_CMS_ENCRYPT = 9; + EVP_PKEY_CTRL_CMS_DECRYPT = 10; + EVP_PKEY_CTRL_CMS_SIGN = 11; + EVP_PKEY_CTRL_CIPHER = 12; + EVP_PKEY_CTRL_GET_MD = 13; + EVP_PKEY_CTRL_SET_DIGEST_SIZE = 14; + EVP_PKEY_ALG_CTRL = $1000; + EVP_PKEY_FLAG_AUTOARGLEN = 2; + EVP_PKEY_FLAG_SIGCTX_CUSTOM = 4; + EC_F_BN_TO_FELEM = 224; + EC_F_D2I_ECPARAMETERS = 144; + EC_F_D2I_ECPKPARAMETERS = 145; + EC_F_D2I_ECPRIVATEKEY = 146; + EC_F_DO_EC_KEY_PRINT = 221; + EC_F_ECDH_CMS_DECRYPT = 238; + EC_F_ECDH_CMS_SET_SHARED_INFO = 239; + EC_F_ECDH_COMPUTE_KEY = 246; + EC_F_ECDH_SIMPLE_COMPUTE_KEY = 257; + EC_F_ECDSA_DO_SIGN_EX = 251; + EC_F_ECDSA_DO_VERIFY = 252; + EC_F_ECDSA_SIGN_EX = 254; + EC_F_ECDSA_SIGN_SETUP = 248; + EC_F_ECDSA_SIG_NEW = 265; + EC_F_ECDSA_VERIFY = 253; + EC_F_ECD_ITEM_VERIFY = 270; + EC_F_ECKEY_PARAM2TYPE = 223; + EC_F_ECKEY_PARAM_DECODE = 212; + EC_F_ECKEY_PRIV_DECODE = 213; + EC_F_ECKEY_PRIV_ENCODE = 214; + EC_F_ECKEY_PUB_DECODE = 215; + EC_F_ECKEY_PUB_ENCODE = 216; + EC_F_ECKEY_TYPE2PARAM = 220; + EC_F_ECPARAMETERS_PRINT = 147; + EC_F_ECPARAMETERS_PRINT_FP = 148; + EC_F_ECPKPARAMETERS_PRINT = 149; + EC_F_ECPKPARAMETERS_PRINT_FP = 150; + EC_F_ECP_NISTZ256_GET_AFFINE = 240; + EC_F_ECP_NISTZ256_INV_MOD_ORD = 275; + EC_F_ECP_NISTZ256_MULT_PRECOMPUTE = 243; + EC_F_ECP_NISTZ256_POINTS_MUL = 241; + EC_F_ECP_NISTZ256_PRE_COMP_NEW = 244; + EC_F_ECP_NISTZ256_WINDOWED_MUL = 242; + EC_F_ECX_KEY_OP = 266; + EC_F_ECX_PRIV_ENCODE = 267; + EC_F_ECX_PUB_ENCODE = 268; + EC_F_EC_ASN1_GROUP2CURVE = 153; + EC_F_EC_ASN1_GROUP2FIELDID = 154; + EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY = 208; + EC_F_EC_GF2M_SIMPLE_FIELD_INV = 296; + EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT = 159; + EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE = 195; + EC_F_EC_GF2M_SIMPLE_LADDER_POST = 285; + EC_F_EC_GF2M_SIMPLE_LADDER_PRE = 288; + EC_F_EC_GF2M_SIMPLE_OCT2POINT = 160; + EC_F_EC_GF2M_SIMPLE_POINT2OCT = 161; + EC_F_EC_GF2M_SIMPLE_POINTS_MUL = 289; + EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES = 162; + EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES = 163; + EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES = 164; + EC_F_EC_GFP_MONT_FIELD_DECODE = 133; + EC_F_EC_GFP_MONT_FIELD_ENCODE = 134; + EC_F_EC_GFP_MONT_FIELD_INV = 297; + EC_F_EC_GFP_MONT_FIELD_MUL = 131; + EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE = 209; + EC_F_EC_GFP_MONT_FIELD_SQR = 132; + EC_F_EC_GFP_MONT_GROUP_SET_CURVE = 189; + EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE = 225; + EC_F_EC_GFP_NISTP224_POINTS_MUL = 228; + EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES = 226; + EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE = 230; + EC_F_EC_GFP_NISTP256_POINTS_MUL = 231; + EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES = 232; + EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE = 233; + EC_F_EC_GFP_NISTP521_POINTS_MUL = 234; + EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES = 235; + EC_F_EC_GFP_NIST_FIELD_MUL = 200; + EC_F_EC_GFP_NIST_FIELD_SQR = 201; + EC_F_EC_GFP_NIST_GROUP_SET_CURVE = 202; + EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES = 287; + EC_F_EC_GFP_SIMPLE_FIELD_INV = 298; + EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT = 165; + EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE = 166; + EC_F_EC_GFP_SIMPLE_MAKE_AFFINE = 102; + EC_F_EC_GFP_SIMPLE_OCT2POINT = 103; + EC_F_EC_GFP_SIMPLE_POINT2OCT = 104; + EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE = 137; + EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES = 167; + EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES = 168; + EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES = 169; + EC_F_EC_GROUP_CHECK = 170; + EC_F_EC_GROUP_CHECK_DISCRIMINANT = 171; + EC_F_EC_GROUP_COPY = 106; + EC_F_EC_GROUP_GET_CURVE = 291; + EC_F_EC_GROUP_GET_CURVE_GF2M = 172; + EC_F_EC_GROUP_GET_CURVE_GFP = 130; + EC_F_EC_GROUP_GET_DEGREE = 173; + EC_F_EC_GROUP_GET_ECPARAMETERS = 261; + EC_F_EC_GROUP_GET_ECPKPARAMETERS = 262; + EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS = 193; + EC_F_EC_GROUP_GET_TRINOMIAL_BASIS = 194; + EC_F_EC_GROUP_NEW = 108; + EC_F_EC_GROUP_NEW_BY_CURVE_NAME = 174; + EC_F_EC_GROUP_NEW_FROM_DATA = 175; + EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS = 263; + EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS = 264; + EC_F_EC_GROUP_SET_CURVE = 292; + EC_F_EC_GROUP_SET_CURVE_GF2M = 176; + EC_F_EC_GROUP_SET_CURVE_GFP = 109; + EC_F_EC_GROUP_SET_GENERATOR = 111; + EC_F_EC_GROUP_SET_SEED = 286; + EC_F_EC_KEY_CHECK_KEY = 177; + EC_F_EC_KEY_COPY = 178; + EC_F_EC_KEY_GENERATE_KEY = 179; + EC_F_EC_KEY_NEW = 182; + EC_F_EC_KEY_NEW_METHOD = 245; + EC_F_EC_KEY_OCT2PRIV = 255; + EC_F_EC_KEY_PRINT = 180; + EC_F_EC_KEY_PRINT_FP = 181; + EC_F_EC_KEY_PRIV2BUF = 279; + EC_F_EC_KEY_PRIV2OCT = 256; + EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES = 229; + EC_F_EC_KEY_SIMPLE_CHECK_KEY = 258; + EC_F_EC_KEY_SIMPLE_OCT2PRIV = 259; + EC_F_EC_KEY_SIMPLE_PRIV2OCT = 260; + EC_F_EC_PKEY_CHECK = 273; + EC_F_EC_PKEY_PARAM_CHECK = 274; + EC_F_EC_POINTS_MAKE_AFFINE = 136; + EC_F_EC_POINTS_MUL = 290; + EC_F_EC_POINT_ADD = 112; + EC_F_EC_POINT_BN2POINT = 280; + EC_F_EC_POINT_CMP = 113; + EC_F_EC_POINT_COPY = 114; + EC_F_EC_POINT_DBL = 115; + EC_F_EC_POINT_GET_AFFINE_COORDINATES = 293; + EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M = 183; + EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP = 116; + EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP = 117; + EC_F_EC_POINT_INVERT = 210; + EC_F_EC_POINT_IS_AT_INFINITY = 118; + EC_F_EC_POINT_IS_ON_CURVE = 119; + EC_F_EC_POINT_MAKE_AFFINE = 120; + EC_F_EC_POINT_NEW = 121; + EC_F_EC_POINT_OCT2POINT = 122; + EC_F_EC_POINT_POINT2BUF = 281; + EC_F_EC_POINT_POINT2OCT = 123; + EC_F_EC_POINT_SET_AFFINE_COORDINATES = 294; + EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M = 185; + EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP = 124; + EC_F_EC_POINT_SET_COMPRESSED_COORDINATES = 295; + EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M = 186; + EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP = 125; + EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP = 126; + EC_F_EC_POINT_SET_TO_INFINITY = 127; + EC_F_EC_PRE_COMP_NEW = 196; + EC_F_EC_SCALAR_MUL_LADDER = 284; + EC_F_EC_WNAF_MUL = 187; + EC_F_EC_WNAF_PRECOMPUTE_MULT = 188; + EC_F_I2D_ECPARAMETERS = 190; + EC_F_I2D_ECPKPARAMETERS = 191; + EC_F_I2D_ECPRIVATEKEY = 192; + EC_F_I2O_ECPUBLICKEY = 151; + EC_F_NISTP224_PRE_COMP_NEW = 227; + EC_F_NISTP256_PRE_COMP_NEW = 236; + EC_F_NISTP521_PRE_COMP_NEW = 237; + EC_F_O2I_ECPUBLICKEY = 152; + EC_F_OLD_EC_PRIV_DECODE = 222; + EC_F_OSSL_ECDH_COMPUTE_KEY = 247; + EC_F_OSSL_ECDSA_SIGN_SIG = 249; + EC_F_OSSL_ECDSA_VERIFY_SIG = 250; + EC_F_PKEY_ECD_CTRL = 271; + EC_F_PKEY_ECD_DIGESTSIGN = 272; + EC_F_PKEY_ECD_DIGESTSIGN25519 = 276; + EC_F_PKEY_ECD_DIGESTSIGN448 = 277; + EC_F_PKEY_ECX_DERIVE = 269; + EC_F_PKEY_EC_CTRL = 197; + EC_F_PKEY_EC_CTRL_STR = 198; + EC_F_PKEY_EC_DERIVE = 217; + EC_F_PKEY_EC_INIT = 282; + EC_F_PKEY_EC_KDF_DERIVE = 283; + EC_F_PKEY_EC_KEYGEN = 199; + EC_F_PKEY_EC_PARAMGEN = 219; + EC_F_PKEY_EC_SIGN = 218; + EC_F_VALIDATE_ECX_DERIVE = 278; + EC_R_ASN1_ERROR = 115; + EC_R_BAD_SIGNATURE = 156; + EC_R_BIGNUM_OUT_OF_RANGE = 144; + EC_R_BUFFER_TOO_SMALL = 100; + EC_R_CANNOT_INVERT = 165; + EC_R_COORDINATES_OUT_OF_RANGE = 146; + EC_R_CURVE_DOES_NOT_SUPPORT_ECDH = 160; + EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING = 159; + EC_R_D2I_ECPKPARAMETERS_FAILURE = 117; + EC_R_DECODE_ERROR = 142; + EC_R_DISCRIMINANT_IS_ZERO = 118; + EC_R_EC_GROUP_NEW_BY_NAME_FAILURE = 119; + EC_R_FIELD_TOO_LARGE = 143; + EC_R_GF2M_NOT_SUPPORTED = 147; + EC_R_GROUP2PKPARAMETERS_FAILURE = 120; + EC_R_I2D_ECPKPARAMETERS_FAILURE = 121; + EC_R_INCOMPATIBLE_OBJECTS = 101; + EC_R_INVALID_ARGUMENT = 112; + EC_R_INVALID_COMPRESSED_POINT = 110; + EC_R_INVALID_COMPRESSION_BIT = 109; + EC_R_INVALID_CURVE = 141; + EC_R_INVALID_DIGEST = 151; + EC_R_INVALID_DIGEST_TYPE = 138; + EC_R_INVALID_ENCODING = 102; + EC_R_INVALID_FIELD = 103; + EC_R_INVALID_FORM = 104; + EC_R_INVALID_GROUP_ORDER = 122; + EC_R_INVALID_KEY = 116; + EC_R_INVALID_OUTPUT_LENGTH = 161; + EC_R_INVALID_PEER_KEY = 133; + EC_R_INVALID_PENTANOMIAL_BASIS = 132; + EC_R_INVALID_PRIVATE_KEY = 123; + EC_R_INVALID_TRINOMIAL_BASIS = 137; + EC_R_KDF_PARAMETER_ERROR = 148; + EC_R_KEYS_NOT_SET = 140; + EC_R_LADDER_POST_FAILURE = 136; + EC_R_LADDER_PRE_FAILURE = 153; + EC_R_LADDER_STEP_FAILURE = 162; + EC_R_MISSING_PARAMETERS = 124; + EC_R_MISSING_PRIVATE_KEY = 125; + EC_R_NEED_NEW_SETUP_VALUES = 157; + EC_R_NOT_A_NIST_PRIME = 135; + EC_R_NOT_IMPLEMENTED = 126; + EC_R_NOT_INITIALIZED = 111; + EC_R_NO_PARAMETERS_SET = 139; + EC_R_NO_PRIVATE_VALUE = 154; + EC_R_OPERATION_NOT_SUPPORTED = 152; + EC_R_PASSED_NULL_PARAMETER = 134; + EC_R_PEER_KEY_ERROR = 149; + EC_R_PKPARAMETERS2GROUP_FAILURE = 127; + EC_R_POINT_ARITHMETIC_FAILURE = 155; + EC_R_POINT_AT_INFINITY = 106; + EC_R_POINT_COORDINATES_BLIND_FAILURE = 163; + EC_R_POINT_IS_NOT_ON_CURVE = 107; + EC_R_RANDOM_NUMBER_GENERATION_FAILED = 158; + EC_R_SHARED_INFO_ERROR = 150; + EC_R_SLOT_FULL = 108; + EC_R_UNDEFINED_GENERATOR = 113; + EC_R_UNDEFINED_ORDER = 128; + EC_R_UNKNOWN_COFACTOR = 164; + EC_R_UNKNOWN_GROUP = 129; + EC_R_UNKNOWN_ORDER = 114; + EC_R_UNSUPPORTED_FIELD = 131; + EC_R_WRONG_CURVE_PARAMETERS = 145; + EC_R_WRONG_ORDER = 130; + OPENSSL_ECC_MAX_FIELD_BITS = 661; + OPENSSL_EC_EXPLICIT_CURVE = $000; + OPENSSL_EC_NAMED_CURVE = $001; + EC_PKEY_NO_PARAMETERS = $001; + EC_PKEY_NO_PUBKEY = $002; + EC_FLAG_NON_FIPS_ALLOW = $1; + EC_FLAG_FIPS_CHECKED = $2; + EC_FLAG_COFACTOR_ECDH = $1000; + EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID = (EVP_PKEY_ALG_CTRL+1); + EVP_PKEY_CTRL_EC_PARAM_ENC = (EVP_PKEY_ALG_CTRL+2); + EVP_PKEY_CTRL_EC_ECDH_COFACTOR = (EVP_PKEY_ALG_CTRL+3); + EVP_PKEY_CTRL_EC_KDF_TYPE = (EVP_PKEY_ALG_CTRL+4); + EVP_PKEY_CTRL_EC_KDF_MD = (EVP_PKEY_ALG_CTRL+5); + EVP_PKEY_CTRL_GET_EC_KDF_MD = (EVP_PKEY_ALG_CTRL+6); + EVP_PKEY_CTRL_EC_KDF_OUTLEN = (EVP_PKEY_ALG_CTRL+7); + EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN = (EVP_PKEY_ALG_CTRL+8); + EVP_PKEY_CTRL_EC_KDF_UKM = (EVP_PKEY_ALG_CTRL+9); + EVP_PKEY_CTRL_GET_EC_KDF_UKM = (EVP_PKEY_ALG_CTRL+10); + EVP_PKEY_CTRL_SET1_ID = (EVP_PKEY_ALG_CTRL+11); + EVP_PKEY_CTRL_GET1_ID = (EVP_PKEY_ALG_CTRL+12); + EVP_PKEY_CTRL_GET1_ID_LEN = (EVP_PKEY_ALG_CTRL+13); + EVP_PKEY_ECDH_KDF_NONE = 1; + EVP_PKEY_ECDH_KDF_X9_63 = 2; + EVP_PKEY_ECDH_KDF_X9_62 = EVP_PKEY_ECDH_KDF_X9_63; + RSA_F_CHECK_PADDING_MD = 140; + RSA_F_ENCODE_PKCS1 = 146; + RSA_F_INT_RSA_VERIFY = 145; + RSA_F_OLD_RSA_PRIV_DECODE = 147; + RSA_F_PKEY_PSS_INIT = 165; + RSA_F_PKEY_RSA_CTRL = 143; + RSA_F_PKEY_RSA_CTRL_STR = 144; + RSA_F_PKEY_RSA_SIGN = 142; + RSA_F_PKEY_RSA_VERIFY = 149; + RSA_F_PKEY_RSA_VERIFYRECOVER = 141; + RSA_F_RSA_ALGOR_TO_MD = 156; + RSA_F_RSA_BUILTIN_KEYGEN = 129; + RSA_F_RSA_CHECK_KEY = 123; + RSA_F_RSA_CHECK_KEY_EX = 160; + RSA_F_RSA_CMS_DECRYPT = 159; + RSA_F_RSA_CMS_VERIFY = 158; + RSA_F_RSA_ITEM_VERIFY = 148; + RSA_F_RSA_METH_DUP = 161; + RSA_F_RSA_METH_NEW = 162; + RSA_F_RSA_METH_SET1_NAME = 163; + RSA_F_RSA_MGF1_TO_MD = 157; + RSA_F_RSA_MULTIP_INFO_NEW = 166; + RSA_F_RSA_NEW_METHOD = 106; + RSA_F_RSA_NULL = 124; + RSA_F_RSA_NULL_PRIVATE_DECRYPT = 132; + RSA_F_RSA_NULL_PRIVATE_ENCRYPT = 133; + RSA_F_RSA_NULL_PUBLIC_DECRYPT = 134; + RSA_F_RSA_NULL_PUBLIC_ENCRYPT = 135; + RSA_F_RSA_OSSL_PRIVATE_DECRYPT = 101; + RSA_F_RSA_OSSL_PRIVATE_ENCRYPT = 102; + RSA_F_RSA_OSSL_PUBLIC_DECRYPT = 103; + RSA_F_RSA_OSSL_PUBLIC_ENCRYPT = 104; + RSA_F_RSA_PADDING_ADD_NONE = 107; + RSA_F_RSA_PADDING_ADD_PKCS1_OAEP = 121; + RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1 = 154; + RSA_F_RSA_PADDING_ADD_PKCS1_PSS = 125; + RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1 = 152; + RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1 = 108; + RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2 = 109; + RSA_F_RSA_PADDING_ADD_SSLV23 = 110; + RSA_F_RSA_PADDING_ADD_X931 = 127; + RSA_F_RSA_PADDING_CHECK_NONE = 111; + RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP = 122; + RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1 = 153; + RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1 = 112; + RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2 = 113; + RSA_F_RSA_PADDING_CHECK_SSLV23 = 114; + RSA_F_RSA_PADDING_CHECK_X931 = 128; + RSA_F_RSA_PARAM_DECODE = 164; + RSA_F_RSA_PRINT = 115; + RSA_F_RSA_PRINT_FP = 116; + RSA_F_RSA_PRIV_DECODE = 150; + RSA_F_RSA_PRIV_ENCODE = 138; + RSA_F_RSA_PSS_GET_PARAM = 151; + RSA_F_RSA_PSS_TO_CTX = 155; + RSA_F_RSA_PUB_DECODE = 139; + RSA_F_RSA_SETUP_BLINDING = 136; + RSA_F_RSA_SIGN = 117; + RSA_F_RSA_SIGN_ASN1_OCTET_STRING = 118; + RSA_F_RSA_VERIFY = 119; + RSA_F_RSA_VERIFY_ASN1_OCTET_STRING = 120; + RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1 = 126; + RSA_F_SETUP_TBUF = 167; + RSA_R_ALGORITHM_MISMATCH = 100; + RSA_R_BAD_E_VALUE = 101; + RSA_R_BAD_FIXED_HEADER_DECRYPT = 102; + RSA_R_BAD_PAD_BYTE_COUNT = 103; + RSA_R_BAD_SIGNATURE = 104; + RSA_R_BLOCK_TYPE_IS_NOT_01 = 106; + RSA_R_BLOCK_TYPE_IS_NOT_02 = 107; + RSA_R_DATA_GREATER_THAN_MOD_LEN = 108; + RSA_R_DATA_TOO_LARGE = 109; + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE = 110; + RSA_R_DATA_TOO_LARGE_FOR_MODULUS = 132; + RSA_R_DATA_TOO_SMALL = 111; + RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE = 122; + RSA_R_DIGEST_DOES_NOT_MATCH = 158; + RSA_R_DIGEST_NOT_ALLOWED = 145; + RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY = 112; + RSA_R_DMP1_NOT_CONGRUENT_TO_D = 124; + RSA_R_DMQ1_NOT_CONGRUENT_TO_D = 125; + RSA_R_D_E_NOT_CONGRUENT_TO_1 = 123; + RSA_R_FIRST_OCTET_INVALID = 133; + RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE = 144; + RSA_R_INVALID_DIGEST = 157; + RSA_R_INVALID_DIGEST_LENGTH = 143; + RSA_R_INVALID_HEADER = 137; + RSA_R_INVALID_LABEL = 160; + RSA_R_INVALID_MESSAGE_LENGTH = 131; + RSA_R_INVALID_MGF1_MD = 156; + RSA_R_INVALID_MULTI_PRIME_KEY = 167; + RSA_R_INVALID_OAEP_PARAMETERS = 161; + RSA_R_INVALID_PADDING = 138; + RSA_R_INVALID_PADDING_MODE = 141; + RSA_R_INVALID_PSS_PARAMETERS = 149; + RSA_R_INVALID_PSS_SALTLEN = 146; + RSA_R_INVALID_SALT_LENGTH = 150; + RSA_R_INVALID_TRAILER = 139; + RSA_R_INVALID_X931_DIGEST = 142; + RSA_R_IQMP_NOT_INVERSE_OF_Q = 126; + RSA_R_KEY_PRIME_NUM_INVALID = 165; + RSA_R_KEY_SIZE_TOO_SMALL = 120; + RSA_R_LAST_OCTET_INVALID = 134; + RSA_R_MISSING_PRIVATE_KEY = 179; + RSA_R_MGF1_DIGEST_NOT_ALLOWED = 152; + RSA_R_MODULUS_TOO_LARGE = 105; + RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R = 168; + RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D = 169; + RSA_R_MP_R_NOT_PRIME = 170; + RSA_R_NO_PUBLIC_EXPONENT = 140; + RSA_R_NULL_BEFORE_BLOCK_MISSING = 113; + RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES = 172; + RSA_R_N_DOES_NOT_EQUAL_P_Q = 127; + RSA_R_OAEP_DECODING_ERROR = 121; + RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE = 148; + RSA_R_PADDING_CHECK_FAILED = 114; + RSA_R_PKCS_DECODING_ERROR = 159; + RSA_R_PSS_SALTLEN_TOO_SMALL = 164; + RSA_R_P_NOT_PRIME = 128; + RSA_R_Q_NOT_PRIME = 129; + RSA_R_RSA_OPERATIONS_NOT_SUPPORTED = 130; + RSA_R_SLEN_CHECK_FAILED = 136; + RSA_R_SLEN_RECOVERY_FAILED = 135; + RSA_R_SSLV3_ROLLBACK_ATTACK = 115; + RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD = 116; + RSA_R_UNKNOWN_ALGORITHM_TYPE = 117; + RSA_R_UNKNOWN_DIGEST = 166; + RSA_R_UNKNOWN_MASK_DIGEST = 151; + RSA_R_UNKNOWN_PADDING_TYPE = 118; + RSA_R_UNSUPPORTED_ENCRYPTION_TYPE = 162; + RSA_R_UNSUPPORTED_LABEL_SOURCE = 163; + RSA_R_UNSUPPORTED_MASK_ALGORITHM = 153; + RSA_R_UNSUPPORTED_MASK_PARAMETER = 154; + RSA_R_UNSUPPORTED_SIGNATURE_TYPE = 155; + RSA_R_VALUE_MISSING = 147; + RSA_R_WRONG_SIGNATURE_LENGTH = 119; + OPENSSL_RSA_MAX_MODULUS_BITS = 16384; + OPENSSL_RSA_FIPS_MIN_MODULUS_BITS = 1024; + OPENSSL_RSA_SMALL_MODULUS_BITS = 3072; + OPENSSL_RSA_MAX_PUBEXP_BITS = 64; + RSA_3 = $3; + RSA_F4 = $10001; + RSA_ASN1_VERSION_DEFAULT = 0; + RSA_ASN1_VERSION_MULTI = 1; + RSA_DEFAULT_PRIME_NUM = 2; + RSA_METHOD_FLAG_NO_CHECK = $0001; + RSA_FLAG_CACHE_PUBLIC = $0002; + RSA_FLAG_CACHE_PRIVATE = $0004; + RSA_FLAG_BLINDING = $0008; + RSA_FLAG_THREAD_SAFE = $0010; + RSA_FLAG_EXT_PKEY = $0020; + RSA_FLAG_NO_BLINDING = $0080; + RSA_FLAG_NO_CONSTTIME = $0000; + RSA_FLAG_NO_EXP_CONSTTIME = RSA_FLAG_NO_CONSTTIME; + RSA_PSS_SALTLEN_DIGEST = -1; + RSA_PSS_SALTLEN_AUTO = -2; + RSA_PSS_SALTLEN_MAX = -3; + RSA_PSS_SALTLEN_MAX_SIGN = -2; + EVP_PKEY_CTRL_RSA_PADDING = (EVP_PKEY_ALG_CTRL+1); + EVP_PKEY_CTRL_RSA_PSS_SALTLEN = (EVP_PKEY_ALG_CTRL+2); + EVP_PKEY_CTRL_RSA_KEYGEN_BITS = (EVP_PKEY_ALG_CTRL+3); + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP = (EVP_PKEY_ALG_CTRL+4); + EVP_PKEY_CTRL_RSA_MGF1_MD = (EVP_PKEY_ALG_CTRL+5); + EVP_PKEY_CTRL_GET_RSA_PADDING = (EVP_PKEY_ALG_CTRL+6); + EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN = (EVP_PKEY_ALG_CTRL+7); + EVP_PKEY_CTRL_GET_RSA_MGF1_MD = (EVP_PKEY_ALG_CTRL+8); + EVP_PKEY_CTRL_RSA_OAEP_MD = (EVP_PKEY_ALG_CTRL+9); + EVP_PKEY_CTRL_RSA_OAEP_LABEL = (EVP_PKEY_ALG_CTRL+10); + EVP_PKEY_CTRL_GET_RSA_OAEP_MD = (EVP_PKEY_ALG_CTRL+11); + EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL = (EVP_PKEY_ALG_CTRL+12); + EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES = (EVP_PKEY_ALG_CTRL+13); + RSA_PKCS1_PADDING = 1; + RSA_SSLV23_PADDING = 2; + RSA_NO_PADDING = 3; + RSA_PKCS1_OAEP_PADDING = 4; + RSA_X931_PADDING = 5; + RSA_PKCS1_PSS_PADDING = 6; + RSA_PKCS1_PADDING_SIZE = 11; + RSA_FLAG_FIPS_METHOD = $0400; + RSA_FLAG_NON_FIPS_ALLOW = $0400; + RSA_FLAG_CHECKED = $0800; + DH_F_COMPUTE_KEY = 102; + DH_F_DHPARAMS_PRINT_FP = 101; + DH_F_DH_BUILTIN_GENPARAMS = 106; + DH_F_DH_CHECK_EX = 121; + DH_F_DH_CHECK_PARAMS_EX = 122; + DH_F_DH_CHECK_PUB_KEY_EX = 123; + DH_F_DH_CMS_DECRYPT = 114; + DH_F_DH_CMS_SET_PEERKEY = 115; + DH_F_DH_CMS_SET_SHARED_INFO = 116; + DH_F_DH_METH_DUP = 117; + DH_F_DH_METH_NEW = 118; + DH_F_DH_METH_SET1_NAME = 119; + DH_F_DH_NEW_BY_NID = 104; + DH_F_DH_NEW_METHOD = 105; + DH_F_DH_PARAM_DECODE = 107; + DH_F_DH_PKEY_PUBLIC_CHECK = 124; + DH_F_DH_PRIV_DECODE = 110; + DH_F_DH_PRIV_ENCODE = 111; + DH_F_DH_PUB_DECODE = 108; + DH_F_DH_PUB_ENCODE = 109; + DH_F_DO_DH_PRINT = 100; + DH_F_GENERATE_KEY = 103; + DH_F_PKEY_DH_CTRL_STR = 120; + DH_F_PKEY_DH_DERIVE = 112; + DH_F_PKEY_DH_INIT = 125; + DH_F_PKEY_DH_KEYGEN = 113; + DH_R_BAD_GENERATOR = 101; + DH_R_BN_DECODE_ERROR = 109; + DH_R_BN_ERROR = 106; + DH_R_CHECK_INVALID_J_VALUE = 115; + DH_R_CHECK_INVALID_Q_VALUE = 116; + DH_R_CHECK_PUBKEY_INVALID = 122; + DH_R_CHECK_PUBKEY_TOO_LARGE = 123; + DH_R_CHECK_PUBKEY_TOO_SMALL = 124; + DH_R_CHECK_P_NOT_PRIME = 117; + DH_R_CHECK_P_NOT_SAFE_PRIME = 118; + DH_R_CHECK_Q_NOT_PRIME = 119; + DH_R_DECODE_ERROR = 104; + DH_R_INVALID_PARAMETER_NAME = 110; + DH_R_INVALID_PARAMETER_NID = 114; + DH_R_INVALID_PUBKEY = 102; + DH_R_KDF_PARAMETER_ERROR = 112; + DH_R_KEYS_NOT_SET = 108; + DH_R_MISSING_PUBKEY = 125; + DH_R_MODULUS_TOO_LARGE = 103; + DH_R_NOT_SUITABLE_GENERATOR = 120; + DH_R_NO_PARAMETERS_SET = 107; + DH_R_NO_PRIVATE_VALUE = 100; + DH_R_PARAMETER_ENCODING_ERROR = 105; + DH_R_PEER_KEY_ERROR = 111; + DH_R_SHARED_INFO_ERROR = 113; + DH_R_UNABLE_TO_CHECK_GENERATOR = 121; + OPENSSL_DH_MAX_MODULUS_BITS = 10000; + OPENSSL_DH_FIPS_MIN_MODULUS_BITS = 1024; + DH_FLAG_CACHE_MONT_P = $01; + DH_FLAG_NO_EXP_CONSTTIME = $00; + DH_FLAG_FIPS_METHOD = $0400; + DH_FLAG_NON_FIPS_ALLOW = $0400; + DH_GENERATOR_2 = 2; + DH_GENERATOR_5 = 5; + DH_CHECK_P_NOT_PRIME = $01; + DH_CHECK_P_NOT_SAFE_PRIME = $02; + DH_UNABLE_TO_CHECK_GENERATOR = $04; + DH_NOT_SUITABLE_GENERATOR = $08; + DH_CHECK_Q_NOT_PRIME = $10; + DH_CHECK_INVALID_Q_VALUE = $20; + DH_CHECK_INVALID_J_VALUE = $40; + DH_CHECK_PUBKEY_TOO_SMALL = $01; + DH_CHECK_PUBKEY_TOO_LARGE = $02; + DH_CHECK_PUBKEY_INVALID = $04; + DH_CHECK_P_NOT_STRONG_PRIME = DH_CHECK_P_NOT_SAFE_PRIME; + EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN = (EVP_PKEY_ALG_CTRL+1); + EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR = (EVP_PKEY_ALG_CTRL+2); + EVP_PKEY_CTRL_DH_RFC5114 = (EVP_PKEY_ALG_CTRL+3); + EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN = (EVP_PKEY_ALG_CTRL+4); + EVP_PKEY_CTRL_DH_PARAMGEN_TYPE = (EVP_PKEY_ALG_CTRL+5); + EVP_PKEY_CTRL_DH_KDF_TYPE = (EVP_PKEY_ALG_CTRL+6); + EVP_PKEY_CTRL_DH_KDF_MD = (EVP_PKEY_ALG_CTRL+7); + EVP_PKEY_CTRL_GET_DH_KDF_MD = (EVP_PKEY_ALG_CTRL+8); + EVP_PKEY_CTRL_DH_KDF_OUTLEN = (EVP_PKEY_ALG_CTRL+9); + EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN = (EVP_PKEY_ALG_CTRL+10); + EVP_PKEY_CTRL_DH_KDF_UKM = (EVP_PKEY_ALG_CTRL+11); + EVP_PKEY_CTRL_GET_DH_KDF_UKM = (EVP_PKEY_ALG_CTRL+12); + EVP_PKEY_CTRL_DH_KDF_OID = (EVP_PKEY_ALG_CTRL+13); + EVP_PKEY_CTRL_GET_DH_KDF_OID = (EVP_PKEY_ALG_CTRL+14); + EVP_PKEY_CTRL_DH_NID = (EVP_PKEY_ALG_CTRL+15); + EVP_PKEY_CTRL_DH_PAD = (EVP_PKEY_ALG_CTRL+16); + EVP_PKEY_DH_KDF_NONE = 1; + EVP_PKEY_DH_KDF_X9_42 = 2; + DSA_F_DSAPARAMS_PRINT = 100; + DSA_F_DSAPARAMS_PRINT_FP = 101; + DSA_F_DSA_BUILTIN_PARAMGEN = 125; + DSA_F_DSA_BUILTIN_PARAMGEN2 = 126; + DSA_F_DSA_DO_SIGN = 112; + DSA_F_DSA_DO_VERIFY = 113; + DSA_F_DSA_METH_DUP = 127; + DSA_F_DSA_METH_NEW = 128; + DSA_F_DSA_METH_SET1_NAME = 129; + DSA_F_DSA_NEW_METHOD = 103; + DSA_F_DSA_PARAM_DECODE = 119; + DSA_F_DSA_PRINT_FP = 105; + DSA_F_DSA_PRIV_DECODE = 115; + DSA_F_DSA_PRIV_ENCODE = 116; + DSA_F_DSA_PUB_DECODE = 117; + DSA_F_DSA_PUB_ENCODE = 118; + DSA_F_DSA_SIGN = 106; + DSA_F_DSA_SIGN_SETUP = 107; + DSA_F_DSA_SIG_NEW = 102; + DSA_F_OLD_DSA_PRIV_DECODE = 122; + DSA_F_PKEY_DSA_CTRL = 120; + DSA_F_PKEY_DSA_CTRL_STR = 104; + DSA_F_PKEY_DSA_KEYGEN = 121; + DSA_R_BAD_Q_VALUE = 102; + DSA_R_BN_DECODE_ERROR = 108; + DSA_R_BN_ERROR = 109; + DSA_R_DECODE_ERROR = 104; + DSA_R_INVALID_DIGEST_TYPE = 106; + DSA_R_INVALID_PARAMETERS = 112; + DSA_R_MISSING_PARAMETERS = 101; + DSA_R_MISSING_PRIVATE_KEY = 111; + DSA_R_MODULUS_TOO_LARGE = 103; + DSA_R_NO_PARAMETERS_SET = 107; + DSA_R_PARAMETER_ENCODING_ERROR = 105; + DSA_R_Q_NOT_PRIME = 113; + DSA_R_SEED_LEN_SMALL = 110; + OPENSSL_DSA_MAX_MODULUS_BITS = 10000; + OPENSSL_DSA_FIPS_MIN_MODULUS_BITS = 1024; + DSA_FLAG_CACHE_MONT_P = $01; + DSA_FLAG_NO_EXP_CONSTTIME = $00; + DSA_FLAG_FIPS_METHOD = $0400; + DSA_FLAG_NON_FIPS_ALLOW = $0400; + DSA_FLAG_FIPS_CHECKED = $0800; + DSS_prime_checks = 64; + EVP_PKEY_CTRL_DSA_PARAMGEN_BITS = (EVP_PKEY_ALG_CTRL+1); + EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS = (EVP_PKEY_ALG_CTRL+2); + EVP_PKEY_CTRL_DSA_PARAMGEN_MD = (EVP_PKEY_ALG_CTRL+3); + SHA_LBLOCK = 16; + SHA_CBLOCK = (SHA_LBLOCK*4); + SHA_LAST_BLOCK = (SHA_CBLOCK-8); + SHA_DIGEST_LENGTH = 20; + SHA256_CBLOCK = (SHA_LBLOCK*4); + SHA224_DIGEST_LENGTH = 28; + SHA256_DIGEST_LENGTH = 32; + SHA384_DIGEST_LENGTH = 48; + SHA512_DIGEST_LENGTH = 64; + SHA512_CBLOCK = (SHA_LBLOCK*8); + X509_F_ADD_CERT_DIR = 100; + X509_F_BUILD_CHAIN = 106; + X509_F_BY_FILE_CTRL = 101; + X509_F_CHECK_NAME_CONSTRAINTS = 149; + X509_F_CHECK_POLICY = 145; + X509_F_DANE_I2D = 107; + X509_F_DIR_CTRL = 102; + X509_F_GET_CERT_BY_SUBJECT = 103; + X509_F_I2D_X509_AUX = 151; + X509_F_LOOKUP_CERTS_SK = 152; + X509_F_NETSCAPE_SPKI_B64_DECODE = 129; + X509_F_NETSCAPE_SPKI_B64_ENCODE = 130; + X509_F_NEW_DIR = 153; + X509_F_X509AT_ADD1_ATTR = 135; + X509_F_X509V3_ADD_EXT = 104; + X509_F_X509_ATTRIBUTE_CREATE_BY_NID = 136; + X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ = 137; + X509_F_X509_ATTRIBUTE_CREATE_BY_TXT = 140; + X509_F_X509_ATTRIBUTE_GET0_DATA = 139; + X509_F_X509_ATTRIBUTE_SET1_DATA = 138; + X509_F_X509_CHECK_PRIVATE_KEY = 128; + X509_F_X509_CRL_DIFF = 105; + X509_F_X509_CRL_METHOD_NEW = 154; + X509_F_X509_CRL_PRINT_FP = 147; + X509_F_X509_EXTENSION_CREATE_BY_NID = 108; + X509_F_X509_EXTENSION_CREATE_BY_OBJ = 109; + X509_F_X509_GET_PUBKEY_PARAMETERS = 110; + X509_F_X509_LOAD_CERT_CRL_FILE = 132; + X509_F_X509_LOAD_CERT_FILE = 111; + X509_F_X509_LOAD_CRL_FILE = 112; + X509_F_X509_LOOKUP_METH_NEW = 160; + X509_F_X509_LOOKUP_NEW = 155; + X509_F_X509_NAME_ADD_ENTRY = 113; + X509_F_X509_NAME_CANON = 156; + X509_F_X509_NAME_ENTRY_CREATE_BY_NID = 114; + X509_F_X509_NAME_ENTRY_CREATE_BY_TXT = 131; + X509_F_X509_NAME_ENTRY_SET_OBJECT = 115; + X509_F_X509_NAME_ONELINE = 116; + X509_F_X509_NAME_PRINT = 117; + X509_F_X509_OBJECT_NEW = 150; + X509_F_X509_PRINT_EX_FP = 118; + X509_F_X509_PUBKEY_DECODE = 148; + X509_F_X509_PUBKEY_GET0 = 119; + X509_F_X509_PUBKEY_SET = 120; + X509_F_X509_REQ_CHECK_PRIVATE_KEY = 144; + X509_F_X509_REQ_PRINT_EX = 121; + X509_F_X509_REQ_PRINT_FP = 122; + X509_F_X509_REQ_TO_X509 = 123; + X509_F_X509_STORE_ADD_CERT = 124; + X509_F_X509_STORE_ADD_CRL = 125; + X509_F_X509_STORE_ADD_LOOKUP = 157; + X509_F_X509_STORE_CTX_GET1_ISSUER = 146; + X509_F_X509_STORE_CTX_INIT = 143; + X509_F_X509_STORE_CTX_NEW = 142; + X509_F_X509_STORE_CTX_PURPOSE_INHERIT = 134; + X509_F_X509_STORE_NEW = 158; + X509_F_X509_TO_X509_REQ = 126; + X509_F_X509_TRUST_ADD = 133; + X509_F_X509_TRUST_SET = 141; + X509_F_X509_VERIFY_CERT = 127; + X509_F_X509_VERIFY_PARAM_NEW = 159; + X509_R_AKID_MISMATCH = 110; + X509_R_BAD_SELECTOR = 133; + X509_R_BAD_X509_FILETYPE = 100; + X509_R_BASE64_DECODE_ERROR = 118; + X509_R_CANT_CHECK_DH_KEY = 114; + X509_R_CERT_ALREADY_IN_HASH_TABLE = 101; + X509_R_CRL_ALREADY_DELTA = 127; + X509_R_CRL_VERIFY_FAILURE = 131; + X509_R_IDP_MISMATCH = 128; + X509_R_INVALID_ATTRIBUTES = 138; + X509_R_INVALID_DIRECTORY = 113; + X509_R_INVALID_FIELD_NAME = 119; + X509_R_INVALID_TRUST = 123; + X509_R_ISSUER_MISMATCH = 129; + X509_R_KEY_TYPE_MISMATCH = 115; + X509_R_KEY_VALUES_MISMATCH = 116; + X509_R_LOADING_CERT_DIR = 103; + X509_R_LOADING_DEFAULTS = 104; + X509_R_METHOD_NOT_SUPPORTED = 124; + X509_R_NAME_TOO_LONG = 134; + X509_R_NEWER_CRL_NOT_NEWER = 132; + X509_R_NO_CERTIFICATE_FOUND = 135; + X509_R_NO_CERTIFICATE_OR_CRL_FOUND = 136; + X509_R_NO_CERT_SET_FOR_US_TO_VERIFY = 105; + X509_R_NO_CRL_FOUND = 137; + X509_R_NO_CRL_NUMBER = 130; + X509_R_PUBLIC_KEY_DECODE_ERROR = 125; + X509_R_PUBLIC_KEY_ENCODE_ERROR = 126; + X509_R_SHOULD_RETRY = 106; + X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN = 107; + X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY = 108; + X509_R_UNKNOWN_KEY_TYPE = 117; + X509_R_UNKNOWN_NID = 109; + X509_R_UNKNOWN_PURPOSE_ID = 121; + X509_R_UNKNOWN_TRUST_ID = 120; + X509_R_UNSUPPORTED_ALGORITHM = 111; + X509_R_WRONG_LOOKUP_TYPE = 112; + X509_R_WRONG_TYPE = 122; + X509_SIG_INFO_VALID = $1; + X509_SIG_INFO_TLS = $2; + X509_FILETYPE_PEM = 1; + X509_FILETYPE_ASN1 = 2; + X509_FILETYPE_DEFAULT = 3; + X509v3_KU_DIGITAL_SIGNATURE = $0080; + X509v3_KU_NON_REPUDIATION = $0040; + X509v3_KU_KEY_ENCIPHERMENT = $0020; + X509v3_KU_DATA_ENCIPHERMENT = $0010; + X509v3_KU_KEY_AGREEMENT = $0008; + X509v3_KU_KEY_CERT_SIGN = $0004; + X509v3_KU_CRL_SIGN = $0002; + X509v3_KU_ENCIPHER_ONLY = $0001; + X509v3_KU_DECIPHER_ONLY = $8000; + X509v3_KU_UNDEF = $ffff; + X509_EX_V_NETSCAPE_HACK = $8000; + X509_EX_V_INIT = $0001; + X509_TRUST_DEFAULT = 0; + X509_TRUST_COMPAT = 1; + X509_TRUST_SSL_CLIENT = 2; + X509_TRUST_SSL_SERVER = 3; + X509_TRUST_EMAIL = 4; + X509_TRUST_OBJECT_SIGN = 5; + X509_TRUST_OCSP_SIGN = 6; + X509_TRUST_OCSP_REQUEST = 7; + X509_TRUST_TSA = 8; + X509_TRUST_MIN = 1; + X509_TRUST_MAX = 8; + X509_TRUST_DYNAMIC = (1 shl 0); + X509_TRUST_DYNAMIC_NAME = (1 shl 1); + X509_TRUST_NO_SS_COMPAT = (1 shl 2); + X509_TRUST_DO_SS_COMPAT = (1 shl 3); + X509_TRUST_OK_ANY_EKU = (1 shl 4); + X509_TRUST_TRUSTED = 1; + X509_TRUST_REJECTED = 2; + X509_TRUST_UNTRUSTED = 3; + X509_FLAG_COMPAT = 0; + X509_FLAG_NO_HEADER = 1; + X509_FLAG_NO_VERSION = (1 shl 1); + X509_FLAG_NO_SERIAL = (1 shl 2); + X509_FLAG_NO_SIGNAME = (1 shl 3); + X509_FLAG_NO_ISSUER = (1 shl 4); + X509_FLAG_NO_VALIDITY = (1 shl 5); + X509_FLAG_NO_SUBJECT = (1 shl 6); + X509_FLAG_NO_PUBKEY = (1 shl 7); + X509_FLAG_NO_EXTENSIONS = (1 shl 8); + X509_FLAG_NO_SIGDUMP = (1 shl 9); + X509_FLAG_NO_AUX = (1 shl 10); + X509_FLAG_NO_ATTRIBUTES = (1 shl 11); + X509_FLAG_NO_IDS = (1 shl 12); + XN_FLAG_SEP_MASK = ($f shl 16); + XN_FLAG_COMPAT = 0; + XN_FLAG_SEP_COMMA_PLUS = (1 shl 16); + XN_FLAG_SEP_CPLUS_SPC = (2 shl 16); + XN_FLAG_SEP_SPLUS_SPC = (3 shl 16); + XN_FLAG_SEP_MULTILINE = (4 shl 16); + XN_FLAG_DN_REV = (1 shl 20); + XN_FLAG_FN_MASK = ($3 shl 21); + XN_FLAG_FN_SN = 0; + XN_FLAG_FN_LN = (1 shl 21); + XN_FLAG_FN_OID = (2 shl 21); + XN_FLAG_FN_NONE = (3 shl 21); + XN_FLAG_SPC_EQ = (1 shl 23); + XN_FLAG_DUMP_UNKNOWN_FIELDS = (1 shl 24); + XN_FLAG_FN_ALIGN = (1 shl 25); + XN_FLAG_RFC2253 = (ASN1_STRFLGS_RFC2253 or XN_FLAG_SEP_COMMA_PLUS or XN_FLAG_DN_REV or XN_FLAG_FN_SN or XN_FLAG_DUMP_UNKNOWN_FIELDS); + XN_FLAG_ONELINE = (ASN1_STRFLGS_RFC2253 or ASN1_STRFLGS_ESC_QUOTE or XN_FLAG_SEP_CPLUS_SPC or XN_FLAG_SPC_EQ or XN_FLAG_FN_SN); + XN_FLAG_MULTILINE = (ASN1_STRFLGS_ESC_CTRL or ASN1_STRFLGS_ESC_MSB or XN_FLAG_SEP_MULTILINE or XN_FLAG_SPC_EQ or XN_FLAG_FN_LN or XN_FLAG_FN_ALIGN); + LH_LOAD_MULT = 256; +// _LHASH = OPENSSL_LHASH; +// LHASH_NODE = OPENSSL_LH_NODE; + X509_LU_RETRY = -1; + X509_LU_FAIL = 0; + X509_L_FILE_LOAD = 1; + X509_L_ADD_DIR = 2; + X509_V_OK = 0; + X509_V_ERR_UNSPECIFIED = 1; + X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT = 2; + X509_V_ERR_UNABLE_TO_GET_CRL = 3; + X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE = 4; + X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE = 5; + X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY = 6; + X509_V_ERR_CERT_SIGNATURE_FAILURE = 7; + X509_V_ERR_CRL_SIGNATURE_FAILURE = 8; + X509_V_ERR_CERT_NOT_YET_VALID = 9; + X509_V_ERR_CERT_HAS_EXPIRED = 10; + X509_V_ERR_CRL_NOT_YET_VALID = 11; + X509_V_ERR_CRL_HAS_EXPIRED = 12; + X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD = 13; + X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD = 14; + X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD = 15; + X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD = 16; + X509_V_ERR_OUT_OF_MEM = 17; + X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT = 18; + X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN = 19; + X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY = 20; + X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE = 21; + X509_V_ERR_CERT_CHAIN_TOO_LONG = 22; + X509_V_ERR_CERT_REVOKED = 23; + X509_V_ERR_INVALID_CA = 24; + X509_V_ERR_PATH_LENGTH_EXCEEDED = 25; + X509_V_ERR_INVALID_PURPOSE = 26; + X509_V_ERR_CERT_UNTRUSTED = 27; + X509_V_ERR_CERT_REJECTED = 28; + X509_V_ERR_SUBJECT_ISSUER_MISMATCH = 29; + X509_V_ERR_AKID_SKID_MISMATCH = 30; + X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH = 31; + X509_V_ERR_KEYUSAGE_NO_CERTSIGN = 32; + X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER = 33; + X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION = 34; + X509_V_ERR_KEYUSAGE_NO_CRL_SIGN = 35; + X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION = 36; + X509_V_ERR_INVALID_NON_CA = 37; + X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED = 38; + X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE = 39; + X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED = 40; + X509_V_ERR_INVALID_EXTENSION = 41; + X509_V_ERR_INVALID_POLICY_EXTENSION = 42; + X509_V_ERR_NO_EXPLICIT_POLICY = 43; + X509_V_ERR_DIFFERENT_CRL_SCOPE = 44; + X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE = 45; + X509_V_ERR_UNNESTED_RESOURCE = 46; + X509_V_ERR_PERMITTED_VIOLATION = 47; + X509_V_ERR_EXCLUDED_VIOLATION = 48; + X509_V_ERR_SUBTREE_MINMAX = 49; + X509_V_ERR_APPLICATION_VERIFICATION = 50; + X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE = 51; + X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX = 52; + X509_V_ERR_UNSUPPORTED_NAME_SYNTAX = 53; + X509_V_ERR_CRL_PATH_VALIDATION_ERROR = 54; + X509_V_ERR_PATH_LOOP = 55; + X509_V_ERR_SUITE_B_INVALID_VERSION = 56; + X509_V_ERR_SUITE_B_INVALID_ALGORITHM = 57; + X509_V_ERR_SUITE_B_INVALID_CURVE = 58; + X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM = 59; + X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED = 60; + X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 = 61; + X509_V_ERR_HOSTNAME_MISMATCH = 62; + X509_V_ERR_EMAIL_MISMATCH = 63; + X509_V_ERR_IP_ADDRESS_MISMATCH = 64; + X509_V_ERR_DANE_NO_MATCH = 65; + X509_V_ERR_EE_KEY_TOO_SMALL = 66; + X509_V_ERR_CA_KEY_TOO_SMALL = 67; + X509_V_ERR_CA_MD_TOO_WEAK = 68; + X509_V_ERR_INVALID_CALL = 69; + X509_V_ERR_STORE_LOOKUP = 70; + X509_V_ERR_NO_VALID_SCTS = 71; + X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION = 72; + X509_V_ERR_OCSP_VERIFY_NEEDED = 73; + X509_V_ERR_OCSP_VERIFY_FAILED = 74; + X509_V_ERR_OCSP_CERT_UNKNOWN = 75; + X509_V_FLAG_CB_ISSUER_CHECK = $0; + X509_V_FLAG_USE_CHECK_TIME = $2; + X509_V_FLAG_CRL_CHECK = $4; + X509_V_FLAG_CRL_CHECK_ALL = $8; + X509_V_FLAG_IGNORE_CRITICAL = $10; + X509_V_FLAG_X509_STRICT = $20; + X509_V_FLAG_ALLOW_PROXY_CERTS = $40; + X509_V_FLAG_POLICY_CHECK = $80; + X509_V_FLAG_EXPLICIT_POLICY = $100; + X509_V_FLAG_INHIBIT_ANY = $200; + X509_V_FLAG_INHIBIT_MAP = $400; + X509_V_FLAG_NOTIFY_POLICY = $800; + X509_V_FLAG_EXTENDED_CRL_SUPPORT = $1000; + X509_V_FLAG_USE_DELTAS = $2000; + X509_V_FLAG_CHECK_SS_SIGNATURE = $4000; + X509_V_FLAG_TRUSTED_FIRST = $8000; + X509_V_FLAG_SUITEB_128_LOS_ONLY = $10000; + X509_V_FLAG_SUITEB_192_LOS = $20000; + X509_V_FLAG_SUITEB_128_LOS = $30000; + X509_V_FLAG_PARTIAL_CHAIN = $80000; + X509_V_FLAG_NO_ALT_CHAINS = $100000; + X509_V_FLAG_NO_CHECK_TIME = $200000; + X509_VP_FLAG_DEFAULT = $1; + X509_VP_FLAG_OVERWRITE = $2; + X509_VP_FLAG_RESET_FLAGS = $4; + X509_VP_FLAG_LOCKED = $8; + X509_VP_FLAG_ONCE = $10; + X509_V_FLAG_POLICY_MASK = (X509_V_FLAG_POLICY_CHECK or X509_V_FLAG_EXPLICIT_POLICY or X509_V_FLAG_INHIBIT_ANY or X509_V_FLAG_INHIBIT_MAP); + DANE_FLAG_NO_DANE_EE_NAMECHECKS = (1 shl 0); + X509_PCY_TREE_FAILURE = -2; + X509_PCY_TREE_INVALID = -1; + X509_PCY_TREE_INTERNAL = 0; + X509_PCY_TREE_VALID = 1; + X509_PCY_TREE_EMPTY = 2; + X509_PCY_TREE_EXPLICIT = 4; + PKCS7_F_DO_PKCS7_SIGNED_ATTRIB = 136; + PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME = 135; + PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP = 118; + PKCS7_F_PKCS7_ADD_CERTIFICATE = 100; + PKCS7_F_PKCS7_ADD_CRL = 101; + PKCS7_F_PKCS7_ADD_RECIPIENT_INFO = 102; + PKCS7_F_PKCS7_ADD_SIGNATURE = 131; + PKCS7_F_PKCS7_ADD_SIGNER = 103; + PKCS7_F_PKCS7_BIO_ADD_DIGEST = 125; + PKCS7_F_PKCS7_COPY_EXISTING_DIGEST = 138; + PKCS7_F_PKCS7_CTRL = 104; + PKCS7_F_PKCS7_DATADECODE = 112; + PKCS7_F_PKCS7_DATAFINAL = 128; + PKCS7_F_PKCS7_DATAINIT = 105; + PKCS7_F_PKCS7_DATAVERIFY = 107; + PKCS7_F_PKCS7_DECRYPT = 114; + PKCS7_F_PKCS7_DECRYPT_RINFO = 133; + PKCS7_F_PKCS7_ENCODE_RINFO = 132; + PKCS7_F_PKCS7_ENCRYPT = 115; + PKCS7_F_PKCS7_FINAL = 134; + PKCS7_F_PKCS7_FIND_DIGEST = 127; + PKCS7_F_PKCS7_GET0_SIGNERS = 124; + PKCS7_F_PKCS7_RECIP_INFO_SET = 130; + PKCS7_F_PKCS7_SET_CIPHER = 108; + PKCS7_F_PKCS7_SET_CONTENT = 109; + PKCS7_F_PKCS7_SET_DIGEST = 126; + PKCS7_F_PKCS7_SET_TYPE = 110; + PKCS7_F_PKCS7_SIGN = 116; + PKCS7_F_PKCS7_SIGNATUREVERIFY = 113; + PKCS7_F_PKCS7_SIGNER_INFO_SET = 129; + PKCS7_F_PKCS7_SIGNER_INFO_SIGN = 139; + PKCS7_F_PKCS7_SIGN_ADD_SIGNER = 137; + PKCS7_F_PKCS7_SIMPLE_SMIMECAP = 119; + PKCS7_F_PKCS7_VERIFY = 117; + PKCS7_R_CERTIFICATE_VERIFY_ERROR = 117; + PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER = 144; + PKCS7_R_CIPHER_NOT_INITIALIZED = 116; + PKCS7_R_CONTENT_AND_DATA_PRESENT = 118; + PKCS7_R_CTRL_ERROR = 152; + PKCS7_R_DECRYPT_ERROR = 119; + PKCS7_R_DIGEST_FAILURE = 101; + PKCS7_R_ENCRYPTION_CTRL_FAILURE = 149; + PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE = 150; + PKCS7_R_ERROR_ADDING_RECIPIENT = 120; + PKCS7_R_ERROR_SETTING_CIPHER = 121; + PKCS7_R_INVALID_NULL_POINTER = 143; + PKCS7_R_INVALID_SIGNED_DATA_TYPE = 155; + PKCS7_R_NO_CONTENT = 122; + PKCS7_R_NO_DEFAULT_DIGEST = 151; + PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND = 154; + PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE = 115; + PKCS7_R_NO_SIGNATURES_ON_DATA = 123; + PKCS7_R_NO_SIGNERS = 142; + PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE = 104; + PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR = 124; + PKCS7_R_PKCS7_ADD_SIGNER_ERROR = 153; + PKCS7_R_PKCS7_DATASIGN = 145; + PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE = 127; + PKCS7_R_SIGNATURE_FAILURE = 105; + PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND = 128; + PKCS7_R_SIGNING_CTRL_FAILURE = 147; + PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE = 148; + PKCS7_R_SMIME_TEXT_ERROR = 129; + PKCS7_R_UNABLE_TO_FIND_CERTIFICATE = 106; + PKCS7_R_UNABLE_TO_FIND_MEM_BIO = 107; + PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST = 108; + PKCS7_R_UNKNOWN_DIGEST_TYPE = 109; + PKCS7_R_UNKNOWN_OPERATION = 110; + PKCS7_R_UNSUPPORTED_CIPHER_TYPE = 111; + PKCS7_R_UNSUPPORTED_CONTENT_TYPE = 112; + PKCS7_R_WRONG_CONTENT_TYPE = 113; + PKCS7_R_WRONG_PKCS7_TYPE = 114; + PKCS7_S_HEADER = 0; + PKCS7_S_BODY = 1; + PKCS7_S_TAIL = 2; + PKCS7_OP_SET_DETACHED_SIGNATURE = 1; + PKCS7_OP_GET_DETACHED_SIGNATURE = 2; + PKCS7_TEXT = $1; + PKCS7_NOCERTS = $2; + PKCS7_NOSIGS = $4; + PKCS7_NOCHAIN = $8; + PKCS7_NOINTERN = $10; + PKCS7_NOVERIFY = $20; + PKCS7_DETACHED = $40; + PKCS7_BINARY = $80; + PKCS7_NOATTR = $100; + PKCS7_NOSMIMECAP = $200; + PKCS7_NOOLDMIMETYPE = $400; + PKCS7_CRLFEOL = $800; + _PKCS7_STREAM = $1000; + PKCS7_NOCRL = $2000; + PKCS7_PARTIAL = $4000; + PKCS7_REUSE_DIGEST = $8000; + PKCS7_NO_DUAL_CONTENT = $10000; + _SMIME_TEXT = PKCS7_TEXT; + SMIME_NOCERTS = PKCS7_NOCERTS; + SMIME_NOSIGS = PKCS7_NOSIGS; + SMIME_NOCHAIN = PKCS7_NOCHAIN; + SMIME_NOINTERN = PKCS7_NOINTERN; + SMIME_NOVERIFY = PKCS7_NOVERIFY; + SMIME_DETACHED = PKCS7_DETACHED; + SMIME_BINARY = PKCS7_BINARY; + SMIME_NOATTR = PKCS7_NOATTR; + SMIME_ASCIICRLF = $80000; + X509_EXT_PACK_UNKNOWN = 1; + X509_EXT_PACK_STRING = 2; + CONF_F_CONF_DUMP_FP = 104; + CONF_F_CONF_LOAD = 100; + CONF_F_CONF_LOAD_FP = 103; + CONF_F_CONF_PARSE_LIST = 119; + CONF_F_DEF_LOAD = 120; + CONF_F_DEF_LOAD_BIO = 121; + CONF_F_GET_NEXT_FILE = 107; + CONF_F_MODULE_ADD = 122; + CONF_F_MODULE_INIT = 115; + CONF_F_MODULE_LOAD_DSO = 117; + CONF_F_MODULE_RUN = 118; + CONF_F_NCONF_DUMP_BIO = 105; + CONF_F_NCONF_DUMP_FP = 106; + CONF_F_NCONF_GET_NUMBER_E = 112; + CONF_F_NCONF_GET_SECTION = 108; + CONF_F_NCONF_GET_STRING = 109; + CONF_F_NCONF_LOAD = 113; + CONF_F_NCONF_LOAD_BIO = 110; + CONF_F_NCONF_LOAD_FP = 114; + CONF_F_NCONF_NEW = 111; + CONF_F_PROCESS_INCLUDE = 116; + CONF_F_SSL_MODULE_INIT = 123; + CONF_F_STR_COPY = 101; + CONF_R_ERROR_LOADING_DSO = 110; + CONF_R_LIST_CANNOT_BE_NULL = 115; + CONF_R_MISSING_CLOSE_SQUARE_BRACKET = 100; + CONF_R_MISSING_EQUAL_SIGN = 101; + CONF_R_MISSING_INIT_FUNCTION = 112; + CONF_R_MODULE_INITIALIZATION_ERROR = 109; + CONF_R_NO_CLOSE_BRACE = 102; + CONF_R_NO_CONF = 105; + CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE = 106; + CONF_R_NO_SECTION = 107; + CONF_R_NO_SUCH_FILE = 114; + CONF_R_NO_VALUE = 108; + CONF_R_NUMBER_TOO_LARGE = 121; + CONF_R_RECURSIVE_DIRECTORY_INCLUDE = 111; + CONF_R_SSL_COMMAND_SECTION_EMPTY = 117; + CONF_R_SSL_COMMAND_SECTION_NOT_FOUND = 118; + CONF_R_SSL_SECTION_EMPTY = 119; + CONF_R_SSL_SECTION_NOT_FOUND = 120; + CONF_R_UNABLE_TO_CREATE_NEW_SECTION = 103; + CONF_R_UNKNOWN_MODULE_NAME = 113; + CONF_R_VARIABLE_EXPANSION_TOO_LONG = 116; + CONF_R_VARIABLE_HAS_NO_VALUE = 104; + CONF_MFLAGS_IGNORE_ERRORS = $1; + CONF_MFLAGS_IGNORE_RETURN_CODES = $2; + CONF_MFLAGS_SILENT = $4; + CONF_MFLAGS_NO_DSO = $8; + CONF_MFLAGS_IGNORE_MISSING_FILE = $10; + CONF_MFLAGS_DEFAULT_SECTION = $20; + X509V3_F_A2I_GENERAL_NAME = 164; + X509V3_F_ADDR_VALIDATE_PATH_INTERNAL = 166; + X509V3_F_ASIDENTIFIERCHOICE_CANONIZE = 161; + X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL = 162; + X509V3_F_BIGNUM_TO_STRING = 167; + X509V3_F_COPY_EMAIL = 122; + X509V3_F_COPY_ISSUER = 123; + X509V3_F_DO_DIRNAME = 144; + X509V3_F_DO_EXT_I2D = 135; + X509V3_F_DO_EXT_NCONF = 151; + X509V3_F_GNAMES_FROM_SECTNAME = 156; + X509V3_F_I2S_ASN1_ENUMERATED = 121; + X509V3_F_I2S_ASN1_IA5STRING = 149; + X509V3_F_I2S_ASN1_INTEGER = 120; + X509V3_F_I2V_AUTHORITY_INFO_ACCESS = 138; + X509V3_F_LEVEL_ADD_NODE = 168; + X509V3_F_NOTICE_SECTION = 132; + X509V3_F_NREF_NOS = 133; + X509V3_F_POLICY_CACHE_CREATE = 169; + X509V3_F_POLICY_CACHE_NEW = 170; + X509V3_F_POLICY_DATA_NEW = 171; + X509V3_F_POLICY_SECTION = 131; + X509V3_F_PROCESS_PCI_VALUE = 150; + X509V3_F_R2I_CERTPOL = 130; + X509V3_F_R2I_PCI = 155; + X509V3_F_S2I_ASN1_IA5STRING = 100; + X509V3_F_S2I_ASN1_INTEGER = 108; + X509V3_F_S2I_ASN1_OCTET_STRING = 112; + X509V3_F_S2I_SKEY_ID = 115; + X509V3_F_SET_DIST_POINT_NAME = 158; + X509V3_F_SXNET_ADD_ID_ASC = 125; + X509V3_F_SXNET_ADD_ID_INTEGER = 126; + X509V3_F_SXNET_ADD_ID_ULONG = 127; + X509V3_F_SXNET_GET_ID_ASC = 128; + X509V3_F_SXNET_GET_ID_ULONG = 129; + X509V3_F_TREE_INIT = 172; + X509V3_F_V2I_ASIDENTIFIERS = 163; + X509V3_F_V2I_ASN1_BIT_STRING = 101; + X509V3_F_V2I_AUTHORITY_INFO_ACCESS = 139; + X509V3_F_V2I_AUTHORITY_KEYID = 119; + X509V3_F_V2I_BASIC_CONSTRAINTS = 102; + X509V3_F_V2I_CRLD = 134; + X509V3_F_V2I_EXTENDED_KEY_USAGE = 103; + X509V3_F_V2I_GENERAL_NAMES = 118; + X509V3_F_V2I_GENERAL_NAME_EX = 117; + X509V3_F_V2I_IDP = 157; + X509V3_F_V2I_IPADDRBLOCKS = 159; + X509V3_F_V2I_ISSUER_ALT = 153; + X509V3_F_V2I_NAME_CONSTRAINTS = 147; + X509V3_F_V2I_POLICY_CONSTRAINTS = 146; + X509V3_F_V2I_POLICY_MAPPINGS = 145; + X509V3_F_V2I_SUBJECT_ALT = 154; + X509V3_F_V2I_TLS_FEATURE = 165; + X509V3_F_V3_GENERIC_EXTENSION = 116; + X509V3_F_X509V3_ADD1_I2D = 140; + X509V3_F_X509V3_ADD_VALUE = 105; + X509V3_F_X509V3_EXT_ADD = 104; + X509V3_F_X509V3_EXT_ADD_ALIAS = 106; + X509V3_F_X509V3_EXT_I2D = 136; + X509V3_F_X509V3_EXT_NCONF = 152; + X509V3_F_X509V3_GET_SECTION = 142; + X509V3_F_X509V3_GET_STRING = 143; + X509V3_F_X509V3_GET_VALUE_BOOL = 110; + X509V3_F_X509V3_PARSE_LIST = 109; + X509V3_F_X509_PURPOSE_ADD = 137; + X509V3_F_X509_PURPOSE_SET = 141; + X509V3_R_BAD_IP_ADDRESS = 118; + X509V3_R_BAD_OBJECT = 119; + X509V3_R_BN_DEC2BN_ERROR = 100; + X509V3_R_BN_TO_ASN1_INTEGER_ERROR = 101; + X509V3_R_DIRNAME_ERROR = 149; + X509V3_R_DISTPOINT_ALREADY_SET = 160; + X509V3_R_DUPLICATE_ZONE_ID = 133; + X509V3_R_ERROR_CONVERTING_ZONE = 131; + X509V3_R_ERROR_CREATING_EXTENSION = 144; + X509V3_R_ERROR_IN_EXTENSION = 128; + X509V3_R_EXPECTED_A_SECTION_NAME = 137; + X509V3_R_EXTENSION_EXISTS = 145; + X509V3_R_EXTENSION_NAME_ERROR = 115; + X509V3_R_EXTENSION_NOT_FOUND = 102; + X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED = 103; + X509V3_R_EXTENSION_VALUE_ERROR = 116; + X509V3_R_ILLEGAL_EMPTY_EXTENSION = 151; + X509V3_R_INCORRECT_POLICY_SYNTAX_TAG = 152; + X509V3_R_INVALID_ASNUMBER = 162; + X509V3_R_INVALID_ASRANGE = 163; + X509V3_R_INVALID_BOOLEAN_STRING = 104; + X509V3_R_INVALID_EXTENSION_STRING = 105; + X509V3_R_INVALID_INHERITANCE = 165; + X509V3_R_INVALID_IPADDRESS = 166; + X509V3_R_INVALID_MULTIPLE_RDNS = 161; + X509V3_R_INVALID_NAME = 106; + X509V3_R_INVALID_NULL_ARGUMENT = 107; + X509V3_R_INVALID_NULL_NAME = 108; + X509V3_R_INVALID_NULL_VALUE = 109; + X509V3_R_INVALID_NUMBER = 140; + X509V3_R_INVALID_NUMBERS = 141; + X509V3_R_INVALID_OBJECT_IDENTIFIER = 110; + X509V3_R_INVALID_OPTION = 138; + X509V3_R_INVALID_POLICY_IDENTIFIER = 134; + X509V3_R_INVALID_PROXY_POLICY_SETTING = 153; + X509V3_R_INVALID_PURPOSE = 146; + X509V3_R_INVALID_SAFI = 164; + X509V3_R_INVALID_SECTION = 135; + X509V3_R_INVALID_SYNTAX = 143; + X509V3_R_ISSUER_DECODE_ERROR = 126; + X509V3_R_MISSING_VALUE = 124; + X509V3_R_NEED_ORGANIZATION_AND_NUMBERS = 142; + X509V3_R_NO_CONFIG_DATABASE = 136; + X509V3_R_NO_ISSUER_CERTIFICATE = 121; + X509V3_R_NO_ISSUER_DETAILS = 127; + X509V3_R_NO_POLICY_IDENTIFIER = 139; + X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED = 154; + X509V3_R_NO_PUBLIC_KEY = 114; + X509V3_R_NO_SUBJECT_DETAILS = 125; + X509V3_R_OPERATION_NOT_DEFINED = 148; + X509V3_R_OTHERNAME_ERROR = 147; + X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED = 155; + X509V3_R_POLICY_PATH_LENGTH = 156; + X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED = 157; + X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY = 159; + X509V3_R_SECTION_NOT_FOUND = 150; + X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS = 122; + X509V3_R_UNABLE_TO_GET_ISSUER_KEYID = 123; + X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT = 111; + X509V3_R_UNKNOWN_EXTENSION = 129; + X509V3_R_UNKNOWN_EXTENSION_NAME = 130; + X509V3_R_UNKNOWN_OPTION = 120; + X509V3_R_UNSUPPORTED_OPTION = 117; + X509V3_R_UNSUPPORTED_TYPE = 167; + X509V3_R_USER_TOO_LONG = 132; + CTX_TEST = $1; + X509V3_CTX_REPLACE = $2; + X509V3_EXT_DYNAMIC = $1; + X509V3_EXT_CTX_DEP = $2; + X509V3_EXT_MULTILINE = $4; + GEN_OTHERNAME = 0; + GEN_EMAIL = 1; + GEN_DNS = 2; + GEN_X400 = 3; + GEN_DIRNAME = 4; + GEN_EDIPARTY = 5; + GEN_URI = 6; + GEN_IPADD = 7; + GEN_RID = 8; + CRLDP_ALL_REASONS = $807f; + CRL_REASON_NONE = -1; + CRL_REASON_UNSPECIFIED = 0; + CRL_REASON_KEY_COMPROMISE = 1; + CRL_REASON_CA_COMPROMISE = 2; + CRL_REASON_AFFILIATION_CHANGED = 3; + CRL_REASON_SUPERSEDED = 4; + CRL_REASON_CESSATION_OF_OPERATION = 5; + CRL_REASON_CERTIFICATE_HOLD = 6; + CRL_REASON_REMOVE_FROM_CRL = 8; + CRL_REASON_PRIVILEGE_WITHDRAWN = 9; + CRL_REASON_AA_COMPROMISE = 10; + IDP_PRESENT = $1; + IDP_INVALID = $2; + IDP_ONLYUSER = $4; + IDP_ONLYCA = $8; + IDP_ONLYATTR = $10; + IDP_INDIRECT = $20; + IDP_REASONS = $40; + EXFLAG_BCONS = $1; + EXFLAG_KUSAGE = $2; + EXFLAG_XKUSAGE = $4; + EXFLAG_NSCERT = $8; + EXFLAG_CA = $10; + EXFLAG_SI = $20; + EXFLAG_V1 = $40; + EXFLAG_INVALID = $80; + EXFLAG_SET = $100; + EXFLAG_CRITICAL = $200; + EXFLAG_PROXY = $400; + EXFLAG_INVALID_POLICY = $800; + EXFLAG_FRESHEST = $1000; + EXFLAG_SS = $2000; + KU_DIGITAL_SIGNATURE = $0080; + KU_NON_REPUDIATION = $0040; + KU_KEY_ENCIPHERMENT = $0020; + KU_DATA_ENCIPHERMENT = $0010; + KU_KEY_AGREEMENT = $0008; + KU_KEY_CERT_SIGN = $0004; + KU_CRL_SIGN = $0002; + KU_ENCIPHER_ONLY = $0001; + KU_DECIPHER_ONLY = $8000; + NS_SSL_CLIENT = $80; + NS_SSL_SERVER = $40; + NS_SMIME = $20; + NS_OBJSIGN = $10; + NS_SSL_CA = $04; + NS_SMIME_CA = $02; + NS_OBJSIGN_CA = $01; + NS_ANY_CA = (NS_SSL_CA or NS_SMIME_CA or NS_OBJSIGN_CA); + XKU_SSL_SERVER = $1; + XKU_SSL_CLIENT = $2; + XKU_SMIME = $4; + XKU_CODE_SIGN = $8; + XKU_SGC = $10; + XKU_OCSP_SIGN = $20; + XKU_TIMESTAMP = $40; + XKU_DVCS = $80; + XKU_ANYEKU = $100; + X509_PURPOSE_DYNAMIC = $1; + X509_PURPOSE_DYNAMIC_NAME = $2; + X509_PURPOSE_SSL_CLIENT = 1; + X509_PURPOSE_SSL_SERVER = 2; + X509_PURPOSE_NS_SSL_SERVER = 3; + X509_PURPOSE_SMIME_SIGN = 4; + X509_PURPOSE_SMIME_ENCRYPT = 5; + X509_PURPOSE_CRL_SIGN = 6; + X509_PURPOSE_ANY = 7; + X509_PURPOSE_OCSP_HELPER = 8; + X509_PURPOSE_TIMESTAMP_SIGN = 9; + X509_PURPOSE_MIN = 1; + X509_PURPOSE_MAX = 9; + X509V3_EXT_UNKNOWN_MASK = ($f shl 16); + X509V3_EXT_DEFAULT = 0; + X509V3_EXT_ERROR_UNKNOWN = (1 shl 16); + X509V3_EXT_PARSE_UNKNOWN = (2 shl 16); + X509V3_EXT_DUMP_UNKNOWN = (3 shl 16); + X509V3_ADD_OP_MASK = $f; + X509V3_ADD_DEFAULT = 0; + X509V3_ADD_APPEND = 1; + X509V3_ADD_REPLACE = 2; + X509V3_ADD_REPLACE_EXISTING = 3; + X509V3_ADD_KEEP_EXISTING = 4; + X509V3_ADD_DELETE = 5; + X509V3_ADD_SILENT = $10; + X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT = $1; + X509_CHECK_FLAG_NO_WILDCARDS = $2; + X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS = $4; + X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS = $8; + X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS = $10; + X509_CHECK_FLAG_NEVER_CHECK_SUBJECT = $20; + _X509_CHECK_FLAG_DOT_SUBDOMAINS = $8000; + ASIdOrRange_id = 0; + ASIdOrRange_range = 1; + ASIdentifierChoice_inherit = 0; + ASIdentifierChoice_asIdsOrRanges = 1; + IPAddressOrRange_addressPrefix = 0; + IPAddressOrRange_addressRange = 1; + IPAddressChoice_inherit = 0; + IPAddressChoice_addressesOrRanges = 1; + V3_ASID_ASNUM = 0; + V3_ASID_RDI = 1; + IANA_AFI_IPV4 = 1; + IANA_AFI_IPV6 = 2; + CMS_F_CHECK_CONTENT = 99; + CMS_F_CMS_ADD0_CERT = 164; + CMS_F_CMS_ADD0_RECIPIENT_KEY = 100; + CMS_F_CMS_ADD0_RECIPIENT_PASSWORD = 165; + CMS_F_CMS_ADD1_RECEIPTREQUEST = 158; + CMS_F_CMS_ADD1_RECIPIENT_CERT = 101; + CMS_F_CMS_ADD1_SIGNER = 102; + CMS_F_CMS_ADD1_SIGNINGTIME = 103; + CMS_F_CMS_COMPRESS = 104; + CMS_F_CMS_COMPRESSEDDATA_CREATE = 105; + CMS_F_CMS_COMPRESSEDDATA_INIT_BIO = 106; + CMS_F_CMS_COPY_CONTENT = 107; + CMS_F_CMS_COPY_MESSAGEDIGEST = 108; + CMS_F_CMS_DATA = 109; + CMS_F_CMS_DATAFINAL = 110; + CMS_F_CMS_DATAINIT = 111; + CMS_F_CMS_DECRYPT = 112; + CMS_F_CMS_DECRYPT_SET1_KEY = 113; + CMS_F_CMS_DECRYPT_SET1_PASSWORD = 166; + CMS_F_CMS_DECRYPT_SET1_PKEY = 114; + CMS_F_CMS_DIGESTALGORITHM_FIND_CTX = 115; + CMS_F_CMS_DIGESTALGORITHM_INIT_BIO = 116; + CMS_F_CMS_DIGESTEDDATA_DO_FINAL = 117; + CMS_F_CMS_DIGEST_VERIFY = 118; + CMS_F_CMS_ENCODE_RECEIPT = 161; + CMS_F_CMS_ENCRYPT = 119; + CMS_F_CMS_ENCRYPTEDCONTENT_INIT = 179; + CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO = 120; + CMS_F_CMS_ENCRYPTEDDATA_DECRYPT = 121; + CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT = 122; + CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY = 123; + CMS_F_CMS_ENVELOPEDDATA_CREATE = 124; + CMS_F_CMS_ENVELOPEDDATA_INIT_BIO = 125; + CMS_F_CMS_ENVELOPED_DATA_INIT = 126; + CMS_F_CMS_ENV_ASN1_CTRL = 171; + CMS_F_CMS_FINAL = 127; + CMS_F_CMS_GET0_CERTIFICATE_CHOICES = 128; + CMS_F_CMS_GET0_CONTENT = 129; + CMS_F_CMS_GET0_ECONTENT_TYPE = 130; + CMS_F_CMS_GET0_ENVELOPED = 131; + CMS_F_CMS_GET0_REVOCATION_CHOICES = 132; + CMS_F_CMS_GET0_SIGNED = 133; + CMS_F_CMS_MSGSIGDIGEST_ADD1 = 162; + CMS_F_CMS_RECEIPTREQUEST_CREATE0 = 159; + CMS_F_CMS_RECEIPT_VERIFY = 160; + CMS_F_CMS_RECIPIENTINFO_DECRYPT = 134; + CMS_F_CMS_RECIPIENTINFO_ENCRYPT = 169; + CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT = 178; + CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG = 175; + CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID = 173; + CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS = 172; + CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP = 174; + CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT = 135; + CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT = 136; + CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID = 137; + CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP = 138; + CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP = 139; + CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT = 140; + CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT = 141; + CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS = 142; + CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID = 143; + CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT = 167; + CMS_F_CMS_RECIPIENTINFO_SET0_KEY = 144; + CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD = 168; + CMS_F_CMS_RECIPIENTINFO_SET0_PKEY = 145; + CMS_F_CMS_SD_ASN1_CTRL = 170; + CMS_F_CMS_SET1_IAS = 176; + CMS_F_CMS_SET1_KEYID = 177; + CMS_F_CMS_SET1_SIGNERIDENTIFIER = 146; + CMS_F_CMS_SET_DETACHED = 147; + CMS_F_CMS_SIGN = 148; + CMS_F_CMS_SIGNED_DATA_INIT = 149; + CMS_F_CMS_SIGNERINFO_CONTENT_SIGN = 150; + CMS_F_CMS_SIGNERINFO_SIGN = 151; + CMS_F_CMS_SIGNERINFO_VERIFY = 152; + CMS_F_CMS_SIGNERINFO_VERIFY_CERT = 153; + CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT = 154; + CMS_F_CMS_SIGN_RECEIPT = 163; + CMS_F_CMS_SI_CHECK_ATTRIBUTES = 183; + CMS_F_CMS_STREAM = 155; + CMS_F_CMS_UNCOMPRESS = 156; + CMS_F_CMS_VERIFY = 157; + CMS_F_KEK_UNWRAP_KEY = 180; + CMS_R_ADD_SIGNER_ERROR = 99; + CMS_R_ATTRIBUTE_ERROR = 161; + CMS_R_CERTIFICATE_ALREADY_PRESENT = 175; + CMS_R_CERTIFICATE_HAS_NO_KEYID = 160; + CMS_R_CERTIFICATE_VERIFY_ERROR = 100; + CMS_R_CIPHER_INITIALISATION_ERROR = 101; + CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR = 102; + CMS_R_CMS_DATAFINAL_ERROR = 103; + CMS_R_CMS_LIB = 104; + CMS_R_CONTENTIDENTIFIER_MISMATCH = 170; + CMS_R_CONTENT_NOT_FOUND = 105; + CMS_R_CONTENT_TYPE_MISMATCH = 171; + CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA = 106; + CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA = 107; + CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA = 108; + CMS_R_CONTENT_VERIFY_ERROR = 109; + CMS_R_CTRL_ERROR = 110; + CMS_R_CTRL_FAILURE = 111; + CMS_R_DECRYPT_ERROR = 112; + CMS_R_ERROR_GETTING_PUBLIC_KEY = 113; + CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE = 114; + CMS_R_ERROR_SETTING_KEY = 115; + CMS_R_ERROR_SETTING_RECIPIENTINFO = 116; + CMS_R_INVALID_ENCRYPTED_KEY_LENGTH = 117; + CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER = 176; + CMS_R_INVALID_KEY_LENGTH = 118; + CMS_R_MD_BIO_INIT_ERROR = 119; + CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH = 120; + CMS_R_MESSAGEDIGEST_WRONG_LENGTH = 121; + CMS_R_MSGSIGDIGEST_ERROR = 172; + CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE = 162; + CMS_R_MSGSIGDIGEST_WRONG_LENGTH = 163; + CMS_R_NEED_ONE_SIGNER = 164; + CMS_R_NOT_A_SIGNED_RECEIPT = 165; + CMS_R_NOT_ENCRYPTED_DATA = 122; + CMS_R_NOT_KEK = 123; + CMS_R_NOT_KEY_AGREEMENT = 181; + CMS_R_NOT_KEY_TRANSPORT = 124; + CMS_R_NOT_PWRI = 177; + CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE = 125; + CMS_R_NO_CIPHER = 126; + CMS_R_NO_CONTENT = 127; + CMS_R_NO_CONTENT_TYPE = 173; + CMS_R_NO_DEFAULT_DIGEST = 128; + CMS_R_NO_DIGEST_SET = 129; + CMS_R_NO_KEY = 130; + CMS_R_NO_KEY_OR_CERT = 174; + CMS_R_NO_MATCHING_DIGEST = 131; + CMS_R_NO_MATCHING_RECIPIENT = 132; + CMS_R_NO_MATCHING_SIGNATURE = 166; + CMS_R_NO_MSGSIGDIGEST = 167; + CMS_R_NO_PASSWORD = 178; + CMS_R_NO_PRIVATE_KEY = 133; + CMS_R_NO_PUBLIC_KEY = 134; + CMS_R_NO_RECEIPT_REQUEST = 168; + CMS_R_NO_SIGNERS = 135; + CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE = 136; + CMS_R_RECEIPT_DECODE_ERROR = 169; + CMS_R_RECIPIENT_ERROR = 137; + CMS_R_SIGNER_CERTIFICATE_NOT_FOUND = 138; + CMS_R_SIGNFINAL_ERROR = 139; + CMS_R_SMIME_TEXT_ERROR = 140; + CMS_R_STORE_INIT_ERROR = 141; + CMS_R_TYPE_NOT_COMPRESSED_DATA = 142; + CMS_R_TYPE_NOT_DATA = 143; + CMS_R_TYPE_NOT_DIGESTED_DATA = 144; + CMS_R_TYPE_NOT_ENCRYPTED_DATA = 145; + CMS_R_TYPE_NOT_ENVELOPED_DATA = 146; + CMS_R_UNABLE_TO_FINALIZE_CONTEXT = 147; + CMS_R_UNKNOWN_CIPHER = 148; + CMS_R_UNKNOWN_DIGEST_ALGORITHM = 149; + CMS_R_UNKNOWN_ID = 150; + CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM = 151; + CMS_R_UNSUPPORTED_CONTENT_TYPE = 152; + CMS_R_UNSUPPORTED_KEK_ALGORITHM = 153; + CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = 179; + CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE = 155; + CMS_R_UNSUPPORTED_RECIPIENT_TYPE = 154; + CMS_R_UNSUPPORTED_TYPE = 156; + CMS_R_UNWRAP_ERROR = 157; + CMS_R_UNWRAP_FAILURE = 180; + CMS_R_VERIFICATION_FAILURE = 158; + CMS_R_WRAP_ERROR = 159; + CMS_SIGNERINFO_ISSUER_SERIAL = 0; + CMS_SIGNERINFO_KEYIDENTIFIER = 1; + CMS_RECIPINFO_NONE = -1; + CMS_RECIPINFO_TRANS = 0; + CMS_RECIPINFO_AGREE = 1; + CMS_RECIPINFO_KEK = 2; + CMS_RECIPINFO_PASS = 3; + CMS_RECIPINFO_OTHER = 4; + CMS_TEXT = $1; + CMS_NOCERTS = $2; + CMS_NO_CONTENT_VERIFY = $4; + CMS_NO_ATTR_VERIFY = $8; + CMS_NOSIGS = (CMS_NO_CONTENT_VERIFY or CMS_NO_ATTR_VERIFY); + CMS_NOINTERN = $10; + CMS_NO_SIGNER_CERT_VERIFY = $20; + CMS_NOVERIFY = $20; + CMS_DETACHED = $40; + CMS_BINARY = $80; + CMS_NOATTR = $100; + CMS_NOSMIMECAP = $200; + CMS_NOOLDMIMETYPE = $400; + CMS_CRLFEOL = $800; + _CMS_STREAM = $1000; + CMS_NOCRL = $2000; + CMS_PARTIAL = $4000; + CMS_REUSE_DIGEST = $8000; + CMS_USE_KEYID = $10000; + CMS_DEBUG_DECRYPT = $20000; + CMS_KEY_PARAM = $40000; + CMS_ASCIICRLF = $80000; + CMS_R_UNKNOWN_DIGEST_ALGORITM = CMS_R_UNKNOWN_DIGEST_ALGORITHM; + CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE = CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE; + COMP_F_BIO_ZLIB_FLUSH = 99; + COMP_F_BIO_ZLIB_NEW = 100; + COMP_F_BIO_ZLIB_READ = 101; + COMP_F_BIO_ZLIB_WRITE = 102; + COMP_F_COMP_CTX_NEW = 103; + COMP_R_ZLIB_DEFLATE_ERROR = 99; + COMP_R_ZLIB_INFLATE_ERROR = 100; + COMP_R_ZLIB_NOT_SUPPORTED = 101; + CT_F_CTLOG_NEW = 117; + CT_F_CTLOG_NEW_FROM_BASE64 = 118; + CT_F_CTLOG_NEW_FROM_CONF = 119; + CT_F_CTLOG_STORE_LOAD_CTX_NEW = 122; + CT_F_CTLOG_STORE_LOAD_FILE = 123; + CT_F_CTLOG_STORE_LOAD_LOG = 130; + CT_F_CTLOG_STORE_NEW = 131; + CT_F_CT_BASE64_DECODE = 124; + CT_F_CT_POLICY_EVAL_CTX_NEW = 133; + CT_F_CT_V1_LOG_ID_FROM_PKEY = 125; + CT_F_I2O_SCT = 107; + CT_F_I2O_SCT_LIST = 108; + CT_F_I2O_SCT_SIGNATURE = 109; + CT_F_O2I_SCT = 110; + CT_F_O2I_SCT_LIST = 111; + CT_F_O2I_SCT_SIGNATURE = 112; + CT_F_SCT_CTX_NEW = 126; + CT_F_SCT_CTX_VERIFY = 128; + CT_F_SCT_NEW = 100; + CT_F_SCT_NEW_FROM_BASE64 = 127; + CT_F_SCT_SET0_LOG_ID = 101; + CT_F_SCT_SET1_EXTENSIONS = 114; + CT_F_SCT_SET1_LOG_ID = 115; + CT_F_SCT_SET1_SIGNATURE = 116; + CT_F_SCT_SET_LOG_ENTRY_TYPE = 102; + CT_F_SCT_SET_SIGNATURE_NID = 103; + CT_F_SCT_SET_VERSION = 104; + CT_R_BASE64_DECODE_ERROR = 108; + CT_R_INVALID_LOG_ID_LENGTH = 100; + CT_R_LOG_CONF_INVALID = 109; + CT_R_LOG_CONF_INVALID_KEY = 110; + CT_R_LOG_CONF_MISSING_DESCRIPTION = 111; + CT_R_LOG_CONF_MISSING_KEY = 112; + CT_R_LOG_KEY_INVALID = 113; + CT_R_SCT_FUTURE_TIMESTAMP = 116; + CT_R_SCT_INVALID = 104; + CT_R_SCT_INVALID_SIGNATURE = 107; + CT_R_SCT_LIST_INVALID = 105; + CT_R_SCT_LOG_ID_MISMATCH = 114; + CT_R_SCT_NOT_SET = 106; + CT_R_SCT_UNSUPPORTED_VERSION = 115; + CT_R_UNRECOGNIZED_SIGNATURE_NID = 101; + CT_R_UNSUPPORTED_ENTRY_TYPE = 102; + CT_R_UNSUPPORTED_VERSION = 103; + SCT_MIN_RSA_BITS = 2048; + CT_V1_HASHLEN = SHA256_DIGEST_LENGTH; + DES_ENCRYPT = 1; + DES_DECRYPT = 0; + DES_CBC_MODE = 0; + DES_PCBC_MODE = 1; + DTLS1_VERSION = $FEFF; + DTLS1_2_VERSION = $FEFD; + DTLS_MIN_VERSION = DTLS1_VERSION; + DTLS_MAX_VERSION = DTLS1_2_VERSION; + DTLS1_VERSION_MAJOR = $FE; + DTLS1_BAD_VER = $0100; + DTLS_ANY_VERSION = $1FFFF; + DTLS1_COOKIE_LENGTH = 256; + DTLS1_RT_HEADER_LENGTH = 13; + DTLS1_HM_HEADER_LENGTH = 12; + DTLS1_HM_BAD_FRAGMENT = -2; + DTLS1_HM_FRAGMENT_RETRY = -3; + DTLS1_CCS_HEADER_LENGTH = 1; + DTLS1_AL_HEADER_LENGTH = 2; + DTLS1_TMO_READ_COUNT = 2; + DTLS1_TMO_WRITE_COUNT = 2; + DTLS1_TMO_ALERT_COUNT = 12; + RAND_F_DATA_COLLECT_METHOD = 127; + RAND_F_DRBG_BYTES = 101; + RAND_F_DRBG_GET_ENTROPY = 105; + RAND_F_DRBG_SETUP = 117; + RAND_F_GET_ENTROPY = 106; + RAND_F_RAND_BYTES = 100; + RAND_F_RAND_DRBG_ENABLE_LOCKING = 119; + RAND_F_RAND_DRBG_GENERATE = 107; + RAND_F_RAND_DRBG_GET_ENTROPY = 120; + RAND_F_RAND_DRBG_GET_NONCE = 123; + RAND_F_RAND_DRBG_INSTANTIATE = 108; + RAND_F_RAND_DRBG_NEW = 109; + RAND_F_RAND_DRBG_RESEED = 110; + RAND_F_RAND_DRBG_RESTART = 102; + RAND_F_RAND_DRBG_SET = 104; + RAND_F_RAND_DRBG_SET_DEFAULTS = 121; + RAND_F_RAND_DRBG_UNINSTANTIATE = 118; + RAND_F_RAND_LOAD_FILE = 111; + RAND_F_RAND_POOL_ACQUIRE_ENTROPY = 122; + RAND_F_RAND_POOL_ADD = 103; + RAND_F_RAND_POOL_ADD_BEGIN = 113; + RAND_F_RAND_POOL_ADD_END = 114; + RAND_F_RAND_POOL_ATTACH = 124; + RAND_F_RAND_POOL_BYTES_NEEDED = 115; + RAND_F_RAND_POOL_GROW = 125; + RAND_F_RAND_POOL_NEW = 116; + RAND_F_RAND_PSEUDO_BYTES = 126; + RAND_F_RAND_WRITE_FILE = 112; + RAND_R_ADDITIONAL_INPUT_TOO_LONG = 102; + RAND_R_ALREADY_INSTANTIATED = 103; + RAND_R_ARGUMENT_OUT_OF_RANGE = 105; + RAND_R_CANNOT_OPEN_FILE = 121; + RAND_R_DRBG_ALREADY_INITIALIZED = 129; + RAND_R_DRBG_NOT_INITIALISED = 104; + RAND_R_ENTROPY_INPUT_TOO_LONG = 106; + RAND_R_ENTROPY_OUT_OF_RANGE = 124; + RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED = 127; + RAND_R_ERROR_INITIALISING_DRBG = 107; + RAND_R_ERROR_INSTANTIATING_DRBG = 108; + RAND_R_ERROR_RETRIEVING_ADDITIONAL_INPUT = 109; + RAND_R_ERROR_RETRIEVING_ENTROPY = 110; + RAND_R_ERROR_RETRIEVING_NONCE = 111; + RAND_R_FAILED_TO_CREATE_LOCK = 126; + RAND_R_FUNC_NOT_IMPLEMENTED = 101; + RAND_R_FWRITE_ERROR = 123; + RAND_R_GENERATE_ERROR = 112; + RAND_R_INTERNAL_ERROR = 113; + RAND_R_IN_ERROR_STATE = 114; + RAND_R_NOT_A_REGULAR_FILE = 122; + RAND_R_NOT_INSTANTIATED = 115; + RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED = 128; + RAND_R_PARENT_LOCKING_NOT_ENABLED = 130; + RAND_R_PARENT_STRENGTH_TOO_WEAK = 131; + RAND_R_PERSONALISATION_STRING_TOO_LONG = 116; + RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED = 133; + RAND_R_PRNG_NOT_SEEDED = 100; + RAND_R_RANDOM_POOL_OVERFLOW = 125; + RAND_R_RANDOM_POOL_UNDERFLOW = 134; + RAND_R_REQUEST_TOO_LARGE_FOR_DRBG = 117; + RAND_R_RESEED_ERROR = 118; + RAND_R_SELFTEST_FAILURE = 119; + RAND_R_TOO_LITTLE_NONCE_REQUESTED = 135; + RAND_R_TOO_MUCH_NONCE_REQUESTED = 136; + RAND_R_UNSUPPORTED_DRBG_FLAGS = 132; + RAND_R_UNSUPPORTED_DRBG_TYPE = 120; + PEM_F_B2I_DSS = 127; + PEM_F_B2I_PVK_BIO = 128; + PEM_F_B2I_RSA = 129; + PEM_F_CHECK_BITLEN_DSA = 130; + PEM_F_CHECK_BITLEN_RSA = 131; + PEM_F_D2I_PKCS8PRIVATEKEY_BIO = 120; + PEM_F_D2I_PKCS8PRIVATEKEY_FP = 121; + PEM_F_DO_B2I = 132; + PEM_F_DO_B2I_BIO = 133; + PEM_F_DO_BLOB_HEADER = 134; + PEM_F_DO_I2B = 146; + PEM_F_DO_PK8PKEY = 126; + PEM_F_DO_PK8PKEY_FP = 125; + PEM_F_DO_PVK_BODY = 135; + PEM_F_DO_PVK_HEADER = 136; + PEM_F_GET_HEADER_AND_DATA = 143; + PEM_F_GET_NAME = 144; + PEM_F_I2B_PVK = 137; + PEM_F_I2B_PVK_BIO = 138; + PEM_F_LOAD_IV = 101; + PEM_F_PEM_ASN1_READ = 102; + PEM_F_PEM_ASN1_READ_BIO = 103; + PEM_F_PEM_ASN1_WRITE = 104; + PEM_F_PEM_ASN1_WRITE_BIO = 105; + PEM_F_PEM_DEF_CALLBACK = 100; + PEM_F_PEM_DO_HEADER = 106; + PEM_F_PEM_GET_EVP_CIPHER_INFO = 107; + PEM_F_PEM_READ = 108; + PEM_F_PEM_READ_BIO = 109; + PEM_F_PEM_READ_BIO_DHPARAMS = 141; + PEM_F_PEM_READ_BIO_EX = 145; + PEM_F_PEM_READ_BIO_PARAMETERS = 140; + PEM_F_PEM_READ_BIO_PRIVATEKEY = 123; + PEM_F_PEM_READ_DHPARAMS = 142; + PEM_F_PEM_READ_PRIVATEKEY = 124; + PEM_F_PEM_SIGNFINAL = 112; + PEM_F_PEM_WRITE = 113; + PEM_F_PEM_WRITE_BIO = 114; + PEM_F_PEM_WRITE_PRIVATEKEY = 139; + PEM_F_PEM_X509_INFO_READ = 115; + PEM_F_PEM_X509_INFO_READ_BIO = 116; + PEM_F_PEM_X509_INFO_WRITE_BIO = 117; + PEM_R_BAD_BASE64_DECODE = 100; + PEM_R_BAD_DECRYPT = 101; + PEM_R_BAD_END_LINE = 102; + PEM_R_BAD_IV_CHARS = 103; + PEM_R_BAD_MAGIC_NUMBER = 116; + PEM_R_BAD_PASSWORD_READ = 104; + PEM_R_BAD_VERSION_NUMBER = 117; + PEM_R_BIO_WRITE_FAILURE = 118; + PEM_R_CIPHER_IS_NULL = 127; + PEM_R_ERROR_CONVERTING_PRIVATE_KEY = 115; + PEM_R_EXPECTING_PRIVATE_KEY_BLOB = 119; + PEM_R_EXPECTING_PUBLIC_KEY_BLOB = 120; + PEM_R_HEADER_TOO_LONG = 128; + PEM_R_INCONSISTENT_HEADER = 121; + PEM_R_KEYBLOB_HEADER_PARSE_ERROR = 122; + PEM_R_KEYBLOB_TOO_SHORT = 123; + PEM_R_MISSING_DEK_IV = 129; + PEM_R_NOT_DEK_INFO = 105; + PEM_R_NOT_ENCRYPTED = 106; + PEM_R_NOT_PROC_TYPE = 107; + PEM_R_NO_START_LINE = 108; + PEM_R_PROBLEMS_GETTING_PASSWORD = 109; + PEM_R_PVK_DATA_TOO_SHORT = 124; + PEM_R_PVK_TOO_SHORT = 125; + PEM_R_READ_KEY = 111; + PEM_R_SHORT_HEADER = 112; + PEM_R_UNEXPECTED_DEK_IV = 130; + PEM_R_UNSUPPORTED_CIPHER = 113; + PEM_R_UNSUPPORTED_ENCRYPTION = 114; + PEM_R_UNSUPPORTED_KEY_COMPONENTS = 126; + PEM_BUFSIZE = 1024; + PEM_STRING_X509_OLD = 'X509 CERTIFICATE'; + PEM_STRING_X509 = 'CERTIFICATE'; + PEM_STRING_X509_TRUSTED = 'TRUSTED CERTIFICATE'; + PEM_STRING_X509_REQ_OLD = 'NEW CERTIFICATE REQUEST'; + PEM_STRING_X509_REQ = 'CERTIFICATE REQUEST'; + PEM_STRING_X509_CRL = 'X509 CRL'; + PEM_STRING_EVP_PKEY = 'ANY PRIVATE KEY'; + PEM_STRING_PUBLIC = 'PUBLIC KEY'; + PEM_STRING_RSA = 'RSA PRIVATE KEY'; + PEM_STRING_RSA_PUBLIC = 'RSA PUBLIC KEY'; + PEM_STRING_DSA = 'DSA PRIVATE KEY'; + PEM_STRING_DSA_PUBLIC = 'DSA PUBLIC KEY'; + PEM_STRING_PKCS7 = 'PKCS7'; + PEM_STRING_PKCS7_SIGNED = 'PKCS #7 SIGNED DATA'; + PEM_STRING_PKCS8 = 'ENCRYPTED PRIVATE KEY'; + PEM_STRING_PKCS8INF = 'PRIVATE KEY'; + PEM_STRING_DHPARAMS = 'DH PARAMETERS'; + PEM_STRING_DHXPARAMS = 'X9.42 DH PARAMETERS'; + PEM_STRING_SSL_SESSION = 'SSL SESSION PARAMETERS'; + PEM_STRING_DSAPARAMS = 'DSA PARAMETERS'; + PEM_STRING_ECDSA_PUBLIC = 'ECDSA PUBLIC KEY'; + PEM_STRING_ECPARAMETERS = 'EC PARAMETERS'; + PEM_STRING_ECPRIVATEKEY = 'EC PRIVATE KEY'; + PEM_STRING_PARAMETERS = 'PARAMETERS'; + PEM_STRING_CMS = 'CMS'; + PEM_TYPE_ENCRYPTED = 10; + PEM_TYPE_MIC_ONLY = 20; + PEM_TYPE_MIC_CLEAR = 30; + PEM_TYPE_CLEAR = 40; + PEM_FLAG_SECURE = $1; + PEM_FLAG_EAY_COMPATIBLE = $2; + PEM_FLAG_ONLY_B64 = $4; + UI_F_CLOSE_CONSOLE = 115; + UI_F_ECHO_CONSOLE = 116; + UI_F_GENERAL_ALLOCATE_BOOLEAN = 108; + UI_F_GENERAL_ALLOCATE_PROMPT = 109; + UI_F_NOECHO_CONSOLE = 117; + UI_F_OPEN_CONSOLE = 114; + UI_F_UI_CONSTRUCT_PROMPT = 121; + UI_F_UI_CREATE_METHOD = 112; + UI_F_UI_CTRL = 111; + UI_F_UI_DUP_ERROR_STRING = 101; + UI_F_UI_DUP_INFO_STRING = 102; + UI_F_UI_DUP_INPUT_BOOLEAN = 110; + UI_F_UI_DUP_INPUT_STRING = 103; + UI_F_UI_DUP_USER_DATA = 118; + UI_F_UI_DUP_VERIFY_STRING = 106; + UI_F_UI_GET0_RESULT = 107; + UI_F_UI_GET_RESULT_LENGTH = 119; + UI_F_UI_NEW_METHOD = 104; + UI_F_UI_PROCESS = 113; + UI_F_UI_SET_RESULT = 105; + UI_F_UI_SET_RESULT_EX = 120; + UI_R_COMMON_OK_AND_CANCEL_CHARACTERS = 104; + UI_R_INDEX_TOO_LARGE = 102; + UI_R_INDEX_TOO_SMALL = 103; + UI_R_NO_RESULT_BUFFER = 105; + UI_R_PROCESSING_ERROR = 107; + UI_R_RESULT_TOO_LARGE = 100; + UI_R_RESULT_TOO_SMALL = 101; + UI_R_SYSASSIGN_ERROR = 109; + UI_R_SYSDASSGN_ERROR = 110; + UI_R_SYSQIOW_ERROR = 111; + UI_R_UNKNOWN_CONTROL_COMMAND = 106; + UI_R_UNKNOWN_TTYGET_ERRNO_VALUE = 108; + UI_R_USER_DATA_DUPLICATION_UNSUPPORTED = 112; + UI_INPUT_FLAG_ECHO = $01; + UI_INPUT_FLAG_DEFAULT_PWD = $02; + UI_INPUT_FLAG_USER_BASE = 16; + UI_CTRL_PRINT_ERRORS = 1; + UI_CTRL_IS_REDOABLE = 2; + ERR_TXT_MALLOCED = $01; + ERR_TXT_STRING = $02; + ERR_FLAG_MARK = $01; + ERR_FLAG_CLEAR = $02; + ERR_NUM_ERRORS = 16; + ERR_LIB_NONE = 1; + ERR_LIB_SYS = 2; + ERR_LIB_BN = 3; + ERR_LIB_RSA = 4; + ERR_LIB_DH = 5; + ERR_LIB_EVP = 6; + ERR_LIB_BUF = 7; + ERR_LIB_OBJ = 8; + ERR_LIB_PEM = 9; + ERR_LIB_DSA = 10; + ERR_LIB_X509 = 11; + ERR_LIB_ASN1 = 13; + ERR_LIB_CONF = 14; + ERR_LIB_CRYPTO = 15; + ERR_LIB_EC = 16; + ERR_LIB_SSL = 20; + ERR_LIB_BIO = 32; + ERR_LIB_PKCS7 = 33; + ERR_LIB_X509V3 = 34; + ERR_LIB_PKCS12 = 35; + ERR_LIB_RAND = 36; + ERR_LIB_DSO = 37; + ERR_LIB_ENGINE = 38; + ERR_LIB_OCSP = 39; + ERR_LIB_UI = 40; + ERR_LIB_COMP = 41; + ERR_LIB_ECDSA = 42; + ERR_LIB_ECDH = 43; + ERR_LIB_OSSL_STORE = 44; + ERR_LIB_FIPS = 45; + ERR_LIB_CMS = 46; + ERR_LIB_TS = 47; + ERR_LIB_HMAC = 48; + ERR_LIB_CT = 50; + ERR_LIB_ASYNC = 51; + ERR_LIB_KDF = 52; + ERR_LIB_SM2 = 53; + ERR_LIB_USER = 128; + SYS_F_FOPEN = 1; + SYS_F_CONNECT = 2; + SYS_F_GETSERVBYNAME = 3; + SYS_F_SOCKET = 4; + SYS_F_IOCTLSOCKET = 5; + SYS_F_BIND = 6; + SYS_F_LISTEN = 7; + SYS_F_ACCEPT = 8; + SYS_F_WSASTARTUP = 9; + SYS_F_OPENDIR = 10; + SYS_F_FREAD = 11; + SYS_F_GETADDRINFO = 12; + SYS_F_GETNAMEINFO = 13; + SYS_F_SETSOCKOPT = 14; + SYS_F_GETSOCKOPT = 15; + SYS_F_GETSOCKNAME = 16; + SYS_F_GETHOSTBYNAME = 17; + SYS_F_FFLUSH = 18; + SYS_F_OPEN = 19; + SYS_F_CLOSE = 20; + SYS_F_IOCTL = 21; + SYS_F_STAT = 22; + SYS_F_FCNTL = 23; + SYS_F_FSTAT = 24; + ERR_R_SYS_LIB = ERR_LIB_SYS; + ERR_R_BN_LIB = ERR_LIB_BN; + ERR_R_RSA_LIB = ERR_LIB_RSA; + ERR_R_DH_LIB = ERR_LIB_DH; + ERR_R_EVP_LIB = ERR_LIB_EVP; + ERR_R_BUF_LIB = ERR_LIB_BUF; + ERR_R_OBJ_LIB = ERR_LIB_OBJ; + ERR_R_PEM_LIB = ERR_LIB_PEM; + ERR_R_DSA_LIB = ERR_LIB_DSA; + ERR_R_X509_LIB = ERR_LIB_X509; + ERR_R_ASN1_LIB = ERR_LIB_ASN1; + ERR_R_EC_LIB = ERR_LIB_EC; + ERR_R_BIO_LIB = ERR_LIB_BIO; + ERR_R_PKCS7_LIB = ERR_LIB_PKCS7; + ERR_R_X509V3_LIB = ERR_LIB_X509V3; + ERR_R_ENGINE_LIB = ERR_LIB_ENGINE; + ERR_R_UI_LIB = ERR_LIB_UI; + ERR_R_ECDSA_LIB = ERR_LIB_ECDSA; + ERR_R_OSSL_STORE_LIB = ERR_LIB_OSSL_STORE; + ERR_R_NESTED_ASN1_ERROR = 58; + ERR_R_MISSING_ASN1_EOS = 63; + ERR_R_FATAL = 64; + ERR_R_MALLOC_FAILURE = (1 or ERR_R_FATAL); + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED = (2 or ERR_R_FATAL); + ERR_R_PASSED_NULL_PARAMETER = (3 or ERR_R_FATAL); + ERR_R_INTERNAL_ERROR = (4 or ERR_R_FATAL); + ERR_R_DISABLED = (5 or ERR_R_FATAL); + ERR_R_INIT_FAIL = (6 or ERR_R_FATAL); + ERR_R_PASSED_INVALID_ARGUMENT = (7); + ERR_R_OPERATION_FAIL = (8 or ERR_R_FATAL); + ENGINE_F_DIGEST_UPDATE = 198; + ENGINE_F_DYNAMIC_CTRL = 180; + ENGINE_F_DYNAMIC_GET_DATA_CTX = 181; + ENGINE_F_DYNAMIC_LOAD = 182; + ENGINE_F_DYNAMIC_SET_DATA_CTX = 183; + ENGINE_F_ENGINE_ADD = 105; + ENGINE_F_ENGINE_BY_ID = 106; + ENGINE_F_ENGINE_CMD_IS_EXECUTABLE = 170; + ENGINE_F_ENGINE_CTRL = 142; + ENGINE_F_ENGINE_CTRL_CMD = 178; + ENGINE_F_ENGINE_CTRL_CMD_STRING = 171; + ENGINE_F_ENGINE_FINISH = 107; + ENGINE_F_ENGINE_GET_CIPHER = 185; + ENGINE_F_ENGINE_GET_DIGEST = 186; + ENGINE_F_ENGINE_GET_FIRST = 195; + ENGINE_F_ENGINE_GET_LAST = 196; + ENGINE_F_ENGINE_GET_NEXT = 115; + ENGINE_F_ENGINE_GET_PKEY_ASN1_METH = 193; + ENGINE_F_ENGINE_GET_PKEY_METH = 192; + ENGINE_F_ENGINE_GET_PREV = 116; + ENGINE_F_ENGINE_INIT = 119; + ENGINE_F_ENGINE_LIST_ADD = 120; + ENGINE_F_ENGINE_LIST_REMOVE = 121; + ENGINE_F_ENGINE_LOAD_PRIVATE_KEY = 150; + ENGINE_F_ENGINE_LOAD_PUBLIC_KEY = 151; + ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT = 194; + ENGINE_F_ENGINE_NEW = 122; + ENGINE_F_ENGINE_PKEY_ASN1_FIND_STR = 197; + ENGINE_F_ENGINE_REMOVE = 123; + ENGINE_F_ENGINE_SET_DEFAULT_STRING = 189; + ENGINE_F_ENGINE_SET_ID = 129; + ENGINE_F_ENGINE_SET_NAME = 130; + ENGINE_F_ENGINE_TABLE_REGISTER = 184; + ENGINE_F_ENGINE_UNLOCKED_FINISH = 191; + ENGINE_F_ENGINE_UP_REF = 190; + ENGINE_F_INT_CLEANUP_ITEM = 199; + ENGINE_F_INT_CTRL_HELPER = 172; + ENGINE_F_INT_ENGINE_CONFIGURE = 188; + ENGINE_F_INT_ENGINE_MODULE_INIT = 187; + ENGINE_F_OSSL_HMAC_INIT = 200; + ENGINE_R_ALREADY_LOADED = 100; + ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER = 133; + ENGINE_R_CMD_NOT_EXECUTABLE = 134; + ENGINE_R_COMMAND_TAKES_INPUT = 135; + ENGINE_R_COMMAND_TAKES_NO_INPUT = 136; + ENGINE_R_CONFLICTING_ENGINE_ID = 103; + ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED = 119; + ENGINE_R_DSO_FAILURE = 104; + ENGINE_R_DSO_NOT_FOUND = 132; + ENGINE_R_ENGINES_SECTION_ERROR = 148; + ENGINE_R_ENGINE_CONFIGURATION_ERROR = 102; + ENGINE_R_ENGINE_IS_NOT_IN_LIST = 105; + ENGINE_R_ENGINE_SECTION_ERROR = 149; + ENGINE_R_FAILED_LOADING_PRIVATE_KEY = 128; + ENGINE_R_FAILED_LOADING_PUBLIC_KEY = 129; + ENGINE_R_FINISH_FAILED = 106; + ENGINE_R_ID_OR_NAME_MISSING = 108; + ENGINE_R_INIT_FAILED = 109; + ENGINE_R_INTERNAL_LIST_ERROR = 110; + ENGINE_R_INVALID_ARGUMENT = 143; + ENGINE_R_INVALID_CMD_NAME = 137; + ENGINE_R_INVALID_CMD_NUMBER = 138; + ENGINE_R_INVALID_INIT_VALUE = 151; + ENGINE_R_INVALID_STRING = 150; + ENGINE_R_NOT_INITIALISED = 117; + ENGINE_R_NOT_LOADED = 112; + ENGINE_R_NO_CONTROL_FUNCTION = 120; + ENGINE_R_NO_INDEX = 144; + ENGINE_R_NO_LOAD_FUNCTION = 125; + ENGINE_R_NO_REFERENCE = 130; + ENGINE_R_NO_SUCH_ENGINE = 116; + ENGINE_R_UNIMPLEMENTED_CIPHER = 146; + ENGINE_R_UNIMPLEMENTED_DIGEST = 147; + ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD = 101; + ENGINE_R_VERSION_INCOMPATIBILITY = 145; + ENGINE_CTRL_SET_LOGSTREAM = 1; + ENGINE_CTRL_SET_PASSWORD_CALLBACK = 2; + ENGINE_CTRL_HUP = 3; + ENGINE_CTRL_SET_USER_INTERFACE = 4; + ENGINE_CTRL_SET_CALLBACK_DATA = 5; + ENGINE_CTRL_LOAD_CONFIGURATION = 6; + ENGINE_CTRL_LOAD_SECTION = 7; + ENGINE_CTRL_HAS_CTRL_FUNCTION = 10; + ENGINE_CTRL_GET_FIRST_CMD_TYPE = 11; + ENGINE_CTRL_GET_NEXT_CMD_TYPE = 12; + ENGINE_CTRL_GET_CMD_FROM_NAME = 13; + ENGINE_CTRL_GET_NAME_LEN_FROM_CMD = 14; + ENGINE_CTRL_GET_NAME_FROM_CMD = 15; + ENGINE_CTRL_GET_DESC_LEN_FROM_CMD = 16; + ENGINE_CTRL_GET_DESC_FROM_CMD = 17; + ENGINE_CTRL_GET_CMD_FLAGS = 18; + ENGINE_CMD_BASE = 200; + ENGINE_CTRL_CHIL_SET_FORKCHECK = 100; + ENGINE_CTRL_CHIL_NO_LOCKING = 101; + HMAC_MAX_MD_CBLOCK = 128; + _IDEA_ENCRYPT = 1; + IDEA_DECRYPT = 0; + IDEA_BLOCK = 8; + IDEA_KEY_LENGTH = 16; + KDF_F_PKEY_HKDF_CTRL_STR = 103; + KDF_F_PKEY_HKDF_DERIVE = 102; + KDF_F_PKEY_HKDF_INIT = 108; + KDF_F_PKEY_SCRYPT_CTRL_STR = 104; + KDF_F_PKEY_SCRYPT_CTRL_UINT64 = 105; + KDF_F_PKEY_SCRYPT_DERIVE = 109; + KDF_F_PKEY_SCRYPT_INIT = 106; + KDF_F_PKEY_SCRYPT_SET_MEMBUF = 107; + KDF_F_PKEY_TLS1_PRF_CTRL_STR = 100; + KDF_F_PKEY_TLS1_PRF_DERIVE = 101; + KDF_F_PKEY_TLS1_PRF_INIT = 110; + KDF_F_TLS1_PRF_ALG = 111; + KDF_R_INVALID_DIGEST = 100; + KDF_R_MISSING_ITERATION_COUNT = 109; + KDF_R_MISSING_KEY = 104; + KDF_R_MISSING_MESSAGE_DIGEST = 105; + KDF_R_MISSING_PARAMETER = 101; + KDF_R_MISSING_PASS = 110; + KDF_R_MISSING_SALT = 111; + KDF_R_MISSING_SECRET = 107; + KDF_R_MISSING_SEED = 106; + KDF_R_UNKNOWN_PARAMETER_TYPE = 103; + KDF_R_VALUE_ERROR = 108; + KDF_R_VALUE_MISSING = 102; + EVP_PKEY_CTRL_TLS_MD = (EVP_PKEY_ALG_CTRL); + EVP_PKEY_CTRL_TLS_SECRET = (EVP_PKEY_ALG_CTRL+1); + EVP_PKEY_CTRL_TLS_SEED = (EVP_PKEY_ALG_CTRL+2); + EVP_PKEY_CTRL_HKDF_MD = (EVP_PKEY_ALG_CTRL+3); + EVP_PKEY_CTRL_HKDF_SALT = (EVP_PKEY_ALG_CTRL+4); + EVP_PKEY_CTRL_HKDF_KEY = (EVP_PKEY_ALG_CTRL+5); + EVP_PKEY_CTRL_HKDF_INFO = (EVP_PKEY_ALG_CTRL+6); + EVP_PKEY_CTRL_HKDF_MODE = (EVP_PKEY_ALG_CTRL+7); + EVP_PKEY_CTRL_PASS = (EVP_PKEY_ALG_CTRL+8); + EVP_PKEY_CTRL_SCRYPT_SALT = (EVP_PKEY_ALG_CTRL+9); + EVP_PKEY_CTRL_SCRYPT_N = (EVP_PKEY_ALG_CTRL+10); + EVP_PKEY_CTRL_SCRYPT_R = (EVP_PKEY_ALG_CTRL+11); + EVP_PKEY_CTRL_SCRYPT_P = (EVP_PKEY_ALG_CTRL+12); + EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES = (EVP_PKEY_ALG_CTRL+13); + EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND = 0; + EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY = 1; + EVP_PKEY_HKDEF_MODE_EXPAND_ONLY = 2; + MD4_CBLOCK = 64; + MD4_LBLOCK = (MD4_CBLOCK div 4); + MD4_DIGEST_LENGTH = 16; + MD5_CBLOCK = 64; + MD5_LBLOCK = (MD5_CBLOCK div 4); + MD5_DIGEST_LENGTH = 16; + MDC2_BLOCK = 8; + MDC2_DIGEST_LENGTH = 16; + OCSP_REVOKED_STATUS_NOSTATUS = -1; + OCSP_REVOKED_STATUS_UNSPECIFIED = 0; + OCSP_REVOKED_STATUS_KEYCOMPROMISE = 1; + OCSP_REVOKED_STATUS_CACOMPROMISE = 2; + OCSP_REVOKED_STATUS_AFFILIATIONCHANGED = 3; + OCSP_REVOKED_STATUS_SUPERSEDED = 4; + OCSP_REVOKED_STATUS_CESSATIONOFOPERATION = 5; + OCSP_REVOKED_STATUS_CERTIFICATEHOLD = 6; + OCSP_REVOKED_STATUS_REMOVEFROMCRL = 8; + OCSP_F_D2I_OCSP_NONCE = 102; + OCSP_F_OCSP_BASIC_ADD1_STATUS = 103; + OCSP_F_OCSP_BASIC_SIGN = 104; + OCSP_F_OCSP_BASIC_SIGN_CTX = 119; + OCSP_F_OCSP_BASIC_VERIFY = 105; + OCSP_F_OCSP_CERT_ID_NEW = 101; + OCSP_F_OCSP_CHECK_DELEGATED = 106; + OCSP_F_OCSP_CHECK_IDS = 107; + OCSP_F_OCSP_CHECK_ISSUER = 108; + OCSP_F_OCSP_CHECK_VALIDITY = 115; + OCSP_F_OCSP_MATCH_ISSUERID = 109; + OCSP_F_OCSP_PARSE_URL = 114; + OCSP_F_OCSP_REQUEST_SIGN = 110; + OCSP_F_OCSP_REQUEST_VERIFY = 116; + OCSP_F_OCSP_RESPONSE_GET1_BASIC = 111; + OCSP_F_PARSE_HTTP_LINE1 = 118; + OCSP_R_CERTIFICATE_VERIFY_ERROR = 101; + OCSP_R_DIGEST_ERR = 102; + OCSP_R_ERROR_IN_NEXTUPDATE_FIELD = 122; + OCSP_R_ERROR_IN_THISUPDATE_FIELD = 123; + OCSP_R_ERROR_PARSING_URL = 121; + OCSP_R_MISSING_OCSPSIGNING_USAGE = 103; + OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE = 124; + OCSP_R_NOT_BASIC_RESPONSE = 104; + OCSP_R_NO_CERTIFICATES_IN_CHAIN = 105; + OCSP_R_NO_RESPONSE_DATA = 108; + OCSP_R_NO_REVOKED_TIME = 109; + OCSP_R_NO_SIGNER_KEY = 130; + OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE = 110; + OCSP_R_REQUEST_NOT_SIGNED = 128; + OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA = 111; + OCSP_R_ROOT_CA_NOT_TRUSTED = 112; + OCSP_R_SERVER_RESPONSE_ERROR = 114; + OCSP_R_SERVER_RESPONSE_PARSE_ERROR = 115; + OCSP_R_SIGNATURE_FAILURE = 117; + OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND = 118; + OCSP_R_STATUS_EXPIRED = 125; + OCSP_R_STATUS_NOT_YET_VALID = 126; + OCSP_R_STATUS_TOO_OLD = 127; + OCSP_R_UNKNOWN_MESSAGE_DIGEST = 119; + OCSP_R_UNKNOWN_NID = 120; + OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE = 129; + OCSP_DEFAULT_NONCE_LENGTH = 16; + OCSP_NOCERTS = $1; + OCSP_NOINTERN = $2; + OCSP_NOSIGS = $4; + OCSP_NOCHAIN = $8; + OCSP_NOVERIFY = $10; + OCSP_NOEXPLICIT = $20; + OCSP_NOCASIGN = $40; + OCSP_NODELEGATED = $80; + OCSP_NOCHECKS = $100; + OCSP_TRUSTOTHER = $200; + OCSP_RESPID_KEY = $400; + OCSP_NOTIME = $800; + OCSP_RESPONSE_STATUS_SUCCESSFUL = 0; + OCSP_RESPONSE_STATUS_MALFORMEDREQUEST = 1; + OCSP_RESPONSE_STATUS_INTERNALERROR = 2; + OCSP_RESPONSE_STATUS_TRYLATER = 3; + OCSP_RESPONSE_STATUS_SIGREQUIRED = 5; + OCSP_RESPONSE_STATUS_UNAUTHORIZED = 6; + V_OCSP_RESPID_NAME = 0; + V_OCSP_RESPID_KEY = 1; + V_OCSP_CERTSTATUS_GOOD = 0; + V_OCSP_CERTSTATUS_REVOKED = 1; + V_OCSP_CERTSTATUS_UNKNOWN = 2; + PEM_STRING_OCSP_REQUEST = 'OCSP REQUEST'; + PEM_STRING_OCSP_RESPONSE = 'OCSP RESPONSE'; + PKCS12_F_OPENSSL_ASC2UNI = 121; + PKCS12_F_OPENSSL_UNI2ASC = 124; + PKCS12_F_OPENSSL_UNI2UTF8 = 127; + PKCS12_F_OPENSSL_UTF82UNI = 129; + PKCS12_F_PKCS12_CREATE = 105; + PKCS12_F_PKCS12_GEN_MAC = 107; + PKCS12_F_PKCS12_INIT = 109; + PKCS12_F_PKCS12_ITEM_DECRYPT_D2I = 106; + PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT = 108; + PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG = 117; + PKCS12_F_PKCS12_KEY_GEN_ASC = 110; + PKCS12_F_PKCS12_KEY_GEN_UNI = 111; + PKCS12_F_PKCS12_KEY_GEN_UTF8 = 116; + PKCS12_F_PKCS12_NEWPASS = 128; + PKCS12_F_PKCS12_PACK_P7DATA = 114; + PKCS12_F_PKCS12_PACK_P7ENCDATA = 115; + PKCS12_F_PKCS12_PARSE = 118; + PKCS12_F_PKCS12_PBE_CRYPT = 119; + PKCS12_F_PKCS12_PBE_KEYIVGEN = 120; + PKCS12_F_PKCS12_SAFEBAG_CREATE0_P8INF = 112; + PKCS12_F_PKCS12_SAFEBAG_CREATE0_PKCS8 = 113; + PKCS12_F_PKCS12_SAFEBAG_CREATE_PKCS8_ENCRYPT = 133; + PKCS12_F_PKCS12_SETUP_MAC = 122; + PKCS12_F_PKCS12_SET_MAC = 123; + PKCS12_F_PKCS12_UNPACK_AUTHSAFES = 130; + PKCS12_F_PKCS12_UNPACK_P7DATA = 131; + PKCS12_F_PKCS12_VERIFY_MAC = 126; + PKCS12_F_PKCS8_ENCRYPT = 125; + PKCS12_F_PKCS8_SET0_PBE = 132; + PKCS12_R_CANT_PACK_STRUCTURE = 100; + PKCS12_R_CONTENT_TYPE_NOT_DATA = 121; + PKCS12_R_DECODE_ERROR = 101; + PKCS12_R_ENCODE_ERROR = 102; + PKCS12_R_ENCRYPT_ERROR = 103; + PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE = 120; + PKCS12_R_INVALID_NULL_ARGUMENT = 104; + PKCS12_R_INVALID_NULL_PKCS12_POINTER = 105; + PKCS12_R_IV_GEN_ERROR = 106; + PKCS12_R_KEY_GEN_ERROR = 107; + PKCS12_R_MAC_ABSENT = 108; + PKCS12_R_MAC_GENERATION_ERROR = 109; + PKCS12_R_MAC_SETUP_ERROR = 110; + PKCS12_R_MAC_STRING_SET_ERROR = 111; + PKCS12_R_MAC_VERIFY_FAILURE = 113; + PKCS12_R_PARSE_ERROR = 114; + PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR = 115; + PKCS12_R_PKCS12_CIPHERFINAL_ERROR = 116; + PKCS12_R_PKCS12_PBE_CRYPT_ERROR = 117; + PKCS12_R_UNKNOWN_DIGEST_ALGORITHM = 118; + PKCS12_R_UNSUPPORTED_PKCS12_MODE = 119; + PKCS12_KEY_ID = 1; + PKCS12_IV_ID = 2; + PKCS12_MAC_ID = 3; + PKCS12_DEFAULT_ITER = PKCS5_DEFAULT_ITER; + PKCS12_MAC_KEY_LENGTH = 20; + PKCS12_SALT_LEN = 8; + KEY_EX = $10; + KEY_SIG = $80; + PKCS12_ERROR = 0; + PKCS12_OK = 1; + RAND_DRBG_FLAG_CTR_NO_DF = $1; + RAND_DRBG_USED_FLAGS = (RAND_DRBG_FLAG_CTR_NO_DF); + RAND_DRBG_STRENGTH = 256; + RAND_DRBG_TYPE = NID_aes_256_ctr; + RAND_DRBG_FLAGS = 0; + _RC2_ENCRYPT = 1; + _RC2_DECRYPT = 0; + RC2_BLOCK = 8; + RC2_KEY_LENGTH = 16; + RIPEMD160_CBLOCK = 64; + RIPEMD160_LBLOCK = (RIPEMD160_CBLOCK div 4); + RIPEMD160_DIGEST_LENGTH = 20; + SEED_BLOCK_SIZE = 16; + SEED_KEY_LENGTH = 16; + SRP_NO_ERROR = 0; + SRP_ERR_VBASE_INCOMPLETE_FILE = 1; + SRP_ERR_VBASE_BN_LIB = 2; + SRP_ERR_OPEN_FILE = 3; + SRP_ERR_MEMORY = 4; + DB_srptype = 0; + DB_srpverifier = 1; + DB_srpsalt = 2; + DB_srpid = 3; + DB_srpgN = 4; + DB_srpinfo = 5; + DB_NUMBER = 6; + DB_SRP_INDEX = 'I'; + DB_SRP_VALID = 'V'; + DB_SRP_REVOKED = 'R'; + DB_SRP_MODIF = 'v'; + SRP_MINIMAL_N = 1024; + SSL_F_ADD_CLIENT_KEY_SHARE_EXT = 438; + SSL_F_ADD_KEY_SHARE = 512; + SSL_F_BYTES_TO_CIPHER_LIST = 519; + SSL_F_CHECK_SUITEB_CIPHER_LIST = 331; + SSL_F_CIPHERSUITE_CB = 622; + SSL_F_CONSTRUCT_CA_NAMES = 552; + SSL_F_CONSTRUCT_KEY_EXCHANGE_TBS = 553; + SSL_F_CONSTRUCT_STATEFUL_TICKET = 636; + SSL_F_CONSTRUCT_STATELESS_TICKET = 637; + SSL_F_CREATE_SYNTHETIC_MESSAGE_HASH = 539; + SSL_F_CREATE_TICKET_PREQUEL = 638; + SSL_F_CT_MOVE_SCTS = 345; + SSL_F_CT_STRICT = 349; + SSL_F_CUSTOM_EXT_ADD = 554; + SSL_F_CUSTOM_EXT_PARSE = 555; + SSL_F_D2I_SSL_SESSION = 103; + SSL_F_DANE_CTX_ENABLE = 347; + SSL_F_DANE_MTYPE_SET = 393; + SSL_F_DANE_TLSA_ADD = 394; + SSL_F_DERIVE_SECRET_KEY_AND_IV = 514; + SSL_F_DO_DTLS1_WRITE = 245; + SSL_F_DO_SSL3_WRITE = 104; + SSL_F_DTLS1_BUFFER_RECORD = 247; + SSL_F_DTLS1_CHECK_TIMEOUT_NUM = 318; + SSL_F_DTLS1_HEARTBEAT = 305; + SSL_F_DTLS1_HM_FRAGMENT_NEW = 623; + SSL_F_DTLS1_PREPROCESS_FRAGMENT = 288; + SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS = 424; + SSL_F_DTLS1_PROCESS_RECORD = 257; + SSL_F_DTLS1_READ_BYTES = 258; + SSL_F_DTLS1_READ_FAILED = 339; + SSL_F_DTLS1_RETRANSMIT_MESSAGE = 390; + SSL_F_DTLS1_WRITE_APP_DATA_BYTES = 268; + SSL_F_DTLS1_WRITE_BYTES = 545; + SSL_F_DTLSV1_LISTEN = 350; + SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC = 371; + SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST = 385; + SSL_F_DTLS_GET_REASSEMBLED_MESSAGE = 370; + SSL_F_DTLS_PROCESS_HELLO_VERIFY = 386; + SSL_F_DTLS_RECORD_LAYER_NEW = 635; + SSL_F_DTLS_WAIT_FOR_DRY = 592; + SSL_F_EARLY_DATA_COUNT_OK = 532; + SSL_F_FINAL_EARLY_DATA = 556; + SSL_F_FINAL_EC_PT_FORMATS = 485; + SSL_F_FINAL_EMS = 486; + SSL_F_FINAL_KEY_SHARE = 503; + SSL_F_FINAL_MAXFRAGMENTLEN = 557; + SSL_F_FINAL_RENEGOTIATE = 483; + SSL_F_FINAL_SERVER_NAME = 558; + SSL_F_FINAL_SIG_ALGS = 497; + SSL_F_GET_CERT_VERIFY_TBS_DATA = 588; + SSL_F_NSS_KEYLOG_INT = 500; + SSL_F_OPENSSL_INIT_SSL = 342; + SSL_F_OSSL_STATEM_CLIENT13_READ_TRANSITION = 436; + SSL_F_OSSL_STATEM_CLIENT13_WRITE_TRANSITION = 598; + SSL_F_OSSL_STATEM_CLIENT_CONSTRUCT_MESSAGE = 430; + SSL_F_OSSL_STATEM_CLIENT_POST_PROCESS_MESSAGE = 593; + SSL_F_OSSL_STATEM_CLIENT_PROCESS_MESSAGE = 594; + SSL_F_OSSL_STATEM_CLIENT_READ_TRANSITION = 417; + SSL_F_OSSL_STATEM_CLIENT_WRITE_TRANSITION = 599; + SSL_F_OSSL_STATEM_SERVER13_READ_TRANSITION = 437; + SSL_F_OSSL_STATEM_SERVER13_WRITE_TRANSITION = 600; + SSL_F_OSSL_STATEM_SERVER_CONSTRUCT_MESSAGE = 431; + SSL_F_OSSL_STATEM_SERVER_POST_PROCESS_MESSAGE = 601; + SSL_F_OSSL_STATEM_SERVER_POST_WORK = 602; + SSL_F_OSSL_STATEM_SERVER_PRE_WORK = 640; + SSL_F_OSSL_STATEM_SERVER_PROCESS_MESSAGE = 603; + SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION = 418; + SSL_F_OSSL_STATEM_SERVER_WRITE_TRANSITION = 604; + SSL_F_PARSE_CA_NAMES = 541; + SSL_F_PITEM_NEW = 624; + SSL_F_PQUEUE_NEW = 625; + SSL_F_PROCESS_KEY_SHARE_EXT = 439; + SSL_F_READ_STATE_MACHINE = 352; + SSL_F_SET_CLIENT_CIPHERSUITE = 540; + SSL_F_SRP_GENERATE_CLIENT_MASTER_SECRET = 595; + SSL_F_SRP_GENERATE_SERVER_MASTER_SECRET = 589; + SSL_F_SRP_VERIFY_SERVER_PARAM = 596; + SSL_F_SSL3_CHANGE_CIPHER_STATE = 129; + SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM = 130; + SSL_F_SSL3_CTRL = 213; + SSL_F_SSL3_CTX_CTRL = 133; + SSL_F_SSL3_DIGEST_CACHED_RECORDS = 293; + SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC = 292; + SSL_F_SSL3_ENC = 608; + SSL_F_SSL3_FINAL_FINISH_MAC = 285; + SSL_F_SSL3_FINISH_MAC = 587; + SSL_F_SSL3_GENERATE_KEY_BLOCK = 238; + SSL_F_SSL3_GENERATE_MASTER_SECRET = 388; + SSL_F_SSL3_GET_RECORD = 143; + SSL_F_SSL3_INIT_FINISHED_MAC = 397; + SSL_F_SSL3_OUTPUT_CERT_CHAIN = 147; + SSL_F_SSL3_READ_BYTES = 148; + SSL_F_SSL3_READ_N = 149; + SSL_F_SSL3_SETUP_KEY_BLOCK = 157; + SSL_F_SSL3_SETUP_READ_BUFFER = 156; + SSL_F_SSL3_SETUP_WRITE_BUFFER = 291; + SSL_F_SSL3_WRITE_BYTES = 158; + SSL_F_SSL3_WRITE_PENDING = 159; + SSL_F_SSL_ADD_CERT_CHAIN = 316; + SSL_F_SSL_ADD_CERT_TO_BUF = 319; + SSL_F_SSL_ADD_CERT_TO_WPACKET = 493; + SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT = 298; + SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT = 277; + SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT = 307; + SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK = 215; + SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK = 216; + SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT = 299; + SSL_F_SSL_ADD_SERVERHELLO_TLSEXT = 278; + SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT = 308; + SSL_F_SSL_BAD_METHOD = 160; + SSL_F_SSL_BUILD_CERT_CHAIN = 332; + SSL_F_SSL_BYTES_TO_CIPHER_LIST = 161; + SSL_F_SSL_CACHE_CIPHERLIST = 520; + SSL_F_SSL_CERT_ADD0_CHAIN_CERT = 346; + SSL_F_SSL_CERT_DUP = 221; + SSL_F_SSL_CERT_NEW = 162; + SSL_F_SSL_CERT_SET0_CHAIN = 340; + SSL_F_SSL_CHECK_PRIVATE_KEY = 163; + SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT = 280; + SSL_F_SSL_CHECK_SRP_EXT_CLIENTHELLO = 606; + SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG = 279; + SSL_F_SSL_CHOOSE_CLIENT_VERSION = 607; + SSL_F_SSL_CIPHER_DESCRIPTION = 626; + SSL_F_SSL_CIPHER_LIST_TO_BYTES = 425; + SSL_F_SSL_CIPHER_PROCESS_RULESTR = 230; + SSL_F_SSL_CIPHER_STRENGTH_SORT = 231; + SSL_F_SSL_CLEAR = 164; + SSL_F_SSL_CLIENT_HELLO_GET1_EXTENSIONS_PRESENT = 627; + SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD = 165; + SSL_F_SSL_CONF_CMD = 334; + SSL_F_SSL_CREATE_CIPHER_LIST = 166; + SSL_F_SSL_CTRL = 232; + SSL_F_SSL_CTX_CHECK_PRIVATE_KEY = 168; + SSL_F_SSL_CTX_ENABLE_CT = 398; + SSL_F_SSL_CTX_MAKE_PROFILES = 309; + SSL_F_SSL_CTX_NEW = 169; + SSL_F_SSL_CTX_SET_ALPN_PROTOS = 343; + SSL_F_SSL_CTX_SET_CIPHER_LIST = 269; + SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE = 290; + SSL_F_SSL_CTX_SET_CT_VALIDATION_CALLBACK = 396; + SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT = 219; + SSL_F_SSL_CTX_SET_SSL_VERSION = 170; + SSL_F_SSL_CTX_SET_TLSEXT_MAX_FRAGMENT_LENGTH = 551; + SSL_F_SSL_CTX_USE_CERTIFICATE = 171; + SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 = 172; + SSL_F_SSL_CTX_USE_CERTIFICATE_FILE = 173; + SSL_F_SSL_CTX_USE_PRIVATEKEY = 174; + SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1 = 175; + SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE = 176; + SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT = 272; + SSL_F_SSL_CTX_USE_RSAPRIVATEKEY = 177; + SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1 = 178; + SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE = 179; + SSL_F_SSL_CTX_USE_SERVERINFO = 336; + SSL_F_SSL_CTX_USE_SERVERINFO_EX = 543; + SSL_F_SSL_CTX_USE_SERVERINFO_FILE = 337; + SSL_F_SSL_DANE_DUP = 403; + SSL_F_SSL_DANE_ENABLE = 395; + SSL_F_SSL_DERIVE = 590; + SSL_F_SSL_DO_CONFIG = 391; + SSL_F_SSL_DO_HANDSHAKE = 180; + SSL_F_SSL_DUP_CA_LIST = 408; + SSL_F_SSL_ENABLE_CT = 402; + SSL_F_SSL_GENERATE_PKEY_GROUP = 559; + SSL_F_SSL_GENERATE_SESSION_ID = 547; + SSL_F_SSL_GET_NEW_SESSION = 181; + SSL_F_SSL_GET_PREV_SESSION = 217; + SSL_F_SSL_GET_SERVER_CERT_INDEX = 322; + SSL_F_SSL_GET_SIGN_PKEY = 183; + SSL_F_SSL_HANDSHAKE_HASH = 560; + SSL_F_SSL_INIT_WBIO_BUFFER = 184; + SSL_F_SSL_KEY_UPDATE = 515; + SSL_F_SSL_LOAD_CLIENT_CA_FILE = 185; + SSL_F_SSL_LOG_MASTER_SECRET = 498; + SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE = 499; + SSL_F_SSL_MODULE_INIT = 392; + SSL_F_SSL_NEW = 186; + SSL_F_SSL_NEXT_PROTO_VALIDATE = 565; + SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT = 300; + SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT = 302; + SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT = 310; + SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT = 301; + SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT = 303; + SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT = 311; + SSL_F_SSL_PEEK = 270; + SSL_F_SSL_PEEK_EX = 432; + SSL_F_SSL_PEEK_INTERNAL = 522; + SSL_F_SSL_READ = 223; + SSL_F_SSL_READ_EARLY_DATA = 529; + SSL_F_SSL_READ_EX = 434; + SSL_F_SSL_READ_INTERNAL = 523; + SSL_F_SSL_RENEGOTIATE = 516; + SSL_F_SSL_RENEGOTIATE_ABBREVIATED = 546; + SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT = 320; + SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT = 321; + SSL_F_SSL_SESSION_DUP = 348; + SSL_F_SSL_SESSION_NEW = 189; + SSL_F_SSL_SESSION_PRINT_FP = 190; + SSL_F_SSL_SESSION_SET1_ID = 423; + SSL_F_SSL_SESSION_SET1_ID_CONTEXT = 312; + SSL_F_SSL_SET_ALPN_PROTOS = 344; + SSL_F_SSL_SET_CERT = 191; + SSL_F_SSL_SET_CERT_AND_KEY = 621; + SSL_F_SSL_SET_CIPHER_LIST = 271; + SSL_F_SSL_SET_CT_VALIDATION_CALLBACK = 399; + SSL_F_SSL_SET_FD = 192; + SSL_F_SSL_SET_PKEY = 193; + SSL_F_SSL_SET_RFD = 194; + SSL_F_SSL_SET_SESSION = 195; + SSL_F_SSL_SET_SESSION_ID_CONTEXT = 218; + SSL_F_SSL_SET_SESSION_TICKET_EXT = 294; + SSL_F_SSL_SET_TLSEXT_MAX_FRAGMENT_LENGTH = 550; + SSL_F_SSL_SET_WFD = 196; + SSL_F_SSL_SHUTDOWN = 224; + SSL_F_SSL_SRP_CTX_INIT = 313; + SSL_F_SSL_START_ASYNC_JOB = 389; + SSL_F_SSL_UNDEFINED_FUNCTION = 197; + SSL_F_SSL_UNDEFINED_VOID_FUNCTION = 244; + SSL_F_SSL_USE_CERTIFICATE = 198; + SSL_F_SSL_USE_CERTIFICATE_ASN1 = 199; + SSL_F_SSL_USE_CERTIFICATE_FILE = 200; + SSL_F_SSL_USE_PRIVATEKEY = 201; + SSL_F_SSL_USE_PRIVATEKEY_ASN1 = 202; + SSL_F_SSL_USE_PRIVATEKEY_FILE = 203; + SSL_F_SSL_USE_PSK_IDENTITY_HINT = 273; + SSL_F_SSL_USE_RSAPRIVATEKEY = 204; + SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1 = 205; + SSL_F_SSL_USE_RSAPRIVATEKEY_FILE = 206; + SSL_F_SSL_VALIDATE_CT = 400; + SSL_F_SSL_VERIFY_CERT_CHAIN = 207; + SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE = 616; + SSL_F_SSL_WRITE = 208; + SSL_F_SSL_WRITE_EARLY_DATA = 526; + SSL_F_SSL_WRITE_EARLY_FINISH = 527; + SSL_F_SSL_WRITE_EX = 433; + SSL_F_SSL_WRITE_INTERNAL = 524; + SSL_F_STATE_MACHINE = 353; + SSL_F_TLS12_CHECK_PEER_SIGALG = 333; + SSL_F_TLS12_COPY_SIGALGS = 533; + SSL_F_TLS13_CHANGE_CIPHER_STATE = 440; + SSL_F_TLS13_ENC = 609; + SSL_F_TLS13_FINAL_FINISH_MAC = 605; + SSL_F_TLS13_GENERATE_SECRET = 591; + SSL_F_TLS13_HKDF_EXPAND = 561; + SSL_F_TLS13_RESTORE_HANDSHAKE_DIGEST_FOR_PHA = 617; + SSL_F_TLS13_SAVE_HANDSHAKE_DIGEST_FOR_PHA = 618; + SSL_F_TLS13_SETUP_KEY_BLOCK = 441; + SSL_F_TLS1_CHANGE_CIPHER_STATE = 209; + SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS = 341; + SSL_F_TLS1_ENC = 401; + SSL_F_TLS1_EXPORT_KEYING_MATERIAL = 314; + SSL_F_TLS1_GET_CURVELIST = 338; + SSL_F_TLS1_PRF = 284; + SSL_F_TLS1_SAVE_U16 = 628; + SSL_F_TLS1_SETUP_KEY_BLOCK = 211; + SSL_F_TLS1_SET_GROUPS = 629; + SSL_F_TLS1_SET_RAW_SIGALGS = 630; + SSL_F_TLS1_SET_SERVER_SIGALGS = 335; + SSL_F_TLS1_SET_SHARED_SIGALGS = 631; + SSL_F_TLS1_SET_SIGALGS = 632; + SSL_F_TLS_CHOOSE_SIGALG = 513; + SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK = 354; + SSL_F_TLS_COLLECT_EXTENSIONS = 435; + SSL_F_TLS_CONSTRUCT_CERTIFICATE_AUTHORITIES = 542; + SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST = 372; + SSL_F_TLS_CONSTRUCT_CERT_STATUS = 429; + SSL_F_TLS_CONSTRUCT_CERT_STATUS_BODY = 494; + SSL_F_TLS_CONSTRUCT_CERT_VERIFY = 496; + SSL_F_TLS_CONSTRUCT_CHANGE_CIPHER_SPEC = 427; + SSL_F_TLS_CONSTRUCT_CKE_DHE = 404; + SSL_F_TLS_CONSTRUCT_CKE_ECDHE = 405; + SSL_F_TLS_CONSTRUCT_CKE_GOST = 406; + SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE = 407; + SSL_F_TLS_CONSTRUCT_CKE_RSA = 409; + SSL_F_TLS_CONSTRUCT_CKE_SRP = 410; + SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE = 484; + SSL_F_TLS_CONSTRUCT_CLIENT_HELLO = 487; + SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE = 488; + SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY = 489; + SSL_F_TLS_CONSTRUCT_CTOS_ALPN = 466; + SSL_F_TLS_CONSTRUCT_CTOS_CERTIFICATE = 355; + SSL_F_TLS_CONSTRUCT_CTOS_COOKIE = 535; + SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA = 530; + SSL_F_TLS_CONSTRUCT_CTOS_EC_PT_FORMATS = 467; + SSL_F_TLS_CONSTRUCT_CTOS_EMS = 468; + SSL_F_TLS_CONSTRUCT_CTOS_ETM = 469; + SSL_F_TLS_CONSTRUCT_CTOS_HELLO = 356; + SSL_F_TLS_CONSTRUCT_CTOS_KEY_EXCHANGE = 357; + SSL_F_TLS_CONSTRUCT_CTOS_KEY_SHARE = 470; + SSL_F_TLS_CONSTRUCT_CTOS_MAXFRAGMENTLEN = 549; + SSL_F_TLS_CONSTRUCT_CTOS_NPN = 471; + SSL_F_TLS_CONSTRUCT_CTOS_PADDING = 472; + SSL_F_TLS_CONSTRUCT_CTOS_POST_HANDSHAKE_AUTH = 619; + SSL_F_TLS_CONSTRUCT_CTOS_PSK = 501; + SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES = 509; + SSL_F_TLS_CONSTRUCT_CTOS_RENEGOTIATE = 473; + SSL_F_TLS_CONSTRUCT_CTOS_SCT = 474; + SSL_F_TLS_CONSTRUCT_CTOS_SERVER_NAME = 475; + SSL_F_TLS_CONSTRUCT_CTOS_SESSION_TICKET = 476; + SSL_F_TLS_CONSTRUCT_CTOS_SIG_ALGS = 477; + SSL_F_TLS_CONSTRUCT_CTOS_SRP = 478; + SSL_F_TLS_CONSTRUCT_CTOS_STATUS_REQUEST = 479; + SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_GROUPS = 480; + SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS = 481; + SSL_F_TLS_CONSTRUCT_CTOS_USE_SRTP = 482; + SSL_F_TLS_CONSTRUCT_CTOS_VERIFY = 358; + SSL_F_TLS_CONSTRUCT_ENCRYPTED_EXTENSIONS = 443; + SSL_F_TLS_CONSTRUCT_END_OF_EARLY_DATA = 536; + SSL_F_TLS_CONSTRUCT_EXTENSIONS = 447; + SSL_F_TLS_CONSTRUCT_FINISHED = 359; + SSL_F_TLS_CONSTRUCT_HELLO_REQUEST = 373; + SSL_F_TLS_CONSTRUCT_HELLO_RETRY_REQUEST = 510; + SSL_F_TLS_CONSTRUCT_KEY_UPDATE = 517; + SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET = 428; + SSL_F_TLS_CONSTRUCT_NEXT_PROTO = 426; + SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE = 490; + SSL_F_TLS_CONSTRUCT_SERVER_HELLO = 491; + SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE = 492; + SSL_F_TLS_CONSTRUCT_STOC_ALPN = 451; + SSL_F_TLS_CONSTRUCT_STOC_CERTIFICATE = 374; + SSL_F_TLS_CONSTRUCT_STOC_COOKIE = 613; + SSL_F_TLS_CONSTRUCT_STOC_CRYPTOPRO_BUG = 452; + SSL_F_TLS_CONSTRUCT_STOC_DONE = 375; + SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA = 531; + SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA_INFO = 525; + SSL_F_TLS_CONSTRUCT_STOC_EC_PT_FORMATS = 453; + SSL_F_TLS_CONSTRUCT_STOC_EMS = 454; + SSL_F_TLS_CONSTRUCT_STOC_ETM = 455; + SSL_F_TLS_CONSTRUCT_STOC_HELLO = 376; + SSL_F_TLS_CONSTRUCT_STOC_KEY_EXCHANGE = 377; + SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE = 456; + SSL_F_TLS_CONSTRUCT_STOC_MAXFRAGMENTLEN = 548; + SSL_F_TLS_CONSTRUCT_STOC_NEXT_PROTO_NEG = 457; + SSL_F_TLS_CONSTRUCT_STOC_PSK = 504; + SSL_F_TLS_CONSTRUCT_STOC_RENEGOTIATE = 458; + SSL_F_TLS_CONSTRUCT_STOC_SERVER_NAME = 459; + SSL_F_TLS_CONSTRUCT_STOC_SESSION_TICKET = 460; + SSL_F_TLS_CONSTRUCT_STOC_STATUS_REQUEST = 461; + SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_GROUPS = 544; + SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_VERSIONS = 611; + SSL_F_TLS_CONSTRUCT_STOC_USE_SRTP = 462; + SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO = 521; + SSL_F_TLS_FINISH_HANDSHAKE = 597; + SSL_F_TLS_GET_MESSAGE_BODY = 351; + SSL_F_TLS_GET_MESSAGE_HEADER = 387; + SSL_F_TLS_HANDLE_ALPN = 562; + SSL_F_TLS_HANDLE_STATUS_REQUEST = 563; + SSL_F_TLS_PARSE_CERTIFICATE_AUTHORITIES = 566; + SSL_F_TLS_PARSE_CLIENTHELLO_TLSEXT = 449; + SSL_F_TLS_PARSE_CTOS_ALPN = 567; + SSL_F_TLS_PARSE_CTOS_COOKIE = 614; + SSL_F_TLS_PARSE_CTOS_EARLY_DATA = 568; + SSL_F_TLS_PARSE_CTOS_EC_PT_FORMATS = 569; + SSL_F_TLS_PARSE_CTOS_EMS = 570; + SSL_F_TLS_PARSE_CTOS_KEY_SHARE = 463; + SSL_F_TLS_PARSE_CTOS_MAXFRAGMENTLEN = 571; + SSL_F_TLS_PARSE_CTOS_POST_HANDSHAKE_AUTH = 620; + SSL_F_TLS_PARSE_CTOS_PSK = 505; + SSL_F_TLS_PARSE_CTOS_PSK_KEX_MODES = 572; + SSL_F_TLS_PARSE_CTOS_RENEGOTIATE = 464; + SSL_F_TLS_PARSE_CTOS_SERVER_NAME = 573; + SSL_F_TLS_PARSE_CTOS_SESSION_TICKET = 574; + SSL_F_TLS_PARSE_CTOS_SIG_ALGS = 575; + SSL_F_TLS_PARSE_CTOS_SIG_ALGS_CERT = 615; + SSL_F_TLS_PARSE_CTOS_SRP = 576; + SSL_F_TLS_PARSE_CTOS_STATUS_REQUEST = 577; + SSL_F_TLS_PARSE_CTOS_SUPPORTED_GROUPS = 578; + SSL_F_TLS_PARSE_CTOS_USE_SRTP = 465; + SSL_F_TLS_PARSE_STOC_ALPN = 579; + SSL_F_TLS_PARSE_STOC_COOKIE = 534; + SSL_F_TLS_PARSE_STOC_EARLY_DATA = 538; + SSL_F_TLS_PARSE_STOC_EARLY_DATA_INFO = 528; + SSL_F_TLS_PARSE_STOC_EC_PT_FORMATS = 580; + SSL_F_TLS_PARSE_STOC_KEY_SHARE = 445; + SSL_F_TLS_PARSE_STOC_MAXFRAGMENTLEN = 581; + SSL_F_TLS_PARSE_STOC_NPN = 582; + SSL_F_TLS_PARSE_STOC_PSK = 502; + SSL_F_TLS_PARSE_STOC_RENEGOTIATE = 448; + SSL_F_TLS_PARSE_STOC_SCT = 564; + SSL_F_TLS_PARSE_STOC_SERVER_NAME = 583; + SSL_F_TLS_PARSE_STOC_SESSION_TICKET = 584; + SSL_F_TLS_PARSE_STOC_STATUS_REQUEST = 585; + SSL_F_TLS_PARSE_STOC_SUPPORTED_VERSIONS = 612; + SSL_F_TLS_PARSE_STOC_USE_SRTP = 446; + SSL_F_TLS_POST_PROCESS_CLIENT_HELLO = 378; + SSL_F_TLS_POST_PROCESS_CLIENT_KEY_EXCHANGE = 384; + SSL_F_TLS_PREPARE_CLIENT_CERTIFICATE = 360; + SSL_F_TLS_PROCESS_AS_HELLO_RETRY_REQUEST = 610; + SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST = 361; + SSL_F_TLS_PROCESS_CERT_STATUS = 362; + SSL_F_TLS_PROCESS_CERT_STATUS_BODY = 495; + SSL_F_TLS_PROCESS_CERT_VERIFY = 379; + SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC = 363; + SSL_F_TLS_PROCESS_CKE_DHE = 411; + SSL_F_TLS_PROCESS_CKE_ECDHE = 412; + SSL_F_TLS_PROCESS_CKE_GOST = 413; + SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE = 414; + SSL_F_TLS_PROCESS_CKE_RSA = 415; + SSL_F_TLS_PROCESS_CKE_SRP = 416; + SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE = 380; + SSL_F_TLS_PROCESS_CLIENT_HELLO = 381; + SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE = 382; + SSL_F_TLS_PROCESS_ENCRYPTED_EXTENSIONS = 444; + SSL_F_TLS_PROCESS_END_OF_EARLY_DATA = 537; + SSL_F_TLS_PROCESS_FINISHED = 364; + SSL_F_TLS_PROCESS_HELLO_REQ = 507; + SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST = 511; + SSL_F_TLS_PROCESS_INITIAL_SERVER_FLIGHT = 442; + SSL_F_TLS_PROCESS_KEY_EXCHANGE = 365; + SSL_F_TLS_PROCESS_KEY_UPDATE = 518; + SSL_F_TLS_PROCESS_NEW_SESSION_TICKET = 366; + SSL_F_TLS_PROCESS_NEXT_PROTO = 383; + SSL_F_TLS_PROCESS_SERVER_CERTIFICATE = 367; + SSL_F_TLS_PROCESS_SERVER_DONE = 368; + SSL_F_TLS_PROCESS_SERVER_HELLO = 369; + SSL_F_TLS_PROCESS_SKE_DHE = 419; + SSL_F_TLS_PROCESS_SKE_ECDHE = 420; + SSL_F_TLS_PROCESS_SKE_PSK_PREAMBLE = 421; + SSL_F_TLS_PROCESS_SKE_SRP = 422; + SSL_F_TLS_PSK_DO_BINDER = 506; + SSL_F_TLS_SCAN_CLIENTHELLO_TLSEXT = 450; + SSL_F_TLS_SETUP_HANDSHAKE = 508; + SSL_F_USE_CERTIFICATE_CHAIN_FILE = 220; + SSL_F_WPACKET_INTERN_INIT_LEN = 633; + SSL_F_WPACKET_START_SUB_PACKET_LEN__ = 634; + SSL_F_WRITE_STATE_MACHINE = 586; + SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY = 291; + SSL_R_APP_DATA_IN_HANDSHAKE = 100; + SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT = 272; + SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE = 143; + SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE = 158; + SSL_R_BAD_CHANGE_CIPHER_SPEC = 103; + SSL_R_BAD_CIPHER = 186; + SSL_R_BAD_DATA = 390; + SSL_R_BAD_DATA_RETURNED_BY_CALLBACK = 106; + SSL_R_BAD_DECOMPRESSION = 107; + SSL_R_BAD_DH_VALUE = 102; + SSL_R_BAD_DIGEST_LENGTH = 111; + SSL_R_BAD_EARLY_DATA = 233; + SSL_R_BAD_ECC_CERT = 304; + SSL_R_BAD_ECPOINT = 306; + SSL_R_BAD_EXTENSION = 110; + SSL_R_BAD_HANDSHAKE_LENGTH = 332; + SSL_R_BAD_HANDSHAKE_STATE = 236; + SSL_R_BAD_HELLO_REQUEST = 105; + SSL_R_BAD_HRR_VERSION = 263; + SSL_R_BAD_KEY_SHARE = 108; + SSL_R_BAD_KEY_UPDATE = 122; + SSL_R_BAD_LEGACY_VERSION = 292; + SSL_R_BAD_LENGTH = 271; + SSL_R_BAD_PACKET = 240; + SSL_R_BAD_PACKET_LENGTH = 115; + SSL_R_BAD_PROTOCOL_VERSION_NUMBER = 116; + SSL_R_BAD_PSK = 219; + SSL_R_BAD_PSK_IDENTITY = 114; + SSL_R_BAD_RECORD_TYPE = 443; + SSL_R_BAD_RSA_ENCRYPT = 119; + SSL_R_BAD_SIGNATURE = 123; + SSL_R_BAD_SRP_A_LENGTH = 347; + SSL_R_BAD_SRP_PARAMETERS = 371; + SSL_R_BAD_SRTP_MKI_VALUE = 352; + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST = 353; + SSL_R_BAD_SSL_FILETYPE = 124; + SSL_R_BAD_VALUE = 384; + SSL_R_BAD_WRITE_RETRY = 127; + SSL_R_BINDER_DOES_NOT_VERIFY = 253; + SSL_R_BIO_NOT_SET = 128; + SSL_R_BLOCK_CIPHER_PAD_IS_WRONG = 129; + SSL_R_BN_LIB = 130; + SSL_R_CALLBACK_FAILED = 234; + SSL_R_CANNOT_CHANGE_CIPHER = 109; + SSL_R_CA_DN_LENGTH_MISMATCH = 131; + SSL_R_CA_KEY_TOO_SMALL = 397; + SSL_R_CA_MD_TOO_WEAK = 398; + SSL_R_CCS_RECEIVED_EARLY = 133; + SSL_R_CERTIFICATE_VERIFY_FAILED = 134; + SSL_R_CERT_CB_ERROR = 377; + SSL_R_CERT_LENGTH_MISMATCH = 135; + SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED = 218; + SSL_R_CIPHER_CODE_WRONG_LENGTH = 137; + SSL_R_CIPHER_OR_HASH_UNAVAILABLE = 138; + SSL_R_CLIENTHELLO_TLSEXT = 226; + SSL_R_COMPRESSED_LENGTH_TOO_LONG = 140; + SSL_R_COMPRESSION_DISABLED = 343; + SSL_R_COMPRESSION_FAILURE = 141; + SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE = 307; + SSL_R_COMPRESSION_LIBRARY_ERROR = 142; + SSL_R_CONNECTION_TYPE_NOT_SET = 144; + SSL_R_CONTEXT_NOT_DANE_ENABLED = 167; + SSL_R_COOKIE_GEN_CALLBACK_FAILURE = 400; + SSL_R_COOKIE_MISMATCH = 308; + SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED = 206; + SSL_R_DANE_ALREADY_ENABLED = 172; + SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL = 173; + SSL_R_DANE_NOT_ENABLED = 175; + SSL_R_DANE_TLSA_BAD_CERTIFICATE = 180; + SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE = 184; + SSL_R_DANE_TLSA_BAD_DATA_LENGTH = 189; + SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH = 192; + SSL_R_DANE_TLSA_BAD_MATCHING_TYPE = 200; + SSL_R_DANE_TLSA_BAD_PUBLIC_KEY = 201; + SSL_R_DANE_TLSA_BAD_SELECTOR = 202; + SSL_R_DANE_TLSA_NULL_DATA = 203; + SSL_R_DATA_BETWEEN_CCS_AND_FINISHED = 145; + SSL_R_DATA_LENGTH_TOO_LONG = 146; + SSL_R_DECRYPTION_FAILED = 147; + SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC = 281; + SSL_R_DH_KEY_TOO_SMALL = 394; + SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG = 148; + SSL_R_DIGEST_CHECK_FAILED = 149; + SSL_R_DTLS_MESSAGE_TOO_BIG = 334; + SSL_R_DUPLICATE_COMPRESSION_ID = 309; + SSL_R_ECC_CERT_NOT_FOR_SIGNING = 318; + SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE = 374; + SSL_R_EE_KEY_TOO_SMALL = 399; + SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST = 354; + SSL_R_ENCRYPTED_LENGTH_TOO_LONG = 150; + SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST = 151; + SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN = 204; + SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE = 194; + SSL_R_EXCESSIVE_MESSAGE_SIZE = 152; + SSL_R_EXTENSION_NOT_RECEIVED = 279; + SSL_R_EXTRA_DATA_IN_MESSAGE = 153; + SSL_R_EXT_LENGTH_MISMATCH = 163; + SSL_R_FAILED_TO_INIT_ASYNC = 405; + SSL_R_FRAGMENTED_CLIENT_HELLO = 401; + SSL_R_GOT_A_FIN_BEFORE_A_CCS = 154; + SSL_R_HTTPS_PROXY_REQUEST = 155; + SSL_R_HTTP_REQUEST = 156; + SSL_R_ILLEGAL_POINT_COMPRESSION = 162; + SSL_R_ILLEGAL_SUITEB_DIGEST = 380; + SSL_R_INAPPROPRIATE_FALLBACK = 373; + SSL_R_INCONSISTENT_COMPRESSION = 340; + SSL_R_INCONSISTENT_EARLY_DATA_ALPN = 222; + SSL_R_INCONSISTENT_EARLY_DATA_SNI = 231; + SSL_R_INCONSISTENT_EXTMS = 104; + SSL_R_INSUFFICIENT_SECURITY = 241; + SSL_R_INVALID_ALERT = 205; + SSL_R_INVALID_CCS_MESSAGE = 260; + SSL_R_INVALID_CERTIFICATE_OR_ALG = 238; + SSL_R_INVALID_COMMAND = 280; + SSL_R_INVALID_COMPRESSION_ALGORITHM = 341; + SSL_R_INVALID_CONFIG = 283; + SSL_R_INVALID_CONFIGURATION_NAME = 113; + SSL_R_INVALID_CONTEXT = 282; + SSL_R_INVALID_CT_VALIDATION_TYPE = 212; + SSL_R_INVALID_KEY_UPDATE_TYPE = 120; + SSL_R_INVALID_MAX_EARLY_DATA = 174; + SSL_R_INVALID_NULL_CMD_NAME = 385; + SSL_R_INVALID_SEQUENCE_NUMBER = 402; + SSL_R_INVALID_SERVERINFO_DATA = 388; + SSL_R_INVALID_SESSION_ID = 999; + SSL_R_INVALID_SRP_USERNAME = 357; + SSL_R_INVALID_STATUS_RESPONSE = 328; + SSL_R_INVALID_TICKET_KEYS_LENGTH = 325; + SSL_R_LENGTH_MISMATCH = 159; + SSL_R_LENGTH_TOO_LONG = 404; + SSL_R_LENGTH_TOO_SHORT = 160; + SSL_R_LIBRARY_BUG = 274; + SSL_R_LIBRARY_HAS_NO_CIPHERS = 161; + SSL_R_MISSING_DSA_SIGNING_CERT = 165; + SSL_R_MISSING_ECDSA_SIGNING_CERT = 381; + SSL_R_MISSING_FATAL = 256; + SSL_R_MISSING_PARAMETERS = 290; + SSL_R_MISSING_RSA_CERTIFICATE = 168; + SSL_R_MISSING_RSA_ENCRYPTING_CERT = 169; + SSL_R_MISSING_RSA_SIGNING_CERT = 170; + SSL_R_MISSING_SIGALGS_EXTENSION = 112; + SSL_R_MISSING_SIGNING_CERT = 221; + SSL_R_MISSING_SRP_PARAM = 358; + SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION = 209; + SSL_R_MISSING_TMP_DH_KEY = 171; + SSL_R_MISSING_TMP_ECDH_KEY = 311; + SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA = 293; + SSL_R_NOT_ON_RECORD_BOUNDARY = 182; + SSL_R_NOT_REPLACING_CERTIFICATE = 289; + SSL_R_NOT_SERVER = 284; + SSL_R_NO_APPLICATION_PROTOCOL = 235; + SSL_R_NO_CERTIFICATES_RETURNED = 176; + SSL_R_NO_CERTIFICATE_ASSIGNED = 177; + SSL_R_NO_CERTIFICATE_SET = 179; + SSL_R_NO_CHANGE_FOLLOWING_HRR = 214; + SSL_R_NO_CIPHERS_AVAILABLE = 181; + SSL_R_NO_CIPHERS_SPECIFIED = 183; + SSL_R_NO_CIPHER_MATCH = 185; + SSL_R_NO_CLIENT_CERT_METHOD = 331; + SSL_R_NO_COMPRESSION_SPECIFIED = 187; + SSL_R_NO_COOKIE_CALLBACK_SET = 287; + SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER = 330; + SSL_R_NO_METHOD_SPECIFIED = 188; + SSL_R_NO_PEM_EXTENSIONS = 389; + SSL_R_NO_PRIVATE_KEY_ASSIGNED = 190; + SSL_R_NO_PROTOCOLS_AVAILABLE = 191; + SSL_R_NO_RENEGOTIATION = 339; + SSL_R_NO_REQUIRED_DIGEST = 324; + SSL_R_NO_SHARED_CIPHER = 193; + SSL_R_NO_SHARED_GROUPS = 410; + SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS = 376; + SSL_R_NO_SRTP_PROFILES = 359; + SSL_R_NO_SUITABLE_KEY_SHARE = 101; + SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM = 118; + SSL_R_NO_VALID_SCTS = 216; + SSL_R_NO_VERIFY_COOKIE_CALLBACK = 403; + SSL_R_NULL_SSL_CTX = 195; + SSL_R_NULL_SSL_METHOD_PASSED = 196; + SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED = 197; + SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED = 344; + SSL_R_OVERFLOW_ERROR = 237; + SSL_R_PACKET_LENGTH_TOO_LONG = 198; + SSL_R_PARSE_TLSEXT = 227; + SSL_R_PATH_TOO_LONG = 270; + SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE = 199; + SSL_R_PEM_NAME_BAD_PREFIX = 391; + SSL_R_PEM_NAME_TOO_SHORT = 392; + SSL_R_PIPELINE_FAILURE = 406; + SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR = 278; + SSL_R_PRIVATE_KEY_MISMATCH = 288; + SSL_R_PROTOCOL_IS_SHUTDOWN = 207; + SSL_R_PSK_IDENTITY_NOT_FOUND = 223; + SSL_R_PSK_NO_CLIENT_CB = 224; + SSL_R_PSK_NO_SERVER_CB = 225; + SSL_R_READ_BIO_NOT_SET = 211; + SSL_R_READ_TIMEOUT_EXPIRED = 312; + SSL_R_RECORD_LENGTH_MISMATCH = 213; + SSL_R_RECORD_TOO_SMALL = 298; + SSL_R_RENEGOTIATE_EXT_TOO_LONG = 335; + SSL_R_RENEGOTIATION_ENCODING_ERR = 336; + SSL_R_RENEGOTIATION_MISMATCH = 337; + SSL_R_REQUEST_PENDING = 285; + SSL_R_REQUEST_SENT = 286; + SSL_R_REQUIRED_CIPHER_MISSING = 215; + SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING = 342; + SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING = 345; + SSL_R_SCT_VERIFICATION_FAILED = 208; + SSL_R_SERVERHELLO_TLSEXT = 275; + SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED = 277; + SSL_R_SHUTDOWN_WHILE_IN_INIT = 407; + SSL_R_SIGNATURE_ALGORITHMS_ERROR = 360; + SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE = 220; + SSL_R_SRP_A_CALC = 361; + SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES = 362; + SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG = 363; + SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE = 364; + SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH = 232; + SSL_R_SSL3_EXT_INVALID_SERVERNAME = 319; + SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE = 320; + SSL_R_SSL3_SESSION_ID_TOO_LONG = 300; + SSL_R_SSLV3_ALERT_BAD_CERTIFICATE = 1042; + SSL_R_SSLV3_ALERT_BAD_RECORD_MAC = 1020; + SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED = 1045; + SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED = 1044; + SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN = 1046; + SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE = 1030; + SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE = 1040; + SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER = 1047; + SSL_R_SSLV3_ALERT_NO_CERTIFICATE = 1041; + SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE = 1010; + SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE = 1043; + SSL_R_SSL_COMMAND_SECTION_EMPTY = 117; + SSL_R_SSL_COMMAND_SECTION_NOT_FOUND = 125; + SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION = 228; + SSL_R_SSL_HANDSHAKE_FAILURE = 229; + SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS = 230; + SSL_R_SSL_NEGATIVE_LENGTH = 372; + SSL_R_SSL_SECTION_EMPTY = 126; + SSL_R_SSL_SECTION_NOT_FOUND = 136; + SSL_R_SSL_SESSION_ID_CALLBACK_FAILED = 301; + SSL_R_SSL_SESSION_ID_CONFLICT = 302; + SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG = 273; + SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH = 303; + SSL_R_SSL_SESSION_ID_TOO_LONG = 408; + SSL_R_SSL_SESSION_VERSION_MISMATCH = 210; + SSL_R_STILL_IN_INIT = 121; + SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED = 1116; + SSL_R_TLSV13_ALERT_MISSING_EXTENSION = 1109; + SSL_R_TLSV1_ALERT_ACCESS_DENIED = 1049; + SSL_R_TLSV1_ALERT_DECODE_ERROR = 1050; + SSL_R_TLSV1_ALERT_DECRYPTION_FAILED = 1021; + SSL_R_TLSV1_ALERT_DECRYPT_ERROR = 1051; + SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION = 1060; + SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK = 1086; + SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY = 1071; + SSL_R_TLSV1_ALERT_INTERNAL_ERROR = 1080; + SSL_R_TLSV1_ALERT_NO_RENEGOTIATION = 1100; + SSL_R_TLSV1_ALERT_PROTOCOL_VERSION = 1070; + SSL_R_TLSV1_ALERT_RECORD_OVERFLOW = 1022; + SSL_R_TLSV1_ALERT_UNKNOWN_CA = 1048; + SSL_R_TLSV1_ALERT_USER_CANCELLED = 1090; + SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE = 1114; + SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE = 1113; + SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE = 1111; + SSL_R_TLSV1_UNRECOGNIZED_NAME = 1112; + SSL_R_TLSV1_UNSUPPORTED_EXTENSION = 1110; + SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT = 365; + SSL_R_TLS_HEARTBEAT_PENDING = 366; + SSL_R_TLS_ILLEGAL_EXPORTER_LABEL = 367; + SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST = 157; + SSL_R_TOO_MANY_KEY_UPDATES = 132; + SSL_R_TOO_MANY_WARN_ALERTS = 409; + SSL_R_TOO_MUCH_EARLY_DATA = 164; + SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS = 314; + SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS = 239; + SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES = 242; + SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES = 243; + SSL_R_UNEXPECTED_CCS_MESSAGE = 262; + SSL_R_UNEXPECTED_END_OF_EARLY_DATA = 178; + SSL_R_UNEXPECTED_MESSAGE = 244; + SSL_R_UNEXPECTED_RECORD = 245; + SSL_R_UNINITIALIZED = 276; + SSL_R_UNKNOWN_ALERT_TYPE = 246; + SSL_R_UNKNOWN_CERTIFICATE_TYPE = 247; + SSL_R_UNKNOWN_CIPHER_RETURNED = 248; + SSL_R_UNKNOWN_CIPHER_TYPE = 249; + SSL_R_UNKNOWN_CMD_NAME = 386; + SSL_R_UNKNOWN_COMMAND = 139; + SSL_R_UNKNOWN_DIGEST = 368; + SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE = 250; + SSL_R_UNKNOWN_PKEY_TYPE = 251; + SSL_R_UNKNOWN_PROTOCOL = 252; + SSL_R_UNKNOWN_SSL_VERSION = 254; + SSL_R_UNKNOWN_STATE = 255; + SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED = 338; + SSL_R_UNSOLICITED_EXTENSION = 217; + SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM = 257; + SSL_R_UNSUPPORTED_ELLIPTIC_CURVE = 315; + SSL_R_UNSUPPORTED_PROTOCOL = 258; + SSL_R_UNSUPPORTED_SSL_VERSION = 259; + SSL_R_UNSUPPORTED_STATUS_TYPE = 329; + SSL_R_USE_SRTP_NOT_NEGOTIATED = 369; + SSL_R_VERSION_TOO_HIGH = 166; + SSL_R_VERSION_TOO_LOW = 396; + SSL_R_WRONG_CERTIFICATE_TYPE = 383; + SSL_R_WRONG_CIPHER_RETURNED = 261; + SSL_R_WRONG_CURVE = 378; + SSL_R_WRONG_SIGNATURE_LENGTH = 264; + SSL_R_WRONG_SIGNATURE_SIZE = 265; + SSL_R_WRONG_SIGNATURE_TYPE = 370; + SSL_R_WRONG_SSL_VERSION = 266; + SSL_R_WRONG_VERSION_NUMBER = 267; + SSL_R_X509_LIB = 268; + SSL_R_X509_VERIFICATION_SETUP_PROBLEMS = 269; + SSL_SESSION_ASN1_VERSION = $0001; + SSL_MAX_SSL_SESSION_ID_LENGTH = 32; + SSL_MAX_SID_CTX_LENGTH = 32; + SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES = (512 div 8); + SSL_MAX_KEY_ARG_LENGTH = 8; + SSL_MAX_MASTER_KEY_LENGTH = 48; + SSL_MAX_PIPELINES = 32; + SSL_TXT_LOW = 'LOW'; + SSL_TXT_MEDIUM = 'MEDIUM'; + SSL_TXT_HIGH = 'HIGH'; + SSL_TXT_FIPS = 'FIPS'; + SSL_TXT_aNULL = 'aNULL'; + SSL_TXT_eNULL = 'eNULL'; + SSL_TXT_NULL = 'NULL'; + SSL_TXT_kRSA = 'kRSA'; + SSL_TXT_kDHr = 'kDHr'; + SSL_TXT_kDHd = 'kDHd'; + SSL_TXT_kDH = 'kDH'; + SSL_TXT_kEDH = 'kEDH'; + SSL_TXT_kDHE = 'kDHE'; + SSL_TXT_kECDHr = 'kECDHr'; + SSL_TXT_kECDHe = 'kECDHe'; + SSL_TXT_kECDH = 'kECDH'; + SSL_TXT_kEECDH = 'kEECDH'; +// SSL_TXT_kECDHE = 'kECDHE'; + SSL_TXT_kPSK = 'kPSK'; + SSL_TXT_kRSAPSK = 'kRSAPSK'; + SSL_TXT_kECDHEPSK = 'kECDHEPSK'; + SSL_TXT_kDHEPSK = 'kDHEPSK'; + SSL_TXT_kGOST = 'kGOST'; + SSL_TXT_kSRP = 'kSRP'; + SSL_TXT_aRSA = 'aRSA'; + SSL_TXT_aDSS = 'aDSS'; + SSL_TXT_aDH = 'aDH'; + SSL_TXT_aECDH = 'aECDH'; + SSL_TXT_aECDSA = 'aECDSA'; + SSL_TXT_aPSK = 'aPSK'; + SSL_TXT_aGOST94 = 'aGOST94'; + SSL_TXT_aGOST01 = 'aGOST01'; + SSL_TXT_aGOST12 = 'aGOST12'; + SSL_TXT_aGOST = 'aGOST'; + SSL_TXT_aSRP = 'aSRP'; + SSL_TXT_DSS = 'DSS'; + SSL_TXT_DH = 'DH'; + SSL_TXT_DHE = 'DHE'; + SSL_TXT_EDH = 'EDH'; +// SSL_TXT_ADH = 'ADH'; + SSL_TXT_RSA = 'RSA'; + SSL_TXT_ECDH = 'ECDH'; + SSL_TXT_EECDH = 'EECDH'; + SSL_TXT_ECDHE = 'ECDHE'; +// SSL_TXT_AECDH = 'AECDH'; + SSL_TXT_ECDSA = 'ECDSA'; + SSL_TXT_PSK = 'PSK'; + SSL_TXT_SRP = 'SRP'; + SSL_TXT_DES = 'DES'; + SSL_TXT_3DES = '3DES'; + SSL_TXT_RC4 = 'RC4'; + SSL_TXT_RC2 = 'RC2'; + SSL_TXT_IDEA = 'IDEA'; + SSL_TXT_SEED = 'SEED'; + SSL_TXT_AES128 = 'AES128'; + SSL_TXT_AES256 = 'AES256'; + SSL_TXT_AES = 'AES'; + SSL_TXT_AES_GCM = 'AESGCM'; + SSL_TXT_AES_CCM = 'AESCCM'; + SSL_TXT_AES_CCM_8 = 'AESCCM8'; + SSL_TXT_CAMELLIA128 = 'CAMELLIA128'; + SSL_TXT_CAMELLIA256 = 'CAMELLIA256'; + SSL_TXT_CAMELLIA = 'CAMELLIA'; + SSL_TXT_CHACHA20 = 'CHACHA20'; + SSL_TXT_GOST = 'GOST89'; + SSL_TXT_ARIA = 'ARIA'; + SSL_TXT_ARIA_GCM = 'ARIAGCM'; + SSL_TXT_ARIA128 = 'ARIA128'; + SSL_TXT_ARIA256 = 'ARIA256'; + SSL_TXT_MD5 = 'MD5'; + SSL_TXT_SHA1 = 'SHA1'; + SSL_TXT_SHA = 'SHA'; + SSL_TXT_GOST94 = 'GOST94'; + SSL_TXT_GOST89MAC = 'GOST89MAC'; + SSL_TXT_GOST12 = 'GOST12'; + SSL_TXT_GOST89MAC12 = 'GOST89MAC12'; + SSL_TXT_SHA256 = 'SHA256'; + SSL_TXT_SHA384 = 'SHA384'; + SSL_TXT_SSLV3 = 'SSLv3'; + SSL_TXT_TLSV1 = 'TLSv1'; + SSL_TXT_TLSV1_1 = 'TLSv1.1'; + SSL_TXT_TLSV1_2 = 'TLSv1.2'; + SSL_TXT_ALL = 'ALL'; + SSL_TXT_CMPALL = 'COMPLEMENTOFALL'; + SSL_TXT_CMPDEF = 'COMPLEMENTOFDEFAULT'; + SSL_DEFAULT_CIPHER_LIST = 'ALL:!COMPLEMENTOFDEFAULT:!eNULL'; + TLS_DEFAULT_CIPHERSUITES = 'TLS_AES_256_GCM_SHA384:' + 'TLS_CHACHA20_POLY1305_SHA256:' + 'TLS_AES_128_GCM_SHA256'; + SSL_SENT_SHUTDOWN = 1; + SSL_RECEIVED_SHUTDOWN = 2; + SSL_FILETYPE_ASN1 = X509_FILETYPE_ASN1; + SSL_FILETYPE_PEM = X509_FILETYPE_PEM; + SSL_EXT_TLS_ONLY = $0001; + SSL_EXT_DTLS_ONLY = $0002; + SSL_EXT_TLS_IMPLEMENTATION_ONLY = $0004; + SSL_EXT_SSL3_ALLOWED = $0008; + SSL_EXT_TLS1_2_AND_BELOW_ONLY = $0010; + SSL_EXT_TLS1_3_ONLY = $0020; + SSL_EXT_IGNORE_ON_RESUMPTION = $0040; + SSL_EXT_CLIENT_HELLO = $0080; + SSL_EXT_TLS1_2_SERVER_HELLO = $0100; + SSL_EXT_TLS1_3_SERVER_HELLO = $0200; + SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS = $0400; + SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST = $0800; + SSL_EXT_TLS1_3_CERTIFICATE = $1000; + SSL_EXT_TLS1_3_NEW_SESSION_TICKET = $2000; + SSL_EXT_TLS1_3_CERTIFICATE_REQUEST = $4000; + SSL_OP_LEGACY_SERVER_CONNECT = $00000004; + SSL_OP_TLSEXT_PADDING = $00000010; + SSL_OP_SAFARI_ECDHE_ECDSA_BUG = $00000040; + SSL_OP_ALLOW_NO_DHE_KEX = $00000400; + SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS = $00000800; + SSL_OP_NO_QUERY_MTU = $00001000; + SSL_OP_COOKIE_EXCHANGE = $00002000; + SSL_OP_NO_TICKET = $00004000; + SSL_OP_CISCO_ANYCONNECT = $00008000; + SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION = $00010000; + SSL_OP_NO_COMPRESSION = $00020000; + SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION = $00040000; + SSL_OP_NO_ENCRYPT_THEN_MAC = $00080000; + SSL_OP_ENABLE_MIDDLEBOX_COMPAT = $00100000; + SSL_OP_PRIORITIZE_CHACHA = $00200000; + SSL_OP_CIPHER_SERVER_PREFERENCE = $00400000; + SSL_OP_TLS_ROLLBACK_BUG = $00800000; + SSL_OP_NO_ANTI_REPLAY = $01000000; + SSL_OP_NO_SSLv3 = $02000000; + SSL_OP_NO_TLSv1 = $04000000; + SSL_OP_NO_TLSv1_2 = $08000000; + SSL_OP_NO_TLSv1_1 = $10000000; + SSL_OP_NO_TLSv1_3 = $20000000; + SSL_OP_NO_DTLSv1 = $04000000; + SSL_OP_NO_DTLSv1_2 = $08000000; + SSL_OP_NO_SSL_MASK = (SSL_OP_NO_SSLv3 or SSL_OP_NO_TLSv1 or SSL_OP_NO_TLSv1_1 or SSL_OP_NO_TLSv1_2 or SSL_OP_NO_TLSv1_3); + SSL_OP_NO_DTLS_MASK = (SSL_OP_NO_DTLSv1 or SSL_OP_NO_DTLSv1_2); + SSL_OP_NO_RENEGOTIATION = $40000000; + SSL_OP_CRYPTOPRO_TLSEXT_BUG = $80000000; + SSL_OP_ALL = (SSL_OP_CRYPTOPRO_TLSEXT_BUG or SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS or SSL_OP_LEGACY_SERVER_CONNECT or SSL_OP_TLSEXT_PADDING or SSL_OP_SAFARI_ECDHE_ECDSA_BUG); + SSL_OP_MICROSOFT_SESS_ID_BUG = $0; + SSL_OP_NETSCAPE_CHALLENGE_BUG = $0; + SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = $0; + SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG = $0; + SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER = $0; + SSL_OP_MSIE_SSLV2_RSA_PADDING = $0; + SSL_OP_SSLEAY_080_CLIENT_DH_BUG = $0; + SSL_OP_TLS_D5_BUG = $0; + SSL_OP_TLS_BLOCK_PADDING_BUG = $0; + SSL_OP_SINGLE_ECDH_USE = $0; + SSL_OP_SINGLE_DH_USE = $0; + SSL_OP_EPHEMERAL_RSA = $0; + SSL_OP_NO_SSLv2 = $0; + SSL_OP_PKCS1_CHECK_1 = $0; + SSL_OP_PKCS1_CHECK_2 = $0; + SSL_OP_NETSCAPE_CA_DN_BUG = $0; + SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = $0; + SSL_MODE_ENABLE_PARTIAL_WRITE = $00000001; + SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER = $00000002; + SSL_MODE_AUTO_RETRY = $00000004; + SSL_MODE_NO_AUTO_CHAIN = $00000008; + SSL_MODE_RELEASE_BUFFERS = $00000010; + SSL_MODE_SEND_CLIENTHELLO_TIME = $00000020; + SSL_MODE_SEND_SERVERHELLO_TIME = $00000040; + SSL_MODE_SEND_FALLBACK_SCSV = $00000080; + SSL_MODE_ASYNC = $00000100; + SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG = $00000400; + SSL_CERT_FLAG_TLS_STRICT = $00000001; + SSL_CERT_FLAG_SUITEB_128_LOS_ONLY = $10000; + SSL_CERT_FLAG_SUITEB_192_LOS = $20000; + SSL_CERT_FLAG_SUITEB_128_LOS = $30000; + SSL_CERT_FLAG_BROKEN_PROTOCOL = $10000000; + SSL_BUILD_CHAIN_FLAG_UNTRUSTED = $1; + SSL_BUILD_CHAIN_FLAG_NO_ROOT = $2; + SSL_BUILD_CHAIN_FLAG_CHECK = $4; + SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR = $8; + SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR = $10; + CERT_PKEY_VALID = $1; + CERT_PKEY_SIGN = $2; + CERT_PKEY_EE_SIGNATURE = $10; + CERT_PKEY_CA_SIGNATURE = $20; + CERT_PKEY_EE_PARAM = $40; + CERT_PKEY_CA_PARAM = $80; + CERT_PKEY_EXPLICIT_SIGN = $100; + CERT_PKEY_ISSUER_NAME = $200; + CERT_PKEY_CERT_TYPE = $400; + CERT_PKEY_SUITEB = $800; + SSL_CONF_FLAG_CMDLINE = $1; + SSL_CONF_FLAG_FILE = $2; + SSL_CONF_FLAG_CLIENT = $4; + SSL_CONF_FLAG_SERVER = $8; + SSL_CONF_FLAG_SHOW_ERRORS = $10; + SSL_CONF_FLAG_CERTIFICATE = $20; + SSL_CONF_FLAG_REQUIRE_PRIVATE = $40; + SSL_CONF_TYPE_UNKNOWN = $0; + SSL_CONF_TYPE_STRING = $1; + SSL_CONF_TYPE_FILE = $2; + SSL_CONF_TYPE_DIR = $3; + SSL_CONF_TYPE_NONE = $4; + SSL_COOKIE_LENGTH = 4096; + SSL_MAX_CERT_LIST_DEFAULT = 1024*100; + SSL_SESSION_CACHE_MAX_SIZE_DEFAULT = (1024*20); + SSL_SESS_CACHE_OFF = $0000; + SSL_SESS_CACHE_CLIENT = $0001; + SSL_SESS_CACHE_SERVER = $0002; + SSL_SESS_CACHE_BOTH = (SSL_SESS_CACHE_CLIENT or SSL_SESS_CACHE_SERVER); + SSL_SESS_CACHE_NO_AUTO_CLEAR = $0080; + SSL_SESS_CACHE_NO_INTERNAL_LOOKUP = $0100; + SSL_SESS_CACHE_NO_INTERNAL_STORE = $0200; + SSL_SESS_CACHE_NO_INTERNAL = (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP or SSL_SESS_CACHE_NO_INTERNAL_STORE); + OPENSSL_NPN_UNSUPPORTED = 0; + OPENSSL_NPN_NEGOTIATED = 1; + OPENSSL_NPN_NO_OVERLAP = 2; + PSK_MAX_IDENTITY_LEN = 128; + PSK_MAX_PSK_LEN = 256; + SSL_NOTHING = 1; + SSL_WRITING = 2; + SSL_READING = 3; + SSL_X509_LOOKUP = 4; + SSL_ASYNC_PAUSED = 5; + SSL_ASYNC_NO_JOBS = 6; + SSL_CLIENT_HELLO_CB = 7; + SSL_MAC_FLAG_READ_MAC_STREAM = 1; + SSL_MAC_FLAG_WRITE_MAC_STREAM = 2; + SSL2_VERSION = $0002; + SSL2_MT_CLIENT_HELLO = 1; + SSL3_CK_SCSV = $030000FF; + SSL3_CK_FALLBACK_SCSV = $03005600; + SSL3_CK_RSA_NULL_MD5 = $03000001; + SSL3_CK_RSA_NULL_SHA = $03000002; + SSL3_CK_RSA_RC4_40_MD5 = $03000003; + SSL3_CK_RSA_RC4_128_MD5 = $03000004; + SSL3_CK_RSA_RC4_128_SHA = $03000005; + SSL3_CK_RSA_RC2_40_MD5 = $03000006; + SSL3_CK_RSA_IDEA_128_SHA = $03000007; + SSL3_CK_RSA_DES_40_CBC_SHA = $03000008; + SSL3_CK_RSA_DES_64_CBC_SHA = $03000009; + SSL3_CK_RSA_DES_192_CBC3_SHA = $0300000A; + SSL3_CK_DH_DSS_DES_40_CBC_SHA = $0300000B; + SSL3_CK_DH_DSS_DES_64_CBC_SHA = $0300000C; + SSL3_CK_DH_DSS_DES_192_CBC3_SHA = $0300000D; + SSL3_CK_DH_RSA_DES_40_CBC_SHA = $0300000E; + SSL3_CK_DH_RSA_DES_64_CBC_SHA = $0300000F; + SSL3_CK_DH_RSA_DES_192_CBC3_SHA = $03000010; + SSL3_CK_DHE_DSS_DES_40_CBC_SHA = $03000011; + SSL3_CK_EDH_DSS_DES_40_CBC_SHA = SSL3_CK_DHE_DSS_DES_40_CBC_SHA; + SSL3_CK_DHE_DSS_DES_64_CBC_SHA = $03000012; + SSL3_CK_EDH_DSS_DES_64_CBC_SHA = SSL3_CK_DHE_DSS_DES_64_CBC_SHA; + SSL3_CK_DHE_DSS_DES_192_CBC3_SHA = $03000013; + SSL3_CK_EDH_DSS_DES_192_CBC3_SHA = SSL3_CK_DHE_DSS_DES_192_CBC3_SHA; + SSL3_CK_DHE_RSA_DES_40_CBC_SHA = $03000014; + SSL3_CK_EDH_RSA_DES_40_CBC_SHA = SSL3_CK_DHE_RSA_DES_40_CBC_SHA; + SSL3_CK_DHE_RSA_DES_64_CBC_SHA = $03000015; + SSL3_CK_EDH_RSA_DES_64_CBC_SHA = SSL3_CK_DHE_RSA_DES_64_CBC_SHA; + SSL3_CK_DHE_RSA_DES_192_CBC3_SHA = $03000016; + SSL3_CK_EDH_RSA_DES_192_CBC3_SHA = SSL3_CK_DHE_RSA_DES_192_CBC3_SHA; + SSL3_CK_ADH_RC4_40_MD5 = $03000017; + SSL3_CK_ADH_RC4_128_MD5 = $03000018; + SSL3_CK_ADH_DES_40_CBC_SHA = $03000019; + SSL3_CK_ADH_DES_64_CBC_SHA = $0300001A; + SSL3_CK_ADH_DES_192_CBC_SHA = $0300001B; + SSL3_RFC_RSA_NULL_MD5 = 'TLS_RSA_WITH_NULL_MD5'; + SSL3_RFC_RSA_NULL_SHA = 'TLS_RSA_WITH_NULL_SHA'; + SSL3_RFC_RSA_DES_192_CBC3_SHA = 'TLS_RSA_WITH_3DES_EDE_CBC_SHA'; + SSL3_RFC_DHE_DSS_DES_192_CBC3_SHA = 'TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA'; + SSL3_RFC_DHE_RSA_DES_192_CBC3_SHA = 'TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA'; + SSL3_RFC_ADH_DES_192_CBC_SHA = 'TLS_DH_anon_WITH_3DES_EDE_CBC_SHA'; + SSL3_RFC_RSA_IDEA_128_SHA = 'TLS_RSA_WITH_IDEA_CBC_SHA'; + SSL3_RFC_RSA_RC4_128_MD5 = 'TLS_RSA_WITH_RC4_128_MD5'; + SSL3_RFC_RSA_RC4_128_SHA = 'TLS_RSA_WITH_RC4_128_SHA'; + SSL3_RFC_ADH_RC4_128_MD5 = 'TLS_DH_anon_WITH_RC4_128_MD5'; + SSL3_TXT_RSA_NULL_MD5 = 'NULL-MD5'; + SSL3_TXT_RSA_NULL_SHA = 'NULL-SHA'; + SSL3_TXT_RSA_RC4_40_MD5 = 'EXP-RC4-MD5'; + SSL3_TXT_RSA_RC4_128_MD5 = 'RC4-MD5'; + SSL3_TXT_RSA_RC4_128_SHA = 'RC4-SHA'; + SSL3_TXT_RSA_RC2_40_MD5 = 'EXP-RC2-CBC-MD5'; + SSL3_TXT_RSA_IDEA_128_SHA = 'IDEA-CBC-SHA'; + SSL3_TXT_RSA_DES_40_CBC_SHA = 'EXP-DES-CBC-SHA'; + SSL3_TXT_RSA_DES_64_CBC_SHA = 'DES-CBC-SHA'; + SSL3_TXT_RSA_DES_192_CBC3_SHA = 'DES-CBC3-SHA'; + SSL3_TXT_DH_DSS_DES_40_CBC_SHA = 'EXP-DH-DSS-DES-CBC-SHA'; + SSL3_TXT_DH_DSS_DES_64_CBC_SHA = 'DH-DSS-DES-CBC-SHA'; + SSL3_TXT_DH_DSS_DES_192_CBC3_SHA = 'DH-DSS-DES-CBC3-SHA'; + SSL3_TXT_DH_RSA_DES_40_CBC_SHA = 'EXP-DH-RSA-DES-CBC-SHA'; + SSL3_TXT_DH_RSA_DES_64_CBC_SHA = 'DH-RSA-DES-CBC-SHA'; + SSL3_TXT_DH_RSA_DES_192_CBC3_SHA = 'DH-RSA-DES-CBC3-SHA'; + SSL3_TXT_DHE_DSS_DES_40_CBC_SHA = 'EXP-DHE-DSS-DES-CBC-SHA'; + SSL3_TXT_DHE_DSS_DES_64_CBC_SHA = 'DHE-DSS-DES-CBC-SHA'; + SSL3_TXT_DHE_DSS_DES_192_CBC3_SHA = 'DHE-DSS-DES-CBC3-SHA'; + SSL3_TXT_DHE_RSA_DES_40_CBC_SHA = 'EXP-DHE-RSA-DES-CBC-SHA'; + SSL3_TXT_DHE_RSA_DES_64_CBC_SHA = 'DHE-RSA-DES-CBC-SHA'; + SSL3_TXT_DHE_RSA_DES_192_CBC3_SHA = 'DHE-RSA-DES-CBC3-SHA'; + SSL3_TXT_EDH_DSS_DES_40_CBC_SHA = 'EXP-EDH-DSS-DES-CBC-SHA'; + SSL3_TXT_EDH_DSS_DES_64_CBC_SHA = 'EDH-DSS-DES-CBC-SHA'; + SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA = 'EDH-DSS-DES-CBC3-SHA'; + SSL3_TXT_EDH_RSA_DES_40_CBC_SHA = 'EXP-EDH-RSA-DES-CBC-SHA'; + SSL3_TXT_EDH_RSA_DES_64_CBC_SHA = 'EDH-RSA-DES-CBC-SHA'; + SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA = 'EDH-RSA-DES-CBC3-SHA'; + SSL3_TXT_ADH_RC4_40_MD5 = 'EXP-ADH-RC4-MD5'; + SSL3_TXT_ADH_RC4_128_MD5 = 'ADH-RC4-MD5'; + SSL3_TXT_ADH_DES_40_CBC_SHA = 'EXP-ADH-DES-CBC-SHA'; + SSL3_TXT_ADH_DES_64_CBC_SHA = 'ADH-DES-CBC-SHA'; + SSL3_TXT_ADH_DES_192_CBC_SHA = 'ADH-DES-CBC3-SHA'; + SSL3_SSL_SESSION_ID_LENGTH = 32; + SSL3_MAX_SSL_SESSION_ID_LENGTH = 32; + SSL3_MASTER_SECRET_SIZE = 48; + SSL3_RANDOM_SIZE = 32; + SSL3_SESSION_ID_SIZE = 32; + SSL3_RT_HEADER_LENGTH = 5; + SSL3_HM_HEADER_LENGTH = 4; + SSL3_ALIGN_PAYLOAD = 8; + SSL3_RT_MAX_MD_SIZE = 64; + SSL_RT_MAX_CIPHER_BLOCK_SIZE = 16; + SSL3_RT_MAX_EXTRA = (16384); + SSL3_RT_MAX_PLAIN_LENGTH = 16384; + SSL3_RT_MAX_COMPRESSED_OVERHEAD = 1024; + SSL3_RT_MAX_ENCRYPTED_OVERHEAD = (256+SSL3_RT_MAX_MD_SIZE); + SSL3_RT_MAX_TLS13_ENCRYPTED_OVERHEAD = 256; + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD = (SSL_RT_MAX_CIPHER_BLOCK_SIZE+SSL3_RT_MAX_MD_SIZE); + SSL3_RT_MAX_COMPRESSED_LENGTH = (SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD); + SSL3_RT_MAX_ENCRYPTED_LENGTH = (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH); + SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH = (SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_TLS13_ENCRYPTED_OVERHEAD); + SSL3_RT_MAX_PACKET_SIZE = (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH); + SSL3_MD_CLIENT_FINISHED_CONST = #67''#76''#78''#84; + SSL3_MD_SERVER_FINISHED_CONST = #83''#82''#86''#82; + SSL3_VERSION = $0300; + SSL3_VERSION_MAJOR = $03; + SSL3_VERSION_MINOR = $00; + SSL3_RT_CHANGE_CIPHER_SPEC = 20; + SSL3_RT_ALERT = 21; + SSL3_RT_HANDSHAKE = 22; + SSL3_RT_APPLICATION_DATA = 23; + DTLS1_RT_HEARTBEAT = 24; + TLS1_RT_CRYPTO = $1000; + TLS1_RT_CRYPTO_PREMASTER = (TLS1_RT_CRYPTO or $1); + TLS1_RT_CRYPTO_CLIENT_RANDOM = (TLS1_RT_CRYPTO or $2); + TLS1_RT_CRYPTO_SERVER_RANDOM = (TLS1_RT_CRYPTO or $3); + TLS1_RT_CRYPTO_MASTER = (TLS1_RT_CRYPTO or $4); + TLS1_RT_CRYPTO_READ = $0000; + TLS1_RT_CRYPTO_WRITE = $0100; + TLS1_RT_CRYPTO_MAC = (TLS1_RT_CRYPTO or $5); + TLS1_RT_CRYPTO_KEY = (TLS1_RT_CRYPTO or $6); + TLS1_RT_CRYPTO_IV = (TLS1_RT_CRYPTO or $7); + TLS1_RT_CRYPTO_FIXED_IV = (TLS1_RT_CRYPTO or $8); + SSL3_RT_HEADER = $100; + SSL3_RT_INNER_CONTENT_TYPE = $101; + SSL3_AL_WARNING = 1; + SSL3_AL_FATAL = 2; + SSL3_AD_CLOSE_NOTIFY = 0; + SSL3_AD_UNEXPECTED_MESSAGE = 10; + SSL3_AD_BAD_RECORD_MAC = 20; + SSL3_AD_DECOMPRESSION_FAILURE = 30; + SSL3_AD_HANDSHAKE_FAILURE = 40; + SSL3_AD_NO_CERTIFICATE = 41; + SSL3_AD_BAD_CERTIFICATE = 42; + SSL3_AD_UNSUPPORTED_CERTIFICATE = 43; + SSL3_AD_CERTIFICATE_REVOKED = 44; + SSL3_AD_CERTIFICATE_EXPIRED = 45; + SSL3_AD_CERTIFICATE_UNKNOWN = 46; + SSL3_AD_ILLEGAL_PARAMETER = 47; + TLS1_HB_REQUEST = 1; + TLS1_HB_RESPONSE = 2; + SSL3_CT_RSA_SIGN = 1; + SSL3_CT_DSS_SIGN = 2; + SSL3_CT_RSA_FIXED_DH = 3; + SSL3_CT_DSS_FIXED_DH = 4; + SSL3_CT_RSA_EPHEMERAL_DH = 5; + SSL3_CT_DSS_EPHEMERAL_DH = 6; + SSL3_CT_FORTEZZA_DMS = 20; + SSL3_CT_NUMBER = 10; + SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS = $0001; + TLS1_FLAGS_TLS_PADDING_BUG = $0; + TLS1_FLAGS_SKIP_CERT_VERIFY = $0010; + TLS1_FLAGS_ENCRYPT_THEN_MAC_READ = $0100; + TLS1_FLAGS_ENCRYPT_THEN_MAC = TLS1_FLAGS_ENCRYPT_THEN_MAC_READ; + TLS1_FLAGS_RECEIVED_EXTMS = $0200; + TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE = $0400; + TLS1_FLAGS_STATELESS = $0800; + SSL3_MT_HELLO_REQUEST = 0; + SSL3_MT_CLIENT_HELLO = 1; + SSL3_MT_SERVER_HELLO = 2; + SSL3_MT_NEWSESSION_TICKET = 4; + SSL3_MT_END_OF_EARLY_DATA = 5; + SSL3_MT_ENCRYPTED_EXTENSIONS = 8; + SSL3_MT_CERTIFICATE = 11; + SSL3_MT_SERVER_KEY_EXCHANGE = 12; + SSL3_MT_CERTIFICATE_REQUEST = 13; + SSL3_MT_SERVER_DONE = 14; + SSL3_MT_CERTIFICATE_VERIFY = 15; + SSL3_MT_CLIENT_KEY_EXCHANGE = 16; + SSL3_MT_FINISHED = 20; + SSL3_MT_CERTIFICATE_URL = 21; + SSL3_MT_CERTIFICATE_STATUS = 22; + SSL3_MT_SUPPLEMENTAL_DATA = 23; + SSL3_MT_KEY_UPDATE = 24; + SSL3_MT_NEXT_PROTO = 67; + SSL3_MT_MESSAGE_HASH = 254; + DTLS1_MT_HELLO_VERIFY_REQUEST = 3; + SSL3_MT_CHANGE_CIPHER_SPEC = $0101; + SSL3_MT_CCS = 1; + SSL3_CC_READ = $001; + SSL3_CC_WRITE = $002; + SSL3_CC_CLIENT = $010; + SSL3_CC_SERVER = $020; + SSL3_CC_EARLY = $040; + SSL3_CC_HANDSHAKE = $080; + SSL3_CC_APPLICATION = $100; + SSL3_CHANGE_CIPHER_CLIENT_WRITE = (SSL3_CC_CLIENT or SSL3_CC_WRITE); + SSL3_CHANGE_CIPHER_SERVER_READ = (SSL3_CC_SERVER or SSL3_CC_READ); + SSL3_CHANGE_CIPHER_CLIENT_READ = (SSL3_CC_CLIENT or SSL3_CC_READ); + SSL3_CHANGE_CIPHER_SERVER_WRITE = (SSL3_CC_SERVER or SSL3_CC_WRITE); + OPENSSL_TLS_SECURITY_LEVEL = 1; + TLS1_VERSION = $0301; + TLS1_1_VERSION = $0302; + TLS1_2_VERSION = $0303; + TLS1_3_VERSION = $0304; + TLS_MAX_VERSION = TLS1_3_VERSION; + TLS_ANY_VERSION = $10000; + TLS1_VERSION_MAJOR = $03; + TLS1_VERSION_MINOR = $01; + TLS1_1_VERSION_MAJOR = $03; + TLS1_1_VERSION_MINOR = $02; + TLS1_2_VERSION_MAJOR = $03; + TLS1_2_VERSION_MINOR = $03; + TLS1_AD_DECRYPTION_FAILED = 21; + TLS1_AD_RECORD_OVERFLOW = 22; + TLS1_AD_UNKNOWN_CA = 48; + TLS1_AD_ACCESS_DENIED = 49; + TLS1_AD_DECODE_ERROR = 50; + TLS1_AD_DECRYPT_ERROR = 51; + TLS1_AD_EXPORT_RESTRICTION = 60; + TLS1_AD_PROTOCOL_VERSION = 70; + TLS1_AD_INSUFFICIENT_SECURITY = 71; + TLS1_AD_INTERNAL_ERROR = 80; + TLS1_AD_INAPPROPRIATE_FALLBACK = 86; + TLS1_AD_USER_CANCELLED = 90; + TLS1_AD_NO_RENEGOTIATION = 100; + TLS13_AD_MISSING_EXTENSION = 109; + TLS13_AD_CERTIFICATE_REQUIRED = 116; + TLS1_AD_UNSUPPORTED_EXTENSION = 110; + TLS1_AD_CERTIFICATE_UNOBTAINABLE = 111; + TLS1_AD_UNRECOGNIZED_NAME = 112; + TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE = 113; + TLS1_AD_BAD_CERTIFICATE_HASH_VALUE = 114; + TLS1_AD_UNKNOWN_PSK_IDENTITY = 115; + TLS1_AD_NO_APPLICATION_PROTOCOL = 120; + TLSEXT_TYPE_server_name = 0; + TLSEXT_TYPE_max_fragment_length = 1; + TLSEXT_TYPE_client_certificate_url = 2; + TLSEXT_TYPE_trusted_ca_keys = 3; + TLSEXT_TYPE_truncated_hmac = 4; + TLSEXT_TYPE_status_request = 5; + TLSEXT_TYPE_user_mapping = 6; + TLSEXT_TYPE_client_authz = 7; + TLSEXT_TYPE_server_authz = 8; + TLSEXT_TYPE_cert_type = 9; + TLSEXT_TYPE_supported_groups = 10; + TLSEXT_TYPE_elliptic_curves = TLSEXT_TYPE_supported_groups; + TLSEXT_TYPE_ec_point_formats = 11; + TLSEXT_TYPE_srp = 12; + TLSEXT_TYPE_signature_algorithms = 13; + TLSEXT_TYPE_use_srtp = 14; + TLSEXT_TYPE_heartbeat = 15; + TLSEXT_TYPE_application_layer_protocol_negotiation = 16; + TLSEXT_TYPE_signed_certificate_timestamp = 18; + TLSEXT_TYPE_padding = 21; + TLSEXT_TYPE_encrypt_then_mac = 22; + TLSEXT_TYPE_extended_master_secret = 23; + TLSEXT_TYPE_session_ticket = 35; + TLSEXT_TYPE_psk = 41; + TLSEXT_TYPE_early_data = 42; + TLSEXT_TYPE_supported_versions = 43; + TLSEXT_TYPE_cookie = 44; + TLSEXT_TYPE_psk_kex_modes = 45; + TLSEXT_TYPE_certificate_authorities = 47; + TLSEXT_TYPE_post_handshake_auth = 49; + TLSEXT_TYPE_signature_algorithms_cert = 50; + TLSEXT_TYPE_key_share = 51; + TLSEXT_TYPE_renegotiate = $ff01; + TLSEXT_TYPE_next_proto_neg = 13172; + TLSEXT_NAMETYPE_host_name = 0; + TLSEXT_STATUSTYPE_ocsp = 1; + TLSEXT_ECPOINTFORMAT_first = 0; + TLSEXT_ECPOINTFORMAT_uncompressed = 0; + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime = 1; + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 = 2; + TLSEXT_ECPOINTFORMAT_last = 2; + TLSEXT_signature_anonymous = 0; + TLSEXT_signature_rsa = 1; + TLSEXT_signature_dsa = 2; + TLSEXT_signature_ecdsa = 3; + TLSEXT_signature_gostr34102001 = 237; + TLSEXT_signature_gostr34102012_256 = 238; + TLSEXT_signature_gostr34102012_512 = 239; + TLSEXT_signature_num = 7; + TLSEXT_hash_none = 0; + TLSEXT_hash_md5 = 1; + TLSEXT_hash_sha1 = 2; + TLSEXT_hash_sha224 = 3; + TLSEXT_hash_sha256 = 4; + TLSEXT_hash_sha384 = 5; + TLSEXT_hash_sha512 = 6; + TLSEXT_hash_gostr3411 = 237; + TLSEXT_hash_gostr34112012_256 = 238; + TLSEXT_hash_gostr34112012_512 = 239; + TLSEXT_hash_num = 10; + TLSEXT_nid_unknown = $1000000; + TLSEXT_curve_P_256 = 23; + TLSEXT_curve_P_384 = 24; + TLSEXT_max_fragment_length_DISABLED = 0; + TLSEXT_max_fragment_length_512 = 1; + TLSEXT_max_fragment_length_1024 = 2; + TLSEXT_max_fragment_length_2048 = 3; + TLSEXT_max_fragment_length_4096 = 4; + TLSEXT_MAXLEN_host_name = 255; + SSL_TLSEXT_ERR_OK = 0; + SSL_TLSEXT_ERR_ALERT_WARNING = 1; + SSL_TLSEXT_ERR_ALERT_FATAL = 2; + SSL_TLSEXT_ERR_NOACK = 3; + TLS1_CK_PSK_WITH_RC4_128_SHA = $0300008A; + TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA = $0300008B; + TLS1_CK_PSK_WITH_AES_128_CBC_SHA = $0300008C; + TLS1_CK_PSK_WITH_AES_256_CBC_SHA = $0300008D; + TLS1_CK_DHE_PSK_WITH_RC4_128_SHA = $0300008E; + TLS1_CK_DHE_PSK_WITH_3DES_EDE_CBC_SHA = $0300008F; + TLS1_CK_DHE_PSK_WITH_AES_128_CBC_SHA = $03000090; + TLS1_CK_DHE_PSK_WITH_AES_256_CBC_SHA = $03000091; + TLS1_CK_RSA_PSK_WITH_RC4_128_SHA = $03000092; + TLS1_CK_RSA_PSK_WITH_3DES_EDE_CBC_SHA = $03000093; + TLS1_CK_RSA_PSK_WITH_AES_128_CBC_SHA = $03000094; + TLS1_CK_RSA_PSK_WITH_AES_256_CBC_SHA = $03000095; + TLS1_CK_PSK_WITH_AES_128_GCM_SHA256 = $030000A8; + TLS1_CK_PSK_WITH_AES_256_GCM_SHA384 = $030000A9; + TLS1_CK_DHE_PSK_WITH_AES_128_GCM_SHA256 = $030000AA; + TLS1_CK_DHE_PSK_WITH_AES_256_GCM_SHA384 = $030000AB; + TLS1_CK_RSA_PSK_WITH_AES_128_GCM_SHA256 = $030000AC; + TLS1_CK_RSA_PSK_WITH_AES_256_GCM_SHA384 = $030000AD; + TLS1_CK_PSK_WITH_AES_128_CBC_SHA256 = $030000AE; + TLS1_CK_PSK_WITH_AES_256_CBC_SHA384 = $030000AF; + TLS1_CK_PSK_WITH_NULL_SHA256 = $030000B0; + TLS1_CK_PSK_WITH_NULL_SHA384 = $030000B1; + TLS1_CK_DHE_PSK_WITH_AES_128_CBC_SHA256 = $030000B2; + TLS1_CK_DHE_PSK_WITH_AES_256_CBC_SHA384 = $030000B3; + TLS1_CK_DHE_PSK_WITH_NULL_SHA256 = $030000B4; + TLS1_CK_DHE_PSK_WITH_NULL_SHA384 = $030000B5; + TLS1_CK_RSA_PSK_WITH_AES_128_CBC_SHA256 = $030000B6; + TLS1_CK_RSA_PSK_WITH_AES_256_CBC_SHA384 = $030000B7; + TLS1_CK_RSA_PSK_WITH_NULL_SHA256 = $030000B8; + TLS1_CK_RSA_PSK_WITH_NULL_SHA384 = $030000B9; + TLS1_CK_PSK_WITH_NULL_SHA = $0300002C; + TLS1_CK_DHE_PSK_WITH_NULL_SHA = $0300002D; + TLS1_CK_RSA_PSK_WITH_NULL_SHA = $0300002E; + TLS1_CK_RSA_WITH_AES_128_SHA = $0300002F; + TLS1_CK_DH_DSS_WITH_AES_128_SHA = $03000030; + TLS1_CK_DH_RSA_WITH_AES_128_SHA = $03000031; + TLS1_CK_DHE_DSS_WITH_AES_128_SHA = $03000032; + TLS1_CK_DHE_RSA_WITH_AES_128_SHA = $03000033; + TLS1_CK_ADH_WITH_AES_128_SHA = $03000034; + TLS1_CK_RSA_WITH_AES_256_SHA = $03000035; + TLS1_CK_DH_DSS_WITH_AES_256_SHA = $03000036; + TLS1_CK_DH_RSA_WITH_AES_256_SHA = $03000037; + TLS1_CK_DHE_DSS_WITH_AES_256_SHA = $03000038; + TLS1_CK_DHE_RSA_WITH_AES_256_SHA = $03000039; + TLS1_CK_ADH_WITH_AES_256_SHA = $0300003A; + TLS1_CK_RSA_WITH_NULL_SHA256 = $0300003B; + TLS1_CK_RSA_WITH_AES_128_SHA256 = $0300003C; + TLS1_CK_RSA_WITH_AES_256_SHA256 = $0300003D; + TLS1_CK_DH_DSS_WITH_AES_128_SHA256 = $0300003E; + TLS1_CK_DH_RSA_WITH_AES_128_SHA256 = $0300003F; + TLS1_CK_DHE_DSS_WITH_AES_128_SHA256 = $03000040; + TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA = $03000041; + TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA = $03000042; + TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA = $03000043; + TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA = $03000044; + TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA = $03000045; + TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA = $03000046; + TLS1_CK_DHE_RSA_WITH_AES_128_SHA256 = $03000067; + TLS1_CK_DH_DSS_WITH_AES_256_SHA256 = $03000068; + TLS1_CK_DH_RSA_WITH_AES_256_SHA256 = $03000069; + TLS1_CK_DHE_DSS_WITH_AES_256_SHA256 = $0300006A; + TLS1_CK_DHE_RSA_WITH_AES_256_SHA256 = $0300006B; + TLS1_CK_ADH_WITH_AES_128_SHA256 = $0300006C; + TLS1_CK_ADH_WITH_AES_256_SHA256 = $0300006D; + TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA = $03000084; + TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA = $03000085; + TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA = $03000086; + TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA = $03000087; + TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA = $03000088; + TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA = $03000089; + TLS1_CK_RSA_WITH_SEED_SHA = $03000096; + TLS1_CK_DH_DSS_WITH_SEED_SHA = $03000097; + TLS1_CK_DH_RSA_WITH_SEED_SHA = $03000098; + TLS1_CK_DHE_DSS_WITH_SEED_SHA = $03000099; + TLS1_CK_DHE_RSA_WITH_SEED_SHA = $0300009A; + TLS1_CK_ADH_WITH_SEED_SHA = $0300009B; + TLS1_CK_RSA_WITH_AES_128_GCM_SHA256 = $0300009C; + TLS1_CK_RSA_WITH_AES_256_GCM_SHA384 = $0300009D; + TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256 = $0300009E; + TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384 = $0300009F; + TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256 = $030000A0; + TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384 = $030000A1; + TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256 = $030000A2; + TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384 = $030000A3; + TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256 = $030000A4; + TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384 = $030000A5; + TLS1_CK_ADH_WITH_AES_128_GCM_SHA256 = $030000A6; + TLS1_CK_ADH_WITH_AES_256_GCM_SHA384 = $030000A7; + TLS1_CK_RSA_WITH_AES_128_CCM = $0300C09C; + TLS1_CK_RSA_WITH_AES_256_CCM = $0300C09D; + TLS1_CK_DHE_RSA_WITH_AES_128_CCM = $0300C09E; + TLS1_CK_DHE_RSA_WITH_AES_256_CCM = $0300C09F; + TLS1_CK_RSA_WITH_AES_128_CCM_8 = $0300C0A0; + TLS1_CK_RSA_WITH_AES_256_CCM_8 = $0300C0A1; + TLS1_CK_DHE_RSA_WITH_AES_128_CCM_8 = $0300C0A2; + TLS1_CK_DHE_RSA_WITH_AES_256_CCM_8 = $0300C0A3; + TLS1_CK_PSK_WITH_AES_128_CCM = $0300C0A4; + TLS1_CK_PSK_WITH_AES_256_CCM = $0300C0A5; + TLS1_CK_DHE_PSK_WITH_AES_128_CCM = $0300C0A6; + TLS1_CK_DHE_PSK_WITH_AES_256_CCM = $0300C0A7; + TLS1_CK_PSK_WITH_AES_128_CCM_8 = $0300C0A8; + TLS1_CK_PSK_WITH_AES_256_CCM_8 = $0300C0A9; + TLS1_CK_DHE_PSK_WITH_AES_128_CCM_8 = $0300C0AA; + TLS1_CK_DHE_PSK_WITH_AES_256_CCM_8 = $0300C0AB; + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CCM = $0300C0AC; + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CCM = $0300C0AD; + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CCM_8 = $0300C0AE; + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CCM_8 = $0300C0AF; + TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA256 = $030000BA; + TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 = $030000BB; + TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = $030000BC; + TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 = $030000BD; + TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = $030000BE; + TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA256 = $030000BF; + TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA256 = $030000C0; + TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 = $030000C1; + TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 = $030000C2; + TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 = $030000C3; + TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 = $030000C4; + TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA256 = $030000C5; + TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA = $0300C001; + TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA = $0300C002; + TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA = $0300C003; + TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA = $0300C004; + TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA = $0300C005; + TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA = $0300C006; + TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA = $0300C007; + TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA = $0300C008; + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = $0300C009; + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = $0300C00A; + TLS1_CK_ECDH_RSA_WITH_NULL_SHA = $0300C00B; + TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA = $0300C00C; + TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA = $0300C00D; + TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA = $0300C00E; + TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA = $0300C00F; + TLS1_CK_ECDHE_RSA_WITH_NULL_SHA = $0300C010; + TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA = $0300C011; + TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA = $0300C012; + TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA = $0300C013; + TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA = $0300C014; + TLS1_CK_ECDH_anon_WITH_NULL_SHA = $0300C015; + TLS1_CK_ECDH_anon_WITH_RC4_128_SHA = $0300C016; + TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA = $0300C017; + TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA = $0300C018; + TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA = $0300C019; + TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA = $0300C01A; + TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = $0300C01B; + TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA = $0300C01C; + TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA = $0300C01D; + TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = $0300C01E; + TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA = $0300C01F; + TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA = $0300C020; + TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = $0300C021; + TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = $0300C022; + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256 = $0300C023; + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384 = $0300C024; + TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256 = $0300C025; + TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384 = $0300C026; + TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256 = $0300C027; + TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384 = $0300C028; + TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256 = $0300C029; + TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384 = $0300C02A; + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = $0300C02B; + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = $0300C02C; + TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = $0300C02D; + TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = $0300C02E; + TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = $0300C02F; + TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = $0300C030; + TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256 = $0300C031; + TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384 = $0300C032; + TLS1_CK_ECDHE_PSK_WITH_RC4_128_SHA = $0300C033; + TLS1_CK_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA = $0300C034; + TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA = $0300C035; + TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA = $0300C036; + TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA256 = $0300C037; + TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA384 = $0300C038; + TLS1_CK_ECDHE_PSK_WITH_NULL_SHA = $0300C039; + TLS1_CK_ECDHE_PSK_WITH_NULL_SHA256 = $0300C03A; + TLS1_CK_ECDHE_PSK_WITH_NULL_SHA384 = $0300C03B; + TLS1_CK_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = $0300C072; + TLS1_CK_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = $0300C073; + TLS1_CK_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = $0300C074; + TLS1_CK_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = $0300C075; + TLS1_CK_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = $0300C076; + TLS1_CK_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 = $0300C077; + TLS1_CK_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = $0300C078; + TLS1_CK_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 = $0300C079; + TLS1_CK_PSK_WITH_CAMELLIA_128_CBC_SHA256 = $0300C094; + TLS1_CK_PSK_WITH_CAMELLIA_256_CBC_SHA384 = $0300C095; + TLS1_CK_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = $0300C096; + TLS1_CK_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = $0300C097; + TLS1_CK_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 = $0300C098; + TLS1_CK_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 = $0300C099; + TLS1_CK_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = $0300C09A; + TLS1_CK_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = $0300C09B; + TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305 = $0300CCA8; + TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = $0300CCA9; + TLS1_CK_DHE_RSA_WITH_CHACHA20_POLY1305 = $0300CCAA; + TLS1_CK_PSK_WITH_CHACHA20_POLY1305 = $0300CCAB; + TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305 = $0300CCAC; + TLS1_CK_DHE_PSK_WITH_CHACHA20_POLY1305 = $0300CCAD; + TLS1_CK_RSA_PSK_WITH_CHACHA20_POLY1305 = $0300CCAE; + TLS1_3_CK_AES_128_GCM_SHA256 = $03001301; + TLS1_3_CK_AES_256_GCM_SHA384 = $03001302; + TLS1_3_CK_CHACHA20_POLY1305_SHA256 = $03001303; + TLS1_3_CK_AES_128_CCM_SHA256 = $03001304; + TLS1_3_CK_AES_128_CCM_8_SHA256 = $03001305; + TLS1_CK_RSA_WITH_ARIA_128_GCM_SHA256 = $0300C050; + TLS1_CK_RSA_WITH_ARIA_256_GCM_SHA384 = $0300C051; + TLS1_CK_DHE_RSA_WITH_ARIA_128_GCM_SHA256 = $0300C052; + TLS1_CK_DHE_RSA_WITH_ARIA_256_GCM_SHA384 = $0300C053; + TLS1_CK_DH_RSA_WITH_ARIA_128_GCM_SHA256 = $0300C054; + TLS1_CK_DH_RSA_WITH_ARIA_256_GCM_SHA384 = $0300C055; + TLS1_CK_DHE_DSS_WITH_ARIA_128_GCM_SHA256 = $0300C056; + TLS1_CK_DHE_DSS_WITH_ARIA_256_GCM_SHA384 = $0300C057; + TLS1_CK_DH_DSS_WITH_ARIA_128_GCM_SHA256 = $0300C058; + TLS1_CK_DH_DSS_WITH_ARIA_256_GCM_SHA384 = $0300C059; + TLS1_CK_DH_anon_WITH_ARIA_128_GCM_SHA256 = $0300C05A; + TLS1_CK_DH_anon_WITH_ARIA_256_GCM_SHA384 = $0300C05B; + TLS1_CK_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 = $0300C05C; + TLS1_CK_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 = $0300C05D; + TLS1_CK_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 = $0300C05E; + TLS1_CK_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 = $0300C05F; + TLS1_CK_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 = $0300C060; + TLS1_CK_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 = $0300C061; + TLS1_CK_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 = $0300C062; + TLS1_CK_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 = $0300C063; + TLS1_CK_PSK_WITH_ARIA_128_GCM_SHA256 = $0300C06A; + TLS1_CK_PSK_WITH_ARIA_256_GCM_SHA384 = $0300C06B; + TLS1_CK_DHE_PSK_WITH_ARIA_128_GCM_SHA256 = $0300C06C; + TLS1_CK_DHE_PSK_WITH_ARIA_256_GCM_SHA384 = $0300C06D; + TLS1_CK_RSA_PSK_WITH_ARIA_128_GCM_SHA256 = $0300C06E; + TLS1_CK_RSA_PSK_WITH_ARIA_256_GCM_SHA384 = $0300C06F; + TLS1_RFC_RSA_WITH_AES_128_SHA = 'TLS_RSA_WITH_AES_128_CBC_SHA'; + TLS1_RFC_DHE_DSS_WITH_AES_128_SHA = 'TLS_DHE_DSS_WITH_AES_128_CBC_SHA'; + TLS1_RFC_DHE_RSA_WITH_AES_128_SHA = 'TLS_DHE_RSA_WITH_AES_128_CBC_SHA'; + TLS1_RFC_ADH_WITH_AES_128_SHA = 'TLS_DH_anon_WITH_AES_128_CBC_SHA'; + TLS1_RFC_RSA_WITH_AES_256_SHA = 'TLS_RSA_WITH_AES_256_CBC_SHA'; + TLS1_RFC_DHE_DSS_WITH_AES_256_SHA = 'TLS_DHE_DSS_WITH_AES_256_CBC_SHA'; + TLS1_RFC_DHE_RSA_WITH_AES_256_SHA = 'TLS_DHE_RSA_WITH_AES_256_CBC_SHA'; + TLS1_RFC_ADH_WITH_AES_256_SHA = 'TLS_DH_anon_WITH_AES_256_CBC_SHA'; + TLS1_RFC_RSA_WITH_NULL_SHA256 = 'TLS_RSA_WITH_NULL_SHA256'; + TLS1_RFC_RSA_WITH_AES_128_SHA256 = 'TLS_RSA_WITH_AES_128_CBC_SHA256'; + TLS1_RFC_RSA_WITH_AES_256_SHA256 = 'TLS_RSA_WITH_AES_256_CBC_SHA256'; + TLS1_RFC_DHE_DSS_WITH_AES_128_SHA256 = 'TLS_DHE_DSS_WITH_AES_128_CBC_SHA256'; + TLS1_RFC_DHE_RSA_WITH_AES_128_SHA256 = 'TLS_DHE_RSA_WITH_AES_128_CBC_SHA256'; + TLS1_RFC_DHE_DSS_WITH_AES_256_SHA256 = 'TLS_DHE_DSS_WITH_AES_256_CBC_SHA256'; + TLS1_RFC_DHE_RSA_WITH_AES_256_SHA256 = 'TLS_DHE_RSA_WITH_AES_256_CBC_SHA256'; + TLS1_RFC_ADH_WITH_AES_128_SHA256 = 'TLS_DH_anon_WITH_AES_128_CBC_SHA256'; + TLS1_RFC_ADH_WITH_AES_256_SHA256 = 'TLS_DH_anon_WITH_AES_256_CBC_SHA256'; + TLS1_RFC_RSA_WITH_AES_128_GCM_SHA256 = 'TLS_RSA_WITH_AES_128_GCM_SHA256'; + TLS1_RFC_RSA_WITH_AES_256_GCM_SHA384 = 'TLS_RSA_WITH_AES_256_GCM_SHA384'; + TLS1_RFC_DHE_RSA_WITH_AES_128_GCM_SHA256 = 'TLS_DHE_RSA_WITH_AES_128_GCM_SHA256'; + TLS1_RFC_DHE_RSA_WITH_AES_256_GCM_SHA384 = 'TLS_DHE_RSA_WITH_AES_256_GCM_SHA384'; + TLS1_RFC_DHE_DSS_WITH_AES_128_GCM_SHA256 = 'TLS_DHE_DSS_WITH_AES_128_GCM_SHA256'; + TLS1_RFC_DHE_DSS_WITH_AES_256_GCM_SHA384 = 'TLS_DHE_DSS_WITH_AES_256_GCM_SHA384'; + TLS1_RFC_ADH_WITH_AES_128_GCM_SHA256 = 'TLS_DH_anon_WITH_AES_128_GCM_SHA256'; + TLS1_RFC_ADH_WITH_AES_256_GCM_SHA384 = 'TLS_DH_anon_WITH_AES_256_GCM_SHA384'; + TLS1_RFC_RSA_WITH_AES_128_CCM = 'TLS_RSA_WITH_AES_128_CCM'; + TLS1_RFC_RSA_WITH_AES_256_CCM = 'TLS_RSA_WITH_AES_256_CCM'; + TLS1_RFC_DHE_RSA_WITH_AES_128_CCM = 'TLS_DHE_RSA_WITH_AES_128_CCM'; + TLS1_RFC_DHE_RSA_WITH_AES_256_CCM = 'TLS_DHE_RSA_WITH_AES_256_CCM'; + TLS1_RFC_RSA_WITH_AES_128_CCM_8 = 'TLS_RSA_WITH_AES_128_CCM_8'; + TLS1_RFC_RSA_WITH_AES_256_CCM_8 = 'TLS_RSA_WITH_AES_256_CCM_8'; + TLS1_RFC_DHE_RSA_WITH_AES_128_CCM_8 = 'TLS_DHE_RSA_WITH_AES_128_CCM_8'; + TLS1_RFC_DHE_RSA_WITH_AES_256_CCM_8 = 'TLS_DHE_RSA_WITH_AES_256_CCM_8'; + TLS1_RFC_PSK_WITH_AES_128_CCM = 'TLS_PSK_WITH_AES_128_CCM'; + TLS1_RFC_PSK_WITH_AES_256_CCM = 'TLS_PSK_WITH_AES_256_CCM'; + TLS1_RFC_DHE_PSK_WITH_AES_128_CCM = 'TLS_DHE_PSK_WITH_AES_128_CCM'; + TLS1_RFC_DHE_PSK_WITH_AES_256_CCM = 'TLS_DHE_PSK_WITH_AES_256_CCM'; + TLS1_RFC_PSK_WITH_AES_128_CCM_8 = 'TLS_PSK_WITH_AES_128_CCM_8'; + TLS1_RFC_PSK_WITH_AES_256_CCM_8 = 'TLS_PSK_WITH_AES_256_CCM_8'; + TLS1_RFC_DHE_PSK_WITH_AES_128_CCM_8 = 'TLS_PSK_DHE_WITH_AES_128_CCM_8'; + TLS1_RFC_DHE_PSK_WITH_AES_256_CCM_8 = 'TLS_PSK_DHE_WITH_AES_256_CCM_8'; + TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_CCM = 'TLS_ECDHE_ECDSA_WITH_AES_128_CCM'; + TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_CCM = 'TLS_ECDHE_ECDSA_WITH_AES_256_CCM'; + TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 'TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8'; + TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_CCM_8 = 'TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8'; + TLS1_3_RFC_AES_128_GCM_SHA256 = 'TLS_AES_128_GCM_SHA256'; + TLS1_3_RFC_AES_256_GCM_SHA384 = 'TLS_AES_256_GCM_SHA384'; + TLS1_3_RFC_CHACHA20_POLY1305_SHA256 = 'TLS_CHACHA20_POLY1305_SHA256'; + TLS1_3_RFC_AES_128_CCM_SHA256 = 'TLS_AES_128_CCM_SHA256'; + TLS1_3_RFC_AES_128_CCM_8_SHA256 = 'TLS_AES_128_CCM_8_SHA256'; + TLS1_RFC_ECDHE_ECDSA_WITH_NULL_SHA = 'TLS_ECDHE_ECDSA_WITH_NULL_SHA'; + TLS1_RFC_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA = 'TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA'; + TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA'; + TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA'; + TLS1_RFC_ECDHE_RSA_WITH_NULL_SHA = 'TLS_ECDHE_RSA_WITH_NULL_SHA'; + TLS1_RFC_ECDHE_RSA_WITH_DES_192_CBC3_SHA = 'TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA'; + TLS1_RFC_ECDHE_RSA_WITH_AES_128_CBC_SHA = 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA'; + TLS1_RFC_ECDHE_RSA_WITH_AES_256_CBC_SHA = 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA'; + TLS1_RFC_ECDH_anon_WITH_NULL_SHA = 'TLS_ECDH_anon_WITH_NULL_SHA'; + TLS1_RFC_ECDH_anon_WITH_DES_192_CBC3_SHA = 'TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA'; + TLS1_RFC_ECDH_anon_WITH_AES_128_CBC_SHA = 'TLS_ECDH_anon_WITH_AES_128_CBC_SHA'; + TLS1_RFC_ECDH_anon_WITH_AES_256_CBC_SHA = 'TLS_ECDH_anon_WITH_AES_256_CBC_SHA'; + TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_SHA256 = 'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256'; + TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_SHA384 = 'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384'; + TLS1_RFC_ECDHE_RSA_WITH_AES_128_SHA256 = 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256'; + TLS1_RFC_ECDHE_RSA_WITH_AES_256_SHA384 = 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384'; + TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256'; + TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384'; + TLS1_RFC_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256'; + TLS1_RFC_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384'; + TLS1_RFC_PSK_WITH_NULL_SHA = 'TLS_PSK_WITH_NULL_SHA'; + TLS1_RFC_DHE_PSK_WITH_NULL_SHA = 'TLS_DHE_PSK_WITH_NULL_SHA'; + TLS1_RFC_RSA_PSK_WITH_NULL_SHA = 'TLS_RSA_PSK_WITH_NULL_SHA'; + TLS1_RFC_PSK_WITH_3DES_EDE_CBC_SHA = 'TLS_PSK_WITH_3DES_EDE_CBC_SHA'; + TLS1_RFC_PSK_WITH_AES_128_CBC_SHA = 'TLS_PSK_WITH_AES_128_CBC_SHA'; + TLS1_RFC_PSK_WITH_AES_256_CBC_SHA = 'TLS_PSK_WITH_AES_256_CBC_SHA'; + TLS1_RFC_DHE_PSK_WITH_3DES_EDE_CBC_SHA = 'TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA'; + TLS1_RFC_DHE_PSK_WITH_AES_128_CBC_SHA = 'TLS_DHE_PSK_WITH_AES_128_CBC_SHA'; + TLS1_RFC_DHE_PSK_WITH_AES_256_CBC_SHA = 'TLS_DHE_PSK_WITH_AES_256_CBC_SHA'; + TLS1_RFC_RSA_PSK_WITH_3DES_EDE_CBC_SHA = 'TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA'; + TLS1_RFC_RSA_PSK_WITH_AES_128_CBC_SHA = 'TLS_RSA_PSK_WITH_AES_128_CBC_SHA'; + TLS1_RFC_RSA_PSK_WITH_AES_256_CBC_SHA = 'TLS_RSA_PSK_WITH_AES_256_CBC_SHA'; + TLS1_RFC_PSK_WITH_AES_128_GCM_SHA256 = 'TLS_PSK_WITH_AES_128_GCM_SHA256'; + TLS1_RFC_PSK_WITH_AES_256_GCM_SHA384 = 'TLS_PSK_WITH_AES_256_GCM_SHA384'; + TLS1_RFC_DHE_PSK_WITH_AES_128_GCM_SHA256 = 'TLS_DHE_PSK_WITH_AES_128_GCM_SHA256'; + TLS1_RFC_DHE_PSK_WITH_AES_256_GCM_SHA384 = 'TLS_DHE_PSK_WITH_AES_256_GCM_SHA384'; + TLS1_RFC_RSA_PSK_WITH_AES_128_GCM_SHA256 = 'TLS_RSA_PSK_WITH_AES_128_GCM_SHA256'; + TLS1_RFC_RSA_PSK_WITH_AES_256_GCM_SHA384 = 'TLS_RSA_PSK_WITH_AES_256_GCM_SHA384'; + TLS1_RFC_PSK_WITH_AES_128_CBC_SHA256 = 'TLS_PSK_WITH_AES_128_CBC_SHA256'; + TLS1_RFC_PSK_WITH_AES_256_CBC_SHA384 = 'TLS_PSK_WITH_AES_256_CBC_SHA384'; + TLS1_RFC_PSK_WITH_NULL_SHA256 = 'TLS_PSK_WITH_NULL_SHA256'; + TLS1_RFC_PSK_WITH_NULL_SHA384 = 'TLS_PSK_WITH_NULL_SHA384'; + TLS1_RFC_DHE_PSK_WITH_AES_128_CBC_SHA256 = 'TLS_DHE_PSK_WITH_AES_128_CBC_SHA256'; + TLS1_RFC_DHE_PSK_WITH_AES_256_CBC_SHA384 = 'TLS_DHE_PSK_WITH_AES_256_CBC_SHA384'; + TLS1_RFC_DHE_PSK_WITH_NULL_SHA256 = 'TLS_DHE_PSK_WITH_NULL_SHA256'; + TLS1_RFC_DHE_PSK_WITH_NULL_SHA384 = 'TLS_DHE_PSK_WITH_NULL_SHA384'; + TLS1_RFC_RSA_PSK_WITH_AES_128_CBC_SHA256 = 'TLS_RSA_PSK_WITH_AES_128_CBC_SHA256'; + TLS1_RFC_RSA_PSK_WITH_AES_256_CBC_SHA384 = 'TLS_RSA_PSK_WITH_AES_256_CBC_SHA384'; + TLS1_RFC_RSA_PSK_WITH_NULL_SHA256 = 'TLS_RSA_PSK_WITH_NULL_SHA256'; + TLS1_RFC_RSA_PSK_WITH_NULL_SHA384 = 'TLS_RSA_PSK_WITH_NULL_SHA384'; + TLS1_RFC_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA = 'TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA'; + TLS1_RFC_ECDHE_PSK_WITH_AES_128_CBC_SHA = 'TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA'; + TLS1_RFC_ECDHE_PSK_WITH_AES_256_CBC_SHA = 'TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA'; + TLS1_RFC_ECDHE_PSK_WITH_AES_128_CBC_SHA256 = 'TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256'; + TLS1_RFC_ECDHE_PSK_WITH_AES_256_CBC_SHA384 = 'TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384'; + TLS1_RFC_ECDHE_PSK_WITH_NULL_SHA = 'TLS_ECDHE_PSK_WITH_NULL_SHA'; + TLS1_RFC_ECDHE_PSK_WITH_NULL_SHA256 = 'TLS_ECDHE_PSK_WITH_NULL_SHA256'; + TLS1_RFC_ECDHE_PSK_WITH_NULL_SHA384 = 'TLS_ECDHE_PSK_WITH_NULL_SHA384'; + TLS1_RFC_SRP_SHA_WITH_3DES_EDE_CBC_SHA = 'TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA'; + TLS1_RFC_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = 'TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA'; + TLS1_RFC_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA = 'TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA'; + TLS1_RFC_SRP_SHA_WITH_AES_128_CBC_SHA = 'TLS_SRP_SHA_WITH_AES_128_CBC_SHA'; + TLS1_RFC_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = 'TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA'; + TLS1_RFC_SRP_SHA_DSS_WITH_AES_128_CBC_SHA = 'TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA'; + TLS1_RFC_SRP_SHA_WITH_AES_256_CBC_SHA = 'TLS_SRP_SHA_WITH_AES_256_CBC_SHA'; + TLS1_RFC_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = 'TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA'; + TLS1_RFC_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = 'TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA'; + TLS1_RFC_DHE_RSA_WITH_CHACHA20_POLY1305 = 'TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256'; + TLS1_RFC_ECDHE_RSA_WITH_CHACHA20_POLY1305 = 'TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256'; + TLS1_RFC_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = 'TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256'; + TLS1_RFC_PSK_WITH_CHACHA20_POLY1305 = 'TLS_PSK_WITH_CHACHA20_POLY1305_SHA256'; + TLS1_RFC_ECDHE_PSK_WITH_CHACHA20_POLY1305 = 'TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256'; + TLS1_RFC_DHE_PSK_WITH_CHACHA20_POLY1305 = 'TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256'; + TLS1_RFC_RSA_PSK_WITH_CHACHA20_POLY1305 = 'TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256'; + TLS1_RFC_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 'TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256'; + TLS1_RFC_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 'TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256'; + TLS1_RFC_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 'TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256'; + TLS1_RFC_ADH_WITH_CAMELLIA_128_CBC_SHA256 = 'TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256'; + TLS1_RFC_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 'TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256'; + TLS1_RFC_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 'TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256'; + TLS1_RFC_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 'TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256'; + TLS1_RFC_ADH_WITH_CAMELLIA_256_CBC_SHA256 = 'TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256'; + TLS1_RFC_RSA_WITH_CAMELLIA_256_CBC_SHA = 'TLS_RSA_WITH_CAMELLIA_256_CBC_SHA'; + TLS1_RFC_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA = 'TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA'; + TLS1_RFC_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA = 'TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA'; + TLS1_RFC_ADH_WITH_CAMELLIA_256_CBC_SHA = 'TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA'; + TLS1_RFC_RSA_WITH_CAMELLIA_128_CBC_SHA = 'TLS_RSA_WITH_CAMELLIA_128_CBC_SHA'; + TLS1_RFC_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA = 'TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA'; + TLS1_RFC_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA = 'TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA'; + TLS1_RFC_ADH_WITH_CAMELLIA_128_CBC_SHA = 'TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA'; + TLS1_RFC_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 'TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256'; + TLS1_RFC_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 'TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384'; + TLS1_RFC_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 'TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256'; + TLS1_RFC_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 'TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384'; + TLS1_RFC_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 'TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256'; + TLS1_RFC_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 'TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384'; + TLS1_RFC_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 'TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256'; + TLS1_RFC_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 'TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384'; + TLS1_RFC_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 'TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256'; + TLS1_RFC_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 'TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384'; + TLS1_RFC_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 'TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256'; + TLS1_RFC_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 'TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384'; + TLS1_RFC_RSA_WITH_SEED_SHA = 'TLS_RSA_WITH_SEED_CBC_SHA'; + TLS1_RFC_DHE_DSS_WITH_SEED_SHA = 'TLS_DHE_DSS_WITH_SEED_CBC_SHA'; + TLS1_RFC_DHE_RSA_WITH_SEED_SHA = 'TLS_DHE_RSA_WITH_SEED_CBC_SHA'; + TLS1_RFC_ADH_WITH_SEED_SHA = 'TLS_DH_anon_WITH_SEED_CBC_SHA'; + TLS1_RFC_ECDHE_PSK_WITH_RC4_128_SHA = 'TLS_ECDHE_PSK_WITH_RC4_128_SHA'; + TLS1_RFC_ECDH_anon_WITH_RC4_128_SHA = 'TLS_ECDH_anon_WITH_RC4_128_SHA'; + TLS1_RFC_ECDHE_ECDSA_WITH_RC4_128_SHA = 'TLS_ECDHE_ECDSA_WITH_RC4_128_SHA'; + TLS1_RFC_ECDHE_RSA_WITH_RC4_128_SHA = 'TLS_ECDHE_RSA_WITH_RC4_128_SHA'; + TLS1_RFC_PSK_WITH_RC4_128_SHA = 'TLS_PSK_WITH_RC4_128_SHA'; + TLS1_RFC_RSA_PSK_WITH_RC4_128_SHA = 'TLS_RSA_PSK_WITH_RC4_128_SHA'; + TLS1_RFC_DHE_PSK_WITH_RC4_128_SHA = 'TLS_DHE_PSK_WITH_RC4_128_SHA'; + TLS1_RFC_RSA_WITH_ARIA_128_GCM_SHA256 = 'TLS_RSA_WITH_ARIA_128_GCM_SHA256'; + TLS1_RFC_RSA_WITH_ARIA_256_GCM_SHA384 = 'TLS_RSA_WITH_ARIA_256_GCM_SHA384'; + TLS1_RFC_DHE_RSA_WITH_ARIA_128_GCM_SHA256 = 'TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256'; + TLS1_RFC_DHE_RSA_WITH_ARIA_256_GCM_SHA384 = 'TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384'; + TLS1_RFC_DH_RSA_WITH_ARIA_128_GCM_SHA256 = 'TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256'; + TLS1_RFC_DH_RSA_WITH_ARIA_256_GCM_SHA384 = 'TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384'; + TLS1_RFC_DHE_DSS_WITH_ARIA_128_GCM_SHA256 = 'TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256'; + TLS1_RFC_DHE_DSS_WITH_ARIA_256_GCM_SHA384 = 'TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384'; + TLS1_RFC_DH_DSS_WITH_ARIA_128_GCM_SHA256 = 'TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256'; + TLS1_RFC_DH_DSS_WITH_ARIA_256_GCM_SHA384 = 'TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384'; + TLS1_RFC_DH_anon_WITH_ARIA_128_GCM_SHA256 = 'TLS_DH_anon_WITH_ARIA_128_GCM_SHA256'; + TLS1_RFC_DH_anon_WITH_ARIA_256_GCM_SHA384 = 'TLS_DH_anon_WITH_ARIA_256_GCM_SHA384'; + TLS1_RFC_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 = 'TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256'; + TLS1_RFC_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 = 'TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384'; + TLS1_RFC_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 = 'TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256'; + TLS1_RFC_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 = 'TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384'; + TLS1_RFC_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 = 'TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256'; + TLS1_RFC_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 = 'TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384'; + TLS1_RFC_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 = 'TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256'; + TLS1_RFC_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 = 'TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384'; + TLS1_RFC_PSK_WITH_ARIA_128_GCM_SHA256 = 'TLS_PSK_WITH_ARIA_128_GCM_SHA256'; + TLS1_RFC_PSK_WITH_ARIA_256_GCM_SHA384 = 'TLS_PSK_WITH_ARIA_256_GCM_SHA384'; + TLS1_RFC_DHE_PSK_WITH_ARIA_128_GCM_SHA256 = 'TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256'; + TLS1_RFC_DHE_PSK_WITH_ARIA_256_GCM_SHA384 = 'TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384'; + TLS1_RFC_RSA_PSK_WITH_ARIA_128_GCM_SHA256 = 'TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256'; + TLS1_RFC_RSA_PSK_WITH_ARIA_256_GCM_SHA384 = 'TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384'; + TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA = 'DHE-DSS-RC4-SHA'; + TLS1_TXT_PSK_WITH_NULL_SHA = 'PSK-NULL-SHA'; + TLS1_TXT_DHE_PSK_WITH_NULL_SHA = 'DHE-PSK-NULL-SHA'; + TLS1_TXT_RSA_PSK_WITH_NULL_SHA = 'RSA-PSK-NULL-SHA'; + TLS1_TXT_RSA_WITH_AES_128_SHA = 'AES128-SHA'; + TLS1_TXT_DH_DSS_WITH_AES_128_SHA = 'DH-DSS-AES128-SHA'; + TLS1_TXT_DH_RSA_WITH_AES_128_SHA = 'DH-RSA-AES128-SHA'; + TLS1_TXT_DHE_DSS_WITH_AES_128_SHA = 'DHE-DSS-AES128-SHA'; + TLS1_TXT_DHE_RSA_WITH_AES_128_SHA = 'DHE-RSA-AES128-SHA'; + TLS1_TXT_ADH_WITH_AES_128_SHA = 'ADH-AES128-SHA'; + TLS1_TXT_RSA_WITH_AES_256_SHA = 'AES256-SHA'; + TLS1_TXT_DH_DSS_WITH_AES_256_SHA = 'DH-DSS-AES256-SHA'; + TLS1_TXT_DH_RSA_WITH_AES_256_SHA = 'DH-RSA-AES256-SHA'; + TLS1_TXT_DHE_DSS_WITH_AES_256_SHA = 'DHE-DSS-AES256-SHA'; + TLS1_TXT_DHE_RSA_WITH_AES_256_SHA = 'DHE-RSA-AES256-SHA'; + TLS1_TXT_ADH_WITH_AES_256_SHA = 'ADH-AES256-SHA'; + TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA = 'ECDH-ECDSA-NULL-SHA'; + TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA = 'ECDH-ECDSA-RC4-SHA'; + TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA = 'ECDH-ECDSA-DES-CBC3-SHA'; + TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA = 'ECDH-ECDSA-AES128-SHA'; + TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 'ECDH-ECDSA-AES256-SHA'; + TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA = 'ECDHE-ECDSA-NULL-SHA'; + TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA = 'ECDHE-ECDSA-RC4-SHA'; + TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA = 'ECDHE-ECDSA-DES-CBC3-SHA'; + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 'ECDHE-ECDSA-AES128-SHA'; + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 'ECDHE-ECDSA-AES256-SHA'; + TLS1_TXT_ECDH_RSA_WITH_NULL_SHA = 'ECDH-RSA-NULL-SHA'; + TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA = 'ECDH-RSA-RC4-SHA'; + TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA = 'ECDH-RSA-DES-CBC3-SHA'; + TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA = 'ECDH-RSA-AES128-SHA'; + TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA = 'ECDH-RSA-AES256-SHA'; + TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA = 'ECDHE-RSA-NULL-SHA'; + TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA = 'ECDHE-RSA-RC4-SHA'; + TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA = 'ECDHE-RSA-DES-CBC3-SHA'; + TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA = 'ECDHE-RSA-AES128-SHA'; + TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA = 'ECDHE-RSA-AES256-SHA'; + TLS1_TXT_ECDH_anon_WITH_NULL_SHA = 'AECDH-NULL-SHA'; + TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA = 'AECDH-RC4-SHA'; + TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA = 'AECDH-DES-CBC3-SHA'; + TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA = 'AECDH-AES128-SHA'; + TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA = 'AECDH-AES256-SHA'; + TLS1_TXT_PSK_WITH_RC4_128_SHA = 'PSK-RC4-SHA'; + TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA = 'PSK-3DES-EDE-CBC-SHA'; + TLS1_TXT_PSK_WITH_AES_128_CBC_SHA = 'PSK-AES128-CBC-SHA'; + TLS1_TXT_PSK_WITH_AES_256_CBC_SHA = 'PSK-AES256-CBC-SHA'; + TLS1_TXT_DHE_PSK_WITH_RC4_128_SHA = 'DHE-PSK-RC4-SHA'; + TLS1_TXT_DHE_PSK_WITH_3DES_EDE_CBC_SHA = 'DHE-PSK-3DES-EDE-CBC-SHA'; + TLS1_TXT_DHE_PSK_WITH_AES_128_CBC_SHA = 'DHE-PSK-AES128-CBC-SHA'; + TLS1_TXT_DHE_PSK_WITH_AES_256_CBC_SHA = 'DHE-PSK-AES256-CBC-SHA'; + TLS1_TXT_RSA_PSK_WITH_RC4_128_SHA = 'RSA-PSK-RC4-SHA'; + TLS1_TXT_RSA_PSK_WITH_3DES_EDE_CBC_SHA = 'RSA-PSK-3DES-EDE-CBC-SHA'; + TLS1_TXT_RSA_PSK_WITH_AES_128_CBC_SHA = 'RSA-PSK-AES128-CBC-SHA'; + TLS1_TXT_RSA_PSK_WITH_AES_256_CBC_SHA = 'RSA-PSK-AES256-CBC-SHA'; + TLS1_TXT_PSK_WITH_AES_128_GCM_SHA256 = 'PSK-AES128-GCM-SHA256'; + TLS1_TXT_PSK_WITH_AES_256_GCM_SHA384 = 'PSK-AES256-GCM-SHA384'; + TLS1_TXT_DHE_PSK_WITH_AES_128_GCM_SHA256 = 'DHE-PSK-AES128-GCM-SHA256'; + TLS1_TXT_DHE_PSK_WITH_AES_256_GCM_SHA384 = 'DHE-PSK-AES256-GCM-SHA384'; + TLS1_TXT_RSA_PSK_WITH_AES_128_GCM_SHA256 = 'RSA-PSK-AES128-GCM-SHA256'; + TLS1_TXT_RSA_PSK_WITH_AES_256_GCM_SHA384 = 'RSA-PSK-AES256-GCM-SHA384'; + TLS1_TXT_PSK_WITH_AES_128_CBC_SHA256 = 'PSK-AES128-CBC-SHA256'; + TLS1_TXT_PSK_WITH_AES_256_CBC_SHA384 = 'PSK-AES256-CBC-SHA384'; + TLS1_TXT_PSK_WITH_NULL_SHA256 = 'PSK-NULL-SHA256'; + TLS1_TXT_PSK_WITH_NULL_SHA384 = 'PSK-NULL-SHA384'; + TLS1_TXT_DHE_PSK_WITH_AES_128_CBC_SHA256 = 'DHE-PSK-AES128-CBC-SHA256'; + TLS1_TXT_DHE_PSK_WITH_AES_256_CBC_SHA384 = 'DHE-PSK-AES256-CBC-SHA384'; + TLS1_TXT_DHE_PSK_WITH_NULL_SHA256 = 'DHE-PSK-NULL-SHA256'; + TLS1_TXT_DHE_PSK_WITH_NULL_SHA384 = 'DHE-PSK-NULL-SHA384'; + TLS1_TXT_RSA_PSK_WITH_AES_128_CBC_SHA256 = 'RSA-PSK-AES128-CBC-SHA256'; + TLS1_TXT_RSA_PSK_WITH_AES_256_CBC_SHA384 = 'RSA-PSK-AES256-CBC-SHA384'; + TLS1_TXT_RSA_PSK_WITH_NULL_SHA256 = 'RSA-PSK-NULL-SHA256'; + TLS1_TXT_RSA_PSK_WITH_NULL_SHA384 = 'RSA-PSK-NULL-SHA384'; + TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA = 'SRP-3DES-EDE-CBC-SHA'; + TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = 'SRP-RSA-3DES-EDE-CBC-SHA'; + TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA = 'SRP-DSS-3DES-EDE-CBC-SHA'; + TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA = 'SRP-AES-128-CBC-SHA'; + TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = 'SRP-RSA-AES-128-CBC-SHA'; + TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA = 'SRP-DSS-AES-128-CBC-SHA'; + TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA = 'SRP-AES-256-CBC-SHA'; + TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = 'SRP-RSA-AES-256-CBC-SHA'; + TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = 'SRP-DSS-AES-256-CBC-SHA'; + TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA = 'CAMELLIA128-SHA'; + TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA = 'DH-DSS-CAMELLIA128-SHA'; + TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA = 'DH-RSA-CAMELLIA128-SHA'; + TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA = 'DHE-DSS-CAMELLIA128-SHA'; + TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA = 'DHE-RSA-CAMELLIA128-SHA'; + TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA = 'ADH-CAMELLIA128-SHA'; + TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA = 'CAMELLIA256-SHA'; + TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA = 'DH-DSS-CAMELLIA256-SHA'; + TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA = 'DH-RSA-CAMELLIA256-SHA'; + TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA = 'DHE-DSS-CAMELLIA256-SHA'; + TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA = 'DHE-RSA-CAMELLIA256-SHA'; + TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA = 'ADH-CAMELLIA256-SHA'; + TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 'CAMELLIA128-SHA256'; + TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 'DH-DSS-CAMELLIA128-SHA256'; + TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 'DH-RSA-CAMELLIA128-SHA256'; + TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 'DHE-DSS-CAMELLIA128-SHA256'; + TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 'DHE-RSA-CAMELLIA128-SHA256'; + TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA256 = 'ADH-CAMELLIA128-SHA256'; + TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 'CAMELLIA256-SHA256'; + TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 'DH-DSS-CAMELLIA256-SHA256'; + TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 'DH-RSA-CAMELLIA256-SHA256'; + TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 'DHE-DSS-CAMELLIA256-SHA256'; + TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 'DHE-RSA-CAMELLIA256-SHA256'; + TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA256 = 'ADH-CAMELLIA256-SHA256'; + TLS1_TXT_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 'PSK-CAMELLIA128-SHA256'; + TLS1_TXT_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 'PSK-CAMELLIA256-SHA384'; + TLS1_TXT_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 'DHE-PSK-CAMELLIA128-SHA256'; + TLS1_TXT_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 'DHE-PSK-CAMELLIA256-SHA384'; + TLS1_TXT_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 'RSA-PSK-CAMELLIA128-SHA256'; + TLS1_TXT_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 'RSA-PSK-CAMELLIA256-SHA384'; + TLS1_TXT_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 'ECDHE-PSK-CAMELLIA128-SHA256'; + TLS1_TXT_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 'ECDHE-PSK-CAMELLIA256-SHA384'; + TLS1_TXT_RSA_WITH_SEED_SHA = 'SEED-SHA'; + TLS1_TXT_DH_DSS_WITH_SEED_SHA = 'DH-DSS-SEED-SHA'; + TLS1_TXT_DH_RSA_WITH_SEED_SHA = 'DH-RSA-SEED-SHA'; + TLS1_TXT_DHE_DSS_WITH_SEED_SHA = 'DHE-DSS-SEED-SHA'; + TLS1_TXT_DHE_RSA_WITH_SEED_SHA = 'DHE-RSA-SEED-SHA'; + TLS1_TXT_ADH_WITH_SEED_SHA = 'ADH-SEED-SHA'; + TLS1_TXT_RSA_WITH_NULL_SHA256 = 'NULL-SHA256'; + TLS1_TXT_RSA_WITH_AES_128_SHA256 = 'AES128-SHA256'; + TLS1_TXT_RSA_WITH_AES_256_SHA256 = 'AES256-SHA256'; + TLS1_TXT_DH_DSS_WITH_AES_128_SHA256 = 'DH-DSS-AES128-SHA256'; + TLS1_TXT_DH_RSA_WITH_AES_128_SHA256 = 'DH-RSA-AES128-SHA256'; + TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256 = 'DHE-DSS-AES128-SHA256'; + TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256 = 'DHE-RSA-AES128-SHA256'; + TLS1_TXT_DH_DSS_WITH_AES_256_SHA256 = 'DH-DSS-AES256-SHA256'; + TLS1_TXT_DH_RSA_WITH_AES_256_SHA256 = 'DH-RSA-AES256-SHA256'; + TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256 = 'DHE-DSS-AES256-SHA256'; + TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256 = 'DHE-RSA-AES256-SHA256'; + TLS1_TXT_ADH_WITH_AES_128_SHA256 = 'ADH-AES128-SHA256'; + TLS1_TXT_ADH_WITH_AES_256_SHA256 = 'ADH-AES256-SHA256'; + TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256 = 'AES128-GCM-SHA256'; + TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384 = 'AES256-GCM-SHA384'; + TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256 = 'DHE-RSA-AES128-GCM-SHA256'; + TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384 = 'DHE-RSA-AES256-GCM-SHA384'; + TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256 = 'DH-RSA-AES128-GCM-SHA256'; + TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384 = 'DH-RSA-AES256-GCM-SHA384'; + TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256 = 'DHE-DSS-AES128-GCM-SHA256'; + TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384 = 'DHE-DSS-AES256-GCM-SHA384'; + TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256 = 'DH-DSS-AES128-GCM-SHA256'; + TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384 = 'DH-DSS-AES256-GCM-SHA384'; + TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256 = 'ADH-AES128-GCM-SHA256'; + TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384 = 'ADH-AES256-GCM-SHA384'; + TLS1_TXT_RSA_WITH_AES_128_CCM = 'AES128-CCM'; + TLS1_TXT_RSA_WITH_AES_256_CCM = 'AES256-CCM'; + TLS1_TXT_DHE_RSA_WITH_AES_128_CCM = 'DHE-RSA-AES128-CCM'; + TLS1_TXT_DHE_RSA_WITH_AES_256_CCM = 'DHE-RSA-AES256-CCM'; + TLS1_TXT_RSA_WITH_AES_128_CCM_8 = 'AES128-CCM8'; + TLS1_TXT_RSA_WITH_AES_256_CCM_8 = 'AES256-CCM8'; + TLS1_TXT_DHE_RSA_WITH_AES_128_CCM_8 = 'DHE-RSA-AES128-CCM8'; + TLS1_TXT_DHE_RSA_WITH_AES_256_CCM_8 = 'DHE-RSA-AES256-CCM8'; + TLS1_TXT_PSK_WITH_AES_128_CCM = 'PSK-AES128-CCM'; + TLS1_TXT_PSK_WITH_AES_256_CCM = 'PSK-AES256-CCM'; + TLS1_TXT_DHE_PSK_WITH_AES_128_CCM = 'DHE-PSK-AES128-CCM'; + TLS1_TXT_DHE_PSK_WITH_AES_256_CCM = 'DHE-PSK-AES256-CCM'; + TLS1_TXT_PSK_WITH_AES_128_CCM_8 = 'PSK-AES128-CCM8'; + TLS1_TXT_PSK_WITH_AES_256_CCM_8 = 'PSK-AES256-CCM8'; + TLS1_TXT_DHE_PSK_WITH_AES_128_CCM_8 = 'DHE-PSK-AES128-CCM8'; + TLS1_TXT_DHE_PSK_WITH_AES_256_CCM_8 = 'DHE-PSK-AES256-CCM8'; + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CCM = 'ECDHE-ECDSA-AES128-CCM'; + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CCM = 'ECDHE-ECDSA-AES256-CCM'; + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 'ECDHE-ECDSA-AES128-CCM8'; + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CCM_8 = 'ECDHE-ECDSA-AES256-CCM8'; + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256 = 'ECDHE-ECDSA-AES128-SHA256'; + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384 = 'ECDHE-ECDSA-AES256-SHA384'; + TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256 = 'ECDH-ECDSA-AES128-SHA256'; + TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384 = 'ECDH-ECDSA-AES256-SHA384'; + TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256 = 'ECDHE-RSA-AES128-SHA256'; + TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384 = 'ECDHE-RSA-AES256-SHA384'; + TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256 = 'ECDH-RSA-AES128-SHA256'; + TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384 = 'ECDH-RSA-AES256-SHA384'; + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 'ECDHE-ECDSA-AES128-GCM-SHA256'; + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 'ECDHE-ECDSA-AES256-GCM-SHA384'; + TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = 'ECDH-ECDSA-AES128-GCM-SHA256'; + TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = 'ECDH-ECDSA-AES256-GCM-SHA384'; + TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 'ECDHE-RSA-AES128-GCM-SHA256'; + TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 'ECDHE-RSA-AES256-GCM-SHA384'; + TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256 = 'ECDH-RSA-AES128-GCM-SHA256'; + TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384 = 'ECDH-RSA-AES256-GCM-SHA384'; + TLS1_TXT_ECDHE_PSK_WITH_RC4_128_SHA = 'ECDHE-PSK-RC4-SHA'; + TLS1_TXT_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA = 'ECDHE-PSK-3DES-EDE-CBC-SHA'; + TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA = 'ECDHE-PSK-AES128-CBC-SHA'; + TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA = 'ECDHE-PSK-AES256-CBC-SHA'; + TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA256 = 'ECDHE-PSK-AES128-CBC-SHA256'; + TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA384 = 'ECDHE-PSK-AES256-CBC-SHA384'; + TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA = 'ECDHE-PSK-NULL-SHA'; + TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA256 = 'ECDHE-PSK-NULL-SHA256'; + TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA384 = 'ECDHE-PSK-NULL-SHA384'; + TLS1_TXT_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 'ECDHE-ECDSA-CAMELLIA128-SHA256'; + TLS1_TXT_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 'ECDHE-ECDSA-CAMELLIA256-SHA384'; + TLS1_TXT_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 'ECDH-ECDSA-CAMELLIA128-SHA256'; + TLS1_TXT_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 'ECDH-ECDSA-CAMELLIA256-SHA384'; + TLS1_TXT_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 'ECDHE-RSA-CAMELLIA128-SHA256'; + TLS1_TXT_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 'ECDHE-RSA-CAMELLIA256-SHA384'; + TLS1_TXT_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 'ECDH-RSA-CAMELLIA128-SHA256'; + TLS1_TXT_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 'ECDH-RSA-CAMELLIA256-SHA384'; + TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305 = 'ECDHE-RSA-CHACHA20-POLY1305'; + TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = 'ECDHE-ECDSA-CHACHA20-POLY1305'; + TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305 = 'DHE-RSA-CHACHA20-POLY1305'; + TLS1_TXT_PSK_WITH_CHACHA20_POLY1305 = 'PSK-CHACHA20-POLY1305'; + TLS1_TXT_ECDHE_PSK_WITH_CHACHA20_POLY1305 = 'ECDHE-PSK-CHACHA20-POLY1305'; + TLS1_TXT_DHE_PSK_WITH_CHACHA20_POLY1305 = 'DHE-PSK-CHACHA20-POLY1305'; + TLS1_TXT_RSA_PSK_WITH_CHACHA20_POLY1305 = 'RSA-PSK-CHACHA20-POLY1305'; + TLS1_TXT_RSA_WITH_ARIA_128_GCM_SHA256 = 'ARIA128-GCM-SHA256'; + TLS1_TXT_RSA_WITH_ARIA_256_GCM_SHA384 = 'ARIA256-GCM-SHA384'; + TLS1_TXT_DHE_RSA_WITH_ARIA_128_GCM_SHA256 = 'DHE-RSA-ARIA128-GCM-SHA256'; + TLS1_TXT_DHE_RSA_WITH_ARIA_256_GCM_SHA384 = 'DHE-RSA-ARIA256-GCM-SHA384'; + TLS1_TXT_DH_RSA_WITH_ARIA_128_GCM_SHA256 = 'DH-RSA-ARIA128-GCM-SHA256'; + TLS1_TXT_DH_RSA_WITH_ARIA_256_GCM_SHA384 = 'DH-RSA-ARIA256-GCM-SHA384'; + TLS1_TXT_DHE_DSS_WITH_ARIA_128_GCM_SHA256 = 'DHE-DSS-ARIA128-GCM-SHA256'; + TLS1_TXT_DHE_DSS_WITH_ARIA_256_GCM_SHA384 = 'DHE-DSS-ARIA256-GCM-SHA384'; + TLS1_TXT_DH_DSS_WITH_ARIA_128_GCM_SHA256 = 'DH-DSS-ARIA128-GCM-SHA256'; + TLS1_TXT_DH_DSS_WITH_ARIA_256_GCM_SHA384 = 'DH-DSS-ARIA256-GCM-SHA384'; + TLS1_TXT_DH_anon_WITH_ARIA_128_GCM_SHA256 = 'ADH-ARIA128-GCM-SHA256'; + TLS1_TXT_DH_anon_WITH_ARIA_256_GCM_SHA384 = 'ADH-ARIA256-GCM-SHA384'; + TLS1_TXT_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 = 'ECDHE-ECDSA-ARIA128-GCM-SHA256'; + TLS1_TXT_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 = 'ECDHE-ECDSA-ARIA256-GCM-SHA384'; + TLS1_TXT_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 = 'ECDH-ECDSA-ARIA128-GCM-SHA256'; + TLS1_TXT_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 = 'ECDH-ECDSA-ARIA256-GCM-SHA384'; + TLS1_TXT_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 = 'ECDHE-ARIA128-GCM-SHA256'; + TLS1_TXT_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 = 'ECDHE-ARIA256-GCM-SHA384'; + TLS1_TXT_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 = 'ECDH-ARIA128-GCM-SHA256'; + TLS1_TXT_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 = 'ECDH-ARIA256-GCM-SHA384'; + TLS1_TXT_PSK_WITH_ARIA_128_GCM_SHA256 = 'PSK-ARIA128-GCM-SHA256'; + TLS1_TXT_PSK_WITH_ARIA_256_GCM_SHA384 = 'PSK-ARIA256-GCM-SHA384'; + TLS1_TXT_DHE_PSK_WITH_ARIA_128_GCM_SHA256 = 'DHE-PSK-ARIA128-GCM-SHA256'; + TLS1_TXT_DHE_PSK_WITH_ARIA_256_GCM_SHA384 = 'DHE-PSK-ARIA256-GCM-SHA384'; + TLS1_TXT_RSA_PSK_WITH_ARIA_128_GCM_SHA256 = 'RSA-PSK-ARIA128-GCM-SHA256'; + TLS1_TXT_RSA_PSK_WITH_ARIA_256_GCM_SHA384 = 'RSA-PSK-ARIA256-GCM-SHA384'; + TLS_CT_RSA_SIGN = 1; + TLS_CT_DSS_SIGN = 2; + TLS_CT_RSA_FIXED_DH = 3; + TLS_CT_DSS_FIXED_DH = 4; + TLS_CT_ECDSA_SIGN = 64; + TLS_CT_RSA_FIXED_ECDH = 65; + TLS_CT_ECDSA_FIXED_ECDH = 66; + TLS_CT_GOST01_SIGN = 22; + TLS_CT_GOST12_SIGN = 238; + TLS_CT_GOST12_512_SIGN = 239; + TLS_CT_NUMBER = 10; + TLS1_FINISH_MAC_LENGTH = 12; + TLS_MD_MAX_CONST_SIZE = 22; + TLS_MD_CLIENT_FINISH_CONST = 'client finished'; + TLS_MD_CLIENT_FINISH_CONST_SIZE = 15; + TLS_MD_SERVER_FINISH_CONST = 'server finished'; + TLS_MD_SERVER_FINISH_CONST_SIZE = 15; + TLS_MD_KEY_EXPANSION_CONST = 'key expansion'; + TLS_MD_KEY_EXPANSION_CONST_SIZE = 13; + TLS_MD_CLIENT_WRITE_KEY_CONST = 'client write key'; + TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE = 16; + TLS_MD_SERVER_WRITE_KEY_CONST = 'server write key'; + TLS_MD_SERVER_WRITE_KEY_CONST_SIZE = 16; + TLS_MD_IV_BLOCK_CONST = 'IV block'; + TLS_MD_IV_BLOCK_CONST_SIZE = 8; + TLS_MD_MASTER_SECRET_CONST = 'master secret'; + TLS_MD_MASTER_SECRET_CONST_SIZE = 13; + TLS_MD_EXTENDED_MASTER_SECRET_CONST = 'extended master secret'; + TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE = 22; + SSL_KEY_UPDATE_NONE = -1; + SSL_KEY_UPDATE_NOT_REQUESTED = 0; + SSL_KEY_UPDATE_REQUESTED = 1; + SSL_ST_CONNECT = $1000; + SSL_ST_ACCEPT = $2000; + SSL_ST_MASK = $0FFF; + SSL_CB_LOOP = $01; + SSL_CB_EXIT = $02; + SSL_CB_READ = $04; + SSL_CB_WRITE = $08; + SSL_CB_ALERT = $4000; + SSL_CB_READ_ALERT = (SSL_CB_ALERT or SSL_CB_READ); + SSL_CB_WRITE_ALERT = (SSL_CB_ALERT or SSL_CB_WRITE); + SSL_CB_ACCEPT_LOOP = (SSL_ST_ACCEPT or SSL_CB_LOOP); + SSL_CB_ACCEPT_EXIT = (SSL_ST_ACCEPT or SSL_CB_EXIT); + SSL_CB_CONNECT_LOOP = (SSL_ST_CONNECT or SSL_CB_LOOP); + SSL_CB_CONNECT_EXIT = (SSL_ST_CONNECT or SSL_CB_EXIT); + SSL_CB_HANDSHAKE_START = $10; + SSL_CB_HANDSHAKE_DONE = $20; + SSL_ST_READ_HEADER = $F0; + SSL_ST_READ_BODY = $F1; + SSL_ST_READ_DONE = $F2; + SSL_VERIFY_NONE = $00; + SSL_VERIFY_PEER = $01; + SSL_VERIFY_FAIL_IF_NO_PEER_CERT = $02; + SSL_VERIFY_CLIENT_ONCE = $04; + SSL_VERIFY_POST_HANDSHAKE = $08; + SSL_AD_REASON_OFFSET = 1000; + SSL_AD_CLOSE_NOTIFY = SSL3_AD_CLOSE_NOTIFY; + SSL_AD_UNEXPECTED_MESSAGE = SSL3_AD_UNEXPECTED_MESSAGE; + SSL_AD_BAD_RECORD_MAC = SSL3_AD_BAD_RECORD_MAC; + SSL_AD_DECRYPTION_FAILED = TLS1_AD_DECRYPTION_FAILED; + SSL_AD_RECORD_OVERFLOW = TLS1_AD_RECORD_OVERFLOW; + SSL_AD_DECOMPRESSION_FAILURE = SSL3_AD_DECOMPRESSION_FAILURE; + SSL_AD_HANDSHAKE_FAILURE = SSL3_AD_HANDSHAKE_FAILURE; + SSL_AD_NO_CERTIFICATE = SSL3_AD_NO_CERTIFICATE; + SSL_AD_BAD_CERTIFICATE = SSL3_AD_BAD_CERTIFICATE; + SSL_AD_UNSUPPORTED_CERTIFICATE = SSL3_AD_UNSUPPORTED_CERTIFICATE; + SSL_AD_CERTIFICATE_REVOKED = SSL3_AD_CERTIFICATE_REVOKED; + SSL_AD_CERTIFICATE_EXPIRED = SSL3_AD_CERTIFICATE_EXPIRED; + SSL_AD_CERTIFICATE_UNKNOWN = SSL3_AD_CERTIFICATE_UNKNOWN; + SSL_AD_ILLEGAL_PARAMETER = SSL3_AD_ILLEGAL_PARAMETER; + SSL_AD_UNKNOWN_CA = TLS1_AD_UNKNOWN_CA; + SSL_AD_ACCESS_DENIED = TLS1_AD_ACCESS_DENIED; + SSL_AD_DECODE_ERROR = TLS1_AD_DECODE_ERROR; + SSL_AD_DECRYPT_ERROR = TLS1_AD_DECRYPT_ERROR; + SSL_AD_EXPORT_RESTRICTION = TLS1_AD_EXPORT_RESTRICTION; + SSL_AD_PROTOCOL_VERSION = TLS1_AD_PROTOCOL_VERSION; + SSL_AD_INSUFFICIENT_SECURITY = TLS1_AD_INSUFFICIENT_SECURITY; + SSL_AD_INTERNAL_ERROR = TLS1_AD_INTERNAL_ERROR; + SSL_AD_USER_CANCELLED = TLS1_AD_USER_CANCELLED; + SSL_AD_NO_RENEGOTIATION = TLS1_AD_NO_RENEGOTIATION; + SSL_AD_MISSING_EXTENSION = TLS13_AD_MISSING_EXTENSION; + SSL_AD_CERTIFICATE_REQUIRED = TLS13_AD_CERTIFICATE_REQUIRED; + SSL_AD_UNSUPPORTED_EXTENSION = TLS1_AD_UNSUPPORTED_EXTENSION; + SSL_AD_CERTIFICATE_UNOBTAINABLE = TLS1_AD_CERTIFICATE_UNOBTAINABLE; + SSL_AD_UNRECOGNIZED_NAME = TLS1_AD_UNRECOGNIZED_NAME; + SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE = TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE; + SSL_AD_BAD_CERTIFICATE_HASH_VALUE = TLS1_AD_BAD_CERTIFICATE_HASH_VALUE; + SSL_AD_UNKNOWN_PSK_IDENTITY = TLS1_AD_UNKNOWN_PSK_IDENTITY; + SSL_AD_INAPPROPRIATE_FALLBACK = TLS1_AD_INAPPROPRIATE_FALLBACK; + SSL_AD_NO_APPLICATION_PROTOCOL = TLS1_AD_NO_APPLICATION_PROTOCOL; + SSL_ERROR_NONE = 0; + SSL_ERROR_SSL = 1; + SSL_ERROR_WANT_READ = 2; + SSL_ERROR_WANT_WRITE = 3; + SSL_ERROR_WANT_X509_LOOKUP = 4; + SSL_ERROR_SYSCALL = 5; + SSL_ERROR_ZERO_RETURN = 6; + SSL_ERROR_WANT_CONNECT = 7; + SSL_ERROR_WANT_ACCEPT = 8; + SSL_ERROR_WANT_ASYNC = 9; + SSL_ERROR_WANT_ASYNC_JOB = 10; + SSL_ERROR_WANT_CLIENT_HELLO_CB = 11; + SSL_CTRL_SET_TMP_DH = 3; + SSL_CTRL_SET_TMP_ECDH = 4; + SSL_CTRL_SET_TMP_DH_CB = 6; + SSL_CTRL_GET_CLIENT_CERT_REQUEST = 9; + SSL_CTRL_GET_NUM_RENEGOTIATIONS = 10; + SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS = 11; + SSL_CTRL_GET_TOTAL_RENEGOTIATIONS = 12; + SSL_CTRL_GET_FLAGS = 13; + SSL_CTRL_EXTRA_CHAIN_CERT = 14; + SSL_CTRL_SET_MSG_CALLBACK = 15; + SSL_CTRL_SET_MSG_CALLBACK_ARG = 16; + SSL_CTRL_SET_MTU = 17; + SSL_CTRL_SESS_NUMBER = 20; + SSL_CTRL_SESS_CONNECT = 21; + SSL_CTRL_SESS_CONNECT_GOOD = 22; + SSL_CTRL_SESS_CONNECT_RENEGOTIATE = 23; + SSL_CTRL_SESS_ACCEPT = 24; + SSL_CTRL_SESS_ACCEPT_GOOD = 25; + SSL_CTRL_SESS_ACCEPT_RENEGOTIATE = 26; + SSL_CTRL_SESS_HIT = 27; + SSL_CTRL_SESS_CB_HIT = 28; + SSL_CTRL_SESS_MISSES = 29; + SSL_CTRL_SESS_TIMEOUTS = 30; + SSL_CTRL_SESS_CACHE_FULL = 31; + SSL_CTRL_MODE = 33; + SSL_CTRL_GET_READ_AHEAD = 40; + SSL_CTRL_SET_READ_AHEAD = 41; + SSL_CTRL_SET_SESS_CACHE_SIZE = 42; + SSL_CTRL_GET_SESS_CACHE_SIZE = 43; + SSL_CTRL_SET_SESS_CACHE_MODE = 44; + SSL_CTRL_GET_SESS_CACHE_MODE = 45; + SSL_CTRL_GET_MAX_CERT_LIST = 50; + SSL_CTRL_SET_MAX_CERT_LIST = 51; + SSL_CTRL_SET_MAX_SEND_FRAGMENT = 52; + SSL_CTRL_SET_TLSEXT_SERVERNAME_CB = 53; + SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG = 54; + SSL_CTRL_SET_TLSEXT_HOSTNAME = 55; + SSL_CTRL_SET_TLSEXT_DEBUG_CB = 56; + SSL_CTRL_SET_TLSEXT_DEBUG_ARG = 57; + SSL_CTRL_GET_TLSEXT_TICKET_KEYS = 58; + SSL_CTRL_SET_TLSEXT_TICKET_KEYS = 59; + SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB = 63; + SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG = 64; + SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE = 65; + SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS = 66; + SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS = 67; + SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS = 68; + SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS = 69; + SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP = 70; + SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP = 71; + SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB = 72; + SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB = 75; + SSL_CTRL_SET_SRP_VERIFY_PARAM_CB = 76; + SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB = 77; + SSL_CTRL_SET_SRP_ARG = 78; + SSL_CTRL_SET_TLS_EXT_SRP_USERNAME = 79; + SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH = 80; + SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD = 81; + DTLS_CTRL_GET_TIMEOUT = 73; + DTLS_CTRL_HANDLE_TIMEOUT = 74; + SSL_CTRL_GET_RI_SUPPORT = 76; + SSL_CTRL_CLEAR_MODE = 78; + SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB = 79; + SSL_CTRL_GET_EXTRA_CHAIN_CERTS = 82; + SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS = 83; + SSL_CTRL_CHAIN = 88; + SSL_CTRL_CHAIN_CERT = 89; + SSL_CTRL_GET_GROUPS = 90; + SSL_CTRL_SET_GROUPS = 91; + SSL_CTRL_SET_GROUPS_LIST = 92; + SSL_CTRL_GET_SHARED_GROUP = 93; + SSL_CTRL_SET_SIGALGS = 97; + SSL_CTRL_SET_SIGALGS_LIST = 98; + SSL_CTRL_CERT_FLAGS = 99; + SSL_CTRL_CLEAR_CERT_FLAGS = 100; + SSL_CTRL_SET_CLIENT_SIGALGS = 101; + SSL_CTRL_SET_CLIENT_SIGALGS_LIST = 102; + SSL_CTRL_GET_CLIENT_CERT_TYPES = 103; + SSL_CTRL_SET_CLIENT_CERT_TYPES = 104; + SSL_CTRL_BUILD_CERT_CHAIN = 105; + SSL_CTRL_SET_VERIFY_CERT_STORE = 106; + SSL_CTRL_SET_CHAIN_CERT_STORE = 107; + SSL_CTRL_GET_PEER_SIGNATURE_NID = 108; + SSL_CTRL_GET_PEER_TMP_KEY = 109; + SSL_CTRL_GET_RAW_CIPHERLIST = 110; + SSL_CTRL_GET_EC_POINT_FORMATS = 111; + SSL_CTRL_GET_CHAIN_CERTS = 115; + SSL_CTRL_SELECT_CURRENT_CERT = 116; + SSL_CTRL_SET_CURRENT_CERT = 117; + SSL_CTRL_SET_DH_AUTO = 118; + DTLS_CTRL_SET_LINK_MTU = 120; + DTLS_CTRL_GET_LINK_MIN_MTU = 121; + SSL_CTRL_GET_EXTMS_SUPPORT = 122; + SSL_CTRL_SET_MIN_PROTO_VERSION = 123; + SSL_CTRL_SET_MAX_PROTO_VERSION = 124; + SSL_CTRL_SET_SPLIT_SEND_FRAGMENT = 125; + SSL_CTRL_SET_MAX_PIPELINES = 126; + SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE = 127; + SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB = 128; + SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG = 129; + SSL_CTRL_GET_MIN_PROTO_VERSION = 130; + SSL_CTRL_GET_MAX_PROTO_VERSION = 131; + SSL_CTRL_GET_SIGNATURE_NID = 132; + SSL_CTRL_GET_TMP_KEY = 133; + SSL_CERT_SET_FIRST = 1; + SSL_CERT_SET_NEXT = 2; + SSL_CERT_SET_SERVER = 3; + SSL_CTRL_GET_SERVER_TMP_KEY = SSL_CTRL_GET_PEER_TMP_KEY; + SSL_CTRL_GET_CURVES = SSL_CTRL_GET_GROUPS; + SSL_CTRL_SET_CURVES = SSL_CTRL_SET_GROUPS; + SSL_CTRL_SET_CURVES_LIST = SSL_CTRL_SET_GROUPS_LIST; + SSL_CTRL_GET_SHARED_CURVE = SSL_CTRL_GET_SHARED_GROUP; + SSL_SERVERINFOV1 = 1; + SSL_SERVERINFOV2 = 2; + SSL_CLIENT_HELLO_SUCCESS = 1; + SSL_CLIENT_HELLO_ERROR = 0; + SSL_CLIENT_HELLO_RETRY = (-1); + SSL_READ_EARLY_DATA_ERROR = 0; + SSL_READ_EARLY_DATA_SUCCESS = 1; + SSL_READ_EARLY_DATA_FINISH = 2; + SSL_EARLY_DATA_NOT_SENT = 0; + SSL_EARLY_DATA_REJECTED = 1; + SSL_EARLY_DATA_ACCEPTED = 2; + SSL_SECOP_OTHER_TYPE = $ffff0000; + SSL_SECOP_OTHER_NONE = 0; + SSL_SECOP_OTHER_CIPHER = (1 shl 16); + SSL_SECOP_OTHER_CURVE = (2 shl 16); + SSL_SECOP_OTHER_DH = (3 shl 16); + SSL_SECOP_OTHER_PKEY = (4 shl 16); + SSL_SECOP_OTHER_SIGALG = (5 shl 16); + SSL_SECOP_OTHER_CERT = (6 shl 16); + SSL_SECOP_PEER = $1000; + SSL_SECOP_CIPHER_SUPPORTED = (1 or SSL_SECOP_OTHER_CIPHER); + SSL_SECOP_CIPHER_SHARED = (2 or SSL_SECOP_OTHER_CIPHER); + SSL_SECOP_CIPHER_CHECK = (3 or SSL_SECOP_OTHER_CIPHER); + SSL_SECOP_CURVE_SUPPORTED = (4 or SSL_SECOP_OTHER_CURVE); + SSL_SECOP_CURVE_SHARED = (5 or SSL_SECOP_OTHER_CURVE); + SSL_SECOP_CURVE_CHECK = (6 or SSL_SECOP_OTHER_CURVE); + SSL_SECOP_TMP_DH = (7 or SSL_SECOP_OTHER_PKEY); + SSL_SECOP_VERSION = (9 or SSL_SECOP_OTHER_NONE); + SSL_SECOP_TICKET = (10 or SSL_SECOP_OTHER_NONE); + SSL_SECOP_SIGALG_SUPPORTED = (11 or SSL_SECOP_OTHER_SIGALG); + SSL_SECOP_SIGALG_SHARED = (12 or SSL_SECOP_OTHER_SIGALG); + SSL_SECOP_SIGALG_CHECK = (13 or SSL_SECOP_OTHER_SIGALG); + SSL_SECOP_SIGALG_MASK = (14 or SSL_SECOP_OTHER_SIGALG); + SSL_SECOP_COMPRESSION = (15 or SSL_SECOP_OTHER_NONE); + SSL_SECOP_EE_KEY = (16 or SSL_SECOP_OTHER_CERT); + SSL_SECOP_CA_KEY = (17 or SSL_SECOP_OTHER_CERT); + SSL_SECOP_CA_MD = (18 or SSL_SECOP_OTHER_CERT); + SSL_SECOP_PEER_EE_KEY = (SSL_SECOP_EE_KEY or SSL_SECOP_PEER); + SSL_SECOP_PEER_CA_KEY = (SSL_SECOP_CA_KEY or SSL_SECOP_PEER); + SSL_SECOP_PEER_CA_MD = (SSL_SECOP_CA_MD or SSL_SECOP_PEER); + OPENSSL_INIT_NO_LOAD_SSL_STRINGS = $00100000; + OPENSSL_INIT_LOAD_SSL_STRINGS = $00200000; + OPENSSL_INIT_SSL_DEFAULT = (OPENSSL_INIT_LOAD_SSL_STRINGS or OPENSSL_INIT_LOAD_CRYPTO_STRINGS); + SSL_TICKET_FATAL_ERR_MALLOC = 0; + SSL_TICKET_FATAL_ERR_OTHER = 1; + SSL_TICKET_NONE = 2; + SSL_TICKET_EMPTY = 3; + SSL_TICKET_NO_DECRYPT = 4; + SSL_TICKET_SUCCESS = 5; + SSL_TICKET_SUCCESS_RENEW = 6; + SSL_TICKET_RETURN_ABORT = 0; + SSL_TICKET_RETURN_IGNORE = 1; + SSL_TICKET_RETURN_IGNORE_RENEW = 2; + SSL_TICKET_RETURN_USE = 3; + SSL_TICKET_RETURN_USE_RENEW = 4; + SRTP_AES128_CM_SHA1_80 = $0001; + SRTP_AES128_CM_SHA1_32 = $0002; + SRTP_AES128_F8_SHA1_80 = $0003; + SRTP_AES128_F8_SHA1_32 = $0004; + SRTP_NULL_SHA1_80 = $0005; + SRTP_NULL_SHA1_32 = $0006; + SRTP_AEAD_AES_128_GCM = $0007; + SRTP_AEAD_AES_256_GCM = $0008; + OSSL_STORE_F_FILE_CTRL = 129; + OSSL_STORE_F_FILE_FIND = 138; + OSSL_STORE_F_FILE_GET_PASS = 118; + OSSL_STORE_F_FILE_LOAD = 119; + OSSL_STORE_F_FILE_LOAD_TRY_DECODE = 124; + OSSL_STORE_F_FILE_NAME_TO_URI = 126; + OSSL_STORE_F_FILE_OPEN = 120; + OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO = 127; + OSSL_STORE_F_OSSL_STORE_EXPECT = 130; + OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT = 128; + OSSL_STORE_F_OSSL_STORE_FIND = 131; + OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT = 100; + OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT = 101; + OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL = 102; + OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME = 103; + OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION = 135; + OSSL_STORE_F_OSSL_STORE_INFO_GET1_PARAMS = 104; + OSSL_STORE_F_OSSL_STORE_INFO_GET1_PKEY = 105; + OSSL_STORE_F_OSSL_STORE_INFO_NEW_CERT = 106; + OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL = 107; + OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED = 123; + OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME = 109; + OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS = 110; + OSSL_STORE_F_OSSL_STORE_INFO_NEW_PKEY = 111; + OSSL_STORE_F_OSSL_STORE_INFO_SET0_NAME_DESCRIPTION = 134; + OSSL_STORE_F_OSSL_STORE_INIT_ONCE = 112; + OSSL_STORE_F_OSSL_STORE_LOADER_NEW = 113; + OSSL_STORE_F_OSSL_STORE_OPEN = 114; + OSSL_STORE_F_OSSL_STORE_OPEN_INT = 115; + OSSL_STORE_F_OSSL_STORE_REGISTER_LOADER_INT = 117; + OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ALIAS = 132; + OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ISSUER_SERIAL = 133; + OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT = 136; + OSSL_STORE_F_OSSL_STORE_SEARCH_BY_NAME = 137; + OSSL_STORE_F_OSSL_STORE_UNREGISTER_LOADER_INT = 116; + OSSL_STORE_F_TRY_DECODE_PARAMS = 121; + OSSL_STORE_F_TRY_DECODE_PKCS12 = 122; + OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED = 125; + OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE = 107; + OSSL_STORE_R_BAD_PASSWORD_READ = 115; + OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC = 113; + OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST = 121; + OSSL_STORE_R_INVALID_SCHEME = 106; + OSSL_STORE_R_IS_NOT_A = 112; + OSSL_STORE_R_LOADER_INCOMPLETE = 116; + OSSL_STORE_R_LOADING_STARTED = 117; + OSSL_STORE_R_NOT_A_CERTIFICATE = 100; + OSSL_STORE_R_NOT_A_CRL = 101; + OSSL_STORE_R_NOT_A_KEY = 102; + OSSL_STORE_R_NOT_A_NAME = 103; + OSSL_STORE_R_NOT_PARAMETERS = 104; + OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR = 114; + OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE = 108; + OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES = 119; + OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED = 109; + OSSL_STORE_R_UNREGISTERED_SCHEME = 105; + OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE = 110; + OSSL_STORE_R_UNSUPPORTED_OPERATION = 118; + OSSL_STORE_R_UNSUPPORTED_SEARCH_TYPE = 120; + OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED = 111; + OSSL_STORE_C_USE_SECMEM = 1; + OSSL_STORE_C_CUSTOM_START = 100; + OSSL_STORE_INFO_NAME = 1; + OSSL_STORE_INFO_PARAMS = 2; + OSSL_STORE_INFO_PKEY = 3; + OSSL_STORE_INFO_CERT = 4; + OSSL_STORE_INFO_CRL = 5; + _OSSL_STORE_SEARCH_BY_NAME = 1; + _OSSL_STORE_SEARCH_BY_ISSUER_SERIAL = 2; + _OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT = 3; + _OSSL_STORE_SEARCH_BY_ALIAS = 4; + TS_F_DEF_SERIAL_CB = 110; + TS_F_DEF_TIME_CB = 111; + TS_F_ESS_ADD_SIGNING_CERT = 112; + TS_F_ESS_ADD_SIGNING_CERT_V2 = 147; + TS_F_ESS_CERT_ID_NEW_INIT = 113; + TS_F_ESS_CERT_ID_V2_NEW_INIT = 156; + TS_F_ESS_SIGNING_CERT_NEW_INIT = 114; + TS_F_ESS_SIGNING_CERT_V2_NEW_INIT = 157; + TS_F_INT_TS_RESP_VERIFY_TOKEN = 149; + TS_F_PKCS7_TO_TS_TST_INFO = 148; + TS_F_TS_ACCURACY_SET_MICROS = 115; + TS_F_TS_ACCURACY_SET_MILLIS = 116; + TS_F_TS_ACCURACY_SET_SECONDS = 117; + TS_F_TS_CHECK_IMPRINTS = 100; + TS_F_TS_CHECK_NONCES = 101; + TS_F_TS_CHECK_POLICY = 102; + TS_F_TS_CHECK_SIGNING_CERTS = 103; + TS_F_TS_CHECK_STATUS_INFO = 104; + TS_F_TS_COMPUTE_IMPRINT = 145; + TS_F_TS_CONF_INVALID = 151; + TS_F_TS_CONF_LOAD_CERT = 153; + TS_F_TS_CONF_LOAD_CERTS = 154; + TS_F_TS_CONF_LOAD_KEY = 155; + TS_F_TS_CONF_LOOKUP_FAIL = 152; + TS_F_TS_CONF_SET_DEFAULT_ENGINE = 146; + TS_F_TS_GET_STATUS_TEXT = 105; + TS_F_TS_MSG_IMPRINT_SET_ALGO = 118; + TS_F_TS_REQ_SET_MSG_IMPRINT = 119; + TS_F_TS_REQ_SET_NONCE = 120; + TS_F_TS_REQ_SET_POLICY_ID = 121; + TS_F_TS_RESP_CREATE_RESPONSE = 122; + TS_F_TS_RESP_CREATE_TST_INFO = 123; + TS_F_TS_RESP_CTX_ADD_FAILURE_INFO = 124; + TS_F_TS_RESP_CTX_ADD_MD = 125; + TS_F_TS_RESP_CTX_ADD_POLICY = 126; + TS_F_TS_RESP_CTX_NEW = 127; + TS_F_TS_RESP_CTX_SET_ACCURACY = 128; + TS_F_TS_RESP_CTX_SET_CERTS = 129; + TS_F_TS_RESP_CTX_SET_DEF_POLICY = 130; + TS_F_TS_RESP_CTX_SET_SIGNER_CERT = 131; + TS_F_TS_RESP_CTX_SET_STATUS_INFO = 132; + TS_F_TS_RESP_GET_POLICY = 133; + TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION = 134; + TS_F_TS_RESP_SET_STATUS_INFO = 135; + TS_F_TS_RESP_SET_TST_INFO = 150; + TS_F_TS_RESP_SIGN = 136; + TS_F_TS_RESP_VERIFY_SIGNATURE = 106; + TS_F_TS_TST_INFO_SET_ACCURACY = 137; + TS_F_TS_TST_INFO_SET_MSG_IMPRINT = 138; + TS_F_TS_TST_INFO_SET_NONCE = 139; + TS_F_TS_TST_INFO_SET_POLICY_ID = 140; + TS_F_TS_TST_INFO_SET_SERIAL = 141; + TS_F_TS_TST_INFO_SET_TIME = 142; + TS_F_TS_TST_INFO_SET_TSA = 143; + TS_F_TS_VERIFY = 108; + TS_F_TS_VERIFY_CERT = 109; + TS_F_TS_VERIFY_CTX_NEW = 144; + TS_R_BAD_PKCS7_TYPE = 132; + TS_R_BAD_TYPE = 133; + TS_R_CANNOT_LOAD_CERT = 137; + TS_R_CANNOT_LOAD_KEY = 138; + TS_R_CERTIFICATE_VERIFY_ERROR = 100; + TS_R_COULD_NOT_SET_ENGINE = 127; + TS_R_COULD_NOT_SET_TIME = 115; + TS_R_DETACHED_CONTENT = 134; + TS_R_ESS_ADD_SIGNING_CERT_ERROR = 116; + TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR = 139; + TS_R_ESS_SIGNING_CERTIFICATE_ERROR = 101; + TS_R_INVALID_NULL_POINTER = 102; + TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE = 117; + TS_R_MESSAGE_IMPRINT_MISMATCH = 103; + TS_R_NONCE_MISMATCH = 104; + TS_R_NONCE_NOT_RETURNED = 105; + TS_R_NO_CONTENT = 106; + TS_R_NO_TIME_STAMP_TOKEN = 107; + TS_R_PKCS7_ADD_SIGNATURE_ERROR = 118; + TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR = 119; + TS_R_PKCS7_TO_TS_TST_INFO_FAILED = 129; + TS_R_POLICY_MISMATCH = 108; + TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE = 120; + TS_R_RESPONSE_SETUP_ERROR = 121; + TS_R_SIGNATURE_FAILURE = 109; + TS_R_THERE_MUST_BE_ONE_SIGNER = 110; + TS_R_TIME_SYSCALL_ERROR = 122; + TS_R_TOKEN_NOT_PRESENT = 130; + TS_R_TOKEN_PRESENT = 131; + TS_R_TSA_NAME_MISMATCH = 111; + TS_R_TSA_UNTRUSTED = 112; + TS_R_TST_INFO_SETUP_ERROR = 123; + TS_R_TS_DATASIGN = 124; + TS_R_UNACCEPTABLE_POLICY = 125; + TS_R_UNSUPPORTED_MD_ALGORITHM = 126; + TS_R_UNSUPPORTED_VERSION = 113; + TS_R_VAR_BAD_VALUE = 135; + TS_R_VAR_LOOKUP_FAILURE = 136; + TS_R_WRONG_CONTENT_TYPE = 114; + TS_STATUS_GRANTED = 0; + TS_STATUS_GRANTED_WITH_MODS = 1; + TS_STATUS_REJECTION = 2; + TS_STATUS_WAITING = 3; + TS_STATUS_REVOCATION_WARNING = 4; + TS_STATUS_REVOCATION_NOTIFICATION = 5; + TS_INFO_BAD_ALG = 0; + TS_INFO_BAD_REQUEST = 2; + TS_INFO_BAD_DATA_FORMAT = 5; + TS_INFO_TIME_NOT_AVAILABLE = 14; + TS_INFO_UNACCEPTED_POLICY = 15; + TS_INFO_UNACCEPTED_EXTENSION = 16; + TS_INFO_ADD_INFO_NOT_AVAILABLE = 17; + TS_INFO_SYSTEM_FAILURE = 25; + TS_TSA_NAME = $01; + TS_ORDERING = $02; + TS_ESS_CERT_ID_CHAIN = $04; + TS_MAX_CLOCK_PRECISION_DIGITS = 6; + TS_MAX_STATUS_LENGTH = (1024*1024); + TS_VFY_SIGNATURE = (1 shl 0); + TS_VFY_VERSION = (1 shl 1); + TS_VFY_POLICY = (1 shl 2); + TS_VFY_IMPRINT = (1 shl 3); + TS_VFY_DATA = (1 shl 4); + TS_VFY_NONCE = (1 shl 5); + TS_VFY_SIGNER = (1 shl 6); + TS_VFY_TSA_NAME = (1 shl 7); + TS_VFY_ALL_IMPRINT = (TS_VFY_SIGNATURE or TS_VFY_VERSION or TS_VFY_POLICY or TS_VFY_IMPRINT or TS_VFY_NONCE or TS_VFY_SIGNER or TS_VFY_TSA_NAME); + TS_VFY_ALL_DATA = (TS_VFY_SIGNATURE or TS_VFY_VERSION or TS_VFY_POLICY or TS_VFY_DATA or TS_VFY_NONCE or TS_VFY_SIGNER or TS_VFY_TSA_NAME); + DB_ERROR_OK = 0; + DB_ERROR_MALLOC = 1; + DB_ERROR_INDEX_CLASH = 2; + DB_ERROR_INDEX_OUT_OF_RANGE = 3; + DB_ERROR_NO_INDEX = 4; + DB_ERROR_INSERT_INDEX_CLASH = 5; + DB_ERROR_WRONG_NUM_FIELDS = 6; + WHIRLPOOL_DIGEST_LENGTH = (512 div 8); + WHIRLPOOL_BBLOCK = 512; + WHIRLPOOL_COUNTER = (256 div 8); + +type + // Forward declarations + PPUTF8Char = {$IFNDEF FPC}{$IF CompilerVersion > 21}^PUTF8Char{$ELSE}^PWideChar{$IFEND}{$ELSE}^PUTF8Char{$ENDIF}; + PPPUTF8Char = ^PPUTF8Char; + PPByte = ^PByte; + PPPByte = ^PPByte; + PPInteger = ^PInteger; + PNativeUInt = ^NativeUInt; + PInt64 = ^Int64; + PPointer = ^Pointer; + PUInt64 = ^UInt64; + PLongint = ^Longint; + PUInt8 = {$IFNDEF FPC}{$IF CompilerVersion > 21}^UInt8{$ELSE}^LongInt{$IFEND}{$ELSE}^UInt8{$ENDIF}; + PPUInt8 = ^PUInt8; + PUInt32 = {$IFNDEF FPC}{$IF CompilerVersion > 21}^UInt32{$ELSE}^LongInt{$IFEND}{$ELSE}^UInt32{$ENDIF}; + Pstack_st = Pointer; + PPstack_st = ^Pstack_st; + Pstack_st_OPENSSL_STRING = Pointer; + PPstack_st_OPENSSL_STRING = ^Pstack_st_OPENSSL_STRING; + Pstack_st_OPENSSL_CSTRING = Pointer; + PPstack_st_OPENSSL_CSTRING = ^Pstack_st_OPENSSL_CSTRING; + Pstack_st_OPENSSL_BLOCK = Pointer; + PPstack_st_OPENSSL_BLOCK = ^Pstack_st_OPENSSL_BLOCK; + Pasn1_object_st = Pointer; + PPasn1_object_st = ^Pasn1_object_st; + Pasn1_pctx_st = Pointer; + PPasn1_pctx_st = ^Pasn1_pctx_st; + Pasn1_sctx_st = Pointer; + PPasn1_sctx_st = ^Pasn1_sctx_st; + Pdane_st = Pointer; + PPdane_st = ^Pdane_st; + Pbio_st = Pointer; + PPbio_st = ^Pbio_st; + Pbignum_st = Pointer; + PPbignum_st = ^Pbignum_st; + Pbignum_ctx = Pointer; + PPbignum_ctx = ^Pbignum_ctx; + Pbn_blinding_st = Pointer; + PPbn_blinding_st = ^Pbn_blinding_st; + Pbn_mont_ctx_st = Pointer; + PPbn_mont_ctx_st = ^Pbn_mont_ctx_st; + Pbn_recp_ctx_st = Pointer; + PPbn_recp_ctx_st = ^Pbn_recp_ctx_st; + Pbn_gencb_st = Pointer; + PPbn_gencb_st = ^Pbn_gencb_st; + Pevp_cipher_st = Pointer; + PPevp_cipher_st = ^Pevp_cipher_st; + Pevp_cipher_ctx_st = Pointer; + PPevp_cipher_ctx_st = ^Pevp_cipher_ctx_st; + Pevp_md_st = Pointer; + PPevp_md_st = ^Pevp_md_st; + Pevp_md_ctx_st = Pointer; + PPevp_md_ctx_st = ^Pevp_md_ctx_st; + Pevp_pkey_st = Pointer; + PPevp_pkey_st = ^Pevp_pkey_st; + Pevp_pkey_asn1_method_st = Pointer; + PPevp_pkey_asn1_method_st = ^Pevp_pkey_asn1_method_st; + Pevp_pkey_method_st = Pointer; + PPevp_pkey_method_st = ^Pevp_pkey_method_st; + Pevp_pkey_ctx_st = Pointer; + PPevp_pkey_ctx_st = ^Pevp_pkey_ctx_st; + Pevp_Encode_Ctx_st = Pointer; + PPevp_Encode_Ctx_st = ^Pevp_Encode_Ctx_st; + Phmac_ctx_st = Pointer; + PPhmac_ctx_st = ^Phmac_ctx_st; + Prsa_meth_st = Pointer; + PPrsa_meth_st = ^Prsa_meth_st; + Pec_key_method_st = Pointer; + PPec_key_method_st = ^Pec_key_method_st; + Prand_drbg_st = Pointer; + PPrand_drbg_st = ^Prand_drbg_st; + Pssl_dane_st = Pointer; + PPssl_dane_st = ^Pssl_dane_st; + Px509_st = Pointer; + PPx509_st = ^Px509_st; + PX509_crl_st = Pointer; + PPX509_crl_st = ^PX509_crl_st; + Px509_crl_method_st = Pointer; + PPx509_crl_method_st = ^Px509_crl_method_st; + Px509_revoked_st = Pointer; + PPx509_revoked_st = ^Px509_revoked_st; + PX509_name_st = Pointer; + PPX509_name_st = ^PX509_name_st; + PX509_pubkey_st = Pointer; + PPX509_pubkey_st = ^PX509_pubkey_st; + Px509_store_st = Pointer; + PPx509_store_st = ^Px509_store_st; + Px509_store_ctx_st = Pointer; + PPx509_store_ctx_st = ^Px509_store_ctx_st; + Px509_object_st = Pointer; + PPx509_object_st = ^Px509_object_st; + Px509_lookup_st = Pointer; + PPx509_lookup_st = ^Px509_lookup_st; + Px509_lookup_method_st = Pointer; + PPx509_lookup_method_st = ^Px509_lookup_method_st; + PX509_VERIFY_PARAM_st = Pointer; + PPX509_VERIFY_PARAM_st = ^PX509_VERIFY_PARAM_st; + Px509_sig_info_st = Pointer; + PPx509_sig_info_st = ^Px509_sig_info_st; + Ppkcs8_priv_key_info_st = Pointer; + PPpkcs8_priv_key_info_st = ^Ppkcs8_priv_key_info_st; + Possl_init_settings_st = Pointer; + PPossl_init_settings_st = ^Possl_init_settings_st; + Pui_st = Pointer; + PPui_st = ^Pui_st; + Pui_method_st = Pointer; + PPui_method_st = ^Pui_method_st; + Pengine_st = Pointer; + PPengine_st = ^Pengine_st; + Pssl_st = Pointer; + PPssl_st = ^Pssl_st; + Pssl_ctx_st = Pointer; + PPssl_ctx_st = ^Pssl_ctx_st; + Pcomp_ctx_st = Pointer; + PPcomp_ctx_st = ^Pcomp_ctx_st; + Pcomp_method_st = Pointer; + PPcomp_method_st = ^Pcomp_method_st; + PX509_POLICY_NODE_st = Pointer; + PPX509_POLICY_NODE_st = ^PX509_POLICY_NODE_st; + PX509_POLICY_LEVEL_st = Pointer; + PPX509_POLICY_LEVEL_st = ^PX509_POLICY_LEVEL_st; + PX509_POLICY_TREE_st = Pointer; + PPX509_POLICY_TREE_st = ^PX509_POLICY_TREE_st; + PX509_POLICY_CACHE_st = Pointer; + PPX509_POLICY_CACHE_st = ^PX509_POLICY_CACHE_st; + Pocsp_req_ctx_st = Pointer; + PPocsp_req_ctx_st = ^Pocsp_req_ctx_st; + Pocsp_response_st = Pointer; + PPocsp_response_st = ^Pocsp_response_st; + Pocsp_responder_id_st = Pointer; + PPocsp_responder_id_st = ^Pocsp_responder_id_st; + Psct_st = Pointer; + PPsct_st = ^Psct_st; + Psct_ctx_st = Pointer; + PPsct_ctx_st = ^Psct_ctx_st; + Pctlog_st = Pointer; + PPctlog_st = ^Pctlog_st; + Pctlog_store_st = Pointer; + PPctlog_store_st = ^Pctlog_store_st; + Pct_policy_eval_ctx_st = Pointer; + PPct_policy_eval_ctx_st = ^Pct_policy_eval_ctx_st; + Possl_store_info_st = Pointer; + PPossl_store_info_st = ^Possl_store_info_st; + Possl_store_search_st = Pointer; + PPossl_store_search_st = ^Possl_store_search_st; + Pstack_st_void = Pointer; + PPstack_st_void = ^Pstack_st_void; + Pbio_addrinfo_st = Pointer; + PPbio_addrinfo_st = ^Pbio_addrinfo_st; + Pbio_method_st = Pointer; + PPbio_method_st = ^Pbio_method_st; + Pstack_st_BIO = Pointer; + PPstack_st_BIO = ^Pstack_st_BIO; + Phostent = Pointer; + PPhostent = ^Phostent; + Pstack_st_X509_ALGOR = Pointer; + PPstack_st_X509_ALGOR = ^Pstack_st_X509_ALGOR; + Pstack_st_ASN1_STRING_TABLE = Pointer; + PPstack_st_ASN1_STRING_TABLE = ^Pstack_st_ASN1_STRING_TABLE; + PASN1_VALUE_st = Pointer; + PPASN1_VALUE_st = ^PASN1_VALUE_st; + Pstack_st_ASN1_INTEGER = Pointer; + PPstack_st_ASN1_INTEGER = ^Pstack_st_ASN1_INTEGER; + Pstack_st_ASN1_GENERALSTRING = Pointer; + PPstack_st_ASN1_GENERALSTRING = ^Pstack_st_ASN1_GENERALSTRING; + Pstack_st_ASN1_UTF8STRING = Pointer; + PPstack_st_ASN1_UTF8STRING = ^Pstack_st_ASN1_UTF8STRING; + Pstack_st_ASN1_TYPE = Pointer; + PPstack_st_ASN1_TYPE = ^Pstack_st_ASN1_TYPE; + Pstack_st_ASN1_OBJECT = Pointer; + PPstack_st_ASN1_OBJECT = ^Pstack_st_ASN1_OBJECT; + Pstack_st_ASN1_VALUE = Pointer; + PPstack_st_ASN1_VALUE = ^Pstack_st_ASN1_VALUE; + Pasync_job_st = Pointer; + PPasync_job_st = ^Pasync_job_st; + Pasync_wait_ctx_st = Pointer; + PPasync_wait_ctx_st = ^Pasync_wait_ctx_st; + Prsa_st = Pointer; + PPrsa_st = ^Prsa_st; + Pdsa_st = Pointer; + PPdsa_st = ^Pdsa_st; + Pdh_st = Pointer; + PPdh_st = ^Pdh_st; + Pec_key_st = Pointer; + PPec_key_st = ^Pec_key_st; + PCMAC_CTX_st = Pointer; + PPCMAC_CTX_st = ^PCMAC_CTX_st; + Pec_method_st = Pointer; + PPec_method_st = ^Pec_method_st; + Pec_group_st = Pointer; + PPec_group_st = ^Pec_group_st; + Pec_point_st = Pointer; + PPec_point_st = ^Pec_point_st; + Pecpk_parameters_st = Pointer; + PPecpk_parameters_st = ^Pecpk_parameters_st; + Pec_parameters_st = Pointer; + PPec_parameters_st = ^Pec_parameters_st; + PECDSA_SIG_st = Pointer; + PPECDSA_SIG_st = ^PECDSA_SIG_st; + PDSA_SIG_st = Pointer; + PPDSA_SIG_st = ^PDSA_SIG_st; + PX509_sig_st = Pointer; + PPX509_sig_st = ^PX509_sig_st; + PX509_name_entry_st = Pointer; + PPX509_name_entry_st = ^PX509_name_entry_st; + Pstack_st_X509_NAME_ENTRY = Pointer; + PPstack_st_X509_NAME_ENTRY = ^Pstack_st_X509_NAME_ENTRY; + Pstack_st_X509_NAME = Pointer; + PPstack_st_X509_NAME = ^Pstack_st_X509_NAME; + PX509_extension_st = Pointer; + PPX509_extension_st = ^PX509_extension_st; + Pstack_st_X509_EXTENSION = Pointer; + PPstack_st_X509_EXTENSION = ^Pstack_st_X509_EXTENSION; + Px509_attributes_st = Pointer; + PPx509_attributes_st = ^Px509_attributes_st; + Pstack_st_X509_ATTRIBUTE = Pointer; + PPstack_st_X509_ATTRIBUTE = ^Pstack_st_X509_ATTRIBUTE; + PX509_req_info_st = Pointer; + PPX509_req_info_st = ^PX509_req_info_st; + PX509_req_st = Pointer; + PPX509_req_st = ^PX509_req_st; + Px509_cert_aux_st = Pointer; + PPx509_cert_aux_st = ^Px509_cert_aux_st; + Px509_cinf_st = Pointer; + PPx509_cinf_st = ^Px509_cinf_st; + Pstack_st_X509 = Pointer; + PPstack_st_X509 = ^Pstack_st_X509; + Pstack_st_X509_TRUST = Pointer; + PPstack_st_X509_TRUST = ^Pstack_st_X509_TRUST; + Pstack_st_X509_REVOKED = Pointer; + PPstack_st_X509_REVOKED = ^Pstack_st_X509_REVOKED; + PX509_crl_info_st = Pointer; + PPX509_crl_info_st = ^PX509_crl_info_st; + Pstack_st_X509_CRL = Pointer; + PPstack_st_X509_CRL = ^Pstack_st_X509_CRL; + Pstack_st_X509_INFO = Pointer; + PPstack_st_X509_INFO = ^Pstack_st_X509_INFO; + Plhash_node_st = Pointer; + PPlhash_node_st = ^Plhash_node_st; + Plhash_st = Pointer; + PPlhash_st = ^Plhash_st; + Pstack_st_X509_LOOKUP = Pointer; + PPstack_st_X509_LOOKUP = ^Pstack_st_X509_LOOKUP; + Pstack_st_X509_OBJECT = Pointer; + PPstack_st_X509_OBJECT = ^Pstack_st_X509_OBJECT; + Pstack_st_X509_VERIFY_PARAM = Pointer; + PPstack_st_X509_VERIFY_PARAM = ^Pstack_st_X509_VERIFY_PARAM; + Pstack_st_PKCS7_SIGNER_INFO = Pointer; + PPstack_st_PKCS7_SIGNER_INFO = ^Pstack_st_PKCS7_SIGNER_INFO; + Pstack_st_PKCS7_RECIP_INFO = Pointer; + PPstack_st_PKCS7_RECIP_INFO = ^Pstack_st_PKCS7_RECIP_INFO; + Pstack_st_PKCS7 = Pointer; + PPstack_st_PKCS7 = ^Pstack_st_PKCS7; + Pstack_st_CONF_VALUE = Pointer; + PPstack_st_CONF_VALUE = ^Pstack_st_CONF_VALUE; + Pconf_imodule_st = Pointer; + PPconf_imodule_st = ^Pconf_imodule_st; + Pconf_module_st = Pointer; + PPconf_module_st = ^Pconf_module_st; + Pstack_st_CONF_MODULE = Pointer; + PPstack_st_CONF_MODULE = ^Pstack_st_CONF_MODULE; + Pstack_st_CONF_IMODULE = Pointer; + PPstack_st_CONF_IMODULE = ^Pstack_st_CONF_IMODULE; + Pstack_st_X509V3_EXT_METHOD = Pointer; + PPstack_st_X509V3_EXT_METHOD = ^Pstack_st_X509V3_EXT_METHOD; + Pstack_st_GENERAL_NAME = Pointer; + PPstack_st_GENERAL_NAME = ^Pstack_st_GENERAL_NAME; + Pstack_st_GENERAL_NAMES = Pointer; + PPstack_st_GENERAL_NAMES = ^Pstack_st_GENERAL_NAMES; + Pstack_st_ACCESS_DESCRIPTION = Pointer; + PPstack_st_ACCESS_DESCRIPTION = ^Pstack_st_ACCESS_DESCRIPTION; + Pstack_st_DIST_POINT = Pointer; + PPstack_st_DIST_POINT = ^Pstack_st_DIST_POINT; + Pstack_st_SXNETID = Pointer; + PPstack_st_SXNETID = ^Pstack_st_SXNETID; + Pstack_st_POLICYQUALINFO = Pointer; + PPstack_st_POLICYQUALINFO = ^Pstack_st_POLICYQUALINFO; + Pstack_st_POLICYINFO = Pointer; + PPstack_st_POLICYINFO = ^Pstack_st_POLICYINFO; + Pstack_st_POLICY_MAPPING = Pointer; + PPstack_st_POLICY_MAPPING = ^Pstack_st_POLICY_MAPPING; + Pstack_st_GENERAL_SUBTREE = Pointer; + PPstack_st_GENERAL_SUBTREE = ^Pstack_st_GENERAL_SUBTREE; + Pstack_st_X509_PURPOSE = Pointer; + PPstack_st_X509_PURPOSE = ^Pstack_st_X509_PURPOSE; + Pstack_st_X509_POLICY_NODE = Pointer; + PPstack_st_X509_POLICY_NODE = ^Pstack_st_X509_POLICY_NODE; + Pstack_st_ASIdOrRange = Pointer; + PPstack_st_ASIdOrRange = ^Pstack_st_ASIdOrRange; + Pstack_st_IPAddressOrRange = Pointer; + PPstack_st_IPAddressOrRange = ^Pstack_st_IPAddressOrRange; + Pstack_st_IPAddressFamily = Pointer; + PPstack_st_IPAddressFamily = ^Pstack_st_IPAddressFamily; + Pstack_st_ASN1_STRING = Pointer; + PPstack_st_ASN1_STRING = ^Pstack_st_ASN1_STRING; + PNamingAuthority_st = Pointer; + PPNamingAuthority_st = ^PNamingAuthority_st; + PProfessionInfo_st = Pointer; + PPProfessionInfo_st = ^PProfessionInfo_st; + PAdmissions_st = Pointer; + PPAdmissions_st = ^PAdmissions_st; + PAdmissionSyntax_st = Pointer; + PPAdmissionSyntax_st = ^PAdmissionSyntax_st; + Pstack_st_ADMISSIONS = Pointer; + PPstack_st_ADMISSIONS = ^Pstack_st_ADMISSIONS; + Pstack_st_PROFESSION_INFO = Pointer; + PPstack_st_PROFESSION_INFO = ^Pstack_st_PROFESSION_INFO; + PCMS_ContentInfo_st = Pointer; + PPCMS_ContentInfo_st = ^PCMS_ContentInfo_st; + PCMS_SignerInfo_st = Pointer; + PPCMS_SignerInfo_st = ^PCMS_SignerInfo_st; + PCMS_RevocationInfoChoice_st = Pointer; + PPCMS_RevocationInfoChoice_st = ^PCMS_RevocationInfoChoice_st; + PCMS_RecipientInfo_st = Pointer; + PPCMS_RecipientInfo_st = ^PCMS_RecipientInfo_st; + PCMS_ReceiptRequest_st = Pointer; + PPCMS_ReceiptRequest_st = ^PCMS_ReceiptRequest_st; + PCMS_Receipt_st = Pointer; + PPCMS_Receipt_st = ^PCMS_Receipt_st; + PCMS_RecipientEncryptedKey_st = Pointer; + PPCMS_RecipientEncryptedKey_st = ^PCMS_RecipientEncryptedKey_st; + PCMS_OtherKeyAttribute_st = Pointer; + PPCMS_OtherKeyAttribute_st = ^PCMS_OtherKeyAttribute_st; + Pstack_st_CMS_SignerInfo = Pointer; + PPstack_st_CMS_SignerInfo = ^Pstack_st_CMS_SignerInfo; + Pstack_st_CMS_RecipientEncryptedKey = Pointer; + PPstack_st_CMS_RecipientEncryptedKey = ^Pstack_st_CMS_RecipientEncryptedKey; + Pstack_st_CMS_RecipientInfo = Pointer; + PPstack_st_CMS_RecipientInfo = ^Pstack_st_CMS_RecipientInfo; + Pstack_st_CMS_RevocationInfoChoice = Pointer; + PPstack_st_CMS_RevocationInfoChoice = ^Pstack_st_CMS_RevocationInfoChoice; + Pstack_st_SCT = Pointer; + PPstack_st_SCT = ^Pstack_st_SCT; + Pstack_st_CTLOG = Pointer; + PPstack_st_CTLOG = ^Pstack_st_CTLOG; + Pui_string_st = Pointer; + PPui_string_st = ^Pui_string_st; + Pstack_st_UI_STRING = Pointer; + PPstack_st_UI_STRING = ^Pstack_st_UI_STRING; + Pocsp_cert_id_st = Pointer; + PPocsp_cert_id_st = ^Pocsp_cert_id_st; + Pstack_st_OCSP_CERTID = Pointer; + PPstack_st_OCSP_CERTID = ^Pstack_st_OCSP_CERTID; + Pocsp_one_request_st = Pointer; + PPocsp_one_request_st = ^Pocsp_one_request_st; + Pstack_st_OCSP_ONEREQ = Pointer; + PPstack_st_OCSP_ONEREQ = ^Pstack_st_OCSP_ONEREQ; + Pocsp_req_info_st = Pointer; + PPocsp_req_info_st = ^Pocsp_req_info_st; + Pocsp_signature_st = Pointer; + PPocsp_signature_st = ^Pocsp_signature_st; + Pocsp_request_st = Pointer; + PPocsp_request_st = ^Pocsp_request_st; + Pocsp_resp_bytes_st = Pointer; + PPocsp_resp_bytes_st = ^Pocsp_resp_bytes_st; + Pstack_st_OCSP_RESPID = Pointer; + PPstack_st_OCSP_RESPID = ^Pstack_st_OCSP_RESPID; + Pocsp_revoked_info_st = Pointer; + PPocsp_revoked_info_st = ^Pocsp_revoked_info_st; + Pocsp_cert_status_st = Pointer; + PPocsp_cert_status_st = ^Pocsp_cert_status_st; + Pocsp_single_response_st = Pointer; + PPocsp_single_response_st = ^Pocsp_single_response_st; + Pstack_st_OCSP_SINGLERESP = Pointer; + PPstack_st_OCSP_SINGLERESP = ^Pstack_st_OCSP_SINGLERESP; + Pocsp_response_data_st = Pointer; + PPocsp_response_data_st = ^Pocsp_response_data_st; + Pocsp_basic_response_st = Pointer; + PPocsp_basic_response_st = ^Pocsp_basic_response_st; + Pocsp_crl_id_st = Pointer; + PPocsp_crl_id_st = ^Pocsp_crl_id_st; + Pocsp_service_locator_st = Pointer; + PPocsp_service_locator_st = ^Pocsp_service_locator_st; + PPKCS12_MAC_DATA_st = Pointer; + PPPKCS12_MAC_DATA_st = ^PPKCS12_MAC_DATA_st; + PPKCS12_st = Pointer; + PPPKCS12_st = ^PPKCS12_st; + PPKCS12_SAFEBAG_st = Pointer; + PPPKCS12_SAFEBAG_st = ^PPKCS12_SAFEBAG_st; + Pstack_st_PKCS12_SAFEBAG = Pointer; + PPstack_st_PKCS12_SAFEBAG = ^Pstack_st_PKCS12_SAFEBAG; + Ppkcs12_bag_st = Pointer; + PPpkcs12_bag_st = ^Ppkcs12_bag_st; + Pstack_st_SRP_gN_cache = Pointer; + PPstack_st_SRP_gN_cache = ^Pstack_st_SRP_gN_cache; + Pstack_st_SRP_user_pwd = Pointer; + PPstack_st_SRP_user_pwd = ^Pstack_st_SRP_user_pwd; + Pstack_st_SRP_gN = Pointer; + PPstack_st_SRP_gN = ^Pstack_st_SRP_gN; + Pssl_method_st = Pointer; + PPssl_method_st = ^Pssl_method_st; + Pssl_cipher_st = Pointer; + PPssl_cipher_st = ^Pssl_cipher_st; + Pssl_session_st = Pointer; + PPssl_session_st = ^Pssl_session_st; + Ptls_sigalgs_st = Pointer; + PPtls_sigalgs_st = ^Ptls_sigalgs_st; + Pssl_conf_ctx_st = Pointer; + PPssl_conf_ctx_st = ^Pssl_conf_ctx_st; + Pssl_comp_st = Pointer; + PPssl_comp_st = ^Pssl_comp_st; + Pstack_st_SRTP_PROTECTION_PROFILE = Pointer; + PPstack_st_SRTP_PROTECTION_PROFILE = ^Pstack_st_SRTP_PROTECTION_PROFILE; + Plhash_st_SSL_SESSION = Pointer; + PPlhash_st_SSL_SESSION = ^Plhash_st_SSL_SESSION; + Pstack_st_SSL_CIPHER = Pointer; + PPstack_st_SSL_CIPHER = ^Pstack_st_SSL_CIPHER; + Pstack_st_SSL_COMP = Pointer; + PPstack_st_SSL_COMP = ^Pstack_st_SSL_COMP; + Possl_store_ctx_st = Pointer; + PPossl_store_ctx_st = ^Possl_store_ctx_st; + Possl_store_loader_st = Pointer; + PPossl_store_loader_st = ^Possl_store_loader_st; + Possl_store_loader_ctx_st = Pointer; + PPossl_store_loader_ctx_st = ^Possl_store_loader_ctx_st; + PTS_msg_imprint_st = Pointer; + PPTS_msg_imprint_st = ^PTS_msg_imprint_st; + PTS_req_st = Pointer; + PPTS_req_st = ^PTS_req_st; + PTS_accuracy_st = Pointer; + PPTS_accuracy_st = ^PTS_accuracy_st; + PTS_tst_info_st = Pointer; + PPTS_tst_info_st = ^PTS_tst_info_st; + PTS_status_info_st = Pointer; + PPTS_status_info_st = ^PTS_status_info_st; + Pstack_st_ESS_CERT_ID = Pointer; + PPstack_st_ESS_CERT_ID = ^Pstack_st_ESS_CERT_ID; + PESS_cert_id_v2_st = Pointer; + PPESS_cert_id_v2_st = ^PESS_cert_id_v2_st; + PESS_signing_cert_v2_st = Pointer; + PPESS_signing_cert_v2_st = ^PESS_signing_cert_v2_st; + Pstack_st_ESS_CERT_ID_V2 = Pointer; + PPstack_st_ESS_CERT_ID_V2 = ^Pstack_st_ESS_CERT_ID_V2; + PTS_resp_st = Pointer; + PPTS_resp_st = ^PTS_resp_st; + Pstack_st_EVP_MD = Pointer; + PPstack_st_EVP_MD = ^Pstack_st_EVP_MD; + Pstack_st_OPENSSL_PSTRING = Pointer; + PPstack_st_OPENSSL_PSTRING = ^Pstack_st_OPENSSL_PSTRING; + Paes_key_st = ^aes_key_st; + PCRYPTO_dynlock = ^CRYPTO_dynlock; + Pcrypto_ex_data_st = ^crypto_ex_data_st; + Pcrypto_threadid_st = ^crypto_threadid_st; + Pasn1_string_st = ^asn1_string_st; + PASN1_ENCODING_st = ^ASN1_ENCODING_st; + Pasn1_string_table_st = ^asn1_string_table_st; + Pasn1_type_st = ^asn1_type_st; + PBIT_STRING_BITNAME_st = ^BIT_STRING_BITNAME_st; + PASN1_TEMPLATE_st = ^ASN1_TEMPLATE_st; + PASN1_ADB_st = ^ASN1_ADB_st; + PASN1_ADB_TABLE_st = ^ASN1_ADB_TABLE_st; + PASN1_ITEM_st = ^ASN1_ITEM_st; + PASN1_TLC_st = ^ASN1_TLC_st; + PASN1_EXTERN_FUNCS_st = ^ASN1_EXTERN_FUNCS_st; + PASN1_PRIMITIVE_FUNCS_st = ^ASN1_PRIMITIVE_FUNCS_st; + PASN1_AUX_st = ^ASN1_AUX_st; + PASN1_PRINT_ARG_st = ^ASN1_PRINT_ARG_st; + PASN1_STREAM_ARG_st = ^ASN1_STREAM_ARG_st; + Pbf_key_st = ^bf_key_st; + Pbuf_mem_st = ^buf_mem_st; + Pcamellia_key_st = ^camellia_key_st; + Pcast_key_st = ^cast_key_st; + Pobj_name_st = ^obj_name_st; + PEVP_CTRL_TLS1_1_MULTIBLOCK_PARAM = ^EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM; + Pevp_cipher_info_st = ^evp_cipher_info_st; + PEC_builtin_curve = ^EC_builtin_curve; + Prsa_pss_params_st = ^rsa_pss_params_st; + Prsa_oaep_params_st = ^rsa_oaep_params_st; + PSHAstate_st = ^SHAstate_st; + PSHA256state_st = ^SHA256state_st; + PSHA512state_st = ^SHA512state_st; + PX509_algor_st = ^X509_algor_st; + PX509_val_st = ^X509_val_st; + Px509_trust_st = ^x509_trust_st; + Pprivate_key_st = ^private_key_st; + PX509_info_st = ^X509_info_st; + PNetscape_spkac_st = ^Netscape_spkac_st; + PNetscape_spki_st = ^Netscape_spki_st; + PNetscape_certificate_sequence = ^Netscape_certificate_sequence; + PPBEPARAM_st = ^PBEPARAM_st; + PPBE2PARAM_st = ^PBE2PARAM_st; + PPBKDF2PARAM_st = ^PBKDF2PARAM_st; + PSCRYPT_PARAMS_st = ^SCRYPT_PARAMS_st; + Plhash_st_OPENSSL_STRING = ^lhash_st_OPENSSL_STRING; + PPlhash_st_OPENSSL_STRING = ^Plhash_st_OPENSSL_STRING; + Plhash_st_OPENSSL_CSTRING = ^lhash_st_OPENSSL_CSTRING; + Ppkcs7_issuer_and_serial_st = ^pkcs7_issuer_and_serial_st; + Ppkcs7_signer_info_st = ^pkcs7_signer_info_st; + Ppkcs7_recip_info_st = ^pkcs7_recip_info_st; + Ppkcs7_signed_st = ^pkcs7_signed_st; + Ppkcs7_enc_content_st = ^pkcs7_enc_content_st; + Ppkcs7_enveloped_st = ^pkcs7_enveloped_st; + Ppkcs7_signedandenveloped_st = ^pkcs7_signedandenveloped_st; + Ppkcs7_digest_st = ^pkcs7_digest_st; + Ppkcs7_encrypted_st = ^pkcs7_encrypted_st; + Ppkcs7_st = ^pkcs7_st; + PCONF_VALUE = ^CONF_VALUE; + PPCONF_VALUE = ^PCONF_VALUE; + Plhash_st_CONF_VALUE = ^lhash_st_CONF_VALUE; + Pconf_method_st = ^conf_method_st; + Pconf_st = ^conf_st; + Pv3_ext_method = ^v3_ext_method; + PX509V3_CONF_METHOD_st = ^X509V3_CONF_METHOD_st; + Pv3_ext_ctx = ^v3_ext_ctx; + PBASIC_CONSTRAINTS_st = ^BASIC_CONSTRAINTS_st; + PPKEY_USAGE_PERIOD_st = ^PKEY_USAGE_PERIOD_st; + PotherName_st = ^otherName_st; + PEDIPartyName_st = ^EDIPartyName_st; + PGENERAL_NAME_st = ^GENERAL_NAME_st; + PACCESS_DESCRIPTION_st = ^ACCESS_DESCRIPTION_st; + PDIST_POINT_NAME_st = ^DIST_POINT_NAME_st; + PDIST_POINT_st = ^DIST_POINT_st; + PAUTHORITY_KEYID_st = ^AUTHORITY_KEYID_st; + PSXNET_ID_st = ^SXNET_ID_st; + PSXNET_st = ^SXNET_st; + PNOTICEREF_st = ^NOTICEREF_st; + PUSERNOTICE_st = ^USERNOTICE_st; + PPOLICYQUALINFO_st = ^POLICYQUALINFO_st; + PPOLICYINFO_st = ^POLICYINFO_st; + PPOLICY_MAPPING_st = ^POLICY_MAPPING_st; + PGENERAL_SUBTREE_st = ^GENERAL_SUBTREE_st; + PNAME_CONSTRAINTS_st = ^NAME_CONSTRAINTS_st; + PPOLICY_CONSTRAINTS_st = ^POLICY_CONSTRAINTS_st; + PPROXY_POLICY_st = ^PROXY_POLICY_st; + PPROXY_CERT_INFO_EXTENSION_st = ^PROXY_CERT_INFO_EXTENSION_st; + PISSUING_DIST_POINT_st = ^ISSUING_DIST_POINT_st; + Px509_purpose_st = ^x509_purpose_st; + PASRange_st = ^ASRange_st; + PASIdOrRange_st = ^ASIdOrRange_st; + PASIdentifierChoice_st = ^ASIdentifierChoice_st; + PASIdentifiers_st = ^ASIdentifiers_st; + PIPAddressRange_st = ^IPAddressRange_st; + PIPAddressOrRange_st = ^IPAddressOrRange_st; + PIPAddressChoice_st = ^IPAddressChoice_st; + PIPAddressFamily_st = ^IPAddressFamily_st; + PDES_ks = ^DES_ks; + Prand_meth_st = ^rand_meth_st; + Perr_state_st = ^err_state_st; + PERR_string_data_st = ^ERR_string_data_st; + Plhash_st_ERR_STRING_DATA = ^lhash_st_ERR_STRING_DATA; + PENGINE_CMD_DEFN_st = ^ENGINE_CMD_DEFN_st; + Pst_dynamic_MEM_fns = ^st_dynamic_MEM_fns; + Pst_dynamic_fns = ^st_dynamic_fns; + Pidea_key_st = ^idea_key_st; + PMD4state_st = ^MD4state_st; + PMD5state_st = ^MD5state_st; + Pmdc2_ctx_st = ^mdc2_ctx_st; + Prc2_key_st = ^rc2_key_st; + Prc4_key_st = ^rc4_key_st; + PRIPEMD160state_st = ^RIPEMD160state_st; + Pseed_key_st = ^seed_key_st; + PSRP_gN_cache_st = ^SRP_gN_cache_st; + PSRP_user_pwd_st = ^SRP_user_pwd_st; + PSRP_VBASE_st = ^SRP_VBASE_st; + PSRP_gN_st = ^SRP_gN_st; + Psrtp_protection_profile_st = ^srtp_protection_profile_st; + Ptls_session_ticket_ext_st = ^tls_session_ticket_ext_st; + Ptxt_db_st = ^txt_db_st; + PWHIRLPOOL_CTX = ^WHIRLPOOL_CTX; + + aes_key_st = record + rd_key: array [0..59] of Cardinal; + rounds: Integer; + end; + + AES_KEY = aes_key_st; + PAES_KEY = ^AES_KEY; + POPENSSL_STACK = Pointer; + PPOPENSSL_STACK = ^POPENSSL_STACK; + + OPENSSL_sk_compfunc = function(p1: Pointer; p2: Pointer): Integer; cdecl; + + OPENSSL_sk_freefunc = procedure(p1: Pointer); cdecl; + + OPENSSL_sk_copyfunc = function(p1: Pointer): Pointer; cdecl; + {$IFNDEF FPC} + {$IF CompilerVersion > 21} + OPENSSL_STRING = PUTF8Char; + {$ELSE} + OPENSSL_STRING = PWideChar; + {$IFEND} + {$ELSE} + OPENSSL_STRING = PUTF8Char; + {$ENDIF} + POPENSSL_STRING = ^OPENSSL_STRING; + PPOPENSSL_STRING = ^POPENSSL_STRING; + POPENSSL_CSTRING = {$IFNDEF FPC}{$IF CompilerVersion > 21}POPENSSL_STRING{$ELSE}^WideString{$IFEND}{$ELSE}PAnsiChar{$ENDIF}; + sk_OPENSSL_STRING_compfunc = function(a: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; b: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + + sk_OPENSSL_STRING_freefunc = procedure(a: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}); cdecl; + + sk_OPENSSL_STRING_copyfunc = function(a: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + + sk_OPENSSL_CSTRING_compfunc = function(a: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; b: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + + sk_OPENSSL_CSTRING_freefunc = procedure(a: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}); cdecl; + + sk_OPENSSL_CSTRING_copyfunc = function(a: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + OPENSSL_BLOCK = Pointer; + + sk_OPENSSL_BLOCK_compfunc = function(a: PPointer; b: PPointer): Integer; cdecl; + + sk_OPENSSL_BLOCK_freefunc = procedure(a: Pointer); cdecl; + + sk_OPENSSL_BLOCK_copyfunc = function(a: Pointer): Pointer; cdecl; + PBIO = Pointer; + PPBIO = ^PBIO; + PBIGNUM = Pointer; + PPBIGNUM = ^PBIGNUM; + PBN_CTX = Pointer; + PPBN_CTX = ^PBN_CTX; + PBN_BLINDING = Pointer; + PPBN_BLINDING = ^PBN_BLINDING; + PBN_MONT_CTX = Pointer; + PPBN_MONT_CTX = ^PBN_MONT_CTX; + PBN_RECP_CTX = Pointer; + PPBN_RECP_CTX = ^PBN_RECP_CTX; + PBN_GENCB = Pointer; + PPBN_GENCB = ^PBN_GENCB; + PEVP_CIPHER = Pointer; + PPEVP_CIPHER = ^PEVP_CIPHER; + PEVP_CIPHER_CTX = Pointer; + PPEVP_CIPHER_CTX = ^PEVP_CIPHER_CTX; + PEVP_MD = Pointer; + PPEVP_MD = ^PEVP_MD; + PEVP_MD_CTX = Pointer; + PPEVP_MD_CTX = ^PEVP_MD_CTX; + PEVP_PKEY = Pointer; + PPEVP_PKEY = ^PEVP_PKEY; + PEVP_PKEY_ASN1_METHOD = Pointer; + PPEVP_PKEY_ASN1_METHOD = ^PEVP_PKEY_ASN1_METHOD; + PEVP_PKEY_METHOD = Pointer; + PPEVP_PKEY_METHOD = ^PEVP_PKEY_METHOD; + PEVP_PKEY_CTX = Pointer; + PPEVP_PKEY_CTX = ^PEVP_PKEY_CTX; + PEVP_ENCODE_CTX = Pointer; + PPEVP_ENCODE_CTX = ^PEVP_ENCODE_CTX; + PHMAC_CTX = Pointer; + PPHMAC_CTX = ^PHMAC_CTX; + PDH = Pointer; + PPDH = ^PDH; + PDH_METHOD = Pointer; + PPDH_METHOD = ^PDH_METHOD; + PDSA = Pointer; + PPDSA = ^PDSA; + PDSA_METHOD = Pointer; + PPDSA_METHOD = ^PDSA_METHOD; + PRSA = Pointer; + PPRSA = ^PRSA; + PRSA_METHOD = Pointer; + PPRSA_METHOD = ^PRSA_METHOD; + PEC_KEY = Pointer; + PPEC_KEY = ^PEC_KEY; + PEC_KEY_METHOD = Pointer; + PPEC_KEY_METHOD = ^PEC_KEY_METHOD; + PSSL_DANE = Pointer; + PPSSL_DANE = ^PSSL_DANE; + PX509_CRL = Pointer; + PPX509_CRL = ^PX509_CRL; + PX509_CRL_METHOD = Pointer; + PPX509_CRL_METHOD = ^PX509_CRL_METHOD; + PX509_REVOKED = Pointer; + PPX509_REVOKED = ^PX509_REVOKED; + PX509_NAME = Pointer; + PPX509_NAME = ^PX509_NAME; + PX509_PUBKEY = Pointer; + PPX509_PUBKEY = ^PX509_PUBKEY; + PX509_STORE = Pointer; + PPX509_STORE = ^PX509_STORE; + PX509_STORE_CTX = Pointer; + PPX509_STORE_CTX = ^PX509_STORE_CTX; + PX509_OBJECT = Pointer; + PPX509_OBJECT = ^PX509_OBJECT; + PX509_LOOKUP = Pointer; + PPX509_LOOKUP = ^PX509_LOOKUP; + PX509_LOOKUP_METHOD = Pointer; + PPX509_LOOKUP_METHOD = ^PX509_LOOKUP_METHOD; + PX509_VERIFY_PARAM = Pointer; + PPX509_VERIFY_PARAM = ^PX509_VERIFY_PARAM; + PX509_SIG_INFO = Pointer; + PPX509_SIG_INFO = ^PX509_SIG_INFO; + PPKCS8_PRIV_KEY_INFO = Pointer; + PPPKCS8_PRIV_KEY_INFO = ^PPKCS8_PRIV_KEY_INFO; + PX509V3_CTX = ^X509V3_CTX; + PCONF = ^CONF; + POPENSSL_INIT_SETTINGS = Pointer; + PPOPENSSL_INIT_SETTINGS = ^POPENSSL_INIT_SETTINGS; + PUI = Pointer; + PPUI = ^PUI; + PUI_METHOD = Pointer; + PPUI_METHOD = ^PUI_METHOD; + PENGINE = Pointer; + PPENGINE = ^PENGINE; + PSSL = Pointer; + PPSSL = ^PSSL; + PSSL_CTX = Pointer; + PPSSL_CTX = ^PSSL_CTX; + PCOMP_CTX = Pointer; + PPCOMP_CTX = ^PCOMP_CTX; + PCOMP_METHOD = Pointer; + PPCOMP_METHOD = ^PCOMP_METHOD; + PX509_POLICY_NODE = Pointer; + PPX509_POLICY_NODE = ^PX509_POLICY_NODE; + PX509_POLICY_LEVEL = Pointer; + PPX509_POLICY_LEVEL = ^PX509_POLICY_LEVEL; + PX509_POLICY_TREE = Pointer; + PPX509_POLICY_TREE = ^PX509_POLICY_TREE; + PX509_POLICY_CACHE = Pointer; + PPX509_POLICY_CACHE = ^PX509_POLICY_CACHE; + PAUTHORITY_KEYID = ^AUTHORITY_KEYID; + PPAUTHORITY_KEYID = ^PAUTHORITY_KEYID; + PDIST_POINT = ^DIST_POINT; + PPDIST_POINT = ^PDIST_POINT; + PISSUING_DIST_POINT = ^ISSUING_DIST_POINT; + PPISSUING_DIST_POINT = ^PISSUING_DIST_POINT; + POCSP_REQ_CTX = Pointer; + PPOCSP_REQ_CTX = ^POCSP_REQ_CTX; + POCSP_RESPONSE = Pointer; + PPOCSP_RESPONSE = ^POCSP_RESPONSE; + POCSP_RESPID = Pointer; + PPOCSP_RESPID = ^POCSP_RESPID; + PSCT = Pointer; + PPSCT = ^PSCT; + PSCT_CTX = Pointer; + PPSCT_CTX = ^PSCT_CTX; + PCTLOG = Pointer; + PPCTLOG = ^PCTLOG; + PCTLOG_STORE = Pointer; + PPCTLOG_STORE = ^PCTLOG_STORE; + PCT_POLICY_EVAL_CTX = Pointer; + PPCT_POLICY_EVAL_CTX = ^PCT_POLICY_EVAL_CTX; + POSSL_STORE_INFO = Pointer; + PPOSSL_STORE_INFO = ^POSSL_STORE_INFO; + POSSL_STORE_SEARCH = Pointer; + PPOSSL_STORE_SEARCH = ^POSSL_STORE_SEARCH; + ossl_intmax_t = Int64; + ossl_uintmax_t = UInt64; + + CRYPTO_dynlock = record + dummy: Integer; + end; + + PCRYPTO_RWLOCK = Pointer; + PPCRYPTO_RWLOCK = ^PCRYPTO_RWLOCK; + + crypto_ex_data_st = record + sk: Pstack_st_void; + end; + CRYPTO_EX_DATA = crypto_ex_data_st; + PCRYPTO_EX_DATA = ^CRYPTO_EX_DATA; + + sk_void_compfunc = function(a: PPointer; b: PPointer): Integer; cdecl; + + sk_void_freefunc = procedure(a: Pointer); cdecl; + + sk_void_copyfunc = function(a: Pointer): Pointer; cdecl; + + PCRYPTO_EX_new = procedure(parent: Pointer; ptr: Pointer; ad: PCRYPTO_EX_DATA; idx: Integer; argl: Integer; argp: Pointer); cdecl; + + PCRYPTO_EX_free = procedure(parent: Pointer; ptr: Pointer; ad: PCRYPTO_EX_DATA; idx: Integer; argl: Integer; argp: Pointer); cdecl; + + PCRYPTO_EX_dup = function(t2: PCRYPTO_EX_DATA; from: PCRYPTO_EX_DATA; from_d: Pointer; idx: Integer; argl: Integer; argp: Pointer): Integer; cdecl; + + crypto_threadid_st = record + dummy: Integer; + end; + + CRYPTO_THREADID = crypto_threadid_st; + CRYPTO_ONCE = Cardinal; + PCRYPTO_ONCE = ^CRYPTO_ONCE; + CRYPTO_THREAD_LOCAL = Cardinal; + PCRYPTO_THREAD_LOCAL = ^CRYPTO_THREAD_LOCAL; + CRYPTO_THREAD_ID = Cardinal; + PBIO_ADDR = Pointer; + PPBIO_ADDR = ^PBIO_ADDR; + PBIO_ADDRINFO = Pointer; + PPBIO_ADDRINFO = ^PBIO_ADDRINFO; + + BIO_callback_fn = function(b: PBIO; oper: Integer; argp: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; argi: Integer; argl: Integer; ret: Integer): Integer; cdecl; + + BIO_callback_fn_ex = function(b: PBIO; oper: Integer; argp: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: NativeUInt; argi: Integer; argl: Integer; ret: Integer; processed: PNativeUInt): Integer; cdecl; + PBIO_METHOD = Pointer; + PPBIO_METHOD = ^PBIO_METHOD; + + PBIO_info_cb = function(p1: PBIO; p2: Integer; p3: Integer): Integer; cdecl; + //bio_info_cb = BIO_info_cb; + + sk_BIO_compfunc = function(a: PPBIO; b: PPBIO): Integer; cdecl; + + sk_BIO_freefunc = procedure(a: PBIO); cdecl; + + sk_BIO_copyfunc = function(a: PBIO): Pbio_st; cdecl; + + Pasn1_ps_func = function(b: PBIO; pbuf: PPByte; plen: PInteger; parg: Pointer): Integer; cdecl; + + BIO_hostserv_priorities = ( + BIO_PARSE_PRIO_HOST = 0, + BIO_PARSE_PRIO_SERV = 1); + PBIO_hostserv_priorities = ^BIO_hostserv_priorities; + + BIO_lookup_type = ( + BIO_LOOKUP_CLIENT = 0, + BIO_LOOKUP_SERVER = 1); + PBIO_lookup_type = ^BIO_lookup_type; + + BIO_sock_info_u = record + case Integer of + 0: (addr: PBIO_ADDR); + end; + + BIO_sock_info_type = ( + BIO_SOCK_INFO_ADDRESS = 0); + PBIO_sock_info_type = ^BIO_sock_info_type; + + asn1_string_st = record + length: Integer; + {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}t1pe{$IFEND}{$ELSE}&type{$ENDIF}: Integer; + data: PByte; + flags: Integer; + end; + + ASN1_INTEGER = asn1_string_st; + PASN1_INTEGER = ^ASN1_INTEGER; + PPASN1_INTEGER = ^PASN1_INTEGER; + ASN1_ENUMERATED = asn1_string_st; + PASN1_ENUMERATED = ^ASN1_ENUMERATED; + PPASN1_ENUMERATED = ^PASN1_ENUMERATED; + ASN1_BIT_STRING = asn1_string_st; + PASN1_BIT_STRING = ^ASN1_BIT_STRING; + PPASN1_BIT_STRING = ^PASN1_BIT_STRING; + ASN1_OCTET_STRING = asn1_string_st; + PASN1_OCTET_STRING = ^ASN1_OCTET_STRING; + PPASN1_OCTET_STRING = ^PASN1_OCTET_STRING; + ASN1_PRINTABLESTRING = asn1_string_st; + PASN1_PRINTABLESTRING = ^ASN1_PRINTABLESTRING; + PPASN1_PRINTABLESTRING = ^PASN1_PRINTABLESTRING; + ASN1_T61STRING = asn1_string_st; + PASN1_T61STRING = ^ASN1_T61STRING; + PPASN1_T61STRING = ^PASN1_T61STRING; + ASN1_IA5STRING = asn1_string_st; + PASN1_IA5STRING = ^ASN1_IA5STRING; + PPASN1_IA5STRING = ^PASN1_IA5STRING; + ASN1_GENERALSTRING = asn1_string_st; + PASN1_GENERALSTRING = ^ASN1_GENERALSTRING; + PPASN1_GENERALSTRING = ^PASN1_GENERALSTRING; + ASN1_UNIVERSALSTRING = asn1_string_st; + PASN1_UNIVERSALSTRING = ^ASN1_UNIVERSALSTRING; + PPASN1_UNIVERSALSTRING = ^PASN1_UNIVERSALSTRING; + ASN1_BMPSTRING = asn1_string_st; + PASN1_BMPSTRING = ^ASN1_BMPSTRING; + PPASN1_BMPSTRING = ^PASN1_BMPSTRING; + ASN1_UTCTIME = asn1_string_st; + PASN1_UTCTIME = ^ASN1_UTCTIME; + PPASN1_UTCTIME = ^PASN1_UTCTIME; + ASN1_TIME = asn1_string_st; + PASN1_TIME = ^ASN1_TIME; + PPASN1_TIME = ^PASN1_TIME; + ASN1_GENERALIZEDTIME = asn1_string_st; + PASN1_GENERALIZEDTIME = ^ASN1_GENERALIZEDTIME; + PPASN1_GENERALIZEDTIME = ^PASN1_GENERALIZEDTIME; + ASN1_VISIBLESTRING = asn1_string_st; + PASN1_VISIBLESTRING = ^ASN1_VISIBLESTRING; + PPASN1_VISIBLESTRING = ^PASN1_VISIBLESTRING; + ASN1_UTF8STRING = asn1_string_st; + PASN1_UTF8STRING = ^ASN1_UTF8STRING; + PPASN1_UTF8STRING = ^PASN1_UTF8STRING; + ASN1_STRING = asn1_string_st; + PASN1_STRING = ^ASN1_STRING; + PPASN1_STRING = ^PASN1_STRING; + ASN1_BOOLEAN = Integer; + ASN1_NULL = Integer; + PASN1_NULL = ^ASN1_NULL; + PPASN1_NULL = ^PASN1_NULL; + PASN1_OBJECT = Pointer; + PPASN1_OBJECT = ^PASN1_OBJECT; + PASN1_PCTX = Pointer; + PPASN1_PCTX = ^PASN1_PCTX; + PASN1_SCTX = Pointer; + PPASN1_SCTX = ^PASN1_SCTX; + + ASN1_ENCODING_st = record + enc: PByte; + len: Integer; + modified: Integer; + end; + + ASN1_ENCODING = ASN1_ENCODING_st; + + asn1_string_table_st = record + nid: Integer; + minsize: Integer; + maxsize: Integer; + mask: Cardinal; + flags: Cardinal; + end; + + ASN1_STRING_TABLE = asn1_string_table_st; + PASN1_STRING_TABLE = ^ASN1_STRING_TABLE; + PPASN1_STRING_TABLE = ^PASN1_STRING_TABLE; + + sk_ASN1_STRING_TABLE_compfunc = function(a: PPASN1_STRING_TABLE; b: PPASN1_STRING_TABLE): Integer; cdecl; + + sk_ASN1_STRING_TABLE_freefunc = procedure(a: PASN1_STRING_TABLE); cdecl; + + sk_ASN1_STRING_TABLE_copyfunc = function(a: PASN1_STRING_TABLE): Pasn1_string_table_st; cdecl; + PASN1_VALUE = Pointer; + PPASN1_VALUE = ^PASN1_VALUE; + + Pd2i_of_void = function(p1: PPointer; p2: PPByte; p3: Integer): Pointer; cdecl; + + Pi2d_of_void = function(p1: Pointer; p2: PPByte): Integer; cdecl; + + sk_ASN1_INTEGER_compfunc = function(a: PPASN1_INTEGER; b: PPASN1_INTEGER): Integer; cdecl; + + sk_ASN1_INTEGER_freefunc = procedure(a: PASN1_INTEGER); cdecl; + + sk_ASN1_INTEGER_copyfunc = function(a: PASN1_INTEGER): Pasn1_string_st; cdecl; + + sk_ASN1_GENERALSTRING_compfunc = function(a: PPASN1_GENERALSTRING; b: PPASN1_GENERALSTRING): Integer; cdecl; + + sk_ASN1_GENERALSTRING_freefunc = procedure(a: PASN1_GENERALSTRING); cdecl; + + sk_ASN1_GENERALSTRING_copyfunc = function(a: PASN1_GENERALSTRING): Pasn1_string_st; cdecl; + + sk_ASN1_UTF8STRING_compfunc = function(a: PPASN1_UTF8STRING; b: PPASN1_UTF8STRING): Integer; cdecl; + + sk_ASN1_UTF8STRING_freefunc = procedure(a: PASN1_UTF8STRING); cdecl; + + sk_ASN1_UTF8STRING_copyfunc = function(a: PASN1_UTF8STRING): Pasn1_string_st; cdecl; + + _anonymous_type_1 = record + case Integer of + 0: (ptr: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}); + 1: (boolean: ASN1_BOOLEAN); + 2: (asn1_string: PASN1_STRING); + 3: ({$IFNDEF FPC}{$IF CompilerVersion > 21}&object{$ELSE}object1{$IFEND}{$ELSE}&object{$ENDIF}: PASN1_OBJECT); + 4: ({$IFNDEF FPC}{$IF CompilerVersion > 21}&integer{$ELSE}integer1{$IFEND}{$ELSE}&integer{$ENDIF}: PASN1_INTEGER); + 5: (enumerated: PASN1_ENUMERATED); + 6: (bit_string: PASN1_BIT_STRING); + 7: (octet_string: PASN1_OCTET_STRING); + 8: (printablestring: PASN1_PRINTABLESTRING); + 9: (t61string: PASN1_T61STRING); + 10: (ia5string: PASN1_IA5STRING); + 11: (generalstring: PASN1_GENERALSTRING); + 12: (bmpstring: PASN1_BMPSTRING); + 13: (universalstring: PASN1_UNIVERSALSTRING); + 14: (utctime: PASN1_UTCTIME); + 15: (generalizedtime: PASN1_GENERALIZEDTIME); + 16: (visiblestring: PASN1_VISIBLESTRING); + 17: (utf8string: PASN1_UTF8STRING); + 18: ({$IFNDEF FPC}{$IF CompilerVersion > 21}&set{$ELSE}set1{$IFEND}{$ELSE}&set{$ENDIF}: PASN1_STRING); + 19: (sequence: PASN1_STRING); + 20: (asn1_value: PASN1_VALUE); + end; + P_anonymous_type_1 = ^_anonymous_type_1; + + asn1_type_st = record + {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; + value: _anonymous_type_1; + end; + + ASN1_TYPE = asn1_type_st; + PASN1_TYPE = ^ASN1_TYPE; + PPASN1_TYPE = ^PASN1_TYPE; + + sk_ASN1_TYPE_compfunc = function(a: PPASN1_TYPE; b: PPASN1_TYPE): Integer; cdecl; + + sk_ASN1_TYPE_freefunc = procedure(a: PASN1_TYPE); cdecl; + + sk_ASN1_TYPE_copyfunc = function(a: PASN1_TYPE): Pasn1_type_st; cdecl; + PASN1_SEQUENCE_ANY = Pointer; + PPASN1_SEQUENCE_ANY = ^PASN1_SEQUENCE_ANY; + + BIT_STRING_BITNAME_st = record + bitnum: Integer; + lname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + sname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + end; + + BIT_STRING_BITNAME = BIT_STRING_BITNAME_st; + PBIT_STRING_BITNAME = ^BIT_STRING_BITNAME; + + sk_ASN1_OBJECT_compfunc = function(a: PPASN1_OBJECT; b: PPASN1_OBJECT): Integer; cdecl; + + sk_ASN1_OBJECT_freefunc = procedure(a: PASN1_OBJECT); cdecl; + + sk_ASN1_OBJECT_copyfunc = function(a: PASN1_OBJECT): Pasn1_object_st; cdecl; + + PASN1_ITEM_EXP = function(): Pointer{PASN1_ITEM}; cdecl; + + ASN1_TEMPLATE_st = record + flags: Cardinal; + tag: Integer; + offset: Cardinal; + field_name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + item: PASN1_ITEM_EXP; + end; + ASN1_TEMPLATE = ASN1_TEMPLATE_st; + PASN1_TEMPLATE = ^ASN1_TEMPLATE; + + ASN1_ITEM_st = record + itype: {$IFNDEF FPC}{$IF CompilerVersion > 21}UTF8Char{$ELSE}WideChar{$IFEND}{$ELSE}UTF8Char{$ENDIF}; + utype: Integer; + templates: PASN1_TEMPLATE; + tcount: Integer; + funcs: Pointer; + size: Integer; + sname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + end; + ASN1_ITEM = ASN1_ITEM_st; + PASN1_ITEM = ^ASN1_ITEM; + + ASN1_ADB_TABLE_st = record + value: Integer; + tt: ASN1_TEMPLATE; + end; + + ASN1_ADB_TABLE = ASN1_ADB_TABLE_st; + PASN1_ADB_TABLE = ^ASN1_ADB_TABLE; + + ASN1_ADB_st = record + flags: Cardinal; + offset: Cardinal; + adb_cb: function(psel: PInteger): Integer; cdecl; + tbl: PASN1_ADB_TABLE; + tblcount: Integer; + default_tt: PASN1_TEMPLATE; + null_tt: PASN1_TEMPLATE; + end; + + ASN1_ADB = ASN1_ADB_st; + + ASN1_TLC_st = record + valid: {$IFNDEF FPC}{$IF CompilerVersion > 21}UTF8Char{$ELSE}WideChar{$IFEND}{$ELSE}UTF8Char{$ENDIF}; + ret: Integer; + plen: Integer; + ptag: Integer; + pclass: Integer; + hdrlen: Integer; + end; + ASN1_TLC = ASN1_TLC_st; + PASN1_TLC = ^ASN1_TLC; + + PASN1_ex_d2i = function(pval: PPASN1_VALUE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer; it: PASN1_ITEM; tag: Integer; aclass: Integer; opt: {$IFNDEF FPC}{$IF CompilerVersion > 21}UTF8Char{$ELSE}WideChar{$IFEND}{$ELSE}UTF8Char{$ENDIF}; ctx: PASN1_TLC): Integer; cdecl; + + PASN1_ex_i2d = function(pval: PPASN1_VALUE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte; it: PASN1_ITEM; tag: Integer; aclass: Integer): Integer; cdecl; + + PASN1_ex_new_func = function(pval: PPASN1_VALUE; it: PASN1_ITEM): Integer; cdecl; + + PASN1_ex_free_func = procedure(pval: PPASN1_VALUE; it: PASN1_ITEM); cdecl; + + PASN1_ex_print_func = function({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; pval: PPASN1_VALUE; indent: Integer; fname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; pctx: PASN1_PCTX): Integer; cdecl; + + PASN1_primitive_i2c = function(pval: PPASN1_VALUE; cont: PByte; putype: PInteger; it: PASN1_ITEM): Integer; cdecl; + + PASN1_primitive_c2i = function(pval: PPASN1_VALUE; cont: PByte; len: Integer; utype: Integer; free_cont: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; it: PASN1_ITEM): Integer; cdecl; + + PASN1_primitive_print = function({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; pval: PPASN1_VALUE; it: PASN1_ITEM; indent: Integer; pctx: PASN1_PCTX): Integer; cdecl; + + ASN1_EXTERN_FUNCS_st = record + app_data: Pointer; + asn1_ex_new: PASN1_ex_new_func; + asn1_ex_free: PASN1_ex_free_func; + asn1_ex_clear: PASN1_ex_free_func; + asn1_ex_d2i: PASN1_ex_d2i; + asn1_ex_i2d: PASN1_ex_i2d; + asn1_ex_print: PASN1_ex_print_func; + end; + + ASN1_EXTERN_FUNCS = ASN1_EXTERN_FUNCS_st; + + ASN1_PRIMITIVE_FUNCS_st = record + app_data: Pointer; + flags: Cardinal; + prim_new: PASN1_ex_new_func; + prim_free: PASN1_ex_free_func; + prim_clear: PASN1_ex_free_func; + prim_c2i: PASN1_primitive_c2i; + prim_i2c: PASN1_primitive_i2c; + prim_print: PASN1_primitive_print; + end; + + ASN1_PRIMITIVE_FUNCS = ASN1_PRIMITIVE_FUNCS_st; + + PASN1_aux_cb = function(operation: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPASN1_VALUE; it: PASN1_ITEM; exarg: Pointer): Integer; cdecl; + + ASN1_AUX_st = record + app_data: Pointer; + flags: Integer; + ref_offset: Integer; + ref_lock: Integer; + asn1_cb: PASN1_aux_cb; + enc_offset: Integer; + end; + + ASN1_AUX = ASN1_AUX_st; + + ASN1_PRINT_ARG_st = record + {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; + indent: Integer; + pctx: PASN1_PCTX; + end; + + ASN1_PRINT_ARG = ASN1_PRINT_ARG_st; + + ASN1_STREAM_ARG_st = record + {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; + ndef_bio: PBIO; + boundary: PPByte; + end; + + ASN1_STREAM_ARG = ASN1_STREAM_ARG_st; + + sk_ASN1_VALUE_compfunc = function(a: PPASN1_VALUE; b: PPASN1_VALUE): Integer; cdecl; + + sk_ASN1_VALUE_freefunc = procedure(a: PASN1_VALUE); cdecl; + + sk_ASN1_VALUE_copyfunc = function(a: PASN1_VALUE): PASN1_VALUE_st; cdecl; + PASYNC_JOB = Pointer; + PPASYNC_JOB = ^PASYNC_JOB; + PASYNC_WAIT_CTX = Pointer; + PPASYNC_WAIT_CTX = ^PASYNC_WAIT_CTX; + + bf_key_st = record + P: array [0..17] of Cardinal; + S: array [0..1023] of Cardinal; + end; + + BF_KEY = bf_key_st; + PBF_KEY = ^BF_KEY; + + buf_mem_st = record + length: NativeUInt; + data: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + max: NativeUInt; + flags: Cardinal; + end; + + BUF_MEM = buf_mem_st; + PBUF_MEM = ^BUF_MEM; + + KEY_TABLE_TYPE = array [0..67] of Cardinal; + + _anonymous_type_2 = record + case Integer of + 0: (d: Double); + 1: (rd_key: KEY_TABLE_TYPE); + end; + P_anonymous_type_2 = ^_anonymous_type_2; + + camellia_key_st = record + u: _anonymous_type_2; + grand_rounds: Integer; + end; + + CAMELLIA_KEY = camellia_key_st; + PCAMELLIA_KEY = ^CAMELLIA_KEY; + + cast_key_st = record + data: array [0..31] of Cardinal; + short_key: Integer; + end; + + CAST_KEY = cast_key_st; + PCAST_KEY = ^CAST_KEY; + + obj_name_st = record + {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; + alias: Integer; + name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + data: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + end; + + OBJ_NAME = obj_name_st; + POBJ_NAME = ^OBJ_NAME; + + EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM = record + {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; + inp: PByte; + len: NativeUInt; + interleave: Cardinal; + end; + + evp_cipher_info_st = record + cipher: PEVP_CIPHER; + iv: array [0..15] of Byte; + end; + + EVP_CIPHER_INFO = evp_cipher_info_st; + PEVP_CIPHER_INFO = ^EVP_CIPHER_INFO; + + PEVP_PBE_KEYGEN = function(ctx: PEVP_CIPHER_CTX; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; param: PASN1_TYPE; cipher: PEVP_CIPHER; md: PEVP_MD; en_de: Integer): Integer; cdecl; + + PEVP_PKEY_gen_cb = function(ctx: PEVP_PKEY_CTX): Integer; cdecl; + PCMAC_CTX = Pointer; + PPCMAC_CTX = ^PCMAC_CTX; + + (** Enum for the point conversion form as defined in X9.62 (ECDSA) + * for the encoding of a elliptic curve point (x,y) *) + point_conversion_form_t = ( + (** the point is encoded as z||x, where the octet z specifies + * which solution of the quadratic equation y is *) + POINT_CONVERSION_COMPRESSED = 2, + (** the point is encoded as z||x||y, where z is the octet 0x04 *) + POINT_CONVERSION_UNCOMPRESSED = 4, + (** the point is encoded as z||x||y, where the octet z specifies + * which solution of the quadratic equation y is *) + POINT_CONVERSION_HYBRID = 6); + Ppoint_conversion_form_t = ^point_conversion_form_t; + PEC_METHOD = Pointer; + PPEC_METHOD = ^PEC_METHOD; + PEC_GROUP = Pointer; + PPEC_GROUP = ^PEC_GROUP; + PEC_POINT = Pointer; + PPEC_POINT = ^PEC_POINT; + PECPKPARAMETERS = Pointer; + PPECPKPARAMETERS = ^PECPKPARAMETERS; + PECPARAMETERS = Pointer; + PPECPARAMETERS = ^PECPARAMETERS; + + (********************************************************************) + EC_builtin_curve = record + nid: Integer; + comment: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + end; + + PECDSA_SIG = Pointer; + PPECDSA_SIG = ^PECDSA_SIG; + + SHAstate_st = record + h0: Cardinal; + h1: Cardinal; + h2: Cardinal; + h3: Cardinal; + h4: Cardinal; + Nl: Cardinal; + Nh: Cardinal; + data: array [0..15] of Cardinal; + num: Cardinal; + end; + + SHA_CTX = SHAstate_st; + PSHA_CTX = ^SHA_CTX; + + SHA256state_st = record + h: array [0..7] of Cardinal; + Nl: Cardinal; + Nh: Cardinal; + data: array [0..15] of Cardinal; + num: Cardinal; + md_len: Cardinal; + end; + + SHA256_CTX = SHA256state_st; + PSHA256_CTX = ^SHA256_CTX; + + _anonymous_type_3 = record + case Integer of + 0: (d: array [0..15] of UInt64); + 1: (p: array [0..127] of Byte); + end; + P_anonymous_type_3 = ^_anonymous_type_3; + + SHA512state_st = record + h: array [0..7] of UInt64; + Nl: UInt64; + Nh: UInt64; + u: _anonymous_type_3; + num: Cardinal; + md_len: Cardinal; + end; + + SHA512_CTX = SHA512state_st; + PSHA512_CTX = ^SHA512_CTX; + + X509_algor_st = record + algorithm: PASN1_OBJECT; + parameter: PASN1_TYPE; + end; + + PX509_ALGORS = Pointer; + PPX509_ALGORS = ^PX509_ALGORS; + + X509_ALGOR = X509_algor_st; + PX509_ALGOR = ^X509_ALGOR; + PPX509_ALGOR = ^PX509_ALGOR; + + sk_X509_ALGOR_compfunc = function(a: PPX509_ALGOR; b: PPX509_ALGOR): Integer; cdecl; + + sk_X509_ALGOR_freefunc = procedure(a: PX509_ALGOR); cdecl; + + sk_X509_ALGOR_copyfunc = function(a: PX509_ALGOR): PX509_algor_st; cdecl; + + rsa_pss_params_st = record + hashAlgorithm: PX509_ALGOR; + maskGenAlgorithm: PX509_ALGOR; + saltLength: PASN1_INTEGER; + trailerField: PASN1_INTEGER; + maskHash: PX509_ALGOR; + end; + + RSA_PSS_PARAMS = rsa_pss_params_st; + PRSA_PSS_PARAMS = ^RSA_PSS_PARAMS; + PPRSA_PSS_PARAMS = ^PRSA_PSS_PARAMS; + + rsa_oaep_params_st = record + hashFunc: PX509_ALGOR; + maskGenFunc: PX509_ALGOR; + pSourceFunc: PX509_ALGOR; + maskHash: PX509_ALGOR; + end; + + RSA_OAEP_PARAMS = rsa_oaep_params_st; + PRSA_OAEP_PARAMS = ^RSA_OAEP_PARAMS; + PPRSA_OAEP_PARAMS = ^PRSA_OAEP_PARAMS; + PDSA_SIG = Pointer; + PPDSA_SIG = ^PDSA_SIG; + + X509_val_st = record + notBefore: PASN1_TIME; + notAfter: PASN1_TIME; + end; + + X509_VAL = X509_val_st; + PX509_VAL = ^X509_VAL; + PPX509_VAL = ^PX509_VAL; + PX509_SIG = Pointer; + PPX509_SIG = ^PX509_SIG; + PX509_NAME_ENTRY = Pointer; + PPX509_NAME_ENTRY = ^PX509_NAME_ENTRY; + + sk_X509_NAME_ENTRY_compfunc = function(a: PPX509_NAME_ENTRY; b: PPX509_NAME_ENTRY): Integer; cdecl; + + sk_X509_NAME_ENTRY_freefunc = procedure(a: PX509_NAME_ENTRY); cdecl; + + sk_X509_NAME_ENTRY_copyfunc = function(a: PX509_NAME_ENTRY): PX509_name_entry_st; cdecl; + + sk_X509_NAME_compfunc = function(a: PPX509_NAME; b: PPX509_NAME): Integer; cdecl; + + sk_X509_NAME_freefunc = procedure(a: PX509_NAME); cdecl; + + sk_X509_NAME_copyfunc = function(a: PX509_NAME): PX509_name_st; cdecl; + PX509_EXTENSION = Pointer; + PPX509_EXTENSION = ^PX509_EXTENSION; + PX509_EXTENSIONS = Pointer; + PPX509_EXTENSIONS = ^PX509_EXTENSIONS; + + sk_X509_EXTENSION_compfunc = function(a: PPX509_EXTENSION; b: PPX509_EXTENSION): Integer; cdecl; + + sk_X509_EXTENSION_freefunc = procedure(a: PX509_EXTENSION); cdecl; + + sk_X509_EXTENSION_copyfunc = function(a: PX509_EXTENSION): PX509_extension_st; cdecl; + PX509_ATTRIBUTE = Pointer; + PPX509_ATTRIBUTE = ^PX509_ATTRIBUTE; + + sk_X509_ATTRIBUTE_compfunc = function(a: PPX509_ATTRIBUTE; b: PPX509_ATTRIBUTE): Integer; cdecl; + + sk_X509_ATTRIBUTE_freefunc = procedure(a: PX509_ATTRIBUTE); cdecl; + + sk_X509_ATTRIBUTE_copyfunc = function(a: PX509_ATTRIBUTE): Px509_attributes_st; cdecl; + PX509_REQ_INFO = Pointer; + PPX509_REQ_INFO = ^PX509_REQ_INFO; + PX509_REQ = Pointer; + PPX509_REQ = ^PX509_REQ; + PX509_CERT_AUX = Pointer; + PPX509_CERT_AUX = ^PX509_CERT_AUX; + + { Certinfo } + TX509_CINF = record + version: PASN1_INTEGER; + serialNumber: PASN1_INTEGER; + signature: PX509_ALGOR; + issuer: PX509_NAME; + validity: PX509_VAL; + subject: PX509_NAME; + key: PX509_PUBKEY; + end; + PX509_CINF = ^TX509_CINF; + PPX509_CINF = ^PX509_CINF; + + TX509 = record + cert_info: PX509_CINF; + sig_alg: PX509_ALGOR; + signature: PASN1_BIT_STRING; + valid: Integer; + references: Integer; + name: {$IFNDEF FPC}{$IF CompilerVersion > 21}MarshaledAString{$ELSE}String{$IFEND}{$ELSE}MarshaledAString{$ENDIF}; + end; + PX509 = ^TX509; + PPX509 = ^PX509; + PSTACK_OF_X509_INFO = PSTACK_st; + + PSTACK_OF_X509_ALGOR = PSTACK_st; + PSTACK_OF_X509 = PSTACK_st; + PPSTACK_OF_X509 = ^PSTACK_OF_X509; + PSTACK_OF_X509_CRL = PSTACK_st; + PSTACK_OF_PKCS7_SIGNER_INFO = PSTACK_st; + PSTACK_OF_X509_ATTRIBUTE = PSTACK_st; + PSTACK = PSTACK_st; + + sk_X509_compfunc = function(a: PPX509; b: PPX509): Integer; cdecl; + + sk_X509_freefunc = procedure(a: PX509); cdecl; + + sk_X509_copyfunc = function(a: PX509): Px509_st; cdecl; + + x509_trust_st = record + trust: Integer; + flags: Integer; + check_trust: function(p1: Px509_trust_st; p2: PX509; p3: Integer): Integer; cdecl; + name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + arg1: Integer; + arg2: Pointer; + end; + + X509_TRUST = x509_trust_st; + PX509_TRUST = ^X509_TRUST; + PPX509_TRUST = ^PX509_TRUST; + + sk_X509_TRUST_compfunc = function(a: PPX509_TRUST; b: PPX509_TRUST): Integer; cdecl; + + sk_X509_TRUST_freefunc = procedure(a: PX509_TRUST); cdecl; + + sk_X509_TRUST_copyfunc = function(a: PX509_TRUST): Px509_trust_st; cdecl; + + sk_X509_REVOKED_compfunc = function(a: PPX509_REVOKED; b: PPX509_REVOKED): Integer; cdecl; + + sk_X509_REVOKED_freefunc = procedure(a: PX509_REVOKED); cdecl; + + sk_X509_REVOKED_copyfunc = function(a: PX509_REVOKED): Px509_revoked_st; cdecl; + PX509_CRL_INFO = Pointer; + PPX509_CRL_INFO = ^PX509_CRL_INFO; + + sk_X509_CRL_compfunc = function(a: PPX509_CRL; b: PPX509_CRL): Integer; cdecl; + + sk_X509_CRL_freefunc = procedure(a: PX509_CRL); cdecl; + + sk_X509_CRL_copyfunc = function(a: PX509_CRL): PX509_crl_st; cdecl; + + private_key_st = record + version: Integer; + enc_algor: PX509_ALGOR; + enc_pkey: PASN1_OCTET_STRING; + dec_pkey: PEVP_PKEY; + key_length: Integer; + key_data: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + key_free: Integer; + cipher: EVP_CIPHER_INFO; + end; + + X509_PKEY = private_key_st; + PX509_PKEY = ^X509_PKEY; + + X509_info_st = record + x509: PX509; + crl: PX509_CRL; + x_pkey: PX509_PKEY; + enc_cipher: EVP_CIPHER_INFO; + enc_len: Integer; + enc_data: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + end; + + X509_INFO = X509_info_st; + PX509_INFO = ^X509_INFO; + PPX509_INFO = ^PX509_INFO; + + sk_X509_INFO_compfunc = function(a: PPX509_INFO; b: PPX509_INFO): Integer; cdecl; + + sk_X509_INFO_freefunc = procedure(a: PX509_INFO); cdecl; + + sk_X509_INFO_copyfunc = function(a: PX509_INFO): PX509_info_st; cdecl; + + Netscape_spkac_st = record + pubkey: PX509_PUBKEY; + challenge: PASN1_IA5STRING; + end; + + NETSCAPE_SPKAC = Netscape_spkac_st; + PNETSCAPE_SPKAC = ^NETSCAPE_SPKAC; + PPNETSCAPE_SPKAC = ^PNETSCAPE_SPKAC; + + Netscape_spki_st = record + spkac: PNETSCAPE_SPKAC; + sig_algor: X509_ALGOR; + signature: PASN1_BIT_STRING; + end; + + NETSCAPE_SPKI = Netscape_spki_st; + PNETSCAPE_SPKI = ^NETSCAPE_SPKI; + PPNETSCAPE_SPKI = ^PNETSCAPE_SPKI; + + Netscape_certificate_sequence = record + {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PASN1_OBJECT; + certs: Pstack_st_X509; + end; + + NETSCAPE_CERT_SEQUENCE = Netscape_certificate_sequence; + PNETSCAPE_CERT_SEQUENCE = ^NETSCAPE_CERT_SEQUENCE; + PPNETSCAPE_CERT_SEQUENCE = ^PNETSCAPE_CERT_SEQUENCE; + + PBEPARAM_st = record + salt: PASN1_OCTET_STRING; + iter: PASN1_INTEGER; + end; + + PBEPARAM = PBEPARAM_st; + PPBEPARAM = ^PBEPARAM; + PPPBEPARAM = ^PPBEPARAM; + + PBE2PARAM_st = record + keyfunc: PX509_ALGOR; + encryption: PX509_ALGOR; + end; + + PBE2PARAM = PBE2PARAM_st; + PPBE2PARAM = ^PBE2PARAM; + PPPBE2PARAM = ^PPBE2PARAM; + + PBKDF2PARAM_st = record + salt: PASN1_TYPE; + iter: PASN1_INTEGER; + keylength: PASN1_INTEGER; + prf: PX509_ALGOR; + end; + + PBKDF2PARAM = PBKDF2PARAM_st; + PPBKDF2PARAM = ^PBKDF2PARAM; + PPPBKDF2PARAM = ^PPBKDF2PARAM; + + SCRYPT_PARAMS_st = record + salt: PASN1_OCTET_STRING; + costParameter: PASN1_INTEGER; + blockSize: PASN1_INTEGER; + parallelizationParameter: PASN1_INTEGER; + keyLength: PASN1_INTEGER; + end; + + SCRYPT_PARAMS = SCRYPT_PARAMS_st; + PSCRYPT_PARAMS = ^SCRYPT_PARAMS; + PPSCRYPT_PARAMS = ^PSCRYPT_PARAMS; + POPENSSL_LH_NODE = Pointer; + PPOPENSSL_LH_NODE = ^POPENSSL_LH_NODE; + + OPENSSL_LH_COMPFUNC = function(p1: Pointer; p2: Pointer): Integer; cdecl; + + OPENSSL_LH_HASHFUNC = function(p1: Pointer): Cardinal; cdecl; + + OPENSSL_LH_DOALL_FUNC = procedure(p1: Pointer); cdecl; + + OPENSSL_LH_DOALL_FUNCARG = procedure(p1: Pointer; p2: Pointer); cdecl; + POPENSSL_LHASH = Pointer; + PPOPENSSL_LHASH = ^POPENSSL_LHASH; + + lh_OPENSSL_STRING_dummy = record + case Integer of + 0: (d1: Pointer); + 1: (d2: Cardinal); + 2: (d3: Integer); + end; + + lhash_st_OPENSSL_STRING = record + dummy: lh_OPENSSL_STRING_dummy; + end; + + lh_OPENSSL_CSTRING_dummy = record + case Integer of + 0: (d1: Pointer); + 1: (d2: Cardinal); + 2: (d3: Integer); + end; + + lhash_st_OPENSSL_CSTRING = record + dummy: lh_OPENSSL_CSTRING_dummy; + end; + + X509_LOOKUP_TYPE = ( + X509_LU_NONE = 0, + X509_LU_X509 = 1, + X509_LU_CRL = 2); + PX509_LOOKUP_TYPE = ^X509_LOOKUP_TYPE; + + sk_X509_LOOKUP_compfunc = function(a: PPX509_LOOKUP; b: PPX509_LOOKUP): Integer; cdecl; + + sk_X509_LOOKUP_freefunc = procedure(a: PX509_LOOKUP); cdecl; + + sk_X509_LOOKUP_copyfunc = function(a: PX509_LOOKUP): Px509_lookup_st; cdecl; + + sk_X509_OBJECT_compfunc = function(a: PPX509_OBJECT; b: PPX509_OBJECT): Integer; cdecl; + + sk_X509_OBJECT_freefunc = procedure(a: PX509_OBJECT); cdecl; + + sk_X509_OBJECT_copyfunc = function(a: PX509_OBJECT): Px509_object_st; cdecl; + + sk_X509_VERIFY_PARAM_compfunc = function(a: PPX509_VERIFY_PARAM; b: PPX509_VERIFY_PARAM): Integer; cdecl; + + sk_X509_VERIFY_PARAM_freefunc = procedure(a: PX509_VERIFY_PARAM); cdecl; + + sk_X509_VERIFY_PARAM_copyfunc = function(a: PX509_VERIFY_PARAM): PX509_VERIFY_PARAM_st; cdecl; + + X509_STORE_CTX_verify_cb = function(p1: Integer; p2: PX509_STORE_CTX): Integer; cdecl; + + X509_STORE_CTX_verify_fn = function(p1: PX509_STORE_CTX): Integer; cdecl; + + X509_STORE_CTX_get_issuer_fn = function(issuer: PPX509; ctx: PX509_STORE_CTX; x: PX509): Integer; cdecl; + + X509_STORE_CTX_check_issued_fn = function(ctx: PX509_STORE_CTX; x: PX509; issuer: PX509): Integer; cdecl; + + X509_STORE_CTX_check_revocation_fn = function(ctx: PX509_STORE_CTX): Integer; cdecl; + + X509_STORE_CTX_get_crl_fn = function(ctx: PX509_STORE_CTX; crl: PPX509_CRL; x: PX509): Integer; cdecl; + + X509_STORE_CTX_check_crl_fn = function(ctx: PX509_STORE_CTX; crl: PX509_CRL): Integer; cdecl; + + X509_STORE_CTX_cert_crl_fn = function(ctx: PX509_STORE_CTX; crl: PX509_CRL; x: PX509): Integer; cdecl; + + X509_STORE_CTX_check_policy_fn = function(ctx: PX509_STORE_CTX): Integer; cdecl; + + X509_STORE_CTX_lookup_certs_fn = function(ctx: PX509_STORE_CTX; nm: PX509_NAME): Pstack_st_X509; cdecl; + + X509_STORE_CTX_lookup_crls_fn = function(ctx: PX509_STORE_CTX; nm: PX509_NAME): Pstack_st_X509_CRL; cdecl; + + X509_STORE_CTX_cleanup_fn = function(ctx: PX509_STORE_CTX): Integer; cdecl; + + X509_LOOKUP_ctrl_fn = function(ctx: PX509_LOOKUP; cmd: Integer; argc: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; argl: Integer; ret: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}): Integer; cdecl; + + X509_LOOKUP_get_by_subject_fn = function(ctx: PX509_LOOKUP; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: X509_LOOKUP_TYPE; name: PX509_NAME; ret: PX509_OBJECT): Integer; cdecl; + + X509_LOOKUP_get_by_issuer_serial_fn = function(ctx: PX509_LOOKUP; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: X509_LOOKUP_TYPE; name: PX509_NAME; serial: PASN1_INTEGER; ret: PX509_OBJECT): Integer; cdecl; + + X509_LOOKUP_get_by_fingerprint_fn = function(ctx: PX509_LOOKUP; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: X509_LOOKUP_TYPE; bytes: PByte; len: Integer; ret: PX509_OBJECT): Integer; cdecl; + + X509_LOOKUP_get_by_alias_fn = function(ctx: PX509_LOOKUP; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: X509_LOOKUP_TYPE; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: Integer; ret: PX509_OBJECT): Integer; cdecl; + + pkcs7_issuer_and_serial_st = record + issuer: PX509_NAME; + serial: PASN1_INTEGER; + end; + + PKCS7_ISSUER_AND_SERIAL = pkcs7_issuer_and_serial_st; + PPKCS7_ISSUER_AND_SERIAL = ^PKCS7_ISSUER_AND_SERIAL; + PPPKCS7_ISSUER_AND_SERIAL = ^PPKCS7_ISSUER_AND_SERIAL; + + pkcs7_signer_info_st = record + version: PASN1_INTEGER; + issuer_and_serial: PPKCS7_ISSUER_AND_SERIAL; + digest_alg: PX509_ALGOR; + auth_attr: Pstack_st_X509_ATTRIBUTE; + digest_enc_alg: PX509_ALGOR; + enc_digest: PASN1_OCTET_STRING; + unauth_attr: Pstack_st_X509_ATTRIBUTE; + pkey: PEVP_PKEY; + end; + + PKCS7_SIGNER_INFO = pkcs7_signer_info_st; + PPKCS7_SIGNER_INFO = ^PKCS7_SIGNER_INFO; + PPPKCS7_SIGNER_INFO = ^PPKCS7_SIGNER_INFO; + + sk_PKCS7_SIGNER_INFO_compfunc = function(a: PPPKCS7_SIGNER_INFO; b: PPPKCS7_SIGNER_INFO): Integer; cdecl; + + sk_PKCS7_SIGNER_INFO_freefunc = procedure(a: PPKCS7_SIGNER_INFO); cdecl; + + sk_PKCS7_SIGNER_INFO_copyfunc = function(a: PPKCS7_SIGNER_INFO): Ppkcs7_signer_info_st; cdecl; + + pkcs7_recip_info_st = record + version: PASN1_INTEGER; + issuer_and_serial: PPKCS7_ISSUER_AND_SERIAL; + key_enc_algor: PX509_ALGOR; + enc_key: PASN1_OCTET_STRING; + cert: PX509; + end; + + PKCS7_RECIP_INFO = pkcs7_recip_info_st; + PPKCS7_RECIP_INFO = ^PKCS7_RECIP_INFO; + PPPKCS7_RECIP_INFO = ^PPKCS7_RECIP_INFO; + + sk_PKCS7_RECIP_INFO_compfunc = function(a: PPPKCS7_RECIP_INFO; b: PPPKCS7_RECIP_INFO): Integer; cdecl; + + sk_PKCS7_RECIP_INFO_freefunc = procedure(a: PPKCS7_RECIP_INFO); cdecl; + + sk_PKCS7_RECIP_INFO_copyfunc = function(a: PPKCS7_RECIP_INFO): Ppkcs7_recip_info_st; cdecl; + + pkcs7_signed_st = record + version: PASN1_INTEGER; + md_algs: Pstack_st_X509_ALGOR; + cert: Pstack_st_X509; + crl: Pstack_st_X509_CRL; + signer_info: Pstack_st_PKCS7_SIGNER_INFO; + contents: Ppkcs7_st; + end; + + PKCS7_SIGNED = pkcs7_signed_st; + PPKCS7_SIGNED = ^PKCS7_SIGNED; + PPPKCS7_SIGNED = ^PPKCS7_SIGNED; + + pkcs7_enc_content_st = record + content_type: PASN1_OBJECT; + algorithm: PX509_ALGOR; + enc_data: PASN1_OCTET_STRING; + cipher: PEVP_CIPHER; + end; + + PKCS7_ENC_CONTENT = pkcs7_enc_content_st; + PPKCS7_ENC_CONTENT = ^PKCS7_ENC_CONTENT; + PPPKCS7_ENC_CONTENT = ^PPKCS7_ENC_CONTENT; + + pkcs7_enveloped_st = record + version: PASN1_INTEGER; + recipientinfo: Pstack_st_PKCS7_RECIP_INFO; + enc_data: PPKCS7_ENC_CONTENT; + end; + + PKCS7_ENVELOPE = pkcs7_enveloped_st; + PPKCS7_ENVELOPE = ^PKCS7_ENVELOPE; + PPPKCS7_ENVELOPE = ^PPKCS7_ENVELOPE; + + pkcs7_signedandenveloped_st = record + version: PASN1_INTEGER; + md_algs: Pstack_st_X509_ALGOR; + cert: Pstack_st_X509; + crl: Pstack_st_X509_CRL; + signer_info: Pstack_st_PKCS7_SIGNER_INFO; + enc_data: PPKCS7_ENC_CONTENT; + recipientinfo: Pstack_st_PKCS7_RECIP_INFO; + end; + + PKCS7_SIGN_ENVELOPE = pkcs7_signedandenveloped_st; + PPKCS7_SIGN_ENVELOPE = ^PKCS7_SIGN_ENVELOPE; + PPPKCS7_SIGN_ENVELOPE = ^PPKCS7_SIGN_ENVELOPE; + + pkcs7_digest_st = record + version: PASN1_INTEGER; + md: PX509_ALGOR; + contents: Ppkcs7_st; + digest: PASN1_OCTET_STRING; + end; + + PKCS7_DIGEST = pkcs7_digest_st; + PPKCS7_DIGEST = ^PKCS7_DIGEST; + PPPKCS7_DIGEST = ^PPKCS7_DIGEST; + + pkcs7_encrypted_st = record + version: PASN1_INTEGER; + enc_data: PPKCS7_ENC_CONTENT; + end; + + _PKCS7_ENCRYPT = pkcs7_encrypted_st; + PPKCS7_ENCRYPT = ^_PKCS7_ENCRYPT; + PPPKCS7_ENCRYPT = ^PPKCS7_ENCRYPT; + + _anonymous_type_4 = record + case Integer of + 0: (ptr: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}); + 1: (data: PASN1_OCTET_STRING); + 2: (sign: PPKCS7_SIGNED); + 3: (enveloped: PPKCS7_ENVELOPE); + 4: (signed_and_enveloped: PPKCS7_SIGN_ENVELOPE); + 5: (digest: PPKCS7_DIGEST); + 6: (encrypted: PPKCS7_ENCRYPT); + 7: (other: PASN1_TYPE); + end; + P_anonymous_type_4 = ^_anonymous_type_4; + + pkcs7_st = record + asn1: PByte; + length: Integer; + state: Integer; + detached: Integer; + {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PASN1_OBJECT; + d: _anonymous_type_4; + end; + + PKCS7 = pkcs7_st; + PPKCS7 = ^PKCS7; + PPPKCS7 = ^PPKCS7; + + sk_PKCS7_compfunc = function(a: PPPKCS7; b: PPPKCS7): Integer; cdecl; + + sk_PKCS7_freefunc = procedure(a: PPKCS7); cdecl; + + sk_PKCS7_copyfunc = function(a: PPKCS7): Ppkcs7_st; cdecl; + + CONF_VALUE = record + section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + value: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + end; + + sk_CONF_VALUE_compfunc = function(a: PPCONF_VALUE; b: PPCONF_VALUE): Integer; cdecl; + + sk_CONF_VALUE_freefunc = procedure(a: PCONF_VALUE); cdecl; + + sk_CONF_VALUE_copyfunc = function(a: PCONF_VALUE): PCONF_VALUE; cdecl; + + lh_CONF_VALUE_dummy = record + case Integer of + 0: (d1: Pointer); + 1: (d2: Cardinal); + 2: (d3: Integer); + end; + + lhash_st_CONF_VALUE = record + dummy: lh_CONF_VALUE_dummy; + end; + + conf_method_st = record + name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + create: function(meth: Pointer{PCONF_METHOD}): Pconf_st; cdecl; + init: function(conf: PCONF): Integer; cdecl; + destroy: function(conf: PCONF): Integer; cdecl; + destroy_data: function(conf: PCONF): Integer; cdecl; + load_bio: function(conf: PCONF; bp: PBIO; eline: PInteger): Integer; cdecl; + dump: function(conf: PCONF; bp: PBIO): Integer; cdecl; + is_number: function(conf: PCONF; c: {$IFNDEF FPC}{$IF CompilerVersion > 21}UTF8Char{$ELSE}WideChar{$IFEND}{$ELSE}UTF8Char{$ENDIF}): Integer; cdecl; + to_int: function(conf: PCONF; c: {$IFNDEF FPC}{$IF CompilerVersion > 21}UTF8Char{$ELSE}WideChar{$IFEND}{$ELSE}UTF8Char{$ENDIF}): Integer; cdecl; + load: function(conf: PCONF; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; eline: PInteger): Integer; cdecl; + end; + CONF_METHOD = conf_method_st; + PCONF_METHOD = ^CONF_METHOD; + + PCONF_IMODULE = Pointer; + PPCONF_IMODULE = ^PCONF_IMODULE; + PCONF_MODULE = Pointer; + PPCONF_MODULE = ^PCONF_MODULE; + + sk_CONF_MODULE_compfunc = function(a: PPCONF_MODULE; b: PPCONF_MODULE): Integer; cdecl; + + sk_CONF_MODULE_freefunc = procedure(a: PCONF_MODULE); cdecl; + + sk_CONF_MODULE_copyfunc = function(a: PCONF_MODULE): Pconf_module_st; cdecl; + + sk_CONF_IMODULE_compfunc = function(a: PPCONF_IMODULE; b: PPCONF_IMODULE): Integer; cdecl; + + sk_CONF_IMODULE_freefunc = procedure(a: PCONF_IMODULE); cdecl; + + sk_CONF_IMODULE_copyfunc = function(a: PCONF_IMODULE): Pconf_imodule_st; cdecl; + + Pconf_init_func = function(md: PCONF_IMODULE; cnf: PCONF): Integer; cdecl; + + Pconf_finish_func = procedure(md: PCONF_IMODULE); cdecl; + + conf_st = record + meth: PCONF_METHOD; + meth_data: Pointer; + data: Plhash_st_CONF_VALUE; + end; + CONF = conf_st; + + X509V3_EXT_NEW = function(): Pointer; cdecl; + + X509V3_EXT_FREE = procedure(p1: Pointer); cdecl; + + _X509V3_EXT_D2I = function(p1: Pointer; p2: PPByte; p3: Integer): Pointer; cdecl; + + _X509V3_EXT_I2D = function(p1: Pointer; p2: PPByte): Integer; cdecl; + + X509V3_EXT_I2V = function(method: Pv3_ext_method; ext: Pointer; extlist: Pstack_st_CONF_VALUE): Pstack_st_CONF_VALUE; cdecl; + + X509V3_EXT_V2I = function(method: Pv3_ext_method; ctx: Pv3_ext_ctx; values: Pstack_st_CONF_VALUE): Pointer; cdecl; + + X509V3_EXT_I2S = function(method: Pv3_ext_method; ext: Pointer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + + X509V3_EXT_S2I = function(method: Pv3_ext_method; ctx: Pv3_ext_ctx; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Pointer; cdecl; + + X509V3_EXT_I2R = function(method: Pv3_ext_method; ext: Pointer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; indent: Integer): Integer; cdecl; + + X509V3_EXT_R2I = function(method: Pv3_ext_method; ctx: Pv3_ext_ctx; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Pointer; cdecl; + + v3_ext_method = record + ext_nid: Integer; + ext_flags: Integer; + it: PASN1_ITEM_EXP; + ext_new: X509V3_EXT_NEW; + ext_free: X509V3_EXT_FREE; + d2i: _X509V3_EXT_D2I; + i2d: _X509V3_EXT_I2D; + i2s: X509V3_EXT_I2S; + s2i: X509V3_EXT_S2I; + i2v: X509V3_EXT_I2V; + v2i: X509V3_EXT_V2I; + i2r: X509V3_EXT_I2R; + r2i: X509V3_EXT_R2I; + usr_data: Pointer; + end; + + X509V3_CONF_METHOD_st = record + get_string: function(db: Pointer; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; value: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + get_section: function(db: Pointer; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Pstack_st_CONF_VALUE; cdecl; + free_string: procedure(db: Pointer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&string{$ELSE}string1{$IFEND}{$ELSE}&string{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}); cdecl; + free_section: procedure(db: Pointer; section: Pstack_st_CONF_VALUE); cdecl; + end; + + X509V3_CONF_METHOD = X509V3_CONF_METHOD_st; + PX509V3_CONF_METHOD = ^X509V3_CONF_METHOD; + + v3_ext_ctx = record + flags: Integer; + issuer_cert: PX509; + subject_cert: PX509; + subject_req: PX509_REQ; + crl: PX509_CRL; + db_meth: PX509V3_CONF_METHOD; + db: Pointer; + end; + X509V3_CTX = v3_ext_ctx; + + X509V3_EXT_METHOD = v3_ext_method; + PX509V3_EXT_METHOD = ^X509V3_EXT_METHOD; + PPX509V3_EXT_METHOD = ^PX509V3_EXT_METHOD; + + sk_X509V3_EXT_METHOD_compfunc = function(a: PPX509V3_EXT_METHOD; b: PPX509V3_EXT_METHOD): Integer; cdecl; + + sk_X509V3_EXT_METHOD_freefunc = procedure(a: PX509V3_EXT_METHOD); cdecl; + + sk_X509V3_EXT_METHOD_copyfunc = function(a: PX509V3_EXT_METHOD): Pv3_ext_method; cdecl; + ENUMERATED_NAMES = BIT_STRING_BITNAME; + + BASIC_CONSTRAINTS_st = record + ca: Integer; + pathlen: PASN1_INTEGER; + end; + + BASIC_CONSTRAINTS = BASIC_CONSTRAINTS_st; + PBASIC_CONSTRAINTS = ^BASIC_CONSTRAINTS; + PPBASIC_CONSTRAINTS = ^PBASIC_CONSTRAINTS; + + PKEY_USAGE_PERIOD_st = record + notBefore: PASN1_GENERALIZEDTIME; + notAfter: PASN1_GENERALIZEDTIME; + end; + + PKEY_USAGE_PERIOD = PKEY_USAGE_PERIOD_st; + PPKEY_USAGE_PERIOD = ^PKEY_USAGE_PERIOD; + PPPKEY_USAGE_PERIOD = ^PPKEY_USAGE_PERIOD; + + otherName_st = record + type_id: PASN1_OBJECT; + value: PASN1_TYPE; + end; + + OTHERNAME = otherName_st; + POTHERNAME = ^OTHERNAME; + PPOTHERNAME = ^POTHERNAME; + + EDIPartyName_st = record + nameAssigner: PASN1_STRING; + partyName: PASN1_STRING; + end; + + EDIPARTYNAME = EDIPartyName_st; + PEDIPARTYNAME = ^EDIPARTYNAME; + PPEDIPARTYNAME = ^PEDIPARTYNAME; + + _anonymous_type_5 = record + case Integer of + 0: (ptr: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}); + 1: (otherName: POTHERNAME); + 2: (rfc822Name: PASN1_IA5STRING); + 3: (dNSName: PASN1_IA5STRING); + 4: (x400Address: PASN1_TYPE); + 5: (directoryName: PX509_NAME); + 6: (ediPartyName: PEDIPARTYNAME); + 7: (uniformResourceIdentifier: PASN1_IA5STRING); + 8: (iPAddress: PASN1_OCTET_STRING); + 9: (registeredID: PASN1_OBJECT); + 10: (ip: PASN1_OCTET_STRING); + 11: (dirn: PX509_NAME); + 12: (ia5: PASN1_IA5STRING); + 13: (rid: PASN1_OBJECT); + 14: (other: PASN1_TYPE); + end; + P_anonymous_type_5 = ^_anonymous_type_5; + + GENERAL_NAME_st = record + {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; + d: _anonymous_type_5; + end; + + GENERAL_NAME = GENERAL_NAME_st; + PGENERAL_NAME = ^GENERAL_NAME; + PPGENERAL_NAME = ^PGENERAL_NAME; + + ACCESS_DESCRIPTION_st = record + method: PASN1_OBJECT; + location: PGENERAL_NAME; + end; + + ACCESS_DESCRIPTION = ACCESS_DESCRIPTION_st; + PACCESS_DESCRIPTION = ^ACCESS_DESCRIPTION; + PPACCESS_DESCRIPTION = ^PACCESS_DESCRIPTION; + PAUTHORITY_INFO_ACCESS = Pointer; + PPAUTHORITY_INFO_ACCESS = ^PAUTHORITY_INFO_ACCESS; + PEXTENDED_KEY_USAGE = Pointer; + PPEXTENDED_KEY_USAGE = ^PEXTENDED_KEY_USAGE; + PTLS_FEATURE = Pointer; + PPTLS_FEATURE = ^PTLS_FEATURE; + + sk_GENERAL_NAME_compfunc = function(a: PPGENERAL_NAME; b: PPGENERAL_NAME): Integer; cdecl; + + sk_GENERAL_NAME_freefunc = procedure(a: PGENERAL_NAME); cdecl; + + sk_GENERAL_NAME_copyfunc = function(a: PGENERAL_NAME): PGENERAL_NAME_st; cdecl; + PGENERAL_NAMES = Pointer; + PPGENERAL_NAMES = ^PGENERAL_NAMES; + + sk_GENERAL_NAMES_compfunc = function(a: PPGENERAL_NAMES; b: PPGENERAL_NAMES): Integer; cdecl; + + sk_GENERAL_NAMES_freefunc = procedure(a: PGENERAL_NAMES); cdecl; + + sk_GENERAL_NAMES_copyfunc = function(a: PGENERAL_NAMES): Pstack_st_GENERAL_NAME; cdecl; + + sk_ACCESS_DESCRIPTION_compfunc = function(a: PPACCESS_DESCRIPTION; b: PPACCESS_DESCRIPTION): Integer; cdecl; + + sk_ACCESS_DESCRIPTION_freefunc = procedure(a: PACCESS_DESCRIPTION); cdecl; + + sk_ACCESS_DESCRIPTION_copyfunc = function(a: PACCESS_DESCRIPTION): PACCESS_DESCRIPTION_st; cdecl; + + _anonymous_type_6 = record + case Integer of + 0: (fullname: PGENERAL_NAMES); + 1: (relativename: Pstack_st_X509_NAME_ENTRY); + end; + P_anonymous_type_6 = ^_anonymous_type_6; + + DIST_POINT_NAME_st = record + {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; + name: _anonymous_type_6; + dpname: PX509_NAME; + end; + + DIST_POINT_NAME = DIST_POINT_NAME_st; + PDIST_POINT_NAME = ^DIST_POINT_NAME; + PPDIST_POINT_NAME = ^PDIST_POINT_NAME; + + DIST_POINT_st = record + distpoint: PDIST_POINT_NAME; + reasons: PASN1_BIT_STRING; + CRLissuer: PGENERAL_NAMES; + dp_reasons: Integer; + end; + DIST_POINT = DIST_POINT_st; + + PCRL_DIST_POINTS = Pointer; + PPCRL_DIST_POINTS = ^PCRL_DIST_POINTS; + + sk_DIST_POINT_compfunc = function(a: PPDIST_POINT; b: PPDIST_POINT): Integer; cdecl; + + sk_DIST_POINT_freefunc = procedure(a: PDIST_POINT); cdecl; + + sk_DIST_POINT_copyfunc = function(a: PDIST_POINT): PDIST_POINT_st; cdecl; + + AUTHORITY_KEYID_st = record + keyid: PASN1_OCTET_STRING; + issuer: PGENERAL_NAMES; + serial: PASN1_INTEGER; + end; + AUTHORITY_KEYID = AUTHORITY_KEYID_st; + + SXNET_ID_st = record + zone: PASN1_INTEGER; + user: PASN1_OCTET_STRING; + end; + + SXNETID = SXNET_ID_st; + PSXNETID = ^SXNETID; + PPSXNETID = ^PSXNETID; + + sk_SXNETID_compfunc = function(a: PPSXNETID; b: PPSXNETID): Integer; cdecl; + + sk_SXNETID_freefunc = procedure(a: PSXNETID); cdecl; + + sk_SXNETID_copyfunc = function(a: PSXNETID): PSXNET_ID_st; cdecl; + + SXNET_st = record + version: PASN1_INTEGER; + ids: Pstack_st_SXNETID; + end; + + SXNET = SXNET_st; + PSXNET = ^SXNET; + PPSXNET = ^PSXNET; + + NOTICEREF_st = record + organization: PASN1_STRING; + noticenos: Pstack_st_ASN1_INTEGER; + end; + + NOTICEREF = NOTICEREF_st; + PNOTICEREF = ^NOTICEREF; + PPNOTICEREF = ^PNOTICEREF; + + USERNOTICE_st = record + noticeref: PNOTICEREF; + exptext: PASN1_STRING; + end; + + USERNOTICE = USERNOTICE_st; + PUSERNOTICE = ^USERNOTICE; + PPUSERNOTICE = ^PUSERNOTICE; + + _anonymous_type_7 = record + case Integer of + 0: (cpsuri: PASN1_IA5STRING); + 1: (usernotice: PUSERNOTICE); + 2: (other: PASN1_TYPE); + end; + P_anonymous_type_7 = ^_anonymous_type_7; + + POLICYQUALINFO_st = record + pqualid: PASN1_OBJECT; + d: _anonymous_type_7; + end; + + POLICYQUALINFO = POLICYQUALINFO_st; + PPOLICYQUALINFO = ^POLICYQUALINFO; + PPPOLICYQUALINFO = ^PPOLICYQUALINFO; + + sk_POLICYQUALINFO_compfunc = function(a: PPPOLICYQUALINFO; b: PPPOLICYQUALINFO): Integer; cdecl; + + sk_POLICYQUALINFO_freefunc = procedure(a: PPOLICYQUALINFO); cdecl; + + sk_POLICYQUALINFO_copyfunc = function(a: PPOLICYQUALINFO): PPOLICYQUALINFO_st; cdecl; + + POLICYINFO_st = record + policyid: PASN1_OBJECT; + qualifiers: Pstack_st_POLICYQUALINFO; + end; + + POLICYINFO = POLICYINFO_st; + PPOLICYINFO = ^POLICYINFO; + PPPOLICYINFO = ^PPOLICYINFO; + PCERTIFICATEPOLICIES = Pointer; + PPCERTIFICATEPOLICIES = ^PCERTIFICATEPOLICIES; + + sk_POLICYINFO_compfunc = function(a: PPPOLICYINFO; b: PPPOLICYINFO): Integer; cdecl; + + sk_POLICYINFO_freefunc = procedure(a: PPOLICYINFO); cdecl; + + sk_POLICYINFO_copyfunc = function(a: PPOLICYINFO): PPOLICYINFO_st; cdecl; + + POLICY_MAPPING_st = record + issuerDomainPolicy: PASN1_OBJECT; + subjectDomainPolicy: PASN1_OBJECT; + end; + + POLICY_MAPPING = POLICY_MAPPING_st; + PPOLICY_MAPPING = ^POLICY_MAPPING; + PPPOLICY_MAPPING = ^PPOLICY_MAPPING; + + sk_POLICY_MAPPING_compfunc = function(a: PPPOLICY_MAPPING; b: PPPOLICY_MAPPING): Integer; cdecl; + + sk_POLICY_MAPPING_freefunc = procedure(a: PPOLICY_MAPPING); cdecl; + + sk_POLICY_MAPPING_copyfunc = function(a: PPOLICY_MAPPING): PPOLICY_MAPPING_st; cdecl; + PPOLICY_MAPPINGS = Pointer; + PPPOLICY_MAPPINGS = ^PPOLICY_MAPPINGS; + + GENERAL_SUBTREE_st = record + base: PGENERAL_NAME; + minimum: PASN1_INTEGER; + maximum: PASN1_INTEGER; + end; + + GENERAL_SUBTREE = GENERAL_SUBTREE_st; + PGENERAL_SUBTREE = ^GENERAL_SUBTREE; + PPGENERAL_SUBTREE = ^PGENERAL_SUBTREE; + + sk_GENERAL_SUBTREE_compfunc = function(a: PPGENERAL_SUBTREE; b: PPGENERAL_SUBTREE): Integer; cdecl; + + sk_GENERAL_SUBTREE_freefunc = procedure(a: PGENERAL_SUBTREE); cdecl; + + sk_GENERAL_SUBTREE_copyfunc = function(a: PGENERAL_SUBTREE): PGENERAL_SUBTREE_st; cdecl; + + NAME_CONSTRAINTS_st = record + permittedSubtrees: Pstack_st_GENERAL_SUBTREE; + excludedSubtrees: Pstack_st_GENERAL_SUBTREE; + end; + NAME_CONSTRAINTS = NAME_CONSTRAINTS_st; + PNAME_CONSTRAINTS = ^NAME_CONSTRAINTS; + + POLICY_CONSTRAINTS_st = record + requireExplicitPolicy: PASN1_INTEGER; + inhibitPolicyMapping: PASN1_INTEGER; + end; + + POLICY_CONSTRAINTS = POLICY_CONSTRAINTS_st; + PPOLICY_CONSTRAINTS = ^POLICY_CONSTRAINTS; + + PROXY_POLICY_st = record + policyLanguage: PASN1_OBJECT; + policy: PASN1_OCTET_STRING; + end; + + PROXY_POLICY = PROXY_POLICY_st; + PPROXY_POLICY = ^PROXY_POLICY; + PPPROXY_POLICY = ^PPROXY_POLICY; + + PROXY_CERT_INFO_EXTENSION_st = record + pcPathLengthConstraint: PASN1_INTEGER; + proxyPolicy: PPROXY_POLICY; + end; + + PROXY_CERT_INFO_EXTENSION = PROXY_CERT_INFO_EXTENSION_st; + PPROXY_CERT_INFO_EXTENSION = ^PROXY_CERT_INFO_EXTENSION; + PPPROXY_CERT_INFO_EXTENSION = ^PPROXY_CERT_INFO_EXTENSION; + + ISSUING_DIST_POINT_st = record + distpoint: PDIST_POINT_NAME; + onlyuser: Integer; + onlyCA: Integer; + onlysomereasons: PASN1_BIT_STRING; + indirectCRL: Integer; + onlyattr: Integer; + end; + ISSUING_DIST_POINT = ISSUING_DIST_POINT_st; + + x509_purpose_st = record + purpose: Integer; + trust: Integer; + flags: Integer; + check_purpose: function(p1: Px509_purpose_st; p2: PX509; p3: Integer): Integer; cdecl; + name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + sname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + usr_data: Pointer; + end; + + X509_PURPOSE = x509_purpose_st; + PX509_PURPOSE = ^X509_PURPOSE; + PPX509_PURPOSE = ^PX509_PURPOSE; + + sk_X509_PURPOSE_compfunc = function(a: PPX509_PURPOSE; b: PPX509_PURPOSE): Integer; cdecl; + + sk_X509_PURPOSE_freefunc = procedure(a: PX509_PURPOSE); cdecl; + + sk_X509_PURPOSE_copyfunc = function(a: PX509_PURPOSE): Px509_purpose_st; cdecl; + + sk_X509_POLICY_NODE_compfunc = function(a: PPX509_POLICY_NODE; b: PPX509_POLICY_NODE): Integer; cdecl; + + sk_X509_POLICY_NODE_freefunc = procedure(a: PX509_POLICY_NODE); cdecl; + + sk_X509_POLICY_NODE_copyfunc = function(a: PX509_POLICY_NODE): PX509_POLICY_NODE_st; cdecl; + + ASRange_st = record + min: PASN1_INTEGER; + max: PASN1_INTEGER; + end; + + ASRange = ASRange_st; + PASRange = ^ASRange; + PPASRange = ^PASRange; + + _anonymous_type_8 = record + case Integer of + 0: (id: PASN1_INTEGER); + 1: (range: PASRange); + end; + P_anonymous_type_8 = ^_anonymous_type_8; + + ASIdOrRange_st = record + {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; + u: _anonymous_type_8; + end; + + ASIdOrRange = ASIdOrRange_st; + PASIdOrRange = ^ASIdOrRange; + PPASIdOrRange = ^PASIdOrRange; + PASIdOrRanges = Pointer; + PPASIdOrRanges = ^PASIdOrRanges; + + sk_ASIdOrRange_compfunc = function(a: PPASIdOrRange; b: PPASIdOrRange): Integer; cdecl; + + sk_ASIdOrRange_freefunc = procedure(a: PASIdOrRange); cdecl; + + sk_ASIdOrRange_copyfunc = function(a: PASIdOrRange): PASIdOrRange_st; cdecl; + + _anonymous_type_9 = record + case Integer of + 0: (inherit: PASN1_NULL); + 1: (asIdsOrRanges: PASIdOrRanges); + end; + P_anonymous_type_9 = ^_anonymous_type_9; + + ASIdentifierChoice_st = record + {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; + u: _anonymous_type_9; + end; + + ASIdentifierChoice = ASIdentifierChoice_st; + PASIdentifierChoice = ^ASIdentifierChoice; + PPASIdentifierChoice = ^PASIdentifierChoice; + + ASIdentifiers_st = record + asnum: PASIdentifierChoice; + rdi: PASIdentifierChoice; + end; + + ASIdentifiers = ASIdentifiers_st; + PASIdentifiers = ^ASIdentifiers; + PPASIdentifiers = ^PASIdentifiers; + + IPAddressRange_st = record + min: PASN1_BIT_STRING; + max: PASN1_BIT_STRING; + end; + + IPAddressRange = IPAddressRange_st; + PIPAddressRange = ^IPAddressRange; + PPIPAddressRange = ^PIPAddressRange; + + _anonymous_type_10 = record + case Integer of + 0: (addressPrefix: PASN1_BIT_STRING); + 1: (addressRange: PIPAddressRange); + end; + P_anonymous_type_10 = ^_anonymous_type_10; + + IPAddressOrRange_st = record + {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; + u: _anonymous_type_10; + end; + + IPAddressOrRange = IPAddressOrRange_st; + PIPAddressOrRange = ^IPAddressOrRange; + PPIPAddressOrRange = ^PIPAddressOrRange; + PIPAddressOrRanges = Pointer; + PPIPAddressOrRanges = ^PIPAddressOrRanges; + + sk_IPAddressOrRange_compfunc = function(a: PPIPAddressOrRange; b: PPIPAddressOrRange): Integer; cdecl; + + sk_IPAddressOrRange_freefunc = procedure(a: PIPAddressOrRange); cdecl; + + sk_IPAddressOrRange_copyfunc = function(a: PIPAddressOrRange): PIPAddressOrRange_st; cdecl; + + _anonymous_type_11 = record + case Integer of + 0: (inherit: PASN1_NULL); + 1: (addressesOrRanges: PIPAddressOrRanges); + end; + P_anonymous_type_11 = ^_anonymous_type_11; + + IPAddressChoice_st = record + {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; + u: _anonymous_type_11; + end; + + IPAddressChoice = IPAddressChoice_st; + PIPAddressChoice = ^IPAddressChoice; + PPIPAddressChoice = ^PIPAddressChoice; + + IPAddressFamily_st = record + addressFamily: PASN1_OCTET_STRING; + ipAddressChoice: PIPAddressChoice; + end; + + IPAddressFamily = IPAddressFamily_st; + PIPAddressFamily = ^IPAddressFamily; + PPIPAddressFamily = ^PIPAddressFamily; + PIPAddrBlocks = Pointer; + PPIPAddrBlocks = ^PIPAddrBlocks; + + sk_IPAddressFamily_compfunc = function(a: PPIPAddressFamily; b: PPIPAddressFamily): Integer; cdecl; + + sk_IPAddressFamily_freefunc = procedure(a: PIPAddressFamily); cdecl; + + sk_IPAddressFamily_copyfunc = function(a: PIPAddressFamily): PIPAddressFamily_st; cdecl; + + sk_ASN1_STRING_compfunc = function(a: PPASN1_STRING; b: PPASN1_STRING): Integer; cdecl; + + sk_ASN1_STRING_freefunc = procedure(a: PASN1_STRING); cdecl; + + sk_ASN1_STRING_copyfunc = function(a: PASN1_STRING): Pasn1_string_st; cdecl; + PNAMING_AUTHORITY = Pointer; + PPNAMING_AUTHORITY = ^PNAMING_AUTHORITY; + PPROFESSION_INFO = Pointer; + PPPROFESSION_INFO = ^PPROFESSION_INFO; + PADMISSIONS = Pointer; + PPADMISSIONS = ^PADMISSIONS; + PADMISSION_SYNTAX = Pointer; + PPADMISSION_SYNTAX = ^PADMISSION_SYNTAX; + + sk_ADMISSIONS_compfunc = function(a: PPADMISSIONS; b: PPADMISSIONS): Integer; cdecl; + + sk_ADMISSIONS_freefunc = procedure(a: PADMISSIONS); cdecl; + + sk_ADMISSIONS_copyfunc = function(a: PADMISSIONS): PAdmissions_st; cdecl; + + sk_PROFESSION_INFO_compfunc = function(a: PPPROFESSION_INFO; b: PPPROFESSION_INFO): Integer; cdecl; + + sk_PROFESSION_INFO_freefunc = procedure(a: PPROFESSION_INFO); cdecl; + + sk_PROFESSION_INFO_copyfunc = function(a: PPROFESSION_INFO): PProfessionInfo_st; cdecl; + PPROFESSION_INFOS = Pointer; + PPPROFESSION_INFOS = ^PPROFESSION_INFOS; + PCMS_ContentInfo = Pointer; + PPCMS_ContentInfo = ^PCMS_ContentInfo; + PCMS_SignerInfo = Pointer; + PPCMS_SignerInfo = ^PCMS_SignerInfo; + PCMS_CertificateChoices = Pointer; + PPCMS_CertificateChoices = ^PCMS_CertificateChoices; + PCMS_RevocationInfoChoice = Pointer; + PPCMS_RevocationInfoChoice = ^PCMS_RevocationInfoChoice; + PCMS_RecipientInfo = Pointer; + PPCMS_RecipientInfo = ^PCMS_RecipientInfo; + PCMS_ReceiptRequest = Pointer; + PPCMS_ReceiptRequest = ^PCMS_ReceiptRequest; + PCMS_Receipt = Pointer; + PPCMS_Receipt = ^PCMS_Receipt; + PCMS_RecipientEncryptedKey = Pointer; + PPCMS_RecipientEncryptedKey = ^PCMS_RecipientEncryptedKey; + PCMS_OtherKeyAttribute = Pointer; + PPCMS_OtherKeyAttribute = ^PCMS_OtherKeyAttribute; + + sk_CMS_SignerInfo_compfunc = function(a: PPCMS_SignerInfo; b: PPCMS_SignerInfo): Integer; cdecl; + + sk_CMS_SignerInfo_freefunc = procedure(a: PCMS_SignerInfo); cdecl; + + sk_CMS_SignerInfo_copyfunc = function(a: PCMS_SignerInfo): PCMS_SignerInfo_st; cdecl; + + sk_CMS_RecipientEncryptedKey_compfunc = function(a: PPCMS_RecipientEncryptedKey; b: PPCMS_RecipientEncryptedKey): Integer; cdecl; + + sk_CMS_RecipientEncryptedKey_freefunc = procedure(a: PCMS_RecipientEncryptedKey); cdecl; + + sk_CMS_RecipientEncryptedKey_copyfunc = function(a: PCMS_RecipientEncryptedKey): PCMS_RecipientEncryptedKey_st; cdecl; + + sk_CMS_RecipientInfo_compfunc = function(a: PPCMS_RecipientInfo; b: PPCMS_RecipientInfo): Integer; cdecl; + + sk_CMS_RecipientInfo_freefunc = procedure(a: PCMS_RecipientInfo); cdecl; + + sk_CMS_RecipientInfo_copyfunc = function(a: PCMS_RecipientInfo): PCMS_RecipientInfo_st; cdecl; + + sk_CMS_RevocationInfoChoice_compfunc = function(a: PPCMS_RevocationInfoChoice; b: PPCMS_RevocationInfoChoice): Integer; cdecl; + + sk_CMS_RevocationInfoChoice_freefunc = procedure(a: PCMS_RevocationInfoChoice); cdecl; + + sk_CMS_RevocationInfoChoice_copyfunc = function(a: PCMS_RevocationInfoChoice): PCMS_RevocationInfoChoice_st; cdecl; + + ct_log_entry_type_t = ( + CT_LOG_ENTRY_TYPE_NOT_SET = -1, + CT_LOG_ENTRY_TYPE_X509 = 0, + CT_LOG_ENTRY_TYPE_PRECERT = 1); + Pct_log_entry_type_t = ^ct_log_entry_type_t; + + sct_version_t = ( + SCT_VERSION_NOT_SET = -1, + SCT_VERSION_V1 = 0); + Psct_version_t = ^sct_version_t; + + sct_source_t = ( + SCT_SOURCE_UNKNOWN = 0, + SCT_SOURCE_TLS_EXTENSION = 1, + SCT_SOURCE_X509V3_EXTENSION = 2, + SCT_SOURCE_OCSP_STAPLED_RESPONSE = 3); + Psct_source_t = ^sct_source_t; + + sct_validation_status_t = ( + SCT_VALIDATION_STATUS_NOT_SET = 0, + SCT_VALIDATION_STATUS_UNKNOWN_LOG = 1, + SCT_VALIDATION_STATUS_VALID = 2, + SCT_VALIDATION_STATUS_INVALID = 3, + SCT_VALIDATION_STATUS_UNVERIFIED = 4, + SCT_VALIDATION_STATUS_UNKNOWN_VERSION = 5); + Psct_validation_status_t = ^sct_validation_status_t; + + sk_SCT_compfunc = function(a: PPSCT; b: PPSCT): Integer; cdecl; + + sk_SCT_freefunc = procedure(a: PSCT); cdecl; + + sk_SCT_copyfunc = function(a: PSCT): Psct_st; cdecl; + + sk_CTLOG_compfunc = function(a: PPCTLOG; b: PPCTLOG): Integer; cdecl; + + sk_CTLOG_freefunc = procedure(a: PCTLOG); cdecl; + + sk_CTLOG_copyfunc = function(a: PCTLOG): Pctlog_st; cdecl; + DES_LONG = Cardinal; + PDES_LONG = ^DES_LONG; + DES_cblock = array [0..7] of Byte; + PDES_cblock = ^DES_cblock; + const_DES_cblock = array [0..7] of Byte; + Pconst_DES_cblock = ^const_DES_cblock; + + _anonymous_type_12 = record + case Integer of + 0: (cblock: DES_cblock); + 1: (deslong: array [0..1] of DES_LONG); + end; + P_anonymous_type_12 = ^_anonymous_type_12; + + DES_ks = record + ks: array [0..15] of _anonymous_type_12; + end; + + DES_key_schedule = DES_ks; + PDES_key_schedule = ^DES_key_schedule; + + rand_meth_st = record + seed: function(buf: Pointer; num: Integer): Integer; cdecl; + bytes: function(buf: PByte; num: Integer): Integer; cdecl; + cleanup: procedure(); cdecl; + add: function(buf: Pointer; num: Integer; randomness: Double): Integer; cdecl; + pseudorand: function(buf: PByte; num: Integer): Integer; cdecl; + status: function(): Integer; cdecl; + end; + + RAND_METHOD = rand_meth_st; + PRAND_METHOD = ^RAND_METHOD; + PRAND_DRBG = Pointer; + PPRAND_DRBG = ^PRAND_DRBG; + + Ppem_password_cb = function(buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; size: Integer; rwflag: Integer; userdata: Pointer): Integer; cdecl; + PUI_STRING = Pointer; + PPUI_STRING = ^PUI_STRING; + + sk_UI_STRING_compfunc = function(a: PPUI_STRING; b: PPUI_STRING): Integer; cdecl; + + sk_UI_STRING_freefunc = procedure(a: PUI_STRING); cdecl; + + sk_UI_STRING_copyfunc = function(a: PUI_STRING): Pui_string_st; cdecl; + + UI_string_types = ( + UIT_NONE = 0, + UIT_PROMPT = 1, + UIT_VERIFY = 2, + UIT_BOOLEAN = 3, + UIT_INFO = 4, + UIT_ERROR = 5); + PUI_string_types = ^UI_string_types; + + err_state_st = record + err_flags: array [0..15] of Integer; + err_buffer: array [0..15] of Cardinal; + err_data: array [0..15] of {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + err_data_flags: array [0..15] of Integer; + err_file: array [0..15] of {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + err_line: array [0..15] of Integer; + top: Integer; + bottom: Integer; + end; + + ERR_STATE = err_state_st; + PERR_STATE = ^ERR_STATE; + + ERR_string_data_st = record + error: Cardinal; + {$IFNDEF FPC}{$IF CompilerVersion > 21}&string{$ELSE}string1{$IFEND}{$ELSE}&string{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + end; + + ERR_STRING_DATA = ERR_string_data_st; + PERR_STRING_DATA = ^ERR_STRING_DATA; + + lh_ERR_STRING_DATA_dummy = record + case Integer of + 0: (d1: Pointer); + 1: (d2: Cardinal); + 2: (d3: Integer); + end; + + lhash_st_ERR_STRING_DATA = record + dummy: lh_ERR_STRING_DATA_dummy; + end; + + ENGINE_CMD_DEFN_st = record + cmd_num: Cardinal; + cmd_name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + cmd_desc: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + cmd_flags: Cardinal; + end; + + ENGINE_CMD_DEFN = ENGINE_CMD_DEFN_st; + PENGINE_CMD_DEFN = ^ENGINE_CMD_DEFN; + + ENGINE_GEN_FUNC_PTR = function(): Integer; cdecl; + + ENGINE_GEN_INT_FUNC_PTR = function(p1: PENGINE): Integer; cdecl; + + ENGINE_CTRL_FUNC_PTR_f = Pointer; + + ENGINE_CTRL_FUNC_PTR = function(p1: PENGINE; p2: Integer; p3: Integer; p4: Pointer; f: ENGINE_CTRL_FUNC_PTR_f): Integer; cdecl; + + ENGINE_LOAD_KEY_PTR = function(p1: PENGINE; p2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ui_method: PUI_METHOD; callback_data: Pointer): Pevp_pkey_st; cdecl; + + ENGINE_SSL_CLIENT_CERT_PTR = function(p1: PENGINE; ssl: PSSL; ca_dn: Pstack_st_X509_NAME; pcert: PPX509; pkey: PPEVP_PKEY; pother: PPstack_st_X509; ui_method: PUI_METHOD; callback_data: Pointer): Integer; cdecl; + + ENGINE_CIPHERS_PTR = function(p1: PENGINE; p2: PPEVP_CIPHER; p3: PPInteger; p4: Integer): Integer; cdecl; + + ENGINE_DIGESTS_PTR = function(p1: PENGINE; p2: PPEVP_MD; p3: PPInteger; p4: Integer): Integer; cdecl; + + ENGINE_PKEY_METHS_PTR = function(p1: PENGINE; p2: PPEVP_PKEY_METHOD; p3: PPInteger; p4: Integer): Integer; cdecl; + + ENGINE_PKEY_ASN1_METHS_PTR = function(p1: PENGINE; p2: PPEVP_PKEY_ASN1_METHOD; p3: PPInteger; p4: Integer): Integer; cdecl; + + dyn_MEM_malloc_fn = function(p1: NativeUInt; p2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; p3: Integer): Pointer; cdecl; + + dyn_MEM_realloc_fn = function(p1: Pointer; p2: NativeUInt; p3: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; p4: Integer): Pointer; cdecl; + + dyn_MEM_free_fn = procedure(p1: Pointer; p2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; p3: Integer); cdecl; + + st_dynamic_MEM_fns = record + malloc_fn: dyn_MEM_malloc_fn; + realloc_fn: dyn_MEM_realloc_fn; + free_fn: dyn_MEM_free_fn; + end; + + dynamic_MEM_fns = st_dynamic_MEM_fns; + + st_dynamic_fns = record + static_state: Pointer; + mem_fns: dynamic_MEM_fns; + end; + + dynamic_fns = st_dynamic_fns; + Pdynamic_fns = ^dynamic_fns; + + dynamic_v_check_fn = function(ossl_version: Cardinal): Cardinal; cdecl; + + dynamic_bind_engine = function(e: PENGINE; id: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; fns: Pdynamic_fns): Integer; cdecl; + IDEA_INT = Cardinal; + + idea_key_st = record + data: array [0..8] of array [0..5] of IDEA_INT; + end; + + IDEA_KEY_SCHEDULE = idea_key_st; + PIDEA_KEY_SCHEDULE = ^IDEA_KEY_SCHEDULE; + + MD4state_st = record + A: Cardinal; + B: Cardinal; + C: Cardinal; + D: Cardinal; + Nl: Cardinal; + Nh: Cardinal; + data: array [0..15] of Cardinal; + num: Cardinal; + end; + + MD4_CTX = MD4state_st; + PMD4_CTX = ^MD4_CTX; + + MD5state_st = record + A: Cardinal; + B: Cardinal; + C: Cardinal; + D: Cardinal; + Nl: Cardinal; + Nh: Cardinal; + data: array [0..15] of Cardinal; + num: Cardinal; + end; + + MD5_CTX = MD5state_st; + PMD5_CTX = ^MD5_CTX; + + mdc2_ctx_st = record + num: Cardinal; + data: array [0..7] of Byte; + h: DES_cblock; + hh: DES_cblock; + pad_type: Integer; + end; + + MDC2_CTX = mdc2_ctx_st; + PMDC2_CTX = ^MDC2_CTX; + + block128_f = procedure({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; key: Pointer); cdecl; + + cbc128_f = procedure({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; key: Pointer; ivec: PByte; enc: Integer); cdecl; + + ctr128_f = procedure({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; blocks: NativeUInt; key: Pointer; ivec: PByte); cdecl; + + ccm128_f = procedure({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; blocks: NativeUInt; key: Pointer; ivec: PByte; cmac: PByte); cdecl; + PGCM128_CONTEXT = Pointer; + PPGCM128_CONTEXT = ^PGCM128_CONTEXT; + PCCM128_CONTEXT = Pointer; + PPCCM128_CONTEXT = ^PCCM128_CONTEXT; + PXTS128_CONTEXT = Pointer; + PPXTS128_CONTEXT = ^PXTS128_CONTEXT; + POCB128_CONTEXT = Pointer; + PPOCB128_CONTEXT = ^POCB128_CONTEXT; + + PArray = Pointer; + ocb128_f = procedure({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; blocks: NativeUInt; key: Pointer; start_block_num: NativeUInt; offset_i: PByte; L_: PArray {Parray [0..15] of Byte}; checksum: PByte); cdecl; + POCSP_CERTID = Pointer; + PPOCSP_CERTID = ^POCSP_CERTID; + + sk_OCSP_CERTID_compfunc = function(a: PPOCSP_CERTID; b: PPOCSP_CERTID): Integer; cdecl; + + sk_OCSP_CERTID_freefunc = procedure(a: POCSP_CERTID); cdecl; + + sk_OCSP_CERTID_copyfunc = function(a: POCSP_CERTID): Pocsp_cert_id_st; cdecl; + POCSP_ONEREQ = Pointer; + PPOCSP_ONEREQ = ^POCSP_ONEREQ; + + sk_OCSP_ONEREQ_compfunc = function(a: PPOCSP_ONEREQ; b: PPOCSP_ONEREQ): Integer; cdecl; + + sk_OCSP_ONEREQ_freefunc = procedure(a: POCSP_ONEREQ); cdecl; + + sk_OCSP_ONEREQ_copyfunc = function(a: POCSP_ONEREQ): Pocsp_one_request_st; cdecl; + POCSP_REQINFO = Pointer; + PPOCSP_REQINFO = ^POCSP_REQINFO; + POCSP_SIGNATURE = Pointer; + PPOCSP_SIGNATURE = ^POCSP_SIGNATURE; + POCSP_REQUEST = Pointer; + PPOCSP_REQUEST = ^POCSP_REQUEST; + POCSP_RESPBYTES = Pointer; + PPOCSP_RESPBYTES = ^POCSP_RESPBYTES; + + sk_OCSP_RESPID_compfunc = function(a: PPOCSP_RESPID; b: PPOCSP_RESPID): Integer; cdecl; + + sk_OCSP_RESPID_freefunc = procedure(a: POCSP_RESPID); cdecl; + + sk_OCSP_RESPID_copyfunc = function(a: POCSP_RESPID): Pocsp_responder_id_st; cdecl; + POCSP_REVOKEDINFO = Pointer; + PPOCSP_REVOKEDINFO = ^POCSP_REVOKEDINFO; + POCSP_CERTSTATUS = Pointer; + PPOCSP_CERTSTATUS = ^POCSP_CERTSTATUS; + POCSP_SINGLERESP = Pointer; + PPOCSP_SINGLERESP = ^POCSP_SINGLERESP; + + sk_OCSP_SINGLERESP_compfunc = function(a: PPOCSP_SINGLERESP; b: PPOCSP_SINGLERESP): Integer; cdecl; + + sk_OCSP_SINGLERESP_freefunc = procedure(a: POCSP_SINGLERESP); cdecl; + + sk_OCSP_SINGLERESP_copyfunc = function(a: POCSP_SINGLERESP): Pocsp_single_response_st; cdecl; + POCSP_RESPDATA = Pointer; + PPOCSP_RESPDATA = ^POCSP_RESPDATA; + POCSP_BASICRESP = Pointer; + PPOCSP_BASICRESP = ^POCSP_BASICRESP; + POCSP_CRLID = Pointer; + PPOCSP_CRLID = ^POCSP_CRLID; + POCSP_SERVICELOC = Pointer; + PPOCSP_SERVICELOC = ^POCSP_SERVICELOC; + PPKCS12_MAC_DATA = Pointer; + PPPKCS12_MAC_DATA = ^PPKCS12_MAC_DATA; + PPKCS12 = Pointer; + PPPKCS12 = ^PPKCS12; + PPKCS12_SAFEBAG = Pointer; + PPPKCS12_SAFEBAG = ^PPKCS12_SAFEBAG; + + sk_PKCS12_SAFEBAG_compfunc = function(a: PPPKCS12_SAFEBAG; b: PPPKCS12_SAFEBAG): Integer; cdecl; + + sk_PKCS12_SAFEBAG_freefunc = procedure(a: PPKCS12_SAFEBAG); cdecl; + + sk_PKCS12_SAFEBAG_copyfunc = function(a: PPKCS12_SAFEBAG): PPKCS12_SAFEBAG_st; cdecl; + PPKCS12_BAGS = Pointer; + PPPKCS12_BAGS = ^PPKCS12_BAGS; + + RAND_DRBG_get_entropy_fn = function(drbg: PRAND_DRBG; pout: PPByte; entropy: Integer; min_len: NativeUInt; max_len: NativeUInt; prediction_resistance: Integer): UInt64; cdecl; + + RAND_DRBG_cleanup_entropy_fn = procedure(ctx: PRAND_DRBG; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outlen: NativeUInt); cdecl; + + RAND_DRBG_get_nonce_fn = function(drbg: PRAND_DRBG; pout: PPByte; entropy: Integer; min_len: NativeUInt; max_len: NativeUInt): UInt64; cdecl; + + RAND_DRBG_cleanup_nonce_fn = procedure(drbg: PRAND_DRBG; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outlen: NativeUInt); cdecl; + RC2_INT = Cardinal; + + rc2_key_st = record + data: array [0..63] of RC2_INT; + end; + + RC2_KEY = rc2_key_st; + PRC2_KEY = ^RC2_KEY; + + rc4_key_st = record + x: Cardinal; + y: Cardinal; + data: array [0..255] of Cardinal; + end; + + RC4_KEY = rc4_key_st; + PRC4_KEY = ^RC4_KEY; + + RIPEMD160state_st = record + A: Cardinal; + B: Cardinal; + C: Cardinal; + D: Cardinal; + E: Cardinal; + Nl: Cardinal; + Nh: Cardinal; + data: array [0..15] of Cardinal; + num: Cardinal; + end; + + RIPEMD160_CTX = RIPEMD160state_st; + PRIPEMD160_CTX = ^RIPEMD160_CTX; + + seed_key_st = record + data: array [0..31] of Cardinal; + end; + + SEED_KEY_SCHEDULE = seed_key_st; + PSEED_KEY_SCHEDULE = ^SEED_KEY_SCHEDULE; + + SRP_gN_cache_st = record + b64_bn: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + bn: PBIGNUM; + end; + + SRP_gN_cache = SRP_gN_cache_st; + PSRP_gN_cache = ^SRP_gN_cache; + PPSRP_gN_cache = ^PSRP_gN_cache; + + sk_SRP_gN_cache_compfunc = function(a: PPSRP_gN_cache; b: PPSRP_gN_cache): Integer; cdecl; + + sk_SRP_gN_cache_freefunc = procedure(a: PSRP_gN_cache); cdecl; + + sk_SRP_gN_cache_copyfunc = function(a: PSRP_gN_cache): PSRP_gN_cache_st; cdecl; + + SRP_user_pwd_st = record + id: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + s: PBIGNUM; + v: PBIGNUM; + g: PBIGNUM; + N: PBIGNUM; + info: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + end; + + SRP_user_pwd = SRP_user_pwd_st; + PSRP_user_pwd = ^SRP_user_pwd; + PPSRP_user_pwd = ^PSRP_user_pwd; + + sk_SRP_user_pwd_compfunc = function(a: PPSRP_user_pwd; b: PPSRP_user_pwd): Integer; cdecl; + + sk_SRP_user_pwd_freefunc = procedure(a: PSRP_user_pwd); cdecl; + + sk_SRP_user_pwd_copyfunc = function(a: PSRP_user_pwd): PSRP_user_pwd_st; cdecl; + + SRP_VBASE_st = record + users_pwd: Pstack_st_SRP_user_pwd; + gN_cache: Pstack_st_SRP_gN_cache; + seed_key: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + default_g: PBIGNUM; + default_N: PBIGNUM; + end; + + SRP_VBASE = SRP_VBASE_st; + PSRP_VBASE = ^SRP_VBASE; + + SRP_gN_st = record + id: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + g: PBIGNUM; + N: PBIGNUM; + end; + + SRP_gN = SRP_gN_st; + PSRP_gN = ^SRP_gN; + PPSRP_gN = ^PSRP_gN; + + sk_SRP_gN_compfunc = function(a: PPSRP_gN; b: PPSRP_gN): Integer; cdecl; + + sk_SRP_gN_freefunc = procedure(a: PSRP_gN); cdecl; + + sk_SRP_gN_copyfunc = function(a: PSRP_gN): PSRP_gN_st; cdecl; + ssl_crock_st = Pointer; + Pssl_crock_st = ^ssl_crock_st; + PSSL_METHOD = Pointer; + PPSSL_METHOD = ^PSSL_METHOD; + PSSL_CIPHER = Pointer; + PPSSL_CIPHER = ^PSSL_CIPHER; + PSSL_SESSION = Pointer; + PPSSL_SESSION = ^PSSL_SESSION; + PTLS_SIGALGS = Pointer; + PPTLS_SIGALGS = ^PTLS_SIGALGS; + PSSL_CONF_CTX = Pointer; + PPSSL_CONF_CTX = ^PSSL_CONF_CTX; + PSSL_COMP = Pointer; + PPSSL_COMP = ^PSSL_COMP; + + srtp_protection_profile_st = record + name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; + id: Cardinal; + end; + + SRTP_PROTECTION_PROFILE = srtp_protection_profile_st; + PSRTP_PROTECTION_PROFILE = ^SRTP_PROTECTION_PROFILE; + PPSRTP_PROTECTION_PROFILE = ^PSRTP_PROTECTION_PROFILE; + + sk_SRTP_PROTECTION_PROFILE_compfunc = function(a: PPSRTP_PROTECTION_PROFILE; b: PPSRTP_PROTECTION_PROFILE): Integer; cdecl; + + sk_SRTP_PROTECTION_PROFILE_freefunc = procedure(a: PSRTP_PROTECTION_PROFILE); cdecl; + + sk_SRTP_PROTECTION_PROFILE_copyfunc = function(a: PSRTP_PROTECTION_PROFILE): Psrtp_protection_profile_st; cdecl; + + tls_session_ticket_ext_cb_fn = function(s: PSSL; data: PByte; len: Integer; arg: Pointer): Integer; cdecl; + + tls_session_secret_cb_fn = function(s: PSSL; secret: Pointer; secret_len: PInteger; peer_ciphers: Pstack_st_SSL_CIPHER; cipher: PPSSL_CIPHER; arg: Pointer): Integer; cdecl; + + custom_ext_add_cb = function(s: PSSL; ext_type: Cardinal; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte; outlen: PNativeUInt; al: PInteger; add_arg: Pointer): Integer; cdecl; + + custom_ext_free_cb = procedure(s: PSSL; ext_type: Cardinal; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; add_arg: Pointer); cdecl; + + custom_ext_parse_cb = function(s: PSSL; ext_type: Cardinal; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inlen: NativeUInt; al: PInteger; parse_arg: Pointer): Integer; cdecl; + + SSL_custom_ext_add_cb_ex = function(s: PSSL; ext_type: Cardinal; context: Cardinal; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte; outlen: PNativeUInt; x: PX509; chainidx: NativeUInt; al: PInteger; add_arg: Pointer): Integer; cdecl; + + SSL_custom_ext_free_cb_ex = procedure(s: PSSL; ext_type: Cardinal; context: Cardinal; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; add_arg: Pointer); cdecl; + + SSL_custom_ext_parse_cb_ex = function(s: PSSL; ext_type: Cardinal; context: Cardinal; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inlen: NativeUInt; x: PX509; chainidx: NativeUInt; al: PInteger; parse_arg: Pointer): Integer; cdecl; + + SSL_verify_cb = function(preverify_ok: Integer; x509_ctx: PX509_STORE_CTX): Integer; cdecl; + + GEN_SESSION_CB = function(ssl: PSSL; id: PByte; id_len: PCardinal): Integer; cdecl; + + SSL_CTX_npn_advertised_cb_func = function(ssl: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte; outlen: PCardinal; arg: Pointer): Integer; cdecl; + + SSL_CTX_npn_select_cb_func = function(s: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte; outlen: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inlen: Cardinal; arg: Pointer): Integer; cdecl; + + SSL_CTX_alpn_select_cb_func = function(ssl: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte; outlen: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inlen: Cardinal; arg: Pointer): Integer; cdecl; + + SSL_psk_client_cb_func = function(ssl: PSSL; hint: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; identity: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; max_identity_len: Cardinal; psk: PByte; max_psk_len: Cardinal): Cardinal; cdecl; + + SSL_psk_server_cb_func = function(ssl: PSSL; identity: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; psk: PByte; max_psk_len: Cardinal): Cardinal; cdecl; + + SSL_psk_find_session_cb_func = function(ssl: PSSL; identity: PByte; identity_len: NativeUInt; sess: PPSSL_SESSION): Integer; cdecl; + + SSL_psk_use_session_cb_func = function(ssl: PSSL; md: PEVP_MD; id: PPByte; idlen: PNativeUInt; sess: PPSSL_SESSION): Integer; cdecl; + + SSL_CTX_keylog_cb_func = procedure(ssl: PSSL; line: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}); cdecl; + + tls_session_ticket_ext_st = record + length: Word; + data: Pointer; + end; + TLS_SESSION_TICKET_EXT = tls_session_ticket_ext_st; + + sk_SSL_CIPHER_compfunc = function(a: PPSSL_CIPHER; b: PPSSL_CIPHER): Integer; cdecl; + + sk_SSL_CIPHER_freefunc = procedure(a: PSSL_CIPHER); cdecl; + + sk_SSL_CIPHER_copyfunc = function(a: PSSL_CIPHER): Pssl_cipher_st; cdecl; + + sk_SSL_COMP_compfunc = function(a: PPSSL_COMP; b: PPSSL_COMP): Integer; cdecl; + + sk_SSL_COMP_freefunc = procedure(a: PSSL_COMP); cdecl; + + sk_SSL_COMP_copyfunc = function(a: PSSL_COMP): Pssl_comp_st; cdecl; + + OSSL_HANDSHAKE_STATE = ( + TLS_ST_BEFORE = 0, + TLS_ST_OK = 1, + DTLS_ST_CR_HELLO_VERIFY_REQUEST = 2, + TLS_ST_CR_SRVR_HELLO = 3, + TLS_ST_CR_CERT = 4, + TLS_ST_CR_CERT_STATUS = 5, + TLS_ST_CR_KEY_EXCH = 6, + TLS_ST_CR_CERT_REQ = 7, + TLS_ST_CR_SRVR_DONE = 8, + TLS_ST_CR_SESSION_TICKET = 9, + TLS_ST_CR_CHANGE = 10, + TLS_ST_CR_FINISHED = 11, + TLS_ST_CW_CLNT_HELLO = 12, + TLS_ST_CW_CERT = 13, + TLS_ST_CW_KEY_EXCH = 14, + TLS_ST_CW_CERT_VRFY = 15, + TLS_ST_CW_CHANGE = 16, + TLS_ST_CW_NEXT_PROTO = 17, + TLS_ST_CW_FINISHED = 18, + TLS_ST_SW_HELLO_REQ = 19, + TLS_ST_SR_CLNT_HELLO = 20, + DTLS_ST_SW_HELLO_VERIFY_REQUEST = 21, + TLS_ST_SW_SRVR_HELLO = 22, + TLS_ST_SW_CERT = 23, + TLS_ST_SW_KEY_EXCH = 24, + TLS_ST_SW_CERT_REQ = 25, + TLS_ST_SW_SRVR_DONE = 26, + TLS_ST_SR_CERT = 27, + TLS_ST_SR_KEY_EXCH = 28, + TLS_ST_SR_CERT_VRFY = 29, + TLS_ST_SR_NEXT_PROTO = 30, + TLS_ST_SR_CHANGE = 31, + TLS_ST_SR_FINISHED = 32, + TLS_ST_SW_SESSION_TICKET = 33, + TLS_ST_SW_CERT_STATUS = 34, + TLS_ST_SW_CHANGE = 35, + TLS_ST_SW_FINISHED = 36, + TLS_ST_SW_ENCRYPTED_EXTENSIONS = 37, + TLS_ST_CR_ENCRYPTED_EXTENSIONS = 38, + TLS_ST_CR_CERT_VRFY = 39, + TLS_ST_SW_CERT_VRFY = 40, + TLS_ST_CR_HELLO_REQ = 41, + TLS_ST_SW_KEY_UPDATE = 42, + TLS_ST_CW_KEY_UPDATE = 43, + TLS_ST_SR_KEY_UPDATE = 44, + TLS_ST_CR_KEY_UPDATE = 45, + TLS_ST_EARLY_DATA = 46, + TLS_ST_PENDING_EARLY_DATA_END = 47, + TLS_ST_CW_END_OF_EARLY_DATA = 48, + TLS_ST_SR_END_OF_EARLY_DATA = 49); + POSSL_HANDSHAKE_STATE = ^OSSL_HANDSHAKE_STATE; + + SSL_client_hello_cb_fn = function(s: PSSL; al: PInteger; arg: Pointer): Integer; cdecl; + + ssl_ct_validation_cb = function(ctx: PCT_POLICY_EVAL_CTX; scts: Pstack_st_SCT; arg: Pointer): Integer; cdecl; + + _anonymous_type_13 = ( + SSL_CT_VALIDATION_PERMISSIVE = 0, + SSL_CT_VALIDATION_STRICT = 1); + P_anonymous_type_13 = ^_anonymous_type_13; + SSL_TICKET_STATUS = Integer; + SSL_TICKET_RETURN = Integer; + + SSL_CTX_generate_session_ticket_fn = function(s: PSSL; arg: Pointer): Integer; cdecl; + + SSL_CTX_decrypt_session_ticket_fn = function(s: PSSL; ss: PSSL_SESSION; keyname: PByte; keyname_length: NativeUInt; status: SSL_TICKET_STATUS; arg: Pointer): Integer; cdecl; + + DTLS_timer_cb = function(s: PSSL; timer_us: Cardinal): Cardinal; cdecl; + + SSL_allow_early_data_cb_fn = function(s: PSSL; arg: Pointer): Integer; cdecl; + POSSL_STORE_CTX = Pointer; + PPOSSL_STORE_CTX = ^POSSL_STORE_CTX; + + OSSL_STORE_post_process_info_fn = function(p1: POSSL_STORE_INFO; p2: Pointer): Possl_store_info_st; cdecl; + POSSL_STORE_LOADER = Pointer; + PPOSSL_STORE_LOADER = ^POSSL_STORE_LOADER; + POSSL_STORE_LOADER_CTX = Pointer; + PPOSSL_STORE_LOADER_CTX = ^POSSL_STORE_LOADER_CTX; + + OSSL_STORE_open_fn = function(loader: POSSL_STORE_LOADER; uri: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ui_method: PUI_METHOD; ui_data: Pointer): Possl_store_loader_ctx_st; cdecl; + + OSSL_STORE_ctrl_fn = function(ctx: POSSL_STORE_LOADER_CTX; cmd: Integer; args: Pointer): Integer; cdecl; + + OSSL_STORE_expect_fn = function(ctx: POSSL_STORE_LOADER_CTX; expected: Integer): Integer; cdecl; + + OSSL_STORE_find_fn = function(ctx: POSSL_STORE_LOADER_CTX; criteria: POSSL_STORE_SEARCH): Integer; cdecl; + + OSSL_STORE_load_fn = function(ctx: POSSL_STORE_LOADER_CTX; ui_method: PUI_METHOD; ui_data: Pointer): Possl_store_info_st; cdecl; + + OSSL_STORE_eof_fn = function(ctx: POSSL_STORE_LOADER_CTX): Integer; cdecl; + + OSSL_STORE_error_fn = function(ctx: POSSL_STORE_LOADER_CTX): Integer; cdecl; + + OSSL_STORE_close_fn = function(ctx: POSSL_STORE_LOADER_CTX): Integer; cdecl; + PTS_MSG_IMPRINT = Pointer; + PPTS_MSG_IMPRINT = ^PTS_MSG_IMPRINT; + PTS_REQ = Pointer; + PPTS_REQ = ^PTS_REQ; + PTS_ACCURACY = Pointer; + PPTS_ACCURACY = ^PTS_ACCURACY; + PTS_TST_INFO = Pointer; + PPTS_TST_INFO = ^PTS_TST_INFO; + PTS_STATUS_INFO = Pointer; + PPTS_STATUS_INFO = ^PTS_STATUS_INFO; + PESS_ISSUER_SERIAL = Pointer; + PPESS_ISSUER_SERIAL = ^PESS_ISSUER_SERIAL; + PESS_CERT_ID = Pointer; + PPESS_CERT_ID = ^PESS_CERT_ID; + PESS_SIGNING_CERT = Pointer; + PPESS_SIGNING_CERT = ^PESS_SIGNING_CERT; + + sk_ESS_CERT_ID_compfunc = function(a: PPESS_CERT_ID; b: PPESS_CERT_ID): Integer; cdecl; + + sk_ESS_CERT_ID_freefunc = procedure(a: PESS_CERT_ID); cdecl; + + sk_ESS_CERT_ID_copyfunc = function(a: PESS_CERT_ID): PESS_cert_id; cdecl; + PESS_CERT_ID_V2 = Pointer; + PPESS_CERT_ID_V2 = ^PESS_CERT_ID_V2; + PESS_SIGNING_CERT_V2 = Pointer; + PPESS_SIGNING_CERT_V2 = ^PESS_SIGNING_CERT_V2; + + sk_ESS_CERT_ID_V2_compfunc = function(a: PPESS_CERT_ID_V2; b: PPESS_CERT_ID_V2): Integer; cdecl; + + sk_ESS_CERT_ID_V2_freefunc = procedure(a: PESS_CERT_ID_V2); cdecl; + + sk_ESS_CERT_ID_V2_copyfunc = function(a: PESS_CERT_ID_V2): PESS_cert_id_v2_st; cdecl; + PTS_RESP = Pointer; + PPTS_RESP = ^PTS_RESP; + + PTS_RESP_CTX = Pointer; + PPTS_RESP_CTX = ^PTS_RESP_CTX; + + TS_serial_cb = function(p1: PTS_resp_ctx; p2: Pointer): Pasn1_string_st; cdecl; + + TS_time_cb = function(p1: PTS_resp_ctx; p2: Pointer; sec: PInteger; usec: PInteger): Integer; cdecl; + + TS_extension_cb = function(p1: PTS_resp_ctx; p2: PX509_EXTENSION; p3: Pointer): Integer; cdecl; + + sk_EVP_MD_compfunc = function(a: PPEVP_MD; b: PPEVP_MD): Integer; cdecl; + + sk_EVP_MD_freefunc = procedure(a: PEVP_MD); cdecl; + + sk_EVP_MD_copyfunc = function(a: PEVP_MD): Pevp_md_st; cdecl; + PTS_VERIFY_CTX = Pointer; + PPTS_VERIFY_CTX = ^PTS_VERIFY_CTX; + OPENSSL_PSTRING = POPENSSL_STRING; + + sk_OPENSSL_PSTRING_compfunc = function(a: PPOPENSSL_STRING; b: PPOPENSSL_STRING): Integer; cdecl; + + sk_OPENSSL_PSTRING_freefunc = procedure(a: POPENSSL_STRING); cdecl; + + sk_OPENSSL_PSTRING_copyfunc = function(a: POPENSSL_STRING): {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; cdecl; + + txt_db_st = record + num_fields: Integer; + data: Pstack_st_OPENSSL_PSTRING; + index: PPlhash_st_OPENSSL_STRING; + qual: Integer { TODO : Cannot convert original type "int (**)(OPENSSL_STRING *)" }; + error: Integer; + arg1: Integer; + arg2: Integer; + arg_row: POPENSSL_STRING; + end; + + TXT_DB = txt_db_st; + PTXT_DB = ^TXT_DB; + + _anonymous_type_14 = record + case Integer of + 0: (c: array [0..63] of Byte); + 1: (q: array [0..7] of Double); + end; + P_anonymous_type_14 = ^_anonymous_type_14; + + WHIRLPOOL_CTX = record + H: _anonymous_type_14; + data: array [0..63] of Byte; + bitoff: Cardinal; + bitlen: array [0..3] of NativeUInt; + end; + +{ Crypto Library } + +function AES_options(): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'AES_options'; + +function AES_set_encrypt_key(userKey: PByte; bits: Integer; key: PAES_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'AES_set_encrypt_key'; + +function AES_set_decrypt_key(userKey: PByte; bits: Integer; key: PAES_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'AES_set_decrypt_key'; + +procedure AES_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; key: PAES_KEY); cdecl; + external LIB_CRYPTO name _PU + 'AES_encrypt'; + +procedure AES_decrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; key: PAES_KEY); cdecl; + external LIB_CRYPTO name _PU + 'AES_decrypt'; + +procedure AES_ecb_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; key: PAES_KEY; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'AES_ecb_encrypt'; + +procedure AES_cbc_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: NativeUInt; key: PAES_KEY; ivec: PByte; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'AES_cbc_encrypt'; + +procedure AES_cfb128_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: NativeUInt; key: PAES_KEY; ivec: PByte; num: PInteger; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'AES_cfb128_encrypt'; + +procedure AES_cfb1_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: NativeUInt; key: PAES_KEY; ivec: PByte; num: PInteger; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'AES_cfb1_encrypt'; + +procedure AES_cfb8_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: NativeUInt; key: PAES_KEY; ivec: PByte; num: PInteger; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'AES_cfb8_encrypt'; + +procedure AES_ofb128_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: NativeUInt; key: PAES_KEY; ivec: PByte; num: PInteger); cdecl; + external LIB_CRYPTO name _PU + 'AES_ofb128_encrypt'; + +procedure AES_ige_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: NativeUInt; key: PAES_KEY; ivec: PByte; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'AES_ige_encrypt'; + +procedure AES_bi_ige_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: NativeUInt; key: PAES_KEY; key2: PAES_KEY; ivec: PByte; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'AES_bi_ige_encrypt'; + +function AES_wrap_key(key: PAES_KEY; iv: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inlen: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'AES_wrap_key'; + +function AES_unwrap_key(key: PAES_KEY; iv: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inlen: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'AES_unwrap_key'; + +function OPENSSL_sk_num(p1: POPENSSL_STACK): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_num'; + +function OPENSSL_sk_value(p1: POPENSSL_STACK; p2: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_value'; + +function OPENSSL_sk_set(st: POPENSSL_STACK; i: Integer; data: Pointer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_set'; + +function OPENSSL_sk_new(cmp: OPENSSL_sk_compfunc): POPENSSL_STACK; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_new'; + +function OPENSSL_sk_new_null(): POPENSSL_STACK; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_new_null'; + +function OPENSSL_sk_new_reserve(c: OPENSSL_sk_compfunc; n: Integer): POPENSSL_STACK; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_new_reserve'; + +function OPENSSL_sk_reserve(st: POPENSSL_STACK; n: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_reserve'; + +procedure OPENSSL_sk_free(p1: POPENSSL_STACK); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_free'; + +type + OPENSSL_sk_pop_free_func = procedure(p1: Pointer); cdecl; + +procedure OPENSSL_sk_pop_free(st: POPENSSL_STACK; func: OPENSSL_sk_pop_free_func); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_pop_free'; + +function OPENSSL_sk_deep_copy(p1: POPENSSL_STACK; c: OPENSSL_sk_copyfunc; f: OPENSSL_sk_freefunc): POPENSSL_STACK; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_deep_copy'; + +function OPENSSL_sk_insert(sk: POPENSSL_STACK; data: Pointer; where: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_insert'; + +function OPENSSL_sk_delete(st: POPENSSL_STACK; loc: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_delete'; + +function OPENSSL_sk_delete_ptr(st: POPENSSL_STACK; p: Pointer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_delete_ptr'; + +function OPENSSL_sk_find(st: POPENSSL_STACK; data: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_find'; + +function OPENSSL_sk_find_ex(st: POPENSSL_STACK; data: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_find_ex'; + +function OPENSSL_sk_push(st: POPENSSL_STACK; data: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_push'; + +function OPENSSL_sk_unshift(st: POPENSSL_STACK; data: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_unshift'; + +function OPENSSL_sk_shift(st: POPENSSL_STACK): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_shift'; + +function OPENSSL_sk_pop(st: POPENSSL_STACK): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_pop'; + +procedure OPENSSL_sk_zero(st: POPENSSL_STACK); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_zero'; + +function OPENSSL_sk_set_cmp_func(sk: POPENSSL_STACK; cmp: OPENSSL_sk_compfunc): OPENSSL_sk_compfunc; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_set_cmp_func'; + +function OPENSSL_sk_dup(st: POPENSSL_STACK): POPENSSL_STACK; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_dup'; + +procedure OPENSSL_sk_sort(st: POPENSSL_STACK); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_sort'; + +function OPENSSL_sk_is_sorted(st: POPENSSL_STACK): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_sk_is_sorted'; + +function ERR_load_CRYPTO_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_CRYPTO_strings'; + +function CRYPTO_THREAD_lock_new(): PCRYPTO_RWLOCK; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_THREAD_lock_new'; + +function CRYPTO_THREAD_read_lock(lock: PCRYPTO_RWLOCK): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_THREAD_read_lock'; + +function CRYPTO_THREAD_write_lock(lock: PCRYPTO_RWLOCK): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_THREAD_write_lock'; + +function CRYPTO_THREAD_unlock(lock: PCRYPTO_RWLOCK): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_THREAD_unlock'; + +procedure CRYPTO_THREAD_lock_free(lock: PCRYPTO_RWLOCK); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_THREAD_lock_free'; + +function CRYPTO_atomic_add(val: PInteger; amount: Integer; ret: PInteger; lock: PCRYPTO_RWLOCK): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_atomic_add'; + +function CRYPTO_mem_ctrl(mode: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_mem_ctrl'; + +function OPENSSL_strlcpy(dst: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; src: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; siz: NativeUInt): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_strlcpy'; + +function OPENSSL_strlcat(dst: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; src: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; siz: NativeUInt): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_strlcat'; + +function OPENSSL_strnlen(str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; maxlen: NativeUInt): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_strnlen'; + +function OPENSSL_buf2hexstr(buffer: PByte; len: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_buf2hexstr'; + +function OPENSSL_hexstr2buf(str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: PInteger): PByte; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_hexstr2buf'; + +function OPENSSL_hexchar2int(c: Byte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_hexchar2int'; + +function OpenSSL_version_num(): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'OpenSSL_version_num'; +function SSLeay(): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'OpenSSL_version_num'; + +function OpenSSL_version({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'OpenSSL_version'; +function SSLeay_version({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'OpenSSL_version'; + +function OPENSSL_issetugid(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_issetugid'; + +function CRYPTO_get_ex_new_index(class_index: Integer; argl: Integer; argp: Pointer; new_func: PCRYPTO_EX_new; dup_func: PCRYPTO_EX_dup; free_func: PCRYPTO_EX_free): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_get_ex_new_index'; + +function CRYPTO_free_ex_index(class_index: Integer; idx: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_free_ex_index'; + +function CRYPTO_new_ex_data(class_index: Integer; obj: Pointer; ad: PCRYPTO_EX_DATA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_new_ex_data'; + +function CRYPTO_dup_ex_data(class_index: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PCRYPTO_EX_DATA; from: PCRYPTO_EX_DATA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_dup_ex_data'; + +procedure CRYPTO_free_ex_data(class_index: Integer; obj: Pointer; ad: PCRYPTO_EX_DATA); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_free_ex_data'; + +function CRYPTO_set_ex_data(ad: PCRYPTO_EX_DATA; idx: Integer; val: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_set_ex_data'; + +function CRYPTO_get_ex_data(ad: PCRYPTO_EX_DATA; idx: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_get_ex_data'; + +type + CRYPTO_set_mem_functions_m = function(p1: NativeUInt; p2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; p3: Integer): Pointer; cdecl; + +type + CRYPTO_set_mem_functions_r = function(p1: Pointer; p2: NativeUInt; p3: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; p4: Integer): Pointer; cdecl; + +type + CRYPTO_set_mem_functions_f = procedure(p1: Pointer; p2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; p3: Integer); cdecl; + +function CRYPTO_set_mem_functions(m: CRYPTO_set_mem_functions_m; r: CRYPTO_set_mem_functions_r; f: CRYPTO_set_mem_functions_f): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_set_mem_functions'; + +function CRYPTO_set_mem_debug(flag: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_set_mem_debug'; + +procedure CRYPTO_get_mem_functions(m: Integer { TODO : Cannot convert original type "void *(**)(size_t, const char *, int)" }; r: Integer { TODO : Cannot convert original type "void *(**)(void *, size_t, const char *, int)" }; f: Integer { TODO : Cannot convert original type "void (**)(void *, const char *, int)" }); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_get_mem_functions'; + +function CRYPTO_malloc(num: NativeUInt; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; line: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_malloc'; + +function CRYPTO_zalloc(num: NativeUInt; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; line: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_zalloc'; + +function CRYPTO_memdup(str: Pointer; siz: NativeUInt; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; line: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_memdup'; + +function CRYPTO_strdup(str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; line: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_strdup'; + +function CRYPTO_strndup(str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; s: NativeUInt; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; line: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_strndup'; + +procedure CRYPTO_free(ptr: Pointer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; line: Integer); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_free'; + +procedure CRYPTO_clear_free(ptr: Pointer; num: NativeUInt; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; line: Integer); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_clear_free'; + +function CRYPTO_realloc(addr: Pointer; num: NativeUInt; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; line: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_realloc'; + +function CRYPTO_clear_realloc(addr: Pointer; old_num: NativeUInt; num: NativeUInt; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; line: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_clear_realloc'; + +function CRYPTO_secure_malloc_init(sz: NativeUInt; minsize: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_secure_malloc_init'; + +function CRYPTO_secure_malloc_done(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_secure_malloc_done'; + +function CRYPTO_secure_malloc(num: NativeUInt; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; line: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_secure_malloc'; + +function CRYPTO_secure_zalloc(num: NativeUInt; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; line: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_secure_zalloc'; + +procedure CRYPTO_secure_free(ptr: Pointer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; line: Integer); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_secure_free'; + +procedure CRYPTO_secure_clear_free(ptr: Pointer; num: NativeUInt; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; line: Integer); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_secure_clear_free'; + +function CRYPTO_secure_allocated(ptr: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_secure_allocated'; + +function CRYPTO_secure_malloc_initialized(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_secure_malloc_initialized'; + +function CRYPTO_secure_actual_size(ptr: Pointer): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_secure_actual_size'; + +function CRYPTO_secure_used(): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_secure_used'; + +procedure OPENSSL_cleanse(ptr: Pointer; len: NativeUInt); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_cleanse'; + +procedure OPENSSL_die(assertion: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; line: Integer); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_die'; + +function OPENSSL_isservice(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_isservice'; + +function FIPS_mode(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'FIPS_mode'; + +function FIPS_mode_set(r: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'FIPS_mode_set'; + +procedure OPENSSL_init(); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_init'; + +type + Ptm = Pointer; + +function OPENSSL_gmtime(timer: PLongint; result: Ptm): Ptm; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_gmtime'; + +function OPENSSL_gmtime_adj(tm: Ptm; offset_day: Integer; offset_sec: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_gmtime_adj'; + +function OPENSSL_gmtime_diff(pday: PInteger; psec: PInteger; from: Ptm; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: Ptm): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_gmtime_diff'; + +function CRYPTO_memcmp(in_a: Pointer; in_b: Pointer; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_memcmp'; + +procedure OPENSSL_cleanup(); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_cleanup'; + +function OPENSSL_init_crypto(opts: UInt64; settings: POPENSSL_INIT_SETTINGS): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_init_crypto'; + +type + OPENSSL_atexit_handler = procedure(); cdecl; + +function OPENSSL_atexit(handler: OPENSSL_atexit_handler): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_atexit'; + +procedure OPENSSL_thread_stop(); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_thread_stop'; + +function OPENSSL_INIT_new(): POPENSSL_INIT_SETTINGS; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_INIT_new'; + +function OPENSSL_INIT_set_config_filename(settings: POPENSSL_INIT_SETTINGS; config_filename: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_INIT_set_config_filename'; + +procedure OPENSSL_INIT_set_config_file_flags(settings: POPENSSL_INIT_SETTINGS; flags: Cardinal); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_INIT_set_config_file_flags'; + +function OPENSSL_INIT_set_config_appname(settings: POPENSSL_INIT_SETTINGS; config_appname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_INIT_set_config_appname'; + +procedure OPENSSL_INIT_free(settings: POPENSSL_INIT_SETTINGS); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_INIT_free'; + +type + CRYPTO_THREAD_run_once_init = procedure(); cdecl; + +function CRYPTO_THREAD_run_once(once: PCRYPTO_ONCE; init: CRYPTO_THREAD_run_once_init): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_THREAD_run_once'; + +type + CRYPTO_THREAD_init_local_cleanup = procedure(p1: Pointer); cdecl; + +function CRYPTO_THREAD_init_local(key: PCRYPTO_THREAD_LOCAL; cleanup: CRYPTO_THREAD_init_local_cleanup): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_THREAD_init_local'; + +function CRYPTO_THREAD_get_local(key: PCRYPTO_THREAD_LOCAL): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_THREAD_get_local'; + +function CRYPTO_THREAD_set_local(key: PCRYPTO_THREAD_LOCAL; val: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_THREAD_set_local'; + +function CRYPTO_THREAD_cleanup_local(key: PCRYPTO_THREAD_LOCAL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_THREAD_cleanup_local'; + +function CRYPTO_THREAD_get_current_id(): CRYPTO_THREAD_ID; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_THREAD_get_current_id'; + +function CRYPTO_THREAD_compare_id(a: CRYPTO_THREAD_ID; b: CRYPTO_THREAD_ID): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_THREAD_compare_id'; + +function ERR_load_BIO_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_BIO_strings'; + +function BIO_get_new_index(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_get_new_index'; + +procedure BIO_set_flags(b: PBIO; flags: Integer); cdecl; + external LIB_CRYPTO name _PU + 'BIO_set_flags'; + +function BIO_test_flags(b: PBIO; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_test_flags'; + +procedure BIO_clear_flags(b: PBIO; flags: Integer); cdecl; + external LIB_CRYPTO name _PU + 'BIO_clear_flags'; + +function BIO_get_callback(b: PBIO): BIO_callback_fn; cdecl; + external LIB_CRYPTO name _PU + 'BIO_get_callback'; + +procedure BIO_set_callback(b: PBIO; callback: BIO_callback_fn); cdecl; + external LIB_CRYPTO name _PU + 'BIO_set_callback'; + +function BIO_get_callback_ex(b: PBIO): BIO_callback_fn_ex; cdecl; + external LIB_CRYPTO name _PU + 'BIO_get_callback_ex'; + +procedure BIO_set_callback_ex(b: PBIO; callback: BIO_callback_fn_ex); cdecl; + external LIB_CRYPTO name _PU + 'BIO_set_callback_ex'; + +function BIO_get_callback_arg(b: PBIO): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'BIO_get_callback_arg'; + +procedure BIO_set_callback_arg(b: PBIO; arg: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}); cdecl; + external LIB_CRYPTO name _PU + 'BIO_set_callback_arg'; + +function BIO_method_name(b: PBIO): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'BIO_method_name'; + +function BIO_method_type(b: PBIO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_method_type'; + +function BIO_ctrl_pending(b: PBIO): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ctrl_pending'; + +function BIO_ctrl_wpending(b: PBIO): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ctrl_wpending'; + +function BIO_ctrl_get_write_guarantee(b: PBIO): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ctrl_get_write_guarantee'; + +function BIO_ctrl_get_read_request(b: PBIO): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ctrl_get_read_request'; + +function BIO_ctrl_reset_read_request(b: PBIO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ctrl_reset_read_request'; + +function BIO_set_ex_data(bio: PBIO; idx: Integer; data: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_set_ex_data'; + +function BIO_get_ex_data(bio: PBIO; idx: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_get_ex_data'; + +function BIO_number_read(bio: PBIO): UInt64; cdecl; + external LIB_CRYPTO name _PU + 'BIO_number_read'; + +function BIO_number_written(bio: PBIO): UInt64; cdecl; + external LIB_CRYPTO name _PU + 'BIO_number_written'; + +function BIO_asn1_set_prefix(b: PBIO; prefix: Pasn1_ps_func; prefix_free: Pasn1_ps_func): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_asn1_set_prefix'; + +type + PPasn1_ps_func = Pointer; + +function BIO_asn1_get_prefix(b: PBIO; pprefix: PPasn1_ps_func; pprefix_free: PPasn1_ps_func): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_asn1_get_prefix'; + +function BIO_asn1_set_suffix(b: PBIO; suffix: Pasn1_ps_func; suffix_free: Pasn1_ps_func): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_asn1_set_suffix'; + +function BIO_asn1_get_suffix(b: PBIO; psuffix: PPasn1_ps_func; psuffix_free: PPasn1_ps_func): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_asn1_get_suffix'; + +function BIO_s_file(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_s_file'; + +function BIO_new_file(filename: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; mode: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_new_file'; + +function BIO_new_fp(stream: PPointer; close_flag: Integer): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_new_fp'; + +function BIO_new({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PBIO_METHOD): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_new'; + +function BIO_free(a: PBIO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_free'; + +procedure BIO_set_data(a: PBIO; ptr: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'BIO_set_data'; + +function BIO_get_data(a: PBIO): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_get_data'; + +procedure BIO_set_init(a: PBIO; init: Integer); cdecl; + external LIB_CRYPTO name _PU + 'BIO_set_init'; + +function BIO_get_init(a: PBIO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_get_init'; + +procedure BIO_set_shutdown(a: PBIO; shut: Integer); cdecl; + external LIB_CRYPTO name _PU + 'BIO_set_shutdown'; + +function BIO_get_shutdown(a: PBIO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_get_shutdown'; + +procedure BIO_vfree(a: PBIO); cdecl; + external LIB_CRYPTO name _PU + 'BIO_vfree'; + +function BIO_up_ref(a: PBIO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_up_ref'; + +function BIO_read(b: PBIO; data: Pointer; dlen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_read'; + +function BIO_read_ex(b: PBIO; data: Pointer; dlen: NativeUInt; readbytes: PNativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_read_ex'; + +function BIO_gets(bp: PBIO; buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; size: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_gets'; + +function BIO_write(b: PBIO; data: Pointer; dlen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_write'; + +function BIO_write_ex(b: PBIO; data: Pointer; dlen: NativeUInt; written: PNativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_write_ex'; + +function BIO_puts(bp: PBIO; buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_puts'; + +function BIO_indent(b: PBIO; indent: Integer; max: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_indent'; + +function BIO_ctrl(bp: PBIO; cmd: Integer; larg: Integer; parg: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ctrl'; + +function BIO_callback_ctrl(b: PBIO; cmd: Integer; fp: PBIO_info_cb): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_callback_ctrl'; + +function BIO_ptr_ctrl(bp: PBIO; cmd: Integer; larg: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ptr_ctrl'; + +function BIO_int_ctrl(bp: PBIO; cmd: Integer; larg: Integer; iarg: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_int_ctrl'; + +function BIO_push(b: PBIO; append: PBIO): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_push'; + +function BIO_pop(b: PBIO): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_pop'; + +procedure BIO_free_all(a: PBIO); cdecl; + external LIB_CRYPTO name _PU + 'BIO_free_all'; + +function BIO_find_type(b: PBIO; bio_type: Integer): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_find_type'; + +function BIO_next(b: PBIO): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_next'; + +procedure BIO_set_next(b: PBIO; next: PBIO); cdecl; + external LIB_CRYPTO name _PU + 'BIO_set_next'; + +function BIO_get_retry_BIO(bio: PBIO; reason: PInteger): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_get_retry_BIO'; + +function BIO_get_retry_reason(bio: PBIO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_get_retry_reason'; + +procedure BIO_set_retry_reason(bio: PBIO; reason: Integer); cdecl; + external LIB_CRYPTO name _PU + 'BIO_set_retry_reason'; + +function BIO_dup_chain({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_dup_chain'; + +function BIO_nread0(bio: PBIO; buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_nread0'; + +function BIO_nread(bio: PBIO; buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; num: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_nread'; + +function BIO_nwrite0(bio: PBIO; buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_nwrite0'; + +function BIO_nwrite(bio: PBIO; buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; num: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_nwrite'; + +function BIO_debug_callback(bio: PBIO; cmd: Integer; argp: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; argi: Integer; argl: Integer; ret: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_debug_callback'; + +function BIO_s_mem(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_s_mem'; + +function BIO_s_secmem(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_s_secmem'; + +function BIO_new_mem_buf(buf: Pointer; len: Integer): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_new_mem_buf'; + +function BIO_s_socket(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_s_socket'; + +function BIO_s_connect(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_s_connect'; + +function BIO_s_accept(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_s_accept'; + +function BIO_s_fd(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_s_fd'; + +function BIO_s_log(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_s_log'; + +function BIO_s_bio(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_s_bio'; + +function BIO_s_null(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_s_null'; + +function BIO_f_null(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_f_null'; + +function BIO_f_buffer(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_f_buffer'; + +function BIO_f_linebuffer(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_f_linebuffer'; + +function BIO_f_nbio_test(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_f_nbio_test'; + +function BIO_s_datagram(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_s_datagram'; + +function BIO_dgram_non_fatal_error(error: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_dgram_non_fatal_error'; + +function BIO_new_dgram(fd: Integer; close_flag: Integer): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_new_dgram'; + +function BIO_sock_should_retry(i: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_sock_should_retry'; + +function BIO_sock_non_fatal_error(error: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_sock_non_fatal_error'; + +function BIO_fd_should_retry(i: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_fd_should_retry'; + +function BIO_fd_non_fatal_error(error: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_fd_non_fatal_error'; + +type + BIO_dump_cb_cb = function(data: Pointer; len: NativeUInt; u: Pointer): Integer; cdecl; + +function BIO_dump_cb(cb: BIO_dump_cb_cb; u: Pointer; s: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_dump_cb'; + +type + BIO_dump_indent_cb_cb = function(data: Pointer; len: NativeUInt; u: Pointer): Integer; cdecl; + +function BIO_dump_indent_cb(cb: BIO_dump_indent_cb_cb; u: Pointer; s: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: Integer; indent: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_dump_indent_cb'; + +function BIO_dump(b: PBIO; bytes: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_dump'; + +function BIO_dump_indent(b: PBIO; bytes: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: Integer; indent: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_dump_indent'; + +function BIO_dump_fp(fp: PPointer; s: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_dump_fp'; + +function BIO_dump_indent_fp(fp: PPointer; s: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: Integer; indent: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_dump_indent_fp'; + +function BIO_hex_string({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; indent: Integer; width: Integer; data: PByte; datalen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_hex_string'; + +function BIO_ADDR_new(): PBIO_ADDR; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ADDR_new'; + +function BIO_ADDR_rawmake(ap: PBIO_ADDR; family: Integer; where: Pointer; wherelen: NativeUInt; port: Word): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ADDR_rawmake'; + +procedure BIO_ADDR_free(p1: PBIO_ADDR); cdecl; + external LIB_CRYPTO name _PU + 'BIO_ADDR_free'; + +procedure BIO_ADDR_clear(ap: PBIO_ADDR); cdecl; + external LIB_CRYPTO name _PU + 'BIO_ADDR_clear'; + +function BIO_ADDR_family(ap: PBIO_ADDR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ADDR_family'; + +function BIO_ADDR_rawaddress(ap: PBIO_ADDR; p: Pointer; l: PNativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ADDR_rawaddress'; + +function BIO_ADDR_rawport(ap: PBIO_ADDR): Word; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ADDR_rawport'; + +function BIO_ADDR_hostname_string(ap: PBIO_ADDR; numeric: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ADDR_hostname_string'; + +function BIO_ADDR_service_string(ap: PBIO_ADDR; numeric: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ADDR_service_string'; + +function BIO_ADDR_path_string(ap: PBIO_ADDR): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ADDR_path_string'; + +function BIO_ADDRINFO_next(bai: PBIO_ADDRINFO): PBIO_ADDRINFO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ADDRINFO_next'; + +function BIO_ADDRINFO_family(bai: PBIO_ADDRINFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ADDRINFO_family'; + +function BIO_ADDRINFO_socktype(bai: PBIO_ADDRINFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ADDRINFO_socktype'; + +function BIO_ADDRINFO_protocol(bai: PBIO_ADDRINFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ADDRINFO_protocol'; + +function BIO_ADDRINFO_address(bai: PBIO_ADDRINFO): PBIO_ADDR; cdecl; + external LIB_CRYPTO name _PU + 'BIO_ADDRINFO_address'; + +procedure BIO_ADDRINFO_free(bai: PBIO_ADDRINFO); cdecl; + external LIB_CRYPTO name _PU + 'BIO_ADDRINFO_free'; + +function BIO_parse_hostserv(hostserv: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; host: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; service: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; hostserv_prio: BIO_hostserv_priorities): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_parse_hostserv'; + +function BIO_lookup(host: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; service: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; lookup_type: BIO_lookup_type; family: Integer; socktype: Integer; res: PPBIO_ADDRINFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_lookup'; + +function BIO_lookup_ex(host: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; service: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; lookup_type: Integer; family: Integer; socktype: Integer; protocol: Integer; res: PPBIO_ADDRINFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_lookup_ex'; + +function BIO_sock_error(sock: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_sock_error'; + +function BIO_socket_ioctl(fd: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; arg: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_socket_ioctl'; + +function BIO_socket_nbio(fd: Integer; mode: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_socket_nbio'; + +function BIO_sock_init(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_sock_init'; + +function BIO_set_tcp_ndelay(sock: Integer; turn_on: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_set_tcp_ndelay'; + +function BIO_gethostbyname(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Phostent; cdecl; + external LIB_CRYPTO name _PU + 'BIO_gethostbyname'; + +function BIO_get_port(str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; port_ptr: PWord): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_get_port'; + +function BIO_get_host_ip(str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ip: PByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_get_host_ip'; + +function BIO_get_accept_socket(host_port: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; mode: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_get_accept_socket'; + +function BIO_accept(sock: Integer; ip_port: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_accept'; + +type + PBIO_sock_info_u = Pointer; + +function BIO_sock_info(sock: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: BIO_sock_info_type; info: PBIO_sock_info_u): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_sock_info'; + +function BIO_socket(domain: Integer; socktype: Integer; protocol: Integer; options: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_socket'; + +function BIO_connect(sock: Integer; addr: PBIO_ADDR; options: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_connect'; + +function BIO_bind(sock: Integer; addr: PBIO_ADDR; options: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_bind'; + +function BIO_listen(sock: Integer; addr: PBIO_ADDR; options: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_listen'; + +function BIO_accept_ex(accept_sock: Integer; addr: PBIO_ADDR; options: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_accept_ex'; + +function BIO_closesocket(sock: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_closesocket'; + +function BIO_new_socket(sock: Integer; close_flag: Integer): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_new_socket'; + +function BIO_new_connect(host_port: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_new_connect'; + +function BIO_new_accept(host_port: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_new_accept'; + +function BIO_new_fd(fd: Integer; close_flag: Integer): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_new_fd'; + +function BIO_new_bio_pair(bio1: PPBIO; writebuf1: NativeUInt; bio2: PPBIO; writebuf2: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_new_bio_pair'; + +procedure BIO_copy_next_retry(b: PBIO); cdecl; + external LIB_CRYPTO name _PU + 'BIO_copy_next_retry'; + +function BIO_printf(bio: PBIO; format: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer varargs; cdecl; + external LIB_CRYPTO name _PU + 'BIO_printf'; + +function BIO_vprintf(bio: PBIO; format: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; args: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_vprintf'; + +function BIO_snprintf(buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; n: NativeUInt; format: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer varargs; cdecl; + external LIB_CRYPTO name _PU + 'BIO_snprintf'; + +function BIO_vsnprintf(buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; n: NativeUInt; format: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; args: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_vsnprintf'; + +function BIO_meth_new({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_meth_new'; + +procedure BIO_meth_free(biom: PBIO_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'BIO_meth_free'; + +//function BIO_meth_get_write(p1: PBIOp2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}p3: Integerbiom: PBIO_METHOD): Integer { TODO : Cannot convert original type "int (*)(BIO *, const char *, int)" }; cdecl; +// external LIB_CRYPTO name _PU + 'BIO_meth_get_write'; + +//function BIO_meth_get_write_ex(p1: PBIOp2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}p3: NativeUIntp4: PNativeUIntbiom: PBIO_METHOD): Integer { TODO : Cannot convert original type "int (*)(BIO *, const char *, size_t, size_t *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'BIO_meth_get_write_ex'; + +type + BIO_meth_set_write_write = function(p1: PBIO; p2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; p3: Integer): Integer; cdecl; + +function BIO_meth_set_write(biom: PBIO_METHOD; write: BIO_meth_set_write_write): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_meth_set_write'; + +type + BIO_meth_set_write_ex_bwrite = function(p1: PBIO; p2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; p3: NativeUInt; p4: PNativeUInt): Integer; cdecl; + +function BIO_meth_set_write_ex(biom: PBIO_METHOD; bwrite: BIO_meth_set_write_ex_bwrite): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_meth_set_write_ex'; + +//function BIO_meth_get_read(p1: PBIOp2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}p3: Integerbiom: PBIO_METHOD): Integer { TODO : Cannot convert original type "int (*)(BIO *, char *, int)" }; cdecl; +// external LIB_CRYPTO name _PU + 'BIO_meth_get_read'; + +//function BIO_meth_get_read_ex(p1: PBIOp2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}p3: NativeUIntp4: PNativeUIntbiom: PBIO_METHOD): Integer { TODO : Cannot convert original type "int (*)(BIO *, char *, size_t, size_t *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'BIO_meth_get_read_ex'; + +type + BIO_meth_set_read_read = function(p1: PBIO; p2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; p3: Integer): Integer; cdecl; + +function BIO_meth_set_read(biom: PBIO_METHOD; read: BIO_meth_set_read_read): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_meth_set_read'; + +type + BIO_meth_set_read_ex_bread = function(p1: PBIO; p2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; p3: NativeUInt; p4: PNativeUInt): Integer; cdecl; + +function BIO_meth_set_read_ex(biom: PBIO_METHOD; bread: BIO_meth_set_read_ex_bread): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_meth_set_read_ex'; + +//function BIO_meth_get_puts(p1: PBIOp2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}biom: PBIO_METHOD): Integer { TODO : Cannot convert original type "int (*)(BIO *, const char *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'BIO_meth_get_puts'; + +type + BIO_meth_set_puts_puts = function(p1: PBIO; p2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + +function BIO_meth_set_puts(biom: PBIO_METHOD; puts: BIO_meth_set_puts_puts): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_meth_set_puts'; + +//function BIO_meth_get_gets(p1: PBIOp2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}p3: Integerbiom: PBIO_METHOD): Integer { TODO : Cannot convert original type "int (*)(BIO *, char *, int)" }; cdecl; +// external LIB_CRYPTO name _PU + 'BIO_meth_get_gets'; + +type + BIO_meth_set_gets_gets = function(p1: PBIO; p2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; p3: Integer): Integer; cdecl; + +function BIO_meth_set_gets(biom: PBIO_METHOD; gets: BIO_meth_set_gets_gets): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_meth_set_gets'; + +//function BIO_meth_get_ctrl(p1: PBIOp2: Integerp3: Integerp4: Pointerbiom: PBIO_METHOD): Integer { TODO : Cannot convert original type "long (*)(BIO *, int, long, void *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'BIO_meth_get_ctrl'; + +type + BIO_meth_set_ctrl_ctrl = function(p1: PBIO; p2: Integer; p3: Integer; p4: Pointer): Integer; cdecl; + +function BIO_meth_set_ctrl(biom: PBIO_METHOD; ctrl: BIO_meth_set_ctrl_ctrl): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_meth_set_ctrl'; + +//function BIO_meth_get_create(p1: PBIObion: PBIO_METHOD): Integer { TODO : Cannot convert original type "int (*)(BIO *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'BIO_meth_get_create'; + +type + BIO_meth_set_create_create = function(p1: PBIO): Integer; cdecl; + +function BIO_meth_set_create(biom: PBIO_METHOD; create: BIO_meth_set_create_create): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_meth_set_create'; + +//function BIO_meth_get_destroy(p1: PBIObiom: PBIO_METHOD): Integer { TODO : Cannot convert original type "int (*)(BIO *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'BIO_meth_get_destroy'; + +type + BIO_meth_set_destroy_destroy = function(p1: PBIO): Integer; cdecl; + +function BIO_meth_set_destroy(biom: PBIO_METHOD; destroy: BIO_meth_set_destroy_destroy): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_meth_set_destroy'; + +//function BIO_meth_get_callback_ctrl(p1: PBIOp2: Integerp3: PBIO_info_cbbiom: PBIO_METHOD): Integer { TODO : Cannot convert original type "long (*)(BIO *, int, BIO_info_cb *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'BIO_meth_get_callback_ctrl'; + +type + BIO_meth_set_callback_ctrl_callback_ctrl = function(p1: PBIO; p2: Integer; p3: PBIO_info_cb): Integer; cdecl; + +function BIO_meth_set_callback_ctrl(biom: PBIO_METHOD; callback_ctrl: BIO_meth_set_callback_ctrl_callback_ctrl): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_meth_set_callback_ctrl'; + +function ERR_load_ASN1_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_ASN1_strings'; + +function ERR_load_BN_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_BN_strings'; + +procedure BN_set_flags(b: PBIGNUM; n: Integer); cdecl; + external LIB_CRYPTO name _PU + 'BN_set_flags'; + +function BN_get_flags(b: PBIGNUM; n: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_get_flags'; + +procedure BN_with_flags(dest: PBIGNUM; b: PBIGNUM; flags: Integer); cdecl; + external LIB_CRYPTO name _PU + 'BN_with_flags'; + +function BN_GENCB_call(cb: PBN_GENCB; a: Integer; b: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GENCB_call'; + +function BN_GENCB_new(): PBN_GENCB; cdecl; + external LIB_CRYPTO name _PU + 'BN_GENCB_new'; + +procedure BN_GENCB_free(cb: PBN_GENCB); cdecl; + external LIB_CRYPTO name _PU + 'BN_GENCB_free'; + +type + BN_GENCB_set_old_callback = procedure(p1: Integer; p2: Integer; p3: Pointer); cdecl; + +procedure BN_GENCB_set_old(gencb: PBN_GENCB; callback: BN_GENCB_set_old_callback; cb_arg: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'BN_GENCB_set_old'; + +type + BN_GENCB_set_callback = function(p1: Integer; p2: Integer; p3: PBN_GENCB): Integer; cdecl; + +procedure BN_GENCB_set(gencb: PBN_GENCB; callback: BN_GENCB_set_callback; cb_arg: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'BN_GENCB_set'; + +function BN_GENCB_get_arg(cb: PBN_GENCB): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GENCB_get_arg'; + +function BN_abs_is_word(a: PBIGNUM; w: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_abs_is_word'; + +function BN_is_zero(a: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_is_zero'; + +function BN_is_one(a: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_is_one'; + +function BN_is_word(a: PBIGNUM; w: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_is_word'; + +function BN_is_odd(a: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_is_odd'; + +procedure BN_zero_ex(a: PBIGNUM); cdecl; + external LIB_CRYPTO name _PU + 'BN_zero_ex'; + +function BN_value_one(): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_value_one'; + +function BN_options(): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'BN_options'; + +function BN_CTX_new(): PBN_CTX; cdecl; + external LIB_CRYPTO name _PU + 'BN_CTX_new'; + +function BN_CTX_secure_new(): PBN_CTX; cdecl; + external LIB_CRYPTO name _PU + 'BN_CTX_secure_new'; + +procedure BN_CTX_free(c: PBN_CTX); cdecl; + external LIB_CRYPTO name _PU + 'BN_CTX_free'; + +procedure BN_CTX_start(ctx: PBN_CTX); cdecl; + external LIB_CRYPTO name _PU + 'BN_CTX_start'; + +function BN_CTX_get(ctx: PBN_CTX): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_CTX_get'; + +procedure BN_CTX_end(ctx: PBN_CTX); cdecl; + external LIB_CRYPTO name _PU + 'BN_CTX_end'; + +function BN_rand(rnd: PBIGNUM; bits: Integer; top: Integer; bottom: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_rand'; + +function BN_priv_rand(rnd: PBIGNUM; bits: Integer; top: Integer; bottom: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_priv_rand'; + +function BN_rand_range(rnd: PBIGNUM; range: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_rand_range'; + +function BN_priv_rand_range(rnd: PBIGNUM; range: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_priv_rand_range'; + +function BN_pseudo_rand(rnd: PBIGNUM; bits: Integer; top: Integer; bottom: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_pseudo_rand'; + +function BN_pseudo_rand_range(rnd: PBIGNUM; range: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_pseudo_rand_range'; + +function BN_num_bits(a: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_num_bits'; + +function BN_num_bits_word(l: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_num_bits_word'; + +function BN_security_bits(L: Integer; N: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_security_bits'; + +function BN_new(): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_new'; + +function BN_secure_new(): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_secure_new'; + +procedure BN_clear_free(a: PBIGNUM); cdecl; + external LIB_CRYPTO name _PU + 'BN_clear_free'; + +function BN_copy(a: PBIGNUM; b: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_copy'; + +procedure BN_swap(a: PBIGNUM; b: PBIGNUM); cdecl; + external LIB_CRYPTO name _PU + 'BN_swap'; + +function BN_bin2bn(s: Pointer; len: Integer; ret: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_bin2bn'; + +function BN_bn2bin(a: PBIGNUM; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_bn2bin'; + +function BN_bn2binpad(a: PBIGNUM; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: Pointer; tolen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_bn2binpad'; + +function BN_lebin2bn(s: Pointer; len: Integer; ret: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_lebin2bn'; + +function BN_bn2lebinpad(a: PBIGNUM; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: Pointer; tolen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_bn2lebinpad'; + +function BN_mpi2bn(s: Pointer; len: Integer; ret: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_mpi2bn'; + +function BN_bn2mpi(a: PBIGNUM; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_bn2mpi'; + +function BN_sub(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_sub'; + +function BN_usub(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_usub'; + +function BN_uadd(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_uadd'; + +function BN_add(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_add'; + +function BN_mul(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mul'; + +function BN_sqr(r: PBIGNUM; a: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_sqr'; + +(** BN_set_negative sets sign of a BIGNUM + * \param b pointer to the BIGNUM object + * \param n 0 if the BIGNUM b should be positive and a value != 0 otherwise + *) +procedure BN_set_negative(b: PBIGNUM; n: Integer); cdecl; + external LIB_CRYPTO name _PU + 'BN_set_negative'; + +(** BN_is_negative returns 1 if the BIGNUM is negative + * \param b pointer to the BIGNUM object + * \return 1 if a < 0 and 0 otherwise + *) +function BN_is_negative(b: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_is_negative'; + +function BN_div(dv: PBIGNUM; rem: PBIGNUM; m: PBIGNUM; d: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_div'; + +function BN_nnmod(r: PBIGNUM; m: PBIGNUM; d: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_nnmod'; + +function BN_mod_add(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM; m: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_add'; + +function BN_mod_add_quick(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM; m: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_add_quick'; + +function BN_mod_sub(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM; m: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_sub'; + +function BN_mod_sub_quick(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM; m: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_sub_quick'; + +function BN_mod_mul(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM; m: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_mul'; + +function BN_mod_sqr(r: PBIGNUM; a: PBIGNUM; m: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_sqr'; + +function BN_mod_lshift1(r: PBIGNUM; a: PBIGNUM; m: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_lshift1'; + +function BN_mod_lshift1_quick(r: PBIGNUM; a: PBIGNUM; m: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_lshift1_quick'; + +function BN_mod_lshift(r: PBIGNUM; a: PBIGNUM; n: Integer; m: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_lshift'; + +function BN_mod_lshift_quick(r: PBIGNUM; a: PBIGNUM; n: Integer; m: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_lshift_quick'; + +function BN_mod_word(a: PBIGNUM; w: Cardinal): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_word'; + +function BN_div_word(a: PBIGNUM; w: Cardinal): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'BN_div_word'; + +function BN_mul_word(a: PBIGNUM; w: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mul_word'; + +function BN_add_word(a: PBIGNUM; w: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_add_word'; + +function BN_sub_word(a: PBIGNUM; w: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_sub_word'; + +function BN_set_word(a: PBIGNUM; w: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_set_word'; + +function BN_get_word(a: PBIGNUM): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'BN_get_word'; + +function BN_cmp(a: PBIGNUM; b: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_cmp'; + +procedure BN_free(a: PBIGNUM); cdecl; + external LIB_CRYPTO name _PU + 'BN_free'; + +function BN_is_bit_set(a: PBIGNUM; n: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_is_bit_set'; + +function BN_lshift(r: PBIGNUM; a: PBIGNUM; n: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_lshift'; + +function BN_lshift1(r: PBIGNUM; a: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_lshift1'; + +function BN_exp(r: PBIGNUM; a: PBIGNUM; p: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_exp'; + +function BN_mod_exp(r: PBIGNUM; a: PBIGNUM; p: PBIGNUM; m: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_exp'; + +function BN_mod_exp_mont(r: PBIGNUM; a: PBIGNUM; p: PBIGNUM; m: PBIGNUM; ctx: PBN_CTX; m_ctx: PBN_MONT_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_exp_mont'; + +function BN_mod_exp_mont_consttime(rr: PBIGNUM; a: PBIGNUM; p: PBIGNUM; m: PBIGNUM; ctx: PBN_CTX; in_mont: PBN_MONT_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_exp_mont_consttime'; + +function BN_mod_exp_mont_word(r: PBIGNUM; a: Cardinal; p: PBIGNUM; m: PBIGNUM; ctx: PBN_CTX; m_ctx: PBN_MONT_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_exp_mont_word'; + +function BN_mod_exp2_mont(r: PBIGNUM; a1: PBIGNUM; p1: PBIGNUM; a2: PBIGNUM; p2: PBIGNUM; m: PBIGNUM; ctx: PBN_CTX; m_ctx: PBN_MONT_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_exp2_mont'; + +function BN_mod_exp_simple(r: PBIGNUM; a: PBIGNUM; p: PBIGNUM; m: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_exp_simple'; + +function BN_mask_bits(a: PBIGNUM; n: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mask_bits'; + +function BN_print_fp(fp: PPointer; a: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_print_fp'; + +function BN_print(bio: PBIO; a: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_print'; + +function BN_reciprocal(r: PBIGNUM; m: PBIGNUM; len: Integer; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_reciprocal'; + +function BN_rshift(r: PBIGNUM; a: PBIGNUM; n: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_rshift'; + +function BN_rshift1(r: PBIGNUM; a: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_rshift1'; + +procedure BN_clear(a: PBIGNUM); cdecl; + external LIB_CRYPTO name _PU + 'BN_clear'; + +function BN_dup(a: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_dup'; + +function BN_ucmp(a: PBIGNUM; b: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_ucmp'; + +function BN_set_bit(a: PBIGNUM; n: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_set_bit'; + +function BN_clear_bit(a: PBIGNUM; n: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_clear_bit'; + +function BN_bn2hex(a: PBIGNUM): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'BN_bn2hex'; + +function BN_bn2dec(a: PBIGNUM): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'BN_bn2dec'; + +function BN_hex2bn(a: PPBIGNUM; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_hex2bn'; + +function BN_dec2bn(a: PPBIGNUM; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_dec2bn'; + +function BN_asc2bn(a: PPBIGNUM; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_asc2bn'; + +function BN_gcd(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_gcd'; + +function BN_kronecker(a: PBIGNUM; b: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_kronecker'; + +function BN_mod_inverse(ret: PBIGNUM; a: PBIGNUM; n: PBIGNUM; ctx: PBN_CTX): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_inverse'; + +function BN_mod_sqrt(ret: PBIGNUM; a: PBIGNUM; n: PBIGNUM; ctx: PBN_CTX): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_sqrt'; + +procedure BN_consttime_swap(swap: Cardinal; a: PBIGNUM; b: PBIGNUM; nwords: Integer); cdecl; + external LIB_CRYPTO name _PU + 'BN_consttime_swap'; + +type + BN_generate_prime_callback = procedure(p1: Integer; p2: Integer; p3: Pointer); cdecl; + +function BN_generate_prime(ret: PBIGNUM; bits: Integer; safe: Integer; add: PBIGNUM; rem: PBIGNUM; callback: BN_generate_prime_callback; cb_arg: Pointer): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_generate_prime'; + +type + BN_is_prime_callback = procedure(p1: Integer; p2: Integer; p3: Pointer); cdecl; + +function BN_is_prime(p: PBIGNUM; nchecks: Integer; callback: BN_is_prime_callback; ctx: PBN_CTX; cb_arg: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_is_prime'; + +type + BN_is_prime_fasttest_callback = procedure(p1: Integer; p2: Integer; p3: Pointer); cdecl; + +function BN_is_prime_fasttest(p: PBIGNUM; nchecks: Integer; callback: BN_is_prime_fasttest_callback; ctx: PBN_CTX; cb_arg: Pointer; do_trial_division: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_is_prime_fasttest'; + +function BN_generate_prime_ex(ret: PBIGNUM; bits: Integer; safe: Integer; add: PBIGNUM; rem: PBIGNUM; cb: PBN_GENCB): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_generate_prime_ex'; + +function BN_is_prime_ex(p: PBIGNUM; nchecks: Integer; ctx: PBN_CTX; cb: PBN_GENCB): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_is_prime_ex'; + +function BN_is_prime_fasttest_ex(p: PBIGNUM; nchecks: Integer; ctx: PBN_CTX; do_trial_division: Integer; cb: PBN_GENCB): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_is_prime_fasttest_ex'; + +function BN_X931_generate_Xpq(Xp: PBIGNUM; Xq: PBIGNUM; nbits: Integer; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_X931_generate_Xpq'; + +function BN_X931_derive_prime_ex(p: PBIGNUM; p1: PBIGNUM; p2: PBIGNUM; Xp: PBIGNUM; Xp1: PBIGNUM; Xp2: PBIGNUM; e: PBIGNUM; ctx: PBN_CTX; cb: PBN_GENCB): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_X931_derive_prime_ex'; + +function BN_X931_generate_prime_ex(p: PBIGNUM; p1: PBIGNUM; p2: PBIGNUM; Xp1: PBIGNUM; Xp2: PBIGNUM; Xp: PBIGNUM; e: PBIGNUM; ctx: PBN_CTX; cb: PBN_GENCB): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_X931_generate_prime_ex'; + +function BN_MONT_CTX_new(): PBN_MONT_CTX; cdecl; + external LIB_CRYPTO name _PU + 'BN_MONT_CTX_new'; + +function BN_mod_mul_montgomery(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM; mont: PBN_MONT_CTX; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_mul_montgomery'; + +function BN_to_montgomery(r: PBIGNUM; a: PBIGNUM; mont: PBN_MONT_CTX; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_to_montgomery'; + +function BN_from_montgomery(r: PBIGNUM; a: PBIGNUM; mont: PBN_MONT_CTX; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_from_montgomery'; + +procedure BN_MONT_CTX_free(mont: PBN_MONT_CTX); cdecl; + external LIB_CRYPTO name _PU + 'BN_MONT_CTX_free'; + +function BN_MONT_CTX_set(mont: PBN_MONT_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&mod{$ELSE}mod1{$IFEND}{$ELSE}&mod{$ENDIF}: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_MONT_CTX_set'; + +function BN_MONT_CTX_copy({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PBN_MONT_CTX; from: PBN_MONT_CTX): PBN_MONT_CTX; cdecl; + external LIB_CRYPTO name _PU + 'BN_MONT_CTX_copy'; + +function BN_MONT_CTX_set_locked(pmont: PPBN_MONT_CTX; lock: PCRYPTO_RWLOCK; {$IFNDEF FPC}{$IF CompilerVersion > 21}&mod{$ELSE}mod1{$IFEND}{$ELSE}&mod{$ENDIF}: PBIGNUM; ctx: PBN_CTX): PBN_MONT_CTX; cdecl; + external LIB_CRYPTO name _PU + 'BN_MONT_CTX_set_locked'; + +function BN_BLINDING_new(A: PBIGNUM; Ai: PBIGNUM; {$IFNDEF FPC}{$IF CompilerVersion > 21}&mod{$ELSE}mod1{$IFEND}{$ELSE}&mod{$ENDIF}: PBIGNUM): PBN_BLINDING; cdecl; + external LIB_CRYPTO name _PU + 'BN_BLINDING_new'; + +procedure BN_BLINDING_free(b: PBN_BLINDING); cdecl; + external LIB_CRYPTO name _PU + 'BN_BLINDING_free'; + +function BN_BLINDING_update(b: PBN_BLINDING; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_BLINDING_update'; + +function BN_BLINDING_convert(n: PBIGNUM; b: PBN_BLINDING; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_BLINDING_convert'; + +function BN_BLINDING_invert(n: PBIGNUM; b: PBN_BLINDING; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_BLINDING_invert'; + +function BN_BLINDING_convert_ex(n: PBIGNUM; r: PBIGNUM; b: PBN_BLINDING; p4: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_BLINDING_convert_ex'; + +function BN_BLINDING_invert_ex(n: PBIGNUM; r: PBIGNUM; b: PBN_BLINDING; p4: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_BLINDING_invert_ex'; + +function BN_BLINDING_is_current_thread(b: PBN_BLINDING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_BLINDING_is_current_thread'; + +procedure BN_BLINDING_set_current_thread(b: PBN_BLINDING); cdecl; + external LIB_CRYPTO name _PU + 'BN_BLINDING_set_current_thread'; + +function BN_BLINDING_lock(b: PBN_BLINDING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_BLINDING_lock'; + +function BN_BLINDING_unlock(b: PBN_BLINDING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_BLINDING_unlock'; + +function BN_BLINDING_get_flags(p1: PBN_BLINDING): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'BN_BLINDING_get_flags'; + +procedure BN_BLINDING_set_flags(p1: PBN_BLINDING; p2: Cardinal); cdecl; + external LIB_CRYPTO name _PU + 'BN_BLINDING_set_flags'; + +type + BN_BLINDING_create_param_bn_mod_exp = function(r: PBIGNUM; a: PBIGNUM; p: PBIGNUM; m: PBIGNUM; ctx: PBN_CTX; m_ctx: PBN_MONT_CTX): Integer; cdecl; + +function BN_BLINDING_create_param(b: PBN_BLINDING; e: PBIGNUM; m: PBIGNUM; ctx: PBN_CTX; bn_mod_exp: BN_BLINDING_create_param_bn_mod_exp; m_ctx: PBN_MONT_CTX): PBN_BLINDING; cdecl; + external LIB_CRYPTO name _PU + 'BN_BLINDING_create_param'; + +procedure BN_set_params(mul: Integer; high: Integer; low: Integer; mont: Integer); cdecl; + external LIB_CRYPTO name _PU + 'BN_set_params'; + +function BN_get_params(which: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_get_params'; + +function BN_RECP_CTX_new(): PBN_RECP_CTX; cdecl; + external LIB_CRYPTO name _PU + 'BN_RECP_CTX_new'; + +procedure BN_RECP_CTX_free(recp: PBN_RECP_CTX); cdecl; + external LIB_CRYPTO name _PU + 'BN_RECP_CTX_free'; + +function BN_RECP_CTX_set(recp: PBN_RECP_CTX; rdiv: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_RECP_CTX_set'; + +function BN_mod_mul_reciprocal(r: PBIGNUM; x: PBIGNUM; y: PBIGNUM; recp: PBN_RECP_CTX; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_mul_reciprocal'; + +function BN_mod_exp_recp(r: PBIGNUM; a: PBIGNUM; p: PBIGNUM; m: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_mod_exp_recp'; + +function BN_div_recp(dv: PBIGNUM; rem: PBIGNUM; m: PBIGNUM; recp: PBN_RECP_CTX; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_div_recp'; + +function BN_GF2m_add(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_add'; + +function BN_GF2m_mod(r: PBIGNUM; a: PBIGNUM; p: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_mod'; + +function BN_GF2m_mod_mul(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM; p: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_mod_mul'; + +function BN_GF2m_mod_sqr(r: PBIGNUM; a: PBIGNUM; p: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_mod_sqr'; + +function BN_GF2m_mod_inv(r: PBIGNUM; b: PBIGNUM; p: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_mod_inv'; + +function BN_GF2m_mod_div(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM; p: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_mod_div'; + +function BN_GF2m_mod_exp(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM; p: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_mod_exp'; + +function BN_GF2m_mod_sqrt(r: PBIGNUM; a: PBIGNUM; p: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_mod_sqrt'; + +function BN_GF2m_mod_solve_quad(r: PBIGNUM; a: PBIGNUM; p: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_mod_solve_quad'; + +function BN_GF2m_mod_arr(r: PBIGNUM; a: PBIGNUM; p: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_mod_arr'; + +function BN_GF2m_mod_mul_arr(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM; p: PInteger; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_mod_mul_arr'; + +function BN_GF2m_mod_sqr_arr(r: PBIGNUM; a: PBIGNUM; p: PInteger; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_mod_sqr_arr'; + +function BN_GF2m_mod_inv_arr(r: PBIGNUM; b: PBIGNUM; p: PInteger; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_mod_inv_arr'; + +function BN_GF2m_mod_div_arr(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM; p: PInteger; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_mod_div_arr'; + +function BN_GF2m_mod_exp_arr(r: PBIGNUM; a: PBIGNUM; b: PBIGNUM; p: PInteger; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_mod_exp_arr'; + +function BN_GF2m_mod_sqrt_arr(r: PBIGNUM; a: PBIGNUM; p: PInteger; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_mod_sqrt_arr'; + +function BN_GF2m_mod_solve_quad_arr(r: PBIGNUM; a: PBIGNUM; p: PInteger; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_mod_solve_quad_arr'; + +function BN_GF2m_poly2arr(a: PBIGNUM; p: PInteger; max: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_poly2arr'; + +function BN_GF2m_arr2poly(p: PInteger; a: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_GF2m_arr2poly'; + +function BN_nist_mod_192(r: PBIGNUM; a: PBIGNUM; p: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_nist_mod_192'; + +function BN_nist_mod_224(r: PBIGNUM; a: PBIGNUM; p: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_nist_mod_224'; + +function BN_nist_mod_256(r: PBIGNUM; a: PBIGNUM; p: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_nist_mod_256'; + +function BN_nist_mod_384(r: PBIGNUM; a: PBIGNUM; p: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_nist_mod_384'; + +function BN_nist_mod_521(r: PBIGNUM; a: PBIGNUM; p: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_nist_mod_521'; + +function BN_get0_nist_prime_192(): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_get0_nist_prime_192'; + +function BN_get0_nist_prime_224(): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_get0_nist_prime_224'; + +function BN_get0_nist_prime_256(): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_get0_nist_prime_256'; + +function BN_get0_nist_prime_384(): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_get0_nist_prime_384'; + +function BN_get0_nist_prime_521(): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_get0_nist_prime_521'; + +//function BN_nist_mod_func(r: PBIGNUMa: PBIGNUMfield: PBIGNUMctx: PBN_CTXp: PBIGNUM): Integer { TODO : Cannot convert original type "int (*)(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'BN_nist_mod_func'; + +function BN_generate_dsa_nonce({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIGNUM; range: PBIGNUM; priv: PBIGNUM; {$IFNDEF FPC}{$IF CompilerVersion > 21}&message{$ELSE}message1{$IFEND}{$ELSE}&message{$ENDIF}: PByte; message_len: NativeUInt; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_generate_dsa_nonce'; + +function BN_get_rfc2409_prime_768(bn: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_get_rfc2409_prime_768'; + +function BN_get_rfc2409_prime_1024(bn: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_get_rfc2409_prime_1024'; + +function BN_get_rfc3526_prime_1536(bn: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_get_rfc3526_prime_1536'; + +function BN_get_rfc3526_prime_2048(bn: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_get_rfc3526_prime_2048'; + +function BN_get_rfc3526_prime_3072(bn: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_get_rfc3526_prime_3072'; + +function BN_get_rfc3526_prime_4096(bn: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_get_rfc3526_prime_4096'; + +function BN_get_rfc3526_prime_6144(bn: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_get_rfc3526_prime_6144'; + +function BN_get_rfc3526_prime_8192(bn: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'BN_get_rfc3526_prime_8192'; + +function BN_bntest_rand(rnd: PBIGNUM; bits: Integer; top: Integer; bottom: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BN_bntest_rand'; + +function d2i_ASN1_SEQUENCE_ANY(a: PPASN1_SEQUENCE_ANY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_SEQUENCE_ANY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_SEQUENCE_ANY'; + +function i2d_ASN1_SEQUENCE_ANY(a: PASN1_SEQUENCE_ANY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_SEQUENCE_ANY'; + +function ASN1_SEQUENCE_ANY_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_SEQUENCE_ANY_it'; + +function d2i_ASN1_SET_ANY(a: PPASN1_SEQUENCE_ANY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_SEQUENCE_ANY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_SET_ANY'; + +function i2d_ASN1_SET_ANY(a: PASN1_SEQUENCE_ANY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_SET_ANY'; + +function ASN1_SET_ANY_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_SET_ANY_it'; + +function ASN1_TYPE_new(): PASN1_TYPE; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TYPE_new'; + +procedure ASN1_TYPE_free(a: PASN1_TYPE); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TYPE_free'; + +function d2i_ASN1_TYPE(a: PPASN1_TYPE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_TYPE; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_TYPE'; + +function i2d_ASN1_TYPE(a: PASN1_TYPE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_TYPE'; + +function ASN1_ANY_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_ANY_it'; + +function ASN1_TYPE_get(a: PASN1_TYPE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TYPE_get'; + +procedure ASN1_TYPE_set(a: PASN1_TYPE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; value: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TYPE_set'; + +function ASN1_TYPE_set1(a: PASN1_TYPE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; value: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TYPE_set1'; + +function ASN1_TYPE_cmp(a: PASN1_TYPE; b: PASN1_TYPE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TYPE_cmp'; + +function ASN1_TYPE_pack_sequence(it: PASN1_ITEM; s: Pointer; t: PPASN1_TYPE): PASN1_TYPE; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TYPE_pack_sequence'; + +function ASN1_TYPE_unpack_sequence(it: PASN1_ITEM; t: PASN1_TYPE): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TYPE_unpack_sequence'; + +function ASN1_OBJECT_new(): PASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_OBJECT_new'; + +procedure ASN1_OBJECT_free(a: PASN1_OBJECT); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_OBJECT_free'; + +function i2d_ASN1_OBJECT(a: PASN1_OBJECT; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_OBJECT'; + +function d2i_ASN1_OBJECT(a: PPASN1_OBJECT; pp: PPByte; length: Integer): PASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_OBJECT'; + +function ASN1_OBJECT_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_OBJECT_it'; + +function ASN1_STRING_new(): PASN1_STRING; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_new'; + +procedure ASN1_STRING_free(a: PASN1_STRING); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_free'; + +procedure ASN1_STRING_clear_free(a: PASN1_STRING); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_clear_free'; + +function ASN1_STRING_copy(dst: PASN1_STRING; str: PASN1_STRING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_copy'; + +function ASN1_STRING_dup(a: PASN1_STRING): PASN1_STRING; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_dup'; + +function ASN1_STRING_type_new({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): PASN1_STRING; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_type_new'; + +function ASN1_STRING_cmp(a: PASN1_STRING; b: PASN1_STRING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_cmp'; + +function ASN1_STRING_set(str: PASN1_STRING; data: Pointer; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_set'; + +procedure ASN1_STRING_set0(str: PASN1_STRING; data: Pointer; len: Integer); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_set0'; + +function ASN1_STRING_length(x: PASN1_STRING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_length'; + +procedure ASN1_STRING_length_set(x: PASN1_STRING; n: Integer); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_length_set'; + +function ASN1_STRING_type(x: PASN1_STRING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_type'; + +function ASN1_STRING_data(x: PASN1_STRING): PByte; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_data'; + +function ASN1_STRING_get0_data(x: PASN1_STRING): PByte; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_get0_data'; + +function ASN1_BIT_STRING_new(): PASN1_BIT_STRING; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_BIT_STRING_new'; + +procedure ASN1_BIT_STRING_free(a: PASN1_BIT_STRING); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_BIT_STRING_free'; + +function d2i_ASN1_BIT_STRING(a: PPASN1_BIT_STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_BIT_STRING; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_BIT_STRING'; + +function i2d_ASN1_BIT_STRING(a: PASN1_BIT_STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_BIT_STRING'; + +function ASN1_BIT_STRING_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_BIT_STRING_it'; + +function ASN1_BIT_STRING_set(a: PASN1_BIT_STRING; d: PByte; length: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_BIT_STRING_set'; + +function ASN1_BIT_STRING_set_bit(a: PASN1_BIT_STRING; n: Integer; value: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_BIT_STRING_set_bit'; + +function ASN1_BIT_STRING_get_bit(a: PASN1_BIT_STRING; n: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_BIT_STRING_get_bit'; + +function ASN1_BIT_STRING_check(a: PASN1_BIT_STRING; flags: PByte; flags_len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_BIT_STRING_check'; + +function ASN1_BIT_STRING_name_print({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; bs: PASN1_BIT_STRING; tbl: PBIT_STRING_BITNAME; indent: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_BIT_STRING_name_print'; + +function ASN1_BIT_STRING_num_asc(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; tbl: PBIT_STRING_BITNAME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_BIT_STRING_num_asc'; + +function ASN1_BIT_STRING_set_asc(bs: PASN1_BIT_STRING; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; value: Integer; tbl: PBIT_STRING_BITNAME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_BIT_STRING_set_asc'; + +function ASN1_INTEGER_new(): PASN1_INTEGER; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_INTEGER_new'; + +procedure ASN1_INTEGER_free(a: PASN1_INTEGER); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_INTEGER_free'; + +function d2i_ASN1_INTEGER(a: PPASN1_INTEGER; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_INTEGER; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_INTEGER'; + +function i2d_ASN1_INTEGER(a: PASN1_INTEGER; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_INTEGER'; + +function ASN1_INTEGER_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_INTEGER_it'; + +function d2i_ASN1_UINTEGER(a: PPASN1_INTEGER; pp: PPByte; length: Integer): PASN1_INTEGER; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_UINTEGER'; + +function ASN1_INTEGER_dup(x: PASN1_INTEGER): PASN1_INTEGER; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_INTEGER_dup'; + +function ASN1_INTEGER_cmp(x: PASN1_INTEGER; y: PASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_INTEGER_cmp'; + +function ASN1_ENUMERATED_new(): PASN1_ENUMERATED; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_ENUMERATED_new'; + +procedure ASN1_ENUMERATED_free(a: PASN1_ENUMERATED); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_ENUMERATED_free'; + +function d2i_ASN1_ENUMERATED(a: PPASN1_ENUMERATED; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_ENUMERATED; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_ENUMERATED'; + +function i2d_ASN1_ENUMERATED(a: PASN1_ENUMERATED; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_ENUMERATED'; + +function ASN1_ENUMERATED_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_ENUMERATED_it'; + +function ASN1_UTCTIME_check(a: PASN1_UTCTIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_UTCTIME_check'; + +function ASN1_UTCTIME_set(s: PASN1_UTCTIME; t: Longint): PASN1_UTCTIME; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_UTCTIME_set'; + +function ASN1_UTCTIME_adj(s: PASN1_UTCTIME; t: Longint; offset_day: Integer; offset_sec: Integer): PASN1_UTCTIME; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_UTCTIME_adj'; + +function ASN1_UTCTIME_set_string(s: PASN1_UTCTIME; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_UTCTIME_set_string'; + +function ASN1_UTCTIME_cmp_time_t(s: PASN1_UTCTIME; t: Longint): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_UTCTIME_cmp_time_t'; + +function ASN1_GENERALIZEDTIME_check(a: PASN1_GENERALIZEDTIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_GENERALIZEDTIME_check'; + +function ASN1_GENERALIZEDTIME_set(s: PASN1_GENERALIZEDTIME; t: Longint): PASN1_GENERALIZEDTIME; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_GENERALIZEDTIME_set'; + +function ASN1_GENERALIZEDTIME_adj(s: PASN1_GENERALIZEDTIME; t: Longint; offset_day: Integer; offset_sec: Integer): PASN1_GENERALIZEDTIME; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_GENERALIZEDTIME_adj'; + +function ASN1_GENERALIZEDTIME_set_string(s: PASN1_GENERALIZEDTIME; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_GENERALIZEDTIME_set_string'; + +function ASN1_TIME_diff(pday: PInteger; psec: PInteger; from: PASN1_TIME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PASN1_TIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TIME_diff'; + +function ASN1_OCTET_STRING_new(): PASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_OCTET_STRING_new'; + +procedure ASN1_OCTET_STRING_free(a: PASN1_OCTET_STRING); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_OCTET_STRING_free'; + +function d2i_ASN1_OCTET_STRING(a: PPASN1_OCTET_STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_OCTET_STRING'; + +function i2d_ASN1_OCTET_STRING(a: PASN1_OCTET_STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_OCTET_STRING'; + +function ASN1_OCTET_STRING_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_OCTET_STRING_it'; + +function ASN1_OCTET_STRING_dup(a: PASN1_OCTET_STRING): PASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_OCTET_STRING_dup'; + +function ASN1_OCTET_STRING_cmp(a: PASN1_OCTET_STRING; b: PASN1_OCTET_STRING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_OCTET_STRING_cmp'; + +function ASN1_OCTET_STRING_set(str: PASN1_OCTET_STRING; data: PByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_OCTET_STRING_set'; + +function ASN1_VISIBLESTRING_new(): PASN1_VISIBLESTRING; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_VISIBLESTRING_new'; + +procedure ASN1_VISIBLESTRING_free(a: PASN1_VISIBLESTRING); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_VISIBLESTRING_free'; + +function d2i_ASN1_VISIBLESTRING(a: PPASN1_VISIBLESTRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_VISIBLESTRING; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_VISIBLESTRING'; + +function i2d_ASN1_VISIBLESTRING(a: PASN1_VISIBLESTRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_VISIBLESTRING'; + +function ASN1_VISIBLESTRING_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_VISIBLESTRING_it'; + +function ASN1_UNIVERSALSTRING_new(): PASN1_UNIVERSALSTRING; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_UNIVERSALSTRING_new'; + +procedure ASN1_UNIVERSALSTRING_free(a: PASN1_UNIVERSALSTRING); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_UNIVERSALSTRING_free'; + +function d2i_ASN1_UNIVERSALSTRING(a: PPASN1_UNIVERSALSTRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_UNIVERSALSTRING; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_UNIVERSALSTRING'; + +function i2d_ASN1_UNIVERSALSTRING(a: PASN1_UNIVERSALSTRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_UNIVERSALSTRING'; + +function ASN1_UNIVERSALSTRING_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_UNIVERSALSTRING_it'; + +function ASN1_UTF8STRING_new(): PASN1_UTF8STRING; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_UTF8STRING_new'; + +procedure ASN1_UTF8STRING_free(a: PASN1_UTF8STRING); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_UTF8STRING_free'; + +function d2i_ASN1_UTF8STRING(a: PPASN1_UTF8STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_UTF8STRING; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_UTF8STRING'; + +function i2d_ASN1_UTF8STRING(a: PASN1_UTF8STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_UTF8STRING'; + +function ASN1_UTF8STRING_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_UTF8STRING_it'; + +function ASN1_NULL_new(): PASN1_NULL; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_NULL_new'; + +procedure ASN1_NULL_free(a: PASN1_NULL); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_NULL_free'; + +function d2i_ASN1_NULL(a: PPASN1_NULL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_NULL; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_NULL'; + +function i2d_ASN1_NULL(a: PASN1_NULL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_NULL'; + +function ASN1_NULL_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_NULL_it'; + +function ASN1_BMPSTRING_new(): PASN1_BMPSTRING; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_BMPSTRING_new'; + +procedure ASN1_BMPSTRING_free(a: PASN1_BMPSTRING); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_BMPSTRING_free'; + +function d2i_ASN1_BMPSTRING(a: PPASN1_BMPSTRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_BMPSTRING; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_BMPSTRING'; + +function i2d_ASN1_BMPSTRING(a: PASN1_BMPSTRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_BMPSTRING'; + +function ASN1_BMPSTRING_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_BMPSTRING_it'; + +function UTF8_getc(str: PByte; len: Integer; val: PCardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UTF8_getc'; + +function UTF8_putc(str: PByte; len: Integer; value: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UTF8_putc'; + +function ASN1_PRINTABLE_new(): PASN1_STRING; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PRINTABLE_new'; + +procedure ASN1_PRINTABLE_free(a: PASN1_STRING); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PRINTABLE_free'; + +function d2i_ASN1_PRINTABLE(a: PPASN1_STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_STRING; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_PRINTABLE'; + +function i2d_ASN1_PRINTABLE(a: PASN1_STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_PRINTABLE'; + +function ASN1_PRINTABLE_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PRINTABLE_it'; + +function DIRECTORYSTRING_new(): PASN1_STRING; cdecl; + external LIB_CRYPTO name _PU + 'DIRECTORYSTRING_new'; + +procedure DIRECTORYSTRING_free(a: PASN1_STRING); cdecl; + external LIB_CRYPTO name _PU + 'DIRECTORYSTRING_free'; + +function d2i_DIRECTORYSTRING(a: PPASN1_STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_STRING; cdecl; + external LIB_CRYPTO name _PU + 'd2i_DIRECTORYSTRING'; + +function i2d_DIRECTORYSTRING(a: PASN1_STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_DIRECTORYSTRING'; + +function DIRECTORYSTRING_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'DIRECTORYSTRING_it'; + +function DISPLAYTEXT_new(): PASN1_STRING; cdecl; + external LIB_CRYPTO name _PU + 'DISPLAYTEXT_new'; + +procedure DISPLAYTEXT_free(a: PASN1_STRING); cdecl; + external LIB_CRYPTO name _PU + 'DISPLAYTEXT_free'; + +function d2i_DISPLAYTEXT(a: PPASN1_STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_STRING; cdecl; + external LIB_CRYPTO name _PU + 'd2i_DISPLAYTEXT'; + +function i2d_DISPLAYTEXT(a: PASN1_STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_DISPLAYTEXT'; + +function DISPLAYTEXT_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'DISPLAYTEXT_it'; + +function ASN1_PRINTABLESTRING_new(): PASN1_PRINTABLESTRING; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PRINTABLESTRING_new'; + +procedure ASN1_PRINTABLESTRING_free(a: PASN1_PRINTABLESTRING); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PRINTABLESTRING_free'; + +function d2i_ASN1_PRINTABLESTRING(a: PPASN1_PRINTABLESTRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_PRINTABLESTRING; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_PRINTABLESTRING'; + +function i2d_ASN1_PRINTABLESTRING(a: PASN1_PRINTABLESTRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_PRINTABLESTRING'; + +function ASN1_PRINTABLESTRING_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PRINTABLESTRING_it'; + +function ASN1_T61STRING_new(): PASN1_T61STRING; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_T61STRING_new'; + +procedure ASN1_T61STRING_free(a: PASN1_T61STRING); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_T61STRING_free'; + +function d2i_ASN1_T61STRING(a: PPASN1_T61STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_T61STRING; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_T61STRING'; + +function i2d_ASN1_T61STRING(a: PASN1_T61STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_T61STRING'; + +function ASN1_T61STRING_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_T61STRING_it'; + +function ASN1_IA5STRING_new(): PASN1_IA5STRING; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_IA5STRING_new'; + +procedure ASN1_IA5STRING_free(a: PASN1_IA5STRING); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_IA5STRING_free'; + +function d2i_ASN1_IA5STRING(a: PPASN1_IA5STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_IA5STRING; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_IA5STRING'; + +function i2d_ASN1_IA5STRING(a: PASN1_IA5STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_IA5STRING'; + +function ASN1_IA5STRING_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_IA5STRING_it'; + +function ASN1_GENERALSTRING_new(): PASN1_GENERALSTRING; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_GENERALSTRING_new'; + +procedure ASN1_GENERALSTRING_free(a: PASN1_GENERALSTRING); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_GENERALSTRING_free'; + +function d2i_ASN1_GENERALSTRING(a: PPASN1_GENERALSTRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_GENERALSTRING; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_GENERALSTRING'; + +function i2d_ASN1_GENERALSTRING(a: PASN1_GENERALSTRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_GENERALSTRING'; + +function ASN1_GENERALSTRING_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_GENERALSTRING_it'; + +function ASN1_UTCTIME_new(): PASN1_UTCTIME; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_UTCTIME_new'; + +procedure ASN1_UTCTIME_free(a: PASN1_UTCTIME); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_UTCTIME_free'; + +function d2i_ASN1_UTCTIME(a: PPASN1_UTCTIME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_UTCTIME; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_UTCTIME'; + +function i2d_ASN1_UTCTIME(a: PASN1_UTCTIME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_UTCTIME'; + +function ASN1_UTCTIME_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_UTCTIME_it'; + +function ASN1_GENERALIZEDTIME_new(): PASN1_GENERALIZEDTIME; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_GENERALIZEDTIME_new'; + +procedure ASN1_GENERALIZEDTIME_free(a: PASN1_GENERALIZEDTIME); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_GENERALIZEDTIME_free'; + +function d2i_ASN1_GENERALIZEDTIME(a: PPASN1_GENERALIZEDTIME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_GENERALIZEDTIME; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_GENERALIZEDTIME'; + +function i2d_ASN1_GENERALIZEDTIME(a: PASN1_GENERALIZEDTIME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_GENERALIZEDTIME'; + +function ASN1_GENERALIZEDTIME_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_GENERALIZEDTIME_it'; + +function ASN1_TIME_new(): PASN1_TIME; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TIME_new'; + +procedure ASN1_TIME_free(a: PASN1_TIME); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TIME_free'; + +function d2i_ASN1_TIME(a: PPASN1_TIME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASN1_TIME; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASN1_TIME'; + +function i2d_ASN1_TIME(a: PASN1_TIME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_TIME'; + +function ASN1_TIME_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TIME_it'; + +function ASN1_OCTET_STRING_NDEF_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_OCTET_STRING_NDEF_it'; + +function ASN1_TIME_set(s: PASN1_TIME; t: Longint): PASN1_TIME; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TIME_set'; + +function ASN1_TIME_adj(s: PASN1_TIME; t: Longint; offset_day: Integer; offset_sec: Integer): PASN1_TIME; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TIME_adj'; + +function ASN1_TIME_check(t: PASN1_TIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TIME_check'; + +function ASN1_TIME_to_generalizedtime(t: PASN1_TIME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPASN1_GENERALIZEDTIME): PASN1_GENERALIZEDTIME; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TIME_to_generalizedtime'; + +function ASN1_TIME_set_string(s: PASN1_TIME; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TIME_set_string'; + +function ASN1_TIME_set_string_X509(s: PASN1_TIME; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TIME_set_string_X509'; + +function ASN1_TIME_to_tm(s: PASN1_TIME; tm: Ptm): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TIME_to_tm'; + +function ASN1_TIME_normalize(s: PASN1_TIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TIME_normalize'; + +function ASN1_TIME_cmp_time_t(s: PASN1_TIME; t: Longint): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TIME_cmp_time_t'; + +function ASN1_TIME_compare(a: PASN1_TIME; b: PASN1_TIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TIME_compare'; + +function i2a_ASN1_INTEGER(bp: PBIO; a: PASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2a_ASN1_INTEGER'; + +function a2i_ASN1_INTEGER(bp: PBIO; bs: PASN1_INTEGER; buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; size: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'a2i_ASN1_INTEGER'; + +function i2a_ASN1_ENUMERATED(bp: PBIO; a: PASN1_ENUMERATED): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2a_ASN1_ENUMERATED'; + +function a2i_ASN1_ENUMERATED(bp: PBIO; bs: PASN1_ENUMERATED; buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; size: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'a2i_ASN1_ENUMERATED'; + +function i2a_ASN1_OBJECT(bp: PBIO; a: PASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2a_ASN1_OBJECT'; + +function a2i_ASN1_STRING(bp: PBIO; bs: PASN1_STRING; buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; size: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'a2i_ASN1_STRING'; + +function i2a_ASN1_STRING(bp: PBIO; a: PASN1_STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2a_ASN1_STRING'; + +function i2t_ASN1_OBJECT(buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; buf_len: Integer; a: PASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2t_ASN1_OBJECT'; + +function a2d_ASN1_OBJECT({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; olen: Integer; buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; num: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'a2d_ASN1_OBJECT'; + +function ASN1_OBJECT_create(nid: Integer; data: PByte; len: Integer; sn: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ln: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_OBJECT_create'; + +function ASN1_INTEGER_get_int64(pr: PInt64; a: PASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_INTEGER_get_int64'; + +function ASN1_INTEGER_set_int64(a: PASN1_INTEGER; r: Int64): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_INTEGER_set_int64'; + +function ASN1_INTEGER_get_uint64(pr: PUInt64; a: PASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_INTEGER_get_uint64'; + +function ASN1_INTEGER_set_uint64(a: PASN1_INTEGER; r: UInt64): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_INTEGER_set_uint64'; + +function ASN1_INTEGER_set(a: PASN1_INTEGER; v: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_INTEGER_set'; + +function ASN1_INTEGER_get(a: PASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_INTEGER_get'; + +function BN_to_ASN1_INTEGER(bn: PBIGNUM; ai: PASN1_INTEGER): PASN1_INTEGER; cdecl; + external LIB_CRYPTO name _PU + 'BN_to_ASN1_INTEGER'; + +function ASN1_INTEGER_to_BN(ai: PASN1_INTEGER; bn: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_INTEGER_to_BN'; + +function ASN1_ENUMERATED_get_int64(pr: PInt64; a: PASN1_ENUMERATED): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_ENUMERATED_get_int64'; + +function ASN1_ENUMERATED_set_int64(a: PASN1_ENUMERATED; r: Int64): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_ENUMERATED_set_int64'; + +function ASN1_ENUMERATED_set(a: PASN1_ENUMERATED; v: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_ENUMERATED_set'; + +function ASN1_ENUMERATED_get(a: PASN1_ENUMERATED): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_ENUMERATED_get'; + +function BN_to_ASN1_ENUMERATED(bn: PBIGNUM; ai: PASN1_ENUMERATED): PASN1_ENUMERATED; cdecl; + external LIB_CRYPTO name _PU + 'BN_to_ASN1_ENUMERATED'; + +function ASN1_ENUMERATED_to_BN(ai: PASN1_ENUMERATED; bn: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_ENUMERATED_to_BN'; + +function ASN1_PRINTABLE_type(s: PByte; max: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PRINTABLE_type'; + +function ASN1_tag2bit(tag: Integer): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_tag2bit'; + +function ASN1_get_object(pp: PPByte; plength: PInteger; ptag: PInteger; pclass: PInteger; omax: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_get_object'; + +function ASN1_check_infinite_end(p: PPByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_check_infinite_end'; + +function ASN1_const_check_infinite_end(p: PPByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_const_check_infinite_end'; + +procedure ASN1_put_object(pp: PPByte; constructed: Integer; length: Integer; tag: Integer; xclass: Integer); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_put_object'; + +function ASN1_put_eoc(pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_put_eoc'; + +function ASN1_object_size(constructed: Integer; length: Integer; tag: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_object_size'; + +function ASN1_dup(i2d: Pi2d_of_void; d2i: Pd2i_of_void; x: Pointer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_dup'; + +function ASN1_item_dup(it: PASN1_ITEM; x: Pointer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_dup'; + +type + ASN1_d2i_fp_xnew = function(): Pointer; cdecl; + +function ASN1_d2i_fp(xnew: ASN1_d2i_fp_xnew; d2i: Pd2i_of_void; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPointer; x: PPointer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_d2i_fp'; + +function ASN1_item_d2i_fp(it: PASN1_ITEM; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPointer; x: Pointer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_d2i_fp'; + +function ASN1_i2d_fp(i2d: Pi2d_of_void; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPointer; x: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_i2d_fp'; + +function ASN1_item_i2d_fp(it: PASN1_ITEM; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPointer; x: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_i2d_fp'; + +function ASN1_STRING_print_ex_fp(fp: PPointer; str: PASN1_STRING; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_print_ex_fp'; + +function ASN1_STRING_to_UTF8({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PASN1_STRING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_to_UTF8'; + +type + ASN1_d2i_bio_xnew = function(): Pointer; cdecl; + +function ASN1_d2i_bio(xnew: ASN1_d2i_bio_xnew; d2i: Pd2i_of_void; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO; x: PPointer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_d2i_bio'; + +function ASN1_item_d2i_bio(it: PASN1_ITEM; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO; x: Pointer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_d2i_bio'; + +function ASN1_i2d_bio(i2d: Pi2d_of_void; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; x: PByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_i2d_bio'; + +function ASN1_item_i2d_bio(it: PASN1_ITEM; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; x: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_i2d_bio'; + +function ASN1_UTCTIME_print(fp: PBIO; a: PASN1_UTCTIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_UTCTIME_print'; + +function ASN1_GENERALIZEDTIME_print(fp: PBIO; a: PASN1_GENERALIZEDTIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_GENERALIZEDTIME_print'; + +function ASN1_TIME_print(fp: PBIO; a: PASN1_TIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TIME_print'; + +function ASN1_STRING_print(bp: PBIO; v: PASN1_STRING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_print'; + +function ASN1_STRING_print_ex({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; str: PASN1_STRING; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_print_ex'; + +function ASN1_buf_print(bp: PBIO; buf: PByte; buflen: NativeUInt; off: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_buf_print'; + +function ASN1_bn_print(bp: PBIO; number: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; num: PBIGNUM; buf: PByte; off: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_bn_print'; + +function ASN1_parse(bp: PBIO; pp: PByte; len: Integer; indent: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_parse'; + +function ASN1_parse_dump(bp: PBIO; pp: PByte; len: Integer; indent: Integer; dump: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_parse_dump'; + +function ASN1_tag2str(tag: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_tag2str'; + +function ASN1_UNIVERSALSTRING_to_string(s: PASN1_UNIVERSALSTRING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_UNIVERSALSTRING_to_string'; + +function ASN1_TYPE_set_octetstring(a: PASN1_TYPE; data: PByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TYPE_set_octetstring'; + +function ASN1_TYPE_get_octetstring(a: PASN1_TYPE; data: PByte; max_len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TYPE_get_octetstring'; + +function ASN1_TYPE_set_int_octetstring(a: PASN1_TYPE; num: Integer; data: PByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TYPE_set_int_octetstring'; + +function ASN1_TYPE_get_int_octetstring(a: PASN1_TYPE; num: PInteger; data: PByte; max_len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TYPE_get_int_octetstring'; + +function ASN1_item_unpack(oct: PASN1_STRING; it: PASN1_ITEM): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_unpack'; + +function ASN1_item_pack(obj: Pointer; it: PASN1_ITEM; oct: PPASN1_OCTET_STRING): PASN1_STRING; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_pack'; + +procedure ASN1_STRING_set_default_mask(mask: Cardinal); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_set_default_mask'; + +function ASN1_STRING_set_default_mask_asc(p: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_set_default_mask_asc'; + +function ASN1_STRING_get_default_mask(): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_get_default_mask'; + +function ASN1_mbstring_copy({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPASN1_STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; len: Integer; inform: Integer; mask: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_mbstring_copy'; + +function ASN1_mbstring_ncopy({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPASN1_STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; len: Integer; inform: Integer; mask: Cardinal; minsize: Integer; maxsize: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_mbstring_ncopy'; + +function ASN1_STRING_set_by_NID({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPASN1_STRING; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inlen: Integer; inform: Integer; nid: Integer): PASN1_STRING; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_set_by_NID'; + +function ASN1_STRING_TABLE_get(nid: Integer): PASN1_STRING_TABLE; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_TABLE_get'; + +function ASN1_STRING_TABLE_add(p1: Integer; p2: Integer; p3: Integer; p4: Cardinal; p5: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_TABLE_add'; + +procedure ASN1_STRING_TABLE_cleanup(); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_STRING_TABLE_cleanup'; + +function ASN1_item_new(it: PASN1_ITEM): PASN1_VALUE; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_new'; + +procedure ASN1_item_free(val: PASN1_VALUE; it: PASN1_ITEM); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_free'; + +function ASN1_item_d2i(val: PPASN1_VALUE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer; it: PASN1_ITEM): PASN1_VALUE; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_d2i'; + +function ASN1_item_i2d(val: PASN1_VALUE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte; it: PASN1_ITEM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_i2d'; + +function ASN1_item_ndef_i2d(val: PASN1_VALUE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte; it: PASN1_ITEM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_ndef_i2d'; + +procedure ASN1_add_oid_module(); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_add_oid_module'; + +procedure ASN1_add_stable_module(); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_add_stable_module'; + +function ASN1_generate_nconf(str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; nconf: PCONF): PASN1_TYPE; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_generate_nconf'; + +function ASN1_generate_v3(str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cnf: PX509V3_CTX): PASN1_TYPE; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_generate_v3'; + +function ASN1_str2mask(str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; pmask: PCardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_str2mask'; + +function ASN1_item_print({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; ifld: PASN1_VALUE; indent: Integer; it: PASN1_ITEM; pctx: PASN1_PCTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_print'; + +function ASN1_PCTX_new(): PASN1_PCTX; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PCTX_new'; + +procedure ASN1_PCTX_free(p: PASN1_PCTX); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PCTX_free'; + +function ASN1_PCTX_get_flags(p: PASN1_PCTX): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PCTX_get_flags'; + +procedure ASN1_PCTX_set_flags(p: PASN1_PCTX; flags: Cardinal); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PCTX_set_flags'; + +function ASN1_PCTX_get_nm_flags(p: PASN1_PCTX): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PCTX_get_nm_flags'; + +procedure ASN1_PCTX_set_nm_flags(p: PASN1_PCTX; flags: Cardinal); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PCTX_set_nm_flags'; + +function ASN1_PCTX_get_cert_flags(p: PASN1_PCTX): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PCTX_get_cert_flags'; + +procedure ASN1_PCTX_set_cert_flags(p: PASN1_PCTX; flags: Cardinal); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PCTX_set_cert_flags'; + +function ASN1_PCTX_get_oid_flags(p: PASN1_PCTX): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PCTX_get_oid_flags'; + +procedure ASN1_PCTX_set_oid_flags(p: PASN1_PCTX; flags: Cardinal); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PCTX_set_oid_flags'; + +function ASN1_PCTX_get_str_flags(p: PASN1_PCTX): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PCTX_get_str_flags'; + +procedure ASN1_PCTX_set_str_flags(p: PASN1_PCTX; flags: Cardinal); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_PCTX_set_str_flags'; + +type + ASN1_SCTX_new_scan_cb = function(ctx: PASN1_SCTX): Integer; cdecl; + +function ASN1_SCTX_new(scan_cb: ASN1_SCTX_new_scan_cb): PASN1_SCTX; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_SCTX_new'; + +procedure ASN1_SCTX_free(p: PASN1_SCTX); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_SCTX_free'; + +function ASN1_SCTX_get_item(p: PASN1_SCTX): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_SCTX_get_item'; + +function ASN1_SCTX_get_template(p: PASN1_SCTX): PASN1_TEMPLATE; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_SCTX_get_template'; + +function ASN1_SCTX_get_flags(p: PASN1_SCTX): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_SCTX_get_flags'; + +procedure ASN1_SCTX_set_app_data(p: PASN1_SCTX; data: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_SCTX_set_app_data'; + +function ASN1_SCTX_get_app_data(p: PASN1_SCTX): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_SCTX_get_app_data'; + +function BIO_f_asn1(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_f_asn1'; + +function BIO_new_NDEF({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; val: PASN1_VALUE; it: PASN1_ITEM): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_new_NDEF'; + +function i2d_ASN1_bio_stream({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; val: PASN1_VALUE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO; flags: Integer; it: PASN1_ITEM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASN1_bio_stream'; + +function PEM_write_bio_ASN1_stream({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; val: PASN1_VALUE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO; flags: Integer; hdr: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; it: PASN1_ITEM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_ASN1_stream'; + +function SMIME_write_ASN1(bio: PBIO; val: PASN1_VALUE; data: PBIO; flags: Integer; ctype_nid: Integer; econt_nid: Integer; mdalgs: Pstack_st_X509_ALGOR; it: PASN1_ITEM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SMIME_write_ASN1'; + +function SMIME_read_ASN1(bio: PBIO; bcont: PPBIO; it: PASN1_ITEM): PASN1_VALUE; cdecl; + external LIB_CRYPTO name _PU + 'SMIME_read_ASN1'; + +function SMIME_crlf_copy({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SMIME_crlf_copy'; + +function SMIME_text({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SMIME_text'; + +function ASN1_ITEM_lookup(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_ITEM_lookup'; + +function ASN1_ITEM_get(i: NativeUInt): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_ITEM_get'; + +function ASN1_BOOLEAN_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_BOOLEAN_it'; + +function ASN1_TBOOLEAN_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_TBOOLEAN_it'; + +function ASN1_FBOOLEAN_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_FBOOLEAN_it'; + +function ASN1_SEQUENCE_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_SEQUENCE_it'; + +function CBIGNUM_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'CBIGNUM_it'; + +function BIGNUM_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'BIGNUM_it'; + +function INT32_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'INT32_it'; + +function ZINT32_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ZINT32_it'; + +function UINT32_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'UINT32_it'; + +function ZUINT32_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ZUINT32_it'; + +function INT64_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'INT64_it'; + +function ZINT64_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ZINT64_it'; + +function UINT64_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'UINT64_it'; + +function ZUINT64_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ZUINT64_it'; + +function LONG_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'LONG_it'; + +function ZLONG_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ZLONG_it'; + +function ASN1_item_ex_new(pval: PPASN1_VALUE; it: PASN1_ITEM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_ex_new'; + +procedure ASN1_item_ex_free(pval: PPASN1_VALUE; it: PASN1_ITEM); cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_ex_free'; + +function ASN1_item_ex_d2i(pval: PPASN1_VALUE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer; it: PASN1_ITEM; tag: Integer; aclass: Integer; opt: {$IFNDEF FPC}{$IF CompilerVersion > 21}UTF8Char{$ELSE}WideChar{$IFEND}{$ELSE}UTF8Char{$ENDIF}; ctx: PASN1_TLC): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_ex_d2i'; + +function ASN1_item_ex_i2d(pval: PPASN1_VALUE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte; it: PASN1_ITEM; tag: Integer; aclass: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_ex_i2d'; + +function ERR_load_ASYNC_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_ASYNC_strings'; + +function ASYNC_init_thread(max_size: NativeUInt; init_size: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASYNC_init_thread'; + +procedure ASYNC_cleanup_thread(); cdecl; + external LIB_CRYPTO name _PU + 'ASYNC_cleanup_thread'; + +function ASYNC_is_capable(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASYNC_is_capable'; + +type + ASYNC_start_job_func = function(p1: Pointer): Integer; cdecl; + +function ASYNC_start_job(job: PPASYNC_JOB; ctx: PASYNC_WAIT_CTX; ret: PInteger; func: ASYNC_start_job_func; args: Pointer; size: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASYNC_start_job'; + +function ASYNC_pause_job(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASYNC_pause_job'; + +function ASYNC_get_current_job(): PASYNC_JOB; cdecl; + external LIB_CRYPTO name _PU + 'ASYNC_get_current_job'; + +function ASYNC_get_wait_ctx(job: PASYNC_JOB): PASYNC_WAIT_CTX; cdecl; + external LIB_CRYPTO name _PU + 'ASYNC_get_wait_ctx'; + +procedure ASYNC_block_pause(); cdecl; + external LIB_CRYPTO name _PU + 'ASYNC_block_pause'; + +procedure ASYNC_unblock_pause(); cdecl; + external LIB_CRYPTO name _PU + 'ASYNC_unblock_pause'; + +procedure BF_set_key(key: PBF_KEY; len: Integer; data: PByte); cdecl; + external LIB_CRYPTO name _PU + 'BF_set_key'; + +procedure BF_encrypt(data: PCardinal; key: PBF_KEY); cdecl; + external LIB_CRYPTO name _PU + 'BF_encrypt'; + +procedure BF_decrypt(data: PCardinal; key: PBF_KEY); cdecl; + external LIB_CRYPTO name _PU + 'BF_decrypt'; + +procedure BF_ecb_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; key: PBF_KEY; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'BF_ecb_encrypt'; + +procedure BF_cbc_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: Integer; schedule: PBF_KEY; ivec: PByte; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'BF_cbc_encrypt'; + +procedure BF_cfb64_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: Integer; schedule: PBF_KEY; ivec: PByte; num: PInteger; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'BF_cfb64_encrypt'; + +procedure BF_ofb64_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: Integer; schedule: PBF_KEY; ivec: PByte; num: PInteger); cdecl; + external LIB_CRYPTO name _PU + 'BF_ofb64_encrypt'; + +function BF_options(): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'BF_options'; + +function ERR_load_BUF_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_BUF_strings'; + +function BUF_MEM_new(): PBUF_MEM; cdecl; + external LIB_CRYPTO name _PU + 'BUF_MEM_new'; + +function BUF_MEM_new_ex(flags: Cardinal): PBUF_MEM; cdecl; + external LIB_CRYPTO name _PU + 'BUF_MEM_new_ex'; + +procedure BUF_MEM_free(a: PBUF_MEM); cdecl; + external LIB_CRYPTO name _PU + 'BUF_MEM_free'; + +function BUF_MEM_grow(str: PBUF_MEM; len: NativeUInt): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'BUF_MEM_grow'; + +function BUF_MEM_grow_clean(str: PBUF_MEM; len: NativeUInt): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'BUF_MEM_grow_clean'; + +procedure BUF_reverse({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; siz: NativeUInt); cdecl; + external LIB_CRYPTO name _PU + 'BUF_reverse'; + +function Camellia_set_key(userKey: PByte; bits: Integer; key: PCAMELLIA_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'Camellia_set_key'; + +procedure Camellia_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; key: PCAMELLIA_KEY); cdecl; + external LIB_CRYPTO name _PU + 'Camellia_encrypt'; + +procedure Camellia_decrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; key: PCAMELLIA_KEY); cdecl; + external LIB_CRYPTO name _PU + 'Camellia_decrypt'; + +procedure Camellia_ecb_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; key: PCAMELLIA_KEY; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'Camellia_ecb_encrypt'; + +procedure Camellia_cbc_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: NativeUInt; key: PCAMELLIA_KEY; ivec: PByte; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'Camellia_cbc_encrypt'; + +procedure Camellia_cfb128_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: NativeUInt; key: PCAMELLIA_KEY; ivec: PByte; num: PInteger; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'Camellia_cfb128_encrypt'; + +procedure Camellia_cfb1_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: NativeUInt; key: PCAMELLIA_KEY; ivec: PByte; num: PInteger; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'Camellia_cfb1_encrypt'; + +procedure Camellia_cfb8_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: NativeUInt; key: PCAMELLIA_KEY; ivec: PByte; num: PInteger; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'Camellia_cfb8_encrypt'; + +procedure Camellia_ofb128_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: NativeUInt; key: PCAMELLIA_KEY; ivec: PByte; num: PInteger); cdecl; + external LIB_CRYPTO name _PU + 'Camellia_ofb128_encrypt'; + +procedure Camellia_ctr128_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: NativeUInt; key: PCAMELLIA_KEY; ivec: PByte; ecount_buf: PByte; num: PCardinal); cdecl; + external LIB_CRYPTO name _PU + 'Camellia_ctr128_encrypt'; + +procedure CAST_set_key(key: PCAST_KEY; len: Integer; data: PByte); cdecl; + external LIB_CRYPTO name _PU + 'CAST_set_key'; + +procedure CAST_ecb_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; key: PCAST_KEY; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'CAST_ecb_encrypt'; + +procedure CAST_encrypt(data: PCardinal; key: PCAST_KEY); cdecl; + external LIB_CRYPTO name _PU + 'CAST_encrypt'; + +procedure CAST_decrypt(data: PCardinal; key: PCAST_KEY); cdecl; + external LIB_CRYPTO name _PU + 'CAST_decrypt'; + +procedure CAST_cbc_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: Integer; ks: PCAST_KEY; iv: PByte; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'CAST_cbc_encrypt'; + +procedure CAST_cfb64_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: Integer; schedule: PCAST_KEY; ivec: PByte; num: PInteger; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'CAST_cfb64_encrypt'; + +procedure CAST_ofb64_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: Integer; schedule: PCAST_KEY; ivec: PByte; num: PInteger); cdecl; + external LIB_CRYPTO name _PU + 'CAST_ofb64_encrypt'; + +function ERR_load_EVP_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_EVP_strings'; + +function ERR_load_OBJ_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_OBJ_strings'; + +function OBJ_NAME_init(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_NAME_init'; + +type + OBJ_NAME_new_index_hash_func = function(p1: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Cardinal; cdecl; + +type + OBJ_NAME_new_index_cmp_func = function(p1: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; p2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + +type + OBJ_NAME_new_index_free_func = procedure(p1: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; p2: Integer; p3: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}); cdecl; + +function OBJ_NAME_new_index(hash_func: OBJ_NAME_new_index_hash_func; cmp_func: OBJ_NAME_new_index_cmp_func; free_func: OBJ_NAME_new_index_free_func): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_NAME_new_index'; + +function OBJ_NAME_get(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_NAME_get'; + +function OBJ_NAME_add(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; data: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_NAME_add'; + +function OBJ_NAME_remove(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_NAME_remove'; + +procedure OBJ_NAME_cleanup({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer); cdecl; + external LIB_CRYPTO name _PU + 'OBJ_NAME_cleanup'; + +type + OBJ_NAME_do_all_fn = procedure(p1: POBJ_NAME; arg: Pointer); cdecl; + +procedure OBJ_NAME_do_all({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; fn: OBJ_NAME_do_all_fn; arg: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'OBJ_NAME_do_all'; + +type + OBJ_NAME_do_all_sorted_fn = procedure(p1: POBJ_NAME; arg: Pointer); cdecl; + +procedure OBJ_NAME_do_all_sorted({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; fn: OBJ_NAME_do_all_sorted_fn; arg: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'OBJ_NAME_do_all_sorted'; + +function OBJ_dup(o: PASN1_OBJECT): PASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_dup'; + +function OBJ_nid2obj(n: Integer): PASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_nid2obj'; + +function OBJ_nid2ln(n: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_nid2ln'; + +function OBJ_nid2sn(n: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_nid2sn'; + +function OBJ_obj2nid(o: PASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_obj2nid'; + +function OBJ_txt2obj(s: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; no_name: Integer): PASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_txt2obj'; + +function OBJ_obj2txt(buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; buf_len: Integer; a: PASN1_OBJECT; no_name: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_obj2txt'; + +function OBJ_txt2nid(s: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_txt2nid'; + +function OBJ_ln2nid(s: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_ln2nid'; + +function OBJ_sn2nid(s: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_sn2nid'; + +function OBJ_cmp(a: PASN1_OBJECT; b: PASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_cmp'; + +type + OBJ_bsearch__cmp = function(p1: Pointer; p2: Pointer): Integer; cdecl; + +function OBJ_bsearch_(key: Pointer; base: Pointer; num: Integer; size: Integer; cmp: OBJ_bsearch__cmp): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_bsearch_'; + +type + OBJ_bsearch_ex__cmp = function(p1: Pointer; p2: Pointer): Integer; cdecl; + +function OBJ_bsearch_ex_(key: Pointer; base: Pointer; num: Integer; size: Integer; cmp: OBJ_bsearch_ex__cmp; flags: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_bsearch_ex_'; + +function OBJ_new_nid(num: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_new_nid'; + +function OBJ_add_object(obj: PASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_add_object'; + +function OBJ_create(oid: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; sn: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ln: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_create'; + +function OBJ_create_objects({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_create_objects'; + +function OBJ_length(obj: PASN1_OBJECT): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_length'; + +function OBJ_get0_data(obj: PASN1_OBJECT): PByte; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_get0_data'; + +function OBJ_find_sigid_algs(signid: Integer; pdig_nid: PInteger; ppkey_nid: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_find_sigid_algs'; + +function OBJ_find_sigid_by_algs(psignid: PInteger; dig_nid: Integer; pkey_nid: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_find_sigid_by_algs'; + +function OBJ_add_sigid(signid: Integer; dig_id: Integer; pkey_id: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OBJ_add_sigid'; + +procedure OBJ_sigid_free(); cdecl; + external LIB_CRYPTO name _PU + 'OBJ_sigid_free'; + +function EVP_MD_meth_new(md_type: Integer; pkey_type: Integer): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_meth_new'; + +function EVP_MD_meth_dup(md: PEVP_MD): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_meth_dup'; + +procedure EVP_MD_meth_free(md: PEVP_MD); cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_meth_free'; + +function EVP_MD_meth_set_input_blocksize(md: PEVP_MD; blocksize: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_meth_set_input_blocksize'; + +function EVP_MD_meth_set_result_size(md: PEVP_MD; resultsize: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_meth_set_result_size'; + +function EVP_MD_meth_set_app_datasize(md: PEVP_MD; datasize: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_meth_set_app_datasize'; + +function EVP_MD_meth_set_flags(md: PEVP_MD; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_meth_set_flags'; + +type + EVP_MD_meth_set_init_init = function(ctx: PEVP_MD_CTX): Integer; cdecl; + +function EVP_MD_meth_set_init(md: PEVP_MD; init: EVP_MD_meth_set_init_init): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_meth_set_init'; + +type + EVP_MD_meth_set_update_update = function(ctx: PEVP_MD_CTX; data: Pointer; count: NativeUInt): Integer; cdecl; + +function EVP_MD_meth_set_update(md: PEVP_MD; update: EVP_MD_meth_set_update_update): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_meth_set_update'; + +type + EVP_MD_meth_set_final_final = function(ctx: PEVP_MD_CTX; md: PByte): Integer; cdecl; + +function EVP_MD_meth_set_final(md: PEVP_MD; {$IFNDEF FPC}{$IF CompilerVersion > 21}&final{$ELSE}final1{$IFEND}{$ELSE}&final{$ENDIF}: EVP_MD_meth_set_final_final): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_meth_set_final'; + +type + EVP_MD_meth_set_copy_copy = function({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PEVP_MD_CTX; from: PEVP_MD_CTX): Integer; cdecl; + +function EVP_MD_meth_set_copy(md: PEVP_MD; copy: EVP_MD_meth_set_copy_copy): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_meth_set_copy'; + +type + EVP_MD_meth_set_cleanup_cleanup = function(ctx: PEVP_MD_CTX): Integer; cdecl; + +function EVP_MD_meth_set_cleanup(md: PEVP_MD; cleanup: EVP_MD_meth_set_cleanup_cleanup): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_meth_set_cleanup'; + +type + EVP_MD_meth_set_ctrl_ctrl = function(ctx: PEVP_MD_CTX; cmd: Integer; p1: Integer; p2: Pointer): Integer; cdecl; + +function EVP_MD_meth_set_ctrl(md: PEVP_MD; ctrl: EVP_MD_meth_set_ctrl_ctrl): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_meth_set_ctrl'; + +function EVP_MD_meth_get_input_blocksize(md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_meth_get_input_blocksize'; + +function EVP_MD_meth_get_result_size(md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_meth_get_result_size'; + +function EVP_MD_meth_get_app_datasize(md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_meth_get_app_datasize'; + +function EVP_MD_meth_get_flags(md: PEVP_MD): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_meth_get_flags'; + +//function EVP_MD_meth_get_init(ctx: PEVP_MD_CTXmd: PEVP_MD): Integer { TODO : Cannot convert original type "int (*)(EVP_MD_CTX *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'EVP_MD_meth_get_init'; + +//function EVP_MD_meth_get_update(ctx: PEVP_MD_CTXdata: Pointercount: NativeUIntmd: PEVP_MD): Integer { TODO : Cannot convert original type "int (*)(EVP_MD_CTX *, const void *, size_t)" }; cdecl; +// external LIB_CRYPTO name _PU + 'EVP_MD_meth_get_update'; + +//function EVP_MD_meth_get_final(ctx: PEVP_MD_CTXmd: PBytemd: PEVP_MD): Integer { TODO : Cannot convert original type "int (*)(EVP_MD_CTX *, unsigned char *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'EVP_MD_meth_get_final'; + +//function EVP_MD_meth_get_copy({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PEVP_MD_CTXfrom: PEVP_MD_CTXmd: PEVP_MD): Integer { TODO : Cannot convert original type "int (*)(EVP_MD_CTX *, const EVP_MD_CTX *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'EVP_MD_meth_get_copy'; + +//function EVP_MD_meth_get_cleanup(ctx: PEVP_MD_CTXmd: PEVP_MD): Integer { TODO : Cannot convert original type "int (*)(EVP_MD_CTX *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'EVP_MD_meth_get_cleanup'; + +//function EVP_MD_meth_get_ctrl(ctx: PEVP_MD_CTXcmd: Integerp1: Integerp2: Pointermd: PEVP_MD): Integer { TODO : Cannot convert original type "int (*)(EVP_MD_CTX *, int, int, void *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'EVP_MD_meth_get_ctrl'; + +function EVP_CIPHER_meth_new(cipher_type: Integer; block_size: Integer; key_len: Integer): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_meth_new'; + +function EVP_CIPHER_meth_dup(cipher: PEVP_CIPHER): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_meth_dup'; + +procedure EVP_CIPHER_meth_free(cipher: PEVP_CIPHER); cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_meth_free'; + +function EVP_CIPHER_meth_set_iv_length(cipher: PEVP_CIPHER; iv_len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_meth_set_iv_length'; + +function EVP_CIPHER_meth_set_flags(cipher: PEVP_CIPHER; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_meth_set_flags'; + +function EVP_CIPHER_meth_set_impl_ctx_size(cipher: PEVP_CIPHER; ctx_size: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_meth_set_impl_ctx_size'; + +type + EVP_CIPHER_meth_set_init_init = function(ctx: PEVP_CIPHER_CTX; key: PByte; iv: PByte; enc: Integer): Integer; cdecl; + +function EVP_CIPHER_meth_set_init(cipher: PEVP_CIPHER; init: EVP_CIPHER_meth_set_init_init): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_meth_set_init'; + +type + EVP_CIPHER_meth_set_do_cipher_do_cipher = function(ctx: PEVP_CIPHER_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inl: NativeUInt): Integer; cdecl; + +function EVP_CIPHER_meth_set_do_cipher(cipher: PEVP_CIPHER; do_cipher: EVP_CIPHER_meth_set_do_cipher_do_cipher): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_meth_set_do_cipher'; + +type + EVP_CIPHER_meth_set_cleanup_cleanup = function(p1: PEVP_CIPHER_CTX): Integer; cdecl; + +function EVP_CIPHER_meth_set_cleanup(cipher: PEVP_CIPHER; cleanup: EVP_CIPHER_meth_set_cleanup_cleanup): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_meth_set_cleanup'; + +type + EVP_CIPHER_meth_set_set_asn1_params_set_asn1_parameters = function(p1: PEVP_CIPHER_CTX; p2: PASN1_TYPE): Integer; cdecl; + +function EVP_CIPHER_meth_set_set_asn1_params(cipher: PEVP_CIPHER; set_asn1_parameters: EVP_CIPHER_meth_set_set_asn1_params_set_asn1_parameters): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_meth_set_set_asn1_params'; + +type + EVP_CIPHER_meth_set_get_asn1_params_get_asn1_parameters = function(p1: PEVP_CIPHER_CTX; p2: PASN1_TYPE): Integer; cdecl; + +function EVP_CIPHER_meth_set_get_asn1_params(cipher: PEVP_CIPHER; get_asn1_parameters: EVP_CIPHER_meth_set_get_asn1_params_get_asn1_parameters): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_meth_set_get_asn1_params'; + +type + EVP_CIPHER_meth_set_ctrl_ctrl = function(p1: PEVP_CIPHER_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; arg: Integer; ptr: Pointer): Integer; cdecl; + +function EVP_CIPHER_meth_set_ctrl(cipher: PEVP_CIPHER; ctrl: EVP_CIPHER_meth_set_ctrl_ctrl): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_meth_set_ctrl'; + +//function EVP_CIPHER_meth_get_init(ctx: PEVP_CIPHER_CTXkey: PByteiv: PByteenc: Integercipher: PEVP_CIPHER): Integer { TODO : Cannot convert original type "int (*)(EVP_CIPHER_CTX *, const unsigned char *, const unsigned char *, int)" }; cdecl; +// external LIB_CRYPTO name _PU + 'EVP_CIPHER_meth_get_init'; + +//function EVP_CIPHER_meth_get_do_cipher(ctx: PEVP_CIPHER_CTX{$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte{$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByteinl: NativeUIntcipher: PEVP_CIPHER): Integer { TODO : Cannot convert original type "int (*)(EVP_CIPHER_CTX *, unsigned char *, const unsigned char *, size_t)" }; cdecl; +// external LIB_CRYPTO name _PU + 'EVP_CIPHER_meth_get_do_cipher'; + +//function EVP_CIPHER_meth_get_cleanup(p1: PEVP_CIPHER_CTXcipher: PEVP_CIPHER): Integer { TODO : Cannot convert original type "int (*)(EVP_CIPHER_CTX *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'EVP_CIPHER_meth_get_cleanup'; + +//function EVP_CIPHER_meth_get_set_asn1_params(p1: PEVP_CIPHER_CTXp2: PASN1_TYPEcipher: PEVP_CIPHER): Integer { TODO : Cannot convert original type "int (*)(EVP_CIPHER_CTX *, ASN1_TYPE *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'EVP_CIPHER_meth_get_set_asn1_params'; + +//function EVP_CIPHER_meth_get_get_asn1_params(p1: PEVP_CIPHER_CTXp2: PASN1_TYPEcipher: PEVP_CIPHER): Integer { TODO : Cannot convert original type "int (*)(EVP_CIPHER_CTX *, ASN1_TYPE *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'EVP_CIPHER_meth_get_get_asn1_params'; + +//function EVP_CIPHER_meth_get_ctrl(p1: PEVP_CIPHER_CTX{$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integerarg: Integerptr: Pointercipher: PEVP_CIPHER): Integer { TODO : Cannot convert original type "int (*)(EVP_CIPHER_CTX *, int, int, void *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'EVP_CIPHER_meth_get_ctrl'; + +function EVP_MD_type(md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_type'; + +function EVP_MD_pkey_type(md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_pkey_type'; + +function EVP_MD_size(md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_size'; + +function EVP_MD_block_size(md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_block_size'; + +function EVP_MD_flags(md: PEVP_MD): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_flags'; + +function EVP_MD_CTX_md(ctx: PEVP_MD_CTX): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_CTX_md'; + +//function EVP_MD_CTX_update_fn(ctx: PEVP_MD_CTXdata: Pointercount: NativeUIntctx: PEVP_MD_CTX): Integer { TODO : Cannot convert original type "int (*)(EVP_MD_CTX *, const void *, size_t)" }; cdecl; +// external LIB_CRYPTO name _PU + 'EVP_MD_CTX_update_fn'; + +type + EVP_MD_CTX_set_update_fn_update = function(ctx: PEVP_MD_CTX; data: Pointer; count: NativeUInt): Integer; cdecl; + +procedure EVP_MD_CTX_set_update_fn(ctx: PEVP_MD_CTX; update: EVP_MD_CTX_set_update_fn_update); cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_CTX_set_update_fn'; + +function EVP_MD_CTX_pkey_ctx(ctx: PEVP_MD_CTX): PEVP_PKEY_CTX; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_CTX_pkey_ctx'; + +procedure EVP_MD_CTX_set_pkey_ctx(ctx: PEVP_MD_CTX; pctx: PEVP_PKEY_CTX); cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_CTX_set_pkey_ctx'; + +function EVP_MD_CTX_md_data(ctx: PEVP_MD_CTX): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_CTX_md_data'; + +function EVP_CIPHER_nid(cipher: PEVP_CIPHER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_nid'; + +function EVP_CIPHER_block_size(cipher: PEVP_CIPHER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_block_size'; + +function EVP_CIPHER_impl_ctx_size(cipher: PEVP_CIPHER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_impl_ctx_size'; + +function EVP_CIPHER_key_length(cipher: PEVP_CIPHER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_key_length'; + +function EVP_CIPHER_iv_length(cipher: PEVP_CIPHER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_iv_length'; + +function EVP_CIPHER_flags(cipher: PEVP_CIPHER): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_flags'; + +function EVP_CIPHER_CTX_cipher(ctx: PEVP_CIPHER_CTX): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_cipher'; + +function EVP_CIPHER_CTX_encrypting(ctx: PEVP_CIPHER_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_encrypting'; + +function EVP_CIPHER_CTX_nid(ctx: PEVP_CIPHER_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_nid'; + +function EVP_CIPHER_CTX_block_size(ctx: PEVP_CIPHER_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_block_size'; + +function EVP_CIPHER_CTX_key_length(ctx: PEVP_CIPHER_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_key_length'; + +function EVP_CIPHER_CTX_iv_length(ctx: PEVP_CIPHER_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_iv_length'; + +function EVP_CIPHER_CTX_iv(ctx: PEVP_CIPHER_CTX): PByte; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_iv'; + +function EVP_CIPHER_CTX_original_iv(ctx: PEVP_CIPHER_CTX): PByte; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_original_iv'; + +function EVP_CIPHER_CTX_iv_noconst(ctx: PEVP_CIPHER_CTX): PByte; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_iv_noconst'; + +function EVP_CIPHER_CTX_buf_noconst(ctx: PEVP_CIPHER_CTX): PByte; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_buf_noconst'; + +function EVP_CIPHER_CTX_num(ctx: PEVP_CIPHER_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_num'; + +procedure EVP_CIPHER_CTX_set_num(ctx: PEVP_CIPHER_CTX; num: Integer); cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_set_num'; + +function EVP_CIPHER_CTX_copy({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PEVP_CIPHER_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PEVP_CIPHER_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_copy'; + +function EVP_CIPHER_CTX_get_app_data(ctx: PEVP_CIPHER_CTX): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_get_app_data'; + +procedure EVP_CIPHER_CTX_set_app_data(ctx: PEVP_CIPHER_CTX; data: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_set_app_data'; + +function EVP_CIPHER_CTX_get_cipher_data(ctx: PEVP_CIPHER_CTX): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_get_cipher_data'; + +function EVP_CIPHER_CTX_set_cipher_data(ctx: PEVP_CIPHER_CTX; cipher_data: Pointer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_set_cipher_data'; + +function EVP_Cipher(c: PEVP_CIPHER_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inl: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_Cipher'; + +function EVP_MD_CTX_ctrl(ctx: PEVP_MD_CTX; cmd: Integer; p1: Integer; p2: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_CTX_ctrl'; + +function EVP_MD_CTX_new(): PEVP_MD_CTX; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_CTX_new'; +function EVP_MD_CTX_create(): PEVP_MD_CTX; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_CTX_new'; + +function EVP_MD_CTX_reset(ctx: PEVP_MD_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_CTX_reset'; + +procedure EVP_MD_CTX_free(ctx: PEVP_MD_CTX); cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_CTX_free'; +procedure EVP_MD_CTX_destroy(ctx: PEVP_MD_CTX); cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_CTX_free'; + +function EVP_MD_CTX_copy_ex({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PEVP_MD_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PEVP_MD_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_CTX_copy_ex'; + +procedure EVP_MD_CTX_set_flags(ctx: PEVP_MD_CTX; flags: Integer); cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_CTX_set_flags'; + +procedure EVP_MD_CTX_clear_flags(ctx: PEVP_MD_CTX; flags: Integer); cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_CTX_clear_flags'; + +function EVP_MD_CTX_test_flags(ctx: PEVP_MD_CTX; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_CTX_test_flags'; + +function EVP_DigestInit_ex(ctx: PEVP_MD_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_MD; impl: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DigestInit_ex'; + +function EVP_DigestUpdate(ctx: PEVP_MD_CTX; d: Pointer; cnt: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DigestUpdate'; + +function EVP_DigestFinal_ex(ctx: PEVP_MD_CTX; md: PByte; s: PCardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DigestFinal_ex'; + +function EVP_Digest(data: Pointer; count: NativeUInt; md: PByte; size: PCardinal; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_MD; impl: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_Digest'; + +function EVP_MD_CTX_copy({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PEVP_MD_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PEVP_MD_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_CTX_copy'; + +function EVP_DigestInit(ctx: PEVP_MD_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DigestInit'; + +function EVP_DigestFinal(ctx: PEVP_MD_CTX; md: PByte; s: PCardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DigestFinal'; + +function EVP_DigestFinalXOF(ctx: PEVP_MD_CTX; md: PByte; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DigestFinalXOF'; + +function EVP_read_pw_string(buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; length: Integer; prompt: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; verify: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_read_pw_string'; + +function EVP_read_pw_string_min(buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; minlen: Integer; maxlen: Integer; prompt: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; verify: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_read_pw_string_min'; + +procedure EVP_set_pw_prompt(prompt: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}); cdecl; + external LIB_CRYPTO name _PU + 'EVP_set_pw_prompt'; + +function EVP_get_pw_prompt(): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'EVP_get_pw_prompt'; + +function EVP_BytesToKey({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_CIPHER; md: PEVP_MD; salt: PByte; data: PByte; datal: Integer; count: Integer; key: PByte; iv: PByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_BytesToKey'; + +procedure EVP_CIPHER_CTX_set_flags(ctx: PEVP_CIPHER_CTX; flags: Integer); cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_set_flags'; + +procedure EVP_CIPHER_CTX_clear_flags(ctx: PEVP_CIPHER_CTX; flags: Integer); cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_clear_flags'; + +function EVP_CIPHER_CTX_test_flags(ctx: PEVP_CIPHER_CTX; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_test_flags'; + +function EVP_EncryptInit(ctx: PEVP_CIPHER_CTX; cipher: PEVP_CIPHER; key: PByte; iv: PByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_EncryptInit'; + +function EVP_EncryptInit_ex(ctx: PEVP_CIPHER_CTX; cipher: PEVP_CIPHER; impl: PENGINE; key: PByte; iv: PByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_EncryptInit_ex'; + +function EVP_EncryptUpdate(ctx: PEVP_CIPHER_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outl: PInteger; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inl: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_EncryptUpdate'; + +function EVP_EncryptFinal_ex(ctx: PEVP_CIPHER_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outl: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_EncryptFinal_ex'; + +function EVP_EncryptFinal(ctx: PEVP_CIPHER_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outl: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_EncryptFinal'; + +function EVP_DecryptInit(ctx: PEVP_CIPHER_CTX; cipher: PEVP_CIPHER; key: PByte; iv: PByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DecryptInit'; + +function EVP_DecryptInit_ex(ctx: PEVP_CIPHER_CTX; cipher: PEVP_CIPHER; impl: PENGINE; key: PByte; iv: PByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DecryptInit_ex'; + +function EVP_DecryptUpdate(ctx: PEVP_CIPHER_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outl: PInteger; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inl: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DecryptUpdate'; + +function EVP_DecryptFinal(ctx: PEVP_CIPHER_CTX; outm: PByte; outl: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DecryptFinal'; + +function EVP_DecryptFinal_ex(ctx: PEVP_CIPHER_CTX; outm: PByte; outl: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DecryptFinal_ex'; + +function EVP_CipherInit(ctx: PEVP_CIPHER_CTX; cipher: PEVP_CIPHER; key: PByte; iv: PByte; enc: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CipherInit'; + +function EVP_CipherInit_ex(ctx: PEVP_CIPHER_CTX; cipher: PEVP_CIPHER; impl: PENGINE; key: PByte; iv: PByte; enc: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CipherInit_ex'; + +function EVP_CipherUpdate(ctx: PEVP_CIPHER_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outl: PInteger; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inl: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CipherUpdate'; + +function EVP_CipherFinal(ctx: PEVP_CIPHER_CTX; outm: PByte; outl: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CipherFinal'; + +function EVP_CipherFinal_ex(ctx: PEVP_CIPHER_CTX; outm: PByte; outl: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CipherFinal_ex'; + +function EVP_SignFinal(ctx: PEVP_MD_CTX; md: PByte; s: PCardinal; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_SignFinal'; + +function EVP_DigestSign(ctx: PEVP_MD_CTX; sigret: PByte; var siglen: NativeUInt; tbs: PByte; tbslen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DigestSign'; + +function EVP_VerifyFinal(ctx: PEVP_MD_CTX; sigbuf: PByte; siglen: Cardinal; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_VerifyFinal'; + +function EVP_DigestVerify(ctx: PEVP_MD_CTX; sigret: PByte; siglen: NativeUInt; tbs: PByte; tbslen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DigestVerify'; + +function EVP_DigestSignInit(ctx: PEVP_MD_CTX; pctx: PPEVP_PKEY_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_MD; e: PENGINE; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DigestSignInit'; + +function EVP_DigestSignFinal(ctx: PEVP_MD_CTX; sigret: PByte; var siglen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DigestSignFinal'; + +function EVP_DigestVerifyInit(ctx: PEVP_MD_CTX; pctx: PPEVP_PKEY_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_MD; e: PENGINE; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DigestVerifyInit'; + +function EVP_DigestVerifyFinal(ctx: PEVP_MD_CTX; sig: PByte; siglen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DigestVerifyFinal'; + +function EVP_OpenInit(ctx: PEVP_CIPHER_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_CIPHER; ek: PByte; ekl: Integer; iv: PByte; priv: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_OpenInit'; + +function EVP_OpenFinal(ctx: PEVP_CIPHER_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outl: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_OpenFinal'; + +function EVP_SealInit(ctx: PEVP_CIPHER_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_CIPHER; ek: PPByte; ekl: PInteger; iv: PByte; pubk: PPEVP_PKEY; npubk: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_SealInit'; + +function EVP_SealFinal(ctx: PEVP_CIPHER_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outl: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_SealFinal'; + +function EVP_ENCODE_CTX_new(): PEVP_ENCODE_CTX; cdecl; + external LIB_CRYPTO name _PU + 'EVP_ENCODE_CTX_new'; + +procedure EVP_ENCODE_CTX_free(ctx: PEVP_ENCODE_CTX); cdecl; + external LIB_CRYPTO name _PU + 'EVP_ENCODE_CTX_free'; + +function EVP_ENCODE_CTX_copy(dctx: PEVP_ENCODE_CTX; sctx: PEVP_ENCODE_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_ENCODE_CTX_copy'; + +function EVP_ENCODE_CTX_num(ctx: PEVP_ENCODE_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_ENCODE_CTX_num'; + +procedure EVP_EncodeInit(ctx: PEVP_ENCODE_CTX); cdecl; + external LIB_CRYPTO name _PU + 'EVP_EncodeInit'; + +function EVP_EncodeUpdate(ctx: PEVP_ENCODE_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outl: PInteger; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inl: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_EncodeUpdate'; + +procedure EVP_EncodeFinal(ctx: PEVP_ENCODE_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outl: PInteger); cdecl; + external LIB_CRYPTO name _PU + 'EVP_EncodeFinal'; + +function EVP_EncodeBlock(t: PByte; f: PByte; n: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_EncodeBlock'; + +procedure EVP_DecodeInit(ctx: PEVP_ENCODE_CTX); cdecl; + external LIB_CRYPTO name _PU + 'EVP_DecodeInit'; + +function EVP_DecodeUpdate(ctx: PEVP_ENCODE_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outl: PInteger; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inl: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DecodeUpdate'; + +function EVP_DecodeFinal(ctx: PEVP_ENCODE_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outl: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DecodeFinal'; + +function EVP_DecodeBlock(t: PByte; f: PByte; n: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_DecodeBlock'; + +function EVP_CIPHER_CTX_new(): PEVP_CIPHER_CTX; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_new'; + +function EVP_CIPHER_CTX_reset(c: PEVP_CIPHER_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_reset'; + +procedure EVP_CIPHER_CTX_free(c: PEVP_CIPHER_CTX); cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_free'; + +function EVP_CIPHER_CTX_set_key_length(x: PEVP_CIPHER_CTX; keylen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_set_key_length'; + +function EVP_CIPHER_CTX_set_padding(c: PEVP_CIPHER_CTX; pad: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_set_padding'; + +function EVP_CIPHER_CTX_ctrl(ctx: PEVP_CIPHER_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; arg: Integer; ptr: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_ctrl'; + +function EVP_CIPHER_CTX_rand_key(ctx: PEVP_CIPHER_CTX; key: PByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_CTX_rand_key'; + +function BIO_f_md(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_f_md'; + +function BIO_f_base64(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_f_base64'; + +function BIO_f_cipher(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_f_cipher'; + +function BIO_f_reliable(): PBIO_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'BIO_f_reliable'; + +function BIO_set_cipher(b: PBIO; c: PEVP_CIPHER; k: PByte; i: PByte; enc: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'BIO_set_cipher'; + +function EVP_md_null(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_md_null'; + +function EVP_md4(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_md4'; + +function EVP_md5(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_md5'; + +function EVP_md5_sha1(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_md5_sha1'; + +function EVP_blake2b512(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_blake2b512'; + +function EVP_blake2s256(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_blake2s256'; + +function EVP_sha1(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_sha1'; + +function EVP_sha224(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_sha224'; + +function EVP_sha256(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_sha256'; + +function EVP_sha384(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_sha384'; + +function EVP_sha512(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_sha512'; + +function EVP_sha512_224(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_sha512_224'; + +function EVP_sha512_256(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_sha512_256'; + +function EVP_sha3_224(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_sha3_224'; + +function EVP_sha3_256(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_sha3_256'; + +function EVP_sha3_384(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_sha3_384'; + +function EVP_sha3_512(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_sha3_512'; + +function EVP_shake128(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_shake128'; + +function EVP_shake256(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_shake256'; + +function EVP_mdc2(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_mdc2'; + +function EVP_ripemd160(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_ripemd160'; + +function EVP_whirlpool(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_whirlpool'; + +function EVP_sm3(): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_sm3'; + +function EVP_enc_null(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_enc_null'; + +function EVP_des_ecb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_ecb'; + +function EVP_des_ede(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_ede'; + +function EVP_des_ede3(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_ede3'; + +function EVP_des_ede_ecb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_ede_ecb'; + +function EVP_des_ede3_ecb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_ede3_ecb'; + +function EVP_des_cfb64(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_cfb64'; +function EVP_des_cfb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_cfb64'; + +function EVP_des_cfb1(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_cfb1'; + +function EVP_des_cfb8(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_cfb8'; + +function EVP_des_ede_cfb64(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_ede_cfb64'; +function EVP_des_ede_cfb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_ede_cfb64'; + +function EVP_des_ede3_cfb64(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_ede3_cfb64'; +function EVP_des_ede3_cfb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_ede3_cfb64'; + +function EVP_des_ede3_cfb1(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_ede3_cfb1'; + +function EVP_des_ede3_cfb8(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_ede3_cfb8'; + +function EVP_des_ofb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_ofb'; + +function EVP_des_ede_ofb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_ede_ofb'; + +function EVP_des_ede3_ofb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_ede3_ofb'; + +function EVP_des_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_cbc'; + +function EVP_des_ede_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_ede_cbc'; + +function EVP_des_ede3_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_ede3_cbc'; + +function EVP_desx_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_desx_cbc'; + +function EVP_des_ede3_wrap(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_des_ede3_wrap'; + +function EVP_rc4(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_rc4'; + +function EVP_rc4_40(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_rc4_40'; + +function EVP_rc4_hmac_md5(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_rc4_hmac_md5'; + +function EVP_idea_ecb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_idea_ecb'; + +function EVP_idea_cfb64(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_idea_cfb64'; +function EVP_idea_cfb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_idea_cfb64'; + +function EVP_idea_ofb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_idea_ofb'; + +function EVP_idea_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_idea_cbc'; + +function EVP_rc2_ecb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_rc2_ecb'; + +function EVP_rc2_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_rc2_cbc'; + +function EVP_rc2_40_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_rc2_40_cbc'; + +function EVP_rc2_64_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_rc2_64_cbc'; + +function EVP_rc2_cfb64(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_rc2_cfb64'; +function EVP_rc2_cfb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_rc2_cfb64'; + +function EVP_rc2_ofb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_rc2_ofb'; + +function EVP_bf_ecb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_bf_ecb'; + +function EVP_bf_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_bf_cbc'; + +function EVP_bf_cfb64(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_bf_cfb64'; +function EVP_bf_cfb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_bf_cfb64'; + +function EVP_bf_ofb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_bf_ofb'; + +function EVP_cast5_ecb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_cast5_ecb'; + +function EVP_cast5_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_cast5_cbc'; + +function EVP_cast5_cfb64(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_cast5_cfb64'; +function EVP_cast5_cfb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_cast5_cfb64'; + +function EVP_cast5_ofb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_cast5_ofb'; + +function EVP_aes_128_ecb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_128_ecb'; + +function EVP_aes_128_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_128_cbc'; + +function EVP_aes_128_cfb1(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_128_cfb1'; + +function EVP_aes_128_cfb8(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_128_cfb8'; + +function EVP_aes_128_cfb128(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_128_cfb128'; +function EVP_aes_128_cfb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_128_cfb128'; + +function EVP_aes_128_ofb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_128_ofb'; + +function EVP_aes_128_ctr(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_128_ctr'; + +function EVP_aes_128_ccm(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_128_ccm'; + +function EVP_aes_128_gcm(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_128_gcm'; + +function EVP_aes_128_xts(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_128_xts'; + +function EVP_aes_128_wrap(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_128_wrap'; + +function EVP_aes_128_wrap_pad(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_128_wrap_pad'; + +function EVP_aes_128_ocb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_128_ocb'; + +function EVP_aes_192_ecb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_192_ecb'; + +function EVP_aes_192_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_192_cbc'; + +function EVP_aes_192_cfb1(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_192_cfb1'; + +function EVP_aes_192_cfb8(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_192_cfb8'; + +function EVP_aes_192_cfb128(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_192_cfb128'; +function EVP_aes_192_cfb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_192_cfb128'; + +function EVP_aes_192_ofb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_192_ofb'; + +function EVP_aes_192_ctr(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_192_ctr'; + +function EVP_aes_192_ccm(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_192_ccm'; + +function EVP_aes_192_gcm(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_192_gcm'; + +function EVP_aes_192_wrap(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_192_wrap'; + +function EVP_aes_192_wrap_pad(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_192_wrap_pad'; + +function EVP_aes_192_ocb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_192_ocb'; + +function EVP_aes_256_ecb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_256_ecb'; + +function EVP_aes_256_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_256_cbc'; + +function EVP_aes_256_cfb1(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_256_cfb1'; + +function EVP_aes_256_cfb8(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_256_cfb8'; + +function EVP_aes_256_cfb128(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_256_cfb128'; +function EVP_aes_256_cfb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_256_cfb128'; + +function EVP_aes_256_ofb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_256_ofb'; + +function EVP_aes_256_ctr(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_256_ctr'; + +function EVP_aes_256_ccm(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_256_ccm'; + +function EVP_aes_256_gcm(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_256_gcm'; + +function EVP_aes_256_xts(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_256_xts'; + +function EVP_aes_256_wrap(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_256_wrap'; + +function EVP_aes_256_wrap_pad(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_256_wrap_pad'; + +function EVP_aes_256_ocb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_256_ocb'; + +function EVP_aes_128_cbc_hmac_sha1(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_128_cbc_hmac_sha1'; + +function EVP_aes_256_cbc_hmac_sha1(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_256_cbc_hmac_sha1'; + +function EVP_aes_128_cbc_hmac_sha256(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_128_cbc_hmac_sha256'; + +function EVP_aes_256_cbc_hmac_sha256(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aes_256_cbc_hmac_sha256'; + +function EVP_aria_128_ecb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_128_ecb'; + +function EVP_aria_128_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_128_cbc'; + +function EVP_aria_128_cfb1(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_128_cfb1'; + +function EVP_aria_128_cfb8(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_128_cfb8'; + +function EVP_aria_128_cfb128(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_128_cfb128'; +function EVP_aria_128_cfb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_128_cfb128'; + +function EVP_aria_128_ctr(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_128_ctr'; + +function EVP_aria_128_ofb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_128_ofb'; + +function EVP_aria_128_gcm(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_128_gcm'; + +function EVP_aria_128_ccm(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_128_ccm'; + +function EVP_aria_192_ecb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_192_ecb'; + +function EVP_aria_192_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_192_cbc'; + +function EVP_aria_192_cfb1(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_192_cfb1'; + +function EVP_aria_192_cfb8(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_192_cfb8'; + +function EVP_aria_192_cfb128(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_192_cfb128'; +function EVP_aria_192_cfb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_192_cfb128'; + +function EVP_aria_192_ctr(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_192_ctr'; + +function EVP_aria_192_ofb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_192_ofb'; + +function EVP_aria_192_gcm(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_192_gcm'; + +function EVP_aria_192_ccm(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_192_ccm'; + +function EVP_aria_256_ecb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_256_ecb'; + +function EVP_aria_256_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_256_cbc'; + +function EVP_aria_256_cfb1(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_256_cfb1'; + +function EVP_aria_256_cfb8(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_256_cfb8'; + +function EVP_aria_256_cfb128(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_256_cfb128'; +function EVP_aria_256_cfb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_256_cfb128'; + +function EVP_aria_256_ctr(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_256_ctr'; + +function EVP_aria_256_ofb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_256_ofb'; + +function EVP_aria_256_gcm(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_256_gcm'; + +function EVP_aria_256_ccm(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_aria_256_ccm'; + +function EVP_camellia_128_ecb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_128_ecb'; + +function EVP_camellia_128_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_128_cbc'; + +function EVP_camellia_128_cfb1(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_128_cfb1'; + +function EVP_camellia_128_cfb8(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_128_cfb8'; + +function EVP_camellia_128_cfb128(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_128_cfb128'; +function EVP_camellia_128_cfb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_128_cfb128'; + +function EVP_camellia_128_ofb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_128_ofb'; + +function EVP_camellia_128_ctr(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_128_ctr'; + +function EVP_camellia_192_ecb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_192_ecb'; + +function EVP_camellia_192_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_192_cbc'; + +function EVP_camellia_192_cfb1(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_192_cfb1'; + +function EVP_camellia_192_cfb8(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_192_cfb8'; + +function EVP_camellia_192_cfb128(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_192_cfb128'; +function EVP_camellia_192_cfb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_192_cfb128'; + +function EVP_camellia_192_ofb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_192_ofb'; + +function EVP_camellia_192_ctr(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_192_ctr'; + +function EVP_camellia_256_ecb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_256_ecb'; + +function EVP_camellia_256_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_256_cbc'; + +function EVP_camellia_256_cfb1(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_256_cfb1'; + +function EVP_camellia_256_cfb8(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_256_cfb8'; + +function EVP_camellia_256_cfb128(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_256_cfb128'; +function EVP_camellia_256_cfb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_256_cfb128'; + +function EVP_camellia_256_ofb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_256_ofb'; + +function EVP_camellia_256_ctr(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_camellia_256_ctr'; + +function EVP_chacha20(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_chacha20'; + +function EVP_chacha20_poly1305(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_chacha20_poly1305'; + +function EVP_seed_ecb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_seed_ecb'; + +function EVP_seed_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_seed_cbc'; + +function EVP_seed_cfb128(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_seed_cfb128'; +function EVP_seed_cfb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_seed_cfb128'; + +function EVP_seed_ofb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_seed_ofb'; + +function EVP_sm4_ecb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_sm4_ecb'; + +function EVP_sm4_cbc(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_sm4_cbc'; + +function EVP_sm4_cfb128(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_sm4_cfb128'; +function EVP_sm4_cfb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_sm4_cfb128'; + +function EVP_sm4_ofb(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_sm4_ofb'; + +function EVP_sm4_ctr(): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_sm4_ctr'; + +function EVP_add_cipher(cipher: PEVP_CIPHER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_add_cipher'; + +function EVP_add_digest(digest: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_add_digest'; + +function EVP_get_cipherbyname(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'EVP_get_cipherbyname'; + +function EVP_get_digestbyname(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_get_digestbyname'; + +type + EVP_CIPHER_do_all_fn = procedure(ciph: PEVP_CIPHER; from: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; x: Pointer); cdecl; + +procedure EVP_CIPHER_do_all(fn: EVP_CIPHER_do_all_fn; arg: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_do_all'; + +type + EVP_CIPHER_do_all_sorted_fn = procedure(ciph: PEVP_CIPHER; from: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; x: Pointer); cdecl; + +procedure EVP_CIPHER_do_all_sorted(fn: EVP_CIPHER_do_all_sorted_fn; arg: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_do_all_sorted'; + +type + EVP_MD_do_all_fn = procedure(ciph: PEVP_MD; from: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; x: Pointer); cdecl; + +procedure EVP_MD_do_all(fn: EVP_MD_do_all_fn; arg: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_do_all'; + +type + EVP_MD_do_all_sorted_fn = procedure(ciph: PEVP_MD; from: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; x: Pointer); cdecl; + +procedure EVP_MD_do_all_sorted(fn: EVP_MD_do_all_sorted_fn; arg: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'EVP_MD_do_all_sorted'; + +function EVP_PKEY_decrypt_old(dec_key: PByte; enc_key: PByte; enc_key_len: Integer; private_key: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_decrypt_old'; + +function EVP_PKEY_encrypt_old(enc_key: PByte; key: PByte; key_len: Integer; pub_key: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_encrypt_old'; + +function EVP_PKEY_type({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_type'; + +function EVP_PKEY_id(pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_id'; + +function EVP_PKEY_base_id(pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_base_id'; + +function EVP_PKEY_bits(pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_bits'; + +function EVP_PKEY_security_bits(pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_security_bits'; + +function EVP_PKEY_size(pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_size'; + +function EVP_PKEY_set_type(pkey: PEVP_PKEY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_set_type'; + +function EVP_PKEY_set_type_str(pkey: PEVP_PKEY; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_set_type_str'; + +function EVP_PKEY_set_alias_type(pkey: PEVP_PKEY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_set_alias_type'; + +function EVP_PKEY_set1_engine(pkey: PEVP_PKEY; e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_set1_engine'; + +function EVP_PKEY_get0_engine(pkey: PEVP_PKEY): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get0_engine'; + +function EVP_PKEY_assign(pkey: PEVP_PKEY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; key: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_assign'; + +function EVP_PKEY_get0(pkey: PEVP_PKEY): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get0'; + +function EVP_PKEY_get0_hmac(pkey: PEVP_PKEY; len: PNativeUInt): PByte; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get0_hmac'; + +function EVP_PKEY_get0_poly1305(pkey: PEVP_PKEY; len: PNativeUInt): PByte; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get0_poly1305'; + +function EVP_PKEY_get0_siphash(pkey: PEVP_PKEY; len: PNativeUInt): PByte; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get0_siphash'; + +function EVP_PKEY_set1_RSA(pkey: PEVP_PKEY; key: Prsa_st): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_set1_RSA'; + +function EVP_PKEY_get0_RSA(pkey: PEVP_PKEY): Prsa_st; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get0_RSA'; + +function EVP_PKEY_get1_RSA(pkey: PEVP_PKEY): Prsa_st; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get1_RSA'; + +function EVP_PKEY_set1_DSA(pkey: PEVP_PKEY; key: Pdsa_st): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_set1_DSA'; + +function EVP_PKEY_get0_DSA(pkey: PEVP_PKEY): Pdsa_st; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get0_DSA'; + +function EVP_PKEY_get1_DSA(pkey: PEVP_PKEY): Pdsa_st; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get1_DSA'; + +function EVP_PKEY_set1_DH(pkey: PEVP_PKEY; key: Pdh_st): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_set1_DH'; + +function EVP_PKEY_get0_DH(pkey: PEVP_PKEY): Pdh_st; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get0_DH'; + +function EVP_PKEY_get1_DH(pkey: PEVP_PKEY): Pdh_st; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get1_DH'; + +function EVP_PKEY_set1_EC_KEY(pkey: PEVP_PKEY; key: Pec_key_st): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_set1_EC_KEY'; + +function EVP_PKEY_get0_EC_KEY(pkey: PEVP_PKEY): Pec_key_st; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get0_EC_KEY'; + +function EVP_PKEY_get1_EC_KEY(pkey: PEVP_PKEY): Pec_key_st; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get1_EC_KEY'; + +function EVP_PKEY_new(): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_new'; + +function EVP_PKEY_up_ref(pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_up_ref'; + +procedure EVP_PKEY_free(pkey: PEVP_PKEY); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_free'; + +function d2i_PublicKey({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; a: PPEVP_PKEY; pp: PPByte; length: Integer): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PublicKey'; + +function i2d_PublicKey(a: PEVP_PKEY; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PublicKey'; + +function d2i_PrivateKey({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; a: PPEVP_PKEY; pp: PPByte; length: Integer): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PrivateKey'; + +function d2i_AutoPrivateKey(a: PPEVP_PKEY; pp: PPByte; length: Integer): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_AutoPrivateKey'; + +function i2d_PrivateKey(a: PEVP_PKEY; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PrivateKey'; + +function EVP_PKEY_copy_parameters({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PEVP_PKEY; from: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_copy_parameters'; + +function EVP_PKEY_missing_parameters(pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_missing_parameters'; + +function EVP_PKEY_save_parameters(pkey: PEVP_PKEY; mode: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_save_parameters'; + +function EVP_PKEY_cmp_parameters(a: PEVP_PKEY; b: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_cmp_parameters'; + +function EVP_PKEY_cmp(a: PEVP_PKEY; b: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_cmp'; + +function EVP_PKEY_print_public({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; pkey: PEVP_PKEY; indent: Integer; pctx: PASN1_PCTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_print_public'; + +function EVP_PKEY_print_private({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; pkey: PEVP_PKEY; indent: Integer; pctx: PASN1_PCTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_print_private'; + +function EVP_PKEY_print_params({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; pkey: PEVP_PKEY; indent: Integer; pctx: PASN1_PCTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_print_params'; + +function EVP_PKEY_get_default_digest_nid(pkey: PEVP_PKEY; pnid: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get_default_digest_nid'; + +function EVP_PKEY_set1_tls_encodedpoint(pkey: PEVP_PKEY; pt: PByte; ptlen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_set1_tls_encodedpoint'; + +function EVP_PKEY_get1_tls_encodedpoint(pkey: PEVP_PKEY; ppt: PPByte): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get1_tls_encodedpoint'; + +function EVP_CIPHER_type(ctx: PEVP_CIPHER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_type'; + +function EVP_CIPHER_param_to_asn1(c: PEVP_CIPHER_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PASN1_TYPE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_param_to_asn1'; + +function EVP_CIPHER_asn1_to_param(c: PEVP_CIPHER_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PASN1_TYPE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_asn1_to_param'; + +function EVP_CIPHER_set_asn1_iv(c: PEVP_CIPHER_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PASN1_TYPE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_set_asn1_iv'; + +function EVP_CIPHER_get_asn1_iv(c: PEVP_CIPHER_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PASN1_TYPE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_CIPHER_get_asn1_iv'; + +function PKCS5_PBE_keyivgen(ctx: PEVP_CIPHER_CTX; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; param: PASN1_TYPE; cipher: PEVP_CIPHER; md: PEVP_MD; en_de: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS5_PBE_keyivgen'; + +function PKCS5_PBKDF2_HMAC_SHA1(pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; salt: PByte; saltlen: Integer; iter: Integer; keylen: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS5_PBKDF2_HMAC_SHA1'; + +function PKCS5_PBKDF2_HMAC(pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; salt: PByte; saltlen: Integer; iter: Integer; digest: PEVP_MD; keylen: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS5_PBKDF2_HMAC'; + +function PKCS5_v2_PBE_keyivgen(ctx: PEVP_CIPHER_CTX; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; param: PASN1_TYPE; cipher: PEVP_CIPHER; md: PEVP_MD; en_de: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS5_v2_PBE_keyivgen'; + +function EVP_PBE_scrypt(pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: NativeUInt; salt: PByte; saltlen: NativeUInt; N: UInt64; r: UInt64; p: UInt64; maxmem: UInt64; key: PByte; keylen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PBE_scrypt'; + +function PKCS5_v2_scrypt_keyivgen(ctx: PEVP_CIPHER_CTX; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; param: PASN1_TYPE; c: PEVP_CIPHER; md: PEVP_MD; en_de: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS5_v2_scrypt_keyivgen'; + +procedure PKCS5_PBE_add(); cdecl; + external LIB_CRYPTO name _PU + 'PKCS5_PBE_add'; + +function EVP_PBE_CipherInit(pbe_obj: PASN1_OBJECT; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; param: PASN1_TYPE; ctx: PEVP_CIPHER_CTX; en_de: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PBE_CipherInit'; + +function EVP_PBE_alg_add_type(pbe_type: Integer; pbe_nid: Integer; cipher_nid: Integer; md_nid: Integer; keygen: PEVP_PBE_KEYGEN): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PBE_alg_add_type'; + +function EVP_PBE_alg_add(nid: Integer; cipher: PEVP_CIPHER; md: PEVP_MD; keygen: PEVP_PBE_KEYGEN): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PBE_alg_add'; + +type + PPEVP_PBE_KEYGEN = Pointer; + +function EVP_PBE_find({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; pbe_nid: Integer; pcnid: PInteger; pmnid: PInteger; pkeygen: PPEVP_PBE_KEYGEN): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PBE_find'; + +procedure EVP_PBE_cleanup(); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PBE_cleanup'; + +function EVP_PBE_get(ptype: PInteger; ppbe_nid: PInteger; num: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PBE_get'; + +function EVP_PKEY_asn1_get_count(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_get_count'; + +function EVP_PKEY_asn1_get0(idx: Integer): PEVP_PKEY_ASN1_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_get0'; + +function EVP_PKEY_asn1_find(pe: PPENGINE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): PEVP_PKEY_ASN1_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_find'; + +function EVP_PKEY_asn1_find_str(pe: PPENGINE; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: Integer): PEVP_PKEY_ASN1_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_find_str'; + +function EVP_PKEY_asn1_add0(ameth: PEVP_PKEY_ASN1_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_add0'; + +function EVP_PKEY_asn1_add_alias({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: Integer; from: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_add_alias'; + +function EVP_PKEY_asn1_get0_info(ppkey_id: PInteger; pkey_base_id: PInteger; ppkey_flags: PInteger; pinfo: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; ppem_str: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; ameth: PEVP_PKEY_ASN1_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_get0_info'; + +function EVP_PKEY_get0_asn1(pkey: PEVP_PKEY): PEVP_PKEY_ASN1_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get0_asn1'; + +function EVP_PKEY_asn1_new(id: Integer; flags: Integer; pem_str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; info: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PEVP_PKEY_ASN1_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_new'; + +procedure EVP_PKEY_asn1_copy(dst: PEVP_PKEY_ASN1_METHOD; src: PEVP_PKEY_ASN1_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_copy'; + +procedure EVP_PKEY_asn1_free(ameth: PEVP_PKEY_ASN1_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_free'; + +type + EVP_PKEY_asn1_set_public_pub_decode = function(pk: PEVP_PKEY; pub: PX509_PUBKEY): Integer; cdecl; + +type + EVP_PKEY_asn1_set_public_pub_encode = function(pub: PX509_PUBKEY; pk: PEVP_PKEY): Integer; cdecl; + +type + EVP_PKEY_asn1_set_public_pub_cmp = function(a: PEVP_PKEY; b: PEVP_PKEY): Integer; cdecl; + +type + EVP_PKEY_asn1_set_public_pub_print = function({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; pkey: PEVP_PKEY; indent: Integer; pctx: PASN1_PCTX): Integer; cdecl; + +type + EVP_PKEY_asn1_set_public_pkey_size = function(pk: PEVP_PKEY): Integer; cdecl; + +type + EVP_PKEY_asn1_set_public_pkey_bits = function(pk: PEVP_PKEY): Integer; cdecl; + +procedure EVP_PKEY_asn1_set_public(ameth: PEVP_PKEY_ASN1_METHOD; pub_decode: EVP_PKEY_asn1_set_public_pub_decode; pub_encode: EVP_PKEY_asn1_set_public_pub_encode; pub_cmp: EVP_PKEY_asn1_set_public_pub_cmp; pub_print: EVP_PKEY_asn1_set_public_pub_print; pkey_size: EVP_PKEY_asn1_set_public_pkey_size; pkey_bits: EVP_PKEY_asn1_set_public_pkey_bits); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_set_public'; + +type + EVP_PKEY_asn1_set_private_priv_decode = function(pk: PEVP_PKEY; p8inf: PPKCS8_PRIV_KEY_INFO): Integer; cdecl; + +type + EVP_PKEY_asn1_set_private_priv_encode = function(p8: PPKCS8_PRIV_KEY_INFO; pk: PEVP_PKEY): Integer; cdecl; + +type + EVP_PKEY_asn1_set_private_priv_print = function({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; pkey: PEVP_PKEY; indent: Integer; pctx: PASN1_PCTX): Integer; cdecl; + +procedure EVP_PKEY_asn1_set_private(ameth: PEVP_PKEY_ASN1_METHOD; priv_decode: EVP_PKEY_asn1_set_private_priv_decode; priv_encode: EVP_PKEY_asn1_set_private_priv_encode; priv_print: EVP_PKEY_asn1_set_private_priv_print); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_set_private'; + +type + EVP_PKEY_asn1_set_param_param_decode = function(pkey: PEVP_PKEY; pder: PPByte; derlen: Integer): Integer; cdecl; + +type + EVP_PKEY_asn1_set_param_param_encode = function(pkey: PEVP_PKEY; pder: PPByte): Integer; cdecl; + +type + EVP_PKEY_asn1_set_param_param_missing = function(pk: PEVP_PKEY): Integer; cdecl; + +type + EVP_PKEY_asn1_set_param_param_copy = function({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PEVP_PKEY; from: PEVP_PKEY): Integer; cdecl; + +type + EVP_PKEY_asn1_set_param_param_cmp = function(a: PEVP_PKEY; b: PEVP_PKEY): Integer; cdecl; + +type + EVP_PKEY_asn1_set_param_param_print = function({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; pkey: PEVP_PKEY; indent: Integer; pctx: PASN1_PCTX): Integer; cdecl; + +procedure EVP_PKEY_asn1_set_param(ameth: PEVP_PKEY_ASN1_METHOD; param_decode: EVP_PKEY_asn1_set_param_param_decode; param_encode: EVP_PKEY_asn1_set_param_param_encode; param_missing: EVP_PKEY_asn1_set_param_param_missing; param_copy: EVP_PKEY_asn1_set_param_param_copy; param_cmp: EVP_PKEY_asn1_set_param_param_cmp; param_print: EVP_PKEY_asn1_set_param_param_print); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_set_param'; + +type + EVP_PKEY_asn1_set_free_pkey_free = procedure(pkey: PEVP_PKEY); cdecl; + +procedure EVP_PKEY_asn1_set_free(ameth: PEVP_PKEY_ASN1_METHOD; pkey_free: EVP_PKEY_asn1_set_free_pkey_free); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_set_free'; + +type + EVP_PKEY_asn1_set_ctrl_pkey_ctrl = function(pkey: PEVP_PKEY; op: Integer; arg1: Integer; arg2: Pointer): Integer; cdecl; + +procedure EVP_PKEY_asn1_set_ctrl(ameth: PEVP_PKEY_ASN1_METHOD; pkey_ctrl: EVP_PKEY_asn1_set_ctrl_pkey_ctrl); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_set_ctrl'; + +type + EVP_PKEY_asn1_set_item_item_verify = function(ctx: PEVP_MD_CTX; it: PASN1_ITEM; asn: Pointer; a: PX509_ALGOR; sig: PASN1_BIT_STRING; pkey: PEVP_PKEY): Integer; cdecl; + +type + EVP_PKEY_asn1_set_item_item_sign = function(ctx: PEVP_MD_CTX; it: PASN1_ITEM; asn: Pointer; alg1: PX509_ALGOR; alg2: PX509_ALGOR; sig: PASN1_BIT_STRING): Integer; cdecl; + +procedure EVP_PKEY_asn1_set_item(ameth: PEVP_PKEY_ASN1_METHOD; item_verify: EVP_PKEY_asn1_set_item_item_verify; item_sign: EVP_PKEY_asn1_set_item_item_sign); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_set_item'; + +type + EVP_PKEY_asn1_set_siginf_siginf_set = function(siginf: PX509_SIG_INFO; alg: PX509_ALGOR; sig: PASN1_STRING): Integer; cdecl; + +procedure EVP_PKEY_asn1_set_siginf(ameth: PEVP_PKEY_ASN1_METHOD; siginf_set: EVP_PKEY_asn1_set_siginf_siginf_set); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_set_siginf'; + +type + EVP_PKEY_asn1_set_check_pkey_check = function(pk: PEVP_PKEY): Integer; cdecl; + +procedure EVP_PKEY_asn1_set_check(ameth: PEVP_PKEY_ASN1_METHOD; pkey_check: EVP_PKEY_asn1_set_check_pkey_check); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_set_check'; + +type + EVP_PKEY_asn1_set_public_check_pkey_pub_check = function(pk: PEVP_PKEY): Integer; cdecl; + +procedure EVP_PKEY_asn1_set_public_check(ameth: PEVP_PKEY_ASN1_METHOD; pkey_pub_check: EVP_PKEY_asn1_set_public_check_pkey_pub_check); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_set_public_check'; + +type + EVP_PKEY_asn1_set_param_check_pkey_param_check = function(pk: PEVP_PKEY): Integer; cdecl; + +procedure EVP_PKEY_asn1_set_param_check(ameth: PEVP_PKEY_ASN1_METHOD; pkey_param_check: EVP_PKEY_asn1_set_param_check_pkey_param_check); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_set_param_check'; + +type + EVP_PKEY_asn1_set_set_priv_key_set_priv_key = function(pk: PEVP_PKEY; priv: PByte; len: NativeUInt): Integer; cdecl; + +procedure EVP_PKEY_asn1_set_set_priv_key(ameth: PEVP_PKEY_ASN1_METHOD; set_priv_key: EVP_PKEY_asn1_set_set_priv_key_set_priv_key); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_set_set_priv_key'; + +type + EVP_PKEY_asn1_set_set_pub_key_set_pub_key = function(pk: PEVP_PKEY; pub: PByte; len: NativeUInt): Integer; cdecl; + +procedure EVP_PKEY_asn1_set_set_pub_key(ameth: PEVP_PKEY_ASN1_METHOD; set_pub_key: EVP_PKEY_asn1_set_set_pub_key_set_pub_key); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_set_set_pub_key'; + +type + EVP_PKEY_asn1_set_get_priv_key_get_priv_key = function(pk: PEVP_PKEY; priv: PByte; len: PNativeUInt): Integer; cdecl; + +procedure EVP_PKEY_asn1_set_get_priv_key(ameth: PEVP_PKEY_ASN1_METHOD; get_priv_key: EVP_PKEY_asn1_set_get_priv_key_get_priv_key); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_set_get_priv_key'; + +type + EVP_PKEY_asn1_set_get_pub_key_get_pub_key = function(pk: PEVP_PKEY; pub: PByte; len: PNativeUInt): Integer; cdecl; + +procedure EVP_PKEY_asn1_set_get_pub_key(ameth: PEVP_PKEY_ASN1_METHOD; get_pub_key: EVP_PKEY_asn1_set_get_pub_key_get_pub_key); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_set_get_pub_key'; + +type + EVP_PKEY_asn1_set_security_bits_pkey_security_bits = function(pk: PEVP_PKEY): Integer; cdecl; + +procedure EVP_PKEY_asn1_set_security_bits(ameth: PEVP_PKEY_ASN1_METHOD; pkey_security_bits: EVP_PKEY_asn1_set_security_bits_pkey_security_bits); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_asn1_set_security_bits'; + +function EVP_PKEY_meth_find({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): PEVP_PKEY_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_find'; + +function EVP_PKEY_meth_new(id: Integer; flags: Integer): PEVP_PKEY_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_new'; + +procedure EVP_PKEY_meth_get0_info(ppkey_id: PInteger; pflags: PInteger; meth: PEVP_PKEY_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get0_info'; + +procedure EVP_PKEY_meth_copy(dst: PEVP_PKEY_METHOD; src: PEVP_PKEY_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_copy'; + +procedure EVP_PKEY_meth_free(pmeth: PEVP_PKEY_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_free'; + +function EVP_PKEY_meth_add0(pmeth: PEVP_PKEY_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_add0'; + +function EVP_PKEY_meth_remove(pmeth: PEVP_PKEY_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_remove'; + +function EVP_PKEY_meth_get_count(): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_count'; + +function EVP_PKEY_meth_get0(idx: NativeUInt): PEVP_PKEY_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get0'; + +function EVP_PKEY_CTX_new(pkey: PEVP_PKEY; e: PENGINE): PEVP_PKEY_CTX; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_new'; + +function EVP_PKEY_CTX_new_id(id: Integer; e: PENGINE): PEVP_PKEY_CTX; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_new_id'; + +function EVP_PKEY_CTX_dup(ctx: PEVP_PKEY_CTX): PEVP_PKEY_CTX; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_dup'; + +procedure EVP_PKEY_CTX_free(ctx: PEVP_PKEY_CTX); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_free'; + +function EVP_PKEY_CTX_ctrl(ctx: PEVP_PKEY_CTX; keytype: Integer; optype: Integer; cmd: Integer; p1: Integer; p2: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_ctrl'; + +function EVP_PKEY_CTX_ctrl_str(ctx: PEVP_PKEY_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; value: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_ctrl_str'; + +function EVP_PKEY_CTX_ctrl_uint64(ctx: PEVP_PKEY_CTX; keytype: Integer; optype: Integer; cmd: Integer; value: UInt64): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_ctrl_uint64'; + +function EVP_PKEY_CTX_str2ctrl(ctx: PEVP_PKEY_CTX; cmd: Integer; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_str2ctrl'; + +function EVP_PKEY_CTX_hex2ctrl(ctx: PEVP_PKEY_CTX; cmd: Integer; hex: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_hex2ctrl'; + +function EVP_PKEY_CTX_md(ctx: PEVP_PKEY_CTX; optype: Integer; cmd: Integer; md: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_md'; + +function EVP_PKEY_CTX_get_operation(ctx: PEVP_PKEY_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_get_operation'; + +procedure EVP_PKEY_CTX_set0_keygen_info(ctx: PEVP_PKEY_CTX; dat: PInteger; datlen: Integer); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_set0_keygen_info'; + +function EVP_PKEY_new_mac_key({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; e: PENGINE; key: PByte; keylen: Integer): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_new_mac_key'; + +function EVP_PKEY_new_raw_private_key({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; e: PENGINE; priv: PByte; len: NativeUInt): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_new_raw_private_key'; + +function EVP_PKEY_new_raw_public_key({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; e: PENGINE; pub: PByte; len: NativeUInt): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_new_raw_public_key'; + +function EVP_PKEY_get_raw_private_key(pkey: PEVP_PKEY; priv: PByte; len: PNativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get_raw_private_key'; + +function EVP_PKEY_get_raw_public_key(pkey: PEVP_PKEY; pub: PByte; len: PNativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get_raw_public_key'; + +function EVP_PKEY_new_CMAC_key(e: PENGINE; priv: PByte; len: NativeUInt; cipher: PEVP_CIPHER): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_new_CMAC_key'; + +procedure EVP_PKEY_CTX_set_data(ctx: PEVP_PKEY_CTX; data: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_set_data'; + +function EVP_PKEY_CTX_get_data(ctx: PEVP_PKEY_CTX): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_get_data'; + +function EVP_PKEY_CTX_get0_pkey(ctx: PEVP_PKEY_CTX): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_get0_pkey'; + +function EVP_PKEY_CTX_get0_peerkey(ctx: PEVP_PKEY_CTX): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_get0_peerkey'; + +procedure EVP_PKEY_CTX_set_app_data(ctx: PEVP_PKEY_CTX; data: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_set_app_data'; + +function EVP_PKEY_CTX_get_app_data(ctx: PEVP_PKEY_CTX): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_get_app_data'; + +function EVP_PKEY_sign_init(ctx: PEVP_PKEY_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_sign_init'; + +function EVP_PKEY_sign(ctx: PEVP_PKEY_CTX; sig: PByte; var siglen: NativeUInt; tbs: PByte; tbslen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_sign'; + +function EVP_PKEY_verify_init(ctx: PEVP_PKEY_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_verify_init'; + +function EVP_PKEY_verify(ctx: PEVP_PKEY_CTX; sig: PByte; siglen: NativeUInt; tbs: PByte; tbslen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_verify'; + +function EVP_PKEY_verify_recover_init(ctx: PEVP_PKEY_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_verify_recover_init'; + +function EVP_PKEY_verify_recover(ctx: PEVP_PKEY_CTX; rout: PByte; routlen: PNativeUInt; sig: PByte; siglen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_verify_recover'; + +function EVP_PKEY_encrypt_init(ctx: PEVP_PKEY_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_encrypt_init'; + +function EVP_PKEY_encrypt(ctx: PEVP_PKEY_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outlen: PNativeUInt; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inlen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_encrypt'; + +function EVP_PKEY_decrypt_init(ctx: PEVP_PKEY_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_decrypt_init'; + +function EVP_PKEY_decrypt(ctx: PEVP_PKEY_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outlen: PNativeUInt; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inlen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_decrypt'; + +function EVP_PKEY_derive_init(ctx: PEVP_PKEY_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_derive_init'; + +function EVP_PKEY_derive_set_peer(ctx: PEVP_PKEY_CTX; peer: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_derive_set_peer'; + +function EVP_PKEY_derive(ctx: PEVP_PKEY_CTX; key: PByte; keylen: PNativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_derive'; + +function EVP_PKEY_paramgen_init(ctx: PEVP_PKEY_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_paramgen_init'; + +function EVP_PKEY_paramgen(ctx: PEVP_PKEY_CTX; ppkey: PPEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_paramgen'; + +function EVP_PKEY_keygen_init(ctx: PEVP_PKEY_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_keygen_init'; + +function EVP_PKEY_keygen(ctx: PEVP_PKEY_CTX; ppkey: PPEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_keygen'; + +function EVP_PKEY_check(ctx: PEVP_PKEY_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_check'; + +function EVP_PKEY_public_check(ctx: PEVP_PKEY_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_public_check'; + +function EVP_PKEY_param_check(ctx: PEVP_PKEY_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_param_check'; + +procedure EVP_PKEY_CTX_set_cb(ctx: PEVP_PKEY_CTX; cb: PEVP_PKEY_gen_cb); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_set_cb'; + +function EVP_PKEY_CTX_get_cb(ctx: PEVP_PKEY_CTX): PEVP_PKEY_gen_cb; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_get_cb'; + +function EVP_PKEY_CTX_get_keygen_info(ctx: PEVP_PKEY_CTX; idx: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_CTX_get_keygen_info'; + +type + EVP_PKEY_meth_set_init_init = function(ctx: PEVP_PKEY_CTX): Integer; cdecl; + +procedure EVP_PKEY_meth_set_init(pmeth: PEVP_PKEY_METHOD; init: EVP_PKEY_meth_set_init_init); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_init'; + +type + EVP_PKEY_meth_set_copy_copy = function(dst: PEVP_PKEY_CTX; src: PEVP_PKEY_CTX): Integer; cdecl; + +procedure EVP_PKEY_meth_set_copy(pmeth: PEVP_PKEY_METHOD; copy: EVP_PKEY_meth_set_copy_copy); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_copy'; + +type + EVP_PKEY_meth_set_cleanup_cleanup = procedure(ctx: PEVP_PKEY_CTX); cdecl; + +procedure EVP_PKEY_meth_set_cleanup(pmeth: PEVP_PKEY_METHOD; cleanup: EVP_PKEY_meth_set_cleanup_cleanup); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_cleanup'; + +type + EVP_PKEY_meth_set_paramgen_paramgen_init = function(ctx: PEVP_PKEY_CTX): Integer; cdecl; + +type + EVP_PKEY_meth_set_paramgen_paramgen = function(ctx: PEVP_PKEY_CTX; pkey: PEVP_PKEY): Integer; cdecl; + +procedure EVP_PKEY_meth_set_paramgen(pmeth: PEVP_PKEY_METHOD; paramgen_init: EVP_PKEY_meth_set_paramgen_paramgen_init; paramgen: EVP_PKEY_meth_set_paramgen_paramgen); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_paramgen'; + +type + EVP_PKEY_meth_set_keygen_keygen_init = function(ctx: PEVP_PKEY_CTX): Integer; cdecl; + +type + EVP_PKEY_meth_set_keygen_keygen = function(ctx: PEVP_PKEY_CTX; pkey: PEVP_PKEY): Integer; cdecl; + +procedure EVP_PKEY_meth_set_keygen(pmeth: PEVP_PKEY_METHOD; keygen_init: EVP_PKEY_meth_set_keygen_keygen_init; keygen: EVP_PKEY_meth_set_keygen_keygen); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_keygen'; + +type + EVP_PKEY_meth_set_sign_sign_init = function(ctx: PEVP_PKEY_CTX): Integer; cdecl; + +type + EVP_PKEY_meth_set_sign_sign = function(ctx: PEVP_PKEY_CTX; sig: PByte; var siglen: NativeUInt; tbs: PByte; tbslen: NativeUInt): Integer; cdecl; + +procedure EVP_PKEY_meth_set_sign(pmeth: PEVP_PKEY_METHOD; sign_init: EVP_PKEY_meth_set_sign_sign_init; sign: EVP_PKEY_meth_set_sign_sign); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_sign'; + +type + EVP_PKEY_meth_set_verify_verify_init = function(ctx: PEVP_PKEY_CTX): Integer; cdecl; + +type + EVP_PKEY_meth_set_verify_verify = function(ctx: PEVP_PKEY_CTX; sig: PByte; siglen: NativeUInt; tbs: PByte; tbslen: NativeUInt): Integer; cdecl; + +procedure EVP_PKEY_meth_set_verify(pmeth: PEVP_PKEY_METHOD; verify_init: EVP_PKEY_meth_set_verify_verify_init; verify: EVP_PKEY_meth_set_verify_verify); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_verify'; + +type + EVP_PKEY_meth_set_verify_recover_verify_recover_init = function(ctx: PEVP_PKEY_CTX): Integer; cdecl; + +type + EVP_PKEY_meth_set_verify_recover_verify_recover = function(ctx: PEVP_PKEY_CTX; sig: PByte; var siglen: NativeUInt; tbs: PByte; tbslen: NativeUInt): Integer; cdecl; + +procedure EVP_PKEY_meth_set_verify_recover(pmeth: PEVP_PKEY_METHOD; verify_recover_init: EVP_PKEY_meth_set_verify_recover_verify_recover_init; verify_recover: EVP_PKEY_meth_set_verify_recover_verify_recover); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_verify_recover'; + +type + EVP_PKEY_meth_set_signctx_signctx_init = function(ctx: PEVP_PKEY_CTX; mctx: PEVP_MD_CTX): Integer; cdecl; + +type + EVP_PKEY_meth_set_signctx_signctx = function(ctx: PEVP_PKEY_CTX; sig: PByte; var siglen: NativeUInt; mctx: PEVP_MD_CTX): Integer; cdecl; + +procedure EVP_PKEY_meth_set_signctx(pmeth: PEVP_PKEY_METHOD; signctx_init: EVP_PKEY_meth_set_signctx_signctx_init; signctx: EVP_PKEY_meth_set_signctx_signctx); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_signctx'; + +type + EVP_PKEY_meth_set_verifyctx_verifyctx_init = function(ctx: PEVP_PKEY_CTX; mctx: PEVP_MD_CTX): Integer; cdecl; + +type + EVP_PKEY_meth_set_verifyctx_verifyctx = function(ctx: PEVP_PKEY_CTX; sig: PByte; siglen: Integer; mctx: PEVP_MD_CTX): Integer; cdecl; + +procedure EVP_PKEY_meth_set_verifyctx(pmeth: PEVP_PKEY_METHOD; verifyctx_init: EVP_PKEY_meth_set_verifyctx_verifyctx_init; verifyctx: EVP_PKEY_meth_set_verifyctx_verifyctx); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_verifyctx'; + +type + EVP_PKEY_meth_set_encrypt_encrypt_init = function(ctx: PEVP_PKEY_CTX): Integer; cdecl; + +type + EVP_PKEY_meth_set_encrypt_encryptfn = function(ctx: PEVP_PKEY_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outlen: PNativeUInt; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inlen: NativeUInt): Integer; cdecl; + +procedure EVP_PKEY_meth_set_encrypt(pmeth: PEVP_PKEY_METHOD; encrypt_init: EVP_PKEY_meth_set_encrypt_encrypt_init; encryptfn: EVP_PKEY_meth_set_encrypt_encryptfn); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_encrypt'; + +type + EVP_PKEY_meth_set_decrypt_decrypt_init = function(ctx: PEVP_PKEY_CTX): Integer; cdecl; + +type + EVP_PKEY_meth_set_decrypt_decrypt = function(ctx: PEVP_PKEY_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outlen: PNativeUInt; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inlen: NativeUInt): Integer; cdecl; + +procedure EVP_PKEY_meth_set_decrypt(pmeth: PEVP_PKEY_METHOD; decrypt_init: EVP_PKEY_meth_set_decrypt_decrypt_init; decrypt: EVP_PKEY_meth_set_decrypt_decrypt); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_decrypt'; + +type + EVP_PKEY_meth_set_derive_derive_init = function(ctx: PEVP_PKEY_CTX): Integer; cdecl; + +type + EVP_PKEY_meth_set_derive_derive = function(ctx: PEVP_PKEY_CTX; key: PByte; keylen: PNativeUInt): Integer; cdecl; + +procedure EVP_PKEY_meth_set_derive(pmeth: PEVP_PKEY_METHOD; derive_init: EVP_PKEY_meth_set_derive_derive_init; derive: EVP_PKEY_meth_set_derive_derive); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_derive'; + +type + EVP_PKEY_meth_set_ctrl_ctrl = function(ctx: PEVP_PKEY_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; p1: Integer; p2: Pointer): Integer; cdecl; + +type + EVP_PKEY_meth_set_ctrl_ctrl_str = function(ctx: PEVP_PKEY_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; value: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + +procedure EVP_PKEY_meth_set_ctrl(pmeth: PEVP_PKEY_METHOD; ctrl: EVP_PKEY_meth_set_ctrl_ctrl; ctrl_str: EVP_PKEY_meth_set_ctrl_ctrl_str); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_ctrl'; + +type + EVP_PKEY_meth_set_digestsign_digestsign = function(ctx: PEVP_MD_CTX; sig: PByte; var siglen: NativeUInt; tbs: PByte; tbslen: NativeUInt): Integer; cdecl; + +procedure EVP_PKEY_meth_set_digestsign(pmeth: PEVP_PKEY_METHOD; digestsign: EVP_PKEY_meth_set_digestsign_digestsign); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_digestsign'; + +type + EVP_PKEY_meth_set_digestverify_digestverify = function(ctx: PEVP_MD_CTX; sig: PByte; siglen: NativeUInt; tbs: PByte; tbslen: NativeUInt): Integer; cdecl; + +procedure EVP_PKEY_meth_set_digestverify(pmeth: PEVP_PKEY_METHOD; digestverify: EVP_PKEY_meth_set_digestverify_digestverify); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_digestverify'; + +type + EVP_PKEY_meth_set_check_check = function(pkey: PEVP_PKEY): Integer; cdecl; + +procedure EVP_PKEY_meth_set_check(pmeth: PEVP_PKEY_METHOD; check: EVP_PKEY_meth_set_check_check); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_check'; + +type + EVP_PKEY_meth_set_public_check_check = function(pkey: PEVP_PKEY): Integer; cdecl; + +procedure EVP_PKEY_meth_set_public_check(pmeth: PEVP_PKEY_METHOD; check: EVP_PKEY_meth_set_public_check_check); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_public_check'; + +type + EVP_PKEY_meth_set_param_check_check = function(pkey: PEVP_PKEY): Integer; cdecl; + +procedure EVP_PKEY_meth_set_param_check(pmeth: PEVP_PKEY_METHOD; check: EVP_PKEY_meth_set_param_check_check); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_param_check'; + +type + EVP_PKEY_meth_set_digest_custom_digest_custom = function(ctx: PEVP_PKEY_CTX; mctx: PEVP_MD_CTX): Integer; cdecl; + +procedure EVP_PKEY_meth_set_digest_custom(pmeth: PEVP_PKEY_METHOD; digest_custom: EVP_PKEY_meth_set_digest_custom_digest_custom); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_set_digest_custom'; + +procedure EVP_PKEY_meth_get_init(pmeth: PEVP_PKEY_METHOD; pinit: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_init'; + +procedure EVP_PKEY_meth_get_copy(pmeth: PEVP_PKEY_METHOD; pcopy: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *, EVP_PKEY_CTX *)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_copy'; + +procedure EVP_PKEY_meth_get_cleanup(pmeth: PEVP_PKEY_METHOD; pcleanup: Integer { TODO : Cannot convert original type "void (**)(EVP_PKEY_CTX *)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_cleanup'; + +procedure EVP_PKEY_meth_get_paramgen(pmeth: PEVP_PKEY_METHOD; pparamgen_init: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *)" }; pparamgen: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *, EVP_PKEY *)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_paramgen'; + +procedure EVP_PKEY_meth_get_keygen(pmeth: PEVP_PKEY_METHOD; pkeygen_init: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *)" }; pkeygen: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *, EVP_PKEY *)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_keygen'; + +procedure EVP_PKEY_meth_get_sign(pmeth: PEVP_PKEY_METHOD; psign_init: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *)" }; psign: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *, unsigned char *, size_t *, const unsigned char *, size_t)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_sign'; + +procedure EVP_PKEY_meth_get_verify(pmeth: PEVP_PKEY_METHOD; pverify_init: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *)" }; pverify: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *, const unsigned char *, size_t, const unsigned char *, size_t)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_verify'; + +procedure EVP_PKEY_meth_get_verify_recover(pmeth: PEVP_PKEY_METHOD; pverify_recover_init: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *)" }; pverify_recover: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *, unsigned char *, size_t *, const unsigned char *, size_t)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_verify_recover'; + +procedure EVP_PKEY_meth_get_signctx(pmeth: PEVP_PKEY_METHOD; psignctx_init: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *, EVP_MD_CTX *)" }; psignctx: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *, unsigned char *, size_t *, EVP_MD_CTX *)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_signctx'; + +procedure EVP_PKEY_meth_get_verifyctx(pmeth: PEVP_PKEY_METHOD; pverifyctx_init: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *, EVP_MD_CTX *)" }; pverifyctx: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *, const unsigned char *, int, EVP_MD_CTX *)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_verifyctx'; + +procedure EVP_PKEY_meth_get_encrypt(pmeth: PEVP_PKEY_METHOD; pencrypt_init: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *)" }; pencryptfn: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *, unsigned char *, size_t *, const unsigned char *, size_t)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_encrypt'; + +procedure EVP_PKEY_meth_get_decrypt(pmeth: PEVP_PKEY_METHOD; pdecrypt_init: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *)" }; pdecrypt: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *, unsigned char *, size_t *, const unsigned char *, size_t)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_decrypt'; + +procedure EVP_PKEY_meth_get_derive(pmeth: PEVP_PKEY_METHOD; pderive_init: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *)" }; pderive: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *, unsigned char *, size_t *)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_derive'; + +procedure EVP_PKEY_meth_get_ctrl(pmeth: PEVP_PKEY_METHOD; pctrl: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *, int, int, void *)" }; pctrl_str: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *, const char *, const char *)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_ctrl'; + +procedure EVP_PKEY_meth_get_digestsign(pmeth: PEVP_PKEY_METHOD; digestsign: Integer { TODO : Cannot convert original type "int (**)(EVP_MD_CTX *, unsigned char *, size_t *, const unsigned char *, size_t)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_digestsign'; + +procedure EVP_PKEY_meth_get_digestverify(pmeth: PEVP_PKEY_METHOD; digestverify: Integer { TODO : Cannot convert original type "int (**)(EVP_MD_CTX *, const unsigned char *, size_t, const unsigned char *, size_t)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_digestverify'; + +procedure EVP_PKEY_meth_get_check(pmeth: PEVP_PKEY_METHOD; pcheck: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY *)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_check'; + +procedure EVP_PKEY_meth_get_public_check(pmeth: PEVP_PKEY_METHOD; pcheck: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY *)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_public_check'; + +procedure EVP_PKEY_meth_get_param_check(pmeth: PEVP_PKEY_METHOD; pcheck: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY *)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_param_check'; + +procedure EVP_PKEY_meth_get_digest_custom(pmeth: PEVP_PKEY_METHOD; pdigest_custom: Integer { TODO : Cannot convert original type "int (**)(EVP_PKEY_CTX *, EVP_MD_CTX *)" }); cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_meth_get_digest_custom'; + +procedure EVP_add_alg_module(); cdecl; + external LIB_CRYPTO name _PU + 'EVP_add_alg_module'; + +function CMAC_CTX_new(): PCMAC_CTX; cdecl; + external LIB_CRYPTO name _PU + 'CMAC_CTX_new'; + +procedure CMAC_CTX_cleanup(ctx: PCMAC_CTX); cdecl; + external LIB_CRYPTO name _PU + 'CMAC_CTX_cleanup'; + +procedure CMAC_CTX_free(ctx: PCMAC_CTX); cdecl; + external LIB_CRYPTO name _PU + 'CMAC_CTX_free'; + +function CMAC_CTX_get0_cipher_ctx(ctx: PCMAC_CTX): PEVP_CIPHER_CTX; cdecl; + external LIB_CRYPTO name _PU + 'CMAC_CTX_get0_cipher_ctx'; + +function CMAC_CTX_copy({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PCMAC_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PCMAC_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMAC_CTX_copy'; + +function CMAC_Init(ctx: PCMAC_CTX; key: Pointer; keylen: NativeUInt; cipher: PEVP_CIPHER; impl: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMAC_Init'; + +function CMAC_Update(ctx: PCMAC_CTX; data: Pointer; dlen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMAC_Update'; + +function CMAC_Final(ctx: PCMAC_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; poutlen: PNativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMAC_Final'; + +function CMAC_resume(ctx: PCMAC_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMAC_resume'; + +function ERR_load_EC_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_EC_strings'; + +(** Returns the basic GFp ec methods which provides the basis for the + * optimized methods. + * \return EC_METHOD object + *) +function EC_GFp_simple_method(): PEC_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'EC_GFp_simple_method'; + +(** Returns GFp methods using montgomery multiplication. + * \return EC_METHOD object + *) +function EC_GFp_mont_method(): PEC_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'EC_GFp_mont_method'; + +(** Returns GFp methods using optimized methods for NIST recommended curves + * \return EC_METHOD object + *) +function EC_GFp_nist_method(): PEC_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'EC_GFp_nist_method'; + +(** Returns the basic GF2m ec method + * \return EC_METHOD object + *) +function EC_GF2m_simple_method(): PEC_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'EC_GF2m_simple_method'; + +(** Creates a new EC_GROUP object + * \param meth EC_METHOD to use + * \return newly created EC_GROUP object or NULL in case of an error. + *) +function EC_GROUP_new(meth: PEC_METHOD): PEC_GROUP; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_new'; + +(** Frees a EC_GROUP object + * \param group EC_GROUP object to be freed. + *) +procedure EC_GROUP_free(group: PEC_GROUP); cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_free'; + +(** Clears and frees a EC_GROUP object + * \param group EC_GROUP object to be cleared and freed. + *) +procedure EC_GROUP_clear_free(group: PEC_GROUP); cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_clear_free'; + +(** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD. + * \param dst destination EC_GROUP object + * \param src source EC_GROUP object + * \return 1 on success and 0 if an error occurred. + *) +function EC_GROUP_copy(dst: PEC_GROUP; src: PEC_GROUP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_copy'; + +(** Creates a new EC_GROUP object and copies the copies the content + * form src to the newly created EC_KEY object + * \param src source EC_GROUP object + * \return newly created EC_GROUP object or NULL in case of an error. + *) +function EC_GROUP_dup(src: PEC_GROUP): PEC_GROUP; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_dup'; + +(** Returns the EC_METHOD of the EC_GROUP object. + * \param group EC_GROUP object + * \return EC_METHOD used in this EC_GROUP object. + *) +function EC_GROUP_method_of(group: PEC_GROUP): PEC_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_method_of'; + +(** Returns the field type of the EC_METHOD. + * \param meth EC_METHOD object + * \return NID of the underlying field type OID. + *) +function EC_METHOD_get_field_type(meth: PEC_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_METHOD_get_field_type'; + +(** Sets the generator and its order/cofactor of a EC_GROUP object. + * \param group EC_GROUP object + * \param generator EC_POINT object with the generator. + * \param order the order of the group generated by the generator. + * \param cofactor the index of the sub-group generated by the generator + * in the group of all points on the elliptic curve. + * \return 1 on success and 0 if an error occurred + *) +function EC_GROUP_set_generator(group: PEC_GROUP; generator: PEC_POINT; order: PBIGNUM; cofactor: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_set_generator'; + +(** Returns the generator of a EC_GROUP object. + * \param group EC_GROUP object + * \return the currently used generator (possibly NULL). + *) +function EC_GROUP_get0_generator(group: PEC_GROUP): PEC_POINT; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get0_generator'; + +(** Returns the montgomery data for order(Generator) + * \param group EC_GROUP object + * \return the currently used montgomery data (possibly NULL). + *) +function EC_GROUP_get_mont_data(group: PEC_GROUP): PBN_MONT_CTX; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get_mont_data'; + +(** Gets the order of a EC_GROUP + * \param group EC_GROUP object + * \param order BIGNUM to which the order is copied + * \param ctx unused + * \return 1 on success and 0 if an error occurred + *) +function EC_GROUP_get_order(group: PEC_GROUP; order: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get_order'; + +(** Gets the order of an EC_GROUP + * \param group EC_GROUP object + * \return the group order + *) +function EC_GROUP_get0_order(group: PEC_GROUP): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get0_order'; + +(** Gets the number of bits of the order of an EC_GROUP + * \param group EC_GROUP object + * \return number of bits of group order. + *) +function EC_GROUP_order_bits(group: PEC_GROUP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_order_bits'; + +(** Gets the cofactor of a EC_GROUP + * \param group EC_GROUP object + * \param cofactor BIGNUM to which the cofactor is copied + * \param ctx unused + * \return 1 on success and 0 if an error occurred + *) +function EC_GROUP_get_cofactor(group: PEC_GROUP; cofactor: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get_cofactor'; + +(** Gets the cofactor of an EC_GROUP + * \param group EC_GROUP object + * \return the group cofactor + *) +function EC_GROUP_get0_cofactor(group: PEC_GROUP): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get0_cofactor'; + +(** Sets the name of a EC_GROUP object + * \param group EC_GROUP object + * \param nid NID of the curve name OID + *) +procedure EC_GROUP_set_curve_name(group: PEC_GROUP; nid: Integer); cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_set_curve_name'; + +(** Returns the curve name of a EC_GROUP object + * \param group EC_GROUP object + * \return NID of the curve name OID or 0 if not set. + *) +function EC_GROUP_get_curve_name(group: PEC_GROUP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get_curve_name'; + +procedure EC_GROUP_set_asn1_flag(group: PEC_GROUP; flag: Integer); cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_set_asn1_flag'; + +function EC_GROUP_get_asn1_flag(group: PEC_GROUP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get_asn1_flag'; + +procedure EC_GROUP_set_point_conversion_form(group: PEC_GROUP; form: point_conversion_form_t); cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_set_point_conversion_form'; + +function EC_GROUP_get_point_conversion_form(p1: PEC_GROUP): point_conversion_form_t; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get_point_conversion_form'; + +function EC_GROUP_get0_seed(x: PEC_GROUP): PByte; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get0_seed'; + +function EC_GROUP_get_seed_len(p1: PEC_GROUP): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get_seed_len'; + +function EC_GROUP_set_seed(p1: PEC_GROUP; p2: PByte; len: NativeUInt): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_set_seed'; + +(** Sets the parameters of a ec curve defined by y^2 = x^3 + a*x + b (for GFp) + * or y^2 + x*y = x^3 + a*x^2 + b (for GF2m) + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + *) +function EC_GROUP_set_curve(group: PEC_GROUP; p: PBIGNUM; a: PBIGNUM; b: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_set_curve'; + +(** Gets the parameters of the ec curve defined by y^2 = x^3 + a*x + b (for GFp) + * or y^2 + x*y = x^3 + a*x^2 + b (for GF2m) + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + *) +function EC_GROUP_get_curve(group: PEC_GROUP; p: PBIGNUM; a: PBIGNUM; b: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get_curve'; + +function EC_GROUP_set_curve_GFp(group: PEC_GROUP; p: PBIGNUM; a: PBIGNUM; b: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_set_curve_GFp'; + +function EC_GROUP_get_curve_GFp(group: PEC_GROUP; p: PBIGNUM; a: PBIGNUM; b: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get_curve_GFp'; + +function EC_GROUP_set_curve_GF2m(group: PEC_GROUP; p: PBIGNUM; a: PBIGNUM; b: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_set_curve_GF2m'; + +function EC_GROUP_get_curve_GF2m(group: PEC_GROUP; p: PBIGNUM; a: PBIGNUM; b: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get_curve_GF2m'; + +(** Returns the number of bits needed to represent a field element + * \param group EC_GROUP object + * \return number of bits needed to represent a field element + *) +function EC_GROUP_get_degree(group: PEC_GROUP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get_degree'; + +(** Checks whether the parameter in the EC_GROUP define a valid ec group + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if group is a valid ec group and 0 otherwise + *) +function EC_GROUP_check(group: PEC_GROUP; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_check'; + +(** Checks whether the discriminant of the elliptic curve is zero or not + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if the discriminant is not zero and 0 otherwise + *) +function EC_GROUP_check_discriminant(group: PEC_GROUP; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_check_discriminant'; + +(** Compares two EC_GROUP objects + * \param a first EC_GROUP object + * \param b second EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 0 if the groups are equal, 1 if not, or -1 on error + *) +function EC_GROUP_cmp(a: PEC_GROUP; b: PEC_GROUP; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_cmp'; + +(** Creates a new EC_GROUP object with the specified parameters defined + * over GFp (defined by the equation y^2 = x^3 + a*x + b) + * \param p BIGNUM with the prime number + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + *) +function EC_GROUP_new_curve_GFp(p: PBIGNUM; a: PBIGNUM; b: PBIGNUM; ctx: PBN_CTX): PEC_GROUP; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_new_curve_GFp'; + +(** Creates a new EC_GROUP object with the specified parameters defined + * over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b) + * \param p BIGNUM with the polynomial defining the underlying field + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + *) +function EC_GROUP_new_curve_GF2m(p: PBIGNUM; a: PBIGNUM; b: PBIGNUM; ctx: PBN_CTX): PEC_GROUP; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_new_curve_GF2m'; + +(** Creates a EC_GROUP object with a curve specified by a NID + * \param nid NID of the OID of the curve name + * \return newly created EC_GROUP object with specified curve or NULL + * if an error occurred + *) +function EC_GROUP_new_by_curve_name(nid: Integer): PEC_GROUP; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_new_by_curve_name'; + +(** Creates a new EC_GROUP object from an ECPARAMETERS object + * \param params pointer to the ECPARAMETERS object + * \return newly created EC_GROUP object with specified curve or NULL + * if an error occurred + *) +function EC_GROUP_new_from_ecparameters(params: PECPARAMETERS): PEC_GROUP; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_new_from_ecparameters'; + +(** Creates an ECPARAMETERS object for the given EC_GROUP object. + * \param group pointer to the EC_GROUP object + * \param params pointer to an existing ECPARAMETERS object or NULL + * \return pointer to the new ECPARAMETERS object or NULL + * if an error occurred. + *) +function EC_GROUP_get_ecparameters(group: PEC_GROUP; params: PECPARAMETERS): PECPARAMETERS; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get_ecparameters'; + +(** Creates a new EC_GROUP object from an ECPKPARAMETERS object + * \param params pointer to an existing ECPKPARAMETERS object, or NULL + * \return newly created EC_GROUP object with specified curve, or NULL + * if an error occurred + *) +function EC_GROUP_new_from_ecpkparameters(params: PECPKPARAMETERS): PEC_GROUP; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_new_from_ecpkparameters'; + +(** Creates an ECPKPARAMETERS object for the given EC_GROUP object. + * \param group pointer to the EC_GROUP object + * \param params pointer to an existing ECPKPARAMETERS object or NULL + * \return pointer to the new ECPKPARAMETERS object or NULL + * if an error occurred. + *) +function EC_GROUP_get_ecpkparameters(group: PEC_GROUP; params: PECPKPARAMETERS): PECPKPARAMETERS; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get_ecpkparameters'; + +function EC_get_builtin_curves(r: PEC_builtin_curve; nitems: NativeUInt): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'EC_get_builtin_curves'; + +function EC_curve_nid2nist(nid: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'EC_curve_nid2nist'; + +function EC_curve_nist2nid(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_curve_nist2nid'; + +(** Creates a new EC_POINT object for the specified EC_GROUP + * \param group EC_GROUP the underlying EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + *) +function EC_POINT_new(group: PEC_GROUP): PEC_POINT; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_new'; + +(** Frees a EC_POINT object + * \param point EC_POINT object to be freed + *) +procedure EC_POINT_free(point: PEC_POINT); cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_free'; + +(** Clears and frees a EC_POINT object + * \param point EC_POINT object to be cleared and freed + *) +procedure EC_POINT_clear_free(point: PEC_POINT); cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_clear_free'; + +(** Copies EC_POINT object + * \param dst destination EC_POINT object + * \param src source EC_POINT object + * \return 1 on success and 0 if an error occurred + *) +function EC_POINT_copy(dst: PEC_POINT; src: PEC_POINT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_copy'; + +(** Creates a new EC_POINT object and copies the content of the supplied + * EC_POINT + * \param src source EC_POINT object + * \param group underlying the EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + *) +function EC_POINT_dup(src: PEC_POINT; group: PEC_GROUP): PEC_POINT; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_dup'; + +(** Returns the EC_METHOD used in EC_POINT object + * \param point EC_POINT object + * \return the EC_METHOD used + *) +function EC_POINT_method_of(point: PEC_POINT): PEC_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_method_of'; + +(** Sets a point to infinity (neutral element) + * \param group underlying EC_GROUP object + * \param point EC_POINT to set to infinity + * \return 1 on success and 0 if an error occurred + *) +function EC_POINT_set_to_infinity(group: PEC_GROUP; point: PEC_POINT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_set_to_infinity'; + +(** Sets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param z BIGNUM with the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + *) +function EC_POINT_set_Jprojective_coordinates_GFp(group: PEC_GROUP; p: PEC_POINT; x: PBIGNUM; y: PBIGNUM; z: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_set_Jprojective_coordinates_GFp'; + +(** Gets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param z BIGNUM for the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + *) +function EC_POINT_get_Jprojective_coordinates_GFp(group: PEC_GROUP; p: PEC_POINT; x: PBIGNUM; y: PBIGNUM; z: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_get_Jprojective_coordinates_GFp'; + +(** Sets the affine coordinates of an EC_POINT + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + *) +function EC_POINT_set_affine_coordinates(group: PEC_GROUP; p: PEC_POINT; x: PBIGNUM; y: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_set_affine_coordinates'; + +(** Gets the affine coordinates of an EC_POINT. + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + *) +function EC_POINT_get_affine_coordinates(group: PEC_GROUP; p: PEC_POINT; x: PBIGNUM; y: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_get_affine_coordinates'; + +function EC_POINT_set_affine_coordinates_GFp(group: PEC_GROUP; p: PEC_POINT; x: PBIGNUM; y: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_set_affine_coordinates_GFp'; + +function EC_POINT_get_affine_coordinates_GFp(group: PEC_GROUP; p: PEC_POINT; x: PBIGNUM; y: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_get_affine_coordinates_GFp'; + +(** Sets the x9.62 compressed coordinates of a EC_POINT + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + *) +function EC_POINT_set_compressed_coordinates(group: PEC_GROUP; p: PEC_POINT; x: PBIGNUM; y_bit: Integer; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_set_compressed_coordinates'; + +function EC_POINT_set_compressed_coordinates_GFp(group: PEC_GROUP; p: PEC_POINT; x: PBIGNUM; y_bit: Integer; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_set_compressed_coordinates_GFp'; + +function EC_POINT_set_affine_coordinates_GF2m(group: PEC_GROUP; p: PEC_POINT; x: PBIGNUM; y: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_set_affine_coordinates_GF2m'; + +function EC_POINT_get_affine_coordinates_GF2m(group: PEC_GROUP; p: PEC_POINT; x: PBIGNUM; y: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_get_affine_coordinates_GF2m'; + +function EC_POINT_set_compressed_coordinates_GF2m(group: PEC_GROUP; p: PEC_POINT; x: PBIGNUM; y_bit: Integer; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_set_compressed_coordinates_GF2m'; + +(** Encodes a EC_POINT object to a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param form point conversion form + * \param buf memory buffer for the result. If NULL the function returns + * required buffer size. + * \param len length of the memory buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + *) +function EC_POINT_point2oct(group: PEC_GROUP; p: PEC_POINT; form: point_conversion_form_t; buf: PByte; len: NativeUInt; ctx: PBN_CTX): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_point2oct'; + +(** Decodes a EC_POINT from a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param buf memory buffer with the encoded ec point + * \param len length of the encoded ec point + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + *) +function EC_POINT_oct2point(group: PEC_GROUP; p: PEC_POINT; buf: PByte; len: NativeUInt; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_oct2point'; + +(** Encodes an EC_POINT object to an allocated octet string + * \param group underlying EC_GROUP object + * \param point EC_POINT object + * \param form point conversion form + * \param pbuf returns pointer to allocated buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + *) +function EC_POINT_point2buf(group: PEC_GROUP; point: PEC_POINT; form: point_conversion_form_t; pbuf: PPByte; ctx: PBN_CTX): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_point2buf'; + +function EC_POINT_point2bn(p1: PEC_GROUP; p2: PEC_POINT; form: point_conversion_form_t; p4: PBIGNUM; p5: PBN_CTX): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_point2bn'; + +function EC_POINT_bn2point(p1: PEC_GROUP; p2: PBIGNUM; p3: PEC_POINT; p4: PBN_CTX): PEC_POINT; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_bn2point'; + +function EC_POINT_point2hex(p1: PEC_GROUP; p2: PEC_POINT; form: point_conversion_form_t; p4: PBN_CTX): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_point2hex'; + +function EC_POINT_hex2point(p1: PEC_GROUP; p2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; p3: PEC_POINT; p4: PBN_CTX): PEC_POINT; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_hex2point'; + +(** Computes the sum of two EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = a + b) + * \param a EC_POINT object with the first summand + * \param b EC_POINT object with the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + *) +function EC_POINT_add(group: PEC_GROUP; r: PEC_POINT; a: PEC_POINT; b: PEC_POINT; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_add'; + +(** Computes the double of a EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = 2 * a) + * \param a EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + *) +function EC_POINT_dbl(group: PEC_GROUP; r: PEC_POINT; a: PEC_POINT; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_dbl'; + +(** Computes the inverse of a EC_POINT + * \param group underlying EC_GROUP object + * \param a EC_POINT object to be inverted (it's used for the result as well) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + *) +function EC_POINT_invert(group: PEC_GROUP; a: PEC_POINT; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_invert'; + +(** Checks whether the point is the neutral element of the group + * \param group the underlying EC_GROUP object + * \param p EC_POINT object + * \return 1 if the point is the neutral element and 0 otherwise + *) +function EC_POINT_is_at_infinity(group: PEC_GROUP; p: PEC_POINT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_is_at_infinity'; + +(** Checks whether the point is on the curve + * \param group underlying EC_GROUP object + * \param point EC_POINT object to check + * \param ctx BN_CTX object (optional) + * \return 1 if the point is on the curve, 0 if not, or -1 on error + *) +function EC_POINT_is_on_curve(group: PEC_GROUP; point: PEC_POINT; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_is_on_curve'; + +(** Compares two EC_POINTs + * \param group underlying EC_GROUP object + * \param a first EC_POINT object + * \param b second EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 1 if the points are not equal, 0 if they are, or -1 on error + *) +function EC_POINT_cmp(group: PEC_GROUP; a: PEC_POINT; b: PEC_POINT; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_cmp'; + +function EC_POINT_make_affine(group: PEC_GROUP; point: PEC_POINT; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_make_affine'; + +function EC_POINTs_make_affine(group: PEC_GROUP; num: NativeUInt; points: PPEC_POINT; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINTs_make_affine'; + +(** Computes r = generator * n + sum_{i=0}^{num-1} p[i] * m[i] + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param num number further summands + * \param p array of size num of EC_POINT objects + * \param m array of size num of BIGNUM objects + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + *) +function EC_POINTs_mul(group: PEC_GROUP; r: PEC_POINT; n: PBIGNUM; num: NativeUInt; p: PPEC_POINT; m: PPBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINTs_mul'; + +(** Computes r = generator * n + q * m + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param q EC_POINT object with the first factor of the second summand + * \param m BIGNUM with the second factor of the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + *) +function EC_POINT_mul(group: PEC_GROUP; r: PEC_POINT; n: PBIGNUM; q: PEC_POINT; m: PBIGNUM; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_POINT_mul'; + +(** Stores multiples of generator for faster point multiplication + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + *) +function EC_GROUP_precompute_mult(group: PEC_GROUP; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_precompute_mult'; + +(** Reports whether a precomputation has been done + * \param group EC_GROUP object + * \return 1 if a pre-computation has been done and 0 otherwise + *) +function EC_GROUP_have_precompute_mult(group: PEC_GROUP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_have_precompute_mult'; + +function ECPKPARAMETERS_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ECPKPARAMETERS_it'; + +function ECPKPARAMETERS_new(): PECPKPARAMETERS; cdecl; + external LIB_CRYPTO name _PU + 'ECPKPARAMETERS_new'; + +procedure ECPKPARAMETERS_free(a: PECPKPARAMETERS); cdecl; + external LIB_CRYPTO name _PU + 'ECPKPARAMETERS_free'; + +function ECPARAMETERS_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ECPARAMETERS_it'; + +function ECPARAMETERS_new(): PECPARAMETERS; cdecl; + external LIB_CRYPTO name _PU + 'ECPARAMETERS_new'; + +procedure ECPARAMETERS_free(a: PECPARAMETERS); cdecl; + external LIB_CRYPTO name _PU + 'ECPARAMETERS_free'; + +(********************************************************************) +function EC_GROUP_get_basis_type(p1: PEC_GROUP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get_basis_type'; + +function EC_GROUP_get_trinomial_basis(p1: PEC_GROUP; k: PCardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get_trinomial_basis'; + +function EC_GROUP_get_pentanomial_basis(p1: PEC_GROUP; k1: PCardinal; k2: PCardinal; k3: PCardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_GROUP_get_pentanomial_basis'; + +function d2i_ECPKParameters(p1: PPEC_GROUP; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PEC_GROUP; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ECPKParameters'; + +function i2d_ECPKParameters(p1: PEC_GROUP; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ECPKParameters'; + +function ECPKParameters_print(bp: PBIO; x: PEC_GROUP; off: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ECPKParameters_print'; + +function ECPKParameters_print_fp(fp: PPointer; x: PEC_GROUP; off: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ECPKParameters_print_fp'; + +(** Creates a new EC_KEY object. + * \return EC_KEY object or NULL if an error occurred. + *) +function EC_KEY_new(): PEC_KEY; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_new'; + +function EC_KEY_get_flags(key: PEC_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_get_flags'; + +procedure EC_KEY_set_flags(key: PEC_KEY; flags: Integer); cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_set_flags'; + +procedure EC_KEY_clear_flags(key: PEC_KEY; flags: Integer); cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_clear_flags'; + +(** Creates a new EC_KEY object using a named curve as underlying + * EC_GROUP object. + * \param nid NID of the named curve. + * \return EC_KEY object or NULL if an error occurred. + *) +function EC_KEY_new_by_curve_name(nid: Integer): PEC_KEY; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_new_by_curve_name'; + +(** Frees a EC_KEY object. + * \param key EC_KEY object to be freed. + *) +procedure EC_KEY_free(key: PEC_KEY); cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_free'; + +(** Copies a EC_KEY object. + * \param dst destination EC_KEY object + * \param src src EC_KEY object + * \return dst or NULL if an error occurred. + *) +function EC_KEY_copy(dst: PEC_KEY; src: PEC_KEY): PEC_KEY; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_copy'; + +(** Creates a new EC_KEY object and copies the content from src to it. + * \param src the source EC_KEY object + * \return newly created EC_KEY object or NULL if an error occurred. + *) +function EC_KEY_dup(src: PEC_KEY): PEC_KEY; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_dup'; + +(** Increases the internal reference count of a EC_KEY object. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + *) +function EC_KEY_up_ref(key: PEC_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_up_ref'; + +(** Returns the ENGINE object of a EC_KEY object + * \param eckey EC_KEY object + * \return the ENGINE object (possibly NULL). + *) +function EC_KEY_get0_engine(eckey: PEC_KEY): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_get0_engine'; + +(** Returns the EC_GROUP object of a EC_KEY object + * \param key EC_KEY object + * \return the EC_GROUP object (possibly NULL). + *) +function EC_KEY_get0_group(key: PEC_KEY): PEC_GROUP; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_get0_group'; + +(** Sets the EC_GROUP of a EC_KEY object. + * \param key EC_KEY object + * \param group EC_GROUP to use in the EC_KEY object (note: the EC_KEY + * object will use an own copy of the EC_GROUP). + * \return 1 on success and 0 if an error occurred. + *) +function EC_KEY_set_group(key: PEC_KEY; group: PEC_GROUP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_set_group'; + +(** Returns the private key of a EC_KEY object. + * \param key EC_KEY object + * \return a BIGNUM with the private key (possibly NULL). + *) +function EC_KEY_get0_private_key(key: PEC_KEY): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_get0_private_key'; + +(** Sets the private key of a EC_KEY object. + * \param key EC_KEY object + * \param prv BIGNUM with the private key (note: the EC_KEY object + * will use an own copy of the BIGNUM). + * \return 1 on success and 0 if an error occurred. + *) +function EC_KEY_set_private_key(key: PEC_KEY; prv: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_set_private_key'; + +(** Returns the public key of a EC_KEY object. + * \param key the EC_KEY object + * \return a EC_POINT object with the public key (possibly NULL) + *) +function EC_KEY_get0_public_key(key: PEC_KEY): PEC_POINT; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_get0_public_key'; + +(** Sets the public key of a EC_KEY object. + * \param key EC_KEY object + * \param pub EC_POINT object with the public key (note: the EC_KEY object + * will use an own copy of the EC_POINT object). + * \return 1 on success and 0 if an error occurred. + *) +function EC_KEY_set_public_key(key: PEC_KEY; pub: PEC_POINT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_set_public_key'; + +function EC_KEY_get_enc_flags(key: PEC_KEY): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_get_enc_flags'; + +procedure EC_KEY_set_enc_flags(eckey: PEC_KEY; flags: Cardinal); cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_set_enc_flags'; + +function EC_KEY_get_conv_form(key: PEC_KEY): point_conversion_form_t; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_get_conv_form'; + +procedure EC_KEY_set_conv_form(eckey: PEC_KEY; cform: point_conversion_form_t); cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_set_conv_form'; + +function EC_KEY_set_ex_data(key: PEC_KEY; idx: Integer; arg: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_set_ex_data'; + +function EC_KEY_get_ex_data(key: PEC_KEY; idx: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_get_ex_data'; + +procedure EC_KEY_set_asn1_flag(eckey: PEC_KEY; asn1_flag: Integer); cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_set_asn1_flag'; + +(** Creates a table of pre-computed multiples of the generator to + * accelerate further EC_KEY operations. + * \param key EC_KEY object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred. + *) +function EC_KEY_precompute_mult(key: PEC_KEY; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_precompute_mult'; + +(** Creates a new ec private (and optional a new public) key. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + *) +function EC_KEY_generate_key(key: PEC_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_generate_key'; + +(** Verifies that a private and/or public key is valid. + * \param key the EC_KEY object + * \return 1 on success and 0 otherwise. + *) +function EC_KEY_check_key(key: PEC_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_check_key'; + +(** Indicates if an EC_KEY can be used for signing. + * \param eckey the EC_KEY object + * \return 1 if can can sign and 0 otherwise. + *) +function EC_KEY_can_sign(eckey: PEC_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_can_sign'; + +(** Sets a public key from affine coordinates performing + * necessary NIST PKV tests. + * \param key the EC_KEY object + * \param x public key x coordinate + * \param y public key y coordinate + * \return 1 on success and 0 otherwise. + *) +function EC_KEY_set_public_key_affine_coordinates(key: PEC_KEY; x: PBIGNUM; y: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_set_public_key_affine_coordinates'; + +(** Encodes an EC_KEY public key to an allocated octet string + * \param key key to encode + * \param form point conversion form + * \param pbuf returns pointer to allocated buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + *) +function EC_KEY_key2buf(key: PEC_KEY; form: point_conversion_form_t; pbuf: PPByte; ctx: PBN_CTX): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_key2buf'; + +(** Decodes a EC_KEY public key from a octet string + * \param key key to decode + * \param buf memory buffer with the encoded ec point + * \param len length of the encoded ec point + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + *) +function EC_KEY_oct2key(key: PEC_KEY; buf: PByte; len: NativeUInt; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_oct2key'; + +(** Decodes an EC_KEY private key from an octet string + * \param key key to decode + * \param buf memory buffer with the encoded private key + * \param len length of the encoded key + * \return 1 on success and 0 if an error occurred + *) +function EC_KEY_oct2priv(key: PEC_KEY; buf: PByte; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_oct2priv'; + +(** Encodes a EC_KEY private key to an octet string + * \param key key to encode + * \param buf memory buffer for the result. If NULL the function returns + * required buffer size. + * \param len length of the memory buffer + * \return the length of the encoded octet string or 0 if an error occurred + *) +function EC_KEY_priv2oct(key: PEC_KEY; buf: PByte; len: NativeUInt): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_priv2oct'; + +(** Encodes an EC_KEY private key to an allocated octet string + * \param eckey key to encode + * \param pbuf returns pointer to allocated buffer + * \return the length of the encoded octet string or 0 if an error occurred + *) +function EC_KEY_priv2buf(eckey: PEC_KEY; pbuf: PPByte): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_priv2buf'; + +(** Decodes a private key from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded private key + * \param len length of the DER encoded private key + * \return the decoded private key or NULL if an error occurred. + *) +function d2i_ECPrivateKey(key: PPEC_KEY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PEC_KEY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ECPrivateKey'; + +(** Encodes a private key object and stores the result in a buffer. + * \param key the EC_KEY object to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + *) +function i2d_ECPrivateKey(key: PEC_KEY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ECPrivateKey'; + +(** Decodes ec parameter from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded ec parameters + * \param len length of the DER encoded ec parameters + * \return a EC_KEY object with the decoded parameters or NULL if an error + * occurred. + *) +function d2i_ECParameters(key: PPEC_KEY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PEC_KEY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ECParameters'; + +(** Encodes ec parameter and stores the result in a buffer. + * \param key the EC_KEY object with ec parameters to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + *) +function i2d_ECParameters(key: PEC_KEY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ECParameters'; + +(** Decodes a ec public key from a octet string. + * \param key a pointer to a EC_KEY object which should be used + * \param in memory buffer with the encoded public key + * \param len length of the encoded public key + * \return EC_KEY object with decoded public key or NULL if an error + * occurred. + *) +function o2i_ECPublicKey(key: PPEC_KEY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PEC_KEY; cdecl; + external LIB_CRYPTO name _PU + 'o2i_ECPublicKey'; + +(** Encodes a ec public key in an octet string. + * \param key the EC_KEY object with the public key + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred + *) +function i2o_ECPublicKey(key: PEC_KEY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2o_ECPublicKey'; + +(** Prints out the ec parameters on human readable form. + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + *) +function ECParameters_print(bp: PBIO; key: PEC_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ECParameters_print'; + +(** Prints out the contents of a EC_KEY object + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + *) +function EC_KEY_print(bp: PBIO; key: PEC_KEY; off: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_print'; + +(** Prints out the ec parameters on human readable form. + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + *) +function ECParameters_print_fp(fp: PPointer; key: PEC_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ECParameters_print_fp'; + +(** Prints out the contents of a EC_KEY object + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + *) +function EC_KEY_print_fp(fp: PPointer; key: PEC_KEY; off: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_print_fp'; + +function EC_KEY_OpenSSL(): PEC_KEY_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_OpenSSL'; + +function EC_KEY_get_default_method(): PEC_KEY_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_get_default_method'; + +procedure EC_KEY_set_default_method(meth: PEC_KEY_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_set_default_method'; + +function EC_KEY_get_method(key: PEC_KEY): PEC_KEY_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_get_method'; + +function EC_KEY_set_method(key: PEC_KEY; meth: PEC_KEY_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_set_method'; + +function EC_KEY_new_method(engine: PENGINE): PEC_KEY; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_new_method'; + +function ECDH_KDF_X9_62({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outlen: NativeUInt; Z: PByte; Zlen: NativeUInt; sinfo: PByte; sinfolen: NativeUInt; md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ECDH_KDF_X9_62'; + +type + ECDH_compute_key_KDF = function({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: Pointer; inlen: NativeUInt; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: Pointer; outlen: PNativeUInt): Pointer; cdecl; + +function ECDH_compute_key({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: Pointer; outlen: NativeUInt; pub_key: PEC_POINT; ecdh: PEC_KEY; KDF: ECDH_compute_key_KDF): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ECDH_compute_key'; + +function ECDSA_SIG_new(): PECDSA_SIG; cdecl; + external LIB_CRYPTO name _PU + 'ECDSA_SIG_new'; + +procedure ECDSA_SIG_free(sig: PECDSA_SIG); cdecl; + external LIB_CRYPTO name _PU + 'ECDSA_SIG_free'; + +function i2d_ECDSA_SIG(sig: PECDSA_SIG; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ECDSA_SIG'; + +function d2i_ECDSA_SIG(sig: PPECDSA_SIG; pp: PPByte; len: Integer): PECDSA_SIG; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ECDSA_SIG'; + +procedure ECDSA_SIG_get0(sig: PECDSA_SIG; pr: PPBIGNUM; ps: PPBIGNUM); cdecl; + external LIB_CRYPTO name _PU + 'ECDSA_SIG_get0'; + +function ECDSA_SIG_get0_r(sig: PECDSA_SIG): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'ECDSA_SIG_get0_r'; + +function ECDSA_SIG_get0_s(sig: PECDSA_SIG): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'ECDSA_SIG_get0_s'; + +function ECDSA_SIG_set0(sig: PECDSA_SIG; r: PBIGNUM; s: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ECDSA_SIG_set0'; + +function ECDSA_do_sign(dgst: PByte; dgst_len: Integer; eckey: PEC_KEY): PECDSA_SIG; cdecl; + external LIB_CRYPTO name _PU + 'ECDSA_do_sign'; + +function ECDSA_do_sign_ex(dgst: PByte; dgstlen: Integer; kinv: PBIGNUM; rp: PBIGNUM; eckey: PEC_KEY): PECDSA_SIG; cdecl; + external LIB_CRYPTO name _PU + 'ECDSA_do_sign_ex'; + +function ECDSA_do_verify(dgst: PByte; dgst_len: Integer; sig: PECDSA_SIG; eckey: PEC_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ECDSA_do_verify'; + +function ECDSA_sign_setup(eckey: PEC_KEY; ctx: PBN_CTX; kinv: PPBIGNUM; rp: PPBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ECDSA_sign_setup'; + +function ECDSA_sign({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; dgst: PByte; dgstlen: Integer; sig: PByte; siglen: PCardinal; eckey: PEC_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ECDSA_sign'; + +function ECDSA_sign_ex({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; dgst: PByte; dgstlen: Integer; sig: PByte; siglen: PCardinal; kinv: PBIGNUM; rp: PBIGNUM; eckey: PEC_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ECDSA_sign_ex'; + +function ECDSA_verify({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; dgst: PByte; dgstlen: Integer; sig: PByte; siglen: Integer; eckey: PEC_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ECDSA_verify'; + +function ECDSA_size(eckey: PEC_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ECDSA_size'; + +function EC_KEY_METHOD_new(meth: PEC_KEY_METHOD): PEC_KEY_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_METHOD_new'; + +procedure EC_KEY_METHOD_free(meth: PEC_KEY_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_METHOD_free'; + +type + EC_KEY_METHOD_set_init_init = function(key: PEC_KEY): Integer; cdecl; + +type + EC_KEY_METHOD_set_init_finish = procedure(key: PEC_KEY); cdecl; + +type + EC_KEY_METHOD_set_init_copy = function(dest: PEC_KEY; src: PEC_KEY): Integer; cdecl; + +type + EC_KEY_METHOD_set_init_set_group = function(key: PEC_KEY; grp: PEC_GROUP): Integer; cdecl; + +type + EC_KEY_METHOD_set_init_set_private = function(key: PEC_KEY; priv_key: PBIGNUM): Integer; cdecl; + +type + EC_KEY_METHOD_set_init_set_public = function(key: PEC_KEY; pub_key: PEC_POINT): Integer; cdecl; + +procedure EC_KEY_METHOD_set_init(meth: PEC_KEY_METHOD; init: EC_KEY_METHOD_set_init_init; finish: EC_KEY_METHOD_set_init_finish; copy: EC_KEY_METHOD_set_init_copy; set_group: EC_KEY_METHOD_set_init_set_group; set_private: EC_KEY_METHOD_set_init_set_private; set_public: EC_KEY_METHOD_set_init_set_public); cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_METHOD_set_init'; + +type + EC_KEY_METHOD_set_keygen_keygen = function(key: PEC_KEY): Integer; cdecl; + +procedure EC_KEY_METHOD_set_keygen(meth: PEC_KEY_METHOD; keygen: EC_KEY_METHOD_set_keygen_keygen); cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_METHOD_set_keygen'; + +type + EC_KEY_METHOD_set_compute_key_ckey = function(psec: PPByte; pseclen: PNativeUInt; pub_key: PEC_POINT; ecdh: PEC_KEY): Integer; cdecl; + +procedure EC_KEY_METHOD_set_compute_key(meth: PEC_KEY_METHOD; ckey: EC_KEY_METHOD_set_compute_key_ckey); cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_METHOD_set_compute_key'; + +type + EC_KEY_METHOD_set_sign_sign = function({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; dgst: PByte; dlen: Integer; sig: PByte; siglen: PCardinal; kinv: PBIGNUM; r: PBIGNUM; eckey: PEC_KEY): Integer; cdecl; + +type + EC_KEY_METHOD_set_sign_sign_setup = function(eckey: PEC_KEY; ctx_in: PBN_CTX; kinvp: PPBIGNUM; rp: PPBIGNUM): Integer; cdecl; + +type + EC_KEY_METHOD_set_sign_sign_sig = function(dgst: PByte; dgst_len: Integer; in_kinv: PBIGNUM; in_r: PBIGNUM; eckey: PEC_KEY): PECDSA_SIG_st; cdecl; + +procedure EC_KEY_METHOD_set_sign(meth: PEC_KEY_METHOD; sign: EC_KEY_METHOD_set_sign_sign; sign_setup: EC_KEY_METHOD_set_sign_sign_setup; sign_sig: EC_KEY_METHOD_set_sign_sign_sig); cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_METHOD_set_sign'; + +type + EC_KEY_METHOD_set_verify_verify = function({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; dgst: PByte; dgst_len: Integer; sigbuf: PByte; sig_len: Integer; eckey: PEC_KEY): Integer; cdecl; + +type + EC_KEY_METHOD_set_verify_verify_sig = function(dgst: PByte; dgst_len: Integer; sig: PECDSA_SIG; eckey: PEC_KEY): Integer; cdecl; + +procedure EC_KEY_METHOD_set_verify(meth: PEC_KEY_METHOD; verify: EC_KEY_METHOD_set_verify_verify; verify_sig: EC_KEY_METHOD_set_verify_verify_sig); cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_METHOD_set_verify'; + +procedure EC_KEY_METHOD_get_init(meth: PEC_KEY_METHOD; pinit: Integer { TODO : Cannot convert original type "int (**)(EC_KEY *)" }; pfinish: Integer { TODO : Cannot convert original type "void (**)(EC_KEY *)" }; pcopy: Integer { TODO : Cannot convert original type "int (**)(EC_KEY *, const EC_KEY *)" }; pset_group: Integer { TODO : Cannot convert original type "int (**)(EC_KEY *, const EC_GROUP *)" }; pset_private: Integer { TODO : Cannot convert original type "int (**)(EC_KEY *, const BIGNUM *)" }; pset_public: Integer { TODO : Cannot convert original type "int (**)(EC_KEY *, const EC_POINT *)" }); cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_METHOD_get_init'; + +procedure EC_KEY_METHOD_get_keygen(meth: PEC_KEY_METHOD; pkeygen: Integer { TODO : Cannot convert original type "int (**)(EC_KEY *)" }); cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_METHOD_get_keygen'; + +procedure EC_KEY_METHOD_get_compute_key(meth: PEC_KEY_METHOD; pck: Integer { TODO : Cannot convert original type "int (**)(unsigned char **, size_t *, const EC_POINT *, const EC_KEY *)" }); cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_METHOD_get_compute_key'; + +procedure EC_KEY_METHOD_get_sign(meth: PEC_KEY_METHOD; psign: Integer { TODO : Cannot convert original type "int (**)(int, const unsigned char *, int, unsigned char *, unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *)" }; psign_setup: Integer { TODO : Cannot convert original type "int (**)(EC_KEY *, BN_CTX *, BIGNUM **, BIGNUM **)" }; psign_sig: Integer { TODO : Cannot convert original type "ECDSA_SIG *(**)(const unsigned char *, int, const BIGNUM *, const BIGNUM *, EC_KEY *)" }); cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_METHOD_get_sign'; + +procedure EC_KEY_METHOD_get_verify(meth: PEC_KEY_METHOD; pverify: Integer { TODO : Cannot convert original type "int (**)(int, const unsigned char *, int, const unsigned char *, int, EC_KEY *)" }; pverify_sig: Integer { TODO : Cannot convert original type "int (**)(const unsigned char *, int, const ECDSA_SIG *, EC_KEY *)" }); cdecl; + external LIB_CRYPTO name _PU + 'EC_KEY_METHOD_get_verify'; + +function ERR_load_RSA_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_RSA_strings'; + +function RSA_new(): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'RSA_new'; + +function RSA_new_method(engine: PENGINE): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'RSA_new_method'; + +function RSA_bits(rsa: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_bits'; + +function RSA_size(rsa: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_size'; + +function RSA_security_bits(rsa: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_security_bits'; + +function RSA_set0_key(r: PRSA; n: PBIGNUM; e: PBIGNUM; d: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_set0_key'; + +function RSA_set0_factors(r: PRSA; p: PBIGNUM; q: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_set0_factors'; + +function RSA_set0_crt_params(r: PRSA; dmp1: PBIGNUM; dmq1: PBIGNUM; iqmp: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_set0_crt_params'; + +function RSA_set0_multi_prime_params(r: PRSA; primes: PPBIGNUM; exps: PPBIGNUM; coeffs: PPBIGNUM; pnum: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_set0_multi_prime_params'; + +procedure RSA_get0_key(r: PRSA; n: PPBIGNUM; e: PPBIGNUM; d: PPBIGNUM); cdecl; + external LIB_CRYPTO name _PU + 'RSA_get0_key'; + +procedure RSA_get0_factors(r: PRSA; p: PPBIGNUM; q: PPBIGNUM); cdecl; + external LIB_CRYPTO name _PU + 'RSA_get0_factors'; + +function RSA_get_multi_prime_extra_count(r: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_get_multi_prime_extra_count'; + +function RSA_get0_multi_prime_factors(r: PRSA; primes: PPBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_get0_multi_prime_factors'; + +procedure RSA_get0_crt_params(r: PRSA; dmp1: PPBIGNUM; dmq1: PPBIGNUM; iqmp: PPBIGNUM); cdecl; + external LIB_CRYPTO name _PU + 'RSA_get0_crt_params'; + +function RSA_get0_multi_prime_crt_params(r: PRSA; exps: PPBIGNUM; coeffs: PPBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_get0_multi_prime_crt_params'; + +function RSA_get0_n(d: PRSA): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'RSA_get0_n'; + +function RSA_get0_e(d: PRSA): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'RSA_get0_e'; + +function RSA_get0_d(d: PRSA): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'RSA_get0_d'; + +function RSA_get0_p(d: PRSA): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'RSA_get0_p'; + +function RSA_get0_q(d: PRSA): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'RSA_get0_q'; + +function RSA_get0_dmp1(r: PRSA): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'RSA_get0_dmp1'; + +function RSA_get0_dmq1(r: PRSA): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'RSA_get0_dmq1'; + +function RSA_get0_iqmp(r: PRSA): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'RSA_get0_iqmp'; + +function RSA_get0_pss_params(r: PRSA): PRSA_PSS_PARAMS; cdecl; + external LIB_CRYPTO name _PU + 'RSA_get0_pss_params'; + +procedure RSA_clear_flags(r: PRSA; flags: Integer); cdecl; + external LIB_CRYPTO name _PU + 'RSA_clear_flags'; + +function RSA_test_flags(r: PRSA; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_test_flags'; + +procedure RSA_set_flags(r: PRSA; flags: Integer); cdecl; + external LIB_CRYPTO name _PU + 'RSA_set_flags'; + +function RSA_get_version(r: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_get_version'; + +function RSA_get0_engine(r: PRSA): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'RSA_get0_engine'; + +type + RSA_generate_key_callback = procedure(p1: Integer; p2: Integer; p3: Pointer); cdecl; + +function RSA_generate_key(bits: Integer; e: Cardinal; callback: RSA_generate_key_callback; cb_arg: Pointer): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'RSA_generate_key'; + +function RSA_generate_key_ex(rsa: PRSA; bits: Integer; e: PBIGNUM; cb: PBN_GENCB): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_generate_key_ex'; + +function RSA_generate_multi_prime_key(rsa: PRSA; bits: Integer; primes: Integer; e: PBIGNUM; cb: PBN_GENCB): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_generate_multi_prime_key'; + +function RSA_X931_derive_ex(rsa: PRSA; p1: PBIGNUM; p2: PBIGNUM; q1: PBIGNUM; q2: PBIGNUM; Xp1: PBIGNUM; Xp2: PBIGNUM; Xp: PBIGNUM; Xq1: PBIGNUM; Xq2: PBIGNUM; Xq: PBIGNUM; e: PBIGNUM; cb: PBN_GENCB): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_X931_derive_ex'; + +function RSA_X931_generate_key_ex(rsa: PRSA; bits: Integer; e: PBIGNUM; cb: PBN_GENCB): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_X931_generate_key_ex'; + +function RSA_check_key(p1: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_check_key'; + +function RSA_check_key_ex(p1: PRSA; cb: PBN_GENCB): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_check_key_ex'; + +function RSA_public_encrypt(flen: Integer; from: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; rsa: PRSA; padding: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_public_encrypt'; + +function RSA_private_encrypt(flen: Integer; from: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; rsa: PRSA; padding: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_private_encrypt'; + +function RSA_public_decrypt(flen: Integer; from: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; rsa: PRSA; padding: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_public_decrypt'; + +function RSA_private_decrypt(flen: Integer; from: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; rsa: PRSA; padding: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_private_decrypt'; + +procedure RSA_free(r: PRSA); cdecl; + external LIB_CRYPTO name _PU + 'RSA_free'; + +function RSA_up_ref(r: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_up_ref'; + +function RSA_flags(r: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_flags'; + +procedure RSA_set_default_method(meth: PRSA_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'RSA_set_default_method'; + +function RSA_get_default_method(): PRSA_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'RSA_get_default_method'; + +function RSA_null_method(): PRSA_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'RSA_null_method'; + +function RSA_get_method(rsa: PRSA): PRSA_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'RSA_get_method'; + +function RSA_set_method(rsa: PRSA; meth: PRSA_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_set_method'; + +function RSA_PKCS1_OpenSSL(): PRSA_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'RSA_PKCS1_OpenSSL'; + +function RSA_pkey_ctx_ctrl(ctx: PEVP_PKEY_CTX; optype: Integer; cmd: Integer; p1: Integer; p2: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_pkey_ctx_ctrl'; + +function d2i_RSAPublicKey(a: PPRSA; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_RSAPublicKey'; + +function i2d_RSAPublicKey(a: PRSA; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_RSAPublicKey'; + +function RSAPublicKey_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'RSAPublicKey_it'; + +function d2i_RSAPrivateKey(a: PPRSA; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_RSAPrivateKey'; + +function i2d_RSAPrivateKey(a: PRSA; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_RSAPrivateKey'; + +function RSAPrivateKey_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'RSAPrivateKey_it'; + +function RSA_PSS_PARAMS_new(): PRSA_PSS_PARAMS; cdecl; + external LIB_CRYPTO name _PU + 'RSA_PSS_PARAMS_new'; + +procedure RSA_PSS_PARAMS_free(a: PRSA_PSS_PARAMS); cdecl; + external LIB_CRYPTO name _PU + 'RSA_PSS_PARAMS_free'; + +function d2i_RSA_PSS_PARAMS(a: PPRSA_PSS_PARAMS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PRSA_PSS_PARAMS; cdecl; + external LIB_CRYPTO name _PU + 'd2i_RSA_PSS_PARAMS'; + +function i2d_RSA_PSS_PARAMS(a: PRSA_PSS_PARAMS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_RSA_PSS_PARAMS'; + +function RSA_PSS_PARAMS_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'RSA_PSS_PARAMS_it'; + +function RSA_OAEP_PARAMS_new(): PRSA_OAEP_PARAMS; cdecl; + external LIB_CRYPTO name _PU + 'RSA_OAEP_PARAMS_new'; + +procedure RSA_OAEP_PARAMS_free(a: PRSA_OAEP_PARAMS); cdecl; + external LIB_CRYPTO name _PU + 'RSA_OAEP_PARAMS_free'; + +function d2i_RSA_OAEP_PARAMS(a: PPRSA_OAEP_PARAMS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PRSA_OAEP_PARAMS; cdecl; + external LIB_CRYPTO name _PU + 'd2i_RSA_OAEP_PARAMS'; + +function i2d_RSA_OAEP_PARAMS(a: PRSA_OAEP_PARAMS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_RSA_OAEP_PARAMS'; + +function RSA_OAEP_PARAMS_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'RSA_OAEP_PARAMS_it'; + +function RSA_print_fp(fp: PPointer; r: PRSA; offset: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_print_fp'; + +function RSA_print(bp: PBIO; r: PRSA; offset: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_print'; + +function RSA_sign({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; m: PByte; m_length: Cardinal; sigret: PByte; siglen: PCardinal; rsa: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_sign'; + +function RSA_verify({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; m: PByte; m_length: Cardinal; sigbuf: PByte; siglen: Cardinal; rsa: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_verify'; + +function RSA_sign_ASN1_OCTET_STRING({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; m: PByte; m_length: Cardinal; sigret: PByte; siglen: PCardinal; rsa: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_sign_ASN1_OCTET_STRING'; + +function RSA_verify_ASN1_OCTET_STRING({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; m: PByte; m_length: Cardinal; sigbuf: PByte; siglen: Cardinal; rsa: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_verify_ASN1_OCTET_STRING'; + +function RSA_blinding_on(rsa: PRSA; ctx: PBN_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_blinding_on'; + +procedure RSA_blinding_off(rsa: PRSA); cdecl; + external LIB_CRYPTO name _PU + 'RSA_blinding_off'; + +function RSA_setup_blinding(rsa: PRSA; ctx: PBN_CTX): PBN_BLINDING; cdecl; + external LIB_CRYPTO name _PU + 'RSA_setup_blinding'; + +function RSA_padding_add_PKCS1_type_1({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; tlen: Integer; f: PByte; fl: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_padding_add_PKCS1_type_1'; + +function RSA_padding_check_PKCS1_type_1({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; tlen: Integer; f: PByte; fl: Integer; rsa_len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_padding_check_PKCS1_type_1'; + +function RSA_padding_add_PKCS1_type_2({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; tlen: Integer; f: PByte; fl: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_padding_add_PKCS1_type_2'; + +function RSA_padding_check_PKCS1_type_2({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; tlen: Integer; f: PByte; fl: Integer; rsa_len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_padding_check_PKCS1_type_2'; + +function PKCS1_MGF1(mask: PByte; len: Integer; seed: PByte; seedlen: Integer; dgst: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS1_MGF1'; + +function RSA_padding_add_PKCS1_OAEP({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; tlen: Integer; f: PByte; fl: Integer; p: PByte; pl: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_padding_add_PKCS1_OAEP'; + +function RSA_padding_check_PKCS1_OAEP({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; tlen: Integer; f: PByte; fl: Integer; rsa_len: Integer; p: PByte; pl: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_padding_check_PKCS1_OAEP'; + +function RSA_padding_add_PKCS1_OAEP_mgf1({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; tlen: Integer; from: PByte; flen: Integer; param: PByte; plen: Integer; md: PEVP_MD; mgf1md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_padding_add_PKCS1_OAEP_mgf1'; + +function RSA_padding_check_PKCS1_OAEP_mgf1({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; tlen: Integer; from: PByte; flen: Integer; num: Integer; param: PByte; plen: Integer; md: PEVP_MD; mgf1md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_padding_check_PKCS1_OAEP_mgf1'; + +function RSA_padding_add_SSLv23({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; tlen: Integer; f: PByte; fl: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_padding_add_SSLv23'; + +function RSA_padding_check_SSLv23({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; tlen: Integer; f: PByte; fl: Integer; rsa_len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_padding_check_SSLv23'; + +function RSA_padding_add_none({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; tlen: Integer; f: PByte; fl: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_padding_add_none'; + +function RSA_padding_check_none({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; tlen: Integer; f: PByte; fl: Integer; rsa_len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_padding_check_none'; + +function RSA_padding_add_X931({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; tlen: Integer; f: PByte; fl: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_padding_add_X931'; + +function RSA_padding_check_X931({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; tlen: Integer; f: PByte; fl: Integer; rsa_len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_padding_check_X931'; + +function RSA_X931_hash_id(nid: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_X931_hash_id'; + +function RSA_verify_PKCS1_PSS(rsa: PRSA; mHash: PByte; Hash: PEVP_MD; EM: PByte; sLen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_verify_PKCS1_PSS'; + +function RSA_padding_add_PKCS1_PSS(rsa: PRSA; EM: PByte; mHash: PByte; Hash: PEVP_MD; sLen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_padding_add_PKCS1_PSS'; + +function RSA_verify_PKCS1_PSS_mgf1(rsa: PRSA; mHash: PByte; Hash: PEVP_MD; mgf1Hash: PEVP_MD; EM: PByte; sLen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_verify_PKCS1_PSS_mgf1'; + +function RSA_padding_add_PKCS1_PSS_mgf1(rsa: PRSA; EM: PByte; mHash: PByte; Hash: PEVP_MD; mgf1Hash: PEVP_MD; sLen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_padding_add_PKCS1_PSS_mgf1'; + +function RSA_set_ex_data(r: PRSA; idx: Integer; arg: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_set_ex_data'; + +function RSA_get_ex_data(r: PRSA; idx: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_get_ex_data'; + +function RSAPublicKey_dup(rsa: PRSA): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'RSAPublicKey_dup'; + +function RSAPrivateKey_dup(rsa: PRSA): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'RSAPrivateKey_dup'; + +function RSA_meth_new(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; flags: Integer): PRSA_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_new'; + +procedure RSA_meth_free(meth: PRSA_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_free'; + +function RSA_meth_dup(meth: PRSA_METHOD): PRSA_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_dup'; + +function RSA_meth_get0_name(meth: PRSA_METHOD): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_get0_name'; + +function RSA_meth_set1_name(meth: PRSA_METHOD; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_set1_name'; + +function RSA_meth_get_flags(meth: PRSA_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_get_flags'; + +function RSA_meth_set_flags(meth: PRSA_METHOD; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_set_flags'; + +function RSA_meth_get0_app_data(meth: PRSA_METHOD): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_get0_app_data'; + +function RSA_meth_set0_app_data(meth: PRSA_METHOD; app_data: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_set0_app_data'; + +//function RSA_meth_get_pub_enc(flen: Integerfrom: PByte{$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PBytersa: PRSApadding: Integermeth: PRSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(int, const unsigned char *, unsigned char *, RSA *, int)" }; cdecl; +// external LIB_CRYPTO name _PU + 'RSA_meth_get_pub_enc'; + +type + RSA_meth_set_pub_enc_pub_enc = function(flen: Integer; from: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; rsa: PRSA; padding: Integer): Integer; cdecl; + +function RSA_meth_set_pub_enc(rsa: PRSA_METHOD; pub_enc: RSA_meth_set_pub_enc_pub_enc): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_set_pub_enc'; + +//function RSA_meth_get_pub_dec(flen: Integerfrom: PByte{$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PBytersa: PRSApadding: Integermeth: PRSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(int, const unsigned char *, unsigned char *, RSA *, int)" }; cdecl; +// external LIB_CRYPTO name _PU + 'RSA_meth_get_pub_dec'; + +type + RSA_meth_set_pub_dec_pub_dec = function(flen: Integer; from: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; rsa: PRSA; padding: Integer): Integer; cdecl; + +function RSA_meth_set_pub_dec(rsa: PRSA_METHOD; pub_dec: RSA_meth_set_pub_dec_pub_dec): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_set_pub_dec'; + +//function RSA_meth_get_priv_enc(flen: Integerfrom: PByte{$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PBytersa: PRSApadding: Integermeth: PRSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(int, const unsigned char *, unsigned char *, RSA *, int)" }; cdecl; +// external LIB_CRYPTO name _PU + 'RSA_meth_get_priv_enc'; + +type + RSA_meth_set_priv_enc_priv_enc = function(flen: Integer; from: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; rsa: PRSA; padding: Integer): Integer; cdecl; + +function RSA_meth_set_priv_enc(rsa: PRSA_METHOD; priv_enc: RSA_meth_set_priv_enc_priv_enc): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_set_priv_enc'; + +//function RSA_meth_get_priv_dec(flen: Integerfrom: PByte{$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PBytersa: PRSApadding: Integermeth: PRSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(int, const unsigned char *, unsigned char *, RSA *, int)" }; cdecl; +// external LIB_CRYPTO name _PU + 'RSA_meth_get_priv_dec'; + +type + RSA_meth_set_priv_dec_priv_dec = function(flen: Integer; from: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PByte; rsa: PRSA; padding: Integer): Integer; cdecl; + +function RSA_meth_set_priv_dec(rsa: PRSA_METHOD; priv_dec: RSA_meth_set_priv_dec_priv_dec): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_set_priv_dec'; + +//function RSA_meth_get_mod_exp(r0: PBIGNUMi: PBIGNUMrsa: PRSActx: PBN_CTXmeth: PRSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(BIGNUM *, const BIGNUM *, RSA *, BN_CTX *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'RSA_meth_get_mod_exp'; + +type + RSA_meth_set_mod_exp_mod_exp = function(r0: PBIGNUM; i: PBIGNUM; rsa: PRSA; ctx: PBN_CTX): Integer; cdecl; + +function RSA_meth_set_mod_exp(rsa: PRSA_METHOD; mod_exp: RSA_meth_set_mod_exp_mod_exp): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_set_mod_exp'; + +//function RSA_meth_get_bn_mod_exp(r: PBIGNUMa: PBIGNUMp: PBIGNUMm: PBIGNUMctx: PBN_CTXm_ctx: PBN_MONT_CTXmeth: PRSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *, BN_MONT_CTX *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'RSA_meth_get_bn_mod_exp'; + +type + RSA_meth_set_bn_mod_exp_bn_mod_exp = function(r: PBIGNUM; a: PBIGNUM; p: PBIGNUM; m: PBIGNUM; ctx: PBN_CTX; m_ctx: PBN_MONT_CTX): Integer; cdecl; + +function RSA_meth_set_bn_mod_exp(rsa: PRSA_METHOD; bn_mod_exp: RSA_meth_set_bn_mod_exp_bn_mod_exp): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_set_bn_mod_exp'; + +//function RSA_meth_get_init(rsa: PRSAmeth: PRSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(RSA *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'RSA_meth_get_init'; + +type + RSA_meth_set_init_init = function(rsa: PRSA): Integer; cdecl; + +function RSA_meth_set_init(rsa: PRSA_METHOD; init: RSA_meth_set_init_init): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_set_init'; + +//function RSA_meth_get_finish(rsa: PRSAmeth: PRSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(RSA *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'RSA_meth_get_finish'; + +type + RSA_meth_set_finish_finish = function(rsa: PRSA): Integer; cdecl; + +function RSA_meth_set_finish(rsa: PRSA_METHOD; finish: RSA_meth_set_finish_finish): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_set_finish'; + +//function RSA_meth_get_sign({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integerm: PBytem_length: Cardinalsigret: PBytesiglen: PCardinalrsa: PRSAmeth: PRSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(int, const unsigned char *, unsigned int, unsigned char *, unsigned int *, const RSA *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'RSA_meth_get_sign'; + +type + RSA_meth_set_sign_sign = function({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; m: PByte; m_length: Cardinal; sigret: PByte; siglen: PCardinal; rsa: PRSA): Integer; cdecl; + +function RSA_meth_set_sign(rsa: PRSA_METHOD; sign: RSA_meth_set_sign_sign): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_set_sign'; + +//function RSA_meth_get_verify(dtype: Integerm: PBytem_length: Cardinalsigbuf: PBytesiglen: Cardinalrsa: PRSAmeth: PRSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(int, const unsigned char *, unsigned int, const unsigned char *, unsigned int, const RSA *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'RSA_meth_get_verify'; + +type + RSA_meth_set_verify_verify = function(dtype: Integer; m: PByte; m_length: Cardinal; sigbuf: PByte; siglen: Cardinal; rsa: PRSA): Integer; cdecl; + +function RSA_meth_set_verify(rsa: PRSA_METHOD; verify: RSA_meth_set_verify_verify): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_set_verify'; + +//function RSA_meth_get_keygen(rsa: PRSAbits: Integere: PBIGNUMcb: PBN_GENCBmeth: PRSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(RSA *, int, BIGNUM *, BN_GENCB *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'RSA_meth_get_keygen'; + +type + RSA_meth_set_keygen_keygen = function(rsa: PRSA; bits: Integer; e: PBIGNUM; cb: PBN_GENCB): Integer; cdecl; + +function RSA_meth_set_keygen(rsa: PRSA_METHOD; keygen: RSA_meth_set_keygen_keygen): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_set_keygen'; + +//function RSA_meth_get_multi_prime_keygen(rsa: PRSAbits: Integerprimes: Integere: PBIGNUMcb: PBN_GENCBmeth: PRSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(RSA *, int, int, BIGNUM *, BN_GENCB *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'RSA_meth_get_multi_prime_keygen'; + +type + RSA_meth_set_multi_prime_keygen_keygen = function(rsa: PRSA; bits: Integer; primes: Integer; e: PBIGNUM; cb: PBN_GENCB): Integer; cdecl; + +function RSA_meth_set_multi_prime_keygen(meth: PRSA_METHOD; keygen: RSA_meth_set_multi_prime_keygen_keygen): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RSA_meth_set_multi_prime_keygen'; + +function ERR_load_DH_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_DH_strings'; + +function DHparams_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'DHparams_it'; + +function DHparams_dup(p1: PDH): PDH; cdecl; + external LIB_CRYPTO name _PU + 'DHparams_dup'; + +function DH_OpenSSL(): PDH_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'DH_OpenSSL'; + +procedure DH_set_default_method(meth: PDH_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'DH_set_default_method'; + +function DH_get_default_method(): PDH_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'DH_get_default_method'; + +function DH_set_method(dh: PDH; meth: PDH_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_set_method'; + +function DH_new_method(engine: PENGINE): PDH; cdecl; + external LIB_CRYPTO name _PU + 'DH_new_method'; + +function DH_new(): PDH; cdecl; + external LIB_CRYPTO name _PU + 'DH_new'; + +procedure DH_free(dh: PDH); cdecl; + external LIB_CRYPTO name _PU + 'DH_free'; + +function DH_up_ref(dh: PDH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_up_ref'; + +function DH_bits(dh: PDH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_bits'; + +function DH_size(dh: PDH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_size'; + +function DH_security_bits(dh: PDH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_security_bits'; + +function DH_set_ex_data(d: PDH; idx: Integer; arg: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_set_ex_data'; + +function DH_get_ex_data(d: PDH; idx: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'DH_get_ex_data'; + +type + DH_generate_parameters_callback = procedure(p1: Integer; p2: Integer; p3: Pointer); cdecl; + +function DH_generate_parameters(prime_len: Integer; generator: Integer; callback: DH_generate_parameters_callback; cb_arg: Pointer): PDH; cdecl; + external LIB_CRYPTO name _PU + 'DH_generate_parameters'; + +function DH_generate_parameters_ex(dh: PDH; prime_len: Integer; generator: Integer; cb: PBN_GENCB): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_generate_parameters_ex'; + +function DH_check_params_ex(dh: PDH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_check_params_ex'; + +function DH_check_ex(dh: PDH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_check_ex'; + +function DH_check_pub_key_ex(dh: PDH; pub_key: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_check_pub_key_ex'; + +function DH_check_params(dh: PDH; ret: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_check_params'; + +function DH_check(dh: PDH; codes: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_check'; + +function DH_check_pub_key(dh: PDH; pub_key: PBIGNUM; codes: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_check_pub_key'; + +function DH_generate_key(dh: PDH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_generate_key'; + +function DH_compute_key(key: PByte; pub_key: PBIGNUM; dh: PDH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_compute_key'; + +function DH_compute_key_padded(key: PByte; pub_key: PBIGNUM; dh: PDH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_compute_key_padded'; + +function d2i_DHparams(a: PPDH; pp: PPByte; length: Integer): PDH; cdecl; + external LIB_CRYPTO name _PU + 'd2i_DHparams'; + +function i2d_DHparams(a: PDH; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_DHparams'; + +function d2i_DHxparams(a: PPDH; pp: PPByte; length: Integer): PDH; cdecl; + external LIB_CRYPTO name _PU + 'd2i_DHxparams'; + +function i2d_DHxparams(a: PDH; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_DHxparams'; + +function DHparams_print_fp(fp: PPointer; x: PDH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DHparams_print_fp'; + +function DHparams_print(bp: PBIO; x: PDH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DHparams_print'; + +function DH_get_1024_160(): PDH; cdecl; + external LIB_CRYPTO name _PU + 'DH_get_1024_160'; + +function DH_get_2048_224(): PDH; cdecl; + external LIB_CRYPTO name _PU + 'DH_get_2048_224'; + +function DH_get_2048_256(): PDH; cdecl; + external LIB_CRYPTO name _PU + 'DH_get_2048_256'; + +function DH_new_by_nid(nid: Integer): PDH; cdecl; + external LIB_CRYPTO name _PU + 'DH_new_by_nid'; + +function DH_get_nid(dh: PDH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_get_nid'; + +function DH_KDF_X9_42({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outlen: NativeUInt; Z: PByte; Zlen: NativeUInt; key_oid: PASN1_OBJECT; ukm: PByte; ukmlen: NativeUInt; md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_KDF_X9_42'; + +procedure DH_get0_pqg(dh: PDH; p: PPBIGNUM; q: PPBIGNUM; g: PPBIGNUM); cdecl; + external LIB_CRYPTO name _PU + 'DH_get0_pqg'; + +function DH_set0_pqg(dh: PDH; p: PBIGNUM; q: PBIGNUM; g: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_set0_pqg'; + +procedure DH_get0_key(dh: PDH; pub_key: PPBIGNUM; priv_key: PPBIGNUM); cdecl; + external LIB_CRYPTO name _PU + 'DH_get0_key'; + +function DH_set0_key(dh: PDH; pub_key: PBIGNUM; priv_key: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_set0_key'; + +function DH_get0_p(dh: PDH): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'DH_get0_p'; + +function DH_get0_q(dh: PDH): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'DH_get0_q'; + +function DH_get0_g(dh: PDH): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'DH_get0_g'; + +function DH_get0_priv_key(dh: PDH): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'DH_get0_priv_key'; + +function DH_get0_pub_key(dh: PDH): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'DH_get0_pub_key'; + +procedure DH_clear_flags(dh: PDH; flags: Integer); cdecl; + external LIB_CRYPTO name _PU + 'DH_clear_flags'; + +function DH_test_flags(dh: PDH; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_test_flags'; + +procedure DH_set_flags(dh: PDH; flags: Integer); cdecl; + external LIB_CRYPTO name _PU + 'DH_set_flags'; + +function DH_get0_engine(d: PDH): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'DH_get0_engine'; + +function DH_get_length(dh: PDH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_get_length'; + +function DH_set_length(dh: PDH; length: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_set_length'; + +function DH_meth_new(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; flags: Integer): PDH_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'DH_meth_new'; + +procedure DH_meth_free(dhm: PDH_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'DH_meth_free'; + +function DH_meth_dup(dhm: PDH_METHOD): PDH_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'DH_meth_dup'; + +function DH_meth_get0_name(dhm: PDH_METHOD): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'DH_meth_get0_name'; + +function DH_meth_set1_name(dhm: PDH_METHOD; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_meth_set1_name'; + +function DH_meth_get_flags(dhm: PDH_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_meth_get_flags'; + +function DH_meth_set_flags(dhm: PDH_METHOD; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_meth_set_flags'; + +function DH_meth_get0_app_data(dhm: PDH_METHOD): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'DH_meth_get0_app_data'; + +function DH_meth_set0_app_data(dhm: PDH_METHOD; app_data: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_meth_set0_app_data'; + +//function DH_meth_get_generate_key(p1: PDHdhm: PDH_METHOD): Integer { TODO : Cannot convert original type "int (*)(DH *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'DH_meth_get_generate_key'; + +type + DH_meth_set_generate_key_generate_key = function(p1: PDH): Integer; cdecl; + +function DH_meth_set_generate_key(dhm: PDH_METHOD; generate_key: DH_meth_set_generate_key_generate_key): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_meth_set_generate_key'; + +//function DH_meth_get_compute_key(key: PBytepub_key: PBIGNUMdh: PDHdhm: PDH_METHOD): Integer { TODO : Cannot convert original type "int (*)(unsigned char *, const BIGNUM *, DH *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'DH_meth_get_compute_key'; + +type + DH_meth_set_compute_key_compute_key = function(key: PByte; pub_key: PBIGNUM; dh: PDH): Integer; cdecl; + +function DH_meth_set_compute_key(dhm: PDH_METHOD; compute_key: DH_meth_set_compute_key_compute_key): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_meth_set_compute_key'; + +//function DH_meth_get_bn_mod_exp(p1: PDHp2: PBIGNUMp3: PBIGNUMp4: PBIGNUMp5: PBIGNUMp6: PBN_CTXp7: PBN_MONT_CTXdhm: PDH_METHOD): Integer { TODO : Cannot convert original type "int (*)(const DH *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *, BN_MONT_CTX *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'DH_meth_get_bn_mod_exp'; + +type + DH_meth_set_bn_mod_exp_bn_mod_exp = function(p1: PDH; p2: PBIGNUM; p3: PBIGNUM; p4: PBIGNUM; p5: PBIGNUM; p6: PBN_CTX; p7: PBN_MONT_CTX): Integer; cdecl; + +function DH_meth_set_bn_mod_exp(dhm: PDH_METHOD; bn_mod_exp: DH_meth_set_bn_mod_exp_bn_mod_exp): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_meth_set_bn_mod_exp'; + +//function DH_meth_get_init(p1: PDHdhm: PDH_METHOD): Integer { TODO : Cannot convert original type "int (*)(DH *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'DH_meth_get_init'; + +type + DH_meth_set_init_init = function(p1: PDH): Integer; cdecl; + +function DH_meth_set_init(dhm: PDH_METHOD; init: DH_meth_set_init_init): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_meth_set_init'; + +//function DH_meth_get_finish(p1: PDHdhm: PDH_METHOD): Integer { TODO : Cannot convert original type "int (*)(DH *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'DH_meth_get_finish'; + +type + DH_meth_set_finish_finish = function(p1: PDH): Integer; cdecl; + +function DH_meth_set_finish(dhm: PDH_METHOD; finish: DH_meth_set_finish_finish): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_meth_set_finish'; + +//function DH_meth_get_generate_params(p1: PDHp2: Integerp3: Integerp4: PBN_GENCBdhm: PDH_METHOD): Integer { TODO : Cannot convert original type "int (*)(DH *, int, int, BN_GENCB *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'DH_meth_get_generate_params'; + +type + DH_meth_set_generate_params_generate_params = function(p1: PDH; p2: Integer; p3: Integer; p4: PBN_GENCB): Integer; cdecl; + +function DH_meth_set_generate_params(dhm: PDH_METHOD; generate_params: DH_meth_set_generate_params_generate_params): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DH_meth_set_generate_params'; + +function ERR_load_DSA_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_DSA_strings'; + +function DSAparams_dup(x: PDSA): PDSA; cdecl; + external LIB_CRYPTO name _PU + 'DSAparams_dup'; + +function DSA_SIG_new(): PDSA_SIG; cdecl; + external LIB_CRYPTO name _PU + 'DSA_SIG_new'; + +procedure DSA_SIG_free(a: PDSA_SIG); cdecl; + external LIB_CRYPTO name _PU + 'DSA_SIG_free'; + +function i2d_DSA_SIG(a: PDSA_SIG; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_DSA_SIG'; + +function d2i_DSA_SIG(v: PPDSA_SIG; pp: PPByte; length: Integer): PDSA_SIG; cdecl; + external LIB_CRYPTO name _PU + 'd2i_DSA_SIG'; + +procedure DSA_SIG_get0(sig: PDSA_SIG; pr: PPBIGNUM; ps: PPBIGNUM); cdecl; + external LIB_CRYPTO name _PU + 'DSA_SIG_get0'; + +function DSA_SIG_set0(sig: PDSA_SIG; r: PBIGNUM; s: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_SIG_set0'; + +function DSA_do_sign(dgst: PByte; dlen: Integer; dsa: PDSA): PDSA_SIG; cdecl; + external LIB_CRYPTO name _PU + 'DSA_do_sign'; + +function DSA_do_verify(dgst: PByte; dgst_len: Integer; sig: PDSA_SIG; dsa: PDSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_do_verify'; + +function DSA_OpenSSL(): PDSA_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'DSA_OpenSSL'; + +procedure DSA_set_default_method(p1: PDSA_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'DSA_set_default_method'; + +function DSA_get_default_method(): PDSA_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'DSA_get_default_method'; + +function DSA_set_method(dsa: PDSA; p2: PDSA_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_set_method'; + +function DSA_get_method(d: PDSA): PDSA_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'DSA_get_method'; + +function DSA_new(): PDSA; cdecl; + external LIB_CRYPTO name _PU + 'DSA_new'; + +function DSA_new_method(engine: PENGINE): PDSA; cdecl; + external LIB_CRYPTO name _PU + 'DSA_new_method'; + +procedure DSA_free(r: PDSA); cdecl; + external LIB_CRYPTO name _PU + 'DSA_free'; + +function DSA_up_ref(r: PDSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_up_ref'; + +function DSA_size(p1: PDSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_size'; + +function DSA_bits(d: PDSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_bits'; + +function DSA_security_bits(d: PDSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_security_bits'; + +function DSA_sign_setup(dsa: PDSA; ctx_in: PBN_CTX; kinvp: PPBIGNUM; rp: PPBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_sign_setup'; + +function DSA_sign({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; dgst: PByte; dlen: Integer; sig: PByte; siglen: PCardinal; dsa: PDSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_sign'; + +function DSA_verify({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; dgst: PByte; dgst_len: Integer; sigbuf: PByte; siglen: Integer; dsa: PDSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_verify'; + +function DSA_set_ex_data(d: PDSA; idx: Integer; arg: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_set_ex_data'; + +function DSA_get_ex_data(d: PDSA; idx: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_get_ex_data'; + +function d2i_DSAPublicKey(a: PPDSA; pp: PPByte; length: Integer): PDSA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_DSAPublicKey'; + +function d2i_DSAPrivateKey(a: PPDSA; pp: PPByte; length: Integer): PDSA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_DSAPrivateKey'; + +function d2i_DSAparams(a: PPDSA; pp: PPByte; length: Integer): PDSA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_DSAparams'; + +type + DSA_generate_parameters_callback = procedure(p1: Integer; p2: Integer; p3: Pointer); cdecl; + +function DSA_generate_parameters(bits: Integer; seed: PByte; seed_len: Integer; counter_ret: PInteger; h_ret: PCardinal; callback: DSA_generate_parameters_callback; cb_arg: Pointer): PDSA; cdecl; + external LIB_CRYPTO name _PU + 'DSA_generate_parameters'; + +function DSA_generate_parameters_ex(dsa: PDSA; bits: Integer; seed: PByte; seed_len: Integer; counter_ret: PInteger; h_ret: PCardinal; cb: PBN_GENCB): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_generate_parameters_ex'; + +function DSA_generate_key(a: PDSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_generate_key'; + +function i2d_DSAPublicKey(a: PDSA; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_DSAPublicKey'; + +function i2d_DSAPrivateKey(a: PDSA; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_DSAPrivateKey'; + +function i2d_DSAparams(a: PDSA; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_DSAparams'; + +function DSAparams_print(bp: PBIO; x: PDSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSAparams_print'; + +function DSA_print(bp: PBIO; x: PDSA; off: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_print'; + +function DSAparams_print_fp(fp: PPointer; x: PDSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSAparams_print_fp'; + +function DSA_print_fp(bp: PPointer; x: PDSA; off: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_print_fp'; + +function DSA_dup_DH(r: PDSA): PDH; cdecl; + external LIB_CRYPTO name _PU + 'DSA_dup_DH'; + +procedure DSA_get0_pqg(d: PDSA; p: PPBIGNUM; q: PPBIGNUM; g: PPBIGNUM); cdecl; + external LIB_CRYPTO name _PU + 'DSA_get0_pqg'; + +function DSA_set0_pqg(d: PDSA; p: PBIGNUM; q: PBIGNUM; g: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_set0_pqg'; + +procedure DSA_get0_key(d: PDSA; pub_key: PPBIGNUM; priv_key: PPBIGNUM); cdecl; + external LIB_CRYPTO name _PU + 'DSA_get0_key'; + +function DSA_set0_key(d: PDSA; pub_key: PBIGNUM; priv_key: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_set0_key'; + +function DSA_get0_p(d: PDSA): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'DSA_get0_p'; + +function DSA_get0_q(d: PDSA): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'DSA_get0_q'; + +function DSA_get0_g(d: PDSA): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'DSA_get0_g'; + +function DSA_get0_pub_key(d: PDSA): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'DSA_get0_pub_key'; + +function DSA_get0_priv_key(d: PDSA): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'DSA_get0_priv_key'; + +procedure DSA_clear_flags(d: PDSA; flags: Integer); cdecl; + external LIB_CRYPTO name _PU + 'DSA_clear_flags'; + +function DSA_test_flags(d: PDSA; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_test_flags'; + +procedure DSA_set_flags(d: PDSA; flags: Integer); cdecl; + external LIB_CRYPTO name _PU + 'DSA_set_flags'; + +function DSA_get0_engine(d: PDSA): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'DSA_get0_engine'; + +function DSA_meth_new(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; flags: Integer): PDSA_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'DSA_meth_new'; + +procedure DSA_meth_free(dsam: PDSA_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'DSA_meth_free'; + +function DSA_meth_dup(dsam: PDSA_METHOD): PDSA_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'DSA_meth_dup'; + +function DSA_meth_get0_name(dsam: PDSA_METHOD): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'DSA_meth_get0_name'; + +function DSA_meth_set1_name(dsam: PDSA_METHOD; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_meth_set1_name'; + +function DSA_meth_get_flags(dsam: PDSA_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_meth_get_flags'; + +function DSA_meth_set_flags(dsam: PDSA_METHOD; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_meth_set_flags'; + +function DSA_meth_get0_app_data(dsam: PDSA_METHOD): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_meth_get0_app_data'; + +function DSA_meth_set0_app_data(dsam: PDSA_METHOD; app_data: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_meth_set0_app_data'; + +//function DSA_meth_get_sign(p1: PBytep2: Integerp3: PDSAdsam: PDSA_METHOD): Integer { TODO : Cannot convert original type "DSA_SIG *(*)(const unsigned char *, int, DSA *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'DSA_meth_get_sign'; + +type + DSA_meth_set_sign_sign = function(p1: PByte; p2: Integer; p3: PDSA): PDSA_SIG_st; cdecl; + +function DSA_meth_set_sign(dsam: PDSA_METHOD; sign: DSA_meth_set_sign_sign): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_meth_set_sign'; + +//function DSA_meth_get_sign_setup(p1: PDSAp2: PBN_CTXp3: PPBIGNUMp4: PPBIGNUMdsam: PDSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(DSA *, BN_CTX *, BIGNUM **, BIGNUM **)" }; cdecl; +// external LIB_CRYPTO name _PU + 'DSA_meth_get_sign_setup'; + +type + DSA_meth_set_sign_setup_sign_setup = function(p1: PDSA; p2: PBN_CTX; p3: PPBIGNUM; p4: PPBIGNUM): Integer; cdecl; + +function DSA_meth_set_sign_setup(dsam: PDSA_METHOD; sign_setup: DSA_meth_set_sign_setup_sign_setup): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_meth_set_sign_setup'; + +//function DSA_meth_get_verify(p1: PBytep2: Integerp3: PDSA_SIGp4: PDSAdsam: PDSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(const unsigned char *, int, DSA_SIG *, DSA *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'DSA_meth_get_verify'; + +type + DSA_meth_set_verify_verify = function(p1: PByte; p2: Integer; p3: PDSA_SIG; p4: PDSA): Integer; cdecl; + +function DSA_meth_set_verify(dsam: PDSA_METHOD; verify: DSA_meth_set_verify_verify): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_meth_set_verify'; + +//function DSA_meth_get_mod_exp(p1: PDSAp2: PBIGNUMp3: PBIGNUMp4: PBIGNUMp5: PBIGNUMp6: PBIGNUMp7: PBIGNUMp8: PBN_CTXp9: PBN_MONT_CTXdsam: PDSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *, BN_MONT_CTX *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'DSA_meth_get_mod_exp'; + +type + DSA_meth_set_mod_exp_mod_exp = function(p1: PDSA; p2: PBIGNUM; p3: PBIGNUM; p4: PBIGNUM; p5: PBIGNUM; p6: PBIGNUM; p7: PBIGNUM; p8: PBN_CTX; p9: PBN_MONT_CTX): Integer; cdecl; + +function DSA_meth_set_mod_exp(dsam: PDSA_METHOD; mod_exp: DSA_meth_set_mod_exp_mod_exp): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_meth_set_mod_exp'; + +//function DSA_meth_get_bn_mod_exp(p1: PDSAp2: PBIGNUMp3: PBIGNUMp4: PBIGNUMp5: PBIGNUMp6: PBN_CTXp7: PBN_MONT_CTXdsam: PDSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *, BN_MONT_CTX *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'DSA_meth_get_bn_mod_exp'; + +type + DSA_meth_set_bn_mod_exp_bn_mod_exp = function(p1: PDSA; p2: PBIGNUM; p3: PBIGNUM; p4: PBIGNUM; p5: PBIGNUM; p6: PBN_CTX; p7: PBN_MONT_CTX): Integer; cdecl; + +function DSA_meth_set_bn_mod_exp(dsam: PDSA_METHOD; bn_mod_exp: DSA_meth_set_bn_mod_exp_bn_mod_exp): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_meth_set_bn_mod_exp'; + +//function DSA_meth_get_init(p1: PDSAdsam: PDSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(DSA *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'DSA_meth_get_init'; + +type + DSA_meth_set_init_init = function(p1: PDSA): Integer; cdecl; + +function DSA_meth_set_init(dsam: PDSA_METHOD; init: DSA_meth_set_init_init): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_meth_set_init'; + +//function DSA_meth_get_finish(p1: PDSAdsam: PDSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(DSA *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'DSA_meth_get_finish'; + +type + DSA_meth_set_finish_finish = function(p1: PDSA): Integer; cdecl; + +function DSA_meth_set_finish(dsam: PDSA_METHOD; finish: DSA_meth_set_finish_finish): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_meth_set_finish'; + +//function DSA_meth_get_paramgen(p1: PDSAp2: Integerp3: PBytep4: Integerp5: PIntegerp6: PCardinalp7: PBN_GENCBdsam: PDSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(DSA *, int, const unsigned char *, int, int *, unsigned long *, BN_GENCB *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'DSA_meth_get_paramgen'; + +type + DSA_meth_set_paramgen_paramgen = function(p1: PDSA; p2: Integer; p3: PByte; p4: Integer; p5: PInteger; p6: PCardinal; p7: PBN_GENCB): Integer; cdecl; + +function DSA_meth_set_paramgen(dsam: PDSA_METHOD; paramgen: DSA_meth_set_paramgen_paramgen): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_meth_set_paramgen'; + +//function DSA_meth_get_keygen(p1: PDSAdsam: PDSA_METHOD): Integer { TODO : Cannot convert original type "int (*)(DSA *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'DSA_meth_get_keygen'; + +type + DSA_meth_set_keygen_keygen = function(p1: PDSA): Integer; cdecl; + +function DSA_meth_set_keygen(dsam: PDSA_METHOD; keygen: DSA_meth_set_keygen_keygen): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DSA_meth_set_keygen'; + +function SHA1_Init(c: PSHA_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SHA1_Init'; + +function SHA1_Update(c: PSHA_CTX; data: Pointer; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SHA1_Update'; + +function SHA1_Final(md: PByte; c: PSHA_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SHA1_Final'; + +function SHA1(d: PByte; n: NativeUInt; md: PByte): PByte; cdecl; + external LIB_CRYPTO name _PU + 'SHA1'; + +procedure SHA1_Transform(c: PSHA_CTX; data: PByte); cdecl; + external LIB_CRYPTO name _PU + 'SHA1_Transform'; + +function SHA224_Init(c: PSHA256_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SHA224_Init'; + +function SHA224_Update(c: PSHA256_CTX; data: Pointer; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SHA224_Update'; + +function SHA224_Final(md: PByte; c: PSHA256_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SHA224_Final'; + +function SHA224(d: PByte; n: NativeUInt; md: PByte): PByte; cdecl; + external LIB_CRYPTO name _PU + 'SHA224'; + +function SHA256_Init(c: PSHA256_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SHA256_Init'; + +function SHA256_Update(c: PSHA256_CTX; data: Pointer; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SHA256_Update'; + +function SHA256_Final(md: PByte; c: PSHA256_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SHA256_Final'; + +function SHA256(d: PByte; n: NativeUInt; md: PByte): PByte; cdecl; + external LIB_CRYPTO name _PU + 'SHA256'; + +procedure SHA256_Transform(c: PSHA256_CTX; data: PByte); cdecl; + external LIB_CRYPTO name _PU + 'SHA256_Transform'; + +function SHA384_Init(c: PSHA512_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SHA384_Init'; + +function SHA384_Update(c: PSHA512_CTX; data: Pointer; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SHA384_Update'; + +function SHA384_Final(md: PByte; c: PSHA512_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SHA384_Final'; + +function SHA384(d: PByte; n: NativeUInt; md: PByte): PByte; cdecl; + external LIB_CRYPTO name _PU + 'SHA384'; + +function SHA512_Init(c: PSHA512_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SHA512_Init'; + +function SHA512_Update(c: PSHA512_CTX; data: Pointer; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SHA512_Update'; + +function SHA512_Final(md: PByte; c: PSHA512_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SHA512_Final'; + +function SHA512(d: PByte; n: NativeUInt; md: PByte): PByte; cdecl; + external LIB_CRYPTO name _PU + 'SHA512'; + +procedure SHA512_Transform(c: PSHA512_CTX; data: PByte); cdecl; + external LIB_CRYPTO name _PU + 'SHA512_Transform'; + +function ERR_load_X509_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_X509_strings'; + +function OPENSSL_LH_error(lh: POPENSSL_LHASH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_LH_error'; + +function OPENSSL_LH_new(h: OPENSSL_LH_HASHFUNC; c: OPENSSL_LH_COMPFUNC): POPENSSL_LHASH; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_LH_new'; + +procedure OPENSSL_LH_free(lh: POPENSSL_LHASH); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_LH_free'; + +function OPENSSL_LH_insert(lh: POPENSSL_LHASH; data: Pointer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_LH_insert'; + +function OPENSSL_LH_delete(lh: POPENSSL_LHASH; data: Pointer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_LH_delete'; + +function OPENSSL_LH_retrieve(lh: POPENSSL_LHASH; data: Pointer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_LH_retrieve'; + +procedure OPENSSL_LH_doall(lh: POPENSSL_LHASH; func: OPENSSL_LH_DOALL_FUNC); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_LH_doall'; + +procedure OPENSSL_LH_doall_arg(lh: POPENSSL_LHASH; func: OPENSSL_LH_DOALL_FUNCARG; arg: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_LH_doall_arg'; + +function OPENSSL_LH_strhash(c: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_LH_strhash'; + +function OPENSSL_LH_num_items(lh: POPENSSL_LHASH): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_LH_num_items'; + +function OPENSSL_LH_get_down_load(lh: POPENSSL_LHASH): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_LH_get_down_load'; + +procedure OPENSSL_LH_set_down_load(lh: POPENSSL_LHASH; down_load: Cardinal); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_LH_set_down_load'; + +procedure OPENSSL_LH_stats(lh: POPENSSL_LHASH; fp: PPointer); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_LH_stats'; + +procedure OPENSSL_LH_node_stats(lh: POPENSSL_LHASH; fp: PPointer); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_LH_node_stats'; + +procedure OPENSSL_LH_node_usage_stats(lh: POPENSSL_LHASH; fp: PPointer); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_LH_node_usage_stats'; + +procedure OPENSSL_LH_stats_bio(lh: POPENSSL_LHASH; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_LH_stats_bio'; + +procedure OPENSSL_LH_node_stats_bio(lh: POPENSSL_LHASH; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_LH_node_stats_bio'; + +procedure OPENSSL_LH_node_usage_stats_bio(lh: POPENSSL_LHASH; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_LH_node_usage_stats_bio'; + +function X509_STORE_set_depth(store: PX509_STORE; depth: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set_depth'; + +procedure X509_STORE_CTX_set_depth(ctx: PX509_STORE_CTX; depth: Integer); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set_depth'; + +function X509_OBJECT_idx_by_subject(h: Pstack_st_X509_OBJECT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: X509_LOOKUP_TYPE; name: PX509_NAME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_OBJECT_idx_by_subject'; + +function X509_OBJECT_retrieve_by_subject(h: Pstack_st_X509_OBJECT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: X509_LOOKUP_TYPE; name: PX509_NAME): PX509_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'X509_OBJECT_retrieve_by_subject'; + +function X509_OBJECT_retrieve_match(h: Pstack_st_X509_OBJECT; x: PX509_OBJECT): PX509_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'X509_OBJECT_retrieve_match'; + +function X509_OBJECT_up_ref_count(a: PX509_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_OBJECT_up_ref_count'; + +function X509_OBJECT_new(): PX509_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'X509_OBJECT_new'; + +procedure X509_OBJECT_free(a: PX509_OBJECT); cdecl; + external LIB_CRYPTO name _PU + 'X509_OBJECT_free'; + +function X509_OBJECT_get_type(a: PX509_OBJECT): X509_LOOKUP_TYPE; cdecl; + external LIB_CRYPTO name _PU + 'X509_OBJECT_get_type'; + +function X509_OBJECT_get0_X509(a: PX509_OBJECT): PX509; cdecl; + external LIB_CRYPTO name _PU + 'X509_OBJECT_get0_X509'; + +function X509_OBJECT_set1_X509(a: PX509_OBJECT; obj: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_OBJECT_set1_X509'; + +function X509_OBJECT_get0_X509_CRL(a: PX509_OBJECT): PX509_CRL; cdecl; + external LIB_CRYPTO name _PU + 'X509_OBJECT_get0_X509_CRL'; + +function X509_OBJECT_set1_X509_CRL(a: PX509_OBJECT; obj: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_OBJECT_set1_X509_CRL'; + +function X509_STORE_new(): PX509_STORE; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_new'; + +procedure X509_STORE_free(v: PX509_STORE); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_free'; + +function X509_STORE_lock(ctx: PX509_STORE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_lock'; + +function X509_STORE_unlock(ctx: PX509_STORE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_unlock'; + +function X509_STORE_up_ref(v: PX509_STORE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_up_ref'; + +function X509_STORE_get0_objects(v: PX509_STORE): Pstack_st_X509_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_get0_objects'; + +function X509_STORE_CTX_get1_certs(st: PX509_STORE_CTX; nm: PX509_NAME): Pstack_st_X509; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get1_certs'; +function X509_STORE_get1_certs(st: PX509_STORE_CTX; nm: PX509_NAME): Pstack_st_X509; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get1_certs'; +function X509_STORE_get1_cert(st: PX509_STORE_CTX; nm: PX509_NAME): Pstack_st_X509; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get1_certs'; + +function X509_STORE_CTX_get1_crls(st: PX509_STORE_CTX; nm: PX509_NAME): Pstack_st_X509_CRL; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get1_crls'; +function X509_STORE_get1_crls(st: PX509_STORE_CTX; nm: PX509_NAME): Pstack_st_X509_CRL; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get1_crls'; +function X509_STORE_get1_crl(st: PX509_STORE_CTX; nm: PX509_NAME): Pstack_st_X509_CRL; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get1_crls'; + +function X509_STORE_set_flags(ctx: PX509_STORE; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set_flags'; + +function X509_STORE_set_purpose(ctx: PX509_STORE; purpose: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set_purpose'; + +function X509_STORE_set_trust(ctx: PX509_STORE; trust: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set_trust'; + +function X509_STORE_set1_param(ctx: PX509_STORE; pm: PX509_VERIFY_PARAM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set1_param'; + +function X509_STORE_get0_param(ctx: PX509_STORE): PX509_VERIFY_PARAM; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_get0_param'; + +procedure X509_STORE_set_verify(ctx: PX509_STORE; verify: X509_STORE_CTX_verify_fn); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set_verify'; + +procedure X509_STORE_CTX_set_verify(ctx: PX509_STORE_CTX; verify: X509_STORE_CTX_verify_fn); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set_verify'; + +function X509_STORE_get_verify(ctx: PX509_STORE): X509_STORE_CTX_verify_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_get_verify'; + +procedure X509_STORE_set_verify_cb(ctx: PX509_STORE; verify_cb: X509_STORE_CTX_verify_cb); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set_verify_cb'; + +function X509_STORE_get_verify_cb(ctx: PX509_STORE): X509_STORE_CTX_verify_cb; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_get_verify_cb'; + +procedure X509_STORE_set_get_issuer(ctx: PX509_STORE; get_issuer: X509_STORE_CTX_get_issuer_fn); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set_get_issuer'; + +function X509_STORE_get_get_issuer(ctx: PX509_STORE): X509_STORE_CTX_get_issuer_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_get_get_issuer'; + +procedure X509_STORE_set_check_issued(ctx: PX509_STORE; check_issued: X509_STORE_CTX_check_issued_fn); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set_check_issued'; + +function X509_STORE_get_check_issued(ctx: PX509_STORE): X509_STORE_CTX_check_issued_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_get_check_issued'; + +procedure X509_STORE_set_check_revocation(ctx: PX509_STORE; check_revocation: X509_STORE_CTX_check_revocation_fn); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set_check_revocation'; + +function X509_STORE_get_check_revocation(ctx: PX509_STORE): X509_STORE_CTX_check_revocation_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_get_check_revocation'; + +procedure X509_STORE_set_get_crl(ctx: PX509_STORE; get_crl: X509_STORE_CTX_get_crl_fn); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set_get_crl'; + +function X509_STORE_get_get_crl(ctx: PX509_STORE): X509_STORE_CTX_get_crl_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_get_get_crl'; + +procedure X509_STORE_set_check_crl(ctx: PX509_STORE; check_crl: X509_STORE_CTX_check_crl_fn); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set_check_crl'; + +function X509_STORE_get_check_crl(ctx: PX509_STORE): X509_STORE_CTX_check_crl_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_get_check_crl'; + +procedure X509_STORE_set_cert_crl(ctx: PX509_STORE; cert_crl: X509_STORE_CTX_cert_crl_fn); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set_cert_crl'; + +function X509_STORE_get_cert_crl(ctx: PX509_STORE): X509_STORE_CTX_cert_crl_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_get_cert_crl'; + +procedure X509_STORE_set_check_policy(ctx: PX509_STORE; check_policy: X509_STORE_CTX_check_policy_fn); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set_check_policy'; + +function X509_STORE_get_check_policy(ctx: PX509_STORE): X509_STORE_CTX_check_policy_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_get_check_policy'; + +procedure X509_STORE_set_lookup_certs(ctx: PX509_STORE; lookup_certs: X509_STORE_CTX_lookup_certs_fn); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set_lookup_certs'; + +function X509_STORE_get_lookup_certs(ctx: PX509_STORE): X509_STORE_CTX_lookup_certs_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_get_lookup_certs'; + +procedure X509_STORE_set_lookup_crls(ctx: PX509_STORE; lookup_crls: X509_STORE_CTX_lookup_crls_fn); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set_lookup_crls'; + +function X509_STORE_get_lookup_crls(ctx: PX509_STORE): X509_STORE_CTX_lookup_crls_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_get_lookup_crls'; + +procedure X509_STORE_set_cleanup(ctx: PX509_STORE; cleanup: X509_STORE_CTX_cleanup_fn); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set_cleanup'; + +function X509_STORE_get_cleanup(ctx: PX509_STORE): X509_STORE_CTX_cleanup_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_get_cleanup'; + +function X509_STORE_set_ex_data(ctx: PX509_STORE; idx: Integer; data: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set_ex_data'; + +function X509_STORE_get_ex_data(ctx: PX509_STORE; idx: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_get_ex_data'; + +function X509_STORE_CTX_new(): PX509_STORE_CTX; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_new'; + +function X509_STORE_CTX_get1_issuer(issuer: PPX509; ctx: PX509_STORE_CTX; x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get1_issuer'; + +procedure X509_STORE_CTX_free(ctx: PX509_STORE_CTX); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_free'; + +function X509_STORE_CTX_init(ctx: PX509_STORE_CTX; store: PX509_STORE; x509: PX509; chain: Pstack_st_X509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_init'; + +procedure X509_STORE_CTX_set0_trusted_stack(ctx: PX509_STORE_CTX; sk: Pstack_st_X509); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set0_trusted_stack'; +procedure X509_STORE_CTX_trusted_stack(ctx: PX509_STORE_CTX; sk: Pstack_st_X509); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set0_trusted_stack'; + +procedure X509_STORE_CTX_cleanup(ctx: PX509_STORE_CTX); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_cleanup'; + +function X509_STORE_CTX_get0_store(ctx: PX509_STORE_CTX): PX509_STORE; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get0_store'; + +function X509_STORE_CTX_get0_cert(ctx: PX509_STORE_CTX): PX509; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get0_cert'; + +function X509_STORE_CTX_get0_untrusted(ctx: PX509_STORE_CTX): Pstack_st_X509; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get0_untrusted'; + +procedure X509_STORE_CTX_set0_untrusted(ctx: PX509_STORE_CTX; sk: Pstack_st_X509); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set0_untrusted'; +procedure X509_STORE_CTX_set_chain(ctx: PX509_STORE_CTX; sk: Pstack_st_X509); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set0_untrusted'; + +procedure X509_STORE_CTX_set_verify_cb(ctx: PX509_STORE_CTX; verify: X509_STORE_CTX_verify_cb); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set_verify_cb'; + +function X509_STORE_CTX_get_verify_cb(ctx: PX509_STORE_CTX): X509_STORE_CTX_verify_cb; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_verify_cb'; + +function X509_STORE_CTX_get_verify(ctx: PX509_STORE_CTX): X509_STORE_CTX_verify_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_verify'; + +function X509_STORE_CTX_get_get_issuer(ctx: PX509_STORE_CTX): X509_STORE_CTX_get_issuer_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_get_issuer'; + +function X509_STORE_CTX_get_check_issued(ctx: PX509_STORE_CTX): X509_STORE_CTX_check_issued_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_check_issued'; + +function X509_STORE_CTX_get_check_revocation(ctx: PX509_STORE_CTX): X509_STORE_CTX_check_revocation_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_check_revocation'; + +function X509_STORE_CTX_get_get_crl(ctx: PX509_STORE_CTX): X509_STORE_CTX_get_crl_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_get_crl'; + +function X509_STORE_CTX_get_check_crl(ctx: PX509_STORE_CTX): X509_STORE_CTX_check_crl_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_check_crl'; + +function X509_STORE_CTX_get_cert_crl(ctx: PX509_STORE_CTX): X509_STORE_CTX_cert_crl_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_cert_crl'; + +function X509_STORE_CTX_get_check_policy(ctx: PX509_STORE_CTX): X509_STORE_CTX_check_policy_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_check_policy'; + +function X509_STORE_CTX_get_lookup_certs(ctx: PX509_STORE_CTX): X509_STORE_CTX_lookup_certs_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_lookup_certs'; + +function X509_STORE_CTX_get_lookup_crls(ctx: PX509_STORE_CTX): X509_STORE_CTX_lookup_crls_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_lookup_crls'; + +function X509_STORE_CTX_get_cleanup(ctx: PX509_STORE_CTX): X509_STORE_CTX_cleanup_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_cleanup'; + +function X509_STORE_add_lookup(v: PX509_STORE; m: PX509_LOOKUP_METHOD): PX509_LOOKUP; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_add_lookup'; + +function X509_LOOKUP_hash_dir(): PX509_LOOKUP_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_hash_dir'; + +function X509_LOOKUP_file(): PX509_LOOKUP_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_file'; + +function X509_LOOKUP_meth_new(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PX509_LOOKUP_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_new'; + +procedure X509_LOOKUP_meth_free(method: PX509_LOOKUP_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_free'; + +type + X509_LOOKUP_meth_set_new_item_new_item = function(ctx: PX509_LOOKUP): Integer; cdecl; + +function X509_LOOKUP_meth_set_new_item(method: PX509_LOOKUP_METHOD; new_item: X509_LOOKUP_meth_set_new_item_new_item): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_set_new_item'; + +//function X509_LOOKUP_meth_get_new_item(ctx: PX509_LOOKUPmethod: PX509_LOOKUP_METHOD): Integer { TODO : Cannot convert original type "int (*)(X509_LOOKUP *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_get_new_item'; + +type + X509_LOOKUP_meth_set_free_free_fn = procedure(ctx: PX509_LOOKUP); cdecl; + +function X509_LOOKUP_meth_set_free(method: PX509_LOOKUP_METHOD; free_fn: X509_LOOKUP_meth_set_free_free_fn): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_set_free'; + +//function X509_LOOKUP_meth_get_free(ctx: PX509_LOOKUPmethod: PX509_LOOKUP_METHOD): Integer { TODO : Cannot convert original type "void (*)(X509_LOOKUP *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_get_free'; + +type + X509_LOOKUP_meth_set_init_init = function(ctx: PX509_LOOKUP): Integer; cdecl; + +function X509_LOOKUP_meth_set_init(method: PX509_LOOKUP_METHOD; init: X509_LOOKUP_meth_set_init_init): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_set_init'; + +//function X509_LOOKUP_meth_get_init(ctx: PX509_LOOKUPmethod: PX509_LOOKUP_METHOD): Integer { TODO : Cannot convert original type "int (*)(X509_LOOKUP *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_get_init'; + +type + X509_LOOKUP_meth_set_shutdown_shutdown = function(ctx: PX509_LOOKUP): Integer; cdecl; + +function X509_LOOKUP_meth_set_shutdown(method: PX509_LOOKUP_METHOD; shutdown: X509_LOOKUP_meth_set_shutdown_shutdown): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_set_shutdown'; + +//function X509_LOOKUP_meth_get_shutdown(ctx: PX509_LOOKUPmethod: PX509_LOOKUP_METHOD): Integer { TODO : Cannot convert original type "int (*)(X509_LOOKUP *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_get_shutdown'; + +function X509_LOOKUP_meth_set_ctrl(method: PX509_LOOKUP_METHOD; ctrl_fn: X509_LOOKUP_ctrl_fn): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_set_ctrl'; + +function X509_LOOKUP_meth_get_ctrl(method: PX509_LOOKUP_METHOD): X509_LOOKUP_ctrl_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_get_ctrl'; + +function X509_LOOKUP_meth_set_get_by_subject(method: PX509_LOOKUP_METHOD; fn: X509_LOOKUP_get_by_subject_fn): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_set_get_by_subject'; + +function X509_LOOKUP_meth_get_get_by_subject(method: PX509_LOOKUP_METHOD): X509_LOOKUP_get_by_subject_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_get_get_by_subject'; + +function X509_LOOKUP_meth_set_get_by_issuer_serial(method: PX509_LOOKUP_METHOD; fn: X509_LOOKUP_get_by_issuer_serial_fn): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_set_get_by_issuer_serial'; + +function X509_LOOKUP_meth_get_get_by_issuer_serial(method: PX509_LOOKUP_METHOD): X509_LOOKUP_get_by_issuer_serial_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_get_get_by_issuer_serial'; + +function X509_LOOKUP_meth_set_get_by_fingerprint(method: PX509_LOOKUP_METHOD; fn: X509_LOOKUP_get_by_fingerprint_fn): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_set_get_by_fingerprint'; + +function X509_LOOKUP_meth_get_get_by_fingerprint(method: PX509_LOOKUP_METHOD): X509_LOOKUP_get_by_fingerprint_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_get_get_by_fingerprint'; + +function X509_LOOKUP_meth_set_get_by_alias(method: PX509_LOOKUP_METHOD; fn: X509_LOOKUP_get_by_alias_fn): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_set_get_by_alias'; + +function X509_LOOKUP_meth_get_get_by_alias(method: PX509_LOOKUP_METHOD): X509_LOOKUP_get_by_alias_fn; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_meth_get_get_by_alias'; + +function X509_STORE_add_cert(ctx: PX509_STORE; x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_add_cert'; + +function X509_STORE_add_crl(ctx: PX509_STORE; x: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_add_crl'; + +function X509_STORE_CTX_get_by_subject(vs: PX509_STORE_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: X509_LOOKUP_TYPE; name: PX509_NAME; ret: PX509_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_by_subject'; +function X509_STORE_get_by_subject(vs: PX509_STORE_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: X509_LOOKUP_TYPE; name: PX509_NAME; ret: PX509_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_by_subject'; + +function X509_STORE_CTX_get_obj_by_subject(vs: PX509_STORE_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: X509_LOOKUP_TYPE; name: PX509_NAME): PX509_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_obj_by_subject'; + +function X509_LOOKUP_ctrl(ctx: PX509_LOOKUP; cmd: Integer; argc: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; argl: Integer; ret: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_ctrl'; + +function X509_load_cert_file(ctx: PX509_LOOKUP; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_load_cert_file'; + +function X509_load_crl_file(ctx: PX509_LOOKUP; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_load_crl_file'; + +function X509_load_cert_crl_file(ctx: PX509_LOOKUP; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_load_cert_crl_file'; + +function X509_LOOKUP_new(method: PX509_LOOKUP_METHOD): PX509_LOOKUP; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_new'; + +procedure X509_LOOKUP_free(ctx: PX509_LOOKUP); cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_free'; + +function X509_LOOKUP_init(ctx: PX509_LOOKUP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_init'; + +function X509_LOOKUP_by_subject(ctx: PX509_LOOKUP; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: X509_LOOKUP_TYPE; name: PX509_NAME; ret: PX509_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_by_subject'; + +function X509_LOOKUP_by_issuer_serial(ctx: PX509_LOOKUP; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: X509_LOOKUP_TYPE; name: PX509_NAME; serial: PASN1_INTEGER; ret: PX509_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_by_issuer_serial'; + +function X509_LOOKUP_by_fingerprint(ctx: PX509_LOOKUP; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: X509_LOOKUP_TYPE; bytes: PByte; len: Integer; ret: PX509_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_by_fingerprint'; + +function X509_LOOKUP_by_alias(ctx: PX509_LOOKUP; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: X509_LOOKUP_TYPE; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: Integer; ret: PX509_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_by_alias'; + +function X509_LOOKUP_set_method_data(ctx: PX509_LOOKUP; data: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_set_method_data'; + +function X509_LOOKUP_get_method_data(ctx: PX509_LOOKUP): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_get_method_data'; + +function X509_LOOKUP_get_store(ctx: PX509_LOOKUP): PX509_STORE; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_get_store'; + +function X509_LOOKUP_shutdown(ctx: PX509_LOOKUP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_LOOKUP_shutdown'; + +function X509_STORE_load_locations(ctx: PX509_STORE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; dir: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_load_locations'; + +function X509_STORE_set_default_paths(ctx: PX509_STORE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_set_default_paths'; + +function X509_STORE_CTX_set_ex_data(ctx: PX509_STORE_CTX; idx: Integer; data: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set_ex_data'; + +function X509_STORE_CTX_get_ex_data(ctx: PX509_STORE_CTX; idx: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_ex_data'; + +function X509_STORE_CTX_get_error(ctx: PX509_STORE_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_error'; + +procedure X509_STORE_CTX_set_error(ctx: PX509_STORE_CTX; s: Integer); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set_error'; + +function X509_STORE_CTX_get_error_depth(ctx: PX509_STORE_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_error_depth'; + +procedure X509_STORE_CTX_set_error_depth(ctx: PX509_STORE_CTX; depth: Integer); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set_error_depth'; + +function X509_STORE_CTX_get_current_cert(ctx: PX509_STORE_CTX): PX509; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_current_cert'; + +procedure X509_STORE_CTX_set_current_cert(ctx: PX509_STORE_CTX; x: PX509); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set_current_cert'; + +function X509_STORE_CTX_get0_current_issuer(ctx: PX509_STORE_CTX): PX509; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get0_current_issuer'; + +function X509_STORE_CTX_get0_current_crl(ctx: PX509_STORE_CTX): PX509_CRL; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get0_current_crl'; + +function X509_STORE_CTX_get0_parent_ctx(ctx: PX509_STORE_CTX): PX509_STORE_CTX; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get0_parent_ctx'; + +function X509_STORE_CTX_get0_chain(ctx: PX509_STORE_CTX): Pstack_st_X509; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get0_chain'; +function X509_STORE_CTX_get_chain(ctx: PX509_STORE_CTX): Pstack_st_X509; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get0_chain'; + +function X509_STORE_CTX_get1_chain(ctx: PX509_STORE_CTX): Pstack_st_X509; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get1_chain'; + +procedure X509_STORE_CTX_set_cert(c: PX509_STORE_CTX; x: PX509); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set_cert'; + +procedure X509_STORE_CTX_set0_verified_chain(c: PX509_STORE_CTX; sk: Pstack_st_X509); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set0_verified_chain'; + +procedure X509_STORE_CTX_set0_crls(c: PX509_STORE_CTX; sk: Pstack_st_X509_CRL); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set0_crls'; + +function X509_STORE_CTX_set_purpose(ctx: PX509_STORE_CTX; purpose: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set_purpose'; + +function X509_STORE_CTX_set_trust(ctx: PX509_STORE_CTX; trust: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set_trust'; + +function X509_STORE_CTX_purpose_inherit(ctx: PX509_STORE_CTX; def_purpose: Integer; purpose: Integer; trust: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_purpose_inherit'; + +procedure X509_STORE_CTX_set_flags(ctx: PX509_STORE_CTX; flags: Cardinal); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set_flags'; + +procedure X509_STORE_CTX_set_time(ctx: PX509_STORE_CTX; flags: Cardinal; t: Longint); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set_time'; + +function X509_STORE_CTX_get0_policy_tree(ctx: PX509_STORE_CTX): PX509_POLICY_TREE; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get0_policy_tree'; + +function X509_STORE_CTX_get_explicit_policy(ctx: PX509_STORE_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_explicit_policy'; + +function X509_STORE_CTX_get_num_untrusted(ctx: PX509_STORE_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get_num_untrusted'; + +function X509_STORE_CTX_get0_param(ctx: PX509_STORE_CTX): PX509_VERIFY_PARAM; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_get0_param'; + +procedure X509_STORE_CTX_set0_param(ctx: PX509_STORE_CTX; param: PX509_VERIFY_PARAM); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set0_param'; + +function X509_STORE_CTX_set_default(ctx: PX509_STORE_CTX; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set_default'; + +procedure X509_STORE_CTX_set0_dane(ctx: PX509_STORE_CTX; dane: PSSL_DANE); cdecl; + external LIB_CRYPTO name _PU + 'X509_STORE_CTX_set0_dane'; + +function X509_VERIFY_PARAM_new(): PX509_VERIFY_PARAM; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_new'; + +procedure X509_VERIFY_PARAM_free(param: PX509_VERIFY_PARAM); cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_free'; + +function X509_VERIFY_PARAM_inherit({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PX509_VERIFY_PARAM; from: PX509_VERIFY_PARAM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_inherit'; + +function X509_VERIFY_PARAM_set1({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PX509_VERIFY_PARAM; from: PX509_VERIFY_PARAM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_set1'; + +function X509_VERIFY_PARAM_set1_name(param: PX509_VERIFY_PARAM; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_set1_name'; + +function X509_VERIFY_PARAM_set_flags(param: PX509_VERIFY_PARAM; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_set_flags'; + +function X509_VERIFY_PARAM_clear_flags(param: PX509_VERIFY_PARAM; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_clear_flags'; + +function X509_VERIFY_PARAM_get_flags(param: PX509_VERIFY_PARAM): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_get_flags'; + +function X509_VERIFY_PARAM_set_purpose(param: PX509_VERIFY_PARAM; purpose: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_set_purpose'; + +function X509_VERIFY_PARAM_set_trust(param: PX509_VERIFY_PARAM; trust: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_set_trust'; + +procedure X509_VERIFY_PARAM_set_depth(param: PX509_VERIFY_PARAM; depth: Integer); cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_set_depth'; + +procedure X509_VERIFY_PARAM_set_auth_level(param: PX509_VERIFY_PARAM; auth_level: Integer); cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_set_auth_level'; + +function X509_VERIFY_PARAM_get_time(param: PX509_VERIFY_PARAM): Longint; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_get_time'; + +procedure X509_VERIFY_PARAM_set_time(param: PX509_VERIFY_PARAM; t: Longint); cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_set_time'; + +function X509_VERIFY_PARAM_add0_policy(param: PX509_VERIFY_PARAM; policy: PASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_add0_policy'; + +function X509_VERIFY_PARAM_set1_policies(param: PX509_VERIFY_PARAM; policies: Pstack_st_ASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_set1_policies'; + +function X509_VERIFY_PARAM_set_inh_flags(param: PX509_VERIFY_PARAM; flags: {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt32{$ELSE}LongInt{$IFEND}{$ELSE}UInt32{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_set_inh_flags'; + +function X509_VERIFY_PARAM_get_inh_flags(param: PX509_VERIFY_PARAM): {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt32{$ELSE}LongInt{$IFEND}{$ELSE}UInt32{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_get_inh_flags'; + +function X509_VERIFY_PARAM_set1_host(param: PX509_VERIFY_PARAM; name: PAnsiChar; namelen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_set1_host'; + +function X509_VERIFY_PARAM_add1_host(param: PX509_VERIFY_PARAM; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; namelen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_add1_host'; + +procedure X509_VERIFY_PARAM_set_hostflags(param: PX509_VERIFY_PARAM; flags: Cardinal); cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_set_hostflags'; + +function X509_VERIFY_PARAM_get_hostflags(param: PX509_VERIFY_PARAM): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_get_hostflags'; + +function X509_VERIFY_PARAM_get0_peername(p1: PX509_VERIFY_PARAM): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_get0_peername'; + +procedure X509_VERIFY_PARAM_move_peername(p1: PX509_VERIFY_PARAM; p2: PX509_VERIFY_PARAM); cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_move_peername'; + +function X509_VERIFY_PARAM_set1_email(param: PX509_VERIFY_PARAM; email: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; emaillen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_set1_email'; + +function X509_VERIFY_PARAM_set1_ip(param: PX509_VERIFY_PARAM; ip: PByte; iplen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_set1_ip'; + +function X509_VERIFY_PARAM_set1_ip_asc(param: PX509_VERIFY_PARAM; ipasc: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_set1_ip_asc'; + +function X509_VERIFY_PARAM_get_depth(param: PX509_VERIFY_PARAM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_get_depth'; + +function X509_VERIFY_PARAM_get_auth_level(param: PX509_VERIFY_PARAM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_get_auth_level'; + +function X509_VERIFY_PARAM_get0_name(param: PX509_VERIFY_PARAM): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_get0_name'; + +function X509_VERIFY_PARAM_add0_table(param: PX509_VERIFY_PARAM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_add0_table'; + +function X509_VERIFY_PARAM_get_count(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_get_count'; + +function X509_VERIFY_PARAM_get0(id: Integer): PX509_VERIFY_PARAM; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_get0'; + +function X509_VERIFY_PARAM_lookup(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PX509_VERIFY_PARAM; cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_lookup'; + +procedure X509_VERIFY_PARAM_table_cleanup(); cdecl; + external LIB_CRYPTO name _PU + 'X509_VERIFY_PARAM_table_cleanup'; + +function X509_policy_check(ptree: PPX509_POLICY_TREE; pexplicit_policy: PInteger; certs: Pstack_st_X509; policy_oids: Pstack_st_ASN1_OBJECT; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_policy_check'; + +procedure X509_policy_tree_free(tree: PX509_POLICY_TREE); cdecl; + external LIB_CRYPTO name _PU + 'X509_policy_tree_free'; + +function X509_policy_tree_level_count(tree: PX509_POLICY_TREE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_policy_tree_level_count'; + +function X509_policy_tree_get0_level(tree: PX509_POLICY_TREE; i: Integer): PX509_POLICY_LEVEL; cdecl; + external LIB_CRYPTO name _PU + 'X509_policy_tree_get0_level'; + +function X509_policy_tree_get0_policies(tree: PX509_POLICY_TREE): Pstack_st_X509_POLICY_NODE; cdecl; + external LIB_CRYPTO name _PU + 'X509_policy_tree_get0_policies'; + +function X509_policy_tree_get0_user_policies(tree: PX509_POLICY_TREE): Pstack_st_X509_POLICY_NODE; cdecl; + external LIB_CRYPTO name _PU + 'X509_policy_tree_get0_user_policies'; + +function X509_policy_level_node_count(level: PX509_POLICY_LEVEL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_policy_level_node_count'; + +function X509_policy_level_get0_node(level: PX509_POLICY_LEVEL; i: Integer): PX509_POLICY_NODE; cdecl; + external LIB_CRYPTO name _PU + 'X509_policy_level_get0_node'; + +function X509_policy_node_get0_policy(node: PX509_POLICY_NODE): PASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'X509_policy_node_get0_policy'; + +function X509_policy_node_get0_qualifiers(node: PX509_POLICY_NODE): Pstack_st_POLICYQUALINFO; cdecl; + external LIB_CRYPTO name _PU + 'X509_policy_node_get0_qualifiers'; + +function X509_policy_node_get0_parent(node: PX509_POLICY_NODE): PX509_POLICY_NODE; cdecl; + external LIB_CRYPTO name _PU + 'X509_policy_node_get0_parent'; + +function ERR_load_PKCS7_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_PKCS7_strings'; + +function PKCS7_ISSUER_AND_SERIAL_new(): PPKCS7_ISSUER_AND_SERIAL; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_ISSUER_AND_SERIAL_new'; + +procedure PKCS7_ISSUER_AND_SERIAL_free(a: PPKCS7_ISSUER_AND_SERIAL); cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_ISSUER_AND_SERIAL_free'; + +function d2i_PKCS7_ISSUER_AND_SERIAL(a: PPPKCS7_ISSUER_AND_SERIAL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPKCS7_ISSUER_AND_SERIAL; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS7_ISSUER_AND_SERIAL'; + +function i2d_PKCS7_ISSUER_AND_SERIAL(a: PPKCS7_ISSUER_AND_SERIAL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS7_ISSUER_AND_SERIAL'; + +function PKCS7_ISSUER_AND_SERIAL_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_ISSUER_AND_SERIAL_it'; + +function PKCS7_ISSUER_AND_SERIAL_digest(data: PPKCS7_ISSUER_AND_SERIAL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_MD; md: PByte; len: PCardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_ISSUER_AND_SERIAL_digest'; + +function d2i_PKCS7_fp(fp: PPointer; p7: PPPKCS7): PPKCS7; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS7_fp'; + +function i2d_PKCS7_fp(fp: PPointer; p7: PPKCS7): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS7_fp'; + +function PKCS7_dup(p7: PPKCS7): PPKCS7; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_dup'; + +function d2i_PKCS7_bio(bp: PBIO; p7: PPPKCS7): PPKCS7; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS7_bio'; + +function i2d_PKCS7_bio(bp: PBIO; p7: PPKCS7): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS7_bio'; + +function i2d_PKCS7_bio_stream({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; p7: PPKCS7; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS7_bio_stream'; + +function PEM_write_bio_PKCS7_stream({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; p7: PPKCS7; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_PKCS7_stream'; + +function PKCS7_SIGNER_INFO_new(): PPKCS7_SIGNER_INFO; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_SIGNER_INFO_new'; + +procedure PKCS7_SIGNER_INFO_free(a: PPKCS7_SIGNER_INFO); cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_SIGNER_INFO_free'; + +function d2i_PKCS7_SIGNER_INFO(a: PPPKCS7_SIGNER_INFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPKCS7_SIGNER_INFO; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS7_SIGNER_INFO'; + +function i2d_PKCS7_SIGNER_INFO(a: PPKCS7_SIGNER_INFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS7_SIGNER_INFO'; + +function PKCS7_SIGNER_INFO_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_SIGNER_INFO_it'; + +function PKCS7_RECIP_INFO_new(): PPKCS7_RECIP_INFO; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_RECIP_INFO_new'; + +procedure PKCS7_RECIP_INFO_free(a: PPKCS7_RECIP_INFO); cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_RECIP_INFO_free'; + +function d2i_PKCS7_RECIP_INFO(a: PPPKCS7_RECIP_INFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPKCS7_RECIP_INFO; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS7_RECIP_INFO'; + +function i2d_PKCS7_RECIP_INFO(a: PPKCS7_RECIP_INFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS7_RECIP_INFO'; + +function PKCS7_RECIP_INFO_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_RECIP_INFO_it'; + +function PKCS7_SIGNED_new(): PPKCS7_SIGNED; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_SIGNED_new'; + +procedure PKCS7_SIGNED_free(a: PPKCS7_SIGNED); cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_SIGNED_free'; + +function d2i_PKCS7_SIGNED(a: PPPKCS7_SIGNED; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPKCS7_SIGNED; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS7_SIGNED'; + +function i2d_PKCS7_SIGNED(a: PPKCS7_SIGNED; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS7_SIGNED'; + +function PKCS7_SIGNED_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_SIGNED_it'; + +function PKCS7_ENC_CONTENT_new(): PPKCS7_ENC_CONTENT; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_ENC_CONTENT_new'; + +procedure PKCS7_ENC_CONTENT_free(a: PPKCS7_ENC_CONTENT); cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_ENC_CONTENT_free'; + +function d2i_PKCS7_ENC_CONTENT(a: PPPKCS7_ENC_CONTENT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPKCS7_ENC_CONTENT; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS7_ENC_CONTENT'; + +function i2d_PKCS7_ENC_CONTENT(a: PPKCS7_ENC_CONTENT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS7_ENC_CONTENT'; + +function PKCS7_ENC_CONTENT_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_ENC_CONTENT_it'; + +function PKCS7_ENVELOPE_new(): PPKCS7_ENVELOPE; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_ENVELOPE_new'; + +procedure PKCS7_ENVELOPE_free(a: PPKCS7_ENVELOPE); cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_ENVELOPE_free'; + +function d2i_PKCS7_ENVELOPE(a: PPPKCS7_ENVELOPE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPKCS7_ENVELOPE; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS7_ENVELOPE'; + +function i2d_PKCS7_ENVELOPE(a: PPKCS7_ENVELOPE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS7_ENVELOPE'; + +function PKCS7_ENVELOPE_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_ENVELOPE_it'; + +function PKCS7_SIGN_ENVELOPE_new(): PPKCS7_SIGN_ENVELOPE; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_SIGN_ENVELOPE_new'; + +procedure PKCS7_SIGN_ENVELOPE_free(a: PPKCS7_SIGN_ENVELOPE); cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_SIGN_ENVELOPE_free'; + +function d2i_PKCS7_SIGN_ENVELOPE(a: PPPKCS7_SIGN_ENVELOPE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPKCS7_SIGN_ENVELOPE; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS7_SIGN_ENVELOPE'; + +function i2d_PKCS7_SIGN_ENVELOPE(a: PPKCS7_SIGN_ENVELOPE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS7_SIGN_ENVELOPE'; + +function PKCS7_SIGN_ENVELOPE_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_SIGN_ENVELOPE_it'; + +function PKCS7_DIGEST_new(): PPKCS7_DIGEST; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_DIGEST_new'; + +procedure PKCS7_DIGEST_free(a: PPKCS7_DIGEST); cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_DIGEST_free'; + +function d2i_PKCS7_DIGEST(a: PPPKCS7_DIGEST; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPKCS7_DIGEST; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS7_DIGEST'; + +function i2d_PKCS7_DIGEST(a: PPKCS7_DIGEST; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS7_DIGEST'; + +function PKCS7_DIGEST_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_DIGEST_it'; + +function PKCS7_ENCRYPT_new(): PPKCS7_ENCRYPT; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_ENCRYPT_new'; + +procedure PKCS7_ENCRYPT_free(a: PPKCS7_ENCRYPT); cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_ENCRYPT_free'; + +function d2i_PKCS7_ENCRYPT(a: PPPKCS7_ENCRYPT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPKCS7_ENCRYPT; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS7_ENCRYPT'; + +function i2d_PKCS7_ENCRYPT(a: PPKCS7_ENCRYPT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS7_ENCRYPT'; + +function PKCS7_ENCRYPT_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_ENCRYPT_it'; + +function PKCS7_new(): PPKCS7; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_new'; + +procedure PKCS7_free(a: PPKCS7); cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_free'; + +function d2i_PKCS7(a: PPPKCS7; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPKCS7; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS7'; + +function i2d_PKCS7(a: PPKCS7; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS7'; + +function PKCS7_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_it'; + +function PKCS7_ATTR_SIGN_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_ATTR_SIGN_it'; + +function PKCS7_ATTR_VERIFY_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_ATTR_VERIFY_it'; + +function i2d_PKCS7_NDEF(a: PPKCS7; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS7_NDEF'; + +function PKCS7_print_ctx({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; x: PPKCS7; indent: Integer; pctx: PASN1_PCTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_print_ctx'; + +function PKCS7_ctrl(p7: PPKCS7; cmd: Integer; larg: Integer; parg: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_ctrl'; + +function PKCS7_set_type(p7: PPKCS7; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_set_type'; + +function PKCS7_set0_type_other(p7: PPKCS7; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; other: PASN1_TYPE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_set0_type_other'; + +function PKCS7_set_content(p7: PPKCS7; p7_data: PPKCS7): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_set_content'; + +function PKCS7_SIGNER_INFO_set(p7i: PPKCS7_SIGNER_INFO; x509: PX509; pkey: PEVP_PKEY; dgst: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_SIGNER_INFO_set'; + +function PKCS7_SIGNER_INFO_sign(si: PPKCS7_SIGNER_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_SIGNER_INFO_sign'; + +function PKCS7_add_signer(p7: PPKCS7; p7i: PPKCS7_SIGNER_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_add_signer'; + +function PKCS7_add_certificate(p7: PPKCS7; x509: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_add_certificate'; + +function PKCS7_add_crl(p7: PPKCS7; x509: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_add_crl'; + +function PKCS7_content_new(p7: PPKCS7; nid: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_content_new'; + +function PKCS7_dataVerify(cert_store: PX509_STORE; ctx: PX509_STORE_CTX; bio: PBIO; p7: PPKCS7; si: PPKCS7_SIGNER_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_dataVerify'; + +function PKCS7_signatureVerify(bio: PBIO; p7: PPKCS7; si: PPKCS7_SIGNER_INFO; x509: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_signatureVerify'; + +function PKCS7_dataInit(p7: PPKCS7; bio: PBIO): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_dataInit'; + +function PKCS7_dataFinal(p7: PPKCS7; bio: PBIO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_dataFinal'; + +function PKCS7_dataDecode(p7: PPKCS7; pkey: PEVP_PKEY; in_bio: PBIO; pcert: PX509): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_dataDecode'; + +function PKCS7_add_signature(p7: PPKCS7; x509: PX509; pkey: PEVP_PKEY; dgst: PEVP_MD): PPKCS7_SIGNER_INFO; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_add_signature'; + +function PKCS7_cert_from_signer_info(p7: PPKCS7; si: PPKCS7_SIGNER_INFO): PX509; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_cert_from_signer_info'; + +function PKCS7_set_digest(p7: PPKCS7; md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_set_digest'; + +function PKCS7_get_signer_info(p7: PPKCS7): Pstack_st_PKCS7_SIGNER_INFO; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_get_signer_info'; + +function PKCS7_add_recipient(p7: PPKCS7; x509: PX509): PPKCS7_RECIP_INFO; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_add_recipient'; + +procedure PKCS7_SIGNER_INFO_get0_algs(si: PPKCS7_SIGNER_INFO; pk: PPEVP_PKEY; pdig: PPX509_ALGOR; psig: PPX509_ALGOR); cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_SIGNER_INFO_get0_algs'; + +procedure PKCS7_RECIP_INFO_get0_alg(ri: PPKCS7_RECIP_INFO; penc: PPX509_ALGOR); cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_RECIP_INFO_get0_alg'; + +function PKCS7_add_recipient_info(p7: PPKCS7; ri: PPKCS7_RECIP_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_add_recipient_info'; + +function PKCS7_RECIP_INFO_set(p7i: PPKCS7_RECIP_INFO; x509: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_RECIP_INFO_set'; + +function PKCS7_set_cipher(p7: PPKCS7; cipher: PEVP_CIPHER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_set_cipher'; + +function PKCS7_stream(boundary: PPPByte; p7: PPKCS7): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_stream'; + +function PKCS7_get_issuer_and_serial(p7: PPKCS7; idx: Integer): PPKCS7_ISSUER_AND_SERIAL; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_get_issuer_and_serial'; + +function PKCS7_digest_from_attributes(sk: Pstack_st_X509_ATTRIBUTE): PASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_digest_from_attributes'; + +function PKCS7_add_signed_attribute(p7si: PPKCS7_SIGNER_INFO; nid: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; data: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_add_signed_attribute'; + +function PKCS7_add_attribute(p7si: PPKCS7_SIGNER_INFO; nid: Integer; atrtype: Integer; value: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_add_attribute'; + +function PKCS7_get_attribute(si: PPKCS7_SIGNER_INFO; nid: Integer): PASN1_TYPE; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_get_attribute'; + +function PKCS7_get_signed_attribute(si: PPKCS7_SIGNER_INFO; nid: Integer): PASN1_TYPE; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_get_signed_attribute'; + +function PKCS7_set_signed_attributes(p7si: PPKCS7_SIGNER_INFO; sk: Pstack_st_X509_ATTRIBUTE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_set_signed_attributes'; + +function PKCS7_set_attributes(p7si: PPKCS7_SIGNER_INFO; sk: Pstack_st_X509_ATTRIBUTE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_set_attributes'; + +function PKCS7_sign(signcert: PX509; pkey: PEVP_PKEY; certs: Pstack_st_X509; data: PBIO; flags: Integer): PPKCS7; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_sign'; + +function PKCS7_sign_add_signer(p7: PPKCS7; signcert: PX509; pkey: PEVP_PKEY; md: PEVP_MD; flags: Integer): PPKCS7_SIGNER_INFO; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_sign_add_signer'; + +function PKCS7_final(p7: PPKCS7; data: PBIO; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_final'; + +function PKCS7_verify(p7: PPKCS7; certs: Pstack_st_X509; store: PX509_STORE; indata: PBIO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_verify'; + +function PKCS7_get0_signers(p7: PPKCS7; certs: Pstack_st_X509; flags: Integer): Pstack_st_X509; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_get0_signers'; + +function PKCS7_encrypt(certs: Pstack_st_X509; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO; cipher: PEVP_CIPHER; flags: Integer): PPKCS7; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_encrypt'; + +function PKCS7_decrypt(p7: PPKCS7; pkey: PEVP_PKEY; cert: PX509; data: PBIO; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_decrypt'; + +function PKCS7_add_attrib_smimecap(si: PPKCS7_SIGNER_INFO; cap: Pstack_st_X509_ALGOR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_add_attrib_smimecap'; + +function PKCS7_get_smimecap(si: PPKCS7_SIGNER_INFO): Pstack_st_X509_ALGOR; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_get_smimecap'; + +function PKCS7_simple_smimecap(sk: Pstack_st_X509_ALGOR; nid: Integer; arg: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_simple_smimecap'; + +function PKCS7_add_attrib_content_type(si: PPKCS7_SIGNER_INFO; coid: PASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_add_attrib_content_type'; + +function PKCS7_add0_attrib_signing_time(si: PPKCS7_SIGNER_INFO; t: PASN1_TIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_add0_attrib_signing_time'; + +function PKCS7_add1_attrib_digest(si: PPKCS7_SIGNER_INFO; md: PByte; mdlen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_add1_attrib_digest'; + +function SMIME_write_PKCS7(bio: PBIO; p7: PPKCS7; data: PBIO; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SMIME_write_PKCS7'; + +function SMIME_read_PKCS7(bio: PBIO; bcont: PPBIO): PPKCS7; cdecl; + external LIB_CRYPTO name _PU + 'SMIME_read_PKCS7'; + +function BIO_new_PKCS7({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; p7: PPKCS7): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_new_PKCS7'; + +procedure X509_CRL_set_default_method(meth: PX509_CRL_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_set_default_method'; + +type + X509_CRL_METHOD_new_crl_init = function(crl: PX509_CRL): Integer; cdecl; + +type + X509_CRL_METHOD_new_crl_free = function(crl: PX509_CRL): Integer; cdecl; + +type + X509_CRL_METHOD_new_crl_lookup = function(crl: PX509_CRL; ret: PPX509_REVOKED; ser: PASN1_INTEGER; issuer: PX509_NAME): Integer; cdecl; + +type + X509_CRL_METHOD_new_crl_verify = function(crl: PX509_CRL; pk: PEVP_PKEY): Integer; cdecl; + +function X509_CRL_METHOD_new(crl_init: X509_CRL_METHOD_new_crl_init; crl_free: X509_CRL_METHOD_new_crl_free; crl_lookup: X509_CRL_METHOD_new_crl_lookup; crl_verify: X509_CRL_METHOD_new_crl_verify): PX509_CRL_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_METHOD_new'; + +procedure X509_CRL_METHOD_free(m: PX509_CRL_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_METHOD_free'; + +procedure X509_CRL_set_meth_data(crl: PX509_CRL; dat: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_set_meth_data'; + +function X509_CRL_get_meth_data(crl: PX509_CRL): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get_meth_data'; + +function X509_verify_cert_error_string(n: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'X509_verify_cert_error_string'; + +function X509_verify(a: PX509; r: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_verify'; + +function X509_REQ_verify(a: PX509_REQ; r: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_verify'; + +function X509_CRL_verify(a: PX509_CRL; r: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_verify'; + +function NETSCAPE_SPKI_verify(a: PNETSCAPE_SPKI; r: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'NETSCAPE_SPKI_verify'; + +function NETSCAPE_SPKI_b64_decode(str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: Integer): PNETSCAPE_SPKI; cdecl; + external LIB_CRYPTO name _PU + 'NETSCAPE_SPKI_b64_decode'; + +function NETSCAPE_SPKI_b64_encode(x: PNETSCAPE_SPKI): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'NETSCAPE_SPKI_b64_encode'; + +function NETSCAPE_SPKI_get_pubkey(x: PNETSCAPE_SPKI): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'NETSCAPE_SPKI_get_pubkey'; + +function NETSCAPE_SPKI_set_pubkey(x: PNETSCAPE_SPKI; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'NETSCAPE_SPKI_set_pubkey'; + +function NETSCAPE_SPKI_print({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; spki: PNETSCAPE_SPKI): Integer; cdecl; + external LIB_CRYPTO name _PU + 'NETSCAPE_SPKI_print'; + +function X509_signature_dump(bp: PBIO; sig: PASN1_STRING; indent: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_signature_dump'; + +function X509_signature_print(bp: PBIO; alg: PX509_ALGOR; sig: PASN1_STRING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_signature_print'; + +function X509_sign(x: PX509; pkey: PEVP_PKEY; md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_sign'; + +function X509_sign_ctx(x: PX509; ctx: PEVP_MD_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_sign_ctx'; + +function X509_http_nbio(rctx: POCSP_REQ_CTX; pcert: PPX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_http_nbio'; + +function X509_REQ_sign(x: PX509_REQ; pkey: PEVP_PKEY; md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_sign'; + +function X509_REQ_sign_ctx(x: PX509_REQ; ctx: PEVP_MD_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_sign_ctx'; + +function X509_CRL_sign(x: PX509_CRL; pkey: PEVP_PKEY; md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_sign'; + +function X509_CRL_sign_ctx(x: PX509_CRL; ctx: PEVP_MD_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_sign_ctx'; + +function X509_CRL_http_nbio(rctx: POCSP_REQ_CTX; pcrl: PPX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_http_nbio'; + +function NETSCAPE_SPKI_sign(x: PNETSCAPE_SPKI; pkey: PEVP_PKEY; md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'NETSCAPE_SPKI_sign'; + +function X509_pubkey_digest(data: PX509; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_MD; md: PByte; len: PCardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_pubkey_digest'; + +function X509_digest(data: PX509; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_MD; md: PByte; len: PCardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_digest'; + +function X509_CRL_digest(data: PX509_CRL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_MD; md: PByte; len: PCardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_digest'; + +function X509_REQ_digest(data: PX509_REQ; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_MD; md: PByte; len: PCardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_digest'; + +function X509_NAME_digest(data: PX509_NAME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_MD; md: PByte; len: PCardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_digest'; + +function d2i_X509_fp(fp: PPointer; x509: PPX509): PX509; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_fp'; + +function i2d_X509_fp(fp: PPointer; x509: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_fp'; + +function d2i_X509_CRL_fp(fp: PPointer; crl: PPX509_CRL): PX509_CRL; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_CRL_fp'; + +function i2d_X509_CRL_fp(fp: PPointer; crl: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_CRL_fp'; + +function d2i_X509_REQ_fp(fp: PPointer; req: PPX509_REQ): PX509_REQ; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_REQ_fp'; + +function i2d_X509_REQ_fp(fp: PPointer; req: PX509_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_REQ_fp'; + +function d2i_RSAPrivateKey_fp(fp: PPointer; rsa: PPRSA): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_RSAPrivateKey_fp'; + +function i2d_RSAPrivateKey_fp(fp: PPointer; rsa: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_RSAPrivateKey_fp'; + +function d2i_RSAPublicKey_fp(fp: PPointer; rsa: PPRSA): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_RSAPublicKey_fp'; + +function i2d_RSAPublicKey_fp(fp: PPointer; rsa: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_RSAPublicKey_fp'; + +function d2i_RSA_PUBKEY_fp(fp: PPointer; rsa: PPRSA): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_RSA_PUBKEY_fp'; + +function i2d_RSA_PUBKEY_fp(fp: PPointer; rsa: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_RSA_PUBKEY_fp'; + +function d2i_DSA_PUBKEY_fp(fp: PPointer; dsa: PPDSA): PDSA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_DSA_PUBKEY_fp'; + +function i2d_DSA_PUBKEY_fp(fp: PPointer; dsa: PDSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_DSA_PUBKEY_fp'; + +function d2i_DSAPrivateKey_fp(fp: PPointer; dsa: PPDSA): PDSA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_DSAPrivateKey_fp'; + +function i2d_DSAPrivateKey_fp(fp: PPointer; dsa: PDSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_DSAPrivateKey_fp'; + +function d2i_EC_PUBKEY_fp(fp: PPointer; eckey: PPEC_KEY): PEC_KEY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_EC_PUBKEY_fp'; + +function i2d_EC_PUBKEY_fp(fp: PPointer; eckey: PEC_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_EC_PUBKEY_fp'; + +function d2i_ECPrivateKey_fp(fp: PPointer; eckey: PPEC_KEY): PEC_KEY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ECPrivateKey_fp'; + +function i2d_ECPrivateKey_fp(fp: PPointer; eckey: PEC_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ECPrivateKey_fp'; + +function d2i_PKCS8_fp(fp: PPointer; p8: PPX509_SIG): PX509_SIG; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS8_fp'; + +function i2d_PKCS8_fp(fp: PPointer; p8: PX509_SIG): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS8_fp'; + +function d2i_PKCS8_PRIV_KEY_INFO_fp(fp: PPointer; p8inf: PPPKCS8_PRIV_KEY_INFO): PPKCS8_PRIV_KEY_INFO; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS8_PRIV_KEY_INFO_fp'; + +function i2d_PKCS8_PRIV_KEY_INFO_fp(fp: PPointer; p8inf: PPKCS8_PRIV_KEY_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS8_PRIV_KEY_INFO_fp'; + +function i2d_PKCS8PrivateKeyInfo_fp(fp: PPointer; key: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS8PrivateKeyInfo_fp'; + +function i2d_PrivateKey_fp(fp: PPointer; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PrivateKey_fp'; + +function d2i_PrivateKey_fp(fp: PPointer; a: PPEVP_PKEY): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PrivateKey_fp'; + +function i2d_PUBKEY_fp(fp: PPointer; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PUBKEY_fp'; + +function d2i_PUBKEY_fp(fp: PPointer; a: PPEVP_PKEY): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PUBKEY_fp'; + +function d2i_X509_bio(bp: PBIO; x509: PPX509): PX509; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_bio'; + +function i2d_X509_bio(bp: PBIO; x509: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_bio'; + +function d2i_X509_CRL_bio(bp: PBIO; crl: PPX509_CRL): PX509_CRL; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_CRL_bio'; + +function i2d_X509_CRL_bio(bp: PBIO; crl: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_CRL_bio'; + +function d2i_X509_REQ_bio(bp: PBIO; req: PPX509_REQ): PX509_REQ; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_REQ_bio'; + +function i2d_X509_REQ_bio(bp: PBIO; req: PX509_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_REQ_bio'; + +function d2i_RSAPrivateKey_bio(bp: PBIO; rsa: PPRSA): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_RSAPrivateKey_bio'; + +function i2d_RSAPrivateKey_bio(bp: PBIO; rsa: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_RSAPrivateKey_bio'; + +function d2i_RSAPublicKey_bio(bp: PBIO; rsa: PPRSA): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_RSAPublicKey_bio'; + +function i2d_RSAPublicKey_bio(bp: PBIO; rsa: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_RSAPublicKey_bio'; + +function d2i_RSA_PUBKEY_bio(bp: PBIO; rsa: PPRSA): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_RSA_PUBKEY_bio'; + +function i2d_RSA_PUBKEY_bio(bp: PBIO; rsa: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_RSA_PUBKEY_bio'; + +function d2i_DSA_PUBKEY_bio(bp: PBIO; dsa: PPDSA): PDSA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_DSA_PUBKEY_bio'; + +function i2d_DSA_PUBKEY_bio(bp: PBIO; dsa: PDSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_DSA_PUBKEY_bio'; + +function d2i_DSAPrivateKey_bio(bp: PBIO; dsa: PPDSA): PDSA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_DSAPrivateKey_bio'; + +function i2d_DSAPrivateKey_bio(bp: PBIO; dsa: PDSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_DSAPrivateKey_bio'; + +function d2i_EC_PUBKEY_bio(bp: PBIO; eckey: PPEC_KEY): PEC_KEY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_EC_PUBKEY_bio'; + +function i2d_EC_PUBKEY_bio(bp: PBIO; eckey: PEC_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_EC_PUBKEY_bio'; + +function d2i_ECPrivateKey_bio(bp: PBIO; eckey: PPEC_KEY): PEC_KEY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ECPrivateKey_bio'; + +function i2d_ECPrivateKey_bio(bp: PBIO; eckey: PEC_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ECPrivateKey_bio'; + +function d2i_PKCS8_bio(bp: PBIO; p8: PPX509_SIG): PX509_SIG; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS8_bio'; + +function i2d_PKCS8_bio(bp: PBIO; p8: PX509_SIG): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS8_bio'; + +function d2i_PKCS8_PRIV_KEY_INFO_bio(bp: PBIO; p8inf: PPPKCS8_PRIV_KEY_INFO): PPKCS8_PRIV_KEY_INFO; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS8_PRIV_KEY_INFO_bio'; + +function i2d_PKCS8_PRIV_KEY_INFO_bio(bp: PBIO; p8inf: PPKCS8_PRIV_KEY_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS8_PRIV_KEY_INFO_bio'; + +function i2d_PKCS8PrivateKeyInfo_bio(bp: PBIO; key: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS8PrivateKeyInfo_bio'; + +function i2d_PrivateKey_bio(bp: PBIO; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PrivateKey_bio'; + +function d2i_PrivateKey_bio(bp: PBIO; a: PPEVP_PKEY): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PrivateKey_bio'; + +function i2d_PUBKEY_bio(bp: PBIO; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PUBKEY_bio'; + +function d2i_PUBKEY_bio(bp: PBIO; a: PPEVP_PKEY): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PUBKEY_bio'; + +function X509_dup(x509: PX509): PX509; cdecl; + external LIB_CRYPTO name _PU + 'X509_dup'; + +function X509_ATTRIBUTE_dup(xa: PX509_ATTRIBUTE): PX509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'X509_ATTRIBUTE_dup'; + +function X509_EXTENSION_dup(ex: PX509_EXTENSION): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509_EXTENSION_dup'; + +function X509_CRL_dup(crl: PX509_CRL): PX509_CRL; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_dup'; + +function X509_REVOKED_dup(rev: PX509_REVOKED): PX509_REVOKED; cdecl; + external LIB_CRYPTO name _PU + 'X509_REVOKED_dup'; + +function X509_REQ_dup(req: PX509_REQ): PX509_REQ; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_dup'; + +function X509_ALGOR_dup(xn: PX509_ALGOR): PX509_ALGOR; cdecl; + external LIB_CRYPTO name _PU + 'X509_ALGOR_dup'; + +function X509_ALGOR_set0(alg: PX509_ALGOR; aobj: PASN1_OBJECT; ptype: Integer; pval: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_ALGOR_set0'; + +procedure X509_ALGOR_get0(paobj: PPASN1_OBJECT; pptype: PInteger; ppval: PPointer; algor: PX509_ALGOR); cdecl; + external LIB_CRYPTO name _PU + 'X509_ALGOR_get0'; + +procedure X509_ALGOR_set_md(alg: PX509_ALGOR; md: PEVP_MD); cdecl; + external LIB_CRYPTO name _PU + 'X509_ALGOR_set_md'; + +function X509_ALGOR_cmp(a: PX509_ALGOR; b: PX509_ALGOR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_ALGOR_cmp'; + +function X509_NAME_dup(xn: PX509_NAME): PX509_NAME; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_dup'; + +function X509_NAME_ENTRY_dup(ne: PX509_NAME_ENTRY): PX509_NAME_ENTRY; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_ENTRY_dup'; + +function X509_cmp_time(s: PASN1_TIME; t: PLongint): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_cmp_time'; + +function X509_cmp_current_time(s: PASN1_TIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_cmp_current_time'; + +function X509_time_adj(s: PASN1_TIME; adj: Integer; t: PLongint): PASN1_TIME; cdecl; + external LIB_CRYPTO name _PU + 'X509_time_adj'; + +function X509_time_adj_ex(s: PASN1_TIME; offset_day: Integer; offset_sec: Integer; t: PLongint): PASN1_TIME; cdecl; + external LIB_CRYPTO name _PU + 'X509_time_adj_ex'; + +function X509_gmtime_adj(s: PASN1_TIME; adj: Integer): PASN1_TIME; cdecl; + external LIB_CRYPTO name _PU + 'X509_gmtime_adj'; + +function X509_get_default_cert_area(): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_default_cert_area'; + +function X509_get_default_cert_dir(): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_default_cert_dir'; + +function X509_get_default_cert_file(): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_default_cert_file'; + +function X509_get_default_cert_dir_env(): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_default_cert_dir_env'; + +function X509_get_default_cert_file_env(): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_default_cert_file_env'; + +function X509_get_default_private_dir(): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_default_private_dir'; + +function X509_to_X509_REQ(x: PX509; pkey: PEVP_PKEY; md: PEVP_MD): PX509_REQ; cdecl; + external LIB_CRYPTO name _PU + 'X509_to_X509_REQ'; + +function X509_REQ_to_X509(r: PX509_REQ; days: Integer; pkey: PEVP_PKEY): PX509; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_to_X509'; + +function X509_ALGOR_new(): PX509_ALGOR; cdecl; + external LIB_CRYPTO name _PU + 'X509_ALGOR_new'; + +procedure X509_ALGOR_free(a: PX509_ALGOR); cdecl; + external LIB_CRYPTO name _PU + 'X509_ALGOR_free'; + +function d2i_X509_ALGOR(a: PPX509_ALGOR; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PX509_ALGOR; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_ALGOR'; + +function i2d_X509_ALGOR(a: PX509_ALGOR; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_ALGOR'; + +function X509_ALGOR_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'X509_ALGOR_it'; + +function d2i_X509_ALGORS(a: PPX509_ALGORS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PX509_ALGORS; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_ALGORS'; + +function i2d_X509_ALGORS(a: PX509_ALGORS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_ALGORS'; + +function X509_ALGORS_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'X509_ALGORS_it'; + +function X509_VAL_new(): PX509_VAL; cdecl; + external LIB_CRYPTO name _PU + 'X509_VAL_new'; + +procedure X509_VAL_free(a: PX509_VAL); cdecl; + external LIB_CRYPTO name _PU + 'X509_VAL_free'; + +function d2i_X509_VAL(a: PPX509_VAL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PX509_VAL; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_VAL'; + +function i2d_X509_VAL(a: PX509_VAL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_VAL'; + +function X509_VAL_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'X509_VAL_it'; + +function X509_PUBKEY_new(): PX509_PUBKEY; cdecl; + external LIB_CRYPTO name _PU + 'X509_PUBKEY_new'; + +procedure X509_PUBKEY_free(a: PX509_PUBKEY); cdecl; + external LIB_CRYPTO name _PU + 'X509_PUBKEY_free'; + +function d2i_X509_PUBKEY(a: PPX509_PUBKEY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PX509_PUBKEY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_PUBKEY'; + +function i2d_X509_PUBKEY(a: PX509_PUBKEY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_PUBKEY'; + +function X509_PUBKEY_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'X509_PUBKEY_it'; + +function X509_PUBKEY_set(x: PPX509_PUBKEY; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_PUBKEY_set'; + +function X509_PUBKEY_get0(key: PX509_PUBKEY): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'X509_PUBKEY_get0'; + +function X509_PUBKEY_get(key: PX509_PUBKEY): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'X509_PUBKEY_get'; + +function X509_get_pubkey_parameters(pkey: PEVP_PKEY; chain: Pstack_st_X509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_pubkey_parameters'; + +function X509_get_pathlen(x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_pathlen'; + +function i2d_PUBKEY(a: PEVP_PKEY; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PUBKEY'; + +function d2i_PUBKEY(a: PPEVP_PKEY; pp: PPByte; length: Integer): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PUBKEY'; + +function i2d_RSA_PUBKEY(a: PRSA; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_RSA_PUBKEY'; + +function d2i_RSA_PUBKEY(a: PPRSA; pp: PPByte; length: Integer): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_RSA_PUBKEY'; + +function i2d_DSA_PUBKEY(a: PDSA; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_DSA_PUBKEY'; + +function d2i_DSA_PUBKEY(a: PPDSA; pp: PPByte; length: Integer): PDSA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_DSA_PUBKEY'; + +function i2d_EC_PUBKEY(a: PEC_KEY; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_EC_PUBKEY'; + +function d2i_EC_PUBKEY(a: PPEC_KEY; pp: PPByte; length: Integer): PEC_KEY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_EC_PUBKEY'; + +function X509_SIG_new(): PX509_SIG; cdecl; + external LIB_CRYPTO name _PU + 'X509_SIG_new'; + +procedure X509_SIG_free(a: PX509_SIG); cdecl; + external LIB_CRYPTO name _PU + 'X509_SIG_free'; + +function d2i_X509_SIG(a: PPX509_SIG; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PX509_SIG; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_SIG'; + +function i2d_X509_SIG(a: PX509_SIG; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_SIG'; + +function X509_SIG_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'X509_SIG_it'; + +procedure X509_SIG_get0(sig: PX509_SIG; palg: PPX509_ALGOR; pdigest: PPASN1_OCTET_STRING); cdecl; + external LIB_CRYPTO name _PU + 'X509_SIG_get0'; + +procedure X509_SIG_getm(sig: PX509_SIG; palg: PPX509_ALGOR; pdigest: PPASN1_OCTET_STRING); cdecl; + external LIB_CRYPTO name _PU + 'X509_SIG_getm'; + +function X509_REQ_INFO_new(): PX509_REQ_INFO; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_INFO_new'; + +procedure X509_REQ_INFO_free(a: PX509_REQ_INFO); cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_INFO_free'; + +function d2i_X509_REQ_INFO(a: PPX509_REQ_INFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PX509_REQ_INFO; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_REQ_INFO'; + +function i2d_X509_REQ_INFO(a: PX509_REQ_INFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_REQ_INFO'; + +function X509_REQ_INFO_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_INFO_it'; + +function X509_REQ_new(): PX509_REQ; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_new'; + +procedure X509_REQ_free(a: PX509_REQ); cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_free'; + +function d2i_X509_REQ(a: PPX509_REQ; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PX509_REQ; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_REQ'; + +function i2d_X509_REQ(a: PX509_REQ; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_REQ'; + +function X509_REQ_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_it'; + +function X509_ATTRIBUTE_new(): PX509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'X509_ATTRIBUTE_new'; + +procedure X509_ATTRIBUTE_free(a: PX509_ATTRIBUTE); cdecl; + external LIB_CRYPTO name _PU + 'X509_ATTRIBUTE_free'; + +function d2i_X509_ATTRIBUTE(a: PPX509_ATTRIBUTE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PX509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_ATTRIBUTE'; + +function i2d_X509_ATTRIBUTE(a: PX509_ATTRIBUTE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_ATTRIBUTE'; + +function X509_ATTRIBUTE_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'X509_ATTRIBUTE_it'; + +function X509_ATTRIBUTE_create(nid: Integer; atrtype: Integer; value: Pointer): PX509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'X509_ATTRIBUTE_create'; + +function X509_EXTENSION_new(): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509_EXTENSION_new'; + +procedure X509_EXTENSION_free(a: PX509_EXTENSION); cdecl; + external LIB_CRYPTO name _PU + 'X509_EXTENSION_free'; + +function d2i_X509_EXTENSION(a: PPX509_EXTENSION; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_EXTENSION'; + +function i2d_X509_EXTENSION(a: PX509_EXTENSION; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_EXTENSION'; + +function X509_EXTENSION_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'X509_EXTENSION_it'; + +function d2i_X509_EXTENSIONS(a: PPX509_EXTENSIONS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PX509_EXTENSIONS; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_EXTENSIONS'; + +function i2d_X509_EXTENSIONS(a: PX509_EXTENSIONS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_EXTENSIONS'; + +function X509_EXTENSIONS_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'X509_EXTENSIONS_it'; + +function X509_NAME_ENTRY_new(): PX509_NAME_ENTRY; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_ENTRY_new'; + +procedure X509_NAME_ENTRY_free(a: PX509_NAME_ENTRY); cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_ENTRY_free'; + +function d2i_X509_NAME_ENTRY(a: PPX509_NAME_ENTRY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PX509_NAME_ENTRY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_NAME_ENTRY'; + +function i2d_X509_NAME_ENTRY(a: PX509_NAME_ENTRY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_NAME_ENTRY'; + +function X509_NAME_ENTRY_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_ENTRY_it'; + +function X509_NAME_new(): PX509_NAME; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_new'; + +procedure X509_NAME_free(a: PX509_NAME); cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_free'; + +function d2i_X509_NAME(a: PPX509_NAME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PX509_NAME; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_NAME'; + +function i2d_X509_NAME(a: PX509_NAME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_NAME'; + +function X509_NAME_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_it'; + +function X509_NAME_set(xn: PPX509_NAME; name: PX509_NAME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_set'; + +function X509_CINF_new(): PX509_CINF; cdecl; + external LIB_CRYPTO name _PU + 'X509_CINF_new'; + +procedure X509_CINF_free(a: PX509_CINF); cdecl; + external LIB_CRYPTO name _PU + 'X509_CINF_free'; + +function d2i_X509_CINF(a: PPX509_CINF; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PX509_CINF; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_CINF'; + +function i2d_X509_CINF(a: PX509_CINF; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_CINF'; + +function X509_CINF_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'X509_CINF_it'; + +function X509_new(): PX509; cdecl; + external LIB_CRYPTO name _PU + 'X509_new'; + +procedure X509_free(a: PX509); cdecl; + external LIB_CRYPTO name _PU + 'X509_free'; + +function d2i_X509(a: PPX509; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PX509; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509'; + +function i2d_X509(a: PX509; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509'; + +function X509_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'X509_it'; + +function X509_CERT_AUX_new(): PX509_CERT_AUX; cdecl; + external LIB_CRYPTO name _PU + 'X509_CERT_AUX_new'; + +procedure X509_CERT_AUX_free(a: PX509_CERT_AUX); cdecl; + external LIB_CRYPTO name _PU + 'X509_CERT_AUX_free'; + +function d2i_X509_CERT_AUX(a: PPX509_CERT_AUX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PX509_CERT_AUX; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_CERT_AUX'; + +function i2d_X509_CERT_AUX(a: PX509_CERT_AUX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_CERT_AUX'; + +function X509_CERT_AUX_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'X509_CERT_AUX_it'; + +function X509_set_ex_data(r: PX509; idx: Integer; arg: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_set_ex_data'; + +function X509_get_ex_data(r: PX509; idx: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_ex_data'; + +function i2d_X509_AUX(a: PX509; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_AUX'; + +function d2i_X509_AUX(a: PPX509; pp: PPByte; length: Integer): PX509; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_AUX'; + +function i2d_re_X509_tbs(x: PX509; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_re_X509_tbs'; + +function X509_SIG_INFO_get(siginf: PX509_SIG_INFO; mdnid: PInteger; pknid: PInteger; secbits: PInteger; flags: PUInt32): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_SIG_INFO_get'; + +procedure X509_SIG_INFO_set(siginf: PX509_SIG_INFO; mdnid: Integer; pknid: Integer; secbits: Integer; flags: {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt32{$ELSE}LongInt{$IFEND}{$ELSE}UInt32{$ENDIF}); cdecl; + external LIB_CRYPTO name _PU + 'X509_SIG_INFO_set'; + +function X509_get_signature_info(x: PX509; mdnid: PInteger; pknid: PInteger; secbits: PInteger; flags: PUInt32): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_signature_info'; + +procedure X509_get0_signature(psig: PPASN1_BIT_STRING; palg: PPX509_ALGOR; x: PX509); cdecl; + external LIB_CRYPTO name _PU + 'X509_get0_signature'; + +function X509_get_signature_nid(x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_signature_nid'; + +function X509_trusted(x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_trusted'; + +function X509_alias_set1(x: PX509; name: PByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_alias_set1'; + +function X509_keyid_set1(x: PX509; id: PByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_keyid_set1'; + +function X509_alias_get0(x: PX509; len: PInteger): PByte; cdecl; + external LIB_CRYPTO name _PU + 'X509_alias_get0'; + +function X509_keyid_get0(x: PX509; len: PInteger): PByte; cdecl; + external LIB_CRYPTO name _PU + 'X509_keyid_get0'; + +type + X509_TRUST_set_default_trust = function(p1: Integer; p2: PX509; p3: Integer): Integer; cdecl; + +//function X509_TRUST_set_default(p1: Integerp2: PX509p3: Integertrust: X509_TRUST_set_default_trust): Integer { TODO : Cannot convert original type "int (*)(int, X509 *, int)" }; cdecl; +// external LIB_CRYPTO name _PU + 'X509_TRUST_set_default'; + +function X509_TRUST_set(t: PInteger; trust: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_TRUST_set'; + +function X509_add1_trust_object(x: PX509; obj: PASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_add1_trust_object'; + +function X509_add1_reject_object(x: PX509; obj: PASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_add1_reject_object'; + +procedure X509_trust_clear(x: PX509); cdecl; + external LIB_CRYPTO name _PU + 'X509_trust_clear'; + +procedure X509_reject_clear(x: PX509); cdecl; + external LIB_CRYPTO name _PU + 'X509_reject_clear'; + +function X509_get0_trust_objects(x: PX509): Pstack_st_ASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'X509_get0_trust_objects'; + +function X509_get0_reject_objects(x: PX509): Pstack_st_ASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'X509_get0_reject_objects'; + +function X509_REVOKED_new(): PX509_REVOKED; cdecl; + external LIB_CRYPTO name _PU + 'X509_REVOKED_new'; + +procedure X509_REVOKED_free(a: PX509_REVOKED); cdecl; + external LIB_CRYPTO name _PU + 'X509_REVOKED_free'; + +function d2i_X509_REVOKED(a: PPX509_REVOKED; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PX509_REVOKED; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_REVOKED'; + +function i2d_X509_REVOKED(a: PX509_REVOKED; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_REVOKED'; + +function X509_REVOKED_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'X509_REVOKED_it'; + +function X509_CRL_INFO_new(): PX509_CRL_INFO; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_INFO_new'; + +procedure X509_CRL_INFO_free(a: PX509_CRL_INFO); cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_INFO_free'; + +function d2i_X509_CRL_INFO(a: PPX509_CRL_INFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PX509_CRL_INFO; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_CRL_INFO'; + +function i2d_X509_CRL_INFO(a: PX509_CRL_INFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_CRL_INFO'; + +function X509_CRL_INFO_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_INFO_it'; + +function X509_CRL_new(): PX509_CRL; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_new'; + +procedure X509_CRL_free(a: PX509_CRL); cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_free'; + +function d2i_X509_CRL(a: PPX509_CRL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PX509_CRL; cdecl; + external LIB_CRYPTO name _PU + 'd2i_X509_CRL'; + +function i2d_X509_CRL(a: PX509_CRL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_X509_CRL'; + +function X509_CRL_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_it'; + +function X509_CRL_add0_revoked(crl: PX509_CRL; rev: PX509_REVOKED): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_add0_revoked'; + +function X509_CRL_get0_by_serial(crl: PX509_CRL; ret: PPX509_REVOKED; serial: PASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get0_by_serial'; + +function X509_CRL_get0_by_cert(crl: PX509_CRL; ret: PPX509_REVOKED; x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get0_by_cert'; + +function X509_PKEY_new(): PX509_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'X509_PKEY_new'; + +procedure X509_PKEY_free(a: PX509_PKEY); cdecl; + external LIB_CRYPTO name _PU + 'X509_PKEY_free'; + +function NETSCAPE_SPKI_new(): PNETSCAPE_SPKI; cdecl; + external LIB_CRYPTO name _PU + 'NETSCAPE_SPKI_new'; + +procedure NETSCAPE_SPKI_free(a: PNETSCAPE_SPKI); cdecl; + external LIB_CRYPTO name _PU + 'NETSCAPE_SPKI_free'; + +function d2i_NETSCAPE_SPKI(a: PPNETSCAPE_SPKI; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PNETSCAPE_SPKI; cdecl; + external LIB_CRYPTO name _PU + 'd2i_NETSCAPE_SPKI'; + +function i2d_NETSCAPE_SPKI(a: PNETSCAPE_SPKI; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_NETSCAPE_SPKI'; + +function NETSCAPE_SPKI_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'NETSCAPE_SPKI_it'; + +function NETSCAPE_SPKAC_new(): PNETSCAPE_SPKAC; cdecl; + external LIB_CRYPTO name _PU + 'NETSCAPE_SPKAC_new'; + +procedure NETSCAPE_SPKAC_free(a: PNETSCAPE_SPKAC); cdecl; + external LIB_CRYPTO name _PU + 'NETSCAPE_SPKAC_free'; + +function d2i_NETSCAPE_SPKAC(a: PPNETSCAPE_SPKAC; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PNETSCAPE_SPKAC; cdecl; + external LIB_CRYPTO name _PU + 'd2i_NETSCAPE_SPKAC'; + +function i2d_NETSCAPE_SPKAC(a: PNETSCAPE_SPKAC; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_NETSCAPE_SPKAC'; + +function NETSCAPE_SPKAC_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'NETSCAPE_SPKAC_it'; + +function NETSCAPE_CERT_SEQUENCE_new(): PNETSCAPE_CERT_SEQUENCE; cdecl; + external LIB_CRYPTO name _PU + 'NETSCAPE_CERT_SEQUENCE_new'; + +procedure NETSCAPE_CERT_SEQUENCE_free(a: PNETSCAPE_CERT_SEQUENCE); cdecl; + external LIB_CRYPTO name _PU + 'NETSCAPE_CERT_SEQUENCE_free'; + +function d2i_NETSCAPE_CERT_SEQUENCE(a: PPNETSCAPE_CERT_SEQUENCE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PNETSCAPE_CERT_SEQUENCE; cdecl; + external LIB_CRYPTO name _PU + 'd2i_NETSCAPE_CERT_SEQUENCE'; + +function i2d_NETSCAPE_CERT_SEQUENCE(a: PNETSCAPE_CERT_SEQUENCE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_NETSCAPE_CERT_SEQUENCE'; + +function NETSCAPE_CERT_SEQUENCE_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'NETSCAPE_CERT_SEQUENCE_it'; + +function X509_INFO_new(): PX509_INFO; cdecl; + external LIB_CRYPTO name _PU + 'X509_INFO_new'; + +procedure X509_INFO_free(a: PX509_INFO); cdecl; + external LIB_CRYPTO name _PU + 'X509_INFO_free'; + +function X509_NAME_oneline(a: PX509_NAME; buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; size: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_oneline'; + +function ASN1_verify(i2d: Pi2d_of_void; algor1: PX509_ALGOR; signature: PASN1_BIT_STRING; data: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_verify'; + +function ASN1_digest(i2d: Pi2d_of_void; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_MD; data: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; md: PByte; len: PCardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_digest'; + +function ASN1_sign(i2d: Pi2d_of_void; algor1: PX509_ALGOR; algor2: PX509_ALGOR; signature: PASN1_BIT_STRING; data: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; pkey: PEVP_PKEY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_sign'; + +function ASN1_item_digest(it: PASN1_ITEM; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_MD; data: Pointer; md: PByte; len: PCardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_digest'; + +function ASN1_item_verify(it: PASN1_ITEM; algor1: PX509_ALGOR; signature: PASN1_BIT_STRING; data: Pointer; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_verify'; + +function ASN1_item_sign(it: PASN1_ITEM; algor1: PX509_ALGOR; algor2: PX509_ALGOR; signature: PASN1_BIT_STRING; data: Pointer; pkey: PEVP_PKEY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_sign'; + +function ASN1_item_sign_ctx(it: PASN1_ITEM; algor1: PX509_ALGOR; algor2: PX509_ALGOR; signature: PASN1_BIT_STRING; asn: Pointer; ctx: PEVP_MD_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ASN1_item_sign_ctx'; + +function X509_get_version(x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_version'; + +function X509_set_version(x: PX509; version: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_set_version'; + +function X509_set_serialNumber(x: PX509; serial: PASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_set_serialNumber'; + +function X509_get_serialNumber(x: PX509): PASN1_INTEGER; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_serialNumber'; + +function X509_get0_serialNumber(x: PX509): PASN1_INTEGER; cdecl; + external LIB_CRYPTO name _PU + 'X509_get0_serialNumber'; + +function X509_set_issuer_name(x: PX509; name: PX509_NAME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_set_issuer_name'; + +function X509_get_issuer_name(a: PX509): PX509_NAME; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_issuer_name'; + +function X509_set_subject_name(x: PX509; name: PX509_NAME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_set_subject_name'; + +function X509_get_subject_name(a: PX509): PX509_NAME; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_subject_name'; + +function X509_get0_notBefore(x: PX509): PASN1_TIME; cdecl; + external LIB_CRYPTO name _PU + 'X509_get0_notBefore'; + +function X509_getm_notBefore(x: PX509): PASN1_TIME; cdecl; + external LIB_CRYPTO name _PU + 'X509_getm_notBefore'; +function X509_get_notBefore(x: PX509): PASN1_TIME; cdecl; + external LIB_CRYPTO name _PU + 'X509_getm_notBefore'; + +function X509_set1_notBefore(x: PX509; tm: PASN1_TIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_set1_notBefore'; +function X509_set_notBefore(x: PX509; tm: PASN1_TIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_set1_notBefore'; + +function X509_get0_notAfter(x: PX509): PASN1_TIME; cdecl; + external LIB_CRYPTO name _PU + 'X509_get0_notAfter'; + +function X509_getm_notAfter(x: PX509): PASN1_TIME; cdecl; + external LIB_CRYPTO name _PU + 'X509_getm_notAfter'; +function X509_get_notAfter(x: PX509): PASN1_TIME; cdecl; + external LIB_CRYPTO name _PU + 'X509_getm_notAfter'; + +function X509_set1_notAfter(x: PX509; tm: PASN1_TIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_set1_notAfter'; +function X509_set_notAfter(x: PX509; tm: PASN1_TIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_set1_notAfter'; + +function X509_set_pubkey(x: PX509; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_set_pubkey'; + +function X509_up_ref(x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_up_ref'; + +function X509_get_signature_type(x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_signature_type'; + +function X509_get_X509_PUBKEY(x: PX509): PX509_PUBKEY; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_X509_PUBKEY'; + +function X509_get0_extensions(x: PX509): Pstack_st_X509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509_get0_extensions'; + +procedure X509_get0_uids(x: PX509; piuid: PPASN1_BIT_STRING; psuid: PPASN1_BIT_STRING); cdecl; + external LIB_CRYPTO name _PU + 'X509_get0_uids'; + +function X509_get0_tbs_sigalg(x: PX509): PX509_ALGOR; cdecl; + external LIB_CRYPTO name _PU + 'X509_get0_tbs_sigalg'; + +function X509_get0_pubkey(x: PX509): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'X509_get0_pubkey'; + +function X509_get_pubkey(x: PX509): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_pubkey'; + +function X509_get0_pubkey_bitstr(x: PX509): PASN1_BIT_STRING; cdecl; + external LIB_CRYPTO name _PU + 'X509_get0_pubkey_bitstr'; + +function X509_certificate_type(x: PX509; pubkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_certificate_type'; + +function X509_REQ_get_version(req: PX509_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_get_version'; + +function X509_REQ_set_version(x: PX509_REQ; version: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_set_version'; + +function X509_REQ_get_subject_name(req: PX509_REQ): PX509_NAME; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_get_subject_name'; + +function X509_REQ_set_subject_name(req: PX509_REQ; name: PX509_NAME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_set_subject_name'; + +procedure X509_REQ_get0_signature(req: PX509_REQ; psig: PPASN1_BIT_STRING; palg: PPX509_ALGOR); cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_get0_signature'; + +function X509_REQ_get_signature_nid(req: PX509_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_get_signature_nid'; + +function i2d_re_X509_REQ_tbs(req: PX509_REQ; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_re_X509_REQ_tbs'; + +function X509_REQ_set_pubkey(x: PX509_REQ; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_set_pubkey'; + +function X509_REQ_get_pubkey(req: PX509_REQ): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_get_pubkey'; + +function X509_REQ_get0_pubkey(req: PX509_REQ): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_get0_pubkey'; + +function X509_REQ_get_X509_PUBKEY(req: PX509_REQ): PX509_PUBKEY; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_get_X509_PUBKEY'; + +function X509_REQ_extension_nid(nid: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_extension_nid'; + +function X509_REQ_get_extension_nids(): PInteger; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_get_extension_nids'; + +procedure X509_REQ_set_extension_nids(nids: PInteger); cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_set_extension_nids'; + +function X509_REQ_get_extensions(req: PX509_REQ): Pstack_st_X509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_get_extensions'; + +function X509_REQ_add_extensions_nid(req: PX509_REQ; exts: Pstack_st_X509_EXTENSION; nid: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_add_extensions_nid'; + +function X509_REQ_add_extensions(req: PX509_REQ; exts: Pstack_st_X509_EXTENSION): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_add_extensions'; + +function X509_REQ_get_attr_count(req: PX509_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_get_attr_count'; + +function X509_REQ_get_attr_by_NID(req: PX509_REQ; nid: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_get_attr_by_NID'; + +function X509_REQ_get_attr_by_OBJ(req: PX509_REQ; obj: PASN1_OBJECT; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_get_attr_by_OBJ'; + +function X509_REQ_get_attr(req: PX509_REQ; loc: Integer): PX509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_get_attr'; + +function X509_REQ_delete_attr(req: PX509_REQ; loc: Integer): PX509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_delete_attr'; + +function X509_REQ_add1_attr(req: PX509_REQ; attr: PX509_ATTRIBUTE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_add1_attr'; + +function X509_REQ_add1_attr_by_OBJ(req: PX509_REQ; obj: PASN1_OBJECT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: PByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_add1_attr_by_OBJ'; + +function X509_REQ_add1_attr_by_NID(req: PX509_REQ; nid: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: PByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_add1_attr_by_NID'; + +function X509_REQ_add1_attr_by_txt(req: PX509_REQ; attrname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: PByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_add1_attr_by_txt'; + +function X509_CRL_set_version(x: PX509_CRL; version: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_set_version'; + +function X509_CRL_set_issuer_name(x: PX509_CRL; name: PX509_NAME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_set_issuer_name'; + +function X509_CRL_set1_lastUpdate(x: PX509_CRL; tm: PASN1_TIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_set1_lastUpdate'; +function X509_CRL_set_lastUpdate(x: PX509_CRL; tm: PASN1_TIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_set1_lastUpdate'; + +function X509_CRL_set1_nextUpdate(x: PX509_CRL; tm: PASN1_TIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_set1_nextUpdate'; +function X509_CRL_set_nextUpdate(x: PX509_CRL; tm: PASN1_TIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_set1_nextUpdate'; + +function X509_CRL_sort(crl: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_sort'; + +function X509_CRL_up_ref(crl: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_up_ref'; + +function X509_CRL_get_version(crl: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get_version'; + +function X509_CRL_get0_lastUpdate(crl: PX509_CRL): PASN1_TIME; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get0_lastUpdate'; + +function X509_CRL_get0_nextUpdate(crl: PX509_CRL): PASN1_TIME; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get0_nextUpdate'; + +function X509_CRL_get_lastUpdate(crl: PX509_CRL): PASN1_TIME; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get_lastUpdate'; + +function X509_CRL_get_nextUpdate(crl: PX509_CRL): PASN1_TIME; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get_nextUpdate'; + +function X509_CRL_get_issuer(crl: PX509_CRL): PX509_NAME; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get_issuer'; + +function X509_CRL_get0_extensions(crl: PX509_CRL): Pstack_st_X509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get0_extensions'; + +function X509_CRL_get_REVOKED(crl: PX509_CRL): Pstack_st_X509_REVOKED; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get_REVOKED'; + +procedure X509_CRL_get0_signature(crl: PX509_CRL; psig: PPASN1_BIT_STRING; palg: PPX509_ALGOR); cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get0_signature'; + +function X509_CRL_get_signature_nid(crl: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get_signature_nid'; + +function i2d_re_X509_CRL_tbs(req: PX509_CRL; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_re_X509_CRL_tbs'; + +function X509_REVOKED_get0_serialNumber(x: PX509_REVOKED): PASN1_INTEGER; cdecl; + external LIB_CRYPTO name _PU + 'X509_REVOKED_get0_serialNumber'; + +function X509_REVOKED_set_serialNumber(x: PX509_REVOKED; serial: PASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REVOKED_set_serialNumber'; + +function X509_REVOKED_get0_revocationDate(x: PX509_REVOKED): PASN1_TIME; cdecl; + external LIB_CRYPTO name _PU + 'X509_REVOKED_get0_revocationDate'; + +function X509_REVOKED_set_revocationDate(r: PX509_REVOKED; tm: PASN1_TIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REVOKED_set_revocationDate'; + +function X509_REVOKED_get0_extensions(r: PX509_REVOKED): Pstack_st_X509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509_REVOKED_get0_extensions'; + +function X509_CRL_diff(base: PX509_CRL; newer: PX509_CRL; skey: PEVP_PKEY; md: PEVP_MD; flags: Cardinal): PX509_CRL; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_diff'; + +function X509_REQ_check_private_key(x509: PX509_REQ; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_check_private_key'; + +function X509_check_private_key(x509: PX509; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_check_private_key'; + +function X509_chain_check_suiteb(perror_depth: PInteger; x: PX509; chain: Pstack_st_X509; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_chain_check_suiteb'; + +function X509_CRL_check_suiteb(crl: PX509_CRL; pk: PEVP_PKEY; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_check_suiteb'; + +function X509_chain_up_ref(chain: Pstack_st_X509): Pstack_st_X509; cdecl; + external LIB_CRYPTO name _PU + 'X509_chain_up_ref'; + +function X509_issuer_and_serial_cmp(a: PX509; b: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_issuer_and_serial_cmp'; + +function X509_issuer_and_serial_hash(a: PX509): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'X509_issuer_and_serial_hash'; + +function X509_issuer_name_cmp(a: PX509; b: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_issuer_name_cmp'; + +function X509_issuer_name_hash(a: PX509): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'X509_issuer_name_hash'; + +function X509_subject_name_cmp(a: PX509; b: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_subject_name_cmp'; + +function X509_subject_name_hash(x: PX509): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'X509_subject_name_hash'; + +function X509_issuer_name_hash_old(a: PX509): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'X509_issuer_name_hash_old'; + +function X509_subject_name_hash_old(x: PX509): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'X509_subject_name_hash_old'; + +function X509_cmp(a: PX509; b: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_cmp'; + +function X509_NAME_cmp(a: PX509_NAME; b: PX509_NAME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_cmp'; + +function X509_NAME_hash(x: PX509_NAME): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_hash'; + +function X509_NAME_hash_old(x: PX509_NAME): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_hash_old'; + +function X509_CRL_cmp(a: PX509_CRL; b: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_cmp'; + +function X509_CRL_match(a: PX509_CRL; b: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_match'; + +function X509_aux_print({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; x: PX509; indent: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_aux_print'; + +function X509_print_ex_fp(bp: PPointer; x: PX509; nmflag: Cardinal; cflag: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_print_ex_fp'; + +function X509_print_fp(bp: PPointer; x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_print_fp'; + +function X509_CRL_print_fp(bp: PPointer; x: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_print_fp'; + +function X509_REQ_print_fp(bp: PPointer; req: PX509_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_print_fp'; + +function X509_NAME_print_ex_fp(fp: PPointer; nm: PX509_NAME; indent: Integer; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_print_ex_fp'; + +function X509_NAME_print(bp: PBIO; name: PX509_NAME; obase: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_print'; + +function X509_NAME_print_ex({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; nm: PX509_NAME; indent: Integer; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_print_ex'; + +function X509_print_ex(bp: PBIO; x: PX509; nmflag: Cardinal; cflag: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_print_ex'; + +function X509_print(bp: PBIO; x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_print'; + +function X509_ocspid_print(bp: PBIO; x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_ocspid_print'; + +function X509_CRL_print_ex({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; x: PX509_CRL; nmflag: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_print_ex'; + +function X509_CRL_print(bp: PBIO; x: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_print'; + +function X509_REQ_print_ex(bp: PBIO; x: PX509_REQ; nmflag: Cardinal; cflag: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_print_ex'; + +function X509_REQ_print(bp: PBIO; req: PX509_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_print'; + +function X509_NAME_entry_count(name: PX509_NAME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_entry_count'; + +function X509_NAME_get_text_by_NID(name: PX509_NAME; nid: Integer; buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_get_text_by_NID'; + +function X509_NAME_get_text_by_OBJ(name: PX509_NAME; obj: PASN1_OBJECT; buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_get_text_by_OBJ'; + +function X509_NAME_get_index_by_NID(name: PX509_NAME; nid: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_get_index_by_NID'; + +function X509_NAME_get_index_by_OBJ(name: PX509_NAME; obj: PASN1_OBJECT; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_get_index_by_OBJ'; + +function X509_NAME_get_entry(name: PX509_NAME; loc: Integer): PX509_NAME_ENTRY; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_get_entry'; + +function X509_NAME_delete_entry(name: PX509_NAME; loc: Integer): PX509_NAME_ENTRY; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_delete_entry'; + +function X509_NAME_add_entry(name: PX509_NAME; ne: PX509_NAME_ENTRY; loc: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&set{$ELSE}set1{$IFEND}{$ELSE}&set{$ENDIF}: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_add_entry'; + +function X509_NAME_add_entry_by_OBJ(name: PX509_NAME; obj: PASN1_OBJECT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: PAnsiChar; len: Integer; loc: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&set{$ELSE}set1{$IFEND}{$ELSE}&set{$ENDIF}: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_add_entry_by_OBJ'; + +function X509_NAME_add_entry_by_NID(name: PX509_NAME; nid: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: PAnsiChar; len: Integer; loc: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&set{$ELSE}set1{$IFEND}{$ELSE}&set{$ENDIF}: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_add_entry_by_NID'; + +function X509_NAME_ENTRY_create_by_txt(ne: PPX509_NAME_ENTRY; field: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: PAnsiChar; len: Integer): PX509_NAME_ENTRY; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_ENTRY_create_by_txt'; + +function X509_NAME_ENTRY_create_by_NID(ne: PPX509_NAME_ENTRY; nid: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: PAnsiChar; len: Integer): PX509_NAME_ENTRY; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_ENTRY_create_by_NID'; + +function X509_NAME_add_entry_by_txt(name: PX509_NAME; field: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: PAnsiChar; len: Integer; loc: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&set{$ELSE}set1{$IFEND}{$ELSE}&set{$ENDIF}: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_add_entry_by_txt'; + +function X509_NAME_ENTRY_create_by_OBJ(ne: PPX509_NAME_ENTRY; obj: PASN1_OBJECT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: PAnsiChar; len: Integer): PX509_NAME_ENTRY; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_ENTRY_create_by_OBJ'; + +function X509_NAME_ENTRY_set_object(ne: PX509_NAME_ENTRY; obj: PASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_ENTRY_set_object'; + +function X509_NAME_ENTRY_set_data(ne: PX509_NAME_ENTRY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: PAnsiChar; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_ENTRY_set_data'; + +function X509_NAME_ENTRY_get_object(ne: PX509_NAME_ENTRY): PASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_ENTRY_get_object'; + +function X509_NAME_ENTRY_get_data(ne: PX509_NAME_ENTRY): PASN1_STRING; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_ENTRY_get_data'; + +function X509_NAME_ENTRY_set(ne: PX509_NAME_ENTRY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_ENTRY_set'; + +function X509_NAME_get0_der(nm: PX509_NAME; pder: PPByte; pderlen: PNativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_NAME_get0_der'; + +function X509v3_get_ext_count(x: Pstack_st_X509_EXTENSION): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_get_ext_count'; + +function X509v3_get_ext_by_NID(x: Pstack_st_X509_EXTENSION; nid: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_get_ext_by_NID'; + +function X509v3_get_ext_by_OBJ(x: Pstack_st_X509_EXTENSION; obj: PASN1_OBJECT; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_get_ext_by_OBJ'; + +function X509v3_get_ext_by_critical(x: Pstack_st_X509_EXTENSION; crit: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_get_ext_by_critical'; + +function X509v3_get_ext(x: Pstack_st_X509_EXTENSION; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_get_ext'; + +function X509v3_delete_ext(x: Pstack_st_X509_EXTENSION; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_delete_ext'; + +function X509v3_add_ext(x: PPstack_st_X509_EXTENSION; ex: PX509_EXTENSION; loc: Integer): Pstack_st_X509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_add_ext'; + +function X509_get_ext_count(x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_ext_count'; + +function X509_get_ext_by_NID(x: PX509; nid: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_ext_by_NID'; + +function X509_get_ext_by_OBJ(x: PX509; obj: PASN1_OBJECT; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_ext_by_OBJ'; + +function X509_get_ext_by_critical(x: PX509; crit: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_ext_by_critical'; + +function X509_get_ext(x: PX509; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_ext'; + +function X509_delete_ext(x: PX509; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509_delete_ext'; + +function X509_add_ext(x: PX509; ex: PX509_EXTENSION; loc: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_add_ext'; + +function X509_get_ext_d2i(x: PX509; nid: Integer; crit: PInteger; idx: PInteger): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_ext_d2i'; + +function X509_add1_ext_i2d(x: PX509; nid: Integer; value: Pointer; crit: Integer; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_add1_ext_i2d'; + +function X509_CRL_get_ext_count(x: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get_ext_count'; + +function X509_CRL_get_ext_by_NID(x: PX509_CRL; nid: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get_ext_by_NID'; + +function X509_CRL_get_ext_by_OBJ(x: PX509_CRL; obj: PASN1_OBJECT; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get_ext_by_OBJ'; + +function X509_CRL_get_ext_by_critical(x: PX509_CRL; crit: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get_ext_by_critical'; + +function X509_CRL_get_ext(x: PX509_CRL; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get_ext'; + +function X509_CRL_delete_ext(x: PX509_CRL; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_delete_ext'; + +function X509_CRL_add_ext(x: PX509_CRL; ex: PX509_EXTENSION; loc: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_add_ext'; + +function X509_CRL_get_ext_d2i(x: PX509_CRL; nid: Integer; crit: PInteger; idx: PInteger): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_get_ext_d2i'; + +function X509_CRL_add1_ext_i2d(x: PX509_CRL; nid: Integer; value: Pointer; crit: Integer; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_CRL_add1_ext_i2d'; + +function X509_REVOKED_get_ext_count(x: PX509_REVOKED): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REVOKED_get_ext_count'; + +function X509_REVOKED_get_ext_by_NID(x: PX509_REVOKED; nid: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REVOKED_get_ext_by_NID'; + +function X509_REVOKED_get_ext_by_OBJ(x: PX509_REVOKED; obj: PASN1_OBJECT; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REVOKED_get_ext_by_OBJ'; + +function X509_REVOKED_get_ext_by_critical(x: PX509_REVOKED; crit: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REVOKED_get_ext_by_critical'; + +function X509_REVOKED_get_ext(x: PX509_REVOKED; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509_REVOKED_get_ext'; + +function X509_REVOKED_delete_ext(x: PX509_REVOKED; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509_REVOKED_delete_ext'; + +function X509_REVOKED_add_ext(x: PX509_REVOKED; ex: PX509_EXTENSION; loc: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REVOKED_add_ext'; + +function X509_REVOKED_get_ext_d2i(x: PX509_REVOKED; nid: Integer; crit: PInteger; idx: PInteger): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REVOKED_get_ext_d2i'; + +function X509_REVOKED_add1_ext_i2d(x: PX509_REVOKED; nid: Integer; value: Pointer; crit: Integer; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_REVOKED_add1_ext_i2d'; + +function X509_EXTENSION_create_by_NID(ex: PPX509_EXTENSION; nid: Integer; crit: Integer; data: PASN1_OCTET_STRING): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509_EXTENSION_create_by_NID'; + +function X509_EXTENSION_create_by_OBJ(ex: PPX509_EXTENSION; obj: PASN1_OBJECT; crit: Integer; data: PASN1_OCTET_STRING): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509_EXTENSION_create_by_OBJ'; + +function X509_EXTENSION_set_object(ex: PX509_EXTENSION; obj: PASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_EXTENSION_set_object'; + +function X509_EXTENSION_set_critical(ex: PX509_EXTENSION; crit: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_EXTENSION_set_critical'; + +function X509_EXTENSION_set_data(ex: PX509_EXTENSION; data: PASN1_OCTET_STRING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_EXTENSION_set_data'; + +function X509_EXTENSION_get_object(ex: PX509_EXTENSION): PASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'X509_EXTENSION_get_object'; + +function X509_EXTENSION_get_data(ne: PX509_EXTENSION): PASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 'X509_EXTENSION_get_data'; + +function X509_EXTENSION_get_critical(ex: PX509_EXTENSION): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_EXTENSION_get_critical'; + +function X509at_get_attr_count(x: Pstack_st_X509_ATTRIBUTE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509at_get_attr_count'; + +function X509at_get_attr_by_NID(x: Pstack_st_X509_ATTRIBUTE; nid: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509at_get_attr_by_NID'; + +function X509at_get_attr_by_OBJ(sk: Pstack_st_X509_ATTRIBUTE; obj: PASN1_OBJECT; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509at_get_attr_by_OBJ'; + +function X509at_get_attr(x: Pstack_st_X509_ATTRIBUTE; loc: Integer): PX509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'X509at_get_attr'; + +function X509at_delete_attr(x: Pstack_st_X509_ATTRIBUTE; loc: Integer): PX509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'X509at_delete_attr'; + +function X509at_add1_attr(x: PPstack_st_X509_ATTRIBUTE; attr: PX509_ATTRIBUTE): Pstack_st_X509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'X509at_add1_attr'; + +function X509at_add1_attr_by_OBJ(x: PPstack_st_X509_ATTRIBUTE; obj: PASN1_OBJECT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: PByte; len: Integer): Pstack_st_X509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'X509at_add1_attr_by_OBJ'; + +function X509at_add1_attr_by_NID(x: PPstack_st_X509_ATTRIBUTE; nid: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: PByte; len: Integer): Pstack_st_X509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'X509at_add1_attr_by_NID'; + +function X509at_add1_attr_by_txt(x: PPstack_st_X509_ATTRIBUTE; attrname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: PByte; len: Integer): Pstack_st_X509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'X509at_add1_attr_by_txt'; + +function X509at_get0_data_by_OBJ(x: Pstack_st_X509_ATTRIBUTE; obj: PASN1_OBJECT; lastpos: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'X509at_get0_data_by_OBJ'; + +function X509_ATTRIBUTE_create_by_NID(attr: PPX509_ATTRIBUTE; nid: Integer; atrtype: Integer; data: Pointer; len: Integer): PX509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'X509_ATTRIBUTE_create_by_NID'; + +function X509_ATTRIBUTE_create_by_OBJ(attr: PPX509_ATTRIBUTE; obj: PASN1_OBJECT; atrtype: Integer; data: Pointer; len: Integer): PX509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'X509_ATTRIBUTE_create_by_OBJ'; + +function X509_ATTRIBUTE_create_by_txt(attr: PPX509_ATTRIBUTE; atrname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: PByte; len: Integer): PX509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'X509_ATTRIBUTE_create_by_txt'; + +function X509_ATTRIBUTE_set1_object(attr: PX509_ATTRIBUTE; obj: PASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_ATTRIBUTE_set1_object'; + +function X509_ATTRIBUTE_set1_data(attr: PX509_ATTRIBUTE; attrtype: Integer; data: Pointer; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_ATTRIBUTE_set1_data'; + +function X509_ATTRIBUTE_get0_data(attr: PX509_ATTRIBUTE; idx: Integer; atrtype: Integer; data: Pointer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'X509_ATTRIBUTE_get0_data'; + +function X509_ATTRIBUTE_count(attr: PX509_ATTRIBUTE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_ATTRIBUTE_count'; + +function X509_ATTRIBUTE_get0_object(attr: PX509_ATTRIBUTE): PASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'X509_ATTRIBUTE_get0_object'; + +function X509_ATTRIBUTE_get0_type(attr: PX509_ATTRIBUTE; idx: Integer): PASN1_TYPE; cdecl; + external LIB_CRYPTO name _PU + 'X509_ATTRIBUTE_get0_type'; + +function EVP_PKEY_get_attr_count(key: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get_attr_count'; + +function EVP_PKEY_get_attr_by_NID(key: PEVP_PKEY; nid: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get_attr_by_NID'; + +function EVP_PKEY_get_attr_by_OBJ(key: PEVP_PKEY; obj: PASN1_OBJECT; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get_attr_by_OBJ'; + +function EVP_PKEY_get_attr(key: PEVP_PKEY; loc: Integer): PX509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_get_attr'; + +function EVP_PKEY_delete_attr(key: PEVP_PKEY; loc: Integer): PX509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_delete_attr'; + +function EVP_PKEY_add1_attr(key: PEVP_PKEY; attr: PX509_ATTRIBUTE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_add1_attr'; + +function EVP_PKEY_add1_attr_by_OBJ(key: PEVP_PKEY; obj: PASN1_OBJECT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: PByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_add1_attr_by_OBJ'; + +function EVP_PKEY_add1_attr_by_NID(key: PEVP_PKEY; nid: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: PByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_add1_attr_by_NID'; + +function EVP_PKEY_add1_attr_by_txt(key: PEVP_PKEY; attrname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: PByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY_add1_attr_by_txt'; + +function X509_verify_cert(ctx: PX509_STORE_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_verify_cert'; + +function X509_find_by_issuer_and_serial(sk: Pstack_st_X509; name: PX509_NAME; serial: PASN1_INTEGER): PX509; cdecl; + external LIB_CRYPTO name _PU + 'X509_find_by_issuer_and_serial'; + +function X509_find_by_subject(sk: Pstack_st_X509; name: PX509_NAME): PX509; cdecl; + external LIB_CRYPTO name _PU + 'X509_find_by_subject'; + +function PBEPARAM_new(): PPBEPARAM; cdecl; + external LIB_CRYPTO name _PU + 'PBEPARAM_new'; + +procedure PBEPARAM_free(a: PPBEPARAM); cdecl; + external LIB_CRYPTO name _PU + 'PBEPARAM_free'; + +function d2i_PBEPARAM(a: PPPBEPARAM; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPBEPARAM; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PBEPARAM'; + +function i2d_PBEPARAM(a: PPBEPARAM; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PBEPARAM'; + +function PBEPARAM_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PBEPARAM_it'; + +function PBE2PARAM_new(): PPBE2PARAM; cdecl; + external LIB_CRYPTO name _PU + 'PBE2PARAM_new'; + +procedure PBE2PARAM_free(a: PPBE2PARAM); cdecl; + external LIB_CRYPTO name _PU + 'PBE2PARAM_free'; + +function d2i_PBE2PARAM(a: PPPBE2PARAM; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPBE2PARAM; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PBE2PARAM'; + +function i2d_PBE2PARAM(a: PPBE2PARAM; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PBE2PARAM'; + +function PBE2PARAM_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PBE2PARAM_it'; + +function PBKDF2PARAM_new(): PPBKDF2PARAM; cdecl; + external LIB_CRYPTO name _PU + 'PBKDF2PARAM_new'; + +procedure PBKDF2PARAM_free(a: PPBKDF2PARAM); cdecl; + external LIB_CRYPTO name _PU + 'PBKDF2PARAM_free'; + +function d2i_PBKDF2PARAM(a: PPPBKDF2PARAM; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPBKDF2PARAM; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PBKDF2PARAM'; + +function i2d_PBKDF2PARAM(a: PPBKDF2PARAM; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PBKDF2PARAM'; + +function PBKDF2PARAM_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PBKDF2PARAM_it'; + +function SCRYPT_PARAMS_new(): PSCRYPT_PARAMS; cdecl; + external LIB_CRYPTO name _PU + 'SCRYPT_PARAMS_new'; + +procedure SCRYPT_PARAMS_free(a: PSCRYPT_PARAMS); cdecl; + external LIB_CRYPTO name _PU + 'SCRYPT_PARAMS_free'; + +function d2i_SCRYPT_PARAMS(a: PPSCRYPT_PARAMS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PSCRYPT_PARAMS; cdecl; + external LIB_CRYPTO name _PU + 'd2i_SCRYPT_PARAMS'; + +function i2d_SCRYPT_PARAMS(a: PSCRYPT_PARAMS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_SCRYPT_PARAMS'; + +function SCRYPT_PARAMS_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'SCRYPT_PARAMS_it'; + +function PKCS5_pbe_set0_algor(algor: PX509_ALGOR; alg: Integer; iter: Integer; salt: PByte; saltlen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS5_pbe_set0_algor'; + +function PKCS5_pbe_set(alg: Integer; iter: Integer; salt: PByte; saltlen: Integer): PX509_ALGOR; cdecl; + external LIB_CRYPTO name _PU + 'PKCS5_pbe_set'; + +function PKCS5_pbe2_set(cipher: PEVP_CIPHER; iter: Integer; salt: PByte; saltlen: Integer): PX509_ALGOR; cdecl; + external LIB_CRYPTO name _PU + 'PKCS5_pbe2_set'; + +function PKCS5_pbe2_set_iv(cipher: PEVP_CIPHER; iter: Integer; salt: PByte; saltlen: Integer; aiv: PByte; prf_nid: Integer): PX509_ALGOR; cdecl; + external LIB_CRYPTO name _PU + 'PKCS5_pbe2_set_iv'; + +function PKCS5_pbe2_set_scrypt(cipher: PEVP_CIPHER; salt: PByte; saltlen: Integer; aiv: PByte; N: UInt64; r: UInt64; p: UInt64): PX509_ALGOR; cdecl; + external LIB_CRYPTO name _PU + 'PKCS5_pbe2_set_scrypt'; + +function PKCS5_pbkdf2_set(iter: Integer; salt: PByte; saltlen: Integer; prf_nid: Integer; keylen: Integer): PX509_ALGOR; cdecl; + external LIB_CRYPTO name _PU + 'PKCS5_pbkdf2_set'; + +function PKCS8_PRIV_KEY_INFO_new(): PPKCS8_PRIV_KEY_INFO; cdecl; + external LIB_CRYPTO name _PU + 'PKCS8_PRIV_KEY_INFO_new'; + +procedure PKCS8_PRIV_KEY_INFO_free(a: PPKCS8_PRIV_KEY_INFO); cdecl; + external LIB_CRYPTO name _PU + 'PKCS8_PRIV_KEY_INFO_free'; + +function d2i_PKCS8_PRIV_KEY_INFO(a: PPPKCS8_PRIV_KEY_INFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPKCS8_PRIV_KEY_INFO; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS8_PRIV_KEY_INFO'; + +function i2d_PKCS8_PRIV_KEY_INFO(a: PPKCS8_PRIV_KEY_INFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS8_PRIV_KEY_INFO'; + +function PKCS8_PRIV_KEY_INFO_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS8_PRIV_KEY_INFO_it'; + +function EVP_PKCS82PKEY(p8: PPKCS8_PRIV_KEY_INFO): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKCS82PKEY'; + +function EVP_PKEY2PKCS8(pkey: PEVP_PKEY): PPKCS8_PRIV_KEY_INFO; cdecl; + external LIB_CRYPTO name _PU + 'EVP_PKEY2PKCS8'; + +function PKCS8_pkey_set0(priv: PPKCS8_PRIV_KEY_INFO; aobj: PASN1_OBJECT; version: Integer; ptype: Integer; pval: Pointer; penc: PByte; penclen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS8_pkey_set0'; + +function PKCS8_pkey_get0(ppkalg: PPASN1_OBJECT; pk: PPByte; ppklen: PInteger; pa: PPX509_ALGOR; p8: PPKCS8_PRIV_KEY_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS8_pkey_get0'; + +function PKCS8_pkey_get0_attrs(p8: PPKCS8_PRIV_KEY_INFO): Pstack_st_X509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'PKCS8_pkey_get0_attrs'; + +function PKCS8_pkey_add1_attr_by_NID(p8: PPKCS8_PRIV_KEY_INFO; nid: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: PByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS8_pkey_add1_attr_by_NID'; + +function X509_PUBKEY_set0_param(pub: PX509_PUBKEY; aobj: PASN1_OBJECT; ptype: Integer; pval: Pointer; penc: PByte; penclen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_PUBKEY_set0_param'; + +function X509_PUBKEY_get0_param(ppkalg: PPASN1_OBJECT; pk: PPByte; ppklen: PInteger; pa: PPX509_ALGOR; pub: PX509_PUBKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_PUBKEY_get0_param'; + +function X509_check_trust(x: PX509; id: Integer; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_check_trust'; + +function X509_TRUST_get_count(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_TRUST_get_count'; + +function X509_TRUST_get0(idx: Integer): PX509_TRUST; cdecl; + external LIB_CRYPTO name _PU + 'X509_TRUST_get0'; + +function X509_TRUST_get_by_id(id: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_TRUST_get_by_id'; + +type + X509_TRUST_add_ck = function(p1: PX509_TRUST; p2: PX509; p3: Integer): Integer; cdecl; + +function X509_TRUST_add(id: Integer; flags: Integer; ck: X509_TRUST_add_ck; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; arg1: Integer; arg2: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_TRUST_add'; + +procedure X509_TRUST_cleanup(); cdecl; + external LIB_CRYPTO name _PU + 'X509_TRUST_cleanup'; + +function X509_TRUST_get_flags(xp: PX509_TRUST): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_TRUST_get_flags'; + +function X509_TRUST_get0_name(xp: PX509_TRUST): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'X509_TRUST_get0_name'; + +function X509_TRUST_get_trust(xp: PX509_TRUST): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_TRUST_get_trust'; + +function ERR_load_CONF_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_CONF_strings'; + +function CONF_set_default_method(meth: PCONF_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CONF_set_default_method'; + +procedure CONF_set_nconf(conf: PCONF; hash: Plhash_st_CONF_VALUE); cdecl; + external LIB_CRYPTO name _PU + 'CONF_set_nconf'; + +function CONF_load(conf: Plhash_st_CONF_VALUE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; eline: PInteger): Plhash_st_CONF_VALUE; cdecl; + external LIB_CRYPTO name _PU + 'CONF_load'; + +function CONF_load_fp(conf: Plhash_st_CONF_VALUE; fp: PPointer; eline: PInteger): Plhash_st_CONF_VALUE; cdecl; + external LIB_CRYPTO name _PU + 'CONF_load_fp'; + +function CONF_load_bio(conf: Plhash_st_CONF_VALUE; bp: PBIO; eline: PInteger): Plhash_st_CONF_VALUE; cdecl; + external LIB_CRYPTO name _PU + 'CONF_load_bio'; + +function CONF_get_section(conf: Plhash_st_CONF_VALUE; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Pstack_st_CONF_VALUE; cdecl; + external LIB_CRYPTO name _PU + 'CONF_get_section'; + +function CONF_get_string(conf: Plhash_st_CONF_VALUE; group: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'CONF_get_string'; + +function CONF_get_number(conf: Plhash_st_CONF_VALUE; group: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CONF_get_number'; + +procedure CONF_free(conf: Plhash_st_CONF_VALUE); cdecl; + external LIB_CRYPTO name _PU + 'CONF_free'; + +function CONF_dump_fp(conf: Plhash_st_CONF_VALUE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CONF_dump_fp'; + +function CONF_dump_bio(conf: Plhash_st_CONF_VALUE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CONF_dump_bio'; + +procedure OPENSSL_config(config_name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_config'; + +function NCONF_new(meth: PCONF_METHOD): PCONF; cdecl; + external LIB_CRYPTO name _PU + 'NCONF_new'; + +function NCONF_default(): PCONF_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'NCONF_default'; + +function NCONF_WIN32(): PCONF_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'NCONF_WIN32'; + +procedure NCONF_free(conf: PCONF); cdecl; + external LIB_CRYPTO name _PU + 'NCONF_free'; + +procedure NCONF_free_data(conf: PCONF); cdecl; + external LIB_CRYPTO name _PU + 'NCONF_free_data'; + +function NCONF_load(conf: PCONF; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; eline: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'NCONF_load'; + +function NCONF_load_fp(conf: PCONF; fp: PPointer; eline: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'NCONF_load_fp'; + +function NCONF_load_bio(conf: PCONF; bp: PBIO; eline: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'NCONF_load_bio'; + +function NCONF_get_section(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Pstack_st_CONF_VALUE; cdecl; + external LIB_CRYPTO name _PU + 'NCONF_get_section'; + +function NCONF_get_string(conf: PCONF; group: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'NCONF_get_string'; + +function NCONF_get_number_e(conf: PCONF; group: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; result: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'NCONF_get_number_e'; + +function NCONF_dump_fp(conf: PCONF; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'NCONF_dump_fp'; + +function NCONF_dump_bio(conf: PCONF; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'NCONF_dump_bio'; + +function CONF_modules_load(cnf: PCONF; appname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CONF_modules_load'; + +function CONF_modules_load_file(filename: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; appname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CONF_modules_load_file'; + +procedure CONF_modules_unload(all: Integer); cdecl; + external LIB_CRYPTO name _PU + 'CONF_modules_unload'; + +procedure CONF_modules_finish(); cdecl; + external LIB_CRYPTO name _PU + 'CONF_modules_finish'; + +function CONF_module_add(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ifunc: Pconf_init_func; ffunc: Pconf_finish_func): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CONF_module_add'; + +function CONF_imodule_get_name(md: PCONF_IMODULE): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'CONF_imodule_get_name'; + +function CONF_imodule_get_value(md: PCONF_IMODULE): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'CONF_imodule_get_value'; + +function CONF_imodule_get_usr_data(md: PCONF_IMODULE): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'CONF_imodule_get_usr_data'; + +procedure CONF_imodule_set_usr_data(md: PCONF_IMODULE; usr_data: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'CONF_imodule_set_usr_data'; + +function CONF_imodule_get_module(md: PCONF_IMODULE): PCONF_MODULE; cdecl; + external LIB_CRYPTO name _PU + 'CONF_imodule_get_module'; + +function CONF_imodule_get_flags(md: PCONF_IMODULE): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'CONF_imodule_get_flags'; + +procedure CONF_imodule_set_flags(md: PCONF_IMODULE; flags: Cardinal); cdecl; + external LIB_CRYPTO name _PU + 'CONF_imodule_set_flags'; + +function CONF_module_get_usr_data(pmod: PCONF_MODULE): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'CONF_module_get_usr_data'; + +procedure CONF_module_set_usr_data(pmod: PCONF_MODULE; usr_data: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'CONF_module_set_usr_data'; + +function CONF_get1_default_config_file(): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'CONF_get1_default_config_file'; + +type + CONF_parse_list_list_cb = function(elem: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: Integer; usr: Pointer): Integer; cdecl; + +function CONF_parse_list(list: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; sep: Integer; nospc: Integer; list_cb: CONF_parse_list_list_cb; arg: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CONF_parse_list'; + +procedure OPENSSL_load_builtin_modules(); cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_load_builtin_modules'; + +function ERR_load_X509V3_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_X509V3_strings'; + +function PROXY_POLICY_new(): PPROXY_POLICY; cdecl; + external LIB_CRYPTO name _PU + 'PROXY_POLICY_new'; + +procedure PROXY_POLICY_free(a: PPROXY_POLICY); cdecl; + external LIB_CRYPTO name _PU + 'PROXY_POLICY_free'; + +function d2i_PROXY_POLICY(a: PPPROXY_POLICY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPROXY_POLICY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PROXY_POLICY'; + +function i2d_PROXY_POLICY(a: PPROXY_POLICY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PROXY_POLICY'; + +function PROXY_POLICY_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PROXY_POLICY_it'; + +function PROXY_CERT_INFO_EXTENSION_new(): PPROXY_CERT_INFO_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'PROXY_CERT_INFO_EXTENSION_new'; + +procedure PROXY_CERT_INFO_EXTENSION_free(a: PPROXY_CERT_INFO_EXTENSION); cdecl; + external LIB_CRYPTO name _PU + 'PROXY_CERT_INFO_EXTENSION_free'; + +function d2i_PROXY_CERT_INFO_EXTENSION(a: PPPROXY_CERT_INFO_EXTENSION; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPROXY_CERT_INFO_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PROXY_CERT_INFO_EXTENSION'; + +function i2d_PROXY_CERT_INFO_EXTENSION(a: PPROXY_CERT_INFO_EXTENSION; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PROXY_CERT_INFO_EXTENSION'; + +function PROXY_CERT_INFO_EXTENSION_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PROXY_CERT_INFO_EXTENSION_it'; + +function BASIC_CONSTRAINTS_new(): PBASIC_CONSTRAINTS; cdecl; + external LIB_CRYPTO name _PU + 'BASIC_CONSTRAINTS_new'; + +procedure BASIC_CONSTRAINTS_free(a: PBASIC_CONSTRAINTS); cdecl; + external LIB_CRYPTO name _PU + 'BASIC_CONSTRAINTS_free'; + +function d2i_BASIC_CONSTRAINTS(a: PPBASIC_CONSTRAINTS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PBASIC_CONSTRAINTS; cdecl; + external LIB_CRYPTO name _PU + 'd2i_BASIC_CONSTRAINTS'; + +function i2d_BASIC_CONSTRAINTS(a: PBASIC_CONSTRAINTS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_BASIC_CONSTRAINTS'; + +function BASIC_CONSTRAINTS_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'BASIC_CONSTRAINTS_it'; + +function SXNET_new(): PSXNET; cdecl; + external LIB_CRYPTO name _PU + 'SXNET_new'; + +procedure SXNET_free(a: PSXNET); cdecl; + external LIB_CRYPTO name _PU + 'SXNET_free'; + +function d2i_SXNET(a: PPSXNET; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PSXNET; cdecl; + external LIB_CRYPTO name _PU + 'd2i_SXNET'; + +function i2d_SXNET(a: PSXNET; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_SXNET'; + +function SXNET_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'SXNET_it'; + +function SXNETID_new(): PSXNETID; cdecl; + external LIB_CRYPTO name _PU + 'SXNETID_new'; + +procedure SXNETID_free(a: PSXNETID); cdecl; + external LIB_CRYPTO name _PU + 'SXNETID_free'; + +function d2i_SXNETID(a: PPSXNETID; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PSXNETID; cdecl; + external LIB_CRYPTO name _PU + 'd2i_SXNETID'; + +function i2d_SXNETID(a: PSXNETID; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_SXNETID'; + +function SXNETID_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'SXNETID_it'; + +function SXNET_add_id_asc(psx: PPSXNET; zone: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; user: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; userlen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SXNET_add_id_asc'; + +function SXNET_add_id_ulong(psx: PPSXNET; lzone: Cardinal; user: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; userlen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SXNET_add_id_ulong'; + +function SXNET_add_id_INTEGER(psx: PPSXNET; izone: PASN1_INTEGER; user: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; userlen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SXNET_add_id_INTEGER'; + +function SXNET_get_id_asc(sx: PSXNET; zone: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 'SXNET_get_id_asc'; + +function SXNET_get_id_ulong(sx: PSXNET; lzone: Cardinal): PASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 'SXNET_get_id_ulong'; + +function SXNET_get_id_INTEGER(sx: PSXNET; zone: PASN1_INTEGER): PASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 'SXNET_get_id_INTEGER'; + +function AUTHORITY_KEYID_new(): PAUTHORITY_KEYID; cdecl; + external LIB_CRYPTO name _PU + 'AUTHORITY_KEYID_new'; + +procedure AUTHORITY_KEYID_free(a: PAUTHORITY_KEYID); cdecl; + external LIB_CRYPTO name _PU + 'AUTHORITY_KEYID_free'; + +function d2i_AUTHORITY_KEYID(a: PPAUTHORITY_KEYID; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PAUTHORITY_KEYID; cdecl; + external LIB_CRYPTO name _PU + 'd2i_AUTHORITY_KEYID'; + +function i2d_AUTHORITY_KEYID(a: PAUTHORITY_KEYID; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_AUTHORITY_KEYID'; + +function AUTHORITY_KEYID_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'AUTHORITY_KEYID_it'; + +function PKEY_USAGE_PERIOD_new(): PPKEY_USAGE_PERIOD; cdecl; + external LIB_CRYPTO name _PU + 'PKEY_USAGE_PERIOD_new'; + +procedure PKEY_USAGE_PERIOD_free(a: PPKEY_USAGE_PERIOD); cdecl; + external LIB_CRYPTO name _PU + 'PKEY_USAGE_PERIOD_free'; + +function d2i_PKEY_USAGE_PERIOD(a: PPPKEY_USAGE_PERIOD; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPKEY_USAGE_PERIOD; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKEY_USAGE_PERIOD'; + +function i2d_PKEY_USAGE_PERIOD(a: PPKEY_USAGE_PERIOD; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKEY_USAGE_PERIOD'; + +function PKEY_USAGE_PERIOD_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKEY_USAGE_PERIOD_it'; + +function GENERAL_NAME_new(): PGENERAL_NAME; cdecl; + external LIB_CRYPTO name _PU + 'GENERAL_NAME_new'; + +procedure GENERAL_NAME_free(a: PGENERAL_NAME); cdecl; + external LIB_CRYPTO name _PU + 'GENERAL_NAME_free'; + +function d2i_GENERAL_NAME(a: PPGENERAL_NAME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PGENERAL_NAME; cdecl; + external LIB_CRYPTO name _PU + 'd2i_GENERAL_NAME'; + +function i2d_GENERAL_NAME(a: PGENERAL_NAME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_GENERAL_NAME'; + +function GENERAL_NAME_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'GENERAL_NAME_it'; + +function GENERAL_NAME_dup(a: PGENERAL_NAME): PGENERAL_NAME; cdecl; + external LIB_CRYPTO name _PU + 'GENERAL_NAME_dup'; + +function GENERAL_NAME_cmp(a: PGENERAL_NAME; b: PGENERAL_NAME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'GENERAL_NAME_cmp'; + +function v2i_ASN1_BIT_STRING(method: PX509V3_EXT_METHOD; ctx: PX509V3_CTX; nval: Pstack_st_CONF_VALUE): PASN1_BIT_STRING; cdecl; + external LIB_CRYPTO name _PU + 'v2i_ASN1_BIT_STRING'; + +function i2v_ASN1_BIT_STRING(method: PX509V3_EXT_METHOD; bits: PASN1_BIT_STRING; extlist: Pstack_st_CONF_VALUE): Pstack_st_CONF_VALUE; cdecl; + external LIB_CRYPTO name _PU + 'i2v_ASN1_BIT_STRING'; + +function i2s_ASN1_IA5STRING(method: PX509V3_EXT_METHOD; ia5: PASN1_IA5STRING): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'i2s_ASN1_IA5STRING'; + +function s2i_ASN1_IA5STRING(method: PX509V3_EXT_METHOD; ctx: PX509V3_CTX; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PASN1_IA5STRING; cdecl; + external LIB_CRYPTO name _PU + 's2i_ASN1_IA5STRING'; + +function i2v_GENERAL_NAME(method: PX509V3_EXT_METHOD; gen: PGENERAL_NAME; ret: Pstack_st_CONF_VALUE): Pstack_st_CONF_VALUE; cdecl; + external LIB_CRYPTO name _PU + 'i2v_GENERAL_NAME'; + +function GENERAL_NAME_print({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; gen: PGENERAL_NAME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'GENERAL_NAME_print'; + +function GENERAL_NAMES_new(): PGENERAL_NAMES; cdecl; + external LIB_CRYPTO name _PU + 'GENERAL_NAMES_new'; + +procedure GENERAL_NAMES_free(a: PGENERAL_NAMES); cdecl; + external LIB_CRYPTO name _PU + 'GENERAL_NAMES_free'; + +function d2i_GENERAL_NAMES(a: PPGENERAL_NAMES; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PGENERAL_NAMES; cdecl; + external LIB_CRYPTO name _PU + 'd2i_GENERAL_NAMES'; + +function i2d_GENERAL_NAMES(a: PGENERAL_NAMES; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_GENERAL_NAMES'; + +function GENERAL_NAMES_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'GENERAL_NAMES_it'; + +function i2v_GENERAL_NAMES(method: PX509V3_EXT_METHOD; gen: PGENERAL_NAMES; extlist: Pstack_st_CONF_VALUE): Pstack_st_CONF_VALUE; cdecl; + external LIB_CRYPTO name _PU + 'i2v_GENERAL_NAMES'; + +function v2i_GENERAL_NAMES(method: PX509V3_EXT_METHOD; ctx: PX509V3_CTX; nval: Pstack_st_CONF_VALUE): PGENERAL_NAMES; cdecl; + external LIB_CRYPTO name _PU + 'v2i_GENERAL_NAMES'; + +function OTHERNAME_new(): POTHERNAME; cdecl; + external LIB_CRYPTO name _PU + 'OTHERNAME_new'; + +procedure OTHERNAME_free(a: POTHERNAME); cdecl; + external LIB_CRYPTO name _PU + 'OTHERNAME_free'; + +function d2i_OTHERNAME(a: PPOTHERNAME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): POTHERNAME; cdecl; + external LIB_CRYPTO name _PU + 'd2i_OTHERNAME'; + +function i2d_OTHERNAME(a: POTHERNAME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_OTHERNAME'; + +function OTHERNAME_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'OTHERNAME_it'; + +function EDIPARTYNAME_new(): PEDIPARTYNAME; cdecl; + external LIB_CRYPTO name _PU + 'EDIPARTYNAME_new'; + +procedure EDIPARTYNAME_free(a: PEDIPARTYNAME); cdecl; + external LIB_CRYPTO name _PU + 'EDIPARTYNAME_free'; + +function d2i_EDIPARTYNAME(a: PPEDIPARTYNAME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PEDIPARTYNAME; cdecl; + external LIB_CRYPTO name _PU + 'd2i_EDIPARTYNAME'; + +function i2d_EDIPARTYNAME(a: PEDIPARTYNAME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_EDIPARTYNAME'; + +function EDIPARTYNAME_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'EDIPARTYNAME_it'; + +function OTHERNAME_cmp(a: POTHERNAME; b: POTHERNAME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OTHERNAME_cmp'; + +procedure GENERAL_NAME_set0_value(a: PGENERAL_NAME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; value: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'GENERAL_NAME_set0_value'; + +function GENERAL_NAME_get0_value(a: PGENERAL_NAME; ptype: PInteger): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'GENERAL_NAME_get0_value'; + +function GENERAL_NAME_set0_othername(gen: PGENERAL_NAME; oid: PASN1_OBJECT; value: PASN1_TYPE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'GENERAL_NAME_set0_othername'; + +function GENERAL_NAME_get0_otherName(gen: PGENERAL_NAME; poid: PPASN1_OBJECT; pvalue: PPASN1_TYPE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'GENERAL_NAME_get0_otherName'; + +function i2s_ASN1_OCTET_STRING(method: PX509V3_EXT_METHOD; ia5: PASN1_OCTET_STRING): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'i2s_ASN1_OCTET_STRING'; + +function s2i_ASN1_OCTET_STRING(method: PX509V3_EXT_METHOD; ctx: PX509V3_CTX; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 's2i_ASN1_OCTET_STRING'; + +function EXTENDED_KEY_USAGE_new(): PEXTENDED_KEY_USAGE; cdecl; + external LIB_CRYPTO name _PU + 'EXTENDED_KEY_USAGE_new'; + +procedure EXTENDED_KEY_USAGE_free(a: PEXTENDED_KEY_USAGE); cdecl; + external LIB_CRYPTO name _PU + 'EXTENDED_KEY_USAGE_free'; + +function d2i_EXTENDED_KEY_USAGE(a: PPEXTENDED_KEY_USAGE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PEXTENDED_KEY_USAGE; cdecl; + external LIB_CRYPTO name _PU + 'd2i_EXTENDED_KEY_USAGE'; + +function i2d_EXTENDED_KEY_USAGE(a: PEXTENDED_KEY_USAGE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_EXTENDED_KEY_USAGE'; + +function EXTENDED_KEY_USAGE_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'EXTENDED_KEY_USAGE_it'; + +function i2a_ACCESS_DESCRIPTION(bp: PBIO; a: PACCESS_DESCRIPTION): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2a_ACCESS_DESCRIPTION'; + +function TLS_FEATURE_new(): PTLS_FEATURE; cdecl; + external LIB_CRYPTO name _PU + 'TLS_FEATURE_new'; + +procedure TLS_FEATURE_free(a: PTLS_FEATURE); cdecl; + external LIB_CRYPTO name _PU + 'TLS_FEATURE_free'; + +function CERTIFICATEPOLICIES_new(): PCERTIFICATEPOLICIES; cdecl; + external LIB_CRYPTO name _PU + 'CERTIFICATEPOLICIES_new'; + +procedure CERTIFICATEPOLICIES_free(a: PCERTIFICATEPOLICIES); cdecl; + external LIB_CRYPTO name _PU + 'CERTIFICATEPOLICIES_free'; + +function d2i_CERTIFICATEPOLICIES(a: PPCERTIFICATEPOLICIES; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PCERTIFICATEPOLICIES; cdecl; + external LIB_CRYPTO name _PU + 'd2i_CERTIFICATEPOLICIES'; + +function i2d_CERTIFICATEPOLICIES(a: PCERTIFICATEPOLICIES; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_CERTIFICATEPOLICIES'; + +function CERTIFICATEPOLICIES_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'CERTIFICATEPOLICIES_it'; + +function POLICYINFO_new(): PPOLICYINFO; cdecl; + external LIB_CRYPTO name _PU + 'POLICYINFO_new'; + +procedure POLICYINFO_free(a: PPOLICYINFO); cdecl; + external LIB_CRYPTO name _PU + 'POLICYINFO_free'; + +function d2i_POLICYINFO(a: PPPOLICYINFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPOLICYINFO; cdecl; + external LIB_CRYPTO name _PU + 'd2i_POLICYINFO'; + +function i2d_POLICYINFO(a: PPOLICYINFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_POLICYINFO'; + +function POLICYINFO_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'POLICYINFO_it'; + +function POLICYQUALINFO_new(): PPOLICYQUALINFO; cdecl; + external LIB_CRYPTO name _PU + 'POLICYQUALINFO_new'; + +procedure POLICYQUALINFO_free(a: PPOLICYQUALINFO); cdecl; + external LIB_CRYPTO name _PU + 'POLICYQUALINFO_free'; + +function d2i_POLICYQUALINFO(a: PPPOLICYQUALINFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPOLICYQUALINFO; cdecl; + external LIB_CRYPTO name _PU + 'd2i_POLICYQUALINFO'; + +function i2d_POLICYQUALINFO(a: PPOLICYQUALINFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_POLICYQUALINFO'; + +function POLICYQUALINFO_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'POLICYQUALINFO_it'; + +function USERNOTICE_new(): PUSERNOTICE; cdecl; + external LIB_CRYPTO name _PU + 'USERNOTICE_new'; + +procedure USERNOTICE_free(a: PUSERNOTICE); cdecl; + external LIB_CRYPTO name _PU + 'USERNOTICE_free'; + +function d2i_USERNOTICE(a: PPUSERNOTICE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PUSERNOTICE; cdecl; + external LIB_CRYPTO name _PU + 'd2i_USERNOTICE'; + +function i2d_USERNOTICE(a: PUSERNOTICE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_USERNOTICE'; + +function USERNOTICE_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'USERNOTICE_it'; + +function NOTICEREF_new(): PNOTICEREF; cdecl; + external LIB_CRYPTO name _PU + 'NOTICEREF_new'; + +procedure NOTICEREF_free(a: PNOTICEREF); cdecl; + external LIB_CRYPTO name _PU + 'NOTICEREF_free'; + +function d2i_NOTICEREF(a: PPNOTICEREF; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PNOTICEREF; cdecl; + external LIB_CRYPTO name _PU + 'd2i_NOTICEREF'; + +function i2d_NOTICEREF(a: PNOTICEREF; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_NOTICEREF'; + +function NOTICEREF_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'NOTICEREF_it'; + +function CRL_DIST_POINTS_new(): PCRL_DIST_POINTS; cdecl; + external LIB_CRYPTO name _PU + 'CRL_DIST_POINTS_new'; + +procedure CRL_DIST_POINTS_free(a: PCRL_DIST_POINTS); cdecl; + external LIB_CRYPTO name _PU + 'CRL_DIST_POINTS_free'; + +function d2i_CRL_DIST_POINTS(a: PPCRL_DIST_POINTS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PCRL_DIST_POINTS; cdecl; + external LIB_CRYPTO name _PU + 'd2i_CRL_DIST_POINTS'; + +function i2d_CRL_DIST_POINTS(a: PCRL_DIST_POINTS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_CRL_DIST_POINTS'; + +function CRL_DIST_POINTS_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'CRL_DIST_POINTS_it'; + +function DIST_POINT_new(): PDIST_POINT; cdecl; + external LIB_CRYPTO name _PU + 'DIST_POINT_new'; + +procedure DIST_POINT_free(a: PDIST_POINT); cdecl; + external LIB_CRYPTO name _PU + 'DIST_POINT_free'; + +function d2i_DIST_POINT(a: PPDIST_POINT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PDIST_POINT; cdecl; + external LIB_CRYPTO name _PU + 'd2i_DIST_POINT'; + +function i2d_DIST_POINT(a: PDIST_POINT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_DIST_POINT'; + +function DIST_POINT_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'DIST_POINT_it'; + +function DIST_POINT_NAME_new(): PDIST_POINT_NAME; cdecl; + external LIB_CRYPTO name _PU + 'DIST_POINT_NAME_new'; + +procedure DIST_POINT_NAME_free(a: PDIST_POINT_NAME); cdecl; + external LIB_CRYPTO name _PU + 'DIST_POINT_NAME_free'; + +function d2i_DIST_POINT_NAME(a: PPDIST_POINT_NAME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PDIST_POINT_NAME; cdecl; + external LIB_CRYPTO name _PU + 'd2i_DIST_POINT_NAME'; + +function i2d_DIST_POINT_NAME(a: PDIST_POINT_NAME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_DIST_POINT_NAME'; + +function DIST_POINT_NAME_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'DIST_POINT_NAME_it'; + +function ISSUING_DIST_POINT_new(): PISSUING_DIST_POINT; cdecl; + external LIB_CRYPTO name _PU + 'ISSUING_DIST_POINT_new'; + +procedure ISSUING_DIST_POINT_free(a: PISSUING_DIST_POINT); cdecl; + external LIB_CRYPTO name _PU + 'ISSUING_DIST_POINT_free'; + +function d2i_ISSUING_DIST_POINT(a: PPISSUING_DIST_POINT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PISSUING_DIST_POINT; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ISSUING_DIST_POINT'; + +function i2d_ISSUING_DIST_POINT(a: PISSUING_DIST_POINT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ISSUING_DIST_POINT'; + +function ISSUING_DIST_POINT_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ISSUING_DIST_POINT_it'; + +function DIST_POINT_set_dpname(dpn: PDIST_POINT_NAME; iname: PX509_NAME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DIST_POINT_set_dpname'; + +function NAME_CONSTRAINTS_check(x: PX509; nc: PNAME_CONSTRAINTS): Integer; cdecl; + external LIB_CRYPTO name _PU + 'NAME_CONSTRAINTS_check'; + +function NAME_CONSTRAINTS_check_CN(x: PX509; nc: PNAME_CONSTRAINTS): Integer; cdecl; + external LIB_CRYPTO name _PU + 'NAME_CONSTRAINTS_check_CN'; + +function ACCESS_DESCRIPTION_new(): PACCESS_DESCRIPTION; cdecl; + external LIB_CRYPTO name _PU + 'ACCESS_DESCRIPTION_new'; + +procedure ACCESS_DESCRIPTION_free(a: PACCESS_DESCRIPTION); cdecl; + external LIB_CRYPTO name _PU + 'ACCESS_DESCRIPTION_free'; + +function d2i_ACCESS_DESCRIPTION(a: PPACCESS_DESCRIPTION; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PACCESS_DESCRIPTION; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ACCESS_DESCRIPTION'; + +function i2d_ACCESS_DESCRIPTION(a: PACCESS_DESCRIPTION; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ACCESS_DESCRIPTION'; + +function ACCESS_DESCRIPTION_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ACCESS_DESCRIPTION_it'; + +function AUTHORITY_INFO_ACCESS_new(): PAUTHORITY_INFO_ACCESS; cdecl; + external LIB_CRYPTO name _PU + 'AUTHORITY_INFO_ACCESS_new'; + +procedure AUTHORITY_INFO_ACCESS_free(a: PAUTHORITY_INFO_ACCESS); cdecl; + external LIB_CRYPTO name _PU + 'AUTHORITY_INFO_ACCESS_free'; + +function d2i_AUTHORITY_INFO_ACCESS(a: PPAUTHORITY_INFO_ACCESS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PAUTHORITY_INFO_ACCESS; cdecl; + external LIB_CRYPTO name _PU + 'd2i_AUTHORITY_INFO_ACCESS'; + +function i2d_AUTHORITY_INFO_ACCESS(a: PAUTHORITY_INFO_ACCESS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_AUTHORITY_INFO_ACCESS'; + +function AUTHORITY_INFO_ACCESS_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'AUTHORITY_INFO_ACCESS_it'; + +function POLICY_MAPPING_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'POLICY_MAPPING_it'; + +function POLICY_MAPPING_new(): PPOLICY_MAPPING; cdecl; + external LIB_CRYPTO name _PU + 'POLICY_MAPPING_new'; + +procedure POLICY_MAPPING_free(a: PPOLICY_MAPPING); cdecl; + external LIB_CRYPTO name _PU + 'POLICY_MAPPING_free'; + +function POLICY_MAPPINGS_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'POLICY_MAPPINGS_it'; + +function GENERAL_SUBTREE_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'GENERAL_SUBTREE_it'; + +function GENERAL_SUBTREE_new(): PGENERAL_SUBTREE; cdecl; + external LIB_CRYPTO name _PU + 'GENERAL_SUBTREE_new'; + +procedure GENERAL_SUBTREE_free(a: PGENERAL_SUBTREE); cdecl; + external LIB_CRYPTO name _PU + 'GENERAL_SUBTREE_free'; + +function NAME_CONSTRAINTS_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'NAME_CONSTRAINTS_it'; + +function NAME_CONSTRAINTS_new(): PNAME_CONSTRAINTS; cdecl; + external LIB_CRYPTO name _PU + 'NAME_CONSTRAINTS_new'; + +procedure NAME_CONSTRAINTS_free(a: PNAME_CONSTRAINTS); cdecl; + external LIB_CRYPTO name _PU + 'NAME_CONSTRAINTS_free'; + +function POLICY_CONSTRAINTS_new(): PPOLICY_CONSTRAINTS; cdecl; + external LIB_CRYPTO name _PU + 'POLICY_CONSTRAINTS_new'; + +procedure POLICY_CONSTRAINTS_free(a: PPOLICY_CONSTRAINTS); cdecl; + external LIB_CRYPTO name _PU + 'POLICY_CONSTRAINTS_free'; + +function POLICY_CONSTRAINTS_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'POLICY_CONSTRAINTS_it'; + +function a2i_GENERAL_NAME({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PGENERAL_NAME; method: PX509V3_EXT_METHOD; ctx: PX509V3_CTX; gen_type: Integer; value: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; is_nc: Integer): PGENERAL_NAME; cdecl; + external LIB_CRYPTO name _PU + 'a2i_GENERAL_NAME'; + +function v2i_GENERAL_NAME(method: PX509V3_EXT_METHOD; ctx: PX509V3_CTX; cnf: PCONF_VALUE): PGENERAL_NAME; cdecl; + external LIB_CRYPTO name _PU + 'v2i_GENERAL_NAME'; + +function v2i_GENERAL_NAME_ex({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PGENERAL_NAME; method: PX509V3_EXT_METHOD; ctx: PX509V3_CTX; cnf: PCONF_VALUE; is_nc: Integer): PGENERAL_NAME; cdecl; + external LIB_CRYPTO name _PU + 'v2i_GENERAL_NAME_ex'; + +procedure X509V3_conf_free(val: PCONF_VALUE); cdecl; + external LIB_CRYPTO name _PU + 'X509V3_conf_free'; + +function X509V3_EXT_nconf_nid(conf: PCONF; ctx: PX509V3_CTX; ext_nid: Integer; value: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_nconf_nid'; + +function X509V3_EXT_nconf(conf: PCONF; ctx: PX509V3_CTX; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; value: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_nconf'; + +function X509V3_EXT_add_nconf_sk(conf: PCONF; ctx: PX509V3_CTX; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; sk: PPstack_st_X509_EXTENSION): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_add_nconf_sk'; + +function X509V3_EXT_add_nconf(conf: PCONF; ctx: PX509V3_CTX; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cert: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_add_nconf'; + +function X509V3_EXT_REQ_add_nconf(conf: PCONF; ctx: PX509V3_CTX; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; req: PX509_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_REQ_add_nconf'; + +function X509V3_EXT_CRL_add_nconf(conf: PCONF; ctx: PX509V3_CTX; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; crl: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_CRL_add_nconf'; + +function X509V3_EXT_conf_nid(conf: Plhash_st_CONF_VALUE; ctx: PX509V3_CTX; ext_nid: Integer; value: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_conf_nid'; + +function X509V3_EXT_conf(conf: Plhash_st_CONF_VALUE; ctx: PX509V3_CTX; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; value: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_conf'; + +function X509V3_EXT_add_conf(conf: Plhash_st_CONF_VALUE; ctx: PX509V3_CTX; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cert: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_add_conf'; + +function X509V3_EXT_REQ_add_conf(conf: Plhash_st_CONF_VALUE; ctx: PX509V3_CTX; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; req: PX509_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_REQ_add_conf'; + +function X509V3_EXT_CRL_add_conf(conf: Plhash_st_CONF_VALUE; ctx: PX509V3_CTX; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; crl: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_CRL_add_conf'; + +function X509V3_add_value_bool_nf(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; asn1_bool: Integer; extlist: PPstack_st_CONF_VALUE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_add_value_bool_nf'; + +function X509V3_get_value_bool(value: PCONF_VALUE; asn1_bool: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_get_value_bool'; + +function X509V3_get_value_int(value: PCONF_VALUE; aint: PPASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_get_value_int'; + +procedure X509V3_set_nconf(ctx: PX509V3_CTX; conf: PCONF); cdecl; + external LIB_CRYPTO name _PU + 'X509V3_set_nconf'; + +procedure X509V3_set_conf_lhash(ctx: PX509V3_CTX; lhash: Plhash_st_CONF_VALUE); cdecl; + external LIB_CRYPTO name _PU + 'X509V3_set_conf_lhash'; + +function X509V3_get_string(ctx: PX509V3_CTX; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_get_string'; + +function X509V3_get_section(ctx: PX509V3_CTX; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Pstack_st_CONF_VALUE; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_get_section'; + +procedure X509V3_string_free(ctx: PX509V3_CTX; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}); cdecl; + external LIB_CRYPTO name _PU + 'X509V3_string_free'; + +procedure X509V3_section_free(ctx: PX509V3_CTX; section: Pstack_st_CONF_VALUE); cdecl; + external LIB_CRYPTO name _PU + 'X509V3_section_free'; + +procedure X509V3_set_ctx(ctx: PX509V3_CTX; issuer: PX509; subject: PX509; req: PX509_REQ; crl: PX509_CRL; flags: Integer); cdecl; + external LIB_CRYPTO name _PU + 'X509V3_set_ctx'; + +function X509V3_add_value(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; value: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; extlist: PPstack_st_CONF_VALUE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_add_value'; + +function X509V3_add_value_uchar(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; value: PByte; extlist: PPstack_st_CONF_VALUE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_add_value_uchar'; + +function X509V3_add_value_bool(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; asn1_bool: Integer; extlist: PPstack_st_CONF_VALUE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_add_value_bool'; + +function X509V3_add_value_int(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; aint: PASN1_INTEGER; extlist: PPstack_st_CONF_VALUE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_add_value_int'; + +function i2s_ASN1_INTEGER(meth: PX509V3_EXT_METHOD; aint: PASN1_INTEGER): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'i2s_ASN1_INTEGER'; + +function s2i_ASN1_INTEGER(meth: PX509V3_EXT_METHOD; value: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PASN1_INTEGER; cdecl; + external LIB_CRYPTO name _PU + 's2i_ASN1_INTEGER'; + +function i2s_ASN1_ENUMERATED(meth: PX509V3_EXT_METHOD; aint: PASN1_ENUMERATED): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'i2s_ASN1_ENUMERATED'; + +function i2s_ASN1_ENUMERATED_TABLE(meth: PX509V3_EXT_METHOD; aint: PASN1_ENUMERATED): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'i2s_ASN1_ENUMERATED_TABLE'; + +function X509V3_EXT_add(ext: PX509V3_EXT_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_add'; + +function X509V3_EXT_add_list(extlist: PX509V3_EXT_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_add_list'; + +function X509V3_EXT_add_alias(nid_to: Integer; nid_from: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_add_alias'; + +procedure X509V3_EXT_cleanup(); cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_cleanup'; + +function X509V3_EXT_get(ext: PX509_EXTENSION): PX509V3_EXT_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_get'; + +function X509V3_EXT_get_nid(nid: Integer): PX509V3_EXT_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_get_nid'; + +function X509V3_add_standard_extensions(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_add_standard_extensions'; + +function X509V3_parse_list(line: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Pstack_st_CONF_VALUE; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_parse_list'; + +function X509V3_EXT_d2i(ext: PX509_EXTENSION): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_d2i'; + +function X509V3_get_d2i(x: Pstack_st_X509_EXTENSION; nid: Integer; crit: PInteger; idx: PInteger): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_get_d2i'; + +function X509V3_EXT_i2d(ext_nid: Integer; crit: Integer; ext_struc: Pointer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_i2d'; + +function X509V3_add1_i2d(x: PPstack_st_X509_EXTENSION; nid: Integer; value: Pointer; crit: Integer; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_add1_i2d'; + +procedure X509V3_EXT_val_prn({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; val: Pstack_st_CONF_VALUE; indent: Integer; ml: Integer); cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_val_prn'; + +function X509V3_EXT_print({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; ext: PX509_EXTENSION; flag: Cardinal; indent: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_print'; + +function X509V3_EXT_print_fp({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPointer; ext: PX509_EXTENSION; flag: Integer; indent: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_EXT_print_fp'; + +function X509V3_extensions_print({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; title: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; exts: Pstack_st_X509_EXTENSION; flag: Cardinal; indent: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_extensions_print'; + +function X509_check_ca(x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_check_ca'; + +function X509_check_purpose(x: PX509; id: Integer; ca: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_check_purpose'; + +function X509_supported_extension(ex: PX509_EXTENSION): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_supported_extension'; + +function X509_PURPOSE_set(p: PInteger; purpose: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_PURPOSE_set'; + +function X509_check_issued(issuer: PX509; subject: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_check_issued'; + +function X509_check_akid(issuer: PX509; akid: PAUTHORITY_KEYID): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_check_akid'; + +procedure X509_set_proxy_flag(x: PX509); cdecl; + external LIB_CRYPTO name _PU + 'X509_set_proxy_flag'; + +procedure X509_set_proxy_pathlen(x: PX509; l: Integer); cdecl; + external LIB_CRYPTO name _PU + 'X509_set_proxy_pathlen'; + +function X509_get_proxy_pathlen(x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_proxy_pathlen'; + +function X509_get_extension_flags(x: PX509): {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt32{$ELSE}LongInt{$IFEND}{$ELSE}UInt32{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_extension_flags'; + +function X509_get_key_usage(x: PX509): {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt32{$ELSE}LongInt{$IFEND}{$ELSE}UInt32{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_key_usage'; + +function X509_get_extended_key_usage(x: PX509): {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt32{$ELSE}LongInt{$IFEND}{$ELSE}UInt32{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'X509_get_extended_key_usage'; + +function X509_get0_subject_key_id(x: PX509): PASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 'X509_get0_subject_key_id'; + +function X509_get0_authority_key_id(x: PX509): PASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 'X509_get0_authority_key_id'; + +function X509_get0_authority_issuer(x: PX509): PGENERAL_NAMES; cdecl; + external LIB_CRYPTO name _PU + 'X509_get0_authority_issuer'; + +function X509_get0_authority_serial(x: PX509): PASN1_INTEGER; cdecl; + external LIB_CRYPTO name _PU + 'X509_get0_authority_serial'; + +function X509_PURPOSE_get_count(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_PURPOSE_get_count'; + +function X509_PURPOSE_get0(idx: Integer): PX509_PURPOSE; cdecl; + external LIB_CRYPTO name _PU + 'X509_PURPOSE_get0'; + +function X509_PURPOSE_get_by_sname(sname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_PURPOSE_get_by_sname'; + +function X509_PURPOSE_get_by_id(id: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_PURPOSE_get_by_id'; + +type + X509_PURPOSE_add_ck = function(p1: PX509_PURPOSE; p2: PX509; p3: Integer): Integer; cdecl; + +function X509_PURPOSE_add(id: Integer; trust: Integer; flags: Integer; ck: X509_PURPOSE_add_ck; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; sname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; arg: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_PURPOSE_add'; + +function X509_PURPOSE_get0_name(xp: PX509_PURPOSE): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'X509_PURPOSE_get0_name'; + +function X509_PURPOSE_get0_sname(xp: PX509_PURPOSE): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'X509_PURPOSE_get0_sname'; + +function X509_PURPOSE_get_trust(xp: PX509_PURPOSE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_PURPOSE_get_trust'; + +procedure X509_PURPOSE_cleanup(); cdecl; + external LIB_CRYPTO name _PU + 'X509_PURPOSE_cleanup'; + +function X509_PURPOSE_get_id(p1: PX509_PURPOSE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_PURPOSE_get_id'; + +function X509_get1_email(x: PX509): Pstack_st_OPENSSL_STRING; cdecl; + external LIB_CRYPTO name _PU + 'X509_get1_email'; + +function X509_REQ_get1_email(x: PX509_REQ): Pstack_st_OPENSSL_STRING; cdecl; + external LIB_CRYPTO name _PU + 'X509_REQ_get1_email'; + +procedure X509_email_free(sk: Pstack_st_OPENSSL_STRING); cdecl; + external LIB_CRYPTO name _PU + 'X509_email_free'; + +function X509_get1_ocsp(x: PX509): Pstack_st_OPENSSL_STRING; cdecl; + external LIB_CRYPTO name _PU + 'X509_get1_ocsp'; + +function X509_check_host(x: PX509; chk: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; chklen: NativeUInt; flags: Cardinal; peername: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_check_host'; + +function X509_check_email(x: PX509; chk: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; chklen: NativeUInt; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_check_email'; + +function X509_check_ip(x: PX509; chk: PByte; chklen: NativeUInt; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_check_ip'; + +function X509_check_ip_asc(x: PX509; ipasc: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509_check_ip_asc'; + +function a2i_IPADDRESS(ipasc: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 'a2i_IPADDRESS'; + +function a2i_IPADDRESS_NC(ipasc: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 'a2i_IPADDRESS_NC'; + +function X509V3_NAME_from_section(nm: PX509_NAME; dn_sk: Pstack_st_CONF_VALUE; chtype: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509V3_NAME_from_section'; + +procedure X509_POLICY_NODE_print({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; node: PX509_POLICY_NODE; indent: Integer); cdecl; + external LIB_CRYPTO name _PU + 'X509_POLICY_NODE_print'; + +function ASRange_new(): PASRange; cdecl; + external LIB_CRYPTO name _PU + 'ASRange_new'; + +procedure ASRange_free(a: PASRange); cdecl; + external LIB_CRYPTO name _PU + 'ASRange_free'; + +function d2i_ASRange(a: PPASRange; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASRange; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASRange'; + +function i2d_ASRange(a: PASRange; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASRange'; + +function ASRange_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASRange_it'; + +function ASIdOrRange_new(): PASIdOrRange; cdecl; + external LIB_CRYPTO name _PU + 'ASIdOrRange_new'; + +procedure ASIdOrRange_free(a: PASIdOrRange); cdecl; + external LIB_CRYPTO name _PU + 'ASIdOrRange_free'; + +function d2i_ASIdOrRange(a: PPASIdOrRange; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASIdOrRange; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASIdOrRange'; + +function i2d_ASIdOrRange(a: PASIdOrRange; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASIdOrRange'; + +function ASIdOrRange_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASIdOrRange_it'; + +function ASIdentifierChoice_new(): PASIdentifierChoice; cdecl; + external LIB_CRYPTO name _PU + 'ASIdentifierChoice_new'; + +procedure ASIdentifierChoice_free(a: PASIdentifierChoice); cdecl; + external LIB_CRYPTO name _PU + 'ASIdentifierChoice_free'; + +function d2i_ASIdentifierChoice(a: PPASIdentifierChoice; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASIdentifierChoice; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASIdentifierChoice'; + +function i2d_ASIdentifierChoice(a: PASIdentifierChoice; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASIdentifierChoice'; + +function ASIdentifierChoice_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASIdentifierChoice_it'; + +function ASIdentifiers_new(): PASIdentifiers; cdecl; + external LIB_CRYPTO name _PU + 'ASIdentifiers_new'; + +procedure ASIdentifiers_free(a: PASIdentifiers); cdecl; + external LIB_CRYPTO name _PU + 'ASIdentifiers_free'; + +function d2i_ASIdentifiers(a: PPASIdentifiers; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PASIdentifiers; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ASIdentifiers'; + +function i2d_ASIdentifiers(a: PASIdentifiers; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ASIdentifiers'; + +function ASIdentifiers_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ASIdentifiers_it'; + +function IPAddressRange_new(): PIPAddressRange; cdecl; + external LIB_CRYPTO name _PU + 'IPAddressRange_new'; + +procedure IPAddressRange_free(a: PIPAddressRange); cdecl; + external LIB_CRYPTO name _PU + 'IPAddressRange_free'; + +function d2i_IPAddressRange(a: PPIPAddressRange; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PIPAddressRange; cdecl; + external LIB_CRYPTO name _PU + 'd2i_IPAddressRange'; + +function i2d_IPAddressRange(a: PIPAddressRange; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_IPAddressRange'; + +function IPAddressRange_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'IPAddressRange_it'; + +function IPAddressOrRange_new(): PIPAddressOrRange; cdecl; + external LIB_CRYPTO name _PU + 'IPAddressOrRange_new'; + +procedure IPAddressOrRange_free(a: PIPAddressOrRange); cdecl; + external LIB_CRYPTO name _PU + 'IPAddressOrRange_free'; + +function d2i_IPAddressOrRange(a: PPIPAddressOrRange; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PIPAddressOrRange; cdecl; + external LIB_CRYPTO name _PU + 'd2i_IPAddressOrRange'; + +function i2d_IPAddressOrRange(a: PIPAddressOrRange; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_IPAddressOrRange'; + +function IPAddressOrRange_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'IPAddressOrRange_it'; + +function IPAddressChoice_new(): PIPAddressChoice; cdecl; + external LIB_CRYPTO name _PU + 'IPAddressChoice_new'; + +procedure IPAddressChoice_free(a: PIPAddressChoice); cdecl; + external LIB_CRYPTO name _PU + 'IPAddressChoice_free'; + +function d2i_IPAddressChoice(a: PPIPAddressChoice; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PIPAddressChoice; cdecl; + external LIB_CRYPTO name _PU + 'd2i_IPAddressChoice'; + +function i2d_IPAddressChoice(a: PIPAddressChoice; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_IPAddressChoice'; + +function IPAddressChoice_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'IPAddressChoice_it'; + +function IPAddressFamily_new(): PIPAddressFamily; cdecl; + external LIB_CRYPTO name _PU + 'IPAddressFamily_new'; + +procedure IPAddressFamily_free(a: PIPAddressFamily); cdecl; + external LIB_CRYPTO name _PU + 'IPAddressFamily_free'; + +function d2i_IPAddressFamily(a: PPIPAddressFamily; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PIPAddressFamily; cdecl; + external LIB_CRYPTO name _PU + 'd2i_IPAddressFamily'; + +function i2d_IPAddressFamily(a: PIPAddressFamily; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_IPAddressFamily'; + +function IPAddressFamily_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'IPAddressFamily_it'; + +function X509v3_asid_add_inherit(asid: PASIdentifiers; which: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_asid_add_inherit'; + +function X509v3_asid_add_id_or_range(asid: PASIdentifiers; which: Integer; min: PASN1_INTEGER; max: PASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_asid_add_id_or_range'; + +function X509v3_addr_add_inherit(addr: PIPAddrBlocks; afi: Cardinal; safi: PCardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_addr_add_inherit'; + +function X509v3_addr_add_prefix(addr: PIPAddrBlocks; afi: Cardinal; safi: PCardinal; a: PByte; prefixlen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_addr_add_prefix'; + +function X509v3_addr_add_range(addr: PIPAddrBlocks; afi: Cardinal; safi: PCardinal; min: PByte; max: PByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_addr_add_range'; + +function X509v3_addr_get_afi(f: PIPAddressFamily): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_addr_get_afi'; + +function X509v3_addr_get_range(aor: PIPAddressOrRange; afi: Cardinal; min: PByte; max: PByte; length: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_addr_get_range'; + +function X509v3_asid_is_canonical(asid: PASIdentifiers): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_asid_is_canonical'; + +function X509v3_addr_is_canonical(addr: PIPAddrBlocks): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_addr_is_canonical'; + +function X509v3_asid_canonize(asid: PASIdentifiers): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_asid_canonize'; + +function X509v3_addr_canonize(addr: PIPAddrBlocks): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_addr_canonize'; + +function X509v3_asid_inherits(asid: PASIdentifiers): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_asid_inherits'; + +function X509v3_addr_inherits(addr: PIPAddrBlocks): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_addr_inherits'; + +function X509v3_asid_subset(a: PASIdentifiers; b: PASIdentifiers): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_asid_subset'; + +function X509v3_addr_subset(a: PIPAddrBlocks; b: PIPAddrBlocks): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_addr_subset'; + +function X509v3_asid_validate_path(p1: PX509_STORE_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_asid_validate_path'; + +function X509v3_addr_validate_path(p1: PX509_STORE_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_addr_validate_path'; + +function X509v3_asid_validate_resource_set(chain: Pstack_st_X509; ext: PASIdentifiers; allow_inheritance: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_asid_validate_resource_set'; + +function X509v3_addr_validate_resource_set(chain: Pstack_st_X509; ext: PIPAddrBlocks; allow_inheritance: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'X509v3_addr_validate_resource_set'; + +function NAMING_AUTHORITY_new(): PNAMING_AUTHORITY; cdecl; + external LIB_CRYPTO name _PU + 'NAMING_AUTHORITY_new'; + +procedure NAMING_AUTHORITY_free(a: PNAMING_AUTHORITY); cdecl; + external LIB_CRYPTO name _PU + 'NAMING_AUTHORITY_free'; + +function d2i_NAMING_AUTHORITY(a: PPNAMING_AUTHORITY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PNAMING_AUTHORITY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_NAMING_AUTHORITY'; + +function i2d_NAMING_AUTHORITY(a: PNAMING_AUTHORITY; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_NAMING_AUTHORITY'; + +function NAMING_AUTHORITY_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'NAMING_AUTHORITY_it'; + +function PROFESSION_INFO_new(): PPROFESSION_INFO; cdecl; + external LIB_CRYPTO name _PU + 'PROFESSION_INFO_new'; + +procedure PROFESSION_INFO_free(a: PPROFESSION_INFO); cdecl; + external LIB_CRYPTO name _PU + 'PROFESSION_INFO_free'; + +function d2i_PROFESSION_INFO(a: PPPROFESSION_INFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPROFESSION_INFO; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PROFESSION_INFO'; + +function i2d_PROFESSION_INFO(a: PPROFESSION_INFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PROFESSION_INFO'; + +function PROFESSION_INFO_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PROFESSION_INFO_it'; + +function ADMISSIONS_new(): PADMISSIONS; cdecl; + external LIB_CRYPTO name _PU + 'ADMISSIONS_new'; + +procedure ADMISSIONS_free(a: PADMISSIONS); cdecl; + external LIB_CRYPTO name _PU + 'ADMISSIONS_free'; + +function d2i_ADMISSIONS(a: PPADMISSIONS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PADMISSIONS; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ADMISSIONS'; + +function i2d_ADMISSIONS(a: PADMISSIONS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ADMISSIONS'; + +function ADMISSIONS_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ADMISSIONS_it'; + +function ADMISSION_SYNTAX_new(): PADMISSION_SYNTAX; cdecl; + external LIB_CRYPTO name _PU + 'ADMISSION_SYNTAX_new'; + +procedure ADMISSION_SYNTAX_free(a: PADMISSION_SYNTAX); cdecl; + external LIB_CRYPTO name _PU + 'ADMISSION_SYNTAX_free'; + +function d2i_ADMISSION_SYNTAX(a: PPADMISSION_SYNTAX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PADMISSION_SYNTAX; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ADMISSION_SYNTAX'; + +function i2d_ADMISSION_SYNTAX(a: PADMISSION_SYNTAX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ADMISSION_SYNTAX'; + +function ADMISSION_SYNTAX_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'ADMISSION_SYNTAX_it'; + +function NAMING_AUTHORITY_get0_authorityId(n: PNAMING_AUTHORITY): PASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'NAMING_AUTHORITY_get0_authorityId'; + +function NAMING_AUTHORITY_get0_authorityURL(n: PNAMING_AUTHORITY): PASN1_IA5STRING; cdecl; + external LIB_CRYPTO name _PU + 'NAMING_AUTHORITY_get0_authorityURL'; + +function NAMING_AUTHORITY_get0_authorityText(n: PNAMING_AUTHORITY): PASN1_STRING; cdecl; + external LIB_CRYPTO name _PU + 'NAMING_AUTHORITY_get0_authorityText'; + +procedure NAMING_AUTHORITY_set0_authorityId(n: PNAMING_AUTHORITY; namingAuthorityId: PASN1_OBJECT); cdecl; + external LIB_CRYPTO name _PU + 'NAMING_AUTHORITY_set0_authorityId'; + +procedure NAMING_AUTHORITY_set0_authorityURL(n: PNAMING_AUTHORITY; namingAuthorityUrl: PASN1_IA5STRING); cdecl; + external LIB_CRYPTO name _PU + 'NAMING_AUTHORITY_set0_authorityURL'; + +procedure NAMING_AUTHORITY_set0_authorityText(n: PNAMING_AUTHORITY; namingAuthorityText: PASN1_STRING); cdecl; + external LIB_CRYPTO name _PU + 'NAMING_AUTHORITY_set0_authorityText'; + +function ADMISSION_SYNTAX_get0_admissionAuthority({$IFNDEF FPC}{$IF CompilerVersion > 21}&as{$ELSE}as1{$IFEND}{$ELSE}&as{$ENDIF}: PADMISSION_SYNTAX): PGENERAL_NAME; cdecl; + external LIB_CRYPTO name _PU + 'ADMISSION_SYNTAX_get0_admissionAuthority'; + +procedure ADMISSION_SYNTAX_set0_admissionAuthority({$IFNDEF FPC}{$IF CompilerVersion > 21}&as{$ELSE}as1{$IFEND}{$ELSE}&as{$ENDIF}: PADMISSION_SYNTAX; aa: PGENERAL_NAME); cdecl; + external LIB_CRYPTO name _PU + 'ADMISSION_SYNTAX_set0_admissionAuthority'; + +function ADMISSION_SYNTAX_get0_contentsOfAdmissions({$IFNDEF FPC}{$IF CompilerVersion > 21}&as{$ELSE}as1{$IFEND}{$ELSE}&as{$ENDIF}: PADMISSION_SYNTAX): Pstack_st_ADMISSIONS; cdecl; + external LIB_CRYPTO name _PU + 'ADMISSION_SYNTAX_get0_contentsOfAdmissions'; + +procedure ADMISSION_SYNTAX_set0_contentsOfAdmissions({$IFNDEF FPC}{$IF CompilerVersion > 21}&as{$ELSE}as1{$IFEND}{$ELSE}&as{$ENDIF}: PADMISSION_SYNTAX; a: Pstack_st_ADMISSIONS); cdecl; + external LIB_CRYPTO name _PU + 'ADMISSION_SYNTAX_set0_contentsOfAdmissions'; + +function ADMISSIONS_get0_admissionAuthority(a: PADMISSIONS): PGENERAL_NAME; cdecl; + external LIB_CRYPTO name _PU + 'ADMISSIONS_get0_admissionAuthority'; + +procedure ADMISSIONS_set0_admissionAuthority(a: PADMISSIONS; aa: PGENERAL_NAME); cdecl; + external LIB_CRYPTO name _PU + 'ADMISSIONS_set0_admissionAuthority'; + +function ADMISSIONS_get0_namingAuthority(a: PADMISSIONS): PNAMING_AUTHORITY; cdecl; + external LIB_CRYPTO name _PU + 'ADMISSIONS_get0_namingAuthority'; + +procedure ADMISSIONS_set0_namingAuthority(a: PADMISSIONS; na: PNAMING_AUTHORITY); cdecl; + external LIB_CRYPTO name _PU + 'ADMISSIONS_set0_namingAuthority'; + +function ADMISSIONS_get0_professionInfos(a: PADMISSIONS): PPROFESSION_INFOS; cdecl; + external LIB_CRYPTO name _PU + 'ADMISSIONS_get0_professionInfos'; + +procedure ADMISSIONS_set0_professionInfos(a: PADMISSIONS; pi: PPROFESSION_INFOS); cdecl; + external LIB_CRYPTO name _PU + 'ADMISSIONS_set0_professionInfos'; + +function PROFESSION_INFO_get0_addProfessionInfo(pi: PPROFESSION_INFO): PASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 'PROFESSION_INFO_get0_addProfessionInfo'; + +procedure PROFESSION_INFO_set0_addProfessionInfo(pi: PPROFESSION_INFO; aos: PASN1_OCTET_STRING); cdecl; + external LIB_CRYPTO name _PU + 'PROFESSION_INFO_set0_addProfessionInfo'; + +function PROFESSION_INFO_get0_namingAuthority(pi: PPROFESSION_INFO): PNAMING_AUTHORITY; cdecl; + external LIB_CRYPTO name _PU + 'PROFESSION_INFO_get0_namingAuthority'; + +procedure PROFESSION_INFO_set0_namingAuthority(pi: PPROFESSION_INFO; na: PNAMING_AUTHORITY); cdecl; + external LIB_CRYPTO name _PU + 'PROFESSION_INFO_set0_namingAuthority'; + +function PROFESSION_INFO_get0_professionItems(pi: PPROFESSION_INFO): Pstack_st_ASN1_STRING; cdecl; + external LIB_CRYPTO name _PU + 'PROFESSION_INFO_get0_professionItems'; + +procedure PROFESSION_INFO_set0_professionItems(pi: PPROFESSION_INFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&as{$ELSE}as1{$IFEND}{$ELSE}&as{$ENDIF}: Pstack_st_ASN1_STRING); cdecl; + external LIB_CRYPTO name _PU + 'PROFESSION_INFO_set0_professionItems'; + +function PROFESSION_INFO_get0_professionOIDs(pi: PPROFESSION_INFO): Pstack_st_ASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'PROFESSION_INFO_get0_professionOIDs'; + +procedure PROFESSION_INFO_set0_professionOIDs(pi: PPROFESSION_INFO; po: Pstack_st_ASN1_OBJECT); cdecl; + external LIB_CRYPTO name _PU + 'PROFESSION_INFO_set0_professionOIDs'; + +function PROFESSION_INFO_get0_registrationNumber(pi: PPROFESSION_INFO): PASN1_PRINTABLESTRING; cdecl; + external LIB_CRYPTO name _PU + 'PROFESSION_INFO_get0_registrationNumber'; + +procedure PROFESSION_INFO_set0_registrationNumber(pi: PPROFESSION_INFO; rn: PASN1_PRINTABLESTRING); cdecl; + external LIB_CRYPTO name _PU + 'PROFESSION_INFO_set0_registrationNumber'; + +function ERR_load_CMS_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_CMS_strings'; + +function CMS_ContentInfo_new(): PCMS_ContentInfo; cdecl; + external LIB_CRYPTO name _PU + 'CMS_ContentInfo_new'; + +procedure CMS_ContentInfo_free(a: PCMS_ContentInfo); cdecl; + external LIB_CRYPTO name _PU + 'CMS_ContentInfo_free'; + +function d2i_CMS_ContentInfo(a: PPCMS_ContentInfo; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PCMS_ContentInfo; cdecl; + external LIB_CRYPTO name _PU + 'd2i_CMS_ContentInfo'; + +function i2d_CMS_ContentInfo(a: PCMS_ContentInfo; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_CMS_ContentInfo'; + +function CMS_ContentInfo_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'CMS_ContentInfo_it'; + +function CMS_ReceiptRequest_new(): PCMS_ReceiptRequest; cdecl; + external LIB_CRYPTO name _PU + 'CMS_ReceiptRequest_new'; + +procedure CMS_ReceiptRequest_free(a: PCMS_ReceiptRequest); cdecl; + external LIB_CRYPTO name _PU + 'CMS_ReceiptRequest_free'; + +function d2i_CMS_ReceiptRequest(a: PPCMS_ReceiptRequest; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PCMS_ReceiptRequest; cdecl; + external LIB_CRYPTO name _PU + 'd2i_CMS_ReceiptRequest'; + +function i2d_CMS_ReceiptRequest(a: PCMS_ReceiptRequest; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_CMS_ReceiptRequest'; + +function CMS_ReceiptRequest_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'CMS_ReceiptRequest_it'; + +function CMS_ContentInfo_print_ctx({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; x: PCMS_ContentInfo; indent: Integer; pctx: PASN1_PCTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_ContentInfo_print_ctx'; + +function CMS_get0_type(cms: PCMS_ContentInfo): PASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'CMS_get0_type'; + +function CMS_dataInit(cms: PCMS_ContentInfo; icont: PBIO): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'CMS_dataInit'; + +function CMS_dataFinal(cms: PCMS_ContentInfo; bio: PBIO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_dataFinal'; + +function CMS_get0_content(cms: PCMS_ContentInfo): PPASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 'CMS_get0_content'; + +function CMS_is_detached(cms: PCMS_ContentInfo): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_is_detached'; + +function CMS_set_detached(cms: PCMS_ContentInfo; detached: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_set_detached'; + +function CMS_stream(boundary: PPPByte; cms: PCMS_ContentInfo): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_stream'; + +function d2i_CMS_bio(bp: PBIO; cms: PPCMS_ContentInfo): PCMS_ContentInfo; cdecl; + external LIB_CRYPTO name _PU + 'd2i_CMS_bio'; + +function i2d_CMS_bio(bp: PBIO; cms: PCMS_ContentInfo): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_CMS_bio'; + +function BIO_new_CMS({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; cms: PCMS_ContentInfo): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'BIO_new_CMS'; + +function i2d_CMS_bio_stream({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; cms: PCMS_ContentInfo; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_CMS_bio_stream'; + +function PEM_write_bio_CMS_stream({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; cms: PCMS_ContentInfo; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_CMS_stream'; + +function SMIME_read_CMS(bio: PBIO; bcont: PPBIO): PCMS_ContentInfo; cdecl; + external LIB_CRYPTO name _PU + 'SMIME_read_CMS'; + +function SMIME_write_CMS(bio: PBIO; cms: PCMS_ContentInfo; data: PBIO; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SMIME_write_CMS'; + +function CMS_final(cms: PCMS_ContentInfo; data: PBIO; dcont: PBIO; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_final'; + +function CMS_sign(signcert: PX509; pkey: PEVP_PKEY; certs: Pstack_st_X509; data: PBIO; flags: Cardinal): PCMS_ContentInfo; cdecl; + external LIB_CRYPTO name _PU + 'CMS_sign'; + +function CMS_sign_receipt(si: PCMS_SignerInfo; signcert: PX509; pkey: PEVP_PKEY; certs: Pstack_st_X509; flags: Cardinal): PCMS_ContentInfo; cdecl; + external LIB_CRYPTO name _PU + 'CMS_sign_receipt'; + +function CMS_data(cms: PCMS_ContentInfo; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_data'; + +function CMS_data_create({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO; flags: Cardinal): PCMS_ContentInfo; cdecl; + external LIB_CRYPTO name _PU + 'CMS_data_create'; + +function CMS_digest_verify(cms: PCMS_ContentInfo; dcont: PBIO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_digest_verify'; + +function CMS_digest_create({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO; md: PEVP_MD; flags: Cardinal): PCMS_ContentInfo; cdecl; + external LIB_CRYPTO name _PU + 'CMS_digest_create'; + +function CMS_EncryptedData_decrypt(cms: PCMS_ContentInfo; key: PByte; keylen: NativeUInt; dcont: PBIO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_EncryptedData_decrypt'; + +function CMS_EncryptedData_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO; cipher: PEVP_CIPHER; key: PByte; keylen: NativeUInt; flags: Cardinal): PCMS_ContentInfo; cdecl; + external LIB_CRYPTO name _PU + 'CMS_EncryptedData_encrypt'; + +function CMS_EncryptedData_set1_key(cms: PCMS_ContentInfo; ciph: PEVP_CIPHER; key: PByte; keylen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_EncryptedData_set1_key'; + +function CMS_verify(cms: PCMS_ContentInfo; certs: Pstack_st_X509; store: PX509_STORE; dcont: PBIO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_verify'; + +function CMS_verify_receipt(rcms: PCMS_ContentInfo; ocms: PCMS_ContentInfo; certs: Pstack_st_X509; store: PX509_STORE; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_verify_receipt'; + +function CMS_get0_signers(cms: PCMS_ContentInfo): Pstack_st_X509; cdecl; + external LIB_CRYPTO name _PU + 'CMS_get0_signers'; + +function CMS_encrypt(certs: Pstack_st_X509; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO; cipher: PEVP_CIPHER; flags: Cardinal): PCMS_ContentInfo; cdecl; + external LIB_CRYPTO name _PU + 'CMS_encrypt'; + +function CMS_decrypt(cms: PCMS_ContentInfo; pkey: PEVP_PKEY; cert: PX509; dcont: PBIO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_decrypt'; + +function CMS_decrypt_set1_pkey(cms: PCMS_ContentInfo; pk: PEVP_PKEY; cert: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_decrypt_set1_pkey'; + +function CMS_decrypt_set1_key(cms: PCMS_ContentInfo; key: PByte; keylen: NativeUInt; id: PByte; idlen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_decrypt_set1_key'; + +function CMS_decrypt_set1_password(cms: PCMS_ContentInfo; pass: PByte; passlen: Int64): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_decrypt_set1_password'; + +function CMS_get0_RecipientInfos(cms: PCMS_ContentInfo): Pstack_st_CMS_RecipientInfo; cdecl; + external LIB_CRYPTO name _PU + 'CMS_get0_RecipientInfos'; + +function CMS_RecipientInfo_type(ri: PCMS_RecipientInfo): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_type'; + +function CMS_RecipientInfo_get0_pkey_ctx(ri: PCMS_RecipientInfo): PEVP_PKEY_CTX; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_get0_pkey_ctx'; + +function CMS_EnvelopedData_create(cipher: PEVP_CIPHER): PCMS_ContentInfo; cdecl; + external LIB_CRYPTO name _PU + 'CMS_EnvelopedData_create'; + +function CMS_add1_recipient_cert(cms: PCMS_ContentInfo; recip: PX509; flags: Cardinal): PCMS_RecipientInfo; cdecl; + external LIB_CRYPTO name _PU + 'CMS_add1_recipient_cert'; + +function CMS_RecipientInfo_set0_pkey(ri: PCMS_RecipientInfo; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_set0_pkey'; + +function CMS_RecipientInfo_ktri_cert_cmp(ri: PCMS_RecipientInfo; cert: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_ktri_cert_cmp'; + +function CMS_RecipientInfo_ktri_get0_algs(ri: PCMS_RecipientInfo; pk: PPEVP_PKEY; recip: PPX509; palg: PPX509_ALGOR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_ktri_get0_algs'; + +function CMS_RecipientInfo_ktri_get0_signer_id(ri: PCMS_RecipientInfo; keyid: PPASN1_OCTET_STRING; issuer: PPX509_NAME; sno: PPASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_ktri_get0_signer_id'; + +function CMS_add0_recipient_key(cms: PCMS_ContentInfo; nid: Integer; key: PByte; keylen: NativeUInt; id: PByte; idlen: NativeUInt; date: PASN1_GENERALIZEDTIME; otherTypeId: PASN1_OBJECT; otherType: PASN1_TYPE): PCMS_RecipientInfo; cdecl; + external LIB_CRYPTO name _PU + 'CMS_add0_recipient_key'; + +function CMS_RecipientInfo_kekri_get0_id(ri: PCMS_RecipientInfo; palg: PPX509_ALGOR; pid: PPASN1_OCTET_STRING; pdate: PPASN1_GENERALIZEDTIME; potherid: PPASN1_OBJECT; pothertype: PPASN1_TYPE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_kekri_get0_id'; + +function CMS_RecipientInfo_set0_key(ri: PCMS_RecipientInfo; key: PByte; keylen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_set0_key'; + +function CMS_RecipientInfo_kekri_id_cmp(ri: PCMS_RecipientInfo; id: PByte; idlen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_kekri_id_cmp'; + +function CMS_RecipientInfo_set0_password(ri: PCMS_RecipientInfo; pass: PByte; passlen: Int64): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_set0_password'; + +function CMS_add0_recipient_password(cms: PCMS_ContentInfo; iter: Integer; wrap_nid: Integer; pbe_nid: Integer; pass: PByte; passlen: Int64; kekciph: PEVP_CIPHER): PCMS_RecipientInfo; cdecl; + external LIB_CRYPTO name _PU + 'CMS_add0_recipient_password'; + +function CMS_RecipientInfo_decrypt(cms: PCMS_ContentInfo; ri: PCMS_RecipientInfo): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_decrypt'; + +function CMS_RecipientInfo_encrypt(cms: PCMS_ContentInfo; ri: PCMS_RecipientInfo): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_encrypt'; + +function CMS_uncompress(cms: PCMS_ContentInfo; dcont: PBIO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_uncompress'; + +function CMS_compress({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO; comp_nid: Integer; flags: Cardinal): PCMS_ContentInfo; cdecl; + external LIB_CRYPTO name _PU + 'CMS_compress'; + +function CMS_set1_eContentType(cms: PCMS_ContentInfo; oid: PASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_set1_eContentType'; + +function CMS_get0_eContentType(cms: PCMS_ContentInfo): PASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'CMS_get0_eContentType'; + +function CMS_add0_CertificateChoices(cms: PCMS_ContentInfo): PCMS_CertificateChoices; cdecl; + external LIB_CRYPTO name _PU + 'CMS_add0_CertificateChoices'; + +function CMS_add0_cert(cms: PCMS_ContentInfo; cert: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_add0_cert'; + +function CMS_add1_cert(cms: PCMS_ContentInfo; cert: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_add1_cert'; + +function CMS_get1_certs(cms: PCMS_ContentInfo): Pstack_st_X509; cdecl; + external LIB_CRYPTO name _PU + 'CMS_get1_certs'; + +function CMS_add0_RevocationInfoChoice(cms: PCMS_ContentInfo): PCMS_RevocationInfoChoice; cdecl; + external LIB_CRYPTO name _PU + 'CMS_add0_RevocationInfoChoice'; + +function CMS_add0_crl(cms: PCMS_ContentInfo; crl: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_add0_crl'; + +function CMS_add1_crl(cms: PCMS_ContentInfo; crl: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_add1_crl'; + +function CMS_get1_crls(cms: PCMS_ContentInfo): Pstack_st_X509_CRL; cdecl; + external LIB_CRYPTO name _PU + 'CMS_get1_crls'; + +function CMS_SignedData_init(cms: PCMS_ContentInfo): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_SignedData_init'; + +function CMS_add1_signer(cms: PCMS_ContentInfo; signer: PX509; pk: PEVP_PKEY; md: PEVP_MD; flags: Cardinal): PCMS_SignerInfo; cdecl; + external LIB_CRYPTO name _PU + 'CMS_add1_signer'; + +function CMS_SignerInfo_get0_pkey_ctx(si: PCMS_SignerInfo): PEVP_PKEY_CTX; cdecl; + external LIB_CRYPTO name _PU + 'CMS_SignerInfo_get0_pkey_ctx'; + +function CMS_SignerInfo_get0_md_ctx(si: PCMS_SignerInfo): PEVP_MD_CTX; cdecl; + external LIB_CRYPTO name _PU + 'CMS_SignerInfo_get0_md_ctx'; + +function CMS_get0_SignerInfos(cms: PCMS_ContentInfo): Pstack_st_CMS_SignerInfo; cdecl; + external LIB_CRYPTO name _PU + 'CMS_get0_SignerInfos'; + +procedure CMS_SignerInfo_set1_signer_cert(si: PCMS_SignerInfo; signer: PX509); cdecl; + external LIB_CRYPTO name _PU + 'CMS_SignerInfo_set1_signer_cert'; + +function CMS_SignerInfo_get0_signer_id(si: PCMS_SignerInfo; keyid: PPASN1_OCTET_STRING; issuer: PPX509_NAME; sno: PPASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_SignerInfo_get0_signer_id'; + +function CMS_SignerInfo_cert_cmp(si: PCMS_SignerInfo; cert: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_SignerInfo_cert_cmp'; + +function CMS_set1_signers_certs(cms: PCMS_ContentInfo; certs: Pstack_st_X509; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_set1_signers_certs'; + +procedure CMS_SignerInfo_get0_algs(si: PCMS_SignerInfo; pk: PPEVP_PKEY; signer: PPX509; pdig: PPX509_ALGOR; psig: PPX509_ALGOR); cdecl; + external LIB_CRYPTO name _PU + 'CMS_SignerInfo_get0_algs'; + +function CMS_SignerInfo_get0_signature(si: PCMS_SignerInfo): PASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 'CMS_SignerInfo_get0_signature'; + +function CMS_SignerInfo_sign(si: PCMS_SignerInfo): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_SignerInfo_sign'; + +function CMS_SignerInfo_verify(si: PCMS_SignerInfo): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_SignerInfo_verify'; + +function CMS_SignerInfo_verify_content(si: PCMS_SignerInfo; chain: PBIO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_SignerInfo_verify_content'; + +function CMS_add_smimecap(si: PCMS_SignerInfo; algs: Pstack_st_X509_ALGOR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_add_smimecap'; + +function CMS_add_simple_smimecap(algs: PPstack_st_X509_ALGOR; algnid: Integer; keysize: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_add_simple_smimecap'; + +function CMS_add_standard_smimecap(smcap: PPstack_st_X509_ALGOR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_add_standard_smimecap'; + +function CMS_signed_get_attr_count(si: PCMS_SignerInfo): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_signed_get_attr_count'; + +function CMS_signed_get_attr_by_NID(si: PCMS_SignerInfo; nid: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_signed_get_attr_by_NID'; + +function CMS_signed_get_attr_by_OBJ(si: PCMS_SignerInfo; obj: PASN1_OBJECT; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_signed_get_attr_by_OBJ'; + +function CMS_signed_get_attr(si: PCMS_SignerInfo; loc: Integer): PX509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'CMS_signed_get_attr'; + +function CMS_signed_delete_attr(si: PCMS_SignerInfo; loc: Integer): PX509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'CMS_signed_delete_attr'; + +function CMS_signed_add1_attr(si: PCMS_SignerInfo; attr: PX509_ATTRIBUTE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_signed_add1_attr'; + +function CMS_signed_add1_attr_by_OBJ(si: PCMS_SignerInfo; obj: PASN1_OBJECT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: Pointer; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_signed_add1_attr_by_OBJ'; + +function CMS_signed_add1_attr_by_NID(si: PCMS_SignerInfo; nid: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: Pointer; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_signed_add1_attr_by_NID'; + +function CMS_signed_add1_attr_by_txt(si: PCMS_SignerInfo; attrname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: Pointer; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_signed_add1_attr_by_txt'; + +function CMS_signed_get0_data_by_OBJ(si: PCMS_SignerInfo; oid: PASN1_OBJECT; lastpos: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_signed_get0_data_by_OBJ'; + +function CMS_unsigned_get_attr_count(si: PCMS_SignerInfo): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_unsigned_get_attr_count'; + +function CMS_unsigned_get_attr_by_NID(si: PCMS_SignerInfo; nid: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_unsigned_get_attr_by_NID'; + +function CMS_unsigned_get_attr_by_OBJ(si: PCMS_SignerInfo; obj: PASN1_OBJECT; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_unsigned_get_attr_by_OBJ'; + +function CMS_unsigned_get_attr(si: PCMS_SignerInfo; loc: Integer): PX509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'CMS_unsigned_get_attr'; + +function CMS_unsigned_delete_attr(si: PCMS_SignerInfo; loc: Integer): PX509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'CMS_unsigned_delete_attr'; + +function CMS_unsigned_add1_attr(si: PCMS_SignerInfo; attr: PX509_ATTRIBUTE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_unsigned_add1_attr'; + +function CMS_unsigned_add1_attr_by_OBJ(si: PCMS_SignerInfo; obj: PASN1_OBJECT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: Pointer; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_unsigned_add1_attr_by_OBJ'; + +function CMS_unsigned_add1_attr_by_NID(si: PCMS_SignerInfo; nid: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: Pointer; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_unsigned_add1_attr_by_NID'; + +function CMS_unsigned_add1_attr_by_txt(si: PCMS_SignerInfo; attrname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; bytes: Pointer; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_unsigned_add1_attr_by_txt'; + +function CMS_unsigned_get0_data_by_OBJ(si: PCMS_SignerInfo; oid: PASN1_OBJECT; lastpos: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_unsigned_get0_data_by_OBJ'; + +function CMS_get1_ReceiptRequest(si: PCMS_SignerInfo; prr: PPCMS_ReceiptRequest): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_get1_ReceiptRequest'; + +function CMS_ReceiptRequest_create0(id: PByte; idlen: Integer; allorfirst: Integer; receiptList: Pstack_st_GENERAL_NAMES; receiptsTo: Pstack_st_GENERAL_NAMES): PCMS_ReceiptRequest; cdecl; + external LIB_CRYPTO name _PU + 'CMS_ReceiptRequest_create0'; + +function CMS_add1_ReceiptRequest(si: PCMS_SignerInfo; rr: PCMS_ReceiptRequest): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_add1_ReceiptRequest'; + +procedure CMS_ReceiptRequest_get0_values(rr: PCMS_ReceiptRequest; pcid: PPASN1_STRING; pallorfirst: PInteger; plist: PPstack_st_GENERAL_NAMES; prto: PPstack_st_GENERAL_NAMES); cdecl; + external LIB_CRYPTO name _PU + 'CMS_ReceiptRequest_get0_values'; + +function CMS_RecipientInfo_kari_get0_alg(ri: PCMS_RecipientInfo; palg: PPX509_ALGOR; pukm: PPASN1_OCTET_STRING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_kari_get0_alg'; + +function CMS_RecipientInfo_kari_get0_reks(ri: PCMS_RecipientInfo): Pstack_st_CMS_RecipientEncryptedKey; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_kari_get0_reks'; + +function CMS_RecipientInfo_kari_get0_orig_id(ri: PCMS_RecipientInfo; pubalg: PPX509_ALGOR; pubkey: PPASN1_BIT_STRING; keyid: PPASN1_OCTET_STRING; issuer: PPX509_NAME; sno: PPASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_kari_get0_orig_id'; + +function CMS_RecipientInfo_kari_orig_id_cmp(ri: PCMS_RecipientInfo; cert: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_kari_orig_id_cmp'; + +function CMS_RecipientEncryptedKey_get0_id(rek: PCMS_RecipientEncryptedKey; keyid: PPASN1_OCTET_STRING; tm: PPASN1_GENERALIZEDTIME; other: PPCMS_OtherKeyAttribute; issuer: PPX509_NAME; sno: PPASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientEncryptedKey_get0_id'; + +function CMS_RecipientEncryptedKey_cert_cmp(rek: PCMS_RecipientEncryptedKey; cert: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientEncryptedKey_cert_cmp'; + +function CMS_RecipientInfo_kari_set0_pkey(ri: PCMS_RecipientInfo; pk: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_kari_set0_pkey'; + +function CMS_RecipientInfo_kari_get0_ctx(ri: PCMS_RecipientInfo): PEVP_CIPHER_CTX; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_kari_get0_ctx'; + +function CMS_RecipientInfo_kari_decrypt(cms: PCMS_ContentInfo; ri: PCMS_RecipientInfo; rek: PCMS_RecipientEncryptedKey): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_RecipientInfo_kari_decrypt'; + +function CMS_SharedInfo_encode(pder: PPByte; kekalg: PX509_ALGOR; ukm: PASN1_OCTET_STRING; keylen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CMS_SharedInfo_encode'; + +function ERR_load_COMP_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_COMP_strings'; + +function COMP_CTX_new(meth: PCOMP_METHOD): PCOMP_CTX; cdecl; + external LIB_CRYPTO name _PU + 'COMP_CTX_new'; + +function COMP_CTX_get_method(ctx: PCOMP_CTX): PCOMP_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'COMP_CTX_get_method'; + +function COMP_CTX_get_type(comp: PCOMP_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'COMP_CTX_get_type'; + +function COMP_get_type(meth: PCOMP_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'COMP_get_type'; + +function COMP_get_name(meth: PCOMP_METHOD): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'COMP_get_name'; + +procedure COMP_CTX_free(ctx: PCOMP_CTX); cdecl; + external LIB_CRYPTO name _PU + 'COMP_CTX_free'; + +function COMP_compress_block(ctx: PCOMP_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; olen: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; ilen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'COMP_compress_block'; + +function COMP_expand_block(ctx: PCOMP_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; olen: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; ilen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'COMP_expand_block'; + +function COMP_zlib(): PCOMP_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'COMP_zlib'; + +function _CONF_new_section(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PCONF_VALUE; cdecl; + external LIB_CRYPTO name _PU + '_CONF_new_section'; + +function _CONF_get_section(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PCONF_VALUE; cdecl; + external LIB_CRYPTO name _PU + '_CONF_get_section'; + +function _CONF_get_section_values(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Pstack_st_CONF_VALUE; cdecl; + external LIB_CRYPTO name _PU + '_CONF_get_section_values'; + +function _CONF_add_string(conf: PCONF; section: PCONF_VALUE; value: PCONF_VALUE): Integer; cdecl; + external LIB_CRYPTO name _PU + '_CONF_add_string'; + +function _CONF_get_string(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + '_CONF_get_string'; + +function _CONF_get_number(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + '_CONF_get_number'; + +function _CONF_new_data(conf: PCONF): Integer; cdecl; + external LIB_CRYPTO name _PU + '_CONF_new_data'; + +procedure _CONF_free_data(conf: PCONF); cdecl; + external LIB_CRYPTO name _PU + '_CONF_free_data'; + +function ERR_load_CT_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_CT_strings'; + +(****************************************** + * CT policy evaluation context functions * + ******************************************) +function CT_POLICY_EVAL_CTX_new(): PCT_POLICY_EVAL_CTX; cdecl; + external LIB_CRYPTO name _PU + 'CT_POLICY_EVAL_CTX_new'; + +procedure CT_POLICY_EVAL_CTX_free(ctx: PCT_POLICY_EVAL_CTX); cdecl; + external LIB_CRYPTO name _PU + 'CT_POLICY_EVAL_CTX_free'; + +function CT_POLICY_EVAL_CTX_get0_cert(ctx: PCT_POLICY_EVAL_CTX): PX509; cdecl; + external LIB_CRYPTO name _PU + 'CT_POLICY_EVAL_CTX_get0_cert'; + +function CT_POLICY_EVAL_CTX_set1_cert(ctx: PCT_POLICY_EVAL_CTX; cert: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CT_POLICY_EVAL_CTX_set1_cert'; + +function CT_POLICY_EVAL_CTX_get0_issuer(ctx: PCT_POLICY_EVAL_CTX): PX509; cdecl; + external LIB_CRYPTO name _PU + 'CT_POLICY_EVAL_CTX_get0_issuer'; + +function CT_POLICY_EVAL_CTX_set1_issuer(ctx: PCT_POLICY_EVAL_CTX; issuer: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CT_POLICY_EVAL_CTX_set1_issuer'; + +function CT_POLICY_EVAL_CTX_get0_log_store(ctx: PCT_POLICY_EVAL_CTX): PCTLOG_STORE; cdecl; + external LIB_CRYPTO name _PU + 'CT_POLICY_EVAL_CTX_get0_log_store'; + +procedure CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(ctx: PCT_POLICY_EVAL_CTX; log_store: PCTLOG_STORE); cdecl; + external LIB_CRYPTO name _PU + 'CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE'; + +function CT_POLICY_EVAL_CTX_get_time(ctx: PCT_POLICY_EVAL_CTX): UInt64; cdecl; + external LIB_CRYPTO name _PU + 'CT_POLICY_EVAL_CTX_get_time'; + +procedure CT_POLICY_EVAL_CTX_set_time(ctx: PCT_POLICY_EVAL_CTX; time_in_ms: UInt64); cdecl; + external LIB_CRYPTO name _PU + 'CT_POLICY_EVAL_CTX_set_time'; + +(***************** + * SCT functions * + *****************) +function SCT_new(): PSCT; cdecl; + external LIB_CRYPTO name _PU + 'SCT_new'; + +function SCT_new_from_base64(version: Byte; logid_base64: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; entry_type: ct_log_entry_type_t; timestamp: UInt64; extensions_base64: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; signature_base64: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PSCT; cdecl; + external LIB_CRYPTO name _PU + 'SCT_new_from_base64'; + +procedure SCT_free(sct: PSCT); cdecl; + external LIB_CRYPTO name _PU + 'SCT_free'; + +procedure SCT_LIST_free(a: Pstack_st_SCT); cdecl; + external LIB_CRYPTO name _PU + 'SCT_LIST_free'; + +function SCT_get_version(sct: PSCT): sct_version_t; cdecl; + external LIB_CRYPTO name _PU + 'SCT_get_version'; + +function SCT_set_version(sct: PSCT; version: sct_version_t): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SCT_set_version'; + +function SCT_get_log_entry_type(sct: PSCT): ct_log_entry_type_t; cdecl; + external LIB_CRYPTO name _PU + 'SCT_get_log_entry_type'; + +function SCT_set_log_entry_type(sct: PSCT; entry_type: ct_log_entry_type_t): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SCT_set_log_entry_type'; + +function SCT_get0_log_id(sct: PSCT; log_id: PPByte): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'SCT_get0_log_id'; + +function SCT_set0_log_id(sct: PSCT; log_id: PByte; log_id_len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SCT_set0_log_id'; + +function SCT_set1_log_id(sct: PSCT; log_id: PByte; log_id_len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SCT_set1_log_id'; + +function SCT_get_timestamp(sct: PSCT): UInt64; cdecl; + external LIB_CRYPTO name _PU + 'SCT_get_timestamp'; + +procedure SCT_set_timestamp(sct: PSCT; timestamp: UInt64); cdecl; + external LIB_CRYPTO name _PU + 'SCT_set_timestamp'; + +function SCT_get_signature_nid(sct: PSCT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SCT_get_signature_nid'; + +function SCT_set_signature_nid(sct: PSCT; nid: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SCT_set_signature_nid'; + +function SCT_get0_extensions(sct: PSCT; ext: PPByte): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'SCT_get0_extensions'; + +procedure SCT_set0_extensions(sct: PSCT; ext: PByte; ext_len: NativeUInt); cdecl; + external LIB_CRYPTO name _PU + 'SCT_set0_extensions'; + +function SCT_set1_extensions(sct: PSCT; ext: PByte; ext_len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SCT_set1_extensions'; + +function SCT_get0_signature(sct: PSCT; sig: PPByte): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'SCT_get0_signature'; + +procedure SCT_set0_signature(sct: PSCT; sig: PByte; sig_len: NativeUInt); cdecl; + external LIB_CRYPTO name _PU + 'SCT_set0_signature'; + +function SCT_set1_signature(sct: PSCT; sig: PByte; sig_len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SCT_set1_signature'; + +function SCT_get_source(sct: PSCT): sct_source_t; cdecl; + external LIB_CRYPTO name _PU + 'SCT_get_source'; + +function SCT_set_source(sct: PSCT; source: sct_source_t): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SCT_set_source'; + +function SCT_validation_status_string(sct: PSCT): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'SCT_validation_status_string'; + +procedure SCT_print(sct: PSCT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; indent: Integer; logs: PCTLOG_STORE); cdecl; + external LIB_CRYPTO name _PU + 'SCT_print'; + +procedure SCT_LIST_print(sct_list: Pstack_st_SCT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; indent: Integer; separator: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; logs: PCTLOG_STORE); cdecl; + external LIB_CRYPTO name _PU + 'SCT_LIST_print'; + +function SCT_get_validation_status(sct: PSCT): sct_validation_status_t; cdecl; + external LIB_CRYPTO name _PU + 'SCT_get_validation_status'; + +function SCT_validate(sct: PSCT; ctx: PCT_POLICY_EVAL_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SCT_validate'; + +function SCT_LIST_validate(scts: Pstack_st_SCT; ctx: PCT_POLICY_EVAL_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SCT_LIST_validate'; + +(********************************* + * SCT parsing and serialisation * + *********************************) +function i2o_SCT_LIST(a: Pstack_st_SCT; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2o_SCT_LIST'; + +function o2i_SCT_LIST(a: PPstack_st_SCT; pp: PPByte; len: NativeUInt): Pstack_st_SCT; cdecl; + external LIB_CRYPTO name _PU + 'o2i_SCT_LIST'; + +function i2d_SCT_LIST(a: Pstack_st_SCT; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_SCT_LIST'; + +function d2i_SCT_LIST(a: PPstack_st_SCT; pp: PPByte; len: Integer): Pstack_st_SCT; cdecl; + external LIB_CRYPTO name _PU + 'd2i_SCT_LIST'; + +function i2o_SCT(sct: PSCT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2o_SCT'; + +function o2i_SCT(psct: PPSCT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: NativeUInt): PSCT; cdecl; + external LIB_CRYPTO name _PU + 'o2i_SCT'; + +(******************** + * CT log functions * + ********************) +function CTLOG_new(public_key: PEVP_PKEY; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PCTLOG; cdecl; + external LIB_CRYPTO name _PU + 'CTLOG_new'; + +function CTLOG_new_from_base64(ct_log: PPCTLOG; pkey_base64: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CTLOG_new_from_base64'; + +procedure CTLOG_free(log: PCTLOG); cdecl; + external LIB_CRYPTO name _PU + 'CTLOG_free'; + +function CTLOG_get0_name(log: PCTLOG): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'CTLOG_get0_name'; + +procedure CTLOG_get0_log_id(log: PCTLOG; log_id: PPUInt8; log_id_len: PNativeUInt); cdecl; + external LIB_CRYPTO name _PU + 'CTLOG_get0_log_id'; + +function CTLOG_get0_public_key(log: PCTLOG): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'CTLOG_get0_public_key'; + +(************************** + * CT log store functions * + **************************) +function CTLOG_STORE_new(): PCTLOG_STORE; cdecl; + external LIB_CRYPTO name _PU + 'CTLOG_STORE_new'; + +procedure CTLOG_STORE_free(store: PCTLOG_STORE); cdecl; + external LIB_CRYPTO name _PU + 'CTLOG_STORE_free'; + +function CTLOG_STORE_get0_log_by_id(store: PCTLOG_STORE; log_id: PUInt8; log_id_len: NativeUInt): PCTLOG; cdecl; + external LIB_CRYPTO name _PU + 'CTLOG_STORE_get0_log_by_id'; + +function CTLOG_STORE_load_file(store: PCTLOG_STORE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CTLOG_STORE_load_file'; + +function CTLOG_STORE_load_default_file(store: PCTLOG_STORE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CTLOG_STORE_load_default_file'; + +function _shadow_DES_check_key(): PInteger; cdecl; + external LIB_CRYPTO name _PU + '_shadow_DES_check_key'; + +function DES_options(): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'DES_options'; + +procedure DES_ecb3_encrypt(input: Pconst_DES_cblock; output: PDES_cblock; ks1: PDES_key_schedule; ks2: PDES_key_schedule; ks3: PDES_key_schedule; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'DES_ecb3_encrypt'; + +function DES_cbc_cksum(input: PByte; output: PDES_cblock; length: Integer; schedule: PDES_key_schedule; ivec: Pconst_DES_cblock): DES_LONG; cdecl; + external LIB_CRYPTO name _PU + 'DES_cbc_cksum'; + +procedure DES_cbc_encrypt(input: PByte; output: PByte; length: Integer; schedule: PDES_key_schedule; ivec: PDES_cblock; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'DES_cbc_encrypt'; + +procedure DES_ncbc_encrypt(input: PByte; output: PByte; length: Integer; schedule: PDES_key_schedule; ivec: PDES_cblock; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'DES_ncbc_encrypt'; + +procedure DES_xcbc_encrypt(input: PByte; output: PByte; length: Integer; schedule: PDES_key_schedule; ivec: PDES_cblock; inw: Pconst_DES_cblock; outw: Pconst_DES_cblock; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'DES_xcbc_encrypt'; + +procedure DES_cfb_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; numbits: Integer; length: Integer; schedule: PDES_key_schedule; ivec: PDES_cblock; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'DES_cfb_encrypt'; + +procedure DES_ecb_encrypt(input: Pconst_DES_cblock; output: PDES_cblock; ks: PDES_key_schedule; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'DES_ecb_encrypt'; + +procedure DES_encrypt1(data: PDES_LONG; ks: PDES_key_schedule; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'DES_encrypt1'; + +procedure DES_encrypt2(data: PDES_LONG; ks: PDES_key_schedule; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'DES_encrypt2'; + +procedure DES_encrypt3(data: PDES_LONG; ks1: PDES_key_schedule; ks2: PDES_key_schedule; ks3: PDES_key_schedule); cdecl; + external LIB_CRYPTO name _PU + 'DES_encrypt3'; + +procedure DES_decrypt3(data: PDES_LONG; ks1: PDES_key_schedule; ks2: PDES_key_schedule; ks3: PDES_key_schedule); cdecl; + external LIB_CRYPTO name _PU + 'DES_decrypt3'; + +procedure DES_ede3_cbc_encrypt(input: PByte; output: PByte; length: Integer; ks1: PDES_key_schedule; ks2: PDES_key_schedule; ks3: PDES_key_schedule; ivec: PDES_cblock; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'DES_ede3_cbc_encrypt'; + +procedure DES_ede3_cfb64_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: Integer; ks1: PDES_key_schedule; ks2: PDES_key_schedule; ks3: PDES_key_schedule; ivec: PDES_cblock; num: PInteger; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'DES_ede3_cfb64_encrypt'; + +procedure DES_ede3_cfb_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; numbits: Integer; length: Integer; ks1: PDES_key_schedule; ks2: PDES_key_schedule; ks3: PDES_key_schedule; ivec: PDES_cblock; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'DES_ede3_cfb_encrypt'; + +procedure DES_ede3_ofb64_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: Integer; ks1: PDES_key_schedule; ks2: PDES_key_schedule; ks3: PDES_key_schedule; ivec: PDES_cblock; num: PInteger); cdecl; + external LIB_CRYPTO name _PU + 'DES_ede3_ofb64_encrypt'; + +function DES_fcrypt(buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; salt: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ret: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'DES_fcrypt'; + +function DES_crypt(buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; salt: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'DES_crypt'; + +procedure DES_ofb_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; numbits: Integer; length: Integer; schedule: PDES_key_schedule; ivec: PDES_cblock); cdecl; + external LIB_CRYPTO name _PU + 'DES_ofb_encrypt'; + +procedure DES_pcbc_encrypt(input: PByte; output: PByte; length: Integer; schedule: PDES_key_schedule; ivec: PDES_cblock; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'DES_pcbc_encrypt'; + +function DES_quad_cksum(input: PByte; output: PDES_cblock; length: Integer; out_count: Integer; seed: PDES_cblock): DES_LONG; cdecl; + external LIB_CRYPTO name _PU + 'DES_quad_cksum'; + +function DES_random_key(ret: PDES_cblock): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DES_random_key'; + +procedure DES_set_odd_parity(key: PDES_cblock); cdecl; + external LIB_CRYPTO name _PU + 'DES_set_odd_parity'; +procedure DES_fixup_key_parity(key: PDES_cblock); cdecl; + external LIB_CRYPTO name _PU + 'DES_set_odd_parity'; + +function DES_check_key_parity(key: Pconst_DES_cblock): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DES_check_key_parity'; + +function DES_is_weak_key(key: Pconst_DES_cblock): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DES_is_weak_key'; + +function DES_set_key(key: Pconst_DES_cblock; schedule: PDES_key_schedule): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DES_set_key'; + +function DES_key_sched(key: Pconst_DES_cblock; schedule: PDES_key_schedule): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DES_key_sched'; + +function DES_set_key_checked(key: Pconst_DES_cblock; schedule: PDES_key_schedule): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DES_set_key_checked'; + +procedure DES_set_key_unchecked(key: Pconst_DES_cblock; schedule: PDES_key_schedule); cdecl; + external LIB_CRYPTO name _PU + 'DES_set_key_unchecked'; + +procedure DES_string_to_key(str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; key: PDES_cblock); cdecl; + external LIB_CRYPTO name _PU + 'DES_string_to_key'; + +procedure DES_string_to_2keys(str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; key1: PDES_cblock; key2: PDES_cblock); cdecl; + external LIB_CRYPTO name _PU + 'DES_string_to_2keys'; + +procedure DES_cfb64_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: Integer; schedule: PDES_key_schedule; ivec: PDES_cblock; num: PInteger; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'DES_cfb64_encrypt'; + +procedure DES_ofb64_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: Integer; schedule: PDES_key_schedule; ivec: PDES_cblock; num: PInteger); cdecl; + external LIB_CRYPTO name _PU + 'DES_ofb64_encrypt'; + +function _openssl_ebcdic2ascii(dest: Pointer; srce: Pointer; count: NativeUInt): Pointer; cdecl; + external LIB_CRYPTO name _PU + '_openssl_ebcdic2ascii'; + +function _openssl_ascii2ebcdic(dest: Pointer; srce: Pointer; count: NativeUInt): Pointer; cdecl; + external LIB_CRYPTO name _PU + '_openssl_ascii2ebcdic'; + +function ERR_load_RAND_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_RAND_strings'; + +function RAND_set_rand_method(meth: PRAND_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_set_rand_method'; + +function RAND_get_rand_method(): PRAND_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'RAND_get_rand_method'; + +function RAND_set_rand_engine(engine: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_set_rand_engine'; + +function RAND_OpenSSL(): PRAND_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'RAND_OpenSSL'; + +function RAND_bytes(buf: PByte; num: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_bytes'; + +function RAND_priv_bytes(buf: PByte; num: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_priv_bytes'; + +function RAND_pseudo_bytes(buf: PByte; num: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_pseudo_bytes'; + +procedure RAND_seed(buf: Pointer; num: Integer); cdecl; + external LIB_CRYPTO name _PU + 'RAND_seed'; + +procedure RAND_keep_random_devices_open(keep: Integer); cdecl; + external LIB_CRYPTO name _PU + 'RAND_keep_random_devices_open'; + +procedure RAND_add(buf: Pointer; num: Integer; randomness: Double); cdecl; + external LIB_CRYPTO name _PU + 'RAND_add'; + +function RAND_load_file({$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; max_bytes: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_load_file'; + +function RAND_write_file({$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_write_file'; + +function RAND_file_name({$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; num: NativeUInt): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'RAND_file_name'; + +function RAND_status(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_status'; + +function RAND_poll(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_poll'; + +function ERR_load_PEM_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_PEM_strings'; + +function PEM_get_EVP_CIPHER_INFO(header: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cipher: PEVP_CIPHER_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_get_EVP_CIPHER_INFO'; + +function PEM_do_header(cipher: PEVP_CIPHER_INFO; data: PByte; len: PInteger; callback: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_do_header'; + +function PEM_read_bio(bp: PBIO; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; header: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; data: PPByte; len: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio'; + +function PEM_read_bio_ex(bp: PBIO; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; header: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; data: PPByte; len: PInteger; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_ex'; + +function PEM_bytes_read_bio_secmem(pdata: PPByte; plen: PInteger; pnm: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; bp: PBIO; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_bytes_read_bio_secmem'; + +function PEM_write_bio(bp: PBIO; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; hdr: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; data: PByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio'; + +function PEM_bytes_read_bio(pdata: PPByte; plen: PInteger; pnm: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; bp: PBIO; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_bytes_read_bio'; + +function PEM_ASN1_read_bio(d2i: Pd2i_of_void; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; bp: PBIO; x: PPointer; cb: Ppem_password_cb; u: Pointer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_ASN1_read_bio'; + +function PEM_ASN1_write_bio(i2d: Pi2d_of_void; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; bp: PBIO; x: Pointer; enc: PEVP_CIPHER; kstr: PByte; klen: Integer; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_ASN1_write_bio'; + +function PEM_X509_INFO_read_bio(bp: PBIO; sk: Pstack_st_X509_INFO; cb: Ppem_password_cb; u: Pointer): Pstack_st_X509_INFO; cdecl; + external LIB_CRYPTO name _PU + 'PEM_X509_INFO_read_bio'; + +function PEM_X509_INFO_write_bio(bp: PBIO; xi: PX509_INFO; enc: PEVP_CIPHER; kstr: PByte; klen: Integer; cd: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_X509_INFO_write_bio'; + +function PEM_read(fp: PPointer; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; header: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; data: PPByte; len: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read'; + +function PEM_write(fp: PPointer; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; hdr: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; data: PByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write'; + +function PEM_ASN1_read(d2i: Pd2i_of_void; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; fp: PPointer; x: PPointer; cb: Ppem_password_cb; u: Pointer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_ASN1_read'; + +function PEM_ASN1_write(i2d: Pi2d_of_void; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; fp: PPointer; x: Pointer; enc: PEVP_CIPHER; kstr: PByte; klen: Integer; callback: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_ASN1_write'; + +function PEM_X509_INFO_read(fp: PPointer; sk: Pstack_st_X509_INFO; cb: Ppem_password_cb; u: Pointer): Pstack_st_X509_INFO; cdecl; + external LIB_CRYPTO name _PU + 'PEM_X509_INFO_read'; + +function PEM_SignInit(ctx: PEVP_MD_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_SignInit'; + +function PEM_SignUpdate(ctx: PEVP_MD_CTX; d: PByte; cnt: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_SignUpdate'; + +function PEM_SignFinal(ctx: PEVP_MD_CTX; sigret: PByte; siglen: PCardinal; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_SignFinal'; + +function PEM_def_callback(buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; num: Integer; rwflag: Integer; userdata: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_def_callback'; + +procedure PEM_proc_type(buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer); cdecl; + external LIB_CRYPTO name _PU + 'PEM_proc_type'; + +procedure PEM_dek_info(buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: Integer; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}); cdecl; + external LIB_CRYPTO name _PU + 'PEM_dek_info'; + +function PEM_read_bio_X509(bp: PBIO; x: PPX509; cb: Ppem_password_cb; u: Pointer): PX509; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_X509'; + +function PEM_read_X509(fp: PPointer; x: PPX509; cb: Ppem_password_cb; u: Pointer): PX509; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_X509'; + +function PEM_write_bio_X509(bp: PBIO; x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_X509'; + +function PEM_write_X509(fp: PPointer; x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_X509'; + +function PEM_read_bio_X509_AUX(bp: PBIO; x: PPX509; cb: Ppem_password_cb; u: Pointer): PX509; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_X509_AUX'; + +function PEM_read_X509_AUX(fp: PPointer; x: PPX509; cb: Ppem_password_cb; u: Pointer): PX509; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_X509_AUX'; + +function PEM_write_bio_X509_AUX(bp: PBIO; x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_X509_AUX'; + +function PEM_write_X509_AUX(fp: PPointer; x: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_X509_AUX'; + +function PEM_read_bio_X509_REQ(bp: PBIO; x: PPX509_REQ; cb: Ppem_password_cb; u: Pointer): PX509_REQ; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_X509_REQ'; + +function PEM_read_X509_REQ(fp: PPointer; x: PPX509_REQ; cb: Ppem_password_cb; u: Pointer): PX509_REQ; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_X509_REQ'; + +function PEM_write_bio_X509_REQ(bp: PBIO; x: PX509_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_X509_REQ'; + +function PEM_write_X509_REQ(fp: PPointer; x: PX509_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_X509_REQ'; + +function PEM_write_bio_X509_REQ_NEW(bp: PBIO; x: PX509_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_X509_REQ_NEW'; + +function PEM_write_X509_REQ_NEW(fp: PPointer; x: PX509_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_X509_REQ_NEW'; + +function PEM_read_bio_X509_CRL(bp: PBIO; x: PPX509_CRL; cb: Ppem_password_cb; u: Pointer): PX509_CRL; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_X509_CRL'; + +function PEM_read_X509_CRL(fp: PPointer; x: PPX509_CRL; cb: Ppem_password_cb; u: Pointer): PX509_CRL; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_X509_CRL'; + +function PEM_write_bio_X509_CRL(bp: PBIO; x: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_X509_CRL'; + +function PEM_write_X509_CRL(fp: PPointer; x: PX509_CRL): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_X509_CRL'; + +function PEM_read_bio_PKCS7(bp: PBIO; x: PPPKCS7; cb: Ppem_password_cb; u: Pointer): PPKCS7; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_PKCS7'; + +function PEM_read_PKCS7(fp: PPointer; x: PPPKCS7; cb: Ppem_password_cb; u: Pointer): PPKCS7; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_PKCS7'; + +function PEM_write_bio_PKCS7(bp: PBIO; x: PPKCS7): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_PKCS7'; + +function PEM_write_PKCS7(fp: PPointer; x: PPKCS7): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_PKCS7'; + +function PEM_read_bio_NETSCAPE_CERT_SEQUENCE(bp: PBIO; x: PPNETSCAPE_CERT_SEQUENCE; cb: Ppem_password_cb; u: Pointer): PNETSCAPE_CERT_SEQUENCE; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_NETSCAPE_CERT_SEQUENCE'; + +function PEM_read_NETSCAPE_CERT_SEQUENCE(fp: PPointer; x: PPNETSCAPE_CERT_SEQUENCE; cb: Ppem_password_cb; u: Pointer): PNETSCAPE_CERT_SEQUENCE; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_NETSCAPE_CERT_SEQUENCE'; + +function PEM_write_bio_NETSCAPE_CERT_SEQUENCE(bp: PBIO; x: PNETSCAPE_CERT_SEQUENCE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_NETSCAPE_CERT_SEQUENCE'; + +function PEM_write_NETSCAPE_CERT_SEQUENCE(fp: PPointer; x: PNETSCAPE_CERT_SEQUENCE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_NETSCAPE_CERT_SEQUENCE'; + +function PEM_read_bio_PKCS8(bp: PBIO; x: PPX509_SIG; cb: Ppem_password_cb; u: Pointer): PX509_SIG; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_PKCS8'; + +function PEM_read_PKCS8(fp: PPointer; x: PPX509_SIG; cb: Ppem_password_cb; u: Pointer): PX509_SIG; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_PKCS8'; + +function PEM_write_bio_PKCS8(bp: PBIO; x: PX509_SIG): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_PKCS8'; + +function PEM_write_PKCS8(fp: PPointer; x: PX509_SIG): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_PKCS8'; + +function PEM_read_bio_PKCS8_PRIV_KEY_INFO(bp: PBIO; x: PPPKCS8_PRIV_KEY_INFO; cb: Ppem_password_cb; u: Pointer): PPKCS8_PRIV_KEY_INFO; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_PKCS8_PRIV_KEY_INFO'; + +function PEM_read_PKCS8_PRIV_KEY_INFO(fp: PPointer; x: PPPKCS8_PRIV_KEY_INFO; cb: Ppem_password_cb; u: Pointer): PPKCS8_PRIV_KEY_INFO; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_PKCS8_PRIV_KEY_INFO'; + +function PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp: PBIO; x: PPKCS8_PRIV_KEY_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_PKCS8_PRIV_KEY_INFO'; + +function PEM_write_PKCS8_PRIV_KEY_INFO(fp: PPointer; x: PPKCS8_PRIV_KEY_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_PKCS8_PRIV_KEY_INFO'; + +function PEM_read_bio_RSAPrivateKey(bp: PBIO; x: PPRSA; cb: Ppem_password_cb; u: Pointer): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_RSAPrivateKey'; + +function PEM_read_RSAPrivateKey(fp: PPointer; x: PPRSA; cb: Ppem_password_cb; u: Pointer): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_RSAPrivateKey'; + +function PEM_write_bio_RSAPrivateKey(bp: PBIO; x: PRSA; enc: PEVP_CIPHER; kstr: PByte; klen: Integer; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_RSAPrivateKey'; + +function PEM_write_RSAPrivateKey(fp: PPointer; x: PRSA; enc: PEVP_CIPHER; kstr: PByte; klen: Integer; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_RSAPrivateKey'; + +function PEM_read_bio_RSAPublicKey(bp: PBIO; x: PPRSA; cb: Ppem_password_cb; u: Pointer): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_RSAPublicKey'; + +function PEM_read_RSAPublicKey(fp: PPointer; x: PPRSA; cb: Ppem_password_cb; u: Pointer): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_RSAPublicKey'; + +function PEM_write_bio_RSAPublicKey(bp: PBIO; x: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_RSAPublicKey'; + +function PEM_write_RSAPublicKey(fp: PPointer; x: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_RSAPublicKey'; + +function PEM_read_bio_RSA_PUBKEY(bp: PBIO; x: PPRSA; cb: Ppem_password_cb; u: Pointer): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_RSA_PUBKEY'; + +function PEM_read_RSA_PUBKEY(fp: PPointer; x: PPRSA; cb: Ppem_password_cb; u: Pointer): PRSA; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_RSA_PUBKEY'; + +function PEM_write_bio_RSA_PUBKEY(bp: PBIO; x: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_RSA_PUBKEY'; + +function PEM_write_RSA_PUBKEY(fp: PPointer; x: PRSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_RSA_PUBKEY'; + +function PEM_read_bio_DSAPrivateKey(bp: PBIO; x: PPDSA; cb: Ppem_password_cb; u: Pointer): PDSA; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_DSAPrivateKey'; + +function PEM_read_DSAPrivateKey(fp: PPointer; x: PPDSA; cb: Ppem_password_cb; u: Pointer): PDSA; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_DSAPrivateKey'; + +function PEM_write_bio_DSAPrivateKey(bp: PBIO; x: PDSA; enc: PEVP_CIPHER; kstr: PByte; klen: Integer; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_DSAPrivateKey'; + +function PEM_write_DSAPrivateKey(fp: PPointer; x: PDSA; enc: PEVP_CIPHER; kstr: PByte; klen: Integer; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_DSAPrivateKey'; + +function PEM_read_bio_DSA_PUBKEY(bp: PBIO; x: PPDSA; cb: Ppem_password_cb; u: Pointer): PDSA; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_DSA_PUBKEY'; + +function PEM_read_DSA_PUBKEY(fp: PPointer; x: PPDSA; cb: Ppem_password_cb; u: Pointer): PDSA; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_DSA_PUBKEY'; + +function PEM_write_bio_DSA_PUBKEY(bp: PBIO; x: PDSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_DSA_PUBKEY'; + +function PEM_write_DSA_PUBKEY(fp: PPointer; x: PDSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_DSA_PUBKEY'; + +function PEM_read_bio_DSAparams(bp: PBIO; x: PPDSA; cb: Ppem_password_cb; u: Pointer): PDSA; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_DSAparams'; + +function PEM_read_DSAparams(fp: PPointer; x: PPDSA; cb: Ppem_password_cb; u: Pointer): PDSA; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_DSAparams'; + +function PEM_write_bio_DSAparams(bp: PBIO; x: PDSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_DSAparams'; + +function PEM_write_DSAparams(fp: PPointer; x: PDSA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_DSAparams'; + +function PEM_read_bio_ECPKParameters(bp: PBIO; x: PPEC_GROUP; cb: Ppem_password_cb; u: Pointer): PEC_GROUP; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_ECPKParameters'; + +function PEM_read_ECPKParameters(fp: PPointer; x: PPEC_GROUP; cb: Ppem_password_cb; u: Pointer): PEC_GROUP; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_ECPKParameters'; + +function PEM_write_bio_ECPKParameters(bp: PBIO; x: PEC_GROUP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_ECPKParameters'; + +function PEM_write_ECPKParameters(fp: PPointer; x: PEC_GROUP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_ECPKParameters'; + +function PEM_read_bio_ECPrivateKey(bp: PBIO; x: PPEC_KEY; cb: Ppem_password_cb; u: Pointer): PEC_KEY; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_ECPrivateKey'; + +function PEM_read_ECPrivateKey(fp: PPointer; x: PPEC_KEY; cb: Ppem_password_cb; u: Pointer): PEC_KEY; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_ECPrivateKey'; + +function PEM_write_bio_ECPrivateKey(bp: PBIO; x: PEC_KEY; enc: PEVP_CIPHER; kstr: PByte; klen: Integer; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_ECPrivateKey'; + +function PEM_write_ECPrivateKey(fp: PPointer; x: PEC_KEY; enc: PEVP_CIPHER; kstr: PByte; klen: Integer; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_ECPrivateKey'; + +function PEM_read_bio_EC_PUBKEY(bp: PBIO; x: PPEC_KEY; cb: Ppem_password_cb; u: Pointer): PEC_KEY; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_EC_PUBKEY'; + +function PEM_read_EC_PUBKEY(fp: PPointer; x: PPEC_KEY; cb: Ppem_password_cb; u: Pointer): PEC_KEY; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_EC_PUBKEY'; + +function PEM_write_bio_EC_PUBKEY(bp: PBIO; x: PEC_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_EC_PUBKEY'; + +function PEM_write_EC_PUBKEY(fp: PPointer; x: PEC_KEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_EC_PUBKEY'; + +function PEM_read_bio_DHparams(bp: PBIO; x: PPDH; cb: Ppem_password_cb; u: Pointer): PDH; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_DHparams'; + +function PEM_read_DHparams(fp: PPointer; x: PPDH; cb: Ppem_password_cb; u: Pointer): PDH; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_DHparams'; + +function PEM_write_bio_DHparams(bp: PBIO; x: PDH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_DHparams'; + +function PEM_write_DHparams(fp: PPointer; x: PDH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_DHparams'; + +function PEM_write_bio_DHxparams(bp: PBIO; x: PDH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_DHxparams'; + +function PEM_write_DHxparams(fp: PPointer; x: PDH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_DHxparams'; + +function PEM_read_bio_PrivateKey(bp: PBIO; x: PPEVP_PKEY; cb: Ppem_password_cb; u: Pointer): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_PrivateKey'; + +function PEM_read_PrivateKey(fp: PPointer; x: PPEVP_PKEY; cb: Ppem_password_cb; u: Pointer): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_PrivateKey'; + +function PEM_write_bio_PrivateKey(bp: PBIO; x: PEVP_PKEY; enc: PEVP_CIPHER; kstr: PByte; klen: Integer; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_PrivateKey'; + +function PEM_write_PrivateKey(fp: PPointer; x: PEVP_PKEY; enc: PEVP_CIPHER; kstr: PByte; klen: Integer; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_PrivateKey'; + +function PEM_read_bio_PUBKEY(bp: PBIO; x: PPEVP_PKEY; cb: Ppem_password_cb; u: Pointer): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_PUBKEY'; + +function PEM_read_PUBKEY(fp: PPointer; x: PPEVP_PKEY; cb: Ppem_password_cb; u: Pointer): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_PUBKEY'; + +function PEM_write_bio_PUBKEY(bp: PBIO; x: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_PUBKEY'; + +function PEM_write_PUBKEY(fp: PPointer; x: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_PUBKEY'; + +function PEM_write_bio_PrivateKey_traditional(bp: PBIO; x: PEVP_PKEY; enc: PEVP_CIPHER; kstr: PByte; klen: Integer; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_PrivateKey_traditional'; + +function PEM_write_bio_PKCS8PrivateKey_nid(bp: PBIO; x: PEVP_PKEY; nid: Integer; kstr: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; klen: Integer; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_PKCS8PrivateKey_nid'; + +function PEM_write_bio_PKCS8PrivateKey(p1: PBIO; p2: PEVP_PKEY; p3: PEVP_CIPHER; p4: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; p5: Integer; p6: Ppem_password_cb; p7: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_PKCS8PrivateKey'; + +function i2d_PKCS8PrivateKey_bio(bp: PBIO; x: PEVP_PKEY; enc: PEVP_CIPHER; kstr: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; klen: Integer; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS8PrivateKey_bio'; + +function i2d_PKCS8PrivateKey_nid_bio(bp: PBIO; x: PEVP_PKEY; nid: Integer; kstr: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; klen: Integer; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS8PrivateKey_nid_bio'; + +function d2i_PKCS8PrivateKey_bio(bp: PBIO; x: PPEVP_PKEY; cb: Ppem_password_cb; u: Pointer): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS8PrivateKey_bio'; + +function i2d_PKCS8PrivateKey_fp(fp: PPointer; x: PEVP_PKEY; enc: PEVP_CIPHER; kstr: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; klen: Integer; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS8PrivateKey_fp'; + +function i2d_PKCS8PrivateKey_nid_fp(fp: PPointer; x: PEVP_PKEY; nid: Integer; kstr: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; klen: Integer; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS8PrivateKey_nid_fp'; + +function PEM_write_PKCS8PrivateKey_nid(fp: PPointer; x: PEVP_PKEY; nid: Integer; kstr: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; klen: Integer; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_PKCS8PrivateKey_nid'; + +function d2i_PKCS8PrivateKey_fp(fp: PPointer; x: PPEVP_PKEY; cb: Ppem_password_cb; u: Pointer): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS8PrivateKey_fp'; + +function PEM_write_PKCS8PrivateKey(fp: PPointer; x: PEVP_PKEY; enc: PEVP_CIPHER; kstr: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; klen: Integer; cd: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_PKCS8PrivateKey'; + +function PEM_read_bio_Parameters(bp: PBIO; x: PPEVP_PKEY): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'PEM_read_bio_Parameters'; + +function PEM_write_bio_Parameters(bp: PBIO; x: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PEM_write_bio_Parameters'; + +function b2i_PrivateKey({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; length: Integer): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'b2i_PrivateKey'; + +function b2i_PublicKey({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; length: Integer): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'b2i_PublicKey'; + +function b2i_PrivateKey_bio({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'b2i_PrivateKey_bio'; + +function b2i_PublicKey_bio({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'b2i_PublicKey_bio'; + +function i2b_PrivateKey_bio({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; pk: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2b_PrivateKey_bio'; + +function i2b_PublicKey_bio({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; pk: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2b_PublicKey_bio'; + +function b2i_PVK_bio({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO; cb: Ppem_password_cb; u: Pointer): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'b2i_PVK_bio'; + +function i2b_PVK_bio({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; pk: PEVP_PKEY; enclevel: Integer; cb: Ppem_password_cb; u: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2b_PVK_bio'; + +function ERR_load_UI_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_UI_strings'; + +function UI_new(): PUI; cdecl; + external LIB_CRYPTO name _PU + 'UI_new'; + +function UI_new_method(method: PUI_METHOD): PUI; cdecl; + external LIB_CRYPTO name _PU + 'UI_new_method'; + +procedure UI_free(ui: PUI); cdecl; + external LIB_CRYPTO name _PU + 'UI_free'; + +function UI_add_input_string(ui: PUI; prompt: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; flags: Integer; result_buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; minsize: Integer; maxsize: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_add_input_string'; + +function UI_dup_input_string(ui: PUI; prompt: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; flags: Integer; result_buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; minsize: Integer; maxsize: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_dup_input_string'; + +function UI_add_verify_string(ui: PUI; prompt: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; flags: Integer; result_buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; minsize: Integer; maxsize: Integer; test_buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_add_verify_string'; + +function UI_dup_verify_string(ui: PUI; prompt: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; flags: Integer; result_buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; minsize: Integer; maxsize: Integer; test_buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_dup_verify_string'; + +function UI_add_input_boolean(ui: PUI; prompt: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; action_desc: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ok_chars: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cancel_chars: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; flags: Integer; result_buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_add_input_boolean'; + +function UI_dup_input_boolean(ui: PUI; prompt: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; action_desc: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ok_chars: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cancel_chars: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; flags: Integer; result_buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_dup_input_boolean'; + +function UI_add_info_string(ui: PUI; text: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_add_info_string'; + +function UI_dup_info_string(ui: PUI; text: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_dup_info_string'; + +function UI_add_error_string(ui: PUI; text: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_add_error_string'; + +function UI_dup_error_string(ui: PUI; text: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_dup_error_string'; + +function UI_construct_prompt(ui_method: PUI; object_desc: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; object_name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'UI_construct_prompt'; + +function UI_add_user_data(ui: PUI; user_data: Pointer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'UI_add_user_data'; + +function UI_dup_user_data(ui: PUI; user_data: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_dup_user_data'; + +function UI_get0_user_data(ui: PUI): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'UI_get0_user_data'; + +function UI_get0_result(ui: PUI; i: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'UI_get0_result'; + +function UI_get_result_length(ui: PUI; i: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_get_result_length'; + +function UI_process(ui: PUI): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_process'; + +type + UI_ctrl_f = procedure(); cdecl; + +function UI_ctrl(ui: PUI; cmd: Integer; i: Integer; p: Pointer; f: UI_ctrl_f): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_ctrl'; + +function UI_set_ex_data(r: PUI; idx: Integer; arg: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_set_ex_data'; + +function UI_get_ex_data(r: PUI; idx: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'UI_get_ex_data'; + +procedure UI_set_default_method(meth: PUI_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'UI_set_default_method'; + +function UI_get_default_method(): PUI_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'UI_get_default_method'; + +function UI_get_method(ui: PUI): PUI_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'UI_get_method'; + +function UI_set_method(ui: PUI; meth: PUI_METHOD): PUI_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'UI_set_method'; + +function UI_OpenSSL(): PUI_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'UI_OpenSSL'; + +function UI_null(): PUI_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'UI_null'; + +function UI_create_method(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PUI_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'UI_create_method'; + +procedure UI_destroy_method(ui_method: PUI_METHOD); cdecl; + external LIB_CRYPTO name _PU + 'UI_destroy_method'; + +type + UI_method_set_opener_opener = function(ui: PUI): Integer; cdecl; + +function UI_method_set_opener(method: PUI_METHOD; opener: UI_method_set_opener_opener): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_method_set_opener'; + +type + UI_method_set_writer_writer = function(ui: PUI; uis: PUI_STRING): Integer; cdecl; + +function UI_method_set_writer(method: PUI_METHOD; writer: UI_method_set_writer_writer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_method_set_writer'; + +type + UI_method_set_flusher_flusher = function(ui: PUI): Integer; cdecl; + +function UI_method_set_flusher(method: PUI_METHOD; flusher: UI_method_set_flusher_flusher): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_method_set_flusher'; + +type + UI_method_set_reader_reader = function(ui: PUI; uis: PUI_STRING): Integer; cdecl; + +function UI_method_set_reader(method: PUI_METHOD; reader: UI_method_set_reader_reader): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_method_set_reader'; + +type + UI_method_set_closer_closer = function(ui: PUI): Integer; cdecl; + +function UI_method_set_closer(method: PUI_METHOD; closer: UI_method_set_closer_closer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_method_set_closer'; + +type + UI_method_set_data_duplicator_duplicator = function(ui: PUI; ui_data: Pointer): Pointer; cdecl; + +type + UI_method_set_data_duplicator_destructor = procedure(ui: PUI; ui_data: Pointer); cdecl; + +function UI_method_set_data_duplicator(method: PUI_METHOD; duplicator: UI_method_set_data_duplicator_duplicator; {$IFNDEF FPC}{$IF CompilerVersion > 21}&destructor{$ELSE}destructor1{$IFEND}{$ELSE}&destructor{$ENDIF}: UI_method_set_data_duplicator_destructor): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_method_set_data_duplicator'; + +type + UI_method_set_prompt_constructor_prompt_constructor = function(ui: PUI; object_desc: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; object_name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + +function UI_method_set_prompt_constructor(method: PUI_METHOD; prompt_constructor: UI_method_set_prompt_constructor_prompt_constructor): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_method_set_prompt_constructor'; + +function UI_method_set_ex_data(method: PUI_METHOD; idx: Integer; data: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_method_set_ex_data'; + +//function UI_method_get_opener(p1: PUImethod: PUI_METHOD): Integer { TODO : Cannot convert original type "int (*)(UI *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'UI_method_get_opener'; + +//function UI_method_get_writer(p1: PUIp2: PUI_STRINGmethod: PUI_METHOD): Integer { TODO : Cannot convert original type "int (*)(UI *, UI_STRING *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'UI_method_get_writer'; + +//function UI_method_get_flusher(p1: PUImethod: PUI_METHOD): Integer { TODO : Cannot convert original type "int (*)(UI *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'UI_method_get_flusher'; + +//function UI_method_get_reader(p1: PUIp2: PUI_STRINGmethod: PUI_METHOD): Integer { TODO : Cannot convert original type "int (*)(UI *, UI_STRING *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'UI_method_get_reader'; + +//function UI_method_get_closer(p1: PUImethod: PUI_METHOD): Integer { TODO : Cannot convert original type "int (*)(UI *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'UI_method_get_closer'; + +//function UI_method_get_prompt_constructor(p1: PUIp2: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}p3: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}method: PUI_METHOD): Integer { TODO : Cannot convert original type "char *(*)(UI *, const char *, const char *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'UI_method_get_prompt_constructor'; + +//function UI_method_get_data_duplicator(p1: PUIp2: Pointermethod: PUI_METHOD): Integer { TODO : Cannot convert original type "void *(*)(UI *, void *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'UI_method_get_data_duplicator'; + +//function UI_method_get_data_destructor(p1: PUIp2: Pointermethod: PUI_METHOD): Integer { TODO : Cannot convert original type "void (*)(UI *, void *)" }; cdecl; +// external LIB_CRYPTO name _PU + 'UI_method_get_data_destructor'; + +function UI_method_get_ex_data(method: PUI_METHOD; idx: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'UI_method_get_ex_data'; + +function UI_get_string_type(uis: PUI_STRING): UI_string_types; cdecl; + external LIB_CRYPTO name _PU + 'UI_get_string_type'; + +function UI_get_input_flags(uis: PUI_STRING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_get_input_flags'; + +function UI_get0_output_string(uis: PUI_STRING): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'UI_get0_output_string'; + +function UI_get0_action_string(uis: PUI_STRING): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'UI_get0_action_string'; + +function UI_get0_result_string(uis: PUI_STRING): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'UI_get0_result_string'; + +function UI_get_result_string_length(uis: PUI_STRING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_get_result_string_length'; + +function UI_get0_test_string(uis: PUI_STRING): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'UI_get0_test_string'; + +function UI_get_result_minsize(uis: PUI_STRING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_get_result_minsize'; + +function UI_get_result_maxsize(uis: PUI_STRING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_get_result_maxsize'; + +function UI_set_result(ui: PUI; uis: PUI_STRING; result: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_set_result'; + +function UI_set_result_ex(ui: PUI; uis: PUI_STRING; result: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_set_result_ex'; + +function UI_UTIL_read_pw_string(buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; length: Integer; prompt: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; verify: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_UTIL_read_pw_string'; + +function UI_UTIL_read_pw(buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; buff: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; size: Integer; prompt: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; verify: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'UI_UTIL_read_pw'; + +function UI_UTIL_wrap_read_pem_callback(cb: Ppem_password_cb; rwflag: Integer): PUI_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'UI_UTIL_wrap_read_pem_callback'; + +procedure ERR_put_error(lib: Integer; func: Integer; reason: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; line: Integer); cdecl; + external LIB_CRYPTO name _PU + 'ERR_put_error'; + +procedure ERR_set_error_data(data: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; flags: Integer); cdecl; + external LIB_CRYPTO name _PU + 'ERR_set_error_data'; + +function ERR_get_error(): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'ERR_get_error'; + +function ERR_get_error_line({$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; line: PInteger): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'ERR_get_error_line'; + +function ERR_get_error_line_data({$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; line: PInteger; data: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; flags: PInteger): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'ERR_get_error_line_data'; + +function ERR_peek_error(): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'ERR_peek_error'; + +function ERR_peek_error_line({$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; line: PInteger): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'ERR_peek_error_line'; + +function ERR_peek_error_line_data({$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; line: PInteger; data: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; flags: PInteger): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'ERR_peek_error_line_data'; + +function ERR_peek_last_error(): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'ERR_peek_last_error'; + +function ERR_peek_last_error_line({$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; line: PInteger): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'ERR_peek_last_error_line'; + +function ERR_peek_last_error_line_data({$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; line: PInteger; data: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; flags: PInteger): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'ERR_peek_last_error_line_data'; + +procedure ERR_clear_error(); cdecl; + external LIB_CRYPTO name _PU + 'ERR_clear_error'; + +function ERR_error_string(e: Cardinal; buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'ERR_error_string'; + +procedure ERR_error_string_n(e: Cardinal; buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: NativeUInt); cdecl; + external LIB_CRYPTO name _PU + 'ERR_error_string_n'; + +function ERR_lib_error_string(e: Cardinal): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'ERR_lib_error_string'; + +function ERR_func_error_string(e: Cardinal): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'ERR_func_error_string'; + +function ERR_reason_error_string(e: Cardinal): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'ERR_reason_error_string'; + +type + ERR_print_errors_cb_cb = function(str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: NativeUInt; u: Pointer): Integer; cdecl; + +procedure ERR_print_errors_cb(cb: ERR_print_errors_cb_cb; u: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'ERR_print_errors_cb'; + +procedure ERR_print_errors_fp(fp: PPointer); cdecl; + external LIB_CRYPTO name _PU + 'ERR_print_errors_fp'; + +procedure ERR_print_errors(bp: PBIO); cdecl; + external LIB_CRYPTO name _PU + 'ERR_print_errors'; + +procedure ERR_add_error_data(num: Integer) varargs; cdecl; + external LIB_CRYPTO name _PU + 'ERR_add_error_data'; + +procedure ERR_add_error_vdata(num: Integer; args: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'ERR_add_error_vdata'; + +function ERR_load_strings(lib: Integer; str: PERR_STRING_DATA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_strings'; + +function ERR_load_strings_const(str: PERR_STRING_DATA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_strings_const'; + +function ERR_unload_strings(lib: Integer; str: PERR_STRING_DATA): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_unload_strings'; + +function ERR_load_ERR_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_ERR_strings'; + +procedure ERR_remove_thread_state(p1: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'ERR_remove_thread_state'; + +procedure ERR_remove_state(pid: Cardinal); cdecl; + external LIB_CRYPTO name _PU + 'ERR_remove_state'; + +function ERR_get_state(): PERR_STATE; cdecl; + external LIB_CRYPTO name _PU + 'ERR_get_state'; + +function ERR_get_next_error_library(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_get_next_error_library'; + +function ERR_set_mark(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_set_mark'; + +function ERR_pop_to_mark(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_pop_to_mark'; + +function ERR_clear_last_mark(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_clear_last_mark'; + +function ERR_load_ENGINE_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_ENGINE_strings'; + +function ENGINE_get_first(): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_first'; + +function ENGINE_get_last(): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_last'; + +function ENGINE_get_next(e: PENGINE): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_next'; + +function ENGINE_get_prev(e: PENGINE): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_prev'; + +function ENGINE_add(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_add'; + +function ENGINE_remove(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_remove'; + +function ENGINE_by_id(id: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_by_id'; + +procedure ENGINE_load_builtin_engines(); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_load_builtin_engines'; + +function ENGINE_get_table_flags(): Cardinal; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_table_flags'; + +procedure ENGINE_set_table_flags(flags: Cardinal); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_table_flags'; + +function ENGINE_register_RSA(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_RSA'; + +procedure ENGINE_unregister_RSA(e: PENGINE); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_unregister_RSA'; + +procedure ENGINE_register_all_RSA(); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_all_RSA'; + +function ENGINE_register_DSA(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_DSA'; + +procedure ENGINE_unregister_DSA(e: PENGINE); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_unregister_DSA'; + +procedure ENGINE_register_all_DSA(); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_all_DSA'; + +function ENGINE_register_EC(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_EC'; + +procedure ENGINE_unregister_EC(e: PENGINE); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_unregister_EC'; + +procedure ENGINE_register_all_EC(); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_all_EC'; + +function ENGINE_register_DH(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_DH'; + +procedure ENGINE_unregister_DH(e: PENGINE); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_unregister_DH'; + +procedure ENGINE_register_all_DH(); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_all_DH'; + +function ENGINE_register_RAND(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_RAND'; + +procedure ENGINE_unregister_RAND(e: PENGINE); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_unregister_RAND'; + +procedure ENGINE_register_all_RAND(); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_all_RAND'; + +function ENGINE_register_ciphers(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_ciphers'; + +procedure ENGINE_unregister_ciphers(e: PENGINE); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_unregister_ciphers'; + +procedure ENGINE_register_all_ciphers(); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_all_ciphers'; + +function ENGINE_register_digests(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_digests'; + +procedure ENGINE_unregister_digests(e: PENGINE); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_unregister_digests'; + +procedure ENGINE_register_all_digests(); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_all_digests'; + +function ENGINE_register_pkey_meths(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_pkey_meths'; + +procedure ENGINE_unregister_pkey_meths(e: PENGINE); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_unregister_pkey_meths'; + +procedure ENGINE_register_all_pkey_meths(); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_all_pkey_meths'; + +function ENGINE_register_pkey_asn1_meths(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_pkey_asn1_meths'; + +procedure ENGINE_unregister_pkey_asn1_meths(e: PENGINE); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_unregister_pkey_asn1_meths'; + +procedure ENGINE_register_all_pkey_asn1_meths(); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_all_pkey_asn1_meths'; + +function ENGINE_register_complete(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_complete'; + +function ENGINE_register_all_complete(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_register_all_complete'; + +type + ENGINE_ctrl_f = procedure(); cdecl; + +function ENGINE_ctrl(e: PENGINE; cmd: Integer; i: Integer; p: Pointer; f: ENGINE_ctrl_f): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_ctrl'; + +function ENGINE_cmd_is_executable(e: PENGINE; cmd: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_cmd_is_executable'; + +type + ENGINE_ctrl_cmd_f = procedure(); cdecl; + +function ENGINE_ctrl_cmd(e: PENGINE; cmd_name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; i: Integer; p: Pointer; f: ENGINE_ctrl_cmd_f; cmd_optional: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_ctrl_cmd'; + +function ENGINE_ctrl_cmd_string(e: PENGINE; cmd_name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; arg: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cmd_optional: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_ctrl_cmd_string'; + +function ENGINE_new(): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_new'; + +function ENGINE_free(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_free'; + +function ENGINE_up_ref(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_up_ref'; + +function ENGINE_set_id(e: PENGINE; id: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_id'; + +function ENGINE_set_name(e: PENGINE; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_name'; + +function ENGINE_set_RSA(e: PENGINE; rsa_meth: PRSA_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_RSA'; + +function ENGINE_set_DSA(e: PENGINE; dsa_meth: PDSA_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_DSA'; + +function ENGINE_set_EC(e: PENGINE; ecdsa_meth: PEC_KEY_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_EC'; + +function ENGINE_set_DH(e: PENGINE; dh_meth: PDH_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_DH'; + +function ENGINE_set_RAND(e: PENGINE; rand_meth: PRAND_METHOD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_RAND'; + +function ENGINE_set_destroy_function(e: PENGINE; destroy_f: ENGINE_GEN_INT_FUNC_PTR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_destroy_function'; + +function ENGINE_set_init_function(e: PENGINE; init_f: ENGINE_GEN_INT_FUNC_PTR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_init_function'; + +function ENGINE_set_finish_function(e: PENGINE; finish_f: ENGINE_GEN_INT_FUNC_PTR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_finish_function'; + +function ENGINE_set_ctrl_function(e: PENGINE; ctrl_f: ENGINE_CTRL_FUNC_PTR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_ctrl_function'; + +function ENGINE_set_load_privkey_function(e: PENGINE; loadpriv_f: ENGINE_LOAD_KEY_PTR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_load_privkey_function'; + +function ENGINE_set_load_pubkey_function(e: PENGINE; loadpub_f: ENGINE_LOAD_KEY_PTR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_load_pubkey_function'; + +function ENGINE_set_load_ssl_client_cert_function(e: PENGINE; loadssl_f: ENGINE_SSL_CLIENT_CERT_PTR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_load_ssl_client_cert_function'; + +function ENGINE_set_ciphers(e: PENGINE; f: ENGINE_CIPHERS_PTR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_ciphers'; + +function ENGINE_set_digests(e: PENGINE; f: ENGINE_DIGESTS_PTR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_digests'; + +function ENGINE_set_pkey_meths(e: PENGINE; f: ENGINE_PKEY_METHS_PTR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_pkey_meths'; + +function ENGINE_set_pkey_asn1_meths(e: PENGINE; f: ENGINE_PKEY_ASN1_METHS_PTR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_pkey_asn1_meths'; + +function ENGINE_set_flags(e: PENGINE; flags: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_flags'; + +function ENGINE_set_cmd_defns(e: PENGINE; defns: PENGINE_CMD_DEFN): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_cmd_defns'; + +function ENGINE_set_ex_data(e: PENGINE; idx: Integer; arg: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_ex_data'; + +function ENGINE_get_ex_data(e: PENGINE; idx: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_ex_data'; + +function ENGINE_get_id(e: PENGINE): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_id'; + +function ENGINE_get_name(e: PENGINE): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_name'; + +function ENGINE_get_RSA(e: PENGINE): PRSA_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_RSA'; + +function ENGINE_get_DSA(e: PENGINE): PDSA_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_DSA'; + +function ENGINE_get_EC(e: PENGINE): PEC_KEY_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_EC'; + +function ENGINE_get_DH(e: PENGINE): PDH_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_DH'; + +function ENGINE_get_RAND(e: PENGINE): PRAND_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_RAND'; + +function ENGINE_get_destroy_function(e: PENGINE): ENGINE_GEN_INT_FUNC_PTR; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_destroy_function'; + +function ENGINE_get_init_function(e: PENGINE): ENGINE_GEN_INT_FUNC_PTR; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_init_function'; + +function ENGINE_get_finish_function(e: PENGINE): ENGINE_GEN_INT_FUNC_PTR; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_finish_function'; + +function ENGINE_get_ctrl_function(e: PENGINE): ENGINE_CTRL_FUNC_PTR; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_ctrl_function'; + +function ENGINE_get_load_privkey_function(e: PENGINE): ENGINE_LOAD_KEY_PTR; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_load_privkey_function'; + +function ENGINE_get_load_pubkey_function(e: PENGINE): ENGINE_LOAD_KEY_PTR; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_load_pubkey_function'; + +function ENGINE_get_ssl_client_cert_function(e: PENGINE): ENGINE_SSL_CLIENT_CERT_PTR; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_ssl_client_cert_function'; + +function ENGINE_get_ciphers(e: PENGINE): ENGINE_CIPHERS_PTR; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_ciphers'; + +function ENGINE_get_digests(e: PENGINE): ENGINE_DIGESTS_PTR; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_digests'; + +function ENGINE_get_pkey_meths(e: PENGINE): ENGINE_PKEY_METHS_PTR; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_pkey_meths'; + +function ENGINE_get_pkey_asn1_meths(e: PENGINE): ENGINE_PKEY_ASN1_METHS_PTR; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_pkey_asn1_meths'; + +function ENGINE_get_cipher(e: PENGINE; nid: Integer): PEVP_CIPHER; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_cipher'; + +function ENGINE_get_digest(e: PENGINE; nid: Integer): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_digest'; + +function ENGINE_get_pkey_meth(e: PENGINE; nid: Integer): PEVP_PKEY_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_pkey_meth'; + +function ENGINE_get_pkey_asn1_meth(e: PENGINE; nid: Integer): PEVP_PKEY_ASN1_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_pkey_asn1_meth'; + +function ENGINE_get_pkey_asn1_meth_str(e: PENGINE; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: Integer): PEVP_PKEY_ASN1_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_pkey_asn1_meth_str'; + +function ENGINE_pkey_asn1_find_str(pe: PPENGINE; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; len: Integer): PEVP_PKEY_ASN1_METHOD; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_pkey_asn1_find_str'; + +function ENGINE_get_cmd_defns(e: PENGINE): PENGINE_CMD_DEFN; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_cmd_defns'; + +function ENGINE_get_flags(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_flags'; + +function ENGINE_init(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_init'; + +function ENGINE_finish(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_finish'; + +function ENGINE_load_private_key(e: PENGINE; key_id: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ui_method: PUI_METHOD; callback_data: Pointer): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_load_private_key'; + +function ENGINE_load_public_key(e: PENGINE; key_id: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ui_method: PUI_METHOD; callback_data: Pointer): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_load_public_key'; + +function ENGINE_load_ssl_client_cert(e: PENGINE; s: PSSL; ca_dn: Pstack_st_X509_NAME; pcert: PPX509; ppkey: PPEVP_PKEY; pother: PPstack_st_X509; ui_method: PUI_METHOD; callback_data: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_load_ssl_client_cert'; + +function ENGINE_get_default_RSA(): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_default_RSA'; + +function ENGINE_get_default_DSA(): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_default_DSA'; + +function ENGINE_get_default_EC(): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_default_EC'; + +function ENGINE_get_default_DH(): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_default_DH'; + +function ENGINE_get_default_RAND(): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_default_RAND'; + +function ENGINE_get_cipher_engine(nid: Integer): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_cipher_engine'; + +function ENGINE_get_digest_engine(nid: Integer): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_digest_engine'; + +function ENGINE_get_pkey_meth_engine(nid: Integer): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_pkey_meth_engine'; + +function ENGINE_get_pkey_asn1_meth_engine(nid: Integer): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_pkey_asn1_meth_engine'; + +function ENGINE_set_default_RSA(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_default_RSA'; + +function ENGINE_set_default_string(e: PENGINE; def_list: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_default_string'; + +function ENGINE_set_default_DSA(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_default_DSA'; + +function ENGINE_set_default_EC(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_default_EC'; + +function ENGINE_set_default_DH(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_default_DH'; + +function ENGINE_set_default_RAND(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_default_RAND'; + +function ENGINE_set_default_ciphers(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_default_ciphers'; + +function ENGINE_set_default_digests(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_default_digests'; + +function ENGINE_set_default_pkey_meths(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_default_pkey_meths'; + +function ENGINE_set_default_pkey_asn1_meths(e: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_default_pkey_asn1_meths'; + +function ENGINE_set_default(e: PENGINE; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_set_default'; + +procedure ENGINE_add_conf_module(); cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_add_conf_module'; + +function ENGINE_get_static_state(): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'ENGINE_get_static_state'; + +function HMAC_size(e: PHMAC_CTX): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'HMAC_size'; + +function HMAC_CTX_new(): PHMAC_CTX; cdecl; + external LIB_CRYPTO name _PU + 'HMAC_CTX_new'; + +function HMAC_CTX_reset(ctx: PHMAC_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'HMAC_CTX_reset'; + +procedure HMAC_CTX_free(ctx: PHMAC_CTX); cdecl; + external LIB_CRYPTO name _PU + 'HMAC_CTX_free'; + +function HMAC_Init(ctx: PHMAC_CTX; key: Pointer; len: Integer; md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'HMAC_Init'; + +function HMAC_Init_ex(ctx: PHMAC_CTX; key: Pointer; len: Integer; md: PEVP_MD; impl: PENGINE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'HMAC_Init_ex'; + +function HMAC_Update(ctx: PHMAC_CTX; data: PByte; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'HMAC_Update'; + +function HMAC_Final(ctx: PHMAC_CTX; md: PByte; len: PCardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'HMAC_Final'; + +function HMAC(evp_md: PEVP_MD; key: Pointer; key_len: Integer; d: PByte; n: NativeUInt; md: PByte; var md_len: Cardinal): PByte; cdecl; + external LIB_CRYPTO name _PU + 'HMAC'; + +function HMAC_CTX_copy(dctx: PHMAC_CTX; sctx: PHMAC_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'HMAC_CTX_copy'; + +procedure HMAC_CTX_set_flags(ctx: PHMAC_CTX; flags: Cardinal); cdecl; + external LIB_CRYPTO name _PU + 'HMAC_CTX_set_flags'; + +function HMAC_CTX_get_md(ctx: PHMAC_CTX): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'HMAC_CTX_get_md'; + +function IDEA_options(): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'IDEA_options'; + +procedure IDEA_ecb_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; ks: PIDEA_KEY_SCHEDULE); cdecl; + external LIB_CRYPTO name _PU + 'IDEA_ecb_encrypt'; + +procedure IDEA_set_encrypt_key(key: PByte; ks: PIDEA_KEY_SCHEDULE); cdecl; + external LIB_CRYPTO name _PU + 'IDEA_set_encrypt_key'; + +procedure IDEA_set_decrypt_key(ek: PIDEA_KEY_SCHEDULE; dk: PIDEA_KEY_SCHEDULE); cdecl; + external LIB_CRYPTO name _PU + 'IDEA_set_decrypt_key'; + +procedure IDEA_cbc_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: Integer; ks: PIDEA_KEY_SCHEDULE; iv: PByte; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'IDEA_cbc_encrypt'; + +procedure IDEA_cfb64_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: Integer; ks: PIDEA_KEY_SCHEDULE; iv: PByte; num: PInteger; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'IDEA_cfb64_encrypt'; + +procedure IDEA_ofb64_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: Integer; ks: PIDEA_KEY_SCHEDULE; iv: PByte; num: PInteger); cdecl; + external LIB_CRYPTO name _PU + 'IDEA_ofb64_encrypt'; + +procedure IDEA_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PCardinal; ks: PIDEA_KEY_SCHEDULE); cdecl; + external LIB_CRYPTO name _PU + 'IDEA_encrypt'; + +function ERR_load_KDF_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_KDF_strings'; + +function MD4_Init(c: PMD4_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'MD4_Init'; + +function MD4_Update(c: PMD4_CTX; data: Pointer; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'MD4_Update'; + +function MD4_Final(md: PByte; c: PMD4_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'MD4_Final'; + +function MD4(d: PByte; n: NativeUInt; md: PByte): PByte; cdecl; + external LIB_CRYPTO name _PU + 'MD4'; + +procedure MD4_Transform(c: PMD4_CTX; b: PByte); cdecl; + external LIB_CRYPTO name _PU + 'MD4_Transform'; + +function MD5_Init(c: PMD5_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'MD5_Init'; + +function MD5_Update(c: PMD5_CTX; data: Pointer; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'MD5_Update'; + +function MD5_Final(md: PByte; c: PMD5_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'MD5_Final'; + +function MD5(d: PByte; n: NativeUInt; md: PByte): PByte; cdecl; + external LIB_CRYPTO name _PU + 'MD5'; + +procedure MD5_Transform(c: PMD5_CTX; b: PByte); cdecl; + external LIB_CRYPTO name _PU + 'MD5_Transform'; + +function MDC2_Init(c: PMDC2_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'MDC2_Init'; + +function MDC2_Update(c: PMDC2_CTX; data: PByte; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'MDC2_Update'; + +function MDC2_Final(md: PByte; c: PMDC2_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'MDC2_Final'; + +function MDC2(d: PByte; n: NativeUInt; md: PByte): PByte; cdecl; + external LIB_CRYPTO name _PU + 'MDC2'; + +procedure CRYPTO_cbc128_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; key: Pointer; ivec: PByte; block: block128_f); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_cbc128_encrypt'; + +procedure CRYPTO_cbc128_decrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; key: Pointer; ivec: PByte; block: block128_f); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_cbc128_decrypt'; + +procedure CRYPTO_ctr128_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; key: Pointer; ivec: PByte; ecount_buf: PByte; num: PCardinal; block: block128_f); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ctr128_encrypt'; + +procedure CRYPTO_ctr128_encrypt_ctr32({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; key: Pointer; ivec: PByte; ecount_buf: PByte; num: PCardinal; ctr: ctr128_f); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ctr128_encrypt_ctr32'; + +procedure CRYPTO_ofb128_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; key: Pointer; ivec: PByte; num: PInteger; block: block128_f); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ofb128_encrypt'; + +procedure CRYPTO_cfb128_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; key: Pointer; ivec: PByte; num: PInteger; enc: Integer; block: block128_f); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_cfb128_encrypt'; + +procedure CRYPTO_cfb128_8_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: NativeUInt; key: Pointer; ivec: PByte; num: PInteger; enc: Integer; block: block128_f); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_cfb128_8_encrypt'; + +procedure CRYPTO_cfb128_1_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; bits: NativeUInt; key: Pointer; ivec: PByte; num: PInteger; enc: Integer; block: block128_f); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_cfb128_1_encrypt'; + +function CRYPTO_cts128_encrypt_block({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; key: Pointer; ivec: PByte; block: block128_f): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_cts128_encrypt_block'; + +function CRYPTO_cts128_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; key: Pointer; ivec: PByte; cbc: cbc128_f): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_cts128_encrypt'; + +function CRYPTO_cts128_decrypt_block({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; key: Pointer; ivec: PByte; block: block128_f): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_cts128_decrypt_block'; + +function CRYPTO_cts128_decrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; key: Pointer; ivec: PByte; cbc: cbc128_f): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_cts128_decrypt'; + +function CRYPTO_nistcts128_encrypt_block({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; key: Pointer; ivec: PByte; block: block128_f): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_nistcts128_encrypt_block'; + +function CRYPTO_nistcts128_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; key: Pointer; ivec: PByte; cbc: cbc128_f): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_nistcts128_encrypt'; + +function CRYPTO_nistcts128_decrypt_block({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; key: Pointer; ivec: PByte; block: block128_f): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_nistcts128_decrypt_block'; + +function CRYPTO_nistcts128_decrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; key: Pointer; ivec: PByte; cbc: cbc128_f): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_nistcts128_decrypt'; + +function CRYPTO_gcm128_new(key: Pointer; block: block128_f): PGCM128_CONTEXT; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_gcm128_new'; + +procedure CRYPTO_gcm128_init(ctx: PGCM128_CONTEXT; key: Pointer; block: block128_f); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_gcm128_init'; + +procedure CRYPTO_gcm128_setiv(ctx: PGCM128_CONTEXT; iv: PByte; len: NativeUInt); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_gcm128_setiv'; + +function CRYPTO_gcm128_aad(ctx: PGCM128_CONTEXT; aad: PByte; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_gcm128_aad'; + +function CRYPTO_gcm128_encrypt(ctx: PGCM128_CONTEXT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_gcm128_encrypt'; + +function CRYPTO_gcm128_decrypt(ctx: PGCM128_CONTEXT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_gcm128_decrypt'; + +function CRYPTO_gcm128_encrypt_ctr32(ctx: PGCM128_CONTEXT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; stream: ctr128_f): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_gcm128_encrypt_ctr32'; + +function CRYPTO_gcm128_decrypt_ctr32(ctx: PGCM128_CONTEXT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; stream: ctr128_f): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_gcm128_decrypt_ctr32'; + +function CRYPTO_gcm128_finish(ctx: PGCM128_CONTEXT; tag: PByte; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_gcm128_finish'; + +procedure CRYPTO_gcm128_tag(ctx: PGCM128_CONTEXT; tag: PByte; len: NativeUInt); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_gcm128_tag'; + +procedure CRYPTO_gcm128_release(ctx: PGCM128_CONTEXT); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_gcm128_release'; + +procedure CRYPTO_ccm128_init(ctx: PCCM128_CONTEXT; M: Cardinal; L: Cardinal; key: Pointer; block: block128_f); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ccm128_init'; + +function CRYPTO_ccm128_setiv(ctx: PCCM128_CONTEXT; nonce: PByte; nlen: NativeUInt; mlen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ccm128_setiv'; + +procedure CRYPTO_ccm128_aad(ctx: PCCM128_CONTEXT; aad: PByte; alen: NativeUInt); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ccm128_aad'; + +function CRYPTO_ccm128_encrypt(ctx: PCCM128_CONTEXT; inp: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ccm128_encrypt'; + +function CRYPTO_ccm128_decrypt(ctx: PCCM128_CONTEXT; inp: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ccm128_decrypt'; + +function CRYPTO_ccm128_encrypt_ccm64(ctx: PCCM128_CONTEXT; inp: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; stream: ccm128_f): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ccm128_encrypt_ccm64'; + +function CRYPTO_ccm128_decrypt_ccm64(ctx: PCCM128_CONTEXT; inp: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; stream: ccm128_f): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ccm128_decrypt_ccm64'; + +function CRYPTO_ccm128_tag(ctx: PCCM128_CONTEXT; tag: PByte; len: NativeUInt): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ccm128_tag'; + +function CRYPTO_xts128_encrypt(ctx: PXTS128_CONTEXT; iv: PByte; inp: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; enc: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_xts128_encrypt'; + +function CRYPTO_128_wrap(key: Pointer; iv: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inlen: NativeUInt; block: block128_f): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_128_wrap'; + +function CRYPTO_128_unwrap(key: Pointer; iv: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inlen: NativeUInt; block: block128_f): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_128_unwrap'; + +function CRYPTO_128_wrap_pad(key: Pointer; icv: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inlen: NativeUInt; block: block128_f): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_128_wrap_pad'; + +function CRYPTO_128_unwrap_pad(key: Pointer; icv: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inlen: NativeUInt; block: block128_f): NativeUInt; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_128_unwrap_pad'; + +function CRYPTO_ocb128_new(keyenc: Pointer; keydec: Pointer; encrypt: block128_f; decrypt: block128_f; stream: ocb128_f): POCB128_CONTEXT; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ocb128_new'; + +function CRYPTO_ocb128_init(ctx: POCB128_CONTEXT; keyenc: Pointer; keydec: Pointer; encrypt: block128_f; decrypt: block128_f; stream: ocb128_f): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ocb128_init'; + +function CRYPTO_ocb128_copy_ctx(dest: POCB128_CONTEXT; src: POCB128_CONTEXT; keyenc: Pointer; keydec: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ocb128_copy_ctx'; + +function CRYPTO_ocb128_setiv(ctx: POCB128_CONTEXT; iv: PByte; len: NativeUInt; taglen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ocb128_setiv'; + +function CRYPTO_ocb128_aad(ctx: POCB128_CONTEXT; aad: PByte; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ocb128_aad'; + +function CRYPTO_ocb128_encrypt(ctx: POCB128_CONTEXT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ocb128_encrypt'; + +function CRYPTO_ocb128_decrypt(ctx: POCB128_CONTEXT; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ocb128_decrypt'; + +function CRYPTO_ocb128_finish(ctx: POCB128_CONTEXT; tag: PByte; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ocb128_finish'; + +function CRYPTO_ocb128_tag(ctx: POCB128_CONTEXT; tag: PByte; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ocb128_tag'; + +procedure CRYPTO_ocb128_cleanup(ctx: POCB128_CONTEXT); cdecl; + external LIB_CRYPTO name _PU + 'CRYPTO_ocb128_cleanup'; + +function ERR_load_OCSP_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_OCSP_strings'; + +function OCSP_CERTID_dup(id: POCSP_CERTID): POCSP_CERTID; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_CERTID_dup'; + +function OCSP_sendreq_bio(b: PBIO; path: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; req: POCSP_REQUEST): POCSP_RESPONSE; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_sendreq_bio'; + +function OCSP_sendreq_new(io: PBIO; path: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; req: POCSP_REQUEST; maxline: Integer): POCSP_REQ_CTX; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_sendreq_new'; + +function OCSP_REQ_CTX_nbio(rctx: POCSP_REQ_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQ_CTX_nbio'; + +function OCSP_sendreq_nbio(presp: PPOCSP_RESPONSE; rctx: POCSP_REQ_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_sendreq_nbio'; + +function OCSP_REQ_CTX_new(io: PBIO; maxline: Integer): POCSP_REQ_CTX; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQ_CTX_new'; + +procedure OCSP_REQ_CTX_free(rctx: POCSP_REQ_CTX); cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQ_CTX_free'; + +procedure OCSP_set_max_response_length(rctx: POCSP_REQ_CTX; len: Cardinal); cdecl; + external LIB_CRYPTO name _PU + 'OCSP_set_max_response_length'; + +function OCSP_REQ_CTX_i2d(rctx: POCSP_REQ_CTX; it: PASN1_ITEM; val: PASN1_VALUE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQ_CTX_i2d'; + +function OCSP_REQ_CTX_nbio_d2i(rctx: POCSP_REQ_CTX; pval: PPASN1_VALUE; it: PASN1_ITEM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQ_CTX_nbio_d2i'; + +function OCSP_REQ_CTX_get0_mem_bio(rctx: POCSP_REQ_CTX): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQ_CTX_get0_mem_bio'; + +function OCSP_REQ_CTX_http(rctx: POCSP_REQ_CTX; op: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; path: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQ_CTX_http'; + +function OCSP_REQ_CTX_set1_req(rctx: POCSP_REQ_CTX; req: POCSP_REQUEST): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQ_CTX_set1_req'; + +function OCSP_REQ_CTX_add1_header(rctx: POCSP_REQ_CTX; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; value: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQ_CTX_add1_header'; + +function OCSP_cert_to_id(dgst: PEVP_MD; subject: PX509; issuer: PX509): POCSP_CERTID; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_cert_to_id'; + +function OCSP_cert_id_new(dgst: PEVP_MD; issuerName: PX509_NAME; issuerKey: PASN1_BIT_STRING; serialNumber: PASN1_INTEGER): POCSP_CERTID; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_cert_id_new'; + +function OCSP_request_add0_id(req: POCSP_REQUEST; cid: POCSP_CERTID): POCSP_ONEREQ; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_request_add0_id'; + +function OCSP_request_add1_nonce(req: POCSP_REQUEST; val: PByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_request_add1_nonce'; + +function OCSP_basic_add1_nonce(resp: POCSP_BASICRESP; val: PByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_basic_add1_nonce'; + +function OCSP_check_nonce(req: POCSP_REQUEST; bs: POCSP_BASICRESP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_check_nonce'; + +function OCSP_copy_nonce(resp: POCSP_BASICRESP; req: POCSP_REQUEST): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_copy_nonce'; + +function OCSP_request_set1_name(req: POCSP_REQUEST; nm: PX509_NAME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_request_set1_name'; + +function OCSP_request_add1_cert(req: POCSP_REQUEST; cert: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_request_add1_cert'; + +function OCSP_request_sign(req: POCSP_REQUEST; signer: PX509; key: PEVP_PKEY; dgst: PEVP_MD; certs: Pstack_st_X509; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_request_sign'; + +function OCSP_response_status(resp: POCSP_RESPONSE): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_response_status'; + +function OCSP_response_get1_basic(resp: POCSP_RESPONSE): POCSP_BASICRESP; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_response_get1_basic'; + +function OCSP_resp_get0_signature(bs: POCSP_BASICRESP): PASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_resp_get0_signature'; + +function OCSP_resp_get0_tbs_sigalg(bs: POCSP_BASICRESP): PX509_ALGOR; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_resp_get0_tbs_sigalg'; + +function OCSP_resp_get0_respdata(bs: POCSP_BASICRESP): POCSP_RESPDATA; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_resp_get0_respdata'; + +function OCSP_resp_get0_signer(bs: POCSP_BASICRESP; signer: PPX509; extra_certs: Pstack_st_X509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_resp_get0_signer'; + +function OCSP_resp_count(bs: POCSP_BASICRESP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_resp_count'; + +function OCSP_resp_get0(bs: POCSP_BASICRESP; idx: Integer): POCSP_SINGLERESP; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_resp_get0'; + +function OCSP_resp_get0_produced_at(bs: POCSP_BASICRESP): PASN1_GENERALIZEDTIME; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_resp_get0_produced_at'; + +function OCSP_resp_get0_certs(bs: POCSP_BASICRESP): Pstack_st_X509; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_resp_get0_certs'; + +function OCSP_resp_get0_id(bs: POCSP_BASICRESP; pid: PPASN1_OCTET_STRING; pname: PPX509_NAME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_resp_get0_id'; + +function OCSP_resp_get1_id(bs: POCSP_BASICRESP; pid: PPASN1_OCTET_STRING; pname: PPX509_NAME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_resp_get1_id'; + +function OCSP_resp_find(bs: POCSP_BASICRESP; id: POCSP_CERTID; last: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_resp_find'; + +function OCSP_single_get0_status(single: POCSP_SINGLERESP; reason: PInteger; revtime: PPASN1_GENERALIZEDTIME; thisupd: PPASN1_GENERALIZEDTIME; nextupd: PPASN1_GENERALIZEDTIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_single_get0_status'; + +function OCSP_resp_find_status(bs: POCSP_BASICRESP; id: POCSP_CERTID; status: PInteger; reason: PInteger; revtime: PPASN1_GENERALIZEDTIME; thisupd: PPASN1_GENERALIZEDTIME; nextupd: PPASN1_GENERALIZEDTIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_resp_find_status'; + +function OCSP_check_validity(thisupd: PASN1_GENERALIZEDTIME; nextupd: PASN1_GENERALIZEDTIME; sec: Integer; maxsec: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_check_validity'; + +function OCSP_request_verify(req: POCSP_REQUEST; certs: Pstack_st_X509; store: PX509_STORE; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_request_verify'; + +function OCSP_parse_url(url: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; phost: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; pport: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; ppath: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; pssl: PInteger): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_parse_url'; + +function OCSP_id_issuer_cmp(a: POCSP_CERTID; b: POCSP_CERTID): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_id_issuer_cmp'; + +function OCSP_id_cmp(a: POCSP_CERTID; b: POCSP_CERTID): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_id_cmp'; + +function OCSP_request_onereq_count(req: POCSP_REQUEST): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_request_onereq_count'; + +function OCSP_request_onereq_get0(req: POCSP_REQUEST; i: Integer): POCSP_ONEREQ; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_request_onereq_get0'; + +function OCSP_onereq_get0_id(one: POCSP_ONEREQ): POCSP_CERTID; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_onereq_get0_id'; + +function OCSP_id_get0_info(piNameHash: PPASN1_OCTET_STRING; pmd: PPASN1_OBJECT; pikeyHash: PPASN1_OCTET_STRING; pserial: PPASN1_INTEGER; cid: POCSP_CERTID): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_id_get0_info'; + +function OCSP_request_is_signed(req: POCSP_REQUEST): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_request_is_signed'; + +function OCSP_response_create(status: Integer; bs: POCSP_BASICRESP): POCSP_RESPONSE; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_response_create'; + +function OCSP_basic_add1_status(rsp: POCSP_BASICRESP; cid: POCSP_CERTID; status: Integer; reason: Integer; revtime: PASN1_TIME; thisupd: PASN1_TIME; nextupd: PASN1_TIME): POCSP_SINGLERESP; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_basic_add1_status'; + +function OCSP_basic_add1_cert(resp: POCSP_BASICRESP; cert: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_basic_add1_cert'; + +function OCSP_basic_sign(brsp: POCSP_BASICRESP; signer: PX509; key: PEVP_PKEY; dgst: PEVP_MD; certs: Pstack_st_X509; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_basic_sign'; + +function OCSP_basic_sign_ctx(brsp: POCSP_BASICRESP; signer: PX509; ctx: PEVP_MD_CTX; certs: Pstack_st_X509; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_basic_sign_ctx'; + +function OCSP_RESPID_set_by_name(respid: POCSP_RESPID; cert: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_RESPID_set_by_name'; + +function OCSP_RESPID_set_by_key(respid: POCSP_RESPID; cert: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_RESPID_set_by_key'; + +function OCSP_RESPID_match(respid: POCSP_RESPID; cert: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_RESPID_match'; + +function OCSP_crlID_new(url: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; n: PInteger; tim: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_crlID_new'; + +function OCSP_accept_responses_new(oids: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_accept_responses_new'; + +function OCSP_archive_cutoff_new(tim: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_archive_cutoff_new'; + +function OCSP_url_svcloc_new(issuer: PX509_NAME; urls: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_url_svcloc_new'; + +function OCSP_REQUEST_get_ext_count(x: POCSP_REQUEST): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQUEST_get_ext_count'; + +function OCSP_REQUEST_get_ext_by_NID(x: POCSP_REQUEST; nid: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQUEST_get_ext_by_NID'; + +function OCSP_REQUEST_get_ext_by_OBJ(x: POCSP_REQUEST; obj: PASN1_OBJECT; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQUEST_get_ext_by_OBJ'; + +function OCSP_REQUEST_get_ext_by_critical(x: POCSP_REQUEST; crit: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQUEST_get_ext_by_critical'; + +function OCSP_REQUEST_get_ext(x: POCSP_REQUEST; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQUEST_get_ext'; + +function OCSP_REQUEST_delete_ext(x: POCSP_REQUEST; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQUEST_delete_ext'; + +function OCSP_REQUEST_get1_ext_d2i(x: POCSP_REQUEST; nid: Integer; crit: PInteger; idx: PInteger): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQUEST_get1_ext_d2i'; + +function OCSP_REQUEST_add1_ext_i2d(x: POCSP_REQUEST; nid: Integer; value: Pointer; crit: Integer; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQUEST_add1_ext_i2d'; + +function OCSP_REQUEST_add_ext(x: POCSP_REQUEST; ex: PX509_EXTENSION; loc: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQUEST_add_ext'; + +function OCSP_ONEREQ_get_ext_count(x: POCSP_ONEREQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_ONEREQ_get_ext_count'; + +function OCSP_ONEREQ_get_ext_by_NID(x: POCSP_ONEREQ; nid: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_ONEREQ_get_ext_by_NID'; + +function OCSP_ONEREQ_get_ext_by_OBJ(x: POCSP_ONEREQ; obj: PASN1_OBJECT; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_ONEREQ_get_ext_by_OBJ'; + +function OCSP_ONEREQ_get_ext_by_critical(x: POCSP_ONEREQ; crit: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_ONEREQ_get_ext_by_critical'; + +function OCSP_ONEREQ_get_ext(x: POCSP_ONEREQ; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_ONEREQ_get_ext'; + +function OCSP_ONEREQ_delete_ext(x: POCSP_ONEREQ; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_ONEREQ_delete_ext'; + +function OCSP_ONEREQ_get1_ext_d2i(x: POCSP_ONEREQ; nid: Integer; crit: PInteger; idx: PInteger): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_ONEREQ_get1_ext_d2i'; + +function OCSP_ONEREQ_add1_ext_i2d(x: POCSP_ONEREQ; nid: Integer; value: Pointer; crit: Integer; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_ONEREQ_add1_ext_i2d'; + +function OCSP_ONEREQ_add_ext(x: POCSP_ONEREQ; ex: PX509_EXTENSION; loc: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_ONEREQ_add_ext'; + +function OCSP_BASICRESP_get_ext_count(x: POCSP_BASICRESP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_BASICRESP_get_ext_count'; + +function OCSP_BASICRESP_get_ext_by_NID(x: POCSP_BASICRESP; nid: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_BASICRESP_get_ext_by_NID'; + +function OCSP_BASICRESP_get_ext_by_OBJ(x: POCSP_BASICRESP; obj: PASN1_OBJECT; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_BASICRESP_get_ext_by_OBJ'; + +function OCSP_BASICRESP_get_ext_by_critical(x: POCSP_BASICRESP; crit: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_BASICRESP_get_ext_by_critical'; + +function OCSP_BASICRESP_get_ext(x: POCSP_BASICRESP; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_BASICRESP_get_ext'; + +function OCSP_BASICRESP_delete_ext(x: POCSP_BASICRESP; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_BASICRESP_delete_ext'; + +function OCSP_BASICRESP_get1_ext_d2i(x: POCSP_BASICRESP; nid: Integer; crit: PInteger; idx: PInteger): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_BASICRESP_get1_ext_d2i'; + +function OCSP_BASICRESP_add1_ext_i2d(x: POCSP_BASICRESP; nid: Integer; value: Pointer; crit: Integer; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_BASICRESP_add1_ext_i2d'; + +function OCSP_BASICRESP_add_ext(x: POCSP_BASICRESP; ex: PX509_EXTENSION; loc: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_BASICRESP_add_ext'; + +function OCSP_SINGLERESP_get_ext_count(x: POCSP_SINGLERESP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SINGLERESP_get_ext_count'; + +function OCSP_SINGLERESP_get_ext_by_NID(x: POCSP_SINGLERESP; nid: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SINGLERESP_get_ext_by_NID'; + +function OCSP_SINGLERESP_get_ext_by_OBJ(x: POCSP_SINGLERESP; obj: PASN1_OBJECT; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SINGLERESP_get_ext_by_OBJ'; + +function OCSP_SINGLERESP_get_ext_by_critical(x: POCSP_SINGLERESP; crit: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SINGLERESP_get_ext_by_critical'; + +function OCSP_SINGLERESP_get_ext(x: POCSP_SINGLERESP; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SINGLERESP_get_ext'; + +function OCSP_SINGLERESP_delete_ext(x: POCSP_SINGLERESP; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SINGLERESP_delete_ext'; + +function OCSP_SINGLERESP_get1_ext_d2i(x: POCSP_SINGLERESP; nid: Integer; crit: PInteger; idx: PInteger): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SINGLERESP_get1_ext_d2i'; + +function OCSP_SINGLERESP_add1_ext_i2d(x: POCSP_SINGLERESP; nid: Integer; value: Pointer; crit: Integer; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SINGLERESP_add1_ext_i2d'; + +function OCSP_SINGLERESP_add_ext(x: POCSP_SINGLERESP; ex: PX509_EXTENSION; loc: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SINGLERESP_add_ext'; + +function OCSP_SINGLERESP_get0_id(x: POCSP_SINGLERESP): POCSP_CERTID; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SINGLERESP_get0_id'; + +function OCSP_SINGLERESP_new(): POCSP_SINGLERESP; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SINGLERESP_new'; + +procedure OCSP_SINGLERESP_free(a: POCSP_SINGLERESP); cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SINGLERESP_free'; + +function d2i_OCSP_SINGLERESP(a: PPOCSP_SINGLERESP; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): POCSP_SINGLERESP; cdecl; + external LIB_CRYPTO name _PU + 'd2i_OCSP_SINGLERESP'; + +function i2d_OCSP_SINGLERESP(a: POCSP_SINGLERESP; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_OCSP_SINGLERESP'; + +function OCSP_SINGLERESP_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SINGLERESP_it'; + +function OCSP_CERTSTATUS_new(): POCSP_CERTSTATUS; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_CERTSTATUS_new'; + +procedure OCSP_CERTSTATUS_free(a: POCSP_CERTSTATUS); cdecl; + external LIB_CRYPTO name _PU + 'OCSP_CERTSTATUS_free'; + +function d2i_OCSP_CERTSTATUS(a: PPOCSP_CERTSTATUS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): POCSP_CERTSTATUS; cdecl; + external LIB_CRYPTO name _PU + 'd2i_OCSP_CERTSTATUS'; + +function i2d_OCSP_CERTSTATUS(a: POCSP_CERTSTATUS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_OCSP_CERTSTATUS'; + +function OCSP_CERTSTATUS_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_CERTSTATUS_it'; + +function OCSP_REVOKEDINFO_new(): POCSP_REVOKEDINFO; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REVOKEDINFO_new'; + +procedure OCSP_REVOKEDINFO_free(a: POCSP_REVOKEDINFO); cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REVOKEDINFO_free'; + +function d2i_OCSP_REVOKEDINFO(a: PPOCSP_REVOKEDINFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): POCSP_REVOKEDINFO; cdecl; + external LIB_CRYPTO name _PU + 'd2i_OCSP_REVOKEDINFO'; + +function i2d_OCSP_REVOKEDINFO(a: POCSP_REVOKEDINFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_OCSP_REVOKEDINFO'; + +function OCSP_REVOKEDINFO_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REVOKEDINFO_it'; + +function OCSP_BASICRESP_new(): POCSP_BASICRESP; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_BASICRESP_new'; + +procedure OCSP_BASICRESP_free(a: POCSP_BASICRESP); cdecl; + external LIB_CRYPTO name _PU + 'OCSP_BASICRESP_free'; + +function d2i_OCSP_BASICRESP(a: PPOCSP_BASICRESP; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): POCSP_BASICRESP; cdecl; + external LIB_CRYPTO name _PU + 'd2i_OCSP_BASICRESP'; + +function i2d_OCSP_BASICRESP(a: POCSP_BASICRESP; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_OCSP_BASICRESP'; + +function OCSP_BASICRESP_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_BASICRESP_it'; + +function OCSP_RESPDATA_new(): POCSP_RESPDATA; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_RESPDATA_new'; + +procedure OCSP_RESPDATA_free(a: POCSP_RESPDATA); cdecl; + external LIB_CRYPTO name _PU + 'OCSP_RESPDATA_free'; + +function d2i_OCSP_RESPDATA(a: PPOCSP_RESPDATA; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): POCSP_RESPDATA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_OCSP_RESPDATA'; + +function i2d_OCSP_RESPDATA(a: POCSP_RESPDATA; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_OCSP_RESPDATA'; + +function OCSP_RESPDATA_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_RESPDATA_it'; + +function OCSP_RESPID_new(): POCSP_RESPID; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_RESPID_new'; + +procedure OCSP_RESPID_free(a: POCSP_RESPID); cdecl; + external LIB_CRYPTO name _PU + 'OCSP_RESPID_free'; + +function d2i_OCSP_RESPID(a: PPOCSP_RESPID; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): POCSP_RESPID; cdecl; + external LIB_CRYPTO name _PU + 'd2i_OCSP_RESPID'; + +function i2d_OCSP_RESPID(a: POCSP_RESPID; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_OCSP_RESPID'; + +function OCSP_RESPID_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_RESPID_it'; + +function OCSP_RESPONSE_new(): POCSP_RESPONSE; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_RESPONSE_new'; + +procedure OCSP_RESPONSE_free(a: POCSP_RESPONSE); cdecl; + external LIB_CRYPTO name _PU + 'OCSP_RESPONSE_free'; + +function d2i_OCSP_RESPONSE(a: PPOCSP_RESPONSE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): POCSP_RESPONSE; cdecl; + external LIB_CRYPTO name _PU + 'd2i_OCSP_RESPONSE'; + +function i2d_OCSP_RESPONSE(a: POCSP_RESPONSE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_OCSP_RESPONSE'; + +function OCSP_RESPONSE_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_RESPONSE_it'; + +function OCSP_RESPBYTES_new(): POCSP_RESPBYTES; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_RESPBYTES_new'; + +procedure OCSP_RESPBYTES_free(a: POCSP_RESPBYTES); cdecl; + external LIB_CRYPTO name _PU + 'OCSP_RESPBYTES_free'; + +function d2i_OCSP_RESPBYTES(a: PPOCSP_RESPBYTES; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): POCSP_RESPBYTES; cdecl; + external LIB_CRYPTO name _PU + 'd2i_OCSP_RESPBYTES'; + +function i2d_OCSP_RESPBYTES(a: POCSP_RESPBYTES; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_OCSP_RESPBYTES'; + +function OCSP_RESPBYTES_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_RESPBYTES_it'; + +function OCSP_ONEREQ_new(): POCSP_ONEREQ; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_ONEREQ_new'; + +procedure OCSP_ONEREQ_free(a: POCSP_ONEREQ); cdecl; + external LIB_CRYPTO name _PU + 'OCSP_ONEREQ_free'; + +function d2i_OCSP_ONEREQ(a: PPOCSP_ONEREQ; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): POCSP_ONEREQ; cdecl; + external LIB_CRYPTO name _PU + 'd2i_OCSP_ONEREQ'; + +function i2d_OCSP_ONEREQ(a: POCSP_ONEREQ; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_OCSP_ONEREQ'; + +function OCSP_ONEREQ_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_ONEREQ_it'; + +function OCSP_CERTID_new(): POCSP_CERTID; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_CERTID_new'; + +procedure OCSP_CERTID_free(a: POCSP_CERTID); cdecl; + external LIB_CRYPTO name _PU + 'OCSP_CERTID_free'; + +function d2i_OCSP_CERTID(a: PPOCSP_CERTID; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): POCSP_CERTID; cdecl; + external LIB_CRYPTO name _PU + 'd2i_OCSP_CERTID'; + +function i2d_OCSP_CERTID(a: POCSP_CERTID; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_OCSP_CERTID'; + +function OCSP_CERTID_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_CERTID_it'; + +function OCSP_REQUEST_new(): POCSP_REQUEST; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQUEST_new'; + +procedure OCSP_REQUEST_free(a: POCSP_REQUEST); cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQUEST_free'; + +function d2i_OCSP_REQUEST(a: PPOCSP_REQUEST; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): POCSP_REQUEST; cdecl; + external LIB_CRYPTO name _PU + 'd2i_OCSP_REQUEST'; + +function i2d_OCSP_REQUEST(a: POCSP_REQUEST; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_OCSP_REQUEST'; + +function OCSP_REQUEST_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQUEST_it'; + +function OCSP_SIGNATURE_new(): POCSP_SIGNATURE; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SIGNATURE_new'; + +procedure OCSP_SIGNATURE_free(a: POCSP_SIGNATURE); cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SIGNATURE_free'; + +function d2i_OCSP_SIGNATURE(a: PPOCSP_SIGNATURE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): POCSP_SIGNATURE; cdecl; + external LIB_CRYPTO name _PU + 'd2i_OCSP_SIGNATURE'; + +function i2d_OCSP_SIGNATURE(a: POCSP_SIGNATURE; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_OCSP_SIGNATURE'; + +function OCSP_SIGNATURE_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SIGNATURE_it'; + +function OCSP_REQINFO_new(): POCSP_REQINFO; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQINFO_new'; + +procedure OCSP_REQINFO_free(a: POCSP_REQINFO); cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQINFO_free'; + +function d2i_OCSP_REQINFO(a: PPOCSP_REQINFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): POCSP_REQINFO; cdecl; + external LIB_CRYPTO name _PU + 'd2i_OCSP_REQINFO'; + +function i2d_OCSP_REQINFO(a: POCSP_REQINFO; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_OCSP_REQINFO'; + +function OCSP_REQINFO_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQINFO_it'; + +//function OCSP_CRLID_new(): POCSP_CRLID; cdecl; +// external LIB_CRYPTO name _PU + 'OCSP_CRLID_new'; + +procedure OCSP_CRLID_free(a: POCSP_CRLID); cdecl; + external LIB_CRYPTO name _PU + 'OCSP_CRLID_free'; + +function d2i_OCSP_CRLID(a: PPOCSP_CRLID; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): POCSP_CRLID; cdecl; + external LIB_CRYPTO name _PU + 'd2i_OCSP_CRLID'; + +function i2d_OCSP_CRLID(a: POCSP_CRLID; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_OCSP_CRLID'; + +function OCSP_CRLID_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_CRLID_it'; + +function OCSP_SERVICELOC_new(): POCSP_SERVICELOC; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SERVICELOC_new'; + +procedure OCSP_SERVICELOC_free(a: POCSP_SERVICELOC); cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SERVICELOC_free'; + +function d2i_OCSP_SERVICELOC(a: PPOCSP_SERVICELOC; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): POCSP_SERVICELOC; cdecl; + external LIB_CRYPTO name _PU + 'd2i_OCSP_SERVICELOC'; + +function i2d_OCSP_SERVICELOC(a: POCSP_SERVICELOC; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_OCSP_SERVICELOC'; + +function OCSP_SERVICELOC_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_SERVICELOC_it'; + +function OCSP_response_status_str(s: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_response_status_str'; + +function OCSP_cert_status_str(s: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_cert_status_str'; + +function OCSP_crl_reason_str(s: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_crl_reason_str'; + +function OCSP_REQUEST_print(bp: PBIO; a: POCSP_REQUEST; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_REQUEST_print'; + +function OCSP_RESPONSE_print(bp: PBIO; o: POCSP_RESPONSE; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_RESPONSE_print'; + +function OCSP_basic_verify(bs: POCSP_BASICRESP; certs: Pstack_st_X509; st: PX509_STORE; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OCSP_basic_verify'; + +function ERR_load_PKCS12_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_PKCS12_strings'; + +function PKCS12_get_attr(bag: PPKCS12_SAFEBAG; attr_nid: Integer): PASN1_TYPE; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_get_attr'; + +function PKCS8_get_attr(p8: PPKCS8_PRIV_KEY_INFO; attr_nid: Integer): PASN1_TYPE; cdecl; + external LIB_CRYPTO name _PU + 'PKCS8_get_attr'; + +function PKCS12_mac_present(p12: PPKCS12): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_mac_present'; + +procedure PKCS12_get0_mac(pmac: PPASN1_OCTET_STRING; pmacalg: PPX509_ALGOR; psalt: PPASN1_OCTET_STRING; piter: PPASN1_INTEGER; p12: PPKCS12); cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_get0_mac'; + +function PKCS12_SAFEBAG_get0_attr(bag: PPKCS12_SAFEBAG; attr_nid: Integer): PASN1_TYPE; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_get0_attr'; + +function PKCS12_SAFEBAG_get0_type(bag: PPKCS12_SAFEBAG): PASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_get0_type'; + +function PKCS12_SAFEBAG_get_nid(bag: PPKCS12_SAFEBAG): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_get_nid'; +function PKCS12_bag_type(bag: PPKCS12_SAFEBAG): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_get_nid'; +function M_PKCS12_bag_type(bag: PPKCS12_SAFEBAG): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_get_nid'; + +function PKCS12_SAFEBAG_get_bag_nid(bag: PPKCS12_SAFEBAG): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_get_bag_nid'; +function M_PKCS12_crl_bag_type(bag: PPKCS12_SAFEBAG): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_get_bag_nid'; +function PKCS12_cert_bag_type(bag: PPKCS12_SAFEBAG): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_get_bag_nid'; + +function PKCS12_SAFEBAG_get1_cert(bag: PPKCS12_SAFEBAG): PX509; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_get1_cert'; +function PKCS12_certbag2x509(bag: PPKCS12_SAFEBAG): PX509; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_get1_cert'; + +function PKCS12_SAFEBAG_get1_crl(bag: PPKCS12_SAFEBAG): PX509_CRL; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_get1_crl'; +function PKCS12_certbag2scrl(bag: PPKCS12_SAFEBAG): PX509_CRL; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_get1_crl'; + +function PKCS12_SAFEBAG_get0_safes(bag: PPKCS12_SAFEBAG): Pstack_st_PKCS12_SAFEBAG; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_get0_safes'; + +function PKCS12_SAFEBAG_get0_p8inf(bag: PPKCS12_SAFEBAG): PPKCS8_PRIV_KEY_INFO; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_get0_p8inf'; + +function PKCS12_SAFEBAG_get0_pkcs8(bag: PPKCS12_SAFEBAG): PX509_SIG; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_get0_pkcs8'; + +function PKCS12_SAFEBAG_create_cert(x509: PX509): PPKCS12_SAFEBAG; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_create_cert'; +function PKCS12_x5092certbag(x509: PX509): PPKCS12_SAFEBAG; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_create_cert'; + +function PKCS12_SAFEBAG_create_crl(crl: PX509_CRL): PPKCS12_SAFEBAG; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_create_crl'; +function PKCS12_x509crl2certbag(crl: PX509_CRL): PPKCS12_SAFEBAG; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_create_crl'; + +function PKCS12_SAFEBAG_create0_p8inf(p8: PPKCS8_PRIV_KEY_INFO): PPKCS12_SAFEBAG; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_create0_p8inf'; + +function PKCS12_SAFEBAG_create0_pkcs8(p8: PX509_SIG): PPKCS12_SAFEBAG; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_create0_pkcs8'; + +function PKCS12_SAFEBAG_create_pkcs8_encrypt(pbe_nid: Integer; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; salt: PByte; saltlen: Integer; iter: Integer; p8inf: PPKCS8_PRIV_KEY_INFO): PPKCS12_SAFEBAG; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_create_pkcs8_encrypt'; +function PKCS12_MAKE_SHKEYBAG(pbe_nid: Integer; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; salt: PByte; saltlen: Integer; iter: Integer; p8inf: PPKCS8_PRIV_KEY_INFO): PPKCS12_SAFEBAG; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_create_pkcs8_encrypt'; + +function PKCS12_item_pack_safebag(obj: Pointer; it: PASN1_ITEM; nid1: Integer; nid2: Integer): PPKCS12_SAFEBAG; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_item_pack_safebag'; + +function PKCS8_decrypt(p8: PX509_SIG; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer): PPKCS8_PRIV_KEY_INFO; cdecl; + external LIB_CRYPTO name _PU + 'PKCS8_decrypt'; + +function PKCS12_decrypt_skey(bag: PPKCS12_SAFEBAG; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer): PPKCS8_PRIV_KEY_INFO; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_decrypt_skey'; + +function PKCS8_encrypt(pbe_nid: Integer; cipher: PEVP_CIPHER; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; salt: PByte; saltlen: Integer; iter: Integer; p8: PPKCS8_PRIV_KEY_INFO): PX509_SIG; cdecl; + external LIB_CRYPTO name _PU + 'PKCS8_encrypt'; + +function PKCS8_set0_pbe(pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; p8inf: PPKCS8_PRIV_KEY_INFO; pbe: PX509_ALGOR): PX509_SIG; cdecl; + external LIB_CRYPTO name _PU + 'PKCS8_set0_pbe'; + +function PKCS12_pack_p7data(sk: Pstack_st_PKCS12_SAFEBAG): PPKCS7; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_pack_p7data'; + +function PKCS12_unpack_p7data(p7: PPKCS7): Pstack_st_PKCS12_SAFEBAG; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_unpack_p7data'; + +function PKCS12_pack_p7encdata(pbe_nid: Integer; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; salt: PByte; saltlen: Integer; iter: Integer; bags: Pstack_st_PKCS12_SAFEBAG): PPKCS7; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_pack_p7encdata'; + +function PKCS12_unpack_p7encdata(p7: PPKCS7; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer): Pstack_st_PKCS12_SAFEBAG; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_unpack_p7encdata'; + +function PKCS12_pack_authsafes(p12: PPKCS12; safes: Pstack_st_PKCS7): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_pack_authsafes'; + +function PKCS12_unpack_authsafes(p12: PPKCS12): Pstack_st_PKCS7; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_unpack_authsafes'; + +function PKCS12_add_localkeyid(bag: PPKCS12_SAFEBAG; name: PByte; namelen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_add_localkeyid'; + +function PKCS12_add_friendlyname_asc(bag: PPKCS12_SAFEBAG; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; namelen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_add_friendlyname_asc'; + +function PKCS12_add_friendlyname_utf8(bag: PPKCS12_SAFEBAG; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; namelen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_add_friendlyname_utf8'; +function PKCS12_add_friendlyname(bag: PPKCS12_SAFEBAG; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; namelen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_add_friendlyname_utf8'; + +function PKCS12_add_CSPName_asc(bag: PPKCS12_SAFEBAG; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; namelen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_add_CSPName_asc'; + +function PKCS12_add_friendlyname_uni(bag: PPKCS12_SAFEBAG; name: PByte; namelen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_add_friendlyname_uni'; + +function PKCS8_add_keyusage(p8: PPKCS8_PRIV_KEY_INFO; usage: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS8_add_keyusage'; + +function PKCS12_get_attr_gen(attrs: Pstack_st_X509_ATTRIBUTE; attr_nid: Integer): PASN1_TYPE; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_get_attr_gen'; + +function PKCS12_get_friendlyname(bag: PPKCS12_SAFEBAG): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_get_friendlyname'; + +function PKCS12_SAFEBAG_get0_attrs(bag: PPKCS12_SAFEBAG): Pstack_st_X509_ATTRIBUTE; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_get0_attrs'; + +function PKCS12_pbe_crypt(algor: PX509_ALGOR; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inlen: Integer; data: PPByte; datalen: PInteger; en_de: Integer): PByte; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_pbe_crypt'; + +function PKCS12_item_decrypt_d2i(algor: PX509_ALGOR; it: PASN1_ITEM; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; oct: PASN1_OCTET_STRING; zbuf: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_item_decrypt_d2i'; + +function PKCS12_item_i2d_encrypt(algor: PX509_ALGOR; it: PASN1_ITEM; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; obj: Pointer; zbuf: Integer): PASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_item_i2d_encrypt'; + +function PKCS12_init(mode: Integer): PPKCS12; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_init'; + +function PKCS12_key_gen_asc(pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; salt: PByte; saltlen: Integer; id: Integer; iter: Integer; n: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; md_type: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_key_gen_asc'; + +function PKCS12_key_gen_uni(pass: PByte; passlen: Integer; salt: PByte; saltlen: Integer; id: Integer; iter: Integer; n: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; md_type: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_key_gen_uni'; + +function PKCS12_key_gen_utf8(pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; salt: PByte; saltlen: Integer; id: Integer; iter: Integer; n: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; md_type: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_key_gen_utf8'; +function PKCS12_key_gen(pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; salt: PByte; saltlen: Integer; id: Integer; iter: Integer; n: Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; md_type: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_key_gen_utf8'; + +function PKCS12_PBE_keyivgen(ctx: PEVP_CIPHER_CTX; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; param: PASN1_TYPE; cipher: PEVP_CIPHER; md_type: PEVP_MD; en_de: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_PBE_keyivgen'; + +function PKCS12_gen_mac(p12: PPKCS12; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; mac: PByte; maclen: PCardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_gen_mac'; + +function PKCS12_verify_mac(p12: PPKCS12; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_verify_mac'; + +function PKCS12_set_mac(p12: PPKCS12; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; passlen: Integer; salt: PByte; saltlen: Integer; iter: Integer; md_type: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_set_mac'; + +function PKCS12_setup_mac(p12: PPKCS12; iter: Integer; salt: PByte; saltlen: Integer; md_type: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_setup_mac'; + +function OPENSSL_asc2uni(asc: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; asclen: Integer; uni: PPByte; unilen: PInteger): PByte; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_asc2uni'; + +function OPENSSL_uni2asc(uni: PByte; unilen: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_uni2asc'; + +function OPENSSL_utf82uni(asc: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; asclen: Integer; uni: PPByte; unilen: PInteger): PByte; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_utf82uni'; + +function OPENSSL_uni2utf8(uni: PByte; unilen: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'OPENSSL_uni2utf8'; + +function PKCS12_new(): PPKCS12; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_new'; + +procedure PKCS12_free(a: PPKCS12); cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_free'; + +function d2i_PKCS12(a: PPPKCS12; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPKCS12; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS12'; + +function i2d_PKCS12(a: PPKCS12; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS12'; + +function PKCS12_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_it'; + +function PKCS12_MAC_DATA_new(): PPKCS12_MAC_DATA; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_MAC_DATA_new'; + +procedure PKCS12_MAC_DATA_free(a: PPKCS12_MAC_DATA); cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_MAC_DATA_free'; + +function d2i_PKCS12_MAC_DATA(a: PPPKCS12_MAC_DATA; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPKCS12_MAC_DATA; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS12_MAC_DATA'; + +function i2d_PKCS12_MAC_DATA(a: PPKCS12_MAC_DATA; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS12_MAC_DATA'; + +function PKCS12_MAC_DATA_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_MAC_DATA_it'; + +function PKCS12_SAFEBAG_new(): PPKCS12_SAFEBAG; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_new'; + +procedure PKCS12_SAFEBAG_free(a: PPKCS12_SAFEBAG); cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_free'; + +function d2i_PKCS12_SAFEBAG(a: PPPKCS12_SAFEBAG; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPKCS12_SAFEBAG; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS12_SAFEBAG'; + +function i2d_PKCS12_SAFEBAG(a: PPKCS12_SAFEBAG; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS12_SAFEBAG'; + +function PKCS12_SAFEBAG_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAG_it'; + +function PKCS12_BAGS_new(): PPKCS12_BAGS; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_BAGS_new'; + +procedure PKCS12_BAGS_free(a: PPKCS12_BAGS); cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_BAGS_free'; + +function d2i_PKCS12_BAGS(a: PPPKCS12_BAGS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PPByte; len: Integer): PPKCS12_BAGS; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS12_BAGS'; + +function i2d_PKCS12_BAGS(a: PPKCS12_BAGS; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS12_BAGS'; + +function PKCS12_BAGS_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_BAGS_it'; + +function PKCS12_SAFEBAGS_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_SAFEBAGS_it'; + +function PKCS12_AUTHSAFES_it(): PASN1_ITEM; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_AUTHSAFES_it'; + +procedure PKCS12_PBE_add(); cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_PBE_add'; + +function PKCS12_parse(p12: PPKCS12; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; pkey: PPEVP_PKEY; cert: PPX509; ca: PPstack_st_X509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_parse'; + +function PKCS12_create(pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; pkey: PEVP_PKEY; cert: PX509; ca: Pstack_st_X509; nid_key: Integer; nid_cert: Integer; iter: Integer; mac_iter: Integer; keytype: Integer): PPKCS12; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_create'; + +function PKCS12_add_cert(pbags: PPstack_st_PKCS12_SAFEBAG; cert: PX509): PPKCS12_SAFEBAG; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_add_cert'; + +function PKCS12_add_key(pbags: PPstack_st_PKCS12_SAFEBAG; key: PEVP_PKEY; key_usage: Integer; iter: Integer; key_nid: Integer; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PPKCS12_SAFEBAG; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_add_key'; + +function PKCS12_add_safe(psafes: PPstack_st_PKCS7; bags: Pstack_st_PKCS12_SAFEBAG; safe_nid: Integer; iter: Integer; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_add_safe'; + +function PKCS12_add_safes(safes: Pstack_st_PKCS7; p7_nid: Integer): PPKCS12; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_add_safes'; + +function i2d_PKCS12_bio(bp: PBIO; p12: PPKCS12): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS12_bio'; + +function i2d_PKCS12_fp(fp: PPointer; p12: PPKCS12): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_PKCS12_fp'; + +function d2i_PKCS12_bio(bp: PBIO; p12: PPPKCS12): PPKCS12; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS12_bio'; + +function d2i_PKCS12_fp(fp: PPointer; p12: PPPKCS12): PPKCS12; cdecl; + external LIB_CRYPTO name _PU + 'd2i_PKCS12_fp'; + +function PKCS12_newpass(p12: PPKCS12; oldpass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; newpass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'PKCS12_newpass'; + +function RAND_DRBG_new({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; flags: Cardinal; parent: PRAND_DRBG): PRAND_DRBG; cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_new'; + +function RAND_DRBG_secure_new({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; flags: Cardinal; parent: PRAND_DRBG): PRAND_DRBG; cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_secure_new'; + +function RAND_DRBG_set(drbg: PRAND_DRBG; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_set'; + +function RAND_DRBG_set_defaults({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; flags: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_set_defaults'; + +function RAND_DRBG_instantiate(drbg: PRAND_DRBG; pers: PByte; perslen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_instantiate'; + +function RAND_DRBG_uninstantiate(drbg: PRAND_DRBG): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_uninstantiate'; + +procedure RAND_DRBG_free(drbg: PRAND_DRBG); cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_free'; + +function RAND_DRBG_reseed(drbg: PRAND_DRBG; adin: PByte; adinlen: NativeUInt; prediction_resistance: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_reseed'; + +function RAND_DRBG_generate(drbg: PRAND_DRBG; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outlen: NativeUInt; prediction_resistance: Integer; adin: PByte; adinlen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_generate'; + +function RAND_DRBG_bytes(drbg: PRAND_DRBG; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outlen: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_bytes'; + +function RAND_DRBG_set_reseed_interval(drbg: PRAND_DRBG; interval: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_set_reseed_interval'; + +function RAND_DRBG_set_reseed_time_interval(drbg: PRAND_DRBG; interval: Longint): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_set_reseed_time_interval'; + +function RAND_DRBG_set_reseed_defaults(master_reseed_interval: Cardinal; slave_reseed_interval: Cardinal; master_reseed_time_interval: Longint; slave_reseed_time_interval: Longint): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_set_reseed_defaults'; + +function RAND_DRBG_get0_master(): PRAND_DRBG; cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_get0_master'; + +function RAND_DRBG_get0_public(): PRAND_DRBG; cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_get0_public'; + +function RAND_DRBG_get0_private(): PRAND_DRBG; cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_get0_private'; + +function RAND_DRBG_set_ex_data(drbg: PRAND_DRBG; idx: Integer; arg: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_set_ex_data'; + +function RAND_DRBG_get_ex_data(drbg: PRAND_DRBG; idx: Integer): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_get_ex_data'; + +function RAND_DRBG_set_callbacks(drbg: PRAND_DRBG; get_entropy: RAND_DRBG_get_entropy_fn; cleanup_entropy: RAND_DRBG_cleanup_entropy_fn; get_nonce: RAND_DRBG_get_nonce_fn; cleanup_nonce: RAND_DRBG_cleanup_nonce_fn): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RAND_DRBG_set_callbacks'; + +procedure RC2_set_key(key: PRC2_KEY; len: Integer; data: PByte; bits: Integer); cdecl; + external LIB_CRYPTO name _PU + 'RC2_set_key'; + +procedure RC2_ecb_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; key: PRC2_KEY; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'RC2_ecb_encrypt'; + +procedure RC2_encrypt(data: PCardinal; key: PRC2_KEY); cdecl; + external LIB_CRYPTO name _PU + 'RC2_encrypt'; + +procedure RC2_decrypt(data: PCardinal; key: PRC2_KEY); cdecl; + external LIB_CRYPTO name _PU + 'RC2_decrypt'; + +procedure RC2_cbc_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: Integer; ks: PRC2_KEY; iv: PByte; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'RC2_cbc_encrypt'; + +procedure RC2_cfb64_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: Integer; schedule: PRC2_KEY; ivec: PByte; num: PInteger; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'RC2_cfb64_encrypt'; + +procedure RC2_ofb64_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; length: Integer; schedule: PRC2_KEY; ivec: PByte; num: PInteger); cdecl; + external LIB_CRYPTO name _PU + 'RC2_ofb64_encrypt'; + +function RC4_options(): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'RC4_options'; + +procedure RC4_set_key(key: PRC4_KEY; len: Integer; data: PByte); cdecl; + external LIB_CRYPTO name _PU + 'RC4_set_key'; + +procedure RC4(key: PRC4_KEY; len: NativeUInt; indata: PByte; outdata: PByte); cdecl; + external LIB_CRYPTO name _PU + 'RC4'; + +function RIPEMD160_Init(c: PRIPEMD160_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RIPEMD160_Init'; + +function RIPEMD160_Update(c: PRIPEMD160_CTX; data: Pointer; len: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RIPEMD160_Update'; + +function RIPEMD160_Final(md: PByte; c: PRIPEMD160_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'RIPEMD160_Final'; + +function RIPEMD160(d: PByte; n: NativeUInt; md: PByte): PByte; cdecl; + external LIB_CRYPTO name _PU + 'RIPEMD160'; + +procedure RIPEMD160_Transform(c: PRIPEMD160_CTX; b: PByte); cdecl; + external LIB_CRYPTO name _PU + 'RIPEMD160_Transform'; + +procedure SEED_set_key(rawkey: PByte; ks: PSEED_KEY_SCHEDULE); cdecl; + external LIB_CRYPTO name _PU + 'SEED_set_key'; + +procedure SEED_encrypt(s: PByte; d: PByte; ks: PSEED_KEY_SCHEDULE); cdecl; + external LIB_CRYPTO name _PU + 'SEED_encrypt'; + +procedure SEED_decrypt(s: PByte; d: PByte; ks: PSEED_KEY_SCHEDULE); cdecl; + external LIB_CRYPTO name _PU + 'SEED_decrypt'; + +procedure SEED_ecb_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; ks: PSEED_KEY_SCHEDULE; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'SEED_ecb_encrypt'; + +procedure SEED_cbc_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; ks: PSEED_KEY_SCHEDULE; ivec: PByte; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'SEED_cbc_encrypt'; + +procedure SEED_cfb128_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; ks: PSEED_KEY_SCHEDULE; ivec: PByte; num: PInteger; enc: Integer); cdecl; + external LIB_CRYPTO name _PU + 'SEED_cfb128_encrypt'; + +procedure SEED_ofb128_encrypt({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; len: NativeUInt; ks: PSEED_KEY_SCHEDULE; ivec: PByte; num: PInteger); cdecl; + external LIB_CRYPTO name _PU + 'SEED_ofb128_encrypt'; + +procedure SRP_user_pwd_free(user_pwd: PSRP_user_pwd); cdecl; + external LIB_CRYPTO name _PU + 'SRP_user_pwd_free'; + +function SRP_VBASE_new(seed_key: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PSRP_VBASE; cdecl; + external LIB_CRYPTO name _PU + 'SRP_VBASE_new'; + +procedure SRP_VBASE_free(vb: PSRP_VBASE); cdecl; + external LIB_CRYPTO name _PU + 'SRP_VBASE_free'; + +function SRP_VBASE_init(vb: PSRP_VBASE; verifier_file: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SRP_VBASE_init'; + +function SRP_VBASE_get_by_user(vb: PSRP_VBASE; username: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PSRP_user_pwd; cdecl; + external LIB_CRYPTO name _PU + 'SRP_VBASE_get_by_user'; + +function SRP_VBASE_get1_by_user(vb: PSRP_VBASE; username: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PSRP_user_pwd; cdecl; + external LIB_CRYPTO name _PU + 'SRP_VBASE_get1_by_user'; + +function SRP_create_verifier(user: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; salt: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; verifier: {$IFNDEF FPC}{$IF CompilerVersion > 21}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ELSE}PWideChar{$IFEND}{$ELSE}{$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}{$ENDIF}; N: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; g: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SRP_create_verifier'; + +function SRP_create_verifier_BN(user: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; salt: PPBIGNUM; verifier: PPBIGNUM; N: PBIGNUM; g: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SRP_create_verifier_BN'; + +function SRP_check_known_gN_param(g: PBIGNUM; N: PBIGNUM): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'SRP_check_known_gN_param'; + +function SRP_get_default_gN(id: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PSRP_gN; cdecl; + external LIB_CRYPTO name _PU + 'SRP_get_default_gN'; + +function SRP_Calc_server_key(A: PBIGNUM; v: PBIGNUM; u: PBIGNUM; b: PBIGNUM; N: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'SRP_Calc_server_key'; + +function SRP_Calc_B(b: PBIGNUM; N: PBIGNUM; g: PBIGNUM; v: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'SRP_Calc_B'; + +function SRP_Verify_A_mod_N(A: PBIGNUM; N: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SRP_Verify_A_mod_N'; + +function SRP_Calc_u(A: PBIGNUM; B: PBIGNUM; N: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'SRP_Calc_u'; + +function SRP_Calc_x(s: PBIGNUM; user: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'SRP_Calc_x'; + +function SRP_Calc_A(a: PBIGNUM; N: PBIGNUM; g: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'SRP_Calc_A'; + +function SRP_Calc_client_key(N: PBIGNUM; B: PBIGNUM; g: PBIGNUM; x: PBIGNUM; a: PBIGNUM; u: PBIGNUM): PBIGNUM; cdecl; + external LIB_CRYPTO name _PU + 'SRP_Calc_client_key'; + +function SRP_Verify_B_mod_N(B: PBIGNUM; N: PBIGNUM): Integer; cdecl; + external LIB_CRYPTO name _PU + 'SRP_Verify_B_mod_N'; + +function DTLSv1_listen(s: PSSL; client: PBIO_ADDR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'DTLSv1_listen'; + +procedure DTLS_set_timer_cb(s: PSSL; cb: DTLS_timer_cb); cdecl; + external LIB_CRYPTO name _PU + 'DTLS_set_timer_cb'; + +function ERR_load_OSSL_STORE_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_OSSL_STORE_strings'; + +function OSSL_STORE_open(uri: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ui_method: PUI_METHOD; ui_data: Pointer; post_process: OSSL_STORE_post_process_info_fn; post_process_data: Pointer): POSSL_STORE_CTX; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_open'; + +function OSSL_STORE_ctrl(ctx: POSSL_STORE_CTX; cmd: Integer): Integer varargs; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_ctrl'; + +function OSSL_STORE_vctrl(ctx: POSSL_STORE_CTX; cmd: Integer; args: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_vctrl'; + +function OSSL_STORE_load(ctx: POSSL_STORE_CTX): POSSL_STORE_INFO; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_load'; + +function OSSL_STORE_eof(ctx: POSSL_STORE_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_eof'; + +function OSSL_STORE_error(ctx: POSSL_STORE_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_error'; + +function OSSL_STORE_close(ctx: POSSL_STORE_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_close'; + +function OSSL_STORE_INFO_new_NAME(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): POSSL_STORE_INFO; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_new_NAME'; + +function OSSL_STORE_INFO_set0_NAME_description(info: POSSL_STORE_INFO; desc: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_set0_NAME_description'; + +function OSSL_STORE_INFO_new_PARAMS(params: PEVP_PKEY): POSSL_STORE_INFO; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_new_PARAMS'; + +function OSSL_STORE_INFO_new_PKEY(pkey: PEVP_PKEY): POSSL_STORE_INFO; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_new_PKEY'; + +function OSSL_STORE_INFO_new_CERT(x509: PX509): POSSL_STORE_INFO; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_new_CERT'; + +function OSSL_STORE_INFO_new_CRL(crl: PX509_CRL): POSSL_STORE_INFO; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_new_CRL'; + +function OSSL_STORE_INFO_get_type(info: POSSL_STORE_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_get_type'; + +function OSSL_STORE_INFO_get0_NAME(info: POSSL_STORE_INFO): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_get0_NAME'; + +function OSSL_STORE_INFO_get1_NAME(info: POSSL_STORE_INFO): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_get1_NAME'; + +function OSSL_STORE_INFO_get0_NAME_description(info: POSSL_STORE_INFO): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_get0_NAME_description'; + +function OSSL_STORE_INFO_get1_NAME_description(info: POSSL_STORE_INFO): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_get1_NAME_description'; + +function OSSL_STORE_INFO_get0_PARAMS(info: POSSL_STORE_INFO): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_get0_PARAMS'; + +function OSSL_STORE_INFO_get1_PARAMS(info: POSSL_STORE_INFO): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_get1_PARAMS'; + +function OSSL_STORE_INFO_get0_PKEY(info: POSSL_STORE_INFO): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_get0_PKEY'; + +function OSSL_STORE_INFO_get1_PKEY(info: POSSL_STORE_INFO): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_get1_PKEY'; + +function OSSL_STORE_INFO_get0_CERT(info: POSSL_STORE_INFO): PX509; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_get0_CERT'; + +function OSSL_STORE_INFO_get1_CERT(info: POSSL_STORE_INFO): PX509; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_get1_CERT'; + +function OSSL_STORE_INFO_get0_CRL(info: POSSL_STORE_INFO): PX509_CRL; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_get0_CRL'; + +function OSSL_STORE_INFO_get1_CRL(info: POSSL_STORE_INFO): PX509_CRL; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_get1_CRL'; + +function OSSL_STORE_INFO_type_string({$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_type_string'; + +procedure OSSL_STORE_INFO_free(info: POSSL_STORE_INFO); cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_INFO_free'; + +function OSSL_STORE_supports_search(ctx: POSSL_STORE_CTX; search_type: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_supports_search'; + +function OSSL_STORE_SEARCH_by_name(name: PX509_NAME): POSSL_STORE_SEARCH; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_SEARCH_by_name'; + +function OSSL_STORE_SEARCH_by_issuer_serial(name: PX509_NAME; serial: PASN1_INTEGER): POSSL_STORE_SEARCH; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_SEARCH_by_issuer_serial'; + +function OSSL_STORE_SEARCH_by_key_fingerprint(digest: PEVP_MD; bytes: PByte; len: NativeUInt): POSSL_STORE_SEARCH; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_SEARCH_by_key_fingerprint'; + +function OSSL_STORE_SEARCH_by_alias(alias: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): POSSL_STORE_SEARCH; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_SEARCH_by_alias'; + +procedure OSSL_STORE_SEARCH_free(search: POSSL_STORE_SEARCH); cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_SEARCH_free'; + +function OSSL_STORE_SEARCH_get_type(criterion: POSSL_STORE_SEARCH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_SEARCH_get_type'; + +function OSSL_STORE_SEARCH_get0_name(criterion: POSSL_STORE_SEARCH): PX509_NAME; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_SEARCH_get0_name'; + +function OSSL_STORE_SEARCH_get0_serial(criterion: POSSL_STORE_SEARCH): PASN1_INTEGER; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_SEARCH_get0_serial'; + +function OSSL_STORE_SEARCH_get0_bytes(criterion: POSSL_STORE_SEARCH; length: PNativeUInt): PByte; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_SEARCH_get0_bytes'; + +function OSSL_STORE_SEARCH_get0_string(criterion: POSSL_STORE_SEARCH): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_SEARCH_get0_string'; + +function OSSL_STORE_SEARCH_get0_digest(criterion: POSSL_STORE_SEARCH): PEVP_MD; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_SEARCH_get0_digest'; + +function OSSL_STORE_expect(ctx: POSSL_STORE_CTX; expected_type: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_expect'; + +function OSSL_STORE_find(ctx: POSSL_STORE_CTX; search: POSSL_STORE_SEARCH): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_find'; + +function OSSL_STORE_LOADER_new(e: PENGINE; scheme: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): POSSL_STORE_LOADER; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_LOADER_new'; + +function OSSL_STORE_LOADER_get0_engine(loader: POSSL_STORE_LOADER): PENGINE; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_LOADER_get0_engine'; + +function OSSL_STORE_LOADER_get0_scheme(loader: POSSL_STORE_LOADER): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_LOADER_get0_scheme'; + +function OSSL_STORE_LOADER_set_open(loader: POSSL_STORE_LOADER; open_function: OSSL_STORE_open_fn): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_LOADER_set_open'; + +function OSSL_STORE_LOADER_set_ctrl(loader: POSSL_STORE_LOADER; ctrl_function: OSSL_STORE_ctrl_fn): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_LOADER_set_ctrl'; + +function OSSL_STORE_LOADER_set_expect(loader: POSSL_STORE_LOADER; expect_function: OSSL_STORE_expect_fn): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_LOADER_set_expect'; + +function OSSL_STORE_LOADER_set_find(loader: POSSL_STORE_LOADER; find_function: OSSL_STORE_find_fn): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_LOADER_set_find'; + +function OSSL_STORE_LOADER_set_load(loader: POSSL_STORE_LOADER; load_function: OSSL_STORE_load_fn): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_LOADER_set_load'; + +function OSSL_STORE_LOADER_set_eof(loader: POSSL_STORE_LOADER; eof_function: OSSL_STORE_eof_fn): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_LOADER_set_eof'; + +function OSSL_STORE_LOADER_set_error(loader: POSSL_STORE_LOADER; error_function: OSSL_STORE_error_fn): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_LOADER_set_error'; + +function OSSL_STORE_LOADER_set_close(loader: POSSL_STORE_LOADER; close_function: OSSL_STORE_close_fn): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_LOADER_set_close'; + +procedure OSSL_STORE_LOADER_free(loader: POSSL_STORE_LOADER); cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_LOADER_free'; + +function OSSL_STORE_register_loader(loader: POSSL_STORE_LOADER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_register_loader'; + +function OSSL_STORE_unregister_loader(scheme: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): POSSL_STORE_LOADER; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_unregister_loader'; + +type + OSSL_STORE_do_all_loaders_do_function = procedure(loader: POSSL_STORE_LOADER; do_arg: Pointer); cdecl; + +function OSSL_STORE_do_all_loaders(do_function: OSSL_STORE_do_all_loaders_do_function; do_arg: Pointer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'OSSL_STORE_do_all_loaders'; + +function ERR_load_TS_strings(): Integer; cdecl; + external LIB_CRYPTO name _PU + 'ERR_load_TS_strings'; + +function TS_REQ_new(): PTS_REQ; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_new'; + +procedure TS_REQ_free(a: PTS_REQ); cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_free'; + +function i2d_TS_REQ(a: PTS_REQ; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_TS_REQ'; + +function d2i_TS_REQ(a: PPTS_REQ; pp: PPByte; length: Integer): PTS_REQ; cdecl; + external LIB_CRYPTO name _PU + 'd2i_TS_REQ'; + +function TS_REQ_dup(a: PTS_REQ): PTS_REQ; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_dup'; + +function d2i_TS_REQ_fp(fp: PPointer; a: PPTS_REQ): PTS_REQ; cdecl; + external LIB_CRYPTO name _PU + 'd2i_TS_REQ_fp'; + +function i2d_TS_REQ_fp(fp: PPointer; a: PTS_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_TS_REQ_fp'; + +function d2i_TS_REQ_bio(fp: PBIO; a: PPTS_REQ): PTS_REQ; cdecl; + external LIB_CRYPTO name _PU + 'd2i_TS_REQ_bio'; + +function i2d_TS_REQ_bio(fp: PBIO; a: PTS_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_TS_REQ_bio'; + +function TS_MSG_IMPRINT_new(): PTS_MSG_IMPRINT; cdecl; + external LIB_CRYPTO name _PU + 'TS_MSG_IMPRINT_new'; + +procedure TS_MSG_IMPRINT_free(a: PTS_MSG_IMPRINT); cdecl; + external LIB_CRYPTO name _PU + 'TS_MSG_IMPRINT_free'; + +function i2d_TS_MSG_IMPRINT(a: PTS_MSG_IMPRINT; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_TS_MSG_IMPRINT'; + +function d2i_TS_MSG_IMPRINT(a: PPTS_MSG_IMPRINT; pp: PPByte; length: Integer): PTS_MSG_IMPRINT; cdecl; + external LIB_CRYPTO name _PU + 'd2i_TS_MSG_IMPRINT'; + +function TS_MSG_IMPRINT_dup(a: PTS_MSG_IMPRINT): PTS_MSG_IMPRINT; cdecl; + external LIB_CRYPTO name _PU + 'TS_MSG_IMPRINT_dup'; + +function d2i_TS_MSG_IMPRINT_fp(fp: PPointer; a: PPTS_MSG_IMPRINT): PTS_MSG_IMPRINT; cdecl; + external LIB_CRYPTO name _PU + 'd2i_TS_MSG_IMPRINT_fp'; + +function i2d_TS_MSG_IMPRINT_fp(fp: PPointer; a: PTS_MSG_IMPRINT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_TS_MSG_IMPRINT_fp'; + +function d2i_TS_MSG_IMPRINT_bio(bio: PBIO; a: PPTS_MSG_IMPRINT): PTS_MSG_IMPRINT; cdecl; + external LIB_CRYPTO name _PU + 'd2i_TS_MSG_IMPRINT_bio'; + +function i2d_TS_MSG_IMPRINT_bio(bio: PBIO; a: PTS_MSG_IMPRINT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_TS_MSG_IMPRINT_bio'; + +function TS_RESP_new(): PTS_RESP; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_new'; + +procedure TS_RESP_free(a: PTS_RESP); cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_free'; + +function i2d_TS_RESP(a: PTS_RESP; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_TS_RESP'; + +function d2i_TS_RESP(a: PPTS_RESP; pp: PPByte; length: Integer): PTS_RESP; cdecl; + external LIB_CRYPTO name _PU + 'd2i_TS_RESP'; + +function PKCS7_to_TS_TST_INFO(token: PPKCS7): PTS_TST_INFO; cdecl; + external LIB_CRYPTO name _PU + 'PKCS7_to_TS_TST_INFO'; + +function TS_RESP_dup(a: PTS_RESP): PTS_RESP; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_dup'; + +function d2i_TS_RESP_fp(fp: PPointer; a: PPTS_RESP): PTS_RESP; cdecl; + external LIB_CRYPTO name _PU + 'd2i_TS_RESP_fp'; + +function i2d_TS_RESP_fp(fp: PPointer; a: PTS_RESP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_TS_RESP_fp'; + +function d2i_TS_RESP_bio(bio: PBIO; a: PPTS_RESP): PTS_RESP; cdecl; + external LIB_CRYPTO name _PU + 'd2i_TS_RESP_bio'; + +function i2d_TS_RESP_bio(bio: PBIO; a: PTS_RESP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_TS_RESP_bio'; + +function TS_STATUS_INFO_new(): PTS_STATUS_INFO; cdecl; + external LIB_CRYPTO name _PU + 'TS_STATUS_INFO_new'; + +procedure TS_STATUS_INFO_free(a: PTS_STATUS_INFO); cdecl; + external LIB_CRYPTO name _PU + 'TS_STATUS_INFO_free'; + +function i2d_TS_STATUS_INFO(a: PTS_STATUS_INFO; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_TS_STATUS_INFO'; + +function d2i_TS_STATUS_INFO(a: PPTS_STATUS_INFO; pp: PPByte; length: Integer): PTS_STATUS_INFO; cdecl; + external LIB_CRYPTO name _PU + 'd2i_TS_STATUS_INFO'; + +function TS_STATUS_INFO_dup(a: PTS_STATUS_INFO): PTS_STATUS_INFO; cdecl; + external LIB_CRYPTO name _PU + 'TS_STATUS_INFO_dup'; + +function TS_TST_INFO_new(): PTS_TST_INFO; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_new'; + +procedure TS_TST_INFO_free(a: PTS_TST_INFO); cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_free'; + +function i2d_TS_TST_INFO(a: PTS_TST_INFO; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_TS_TST_INFO'; + +function d2i_TS_TST_INFO(a: PPTS_TST_INFO; pp: PPByte; length: Integer): PTS_TST_INFO; cdecl; + external LIB_CRYPTO name _PU + 'd2i_TS_TST_INFO'; + +function TS_TST_INFO_dup(a: PTS_TST_INFO): PTS_TST_INFO; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_dup'; + +function d2i_TS_TST_INFO_fp(fp: PPointer; a: PPTS_TST_INFO): PTS_TST_INFO; cdecl; + external LIB_CRYPTO name _PU + 'd2i_TS_TST_INFO_fp'; + +function i2d_TS_TST_INFO_fp(fp: PPointer; a: PTS_TST_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_TS_TST_INFO_fp'; + +function d2i_TS_TST_INFO_bio(bio: PBIO; a: PPTS_TST_INFO): PTS_TST_INFO; cdecl; + external LIB_CRYPTO name _PU + 'd2i_TS_TST_INFO_bio'; + +function i2d_TS_TST_INFO_bio(bio: PBIO; a: PTS_TST_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_TS_TST_INFO_bio'; + +function TS_ACCURACY_new(): PTS_ACCURACY; cdecl; + external LIB_CRYPTO name _PU + 'TS_ACCURACY_new'; + +procedure TS_ACCURACY_free(a: PTS_ACCURACY); cdecl; + external LIB_CRYPTO name _PU + 'TS_ACCURACY_free'; + +function i2d_TS_ACCURACY(a: PTS_ACCURACY; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_TS_ACCURACY'; + +function d2i_TS_ACCURACY(a: PPTS_ACCURACY; pp: PPByte; length: Integer): PTS_ACCURACY; cdecl; + external LIB_CRYPTO name _PU + 'd2i_TS_ACCURACY'; + +function TS_ACCURACY_dup(a: PTS_ACCURACY): PTS_ACCURACY; cdecl; + external LIB_CRYPTO name _PU + 'TS_ACCURACY_dup'; + +function ESS_ISSUER_SERIAL_new(): PESS_ISSUER_SERIAL; cdecl; + external LIB_CRYPTO name _PU + 'ESS_ISSUER_SERIAL_new'; + +procedure ESS_ISSUER_SERIAL_free(a: PESS_ISSUER_SERIAL); cdecl; + external LIB_CRYPTO name _PU + 'ESS_ISSUER_SERIAL_free'; + +function i2d_ESS_ISSUER_SERIAL(a: PESS_ISSUER_SERIAL; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ESS_ISSUER_SERIAL'; + +function d2i_ESS_ISSUER_SERIAL(a: PPESS_ISSUER_SERIAL; pp: PPByte; length: Integer): PESS_ISSUER_SERIAL; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ESS_ISSUER_SERIAL'; + +function ESS_ISSUER_SERIAL_dup(a: PESS_ISSUER_SERIAL): PESS_ISSUER_SERIAL; cdecl; + external LIB_CRYPTO name _PU + 'ESS_ISSUER_SERIAL_dup'; + +function ESS_CERT_ID_new(): PESS_CERT_ID; cdecl; + external LIB_CRYPTO name _PU + 'ESS_CERT_ID_new'; + +procedure ESS_CERT_ID_free(a: PESS_CERT_ID); cdecl; + external LIB_CRYPTO name _PU + 'ESS_CERT_ID_free'; + +function i2d_ESS_CERT_ID(a: PESS_CERT_ID; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ESS_CERT_ID'; + +function d2i_ESS_CERT_ID(a: PPESS_CERT_ID; pp: PPByte; length: Integer): PESS_CERT_ID; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ESS_CERT_ID'; + +function ESS_CERT_ID_dup(a: PESS_CERT_ID): PESS_CERT_ID; cdecl; + external LIB_CRYPTO name _PU + 'ESS_CERT_ID_dup'; + +function ESS_SIGNING_CERT_new(): PESS_SIGNING_CERT; cdecl; + external LIB_CRYPTO name _PU + 'ESS_SIGNING_CERT_new'; + +procedure ESS_SIGNING_CERT_free(a: PESS_SIGNING_CERT); cdecl; + external LIB_CRYPTO name _PU + 'ESS_SIGNING_CERT_free'; + +function i2d_ESS_SIGNING_CERT(a: PESS_SIGNING_CERT; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ESS_SIGNING_CERT'; + +function d2i_ESS_SIGNING_CERT(a: PPESS_SIGNING_CERT; pp: PPByte; length: Integer): PESS_SIGNING_CERT; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ESS_SIGNING_CERT'; + +function ESS_SIGNING_CERT_dup(a: PESS_SIGNING_CERT): PESS_SIGNING_CERT; cdecl; + external LIB_CRYPTO name _PU + 'ESS_SIGNING_CERT_dup'; + +function ESS_CERT_ID_V2_new(): PESS_CERT_ID_V2; cdecl; + external LIB_CRYPTO name _PU + 'ESS_CERT_ID_V2_new'; + +procedure ESS_CERT_ID_V2_free(a: PESS_CERT_ID_V2); cdecl; + external LIB_CRYPTO name _PU + 'ESS_CERT_ID_V2_free'; + +function i2d_ESS_CERT_ID_V2(a: PESS_CERT_ID_V2; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ESS_CERT_ID_V2'; + +function d2i_ESS_CERT_ID_V2(a: PPESS_CERT_ID_V2; pp: PPByte; length: Integer): PESS_CERT_ID_V2; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ESS_CERT_ID_V2'; + +function ESS_CERT_ID_V2_dup(a: PESS_CERT_ID_V2): PESS_CERT_ID_V2; cdecl; + external LIB_CRYPTO name _PU + 'ESS_CERT_ID_V2_dup'; + +function ESS_SIGNING_CERT_V2_new(): PESS_SIGNING_CERT_V2; cdecl; + external LIB_CRYPTO name _PU + 'ESS_SIGNING_CERT_V2_new'; + +procedure ESS_SIGNING_CERT_V2_free(a: PESS_SIGNING_CERT_V2); cdecl; + external LIB_CRYPTO name _PU + 'ESS_SIGNING_CERT_V2_free'; + +function i2d_ESS_SIGNING_CERT_V2(a: PESS_SIGNING_CERT_V2; pp: PPByte): Integer; cdecl; + external LIB_CRYPTO name _PU + 'i2d_ESS_SIGNING_CERT_V2'; + +function d2i_ESS_SIGNING_CERT_V2(a: PPESS_SIGNING_CERT_V2; pp: PPByte; length: Integer): PESS_SIGNING_CERT_V2; cdecl; + external LIB_CRYPTO name _PU + 'd2i_ESS_SIGNING_CERT_V2'; + +function ESS_SIGNING_CERT_V2_dup(a: PESS_SIGNING_CERT_V2): PESS_SIGNING_CERT_V2; cdecl; + external LIB_CRYPTO name _PU + 'ESS_SIGNING_CERT_V2_dup'; + +function TS_REQ_set_version(a: PTS_REQ; version: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_set_version'; + +function TS_REQ_get_version(a: PTS_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_get_version'; + +function TS_STATUS_INFO_set_status(a: PTS_STATUS_INFO; i: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_STATUS_INFO_set_status'; + +function TS_STATUS_INFO_get0_status(a: PTS_STATUS_INFO): PASN1_INTEGER; cdecl; + external LIB_CRYPTO name _PU + 'TS_STATUS_INFO_get0_status'; + +function TS_STATUS_INFO_get0_text(a: PTS_STATUS_INFO): Pstack_st_ASN1_UTF8STRING; cdecl; + external LIB_CRYPTO name _PU + 'TS_STATUS_INFO_get0_text'; + +function TS_STATUS_INFO_get0_failure_info(a: PTS_STATUS_INFO): PASN1_BIT_STRING; cdecl; + external LIB_CRYPTO name _PU + 'TS_STATUS_INFO_get0_failure_info'; + +function TS_REQ_set_msg_imprint(a: PTS_REQ; msg_imprint: PTS_MSG_IMPRINT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_set_msg_imprint'; + +function TS_REQ_get_msg_imprint(a: PTS_REQ): PTS_MSG_IMPRINT; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_get_msg_imprint'; + +function TS_MSG_IMPRINT_set_algo(a: PTS_MSG_IMPRINT; alg: PX509_ALGOR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_MSG_IMPRINT_set_algo'; + +function TS_MSG_IMPRINT_get_algo(a: PTS_MSG_IMPRINT): PX509_ALGOR; cdecl; + external LIB_CRYPTO name _PU + 'TS_MSG_IMPRINT_get_algo'; + +function TS_MSG_IMPRINT_set_msg(a: PTS_MSG_IMPRINT; d: PByte; len: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_MSG_IMPRINT_set_msg'; + +function TS_MSG_IMPRINT_get_msg(a: PTS_MSG_IMPRINT): PASN1_OCTET_STRING; cdecl; + external LIB_CRYPTO name _PU + 'TS_MSG_IMPRINT_get_msg'; + +function TS_REQ_set_policy_id(a: PTS_REQ; policy: PASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_set_policy_id'; + +function TS_REQ_get_policy_id(a: PTS_REQ): PASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_get_policy_id'; + +function TS_REQ_set_nonce(a: PTS_REQ; nonce: PASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_set_nonce'; + +function TS_REQ_get_nonce(a: PTS_REQ): PASN1_INTEGER; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_get_nonce'; + +function TS_REQ_set_cert_req(a: PTS_REQ; cert_req: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_set_cert_req'; + +function TS_REQ_get_cert_req(a: PTS_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_get_cert_req'; + +function TS_REQ_get_exts(a: PTS_REQ): Pstack_st_X509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_get_exts'; + +procedure TS_REQ_ext_free(a: PTS_REQ); cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_ext_free'; + +function TS_REQ_get_ext_count(a: PTS_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_get_ext_count'; + +function TS_REQ_get_ext_by_NID(a: PTS_REQ; nid: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_get_ext_by_NID'; + +function TS_REQ_get_ext_by_OBJ(a: PTS_REQ; obj: PASN1_OBJECT; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_get_ext_by_OBJ'; + +function TS_REQ_get_ext_by_critical(a: PTS_REQ; crit: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_get_ext_by_critical'; + +function TS_REQ_get_ext(a: PTS_REQ; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_get_ext'; + +function TS_REQ_delete_ext(a: PTS_REQ; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_delete_ext'; + +function TS_REQ_add_ext(a: PTS_REQ; ex: PX509_EXTENSION; loc: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_add_ext'; + +function TS_REQ_get_ext_d2i(a: PTS_REQ; nid: Integer; crit: PInteger; idx: PInteger): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_get_ext_d2i'; + +function TS_REQ_print_bio(bio: PBIO; a: PTS_REQ): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_print_bio'; + +function TS_RESP_set_status_info(a: PTS_RESP; info: PTS_STATUS_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_set_status_info'; + +function TS_RESP_get_status_info(a: PTS_RESP): PTS_STATUS_INFO; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_get_status_info'; + +procedure TS_RESP_set_tst_info(a: PTS_RESP; p7: PPKCS7; tst_info: PTS_TST_INFO); cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_set_tst_info'; + +function TS_RESP_get_token(a: PTS_RESP): PPKCS7; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_get_token'; + +function TS_RESP_get_tst_info(a: PTS_RESP): PTS_TST_INFO; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_get_tst_info'; + +function TS_TST_INFO_set_version(a: PTS_TST_INFO; version: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_set_version'; + +function TS_TST_INFO_get_version(a: PTS_TST_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_get_version'; + +function TS_TST_INFO_set_policy_id(a: PTS_TST_INFO; policy_id: PASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_set_policy_id'; + +function TS_TST_INFO_get_policy_id(a: PTS_TST_INFO): PASN1_OBJECT; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_get_policy_id'; + +function TS_TST_INFO_set_msg_imprint(a: PTS_TST_INFO; msg_imprint: PTS_MSG_IMPRINT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_set_msg_imprint'; + +function TS_TST_INFO_get_msg_imprint(a: PTS_TST_INFO): PTS_MSG_IMPRINT; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_get_msg_imprint'; + +function TS_TST_INFO_set_serial(a: PTS_TST_INFO; serial: PASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_set_serial'; + +function TS_TST_INFO_get_serial(a: PTS_TST_INFO): PASN1_INTEGER; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_get_serial'; + +function TS_TST_INFO_set_time(a: PTS_TST_INFO; gtime: PASN1_GENERALIZEDTIME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_set_time'; + +function TS_TST_INFO_get_time(a: PTS_TST_INFO): PASN1_GENERALIZEDTIME; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_get_time'; + +function TS_TST_INFO_set_accuracy(a: PTS_TST_INFO; accuracy: PTS_ACCURACY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_set_accuracy'; + +function TS_TST_INFO_get_accuracy(a: PTS_TST_INFO): PTS_ACCURACY; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_get_accuracy'; + +function TS_ACCURACY_set_seconds(a: PTS_ACCURACY; seconds: PASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_ACCURACY_set_seconds'; + +function TS_ACCURACY_get_seconds(a: PTS_ACCURACY): PASN1_INTEGER; cdecl; + external LIB_CRYPTO name _PU + 'TS_ACCURACY_get_seconds'; + +function TS_ACCURACY_set_millis(a: PTS_ACCURACY; millis: PASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_ACCURACY_set_millis'; + +function TS_ACCURACY_get_millis(a: PTS_ACCURACY): PASN1_INTEGER; cdecl; + external LIB_CRYPTO name _PU + 'TS_ACCURACY_get_millis'; + +function TS_ACCURACY_set_micros(a: PTS_ACCURACY; micros: PASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_ACCURACY_set_micros'; + +function TS_ACCURACY_get_micros(a: PTS_ACCURACY): PASN1_INTEGER; cdecl; + external LIB_CRYPTO name _PU + 'TS_ACCURACY_get_micros'; + +function TS_TST_INFO_set_ordering(a: PTS_TST_INFO; ordering: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_set_ordering'; + +function TS_TST_INFO_get_ordering(a: PTS_TST_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_get_ordering'; + +function TS_TST_INFO_set_nonce(a: PTS_TST_INFO; nonce: PASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_set_nonce'; + +function TS_TST_INFO_get_nonce(a: PTS_TST_INFO): PASN1_INTEGER; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_get_nonce'; + +function TS_TST_INFO_set_tsa(a: PTS_TST_INFO; tsa: PGENERAL_NAME): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_set_tsa'; + +function TS_TST_INFO_get_tsa(a: PTS_TST_INFO): PGENERAL_NAME; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_get_tsa'; + +function TS_TST_INFO_get_exts(a: PTS_TST_INFO): Pstack_st_X509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_get_exts'; + +procedure TS_TST_INFO_ext_free(a: PTS_TST_INFO); cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_ext_free'; + +function TS_TST_INFO_get_ext_count(a: PTS_TST_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_get_ext_count'; + +function TS_TST_INFO_get_ext_by_NID(a: PTS_TST_INFO; nid: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_get_ext_by_NID'; + +function TS_TST_INFO_get_ext_by_OBJ(a: PTS_TST_INFO; obj: PASN1_OBJECT; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_get_ext_by_OBJ'; + +function TS_TST_INFO_get_ext_by_critical(a: PTS_TST_INFO; crit: Integer; lastpos: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_get_ext_by_critical'; + +function TS_TST_INFO_get_ext(a: PTS_TST_INFO; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_get_ext'; + +function TS_TST_INFO_delete_ext(a: PTS_TST_INFO; loc: Integer): PX509_EXTENSION; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_delete_ext'; + +function TS_TST_INFO_add_ext(a: PTS_TST_INFO; ex: PX509_EXTENSION; loc: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_add_ext'; + +function TS_TST_INFO_get_ext_d2i(a: PTS_TST_INFO; nid: Integer; crit: PInteger; idx: PInteger): Pointer; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_get_ext_d2i'; + +function TS_RESP_CTX_new(): PTS_RESP_CTX; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_new'; + +procedure TS_RESP_CTX_free(ctx: PTS_RESP_CTX); cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_free'; + +function TS_RESP_CTX_set_signer_cert(ctx: PTS_RESP_CTX; signer: PX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_set_signer_cert'; + +function TS_RESP_CTX_set_signer_key(ctx: PTS_RESP_CTX; key: PEVP_PKEY): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_set_signer_key'; + +function TS_RESP_CTX_set_signer_digest(ctx: PTS_RESP_CTX; signer_digest: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_set_signer_digest'; + +function TS_RESP_CTX_set_ess_cert_id_digest(ctx: PTS_RESP_CTX; md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_set_ess_cert_id_digest'; + +function TS_RESP_CTX_set_def_policy(ctx: PTS_RESP_CTX; def_policy: PASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_set_def_policy'; + +function TS_RESP_CTX_set_certs(ctx: PTS_RESP_CTX; certs: Pstack_st_X509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_set_certs'; + +function TS_RESP_CTX_add_policy(ctx: PTS_RESP_CTX; policy: PASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_add_policy'; + +function TS_RESP_CTX_add_md(ctx: PTS_RESP_CTX; md: PEVP_MD): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_add_md'; + +function TS_RESP_CTX_set_accuracy(ctx: PTS_RESP_CTX; secs: Integer; millis: Integer; micros: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_set_accuracy'; + +function TS_RESP_CTX_set_clock_precision_digits(ctx: PTS_RESP_CTX; clock_precision_digits: Cardinal): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_set_clock_precision_digits'; + +procedure TS_RESP_CTX_add_flags(ctx: PTS_RESP_CTX; flags: Integer); cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_add_flags'; + +procedure TS_RESP_CTX_set_serial_cb(ctx: PTS_RESP_CTX; cb: TS_serial_cb; data: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_set_serial_cb'; + +procedure TS_RESP_CTX_set_time_cb(ctx: PTS_RESP_CTX; cb: TS_time_cb; data: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_set_time_cb'; + +procedure TS_RESP_CTX_set_extension_cb(ctx: PTS_RESP_CTX; cb: TS_extension_cb; data: Pointer); cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_set_extension_cb'; + +function TS_RESP_CTX_set_status_info(ctx: PTS_RESP_CTX; status: Integer; text: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_set_status_info'; + +function TS_RESP_CTX_set_status_info_cond(ctx: PTS_RESP_CTX; status: Integer; text: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_set_status_info_cond'; + +function TS_RESP_CTX_add_failure_info(ctx: PTS_RESP_CTX; failure: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_add_failure_info'; + +function TS_RESP_CTX_get_request(ctx: PTS_RESP_CTX): PTS_REQ; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_get_request'; + +function TS_RESP_CTX_get_tst_info(ctx: PTS_RESP_CTX): PTS_TST_INFO; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_CTX_get_tst_info'; + +function TS_RESP_create_response(ctx: PTS_RESP_CTX; req_bio: PBIO): PTS_RESP; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_create_response'; + +function TS_RESP_verify_signature(token: PPKCS7; certs: Pstack_st_X509; store: PX509_STORE; signer_out: PPX509): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_verify_signature'; + +function TS_RESP_verify_response(ctx: PTS_VERIFY_CTX; response: PTS_RESP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_verify_response'; + +function TS_RESP_verify_token(ctx: PTS_VERIFY_CTX; token: PPKCS7): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_verify_token'; + +function TS_VERIFY_CTX_new(): PTS_VERIFY_CTX; cdecl; + external LIB_CRYPTO name _PU + 'TS_VERIFY_CTX_new'; + +procedure TS_VERIFY_CTX_init(ctx: PTS_VERIFY_CTX); cdecl; + external LIB_CRYPTO name _PU + 'TS_VERIFY_CTX_init'; + +procedure TS_VERIFY_CTX_free(ctx: PTS_VERIFY_CTX); cdecl; + external LIB_CRYPTO name _PU + 'TS_VERIFY_CTX_free'; + +procedure TS_VERIFY_CTX_cleanup(ctx: PTS_VERIFY_CTX); cdecl; + external LIB_CRYPTO name _PU + 'TS_VERIFY_CTX_cleanup'; + +function TS_VERIFY_CTX_set_flags(ctx: PTS_VERIFY_CTX; f: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_VERIFY_CTX_set_flags'; + +function TS_VERIFY_CTX_add_flags(ctx: PTS_VERIFY_CTX; f: Integer): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_VERIFY_CTX_add_flags'; + +function TS_VERIFY_CTX_set_data(ctx: PTS_VERIFY_CTX; b: PBIO): PBIO; cdecl; + external LIB_CRYPTO name _PU + 'TS_VERIFY_CTX_set_data'; + +function TS_VERIFY_CTX_set_imprint(ctx: PTS_VERIFY_CTX; hexstr: PByte; len: Integer): PByte; cdecl; + external LIB_CRYPTO name _PU + 'TS_VERIFY_CTX_set_imprint'; + +function TS_VERIFY_CTX_set_store(ctx: PTS_VERIFY_CTX; s: PX509_STORE): PX509_STORE; cdecl; + external LIB_CRYPTO name _PU + 'TS_VERIFY_CTX_set_store'; + +function TS_VERIFY_CTS_set_certs(ctx: PTS_VERIFY_CTX; certs: Pstack_st_X509): Pstack_st_X509; cdecl; + external LIB_CRYPTO name _PU + 'TS_VERIFY_CTS_set_certs'; + +function TS_REQ_to_TS_VERIFY_CTX(req: PTS_REQ; ctx: PTS_VERIFY_CTX): PTS_VERIFY_CTX; cdecl; + external LIB_CRYPTO name _PU + 'TS_REQ_to_TS_VERIFY_CTX'; + +function TS_RESP_print_bio(bio: PBIO; a: PTS_RESP): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_RESP_print_bio'; + +function TS_STATUS_INFO_print_bio(bio: PBIO; a: PTS_STATUS_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_STATUS_INFO_print_bio'; + +function TS_TST_INFO_print_bio(bio: PBIO; a: PTS_TST_INFO): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_TST_INFO_print_bio'; + +function TS_ASN1_INTEGER_print_bio(bio: PBIO; num: PASN1_INTEGER): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_ASN1_INTEGER_print_bio'; + +function TS_OBJ_print_bio(bio: PBIO; obj: PASN1_OBJECT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_OBJ_print_bio'; + +function TS_ext_print_bio(bio: PBIO; extensions: Pstack_st_X509_EXTENSION): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_ext_print_bio'; + +function TS_X509_ALGOR_print_bio(bio: PBIO; alg: PX509_ALGOR): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_X509_ALGOR_print_bio'; + +function TS_MSG_IMPRINT_print_bio(bio: PBIO; msg: PTS_MSG_IMPRINT): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_MSG_IMPRINT_print_bio'; + +function TS_CONF_load_cert({$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PX509; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_load_cert'; + +function TS_CONF_load_certs({$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Pstack_st_X509; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_load_certs'; + +function TS_CONF_load_key({$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): PEVP_PKEY; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_load_key'; + +function TS_CONF_get_tsa_section(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_get_tsa_section'; + +function TS_CONF_set_serial(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cb: TS_serial_cb; ctx: PTS_RESP_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_set_serial'; + +function TS_CONF_set_crypto_device(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; device: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_set_crypto_device'; + +function TS_CONF_set_default_engine(name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_set_default_engine'; + +function TS_CONF_set_signer_cert(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cert: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ctx: PTS_RESP_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_set_signer_cert'; + +function TS_CONF_set_certs(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; certs: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ctx: PTS_RESP_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_set_certs'; + +function TS_CONF_set_signer_key(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; key: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ctx: PTS_RESP_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_set_signer_key'; + +function TS_CONF_set_signer_digest(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; md: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ctx: PTS_RESP_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_set_signer_digest'; + +function TS_CONF_set_def_policy(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; policy: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ctx: PTS_RESP_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_set_def_policy'; + +function TS_CONF_set_policies(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ctx: PTS_RESP_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_set_policies'; + +function TS_CONF_set_digests(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ctx: PTS_RESP_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_set_digests'; + +function TS_CONF_set_accuracy(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ctx: PTS_RESP_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_set_accuracy'; + +function TS_CONF_set_clock_precision_digits(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ctx: PTS_RESP_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_set_clock_precision_digits'; + +function TS_CONF_set_ordering(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ctx: PTS_RESP_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_set_ordering'; + +function TS_CONF_set_tsa_name(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ctx: PTS_RESP_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_set_tsa_name'; + +function TS_CONF_set_ess_cert_id_chain(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ctx: PTS_RESP_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_set_ess_cert_id_chain'; + +function TS_CONF_set_ess_cert_id_digest(conf: PCONF; section: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; ctx: PTS_RESP_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TS_CONF_set_ess_cert_id_digest'; + +function TXT_DB_read({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PBIO; num: Integer): PTXT_DB; cdecl; + external LIB_CRYPTO name _PU + 'TXT_DB_read'; + +function TXT_DB_write({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PBIO; db: PTXT_DB): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TXT_DB_write'; + +type + TXT_DB_create_index_qual = function(p1: POPENSSL_STRING): Integer; cdecl; + +function TXT_DB_create_index(db: PTXT_DB; field: Integer; qual: TXT_DB_create_index_qual; hash: OPENSSL_LH_HASHFUNC; cmp: OPENSSL_LH_COMPFUNC): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TXT_DB_create_index'; + +procedure TXT_DB_free(db: PTXT_DB); cdecl; + external LIB_CRYPTO name _PU + 'TXT_DB_free'; + +function TXT_DB_get_by_index(db: PTXT_DB; idx: Integer; value: POPENSSL_STRING): POPENSSL_STRING; cdecl; + external LIB_CRYPTO name _PU + 'TXT_DB_get_by_index'; + +function TXT_DB_insert(db: PTXT_DB; value: POPENSSL_STRING): Integer; cdecl; + external LIB_CRYPTO name _PU + 'TXT_DB_insert'; + +function WHIRLPOOL_Init(c: PWHIRLPOOL_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'WHIRLPOOL_Init'; + +function WHIRLPOOL_Update(c: PWHIRLPOOL_CTX; inp: Pointer; bytes: NativeUInt): Integer; cdecl; + external LIB_CRYPTO name _PU + 'WHIRLPOOL_Update'; + +procedure WHIRLPOOL_BitUpdate(c: PWHIRLPOOL_CTX; inp: Pointer; bits: NativeUInt); cdecl; + external LIB_CRYPTO name _PU + 'WHIRLPOOL_BitUpdate'; + +function WHIRLPOOL_Final(md: PByte; c: PWHIRLPOOL_CTX): Integer; cdecl; + external LIB_CRYPTO name _PU + 'WHIRLPOOL_Final'; + +function WHIRLPOOL(inp: Pointer; bytes: NativeUInt; md: PByte): PByte; cdecl; + external LIB_CRYPTO name _PU + 'WHIRLPOOL'; + +{ Ssl Library } + +function BIO_f_ssl(): PBIO_METHOD; cdecl; + external LIB_SSL name _PU + 'BIO_f_ssl'; + +function BIO_new_ssl(ctx: PSSL_CTX; client: Integer): PBIO; cdecl; + external LIB_SSL name _PU + 'BIO_new_ssl'; + +function BIO_new_ssl_connect(ctx: PSSL_CTX): PBIO; cdecl; + external LIB_SSL name _PU + 'BIO_new_ssl_connect'; + +function BIO_new_buffer_ssl_connect(ctx: PSSL_CTX): PBIO; cdecl; + external LIB_SSL name _PU + 'BIO_new_buffer_ssl_connect'; + +function BIO_ssl_copy_session_id({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PBIO; from: PBIO): Integer; cdecl; + external LIB_SSL name _PU + 'BIO_ssl_copy_session_id'; + +procedure BIO_ssl_shutdown(ssl_bio: PBIO); cdecl; + external LIB_SSL name _PU + 'BIO_ssl_shutdown'; + +function DTLSv1_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'DTLSv1_method'; + +function DTLSv1_server_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'DTLSv1_server_method'; + +function DTLSv1_client_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'DTLSv1_client_method'; + +function DTLSv1_2_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'DTLSv1_2_method'; + +function DTLSv1_2_server_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'DTLSv1_2_server_method'; + +function DTLSv1_2_client_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'DTLSv1_2_client_method'; + +function DTLS_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'DTLS_method'; + +function DTLS_server_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'DTLS_server_method'; + +function DTLS_client_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'DTLS_client_method'; + +function DTLS_get_data_mtu(s: PSSL): NativeUInt; cdecl; + external LIB_SSL name _PU + 'DTLS_get_data_mtu'; + +function ERR_load_SSL_strings(): Integer; cdecl; + external LIB_SSL name _PU + 'ERR_load_SSL_strings'; + +function OPENSSL_cipher_name(rfc_name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'OPENSSL_cipher_name'; + +function OPENSSL_init_ssl(opts: UInt64; settings: POPENSSL_INIT_SETTINGS): Integer; cdecl; + external LIB_SSL name _PU + 'OPENSSL_init_ssl'; + +function PEM_read_bio_SSL_SESSION(bp: PBIO; x: PPSSL_SESSION; cb: Ppem_password_cb; u: Pointer): PSSL_SESSION; cdecl; + external LIB_SSL name _PU + 'PEM_read_bio_SSL_SESSION'; + +function PEM_read_SSL_SESSION(fp: PPointer; x: PPSSL_SESSION; cb: Ppem_password_cb; u: Pointer): PSSL_SESSION; cdecl; + external LIB_SSL name _PU + 'PEM_read_SSL_SESSION'; + +function PEM_write_bio_SSL_SESSION(bp: PBIO; x: PSSL_SESSION): Integer; cdecl; + external LIB_SSL name _PU + 'PEM_write_bio_SSL_SESSION'; + +function PEM_write_SSL_SESSION(fp: PPointer; x: PSSL_SESSION): Integer; cdecl; + external LIB_SSL name _PU + 'PEM_write_SSL_SESSION'; + +function SRP_Calc_A_param(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SRP_Calc_A_param'; + +function i2d_SSL_SESSION({$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PSSL_SESSION; pp: PPByte): Integer; cdecl; + external LIB_SSL name _PU + 'i2d_SSL_SESSION'; + +function d2i_SSL_SESSION(a: PPSSL_SESSION; pp: PPByte; length: Integer): PSSL_SESSION; cdecl; + external LIB_SSL name _PU + 'd2i_SSL_SESSION'; + +function SSL_get_peer_certificate(s: PSSL): PX509; cdecl; + external LIB_SSL name _PU + 'SSL_get_peer_certificate'; + +function SSL_get_peer_cert_chain(s: PSSL): Pstack_st_X509; cdecl; + external LIB_SSL name _PU + 'SSL_get_peer_cert_chain'; + +function SSL_CTX_get_verify_mode(ctx: PSSL_CTX): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_verify_mode'; + +function SSL_CTX_get_verify_depth(ctx: PSSL_CTX): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_verify_depth'; + +function SSL_CTX_get_verify_callback(ctx: PSSL_CTX): SSL_verify_cb; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_verify_callback'; + +procedure SSL_CTX_set_verify(ctx: PSSL_CTX; mode: Integer; callback: SSL_verify_cb); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_verify'; + +procedure SSL_CTX_set_verify_depth(ctx: PSSL_CTX; depth: Integer); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_verify_depth'; + +type + SSL_CTX_set_cert_verify_callback_cb = function(p1: PX509_STORE_CTX; p2: Pointer): Integer; cdecl; + +procedure SSL_CTX_set_cert_verify_callback(ctx: PSSL_CTX; cb: SSL_CTX_set_cert_verify_callback_cb; arg: Pointer); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_cert_verify_callback'; + +type + SSL_CTX_set_cert_cb_cb = function(ssl: PSSL; arg: Pointer): Integer; cdecl; + +procedure SSL_CTX_set_cert_cb(c: PSSL_CTX; cb: SSL_CTX_set_cert_cb_cb; arg: Pointer); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_cert_cb'; + +function SSL_CTX_use_RSAPrivateKey(ctx: PSSL_CTX; rsa: PRSA): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_use_RSAPrivateKey'; + +function SSL_CTX_use_RSAPrivateKey_ASN1(ctx: PSSL_CTX; d: PByte; len: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_use_RSAPrivateKey_ASN1'; + +function SSL_CTX_use_PrivateKey(ctx: PSSL_CTX; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_use_PrivateKey'; + +function SSL_CTX_use_PrivateKey_ASN1(pk: Integer; ctx: PSSL_CTX; d: PByte; len: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_use_PrivateKey_ASN1'; + +function SSL_CTX_use_certificate(ctx: PSSL_CTX; x: PX509): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_use_certificate'; + +function SSL_CTX_use_certificate_ASN1(ctx: PSSL_CTX; len: Integer; d: PByte): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_use_certificate_ASN1'; + +function SSL_CTX_use_cert_and_key(ctx: PSSL_CTX; x509: PX509; privatekey: PEVP_PKEY; chain: Pstack_st_X509; {$IFNDEF FPC}{$IF CompilerVersion > 21}&override{$ELSE}override1{$IFEND}{$ELSE}&override{$ENDIF}: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_use_cert_and_key'; + +procedure SSL_CTX_set_default_passwd_cb(ctx: PSSL_CTX; cb: Ppem_password_cb); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_default_passwd_cb'; + +procedure SSL_CTX_set_default_passwd_cb_userdata(ctx: PSSL_CTX; u: Pointer); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_default_passwd_cb_userdata'; + +function SSL_CTX_get_default_passwd_cb(ctx: PSSL_CTX): Ppem_password_cb; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_default_passwd_cb'; + +function SSL_CTX_get_default_passwd_cb_userdata(ctx: PSSL_CTX): Pointer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_default_passwd_cb_userdata'; + +procedure SSL_set_default_passwd_cb(s: PSSL; cb: Ppem_password_cb); cdecl; + external LIB_SSL name _PU + 'SSL_set_default_passwd_cb'; + +procedure SSL_set_default_passwd_cb_userdata(s: PSSL; u: Pointer); cdecl; + external LIB_SSL name _PU + 'SSL_set_default_passwd_cb_userdata'; + +function SSL_get_default_passwd_cb(s: PSSL): Ppem_password_cb; cdecl; + external LIB_SSL name _PU + 'SSL_get_default_passwd_cb'; + +function SSL_get_default_passwd_cb_userdata(s: PSSL): Pointer; cdecl; + external LIB_SSL name _PU + 'SSL_get_default_passwd_cb_userdata'; + +function SSL_CTX_check_private_key(ctx: PSSL_CTX): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_check_private_key'; + +function SSL_check_private_key(ctx: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_check_private_key'; + +function SSL_CTX_set_session_id_context(ctx: PSSL_CTX; sid_ctx: PByte; sid_ctx_len: Cardinal): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_session_id_context'; + +function SSL_new(ctx: PSSL_CTX): PSSL; cdecl; + external LIB_SSL name _PU + 'SSL_new'; + +function SSL_up_ref(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_up_ref'; + +function SSL_is_dtls(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_is_dtls'; + +function SSL_set_session_id_context(ssl: PSSL; sid_ctx: PByte; sid_ctx_len: Cardinal): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_session_id_context'; + +function SSL_CTX_set_purpose(ctx: PSSL_CTX; purpose: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_purpose'; + +function SSL_set_purpose(ssl: PSSL; purpose: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_purpose'; + +function SSL_CTX_set_trust(ctx: PSSL_CTX; trust: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_trust'; + +function SSL_set_trust(ssl: PSSL; trust: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_trust'; + +function SSL_set1_host(s: PSSL; hostname: PAnsiChar): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set1_host'; + +function SSL_add1_host(s: PSSL; hostname: PAnsiChar): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_add1_host'; + +function SSL_get0_peername(s: PSSL): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_get0_peername'; + +procedure SSL_set_hostflags(s: PSSL; flags: Cardinal); cdecl; + external LIB_SSL name _PU + 'SSL_set_hostflags'; + +function SSL_CTX_dane_enable(ctx: PSSL_CTX): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_dane_enable'; + +function SSL_CTX_dane_mtype_set(ctx: PSSL_CTX; md: PEVP_MD; mtype: {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt8{$ELSE}LongInt{$IFEND}{$ELSE}UInt8{$ENDIF}; ord: {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt8{$ELSE}LongInt{$IFEND}{$ELSE}UInt8{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_dane_mtype_set'; + +function SSL_dane_enable(s: PSSL; basedomain: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_dane_enable'; + +function SSL_dane_tlsa_add(s: PSSL; usage: {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt8{$ELSE}LongInt{$IFEND}{$ELSE}UInt8{$ENDIF}; selector: {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt8{$ELSE}LongInt{$IFEND}{$ELSE}UInt8{$ENDIF}; mtype: {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt8{$ELSE}LongInt{$IFEND}{$ELSE}UInt8{$ENDIF}; data: PByte; dlen: NativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_dane_tlsa_add'; + +function SSL_get0_dane_authority(s: PSSL; mcert: PPX509; mspki: PPEVP_PKEY): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get0_dane_authority'; + +function SSL_get0_dane_tlsa(s: PSSL; usage: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUInt8{$ELSE}PLongInt{$IFEND}{$ELSE}PUInt8{$ENDIF}; selector: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUInt8{$ELSE}PLongInt{$IFEND}{$ELSE}PUInt8{$ENDIF}; mtype: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUInt8{$ELSE}PLongInt{$IFEND}{$ELSE}PUInt8{$ENDIF}; data: PPByte; dlen: PNativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get0_dane_tlsa'; + +function SSL_get0_dane(ssl: PSSL): PSSL_DANE; cdecl; + external LIB_SSL name _PU + 'SSL_get0_dane'; + +function SSL_CTX_dane_set_flags(ctx: PSSL_CTX; flags: Cardinal): Cardinal; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_dane_set_flags'; + +function SSL_CTX_dane_clear_flags(ctx: PSSL_CTX; flags: Cardinal): Cardinal; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_dane_clear_flags'; + +function SSL_dane_set_flags(ssl: PSSL; flags: Cardinal): Cardinal; cdecl; + external LIB_SSL name _PU + 'SSL_dane_set_flags'; + +function SSL_dane_clear_flags(ssl: PSSL; flags: Cardinal): Cardinal; cdecl; + external LIB_SSL name _PU + 'SSL_dane_clear_flags'; + +function SSL_CTX_set1_param(ctx: PSSL_CTX; vpm: PX509_VERIFY_PARAM): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set1_param'; + +function SSL_set1_param(ssl: PSSL; vpm: PX509_VERIFY_PARAM): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set1_param'; + +function SSL_CTX_get0_param(ctx: PSSL_CTX): PX509_VERIFY_PARAM; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get0_param'; + +function SSL_get0_param(ssl: PSSL): PX509_VERIFY_PARAM; cdecl; + external LIB_SSL name _PU + 'SSL_get0_param'; + +function SSL_CTX_set_srp_username(ctx: PSSL_CTX; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_srp_username'; + +function SSL_CTX_set_srp_password(ctx: PSSL_CTX; password: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_srp_password'; + +function SSL_CTX_set_srp_strength(ctx: PSSL_CTX; strength: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_srp_strength'; + +type + SSL_CTX_set_srp_client_pwd_callback_cb = function(p1: PSSL; p2: Pointer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + +function SSL_CTX_set_srp_client_pwd_callback(ctx: PSSL_CTX; cb: SSL_CTX_set_srp_client_pwd_callback_cb): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_srp_client_pwd_callback'; + +type + SSL_CTX_set_srp_verify_param_callback_cb = function(p1: PSSL; p2: Pointer): Integer; cdecl; + +function SSL_CTX_set_srp_verify_param_callback(ctx: PSSL_CTX; cb: SSL_CTX_set_srp_verify_param_callback_cb): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_srp_verify_param_callback'; + +type + SSL_CTX_set_srp_username_callback_cb = function(p1: PSSL; p2: PInteger; p3: Pointer): Integer; cdecl; + +function SSL_CTX_set_srp_username_callback(ctx: PSSL_CTX; cb: SSL_CTX_set_srp_username_callback_cb): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_srp_username_callback'; + +function SSL_CTX_set_srp_cb_arg(ctx: PSSL_CTX; arg: Pointer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_srp_cb_arg'; + +function SSL_set_srp_server_param(s: PSSL; N: PBIGNUM; g: PBIGNUM; sa: PBIGNUM; v: PBIGNUM; info: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_srp_server_param'; + +function SSL_set_srp_server_param_pw(s: PSSL; user: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; pass: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; grp: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_srp_server_param_pw'; + +function SSL_get_srp_g(s: PSSL): PBIGNUM; cdecl; + external LIB_SSL name _PU + 'SSL_get_srp_g'; + +function SSL_get_srp_N(s: PSSL): PBIGNUM; cdecl; + external LIB_SSL name _PU + 'SSL_get_srp_N'; + +function SSL_get_srp_username(s: PSSL): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_get_srp_username'; + +function SSL_get_srp_userinfo(s: PSSL): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_get_srp_userinfo'; + +procedure SSL_CTX_set_client_hello_cb(c: PSSL_CTX; cb: SSL_client_hello_cb_fn; arg: Pointer); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_client_hello_cb'; + +function SSL_client_hello_isv2(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_client_hello_isv2'; + +function SSL_client_hello_get0_legacy_version(s: PSSL): Cardinal; cdecl; + external LIB_SSL name _PU + 'SSL_client_hello_get0_legacy_version'; + +function SSL_client_hello_get0_random(s: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): NativeUInt; cdecl; + external LIB_SSL name _PU + 'SSL_client_hello_get0_random'; + +function SSL_client_hello_get0_session_id(s: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): NativeUInt; cdecl; + external LIB_SSL name _PU + 'SSL_client_hello_get0_session_id'; + +function SSL_client_hello_get0_ciphers(s: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): NativeUInt; cdecl; + external LIB_SSL name _PU + 'SSL_client_hello_get0_ciphers'; + +function SSL_client_hello_get0_compression_methods(s: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte): NativeUInt; cdecl; + external LIB_SSL name _PU + 'SSL_client_hello_get0_compression_methods'; + +function SSL_client_hello_get1_extensions_present(s: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPInteger; outlen: PNativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_client_hello_get1_extensions_present'; + +function SSL_client_hello_get0_ext(s: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Cardinal; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte; outlen: PNativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_client_hello_get0_ext'; + +procedure SSL_certs_clear(s: PSSL); cdecl; + external LIB_SSL name _PU + 'SSL_certs_clear'; + +procedure SSL_free(ssl: PSSL); cdecl; + external LIB_SSL name _PU + 'SSL_free'; + +function SSL_accept(ssl: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_accept'; + +function SSL_stateless(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_stateless'; + +function SSL_connect(ssl: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_connect'; + +function SSL_read(ssl: PSSL; buf: Pointer; num: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_read'; + +function SSL_read_ex(ssl: PSSL; buf: Pointer; num: NativeUInt; readbytes: PNativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_read_ex'; + +function SSL_read_early_data(s: PSSL; buf: Pointer; num: NativeUInt; readbytes: PNativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_read_early_data'; + +function SSL_peek(ssl: PSSL; buf: Pointer; num: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_peek'; + +function SSL_peek_ex(ssl: PSSL; buf: Pointer; num: NativeUInt; readbytes: PNativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_peek_ex'; + +function SSL_write(ssl: PSSL; buf: Pointer; num: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_write'; + +function SSL_write_ex(s: PSSL; buf: Pointer; num: NativeUInt; written: PNativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_write_ex'; + +function SSL_write_early_data(s: PSSL; buf: Pointer; num: NativeUInt; written: PNativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_write_early_data'; + +function SSL_ctrl(ssl: PSSL; cmd: Integer; larg: Integer; parg: Pointer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_ctrl'; + +type + SSL_callback_ctrl_ = procedure(); cdecl; + +function SSL_callback_ctrl(p1: PSSL; p2: Integer; p3: SSL_callback_ctrl_): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_callback_ctrl'; + +function SSL_CTX_ctrl(ctx: PSSL_CTX; cmd: Integer; larg: Integer; parg: Pointer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_ctrl'; + +type + SSL_CTX_callback_ctrl_ = procedure(); cdecl; + +function SSL_CTX_callback_ctrl(p1: PSSL_CTX; p2: Integer; p3: SSL_CTX_callback_ctrl_): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_callback_ctrl'; + +function SSL_get_early_data_status(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_early_data_status'; + +function SSL_get_error(s: PSSL; ret_code: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_error'; + +function SSL_get_version(s: PSSL): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_get_version'; + +function SSL_CTX_set_ssl_version(ctx: PSSL_CTX; meth: PSSL_METHOD): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_ssl_version'; + +function SSL_get_ciphers(s: PSSL): Pstack_st_SSL_CIPHER; cdecl; + external LIB_SSL name _PU + 'SSL_get_ciphers'; + +function SSL_CTX_get_ciphers(ctx: PSSL_CTX): Pstack_st_SSL_CIPHER; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_ciphers'; + +function SSL_get_client_ciphers(s: PSSL): Pstack_st_SSL_CIPHER; cdecl; + external LIB_SSL name _PU + 'SSL_get_client_ciphers'; + +function SSL_get1_supported_ciphers(s: PSSL): Pstack_st_SSL_CIPHER; cdecl; + external LIB_SSL name _PU + 'SSL_get1_supported_ciphers'; + +function SSL_do_handshake(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_do_handshake'; + +function SSL_key_update(s: PSSL; updatetype: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_key_update'; + +function SSL_get_key_update_type(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_key_update_type'; + +function SSL_renegotiate(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_renegotiate'; + +function SSL_renegotiate_abbreviated(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_renegotiate_abbreviated'; + +function SSL_renegotiate_pending(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_renegotiate_pending'; + +function SSL_shutdown(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_shutdown'; + +function SSL_verify_client_post_handshake(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_verify_client_post_handshake'; + +procedure SSL_CTX_set_post_handshake_auth(ctx: PSSL_CTX; val: Integer); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_post_handshake_auth'; + +procedure SSL_set_post_handshake_auth(s: PSSL; val: Integer); cdecl; + external LIB_SSL name _PU + 'SSL_set_post_handshake_auth'; + +function SSL_CTX_get_ssl_method(ctx: PSSL_CTX): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_ssl_method'; + +function SSL_get_ssl_method(s: PSSL): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'SSL_get_ssl_method'; + +function SSL_set_ssl_method(s: PSSL; method: PSSL_METHOD): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_ssl_method'; + +function SSL_alert_type_string_long(value: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_alert_type_string_long'; + +function SSL_alert_type_string(value: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_alert_type_string'; + +function SSL_alert_desc_string_long(value: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_alert_desc_string_long'; + +function SSL_alert_desc_string(value: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_alert_desc_string'; + +procedure SSL_set0_CA_list(s: PSSL; name_list: Pstack_st_X509_NAME); cdecl; + external LIB_SSL name _PU + 'SSL_set0_CA_list'; + +procedure SSL_CTX_set0_CA_list(ctx: PSSL_CTX; name_list: Pstack_st_X509_NAME); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set0_CA_list'; + +function SSL_get0_CA_list(s: PSSL): Pstack_st_X509_NAME; cdecl; + external LIB_SSL name _PU + 'SSL_get0_CA_list'; + +function SSL_CTX_get0_CA_list(ctx: PSSL_CTX): Pstack_st_X509_NAME; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get0_CA_list'; + +function SSL_add1_to_CA_list(ssl: PSSL; x: PX509): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_add1_to_CA_list'; + +function SSL_CTX_add1_to_CA_list(ctx: PSSL_CTX; x: PX509): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_add1_to_CA_list'; + +function SSL_get0_peer_CA_list(s: PSSL): Pstack_st_X509_NAME; cdecl; + external LIB_SSL name _PU + 'SSL_get0_peer_CA_list'; + +procedure SSL_set_client_CA_list(s: PSSL; name_list: Pstack_st_X509_NAME); cdecl; + external LIB_SSL name _PU + 'SSL_set_client_CA_list'; + +procedure SSL_CTX_set_client_CA_list(ctx: PSSL_CTX; name_list: Pstack_st_X509_NAME); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_client_CA_list'; + +function SSL_get_client_CA_list(s: PSSL): Pstack_st_X509_NAME; cdecl; + external LIB_SSL name _PU + 'SSL_get_client_CA_list'; + +function SSL_CTX_get_client_CA_list(s: PSSL_CTX): Pstack_st_X509_NAME; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_client_CA_list'; + +function SSL_add_client_CA(ssl: PSSL; x: PX509): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_add_client_CA'; + +function SSL_CTX_add_client_CA(ctx: PSSL_CTX; x: PX509): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_add_client_CA'; + +procedure SSL_set_connect_state(s: PSSL); cdecl; + external LIB_SSL name _PU + 'SSL_set_connect_state'; + +procedure SSL_set_accept_state(s: PSSL); cdecl; + external LIB_SSL name _PU + 'SSL_set_accept_state'; + +function SSL_get_default_timeout(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_default_timeout'; + +function SSL_CIPHER_description(p1: PSSL_CIPHER; buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; size: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_CIPHER_description'; + +function SSL_dup_CA_list(sk: Pstack_st_X509_NAME): Pstack_st_X509_NAME; cdecl; + external LIB_SSL name _PU + 'SSL_dup_CA_list'; + +function SSL_dup(ssl: PSSL): PSSL; cdecl; + external LIB_SSL name _PU + 'SSL_dup'; + +function SSL_get_certificate(ssl: PSSL): PX509; cdecl; + external LIB_SSL name _PU + 'SSL_get_certificate'; + +function SSL_get_privatekey(ssl: PSSL): Pevp_pkey_st; cdecl; + external LIB_SSL name _PU + 'SSL_get_privatekey'; + +function SSL_CTX_get0_certificate(ctx: PSSL_CTX): PX509; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get0_certificate'; + +function SSL_CTX_get0_privatekey(ctx: PSSL_CTX): PEVP_PKEY; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get0_privatekey'; + +procedure SSL_CTX_set_quiet_shutdown(ctx: PSSL_CTX; mode: Integer); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_quiet_shutdown'; + +function SSL_CTX_get_quiet_shutdown(ctx: PSSL_CTX): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_quiet_shutdown'; + +procedure SSL_set_quiet_shutdown(ssl: PSSL; mode: Integer); cdecl; + external LIB_SSL name _PU + 'SSL_set_quiet_shutdown'; + +function SSL_get_quiet_shutdown(ssl: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_quiet_shutdown'; + +procedure SSL_set_shutdown(ssl: PSSL; mode: Integer); cdecl; + external LIB_SSL name _PU + 'SSL_set_shutdown'; + +function SSL_get_shutdown(ssl: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_shutdown'; + +function SSL_version(ssl: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_version'; + +function SSL_client_version(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_client_version'; + +function SSL_CTX_set_default_verify_paths(ctx: PSSL_CTX): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_default_verify_paths'; + +function SSL_CTX_set_default_verify_dir(ctx: PSSL_CTX): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_default_verify_dir'; + +function SSL_CTX_set_default_verify_file(ctx: PSSL_CTX): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_default_verify_file'; + +function SSL_CTX_load_verify_locations(ctx: PSSL_CTX; CAfile: PAnsiChar; CApath: PAnsiChar): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_load_verify_locations'; + +function SSL_get_session(ssl: PSSL): PSSL_SESSION; cdecl; + external LIB_SSL name _PU + 'SSL_get_session'; +function SSL_get0_session(ssl: PSSL): PSSL_SESSION; cdecl; + external LIB_SSL name _PU + 'SSL_get_session'; + +function SSL_get1_session(ssl: PSSL): PSSL_SESSION; cdecl; + external LIB_SSL name _PU + 'SSL_get1_session'; + +function SSL_get_SSL_CTX(ssl: PSSL): PSSL_CTX; cdecl; + external LIB_SSL name _PU + 'SSL_get_SSL_CTX'; + +function SSL_set_SSL_CTX(ssl: PSSL; ctx: PSSL_CTX): PSSL_CTX; cdecl; + external LIB_SSL name _PU + 'SSL_set_SSL_CTX'; + +type + SSL_set_info_callback_cb = procedure(ssl: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; val: Integer); cdecl; + +procedure SSL_set_info_callback(ssl: PSSL; cb: SSL_set_info_callback_cb); cdecl; + external LIB_SSL name _PU + 'SSL_set_info_callback'; + +//function SSL_get_info_callback(ssl: PSSL{$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integerval: Integerssl: PSSL): Integer { TODO : Cannot convert original type "void (*)(const SSL *, int, int)" }; cdecl; +// external LIB_SSL name _PU + 'SSL_get_info_callback'; + +function SSL_get_state(ssl: PSSL): OSSL_HANDSHAKE_STATE; cdecl; + external LIB_SSL name _PU + 'SSL_get_state'; + +procedure SSL_set_verify_result(ssl: PSSL; v: Integer); cdecl; + external LIB_SSL name _PU + 'SSL_set_verify_result'; + +function SSL_get_verify_result(ssl: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_verify_result'; + +function SSL_get0_verified_chain(s: PSSL): Pstack_st_X509; cdecl; + external LIB_SSL name _PU + 'SSL_get0_verified_chain'; + +function SSL_get_client_random(ssl: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outlen: NativeUInt): NativeUInt; cdecl; + external LIB_SSL name _PU + 'SSL_get_client_random'; + +function SSL_get_server_random(ssl: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outlen: NativeUInt): NativeUInt; cdecl; + external LIB_SSL name _PU + 'SSL_get_server_random'; + +function SSL_SESSION_get_master_key(sess: PSSL_SESSION; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; outlen: NativeUInt): NativeUInt; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_get_master_key'; + +function SSL_SESSION_set1_master_key(sess: PSSL_SESSION; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; len: NativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_set1_master_key'; + +function SSL_SESSION_get_max_fragment_length(sess: PSSL_SESSION): {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt8{$ELSE}LongInt{$IFEND}{$ELSE}UInt8{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_get_max_fragment_length'; + +function SSL_set_ex_data(ssl: PSSL; idx: Integer; data: Pointer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_ex_data'; + +function SSL_get_ex_data(ssl: PSSL; idx: Integer): Pointer; cdecl; + external LIB_SSL name _PU + 'SSL_get_ex_data'; + +function SSL_SESSION_set_ex_data(ss: PSSL_SESSION; idx: Integer; data: Pointer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_set_ex_data'; + +function SSL_SESSION_get_ex_data(ss: PSSL_SESSION; idx: Integer): Pointer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_get_ex_data'; + +function SSL_CTX_set_ex_data(ssl: PSSL_CTX; idx: Integer; data: Pointer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_ex_data'; + +function SSL_CTX_get_ex_data(ssl: PSSL_CTX; idx: Integer): Pointer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_ex_data'; + +function SSL_get_ex_data_X509_STORE_CTX_idx(): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_ex_data_X509_STORE_CTX_idx'; + +procedure SSL_CTX_set_default_read_buffer_len(ctx: PSSL_CTX; len: NativeUInt); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_default_read_buffer_len'; + +procedure SSL_set_default_read_buffer_len(s: PSSL; len: NativeUInt); cdecl; + external LIB_SSL name _PU + 'SSL_set_default_read_buffer_len'; + +type + SSL_CTX_set_tmp_dh_callback_dh = function(ssl: PSSL; is_export: Integer; keylength: Integer): Pdh_st; cdecl; + +procedure SSL_CTX_set_tmp_dh_callback(ctx: PSSL_CTX; dh: SSL_CTX_set_tmp_dh_callback_dh); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_tmp_dh_callback'; + +type + SSL_set_tmp_dh_callback_dh = function(ssl: PSSL; is_export: Integer; keylength: Integer): Pdh_st; cdecl; + +procedure SSL_set_tmp_dh_callback(ssl: PSSL; dh: SSL_set_tmp_dh_callback_dh); cdecl; + external LIB_SSL name _PU + 'SSL_set_tmp_dh_callback'; + +function SSL_get_current_compression(s: PSSL): PCOMP_METHOD; cdecl; + external LIB_SSL name _PU + 'SSL_get_current_compression'; + +function SSL_get_current_expansion(s: PSSL): PCOMP_METHOD; cdecl; + external LIB_SSL name _PU + 'SSL_get_current_expansion'; + +function SSL_COMP_get_name(comp: PCOMP_METHOD): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_COMP_get_name'; + +function SSL_COMP_get0_name(comp: PSSL_COMP): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_COMP_get0_name'; + +function SSL_COMP_get_id(comp: PSSL_COMP): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_COMP_get_id'; + +function SSL_COMP_get_compression_methods(): Pstack_st_SSL_COMP; cdecl; + external LIB_SSL name _PU + 'SSL_COMP_get_compression_methods'; + +function SSL_COMP_set0_compression_methods(meths: Pstack_st_SSL_COMP): Pstack_st_SSL_COMP; cdecl; + external LIB_SSL name _PU + 'SSL_COMP_set0_compression_methods'; + +function SSL_COMP_add_compression_method(id: Integer; cm: PCOMP_METHOD): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_COMP_add_compression_method'; + +function SSL_CIPHER_find(ssl: PSSL; ptr: PByte): PSSL_CIPHER; cdecl; + external LIB_SSL name _PU + 'SSL_CIPHER_find'; + +function SSL_CIPHER_get_cipher_nid(c: PSSL_CIPHER): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CIPHER_get_cipher_nid'; + +function SSL_CIPHER_get_digest_nid(c: PSSL_CIPHER): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CIPHER_get_digest_nid'; + +function SSL_bytes_to_cipher_list(s: PSSL; bytes: PByte; len: NativeUInt; isv2format: Integer; sk: PPstack_st_SSL_CIPHER; scsvs: PPstack_st_SSL_CIPHER): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_bytes_to_cipher_list'; + +function SSL_set_session_ticket_ext(s: PSSL; ext_data: Pointer; ext_len: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_session_ticket_ext'; + +function SSL_set_session_ticket_ext_cb(s: PSSL; cb: tls_session_ticket_ext_cb_fn; arg: Pointer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_session_ticket_ext_cb'; + +function SSL_set_session_secret_cb(s: PSSL; session_secret_cb: tls_session_secret_cb_fn; arg: Pointer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_session_secret_cb'; + +type + SSL_CTX_set_not_resumable_session_callback_cb = function(ssl: PSSL; is_forward_secure: Integer): Integer; cdecl; + +procedure SSL_CTX_set_not_resumable_session_callback(ctx: PSSL_CTX; cb: SSL_CTX_set_not_resumable_session_callback_cb); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_not_resumable_session_callback'; + +type + SSL_set_not_resumable_session_callback_cb = function(ssl: PSSL; is_forward_secure: Integer): Integer; cdecl; + +procedure SSL_set_not_resumable_session_callback(ssl: PSSL; cb: SSL_set_not_resumable_session_callback_cb); cdecl; + external LIB_SSL name _PU + 'SSL_set_not_resumable_session_callback'; + +type + SSL_CTX_set_record_padding_callback_cb = function(ssl: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; len: NativeUInt; arg: Pointer): UInt64; cdecl; + +procedure SSL_CTX_set_record_padding_callback(ctx: PSSL_CTX; cb: SSL_CTX_set_record_padding_callback_cb); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_record_padding_callback'; + +procedure SSL_CTX_set_record_padding_callback_arg(ctx: PSSL_CTX; arg: Pointer); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_record_padding_callback_arg'; + +function SSL_CTX_get_record_padding_callback_arg(ctx: PSSL_CTX): Pointer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_record_padding_callback_arg'; + +function SSL_CTX_set_block_padding(ctx: PSSL_CTX; block_size: NativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_block_padding'; + +type + SSL_set_record_padding_callback_cb = function(ssl: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; len: NativeUInt; arg: Pointer): UInt64; cdecl; + +procedure SSL_set_record_padding_callback(ssl: PSSL; cb: SSL_set_record_padding_callback_cb); cdecl; + external LIB_SSL name _PU + 'SSL_set_record_padding_callback'; + +procedure SSL_set_record_padding_callback_arg(ssl: PSSL; arg: Pointer); cdecl; + external LIB_SSL name _PU + 'SSL_set_record_padding_callback_arg'; + +function SSL_get_record_padding_callback_arg(ssl: PSSL): Pointer; cdecl; + external LIB_SSL name _PU + 'SSL_get_record_padding_callback_arg'; + +function SSL_set_block_padding(ssl: PSSL; block_size: NativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_block_padding'; + +function SSL_set_num_tickets(s: PSSL; num_tickets: NativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_num_tickets'; + +function SSL_get_num_tickets(s: PSSL): NativeUInt; cdecl; + external LIB_SSL name _PU + 'SSL_get_num_tickets'; + +function SSL_CTX_set_num_tickets(ctx: PSSL_CTX; num_tickets: NativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_num_tickets'; + +function SSL_CTX_get_num_tickets(ctx: PSSL_CTX): NativeUInt; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_num_tickets'; + +function SSL_session_reused(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_session_reused'; + +function SSL_is_server(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_is_server'; + +function SSL_CONF_CTX_new(): PSSL_CONF_CTX; cdecl; + external LIB_SSL name _PU + 'SSL_CONF_CTX_new'; + +function SSL_CONF_CTX_finish(cctx: PSSL_CONF_CTX): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CONF_CTX_finish'; + +procedure SSL_CONF_CTX_free(cctx: PSSL_CONF_CTX); cdecl; + external LIB_SSL name _PU + 'SSL_CONF_CTX_free'; + +function SSL_CONF_CTX_set_flags(cctx: PSSL_CONF_CTX; flags: Cardinal): Cardinal; cdecl; + external LIB_SSL name _PU + 'SSL_CONF_CTX_set_flags'; + +function SSL_CONF_CTX_clear_flags(cctx: PSSL_CONF_CTX; flags: Cardinal): Cardinal; cdecl; + external LIB_SSL name _PU + 'SSL_CONF_CTX_clear_flags'; + +function SSL_CONF_CTX_set1_prefix(cctx: PSSL_CONF_CTX; pre: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CONF_CTX_set1_prefix'; + +procedure SSL_CONF_CTX_set_ssl(cctx: PSSL_CONF_CTX; ssl: PSSL); cdecl; + external LIB_SSL name _PU + 'SSL_CONF_CTX_set_ssl'; + +procedure SSL_CONF_CTX_set_ssl_ctx(cctx: PSSL_CONF_CTX; ctx: PSSL_CTX); cdecl; + external LIB_SSL name _PU + 'SSL_CONF_CTX_set_ssl_ctx'; + +function SSL_CONF_cmd(cctx: PSSL_CONF_CTX; cmd: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; value: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CONF_cmd'; + +function SSL_CONF_cmd_argv(cctx: PSSL_CONF_CTX; pargc: PInteger; pargv: {$IFNDEF FPC}{$IF CompilerVersion > 21}PPUTF8Char{$ELSE}PPWideChar{$IFEND}{$ELSE}PPUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CONF_cmd_argv'; + +function SSL_CONF_cmd_value_type(cctx: PSSL_CONF_CTX; cmd: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CONF_cmd_value_type'; + +procedure SSL_add_ssl_module(); cdecl; + external LIB_SSL name _PU + 'SSL_add_ssl_module'; + +function SSL_config(s: PSSL; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_config'; + +function SSL_CTX_config(ctx: PSSL_CTX; name: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_config'; + +function SSL_set_ct_validation_callback(s: PSSL; callback: ssl_ct_validation_cb; arg: Pointer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_ct_validation_callback'; + +function SSL_CTX_set_ct_validation_callback(ctx: PSSL_CTX; callback: ssl_ct_validation_cb; arg: Pointer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_ct_validation_callback'; + +function SSL_enable_ct(s: PSSL; validation_mode: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_enable_ct'; + +function SSL_CTX_enable_ct(ctx: PSSL_CTX; validation_mode: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_enable_ct'; + +function SSL_ct_is_enabled(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_ct_is_enabled'; + +function SSL_CTX_ct_is_enabled(ctx: PSSL_CTX): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_ct_is_enabled'; + +function SSL_get0_peer_scts(s: PSSL): Pstack_st_SCT; cdecl; + external LIB_SSL name _PU + 'SSL_get0_peer_scts'; + +function SSL_CTX_set_default_ctlog_list_file(ctx: PSSL_CTX): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_default_ctlog_list_file'; + +function SSL_CTX_set_ctlog_list_file(ctx: PSSL_CTX; path: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_ctlog_list_file'; + +procedure SSL_CTX_set0_ctlog_store(ctx: PSSL_CTX; logs: PCTLOG_STORE); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set0_ctlog_store'; + +function SSL_CTX_get0_ctlog_store(ctx: PSSL_CTX): PCTLOG_STORE; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get0_ctlog_store'; + +procedure SSL_set_security_level(s: PSSL; level: Integer); cdecl; + external LIB_SSL name _PU + 'SSL_set_security_level'; + +function SSL_get_security_level(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_security_level'; + +type + SSL_set_security_callback_cb = function(s: PSSL; ctx: PSSL_CTX; op: Integer; bits: Integer; nid: Integer; other: Pointer; ex: Pointer): Integer; cdecl; + +procedure SSL_set_security_callback(s: PSSL; cb: SSL_set_security_callback_cb); cdecl; + external LIB_SSL name _PU + 'SSL_set_security_callback'; + +//function SSL_get_security_callback(s: PSSLctx: PSSL_CTXop: Integerbits: Integernid: Integerother: Pointerex: Pointers: PSSL): Integer { TODO : Cannot convert original type "int (*)(const SSL *, const SSL_CTX *, int, int, int, void *, void *)" }; cdecl; +// external LIB_SSL name _PU + 'SSL_get_security_callback'; + +procedure SSL_set0_security_ex_data(s: PSSL; ex: Pointer); cdecl; + external LIB_SSL name _PU + 'SSL_set0_security_ex_data'; + +function SSL_get0_security_ex_data(s: PSSL): Pointer; cdecl; + external LIB_SSL name _PU + 'SSL_get0_security_ex_data'; + +procedure SSL_CTX_set_security_level(ctx: PSSL_CTX; level: Integer); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_security_level'; + +function SSL_CTX_get_security_level(ctx: PSSL_CTX): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_security_level'; + +type + SSL_CTX_set_security_callback_cb = function(s: PSSL; ctx: PSSL_CTX; op: Integer; bits: Integer; nid: Integer; other: Pointer; ex: Pointer): Integer; cdecl; + +procedure SSL_CTX_set_security_callback(ctx: PSSL_CTX; cb: SSL_CTX_set_security_callback_cb); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_security_callback'; + +//function SSL_CTX_get_security_callback(s: PSSLctx: PSSL_CTXop: Integerbits: Integernid: Integerother: Pointerex: Pointerctx: PSSL_CTX): Integer { TODO : Cannot convert original type "int (*)(const SSL *, const SSL_CTX *, int, int, int, void *, void *)" }; cdecl; +// external LIB_SSL name _PU + 'SSL_CTX_get_security_callback'; + +procedure SSL_CTX_set0_security_ex_data(ctx: PSSL_CTX; ex: Pointer); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set0_security_ex_data'; + +function SSL_CTX_get0_security_ex_data(ctx: PSSL_CTX): Pointer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get0_security_ex_data'; + +function SSL_free_buffers(ssl: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_free_buffers'; + +function SSL_alloc_buffers(ssl: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_alloc_buffers'; + +function SSL_CTX_set_session_ticket_cb(ctx: PSSL_CTX; gen_cb: SSL_CTX_generate_session_ticket_fn; dec_cb: SSL_CTX_decrypt_session_ticket_fn; arg: Pointer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_session_ticket_cb'; + +function SSL_SESSION_set1_ticket_appdata(ss: PSSL_SESSION; data: Pointer; len: NativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_set1_ticket_appdata'; + +function SSL_SESSION_get0_ticket_appdata(ss: PSSL_SESSION; data: PPointer; len: PNativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_get0_ticket_appdata'; + +procedure SSL_CTX_set_allow_early_data_cb(ctx: PSSL_CTX; cb: SSL_allow_early_data_cb_fn; arg: Pointer); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_allow_early_data_cb'; + +procedure SSL_set_allow_early_data_cb(s: PSSL; cb: SSL_allow_early_data_cb_fn; arg: Pointer); cdecl; + external LIB_SSL name _PU + 'SSL_set_allow_early_data_cb'; + +function SSL_CTX_set_tlsext_use_srtp(ctx: PSSL_CTX; profiles: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_tlsext_use_srtp'; + +function SSL_set_tlsext_use_srtp(ssl: PSSL; profiles: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_tlsext_use_srtp'; + +function SSL_get_srtp_profiles(ssl: PSSL): Pstack_st_SRTP_PROTECTION_PROFILE; cdecl; + external LIB_SSL name _PU + 'SSL_get_srtp_profiles'; + +function SSL_get_selected_srtp_profile(s: PSSL): PSRTP_PROTECTION_PROFILE; cdecl; + external LIB_SSL name _PU + 'SSL_get_selected_srtp_profile'; + +type + SSL_CTX_set_msg_callback_cb = procedure(write_p: Integer; version: Integer; content_type: Integer; buf: Pointer; len: NativeUInt; ssl: PSSL; arg: Pointer); cdecl; + +procedure SSL_CTX_set_msg_callback(ctx: PSSL_CTX; cb: SSL_CTX_set_msg_callback_cb); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_msg_callback'; + +type + SSL_set_msg_callback_cb = procedure(write_p: Integer; version: Integer; content_type: Integer; buf: Pointer; len: NativeUInt; ssl: PSSL; arg: Pointer); cdecl; + +procedure SSL_set_msg_callback(ssl: PSSL; cb: SSL_set_msg_callback_cb); cdecl; + external LIB_SSL name _PU + 'SSL_set_msg_callback'; + +function SSL_SRP_CTX_init(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SRP_CTX_init'; + +function SSL_CTX_SRP_CTX_init(ctx: PSSL_CTX): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_SRP_CTX_init'; + +function SSL_SRP_CTX_free(ctx: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SRP_CTX_free'; + +function SSL_CTX_SRP_CTX_free(ctx: PSSL_CTX): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_SRP_CTX_free'; + +function SSL_srp_server_param_with_username(s: PSSL; ad: PInteger): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_srp_server_param_with_username'; + +function SSL_CTX_sessions(ctx: PSSL_CTX): Plhash_st_SSL_SESSION; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_sessions'; + +type + SSL_CTX_sess_set_new_cb_new_session_cb = function(ssl: Pssl_st; sess: PSSL_SESSION): Integer; cdecl; + +procedure SSL_CTX_sess_set_new_cb(ctx: PSSL_CTX; new_session_cb: SSL_CTX_sess_set_new_cb_new_session_cb); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_sess_set_new_cb'; + +//function SSL_CTX_sess_get_new_cb(ssl: Pssl_stsess: PSSL_SESSIONctx: PSSL_CTX): Integer { TODO : Cannot convert original type "int (*)(struct ssl_st *, SSL_SESSION *)" }; cdecl; +// external LIB_SSL name _PU + 'SSL_CTX_sess_get_new_cb'; + +type + SSL_CTX_sess_set_remove_cb_remove_session_cb = procedure(ctx: Pssl_ctx_st; sess: PSSL_SESSION); cdecl; + +procedure SSL_CTX_sess_set_remove_cb(ctx: PSSL_CTX; remove_session_cb: SSL_CTX_sess_set_remove_cb_remove_session_cb); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_sess_set_remove_cb'; + +//function SSL_CTX_sess_get_remove_cb(ctx: Pssl_ctx_stsess: PSSL_SESSIONctx: PSSL_CTX): Integer { TODO : Cannot convert original type "void (*)(struct ssl_ctx_st *, SSL_SESSION *)" }; cdecl; +// external LIB_SSL name _PU + 'SSL_CTX_sess_get_remove_cb'; + +type + SSL_CTX_sess_set_get_cb_get_session_cb = function(ssl: Pssl_st; data: PByte; len: Integer; copy: PInteger): Pssl_session_st; cdecl; + +procedure SSL_CTX_sess_set_get_cb(ctx: PSSL_CTX; get_session_cb: SSL_CTX_sess_set_get_cb_get_session_cb); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_sess_set_get_cb'; + +//function SSL_CTX_sess_get_get_cb(ssl: Pssl_stdata: PBytelen: Integercopy: PIntegerctx: PSSL_CTX): Integer { TODO : Cannot convert original type "SSL_SESSION *(*)(struct ssl_st *, const unsigned char *, int, int *)" }; cdecl; +// external LIB_SSL name _PU + 'SSL_CTX_sess_get_get_cb'; + +type + SSL_CTX_set_info_callback_cb = procedure(ssl: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer; val: Integer); cdecl; + +procedure SSL_CTX_set_info_callback(ctx: PSSL_CTX; cb: SSL_CTX_set_info_callback_cb); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_info_callback'; + +//function SSL_CTX_get_info_callback(ssl: PSSL{$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integerval: Integerctx: PSSL_CTX): Integer { TODO : Cannot convert original type "void (*)(const SSL *, int, int)" }; cdecl; +// external LIB_SSL name _PU + 'SSL_CTX_get_info_callback'; + +type + SSL_CTX_set_client_cert_cb_client_cert_cb = function(ssl: PSSL; x509: PPX509; pkey: PPEVP_PKEY): Integer; cdecl; + +procedure SSL_CTX_set_client_cert_cb(ctx: PSSL_CTX; client_cert_cb: SSL_CTX_set_client_cert_cb_client_cert_cb); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_client_cert_cb'; + +//function SSL_CTX_get_client_cert_cb(ssl: PSSLx509: PPX509pkey: PPEVP_PKEYctx: PSSL_CTX): Integer { TODO : Cannot convert original type "int (*)(SSL *, X509 **, EVP_PKEY **)" }; cdecl; +// external LIB_SSL name _PU + 'SSL_CTX_get_client_cert_cb'; + +function SSL_CTX_set_client_cert_engine(ctx: PSSL_CTX; e: PENGINE): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_client_cert_engine'; + +type + SSL_CTX_set_cookie_generate_cb_app_gen_cookie_cb = function(ssl: PSSL; cookie: PByte; cookie_len: PCardinal): Integer; cdecl; + +procedure SSL_CTX_set_cookie_generate_cb(ctx: PSSL_CTX; app_gen_cookie_cb: SSL_CTX_set_cookie_generate_cb_app_gen_cookie_cb); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_cookie_generate_cb'; + +type + SSL_CTX_set_cookie_verify_cb_app_verify_cookie_cb = function(ssl: PSSL; cookie: PByte; cookie_len: Cardinal): Integer; cdecl; + +procedure SSL_CTX_set_cookie_verify_cb(ctx: PSSL_CTX; app_verify_cookie_cb: SSL_CTX_set_cookie_verify_cb_app_verify_cookie_cb); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_cookie_verify_cb'; + +type + SSL_CTX_set_stateless_cookie_generate_cb_gen_stateless_cookie_cb = function(ssl: PSSL; cookie: PByte; cookie_len: PNativeUInt): Integer; cdecl; + +procedure SSL_CTX_set_stateless_cookie_generate_cb(ctx: PSSL_CTX; gen_stateless_cookie_cb: SSL_CTX_set_stateless_cookie_generate_cb_gen_stateless_cookie_cb); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_stateless_cookie_generate_cb'; + +type + SSL_CTX_set_stateless_cookie_verify_cb_verify_stateless_cookie_cb = function(ssl: PSSL; cookie: PByte; cookie_len: NativeUInt): Integer; cdecl; + +procedure SSL_CTX_set_stateless_cookie_verify_cb(ctx: PSSL_CTX; verify_stateless_cookie_cb: SSL_CTX_set_stateless_cookie_verify_cb_verify_stateless_cookie_cb); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_stateless_cookie_verify_cb'; + +procedure SSL_CTX_set_next_protos_advertised_cb(s: PSSL_CTX; cb: SSL_CTX_npn_advertised_cb_func; arg: Pointer); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_next_protos_advertised_cb'; +procedure SSL_CTX_set_npn_advertised_cb(s: PSSL_CTX; cb: SSL_CTX_npn_advertised_cb_func; arg: Pointer); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_next_protos_advertised_cb'; + +procedure SSL_CTX_set_next_proto_select_cb(s: PSSL_CTX; cb: SSL_CTX_npn_select_cb_func; arg: Pointer); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_next_proto_select_cb'; +procedure SSL_CTX_set_npn_select_cb(s: PSSL_CTX; cb: SSL_CTX_npn_select_cb_func; arg: Pointer); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_next_proto_select_cb'; + +procedure SSL_get0_next_proto_negotiated(s: PSSL; data: PPByte; len: PCardinal); cdecl; + external LIB_SSL name _PU + 'SSL_get0_next_proto_negotiated'; +procedure SSL_get0_npn_negotiated(s: PSSL; data: PPByte; len: PCardinal); cdecl; + external LIB_SSL name _PU + 'SSL_get0_next_proto_negotiated'; + +function SSL_select_next_proto({$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PPByte; outlen: PByte; {$IFNDEF FPC}{$IF CompilerVersion > 21}&in{$ELSE}in1{$IFEND}{$ELSE}&in{$ENDIF}: PByte; inlen: Cardinal; client: PByte; client_len: Cardinal): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_select_next_proto'; + +function SSL_CTX_set_alpn_protos(ctx: PSSL_CTX; protos: PByte; protos_len: Cardinal): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_alpn_protos'; + +function SSL_set_alpn_protos(ssl: PSSL; protos: PByte; protos_len: Cardinal): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_alpn_protos'; + +procedure SSL_CTX_set_alpn_select_cb(ctx: PSSL_CTX; cb: SSL_CTX_alpn_select_cb_func; arg: Pointer); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_alpn_select_cb'; + +procedure SSL_get0_alpn_selected(ssl: PSSL; data: PPByte; len: PCardinal); cdecl; + external LIB_SSL name _PU + 'SSL_get0_alpn_selected'; + +procedure SSL_CTX_set_psk_client_callback(ctx: PSSL_CTX; cb: SSL_psk_client_cb_func); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_psk_client_callback'; + +procedure SSL_set_psk_client_callback(ssl: PSSL; cb: SSL_psk_client_cb_func); cdecl; + external LIB_SSL name _PU + 'SSL_set_psk_client_callback'; + +procedure SSL_CTX_set_psk_server_callback(ctx: PSSL_CTX; cb: SSL_psk_server_cb_func); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_psk_server_callback'; + +procedure SSL_set_psk_server_callback(ssl: PSSL; cb: SSL_psk_server_cb_func); cdecl; + external LIB_SSL name _PU + 'SSL_set_psk_server_callback'; + +function SSL_CTX_use_psk_identity_hint(ctx: PSSL_CTX; identity_hint: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_use_psk_identity_hint'; + +function SSL_use_psk_identity_hint(s: PSSL; identity_hint: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_use_psk_identity_hint'; + +function SSL_get_psk_identity_hint(s: PSSL): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_get_psk_identity_hint'; + +function SSL_get_psk_identity(s: PSSL): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_get_psk_identity'; + +procedure SSL_set_psk_find_session_callback(s: PSSL; cb: SSL_psk_find_session_cb_func); cdecl; + external LIB_SSL name _PU + 'SSL_set_psk_find_session_callback'; + +procedure SSL_CTX_set_psk_find_session_callback(ctx: PSSL_CTX; cb: SSL_psk_find_session_cb_func); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_psk_find_session_callback'; + +procedure SSL_set_psk_use_session_callback(s: PSSL; cb: SSL_psk_use_session_cb_func); cdecl; + external LIB_SSL name _PU + 'SSL_set_psk_use_session_callback'; + +procedure SSL_CTX_set_psk_use_session_callback(ctx: PSSL_CTX; cb: SSL_psk_use_session_cb_func); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_psk_use_session_callback'; + +function SSL_CTX_has_client_custom_ext(ctx: PSSL_CTX; ext_type: Cardinal): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_has_client_custom_ext'; + +function SSL_CTX_add_client_custom_ext(ctx: PSSL_CTX; ext_type: Cardinal; add_cb: custom_ext_add_cb; free_cb: custom_ext_free_cb; add_arg: Pointer; parse_cb: custom_ext_parse_cb; parse_arg: Pointer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_add_client_custom_ext'; + +function SSL_CTX_add_server_custom_ext(ctx: PSSL_CTX; ext_type: Cardinal; add_cb: custom_ext_add_cb; free_cb: custom_ext_free_cb; add_arg: Pointer; parse_cb: custom_ext_parse_cb; parse_arg: Pointer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_add_server_custom_ext'; + +function SSL_CTX_add_custom_ext(ctx: PSSL_CTX; ext_type: Cardinal; context: Cardinal; add_cb: SSL_custom_ext_add_cb_ex; free_cb: SSL_custom_ext_free_cb_ex; add_arg: Pointer; parse_cb: SSL_custom_ext_parse_cb_ex; parse_arg: Pointer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_add_custom_ext'; + +function SSL_extension_supported(ext_type: Cardinal): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_extension_supported'; + +procedure SSL_CTX_set_keylog_callback(ctx: PSSL_CTX; cb: SSL_CTX_keylog_cb_func); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_keylog_callback'; + +function SSL_CTX_get_keylog_callback(ctx: PSSL_CTX): SSL_CTX_keylog_cb_func; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_keylog_callback'; + +function SSL_CTX_set_max_early_data(ctx: PSSL_CTX; max_early_data: {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt32{$ELSE}LongInt{$IFEND}{$ELSE}UInt32{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_max_early_data'; + +function SSL_CTX_get_max_early_data(ctx: PSSL_CTX): {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt32{$ELSE}LongInt{$IFEND}{$ELSE}UInt32{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_max_early_data'; + +function SSL_set_max_early_data(s: PSSL; max_early_data: {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt32{$ELSE}LongInt{$IFEND}{$ELSE}UInt32{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_max_early_data'; + +function SSL_get_max_early_data(s: PSSL): {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt32{$ELSE}LongInt{$IFEND}{$ELSE}UInt32{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_get_max_early_data'; + +function SSL_CTX_set_recv_max_early_data(ctx: PSSL_CTX; recv_max_early_data: {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt32{$ELSE}LongInt{$IFEND}{$ELSE}UInt32{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_recv_max_early_data'; + +function SSL_CTX_get_recv_max_early_data(ctx: PSSL_CTX): {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt32{$ELSE}LongInt{$IFEND}{$ELSE}UInt32{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_recv_max_early_data'; + +function SSL_set_recv_max_early_data(s: PSSL; recv_max_early_data: {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt32{$ELSE}LongInt{$IFEND}{$ELSE}UInt32{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_recv_max_early_data'; + +function SSL_get_recv_max_early_data(s: PSSL): {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt32{$ELSE}LongInt{$IFEND}{$ELSE}UInt32{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_get_recv_max_early_data'; + +function SSL_CTX_set_tlsext_max_fragment_length(ctx: PSSL_CTX; mode: {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt8{$ELSE}LongInt{$IFEND}{$ELSE}UInt8{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_tlsext_max_fragment_length'; + +function SSL_set_tlsext_max_fragment_length(ssl: PSSL; mode: {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt8{$ELSE}LongInt{$IFEND}{$ELSE}UInt8{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_tlsext_max_fragment_length'; + +function SSL_get_servername(s: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_get_servername'; + +function SSL_get_servername_type(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_servername_type'; + +function SSL_export_keying_material(s: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; olen: NativeUInt; {$IFNDEF FPC}{$IF CompilerVersion > 21}&label{$ELSE}label1{$IFEND}{$ELSE}&label{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; llen: NativeUInt; context: PByte; contextlen: NativeUInt; use_context: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_export_keying_material'; + +function SSL_export_keying_material_early(s: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&out{$ELSE}out1{$IFEND}{$ELSE}&out{$ENDIF}: PByte; olen: NativeUInt; {$IFNDEF FPC}{$IF CompilerVersion > 21}&label{$ELSE}label1{$IFEND}{$ELSE}&label{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; llen: NativeUInt; context: PByte; contextlen: NativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_export_keying_material_early'; + +function SSL_get_peer_signature_type_nid(s: PSSL; pnid: PInteger): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_peer_signature_type_nid'; + +function SSL_get_signature_type_nid(s: PSSL; pnid: PInteger): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_signature_type_nid'; + +function SSL_get_sigalgs(s: PSSL; idx: Integer; psign: PInteger; phash: PInteger; psignandhash: PInteger; rsig: PByte; rhash: PByte): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_sigalgs'; + +function SSL_get_shared_sigalgs(s: PSSL; idx: Integer; psign: PInteger; phash: PInteger; psignandhash: PInteger; rsig: PByte; rhash: PByte): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_shared_sigalgs'; + +function SSL_check_chain(s: PSSL; x: PX509; pk: PEVP_PKEY; chain: Pstack_st_X509): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_check_chain'; + +procedure SSL_set_debug(s: PSSL; debug: Integer); cdecl; + external LIB_SSL name _PU + 'SSL_set_debug'; + +function SSL_in_init(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_in_init'; + +function SSL_in_before(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_in_before'; + +function SSL_is_init_finished(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_is_init_finished'; + +function SSL_get_finished(s: PSSL; buf: Pointer; count: NativeUInt): NativeUInt; cdecl; + external LIB_SSL name _PU + 'SSL_get_finished'; + +function SSL_get_peer_finished(s: PSSL; buf: Pointer; count: NativeUInt): NativeUInt; cdecl; + external LIB_SSL name _PU + 'SSL_get_peer_finished'; + +function SSL_CTX_set_cipher_list(p1: PSSL_CTX; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_cipher_list'; + +function SSL_CTX_new(meth: PSSL_METHOD): PSSL_CTX; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_new'; + +function SSL_CTX_up_ref(ctx: PSSL_CTX): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_up_ref'; + +procedure SSL_CTX_free(p1: PSSL_CTX); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_free'; + +function SSL_CTX_set_timeout(ctx: PSSL_CTX; t: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_timeout'; + +function SSL_CTX_get_timeout(ctx: PSSL_CTX): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_timeout'; + +function SSL_CTX_get_cert_store(p1: PSSL_CTX): PX509_STORE; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_cert_store'; + +procedure SSL_CTX_set_cert_store(p1: PSSL_CTX; p2: PX509_STORE); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_cert_store'; + +procedure SSL_CTX_set1_cert_store(p1: PSSL_CTX; p2: PX509_STORE); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set1_cert_store'; + +function SSL_want(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_want'; + +function SSL_clear(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_clear'; + +procedure SSL_CTX_flush_sessions(ctx: PSSL_CTX; tm: Integer); cdecl; + external LIB_SSL name _PU + 'SSL_CTX_flush_sessions'; + +function SSL_get_current_cipher(s: PSSL): PSSL_CIPHER; cdecl; + external LIB_SSL name _PU + 'SSL_get_current_cipher'; + +function SSL_get_pending_cipher(s: PSSL): PSSL_CIPHER; cdecl; + external LIB_SSL name _PU + 'SSL_get_pending_cipher'; + +function SSL_CIPHER_get_bits(c: PSSL_CIPHER; alg_bits: PInteger): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CIPHER_get_bits'; + +function SSL_CIPHER_get_version(c: PSSL_CIPHER): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_CIPHER_get_version'; + +function SSL_CIPHER_get_name(c: PSSL_CIPHER): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_CIPHER_get_name'; + +function SSL_CIPHER_standard_name(c: PSSL_CIPHER): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_CIPHER_standard_name'; + +function SSL_CIPHER_get_id(c: PSSL_CIPHER): {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt32{$ELSE}LongInt{$IFEND}{$ELSE}UInt32{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_CIPHER_get_id'; + +function SSL_CIPHER_get_protocol_id(c: PSSL_CIPHER): {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt16{$ELSE}LongInt{$IFEND}{$ELSE}UInt16{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_CIPHER_get_protocol_id'; + +function SSL_CIPHER_get_kx_nid(c: PSSL_CIPHER): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CIPHER_get_kx_nid'; + +function SSL_CIPHER_get_auth_nid(c: PSSL_CIPHER): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CIPHER_get_auth_nid'; + +function SSL_CIPHER_get_handshake_digest(c: PSSL_CIPHER): PEVP_MD; cdecl; + external LIB_SSL name _PU + 'SSL_CIPHER_get_handshake_digest'; + +function SSL_CIPHER_is_aead(c: PSSL_CIPHER): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CIPHER_is_aead'; + +function SSL_get_fd(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_fd'; + +function SSL_get_rfd(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_rfd'; + +function SSL_get_wfd(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_wfd'; + +function SSL_get_cipher_list(s: PSSL; n: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_get_cipher_list'; + +function SSL_get_shared_ciphers(s: PSSL; buf: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; size: Integer): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_get_shared_ciphers'; + +function SSL_get_read_ahead(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_read_ahead'; + +function SSL_pending(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_pending'; + +function SSL_has_pending(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_has_pending'; + +function SSL_set_fd(s: PSSL; fd: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_fd'; + +function SSL_set_rfd(s: PSSL; fd: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_rfd'; + +function SSL_set_wfd(s: PSSL; fd: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_wfd'; + +procedure SSL_set0_rbio(s: PSSL; rbio: PBIO); cdecl; + external LIB_SSL name _PU + 'SSL_set0_rbio'; + +procedure SSL_set0_wbio(s: PSSL; wbio: PBIO); cdecl; + external LIB_SSL name _PU + 'SSL_set0_wbio'; + +procedure SSL_set_bio(s: PSSL; rbio: PBIO; wbio: PBIO); cdecl; + external LIB_SSL name _PU + 'SSL_set_bio'; + +function SSL_get_rbio(s: PSSL): PBIO; cdecl; + external LIB_SSL name _PU + 'SSL_get_rbio'; + +function SSL_get_wbio(s: PSSL): PBIO; cdecl; + external LIB_SSL name _PU + 'SSL_get_wbio'; + +function SSL_set_cipher_list(s: PSSL; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_cipher_list'; + +function SSL_CTX_set_ciphersuites(ctx: PSSL_CTX; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_ciphersuites'; + +function SSL_set_ciphersuites(s: PSSL; str: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_ciphersuites'; + +procedure SSL_set_read_ahead(s: PSSL; yes: Integer); cdecl; + external LIB_SSL name _PU + 'SSL_set_read_ahead'; + +function SSL_get_verify_mode(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_verify_mode'; + +function SSL_get_verify_depth(s: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_get_verify_depth'; + +function SSL_get_verify_callback(s: PSSL): SSL_verify_cb; cdecl; + external LIB_SSL name _PU + 'SSL_get_verify_callback'; + +procedure SSL_set_verify(s: PSSL; mode: Integer; callback: SSL_verify_cb); cdecl; + external LIB_SSL name _PU + 'SSL_set_verify'; + +procedure SSL_set_verify_depth(s: PSSL; depth: Integer); cdecl; + external LIB_SSL name _PU + 'SSL_set_verify_depth'; + +type + SSL_set_cert_cb_cb = function(ssl: PSSL; arg: Pointer): Integer; cdecl; + +procedure SSL_set_cert_cb(s: PSSL; cb: SSL_set_cert_cb_cb; arg: Pointer); cdecl; + external LIB_SSL name _PU + 'SSL_set_cert_cb'; + +function SSL_use_RSAPrivateKey(ssl: PSSL; rsa: PRSA): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_use_RSAPrivateKey'; + +function SSL_use_RSAPrivateKey_ASN1(ssl: PSSL; d: PByte; len: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_use_RSAPrivateKey_ASN1'; + +function SSL_use_PrivateKey(ssl: PSSL; pkey: PEVP_PKEY): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_use_PrivateKey'; + +function SSL_use_PrivateKey_ASN1(pk: Integer; ssl: PSSL; d: PByte; len: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_use_PrivateKey_ASN1'; + +function SSL_use_certificate(ssl: PSSL; x: PX509): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_use_certificate'; + +function SSL_use_certificate_ASN1(ssl: PSSL; d: PByte; len: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_use_certificate_ASN1'; + +function SSL_use_cert_and_key(ssl: PSSL; x509: PX509; privatekey: PEVP_PKEY; chain: Pstack_st_X509; {$IFNDEF FPC}{$IF CompilerVersion > 21}&override{$ELSE}override1{$IFEND}{$ELSE}&override{$ENDIF}: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_use_cert_and_key'; + +function SSL_CTX_use_serverinfo(ctx: PSSL_CTX; serverinfo: PByte; serverinfo_length: NativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_use_serverinfo'; + +function SSL_CTX_use_serverinfo_ex(ctx: PSSL_CTX; version: Cardinal; serverinfo: PByte; serverinfo_length: NativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_use_serverinfo_ex'; + +function SSL_CTX_use_serverinfo_file(ctx: PSSL_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_use_serverinfo_file'; + +function SSL_use_RSAPrivateKey_file(ssl: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_use_RSAPrivateKey_file'; + +function SSL_use_PrivateKey_file(ssl: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_use_PrivateKey_file'; + +function SSL_use_certificate_file(ssl: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_use_certificate_file'; + +function SSL_CTX_use_RSAPrivateKey_file(ctx: PSSL_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_use_RSAPrivateKey_file'; + +function SSL_CTX_use_PrivateKey_file(ctx: PSSL_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_use_PrivateKey_file'; + +function SSL_CTX_use_certificate_file(ctx: PSSL_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; {$IFNDEF FPC}{$IF CompilerVersion > 21}&type{$ELSE}type1{$IFEND}{$ELSE}&type{$ENDIF}: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_use_certificate_file'; + +function SSL_CTX_use_certificate_chain_file(ctx: PSSL_CTX; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_use_certificate_chain_file'; + +function SSL_use_certificate_chain_file(ssl: PSSL; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_use_certificate_chain_file'; + +function SSL_load_client_CA_file({$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Pstack_st_X509_NAME; cdecl; + external LIB_SSL name _PU + 'SSL_load_client_CA_file'; + +function SSL_add_file_cert_subjects_to_stack(stackCAs: Pstack_st_X509_NAME; {$IFNDEF FPC}{$IF CompilerVersion > 21}&file{$ELSE}file1{$IFEND}{$ELSE}&file{$ENDIF}: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_add_file_cert_subjects_to_stack'; + +function SSL_add_dir_cert_subjects_to_stack(stackCAs: Pstack_st_X509_NAME; dir: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_add_dir_cert_subjects_to_stack'; + +function SSL_state_string(s: PSSL): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_state_string'; + +function SSL_rstate_string(s: PSSL): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_rstate_string'; + +function SSL_state_string_long(s: PSSL): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_state_string_long'; + +function SSL_rstate_string_long(s: PSSL): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_rstate_string_long'; + +function SSL_SESSION_get_time(s: PSSL_SESSION): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_get_time'; + +function SSL_SESSION_set_time(s: PSSL_SESSION; t: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_set_time'; + +function SSL_SESSION_get_timeout(s: PSSL_SESSION): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_get_timeout'; + +function SSL_SESSION_set_timeout(s: PSSL_SESSION; t: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_set_timeout'; + +function SSL_SESSION_get_protocol_version(s: PSSL_SESSION): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_get_protocol_version'; + +function SSL_SESSION_set_protocol_version(s: PSSL_SESSION; version: Integer): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_set_protocol_version'; + +function SSL_SESSION_get0_hostname(s: PSSL_SESSION): {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_get0_hostname'; + +function SSL_SESSION_set1_hostname(s: PSSL_SESSION; hostname: {$IFNDEF FPC}{$IF CompilerVersion > 21}PUTF8Char{$ELSE}PWideChar{$IFEND}{$ELSE}PUTF8Char{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_set1_hostname'; + +procedure SSL_SESSION_get0_alpn_selected(s: PSSL_SESSION; alpn: PPByte; len: PNativeUInt); cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_get0_alpn_selected'; + +function SSL_SESSION_set1_alpn_selected(s: PSSL_SESSION; alpn: PByte; len: NativeUInt): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_set1_alpn_selected'; + +function SSL_SESSION_get0_cipher(s: PSSL_SESSION): PSSL_CIPHER; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_get0_cipher'; + +function SSL_SESSION_set_cipher(s: PSSL_SESSION; cipher: PSSL_CIPHER): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_set_cipher'; + +function SSL_SESSION_has_ticket(s: PSSL_SESSION): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_has_ticket'; + +function SSL_SESSION_get_ticket_lifetime_hint(s: PSSL_SESSION): Cardinal; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_get_ticket_lifetime_hint'; + +procedure SSL_SESSION_get0_ticket(s: PSSL_SESSION; tick: PPByte; len: PNativeUInt); cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_get0_ticket'; + +function SSL_SESSION_get_max_early_data(s: PSSL_SESSION): {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt32{$ELSE}LongInt{$IFEND}{$ELSE}UInt32{$ENDIF}; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_get_max_early_data'; + +function SSL_SESSION_set_max_early_data(s: PSSL_SESSION; max_early_data: {$IFNDEF FPC}{$IF CompilerVersion > 21}UInt32{$ELSE}LongInt{$IFEND}{$ELSE}UInt32{$ENDIF}): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_set_max_early_data'; + +function SSL_copy_session_id({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PSSL; from: PSSL): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_copy_session_id'; + +function SSL_SESSION_get0_peer(s: PSSL_SESSION): PX509; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_get0_peer'; + +function SSL_SESSION_set1_id_context(s: PSSL_SESSION; sid_ctx: PByte; sid_ctx_len: Cardinal): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_set1_id_context'; + +function SSL_SESSION_set1_id(s: PSSL_SESSION; sid: PByte; sid_len: Cardinal): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_set1_id'; + +function SSL_SESSION_is_resumable(s: PSSL_SESSION): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_is_resumable'; + +function SSL_SESSION_new(): PSSL_SESSION; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_new'; + +function SSL_SESSION_dup(src: PSSL_SESSION): PSSL_SESSION; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_dup'; + +function SSL_SESSION_get_id(s: PSSL_SESSION; len: PCardinal): PByte; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_get_id'; + +function SSL_SESSION_get0_id_context(s: PSSL_SESSION; len: PCardinal): PByte; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_get0_id_context'; + +function SSL_SESSION_get_compress_id(s: PSSL_SESSION): Cardinal; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_get_compress_id'; + +function SSL_SESSION_print_fp(fp: PPointer; ses: PSSL_SESSION): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_print_fp'; + +function SSL_SESSION_print(fp: PBIO; ses: PSSL_SESSION): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_print'; + +function SSL_SESSION_print_keylog(bp: PBIO; x: PSSL_SESSION): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_print_keylog'; + +function SSL_SESSION_up_ref(ses: PSSL_SESSION): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_up_ref'; + +procedure SSL_SESSION_free(ses: PSSL_SESSION); cdecl; + external LIB_SSL name _PU + 'SSL_SESSION_free'; + +function SSL_set_session({$IFNDEF FPC}{$IF CompilerVersion > 21}&to{$ELSE}to1{$IFEND}{$ELSE}&to{$ENDIF}: PSSL; session: PSSL_SESSION): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_session'; + +function SSL_CTX_add_session(ctx: PSSL_CTX; session: PSSL_SESSION): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_add_session'; + +function SSL_CTX_remove_session(ctx: PSSL_CTX; session: PSSL_SESSION): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_remove_session'; + +function SSL_CTX_set_generate_session_id(ctx: PSSL_CTX; cb: GEN_SESSION_CB): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_generate_session_id'; + +function SSL_set_generate_session_id(s: PSSL; cb: GEN_SESSION_CB): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_set_generate_session_id'; + +function SSL_has_matching_session_id(s: PSSL; id: PByte; id_len: Cardinal): Integer; cdecl; + external LIB_SSL name _PU + 'SSL_has_matching_session_id'; + +function SSL_CTX_get_options(ctx: PSSL_CTX): Cardinal; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_get_options'; + +function SSL_get_options(s: PSSL): Cardinal; cdecl; + external LIB_SSL name _PU + 'SSL_get_options'; + +function SSL_CTX_clear_options(ctx: PSSL_CTX; op: Cardinal): Cardinal; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_clear_options'; + +function SSL_clear_options(s: PSSL; op: Cardinal): Cardinal; cdecl; + external LIB_SSL name _PU + 'SSL_clear_options'; + +function SSL_CTX_set_options(ctx: PSSL_CTX; op: Cardinal): Cardinal; cdecl; + external LIB_SSL name _PU + 'SSL_CTX_set_options'; + +function SSL_set_options(s: PSSL; op: Cardinal): Cardinal; cdecl; + external LIB_SSL name _PU + 'SSL_set_options'; + +function TLS_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'TLS_method'; +function SSLv23_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'TLS_method'; + +function TLS_server_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'TLS_server_method'; +function SSLv23_server_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'TLS_server_method'; + +function TLS_client_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'TLS_client_method'; +function SSLv23_client_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'TLS_client_method'; + +function TLSv1_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'TLSv1_method'; + +function TLSv1_server_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'TLSv1_server_method'; + +function TLSv1_client_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'TLSv1_client_method'; + +function TLSv1_1_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'TLSv1_1_method'; + +function TLSv1_1_server_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'TLSv1_1_server_method'; + +function TLSv1_1_client_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'TLSv1_1_client_method'; + +function TLSv1_2_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'TLSv1_2_method'; + +function TLSv1_2_server_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'TLSv1_2_server_method'; + +function TLSv1_2_client_method(): PSSL_METHOD; cdecl; + external LIB_SSL name _PU + 'TLSv1_2_client_method'; + +type + PTimeVal = ^TTimeVal; + timeval = record + tv_sec: Longint; + tv_usec: Longint; + end; + TTimeVal = timeval; + +{ LibCrypto Helpers } +function BIO_get_flags(b: PBIO): Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}inline;{$IFEND}{$ELSE}inline;{$ENDIF} +function BIO_should_retry(b: PBIO): Boolean; {$IFNDEF FPC}{$IF CompilerVersion > 21}inline;{$IFEND}{$ELSE}inline;{$ENDIF} +function BIO_should_read(b: PBIO): Boolean; {$IFNDEF FPC}{$IF CompilerVersion > 21}inline;{$IFEND}{$ELSE}inline;{$ENDIF} +function BIO_should_write(b: PBIO): Boolean; {$IFNDEF FPC}{$IF CompilerVersion > 21}inline;{$IFEND}{$ELSE}inline;{$ENDIF} +function BIO_should_io_special(b: PBIO): Boolean; {$IFNDEF FPC}{$IF CompilerVersion > 21}inline;{$IFEND}{$ELSE}inline;{$ENDIF} +function BIO_retry_type(b: PBIO): Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}inline;{$IFEND}{$ELSE}inline;{$ENDIF} +function BIO_get_ssl(b: PBIO; s: PSSL): Integer; +function BIO_pending(b: PBIO): Integer; + +function SSL_error(const AErrorCode: Integer): String; +function SSL_is_fatal_error(const AErrorCode: Integer): Boolean; + +{ LibSsl Helpers } +function SSL_CTX_set_session_cache_mode(ctx: PSSL_CTX; mode: Integer): Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}inline;{$IFEND}{$ELSE}inline;{$ENDIF} +function SSL_CTX_add_extra_chain_cert(ctx: PSSL_CTX; cert: PX509): Longword; {$IFNDEF FPC}{$IF CompilerVersion > 21}inline;{$IFEND}{$ELSE}inline;{$ENDIF} +function SSL_CTX_set_tmp_dh(ctx: PSSL_CTX; dh: Pointer): Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}inline;{$IFEND}{$ELSE}inline;{$ENDIF} +function SSL_CTX_set_tmp_ecdh(ctx: PSSL_CTX; ecdh: Pointer): Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}inline;{$IFEND}{$ELSE}inline;{$ENDIF} +function SSL_CTX_set_ecdh_auto(ctx: PSSL_CTX; onoff: Integer): Integer; +function SSL_CTX_set_min_proto_version(ctx: PSSL_CTX; version: Integer): Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}inline;{$IFEND}{$ELSE}inline;{$ENDIF} +function SSL_CTX_set_max_proto_version(ctx: PSSL_CTX; version: Integer): Integer; {$IFNDEF FPC}{$IF CompilerVersion > 21}inline;{$IFEND}{$ELSE}inline;{$ENDIF} +function SSL_set_tlsext_host_name(const s: PSSL; const name: String): LongInt; {$IFNDEF FPC}{$IF CompilerVersion > 21}inline;{$IFEND}{$ELSE}inline;{$ENDIF} +function SSL_set_mode(s: PSSL; version: Integer): Integer; +function SSL_get_mode(s: PSSL): Integer; + +function DTLSv1_get_timeout(s: PSSL; timeval: PTimeVal): LongInt; +procedure DTLSv1_handle_timeout(s: PSSL); + +implementation + +{ Helper routines } + +function BIO_get_flags(b: PBIO): Integer; +begin + Result := BIO_test_flags(b, not 0); +end; + +function BIO_should_retry(b: PBIO): Boolean; +begin + Result := ((BIO_get_flags(b) and BIO_FLAGS_SHOULD_RETRY) <> 0); +end; + +function BIO_should_read(b: PBIO): Boolean; +begin + Result := ((BIO_get_flags(b) and BIO_FLAGS_READ) <> 0); +end; + +function BIO_should_write(b: PBIO): Boolean; +begin + Result := ((BIO_get_flags(b) and BIO_FLAGS_WRITE) <> 0); +end; + +function BIO_should_io_special(b: PBIO): Boolean; +begin + Result := ((BIO_get_flags(b) and BIO_FLAGS_IO_SPECIAL) <> 0); +end; + +function BIO_retry_type(b: PBIO): Integer; +begin + Result := (BIO_get_flags(b) and BIO_FLAGS_RWS); +end; + +function BIO_get_ssl(b: PBIO; s: PSSL): Integer; +begin + Result := BIO_ctrl(b, BIO_C_GET_SSL, 0, s); +end; + +function BIO_pending(b: PBIO): Integer; +begin + Result := BIO_ctrl(b, _BIO_CTRL_PENDING, 0, nil); +end; + +function SSL_error(const AErrorCode: Integer): String; +var +{$IFNDEF FPC} + {$IF CompilerVersion > 21} + P: TPtrWrapper; + {$ELSE} + P: Pointer; + {$IFEND} +{$ELSE} + P: Pointer; +{$ENDIF} +begin + P := {$IFNDEF FPC}{$IF CompilerVersion > 21}TMarshal.{$IFEND}{$ENDIF}AllocMem(1024); + try + ERR_error_string_n(AErrorCode, P{$IFNDEF FPC}{$IF CompilerVersion > 21}.ToPointer{$IFEND}{$ENDIF}, 1024); + {$IFNDEF FPC} + {$IF CompilerVersion > 21} + Result := TMarshal.ReadStringAsAnsi(P); + {$ELSE} + SetLength(Result, Length(PChar(P)^)); + SetString(Result, PChar(P), Length(Result)); + {$IFEND} + {$ELSE} + SetLength(Result, Length(PChar(P)^)); + SetString(Result, PChar(P), Length(Result)); + {$ENDIF} + finally + {$IFNDEF FPC}{$IF CompilerVersion > 21}TMarshal.{$IFEND}{$ENDIF}FreeMem(P); + end; +end; + +function SSL_is_fatal_error(const AErrorCode: Integer): Boolean; +begin + case AErrorCode of + SSL_ERROR_NONE, + SSL_ERROR_WANT_READ, + SSL_ERROR_WANT_WRITE, + SSL_ERROR_WANT_CONNECT, + SSL_ERROR_WANT_ACCEPT: Result := False; + else + Result := True; + end; +end; + +function SSL_CTX_set_session_cache_mode(ctx: PSSL_CTX; mode: Integer): Integer; +begin + Result := SSL_CTX_ctrl(ctx, SSL_CTRL_SET_SESS_CACHE_MODE, mode, nil); +end; + +function SSL_CTX_add_extra_chain_cert(ctx: PSSL_CTX; cert: PX509): Longword; +begin + Result := SSL_CTX_ctrl(ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, cert); +end; + +function SSL_CTX_set_tmp_dh(ctx: PSSL_CTX; dh: Pointer): Integer; +begin + Result := SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_DH, 0, dh); +end; + +function SSL_CTX_set_tmp_ecdh(ctx: PSSL_CTX; ecdh: Pointer): Integer; +begin + Result := SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_ECDH, 0, ecdh); +end; + +function SSL_CTX_set_ecdh_auto(ctx: PSSL_CTX; onoff: Integer): Integer; +begin + Result := 1; +end; + +function SSL_CTX_set_min_proto_version(ctx: PSSL_CTX; version: Integer): Integer; +begin + Result := SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, Nil); +end; + +function SSL_CTX_set_max_proto_version(ctx: PSSL_CTX; version: Integer): Integer; +begin + Result := SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, Nil); +end; + +function SSL_set_tlsext_host_name(const s: PSSL; const name: String): Longint; +begin + Result := SSL_ctrl(s, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, Pointer(Utf8Encode(name))); +end; + +function SSL_set_mode(s: PSSL; version: Integer): Integer; +begin + Result := SSL_ctrl(s, SSL_CTRL_MODE, version, Nil); +end; + +function SSL_get_mode(s: PSSL): Integer; +begin + Result := SSL_ctrl(s, SSL_CTRL_MODE, 0, Nil); +end; + +function DTLSv1_get_timeout(s: PSSL; timeval: PTimeVal): LongInt; +begin + Result := SSL_ctrl(s, DTLS_CTRL_GET_TIMEOUT, 0, timeval); +end; + +procedure DTLSv1_handle_timeout(s: PSSL); +begin + SSL_ctrl(s, DTLS_CTRL_HANDLE_TIMEOUT, 0, Nil); +end; + +end. diff --git a/CORE/Source/Sockets/uRESTDWFCMOpenSSLHTTP.pas b/CORE/Source/Sockets/uRESTDWFCMOpenSSLHTTP.pas new file mode 100644 index 000000000..d6d88d17d --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFCMOpenSSLHTTP.pas @@ -0,0 +1,490 @@ +Unit uRESTDWFCMOpenSSLHTTP; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + uRESTDWFCMTransport; + +Type + TRESTDWFCMOpenSSLHTTPTransport = Class(TRESTDWFCMHTTPTransport) + Private + FVerifyPeer : Boolean; + FCAFile : String; + FCAPath : String; + + Function DecodeChunked(Const AData : AnsiString) : AnsiString; + Public + Constructor Create; + + Procedure ConfigureTLS(AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); Override; + + Function Post(Const AURL : String; + AHeaders : TStrings; + ABody : TStream; + AResponse : TStream; + AResponseError : TStream) : Integer; Override; + End; + +Implementation + +Uses + uRESTDWOpenSslLib, + uRESTDWFCMTLS; + +Constructor TRESTDWFCMOpenSSLHTTPTransport.Create; +Begin + Inherited Create; + FVerifyPeer := True; + FCAFile := ''; + FCAPath := ''; +End; + +Procedure TRESTDWFCMOpenSSLHTTPTransport.ConfigureTLS(AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); +Begin + FVerifyPeer := AVerifyPeer; + FCAFile := ACAFile; + FCAPath := ACAPath; +End; + +Procedure ParseHTTPSURL(Const AURL : String; + Var AHost, + APath : String; + Var APort : Integer); +Var + S : String; + P, + C : Integer; +Begin + S := Trim(AURL); + + If Pos('https://', LowerCase(S)) <> 1 Then + Raise Exception.Create('FCM HTTP: somente HTTPS e suportado'); + + Delete(S, 1, Length('https://')); + + P := Pos('/', S); + If P = 0 Then + Begin + AHost := S; + APath := '/'; + End + Else + Begin + AHost := Copy(S, 1, P - 1); + APath := Copy(S, P, MaxInt); + End; + + APort := 443; + + C := Pos(':', AHost); + If C > 0 Then + Begin + APort := StrToIntDef(Copy(AHost, C + 1, MaxInt), 443); + AHost := Copy(AHost, 1, C - 1); + End; +End; + +Function HexToInt(Const AValue : String) : Integer; +Var + I, + LDigit : Integer; + C : Char; +Begin + Result := 0; + + For I := 1 To Length(AValue) Do + Begin + C := UpCase(AValue[I]); + + If (C >= '0') And (C <= '9') Then + LDigit := Ord(C) - Ord('0') + Else + If (C >= 'A') And (C <= 'F') Then + LDigit := Ord(C) - Ord('A') + 10 + Else + Break; + + Result := (Result Shl 4) Or LDigit; + End; +End; + +Function TRESTDWFCMOpenSSLHTTPTransport.DecodeChunked(Const AData : AnsiString) : AnsiString; +Var + LPos, + LEnd, + LChunkSize, + LSemi : Integer; + LLine : String; +Begin + Result := ''; + LPos := 1; + + While LPos <= Length(AData) Do + Begin + LEnd := LPos; + + While (LEnd < Length(AData)) And + Not ((AData[LEnd] = #13) And + (AData[LEnd + 1] = #10)) Do + Inc(LEnd); + + If LEnd >= Length(AData) Then + Raise Exception.Create('FCM HTTPS: resposta chunked invalida'); + + LLine := String(Copy(AData, LPos, LEnd - LPos)); + LSemi := Pos(';', LLine); + + If LSemi > 0 Then + LLine := Copy(LLine, 1, LSemi - 1); + + LLine := Trim(LLine); + + If LLine = '' Then + Raise Exception.Create('FCM HTTPS: tamanho de chunk ausente'); + + LChunkSize := StrToIntDef('$' + LLine, -1); + + If LChunkSize < 0 Then + Raise Exception.Create('FCM HTTPS: tamanho de chunk invalido'); + + LPos := LEnd + 2; + + If LChunkSize = 0 Then + Exit; + + If LChunkSize > Length(AData) - LPos + 1 Then + Raise Exception.Create('FCM HTTPS: chunk truncado'); + + Result := Result + Copy(AData, LPos, LChunkSize); + Inc(LPos, LChunkSize); + + If Copy(AData, LPos, 2) <> #13#10 Then + Raise Exception.Create('FCM HTTPS: terminador de chunk invalido'); + + Inc(LPos, 2); + End; +End; + +Function TRESTDWFCMOpenSSLHTTPTransport.Post(Const AURL : String; + AHeaders : TStrings; + ABody : TStream; + AResponse : TStream; + AResponseError : TStream) : Integer; +Var + LContext : PSSL_CTX; + LBIO : PBIO; + LSSL : PSSL; + LHost, + LPath, + LHostPort : String; + LRequest, + LRaw, + LHeader, + LBodyText, + LResponseBody, + LStatusLine : AnsiString; + LPort, + I, + P, + LHeaderEnd, + LStatusEnd, + LRead, + LContentLength : Integer; + LBuffer : Array[0..8191] Of Byte; + LBodyBytes : TMemoryStream; + LChunked : Boolean; +Begin + Result := 0; + + If AResponse <> Nil Then + Begin + AResponse.Size := 0; + AResponse.Position := 0; + End; + + If AResponseError <> Nil Then + Begin + AResponseError.Size := 0; + AResponseError.Position := 0; + End; + + ParseHTTPSURL(AURL, + LHost, + LPath, + LPort); + + LBodyBytes := TMemoryStream.Create; + Try + If ABody <> Nil Then + Begin + ABody.Position := 0; + LBodyBytes.CopyFrom(ABody, 0); + End; + + LRequest := + AnsiString( + 'POST ' + LPath + ' HTTP/1.1' + #13#10 + + 'Host: ' + LHost + #13#10 + + 'Connection: close' + #13#10 + + 'Content-Length: ' + IntToStr(LBodyBytes.Size) + #13#10 + ); + + If AHeaders <> Nil Then + For I := 0 To AHeaders.Count - 1 Do + If AHeaders.Names[I] <> '' Then + LRequest := + LRequest + + AnsiString( + AHeaders.Names[I] + ': ' + + AHeaders.ValueFromIndex[I] + #13#10 + ); + + LRequest := LRequest + #13#10; + + LContext := SSL_CTX_new(TLSv1_2_client_method); + If LContext = Nil Then + Raise Exception.Create('FCM HTTPS: SSL_CTX_new falhou'); + + Try + RESTDWFCMConfigureTLSContext( + LContext, + FVerifyPeer, + FCAFile, + FCAPath + ); + Except + SSL_CTX_free(LContext); + Raise; + End; + + LBIO := BIO_new_ssl_connect(LContext); + If LBIO = Nil Then + Begin + SSL_CTX_free(LContext); + Raise Exception.Create('FCM HTTPS: BIO_new_ssl_connect falhou'); + End; + + Try + LHostPort := LHost + ':' + IntToStr(LPort); + + If BIO_ctrl(LBIO, + BIO_C_SET_CONNECT, + 0, + PAnsiChar(AnsiString(LHostPort))) <= 0 Then + Raise Exception.Create('FCM HTTPS: host invalido'); + + LSSL := Nil; + + BIO_ctrl(LBIO, + BIO_C_GET_SSL, + 0, + @LSSL); + + If LSSL <> Nil Then + RESTDWFCMConfigureTLSConnection( + LSSL, + LHost, + FVerifyPeer + ); + + If BIO_ctrl(LBIO, + BIO_C_DO_STATE_MACHINE, + 0, + Nil) <= 0 Then + Raise Exception.Create('FCM HTTPS: conexao TLS falhou'); + + RESTDWFCMCheckTLSConnection( + LSSL, + FVerifyPeer + ); + + If LRequest <> '' Then + Begin + P := 1; + + While P <= Length(LRequest) Do + Begin + LRead := BIO_write(LBIO, + @LRequest[P], + Length(LRequest) - P + 1); + + If LRead <= 0 Then + Raise Exception.Create('FCM HTTPS: escrita do cabecalho falhou'); + + Inc(P, LRead); + End; + End; + + If LBodyBytes.Size > 0 Then + Begin + LBodyBytes.Position := 0; + + While LBodyBytes.Position < LBodyBytes.Size Do + Begin + LRead := LBodyBytes.Read(LBuffer[0], + SizeOf(LBuffer)); + + If LRead <= 0 Then + Break; + + P := 0; + + While P < LRead Do + Begin + I := BIO_write(LBIO, + @LBuffer[P], + LRead - P); + + If I <= 0 Then + Raise Exception.Create('FCM HTTPS: escrita do body falhou'); + + Inc(P, I); + End; + End; + End; + + LRaw := ''; + + Repeat + LRead := BIO_read(LBIO, + @LBuffer[0], + SizeOf(LBuffer)); + + If LRead > 0 Then + Begin + SetLength(LBodyText, LRead); + + For I := 0 To LRead - 1 Do + LBodyText[I + 1] := AnsiChar(LBuffer[I]); + + LRaw := LRaw + LBodyText; + End; + Until LRead <= 0; + + LHeaderEnd := Pos(#13#10#13#10, LRaw); + + If LHeaderEnd = 0 Then + Raise Exception.Create('FCM HTTPS: resposta HTTP invalida'); + + LHeader := Copy(LRaw, 1, LHeaderEnd - 1); + LResponseBody := Copy(LRaw, + LHeaderEnd + 4, + MaxInt); + + LStatusEnd := Pos(#13#10, LHeader); + + If LStatusEnd > 0 Then + LStatusLine := Copy(LHeader, 1, LStatusEnd - 1) + Else + LStatusLine := LHeader; + + P := Pos(' ', LStatusLine); + + If P = 0 Then + Raise Exception.Create('FCM HTTPS: status HTTP invalido'); + + Result := + StrToIntDef( + Copy( + LStatusLine, + P + 1, + 3 + ), + -1 + ); + + If Result < 100 Then + Raise Exception.Create('FCM HTTPS: codigo HTTP invalido'); + + LChunked := + Pos('transfer-encoding: chunked', + LowerCase(LHeader)) > 0; + + If LChunked Then + LResponseBody := DecodeChunked(LResponseBody) + Else + Begin + LContentLength := 0; + P := Pos('content-length:', + LowerCase(LHeader)); + + If P > 0 Then + Begin + P := P + Length('content-length:'); + + While (P <= Length(LHeader)) And + (LHeader[P] = ' ') Do + Inc(P); + + I := P; + + While (I <= Length(LHeader)) And + (LHeader[I] >= '0') And + (LHeader[I] <= '9') Do + Inc(I); + + LContentLength := + StrToIntDef( + Copy(LHeader, + P, + I - P), + 0 + ); + + If LContentLength > 0 Then + Begin + If Length(LResponseBody) < LContentLength Then + Raise Exception.Create('FCM HTTPS: body HTTP truncado'); + + If Length(LResponseBody) > LContentLength Then + SetLength( + LResponseBody, + LContentLength + ); + End; + End; + End; + + If (Result >= 200) And + (Result < 300) Then + Begin + If (AResponse <> Nil) And + (LResponseBody <> '') Then + AResponse.WriteBuffer( + LResponseBody[1], + Length(LResponseBody) + ); + End + Else + Begin + If (AResponseError <> Nil) And + (LResponseBody <> '') Then + AResponseError.WriteBuffer( + LResponseBody[1], + Length(LResponseBody) + ); + End; + Finally + BIO_free_all(LBIO); + SSL_CTX_free(LContext); + End; + Finally + LBodyBytes.Free; + + If AResponse <> Nil Then + AResponse.Position := 0; + + If AResponseError <> Nil Then + AResponseError.Position := 0; + End; +End; + +End. diff --git a/CORE/Source/Sockets/uRESTDWFCMOpenSSLStream.pas b/CORE/Source/Sockets/uRESTDWFCMOpenSSLStream.pas new file mode 100644 index 000000000..52ac7724b --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFCMOpenSSLStream.pas @@ -0,0 +1,278 @@ +Unit uRESTDWFCMOpenSSLStream; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + uRESTDWFCMTransport; + +Type + TRESTDWFCMOpenSSLStreamTransport = Class(TRESTDWFCMStreamTransport) + Private + FContext : Pointer; + FBIO : Pointer; + FConnected : Boolean; + FVerifyPeer : Boolean; + FCAFile : String; + FCAPath : String; + + Procedure ReleaseHandles; + Public + Constructor Create; + Destructor Destroy; Override; + + Procedure ConfigureTLS(AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); Override; + + Procedure Connect(Const AHost : String; + APort : Integer); Override; + Procedure Disconnect; Override; + Function Connected : Boolean; Override; + Function ReadByte : Byte; Override; + Procedure ReadBuffer(Var ABuffer; ACount : Integer); Override; + Procedure WriteBuffer(Const ABuffer; ACount : Integer); Override; + End; + +Implementation + +Uses + uRESTDWOpenSslLib, + uRESTDWFCMCompat, + uRESTDWFCMTLS; + +Constructor TRESTDWFCMOpenSSLStreamTransport.Create; +Begin + Inherited Create; + FContext := Nil; + FBIO := Nil; + FConnected := False; + FVerifyPeer := True; + FCAFile := ''; + FCAPath := ''; +End; + +Procedure TRESTDWFCMOpenSSLStreamTransport.ConfigureTLS(AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); +Begin + FVerifyPeer := AVerifyPeer; + FCAFile := ACAFile; + FCAPath := ACAPath; +End; + +Destructor TRESTDWFCMOpenSSLStreamTransport.Destroy; +Begin + FConnected := False; + ReleaseHandles; + Inherited Destroy; +End; + +Procedure TRESTDWFCMOpenSSLStreamTransport.ReleaseHandles; +Begin + If FBIO <> Nil Then + Begin + BIO_free_all(PBIO(FBIO)); + FBIO := Nil; + End; + + If FContext <> Nil Then + Begin + SSL_CTX_free(PSSL_CTX(FContext)); + FContext := Nil; + End; +End; + +Procedure TRESTDWFCMOpenSSLStreamTransport.Connect(Const AHost : String; + APort : Integer); +Var + LContext : PSSL_CTX; + LBIO : PBIO; + LSSL : PSSL; + LHostPort : AnsiString; +Begin + FConnected := False; + ReleaseHandles; + + LContext := SSL_CTX_new(TLSv1_2_client_method); + + If LContext = Nil Then + Raise Exception.Create('FCM TLS: SSL_CTX_new falhou'); + + LBIO := Nil; + + Try + RESTDWFCMConfigureTLSContext( + LContext, + FVerifyPeer, + FCAFile, + FCAPath + ); + + LBIO := BIO_new_ssl_connect(LContext); + + If LBIO = Nil Then + Raise Exception.Create('FCM TLS: BIO_new_ssl_connect falhou'); + + LHostPort := + AnsiString( + AHost + ':' + IntToStr(APort) + ); + + If BIO_ctrl( + LBIO, + BIO_C_SET_CONNECT, + 0, + PAnsiChar(LHostPort) + ) <= 0 Then + Raise Exception.Create('FCM TLS: hostname invalido'); + + LSSL := Nil; + + BIO_ctrl( + LBIO, + BIO_C_GET_SSL, + 0, + @LSSL + ); + + RESTDWFCMConfigureTLSConnection( + LSSL, + AHost, + FVerifyPeer + ); + + If BIO_ctrl( + LBIO, + BIO_C_DO_STATE_MACHINE, + 0, + Nil + ) <= 0 Then + Raise Exception.Create('FCM TLS: conexao falhou'); + + RESTDWFCMCheckTLSConnection( + LSSL, + FVerifyPeer + ); + + If BIO_ctrl( + LBIO, + BIO_C_SET_NBIO, + 1, + Nil + ) <= 0 Then + Raise Exception.Create('FCM TLS: modo nonblocking falhou'); + + FContext := LContext; + FBIO := LBIO; + FConnected := True; + + { Ownership transferido para a instancia. } + LContext := Nil; + LBIO := Nil; + Finally + If LBIO <> Nil Then + BIO_free_all(LBIO); + + If LContext <> Nil Then + SSL_CTX_free(LContext); + End; +End; + +Procedure TRESTDWFCMOpenSSLStreamTransport.Disconnect; +Begin + { Nao libera BIO/SSL_CTX aqui. Disconnect pode ser chamado por outra + thread enquanto ReadBuffer esta executando. O BIO esta em nonblocking; + a thread leitora observa FConnected=False, sai e o destructor libera + os handles somente depois que a worker terminou. } + FConnected := False; +End; + +Function TRESTDWFCMOpenSSLStreamTransport.Connected : Boolean; +Begin + Result := FConnected And (FBIO <> Nil); +End; + +Function TRESTDWFCMOpenSSLStreamTransport.ReadByte : Byte; +Begin + ReadBuffer(Result, 1); +End; + +Procedure TRESTDWFCMOpenSSLStreamTransport.ReadBuffer(Var ABuffer; + ACount : Integer); +Var + LRead, + LTotal : Integer; + P : PByte; +Begin + If Not Connected Then + Raise Exception.Create('FCM TLS: stream desconectado'); + + P := @ABuffer; + LTotal := 0; + + While LTotal < ACount Do + Begin + LRead := BIO_read(PBIO(FBIO), + RESTDWFCMPtrOffset(P, LTotal), + ACount - LTotal); + If LRead <= 0 Then + Begin + If Not FConnected Then + Raise Exception.Create('FCM TLS: leitura interrompida'); + + If BIO_should_retry(PBIO(FBIO)) Then + Begin + RESTDWFCMSleep(10); + Continue; + End; + + FConnected := False; + Raise Exception.Create('FCM TLS: leitura encerrada'); + End; + + Inc(LTotal, LRead); + End; +End; + +Procedure TRESTDWFCMOpenSSLStreamTransport.WriteBuffer(Const ABuffer; + ACount : Integer); +Var + LWritten, + LTotal : Integer; + P : PByte; +Begin + If Not Connected Then + Raise Exception.Create('FCM TLS: stream desconectado'); + + P := @ABuffer; + LTotal := 0; + + While LTotal < ACount Do + Begin + LWritten := BIO_write(PBIO(FBIO), + RESTDWFCMPtrOffset(P, LTotal), + ACount - LTotal); + If LWritten <= 0 Then + Begin + If Not FConnected Then + Raise Exception.Create('FCM TLS: escrita interrompida'); + + If BIO_should_retry(PBIO(FBIO)) Then + Begin + RESTDWFCMSleep(10); + Continue; + End; + + FConnected := False; + Raise Exception.Create('FCM TLS: escrita encerrada'); + End; + + Inc(LTotal, LWritten); + End; +End; + +End. diff --git a/CORE/Source/Sockets/uRESTDWFCMProto.pas b/CORE/Source/Sockets/uRESTDWFCMProto.pas new file mode 100644 index 000000000..02a035fd1 --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFCMProto.pas @@ -0,0 +1,231 @@ +Unit uRESTDWFCMProto; + +interface + +{$I uRESTDW.inc} + +uses + Classes, + uRESTDWFCMCompat, + SysUtils; + +type + TRESTDWProto = class + public + Class Procedure WriteVarInt(AStream : TStream; AValue : TRESTDWFCMUInt64); + + Class Function ReadVarInt(AStream : TStream) : TRESTDWFCMUInt64; + + Class Procedure FieldVarInt(AStream : TStream; AField : Integer; AValue : TRESTDWFCMUInt64); + Class Procedure FieldFixed64(AStream : TStream; AField : Integer; AValue : TRESTDWFCMUInt64); + + Class Procedure FieldBool(AStream : TStream; AField : Integer; AValue : Boolean); + + Class Procedure FieldString(AStream : TStream; AField : Integer; Const AValue : String); + + Class Procedure FieldBytes(AStream : TStream; AField : Integer; Const AValue : TRESTDWFCMBytes); + + Class Function ReadLengthDelimited(AStream : TStream) : TRESTDWFCMBytes; + + Class Function FindStringField(Const AData : TRESTDWFCMBytes; AField : Integer) : String; + end; + +implementation + +class procedure TRESTDWProto.WriteVarInt( + AStream: TStream; + AValue: TRESTDWFCMUInt64 +); +var + LByte: Byte; +begin + repeat + LByte := Byte(AValue and $7F); + AValue := AValue shr 7; + + if AValue <> 0 then + LByte := LByte or $80; + + AStream.WriteBuffer(LByte, 1); + until AValue = 0; +end; + +class function TRESTDWProto.ReadVarInt( + AStream: TStream +): TRESTDWFCMUInt64; +var + LByte: Byte; + LShift: Integer; +begin + Result := 0; + LShift := 0; + + repeat + AStream.ReadBuffer(LByte, 1); + + If (LShift = 63) And + ((LByte And $FE) <> 0) Then + Raise Exception.Create('Protobuf varint excede UInt64'); + + Result := + Result Or + (TRESTDWFCMUInt64(LByte And $7F) Shl LShift); + + If (LByte And $80) = 0 Then + Break; + + Inc(LShift, 7); + + If LShift > 63 Then + Raise Exception.Create('Protobuf varint invalido'); + until False; +end; + +class procedure TRESTDWProto.FieldVarInt( + AStream: TStream; + AField: Integer; + AValue: TRESTDWFCMUInt64 +); +begin + WriteVarInt(AStream, TRESTDWFCMUInt64(AField shl 3)); + WriteVarInt(AStream, AValue); +end; + +Class Procedure TRESTDWProto.FieldFixed64(AStream : TStream; + AField : Integer; + AValue : TRESTDWFCMUInt64); +Var + LBytes : Array[0..7] Of Byte; + LIndex : Integer; +Begin + WriteVarInt( + AStream, + TRESTDWFCMUInt64((AField Shl 3) Or 1) + ); + + For LIndex := 0 To 7 Do + LBytes[LIndex] := Byte( + (AValue Shr (LIndex * 8)) And $FF + ); + + AStream.WriteBuffer( + LBytes[0], + SizeOf(LBytes) + ); +End; + + +class procedure TRESTDWProto.FieldBool( + AStream: TStream; + AField: Integer; + AValue: Boolean +); +begin + if AValue then + FieldVarInt(AStream, AField, 1) + else + FieldVarInt(AStream, AField, 0); +end; + +class procedure TRESTDWProto.FieldString( + AStream: TStream; + AField: Integer; + const AValue: string +); +var + LBytes: TRESTDWFCMBytes; +begin + LBytes := RESTDWFCMStringToBytes(AValue); + FieldBytes(AStream, AField, LBytes); +end; + +class procedure TRESTDWProto.FieldBytes( + AStream: TStream; + AField: Integer; + const AValue: TRESTDWFCMBytes +); +begin + WriteVarInt(AStream, TRESTDWFCMUInt64((AField shl 3) or 2)); + WriteVarInt(AStream, Length(AValue)); + + if Length(AValue) > 0 then + AStream.WriteBuffer(AValue[0], Length(AValue)); +end; + +class function TRESTDWProto.ReadLengthDelimited( + AStream: TStream +): TRESTDWFCMBytes; +var + LLength: TRESTDWFCMUInt64; +begin + LLength := ReadVarInt(AStream); + + If LLength > TRESTDWFCMUInt64(MaxInt) Then + Raise Exception.Create('Protobuf length excede Integer'); + + If LLength > TRESTDWFCMUInt64(AStream.Size - AStream.Position) Then + Raise Exception.Create('Protobuf length excede o stream'); + + SetLength(Result, Integer(LLength)); + + If LLength > 0 Then + AStream.ReadBuffer(Result[0], Integer(LLength)); +end; + +class function TRESTDWProto.FindStringField( + const AData: TRESTDWFCMBytes; + AField: Integer +): string; +var + LStream: TRESTDWFCMBytesStream; + LKey: TRESTDWFCMUInt64; + LWireType: TRESTDWFCMUInt64; + LField: TRESTDWFCMUInt64; + LBytes: TRESTDWFCMBytes; +begin + Result := ''; + LStream := TRESTDWFCMBytesStream.Create(AData); + try + while LStream.Position < LStream.Size do + begin + LKey := ReadVarInt(LStream); + LWireType := LKey and 7; + LField := LKey shr 3; + + case LWireType of + 0: + ReadVarInt(LStream); + + 1: + Begin + If (LStream.Size - LStream.Position) < 8 Then + Raise Exception.Create('Protobuf fixed64 truncado'); + LStream.Seek(8, soCurrent); + End; + + 2: + begin + LBytes := ReadLengthDelimited(LStream); + if LField = TRESTDWFCMUInt64(AField) then + begin + Result := RESTDWFCMBytesToString(LBytes); + Exit; + end; + end; + + 5: + Begin + If (LStream.Size - LStream.Position) < 4 Then + Raise Exception.Create('Protobuf fixed32 truncado'); + LStream.Seek(4, soCurrent); + End; + else + raise Exception.Create('Wire type protobuf nao suportado'); + end; + end; + finally + LStream.Free; + end; +end; + +end. diff --git a/CORE/Source/Sockets/uRESTDWFCMRegistration.pas b/CORE/Source/Sockets/uRESTDWFCMRegistration.pas new file mode 100644 index 000000000..455464c99 --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFCMRegistration.pas @@ -0,0 +1,256 @@ +Unit uRESTDWFCMRegistration; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + uRESTDWFCMTypes, + uRESTDWFCMTransport; + +Type + TRESTDWFCMRegistration = Class + Private + FConfig : TRESTDWFCMConfig; + FHTTP : TRESTDWFCMHTTPTransport; + Function Post(Const AURL, + ABody : String; + AHeaders : TStrings; + Var AResponse : String) : Integer; + Function NewPushAppID : String; + Procedure RegisterGCMEndpoint(Var ACredentials : TRESTDWFCMCredentials); + Procedure RegisterFCMToken(Var ACredentials : TRESTDWFCMCredentials); + Public + Constructor Create(Const AConfig : TRESTDWFCMConfig; + AHTTP : TRESTDWFCMHTTPTransport); + Procedure Execute(Var ACredentials : TRESTDWFCMCredentials); + End; + +Implementation + +Uses + uRESTDWFCMCompat, + uRESTDWFCMWebPush, + uRESTDWFCMCheckin; + +Const + CGCMRegistrationURL = 'https://android.clients.google.com/c2dm/register3'; + CFCMRegistrationURL = 'https://fcmregistrations.googleapis.com/v1/projects/'; + CFCMSendBase = 'https://fcm.googleapis.com/fcm/send/'; + CGCMRegisterApp = 'org.chromium.linux'; + CDefaultVAPIDKey = + 'BDOU99-h67HcA6JeFXHbSNMu7e2yNNu3RzoMj8TM4W88jITfq7ZmPvIM1Iv-4_l2LxQcYwhqby2xGpWwzjfAnG4'; + +Constructor TRESTDWFCMRegistration.Create(Const AConfig : TRESTDWFCMConfig; + AHTTP : TRESTDWFCMHTTPTransport); +Begin + Inherited Create; + FConfig := AConfig; + FHTTP := AHTTP; +End; + +Function TRESTDWFCMRegistration.Post(Const AURL, + ABody : String; + AHeaders : TStrings; + Var AResponse : String) : Integer; +Var + LBody, + LResponse, + LError : TRESTDWFCMUTF8Stream; +Begin + LBody := TRESTDWFCMUTF8Stream.Create(ABody); + LResponse := TRESTDWFCMUTF8Stream.Create(''); + LError := TRESTDWFCMUTF8Stream.Create(''); + Try + Result := FHTTP.Post(AURL, AHeaders, LBody, LResponse, LError); + If LResponse.Size > 0 Then + AResponse := LResponse.AsString + Else + AResponse := LError.AsString; + Finally + LError.Free; + LResponse.Free; + LBody.Free; + End; +End; + +Function TRESTDWFCMRegistration.NewPushAppID : String; +Var + LGUID : TGUID; + LBundle : String; +Begin + If FConfig.ClientCategory <> '' Then + LBundle := FConfig.ClientCategory + Else + LBundle := 'receiver.push.com'; + + CreateGUID(LGUID); + Result := GUIDToString(LGUID); + Result := StringReplace(Result, '{', '', [rfReplaceAll]); + Result := StringReplace(Result, '}', '', [rfReplaceAll]); + Result := LowerCase(Result); + Result := 'wp:' + LBundle + '#' + Result; +End; + +Procedure TRESTDWFCMRegistration.RegisterGCMEndpoint(Var ACredentials : TRESTDWFCMCredentials); +Var + LBody, + LAuthorization, + LResponse, + LURL : String; + LHeaders : TStringList; + LCode, + LTry : Integer; + LCheckin : TRESTDWGCMCheckin; +Begin + If ACredentials.DeviceID = 0 Then + Raise Exception.Create('DeviceID nao foi criado'); + If ACredentials.SecurityToken = 0 Then + Raise Exception.Create('SecurityToken nao foi criado'); + If ACredentials.PushAppID = '' Then + ACredentials.PushAppID := NewPushAppID; + + If ACredentials.RegistrationURL <> '' Then + LURL := ACredentials.RegistrationURL + Else + LURL := CGCMRegistrationURL; + + For LTry := 0 To 4 Do + Begin + LBody := + 'app=' + RESTDWFCMURLEncode(CGCMRegisterApp) + + '&X-subtype=' + RESTDWFCMURLEncode(ACredentials.PushAppID) + + '&device=' + RESTDWFCMURLEncode(RESTDWFCMUIntToStr(ACredentials.DeviceID)) + + '&sender=' + RESTDWFCMURLEncode(CDefaultVAPIDKey); + + LAuthorization := + 'AidLogin ' + + RESTDWFCMUIntToStr(ACredentials.DeviceID) + + ':' + + RESTDWFCMUIntToStr(ACredentials.SecurityToken); + + LHeaders := TStringList.Create; + Try + LHeaders.Values['Authorization'] := LAuthorization; + LHeaders.Values['Content-Type'] := 'application/x-www-form-urlencoded'; + LHeaders.Values['Accept'] := '*/*'; + LCode := Post(LURL, LBody, LHeaders, LResponse); + Finally + LHeaders.Free; + End; + + LResponse := Trim(LResponse); + If (LCode Div 100) <> 2 Then + Raise Exception.Create('GCM Endpoint HTTP ' + + IntToStr(LCode) + ': ' + LResponse); + + If Pos('token=', LResponse) = 1 Then + Begin + ACredentials.PushSubscriptionID := Copy(LResponse, 7, MaxInt); + Break; + End; + + If SameText(LResponse, 'Error=PHONE_REGISTRATION_ERROR') Then + Begin + ACredentials.DeviceID := 0; + ACredentials.SecurityToken := 0; + ACredentials.RegistrationURL := ''; + + LCheckin := TRESTDWGCMCheckin.Create(FHTTP); + Try + LCheckin.Execute(ACredentials); + Finally + LCheckin.Free; + End; + + If ACredentials.RegistrationURL <> '' Then + LURL := ACredentials.RegistrationURL + Else + LURL := CGCMRegistrationURL; + + If LTry < 4 Then + RESTDWFCMSleep(1000 * (LTry + 1)); + Continue; + End; + + If Pos('Error=', LResponse) = 1 Then + Raise Exception.Create('GCM Endpoint: ' + LResponse); + + Raise Exception.Create('GCM Endpoint resposta inesperada: ' + LResponse); + End; + + If ACredentials.PushSubscriptionID = '' Then + Raise Exception.Create('GCM Endpoint: PHONE_REGISTRATION_ERROR apos novo check-in'); + + ACredentials.PushEndpoint := CFCMSendBase + ACredentials.PushSubscriptionID; +End; + +Procedure TRESTDWFCMRegistration.RegisterFCMToken(Var ACredentials : TRESTDWFCMCredentials); +Var + LURL, + LBody, + LResponse : String; + LHeaders : TStringList; + LCode : Integer; +Begin + If ACredentials.FISAuthToken = '' Then + Raise Exception.Create('FISAuthToken nao foi criado'); + If ACredentials.PushEndpoint = '' Then + Raise Exception.Create('PushEndpoint nao foi criado'); + If ACredentials.PushPublicKey = '' Then + Raise Exception.Create('PushPublicKey nao foi criada'); + If ACredentials.PushAuth = '' Then + Raise Exception.Create('PushAuth nao foi criado'); + + LBody := + '{"web":{"endpoint":"' + ACredentials.PushEndpoint + + '","auth":"' + ACredentials.PushAuth + + '","p256dh":"' + ACredentials.PushPublicKey + '"'; + + If (FConfig.VAPIDKey <> '') And + (FConfig.VAPIDKey <> CDefaultVAPIDKey) Then + LBody := LBody + ',"applicationPubKey":"' + + FConfig.VAPIDKey + '"'; + + LBody := LBody + '}}'; + LURL := CFCMRegistrationURL + FConfig.ProjectID + '/registrations'; + + LHeaders := TStringList.Create; + Try + LHeaders.Values['x-goog-api-key'] := FConfig.APIKey; + LHeaders.Values['x-goog-firebase-installations-auth'] := + 'FIS ' + ACredentials.FISAuthToken; + LHeaders.Values['Content-Type'] := 'application/json'; + LHeaders.Values['Accept'] := 'application/json'; + + LCode := Post(LURL, LBody, LHeaders, LResponse); + Finally + LHeaders.Free; + End; + + If (LCode Div 100) <> 2 Then + Raise Exception.Create('FCM Registration HTTP ' + + IntToStr(LCode) + ': ' + LResponse); + + ACredentials.FCMToken := RESTDWFCMJSONValue(LResponse, 'token'); + If ACredentials.FCMToken = '' Then + Raise Exception.Create('FCM Registration retornou token vazio'); +End; + +Procedure TRESTDWFCMRegistration.Execute(Var ACredentials : TRESTDWFCMCredentials); +Begin + { A estrutura de subscription usada pelo endpoint tem formato WebPush, + mas e criada e negociada pelo REST Dataware. Nao existe navegador, + ServiceWorker ou Push API envolvidos nesta chamada. } + TRESTDWWebPush.Prepare(FConfig, ACredentials); + + If (ACredentials.PushSubscriptionID = '') Or + (ACredentials.PushEndpoint = '') Then + RegisterGCMEndpoint(ACredentials); + + RegisterFCMToken(ACredentials); +End; + +End. diff --git a/CORE/Source/Sockets/uRESTDWFCMTLS.pas b/CORE/Source/Sockets/uRESTDWFCMTLS.pas new file mode 100644 index 000000000..f36eefe3a --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFCMTLS.pas @@ -0,0 +1,184 @@ +Unit uRESTDWFCMTLS; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + uRESTDWOpenSslLib; + +Procedure RESTDWFCMConfigureTLSContext(AContext : PSSL_CTX; + AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); + +Procedure RESTDWFCMConfigureTLSConnection(ASSL : PSSL; + Const AHost : String; + AVerifyPeer : Boolean); + +Procedure RESTDWFCMCheckTLSConnection(ASSL : PSSL; + AVerifyPeer : Boolean); + +Implementation + +Function RESTDWFCMLoadLocation(AContext : PSSL_CTX; + Const ACAFile, + ACAPath : String) : Boolean; +Var + LFile, + LPath : AnsiString; + PFile, + PPath : PAnsiChar; +Begin + Result := False; + + LFile := AnsiString(ACAFile); + LPath := AnsiString(ACAPath); + + If LFile <> '' Then + PFile := PAnsiChar(LFile) + Else + PFile := Nil; + + If LPath <> '' Then + PPath := PAnsiChar(LPath) + Else + PPath := Nil; + + If (PFile = Nil) And + (PPath = Nil) Then + Exit; + + Result := + SSL_CTX_load_verify_locations( + AContext, + PFile, + PPath + ) = 1; +End; + +Function RESTDWFCMDefaultCAFile : String; +Begin + Result := + ExtractFilePath(ParamStr(0)) + + 'RESTDWRootCA.pem'; +End; + +Procedure RESTDWFCMConfigureTLSContext(AContext : PSSL_CTX; + AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); +Var + LLoaded : Boolean; +Begin + If AContext = Nil Then + Raise Exception.Create('FCM TLS: contexto OpenSSL invalido'); + + SSL_CTX_set_options( + AContext, + SSL_OP_NO_SSLv2 Or + SSL_OP_NO_SSLv3 Or + SSL_OP_NO_TLSv1 Or + SSL_OP_NO_TLSv1_1 + ); + + If Not AVerifyPeer Then + Begin + SSL_CTX_set_verify( + AContext, + SSL_VERIFY_NONE, + Nil + ); + Exit; + End; + + SSL_CTX_set_verify( + AContext, + SSL_VERIFY_PEER, + Nil + ); + + LLoaded := False; + + If (ACAFile <> '') Or + (ACAPath <> '') Then + Begin + LLoaded := + RESTDWFCMLoadLocation( + AContext, + ACAFile, + ACAPath + ); + + If Not LLoaded Then + Raise Exception.Create( + 'FCM TLS: nao foi possivel carregar TLSCAFile/TLSCAPath' + ); + End + Else + LLoaded := + RESTDWFCMLoadLocation( + AContext, + RESTDWFCMDefaultCAFile, + '' + ); + + If Not LLoaded Then + Raise Exception.Create( + 'FCM TLS: RESTDWRootCA.pem nao encontrado' + ); +End; + +Procedure RESTDWFCMConfigureTLSConnection(ASSL : PSSL; + Const AHost : String; + AVerifyPeer : Boolean); +Var + LHost : AnsiString; +Begin + If ASSL = Nil Then + Raise Exception.Create('FCM TLS: SSL invalido'); + + If AHost <> '' Then + SSL_set_tlsext_host_name( + ASSL, + AHost + ); + + If Not AVerifyPeer Then + Exit; + + LHost := AnsiString(AHost); + + If LHost = '' Then + Raise Exception.Create( + 'FCM TLS: hostname necessario para validacao TLS' + ); + + If X509_VERIFY_PARAM_set1_host( + SSL_get0_param(ASSL), + PAnsiChar(LHost), + 0 + ) <> 1 Then + Raise Exception.Create( + 'FCM TLS: nao foi possivel configurar validacao do hostname' + ); +End; + +Procedure RESTDWFCMCheckTLSConnection(ASSL : PSSL; + AVerifyPeer : Boolean); +Begin + If Not AVerifyPeer Then + Exit; + + If ASSL = Nil Then + Raise Exception.Create('FCM TLS: SSL invalido'); + + If SSL_get_verify_result(ASSL) <> X509_V_OK Then + Raise Exception.Create( + 'FCM TLS: cadeia de certificados nao confiavel' + ); +End; + +End. diff --git a/CORE/Source/Sockets/uRESTDWFCMTransport.pas b/CORE/Source/Sockets/uRESTDWFCMTransport.pas new file mode 100644 index 000000000..cda2e17bc --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFCMTransport.pas @@ -0,0 +1,54 @@ +Unit uRESTDWFCMTransport; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils; + +Type + TRESTDWFCMHTTPTransport = Class + Public + Procedure ConfigureTLS(AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); Virtual; + + Function Post(Const AURL : String; + AHeaders : TStrings; + ABody : TStream; + AResponse : TStream; + AResponseError : TStream) : Integer; Virtual; Abstract; + End; + + TRESTDWFCMStreamTransport = Class + Public + Procedure ConfigureTLS(AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); Virtual; + + Procedure Connect(Const AHost : String; + APort : Integer); Virtual; Abstract; + Procedure Disconnect; Virtual; Abstract; + Function Connected : Boolean; Virtual; Abstract; + Function ReadByte : Byte; Virtual; Abstract; + Procedure ReadBuffer(Var ABuffer; ACount : Integer); Virtual; Abstract; + Procedure WriteBuffer(Const ABuffer; ACount : Integer); Virtual; Abstract; + End; + +Implementation + +Procedure TRESTDWFCMHTTPTransport.ConfigureTLS(AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); +Begin +End; + +Procedure TRESTDWFCMStreamTransport.ConfigureTLS(AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); +Begin +End; + +End. diff --git a/CORE/Source/Sockets/uRESTDWFCMTypes.pas b/CORE/Source/Sockets/uRESTDWFCMTypes.pas new file mode 100644 index 000000000..0d98ce44f --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFCMTypes.pas @@ -0,0 +1,52 @@ +Unit uRESTDWFCMTypes; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + uRESTDWFCMCompat; + +Type + TRESTDWFCMState = ( + fsStopped, + fsStarting, + fsCreatingInstallation, + fsRefreshingAuth, + fsCheckin, + fsRegisteringToken, + fsConnecting, + fsConnected, + fsError + ); + + TRESTDWFCMConfig = Record + ProjectID : String; + AppID : String; + APIKey : String; + VAPIDKey : String; + ClientCategory : String; + End; + + TRESTDWFCMCredentials = Record + DeviceID : TRESTDWFCMUInt64; + SecurityToken : TRESTDWFCMUInt64; + FID : String; + FISRefreshToken : String; + FISAuthToken : String; + RegistrationURL : String; + PushAppID : String; + PushInstanceID : String; + PushSubscriptionID : String; + PushEndpoint : String; + PushPublicKey : String; + PushPrivateKey : String; + PushAuth : String; + FCMToken : String; + End; + +Implementation + +End. diff --git a/CORE/Source/Sockets/uRESTDWFCMValue.pas b/CORE/Source/Sockets/uRESTDWFCMValue.pas new file mode 100644 index 000000000..245537f05 --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFCMValue.pas @@ -0,0 +1,255 @@ +Unit uRESTDWFCMValue; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + uRESTDWFCMCompat; + +Type + TRESTDWFCMValueKind = ( + fvkNull, + fvkString, + fvkNumber, + fvkBoolean, + fvkObject, + fvkArray + ); + + TRESTDWFCMValue = Class(TPersistent) + Private + FName : String; + FKind : TRESTDWFCMValueKind; + FStringValue : String; + FNumberValue : String; + FBooleanValue : Boolean; + FItems : TList; + + Procedure ClearItems; + Function GetCount : Integer; + Function GetItem(AIndex : Integer) : TRESTDWFCMValue; + Public + Constructor Create(AKind : TRESTDWFCMValueKind); Reintroduce; Overload; + Constructor Create; Overload; + Destructor Destroy; Override; + + Procedure Assign(Source : TPersistent); Override; + Procedure Clear; + + Function AddNull(Const AName : String) : TRESTDWFCMValue; + Function AddString(Const AName, + AValue : String) : TRESTDWFCMValue; + Function AddNumber(Const AName, + AValue : String) : TRESTDWFCMValue; + Function AddInteger(Const AName : String; + AValue : Int64) : TRESTDWFCMValue; + Function AddBoolean(Const AName : String; + AValue : Boolean) : TRESTDWFCMValue; + Function AddObject(Const AName : String) : TRESTDWFCMValue; + Function AddArray(Const AName : String) : TRESTDWFCMValue; Overload; + + Function AddArrayNull : TRESTDWFCMValue; + Function AddArrayString(Const AValue : String) : TRESTDWFCMValue; + Function AddArrayNumber(Const AValue : String) : TRESTDWFCMValue; + Function AddArrayInteger(AValue : Int64) : TRESTDWFCMValue; + Function AddArrayBoolean(AValue : Boolean) : TRESTDWFCMValue; + Function AddArrayObject : TRESTDWFCMValue; + Function AddArray : TRESTDWFCMValue; Overload; + + Property Count : Integer Read GetCount; + Property Items[AIndex : Integer] : TRESTDWFCMValue Read GetItem; Default; + Property Name : String Read FName Write FName; + Property Kind : TRESTDWFCMValueKind Read FKind Write FKind; + Property StringValue : String Read FStringValue Write FStringValue; + Property NumberValue : String Read FNumberValue Write FNumberValue; + Property BooleanValue : Boolean Read FBooleanValue Write FBooleanValue; + End; + +Implementation + +Constructor TRESTDWFCMValue.Create; +Begin + Inherited Create; + FItems := TList.Create; + FKind := fvkObject; +End; + +Constructor TRESTDWFCMValue.Create(AKind : TRESTDWFCMValueKind); +Begin + Inherited Create; + FItems := TList.Create; + FKind := AKind; +End; + +Destructor TRESTDWFCMValue.Destroy; +Begin + ClearItems; + FItems.Free; + Inherited Destroy; +End; + +Procedure TRESTDWFCMValue.ClearItems; +Var + I : Integer; +Begin + For I := FItems.Count - 1 DownTo 0 Do + TObject(FItems[I]).Free; + + FItems.Clear; +End; + +Procedure TRESTDWFCMValue.Clear; +Begin + ClearItems; + FName := ''; + FStringValue := ''; + FNumberValue := ''; + FBooleanValue := False; + FKind := fvkObject; +End; + +Function TRESTDWFCMValue.GetCount : Integer; +Begin + Result := FItems.Count; +End; + +Function TRESTDWFCMValue.GetItem(AIndex : Integer) : TRESTDWFCMValue; +Begin + Result := TRESTDWFCMValue(FItems[AIndex]); +End; + +Procedure TRESTDWFCMValue.Assign(Source : TPersistent); +Var + LSource : TRESTDWFCMValue; + LItem : TRESTDWFCMValue; + LNew : TRESTDWFCMValue; + I : Integer; +Begin + If Source Is TRESTDWFCMValue Then + Begin + LSource := TRESTDWFCMValue(Source); + + ClearItems; + + FName := LSource.Name; + FKind := LSource.Kind; + FStringValue := LSource.StringValue; + FNumberValue := LSource.NumberValue; + FBooleanValue := LSource.BooleanValue; + + For I := 0 To LSource.Count - 1 Do + Begin + LItem := LSource[I]; + LNew := TRESTDWFCMValue.Create(LItem.Kind); + LNew.Assign(LItem); + FItems.Add(LNew); + End; + End + Else + Inherited Assign(Source); +End; + +Function TRESTDWFCMValue.AddNull(Const AName : String) : TRESTDWFCMValue; +Begin + Result := TRESTDWFCMValue.Create(fvkNull); + Result.Name := AName; + FItems.Add(Result); +End; + +Function TRESTDWFCMValue.AddString(Const AName, + AValue : String) : TRESTDWFCMValue; +Begin + Result := TRESTDWFCMValue.Create(fvkString); + Result.Name := AName; + Result.StringValue := AValue; + FItems.Add(Result); +End; + +Function TRESTDWFCMValue.AddNumber(Const AName, + AValue : String) : TRESTDWFCMValue; +Begin + Result := TRESTDWFCMValue.Create(fvkNumber); + Result.Name := AName; + Result.NumberValue := AValue; + FItems.Add(Result); +End; + +Function TRESTDWFCMValue.AddInteger(Const AName : String; + AValue : Int64) : TRESTDWFCMValue; +Begin + If AValue < 0 Then + Result := + AddNumber( + AName, + '-' + RESTDWFCMUIntToStr(TRESTDWFCMUInt64(-(AValue + 1)) + 1) + ) + Else + Result := + AddNumber( + AName, + RESTDWFCMUIntToStr(TRESTDWFCMUInt64(AValue)) + ); +End; + +Function TRESTDWFCMValue.AddBoolean(Const AName : String; + AValue : Boolean) : TRESTDWFCMValue; +Begin + Result := TRESTDWFCMValue.Create(fvkBoolean); + Result.Name := AName; + Result.BooleanValue := AValue; + FItems.Add(Result); +End; + +Function TRESTDWFCMValue.AddObject(Const AName : String) : TRESTDWFCMValue; +Begin + Result := TRESTDWFCMValue.Create(fvkObject); + Result.Name := AName; + FItems.Add(Result); +End; + +Function TRESTDWFCMValue.AddArray(Const AName : String) : TRESTDWFCMValue; +Begin + Result := TRESTDWFCMValue.Create(fvkArray); + Result.Name := AName; + FItems.Add(Result); +End; + +Function TRESTDWFCMValue.AddArrayNull : TRESTDWFCMValue; +Begin + Result := AddNull(''); +End; + +Function TRESTDWFCMValue.AddArrayString(Const AValue : String) : TRESTDWFCMValue; +Begin + Result := AddString('', AValue); +End; + +Function TRESTDWFCMValue.AddArrayNumber(Const AValue : String) : TRESTDWFCMValue; +Begin + Result := AddNumber('', AValue); +End; + +Function TRESTDWFCMValue.AddArrayInteger(AValue : Int64) : TRESTDWFCMValue; +Begin + Result := AddInteger('', AValue); +End; + +Function TRESTDWFCMValue.AddArrayBoolean(AValue : Boolean) : TRESTDWFCMValue; +Begin + Result := AddBoolean('', AValue); +End; + +Function TRESTDWFCMValue.AddArrayObject : TRESTDWFCMValue; +Begin + Result := AddObject(''); +End; + +Function TRESTDWFCMValue.AddArray : TRESTDWFCMValue; +Begin + Result := AddArray(''); +End; + +End. diff --git a/CORE/Source/Sockets/uRESTDWFCMWebPush.pas b/CORE/Source/Sockets/uRESTDWFCMWebPush.pas new file mode 100644 index 000000000..0cefeeb88 --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFCMWebPush.pas @@ -0,0 +1,144 @@ +Unit uRESTDWFCMWebPush; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + uRESTDWFCMTypes, + uRESTDWFCMCompat; + +Type + TRESTDWWebPush = Class + Private + Class Procedure GenerateP256Keys(Out APublicKey, + APrivateKey : String); + Class Procedure GenerateAuthSecret(Out ASecret : String); + Public + Class Procedure Prepare(Const AConfig : TRESTDWFCMConfig; + Var ACredentials : TRESTDWFCMCredentials); + End; + +Implementation + +Uses + uRESTDWOpenSslLib; + +Class Procedure TRESTDWWebPush.GenerateAuthSecret(Out ASecret : String); +Var + LSecret : TRESTDWFCMBytes; +Begin + SetLength(LSecret, 16); + If RAND_bytes(@LSecret[0], Length(LSecret)) <> 1 Then + Raise Exception.Create('FCM WebPush: RAND_bytes falhou'); + ASecret := RESTDWFCMBase64URL(LSecret); +End; + +Class Procedure TRESTDWWebPush.GenerateP256Keys(Out APublicKey, + APrivateKey : String); +Var + LKey : PEC_KEY; + LPrivateBN : PBIGNUM; + LPublic : TRESTDWFCMBytes; + LPrivate : TRESTDWFCMBytes; + LPtr : PByte; + LSize : Integer; +Begin + APublicKey := ''; + APrivateKey := ''; + + LKey := EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + If LKey = Nil Then + Raise Exception.Create('FCM WebPush: EC_KEY_new_by_curve_name falhou'); + Try + If EC_KEY_generate_key(LKey) <> 1 Then + Raise Exception.Create('FCM WebPush: EC_KEY_generate_key falhou'); + + LSize := i2o_ECPublicKey(LKey, Nil); + If LSize <= 0 Then + Raise Exception.Create('FCM WebPush: tamanho da chave publica invalido'); + SetLength(LPublic, LSize); + LPtr := @LPublic[0]; + If i2o_ECPublicKey(LKey, @LPtr) <> LSize Then + Raise Exception.Create('FCM WebPush: export da chave publica falhou'); + + LPrivateBN := EC_KEY_get0_private_key(LKey); + If LPrivateBN = Nil Then + Raise Exception.Create('FCM WebPush: chave privada ausente'); + SetLength(LPrivate, 32); + FillChar(LPrivate[0], Length(LPrivate), 0); + LSize := (BN_num_bits(LPrivateBN) + 7) Div 8; + + If LSize > 32 Then + Raise Exception.Create('FCM WebPush: chave privada P-256 invalida'); + + If LSize > 0 Then + BN_bn2bin(LPrivateBN, @LPrivate[32 - LSize]); + + APublicKey := RESTDWFCMBase64URL(LPublic); + APrivateKey := RESTDWFCMBase64URL(LPrivate); + Finally + EC_KEY_free(LKey); + End; +End; + +Class Procedure TRESTDWWebPush.Prepare(Const AConfig : TRESTDWFCMConfig; + Var ACredentials : TRESTDWFCMCredentials); +Var + LPublic, + LPrivate, + LAuth : TRESTDWFCMBytes; + LValid : Boolean; +Begin + LValid := False; + + If (ACredentials.PushPublicKey <> '') And + (ACredentials.PushPrivateKey <> '') And + (ACredentials.PushAuth <> '') Then + Begin + Try + LPublic := + RESTDWFCMBase64URLDecode( + ACredentials.PushPublicKey + ); + + LPrivate := + RESTDWFCMBase64URLDecode( + ACredentials.PushPrivateKey + ); + + LAuth := + RESTDWFCMBase64URLDecode( + ACredentials.PushAuth + ); + + LValid := + (Length(LPublic) = 65) And + (LPublic[0] = $04) And + (Length(LPrivate) = 32) And + (Length(LAuth) = 16); + Except + LValid := False; + End; + End; + + If LValid Then + Exit; + + ACredentials.PushPublicKey := ''; + ACredentials.PushPrivateKey := ''; + ACredentials.PushAuth := ''; + + GenerateP256Keys( + ACredentials.PushPublicKey, + ACredentials.PushPrivateKey + ); + + GenerateAuthSecret( + ACredentials.PushAuth + ); +End; + +End. diff --git a/CORE/Source/Sockets/uRESTDWFirebaseCloudMessaging.pas b/CORE/Source/Sockets/uRESTDWFirebaseCloudMessaging.pas new file mode 100644 index 000000000..fd2d08b1d --- /dev/null +++ b/CORE/Source/Sockets/uRESTDWFirebaseCloudMessaging.pas @@ -0,0 +1,1341 @@ +Unit uRESTDWFirebaseCloudMessaging; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + IniFiles, + SyncObjs, + uRESTDWFCMTypes, + uRESTDWFCMMessage, + uRESTDWFCMTransport; + +Type + TRESTDWFirebaseCloudMessaging = Class; + + TRESTDWFCMTokenEvent = Procedure(Sender : TObject; + Const AToken : String) Of Object; + + TRESTDWFCMMessageEvent = Procedure(Sender : TObject; + Message : TRESTDWFCMMessage) Of Object; + + TRESTDWFCMErrorEvent = Procedure(Sender : TObject; + Const AWhere, + AError : String) Of Object; + + TRESTDWFCMStateEvent = Procedure(Sender : TObject; + AState : TRESTDWFCMState) Of Object; + + TRESTDWFCMConnection = Class(TPersistent) + Private + FAutoReconnect : Boolean; + FConnectTimeout : Integer; + FReadTimeout : Integer; + FMCSReadTimeout : Integer; + FReconnectDelay : Integer; + FTLSVerifyPeer : Boolean; + FTLSCAFile : String; + FTLSCAPath : String; + + Function GetTLSAllowInsecure : Boolean; + Procedure SetTLSAllowInsecure(AValue : Boolean); + Public + Constructor Create; + Procedure Assign(Source : TPersistent); Override; + Published + Property AutoReconnect : Boolean Read FAutoReconnect Write FAutoReconnect; + Property ConnectTimeout : Integer Read FConnectTimeout Write FConnectTimeout; + Property ReadTimeout : Integer Read FReadTimeout Write FReadTimeout; + Property MCSReadTimeout : Integer Read FMCSReadTimeout Write FMCSReadTimeout; + Property ReconnectDelay : Integer Read FReconnectDelay Write FReconnectDelay; + Property TLSAllowInsecure : Boolean Read GetTLSAllowInsecure Write SetTLSAllowInsecure; + Property TLSVerifyPeer : Boolean Read FTLSVerifyPeer Write FTLSVerifyPeer; + Property TLSCAFile : String Read FTLSCAFile Write FTLSCAFile; + Property TLSCAPath : String Read FTLSCAPath Write FTLSCAPath; + End; + + TRESTDWFCMReceive = Class(TPersistent) + Private + FQueueSize : Integer; + Public + Constructor Create; + Procedure Assign(Source : TPersistent); Override; + Published + Property QueueSize : Integer Read FQueueSize Write FQueueSize; + End; + + TRESTDWFCMNotificationDisplayEvent = Procedure(Sender : TObject; + Target : TComponent; + Const ATitle, + ABody, + AImageURL : String) Of Object; + + TRESTDWFCMNotification = Class(TPersistent) + Private + FOwner : TComponent; + FActive : Boolean; + FTitle : String; + FPushObject : TComponent; + FToastObject : TComponent; + FOnDisplay : TRESTDWFCMNotificationDisplayEvent; + + Procedure SetPushObject(AValue : TComponent); + Procedure SetToastObject(AValue : TComponent); + Public + Constructor Create(AOwner : TComponent); + Published + Property Active : Boolean Read FActive Write FActive; + Property Title : String Read FTitle Write FTitle; + Property PushObject : TComponent Read FPushObject Write SetPushObject; + Property ToastObject : TComponent Read FToastObject Write SetToastObject; + Property OnDisplay : TRESTDWFCMNotificationDisplayEvent Read FOnDisplay Write FOnDisplay; + End; + + TRESTDWFCMQueueItem = Class + Public + PersistentID : String; + Message : TRESTDWFCMMessage; + Destructor Destroy; Override; + End; + + TRESTDWFCMWorker = Class(TThread) + Private + FOwner : TRESTDWFirebaseCloudMessaging; + Protected + Procedure Execute; Override; + Public + Constructor Create(AOwner : TRESTDWFirebaseCloudMessaging); + Function MustTerminate : Boolean; + End; + + TRESTDWFirebaseCloudMessaging = Class(TComponent) + Private + FProjectID : String; + + FAppID : String; + FAPIKey : String; + + FVAPIDKey : String; + + FClientEmail : String; + FPrivateKey : String; + FToken : String; + + FLastRequest : String; + FLastResponse : String; + FLastError : String; + FResponseCode : Integer; + + FStateLoaded : Boolean; + + FHTTP : TRESTDWFCMHTTPTransport; + FSendHTTP : TRESTDWFCMHTTPTransport; + FSendOAuth : TObject; + FSendLock : TCriticalSection; + FMCSLock : TCriticalSection; + FMCSStream : TRESTDWFCMStreamTransport; + FMCS : TObject; + FThread : TRESTDWFCMWorker; + FWorkerFinished : Boolean; + FInReceiveCallback : Boolean; + FCredentials : TRESTDWFCMCredentials; + + FQueue : TList; + FQueueLock : TCriticalSection; + FConnection : TRESTDWFCMConnection; + FReceive : TRESTDWFCMReceive; + FNotification : TRESTDWFCMNotification; + + FOnToken : TRESTDWFCMTokenEvent; + FOnMessage : TRESTDWFCMMessageEvent; + FOnError : TRESTDWFCMErrorEvent; + FOnState : TRESTDWFCMStateEvent; + + Function GetConfig : TRESTDWFCMConfig; + Function GetStateFileName : String; + Procedure LoadState; + Procedure SaveState; + Procedure Worker; + Procedure ProcessQueue; + Function SendTarget(Const ATargetName, + ATargetValue : String; + AMessage : TRESTDWFCMMessage) : Boolean; + Procedure MCSData(Sender : TObject; + Const APersistentID, + AMessageData, + ARaw : String); + Protected + Procedure Notification(AComponent : TComponent; + Operation : TOperation); Override; + + Function CreateHTTPTransport(AConnectTimeout, + AReadTimeout : Integer) : TRESTDWFCMHTTPTransport; Virtual; Abstract; + + Function CreateMCSStreamTransport(AConnectTimeout, + AReadTimeout : Integer) : TRESTDWFCMStreamTransport; Virtual; Abstract; + + Procedure SetToken(Const AValue : String); + Procedure QueueMessage(Const APersistentID : String; + AMessage : TRESTDWFCMMessage); + Procedure Error(Const AWhere, + AError : String); + Procedure State(AState : TRESTDWFCMState); + Procedure EnsureOpenSSL; + Public + Constructor Create(AOwner : TComponent); Override; + Destructor Destroy; Override; + + Procedure Start; + Procedure Stop; + Procedure RefreshToken; + Procedure LoadGoogleServices(Const AFileName : String); + Procedure LoadServiceAccount(Const AFileName : String); + Procedure LoadServiceAccountConfig(Const AFileName : String); + + Function Send(Const ADeviceToken : String; + AMessage : TRESTDWFCMMessage) : Boolean; + Function SendTopic(Const ATopic : String; + AMessage : TRESTDWFCMMessage) : Boolean; + Function SendCondition(Const ACondition : String; + AMessage : TRESTDWFCMMessage) : Boolean; + + Property Token : String Read FToken; + Property LastRequest : String Read FLastRequest; + Property LastResponse : String Read FLastResponse; + Property LastError : String Read FLastError; + Property ResponseCode : Integer Read FResponseCode; + Published + Property ProjectID : String Read FProjectID Write FProjectID; + + Property AppID : String Read FAppID Write FAppID; + Property APIKey : String Read FAPIKey Write FAPIKey; + + Property VAPIDKey : String Read FVAPIDKey Write FVAPIDKey; + + Property ClientEmail : String Read FClientEmail Write FClientEmail; + Property PrivateKey : String Read FPrivateKey Write FPrivateKey; + + Property Connection : TRESTDWFCMConnection Read FConnection; + Property Receive : TRESTDWFCMReceive Read FReceive; + Property NotificationOptions : TRESTDWFCMNotification Read FNotification; + + Property OnToken : TRESTDWFCMTokenEvent Read FOnToken Write FOnToken; + Property OnMessage : TRESTDWFCMMessageEvent Read FOnMessage Write FOnMessage; + Property OnError : TRESTDWFCMErrorEvent Read FOnError Write FOnError; + Property OnState : TRESTDWFCMStateEvent Read FOnState Write FOnState; + End; + +Implementation + +Uses + uRESTDWFCMCompat, + uRESTDWFCMJSON, + uRESTDWFCMOAuth, + uRESTDWFCMFIS, + uRESTDWFCMCheckin, + uRESTDWFCMRegistration, + uRESTDWFCMMCS, + uRESTDWOpenSslLib; + +Constructor TRESTDWFCMNotification.Create(AOwner : TComponent); +Begin + Inherited Create; + FOwner := AOwner; +End; + +Procedure TRESTDWFCMNotification.SetPushObject(AValue : TComponent); +Begin + FPushObject := AValue; + + If Assigned(FOwner) And + Assigned(FPushObject) Then + FPushObject.FreeNotification(FOwner); +End; + +Procedure TRESTDWFCMNotification.SetToastObject(AValue : TComponent); +Begin + FToastObject := AValue; + + If Assigned(FOwner) And + Assigned(FToastObject) Then + FToastObject.FreeNotification(FOwner); +End; + +Function TRESTDWFCMConnection.GetTLSAllowInsecure : Boolean; +Begin + Result := Not FTLSVerifyPeer; +End; + +Procedure TRESTDWFCMConnection.SetTLSAllowInsecure(AValue : Boolean); +Begin + FTLSVerifyPeer := Not AValue; +End; + +Constructor TRESTDWFCMConnection.Create; +Begin + Inherited Create; + + FAutoReconnect := True; + FConnectTimeout := 15000; + FReadTimeout := 30000; + FMCSReadTimeout := 0; + FReconnectDelay := 2000; + FTLSVerifyPeer := True; + FTLSCAFile := ''; + FTLSCAPath := ''; +End; + +Procedure TRESTDWFCMConnection.Assign(Source : TPersistent); +Var + LSource : TRESTDWFCMConnection; +Begin + If Source Is TRESTDWFCMConnection Then + Begin + LSource := TRESTDWFCMConnection(Source); + + FAutoReconnect := LSource.AutoReconnect; + FConnectTimeout := LSource.ConnectTimeout; + FReadTimeout := LSource.ReadTimeout; + FMCSReadTimeout := LSource.MCSReadTimeout; + FReconnectDelay := LSource.ReconnectDelay; + FTLSVerifyPeer := LSource.TLSVerifyPeer; + FTLSCAFile := LSource.TLSCAFile; + FTLSCAPath := LSource.TLSCAPath; + End + Else + Inherited Assign(Source); +End; + +Constructor TRESTDWFCMReceive.Create; +Begin + Inherited Create; + FQueueSize := 1000; +End; + +Procedure TRESTDWFCMReceive.Assign(Source : TPersistent); +Begin + If Source Is TRESTDWFCMReceive Then + FQueueSize := TRESTDWFCMReceive(Source).QueueSize + Else + Inherited Assign(Source); +End; + +Destructor TRESTDWFCMQueueItem.Destroy; +Begin + Message.Free; + Inherited Destroy; +End; + +Constructor TRESTDWFCMWorker.Create(AOwner : TRESTDWFirebaseCloudMessaging); +Begin + Inherited Create(True); + FreeOnTerminate := False; + FOwner := AOwner; +End; + +Procedure TRESTDWFCMWorker.Execute; +Begin + FOwner.Worker; +End; + +Function TRESTDWFCMWorker.MustTerminate : Boolean; +Begin + Result := Terminated; +End; + +Constructor TRESTDWFirebaseCloudMessaging.Create(AOwner : TComponent); +Begin + Inherited Create(AOwner); +{ O estado pertence ao REST Dataware, nao ao SysOp. } + + FQueue := TList.Create; + FQueueLock := TCriticalSection.Create; + FSendLock := TCriticalSection.Create; + FMCSLock := TCriticalSection.Create; + FConnection := TRESTDWFCMConnection.Create; + FReceive := TRESTDWFCMReceive.Create; + FNotification := TRESTDWFCMNotification.Create(Self); + + FHTTP := Nil; + FSendHTTP := Nil; + FSendOAuth := Nil; + FMCSStream := Nil; + FMCS := Nil; + FThread := Nil; + FWorkerFinished := False; + FInReceiveCallback := False; + +End; + +Destructor TRESTDWFirebaseCloudMessaging.Destroy; +Begin + Stop; + + FQueueLock.Acquire; + Try + While FQueue.Count > 0 Do + Begin + TObject(FQueue[FQueue.Count - 1]).Free; + FQueue.Delete(FQueue.Count - 1); + End; + Finally + FQueueLock.Release; + End; + + FSendOAuth.Free; + FSendHTTP.Free; + + FNotification.Free; + FReceive.Free; + FConnection.Free; + FMCSLock.Free; + FSendLock.Free; + FQueueLock.Free; + FQueue.Free; + + Inherited Destroy; +End; + +Procedure TRESTDWFirebaseCloudMessaging.Notification(AComponent : TComponent; + Operation : TOperation); +Begin + Inherited Notification(AComponent, Operation); + + If (Operation = opRemove) And + Assigned(FNotification) Then + Begin + If FNotification.FPushObject = AComponent Then + FNotification.FPushObject := Nil; + + If FNotification.FToastObject = AComponent Then + FNotification.FToastObject := Nil; + End; +End; + +Procedure TRESTDWFirebaseCloudMessaging.EnsureOpenSSL; +Begin + {$IFNDEF RESTDWLAMW} + If Not LoadCrypto Then + Raise Exception.Create('OpenSSL Crypto library not found'); + + If Not LoadSSL Then + Raise Exception.Create('OpenSSL SSL library not found'); + {$ENDIF} +End; + +Function TRESTDWFirebaseCloudMessaging.GetConfig : TRESTDWFCMConfig; +Begin + Result.ProjectID := FProjectID; + Result.AppID := FAppID; + Result.APIKey := FAPIKey; + Result.VAPIDKey := FVAPIDKey; + Result.ClientCategory := 'com.restdw.fcm'; +End; + +Function TRESTDWFirebaseCloudMessaging.GetStateFileName : String; +Var + LName : String; + I : Integer; +Begin +LName := FProjectID; + + If FAppID <> '' Then + LName := LName + '_' + FAppID; + + If LName = '' Then + LName := 'client'; + + For I := 1 To Length(LName) Do + If Not (((LName[I] >= 'a') And (LName[I] <= 'z')) Or + ((LName[I] >= 'A') And (LName[I] <= 'Z')) Or + ((LName[I] >= '0') And (LName[I] <= '9')) Or + (LName[I] = '-') Or + (LName[I] = '_') Or + (LName[I] = '.')) Then + LName[I] := '_'; + + If Length(LName) > 120 Then + SetLength(LName, 120); + + Result := + ExtractFilePath(ParamStr(0)) + + 'restdw_fcm_' + + LName + + '.dat'; +End; + +Procedure TRESTDWFirebaseCloudMessaging.LoadState; +Const + CStateVersion = 48; +Var + LIni : TIniFile; +Begin + + If Not FileExists(GetStateFileName) Then + Exit; + + LIni := TIniFile.Create(GetStateFileName); + Try + If LIni.ReadInteger('FCM', 'StateVersion', 0) <> CStateVersion Then + Exit; + + If Not SameText( + LIni.ReadString('FCM', 'ProjectID', ''), + FProjectID + ) Then + Exit; + + If Not SameText( + LIni.ReadString('FCM', 'AppID', ''), + FAppID + ) Then + Exit; + + FCredentials.DeviceID := + RESTDWFCMStrToUInt64Def( + LIni.ReadString('FCM', 'DeviceID', '0'), + 0 + ); + + FCredentials.SecurityToken := + RESTDWFCMStrToUInt64Def( + LIni.ReadString('FCM', 'SecurityToken', '0'), + 0 + ); + + FCredentials.FID := LIni.ReadString('FCM', 'FID', ''); + FCredentials.FISRefreshToken := LIni.ReadString('FCM', 'FISRefreshToken', ''); + FCredentials.FISAuthToken := LIni.ReadString('FCM', 'FISAuthToken', ''); + FCredentials.RegistrationURL := LIni.ReadString('FCM', 'RegistrationURL', ''); + FCredentials.PushAppID := LIni.ReadString('FCM', 'PushAppID', ''); + FCredentials.PushInstanceID := LIni.ReadString('FCM', 'PushInstanceID', ''); + FCredentials.PushSubscriptionID := LIni.ReadString('FCM', 'PushSubscriptionID', ''); + FCredentials.PushEndpoint := LIni.ReadString('FCM', 'PushEndpoint', ''); + FCredentials.PushPublicKey := LIni.ReadString('FCM', 'PushPublicKey', ''); + FCredentials.PushPrivateKey := LIni.ReadString('FCM', 'PushPrivateKey', ''); + FCredentials.PushAuth := LIni.ReadString('FCM', 'PushAuth', ''); + FCredentials.FCMToken := LIni.ReadString('FCM', 'FCMToken', ''); + + FToken := FCredentials.FCMToken; + Finally + LIni.Free; + End; +End; + +Procedure TRESTDWFirebaseCloudMessaging.SaveState; +Const + CStateVersion = 48; +Var + LIni : TIniFile; +Begin + + LIni := TIniFile.Create(GetStateFileName); + Try + LIni.WriteInteger('FCM', 'StateVersion', CStateVersion); + LIni.WriteString('FCM', 'ProjectID', FProjectID); + LIni.WriteString('FCM', 'AppID', FAppID); + + LIni.WriteString('FCM', 'DeviceID', RESTDWFCMUIntToStr(FCredentials.DeviceID)); + LIni.WriteString('FCM', 'SecurityToken', RESTDWFCMUIntToStr(FCredentials.SecurityToken)); + LIni.WriteString('FCM', 'FID', FCredentials.FID); + LIni.WriteString('FCM', 'FISRefreshToken', FCredentials.FISRefreshToken); + LIni.WriteString('FCM', 'FISAuthToken', FCredentials.FISAuthToken); + LIni.WriteString('FCM', 'RegistrationURL', FCredentials.RegistrationURL); + LIni.WriteString('FCM', 'PushAppID', FCredentials.PushAppID); + LIni.WriteString('FCM', 'PushInstanceID', FCredentials.PushInstanceID); + LIni.WriteString('FCM', 'PushSubscriptionID', FCredentials.PushSubscriptionID); + LIni.WriteString('FCM', 'PushEndpoint', FCredentials.PushEndpoint); + LIni.WriteString('FCM', 'PushPublicKey', FCredentials.PushPublicKey); + LIni.WriteString('FCM', 'PushPrivateKey', FCredentials.PushPrivateKey); + LIni.WriteString('FCM', 'PushAuth', FCredentials.PushAuth); + LIni.WriteString('FCM', 'FCMToken', FCredentials.FCMToken); + Finally + LIni.Free; + End; +End; + +Procedure TRESTDWFirebaseCloudMessaging.SetToken(Const AValue : String); +Begin + FToken := AValue; + + If Assigned(FOnToken) Then + Try + FOnToken(Self, FToken); + Except + End; +End; + +Procedure TRESTDWFirebaseCloudMessaging.Error(Const AWhere, + AError : String); +Begin + If Assigned(FOnError) Then + Try + FOnError(Self, AWhere, AError); + Except + End; +End; + +Procedure TRESTDWFirebaseCloudMessaging.State(AState : TRESTDWFCMState); +Begin + If Assigned(FOnState) Then + Try + FOnState(Self, AState); + Except + End; +End; + +Procedure TRESTDWFirebaseCloudMessaging.MCSData(Sender : TObject; + Const APersistentID, + AMessageData, + ARaw : String); +Var + LMessage : TRESTDWFCMMessage; +Begin + LMessage := TRESTDWFCMMessage.Create; + Try + If ARaw <> '' Then + RESTDWFCMJSONToMessage(ARaw, LMessage); + + If AMessageData <> '' Then + Begin + RESTDWFCMJSONToData(AMessageData, LMessage.Data); + If LMessage.Data.Count = 0 Then + LMessage.Data.Values['messagedata'] := AMessageData; + If LMessage.Title = '' Then + LMessage.Title := LMessage.Data.Values['title']; + + If LMessage.Body = '' Then + LMessage.Body := LMessage.Data.Values['body']; + End; + + QueueMessage(APersistentID, LMessage); + LMessage := Nil; + Finally + LMessage.Free; + End; +End; + +Procedure TRESTDWFirebaseCloudMessaging.QueueMessage(Const APersistentID : String; + AMessage : TRESTDWFCMMessage); +Var + LItem : TRESTDWFCMQueueItem; + LQueueItem : TRESTDWFCMQueueItem; + LMCS : TRESTDWMCSClient; + LDuplicate, + LQueueFull : Boolean; + I : Integer; +Begin + If AMessage = Nil Then + Exit; + + LItem := Nil; + LDuplicate := False; + LQueueFull := False; + + FQueueLock.Acquire; + Try + If APersistentID <> '' Then + For I := 0 To FQueue.Count - 1 Do + Begin + LQueueItem := TRESTDWFCMQueueItem(FQueue[I]); + + If LQueueItem.PersistentID = APersistentID Then + Begin + LDuplicate := True; + Break; + End; + End; + + If Not LDuplicate Then + Begin + If (FReceive.QueueSize > 0) And + (FQueue.Count >= FReceive.QueueSize) Then + LQueueFull := True + Else + Begin + LItem := TRESTDWFCMQueueItem.Create; + LItem.PersistentID := APersistentID; + LItem.Message := AMessage; + FQueue.Add(LItem); + End; + End; + Finally + FQueueLock.Release; + End; + + If LDuplicate Then + Begin + AMessage.Free; + + { A mensagem ja estava na FIFO porque um ACK anterior falhou. + Confirma novamente sem inserir uma segunda copia. } + FMCSLock.Acquire; + Try + If (APersistentID <> '') And + Assigned(FMCS) Then + Begin + LMCS := TRESTDWMCSClient(FMCS); + LMCS.Ack(APersistentID); + End; + Finally + FMCSLock.Release; + End; + + ProcessQueue; + Exit; + End; + + If LQueueFull Then + Begin + AMessage.Free; + + Error( + 'Receive', + 'FIFO queue is full' + ); + + { Sem ACK: o MCS pode reenviar depois. } + Exit; + End; + + { ACK somente depois que a mensagem ja esta garantida na FIFO. } + FMCSLock.Acquire; + Try + If (APersistentID <> '') And + Assigned(FMCS) Then + Begin + LMCS := TRESTDWMCSClient(FMCS); + LMCS.Ack(APersistentID); + End; + Finally + FMCSLock.Release; + End; + + ProcessQueue; +End; + +Procedure TRESTDWFirebaseCloudMessaging.ProcessQueue; +Var + LItem : TRESTDWFCMQueueItem; +Begin + Repeat + LItem := Nil; + + FQueueLock.Acquire; + Try + If FQueue.Count > 0 Then + Begin + LItem := TRESTDWFCMQueueItem(FQueue[0]); + FQueue.Delete(0); + End; + Finally + FQueueLock.Release; + End; + + If LItem <> Nil Then + Try + FInReceiveCallback := True; + Try + Try + If FNotification.Active And + Assigned(FNotification.FOnDisplay) Then + Begin + If FNotification.PushObject <> Nil Then + FNotification.FOnDisplay(Self, + FNotification.PushObject, + FNotification.Title, + LItem.Message.Body, + LItem.Message.ImageURL) + Else + If FNotification.ToastObject <> Nil Then + FNotification.FOnDisplay(Self, + FNotification.ToastObject, + FNotification.Title, + LItem.Message.Body, + LItem.Message.ImageURL); + End; + Except + On E : Exception Do + Error( + 'Notification', + E.Message + ); + End; + + Try + If Assigned(FOnMessage) Then + FOnMessage(Self, LItem.Message); + Except + On E : Exception Do + Error( + 'OnMessage', + E.Message + ); + End; + Finally + FInReceiveCallback := False; + End; + Finally + LItem.Free; + End; + + If Assigned(FThread) And + FThread.MustTerminate Then + Exit; + Until LItem = Nil; +End; + +Procedure TRESTDWFirebaseCloudMessaging.Worker; +Var + LInstallations : TRESTDWFirebaseInstallations; + LCheckin : TRESTDWGCMCheckin; + LRegistration : TRESTDWFCMRegistration; + LMCS : TRESTDWMCSClient; + LWhere : String; + LRetry : Integer; +Begin + LWhere := 'Inicializacao'; + + Try + If (FProjectID = '') Or + (FAppID = '') Or + (FAPIKey = '') Then + Raise Exception.Create('Configuracao Firebase FCM incompleta'); + + FHTTP := CreateHTTPTransport( + FConnection.ConnectTimeout, + FConnection.ReadTimeout + ); + If FHTTP = Nil Then + Raise Exception.Create('Motor HTTP FCM nao disponivel'); + + FHTTP.ConfigureTLS( + Not FConnection.TLSAllowInsecure, + FConnection.TLSCAFile, + FConnection.TLSCAPath + ); + + If (FCredentials.FID = '') Or + (FCredentials.FISRefreshToken = '') Then + Begin + State(fsCreatingInstallation); + LWhere := 'FIS CreateInstallation'; + + LInstallations := TRESTDWFirebaseInstallations.Create(GetConfig, FHTTP); + Try + LInstallations.CreateInstallation(FCredentials); + Finally + LInstallations.Free; + End; + End; + + State(fsRefreshingAuth); + LWhere := 'FIS RefreshAuthToken'; + + LInstallations := TRESTDWFirebaseInstallations.Create(GetConfig, FHTTP); + Try + LInstallations.RefreshAuthToken(FCredentials); + Finally + LInstallations.Free; + End; + + State(fsCheckin); + LWhere := 'GCM Checkin'; + + LCheckin := TRESTDWGCMCheckin.Create(FHTTP); + Try + LCheckin.Execute(FCredentials); + Finally + LCheckin.Free; + End; + + State(fsRegisteringToken); + LWhere := 'FCM Registration'; + + LRegistration := TRESTDWFCMRegistration.Create(GetConfig, FHTTP); + Try + LRegistration.Execute(FCredentials); + Finally + LRegistration.Free; + End; + + SaveState; + SetToken(FCredentials.FCMToken); + + State(fsCheckin); + LWhere := 'GCM Checkin antes do MCS'; + + LCheckin := TRESTDWGCMCheckin.Create(FHTTP); + Try + LCheckin.Execute(FCredentials); + Finally + LCheckin.Free; + End; + SaveState; + + While Not FThread.MustTerminate Do + Begin + Try + State(fsConnecting); + LWhere := 'MCS Connect'; + + If FThread.MustTerminate Then + Break; + + FMCSStream := CreateMCSStreamTransport( + FConnection.ConnectTimeout, + FConnection.MCSReadTimeout + ); + + If FMCSStream = Nil Then + Raise Exception.Create('Motor de stream TLS FCM nao disponivel'); + + FMCSStream.ConfigureTLS( + Not FConnection.TLSAllowInsecure, + FConnection.TLSCAFile, + FConnection.TLSCAPath + ); + + If FThread.MustTerminate Then + Begin + FreeAndNil(FMCSStream); + Break; + End; + + LMCS := TRESTDWMCSClient.Create(FCredentials, FMCSStream); + + FMCSLock.Acquire; + Try + FMCS := LMCS; + Finally + FMCSLock.Release; + End; + + Try + LMCS.OnData := {$IFDEF FPC}@{$ENDIF}MCSData; + LMCS.Connect; + State(fsConnected); + + LWhere := 'MCS Receive'; + LMCS.Run; + Finally + LMCS.OnData := Nil; + + FMCSLock.Acquire; + Try + FMCS := Nil; + Finally + FMCSLock.Release; + End; + + LMCS.Free; + FreeAndNil(FMCSStream); + End; + + If Not FThread.MustTerminate Then + Raise Exception.Create('Canal MCS desconectado'); + Except + On E : Exception Do + Begin + If FThread.MustTerminate Then + Break; + + State(fsError); + Error(LWhere, E.Message); + + If Not FConnection.AutoReconnect Then + Break; + + If FConnection.ReconnectDelay > 0 Then + For LRetry := 1 To (FConnection.ReconnectDelay Div 100) Do + Begin + If FThread.MustTerminate Then + Break; + RESTDWFCMSleep(100); + End; + End; + End; + End; + Except + On E : Exception Do + Begin + State(fsError); + Error(LWhere, E.Message); + End; + End; + + FreeAndNil(FHTTP); + FWorkerFinished := True; +End; + +Procedure TRESTDWFirebaseCloudMessaging.Start; +Begin + EnsureOpenSSL; + + If Assigned(FThread) Then + Begin + If FWorkerFinished Then + Begin + FThread.WaitFor; + FreeAndNil(FThread); + FWorkerFinished := False; + End + Else + Exit; + End; + + If Not FStateLoaded Then + Begin + LoadState; + FStateLoaded := True; + End; + + State(fsStarting); + FWorkerFinished := False; + FThread := TRESTDWFCMWorker.Create(Self); + + {$IFDEF FPC} + FThread.Start; + {$ELSE} + {$IFDEF DELPHI2010UP} + FThread.Start; + {$ELSE} + FThread.Resume; + {$ENDIF} + {$ENDIF} +End; + +Procedure TRESTDWFirebaseCloudMessaging.Stop; +Var + LMCS : TRESTDWMCSClient; +Begin + If Assigned(FThread) Then + FThread.Terminate; + + FMCSLock.Acquire; + Try + If Assigned(FMCS) Then + Begin + LMCS := TRESTDWMCSClient(FMCS); + LMCS.Stop; + End + Else + If Assigned(FMCSStream) Then + FMCSStream.Disconnect; + Finally + FMCSLock.Release; + End; + + If FInReceiveCallback Then + Exit; + + If Assigned(FThread) Then + Begin + FThread.WaitFor; + FreeAndNil(FThread); + FWorkerFinished := False; + End; + + State(fsStopped); +End; + +Procedure TRESTDWFirebaseCloudMessaging.LoadGoogleServices(Const AFileName : String); +Var + LFile : TStringList; + LJSON : String; + LValue : String; +Begin + If Not FileExists(AFileName) Then + Raise Exception.Create('google-services.json nao encontrado'); + + LFile := TStringList.Create; + Try + LFile.LoadFromFile(AFileName); + LJSON := LFile.Text; + Finally + LFile.Free; + End; + + LValue := RESTDWFCMJSONValue(LJSON, 'project_id'); + If LValue <> '' Then + FProjectID := LValue; + + LValue := RESTDWFCMJSONValue(LJSON, 'mobilesdk_app_id'); + If LValue <> '' Then + FAppID := LValue; + + LValue := RESTDWFCMJSONValue(LJSON, 'current_key'); + If LValue <> '' Then + FAPIKey := LValue; + + If FProjectID = '' Then + Raise Exception.Create('project_id ausente no google-services.json'); + + If FAppID = '' Then + Raise Exception.Create('mobilesdk_app_id ausente no google-services.json'); + + If FAPIKey = '' Then + Raise Exception.Create('current_key ausente no google-services.json'); +End; + +Procedure TRESTDWFirebaseCloudMessaging.LoadServiceAccountConfig(Const AFileName : String); +Var + LFile : TStringList; + LJSON : String; + LValue : String; +Begin + If Not FileExists(AFileName) Then + Raise Exception.Create('Arquivo de conta de servico nao encontrado'); + + LFile := TStringList.Create; + Try + LFile.LoadFromFile(AFileName); + LJSON := LFile.Text; + Finally + LFile.Free; + End; + + LValue := RESTDWFCMJSONValue(LJSON, 'project_id'); + If LValue <> '' Then + FProjectID := LValue; + + FClientEmail := + RESTDWFCMJSONValue( + LJSON, + 'client_email' + ); + + FPrivateKey := + RESTDWFCMJSONValue( + LJSON, + 'private_key' + ); + + If FClientEmail = '' Then + Raise Exception.Create('client_email ausente na conta de servico'); + + If FPrivateKey = '' Then + Raise Exception.Create('private_key ausente na conta de servico'); +End; + +Procedure TRESTDWFirebaseCloudMessaging.LoadServiceAccount(Const AFileName : String); +Begin + LoadServiceAccountConfig(AFileName); +End; + +Procedure TRESTDWFirebaseCloudMessaging.RefreshToken; +Begin + Stop; + + FCredentials.FCMToken := ''; + FCredentials.PushSubscriptionID := ''; + FCredentials.PushEndpoint := ''; + FToken := ''; + + SaveState; + Start; +End; + +Function TRESTDWFirebaseCloudMessaging.SendTarget(Const ATargetName, + ATargetValue : String; + AMessage : TRESTDWFCMMessage) : Boolean; +Var + LOAuth : TRESTDWFCMOAuth; + LHeaders : TStringList; + LBody, + LResponse, + LError : TRESTDWFCMUTF8Stream; + LToken, + LURL : String; + LTry, + LDelay : Integer; + LNotifyError : String; +Begin + EnsureOpenSSL; + + Result := False; + LNotifyError := ''; + + If AMessage = Nil Then + Begin + FLastError := 'Message is nil'; + Exit; + End; + + If ATargetValue = '' Then + Begin + FLastError := ATargetName + ' is empty'; + Exit; + End; + + If FProjectID = '' Then + Raise Exception.Create('ProjectID nao configurado'); + + If FClientEmail = '' Then + Raise Exception.Create('ClientEmail nao configurado'); + + If FPrivateKey = '' Then + Raise Exception.Create('PrivateKey nao configurada'); + + FSendLock.Acquire; + Try + FLastRequest := ''; + FLastResponse := ''; + FLastError := ''; + FResponseCode := 0; + + If FSendHTTP = Nil Then + FSendHTTP := CreateHTTPTransport( + FConnection.ConnectTimeout, + FConnection.ReadTimeout + ); + + If FSendHTTP = Nil Then + Raise Exception.Create('Motor HTTP FCM nao disponivel'); + + FSendHTTP.ConfigureTLS( + Not FConnection.TLSAllowInsecure, + FConnection.TLSCAFile, + FConnection.TLSCAPath + ); + + If FSendOAuth = Nil Then + FSendOAuth := TRESTDWFCMOAuth.Create(FSendHTTP); + + LOAuth := TRESTDWFCMOAuth(FSendOAuth); + LOAuth.HTTPTransport := FSendHTTP; + + LToken := + LOAuth.AccessToken( + FClientEmail, + FPrivateKey + ); + + LURL := + 'https://fcm.googleapis.com/v1/projects/' + + FProjectID + + '/messages:send'; + + FLastRequest := + RESTDWFCMMessageToJSONTarget( + ATargetName, + ATargetValue, + AMessage, + False + ); + + LHeaders := TStringList.Create; + LBody := TRESTDWFCMUTF8Stream.Create(FLastRequest); + LResponse := TRESTDWFCMUTF8Stream.Create(''); + LError := TRESTDWFCMUTF8Stream.Create(''); + Try + LHeaders.Values['Authorization'] := 'Bearer ' + LToken; + LHeaders.Values['Content-Type'] := 'application/json; charset=utf-8'; + LHeaders.Values['Accept'] := 'application/json'; + + For LTry := 0 To 3 Do + Begin + LBody.Position := 0; + LResponse.Size := 0; + LError.Size := 0; + + FResponseCode := + FSendHTTP.Post( + LURL, + LHeaders, + LBody, + LResponse, + LError + ); + + If (FResponseCode <> 429) And + (FResponseCode <> 500) And + (FResponseCode <> 502) And + (FResponseCode <> 503) And + (FResponseCode <> 504) Then + Break; + + If LTry < 3 Then + Begin + LDelay := 1000 Shl LTry; + RESTDWFCMSleep(LDelay); + End; + End; + + If LResponse.Size > 0 Then + FLastResponse := LResponse.AsString + Else + FLastResponse := LError.AsString; + + Result := + (FResponseCode >= 200) And + (FResponseCode < 300); + + If Not Result Then + Begin + FLastError := + 'FCM HTTP ' + + IntToStr(FResponseCode) + + ': ' + + FLastResponse; + + LNotifyError := FLastError; + End; + Finally + LError.Free; + LResponse.Free; + LBody.Free; + LHeaders.Free; + End; + Finally + FSendLock.Release; + End; + + If LNotifyError <> '' Then + Error( + 'Send', + LNotifyError + ); +End; + +Function TRESTDWFirebaseCloudMessaging.Send(Const ADeviceToken : String; + AMessage : TRESTDWFCMMessage) : Boolean; +Begin + Result := SendTarget( + 'token', + ADeviceToken, + AMessage + ); +End; + +Function TRESTDWFirebaseCloudMessaging.SendTopic(Const ATopic : String; + AMessage : TRESTDWFCMMessage) : Boolean; +Var + LTopic : String; +Begin + LTopic := ATopic; + + If Pos('/topics/', LTopic) = 1 Then + Delete(LTopic, 1, Length('/topics/')); + + Result := SendTarget( + 'topic', + LTopic, + AMessage + ); +End; + +Function TRESTDWFirebaseCloudMessaging.SendCondition(Const ACondition : String; + AMessage : TRESTDWFCMMessage) : Boolean; +Begin + Result := SendTarget( + 'condition', + ACondition, + AMessage + ); +End; + +End. From c28fcf16e9053ba6648024d532a03c0669cbbef1 Mon Sep 17 00:00:00 2001 From: Roniery Santos Cardoso Date: Tue, 8 Sep 2026 22:00:27 -0300 Subject: [PATCH 06/22] feat(fcm): transporte FCM por client (Ics/Indy/HttpDef/Fphttp) e SSL/TAURUS_TLS Implementa o transporte de Firebase Cloud Messaging para cada biblioteca de socket (Ics, Indy, HttpDef, Fphttp) e ajusta as bases desses clients com as correcoes de SSL/TAURUS_TLS para uso em Android/iOS/Windows. refs r4013-r4014, r4017, r4024, r4026, r4033, r4036, r4043 --- CORE/Source/Sockets/Docs/FCM_ARCHITECTURE.md | 60 +++ .../Fphttp/uRESTDWFpHttpFCMTransport.pas | 172 +++++++++ .../uRESTDWFpHttpFirebaseCloudMessaging.pas | 34 ++ .../Sockets/Fphttp/uRESTDWFphttpBase.pas | 14 +- .../Sockets/Fphttp/uRESTDWFphttpReg.pas | 14 +- .../Sockets/HttpDef/uRESTDWHttpDefBase.pas | 14 +- .../HttpDef/uRESTDWHttpDefFCMTransport.pas | 172 +++++++++ .../uRESTDWHttpDefFirebaseCloudMessaging.pas | 34 ++ .../Sockets/HttpDef/uRESTDWHttpDefReg.pas | 14 +- CORE/Source/Sockets/Ics/uRESTDWIcsBase.pas | 12 +- .../Sockets/Ics/uRESTDWIcsFCMTransport.pas | 227 +++++++++++ .../Ics/uRESTDWIcsFirebaseCloudMessaging.pas | 34 ++ CORE/Source/Sockets/Ics/uRESTDWIcsReg.pas | 14 +- CORE/Source/Sockets/Indy/uRESTDWIdBase.pas | 279 ++++++++++---- .../Sockets/Indy/uRESTDWIdFCMTransport.pas | 354 ++++++++++++++++++ .../Indy/uRESTDWIdFirebaseCloudMessaging.pas | 34 ++ CORE/Source/Sockets/Indy/uRESTDWIdReg.dcr | Bin 0 -> 2796 bytes CORE/Source/Sockets/Indy/uRESTDWIdReg.pas | 18 +- 18 files changed, 1384 insertions(+), 116 deletions(-) create mode 100644 CORE/Source/Sockets/Docs/FCM_ARCHITECTURE.md create mode 100644 CORE/Source/Sockets/Fphttp/uRESTDWFpHttpFCMTransport.pas create mode 100644 CORE/Source/Sockets/Fphttp/uRESTDWFpHttpFirebaseCloudMessaging.pas create mode 100644 CORE/Source/Sockets/HttpDef/uRESTDWHttpDefFCMTransport.pas create mode 100644 CORE/Source/Sockets/HttpDef/uRESTDWHttpDefFirebaseCloudMessaging.pas create mode 100644 CORE/Source/Sockets/Ics/uRESTDWIcsFCMTransport.pas create mode 100644 CORE/Source/Sockets/Ics/uRESTDWIcsFirebaseCloudMessaging.pas create mode 100644 CORE/Source/Sockets/Indy/uRESTDWIdFCMTransport.pas create mode 100644 CORE/Source/Sockets/Indy/uRESTDWIdFirebaseCloudMessaging.pas create mode 100644 CORE/Source/Sockets/Indy/uRESTDWIdReg.dcr diff --git a/CORE/Source/Sockets/Docs/FCM_ARCHITECTURE.md b/CORE/Source/Sockets/Docs/FCM_ARCHITECTURE.md new file mode 100644 index 000000000..744fe9909 --- /dev/null +++ b/CORE/Source/Sockets/Docs/FCM_ARCHITECTURE.md @@ -0,0 +1,60 @@ +# REST Dataware 2.1 - Arquitetura FCM + +## Regra principal + +O Firebase Cloud Messaging do REST Dataware é uma implementação própria do +REST Dataware. + +O CORE não depende de: + +- SDK Firebase/Google; +- PushService; +- WebView; +- navegador; +- API Android; +- API iOS; +- APNS nativo; +- trust store do SysOp; +- certificados fornecidos pelo SysOp; +- serviço/background registrado automaticamente pela plataforma. + +A mesma lógica de protocolo é usada em Desktop e Mobile. + +## Motores + +A disponibilidade do componente é definida pelo motor escolhido. + +O CORE não tenta compensar uma limitação de um motor usando uma API nativa do +SysOp. + +- Indy: disponível onde o motor Indy do REST Dataware estiver suportado. +- ICS: disponível apenas nas plataformas realmente suportadas pelo motor ICS. + Se o motor ICS não suporta Android, o componente ICS não é disponibilizado + para Android. +- FpHTTP: disponível nas plataformas suportadas pelo motor FpHTTP/Lazarus. +- HttpDef: disponível onde o motor HttpDef REST Dataware estiver suportado. +- JClient/LAMW: estrutura instalável; transporte próprio permanece separado + até sua implementação. + +Cada motor negocia tanto envio quanto recebimento. + +## TLS + +Os motores OpenSSL usam o CA bundle `RESTDWRootCA.pem` distribuído pelo REST +Dataware, ou `Connection.TLSCAFile/TLSCAPath` informado pelo programador. + +O FCM não consulta certificados/trust stores do SysOp. + +`TLSAllowInsecure=False` é o padrão seguro. + +## Background e interface + +O componente não registra Service Android/iOS, PushService, Toast ou qualquer +serviço nativo. + +Se o programador precisar execução em background, ele cria o serviço da +aplicação e instancia o componente REST Dataware dentro dele. + +`OnMessage` e demais eventos retransmitem o conteúdo recebido. Uma camada +opcional pode usar esses eventos para exibir Push, Toast ou outra interface, +sem criar dependência no CORE FCM. diff --git a/CORE/Source/Sockets/Fphttp/uRESTDWFpHttpFCMTransport.pas b/CORE/Source/Sockets/Fphttp/uRESTDWFpHttpFCMTransport.pas new file mode 100644 index 000000000..1e2ff9b9d --- /dev/null +++ b/CORE/Source/Sockets/Fphttp/uRESTDWFpHttpFCMTransport.pas @@ -0,0 +1,172 @@ +Unit uRESTDWFpHttpFCMTransport; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + fphttpclient, + ssockets, + sslsockets, + opensslsockets, + uRESTDWFCMTransport, + uRESTDWFCMCompat, + uRESTDWFCMOpenSSLStream; + +Type + TRESTDWFpHttpFCMHTTPTransport = Class(TRESTDWFCMHTTPTransport) + Private + FConnectTimeout : Integer; + FReadTimeout : Integer; + FVerifyPeer : Boolean; + FCAFile : String; + FCAPath : String; + + Procedure GetSocketHandler(Sender : TObject; + Const UseSSL : Boolean; + Out AHandler : TSocketHandler); + Public + Constructor Create(AConnectTimeout, AReadTimeout : Integer); + + Procedure ConfigureTLS(AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); Override; + + Function Post(Const AURL : String; + AHeaders : TStrings; + ABody : TStream; + AResponse : TStream; + AResponseError : TStream) : Integer; Override; + End; + + TRESTDWFpHttpFCMStreamTransport = Class(TRESTDWFCMOpenSSLStreamTransport) + End; + +Implementation + +Procedure TRESTDWFpHttpFCMHTTPTransport.GetSocketHandler(Sender : TObject; + Const UseSSL : Boolean; + Out AHandler : TSocketHandler); +Var + LSSL : TSSLSocketHandler; +Begin + AHandler := Nil; + If Not UseSSL Then + Exit; + LSSL := TSSLSocketHandler.GetDefaultHandler; + LSSL.VerifyPeerCert := FVerifyPeer; + If FCAFile <> '' Then + LSSL.CertificateData.CertCA.FileName := FCAFile; + {$IF FPC_FULLVERSION >= 30301} + If FCAPath <> '' Then + LSSL.CertificateData.TrustedCertsDir := FCAPath; + {$ENDIF} + AHandler := LSSL; +End; + +Constructor TRESTDWFpHttpFCMHTTPTransport.Create(AConnectTimeout, AReadTimeout : Integer); +Begin + Inherited Create; + + FConnectTimeout := AConnectTimeout; + FReadTimeout := AReadTimeout; + FVerifyPeer := True; + FCAFile := ''; + FCAPath := ''; +End; + +Procedure TRESTDWFpHttpFCMHTTPTransport.ConfigureTLS(AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); +Begin + FVerifyPeer := AVerifyPeer; + FCAFile := ACAFile; + FCAPath := ACAPath; +End; + +Function TRESTDWFpHttpFCMHTTPTransport.Post(Const AURL : String; + AHeaders : TStrings; + ABody : TStream; + AResponse : TStream; + AResponseError : TStream) : Integer; +Var + LHTTP : TFPHTTPClient; + I : Integer; +Begin + If AResponse <> Nil Then + Begin + AResponse.Size := 0; + AResponse.Position := 0; + End; + + If AResponseError <> Nil Then + Begin + AResponseError.Size := 0; + AResponseError.Position := 0; + End; + + LHTTP := TFPHTTPClient.Create(Nil); + Try + LHTTP.AllowRedirect := True; + LHTTP.ConnectTimeout := FConnectTimeout; + LHTTP.IOTimeout := FReadTimeout; + + LHTTP.OnGetSocketHandler := {$IFDEF FPC}@{$ENDIF}GetSocketHandler; + + If AHeaders <> Nil Then + For I := 0 To AHeaders.Count - 1 Do + LHTTP.AddHeader(AHeaders.Names[I], + AHeaders.ValueFromIndex[I]); + + If ABody <> Nil Then + Begin + ABody.Position := 0; + LHTTP.RequestBody := ABody; + End; + + Try + LHTTP.Post(AURL, AResponse); + Result := LHTTP.ResponseStatusCode; + Except + On E : Exception Do + Begin + Result := LHTTP.ResponseStatusCode; + + If (Result >= 400) And + (AResponse <> Nil) And + (AResponseError <> Nil) And + (AResponse.Size > 0) Then + Begin + AResponse.Position := 0; + AResponseError.CopyFrom(AResponse, 0); + AResponseError.Position := 0; + AResponse.Size := 0; + End + Else + If (AResponseError <> Nil) And + (E.Message <> '') Then + RESTDWFCMWriteUTF8( + AResponseError, + E.Message + ); + + If Result = 0 Then + Raise; + End; + End; + + If AResponse <> Nil Then + AResponse.Position := 0; + + If AResponseError <> Nil Then + AResponseError.Position := 0; + + Finally + LHTTP.RequestBody := Nil; + LHTTP.Free; + End; +End; + +End. diff --git a/CORE/Source/Sockets/Fphttp/uRESTDWFpHttpFirebaseCloudMessaging.pas b/CORE/Source/Sockets/Fphttp/uRESTDWFpHttpFirebaseCloudMessaging.pas new file mode 100644 index 000000000..aaeb2b42c --- /dev/null +++ b/CORE/Source/Sockets/Fphttp/uRESTDWFpHttpFirebaseCloudMessaging.pas @@ -0,0 +1,34 @@ +Unit uRESTDWFpHttpFirebaseCloudMessaging; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + uRESTDWFirebaseCloudMessaging, + uRESTDWFCMTransport; + +Type + TRESTDWFpHttpFirebaseCloudMessaging = Class(TRESTDWFirebaseCloudMessaging) + Protected + Function CreateHTTPTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMHTTPTransport; Override; + Function CreateMCSStreamTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMStreamTransport; Override; + End; + +Implementation + +Uses + uRESTDWFpHttpFCMTransport; + +Function TRESTDWFpHttpFirebaseCloudMessaging.CreateHTTPTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMHTTPTransport; +Begin + Result := TRESTDWFpHttpFCMHTTPTransport.Create(AConnectTimeout, AReadTimeout); +End; + +Function TRESTDWFpHttpFirebaseCloudMessaging.CreateMCSStreamTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMStreamTransport; +Begin + Result := TRESTDWFpHttpFCMStreamTransport.Create; +End; + +End. diff --git a/CORE/Source/Sockets/Fphttp/uRESTDWFphttpBase.pas b/CORE/Source/Sockets/Fphttp/uRESTDWFphttpBase.pas index 9b1930517..2481d4be5 100644 --- a/CORE/Source/Sockets/Fphttp/uRESTDWFphttpBase.pas +++ b/CORE/Source/Sockets/Fphttp/uRESTDWFphttpBase.pas @@ -1,22 +1,22 @@ unit uRESTDWFphttpBase; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. A. Brito - Admin - Administrador do desenvolvimento. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -453,7 +453,7 @@ procedure TRESTDWFphttpServicePooler.ExecRequest( if Assigned(ResultStream) then begin AResponse.ContentStream := ResultStream; - AResponse.SendContent; //SendContent é necessário para devolver o conteúdo + AResponse.SendContent; //SendContent necessrio para devolver o contedo AResponse.ContentStream := nil; AResponse.ContentLength := ResultStream.Size; end; @@ -470,7 +470,7 @@ procedure TRESTDWFphttpServicePooler.ExecRequest( if Assigned(ResultStream) then begin AResponse.ContentStream := ResultStream; - AResponse.SendContent; //SendContent é necessário para devolver o conteúdo + AResponse.SendContent; //SendContent necessrio para devolver o contedo AResponse.ContentStream := nil; AResponse.ContentLength := ResultStream.Size; end; diff --git a/CORE/Source/Sockets/Fphttp/uRESTDWFphttpReg.pas b/CORE/Source/Sockets/Fphttp/uRESTDWFphttpReg.pas index 2dde9fcb4..f1344c4ee 100644 --- a/CORE/Source/Sockets/Fphttp/uRESTDWFphttpReg.pas +++ b/CORE/Source/Sockets/Fphttp/uRESTDWFphttpReg.pas @@ -1,21 +1,21 @@ unit uRESTDWFphttpReg; -{$I ..\..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. A. Brito - Admin - Administrador do desenvolvimento. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -25,7 +25,7 @@ interface uses - Classes, PropEdits, uRESTDWFphttpBase, LResources; + Classes, PropEdits, uRESTDWFphttpBase, uRESTDWFpHttpFirebaseCloudMessaging, LResources; Type TPoolersList = Class(TStringProperty) @@ -76,6 +76,8 @@ procedure TPoolersList.GetValues(Proc: TGetStrProc); Procedure Register; Begin + + RegisterComponents('REST Dataware - Client', [TRESTDWFpHttpFirebaseCloudMessaging]); RegisterComponents('REST Dataware - Service', [TRESTDWfpHttpServicePooler]); End; diff --git a/CORE/Source/Sockets/HttpDef/uRESTDWHttpDefBase.pas b/CORE/Source/Sockets/HttpDef/uRESTDWHttpDefBase.pas index e8be233b5..7a97570e0 100644 --- a/CORE/Source/Sockets/HttpDef/uRESTDWHttpDefBase.pas +++ b/CORE/Source/Sockets/HttpDef/uRESTDWHttpDefBase.pas @@ -1,22 +1,22 @@ unit uRESTDWHttpDefBase; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. A. Brito - Admin - Administrador do desenvolvimento. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -441,7 +441,7 @@ procedure TRESTDWHttpDefServicePooler.ExecRequest( if Assigned(ResultStream) then begin AResponse.ContentStream := ResultStream; - AResponse.SendContent; //SendContent é necessário para devolver o conteúdo + AResponse.SendContent; //SendContent necessrio para devolver o contedo AResponse.ContentStream := nil; AResponse.ContentLength := ResultStream.Size; end; @@ -458,7 +458,7 @@ procedure TRESTDWHttpDefServicePooler.ExecRequest( if Assigned(ResultStream) then begin AResponse.ContentStream := ResultStream; - AResponse.SendContent; //SendContent é necessário para devolver o conteúdo + AResponse.SendContent; //SendContent necessrio para devolver o contedo AResponse.ContentStream := nil; AResponse.ContentLength := ResultStream.Size; end; diff --git a/CORE/Source/Sockets/HttpDef/uRESTDWHttpDefFCMTransport.pas b/CORE/Source/Sockets/HttpDef/uRESTDWHttpDefFCMTransport.pas new file mode 100644 index 000000000..ed560d75f --- /dev/null +++ b/CORE/Source/Sockets/HttpDef/uRESTDWHttpDefFCMTransport.pas @@ -0,0 +1,172 @@ +Unit uRESTDWHttpDefFCMTransport; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + fphttpclient, + ssockets, + sslsockets, + opensslsockets, + uRESTDWFCMTransport, + uRESTDWFCMCompat, + uRESTDWFCMOpenSSLStream; + +Type + TRESTDWHttpDefFCMHTTPTransport = Class(TRESTDWFCMHTTPTransport) + Private + FConnectTimeout : Integer; + FReadTimeout : Integer; + FVerifyPeer : Boolean; + FCAFile : String; + FCAPath : String; + + Procedure GetSocketHandler(Sender : TObject; + Const UseSSL : Boolean; + Out AHandler : TSocketHandler); + Public + Constructor Create(AConnectTimeout, AReadTimeout : Integer); + + Procedure ConfigureTLS(AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); Override; + + Function Post(Const AURL : String; + AHeaders : TStrings; + ABody : TStream; + AResponse : TStream; + AResponseError : TStream) : Integer; Override; + End; + + TRESTDWHttpDefFCMStreamTransport = Class(TRESTDWFCMOpenSSLStreamTransport) + End; + +Implementation + +Procedure TRESTDWHttpDefFCMHTTPTransport.GetSocketHandler(Sender : TObject; + Const UseSSL : Boolean; + Out AHandler : TSocketHandler); +Var + LSSL : TSSLSocketHandler; +Begin + AHandler := Nil; + If Not UseSSL Then + Exit; + LSSL := TSSLSocketHandler.GetDefaultHandler; + LSSL.VerifyPeerCert := FVerifyPeer; + If FCAFile <> '' Then + LSSL.CertificateData.CertCA.FileName := FCAFile; + {$IF FPC_FULLVERSION >= 30301} + If FCAPath <> '' Then + LSSL.CertificateData.TrustedCertsDir := FCAPath; + {$ENDIF} + AHandler := LSSL; +End; + +Constructor TRESTDWHttpDefFCMHTTPTransport.Create(AConnectTimeout, AReadTimeout : Integer); +Begin + Inherited Create; + + FConnectTimeout := AConnectTimeout; + FReadTimeout := AReadTimeout; + FVerifyPeer := True; + FCAFile := ''; + FCAPath := ''; +End; + +Procedure TRESTDWHttpDefFCMHTTPTransport.ConfigureTLS(AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); +Begin + FVerifyPeer := AVerifyPeer; + FCAFile := ACAFile; + FCAPath := ACAPath; +End; + +Function TRESTDWHttpDefFCMHTTPTransport.Post(Const AURL : String; + AHeaders : TStrings; + ABody : TStream; + AResponse : TStream; + AResponseError : TStream) : Integer; +Var + LHTTP : TFPHTTPClient; + I : Integer; +Begin + If AResponse <> Nil Then + Begin + AResponse.Size := 0; + AResponse.Position := 0; + End; + + If AResponseError <> Nil Then + Begin + AResponseError.Size := 0; + AResponseError.Position := 0; + End; + + LHTTP := TFPHTTPClient.Create(Nil); + Try + LHTTP.AllowRedirect := True; + LHTTP.ConnectTimeout := FConnectTimeout; + LHTTP.IOTimeout := FReadTimeout; + + LHTTP.OnGetSocketHandler := {$IFDEF FPC}@{$ENDIF}GetSocketHandler; + + If AHeaders <> Nil Then + For I := 0 To AHeaders.Count - 1 Do + LHTTP.AddHeader(AHeaders.Names[I], + AHeaders.ValueFromIndex[I]); + + If ABody <> Nil Then + Begin + ABody.Position := 0; + LHTTP.RequestBody := ABody; + End; + + Try + LHTTP.Post(AURL, AResponse); + Result := LHTTP.ResponseStatusCode; + Except + On E : Exception Do + Begin + Result := LHTTP.ResponseStatusCode; + + If (Result >= 400) And + (AResponse <> Nil) And + (AResponseError <> Nil) And + (AResponse.Size > 0) Then + Begin + AResponse.Position := 0; + AResponseError.CopyFrom(AResponse, 0); + AResponseError.Position := 0; + AResponse.Size := 0; + End + Else + If (AResponseError <> Nil) And + (E.Message <> '') Then + RESTDWFCMWriteUTF8( + AResponseError, + E.Message + ); + + If Result = 0 Then + Raise; + End; + End; + + If AResponse <> Nil Then + AResponse.Position := 0; + + If AResponseError <> Nil Then + AResponseError.Position := 0; + + Finally + LHTTP.RequestBody := Nil; + LHTTP.Free; + End; +End; + +End. diff --git a/CORE/Source/Sockets/HttpDef/uRESTDWHttpDefFirebaseCloudMessaging.pas b/CORE/Source/Sockets/HttpDef/uRESTDWHttpDefFirebaseCloudMessaging.pas new file mode 100644 index 000000000..b1ae0dda7 --- /dev/null +++ b/CORE/Source/Sockets/HttpDef/uRESTDWHttpDefFirebaseCloudMessaging.pas @@ -0,0 +1,34 @@ +Unit uRESTDWHttpDefFirebaseCloudMessaging; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + uRESTDWFirebaseCloudMessaging, + uRESTDWFCMTransport; + +Type + TRESTDWHttpDefFirebaseCloudMessaging = Class(TRESTDWFirebaseCloudMessaging) + Protected + Function CreateHTTPTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMHTTPTransport; Override; + Function CreateMCSStreamTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMStreamTransport; Override; + End; + +Implementation + +Uses + uRESTDWHttpDefFCMTransport; + +Function TRESTDWHttpDefFirebaseCloudMessaging.CreateHTTPTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMHTTPTransport; +Begin + Result := TRESTDWHttpDefFCMHTTPTransport.Create(AConnectTimeout, AReadTimeout); +End; + +Function TRESTDWHttpDefFirebaseCloudMessaging.CreateMCSStreamTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMStreamTransport; +Begin + Result := TRESTDWHttpDefFCMStreamTransport.Create; +End; + +End. diff --git a/CORE/Source/Sockets/HttpDef/uRESTDWHttpDefReg.pas b/CORE/Source/Sockets/HttpDef/uRESTDWHttpDefReg.pas index b86e07a02..932c41a4e 100644 --- a/CORE/Source/Sockets/HttpDef/uRESTDWHttpDefReg.pas +++ b/CORE/Source/Sockets/HttpDef/uRESTDWHttpDefReg.pas @@ -1,21 +1,21 @@ unit uRESTDWHttpDefReg; -{$I ..\..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. A. Brito - Admin - Administrador do desenvolvimento. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -25,7 +25,7 @@ interface uses - Classes, PropEdits, uRESTDWHttpDefBase, LResources; + Classes, PropEdits, uRESTDWHttpDefBase, uRESTDWHttpDefFirebaseCloudMessaging, LResources; Type TPoolersList = Class(TStringProperty) @@ -76,6 +76,8 @@ procedure TPoolersList.GetValues(Proc: TGetStrProc); Procedure Register; Begin + + RegisterComponents('REST Dataware - Client', [TRESTDWHttpDefFirebaseCloudMessaging]); RegisterComponents('REST Dataware - Service', [TRESTDWHttpDefServicePooler]); End; diff --git a/CORE/Source/Sockets/Ics/uRESTDWIcsBase.pas b/CORE/Source/Sockets/Ics/uRESTDWIcsBase.pas index 7ceac58da..001e91a3c 100644 --- a/CORE/Source/Sockets/Ics/uRESTDWIcsBase.pas +++ b/CORE/Source/Sockets/Ics/uRESTDWIcsBase.pas @@ -1,21 +1,21 @@ unit uRESTDWIcsBase; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. A. Brito - Admin - Administrador do desenvolvimento. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -26,7 +26,7 @@ // Inserir outras propriedades do SSL no Pooler (SetHttpServerSSL); // TODO 1 -// Passar parâmetros do diretório, página e url padrão (SetParamsHttpConnection); +// Passar parmetros do diretrio, pgina e url padro (SetParamsHttpConnection); interface diff --git a/CORE/Source/Sockets/Ics/uRESTDWIcsFCMTransport.pas b/CORE/Source/Sockets/Ics/uRESTDWIcsFCMTransport.pas new file mode 100644 index 000000000..0d0fffb0a --- /dev/null +++ b/CORE/Source/Sockets/Ics/uRESTDWIcsFCMTransport.pas @@ -0,0 +1,227 @@ +Unit uRESTDWIcsFCMTransport; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + OverbyteIcsHttpProt, + OverbyteIcsSslBase, + OverbyteIcsSslX509Utils, + OverbyteIcsSSLEAY, + uRESTDWFCMTransport, + uRESTDWFCMCompat, + uRESTDWFCMOpenSSLStream; + +Type + TRESTDWIcsFCMHTTPTransport = Class(TRESTDWFCMHTTPTransport) + Private + FHTTP : TSslHttpCli; + FSSL : TSslContext; + FHeaders : TStringList; + + Procedure BeforeHeaderSend(Sender : TObject; + Const AMethod : String; + AHeaders : TStrings); + Public + Constructor Create(AConnectTimeout, AReadTimeout : Integer); + Destructor Destroy; Override; + + Procedure ConfigureTLS(AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); Override; + + Function Post(Const AURL : String; + AHeaders : TStrings; + ABody : TStream; + AResponse : TStream; + AResponseError : TStream) : Integer; Override; + End; + + TRESTDWIcsFCMStreamTransport = Class(TRESTDWFCMOpenSSLStreamTransport) + End; + +Implementation + +Constructor TRESTDWIcsFCMHTTPTransport.Create(AConnectTimeout, AReadTimeout : Integer); +Begin + Inherited Create; + + FHeaders := TStringList.Create; + FHTTP := TSslHttpCli.Create(Nil); + FSSL := TSslContext.Create(Nil); + + FHTTP.MultiThreaded := True; + FHTTP.SslContext := FSSL; + FHTTP.FollowRelocation := True; + FHTTP.Connection := 'close'; + FHTTP.RequestVer := '1.1'; + If AReadTimeout > 0 Then + FHTTP.Timeout := (AReadTimeout + 999) Div 1000 + Else + FHTTP.Timeout := 0; + FHTTP.OnBeforeHeaderSend := BeforeHeaderSend; + + FSSL.SslVerifyPeer := True; + FSSL.SslMinVersion := sslVerTLS1_2; + FSSL.SslMaxVersion := sslVerMax; + + If (FSSL.SslCAFile = '') And + (FSSL.SslCAPath = '') And + (FSSL.SslCALines.Count = 0) Then + FSSL.SslCALines.Text := sslRootCACertsBundle; + +End; + +Procedure TRESTDWIcsFCMHTTPTransport.ConfigureTLS(AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); +Begin + FSSL.SslVerifyPeer := AVerifyPeer; + + If ACAFile <> '' Then + Begin + FSSL.SslCAFile := ACAFile; + FSSL.SslCALines.Clear; + End; + + If ACAPath <> '' Then + FSSL.SslCAPath := ACAPath; + + If AVerifyPeer And + (ACAFile = '') And + (ACAPath = '') And + (FSSL.SslCAFile = '') And + (FSSL.SslCAPath = '') And + (FSSL.SslCALines.Count = 0) Then + FSSL.SslCALines.Text := sslRootCACertsBundle; + + FSSL.InitContext; +End; + +Destructor TRESTDWIcsFCMHTTPTransport.Destroy; +Begin + FHTTP.OnBeforeHeaderSend := Nil; + FHTTP.SslContext := Nil; + + FHTTP.Free; + FSSL.Free; + FHeaders.Free; + + Inherited Destroy; +End; + +Procedure TRESTDWIcsFCMHTTPTransport.BeforeHeaderSend(Sender : TObject; + Const AMethod : String; + AHeaders : TStrings); +Var + I : Integer; +Begin + For I := 0 To FHeaders.Count - 1 Do + If (FHeaders.Names[I] <> '') And + (Not SameText(FHeaders.Names[I], 'Content-Type')) And + (Not SameText(FHeaders.Names[I], 'Accept')) And + (Not SameText(FHeaders.Names[I], 'Content-Length')) And + (Not SameText(FHeaders.Names[I], 'Host')) Then + AHeaders.Add( + FHeaders.Names[I] + ': ' + + FHeaders.ValueFromIndex[I] + ); +End; + +Function TRESTDWIcsFCMHTTPTransport.Post(Const AURL : String; + AHeaders : TStrings; + ABody : TStream; + AResponse : TStream; + AResponseError : TStream) : Integer; +Var + I : Integer; + LContentType : String; + LAccept : String; +Begin + Result := 0; + + If AResponse <> Nil Then + Begin + AResponse.Size := 0; + AResponse.Position := 0; + End; + + If AResponseError <> Nil Then + Begin + AResponseError.Size := 0; + AResponseError.Position := 0; + End; + + FHeaders.Clear; + + If AHeaders <> Nil Then + FHeaders.Assign(AHeaders); + + LContentType := ''; + LAccept := ''; + + For I := 0 To FHeaders.Count - 1 Do + Begin + If SameText(FHeaders.Names[I], 'Content-Type') Then + LContentType := FHeaders.ValueFromIndex[I] + Else + If SameText(FHeaders.Names[I], 'Accept') Then + LAccept := FHeaders.ValueFromIndex[I]; + End; + + FHTTP.URL := AURL; + FHTTP.ContentTypePost := LContentType; + FHTTP.Accept := LAccept; + FHTTP.SendStream := ABody; + FHTTP.RcvdStream := AResponse; + + If ABody <> Nil Then + ABody.Position := 0; + + Try + Try + FHTTP.Post; + Result := FHTTP.StatusCode; + Except + On E : Exception Do + Begin + Result := FHTTP.StatusCode; + + If (AResponseError <> Nil) And + (E.Message <> '') Then + RESTDWFCMWriteUTF8( + AResponseError, + E.Message + ); + + If Result = 0 Then + Raise; + End; + End; + + If (Result >= 400) And + (AResponse <> Nil) And + (AResponseError <> Nil) And + (AResponse.Size > 0) Then + Begin + AResponse.Position := 0; + AResponseError.CopyFrom(AResponse, 0); + AResponseError.Position := 0; + AResponse.Size := 0; + End; + Finally + FHTTP.SendStream := Nil; + FHTTP.RcvdStream := Nil; + + If AResponse <> Nil Then + AResponse.Position := 0; + + If AResponseError <> Nil Then + AResponseError.Position := 0; + End; +End; + +End. diff --git a/CORE/Source/Sockets/Ics/uRESTDWIcsFirebaseCloudMessaging.pas b/CORE/Source/Sockets/Ics/uRESTDWIcsFirebaseCloudMessaging.pas new file mode 100644 index 000000000..86755bb8f --- /dev/null +++ b/CORE/Source/Sockets/Ics/uRESTDWIcsFirebaseCloudMessaging.pas @@ -0,0 +1,34 @@ +Unit uRESTDWIcsFirebaseCloudMessaging; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + uRESTDWFirebaseCloudMessaging, + uRESTDWFCMTransport; + +Type + TRESTDWIcsFirebaseCloudMessaging = Class(TRESTDWFirebaseCloudMessaging) + Protected + Function CreateHTTPTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMHTTPTransport; Override; + Function CreateMCSStreamTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMStreamTransport; Override; + End; + +Implementation + +Uses + uRESTDWIcsFCMTransport; + +Function TRESTDWIcsFirebaseCloudMessaging.CreateHTTPTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMHTTPTransport; +Begin + Result := TRESTDWIcsFCMHTTPTransport.Create(AConnectTimeout, AReadTimeout); +End; + +Function TRESTDWIcsFirebaseCloudMessaging.CreateMCSStreamTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMStreamTransport; +Begin + Result := TRESTDWIcsFCMStreamTransport.Create; +End; + +End. diff --git a/CORE/Source/Sockets/Ics/uRESTDWIcsReg.pas b/CORE/Source/Sockets/Ics/uRESTDWIcsReg.pas index 957da1d34..beebbccda 100644 --- a/CORE/Source/Sockets/Ics/uRESTDWIcsReg.pas +++ b/CORE/Source/Sockets/Ics/uRESTDWIcsReg.pas @@ -1,21 +1,21 @@ unit uRESTDWIcsReg; -{$I ..\..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. A. Brito - Admin - Administrador do desenvolvimento. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -26,7 +26,7 @@ interface uses Classes, DesignIntf, DesignEditors, - uRESTDWIcsBase; + uRESTDWIcsBase, uRESTDWIcsFirebaseCloudMessaging; Type TPoolersList = Class(TStringProperty) @@ -77,6 +77,8 @@ procedure TPoolersList.GetValues(Proc: TGetStrProc); Procedure Register; Begin + + RegisterComponents('REST Dataware - Client', [TRESTDWIcsFirebaseCloudMessaging]); RegisterComponents('REST Dataware - Service', [TRESTDWIcsServicePooler]); End; diff --git a/CORE/Source/Sockets/Indy/uRESTDWIdBase.pas b/CORE/Source/Sockets/Indy/uRESTDWIdBase.pas index 4f7a68248..a1eba3926 100644 --- a/CORE/Source/Sockets/Indy/uRESTDWIdBase.pas +++ b/CORE/Source/Sockets/Indy/uRESTDWIdBase.pas @@ -1,6 +1,6 @@ unit uRESTDWIdBase; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . @@ -119,6 +119,7 @@ interface {$IFDEF USE_TAURUS_TLS} vUseTaurus : Boolean; {$ENDIF} +// ThreadMgrPool : TIdSchedulerOfThreadPool; vCipherList, vaSSLRootCertFile, ASSLPrivateKeyFile, @@ -296,8 +297,8 @@ interface {$ENDIF} ssl : TComponent;//TIdSSLIOHandlerSocketOpenSSL; vSSLVersions : TRESTDWSSLVersions; - vCertMode : TRESTDWSSLMode; aSSLMethod : TRESTDWSSLVersion; + vSSLMode : TRESTDWSSLMode; Function GetSSlVersion : Pointer; Function GetSSlMode : Pointer; Function GetSSlVersions : Pointer; @@ -324,7 +325,7 @@ interface Const AStatusText : String); Procedure SetOnStatus (Value : TOnStatus); Override; Procedure DestroyClient;Override; - Procedure SetCertOptions; + Procedure SetCertOptions (Var assl : TComponent); Procedure Getpassword (Var Password : String); Function GetVerifyCert : Boolean; Procedure SetVerifyCert (aValue : Boolean); @@ -464,9 +465,9 @@ interface Property UseTaurus : Boolean Read vUseTaurus Write vUseTaurus; {$ENDIF} Property VerifyCert : Boolean Read GetVerifyCert Write SetVerifyCert; + Property SSLMode : TRESTDWSSLMode Read vSSLMode Write vSSLMode; Property SSLMethod : TRESTDWSSLVersion Read aSSLMethod Write aSSLMethod; Property SSLVersions : TRESTDWSSLVersions Read vSSLVersions Write vSSLVersions; - Property CertMode : TRESTDWSSLMode Read vCertMode Write vCertMode; Property CertFile : String Read vCertFile Write vCertFile; Property KeyFile : String Read vKeyFile Write vKeyFile; Property RootCertFile : String Read vRootCertFile Write vRootCertFile; @@ -511,10 +512,11 @@ interface ASSLPrivateKeyPassword, ASSLCertFile : String; HttpRequest : TRESTDWIdClientREST; + vSSLMode : TRESTDWSSLMode; aSSLMethod : TRESTDWSSLVersion; vSSLVersions : TRESTDWSSLVersions; - Function GetSSlVersion : Integer; - Function GetSSlMode : Integer; + Function GetSSlVersion : Pointer; + Function GetSSlMode : Pointer; Function GetSSlVersions : TRESTDWVersionsBase; Function SendEvent (EventData : String; Var Params : TRESTDWParams; @@ -548,6 +550,7 @@ interface Property SSLPrivateKeyPassword : String Read aSSLPrivateKeyPassword Write aSSLPrivateKeyPassword; Property SSLCertFile : String Read aSSLCertFile Write aSSLCertFile; Property SSLRootCertFile : String Read vaSSLRootCertFile Write vaSSLRootCertFile; + Property SSLMode : TRESTDWSSLMode Read vSSLMode Write vSSLMode; Property SSLMethod : TRESTDWSSLVersion Read aSSLMethod Write aSSLMethod; Property SSLVersions : TRESTDWSSLVersions Read vSSLVersions Write vSSLVersions; End; @@ -2980,45 +2983,45 @@ TIdHTTPAccess = class(TIdHTTP) aTaurSSLMode : TTaurusTLSSSLMode; {$ELSE} Var - SSLMode : TRESTDWSSLMode; + bSSLMode : TRESTDWSSLMode; {$ENDIF} Begin Result := Nil; {$IFDEF USE_TAURUS_TLS} If vUseTaurus Then Begin - If vCertMode = sslUnassigned Then + If vSSLMode = sslUnassigned Then aTaurSSLMode := TTaurusTLSSSLMode(sslmUnassigned) - Else If vCertMode = sslClient Then + Else If vSSLMode = sslClient Then aTaurSSLMode := TTaurusTLSSSLMode(sslmClient) - Else If vCertMode = sslServer Then + Else If vSSLMode = sslServer Then aTaurSSLMode := TTaurusTLSSSLMode(sslmServer) - Else If vCertMode = sslBoth Then + Else If vSSLMode = sslBoth Then aTaurSSLMode := TTaurusTLSSSLMode(sslmBoth); Result := @aTaurSSLMode; End Else Begin - If vCertMode = sslUnassigned Then + If vSSLMode = sslUnassigned Then bSSLMode := sslmUnassigned - Else If vCertMode = sslClient Then + Else If vSSLMode = sslClient Then bSSLMode := sslmClient - Else If vCertMode = sslServer Then + Else If vSSLMode = sslServer Then bSSLMode := sslmServer - Else If vCertMode = sslBoth Then + Else If vSSLMode = sslBoth Then bSSLMode := sslmBoth; Result := @bSSLMode; End; {$ELSE} - If vCertMode = sslUnassigned Then - SSLMode := sslUnassigned - Else If vCertMode = sslClient Then - SSLMode := sslClient - Else If vCertMode = sslServer Then - SSLMode := sslServer - Else If vCertMode = sslBoth Then - SSLMode := sslBoth; - Result := @SSLMode; + If vSSLMode = sslUnassigned Then + bSSLMode := sslUnassigned + Else If vSSLMode = sslClient Then + bSSLMode := sslClient + Else If vSSLMode = sslServer Then + bSSLMode := sslServer + Else If vSSLMode = sslBoth Then + bSSLMode := sslBoth; + Result := @bSSLMode; {$ENDIF} End; @@ -3160,11 +3163,11 @@ TIdHTTPAccess = class(TIdHTTP) vVerifyCert := aValue; End; -Procedure TRESTDWIdClientREST.SetCertOptions; +Procedure TRESTDWIdClientREST.SetCertOptions(Var assl : TComponent); Var vRESTDWVersionsBase : Pointer; Begin - If Assigned(ssl) Then + If Assigned(assl) Then Begin {$IFDEF FPC} TIdSSLIOHandlerSocketOpenSSL(ssl).OnGetPassword := @Getpassword; @@ -3176,22 +3179,26 @@ TIdHTTPAccess = class(TIdHTTP) End Else Begin - TIdSSLIOHandlerSocketOpenSSL(ssl).OnGetPassword := Getpassword; - TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.CertFile := vCertFile; - TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.KeyFile := vKeyFile; - TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.RootCertFile := vRootCertFile; - TIdSSLIOHandlerSocketOpenSSL(ssl).Host := vHostCert; - TIdSSLIOHandlerSocketOpenSSL(ssl).Port := vPortCert; - TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.Mode := TIdSSLMode(GetSSlMode);; + TIdSSLIOHandlerSocketOpenSSL(assl).OnGetPassword := Getpassword; + TIdSSLIOHandlerSocketOpenSSL(assl).SSLOptions.CertFile := vCertFile; + TIdSSLIOHandlerSocketOpenSSL(assl).SSLOptions.KeyFile := vKeyFile; + TIdSSLIOHandlerSocketOpenSSL(assl).SSLOptions.RootCertFile := vRootCertFile; + TIdSSLIOHandlerSocketOpenSSL(assl).Host := vHostCert; + TIdSSLIOHandlerSocketOpenSSL(assl).Port := vPortCert; + TIdSSLIOHandlerSocketOpenSSL(assl).SSLOptions.Method := TIdSSLVersion(Pointer(GetSSlVersion)^); + TIdSSLIOHandlerSocketOpenSSL(assl).SSLOptions.Mode := TIdSSLMode(Pointer(GetSSlMode)^); + TIdSSLIOHandlerSocketOpenSSL(assl).SSLOptions.SSLVersions := TIdSSLVersions(Pointer(vRESTDWVersionsBase)^); End; {$ELSE} - TIdSSLIOHandlerSocketOpenSSL(ssl).OnGetPassword := Getpassword; - TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.CertFile := vCertFile; - TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.KeyFile := vKeyFile; - TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.RootCertFile := vRootCertFile; - TIdSSLIOHandlerSocketOpenSSL(ssl).Host := vHostCert; - TIdSSLIOHandlerSocketOpenSSL(ssl).Port := vPortCert; - TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.Mode := TIdSSLMode(GetSSlMode);; + TIdSSLIOHandlerSocketOpenSSL(assl).OnGetPassword := Getpassword; + TIdSSLIOHandlerSocketOpenSSL(assl).SSLOptions.CertFile := vCertFile; + TIdSSLIOHandlerSocketOpenSSL(assl).SSLOptions.KeyFile := vKeyFile; + TIdSSLIOHandlerSocketOpenSSL(assl).SSLOptions.RootCertFile := vRootCertFile; + TIdSSLIOHandlerSocketOpenSSL(assl).SSLOptions.Method := TIdSSLVersion(Pointer(GetSSlVersion)^); + TIdSSLIOHandlerSocketOpenSSL(assl).SSLOptions.Mode := TIdSSLMode(Pointer(GetSSlMode)^); + TIdSSLIOHandlerSocketOpenSSL(assl).SSLOptions.SSLVersions := TIdSSLVersions(Pointer(vRESTDWVersionsBase)^); + TIdSSLIOHandlerSocketOpenSSL(assl).Host := vHostCert; + TIdSSLIOHandlerSocketOpenSSL(assl).Port := vPortCert; {$ENDIF} {$ENDIF} End; @@ -3296,16 +3303,15 @@ TIdHTTPAccess = class(TIdHTTP) End; Procedure TRESTDWIdClientREST.SetUseSSL(Value : Boolean); -{$IFDEF USE_TAURUS_TLS} Var - vRESTDWVersionsBase : TRESTDWVersionsBase; -{$ENDIF} + vRESTDWVersionsBase : Pointer; Begin Inherited; If Assigned(HttpRequest) Then HttpRequest.IOHandler := Nil; If Value Then Begin + vRESTDWVersionsBase := GetSSlVersions; If ssl = Nil Then Begin {$IFDEF FPC} @@ -3323,35 +3329,52 @@ TIdHTTPAccess = class(TIdHTTP) Begin ssl := TIdSSLIOHandlerSocketOpenSSL.Create(HttpRequest); TIdSSLIOHandlerSocketOpenSSL(ssl).OnVerifyPeer := IdSSLIOHandlerSocketOpenSSL1VerifyPeer; - TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.Method := TIdSSLVersion(GetSSlVersion);//aSSLMethod; - TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.SSLVersions := TIdSSLVersions(Pointer(@vRESTDWVersionsBase)^); - TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.Mode := TIdSSLMode(GetSSlMode);//vSSLMode; + TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.Mode := TIdSSLMode(Pointer(GetSSlMode)^);//vSSLMode; + TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.Method := TIdSSLVersion(Pointer(GetSSlVersion)^);//aSSLMethod; + TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.SSLVersions := TIdSSLVersions(Pointer(@vSSLVersions)^); TIdSSLIOHandlerSocketOpenSSL(ssl).OnGetPassword := Getpassword; If Assigned(HttpRequest) Then HttpRequest.IOHandler := TIdSSLIOHandlerSocketOpenSSL(ssl); End; {$ELSE} - ssl := TIdSSLIOHandlerSocketOpenSSL.Create(HttpRequest); - TIdSSLIOHandlerSocketOpenSSL(ssl).OnVerifyPeer := IdSSLIOHandlerSocketOpenSSL1VerifyPeer; - TIdSSLIOHandlerSocketOpenSSL(ssl).OnGetPassword := Getpassword; - If Assigned(HttpRequest) Then - HttpRequest.IOHandler := TIdSSLIOHandlerSocketOpenSSL(ssl); + ssl := TIdSSLIOHandlerSocketOpenSSL.Create(HttpRequest); + TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.Mode := TIdSSLMode(Pointer(GetSSlMode)^);//vSSLMode; + TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.Method := TIdSSLVersion(Pointer(GetSSlVersion)^);//aSSLMethod; + TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.SSLVersions := TIdSSLVersions(Pointer(@vSSLVersions)^); + TIdSSLIOHandlerSocketOpenSSL(ssl).OnVerifyPeer := IdSSLIOHandlerSocketOpenSSL1VerifyPeer; + TIdSSLIOHandlerSocketOpenSSL(ssl).OnGetPassword := Getpassword; + {$ENDIF} + {$ENDIF} + End + Else + Begin + {$IFDEF FPC} +// SetCertOptions(TIdSSLIOHandlerSocketOpenSSL(ssl)); +// TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.Mode := TIdSSLMode(Pointer(GetSSlMode)^); +// TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.Method := TIdSSLVersion(Pointer(GetSSlVersion)^); +// TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.SSLVersions := TIdSSLVersions(Pointer(vRESTDWVersionsBase)^); + {$ELSE} + {$IFDEF USE_TAURUS_TLS} + {$ELSE} +// SetCertOptions(TComponent(TIdSSLIOHandlerSocketOpenSSL(ssl))); +// TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.Mode := TIdSSLMode(Pointer(GetSSlMode)^); +// TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.Method := TIdSSLVersion(Pointer(GetSSlVersion)^); +// TIdSSLIOHandlerSocketOpenSSL(ssl).SSLOptions.SSLVersions := TIdSSLVersions(Pointer(vRESTDWVersionsBase)^); {$ENDIF} {$ENDIF} End; - SetCertOptions; -// If sslvSSLv2 in vSSLVersions Then -// ssl.SSLOptions.Method := sslvSSLv2 -// Else If sslvSSLv23 in vSSLVersions Then -// ssl.SSLOptions.Method := sslvSSLv23 -// Else If sslvSSLv3 in vSSLVersions Then -// ssl.SSLOptions.Method := sslvSSLv3 -// Else If sslvTLSv1 in vSSLVersions Then -// ssl.SSLOptions.Method := sslvTLSv1 -// Else If sslvTLSv1_1 in vSSLVersions Then -// ssl.SSLOptions.Method := sslvTLSv1_1 -// Else If sslvTLSv1_2 in vSSLVersions Then -// ssl.SSLOptions.Method := sslvTLSv1_2; + {$IFDEF FPC} + If Assigned(HttpRequest) Then + HttpRequest.IOHandler := TIdSSLIOHandlerSocketOpenSSL(ssl); + {$ELSE} + {$IFDEF USE_TAURUS_TLS} + If Assigned(HttpRequest) Then + HttpRequest.IOHandler := TIdSSLIOHandlerSocketOpenSSL(ssl); + {$ELSE} + If Assigned(HttpRequest) Then + HttpRequest.IOHandler := TIdSSLIOHandlerSocketOpenSSL(ssl); + {$ENDIF} + {$ENDIF} End Else Begin @@ -3677,6 +3700,7 @@ TIdHTTPAccess = class(TIdHTTP) SetSocketKind('Standalone - Indy'); lHandler := Nil; HTTPServer := TIdHTTPServer.Create(Nil); +// ThreadMgrPool := TIdSchedulerOfThreadPool.Create(Nil); {$IFDEF FPC} HTTPServer.OnQuerySSLPort := @IdHTTPServerQuerySSLPort; HTTPServer.OnCommandGet := @aCommandGet; @@ -3693,8 +3717,10 @@ TIdHTTPAccess = class(TIdHTTP) HTTPServer.OnCreatePostStream := CreatePostStream; HTTPServer.OnParseAuthentication := OnParseAuthentication; {$ENDIF} - HTTPServer.MaxConnections := -1; - FSocketKind := 'Indy'; + HTTPServer.MaxConnections := -1; + FSocketKind := 'Indy'; + HTTPServer.KeepAlive := False; +// HTTPServer.Scheduler := ThreadMgrPool; End; Destructor TRESTDWIdServicePooler.Destroy; @@ -3710,6 +3736,7 @@ TIdHTTPAccess = class(TIdHTTP) {$ELSE} FreeAndNil(lHandler); FreeAndNil(HTTPServer); +// FreeAndNil(ThreadMgrPool); {$ENDIF} Inherited; End; @@ -3890,6 +3917,8 @@ TIdHTTPAccess = class(TIdHTTP) HTTPServer.IOHandler := TIdServerIOHandlerSSLOpenSSL(lHandler); End; {$ELSE} + If Not Assigned(lHandler) Then + lHandler := TIdServerIOHandlerSSLOpenSSL.Create(Nil); TIdServerIOHandlerSSLOpenSSL(lHandler).SSLOptions.SSLVersions := TIdSSLVersions(Pointer(vRESTDWVersionsBase)^); TIdServerIOHandlerSSLOpenSSL(lHandler).SSLOptions.Method := TIdSSLVersion(Pointer(GetSSlVersion)^);//aSSLMethod; {$IFDEF FPC} @@ -4184,14 +4213,117 @@ procedure TRESTDWIdClientPooler.Abort; Inherited; End; -Function TRESTDWIdClientPooler.GetSSlMode : Integer; +Function TRESTDWIdClientPooler.GetSSlMode : Pointer; +{$IFDEF USE_TAURUS_TLS} + Var + bSSLMode : TIdSSLMode; + aTaurSSLMode : TTaurusTLSSSLMode; +{$ELSE} +Var + bSSLMode : TRESTDWSSLMode; +{$ENDIF} Begin - Result := 0; + Result := Nil; + {$IFDEF USE_TAURUS_TLS} + If vUseTaurus Then + Begin + If vSSLMode = sslUnassigned Then + aTaurSSLMode := TTaurusTLSSSLMode(sslmUnassigned) + Else If vSSLMode = sslClient Then + aTaurSSLMode := TTaurusTLSSSLMode(sslmClient) + Else If vSSLMode = sslServer Then + aTaurSSLMode := TTaurusTLSSSLMode(sslmServer) + Else If vSSLMode = sslBoth Then + aTaurSSLMode := TTaurusTLSSSLMode(sslmBoth); + Result := @aTaurSSLMode; + End + Else + Begin + If vSSLMode = sslUnassigned Then + bSSLMode := sslmUnassigned + Else If vSSLMode = sslClient Then + bSSLMode := sslmClient + Else If vSSLMode = sslServer Then + bSSLMode := sslmServer + Else If vSSLMode = sslBoth Then + bSSLMode := sslmBoth; + Result := @bSSLMode; + End; + {$ELSE} + If vSSLMode = sslUnassigned Then + bSSLMode := sslUnassigned + Else If vSSLMode = sslClient Then + bSSLMode := sslClient + Else If vSSLMode = sslServer Then + bSSLMode := sslServer + Else If vSSLMode = sslBoth Then + bSSLMode := sslBoth; + Result := @bSSLMode; + {$ENDIF} End; -Function TRESTDWIdClientPooler.GetSSlVersion : Integer; +Function TRESTDWIdClientPooler.GetSSlVersion : Pointer; +Var + SSLVersion : TIdSSLVersion; + {$IFDEF USE_TAURUS_TLS} + MinSSLVersion : TTaurusTLSSSLVersion; + {$ENDIF} Begin - Result := 0; + Result := Nil; + {$IFDEF USE_TAURUS_TLS} + If vUseTaurus Then + Begin + If SSLv2 = aSSLMethod Then + MinSSLVersion := TTaurusTLSSSLVersion(SSLv2); + If SSLv23 = aSSLMethod Then + MinSSLVersion := TTaurusTLSSSLVersion(SSLv23); + If SSLv3 = aSSLMethod Then + MinSSLVersion := TTaurusTLSSSLVersion(SSLv3); + If TLSv1 = aSSLMethod Then + MinSSLVersion := TTaurusTLSSSLVersion(TLSv1); + If TLSv1_1 = aSSLMethod Then + MinSSLVersion := TTaurusTLSSSLVersion(TLSv1_1); + If TLSv1_2 = aSSLMethod Then + MinSSLVersion := TTaurusTLSSSLVersion(TLSv1_2); + If TLSv1_3 = aSSLMethod Then + MinSSLVersion := TTaurusTLSSSLVersion(TLSv1_3); + Result := @MinSSLVersion; + End + Else + Begin + If aSSLMethod = SSLv2 Then + SSLVersion := sslvSSLv2; + If aSSLMethod = SSLv23 Then + SSLVersion := sslvSSLv23; + If aSSLMethod = SSLv3 Then + SSLVersion := sslvSSLv3; + If aSSLMethod = TLSv1 Then + SSLVersion := sslvTLSv1; + If aSSLMethod = TLSv1_1 Then + SSLVersion := sslvTLSv1_1; + If aSSLMethod = TLSv1_2 Then + SSLVersion := sslvTLSv1_2; + If aSSLMethod = TLSv1_3 Then + Raise Exception.Create('Indy no have TLS 1.3 Support...'); + Result := @SSLVersion; + End; + {$ELSE} + If aSSLMethod = SSLv2 Then + SSLVersion := sslvSSLv2; + If aSSLMethod = SSLv23 Then + SSLVersion := sslvSSLv23; + If aSSLMethod = SSLv3 Then + SSLVersion := sslvSSLv3; + If aSSLMethod = TLSv1 Then + SSLVersion := sslvTLSv1; + If aSSLMethod = TLSv1_1 Then + SSLVersion := sslvTLSv1_1; + If aSSLMethod = TLSv1_2 Then + SSLVersion := sslvTLSv1_2; + If aSSLMethod = TLSv1_3 Then + Raise Exception.Create('Indy no have TLS 1.3 Support...'); + Result := @SSLVersion; + {$ENDIF} End; Function TRESTDWIdClientPooler.GetSSlVersions : TRESTDWVersionsBase; @@ -5168,7 +5300,12 @@ procedure TRESTDWIdClientPooler.Abort; FreeAndNil(HttpRequest); HttpRequest := TRESTDWIdClientREST.Create(Nil); If (TypeRequest = trHttps) Then - HttpRequest.SSLVersions := SSLVersions;//PIdSSLVersions(@SSLVersions)^; + Begin + HttpRequest.SSLMode := vSSlMode; + HttpRequest.SSLVersions := vSSLVersions;//PIdSSLVersions(@SSLVersions)^; + HttpRequest.SSLMethod := aSSLMethod; + HttpRequest.UseSSL := TypeRequest = trHttps; + End; HttpRequest.UserAgent := UserAgent; SetCharsetRequest(HttpRequest, Encoding); SetParams(ProxyOptions, RequestTimeout, ConnectTimeout, AuthenticationOptions); diff --git a/CORE/Source/Sockets/Indy/uRESTDWIdFCMTransport.pas b/CORE/Source/Sockets/Indy/uRESTDWIdFCMTransport.pas new file mode 100644 index 000000000..3d423bc3b --- /dev/null +++ b/CORE/Source/Sockets/Indy/uRESTDWIdFCMTransport.pas @@ -0,0 +1,354 @@ +Unit uRESTDWIdFCMTransport; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + SysUtils, + IdHTTP, + IdTCPClient, + IdSSLOpenSSL, + uRESTDWFCMTransport, + uRESTDWFCMCompat; + +Type + TRESTDWIdFCMHTTPTransport = Class(TRESTDWFCMHTTPTransport) + Private + FHTTP : TIdHTTP; + FSSL : TIdSSLIOHandlerSocketOpenSSL; + FVerifyPeer : Boolean; + + Function VerifyPeer(Certificate : TIdX509; + AOk : Boolean; + ADepth, + AError : Integer) : Boolean; + Public + Constructor Create(AConnectTimeout, AReadTimeout : Integer); + Destructor Destroy; Override; + + Procedure ConfigureTLS(AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); Override; + + Function Post(Const AURL : String; + AHeaders : TStrings; + ABody : TStream; + AResponse : TStream; + AResponseError : TStream) : Integer; Override; + End; + + TRESTDWIdFCMStreamTransport = Class(TRESTDWFCMStreamTransport) + Private + FTCP : TIdTCPClient; + FSSL : TIdSSLIOHandlerSocketOpenSSL; + FVerifyPeer : Boolean; + + Function VerifyPeer(Certificate : TIdX509; + AOk : Boolean; + ADepth, + AError : Integer) : Boolean; + Public + Constructor Create(AConnectTimeout, AReadTimeout : Integer); + Destructor Destroy; Override; + + Procedure ConfigureTLS(AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); Override; + + Procedure Connect(Const AHost : String; + APort : Integer); Override; + Procedure Disconnect; Override; + Function Connected : Boolean; Override; + Function ReadByte : Byte; Override; + Procedure ReadBuffer(Var ABuffer; ACount : Integer); Override; + Procedure WriteBuffer(Const ABuffer; ACount : Integer); Override; + End; + +Implementation + +Constructor TRESTDWIdFCMHTTPTransport.Create(AConnectTimeout, AReadTimeout : Integer); +Begin + Inherited Create; + + FHTTP := TIdHTTP.Create(Nil); + FSSL := TIdSSLIOHandlerSocketOpenSSL.Create(Nil); + + FSSL.SSLOptions.Method := sslvTLSv1_2; + FSSL.PassThrough := False; + FVerifyPeer := True; + FSSL.OnVerifyPeer := {$IFDEF FPC}@{$ENDIF}VerifyPeer; + + FHTTP.IOHandler := FSSL; + FHTTP.ConnectTimeout := AConnectTimeout; + FHTTP.ReadTimeout := AReadTimeout; + FHTTP.HandleRedirects := True; +End; + +Function TRESTDWIdFCMHTTPTransport.VerifyPeer(Certificate : TIdX509; + AOk : Boolean; + ADepth, + AError : Integer) : Boolean; +Begin + If FVerifyPeer Then + Result := AOk + Else + Result := True; +End; + +Procedure TRESTDWIdFCMHTTPTransport.ConfigureTLS(AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); +Begin + FVerifyPeer := AVerifyPeer; + + If AVerifyPeer Then + FSSL.SSLOptions.VerifyMode := [sslvrfPeer] + Else + FSSL.SSLOptions.VerifyMode := []; + + If ACAFile <> '' Then + FSSL.SSLOptions.RootCertFile := ACAFile + Else + If FileExists( + ExtractFilePath(ParamStr(0)) + + 'RESTDWRootCA.pem' + ) Then + FSSL.SSLOptions.RootCertFile := + ExtractFilePath(ParamStr(0)) + + 'RESTDWRootCA.pem'; + + { Indy OpenSSL usa o mesmo CA bundle controlado pelo REST Dataware; ACAPath nao possui equivalente direto + neste IOHandler antigo. O MCS Indy continua usando o proprio IOHandler. } +End; + +Destructor TRESTDWIdFCMHTTPTransport.Destroy; +Begin + FHTTP.IOHandler := Nil; + + FHTTP.Free; + FSSL.Free; + + Inherited Destroy; +End; + +Function TRESTDWIdFCMHTTPTransport.Post(Const AURL : String; + AHeaders : TStrings; + ABody : TStream; + AResponse : TStream; + AResponseError : TStream) : Integer; +Var + I : Integer; +Begin + Result := 0; + + If AResponse <> Nil Then + Begin + AResponse.Size := 0; + AResponse.Position := 0; + End; + + If AResponseError <> Nil Then + Begin + AResponseError.Size := 0; + AResponseError.Position := 0; + End; + + FHTTP.Request.CustomHeaders.Clear; + FHTTP.Request.ContentType := ''; + FHTTP.Request.Accept := ''; + + If AHeaders <> Nil Then + For I := 0 To AHeaders.Count - 1 Do + Begin + If SameText(AHeaders.Names[I], 'Content-Type') Then + FHTTP.Request.ContentType := AHeaders.ValueFromIndex[I] + Else + If SameText(AHeaders.Names[I], 'Accept') Then + FHTTP.Request.Accept := AHeaders.ValueFromIndex[I] + Else + FHTTP.Request.CustomHeaders.Values[AHeaders.Names[I]] := + AHeaders.ValueFromIndex[I]; + End; + + If ABody <> Nil Then + ABody.Position := 0; + + Try + Try + FHTTP.Post( + AURL, + ABody, + AResponse + ); + + Result := FHTTP.ResponseCode; + Except + On E : EIdHTTPProtocolException Do + Begin + Result := E.ErrorCode; + + If (AResponseError <> Nil) And + (E.ErrorMessage <> '') Then + RESTDWFCMWriteUTF8( + AResponseError, + E.ErrorMessage + ); + End; + End; + Finally + If AResponse <> Nil Then + AResponse.Position := 0; + + If AResponseError <> Nil Then + AResponseError.Position := 0; + End; +End; + +Constructor TRESTDWIdFCMStreamTransport.Create(AConnectTimeout, AReadTimeout : Integer); +Begin + Inherited Create; + + FTCP := TIdTCPClient.Create(Nil); + FSSL := TIdSSLIOHandlerSocketOpenSSL.Create(Nil); + + FSSL.SSLOptions.Method := sslvTLSv1_2; + FSSL.PassThrough := False; + FVerifyPeer := True; + FSSL.OnVerifyPeer := {$IFDEF FPC}@{$ENDIF}VerifyPeer; + + FTCP.IOHandler := FSSL; + FTCP.ConnectTimeout := AConnectTimeout; + FTCP.ReadTimeout := AReadTimeout; +End; + +Function TRESTDWIdFCMStreamTransport.VerifyPeer(Certificate : TIdX509; + AOk : Boolean; + ADepth, + AError : Integer) : Boolean; +Begin + If FVerifyPeer Then + Result := AOk + Else + Result := True; +End; + +Procedure TRESTDWIdFCMStreamTransport.ConfigureTLS(AVerifyPeer : Boolean; + Const ACAFile, + ACAPath : String); +Begin + FVerifyPeer := AVerifyPeer; + + If AVerifyPeer Then + FSSL.SSLOptions.VerifyMode := [sslvrfPeer] + Else + FSSL.SSLOptions.VerifyMode := []; + + If ACAFile <> '' Then + FSSL.SSLOptions.RootCertFile := ACAFile + Else + If FileExists( + ExtractFilePath(ParamStr(0)) + + 'RESTDWRootCA.pem' + ) Then + FSSL.SSLOptions.RootCertFile := + ExtractFilePath(ParamStr(0)) + + 'RESTDWRootCA.pem'; +End; + +Destructor TRESTDWIdFCMStreamTransport.Destroy; +Begin + Disconnect; + + FTCP.IOHandler := Nil; + + FTCP.Free; + FSSL.Free; + + Inherited Destroy; +End; + +Procedure TRESTDWIdFCMStreamTransport.Connect(Const AHost : String; + APort : Integer); +Begin + Disconnect; + + FTCP.Host := AHost; + FTCP.Port := APort; + FSSL.Host := AHost; + FSSL.Port := APort; + FTCP.Connect; +End; + +Procedure TRESTDWIdFCMStreamTransport.Disconnect; +Begin + If FTCP.Connected Then + FTCP.Disconnect; +End; + +Function TRESTDWIdFCMStreamTransport.Connected : Boolean; +Begin + Result := FTCP.Connected; +End; + +Function TRESTDWIdFCMStreamTransport.ReadByte : Byte; +Begin + Result := FTCP.IOHandler.ReadByte; +End; + +Procedure TRESTDWIdFCMStreamTransport.ReadBuffer(Var ABuffer; + ACount : Integer); +Var + LStream : TMemoryStream; +Begin + If ACount <= 0 Then + Exit; + + LStream := TMemoryStream.Create; + Try + FTCP.IOHandler.ReadStream( + LStream, + ACount, + False + ); + + LStream.Position := 0; + + LStream.ReadBuffer( + ABuffer, + ACount + ); + Finally + LStream.Free; + End; +End; + +Procedure TRESTDWIdFCMStreamTransport.WriteBuffer(Const ABuffer; + ACount : Integer); +Var + LStream : TMemoryStream; +Begin + If ACount <= 0 Then + Exit; + + LStream := TMemoryStream.Create; + Try + LStream.WriteBuffer( + ABuffer, + ACount + ); + + LStream.Position := 0; + + FTCP.IOHandler.Write( + LStream, + 0, + False + ); + Finally + LStream.Free; + End; +End; + +End. diff --git a/CORE/Source/Sockets/Indy/uRESTDWIdFirebaseCloudMessaging.pas b/CORE/Source/Sockets/Indy/uRESTDWIdFirebaseCloudMessaging.pas new file mode 100644 index 000000000..c71f7ebee --- /dev/null +++ b/CORE/Source/Sockets/Indy/uRESTDWIdFirebaseCloudMessaging.pas @@ -0,0 +1,34 @@ +Unit uRESTDWIdFirebaseCloudMessaging; + +Interface + +{$I uRESTDW.inc} + +Uses + Classes, + uRESTDWFirebaseCloudMessaging, + uRESTDWFCMTransport; + +Type + TRESTDWIdFirebaseCloudMessaging = Class(TRESTDWFirebaseCloudMessaging) + Protected + Function CreateHTTPTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMHTTPTransport; Override; + Function CreateMCSStreamTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMStreamTransport; Override; + End; + +Implementation + +Uses + uRESTDWIdFCMTransport; + +Function TRESTDWIdFirebaseCloudMessaging.CreateHTTPTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMHTTPTransport; +Begin + Result := TRESTDWIdFCMHTTPTransport.Create(AConnectTimeout, AReadTimeout); +End; + +Function TRESTDWIdFirebaseCloudMessaging.CreateMCSStreamTransport(AConnectTimeout, AReadTimeout : Integer) : TRESTDWFCMStreamTransport; +Begin + Result := TRESTDWIdFCMStreamTransport.Create(AConnectTimeout, AReadTimeout); +End; + +End. diff --git a/CORE/Source/Sockets/Indy/uRESTDWIdReg.dcr b/CORE/Source/Sockets/Indy/uRESTDWIdReg.dcr new file mode 100644 index 0000000000000000000000000000000000000000..9b37ac8601b55a7d5ca3cb596eb2a8b760cbb97f GIT binary patch literal 2796 zcmbtVcT`kY8vou5B1U2-M^jAHtcOk9B*vQKk;ob_+1QOojo4RBKrEniq&a{fA`D8E zqM)LH0hAsPq^Sr3Mg@lfL^?>Fnb+^$JA+F6cfa#)dG~$qcfbAt0DOiALb`#sf1?h4 z01JGAkOY2#jbH|w@cIL6fuHbfj%RZAZ!pE@X0Q@g!#dcEzpT-6Zo=oQFwa^%>*$+F zZ{dyccKXPmv^#)1_`c!^y78KmV;NBt1_lP2o0}g!dQ|=B(ewKHzE`hmYpQ#?yE{8O z+g`qGZ)>Zns>E|oPfu4@S8Ho)LqkJTQ=>wmP%4%6_4RG7t&B#45DL3+{`Z3ie7wD* zA|w1y`zBpa3=IjA2c12zZ;z{^gPV)Xnne9Wl74*u2_v|&cm0Fd z3%4w{C0T7xIkxZOj&)WBaO#U`eJ#x*R*BcjBk*`DXa?zrmtVzfqMNIRA~tbDeSiLE zM$!UlV{UrN?^|oGTy&c$P1tCnDEzabFh9%3&CW<-_dewLyJH!2_7Qjv8;I*sstf#( z=G9>IMy~o=``z@M1(3U9Y*S`ZzKdnCziZ|x`(*1~?Bhl9 z*$_ULI{!KN&6YS%g0QvAN6CZnSV0t7WfdK7r9Nyx9|ZQ8bl6JLwhb&z94IGbScRn7 z2sVg&XIT#X0)xLw>sCw7eGDOMM&V%BV^XUI9Y1BQL2v@mLBiQckPQ@Bd@bFHrk4rx zDw(gV82w05-Pp;*m5)l*j~1#=}9B;`}p8p}2VHu%Ak|z97jtqSpwJ$dNL_ z=6VR}`l!H=O{P#1M91y_H89aAsh0{D$9ZX{x^%pVn!zVSZ}2?zlX4;q1|j)Aif|O+ z!=9H+{2C$mTRzW7yag?ZA9jRI-I*8-sc5a|t(5pJd;+D(lJOdHDfSdLtyZ299P+9? zB6g!yT(PfkXPJ0+hL{H^6P{##A-RGgLJpu37?h8p8=n#ome&4E(qRN;^ujX)s=bmg zv=D0c@uf?}l228oQ(O{#)P>XdlK1=N-}5vnfW+1KavVH=*Ncclh~$XKsF-{kvHraH z{H$1el&jv1s=r5dOZv`E)>P&YVMr~-yjm=6JtVIfRwR#(u$72N-OuO}5AMY+@kOGj zyud$kQe870%8w+UMt}J) z#!`UYxS9R`J#;=S9%+j2_EFMS$#~sI0pIyW=q01n#)ZW2AM31{qOePmL_6Rt&e#| z)mISOm+DGq`F3PPC46NNx7jRgy=j8Q>Qw7pnVt?uCrP3p$E=IQD6VI^U10 zh<+X|%U!1bBr)oKfPK;)^Fq1*!)vkfW%EuLNn2_jk~r2j3AVXZT^d5yX4h={sBi`3 zn@iDq&Z0l1x-AirziRw3K+XDMd4o?YdnCSFu z`y5M!Ih3vd-%kw`WyOSFSBWm|;SK@k0LYOl-m_586U|kinN>)#29>W~gzTVt?YNfv zceVHo#%FHq5ahrHy@yUgjK@y!73bWhjZztEw-~hXkmyVGA2l4VEg~UHj+nYigg6}PdQMzTxyiy(59@qErwHrJ573gI{QjgQu(ME%U)n8UQUjO3Co z8_6A*w7FLsBb2Q|Wpla;KJ@*=4Q0V_nkA|DtOf_?8+>gc!iw-h&oi#VTU3S$b+)K> s#qhPo%!_)G&%{&OS%Uk{xwt+uc`2-i(J{3zlbD)uAK<~14L~u00000 literal 0 HcmV?d00001 diff --git a/CORE/Source/Sockets/Indy/uRESTDWIdReg.pas b/CORE/Source/Sockets/Indy/uRESTDWIdReg.pas index c8e8c9d70..0fe0a9a90 100644 --- a/CORE/Source/Sockets/Indy/uRESTDWIdReg.pas +++ b/CORE/Source/Sockets/Indy/uRESTDWIdReg.pas @@ -1,21 +1,21 @@ unit uRESTDWIdReg; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. A. Brito - Admin - Administrador do desenvolvimento. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. @@ -40,7 +40,7 @@ interface {$ENDIF} DesignIntf, DesignEditors, {$ENDIF} - Classes, uRESTDWIdBase; + Classes, uRESTDWIdBase, uRESTDWIdFirebaseCloudMessaging; {$IFNDEF RESTDWLAMW} Type @@ -56,6 +56,10 @@ interface Implementation +{$IFNDEF RESTDWLAZARUS} +{$R 'uRESTDWIdReg.dcr'} +{$ENDIF} + {$IFNDEF RESTDWLAMW} Function TPoolersList.GetAttributes: TPropertyAttributes; Begin @@ -96,7 +100,7 @@ interface Procedure Register; Begin RegisterComponents ('REST Dataware - Service', [TRESTDWIdServicePooler, TRESTDWIdProxyRequest, TRESTDWIdPoolerList]); - RegisterComponents ('REST Dataware - Client', [TRESTDWIdClientREST, TRESTDWIdClientPooler]); + RegisterComponents ('REST Dataware - Client', [TRESTDWIdClientREST, TRESTDWIdClientPooler, TRESTDWIdFirebaseCloudMessaging]); RegisterComponents ('REST Dataware - DB', [TRESTDWIdDatabase]); {$IFNDEF RESTDWLAMW} RegisterPropertyEditor(TypeInfo(String), TRESTDWIdDatabase, 'PoolerName', TPoolersList); From 6b27c244b24b33bbc902c4a6dd2e8ef841394b57 Mon Sep 17 00:00:00 2001 From: Roniery Santos Cardoso Date: Tue, 8 Sep 2026 22:00:40 -0300 Subject: [PATCH 07/22] feat(html-designer): adiciona HTML Designer (Webpascal) e FMC Novo HTML Designer integrado (Webpascal), com WebView (WebView2), SynEdit privado embarcado e adaptadores de JSON/PageProducer, alem do FMC (uRESTDWHTMLEditor/uRESTDWFMXHTMLEditor) e ajustes no SelfSigned e no DMDados. refs r4027-r4028, r4045-r4047 --- .../Plugins/DMDados/uRESTDWDatamodule.pas | 2 +- .../HTMLEditor/PrivateSynEdit/SynEdit.inc | 1425 + .../PrivateSynEdit/uRESTDWPrivSynEdit.pas | 11958 ++++++++ .../uRESTDWPrivSynEditCodeFolding.pas | 1089 + .../uRESTDWPrivSynEditHighlighter.pas | 1318 + .../uRESTDWPrivSynEditHighlighterOptions.pas | 97 + .../uRESTDWPrivSynEditKbdHandler.pas | 401 + .../uRESTDWPrivSynEditKeyCmds.pas | 1026 + .../uRESTDWPrivSynEditKeyConst.pas | 121 + .../uRESTDWPrivSynEditMiscClasses.pas | 1620 + .../uRESTDWPrivSynEditMiscProcs.pas | 963 + .../uRESTDWPrivSynEditStrConst.pas | 577 + .../uRESTDWPrivSynEditTextBuffer.pas | 1397 + .../uRESTDWPrivSynEditTypes.pas | 149 + .../uRESTDWPrivSynEditWordWrap.pas | 637 + .../uRESTDWPrivSynHighlighterCss.pas | 1146 + .../uRESTDWPrivSynHighlighterHashEntries.pas | 251 + .../uRESTDWPrivSynHighlighterHtml.pas | 1225 + .../uRESTDWPrivSynHighlighterJScript.pas | 4900 +++ .../uRESTDWPrivSynHighlighterMulti.pas | 1113 + .../PrivateSynEdit/uRESTDWPrivSynRegExpr.pas | 4107 +++ .../uRESTDWPrivSynTextDrawer.pas | 1043 + .../PrivateSynEdit/uRESTDWPrivSynUnicode.pas | 3708 +++ .../PrivateSynEdit/uRESTDWPrivSynUsp10.pas | 2631 ++ .../WebView/uRESTDWPrivWVBrowser.pas | 272 + .../WebView/uRESTDWPrivWVBrowserBase.pas | 8702 ++++++ .../WebView/uRESTDWPrivWVConstants.pas | 98 + .../WebView/uRESTDWPrivWVCoreWebView2.pas | 2652 ++ .../WebView/uRESTDWPrivWVCoreWebView2Args.pas | 5131 ++++ ...rivWVCoreWebView2CompositionController.pas | 502 + .../uRESTDWPrivWVCoreWebView2Controller.pas | 699 + ...TDWPrivWVCoreWebView2ControllerOptions.pas | 296 + ...uRESTDWPrivWVCoreWebView2CookieManager.pas | 185 + ...WVCoreWebView2CustomSchemeRegistration.pas | 198 + .../uRESTDWPrivWVCoreWebView2Delegates.pas | 4630 +++ .../uRESTDWPrivWVCoreWebView2Environment.pas | 962 + ...DWPrivWVCoreWebView2EnvironmentOptions.pas | 402 + .../WebView/uRESTDWPrivWVCoreWebView2Find.pas | 272 + .../uRESTDWPrivWVCoreWebView2FindOptions.pas | 210 + ...uRESTDWPrivWVCoreWebView2PrintSettings.pas | 661 + .../uRESTDWPrivWVCoreWebView2Profile.pas | 724 + .../uRESTDWPrivWVCoreWebView2Settings.pas | 728 + .../WebView/uRESTDWPrivWVEvents.pas | 133 + .../WebView/uRESTDWPrivWVInterfaces.pas | 352 + .../WebView/uRESTDWPrivWVLibFunctions.pas | 100 + .../WebView/uRESTDWPrivWVLoader.pas | 2247 ++ .../WebView/uRESTDWPrivWVLoaderInternal.pas | 978 + .../WebView/uRESTDWPrivWVMiscFunctions.pas | 740 + .../WebView/uRESTDWPrivWVTypeLibrary.pas | 15641 ++++++++++ .../HTMLEditor/WebView/uRESTDWPrivWVTypes.pas | 738 + .../WebView/uRESTDWPrivWVWinControl.pas | 120 + .../WebView/uRESTDWPrivWVWindowParent.pas | 151 + .../uRESTDWHTMLComponentManager.pas | 1136 + .../HTMLEditor/uRESTDWHTMLDesigner.pas | 9457 ++++++ .../HTMLEditor/uRESTDWHTMLDesignerAI.pas | 671 + .../HTMLEditor/uRESTDWHTMLDesignerIcons.pas | 9498 ++++++ .../HTMLEditor/uRESTDWHTMLIDECompat.pas | 277 + .../HTMLEditor/uRESTDWHTMLJSONCompat.pas | 247 + .../uRESTDWHTMLPageProducerAdapter.pas | 319 + .../HTMLEditor/uRESTDWHTMLWebAssets.pas | 24516 ++++++++++++++++ .../Plugins/HTMLEditor/uRESTDWHTMLWebView.pas | 1875 ++ .../Plugins/SelfSigned/uRESTDWSelfSigned.pas | 10 +- .../SelfSigned/uRESTDWSelfSignedMacros.pas | 10 +- .../SelfSigned/uRESTDWSelfSignedReg.pas | 10 +- CORE/Source/Plugins/uRESTDWFMXHTMLEditor.pas | 44 + CORE/Source/Plugins/uRESTDWHTMLEditor.pas | 36 + 66 files changed, 139518 insertions(+), 16 deletions(-) create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/SynEdit.inc create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEdit.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditCodeFolding.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditHighlighter.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditHighlighterOptions.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditKbdHandler.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditKeyCmds.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditKeyConst.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditMiscClasses.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditMiscProcs.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditStrConst.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditTextBuffer.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditTypes.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditWordWrap.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterCss.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterHashEntries.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterHtml.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterJScript.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterMulti.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynRegExpr.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynTextDrawer.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynUnicode.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynUsp10.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVBrowser.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVBrowserBase.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVConstants.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Args.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2CompositionController.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Controller.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2ControllerOptions.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2CookieManager.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2CustomSchemeRegistration.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Delegates.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Environment.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2EnvironmentOptions.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Find.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2FindOptions.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2PrintSettings.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Profile.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Settings.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVEvents.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVInterfaces.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVLibFunctions.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVLoader.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVLoaderInternal.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVMiscFunctions.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVTypeLibrary.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVTypes.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVWinControl.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVWindowParent.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLComponentManager.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLDesigner.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLDesignerAI.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLDesignerIcons.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLIDECompat.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLJSONCompat.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLPageProducerAdapter.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLWebAssets.pas create mode 100644 CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLWebView.pas create mode 100644 CORE/Source/Plugins/uRESTDWFMXHTMLEditor.pas create mode 100644 CORE/Source/Plugins/uRESTDWHTMLEditor.pas diff --git a/CORE/Source/Plugins/DMDados/uRESTDWDatamodule.pas b/CORE/Source/Plugins/DMDados/uRESTDWDatamodule.pas index b1640fad9..28eaee09e 100644 --- a/CORE/Source/Plugins/DMDados/uRESTDWDatamodule.pas +++ b/CORE/Source/Plugins/DMDados/uRESTDWDatamodule.pas @@ -1,6 +1,6 @@ unit uRESTDWDatamodule; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/SynEdit.inc b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/SynEdit.inc new file mode 100644 index 000000000..2bfa86ef3 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/SynEdit.inc @@ -0,0 +1,1425 @@ +(******************************************************************************) +(* SynEdit Include File. This file was adapted from Brad Stowers' DFS.INC *) +(* file and used with permission. This will help reduce headaches when new *) +(* versions of Delphi and C++Builder are released, among other things. *) +(******************************************************************************) +(* Brad Stowers: bstowers@pobox.com *) +(* Delphi Free Stuff: http://delphifreestuff.com/ *) +(* February 24, 1999 *) +(******************************************************************************) +(* *) +(* Complete Boolean Evaluation compiler directive is turned off by including *) +(* this file. *) +(* The $ObjExportAll directive is turned on if compiling with C++Builder 3 or *) +(* higher. This is required for Delphi components built in Builder with *) +(* run-time packages. *) +(* *) +(* Here is a brief explanation of what each of the defines mean: *) +(* SYN_WIN32 : Compilation target is 32-bit Windows *) +(* SYN_COMPILER_2 : Delphi 2 or C++Builder 1 is the compiler. *) +(* SYN_COMPILER_2_UP : Delphi 2 or higher, or C++Builder 1 or higher is *) +(* the compiler. *) +(* SYN_COMPILER_3 : Delphi 3 or C++Builder 3 is the compiler. *) +(* SYN_COMPILER_3_UP : Delphi 3 or higher, or C++Builder 3 or higher is *) +(* the compiler. *) +(* SYN_COMPILER_4 : Delphi 4 or C++Builder 4 is the compiler. *) +(* SYN_COMPILER_4_UP : Delphi 4 or higher, or C++Builder 4 or higher is *) +(* the compiler. *) +(* SYN_COMPILER_5 : Delphi 5 or C++Builder 5 is the compiler. *) +(* SYN_COMPILER_5_UP : Delphi 5 or higher, or C++Builder 5 or higher is *) +(* the compiler. *) +(* SYN_COMPILER_6 : Delphi 6, C++Builder 6, Kylix 1 or Kylix 2 is *) +(* the compiler. *) +(* SYN_COMPILER_6_UP : Delphi 6, C++Builder 6, Kylix 1, Kylix 2 or higher *) +(* is the compiler. *) +(* SYN_COMPILER_7 : Delphi 7 or Kylix 3 is the compiler. *) +(* SYN_COMPILER_7_UP : Delphi 7, Kylix 3 or higher is the compiler. *) +(* SYN_COMPILER_9 : Delphi 2005 is the compiler. *) +(* SYN_COMPILER_9_UP : Delphi 2005 or higher is the compiler. *) +(* SYN_COMPILER_10 : Delphi 2006 is the compiler. *) +(* SYN_COMPILER_10_UP : Delphi 2006 or higher is the compiler. *) +(* SYN_COMPILER_11 : Delphi 2007 is the compiler. *) +(* SYN_COMPILER_11_UP : Delphi 2007 or higher is the compiler. *) +(* SYN_COMPILER_12 : Delphi 2009 is the compiler. *) +(* SYN_COMPILER_12_UP : Delphi 2009 or higher is the compiler. *) +(* SYN_COMPILER_14 : Delphi 2010 is the compiler. *) +(* SYN_COMPILER_14_UP : Delphi 2010 or higher is the compiler. *) +(* SYN_COMPILER_15 : Delphi XE is the compiler. *) +(* SYN_COMPILER_15_UP : Delphi XE or higher is the compiler. *) +(* SYN_COMPILER_16 : Delphi XE2 is the compiler. *) +(* SYN_COMPILER_16_UP : Delphi XE2 or higher is the compiler. *) +(* SYN_COMPILER_17 : Delphi XE3 is the compiler. *) +(* SYN_COMPILER_17_UP : Delphi XE3 or higher is the compiler. *) +(* SYN_COMPILER_18 : Delphi XE4 is the compiler. *) +(* SYN_COMPILER_18_UP : Delphi XE4 or higher is the compiler. *) +(* SYN_COMPILER_19 : Delphi XE5 is the compiler. *) +(* SYN_COMPILER_19_UP : Delphi XE5 or higher is the compiler. *) +(* SYN_COMPILER_20 : Delphi XE6 is the compiler. *) +(* SYN_COMPILER_20_UP : Delphi XE6 or higher is the compiler. *) +(* SYN_COMPILER_21 : Delphi XE7 is the compiler. *) +(* SYN_COMPILER_21_UP : Delphi XE7 or higher is the compiler. *) +(* SYN_COMPILER_22 : Delphi XE8 is the compiler. *) +(* SYN_COMPILER_22_UP : Delphi XE8 or higher is the compiler. *) +(* SYN_CPPB : Any version of C++Builder is being used. *) +(* SYN_CPPB_1 : C++B v1.0x is being used. *) +(* SYN_CPPB_3 : C++B v3.0x is being used. *) +(* SYN_CPPB_3_UP : C++B v3.0x or higher is being used. *) +(* SYN_CPPB_4 : C++B v4.0x is being used. *) +(* SYN_CPPB_4_UP : C++B v4.0x or higher is being used. *) +(* SYN_CPPB_5 : C++B v5.0x is being used. *) +(* SYN_CPPB_5_UP : C++B v5.0x or higher is being used. *) +(* SYN_CPPB_6 : C++B v6.0x is being used. *) +(* SYN_CPPB_6_UP : C++B v6.0x or higher is being used. *) +(* SYN_DELPHI : Any version of Delphi is being used. *) +(* SYN_DELPHI_PE : The personal edition of Delphi is being used. *) +(* SYN_DELPHI_2 : Delphi 2 is being used. *) +(* SYN_DELPHI_2_UP : Delphi 2 or higher is being used. *) +(* SYN_DELPHI_3 : Delphi 3 is being used. *) +(* SYN_DELPHI_3_UP : Delphi 3 or higher is being used. *) +(* SYN_DELPHI_4 : Delphi 4 is being used. *) +(* SYN_DELPHI_4_UP : Delphi 4 or higher is being used. *) +(* SYN_DELPHI_5 : Delphi 5 is being used. *) +(* SYN_DELPHI_5_UP : Delphi 5 or higher is being used. *) +(* SYN_DELPHI_6 : Delphi 6 is being used. *) +(* SYN_DELPHI_6_UP : Delphi 6 or higher is being used. *) +(* SYN_DELPHI_7 : Delphi 7 is being used. *) +(* SYN_DELPHI_7_UP : Delphi 7 or higher is being used. *) +(* SYN_DELPHI_8 : Delphi 8 is being used. *) +(* SYN_DELPHI_8_UP : Delphi 8 or higher is being used. *) +(* SYN_DELPHI_2005 : Delphi 2005 is being used. *) +(* SYN_DELPHI_2005_UP : Delphi 2005 or higher is being used. *) +(* SYN_DELPHI_2006 : Delphi 2006 is being used. *) +(* SYN_DELPHI_2006_UP : Delphi 2006 or higher is being used. *) +(* SYN_DELPHI_2007 : Delphi 2007 is being used. *) +(* SYN_DELPHI_2007_UP : Delphi 2007 or higher is being used. *) +(* SYN_DELPHI_2009 : Delphi 2009 is being used. *) +(* SYN_DELPHI_2009_UP : Delphi 2009 or higher is being used. *) +(* SYN_DELPHI_2010 : Delphi 2010 is being used. *) +(* SYN_DELPHI_2010_UP : Delphi 2010 or higher is being used. *) +(* SYN_DELPHI_XE : Delphi XE is being used. *) +(* SYN_DELPHI_XE_UP : Delphi XE or higher is being used. *) +(* SYN_DELPHI_XE2 : Delphi XE2 is being used. *) +(* SYN_DELPHI_XE2_UP : Delphi XE2 or higher is being used. *) +(* SYN_DELPHI_XE3 : Delphi XE3 is being used. *) +(* SYN_DELPHI_XE3_UP : Delphi XE3 or higher is being used. *) +(* SYN_DELPHI_XE4 : Delphi XE4 is being used. *) +(* SYN_DELPHI_XE4_UP : Delphi XE4 or higher is being used. *) +(* SYN_DELPHI_XE5 : Delphi XE5 is being used. *) +(* SYN_DELPHI_XE5_UP : Delphi XE5 or higher is being used. *) +(* SYN_DELPHI_XE6 : Delphi XE6 is being used. *) +(* SYN_DELPHI_XE6_UP : Delphi XE6 or higher is being used. *) +(* SYN_DELPHI_XE7 : Delphi XE7 is being used. *) +(* SYN_DELPHI_XE7_UP : Delphi XE7 or higher is being used. *) +(* SYN_DELPHI_XE8 : Delphi XE8 is being used. *) +(* SYN_DELPHI_XE8_UP : Delphi XE8 or higher is being used. *) +(* SYN_DELPHI_10 : Delphi RX 10 (Seattle) is being used. *) +(* SYN_DELPHI_10_UP : Delphi RX 10 or higher is being used. *) +(* SYN_DELPHI_10_1 : Delphi RX 10.1 (Berlin) is being used. *) +(* SYN_DELPHI_10_1_UP : Delphi RX 10.1 or higher is being used. *) +(* SYN_DELPHI_10_2 : Delphi RX 10.2 (Tokyo) is being used. *) +(* SYN_DELPHI_10_2_UP : Delphi RX 10.2 or higher is being used. *) +(* SYN_DELPHI_10_3 : Delphi RX 10.3 (Rio) is being used. *) +(* SYN_DELPHI_10_3_UP : Delphi RX 10.3 or higher is being used. *) +(* SYN_KYLIX : Kylix 1.0 is being using. *) +(******************************************************************************) + +{$DEFINE SYNEDIT_INCLUDE} + +{------------------------------------------------------------------------------} +{ Common compiler defines } +{ (remove the dot in front of a define to enable it) } +{------------------------------------------------------------------------------} + +{$B-,H+} // defaults are short evaluation of boolean values and long strings + +{.$DEFINE SYN_DEVELOPMENT_CHECKS} // additional tests for debugging +{$IFDEF SYN_DEVELOPMENT_CHECKS} + {$R+,Q+,S+,T+} +{$ENDIF} + +{------------------------------------------------------------------------------} +{ Pull in all defines from SynEditJedi.inc (must be done after the common } +{ compiler defines to work correctly). Use SynEdit-prefix to avoid problems } +{ with other versions of jedi.inc in the search-path. } +{------------------------------------------------------------------------------} + +{$I SynEditJedi.inc} + +{------------------------------------------------------------------------------} +{ SYN_LINUX and SYN_KYLIX defines } +{------------------------------------------------------------------------------} + +{$IFDEF LINUX} + {$DEFINE SYN_LINUX} + {$DEFINE SYN_KYLIX} + {$DEFINE SYN_COMPILER_6} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_6} +{$ENDIF} + +{------------------------------------------------------------------------------} +{ VERXXX to SYN_COMPILERX, SYN_DELPHIX and SYN_CPPBX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF VER370} + {$DEFINE SYN_COMPILER_37} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_13_0} +{$ENDIF} + +{$IFDEF VER360} + {$DEFINE SYN_COMPILER_29} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_12_0} +{$ENDIF} + +{$IFDEF VER350} + {$DEFINE SYN_COMPILER_28} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_11_0} +{$ENDIF} + +{$IFDEF VER340} + {$DEFINE SYN_COMPILER_27} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_10_4} +{$ENDIF} + +{$IFDEF VER330} + {$DEFINE SYN_COMPILER_26} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_10_3} +{$ENDIF} + +{$IFDEF VER320} + {$DEFINE SYN_COMPILER_25} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_10_2} +{$ENDIF} + +{$IFDEF VER310} + {$DEFINE SYN_COMPILER_24} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_10_1} +{$ENDIF} + +{$IFDEF VER300} + {$DEFINE SYN_COMPILER_23} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_10} +{$ENDIF} + +{$IFDEF VER290} + {$DEFINE SYN_COMPILER_22} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_XE8} +{$ENDIF} + +{$IFDEF VER280} + {$DEFINE SYN_COMPILER_21} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_XE7} +{$ENDIF} + +{$IFDEF VER270} + {$DEFINE SYN_COMPILER_20} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_XE6} +{$ENDIF} + +{$IFDEF VER260} + {$DEFINE SYN_COMPILER_19} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_XE5} +{$ENDIF} + +{$IFDEF VER250} + {$DEFINE SYN_COMPILER_18} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_XE4} +{$ENDIF} + +{$IFDEF VER240} + {$DEFINE SYN_COMPILER_17} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_XE3} +{$ENDIF} + +{$IFDEF VER230} + {$DEFINE SYN_COMPILER_16} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_XE2} +{$ENDIF} + +{$IFDEF VER220} + {$DEFINE SYN_COMPILER_15} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_XE} +{$ENDIF} + +{$IFDEF VER210} + {$DEFINE SYN_COMPILER_14} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_2010} +{$ENDIF} + +{$IFDEF VER200} + {$DEFINE SYN_COMPILER_12} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_2009} +{$ENDIF} + +{$IFDEF VER190} + {$DEFINE SYN_COMPILER_11} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_2007} +{$ENDIF} + +{$IFDEF VER180} + {$DEFINE SYN_COMPILER_10} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_2006} +{$ENDIF} + +{$IFDEF VER170} + {$DEFINE SYN_COMPILER_9} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_2005} +{$ENDIF} + +{$IFDEF VER160} + {$DEFINE SYN_COMPILER_8} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_8} +{$ENDIF} + +{$IFDEF VER150} + {$DEFINE SYN_COMPILER_7} + {$IFNDEF BCB} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_7} + {$ELSE} + {.$DEFINE SYN_CPPB} + {.$DEFINE SYN_CPPB_7} + {$ENDIF} +{$ENDIF} + +{$IFDEF VER140} + {$DEFINE SYN_COMPILER_6} + {$IFNDEF BCB} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_6} + {$ELSE} + {$DEFINE SYN_CPPB} + {$DEFINE SYN_CPPB_6} + {$ENDIF} +{$ENDIF} + +{$IFDEF VER130} + {$DEFINE SYN_COMPILER_5} + {$IFNDEF BCB} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_5} + {$ELSE} + {$DEFINE SYN_CPPB} + {$DEFINE SYN_CPPB_5} + {$ENDIF} +{$ENDIF} + +{$IFDEF VER125} + {$DEFINE SYN_COMPILER_4} + {$DEFINE SYN_CPPB} + {$DEFINE SYN_CPPB_4} +{$ENDIF} + +{$IFDEF VER120} + {$DEFINE SYN_COMPILER_4} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_4} +{$ENDIF} + +{$IFDEF VER110} + {$DEFINE SYN_COMPILER_3} + {$DEFINE SYN_CPPB} + {$DEFINE SYN_CPPB_3} +{$ENDIF} + +{$IFDEF VER100} + {$DEFINE SYN_COMPILER_3} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_3} +{$ENDIF} + +{$IFDEF VER93} + {$DEFINE SYN_COMPILER_2} { C++B v1 compiler is really v2 } + {$DEFINE SYN_CPPB} + {$DEFINE SYN_CPPB_1} +{$ENDIF} + +{$IFDEF VER90} + {$DEFINE SYN_COMPILER_2} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_2} +{$ENDIF} + +{$IFDEF SYN_COMPILER_2} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_3} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_4} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_5} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_6} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_7} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_8} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_9} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_10} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_11} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_12} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_14} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_15} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_16} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_17} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_18} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_19} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_20} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_21} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_22} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} + {$DEFINE SYN_COMPILER_22_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_23} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} + {$DEFINE SYN_COMPILER_22_UP} + {$DEFINE SYN_COMPILER_23_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_24} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} + {$DEFINE SYN_COMPILER_22_UP} + {$DEFINE SYN_COMPILER_23_UP} + {$DEFINE SYN_COMPILER_24_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_25} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} + {$DEFINE SYN_COMPILER_22_UP} + {$DEFINE SYN_COMPILER_23_UP} + {$DEFINE SYN_COMPILER_24_UP} + {$DEFINE SYN_COMPILER_25_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_26} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} + {$DEFINE SYN_COMPILER_22_UP} + {$DEFINE SYN_COMPILER_23_UP} + {$DEFINE SYN_COMPILER_24_UP} + {$DEFINE SYN_COMPILER_25_UP} + {$DEFINE SYN_COMPILER_26_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_27} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} + {$DEFINE SYN_COMPILER_22_UP} + {$DEFINE SYN_COMPILER_23_UP} + {$DEFINE SYN_COMPILER_24_UP} + {$DEFINE SYN_COMPILER_25_UP} + {$DEFINE SYN_COMPILER_26_UP} + {$DEFINE SYN_COMPILER_27_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_28} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} + {$DEFINE SYN_COMPILER_22_UP} + {$DEFINE SYN_COMPILER_23_UP} + {$DEFINE SYN_COMPILER_24_UP} + {$DEFINE SYN_COMPILER_25_UP} + {$DEFINE SYN_COMPILER_26_UP} + {$DEFINE SYN_COMPILER_27_UP} + {$DEFINE SYN_COMPILER_28_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_29} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} + {$DEFINE SYN_COMPILER_22_UP} + {$DEFINE SYN_COMPILER_23_UP} + {$DEFINE SYN_COMPILER_24_UP} + {$DEFINE SYN_COMPILER_25_UP} + {$DEFINE SYN_COMPILER_26_UP} + {$DEFINE SYN_COMPILER_27_UP} + {$DEFINE SYN_COMPILER_28_UP} + {$DEFINE SYN_COMPILER_29_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_37} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} + {$DEFINE SYN_COMPILER_22_UP} + {$DEFINE SYN_COMPILER_23_UP} + {$DEFINE SYN_COMPILER_24_UP} + {$DEFINE SYN_COMPILER_25_UP} + {$DEFINE SYN_COMPILER_26_UP} + {$DEFINE SYN_COMPILER_27_UP} + {$DEFINE SYN_COMPILER_28_UP} + {$DEFINE SYN_COMPILER_29_UP} + {$DEFINE SYN_COMPILER_37_UP} +{$ENDIF} + + +{$IFDEF SYN_DELPHI_2} + {$DEFINE SYN_DELPHI_2_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_3} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_4} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_5} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_6} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_7} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_8} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_2005} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_2006} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_2007} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_2009} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_2010} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_XE} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_XE2} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_XE3} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_XE4} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_XE5} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_XE6} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_XE7} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_XE8} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} + {$DEFINE SYN_DELPHI_XE8_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_10} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} + {$DEFINE SYN_DELPHI_XE8_UP} + {$DEFINE SYN_DELPHI_10_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_10_1} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} + {$DEFINE SYN_DELPHI_XE8_UP} + {$DEFINE SYN_DELPHI_10_1_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_10_2} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} + {$DEFINE SYN_DELPHI_XE8_UP} + {$DEFINE SYN_DELPHI_10_1_UP} + {$DEFINE SYN_DELPHI_10_2_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_10_3} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} + {$DEFINE SYN_DELPHI_XE8_UP} + {$DEFINE SYN_DELPHI_10_1_UP} + {$DEFINE SYN_DELPHI_10_2_UP} + {$DEFINE SYN_DELPHI_10_3_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_10_4} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} + {$DEFINE SYN_DELPHI_XE8_UP} + {$DEFINE SYN_DELPHI_10_1_UP} + {$DEFINE SYN_DELPHI_10_2_UP} + {$DEFINE SYN_DELPHI_10_3_UP} + {$DEFINE SYN_DELPHI_10_4_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_11_0} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} + {$DEFINE SYN_DELPHI_XE8_UP} + {$DEFINE SYN_DELPHI_10_1_UP} + {$DEFINE SYN_DELPHI_10_2_UP} + {$DEFINE SYN_DELPHI_10_3_UP} + {$DEFINE SYN_DELPHI_10_4_UP} + {$DEFINE SYN_DELPHI_11_0_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_12_0} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} + {$DEFINE SYN_DELPHI_XE8_UP} + {$DEFINE SYN_DELPHI_10_1_UP} + {$DEFINE SYN_DELPHI_10_2_UP} + {$DEFINE SYN_DELPHI_10_3_UP} + {$DEFINE SYN_DELPHI_10_4_UP} + {$DEFINE SYN_DELPHI_11_0_UP} + {$DEFINE SYN_DELPHI_12_0_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_13_0} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} + {$DEFINE SYN_DELPHI_XE8_UP} + {$DEFINE SYN_DELPHI_10_1_UP} + {$DEFINE SYN_DELPHI_10_2_UP} + {$DEFINE SYN_DELPHI_10_3_UP} + {$DEFINE SYN_DELPHI_10_4_UP} + {$DEFINE SYN_DELPHI_11_0_UP} + {$DEFINE SYN_DELPHI_12_0_UP} + {$DEFINE SYN_DELPHI_13_0_UP} +{$ENDIF} + +{$IFDEF SYN_CPPB_6} + {$DEFINE SYN_CPPB_3_UP} + {$DEFINE SYN_CPPB_4_UP} + {$DEFINE SYN_CPPB_5_UP} + {$DEFINE SYN_CPPB_6_UP} +{$ENDIF} + +{$IFDEF SYN_CPPB_3} + {$DEFINE SYN_CPPB_3_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_3_UP} + {$DEFINE SYN_NO_COM_CLEANUP} +{$ENDIF} + +{$IFDEF SYN_CPPB_3_UP} + // C++Builder requires this if you use Delphi components in run-time packages. + {$ObjExportAll On} +{$ENDIF} + +{------------------------------------------------------------------------------} +{ MSWINDOWS and SYN_WIN32 } +{------------------------------------------------------------------------------} + +{$IFDEF SYN_KYLIX} + Kylix is no longer supported. Please refer to the branch 'Kylix' +{$ELSE} + {$IFNDEF SYN_COMPILER_16_UP} + {$DEFINE MSWINOWS} + {$ENDIF} + {$DEFINE SYN_WIN32} // deprecated, do not use +{$ENDIF} + +{------------------------------------------------------------------------------} +{ Please change this to suit your needs (to activate an option remove the dot } +{ in front of a DEFINE) } +{------------------------------------------------------------------------------} + +// "Heredoc" syntax highlighting +// If you enable the following statement and use highlighter(s) that have +// support for "Heredoc" strings as scheme(s) in SynMultiSyn, you must +// implement your own SynMultiSyn OnCustomRange event handler in order to +// properly store Range State information +{.$DEFINE SYN_HEREDOC} + +// Define OWN_UnicodeString_MEMMGR to speed up WideStrings-handling +{$IFDEF MSWINOWS} + {$IFNDEF UNICODE} + {$DEFINE OWN_UnicodeString_MEMMGR} + {$ENDIF} +{$ENDIF} + +// Turn this off if you don't need complex script support, since it is slower +{-$DEFINE SYN_UNISCRIBE} + +// Code Folding +{$IFDEF SYN_DELPHI_XE_UP} + {$DEFINE SYN_CodeFolding} +{$ENDIF} diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEdit.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEdit.pas new file mode 100644 index 000000000..194b43c74 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEdit.pas @@ -0,0 +1,11958 @@ +{------------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: uRESTDWPrivSynEdit.pas, released 2000-04-07. +The Original Code is based on mwCustomEdit.pas by Martin Waldenburg, part of +the mwEdit component suite. +Portions created by Martin Waldenburg are Copyright (C) 1998 Martin Waldenburg. +Unicode translation by Maël Hörz. +All Rights Reserved. + +Contributors to the uRESTDWPrivSynEdit and mwEdit projects are listed in the +Contributors.txt file. + +Alternatively, the contents of this file may be used under the terms of the +GNU General Public License Version 2 or later (the "GPL"), in which case +the provisions of the GPL are applicable instead of those above. +If you wish to allow use of your version of this file only under the terms +of the GPL and not to allow others to use your version of this file +under the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the GPL. +If you do not delete the provisions above, a recipient may use your version +of this file under either the MPL or the GPL. + +$Id: uRESTDWPrivSynEdit.pas,v 1.32.1 2012/19/09 10:50:00 CodehunterWorks Exp $ + +You may retrieve the latest version of this file at the uRESTDWPrivSynEdit home page, +located at http://uRESTDWPrivSynEdit.SourceForge.net + +Known Issues: +- Undo is buggy when dealing with Hard Tabs (when inserting text after EOL and + when trimming). + +-------------------------------------------------------------------------------} +//todo: remove uRESTDWPrivSynEdit Clipboard Format? +//todo: in WordWrap mode, parse lines only once in PaintLines() +//todo: Remove checks for WordWrap. Must abstract the behaviour with the plugins instead. +//todo: Move WordWrap glyph to the WordWrap plugin. +//todo: remove FShowSpecChar variable +//todo: remove the several Undo block types? + +unit uRESTDWPrivSynEdit; + +{$I uRESTDWPrivSynEdit.inc} + +interface + +uses + Controls, + Contnrs, + Graphics, + Forms, + StdCtrls, + ExtCtrls, + Windows, + Messages, + {$IFDEF SYN_COMPILER_4_UP} + StdActns, + Dialogs, + {$ENDIF} + {$IFDEF SYN_COMPILER_7} + Themes, + {$ENDIF} + {$IFDEF SYN_COMPILER_17_UP} + Types, UITypes, + {$ENDIF} + Imm, + uRESTDWPrivSynUnicode, + uRESTDWPrivSynTextDrawer, + uRESTDWPrivSynEditTypes, + uRESTDWPrivSynEditKeyConst, + uRESTDWPrivSynEditMiscProcs, + uRESTDWPrivSynEditMiscClasses, + uRESTDWPrivSynEditTextBuffer, + uRESTDWPrivSynEditKeyCmds, + uRESTDWPrivSynEditHighlighter, + uRESTDWPrivSynEditKbdHandler, +{$IFDEF SYN_CodeFolding} + uRESTDWPrivSynEditCodeFolding, +{$ENDIF} +{$IFDEF UNICODE} + WideStrUtils, +{$ENDIF} + Math, + SysUtils, + Classes; + +const +{$IFNDEF SYN_COMPILER_3_UP} + // not defined in all Delphi versions + WM_MOUSEWHEEL = $020A; +{$ENDIF} +{$IFNDEF SYN_COMPILER_7_UP} + // not defined in all Delphi versions + WS_EX_COMPOSITED = $02000000; +{$ENDIF} + + // maximum scroll range + MAX_SCROLL = 32767; + + // Max number of book/gutter marks returned from GetEditMarksForLine - that + // really should be enough. + MAX_MARKS = 16; + + SYNEDIT_CLIPBOARD_FORMAT = 'uRESTDWPrivSynEdit Control Block Type'; + + // Reconversion string. + IMR_COMPOSITIONWINDOW = $0001; + IMR_CANDIDATEWINDOW = $0002; + IMR_COMPOSITIONFONT = $0003; + IMR_RECONVERTSTRING = $0004; + IMR_CONFIRMRECONVERTSTRING = $0005; + IMR_QUERYCHARPOSITION = $0006; + IMR_DOCUMENTFEED = $0007; + + SCS_SETSTR = GCS_COMPREADSTR or GCS_COMPSTR; + SCS_CHANGEATTR = GCS_COMPREADATTR or GCS_COMPATTR; + SCS_CHANGECLAUSE = GCS_COMPREADCLAUSE or GCS_COMPCLAUSE; + SCS_SETRECONVERTSTRING = $00010000; + SCS_QUERYRECONVERTSTRING = $00020000; + +var + SynEditClipboardFormat: UINT; + +type + TBufferCoord = uRESTDWPrivSynEditTypes.TBufferCoord; + TDisplayCoord = uRESTDWPrivSynEditTypes.TDisplayCoord; + + TSynBorderStyle = TBorderStyle; + + TSynReplaceAction = (raCancel, raSkip, raReplace, raReplaceAll); + + ESynEditError = class(ESynError); + + TDropFilesEvent = procedure(Sender: TObject; X, Y: Integer; AFiles: TUnicodeStrings) + of object; + + THookedCommandEvent = procedure(Sender: TObject; AfterProcessing: Boolean; + var Handled: Boolean; var Command: TSynEditorCommand; var AChar: WideChar; + Data, HandlerData: Pointer) of object; + + TPaintEvent = procedure(Sender: TObject; ACanvas: TCanvas) of object; + + TProcessCommandEvent = procedure(Sender: TObject; + var Command: TSynEditorCommand; var AChar: WideChar; Data: Pointer) of object; + + TReplaceTextEvent = procedure(Sender: TObject; const ASearch, AReplace: + UnicodeString; Line, Column: Integer; var Action: TSynReplaceAction) of object; + + TSpecialLineColorsEvent = procedure(Sender: TObject; Line: Integer; + var Special: Boolean; var FG, BG: TColor) of object; + TSpecialTokenAttributesEvent = procedure(Sender: TObject; ALine, APos: Integer; const AToken: string; + var ASpecial: Boolean; var FG, BG: TColor; var AStyle: TFontStyles) of object; + + TTransientType = (ttBefore, ttAfter); + TPaintTransient = procedure(Sender: TObject; Canvas: TCanvas; + TransientType: TTransientType) of object; + + TScrollEvent = procedure(Sender: TObject; ScrollBar: TScrollBarKind) of object; + + TGutterGetTextEvent = procedure(Sender: TObject; aLine: Integer; + var aText: UnicodeString) of object; + + TGutterPaintEvent = procedure(Sender: TObject; aLine: Integer; + X, Y: Integer) of object; + + TSynEditCaretType = (ctVerticalLine, ctHorizontalLine, ctHalfBlock, ctBlock, ctVerticalLine2); + + TSynStateFlag = (sfCaretChanged, sfScrollbarChanged, sfLinesChanging, + sfIgnoreNextChar, sfCaretVisible, sfDblClicked, sfPossibleGutterClick, + sfWaitForDragging, sfInsideRedo, sfGutterDragging, sfMouseCaptured); + + TSynStateFlags = set of TSynStateFlag; + + TScrollHintFormat = (shfTopLineOnly, shfTopToBottom); + + TSynHintMode = (shmDefault, shmToken); + + TGetTokenHintEvent = procedure(Sender: TObject; Coords: TBufferCoord; const Token: string; + TokenType: Integer; Attri: TSynHighlighterAttributes; var HintText: string) of object; + + TSynEditorOption = ( + eoAltSetsColumnMode, //Holding down the Alt Key will put the selection mode into columnar format + eoAutoIndent, //Will indent the caret on new lines with the same amount of leading white space as the preceding line + eoAutoSizeMaxScrollWidth, //Automatically resizes the MaxScrollWidth property when inserting text + eoDisableScrollArrows, //Disables the scroll bar arrow buttons when you can't scroll in that direction any more + eoDragDropEditing, //Allows you to select a block of text and drag it within the document to another location + eoDropFiles, //Allows the editor accept OLE file drops + eoEnhanceHomeKey, //enhances home key positioning, similar to visual studio + eoEnhanceEndKey, //enhances End key positioning, similar to JDeveloper + eoGroupUndo, //When undoing/redoing actions, handle all continous changes of the same kind in one call instead undoing/redoing each command separately + eoHalfPageScroll, //When scrolling with page-up and page-down commands, only scroll a half page at a time + eoHideShowScrollbars, //if enabled, then the scrollbars will only show when necessary. If you have ScrollPastEOL, then it the horizontal bar will always be there (it uses MaxLength instead) + eoKeepCaretX, //When moving through lines w/o Cursor Past EOL, keeps the X position of the cursor + eoNoCaret, //Makes it so the caret is never visible + eoNoSelection, //Disables selecting text + eoRightMouseMovesCursor, //When clicking with the right mouse for a popup menu, move the cursor to that location + eoScrollByOneLess, //Forces scrolling to be one less + eoScrollHintFollows, //The scroll hint follows the mouse when scrolling vertically + eoScrollPastEof, //Allows the cursor to go past the end of file marker + eoScrollPastEol, //Allows the cursor to go past the last character into the white space at the end of a line + eoShowScrollHint, //Shows a hint of the visible line numbers when scrolling vertically + eoShowSpecialChars, //Shows the special Characters + eoSmartTabDelete, //similar to Smart Tabs, but when you delete characters + eoSmartTabs, //When tabbing, the cursor will go to the next non-white space character of the previous line + eoSpecialLineDefaultFg, //disables the foreground text color override when using the OnSpecialLineColor event + eoTabIndent, //When active and act as block indent, unindent when text is selected + eoTabsToSpaces, //Converts a tab character to a specified number of space characters + eoTrimTrailingSpaces //Spaces at the end of lines will be trimmed and not saved + ); + + TSynEditorOptions = set of TSynEditorOption; + + TSynFontSmoothMethod = (fsmNone, fsmAntiAlias, fsmClearType); + +const + SYNEDIT_DEFAULT_OPTIONS = [eoAutoIndent, eoDragDropEditing, eoEnhanceEndKey, + eoScrollPastEol, eoShowScrollHint, eoSmartTabs, eoTabsToSpaces, + eoSmartTabDelete, eoGroupUndo]; + +type + TCreateParamsW = record + Caption: PWideChar; + Style: DWORD; + ExStyle: DWORD; + X, Y: Integer; + Width, Height: Integer; + WndParent: HWnd; + Param: Pointer; + WindowClass: TWndClassW; + WinClassName: array[0..63] of WideChar; + InternalCaption: UnicodeString; + end; + +type +// use scAll to update a statusbar when another TCustomSynEdit got the focus + TSynStatusChange = (scAll, scCaretX, scCaretY, scLeftChar, scTopLine, + scInsertMode, scModified, scSelection, scReadOnly); + TSynStatusChanges = set of TSynStatusChange; + + TContextHelpEvent = procedure(Sender: TObject; Word: UnicodeString) + of object; + + TStatusChangeEvent = procedure(Sender: TObject; Changes: TSynStatusChanges) + of object; + + TMouseCursorEvent = procedure(Sender: TObject; const aLineCharPos: TBufferCoord; + var aCursor: TCursor) of object; + +{$IFDEF SYN_CodeFolding} + TScanForFoldRangesEvent = procedure(Sender: TObject; + FoldRanges: TSynFoldRanges; LinesToScan: TStrings; + FromLine : Integer; ToLine : Integer) of object; +{$ENDIF} + + TCustomSynEdit = class; + + TSynEditMark = class + protected + FLine, FChar, FImage: Integer; + FEdit: TCustomSynEdit; + FVisible: Boolean; + FInternalImage: Boolean; + FBookmarkNum: Integer; + function GetEdit: TCustomSynEdit; virtual; + procedure SetChar(const Value: Integer); virtual; + procedure SetImage(const Value: Integer); virtual; + procedure SetLine(const Value: Integer); virtual; + procedure SetVisible(const Value: Boolean); + procedure SetInternalImage(const Value: Boolean); + function GetIsBookmark: Boolean; + public + constructor Create(AOwner: TCustomSynEdit); + property Line: Integer read FLine write SetLine; + property Char: Integer read FChar write SetChar; + property Edit: TCustomSynEdit read FEdit; + property ImageIndex: Integer read FImage write SetImage; + property BookmarkNumber: Integer read FBookmarkNum write FBookmarkNum; + property Visible: Boolean read FVisible write SetVisible; + property InternalImage: Boolean read FInternalImage write SetInternalImage; + property IsBookmark: Boolean read GetIsBookmark; + end; + + TPlaceMarkEvent = procedure(Sender: TObject; var Mark: TSynEditMark) + of object; + + TSynEditMarks = array[1..MAX_MARKS] of TSynEditMark; + + { A list of mark objects. Each object cause a litle picture to be drawn in the gutter. } + TSynEditMarkList = class(TObjectList) // It makes more sence to derive from TObjectList, + protected // as it automatically frees its members + FEdit: TCustomSynEdit; + FOnChange: TNotifyEvent; + procedure Notify(Ptr: Pointer; Action: TListNotification); override; + function GetItem(Index: Integer): TSynEditMark; + procedure SetItem(Index: Integer; Item: TSynEditMark); + property OwnsObjects; // This is to hide the inherited property, + public // because TSynEditMarkList always owns the marks + constructor Create(AOwner: TCustomSynEdit); + function First: TSynEditMark; + function Last: TSynEditMark; + function Extract(Item: TSynEditMark): TSynEditMark; + procedure ClearLine(line: Integer); + procedure GetMarksForLine(line: Integer; var Marks: TSynEditMarks); + procedure Place(mark: TSynEditMark); + public + property Items[Index: Integer]: TSynEditMark read GetItem write SetItem; default; + property Edit: TCustomSynEdit read FEdit; + property OnChange: TNotifyEvent read FOnChange write FOnChange; + end; + + TGutterClickEvent = procedure(Sender: TObject; Button: TMouseButton; + X, Y, Line: Integer; Mark: TSynEditMark) of object; + + // aIndex parameters of Line notifications are 0-based. + // aRow parameter of GetRowLength() is 1-based. + ISynEditBufferPlugin = interface + // conversion methods + function BufferToDisplayPos(const aPos: TBufferCoord): TDisplayCoord; + function DisplayToBufferPos(const aPos: TDisplayCoord): TBufferCoord; + function RowCount: Integer; + function GetRowLength(aRow: Integer): Integer; + // plugin notifications + function LinesInserted(aIndex: Integer; aCount: Integer): Integer; + function LinesDeleted(aIndex: Integer; aCount: Integer): Integer; + function LinesPutted(aIndex: Integer; aCount: Integer): Integer; + // font or size change + procedure DisplayChanged; + // pretty clear, heh? + procedure Reset; + end; + + TSynEditPlugin = class(TObject) + private + FOwner: TCustomSynEdit; + protected + procedure AfterPaint(ACanvas: TCanvas; const AClip: TRect; + FirstLine, LastLine: Integer); virtual; + procedure PaintTransient(ACanvas: TCanvas; ATransientType: TTransientType); virtual; + procedure LinesInserted(FirstLine, Count: Integer); virtual; + procedure LinesDeleted(FirstLine, Count: Integer); virtual; + protected + property Editor: TCustomSynEdit read FOwner; + public + constructor Create(AOwner: TCustomSynEdit); + destructor Destroy; override; + end; + +{$IFDEF SYN_COMPILER_6_UP} + TCustomSynEditSearchNotFoundEvent = procedure(Sender: TObject; + FindText: UnicodeString) of object; +{$ENDIF} + + // Reconversion string. + PReconvertString = ^TReconvertString; + TReconvertString = record + dwSize: DWord; + dwVersion: DWord; + dwStrLen: DWord; + dwStrOffset: DWord; + dwCompStrLen: DWord; + dwCompStrOffset: DWord; + dwTargetStrLen: DWord; + dwTargetStrOffset: DWord; + end; + + + TCustomSynEdit = class(TCustomControl) + private + procedure CMHintShow(var Msg: TMessage); message CM_HINTSHOW; + procedure WMCancelMode(var Message: TMessage); message WM_CANCELMODE; + procedure WMCaptureChanged(var Msg: TMessage); message WM_CAPTURECHANGED; + procedure WMChar(var Msg: TWMChar); message WM_CHAR; + procedure WMClear(var Msg: TMessage); message WM_CLEAR; + procedure WMCopy(var Message: TMessage); message WM_COPY; + procedure WMCut(var Message: TMessage); message WM_CUT; + procedure WMDropFiles(var Msg: TMessage); message WM_DROPFILES; + procedure WMDestroy(var Message: TWMDestroy); message WM_DESTROY; + procedure WMEraseBkgnd(var Msg: TMessage); message WM_ERASEBKGND; + procedure WMGetDlgCode(var Msg: TWMGetDlgCode); message WM_GETDLGCODE; + procedure WMGetText(var Msg: TWMGetText); message WM_GETTEXT; + procedure WMGetTextLength(var Msg: TWMGetTextLength); message WM_GETTEXTLENGTH; + procedure WMHScroll(var Msg: TWMScroll); message WM_HSCROLL; + procedure WMPaste(var Message: TMessage); message WM_PASTE; + procedure WMSetText(var Msg: TWMSetText); message WM_SETTEXT; + procedure WMImeChar(var Msg: TMessage); message WM_IME_CHAR; + procedure WMImeComposition(var Msg: TMessage); message WM_IME_COMPOSITION; + procedure WMImeNotify(var Msg: TMessage); message WM_IME_NOTIFY; + procedure WMImeRequest(var Message: TMessage); message WM_IME_REQUEST; + procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS; + procedure WMSetCursor(var Msg: TWMSetCursor); message WM_SETCURSOR; + procedure WMSetFocus(var Msg: TWMSetFocus); message WM_SETFOCUS; + procedure WMSize(var Msg: TWMSize); message WM_SIZE; + procedure WMUndo(var Msg: TMessage); message WM_UNDO; + procedure WMVScroll(var Msg: TWMScroll); message WM_VSCROLL; +{$IFNDEF SYN_COMPILER_6_UP} + procedure WMMouseWheel(var Msg: TMessage); message WM_MOUSEWHEEL; +{$ENDIF} + private +{$IFDEF SYN_CodeFolding} + fUseCodeFolding : Boolean; + fCodeFolding: TSynCodeFolding; + fAllFoldRanges: TSynFoldRanges; +{$ENDIF} + FAlwaysShowCaret: Boolean; + FBlockBegin: TBufferCoord; + FBlockEnd: TBufferCoord; + FCaretX: Integer; + FLastCaretX: Integer; + FCaretY: Integer; + FCharsInWindow: Integer; + FCharWidth: Integer; + FFontDummy: TFont; + FFontSmoothing: TSynFontSmoothMethod; + FHintMode: TSynHintMode; + FInserting: Boolean; + FLines: TUnicodeStrings; + FOrigLines: TUnicodeStrings; + FOrigUndoList: TSynEditUndoList; + FOrigRedoList: TSynEditUndoList; + FLinesInWindow: Integer; + FLeftChar: Integer; + FMaxScrollWidth: Integer; + FPaintLock: Integer; + FReadOnly: Boolean; + FRightEdge: Integer; + FRightEdgeColor: TColor; + FScrollHintColor: TColor; + FScrollHintFormat: TScrollHintFormat; + FScrollBars: TScrollStyle; + FTextHeight: Integer; + FTextOffset: Integer; + FTopLine: Integer; + FHighlighter: TSynCustomHighlighter; + FSelectedColor: TSynSelectedColor; + FActiveLineColor: TColor; + FUndoList: TSynEditUndoList; + FRedoList: TSynEditUndoList; + FBookMarks: array[0..9] of TSynEditMark; // these are just references, FMarkList is the owner + FMouseDownX: Integer; + FMouseDownY: Integer; + FBookMarkOpt: TSynBookMarkOpt; + FBorderStyle: TSynBorderStyle; + FHideSelection: Boolean; + FMouseWheelAccumulator: Integer; + FOverwriteCaret: TSynEditCaretType; + FInsertCaret: TSynEditCaretType; + FCaretOffset: TPoint; + FKeyStrokes: TSynEditKeyStrokes; + FModified: Boolean; + FMarkList: TSynEditMarkList; + FExtraLineSpacing: Integer; + FSelectionMode: TSynSelectionMode; + FActiveSelectionMode: TSynSelectionMode; //mode of the active selection + FWantReturns: Boolean; + FWantTabs: Boolean; + FWordWrapPlugin: ISynEditBufferPlugin; + FWordWrapGlyph: TSynGlyph; + FCaretAtEOL: Boolean; // used by wordwrap + + FGutter: TSynGutter; + FTabWidth: Integer; + FTextDrawer: TSynTextDrawer; + FInvalidateRect: TRect; + FStateFlags: TSynStateFlags; + FOptions: TSynEditorOptions; + FStatusChanges: TSynStatusChanges; + FLastKey: Word; + FLastShiftState: TShiftState; + FSearchEngine: TSynEditSearchCustom; + FHookedCommandHandlers: TObjectList; + FKbdHandler: TSynEditKbdHandler; + FFocusList: TList; + FPlugins: TObjectList; + FScrollTimer: TTimer; + FScrollDeltaX, fScrollDeltaY: Integer; + // event handlers + FOnChange: TNotifyEvent; + FOnClearMark: TPlaceMarkEvent; + FOnCommandProcessed: TProcessCommandEvent; + FOnDropFiles: TDropFilesEvent; + FOnGutterClick: TGutterClickEvent; + FOnKeyPressW: TKeyPressWEvent; + FOnMouseCursor: TMouseCursorEvent; + FOnPaint: TPaintEvent; + FOnPlaceMark: TPlaceMarkEvent; + FOnProcessCommand: TProcessCommandEvent; + FOnProcessUserCommand: TProcessCommandEvent; + FOnReplaceText: TReplaceTextEvent; + FOnSpecialLineColors: TSpecialLineColorsEvent; + FOnSpecialTokenAttributes: TSpecialTokenAttributesEvent; + FOnContextHelp: TContextHelpEvent; + FOnPaintTransient: TPaintTransient; + FOnScroll: TScrollEvent; + FOnTokenHint: TGetTokenHintEvent; + FOnGutterGetText: TGutterGetTextEvent; + FOnGutterPaint: TGutterPaintEvent; + FOnStatusChange: TStatusChangeEvent; +{$IFDEF SYN_CodeFolding} + fOnScanForFoldRanges : TScanForFoldRangesEvent; +{$ENDIF} + + FShowSpecChar: Boolean; + FPaintTransientLock: Integer; + FIsScrolling: Boolean; + + FChainListCleared: TNotifyEvent; + FChainListDeleted: TStringListChangeEvent; + FChainListInserted: TStringListChangeEvent; + FChainListPutted: TStringListChangeEvent; + FChainLinesChanging: TNotifyEvent; + FChainLinesChanged: TNotifyEvent; + FChainedEditor: TCustomSynEdit; + FChainUndoAdded: TNotifyEvent; + FChainRedoAdded: TNotifyEvent; + + FAdditionalWordBreakChars: TSysCharSet; + FAdditionalIdentChars: TSysCharSet; + +{$IFDEF SYN_COMPILER_6_UP} + FSearchNotFound: TCustomSynEditSearchNotFoundEvent; + FOnFindBeforeSearch: TNotifyEvent; + FOnReplaceBeforeSearch: TNotifyEvent; + FOnCloseBeforeSearch: TNotifyEvent; + FSelStartBeforeSearch: Integer; + FSelLengthBeforeSearch: Integer; +{$ENDIF} + + FWindowProducedMessage: Boolean; + +{$IFDEF SYN_LINUX} + FDeadKeysFixed: Boolean; +{$ENDIF} + +{$IFDEF SYN_CodeFolding} + procedure ReScanForFoldRanges(FromLine : Integer; ToLine : Integer); + procedure FullFoldScan; + procedure ScanForFoldRanges(FoldRanges: TSynFoldRanges; + LinesToScan: TStrings; FromLine : Integer; ToLine : Integer); +{$ENDIF} + procedure BookMarkOptionsChanged(Sender: TObject); + procedure ComputeCaret(X, Y: Integer); + procedure ComputeScroll(X, Y: Integer); + procedure DoHomeKey(Selection: Boolean); + procedure DoEndKey(Selection: Boolean); + procedure DoLinesDeleted(FirstLine, Count: Integer); + procedure DoLinesInserted(FirstLine, Count: Integer); + procedure DoShiftTabKey; + procedure DoTabKey; + procedure DoCaseChange(const Cmd : TSynEditorCommand); + function FindHookedCmdEvent(AHandlerProc: THookedCommandEvent): Integer; + procedure SynFontChanged(Sender: TObject); + function GetBlockBegin: TBufferCoord; + function GetBlockEnd: TBufferCoord; + function GetCanPaste: Boolean; + function GetCanRedo: Boolean; + function GetCanUndo: Boolean; + function GetCaretXY: TBufferCoord; + function GetDisplayX: Integer; + function GetDisplayY: Integer; + function GetDisplayXY: TDisplayCoord; + function GetDisplayLineCount: Integer; + function GetFont: TFont; + function GetHookedCommandHandlersCount: Integer; + function GetLineText: UnicodeString; + function GetMaxUndo: Integer; + function GetOptions: TSynEditorOptions; + function GetSelAvail: Boolean; + function GetSelTabBlock: Boolean; + function GetSelTabLine: Boolean; + function GetSelText: UnicodeString; + function SynGetText: UnicodeString; + function GetWordAtCursor: UnicodeString; + function GetWordAtMouse: UnicodeString; + function GetWordWrap: Boolean; + procedure GutterChanged(Sender: TObject); + function LeftSpaces(const Line: UnicodeString): Integer; + function LeftSpacesEx(const Line: UnicodeString; WantTabs: Boolean; CalcAlways : Boolean = False): Integer; + function GetLeftSpacing(CharCount: Integer; WantTabs: Boolean): UnicodeString; + procedure LinesChanging(Sender: TObject); + procedure MoveCaretAndSelection(const ptBefore, ptAfter: TBufferCoord; + SelectionCommand: Boolean); + procedure MoveCaretHorz(DX: Integer; SelectionCommand: Boolean); + procedure MoveCaretVert(DY: Integer; SelectionCommand: Boolean); + procedure PluginsAfterPaint(ACanvas: TCanvas; const AClip: TRect; + FirstLine, LastLine: Integer); + procedure ReadAddedKeystrokes(Reader: TReader); + procedure ReadRemovedKeystrokes(Reader: TReader); + function ScanFrom(Index: Integer): Integer; + procedure ScrollTimerHandler(Sender: TObject); + procedure SelectedColorsChanged(Sender: TObject); + procedure SetAdditionalIdentChars(const Value: TSysCharSet); + procedure SetAdditionalWordBreakChars(const Value: TSysCharSet); + procedure SetBlockBegin(Value: TBufferCoord); + procedure SetBlockEnd(Value: TBufferCoord); + procedure SetBorderStyle(Value: TSynBorderStyle); + procedure SetCaretX(Value: Integer); + procedure SetCaretY(Value: Integer); + procedure InternalSetCaretX(Value: Integer); + procedure InternalSetCaretY(Value: Integer); + procedure SetInternalDisplayXY(const aPos: TDisplayCoord); + procedure SetActiveLineColor(Value: TColor); + procedure SetExtraLineSpacing(const Value: Integer); + procedure SetFont(const Value: TFont); + procedure SetGutter(const Value: TSynGutter); + procedure SetGutterWidth(Value: Integer); + procedure SetHideSelection(const Value: Boolean); + procedure SetHighlighter(const Value: TSynCustomHighlighter); + procedure SetInsertCaret(const Value: TSynEditCaretType); + procedure SetInsertMode(const Value: Boolean); + procedure SetKeystrokes(const Value: TSynEditKeyStrokes); + procedure SetLeftChar(Value: Integer); + procedure SetLines(Value: TUnicodeStrings); + procedure SetLineText(Value: UnicodeString); + procedure SetMaxScrollWidth(Value: Integer); + procedure SetMaxUndo(const Value: Integer); + procedure SetModified(Value: Boolean); + procedure SetOptions(Value: TSynEditorOptions); + procedure SetOverwriteCaret(const Value: TSynEditCaretType); + procedure SetRightEdge(Value: Integer); + procedure SetRightEdgeColor(Value: TColor); + procedure SetScrollBars(const Value: TScrollStyle); + procedure SetSearchEngine(Value: TSynEditSearchCustom); + procedure SetSelectionMode(const Value: TSynSelectionMode); + procedure SetActiveSelectionMode(const Value: TSynSelectionMode); + procedure SetSelTextExternal(const Value: UnicodeString); + procedure SetTabWidth(Value: Integer); + procedure SynSetText(const Value: UnicodeString); + procedure SetTopLine(Value: Integer); + procedure SetWordWrap(const Value: Boolean); + procedure SetWordWrapGlyph(const Value: TSynGlyph); + procedure WordWrapGlyphChange(Sender: TObject); + procedure SizeOrFontChanged(bFont: Boolean); + procedure ProperSetLine(ALine: Integer; const ALineText: UnicodeString); + procedure UpdateModifiedStatus; + procedure UndoRedoAdded(Sender: TObject); + procedure UpdateLastCaretX; + procedure UpdateScrollBars; + procedure WriteAddedKeystrokes(Writer: TWriter); + procedure WriteRemovedKeystrokes(Writer: TWriter); + +{$IFDEF SYN_COMPILER_6_UP} + procedure DoSearchFindFirstExecute(Action: TSearchFindFirst); + procedure DoSearchFindExecute(Action: TSearchFind); + procedure DoSearchReplaceExecute(Action: TSearchReplace); + procedure DoSearchFindNextExecute(Action: TSearchFindNext); + procedure FindDialogFindFirst(Sender: TObject); + procedure FindDialogFind(Sender: TObject); + function SearchByFindDialog(FindDialog: TFindDialog) : bool; + procedure FindDialogClose(Sender: TObject); +{$ENDIF} +{$IFDEF SYN_CodeFolding} + procedure SetUseCodeFolding(const Value: Boolean); + procedure OnCodeFoldingChange(Sender: TObject); + function GetCollapseMarkRect(Row: Integer; Line: Integer = -1): TRect; + function GetFoldShapeRect(Row: Integer): TRect; +{$ENDIF} + protected + FIgnoreNextChar: Boolean; + FCharCodeString: string; +{$IFDEF SYN_COMPILER_6_UP} + function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; + MousePos: TPoint): Boolean; override; +{$ENDIF} + procedure CreateParams(var Params: TCreateParams); override; + procedure CreateWnd; override; + procedure DestroyWnd; override; + procedure InvalidateRect(const aRect: TRect; aErase: Boolean); virtual; + procedure DblClick; override; + procedure DecPaintLock; + procedure DefineProperties(Filer: TFiler); override; + procedure DoChange; virtual; + procedure DoKeyPressW(var Message: TWMKey); + procedure DragCanceled; override; + procedure DragOver(Source: TObject; X, Y: Integer; + State: TDragState; var Accept: Boolean); override; + function GetReadOnly: Boolean; virtual; + procedure HighlighterAttrChanged(Sender: TObject); + procedure IncPaintLock; + procedure InitializeCaret; + procedure KeyUp(var Key: Word; Shift: TShiftState); override; + procedure KeyDown(var Key: Word; Shift: TShiftState); override; + procedure KeyPress(var Key: Char); override; + procedure KeyPressW(var Key: WideChar); virtual; + procedure LinesChanged(Sender: TObject); virtual; + procedure ListCleared(Sender: TObject); + procedure ListDeleted(Sender: TObject; aIndex: Integer; aCount: Integer); + procedure ListInserted(Sender: TObject; Index: Integer; aCount: Integer); + procedure ListPutted(Sender: TObject; Index: Integer; aCount: Integer); + //helper procs to chain list commands + procedure ChainListCleared(Sender: TObject); + procedure ChainListDeleted(Sender: TObject; aIndex: Integer; aCount: Integer); + procedure ChainListInserted(Sender: TObject; aIndex: Integer; aCount: Integer); + procedure ChainListPutted(Sender: TObject; aIndex: Integer; aCount: Integer); + procedure ChainLinesChanging(Sender: TObject); + procedure ChainLinesChanged(Sender: TObject); + procedure ChainUndoRedoAdded(Sender: TObject); + procedure ScanRanges; + procedure Loaded; override; + procedure MarkListChange(Sender: TObject); + procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: + Integer); override; + procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; + procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); + override; + procedure NotifyHookedCommandHandlers(AfterProcessing: Boolean; + var Command: TSynEditorCommand; var AChar: WideChar; Data: Pointer); virtual; + procedure Paint; override; + procedure PaintGutter(const AClip: TRect; const aFirstRow, + aLastRow: Integer); virtual; + procedure PaintTextLines(AClip: TRect; const aFirstRow, aLastRow, + FirstCol, LastCol: Integer); virtual; + procedure RecalcCharExtent; + procedure RedoItem; + procedure InternalSetCaretXY(const Value: TBufferCoord); virtual; + procedure SetCaretXY(const Value: TBufferCoord); virtual; + procedure SetCaretXYEx(CallEnsureCursorPos: Boolean; Value: TBufferCoord); virtual; + procedure SetFontSmoothing(AValue: TSynFontSmoothMethod); + procedure SetName(const Value: TComponentName); override; + procedure SetReadOnly(Value: Boolean); virtual; + procedure SetWantReturns(Value: Boolean); + procedure SetSelTextPrimitive(const Value: UnicodeString); + procedure SetSelTextPrimitiveEx(PasteMode: TSynSelectionMode; Value: PWideChar; + AddToUndoList: Boolean); + procedure SetWantTabs(Value: Boolean); + procedure StatusChanged(AChanges: TSynStatusChanges); + // If the translations requires Data, memory will be allocated for it via a + // GetMem call. The client must call FreeMem on Data if it is not NIL. + function TranslateKeyCode(Code: Word; Shift: TShiftState; + var Data: Pointer): TSynEditorCommand; + procedure UndoItem; + procedure UpdateMouseCursor; virtual; + protected + FGutterWidth: Integer; + FInternalImage: TSynInternalImage; + procedure HideCaret; + procedure ShowCaret; + procedure DoOnClearBookmark(var Mark: TSynEditMark); virtual; + procedure DoOnCommandProcessed(Command: TSynEditorCommand; AChar: WideChar; + Data: Pointer); virtual; + // no method DoOnDropFiles, intercept the WM_DROPFILES instead + procedure DoOnGutterClick(Button: TMouseButton; X, Y: Integer); virtual; + procedure DoOnPaint; virtual; + procedure DoOnPaintTransientEx(TransientType: TTransientType; Lock: Boolean); virtual; + procedure DoOnPaintTransient(TransientType: TTransientType); virtual; + + procedure DoOnPlaceMark(var Mark: TSynEditMark); virtual; + procedure DoOnProcessCommand(var Command: TSynEditorCommand; + var AChar: WideChar; Data: Pointer); virtual; + function DoOnReplaceText(const ASearch, AReplace: UnicodeString; + Line, Column: Integer): TSynReplaceAction; virtual; + function DoOnSpecialLineColors(Line: Integer; + var Foreground, Background: TColor): Boolean; virtual; + procedure DoOnSpecialTokenAttributes(ALine, APos: Integer; const AToken: string; var FG, BG: TColor; + var AStyle: TFontStyles); + procedure DoOnStatusChange(Changes: TSynStatusChanges); virtual; + function GetSelEnd: Integer; + function GetSelStart: Integer; + function GetSelLength: Integer; + procedure SetSelEnd(const Value: Integer); + procedure SetSelStart(const Value: Integer); + procedure SetSelLength(const Value: Integer); + procedure SetAlwaysShowCaret(const Value: Boolean); + function ShrinkAtWideGlyphs(const S: UnicodeString; First: Integer; + var CharCount: Integer): UnicodeString; + procedure LinesHookChanged; + procedure FontSmoothingChanged; + property InternalCaretX: Integer write InternalSetCaretX; + property InternalCaretY: Integer write InternalSetCaretY; + property InternalCaretXY: TBufferCoord write InternalSetCaretXY; + property FontSmoothing: TSynFontSmoothMethod read FFontSmoothing write SetFontSmoothing; +//++ DPI-Aware + procedure ChangeScale(M, D: Integer{$if CompilerVersion >= 31}; isDpiChange: Boolean{$ifend}); override; +//-- DPI-Aware + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + property Canvas; + property SelStart: Integer read GetSelStart write SetSelStart; + property SelEnd: Integer read GetSelEnd write SetSelEnd; + property AlwaysShowCaret: Boolean read FAlwaysShowCaret + write SetAlwaysShowCaret; + procedure UpdateCaret; +{$IFDEF SYN_COMPILER_4_UP} + procedure AddKey(Command: TSynEditorCommand; Key1: Word; SS1: TShiftState; + Key2: Word = 0; SS2: TShiftState = []); +{$ELSE} + procedure AddKey(Command: TSynEditorCommand; Key1: Word; SS1: TShiftState; + Key2: Word; SS2: TShiftState); +{$ENDIF} + procedure BeginUndoBlock; + procedure BeginUpdate; + function CaretInView: Boolean; + function CharIndexToRowCol(Index: Integer): TBufferCoord; + procedure Clear; + procedure ClearAll; + procedure ClearBookMark(BookMark: Integer); + procedure ClearSelection; + procedure CommandProcessor(Command: TSynEditorCommand; AChar: WideChar; + Data: Pointer); virtual; + procedure ClearUndo; + procedure CopyToClipboard; + procedure CutToClipboard; + procedure DoCopyToClipboard(const SText: UnicodeString); + procedure DragDrop(Source: TObject; X, Y: Integer); override; + procedure EndUndoBlock; + procedure EndUpdate; + procedure EnsureCursorPosVisible; + procedure EnsureCursorPosVisibleEx(ForceToMiddle: Boolean; + EvenIfVisible: Boolean = False); + procedure FindMatchingBracket; virtual; + function GetMatchingBracket: TBufferCoord; virtual; + function GetMatchingBracketEx(const APoint: TBufferCoord): TBufferCoord; virtual; +{$IFDEF SYN_COMPILER_4_UP} + function ExecuteAction(Action: TBasicAction): Boolean; override; +{$ENDIF} + procedure ExecuteCommand(Command: TSynEditorCommand; AChar: WideChar; + Data: Pointer); virtual; + function ExpandAtWideGlyphs(const S: UnicodeString): UnicodeString; + function GetBookMark(BookMark: Integer; var X, Y: Integer): Boolean; + function GetHighlighterAttriAtRowCol(const XY: TBufferCoord; var Token: UnicodeString; + var Attri: TSynHighlighterAttributes): Boolean; + function GetHighlighterAttriAtRowColEx(const XY: TBufferCoord; var Token: UnicodeString; + var TokenType, Start: Integer; + var Attri: TSynHighlighterAttributes): Boolean; + function GetPositionOfMouse(out aPos: TBufferCoord): Boolean; + function GetWordAtRowCol(XY: TBufferCoord): UnicodeString; + procedure GotoBookMark(BookMark: Integer); virtual; + procedure GotoLineAndCenter(ALine: Integer); virtual; + function IsIdentChar(AChar: WideChar): Boolean; virtual; + function IsWhiteChar(AChar: WideChar): Boolean; virtual; + function IsWordBreakChar(AChar: WideChar): Boolean; virtual; + + procedure InsertBlock(const BB, BE: TBufferCoord; ChangeStr: PWideChar; AddToUndoList: Boolean); + procedure InsertLine(const BB, BE: TBufferCoord; ChangeStr: PWideChar; AddToUndoList: Boolean); + function UnifiedSelection: TBufferBlock; + procedure DoBlockIndent; + procedure DoBlockUnindent; + + procedure InvalidateGutter; + procedure InvalidateGutterLine(aLine: Integer); + procedure InvalidateGutterLines(FirstLine, LastLine: Integer); + procedure InvalidateLine(Line: Integer); + procedure InvalidateLines(FirstLine, LastLine: Integer); + procedure InvalidateSelection; + procedure MarkModifiedLinesAsSaved; + procedure ResetModificationIndicator; + function IsBookmark(BookMark: Integer): Boolean; + function IsPointInSelection(const Value: TBufferCoord): Boolean; + procedure LockUndo; + function BufferToDisplayPos(const p: TBufferCoord): TDisplayCoord; + function DisplayToBufferPos(const p: TDisplayCoord): TBufferCoord; + function LineToRow(aLine: Integer): Integer; + function RowToLine(aRow: Integer): Integer; + procedure Notification(AComponent: TComponent; + Operation: TOperation); override; + procedure PasteFromClipboard; + + function NextWordPos: TBufferCoord; virtual; + function NextWordPosEx(const XY: TBufferCoord): TBufferCoord; virtual; + function WordStart: TBufferCoord; virtual; + function WordStartEx(const XY: TBufferCoord): TBufferCoord; virtual; + function WordEnd: TBufferCoord; virtual; + function WordEndEx(const XY: TBufferCoord): TBufferCoord; virtual; + function PrevWordPos: TBufferCoord; virtual; + function PrevWordPosEx(const XY: TBufferCoord): TBufferCoord; virtual; + + function PixelsToRowColumn(aX, aY: Integer): TDisplayCoord; + function PixelsToNearestRowColumn(aX, aY: Integer): TDisplayCoord; + procedure Redo; + procedure RegisterCommandHandler(const AHandlerProc: THookedCommandEvent; + AHandlerData: Pointer); + function RowColumnToPixels(const RowCol: TDisplayCoord): TPoint; + function RowColToCharIndex(RowCol: TBufferCoord): Integer; + function SearchReplace(const ASearch, AReplace: UnicodeString; + AOptions: TSynSearchOptions): Integer; + procedure SelectAll; + procedure SetBookMark(BookMark: Integer; X: Integer; Y: Integer); + procedure SetCaretAndSelection(const ptCaret, ptBefore, ptAfter: TBufferCoord); + procedure SetDefaultKeystrokes; virtual; + procedure SetSelWord; + procedure SetWordBlock(Value: TBufferCoord); + procedure Undo; + procedure UnlockUndo; + procedure UnregisterCommandHandler(AHandlerProc: THookedCommandEvent); +{$IFDEF SYN_COMPILER_4_UP} + function UpdateAction(Action: TBasicAction): Boolean; override; +{$ENDIF} + procedure SetFocus; override; + + procedure AddKeyUpHandler(aHandler: TKeyEvent); + procedure RemoveKeyUpHandler(aHandler: TKeyEvent); + procedure AddKeyDownHandler(aHandler: TKeyEvent); + procedure RemoveKeyDownHandler(aHandler: TKeyEvent); + procedure AddKeyPressHandler(aHandler: TKeyPressWEvent); + procedure RemoveKeyPressHandler(aHandler: TKeyPressWEvent); + procedure AddFocusControl(aControl: TWinControl); + procedure RemoveFocusControl(aControl: TWinControl); + procedure AddMouseDownHandler(aHandler: TMouseEvent); + procedure RemoveMouseDownHandler(aHandler: TMouseEvent); + procedure AddMouseUpHandler(aHandler: TMouseEvent); + procedure RemoveMouseUpHandler(aHandler: TMouseEvent); + procedure AddMouseCursorHandler(aHandler: TMouseCursorEvent); + procedure RemoveMouseCursorHandler(aHandler: TMouseCursorEvent); + + procedure WndProc(var Msg: TMessage); override; + procedure SetLinesPointer(ASynEdit: TCustomSynEdit); + procedure RemoveLinesPointer; + procedure HookTextBuffer(aBuffer: TSynEditStringList; + aUndo, aRedo: TSynEditUndoList); + procedure UnHookTextBuffer; +{$IFDEF SYN_CodeFolding} + procedure CollapseAll; + procedure UncollapseAll; + procedure Collapse(FoldRangeIndex: Integer; Invalidate:Boolean = True); + procedure Uncollapse(FoldRangeIndex: Integer; Invalidate:Boolean = True); + procedure UncollapseAroundLine(Line: Integer); + procedure CollapseNearest; + procedure UncollapseNearest; + procedure CollapseLevel(Level : integer); + procedure UnCollapseLevel(Level : integer); + procedure CollapseFoldType(FoldType : Integer); + procedure UnCollapseFoldType(FoldType : Integer); +{$ENDIF} + public + property AdditionalIdentChars: TSysCharSet read FAdditionalIdentChars write SetAdditionalIdentChars; + property AdditionalWordBreakChars: TSysCharSet read FAdditionalWordBreakChars write SetAdditionalWordBreakChars; + property BlockBegin: TBufferCoord read GetBlockBegin write SetBlockBegin; + property BlockEnd: TBufferCoord read GetBlockEnd write SetBlockEnd; + property CanPaste: Boolean read GetCanPaste; + property CanRedo: Boolean read GetCanRedo; + property CanUndo: Boolean read GetCanUndo; + property CaretX: Integer read FCaretX write SetCaretX; + property CaretY: Integer read FCaretY write SetCaretY; + property CaretXY: TBufferCoord read GetCaretXY write SetCaretXY; + property ActiveLineColor: TColor read FActiveLineColor + write SetActiveLineColor default clNone; + property DisplayX: Integer read GetDisplayX; + property DisplayY: Integer read GetDisplayY; + property DisplayXY: TDisplayCoord read GetDisplayXY; + property DisplayLineCount: Integer read GetDisplayLineCount; + property CharsInWindow: Integer read FCharsInWindow; + property CharWidth: Integer read FCharWidth; + property Color; + property Font: TFont read GetFont write SetFont; + property Highlighter: TSynCustomHighlighter + read FHighlighter write SetHighlighter; + property HintMode: TSynHintMode read FHintMode write FHintMode default shmDefault; + property LeftChar: Integer read FLeftChar write SetLeftChar; + property LineHeight: Integer read FTextHeight; + property LinesInWindow: Integer read FLinesInWindow; + property LineText: UnicodeString read GetLineText write SetLineText; + property Lines: TUnicodeStrings read FLines write SetLines; + property Marks: TSynEditMarkList read FMarkList; + property MaxScrollWidth: Integer read FMaxScrollWidth write SetMaxScrollWidth + default 1024; + property Modified: Boolean read FModified write SetModified; + property PaintLock: Integer read FPaintLock; + property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False; + property SearchEngine: TSynEditSearchCustom read FSearchEngine write SetSearchEngine; + property SelAvail: Boolean read GetSelAvail; + property SelLength: Integer read GetSelLength write SetSelLength; + property SelTabBlock: Boolean read GetSelTabBlock; + property SelTabLine: Boolean read GetSelTabLine; + property SelText: UnicodeString read GetSelText write SetSelTextExternal; + property StateFlags: TSynStateFlags read FStateFlags; + property Text: UnicodeString read SynGetText write SynSetText; + property TopLine: Integer read FTopLine write SetTopLine; + property WordAtCursor: UnicodeString read GetWordAtCursor; + property WordAtMouse: UnicodeString read GetWordAtMouse; + property UndoList: TSynEditUndoList read FUndoList; + property RedoList: TSynEditUndoList read FRedoList; + public + property OnProcessCommand: TProcessCommandEvent + read FOnProcessCommand write FOnProcessCommand; + +{$IFDEF SYN_CodeFolding} + property CodeFolding: TSynCodeFolding read fCodeFolding write fCodeFolding; + property UseCodeFolding: Boolean read fUseCodeFolding write SetUseCodeFolding; + property AllFoldRanges: TSynFoldRanges read fAllFoldRanges; +{$ENDIF} + property BookMarkOptions: TSynBookMarkOpt + read FBookMarkOpt write FBookMarkOpt; + property BorderStyle: TSynBorderStyle read FBorderStyle write SetBorderStyle + default bsSingle; + property ExtraLineSpacing: Integer + read FExtraLineSpacing write SetExtraLineSpacing default 0; + property Gutter: TSynGutter read FGutter write SetGutter; + property HideSelection: Boolean read FHideSelection write SetHideSelection + default False; + property InsertCaret: TSynEditCaretType read FInsertCaret + write SetInsertCaret default ctVerticalLine; + property InsertMode: Boolean read FInserting write SetInsertMode + default true; + property IsScrolling : Boolean read FIsScrolling; + property Keystrokes: TSynEditKeyStrokes + read FKeyStrokes write SetKeystrokes stored False; + property MaxUndo: Integer read GetMaxUndo write SetMaxUndo default 1024; + property Options: TSynEditorOptions read GetOptions write SetOptions + default SYNEDIT_DEFAULT_OPTIONS; + property OverwriteCaret: TSynEditCaretType read FOverwriteCaret + write SetOverwriteCaret default ctBlock; + property RightEdge: Integer read FRightEdge write SetRightEdge default 80; + property RightEdgeColor: TColor + read FRightEdgeColor write SetRightEdgeColor default clSilver; + property ScrollHintColor: TColor read FScrollHintColor + write FScrollHintColor default clInfoBk; + property ScrollHintFormat: TScrollHintFormat read FScrollHintFormat + write FScrollHintFormat default shfTopLineOnly; + property ScrollBars: TScrollStyle + read FScrollBars write SetScrollBars default ssBoth; + property SelectedColor: TSynSelectedColor + read FSelectedColor write FSelectedColor; + property SelectionMode: TSynSelectionMode + read FSelectionMode write SetSelectionMode default smNormal; + property ActiveSelectionMode: TSynSelectionMode read FActiveSelectionMode + write SetActiveSelectionMode stored False; + property TabWidth: Integer read FTabWidth write SetTabWidth default 8; + property WantReturns: Boolean read FWantReturns write SetWantReturns default True; + property WantTabs: Boolean read FWantTabs write SetWantTabs default False; + property WordWrap: Boolean read GetWordWrap write SetWordWrap default False; + property WordWrapGlyph: TSynGlyph read FWordWrapGlyph write SetWordWrapGlyph; + property OnChange: TNotifyEvent read FOnChange write FOnChange; + property OnClearBookmark: TPlaceMarkEvent read FOnClearMark + write FOnClearMark; + property OnCommandProcessed: TProcessCommandEvent + read FOnCommandProcessed write FOnCommandProcessed; + property OnContextHelp: TContextHelpEvent + read FOnContextHelp write FOnContextHelp; + property OnDropFiles: TDropFilesEvent read FOnDropFiles write FOnDropFiles; + property OnGutterClick: TGutterClickEvent + read FOnGutterClick write FOnGutterClick; + property OnGutterGetText: TGutterGetTextEvent read FOnGutterGetText + write FOnGutterGetText; + property OnGutterPaint: TGutterPaintEvent read FOnGutterPaint + write FOnGutterPaint; + property OnMouseCursor: TMouseCursorEvent read FOnMouseCursor + write FOnMouseCursor; + property OnKeyPress: TKeyPressWEvent read FOnKeyPressW write FOnKeyPressW; + property OnPaint: TPaintEvent read FOnPaint write FOnPaint; + property OnPlaceBookmark: TPlaceMarkEvent + read FOnPlaceMark write FOnPlaceMark; + property OnProcessUserCommand: TProcessCommandEvent + read FOnProcessUserCommand write FOnProcessUserCommand; + property OnReplaceText: TReplaceTextEvent read FOnReplaceText + write FOnReplaceText; + property OnSpecialLineColors: TSpecialLineColorsEvent + read FOnSpecialLineColors write FOnSpecialLineColors; + property OnSpecialTokenAttributes: TSpecialTokenAttributesEvent + read FOnSpecialTokenAttributes write FOnSpecialTokenAttributes; + property OnStatusChange: TStatusChangeEvent + read FOnStatusChange write FOnStatusChange; + property OnPaintTransient: TPaintTransient + read FOnPaintTransient write FOnPaintTransient; + property OnScroll: TScrollEvent + read FOnScroll write FOnScroll; + property OnTokenHint: TGetTokenHintEvent read FOnTokenHint write FOnTokenHint; +{$IFDEF SYN_CodeFolding} + property OnScanForFoldRanges: TScanForFoldRangesEvent + read fOnScanForFoldRanges write fOnScanForFoldRanges; +{$ENDIF} + published + property Cursor default crIBeam; +{$IFDEF SYN_COMPILER_6_UP} + property OnSearchNotFound: TCustomSynEditSearchNotFoundEvent + read FSearchNotFound write FSearchNotFound; +{$ENDIF} + end; + + TSynEdit = class(TCustomSynEdit) + published + // inherited properties + property Align; +{$IFDEF SYN_COMPILER_4_UP} + property Anchors; + property Constraints; +{$ENDIF} + property Color; + property ActiveLineColor; + property Ctl3D; + property ParentCtl3D; + property Enabled; + property Font; + property Height; + property Name; + property ParentColor default False; + property ParentFont default False; + property ParentShowHint; + property PopupMenu; + property ShowHint; + property TabOrder; + property TabStop default True; + property Visible; + property Width; + // inherited events + property OnClick; + property OnDblClick; + property OnDragDrop; + property OnDragOver; +{$IFDEF SYN_COMPILER_4_UP} + property OnEndDock; + property OnStartDock; +{$ENDIF} + property OnEndDrag; + property OnEnter; + property OnExit; + property OnKeyDown; + property OnKeyPress; + property OnKeyUp; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; + property OnMouseWheelDown; + property OnMouseWheelUp; + property OnStartDrag; + // TCustomSynEdit properties +{$IFDEF SYN_CodeFolding} + property CodeFolding; + property UseCodeFolding; +{$ENDIF} + property BookMarkOptions; + property BorderStyle; + property ExtraLineSpacing; + property Gutter; + property HideSelection; + property Highlighter; + property HintMode; + property ImeMode; + property ImeName; + property InsertCaret; + property InsertMode; + property Keystrokes; + property Lines; + property MaxScrollWidth; + property MaxUndo; + property Options; + property OverwriteCaret; + property ReadOnly; + property RightEdge; + property RightEdgeColor; + property ScrollHintColor; + property ScrollHintFormat; + property ScrollBars; + property SearchEngine; + property SelectedColor; + property SelectionMode; + property TabWidth; + property WantReturns; + property WantTabs; + property WordWrap; + property WordWrapGlyph; + // TCustomSynEdit events + property OnChange; + property OnClearBookmark; + property OnCommandProcessed; + property OnContextHelp; + property OnDropFiles; + property OnGutterClick; + property OnGutterGetText; + property OnGutterPaint; + property OnMouseCursor; + property OnPaint; + property OnPlaceBookmark; + property OnProcessCommand; + property OnProcessUserCommand; + property OnReplaceText; + property OnScroll; + property OnSpecialLineColors; + property OnStatusChange; + property OnTokenHint; + property OnPaintTransient; +{$IFDEF SYN_CodeFolding} + property OnScanForFoldRanges; +{$ENDIF} + + property FontSmoothing; + end; + +implementation + +{$IFDEF RESTDWPRIVSYNEDITRESOURCE} +{$R uRESTDWPrivSynEdit.res} +{$ENDIF} + +uses +{$IFDEF SYN_COMPILER_6_UP} + Consts, +{$ENDIF} +{$IFDEF SYN_COMPILER_18_UP} + AnsiStrings, +{$ENDIF} + Clipbrd, + ShellAPI, + uRESTDWPrivSynEditWordWrap, + uRESTDWPrivSynEditStrConst; + +function CeilOfIntDiv(Dividend: Cardinal; Divisor: Word): Word; +Var + Remainder: Word; +begin + DivMod(Dividend, Divisor, Result, Remainder); + if Remainder > 0 then + Inc(Result); +end; + +function TrimTrailingSpaces(const S: UnicodeString): UnicodeString; +var + I: Integer; +begin + I := Length(S); + while (I > 0) and ((S[I] = #32) or (S[I] = #9)) do + Dec(I); + Result := Copy(S, 1, I); +end; + +{ THookedCommandHandlerEntry } + +type + THookedCommandHandlerEntry = class(TObject) + private + FEvent: THookedCommandEvent; + FData: Pointer; + constructor Create(AEvent: THookedCommandEvent; AData: Pointer); + function Equals(AEvent: THookedCommandEvent): Boolean; {$IFDEF UNICODE} reintroduce; {$ENDIF} + end; + +constructor THookedCommandHandlerEntry.Create(AEvent: THookedCommandEvent; + AData: Pointer); +begin + inherited Create; + FEvent := AEvent; + FData := AData; +end; + +function THookedCommandHandlerEntry.Equals(AEvent: THookedCommandEvent): Boolean; +begin + with TMethod(FEvent) do + Result := (Code = TMethod(AEvent).Code) and (Data = TMethod(AEvent).Data); +end; + +{ TCustomSynEdit } + +function TCustomSynEdit.PixelsToNearestRowColumn(aX, aY: Integer): TDisplayCoord; +// Result is in display coordinates +var + f: Single; +begin + f := (aX - FGutterWidth - 2) / FCharWidth; + // don't return a partially visible last line + if aY >= FLinesInWindow * FTextHeight then + begin + aY := FLinesInWindow * FTextHeight - 1; + if aY < 0 then + aY := 0; + end; + Result.Column := Max(1, LeftChar + Round(f)); + Result.Row := Max(1, TopLine + (aY div FTextHeight)); +end; + +function TCustomSynEdit.PixelsToRowColumn(aX, aY: Integer): TDisplayCoord; +begin + Result.Column := Max(1, LeftChar + ((aX - FGutterWidth - 2) div FCharWidth)); + Result.Row := Max(1, TopLine + (aY div FTextHeight)); +end; + +function TCustomSynEdit.RowColumnToPixels(const RowCol: TDisplayCoord): TPoint; +begin + Result.X := (RowCol.Column-1) * FCharWidth + FTextOffset; + Result.Y := (RowCol.Row - FTopLine) * FTextHeight; +end; + +procedure TCustomSynEdit.ComputeCaret(X, Y: Integer); +//X,Y are pixel coordinates +var + vCaretNearestPos : TDisplayCoord; +begin + vCaretNearestPos := PixelsToNearestRowColumn(X, Y); + vCaretNearestPos.Row := MinMax(vCaretNearestPos.Row, 1, DisplayLineCount); + SetInternalDisplayXY(vCaretNearestPos); +end; + +procedure TCustomSynEdit.ComputeScroll(X, Y: Integer); +//X,Y are pixel coordinates +var + iScrollBounds: TRect; { relative to the client area } +begin + { don't scroll if dragging text from other control } + if (not MouseCapture) and (not Dragging) then + begin + FScrollTimer.Enabled := False; + Exit; + end; + + iScrollBounds := Bounds(FGutterWidth, 0, FCharsInWindow * FCharWidth, + FLinesInWindow * FTextHeight); + if BorderStyle = bsNone then + InflateRect(iScrollBounds, -2, -2); + + if X < iScrollBounds.Left then + FScrollDeltaX := (X - iScrollBounds.Left) div FCharWidth - 1 + else if X >= iScrollBounds.Right then + FScrollDeltaX := (X - iScrollBounds.Right) div FCharWidth + 1 + else + FScrollDeltaX := 0; + + if Y < iScrollBounds.Top then + fScrollDeltaY := (Y - iScrollBounds.Top) div FTextHeight - 1 + else if Y >= iScrollBounds.Bottom then + fScrollDeltaY := (Y - iScrollBounds.Bottom) div FTextHeight + 1 + else + fScrollDeltaY := 0; + + FScrollTimer.Enabled := (FScrollDeltaX <> 0) or (fScrollDeltaY <> 0); +end; + +procedure TCustomSynEdit.DoCopyToClipboard(const SText: UnicodeString); +var + Mem: HGLOBAL; + P: PByte; + SLen: Integer; +begin + if SText = '' then Exit; + SetClipboardText(SText); + SLen := Length(SText); + // Open and Close are the only TClipboard methods we use because TClipboard + // is very hard (impossible) to work with if you want to put more than one + // format on it at a time. + Clipboard.Open; + try + // Copy it in our custom format so we know what kind of block it is. + // That effects how it is pasted in. + // This format is kept as ANSI to be compatible with programs using the + // ANSI version of uRESTDWPrivSynEdit. + Mem := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, + sizeof(TSynSelectionMode) + SLen + 1); + if Mem <> 0 then + begin + P := GlobalLock(Mem); + try + if P <> nil then + begin + // Our format: TSynSelectionMode value followed by Ansi-text. + PSynSelectionMode(P)^ := FActiveSelectionMode; + Inc(P, SizeOf(TSynSelectionMode)); + Move(PAnsiChar(AnsiString(SText))^, P^, SLen + 1); + SetClipboardData(SynEditClipboardFormat, Mem); + end; + finally + GlobalUnlock(Mem); + end; + end; + // Don't free Mem! It belongs to the clipboard now, and it will free it + // when it is done with it. + finally + Clipboard.Close; + end; +end; + +procedure TCustomSynEdit.CopyToClipboard; +var + SText: UnicodeString; + ChangeTrim: Boolean; +begin + if SelAvail then + begin + ChangeTrim := (FActiveSelectionMode = smColumn) and (eoTrimTrailingSpaces in Options); + try + if ChangeTrim then + Exclude(FOptions, eoTrimTrailingSpaces); + SText := SelText; + finally + if ChangeTrim then + Include(FOptions, eoTrimTrailingSpaces); + end; + DoCopyToClipboard(SText); + end; +end; + +procedure TCustomSynEdit.CutToClipboard; +begin + if not ReadOnly and SelAvail then + begin + BeginUndoBlock; + try + DoCopyToClipboard(SelText); + SelText := ''; + finally + EndUndoBlock; + end; + end; +end; + +constructor TCustomSynEdit.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + FLines := TSynEditStringList.Create(ExpandAtWideGlyphs); + FOrigLines := FLines; + with TSynEditStringList(FLines) do + begin + OnChange := LinesChanged; + OnChanging := LinesChanging; + OnCleared := ListCleared; + OnDeleted := ListDeleted; + OnInserted := ListInserted; + OnPutted := ListPutted; + end; + FFontDummy := TFont.Create; + FUndoList := TSynEditUndoList.Create; + FUndoList.OnAddedUndo := UndoRedoAdded; + FOrigUndoList := FUndoList; + FRedoList := TSynEditUndoList.Create; + FRedoList.OnAddedUndo := UndoRedoAdded; + FOrigRedoList := FRedoList; + +{$IFDEF SYN_COMPILER_4_UP} + DoubleBuffered := False; +{$ENDIF} + FActiveLineColor := clNone; + FSelectedColor := TSynSelectedColor.Create; + FSelectedColor.OnChange := SelectedColorsChanged; + FBookMarkOpt := TSynBookMarkOpt.Create(Self); + FBookMarkOpt.OnChange := BookMarkOptionsChanged; +// FRightEdge has to be set before FontChanged is called for the first time + FRightEdge := 80; + FGutter := TSynGutter.Create; + FGutter.OnChange := GutterChanged; + FGutterWidth := FGutter.Width; + FWordWrapGlyph := TSynGlyph.Create(HINSTANCE, 'SynEditWrapped', clLime); + FWordWrapGlyph.OnChange := WordWrapGlyphChange; + FTextOffset := FGutterWidth + 2; + ControlStyle := ControlStyle + [csOpaque, csSetCaption]; +{$IFDEF SYN_COMPILER_7_UP} + ControlStyle := ControlStyle + [csNeedsBorderPaint]; +{$ENDIF} + Height := 150; + Width := 200; + Cursor := crIBeam; + Color := clWindow; +{$IFDEF MSWINDOWS} + FFontDummy.Name := 'Courier New'; + FFontDummy.Size := 10; +{$ENDIF} +{$IFDEF SYN_COMPILER_3_UP} + FFontDummy.CharSet := DEFAULT_CHARSET; +{$ENDIF} + FTextDrawer := TSynTextDrawer.Create([fsBold], FFontDummy); + Font.Assign(FFontDummy); + Font.OnChange := SynFontChanged; + ParentFont := False; + ParentColor := False; + TabStop := True; + FInserting := True; + FMaxScrollWidth := 1024; + FScrollBars := ssBoth; + FBorderStyle := bsSingle; + FHintMode := shmDefault; + FInsertCaret := ctVerticalLine; + FOverwriteCaret := ctBlock; + FSelectionMode := smNormal; + FActiveSelectionMode := smNormal; + FFocusList := TList.Create; + FKbdHandler := TSynEditKbdHandler.Create; + FKeyStrokes := TSynEditKeyStrokes.Create(Self); + FMarkList := TSynEditMarkList.Create(self); + FMarkList.OnChange := MarkListChange; + SetDefaultKeystrokes; + FRightEdgeColor := clSilver; + FWantReturns := True; + FWantTabs := False; + FTabWidth := 8; + FLeftChar := 1; + FTopLine := 1; + FCaretX := 1; + FLastCaretX := 1; + FCaretY := 1; + FBlockBegin.Char := 1; + FBlockBegin.Line := 1; + FBlockEnd := FBlockBegin; + FOptions := SYNEDIT_DEFAULT_OPTIONS; + FScrollTimer := TTimer.Create(Self); + FScrollTimer.Enabled := False; + FScrollTimer.Interval := 100; + FScrollTimer.OnTimer := ScrollTimerHandler; + + FScrollHintColor := clInfoBk; + FScrollHintFormat := shfTopLineOnly; +{$IFDEF SYN_CodeFolding} + FCodeFolding := TSynCodeFolding.Create; + FCodeFolding.OnChange := OnCodeFoldingChange; + FAllFoldRanges := TSynFoldRanges.Create; +{$ENDIF} + + SynFontChanged(nil); +end; + +procedure TCustomSynEdit.CreateParams(var Params: TCreateParams); +const + BorderStyles: array[TBorderStyle] of DWORD = (0, WS_BORDER); + ClassStylesOff = CS_VREDRAW or CS_HREDRAW; +begin + // Clear WindowText to avoid it being used as Caption, or else window creation will + // fail if it's bigger than 64KB. It's useless to set the Caption anyway. + StrDispose(WindowText); + WindowText := nil; + inherited CreateParams(Params); + with Params do + begin + WindowClass.Style := WindowClass.Style and not ClassStylesOff; + Style := Style or BorderStyles[FBorderStyle] or WS_CLIPCHILDREN; + + if NewStyleControls and Ctl3D and (FBorderStyle = bsSingle) then + begin + Style := Style and not WS_BORDER; + ExStyle := ExStyle or WS_EX_CLIENTEDGE; + // avoid flicker while scrolling or resizing + if not (csDesigning in ComponentState) and CheckWin32Version(5, 1) then + ExStyle := ExStyle or WS_EX_COMPOSITED; + end; + +{$IFNDEF UNICODE} + if not (csDesigning in ComponentState) then + begin + // Necessary for unicode support, especially IME won't work else + if Win32PlatformIsUnicode then + WindowClass.lpfnWndProc := @DefWindowProcW; + end; +{$ENDIF} + end; +end; + +procedure TCustomSynEdit.DecPaintLock; +var + vAuxPos: TDisplayCoord; +begin + Assert(FPaintLock > 0); + Dec(FPaintLock); + if (FPaintLock = 0) and HandleAllocated then + begin + if sfScrollbarChanged in FStateFlags then + UpdateScrollbars; + // Locks the caret inside the visible area + if WordWrap and ([scCaretX,scCaretY] * FStatusChanges <> []) then + begin + vAuxPos := DisplayXY; + // This may happen in the last row of a line or in rows which length is + // greater than CharsInWindow (Tabs and Spaces are allowed beyond + // CharsInWindow while wrapping the lines) + if (vAuxPos.Column > CharsInWindow +1) and (CharsInWindow > 0) then + begin + if FCaretAtEOL then + FCaretAtEOL := False + else + begin + if scCaretY in FStatusChanges then + begin + vAuxPos.Column := CharsInWindow + 1; + FCaretX := DisplayToBufferPos(vAuxPos).Char; + Include(FStatusChanges,scCaretX); + UpdateLastCaretX; + end; + end; + Include(FStateFlags, sfCaretChanged); + end; + end; + if sfCaretChanged in FStateFlags then + UpdateCaret; + if FStatusChanges <> [] then + DoOnStatusChange(FStatusChanges); + end; +end; + +destructor TCustomSynEdit.Destroy; +begin + Highlighter := nil; + if (FChainedEditor <> nil) or (FLines <> FOrigLines) then + RemoveLinesPointer; + + inherited Destroy; + + // free listeners while other fields are still valid + + // do not use FreeAndNil, it first nils and then freey causing problems with + // code accessing FHookedCommandHandlers while destruction + FHookedCommandHandlers.Free; + FHookedCommandHandlers := nil; + // do not use FreeAndNil, it first nils and then frees causing problems with + // code accessing FPlugins while destruction + FPlugins.Free; + FPlugins := nil; + + FMarkList.Free; + FBookMarkOpt.Free; + FKeyStrokes.Free; + FKbdHandler.Free; + FFocusList.Free; + FSelectedColor.Free; + FOrigUndoList.Free; + FOrigRedoList.Free; + FGutter.Free; + FWordWrapGlyph.Free; + FTextDrawer.Free; + FInternalImage.Free; + FFontDummy.Free; + FOrigLines.Free; +{$IFDEF SYN_CodeFolding} + fCodeFolding.Free; + fAllFoldRanges.Free; +{$ENDIF} +end; + +function TCustomSynEdit.GetBlockBegin: TBufferCoord; +begin + if (FBlockEnd.Line < FBlockBegin.Line) + or ((FBlockEnd.Line = FBlockBegin.Line) and (FBlockEnd.Char < FBlockBegin.Char)) + then + Result := FBlockEnd + else + Result := FBlockBegin; +end; + +function TCustomSynEdit.GetBlockEnd: TBufferCoord; +begin + if (FBlockEnd.Line < FBlockBegin.Line) + or ((FBlockEnd.Line = FBlockBegin.Line) and (FBlockEnd.Char < FBlockBegin.Char)) + then + Result := FBlockBegin + else + Result := FBlockEnd; +end; + +procedure TCustomSynEdit.SynFontChanged(Sender: TObject); +begin + RecalcCharExtent; + SizeOrFontChanged(True); +end; + +function TCustomSynEdit.GetFont: TFont; +begin + Result := inherited Font; +end; + +function TCustomSynEdit.GetLineText: UnicodeString; +begin + if (CaretY >= 1) and (CaretY <= Lines.Count) then + Result := Lines[CaretY - 1] + else + Result := ''; +end; + +function TCustomSynEdit.GetSelAvail: Boolean; +begin + Result := (FBlockBegin.Char <> FBlockEnd.Char) or + ((FBlockBegin.Line <> FBlockEnd.Line) and (FActiveSelectionMode <> smColumn)); +end; + +function TCustomSynEdit.GetSelTabBlock: Boolean; +begin + Result := (FBlockBegin.Line <> FBlockEnd.Line) and (FActiveSelectionMode <> smColumn); +end; + +function TCustomSynEdit.GetSelTabLine: Boolean; +begin + Result := (BlockBegin.Char <= 1) and (BlockEnd.Char > length(Lines[CaretY - 1])) and SelAvail; +end; + +function TCustomSynEdit.GetSelText: UnicodeString; + + function CopyPadded(const S: UnicodeString; Index, Count: Integer): UnicodeString; + var + SrcLen: Integer; + DstLen: Integer; + i: Integer; + P: PWideChar; + begin + SrcLen := Length(S); + DstLen := Index + Count; + if SrcLen >= DstLen then + Result := Copy(S, Index, Count) + else begin + SetLength(Result, DstLen); + P := PWideChar(Result); + WStrCopy(P, PWideChar(Copy(S, Index, Count))); + Inc(P, Length(S)); + for i := 0 to DstLen - Srclen - 1 do + P[i] := #32; + end; + end; + + procedure CopyAndForward(const S: UnicodeString; Index, Count: Integer; var P: + PWideChar); + var + pSrc: PWideChar; + SrcLen: Integer; + DstLen: Integer; + begin + SrcLen := Length(S); + if (Index <= SrcLen) and (Count > 0) then + begin + Dec(Index); + pSrc := PWideChar(S) + Index; + DstLen := Min(SrcLen - Index, Count); + Move(pSrc^, P^, DstLen * sizeof(WideChar)); + Inc(P, DstLen); + P^ := #0; + end; + end; + + function CopyPaddedAndForward(const S: UnicodeString; Index, Count: Integer; + var P: PWideChar): Integer; + var + OldP: PWideChar; + Len, i: Integer; + begin + Result := 0; + OldP := P; + CopyAndForward(S, Index, Count, P); + Len := Count - (P - OldP); + if not (eoTrimTrailingSpaces in Options) then + begin + for i := 0 to Len - 1 do + P[i] := #32; + Inc(P, Len); + end + else + Result := Len; + end; + +var + First, Last, TotalLen: Integer; + ColFrom, ColTo: Integer; + I: Integer; + l, r: Integer; + s: UnicodeString; + P: PWideChar; + cRow: Integer; + vAuxLineChar: TBufferCoord; + vAuxRowCol: TDisplayCoord; + vTrimCount: Integer; +begin + if not SelAvail then + Result := '' + else begin + ColFrom := BlockBegin.Char; + First := BlockBegin.Line - 1; + // + ColTo := BlockEnd.Char; + Last := BlockEnd.Line - 1; + // + TotalLen := 0; + case FActiveSelectionMode of + smNormal: + if (First = Last) then + Result := Copy(Lines[First], ColFrom, ColTo - ColFrom) + else begin + // step1: calculate total length of result string + TotalLen := Max(0, Length(Lines[First]) - ColFrom + 1); + for i := First + 1 to Last - 1 do + Inc(TotalLen, Length(Lines[i])); + Inc(TotalLen, ColTo - 1); + Inc(TotalLen, Length(SLineBreak) * (Last - First)); + // step2: build up result string + SetLength(Result, TotalLen); + P := PWideChar(Result); + CopyAndForward(Lines[First], ColFrom, MaxInt, P); + + CopyAndForward(SLineBreak, 1, MaxInt, P); + + for i := First + 1 to Last - 1 do + begin + CopyAndForward(Lines[i], 1, MaxInt, P); + CopyAndForward(SLineBreak, 1, MaxInt, P); + end; + CopyAndForward(Lines[Last], 1, ColTo - 1, P); + end; + smColumn: + begin + with BufferToDisplayPos(BlockBegin) do + begin + First := Row; + ColFrom := Column; + end; + with BufferToDisplayPos(BlockEnd) do + begin + Last := Row; + ColTo := Column; + end; + if ColFrom > ColTo then + SwapInt(ColFrom, ColTo); + // step1: pre-allocate string large enough for worst case + TotalLen := ((ColTo - ColFrom) + Length(sLineBreak)) * + (Last - First +1); + SetLength(Result, TotalLen); + P := PWideChar(Result); + + // step2: copy chunks to the pre-allocated string + TotalLen := 0; + for cRow := First to Last do + begin + vAuxRowCol.Row := cRow; + vAuxRowCol.Column := ColFrom; + vAuxLineChar := DisplayToBufferPos(vAuxRowCol); + l := vAuxLineChar.Char; + s := Lines[vAuxLineChar.Line - 1]; + vAuxRowCol.Column := ColTo; + r := DisplayToBufferPos(vAuxRowCol).Char; + + vTrimCount := CopyPaddedAndForward(s, l, r - l, P); + TotalLen := TotalLen + (r - l) - vTrimCount + Length(sLineBreak); + CopyAndForward(sLineBreak, 1, MaxInt, P); + end; + SetLength(Result, TotalLen - Length(sLineBreak)); + end; + smLine: + begin + // If block selection includes LastLine, + // line break code(s) of the last line will not be added. + // step1: calculate total length of result string + for i := First to Last do + Inc(TotalLen, Length(Lines[i]) + Length(SLineBreak)); + if Last = Lines.Count then + Dec(TotalLen, Length(SLineBreak)); + // step2: build up result string + SetLength(Result, TotalLen); + P := PWideChar(Result); + for i := First to Last - 1 do + begin + CopyAndForward(Lines[i], 1, MaxInt, P); + CopyAndForward(SLineBreak, 1, MaxInt, P); + end; + CopyAndForward(Lines[Last], 1, MaxInt, P); + if (Last + 1) < Lines.Count then + CopyAndForward(SLineBreak, 1, MaxInt, P); + end; + end; + end; +end; + +function TCustomSynEdit.SynGetText: UnicodeString; +begin + Result := Lines.Text; +end; + +function TCustomSynEdit.GetWordAtCursor: UnicodeString; +begin + Result := GetWordAtRowCol(CaretXY); +end; + +procedure TCustomSynEdit.HideCaret; +begin + if sfCaretVisible in FStateFlags then + if Windows.HideCaret(Handle) then + Exclude(FStateFlags, sfCaretVisible); +end; + +procedure TCustomSynEdit.IncPaintLock; +begin + Inc(FPaintLock); +end; + +procedure TCustomSynEdit.InvalidateGutter; +begin + InvalidateGutterLines(-1, -1); +end; + +procedure TCustomSynEdit.InvalidateGutterLine(aLine: Integer); +begin + if (aLine < 1) or (aLine > Lines.Count) then + Exit; + + InvalidateGutterLines(aLine, aLine); +end; + +procedure TCustomSynEdit.InvalidateGutterLines(FirstLine, LastLine: Integer); +// note: FirstLine and LastLine don't need to be in correct order +var + rcInval: TRect; +begin + if Visible and HandleAllocated then + if (FirstLine = -1) and (LastLine = -1) then + begin + rcInval := Rect(0, 0, FGutterWidth, ClientHeight); + if sfLinesChanging in FStateFlags then + UnionRect(fInvalidateRect, rcInval, fInvalidateRect) + else + InvalidateRect(rcInval, False); + end + else begin + { find the visible lines first } + if (LastLine < FirstLine) then + SwapInt(LastLine, FirstLine); +{$IFDEF SYN_CodeFolding} + if UseCodeFolding or WordWrap then +{$ELSE} + if WordWrap then +{$ENDIF} + begin + FirstLine := LineToRow(FirstLine); + if LastLine <= Lines.Count then + LastLine := LineToRow(LastLine) + else + LastLine := MaxInt; + end; + FirstLine := Max(FirstLine, TopLine); + LastLine := Min(LastLine, TopLine + LinesInWindow); + { any line visible? } + if (LastLine >= FirstLine) then + begin + rcInval := Rect(0, FTextHeight * (FirstLine - TopLine), + FGutterWidth, FTextHeight * (LastLine - TopLine + 1)); + if sfLinesChanging in FStateFlags then + UnionRect(fInvalidateRect, rcInval, fInvalidateRect) + else + InvalidateRect(rcInval, False); + end; + end; +end; + +procedure TCustomSynEdit.InvalidateLines(FirstLine, LastLine: Integer); +// note: FirstLine and LastLine don't need to be in correct order +var + rcInval: TRect; +begin + if Visible and HandleAllocated then + if (FirstLine = -1) and (LastLine = -1) then + begin + rcInval := ClientRect; + Inc(rcInval.Left, FGutterWidth); + if sfLinesChanging in FStateFlags then +//++ Flicker Reduction + UnionRect(fInvalidateRect, rcInval, fInvalidateRect) +//-- Flicker Reduction + else + InvalidateRect(rcInval, False); + end + else begin + FirstLine := Max(FirstLine,1); + LastLine := Max(LastLine,1); + { find the visible lines first } + if (LastLine < FirstLine) then + SwapInt(LastLine, FirstLine); + + if LastLine >= Lines.Count then + LastLine := MaxInt; // paint empty space beyond last line + +{$IFDEF SYN_CodeFolding} + if UseCodeFolding or WordWrap then + begin + FirstLine := LineToRow(FirstLine); + // Could avoid this conversion if (First = Last) and + // (Length < CharsInWindow) but the dependency isn't worth IMO. + if LastLine < Lines.Count then begin + if UseCodeFolding then + LastLine := LineToRow(LastLine) + else + LastLine := LineToRow(LastLine + 1) - 1; + end; + end; +{$ELSE} + if WordWrap then + begin + FirstLine := LineToRow(FirstLine); + // Could avoid this conversion if (First = Last) and + // (Length < CharsInWindow) but the dependency isn't worth IMO. + if LastLine < Lines.Count then + LastLine := LineToRow(LastLine + 1) - 1; + end; +{$ENDIF} + + // TopLine is in display coordinates, so FirstLine and LastLine must be + // converted previously. + FirstLine := Max(FirstLine, TopLine); + LastLine := Min(LastLine, TopLine + LinesInWindow); + + { any line visible? } + if (LastLine >= FirstLine) then + begin + rcInval := Rect(FGutterWidth, FTextHeight * (FirstLine - TopLine), + ClientWidth, FTextHeight * (LastLine - TopLine + 1)); + if sfLinesChanging in FStateFlags then + UnionRect(fInvalidateRect, rcInval, fInvalidateRect) + else + InvalidateRect(rcInval, False); + end; + end; +end; + +procedure TCustomSynEdit.InvalidateSelection; +begin + InvalidateLines(BlockBegin.Line, BlockEnd.Line); +end; + +{$IFDEF SYN_COMPILER_5} +function TryStrToInt(const S: string; out Value: Integer): Boolean; +var + E: Integer; +begin + Val(S, Value, E); + Result := E = 0; +end; +{$ENDIF} + +procedure TCustomSynEdit.KeyUp(var Key: Word; Shift: TShiftState); +{$IFDEF SYN_LINUX} +var + Code: Byte; +{$ENDIF} +var + CharCode: Integer; + KeyMsg: TWMKey; +begin + {$IFDEF SYN_LINUX} + // uniform Keycode: key has the same value wether Shift is pressed or not + if Key <= 255 then + begin + Code := XKeysymToKeycode(Xlib.PDisplay(QtDisplay), Key); + Key := XKeycodeToKeysym(Xlib.PDisplay(QtDisplay), Code, 0); + if AnsiChar(Key) in ['a'..'z'] then Key := Ord(UpCase(AnsiChar(Key))); + end; + {$ENDIF} + + if (ssAlt in Shift) and (Key >= VK_NUMPAD0) and (Key <= VK_NUMPAD9) then + FCharCodeString := FCharCodeString + IntToStr(Key - VK_NUMPAD0); + + if Key = VK_MENU then + begin + if (FCharCodeString <> '') and TryStrToInt(FCharCodeString, CharCode) and + (CharCode >= 256) and (CharCode <= 65535) then + begin + KeyMsg.Msg := WM_CHAR; + KeyMsg.CharCode := CharCode; + KeyMsg.Unused := 0; + KeyMsg.KeyData := 0; + DoKeyPressW(KeyMsg); + FIgnoreNextChar := True; + end; + FCharCodeString := ''; + end; + + inherited; + FKbdHandler.ExecuteKeyUp(Self, Key, Shift); +end; + +procedure TCustomSynEdit.KeyDown(var Key: Word; Shift: TShiftState); +var + Data: Pointer; + C: WideChar; + Cmd: TSynEditorCommand; + {$IFDEF SYN_LINUX} + Code: Byte; + {$ENDIF} +begin + {$IFDEF SYN_LINUX} + // uniform Keycode: key has the same value wether Shift is pressed or not + if Key <= 255 then + begin + Code := XKeysymToKeycode(Xlib.PDisplay(QtDisplay), Key); + Key := XKeycodeToKeysym(Xlib.PDisplay(QtDisplay), Code, 0); + if AnsiChar(Key) in ['a'..'z'] then Key := Ord(UpCase(AnsiChar(Key))); + end; + {$ENDIF} + inherited; + FKbdHandler.ExecuteKeyDown(Self, Key, Shift); + + Data := nil; + C := #0; + try + Cmd := TranslateKeyCode(Key, Shift, Data); + if Cmd <> ecNone then begin + Key := 0; // eat it. + Include(FStateFlags, sfIgnoreNextChar); + CommandProcessor(Cmd, C, Data); + end + else + Exclude(FStateFlags, sfIgnoreNextChar); + finally + if Data <> nil then + FreeMem(Data); + end; +end; + +procedure TCustomSynEdit.Loaded; +begin + inherited Loaded; + GutterChanged(Self); + UpdateScrollBars; +end; + +procedure TCustomSynEdit.KeyPress(var Key: Char); +begin +end; + +type + TAccessWinControl = class(TWinControl); + +{.$MESSAGE 'Check what must be adapted in DoKeyPressW and related methods'} +procedure TCustomSynEdit.DoKeyPressW(var Message: TWMKey); +var + Form: TCustomForm; + Key: WideChar; +begin + if FIgnoreNextChar then + begin + FIgnoreNextChar := False; + Exit; + end; + + Key := WideChar(Message.CharCode); + + Form := GetParentForm(Self); + if (Form <> nil) and (Form <> TWinControl(Self)) and Form.KeyPreview and + (Key <= High(AnsiChar)) and TAccessWinControl(Form).DoKeyPress(Message) + then + Exit; + Key := WideChar(Message.CharCode); + + if (csNoStdEvents in ControlStyle) then Exit; + + if Assigned(FOnKeyPressW) then + FOnKeyPressW(Self, Key); + + if WideChar(Key) <> #0 then + KeyPressW(Key); +end; + +procedure TCustomSynEdit.KeyPressW(var Key: WideChar); +begin + // don't fire the event if key is to be ignored + if not (sfIgnoreNextChar in FStateFlags) then + begin + FKbdHandler.ExecuteKeyPress(Self, Key); + CommandProcessor(ecChar, Key, nil); + end + else + // don't ignore further keys + Exclude(FStateFlags, sfIgnoreNextChar); +end; + +function TCustomSynEdit.LeftSpaces(const Line: UnicodeString): Integer; +begin + Result := LeftSpacesEx(Line, False); +end; + +function TCustomSynEdit.LeftSpacesEx(const Line: UnicodeString; WantTabs: Boolean; CalcAlways : Boolean = False): Integer; +var + p: PWideChar; +begin + p := PWideChar(UnicodeString(Line)); + if Assigned(p) and ((eoAutoIndent in fOptions) or CalcAlways) then + begin + Result := 0; + while (p^ >= #1) and (p^ <= #32) do + begin + if (p^ = #9) and WantTabs then + Inc(Result, TabWidth) + else + Inc(Result); + Inc(p); + end; + end + else + Result := 0; +end; + +function TCustomSynEdit.GetLeftSpacing(CharCount: Integer; WantTabs: Boolean): UnicodeString; +begin + if WantTabs and not(eoTabsToSpaces in Options) and (CharCount >= TabWidth) then + Result := UnicodeStringOfChar(#9, CharCount div TabWidth) + + UnicodeStringOfChar(#32, CharCount mod TabWidth) + else + Result := UnicodeStringOfChar(#32, CharCount); +end; + +procedure TCustomSynEdit.LinesChanging(Sender: TObject); +begin + Include(FStateFlags, sfLinesChanging); +end; + +procedure TCustomSynEdit.LinesChanged(Sender: TObject); +var + vOldMode: TSynSelectionMode; +begin +{$IFDEF SYN_CodeFolding} + if (sfLinesChanging in fStateFlags) and fAllFoldRanges.StopScanning(fLines) then + begin + if Assigned(fHighlighter) and (fHighlighter is TSynCustomCodeFoldingHighlighter) then + TSynCustomCodeFoldingHighlighter(fHighlighter).AdjustFoldRanges(AllFoldRanges, + fLines); + InvalidateGutter; + Include(fStateFlags, sfScrollbarChanged); + end; +{$ENDIF} + Exclude(FStateFlags, sfLinesChanging); + if HandleAllocated then + begin +//++ Flicker Reduction +// UpdateScrollBars; +//-- Flicker Reduction + vOldMode := FActiveSelectionMode; + SetBlockBegin(CaretXY); + FActiveSelectionMode := vOldMode; + InvalidateRect(FInvalidateRect, False); + FillChar(FInvalidateRect, SizeOf(TRect), 0); + if FGutter.ShowLineNumbers and FGutter.AutoSize then + FGutter.AutoSizeDigitCount(Lines.Count); + if not (eoScrollPastEof in Options) then + TopLine := TopLine; + end; +end; + +procedure TCustomSynEdit.MouseDown(Button: TMouseButton; Shift: TShiftState; + X, Y: Integer); +var + bWasSel: Boolean; + bStartDrag: Boolean; + TmpBegin, TmpEnd: TBufferCoord; +begin + TmpBegin := FBlockBegin; + TmpEnd := FBlockEnd; + + bWasSel := False; + bStartDrag := False; + if Button = mbLeft then + begin + if SelAvail then + begin + //remember selection state, as it will be cleared later + bWasSel := True; + FMouseDownX := X; + FMouseDownY := Y; + end; + end; + + inherited MouseDown(Button, Shift, X, Y); + + if (Button = mbLeft) and (ssDouble in Shift) then Exit; + + FKbdHandler.ExecuteMouseDown(Self, Button, Shift, X, Y); + + if (Button in [mbLeft, mbRight]) then + begin + if Button = mbRight then + begin + if (eoRightMouseMovesCursor in Options) and + (SelAvail and not IsPointInSelection(DisplayToBufferPos(PixelsToRowColumn(X, Y))) + or not SelAvail) then + begin + InvalidateSelection; + FBlockEnd := FBlockBegin; + ComputeCaret(X, Y); + end + else + Exit; + end + else + ComputeCaret(X, Y); + end; + + if Button = mbLeft then + begin + //I couldn't track down why, but sometimes (and definately not all the time) + //the block positioning is lost. This makes sure that the block is + //maintained in case they started a drag operation on the block + FBlockBegin := TmpBegin; + FBlockEnd := TmpEnd; + + MouseCapture := True; + //For some reason uRESTDWPrivSynEdit could get to a state where MouseCapture was True + //while just scrolling the window. That resulted in contents being painted + //while vertical scrollbar was moved. To make sure that we paint only when + //a MouseDown has happened inside the uRESTDWPrivSynEdit Window, an extra flag is used. + Include(FStateFlags, sfMouseCaptured); + //if mousedown occurred in selected block begin drag operation + Exclude(FStateFlags, sfWaitForDragging); + if bWasSel and (eoDragDropEditing in FOptions) and (X >= FGutterWidth + 2) + and (SelectionMode = smNormal) and IsPointInSelection(DisplayToBufferPos(PixelsToRowColumn(X, Y))) then + begin + bStartDrag := True + end; + end; + + if (Button = mbLeft) and bStartDrag then + Include(FStateFlags, sfWaitForDragging) + else + begin + if not (sfDblClicked in FStateFlags) then + begin + if ssShift in Shift then + //BlockBegin and BlockEnd are restored to their original position in the + //code from above and SetBlockEnd will take care of proper invalidation + SetBlockEnd(CaretXY) + else + begin + if (eoAltSetsColumnMode in Options) and (FActiveSelectionMode <> smLine) then + begin + if ssAlt in Shift then + SelectionMode := smColumn + else + SelectionMode := smNormal; + end; + //Selection mode must be set before calling SetBlockBegin + SetBlockBegin(CaretXY); + end; + end; + end; + + if (X < FGutterWidth) then + Include(FStateFlags, sfPossibleGutterClick); + if (sfPossibleGutterClick in FStateFlags) and (Button = mbRight) then + begin + DoOnGutterClick(Button, X, Y) + end; + + SetFocus; + Windows.SetFocus(Handle); +end; + +procedure TCustomSynEdit.MouseMove(Shift: TShiftState; X, Y: Integer); +var + P: TDisplayCoord; +begin + inherited MouseMove(Shift, x, y); + if MouseCapture and (sfWaitForDragging in FStateFlags) then + begin + if (Abs(FMouseDownX - X) >= GetSystemMetrics(SM_CXDRAG)) + or (Abs(FMouseDownY - Y) >= GetSystemMetrics(SM_CYDRAG)) then + begin + Exclude(FStateFlags, sfWaitForDragging); + BeginDrag(False); + end; + end + else if (ssLeft in Shift) and MouseCapture and (sfMouseCaptured in FStateFlags) then + begin + // should we begin scrolling? + ComputeScroll(X, Y); + { compute new caret } + P := PixelsToNearestRowColumn(X, Y); + P.Row := MinMax(P.Row, 1, DisplayLineCount); + if FScrollDeltaX <> 0 then + P.Column := DisplayX; + if fScrollDeltaY <> 0 then + P.Row := DisplayY; + InternalCaretXY := DisplayToBufferPos(P); + BlockEnd := CaretXY; + if (sfPossibleGutterClick in FStateFlags) and (FBlockBegin.Line <> CaretXY.Line) then + Include(FStateFlags, sfGutterDragging); + end; +end; + +procedure TCustomSynEdit.ScrollTimerHandler(Sender: TObject); +var + iMousePos: TPoint; + C: TDisplayCoord; + X, Y: Integer; + vCaret: TBufferCoord; +begin + GetCursorPos( iMousePos ); + iMousePos := ScreenToClient( iMousePos ); + C := PixelsToRowColumn( iMousePos.X, iMousePos.Y ); + C.Row := MinMax(C.Row, 1, DisplayLineCount); + if FScrollDeltaX <> 0 then + begin + LeftChar := LeftChar + FScrollDeltaX; + X := LeftChar; + if FScrollDeltaX > 0 then // scrolling right? + Inc(X, CharsInWindow); + C.Column := X; + end; + if fScrollDeltaY <> 0 then + begin + if GetKeyState(SYNEDIT_SHIFT) < 0 then + TopLine := TopLine + fScrollDeltaY * LinesInWindow + else + TopLine := TopLine + fScrollDeltaY; + Y := TopLine; + if fScrollDeltaY > 0 then // scrolling down? + Inc(Y, LinesInWindow - 1); + C.Row := MinMax(Y, 1, DisplayLineCount); + end; + vCaret := DisplayToBufferPos(C); + if (CaretX <> vCaret.Char) or (CaretY <> vCaret.Line) then + begin + // changes to line / column in one go + IncPaintLock; + try + InternalCaretXY := vCaret; + // if MouseCapture is True we're changing selection. otherwise we're dragging + if MouseCapture and (sfMouseCaptured in FStateFlags) then + SetBlockEnd(CaretXY); + finally + DecPaintLock; + end; + end; + ComputeScroll(iMousePos.x, iMousePos.y); +end; + +procedure TCustomSynEdit.MouseUp(Button: TMouseButton; Shift: TShiftState; + X, Y: Integer); +{$IFDEF SYN_CodeFolding} +Var + ptLineCol: TBufferCoord; + ptRowCol: TDisplayCoord; + Index: Integer; + Rect: TRect; +{$ENDIF} +begin + inherited MouseUp(Button, Shift, X, Y); + FKbdHandler.ExecuteMouseUp(Self, Button, Shift, X, Y); + + FScrollTimer.Enabled := False; + if (Button = mbRight) and (Shift = [ssRight]) and Assigned(PopupMenu) then + Exit; + MouseCapture := False; + Exclude(FStateFlags, sfMouseCaptured); + if (sfPossibleGutterClick in FStateFlags) and (X < FGutterWidth) and (Button <> mbRight) then + DoOnGutterClick(Button, X, Y) + else + if FStateFlags * [sfDblClicked, sfWaitForDragging] = [sfWaitForDragging] then + begin + ComputeCaret(X, Y); + if not(ssShift in Shift) then + SetBlockBegin(CaretXY); + SetBlockEnd(CaretXY); + Exclude(FStateFlags, sfWaitForDragging); + end; + Exclude(FStateFlags, sfDblClicked); + Exclude(FStateFlags, sfPossibleGutterClick); + Exclude(FStateFlags, sfGutterDragging); +{$IFDEF SYN_CodeFolding} + ptRowCol := PixelsToRowColumn(X, Y); + ptLineCol := DisplayToBufferPos(ptRowCol); + + if UseCodeFolding and CodeFolding.ShowHintMark and + fAllFoldRanges.CollapsedFoldStartAtLine(ptLineCol.Line, Index) then + begin + Rect := GetCollapseMarkRect(ptRowCol.Row, ptLineCol.Line); + if PtInRect(Rect, Point(X,Y)) then + Uncollapse(Index); + end; +{$ENDIF} +end; + +procedure TCustomSynEdit.DoOnGutterClick(Button: TMouseButton; X, Y: Integer); +var + i : Integer; + offs : Integer; + line : Integer; + allmrk: TSynEditMarks; + mark : TSynEditMark; +{$IFDEF SYN_CodeFolding} + Index : integer; + RowColumn: TDisplayCoord; +begin + RowColumn := PixelsToRowColumn(X, Y); + Line := RowToLine(RowColumn.Row); + + // Check if we clicked on a folding thing + if UseCodeFolding then begin + if AllFoldRanges.FoldStartAtLine(Line, Index) then + begin + // See if we actually clicked on the rectangle... + if PtInRect(GetFoldShapeRect(RowColumn.Row), Point(X, Y)) then begin + if AllFoldRanges.Ranges[Index].Collapsed then + Uncollapse(Index) + else + Collapse(Index); + Exit; + end; + end; + end; +{$ELSE} +begin +{$ENDIF} + if Assigned(FOnGutterClick) then + begin + line := DisplayToBufferPos(PixelsToRowColumn(X,Y)).Line; + if line <= Lines.Count then + begin + Marks.GetMarksForLine(line, allmrk); + offs := 0; + mark := nil; + for i := 1 to MAX_MARKS do + begin + if assigned(allmrk[i]) then + begin + Inc(offs, BookMarkOptions.XOffset); + if X < offs then + begin + mark := allmrk[i]; + Break; + end; + end; + end; //for + FOnGutterClick(Self, Button, X, Y, line, mark); + end; + end; +end; + +procedure TCustomSynEdit.Paint; +var + rcClip, rcDraw: TRect; + nL1, nL2, nC1, nC2: Integer; +begin + // Get the invalidated rect. Compute the invalid area in lines / columns. + rcClip := Canvas.ClipRect; + // columns + nC1 := LeftChar; + if (rcClip.Left > FGutterWidth + 2) then + Inc(nC1, (rcClip.Left - FGutterWidth - 2) div CharWidth); + nC2 := LeftChar + + (rcClip.Right - FGutterWidth - 2 + CharWidth - 1) div CharWidth; + // lines + nL1 := Max(TopLine + rcClip.Top div FTextHeight, TopLine); + nL2 := MinMax(TopLine + (rcClip.Bottom + FTextHeight - 1) div FTextHeight, + 1, DisplayLineCount); + + // Now paint everything while the caret is hidden. + HideCaret; + try + // First paint the gutter area if it was (partly) invalidated. + if (rcClip.Left < FGutterWidth) then + begin + rcDraw := rcClip; + rcDraw.Right := FGutterWidth; + PaintGutter(rcDraw, nL1, nL2); + end; + // Then paint the text area if it was (partly) invalidated. + if (rcClip.Right > FGutterWidth) then + begin + rcDraw := rcClip; + rcDraw.Left := Max(rcDraw.Left, FGutterWidth); + PaintTextLines(rcDraw, nL1, nL2, nC1, nC2); + end; + + // consider paint lock (inserted by CWBudde, 30th of July 2015) + if PaintLock = 0 then + PluginsAfterPaint(Canvas, rcClip, nL1, nL2); + // If there is a custom paint handler call it. + if PaintLock = 0 then + DoOnPaint; + if PaintLock = 0 then + DoOnPaintTransient(ttAfter); + finally + UpdateCaret; + end; +end; + +procedure TCustomSynEdit.PaintGutter(const AClip: TRect; + const aFirstRow, aLastRow: Integer); + + procedure DrawMark(aMark: TSynEditMark; var aGutterOff: Integer; + aMarkRow: Integer); + begin + if (not aMark.InternalImage) and Assigned(FBookMarkOpt.BookmarkImages) then + begin + if aMark.ImageIndex <= FBookMarkOpt.BookmarkImages.Count then + begin + if aMark.IsBookmark = BookMarkOptions.DrawBookmarksFirst then + aGutterOff := 0 + else if aGutterOff = 0 then + aGutterOff := FBookMarkOpt.XOffset; + with FBookMarkOpt do + BookmarkImages.Draw(Canvas, LeftMargin + aGutterOff, + (aMarkRow - TopLine) * FTextHeight, aMark.ImageIndex); + Inc(aGutterOff, FBookMarkOpt.XOffset); + end; + end + else begin + if aMark.ImageIndex in [0..9] then + begin + if not Assigned(FInternalImage) then + begin + FInternalImage := TSynInternalImage.Create(HINSTANCE, + 'SynEditInternalImages', 10); +//++ DPI-Aware + if Screen.PixelsPerInch >= 120 then + fInternalImage.ChangeScale(Screen.PixelsPerInch, 96); +//-- DPI-Aware + end; + if aGutterOff = 0 then + begin + FInternalImage.Draw(Canvas, aMark.ImageIndex, + FBookMarkOpt.LeftMargin + aGutterOff, + (aMarkRow - TopLine) * FTextHeight, FTextHeight); + end; + Inc(aGutterOff, FBookMarkOpt.XOffset); + end; + end; + end; + + procedure DrawModification(Color: TColor; Top, Bottom: Integer); + var + OldColor: TColor; + OldStyle: TBrushStyle; + begin + FTextDrawer.SetBackColor(Color); + + OldStyle := Canvas.Brush.Style; + OldColor := Canvas.Brush.Color; + + Canvas.Brush.Style := bsSolid; + Canvas.Brush.Color := Color; + + Canvas.FillRect(Rect(FGutterWidth - FGutter.RightOffset - FGutter.ModificationBarWidth, Top, + FGutterWidth - FGutter.RightOffset, Bottom)); + + Canvas.Brush.Style := OldStyle; + Canvas.Brush.Color := OldColor; + + FTextDrawer.SetBackColor(FGutter.Color); + end; + +var + cLine: Integer; + cMark: Integer; + rcLine: TRect; + aGutterOffs: PIntArray; + bHasOtherMarks: Boolean; + s: UnicodeString; + vFirstLine: Integer; + vLastLine: Integer; + vMarkRow: Integer; + vGutterRow: Integer; + vLineTop: Integer; + vTextOffset: Integer; + dc: HDC; + TextSize: TSize; +{$IFDEF SYN_CodeFolding} + vLine: Integer; + cRow : Integer; + rcFold: TRect; + x: Integer; + FoldRange: TSynFoldRange; + Index : Integer; +{$ENDIF} +begin + vFirstLine := RowToLine(aFirstRow); + vLastLine := RowToLine(aLastRow); + //todo: Does the following comment still apply? + // Changed to use FTextDrawer.BeginDrawing and FTextDrawer.EndDrawing only + // when absolutely necessary. Note: Never change brush / pen / font of the + // canvas inside of this block (only through methods of FTextDrawer)! + // If we have to draw the line numbers then we don't want to erase + // the background first. Do it line by line with TextRect instead + // and fill only the area after the last visible line. + dc := Canvas.Handle; + + if FGutter.Gradient then + SynDrawGradient(Canvas, FGutter.GradientStartColor, FGutter.GradientEndColor, + FGutter.GradientSteps, Rect(0, 0, FGutterWidth, ClientHeight), True); + + Canvas.Brush.Color := FGutter.Color; + + if FGutter.ShowLineNumbers then + begin + if FGutter.UseFontStyle then + FTextDrawer.SetBaseFont(FGutter.Font) + else + FTextDrawer.Style := []; + FTextDrawer.BeginDrawing(dc); + try + if FGutter.UseFontStyle then + FTextDrawer.SetForeColor(FGutter.Font.Color) + else + FTextDrawer.SetForeColor(Self.Font.Color); + FTextDrawer.SetBackColor(FGutter.Color); + + // prepare the rect initially + rcLine := AClip; + rcLine.Right := Max(rcLine.Right, FGutterWidth - 2); + rcLine.Bottom := rcLine.Top; + + for cLine := vFirstLine to vLastLine do + begin +{$IFDEF SYN_CodeFolding} + if UseCodeFolding and AllFoldRanges.FoldHidesLine(cLine, Index) then + continue; +{$ENDIF} + vLineTop := (LineToRow(cLine) - TopLine) * FTextHeight; + if WordWrap and not FGutter.Gradient then + begin + // erase space between wrapped lines (from previous line to current one) + rcLine.Top := rcLine.Bottom; + rcLine.Bottom := vLineTop; + with rcLine do + FTextDrawer.ExtTextOut(Left, Top, [tooOpaque], rcLine, '', 0); + end; + // next line rect + rcLine.Top := vLineTop; + rcLine.Bottom := rcLine.Top + FTextHeight; + + s := FGutter.FormatLineNumber(cLine); + if Assigned(OnGutterGetText) then + OnGutterGetText(Self, cLine, s); + TextSize := GetTextSize(DC, PWideChar(s), Length(s)); + vTextOffset := (FGutterWidth - FGutter.RightOffset - FGutter.RightMargin) - TextSize.cx; + if FGutter.ShowModification then + vTextOffset := vTextOffset - FGutter.ModificationBarWidth; + + if FGutter.Gradient then + begin + SetBkMode(DC, TRANSPARENT); + Windows.ExtTextOutW(DC, vTextOffset, + rcLine.Top + ((FTextHeight - Integer(TextSize.cy)) div 2), 0, + @rcLine, PWideChar(s), Length(s), nil); + SetBkMode(DC, OPAQUE); + end + else + Windows.ExtTextOutW(DC, vTextOffset, + rcLine.Top + ((FTextHeight - Integer(TextSize.cy)) div 2), ETO_OPAQUE, + @rcLine, PWideChar(s), Length(s), nil); + + // eventually draw modifications + if FGutter.ShowModification then + case TSynEditStringList(FLines).Modification[cLine - 1] of + smModified: + DrawModification(FGutter.ModificationColorModified, rcLine.Top, rcLine.Bottom); + smSaved: + DrawModification(FGutter.ModificationColorSaved, rcLine.Top, rcLine.Bottom); + end; + end; + // now erase the remaining area if any + if (AClip.Bottom > rcLine.Bottom) and not FGutter.Gradient then + begin + rcLine.Top := rcLine.Bottom; + rcLine.Bottom := AClip.Bottom; + with rcLine do + FTextDrawer.ExtTextOut(Left, Top, [tooOpaque], rcLine, '', 0); + end; + finally + FTextDrawer.EndDrawing; + if FGutter.UseFontStyle then + FTextDrawer.SetBaseFont(Self.Font); + end; + end + else + begin + if not FGutter.Gradient then + Canvas.FillRect(AClip); + + if FGutter.ShowModification then + for cLine := vFirstLine to vLastLine do + begin + vLineTop := (LineToRow(cLine) - TopLine) * FTextHeight; + case TSynEditStringList(FLines).Modification[cLine - 1] of + smModified: + DrawModification(FGutter.ModificationColorModified, vLineTop, vLineTop + fTextHeight); + smSaved: + DrawModification(FGutter.ModificationColorSaved, vLineTop, vLineTop + fTextHeight); + end; + end; + end; + +{$IFDEF MSWINDOWS} + // draw Word wrap glyphs transparently over gradient + if FGutter.Gradient then + Canvas.Brush.Style := bsClear; +{$ENDIF} + // paint wrapped line glyphs + if WordWrap and FWordWrapGlyph.Visible then + for cLine := aFirstRow to aLastRow do + if LineToRow(RowToLine(cLine)) <> cLine then + FWordWrapGlyph.Draw(Canvas, + (FGutterWidth - FGutter.RightOffset - 2) - FWordWrapGlyph.Width, + (cLine - TopLine) * FTextHeight, FTextHeight); +{$IFDEF MSWINDOWS} + // restore brush + if FGutter.Gradient then + Canvas.Brush.Style := bsSolid; +{$ENDIF} + +{$IFDEF SYN_CodeFolding} + // Draw the folding lines and squares + if UseCodeFolding then begin + for cRow := aFirstRow to aLastRow do begin + vLine := RowToLine(cRow); + if (vLine > Lines.Count) and not (Lines.Count = 0) then + break; + + rcFold := GetFoldShapeRect(cRow); + + Canvas.Pen.Color := fCodeFolding.FolderBarLinesColor; + + // Any fold ranges beginning on this line? + if AllFoldRanges.FoldStartAtLine(vLine, Index) then begin + FoldRange := AllFoldRanges.Ranges[Index]; + Canvas.Brush.Color := fCodeFolding.FolderBarLinesColor; + Canvas.FrameRect(rcFold); + + // Paint minus sign + Canvas.Pen.Color := fCodeFolding.FolderBarLinesColor; + Canvas.MoveTo(rcFold.Left + 2, rcFold.Top + ((rcFold.Bottom - rcFold.Top) div 2)); + Canvas.LineTo(rcFold.Right - 2, rcFold.Top + ((rcFold.Bottom - rcFold.Top) div 2)); + + // Paint vertical line of plus sign + if FoldRange.Collapsed then begin + x := rcFold.Left + ((rcFold.Right - rcFold.Left) div 2); + Canvas.MoveTo(x, rcFold.Top + 2); + Canvas.LineTo(x, rcFold.Bottom - 2); + end + else + // Draw the bottom part of a line + begin + x := rcFold.Left + ((rcFold.Right - rcFold.Left) div 2); + Canvas.MoveTo(x, rcFold.Bottom); + Canvas.LineTo(x, (cRow - fTopLine + 1) * LineHeight); + end; + end + else begin + // Need to paint a line end? + if AllFoldRanges.FoldEndAtLine(vLine, Index) then begin + x := rcFold.Left + ((rcFold.Right - rcFold.Left) div 2); + Canvas.MoveTo(x, (cRow - fTopLine) * LineHeight); + Canvas.LineTo(x, rcFold.Top + ((rcFold.Bottom - rcFold.Top) div 2)); + Canvas.LineTo(rcFold.Right, rcFold.Top + ((rcFold.Bottom - rcFold.Top) div 2)); + end; + // Need to paint a line? + if AllFoldRanges.FoldAroundLine(vLine, Index) then begin + x := rcFold.Left + ((rcFold.Right - rcFold.Left) div 2); + Canvas.MoveTo(x, (cRow - fTopLine) * LineHeight); + Canvas.LineTo(x, (cRow - fTopLine + 1) * LineHeight); + end; + end; + end; + end; +{$ENDIF} + + // the gutter separator if visible + if (FGutter.BorderStyle <> gbsNone) and (AClip.Right >= FGutterWidth - 2) then + with Canvas do + begin + Pen.Color := FGutter.BorderColor; + Pen.Width := 1; + with AClip do + begin + if FGutter.BorderStyle = gbsMiddle then + begin + MoveTo(FGutterWidth - 2, Top); + LineTo(FGutterWidth - 2, Bottom); + Pen.Color := FGutter.Color; + end; + MoveTo(FGutterWidth - 1, Top); + LineTo(FGutterWidth - 1, Bottom); + end; + end; + + // now the gutter marks + if BookMarkOptions.GlyphsVisible and (Marks.Count > 0) + and (vLastLine >= vFirstLine) then + begin + aGutterOffs := AllocMem((aLastRow - aFirstRow + 1) * SizeOf(Integer)); + try + // Instead of making a two pass loop we look while drawing the bookmarks + // whether there is any other mark to be drawn + bHasOtherMarks := False; + for cMark := 0 to Marks.Count - 1 do with Marks[cMark] do +{$IFDEF SYN_CodeFolding} + if Visible and (Line >= vFirstLine) and (Line <= vLastLine) and (Line <= FLines.Count) + and not (UseCodeFolding and AllFoldRanges.FoldHidesLine(Line, Index)) + then +{$ELSE} + if Visible and (Line >= vFirstLine) and (Line <= vLastLine) then +{$ENDIF} + begin + if IsBookmark <> BookMarkOptions.DrawBookmarksFirst then + bHasOtherMarks := True + else begin + vMarkRow := LineToRow(Line); + if vMarkRow >= aFirstRow then + DrawMark(Marks[cMark], aGutterOffs[vMarkRow - aFirstRow], vMarkRow); + end + end; + if bHasOtherMarks then + for cMark := 0 to Marks.Count - 1 do with Marks[cMark] do + begin + if Visible and (IsBookmark <> BookMarkOptions.DrawBookmarksFirst) +{$IFDEF SYN_CodeFolding} + and (Line >= vFirstLine) and (Line <= vLastLine) and (Line <= FLines.Count) + and not (UseCodeFolding and AllFoldRanges.FoldHidesLine(Line, Index)) then +{$ELSE} + and (Line >= vFirstLine) and (Line <= vLastLine) then +{$ENDIF} + begin + vMarkRow := LineToRow(Line); + if vMarkRow >= aFirstRow then + DrawMark(Marks[cMark], aGutterOffs[vMarkRow - aFirstRow], vMarkRow); + end; + end; + if Assigned(OnGutterPaint) then + for cLine := vFirstLine to vLastLine do + begin + vGutterRow := LineToRow(cLine); + OnGutterPaint(Self, cLine, aGutterOffs[vGutterRow - aFirstRow], + (vGutterRow - TopLine) * LineHeight); + end; + finally + FreeMem(aGutterOffs); + end; + end + else if Assigned(OnGutterPaint) then + begin + for cLine := vFirstLine to vLastLine do + begin + vGutterRow := LineToRow(cLine); + OnGutterPaint(Self, cLine, 0, (vGutterRow - TopLine) * LineHeight); + end; + end; +end; + +// Inserts filling chars into a string containing chars that display as glyphs +// wider than an average glyph. (This is often the case with Asian glyphs, which +// are usually wider than latin glpyhs) +// This is only to simplify paint-operations and has nothing to do with +// multi-byte chars. +function TCustomSynEdit.ExpandAtWideGlyphs(const S: UnicodeString): UnicodeString; +var + i, j, CountOfAvgGlyphs: Integer; +begin + Result := S; + j := 0; + SetLength(Result, Length(S) * 2); // speed improvement + + for i := 1 to Length(S) do + begin + Inc(j); + CountOfAvgGlyphs := CeilOfIntDiv(FTextDrawer.TextWidth(S[i]), FCharWidth); + + if j + CountOfAvgGlyphs > Length(Result) then + SetLength(Result, Length(Result) + 128); + + // insert CountOfAvgGlyphs filling chars + while CountOfAvgGlyphs > 1 do + begin + Result[j] := FillerChar; + Inc(j); + Dec(CountOfAvgGlyphs); + end; + + Result[j] := S[i]; + end; + + SetLength(Result, j); +end; + +// does the opposite of ExpandAtWideGlyphs +function TCustomSynEdit.ShrinkAtWideGlyphs(const S: UnicodeString; First: Integer; + var CharCount: Integer): UnicodeString; +var + i, j: Integer; +begin + SetLength(Result, Length(S)); + + i := First; + j := 0; + while i < First + CharCount do + begin + Inc(j); + while S[i] = FillerChar do + Inc(i); + Result[j] := S[i]; + Inc(i); + end; + + SetLength(Result, j); + CharCount := j; +end; + +procedure TCustomSynEdit.PaintTextLines(AClip: TRect; const aFirstRow, aLastRow, + FirstCol, LastCol: Integer); +var + bDoRightEdge: Boolean; // right edge + nRightEdge: Integer; + // selection info + bAnySelection: Boolean; // any selection visible? + vSelStart: TDisplayCoord; // start of selected area + vSelEnd: TDisplayCoord; // end of selected area + // info about normal and selected text and background colors + bSpecialLine, bLineSelected, bCurrentLine: Boolean; + colFG, colBG: TColor; + colSelFG, colSelBG: TColor; + // info about selection of the current line + nLineSelStart, nLineSelEnd: Integer; + bComplexLine: Boolean; + // painting the background and the text + rcLine, rcToken: TRect; + TokenAccu: record + // Note: s is not managed as a string, it will only grow!!! + // Never use AppendStr or "+", use Len and MaxLen instead and + // copy the string chars directly. This is for efficiency. + Len, MaxLen, CharsBefore: Integer; + s: UnicodeString; + TabString: UnicodeString; + FG, BG: TColor; + Style: TFontStyles; + end; + dc: HDC; + SynTabGlyphString: UnicodeString; + + vFirstLine: Integer; + vLastLine: Integer; + +{ local procedures } + + function colEditorBG: TColor; + var + iAttri: TSynHighlighterAttributes; + begin + if (ActiveLineColor <> clNone) and (bCurrentLine) then + Result := ActiveLineColor + else begin + Result := Color; + if Highlighter <> nil then + begin + iAttri := Highlighter.WhitespaceAttribute; + if (iAttri <> nil) and (iAttri.Background <> clNone) then + Result := iAttri.Background; + end; + end; + end; + + procedure ComputeSelectionInfo; + var + vStart: TBufferCoord; + vEnd: TBufferCoord; + begin + bAnySelection := False; + // Only if selection is visible anyway. + if not HideSelection or Self.Focused then + begin + bAnySelection := True; + // Get the *real* start of the selected area. + if FBlockBegin.Line < FBlockEnd.Line then + begin + vStart := FBlockBegin; + vEnd := FBlockEnd; + end + else if FBlockBegin.Line > FBlockEnd.Line then + begin + vEnd := FBlockBegin; + vStart := FBlockEnd; + end + else if FBlockBegin.Char <> FBlockEnd.Char then + begin + // No selection at all, or it is only on this line. + vStart.Line := FBlockBegin.Line; + vEnd.Line := vStart.Line; + if FBlockBegin.Char < FBlockEnd.Char then + begin + vStart.Char := FBlockBegin.Char; + vEnd.Char := FBlockEnd.Char; + end + else + begin + vStart.Char := FBlockEnd.Char; + vEnd.Char := FBlockBegin.Char; + end; + end + else + bAnySelection := False; + // If there is any visible selection so far, then test if there is an + // intersection with the area to be painted. + if bAnySelection then + begin + // Don't care if the selection is not visible. + bAnySelection := (vEnd.Line >= vFirstLine) and (vStart.Line <= vLastLine); + if bAnySelection then + begin + // Transform the selection from text space into screen space + vSelStart := BufferToDisplayPos(vStart); + vSelEnd := BufferToDisplayPos(vEnd); + // In the column selection mode sort the begin and end of the selection, + // this makes the painting code simpler. + if (FActiveSelectionMode = smColumn) and (vSelStart.Column > vSelEnd.Column) then + SwapInt(vSelStart.Column, vSelEnd.Column); + end; + end; + end; + end; + + procedure SetDrawingColors(Selected: Boolean); + begin + with FTextDrawer do + if Selected then + begin + SetBackColor(colSelBG); + SetForeColor(colSelFG); + Canvas.Brush.Color := colSelBG; + end + else begin + SetBackColor(colBG); + SetForeColor(colFG); + Canvas.Brush.Color := colBG; + end; + end; + + function ColumnToXValue(Col: Integer): Integer; + begin + Result := FTextOffset + Pred(Col) * FCharWidth; + end; + + //todo: Review SpecialChars and HardTabs painting. Token parameter of PaintToken procedure could very probably be passed by reference. + + // Note: The PaintToken procedure will take care of invalid parameters + // like empty token rect or invalid indices into TokenLen. + // CharsBefore tells if Token starts at column one or not + procedure PaintToken(Token: UnicodeString; + TokenLen, CharsBefore, First, Last: Integer); + var + Text: UnicodeString; + Counter, nX, nCharsToPaint: Integer; + sTabbedToken: UnicodeString; + DoTabPainting: Boolean; + i, TabStart, TabLen, CountOfAvgGlyphs, VisibleGlyphPart, FillerCount, + NonFillerPos: Integer; + rcTab: TRect; + const + ETOOptions = [tooOpaque, tooClipped]; + begin + sTabbedToken := Token; + DoTabPainting := False; + + Counter := Last - CharsBefore; + while Counter > First - CharsBefore - 1 do + begin + if Length(Token) >= Counter then + begin + if FShowSpecChar and (Token[Counter] = #32) then + Token[Counter] := SynSpaceGlyph + else if Token[Counter] = #9 then + begin + Token[Counter] := #32; //Tabs painted differently if necessary + DoTabPainting := FShowSpecChar; + end; + end; + Dec(Counter); + end; + + if (Last >= First) and (rcToken.Right > rcToken.Left) then + begin + nX := ColumnToXValue(First); + + Dec(First, CharsBefore); + Dec(Last, CharsBefore); + + if (First > TokenLen) then + begin + nCharsToPaint := 0; + Text := ''; + end + else + begin + FillerCount := 0; + NonFillerPos := First; + while Token[NonFillerPos] = FillerChar do + begin + Inc(FillerCount); + Inc(NonFillerPos); + end; + + CountOfAvgGlyphs := CeilOfIntDiv(FTextDrawer.TextWidth(Token[NonFillerPos]) , FCharWidth); + + // first visible part of the glyph (1-based) + // (the glyph is visually sectioned in parts of size FCharWidth) + VisibleGlyphPart := CountOfAvgGlyphs - FillerCount; + + // clip off invisible parts + nX := nX - FCharWidth * (VisibleGlyphPart - 1); + + nCharsToPaint := Min(Last - First + 1, TokenLen - First + 1); + + // clip off partially visible glyphs at line end + if WordWrap then + while nX + FCharWidth * nCharsToPaint > ClientWidth do + begin + Dec(nCharsToPaint); + while (nCharsToPaint > 0) and (Token[First + nCharsToPaint - 1] = FillerChar) do + Dec(nCharsToPaint); + end; + + // same as copy(Token, First, nCharsToPaint) and remove filler chars + Text := ShrinkAtWideGlyphs(Token, First, nCharsToPaint); + end; + + FTextDrawer.ExtTextOut(nX, rcToken.Top, ETOOptions, rcToken, + PWideChar(Text), nCharsToPaint); + + if DoTabPainting then + begin + // fix everything before the FirstChar + for i := 1 to First - 1 do // wipe the text out so we don't + if sTabbedToken[i] = #9 then // count it out of the range + sTabbedToken[i] := #32; // we're looking for + + TabStart := pos(#9, sTabbedToken); + rcTab.Top := rcToken.Top; + rcTab.Bottom := rcToken.Bottom; + while (TabStart > 0) and (TabStart >= First) and (TabStart <= Last) do + begin + TabLen := 1; + while (TabStart + CharsBefore + TabLen - 1) mod FTabWidth <> 0 do Inc(TabLen); + Text := SynTabGlyphString; + + nX := ColumnToXValue(CharsBefore + TabStart + (TabLen div 2) - 1); + if TabLen mod 2 = 0 then + nX := nX + (FCharWidth div 2) + else nX := nX + FCharWidth; + + rcTab.Left := nX; + rcTab.Right := nX + FTextDrawer.GetCharWidth; + + FTextDrawer.ExtTextOut(nX, rcTab.Top, ETOOptions, rcTab, + PWideChar(Text), 1); + + for i := 0 to TabLen - 1 do //wipe the text out so we don't + sTabbedToken[TabStart + i] := #32; //count it again + + TabStart := pos(#9, sTabbedToken); + end; + end; + rcToken.Left := rcToken.Right; + end; + end; + + procedure AdjustEndRect; + // trick to avoid clipping the last pixels of text in italic, + // see also AdjustLastCharWidth() in TSynTextDrawer.ExtTextOut() + var + LastChar: Cardinal; + NormalCharWidth, RealCharWidth: Integer; + CharInfo: TABC; + tm: TTextMetricA; + begin + LastChar := Ord(TokenAccu.s[TokenAccu.Len]); + NormalCharWidth := FTextDrawer.TextWidth(WideChar(LastChar)); + RealCharWidth := NormalCharWidth; + if Win32PlatformIsUnicode then + begin + if GetCharABCWidthsW(Canvas.Handle, LastChar, LastChar, CharInfo) then + begin + RealCharWidth := CharInfo.abcA + Integer(CharInfo.abcB); + if CharInfo.abcC >= 0 then + Inc(RealCharWidth, CharInfo.abcC); + end + else if LastChar < Ord(High(AnsiChar)) then + begin + GetTextMetricsA(Canvas.Handle, tm); + RealCharWidth := tm.tmAveCharWidth + tm.tmOverhang; + end; + end + else if WideChar(LastChar) <= High(AnsiChar) then + begin + if GetCharABCWidths(Canvas.Handle, LastChar, LastChar, CharInfo) then + begin + RealCharWidth := CharInfo.abcA + Integer(CharInfo.abcB); + if CharInfo.abcC >= 0 then + Inc(RealCharWidth, CharInfo.abcC); + end + else if LastChar < Ord(High(AnsiChar)) then + begin + GetTextMetricsA(Canvas.Handle, tm); + RealCharWidth := tm.tmAveCharWidth + tm.tmOverhang; + end; + end; + + if RealCharWidth > NormalCharWidth then + Inc(rcToken.Left, RealCharWidth - NormalCharWidth); + end; + + procedure PaintHighlightToken(bFillToEOL: Boolean); + var + bComplexToken: Boolean; + nC1, nC2, nC1Sel, nC2Sel: Integer; + bU1, bSel, bU2: Boolean; + nX1, nX2: Integer; + begin + // Compute some helper variables. + nC1 := Max(FirstCol, TokenAccu.CharsBefore + 1); + nC2 := Min(LastCol, TokenAccu.CharsBefore + TokenAccu.Len + 1); + if bComplexLine then + begin + bU1 := (nC1 < nLineSelStart); + bSel := (nC1 < nLineSelEnd) and (nC2 >= nLineSelStart); + bU2 := (nC2 >= nLineSelEnd); + bComplexToken := bSel and (bU1 or bU2); + end + else + begin + bU1 := False; // to shut up Compiler warning Delphi 2 + bSel := bLineSelected; + bU2 := False; // to shut up Compiler warning Delphi 2 + bComplexToken := False; + end; + // Any token chars accumulated? + if (TokenAccu.Len > 0) then + begin + // Initialize the colors and the font style. + if not bSpecialLine then + begin + colBG := TokenAccu.BG; + colFG := TokenAccu.FG; + end; + + if bSpecialLine and (eoSpecialLineDefaultFg in FOptions) then + colFG := TokenAccu.FG; + + FTextDrawer.SetStyle(TokenAccu.Style); + // Paint the chars + if bComplexToken then + begin + // first unselected part of the token + if bU1 then + begin + SetDrawingColors(False); + rcToken.Right := ColumnToXValue(nLineSelStart); + with TokenAccu do + PaintToken(s, Len, CharsBefore, nC1, nLineSelStart); + end; + // selected part of the token + SetDrawingColors(True); + nC1Sel := Max(nLineSelStart, nC1); + nC2Sel := Min(nLineSelEnd, nC2); + rcToken.Right := ColumnToXValue(nC2Sel); + with TokenAccu do + PaintToken(s, Len, CharsBefore, nC1Sel, nC2Sel); + // second unselected part of the token + if bU2 then + begin + SetDrawingColors(False); + rcToken.Right := ColumnToXValue(nC2); + with TokenAccu do + PaintToken(s, Len, CharsBefore, nLineSelEnd, nC2); + end; + end + else + begin + SetDrawingColors(bSel); + rcToken.Right := ColumnToXValue(nC2); + with TokenAccu do + PaintToken(s, Len, CharsBefore, nC1, nC2); + end; + end; + + // Fill the background to the end of this line if necessary. + if bFillToEOL and (rcToken.Left < rcLine.Right) then + begin + if not bSpecialLine then colBG := colEditorBG; + if bComplexLine then + begin + nX1 := ColumnToXValue(nLineSelStart); + nX2 := ColumnToXValue(nLineSelEnd); + if (rcToken.Left < nX1) then + begin + SetDrawingColors(False); + rcToken.Right := nX1; + if (TokenAccu.Len > 0) and (TokenAccu.Style <> []) then + AdjustEndRect; + Canvas.FillRect(rcToken); + rcToken.Left := nX1; + end; + if (rcToken.Left < nX2) then + begin + SetDrawingColors(True); + rcToken.Right := nX2; + if (TokenAccu.Len > 0) and (TokenAccu.Style <> []) then + AdjustEndRect; + Canvas.FillRect(rcToken); + rcToken.Left := nX2; + end; + if (rcToken.Left < rcLine.Right) then + begin + SetDrawingColors(False); + rcToken.Right := rcLine.Right; + if (TokenAccu.Len > 0) and (TokenAccu.Style <> []) then + AdjustEndRect; + Canvas.FillRect(rcToken); + end; + end + else + begin + SetDrawingColors(bLineSelected); + rcToken.Right := rcLine.Right; + if (TokenAccu.Len > 0) and (TokenAccu.Style <> []) then + AdjustEndRect; + Canvas.FillRect(rcToken); + end; + end; + end; + + // Store the token chars with the attributes in the TokenAccu + // record. This will paint any chars already stored if there is + // a (visible) change in the attributes. + procedure AddHighlightToken(const Token: UnicodeString; + CharsBefore, TokenLen: Integer; + Foreground, Background: TColor; + Style: TFontStyles); + var + bCanAppend: Boolean; + bSpacesTest, bIsSpaces: Boolean; + i: Integer; + + function TokenIsSpaces: Boolean; + var + pTok: PWideChar; + begin + if not bSpacesTest then + begin + bSpacesTest := True; + pTok := PWideChar(Token); + while pTok^ <> #0 do + begin + if pTok^ <> #32 then + Break; + Inc(pTok); + end; + bIsSpaces := pTok^ = #0; + end; + Result := bIsSpaces; + end; + + begin + if (Background = clNone) or + ((ActiveLineColor <> clNone) and (bCurrentLine)) then + begin + Background := colEditorBG; + end; + if Foreground = clNone then Foreground := Font.Color; + // Do we have to paint the old chars first, or can we just append? + bCanAppend := False; + bSpacesTest := False; + if (TokenAccu.Len > 0) then + begin + // font style must be the same or token is only spaces + if (TokenAccu.Style = Style) + or (not (fsUnderline in Style) and not (fsUnderline in TokenAccu.Style) + and TokenIsSpaces) then + begin + // either special colors or same colors + if (bSpecialLine and not (eoSpecialLineDefaultFg in FOptions)) or bLineSelected or + // background color must be the same and + ((TokenAccu.BG = Background) and + // foreground color must be the same or token is only spaces + ((TokenAccu.FG = Foreground) or TokenIsSpaces)) then + begin + bCanAppend := True; + end; + end; + // If we can't append it, then we have to paint the old token chars first. + if not bCanAppend then + PaintHighlightToken(False); + end; + // Don't use AppendStr because it's more expensive. + if bCanAppend then + begin + if (TokenAccu.Len + TokenLen > TokenAccu.MaxLen) then + begin + TokenAccu.MaxLen := TokenAccu.Len + TokenLen + 32; + SetLength(TokenAccu.s, TokenAccu.MaxLen); + end; + for i := 1 to TokenLen do + TokenAccu.s[TokenAccu.Len + i] := Token[i]; + Inc(TokenAccu.Len, TokenLen); + end + else + begin + TokenAccu.Len := TokenLen; + if (TokenAccu.Len > TokenAccu.MaxLen) then + begin + TokenAccu.MaxLen := TokenAccu.Len + 32; + SetLength(TokenAccu.s, TokenAccu.MaxLen); + end; + for i := 1 to TokenLen do + TokenAccu.s[i] := Token[i]; + TokenAccu.CharsBefore := CharsBefore; + TokenAccu.FG := Foreground; + TokenAccu.BG := Background; + TokenAccu.Style := Style; + end; + end; + +{$IFDEF SYN_CodeFolding} + procedure PaintFoldAttributes; + var + i, TabSteps, LineIndent, LastNonBlank, X, Y, cRow, vLine: Integer; + DottedPen, OldPen: HPEN; + DottedPenDesc: LOGBRUSH; + CollapsedTo : integer; + HintRect : TRect; + begin + // Paint indent guides. Use folds to determine indent value of these + // Use a separate loop so we can use a custom pen + if not UseCodeFolding then + Exit; + + // Paint indent guides using custom pen + if fCodeFolding.IndentGuides then begin + DottedPenDesc.lbStyle := BS_SOLID; + DottedPenDesc.lbColor := fCodeFolding.IndentGuidesColor; + DottedPen := ExtCreatePen(PS_COSMETIC or PS_ALTERNATE, 1, DottedPenDesc, 0, nil); + try + OldPen := SelectObject(Canvas.Handle, DottedPen); + + // Now loop through all the lines. The indices are valid for Lines. + for cRow := aFirstRow to aLastRow do begin + vLine := RowToLine(cRow); + if (vLine > Lines.Count) and not (Lines.Count = 0) then + break; + + // Set vertical coord + Y := (LineToRow(vLine) - TopLine) * fTextHeight; // limit inside clip rect + if (fTextHeight mod 2 = 1) and (vLine mod 2 = 0) then // even + Inc(Y); + + // Get next nonblank line + LastNonBlank := cRow; + while (RowToLine(LastNonBlank) <= fLines.Count) + and (TrimLeft(fLines[RowToLine(LastNonBlank)-1]) = '') do + Inc(LastNonBlank); + LineIndent := LeftSpacesEx(fLines[RowToLine(LastNonBlank)-1], True, True); + + // Step horizontal coord + TabSteps := TabWidth; + while TabSteps < LineIndent do begin + X := TabSteps * CharWidth + fTextOffset - 2; + if TabSteps >= fLeftChar then begin + // Move to top of vertical line + Canvas.MoveTo(X, Y); + Inc(Y, fTextHeight); + + // Draw down and move back up + Canvas.LineTo(X, Y); + Dec(Y, fTextHeight); + end; + Inc(TabSteps, TabWidth); + end; + end; + + // Reset pen + SelectObject(Canvas.Handle, OldPen); + finally + DeleteObject(DottedPen); + end; + end; + + // Paint collapsed lines using changed pen + if fCodeFolding.ShowCollapsedLine or fCodeFolding.ShowHintMark then begin + Canvas.Pen.Color := fCodeFolding.CollapsedLineColor; + + CollapsedTo := 0; + for i := 0 to fAllFoldRanges.Count - 1 do begin + with fAllFoldRanges.Ranges[i] do begin + if FromLine > vLastLine then + break; + if Collapsed and (FromLine > CollapsedTo) and (FromLine >= vFirstLine) then + begin + if fCodeFolding.ShowCollapsedLine then + begin + // Get starting and end points + Y := (LineToRow(FromLine) - TopLine + 1) * fTextHeight - 1; + Canvas.MoveTo(AClip.Left, Y); + Canvas.LineTo(AClip.Right, Y); + end; + if fCodeFolding.ShowHintMark then + begin + HintRect := GetCollapseMarkRect(LineToRow(FromLine), FromLine); + if InRange(HintRect.Left, 1, ClientWidth-1) then + begin + fTextDrawer.BeginDrawing(Canvas.Handle); + SetBkMode(Canvas.Handle, TRANSPARENT); + fTextDrawer.SetForeColor(fCodeFolding.CollapsedLineColor); + with HintRect do + ftextDrawer.ExtTextOut(Left + 2 * CharWidth div 7, + Top - LineHeight div 5, [], HintRect, '...', 3); + SetBkMode(Canvas.Handle, OPAQUE); + Canvas.Pen.Width := IfThen(LineHeight > 30, 2, 1); + Canvas.Brush.Style := bsClear; + Inc(HintRect.Top, LineHeight div 7); + Canvas.Rectangle(HintRect); + Canvas.Brush.Style := bsSolid; + Canvas.Pen.Width := 1; + fTextDrawer.EndDrawing; + end; + end; + end; + if Collapsed then + CollapsedTo := Max(CollapsedTo, ToLine); + end; + end; + end; + end; +{$ENDIF} + + procedure PaintLines; + var + nLine: Integer; // line index for the loop + cRow: Integer; + sLine: UnicodeString; // the current line (tab expanded) + sLineExpandedAtWideGlyphs: UnicodeString; + sToken: UnicodeString; // highlighter token info + nTokenPos, nTokenLen: Integer; + attr: TSynHighlighterAttributes; + vAuxPos: TDisplayCoord; + vFirstChar: Integer; + vLastChar: Integer; + vStartRow: Integer; + vEndRow: Integer; + TokenFG, TokenBG: TColor; + TokenStyle: TFontStyles; + begin + // Initialize rcLine for drawing. Note that Top and Bottom are updated + // inside the loop. Get only the starting point for this. + rcLine := AClip; + rcLine.Left := FGutterWidth + 2; + rcLine.Bottom := (aFirstRow - TopLine) * FTextHeight; + // Make sure the token accumulator string doesn't get reassigned to often. + if Assigned(FHighlighter) then + begin + TokenAccu.MaxLen := Max(128, FCharsInWindow); + SetLength(TokenAccu.s, TokenAccu.MaxLen); + end; + // Now loop through all the lines. The indices are valid for Lines. + for nLine := vFirstLine to vLastLine do + begin +{$IFDEF SYN_CodeFolding} + if UseCodeFolding and AllFoldRanges.FoldHidesLine(nLine) then + continue; +{$ENDIF} + sLine := TSynEditStringList(Lines).ExpandedStrings[nLine - 1]; + sLineExpandedAtWideGlyphs := ExpandAtWideGlyphs(sLine); + // determine whether will be painted with ActiveLineColor + bCurrentLine := CaretY = nLine; + // Initialize the text and background colors, maybe the line should + // use special values for them. + colFG := Font.Color; + colBG := colEditorBG; + bSpecialLine := DoOnSpecialLineColors(nLine, colFG, colBG); + if bSpecialLine then + begin + // The selection colors are just swapped, like seen in Delphi. + colSelFG := colBG; + colSelBG := colFG; + end + else + begin + colSelFG := FSelectedColor.Foreground; + colSelBG := FSelectedColor.Background; + end; + + vStartRow := Max(LineToRow(nLine), aFirstRow); + vEndRow := Min(LineToRow(nLine + 1) - 1, aLastRow); +{$IFDEF SYN_CodeFolding} + vEndRow := Max(vEndRow, vStartRow); +{$ENDIF} + for cRow := vStartRow to vEndRow do + begin + if WordWrap then + begin + vAuxPos.Row := cRow; + if Assigned(FHighlighter) then + vAuxPos.Column := FirstCol + else + // When no highlighter is assigned, we must always start from the + // first char in a row and PaintToken will do the actual clipping + vAuxPos.Column := 1; + vFirstChar := FWordWrapPlugin.DisplayToBufferPos(vAuxPos).Char; + vAuxPos.Column := LastCol; + vLastChar := FWordWrapPlugin.DisplayToBufferPos(vAuxPos).Char; + end + else + begin + vFirstChar := FirstCol; + vLastChar := LastCol; + end; + // Get the information about the line selection. Three different parts + // are possible (unselected before, selected, unselected after), only + // unselected or only selected means bComplexLine will be False. Start + // with no selection, compute based on the visible columns. + bComplexLine := False; + nLineSelStart := 0; + nLineSelEnd := 0; + // Does the selection intersect the visible area? + if bAnySelection and (cRow >= vSelStart.Row) and (cRow <= vSelEnd.Row) then + begin + // Default to a fully selected line. This is correct for the smLine + // selection mode and a good start for the smNormal mode. + nLineSelStart := FirstCol; + nLineSelEnd := LastCol + 1; + if (FActiveSelectionMode = smColumn) or + ((FActiveSelectionMode = smNormal) and (cRow = vSelStart.Row)) then + begin + if (vSelStart.Column > LastCol) then + begin + nLineSelStart := 0; + nLineSelEnd := 0; + end + else if (vSelStart.Column > FirstCol) then + begin + nLineSelStart := vSelStart.Column; + bComplexLine := True; + end; + end; + if (FActiveSelectionMode = smColumn) or + ((FActiveSelectionMode = smNormal) and (cRow = vSelEnd.Row)) then + begin + if (vSelEnd.Column < FirstCol) then + begin + nLineSelStart := 0; + nLineSelEnd := 0; + end + else if (vSelEnd.Column < LastCol) then + begin + nLineSelEnd := vSelEnd.Column; + bComplexLine := True; + end; + end; + end; //endif bAnySelection + + // Update the rcLine rect to this line. + rcLine.Top := rcLine.Bottom; + Inc(rcLine.Bottom, FTextHeight); + + bLineSelected := not bComplexLine and (nLineSelStart > 0); + rcToken := rcLine; + + if not Assigned(FHighlighter) or not FHighlighter.Enabled then + begin + // Remove text already displayed (in previous rows) + if (vFirstChar <> FirstCol) or (vLastChar <> LastCol) then + sToken := Copy(sLineExpandedAtWideGlyphs, vFirstChar, vLastChar - vFirstChar) + else + sToken := Copy(sLineExpandedAtWideGlyphs, 1, vLastChar); + if FShowSpecChar and (Length(sLineExpandedAtWideGlyphs) < vLastChar) then + sToken := sToken + SynLineBreakGlyph; + nTokenLen := Length(sToken); + if bComplexLine then + begin + SetDrawingColors(False); + rcToken.Left := Max(rcLine.Left, ColumnToXValue(FirstCol)); + rcToken.Right := Min(rcLine.Right, ColumnToXValue(nLineSelStart)); + PaintToken(sToken, nTokenLen, 0, FirstCol, nLineSelStart); + rcToken.Left := Max(rcLine.Left, ColumnToXValue(nLineSelEnd)); + rcToken.Right := Min(rcLine.Right, ColumnToXValue(LastCol)); + PaintToken(sToken, nTokenLen, 0, nLineSelEnd, LastCol); + SetDrawingColors(True); + rcToken.Left := Max(rcLine.Left, ColumnToXValue(nLineSelStart)); + rcToken.Right := Min(rcLine.Right, ColumnToXValue(nLineSelEnd)); + PaintToken(sToken, nTokenLen, 0, nLineSelStart, nLineSelEnd - 1); + end + else + begin + SetDrawingColors(bLineSelected); + PaintToken(sToken, nTokenLen, 0, FirstCol, LastCol); + end; + end + else + begin + // Initialize highlighter with line text and range info. It is + // necessary because we probably did not scan to the end of the last + // line - the internal highlighter range might be wrong. + if nLine = 1 then + FHighlighter.ResetRange + else + FHighlighter.SetRange(TSynEditStringList(Lines).Ranges[nLine - 2]); + FHighlighter.SetLineExpandedAtWideGlyphs(sLine, sLineExpandedAtWideGlyphs, + nLine - 1); + // Try to concatenate as many tokens as possible to minimize the count + // of ExtTextOutW calls necessary. This depends on the selection state + // or the line having special colors. For spaces the foreground color + // is ignored as well. + TokenAccu.Len := 0; + nTokenPos := 0; + nTokenLen := 0; + attr := nil; + // Test first whether anything of this token is visible. + while not FHighlighter.GetEol do + begin + nTokenPos := FHighlighter.GetExpandedTokenPos; + sToken := FHighlighter.GetExpandedToken; + nTokenLen := Length(sToken); + if nTokenPos + nTokenLen >= vFirstChar then + begin + if nTokenPos + nTokenLen > vLastChar then + begin + if nTokenPos > vLastChar then + Break; + if WordWrap then + nTokenLen := vLastChar - nTokenPos - 1 + else + nTokenLen := vLastChar - nTokenPos; + end; + // Remove offset generated by tokens already displayed (in previous rows) + Dec(nTokenPos, vFirstChar - FirstCol); + // It's at least partially visible. Get the token attributes now. + attr := FHighlighter.GetTokenAttribute; + if Assigned(attr) then + begin + TokenFG := attr.Foreground; + TokenBG := attr.Background; + TokenStyle := attr.Style; + end + else + begin + TokenFG := colFG; + TokenBG := colBG; + TokenStyle := Font.Style; + end; + DoOnSpecialTokenAttributes(nLine, nTokenPos, sToken, TokenFG, TokenBG, TokenStyle); + AddHighlightToken(sToken, nTokenPos, nTokenLen, TokenFG, TokenBG, TokenStyle); + end; + // Let the highlighter scan the next token. + FHighlighter.Next; + end; + // Draw anything that's left in the TokenAccu record. Fill to the end + // of the invalid area with the correct colors. + if FShowSpecChar and FHighlighter.GetEol then + begin + if (attr = nil) or (attr <> FHighlighter.CommentAttribute) then + attr := FHighlighter.WhitespaceAttribute; + AddHighlightToken(SynLineBreakGlyph, nTokenPos + nTokenLen, 1, + attr.Foreground, attr.Background, []); + end; + PaintHighlightToken(True); + end; + // Now paint the right edge if necessary. We do it line by line to reduce + // the flicker. Should not cost very much anyway, compared to the many + // calls to ExtTextOutW. + if bDoRightEdge then + begin + Canvas.MoveTo(nRightEdge, rcLine.Top); + Canvas.LineTo(nRightEdge, rcLine.Bottom + 1); + end; + end; //endfor cRow + bCurrentLine := False; + end; //endfor cLine + end; + +{ end local procedures } + +begin + vFirstLine := RowToLine(aFirstRow); + vLastLine := RowToLine(aLastRow); + + bCurrentLine := False; + // If the right edge is visible and in the invalid area, prepare to paint it. + // Do this first to realize the pen when getting the dc variable. + SynTabGlyphString := SynTabGlyph; + bDoRightEdge := False; + if (FRightEdge > 0) then + begin // column value + nRightEdge := FTextOffset + FRightEdge * FCharWidth; // pixel value + if (nRightEdge >= AClip.Left) and (nRightEdge <= AClip.Right) then + begin + bDoRightEdge := True; + Canvas.Pen.Color := FRightEdgeColor; + Canvas.Pen.Width := 1; + end; + end; + // Do everything else with API calls. This (maybe) realizes the new pen color. + dc := Canvas.Handle; + + // If anything of the two pixel space before the text area is visible, then + // fill it with the component background color. + if (AClip.Left < FGutterWidth + 2) then + begin + rcToken := AClip; + rcToken.Left := Max(AClip.Left, FGutterWidth); + rcToken.Right := FGutterWidth + 2; + // Paint whole left edge of the text with same color. + // (value of WhiteAttribute can vary in e.g. MultiSyn) + if Highlighter <> nil then + Highlighter.ResetRange; + Canvas.Brush.Color := colEditorBG; + Canvas.FillRect(rcToken); + // Adjust the invalid area to not include this area. + AClip.Left := rcToken.Right; + end; + // Paint the visible text lines. To make this easier, compute first the + // necessary information about the selected area: is there any visible + // selected area, and what are its lines / columns? + if (vLastLine >= vFirstLine) then + begin + ComputeSelectionInfo; + FTextDrawer.Style := Font.Style; + FTextDrawer.BeginDrawing(dc); + try + PaintLines; + finally + FTextDrawer.EndDrawing; + end; + end; + // If there is anything visible below the last line, then fill this as well. + rcToken := AClip; + rcToken.Top := (aLastRow - TopLine + 1) * FTextHeight; + if (rcToken.Top < rcToken.Bottom) then + begin + if Highlighter <> nil then + Highlighter.ResetRange; + Canvas.Brush.Color := colEditorBG; + Canvas.FillRect(rcToken); + // Draw the right edge if necessary. + if bDoRightEdge then + begin + Canvas.MoveTo(nRightEdge, rcToken.Top); + Canvas.LineTo(nRightEdge, rcToken.Bottom + 1); + end; + end; + + {$IFDEF SYN_CodeFolding} + // This messes with pen colors, so draw after right margin has been drawn + PaintFoldAttributes; +{$ENDIF} +end; + +procedure TCustomSynEdit.PasteFromClipboard; +var + AddPasteEndMarker: Boolean; + vStartOfBlock: TBufferCoord; + vEndOfBlock: TBufferCoord; + StoredPaintLock: Integer; + PasteMode: TSynSelectionMode; + Mem: HGLOBAL; + P: PByte; +begin + if not CanPaste then + Exit; + DoOnPaintTransient(ttBefore); + BeginUndoBlock; + AddPasteEndMarker := False; + PasteMode := SelectionMode; + try + // Check for our special format and read PasteMode. + // The text is ignored as it is ANSI-only to stay compatible with programs + // using the ANSI version of uRESTDWPrivSynEdit. + // + // Instead we take the text stored in CF_UNICODETEXT or CF_TEXT. + if Clipboard.HasFormat(SynEditClipboardFormat) then + begin + Clipboard.Open; + try + Mem := Clipboard.GetAsHandle(SynEditClipboardFormat); + P := GlobalLock(Mem); + try + if P <> nil then + PasteMode := PSynSelectionMode(P)^; + finally + GlobalUnlock(Mem); + end + finally + Clipboard.Close; + end; + end; + + FUndoList.AddChange(crPasteBegin, BlockBegin, BlockEnd, '', smNormal); + AddPasteEndMarker := True; + if SelAvail then + begin + FUndoList.AddChange(crDelete, FBlockBegin, FBlockEnd, SelText, + FActiveSelectionMode); + end + else + ActiveSelectionMode := SelectionMode; + + if SelAvail then + begin + vStartOfBlock := BlockBegin; + vEndOfBlock := BlockEnd; + FBlockBegin := vStartOfBlock; + FBlockEnd := vEndOfBlock; + + // Pasting always occurs at column 0 when current selection is + // smLine type + if FActiveSelectionMode = smLine then + vStartOfBlock.Char := 1; + end + else + vStartOfBlock := CaretXY; + + Inc(FPaintTransientLock); + SetSelTextPrimitiveEx(PasteMode, PWideChar(GetClipboardText), True); + Dec(FPaintTransientLock); + vEndOfBlock := BlockEnd; + if PasteMode = smNormal then + FUndoList.AddChange(crPaste, vStartOfBlock, vEndOfBlock, SelText, + PasteMode) + else if PasteMode = smColumn then + // Do nothing. Moved to InsertColumn + else if PasteMode = smLine then + if CaretX = 1 then + FUndoList.AddChange(crPaste, BufferCoord(1, vStartOfBlock.Line), + BufferCoord(CharsInWindow, vEndOfBlock.Line - 1), SelText, smLine) + else + FUndoList.AddChange(crPaste, BufferCoord(1, vStartOfBlock.Line), + vEndOfBlock, SelText, smNormal); + finally + if AddPasteEndMarker then + FUndoList.AddChange(crPasteEnd, BlockBegin, BlockEnd, '', smNormal); + EndUndoBlock; + end; + + // ClientRect can be changed by UpdateScrollBars if eoHideShowScrollBars + // is enabled + if eoHideShowScrollBars in Options then + begin + StoredPaintLock := FPaintLock; + try + FPaintLock := 0; + UpdateScrollBars; + finally + FPaintLock := StoredPaintLock; + end; + end; + + EnsureCursorPosVisible; + // Selection should have changed... + StatusChanged([scSelection]); + DoOnPaintTransient(ttAfter); +end; + +procedure TCustomSynEdit.SelectAll; +var + LastPt: TBufferCoord; +begin + LastPt.Char := 1; + LastPt.Line := Lines.Count; + if LastPt.Line > 0 then + Inc(LastPt.Char, Length(Lines[LastPt.Line - 1])) + else + LastPt.Line := 1; + SetCaretAndSelection(LastPt, BufferCoord(1, 1), LastPt); + // Selection should have changed... + StatusChanged([scSelection]); +end; + +procedure TCustomSynEdit.SetBlockBegin(Value: TBufferCoord); +var + nInval1, nInval2: Integer; + SelChanged: Boolean; +begin + ActiveSelectionMode := SelectionMode; + if (eoScrollPastEol in Options) and not WordWrap then + Value.Char := MinMax(Value.Char, 1, FMaxScrollWidth + 1) + else + Value.Char := Max(Value.Char, 1); + Value.Line := MinMax(Value.Line, 1, Lines.Count); + if (FActiveSelectionMode = smNormal) then + if (Value.Line >= 1) and (Value.Line <= Lines.Count) then + Value.Char := Min(Value.Char, Length(Lines[Value.Line - 1]) + 1) + else + Value.Char := 1; + if SelAvail then + begin + if FBlockBegin.Line < FBlockEnd.Line then + begin + nInval1 := Min(Value.Line, FBlockBegin.Line); + nInval2 := Max(Value.Line, FBlockEnd.Line); + end + else + begin + nInval1 := Min(Value.Line, FBlockEnd.Line); + nInval2 := Max(Value.Line, FBlockBegin.Line); + end; + FBlockBegin := Value; + FBlockEnd := Value; + InvalidateLines(nInval1, nInval2); + SelChanged := True; + end + else + begin + SelChanged := + (FBlockBegin.Char <> Value.Char) or (FBlockBegin.Line <> Value.Line) or + (FBlockEnd.Char <> Value.Char) or (FBlockEnd.Line <> Value.Line); + FBlockBegin := Value; + FBlockEnd := Value; + end; + if SelChanged then + StatusChanged([scSelection]); +end; + +procedure TCustomSynEdit.SetBlockEnd(Value: TBufferCoord); +var + nLine: Integer; +begin + ActiveSelectionMode := SelectionMode; + if not (eoNoSelection in Options) then + begin + if (eoScrollPastEol in Options) and not WordWrap then + Value.Char := MinMax(Value.Char, 1, FMaxScrollWidth + 1) + else + Value.Char := Max(Value.Char, 1); + Value.Line := MinMax(Value.Line, 1, Lines.Count); + if (FActiveSelectionMode = smNormal) then + if (Value.Line >= 1) and (Value.Line <= Lines.Count) then + Value.Char := Min(Value.Char, Length(Lines[Value.Line - 1]) + 1) + else + Value.Char := 1; + if (Value.Char <> FBlockEnd.Char) or (Value.Line <> FBlockEnd.Line) then + begin + if (Value.Char <> FBlockEnd.Char) or (Value.Line <> FBlockEnd.Line) then + begin + if (FActiveSelectionMode = smColumn) and (Value.Char <> FBlockEnd.Char) then + begin + InvalidateLines( + Min(FBlockBegin.Line, Min(FBlockEnd.Line, Value.Line)), + Max(FBlockBegin.Line, Max(FBlockEnd.Line, Value.Line))); + FBlockEnd := Value; + end + else begin + nLine := FBlockEnd.Line; + FBlockEnd := Value; + if (FActiveSelectionMode <> smColumn) or (FBlockBegin.Char <> FBlockEnd.Char) then + InvalidateLines(nLine, FBlockEnd.Line); + end; + StatusChanged([scSelection]); + end; + end; + end; +end; + +procedure TCustomSynEdit.SetCaretX(Value: Integer); +var + vNewCaret: TBufferCoord; +begin + vNewCaret.Char := Value; + vNewCaret.Line := CaretY; + SetCaretXY(vNewCaret); +end; + +procedure TCustomSynEdit.SetCaretY(Value: Integer); +var + vNewCaret: TBufferCoord; +begin + vNewCaret.Line := Value; + vNewCaret.Char := CaretX; + SetCaretXY(vNewCaret); +end; + +procedure TCustomSynEdit.InternalSetCaretX(Value: Integer); +var + vNewCaret: TBufferCoord; +begin + vNewCaret.Char := Value; + vNewCaret.Line := CaretY; + InternalSetCaretXY(vNewCaret); +end; + +procedure TCustomSynEdit.InternalSetCaretY(Value: Integer); +var + vNewCaret: TBufferCoord; +begin + vNewCaret.Line := Value; + vNewCaret.Char := CaretX; + InternalSetCaretXY(vNewCaret); +end; + +function TCustomSynEdit.GetCaretXY: TBufferCoord; +begin + Result.Char := CaretX; + Result.Line := CaretY; +end; + +function TCustomSynEdit.GetDisplayX: Integer; +begin + Result := DisplayXY.Column; +end; + +function TCustomSynEdit.GetDisplayY: Integer; +begin +{$IFDEF SYN_CodeFolding} + if not WordWrap and not UseCodeFolding then +{$ELSE} + if not WordWrap then +{$ENDIF} + Result := CaretY + else + Result := DisplayXY.Row; +end; + +Function TCustomSynEdit.GetDisplayXY: TDisplayCoord; +begin + Result := BufferToDisplayPos(CaretXY); + if WordWrap and FCaretAtEOL then + begin + if Result.Column = 1 then + begin + Dec(Result.Row); + Result.Column := FWordWrapPlugin.GetRowLength(Result.Row) +1; + end + else begin + // Work-around situations where FCaretAtEOL should have been updated because of + //text change (it's only valid when Column = 1). Updating it in ProperSetLine() + //would probably be the right thing, but... + FCaretAtEOL := False; + end; + end; +end; + +procedure TCustomSynEdit.SetCaretXY(const Value: TBufferCoord); +//there are two setCaretXY methods. One Internal, one External. The published +//property CaretXY (re)sets the block as well +begin + IncPaintLock; + try + Include(FStatusChanges, scSelection); + SetCaretXYEx(True, Value); + if SelAvail then + InvalidateSelection; + FBlockBegin.Char := FCaretX; + FBlockBegin.Line := FCaretY; + FBlockEnd := FBlockBegin; + finally + DecPaintLock; + end; +end; + +procedure TCustomSynEdit.InternalSetCaretXY(const Value: TBufferCoord); +begin + SetCaretXYEx(True, Value); +end; + +procedure TCustomSynEdit.UpdateLastCaretX; +begin + FLastCaretX := DisplayX; +end; + +procedure TCustomSynEdit.SetCaretXYEx(CallEnsureCursorPos: Boolean; Value: TBufferCoord); +var + nMaxX: Integer; + vTriggerPaint: Boolean; +begin + FCaretAtEOL := False; + vTriggerPaint := HandleAllocated; + if vTriggerPaint then + DoOnPaintTransient(ttBefore); + if WordWrap then + nMaxX := MaxInt + else + nMaxX := MaxScrollWidth + 1; + if Value.Line > Lines.Count then + Value.Line := Lines.Count; + if Value.Line < 1 then + begin + // this is just to make sure if Lines stringlist should be empty + Value.Line := 1; + if not (eoScrollPastEol in FOptions) then + nMaxX := 1; + end + else + begin + if not (eoScrollPastEol in FOptions) then + nMaxX := Length(Lines[Value.Line - 1]) + 1; + end; + if (Value.Char > nMaxX) and (not(eoScrollPastEol in Options) or + not(eoAutoSizeMaxScrollWidth in Options)) then + begin + Value.Char := nMaxX; + end; + if Value.Char < 1 then + Value.Char := 1; + if (Value.Char <> FCaretX) or (Value.Line <> FCaretY) then + begin + IncPaintLock; + try + // simply include the flags, FPaintLock is > 0 + if FCaretX <> Value.Char then + begin + FCaretX := Value.Char; + Include(FStatusChanges, scCaretX); + end; + if FCaretY <> Value.Line then + begin + if ActiveLineColor <> clNone then + begin + InvalidateLine(Value.Line); + InvalidateLine(FCaretY); + end; + FCaretY := Value.Line; + Include(FStatusChanges, scCaretY); +{$IFDEF SYN_CodeFolding} + UncollapseAroundLine(fCaretY); +{$ENDIF} + end; + // Call UpdateLastCaretX before DecPaintLock because the event handler it + // calls could raise an exception, and we don't want fLastCaretX to be + // left in an undefined state if that happens. + UpdateLastCaretX; + if CallEnsureCursorPos then + EnsureCursorPosVisible; + Include(FStateFlags, sfCaretChanged); +//++ Flicker Reduction +// Include(fStateFlags, sfScrollbarChanged); +//-- Flicker Reduction + finally + DecPaintLock; + end; + end + else begin + // Also call UpdateLastCaretX if the caret didn't move. Apps don't know + // anything about FLastCaretX and they shouldn't need to. So, to avoid any + // unwanted surprises, always update FLastCaretX whenever CaretXY is + // assigned to. + // Note to uRESTDWPrivSynEdit developers: If this is undesirable in some obscure + // case, just save the value of FLastCaretX before assigning to CaretXY and + // restore it afterward as appropriate. + UpdateLastCaretX; + end; + if vTriggerPaint then + DoOnPaintTransient(ttAfter); +end; + +function TCustomSynEdit.CaretInView: Boolean; +var + vCaretRowCol: TDisplayCoord; +begin + vCaretRowCol := DisplayXY; + Result := (vCaretRowCol.Column >= LeftChar) + and (vCaretRowCol.Column <= LeftChar + CharsInWindow) + and (vCaretRowCol.Row >= TopLine) + and (vCaretRowCol.Row <= TopLine + LinesInWindow); +end; + +procedure TCustomSynEdit.SetActiveLineColor(Value: TColor); +begin + if (FActiveLineColor <> Value) then + begin + FActiveLineColor := Value; + InvalidateLine(CaretY); + end; +end; + +procedure TCustomSynEdit.SetFont(const Value: TFont); +var + DC: HDC; + Save: THandle; + Metrics: TTextMetric; + AveCW, MaxCW: Integer; +begin + DC := GetDC(0); + Save := SelectObject(DC, Value.Handle); + GetTextMetrics(DC, Metrics); + SelectObject(DC, Save); + ReleaseDC(0, DC); + with Metrics do + begin + AveCW := tmAveCharWidth; + MaxCW := tmMaxCharWidth; + end; + case AveCW = MaxCW of + True: inherited Font := Value; + False: + begin + with FFontDummy do + begin + Color := Value.Color; + Pitch := fpFixed; + Size := Value.Size; + Style := Value.Style; + Name := Value.Name; + end; + inherited Font := FFontDummy; + end; + end; + + TSynEditStringList(FLines).FontChanged; + if FGutter.ShowLineNumbers then + GutterChanged(Self); +end; + +procedure TCustomSynEdit.SetGutterWidth(Value: Integer); +begin + Value := Max(Value, 0); + if FGutterWidth <> Value then + begin + FGutterWidth := Value; + FTextOffset := FGutterWidth + 2 - (LeftChar - 1) * FCharWidth; + if HandleAllocated then + begin + FCharsInWindow := Max(ClientWidth - FGutterWidth - 2, 0) div FCharWidth; + if WordWrap then + FWordWrapPlugin.DisplayChanged; + UpdateScrollBars; + Invalidate; + end; + end; +end; + +procedure TCustomSynEdit.SetLeftChar(Value: Integer); +var + MaxVal: Integer; + iDelta: Integer; + iTextArea: TRect; +begin + if WordWrap then + Value := 1; + + if eoScrollPastEol in Options then + begin + if eoAutoSizeMaxScrollWidth in Options then + MaxVal := MaxInt - CharsInWindow + else + MaxVal := MaxScrollWidth - CharsInWindow + 1 + end + else + begin + MaxVal := TSynEditStringList(Lines).LengthOfLongestLine; + if MaxVal > CharsInWindow then + MaxVal := MaxVal - CharsInWindow + 1 + else + MaxVal := 1; + end; + Value := MinMax(Value, 1, MaxVal); + if Value <> FLeftChar then + begin + iDelta := FLeftChar - Value; + FLeftChar := Value; + FTextOffset := FGutterWidth + 2 - (LeftChar - 1) * FCharWidth; + if Abs(iDelta) < CharsInWindow then + begin + iTextArea := ClientRect; + Inc(iTextArea.Left, FGutterWidth + 2); + ScrollWindow(Handle, iDelta * CharWidth, 0, @iTextArea, @iTextArea); + end + else + InvalidateLines(-1, -1); + if (Options >= [eoAutoSizeMaxScrollWidth, eoScrollPastEol]) and + (MaxScrollWidth < LeftChar + CharsInWindow) then + begin + MaxScrollWidth := LeftChar + CharsInWindow + end + else + UpdateScrollBars; + StatusChanged([scLeftChar]); + end; +end; + +procedure TCustomSynEdit.SetLines(Value: TUnicodeStrings); +begin + Lines.Assign(Value); +end; + +procedure TCustomSynEdit.SetLineText(Value: UnicodeString); +begin + if (CaretY >= 1) and (CaretY <= Max(1, Lines.Count)) then + Lines[CaretY - 1] := Value; +end; + +procedure TCustomSynEdit.SetFontSmoothing(AValue: TSynFontSmoothMethod); +begin + if FFontSmoothing <> AValue then + begin + FFontSmoothing := AValue; + FontSmoothingChanged; + end; +end; + +procedure TCustomSynEdit.SetName(const Value: TComponentName); +var + TextToName: Boolean; +begin + TextToName := (ComponentState * [csDesigning, csLoading] = [csDesigning]) + and (TrimRight(Text) = Name); + inherited SetName(Value); + if TextToName then + Text := Value; +end; + +procedure TCustomSynEdit.SetScrollBars(const Value: TScrollStyle); +begin + if (FScrollBars <> Value) then + begin + FScrollBars := Value; + UpdateScrollBars; + Invalidate; + end; +end; + +procedure TCustomSynEdit.SetSelTextPrimitive(const Value: UnicodeString); +begin + SetSelTextPrimitiveEx(FActiveSelectionMode, PWideChar(Value), True); +end; + +// This is really a last minute change and I hope I did it right. +// Reason for this modification: next two lines will loose the CaretX position +// if eoScrollPastEol is not set in Options. That is not really a good idea +// as we would typically want the cursor to stay where it is. +// To fix this (in the absence of a better idea), I changed the code in +// DeleteSelection not to trim the string if eoScrollPastEol is not set. +procedure TCustomSynEdit.SetSelTextPrimitiveEx(PasteMode: TSynSelectionMode; + Value: PWideChar; AddToUndoList: Boolean); +var + BB, BE: TBufferCoord; + TempString: UnicodeString; + + procedure DeleteSelection; + var + x, MarkOffset, MarkOffset2: Integer; + UpdateMarks: Boolean; + Count: Integer; + begin + UpdateMarks := False; + MarkOffset := 0; + MarkOffset2 := 0; + case FActiveSelectionMode of + smNormal: + begin + if Lines.Count > 0 then + begin + // Create a string that contains everything on the first line up + // to the selection mark, and everything on the last line after + // the selection mark. + if BB.Char > 1 then + MarkOffset2 := 1; + TempString := Copy(Lines[BB.Line - 1], 1, BB.Char - 1) + + Copy(Lines[BE.Line - 1], BE.Char, MaxInt); + // Delete all lines in the selection range. + TSynEditStringList(Lines).DeleteLines(BB.Line, BE.Line - BB.Line); + // Put the stuff that was outside of selection back in. + if Options >= [eoScrollPastEol, eoTrimTrailingSpaces] then + TempString := TrimTrailingSpaces(TempString); + Lines[BB.Line - 1] := TempString; + end; + UpdateMarks := True; + InternalCaretXY := BB; + end; + smColumn: + begin + // swap X if needed + if BB.Char > BE.Char then + SwapInt(Integer(BB.Char), Integer(BE.Char)); + + for x := BB.Line - 1 to BE.Line - 1 do + begin + TempString := Lines[x]; + Delete(TempString, BB.Char, BE.Char - BB.Char); + ProperSetLine(x, TempString); + end; + // Lines never get deleted completely, so keep caret at end. + InternalCaretXY := BufferCoord(BB.Char, FBlockEnd.Line); + // Column deletion never removes a line entirely, so no mark + // updating is needed here. + end; + smLine: + begin + if BE.Line = Lines.Count then + begin + Lines[BE.Line - 1] := ''; + for x := BE.Line - 2 downto BB.Line - 1 do + Lines.Delete(x); + end + else begin + for x := BE.Line - 1 downto BB.Line - 1 do + Lines.Delete(x); + end; + // smLine deletion always resets to first column. + InternalCaretXY := BufferCoord(1, BB.Line); + UpdateMarks := TRUE; + MarkOffset := 1; + end; + end; + + // Update marks + if UpdateMarks then + begin + Count := BE.Line - BB.Line + MarkOffset; + if Count > 0 then + DoLinesDeleted(BB.Line + MarkOffset2, Count); + end; + end; + + procedure InsertText; + + function CountLines(p: PWideChar): Integer; + begin + Result := 0; + while p^ <> #0 do + begin + if p^ = #13 then + Inc(p); + if p^ = #10 then + Inc(p); + Inc(Result); + p := GetEOL(p); + end; + end; + + function InsertNormal: Integer; + var + sLeftSide: UnicodeString; + sRightSide: UnicodeString; + Str: UnicodeString; + Start: PWideChar; + P: PWideChar; + begin + Result := 0; + sLeftSide := Copy(LineText, 1, CaretX - 1); + if CaretX - 1 > Length(sLeftSide) then + begin + sLeftSide := sLeftSide + UnicodeStringOfChar(#32, + CaretX - 1 - Length(sLeftSide)); + end; + sRightSide := Copy(LineText, CaretX, Length(LineText) - (CaretX - 1)); + // step1: insert the first line of Value into current line + Start := PWideChar(Value); + P := GetEOL(Start); + if P^ <> #0 then + begin + Str := sLeftSide + Copy(Value, 1, P - Start); + ProperSetLine(CaretY - 1, Str); + TSynEditStringList(Lines).InsertLines(CaretY, CountLines(P)); + end + else begin + Str := sLeftSide + Value + sRightSide; + ProperSetLine(CaretY -1, Str); + end; + // step2: insert left lines of Value + while P^ <> #0 do + begin + if P^ = #13 then + Inc(P); + if P^ = #10 then + Inc(P); + Inc(FCaretY); + Include(FStatusChanges, scCaretY); + Start := P; + P := GetEOL(Start); + if P = Start then + begin + if p^ <> #0 then + Str := '' + else + Str := sRightSide; + end + else begin + SetString(Str, Start, P - Start); + if p^ = #0 then + Str := Str + sRightSide + end; + ProperSetLine(CaretY -1, Str); + Inc(Result); + end; + if eoTrimTrailingSpaces in Options then + if sRightSide = '' then + FCaretX := GetExpandedLength(Str, TabWidth) + 1 + else + FCaretX := 1 + Length(Lines[CaretY - 1]) - Length(TrimTrailingSpaces(sRightSide)) + else FCaretX := 1 + Length(Lines[CaretY - 1]) - Length(sRightSide); + StatusChanged([scCaretX]); + end; + + function InsertColumn: Integer; + var + Str: UnicodeString; + Start: PWideChar; + P: PWideChar; + Len: Integer; + InsertPos: Integer; + LineBreakPos: TBufferCoord; + begin + Result := 0; + // Insert string at current position + InsertPos := CaretX; + Start := PWideChar(Value); + repeat + P := GetEOL(Start); + if P <> Start then + begin + SetLength(Str, P - Start); + Move(Start^, Str[1], (P - Start) * sizeof(WideChar)); + if CaretY > Lines.Count then + begin + Inc(Result); + TempString := UnicodeStringOfChar(#32, InsertPos - 1) + Str; + Lines.Add(''); + if AddToUndoList then + begin + LineBreakPos.Line := CaretY -1; + LineBreakPos.Char := Length(Lines[CaretY - 2]) + 1; + FUndoList.AddChange(crLineBreak, LineBreakPos, LineBreakPos, '', smNormal); + end; + end + else begin + TempString := Lines[CaretY - 1]; + Len := Length(TempString); + if Len < InsertPos then + begin + TempString := + TempString + UnicodeStringOfChar(#32, InsertPos - Len - 1) + Str + end + else + Insert(Str, TempString, InsertPos); + end; + ProperSetLine(CaretY - 1, TempString); + // Add undo change here from PasteFromClipboard + if AddToUndoList then + begin + FUndoList.AddChange(crPaste, BufferCoord(InsertPos, CaretY), + BufferCoord(InsertPos + (P - Start), CaretY), '', FActiveSelectionMode); + end; + end; + if P^ = #13 then + begin + Inc(P); + if P^ = #10 then + Inc(P); + Inc(FCaretY); + Include(FStatusChanges, scCaretY); + end; + Start := P; + until P^ = #0; + Inc(FCaretX, Length(Str)); + Include(FStatusChanges, scCaretX); + end; + + function InsertLine: Integer; + var + Start: PWideChar; + P: PWideChar; + Str: UnicodeString; + n: Integer; + begin + Result := 0; + FCaretX := 1; + // Insert string before current line + Start := PWideChar(Value); + repeat + P := GetEOL(Start); + if P <> Start then + begin + SetLength(Str, P - Start); + Move(Start^, Str[1], (P - Start) * sizeof(WideChar)); + end + else + Str := ''; + if (P^ = #0) then + begin + n := Lines.Count; + if (n >= CaretY) then + Lines[CaretY - 1] := Str + Lines[CaretY - 1] + else + Lines.Add(Str); + if eoTrimTrailingSpaces in Options then + Lines[CaretY - 1] := TrimTrailingSpaces(Lines[CaretY - 1]); + FCaretX := 1 + Length(Str); + end + else begin + //--------- KV from SynEditStudio + if (CaretY = Lines.Count) or InsertMode then + begin + Lines.Insert(CaretY -1, ''); + Inc(Result); + end; + //--------- + ProperSetLine(CaretY - 1, Str); + Inc(FCaretY); + Include(FStatusChanges, scCaretY); + Inc(Result); + if P^ = #13 then + Inc(P); + if P^ = #10 then + Inc(P); + Start := P; + end; + until P^ = #0; + StatusChanged([scCaretX]); + end; + + var + StartLine: Integer; + StartCol: Integer; + InsertedLines: Integer; + begin + if Value = '' then + Exit; + + StartLine := CaretY; + StartCol := CaretX; + case PasteMode of + smNormal: + InsertedLines := InsertNormal; + smColumn: + InsertedLines := InsertColumn; + smLine: + InsertedLines := InsertLine; + else + InsertedLines := 0; + end; + // We delete selected based on the current selection mode, but paste + // what's on the clipboard according to what it was when copied. + // Update marks + if InsertedLines > 0 then + begin + if (PasteMode = smNormal) and (StartCol > 1) then + Inc(StartLine); + DoLinesInserted(StartLine, InsertedLines); + end; + // Force caret reset + InternalCaretXY := CaretXY; + end; + +begin + IncPaintLock; + Lines.BeginUpdate; + try + BB := BlockBegin; + BE := BlockEnd; + if SelAvail then + begin + DeleteSelection; + InternalCaretXY := BB; + end; + if (Value <> nil) and (Value[0] <> #0) then + InsertText; + if CaretY < 1 then + InternalCaretY := 1; + finally + Lines.EndUpdate; + DecPaintLock; + end; +end; + +procedure TCustomSynEdit.SynSetText(const Value: UnicodeString); +begin + Lines.Text := Value; +end; + +procedure TCustomSynEdit.SetTopLine(Value: Integer); +var + Delta: Integer; +begin + if (eoScrollPastEof in Options) then + Value := Min(Value, DisplayLineCount) + else + Value := Min(Value, DisplayLineCount - FLinesInWindow + 1); + Value := Max(Value, 1); + if Value <> TopLine then + begin + Delta := TopLine - Value; + FTopLine := Value; + if Abs(Delta) < FLinesInWindow then + ScrollWindow(Handle, 0, FTextHeight * Delta, nil, nil) + else + Invalidate; + + UpdateWindow(Handle); + UpdateScrollBars; + StatusChanged([scTopLine]); + end; +end; + +{$IFDEF SYN_CodeFolding} +procedure TCustomSynEdit.SetUseCodeFolding(const Value: Boolean); +Var + ValidValue : Boolean; +begin + ValidValue := Value and ((Assigned(fHighlighter) and + (fHighlighter is TSynCustomCodeFoldingHighlighter)) + or Assigned(fOnScanForFoldRanges)); + + if fUseCodeFolding <> ValidValue then + begin + AllFoldRanges.Reset; + fUseCodeFolding := ValidValue; + Invalidate; // better Invalidate before changing LeftChar and TopLine + if ValidValue then + begin + // !!Mutually exclusive with WordWrap to reduce complexity + WordWrap := False; + FullFoldScan; + end; + OnCodeFoldingChange(Self); + InvalidateGutter; + end; +end; + +procedure TCustomSynEdit.OnCodeFoldingChange(Sender: TObject); +begin + if fUseCodeFolding then + // The fold shape is drawn in a square 2 * Gutter.RightMargin + // to the right of RightOffset and 2 * Gutter.RightMagin to the left of + // fGuttterWidth. It is centered vertically. + // Gutter.RightMargin is 2 at 96 DPI + Gutter.RightOffset := CodeFolding.GutterShapeSize + 3 * Gutter.RightMargin + else + Gutter.RightOffset := Gutter.RightMargin; + Invalidate; +end; + +function TCustomSynEdit.GetCollapseMarkRect(Row, Line: Integer): TRect; +begin + Result := Rect(0, 0, 0, 0); + + if not UseCodeFolding then + Exit; + + if Line < 0 then + Line := RowToLine(Row); + + if not AllFoldRanges.CollapsedFoldStartAtLine(Line) then + Exit; + + { Prepare rect } + with Result do + begin + Top := (Row - fTopLine) * fTextHeight + 1; + Bottom := Top + fTextHeight - 2; + end; + + Result.Left := fTextOffset + + (TSynEditStringList(fLines).ExpandedStringLengths[Line-1] + 1) * fCharWidth; + + { Fix rect } + if eoShowSpecialChars in fOptions then + Inc(Result.Left, fCharWidth); + + // Deal wwth horizontal Scroll + Result.Left := Max(Result.Left, fGutterWidth + fCharWidth); + + Result.Right := Result.Left + fCharWidth * 3 + 4 * (fCharWidth div 7); +end; + +function TCustomSynEdit.GetFoldShapeRect(Row: Integer): TRect; +begin + // Form a square rect for the square the user can click on + // The fold shape is drawn in a square 4 pixels to the right of RightOffset + // 4 pixels from the fGuttterWidth. It is vertically centered within a line. + Result.Left := fGutterWidth - CodeFolding.GutterShapeSize - 2 * Gutter.RightMargin; + Result.Right := Result.Left + CodeFolding.GutterShapeSize; + Result.Top := (Row - fTopLine) * LineHeight; + // make a square rect + Result.Top := Result.Top + ((LineHeight - (Result.Right - Result.Left)) div 2); + Result.Bottom := Result.Top + (Result.Right - Result.Left); +end; +{$ENDIF} + +procedure TCustomSynEdit.ShowCaret; +begin + if not (eoNoCaret in Options) and not (sfCaretVisible in FStateFlags) then + begin + if Windows.ShowCaret(Handle) then + Include(FStateFlags, sfCaretVisible); + end; +end; + +procedure TCustomSynEdit.UpdateCaret; +var + CX, CY: Integer; + iClientRect: TRect; + vCaretDisplay: TDisplayCoord; + vCaretPix: TPoint; + cf: TCompositionForm; + vSelStartPix: TPoint; +begin + if (PaintLock <> 0) or not (Focused or FAlwaysShowCaret) then + Include(FStateFlags, sfCaretChanged) + else + begin + Exclude(FStateFlags, sfCaretChanged); + vCaretDisplay := DisplayXY; + if WordWrap and (vCaretDisplay.Column > CharsInWindow + 1) then + vCaretDisplay.Column := CharsInWindow + 1; + vCaretPix := RowColumnToPixels(vCaretDisplay); + CX := vCaretPix.X + FCaretOffset.X; + CY := vCaretPix.Y + FCaretOffset.Y; + iClientRect := GetClientRect; + Inc(iClientRect.Left, FGutterWidth); + if (CX >= iClientRect.Left) and (CX < iClientRect.Right) + and (CY >= iClientRect.Top) and (CY < iClientRect.Bottom) then + begin + SetCaretPos(CX, CY); + ShowCaret; + end + else + begin + SetCaretPos(CX, CY); + HideCaret; + end; + if (Self.SelAvail = False) then + begin + cf.dwStyle := CFS_POINT; + cf.ptCurrentPos := Point(CX, CY); + ImmSetCompositionWindow(ImmGetContext(Handle), @cf); + end + else + begin + vSelStartPix := Self.RowColumnToPixels(BufferToDisplayPos(Self.BlockBegin)); + Self.SetImeCompositionWindow(Self.Font, vSelStartPix.X, vSelStartPix.Y); + end; + end; +end; + +procedure TCustomSynEdit.UpdateScrollBars; +var + nMaxScroll: Integer; + ScrollInfo: TScrollInfo; + iRightChar: Integer; +begin + if not HandleAllocated or (PaintLock <> 0) then + Include(FStateFlags, sfScrollbarChanged) + else begin + Exclude(FStateFlags, sfScrollbarChanged); + if fScrollBars <> ssNone then + begin + ScrollInfo.cbSize := SizeOf(ScrollInfo); + ScrollInfo.fMask := SIF_ALL; + if not(eoHideShowScrollbars in Options) then + begin + ScrollInfo.fMask := ScrollInfo.fMask or SIF_DISABLENOSCROLL; + end; + + if Visible then SendMessage(Handle, WM_SETREDRAW, 0, 0); + + if (fScrollBars in [{$IFDEF SYN_COMPILER_17_UP}TScrollStyle.{$ENDIF}ssBoth, {$IFDEF SYN_COMPILER_17_UP}TScrollStyle.{$ENDIF}ssHorizontal]) and not WordWrap then + begin + if eoScrollPastEol in Options then + nMaxScroll := MaxScrollWidth + else + nMaxScroll := Max(TSynEditStringList(Lines).LengthOfLongestLine, 1); + if nMaxScroll <= MAX_SCROLL then + begin + ScrollInfo.nMin := 1; + ScrollInfo.nMax := nMaxScroll; + ScrollInfo.nPage := CharsInWindow; + ScrollInfo.nPos := LeftChar; + end + else begin + ScrollInfo.nMin := 0; + ScrollInfo.nMax := MAX_SCROLL; + ScrollInfo.nPage := MulDiv(MAX_SCROLL, CharsInWindow, nMaxScroll); + ScrollInfo.nPos := MulDiv(MAX_SCROLL, LeftChar, nMaxScroll); + end; + + ShowScrollBar(Handle, SB_HORZ, not(eoHideShowScrollbars in Options) or + (ScrollInfo.nMin = 0) or (ScrollInfo.nMax > CharsInWindow)); + SetScrollInfo(Handle, SB_HORZ, ScrollInfo, True); + + //Now for the arrows + if (eoDisableScrollArrows in Options) or (nMaxScroll <= CharsInWindow) then + begin + iRightChar := LeftChar + CharsInWindow -1; + if (LeftChar <= 1) and (iRightChar >= nMaxScroll) then + begin + EnableScrollBar(Handle, SB_HORZ, ESB_DISABLE_BOTH); + end + else begin + EnableScrollBar(Handle, SB_HORZ, ESB_ENABLE_BOTH); + if (LeftChar <= 1) then + EnableScrollBar(Handle, SB_HORZ, ESB_DISABLE_LEFT) + else if iRightChar >= nMaxScroll then + EnableScrollBar(Handle, SB_HORZ, ESB_DISABLE_RIGHT) + end; + end + else + EnableScrollBar(Handle, SB_HORZ, ESB_ENABLE_BOTH); + end + else + ShowScrollBar(Handle, SB_HORZ, False); + + if fScrollBars in [ssBoth, ssVertical] then + begin + nMaxScroll := DisplayLineCount; + if (eoScrollPastEof in Options) then + Inc(nMaxScroll, LinesInWindow - 1); + if nMaxScroll <= MAX_SCROLL then + begin + ScrollInfo.nMin := 1; + ScrollInfo.nMax := Max(1, nMaxScroll); + ScrollInfo.nPage := LinesInWindow; + ScrollInfo.nPos := TopLine; + end + else begin + ScrollInfo.nMin := 0; + ScrollInfo.nMax := MAX_SCROLL; + ScrollInfo.nPage := MulDiv(MAX_SCROLL, LinesInWindow, nMaxScroll); + ScrollInfo.nPos := MulDiv(MAX_SCROLL, TopLine, nMaxScroll); + end; + + ShowScrollBar(Handle, SB_VERT, not(eoHideShowScrollbars in Options) or + (ScrollInfo.nMin = 0) or (ScrollInfo.nMax > LinesInWindow)); + SetScrollInfo(Handle, SB_VERT, ScrollInfo, True); + + if (eoDisableScrollArrows in Options) or (nMaxScroll <= LinesInWindow) then + begin + if (TopLine <= 1) and (nMaxScroll <= LinesInWindow) then + begin + EnableScrollBar(Handle, SB_VERT, ESB_DISABLE_BOTH); + end + else begin + EnableScrollBar(Handle, SB_VERT, ESB_ENABLE_BOTH); + if (TopLine <= 1) then + EnableScrollBar(Handle, SB_VERT, ESB_DISABLE_UP) + else if ((DisplayLineCount - TopLine - LinesInWindow + 1) = 0) then + EnableScrollBar(Handle, SB_VERT, ESB_DISABLE_DOWN); + end; + end + else + EnableScrollBar(Handle, SB_VERT, ESB_ENABLE_BOTH); + + if Visible then SendMessage(Handle, WM_SETREDRAW, -1, 0); + if FPaintLock=0 then + Invalidate; + + end + else + ShowScrollBar(Handle, SB_VERT, False); + + end {endif fScrollBars <> ssNone} + else + ShowScrollBar(Handle, SB_BOTH, False); + end; +end; + +{$IFDEF SYN_COMPILER_6_UP} +function TCustomSynEdit.DoMouseWheel(Shift: TShiftState; + WheelDelta: Integer; MousePos: TPoint): Boolean; +const + WHEEL_DIVISOR = 120; // Mouse Wheel standard +var + iWheelClicks: Integer; + iLinesToScroll: Integer; +begin + Result := inherited DoMouseWheel(Shift, WheelDelta, MousePos); + if Result then + Exit; + if GetKeyState(SYNEDIT_CONTROL) < 0 then + iLinesToScroll := LinesInWindow shr Ord(eoHalfPageScroll in FOptions) + else + iLinesToScroll := 3; + Inc(FMouseWheelAccumulator, WheelDelta); + iWheelClicks := FMouseWheelAccumulator div WHEEL_DIVISOR; + FMouseWheelAccumulator := FMouseWheelAccumulator mod WHEEL_DIVISOR; + TopLine := TopLine - iWheelClicks * iLinesToScroll; + Update; + if Assigned(OnScroll) then OnScroll(Self,sbVertical); + Result := True; +end; +{$ENDIF} + +{$IFDEF SYN_COMPILER_12_UP} +type + PHintInfo = Controls.PHintInfo; +{$ENDIF} + +procedure TCustomSynEdit.CMHintShow(var Msg: TMessage); +var + FoundHint: Boolean; + MouseCoords, TokenCoords: TBufferCoord; + TokenStr: UnicodeString; + TokenHint: string; + TokenType, Start: Integer; + Attri: TSynHighlighterAttributes; + D: TDisplayCoord; + P1, P2: TPoint; + TokenRect: TRect; +begin + if FHintMode = shmToken then + begin + FoundHint := False; + if Assigned(FOnTokenHint) and GetPositionOfMouse(MouseCoords) and + GetHighlighterAttriAtRowColEx(MouseCoords, TokenStr, TokenType, Start, Attri) then + begin + TokenCoords.Char := Start; + TokenCoords.Line := MouseCoords.Line; + FOnTokenHint(Self, TokenCoords, TokenStr, TokenType, Attri, TokenHint); + FoundHint := TokenHint <> ''; + end; + + if FoundHint then + begin + D := BufferToDisplayPos(TokenCoords); + P1 := RowColumnToPixels(D); + P2.X := P1.X + Length(TokenStr) * CharWidth; + P2.Y := P1.Y + FTextHeight; + TokenRect.TopLeft := P1; + TokenRect.BottomRight := P2; + + InflateRect(TokenRect, 2, 2); + with PHintInfo(Msg.LParam)^ do + begin + HintStr := TokenHint; + CursorRect := TokenRect; + HintData := nil; + end; + Msg.Result := 0; + end + else + Msg.Result := 1; + end + else + inherited; +end; + +procedure TCustomSynEdit.WMCaptureChanged(var Msg: TMessage); +begin + FScrollTimer.Enabled := False; + inherited; +end; + +procedure TCustomSynEdit.WMChar(var Msg: TWMChar); +begin +{$IFNDEF UNICODE} + if not Win32PlatformIsUnicode then + Msg.CharCode := Word(KeyUnicode(AnsiChar(Msg.CharCode))); +{$ENDIF} + + DoKeyPressW(Msg); +end; + +procedure TCustomSynEdit.WMClear(var Msg: TMessage); +begin + if not ReadOnly then + SelText := ''; +end; + +procedure TCustomSynEdit.WMCopy(var Message: TMessage); +begin + CopyToClipboard; + Message.Result := ord(True); +end; + +procedure TCustomSynEdit.WMCut(var Message: TMessage); +begin + if not ReadOnly then + CutToClipboard; + Message.Result := ord(True); +end; + +procedure TCustomSynEdit.WMDropFiles(var Msg: TMessage); +var + i, iNumberDropped: Integer; + {$IFNDEF UNICODE} + FileNameA: array[0..MAX_PATH - 1] of AnsiChar; + {$ENDIF} + FileNameW: array[0..MAX_PATH - 1] of WideChar; + Point: TPoint; + FilesList: TUnicodeStringList; +begin + try + if Assigned(FOnDropFiles) then + begin + FilesList := TUnicodeStringList.Create; + try + iNumberDropped := DragQueryFile(THandle(Msg.wParam), Cardinal(-1), + nil, 0); + DragQueryPoint(THandle(Msg.wParam), Point); + +{$IFNDEF UNICODE} + if Win32PlatformIsUnicode then +{$ENDIF} + for i := 0 to iNumberDropped - 1 do + begin + DragQueryFileW(THandle(Msg.wParam), i, FileNameW, + sizeof(FileNameW) div 2); + FilesList.Add(FileNameW) +{$IFNDEF UNICODE} + end + else + for i := 0 to iNumberDropped - 1 do + begin + DragQueryFileA(THandle(Msg.wParam), i, FileNameA, + sizeof(FileNameA)); + FilesList.Add(UnicodeString(FileNameA)) +{$ENDIF} + end; + FOnDropFiles(Self, Point.X, Point.Y, FilesList); + finally + FilesList.Free; + end; + end; + finally + Msg.Result := 0; + DragFinish(THandle(Msg.wParam)); + end; +end; + +procedure TCustomSynEdit.WMDestroy(var Message: TWMDestroy); +begin + {$IFDEF UNICODE} + // assign WindowText here, otherwise the VCL will call GetText twice + if WindowText = nil then + WindowText := Lines.GetText; + {$ENDIF} + inherited; +end; + +procedure TCustomSynEdit.WMEraseBkgnd(var Msg: TMessage); +begin + Msg.Result := 1; +end; + +procedure TCustomSynEdit.WMGetDlgCode(var Msg: TWMGetDlgCode); +begin + inherited; + Msg.Result := Msg.Result or DLGC_WANTARROWS or DLGC_WANTCHARS; + if FWantTabs then + Msg.Result := Msg.Result or DLGC_WANTTAB; + if FWantReturns then + Msg.Result := Msg.Result or DLGC_WANTALLKEYS; +end; + +procedure TCustomSynEdit.WMGetText(var Msg: TWMGetText); +begin + if HandleAllocated and IsWindowUnicode(Handle) then + begin + WStrLCopy(PWideChar(Msg.Text), PWideChar(Text), Msg.TextMax - 1); + Msg.Result := WStrLen(PWideChar(Msg.Text)); + end + else + begin + {$IFDEF SYN_COMPILER_18_UP}AnsiStrings.{$ENDIF}StrLCopy(PAnsiChar(Msg.Text), PAnsiChar(AnsiString(Text)), Msg.TextMax - 1); + Msg.Result := {$IFDEF SYN_COMPILER_18_UP}AnsiStrings.{$ENDIF}StrLen(PAnsiChar(Msg.Text)); + end; +end; + +procedure TCustomSynEdit.WMGetTextLength(var Msg: TWMGetTextLength); +begin +{$IFDEF SYN_COMPILER_4_UP} + // Avoid (useless) temporary copy of WindowText while window is recreated + // because of docking. + if csDocking in ControlState then + Msg.Result := 0 + else +{$ENDIF} + Msg.Result := Length(Text); +end; + +procedure TCustomSynEdit.WMHScroll(var Msg: TWMScroll); +var + iMaxWidth: Integer; +begin + Msg.Result := 0; + case Msg.ScrollCode of + // Scrolls to start / end of the line + SB_LEFT: LeftChar := 1; + SB_RIGHT: + if eoScrollPastEol in Options then + LeftChar := MaxScrollWidth - CharsInWindow +1 + else + // Simply set LeftChar property to the LengthOfLongestLine, + // it would do the range checking and constrain the value if necessary + LeftChar := TSynEditStringList(Lines).LengthOfLongestLine; + // Scrolls one char left / right + SB_LINERIGHT: LeftChar := LeftChar + 1; + SB_LINELEFT: LeftChar := LeftChar - 1; + // Scrolls one page of chars left / right + SB_PAGERIGHT: LeftChar := LeftChar + + (FCharsInWindow - Ord(eoScrollByOneLess in FOptions)); + SB_PAGELEFT: LeftChar := LeftChar + - (FCharsInWindow - Ord(eoScrollByOneLess in FOptions)); + // Scrolls to the current scroll bar position + SB_THUMBPOSITION, + SB_THUMBTRACK: + begin + FIsScrolling := True; + if eoScrollPastEol in Options then + iMaxWidth := MaxScrollWidth + else + iMaxWidth := Max(TSynEditStringList(Lines).LengthOfLongestLine, 1); + if iMaxWidth > MAX_SCROLL then + LeftChar := MulDiv(iMaxWidth, Msg.Pos, MAX_SCROLL) + else + LeftChar := Msg.Pos; + end; + SB_ENDSCROLL: FIsScrolling := False; + end; + if Assigned(OnScroll) then OnScroll(Self,sbHorizontal); +end; + +function IsWindows98orLater: Boolean; +begin + Result := (Win32MajorVersion > 4) or + (Win32MajorVersion = 4) and (Win32MinorVersion > 0); +end; + +procedure TCustomSynEdit.WMImeChar(var Msg: TMessage); +begin + // do nothing here, the IME string is retrieved in WMImeComposition + + // Handling the WM_IME_CHAR message stops Windows from sending WM_CHAR + // messages while using the IME +end; + +procedure TCustomSynEdit.WMImeComposition(var Msg: TMessage); +var + imc: HIMC; + PW: PWideChar; + PA: PAnsiChar; + PWLength: Integer; + ImeCount: Integer; +begin + if (Msg.LParam and GCS_RESULTSTR) <> 0 then + begin + imc := ImmGetContext(Handle); + try + if IsWindows98orLater then + begin + ImeCount := ImmGetCompositionStringW(imc, GCS_RESULTSTR, nil, 0); + // ImeCount is always the size in bytes, also for Unicode + GetMem(PW, ImeCount + sizeof(WideChar)); + try + ImmGetCompositionStringW(imc, GCS_RESULTSTR, PW, ImeCount); + PW[ImeCount div sizeof(WideChar)] := #0; + CommandProcessor(ecImeStr, #0, PW); + finally + FreeMem(PW); + end; + end + else + begin + ImeCount := ImmGetCompositionStringA(imc, GCS_RESULTSTR, nil, 0); + // ImeCount is always the size in bytes, also for Unicode + GetMem(PA, ImeCount + sizeof(AnsiChar)); + try + ImmGetCompositionStringA(imc, GCS_RESULTSTR, PA, ImeCount); + PA[ImeCount] := #0; + + PWLength := MultiByteToWideChar(DefaultSystemCodePage, 0, PA, ImeCount, + nil, 0); + GetMem(PW, (PWLength + 1) * sizeof(WideChar)); + try + MultiByteToWideChar(DefaultSystemCodePage, 0, PA, ImeCount, + PW, PWLength); + CommandProcessor(ecImeStr, #0, PW); + finally + FreeMem(PW); + end; + finally + FreeMem(PA); + end; + end; + finally + ImmReleaseContext(Handle, imc); + end; + end; + inherited; +end; + +procedure TCustomSynEdit.WMImeNotify(var Msg: TMessage); +var + imc: HIMC; + LogFontW: TLogFontW; + LogFontA: TLogFontA; +begin + with Msg do + begin + case WParam of + IMN_SETOPENSTATUS: + begin + imc := ImmGetContext(Handle); + if imc <> 0 then + begin + if IsWindows98orLater then + begin + GetObjectW(Font.Handle, SizeOf(TLogFontW), @LogFontW); + ImmSetCompositionFontW(imc, @LogFontW); + end + else + begin + GetObjectA(Font.Handle, SizeOf(TLogFontA), @LogFontA); + ImmSetCompositionFontA(imc, @LogFontA); + end; + ImmReleaseContext(Handle, imc); + end; + end; + end; + end; + inherited; +end; + +procedure TCustomSynEdit.WMImeRequest(var Message: TMessage); +var + pReconvert: PReconvertString; + TargetText: string; + TargetByteLength: Integer; + pTarget: PChar; + H: HIMC; +begin + case Message.WParam of + IMR_RECONVERTSTRING: + begin + // Reconversion string + if (Self.SelLength <> 0) then + begin + TargetText := Self.SelText; + end + else + begin + if (Self.Lines.Count >= Self.CaretY - 1) then + TargetText := Self.Lines[Self.CaretY - 1] + else + TargetText := ''; + end; + TargetByteLength := Length(TargetText) * sizeof(Char); + + if (Message.LParam = 0) then + begin + // 1st time (get buffer size (bytes)) + // Select only one row + if (Self.BlockBegin.Line = Self.BlockEnd.Line) then + Message.Result := Sizeof(TReconvertString) + TargetByteLength + else + Message.Result := 0; + end + else + begin + // 2nd time + pReconvert := Pointer(Message.LParam); + pReconvert.dwSize := Sizeof(TReconvertString); + pReconvert.dwVersion := 0; + pReconvert.dwStrLen := Length(TargetText); + pReconvert.dwStrOffset := Sizeof(TReconvertString); + + pTarget := Pointer(Message.LParam + Sizeof(TReconvertString)); + move(TargetText[1], pTarget^, TargetByteLength); + + if (Self.SelLength <> 0) then + begin + pReconvert.dwTargetStrLen := 0; + pReconvert.dwTargetStrOffset := 0; + pReconvert.dwCompStrLen := Length(TargetText); + pReconvert.dwCompStrOffset := 0; + end + else + begin + pReconvert.dwTargetStrLen := 0; + pReconvert.dwTargetStrOffset := (Self.CaretX - 1) * sizeof(Char); + H := Imm32GetContext(Handle); + try + ImmSetCompositionString(H, SCS_QUERYRECONVERTSTRING, pReconvert, Sizeof(TReconvertString) + TargetByteLength, nil, 0); + if (pReconvert.dwCompStrLen <> 0) then + begin + Self.CaretX := pReconvert.dwCompStrOffset div sizeof(Char) + 1; + Self.SelStart := RowColToCharIndex(Self.CaretXY); + Self.SelLength := pReconvert.dwCompStrLen; + end; + finally + Imm32ReleaseContext(Handle, H); + end; + end; + Message.Result := Sizeof(TReconvertString) + TargetByteLength; + end; + end; + IMR_DOCUMENTFEED: + begin + // Notifies an application when the selected IME needs the converted string from the application. + if (Self.Lines.Count >= Self.CaretY) then + TargetText := Self.Lines[Self.CaretY] + else + TargetText := ''; + if (Message.LParam = 0) then + begin + // 1st time (get line size (bytes)) + Message.Result := Sizeof(TReconvertString) + Length(TargetText) * sizeof(Char); + end + else + begin + // 2nd time + pReconvert := Pointer(Message.LParam); + pReconvert.dwSize := Sizeof(TReconvertString); + pReconvert.dwVersion := 0; + pReconvert.dwStrLen := Length(TargetText); + pReconvert.dwStrOffset := Sizeof(TReconvertString); + pReconvert.dwCompStrLen := 0; + pReconvert.dwCompStrOffset := 0; + pReconvert.dwTargetStrLen := 0; + pReconvert.dwTargetStrOffset := (Self.CaretX - 1) * sizeof(Char); + + pTarget := Pointer(Message.LParam + Sizeof(TReconvertString)); + move(TargetText[1], pTarget^, Length(TargetText) * sizeof(Char)); + + Message.Result := Sizeof(TReconvertString) + Length(TargetText) * sizeof(Char); + end; + end; + end; +end; + +procedure TCustomSynEdit.WMKillFocus(var Msg: TWMKillFocus); +begin + inherited; + CommandProcessor(ecLostFocus, #0, nil); + //Added check for focused to prevent caret disappearing problem + if Focused or FAlwaysShowCaret then + Exit; + HideCaret; + Windows.DestroyCaret; + if FHideSelection and SelAvail then + InvalidateSelection; +end; + +procedure TCustomSynEdit.WMPaste(var Message: TMessage); +begin + if not ReadOnly then + PasteFromClipboard; + Message.Result := ord(True); +end; + +procedure TCustomSynEdit.WMCancelMode(var Message:TMessage); +begin + +end; + +procedure TCustomSynEdit.WMSetFocus(var Msg: TWMSetFocus); +begin + CommandProcessor(ecGotFocus, #0, nil); + + InitializeCaret; + if FHideSelection and SelAvail then + InvalidateSelection; +end; + +procedure TCustomSynEdit.WMSetText(var Msg: TWMSetText); +begin + Msg.Result := 1; + try + if HandleAllocated and IsWindowUnicode(Handle) then + Text := PWideChar(Msg.Text) + else + Text := UnicodeString(PAnsiChar(Msg.Text)); + except + Msg.Result := 0; + raise + end +end; + +procedure TCustomSynEdit.WMSize(var Msg: TWMSize); +begin + inherited; + SizeOrFontChanged(False); +end; + +procedure TCustomSynEdit.WMUndo(var Msg: TMessage); +begin + Undo; +end; + +var + ScrollHintWnd: THintWindow; + +function GetScrollHint: THintWindow; +begin + if ScrollHintWnd = nil then + ScrollHintWnd := HintWindowClass.Create(Application); + Result := ScrollHintWnd; +end; + +procedure TCustomSynEdit.WMVScroll(var Msg: TWMScroll); +var + s: string; + rc: TRect; + pt: TPoint; + ScrollHint: THintWindow; + ButtonH: Integer; + ScrollInfo: TScrollInfo; +begin + Msg.Result := 0; + case Msg.ScrollCode of + // Scrolls to start / end of the text + SB_TOP: TopLine := 1; + SB_BOTTOM: TopLine := DisplayLineCount; + // Scrolls one line up / down + SB_LINEDOWN: TopLine := TopLine + 1; + SB_LINEUP: TopLine := TopLine - 1; + // Scrolls one page of lines up / down + SB_PAGEDOWN: TopLine := TopLine + + (FLinesInWindow - Ord(eoScrollByOneLess in FOptions)); + SB_PAGEUP: TopLine := TopLine + - (FLinesInWindow - Ord(eoScrollByOneLess in FOptions)); + // Scrolls to the current scroll bar position + SB_THUMBPOSITION, + SB_THUMBTRACK: + begin + FIsScrolling := True; + if DisplayLineCount > MAX_SCROLL then + TopLine := MulDiv(LinesInWindow + DisplayLineCount - 1, Msg.Pos, + MAX_SCROLL) + else + TopLine := Msg.Pos; + + if eoShowScrollHint in FOptions then + begin + ScrollHint := GetScrollHint; + ScrollHint.Color := FScrollHintColor; + case FScrollHintFormat of + shfTopLineOnly: + s := Format(SYNS_ScrollInfoFmtTop, [RowToLine(TopLine)]); + else + s := Format(SYNS_ScrollInfoFmt, [RowToLine(TopLine), + RowToLine(TopLine + Min(LinesInWindow, DisplayLineCount-TopLine))]); + end; + +{$IFDEF SYN_COMPILER_3_UP} + rc := ScrollHint.CalcHintRect(200, s, nil); +{$ELSE} + rc := Rect(0, 0, TextWidth(ScrollHint.Canvas, s) + 6, + TextHeight(ScrollHint.Canvas, s) + 4); +{$ENDIF} + if eoScrollHintFollows in FOptions then + begin + ButtonH := GetSystemMetrics(SM_CYVSCROLL); + + FillChar(ScrollInfo, SizeOf(ScrollInfo), 0); + ScrollInfo.cbSize := SizeOf(ScrollInfo); + ScrollInfo.fMask := SIF_ALL; + GetScrollInfo(Handle, SB_VERT, ScrollInfo); + + pt := ClientToScreen(Point(ClientWidth - rc.Right - 4, + ((rc.Bottom - rc.Top) shr 1) + //half the size of the hint window + Round((ScrollInfo.nTrackPos / ScrollInfo.nMax) * //The percentage of the page that has been scrolled + (ClientHeight - (ButtonH * 2))) //The height minus the arrow buttons + + ButtonH)); //The height of the top button + end + else + pt := ClientToScreen(Point(ClientWidth - rc.Right - 4, 10)); + + OffsetRect(rc, pt.x, pt.y); + ScrollHint.ActivateHint(rc, s); +{$IFDEF SYN_COMPILER_3} + SendMessage(ScrollHint.Handle, WM_NCPAINT, 1, 0); +{$ENDIF} +{$IFNDEF SYN_COMPILER_3_UP} + ScrollHint.Invalidate; +{$ENDIF} + ScrollHint.Update; + end; + end; + // Ends scrolling + SB_ENDSCROLL: + begin + FIsScrolling := False; + if eoShowScrollHint in FOptions then + ShowWindow(GetScrollHint.Handle, SW_HIDE); + end; + end; + Update; + if Assigned(OnScroll) then OnScroll(Self,sbVertical); +end; + +function TCustomSynEdit.ScanFrom(Index: Integer): Integer; +var + iRange: TSynEditRange; +begin + Result := Index; + if Result >= Lines.Count then Exit; + + if Result = 0 then + FHighlighter.ResetRange + else + FHighlighter.SetRange(TSynEditStringList(Lines).Ranges[Result - 1]); + + repeat + FHighlighter.SetLine(Lines[Result], Result); + FHighlighter.NextToEol; + iRange := FHighlighter.GetRange; + if TSynEditStringList(Lines).Ranges[Result] = iRange then + Exit; // avoid the final decrement + TSynEditStringList(Lines).Ranges[Result] := iRange; + Inc(Result); + until (Result = Lines.Count); + Dec(Result); +end; + +procedure TCustomSynEdit.ListCleared(Sender: TObject); +begin + if WordWrap then + FWordWrapPlugin.Reset; + +{$IFDEF SYN_CodeFolding} + if UseCodeFolding then + AllFoldRanges.Reset; +{$ENDIF} + + ClearUndo; + // invalidate the *whole* client area + FillChar(FInvalidateRect, SizeOf(TRect), 0); + Invalidate; + // set caret and selected block to start of text + CaretXY := BufferCoord(1, 1); + // scroll to start of text + TopLine := 1; + LeftChar := 1; + Include(FStatusChanges, scAll); +end; + +procedure TCustomSynEdit.ListDeleted(Sender: TObject; aIndex: Integer; + aCount: Integer); +{$IFDEF SYN_CodeFolding} +Var + vLastScan: Integer; +begin + vLastScan := aIndex; + if Assigned(fHighlighter) and (Lines.Count > 0) then + vLastScan := ScanFrom(aIndex); + + if UseCodeFolding then begin + AllFoldRanges.LinesDeleted(aIndex, aCount); + // Scan the same lines the highlighter has scanned + ReScanForFoldRanges(aIndex, vLastScan); + InvalidateGutter; + end; +{$ELSE} +begin +{$ENDIF} + if Assigned(FHighlighter) and (Lines.Count > 0) then + ScanFrom(aIndex); + + if WordWrap then + FWordWrapPlugin.LinesDeleted(aIndex, aCount); + + InvalidateLines(aIndex + 1, MaxInt); + InvalidateGutterLines(aIndex + 1, MaxInt); +//++ Flicker Reduction + Include(fStateFlags, sfScrollbarChanged); +//-- Flicker Reduction +end; + +procedure TCustomSynEdit.ListInserted(Sender: TObject; Index: Integer; + aCount: Integer); +var + L: Integer; + vLastScan: Integer; +{$IFDEF SYN_CodeFolding} + FoldIndex: Integer; +begin + vLastScan := Index; +{$ELSE} +begin +{$ENDIF} + if Assigned(FHighlighter) and (Lines.Count > 0) then + begin + vLastScan := Index; + repeat + vLastScan := ScanFrom(vLastScan); + Inc(vLastScan); + until vLastScan >= Index + aCount; + end; + +{$IFDEF SYN_CodeFolding} + if UseCodeFolding then begin + if fAllFoldRanges.CollapsedFoldStartAtLine(Index, FoldIndex) then + // insertion starts at collapsed fold + Uncollapse(FoldIndex); + AllFoldRanges.LinesInserted(Index, aCount); + // Scan the same lines the highlighter has scanned + ReScanForFoldRanges(Index, vLastScan-1); + end; +{$ENDIF} + + if WordWrap then + FWordWrapPlugin.LinesInserted(Index, aCount); + + InvalidateLines(Index + 1, MaxInt); + InvalidateGutterLines(Index + 1, MaxInt); +//++ Flicker Reduction + Include(fStateFlags, sfScrollbarChanged); +//-- Flicker Reduction + + if (eoAutoSizeMaxScrollWidth in FOptions) then + begin + L := TSynEditStringList(Lines).ExpandedStringLengths[Index]; + if L > MaxScrollWidth then + MaxScrollWidth := L; + end; +end; + +procedure TCustomSynEdit.ListPutted(Sender: TObject; Index: Integer; + aCount: Integer); +var + L: Integer; + vEndLine: Integer; +{$IFDEF SYN_CodeFolding} + vLastScan: Integer; + FoldIndex: Integer; +{$ENDIF} +begin + vEndLine := Index +1; + if WordWrap then + begin + if FWordWrapPlugin.LinesPutted(Index, aCount) <> 0 then + vEndLine := MaxInt; + InvalidateGutterLines(Index + 1, vEndLine); + end; +{$IFDEF SYN_CodeFolding} + vLastScan := Index; + if Assigned(fHighlighter) then + begin + vLastScan := ScanFrom(Index); + vEndLine := Max(vEndLine, vLastScan + 1); +{$ELSE} + if Assigned(FHighlighter) then + begin + vEndLine := Max(vEndLine, ScanFrom(Index) + 1); +{$ENDIF} + // If this editor is chained then the real owner of text buffer will probably + // have already parsed the changes, so ScanFrom will return immediately. + if FLines <> FOrigLines then + vEndLine := MaxInt; + end; + + {$IFDEF SYN_CodeFolding} + if fUseCodeFolding then begin + if fAllFoldRanges.CollapsedFoldStartAtLine(Index + 1, FoldIndex) then + // modification happens at collapsed fold + Uncollapse(FoldIndex); + AllFoldRanges.LinesPutted(Index, aCount); + // Scan the same lines the highlighter has scanned + ReScanForFoldRanges(Index, vLastScan); + end; +{$ENDIF} + + InvalidateLines(Index + 1, vEndLine); + InvalidateGutterLines(Index + 1, vEndLine); + + if (eoAutoSizeMaxScrollWidth in FOptions) then + begin + L := TSynEditStringList(Lines).ExpandedStringLengths[Index]; + if L > MaxScrollWidth then + MaxScrollWidth := L; + end; +end; + +procedure TCustomSynEdit.ScanRanges; +var + i: Integer; +begin + if Assigned(FHighlighter) and (Lines.Count > 0) then begin + FHighlighter.ResetRange; + i := 0; + repeat + FHighlighter.SetLine(Lines[i], i); + FHighlighter.NextToEol; + TSynEditStringList(Lines).Ranges[i] := FHighlighter.GetRange; + Inc(i); + until i >= Lines.Count; + end; +end; + +procedure TCustomSynEdit.SetWordBlock(Value: TBufferCoord); +var + vBlockBegin: TBufferCoord; + vBlockEnd: TBufferCoord; + TempString: UnicodeString; + + procedure CharScan; + var + cRun: Integer; + begin + { search BlockEnd } + vBlockEnd.Char := Length(TempString); + for cRun := Value.Char to Length(TempString) do + if not IsIdentChar(TempString[cRun]) then + begin + vBlockEnd.Char := cRun; + Break; + end; + { search BlockBegin } + vBlockBegin.Char := 1; + for cRun := Value.Char - 1 downto 1 do + if not IsIdentChar(TempString[cRun]) then + begin + vBlockBegin.Char := cRun + 1; + Break; + end; + end; + +begin + if (eoScrollPastEol in Options) and not WordWrap then + Value.Char := MinMax(Value.Char, 1, FMaxScrollWidth + 1) + else + Value.Char := Max(Value.Char, 1); + Value.Line := MinMax(Value.Line, 1, Lines.Count); + TempString := Lines[Value.Line - 1] + #0; //needed for CaretX = LineLength + 1 + if Value.Char > Length(TempString) then + begin + InternalCaretXY := BufferCoord(Length(TempString), Value.Line); + Exit; + end; + + CharScan; + + vBlockBegin.Line := Value.Line; + vBlockEnd.Line := Value.Line; + SetCaretAndSelection(vBlockEnd, vBlockBegin, vBlockEnd); + InvalidateLine(Value.Line); + StatusChanged([scSelection]); +end; + +procedure TCustomSynEdit.DblClick; +var + ptMouse: TPoint; +begin + GetCursorPos(ptMouse); + ptMouse := ScreenToClient(ptMouse); + if ptMouse.X >= FGutterWidth + 2 then + begin + if not (eoNoSelection in FOptions) then + SetWordBlock(CaretXY); + inherited; + Include(FStateFlags, sfDblClicked); + Exclude(FStateFlags, sfMouseCaptured); + MouseCapture := False; + end + else + inherited; +end; + +function TCustomSynEdit.GetCanUndo: Boolean; +begin + Result := not ReadOnly and FUndoList.CanUndo; +end; + +function TCustomSynEdit.GetCanRedo: Boolean; +begin + Result := not ReadOnly and FRedoList.CanUndo; +end; + +function TCustomSynEdit.GetCanPaste; +begin + Result := not ReadOnly and ClipboardProvidesText; +end; + +procedure TCustomSynEdit.InsertBlock(const BB, BE: TBufferCoord; ChangeStr: PWideChar; + AddToUndoList: Boolean); +// used by BlockIndent and Redo +begin + SetCaretAndSelection(BB, BB, BE); + ActiveSelectionMode := smColumn; + SetSelTextPrimitiveEx(smColumn, ChangeStr, AddToUndoList); + StatusChanged([scSelection]); +end; + +procedure TCustomSynEdit.InsertLine(const BB, BE: TBufferCoord; ChangeStr: PWideChar; + AddToUndoList: Boolean); +begin + SetCaretAndSelection(BB, BB, BE); + ActiveSelectionMode := smLine; + SetSelTextPrimitiveEx(smLine, ChangeStr, AddToUndoList); + StatusChanged([scSelection]); +end; + +procedure TCustomSynEdit.Redo; + + procedure RemoveGroupBreak; + var + Item: TSynEditUndoItem; + OldBlockNumber: Integer; + begin + if FRedoList.LastChangeReason = crGroupBreak then + begin + OldBlockNumber := UndoList.BlockChangeNumber; + Item := FRedoList.PopItem; + try + UndoList.BlockChangeNumber := Item.ChangeNumber; + FUndoList.AddGroupBreak; + finally + UndoList.BlockChangeNumber := OldBlockNumber; + Item.Free; + end; + UpdateModifiedStatus; + end; + end; + +var + Item: TSynEditUndoItem; + OldChangeNumber: Integer; + SaveChangeNumber: Integer; + FLastChange : TSynChangeReason; + FAutoComplete: Boolean; + FPasteAction: Boolean; + FSpecial1: Boolean; + FSpecial2: Boolean; + FKeepGoing: Boolean; +begin + if ReadOnly then + Exit; + + FLastChange := FRedoList.LastChangeReason; + FAutoComplete := FLastChange = crAutoCompleteBegin; + FPasteAction := FLastChange = crPasteBegin; + FSpecial1 := FLastChange = crSpecial1Begin; + FSpecial2 := FLastChange = crSpecial2Begin; + + Item := FRedoList.PeekItem; + if Item <> nil then + begin + OldChangeNumber := Item.ChangeNumber; + SaveChangeNumber := FUndoList.BlockChangeNumber; + FUndoList.BlockChangeNumber := Item.ChangeNumber; + try + repeat + RedoItem; + Item := FRedoList.PeekItem; + if Item = nil then + FKeepGoing := False + else begin + if FAutoComplete then + FKeepGoing := (FRedoList.LastChangeReason <> crAutoCompleteEnd) + else if FPasteAction then + FKeepGoing := (FRedoList.LastChangeReason <> crPasteEnd) + else if FSpecial1 then + FKeepGoing := (FRedoList.LastChangeReason <> crSpecial1End) + else if FSpecial2 then + FKeepGoing := (FRedoList.LastChangeReason <> crSpecial2End) + else if Item.ChangeNumber = OldChangeNumber then + FKeepGoing := True + else begin + FKeepGoing := ((eoGroupUndo in FOptions) and + (FLastChange = Item.ChangeReason) and + not(FLastChange in [crIndent, crUnindent])); + end; + FLastChange := Item.ChangeReason; + end; + until not(FKeepGoing); + + //we need to eat the last command since it does nothing and also update modified status... + if (FAutoComplete and (FRedoList.LastChangeReason = crAutoCompleteEnd)) or + (FPasteAction and (FRedoList.LastChangeReason = crPasteEnd)) or + (FSpecial1 and (FRedoList.LastChangeReason = crSpecial1End)) or + (FSpecial2 and (FRedoList.LastChangeReason = crSpecial2End)) then + begin + RedoItem; + UpdateModifiedStatus; + end; + + finally + FUndoList.BlockChangeNumber := SaveChangeNumber; + end; + RemoveGroupBreak; + end; +end; + +procedure TCustomSynEdit.RedoItem; +var + Item: TSynEditUndoItem; + Run, StrToDelete: PWideChar; + Len: Integer; + TempString: UnicodeString; + CaretPt: TBufferCoord; + ChangeScrollPastEol: Boolean; + BeginX: Integer; +begin + ChangeScrollPastEol := not (eoScrollPastEol in Options); + Item := FRedoList.PopItem; + if Assigned(Item) then + try + ActiveSelectionMode := Item.ChangeSelMode; + IncPaintLock; + Include(FOptions, eoScrollPastEol); + FUndoList.InsideRedo := True; + case Item.ChangeReason of + crCaret: + begin + FUndoList.AddChange(Item.ChangeReason, CaretXY, CaretXY, '', FActiveSelectionMode); + InternalCaretXY := Item.ChangeStartPos; + end; + crSelection: + begin + FUndoList.AddChange(Item.ChangeReason, BlockBegin, BlockEnd, '', FActiveSelectionMode); + SetCaretAndSelection(CaretXY, Item.ChangeStartPos, Item.ChangeEndPos); + end; + crInsert, crPaste, crDragDropInsert: + begin + SetCaretAndSelection(Item.ChangeStartPos, Item.ChangeStartPos, + Item.ChangeStartPos); + SetSelTextPrimitiveEx(Item.ChangeSelMode, PWideChar(Item.ChangeStr), + False); + InternalCaretXY := Item.ChangeEndPos; + FUndoList.AddChange(Item.ChangeReason, Item.ChangeStartPos, + Item.ChangeEndPos, SelText, Item.ChangeSelMode); + if Item.ChangeReason = crDragDropInsert then begin + SetCaretAndSelection(Item.ChangeStartPos, Item.ChangeStartPos, + Item.ChangeEndPos); + end; + end; + crDeleteAfterCursor, crSilentDeleteAfterCursor: + begin + SetCaretAndSelection(Item.ChangeStartPos, Item.ChangeStartPos, + Item.ChangeEndPos); + TempString := SelText; + SetSelTextPrimitiveEx(Item.ChangeSelMode, PWideChar(Item.ChangeStr), + False); + FUndoList.AddChange(Item.ChangeReason, Item.ChangeStartPos, + Item.ChangeEndPos, TempString, Item.ChangeSelMode); + InternalCaretXY := Item.ChangeEndPos; + end; + crDelete, crSilentDelete: + begin + SetCaretAndSelection(Item.ChangeStartPos, Item.ChangeStartPos, + Item.ChangeEndPos); + TempString := SelText; + SetSelTextPrimitiveEx(Item.ChangeSelMode, PWideChar(Item.ChangeStr), + False); + FUndoList.AddChange(Item.ChangeReason, Item.ChangeStartPos, + Item.ChangeEndPos, TempString, Item.ChangeSelMode); + InternalCaretXY := Item.ChangeStartPos; + end; + crLineBreak: + begin + CaretPt := Item.ChangeStartPos; + SetCaretAndSelection(CaretPt, CaretPt, CaretPt); + CommandProcessor(ecLineBreak, #13, nil); + end; + crIndent: + begin + SetCaretAndSelection(Item.ChangeEndPos, Item.ChangeStartPos, + Item.ChangeEndPos); + FUndoList.AddChange(Item.ChangeReason, Item.ChangeStartPos, + Item.ChangeEndPos, Item.ChangeStr, Item.ChangeSelMode); + end; + crUnindent : + begin // re-delete the (raggered) column + // Delete string + StrToDelete := PWideChar(Item.ChangeStr); + InternalCaretY := Item.ChangeStartPos.Line; + if Item.ChangeSelMode = smColumn then + BeginX := Min(Item.ChangeStartPos.Char, Item.ChangeEndPos.Char) + else + BeginX := 1; + repeat + Run := GetEOL(StrToDelete); + if Run <> StrToDelete then + begin + Len := Run - StrToDelete; + if Len > 0 then + begin + TempString := Lines[CaretY - 1]; + Delete(TempString, BeginX, Len); + Lines[CaretY - 1] := TempString; + end; + end + else + Len := 0; + if Run^ = #13 then + begin + Inc(Run); + if Run^ = #10 then + Inc(Run); + Inc(FCaretY); + end; + StrToDelete := Run; + until Run^ = #0; + if Item.ChangeSelMode = smColumn then + SetCaretAndSelection(Item.ChangeStartPos, Item.ChangeStartPos, + Item.ChangeEndPos) + else begin + // restore selection + CaretPt.Char := Item.ChangeStartPos.Char - FTabWidth; + CaretPt.Line := Item.ChangeStartPos.Line; + SetCaretAndSelection( CaretPt, CaretPt, + BufferCoord(Item.ChangeEndPos.Char - Len, Item.ChangeEndPos.Line) ); + end; + // add to undo list + FUndoList.AddChange(Item.ChangeReason, Item.ChangeStartPos, + Item.ChangeEndPos, Item.ChangeStr, Item.ChangeSelMode); + end; + crWhiteSpaceAdd: + begin + FUndoList.AddChange(Item.ChangeReason, Item.ChangeStartPos, + Item.ChangeEndPos, '', Item.ChangeSelMode); + SetCaretAndSelection(Item.ChangeEndPos, Item.ChangeEndPos, + Item.ChangeEndPos); + SetSelTextPrimitiveEx(Item.ChangeSelMode, PWideChar(Item.ChangeStr), True); + InternalCaretXY := Item.ChangeStartPos; + end; + end; + finally + FUndoList.InsideRedo := False; + if ChangeScrollPastEol then + Exclude(FOptions, eoScrollPastEol); + Item.Free; + DecPaintLock; + end; +end; + +{$IFDEF SYN_CodeFolding} +procedure TCustomSynEdit.Collapse(FoldRangeIndex: Integer; Invalidate:Boolean); +begin + AllFoldRanges.Ranges.List[FoldRangeIndex].Collapsed := True; + + with AllFoldRanges.Ranges[FoldRangeIndex] do + begin + // Extract caret from fold + if (fCaretY > FromLine) and (fCaretY <= ToLine) then + CaretXY := BufferCoord(Length(Lines[FromLine - 1]) + 1, FromLine); + + if Invalidate then begin + // Redraw the collapsed line and below + InvalidateLines(FromLine, MaxInt); + + // Redraw fold mark + InvalidateGutterLines(FromLine, MaxInt); + + UpdateScrollBars; + end else + // Update Scrollbars + Include(fStateFlags, sfScrollbarChanged); + end; +end; + +procedure TCustomSynEdit.CollapseAll; +var + i: Integer; +begin + if not fUseCodeFolding then Exit; + for i := fAllFoldRanges.Count - 1 downto 0 do + Collapse(i, False); + + InvalidateLines(-1, -1); + InvalidateGutterLines(-1, -1); + + EnsureCursorPosVisible; +end; + + +procedure TCustomSynEdit.CollapseLevel(Level: integer); +Var + i : integer; + RangeIndices : TArray; +begin + if not fUseCodeFolding then Exit; + RangeIndices := AllFoldRanges.FoldsAtLevel(Level); + for i := Low(RangeIndices) to High(RangeIndices) do + Collapse(RangeIndices[i], False); + + InvalidateLines(-1, -1); + InvalidateGutterLines(-1, -1); + + EnsureCursorPosVisible; +end; + +procedure TCustomSynEdit.CollapseNearest; +Var + Index : integer; +begin + if not fUseCodeFolding then Exit; + if AllFoldRanges.FoldAroundLineEx(CaretY, False, True, True, Index) then + Collapse(Index); + + EnsureCursorPosVisible; +end; + +procedure TCustomSynEdit.CollapseFoldType(FoldType : Integer); +Var + i : integer; + RangeIndices : TArray; +begin + if not fUseCodeFolding then Exit; + RangeIndices := AllFoldRanges.FoldsOfType(FoldType); + for i := Low(RangeIndices) to High(RangeIndices) do + Collapse(RangeIndices[i],False); + + InvalidateLines(-1, -1); + InvalidateGutterLines(-1, -1); + + EnsureCursorPosVisible; +end; + +procedure TCustomSynEdit.Uncollapse(FoldRangeIndex: Integer; Invalidate:Boolean); +begin + AllFoldRanges.Ranges.List[FoldRangeIndex].Collapsed := False; + + if Invalidate then with AllFoldRanges.Ranges[FoldRangeIndex] do + begin + // Redraw the uncollapsed line and below + InvalidateLines(FromLine, MaxInt); + + // Redraw fold marks + InvalidateGutterLines(FromLine, MaxInt); + + // Make sure we can see the cursor + // EnsureCursorPosVisible; + + UpdateScrollBars; + end else + // Update Scrollbars + Include(fStateFlags, sfScrollbarChanged); +end; + +procedure TCustomSynEdit.UncollapseAroundLine(Line: Integer); +var + Index: Integer; +begin + if not fUseCodeFolding then Exit; + // Open up the closed folds around the focused line until we can see the line we're looking for + while AllFoldRanges.FoldHidesLine(line, Index) do + Uncollapse(Index); +end; + +procedure TCustomSynEdit.UnCollapseLevel(Level: integer); +Var + i : integer; + RangeIndices : TArray; +begin + if not fUseCodeFolding then Exit; + RangeIndices := AllFoldRanges.FoldsAtLevel(Level); + for i := Low(RangeIndices) to High(RangeIndices) do + Uncollapse(RangeIndices[i], False); + + InvalidateLines(-1, -1); + InvalidateGutterLines(-1, -1); + + EnsureCursorPosVisible; +end; + +procedure TCustomSynEdit.UncollapseNearest; +Var + Index : integer; +begin + if not fUseCodeFolding then Exit; + if AllFoldRanges.CollapsedFoldStartAtLine(CaretY, Index) then + Uncollapse(Index); + + EnsureCursorPosVisible; +end; + +procedure TCustomSynEdit.UnCollapseFoldType(FoldType : Integer); +Var + i : integer; + RangeIndices : TArray; +begin + if not fUseCodeFolding then Exit; + RangeIndices := AllFoldRanges.FoldsOfType(FoldType); + for i := Low(RangeIndices) to High(RangeIndices) do + Uncollapse(RangeIndices[i], False); + + InvalidateLines(-1, -1); + InvalidateGutterLines(-1, -1); + + EnsureCursorPosVisible; +end; + +procedure TCustomSynEdit.UncollapseAll; +var + i: Integer; +begin + if not fUseCodeFolding then Exit; + for i := fAllFoldRanges.Count - 1 downto 0 do + Uncollapse(i, False); + + InvalidateLines(-1, -1); + InvalidateGutterLines(-1, -1); + + EnsureCursorPosVisible; +end; +{$ENDIF} + +procedure TCustomSynEdit.Undo; + + procedure RemoveGroupBreak; + var + Item: TSynEditUndoItem; + OldBlockNumber: Integer; + begin + if FUndoList.LastChangeReason = crGroupBreak then + begin + OldBlockNumber := RedoList.BlockChangeNumber; + try + Item := FUndoList.PopItem; + RedoList.BlockChangeNumber := Item.ChangeNumber; + Item.Free; + FRedoList.AddGroupBreak; + finally + RedoList.BlockChangeNumber := OldBlockNumber; + end; + end; + end; + +var + Item: TSynEditUndoItem; + OldChangeNumber: Integer; + SaveChangeNumber: Integer; + FLastChange : TSynChangeReason; + FAutoComplete: Boolean; + FPasteAction: Boolean; + FSpecial1: Boolean; + FSpecial2: Boolean; + FKeepGoing: Boolean; +begin + if ReadOnly then + Exit; + + RemoveGroupBreak; + + FLastChange := FUndoList.LastChangeReason; + FAutoComplete := FLastChange = crAutoCompleteEnd; + FPasteAction := FLastChange = crPasteEnd; + FSpecial1 := FLastChange = crSpecial1End; + FSpecial2 := FLastChange = crSpecial2End; + + Item := FUndoList.PeekItem; + if Item <> nil then + begin + OldChangeNumber := Item.ChangeNumber; + SaveChangeNumber := FRedoList.BlockChangeNumber; + FRedoList.BlockChangeNumber := Item.ChangeNumber; + + try + repeat + UndoItem; + Item := FUndoList.PeekItem; + if Item = nil then + FKeepGoing := False + else begin + if FAutoComplete then + FKeepGoing := (FUndoList.LastChangeReason <> crAutoCompleteBegin) + else if FPasteAction then + FKeepGoing := (FUndoList.LastChangeReason <> crPasteBegin) + else if FSpecial1 then + FKeepGoing := (FUndoList.LastChangeReason <> crSpecial1Begin) + else if FSpecial2 then + FKeepGoing := (FUndoList.LastChangeReason <> crSpecial2Begin) + else if Item.ChangeNumber = OldChangeNumber then + FKeepGoing := True + else begin + FKeepGoing := ((eoGroupUndo in FOptions) and + (FLastChange = Item.ChangeReason) and + not(FLastChange in [crIndent, crUnindent])); + end; + FLastChange := Item.ChangeReason; + end; + until not(FKeepGoing); + + //we need to eat the last command since it does nothing and also update modified status... + if (FAutoComplete and (FUndoList.LastChangeReason = crAutoCompleteBegin)) or + (FPasteAction and (FUndoList.LastChangeReason = crPasteBegin)) or + (FSpecial1 and (FUndoList.LastChangeReason = crSpecial1Begin)) or + (FSpecial2 and (FUndoList.LastChangeReason = crSpecial2Begin)) then + begin + UndoItem; + UpdateModifiedStatus; + end; + + finally + FRedoList.BlockChangeNumber := SaveChangeNumber; + end; + end; +end; + +procedure TCustomSynEdit.UndoItem; +var + Item: TSynEditUndoItem; + TmpPos: TBufferCoord; + TmpStr: UnicodeString; + ChangeScrollPastEol: Boolean; + BeginX: Integer; +begin + ChangeScrollPastEol := not (eoScrollPastEol in Options); + Item := FUndoList.PopItem; + if Assigned(Item) then + try + ActiveSelectionMode := Item.ChangeSelMode; + IncPaintLock; + Include(FOptions, eoScrollPastEol); + case Item.ChangeReason of + crCaret: + begin + FRedoList.AddChange(Item.ChangeReason, CaretXY, CaretXY, '', FActiveSelectionMode); + InternalCaretXY := Item.ChangeStartPos; + end; + crSelection: + begin + FRedoList.AddChange(Item.ChangeReason, BlockBegin, BlockEnd, '', FActiveSelectionMode); + SetCaretAndSelection(CaretXY, Item.ChangeStartPos, Item.ChangeEndPos); + end; + crInsert, crPaste, crDragDropInsert: + begin + SetCaretAndSelection(Item.ChangeStartPos, Item.ChangeStartPos, + Item.ChangeEndPos); + TmpStr := SelText; + SetSelTextPrimitiveEx(Item.ChangeSelMode, PWideChar(Item.ChangeStr), + False); + FRedoList.AddChange(Item.ChangeReason, Item.ChangeStartPos, + Item.ChangeEndPos, TmpStr, Item.ChangeSelMode); + InternalCaretXY := Item.ChangeStartPos; + end; + crDeleteAfterCursor, crDelete, + crSilentDelete, crSilentDeleteAfterCursor, + crDeleteAll: + begin + // If there's no selection, we have to set + // the Caret's position manualy. + if Item.ChangeSelMode = smColumn then + TmpPos := BufferCoord( + Min(Item.ChangeStartPos.Char, Item.ChangeEndPos.Char), + Min(Item.ChangeStartPos.Line, Item.ChangeEndPos.Line)) + else + TmpPos := TBufferCoord(MinPoint( + TPoint(Item.ChangeStartPos), TPoint(Item.ChangeEndPos))); + if (Item.ChangeReason in [crDeleteAfterCursor, + crSilentDeleteAfterCursor]) and (TmpPos.Line > Lines.Count) then + begin + InternalCaretXY := BufferCoord(1, Lines.Count); + FLines.Add(''); + end; + CaretXY := TmpPos; + SetSelTextPrimitiveEx(Item.ChangeSelMode, PWideChar(Item.ChangeStr), + False ); + if Item.ChangeReason in [crDeleteAfterCursor, + crSilentDeleteAfterCursor] + then + TmpPos := Item.ChangeStartPos + else + TmpPos := Item.ChangeEndPos; + if Item.ChangeReason in [crSilentDelete, crSilentDeleteAfterCursor] + then + InternalCaretXY := TmpPos + else begin + SetCaretAndSelection(TmpPos, Item.ChangeStartPos, + Item.ChangeEndPos); + end; + FRedoList.AddChange(Item.ChangeReason, Item.ChangeStartPos, + Item.ChangeEndPos, '', Item.ChangeSelMode); + if Item.ChangeReason = crDeleteAll then begin + InternalCaretXY := BufferCoord(1, 1); + FBlockEnd := BufferCoord(1, 1); + end; + EnsureCursorPosVisible; + end; + crLineBreak: + begin + // If there's no selection, we have to set + // the Caret's position manualy. + InternalCaretXY := Item.ChangeStartPos; + if CaretY > 0 then + begin + TmpStr := Lines.Strings[CaretY - 1]; + if (Length(TmpStr) < CaretX - 1) + and (LeftSpaces(Item.ChangeStr) = 0) + then + TmpStr := TmpStr + UnicodeStringOfChar(#32, CaretX - 1 - Length(TmpStr)); + ProperSetLine(CaretY - 1, TmpStr + Item.ChangeStr); + Lines.Delete(Item.ChangeEndPos.Line); + end + else + ProperSetLine(CaretY - 1, Item.ChangeStr); + DoLinesDeleted(CaretY + 1, 1); + FRedoList.AddChange(Item.ChangeReason, Item.ChangeStartPos, + Item.ChangeEndPos, '', Item.ChangeSelMode); + end; + crIndent: + begin + SetCaretAndSelection(Item.ChangeEndPos, Item.ChangeStartPos, + Item.ChangeEndPos); + FRedoList.AddChange(Item.ChangeReason, Item.ChangeStartPos, + Item.ChangeEndPos, Item.ChangeStr, Item.ChangeSelMode); + end; + crUnindent: // reinsert the (raggered) column that was deleted + begin + // reinsert the string + if Item.ChangeSelMode <> smColumn then + InsertBlock(BufferCoord(1, Item.ChangeStartPos.Line), + BufferCoord(1, Item.ChangeEndPos.Line), + PWideChar(Item.ChangeStr), False) + else + begin + BeginX := Min( Item.ChangeStartPos.Char, Item.ChangeEndPos.Char ); + InsertBlock(BufferCoord(BeginX, Item.ChangeStartPos.Line), + BufferCoord(BeginX, Item.ChangeEndPos.Line), + PWideChar(Item.ChangeStr), False); + end; + SetCaretAndSelection(Item.ChangeStartPos, Item.ChangeStartPos, + Item.ChangeEndPos); + FRedoList.AddChange(Item.ChangeReason, Item.ChangeStartPos, + Item.ChangeEndPos, Item.ChangeStr, Item.ChangeSelMode); + end; + crWhiteSpaceAdd: + begin + SetCaretAndSelection(Item.ChangeStartPos, Item.ChangeStartPos, + Item.ChangeEndPos); + TmpStr := SelText; + SetSelTextPrimitiveEx(Item.ChangeSelMode, PWideChar(Item.ChangeStr), True); + FRedoList.AddChange(Item.ChangeReason, Item.ChangeStartPos, + Item.ChangeEndPos, TmpStr, Item.ChangeSelMode); + InternalCaretXY := Item.ChangeStartPos; + end; + end; + finally + if ChangeScrollPastEol then + Exclude(FOptions, eoScrollPastEol); + Item.Free; + DecPaintLock; + end; +end; + +procedure TCustomSynEdit.ClearBookMark(BookMark: Integer); +begin + if (BookMark in [0..9]) and assigned(FBookMarks[BookMark]) then + begin + DoOnClearBookmark(FBookMarks[BookMark]); + FMarkList.Remove(FBookMarks[Bookmark]); + FBookMarks[BookMark] := nil; + end +end; + +procedure TCustomSynEdit.GotoBookMark(BookMark: Integer); +var + iNewPos: TBufferCoord; +begin + if (BookMark in [0..9]) and + assigned(FBookMarks[BookMark]) and + (FBookMarks[BookMark].Line <= FLines.Count) + then + begin + iNewPos.Char := FBookMarks[BookMark].Char; + iNewPos.Line := FBookMarks[BookMark].Line; + //call it this way instead to make sure that the caret ends up in the middle + //if it is off screen (like Delphi does with bookmarks) + SetCaretXYEx(False, iNewPos); + EnsureCursorPosVisibleEx(True); + if SelAvail then + InvalidateSelection; + FBlockBegin.Char := FCaretX; + FBlockBegin.Line := FCaretY; + FBlockEnd := FBlockBegin; + end; +end; + +procedure TCustomSynEdit.GotoLineAndCenter(ALine: Integer); +begin + SetCaretXYEx( False, BufferCoord(1, ALine) ); + if SelAvail then + InvalidateSelection; + FBlockBegin.Char := FCaretX; + FBlockBegin.Line := FCaretY; + FBlockEnd := FBlockBegin; + EnsureCursorPosVisibleEx(True); +end; + +procedure TCustomSynEdit.SetBookMark(BookMark: Integer; X: Integer; Y: Integer); +var + mark: TSynEditMark; +begin + if (BookMark in [0..9]) and (Y >= 1) and (Y <= Max(1, FLines.Count)) then + begin + mark := TSynEditMark.Create(self); + with mark do + begin + Line := Y; + Char := X; + ImageIndex := Bookmark; + BookmarkNumber := Bookmark; + Visible := True; + InternalImage := (FBookMarkOpt.BookmarkImages = nil); + end; + DoOnPlaceMark(Mark); + if (mark <> nil) then + begin + if assigned(FBookMarks[BookMark]) then + ClearBookmark(BookMark); + FBookMarks[BookMark] := mark; + FMarkList.Add(FBookMarks[BookMark]); + end; + end; +end; + +function IsTextMessage(Msg: UINT): Boolean; +begin + Result := (Msg = WM_SETTEXT) or (Msg = WM_GETTEXT) or (Msg = WM_GETTEXTLENGTH); +end; + +procedure TCustomSynEdit.WndProc(var Msg: TMessage); +const + ALT_KEY_DOWN = $20000000; +begin + // Prevent Alt-Backspace from beeping + if (Msg.Msg = WM_SYSCHAR) and (Msg.wParam = VK_BACK) and + (Msg.lParam and ALT_KEY_DOWN <> 0) + then + Msg.Msg := 0; + + // handle direct WndProc calls that could happen through VCL-methods like Perform + if HandleAllocated and IsWindowUnicode(Handle) then + if not FWindowProducedMessage then + begin + FWindowProducedMessage := True; + if IsTextMessage(Msg.Msg) then + begin + with Msg do + Result := SendMessageA(Handle, Msg, wParam, lParam); + Exit; + end; + end + else + FWindowProducedMessage := False; + + inherited; +end; + +procedure TCustomSynEdit.ChainListCleared(Sender: TObject); +begin + if Assigned(FChainListCleared) then + FChainListCleared(Sender); + TSynEditStringList(FOrigLines).OnCleared(Sender); +end; + +procedure TCustomSynEdit.ChainListDeleted(Sender: TObject; aIndex: Integer; + aCount: Integer); +begin + if Assigned(FChainListDeleted) then + FChainListDeleted(Sender, aIndex, aCount); + TSynEditStringList(FOrigLines).OnDeleted(Sender, aIndex, aCount); +end; + +procedure TCustomSynEdit.ChainListInserted(Sender: TObject; aIndex: Integer; + aCount: Integer); +begin + if Assigned(FChainListInserted) then + FChainListInserted(Sender, aIndex, aCount); + TSynEditStringList(FOrigLines).OnInserted(Sender, aIndex, aCount); +end; + +procedure TCustomSynEdit.ChainListPutted(Sender: TObject; aIndex: Integer; + aCount: Integer); +begin + if Assigned(FChainListPutted) then + FChainListPutted(Sender, aIndex, aCount); + TSynEditStringList(FOrigLines).OnPutted(Sender, aIndex, aCount); +end; + +procedure TCustomSynEdit.ChainLinesChanging(Sender: TObject); +begin + if Assigned(FChainLinesChanging) then + FChainLinesChanging(Sender); + TSynEditStringList(FOrigLines).OnChanging(Sender); +end; + +procedure TCustomSynEdit.ChainLinesChanged(Sender: TObject); +begin + if Assigned(FChainLinesChanged) then + FChainLinesChanged(Sender); + TSynEditStringList(FOrigLines).OnChange(Sender); +end; + +procedure TCustomSynEdit.ChainUndoRedoAdded(Sender: TObject); +var + iList: TSynEditUndoList; + iHandler: TNotifyEvent; +begin + if Sender = FUndoList then + begin + iList := FOrigUndoList; + iHandler := FChainUndoAdded; + end + else { if Sender = FRedoList then } + begin + iList := FOrigRedoList; + iHandler := FChainRedoAdded; + end; + if Assigned(iHandler) then + iHandler(Sender); + iList.OnAddedUndo(Sender); +end; + +//++ DPI-Aware +procedure TCustomSynEdit.ChangeScale(M, D: Integer{$if CompilerVersion >= 31}; isDpiChange: Boolean{$ifend}); +begin + {$if CompilerVersion >= 31}if isDpiChange then begin{$ifend} + if Assigned(fGutter) then fGutter.ChangeScale(M,D); + if Assigned(fBookMarkOpt) then fBookMarkOpt.ChangeScale(M, D); + if Assigned(fWordWrapGlyph) then fWordWrapGlyph.ChangeScale(M, D); + {$if CompilerVersion >= 31}end;{$ifend} + inherited ChangeScale(M, D{$if CompilerVersion >= 31}, isDpiChange{$ifend}); + end; +//-- DPI-Aware + +procedure TCustomSynEdit.UnHookTextBuffer; +var + vOldWrap: Boolean; +begin + Assert(FChainedEditor = nil); + if FLines = FOrigLines then + Exit; + + vOldWrap := WordWrap; + WordWrap := False; + + //first put back the real methods + with TSynEditStringList(FLines) do + begin + OnCleared := FChainListCleared; + OnDeleted := FChainListDeleted; + OnInserted := FChainListInserted; + OnPutted := FChainListPutted; + OnChanging := FChainLinesChanging; + OnChange := FChainLinesChanged; + end; + FUndoList.OnAddedUndo := FChainUndoAdded; + FRedoList.OnAddedUndo := FChainRedoAdded; + + FChainListCleared := nil; + FChainListDeleted := nil; + FChainListInserted := nil; + FChainListPutted := nil; + FChainLinesChanging := nil; + FChainLinesChanged := nil; + FChainUndoAdded := nil; + + //make the switch + FLines := FOrigLines; + FUndoList := FOrigUndoList; + FRedoList := FOrigRedoList; + LinesHookChanged; + + WordWrap := vOldWrap; +end; + +procedure TCustomSynEdit.HookTextBuffer(aBuffer: TSynEditStringList; + aUndo, aRedo: TSynEditUndoList); +var + vOldWrap: Boolean; +begin + Assert(FChainedEditor = nil); + Assert(FLines = FOrigLines); + + vOldWrap := WordWrap; + WordWrap := False; + + if FChainedEditor <> nil then + RemoveLinesPointer + else if FLines <> FOrigLines then + UnHookTextBuffer; + + //store the current values and put in the chained methods + FChainListCleared := aBuffer.OnCleared; + aBuffer.OnCleared := ChainListCleared; + FChainListDeleted := aBuffer.OnDeleted; + aBuffer.OnDeleted := ChainListDeleted; + FChainListInserted := aBuffer.OnInserted; + aBuffer.OnInserted := ChainListInserted; + FChainListPutted := aBuffer.OnPutted; + aBuffer.OnPutted := ChainListPutted; + FChainLinesChanging := aBuffer.OnChanging; + aBuffer.OnChanging := ChainLinesChanging; + FChainLinesChanged := aBuffer.OnChange; + aBuffer.OnChange := ChainLinesChanged; + + FChainUndoAdded := aUndo.OnAddedUndo; + aUndo.OnAddedUndo := ChainUndoRedoAdded; + FChainRedoAdded := aRedo.OnAddedUndo; + aRedo.OnAddedUndo := ChainUndoRedoAdded; + + //make the switch + FLines := aBuffer; + FUndoList := aUndo; + FRedoList := aRedo; + LinesHookChanged; + + WordWrap := vOldWrap; +end; + +procedure TCustomSynEdit.LinesHookChanged; +var + iLongestLineLength: Integer; +begin + Invalidate; + if eoAutoSizeMaxScrollWidth in FOptions then + begin + iLongestLineLength := TSynEditStringList(Lines).LengthOfLongestLine; + if iLongestLineLength > MaxScrollWidth then + MaxScrollWidth := iLongestLineLength; + end; + UpdateScrollBars; +end; + +procedure TCustomSynEdit.SetLinesPointer(ASynEdit: TCustomSynEdit); +begin + HookTextBuffer(TSynEditStringList(ASynEdit.Lines), + ASynEdit.UndoList, ASynEdit.RedoList); + + FChainedEditor := ASynEdit; + ASynEdit.FreeNotification(Self); +end; + +procedure TCustomSynEdit.RemoveLinesPointer; +begin + {$IFDEF SYN_COMPILER_5_UP} + if Assigned(FChainedEditor) then + RemoveFreeNotification(FChainedEditor); + {$ENDIF} + FChainedEditor := nil; + + UnHookTextBuffer; +end; + +procedure TCustomSynEdit.DragCanceled; +begin + FScrollTimer.Enabled := False; + inherited; +end; + +procedure TCustomSynEdit.DragOver(Source: TObject; X, Y: Integer; + State: TDragState; var Accept: Boolean); +var + vNewPos: TDisplayCoord; +begin + inherited; + if (Source is TCustomSynEdit) and not ReadOnly then + begin + Accept := True; + + //Ctrl is pressed => change cursor to indicate copy instead of move + if GetKeyState(VK_CONTROL) < 0 then + DragCursor := crMultiDrag + else + DragCursor := crDrag; + + if Dragging then //if the drag source is the uRESTDWPrivSynEdit itself + begin + if State = dsDragLeave then //restore prev caret position + ComputeCaret(FMouseDownX, FMouseDownY) + else + begin + vNewPos := PixelsToNearestRowColumn(X, Y); + vNewPos.Column := MinMax(vNewPos.Column, LeftChar, LeftChar + CharsInWindow - 1); + vNewPos.Row := MinMax(vNewPos.Row, TopLine, TopLine + LinesInWindow - 1); + InternalCaretXY := DisplayToBufferPos(vNewPos); + ComputeScroll(X, Y); + end; + end + else //if is dragging from another uRESTDWPrivSynEdit + ComputeCaret(X, Y); //position caret under the mouse cursor + end; +end; + +procedure TCustomSynEdit.DragDrop(Source: TObject; X, Y: Integer); +var + vNewCaret: TBufferCoord; + DoDrop, DropAfter, DropMove: Boolean; + vBB, vBE: TBufferCoord; + DragDropText: UnicodeString; + ChangeScrollPastEOL: Boolean; +begin + if not ReadOnly and (Source is TCustomSynEdit) + and TCustomSynEdit(Source).SelAvail then + begin + IncPaintLock; + try + inherited; + ComputeCaret(X, Y); + vNewCaret := CaretXY; + // if from other control then move when SHIFT, else copy + // if from Self then copy when CTRL, else move + if Source <> Self then + begin + DropMove := GetKeyState(VK_SHIFT) < 0; + DoDrop := True; + DropAfter := False; + end + else + begin + DropMove := GetKeyState(VK_CONTROL) >= 0; + vBB := BlockBegin; + vBE := BlockEnd; + DropAfter := (vNewCaret.Line > vBE.Line) + or ((vNewCaret.Line = vBE.Line) and ((vNewCaret.Char > vBE.Char) or + ((not DropMove) and (vNewCaret.Char = vBE.Char)))); + DoDrop := DropAfter or (vNewCaret.Line < vBB.Line) + or ((vNewCaret.Line = vBB.Line) and ((vNewCaret.Char < vBB.Char) or + ((not DropMove) and (vNewCaret.Char = vBB.Char)))); + end; + if DoDrop then begin + BeginUndoBlock; + try + DragDropText := TCustomSynEdit(Source).SelText; + // delete the selected text if necessary + if DropMove then + begin + if Source <> Self then + TCustomSynEdit(Source).SelText := '' + else + begin + SelText := ''; + // adjust horizontal drop position + if DropAfter and (vNewCaret.Line = vBE.Line) then + Dec(vNewCaret.Char, vBE.Char - vBB.Char); + // adjust vertical drop position + if DropAfter and (vBE.Line > vBB.Line) then + Dec(vNewCaret.Line, vBE.Line - vBB.Line); + end; + end; + //todo: this is probably already done inside SelText + // insert the selected text + ChangeScrollPastEOL := not (eoScrollPastEol in FOptions); + try + if ChangeScrollPastEOL then + Include(FOptions, eoScrollPastEol); + InternalCaretXY := vNewCaret; + BlockBegin := vNewCaret; + { Add the text. Undo is locked so the action is recorded as crDragDropInsert + instead of crInsert (code right bellow). } + Assert(not SelAvail); + LockUndo; + try + SelText := DragDropText; + finally + UnlockUndo; + end; + finally + if ChangeScrollPastEOL then + Exclude(FOptions, eoScrollPastEol); + end; + // save undo information + if Source = Self then + begin + FUndoList.AddChange(crDragDropInsert, vNewCaret, BlockEnd, SelText, + FActiveSelectionMode); + end + else begin + FUndoList.AddChange(crInsert, vNewCaret, BlockEnd, + SelText, FActiveSelectionMode); + end; + BlockEnd := CaretXY; + CommandProcessor(ecSelGotoXY, #0, @vNewCaret); + finally + EndUndoBlock; + end; + end; + finally + DecPaintLock; + end; + end + else + inherited; +end; + +procedure TCustomSynEdit.SetRightEdge(Value: Integer); +begin + if FRightEdge <> Value then + begin + FRightEdge := Value; + Invalidate; + end; +end; + +procedure TCustomSynEdit.SetRightEdgeColor(Value: TColor); +var + nX: Integer; + rcInval: TRect; +begin + if FRightEdgeColor <> Value then + begin + FRightEdgeColor := Value; + if HandleAllocated then + begin + nX := FTextOffset + FRightEdge * FCharWidth; + rcInval := Rect(nX - 1, 0, nX + 1, Height); + InvalidateRect(rcInval, False); + end; + end; +end; + +function TCustomSynEdit.GetMaxUndo: Integer; +begin + result := FUndoList.MaxUndoActions; +end; + +procedure TCustomSynEdit.SetMaxUndo(const Value: Integer); +begin + if Value > -1 then + begin + FUndoList.MaxUndoActions := Value; + FRedoList.MaxUndoActions := Value; + end; +end; + +procedure TCustomSynEdit.Notification(AComponent: TComponent; + Operation: TOperation); +begin + inherited Notification(AComponent, Operation); + if Operation = opRemove then + begin + if AComponent = FSearchEngine then + begin + SearchEngine := nil; + end; + + if AComponent = FHighlighter then + begin + Highlighter := nil; + end; + + if AComponent = FChainedEditor then + begin + RemoveLinesPointer; + end; + + if (FBookMarkOpt <> nil) then + if (AComponent = FBookMarkOpt.BookmarkImages) then + begin + FBookMarkOpt.BookmarkImages := nil; + InvalidateGutterLines(-1, -1); + end; + end; +end; + +procedure TCustomSynEdit.SetHighlighter(const Value: TSynCustomHighlighter); +{$IFDEF SYN_CodeFolding} +Var + OldUseCodeFolding : Boolean; +{$ENDIF} +begin + if Value <> FHighlighter then + begin + if Assigned(FHighlighter) then + begin + FHighlighter.UnhookAttrChangeEvent(HighlighterAttrChanged); +{$IFDEF SYN_COMPILER_5_UP} + FHighlighter.RemoveFreeNotification(Self); +{$ENDIF} + end; + if Assigned(Value) then + begin + Value.HookAttrChangeEvent(HighlighterAttrChanged); + Value.FreeNotification(Self); + end; + FHighlighter := Value; + if not(csDestroying in ComponentState) then + HighlighterAttrChanged(FHighlighter); + +{$IFDEF SYN_CodeFolding} + // Disable Code Folding if not supported by highlighter + OldUseCodeFolding := fUseCodeFolding; + UseCodeFolding := False; + UseCodeFolding := OldUseCodeFolding; + if fHighlighter is TSynCustomCodeFoldingHighlighter then + TSynCustomCodeFoldingHighlighter(fHighlighter).InitFoldRanges(fAllFoldRanges); +{$ENDIF} + end; +end; + +procedure TCustomSynEdit.SetBorderStyle(Value: TSynBorderStyle); +begin + if FBorderStyle <> Value then + begin + FBorderStyle := Value; + RecreateWnd; + end; +end; + +procedure TCustomSynEdit.SetHideSelection(const Value: Boolean); +begin + if FHideSelection <> Value then + begin + FHideSelection := Value; + InvalidateSelection; + end; +end; + +procedure TCustomSynEdit.SetInsertMode(const Value: Boolean); +begin + if FInserting <> Value then + begin + FInserting := Value; + if not (csDesigning in ComponentState) then + // Reset the caret. + InitializeCaret; + StatusChanged([scInsertMode]); + end; +end; + +procedure TCustomSynEdit.InitializeCaret; +var + ct: TSynEditCaretType; + cw, ch: Integer; +begin + // CreateCaret automatically destroys the previous one, so we don't have to + // worry about cleaning up the old one here with DestroyCaret. + // Ideally, we will have properties that control what these two carets look like. + if InsertMode then + ct := FInsertCaret + else + ct := FOverwriteCaret; + case ct of + ctHorizontalLine: + begin + cw := FCharWidth; + ch := 2; + FCaretOffset := Point(0, FTextHeight - 2); + end; + ctHalfBlock: + begin + cw := FCharWidth; + ch := (FTextHeight - 2) div 2; + FCaretOffset := Point(0, ch); + end; + ctBlock: + begin + cw := FCharWidth; + ch := FTextHeight - 2; + FCaretOffset := Point(0, 0); + end; + ctVerticalLine2: + begin + cw := 2; + ch := FTextHeight + 1; + FCaretOffset := Point(0, 0); + end; + else + begin // ctVerticalLine + cw := 2; + ch := FTextHeight - 2; + FCaretOffset := Point(-1, 0); + end; + end; + Exclude(FStateFlags, sfCaretVisible); + + if Focused or FAlwaysShowCaret then + begin + CreateCaret(Handle, 0, cw, ch); + UpdateCaret; + end; +end; + +procedure TCustomSynEdit.SetInsertCaret(const Value: TSynEditCaretType); +begin + if FInsertCaret <> Value then + begin + FInsertCaret := Value; + InitializeCaret; + end; +end; + +procedure TCustomSynEdit.SetOverwriteCaret(const Value: TSynEditCaretType); +begin + if FOverwriteCaret <> Value then + begin + FOverwriteCaret := Value; + InitializeCaret; + end; +end; + +procedure TCustomSynEdit.SetMaxScrollWidth(Value: Integer); +begin + Value := MinMax(Value, 1, MaxInt - 1); + if MaxScrollWidth <> Value then + begin + FMaxScrollWidth := Value; + if eoScrollPastEol in Options then + UpdateScrollBars; + end; +end; + +procedure TCustomSynEdit.EnsureCursorPosVisible; +begin + EnsureCursorPosVisibleEx(False); +end; + +procedure TCustomSynEdit.EnsureCursorPosVisibleEx(ForceToMiddle: Boolean; + EvenIfVisible: Boolean = False); +var + TmpMiddle: Integer; + VisibleX: Integer; + vCaretRow: Integer; +begin + HandleNeeded; + IncPaintLock; + try + // Make sure X is visible + VisibleX := DisplayX; + if VisibleX < LeftChar then + LeftChar := VisibleX + else if VisibleX >= CharsInWindow + LeftChar then + LeftChar := VisibleX - CharsInWindow + 1 + else + LeftChar := LeftChar; + + // Make sure Y is visible + vCaretRow := DisplayY; + if ForceToMiddle then + begin + if vCaretRow < (TopLine - 1) then + begin + TmpMiddle := LinesInWindow div 2; + if vCaretRow - TmpMiddle < 0 then + TopLine := 1 + else + TopLine := vCaretRow - TmpMiddle + 1; + end + else if vCaretRow > (TopLine + (LinesInWindow - 2)) then + begin + TmpMiddle := LinesInWindow div 2; + TopLine := vCaretRow - (LinesInWindow - 1) + TmpMiddle; + end + { Forces to middle even if visible in viewport } + else if EvenIfVisible then + begin + TmpMiddle := FLinesInWindow div 2; + TopLine := vCaretRow - TmpMiddle + 1; + end; + end + else begin + if vCaretRow < TopLine then + TopLine := vCaretRow + else if vCaretRow > TopLine + Max(1, LinesInWindow) - 1 then + TopLine := vCaretRow - (LinesInWindow - 1) + else + TopLine := TopLine; + end; + finally + DecPaintLock; + end; +end; + +procedure TCustomSynEdit.SetKeystrokes(const Value: TSynEditKeyStrokes); +begin + if Value = nil then + FKeyStrokes.Clear + else + FKeyStrokes.Assign(Value); +end; + +procedure TCustomSynEdit.SetDefaultKeystrokes; +begin + FKeyStrokes.ResetDefaults; +end; + +// If the translations requires Data, memory will be allocated for it via a +// GetMem call. The client must call FreeMem on Data if it is not NIL. + +function TCustomSynEdit.TranslateKeyCode(Code: Word; Shift: TShiftState; + var Data: Pointer): TSynEditorCommand; +var + i: Integer; +{$IFNDEF SYN_COMPILER_3_UP} +const + VK_ACCEPT = $30; +{$ENDIF} +begin + i := KeyStrokes.FindKeycode2(FLastKey, FLastShiftState, Code, Shift); + if i >= 0 then + Result := KeyStrokes[i].Command + else begin + i := Keystrokes.FindKeycode(Code, Shift); + if i >= 0 then + Result := Keystrokes[i].Command + else + Result := ecNone; + end; + if (Result = ecNone) and (Code >= VK_ACCEPT) and (Code <= VK_SCROLL) then + begin + FLastKey := Code; + FLastShiftState := Shift; + end + else + begin + FLastKey := 0; + FLastShiftState := []; + end; +end; + +procedure TCustomSynEdit.CommandProcessor(Command: TSynEditorCommand; + AChar: WideChar; Data: Pointer); +begin + // first the program event handler gets a chance to process the command + DoOnProcessCommand(Command, AChar, Data); + if Command <> ecNone then + begin + // notify hooked command handlers before the command is executed inside of + // the class + NotifyHookedCommandHandlers(False, Command, AChar, Data); + // internal command handler + if (Command <> ecNone) and (Command < ecUserFirst) then + ExecuteCommand(Command, AChar, Data); + // notify hooked command handlers after the command was executed inside of + // the class + if Command <> ecNone then + NotifyHookedCommandHandlers(True, Command, AChar, Data); + end; + DoOnCommandProcessed(Command, AChar, Data); +end; + +procedure TCustomSynEdit.ExecuteCommand(Command: TSynEditorCommand; AChar: WideChar; + Data: Pointer); + + procedure SetSelectedTextEmpty; + var + vSelText: UnicodeString; + vUndoBegin, vUndoEnd: TBufferCoord; + begin + vUndoBegin := FBlockBegin; + vUndoEnd := FBlockEnd; + vSelText := SelText; + SetSelTextPrimitive(''); + if (vUndoBegin.Line < vUndoEnd.Line) or ( + (vUndoBegin.Line = vUndoEnd.Line) and (vUndoBegin.Char < vUndoEnd.Char)) then + begin + FUndoList.AddChange(crDelete, vUndoBegin, vUndoEnd, vSelText, + FActiveSelectionMode); + end + else + begin + FUndoList.AddChange(crDeleteAfterCursor, vUndoBegin, vUndoEnd, vSelText, + FActiveSelectionMode); + end; + end; + + procedure ForceCaretX(aCaretX: Integer); + var + vRestoreScroll: Boolean; + begin + vRestoreScroll := not (eoScrollPastEol in FOptions); + Include(FOptions, eoScrollPastEol); + try + InternalCaretX := aCaretX; + finally + if vRestoreScroll then + Exclude(FOptions, eoScrollPastEol); + end; + end; + +var + CX: Integer; + Len: Integer; + Temp: UnicodeString; + Temp2: UnicodeString; + Helper: UnicodeString; + TabBuffer: UnicodeString; + SpaceBuffer: UnicodeString; + SpaceCount1: Integer; + SpaceCount2: Integer; + BackCounter: Integer; + StartOfBlock: TBufferCoord; + EndOfBlock: TBufferCoord; + bChangeScroll: Boolean; + moveBkm: Boolean; + WP: TBufferCoord; + Caret: TBufferCoord; + CaretNew: TBufferCoord; + counter: Integer; + InsDelta: Integer; + iUndoBegin, iUndoEnd: TBufferCoord; + vCaretRow: Integer; + vTabTrim: Integer; + s: UnicodeString; + i: Integer; +begin + IncPaintLock; + try + case Command of +// horizontal caret movement or selection + ecLeft, ecSelLeft: + MoveCaretHorz(-1, Command = ecSelLeft); + ecRight, ecSelRight: + MoveCaretHorz(1, Command = ecSelRight); + ecPageLeft, ecSelPageLeft: + MoveCaretHorz(-CharsInWindow, Command = ecSelPageLeft); + ecPageRight, ecSelPageRight: + MoveCaretHorz(CharsInWindow, Command = ecSelPageRight); + ecLineStart, ecSelLineStart: + begin + DoHomeKey(Command = ecSelLineStart); + end; + ecLineEnd, ecSelLineEnd: + DoEndKey(Command = ecSelLineEnd); +// vertical caret movement or selection + ecUp, ecSelUp: + begin + MoveCaretVert(-1, Command = ecSelUp); + Update; + end; + ecDown, ecSelDown: + begin + MoveCaretVert(1, Command = ecSelDown); + Update; + end; + ecPageUp, ecSelPageUp, ecPageDown, ecSelPageDown: + begin + counter := FLinesInWindow shr Ord(eoHalfPageScroll in FOptions); + if eoScrollByOneLess in FOptions then + Dec(counter); + if (Command in [ecPageUp, ecSelPageUp]) then + counter := -counter; + TopLine := TopLine + counter; + MoveCaretVert(counter, Command in [ecSelPageUp, ecSelPageDown]); + Update; + end; + ecPageTop, ecSelPageTop: + begin + CaretNew := DisplayToBufferPos( + DisplayCoord(DisplayX, TopLine) ); + MoveCaretAndSelection(CaretXY, CaretNew, Command = ecSelPageTop); + Update; + end; + ecPageBottom, ecSelPageBottom: + begin + CaretNew := DisplayToBufferPos( + DisplayCoord(DisplayX, TopLine + LinesInWindow -1) ); + MoveCaretAndSelection(CaretXY, CaretNew, Command = ecSelPageBottom); + Update; + end; + ecEditorTop, ecSelEditorTop: + begin + CaretNew.Char := 1; + CaretNew.Line := 1; + MoveCaretAndSelection(CaretXY, CaretNew, Command = ecSelEditorTop); + Update; + end; + ecEditorBottom, ecSelEditorBottom: + begin + CaretNew.Char := 1; + CaretNew.Line := Lines.Count; + if (CaretNew.Line > 0) then + CaretNew.Char := Length(Lines[CaretNew.Line - 1]) + 1; + MoveCaretAndSelection(CaretXY, CaretNew, Command = ecSelEditorBottom); + Update; + end; +// goto special line / column position + ecGotoXY, ecSelGotoXY: + if Assigned(Data) then + begin + MoveCaretAndSelection(CaretXY, TBufferCoord(Data^), Command = ecSelGotoXY); + Update; + end; +// Word selection + ecWordLeft, ecSelWordLeft: + begin + CaretNew := PrevWordPos; + MoveCaretAndSelection(CaretXY, CaretNew, Command = ecSelWordLeft); + end; + ecWordRight, ecSelWordRight: + begin + CaretNew := NextWordPos; + MoveCaretAndSelection(CaretXY, CaretNew, Command = ecSelWordRight); + end; + ecSelWord: + begin + SetSelWord; + end; + ecSelectAll: + begin + SelectAll; + end; + ecDeleteLastChar: + if not ReadOnly then begin + DoOnPaintTransientEx(ttBefore,true); + try + if SelAvail then + SetSelectedTextEmpty + else begin + Temp := LineText; + TabBuffer := TSynEditStringList(Lines).ExpandedStrings[CaretY - 1]; + Len := Length(Temp); + Caret := CaretXY; + vTabTrim := 0; + if CaretX > Len + 1 then + begin + Helper := ''; + if eoSmartTabDelete in FOptions then + begin + //It's at the end of the line, move it to the length + if Len > 0 then + InternalCaretX := Len + 1 + else begin + //move it as if there were normal spaces there + SpaceCount1 := CaretX - 1; + SpaceCount2 := 0; + // unindent + if SpaceCount1 > 0 then + begin + BackCounter := CaretY - 2; + //It's better not to have if statement inside loop + if (eoTrimTrailingSpaces in Options) then + while BackCounter >= 0 do + begin + SpaceCount2 := LeftSpacesEx(Lines[BackCounter], True); + if (SpaceCount2 > 0) and (SpaceCount2 < SpaceCount1) then + Break; + Dec(BackCounter); + end + else + while BackCounter >= 0 do + begin + SpaceCount2 := LeftSpaces(Lines[BackCounter]); + if (SpaceCount2 > 0) and (SpaceCount2 < SpaceCount1) then + Break; + Dec(BackCounter); + end; + if (BackCounter = -1) and (SpaceCount2 > SpaceCount1) then + SpaceCount2 := 0; + end; + if SpaceCount2 = SpaceCount1 then + SpaceCount2 := 0; + FCaretX := FCaretX - (SpaceCount1 - SpaceCount2); + UpdateLastCaretX; + FStateFlags := FStateFlags + [sfCaretChanged]; + StatusChanged([scCaretX]); + end; + end + else begin + // only move caret one column + InternalCaretX := CaretX - 1; + end; + end else if CaretX = 1 then begin + // join this line with the last line if possible + if CaretY > 1 then + begin + InternalCaretY := CaretY - 1; + InternalCaretX := Length(Lines[CaretY - 1]) + 1; + Lines.Delete(CaretY); + DoLinesDeleted(CaretY+1, 1); + if eoTrimTrailingSpaces in Options then + Temp := TrimTrailingSpaces(Temp); + + LineText := LineText + Temp; + Helper := #13#10; + end; + end + else begin + // delete text before the caret + SpaceCount1 := LeftSpaces(Temp); + SpaceCount2 := 0; + if (Temp[CaretX - 1] <= #32) and (SpaceCount1 = CaretX - 1) then + begin + if eoSmartTabDelete in FOptions then + begin + // unindent + if SpaceCount1 > 0 then + begin + BackCounter := CaretY - 2; + //It's better not to have if statement inside loop + if (eoTrimTrailingSpaces in Options) then + while BackCounter >= 0 do + begin + SpaceCount2 := LeftSpacesEx(Lines[BackCounter], True); + if (SpaceCount2 > 0) and (SpaceCount2 < SpaceCount1) then + Break; + Dec(BackCounter); + end + else + while BackCounter >= 0 do + begin + SpaceCount2 := LeftSpaces(Lines[BackCounter]); + if (SpaceCount2 > 0) and (SpaceCount2 < SpaceCount1) then + Break; + Dec(BackCounter); + end; + if (BackCounter = -1) and (SpaceCount2 > SpaceCount1) then + SpaceCount2 := 0; + end; + if SpaceCount2 = SpaceCount1 then + SpaceCount2 := 0; + Helper := Copy(Temp, 1, SpaceCount1 - SpaceCount2); + Delete(Temp, 1, SpaceCount1 - SpaceCount2); + end + else begin + SpaceCount2 := SpaceCount1; + //how much till the next tab column + BackCounter := (DisplayX - 1) mod FTabWidth; + if BackCounter = 0 then BackCounter := FTabWidth; + + SpaceCount1 := 0; + CX := DisplayX - BackCounter; + while (SpaceCount1 < FTabWidth) and + (SpaceCount1 < BackCounter) and + (TabBuffer[CX] <> #9) do + begin + Inc(SpaceCount1); + Inc(CX); + end; + {$IFOPT R+} + // Avoids an exception when compiled with $R+. + // 'CX' can be 'Length(TabBuffer)+1', which isn't an AV and evaluates + //to #0. But when compiled with $R+, Delphi raises an Exception. + if CX <= Length(TabBuffer) then + {$ENDIF} + if TabBuffer[CX] = #9 then + SpaceCount1 := SpaceCount1 + 1; + + if SpaceCount2 = SpaceCount1 then + begin + Helper := Copy(Temp, 1, SpaceCount1); + Delete(Temp, 1, SpaceCount1); + end + else begin + Helper := Copy(Temp, SpaceCount2 - SpaceCount1 + 1, SpaceCount1); + Delete(Temp, SpaceCount2 - SpaceCount1 + 1, SpaceCount1); + end; + SpaceCount2 := 0; + end; + FCaretX := FCaretX - (SpaceCount1 - SpaceCount2); + UpdateLastCaretX; + // Stores the previous "expanded" CaretX if the line contains tabs. + if (eoTrimTrailingSpaces in Options) and (Len <> Length(TabBuffer)) then + vTabTrim := CharIndex2CaretPos(CaretX, TabWidth, Temp); + ProperSetLine(CaretY - 1, Temp); + FStateFlags := FStateFlags + [sfCaretChanged]; + StatusChanged([scCaretX]); + // Calculates a delta to CaretX to compensate for trimmed tabs. + if vTabTrim <> 0 then + if Length(Temp) <> Length(LineText) then + Dec(vTabTrim, CharIndex2CaretPos(CaretX, TabWidth, LineText)) + else + vTabTrim := 0; + end + else begin + // delete char + counter := 1; + InternalCaretX := CaretX - counter; + // Stores the previous "expanded" CaretX if the line contains tabs. + if (eoTrimTrailingSpaces in Options) and (Len <> Length(TabBuffer)) then + vTabTrim := CharIndex2CaretPos(CaretX, TabWidth, Temp); + Helper := Copy(Temp, CaretX, counter); + Delete(Temp, CaretX, counter); + ProperSetLine(CaretY - 1, Temp); + // Calculates a delta to CaretX to compensate for trimmed tabs. + if vTabTrim <> 0 then + if Length(Temp) <> Length(LineText) then + Dec(vTabTrim, CharIndex2CaretPos(CaretX, TabWidth, LineText)) + else + vTabTrim := 0; + end; + end; + if (Caret.Char <> CaretX) or (Caret.Line <> CaretY) then + begin + FUndoList.AddChange(crSilentDelete, CaretXY, Caret, Helper, + smNormal); + if vTabTrim <> 0 then + ForceCaretX(CaretX + vTabTrim); + end; + end; + EnsureCursorPosVisible; + finally + DoOnPaintTransientEx(ttAfter,true); + end; + end; + ecDeleteChar: + if not ReadOnly then begin + DoOnPaintTransient(ttBefore); + + if SelAvail then + SetSelectedTextEmpty + else begin + // Call UpdateLastCaretX. Even though the caret doesn't move, the + // current caret position should "stick" whenever text is modified. + UpdateLastCaretX; + Temp := LineText; + Len := Length(Temp); + if CaretX <= Len then + begin + // delete char + counter := 1; + Helper := Copy(Temp, CaretX, counter); + Caret.Char := CaretX + counter; + Caret.Line := CaretY; + Delete(Temp, CaretX, counter); + ProperSetLine(CaretY - 1, Temp); + end + else begin + // join line with the line after + if CaretY < Lines.Count then + begin + Helper := UnicodeStringOfChar(#32, CaretX - 1 - Len); + ProperSetLine(CaretY - 1, Temp + Helper + Lines[CaretY]); + Caret.Char := 1; + Caret.Line := CaretY + 1; + Helper := #13#10; + Lines.Delete(CaretY); + DoLinesDeleted(CaretY +1, 1); + end; + end; + if (Caret.Char <> CaretX) or (Caret.Line <> CaretY) then + begin + FUndoList.AddChange(crSilentDeleteAfterCursor, CaretXY, Caret, + Helper, smNormal); + end; + end; + DoOnPaintTransient(ttAfter); + end; + ecDeleteWord, ecDeleteEOL: + if not ReadOnly then begin + DoOnPaintTransient(ttBefore); + Len := Length(LineText); + if Command = ecDeleteWord then + begin + WP := WordEnd; + Temp := LineText; + if (WP.Char < CaretX) or ((WP.Char = CaretX) and (WP.Line < FLines.Count)) then + begin + if WP.Char > Len then + begin + Inc(WP.Line); + WP.Char := 1; + Temp := Lines[WP.Line - 1]; + end + else if Temp[WP.Char] <> #32 then + Inc(WP.Char); + end; + {$IFOPT R+} + Temp := Temp + #0; + {$ENDIF} + if Temp <> '' then + while Temp[WP.Char] = #32 do + Inc(WP.Char); + end + else begin + WP.Char := Len + 1; + WP.Line := CaretY; + end; + if (WP.Char <> CaretX) or (WP.Line <> CaretY) then + begin + SetBlockBegin(CaretXY); + SetBlockEnd(WP); + ActiveSelectionMode := smNormal; + Helper := SelText; + SetSelTextPrimitive(UnicodeStringOfChar(' ', CaretX - BlockBegin.Char)); + FUndoList.AddChange(crSilentDeleteAfterCursor, CaretXY, WP, + Helper, smNormal); + InternalCaretXY := CaretXY; + end; + end; + ecDeleteLastWord, ecDeleteBOL: + if not ReadOnly then begin + DoOnPaintTransient(ttBefore); + if Command = ecDeleteLastWord then + WP := PrevWordPos + else begin + WP.Char := 1; + WP.Line := CaretY; + end; + if (WP.Char <> CaretX) or (WP.Line <> CaretY) then + begin + SetBlockBegin(CaretXY); + SetBlockEnd(WP); + ActiveSelectionMode := smNormal; + Helper := SelText; + SetSelTextPrimitive(''); + FUndoList.AddChange(crSilentDelete, WP, CaretXY, Helper, + smNormal); + InternalCaretXY := WP; + end; + DoOnPaintTransient(ttAfter); + end; + ecDeleteLine: + if not ReadOnly and (Lines.Count > 0) and not ((CaretY = Lines.Count) and (Length(Lines[CaretY - 1]) = 0)) + then begin + DoOnPaintTransient(ttBefore); + if SelAvail then + SetBlockBegin(CaretXY); + Helper := LineText; + if CaretY = Lines.Count then + begin + Lines[CaretY - 1] := ''; + FUndoList.AddChange(crSilentDeleteAfterCursor, BufferCoord(1, CaretY), + BufferCoord(Length(Helper) + 1, CaretY), Helper, smNormal); + end + else begin + Lines.Delete(CaretY - 1); + Helper := Helper + #13#10; + FUndoList.AddChange(crSilentDeleteAfterCursor, BufferCoord(1, CaretY), + BufferCoord(1, CaretY + 1), Helper, smNormal); + DoLinesDeleted(CaretY, 1); + end; + InternalCaretXY := BufferCoord(1, CaretY); // like seen in the Delphi editor + end; + ecClearAll: + begin + if not ReadOnly then ClearAll; + end; + ecInsertLine, + ecLineBreak: + if not ReadOnly then begin + UndoList.BeginBlock; + try + if SelAvail then + begin + Helper := SelText; + iUndoBegin := FBlockBegin; + iUndoEnd := FBlockEnd; + SetSelTextPrimitive(''); + FUndoList.AddChange(crDelete, iUndoBegin, iUndoEnd, Helper, + FActiveSelectionMode); + end; + Temp := LineText; + Temp2 := Temp; +// This is sloppy, but the Right Thing would be to track the column of markers +// too, so they could be moved depending on whether they are after the caret... + InsDelta := Ord(CaretX = 1); + Len := Length(Temp); + if Len > 0 then + begin + if Len >= CaretX then + begin + if CaretX > 1 then + begin + Temp := Copy(LineText, 1, CaretX - 1); + SpaceCount1 := LeftSpacesEx(Temp,true); + Delete(Temp2, 1, CaretX - 1); + Lines.Insert(CaretY, GetLeftSpacing(SpaceCount1, True) + Temp2); + ProperSetLine(CaretY - 1, Temp); + FUndoList.AddChange(crLineBreak, CaretXY, CaretXY, Temp2, + smNormal); + if Command = ecLineBreak then + InternalCaretXY := BufferCoord( + Length(GetLeftSpacing(SpaceCount1,true)) + 1, + CaretY + 1); + end + else begin + Lines.Insert(CaretY - 1, ''); + FUndoList.AddChange(crLineBreak, CaretXY, CaretXY, Temp2, + smNormal); + if Command = ecLineBreak then + InternalCaretY := CaretY + 1; + end; + end + else begin + SpaceCount2 := 0; + BackCounter := CaretY; + if eoAutoIndent in Options then + begin + repeat + Dec(BackCounter); + Temp := Lines[BackCounter]; + SpaceCount2 := LeftSpaces(Temp); + until (BackCounter = 0) or (Temp <> ''); + end; + Lines.Insert(CaretY, ''); + Caret := CaretXY; + + FUndoList.AddChange(crLineBreak, Caret, Caret, '', smNormal); //KV + if Command = ecLineBreak then + begin + InternalCaretXY := BufferCoord(1, CaretY +1); + if SpaceCount2 > 0 then + begin + SpaceBuffer := Copy(Lines[BackCounter], 1, SpaceCount2); + for i := 1 to Length(SpaceBuffer) do + if SpaceBuffer[i] = #9 then + CommandProcessor(ecTab, #0, nil) + else + CommandProcessor(ecChar, SpaceBuffer[i], nil); + end; + end; + end; + end + else begin + if FLines.Count = 0 then + FLines.Add(''); + SpaceCount2 := 0; + if eoAutoIndent in Options then + begin + BackCounter := CaretY - 1; + while BackCounter >= 0 do + begin + SpaceCount2 := LeftSpacesEx(Lines[BackCounter],True); + if Length(Lines[BackCounter]) > 0 then + Break; + Dec(BackCounter); + end; + end; + Lines.Insert(CaretY - 1, ''); + FUndoList.AddChange(crLineBreak, CaretXY, CaretXY, '', smNormal); + if Command = ecLineBreak then + InternalCaretX := SpaceCount2 + 1; + if Command = ecLineBreak then + InternalCaretY := CaretY + 1; + end; + DoLinesInserted(CaretY - InsDelta, 1); + BlockBegin := CaretXY; + BlockEnd := CaretXY; + EnsureCursorPosVisible; + UpdateLastCaretX; + finally + UndoList.EndBlock; + end; + end; + ecTab: + if not ReadOnly then DoTabKey; + ecShiftTab: + if not ReadOnly then DoShiftTabKey; + ecMatchBracket: + FindMatchingBracket; + ecChar: + // #127 is Ctrl + Backspace, #32 is space + if not ReadOnly and (AChar >= #32) and (AChar <> #127) then + begin + if SelAvail then + begin + BeginUndoBlock; + try + Helper := SelText; + iUndoBegin := FBlockBegin; + iUndoEnd := FBlockEnd; + StartOfBlock := BlockBegin; + if FActiveSelectionMode = smLine then + StartOfBlock.Char := 1; + FUndoList.AddChange(crDelete, iUndoBegin, iUndoEnd, Helper, + FActiveSelectionMode); + SetSelTextPrimitive(AChar); + if FActiveSelectionMode <> smColumn then + begin + FUndoList.AddChange(crInsert, StartOfBlock, BlockEnd, '', + smNormal); + end; + finally + EndUndoBlock; + end; + end + else + begin + SpaceCount2 := 0; + Temp := LineText; + Len := Length(Temp); + if Len < CaretX then + begin + if (Len > 0) then + SpaceBuffer := UnicodeStringOfChar(#32, CaretX - Len - Ord(FInserting)) + else + SpaceBuffer := GetLeftSpacing(CaretX - Len - Ord(FInserting), True); + SpaceCount2 := Length(SpaceBuffer); + + Temp := Temp + SpaceBuffer; + end; + // Added the check for whether or not we're in insert mode. + // If we are, we append one less space than we would in overwrite mode. + // This is because in overwrite mode we have to put in a final space + // character which will be overwritten with the typed character. If we put the + // extra space in in insert mode, it would be left at the end of the line and + // cause problems unless eoTrimTrailingSpaces is set. + bChangeScroll := not (eoScrollPastEol in FOptions); + try + if bChangeScroll then Include(FOptions, eoScrollPastEol); + StartOfBlock := CaretXY; + + if FInserting then + begin + if not WordWrap and not (eoAutoSizeMaxScrollWidth in Options) + and (CaretX > MaxScrollWidth) then + begin + Exit; + end; + Insert(AChar, Temp, CaretX); + if (eoTrimTrailingSpaces in Options) and ((AChar = #9) or (AChar = #32)) and (Length(TrimTrailingSpaces(LineText)) = 0) then + InternalCaretX := GetExpandedLength(Temp, TabWidth) + 1 + else + begin + if Len = 0 then + InternalCaretX := Length(Temp) + 1 + else + InternalCaretX := CaretX + 1; + end; + ProperSetLine(CaretY - 1, Temp); + if SpaceCount2 > 0 then + begin + BeginUndoBlock; + try + //if we inserted spaces with this char, we need to account for those + //in the X Position + StartOfBlock.Char := StartOfBlock.Char - SpaceCount2; + EndOfBlock := CaretXY; + EndOfBlock.Char := EndOfBlock.Char - 1; + //The added whitespace + FUndoList.AddChange(crWhiteSpaceAdd, EndOfBlock, StartOfBlock, '', + smNormal); + StartOfBlock.Char := StartOfBlock.Char + SpaceCount2; + + FUndoList.AddChange(crInsert, StartOfBlock, CaretXY, '', + smNormal); + finally + EndUndoBlock; + end; + end + else begin + FUndoList.AddChange(crInsert, StartOfBlock, CaretXY, '', + smNormal); + end; + end + else begin +// Processing of case character covers on LeadByte. + counter := 1; + Helper := Copy(Temp, CaretX, counter); + Temp[CaretX] := AChar; + CaretNew.Char := CaretX + counter; + CaretNew.Line := CaretY; + ProperSetLine(CaretY - 1, Temp); + FUndoList.AddChange(crInsert, StartOfBlock, CaretNew, Helper, + smNormal); + InternalCaretX := CaretX + 1; + end; + if CaretX >= LeftChar + FCharsInWindow then + LeftChar := LeftChar + Min(25, FCharsInWindow - 1); + finally + if bChangeScroll then Exclude(FOptions, eoScrollPastEol); + end; + end; + DoOnPaintTransient(ttAfter); + end; + ecUpperCase, + ecLowerCase, + ecToggleCase, + ecTitleCase, + ecUpperCaseBlock, + ecLowerCaseBlock, + ecToggleCaseBlock, + ecTitleCaseBlock: + if not ReadOnly then DoCaseChange(Command); + ecUndo: + begin + if not ReadOnly then Undo; + end; + ecRedo: + begin + if not ReadOnly then Redo; + end; + ecGotoMarker0..ecGotoMarker9: + begin + if BookMarkOptions.EnableKeys then + GotoBookMark(Command - ecGotoMarker0); + end; + ecSetMarker0..ecSetMarker9: + begin + if BookMarkOptions.EnableKeys then + begin + CX := Command - ecSetMarker0; + if Assigned(Data) then + Caret := TBufferCoord(Data^) + else + Caret := CaretXY; + if assigned(FBookMarks[CX]) then + begin + moveBkm := (FBookMarks[CX].Line <> Caret.Line); + ClearBookMark(CX); + if moveBkm then + SetBookMark(CX, Caret.Char, Caret.Line); + end + else + SetBookMark(CX, Caret.Char, Caret.Line); + end; // if BookMarkOptions.EnableKeys + end; + ecCut: + begin + if (not ReadOnly) and SelAvail then + CutToClipboard; + end; + ecCopy: + begin + CopyToClipboard; + end; + ecPaste: + begin + if not ReadOnly then PasteFromClipboard; + end; + ecScrollUp, ecScrollDown: + begin + vCaretRow := DisplayY; + if (vCaretRow < TopLine) or (vCaretRow >= TopLine + LinesInWindow) then + // If the caret is not in view then, like the Delphi editor, move + // it in view and do nothing else + EnsureCursorPosVisible + else begin + if Command = ecScrollUp then + begin + TopLine := TopLine - 1; + if vCaretRow > TopLine + LinesInWindow - 1 then + MoveCaretVert((TopLine + LinesInWindow - 1) - vCaretRow, False); + end + else begin + TopLine := TopLine + 1; + if vCaretRow < TopLine then + MoveCaretVert(TopLine - vCaretRow, False); + end; + EnsureCursorPosVisible; + Update; + end; + end; + ecScrollLeft: + begin + LeftChar := LeftChar - 1; + // todo: The following code was commented out because it is not MBCS or hard-tab safe. + //if CaretX > LeftChar + CharsInWindow then + // InternalCaretX := LeftChar + CharsInWindow; + Update; + end; + ecScrollRight: + begin + LeftChar := LeftChar + 1; + // todo: The following code was commented out because it is not MBCS or hard-tab safe. + //if CaretX < LeftChar then + // InternalCaretX := LeftChar; + Update; + end; + ecInsertMode: + begin + InsertMode := True; + end; + ecOverwriteMode: + begin + InsertMode := False; + end; + ecToggleMode: + begin + InsertMode := not InsertMode; + end; + ecBlockIndent: + if not ReadOnly then DoBlockIndent; + ecBlockUnindent: + if not ReadOnly then DoBlockUnindent; + ecNormalSelect: + SelectionMode := smNormal; + ecColumnSelect: + SelectionMode := smColumn; + ecLineSelect: + SelectionMode := smLine; + ecContextHelp: + begin + if Assigned (FOnContextHelp) then + FOnContextHelp (self,WordAtCursor); + end; + ecImeStr: + if not ReadOnly then + begin + SetString(S, PWideChar(Data), WStrLen(Data)); + if SelAvail then + begin + BeginUndoBlock; + try + FUndoList.AddChange(crDelete, FBlockBegin, FBlockEnd, SelText, + smNormal); + StartOfBlock := BlockBegin; + EndOfBlock.Line := BlockBegin.Line; + EndOfBlock.Char := BlockBegin.Char + Length(s); + SetSelTextPrimitive(s); + FUndoList.AddChange(crInsert, StartOfBlock, EndOfBlock, '', + smNormal); + finally + EndUndoBlock; + end; + InvalidateGutterLines(-1, -1); + end + else + begin + Temp := LineText; + Len := Length(Temp); + if Len < CaretX then + Temp := Temp + UnicodeStringOfChar(#32, CaretX - Len - 1); + bChangeScroll := not (eoScrollPastEol in FOptions); + try + if bChangeScroll then Include(FOptions, eoScrollPastEol); + StartOfBlock := CaretXY; + Len := Length(s); + if not FInserting then + begin + Helper := Copy(Temp, CaretX, Len); + Delete(Temp, CaretX, Len); + end; + Insert(s, Temp, CaretX); + InternalCaretX := (CaretX + Len); + ProperSetLine(CaretY - 1, Temp); + if FInserting then + Helper := ''; + FUndoList.AddChange(crInsert, StartOfBlock, CaretXY, Helper, + smNormal); + if CaretX >= LeftChar + FCharsInWindow then + LeftChar := LeftChar + min(25, FCharsInWindow - 1); + finally + if bChangeScroll then Exclude(FOptions, eoScrollPastEol); + end; + end; + end; +{$IFDEF SYN_CodeFolding} + ecFoldAll: begin CollapseAll; end; + ecUnfoldAll: begin UncollapseAll; end; + ecFoldNearest: begin CollapseNearest; end; + ecUnfoldNearest: begin UncollapseNearest; end; + ecFoldLevel1: begin CollapseLevel(1); end; + ecFoldLevel2: begin CollapseLevel(2); end; + ecFoldLevel3: begin CollapseLevel(3); end; + ecUnfoldLevel1: begin UncollapseLevel(1); end; + ecUnfoldLevel2: begin UncollapseLevel(2); end; + ecUnfoldLevel3: begin UncollapseLevel(3); end; + ecFoldRegions: begin CollapseFoldType(FoldRegionType) end; + ecUnfoldRegions: begin UnCollapseFoldType(FoldRegionType) end; +{$ENDIF} + end; + finally + DecPaintLock; + end; +end; + +procedure TCustomSynEdit.DoOnCommandProcessed(Command: TSynEditorCommand; + AChar: WideChar; Data: Pointer); +begin + if Assigned(FOnCommandProcessed) then + FOnCommandProcessed(Self, Command, AChar, Data); +end; + +procedure TCustomSynEdit.DoOnProcessCommand(var Command: TSynEditorCommand; + var AChar: WideChar; Data: Pointer); +begin + if Command < ecUserFirst then + begin + if Assigned(FOnProcessCommand) then + FOnProcessCommand(Self, Command, AChar, Data); + end + else begin + if Assigned(FOnProcessUserCommand) then + FOnProcessUserCommand(Self, Command, AChar, Data); + end; +end; + +procedure TCustomSynEdit.ClearAll; +begin + Lines.Clear; + FMarkList.Clear; // FMarkList.Clear also frees all bookmarks, + FillChar(FBookMarks, sizeof(FBookMarks), 0); // so FBookMarks should be cleared too + FUndoList.Clear; + FRedoList.Clear; + Modified := False; +end; + +procedure TCustomSynEdit.ClearSelection; +begin + if SelAvail then + SelText := ''; +end; + +function TCustomSynEdit.NextWordPosEx(const XY: TBufferCoord): TBufferCoord; +var + CX, CY, LineLen: Integer; + Line: UnicodeString; +begin + CX := XY.Char; + CY := XY.Line; + + // valid line? + if (CY >= 1) and (CY <= Lines.Count) then + begin + Line := Lines[CY - 1]; + + LineLen := Length(Line); + if CX >= LineLen then + begin + // find first IdentChar or multibyte char in the next line + if CY < Lines.Count then + begin + Line := Lines[CY]; + Inc(CY); + CX := StrScanForCharInCategory(Line, 1, IsIdentChar); + if CX = 0 then + Inc(CX); + end; + end + else + begin + // find next Word-break-char if current char is an IdentChar + if IsIdentChar(Line[CX]) then + CX := StrScanForCharInCategory(Line, CX, IsWordBreakChar); + // if Word-break-char found, find the next IdentChar + if CX > 0 then + CX := StrScanForCharInCategory(Line, CX, IsIdentChar); + // if one of those failed just position at the end of the line + if CX = 0 then + CX := LineLen + 1; + end; + end; + Result.Char := CX; + Result.Line := CY; +end; + +function TCustomSynEdit.WordStartEx(const XY: TBufferCoord): TBufferCoord; +var + CX, CY: Integer; + Line: UnicodeString; +begin + CX := XY.Char; + CY := XY.Line; + // valid line? + if (CY >= 1) and (CY <= Lines.Count) then + begin + Line := Lines[CY - 1]; + CX := Min(CX, Length(Line) + 1); + + if CX > 1 then + begin // only find previous char, if not already on start of line + // if previous char isn't a word-break-char search for the last IdentChar + if not IsWordBreakChar(Line[CX - 1]) then + CX := StrRScanForCharInCategory(Line, CX - 1, IsWordBreakChar) + 1; + end; + end; + Result.Char := CX; + Result.Line := CY; +end; + +function TCustomSynEdit.WordEndEx(const XY: TBufferCoord): TBufferCoord; +var + CX, CY: Integer; + Line: UnicodeString; +begin + CX := XY.Char; + CY := XY.Line; + // valid line? + if (CY >= 1) and (CY <= Lines.Count) then + begin + Line := Lines[CY - 1]; + + CX := StrScanForCharInCategory(Line, CX, IsWordBreakChar); + // if no Word-break-char is found just position at the end of the line + if CX = 0 then + CX := Length(Line) + 1; + end; + Result.Char := CX; + Result.Line := CY; +end; + +function TCustomSynEdit.PrevWordPosEx(const XY: TBufferCoord): TBufferCoord; +var + CX, CY: Integer; + Line: UnicodeString; +begin + CX := XY.Char; + CY := XY.Line; + // valid line? + if (CY >= 1) and (CY <= Lines.Count) then + begin + Line := Lines[CY - 1]; + CX := Min(CX, Length(Line) + 1); + + if CX <= 1 then + begin + // find last IdentChar in the previous line + if CY > 1 then + begin + Dec(CY); + Line := Lines[CY - 1]; + CX := Length(Line) + 1; + end; + end + else + begin + // if previous char is a Word-break-char search for the last IdentChar + if IsWordBreakChar(Line[CX - 1]) then + CX := StrRScanForCharInCategory(Line, CX - 1, IsIdentChar); + if CX > 0 then + // search for the first IdentChar of this "word" + CX := StrRScanForCharInCategory(Line, CX - 1, IsWordBreakChar) + 1; + if CX = 0 then + begin + // else just position at the end of the previous line + if CY > 1 then + begin + Dec(CY); + Line := Lines[CY - 1]; + CX := Length(Line) + 1; + end + else + CX := 1; + end; + end; + end; + Result.Char := CX; + Result.Line := CY; +end; + +procedure TCustomSynEdit.SetSelectionMode(const Value: TSynSelectionMode); +begin + if FSelectionMode <> Value then + begin + FSelectionMode := Value; + ActiveSelectionMode := Value; + end; +end; + +procedure TCustomSynEdit.SetActiveSelectionMode(const Value: TSynSelectionMode); +begin + if FActiveSelectionMode <> Value then + begin + if SelAvail then + InvalidateSelection; + FActiveSelectionMode := Value; + if SelAvail then + InvalidateSelection; + StatusChanged([scSelection]); + end; +end; + +procedure TCustomSynEdit.SetAdditionalIdentChars(const Value: TSysCharSet); +begin + FAdditionalIdentChars := Value; +end; + +procedure TCustomSynEdit.SetAdditionalWordBreakChars(const Value: TSysCharSet); +begin + FAdditionalWordBreakChars := Value; +end; + +procedure TCustomSynEdit.BeginUndoBlock; +begin + FUndoList.BeginBlock; +end; + +procedure TCustomSynEdit.BeginUpdate; +begin + IncPaintLock; +end; + +procedure TCustomSynEdit.EndUndoBlock; +begin + FUndoList.EndBlock; +end; + +procedure TCustomSynEdit.EndUpdate; +begin + DecPaintLock; +end; + +procedure TCustomSynEdit.AddKey(Command: TSynEditorCommand; + Key1: Word; SS1: TShiftState; Key2: Word; SS2: TShiftState); +var + Key: TSynEditKeyStroke; +begin + Key := Keystrokes.Add; + Key.Command := Command; + Key.Key := Key1; + Key.Shift := SS1; + Key.Key2 := Key2; + Key.Shift2 := SS2; +end; + +{ Called by FMarkList if change } +procedure TCustomSynEdit.MarkListChange(Sender: TObject); +begin + InvalidateGutter; +end; + +procedure TCustomSynEdit.MarkModifiedLinesAsSaved; +begin + TSynEditStringList(FLines).MarkModifiedLinesAsSaved; + if FGutter.ShowModification then + InvalidateGutter; +end; + +function TCustomSynEdit.GetSelStart: Integer; +begin + if GetSelAvail then + Result := RowColToCharIndex(BlockBegin) + else + Result := RowColToCharIndex(CaretXY); +end; + +procedure TCustomSynEdit.SetAlwaysShowCaret(const Value: Boolean); +begin + if FAlwaysShowCaret <> Value then + begin + FAlwaysShowCaret := Value; + if not(csDestroying in ComponentState) and not(focused) then + begin + if Value then + begin + InitializeCaret; + end + else + begin + HideCaret; + Windows.DestroyCaret; + end; + end; + end; +end; + +procedure TCustomSynEdit.SetSelStart(const Value: Integer); +begin + { if we don't call HandleNeeded, CharsInWindow may be 0 and LeftChar will + be set to CaretX } + HandleNeeded; + InternalCaretXY := CharIndexToRowCol(Value); + BlockBegin := CaretXY; +end; + +function TCustomSynEdit.GetSelEnd: Integer; +begin + if GetSelAvail then + Result := RowColToCharIndex(Blockend) + else + Result := RowColToCharIndex(CaretXY); +end; + +procedure TCustomSynEdit.SetSelEnd(const Value: Integer); +begin + HandleNeeded; + BlockEnd := CharIndexToRowCol( Value ); +end; + +procedure TCustomSynEdit.SetSelWord; +begin + SetWordBlock(CaretXY); +end; + +procedure TCustomSynEdit.SetExtraLineSpacing(const Value: Integer); +begin + FExtraLineSpacing := Value; + SynFontChanged(self); +end; + +function TCustomSynEdit.GetBookMark(BookMark: Integer; var X, Y: Integer): + Boolean; +var + i: Integer; +begin + Result := False; + if assigned(Marks) then + for i := 0 to Marks.Count - 1 do + if Marks[i].IsBookmark and (Marks[i].BookmarkNumber = BookMark) then + begin + X := Marks[i].Char; + Y := Marks[i].Line; + Result := True; + Exit; + end; +end; + +function TCustomSynEdit.IsBookmark(BookMark: Integer): Boolean; +var + x, y: Integer; +begin + Result := GetBookMark(BookMark, x, y); +end; + +procedure TCustomSynEdit.ClearUndo; +begin + FUndoList.Clear; + FRedoList.Clear; +end; + +procedure TCustomSynEdit.SetSelTextExternal(const Value: UnicodeString); +var + StartOfBlock, EndOfBlock: TBufferCoord; +begin + BeginUndoBlock; + try + if SelAvail then + begin + FUndoList.AddChange(crDelete, FBlockBegin, FBlockEnd, + SelText, FActiveSelectionMode); + end + else + ActiveSelectionMode := SelectionMode; + StartOfBlock := BlockBegin; + EndOfBlock := BlockEnd; + FBlockBegin := StartOfBlock; + FBlockEnd := EndOfBlock; + SetSelTextPrimitive(Value); + if (Value <> '') and (FActiveSelectionMode <> smColumn) then + FUndoList.AddChange(crInsert, StartOfBlock, BlockEnd, '', FActiveSelectionMode); + finally + EndUndoBlock; + end; +end; + +procedure TCustomSynEdit.SetGutter(const Value: TSynGutter); +begin + FGutter.Assign(Value); +end; + +procedure TCustomSynEdit.GutterChanged(Sender: TObject); +var + nW: Integer; +begin + if not (csLoading in ComponentState) then + begin + if FGutter.ShowLineNumbers and FGutter.AutoSize then + FGutter.AutoSizeDigitCount(Lines.Count); + if FGutter.UseFontStyle then + begin + FTextDrawer.SetBaseFont(FGutter.Font); + nW := FGutter.RealGutterWidth(FTextDrawer.CharWidth); + FTextDrawer.SetBaseFont(Font); + end + else + nW := FGutter.RealGutterWidth(FCharWidth); + if nW = FGutterWidth then + InvalidateGutter + else + SetGutterWidth(nW); + end; +end; + +procedure TCustomSynEdit.LockUndo; +begin + FUndoList.Lock; + FRedoList.Lock; +end; + +procedure TCustomSynEdit.UnlockUndo; +begin + FUndoList.Unlock; + FRedoList.Unlock; +end; + +function TCustomSynEdit.UnifiedSelection: TBufferBlock; +begin + if BlockBegin.Line > BlockEnd.Line then begin + Result.BeginLine := BlockEnd.Line; + Result.EndLine := BlockBegin.Line; + end else begin + Result.BeginLine := BlockBegin.Line; + Result.EndLine := BlockEnd.Line; + end; + if BlockBegin.Char > BlockEnd.Char then begin + Result.BeginChar := BlockEnd.Char; + Result.EndChar := BlockBegin.Char; + end else begin + Result.BeginChar := BlockBegin.Char; + Result.EndChar := BlockEnd.Char; + end; +end; + + +{$IFNDEF SYN_COMPILER_6_UP} +procedure TCustomSynEdit.WMMouseWheel(var Msg: TMessage); +var + nDelta: Integer; + nWheelClicks: Integer; +{$IFNDEF SYN_COMPILER_4_UP} +const + LinesToScroll = 3; + WHEEL_DELTA = 120; + WHEEL_PAGESCROLL = MAXDWORD; + SPI_GETWHEELSCROLLLINES = 104; +{$ENDIF} +begin + if csDesigning in ComponentState then + Exit; + + Msg.Result := 1; + +{$IFDEF SYN_COMPILER_4_UP} + // In some occasions Windows will not properly initialize mouse wheel, but + // will still keep sending WM_MOUSEWHEEL message. Calling inherited procedure + // will re-initialize related properties (i.e. Mouse.WheelScrollLines) + inherited; +{$ENDIF} + + if GetKeyState(VK_CONTROL) >= 0 then + begin +{$IFDEF SYN_COMPILER_4_UP} + nDelta := Mouse.WheelScrollLines +{$ELSE} + if not SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, @nDelta, 0) then + nDelta := LinesToScroll; +{$ENDIF} + end + else + nDelta := LinesInWindow shr Ord(eoHalfPageScroll in FOptions); + + Inc(FMouseWheelAccumulator, SmallInt(Msg.wParamHi)); + nWheelClicks := FMouseWheelAccumulator div WHEEL_DELTA; + FMouseWheelAccumulator := FMouseWheelAccumulator mod WHEEL_DELTA; + if (nDelta = Integer(WHEEL_PAGESCROLL)) or (nDelta > LinesInWindow) then + nDelta := LinesInWindow; + TopLine := TopLine - (nDelta * nWheelClicks); + Update; + if Assigned(OnScroll) then OnScroll(Self,sbVertical); +end; +{$ENDIF} + +procedure TCustomSynEdit.WMSetCursor(var Msg: TWMSetCursor); +begin + if (Msg.HitTest = HTCLIENT) and (Msg.CursorWnd = Handle) and + not(csDesigning in ComponentState) then + begin + UpdateMouseCursor; + end + else + inherited; +end; + +procedure TCustomSynEdit.SetTabWidth(Value: Integer); +begin + Value := MinMax(Value, 1, 256); + if (Value <> FTabWidth) then begin + FTabWidth := Value; + TSynEditStringList(Lines).TabWidth := Value; + Invalidate; // to redraw text containing tab chars + if WordWrap then + begin + FWordWrapPlugin.Reset; + InvalidateGutter; + end; + end; +end; + +procedure TCustomSynEdit.SelectedColorsChanged(Sender: TObject); +begin + InvalidateSelection; +end; + +// find / replace + +function TCustomSynEdit.SearchReplace(const ASearch, AReplace: UnicodeString; + AOptions: TSynSearchOptions): Integer; +var + ptStart, ptEnd: TBufferCoord; // start and end of the search range + ptCurrent: TBufferCoord; // current search position + nSearchLen, nReplaceLen, n, nFound: Integer; + nInLine: Integer; + bBackward, bFromCursor: Boolean; + bPrompt: Boolean; + bReplace, bReplaceAll: Boolean; + bEndUndoBlock: Boolean; + nAction: TSynReplaceAction; + iResultOffset: Integer; + + function InValidSearchRange(First, Last: Integer): Boolean; + begin + Result := True; + if (FActiveSelectionMode = smNormal) or not (ssoSelectedOnly in AOptions) then + begin + if ((ptCurrent.Line = ptStart.Line) and (First < ptStart.Char)) or + ((ptCurrent.Line = ptEnd.Line) and (Last > ptEnd.Char)) + then + Result := False; + end + else + if (FActiveSelectionMode = smColumn) then + // solves bug in search/replace when smColumn mode active and no selection + Result := (First >= ptStart.Char) and (Last <= ptEnd.Char) or (ptEnd.Char - ptStart.Char < 1); + end; + +begin + if not Assigned(FSearchEngine) then + raise ESynEditError.Create('No search engine has been assigned'); + + Result := 0; + // can't search for or replace an empty string + if Length(ASearch) = 0 then Exit; + // get the text range to search in, ignore the "Search in selection only" + // option if nothing is selected + bBackward := (ssoBackwards in AOptions); + bPrompt := (ssoPrompt in AOptions); + bReplace := (ssoReplace in AOptions); + bReplaceAll := (ssoReplaceAll in AOptions); + bFromCursor := not (ssoEntireScope in AOptions); + if not SelAvail then Exclude(AOptions, ssoSelectedOnly); + if (ssoSelectedOnly in AOptions) then begin + ptStart := BlockBegin; + ptEnd := BlockEnd; + // search the whole line in the line selection mode + if (FActiveSelectionMode = smLine) then + begin + ptStart.Char := 1; + ptEnd.Char := Length(Lines[ptEnd.Line - 1]) + 1; + end + else if (FActiveSelectionMode = smColumn) then + // make sure the start column is smaller than the end column + if (ptStart.Char > ptEnd.Char) then + SwapInt(Integer(ptStart.Char), Integer(ptEnd.Char)); + // ignore the cursor position when searching in the selection + if bBackward then + ptCurrent := ptEnd + else + ptCurrent := ptStart; + end + else + begin + ptStart.Char := 1; + ptStart.Line := 1; + ptEnd.Line := Lines.Count; + ptEnd.Char := Length(Lines[ptEnd.Line - 1]) + 1; + if bFromCursor then + if bBackward then ptEnd := CaretXY else ptStart := CaretXY; + if bBackward then ptCurrent := ptEnd else ptCurrent := ptStart; + end; + // initialize the search engine + FSearchEngine.Options := AOptions; + FSearchEngine.Pattern := ASearch; + // search while the current search position is inside of the search range + nReplaceLen := 0; + DoOnPaintTransient(ttBefore); + if bReplaceAll and not bPrompt then + begin + IncPaintLock; + BeginUndoBlock; + bEndUndoBlock := True; + end + else + bEndUndoBlock := False; + Inc(FPaintTransientLock); + try + while (ptCurrent.Line >= ptStart.Line) and (ptCurrent.Line <= ptEnd.Line) do + begin + nInLine := FSearchEngine.FindAll(Lines[ptCurrent.Line - 1]); + iResultOffset := 0; + if bBackward then + n := Pred(FSearchEngine.ResultCount) + else + n := 0; + // Operate on all results in this line. + while nInLine > 0 do + begin + // An occurrence may have been replaced with a text of different length + nFound := FSearchEngine.Results[n] + iResultOffset; + nSearchLen := FSearchEngine.Lengths[n]; + if bBackward then Dec(n) else Inc(n); + Dec(nInLine); + // Is the search result entirely in the search range? + if not InValidSearchRange(nFound, nFound + nSearchLen) then continue; + Inc(Result); + // Select the text, so the user can see it in the OnReplaceText event + // handler or as the search result. + + ptCurrent.Char := nFound; + BlockBegin := ptCurrent; + // Be sure to use the Ex version of CursorPos so that it appears in the middle if necessary + SetCaretXYEx(False, BufferCoord(1, ptCurrent.Line)); + EnsureCursorPosVisibleEx(True); + Inc(ptCurrent.Char, nSearchLen); + BlockEnd := ptCurrent; + InternalCaretXY := ptCurrent; + if bBackward then InternalCaretXY := BlockBegin else InternalCaretXY := ptCurrent; + // If it's a search only we can leave the procedure now. + if not (bReplace or bReplaceAll) then Exit; + // Prompt and replace or replace all. If user chooses to replace + // all after prompting, turn off prompting. + if bPrompt and Assigned(FOnReplaceText) then + begin + nAction := DoOnReplaceText(ASearch, AReplace, ptCurrent.Line, nFound); + if nAction = raCancel then + Exit; + end + else + nAction := raReplace; + if nAction = raSkip then + Dec(Result) + else begin + // user has been prompted and has requested to silently replace all + // so turn off prompting + if nAction = raReplaceAll then begin + if not bReplaceAll or bPrompt then + begin + bReplaceAll := True; + IncPaintLock; + end; + bPrompt := False; + if bEndUndoBlock = False then + BeginUndoBlock; + bEndUndoBlock := true; + end; + // Allow advanced substition in the search engine + SelText := FSearchEngine.Replace(SelText, AReplace); + nReplaceLen := CaretX - nFound; + end; + // fix the caret position and the remaining results + if not bBackward then begin + InternalCaretX := nFound + nReplaceLen; + if (nSearchLen <> nReplaceLen) and (nAction <> raSkip) then + begin + Inc(iResultOffset, nReplaceLen - nSearchLen); + if (FActiveSelectionMode <> smColumn) and (CaretY = ptEnd.Line) then + begin + Inc(ptEnd.Char, nReplaceLen - nSearchLen); + BlockEnd := ptEnd; + end; + end; + end; + if not bReplaceAll then + Exit; + end; + // search next / previous line + if bBackward then + Dec(ptCurrent.Line) + else + Inc(ptCurrent.Line); + end; + finally + if bReplaceAll and not bPrompt then DecPaintLock; + if bEndUndoBlock then EndUndoBlock; + Dec(FPaintTransientLock); + DoOnPaintTransient( ttAfter ); + end; +end; + +function TCustomSynEdit.IsPointInSelection(const Value: TBufferCoord): Boolean; +var + ptBegin, ptEnd: TBufferCoord; +begin + ptBegin := BlockBegin; + ptEnd := BlockEnd; + if (Value.Line >= ptBegin.Line) and (Value.Line <= ptEnd.Line) and + ((ptBegin.Line <> ptEnd.Line) or (ptBegin.Char <> ptEnd.Char)) then + begin + if FActiveSelectionMode = smLine then + Result := True + else if (FActiveSelectionMode = smColumn) then + begin + if (ptBegin.Char > ptEnd.Char) then + Result := (Value.Char >= ptEnd.Char) and (Value.Char < ptBegin.Char) + else if (ptBegin.Char < ptEnd.Char) then + Result := (Value.Char >= ptBegin.Char) and (Value.Char < ptEnd.Char) + else + Result := False; + end + else + Result := ((Value.Line > ptBegin.Line) or (Value.Char >= ptBegin.Char)) and + ((Value.Line < ptEnd.Line) or (Value.Char < ptEnd.Char)); + end + else + Result := False; +end; + +procedure TCustomSynEdit.SetFocus; +begin + if (FFocusList.Count > 0) then + begin + if TWinControl (FFocusList.Last).CanFocus then + TWinControl (FFocusList.Last).SetFocus; + Exit; + end; + inherited; +end; + +procedure TCustomSynEdit.UpdateMouseCursor; + +var + ptCursor: TPoint; + ptLineCol: TBufferCoord; + iNewCursor: TCursor; +{$IFDEF SYN_CodeFolding} + ptRowCol: TDisplayCoord; + Rect: TRect; +{$ENDIF} +begin + GetCursorPos(ptCursor); + ptCursor := ScreenToClient(ptCursor); +{$IFDEF SYN_CodeFolding} + ptRowCol := PixelsToRowColumn(ptCursor.X, ptCursor.Y); + ptLineCol := DisplayToBufferPos(ptRowCol); + if (ptCursor.X < fGutterWidth) then begin + if UseCodeFolding and + fAllFoldRanges.FoldStartAtLine(ptLineCol.Line) then + begin + Rect := GetFoldShapeRect(ptRowCol.Row); + if PtInRect(Rect, ptCursor) then + SetCursor(Screen.Cursors[crHandPoint]) + else + SetCursor(Screen.Cursors[fGutter.Cursor]); + end else + SetCursor(Screen.Cursors[fGutter.Cursor]) + end else begin + if (eoDragDropEditing in fOptions) and (not MouseCapture) and IsPointInSelection(ptLineCol) then + iNewCursor := crArrow + else if UseCodeFolding and CodeFolding.ShowHintMark and + fAllFoldRanges.CollapsedFoldStartAtLine(ptLineCol.Line) then + begin + Rect := GetCollapseMarkRect(ptRowCol.Row, ptLineCol.Line); + if PtInRect(Rect, ptCursor) then + iNewCursor := crHandPoint; + end else +{$ELSE} + if (ptCursor.X < FGutterWidth) then + SetCursor(Screen.Cursors[FGutter.Cursor]) + else begin + ptLineCol := DisplayToBufferPos(PixelsToRowColumn(ptCursor.X, ptCursor.Y)); + if (eoDragDropEditing in FOptions) and (not MouseCapture) and not (sfMouseCaptured in FStateFlags) and IsPointInSelection(ptLineCol) then + iNewCursor := crArrow + else +{$ENDIF} + iNewCursor := Cursor; + if Assigned(OnMouseCursor) then + OnMouseCursor(Self, ptLineCol, iNewCursor); + FKbdHandler.ExecuteMouseCursor(Self, ptLineCol, iNewCursor); + SetCursor(Screen.Cursors[iNewCursor]); + end; +end; + +procedure TCustomSynEdit.BookMarkOptionsChanged(Sender: TObject); +begin + InvalidateGutter; +end; + +function TCustomSynEdit.GetOptions: TSynEditorOptions; +begin + Result := FOptions; +end; + +procedure TCustomSynEdit.SetOptions(Value: TSynEditorOptions); +const + ScrollOptions = [eoDisableScrollArrows,eoHideShowScrollbars, + eoScrollPastEof,eoScrollPastEol]; +var + bSetDrag: Boolean; + TmpBool: Boolean; + bUpdateScroll: Boolean; + vTempBlockBegin, vTempBlockEnd : TBufferCoord; +begin + if (Value <> FOptions) then + begin + bSetDrag := (eoDropFiles in FOptions) <> (eoDropFiles in Value); + + if not (eoScrollPastEol in Options) then + LeftChar := LeftChar; + if not (eoScrollPastEof in Options) then + TopLine := TopLine; + + bUpdateScroll := (Options * ScrollOptions) <> (Value * ScrollOptions); + + FOptions := Value; + + // constrain caret position to MaxScrollWidth if eoScrollPastEol is enabled + InternalCaretXY := CaretXY; + if (eoScrollPastEol in Options) then + begin + vTempBlockBegin := BlockBegin; + vTempBlockEnd := BlockEnd; + SetBlockBegin(vTempBlockBegin); + SetBlockEnd(vTempBlockEnd); + end; + + // (un)register HWND as drop target + if bSetDrag and not (csDesigning in ComponentState) and HandleAllocated then + DragAcceptFiles(Handle, (eoDropFiles in FOptions)); + + TmpBool := eoShowSpecialChars in Value; + if TmpBool <> FShowSpecChar then + begin + FShowSpecChar := TmpBool; + Invalidate; + end; + if bUpdateScroll then + UpdateScrollBars; + end; +end; + +procedure TCustomSynEdit.SizeOrFontChanged(bFont: Boolean); +begin + if HandleAllocated and (FCharWidth <> 0) then + begin + FCharsInWindow := Max(ClientWidth - FGutterWidth - 2, 0) div FCharWidth; + FLinesInWindow := ClientHeight div FTextHeight; + if WordWrap then + begin + FWordWrapPlugin.DisplayChanged; + Invalidate; + end; + if bFont then + begin + if Gutter.ShowLineNumbers then + GutterChanged(Self) + else + UpdateScrollbars; + InitializeCaret; + Exclude(FStateFlags, sfCaretChanged); + Invalidate; + end + else + UpdateScrollbars; + Exclude(FStateFlags, sfScrollbarChanged); + if not (eoScrollPastEol in Options) then + LeftChar := LeftChar; + if not (eoScrollPastEof in Options) then + TopLine := TopLine; + end; +end; + +procedure TCustomSynEdit.MoveCaretHorz(DX: Integer; SelectionCommand: Boolean); +var + ptO, ptDst: TBufferCoord; + s: UnicodeString; + nLineLen: Integer; + bChangeY: Boolean; + vCaretRowCol: TDisplayCoord; +begin + if WordWrap then + begin + if DX > 0 then + begin + if FCaretAtEOL then + begin + FCaretAtEOL := False; + UpdateLastCaretX; + IncPaintLock; + Include(FStateFlags, sfCaretChanged); + DecPaintLock; + Exit; + end; + end + else + begin // DX < 0. Handle ecLeft/ecPageLeft at BOL. + if (not FCaretAtEOL) and (CaretX > 1) and (DisplayX = 1) then + begin + FCaretAtEOL := True; + UpdateLastCaretX; + if DisplayX > CharsInWindow +1 then + SetInternalDisplayXY( DisplayCoord(CharsInWindow +1, DisplayY) ) + else begin + IncPaintLock; + Include(FStateFlags, sfCaretChanged); + DecPaintLock; + end; + Exit; + end; + end; + end; + ptO := CaretXY; + ptDst := ptO; + s := LineText; + nLineLen := Length(s); + // only moving or selecting one char can change the line + bChangeY := not (eoScrollPastEol in FOptions); + if bChangeY and (DX = -1) and (ptO.Char = 1) and (ptO.Line > 1) then + begin + // end of previous line + Dec(ptDst.Line); + ptDst.Char := Length(Lines[ptDst.Line - 1]) + 1; + end + else if bChangeY and (DX = 1) and (ptO.Char > nLineLen) and (ptO.Line < Lines.Count) then + begin + // start of next line + Inc(ptDst.Line); + ptDst.Char := 1; + end + else begin + ptDst.Char := Max(1, ptDst.Char + DX); + // don't go past last char when ScrollPastEol option not set + if (DX > 0) and bChangeY then + ptDst.Char := Min(ptDst.Char, nLineLen + 1); + end; + // set caret and block begin / end + MoveCaretAndSelection(FBlockBegin, ptDst, SelectionCommand); + // if caret is beyond CharsInWindow move to next row (this means there are + // spaces/tabs at the end of the row) + if WordWrap and (DX > 0) and (CaretX < Length(LineText)) then + begin + vCaretRowCol := DisplayXY; + if (vCaretRowCol.Column = 1) and (LineToRow(CaretY) <> vCaretRowCol.Row) then + begin + FCaretAtEOL := True; + UpdateLastCaretX; + end + else if vCaretRowCol.Column > CharsInWindow +1 then + begin + Inc(vCaretRowCol.Row); + vCaretRowCol.Column := 1; + InternalCaretXY := DisplayToBufferPos(vCaretRowCol); + end; + end; +end; + +procedure TCustomSynEdit.MoveCaretVert(DY: Integer; SelectionCommand: Boolean); +var + ptO, ptDst, vEOLTestPos: TDisplayCoord; + vDstLineChar: TBufferCoord; + SaveLastCaretX: Integer; +begin + ptO := DisplayXY; + ptDst := ptO; + + Inc(ptDst.Row, DY); + if DY >= 0 then + begin + if RowToLine(ptDst.Row) > Lines.Count then + ptDst.Row := Max(1, DisplayLineCount); + end + else begin + if ptDst.Row < 1 then + ptDst.Row := 1; + end; + + if (ptO.Row <> ptDst.Row) then + begin + if eoKeepCaretX in Options then + ptDst.Column := FLastCaretX; + end; + vDstLineChar := DisplayToBufferPos(ptDst); + SaveLastCaretX := FLastCaretX; + + // set caret and block begin / end + IncPaintLock; + MoveCaretAndSelection(FBlockBegin, vDstLineChar, SelectionCommand); + if WordWrap then + begin + vEOLTestPos := BufferToDisplayPos(vDstLineChar); + FCaretAtEOL := (vEOLTestPos.Column = 1) and (vEOLTestPos.Row <> ptDst.Row); + end; + DecPaintLock; + + // Restore FLastCaretX after moving caret, since UpdateLastCaretX, called by + // SetCaretXYEx, changes them. This is the one case where we don't want that. + FLastCaretX := SaveLastCaretX; +end; + +procedure TCustomSynEdit.MoveCaretAndSelection(const ptBefore, ptAfter: TBufferCoord; + SelectionCommand: Boolean); +begin + if (eoGroupUndo in FOptions) and UndoList.CanUndo then + FUndoList.AddGroupBreak; + + IncPaintLock; + if SelectionCommand then + begin + if not SelAvail then + SetBlockBegin(ptBefore); + SetBlockEnd(ptAfter); + end + else + SetBlockBegin(ptAfter); + InternalCaretXY := ptAfter; + DecPaintLock; +end; + +procedure TCustomSynEdit.SetCaretAndSelection(const ptCaret, ptBefore, + ptAfter: TBufferCoord); +var + vOldMode: TSynSelectionMode; +begin + vOldMode := FActiveSelectionMode; + IncPaintLock; + try + InternalCaretXY := ptCaret; + SetBlockBegin(ptBefore); + SetBlockEnd(ptAfter); + finally + ActiveSelectionMode := vOldMode; + DecPaintLock; + end; +end; + +procedure TCustomSynEdit.RecalcCharExtent; +const + iFontStyles: array[0..3] of TFontStyles = ([], [fsItalic], [fsBold], + [fsItalic, fsBold]); +var + iHasStyle: array[0..3] of Boolean; + cAttr: Integer; + cStyle: Integer; + iCurr: TFontStyles; + Done: Boolean; +begin + FillChar(iHasStyle, SizeOf(iHasStyle), 0); + if Assigned(FHighlighter) and (FHighlighter.AttrCount > 0) then + begin + for cAttr := 0 to FHighlighter.AttrCount - 1 do + begin + iCurr := FHighlighter.Attribute[cAttr].Style * [fsItalic, fsBold]; + for cStyle := 0 to 3 do + if iCurr = iFontStyles[cStyle] then + begin + iHasStyle[cStyle] := True; + Break; + end; + end; + end + else + begin + iCurr := Font.Style * [fsItalic, fsBold]; + for cStyle := 0 to 3 do + if iCurr = iFontStyles[cStyle] then + begin + iHasStyle[cStyle] := True; + Break; + end; + end; + + Done := False; + FTextHeight := 0; + FCharWidth := 0; + FTextDrawer.BaseFont := Self.Font; + + if not Done then + for cStyle := 0 to 3 do + if iHasStyle[cStyle] then + begin + FTextDrawer.BaseStyle := iFontStyles[cStyle]; + FTextHeight := Max(FTextHeight, FTextDrawer.CharHeight); + FCharWidth := Max(FCharWidth, FTextDrawer.CharWidth); + end; + Inc(FTextHeight, FExtraLineSpacing); +end; + +procedure TCustomSynEdit.HighlighterAttrChanged(Sender: TObject); +begin + RecalcCharExtent; + if Sender is TSynCustomHighlighter then + begin + Lines.BeginUpdate; + try + ScanRanges; + finally + Lines.EndUpdate; + end; + end + else + Invalidate; + SizeOrFontChanged(True); +end; + +procedure TCustomSynEdit.StatusChanged(AChanges: TSynStatusChanges); +begin + FStatusChanges := FStatusChanges + AChanges; + if PaintLock = 0 then + DoOnStatusChange(FStatusChanges); +end; + +procedure TCustomSynEdit.DoCaseChange(const Cmd: TSynEditorCommand); + + function ToggleCase(const aStr: UnicodeString): UnicodeString; + var + i: Integer; + sLower: UnicodeString; + begin + Result := SynWideUpperCase(aStr); + sLower := SynWideLowerCase(aStr); + for i := 1 to Length(aStr) do + begin + if Result[i] = aStr[i] then + Result[i] := sLower[i]; + end; + end; + + function TitleCase(const aStr: UnicodeString): UnicodeString; + var + i: Integer; + begin + Result := SynWideLowerCase(aStr); + for i := 1 to Length(Result) do + if (i = 1) or IsWordBreakChar(Result[i-1]) then Result[i] := SynWideUpperCase(Result[i])[1]; + end; + +var + w: UnicodeString; + oldCaret, oldBlockBegin, oldBlockEnd: TBufferCoord; + bHadSel : Boolean; +begin + Assert((Cmd >= ecUpperCase) and (Cmd <= ecTitleCaseBlock)); + if SelAvail then + begin + bHadSel := True; + oldBlockBegin := BlockBegin; + oldBlockEnd := BlockEnd; + end + else begin + bHadSel := False; + end; + oldCaret := CaretXY; + try + if Cmd < ecUpperCaseBlock then + begin + { Word commands } + SetSelWord; + if SelText = '' then + begin + { searches a previous Word } + InternalCaretXY := PrevWordPos; + SetSelWord; + if SelText = '' then + begin + { try once more since PrevWordPos may have failed last time. + (PrevWordPos "points" to the end of the previous line instead of the + beggining of the previous Word if invoked (e.g.) when CaretX = 1) } + InternalCaretXY := PrevWordPos; + SetSelWord; + end; + end; + end + else begin + { block commands } + if not SelAvail then + begin + if CaretX <= Length(LineText) then + MoveCaretHorz(1, True) + else if CaretY < Lines.Count then + InternalCaretXY := BufferCoord(1, CaretY +1); + end; + end; + + w := SelText; + if w <> '' then + begin + case Cmd of + ecUpperCase, ecUpperCaseBlock: + w := SynWideUpperCase(w); + ecLowerCase, ecLowerCaseBlock: + w := SynWideLowerCase(w); + ecToggleCase, ecToggleCaseBlock: + w := ToggleCase(w); + ecTitleCase, ecTitleCaseBlock: + w := TitleCase(w); + end; + BeginUndoBlock; + try + if bHadSel then + FUndoList.AddChange(crSelection, oldBlockBegin, oldBlockEnd, '', FActiveSelectionMode) + else + FUndoList.AddChange(crSelection, oldCaret, oldCaret, '', FActiveSelectionMode); + FUndoList.AddChange(crCaret, oldCaret, oldCaret, '', FActiveSelectionMode); + SelText := w; + finally + EndUndoBlock; + end; + end; + finally + { "word" commands do not restore Selection } + if bHadSel and (Cmd >= ecUpperCaseBlock) then + begin + BlockBegin := oldBlockBegin; + BlockEnd := oldBlockEnd; + end; + { "block" commands with empty Selection move the Caret } + if bHadSel or (Cmd < ecUpperCaseBlock) then + CaretXY := oldCaret; + end; +end; + +procedure TCustomSynEdit.DoTabKey; +var + StartOfBlock: TBufferCoord; + i, MinLen, iLine: Integer; + PrevLine, Spaces: UnicodeString; + p: PWideChar; + NewCaretX: Integer; + ChangeScroll: Boolean; + nPhysX, nDistanceToTab, nSpacesToNextTabStop : Integer; + OldSelTabLine, vIgnoreSmartTabs: Boolean; +begin + // Provide Visual Studio like block indenting + OldSelTabLine := SelTabLine; + if (eoTabIndent in Options) and ((SelTabBlock) or (OldSelTabLine)) then + begin + DoBlockIndent; + if OldSelTabLine then + begin + if FBlockBegin.Char < FBlockEnd.Char then + FBlockBegin.Char := 1 + else + FBlockEnd.Char := 1; + end; + Exit; + end; + i := 0; + iLine := 0; + MinLen := 0; + vIgnoreSmartTabs := False; + if eoSmartTabs in FOptions then + begin + iLine := CaretY - 1; + if (iLine > 0) and (iLine < Lines.Count) then + begin + Dec(iLine); + repeat + //todo: rethink it + MinLen := DisplayToBufferPos(DisplayCoord( + BufferToDisplayPos(CaretXY).Column, LineToRow(iLine + 1))).Char; + PrevLine := Lines[iLine]; + if (Length(PrevLine) >= MinLen) then begin + p := @PrevLine[MinLen]; + // scan over non-whitespaces + repeat + if (p^ = #9) or (p^ = #32) then + Break; + Inc(i); + Inc(p); + until p^ = #0; + // scan over whitespaces + if p^ <> #0 then + repeat + if (p^ <> #9) and (p^ <> #32) then Break; + Inc(i); + Inc(p); + until p^ = #0; + Break; + end; + Dec(iLine); + until iLine < 0; + end + else + vIgnoreSmartTabs := True; + end; + FUndoList.BeginBlock; + try + if SelAvail then + begin + FUndoList.AddChange(crDelete, FBlockBegin, FBlockEnd, SelText, + FActiveSelectionMode); + SetSelTextPrimitive(''); + end; + StartOfBlock := CaretXY; + + if i = 0 then + begin + if (eoTabsToSpaces in FOptions) then + begin + i := TabWidth - (StartOfBlock.Char - 1) mod TabWidth; + if i = 0 then + i := TabWidth; + end + else + i := TabWidth; + end; + + if eoTabsToSpaces in FOptions then + begin + Spaces := UnicodeStringOfChar(#32, i); + NewCaretX := StartOfBlock.Char + i; + end + else if (eoTrimTrailingSpaces in Options) and (StartOfBlock.Char > Length(LineText)) then + begin + // work-around for trimming Tabs + nPhysX := BufferToDisplayPos(CaretXY).Column; + if (eoSmartTabs in FOptions) and not vIgnoreSmartTabs and (iLine > -1) then + begin + i := BufferToDisplayPos( BufferCoord(MinLen+i, iLine+1) ).Column; + nDistanceToTab := i - nPhysX; + end + else + nDistanceToTab := TabWidth - ((nPhysX - 1) mod TabWidth); + NewCaretX := StartOfBlock.Char + nDistanceToTab; + end + else begin + if (eoSmartTabs in FOptions) and not vIgnoreSmartTabs and (iLine > -1) then + begin + Spaces := Copy(FLines[CaretXY.Line - 1], 1, CaretXY.Char - 1); + while Pos(#9, Spaces) > 0 do + Delete(Spaces, Pos(#9, Spaces), 1); + Spaces := WideTrim(Spaces); + + //smart tabs are only in the front of the line *NOT IN THE MIDDLE* + if Spaces = '' then + begin + i := BufferToDisplayPos( BufferCoord(MinLen+i, iLine+1) ).Column; + + nPhysX := DisplayX; + nDistanceToTab := i - nPhysX; + nSpacesToNextTabStop := TabWidth - ((nPhysX - 1) mod TabWidth); + if nSpacesToNextTabStop <= nDistanceToTab then begin + Spaces := #9; + Dec(nDistanceToTab, nSpacesToNextTabStop); + end; + while nDistanceToTab >= TabWidth do begin + Spaces := Spaces + #9; + Dec(nDistanceToTab, TabWidth); + end; + if nDistanceToTab > 0 then + Spaces := Spaces + UnicodeStringOfChar(#32, nDistanceToTab); + end else + Spaces := #9; + end + else begin + Spaces := #9; + end; + if (eoTrimTrailingSpaces in Options) and (Length(TrimTrailingSpaces(LineText)) = 0) then + NewCaretX := StartOfBlock.Char + GetExpandedLength(Spaces, TabWidth) + else + NewCaretX := StartOfBlock.Char + Length(Spaces); + end; + + SetSelTextPrimitive(Spaces); + // Undo is already handled in SetSelText when SelectionMode is Column + if FActiveSelectionMode <> smColumn then + begin + FUndoList.AddChange(crInsert, StartOfBlock, CaretXY, SelText, + FActiveSelectionMode); + end; + finally + FUndoList.EndBlock; + end; + + ChangeScroll := not(eoScrollPastEol in FOptions); + try + Include(FOptions, eoScrollPastEol); + InternalCaretX := NewCaretX; + finally + if ChangeScroll then + Exclude(FOptions, eoScrollPastEol); + end; + + EnsureCursorPosVisible; +end; + +procedure TCustomSynEdit.DoShiftTabKey; +// shift-tab key handling +var + NewX: Integer; + Line: UnicodeString; + LineLen: Integer; + DestX: Integer; + + MaxLen, iLine: Integer; + PrevLine, OldSelText: UnicodeString; + p: PWideChar; + OldCaretXY: TBufferCoord; + ChangeScroll: Boolean; +begin + // Provide Visual Studio like block indenting + if (eoTabIndent in Options) and ((SelTabBlock) or (SelTabLine)) then + begin + DoBlockUnIndent; + Exit; + end; + + NewX := CaretX; + + if (NewX <> 1) and (eoSmartTabs in FOptions) then + begin + iLine := CaretY - 1; + if (iLine > 0) and (iLine < Lines.Count) then + begin + Dec(iLine); + MaxLen := CaretX - 1; + repeat + PrevLine := Lines[iLine]; + if (Length(PrevLine) >= MaxLen) then + begin + p := @PrevLine[MaxLen]; + // scan over whitespaces + repeat + if p^ <> #32 then Break; + Dec(NewX); + Dec(p); + until NewX = 1; + // scan over non-whitespaces + if NewX <> 1 then + repeat + if p^ = #32 then Break; + Dec(NewX); + Dec(p); + until NewX = 1; + Break; + end; + Dec(iLine); + until iLine < 0; + end; + end; + + if NewX = CaretX then + begin + Line := LineText; + LineLen := Length(Line); + + // find real un-tab position + + DestX := ((CaretX - 2) div TabWidth) * TabWidth + 1; + if NewX > LineLen then + NewX := DestX + else if (NewX > DestX) and (Line[NewX - 1] = #9) then + Dec(NewX) + else begin + while (NewX > DestX) and ((NewX - 1 > LineLen) or (Line[NewX - 1] = #32)) do + Dec(NewX); + end; + end; + + // perform un-tab + if (NewX <> CaretX) then + begin + SetBlockBegin(BufferCoord(NewX, CaretY)); + SetBlockEnd(CaretXY); + OldCaretXY := CaretXY; + + OldSelText := SelText; + SetSelTextPrimitive(''); + + FUndoList.AddChange(crSilentDelete, BufferCoord(NewX, CaretY), + OldCaretXY, OldSelText, smNormal); + + // KV + ChangeScroll := not(eoScrollPastEol in FOptions); + try + Include(FOptions, eoScrollPastEol); + InternalCaretX := NewX; + finally + if ChangeScroll then + Exclude(FOptions, eoScrollPastEol); + end; + end; +end; + +procedure TCustomSynEdit.DoHomeKey(Selection: Boolean); + + function LastCharInRow: Integer; + var + vPos: TDisplayCoord; + begin + if FLines.Count = 0 then + Result := 1 + else + begin + vPos := DisplayXY; + vPos.Column := Min(CharsInWindow, FWordWrapPlugin.GetRowLength(vPos.Row) + 1); + Result := DisplayToBufferPos(vPos).Char; + end; + end; + +var + newX: Integer; + first_nonblank: Integer; + s: UnicodeString; + vNewPos: TDisplayCoord; + vMaxX: Integer; +begin + // home key enhancement + if (eoEnhanceHomeKey in FOptions) and (LineToRow(CaretY) = DisplayY) then + begin + s := FLines[CaretXY.Line - 1]; + + first_nonblank := 1; + if WordWrap then + vMaxX := LastCharInRow() -1 + else + vMaxX := Length(s); + while (first_nonblank <= vMaxX) and + CharInSet(s[first_nonblank], [#32, #9]) + do + Inc(first_nonblank); + Dec(first_nonblank); + + newX := CaretXY.Char - 1; + + if (newX > first_nonblank) or (newX = 0) then + newX := first_nonblank + 1 + else + newX := 1; + end + else + newX := 1; + + if WordWrap then + begin + vNewPos.Row := DisplayY; + vNewPos.Column := BufferToDisplayPos(BufferCoord(newX, CaretY)).Column; + MoveCaretAndSelection(CaretXY, DisplayToBufferPos(vNewPos), Selection); + end + else + MoveCaretAndSelection(CaretXY, BufferCoord(newX, CaretY), Selection); +end; + +procedure TCustomSynEdit.DoEndKey(Selection: Boolean); + + function CaretInLastRow: Boolean; + var + vLastRow: Integer; + begin + if not WordWrap then + Result := True + else + begin + vLastRow := LineToRow(CaretY + 1) - 1; + // This check allows good behaviour with empty rows (this can be useful in a diff app ;-) + while (vLastRow > 1) + and (FWordWrapPlugin.GetRowLength(vLastRow) = 0) + and (RowToLine(vLastRow) = CaretY) do + begin + Dec(vLastRow); + end; + Result := DisplayY = vLastRow; + end; + end; + + function FirstCharInRow: Integer; + var + vPos: TDisplayCoord; + begin + vPos.Row := DisplayY; + vPos.Column := 1; + Result := DisplayToBufferPos(vPos).Char; + end; + +var + vText: UnicodeString; + vLastNonBlank: Integer; + vNewX: Integer; + vNewCaret: TDisplayCoord; + vMinX: Integer; + vEnhance: Boolean; +begin + if (eoEnhanceEndKey in FOptions) and CaretInLastRow then + begin + vEnhance := True; + vText := LineText; + vLastNonBlank := Length(vText); + if WordWrap then + vMinX := FirstCharInRow() - 1 + else + vMinX := 0; + while (vLastNonBlank > vMinX) and CharInSet(vText[vLastNonBlank], [#32, #9]) do + Dec(vLastNonBlank); + + vNewX := CaretX - 1; + if vNewX = vLastNonBlank then + vNewX := Length(LineText) + 1 + else + vNewX := vLastNonBlank + 1; + end + else + begin + vNewX := Length(LineText) + 1; + vEnhance := False; + end; + + if WordWrap then + begin + vNewCaret.Row := DisplayY; + if vEnhance then + vNewCaret.Column := BufferToDisplayPos(BufferCoord(vNewX, CaretY)).Column + else + vNewCaret.Column := FWordWrapPlugin.GetRowLength(vNewCaret.Row) + 1; + vNewCaret.Column := Min(CharsInWindow + 1, vNewCaret.Column); + MoveCaretAndSelection(CaretXY, DisplayToBufferPos(vNewCaret), Selection); + // Updates FCaretAtEOL flag. + SetInternalDisplayXY(vNewCaret); + end + else + MoveCaretAndSelection(CaretXY, + BufferCoord(vNewX, CaretY), Selection); +end; + +procedure TCustomSynEdit.CreateWnd; +begin + inherited; + +{$IFNDEF UNICODE} + if not (csDesigning in ComponentState) then + begin + // "redefine" window-procedure to get Unicode messages + if Win32PlatformIsUnicode then + SetWindowLongW(Handle, GWL_WNDPROC, Integer(GetWindowLongA(Handle, GWL_WNDPROC))); + end; +{$ENDIF} + + if (eoDropFiles in FOptions) and not (csDesigning in ComponentState) then + DragAcceptFiles(Handle, True); + + UpdateScrollBars; +end; + +procedure TCustomSynEdit.DestroyWnd; +begin + if (eoDropFiles in FOptions) and not (csDesigning in ComponentState) then + DragAcceptFiles(Handle, False); + +{$IFNDEF UNICODE} + if not (csDesigning in ComponentState) then + begin + // restore window-procedure to what VCL expects + if Win32PlatformIsUnicode then + SetWindowLongA(Handle, GWL_WNDPROC, Integer(GetWindowLongW(Handle, GWL_WNDPROC))); + end; +{$ENDIF} + +{$IFDEF UNICODE} + // assign WindowText here, otherwise the VCL will call GetText twice + if WindowText = nil then + WindowText := Lines.GetText; +{$ENDIF} + inherited; +end; + +procedure TCustomSynEdit.InvalidateRect(const aRect: TRect; aErase: Boolean); +begin + Windows.InvalidateRect(Handle, @aRect, aErase); +end; + +procedure TCustomSynEdit.DoBlockIndent; +var + OrgCaretPos: TBufferCoord; + BB, BE: TBufferCoord; + Run, StrToInsert: PWideChar; + e, x, i, InsertStrLen: Integer; + Spaces: UnicodeString; + OrgSelectionMode: TSynSelectionMode; + InsertionPos: TBufferCoord; +begin + OrgSelectionMode := FActiveSelectionMode; + OrgCaretPos := CaretXY; + + StrToInsert := nil; + if SelAvail then + try + // keep current selection detail + BB := BlockBegin; + BE := BlockEnd; + + // build text to insert + if (BE.Char = 1) then + begin + e := BE.Line - 1; + x := 1; + end + else begin + e := BE.Line; + if eoTabsToSpaces in Options then + x := CaretX + FTabWidth + else x := CaretX + 1; + end; + if (eoTabsToSpaces in Options) then + begin + InsertStrLen := (FTabWidth + 2) * (e - BB.Line) + FTabWidth + 1; + // chars per line * lines-1 + last line + null char + StrToInsert := WStrAlloc(InsertStrLen); + Run := StrToInsert; + Spaces := UnicodeStringOfChar(#32, FTabWidth); + end + else begin + InsertStrLen := 3 * (e - BB.Line) + 2; + // #9#13#10 * lines-1 + (last line's #9 + null char) + StrToInsert := WStrAlloc(InsertStrLen); + Run := StrToInsert; + Spaces := #9; + end; + for i := BB.Line to e-1 do + begin + WStrCopy(Run, PWideChar(Spaces + #13#10)); + Inc(Run, Length(spaces) + 2); + end; + WStrCopy(Run, PWideChar(Spaces)); + + FUndoList.BeginBlock; + try + InsertionPos.Line := BB.Line; + if FActiveSelectionMode = smColumn then + InsertionPos.Char := Min(BB.Char, BE.Char) + else + InsertionPos.Char := 1; + InsertBlock(InsertionPos, InsertionPos, StrToInsert, True); + FUndoList.AddChange(crIndent, BB, BE, '', smColumn); + //We need to save the position of the end block for redo + FUndoList.AddChange(crIndent, + BufferCoord(BB.Char + length(Spaces), BB.Line), + BufferCoord(BE.Char + length(Spaces), BE.Line), + '', smColumn); + finally + FUndoList.EndBlock; + end; + + //adjust the x position of orgcaretpos appropriately + OrgCaretPos.Char := X; + finally + if BE.Char > 1 then + Inc(BE.Char, Length(Spaces)); + WStrDispose(StrToInsert); + SetCaretAndSelection(OrgCaretPos, + BufferCoord(BB.Char + Length(Spaces), BB.Line), BE); + ActiveSelectionMode := OrgSelectionMode; + end; +end; + +procedure TCustomSynEdit.DoBlockUnindent; +var + OrgCaretPos, + BB, BE: TBufferCoord; + Line, Run, + FullStrToDelete, + StrToDelete: PWideChar; + Len, x, StrToDeleteLen, i, TmpDelLen, FirstIndent, LastIndent, e: Integer; + TempString: UnicodeString; + OrgSelectionMode: TSynSelectionMode; + SomethingToDelete: Boolean; + + function GetDelLen: Integer; + var + Run: PWideChar; + begin + Result := 0; + Run := Line; + //Take care of tab character + if Run[0] = #9 then + begin + Result := 1; + SomethingToDelete := True; + Exit; + end; + //Deal with compound tabwidths Sometimes they have TabChars after a few + //spaces, yet we need to delete the whole tab width even though the char + //count might not be FTabWidth because of the TabChar + while (Run[0] = #32) and (Result < FTabWidth) do + begin + Inc(Result); + Inc(Run); + SomethingToDelete := True; + end; + if (Run[0] = #9) and (Result < FTabWidth) then + Inc(Result); + end; + +begin + OrgSelectionMode := FActiveSelectionMode; + Len := 0; + LastIndent := 0; + if SelAvail then + begin + // store current selection detail + BB := BlockBegin; + BE := BlockEnd; + OrgCaretPos := CaretXY; + x := FCaretX; + + // convert selection to complete lines + if BE.Char = 1 then + e := BE.Line - 1 + else + e := BE.Line; + + // build string to delete + StrToDeleteLen := (FTabWidth + 2) * (e - BB.Line) + FTabWidth + 1; + // chars per line * lines-1 + last line + null char + StrToDelete := WStrAlloc(StrToDeleteLen); + StrToDelete[0] := #0; + SomethingToDelete := False; + for i := BB.Line to e-1 do + begin + Line := PWideChar(Lines[i - 1]); + //'Line' is 0-based, 'BB.x' is 1-based, so the '-1' + //And must not increment 'Line' pointer by more than its 'Length' + if FActiveSelectionMode = smColumn then + Inc(Line, MinIntValue([BB.Char - 1, BE.Char - 1, Length(Lines[i - 1])])); + //Instead of doing a UnicodeStringOfChar, we need to get *exactly* what was + //being deleted incase there is a TabChar + TmpDelLen := GetDelLen; + WStrCat(StrToDelete, PWideChar(Copy(Line, 1, TmpDelLen))); + WStrCat(StrToDelete, PWideChar(UnicodeString(#13#10))); + if (FCaretY = i) and (x <> 1) then + x := x - TmpDelLen; + end; + Line := PWideChar(Lines[e - 1]); + if FActiveSelectionMode = smColumn then + Inc(Line, MinIntValue([BB.Char - 1, BE.Char - 1, Length(Lines[e - 1])])); + TmpDelLen := GetDelLen; + WStrCat(StrToDelete, PWideChar(Copy(Line, 1, TmpDelLen))); + if (FCaretY = e) and (x <> 1) then + x := x - TmpDelLen; + + FirstIndent := -1; + FullStrToDelete := nil; + // Delete string + if SomethingToDelete then + begin + FullStrToDelete := StrToDelete; + InternalCaretY := BB.Line; + if FActiveSelectionMode <> smColumn then + i := 1 + else + i := Min(BB.Char, BE.Char); + repeat + Run := GetEOL(StrToDelete); + if Run <> StrToDelete then + begin + Len := Run - StrToDelete; + if FirstIndent = -1 then + FirstIndent := Len; + if Len > 0 then + begin + TempString := Lines[CaretY - 1]; + Delete(TempString, i, Len); + Lines[CaretY - 1] := TempString; + end; + end; + if Run^ = #13 then + begin + Inc(Run); + if Run^ = #10 then + Inc(Run); + Inc(FCaretY); + end; + StrToDelete := Run; + until Run^ = #0; + LastIndent := Len; + FUndoList.AddChange(crUnindent, BB, BE, FullStrToDelete, FActiveSelectionMode); + end; + // restore selection + if FirstIndent = -1 then + FirstIndent := 0; + //adjust the x position of orgcaretpos appropriately + if FActiveSelectionMode = smColumn then + SetCaretAndSelection(OrgCaretPos, BB, BE) + else + begin + OrgCaretPos.Char := X; + Dec(BB.Char, FirstIndent); + Dec(BE.Char, LastIndent); + SetCaretAndSelection(OrgCaretPos, BB, BE); + end; + ActiveSelectionMode := OrgSelectionMode; + if FullStrToDelete <> nil then + WStrDispose(FullStrToDelete) + else + WStrDispose(StrToDelete); + end; +end; + +{$IFDEF SYN_COMPILER_4_UP} +function TCustomSynEdit.ExecuteAction(Action: TBasicAction): Boolean; +begin + if Action is TEditAction then + begin + Result := Focused; + if Result then + begin + if Action is TEditCut then + CommandProcessor(ecCut, ' ', nil) + else if Action is TEditCopy then + CommandProcessor(ecCopy, ' ', nil) + else if Action is TEditPaste then + CommandProcessor(ecPaste, ' ', nil) +{$IFDEF SYN_COMPILER_5_UP} + else if Action is TEditDelete then + begin + if SelAvail then + ClearSelection + else + CommandProcessor(ecDeleteChar, ' ', nil) + end + else if Action is TEditUndo then + CommandProcessor(ecUndo, ' ', nil) + else if Action is TEditSelectAll then + CommandProcessor(ecSelectAll, ' ', nil); +{$ENDIF} + end + end +{$IFDEF SYN_COMPILER_6_UP} + else if Action is TSearchAction then + begin + Result := Focused; + if Action is TSearchFindFirst then + DoSearchFindFirstExecute(TSearchFindFirst(Action)) + else if Action is TSearchFind then + DoSearchFindExecute(TSearchFind(Action)) + else if Action is TSearchReplace then + DoSearchReplaceExecute(TSearchReplace(Action)); + end + else if Action is TSearchFindNext then + begin + Result := Focused; + DoSearchFindNextExecute(TSearchFindNext(Action)) + end +{$ENDIF} + else + Result := inherited ExecuteAction(Action); +end; + +function TCustomSynEdit.UpdateAction(Action: TBasicAction): Boolean; +begin + if Action is TEditAction then + begin + Result := Focused; + if Result then + begin + if Action is TEditCut then + TEditAction(Action).Enabled := SelAvail and not ReadOnly + else if Action is TEditCopy then + TEditAction(Action).Enabled := SelAvail + else if Action is TEditPaste then + TEditAction(Action).Enabled := CanPaste +{$IFDEF SYN_COMPILER_5_UP} + else if Action is TEditDelete then + TEditAction(Action).Enabled := not ReadOnly + else if Action is TEditUndo then + TEditAction(Action).Enabled := CanUndo + else if Action is TEditSelectAll then + TEditAction(Action).Enabled := True; +{$ENDIF} + end; +{$IFDEF SYN_COMPILER_6_UP} + end else if Action is TSearchAction then + begin + Result := Focused; + if Result then + begin + if Action is TSearchFindFirst then + TSearchAction(Action).Enabled := (Text<>'') and assigned(FSearchEngine) + else if Action is TSearchFind then + TSearchAction(Action).Enabled := (Text<>'') and assigned(FSearchEngine) + else if Action is TSearchReplace then + TSearchAction(Action).Enabled := (Text<>'') and assigned(FSearchEngine); + end; + end else if Action is TSearchFindNext then + begin + Result := Focused; + if Result then + TSearchAction(Action).Enabled := (Text<>'') + and (TSearchFindNext(Action).SearchFind <> nil) + and (TSearchFindNext(Action).SearchFind.Dialog.FindText <> ''); +{$ENDIF} + end + else + Result := inherited UpdateAction(Action); +end; +{$ENDIF} + +procedure TCustomSynEdit.SetModified(Value: Boolean); +begin + if Value <> FModified then begin + FModified := Value; + if (eoGroupUndo in Options) and (not Value) and UndoList.CanUndo then + UndoList.AddGroupBreak; + UndoList.InitialState := not Value; + StatusChanged([scModified]); + end; +end; + +function TCustomSynEdit.DoOnSpecialLineColors(Line: Integer; var Foreground, + Background: TColor): Boolean; +begin + Result := False; + if Assigned(FOnSpecialLineColors) then + FOnSpecialLineColors(Self, Line, Result, Foreground, Background); +end; + +procedure TCustomSynEdit.DoOnSpecialTokenAttributes(ALine, APos: Integer; const AToken: string; var FG, BG: TColor; + var AStyle: TFontStyles); +var + Special: Boolean; +begin + if Assigned(FOnSpecialTokenAttributes) then + begin + Special := False; + FOnSpecialTokenAttributes(Self, ALine, APos, AToken, Special, FG, BG, AStyle); + end; +end; + +procedure TCustomSynEdit.InvalidateLine(Line: Integer); +var + rcInval: TRect; +begin + if (not HandleAllocated) or (Line < 1) or (Line > Lines.Count) or (not Visible) then + Exit; + +{$IFDEF SYN_CodeFolding} + if UseCodeFolding or WordWrap then +{$ELSE} + if WordWrap then +{$ENDIF} + begin + InvalidateLines(Line, Line); + Exit; + end; + + if (Line >= TopLine) and (Line <= TopLine + LinesInWindow) then + begin + // invalidate text area of this line + rcInval := Rect(FGutterWidth, FTextHeight * (Line - TopLine), ClientWidth, 0); + rcInval.Bottom := rcInval.Top + FTextHeight; + if sfLinesChanging in FStateFlags then + UnionRect(fInvalidateRect, rcInval, fInvalidateRect) + else + InvalidateRect(rcInval, False); + end; +end; + +function TCustomSynEdit.GetReadOnly: Boolean; +begin + Result := FReadOnly; +end; + +procedure TCustomSynEdit.SetReadOnly(Value: Boolean); +begin + if FReadOnly <> Value then + begin + FReadOnly := Value; + StatusChanged([scReadOnly]); + end; +end; + +procedure TCustomSynEdit.FindMatchingBracket; +begin + InternalCaretXY := GetMatchingBracket; +end; + +procedure TCustomSynEdit.FontSmoothingChanged; +const + NONANTIALIASED_QUALITY = 3; + ANTIALIASED_QUALITY = 4; + CLEARTYPE_QUALITY = 5; +var + bMethod: Byte; + lf: TLogFont; +begin + case FFontSmoothing of + fsmAntiAlias: + bMethod := ANTIALIASED_QUALITY; + fsmClearType: + bMethod := CLEARTYPE_QUALITY; + else // fsmNone also + bMethod := NONANTIALIASED_QUALITY; + end; + GetObject(Font.Handle, SizeOf(TLogFont), @lf); + lf.lfQuality := bMethod; + Font.Handle := CreateFontIndirect(lf); +end; + +function TCustomSynEdit.GetMatchingBracket: TBufferCoord; +begin + Result := GetMatchingBracketEx(CaretXY); +end; + +function TCustomSynEdit.GetMatchingBracketEx(const APoint: TBufferCoord): TBufferCoord; +const + Brackets: array[0..7] of WideChar = ('(', ')', '[', ']', '{', '}', '<', '>'); +var + Line: UnicodeString; + i, PosX, PosY, Len: Integer; + Test, BracketInc, BracketDec: WideChar; + NumBrackets: Integer; + vDummy: UnicodeString; + attr: TSynHighlighterAttributes; + p: TBufferCoord; + isCommentOrString: Boolean; +begin + Result.Char := 0; + Result.Line := 0; + // get char at caret + PosX := APoint.Char; + PosY := APoint.Line; + Line := Lines[APoint.Line - 1]; + if Length(Line) >= PosX then + begin + Test := Line[PosX]; + // is it one of the recognized brackets? + for i := Low(Brackets) to High(Brackets) do + if Test = Brackets[i] then + begin + // this is the bracket, get the matching one and the direction + BracketInc := Brackets[i]; + BracketDec := Brackets[i xor 1]; // 0 -> 1, 1 -> 0, ... + // search for the matching bracket (that is until NumBrackets = 0) + NumBrackets := 1; + if Odd(i) then + begin + repeat + // search until start of line + while PosX > 1 do + begin + Dec(PosX); + Test := Line[PosX]; + p.Char := PosX; + p.Line := PosY; + if (Test = BracketInc) or (Test = BracketDec) then + begin + if GetHighlighterAttriAtRowCol(p, vDummy, attr) then + isCommentOrString := (attr = Highlighter.StringAttribute) or + (attr = Highlighter.CommentAttribute) + else + isCommentOrString := False; + if (Test = BracketInc) and (not isCommentOrString) then + Inc(NumBrackets) + else if (Test = BracketDec) and (not isCommentOrString) then + begin + Dec(NumBrackets); + if NumBrackets = 0 then + begin + // matching bracket found, set caret and bail out + Result := P; + Exit; + end; + end; + end; + end; + // get previous line if possible + if PosY = 1 then Break; + Dec(PosY); + Line := Lines[PosY - 1]; + PosX := Length(Line) + 1; + until False; + end + else begin + repeat + // search until end of line + Len := Length(Line); + while PosX < Len do + begin + Inc(PosX); + Test := Line[PosX]; + p.Char := PosX; + p.Line := PosY; + if (Test = BracketInc) or (Test = BracketDec) then + begin + if GetHighlighterAttriAtRowCol(p, vDummy, attr) then + isCommentOrString := (attr = Highlighter.StringAttribute) or + (attr = Highlighter.CommentAttribute) + else + isCommentOrString := False; + if (Test = BracketInc) and (not isCommentOrString) then + Inc(NumBrackets) + else if (Test = BracketDec)and (not isCommentOrString) then + begin + Dec(NumBrackets); + if NumBrackets = 0 then + begin + // matching bracket found, set caret and bail out + Result := P; + Exit; + end; + end; + end; + end; + // get next line if possible + if PosY = Lines.Count then + Break; + Inc(PosY); + Line := Lines[PosY - 1]; + PosX := 0; + until False; + end; + // don't test the other brackets, we're done + Break; + end; + end; +end; + +function TCustomSynEdit.GetHighlighterAttriAtRowCol(const XY: TBufferCoord; + var Token: UnicodeString; var Attri: TSynHighlighterAttributes): Boolean; +var + TmpType, TmpStart: Integer; +begin + Result := GetHighlighterAttriAtRowColEx(XY, Token, TmpType, TmpStart, Attri); +end; + +function TCustomSynEdit.GetHighlighterAttriAtRowColEx(const XY: TBufferCoord; + var Token: UnicodeString; var TokenType, Start: Integer; + var Attri: TSynHighlighterAttributes): Boolean; +var + PosX, PosY: Integer; + Line: UnicodeString; +begin + PosY := XY.Line - 1; + if Assigned(Highlighter) and (PosY >= 0) and (PosY < Lines.Count) then + begin + Line := Lines[PosY]; + if PosY = 0 then + Highlighter.ResetRange + else + Highlighter.SetRange(TSynEditStringList(Lines).Ranges[PosY - 1]); + Highlighter.SetLine(Line, PosY); + PosX := XY.Char; + if (PosX > 0) and (PosX <= Length(Line)) then + while not Highlighter.GetEol do + begin + Start := Highlighter.GetTokenPos + 1; + Token := Highlighter.GetToken; + if (PosX >= Start) and (PosX < Start + Length(Token)) then + begin + Attri := Highlighter.GetTokenAttribute; + TokenType := Highlighter.GetTokenKind; + Result := True; + Exit; + end; + Highlighter.Next; + end; + end; + Token := ''; + Attri := nil; + Result := False; +end; + +function TCustomSynEdit.FindHookedCmdEvent(AHandlerProc: THookedCommandEvent): Integer; +var + Entry: THookedCommandHandlerEntry; +begin + Result := GetHookedCommandHandlersCount - 1; + while Result >= 0 do + begin + Entry := THookedCommandHandlerEntry(FHookedCommandHandlers[Result]); + if Entry.Equals(AHandlerProc) then + Break; + Dec(Result); + end; +end; + +function TCustomSynEdit.GetHookedCommandHandlersCount: Integer; +begin + if Assigned(FHookedCommandHandlers) then + Result := FHookedCommandHandlers.Count + else + Result := 0; +end; + +procedure TCustomSynEdit.RegisterCommandHandler( + const AHandlerProc: THookedCommandEvent; AHandlerData: Pointer); +begin + if not Assigned(AHandlerProc) then + begin +{$IFDEF SYN_DEVELOPMENT_CHECKS} + raise Exception.Create('Event handler is NIL in RegisterCommandHandler'); +{$ENDIF} + Exit; + end; + if not Assigned(FHookedCommandHandlers) then + FHookedCommandHandlers := TObjectList.Create; + if FindHookedCmdEvent(AHandlerProc) = -1 then + FHookedCommandHandlers.Add(THookedCommandHandlerEntry.Create( + AHandlerProc, AHandlerData)) + else +{$IFDEF SYN_DEVELOPMENT_CHECKS} + raise Exception.CreateFmt('Event handler (%p, %p) already registered', + [TMethod(AHandlerProc).Data, TMethod(AHandlerProc).Code]); +{$ENDIF} +end; + +procedure TCustomSynEdit.UnregisterCommandHandler(AHandlerProc: + THookedCommandEvent); +var + i: Integer; +begin + if not Assigned(AHandlerProc) then + begin +{$IFDEF SYN_DEVELOPMENT_CHECKS} + raise Exception.Create('Event handler is NIL in UnregisterCommandHandler'); +{$ENDIF} + Exit; + end; + i := FindHookedCmdEvent(AHandlerProc); + if i > -1 then + FHookedCommandHandlers.Delete(i) + else +{$IFDEF SYN_DEVELOPMENT_CHECKS} + raise Exception.CreateFmt('Event handler (%p, %p) is not registered', + [TMethod(AHandlerProc).Data, TMethod(AHandlerProc).Code]); +{$ENDIF} +end; + +procedure TCustomSynEdit.NotifyHookedCommandHandlers(AfterProcessing: Boolean; + var Command: TSynEditorCommand; var AChar: WideChar; Data: Pointer); +var + Handled: Boolean; + i: Integer; + Entry: THookedCommandHandlerEntry; +begin + Handled := False; + for i := 0 to GetHookedCommandHandlersCount - 1 do + begin + Entry := THookedCommandHandlerEntry(FHookedCommandHandlers[i]); + // NOTE: Command should NOT be set to ecNone, because this might interfere + // with other handlers. Set Handled to False instead (and check its value + // to not process the command twice). + Entry.FEvent(Self, AfterProcessing, Handled, Command, AChar, Data, + Entry.FData); + end; + if Handled then + Command := ecNone; +end; + +procedure TCustomSynEdit.DoOnClearBookmark(var Mark: TSynEditMark); +begin + if Assigned(FOnClearMark) then + FOnClearMark(Self, Mark); +end; + +procedure TCustomSynEdit.DoOnPaintTransientEx(TransientType: TTransientType; Lock: Boolean); +var + DoTransient: Boolean; + i: Integer; +begin + DoTransient :=(FPaintTransientLock=0); + if Lock then + begin + if (TransientType=ttBefore) then Inc(FPaintTransientLock) + else + begin + Dec(FPaintTransientLock); + DoTransient :=(FPaintTransientLock=0); + end; + end; + + if DoTransient then + begin + // plugins + if FPlugins <> nil then + for i := 0 to FPlugins.Count - 1 do + TSynEditPlugin(FPlugins[i]).PaintTransient(Canvas, TransientType); + // event + if Assigned(FOnPaintTransient) then + begin + Canvas.Font.Assign(Font); + Canvas.Brush.Color := Color; + HideCaret; + try + FOnPaintTransient(Self, Canvas, TransientType); + finally + ShowCaret; + end; + end; + end; +end; + +procedure TCustomSynEdit.DoOnPaintTransient(TransientType: TTransientType); +begin + DoOnPaintTransientEx(TransientType, False); +end; + +procedure TCustomSynEdit.DoOnPaint; +begin + if Assigned(FOnPaint) then + begin + Canvas.Font.Assign(Font); + Canvas.Brush.Color := Color; + FOnPaint(Self, Canvas); + end; +end; + +procedure TCustomSynEdit.DoOnPlaceMark(var Mark: TSynEditMark); +begin + if Assigned(FOnPlaceMark) then + FOnPlaceMark(Self, Mark); +end; + +function TCustomSynEdit.DoOnReplaceText(const ASearch, AReplace: UnicodeString; + Line, Column: Integer): TSynReplaceAction; +begin + Result := raCancel; + if Assigned(FOnReplaceText) then + FOnReplaceText(Self, ASearch, AReplace, Line, Column, Result); +end; + +procedure TCustomSynEdit.DoOnStatusChange(Changes: TSynStatusChanges); +begin + if Assigned(FOnStatusChange) then + begin + FOnStatusChange(Self, FStatusChanges); + FStatusChanges := []; + end; +end; + +procedure TCustomSynEdit.UpdateModifiedStatus; +begin + Modified := not UndoList.InitialState; +end; + +procedure TCustomSynEdit.UndoRedoAdded(Sender: TObject); +begin + UpdateModifiedStatus; + + // we have to clear the redo information, since adding undo info removes + // the necessary context to undo earlier edit actions + if (Sender = FUndoList) and not FUndoList.InsideRedo and + (FUndoList.PeekItem<>nil) and (FUndoList.PeekItem.ChangeReason<>crGroupBreak) then + FRedoList.Clear; + if TSynEditUndoList(Sender).BlockCount = 0 then + DoChange; +end; + +function TCustomSynEdit.GetWordAtRowCol(XY: TBufferCoord): UnicodeString; + +// TODO: consider removing the use of Low/High(string) since this code is anyway not zero-based strings ready +{$IFNDEF SYN_COMPILER_17_UP} + function Low(AStr: UnicodeString): Integer; {$IFDEF SYN_COMPILER_9_UP}inline;{$ENDIF} + begin + Result := 1; + end; + + function High(AStr: UnicodeString): Integer; {$IFDEF SYN_COMPILER_9_UP}inline;{$ENDIF} + begin + Result := Length(AStr); + end; +{$ENDIF} + +var + Line: UnicodeString; + Start, Stop: Integer; +begin + Result := ''; + if (XY.Line >= 1) and (XY.Line <= Lines.Count) then + begin + Line := Lines[XY.Line - 1]; + if (Length(Line) > 0) and + ((XY.Char >= Low(Line)) and (XY.Char <= High(Line))) and + IsIdentChar(Line[XY.Char]) then + begin + Start := XY.Char; + while (Start > Low(Line)) and IsIdentChar(Line[Start - 1]) do + Dec(Start); + + Stop := XY.Char + 1; + while (Stop <= High(Line)) and IsIdentChar(Line[Stop]) do + Inc(Stop); + + Result := Copy(Line, Start, Stop - Start); + end; + end; +end; + +function TCustomSynEdit.BufferToDisplayPos(const p: TBufferCoord): TDisplayCoord; +// BufferToDisplayPos takes a position in the text and transforms it into +// the row and column it appears to be on the screen +var + s: UnicodeString; + i, L: Integer; + x, CountOfAvgGlyphs: Integer; +begin + Canvas.Font := Font; + + Result := TDisplayCoord(p); + if p.Line - 1 < Lines.Count then + begin + s := Lines[p.Line - 1]; + l := Length(s); + x := 0; + + for i := 1 to p.Char - 1 do begin + if (i <= l) and (s[i] = #9) then + Inc(x, TabWidth - (x mod TabWidth)) + else if i <= l then + begin + CountOfAvgGlyphs := CeilOfIntDiv(FTextDrawer.TextWidth(s[i]), FCharWidth); + Inc(x, CountOfAvgGlyphs); + end + else + Inc(x); + end; + Result.Column := x + 1; + end; + if WordWrap then + Result := FWordWrapPlugin.BufferToDisplayPos(TBufferCoord(Result)); +{$IFDEF SYN_CodeFolding} + if UseCodeFolding then + Result.Row := fAllFoldRanges.FoldLineToRow(Result.Row) +{$ENDIF} +end; + +function TCustomSynEdit.DisplayToBufferPos(const p: TDisplayCoord): TBufferCoord; +// DisplayToBufferPos takes a position on screen and transfrom it +// into position of text +var + s: UnicodeString; + i, L: Integer; + x, CountOfAvgGlyphs: Integer; +begin + Canvas.Font := Font; + + if WordWrap then + Result := FWordWrapPlugin.DisplayToBufferPos(p) + else + Result := TBufferCoord(p); +{$IFDEF SYN_CodeFolding} + if UseCodeFolding then + Result.Line := fAllFoldRanges.FoldRowToLine(p.Row); +{$ENDIF} + + if Result.Line <= lines.Count then + begin + s := Lines[Result.Line - 1]; + l := Length(s); + x := 0; + i := 0; + + while x < Result.Char do + begin + Inc(i); + if (i <= l) and (s[i] = #9) then + Inc(x, TabWidth - (x mod TabWidth)) + else if i <= l then + begin + CountOfAvgGlyphs := CeilOfIntDiv(FTextDrawer.TextWidth(s[i]), FCharWidth); + Inc(x, CountOfAvgGlyphs); + end + else + Inc(x); + end; + Result.Char := i; + end; +end; + +procedure TCustomSynEdit.DoLinesDeleted(FirstLine, Count: Integer); +var + i: Integer; +begin + // gutter marks + for i := 0 to Marks.Count - 1 do + if Marks[i].Line >= FirstLine + Count then + Marks[i].Line := Marks[i].Line - Count + else if Marks[i].Line > FirstLine then + Marks[i].Line := FirstLine; + + // plugins + if FPlugins <> nil then + for i := 0 to FPlugins.Count - 1 do + TSynEditPlugin(FPlugins[i]).LinesDeleted(FirstLine, Count); +end; + +procedure TCustomSynEdit.DoLinesInserted(FirstLine, Count: Integer); +var + i: Integer; +begin + // gutter marks + for i := 0 to Marks.Count - 1 do + if Marks[i].Line >= FirstLine then + Marks[i].Line := Marks[i].Line + Count; + + // plugins + if FPlugins <> nil then + for i := 0 to FPlugins.Count - 1 do + TSynEditPlugin(FPlugins[i]).LinesInserted(FirstLine, Count); +end; + +procedure TCustomSynEdit.PluginsAfterPaint(ACanvas: TCanvas; const AClip: TRect; + FirstLine, LastLine: Integer); +var + i: Integer; +begin + if FPlugins <> nil then + for i := 0 to FPlugins.Count - 1 do + TSynEditPlugin(FPlugins[i]).AfterPaint(ACanvas, AClip, FirstLine, LastLine); +end; + +procedure TCustomSynEdit.ProperSetLine(ALine: Integer; const ALineText: UnicodeString); +begin + if eoTrimTrailingSpaces in Options then + Lines[ALine] := TrimTrailingSpaces(ALineText) + else + Lines[ALine] := ALineText; +end; + +procedure TCustomSynEdit.AddKeyUpHandler(aHandler: TKeyEvent); +begin + FKbdHandler.AddKeyUpHandler(aHandler); +end; + +procedure TCustomSynEdit.RemoveKeyUpHandler(aHandler: TKeyEvent); +begin + FKbdHandler.RemoveKeyUpHandler(aHandler); +end; + +procedure TCustomSynEdit.AddKeyDownHandler(aHandler: TKeyEvent); +begin + FKbdHandler.AddKeyDownHandler(aHandler); +end; + +procedure TCustomSynEdit.RemoveKeyDownHandler(aHandler: TKeyEvent); +begin + FKbdHandler.RemoveKeyDownHandler(aHandler); +end; + +procedure TCustomSynEdit.AddKeyPressHandler(aHandler: TKeyPressWEvent); +begin + FKbdHandler.AddKeyPressHandler(aHandler); +end; + +procedure TCustomSynEdit.RemoveKeyPressHandler(aHandler: TKeyPressWEvent); +begin + FKbdHandler.RemoveKeyPressHandler(aHandler); +end; + +procedure TCustomSynEdit.AddFocusControl(aControl: TWinControl); +begin + FFocusList.Add(aControl); +end; + +procedure TCustomSynEdit.RemoveFocusControl(aControl: TWinControl); +begin + FFocusList.Remove(aControl); +end; + +function TCustomSynEdit.IsIdentChar(AChar: WideChar): Boolean; +begin + if Assigned(Highlighter) then + Result := Highlighter.IsIdentChar(AChar) + else + Result := AChar >= #33; + + if Assigned(Highlighter) then + Result := Result or CharInSet(AChar, Highlighter.AdditionalIdentChars) + else + Result := Result or CharInSet(AChar, Self.AdditionalIdentChars); + + Result := Result and not IsWordBreakChar(AChar); +end; + +function TCustomSynEdit.IsWhiteChar(AChar: WideChar): Boolean; +begin + if Assigned(Highlighter) then + Result := Highlighter.IsWhiteChar(AChar) + else + case AChar of + #0..#32: + Result := True; + else + Result := not (IsIdentChar(AChar) or IsWordBreakChar(AChar)) + end +end; + +function TCustomSynEdit.IsWordBreakChar(AChar: WideChar): Boolean; +begin + if Assigned(Highlighter) then + Result := Highlighter.IsWordBreakChar(AChar) + else + case AChar of + #0..#32, '.', ',', ';', ':', '"', '''', WideChar(#$00B4), '`', + WideChar(#$00B0), '^', '!', '?', '&', '$', '@', WideChar(#$00A7), '%', + '#', '~', '[', ']', '(', ')', '{', '}', '<', '>', '-', '=', '+', '*', + '/', '\', '|': + Result := True; + else + Result := False; + end; + + if Assigned(Highlighter) then + begin + Result := Result or CharInSet(AChar, Highlighter.AdditionalWordBreakChars); + Result := Result and not CharInSet(AChar, Highlighter.AdditionalIdentChars); + end + else + begin + Result := Result or CharInSet(AChar, Self.AdditionalWordBreakChars); + Result := Result and not CharInSet(AChar, Self.AdditionalIdentChars); + end; +end; + +procedure TCustomSynEdit.SetSearchEngine(Value: TSynEditSearchCustom); +begin + if (FSearchEngine <> Value) then + begin + FSearchEngine := Value; + if Assigned(FSearchEngine) then + FSearchEngine.FreeNotification(Self); + end; +end; + +function TCustomSynEdit.NextWordPos: TBufferCoord; +begin + Result := NextWordPosEx(CaretXY); +end; + +function TCustomSynEdit.WordStart: TBufferCoord; +begin + Result := WordStartEx(CaretXY); +end; + +function TCustomSynEdit.WordEnd: TBufferCoord; +begin + Result := WordEndEx(CaretXY); +end; + +function TCustomSynEdit.PrevWordPos: TBufferCoord; +begin + Result := PrevWordPosEx(CaretXY); +end; + +function TCustomSynEdit.GetPositionOfMouse(out aPos: TBufferCoord): Boolean; +// Get XY caret position of mouse. Returns False if point is outside the +// region of the uRESTDWPrivSynEdit control. +var + Point: TPoint; +begin + GetCursorPos(Point); // mouse position (on screen) + Point := Self.ScreenToClient(Point); // convert to uRESTDWPrivSynEdit coordinates + { Make sure it fits within the uRESTDWPrivSynEdit bounds } + if (Point.X < 0) or (Point.Y < 0) or (Point.X > Self.Width) or (Point.Y> Self.Height) then + begin + Result := False; + Exit; + end; + + { inside the editor, get the Word under the mouse pointer } + aPos := DisplayToBufferPos(PixelsToRowColumn(Point.X, Point.Y)); + Result := True; +end; + +function TCustomSynEdit.GetWordAtMouse: UnicodeString; +var + Point: TBufferCoord; +begin + { Return the Word under the mouse } + if GetPositionOfMouse(Point) then // if point is valid + Result := Self.GetWordAtRowCol(Point); // return the point at the mouse position +end; + +function TCustomSynEdit.CharIndexToRowCol(Index: Integer): TBufferCoord; +{ Index is 0-based; Result.x and Result.y are 1-based } +var + x, y, Chars: Integer; +begin + x := 0; + y := 0; + Chars := 0; + while y < Lines.Count do + begin + x := Length(Lines[y]); + if Chars + x + 2 > Index then + begin + x := Index - Chars; + Break; + end; + Inc(Chars, x + 2); + x := 0; + Inc(y); + end; + Result.Char := x + 1; + Result.Line := y + 1; +end; + +function TCustomSynEdit.RowColToCharIndex(RowCol: TBufferCoord): Integer; +{ Row and Col are 1-based; Result is 0-based } +var + synEditStringList : TSynEditStringList; +begin + RowCol.Line := Max(0, Min(Lines.Count, RowCol.Line) - 1); + synEditStringList := (FLines as TSynEditStringList); + // CharIndexToRowCol assumes a line break size of two + Result := synEditStringList.LineCharIndex(RowCol.Line) + + RowCol.Line * 2 + (RowCol.Char -1); +end; + +procedure TCustomSynEdit.Clear; +{ just to attain interface compatibility with TMemo } +begin + ClearAll; +end; + +function TCustomSynEdit.GetSelLength: Integer; +begin + if SelAvail then + Result := RowColToCharIndex(BlockEnd) - RowColToCharIndex(BlockBegin) + else + Result := 0; +end; + +procedure TCustomSynEdit.SetSelLength(const Value: Integer); +var + iNewCharIndex: Integer; + iNewBegin: TBufferCoord; + iNewEnd: TBufferCoord; +begin + iNewCharIndex := RowColToCharIndex(BlockBegin) + Value; + if (Value >= 0) or (iNewCharIndex < 0) then + begin + if iNewCharIndex < 0 then + begin + iNewEnd.Char := Length(Lines[Lines.Count - 1]) + 1; + iNewEnd.Line := Lines.Count; + end + else + iNewEnd := CharIndexToRowCol(iNewCharIndex); + SetCaretAndSelection(iNewEnd, BlockBegin, iNewEnd); + end + else begin + iNewBegin := CharIndexToRowCol(iNewCharIndex); + SetCaretAndSelection(iNewBegin, iNewBegin, BlockBegin); + end; +end; + +procedure TCustomSynEdit.DefineProperties(Filer: TFiler); + +{$IFDEF SYN_COMPILER_6_UP} + function CollectionsEqual(C1, C2: TCollection): Boolean; + begin + Result := Classes.CollectionsEqual(C1, C2, nil, nil); + end; +{$ENDIF} + + function HasKeyData: Boolean; + var + iDefKeys: TSynEditKeyStrokes; + begin + if Filer.Ancestor <> nil then + begin + Result := not CollectionsEqual(Keystrokes, + TCustomSynEdit(Filer.Ancestor).Keystrokes); + end + else begin + iDefKeys := TSynEditKeyStrokes.Create(nil); + try + iDefKeys.ResetDefaults; + Result := not CollectionsEqual(Keystrokes, iDefKeys); + finally + iDefKeys.Free; + end; + end; + end; + +var + iSaveKeyData: Boolean; +begin + inherited; +{$IFNDEF UNICODE} + UnicodeDefineProperties(Filer, Self); +{$ENDIF} + iSaveKeyData := HasKeyData; + Filer.DefineProperty('RemovedKeystrokes', ReadRemovedKeystrokes, + WriteRemovedKeystrokes, iSaveKeyData); + Filer.DefineProperty('AddedKeystrokes', ReadAddedKeystrokes, WriteAddedKeystrokes, + iSaveKeyData); +end; + +procedure TCustomSynEdit.DoChange; +begin + if Assigned(FOnChange) then + FOnChange(Self); +end; + +procedure TCustomSynEdit.ReadAddedKeystrokes(Reader: TReader); +var + iAddKeys: TSynEditKeyStrokes; + cKey: Integer; +begin + if Reader.NextValue = vaCollection then + Reader.ReadValue + else + Exit; + iAddKeys := TSynEditKeyStrokes.Create(Self); + try + Reader.ReadCollection(iAddKeys); + for cKey := 0 to iAddKeys.Count -1 do + Keystrokes.Add.Assign(iAddKeys[cKey]); + finally + iAddKeys.Free; + end; +end; + +procedure TCustomSynEdit.ReadRemovedKeystrokes(Reader: TReader); +var + iDelKeys: TSynEditKeyStrokes; + cKey: Integer; + iKey: TSynEditKeyStroke; + iToDelete: Integer; +begin + if Reader.NextValue = vaCollection then + Reader.ReadValue + else + Exit; + iDelKeys := TSynEditKeyStrokes.Create(nil); + try + Reader.ReadCollection(iDelKeys); + for cKey := 0 to iDelKeys.Count -1 do + begin + iKey := iDelKeys[cKey]; + iToDelete := Keystrokes.FindShortcut2(iKey.ShortCut, iKey.ShortCut2); + if (iToDelete >= 0) and (Keystrokes[iToDelete].Command = iKey.Command) then + Keystrokes[iToDelete].Free; + end; + finally + iDelKeys.Free; + end; +end; + +procedure TCustomSynEdit.WriteAddedKeystrokes(Writer: TWriter); +var + iDefaultKeys: TSynEditKeyStrokes; + iAddedKeys: TSynEditKeyStrokes; + cKey: Integer; + iKey: TSynEditKeyStroke; + iDelIndex: Integer; +begin + iDefaultKeys := TSynEditKeyStrokes.Create(nil); + try + if Writer.Ancestor <> nil then + iDefaultKeys.Assign(TSynEdit(Writer.Ancestor).Keystrokes) + else + iDefaultKeys.ResetDefaults; + iAddedKeys := TSynEditKeyStrokes.Create(nil); + try + for cKey := 0 to Keystrokes.Count -1 do + begin + iKey := Keystrokes[cKey]; + iDelIndex := iDefaultKeys.FindShortcut2(iKey.ShortCut, iKey.ShortCut2); + //if it's not a default keystroke, add it + if (iDelIndex < 0) or (iDefaultKeys[iDelIndex].Command <> iKey.Command) then + iAddedKeys.Add.Assign(iKey); + end; + Writer.WriteCollection(iAddedKeys); + finally + iAddedKeys.Free; + end; + finally + iDefaultKeys.Free; + end; +end; + +procedure TCustomSynEdit.WriteRemovedKeystrokes(Writer: TWriter); +var + iRemovedKeys: TSynEditKeyStrokes; + cKey: Integer; + iKey: TSynEditKeyStroke; + iFoundAt: Integer; +begin + iRemovedKeys := TSynEditKeyStrokes.Create(nil); + try + if Writer.Ancestor <> nil then + iRemovedKeys.Assign(TSynEdit(Writer.Ancestor).Keystrokes) + else + iRemovedKeys.ResetDefaults; + cKey := 0; + while cKey < iRemovedKeys.Count do + begin + iKey := iRemovedKeys[cKey]; + iFoundAt := Keystrokes.FindShortcut2(iKey.ShortCut, iKey.ShortCut2); + if (iFoundAt >= 0) and (Keystrokes[iFoundAt].Command = iKey.Command) then + iKey.Free //if exists in Keystrokes, then shouldn't be in "removed" list + else + Inc(cKey); + end; + Writer.WriteCollection(iRemovedKeys); + finally + iRemovedKeys.Free; + end; +end; + +procedure TCustomSynEdit.AddMouseDownHandler(aHandler: TMouseEvent); +begin + FKbdHandler.AddMouseDownHandler(aHandler); +end; + +procedure TCustomSynEdit.RemoveMouseDownHandler(aHandler: TMouseEvent); +begin + FKbdHandler.RemoveMouseDownHandler(aHandler); +end; + +procedure TCustomSynEdit.AddMouseUpHandler(aHandler: TMouseEvent); +begin + FKbdHandler.AddMouseUpHandler(aHandler); +end; + +procedure TCustomSynEdit.RemoveMouseUpHandler(aHandler: TMouseEvent); +begin + FKbdHandler.RemoveMouseUpHandler(aHandler); +end; + +procedure TCustomSynEdit.ResetModificationIndicator; +begin + TSynEditStringList(FLines).ResetModificationIndicator; + if FGutter.ShowModification then + InvalidateGutter; +end; + +{$IFDEF SYN_CodeFolding} + +procedure TCustomSynEdit.FullFoldScan; +begin + if UseCodeFolding then + begin + ReScanForFoldRanges(0, fLines.Count -1); + end; +end; + +procedure TCustomSynEdit.ReScanForFoldRanges(FromLine : Integer; ToLine : Integer); +Var + AdjustedToLine: Integer; +begin + AdjustedToLine := Max(Min(ToLine, Lines.Count - 1), FromLine); + fAllFoldRanges.StartScanning; + ScanForFoldRanges(fAllFoldRanges, fLines, FromLine, AdjustedToLine); + { StopScanning recreates AllFoldRanges. + Normally at this point (sfLinesChanging in fStateFlags) = True + and StopScanning will be called when LinesChanged is executed } + if not (sfLinesChanging in fStateFlags) and fAllFoldRanges.StopScanning(fLines) then + begin + if Assigned(fHighlighter) and (fHighlighter is TSynCustomCodeFoldingHighlighter) then + TSynCustomCodeFoldingHighlighter(fHighlighter).AdjustFoldRanges(AllFoldRanges, + fLines); + InvalidateGutter; + Include(fStateFlags, sfScrollbarChanged); + end; +end; + +procedure TCustomSynEdit.ScanForFoldRanges(FoldRanges: TSynFoldRanges; + LinesToScan: TStrings; FromLine : Integer; ToLine : Integer); +begin + if Assigned(fHighlighter) and (fHighlighter is TSynCustomCodeFoldingHighlighter) then + TSynCustomCodeFoldingHighlighter(fHighlighter).ScanForFoldRanges(FoldRanges, + LinesToScan, FromLine, ToLine); + + if Assigned(fOnScanForFoldRanges) then + fOnScanForFoldRanges(Self, FoldRanges, LinesToScan, FromLine, ToLine); +end; +{$ENDIF} + +procedure TCustomSynEdit.AddMouseCursorHandler(aHandler: TMouseCursorEvent); +begin + FKbdHandler.AddMouseCursorHandler(aHandler); +end; + +procedure TCustomSynEdit.RemoveMouseCursorHandler(aHandler: TMouseCursorEvent); +begin + FKbdHandler.RemoveMouseCursorHandler(aHandler); +end; + +{$IFDEF SYN_COMPILER_6_UP} +procedure TCustomSynEdit.DoSearchFindFirstExecute(Action: TSearchFindFirst); +begin + FOnFindBeforeSearch := Action.Dialog.OnFind; + FOnCloseBeforeSearch := Action.Dialog.OnClose; + FSelStartBeforeSearch := SelStart; FSelLengthBeforeSearch := SelLength; + + Action.Dialog.OnFind := FindDialogFindFirst; + Action.Dialog.OnClose := FindDialogClose; + Action.Dialog.Execute(); +end; + +procedure TCustomSynEdit.DoSearchFindExecute(Action: TSearchFind); +begin + FOnFindBeforeSearch := Action.Dialog.OnFind; + FOnCloseBeforeSearch := Action.Dialog.OnClose; + + Action.Dialog.OnFind := FindDialogFind; + Action.Dialog.OnClose := FindDialogClose; + Action.Dialog.Execute(); +end; + +procedure TCustomSynEdit.DoSearchReplaceExecute(Action: TSearchReplace); +begin + FOnFindBeforeSearch := Action.Dialog.OnFind; + FOnReplaceBeforeSearch := Action.Dialog.OnReplace; + FOnCloseBeforeSearch := Action.Dialog.OnClose; + + Action.Dialog.OnFind := FindDialogFind; + Action.Dialog.OnReplace := FindDialogFind; + Action.Dialog.OnClose := FindDialogClose; + Action.Dialog.Execute(); +end; + +procedure TCustomSynEdit.DoSearchFindNextExecute(Action: TSearchFindNext); +begin + SearchByFindDialog(Action.SearchFind.Dialog); +end; + +procedure TCustomSynEdit.FindDialogFindFirst(Sender: TObject); +begin + TFindDialog(Sender).CloseDialog; + + if (SelStart = FSelStartBeforeSearch) and (SelLength = FSelLengthBeforeSearch) then + begin + SelStart := 0; + SelLength := 0; + end; + + if Sender is TFindDialog then + if not SearchByFindDialog(TFindDialog(Sender)) and (SelStart = 0) and (SelLength = 0) then + begin + SelStart := FSelStartBeforeSearch; + SelLength := FSelLengthBeforeSearch; + end; +end; + +procedure TCustomSynEdit.FindDialogFind(Sender: TObject); +begin + if Sender is TFindDialog then + SearchByFindDialog(TFindDialog(Sender)); +end; + +function TCustomSynEdit.SearchByFindDialog(FindDialog: TFindDialog) : bool; +var + Options :TSynSearchOptions; + ReplaceText, MessageText: string; + OldSelStart, OldSelLength: Integer; +begin + if (frReplaceAll in FindDialog.Options) then Options := [ssoReplaceAll] + else if (frReplace in FindDialog.Options) then Options := [ssoReplace] + else Options := [ssoSelectedOnly]; + + if (frMatchCase in FindDialog.Options) then Options := Options + [ssoMatchCase]; + if (frWholeWord in FindDialog.Options) then Options := Options + [ssoWholeWord]; + if (not (frDown in FindDialog.Options)) then Options := Options + [ssoBackwards]; + + if (ssoSelectedOnly in Options) + then ReplaceText := '' + else ReplaceText := TReplaceDialog(FindDialog).ReplaceText; + + OldSelStart := SelStart; OldSelLength := SelLength; + if (UpperCase(SelText) = UpperCase(FindDialog.FindText)) and not (frReplace in FindDialog.Options) then + SelStart := SelStart + SelLength + else + SelLength := 0; + + Result := SearchReplace(FindDialog.FindText, ReplaceText, Options) > 0; + if not Result then + begin + SelStart := OldSelStart; SelLength := OldSelLength; + if Assigned(OnSearchNotFound) then + OnSearchNotFound(self, FindDialog.FindText) + else + begin + MessageText := Format(STextNotFound, [FindDialog.FindText]); + ShowMessage(MessageText); + end; + end + else if (frReplace in FindDialog.Options) then + begin + SelStart := SelStart - Length(FindDialog.FindText) - 1; + SelLength := Length(FindDialog.FindText) + 1; + end; +end; + +procedure TCustomSynEdit.FindDialogClose(Sender: TObject); +begin + TFindDialog(Sender).OnFind := FOnFindBeforeSearch; + if Sender is TReplaceDialog then + TReplaceDialog(Sender).OnReplace := FOnReplaceBeforeSearch; + TFindDialog(Sender).OnClose := FOnCloseBeforeSearch; +end; +{$ENDIF} + +function TCustomSynEdit.GetWordWrap: Boolean; +begin + Result := FWordWrapPlugin <> nil; +end; + +procedure TCustomSynEdit.SetWordWrap(const Value: Boolean); +var + vTempBlockBegin, vTempBlockEnd : TBufferCoord; + vOldTopLine: Integer; + vShowCaret: Boolean; +begin + if WordWrap <> Value then + begin + Invalidate; // better Invalidate before changing LeftChar and TopLine + vShowCaret := CaretInView; + vOldTopLine := RowToLine(TopLine); +{$IFDEF SYN_CodeFolding} + // !!Mutually exclusive with CodeFolding to reduce complexity + if Value and not UseCodeFolding then +{$ELSE} + if Value then +{$ENDIF} + begin + FWordWrapPlugin := TSynWordWrapPlugin.Create(Self); + LeftChar := 1; + end + else + FWordWrapPlugin := nil; + TopLine := LineToRow(vOldTopLine); + UpdateScrollBars; + + // constrain caret position to MaxScrollWidth if eoScrollPastEol is enabled + if (eoScrollPastEol in Options) then + begin + InternalCaretXY := CaretXY; + vTempBlockBegin := BlockBegin; + vTempBlockEnd := BlockEnd; + SetBlockBegin(vTempBlockBegin); + SetBlockEnd(vTempBlockEnd); + end; + if vShowCaret then + EnsureCursorPosVisible; + end; +end; + +function TCustomSynEdit.GetDisplayLineCount: Integer; +begin +{$IFDEF SYN_CodeFolding} + if fWordWrapPlugin = nil then begin + if fUseCodeFolding then + Result := LineToRow(Lines.Count) + else + Result := Lines.Count + end else if Lines.Count = 0 then +{$ELSE} + if FWordWrapPlugin = nil then + Result := Lines.Count + else if Lines.Count = 0 then +{$ENDIF} + Result := 0 + else begin + Result := FWordWrapPlugin.RowCount; + end; +end; + +function TCustomSynEdit.LineToRow(aLine: Integer): Integer; +var + vBufferPos: TBufferCoord; +begin +{$IFDEF SYN_CodeFolding} + if not WordWrap and not UseCodeFolding then +{$ELSE} + if not WordWrap then +{$ENDIF} + Result := aLine + else begin + vBufferPos.Char := 1; + vBufferPos.Line := aLine; + Result := BufferToDisplayPos(vBufferPos).Row; + end; +end; + +function TCustomSynEdit.RowToLine(aRow: Integer): Integer; +var + vDisplayPos: TDisplayCoord; +begin +{$IFDEF SYN_CodeFolding} + if not WordWrap and not UseCodeFolding then +{$ELSE} + if not WordWrap then +{$ENDIF} + Result := aRow + else begin + vDisplayPos.Column := 1; + vDisplayPos.Row := aRow; + Result := DisplayToBufferPos(vDisplayPos).Line; + end; +end; + +procedure TCustomSynEdit.SetInternalDisplayXY(const aPos: TDisplayCoord); +begin + IncPaintLock; + InternalCaretXY := DisplayToBufferPos(aPos); + FCaretAtEOL := WordWrap and (aPos.Row <= FWordWrapPlugin.RowCount) and + (aPos.Column > FWordWrapPlugin.GetRowLength(aPos.Row)) and + (DisplayY <> aPos.Row); + DecPaintLock; + UpdateLastCaretX; +end; + +procedure TCustomSynEdit.SetWantReturns(Value: Boolean); +begin + FWantReturns := Value; +end; + +procedure TCustomSynEdit.SetWantTabs(Value: Boolean); +begin + FWantTabs := Value; +end; + +procedure TCustomSynEdit.SetWordWrapGlyph(const Value: TSynGlyph); +begin + FWordWrapGlyph.Assign(Value); +end; + +procedure TCustomSynEdit.WordWrapGlyphChange(Sender: TObject); +begin + if not (csLoading in ComponentState) then + InvalidateGutter; +end; + + +{ TSynEditMark } + +function TSynEditMark.GetEdit: TCustomSynEdit; +begin + if FEdit <> nil then try + if FEdit.Marks.IndexOf(self) = -1 then + FEdit := nil; + except + FEdit := nil; + end; + Result := FEdit; +end; + +function TSynEditMark.GetIsBookmark: Boolean; +begin + Result := (FBookmarkNum >= 0); +end; + +procedure TSynEditMark.SetChar(const Value: Integer); +begin + FChar := Value; +end; + +procedure TSynEditMark.SetImage(const Value: Integer); +begin + FImage := Value; + if FVisible and Assigned(FEdit) then + FEdit.InvalidateGutterLines(FLine, FLine); +end; + +procedure TSynEditMark.SetInternalImage(const Value: Boolean); +begin + FInternalImage := Value; + if FVisible and Assigned(FEdit) then + FEdit.InvalidateGutterLines(FLine, FLine); +end; + +procedure TSynEditMark.SetLine(const Value: Integer); +begin + if FVisible and Assigned(FEdit) then + begin + if FLine > 0 then + FEdit.InvalidateGutterLines(FLine, FLine); + FLine := Value; + FEdit.InvalidateGutterLines(FLine, FLine); + end + else + FLine := Value; +end; + +procedure TSynEditMark.SetVisible(const Value: Boolean); +begin + if FVisible <> Value then + begin + FVisible := Value; + if Assigned(FEdit) then + FEdit.InvalidateGutterLines(FLine, FLine); + end; +end; + +constructor TSynEditMark.Create(AOwner: TCustomSynEdit); +begin + inherited Create; + FBookmarkNum := -1; + FEdit := AOwner; +end; + +{ TSynEditMarkList } + +procedure TSynEditMarkList.Notify(Ptr: Pointer; Action: TListNotification); +begin + inherited; + if Assigned(FOnChange) then + FOnChange(Self); +end; + +function TSynEditMarkList.GetItem(Index: Integer): TSynEditMark; +begin + Result := TSynEditMark(inherited GetItem(Index)); +end; + +procedure TSynEditMarkList.SetItem(Index: Integer; Item: TSynEditMark); +begin + inherited SetItem(Index, Item); +end; + +constructor TSynEditMarkList.Create(AOwner: TCustomSynEdit); +begin + inherited Create; + FEdit := AOwner; +end; + +function TSynEditMarkList.First: TSynEditMark; +begin + Result := TSynEditMark(inherited First); +end; + +function TSynEditMarkList.Last: TSynEditMark; +begin + Result := TSynEditMark(inherited Last); +end; + +function TSynEditMarkList.Extract(Item: TSynEditMark): TSynEditMark; +begin + Result := TSynEditMark(inherited Extract(Item)); +end; + +procedure TSynEditMarkList.ClearLine(Line: Integer); +var + i: Integer; +begin + for i := Count - 1 downto 0 do + if not Items[i].IsBookmark and (Items[i].Line = Line) then + Delete(i); +end; + +procedure TSynEditMarkList.GetMarksForLine(line: Integer; var marks: TSynEditMarks); +//Returns up to maxMarks book/gutter marks for a chosen line. +var + cnt: Integer; + i: Integer; +begin + FillChar(marks, SizeOf(marks), 0); + cnt := 0; + for i := 0 to Count - 1 do + begin + if Items[i].Line = line then + begin + Inc(cnt); + marks[cnt] := Items[i]; + if cnt = MAX_MARKS then + Break; + end; + end; +end; + +procedure TSynEditMarkList.Place(mark: TSynEditMark); +begin + if assigned(FEdit) then + if Assigned(FEdit.OnPlaceBookmark) then + FEdit.OnPlaceBookmark(FEdit, mark); + if assigned(mark) then + Add(mark); +end; + +{ TSynEditPlugin } + +constructor TSynEditPlugin.Create(AOwner: TCustomSynEdit); +begin + inherited Create; + if AOwner <> nil then + begin + FOwner := AOwner; + if FOwner.FPlugins = nil then + FOwner.FPlugins := TObjectList.Create; + FOwner.FPlugins.Add(Self); + end; +end; + +destructor TSynEditPlugin.Destroy; +begin + if FOwner <> nil then + FOwner.FPlugins.Extract(Self); // we are being destroyed, FOwner should not free us + inherited Destroy; +end; + +procedure TSynEditPlugin.AfterPaint(ACanvas: TCanvas; const AClip: TRect; + FirstLine, LastLine: Integer); +begin + // nothing +end; + +procedure TSynEditPlugin.PaintTransient(ACanvas: TCanvas; ATransientType: TTransientType); +begin + // nothing +end; + +procedure TSynEditPlugin.LinesInserted(FirstLine, Count: Integer); +begin + // nothing +end; + +procedure TSynEditPlugin.LinesDeleted(FirstLine, Count: Integer); +begin + // nothing +end; + +{$IFNDEF UNICODE} +var + GetMsgHook: HHOOK; + +function GetMsgProc(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; +var +{$IFNDEF SYN_COMPILER_9_UP} + WndProc: Pointer; +{$ENDIF} + WinCtrl: TWinControl; +begin + WinCtrl := TCustomSynEdit(FindControl(PMsg(lParam)^.hWnd)); + if WinCtrl is TCustomSynEdit then + begin + TCustomSynEdit(WinCtrl).FWindowProducedMessage := True; + +{$IFNDEF SYN_COMPILER_9_UP} + if Code = HC_ACTION then + begin + with PMsg(lParam)^ do + case message of + WM_CHAR: + begin + if wParam > Ord(High(AnsiChar)) then + if IsWindowUnicode(hWnd) then + begin + WndProc := Pointer(GetWindowLong(hWnd, GWL_WNDPROC)); + CallWindowProcW(WndProc, hWnd, WM_CHAR, wParam, lParam); + Message := WM_NULL; + end; + end; + end; + end; +{$ENDIF} + + end; + + Result := CallNextHookEx(GetMsgHook, Code, wParam, lParam); +end; +{$ENDIF} + +initialization +{$IFNDEF UNICODE} + if Win32PlatformIsUnicode and not (csDesigning in Application.ComponentState) then + begin + // Hooking GetMessage/PeekMessage-calls is necessary as the use of + // PeekMessageA in TApplication.ProcessMessage mutilates Unicode-messages. + GetMsgHook := SetWindowsHookExW(WH_GETMESSAGE, GetMsgProc, 0, + GetCurrentThreadId); + end + else + GetMsgHook := 0; +{$ENDIF} + SynEditClipboardFormat := RegisterClipboardFormat(SYNEDIT_CLIPBOARD_FORMAT); + +finalization +{$IFNDEF UNICODE} + if Win32PlatformIsUnicode and (GetMsgHook <> 0) then + UnhookWindowsHookEx(GetMsgHook); +{$ENDIF} + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditCodeFolding.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditCodeFolding.pas new file mode 100644 index 000000000..e40352f7e --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditCodeFolding.pas @@ -0,0 +1,1089 @@ +{ ------------------------------------------------------------------------------- + The contents of this file are subject to the Mozilla Public License + Version 1.1 (the "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" basis, + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + the specific language governing rights and limitations under the License. + + The Original Code is uRESTDWPrivSynEditWordWrap.pas by Flvio Etrusco, released 2003-12-11. + Unicode translation by Mal Hrz. + All Rights Reserved. + + Contributors to the uRESTDWPrivSynEdit and mwEdit projects are listed in the + Contributors.txt file. + + Alternatively, the contents of this file may be used under the terms of the + GNU General Public License Version 2 or later (the "GPL"), in which case + the provisions of the GPL are applicable instead of those above. + If you wish to allow use of your version of this file only under the terms + of the GPL and not to allow others to use your version of this file + under the MPL, indicate your decision by deleting the provisions above and + replace them with the notice and other provisions required by the GPL. + If you do not delete the provisions above, a recipient may use your version + of this file under either the MPL or the GPL. + ------------------------------------------------------------------------------- } +unit uRESTDWPrivSynEditCodeFolding; +{ + Introduction + ============ + This unit adds code folding support for uRESTDWPrivSynEdit. + It blends well with the uRESTDWPrivSynEdit highligting infrastructure and provides + fast and efficient code folding that can cope with files with tens of + thousands of line without lags. + + Converting existing highlighters + ================================ + + To support code folding a Highlighter must inherit from + TSynCustomCodeFoldingHighlighter and implement one abstact procedure + ScanForFoldRanges(FoldRanges: TSynFoldRanges; + LinesToScan: TStrings; FromLine: Integer; ToLine: Integer); + For each line ScanForFoldRanges needs to call one of the following: + FoldRanges.StartFoldRange + FoldRanges.StopFoldRange + FoldRanges.NoFoldInfo + ScanForFoldRanges is called after the standard highlighter scanning has taken + place so one can use the Range information stored inside LinesToScan, which + is a TSynEditStringList, to avoid duplicating effort. + + Initally two hightlighters have been converted uRESTDWPrivSynHighlighterJScript and + SynHighlighterPython, to serve as examples of adding code folding suppot to + brace-based and indentation-based languagges. + + Alternatively, code folding support can be provided just by implementing + the uRESTDWPrivSynEdit OnScanForFoldRangesEvent event. + + Demo of Coding Folding + ====================== + A Folding demo has been added that demonstrates the use of the JScript and + Python highlighters as well as the use of the OnScanForFoldRangesEvent event + to support code folding in C++ files. + + uRESTDWPrivSynEdit Commands and Shortcuts + ============================== + The following commands have been added: + ecFoldAll, ecUnfoldAll, ecFoldNearest, ecUnfoldNearest, ecFoldLevel1, + ecFoldLevel2, ecFoldLevel3,, ecUnfoldLevel1, ecUnfoldLevel2, + ecUnfoldLevel3, ecFoldRegions + + The default customisable shortcuts are: + AddKey(ecFoldAll, VK_OEM_MINUS, [ssCtrl, ssShift]); //- _ + AddKey(ecUnfoldAll, VK_OEM_PLUS, [ssCtrl, ssShift]); //= + + AddKey(ecFoldNearest, VK_OEM_2, [ssCtrl]); // Divide //'/' + AddKey(ecUnfoldNearest, VK_OEM_2, [ssCtrl, ssShift]); + AddKey(ecFoldLevel1, ord('K'), [ssCtrl], Ord('1'), [ssCtrl]); + AddKey(ecFoldLevel2, ord('K'), [ssCtrl], Ord('2'), [ssCtrl]); + AddKey(ecFoldLevel3, ord('K'), [ssCtrl], Ord('3'), [ssCtrl]); + AddKey(ecUnfoldLevel1, ord('K'), [ssCtrl, ssShift], Ord('1'), [ssCtrl, ssShift]); + AddKey(ecUnfoldLevel2, ord('K'), [ssCtrl, ssShift], Ord('2'), [ssCtrl, ssShift]); + AddKey(ecUnfoldLevel3, ord('K'), [ssCtrl, ssShift], Ord('3'), [ssCtrl, ssShift]); + + Limitations + =========== + - Code folding can not be used simultaneously with Wordwrap. uRESTDWPrivSynEdit takes + care of that. + - The code uses generic collections, so it cannot be used with Delphi + versions prior to Delphi 2009. + + Improvements + ============ + Although the code folding infrastructure is fairly complete, improvements + can be made in providing the use with more painting options + (folding hints etc.) + + Technical details + ================= + The main code folding structure is TSynFoldRanges. It contains a public + TList (sorted by starting line numbers). This list is used by + uRESTDWPrivSynEdit to paint the gutter and lines, fold and unfold ranges etc. + Internally, TSynFoldRange maintains a TList that is modified + during scanning. The TList is reconstructed from the + TList only when it is necessary. + +} +interface + +{$I uRESTDWPrivSynEdit.inc} + +uses + Graphics, + Types, + Classes, + SysUtils, + Generics.Defaults, + Generics.Collections, + uRESTDWPrivSynEditHighlighter; + +type +{$IFNDEF SYN_DELPHI_XE3_UP} + // use small hack in XE and XE2 to make internal array accessible as in XE3 and up + TList = class(Generics.Collections.TList) + private + function GetList: TArray; + public + property List: TArray read GetList; + end; +{$ENDIF} + + // Custom COde Folding Exception + TSynCodeFoldingException = class(Exception) + end; + + // A single fold + // Important: FromLine, ToLine are 1-based + TSynFoldRange = record + FromLine: Integer; // Beginning line + ToLine: Integer; // End line + FoldType: Integer; // Could be used by some complex highlighters + Indent : Integer; // Only used for Indent based folding (Python) + Collapsed: Boolean; // Is collapsed? + private + function GetLinesCollapsed: Integer; + public + procedure Move(Count: Integer); + property LinesCollapsed: Integer read GetLinesCollapsed; + constructor Create(AFromLine : Integer; AToLine : Integer = -1; + AFoldType : Integer = 1; AIndent : Integer = -1; + ACollapsed : Boolean = False); + end; + + PSynFoldRange = ^TSynFoldRange; + + {Support for indendation based code folding as in Python, F#} + TSynCodeFoldingMode = (cfmStandard, cfmIndentation); + + TSynFoldRanges = class(TObject) + { + The main code folding data structure. + Scanning affects the fFoldInfoList data structure + uRESTDWPrivSynEdit Painting is based on the fRanges structure + fRanges gets updated from fFoldInfoList when needed + Both fRanges and fFoldInfoList are kept sorted by FromLine + Line indices in both fRanges and fFoldInfoList are 1-based + } + private + type + TFoldOpenClose = (focOpen, focClose); + + TLineFoldInfo = record + Line : Integer; + FoldOpenClose : TFoldOpenClose; + FoldType : Integer; + Indent : Integer; + constructor Create(ALine : Integer; + AFoldOpenClose : TFoldOpenClose = focOpen; + AFoldType : Integer = 1; AIndent : Integer = -1); + end; + + private + fCodeFoldingMode : TSynCodeFoldingMode; + fRangesNeedFixing : Boolean; + fRanges: TList; + fCollapsedState : TList; + fFoldInfoList : TList; + function Get(Index: Integer): TSynFoldRange; + function GetCount: Integer; + public + constructor Create; + destructor Destroy; override; + + {utility routines} + function FoldStartAtLine(Line: Integer): Boolean; overload; + function FoldStartAtLine(Line: Integer; out Index: Integer): Boolean; overload; + function CollapsedFoldStartAtLine(Line: Integer): Boolean; overload; + function CollapsedFoldStartAtLine(Line: Integer; out Index: Integer): Boolean; overload; + function FoldEndAtLine(Line: Integer) : Boolean; overload; + function FoldEndAtLine(Line: Integer; out Index: Integer) : Boolean; overload; + function FoldAroundLineEx(Line: Integer; WantCollapsed, AcceptFromLine, + AcceptToLine: Boolean; out Index: Integer): Boolean; + function CollapsedFoldAroundLine(Line: Integer): Boolean; overload; + function CollapsedFoldAroundLine(Line: Integer; out Index: Integer): Boolean; overload; + function FoldAroundLine(Line: Integer) : Boolean; overload; + function FoldAroundLine(Line: Integer; out Index: Integer) : Boolean; overload; + function FoldHidesLine(Line: Integer) : Boolean; overload; + function FoldHidesLine(Line: Integer; out Index: Integer) : Boolean; overload; + function FoldsAtLevel(Level : integer) : TArray; + function FoldsOfType(aType : integer) : TArray; + + {Scanning support} + procedure StoreCollapsedState; + procedure RestoreCollapsedState; + procedure StartScanning; + function StopScanning(Lines : TStrings) : Boolean; // Returns True of Ranges were updated + procedure AddLineInfo(ALine: Integer; AFoldType: Integer; + AFoldOpenClose: TFoldOpenClose; AIndent : Integer); + procedure StartFoldRange(ALine : Integer; AFoldType : integer; AIndent : Integer = -1); + procedure StopFoldRange(ALine : Integer; AFoldType : integer; AIndent : Integer = -1); + procedure NoFoldInfo(ALine : Integer); + function GetIndentLevel(Line : Integer) : Integer; + procedure RecreateFoldRanges(Lines : TStrings); + + // plugin notifications and support routines + function FoldLineToRow(Line: Integer): Integer; + function FoldRowToLine(Row: Integer): Integer; + function LinesInserted(aIndex: Integer; aCount: Integer): Integer; + function LinesDeleted(aIndex: Integer; aCount: Integer): Integer; + function LinesPutted(aIndex: Integer; aCount: Integer): Integer; + procedure Reset; + + {Access to the internal FoldRange list routines} + procedure AddByParts(AFoldType: Integer; AFromLine: Integer; AToLine: Integer = -1); + procedure AddFoldRange(FoldRange: TSynFoldRange); + property CodeFoldingMode : TSynCodeFoldingMode + read fCodeFoldingMode write fCodeFoldingMode; + property Count: Integer read GetCount; + property FoldRange[Index : Integer] : TSynFoldRange read Get; default; + property Ranges: TList read fRanges; + end; + + TSynCodeFoldingChangeEvent = procedure(Sender: TObject) of object; + + TSynCodeFolding = class(TPersistent) + { Class to store and expose to the designer Code Folding properties } + private + fIndentGuides: Boolean; + fCollapsedLineColor: TColor; + fFolderBarLinesColor: TColor; + fIndentGuidesColor: TColor; + fShowCollapsedLine: Boolean; + fShowHintMark : Boolean; + fGutterShapeSize : Integer; + fOnChange : TSynCodeFoldingChangeEvent; + procedure SetIndentGuides(const Value: Boolean); + procedure SetCollapsedLineColor(const Value: TColor); + procedure SetFolderBarLinesColor(const Value: TColor); + procedure SetIndentGuidesColor(const Value: TColor); + procedure SetShowCollapsedLine(const Value: Boolean); + procedure SetShowHintMark(const Value: Boolean); + procedure SetGutterShapeSize(const Value: Integer); + public + constructor Create; + procedure Assign(Source: TPersistent); override; + property OnChange: TSynCodeFoldingChangeEvent read fOnChange write fOnChange; + published + // Size of the gutter shapes in pixels at 96 PPI - had to be odd number + property GutterShapeSize: Integer read fGutterShapeSize + write SetGutterShapeSize; + property CollapsedLineColor: TColor read fCollapsedLineColor + write SetCollapsedLineColor; + property FolderBarLinesColor: TColor read fFolderBarLinesColor + write SetFolderBarLinesColor; + property IndentGuidesColor: TColor read fIndentGuidesColor + write SetIndentGuidesColor; + property IndentGuides: Boolean read fIndentGuides write SetIndentGuides; + property ShowCollapsedLine: Boolean read fShowCollapsedLine + write SetShowCollapsedLine; + property ShowHintMark: Boolean read fShowHintMark + write SetShowHintMark; + end; + + TSynCustomCodeFoldingHighlighter = class(TSynCustomHighlighter) + protected + // Utility functions + function GetLineRange(Lines: TStrings; Line : Integer) : Pointer; + function GetHighlighterAttriAtRowCol(const Lines : TStrings; + const Line: Integer; const Char: Integer): TSynHighlighterAttributes; + function GetHighlighterAttriAtRowColEx(const Lines : TStrings; + const Line, Char: Integer; var Token: string; + var TokenType, Start: Integer; var Attri: TSynHighlighterAttributes): boolean; + function TabWidth(LinesToScan: TStrings) : integer; + public + // Called when a Highlighter is assigned to uRESTDWPrivSynEdit; + // No need to override except to change the SynCodeFoldingMode + procedure InitFoldRanges(FoldRanges : TSynFoldRanges); virtual; + // Called after Highlighter ranges have been set + procedure ScanForFoldRanges(FoldRanges: TSynFoldRanges; + LinesToScan: TStrings; FromLine: Integer; ToLine: Integer); virtual; abstract; + // Called immediately after FoldRanges have been recreated + // Override only if some finetuning of the FoldRanges is need. + procedure AdjustFoldRanges(FoldRanges: TSynFoldRanges; + LinesToScan: TStrings); virtual; + end; + + Const + FoldRegionType: Integer = 99; + +implementation + +uses + uRESTDWPrivSynEditTextBuffer, + Math; + +{$IFNDEF SYN_DELPHI_XE3_UP} +function TList.GetList: TArray; +begin + // use bug that existed in XE and XE2 that made + // it possible to access private members from parent class + Result := TArray(FItems); +end; +{$ENDIF} + +{ TSynEditFoldRanges } + +function TSynFoldRanges.CollapsedFoldAroundLine(Line: Integer): Boolean; +Var + Index: Integer; +begin + Result := CollapsedFoldAroundLine(Line, Index); +end; + +function TSynFoldRanges.CollapsedFoldAroundLine(Line: Integer; + out Index: Integer): Boolean; +begin + Result := FoldAroundLineEx(Line, True, False, False, Index); +end; + +function TSynFoldRanges.CollapsedFoldStartAtLine(Line: Integer): Boolean; +Var + Index: Integer; +begin + Result := CollapsedFoldStartAtLine(Line, Index); +end; + +function TSynFoldRanges.CollapsedFoldStartAtLine(Line: Integer; + out Index: Integer): Boolean; +begin + Result := fRanges.BinarySearch(TSynFoldRange.Create(Line), Index); + if Result then + Result := Result and fRanges[Index].Collapsed; +end; + +constructor TSynFoldRanges.Create; +begin + inherited; + fCodeFoldingMode := cfmStandard; + + fRanges := TList.Create(TComparer.Construct( + function(const L, R: TSynFoldRange): Integer + begin + Result := L.FromLine - R.FromLine; + end)); + + fCollapsedState := TList.Create; + + fFoldInfoList := TList.Create(TComparer.Construct( + function(const L, R: TLineFoldInfo): Integer + begin + Result := L.Line - R.Line; + end)); +end; + +destructor TSynFoldRanges.Destroy; +begin + fRanges.Free; + fCollapsedState.Free; + fFoldInfoList.Free; + inherited; +end; + +function TSynFoldRanges.FoldAroundLine(Line: Integer): Boolean; +Var + Index: Integer; +begin + Result := FoldAroundLine(Line, Index); +end; + +function TSynFoldRanges.FoldAroundLine(Line: Integer; + out Index: Integer): Boolean; +begin + Result := FoldAroundLineEx(Line, False, False, False, Index); +end; + +function TSynFoldRanges.FoldAroundLineEx(Line: Integer; + WantCollapsed, AcceptFromLine, AcceptToLine: Boolean; + out Index: Integer): Boolean; +var + i: Integer; +begin + Result := False; + for i := 0 to fRanges.Count - 1 do + begin + with fRanges.List[i] do + begin + if ((FromLine < Line) or ((FromLine <= Line) and AcceptFromLine)) and + ((ToLine > Line) or ((ToLine >= Line) and AcceptToLine)) and + (Collapsed = WantCollapsed) then + begin + Index := i; + Result := True; + end; + if FromLine > Line then + Exit; + end; + end; +end; + +function TSynFoldRanges.FoldEndAtLine(Line: Integer; + out Index: Integer): Boolean; +var + i: Integer; +begin + Result := False; + for i := 0 to fRanges.Count - 1 do + with fRanges.List[i] do + if (ToLine = Line) then + begin + Index := i; + Result := True; + Break; + end + else if FromLine > Line then + Break; // sorted by line. don't bother scanning further +end; + +function TSynFoldRanges.FoldEndAtLine(Line: Integer): Boolean; +Var + Index: Integer; +begin + Result := FoldEndAtLine(Line, Index); +end; + +function TSynFoldRanges.FoldHidesLine(Line: Integer): Boolean; +Var + Index: Integer; +begin + Result := FoldHidesLine(Line, Index); +end; + +function TSynFoldRanges.FoldHidesLine(Line: Integer; + out Index: Integer): Boolean; +begin + Result := FoldAroundLineEx(Line, True, False, True, Index); +end; + +function TSynFoldRanges.FoldLineToRow(Line: Integer): Integer; +var + i: Integer; + CollapsedTo: Integer; +begin + Result := Line; + CollapsedTo := 0; + for i := 0 to fRanges.Count - 1 do + with fRanges.List[i] do + begin + // fold after line + if FromLine >= Line then + Break; + + if Collapsed then + begin + // Line is found after fold + if ToLine < Line then + begin + Dec(Result, Max(ToLine - Max(FromLine, CollapsedTo), 0)); + CollapsedTo := Max(CollapsedTo, ToLine); + // Inside fold + end + else + begin + Dec(Result, Line - Max(FromLine, CollapsedTo)); + Break; + end; + end; + end; +end; + +function TSynFoldRanges.FoldRowToLine(Row: Integer): Integer; +var + i: Integer; + CollapsedTo: Integer; +begin + Result := Row; + CollapsedTo := 0; + for i := 0 to fRanges.Count - 1 do + with fRanges.List[i] do + begin + if FromLine >= Result then + Break; + + if Collapsed then + begin + Inc(Result, Max(ToLine - Max(FromLine, CollapsedTo), 0)); + CollapsedTo := Max(CollapsedTo, ToLine); + end; + end; +end; + +function TSynFoldRanges.FoldsAtLevel(Level: integer): TArray; +{ + Returns an array of indices of folds with level = Level + ignoring fold ranges of type FoldRegionType +} +Var + i : integer; + FRStack : TList; + ResultList : TList; + + procedure RemoveClosed(Line : integer); + Var + j : integer; + begin + for j := FRStack.Count-1 downto 0 do + if fRanges.List[FRStack[j]].ToLine <= Line then + FRStack.Delete(j); + end; +begin + FRStack := TList.Create; + ResultList := TList.Create; + try + for i := 0 to fRanges.Count - 1 do + begin + if fRanges.List[i].FoldType = FoldRegionType then + continue; + RemoveClosed(fRanges.List[i].FromLine); + FRStack.Add(i); + if FRStack.Count = Level then + ResultList.Add(i); + end; + Result := ResultList.ToArray; + finally + FRStack.Free; + ResultList.Free; + end; +end; + +function TSynFoldRanges.FoldsOfType(aType: integer): TArray; +{ + Returns an array of indices of folds with FoldType = aType +} +Var + i : integer; + ResultList : TList; +begin + ResultList := TList.Create; + try + for i := 0 to fRanges.Count - 1 do + begin + if fRanges.List[i].FoldType = aType then + ResultList.Add(i); + end; + Result := ResultList.ToArray; + finally + ResultList.Free; + end; +end; + +function TSynFoldRanges.FoldStartAtLine(Line: Integer): Boolean; +Var + Index: Integer; +begin + Result := FoldStartAtLine(Line, Index); +end; + +function TSynFoldRanges.FoldStartAtLine(Line: Integer; out Index: Integer): Boolean; +{ + If Result is False it Returns the First Index with Line greater than Line +} +begin + Result := fRanges.BinarySearch(TSynFoldRange.Create(Line), Index); +end; + +procedure TSynFoldRanges.AddByParts(AFoldType: Integer; AFromLine: Integer; + AToLine: Integer); +Var + Index : integer; + FR : TSynFoldRange; +begin + // Insert keeping the list sorted + FR := TSynFoldRange.Create(AFromLine, AToLine, AFoldType); + if FoldStartAtLine(AFromLine, Index) then + fRanges.List[Index] := FR + else + fRanges.Insert(Index, FR); +end; + +procedure TSynFoldRanges.AddFoldRange(FoldRange: TSynFoldRange); +begin + fRanges.Add(FoldRange); +end; + +procedure TSynFoldRanges.AddLineInfo(ALine: Integer; AFoldType: Integer; + AFoldOpenClose: TFoldOpenClose; AIndent : Integer); +var + LineFoldInfo: TLineFoldInfo; + Index: Integer; +begin + LineFoldInfo := TLineFoldInfo.Create(ALine, AFoldOpenClose, AFoldType, AIndent); + + // Insert keeping the list sorted + if fFoldInfoList.BinarySearch(LineFoldInfo, Index) then + begin + if (fFoldInfoList.List[Index].FoldOpenClose <> AFoldOpenClose) or + (fFoldInfoList.List[Index].FoldType <> AFoldType) or + (fFoldInfoList.List[Index].Indent <> AIndent) then + begin + fFoldInfoList.List[Index].FoldOpenClose := AFoldOpenClose; + fFoldInfoList.List[Index].FoldType := AFoldType; + fFoldInfoList.List[Index].Indent := AIndent; + fRangesNeedFixing := True; + end; + end + else begin + fFoldInfoList.Insert(Index, LineFoldInfo); + fRangesNeedFixing := True; + end; +end; + +function TSynFoldRanges.Get(Index: Integer): TSynFoldRange; +begin + Result := TSynFoldRange(fRanges[Index]); +end; + +function TSynFoldRanges.GetCount: Integer; +begin + Result := fRanges.Count; +end; + + +function TSynFoldRanges.GetIndentLevel(Line: Integer): Integer; +Var + Index : Integer; + i : Integer; +begin + Result := -1; + fFoldInfoList.BinarySearch(TLineFoldInfo.Create(Line), Index); + // Search above Line + for I := Index - 1 downto 0 do + if fFoldInfoList.List[i].Indent >= 0 then begin + Result := fFoldInfoList.List[i].Indent; + break + end; +end; + +function TSynFoldRanges.LinesDeleted(aIndex, aCount: Integer): Integer; +{ + Adjust fFoldInfoList and fRanges + aIndex is 0-based fFoldInfoList and fRanges are 1-based + If needed recreate fRanges +} +var + i : Integer; +begin + fRangesNeedFixing := False; + + Result := aCount; + // Adjust fFoldInfoList + // aIndex is 0-based fFoldInfoList is 1-based + for i := fFoldInfoList.Count - 1 downto 0 do + with fFoldInfoList.List[i] do + if Line > aIndex + aCount then + Dec(fFoldInfoList.List[i].Line, aCount) + else if Line > aIndex then begin + fRangesNeedFixing := True; + fFoldInfoList.Delete(i); + end else + break; + + for i := fRanges.Count - 1 downto 0 do + with fRanges.List[i] do + if (FromLine > aIndex + aCount) then + // Move after affected area + Ranges.List[i].Move(-aCount) + else if FromLine > aIndex then + begin + fRangesNeedFixing := True; + fRanges.Delete(i); + end else if ToLine > aIndex + aCount then + Dec(fRanges.List[i].ToLine, aCount) + else if ToLine > aIndex then + Dec(fRanges.List[i].ToLine, ToLine - aIndex) +end; + +function TSynFoldRanges.LinesInserted(aIndex, aCount: Integer): Integer; +{ + Adjust fFoldInfoList and fRanges + aIndex is 0-based fFoldInfoList and fRanges are 1-based +} +var + i: Integer; +begin + Result := aCount; + for i := fFoldInfoList.Count - 1 downto 0 do + with fFoldInfoList.List[i] do + if Line > aIndex then + Inc(fFoldInfoList.List[i].Line, aCount) + else + break; + + for i := fRanges.Count - 1 downto 0 do + with fRanges.List[i] do + begin + if (FromLine > aIndex) then // insertion of count lines above FromLine + fRanges.List[i].Move(aCount) + else if (ToLine > aIndex) then + Inc(fRanges.List[i].ToLine, aCount); + end; +end; + +function TSynFoldRanges.LinesPutted(aIndex, aCount: Integer): Integer; +begin + Result := 1; +end; + +procedure TSynFoldRanges.NoFoldInfo(ALine: Integer); +Var + Index : Integer; +begin + if fFoldInfoList.BinarySearch(TLineFoldInfo.Create(ALine), Index) + then + begin + // we have deleted an existing fold open or close mark + fRangesNeedFixing := True; + fFoldInfoList.Delete(Index); + end; +end; + +procedure TSynFoldRanges.RecreateFoldRanges(Lines : TStrings); +Var + OpenFoldStack : TList; + LFI : TLineFoldInfo; + PFoldRange : PSynFoldRange; + i : Integer; + Line : integer; +begin + { TODO : Account for type } + fRanges.Clear; + + OpenFoldStack := TList.Create; + try + for LFI in fFoldInfoList do + begin + if LFI.FoldOpenClose = focOpen then + begin + if LFI.Indent >= 0 then begin + for i := OpenFoldStack.Count - 1 downto 0 do + begin + // Close all Fold Ranges with less Indent + PFoldRange := @fRanges.List[OpenFoldStack.List[i]]; + if (PFoldRange^.Indent >= LFI.Indent) then begin + PFoldRange^.ToLine := LFI.Line - 1; // Do not include Line + OpenFoldStack.Delete(i); + end; + end; + end; + fRanges.Add(TSynFoldRange.Create(LFI.Line, LFI.Line, LFI.FoldType, LFI.Indent)); + OpenFoldStack.Add(FRanges.Count -1); + end + else + // foClose + begin + if LFI.Indent >= 0 then begin + for i := OpenFoldStack.Count - 1 downto 0 do + begin + // Close all Fold Ranges with less Indent + PFoldRange := @fRanges.List[OpenFoldStack.List[i]]; + if (PFoldRange^.Indent >= LFI.Indent) then begin + PFoldRange^.ToLine := LFI.Line - 1; // Do not include Line + OpenFoldStack.Delete(i); + end; + end; + end + else + for i := OpenFoldStack.Count - 1 downto 0 do + begin + PFoldRange := @fRanges.List[OpenFoldStack.List[i]]; + if (PFoldRange^.FoldType = LFI.FoldType) then begin + PFoldRange^.ToLine := LFI.Line; + OpenFoldStack.Delete(i); + break; + end; + end; + end; + end; + + if CodeFoldingMode = cfmIndentation then + begin + // close all open indent based folds + for i := OpenFoldStack.Count - 1 downto 0 do + begin + // Close all Fold Ranges with less Indent + PFoldRange := @fRanges.List[OpenFoldStack.List[i]]; + if (PFoldRange^.Indent >= 0) then begin + PFoldRange^.ToLine := Lines.Count; // + OpenFoldStack.Delete(i); + end; + end; + // Adjust LineTo for Indent based folds with empty lines in the end + for i := 0 to fRanges.Count - 1 do begin + PFoldRange := @fRanges.List[i]; + if PFoldRange^.Indent >= 0 then + begin + Line := PFoldRange^.ToLine; + while (Line > PFoldRange^.FromLine) and (TrimLeft( Lines[Line-1]) = '') do + begin + Dec(PFoldRange^.ToLine); + Dec(Line); + end; + end; + end; + end; + + finally + OpenFoldStack.Free; + end; +end; + +procedure TSynFoldRanges.Reset; +begin + fRanges.Clear; + fCollapsedState.Clear; + fFoldInfoList.Clear; + fRangesNeedFixing := False; +end; + +procedure TSynFoldRanges.ReStoreCollapsedState; +Var + i, Index : integer; +begin + for i in fCollapsedState do begin + if FoldStartAtLine(i, Index) then + fRanges.List[Index].Collapsed := True; + end; + fCollapsedState.Clear; +end; + +procedure TSynFoldRanges.StartFoldRange(ALine, AFoldType: integer; AIndent : Integer); +begin + AddLineInfo(ALine, AFoldType, focOpen, AIndent); +end; + +procedure TSynFoldRanges.StartScanning; +begin +end; + +procedure TSynFoldRanges.StopFoldRange(ALine, AFoldType: integer; AIndent : Integer); +begin + AddLineInfo(ALine, AFoldType, focClose, AIndent); +end; + +function TSynFoldRanges.StopScanning(Lines : TStrings) : Boolean; +{ + Returns true if fold ranges changed + Recreates FoldRanges if the uRESTDWPrivSynEdit lines are not updating +} +begin + Result := fRangesNeedFixing; + + if Result then begin + StoreCollapsedState; + RecreateFoldRanges(Lines); + RestoreCollapsedState; + fRangesNeedFixing := False; + end; +end; + +procedure TSynFoldRanges.StoreCollapsedState; +Var + FoldRange : TSynFoldRange; +begin + fCollapsedState.Clear; + for FoldRange in fRanges do + if FoldRange.Collapsed then + fCollapsedState.Add(FoldRange.FromLine); +end; + +{ TSynEditFoldRange } + +constructor TSynFoldRange.Create(AFromLine, AToLine, AFoldType: Integer; + AIndent : Integer; ACollapsed: Boolean); +begin + FromLine := AFromLine; + ToLine := AToLine; + FoldType := AFoldType; + Indent := AIndent; + Collapsed := ACollapsed; +end; + +function TSynFoldRange.GetLinesCollapsed: Integer; +begin + if Collapsed then + Result := ToLine - FromLine + else + Result := 0; +end; + +procedure TSynFoldRange.Move(Count: Integer); +begin + Inc(FromLine, Count); + Inc(ToLine, Count); +end; + +procedure TSynCodeFolding.Assign(Source: TPersistent); +begin + if Source is TSynCodeFolding then + begin + fIndentGuides := TSynCodeFolding(Source).fIndentGuides; + fCollapsedLineColor := TSynCodeFolding(Source).fCollapsedLineColor; + fFolderBarLinesColor := TSynCodeFolding(Source).fFolderBarLinesColor; + fIndentGuidesColor := TSynCodeFolding(Source).fIndentGuidesColor; + fShowCollapsedLine := TSynCodeFolding(Source).fShowCollapsedLine; + fShowHintMark := TSynCodeFolding(Source).fShowHintMark; + fGutterShapeSize := TSynCodeFolding(Source).fGutterShapeSize; + end + else + inherited Assign(Source); +end; + +constructor TSynCodeFolding.Create; +begin + fIndentGuides := True; + fCollapsedLineColor := clGrayText; + fFolderBarLinesColor := clGrayText; + fIndentGuidesColor := clGray; + fShowCollapsedLine := False; + fShowHintMark := True; + fGutterShapeSize := 11; +end; + +{ TSynFoldRanges.TLineFoldInfo } + +constructor TSynFoldRanges.TLineFoldInfo.Create(ALine: Integer; + AFoldOpenClose: TFoldOpenClose; AFoldType: Integer; AIndent : Integer); +begin + Line := ALine; + FoldOpenClose := AFoldOpenClose; + FoldType := AFoldType; + Indent := AIndent; +end; + +{ TSynCustomCodeFoldingHighlighter } + +procedure TSynCustomCodeFoldingHighlighter.AdjustFoldRanges( + FoldRanges: TSynFoldRanges; LinesToScan: TStrings); +begin + // Do nothing +end; + +function TSynCustomCodeFoldingHighlighter.GetHighlighterAttriAtRowCol( + const Lines: TStrings; const Line: Integer; + const Char: Integer): TSynHighlighterAttributes; +var + Token: string; + TokenType, Start: Integer; +begin + GetHighlighterAttriAtRowColEx(Lines, Line, Char, Token, TokenType, + Start, Result); +end; + +function TSynCustomCodeFoldingHighlighter.GetHighlighterAttriAtRowColEx( + const Lines: TStrings; const Line, Char: Integer; var Token: string; + var TokenType, Start: Integer; var Attri: TSynHighlighterAttributes): boolean; +var + LineText: string; +begin + if (Line >= 0) and (Line < Lines.Count) then + begin + LineText := Lines[Line]; + if Line = 0 then + ResetRange + else + SetRange(TSynEditStringList(Lines).Ranges[Line - 1]); + SetLine(LineText, Line); + if (Char > 0) and (Char <= Length(LineText)) then + while not GetEol do + begin + Start := GetTokenPos + 1; + Token := GetToken; + if (Char >= Start) and (Char < Start + Length(Token)) then + begin + Attri := GetTokenAttribute; + TokenType := GetTokenKind; + Result := True; + exit; + end; + Next; + end; + end; + Token := ''; + Attri := nil; + Result := False; +end; + +function TSynCustomCodeFoldingHighlighter.GetLineRange(Lines: TStrings; + Line: Integer): Pointer; +begin + if (Line >= 0) and (Line < Lines.Count) then + Result := TSynEditStringList(Lines).Ranges[Line] + else + Result := nil; +end; + +procedure TSynCustomCodeFoldingHighlighter.InitFoldRanges( + FoldRanges: TSynFoldRanges); +begin + FoldRanges.CodeFoldingMode := cfmStandard; +end; + +function TSynCustomCodeFoldingHighlighter.TabWidth( + LinesToScan: TStrings): integer; +begin + Result := TSynEditStringList(LinesToScan).TabWidth; +end; + +{ TSynCodeFolding } + +procedure TSynCodeFolding.SetCollapsedLineColor(const Value: TColor); +begin + if fCollapsedLineColor <> Value then begin + fCollapsedLineColor := Value; + if Assigned(fOnChange) then fOnChange(Self); + end; +end; + +procedure TSynCodeFolding.SetFolderBarLinesColor(const Value: TColor); +begin + if fFolderBarLinesColor <> Value then begin + fFolderBarLinesColor := Value; + if Assigned(fOnChange) then fOnChange(Self); + end; +end; + +procedure TSynCodeFolding.SetGutterShapeSize(const Value: Integer); +Var + NewValue: Integer; +begin + NewValue := Value; + if not Odd(NewValue) then + Dec(NewValue); + if fGutterShapeSize <> NewValue then begin + fGutterShapeSize := NewValue; + if Assigned(fOnChange) then fOnChange(Self); + end; +end; + +procedure TSynCodeFolding.SetIndentGuides(const Value: Boolean); +begin + if fIndentGuides <> Value then begin + fIndentGuides := Value; + if Assigned(fOnChange) then fOnChange(Self); + end; +end; + +procedure TSynCodeFolding.SetIndentGuidesColor(const Value: TColor); +begin + if fIndentGuidesColor <> Value then begin + fIndentGuidesColor := Value; + if Assigned(fOnChange) then fOnChange(Self); + end; +end; + +procedure TSynCodeFolding.SetShowHintMark(const Value: Boolean); +begin + if fShowHintMark <> Value then begin + fShowHintMark := Value; + if Assigned(fOnChange) then fOnChange(Self); + end; +end; + +procedure TSynCodeFolding.SetShowCollapsedLine(const Value: Boolean); +begin + if fShowCollapsedLine <> Value then begin + fShowCollapsedLine := Value; + if Assigned(fOnChange) then fOnChange(Self); + end; +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditHighlighter.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditHighlighter.pas new file mode 100644 index 000000000..b1c6d30cb --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditHighlighter.pas @@ -0,0 +1,1318 @@ +{------------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: uRESTDWPrivSynEditHighlighter.pas, released 2000-04-07. + +The Original Code is based on mwHighlighter.pas by Martin Waldenburg, part of +the mwEdit component suite. +Portions created by Martin Waldenburg are Copyright (C) 1998 Martin Waldenburg. +Unicode translation by Maël Hörz. +Options property added by CodehunterWorks +All Rights Reserved. + +Contributors to the uRESTDWPrivSynEdit and mwEdit projects are listed in the +Contributors.txt file. + +$Id: uRESTDWPrivSynEditHighlighter.pas,v 1.9.1 2012/09/12 08:17:19 CodehunterWorks Exp $ + +You may retrieve the latest version of this file at the uRESTDWPrivSynEdit home page, +located at http://uRESTDWPrivSynEdit.SourceForge.net + +Known Issues: +-------------------------------------------------------------------------------} + +unit uRESTDWPrivSynEditHighlighter; + +{$I uRESTDWPrivSynEdit.inc} + +interface + +uses + Graphics, + Windows, + Registry, + IniFiles, + uRESTDWPrivSynEditTypes, + uRESTDWPrivSynEditMiscClasses, + uRESTDWPrivSynUnicode, + SysUtils, + Classes, + uRESTDWPrivSynEditHighlighterOptions; + +type + TBetterRegistry = uRESTDWPrivSynEditMiscClasses.TBetterRegistry; + +type + TSynHighlighterAttributes = class(TPersistent) + private + FBackground: TColor; + FBackgroundDefault: TColor; + FForeground: TColor; + FForegroundDefault: TColor; + FFriendlyName: UnicodeString; + FName: string; + FStyle: TFontStyles; + FStyleDefault: TFontStyles; + FOnChange: TNotifyEvent; + procedure Changed; virtual; + function GetBackgroundColorStored: Boolean; + function GetForegroundColorStored: Boolean; + function GetFontStyleStored: Boolean; + procedure SetBackground(Value: TColor); + procedure SetForeground(Value: TColor); + procedure SetStyle(Value: TFontStyles); + function GetStyleFromInt: Integer; + procedure SetStyleFromInt(const Value: Integer); + public + procedure Assign(Source: TPersistent); override; + procedure AssignColorAndStyle(Source: TSynHighlighterAttributes); + constructor Create(AName: string); overload; + constructor Create(AName: string; AFriendlyName: UnicodeString); overload; + procedure InternalSaveDefaultValues; + + function LoadFromBorlandRegistry(RootKey: HKEY; AttrKey, AttrName: string; + OldStyle: Boolean): Boolean; virtual; + function LoadFromRegistry(Reg: TBetterRegistry): Boolean; + function SaveToRegistry(Reg: TBetterRegistry): Boolean; +//Fix type changed to TCustomIniFile for use both TMemIniFile and TIniFile + function LoadFromFile(Ini: TCustomIniFile): Boolean; + function SaveToFile(Ini: TCustomIniFile): Boolean; + public + procedure SetColors(Foreground, Background: TColor); + property FriendlyName: UnicodeString read FFriendlyName; + property IntegerStyle: Integer read GetStyleFromInt write SetStyleFromInt; + property Name: string read FName; + property OnChange: TNotifyEvent read FOnChange write FOnChange; + published + property Background: TColor read FBackground write SetBackground + stored GetBackgroundColorStored; + property Foreground: TColor read FForeground write SetForeground + stored GetForegroundColorStored; + property Style: TFontStyles read FStyle write SetStyle + stored GetFontStyleStored; + end; + + TSynHighlighterCapability = ( + hcUserSettings, // supports Enum/UseUserSettings + hcRegistry // supports LoadFrom/SaveToRegistry + ); + + TSynHighlighterCapabilities = set of TSynHighlighterCapability; + +const + SYN_ATTR_COMMENT = 0; + SYN_ATTR_IDENTIFIER = 1; + SYN_ATTR_KEYWORD = 2; + SYN_ATTR_STRING = 3; + SYN_ATTR_WHITESPACE = 4; + SYN_ATTR_SYMBOL = 5; + +type + TSynCustomHighlighter = class(TComponent) + private + FAttributes: TStringList; + FAttrChangeHooks: TSynNotifyEventChain; + FUpdateCount: Integer; + FEnabled: Boolean; + FAdditionalWordBreakChars: TSysCharSet; + FAdditionalIdentChars: TSysCharSet; + FExportName: string; + FOptions: TSynEditHighlighterOptions; + function GetExportName: string; + procedure SetEnabled(const Value: Boolean); + procedure SetAdditionalIdentChars(const Value: TSysCharSet); + procedure SetAdditionalWordBreakChars(const Value: TSysCharSet); + protected + FCasedLine: PWideChar; + FCasedLineStr: UnicodeString; + FCaseSensitive: Boolean; + FDefaultFilter: string; + FExpandedLine: PWideChar; + FExpandedLineLen: Integer; + FExpandedLineStr: UnicodeString; + FExpandedTokenPos: Integer; + FLine: PWideChar; + FLineLen: Integer; + FLineStr: UnicodeString; + FLineNumber: Integer; + FStringLen: Integer; + FToIdent: PWideChar; + FTokenPos: Integer; + FUpdateChange: Boolean; + Run: Integer; + FExpandedRun: Integer; + FOldRun: Integer; + procedure Loaded; override; + procedure AddAttribute(Attri: TSynHighlighterAttributes); + procedure DefHighlightChange(Sender: TObject); + procedure DefineProperties(Filer: TFiler); override; + procedure FreeHighlighterAttributes; + function GetAttribCount: Integer; virtual; + function GetAttribute(Index: Integer): TSynHighlighterAttributes; virtual; + function GetDefaultAttribute(Index: Integer): TSynHighlighterAttributes; + virtual; abstract; + function GetDefaultFilter: string; virtual; + function GetSampleSource: UnicodeString; virtual; + procedure DoSetLine(const Value: UnicodeString; LineNumber: Integer); virtual; + function IsCurrentToken(const Token: UnicodeString): Boolean; virtual; + function IsFilterStored: Boolean; virtual; + function IsLineEnd(Run: Integer): Boolean; virtual; + procedure SetAttributesOnChange(AEvent: TNotifyEvent); + procedure SetDefaultFilter(Value: string); virtual; + procedure SetSampleSource(Value: UnicodeString); virtual; + protected + function GetCapabilitiesProp: TSynHighlighterCapabilities; + function GetFriendlyLanguageNameProp: UnicodeString; + function GetLanguageNameProp: string; + public + class function GetCapabilities: TSynHighlighterCapabilities; virtual; + class function GetFriendlyLanguageName: UnicodeString; virtual; + class function GetLanguageName: string; virtual; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure Assign(Source: TPersistent); override; + procedure BeginUpdate; + procedure EndUpdate; + function GetEol: Boolean; virtual; abstract; + function GetExpandedToken: UnicodeString; virtual; + function GetExpandedTokenPos: Integer; virtual; + function GetKeyWords(TokenKind: Integer): UnicodeString; virtual; + function GetRange: Pointer; virtual; + function GetToken: UnicodeString; virtual; + function GetTokenAttribute: TSynHighlighterAttributes; virtual; abstract; + function GetTokenKind: Integer; virtual; abstract; + function GetTokenPos: Integer; virtual; + function IsKeyword(const AKeyword: UnicodeString): Boolean; virtual; + procedure Next; virtual; + procedure NextToEol; + function PosToExpandedPos(Pos: Integer): Integer; + procedure SetLineExpandedAtWideGlyphs(const Line, ExpandedLine: UnicodeString; + LineNumber: Integer); virtual; + procedure SetLine(const Value: UnicodeString; LineNumber: Integer); virtual; + procedure SetRange(Value: Pointer); virtual; + procedure ResetRange; virtual; + function UseUserSettings(settingIndex: Integer): Boolean; virtual; + procedure EnumUserSettings(Settings: TStrings); virtual; + + function LoadFromRegistry(RootKey: HKEY; Key: string): Boolean; virtual; + function SaveToRegistry(RootKey: HKEY; Key: string): Boolean; virtual; + function LoadFromFile(AFileName: string): Boolean; + function SaveToFile(AFileName: string): Boolean; + + procedure HookAttrChangeEvent(ANotifyEvent: TNotifyEvent); + procedure UnhookAttrChangeEvent(ANotifyEvent: TNotifyEvent); + function IsIdentChar(AChar: WideChar): Boolean; virtual; + function IsWhiteChar(AChar: WideChar): Boolean; virtual; + function IsWordBreakChar(AChar: WideChar): Boolean; virtual; + property FriendlyLanguageName: UnicodeString read GetFriendlyLanguageNameProp; + property LanguageName: string read GetLanguageNameProp; + public + property AdditionalIdentChars: TSysCharSet read FAdditionalIdentChars write SetAdditionalIdentChars; + property AdditionalWordBreakChars: TSysCharSet read FAdditionalWordBreakChars write SetAdditionalWordBreakChars; + property AttrCount: Integer read GetAttribCount; + property Attribute[Index: Integer]: TSynHighlighterAttributes + read GetAttribute; + property Capabilities: TSynHighlighterCapabilities read GetCapabilitiesProp; + property SampleSource: UnicodeString read GetSampleSource write SetSampleSource; + property CommentAttribute: TSynHighlighterAttributes + index SYN_ATTR_COMMENT read GetDefaultAttribute; + property IdentifierAttribute: TSynHighlighterAttributes + index SYN_ATTR_IDENTIFIER read GetDefaultAttribute; + property KeywordAttribute: TSynHighlighterAttributes + index SYN_ATTR_KEYWORD read GetDefaultAttribute; + property StringAttribute: TSynHighlighterAttributes + index SYN_ATTR_STRING read GetDefaultAttribute; + property SymbolAttribute: TSynHighlighterAttributes + index SYN_ATTR_SYMBOL read GetDefaultAttribute; + property WhitespaceAttribute: TSynHighlighterAttributes + index SYN_ATTR_WHITESPACE read GetDefaultAttribute; + property ExportName: string read GetExportName; + published + property DefaultFilter: string read GetDefaultFilter write SetDefaultFilter + stored IsFilterStored; + property Enabled: Boolean read FEnabled write SetEnabled default True; + property Options: TSynEditHighlighterOptions read FOptions write FOptions; // <-- Codehunter patch + end; + + TSynCustomHighlighterClass = class of TSynCustomHighlighter; + +{$IFNDEF SYN_CPPB_1} + TSynHighlighterList = class(TList) + private + FHighlighterList: TList; + function GetItem(Index: Integer): TSynCustomHighlighterClass; + public + constructor Create; + destructor Destroy; override; + function Count: Integer; + function FindByFriendlyName(FriendlyName: string): Integer; + function FindByName(Name: string): Integer; + function FindByClass(Comp: TComponent): Integer; + property Items[Index: Integer]: TSynCustomHighlighterClass + read GetItem; default; + end; + + procedure RegisterPlaceableHighlighter(highlighter: + TSynCustomHighlighterClass); + function GetPlaceableHighlighters: TSynHighlighterList; +{$ENDIF} + +implementation + +uses + uRESTDWPrivSynEditMiscProcs, +{$IFDEF UNICODE} + WideStrUtils, +{$ENDIF} + uRESTDWPrivSynEditStrConst; + +{$IFNDEF SYN_CPPB_1} +{ THighlighterList } + +function TSynHighlighterList.Count: Integer; +begin + Result := FHighlighterList.Count; +end; + +constructor TSynHighlighterList.Create; +begin + inherited Create; + FHighlighterList := TList.Create; +end; + +destructor TSynHighlighterList.Destroy; +begin + FHighlighterList.Free; + inherited; +end; + +function TSynHighlighterList.FindByClass(Comp: TComponent): Integer; +var + i: Integer; +begin + Result := -1; + for i := 0 to Count - 1 do + begin + if Comp is Items[i] then + begin + Result := i; + Exit; + end; + end; +end; + +function TSynHighlighterList.FindByFriendlyName(FriendlyName: string): Integer; +var + i: Integer; +begin + Result := -1; + for i := 0 to Count - 1 do + begin + if Items[i].GetFriendlyLanguageName = FriendlyName then + begin + Result := i; + Exit; + end; + end; +end; + +function TSynHighlighterList.FindByName(Name: string): Integer; +var + i: Integer; +begin + Result := -1; + for i := 0 to Count - 1 do + begin + if Items[i].GetLanguageName = Name then + begin + Result := i; + Exit; + end; + end; +end; + +function TSynHighlighterList.GetItem(Index: Integer): TSynCustomHighlighterClass; +begin + Result := TSynCustomHighlighterClass(FHighlighterList[Index]); +end; + +var + G_PlaceableHighlighters: TSynHighlighterList; + + function GetPlaceableHighlighters: TSynHighlighterList; + begin + Result := G_PlaceableHighlighters; + end; + + procedure RegisterPlaceableHighlighter(highlighter: TSynCustomHighlighterClass); + begin + if G_PlaceableHighlighters.FHighlighterList.IndexOf(highlighter) < 0 then + G_PlaceableHighlighters.FHighlighterList.Add(highlighter); + end; +{$ENDIF} + +{ TSynHighlighterAttributes } + +procedure TSynHighlighterAttributes.Assign(Source: TPersistent); +begin + if Source is TSynHighlighterAttributes then + begin + FName := TSynHighlighterAttributes(Source).FName; + AssignColorAndStyle(TSynHighlighterAttributes(Source)); + end + else + inherited Assign(Source); +end; + +procedure TSynHighlighterAttributes.AssignColorAndStyle(Source: TSynHighlighterAttributes); +var + bChanged: Boolean; +begin + bChanged := False; + if FBackground <> Source.FBackground then + begin + FBackground := Source.FBackground; + bChanged := True; + end; + if FForeground <> Source.FForeground then + begin + FForeground := Source.FForeground; + bChanged := True; + end; + if FStyle <> Source.FStyle then + begin + FStyle := Source.FStyle; + bChanged := True; + end; + if bChanged then + Changed; +end; + + +procedure TSynHighlighterAttributes.Changed; +begin + if Assigned(FOnChange) then + FOnChange(Self); +end; + +constructor TSynHighlighterAttributes.Create(AName: string); +begin + Create(AName, AName); +end; + +constructor TSynHighlighterAttributes.Create(AName: string; AFriendlyName: UnicodeString); +begin + inherited Create; + Background := clNone; + Foreground := clNone; + FName := AName; + FFriendlyName := AFriendlyName; +end; + +function TSynHighlighterAttributes.GetBackgroundColorStored: Boolean; +begin + Result := FBackground <> FBackgroundDefault; +end; + +function TSynHighlighterAttributes.GetForegroundColorStored: Boolean; +begin + Result := FForeground <> FForegroundDefault; +end; + +function TSynHighlighterAttributes.GetFontStyleStored: Boolean; +begin + Result := FStyle <> FStyleDefault; +end; + +procedure TSynHighlighterAttributes.InternalSaveDefaultValues; +begin + FForegroundDefault := FForeground; + FBackgroundDefault := FBackground; + FStyleDefault := FStyle; +end; + +function TSynHighlighterAttributes.LoadFromBorlandRegistry(RootKey: HKEY; + AttrKey, AttrName: string; OldStyle: Boolean): Boolean; + // How the highlighting information is stored: + // Delphi 1.0: + // I don't know and I don't care. + // Delphi 2.0 & 3.0: + // In the registry branch HKCU\Software\Borland\Delphi\x.0\Highlight + // where x=2 or x=3. + // Each entry is one string value, encoded as + // ,,,,,, + // Example: + // 0,16777215,BI,0,1,0,15 + // foreground color (RGB): 0 + // background color (RGB): 16777215 ($FFFFFF) + // font style: BI (bold italic), possible flags: B(old), I(talic), U(nderline) + // default foreground: no, specified color will be used (black (0) is used when this flag is 1) + // default background: yes, white ($FFFFFF, 15) will be used for background + // foreground index: 0 (foreground index (Pal16), corresponds to foreground RGB color) + // background index: 15 (background index (Pal16), corresponds to background RGB color) + // Delphi 4.0 & 5.0: + // In the registry branch HKCU\Software\Borland\Delphi\4.0\Editor\Highlight. + // Each entry is subkey containing several values: + // Foreground Color: foreground index (Pal16), 0..15 (dword) + // Background Color: background index (Pal16), 0..15 (dword) + // Bold: fsBold yes/no, 0/True (string) + // Italic: fsItalic yes/no, 0/True (string) + // Underline: fsUnderline yes/no, 0/True (string) + // Default Foreground: use default foreground (clBlack) yes/no, False/-1 (string) + // Default Background: use default backround (clWhite) yes/no, False/-1 (string) +const + Pal16: array [0..15] of TColor = ( + clBlack, clMaroon, clGreen, clOlive, clNavy, clPurple, clTeal, clLtGray, + clDkGray, clRed, clLime, clYellow, clBlue, clFuchsia, clAqua, clWhite + ); + + function LoadOldStyle(RootKey: HKEY; AttrKey, AttrName: string): Boolean; + var + descript: string; + fgColRGB: string; + bgColRGB: string; + fontStyle: string; + fgDefault: string; + bgDefault: string; + fgIndex16: string; + bgIndex16: string; + reg: TBetterRegistry; + + function Get(var Name: string): string; + var + p: Integer; + begin + p := Pos(',', Name); + if p = 0 then p := Length(Name) + 1; + Result := Copy(name, 1, p - 1); + name := Copy(name, p + 1, Length(name) - p); + end; + + begin { LoadOldStyle } + Result := False; + try + reg := TBetterRegistry.Create; + reg.RootKey := RootKey; + try + with reg do + begin + if OpenKeyReadOnly(AttrKey) then + begin + try + if ValueExists(AttrName) then + begin + descript := ReadString(AttrName); + fgColRGB := Get(descript); + bgColRGB := Get(descript); + fontStyle := Get(descript); + fgDefault := Get(descript); + bgDefault := Get(descript); + fgIndex16 := Get(descript); + bgIndex16 := Get(descript); + if bgDefault = '1' then + Background := clWindow + else + Background := Pal16[StrToInt(bgIndex16)]; + if fgDefault = '1' then + Foreground := clWindowText + else + Foreground := Pal16[StrToInt(fgIndex16)]; + Style := []; + if Pos('B', fontStyle) > 0 then Style := Style + [fsBold]; + if Pos('I', fontStyle) > 0 then Style := Style + [fsItalic]; + if Pos('U', fontStyle) > 0 then Style := Style + [fsUnderline]; + Result := True; + end; + finally + CloseKey; + end; + end; // if + end; // with + finally + reg.Free; + end; + except + end; + end; { LoadOldStyle } + + function LoadNewStyle(RootKey: HKEY; AttrKey, AttrName: string): Boolean; + var + fgColor: Integer; + bgColor: Integer; + fontBold: string; + fontItalic: string; + fontUnderline: string; + fgDefault: string; + bgDefault: string; + reg: TBetterRegistry; + + function IsTrue(Value: string): Boolean; + begin + Result := not ((UpperCase(Value) = 'FALSE') or (Value = '0')); + end; { IsTrue } + + begin + Result := False; + try + reg := TBetterRegistry.Create; + reg.RootKey := RootKey; + try + with reg do + begin + if OpenKeyReadOnly(AttrKey + '\' + AttrName) then + begin + try + if ValueExists('Foreground Color') + then fgColor := Pal16[ReadInteger('Foreground Color')] + else if ValueExists('Foreground Color New') then + fgColor := StringToColor(ReadString('Foreground Color New')) + else + Exit; + if ValueExists('Background Color') + then bgColor := Pal16[ReadInteger('Background Color')] + else if ValueExists('Background Color New') then + bgColor := StringToColor(ReadString('Background Color New')) + else + Exit; + if ValueExists('Bold') + then fontBold := ReadString('Bold') + else Exit; + if ValueExists('Italic') + then fontItalic := ReadString('Italic') + else Exit; + if ValueExists('Underline') + then fontUnderline := ReadString('Underline') + else Exit; + if ValueExists('Default Foreground') + then fgDefault := ReadString('Default Foreground') + else Exit; + if ValueExists('Default Background') + then bgDefault := ReadString('Default Background') + else Exit; + if IsTrue(bgDefault) + then Background := clWindow + else Background := bgColor; + if IsTrue(fgDefault) + then Foreground := clWindowText + else Foreground := fgColor; + Style := []; + if IsTrue(fontBold) then Style := Style + [fsBold]; + if IsTrue(fontItalic) then Style := Style + [fsItalic]; + if IsTrue(fontUnderline) then Style := Style + [fsUnderline]; + Result := True; + finally + CloseKey; + end; + end; // if + end; // with + finally + reg.Free; + end; + except + end; + end; { LoadNewStyle } + +begin + if OldStyle then + Result := LoadOldStyle(RootKey, AttrKey, AttrName) + else + Result := LoadNewStyle(RootKey, AttrKey, AttrName); +end; { TSynHighlighterAttributes.LoadFromBorlandRegistry } + +procedure TSynHighlighterAttributes.SetBackground(Value: TColor); +begin + if FBackground <> Value then + begin + FBackground := Value; + Changed; + end; +end; + +procedure TSynHighlighterAttributes.SetColors(Foreground, Background: TColor); +begin + if (FForeground <> Foreground) or (FBackground <> Background) then + begin + FForeground := Foreground; + FBackground := Background; + Changed; + end; +end; + +procedure TSynHighlighterAttributes.SetForeground(Value: TColor); +begin + if FForeground <> Value then + begin + FForeground := Value; + Changed; + end; +end; + +procedure TSynHighlighterAttributes.SetStyle(Value: TFontStyles); +begin + if FStyle <> Value then + begin + FStyle := Value; + Changed; + end; +end; + +function TSynHighlighterAttributes.LoadFromRegistry(Reg: TBetterRegistry): Boolean; +var + Key: string; +begin + Key := Reg.CurrentPath; + if Reg.KeyExists(Name) then + begin + if Reg.OpenKeyReadOnly(Name) then + begin + if Reg.ValueExists('Background') then + Background := Reg.ReadInteger('Background'); + if Reg.ValueExists('Foreground') then + Foreground := Reg.ReadInteger('Foreground'); + if Reg.ValueExists('Style') then + IntegerStyle := Reg.ReadInteger('Style'); + reg.OpenKeyReadOnly('\' + Key); + Result := True; + end + else + Result := False; + end + else + Result := False; +end; + +function TSynHighlighterAttributes.SaveToRegistry(Reg: TBetterRegistry): Boolean; +var + Key: string; +begin + Key := Reg.CurrentPath; + if Reg.OpenKey(Name, True) then + begin + Reg.WriteInteger('Background', Background); + Reg.WriteInteger('Foreground', Foreground); + Reg.WriteInteger('Style', IntegerStyle); + reg.OpenKey('\' + Key, False); + Result := True; + end + else + Result := False; +end; + +function TSynHighlighterAttributes.LoadFromFile(Ini : TCustomIniFile): boolean; +var + S: TStringList; +begin + S := TStringList.Create; + try + Ini.ReadSection(Name, S); + if S.Count > 0 then + begin + if S.IndexOf('Background') <> -1 then + Background := Ini.ReadInteger(Name, 'Background', Background); + if S.IndexOf('Foreground') <> -1 then + Foreground := Ini.ReadInteger(Name, 'Foreground', Foreground); + if S.IndexOf('Style') <> -1 then + IntegerStyle := Ini.ReadInteger(Name, 'Style', IntegerStyle); + Result := true; + end + else + Result := False; + finally + S.Free; + end; +end; + +function TSynHighlighterAttributes.SaveToFile(Ini : TCustomIniFile): boolean; +begin + Ini.WriteInteger(Name, 'Background', Background); + Ini.WriteInteger(Name, 'Foreground', Foreground); + Ini.WriteInteger(Name, 'Style', IntegerStyle); + Result := True; +end; + +function TSynHighlighterAttributes.GetStyleFromInt: Integer; +begin + if fsBold in Style then Result := 1 else Result := 0; + if fsItalic in Style then Result := Result + 2; + if fsUnderline in Style then Result:= Result + 4; + if fsStrikeout in Style then Result:= Result + 8; +end; + +procedure TSynHighlighterAttributes.SetStyleFromInt(const Value: Integer); +begin + if Value and $1 = 0 then Style:= [] else Style := [fsBold]; + if Value and $2 <> 0 then Style:= Style + [fsItalic]; + if Value and $4 <> 0 then Style:= Style + [fsUnderline]; + if Value and $8 <> 0 then Style:= Style + [fsStrikeout]; +end; + +{ TSynCustomHighlighter } + +constructor TSynCustomHighlighter.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + FAttributes := TStringList.Create; + FAttributes.Duplicates := dupError; + FAttributes.Sorted := True; + FAttrChangeHooks := TSynNotifyEventChain.CreateEx(Self); + FDefaultFilter := ''; + FEnabled := True; + FOptions:= TSynEditHighlighterOptions.Create; // <-- Codehunter patch +end; + +destructor TSynCustomHighlighter.Destroy; +begin + inherited Destroy; + FreeHighlighterAttributes; + FAttributes.Free; + FAttrChangeHooks.Free; + FOptions.Free; // <-- Codehunter patch +end; + +procedure TSynCustomHighlighter.BeginUpdate; +begin + Inc(FUpdateCount); +end; + +procedure TSynCustomHighlighter.EndUpdate; +begin + if FUpdateCount > 0 then + begin + Dec(FUpdateCount); + if (FUpdateCount = 0) and FUpdateChange then + begin + FUpdateChange := False; + DefHighlightChange(nil); + end; + end; +end; + +procedure TSynCustomHighlighter.FreeHighlighterAttributes; +var + i: Integer; +begin + if FAttributes <> nil then + begin + for i := FAttributes.Count - 1 downto 0 do + TSynHighlighterAttributes(FAttributes.Objects[i]).Free; + FAttributes.Clear; + end; +end; + +procedure TSynCustomHighlighter.Assign(Source: TPersistent); +var + Src: TSynCustomHighlighter; + i, j: Integer; + AttriName: string; + SrcAttri: TSynHighlighterAttributes; +begin + if (Source <> nil) and (Source is TSynCustomHighlighter) then + begin + Src := TSynCustomHighlighter(Source); + for i := 0 to AttrCount - 1 do + begin + // assign first attribute with the same name + AttriName := Attribute[i].Name; + for j := 0 to Src.AttrCount - 1 do + begin + SrcAttri := Src.Attribute[j]; + if AttriName = SrcAttri.Name then + begin + Attribute[i].Assign(SrcAttri); + Break; + end; + end; + end; + // assign the sample source text only if same or descendant class + if Src is ClassType then + SampleSource := Src.SampleSource; + //fWordBreakChars := Src.WordBreakChars; //TODO: does this make sense anyway? + DefaultFilter := Src.DefaultFilter; + Enabled := Src.Enabled; + end + else + inherited Assign(Source); +end; + +procedure TSynCustomHighlighter.EnumUserSettings(Settings: TStrings); +begin + Settings.Clear; +end; + +function TSynCustomHighlighter.UseUserSettings(settingIndex: Integer): Boolean; +begin + Result := False; +end; + +function TSynCustomHighlighter.LoadFromRegistry(RootKey: HKEY; + Key: string): Boolean; +var + r: TBetterRegistry; + i: Integer; +begin + r := TBetterRegistry.Create; + try + r.RootKey := RootKey; + if r.OpenKeyReadOnly(Key) then + begin + Result := True; + for i := 0 to AttrCount - 1 do + Result := Attribute[i].LoadFromRegistry(r) and Result; + end + else + Result := False; + finally + r.Free; + end; +end; + +function TSynCustomHighlighter.SaveToRegistry(RootKey: HKEY; + Key: string): Boolean; +var + r: TBetterRegistry; + i: Integer; +begin + r := TBetterRegistry.Create; + try + r.RootKey := RootKey; + if r.OpenKey(Key,True) then + begin + Result := True; + for i := 0 to AttrCount - 1 do + Result := Attribute[i].SaveToRegistry(r) and Result; + end + else + Result := False; + finally + r.Free; + end; +end; + +function TSynCustomHighlighter.LoadFromFile(AFileName : String): Boolean; +var + AIni: TIniFile; + i: Integer; +begin + AIni := TIniFile.Create(AFileName); + try + with AIni do + begin + Result := True; + for i := 0 to AttrCount - 1 do + Result := Attribute[i].LoadFromFile(AIni) and Result; + end; + finally + AIni.Free; + end; +end; + +function TSynCustomHighlighter.SaveToFile(AFileName : String): Boolean; +var + AIni: TIniFile; + i: Integer; +begin + AIni := TIniFile.Create(AFileName); + try + with AIni do + begin + Result := True; + for i := 0 to AttrCount - 1 do + Result := Attribute[i].SaveToFile(AIni) and Result; + end; + finally + AIni.Free; + end; +end; + +procedure TSynCustomHighlighter.AddAttribute(Attri: TSynHighlighterAttributes); +begin + FAttributes.AddObject(Attri.Name, Attri); +end; + +procedure TSynCustomHighlighter.DefHighlightChange(Sender: TObject); +begin + if FUpdateCount > 0 then + FUpdateChange := True + else if not(csLoading in ComponentState) then + begin + FAttrChangeHooks.Sender := Sender; + FAttrChangeHooks.Fire; + end; +end; + +procedure TSynCustomHighlighter.DefineProperties(Filer: TFiler); +begin + inherited; +{$IFNDEF UNICODE} + UnicodeDefineProperties(Filer, Self); +{$ENDIF} +end; + +function TSynCustomHighlighter.GetAttribCount: Integer; +begin + Result := FAttributes.Count; +end; + +function TSynCustomHighlighter.GetAttribute(Index: Integer): + TSynHighlighterAttributes; +begin + Result := nil; + if (Index >= 0) and (Index < FAttributes.Count) then + Result := TSynHighlighterAttributes(FAttributes.Objects[Index]); +end; + +class function TSynCustomHighlighter.GetCapabilities: TSynHighlighterCapabilities; +begin + Result := [hcRegistry]; //registry save/load supported by default +end; + +function TSynCustomHighlighter.GetCapabilitiesProp: TSynHighlighterCapabilities; +begin + Result := GetCapabilities; +end; + +function TSynCustomHighlighter.GetDefaultFilter: string; +begin + Result := FDefaultFilter; +end; + +function TSynCustomHighlighter.GetExpandedTokenPos: Integer; +begin + if FExpandedLine = nil then + Result := FTokenPos + else + Result := FExpandedTokenPos; +end; + +function TSynCustomHighlighter.GetExportName: string; +begin + if FExportName = '' then + FExportName := uRESTDWPrivSynEditMiscProcs.DeleteTypePrefixAndSynSuffix(ClassName); + Result := FExportName; +end; + +function TSynCustomHighlighter.GetExpandedToken: UnicodeString; +var + Len: Integer; +begin + if FExpandedLine = nil then + begin + Result := GetToken; + Exit; + end; + + Len := FExpandedRun - FExpandedTokenPos; + SetLength(Result, Len); + if Len > 0 then + WStrLCopy(@Result[1], FExpandedLine + FExpandedTokenPos, Len); +end; + +class function TSynCustomHighlighter.GetFriendlyLanguageName: UnicodeString; +begin +{$IFDEF SYN_DEVELOPMENT_CHECKS} + raise Exception.CreateFmt('%s.GetFriendlyLanguageName not implemented', [ClassName]); +{$ENDIF} + Result := SYNS_FriendlyLangUnknown; +end; + +class function TSynCustomHighlighter.GetLanguageName: string; +begin +{$IFDEF SYN_DEVELOPMENT_CHECKS} + raise Exception.CreateFmt('%s.GetLanguageName not implemented', [ClassName]); +{$ENDIF} + Result := SYNS_LangUnknown; +end; + +function TSynCustomHighlighter.GetFriendlyLanguageNameProp: UnicodeString; +begin + Result := GetFriendlyLanguageName; +end; + +function TSynCustomHighlighter.GetLanguageNameProp: string; +begin + Result := GetLanguageName; +end; + +function TSynCustomHighlighter.GetRange: Pointer; +begin + Result := nil; +end; + +function TSynCustomHighlighter.GetToken: UnicodeString; +var + Len: Integer; +begin + Len := Run - FTokenPos; + SetLength(Result, Len); + if Len > 0 then + WStrLCopy(@Result[1], FCasedLine + FTokenPos, Len); +end; + +function TSynCustomHighlighter.GetTokenPos: Integer; +begin + Result := FTokenPos; +end; + +function TSynCustomHighlighter.GetKeyWords(TokenKind: Integer): UnicodeString; +begin + Result := ''; +end; + +function TSynCustomHighlighter.GetSampleSource: UnicodeString; +begin + Result := ''; +end; + +procedure TSynCustomHighlighter.HookAttrChangeEvent(ANotifyEvent: TNotifyEvent); +begin + FAttrChangeHooks.Add(ANotifyEvent); +end; + +function TSynCustomHighlighter.IsCurrentToken(const Token: UnicodeString): Boolean; +var + I: Integer; + Temp: PWideChar; +begin + Temp := FToIdent; + if Length(Token) = FStringLen then + begin + Result := True; + for i := 1 to FStringLen do + begin + if Temp^ <> Token[i] then + begin + Result := False; + Break; + end; + Inc(Temp); + end; + end + else + Result := False; +end; + +function TSynCustomHighlighter.IsFilterStored: Boolean; +begin + Result := True; +end; + +function TSynCustomHighlighter.IsIdentChar(AChar: WideChar): Boolean; +begin + if IsWordBreakChar(Achar) then + Result := False + else + Result := True; +end; + +function TSynCustomHighlighter.IsKeyword(const AKeyword: UnicodeString): Boolean; +begin + Result := False; +end; + +function TSynCustomHighlighter.IsLineEnd(Run: Integer): Boolean; +begin + Result := (Run >= FLineLen) or (FLine[Run] = #10) or (FLine[Run] = #13); +end; + +function TSynCustomHighlighter.IsWhiteChar(AChar: WideChar): Boolean; +begin + case AChar of + #0..#32: + Result := True; + else + Result := not (IsIdentChar(AChar) or IsWordBreakChar(AChar)) + end +end; + +function TSynCustomHighlighter.IsWordBreakChar(AChar: WideChar): Boolean; +begin + case AChar of + #0..#32, '.', ',', ';', ':', '"', '''', WideChar(#$00B4), WideChar(#$0060), + WideChar(#$00B0), '^', '!', '?', '&', '$', '@', WideChar(#$00A7), '%', '#', + '~', '[', ']', '(', ')', '{', '}', '<', '>', '-', '=', '+', '*', '/', '\', + '|': + Result := True; + else + Result := False; + end; +end; + +procedure TSynCustomHighlighter.Next; +var + Delta: Integer; +begin + if FOldRun = Run then Exit; + + FExpandedTokenPos := FExpandedRun; + if FExpandedLine = nil then Exit; + + Delta := Run - FOldRun; + while Delta > 0 do + begin + while FExpandedLine[FExpandedRun] = FillerChar do + Inc(FExpandedRun); + Inc(FExpandedRun); + Dec(Delta); + end; + FOldRun := Run; +end; + +procedure TSynCustomHighlighter.NextToEol; +begin + while not GetEol do Next; +end; + +procedure TSynCustomHighlighter.ResetRange; +begin +end; + +procedure TSynCustomHighlighter.SetAdditionalIdentChars( + const Value: TSysCharSet); +begin + FAdditionalIdentChars := Value; +end; + +procedure TSynCustomHighlighter.SetAdditionalWordBreakChars( + const Value: TSysCharSet); +begin + FAdditionalWordBreakChars := Value; +end; + +procedure TSynCustomHighlighter.SetAttributesOnChange(AEvent: TNotifyEvent); +var + i: Integer; + Attri: TSynHighlighterAttributes; +begin + for i := FAttributes.Count - 1 downto 0 do + begin + Attri := TSynHighlighterAttributes(FAttributes.Objects[i]); + if Attri <> nil then + begin + Attri.OnChange := AEvent; + Attri.InternalSaveDefaultValues; + end; + end; +end; + +procedure TSynCustomHighlighter.SetLineExpandedAtWideGlyphs(const Line, + ExpandedLine: UnicodeString; LineNumber: Integer); +begin + FExpandedLineStr := ExpandedLine; + FExpandedLine := PWideChar(FExpandedLineStr); + FExpandedLineLen := Length(FExpandedLineStr); + DoSetLine(Line, LineNumber); + Next; +end; + +procedure TSynCustomHighlighter.SetLine(const Value: UnicodeString; LineNumber: Integer); +begin + FExpandedLineStr := ''; + FExpandedLine := nil; + FExpandedLineLen := 0; + DoSetLine(Value, LineNumber); + Next; +end; + +procedure TSynCustomHighlighter.DoSetLine(const Value: UnicodeString; LineNumber: Integer); + + procedure DoWideLowerCase(const value : UnicodeString; var dest : UnicodeString); + begin + // segregated here so case-insensitive highlighters don't have to pay the overhead + // of the exception frame for the release of the temporary string + dest := SynWideLowerCase(value); + end; + +begin + // UnicodeStrings are not reference counted, hence we need to copy + if FCaseSensitive then + begin + FLineStr := Value; + FCasedLineStr := ''; + FCasedLine := PWideChar(FLineStr); + end + else + begin + DoWideLowerCase(Value, FLineStr); + FCasedLineStr := Value; + FCasedLine := PWideChar(FCasedLineStr); + end; + FLine := PWideChar(FLineStr); + FLineLen := Length(FLineStr); + + Run := 0; + FExpandedRun := 0; + FOldRun := Run; + FLineNumber := LineNumber; +end; + +procedure TSynCustomHighlighter.SetRange(Value: Pointer); +begin +end; + +procedure TSynCustomHighlighter.SetDefaultFilter(Value: string); +begin + FDefaultFilter := Value; +end; + +procedure TSynCustomHighlighter.SetSampleSource(Value: UnicodeString); +begin + // TODO: sure this should be empty? +end; + +procedure TSynCustomHighlighter.UnhookAttrChangeEvent(ANotifyEvent: TNotifyEvent); +begin + FAttrChangeHooks.Remove(ANotifyEvent); +end; + +procedure TSynCustomHighlighter.SetEnabled(const Value: Boolean); +begin + if FEnabled <> Value then + begin + FEnabled := Value; + DefHighlightChange(nil); + end; +end; + +procedure TSynCustomHighlighter.Loaded; +begin + inherited; + DefHighlightChange(nil); +end; + +// Pos and Result are 1-based (i.e. positions in a UnicodeString not a PWideChar) +function TSynCustomHighlighter.PosToExpandedPos(Pos: Integer): Integer; +var + i: Integer; +begin + if FExpandedLine = nil then + begin + Result := Pos; + Exit; + end; + + Result := 0; + i := 0; + while i < Pos do + begin + while FExpandedLine[Result] = FillerChar do + Inc(Result); + Inc(Result); + Inc(i); + end; +end; + +{$IFNDEF SYN_CPPB_1} +initialization + G_PlaceableHighlighters := TSynHighlighterList.Create; +finalization + G_PlaceableHighlighters.Free; + G_PlaceableHighlighters := nil; +{$ENDIF} +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditHighlighterOptions.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditHighlighterOptions.pas new file mode 100644 index 000000000..6976f7cbb --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditHighlighterOptions.pas @@ -0,0 +1,97 @@ +{------------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +Datetime format is dd.MM.yyyy hh:mm:ss. + +The Original Code is: uRESTDWPrivSynEditHighlighterOptions.pas, released 12.09.2012. + +All Rights Reserved. + +Contributors to the uRESTDWPrivSynEdit and mwEdit projects are listed in the +Contributors.txt file. + +$Id: uRESTDWPrivSynEditHighlighterOptions.pas,v 1.0.2 25.10.2012 11:16:19 CodehunterWorks Exp $ + +You may retrieve the latest version of this file at the uRESTDWPrivSynEdit home page, +located at http://uRESTDWPrivSynEdit.SourceForge.net + +Last Changes: + 21.09.2012 08:37:10 - Moved from String to WideString + 25.10.2012 11:16:19 - Added DefaultExtension property + +Known Issues: +-------------------------------------------------------------------------------} + +unit uRESTDWPrivSynEditHighlighterOptions; + +interface + +uses + Classes; + +type + TSynEditHighlighterOptions = class(TPersistent) + private + FAutoDetectEnabled: Boolean; + FAutoDetectLineLimit: Cardinal; + FAutoDetectMatchExpression: WideString; + FDefaultExtension: WideString; + FLineCommentarEnd: WideString; + FLineCommentarStart: WideString; + FTitle: WideString; + FVisible: Boolean; + public + procedure Assign(Source: TPersistent); override; + procedure AssignTo(Dest: TPersistent); override; + published + property AutoDetectEnabled: Boolean read FAutoDetectEnabled write FAutoDetectEnabled; + property AutoDetectLineLimit: Cardinal read FAutoDetectLineLimit write FAutoDetectLineLimit; + property AutoDetectMatchExpression: WideString read FAutoDetectMatchExpression write FAutoDetectMatchExpression; + property DefaultExtension: WideString read FDefaultExtension write FDefaultExtension; + property LineCommentarEnd: WideString read FLineCommentarEnd write FLineCommentarEnd; + property LineCommentarStart: WideString read FLineCommentarStart write FLineCommentarStart; + property Title: WideString read FTitle write FTitle; + property Visible: Boolean read FVisible write FVisible; + end; + +implementation + +procedure TSynEditHighlighterOptions.Assign(Source: TPersistent); +begin + if Source.InheritsFrom(TSynEditHighlighterOptions) then begin + with TSynEditHighlighterOptions(Source) do begin + FAutoDetectEnabled := AutoDetectEnabled; + FAutoDetectMatchExpression := AutoDetectMatchExpression; + FAutoDetectLineLimit := AutoDetectLineLimit; + FDefaultExtension := DefaultExtension; + FLineCommentarStart := LineCommentarStart; + FLineCommentarEnd := LineCommentarEnd; + FTitle := Title; + FVisible := Visible; + end; + end; +end; + +procedure TSynEditHighlighterOptions.AssignTo(Dest: TPersistent); +begin + if Dest.InheritsFrom(TSynEditHighlighterOptions) then begin + with TSynEditHighlighterOptions(Dest) do begin + AutoDetectEnabled := FAutoDetectEnabled; + AutoDetectMatchExpression := FAutoDetectMatchExpression; + AutoDetectLineLimit := FAutoDetectLineLimit; + DefaultExtension := FDefaultExtension; + LineCommentarStart := FLineCommentarStart; + LineCommentarEnd := FLineCommentarEnd; + Title := FTitle; + Visible := FVisible; + end; + end; +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditKbdHandler.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditKbdHandler.pas new file mode 100644 index 000000000..a7847a0e6 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditKbdHandler.pas @@ -0,0 +1,401 @@ +{------------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: uRESTDWPrivSynEditKeyCmds.pas, released 2000-04-07. +The Original Code is based on the mwKeyCmds.pas file from the +mwEdit component suite by Martin Waldenburg and other developers, the Initial +Author of this file is Brad Stowers. +Unicode translation by Mal Hrz. +All Rights Reserved. + +Contributors to the uRESTDWPrivSynEdit and mwEdit projects are listed in the +Contributors.txt file. + +Alternatively, the contents of this file may be used under the terms of the +GNU General Public License Version 2 or later (the "GPL"), in which case +the provisions of the GPL are applicable instead of those above. +If you wish to allow use of your version of this file only under the terms +of the GPL and not to allow others to use your version of this file +under the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the GPL. +If you do not delete the provisions above, a recipient may use your version +of this file under either the MPL or the GPL. + +$Id: uRESTDWPrivSynEditKbdHandler.pas,v 1.10.2.1 2004/08/31 12:55:17 maelh Exp $ + +You may retrieve the latest version of this file at the uRESTDWPrivSynEdit home page, +located at http://uRESTDWPrivSynEdit.SourceForge.net + +Known Issues: +-------------------------------------------------------------------------------} + +{$IFNDEF QSYNEDITKBDHANDLER} +unit uRESTDWPrivSynEditKbdHandler; +{$ENDIF} + +{$I uRESTDWPrivSynEdit.inc} + +interface + +uses + Windows, + Messages, + Graphics, + Controls, + Forms, + uRESTDWPrivSynEditTypes, + SysUtils, + Classes; + +type + { This class provides a TWinControl-Object which supports only the + needed Methods } + TKeyboardControl = class(TWinControl) + public + property OnKeyDown; + property OnKeyPress; + property OnMouseDown; + end; + + TMouseCursorEvent = procedure(Sender: TObject; const aLineCharPos: TBufferCoord; + var aCursor: TCursor) of object; + + TMethodList = class + private + FData: TList; + function GetItem(Index: Integer): TMethod; + function GetCount: Integer; + public + constructor Create; + destructor Destroy; override; + procedure Add(aHandler: TMethod); + procedure Remove(aHandler: TMethod); + property Items[Index: Integer]: TMethod read GetItem; default; + property Count: Integer read GetCount; + end; + + TSynEditKbdHandler = class (TObject) + private + FKeyPressChain: TMethodList; + FKeyDownChain: TMethodList; + FKeyUpChain: TMethodList; + FMouseDownChain: TMethodList; + FMouseUpChain: TMethodList; + FMouseCursorChain: TMethodList; + { avoid infinite recursiveness } + FInKeyPress: Boolean; + FInKeyDown: Boolean; + FInKeyUp: Boolean; + FInMouseDown: Boolean; + FInMouseUp: Boolean; + FInMouseCursor: Boolean; + public + constructor Create; + destructor Destroy; override; + + procedure ExecuteKeyPress(Sender: TObject; var Key: WideChar); + procedure ExecuteKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); + procedure ExecuteKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); + procedure ExecuteMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure ExecuteMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure ExecuteMouseCursor(Sender: TObject; const aLineCharPos: TBufferCoord; + var aCursor: TCursor); + + procedure AddKeyDownHandler(aHandler: TKeyEvent); + procedure RemoveKeyDownHandler(aHandler: TKeyEvent); + procedure AddKeyUpHandler(aHandler: TKeyEvent); + procedure RemoveKeyUpHandler(aHandler: TKeyEvent); + procedure AddKeyPressHandler(aHandler: TKeyPressWEvent); + procedure RemoveKeyPressHandler(aHandler: TKeyPressWEvent); + procedure AddMouseDownHandler(aHandler: TMouseEvent); + procedure RemoveMouseDownHandler(aHandler: TMouseEvent); + procedure AddMouseUpHandler(aHandler: TMouseEvent); + procedure RemoveMouseUpHandler(aHandler: TMouseEvent); + procedure AddMouseCursorHandler(aHandler: TMouseCursorEvent); + procedure RemoveMouseCursorHandler(aHandler: TMouseCursorEvent); + end; + + +implementation + +{ TSynEditKbdHandler } + +procedure TSynEditKbdHandler.AddKeyDownHandler(aHandler: TKeyEvent); +begin + FKeyDownChain.Add(TMethod(aHandler)); +end; + +procedure TSynEditKbdHandler.AddKeyUpHandler(aHandler: TKeyEvent); +begin + FKeyUpChain.Add(TMethod(aHandler)); +end; + +procedure TSynEditKbdHandler.AddKeyPressHandler(aHandler: TKeyPressWEvent); +begin + FKeyPressChain.Add(TMethod(aHandler)); +end; + +procedure TSynEditKbdHandler.AddMouseDownHandler(aHandler: TMouseEvent); +begin + FMouseDownChain.Add(TMethod(aHandler)); +end; + +procedure TSynEditKbdHandler.AddMouseUpHandler(aHandler: TMouseEvent); +begin + FMouseUpChain.Add(TMethod(aHandler)); +end; + +procedure TSynEditKbdHandler.AddMouseCursorHandler(aHandler: TMouseCursorEvent); +begin + FMouseCursorChain.Add(TMethod(aHandler)); +end; + +constructor TSynEditKbdHandler.Create; +begin + inherited; + + { Elements to handle KeyDown-Events } + FKeyDownChain := TMethodList.Create; + + { Elements to handle KeyUp-Events } + FKeyUpChain := TMethodList.Create; + + { Elements to handle KeyPress-Events } + FKeyPressChain := TMethodList.Create; + + { Elements to handle MouseDown Events } + FMouseDownChain := TMethodList.Create; + + { Elements to handle MouseUp Events } + FMouseUpChain := TMethodList.Create; + + { Elements to handle MouseCursor Events } + FMouseCursorChain := TMethodList.Create; +end; + +destructor TSynEditKbdHandler.Destroy; +begin + FKeyPressChain.Free; + FKeyDownChain.Free; + FKeyUpChain.Free; + FMouseDownChain.Free; + FMouseUpChain.Free; + FMouseCursorChain.Free; + + inherited Destroy; +end; + +procedure TSynEditKbdHandler.ExecuteKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); +var + idx: Integer; +begin + if FInKeyDown then + Exit; + FInKeyDown := True; + try + with FKeyDownChain do + begin + for idx := Count - 1 downto 0 do + begin + TKeyEvent(Items[idx])(Sender, Key, Shift); + if (Key = 0) then + begin + FInKeyDown := False; + Exit; + end; + end; + end; + finally + FInKeyDown := False; + end; +end; + +procedure TSynEditKbdHandler.ExecuteKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); +var + idx: Integer; +begin + if FInKeyUp then + Exit; + FInKeyUp := True; + try + with FKeyUpChain do + begin + for idx := Count - 1 downto 0 do + begin + TKeyEvent(Items[idx])(Sender,Key,Shift); + if (Key = 0) then + begin + FInKeyUp := False; + Exit; + end; + end; + end; + finally + FInKeyUp := False; + end; +end; + +procedure TSynEditKbdHandler.ExecuteKeyPress(Sender: TObject; var Key: WideChar); +var + idx: Integer; +begin + if FInKeyPress then + Exit; + FInKeyPress := True; + try + with FKeyPressChain do + begin + for idx := Count - 1 downto 0 do + begin + TKeyPressWEvent(Items[idx])(Sender, Key); + if (Key = #0) then + begin + FInKeyPress := False; + Exit; + end; + end; + end; + finally + FInKeyPress := False; + end; +end; + +procedure TSynEditKbdHandler.ExecuteMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +var + cHandler: Integer; +begin + if FInMouseDown then + Exit; + FInMouseDown := True; + try + for cHandler := FMouseDownChain.Count - 1 downto 0 do + TMouseEvent(FMouseDownChain[cHandler])(Sender, Button, Shift, X, Y); + finally + FInMouseDown := False; + end; +end; + +procedure TSynEditKbdHandler.ExecuteMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +var + cHandler: Integer; +begin + if FInMouseUp then + Exit; + FInMouseUp := True; + try + for cHandler := FMouseUpChain.Count - 1 downto 0 do + TMouseEvent(FMouseUpChain[cHandler])(Sender, Button, Shift, X, Y); + finally + FInMouseUp := False; + end; +end; + +procedure TSynEditKbdHandler.ExecuteMouseCursor(Sender: TObject; + const aLineCharPos: TBufferCoord; var aCursor: TCursor); +var + cHandler: Integer; +begin + if FInMouseCursor then + Exit; + FInMouseCursor := True; + try + for cHandler := FMouseCursorChain.Count - 1 downto 0 do + TMouseCursorEvent(FMouseCursorChain[cHandler])(Sender, aLineCharPos, aCursor); + finally + FInMouseCursor := False; + end; +end; + +procedure TSynEditKbdHandler.RemoveKeyDownHandler(aHandler: TKeyEvent); +begin + FKeyDownChain.Remove(TMethod(aHandler)); +end; + +procedure TSynEditKbdHandler.RemoveKeyUpHandler(aHandler: TKeyEvent); +begin + FKeyUpChain.Remove(TMethod(aHandler)); +end; + +procedure TSynEditKbdHandler.RemoveKeyPressHandler(aHandler: TKeyPressWEvent); +begin + FKeyPressChain.Remove(TMethod(aHandler)); +end; + +procedure TSynEditKbdHandler.RemoveMouseDownHandler(aHandler: TMouseEvent); +begin + FMouseDownChain.Remove(TMethod(aHandler)); +end; + +procedure TSynEditKbdHandler.RemoveMouseUpHandler(aHandler: TMouseEvent); +begin + FMouseUpChain.Remove(TMethod(aHandler)); +end; + +procedure TSynEditKbdHandler.RemoveMouseCursorHandler(aHandler: TMouseCursorEvent); +begin + FMouseCursorChain.Remove(TMethod(aHandler)); +end; + +{ TMethodList } + +procedure TMethodList.Add(aHandler: TMethod); +begin + FData.Add(aHandler.Data); + FData.Add(aHandler.Code); +end; + +constructor TMethodList.Create; +begin + inherited; + + FData := TList.Create; +end; + +destructor TMethodList.Destroy; +begin + FData.Free; + + inherited; +end; + +function TMethodList.GetCount: Integer; +begin + Result := FData.Count div 2; +end; + +function TMethodList.GetItem(Index: Integer): TMethod; +begin + Index := Index * 2; + Result.Data := FData[Index]; + Result.Code := FData[Index + 1]; +end; + +procedure TMethodList.Remove(aHandler: TMethod); +var + cPos: Integer; +begin + cPos := FData.Count - 2; + while cPos >= 0 do + begin + if (FData.List[cPos] = aHandler.Data) and (FData.List[cPos + 1] = aHandler.Code) then + begin + FData.Delete(cPos); + FData.Delete(cPos); + Exit; + end; + Dec(cPos, 2); + end; +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditKeyCmds.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditKeyCmds.pas new file mode 100644 index 000000000..da8a82de1 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditKeyCmds.pas @@ -0,0 +1,1026 @@ +{------------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: uRESTDWPrivSynEditKeyCmds.pas, released 2000-04-07. +The Original Code is based on the mwKeyCmds.pas file from the +mwEdit component suite by Martin Waldenburg and other developers, the Initial +Author of this file is Brad Stowers. +All Rights Reserved. + +Contributors to the uRESTDWPrivSynEdit and mwEdit projects are listed in the +Contributors.txt file. + +Alternatively, the contents of this file may be used under the terms of the +GNU General Public License Version 2 or later (the "GPL"), in which case +the provisions of the GPL are applicable instead of those above. +If you wish to allow use of your version of this file only under the terms +of the GPL and not to allow others to use your version of this file +under the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the GPL. +If you do not delete the provisions above, a recipient may use your version +of this file under either the MPL or the GPL. + +$Id: uRESTDWPrivSynEditKeyCmds.pas,v 1.23.2.4 2008/09/14 16:24:58 maelh Exp $ + +You may retrieve the latest version of this file at the uRESTDWPrivSynEdit home page, +located at http://uRESTDWPrivSynEdit.SourceForge.net + +Known Issues: +-------------------------------------------------------------------------------} +// TODO: introduce friendly Names for the Commands (EditorCommandStrs is not good enough for end-users) + +{$IFNDEF QSYNEDITKEYCMDS} +unit uRESTDWPrivSynEditKeyCmds; +{$ENDIF} + +{$I uRESTDWPrivSynEdit.inc} + +interface + +uses + Menus, + uRESTDWPrivSynUnicode, + Classes, + SysUtils; + +const + //**************************************************************************** + // NOTE! If you add an editor command, you must also update the + // EditorCommandStrs constant array in implementation section below, or the + // command will not show up in the IDE. + //**************************************************************************** + + // "Editor Commands". Key strokes are translated from a table into these + // I used constants instead of a set so that additional commands could be + // added in descendants (you can't extend a set) + + // There are two ranges of editor commands: the ecViewXXX commands are always + // valid, while the ecEditXXX commands are ignored when the editor is in + // read-only mode + + ecNone = 0; // Nothing. Useful for user event to handle command + ecViewCommandFirst = 0; + ecViewCommandLast = 500; + ecEditCommandFirst = 501; + ecEditCommandLast = 1000; + + ecLeft = 1; // Move cursor left one char + ecRight = 2; // Move cursor right one char + ecUp = 3; // Move cursor up one line + ecDown = 4; // Move cursor down one line + ecWordLeft = 5; // Move cursor left one Word + ecWordRight = 6; // Move cursor right one Word + ecLineStart = 7; // Move cursor to beginning of line + ecLineEnd = 8; // Move cursor to end of line + ecPageUp = 9; // Move cursor up one page + ecPageDown = 10; // Move cursor down one page + ecPageLeft = 11; // Move cursor right one page + ecPageRight = 12; // Move cursor left one page + ecPageTop = 13; // Move cursor to top of page + ecPageBottom = 14; // Move cursor to bottom of page + ecEditorTop = 15; // Move cursor to absolute beginning + ecEditorBottom = 16; // Move cursor to absolute end + ecGotoXY = 17; // Move cursor to specific coordinates, Data = PPoint + +//****************************************************************************** +// Maybe the command processor should just take a Boolean that signifies if +// selection is affected or not? +//****************************************************************************** + + ecSelection = 100; // Add this to ecXXX command to get equivalent + // command, but with selection enabled. This is not + // a command itself. + // Same as commands above, except they affect selection, too + ecSelLeft = ecLeft + ecSelection; + ecSelRight = ecRight + ecSelection; + ecSelUp = ecUp + ecSelection; + ecSelDown = ecDown + ecSelection; + ecSelWordLeft = ecWordLeft + ecSelection; + ecSelWordRight = ecWordRight + ecSelection; + ecSelLineStart = ecLineStart + ecSelection; + ecSelLineEnd = ecLineEnd + ecSelection; + ecSelPageUp = ecPageUp + ecSelection; + ecSelPageDown = ecPageDown + ecSelection; + ecSelPageLeft = ecPageLeft + ecSelection; + ecSelPageRight = ecPageRight + ecSelection; + ecSelPageTop = ecPageTop + ecSelection; + ecSelPageBottom = ecPageBottom + ecSelection; + ecSelEditorTop = ecEditorTop + ecSelection; + ecSelEditorBottom = ecEditorBottom + ecSelection; + ecSelGotoXY = ecGotoXY + ecSelection; // Data = PPoint + + ecSelWord = 198; + ecSelectAll = 199; // Select entire contents of editor, cursor to end + + ecCopy = 201; // Copy selection to clipboard + + ecScrollUp = 211; // Scroll up one line leaving cursor position unchanged. + ecScrollDown = 212; // Scroll down one line leaving cursor position unchanged. + ecScrollLeft = 213; // Scroll left one char leaving cursor position unchanged. + ecScrollRight = 214; // Scroll right one char leaving cursor position unchanged. + + ecInsertMode = 221; // Set insert mode + ecOverwriteMode = 222; // Set overwrite mode + ecToggleMode = 223; // Toggle ins/ovr mode + + ecNormalSelect = 231; // Normal selection mode + ecColumnSelect = 232; // Column selection mode + ecLineSelect = 233; // Line selection mode + + ecMatchBracket = 250; // Go to matching bracket + ecCommentBlock = 251; // Comment Block + + ecGotoMarker0 = 301; // Goto marker + ecGotoMarker1 = 302; // Goto marker + ecGotoMarker2 = 303; // Goto marker + ecGotoMarker3 = 304; // Goto marker + ecGotoMarker4 = 305; // Goto marker + ecGotoMarker5 = 306; // Goto marker + ecGotoMarker6 = 307; // Goto marker + ecGotoMarker7 = 308; // Goto marker + ecGotoMarker8 = 309; // Goto marker + ecGotoMarker9 = 310; // Goto marker + ecSetMarker0 = 351; // Set marker, Data = PPoint - X, Y Pos + ecSetMarker1 = 352; // Set marker, Data = PPoint - X, Y Pos + ecSetMarker2 = 353; // Set marker, Data = PPoint - X, Y Pos + ecSetMarker3 = 354; // Set marker, Data = PPoint - X, Y Pos + ecSetMarker4 = 355; // Set marker, Data = PPoint - X, Y Pos + ecSetMarker5 = 356; // Set marker, Data = PPoint - X, Y Pos + ecSetMarker6 = 357; // Set marker, Data = PPoint - X, Y Pos + ecSetMarker7 = 358; // Set marker, Data = PPoint - X, Y Pos + ecSetMarker8 = 359; // Set marker, Data = PPoint - X, Y Pos + ecSetMarker9 = 360; // Set marker, Data = PPoint - X, Y Pos + + ecGotFocus = 480; + ecLostFocus = 481; + + ecContextHelp = 490; // Help on Word, Data = Word + + ecDeleteLastChar = 501; // Delete last char (i.e. backspace key) + ecDeleteChar = 502; // Delete char at cursor (i.e. delete key) + ecDeleteWord = 503; // Delete from cursor to end of Word + ecDeleteLastWord = 504; // Delete from cursor to start of Word + ecDeleteBOL = 505; // Delete from cursor to beginning of line + ecDeleteEOL = 506; // Delete from cursor to end of line + ecDeleteLine = 507; // Delete current line + ecClearAll = 508; // Delete everything + ecLineBreak = 509; // Break line at current position, move caret to new line + ecInsertLine = 510; // Break line at current position, leave caret + ecChar = 511; // Insert a character at current position + + ecImeStr = 550; // Insert character(s) from IME + + ecUndo = 601; // Perform undo if available + ecRedo = 602; // Perform redo if available + ecCut = 603; // Cut selection to clipboard + ecPaste = 604; // Paste clipboard to current position + + ecBlockIndent = 610; // Indent selection + ecBlockUnindent = 611; // Unindent selection + ecTab = 612; // Tab key + ecShiftTab = 613; // Shift+Tab key + + ecAutoCompletion = 650; + + ecUpperCase = 620; // apply to the current or previous Word + ecLowerCase = 621; + ecToggleCase = 622; + ecTitleCase = 623; + ecUpperCaseBlock = 625; // apply to current selection, or current char if no selection + ecLowerCaseBlock = 626; + ecToggleCaseBlock = 627; + ecTitleCaseBlock = 628; + + ecString = 630; //Insert a whole string + + {$IFDEF SYN_CodeFolding} + ecFoldAll = 701; + ecUnfoldAll = 702; + ecFoldNearest = 705; + ecUnfoldNearest = 706; + ecFoldLevel1 = 711; + ecFoldLevel2 = 712; + ecFoldLevel3 = 713; + ecUnfoldLevel1 = 721; + ecUnfoldLevel2 = 722; + ecUnfoldLevel3 = 723; + ecFoldRegions = 731; + ecUnfoldRegions = 732; + {$ENDIF} + + ecUserFirst = 1001; // Start of user-defined commands + +type + ESynKeyError = class(Exception); + + TSynEditorCommand = type Word; + + TSynEditKeyStroke = class(TCollectionItem) + private + FKey: Word; // Virtual keycode, i.e. VK_xxx + FShift: TShiftState; + FKey2: Word; + FShift2: TShiftState; + FCommand: TSynEditorCommand; + function GetShortCut: TShortCut; + function GetShortCut2: TShortCut; + procedure SetCommand(const Value: TSynEditorCommand); + procedure SetKey(const Value: Word); + procedure SetKey2(const Value: Word); + procedure SetShift(const Value: TShiftState); + procedure SetShift2(const Value: TShiftState); + procedure SetShortCut(const Value: TShortCut); + procedure SetShortCut2(const Value: TShortCut); + protected +{$IFDEF SYN_COMPILER_3_UP} + function GetDisplayName: string; override; +{$ENDIF} + public + procedure Assign(Source: TPersistent); override; + procedure LoadFromStream(AStream: TStream); + procedure SaveToStream(AStream: TStream); + // No duplicate checking is done if assignment made via these properties! + property Key: Word read FKey write SetKey; + property Key2: Word read FKey2 write SetKey2; + property Shift: TShiftState read FShift write SetShift; + property Shift2: TShiftState read FShift2 write SetShift2; + published + property Command: TSynEditorCommand read FCommand write SetCommand; + property ShortCut: TShortCut read GetShortCut write SetShortCut + default 0; + property ShortCut2: TShortCut read GetShortCut2 write SetShortCut2 + default 0; + end; + + TSynEditKeyStrokes = class(TCollection) + private + FOwner: TPersistent; + function GetItem(Index: Integer): TSynEditKeyStroke; + procedure SetItem(Index: Integer; Value: TSynEditKeyStroke); + protected +{$IFDEF SYN_COMPILER_3_UP} + function GetOwner: TPersistent; override; +{$ENDIF} + public + constructor Create(AOwner: TPersistent); + function Add: TSynEditKeyStroke; + procedure AddKey(const ACmd: TSynEditorCommand; const AKey: word; + const AShift: TShiftState; const AKey2: word = 0; + const AShift2: TShiftState = []); + procedure Assign(Source: TPersistent); override; + function FindCommand(Cmd: TSynEditorCommand): Integer; + function FindKeycode(Code: Word; SS: TShiftState): Integer; + function FindKeycode2(Code1: Word; SS1: TShiftState; + Code2: Word; SS2: TShiftState): Integer; + function FindShortcut(SC: TShortcut): Integer; + function FindShortcut2(SC, SC2: TShortcut): Integer; + procedure LoadFromStream(AStream: TStream); + procedure ResetDefaults; + procedure SaveToStream(AStream: TStream); + public + property Items[Index: Integer]: TSynEditKeyStroke read GetItem + write SetItem; default; + end; + +// These are mainly for the TSynEditorCommand property editor, but could be +// useful elsewhere. +function EditorCommandToDescrString(Cmd: TSynEditorCommand): string; +function EditorCommandToCodeString(Cmd: TSynEditorCommand): string; +procedure GetEditorCommandValues(Proc: TGetStrProc); +procedure GetEditorCommandExtended(Proc: TGetStrProc); +function IdentToEditorCommand(const Ident: string; var Cmd: longint): Boolean; +function EditorCommandToIdent(Cmd: longint; var Ident: string): Boolean; +function ConvertCodeStringToExtended(AString: string): string; +function ConvertExtendedToCodeString(AString: string): string; +function ConvertExtendedToCommand(AString: string): TSynEditorCommand; +function ConvertCodeStringToCommand(AString: string): TSynEditorCommand; +function IndexToEditorCommand(const AIndex: Integer): Integer; + +implementation + +uses + Windows, + uRESTDWPrivSynEditKeyConst, + uRESTDWPrivSynEditStrConst; + +{ Command mapping routines } + +{$IFDEF SYN_COMPILER_2} +// This is defined in D3/C3 and up. +type + TIdentMapEntry = record + Value: TSynEditorCommand; + Name: string; + end; +{$ENDIF} + +const +{$IFDEF SYN_CodeFolding} + EditorCommandStrs: array[0..113] of TIdentMapEntry = ( +{$ELSE} + EditorCommandStrs: array[0..101] of TIdentMapEntry = ( +{$ENDIF} + (Value: ecNone; Name: 'ecNone'), + (Value: ecLeft; Name: 'ecLeft'), + (Value: ecRight; Name: 'ecRight'), + (Value: ecUp; Name: 'ecUp'), + (Value: ecDown; Name: 'ecDown'), + (Value: ecWordLeft; Name: 'ecWordLeft'), + (Value: ecWordRight; Name: 'ecWordRight'), + (Value: ecLineStart; Name: 'ecLineStart'), + (Value: ecLineEnd; Name: 'ecLineEnd'), + (Value: ecPageUp; Name: 'ecPageUp'), + (Value: ecPageDown; Name: 'ecPageDown'), + (Value: ecPageLeft; Name: 'ecPageLeft'), + (Value: ecPageRight; Name: 'ecPageRight'), + (Value: ecPageTop; Name: 'ecPageTop'), + (Value: ecPageBottom; Name: 'ecPageBottom'), + (Value: ecEditorTop; Name: 'ecEditorTop'), + (Value: ecEditorBottom; Name: 'ecEditorBottom'), + (Value: ecGotoXY; Name: 'ecGotoXY'), + (Value: ecSelLeft; Name: 'ecSelLeft'), + (Value: ecSelRight; Name: 'ecSelRight'), + (Value: ecSelUp; Name: 'ecSelUp'), + (Value: ecSelDown; Name: 'ecSelDown'), + (Value: ecSelWordLeft; Name: 'ecSelWordLeft'), + (Value: ecSelWordRight; Name: 'ecSelWordRight'), + (Value: ecSelLineStart; Name: 'ecSelLineStart'), + (Value: ecSelLineEnd; Name: 'ecSelLineEnd'), + (Value: ecSelPageUp; Name: 'ecSelPageUp'), + (Value: ecSelPageDown; Name: 'ecSelPageDown'), + (Value: ecSelPageLeft; Name: 'ecSelPageLeft'), + (Value: ecSelPageRight; Name: 'ecSelPageRight'), + (Value: ecSelPageTop; Name: 'ecSelPageTop'), + (Value: ecSelPageBottom; Name: 'ecSelPageBottom'), + (Value: ecSelEditorTop; Name: 'ecSelEditorTop'), + (Value: ecSelEditorBottom; Name: 'ecSelEditorBottom'), + (Value: ecSelGotoXY; Name: 'ecSelGotoXY'), + (Value: ecSelWord; Name: 'ecSelWord'), + (Value: ecSelectAll; Name: 'ecSelectAll'), + (Value: ecDeleteLastChar; Name: 'ecDeleteLastChar'), + (Value: ecDeleteChar; Name: 'ecDeleteChar'), + (Value: ecDeleteWord; Name: 'ecDeleteWord'), + (Value: ecDeleteLastWord; Name: 'ecDeleteLastWord'), + (Value: ecDeleteBOL; Name: 'ecDeleteBOL'), + (Value: ecDeleteEOL; Name: 'ecDeleteEOL'), + (Value: ecDeleteLine; Name: 'ecDeleteLine'), + (Value: ecClearAll; Name: 'ecClearAll'), + (Value: ecLineBreak; Name: 'ecLineBreak'), + (Value: ecInsertLine; Name: 'ecInsertLine'), + (Value: ecChar; Name: 'ecChar'), + (Value: ecImeStr; Name: 'ecImeStr'), + (Value: ecUndo; Name: 'ecUndo'), + (Value: ecRedo; Name: 'ecRedo'), + (Value: ecCut; Name: 'ecCut'), + (Value: ecCopy; Name: 'ecCopy'), + (Value: ecPaste; Name: 'ecPaste'), + (Value: ecScrollUp; Name: 'ecScrollUp'), + (Value: ecScrollDown; Name: 'ecScrollDown'), + (Value: ecScrollLeft; Name: 'ecScrollLeft'), + (Value: ecScrollRight; Name: 'ecScrollRight'), + (Value: ecInsertMode; Name: 'ecInsertMode'), + (Value: ecOverwriteMode; Name: 'ecOverwriteMode'), + (Value: ecToggleMode; Name: 'ecToggleMode'), + (Value: ecBlockIndent; Name: 'ecBlockIndent'), + (Value: ecBlockUnindent; Name: 'ecBlockUnindent'), + (Value: ecTab; Name: 'ecTab'), + (Value: ecShiftTab; Name: 'ecShiftTab'), + (Value: ecMatchBracket; Name: 'ecMatchBracket'), + (Value: ecCommentBlock; Name: 'ecCommentBlock'), + (Value: ecNormalSelect; Name: 'ecNormalSelect'), + (Value: ecColumnSelect; Name: 'ecColumnSelect'), + (Value: ecLineSelect; Name: 'ecLineSelect'), + (Value: ecAutoCompletion; Name: 'ecAutoCompletion'), + (Value: ecUserFirst; Name: 'ecUserFirst'), + (Value: ecContextHelp; Name: 'ecContextHelp'), + (Value: ecGotoMarker0; Name: 'ecGotoMarker0'), + (Value: ecGotoMarker1; Name: 'ecGotoMarker1'), + (Value: ecGotoMarker2; Name: 'ecGotoMarker2'), + (Value: ecGotoMarker3; Name: 'ecGotoMarker3'), + (Value: ecGotoMarker4; Name: 'ecGotoMarker4'), + (Value: ecGotoMarker5; Name: 'ecGotoMarker5'), + (Value: ecGotoMarker6; Name: 'ecGotoMarker6'), + (Value: ecGotoMarker7; Name: 'ecGotoMarker7'), + (Value: ecGotoMarker8; Name: 'ecGotoMarker8'), + (Value: ecGotoMarker9; Name: 'ecGotoMarker9'), + (Value: ecSetMarker0; Name: 'ecSetMarker0'), + (Value: ecSetMarker1; Name: 'ecSetMarker1'), + (Value: ecSetMarker2; Name: 'ecSetMarker2'), + (Value: ecSetMarker3; Name: 'ecSetMarker3'), + (Value: ecSetMarker4; Name: 'ecSetMarker4'), + (Value: ecSetMarker5; Name: 'ecSetMarker5'), + (Value: ecSetMarker6; Name: 'ecSetMarker6'), + (Value: ecSetMarker7; Name: 'ecSetMarker7'), + (Value: ecSetMarker8; Name: 'ecSetMarker8'), + (Value: ecSetMarker9; Name: 'ecSetMarker9'), + (Value: ecUpperCase; Name: 'ecUpperCase'), + (Value: ecLowerCase; Name: 'ecLowerCase'), + (Value: ecToggleCase; Name: 'ecToggleCase'), + (Value: ecTitleCase; Name: 'ecTitleCase'), + (Value: ecUpperCaseBlock; Name: 'ecUpperCaseBlock'), + (Value: ecLowerCaseBlock; Name: 'ecLowerCaseBlock'), + (Value: ecToggleCaseBlock; Name: 'ecToggleCaseBlock'), + (Value: ecTitleCaseBlock; Name: 'ecTitleCaseBlock'), +{$IFDEF SYN_CodeFolding} + (Value: ecString; Name:'ecString'), + (Value: ecFoldAll; Name:'ecFoldAll'), + (Value: ecUnfoldAll; Name:'ecUnfoldAll'), + (Value: ecFoldNearest; Name:'ecFoldNearest'), + (Value: ecUnfoldNearest; Name:'ecUnfoldNearest'), + (Value: ecFoldLevel1; Name:'ecFoldLevel1'), + (Value: ecFoldLevel2; Name:'ecFoldLevel2'), + (Value: ecFoldLevel3; Name:'ecFoldLevel3'), + (Value: ecUnfoldLevel1; Name:'ecUnfoldLevel1'), + (Value: ecUnfoldLevel2; Name:'ecUnfoldLevel2'), + (Value: ecUnfoldLevel3; Name:'ecUnfoldLevel3'), + (Value: ecFoldRegions; Name:'ecFoldRanges'), + (Value: ecUnfoldRegions; Name:'ecUnfoldRanges')); +{$ELSE} + (Value: ecString; Name:'ecString')); +{$ENDIF} + +procedure GetEditorCommandValues(Proc: TGetStrProc); +var + i: Integer; +begin + for i := Low(EditorCommandStrs) to High(EditorCommandStrs) do + Proc(EditorCommandStrs[I].Name); +end; + +procedure GetEditorCommandExtended(Proc: TGetStrProc); +var + i: Integer; +begin + for i := Low(EditorCommandStrs) to High(EditorCommandStrs) do + Proc(ConvertCodeStringToExtended(EditorCommandStrs[I].Name)); +end; + +function IdentToEditorCommand(const Ident: string; var Cmd: longint): Boolean; +{$IFDEF SYN_COMPILER_2} +var + I: Integer; +{$ENDIF} +begin +{$IFDEF SYN_COMPILER_2} + Result := FALSE; + for I := Low(EditorCommandStrs) to High(EditorCommandStrs) do + if CompareText(EditorCommandStrs[I].Name, Ident) = 0 then + begin + Result := TRUE; + Cmd := EditorCommandStrs[I].Value; + Break; + end; +{$ELSE} + Result := IdentToInt(Ident, Cmd, EditorCommandStrs); +{$ENDIF} +end; + +function EditorCommandToIdent(Cmd: longint; var Ident: string): Boolean; +{$IFDEF SYN_COMPILER_2} +var + I: Integer; +{$ENDIF} +begin +{$IFDEF SYN_COMPILER_2} + Result := FALSE; + for I := Low(EditorCommandStrs) to High(EditorCommandStrs) do + if EditorCommandStrs[I].Value = Cmd then + begin + Result := TRUE; + Ident := EditorCommandStrs[I].Name; + Break; + end; +{$ELSE} + Result := IntToIdent(Cmd, Ident, EditorCommandStrs); +{$ENDIF} +end; + +function EditorCommandToDescrString(Cmd: TSynEditorCommand): string; +begin + // Doesn't do anything yet. + Result := ''; +end; + +function EditorCommandToCodeString(Cmd: TSynEditorCommand): string; +begin + if not EditorCommandToIdent(Cmd, Result) then + Result := IntToStr(Cmd); +end; + +{ TSynEditKeyStroke } + +procedure TSynEditKeyStroke.Assign(Source: TPersistent); +begin + if Source is TSynEditKeyStroke then + begin + Command := TSynEditKeyStroke(Source).Command; + Key := TSynEditKeyStroke(Source).Key; + Key2 := TSynEditKeyStroke(Source).Key2; + Shift := TSynEditKeyStroke(Source).Shift; + Shift2 := TSynEditKeyStroke(Source).Shift2; + end else + inherited Assign(Source); +end; + +{$IFDEF SYN_COMPILER_3_UP} +function TSynEditKeyStroke.GetDisplayName: string; +begin + Result := EditorCommandToCodeString(Command) + ' - ' + ShortCutToText(ShortCut); + if ShortCut <> 0 then + Result := Result + ' ' + ShortCutToText(ShortCut2); + if Result = '' then + Result := inherited GetDisplayName; +end; +{$ENDIF} + +function TSynEditKeyStroke.GetShortCut: TShortCut; +begin + Result := Menus.ShortCut(Key, Shift); +end; + +procedure TSynEditKeyStroke.SetCommand(const Value: TSynEditorCommand); +begin + if Value <> FCommand then + FCommand := Value; +end; + +procedure TSynEditKeyStroke.SetKey(const Value: Word); +begin + if Value <> FKey then + FKey := Value; +end; + +procedure TSynEditKeyStroke.SetShift(const Value: TShiftState); +begin + if Value <> FShift then + FShift := Value; +end; + +procedure TSynEditKeyStroke.SetShortCut(const Value: TShortCut); +var + NewKey: Word; + NewShift: TShiftState; + Dup: Integer; +begin + // Duplicate values of no shortcut are OK. + if Value <> 0 then + begin + // Check for duplicate shortcut in the collection and disallow if there is. + Dup := TSynEditKeyStrokes(Collection).FindShortcut2(Value, ShortCut2); + if (Dup <> -1) and (Dup <> Self.Index) then + begin + raise ESynKeyError.Create(SYNS_EDuplicateShortCut); + end; + end; + + Menus.ShortCutToKey(Value, NewKey, NewShift); + + if (NewKey <> Key) or (NewShift <> Shift) then + begin + Key := NewKey; + Shift := NewShift; + end; +end; + +procedure TSynEditKeyStroke.SetKey2(const Value: Word); +begin + if Value <> FKey2 then + FKey2 := Value; +end; + +procedure TSynEditKeyStroke.SetShift2(const Value: TShiftState); +begin + if Value <> FShift2 then + FShift2 := Value; +end; + +procedure TSynEditKeyStroke.SetShortCut2(const Value: TShortCut); +var + NewKey: Word; + NewShift: TShiftState; + Dup: Integer; +begin + // Duplicate values of no shortcut are OK. + if Value <> 0 then + begin + // Check for duplicate shortcut in the collection and disallow if there is. + Dup := TSynEditKeyStrokes(Collection).FindShortcut2(ShortCut, Value); + if (Dup <> -1) and (Dup <> Self.Index) then + raise ESynKeyError.Create(SYNS_EDuplicateShortCut); + end; + + Menus.ShortCutToKey(Value, NewKey, NewShift); + if (NewKey <> Key2) or (NewShift <> Shift2) then + begin + Key2 := NewKey; + Shift2 := NewShift; + end; +end; + +function TSynEditKeyStroke.GetShortCut2: TShortCut; +begin + Result := Menus.ShortCut(Key2, Shift2); +end; + +procedure TSynEditKeyStroke.LoadFromStream(AStream: TStream); +begin + with AStream do begin + Read(fKey, SizeOf(fKey)); + Read(fShift, SizeOf(fShift)); + Read(fKey2, SizeOf(fKey2)); + Read(fShift2, SizeOf(fShift2)); + Read(fCommand, SizeOf(fCommand)); + end; +end; + +procedure TSynEditKeyStroke.SaveToStream(AStream: TStream); +begin + with AStream do begin + Write(fKey, SizeOf(fKey)); + Write(fShift, SizeOf(fShift)); + Write(fKey2, SizeOf(fKey2)); + Write(fShift2, SizeOf(fShift2)); + Write(fCommand, SizeOf(fCommand)); + end; +end; + + +{ TSynEditKeyStrokes } + +function TSynEditKeyStrokes.Add: TSynEditKeyStroke; +begin + Result := TSynEditKeyStroke(inherited Add); +end; + +procedure TSynEditKeyStrokes.AddKey(const ACmd: TSynEditorCommand; const AKey: word; + const AShift: TShiftState; const AKey2: word; const AShift2: TShiftState); +var + NewKeystroke: TSynEditKeyStroke; +begin + NewKeystroke := Add; + try + NewKeystroke.Key := AKey; + NewKeystroke.Shift := AShift; + NewKeystroke.Key2 := AKey2; + NewKeystroke.Shift2 := AShift2; + NewKeystroke.Command := ACmd; + except + NewKeystroke.Free; + raise; + end; +end; + +procedure TSynEditKeyStrokes.Assign(Source: TPersistent); +var + x: Integer; +begin + if Source is TSynEditKeyStrokes then + begin + Clear; + for x := 0 to TSynEditKeyStrokes(Source).Count-1 do + begin + with Add do + Assign(TSynEditKeyStrokes(Source)[x]); + end; + end + else + inherited Assign(Source); +end; + +constructor TSynEditKeyStrokes.Create(AOwner: TPersistent); +begin + inherited Create(TSynEditKeyStroke); + FOwner := AOwner; +end; + +function TSynEditKeyStrokes.FindCommand(Cmd: TSynEditorCommand): Integer; +var + x: Integer; +begin + Result := -1; + for x := 0 to Count-1 do + if Items[x].Command = Cmd then + begin + Result := x; + Break; + end; +end; + +function TSynEditKeyStrokes.FindKeycode(Code: Word; SS: TShiftState): Integer; +var + x: Integer; +begin + Result := -1; + for x := 0 to Count-1 do + if (Items[x].Key = Code) and (Items[x].Shift = SS) and (Items[x].Key2 = 0) + then begin + Result := x; + Break; + end; +end; + +function TSynEditKeyStrokes.FindKeycode2(Code1: Word; SS1: TShiftState; + Code2: Word; SS2: TShiftState): Integer; +var + x: Integer; +begin + Result := -1; + for x := 0 to Count-1 do + if (Items[x].Key = Code1) and (Items[x].Shift = SS1) and + (Items[x].Key2 = Code2) and (Items[x].Shift2 = SS2) then + begin + Result := x; + Break; + end; +end; + +function TSynEditKeyStrokes.FindShortcut(SC: TShortcut): Integer; +var + x: Integer; +begin + Result := -1; + for x := 0 to Count-1 do + if Items[x].Shortcut = SC then + begin + Result := x; + Break; + end; +end; + +function TSynEditKeyStrokes.FindShortcut2(SC, SC2: TShortcut): Integer; +var + x: Integer; +begin + Result := -1; + for x := 0 to Count-1 do + if (Items[x].Shortcut = SC) and (Items[x].Shortcut2 = SC2) then + begin + Result := x; + Break; + end; +end; + +function TSynEditKeyStrokes.GetItem(Index: Integer): TSynEditKeyStroke; +begin + Result := TSynEditKeyStroke(inherited GetItem(Index)); +end; + +{$IFDEF SYN_COMPILER_3_UP} +function TSynEditKeyStrokes.GetOwner: TPersistent; +begin + Result := FOwner; +end; +{$ENDIF} + +procedure TSynEditKeyStrokes.LoadFromStream(AStream: TStream); +var + Num: Integer; +begin + Clear; + AStream.Read(Num, SizeOf(Num)); + while Num > 0 do begin + with Add do + LoadFromStream(AStream); + Dec(Num); + end; +end; + +procedure TSynEditKeyStrokes.ResetDefaults; +begin + Clear; + + AddKey(ecUp, SYNEDIT_UP, []); + AddKey(ecSelUp, SYNEDIT_UP, [ssShift]); + AddKey(ecScrollUp, SYNEDIT_UP, [ssCtrl]); + AddKey(ecDown, SYNEDIT_DOWN, []); + AddKey(ecSelDown, SYNEDIT_DOWN, [ssShift]); + AddKey(ecScrollDown, SYNEDIT_DOWN, [ssCtrl]); + AddKey(ecLeft, SYNEDIT_LEFT, []); + AddKey(ecSelLeft, SYNEDIT_LEFT, [ssShift]); + AddKey(ecWordLeft, SYNEDIT_LEFT, [ssCtrl]); + AddKey(ecSelWordLeft, SYNEDIT_LEFT, [ssShift,ssCtrl]); + AddKey(ecRight, SYNEDIT_RIGHT, []); + AddKey(ecSelRight, SYNEDIT_RIGHT, [ssShift]); + AddKey(ecWordRight, SYNEDIT_RIGHT, [ssCtrl]); + AddKey(ecSelWordRight, SYNEDIT_RIGHT, [ssShift,ssCtrl]); + AddKey(ecPageDown, SYNEDIT_NEXT, []); + AddKey(ecSelPageDown, SYNEDIT_NEXT, [ssShift]); + AddKey(ecPageBottom, SYNEDIT_NEXT, [ssCtrl]); + AddKey(ecSelPageBottom, SYNEDIT_NEXT, [ssShift,ssCtrl]); + AddKey(ecPageUp, SYNEDIT_PRIOR, []); + AddKey(ecSelPageUp, SYNEDIT_PRIOR, [ssShift]); + AddKey(ecPageTop, SYNEDIT_PRIOR, [ssCtrl]); + AddKey(ecSelPageTop, SYNEDIT_PRIOR, [ssShift,ssCtrl]); + AddKey(ecLineStart, SYNEDIT_HOME, []); + AddKey(ecSelLineStart, SYNEDIT_HOME, [ssShift]); + AddKey(ecEditorTop, SYNEDIT_HOME, [ssCtrl]); + AddKey(ecSelEditorTop, SYNEDIT_HOME, [ssShift,ssCtrl]); + AddKey(ecLineEnd, SYNEDIT_END, []); + AddKey(ecSelLineEnd, SYNEDIT_END, [ssShift]); + AddKey(ecEditorBottom, SYNEDIT_END, [ssCtrl]); + AddKey(ecSelEditorBottom, SYNEDIT_END, [ssShift,ssCtrl]); + AddKey(ecToggleMode, SYNEDIT_INSERT, []); + AddKey(ecCopy, SYNEDIT_INSERT, [ssCtrl]); + AddKey(ecCut, SYNEDIT_DELETE, [ssShift]); + AddKey(ecPaste, SYNEDIT_INSERT, [ssShift]); + AddKey(ecDeleteChar, SYNEDIT_DELETE, []); + AddKey(ecDeleteLastChar, SYNEDIT_BACK, []); + AddKey(ecDeleteLastChar, SYNEDIT_BACK, [ssShift]); + AddKey(ecDeleteLastWord, SYNEDIT_BACK, [ssCtrl]); + AddKey(ecUndo, SYNEDIT_BACK, [ssAlt]); + AddKey(ecRedo, SYNEDIT_BACK, [ssAlt,ssShift]); + AddKey(ecLineBreak, SYNEDIT_RETURN, []); + AddKey(ecLineBreak, SYNEDIT_RETURN, [ssShift]); + AddKey(ecTab, SYNEDIT_TAB, []); + AddKey(ecShiftTab, SYNEDIT_TAB, [ssShift]); + AddKey(ecContextHelp, SYNEDIT_F1, []); + + AddKey(ecSelectAll, ord('A'), [ssCtrl]); + AddKey(ecCopy, ord('C'), [ssCtrl]); + AddKey(ecPaste, ord('V'), [ssCtrl]); + AddKey(ecCut, ord('X'), [ssCtrl]); + AddKey(ecBlockIndent, ord('I'), [ssCtrl,ssShift]); + AddKey(ecBlockUnindent, ord('U'), [ssCtrl,ssShift]); + AddKey(ecLineBreak, ord('M'), [ssCtrl]); + AddKey(ecInsertLine, ord('N'), [ssCtrl]); + AddKey(ecDeleteWord, ord('T'), [ssCtrl]); + AddKey(ecDeleteLine, ord('Y'), [ssCtrl]); + AddKey(ecDeleteEOL, ord('Y'), [ssCtrl,ssShift]); + AddKey(ecUndo, ord('Z'), [ssCtrl]); + AddKey(ecRedo, ord('Z'), [ssCtrl,ssShift]); + AddKey(ecGotoMarker0, ord('0'), [ssCtrl]); + AddKey(ecGotoMarker1, ord('1'), [ssCtrl]); + AddKey(ecGotoMarker2, ord('2'), [ssCtrl]); + AddKey(ecGotoMarker3, ord('3'), [ssCtrl]); + AddKey(ecGotoMarker4, ord('4'), [ssCtrl]); + AddKey(ecGotoMarker5, ord('5'), [ssCtrl]); + AddKey(ecGotoMarker6, ord('6'), [ssCtrl]); + AddKey(ecGotoMarker7, ord('7'), [ssCtrl]); + AddKey(ecGotoMarker8, ord('8'), [ssCtrl]); + AddKey(ecGotoMarker9, ord('9'), [ssCtrl]); + AddKey(ecSetMarker0, ord('0'), [ssCtrl,ssShift]); + AddKey(ecSetMarker1, ord('1'), [ssCtrl,ssShift]); + AddKey(ecSetMarker2, ord('2'), [ssCtrl,ssShift]); + AddKey(ecSetMarker3, ord('3'), [ssCtrl,ssShift]); + AddKey(ecSetMarker4, ord('4'), [ssCtrl,ssShift]); + AddKey(ecSetMarker5, ord('5'), [ssCtrl,ssShift]); + AddKey(ecSetMarker6, ord('6'), [ssCtrl,ssShift]); + AddKey(ecSetMarker7, ord('7'), [ssCtrl,ssShift]); + AddKey(ecSetMarker8, ord('8'), [ssCtrl,ssShift]); + AddKey(ecSetMarker9, ord('9'), [ssCtrl,ssShift]); + AddKey(ecNormalSelect, ord('N'), [ssCtrl,ssShift]); + AddKey(ecColumnSelect, ord('C'), [ssCtrl,ssShift]); + AddKey(ecLineSelect, ord('L'), [ssCtrl,ssShift]); + AddKey(ecMatchBracket, ord('B'), [ssCtrl,ssShift]); +{$IFDEF SYN_CodeFolding} + AddKey(ecFoldAll, VK_OEM_MINUS, [ssCtrl, ssShift]); {- _} + AddKey(ecUnfoldAll, VK_OEM_PLUS, [ssCtrl, ssShift]); {= +} + AddKey(ecFoldNearest, VK_OEM_2, [ssCtrl]); // Divide {'/'} + AddKey(ecUnfoldNearest, VK_OEM_2, [ssCtrl, ssShift]); + AddKey(ecFoldLevel1, ord('K'), [ssCtrl], Ord('1'), [ssCtrl]); + AddKey(ecFoldLevel2, ord('K'), [ssCtrl], Ord('2'), [ssCtrl]); + AddKey(ecFoldLevel3, ord('K'), [ssCtrl], Ord('3'), [ssCtrl]); + AddKey(ecUnfoldLevel1, ord('K'), [ssCtrl, ssShift], Ord('1'), [ssCtrl, ssShift]); + AddKey(ecUnfoldLevel2, ord('K'), [ssCtrl, ssShift], Ord('2'), [ssCtrl, ssShift]); + AddKey(ecUnfoldLevel3, ord('K'), [ssCtrl, ssShift], Ord('3'), [ssCtrl, ssShift]); +{$ENDIF} +end; + +procedure TSynEditKeyStrokes.SetItem(Index: Integer; Value: TSynEditKeyStroke); +begin + inherited SetItem(Index, Value); +end; + +procedure TSynEditKeyStrokes.SaveToStream(AStream: TStream); +var + i, Num: Integer; +begin + Num := Count; + AStream.Write(Num, SizeOf(Num)); + for i := 0 to Num - 1 do + Items[i].SaveToStream(AStream); +end; + +function ConvertCodeStringToExtended(AString: string): string; +var + i: Integer; + WorkStr: string; +begin + if pos('ec', AString) = 1 then + begin + Delete(AString, 1, 2); + WorkStr := ''; + + for i := length(AString) downto 1 do + if CharInSet(AString[i], ['A'..'Z', '0'..'9']) and (i > 1) and + not CharInSet(AString[i - 1], ['A'..'Z', '0'..'9']) then + begin + WorkStr := ' ' + AString[i] + WorkStr + end + else + WorkStr := AString[i] + WorkStr; + + trim(WorkStr); + + i := pos('Sel ', WorkStr); + while i <> 0 do + begin + Delete(WorkStr, i, Length('Sel ')); + Insert('Select ', WorkStr, i); + i := pos('Sel ', WorkStr); + end; + + i := pos('Marker ', WorkStr); + while i <> 0 do + begin + Delete(WorkStr, i, Length('Marker ')); + Insert('Bookmark ', WorkStr,i); + i := pos('Marker ', WorkStr); + end; + + Result := Trim(WorkStr); + end + else + Result := AString; +end; + +function ConvertExtendedToCodeString(AString: string): string; +var + i: Integer; + WorkStr: string; +begin + if pos('ec', AString) = 1 then + begin + Result := AString; + Exit; + end; + + WorkStr := AString; + + i := pos('Select All', WorkStr); + if i = 0 then + begin + i := pos('Select ', WorkStr); + while i <> 0 do + begin + Delete(WorkStr,i,Length('Select ')); + Insert('Sel ',WorkStr,i); + i := pos('Select ', WorkStr); + end; + end; + + i := pos('Bookmark ', WorkStr); + while i <> 0 do + begin + Delete(WorkStr,i,Length('Bookmark ')); + Insert('Marker ',WorkStr,i); + i := pos('Bookmark ', WorkStr); + end; + + i := pos(' ', WorkStr); + while i <> 0 do + begin + delete(WorkStr,i,1); + i := pos(' ', WorkStr); + end; + + Result := 'ec' + WorkStr; +end; + +function IndexToEditorCommand(const AIndex: Integer): Integer; +begin + Result := EditorCommandStrs[AIndex].Value; +end; + +function ConvertExtendedToCommand(AString: string): TSynEditorCommand; +begin + Result := ConvertCodeStringToCommand(ConvertExtendedToCodeString(AString)); +end; + +function ConvertCodeStringToCommand(AString: string): TSynEditorCommand; +var + I: Integer; +begin + Result := ecNone; + + AString := Uppercase(AString); + for i := Low(EditorCommandStrs) to High(EditorCommandStrs) do + if Uppercase(EditorCommandStrs[i].Name) = AString then + begin + Result := EditorCommandStrs[i].Value; + Break; + end; +end; + + +initialization + RegisterIntegerConsts(TypeInfo(TSynEditorCommand), IdentToEditorCommand, + EditorCommandToIdent); +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditKeyConst.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditKeyConst.pas new file mode 100644 index 000000000..bba3064b2 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditKeyConst.pas @@ -0,0 +1,121 @@ +{------------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: uRESTDWPrivSynEditKeyCmds.pas, released 2000-04-07. +The Original Code is based on the mwKeyCmds.pas file from the +mwEdit component suite by Martin Waldenburg and other developers, the Initial +Author of this file is Brad Stowers. +All Rights Reserved. + +Contributors to the uRESTDWPrivSynEdit and mwEdit projects are listed in the +Contributors.txt file. + +Alternatively, the contents of this file may be used under the terms of the +GNU General Public License Version 2 or later (the "GPL"), in which case +the provisions of the GPL are applicable instead of those above. +If you wish to allow use of your version of this file only under the terms +of the GPL and not to allow others to use your version of this file +under the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the GPL. +If you do not delete the provisions above, a recipient may use your version +of this file under either the MPL or the GPL. + +$Id: uRESTDWPrivSynEditKeyConst.pas,v 1.4.2.1 2004/08/31 12:55:17 maelh Exp $ + +You may retrieve the latest version of this file at the uRESTDWPrivSynEdit home page, +located at http://uRESTDWPrivSynEdit.SourceForge.net + +Known Issues: +-------------------------------------------------------------------------------} + +{$IFNDEF QSYNEDITKEYCONST} +unit uRESTDWPrivSynEditKeyConst; +{$ENDIF} + +{ This unit provides a translation of DELPHI and CLX key constants to + more readable uRESTDWPrivSynEdit constants } + +{$I uRESTDWPrivSynEdit.inc} + +interface + +uses + Windows; + +const + + SYNEDIT_RETURN = VK_RETURN; + SYNEDIT_ESCAPE = VK_ESCAPE; + SYNEDIT_SPACE = VK_SPACE; + SYNEDIT_PRIOR = VK_PRIOR; + SYNEDIT_NEXT = VK_NEXT; + SYNEDIT_END = VK_END; + SYNEDIT_HOME = VK_HOME; + SYNEDIT_UP = VK_UP; + SYNEDIT_DOWN = VK_DOWN; + SYNEDIT_BACK = VK_BACK; + SYNEDIT_LEFT = VK_LEFT; + SYNEDIT_RIGHT = VK_RIGHT; + SYNEDIT_MENU = VK_MENU; + SYNEDIT_CONTROL = VK_CONTROL; + SYNEDIT_SHIFT = VK_SHIFT; + SYNEDIT_F1 = VK_F1; + SYNEDIT_F2 = VK_F2; + SYNEDIT_F3 = VK_F3; + SYNEDIT_F4 = VK_F4; + SYNEDIT_F5 = VK_F5; + SYNEDIT_F6 = VK_F6; + SYNEDIT_F7 = VK_F7; + SYNEDIT_F8 = VK_F8; + SYNEDIT_F9 = VK_F9; + SYNEDIT_F10 = VK_F10; + SYNEDIT_F11 = VK_F11; + SYNEDIT_F12 = VK_F12; + SYNEDIT_F13 = VK_F13; + SYNEDIT_F14 = VK_F14; + SYNEDIT_F15 = VK_F15; + SYNEDIT_F16 = VK_F16; + SYNEDIT_F17 = VK_F17; + SYNEDIT_F18 = VK_F18; + SYNEDIT_F19 = VK_F19; + SYNEDIT_F20 = VK_F20; + SYNEDIT_F21 = VK_F21; + SYNEDIT_F22 = VK_F22; + SYNEDIT_F23 = VK_F23; + SYNEDIT_F24 = VK_F24; + SYNEDIT_PRINT = VK_PRINT; + SYNEDIT_INSERT = VK_INSERT; + SYNEDIT_DELETE = VK_DELETE; + SYNEDIT_NUMPAD0 = VK_NUMPAD0; + SYNEDIT_NUMPAD1 = VK_NUMPAD1; + SYNEDIT_NUMPAD2 = VK_NUMPAD2; + SYNEDIT_NUMPAD3 = VK_NUMPAD3; + SYNEDIT_NUMPAD4 = VK_NUMPAD4; + SYNEDIT_NUMPAD5 = VK_NUMPAD5; + SYNEDIT_NUMPAD6 = VK_NUMPAD6; + SYNEDIT_NUMPAD7 = VK_NUMPAD7; + SYNEDIT_NUMPAD8 = VK_NUMPAD8; + SYNEDIT_NUMPAD9 = VK_NUMPAD9; + SYNEDIT_MULTIPLY = VK_MULTIPLY; + SYNEDIT_ADD = VK_ADD; + SYNEDIT_SEPARATOR = VK_SEPARATOR; + SYNEDIT_SUBTRACT = VK_SUBTRACT; + SYNEDIT_DECIMAL = VK_DECIMAL; + SYNEDIT_DIVIDE = VK_DIVIDE; + SYNEDIT_NUMLOCK = VK_NUMLOCK; + SYNEDIT_SCROLL = VK_SCROLL; + SYNEDIT_TAB = VK_TAB; + SYNEDIT_CLEAR = VK_CLEAR; + SYNEDIT_PAUSE = VK_PAUSE; + SYNEDIT_CAPITAL = VK_CAPITAL; + +implementation + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditMiscClasses.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditMiscClasses.pas new file mode 100644 index 000000000..1f1c5ca94 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditMiscClasses.pas @@ -0,0 +1,1620 @@ +{------------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: uRESTDWPrivSynEditMiscClasses.pas, released 2000-04-07. +The Original Code is based on the mwSupportClasses.pas file from the +mwEdit component suite by Martin Waldenburg and other developers, the Initial +Author of this file is Michael Hieke. +Unicode translation by Ma�l H�rz. +All Rights Reserved. + +Contributors to the uRESTDWPrivSynEdit and mwEdit projects are listed in the +Contributors.txt file. + +Alternatively, the contents of this file may be used under the terms of the +GNU General Public License Version 2 or later (the "GPL"), in which case +the provisions of the GPL are applicable instead of those above. +If you wish to allow use of your version of this file only under the terms +of the GPL and not to allow others to use your version of this file +under the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the GPL. +If you do not delete the provisions above, a recipient may use your version +of this file under either the MPL or the GPL. + +$Id: uRESTDWPrivSynEditMiscClasses.pas,v 1.35.2.9 2008/09/17 13:59:12 maelh Exp $ + +You may retrieve the latest version of this file at the uRESTDWPrivSynEdit home page, +located at http://uRESTDWPrivSynEdit.SourceForge.net + +Known Issues: +-------------------------------------------------------------------------------} + +{$IFNDEF QSYNEDITMISCCLASSES} +unit uRESTDWPrivSynEditMiscClasses; +{$ENDIF} + +{$I uRESTDWPrivSynEdit.inc} + +interface + +uses + Consts, + Windows, + Messages, + Graphics, + Controls, + Forms, + StdCtrls, + Menus, + Registry, + uRESTDWPrivSynEditTypes, + uRESTDWPrivSynEditKeyConst, + uRESTDWPrivSynUnicode, +{$IFDEF SYN_COMPILER_4_UP} + Math, +{$ENDIF} + Classes, + SysUtils; + +type + TSynSelectedColor = class(TPersistent) + private + FBG: TColor; + FFG: TColor; + FOnChange: TNotifyEvent; + procedure SetBG(Value: TColor); + procedure SetFG(Value: TColor); + public + constructor Create; + procedure Assign(Source: TPersistent); override; + published + property Background: TColor read FBG write SetBG default clHighLight; + property Foreground: TColor read FFG write SetFG default clHighLightText; + property OnChange: TNotifyEvent read FOnChange write FOnChange; + end; + + TSynGutterBorderStyle = (gbsNone, gbsMiddle, gbsRight); + + TSynGutter = class(TPersistent) + private + FFont: TFont; + FColor: TColor; + FBorderColor: TColor; + FWidth: Integer; + FShowLineNumbers: Boolean; + FShowModification: Boolean; + FDigitCount: Integer; + FLeadingZeros: Boolean; + FZeroStart: Boolean; + FLeftOffset: Integer; + FRightOffset: Integer; + FRightMargin: integer; + FOnChange: TNotifyEvent; + FCursor: TCursor; + FVisible: Boolean; + FUseFontStyle: Boolean; + FAutoSize: Boolean; + FAutoSizeDigitCount: Integer; + FBorderStyle: TSynGutterBorderStyle; + FLineNumberStart: Integer; + FGradient: Boolean; + FGradientStartColor: TColor; + FGradientEndColor: TColor; + FGradientSteps: Integer; + FModificationBarWidth: Integer; + FModificationColorModified: TColor; + FModificationColorSaved: TColor; + procedure SetAutoSize(const Value: Boolean); + procedure SetBorderColor(const Value: TColor); + procedure SetColor(const Value: TColor); + procedure SetDigitCount(Value: Integer); + procedure SetLeadingZeros(const Value: Boolean); + procedure SetLeftOffset(Value: Integer); + procedure SetRightOffset(Value: Integer); + procedure SetRightMargin(Value: integer); + procedure SetShowLineNumbers(const Value: Boolean); + procedure SetShowModification(const Value: Boolean); + procedure SetUseFontStyle(Value: Boolean); + procedure SetVisible(Value: Boolean); + procedure SetWidth(Value: Integer); + procedure SetZeroStart(const Value: Boolean); + procedure SetFont(Value: TFont); + procedure OnFontChange(Sender: TObject); + procedure SetBorderStyle(const Value: TSynGutterBorderStyle); + procedure SetLineNumberStart(const Value: Integer); + procedure SetGradient(const Value: Boolean); + procedure SetGradientStartColor(const Value: TColor); + procedure SetGradientEndColor(const Value: TColor); + procedure SetGradientSteps(const Value: Integer); + function GetWidth: Integer; + procedure SetModificationColorModified(const Value: TColor); + procedure SetModificationColorSaved(const Value: TColor); + procedure SetModificationBarWidth(const Value: Integer); + public + constructor Create; + destructor Destroy; override; + procedure Assign(Source: TPersistent); override; + procedure AutoSizeDigitCount(LinesCount: Integer); + function FormatLineNumber(Line: Integer): string; + function RealGutterWidth(CharWidth: Integer): Integer; +//++ DPI-Aware + procedure ChangeScale(M, D: Integer); virtual; +//-- DPI-Aware + published + property AutoSize: Boolean read FAutoSize write SetAutoSize default FALSE; + property BorderStyle: TSynGutterBorderStyle read FBorderStyle + write SetBorderStyle default gbsMiddle; + property Color: TColor read FColor write SetColor default clBtnFace; + property BorderColor: TColor read FBorderColor write SetBorderColor default clWindow; + property Cursor: TCursor read FCursor write FCursor default crDefault; + property DigitCount: Integer read FDigitCount write SetDigitCount + default 4; + property Font: TFont read FFont write SetFont; + property LeadingZeros: Boolean read FLeadingZeros write SetLeadingZeros + default FALSE; + property LeftOffset: Integer read FLeftOffset write SetLeftOffset + default 16; + property ModificationBarWidth: Integer read FModificationBarWidth + write SetModificationBarWidth default 4; + property ModificationColorModified: TColor read FModificationColorModified + write SetModificationColorModified default clYellow; + property ModificationColorSaved: TColor read FModificationColorSaved + write SetModificationColorSaved default clLime; + property RightOffset: Integer read FRightOffset write SetRightOffset + default 2; + property RightMargin: integer read FRightMargin write SetRightMargin + default 2; + property ShowLineNumbers: Boolean read FShowLineNumbers + write SetShowLineNumbers default FALSE; + property ShowModification: Boolean read FShowModification + write SetShowModification default FALSE; + property UseFontStyle: Boolean read FUseFontStyle write SetUseFontStyle + default True; + property Visible: Boolean read FVisible write SetVisible default TRUE; + property Width: Integer read GetWidth write SetWidth default 30; + property ZeroStart: Boolean read FZeroStart write SetZeroStart + default False; + property LineNumberStart: Integer read FLineNumberStart write SetLineNumberStart default 1; + property Gradient: Boolean read FGradient write SetGradient default False; + property GradientStartColor: TColor read FGradientStartColor write SetGradientStartColor default clWindow; + property GradientEndColor: TColor read FGradientEndColor write SetGradientEndColor default clBtnFace; + property GradientSteps: Integer read FGradientSteps write SetGradientSteps default 48; + + property OnChange: TNotifyEvent read FOnChange write FOnChange; + end; + + TSynBookMarkOpt = class(TPersistent) + private + FBookmarkImages: TImageList; + FDrawBookmarksFirst: Boolean; + FEnableKeys: Boolean; + FGlyphsVisible: Boolean; + FLeftMargin: Integer; + FOwner: TComponent; + FXoffset: Integer; + FOnChange: TNotifyEvent; + procedure SetBookmarkImages(const Value: TImageList); + procedure SetDrawBookmarksFirst(Value: Boolean); + procedure SetGlyphsVisible(Value: Boolean); + procedure SetLeftMargin(Value: Integer); + procedure SetXOffset(Value: Integer); + public + constructor Create(AOwner: TComponent); + procedure Assign(Source: TPersistent); override; +//++ DPI-Aware + procedure ChangeScale(M, D: Integer); virtual; +//-- DPI-Aware + published + property BookmarkImages: TImageList + read FBookmarkImages write SetBookmarkImages; + property DrawBookmarksFirst: Boolean read FDrawBookmarksFirst + write SetDrawBookmarksFirst default True; + property EnableKeys: Boolean + read FEnableKeys write FEnableKeys default True; + property GlyphsVisible: Boolean + read FGlyphsVisible write SetGlyphsVisible default True; + property LeftMargin: Integer read FLeftMargin write SetLeftMargin default 2; + property XOffset: Integer read FXoffset write SetXOffset default 12; + + property OnChange: TNotifyEvent read FOnChange write FOnChange; + end; + + TSynGlyph = class(TPersistent) + private + FVisible: Boolean; + FInternalGlyph, FGlyph: TBitmap; + FInternalMaskColor, FMaskColor: TColor; + FOnChange: TNotifyEvent; + procedure SetGlyph(Value: TBitmap); + procedure GlyphChange(Sender: TObject); + procedure SetMaskColor(Value: TColor); + procedure SetVisible(Value: Boolean); + function GetWidth : Integer; + function GetHeight : Integer; + public + constructor Create(aModule: THandle; const aName: string; aMaskColor: TColor); + destructor Destroy; override; + procedure Assign(aSource: TPersistent); override; + procedure Draw(aCanvas: TCanvas; aX, aY, aLineHeight: Integer); + property Width : Integer read GetWidth; + property Height : Integer read GetHeight; +//++ DPI-Aware + procedure ChangeScale(M, D: Integer); virtual; +//-- DPI-Aware + published + property Glyph: TBitmap read FGlyph write SetGlyph; + property MaskColor: TColor read FMaskColor write SetMaskColor default clNone; + property Visible: Boolean read FVisible write SetVisible default True; + + property OnChange: TNotifyEvent read FOnChange write FOnChange; + end; + + { TSynMethodChain } + + ESynMethodChain = class(Exception); + TSynExceptionEvent = procedure (Sender: TObject; E: Exception; + var DoContinue: Boolean) of object; + + TSynMethodChain = class(TObject) + private + FNotifyProcs: TList; + FExceptionHandler: TSynExceptionEvent; + protected + procedure DoFire(const AEvent: TMethod); virtual; abstract; + function DoHandleException(E: Exception): Boolean; virtual; + property ExceptionHandler: TSynExceptionEvent read FExceptionHandler + write FExceptionHandler; + public + constructor Create; virtual; + destructor Destroy; override; + procedure Add(AEvent: TMethod); + procedure Remove(AEvent: TMethod); + procedure Fire; + end; + + { TSynNotifyEventChain } + + TSynNotifyEventChain = class(TSynMethodChain) + private + FSender: TObject; + protected + procedure DoFire(const AEvent: TMethod); override; + public + constructor CreateEx(ASender: TObject); + procedure Add(AEvent: TNotifyEvent); + procedure Remove(AEvent: TNotifyEvent); + property ExceptionHandler; + property Sender: TObject read FSender write FSender; + end; + + { TSynInternalImage } + + TSynInternalImage = class(TObject) + private + FImages : TBitmap; + FWidth : Integer; + FHeight : Integer; + FCount : Integer; + + function CreateBitmapFromInternalList(aModule: THandle; const Name: string): TBitmap; + procedure FreeBitmapFromInternalList; + public + constructor Create(aModule: THandle; const Name: string; Count: Integer); + destructor Destroy; override; + + procedure Draw(ACanvas: TCanvas; Number, X, Y, LineHeight: Integer); overload; + procedure DrawTransparent(ACanvas: TCanvas; Number, X, Y, + LineHeight: Integer; TransparentColor: TColor); overload; +//++ DPI-Aware + procedure ChangeScale(M, D: Integer); virtual; +//-- DPI-Aware + end; + +{ TSynHotKey } + +const + BorderWidth = 0; + +type + TSynBorderStyle = TBorderStyle; + + THKModifier = (hkShift, hkCtrl, hkAlt); + THKModifiers = set of THKModifier; + THKInvalidKey = (hcNone, hcShift, hcCtrl, hcAlt, hcShiftCtrl, + hcShiftAlt, hcCtrlAlt, hcShiftCtrlAlt); + THKInvalidKeys = set of THKInvalidKey; + + TSynHotKey = class(TCustomControl) + private + FBorderStyle: TSynBorderStyle; + FHotKey: TShortCut; + FInvalidKeys: THKInvalidKeys; + FModifiers: THKModifiers; + FPressedOnlyModifiers: Boolean; + procedure SetBorderStyle(const Value: TSynBorderStyle); + procedure SetHotKey(const Value: TShortCut); + procedure SetInvalidKeys(const Value: THKInvalidKeys); + procedure SetModifiers(const Value: THKModifiers); + procedure WMGetDlgCode(var Message: TMessage); message WM_GETDLGCODE; + procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS; + procedure WMSetFocus(var Msg: TWMSetFocus); message WM_SETFOCUS; + protected + procedure DoExit; override; + procedure KeyDown(var Key: Word; Shift: TShiftState); override; + procedure KeyUp(var Key: Word; Shift: TShiftState); override; + procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; + procedure Paint; override; + procedure CreateParams(var Params: TCreateParams); override; + public + constructor Create(AOwner: TComponent); override; + published + property BorderStyle: TSynBorderStyle read FBorderStyle write SetBorderStyle + default bsSingle; + property HotKey: TShortCut read FHotKey write SetHotKey default $0041; { Alt+A } + property InvalidKeys: THKInvalidKeys read FInvalidKeys write SetInvalidKeys default [hcNone, hcShift]; + property Modifiers: THKModifiers read FModifiers write SetModifiers default [hkAlt]; + end; + + TSynEditSearchCustom = class(TComponent) + protected + function GetPattern: UnicodeString; virtual; abstract; + procedure SetPattern(const Value: UnicodeString); virtual; abstract; + function GetLength(Index: Integer): Integer; virtual; abstract; + function GetResult(Index: Integer): Integer; virtual; abstract; + function GetResultCount: Integer; virtual; abstract; + procedure SetOptions(const Value: TSynSearchOptions); virtual; abstract; + public + function FindAll(const NewText: UnicodeString): Integer; virtual; abstract; + function Replace(const aOccurrence, aReplacement: UnicodeString): UnicodeString; virtual; abstract; + property Pattern: UnicodeString read GetPattern write SetPattern; + property ResultCount: Integer read GetResultCount; + property Results[Index: Integer]: Integer read GetResult; + property Lengths[Index: Integer]: Integer read GetLength; + property Options: TSynSearchOptions write SetOptions; + end; + + {$IFNDEF SYN_COMPILER_4_UP} + TBetterRegistry = class(TRegistry) + function OpenKeyReadOnly(const Key: string): Boolean; + end; + {$ELSE} + TBetterRegistry = TRegistry; + {$ENDIF} + +//++ DPI-Aware + procedure ResizeBitmap(Bitmap: TBitmap; const NewWidth, + NewHeight: integer); +//-- DPI-Aware + + +implementation + +uses + uRESTDWPrivSynEditMiscProcs; + +//++ DPI-Aware +procedure ResizeBitmap(Bitmap: TBitmap; const NewWidth, + NewHeight: integer); +var + buffer: TBitmap; +begin + buffer := TBitmap.Create; + try + {$IFDEF SYN_COMPILER_12_UP} + buffer.SetSize(NewWidth, NewHeight); + {$ELSE} + buffer.Width := NewWidth; + buffer.Height := NewHeight; + {$ENDIF} + buffer.Canvas.StretchDraw(Rect(0, 0, NewWidth, NewHeight), Bitmap); + {$IFDEF SYN_COMPILER_12_UP} + buffer.SetSize(NewWidth, NewHeight); + {$ELSE} + buffer.Width := NewWidth; + buffer.Height := NewHeight; + {$ENDIF} + Bitmap.Canvas.Draw(0, 0, buffer); + finally + buffer.Free; + end; +end; +//-- DPI-Aware + +{ TSynSelectedColor } + +constructor TSynSelectedColor.Create; +begin + inherited Create; + FBG := clHighLight; + FFG := clHighLightText; +end; + +procedure TSynSelectedColor.Assign(Source: TPersistent); +var + Src: TSynSelectedColor; +begin + if (Source <> nil) and (Source is TSynSelectedColor) then begin + Src := TSynSelectedColor(Source); + FBG := Src.FBG; + FFG := Src.FFG; + if Assigned(FOnChange) then FOnChange(Self); + end else + inherited Assign(Source); +end; + +procedure TSynSelectedColor.SetBG(Value: TColor); +begin + if (FBG <> Value) then begin + FBG := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynSelectedColor.SetFG(Value: TColor); +begin + if (FFG <> Value) then begin + FFG := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +{ TSynGutter } +//++ DPI-Aware +procedure TSynGutter.ChangeScale(M, D: Integer); +begin + fWidth := MulDiv(fWidth, M, D); + fLeftOffset := MulDiv(fLeftOffset, M, D); + fRightOffset := MulDiv(fRightOffset, M, D); + fFont.Height := MulDiv(fFont.Height, M, D); + if Assigned(fOnChange) then fOnChange(Self); +end; +//-- DPI-Aware + + +constructor TSynGutter.Create; +begin + inherited Create; + FFont := TFont.Create; + FFont.Name := 'Courier New'; + FFont.Size := 8; + FFont.Style := []; + FUseFontStyle := True; + FFont.OnChange := OnFontChange; + + FColor := clBtnFace; + FVisible := TRUE; + FWidth := 30; + FLeftOffset := 16; + FDigitCount := 4; + FAutoSizeDigitCount := FDigitCount; + FRightOffset := 2; + FRightMargin := 2; + FBorderColor := clWindow; + FBorderStyle := gbsMiddle; + FLineNumberStart := 1; + FZeroStart := False; + FGradient := False; + FGradientStartColor := clWindow; + FGradientEndColor := clBtnFace; + FGradientSteps := 48; + + FShowModification := FALSE; + FModificationBarWidth := 4; + FModificationColorModified := clYellow; + FModificationColorSaved := clLime; +end; + +destructor TSynGutter.Destroy; +begin + FFont.Free; + inherited Destroy; +end; + +procedure TSynGutter.Assign(Source: TPersistent); +var + Src: TSynGutter; +begin + if Assigned(Source) and (Source is TSynGutter) then + begin + Src := TSynGutter(Source); + FFont.Assign(src.Font); + FUseFontStyle := src.FUseFontStyle; + FColor := Src.FColor; + FVisible := Src.FVisible; + FWidth := Src.FWidth; + FShowLineNumbers := Src.FShowLineNumbers; + FLeadingZeros := Src.FLeadingZeros; + FZeroStart := Src.FZeroStart; + FLeftOffset := Src.FLeftOffset; + FDigitCount := Src.FDigitCount; + FRightOffset := Src.FRightOffset; + FRightMargin := Src.FRightMargin; + FAutoSize := Src.FAutoSize; + FAutoSizeDigitCount := Src.FAutoSizeDigitCount; + FLineNumberStart := Src.FLineNumberStart; + FBorderColor := Src.FBorderColor; + FBorderStyle := Src.FBorderStyle; + FGradient := Src.FGradient; + FGradientStartColor := Src.FGradientStartColor; + FGradientEndColor := Src.FGradientEndColor; + FGradientSteps := Src.FGradientSteps; + if Assigned(FOnChange) then FOnChange(Self); + end + else + inherited; +end; + +procedure TSynGutter.AutoSizeDigitCount(LinesCount: Integer); +var + nDigits: Integer; +begin + if FVisible and FAutoSize and FShowLineNumbers then + begin + if FZeroStart then + Dec(LinesCount) + else if FLineNumberStart > 1 then + Inc(LinesCount, FLineNumberStart - 1); + + nDigits := Max(Length(IntToStr(LinesCount)), FDigitCount); + if FAutoSizeDigitCount <> nDigits then begin + FAutoSizeDigitCount := nDigits; + if Assigned(FOnChange) then FOnChange(Self); + end; + end else + FAutoSizeDigitCount := FDigitCount; +end; + +function TSynGutter.FormatLineNumber(Line: Integer): string; +var + i: Integer; +begin + if FZeroStart then + Dec(Line) + else if FLineNumberStart > 1 then + Inc(Line, FLineNumberStart - 1); + Result := Format('%*d', [FAutoSizeDigitCount, Line]); + if FLeadingZeros then + for i := 1 to FAutoSizeDigitCount - 1 do + begin + if (Result[i] <> ' ') then + Break; + Result[i] := '0'; + end; +end; + +function TSynGutter.RealGutterWidth(CharWidth: Integer): Integer; +begin + if not FVisible then + Result := 0 + else + begin + if FShowLineNumbers then + Result := FLeftOffset + FRightOffset + FAutoSizeDigitCount * CharWidth + FRightMargin + else if FAutoSize then + Result := FLeftOffset + FRightOffset + FRightMargin + else + Result := FWidth; + + // take modification indicator into account + if FShowModification then + Result := Result + FModificationBarWidth; + end; +end; + +procedure TSynGutter.SetAutoSize(const Value: Boolean); +begin + if FAutoSize <> Value then begin + FAutoSize := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetColor(const Value: TColor); +begin + if FColor <> Value then begin + FColor := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetFont(Value: TFont); +begin + FFont.Assign(Value); +end; + +procedure TSynGutter.OnFontChange(Sender: TObject); +begin + if Assigned(FOnChange) then FOnChange(Self); +end; + +procedure TSynGutter.SetDigitCount(Value: Integer); +begin + Value := MinMax(Value, 2, 12); + if FDigitCount <> Value then begin + FDigitCount := Value; + FAutoSizeDigitCount := FDigitCount; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetLeadingZeros(const Value: Boolean); +begin + if FLeadingZeros <> Value then begin + FLeadingZeros := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetLeftOffset(Value: Integer); +begin + Value := Max(0, Value); + if FLeftOffset <> Value then begin + FLeftOffset := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetRightOffset(Value: Integer); +begin + Value := Max(0, Value); + if FRightOffset <> Value then begin + FRightOffset := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetRightMargin(Value: integer); +begin + Value := Max(0, Value); + if fRightMargin <> Value then begin + fRightMargin := Value; + if Assigned(fOnChange) then fOnChange(Self); + end; +end; + +procedure TSynGutter.SetShowLineNumbers(const Value: Boolean); +begin + if FShowLineNumbers <> Value then begin + FShowLineNumbers := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetShowModification(const Value: Boolean); +begin + if FShowModification <> Value then begin + FShowModification := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetUseFontStyle(Value: Boolean); +begin + if FUseFontStyle <> Value then begin + FUseFontStyle := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetVisible(Value: Boolean); +begin + if FVisible <> Value then begin + FVisible := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetWidth(Value: Integer); +begin + Value := Max(0, Value); + if FWidth <> Value then begin + FWidth := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetZeroStart(const Value: Boolean); +begin + if FZeroStart <> Value then begin + FZeroStart := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetBorderStyle(const Value: TSynGutterBorderStyle); +begin + FBorderStyle := Value; + if Assigned(FOnChange) then FOnChange(Self); +end; + +procedure TSynGutter.SetLineNumberStart(const Value: Integer); +begin + if Value <> FLineNumberStart then + begin + FLineNumberStart := Value; + if FLineNumberStart < 0 then + FLineNumberStart := 0; + if FLineNumberStart = 0 then + FZeroStart := True + else + FZeroStart := False; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetModificationBarWidth(const Value: Integer); +begin + if FModificationBarWidth <> Value then + begin + FModificationBarWidth := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetModificationColorModified(const Value: TColor); +begin + if FModificationColorModified <> Value then + begin + FModificationColorModified := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetModificationColorSaved(const Value: TColor); +begin + if FModificationColorSaved <> Value then + begin + FModificationColorSaved := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetBorderColor(const Value: TColor); +begin + if FBorderColor <> Value then + begin + FBorderColor := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetGradient(const Value: Boolean); +begin + if Value <> FGradient then + begin + FGradient := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetGradientEndColor(const Value: TColor); +begin + if Value <> FGradientEndColor then + begin + FGradientEndColor := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetGradientStartColor(const Value: TColor); +begin + if Value <> FGradientStartColor then + begin + FGradientStartColor := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGutter.SetGradientSteps(const Value: Integer); +begin + if Value <> FGradientSteps then + begin + FGradientSteps := Value; + if FGradientSteps < 2 then + FGradientSteps := 2; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +function TSynGutter.GetWidth: Integer; +begin + if not Visible then + Result := 0 + else + Result := FWidth; +end; + +{ TSynBookMarkOpt } + +//++ DPI-Aware +procedure TSynBookMarkOpt.ChangeScale(M, D: Integer); +Var + L : Integer; +begin + L := (M div D) * D; // Factor multiple of 100% + fLeftMargin := MulDiv(fLeftMargin, L, D); + fXoffset := MulDiv(fXoffset, L, D); +end; +//-- DPI-Aware + +constructor TSynBookMarkOpt.Create(AOwner: TComponent); +begin + inherited Create; + FDrawBookmarksFirst := TRUE; + FEnableKeys := True; + FGlyphsVisible := True; + FLeftMargin := 2; + FOwner := AOwner; + FXoffset := 12; +end; + +procedure TSynBookMarkOpt.Assign(Source: TPersistent); +var + Src: TSynBookMarkOpt; +begin + if (Source <> nil) and (Source is TSynBookMarkOpt) then begin + Src := TSynBookMarkOpt(Source); + FBookmarkImages := Src.FBookmarkImages; + FDrawBookmarksFirst := Src.FDrawBookmarksFirst; + FEnableKeys := Src.FEnableKeys; + FGlyphsVisible := Src.FGlyphsVisible; + FLeftMargin := Src.FLeftMargin; + FXoffset := Src.FXoffset; + if Assigned(FOnChange) then FOnChange(Self); + end else + inherited Assign(Source); +end; + +procedure TSynBookMarkOpt.SetBookmarkImages(const Value: TImageList); +begin + if FBookmarkImages <> Value then begin + FBookmarkImages := Value; + if Assigned(FBookmarkImages) then FBookmarkImages.FreeNotification(FOwner); + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynBookMarkOpt.SetDrawBookmarksFirst(Value: Boolean); +begin + if Value <> FDrawBookmarksFirst then begin + FDrawBookmarksFirst := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynBookMarkOpt.SetGlyphsVisible(Value: Boolean); +begin + if FGlyphsVisible <> Value then begin + FGlyphsVisible := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynBookMarkOpt.SetLeftMargin(Value: Integer); +begin + if FLeftMargin <> Value then begin + FLeftMargin := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynBookMarkOpt.SetXOffset(Value: Integer); +begin + if FXoffset <> Value then begin + FXoffset := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +{ TSynGlyph } + +//++ DPI-Aware +procedure TSynGlyph.ChangeScale(M, D: Integer); +Var + L : Integer; +begin + L := (M div D) * D; // Factor multiple of 100% + ResizeBitmap(fInternalGlyph, MulDiv(fInternalGlyph.Width, L, D), MulDiv(fInternalGlyph.Height, L, D)); + ResizeBitmap(fGlyph, MulDiv(fGlyph.Width, L, D), MulDiv(fGlyph.Height, L, D)); +end; +//-- DPI-Aware + +constructor TSynGlyph.Create(aModule: THandle; const aName: string; aMaskColor: TColor); +begin + inherited Create; + + if aName <> '' then + begin + FInternalGlyph := TBitmap.Create; + try + FInternalGlyph.LoadFromResourceName(aModule, aName); + FInternalMaskColor := aMaskColor; + except + FreeAndNil(FInternalGlyph); + FInternalMaskColor := clNone; + end; + end + else + FInternalMaskColor := clNone; + + FVisible := True; + FGlyph := TBitmap.Create; + FGlyph.OnChange := GlyphChange; + FMaskColor := clNone; +end; + +destructor TSynGlyph.Destroy; +begin + if Assigned(FInternalGlyph) then + FreeAndNil(FInternalGlyph); + + FGlyph.Free; + + inherited Destroy; +end; + +procedure TSynGlyph.Assign(aSource: TPersistent); +var + vSrc : TSynGlyph; +begin + if Assigned(aSource) and (aSource is TSynGlyph) then + begin + vSrc := TSynGlyph(aSource); + FInternalGlyph := vSrc.FInternalGlyph; + FInternalMaskColor := vSrc.FInternalMaskColor; + FVisible := vSrc.FVisible; + FGlyph := vSrc.FGlyph; + FMaskColor := vSrc.FMaskColor; + if Assigned(FOnChange) then FOnChange(Self); + end + else + inherited; +end; + +procedure TSynGlyph.Draw(aCanvas: TCanvas; aX, aY, aLineHeight: Integer); +var + rcSrc, rcDest : TRect; + vGlyph : TBitmap; + vMaskColor : TColor; +begin + if not FGlyph.Empty then + begin + vGlyph := FGlyph; + vMaskColor := FMaskColor; + end + else if Assigned(FInternalGlyph) then + begin + vGlyph := FInternalGlyph; + vMaskColor := FInternalMaskColor; + end + else + Exit; + + if aLineHeight >= vGlyph.Height then + begin + rcSrc := Rect(0, 0, vGlyph.Width, vGlyph.Height); + Inc(aY, (aLineHeight - vGlyph.Height) div 2); + rcDest := Rect(aX, aY, aX + vGlyph.Width, aY + vGlyph.Height); + end + else + begin + rcDest := Rect(aX, aY, aX + vGlyph.Width, aY + aLineHeight); + aY := (vGlyph.Height - aLineHeight) div 2; + rcSrc := Rect(0, aY, vGlyph.Width, aY + aLineHeight); + end; + + aCanvas.BrushCopy(rcDest, vGlyph, rcSrc, vMaskColor); +end; + +procedure TSynGlyph.SetGlyph(Value: TBitmap); +begin + FGlyph.Assign(Value); +end; + +procedure TSynGlyph.GlyphChange(Sender: TObject); +begin + if Assigned(FOnChange) then FOnChange(Self); +end; + +procedure TSynGlyph.SetMaskColor(Value: TColor); +begin + if FMaskColor <> Value then + begin + FMaskColor := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +procedure TSynGlyph.SetVisible(Value: Boolean); +begin + if FVisible <> Value then + begin + FVisible := Value; + if Assigned(FOnChange) then FOnChange(Self); + end; +end; + +function TSynGlyph.GetWidth : Integer; +begin + if not FGlyph.Empty then + Result := FGlyph.Width + else + if Assigned(FInternalGlyph) then + Result := FInternalGlyph.Width + else + Result := 0; +end; + +function TSynGlyph.GetHeight : Integer; +begin + if not FGlyph.Empty then + Result := FGlyph.Height + else + if Assigned(FInternalGlyph) then + Result := FInternalGlyph.Height + else + Result := 0; +end; + +{ TSynMethodChain } + +procedure TSynMethodChain.Add(AEvent: TMethod); +begin + if not Assigned(@AEvent) then + raise ESynMethodChain.CreateFmt( + '%s.Entry : the parameter `AEvent'' must be specified.', [ClassName]); + + with FNotifyProcs, AEvent do + begin + Add(Code); + Add(Data); + end +end; + +constructor TSynMethodChain.Create; +begin + inherited; + FNotifyProcs := TList.Create; +end; + +destructor TSynMethodChain.Destroy; +begin + FNotifyProcs.Free; + inherited; +end; + +function TSynMethodChain.DoHandleException(E: Exception): Boolean; +begin + if not Assigned(FExceptionHandler) then + raise E + else + try + Result := True; + FExceptionHandler(Self, E, Result); + except + raise ESynMethodChain.CreateFmt( + '%s.DoHandleException : MUST NOT occur any kind of exception in '+ + 'ExceptionHandler', [ClassName]); + end; +end; + +procedure TSynMethodChain.Fire; +var + AMethod: TMethod; + i: Integer; +begin + i := 0; + with FNotifyProcs, AMethod do + while i < Count do + try + repeat + Code := Items[i]; + Inc(i); + Data := Items[i]; + Inc(i); + + DoFire(AMethod) + until i >= Count; + except + on E: Exception do + if not DoHandleException(E) then + i := MaxInt; + end; +end; + +procedure TSynMethodChain.Remove(AEvent: TMethod); +var + i: Integer; +begin + if not Assigned(@AEvent) then + raise ESynMethodChain.CreateFmt( + '%s.Remove: the parameter `AEvent'' must be specified.', [ClassName]); + + with FNotifyProcs, AEvent do + begin + i := Count - 1; + while i > 0 do + if Items[i] <> Data then + Dec(i, 2) + else + begin + Dec(i); + if Items[i] = Code then + begin + Delete(i); + Delete(i); + end; + Dec(i); + end; + end; +end; + +{ TSynNotifyEventChain } + +procedure TSynNotifyEventChain.Add(AEvent: TNotifyEvent); +begin + inherited Add(TMethod(AEvent)); +end; + +constructor TSynNotifyEventChain.CreateEx(ASender: TObject); +begin + inherited Create; + FSender := ASender; +end; + +procedure TSynNotifyEventChain.DoFire(const AEvent: TMethod); +begin + TNotifyEvent(AEvent)(FSender); +end; + +procedure TSynNotifyEventChain.Remove(AEvent: TNotifyEvent); +begin + inherited Remove(TMethod(AEvent)); +end; + + +{ TSynInternalImage } + +type + TInternalResource = class (TObject) + public + UsageCount : Integer; + Name : string; + Bitmap : TBitmap; + end; + +var + InternalResources: TList; + +//++ DPI-Aware +procedure TSynInternalImage.ChangeScale(M, D: Integer); +Var + L: Integer; +begin + L := (M div D) * D; // Factor multiple of 100% + fWidth := MulDiv(fWidth, L, D); + ResizeBitmap(fImages, fWidth * fCount, MulDiv(fImages.Height, L, D)); + fHeight := fImages.Height; +end; +//-- DPI-Aware + +constructor TSynInternalImage.Create(aModule: THandle; const Name: string; + Count: Integer); +begin + inherited Create; + FImages := CreateBitmapFromInternalList(aModule, Name); + FWidth := (FImages.Width + Count shr 1) div Count; + FHeight := FImages.Height; + FCount := Count; +end; + +destructor TSynInternalImage.Destroy; +begin + FreeBitmapFromInternalList; + inherited Destroy; +end; + +function TSynInternalImage.CreateBitmapFromInternalList(aModule: THandle; + const Name: string): TBitmap; +var + idx: Integer; + newIntRes: TInternalResource; +begin + { There is no list until now } + if (InternalResources = nil) then + InternalResources := TList.Create; + + { Search the list for the needed resource } + for idx := 0 to InternalResources.Count - 1 do + if (TInternalResource(InternalResources[idx]).Name = UpperCase(Name)) then + with TInternalResource(InternalResources[idx]) do begin + UsageCount := UsageCount + 1; + Result := Bitmap; + Exit; + end; + + { There is no loaded resource in the list so let's create a new one } + Result := TBitmap.Create; + try + Result.LoadFromResourceName(aModule, Name); + except + Result.Free; + Result := nil; + Exit; + end; + + { Add the new resource to our list } + newIntRes:= TInternalResource.Create; + newIntRes.UsageCount := 1; + newIntRes.Name := UpperCase(Name); + newIntRes.Bitmap := Result; + InternalResources.Add(newIntRes); +end; + +procedure TSynInternalImage.FreeBitmapFromInternalList; +var + idx: Integer; + intRes: TInternalResource; + function FindImageInList: Integer; + begin + for Result := 0 to InternalResources.Count - 1 do + if (TInternalResource (InternalResources[Result]).Bitmap = FImages) then + Exit; + Result := -1; + end; +begin + { Search the index of our resource in the list } + idx := FindImageInList; + + { Ey, what's this ???? } + if (idx = -1) then + Exit; + + { Decrement the usagecount in the object. If there are no more users + remove the object from the list and free it } + intRes := TInternalResource (InternalResources[idx]); + with intRes do begin + UsageCount := UsageCount - 1; + if (UsageCount = 0) then begin + Bitmap.Free; + InternalResources.Delete (idx); + intRes.Free; + end; + end; + + { If there are no more entries in the list free it } + if (InternalResources.Count = 0) then begin + InternalResources.Free; + InternalResources := nil; + end; +end; + +procedure TSynInternalImage.Draw(ACanvas: TCanvas; + Number, X, Y, LineHeight: Integer); +var + rcSrc, rcDest: TRect; +begin + if (Number >= 0) and (Number < FCount) then + begin + if LineHeight >= FHeight then begin + rcSrc := Rect(Number * FWidth, 0, (Number + 1) * FWidth, FHeight); + Inc(Y, (LineHeight - FHeight) div 2); + rcDest := Rect(X, Y, X + FWidth, Y + FHeight); + end else begin + rcDest := Rect(X, Y, X + FWidth, Y + LineHeight); + Y := (FHeight - LineHeight) div 2; + rcSrc := Rect(Number * FWidth, Y, (Number + 1) * FWidth, + Y + LineHeight); + end; + ACanvas.CopyRect(rcDest, FImages.Canvas, rcSrc); + end; +end; + +procedure TSynInternalImage.DrawTransparent(ACanvas: TCanvas; Number, X, Y, + LineHeight: Integer; TransparentColor: TColor); +var + rcSrc, rcDest: TRect; +begin + if (Number >= 0) and (Number < FCount) then + begin + if LineHeight >= FHeight then begin + rcSrc := Rect(Number * FWidth, 0, (Number + 1) * FWidth, FHeight); + Inc(Y, (LineHeight - FHeight) div 2); + rcDest := Rect(X, Y, X + FWidth, Y + FHeight); + end else begin + rcDest := Rect(X, Y, X + FWidth, Y + LineHeight); + Y := (FHeight - LineHeight) div 2; + rcSrc := Rect(Number * FWidth, Y, (Number + 1) * FWidth, + Y + LineHeight); + end; + ACanvas.BrushCopy(rcDest, FImages, rcSrc, TransparentColor); + end; +end; + + +{ TSynHotKey } + +function KeySameAsShiftState(Key: Word; Shift: TShiftState): Boolean; +begin + Result := (Key = SYNEDIT_SHIFT) and (ssShift in Shift) or + (Key = SYNEDIT_CONTROL) and (ssCtrl in Shift) or + (Key = SYNEDIT_MENU) and (ssAlt in Shift); +end; + +function ModifiersToShiftState(Modifiers: THKModifiers): TShiftState; +begin + Result := []; + if hkShift in Modifiers then Include(Result, ssShift); + if hkCtrl in Modifiers then Include(Result, ssCtrl); + if hkAlt in Modifiers then Include(Result, ssAlt); +end; + +function ShiftStateToTHKInvalidKey(Shift: TShiftState): THKInvalidKey; +begin + Shift := Shift * [ssShift, ssAlt, ssCtrl]; + if Shift = [ssShift] then + Result := hcShift + else if Shift = [ssCtrl] then + Result := hcCtrl + else if Shift = [ssAlt] then + Result := hcAlt + else if Shift = [ssShift, ssCtrl] then + Result := hcShiftCtrl + else if Shift = [ssShift, ssAlt] then + Result := hcShiftAlt + else if Shift = [ssCtrl, ssAlt] then + Result := hcCtrlAlt + else if Shift = [ssShift, ssCtrl, ssAlt] then + Result := hcShiftCtrlAlt + else + Result := hcNone; +end; + +function ShortCutToTextEx(Key: Word; Shift: TShiftState): UnicodeString; +begin + if ssCtrl in Shift then Result := SmkcCtrl; + if ssShift in Shift then Result := Result + SmkcShift; + if ssAlt in Shift then Result := Result + SmkcAlt; + + Result := Result + ShortCutToText(TShortCut(Key)); + if Result = '' then + Result := srNone; +end; + +constructor TSynHotKey.Create(AOwner: TComponent); +begin + inherited; + + BorderStyle := bsSingle; + {$IFDEF SYN_COMPILER_7_UP} + ControlStyle := ControlStyle + [csNeedsBorderPaint]; + {$ENDIF} + + FInvalidKeys := [hcNone, hcShift]; + FModifiers := [hkAlt]; + SetHotKey($0041); { Alt+A } + + ParentColor := False; + Color := clWindow; + TabStop := True; +end; + +procedure TSynHotKey.CreateParams(var Params: TCreateParams); +const + BorderStyles: array[TSynBorderStyle] of DWORD = (0, WS_BORDER); + ClassStylesOff = CS_VREDRAW or CS_HREDRAW; +begin + inherited CreateParams(Params); + with Params do + begin + WindowClass.Style := WindowClass.Style and not ClassStylesOff; + Style := Style or BorderStyles[FBorderStyle] or WS_CLIPCHILDREN; + + if NewStyleControls and Ctl3D and (FBorderStyle = bsSingle) then + begin + Style := Style and not WS_BORDER; + ExStyle := ExStyle or WS_EX_CLIENTEDGE; + end; + end; +end; + +procedure TSynHotKey.DoExit; +begin + inherited; + if FPressedOnlyModifiers then + begin + Text := srNone; + Invalidate; + end; +end; + +procedure TSynHotKey.KeyDown(var Key: Word; Shift: TShiftState); +var + MaybeInvalidKey: THKInvalidKey; + SavedKey: Word; + {$IFDEF SYN_LINUX} + Code: Byte; + {$ENDIF} +begin + {$IFDEF SYN_LINUX} + // uniform Keycode: key has the same value wether Shift is pressed or not + if Key <= 255 then + begin + Code := XKeysymToKeycode(Xlib.PDisplay(QtDisplay), Key); + Key := XKeycodeToKeysym(Xlib.PDisplay(QtDisplay), Code, 0); + if AnsiChar(Key) in ['a'..'z'] then Key := Ord(UpCase(AnsiChar(Key))); + end; + {$ENDIF} + + SavedKey := Key; + FPressedOnlyModifiers := KeySameAsShiftState(Key, Shift); + + MaybeInvalidKey := ShiftStateToTHKInvalidKey(Shift); + if MaybeInvalidKey in FInvalidKeys then + Shift := ModifiersToShiftState(FModifiers); + + if not FPressedOnlyModifiers then + begin + FHotKey := ShortCut(Key, Shift) + end + else + begin + FHotKey := 0; + Key := 0; + end; + + if Text <> ShortCutToTextEx(Key, Shift) then + begin + Text := ShortCutToTextEx(Key, Shift); + Invalidate; + SetCaretPos(BorderWidth + 1 + TextWidth(Canvas, Text), BorderWidth + 1); + end; + + Key := SavedKey; +end; + +procedure TSynHotKey.KeyUp(var Key: Word; Shift: TShiftState); +{$IFDEF SYN_LINUX} +var + Code: Byte; +{$ENDIF} +begin + {$IFDEF SYN_LINUX} + // uniform Keycode: key has the same value wether Shift is pressed or not + if Key <= 255 then + begin + Code := XKeysymToKeycode(Xlib.PDisplay(QtDisplay), Key); + Key := XKeycodeToKeysym(Xlib.PDisplay(QtDisplay), Code, 0); + if AnsiChar(Key) in ['a'..'z'] then Key := Ord(UpCase(AnsiChar(Key))); + end; + {$ENDIF} + + if FPressedOnlyModifiers then + begin + Text := srNone; + Invalidate; + SetCaretPos(BorderWidth + 1 + TextWidth(Canvas, Text), BorderWidth + 1); + end; +end; + +procedure TSynHotKey.MouseDown(Button: TMouseButton; Shift: TShiftState; X, + Y: Integer); +begin + inherited; + SetFocus; +end; + +procedure TSynHotKey.Paint; +var + r: TRect; +begin + r := ClientRect; + + Canvas.Brush.Style := bsSolid; + Canvas.Brush.Color := Color; + InflateRect(r, -BorderWidth, -BorderWidth); + Canvas.FillRect(r); + TextRect(Canvas, r, BorderWidth + 1, BorderWidth + 1, Text); +end; + +procedure TSynHotKey.SetBorderStyle(const Value: TSynBorderStyle); +begin + if FBorderStyle <> Value then + begin + FBorderStyle := Value; + RecreateWnd; + end; +end; + +procedure TSynHotKey.SetHotKey(const Value: TShortCut); +var + Key: Word; + Shift: TShiftState; + MaybeInvalidKey: THKInvalidKey; +begin + ShortCutToKey(Value, Key, Shift); + + MaybeInvalidKey := ShiftStateToTHKInvalidKey(Shift); + if MaybeInvalidKey in FInvalidKeys then + Shift := ModifiersToShiftState(FModifiers); + + FHotKey := ShortCut(Key, Shift); + Text := ShortCutToTextEx(Key, Shift); + Invalidate; + if not Visible then + SetCaretPos(BorderWidth + 1 + TextWidth(Canvas, Text), BorderWidth + 1); +end; + +procedure TSynHotKey.SetInvalidKeys(const Value: THKInvalidKeys); +begin + FInvalidKeys := Value; + SetHotKey(FHotKey); +end; + +procedure TSynHotKey.SetModifiers(const Value: THKModifiers); +begin + FModifiers := Value; + SetHotKey(FHotKey); +end; + +procedure TSynHotKey.WMGetDlgCode(var Message: TMessage); +begin + Message.Result := DLGC_WANTTAB or DLGC_WANTARROWS; +end; + +procedure TSynHotKey.WMKillFocus(var Msg: TWMKillFocus); +begin + DestroyCaret; +end; + +procedure TSynHotKey.WMSetFocus(var Msg: TWMSetFocus); +begin + Canvas.Font := Font; + CreateCaret(Handle, 0, 1, -Canvas.Font.Height + 2); + SetCaretPos(BorderWidth + 1 + TextWidth(Canvas, Text), BorderWidth + 1); + ShowCaret(Handle); +end; + + +{$IFNDEF SYN_COMPILER_4_UP} + +{ TBetterRegistry } + +function TBetterRegistry.OpenKeyReadOnly(const Key: string): Boolean; + + function IsRelative(const Value: string): Boolean; + begin + Result := not ((Value <> '') and (Value[1] = '\')); + end; + +var + TempKey: HKey; + S: string; + Relative: Boolean; +begin + S := Key; + Relative := IsRelative(S); + + if not Relative then Delete(S, 1, 1); + TempKey := 0; + Result := RegOpenKeyEx(GetBaseKey(Relative), PChar(S), 0, + KEY_READ, TempKey) = ERROR_SUCCESS; + if Result then + begin + if (CurrentKey <> 0) and Relative then S := CurrentPath + '\' + S; + ChangeKey(TempKey, S); + end; +end; { TBetterRegistry.OpenKeyReadOnly } + +{$ENDIF SYN_COMPILER_4_UP} + +begin + InternalResources := nil; +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditMiscProcs.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditMiscProcs.pas new file mode 100644 index 000000000..076d21239 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditMiscProcs.pas @@ -0,0 +1,963 @@ +{------------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: uRESTDWPrivSynEditMiscProcs.pas, released 2000-04-07. +The Original Code is based on the mwSupportProcs.pas file from the +mwEdit component suite by Martin Waldenburg and other developers, the Initial +Author of this file is Michael Hieke. +Unicode translation by Mal Hrz. +All Rights Reserved. + +Contributors to the uRESTDWPrivSynEdit and mwEdit projects are listed in the +Contributors.txt file. + +Alternatively, the contents of this file may be used under the terms of the +GNU General Public License Version 2 or later (the "GPL"), in which case +the provisions of the GPL are applicable instead of those above. +If you wish to allow use of your version of this file only under the terms +of the GPL and not to allow others to use your version of this file +under the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the GPL. +If you do not delete the provisions above, a recipient may use your version +of this file under either the MPL or the GPL. + +$Id: uRESTDWPrivSynEditMiscProcs.pas,v 1.35.2.8 2009/09/28 17:54:20 maelh Exp $ + +You may retrieve the latest version of this file at the uRESTDWPrivSynEdit home page, +located at http://uRESTDWPrivSynEdit.SourceForge.net + +Known Issues: +-------------------------------------------------------------------------------} + +{$IFNDEF QSYNEDITMISCPROCS} +unit uRESTDWPrivSynEditMiscProcs; +{$ENDIF} + +{$I uRESTDWPrivSynEdit.inc} + +interface + +uses + Windows, + Graphics, + uRESTDWPrivSynEditTypes, + uRESTDWPrivSynEditHighlighter, + uRESTDWPrivSynUnicode, +{$IFDEF SYN_COMPILER_4_UP} + Math, +{$ENDIF} + Classes; + +const + MaxIntArraySize = MaxInt div 16; + +type + PIntArray = ^TIntArray; + TIntArray = array[0..MaxIntArraySize - 1] of Integer; + +{$IFNDEF SYN_COMPILER_4_UP} +function Max(x, y: Integer): Integer; +function Min(x, y: Integer): Integer; +{$ENDIF} + +function MinMax(x, mi, ma: Integer): Integer; +procedure SwapInt(var l, r: Integer); +function MaxPoint(const P1, P2: TPoint): TPoint; +function MinPoint(const P1, P2: TPoint): TPoint; + +function GetIntArray(Count: Cardinal; InitialValue: Integer): PIntArray; + +procedure InternalFillRect(dc: HDC; const rcPaint: TRect); + +// Converting tabs to spaces: To use the function several times it's better +// to use a function pointer that is set to the fastest conversion function. +type + TConvertTabsProc = function(const Line: UnicodeString; + TabWidth: Integer): UnicodeString; + +function GetBestConvertTabsProc(TabWidth: Integer): TConvertTabsProc; +// This is the slowest conversion function which can handle TabWidth <> 2^n. +function ConvertTabs(const Line: UnicodeString; TabWidth: Integer): UnicodeString; + +type + TConvertTabsProcEx = function(const Line: UnicodeString; TabWidth: Integer; + var HasTabs: Boolean): UnicodeString; + +function GetBestConvertTabsProcEx(TabWidth: Integer): TConvertTabsProcEx; +// This is the slowest conversion function which can handle TabWidth <> 2^n. +function ConvertTabsEx(const Line: UnicodeString; TabWidth: Integer; + var HasTabs: Boolean): UnicodeString; + +function GetExpandedLength(const aStr: UnicodeString; aTabWidth: Integer): Integer; + +function CharIndex2CaretPos(Index, TabWidth: Integer; + const Line: UnicodeString): Integer; +function CaretPos2CharIndex(Position, TabWidth: Integer; const Line: UnicodeString; + var InsideTabChar: Boolean): Integer; + +// search for the first char of set AChars in Line, starting at index Start +function StrScanForCharInCategory(const Line: UnicodeString; Start: Integer; + IsOfCategory: TCategoryMethod): Integer; +// the same, but searching backwards +function StrRScanForCharInCategory(const Line: UnicodeString; Start: Integer; + IsOfCategory: TCategoryMethod): Integer; + +function GetEOL(Line: PWideChar): PWideChar; + +// Remove all '/' characters from string by changing them into '\.'. +// Change all '\' characters into '\\' to allow for unique decoding. +function EncodeString(s: UnicodeString): UnicodeString; + +// Decodes string, encoded with EncodeString. +function DecodeString(s: UnicodeString): UnicodeString; + +{$IFNDEF SYN_COMPILER_5_UP} +procedure FreeAndNil(var Obj); +{$ENDIF} + +{$IFNDEF SYN_COMPILER_3_UP} +procedure Assert(Expr: Boolean); { stub for Delphi 2 } +{$ENDIF} + +{$IFNDEF SYN_COMPILER_3_UP} +function LastDelimiter(const Delimiters, S: UnicodeString): Integer; +{$ENDIF} + +{$IFNDEF SYN_COMPILER_4_UP} +type + TReplaceFlags = set of (rfReplaceAll, rfIgnoreCase); + +function StringReplace(const S, OldPattern, NewPattern: UnicodeString; + Flags: TReplaceFlags): UnicodeString; +{$ENDIF} + +type + THighlighterAttriProc = function (Highlighter: TSynCustomHighlighter; + Attri: TSynHighlighterAttributes; UniqueAttriName: string; + Params: array of Pointer): Boolean of object; + +// Enums all child highlighters and their attributes of a TSynMultiSyn through a +// callback function. +// This function also handles nested TSynMultiSyns including their MarkerAttri. +function EnumHighlighterAttris(Highlighter: TSynCustomHighlighter; + SkipDuplicates: Boolean; HighlighterAttriProc: THighlighterAttriProc; + Params: array of Pointer): Boolean; + +{$IFDEF SYN_HEREDOC} +// Calculates Frame Check Sequence (FCS) 16-bit Checksum (as defined in RFC 1171) +function CalcFCS(const ABuf; ABufSize: Cardinal): Word; +{$ENDIF} + +procedure SynDrawGradient(const ACanvas: TCanvas; const AStartColor, + AEndColor: TColor; ASteps: Integer; const ARect: TRect; + const AHorizontal: Boolean); overload; + +function DeleteTypePrefixAndSynSuffix(S: string): string; + +implementation + +uses + SysUtils, + uRESTDWPrivSynHighlighterMulti; + +{$IFNDEF SYN_COMPILER_4_UP} +function Max(x, y: Integer): Integer; +begin + if x > y then Result := x else Result := y; +end; + +function Min(x, y: Integer): Integer; +begin + if x < y then Result := x else Result := y; +end; +{$ENDIF} + +function MinMax(x, mi, ma: Integer): Integer; +begin + x := Min(x, ma); + Result := Max(x, mi); +end; + +procedure SwapInt(var l, r: Integer); +var + tmp: Integer; +begin + tmp := r; + r := l; + l := tmp; +end; + +function MaxPoint(const P1, P2: TPoint): TPoint; +begin + if (P2.y > P1.y) or ((P2.y = P1.y) and (P2.x > P1.x)) then + Result := P2 + else + Result := P1; +end; + +function MinPoint(const P1, P2: TPoint): TPoint; +begin + if (P2.y < P1.y) or ((P2.y = P1.y) and (P2.x < P1.x)) then + Result := P2 + else + Result := P1; +end; + +function GetIntArray(Count: Cardinal; InitialValue: Integer): PIntArray; +var + p: PInteger; +begin + Result := AllocMem(Count * SizeOf(Integer)); + if Assigned(Result) and (InitialValue <> 0) then + begin + p := PInteger(Result); + while (Count > 0) do + begin + p^ := InitialValue; + Inc(p); + Dec(Count); + end; + end; +end; + +procedure InternalFillRect(dc: HDC; const rcPaint: TRect); +begin + ExtTextOut(dc, 0, 0, ETO_OPAQUE, @rcPaint, nil, 0, nil); +end; + +// Please don't change this function; no stack frame and efficient register use. +function GetHasTabs(pLine: PWideChar; var CharsBefore: Integer): Boolean; +begin + CharsBefore := 0; + if Assigned(pLine) then + begin + while pLine^ <> #0 do + begin + if pLine^ = #9 then + Break; + Inc(CharsBefore); + Inc(pLine); + end; + Result := pLine^ = #9; + end + else + Result := False; +end; + + +function ConvertTabs1Ex(const Line: UnicodeString; TabWidth: Integer; + var HasTabs: Boolean): UnicodeString; +var + pDest: PWideChar; + nBeforeTab: Integer; +begin + Result := Line; // increment reference count only + if GetHasTabs(Pointer(Line), nBeforeTab) then + begin + HasTabs := True; + pDest := @Result[nBeforeTab + 1]; // this will make a copy of Line + // We have at least one tab in the string, and the tab width is 1. + // pDest points to the first tab char. We overwrite all tabs with spaces. + repeat + if (pDest^ = #9) then pDest^ := ' '; + Inc(pDest); + until (pDest^ = #0); + end + else + HasTabs := False; +end; + +function ConvertTabs1(const Line: UnicodeString; TabWidth: Integer): UnicodeString; +var + HasTabs: Boolean; +begin + Result := ConvertTabs1Ex(Line, TabWidth, HasTabs); +end; + +function ConvertTabs2nEx(const Line: UnicodeString; TabWidth: Integer; + var HasTabs: Boolean): UnicodeString; +var + i, DestLen, TabCount, TabMask: Integer; + pSrc, pDest: PWideChar; +begin + Result := Line; // increment reference count only + if GetHasTabs(Pointer(Line), DestLen) then + begin + HasTabs := True; + pSrc := @Line[1 + DestLen]; + // We have at least one tab in the string, and the tab width equals 2^n. + // pSrc points to the first tab char in Line. We get the number of tabs + // and the length of the expanded string now. + TabCount := 0; + TabMask := (TabWidth - 1) xor $7FFFFFFF; + repeat + if pSrc^ = #9 then + begin + DestLen := (DestLen + TabWidth) and TabMask; + Inc(TabCount); + end + else + Inc(DestLen); + Inc(pSrc); + until (pSrc^ = #0); + // Set the length of the expanded string. + SetLength(Result, DestLen); + DestLen := 0; + pSrc := PWideChar(Line); + pDest := PWideChar(Result); + // We use another TabMask here to get the difference to 2^n. + TabMask := TabWidth - 1; + repeat + if pSrc^ = #9 then + begin + i := TabWidth - (DestLen and TabMask); + Inc(DestLen, i); + //This is used for both drawing and other stuff and is meant to be #9 and not #32 + repeat + pDest^ := #9; + Inc(pDest); + Dec(i); + until (i = 0); + Dec(TabCount); + if TabCount = 0 then + begin + repeat + Inc(pSrc); + pDest^ := pSrc^; + Inc(pDest); + until (pSrc^ = #0); + Exit; + end; + end + else + begin + pDest^ := pSrc^; + Inc(pDest); + Inc(DestLen); + end; + Inc(pSrc); + until (pSrc^ = #0); + end + else + HasTabs := False; +end; + +function ConvertTabs2n(const Line: UnicodeString; TabWidth: Integer): UnicodeString; +var + HasTabs: Boolean; +begin + Result := ConvertTabs2nEx(Line, TabWidth, HasTabs); +end; + +function ConvertTabsEx(const Line: UnicodeString; TabWidth: Integer; + var HasTabs: Boolean): UnicodeString; +var + i, DestLen, TabCount: Integer; + pSrc, pDest: PWideChar; +begin + Result := Line; // increment reference count only + if GetHasTabs(Pointer(Line), DestLen) then + begin + HasTabs := True; + pSrc := @Line[1 + DestLen]; + // We have at least one tab in the string, and the tab width is greater + // than 1. pSrc points to the first tab char in Line. We get the number + // of tabs and the length of the expanded string now. + TabCount := 0; + repeat + if pSrc^ = #9 then + begin + DestLen := DestLen + TabWidth - DestLen mod TabWidth; + Inc(TabCount); + end + else + Inc(DestLen); + Inc(pSrc); + until (pSrc^ = #0); + // Set the length of the expanded string. + SetLength(Result, DestLen); + DestLen := 0; + pSrc := PWideChar(Line); + pDest := PWideChar(Result); + repeat + if pSrc^ = #9 then + begin + i := TabWidth - (DestLen mod TabWidth); + Inc(DestLen, i); + repeat + pDest^ := #9; + Inc(pDest); + Dec(i); + until (i = 0); + Dec(TabCount); + if TabCount = 0 then + begin + repeat + Inc(pSrc); + pDest^ := pSrc^; + Inc(pDest); + until (pSrc^ = #0); + Exit; + end; + end + else + begin + pDest^ := pSrc^; + Inc(pDest); + Inc(DestLen); + end; + Inc(pSrc); + until (pSrc^ = #0); + end + else + HasTabs := False; +end; + +function ConvertTabs(const Line: UnicodeString; TabWidth: Integer): UnicodeString; +var + HasTabs: Boolean; +begin + Result := ConvertTabsEx(Line, TabWidth, HasTabs); +end; + +function IsPowerOfTwo(TabWidth: Integer): Boolean; +var + nW: Integer; +begin + nW := 2; + repeat + if (nW >= TabWidth) then + Break; + Inc(nW, nW); + until (nW >= $10000); // we don't want 64 kByte spaces... + Result := (nW = TabWidth); +end; + +function GetBestConvertTabsProc(TabWidth: Integer): TConvertTabsProc; +begin + if (TabWidth < 2) then Result := TConvertTabsProc(@ConvertTabs1) + else if IsPowerOfTwo(TabWidth) then + Result := TConvertTabsProc(@ConvertTabs2n) + else + Result := TConvertTabsProc(@ConvertTabs); +end; + +function GetBestConvertTabsProcEx(TabWidth: Integer): TConvertTabsProcEx; +begin + if (TabWidth < 2) then Result := ConvertTabs1Ex + else if IsPowerOfTwo(TabWidth) then + Result := ConvertTabs2nEx + else + Result := ConvertTabsEx; +end; + +function GetExpandedLength(const aStr: UnicodeString; aTabWidth: Integer): Integer; +var + iRun: PWideChar; +begin + Result := 0; + iRun := PWideChar(aStr); + while iRun^ <> #0 do + begin + if iRun^ = #9 then + Inc(Result, aTabWidth - (Result mod aTabWidth)) + else + Inc(Result); + Inc(iRun); + end; +end; + +function CharIndex2CaretPos(Index, TabWidth: Integer; + const Line: UnicodeString): Integer; +var + iChar: Integer; + pNext: PWideChar; +begin +// possible sanity check here: Index := Max(Index, Length(Line)); + if Index > 1 then + begin + if (TabWidth <= 1) or not GetHasTabs(Pointer(Line), iChar) then + Result := Index + else + begin + if iChar + 1 >= Index then + Result := Index + else + begin + // iChar is number of chars before first #9 + Result := iChar; + // Index is *not* zero-based + Inc(iChar); + Dec(Index, iChar); + pNext := @Line[iChar]; + while Index > 0 do + begin + case pNext^ of + #0: + begin + Inc(Result, Index); + Break; + end; + #9: + begin + // Result is still zero-based + Inc(Result, TabWidth); + Dec(Result, Result mod TabWidth); + end; + else + Inc(Result); + end; + Dec(Index); + Inc(pNext); + end; + // done with zero-based computation + Inc(Result); + end; + end; + end + else + Result := 1; +end; + +function CaretPos2CharIndex(Position, TabWidth: Integer; const Line: UnicodeString; + var InsideTabChar: Boolean): Integer; +var + iPos: Integer; + pNext: PWideChar; +begin + InsideTabChar := False; + if Position > 1 then + begin + if (TabWidth <= 1) or not GetHasTabs(Pointer(Line), iPos) then + Result := Position + else + begin + if iPos + 1 >= Position then + Result := Position + else + begin + // iPos is number of chars before first #9 + Result := iPos + 1; + pNext := @Line[Result]; + // for easier computation go zero-based (mod-operation) + Dec(Position); + while iPos < Position do + begin + case pNext^ of + #0: + Break; + #9: + begin + Inc(iPos, TabWidth); + Dec(iPos, iPos mod TabWidth); + if iPos > Position then + begin + InsideTabChar := True; + Break; + end; + end; + else + Inc(iPos); + end; + Inc(Result); + Inc(pNext); + end; + end; + end; + end + else + Result := Position; +end; + +function StrScanForCharInCategory(const Line: UnicodeString; Start: Integer; + IsOfCategory: TCategoryMethod): Integer; +var + p: PWideChar; +begin + if (Start > 0) and (Start <= Length(Line)) then + begin + p := PWideChar(@Line[Start]); + repeat + if IsOfCategory(p^) then + begin + Result := Start; + Exit; + end; + Inc(p); + Inc(Start); + until p^ = #0; + end; + Result := 0; +end; + +function StrRScanForCharInCategory(const Line: UnicodeString; Start: Integer; + IsOfCategory: TCategoryMethod): Integer; +var + I: Integer; +begin + Result := 0; + if (Start > 0) and (Start <= Length(Line)) then + begin + for I := Start downto 1 do + if IsOfCategory(Line[I]) then + begin + Result := I; + Exit; + end; + end; +end; + +function GetEOL(Line: PWideChar): PWideChar; +begin + Result := Line; + if Assigned(Result) then + while (Result^ <> #0) and (Result^ <> #10) and (Result^ <> #13) do + Inc(Result); +end; + +{$IFOPT R+}{$DEFINE RestoreRangeChecking}{$ELSE}{$UNDEF RestoreRangeChecking}{$ENDIF} +{$R-} +function EncodeString(s: UnicodeString): UnicodeString; +var + i, j: Integer; +begin + SetLength(Result, 2 * Length(s)); // worst case + j := 0; + for i := 1 to Length(s) do + begin + Inc(j); + if s[i] = '\' then + begin + Result[j] := '\'; + Result[j + 1] := '\'; + Inc(j); + end + else if s[i] = '/' then + begin + Result[j] := '\'; + Result[j + 1] := '.'; + Inc(j); + end + else + Result[j] := s[i]; + end; //for + SetLength(Result, j); +end; { EncodeString } + +function DecodeString(s: UnicodeString): UnicodeString; +var + i, j: Integer; +begin + SetLength(Result, Length(s)); // worst case + j := 0; + i := 1; + while i <= Length(s) do + begin + Inc(j); + if s[i] = '\' then + begin + Inc(i); + if s[i] = '\' then + Result[j] := '\' + else + Result[j] := '/'; + end + else + Result[j] := s[i]; + Inc(i); + end; //for + SetLength(Result,j); +end; { DecodeString } +{$IFDEF RestoreRangeChecking}{$R+}{$ENDIF} + +{$IFNDEF SYN_COMPILER_5_UP} +procedure FreeAndNil(var Obj); +var + P: TObject; +begin + P := TObject(Obj); + TObject(Obj) := nil; + P.Free; +end; +{$ENDIF} + +{$IFNDEF SYN_COMPILER_3_UP} +procedure Assert(Expr: Boolean); { stub for Delphi 2 } +begin +end; +{$ENDIF} + +{$IFNDEF SYN_COMPILER_3_UP} +function LastDelimiter(const Delimiters, S: UnicodeString): Integer; +var + P: PWideChar; +begin + Result := Length(S); + P := PWideChar(Delimiters); + while Result > 0 do + begin + if (S[Result] <> #0) and (StrScan(P, S[Result]) <> nil) then + Exit; + Dec(Result); + end; +end; +{$ENDIF} + +{$IFNDEF SYN_COMPILER_4_UP} +function StringReplace(const S, OldPattern, NewPattern: UnicodeString; + Flags: TReplaceFlags): UnicodeString; +var + SearchStr, Patt, NewStr: UnicodeString; + Offset: Integer; +begin + if rfIgnoreCase in Flags then + begin + SearchStr := SynWideUpperCase(S); + Patt := SynWideUpperCase(OldPattern); + end + else + begin + SearchStr := S; + Patt := OldPattern; + end; + NewStr := S; + Result := ''; + while SearchStr <> '' do + begin + Offset := Pos(Patt, SearchStr); + if Offset = 0 then + begin + Result := Result + NewStr; + Break; + end; + Result := Result + Copy(NewStr, 1, Offset - 1) + NewPattern; + NewStr := Copy(NewStr, Offset + Length(OldPattern), MaxInt); + if not (rfReplaceAll in Flags) then + begin + Result := Result + NewStr; + Break; + end; + SearchStr := Copy(SearchStr, Offset + Length(Patt), MaxInt); + end; +end; +{$ENDIF} + +function DeleteTypePrefixAndSynSuffix(S: string): string; +begin + Result := S; + if CharInSet(Result[1], ['T', 't']) then //ClassName is never empty so no AV possible + if Pos('tsyn', LowerCase(Result)) = 1 then + Delete(Result, 1, 4) + else + Delete(Result, 1, 1); + + if Copy(LowerCase(Result), Length(Result) - 2, 3) = 'syn' then + SetLength(Result, Length(Result) - 3); +end; + +function GetHighlighterIndex(Highlighter: TSynCustomHighlighter; + HighlighterList: TList): Integer; +var + i: Integer; +begin + Result := 1; + for i := 0 to HighlighterList.Count - 1 do + if HighlighterList[i] = Highlighter then + Exit + else if Assigned(HighlighterList[i]) and (TObject(HighlighterList[i]).ClassType = Highlighter.ClassType) then + Inc(Result); +end; + +function InternalEnumHighlighterAttris(Highlighter: TSynCustomHighlighter; + SkipDuplicates: Boolean; HighlighterAttriProc: THighlighterAttriProc; + Params: array of Pointer; HighlighterList: TList): Boolean; +var + i: Integer; + UniqueAttriName: string; +begin + Result := True; + + if (HighlighterList.IndexOf(Highlighter) >= 0) then + begin + if SkipDuplicates then Exit; + end + else + HighlighterList.Add(Highlighter); + + if Highlighter is TSynMultiSyn then + with TSynMultiSyn(Highlighter) do + begin + Result := InternalEnumHighlighterAttris(DefaultHighlighter, SkipDuplicates, + HighlighterAttriProc, Params, HighlighterList); + if not Result then Exit; + + for i := 0 to Schemes.Count - 1 do + begin + UniqueAttriName := Highlighter.ExportName + + IntToStr(GetHighlighterIndex(Highlighter, HighlighterList)) + '.' + + Schemes[i].MarkerAttri.Name + IntToStr(i + 1); + + Result := HighlighterAttriProc(Highlighter, Schemes[i].MarkerAttri, + UniqueAttriName, Params); + if not Result then Exit; + + Result := InternalEnumHighlighterAttris(Schemes[i].Highlighter, + SkipDuplicates, HighlighterAttriProc, Params, HighlighterList); + if not Result then Exit + end + end + else if Assigned(Highlighter) then + for i := 0 to Highlighter.AttrCount - 1 do + begin + UniqueAttriName := Highlighter.ExportName + + IntToStr(GetHighlighterIndex(Highlighter, HighlighterList)) + '.' + + Highlighter.Attribute[i].Name; + + Result := HighlighterAttriProc(Highlighter, Highlighter.Attribute[i], + UniqueAttriName, Params); + if not Result then Exit + end +end; + +function EnumHighlighterAttris(Highlighter: TSynCustomHighlighter; + SkipDuplicates: Boolean; HighlighterAttriProc: THighlighterAttriProc; + Params: array of Pointer): Boolean; +var + HighlighterList: TList; +begin + if not Assigned(Highlighter) or not Assigned(HighlighterAttriProc) then + begin + Result := False; + Exit; + end; + + HighlighterList := TList.Create; + try + Result := InternalEnumHighlighterAttris(Highlighter, SkipDuplicates, + HighlighterAttriProc, Params, HighlighterList) + finally + HighlighterList.Free + end +end; + +{$IFDEF SYN_HEREDOC} +// Fast Frame Check Sequence (FCS) Implementation +// Translated from sample code given with RFC 1171 by Marko Njezic + +const + fcstab : array[Byte] of Word = ( + $0000, $1189, $2312, $329b, $4624, $57ad, $6536, $74bf, + $8c48, $9dc1, $af5a, $bed3, $ca6c, $dbe5, $e97e, $f8f7, + $1081, $0108, $3393, $221a, $56a5, $472c, $75b7, $643e, + $9cc9, $8d40, $bfdb, $ae52, $daed, $cb64, $f9ff, $e876, + $2102, $308b, $0210, $1399, $6726, $76af, $4434, $55bd, + $ad4a, $bcc3, $8e58, $9fd1, $eb6e, $fae7, $c87c, $d9f5, + $3183, $200a, $1291, $0318, $77a7, $662e, $54b5, $453c, + $bdcb, $ac42, $9ed9, $8f50, $fbef, $ea66, $d8fd, $c974, + $4204, $538d, $6116, $709f, $0420, $15a9, $2732, $36bb, + $ce4c, $dfc5, $ed5e, $fcd7, $8868, $99e1, $ab7a, $baf3, + $5285, $430c, $7197, $601e, $14a1, $0528, $37b3, $263a, + $decd, $cf44, $fddf, $ec56, $98e9, $8960, $bbfb, $aa72, + $6306, $728f, $4014, $519d, $2522, $34ab, $0630, $17b9, + $ef4e, $fec7, $cc5c, $ddd5, $a96a, $b8e3, $8a78, $9bf1, + $7387, $620e, $5095, $411c, $35a3, $242a, $16b1, $0738, + $ffcf, $ee46, $dcdd, $cd54, $b9eb, $a862, $9af9, $8b70, + $8408, $9581, $a71a, $b693, $c22c, $d3a5, $e13e, $f0b7, + $0840, $19c9, $2b52, $3adb, $4e64, $5fed, $6d76, $7cff, + $9489, $8500, $b79b, $a612, $d2ad, $c324, $f1bf, $e036, + $18c1, $0948, $3bd3, $2a5a, $5ee5, $4f6c, $7df7, $6c7e, + $a50a, $b483, $8618, $9791, $e32e, $f2a7, $c03c, $d1b5, + $2942, $38cb, $0a50, $1bd9, $6f66, $7eef, $4c74, $5dfd, + $b58b, $a402, $9699, $8710, $f3af, $e226, $d0bd, $c134, + $39c3, $284a, $1ad1, $0b58, $7fe7, $6e6e, $5cf5, $4d7c, + $c60c, $d785, $e51e, $f497, $8028, $91a1, $a33a, $b2b3, + $4a44, $5bcd, $6956, $78df, $0c60, $1de9, $2f72, $3efb, + $d68d, $c704, $f59f, $e416, $90a9, $8120, $b3bb, $a232, + $5ac5, $4b4c, $79d7, $685e, $1ce1, $0d68, $3ff3, $2e7a, + $e70e, $f687, $c41c, $d595, $a12a, $b0a3, $8238, $93b1, + $6b46, $7acf, $4854, $59dd, $2d62, $3ceb, $0e70, $1ff9, + $f78f, $e606, $d49d, $c514, $b1ab, $a022, $92b9, $8330, + $7bc7, $6a4e, $58d5, $495c, $3de3, $2c6a, $1ef1, $0f78 + ); + +function CalcFCS(const ABuf; ABufSize: Cardinal): Word; +var + CurFCS: Word; + P: ^Byte; +begin + CurFCS := $ffff; + P := @ABuf; + while ABufSize <> 0 do + begin + CurFCS := (CurFCS shr 8) xor fcstab[(CurFCS xor P^) and $ff]; + Dec(ABufSize); + Inc(P); + end; + Result := CurFCS; +end; +{$ENDIF} + +procedure SynDrawGradient(const ACanvas: TCanvas; const AStartColor, AEndColor: TColor; + ASteps: Integer; const ARect: TRect; const AHorizontal: Boolean); +var + StartColorR, StartColorG, StartColorB: Byte; + DiffColorR, DiffColorG, DiffColorB: Integer; + i, Size: Integer; + PaintRect: TRect; +begin + StartColorR := GetRValue(ColorToRGB(AStartColor)); + StartColorG := GetGValue(ColorToRGB(AStartColor)); + StartColorB := GetBValue(ColorToRGB(AStartColor)); + + DiffColorR := GetRValue(ColorToRGB(AEndColor)) - StartColorR; + DiffColorG := GetGValue(ColorToRGB(AEndColor)) - StartColorG; + DiffColorB := GetBValue(ColorToRGB(AEndColor)) - StartColorB; + + ASteps := MinMax(ASteps, 2, 256); + + if AHorizontal then + begin + Size := ARect.Right - ARect.Left; + PaintRect.Top := ARect.Top; + PaintRect.Bottom := ARect.Bottom; + + for i := 0 to ASteps - 1 do + begin + PaintRect.Left := ARect.Left + MulDiv(i, Size, ASteps); + PaintRect.Right := ARect.Left + MulDiv(i + 1, Size, ASteps); + + ACanvas.Brush.Color := RGB(StartColorR + MulDiv(i, DiffColorR, ASteps - 1), + StartColorG + MulDiv(i, DiffColorG, ASteps - 1), + StartColorB + MulDiv(i, DiffColorB, ASteps - 1)); + + ACanvas.FillRect(PaintRect); + end; + end + else + begin + Size := ARect.Bottom - ARect.Top; + PaintRect.Left := ARect.Left; + PaintRect.Right := ARect.Right; + + for i := 0 to ASteps - 1 do + begin + PaintRect.Top := ARect.Top + MulDiv(i, Size, ASteps); + PaintRect.Bottom := ARect.Top + MulDiv(i + 1, Size, ASteps); + + ACanvas.Brush.Color := RGB(StartColorR + MulDiv(i, DiffColorR, ASteps - 1), + StartColorG + MulDiv(i, DiffColorG, ASteps - 1), + StartColorB + MulDiv(i, DiffColorB, ASteps - 1)); + + ACanvas.FillRect(PaintRect); + end; + end; +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditStrConst.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditStrConst.pas new file mode 100644 index 000000000..5b486b7ec --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditStrConst.pas @@ -0,0 +1,577 @@ +{------------------------------------------------------------------------------- +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: uRESTDWPrivSynEditStrConst.pas, released 2000-04-07. +The Original Code is based on mwLocalStr.pas by Michael Hieke, part of the +mwEdit component suite. +All Rights Reserved. + +Contributors to the uRESTDWPrivSynEdit and mwEdit projects are listed in the +Contributors.txt file. + +Alternatively, the contents of this file may be used under the terms of the +GNU General Public License Version 2 or later (the "GPL"), in which case +the provisions of the GPL are applicable instead of those above. +If you wish to allow use of your version of this file only under the terms +of the GPL and not to allow others to use your version of this file +under the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the GPL. +If you do not delete the provisions above, a recipient may use your version +of this file under either the MPL or the GPL. + +$Id: uRESTDWPrivSynEditStrConst.pas,v 1.41.2.5 2009/01/06 16:26:01 maelh Exp $ + +You may retrieve the latest version of this file at the uRESTDWPrivSynEdit home page, +located at http://uRESTDWPrivSynEdit.SourceForge.net + +Known Issues: +-------------------------------------------------------------------------------} + +unit uRESTDWPrivSynEditStrConst; + +{$I uRESTDWPrivSynEdit.inc} + +interface + +// NOTE: this is design-time stuff, so no need to have it in stringtables +const + SYNS_ComponentsPage = 'uRESTDWPrivSynEdit'; + SYNS_HighlightersPage = 'uRESTDWPrivSynEdit Highlighters'; + +// NOTE: the following constants are used to store information to the registry, +// INI files or XML files. For maximum compatibility only the chars +// 'A'..'Z', 'a'..'z', '0'..'9', '_' and '-' are allowed! +// +// If you want translated/"pretty"/more detailed descriptions use the +// resourcestrings, i.e. the "friendly" versions below. + +// constant names for highlighter attributes +// +// +const + SYNS_AttrAreaAIdentifier = 'Area_A_Identifier'; + SYNS_AttrArrowHead = 'ArrowHead'; + SYNS_AttrAsm = 'Asm'; + SYNS_AttrAsmComment = 'AsmComment'; + SYNS_AttrAsmKey = 'AsmKey'; + SYNS_AttrAssembler = 'Assembler'; + SYNS_AttrAtRules = 'AtRules'; + SYNS_AttrAttribute = 'Attribute'; + SYNS_AttrAttributeName = 'AttributeName'; + SYNS_AttrAttributeValue = 'AttributeValue'; + SYNS_AttrBasicTypes = 'BasicTypes'; + SYNS_AttrBlock = 'Block'; + SYNS_AttrBoolean = 'Booleanvalue'; + SYNS_AttrBrackets = 'Brackets'; + SYNS_AttrCDATASection = 'CDATA-Section'; + SYNS_AttrCharacter = 'Character'; + SYNS_AttrClass = 'Class'; + SYNS_AttrColor = 'ColorValue'; + SYNS_AttrConstant = 'Constant'; + SYNS_AttrComment = 'Comment'; + SYNS_AttrCondition = 'Condition'; + SYNS_AttrConditionalComment = 'ConditionalComment'; + SYNS_AttrConsoleOutput = 'ConsoleOutput'; + SYNS_AttrDataType = 'DataType'; + SYNS_AttrDebugLines = 'DebuggingLines'; + SYNS_AttrDefaultPackage = 'DefaultPackages'; + SYNS_AttrDelimitedIdentifier = 'DelimitedIdentifier'; + SYNS_AttrDir = 'Direction'; + SYNS_AttrDirections = 'Directions'; + SYNS_AttrDirective = 'Directive'; + SYNS_AttrDOCTYPESection = 'DOCTYPE-Section'; + SYNS_AttrDocumentation = 'Documentation'; + SYNS_AttrElementName = 'ElementName'; + SYNS_AttrEmbedSQL = 'EmbeddedSQL'; + SYNS_AttrEmbedText = 'EmbeddedText'; + SYNS_AttrEntityReference = 'EntityReference'; + SYNS_AttrEscapeAmpersand = 'EscapeAmpersand'; + SYNS_AttrEvent = 'Event'; + SYNS_AttrException = 'Exception'; + SYNS_AttrFirstTri = 'FirstTri'; + SYNS_AttrFloat = 'Float'; + SYNS_AttrForm = 'Form'; + SYNS_AttrFourthTri = 'FourthTri'; + SYNS_AttrFunction = 'Function'; + SYNS_AttrHexadecimal = 'Hexadecimal'; + SYNS_AttrIcon = 'IconReference'; + SYNS_AttrIdentifier = 'Identifier'; + SYNS_AttrIllegalChar = 'IllegalChar'; + SYNS_AttrInclude = 'Include'; + SYNS_AttrIndicator = 'IndicatorArea'; + SYNS_AttrIndirect = 'Indirect'; + SYNS_AttrInstructions = 'Instructions'; + SYNS_AttrInvalidSymbol = 'InvalidSymbol'; + SYNS_AttrInterfaceQualifier = 'InterfaceQualifier'; + SYNS_AttrInternalFunction = 'InternalFunction'; + SYNS_AttrKey = 'Key'; + SYNS_AttrLabel = 'Label'; + SYNS_AttrLace = 'Lace'; + SYNS_AttrLine = 'Line'; + SYNS_AttrMacro = 'Macro'; + SYNS_AttrMarker = 'Marker'; + SYNS_AttrMathMode = 'MathMode'; + SYNS_AttrMessage = 'Message'; + SYNS_AttrMiscellaneous = 'Miscellaneous'; + SYNS_AttrNamespaceAttrName = 'NamespaceAttributeName'; + SYNS_AttrNamespaceAttrValue = 'NamespaceAttributeValue'; + SYNS_AttrNonReservedKeyword = 'NonreservedKeyword'; + SYNS_AttrNull = 'Null'; + SYNS_AttrNumber = 'Number'; + SYNS_AttrOctal = 'Octal'; + SYNS_AttrOperator = 'Operator'; + SYNS_AttrOperatorAndSymbols = 'OperatorAndSymbols'; + SYNS_AttrOpLine = 'OpLine'; + SYNS_AttrOptions = 'Options'; + SYNS_AttrPath = 'PathName'; + SYNS_AttrPLSQL = 'PLSQL-ReservedWord'; + SYNS_AttrPragma = 'Pragma'; + SYNS_AttrPredefined = 'Predefined'; + SYNS_AttrPreprocessor = 'Preprocessor'; + SYNS_AttrProcessingInstr = 'ProcessingInstruction'; + SYNS_AttrProcName = 'ProcName'; + SYNS_AttrProperty = 'Property'; + SYNS_AttrQuad = 'Quad'; + SYNS_AttrQualifier = 'Qualifier'; + SYNS_AttrRegister = 'Register'; + SYNS_AttrReservedWord = 'ReservedWord'; + SYNS_AttrResultValue = 'ResultValue'; + SYNS_AttrRoundBracket = 'RoundBracket'; + SYNS_AttrRpl = 'Rpl'; + SYNS_AttrRplKey = 'Rpl-Key'; + SYNS_AttrRplComment = 'Rpl-Comment'; + SYNS_AttrSASM = 'SASM'; + SYNS_AttrSASMComment = 'SASM-Comment'; + SYNS_AttrSASMKey = 'SASM-Key'; + SYNS_AttrSecondReservedWord = 'SecondReservedWord'; + SYNS_AttrSecondTri = 'SecondTri'; + SYNS_AttrSection = 'Section'; + SYNS_AttrSequence = 'SequenceNumberArea'; + SYNS_AttrShape = 'Shape'; + SYNS_AttrSingleString = 'SingleQuotedString'; + SYNS_AttrSpace = 'Space'; + SYNS_AttrSpecialVariable = 'SpecialVariable'; + SYNS_AttrSQLKey = 'SQL-Keyword'; + SYNS_AttrSQLPlus = 'SQLPlus-Command'; + SYNS_AttrSquareBracket = 'SquareBracket'; + SYNS_AttrString = 'String'; + SYNS_AttrSymbol = 'Symbol'; + SYNS_AttrSyntaxError = 'SyntaxError'; + SYNS_AttrSystem = 'SystemFunctionsAndVariables'; + SYNS_AttrSystemValue = 'SystemValue'; + SYNS_AttrTagArea = 'TagArea'; + SYNS_AttrTableName = 'TableName'; + SYNS_AttrTerminator = 'Terminator'; + SYNS_AttrTeXCommand = 'TeX-Command'; + SYNS_AttrText = 'Text'; + SYNS_AttrTextMathMode = 'TextInMathMode'; + SYNS_AttrThirdTri = 'ThirdTri'; + SYNS_AttrTixKeyWords = 'Tix-Keywords'; + SYNS_AttrTriangle = 'Triangle'; + SYNS_AttrUndefinedProperty = 'UndefinedProperty'; + SYNS_AttrUnknownWord = 'UnknownWord'; + SYNS_AttrURI = 'URI'; + SYNS_AttrUser = 'UserFunctionsAndVariables'; + SYNS_AttrUserFunction = 'UserFunctions'; + SYNS_AttrValue = 'Value'; + SYNS_AttrVariable = 'Variable'; + SYNS_AttrVisitedURI = 'VisitedURI'; + SYNS_AttrVrmlAppearance = 'Vrml_Appearance'; + SYNS_AttrVrmlAttribute = 'Vrml_Attribute'; + SYNS_AttrVrmlDefinition = 'Vrml_Definition'; + SYNS_AttrVrmlEvent = 'Vrml_Event'; + SYNS_AttrVrmlGrouping = 'Vrml_Grouping'; + SYNS_AttrVrmlInterpolator = 'Vrml_Interpolator'; + SYNS_AttrVrmlLight = 'Vrml_Light'; + SYNS_AttrVrmlNode = 'Vrml_Node'; + SYNS_AttrVrmlParameter = 'Vrml_Parameter'; + SYNS_AttrVrmlProto = 'Vrml_Proto'; + SYNS_AttrVrmlSensor = 'Vrml_Sensor'; + SYNS_AttrVrmlShape = 'Vrml_Shape'; + SYNS_AttrVrmlShape_Hint = 'Vrml_Shape_Hint'; + SYNS_AttrVrmlTime_dependent = 'Vrml_Time_dependent'; + SYNS_AttrVrmlViewpoint = 'Vrml_Viewpoint'; + SYNS_AttrVrmlWorldInfo = 'Vrml_WorldInfo'; + SYNS_AttrWhitespace = 'Whitespace'; + SYNS_AttrWidgetWords = 'Widget-Keywords'; + SYNS_AttrX3DDocType = 'X3DDocType'; + SYNS_AttrX3DHeader = 'X3DHeader'; + + // constant language names + SYNS_Lang68HC11 = '68HC11_Assembler'; + SYNS_LangADSP21xx = 'ADSP21xx'; + SYNS_LangAWK = 'AWK'; + SYNS_LangBaan = 'Baan_4GL'; + SYNS_LangBatch = 'MS-DOS_Batch'; + SYNS_LangCache = 'CacheObjectScript'; + SYNS_LangCAClipper = 'CA-Clipper'; + SYNS_LangCOBOL = 'COBOL'; + SYNS_LangCORBAIDL = 'CORBA_IDL'; + SYNS_LangCPM = 'COAS_Product_Manager_Report'; + SYNS_LangCPP = 'CandCPlusPlus'; + SYNS_LangCS = 'CSharp'; + SYNS_LangCSS = 'CascadingStyleSheet'; + SYNS_LangDfm = 'BorlandForms'; + SYNS_LangDOT = 'DOT_Graph_Drawing_Description_language'; + SYNS_LangECMAScript = 'ECMAScript'; + SYNS_LangEiffel = 'Eiffel'; + SYNS_LangFortran = 'Fortran'; + SYNS_LangFoxpro = 'Foxpro'; + SYNS_LangGalaxy = 'Galaxy'; + SYNS_LangGembase = 'Gembase'; + SYNS_LangGeneral = 'General'; + SYNS_LangGeneralMulti = 'General_Multi-Highlighter'; + SYNS_LangGLSL = 'OpenGL Shader Language'; + SYNS_LangGo = 'Go'; + SYNS_LangGWS = 'GW-TEL'; + SYNS_LangHaskell = 'Haskell'; + SYNS_LangHP48 = 'HP48'; + SYNS_LangHTML = 'HTML'; + SYNS_LangINI = 'INI'; + SYNS_LangInno = 'InnoSetupScript'; + SYNS_LangJava = 'Java'; + SYNS_LangJScript = 'JavaScript'; + SYNS_LangJSON = 'JSON'; + SYNS_LangKIX = 'KiXtart'; + SYNS_LangLDraw = 'LEGO_LDraw'; + SYNS_LangLLVMIR = 'LLVM IR'; + SYNS_LangMASM = 'x86Assembly MASM'; + SYNS_LangModelica = 'Modelica'; + SYNS_LangModula3 = 'Modula3'; + SYNS_LangNameUNIXShellScript = 'UNIXShellScript'; + SYNS_LangPascal = 'ObjectPascal'; + SYNS_LangPerl = 'Perl'; + SYNS_LangPHP = 'PHP'; + SYNS_LangProgress = 'Progress'; + SYNS_LangPython = 'Python'; + SYNS_LangRC = 'Resource'; + SYNS_LangRuby = 'Ruby'; + SYNS_LangSDD = 'SemantaDataDictionary'; + SYNS_LangSML = 'StandardML'; + SYNS_LangSQL = 'SQL'; + SYNS_LangST = 'StructuredText'; + SYNS_LangSybaseSQL = 'SybaseSQL'; + SYNS_LangSynGenMsgfiles = 'SynGen_Msg'; + SYNS_LangTclTk = 'TclTk'; + SYNS_LangTeX = 'TeX'; + SYNS_LangUnknown = ''; + SYNS_LangUnreal = 'Unreal'; + SYNS_LangURI = 'URI'; + SYNS_LangVBSScript = 'MS-VBScript'; + SYNS_LangVisualBASIC = 'VisualBasic'; + SYNS_LangVrml97 = 'Vrml97'; + SYNS_LangX86Asm = 'x86Assembly'; + SYNS_LangXML = 'XML'; + +resourcestring + SYNS_NoSearchEngineError = 'No search engine has been assigned'; + + SYNS_Untitled = 'Untitled'; + + // Friendly names for highlighter attributes + SYNS_FriendlyAttrAreaAIdentifier = 'Area A Identifier'; + SYNS_FriendlyAttrArrowHead = 'ArrowHead'; + SYNS_FriendlyAttrAsm = 'Asm'; + SYNS_FriendlyAttrAsmComment = 'Asm Comment'; + SYNS_FriendlyAttrAsmKey = 'Asm Key'; + SYNS_FriendlyAttrAssembler = 'Assembler'; + SYNS_FriendlyAttrAtRules = '@-Rules'; + SYNS_FriendlyAttrAttribute = 'Attribute'; + SYNS_FriendlyAttrAttributeName = 'Attribute Name'; + SYNS_FriendlyAttrAttributeValue = 'Attribute Value'; + SYNS_FriendlyAttrBasicTypes = 'Basic Types'; + SYNS_FriendlyAttrBlock = 'Block'; + SYNS_FriendlyAttrBoolean = 'Boolean value'; + SYNS_FriendlyAttrBrackets = 'Brackets'; + SYNS_FriendlyAttrCDATASection = 'CDATA Section'; + SYNS_FriendlyAttrCharacter = 'Character'; + SYNS_FriendlyAttrClass = 'Class'; + SYNS_FriendlyAttrColor = 'Color Value'; + SYNS_FriendlyAttrComment = 'Comment'; + SYNS_FriendlyAttrCondition = 'Condition'; + SYNS_FriendlyAttrConditionalComment = 'Conditional Comment'; + SYNS_FriendlyAttrConsoleOutput = 'Console output'; + SYNS_FriendlyAttrConstant = 'Constant'; + SYNS_FriendlyAttrDataType = 'Data Type'; + SYNS_FriendlyAttrDebugLines = 'Debugging Lines'; + SYNS_FriendlyAttrDefaultPackage = 'Default Packages'; + SYNS_FriendlyAttrDelimitedIdentifier = 'Delimited Identifier'; + SYNS_FriendlyAttrDir = 'Direction'; + SYNS_FriendlyAttrDirections = 'Directions'; + SYNS_FriendlyAttrDirective = 'Directive'; + SYNS_FriendlyAttrDOCTYPESection = 'DOCTYPE Section'; + SYNS_FriendlyAttrDocumentation = 'Documentation'; + SYNS_FriendlyAttrElementName = 'Element Name'; + SYNS_FriendlyAttrEmbedSQL = 'Embedded SQL'; + SYNS_FriendlyAttrEmbedText = 'Embedded Text'; + SYNS_FriendlyAttrEntityReference = 'Entity Reference'; + SYNS_FriendlyAttrEscapeAmpersand = 'Escape Ampersand'; + SYNS_FriendlyAttrEvent = 'Event'; + SYNS_FriendlyAttrException = 'Exception'; + SYNS_FriendlyAttrFirstTri = 'FirstTri'; + SYNS_FriendlyAttrFloat = 'Float'; + SYNS_FriendlyAttrForm = 'Form'; + SYNS_FriendlyAttrFourthTri = 'FourthTri'; + SYNS_FriendlyAttrFunction = 'Function'; + SYNS_FriendlyAttrHexadecimal = 'Hexadecimal'; + SYNS_FriendlyAttrIcon = 'Icon Reference'; + SYNS_FriendlyAttrIdentifier = 'Identifier'; + SYNS_FriendlyAttrIllegalChar = 'Illegal Char'; + SYNS_FriendlyAttrInclude = 'Include'; + SYNS_FriendlyAttrIndicator = 'Indicator Area'; + SYNS_FriendlyAttrIndirect = 'Indirect'; + SYNS_FriendlyAttrInstructions = 'Instructions'; + SYNS_FriendlyAttrInterfaceQualifier = 'Interface Qualifier'; + SYNS_FriendlyAttrInternalFunction = 'Internal Function'; + SYNS_FriendlyAttrInvalidSymbol = 'Invalid Symbol'; + SYNS_FriendlyAttrKey = 'Key'; + SYNS_FriendlyAttrLabel = 'Label'; + SYNS_FriendlyAttrLace = 'Lace'; + SYNS_FriendlyAttrLine = 'Line'; + SYNS_FriendlyAttrMacro = 'Macro'; + SYNS_FriendlyAttrMarker = 'Marker'; + SYNS_FriendlyAttrMathMode = 'Math Mode'; + SYNS_FriendlyAttrMessage = 'Message'; + SYNS_FriendlyAttrMiscellaneous = 'Miscellaneous'; + SYNS_FriendlyAttrNamespaceAttrName = 'Namespace Attribute Name'; + SYNS_FriendlyAttrNamespaceAttrValue = 'Namespace Attribute Value'; + SYNS_FriendlyAttrNonReservedKeyword = 'Non-reserved Keyword'; + SYNS_FriendlyAttrNull = 'Null'; + SYNS_FriendlyAttrNumber = 'Number'; + SYNS_FriendlyAttrOctal = 'Octal'; + SYNS_FriendlyAttrOperator = 'Operator'; + SYNS_FriendlyAttrOperatorAndSymbols = 'Operator And Symbols'; + SYNS_FriendlyAttrOpLine = 'OpLine'; + SYNS_FriendlyAttrOptions = 'Options'; + SYNS_FriendlyAttrPath = 'Pathname'; + SYNS_FriendlyAttrPLSQL = 'PL/SQL Reserved Word'; + SYNS_FriendlyAttrPragma = 'Pragma'; + SYNS_FriendlyAttrPredefined = 'Predefined'; + SYNS_FriendlyAttrPreprocessor = 'Preprocessor'; + SYNS_FriendlyAttrProcessingInstr = 'Processing Instruction'; + SYNS_FriendlyAttrProcName = 'Procedure name'; + SYNS_FriendlyAttrProperty = 'Property'; + SYNS_FriendlyAttrQuad = 'Quad'; + SYNS_FriendlyAttrQualifier = 'Qualifier'; + SYNS_FriendlyAttrRegister = 'Register'; + SYNS_FriendlyAttrReservedWord = 'Reserved Word'; + SYNS_FriendlyAttrResultValue = 'Result Value'; + SYNS_FriendlyAttrRoundBracket = 'Round Bracket'; + SYNS_FriendlyAttrRpl = 'Rpl'; + SYNS_FriendlyAttrRplKey = 'Rpl Key'; + SYNS_FriendlyAttrRplComment = 'Rpl Comment'; + SYNS_FriendlyAttrSASM = 'SASM'; + SYNS_FriendlyAttrSASMComment = 'SASM Comment'; + SYNS_FriendlyAttrSASMKey = 'SASM Key'; + SYNS_FriendlyAttrSecondReservedWord = 'Second Reserved Word'; + SYNS_FriendlyAttrSecondTri = 'SecondTri'; + SYNS_FriendlyAttrSection = 'Section'; + SYNS_FriendlyAttrSequence = 'Sequence Number Area'; + SYNS_FriendlyAttrShape = 'Shape'; + SYNS_FriendlyAttrSingleString = 'Single Quoted String'; + SYNS_FriendlyAttrSpace = 'Space'; + SYNS_FriendlyAttrSpecialVariable = 'Special Variable'; + SYNS_FriendlyAttrSQLKey = 'SQL Keyword'; + SYNS_FriendlyAttrSQLPlus = 'SQL*Plus Command'; + SYNS_FriendlyAttrSquareBracket = 'Square Bracket'; + SYNS_FriendlyAttrString = 'String'; + SYNS_FriendlyAttrSymbol = 'Symbol'; + SYNS_FriendlyAttrSyntaxError = 'Syntax Error'; + SYNS_FriendlyAttrSystem = 'System Functions and Variables'; + SYNS_FriendlyAttrSystemValue = 'System Value'; + SYNS_FriendlyAttrTagArea = 'Tag Area'; + SYNS_FriendlyAttrTableName = 'Table Name'; + SYNS_FriendlyAttrTerminator = 'Terminator'; + SYNS_FriendlyAttrTeXCommand = 'TeX Command'; + SYNS_FriendlyAttrText = 'Text'; + SYNS_FriendlyAttrTextMathMode = 'Text in Math Mode'; + SYNS_FriendlyAttrThirdTri = 'ThirdTri'; + SYNS_FriendlyAttrTixKeyWords = 'Tix Keywords'; + SYNS_FriendlyAttrTriangle = 'Triangle'; + SYNS_FriendlyAttrUndefinedProperty = 'Undefined Property'; + SYNS_FriendlyAttrUnknownWord = 'Unknown Word'; + SYNS_FriendlyAttrURI = 'URI'; + SYNS_FriendlyAttrUser = 'User Functions and Variables'; + SYNS_FriendlyAttrUserFunction = 'User Functions'; + SYNS_FriendlyAttrValue = 'Value'; + SYNS_FriendlyAttrVariable = 'Variable'; + SYNS_FriendlyAttrVisitedURI = 'Visited URI'; + SYNS_FriendlyAttrVrmlAppearance = 'Vrml_Appearance'; + SYNS_FriendlyAttrVrmlAttribute = 'Vrml_Attribute'; + SYNS_FriendlyAttrVrmlDefinition = 'Vrml_Definition'; + SYNS_FriendlyAttrVrmlEvent = 'Vrml_Event'; + SYNS_FriendlyAttrVrmlGrouping = 'Vrml_Grouping'; + SYNS_FriendlyAttrVrmlInterpolator = 'Vrml_Interpolator'; + SYNS_FriendlyAttrVrmlLight = 'Vrml_Light'; + SYNS_FriendlyAttrVrmlNode = 'Vrml_Node'; + SYNS_FriendlyAttrVrmlParameter = 'Vrml_Parameter'; + SYNS_FriendlyAttrVrmlProto = 'Vrml_Proto'; + SYNS_FriendlyAttrVrmlSensor = 'Vrml_Sensor'; + SYNS_FriendlyAttrVrmlShape = 'Vrml_Shape'; + SYNS_FriendlyAttrVrmlShape_Hint = 'Vrml_Shape_Hint'; + SYNS_FriendlyAttrVrmlTime_dependent = 'Vrml_Time_dependent'; + SYNS_FriendlyAttrVrmlViewpoint = 'Vrml_Viewpoint'; + SYNS_FriendlyAttrVrmlWorldInfo = 'Vrml_WorldInfo'; + SYNS_FriendlyAttrWhitespace = 'Whitespace'; + SYNS_FriendlyAttrWidgetWords = 'Widget Keywords'; + SYNS_FriendlyAttrX3DDocType = 'X3DDocType'; + SYNS_FriendlyAttrX3DHeader = 'X3DHeader'; + + // names of exporter output formats + SYNS_ExporterFormatHTML = 'HTML'; + SYNS_ExporterFormatRTF = 'RTF'; + SYNS_ExporterFormatTeX = 'TeX'; + + // TCustomSynEdit scroll hint window caption + SYNS_ScrollInfoFmt = '%d - %d'; + SYNS_ScrollInfoFmtTop = 'Top Line: %d'; + // TSynEditPrintPreview page number + SYNS_PreviewScrollInfoFmt = 'Page: %d'; + + // strings for property editors etc + SYNS_EDuplicateShortcut = 'Shortcut already exists'; + SYNS_ShortcutNone = ''; + SYNS_DuplicateShortcutMsg = 'The keystroke "%s" is already assigned ' + + 'to another editor command. (%s)'; + SYNS_DuplicateShortcutMsg2 = 'The keystroke "%s" is already assigned ' + + 'to another editor command.'#13#10'The ' + + 'shortcut for this item has not been changed.'; + + // Filters used for open/save dialog + SYNS_FilterADSP21xx = 'DSP Files (*.dsp;*.inc)|*.dsp;*.inc'; + SYNS_FilterAsm68HC11 = '68HC11 Assembler Files (*.hc11;*.asm;*.asc)|*.hc11;*.asm;*.asc'; + SYNS_FilterAWK = 'AWK Scripts (*.awk)|*.awk'; + SYNS_FilterBaan = 'Baan 4GL Files (*.cln)|*.cln'; + SYNS_FilterBatch = 'MS-DOS Batch Files (*.bat;*.cmd)|*.bat;*.cmd'; + SYNS_FilterCache = 'Cache Files (*.mac;*.inc;*.int)|*.mac;*.inc;*.int'; + SYNS_FilterCAClipper = 'CA-Clipper Files (*.prg;*.ch;*.inc)|*.prg;*.ch;*.inc'; + SYNS_FilterCOBOL = 'COBOL Files (*.cbl;*.cob)|*.cbl;*.cob'; + SYNS_FilterCORBAIDL = 'CORBA IDL Files (*.idl)|*.idl'; + SYNS_FilterCPM = 'CPM Reports (*.rdf;*.rif;*.rmf;*.rxf)|*.rdf;*.rif;*.rmf;*.rxf'; + SYNS_FilterCPP = 'C/C++ Files (*.c;*.cpp;*.cc;*.h;*.hpp;*.hh;*.cxx;*.hxx;*.cu)|*.c;*.cpp;*.cc;*.h;*.hpp;*.hh;*.cxx;*.hxx;*.cu'; + SYNS_FilterCS = 'C# Files (*.cs)|*.cs'; + SYNS_FilterCSS = 'Cascading Stylesheets (*.css)|*.css'; + SYNS_FilterDFM = 'Borland Form Files (*.dfm;*.xfm)|*.dfm;*.xfm'; + SYNS_FilterDOT = 'DOT Graph Drawing Description (*.dot)|*.dot'; + SYNS_FilterDWS = 'DWScript Files (*.dws;*.pas;*.inc)|*.dws;*.pas;*.inc'; + SYNS_FilterEcmaScript = 'Javascript Files (*.js)|*.js'; + SYNS_FilterEiffel = 'Eiffel (*.e;*.ace)|*.e;*.ace'; + SYNS_FilterFortran = 'Fortran Files (*.for)|*.for'; + SYNS_FilterFoxpro = 'Foxpro Files (*.prg)|*.prg'; + SYNS_FilterGalaxy = 'Galaxy Files (*.gtv;*.galrep;*.txt)|*.gtv;*.galrep;*.txt'; + SYNS_FilterGembase = 'GEMBASE Files (*.dml;*.gem)|*.dml;*.gem'; + SYNS_FilterGo = 'Go files (*.go)|*.go'; + SYNS_FilterGLSL = 'GLSL files (*.glsl)|*.glsl'; + SYNS_FilterGWS = 'GW-TEL Scripts (*.gws)|*.gws'; + SYNS_FilterHaskell = 'Haskell Files (*.hs;*.lhs)|*.hs;*.lhs'; + SYNS_FilterHP48 = 'HP48 Files (*.s;*.sou;*.a;*.hp)|*.s;*.sou;*.a;*.hp'; + SYNS_FilterHTML = 'HTML Documents (*.htm;*.html)|*.htm;*.html'; + SYNS_FilterINI = 'INI Files (*.ini)|*.ini'; + SYNS_FilterInno = 'Inno Setup Scripts (*.iss)|*.iss'; + SYNS_FilterJava = 'Java Files (*.java)|*.java'; + SYNS_FilterJScript = 'Javascript Files (*.js)|*.js'; + SYNS_FilterJSON = 'JSON Files (*.json)|*.json'; + SYNS_FilterKIX = 'KiXtart Scripts (*.kix)|*.kix'; + SYNS_FilterLDraw = 'LEGO LDraw Files (*.ldr)|*.ldr'; + SYNS_FilterLLVMIR = 'LLVM IR files (*.ll)|*.ll'; + SYNS_FilterModelica = 'Modelica Files (*.mo)|*.mo'; + SYNS_FilterModula3 = 'Modula-3 Files (*.m3)|*.m3'; + SYNS_FilterPascal = 'Pascal Files (*.pas;*.pp;*.dpr;*.dpk;*.inc)|*.pas;*.pp;*.dpr;*.dpk;*.inc'; + SYNS_FilterPerl = 'Perl Files (*.pl;*.pm;*.cgi)|*.pl;*.pm;*.cgi'; + SYNS_FilterPHP = 'PHP Files (*.php;*.php3;*.phtml;*.inc)|*.php;*.php3;*.phtml;*.inc'; + SYNS_FilterProgress = 'Progress Files (*.w;*.p;*.i)|*.w;*.p;*.i'; + SYNS_FilterPython = 'Python Files (*.py)|*.py'; + SYNS_FilterRC = 'Resource Files (*.rc)|*.rc'; + SYNS_FilterRTF = 'Rich Text Format Documents (*.rtf)|*.rtf'; + SYNS_FilterRuby = 'Ruby Files (*.rb;*.rbw)|*.rb;*.rbw'; + SYNS_FilterSDD = 'Semanta DD Files (*.sdd)|*.sdd'; + SYNS_FilterSML = 'Standard ML Files (*.sml)|*.sml'; + SYNS_FilterSQL = 'SQL Files (*.sql)|*.sql'; + SYNS_FilterST = 'Structured Text Files (*.st)|*.st'; + SYNS_FilterSynGenMsgfiles = 'Msg Files (*.msg)|*.msg'; + SYNS_FilterTclTk = 'Tcl/Tk Files (*.tcl)|*.tcl'; + SYNS_FilterTeX = 'TeX Files (*.tex)|*.tex'; + SYNS_FilterUNIXShellScript = 'UNIX Shell Scripts (*.sh)|*.sh'; + SYNS_FilterURI = 'All Files (*.*)|*.*'; + SYNS_FilterVBScript = 'VBScript Files (*.vbs)|*.vbs'; + SYNS_FilterVisualBASIC = 'Visual Basic Files (*.bas)|*.bas'; + SYNS_FilterVrml97 = 'Vrml97/X3D World (*.wrl;*.wrml;*.vrl;*.vrml;*.x3d)|*.wrl;*.wrml;*.vrl;*.vrml;*.x3d'; + SYNS_FilterX86Assembly = 'x86 Assembly Files (*.asm)|*.asm'; + SYNS_FilterXML = 'XML Files (*.xml;*.xsd;*.xsl;*.xslt;*.dtd)|*.xml;*.xsd;*.xsl;*.xslt;*.dtd'; + + // friendly language names + SYNS_FriendlyLang68HC11 = '68HC11 Assembler'; + SYNS_FriendlyLangADSP21xx = 'ADSP21xx'; + SYNS_FriendlyLangAWK = 'AWK'; + SYNS_FriendlyLangBaan = 'Baan 4GL'; + SYNS_FriendlyLangBatch = 'MS-DOS Batch'; + SYNS_FriendlyLangCache = 'Cache Object Script'; + SYNS_FriendlyLangCAClipper = 'CA-Clipper'; + SYNS_FriendlyLangCOBOL = 'COBOL'; + SYNS_FriendlyLangCORBAIDL = 'CORBA IDL'; + SYNS_FriendlyLangCPM = 'COAS Product Manager Report'; + SYNS_FriendlyLangCPP = 'C/C++'; + SYNS_FriendlyLangCS = 'C#'; + SYNS_FriendlyLangCSS = 'Cascading Style Sheet'; + SYNS_FriendlyLangDfm = 'Borland Forms'; + SYNS_FriendlyLangDOT = 'DOT Graph Drawing Description language'; + SYNS_FriendlyLangEcmaScript = 'ECMA Script'; + SYNS_FriendlyLangEiffel = 'Eiffel'; + SYNS_FriendlyLangFortran = 'Fortran'; + SYNS_FriendlyLangFoxpro = 'Foxpro'; + SYNS_FriendlyLangGalaxy = 'Galaxy'; + SYNS_FriendlyLangGembase = 'Gembase'; + SYNS_FriendlyLangGeneral = 'General'; + SYNS_FriendlyLangGeneralMulti = 'General Multi-Highlighter'; + SYNS_FriendlyLangGo = 'Go'; + SYNS_FriendlyLangGLSL = 'GLSL'; + SYNS_FriendlyLangGWS = 'GW-TEL'; + SYNS_FriendlyLangHaskell = 'Haskell'; + SYNS_FriendlyLangHP48 = 'HP48'; + SYNS_FriendlyLangHTML = 'HTML'; + SYNS_FriendlyLangINI = 'INI'; + SYNS_FriendlyLangInno = 'Inno Setup Script'; + SYNS_FriendlyLangJava = 'Java'; + SYNS_FriendlyLangJavaScript = 'JavaScript'; + SYNS_FriendlyLangJScript = 'JavaScript'; + SYNS_FriendlyLangJSON = 'JSON'; + SYNS_FriendlyLangKIX = 'KiXtart'; + SYNS_FriendlyLangLDraw = 'LEGO LDraw'; + SYNS_FriendlyLangLLVMIR = 'LLVM Intermediate Representation'; + SYNS_FriendlyLangMASM = 'x86 Assembly MASM'; + SYNS_FriendlyLangModelica = 'Modelica'; + SYNS_FriendlyLangModula3 = 'Modula 3'; + SYNS_FriendlyLangNameUNIXShellScript = 'UNIX Shell Script'; + SYNS_FriendlyLangPascal = 'Object Pascal'; + SYNS_FriendlyLangPerl = 'Perl'; + SYNS_FriendlyLangPHP = 'PHP'; + SYNS_FriendlyLangProgress = 'Progress'; + SYNS_FriendlyLangPython = 'Python'; + SYNS_FriendlyLangRC = 'Resource'; + SYNS_FriendlyLangRuby = 'Ruby'; + SYNS_FriendlyLangSDD = 'Semanta Data Dictionary'; + SYNS_FriendlyLangSML = 'Standard ML'; + SYNS_FriendlyLangSQL = 'SQL'; + SYNS_FriendlyLangST = 'Structured Text'; + SYNS_FriendlyLangSybaseSQL = 'Sybase SQL'; + SYNS_FriendlyLangSynGenMsgfiles = 'SynGen Msg'; + SYNS_FriendlyLangTclTk = 'Tcl/Tk'; + SYNS_FriendlyLangTeX = 'TeX'; + SYNS_FriendlyLangUnknown = ''; + SYNS_FriendlyLangUnreal = 'Unreal'; + SYNS_FriendlyLangURI = 'URI'; + SYNS_FriendlyLangVBSScript = 'MS VBScript'; + SYNS_FriendlyLangVisualBASIC = 'Visual Basic'; + SYNS_FriendlyLangVrml97 = 'Vrml97'; + SYNS_FriendlyLangX86Asm = 'x86 Assembly'; + SYNS_FriendlyLangXML = 'XML'; + +implementation + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditTextBuffer.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditTextBuffer.pas new file mode 100644 index 000000000..4e2d60de6 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditTextBuffer.pas @@ -0,0 +1,1397 @@ +{------------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: uRESTDWPrivSynEditTextBuffer.pas, released 2000-04-07. +The Original Code is based on parts of mwCustomEdit.pas by Martin Waldenburg, +part of the mwEdit component suite. +Portions created by Martin Waldenburg are Copyright (C) 1998 Martin Waldenburg. +Unicode translation by Mal Hrz. +All Rights Reserved. + +Contributors to the uRESTDWPrivSynEdit and mwEdit projects are listed in the +Contributors.txt file. + +Alternatively, the contents of this file may be used under the terms of the +GNU General Public License Version 2 or later (the "GPL"), in which case +the provisions of the GPL are applicable instead of those above. +If you wish to allow use of your version of this file only under the terms +of the GPL and not to allow others to use your version of this file +under the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the GPL. +If you do not delete the provisions above, a recipient may use your version +of this file under either the MPL or the GPL. + +$Id: uRESTDWPrivSynEditTextBuffer.pas,v 1.14 2011/12/28 09:24:20 Egg Exp $ + +You may retrieve the latest version of this file at the uRESTDWPrivSynEdit home page, +located at http://uRESTDWPrivSynEdit.SourceForge.net + +Known Issues: +-------------------------------------------------------------------------------} +//todo: Avoid calculating expanded string unncessarily (just calculate expandedLength instead). + +{$IFNDEF QSYNEDITTEXTBUFFER} +unit uRESTDWPrivSynEditTextBuffer; +{$ENDIF} + +{$I uRESTDWPrivSynEdit.inc} + +interface + +uses + Windows, + uRESTDWPrivSynEditTypes, + uRESTDWPrivSynEditMiscProcs, + uRESTDWPrivSynUnicode, + Classes, + SysUtils, + Graphics; + +type + TSynEditRange = Pointer; + + TSynEditStringFlag = (sfHasTabs, sfHasNoTabs, sfExpandedLengthUnknown, + sfModified, sfSaved); + TSynEditStringFlags = set of TSynEditStringFlag; + + PSynEditStringRec = ^TSynEditStringRec; + TSynEditStringRec = record + {$IFDEF OWN_UnicodeString_MEMMGR} + FString: PWideChar; // "array of WideChar"; + {$ELSE} + FString: UnicodeString; + {$ENDIF OWN_UnicodeString_MEMMGR} + FObject: TObject; + FRange: TSynEditRange; + FExpandedLength: Integer; + fCharIndex : Integer; + FFlags: TSynEditStringFlags; + end; + + TSynEditTwoWideChars = record + One, Two : WideChar; + end; + PSynEditTwoWideChars = ^TSynEditTwoWideChars; + +const + SynEditStringRecSize = SizeOf(TSynEditStringRec); + MaxSynEditStrings = MaxInt div SynEditStringRecSize; + + NullRange = TSynEditRange(-1); + +type + PSynEditStringRecList = ^TSynEditStringRecList; + TSynEditStringRecList = array[0..MaxSynEditStrings - 1] of TSynEditStringRec; + + TStringListChangeEvent = procedure(Sender: TObject; Index: Integer; + Count: Integer) of object; + + TExpandAtWideGlyphsFunc = function (const S: UnicodeString): UnicodeString of object; + + TSynEditFileFormat = (sffDos, sffUnix, sffMac, sffUnicode); // DOS: CRLF, UNIX: LF, Mac: CR, Unicode: LINE SEPARATOR + + TSynEditModification = (smOriginal, smModified, smSaved); + + TSynEditStringList = class(TUnicodeStrings) + private + FList: PSynEditStringRecList; + FCount: Integer; + FCapacity: Integer; + FFileFormat: TSynEditFileFormat; + FAppendNewLineAtEOF: Boolean; + FConvertTabsProc: TConvertTabsProcEx; + FIndexOfLongestLine: Integer; + FTabWidth: Integer; + FExpandAtWideGlyphsFunc: TExpandAtWideGlyphsFunc; + FCharIndexesAreValid : Boolean; + FOnChange: TNotifyEvent; + FOnChanging: TNotifyEvent; + FOnCleared: TNotifyEvent; + FOnDeleted: TStringListChangeEvent; + FOnInserted: TStringListChangeEvent; + FOnPutted: TStringListChangeEvent; + function ExpandString(Index: Integer): UnicodeString; + function GetExpandedString(Index: Integer): UnicodeString; + function GetExpandedStringLength(Index: Integer): Integer; + function GetLengthOfLongestLine: Integer; + function GetRange(Index: Integer): TSynEditRange; + function GetModification(Index: Integer): TSynEditModification; + procedure Grow; + procedure InsertItem(Index: Integer; const S: UnicodeString); + procedure PutRange(Index: Integer; ARange: TSynEditRange); + procedure SetFileFormat(const Value: TSynEditFileFormat); + {$IFDEF OWN_UnicodeString_MEMMGR} + procedure SetListString(Index: Integer; const S: UnicodeString); + {$ENDIF OWN_UnicodeString_MEMMGR} + protected + FStreaming: Boolean; + function Get(Index: Integer): UnicodeString; override; + function GetCapacity: Integer; + {$IFDEF SYN_COMPILER_3_UP} override; {$ENDIF} + function GetCount: Integer; override; + function GetObject(Index: Integer): TObject; override; + function GetTextStr: UnicodeString; override; + procedure Put(Index: Integer; const S: UnicodeString); override; + procedure PutObject(Index: Integer; AObject: TObject); override; + procedure SetCapacity(NewCapacity: Integer); + {$IFDEF SYN_COMPILER_3_UP} override; {$ENDIF} + procedure SetTabWidth(Value: Integer); + procedure SetUpdateState(Updating: Boolean); override; + procedure UpdateCharIndexes; + public + constructor Create(AExpandAtWideGlyphsFunc: TExpandAtWideGlyphsFunc); + destructor Destroy; override; + function Add(const S: UnicodeString): Integer; override; + procedure AddStrings(Strings: TUnicodeStrings); override; + procedure Clear; override; + procedure Delete(Index: Integer); override; + procedure DeleteLines(Index, NumLines: Integer); + procedure Exchange(Index1, Index2: Integer); override; + procedure Insert(Index: Integer; const S: UnicodeString); override; + procedure InsertLines(Index, NumLines: Integer); + procedure InsertStrings(Index: Integer; NewStrings: TUnicodeStrings); + procedure InsertText(Index: Integer; NewText: UnicodeString); +{$IFDEF UNICODE} + procedure SaveToStream(Stream: TStream; Encoding: TEncoding); override; + function GetSeparatedText(Separators: UnicodeString): UnicodeString; +{$ELSE} + procedure SaveToStream(Stream: TStream; WithBOM: Boolean = True); override; +{$ENDIF} + procedure SetTextStr(const Value: UnicodeString); override; + procedure LoadFromStream(Stream: TStream); override; + procedure FontChanged; + function LineCharLength(Index : Integer) : Integer; + function LineCharIndex(Index : Integer) : Integer; + + procedure MarkModifiedLinesAsSaved; + procedure ResetModificationIndicator; + + property AppendNewLineAtEOF: Boolean read FAppendNewLineAtEOF write FAppendNewLineAtEOF; + + property FileFormat: TSynEditFileFormat read FFileFormat write SetFileFormat; + property ExpandedStrings[Index: Integer]: UnicodeString read GetExpandedString; + property ExpandedStringLengths[Index: Integer]: Integer read GetExpandedStringLength; + property LengthOfLongestLine: Integer read GetLengthOfLongestLine; + property Ranges[Index: Integer]: TSynEditRange read GetRange write PutRange; + property Modification[Index: Integer]: TSynEditModification read GetModification; + property TabWidth: Integer read FTabWidth write SetTabWidth; + property OnChange: TNotifyEvent read FOnChange write FOnChange; + property OnChanging: TNotifyEvent read FOnChanging write FOnChanging; + property OnCleared: TNotifyEvent read FOnCleared write FOnCleared; + property OnDeleted: TStringListChangeEvent read FOnDeleted write FOnDeleted; + property OnInserted: TStringListChangeEvent read FOnInserted + write FOnInserted; + property OnPutted: TStringListChangeEvent read FOnPutted write FOnPutted; + end; + + ESynEditStringList = class(Exception); + + TSynChangeReason = (crInsert, crPaste, crDragDropInsert, + // Note: several undo entries can be chained together via the ChangeNumber + // see also TCustomSynEdit.[Begin|End]UndoBlock methods + crDeleteAfterCursor, crDelete, + crLineBreak, crIndent, crUnindent, + crSilentDelete, crSilentDeleteAfterCursor, + crAutoCompleteBegin, crAutoCompleteEnd, + crPasteBegin, crPasteEnd, // for pasting, since it might do a lot of operations + crSpecial1Begin, crSpecial1End, + crSpecial2Begin, crSpecial2End, + crCaret, // just restore the Caret, allowing better Undo behavior + crSelection, // restore Selection + crNothing, + crGroupBreak, + crDeleteAll, + crWhiteSpaceAdd // for undo/redo of adding a character past EOL and repositioning the caret + ); + + TSynEditUndoItem = class(TPersistent) + protected + FChangeReason: TSynChangeReason; + FChangeSelMode: TSynSelectionMode; + FChangeStartPos: TBufferCoord; + FChangeEndPos: TBufferCoord; + FChangeStr: UnicodeString; + FChangeNumber: Integer; + public + procedure Assign(Source: TPersistent); override; + property ChangeReason: TSynChangeReason read FChangeReason; + property ChangeSelMode: TSynSelectionMode read FChangeSelMode; + property ChangeStartPos: TBufferCoord read FChangeStartPos; + property ChangeEndPos: TBufferCoord read FChangeEndPos; + property ChangeStr: UnicodeString read FChangeStr; + property ChangeNumber: Integer read FChangeNumber; + end; + + TSynEditUndoList = class(TPersistent) + protected + FBlockChangeNumber: Integer; + FBlockCount: Integer; + FFullUndoImposible: Boolean; + FItems: TList; + FLockCount: Integer; + FMaxUndoActions: Integer; + FNextChangeNumber: Integer; + FInitialChangeNumber: Integer; + FInsideRedo: Boolean; + FOnAddedUndo: TNotifyEvent; + procedure EnsureMaxEntries; + function GetCanUndo: Boolean; + function GetItemCount: Integer; + procedure SetMaxUndoActions(Value: Integer); + procedure SetInitialState(const Value: Boolean); + function GetInitialState: Boolean; + function GetItems(Index: Integer): TSynEditUndoItem; + procedure SetItems(Index: Integer; const Value: TSynEditUndoItem); + public + constructor Create; + destructor Destroy; override; + procedure AddChange(AReason: TSynChangeReason; const AStart, AEnd: TBufferCoord; + const ChangeText: UnicodeString; SelMode: TSynSelectionMode); + procedure BeginBlock; + procedure Clear; + procedure EndBlock; + procedure Lock; + function PeekItem: TSynEditUndoItem; + function PopItem: TSynEditUndoItem; + procedure PushItem(Item: TSynEditUndoItem); + procedure Unlock; + function LastChangeReason: TSynChangeReason; + public + procedure Assign(Source: TPersistent); override; + procedure AddGroupBreak; + procedure DeleteItem(AIndex: Integer); + property BlockChangeNumber: Integer read FBlockChangeNumber + write FBlockChangeNumber; + property CanUndo: Boolean read GetCanUndo; + property FullUndoImpossible: Boolean read FFullUndoImposible; + property InitialState: Boolean read GetInitialState write SetInitialState; + property Items[Index: Integer]: TSynEditUndoItem read GetItems write SetItems; + property ItemCount: Integer read GetItemCount; + property BlockCount: Integer read FBlockCount; + property MaxUndoActions: Integer read FMaxUndoActions + write SetMaxUndoActions; + property InsideRedo: Boolean read FInsideRedo write FInsideRedo; + property OnAddedUndo: TNotifyEvent read FOnAddedUndo write FOnAddedUndo; + end; + +implementation + +{$IFDEF SYN_COMPILER_3_UP} +resourcestring +{$ELSE} +const +{$ENDIF} + SListIndexOutOfBounds = 'Invalid stringlist index %d'; + SInvalidCapacity = 'Stringlist capacity cannot be smaller than count'; + +{ TSynEditStringList } + +procedure ListIndexOutOfBounds(Index: Integer); +begin + raise ESynEditStringList.CreateFmt(SListIndexOutOfBounds, [Index]); +end; + +constructor TSynEditStringList.Create(AExpandAtWideGlyphsFunc: TExpandAtWideGlyphsFunc); +begin + inherited Create; + FExpandAtWideGlyphsFunc := AExpandAtWideGlyphsFunc; + SetFileFormat(sffDos); + FIndexOfLongestLine := -1; + TabWidth := 8; +end; + +destructor TSynEditStringList.Destroy; +begin + FOnChange := nil; + FOnChanging := nil; + inherited Destroy; + {$IFDEF OWN_UnicodeString_MEMMGR} + FOnCleared := nil; + Clear; + {$ELSE} + if FCount <> 0 then + Finalize(FList^[0], FCount); + FCount := 0; + SetCapacity(0); + {$ENDIF OWN_UnicodeString_MEMMGR} +end; + +function TSynEditStringList.Add(const S: UnicodeString): Integer; +begin + BeginUpdate; + Result := FCount; + InsertItem(Result, S); + if Assigned(OnInserted) then + OnInserted(Self, Result, 1); + EndUpdate; +end; + +procedure TSynEditStringList.AddStrings(Strings: TUnicodeStrings); +var + i, FirstAdded: Integer; +begin + if Strings.Count > 0 then begin + FIndexOfLongestLine := -1; + BeginUpdate; + try + i := FCount + Strings.Count; + if i > FCapacity then + SetCapacity((i + 15) and (not 15)); + FirstAdded := FCount; + for i := 0 to Strings.Count - 1 do begin + with FList^[FCount] do begin + Pointer(FString) := nil; + {$IFDEF OWN_UnicodeString_MEMMGR} + SetListString(FCount, Strings[i]); + {$ELSE} + FString := Strings[i]; + {$ENDIF OWN_UnicodeString_MEMMGR} + FObject := Strings.Objects[i]; + FRange := NullRange; + FExpandedLength := -1; + FFlags := [sfExpandedLengthUnknown]; + end; + Inc(FCount); + end; + if Assigned(OnInserted) then + OnInserted(Self, FirstAdded, Strings.Count); + finally + EndUpdate; + end; + end; +end; + +procedure TSynEditStringList.Clear; +{$IFDEF OWN_UnicodeString_MEMMGR} +var + I: Integer; +{$ENDIF OWN_UnicodeString_MEMMGR} +begin + if FCount <> 0 then begin + BeginUpdate; + {$IFDEF OWN_UnicodeString_MEMMGR} + for I := 0 to FCount - 1 do + with FList[I] do + if TDynWideCharArray(FString) <> nil then + TDynWideCharArray(FString) := nil; + {$ELSE} + Finalize(FList^[0], FCount); + {$ENDIF OWN_UnicodeString_MEMMGR} + FCount := 0; + SetCapacity(0); + if Assigned(FOnCleared) then + FOnCleared(Self); + EndUpdate; + end; + FIndexOfLongestLine := -1; +end; + +procedure TSynEditStringList.Delete(Index: Integer); +begin + if (Index < 0) or (Index >= FCount) then + ListIndexOutOfBounds(Index); + BeginUpdate; + {$IFDEF OWN_UnicodeString_MEMMGR} + SetListString(Index, ''); + {$ELSE} + Finalize(FList^[Index]); + {$ENDIF OWN_UnicodeString_MEMMGR} + Dec(FCount); + if Index < FCount then begin + System.Move(FList^[Index + 1], FList^[Index], + (FCount - Index) * SynEditStringRecSize); + {$IFDEF OWN_UnicodeString_MEMMGR} + Pointer(FList[FCount].FString) := nil; // avoid freeing the string, the address is now used in another element + {$ENDIF OWN_UnicodeString_MEMMGR} + end; + FIndexOfLongestLine := -1; + if Assigned(FOnDeleted) then + FOnDeleted( Self, Index, 1 ); + EndUpdate; +end; + +procedure TSynEditStringList.DeleteLines(Index, NumLines: Integer); +var + LinesAfter: Integer; +{$IFDEF OWN_UnicodeString_MEMMGR} + I: Integer; +{$ENDIF OWN_UnicodeString_MEMMGR} +begin + if NumLines > 0 then begin + if (Index < 0) or (Index >= FCount) then + ListIndexOutOfBounds(Index); + LinesAfter := FCount - (Index + NumLines); + if LinesAfter < 0 then + NumLines := FCount - Index; + {$IFDEF OWN_UnicodeString_MEMMGR} + for I := Index to Index + NumLines - 1 do + with FList[I] do + if TDynWideCharArray(FString) <> nil then + TDynWideCharArray(FString) := nil; + {$ELSE} + Finalize(FList^[Index], NumLines); + {$ENDIF OWN_UnicodeString_MEMMGR} + + if LinesAfter > 0 then begin + BeginUpdate; + try + System.Move(FList^[Index + NumLines], FList^[Index], + LinesAfter * SynEditStringRecSize); + finally + EndUpdate; + end; + end; + Dec(FCount, NumLines); + if Assigned(FOnDeleted) then + FOnDeleted( Self, Index, NumLines ); + end; +end; + +procedure TSynEditStringList.Exchange(Index1, Index2: Integer); +var + Temp: TSynEditStringRec; +begin + if (Index1 < 0) or (Index1 >= FCount) then + ListIndexOutOfBounds(Index1); + if (Index2 < 0) or (Index2 >= FCount) then + ListIndexOutOfBounds(Index2); + BeginUpdate; + Temp := FList^[Index1]; + FList^[Index1] := FList^[Index2]; + FList^[Index2] := Temp; + if FIndexOfLongestLine = Index1 then + FIndexOfLongestLine := Index2 + else if FIndexOfLongestLine = Index2 then + FIndexOfLongestLine := Index1; + EndUpdate; +end; + +function TSynEditStringList.ExpandString(Index: Integer): UnicodeString; +var + HasTabs: Boolean; +begin + with FList^[Index] do + {$IFDEF OWN_UnicodeString_MEMMGR} + if Length(TDynWideCharArray(FString)) = 0 then + {$ELSE} + if Length(FString) = 0 then + {$ENDIF} + begin + Result := ''; + Exclude(FFlags, sfExpandedLengthUnknown); + Exclude(FFlags, sfHasTabs); + Include(FFlags, sfHasNoTabs); + FExpandedLength := 0; + end + else + begin + Result := FConvertTabsProc(FString, FTabWidth, HasTabs); + FExpandedLength := Length(FExpandAtWideGlyphsFunc(Result)); + Exclude(FFlags, sfExpandedLengthUnknown); + Exclude(FFlags, sfHasTabs); + Exclude(FFlags, sfHasNoTabs); + if HasTabs then + Include(FFlags, sfHasTabs) + else + Include(FFlags, sfHasNoTabs); + end; +end; + +function TSynEditStringList.Get(Index: Integer): UnicodeString; +{$IFDEF OWN_UnicodeString_MEMMGR} +var + Len: Integer; +{$ENDIF OWN_UnicodeString_MEMMGR} +begin + if Cardinal(Index) 0 then + begin + SetLength(Result, Len - 1); // exclude #0 + if Result <> '' then + System.Move(FString^, Result[1], Len * SizeOf(WideChar)); + end + else + Result := ''; + end + {$ELSE} + Result := FList^[Index].FString + {$ENDIF OWN_UnicodeString_MEMMGR} + else + Result := ''; +end; + +procedure TSynEditStringList.UpdateCharIndexes; +var + i, n : Integer; + p : PSynEditStringRec; +begin + FCharIndexesAreValid:=True; + if FCount=0 then Exit; + p:=@FList^[0]; + n:=0; + for i:=1 to FCount do begin + p.fCharIndex:=n; + Inc(n, Length(p.FString)); + Inc(p); + end; +end; + +function TSynEditStringList.LineCharLength(Index : Integer) : Integer; +begin + if Cardinal(Index)= 0) and (Index < FCount) then + begin + if sfHasNoTabs in FList^[Index].FFlags then + Result := Get(Index) + else + Result := ExpandString(Index); + end else + Result := ''; +end; + +function TSynEditStringList.GetExpandedStringLength(Index: Integer): Integer; +begin + if (Index >= 0) and (Index < FCount) then + begin + if sfExpandedLengthUnknown in FList^[Index].FFlags then + Result := Length( ExpandedStrings[index] ) + else + Result := FList^[Index].FExpandedLength; + end + else + Result := 0; +end; + +function TSynEditStringList.GetLengthOfLongestLine: Integer; +var + i, MaxLen: Integer; + PRec: PSynEditStringRec; +begin + if FIndexOfLongestLine < 0 then + begin + MaxLen := 0; + if FCount > 0 then + begin + PRec := @FList^[0]; + for i := 0 to FCount - 1 do + begin + if sfExpandedLengthUnknown in PRec^.FFlags then + ExpandString(i); + if PRec^.FExpandedLength > MaxLen then + begin + MaxLen := PRec^.FExpandedLength; + FIndexOfLongestLine := i; + end; + Inc(PRec); + end; + end; + end; + if (FIndexOfLongestLine >= 0) and (FIndexOfLongestLine < FCount) then + Result := FList^[FIndexOfLongestLine].FExpandedLength + else + Result := 0; +end; + +function TSynEditStringList.GetModification( + Index: Integer): TSynEditModification; +begin + Result := smOriginal; + if (Index >= 0) and (Index < FCount) then + if sfSaved in FList^[Index].FFlags then + Result := smSaved + else + if sfModified in FList^[Index].FFlags then + Result := smModified; +end; + +function TSynEditStringList.GetObject(Index: Integer): TObject; +begin + if (Index >= 0) and (Index < FCount) then + Result := FList^[Index].FObject + else + Result := nil; +end; + +function TSynEditStringList.GetRange(Index: Integer): TSynEditRange; +begin + if (Index >= 0) and (Index < FCount) then + Result := FList^[Index].FRange + else + Result := nil; +end; + +{$IFDEF UNICODE} +function TSynEditStringList.GetSeparatedText(Separators: UnicodeString): UnicodeString; +{Optimized by Eric Grange} +var + I, L, Size, LineBreakSize: Integer; + P, PLineBreak: PChar; + PRec: PSynEditStringRec; +begin + if FCount = 0 then + begin + Result := ''; + Exit; + end; + LineBreakSize := Length(Separators); + PLineBreak := Pointer(Separators); + + // compute buffer size + Size := (FCount - 1) * LineBreakSize + + LineCharIndex( FCount - 1 ) + + Length( FList^[FCount - 1].FString ); + SetLength(Result, Size); + + P := Pointer(Result); + PRec := @FList^[0]; + + // handle 1st line separately (to avoid trailing line break) + L := Length(PRec.FString); + if L <> 0 then + begin + System.Move(Pointer(PRec.FString)^, P^, L * SizeOf(Char)); + Inc(P, L); + end; + Inc(PRec); + + for I := 1 to FCount-1 do + begin + case LineBreakSize of + 0 : ; + 1 : begin + P^ := PLineBreak^; + Inc(P); + end; + 2 : begin + PSynEditTwoWideChars(P)^ := PSynEditTwoWideChars(PLineBreak)^; + Inc(P, 2); + end; + else + System.Move(PLineBreak^, P^, LineBreakSize * SizeOf(Char)); + Inc(P, LineBreakSize); + end; + if Pointer( PRec.FString ) <> nil then + begin + L := Length(PRec.FString); + System.Move(Pointer(PRec.FString)^, P^, L * SizeOf(Char)); + Inc(P, L); + end; + Inc(PRec); + end; +end; +{$ENDIF} + +function TSynEditStringList.GetTextStr: UnicodeString; +var + LB: UnicodeString; +begin + if not FStreaming then + begin + Result := GetSeparatedText(sLineBreak); + end + else + begin + case FileFormat of + sffDos: + LB := WideCRLF; + sffUnix: + LB := WideLF; + sffMac: + LB := WideCR; + sffUnicode: + LB := WideLineSeparator; + end; + Result := GetSeparatedText(LB); + if AppendNewLineAtEOF then + Result := Result + LB; + end; +end; + +procedure TSynEditStringList.Grow; +var + Delta: Integer; +begin + if FCapacity > 64 then + Delta := FCapacity div 4 + else + Delta := 16; + SetCapacity(FCapacity + Delta); +end; + +procedure TSynEditStringList.Insert(Index: Integer; const S: UnicodeString); +begin + if (Index < 0) or (Index > FCount) then + ListIndexOutOfBounds(Index); + BeginUpdate; + InsertItem(Index, S); + if Assigned(FOnInserted) then + FOnInserted( Self, Index, 1 ); + EndUpdate; +end; + +procedure TSynEditStringList.InsertItem(Index: Integer; const S: UnicodeString); +begin + BeginUpdate; + if FCount = FCapacity then + Grow; + if Index < FCount then + begin + System.Move(FList^[Index], FList^[Index + 1], + (FCount - Index) * SynEditStringRecSize); + end; + FIndexOfLongestLine := -1; + with FList^[Index] do + begin + Pointer(FString) := nil; + {$IFDEF OWN_UnicodeString_MEMMGR} + SetListString(Index, S); + {$ELSE} + FString := S; + {$ENDIF OWN_UnicodeString_MEMMGR} + FObject := nil; + FRange := NullRange; + FExpandedLength := -1; + FFlags := [sfExpandedLengthUnknown]; + Include(FFlags, sfModified); + end; + Inc(FCount); + EndUpdate; +end; + +procedure TSynEditStringList.InsertLines(Index, NumLines: Integer); +var + c_Line: Integer; +begin + if (Index < 0) or (Index > FCount) then + ListIndexOutOfBounds(Index); + if NumLines > 0 then + begin + BeginUpdate; + try + SetCapacity(FCount + NumLines); + if Index < FCount then + begin + System.Move(FList^[Index], FList^[Index + NumLines], + (FCount - Index) * SynEditStringRecSize); + end; + for c_Line := Index to Index + NumLines -1 do + with FList^[c_Line] do + begin + Pointer(FString) := nil; + FObject := nil; + FRange := NullRange; + FExpandedLength := -1; + FFlags := [sfExpandedLengthUnknown]; + end; + Inc(FCount, NumLines); + if Assigned(OnInserted) then + OnInserted(Self, Index, NumLines); + finally + EndUpdate; + end; + end; +end; + +procedure TSynEditStringList.InsertStrings(Index: Integer; + NewStrings: TUnicodeStrings); +var + i, Cnt: Integer; +begin + Cnt := NewStrings.Count; + if Cnt = 0 then Exit; + + BeginUpdate; + try + InsertLines(Index, Cnt); + for i := 0 to Cnt - 1 do + Strings[Index + i] := NewStrings[i]; + finally + EndUpdate; + end; +end; + +procedure TSynEditStringList.InsertText(Index: Integer; + NewText: UnicodeString); +var + TmpStringList: TUnicodeStringList; +begin + if NewText = '' then Exit; + + TmpStringList := TUnicodeStringList.Create; + try + TmpStringList.Text := NewText; + InsertStrings(Index, TmpStringList); + finally + TmpStringList.Free; + end; +end; + +procedure TSynEditStringList.LoadFromStream(Stream: TStream); +begin + FStreaming := True; + inherited; + FStreaming := False; + ResetModificationIndicator; +end; + +procedure TSynEditStringList.MarkModifiedLinesAsSaved; +var + Index: Integer; +begin + for Index := 0 to FCount - 1 do + if sfModified in FList^[Index].FFlags then + Include(FList^[Index].FFlags, sfSaved); +end; + +procedure TSynEditStringList.ResetModificationIndicator; +var + Index: Integer; +begin + for Index := 0 to FCount - 1 do + begin + Exclude(FList^[Index].FFlags, sfModified); + Exclude(FList^[Index].FFlags, sfSaved); + end; +end; + +{$IFDEF UNICODE} +procedure TSynEditStringList.SaveToStream(Stream: TStream; Encoding: TEncoding); +begin + FStreaming := True; + inherited; + FStreaming := False; +end; +{$ELSE} +procedure TSynEditStringList.SaveToStream(Stream: TStream; WithBOM: Boolean); +begin + FStreaming := True; + inherited; + FStreaming := False; +end; +{$ENDIF} + +procedure TSynEditStringList.Put(Index: Integer; const S: UnicodeString); +begin + if (Index = 0) and (FCount = 0) or (FCount = Index) then + Add(S) + else begin + if Cardinal(Index)>=Cardinal(FCount) then + ListIndexOutOfBounds(Index); + BeginUpdate; + FIndexOfLongestLine := -1; + with FList^[Index] do begin + Include(FFlags, sfExpandedLengthUnknown); + Exclude(FFlags, sfHasTabs); + Exclude(FFlags, sfHasNoTabs); + Include(FFlags, sfModified); + Exclude(FFlags, sfSaved); + {$IFDEF OWN_UnicodeString_MEMMGR} + SetListString(Index, S); + {$ELSE} + FString := S; + {$ENDIF OWN_UnicodeString_MEMMGR} + end; + if Assigned(FOnPutted) then + FOnPutted( Self, Index, 1 ); + EndUpdate; + end; +end; + +procedure TSynEditStringList.PutObject(Index: Integer; AObject: TObject); +begin + if Cardinal(Index)>=Cardinal(FCount) then + ListIndexOutOfBounds(Index); + BeginUpdate; + FList^[Index].FObject := AObject; + EndUpdate; +end; + +procedure TSynEditStringList.PutRange(Index: Integer; ARange: TSynEditRange); +begin + if Cardinal(Index)>=Cardinal(FCount) then + ListIndexOutOfBounds(Index); + BeginUpdate; + FList^[Index].FRange := ARange; + EndUpdate; +end; + +procedure TSynEditStringList.SetCapacity(NewCapacity: Integer); +{$IFDEF OWN_UnicodeString_MEMMGR} +var + I : Integer; +{$ENDIF OWN_UnicodeString_MEMMGR} +begin + if NewCapacity < Count then + EListError.Create( SInvalidCapacity ); + ReallocMem(FList, NewCapacity * SynEditStringRecSize); + {$IFDEF OWN_UnicodeString_MEMMGR} + for I := FCount to NewCapacity - 1 do + Pointer(FList[I].FString) := nil; // so that it does not get freed + {$ENDIF OWN_UnicodeString_MEMMGR} + FCapacity := NewCapacity; +end; + +procedure TSynEditStringList.SetFileFormat(const Value: TSynEditFileFormat); +begin + FFileFormat := Value; +{$IFDEF UNICODE} + case FileFormat of + sffDos: + LineBreak := WideCRLF; + sffUnix: + LineBreak := WideLF; + sffMac: + LineBreak := WideCR; + sffUnicode: + LineBreak := WideLineSeparator; + end; +{$ENDIF} +end; + +{$IFDEF OWN_UnicodeString_MEMMGR} +procedure TSynEditStringList.SetListString(Index: Integer; const S: UnicodeString); +var + Len: Integer; + A: TDynWideCharArray; +begin + with FList[Index] do + begin + Pointer(A) := TDynWideCharArray(FString); + if A <> nil then + A := nil; // free memory + + Len := Length(S); + if Len > 0 then + begin + SetLength(A, Len + 1); // include #0 + System.Move(S[1], A[0], Len * SizeOf(WideChar)); + A[Len] := #0; + end; + + FString := PWideChar(A); + Pointer(A) := nil; // do not release the array on procedure Exit + end; +end; +{$ENDIF OWN_UnicodeString_MEMMGR} + +procedure TSynEditStringList.SetTabWidth(Value: Integer); +var + i: Integer; +begin + if Value <> FTabWidth then begin + FTabWidth := Value; + FConvertTabsProc := GetBestConvertTabsProcEx(FTabWidth); + FIndexOfLongestLine := -1; + for i := 0 to FCount - 1 do + with FList^[i] do begin + FExpandedLength := -1; + Exclude(FFlags, sfHasNoTabs); + Include(FFlags, sfExpandedLengthUnknown); + end; + end; +end; + +procedure TSynEditStringList.SetTextStr(const Value: UnicodeString); +var + S: UnicodeString; + Size: Integer; + P, Start, Pmax: PWideChar; + fCR, fLF, fLINESEPARATOR: Boolean; +begin + fLINESEPARATOR := False; + fCR := False; + fLF := False; + BeginUpdate; + try + Clear; + P := Pointer(Value); + if P <> nil then + begin + Size := Length(Value); + Pmax := @Value[Size]; + while (P <= Pmax) do + begin + Start := P; + while (P^ <> WideCR) and (P^ <> WideLF) and (P^ <> WideLineSeparator) and (P <= Pmax) do + begin + Inc(P); + end; + if P<>Start then + begin + SetString(S, Start, P - Start); + InsertItem(FCount, S); + end else InsertItem(FCount, ''); + if P^ = WideLineSeparator then + begin + fLINESEPARATOR := True; + Inc(P); + end; + if P^ = WideCR then + begin + fCR := True; + Inc(P); + end; + if P^ = WideLF then + begin + fLF := True; + Inc(P); + end; + end; + // keep the old format of the file + if not AppendNewLineAtEOF and + (CharInSet(Value[Size], [#10, #13]) or (Value[Size] = WideLineSeparator)) + then + InsertItem(FCount, ''); + end; + if Assigned(OnInserted) and (FCount > 0) then + OnInserted(Self, 0, FCount); + finally + EndUpdate; + end; + if fLINESEPARATOR then + FileFormat := sffUnicode + else if fCR and not fLF then + FileFormat := sffMac + else if fLF and not fCR then + FileFormat := sffUnix + else + FileFormat := sffDos; +end; + +procedure TSynEditStringList.SetUpdateState(Updating: Boolean); +begin + FCharIndexesAreValid:=False; + if Updating then begin + if Assigned(FOnChanging) then + FOnChanging(Self); + end else begin + if Assigned(FOnChange) then + FOnChange(Self); + end; +end; + +procedure TSynEditStringList.FontChanged; +var + i: Integer; +begin + FIndexOfLongestLine := -1; + for i := 0 to FCount - 1 do + with FList^[i] do + begin + FExpandedLength := -1; + Exclude(FFlags, sfHasNoTabs); + Include(FFlags, sfExpandedLengthUnknown); + end; +end; + +{ TSynEditUndoItem } + +procedure TSynEditUndoItem.Assign(Source: TPersistent); +begin + if (Source is TSynEditUndoItem) then + begin + FChangeReason:=TSynEditUndoItem(Source).FChangeReason; + FChangeSelMode:=TSynEditUndoItem(Source).FChangeSelMode; + FChangeStartPos:=TSynEditUndoItem(Source).FChangeStartPos; + FChangeEndPos:=TSynEditUndoItem(Source).FChangeEndPos; + FChangeStr:=TSynEditUndoItem(Source).FChangeStr; + FChangeNumber:=TSynEditUndoItem(Source).FChangeNumber; + end + else + inherited Assign(Source); +end; + + +{ TSynEditUndoList } + +constructor TSynEditUndoList.Create; +begin + inherited Create; + FItems := TList.Create; + FMaxUndoActions := 1024; + FNextChangeNumber := 1; + FInsideRedo := False; +end; + +destructor TSynEditUndoList.Destroy; +begin + Clear; + FItems.Free; + inherited Destroy; +end; + +procedure TSynEditUndoList.Assign(Source: TPersistent); +var + i: Integer; + UndoItem: TSynEditUndoItem; +begin + if (Source is TSynEditUndoList) then + begin + Clear; + for i:=0 to TSynEditUndoList(Source).FItems.Count-1 do + begin + UndoItem:=TSynEditUndoItem.Create; + UndoItem.Assign(TSynEditUndoList(Source).FItems[i]); + FItems.Add(UndoItem); + end; + FBlockChangeNumber:=TSynEditUndoList(Source).FBlockChangeNumber; + FBlockCount:=TSynEditUndoList(Source).FBlockCount; + FFullUndoImposible:=TSynEditUndoList(Source).FFullUndoImposible; + FLockCount:=TSynEditUndoList(Source).FLockCount; + FMaxUndoActions:=TSynEditUndoList(Source).FMaxUndoActions; + FNextChangeNumber:=TSynEditUndoList(Source).FNextChangeNumber; + FInsideRedo:=TSynEditUndoList(Source).FInsideRedo; + end + else + inherited Assign(Source); +end; + +procedure TSynEditUndoList.AddChange(AReason: TSynChangeReason; const AStart, + AEnd: TBufferCoord; const ChangeText: UnicodeString; SelMode: TSynSelectionMode); +var + NewItem: TSynEditUndoItem; +begin + if FLockCount = 0 then begin + NewItem := TSynEditUndoItem.Create; + try + with NewItem do begin + FChangeReason := AReason; + FChangeSelMode := SelMode; + FChangeStartPos := AStart; + FChangeEndPos := AEnd; + FChangeStr := ChangeText; + if FBlockChangeNumber <> 0 then + FChangeNumber := FBlockChangeNumber + else begin + FChangeNumber := FNextChangeNumber; + if FBlockCount = 0 then begin + Inc(FNextChangeNumber); + if FNextChangeNumber = 0 then + Inc(FNextChangeNumber); + end; + end; + end; + PushItem(NewItem); + except + NewItem.Free; + raise; + end; + end; +end; + +procedure TSynEditUndoList.BeginBlock; +begin + Inc(FBlockCount); + FBlockChangeNumber := FNextChangeNumber; +end; + +procedure TSynEditUndoList.Clear; +var + i: Integer; +begin + for i := 0 to FItems.Count - 1 do + TSynEditUndoItem(FItems[i]).Free; + FItems.Clear; + FFullUndoImposible := False; +end; + +procedure TSynEditUndoList.EndBlock; +var + iBlockID: Integer; +begin + if FBlockCount > 0 then begin + Dec(FBlockCount); + if FBlockCount = 0 then begin + iBlockID := FBlockChangeNumber; + FBlockChangeNumber := 0; + Inc(FNextChangeNumber); + if FNextChangeNumber = 0 then + Inc(FNextChangeNumber); + if (FItems.Count > 0) and (PeekItem.ChangeNumber = iBlockID) and + Assigned(OnAddedUndo) then + begin + OnAddedUndo( Self ); + end; + end; + end; +end; + +procedure TSynEditUndoList.EnsureMaxEntries; +var + Item: TSynEditUndoItem; +begin + if FItems.Count > FMaxUndoActions then + begin + FFullUndoImposible := True; + while FItems.Count > FMaxUndoActions do begin + Item := FItems[0]; + Item.Free; + FItems.Delete(0); + end; + end; +end; + +function TSynEditUndoList.GetCanUndo: Boolean; +begin + Result := FItems.Count > 0; +end; + +function TSynEditUndoList.GetItemCount: Integer; +begin + Result := FItems.Count; +end; + +procedure TSynEditUndoList.Lock; +begin + Inc(FLockCount); +end; + +function TSynEditUndoList.PeekItem: TSynEditUndoItem; +var + iLast: Integer; +begin + Result := nil; + iLast := FItems.Count - 1; + if iLast >= 0 then + Result := FItems[iLast]; +end; + +function TSynEditUndoList.PopItem: TSynEditUndoItem; +var + iLast: Integer; +begin + Result := nil; + iLast := FItems.Count - 1; + if iLast >= 0 then begin + Result := FItems[iLast]; + FItems.Delete(iLast); + end; +end; + +procedure TSynEditUndoList.PushItem(Item: TSynEditUndoItem); +begin + if Assigned(Item) then begin + FItems.Add(Item); + EnsureMaxEntries; + if (Item.ChangeReason <> crGroupBreak) and Assigned(OnAddedUndo) then + OnAddedUndo(Self); + end; +end; + +procedure TSynEditUndoList.SetMaxUndoActions(Value: Integer); +begin + if Value < 0 then + Value := 0; + if Value <> FMaxUndoActions then begin + FMaxUndoActions := Value; + EnsureMaxEntries; + end; +end; + +procedure TSynEditUndoList.Unlock; +begin + if FLockCount > 0 then + Dec(FLockCount); +end; + +function TSynEditUndoList.LastChangeReason: TSynChangeReason; +begin + if FItems.Count = 0 then + Result := crNothing + else + Result := TSynEditUndoItem(FItems[FItems.Count - 1]).FChangeReason; +end; + +procedure TSynEditUndoList.AddGroupBreak; +var + vDummy: TBufferCoord; +begin + //Add the GroupBreak even if ItemCount = 0. Since items are stored in + //reverse order in TCustomSynEdit.fRedoList, a GroupBreak could be lost. + if LastChangeReason <> crGroupBreak then + begin + AddChange(crGroupBreak, vDummy, vDummy, '', smNormal); + end; +end; + +procedure TSynEditUndoList.SetInitialState(const Value: Boolean); +begin + if Value then + begin + if ItemCount = 0 then + FInitialChangeNumber := 0 + else + FInitialChangeNumber := PeekItem.ChangeNumber; + end + else + if ItemCount = 0 then + begin + if FInitialChangeNumber = 0 then + FInitialChangeNumber := -1; + end + else if PeekItem.ChangeNumber = FInitialChangeNumber then + FInitialChangeNumber := -1; +end; + +function TSynEditUndoList.GetInitialState: Boolean; +begin + if ItemCount = 0 then + Result := FInitialChangeNumber = 0 + else + Result := PeekItem.ChangeNumber = FInitialChangeNumber; +end; + +function TSynEditUndoList.GetItems(Index: Integer): TSynEditUndoItem; +begin + Result := TSynEditUndoItem(FItems[Index]); +end; + +procedure TSynEditUndoList.SetItems(Index: Integer; + const Value: TSynEditUndoItem); +begin + FItems[Index] := Value; +end; + +procedure TSynEditUndoList.DeleteItem(AIndex: Integer); +begin + TSynEditUndoItem(FItems[AIndex]).Free; + FItems.Delete(AIndex); +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditTypes.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditTypes.pas new file mode 100644 index 000000000..e030c9c6b --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditTypes.pas @@ -0,0 +1,149 @@ +{------------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: uRESTDWPrivSynEditTypes.pas, released 2000-04-07. +The Original Code is based on parts of mwCustomEdit.pas by Martin Waldenburg, +part of the mwEdit component suite. +Portions created by Martin Waldenburg are Copyright (C) 1998 Martin Waldenburg. +Unicode translation by Mal Hrz. +All Rights Reserved. + +Contributors to the uRESTDWPrivSynEdit and mwEdit projects are listed in the +Contributors.txt file. + +Alternatively, the contents of this file may be used under the terms of the +GNU General Public License Version 2 or later (the "GPL"), in which case +the provisions of the GPL are applicable instead of those above. +If you wish to allow use of your version of this file only under the terms +of the GPL and not to allow others to use your version of this file +under the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the GPL. +If you do not delete the provisions above, a recipient may use your version +of this file under either the MPL or the GPL. + +$Id: uRESTDWPrivSynEditTypes.pas,v 1.13.2.2 2012/09/17 14:17:25 CodehunterWorks Exp $ + +You may retrieve the latest version of this file at the uRESTDWPrivSynEdit home page, +located at http://uRESTDWPrivSynEdit.SourceForge.net + +Known Issues: +-------------------------------------------------------------------------------} + +{$IFNDEF QSYNEDITTYPES} +unit uRESTDWPrivSynEditTypes; +{$ENDIF} + +{$I uRESTDWPrivSynEdit.inc} + +interface + +uses + SysUtils; + +const +// These might need to be localized depending on the characterset because they might be +// interpreted as valid ident characters. + SynTabGlyph = WideChar($2192); //'->' + SynSoftBreakGlyph = WideChar($00AC); //'' + SynLineBreakGlyph = WideChar($00B6); //'' + SynSpaceGlyph = WideChar($2219); //'' + +type + ESynError = class(Exception); + + TSynSearchOption = (ssoMatchCase, ssoWholeWord, ssoBackwards, + ssoEntireScope, ssoSelectedOnly, ssoReplace, ssoReplaceAll, ssoPrompt); + TSynSearchOptions = set of TSynSearchOption; + + TCategoryMethod = function(AChar: WideChar): Boolean of object; + + TKeyPressWEvent = procedure(Sender: TObject; var Key: WideChar) of object; + + PSynSelectionMode = ^TSynSelectionMode; + TSynSelectionMode = (smNormal, smLine, smColumn); + + PBorlandSelectionMode = ^TBorlandSelectionMode; + TBorlandSelectionMode = ( + bsmInclusive, // selects inclusive blocks. Borland IDE shortcut: Ctrl+O+I + bsmLine, // selects line blocks. Borland IDE shortcut: Ctrl+O+L + bsmColumn, // selects column blocks. Borland IDE shortcut: Ctrl+O+C + bsmNormal // selects normal Block. Borland IDE shortcut: Ctrl+O+K + ); + + //todo: better field names. CharIndex and LineIndex? + TBufferCoord = record + Char: Integer; + Line: Integer; + {$IFDEF SYN_COMPILER_10_UP} + class operator Equal(a, b: TBufferCoord): Boolean; + {$ENDIF} + end; + + // Codehunter patch: added TBufferBlock + TBufferBlock = record + BeginLine, BeginChar: Integer; + EndLine, EndChar: Integer; + {$IFDEF SYN_COMPILER_10_UP} + class operator Equal(a, b: TBufferBlock): Boolean; + {$ENDIF} + end; + + TDisplayCoord = record + Column: Integer; + Row: Integer; + {$IFDEF SYN_COMPILER_10_UP} + class operator Equal(a, b: TDisplayCoord): Boolean; + {$ENDIF} + end; + +function DisplayCoord(AColumn, ARow: Integer): TDisplayCoord; +function BufferCoord(AChar, ALine: Integer): TBufferCoord; + +implementation + +function DisplayCoord(AColumn, ARow: Integer): TDisplayCoord; +begin + Result.Column := AColumn; + Result.Row := ARow; +end; + +function BufferCoord(AChar, ALine: Integer): TBufferCoord; +begin + Result.Char := AChar; + Result.Line := ALine; +end; + +{$IFDEF SYN_COMPILER_10_UP} + +{ TBufferCoord } + +class operator TBufferCoord.Equal(a, b: TBufferCoord): Boolean; +begin + Result := (a.Char = b.Char) and (a.Line = b.Line); +end; + +{ TBufferBlock } + +class operator TBufferBlock.Equal(a, b: TBufferBlock): Boolean; +begin + Result := (a.BeginLine = b.BeginLine) and (a.BeginChar = b.BeginChar) and + (a.EndLine = b.EndLine) and (a.EndChar = b.EndChar); +end; + +{ TDisplayCoord } + +class operator TDisplayCoord.Equal(a, b: TDisplayCoord): Boolean; +begin + Result := (a.Row = b.Row) and (a.Column = b.Column); +end; + +{$ENDIF} + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditWordWrap.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditWordWrap.pas new file mode 100644 index 000000000..577ae46c8 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynEditWordWrap.pas @@ -0,0 +1,637 @@ +{------------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is uRESTDWPrivSynEditWordWrap.pas by Flvio Etrusco, released 2003-12-11. +Unicode translation by Mal Hrz. +All Rights Reserved. + +Contributors to the uRESTDWPrivSynEdit and mwEdit projects are listed in the +Contributors.txt file. + +Alternatively, the contents of this file may be used under the terms of the +GNU General Public License Version 2 or later (the "GPL"), in which case +the provisions of the GPL are applicable instead of those above. +If you wish to allow use of your version of this file only under the terms +of the GPL and not to allow others to use your version of this file +under the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the GPL. +If you do not delete the provisions above, a recipient may use your version +of this file under either the MPL or the GPL. + +$Id: uRESTDWPrivSynEditWordWrap.pas,v 1.8.2.6 2008/09/14 16:24:59 maelh Exp $ + +You may retrieve the latest version of this file at the uRESTDWPrivSynEdit home page, +located at http://uRESTDWPrivSynEdit.SourceForge.net + +Known Issues: +-------------------------------------------------------------------------------} +//todo: Use a single implementation of ReWrapLines that takes starting line and number of lines to rewrap +//todo: Tweak code to try finding better wrapping points. Some support by the highlighters will be needed, probably. +//todo: Document the code +//todo: The length of the last Row of a Line could be calculated from the Line length instead of being stored. This would be only useful when most of the lines aren't wrapped. + +{$IFNDEF QSYNEDITWORDWRAP} +unit uRESTDWPrivSynEditWordWrap; +{$ENDIF} + +{$I uRESTDWPrivSynEdit.inc} + +interface + +uses + uRESTDWPrivSynEditTypes, + uRESTDWPrivSynEditTextBuffer, + uRESTDWPrivSynEdit, + SysUtils, + Classes; + +var + // Accumulate/hide whitespace at EOL (at end of wrapped rows, actually) + OldWhitespaceBehaviour: Boolean = False; + +const + MaxIndex = MaxInt div 16; + +type + TLineIndex = 0..MaxIndex; + TRowIndex = 0..MaxIndex; + TRowLength = Word; + + TRowIndexArray = array [TLineIndex] of TRowIndex; + PRowIndexArray = ^TRowIndexArray; + + TRowLengthArray = array [TRowIndex] of TRowLength; + PRowLengthArray = ^TRowLengthArray; + + {$IFNDEF SYN_COMPILER_4_UP} + TSysCharSet = set of Char; + {$ENDIF} + + // For clarity, I'll refer to buffer coordinates as 'Line' and + // 'Char' and to display (wrapped) coordinates as 'Row' and 'Column'. + + // FLineOffsets[n] is the index of the first row of the [n+1]th line. + // e.g. Starting row of first line (0) is 0. Starting row of second line (1) + // is FLineOffsets[0]. Clear? + + TSynWordWrapPlugin = class(TInterfacedObject, ISynEditBufferPlugin) + private + FLineOffsets: PRowIndexArray; + FRowLengths: PRowLengthArray; + FLineCapacity: Integer; + FRowCapacity: Integer; + FLineCount: Integer; + + FEditor: TCustomSynEdit; + FMinRowLength: TRowLength; + FMaxRowLength: TRowLength; + procedure GrowLines(aMinSize: Integer); + procedure MoveLines(aStart: TLineIndex; aMoveBy: Integer); + procedure GrowRows(aMinSize: Integer); + procedure MoveRows(aStart: TRowIndex; aMoveBy: Integer); + procedure SetEmpty; + protected + procedure WrapLines; + function ReWrapLine(aIndex: TLineIndex): Integer; + procedure TrimArrays; + property LineOffsets: PRowIndexArray read FLineOffsets; + property RowLengths: PRowLengthArray read FRowLengths; + property Editor: TCustomSynEdit read FEditor; + public + constructor Create(aOwner: TCustomSynEdit); + destructor Destroy; override; + property LineCount: Integer read FLineCount; + { ISynEditBufferPlugin } + function BufferToDisplayPos(const aPos: TBufferCoord): TDisplayCoord; + function DisplayToBufferPos(const aPos: TDisplayCoord): TBufferCoord; + function RowCount: Integer; + function GetRowLength(aRow: Integer): Integer; + function LinesInserted(aIndex: Integer; aCount: Integer): Integer; + function LinesDeleted(aIndex: Integer; aCount: Integer): Integer; + function LinesPutted(aIndex: Integer; aCount: Integer): Integer; + procedure Reset; + procedure DisplayChanged; + end; + +implementation + +uses + uRESTDWPrivSynUnicode, +{$IFDEF SYN_COMPILER_6_UP} + RTLConsts, +{$ELSE} + Consts, +{$ENDIF} +{$IFNDEF SYN_COMPILER_4_UP} + uRESTDWPrivSynEditMiscProcs, +{$ENDIF} + Math; + +{ TSynWordWrapPlugin } + +function TSynWordWrapPlugin.BufferToDisplayPos( + const aPos: TBufferCoord): TDisplayCoord; +var + vStartRow: Integer; // first row of the line + cRow: Integer; + vRowLen: Integer; +begin + Assert(aPos.Char > 0); + Assert(aPos.Line > 0); + if LineCount < aPos.Line then + begin + // beyond EOF + Result.Column := aPos.Char; + Result.Row := RowCount + (aPos.Line - LineCount); + Exit; + end; + if aPos.Line = 1 then + vStartRow := 0 + else + vStartRow := FLineOffsets[aPos.Line - 2]; + vRowLen := 0; + for cRow := vStartRow to FLineOffsets[aPos.Line - 1] - 1 do + begin + Inc(vRowLen, FRowLengths[cRow]); + if aPos.Char <= vRowLen then + begin + Result.Column := aPos.Char - vRowLen + FRowLengths[cRow]; + Result.Row := cRow + 1; + Exit; + end; + end; + // beyond EOL + Result.Column := aPos.Char - vRowLen + FRowLengths[FLineOffsets[aPos.Line - 1] - 1]; + Result.Row := FLineOffsets[aPos.Line - 1]; +end; + +constructor TSynWordWrapPlugin.Create(aOwner: TCustomSynEdit); +begin + inherited Create; // just to work as reminder in case I revert it to a TComponent... + if aOwner = nil then + raise Exception.Create( 'Owner of TSynWordWrapPlugin must be a TCustomSynEdit' ); + FEditor := aOwner; + Reset; +end; + +destructor TSynWordWrapPlugin.Destroy; +begin + inherited; + FreeMem(FLineOffsets); + FreeMem(FRowLengths); +end; + +procedure TSynWordWrapPlugin.DisplayChanged; +begin + if Editor.CharsInWindow <> FMaxRowLength then + Reset; +end; + +function TSynWordWrapPlugin.DisplayToBufferPos( + const aPos: TDisplayCoord): TBufferCoord; +var + cLine: Integer; + cRow: Integer; +begin + Assert(aPos.Column > 0); + Assert(aPos.Row > 0); + if aPos.Row > RowCount then + begin + // beyond EOF + Result.Char := aPos.Column; + Result.Line := aPos.Row - RowCount + LineCount; + Exit; + end; + //todo: use a binary search or something smarter + for cLine := LineCount - 2 downto 0 do + if aPos.Row > FLineOffsets[cLine] then + begin + Result.Line := cLine + 2; + if aPos.Row = FLineOffsets[cLine + 1] then //last row of line + Result.Char := Min(aPos.Column, FMaxRowLength + 1) + else + Result.Char := Min(aPos.Column, FRowLengths[aPos.Row - 1] + 1); + for cRow := FLineOffsets[cLine] to aPos.Row - 2 do + Inc(Result.Char, FRowLengths[cRow]); + Exit; + end; + // first line + Result.Line := 1; + if aPos.Row = FLineOffsets[0] then //last row of line + Result.Char := Min(aPos.Column, FMaxRowLength + 1) + else + Result.Char := Min(aPos.Column, FRowLengths[aPos.Row - 1] + 1); + for cRow := 0 to aPos.Row - 2 do + Inc(Result.Char, FRowLengths[cRow]); +end; + +function TSynWordWrapPlugin.GetRowLength(aRow: Integer): Integer; +// aRow is 1-based... +begin + if (aRow <= 0) or (aRow > RowCount) then + TList.Error(SListIndexError, aRow); + Result := FRowLengths[aRow - 1]; +end; + +procedure TSynWordWrapPlugin.GrowLines(aMinSize: Integer); +const + vStepSize = 256; +begin + Assert(aMinSize > 0); + if aMinSize > FLineCapacity then + begin + aMinSize := aMinSize + vStepSize - (aMinSize mod vStepSize); + ReallocMem(FLineOffsets, aMinSize * SizeOf(TRowIndex)); + FLineCapacity := aMinSize; + end; +end; + +procedure TSynWordWrapPlugin.GrowRows(aMinSize: Integer); +const + vStepSize = 512; +begin + Assert(aMinSize > 0); + if aMinSize > FRowCapacity then + begin + aMinSize := aMinSize + vStepSize - (aMinSize mod vStepSize); + ReallocMem(FRowLengths, aMinSize * SizeOf(TRowLength)); + FRowCapacity := aMinSize; + end; +end; + +function TSynWordWrapPlugin.LinesDeleted(aIndex: Integer; aCount: Integer): Integer; +var + vStartRow: Integer; + vEndRow: Integer; + cLine: Integer; +begin + if FMaxRowLength = 0 then + begin + Result := 0; + Exit; + end; + Assert(aIndex >= 0); + Assert(aCount >= 1); + Assert(aIndex + aCount <= LineCount); + + if aIndex = 0 then + vStartRow := 0 + else + vStartRow := FLineOffsets[aIndex - 1]; + vEndRow := FLineOffsets[aIndex + aCount - 1]; + Result := vEndRow - vStartRow; + // resize FRowLengths + if vEndRow < RowCount then + MoveRows(vEndRow, -Result); + // resize FLineOffsets + MoveLines(aIndex + aCount, -aCount); + Dec(FLineCount, aCount); + // update offsets + for cLine := aIndex to LineCount - 1 do + Dec(FLineOffsets[cLine], Result); +end; + +function TSynWordWrapPlugin.LinesInserted(aIndex: Integer; aCount: Integer): Integer; +var + vPrevOffset: TRowIndex; + cLine: Integer; +begin + if FMaxRowLength = 0 then + begin + Result := 0; + Exit; + end; + Assert(aIndex >= 0); + Assert(aCount >= 1); + Assert(aIndex <= LineCount); + // resize FLineOffsets + GrowLines(LineCount + aCount); + if aIndex < LineCount then // no need for MoveLines if inserting at LineCount (TSynEditStringList.Add) + begin + Inc(FLineCount, aCount); // FLineCount must be updated before calling MoveLines() + MoveLines(aIndex, aCount); + end + else + Inc(FLineCount, aCount); + // set offset to same as previous line (i.e. the line has 0 rows) + if aIndex = 0 then + vPrevOffset := 0 + else + vPrevOffset := FLineOffsets[aIndex - 1]; + for cLine := aIndex to aIndex + aCount - 1 do + FLineOffsets[cLine] := vPrevOffset; + // Rewrap + Result := 0; + for cLine := aIndex to aIndex + aCount - 1 do + Inc(Result, ReWrapLine(cLine)); +end; + +function TSynWordWrapPlugin.LinesPutted(aIndex: Integer; aCount: Integer): Integer; +var + cLine: Integer; +begin + if FMaxRowLength = 0 then + begin + Result := 0; + Exit; + end; + Assert(aIndex >= 0); + Assert(aCount >= 1); + Assert(aIndex + aCount <= LineCount); + // Rewrap + Result := 0; + for cLine := aIndex to aIndex + aCount - 1 do + Inc(Result, ReWrapLine(cLine)); +end; + +procedure TSynWordWrapPlugin.MoveLines(aStart: TLineIndex; aMoveBy: Integer); +var + vMoveCount: Integer; +begin + Assert(aMoveBy <> 0); + Assert(aStart + aMoveBy >= 0); + Assert(aStart + aMoveBy < LineCount); + vMoveCount := LineCount - aStart; + if aMoveBy > 0 then + Dec(vMoveCount, aMoveBy); + Move(FLineOffsets[aStart], FLineOffsets[aStart + aMoveBy], + vMoveCount * SizeOf(TRowIndex)); +end; + +procedure TSynWordWrapPlugin.MoveRows(aStart: TRowIndex; aMoveBy: Integer); +var + vMoveCount: Integer; +begin + Assert(aMoveBy <> 0); + Assert(aStart + aMoveBy >= 0); + Assert(aStart + aMoveBy < RowCount); + vMoveCount := RowCount - aStart; + if aMoveBy > 0 then + Dec(vMoveCount, aMoveBy); + Move(FRowLengths[aStart], FRowLengths[aStart + aMoveBy], + vMoveCount * SizeOf(TRowLength)); +end; + +procedure TSynWordWrapPlugin.Reset; +begin + Assert(Editor.CharsInWindow >= 0); + + FMaxRowLength := Min(Editor.MaxScrollWidth, Editor.CharsInWindow); // see github issue #129 + FMinRowLength := Editor.CharsInWindow - (Editor.CharsInWindow div 3); + + if FMinRowLength <= 0 then + FMinRowLength := 1; + + WrapLines; +end; + +function TSynWordWrapPlugin.ReWrapLine(aIndex: TLineIndex): Integer; +// Returns RowCount delta (how many wrapped lines were added or removed by this change). +var + vMaxNewRows: Cardinal; + vLine: UnicodeString; + vLineRowCount: Integer; //numbers of rows parsed in this line + vTempRowLengths: PRowLengthArray; + vRowBegin: PWideChar; + vLineEnd: PWideChar; + vRowEnd: PWideChar; + vRunner: PWideChar; + vRowMinEnd: PWideChar; + vLastVisibleChar: PWideChar; + + vStartRow: Integer; // first row of the line + vOldNextRow: Integer; // first row of the next line, before the change + cLine: Integer; + + p : PRowIndexArray; +begin + // ****** First parse the new string using an auxiliar array ***** + vLine := TSynEditStringList(Editor.Lines).ExpandedStrings[aIndex]; + vLine := Editor.ExpandAtWideGlyphs(vLine); + // Pre-allocate a buffer for rowlengths + vMaxNewRows := ((Length(vLine) - 1) div FMinRowLength) + 1; + vTempRowLengths := AllocMem(vMaxNewRows * SizeOf(TRowLength)); + try + vLineRowCount := 0; + vRowBegin := PWideChar(vLine); + vRowEnd := vRowBegin + FMaxRowLength; + vLineEnd := vRowBegin + Length(vLine); + while vRowEnd < vLineEnd do + begin + if OldWhitespaceBehaviour and CharInSet(vRowEnd^, [#32, #9]) then + begin + repeat + Inc(vRowEnd); + until not CharInSet(vRowEnd^, [#32, #9]); + end + else + begin + vRowMinEnd := vRowBegin + FMinRowLength; + vRunner := vRowEnd; + while vRunner > vRowMinEnd do + begin + if Editor.IsWordBreakChar(vRunner^) then + begin + vRowEnd := vRunner; + Break; + end; + Dec(vRunner); + end; + end; + // Check TRowLength overflow + if OldWhitespaceBehaviour and (vRowEnd - vRowBegin > High(TRowLength)) then + begin + vRowEnd := vRowBegin + High(TRowLength); + vRowMinEnd := vRowEnd - (High(TRowLength) mod Editor.TabWidth); + while (vRowEnd^ = #9) and (vRowEnd > vRowMinEnd) do + Dec(vRowEnd); + end; + + // do not cut wide glyphs in half + if vRowEnd > vRowBegin then + begin + vLastVisibleChar := vRowEnd - 1; + while (vLastVisibleChar^ = FillerChar) and (vLastVisibleChar > vRowBegin) do + Dec(vLastVisibleChar); + vRowEnd := vLastVisibleChar + 1; + end; + + // Finally store the rowlength + vTempRowLengths[vLineRowCount] := vRowEnd - vRowBegin; + + Inc(vLineRowCount); + vRowBegin := vRowEnd; + Inc(vRowEnd, FMaxRowLength); + end; //endwhile vRowEnd < vLineEnd + if (vLineEnd > vRowBegin) or (Length(vLine) = 0) then + begin + vTempRowLengths[vLineRowCount] := vLineEnd - vRowBegin; + Inc(vLineRowCount); + end; + + // ****** Then updates the main arrays ****** + if aIndex = 0 then + vStartRow := 0 + else + vStartRow := FLineOffsets[aIndex - 1]; + vOldNextRow := FLineOffsets[aIndex]; + Result := vLineRowCount - (vOldNextRow - vStartRow); + if Result <> 0 then + begin + // MoveRows depends on RowCount, so we need some special processing... + if Result > 0 then + begin + // ...if growing, update offsets (and thus RowCount) before rowlengths + GrowRows(RowCount + Result); + if Result = 1 then begin + // EG: this makes Schlemiel run twice as fast, but doesn't solve + // the algorithmic issue if someone can spend some time looking + // at the big picture... there are huge speedups to be made by + // eliminating this loop + p:=FLineOffsets; + for cLine := aIndex to LineCount - 1 do + Inc(p[cLine]) + end else begin + p:=FLineOffsets; + for cLine := aIndex to LineCount - 1 do + Inc(p[cLine], Result); + end; + if vOldNextRow < RowCount - Result then + MoveRows(vOldNextRow, Result); + end + else + begin + // ...if shrinking, update offsets after rowlengths + if vOldNextRow < RowCount then + MoveRows(vOldNextRow, Result); + for cLine := aIndex to LineCount - 1 do + Inc(FLineOffsets[cLine], Result); + end; + end; + Move(vTempRowLengths[0], FRowLengths[vStartRow], vLineRowCount * SizeOf(TRowLength)); + finally + FreeMem(vTempRowLengths); + end; +end; + +procedure TSynWordWrapPlugin.WrapLines; +var + cRow: Integer; + cLine: Integer; + vLine: UnicodeString; + vMaxNewRows: Integer; + vRowBegin: PWideChar; + vLineEnd: PWideChar; + vRowEnd: PWideChar; + vRunner: PWideChar; + vRowMinEnd: PWideChar; + vLastVisibleChar: PWideChar; +begin + if (Editor.Lines.Count = 0) or (FMaxRowLength <= 0) then + begin + SetEmpty; + Exit; + end; + + GrowLines(Editor.Lines.Count); + GrowRows(Editor.Lines.Count); + + cRow := 0; + for cLine := 0 to Editor.Lines.Count - 1 do + begin + vLine := TSynEditStringList(Editor.Lines).ExpandedStrings[cLine]; + vLine := Editor.ExpandAtWideGlyphs(vLine); + + vMaxNewRows := ((Length(vLine) - 1) div FMinRowLength) + 1; + GrowRows(cRow + vMaxNewRows); + + vRowBegin := PWideChar(vLine); + vRowEnd := vRowBegin + FMaxRowLength; + vLineEnd := vRowBegin + Length(vLine); + while vRowEnd < vLineEnd do + begin + if OldWhitespaceBehaviour and CharInSet(vRowEnd^, [#32, #9]) then + begin + repeat + Inc(vRowEnd); + until not CharInSet(vRowEnd^, [#32, #9]); + end + else + begin + vRowMinEnd := vRowBegin + FMinRowLength; + vRunner := vRowEnd; + while vRunner > vRowMinEnd do + begin + if Editor.IsWordBreakChar(vRunner^) then + begin + vRowEnd := vRunner; + Break; + end; + Dec(vRunner); + end; + end; + + if OldWhitespaceBehaviour and (vRowEnd - vRowBegin > High(TRowLength)) then + begin + vRowEnd := vRowBegin + High(TRowLength); + vRowMinEnd := vRowEnd - (High(TRowLength) mod Editor.TabWidth); + while (vRowEnd^ = #9) and (vRowEnd > vRowMinEnd) do + Dec(vRowEnd); + end; + + // do not cut wide glyphs in half + if vRowEnd > vRowBegin then + begin + vLastVisibleChar := vRowEnd - 1; + while (vLastVisibleChar^ = FillerChar) and (vLastVisibleChar > vRowBegin) do + Dec(vLastVisibleChar); + vRowEnd := vLastVisibleChar + 1; + end; + + FRowLengths[cRow] := vRowEnd - vRowBegin; + + Inc(cRow); + vRowBegin := vRowEnd; + Inc(vRowEnd, FMaxRowLength); + end; + if (vLineEnd > vRowBegin) or (Length(vLine) = 0) then + begin + FRowLengths[cRow] := vLineEnd - vRowBegin; + Inc(cRow); + end; + FLineOffsets[cLine] := cRow; + end; + FLineCount := Editor.Lines.Count; +end; + +function TSynWordWrapPlugin.RowCount: Integer; +begin + if LineCount > 0 then + Result := FLineOffsets[LineCount - 1] + else + Result := 0; +end; + +procedure TSynWordWrapPlugin.SetEmpty; +begin + FLineCount := 0; + // free unsused memory + TrimArrays; +end; + +procedure TSynWordWrapPlugin.TrimArrays; +begin + ReallocMem(FLineOffsets, LineCount * SizeOf(TRowIndex)); + FLineCapacity := LineCount; + ReallocMem(FRowLengths, RowCount * SizeOf(TRowLength)); + FRowCapacity := RowCount; +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterCss.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterCss.pas new file mode 100644 index 000000000..4b5a64544 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterCss.pas @@ -0,0 +1,1146 @@ +{------------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: SynHighlighterEnhCSS.pas, released 2001-10-28 +Initial modifications to this CSS Highlighter were made by Ashley Brown, +ashley@ashleybrown.co.uk. + +The Original Code is based on the uRESTDWPrivSynHighlighterHtml.pas, released 2000-04-10 - +this in turn was based on the hkHTMLSyn.pas file from the mwEdit component suite +by Martin Waldenburg and other developers, the Initial Author of this file is +Hideo Koiso. +Unicode translation by Mal Hrz. +All Rights Reserved. + +Contributors to the uRESTDWPrivSynEdit and mwEdit projects are listed in the +Contributors.txt file. + +Alternatively, the contents of this file may be used under the terms of the +GNU General Public License Version 2 or later (the "GPL"), in which case +the provisions of the GPL are applicable instead of those above. +If you wish to allow use of your version of this file only under the terms +of the GPL and not to allow others to use your version of this file +under the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the GPL. +If you do not delete the provisions above, a recipient may use your version +of this file under either the MPL or the GPL. + +You may retrieve the latest version of uRESTDWPrivSynEdit from the uRESTDWPrivSynEdit home page, +located at http://uRESTDWPrivSynEdit.SourceForge.net + +You may retrieve the latest version of this file from +http://www.ashleybrown.co.uk/uRESTDWPrivSynEdit/ + +Known Issues: +-------------------------------------------------------------------------------} +{ +@abstract(Provides an improved CSS highlighter for uRESTDWPrivSynEdit) +@author(Ashley Brown, based on HTML highlighter by Hideo Koiso and converted to uRESTDWPrivSynEdit by Michael Hieke) +@created(2001-10-28) +@lastmod(2003-05-11) +The SynHighlighterEnhCSS unit provides uRESTDWPrivSynEdit with an improved CSS highlighter. + +http://www.ashleybrown.co.uk/ +ashley@ashleybrown.co.uk +} + +unit uRESTDWPrivSynHighlighterCss; + +{$I uRESTDWPrivSynEdit.inc} + +interface + +uses + Graphics, + uRESTDWPrivSynEditTypes, + uRESTDWPrivSynEditHighlighter, + uRESTDWPrivSynHighlighterHashEntries, + uRESTDWPrivSynUnicode, + SysUtils, + Classes; + +type + TtkTokenKind = (tkComment, tkAtRule, tkProperty, tkSelector, tkSelectorAttrib, + tkNull, tkSpace, tkString, tkSymbol, tkText, tkUndefProperty, tkValue, + tkColor, tkNumber, tkImportant); + + TRangeState = (rsComment, rsSelector, rsDeclaration, rsUnknown, rsProperty, + rsValue, rsAttrib, rsParameter); + + TSynCssSyn = class(TSynCustomHighlighter) + private + FRange: TRangeState; + FCommentRange: TRangeState; + FParameterRange: TRangeState; + FTokenID: TtkTokenKind; + FCommentAttri: TSynHighlighterAttributes; + FPropertyAttri: TSynHighlighterAttributes; + FAttributeAttri: TSynHighlighterAttributes; + FSelectorAttri: TSynHighlighterAttributes; + FSpaceAttri: TSynHighlighterAttributes; + FStringAttri: TSynHighlighterAttributes; + FColorAttri: TSynHighlighterAttributes; + FNumberAttri: TSynHighlighterAttributes; + FSymbolAttri: TSynHighlighterAttributes; + FTextAttri: TSynHighlighterAttributes; + FValueAttri: TSynHighlighterAttributes; + FUndefPropertyAttri: TSynHighlighterAttributes; + FImportantPropertyAttri: TSynHighlighterAttributes; + FAtRuleAttri: TSynHighlighterAttributes; + FKeywords: TSynHashEntryList; + procedure DoAddKeyword(AKeyword: UnicodeString; AKind: Integer); + function HashKey(Str: PWideChar): Integer; + function IdentKind(MayBe: PWideChar): TtkTokenKind; + procedure AtRuleProc; + procedure SelectorProc; + procedure AttributeProc; + procedure CommentProc; + procedure BraceCloseProc; + procedure BraceOpenProc; + procedure ParenOpenProc; + procedure ParenCloseProc; + procedure BracketOpenProc; + procedure BracketCloseProc; + procedure CRProc; + procedure SemiProc; + procedure StartValProc; + procedure NumberProc; + procedure IdentProc; + procedure LFProc; + procedure NullProc; + procedure SpaceProc; + procedure StringProc; + procedure HashProc; + procedure SlashProc; + procedure GreaterProc; + procedure PlusProc; + procedure TildeProc; + procedure PipeProc; + procedure CircumflexProc; + procedure AttrContainProc; + procedure EqualProc; + procedure ExclamProc; + protected + function GetSampleSource: UnicodeString; override; + function IsFilterStored: Boolean; override; + procedure NextDeclaration; + public + class function GetLanguageName: string; override; + class function GetFriendlyLanguageName: UnicodeString; override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + function GetDefaultAttribute(Index: Integer): TSynHighlighterAttributes; override; + function GetEol: Boolean; override; + function GetRange: Pointer; override; + function GetTokenID: TtkTokenKind; + function GetTokenAttribute: TSynHighlighterAttributes; override; + function GetTokenKind: Integer; override; + function IsIdentChar(AChar: WideChar): Boolean; override; + procedure Next; override; + procedure SetRange(Value: Pointer); override; + procedure ResetRange; override; + published + property CommentAttri: TSynHighlighterAttributes read FCommentAttri + write FCommentAttri; + property PropertyAttri: TSynHighlighterAttributes read FPropertyAttri + write FPropertyAttri; + property ColorAttri: TSynHighlighterAttributes read FColorAttri + write FColorAttri; + property NumberAttri: TSynHighlighterAttributes read FNumberAttri + write FNumberAttri; + property AtRuleAttri: TSynHighlighterAttributes read FAtRuleAttri + write FAtRuleAttri; + property SelectorAttri: TSynHighlighterAttributes read FSelectorAttri + write FSelectorAttri; + property AttributeAttri: TSynHighlighterAttributes read FAttributeAttri + write FAttributeAttri; + property SpaceAttri: TSynHighlighterAttributes read FSpaceAttri + write FSpaceAttri; + property StringAttri: TSynHighlighterAttributes read FStringAttri + write FStringAttri; + property SymbolAttri: TSynHighlighterAttributes read FSymbolAttri + write FSymbolAttri; + property TextAttri: TSynHighlighterAttributes read FTextAttri + write FTextAttri; + property ValueAttri: TSynHighlighterAttributes read FValueAttri + write FValueAttri; + property UndefPropertyAttri: TSynHighlighterAttributes read FUndefPropertyAttri + write FUndefPropertyAttri; + property ImportantPropertyAttri: TSynHighlighterAttributes read FImportantPropertyAttri + write FImportantPropertyAttri; + end; + +implementation + +uses + uRESTDWPrivSynEditStrConst; + +const + Properties_CSS1 : UnicodeString = + 'background' + +',background-attachment' + +',background-color' + +',background-image' + +',background-position' + +',background-repeat' + +',border' + +',border-bottom' + +',border-bottom-color' + +',border-bottom-style' + +',border-bottom-width' + +',border-color' + +',border-left' + +',border-left-color' + +',border-left-style' + +',border-left-width' + +',border-right' + +',border-right-color' + +',border-right-style' + +',border-right-width' + +',border-style' + +',border-top' + +',border-top-color' + +',border-top-style' + +',border-top-width' + +',border-width' + +',clear' + +',color' + +',display' + +',float' + +',font' + +',font-family' + +',font-size' + +',font-style' + +',font-variant' + +',font-weight' + +',height' + +',letter-spacing' + +',line-height' + +',list-style' + +',list-style-image' + +',list-style-position' + +',list-style-type' + +',margin' + +',margin-bottom' + +',margin-left' + +',margin-right' + +',margin-top' + +',padding' + +',padding-bottom' + +',padding-left' + +',padding-right' + +',padding-top' + +',text-align' + +',text-decoration' + +',text-indent' + +',text-transform' + +',vertical-align' + +',white-space' + +',width' + +',word-spacing'; + Properties_CSS2 : UnicodeString = + 'border-collapse' + +',border-spacing' + +',bottom' + +',caption-side' + +',clip' + +',content' + +',counter-increment' + +',counter-reset' + +',cursor' + +',direction' + +',empty-cells' + +',left' + +',max-height' + +',max-width' + +',min-height' + +',min-width' + +',orphans' + +',outline' + +',outline-color' + +',outline-style' + +',outline-width' + +',overflow' + +',page-break-after' + +',page-break-before' + +',page-break-inside' + +',position' + +',quotes' + +',right' + +',table-layout' + +',top' + +',unicode-bidi' + +',visibility' + +',widows' + +',z-index'; + Properties_CSS2_Aural : UnicodeString = + 'azimuth' + +',cue' + +',cue-after' + +',cue-before' + +',elevation' + +',pause' + +',pause-after' + +',pause-before' + +',pitch' + +',pitch-range' + +',play-during' + +',richness' + +',speak' + +',speak-header' + +',speak-numeral' + +',speak-punctuation' + +',speech-rate' + +',stress' + +',voice-family' + +',volume'; + Properties_CSS3 : UnicodeString = + '@font-face' + +',@font-feature-values' + +',@keyframes' + +',align-content' + +',align-items' + +',align-self' + +',alignment-adjust' + +',alignment-baseline' + +',animation' + +',animation-delay' + +',animation-direction' + +',animation-duration' + +',animation-fill-mode' + +',animation-iteration-count' + +',animation-name' + +',animation-play-state' + +',animation-timing-function' + +',appearance' + +',backface-visibility' + +',background-clip' + +',background-origin' + +',background-size' + +',baseline-shift' + +',bookmark-label' + +',bookmark-level' + +',bookmark-target' + +',border-bottom-left-radius' + +',border-bottom-right-radius' + +',border-image' + +',border-image-outset' + +',border-image-repeat' + +',border-image-slice' + +',border-image-source' + +',border-image-width' + +',border-radius' + +',border-top-left-radius' + +',border-top-right-radius' + +',box-align' + +',box-decoration-break' + +',box-direction' + +',box-flex' + +',box-flex-group' + +',box-lines' + +',box-ordinal-group' + +',box-orient' + +',box-pack' + +',box-shadow' + +',box-sizing' + +',break-after' + +',break-before' + +',break-inside' + +',color-profile' + +',column-count' + +',column-fill' + +',column-gap' + +',column-rule' + +',column-rule-color' + +',column-rule-style' + +',column-rule-width' + +',columns' + +',column-span' + +',column-width' + +',crop' + +',dominant-baseline' + +',drop-initial-after-adjust' + +',drop-initial-after-align' + +',drop-initial-before-adjust' + +',drop-initial-before-align' + +',drop-initial-size' + +',drop-initial-value' + +',filter' + +',fit' + +',fit-position' + +',float-offset' + +',flex' + +',flex-basis' + +',flex-direction' + +',flex-flow' + +',flex-grow' + +',flex-shrink' + +',flex-wrap' + +',font-size-adjust' + +',font-feature-setting' + +',font-kerning' + +',font-language-override' + +',font-synthesis' + +',font-variant-alternates' + +',font-variant-caps' + +',font-variant-east-asian' + +',font-variant-ligatures' + +',font-variant-numeric' + +',font-variant-position' + +',font-stretch' + +',grid-columns' + +',grid-rows' + +',hanging-punctuation' + +',hyphenate-after' + +',hyphenate-before' + +',hyphenate-character' + +',hyphenate-lines' + +',hyphenate-resource' + +',hyphens' + +',icon' + +',image-orientation' + +',image-rendering' + +',image-resolution' + +',ime-mode' + +',justify-content' + +',inline-box-align' + +',line-break' + +',line-stacking' + +',line-stacking-ruby' + +',line-stacking-shift' + +',line-stacking-strategy' + +',mark' + +',mark-after' + +',mark-before' + +',marks' + +',marquee-direction' + +',marquee-play-count' + +',marquee-speed' + +',marquee-style' + +',mask' + +',mask-type' + +',move-to' + +',nav-down' + +',nav-index' + +',nav-left' + +',nav-right' + +',nav-up' + +',object-fit' + +',object-position' + +',opacity' + +',order' + +',outline-offset' + +',overflow-style' + +',overflow-x' + +',overflow-y' + +',overflow-wrap' + +',page' + +',page-policy' + +',perspective' + +',perspective-origin' + +',phonemes' + +',punctuation-trim' + +',rendering-intent' + +',resize' + +',rest' + +',rest-after' + +',rest-before' + +',rotation' + +',rotation-point' + +',ruby-align' + +',ruby-overhang' + +',ruby-position' + +',ruby-span' + +',size' + +',string-set' + +',tab-size' + +',target' + +',target-name' + +',target-new' + +',target-position' + +',text-align-last' + +',text-combine-horizontal' + +',text-decoration-color' + +',text-decoration-line' + +',text-decoration-style' + +',text-height' + +',text-justify' + +',text-orientation' + +',text-outline' + +',text-overflow' + +',text-shadow' + +',text-underline-position' + +',text-wrap' + +',transform' + +',transform-origin' + +',transform-style' + +',transition' + +',transition-delay' + +',transition-duration' + +',transition-property' + +',transition-timing-function' + +',voice-balance' + +',voice-duration' + +',voice-pitch' + +',voice-pitch-range' + +',voice-rate' + +',voice-stress' + +',voice-volume' + +',word-break' + +',word-wrap' + +',writing-mode'; + +{ TSynCssSyn } + +{$Q-} +function TSynCssSyn.HashKey(Str: PWideChar): Integer; +begin + Result := 0; + while CharInSet(Str^, ['a'..'z', 'A'..'Z', '_', '-']) do + begin + if Str^ <> '-' then + case Str^ of + '_': Inc(Result, 27); + '-': Inc(Result, 28); + else Inc(Result, Ord(SynWideUpperCase(Str^)[1]) - 64); + end; + Inc(Str); + end; + while CharInSet(Str^, ['0'..'9']) do + begin + Inc(Result, Ord(Str^) - Ord('0')); + Inc(Str); + end; + FStringLen := Str - FToIdent; +end; +{$Q+} + +function TSynCssSyn.IdentKind(MayBe: PWideChar): TtkTokenKind; +var + Entry: TSynHashEntry; +begin + FToIdent := MayBe; + Entry := FKeywords[HashKey(MayBe)]; + while Assigned(Entry) do + begin + if Entry.KeywordLen > FStringLen then + Break + else if Entry.KeywordLen = FStringLen then + if IsCurrentToken(Entry.Keyword) then + begin + Result := TtkTokenKind(Entry.Kind); + Exit; + end; + Entry := Entry.Next; + end; + Result := tkUndefProperty; +end; + +procedure TSynCssSyn.DoAddKeyword(AKeyword: UnicodeString; AKind: Integer); +var + HashValue: Integer; +begin + HashValue := HashKey(PWideChar(AKeyword)); + FKeywords[HashValue] := TSynHashEntry.Create(AKeyword, AKind); +end; + +constructor TSynCssSyn.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + + FCaseSensitive := False; + + FKeywords := TSynHashEntryList.Create; + FCommentAttri := TSynHighlighterAttributes.Create(SYNS_AttrComment, SYNS_FriendlyAttrComment); + AddAttribute(FCommentAttri); + + FPropertyAttri := TSynHighlighterAttributes.Create(SYNS_AttrProperty, SYNS_FriendlyAttrProperty); + FPropertyAttri.Style := [fsBold]; + AddAttribute(FPropertyAttri); + + FSelectorAttri := TSynHighlighterAttributes.Create(SYNS_AttrReservedWord, SYNS_FriendlyAttrReservedWord); + FSelectorAttri.Style := [fsBold]; + FSelectorAttri.Foreground := $00ff0080; + AddAttribute(FSelectorAttri); + + FAttributeAttri := TSynHighlighterAttributes.Create(SYNS_AttrAttribute, SYNS_FriendlyAttrAttribute); + FAttributeAttri.Style := []; + FAttributeAttri.Foreground := $00ff0080; + AddAttribute(FAttributeAttri); + + FAtRuleAttri := TSynHighlighterAttributes.Create(SYNS_AttrAtRules, SYNS_FriendlyAttrAttribute); + FAtRuleAttri.Style := []; + FAtRuleAttri.Foreground := $00808000; + AddAttribute(FAtRuleAttri); + + FUndefPropertyAttri := TSynHighlighterAttributes.Create( + SYNS_AttrUndefinedProperty, SYNS_FriendlyAttrUndefinedProperty); + FUndefPropertyAttri.Style := [fsBold]; + FUndefPropertyAttri.Foreground := $00ff0080; + AddAttribute(FUndefPropertyAttri); + + FImportantPropertyAttri := TSynHighlighterAttributes.Create( + 'Important', 'Important Marker'); + FImportantPropertyAttri.Style := [fsBold]; + FImportantPropertyAttri.Foreground := clRed; + AddAttribute(FImportantPropertyAttri); + + FSpaceAttri := TSynHighlighterAttributes.Create(SYNS_AttrSpace, SYNS_FriendlyAttrSpace); + AddAttribute(FSpaceAttri); + + FColorAttri := TSynHighlighterAttributes.Create(SYNS_AttrColor, SYNS_FriendlyAttrColor); + AddAttribute(FColorAttri); + + FNumberAttri := TSynHighlighterAttributes.Create(SYNS_AttrNumber, SYNS_FriendlyAttrNumber); + AddAttribute(FNumberAttri); + + FStringAttri := TSynHighlighterAttributes.Create(SYNS_AttrString, SYNS_FriendlyAttrString); + AddAttribute(FStringAttri); + + FSymbolAttri := TSynHighlighterAttributes.Create(SYNS_AttrSymbol, SYNS_FriendlyAttrSymbol); + AddAttribute(FSymbolAttri); + + FTextAttri := TSynHighlighterAttributes.Create(SYNS_AttrText, SYNS_FriendlyAttrText); + AddAttribute(FTextAttri); + + FValueAttri := TSynHighlighterAttributes.Create(SYNS_AttrValue, SYNS_FriendlyAttrValue); + FValueAttri.Foreground := $00ff8000; + AddAttribute(FValueAttri); + + SetAttributesOnChange(DefHighlightChange); + + // TODO: differentiating tkProperty for CSS1, CSS2 & CSS3 highlighting + EnumerateKeywords(Ord(tkProperty), Properties_CSS1, IsIdentChar, DoAddKeyword); + EnumerateKeywords(Ord(tkProperty), Properties_CSS2, IsIdentChar, DoAddKeyword); + EnumerateKeywords(Ord(tkProperty), Properties_CSS2_Aural, IsIdentChar, DoAddKeyword); + EnumerateKeywords(Ord(tkProperty), Properties_CSS3, IsIdentChar, DoAddKeyword); + + FRange := rsSelector; + FDefaultFilter := SYNS_FilterCSS; +end; + +destructor TSynCssSyn.Destroy; +begin + FKeywords.Free; + inherited Destroy; +end; + +procedure TSynCssSyn.AttributeProc; + + function IsStopChar: Boolean; + begin + case FLine[Run] of + #0..#31, ']', '~', '^', '$', '*', '|', '=': + Result := True; + else + Result := False; + end; + end; + +begin + if IsStopChar then + begin + case FLine[Run] of + #0..#31, '{', '/': NextDeclaration; + ']': BracketCloseProc; + '~': TildeProc; + '|': PipeProc; + '=': EqualProc; + '^': CircumflexProc; + '*': AttrContainProc; + end; + Exit; + end; + + FTokenID := tkSelectorAttrib; + while not IsStopChar do + Inc(Run); +end; + +procedure TSynCssSyn.BraceCloseProc; +begin + FRange := rsSelector; + FTokenID := tkSymbol; + Inc(Run); +end; + +procedure TSynCssSyn.BraceOpenProc; +begin + Inc(Run); + FRange := rsDeclaration; + FTokenID := tkSymbol; +end; + +procedure TSynCssSyn.BracketCloseProc; +begin + FTokenID := tkSymbol; + FRange := rsSelector; + Inc(Run); +end; + +procedure TSynCssSyn.BracketOpenProc; +begin + Inc(Run); + FRange := rsAttrib; + FTokenID := tkSymbol; +end; + +procedure TSynCssSyn.CircumflexProc; +begin + Inc(Run); + if FLine[Run] = '=' then + begin + Inc(Run); + FTokenID := tkSymbol; + end; +end; + +procedure TSynCssSyn.AttrContainProc; +begin + Inc(Run); + if FLine[Run] = '=' then + begin + Inc(Run); + FTokenID := tkSymbol; + end; +end; + +procedure TSynCssSyn.CommentProc; +begin + if FLine[Run] = #0 then + NullProc + else + begin + FTokenID := tkComment; + repeat + if (FLine[Run] = '*') and (FLine[Run + 1] = '/') then + begin + FRange := FCommentRange; + Inc(Run, 2); + Break; + end; + Inc(Run); + until IsLineEnd(Run) + end; +end; + +procedure TSynCssSyn.CRProc; +begin + FTokenID := tkSpace; + Inc(Run); + if FLine[Run] = #10 then Inc(Run); +end; + +procedure TSynCssSyn.SemiProc; +begin + FRange := rsUnknown; + FTokenID := tkSymbol; + Inc(Run); +end; + +procedure TSynCssSyn.StartValProc; +begin + FRange := rsValue; + FTokenID := tkSymbol; + Inc(Run); +end; + +procedure TSynCssSyn.NumberProc; +begin + if (FLine[Run] = '-') and not CharInSet(FLine[Run + 1], ['0'..'9']) then + IdentProc + else + begin + Inc(Run); + FTokenID := tkNumber; + while CharInSet(FLine[Run], ['0'..'9', '.']) do + begin + case FLine[Run] of + '.': + if FLine[Run + 1] = '.' then Break; + end; + Inc(Run); + end; + end; +end; + +procedure TSynCssSyn.ParenCloseProc; +begin + FRange := FParameterRange; + FTokenID := tkSymbol; + Inc(Run); +end; + +procedure TSynCssSyn.ParenOpenProc; +begin + Inc(Run); + FParameterRange := FRange; + FRange := rsParameter; + FTokenID := tkSymbol; +end; + +procedure TSynCssSyn.PipeProc; +begin + Inc(Run); + if FLine[Run] = '=' then + begin + Inc(Run); + FTokenID := tkSymbol; + end; +end; + +procedure TSynCssSyn.PlusProc; +begin + Inc(Run); + FTokenID := tkSymbol; +end; + +procedure TSynCssSyn.IdentProc; +begin + case FRange of + rsProperty: + begin + FRange := rsDeclaration; + FTokenID := tkSelector; + Inc(Run, FStringLen); + end; + rsValue, rsParameter: + begin + FTokenID := tkValue; + + while not IsLineEnd(Run) and + not CharInSet(FLine[Run], ['(', ')', '}', ';', ',', ' ']) do + begin + Inc(Run); + end; + + if IsLineEnd(Run) or CharInSet(FLine[Run], ['}', ';']) then + FRange := rsDeclaration; + end; + else + FTokenID := IdentKind((FLine + Run)); + repeat + Inc(Run); + until (FLine[Run] <= #32) or CharInSet(FLine[Run], [':', '"', '}', ';']); + end; +end; + +procedure TSynCssSyn.LFProc; +begin + FTokenID := tkSpace; + Inc(Run); +end; + +procedure TSynCssSyn.NullProc; +begin + FTokenID := tkNull; + Inc(Run); +end; + +procedure TSynCssSyn.AtRuleProc; + + function IsStopChar: Boolean; + begin + case FLine[Run] of + #0..#31, '{', ';': + Result := True; + else + Result := False; + end; + end; + +begin + if IsStopChar then + begin + case FLine[Run] of + #0..#31, '{', ';': SelectorProc; + end; + Exit; + end; + + FTokenID := tkAtRule; + while not IsStopChar do + Inc(Run); +end; + +procedure TSynCssSyn.SelectorProc; + + function IsStopChar: Boolean; + begin + case FLine[Run] of + #0..#31, '{', '/', '[', ']', '>', '+', '~': + Result := True; + else + Result := False; + end; + end; + +begin + if FLine[Run] = '}' then + begin + Inc(Run); + FTokenID := tkSymbol; + Exit; + end; + + if FLine[Run] = '@' then + begin + Inc(Run); + AtRuleProc; + Exit; + end; + + if IsStopChar then + begin + case FLine[Run] of + #0..#31, '{', '/': NextDeclaration; + '[': BracketOpenProc; + ']': BracketCloseProc; + '>': GreaterProc; + '+': PlusProc; + '~': TildeProc; + end; + Exit; + end; + + FTokenID := tkSelector; + while not IsStopChar do + Inc(Run); +end; + +procedure TSynCssSyn.TildeProc; +begin + Inc(Run); + if FLine[Run] = '=' then + begin + Inc(Run); + FTokenID := tkSymbol; + end; +end; + +procedure TSynCssSyn.SpaceProc; +begin + Inc(Run); + FTokenID := tkSpace; + while (FLine[Run] <= #32) and not IsLineEnd(Run) do Inc(Run); +end; + +procedure TSynCssSyn.StringProc; +begin + FTokenID := tkString; + Inc(Run); // first '"' + while not (IsLineEnd(Run) or (FLine[Run] = '"')) do Inc(Run); + if FLine[Run] = '"' then Inc(Run); // last '"' +end; + +procedure TSynCssSyn.HashProc; + + function IsHexChar: Boolean; + begin + case FLine[Run] of + '0'..'9', 'A'..'F', 'a'..'f': + Result := True; + else + Result := False; + end; + end; + +begin + FTokenID := tkColor; + Inc(Run); // '#' + while IsHexChar do Inc(Run); +end; + +procedure TSynCssSyn.EqualProc; +begin + Inc(Run); + FTokenID := tkSymbol; +end; + +procedure TSynCssSyn.ExclamProc; +begin + if (FLine[Run + 1] = 'i') and + (FLine[Run + 2] = 'm') and + (FLine[Run + 3] = 'p') and + (FLine[Run + 4] = 'o') and + (FLine[Run + 5] = 'r') and + (FLine[Run + 6] = 't') and + (FLine[Run + 7] = 'a') and + (FLine[Run + 8] = 'n') and + (FLine[Run + 9] = 't') then + begin + FTokenID := tkImportant; + Inc(Run, 10); + end + else + IdentProc; +end; + +procedure TSynCssSyn.SlashProc; +begin + Inc(Run); + if FLine[Run] = '*' then + begin + FTokenID := tkComment; + FCommentRange := FRange; + FRange := rsComment; + Inc(Run); + if not IsLineEnd(Run) then + CommentProc; + end + else + FTokenID := tkSymbol; +end; + +procedure TSynCssSyn.Next; +begin + FTokenPos := Run; + case FRange of + rsSelector: + SelectorProc; + rsAttrib: + AttributeProc; + rsComment: + CommentProc; + else + NextDeclaration; + end; + + inherited; +end; + +procedure TSynCssSyn.NextDeclaration; +begin + case FLine[Run] of + #0: NullProc; + #10: LFProc; + #13: CRProc; + #1..#9, #11, #12, #14..#32: SpaceProc; + '"': StringProc; + '#': HashProc; + '{': BraceOpenProc; + '}': BraceCloseProc; + '(': ParenOpenProc; + ')': ParenCloseProc; + ':', ',': StartValProc; + ';': SemiProc; + '0'..'9', '-', '.': NumberProc; + '/': SlashProc; + '!': ExclamProc; + else IdentProc; + end; +end; + +function TSynCssSyn.GetDefaultAttribute(Index: Integer): TSynHighlighterAttributes; +begin + case Index of + SYN_ATTR_COMMENT: Result := FCommentAttri; + SYN_ATTR_KEYWORD: Result := FSelectorAttri; + SYN_ATTR_WHITESPACE: Result := FSpaceAttri; + SYN_ATTR_STRING: Result := FStringAttri; + else Result := nil; + end; +end; + +function TSynCssSyn.GetEol: Boolean; +begin + Result := Run = FLineLen + 1; +end; + +function TSynCssSyn.GetTokenID: TtkTokenKind; +begin + Result := FTokenID; +end; + +function TSynCssSyn.GetTokenAttribute: TSynHighlighterAttributes; +begin + case FTokenID of + tkComment: Result := FCommentAttri; + tkAtRule: Result := FAtRuleAttri; + tkProperty: Result := FPropertyAttri; + tkSelector: Result := FSelectorAttri; + tkSelectorAttrib: Result := FAttributeAttri; + tkSpace: Result := FSpaceAttri; + tkString: Result := FStringAttri; + tkSymbol: Result := FSymbolAttri; + tkText: Result := FTextAttri; + tkUndefProperty: Result := FUndefPropertyAttri; + tkImportant: Result := FImportantPropertyAttri; + tkValue: Result := FValueAttri; + tkColor: Result := FColorAttri; + tkNumber: Result := FNumberAttri; + else Result := nil; + end; +end; + +function TSynCssSyn.GetTokenKind: Integer; +begin + Result := Ord(FTokenID); +end; + +procedure TSynCssSyn.GreaterProc; +begin + Inc(Run); + FTokenID := tkSymbol; +end; + +function TSynCssSyn.GetRange: Pointer; +begin + Result := Pointer(FRange); +end; + +procedure TSynCssSyn.SetRange(Value: Pointer); +begin + FRange := TRangeState(Value); +end; + +procedure TSynCssSyn.ResetRange; +begin + FRange:= rsSelector; +end; + +function TSynCssSyn.GetSampleSource: UnicodeString; +begin + Result := '/* Syntax Highlighting */'#13#10 + + 'body { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 8pt }'#13#10 + + 'H1 { font-size: 18pt; color: #000099; made-up-property: 1 }'; +end; { GetSampleSource } + +class function TSynCssSyn.GetLanguageName: string; +begin + Result := SYNS_LangCSS; +end; + +function TSynCssSyn.IsFilterStored: boolean; +begin + Result := FDefaultFilter <> SYNS_FilterCSS; +end; + +function TSynCssSyn.IsIdentChar(AChar: WideChar): Boolean; +begin + case AChar of + '_', '-', '0'..'9', 'A'..'Z', 'a'..'z': + Result := True; + else + Result := False; + end; +end; + +class function TSynCssSyn.GetFriendlyLanguageName: UnicodeString; +begin + Result := SYNS_FriendlyLangCSS; +end; + +initialization +{$IFNDEF SYN_CPPB_1} + RegisterPlaceableHighlighter(TSynCssSyn); +{$ENDIF} +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterHashEntries.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterHashEntries.pas new file mode 100644 index 000000000..62f8b9510 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterHashEntries.pas @@ -0,0 +1,251 @@ +{------------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: uRESTDWPrivSynHighlighterHashEntries.pas, released 2000-04-21. + +The Initial Author of this file is Michael Hieke. +Portions created by Michael Hieke are Copyright 2000 Michael Hieke. +Unicode translation by Mal Hrz. +All Rights Reserved. + +Contributors to the uRESTDWPrivSynEdit project are listed in the Contributors.txt file. + +Alternatively, the contents of this file may be used under the terms of the +GNU General Public License Version 2 or later (the "GPL"), in which case +the provisions of the GPL are applicable instead of those above. +If you wish to allow use of your version of this file only under the terms +of the GPL and not to allow others to use your version of this file +under the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the GPL. +If you do not delete the provisions above, a recipient may use your version +of this file under either the MPL or the GPL. + +$Id: uRESTDWPrivSynHighlighterHashEntries.pas,v 1.5.2.3 2008/09/14 16:25:00 maelh Exp $ + +You may retrieve the latest version of this file at the uRESTDWPrivSynEdit home page, +located at http://uRESTDWPrivSynEdit.SourceForge.net + +Known Issues: +-------------------------------------------------------------------------------} + +{ +@abstract(Support classes for uRESTDWPrivSynEdit highlighters that create the keyword lists at runtime.) +@author(Michael Hieke) +@created(2000-04-21) +@lastmod(2001-09-07) +The classes in this unit can be used to use the hashing algorithm while still +having the ability to change the set of keywords. +} + +unit uRESTDWPrivSynHighlighterHashEntries; + +{$I uRESTDWPrivSynEdit.inc} + +interface + +uses + uRESTDWPrivSynEditTypes, + uRESTDWPrivSynUnicode, + Classes; + +type + { Class to hold the keyword to recognize, its length and its token kind. The + keywords that have the same hashvalue are stored in a single-linked list, + with the Next property pointing to the next entry. The entries are ordered + over the keyword length. } + TSynHashEntry = class(TObject) + protected + { Points to the next keyword entry with the same hashvalue. } + FNext: TSynHashEntry; + { Length of the keyword. } + FKeyLen: Integer; + { The keyword itself. } + FKeyword: UnicodeString; + { Keyword token kind, has to be typecasted to the real token kind type. } + fKind: Integer; + public + { Adds a keyword entry with the same hashvalue. Depending on the length of + the two keywords it might return Self and store NewEntry in the Next + pointer, or return NewEntry and make the Next property of NewEntry point + to Self. This way the order of keyword length is preserved. } + function AddEntry(NewEntry: TSynHashEntry): TSynHashEntry; virtual; + { Creates a keyword entry for the given keyword and token kind. } + constructor Create(const AKey: UnicodeString; AKind: Integer); + { Destroys the keyword entry and all other keyword entries Next points to. } + destructor Destroy; override; + public + { The keyword itself. } + property Keyword: UnicodeString read FKeyword; + { Length of the keyword. } + property KeywordLen: Integer read FKeyLen; + { Keyword token kind, has to be typecasted to the real token kind type. } + property Kind: Integer read fKind; + { Points to the next keyword entry with the same hashvalue. } + property Next: TSynHashEntry read FNext; + end; + + +{$IFNDEF SYN_COMPILER_4_UP} + {$IFNDEF SYN_CPPB_3} + {$DEFINE LIST_CLEAR_NOT_VIRTUAL} + {$ENDIF} +{$ENDIF} + + { A list of keyword entries, stored as single-linked lists under the hashvalue + of the keyword. } + TSynHashEntryList = class(TList) + protected + { Returns the first keyword entry for a given hashcalue, or nil. } + function Get(HashKey: Integer): TSynHashEntry; + { Adds a keyword entry under its hashvalue. Will grow the list count when + necessary, so the maximum hashvalue should be limited outside. The correct + order of keyword entries is maintained. } + procedure Put(HashKey: Integer; Entry: TSynHashEntry); + public +{$IFDEF LIST_CLEAR_NOT_VIRTUAL} + { Overridden destructor clears the list and frees all contained keyword + entries. } + destructor Destroy; override; + { Clears the list and frees all contained keyword entries. } + procedure DeleteEntries; +{$ELSE} + { Clears the list and frees all contained keyword entries. } + procedure Clear; override; +{$ENDIF} + public + { Type-safe access to the first keyword entry for a hashvalue. } + property Items[Index: Integer]: TSynHashEntry read Get write Put; default; + end; + + { Procedural type for adding keyword entries to a TSynHashEntryList when + iterating over all the keywords contained in a string. } + TEnumerateKeywordEvent = procedure(AKeyword: UnicodeString; AKind: Integer) + of object; + +{ This procedure will call AKeywordProc for all keywords in KeywordList. A + keyword is considered any number of successive chars that are contained in + Identifiers, with chars not contained in Identifiers before and after them. } +procedure EnumerateKeywords(AKind: Integer; KeywordList: UnicodeString; + IsIdentChar: TCategoryMethod; AKeywordProc: TEnumerateKeywordEvent); + +implementation + +uses + SysUtils; + +procedure EnumerateKeywords(AKind: Integer; KeywordList: UnicodeString; + IsIdentChar: TCategoryMethod; AKeywordProc: TEnumerateKeywordEvent); +var + pStart, pEnd: PWideChar; + Keyword: UnicodeString; +begin + if Assigned(AKeywordProc) and (KeywordList <> '') then + begin + pEnd := PWideChar(KeywordList); + pStart := pEnd; + repeat + // skip over chars that are not in Identifiers + while (pStart^ <> #0) and not IsIdentChar(pStart^) do + Inc(pStart); + if pStart^ = #0 then + Break; + // find the last char that is in Identifiers + pEnd := pStart + 1; + while (pEnd^ <> #0) and IsIdentChar(pEnd^) do + Inc(pEnd); + // call the AKeywordProc with the keyword + SetString(Keyword, pStart, pEnd - pStart); + AKeywordProc(Keyword, AKind); + Keyword := ''; + // pEnd points to a char not in Identifiers, restart after that + pStart := pEnd + 1; + until (pStart^ = #0) or (pEnd^ = #0); + end; +end; + +{ TSynHashEntry } + +constructor TSynHashEntry.Create(const AKey: UnicodeString; AKind: Integer); +begin + inherited Create; + FKeyLen := Length(AKey); + FKeyword := AKey; + fKind := AKind; +end; + +destructor TSynHashEntry.Destroy; +begin + FNext.Free; + inherited Destroy; +end; + +function TSynHashEntry.AddEntry(NewEntry: TSynHashEntry): TSynHashEntry; +begin + Result := Self; + if Assigned(NewEntry) then + begin + if WideCompareText(NewEntry.Keyword, FKeyword) = 0 then + raise Exception.CreateFmt('Keyword "%s" already in list', [FKeyword]); + if NewEntry.FKeyLen < FKeyLen then + begin + NewEntry.FNext := Self; + Result := NewEntry; + end else if Assigned(FNext) then + FNext := FNext.AddEntry(NewEntry) + else + FNext := NewEntry; + end; +end; + +{ TSynHashEntryList } + +{$IFDEF LIST_CLEAR_NOT_VIRTUAL} +destructor TSynHashEntryList.Destroy; +begin + DeleteEntries; + inherited Destroy; +end; + +procedure TSynHashEntryList.DeleteEntries; +{$ELSE} +procedure TSynHashEntryList.Clear; +{$ENDIF} +var + i: Integer; +begin + for i := 0 to Count - 1 do + TSynHashEntry(Items[i]).Free; + inherited Clear; +end; + +function TSynHashEntryList.Get(HashKey: Integer): TSynHashEntry; +begin + if (HashKey >= 0) and (HashKey < Count) then + Result := inherited Items[HashKey] + else + Result := nil; +end; + +procedure TSynHashEntryList.Put(HashKey: Integer; Entry: TSynHashEntry); +var + ListEntry: TSynHashEntry; +begin + if HashKey >= Count then + Count := HashKey + 1; + ListEntry := TSynHashEntry(inherited Items[HashKey]); + // if there is already a hashentry for this hashvalue let it decide + // where to put the new entry in its single linked list + if Assigned(ListEntry) then + Entry := ListEntry.AddEntry(Entry); + inherited Items[HashKey] := Entry; +end; + +end. + diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterHtml.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterHtml.pas new file mode 100644 index 000000000..b9f643f4f --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterHtml.pas @@ -0,0 +1,1225 @@ +{------------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: uRESTDWPrivSynHighlighterHtml.pas, released 2000-04-10. +The Original Code is based on the hkHTMLSyn.pas file from the +mwEdit component suite by Martin Waldenburg and other developers, the Initial +Author of this file is Hideo Koiso. +Unicode translation by Mal Hrz. +HTML5 tags added by CodehunterWorks +All Rights Reserved. + +Contributors to the uRESTDWPrivSynEdit and mwEdit projects are listed in the +Contributors.txt file. + +Alternatively, the contents of this file may be used under the terms of the +GNU General Public License Version 2 or later (the "GPL"), in which case +the provisions of the GPL are applicable instead of those above. +If you wish to allow use of your version of this file only under the terms +of the GPL and not to allow others to use your version of this file +under the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the GPL. +If you do not delete the provisions above, a recipient may use your version +of this file under either the MPL or the GPL. + +$Id: uRESTDWPrivSynHighlighterHtml.pas,v 1.24.3 2012/09/13 12:05:00 codehunterworks Exp $ + +You may retrieve the latest version of this file at the uRESTDWPrivSynEdit home page, +located at http://uRESTDWPrivSynEdit.SourceForge.net + +Known Issues: +-------------------------------------------------------------------------------} +{ +@abstract(Provides an HTML highlighter for uRESTDWPrivSynEdit) +@author(Hideo Koiso, converted to uRESTDWPrivSynEdit by Michael Hieke) +@created(1999-11-02, converted to uRESTDWPrivSynEdit 2000-04-10) +@lastmod(2012-09-13) +The uRESTDWPrivSynHighlighterHtml unit provides uRESTDWPrivSynEdit with an HTML highlighter. +} + +unit uRESTDWPrivSynHighlighterHtml; + +interface + +{$I uRESTDWPrivSynEdit.inc} + +uses +{$IFDEF UNICODE} + WideStrUtils, +{$ENDIF} + Graphics, + uRESTDWPrivSynEditTypes, + uRESTDWPrivSynEditHighlighter, + uRESTDWPrivSynUnicode, + SysUtils, + Classes; + +const + MAX_ESCAPEAMPS = 249; + + EscapeAmps: array[0..MAX_ESCAPEAMPS - 1] of PWideChar = ( + ('Α'), { ? } { greek capital alpha } + ('Β'), { ? } { greek capital beta } + ('Γ'), { G } { greek capital gamma } + ('Δ'), { ? } { greek capital delta } + ('Ε'), { ? } { greek capital epsilon } + ('Ζ'), { ? } { greek capital zeta } + ('Η'), { ? } { greek capital eta } + ('Θ'), { T } { greek capital theta } + ('Ι'), { ? } { greek capital iota } + ('Κ'), { ? } { greek capital kappa } + ('Λ'), { ? } { greek capital lambda } + ('Μ'), { ? } { greek capital mu } + ('Ν'), { ? } { greek capital nu } + ('Ξ'), { ? } { greek capital xi } + ('Ο'), { ? } { greek capital omicron } + ('Π'), { ? } { greek capital pi } + ('Ρ'), { ? } { greek capital rho } + ('Σ'), { S } { greek capital sigma } + ('Τ'), { ? } { greek capital tau } + ('Υ'), { ? } { greek capital upsilon } + ('Φ'), { F } { greek capital phi } + ('Χ'), { ? } { greek capital chi } + ('Ψ'), { ? } { greek capital psi } + ('Ω'), { O } { greek capital omega } + ('α'), { a } { greek small alpha } + ('β'), { } { greek small beta } + ('γ'), { ? } { greek small gamma } + ('δ'), { d } { greek small delta } + ('ε'), { e } { greek small epsilon } + ('ζ'), { ? } { greek small zeta } + ('η'), { ? } { greek small eta } + ('θ'), { ? } { greek small theta } + ('ι'), { ? } { greek small iota } + ('κ'), { ? } { greek small kappa } + ('λ'), { ? } { greek small lambda } + ('μ'), { } { greek small mu } + ('ν'), { ? } { greek small nu } + ('ξ'), { ? } { greek small xi } + ('ο'), { ? } { greek small omicron } + ('π'), { p } { greek small pi } + ('ρ'), { ? } { greek small rho } + ('ς'), { ? } { greek small final sigma } + ('σ'), { s } { greek small sigma } + ('τ'), { t } { greek small tau } + ('υ'), { ? } { greek small upsilon } + ('φ'), { f } { greek small phi } + ('χ'), { ? } { greek small chi } + ('ψ'), { ? } { greek small psi } + ('ω'), { ? } { greek small omega } + ('ϑ'), { ? } { greek small theta symbol } + ('ϒ'), { ? } { greek upsilon with hook symbol } + ('ϖ'), { ? } { greek pi symbol } + ('•'), { } { bullet } + ('…'), { } { horizontal ellipsis } + ('′'), { ' } { prime } + ('″'), { " } { double prime } + ('‾'), { ? } { overline, = spacing overscore } + ('⁄'), { / } { fraction slash } + ('℘'), { P } { script capital P } + ('ℑ'), { I } { imaginary part } + ('ℜ'), { R } { real part } + ('™'), { } { trademark sign } + ('ℵ'), { ? } { first transfinite cardinal } + ('←'), { ? } { leftwards arrow } + ('↑'), { ? } { upwards arrow } + ('→'), { ? } { rightwards arrow } + ('↓'), { ? } { downwards arrow } + ('↔'), { ? } { left right arrow } + ('↵'), { ? } { carriage return arrow } + ('⇐'), { ? } { leftwards double arrow } + ('⇑'), { ? } { upwards double arrow } + ('⇒'), { ? } { rightwards double arrow } + ('⇓'), { ? } { downwards double arrow } + ('⇔'), { ? } { left right double arrow } + ('∀'), { ? } { for all } + ('∂'), { ? } { partial differential } + ('∃'), { ? } { there exists } + ('∅'), { } { empty set } + ('∇'), { ? } { backward difference } + ('∈'), { ? } { element of } + ('∉'), { ? } { not an element of } + ('∋'), { ? } { contains as member } + ('∏'), { ? } { n-ary product } + ('∑'), { ? } { n-ary sumation } + ('−'), { - } { minus sign } + ('∗'), { * } { asterisk operator } + ('√'), { v } { square root } + ('∝'), { ? } { proportional to } + ('∞'), { 8 } { infinity } + ('∠'), { ? } { angle } + ('∧'), { ? } { logical and } + ('∨'), { ? } { logical or } + ('∩'), { n } { intersection } + ('∪'), { ? } { union } + ('∫'), { ? } { integral } + ('∴'), { ? } { therefore } + ('∼'), { ~ } { similar to = tilde operator } + ('≅'), { ? } { approximately equal to } + ('≈'), { } { almost euqal to } + ('≠'), { ? } { not equal to } + ('≡'), { = } { identical to } + ('≤'), { = } { less-than or equal to } + ('≥'), { = } { greater-than or equal to } + ('⊂'), { ? } { subset of } + ('⊃'), { ? } { superset of } + ('⊄'), { ? } { not a subset of } + ('⊆'), { ? } { subset of or equal to } + ('⊇'), { ? } { superset of or equal to } + ('⊕'), { ? } { circled plus } + ('⊗'), { ? } { circled times } + ('⊥'), { ? } { orthogonal to = perpendicular } + ('⋅'), { } { dot operator } + ('⌈'), { ? } { left ceiling } + ('⌉'), { ? } { right ceiling } + ('⌊'), { ? } { left floor } + ('⌋'), { ? } { right floor } + ('⟨'), { < } { left-pointing angle bracket } + ('⟩'), { > } { right-pointing angle bracket } + ('◊'), { ? } { lozenge } + ('♠'), { ? } { black spade suit } + ('♣'), { ? } { black club suit } + ('♥'), { ? } { black heart suit } + ('♦'), { ? } { black diamond suit } + ('‘'), { } { left single quote } + ('’'), { } { right single quote } + ('‚'), { } { single low-9 quote } + ('“'), { } { left double quote } + ('”'), { } { right double quote } + ('„'), { } { double low-9 quote } + ('†'), { } { dagger } + ('‡'), { } { double dagger } + ('‰'), { } { per mill sign } + ('‹'), { } { single left-pointing angle quote } + ('›'), { } { single right-pointing angle quote } + ('"'), { " " } { double quotation mark } + ('&'), { & & } { ampersand } + ('<'), { < < } { less-than sign } + ('>'), { > } { greater-than sign } + ('–'), { – } { en dash } + ('—'), { — } { em dash } + (' '), {   } { nonbreaking space } + (' '), { } { thin space } + (' '), { } { en space } + (' '), { } { em space } + ('¡'), { ¡ ! } { inverted exclamation } + ('¢'), { ¢ c } { cent sign } + ('£'), { £ L } { pound sterling } + ('¤'), { ¤ } { general currency sign } + ('¥'), { ¥ Y } { yen sign } + ('¦'), { ¦ } { broken vertical bar } + ('&brkbar;'), { ¦ } { broken vertical bar } + ('§'), { § } { section sign } + ('¨'), { ¨ } { umlaut } + ('¨'), { ¨ } { umlaut } + ('©'), { © } { copyright } + ('ª'), { ª a } { feminine ordinal } + ('«'), { « } { left angle quote } + ('¬'), { ¬ } { not sign } + ('­'), { ­ } { soft hyphen } + ('®'), { ® } { registered trademark } + ('¯'), { ¯ } { macron accent } + ('&hibar;'), { ¯ } { macron accent } + ('°'), { ° } { degree sign } + ('±'), { ± } { plus or minus } + ('²'), { ² 2 } { superscript two } + ('³'), { ³ 3 } { superscript three } + ('´'), { ´ } { acute accent } + ('µ'), { µ } { micro sign } + ('¶'), { ¶ } { paragraph sign } + ('·'), { · } { middle dot } + ('¸'), { ¸ } { cedilla } + ('¹'), { ¹ 1 } { superscript one } + ('º'), { º o } { masculine ordinal } + ('»'), { » } { right angle quote } + ('¼'), { ¼ 1 } { one-fourth } + ('½'), { ½ 1 } { one-half } + ('¾'), { ¾ 3 } { three-fourths } + ('¿'), { ¿ ? } { inverted question mark } + ('À'), { À A } { uppercase A, grave accent } + ('Á'), { Á } { uppercase A, acute accent } + ('Â'), {  } { uppercase A, circumflex accent } + ('Ã'), { à A } { uppercase A, tilde } + ('Ä'), { Ä } { uppercase A, umlaut } + ('Å'), { Å A } { uppercase A, ring } + ('Æ'), { Æ A } { uppercase AE } + ('Ç'), { Ç } { uppercase C, cedilla } + ('È'), { È E } { uppercase E, grave accent } + ('É'), { É } { uppercase E, acute accent } + ('Ê'), { Ê E } { uppercase E, circumflex accent } + ('Ë'), { Ë } { uppercase E, umlaut } + ('Ì'), { Ì I } { uppercase I, grave accent } + ('Í'), { Í } { uppercase I, acute accent } + ('Î'), { Î } { uppercase I, circumflex accent } + ('Ï'), { Ï I } { uppercase I, umlaut } + ('Ð'), { Ð ? } { uppercase Eth, Icelandic } + ('Ñ'), { Ñ N } { uppercase N, tilde } + ('Ò'), { Ò O } { uppercase O, grave accent } + ('Ó'), { Ó } { uppercase O, acute accent } + ('Ô'), { Ô } { uppercase O, circumflex accent } + ('Õ'), { Õ O } { uppercase O, tilde } + ('Ö'), { Ö } { uppercase O, umlaut } + ('×'), { × } { multiplication sign } + ('Ø'), { Ø O } { uppercase O, slash } + ('Ù'), { Ù U } { uppercase U, grave accent } + ('Ú'), { Ú } { uppercase U, acute accent } + ('Û'), { Û U } { uppercase U, circumflex accent } + ('Ü'), { Ü } { uppercase U, umlaut } + ('Ý'), { Ý } { uppercase Y, acute accent } + ('Þ'), { Þ ? } { uppercase THORN, Icelandic } + ('ß'), { ß } { lowercase sharps, German } + ('à'), { à } { lowercase a, grave accent } + ('á'), { á } { lowercase a, acute accent } + ('â'), { â } { lowercase a, circumflex accent } + ('ã'), { ã } { lowercase a, tilde } + ('ä'), { ä } { lowercase a, umlaut } + ('å'), { å } { lowercase a, ring } + ('æ'), { æ a } { lowercase ae } + ('ç'), { ç } { lowercase c, cedilla } + ('è'), { è e } { lowercase e, grave accent } + ('é'), { é } { lowercase e, acute accent } + ('ê'), { ê } { lowercase e, circumflex accent } + ('ë'), { ë } { lowercase e, umlaut } + ('ì'), { ì i } { lowercase i, grave accent } + ('í'), { í } { lowercase i, acute accent } + ('î'), { î } { lowercase i, circumflex accent } + ('ï'), { ï i } { lowercase i, umlaut } + ('ð'), { ð ? } { lowercase eth, Icelandic } + ('ñ'), { ñ } { lowercase n, tilde } + ('ò'), { ò o } { lowercase o, grave accent } + ('ó'), { ó } { lowercase o, acute accent } + ('ô'), { ô } { lowercase o, circumflex accent } + ('õ'), { õ o } { lowercase o, tilde } + ('ö'), { ö } { lowercase o, umlaut } + ('÷'), { ÷ } { division sign } + ('ø'), { ø o } { lowercase o, slash } + ('ù'), { ù u } { lowercase u, grave accent } + ('ú'), { ú } { lowercase u, acute accent } + ('û'), { û u } { lowercase u, circumflex accent } + ('ü'), { ü } { lowercase u, umlaut } + ('ý'), { ý } { lowercase y, acute accent } + ('þ'), { þ ? } { lowercase thorn, Icelandic } + ('ÿ'), { ÿ y } { lowercase y, umlaut } + ('€'), { } { euro sign } + ('Œ'), { } { capital ligature OE } + ('œ'), { } { small ligature oe } + ('š'), { } { small S with caron } + ('Š'), { } { capital S with caron } + ('ƒ'), { } { function } + ('ˆ') { } { circumflex accent } + ); + + +type + TtkTokenKind = (tkAmpersand, tkComment, tkIdentifier, tkKey, tkNull, + tkSpace, tkSymbol, tkText, tkUndefKey, tkValue); + + TRangeState = (rsAmpersand, rsComment, rsKey, rsParam, rsText, + rsUnknown, rsValue, rsQuoteValue, rsDoubleQuoteValue); + + PIdentFuncTableFunc = ^TIdentFuncTableFunc; + TIdentFuncTableFunc = function (Index: Integer): TtkTokenKind of object; + + TSynHTMLSyn = class(TSynCustomHighlighter) + private + FAndCode: Integer; + FRange: TRangeState; +// FIdentFuncTable: array[0..1542] of TIdentFuncTableFunc; + FIdentFuncTable: array[0..2178] of TIdentFuncTableFunc; + FTokenID: TtkTokenKind; + FAndAttri: TSynHighlighterAttributes; + FCommentAttri: TSynHighlighterAttributes; + FIdentifierAttri: TSynHighlighterAttributes; + FKeyAttri: TSynHighlighterAttributes; + FSpaceAttri: TSynHighlighterAttributes; + FSymbolAttri: TSynHighlighterAttributes; + FTextAttri: TSynHighlighterAttributes; + FUndefKeyAttri: TSynHighlighterAttributes; + FValueAttri: TSynHighlighterAttributes; + function AltFunc(Index: Integer): TtkTokenKind; + function KeyWordFunc(Index: Integer): TtkTokenKind; + function HashKey(Str: PWideChar): Cardinal; + function IdentKind(MayBe: PWideChar): TtkTokenKind; + procedure InitIdent; + procedure TextProc; + procedure CommentProc; + procedure BraceCloseProc; + procedure BraceOpenProc; + procedure CRProc; + procedure EqualProc; + procedure IdentProc; + procedure LFProc; + procedure NullProc; + procedure SpaceProc; + procedure StringProc; + procedure AmpersandProc; + protected + function GetSampleSource: UnicodeString; override; + function IsFilterStored: Boolean; override; + procedure NextProcedure; + public + class function GetLanguageName: string; override; + class function GetFriendlyLanguageName: UnicodeString; override; + public + constructor Create(AOwner: TComponent); override; + function GetDefaultAttribute(Index: Integer): TSynHighlighterAttributes; + override; + function GetEol: Boolean; override; + function GetRange: Pointer; override; + function GetTokenID: TtkTokenKind; + function GetTokenAttribute: TSynHighlighterAttributes; override; + function GetTokenKind: Integer; override; + function IsIdentChar(AChar: WideChar): Boolean; override; + procedure Next; override; + procedure SetRange(Value: Pointer); override; + procedure ResetRange; override; + published + property AndAttri: TSynHighlighterAttributes read FAndAttri write FAndAttri; + property CommentAttri: TSynHighlighterAttributes read FCommentAttri + write FCommentAttri; + property IdentifierAttri: TSynHighlighterAttributes read FIdentifierAttri + write FIdentifierAttri; + property KeyAttri: TSynHighlighterAttributes read FKeyAttri write FKeyAttri; + property SpaceAttri: TSynHighlighterAttributes read FSpaceAttri + write FSpaceAttri; + property SymbolAttri: TSynHighlighterAttributes read FSymbolAttri + write FSymbolAttri; + property TextAttri: TSynHighlighterAttributes read FTextAttri + write FTextAttri; + property UndefKeyAttri: TSynHighlighterAttributes read FUndefKeyAttri + write FUndefKeyAttri; + property ValueAttri: TSynHighlighterAttributes read FValueAttri + write FValueAttri; + end; + +implementation + +uses + uRESTDWPrivSynEditStrConst; + +const +// KeyWords: array[0..201] of UnicodeString = ( +// '!doctype', '/a', '/abbr', '/acronym', '/address', '/applet', '/b', '/bdo', +// '/big', '/blink', '/blockquote', '/body', '/button', '/caption', '/center', +// '/cite', '/code', '/colgroup', '/comment', '/dd', '/del', '/dfn', '/dir', +// '/div', '/dl', '/dt', '/em', '/embed', '/fieldset', '/font', '/form', +// '/frameset', '/h1', '/h2', '/h3', '/h4', '/h5', '/h6', '/head', '/html', +// '/i', '/iframe', '/ilayer', '/ins', '/kbd', '/label', '/layer', '/legend', +// '/li', '/listing', '/map', '/marquee', '/menu', '/multicol', '/nobr', +// '/noembed', '/noframes', '/nolayer', '/noscript', '/object', '/ol', +// '/optgroup', '/option', '/p', '/pre', '/q', '/s', '/samp', '/script', +// '/select', '/server', '/small', '/span', '/strike', '/strong', '/style', +// '/sub', '/sup', '/table', '/tbody', '/td', '/textarea', '/tfoot', '/th', +// '/thead', '/title', '/tr', '/tt', '/u', '/ul', '/var', '/xmp', 'a', 'abbr', +// 'acronym', 'address', 'applet', 'area', 'b', 'base', 'basefont', 'bdo', +// 'bgsound', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'caption', +// 'center', 'cite', 'code', 'col', 'colgroup', 'comment', 'dd', 'del', 'dfn', +// 'dir', 'div', 'dl', 'dt', 'em', 'embed', 'fieldset', 'font', 'form', +// 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', +// 'html', 'i', 'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'kbd', +// 'keygen', 'label', 'layer', 'legend', 'li', 'link', 'listing', 'map', +// 'marquee', 'menu', 'meta', 'multicol', 'nextid', 'nobr', 'noembed', +// 'noframes', 'nolayer', 'noscript', 'object', 'ol', 'optgroup', 'option', +// 'p', 'param', 'plaintext', 'pre', 'q', 's', 'samp', 'script', 'select', +// 'server', 'small', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', +// 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'title', +// 'tr', 'tt', 'u', 'ul', 'var', 'wbr', 'xmp' +// ); +// +// KeyIndices: array[0..1542] of Integer = ( +// -1, -1, 182, -1, -1, -1, 97, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +// -1, -1, -1, 33, -1, -1, -1, -1, 40, -1, -1, -1, -1, -1, 137, 189, -1, -1, +// -1, -1, -1, -1, -1, -1, 191, -1, -1, -1, -1, -1, -1, -1, 52, 170, -1, -1, +// -1, -1, -1, -1, -1, -1, -1, 5, 55, -1, 83, -1, -1, 34, -1, 198, -1, -1, -1, +// -1, -1, -1, -1, 82, -1, -1, -1, -1, -1, 74, 111, -1, 62, -1, -1, -1, -1, -1, +// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 93, -1, -1, -1, -1, -1, -1, -1, -1, +// -1, -1, 35, 72, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 130, +// 190, -1, 117, -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, 36, -1, -1, 157, -1, -1, -1, +// -1, -1, 13, 114, -1, -1, -1, -1, 131, -1, -1, -1, -1, -1, -1, 21, -1, -1, +// -1, 161, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 139, -1, +// -1, -1, -1, 37, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 192, -1, -1, +// 132, 103, -1, -1, -1, 199, -1, -1, -1, -1, -1, -1, -1, 129, -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, 133, -1, -1, -1, -1, -1, -1, -1, -1, 54, +// -1, -1, -1, -1, -1, 42, -1, -1, -1, -1, -1, -1, -1, -1, -1, 109, -1, -1, -1, +// 148, -1, -1, -1, -1, -1, -1, -1, 96, -1, -1, -1, -1, -1, -1, -1, -1, 134, +// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 183, -1, -1, 168, -1, 45, +// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 179, -1, -1, 63, -1, +// -1, -1, -1, -1, -1, -1, -1, -1, 135, -1, -1, -1, -1, -1, -1, 60, -1, -1, -1, +// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 71, -1, -1, -1, -1, -1, -1, -1, +// -1, -1, -1, -1, -1, -1, 65, -1, -1, -1, -1, -1, -1, -1, 125, -1, -1, -1, -1, +// -1, -1, -1, -1, -1, 4, -1, -1, 39, -1, -1, -1, -1, 128, 20, -1, -1, 51, -1, +// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 176, -1, -1, -1, -1, -1, -1, -1, -1, +// -1, -1, -1, -1, -1, -1, -1, 112, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +// 180, -1, -1, -1, -1, -1, 172, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 107, +// -1, -1, -1, -1, 66, -1, -1, -1, 59, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +// -1, -1, -1, -1, -1, -1, -1, -1, 162, -1, 8, -1, -1, -1, -1, -1, -1, 166, -1, +// -1, -1, 169, 141, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 95, -1, -1, +// -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, 124, -1, -1, -1, -1, -1, -1, -1, +// -1, -1, -1, -1, -1, -1, 19, -1, -1, 41, -1, 173, -1, -1, -1, -1, -1, -1, -1, +// -1, -1, 88, -1, -1, -1, -1, -1, 27, -1, -1, -1, -1, -1, -1, -1, -1, -1, 186, +// -1, -1, -1, -1, -1, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, 200, -1, +// -1, -1, 87, 181, -1, -1, -1, -1, 119, -1, -1, -1, 57, -1, -1, -1, 104, -1, +// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 47, -1, 26, -1, -1, -1, -1, -1, +// -1, -1, -1, -1, -1, -1, -1, -1, -1, 174, -1, -1, -1, -1, -1, -1, -1, -1, -1, +// -1, -1, -1, 201, -1, -1, -1, 195, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +// 58, 50, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 49, -1, -1, -1, 101, +// -1, -1, -1, -1, -1, -1, -1, -1, -1, 116, -1, -1, -1, -1, 113, 187, -1, -1, +// -1, 94, -1, -1, -1, -1, -1, 165, -1, -1, -1, -1, -1, -1, -1, 69, -1, -1, -1, +// -1, -1, 167, -1, -1, 163, -1, -1, 197, -1, -1, -1, -1, 78, -1, 68, -1, -1, +// -1, -1, -1, -1, 145, -1, -1, 196, -1, -1, -1, -1, 12, -1, -1, -1, 160, -1, +// 61, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 123, +// -1, -1, -1, -1, -1, -1, 76, 120, -1, 140, -1, -1, -1, -1, -1, -1, -1, -1, +// -1, -1, 10, -1, -1, -1, -1, -1, 153, -1, -1, -1, -1, -1, -1, -1, 30, -1, -1, +// -1, -1, -1, -1, 142, -1, -1, -1, -1, -1, 99, -1, -1, -1, -1, -1, -1, -1, -1, +// -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 152, -1, 171, +// -1, -1, -1, -1, -1, 11, -1, -1, -1, -1, -1, 150, -1, -1, -1, -1, -1, -1, -1, +// -1, -1, -1, -1, -1, -1, -1, -1, -1, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, +// 22, -1, -1, -1, -1, -1, 138, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +// 24, -1, 70, -1, -1, -1, -1, -1, -1, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, +// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, -1, -1, -1, -1, -1, -1, -1, +// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 53, -1, -1, 177, -1, -1, -1, -1, -1, +// -1, -1, -1, -1, -1, -1, -1, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, 100, -1, +// -1, -1, -1, -1, -1, -1, -1, -1, -1, 108, -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, 144, -1, -1, -1, +// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 90, -1, -1, +// -1, 121, 159, 102, -1, -1, -1, -1, -1, -1, -1, -1, -1, 23, -1, -1, -1, -1, +// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 155, 149, -1, -1, -1, -1, -1, +// -1, -1, -1, -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +// -1, -1, -1, 81, 2, -1, 110, -1, -1, -1, 46, -1, -1, -1, -1, -1, -1, -1, -1, +// -1, -1, -1, -1, -1, -1, 146, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +// 178, -1, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, 143, -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, 164, -1, -1, -1, 48, -1, -1, -1, -1, -1, -1, 9, +// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31, -1, 6, -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, 188, -1, -1, -1, -1, -1, -1, -1, 25, -1, -1, 73, -1, -1, -1, -1, +// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 64, +// 79, -1, -1, -1, -1, -1, -1, -1, -1, -1, 127, -1, -1, -1, 18, -1, -1, -1, -1, +// -1, -1, -1, -1, -1, 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +// -1, -1, 184, -1, -1, -1, 175, -1, -1, 193, -1, 92, 151, 154, -1, -1, -1, -1, +// 106, -1, -1, -1, -1, -1, -1, -1, -1, -1, 194, -1, -1, -1, -1, -1, -1, -1, +// -1, 75, -1, -1, -1, -1, -1, -1, 84, -1, -1, -1, -1, -1, 28, -1, -1, -1, -1, +// -1, -1, 98, -1, 80, -1, -1, -1, 85, -1, -1, -1, -1, 67, -1, 118, -1, -1, -1, +// -1, -1, -1, -1, -1, 126, -1, -1, -1, -1, -1, 77, -1, -1, 122, 44, -1, -1, +// -1, -1, -1, 89, -1, -1, -1, 115, 136, -1, -1, -1, -1, -1, -1, -1, -1, -1, +// -1, -1, -1, -1, -1, -1, -1, 105, -1, -1, -1, -1, -1, -1, -1, -1, 147, -1, +// 16, 185, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +// 158, -1, -1, -1, -1, -1, -1, -1, 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, 91, +// -1, -1, 156, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +// ); + + KeyWords: array[0..256] of UnicodeString = ( + '!doctype', '/!doctype', '/a', '/abbr', '/acronym', '/address', '/applet', + '/area', '/article', '/aside', '/audio', '/b', '/base', '/basefont', '/bb', + '/bdo', '/big', '/blockquote', '/body', '/button', '/canvas', '/caption', + '/center', '/cite', '/code', '/col', '/colgroup', '/command', '/datalist', + '/dd', '/del', '/details', '/dfn', '/dialog', '/dir', '/div', '/dl', '/dt', + '/em', '/embed', '/fieldset', '/figcaption', '/figure', '/font', '/footer', + '/form', '/frame', '/frameset', '/h1', '/h2', '/h3', '/h4', '/h5', '/h6', + '/head', '/header', '/hgroup', '/html', '/i', '/iframe', '/img', '/input', + '/ins', '/kbd', '/keygen', '/label', '/layer', '/legend', '/li', '/link', + '/map', '/mark', '/marquee', '/menu', '/meta', '/meter', '/multicol', + '/nav', '/nobr', '/noembed', '/noframes', '/nolayer', '/noscript', + '/object', '/ol', '/optgroup', '/option', '/output', '/p', '/param', '/pre', + '/progress', '/q', '/rp', '/rt', '/ruby', '/s', '/samp', '/script', + '/section', '/select', '/server', '/small', '/source', '/span', '/strike', + '/strong', '/style', '/sub', '/summary', '/sup', '/table', '/tbody', '/td', + '/textarea', '/tfoot', '/th', '/thead', '/time', '/title', '/tr', '/track', + '/tt', '/u', '/ul', '/var', '/video', '/wbr', '/xmp', 'a', 'abbr', + 'acronym', 'address', 'applet', 'area', 'article', 'aside', 'audio', 'b', + 'base', 'basefont', 'bb', 'bdo', 'big', 'blockquote', 'body', 'button', + 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'command', + 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', + 'dt', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'font', 'footer', + 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', + 'header', 'hgroup', 'html', 'i', 'iframe', 'img', 'input', 'ins', 'kbd', + 'keygen', 'label', 'layer', 'legend', 'li', 'link', 'map', 'mark', + 'marquee', 'menu', 'meta', 'meter', 'multicol', 'nav', 'nobr', 'noembed', + 'noframes', 'nolayer', 'noscript', 'object', 'ol', 'optgroup', 'option', + 'output', 'p', 'param', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', + 'samp', 'script', 'section', 'select', 'server', 'small', 'source', 'span', + 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'uRESTDWPrivSynEdit', 'table', + 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', + 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr', 'xmp' + ); + + KeyIndices: array[0..2178] of Integer = ( + -1, -1, -1, 3, -1, -1, 231, 250, -1, -1, -1, 212, -1, -1, -1, -1, -1, -1, + -1, -1, 175, -1, -1, -1, -1, -1, 128, -1, -1, -1, -1, 155, -1, -1, -1, -1, + -1, -1, -1, 83, -1, 201, 122, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 48, -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, 70, -1, -1, -1, -1, -1, -1, 183, -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, 216, -1, -1, -1, -1, -1, -1, 31, -1, -1, -1, + -1, 89, -1, -1, -1, 234, -1, -1, 188, -1, -1, -1, -1, -1, -1, -1, -1, 107, + -1, -1, 61, -1, -1, -1, -1, -1, 21, -1, -1, -1, 8, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 225, -1, -1, 150, -1, -1, 91, -1, -1, -1, 88, -1, + -1, -1, 158, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 59, -1, + -1, -1, 137, 12, -1, 67, -1, -1, 47, -1, -1, -1, -1, -1, 10, -1, -1, 135, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 218, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 170, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 174, -1, 7, -1, -1, -1, 142, -1, -1, -1, -1, -1, -1, -1, -1, 133, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 232, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 77, -1, -1, -1, 178, -1, -1, -1, -1, -1, + -1, 209, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 130, -1, 162, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 51, -1, -1, -1, 237, -1, -1, -1, + 17, -1, -1, -1, -1, -1, 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 79, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 157, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 210, -1, -1, -1, 104, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 206, -1, -1, -1, -1, -1, -1, -1, -1, 165, -1, -1, -1, -1, + -1, -1, -1, 254, -1, -1, -1, -1, -1, -1, 73, -1, -1, -1, -1, 126, -1, -1, + -1, -1, -1, -1, -1, 24, -1, -1, 238, -1, 96, -1, 38, -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, 248, -1, -1, -1, 156, -1, 103, -1, -1, + -1, -1, -1, -1, -1, -1, 239, 211, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 111, -1, -1, -1, -1, -1, -1, -1, 120, -1, -1, -1, 29, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 71, 84, -1, -1, -1, -1, -1, 87, -1, -1, -1, -1, 186, -1, + -1, -1, -1, -1, -1, -1, -1, 243, -1, -1, -1, -1, 20, -1, -1, -1, -1, -1, -1, + 115, -1, -1, -1, -1, -1, -1, 26, 138, -1, -1, -1, -1, -1, -1, -1, 163, -1, + -1, 144, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 181, 22, -1, -1, -1, -1, 255, -1, -1, -1, -1, -1, -1, 36, -1, -1, 240, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 112, -1, -1, -1, -1, -1, -1, + 153, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 34, -1, -1, -1, + -1, -1, -1, -1, 106, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 256, + -1, 164, -1, -1, -1, -1, -1, -1, -1, -1, -1, 192, 145, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 37, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 114, -1, 197, + 63, -1, -1, -1, -1, -1, -1, 64, -1, -1, -1, -1, -1, -1, 202, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 75, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 44, -1, 200, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, 151, + -1, -1, -1, -1, -1, -1, 242, -1, -1, -1, -1, -1, -1, -1, -1, 193, 176, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 66, -1, -1, -1, -1, -1, 220, -1, -1, -1, + 141, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 49, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 81, -1, -1, 93, 76, -1, -1, 14, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, -1, -1, -1, -1, 230, -1, 198, -1, + -1, -1, -1, -1, -1, 69, -1, -1, -1, -1, 101, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 244, -1, -1, -1, -1, 208, -1, -1, -1, + -1, -1, -1, -1, 100, 203, 5, -1, -1, -1, -1, -1, 41, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 116, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 25, -1, -1, -1, -1, -1, 45, 92, -1, -1, -1, -1, 80, 204, -1, + -1, -1, -1, -1, 42, -1, -1, -1, -1, -1, 132, -1, 249, -1, -1, -1, -1, -1, + -1, -1, 82, -1, 16, -1, 121, 86, -1, -1, -1, 224, -1, 195, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 159, -1, -1, 54, + -1, -1, -1, -1, -1, -1, -1, -1, 207, -1, -1, 68, -1, -1, -1, -1, -1, -1, + 252, -1, 233, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, + -1, -1, -1, -1, -1, -1, 251, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 124, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 108, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 179, 18, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 191, -1, -1, -1, -1, -1, 99, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 52, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 90, + 171, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 72, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 168, -1, -1, -1, 226, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 222, -1, -1, -1, -1, -1, 253, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 246, -1, -1, -1, -1, -1, -1, -1, -1, -1, 196, + -1, -1, -1, -1, -1, -1, 199, -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, 6, -1, -1, + -1, -1, 0, -1, -1, 229, -1, -1, 228, -1, -1, -1, -1, -1, 215, -1, 125, 102, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 227, -1, 172, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 194, -1, -1, + -1, -1, -1, -1, -1, 184, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 161, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 169, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 213, -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, 205, -1, -1, 190, -1, -1, -1, 97, -1, -1, -1, -1, -1, 33, -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, 247, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 119, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 55, -1, 19, -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, -1, -1, -1, 148, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 223, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 187, -1, -1, -1, + 95, -1, 136, -1, 177, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, -1, -1, -1, + 118, -1, -1, -1, -1, -1, -1, 152, -1, -1, -1, -1, -1, -1, 40, -1, -1, -1, + -1, -1, -1, 50, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 143, -1, -1, -1, -1, -1, -1, -1, 214, -1, 166, + 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 39, -1, -1, -1, -1, 147, -1, -1, + -1, -1, -1, 15, -1, -1, 167, -1, -1, 173, -1, -1, -1, -1, -1, -1, -1, 131, + -1, -1, -1, 46, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 57, -1, + -1, -1, -1, -1, -1, -1, 149, -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, 235, 35, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 110, -1, -1, -1, -1, -1, -1, -1, + 27, -1, -1, -1, -1, -1, -1, -1, 160, -1, -1, -1, -1, -1, 74, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 78, -1, -1, -1, 30, -1, + 217, -1, -1, -1, -1, -1, 189, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 154, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 182, -1, 146, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 139, -1, -1, 98, -1, -1, -1, -1, 129, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, -1, 180, -1, -1, + 245, -1, -1, -1, -1, -1, -1, 241, -1, -1, -1, -1, 117, -1, 221, -1, -1, -1, + -1, -1, 23, -1, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, 53, -1, 1, -1, -1, + -1, -1, -1, -1, -1, 113, -1, -1, 134, -1, -1, -1, 94, -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, 185, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 140, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 43, -1, -1, -1, -1, -1, 109, -1, -1, -1, + -1, -1, 105, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 85, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 127, -1, -1, -1, 28, -1, -1, -1, -1, 123, -1, -1, -1, -1, -1, -1, + -1, 236, -1, 219, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1 + ); + +{$Q-} +function TSynHTMLSyn.HashKey(Str: PWideChar): Cardinal; +begin +// Result := 0; +// while IsIdentChar(Str^) or CharInSet(Str^, ['!', '/']) do +// begin +// Result := Result * 932 + Ord(Str^) * 46; +// Inc(Str); +// end; +// Result := Result mod 1543; +// FStringLen := Str - FToIdent; + + Result := 0; + while IsIdentChar(Str^) do + begin + Result := Result * 627 + Ord(Str^) * 829; + Inc(Str); + end; + Result := Result mod 2179; + FStringLen := Str - FToIdent; +end; +{$Q+} + +function TSynHTMLSyn.IdentKind(MayBe: PWideChar): TtkTokenKind; +var + Key: Cardinal; +begin + FToIdent := MayBe; + Key := HashKey(MayBe); + if Key <= High(FIdentFuncTable) then + Result := FIdentFuncTable[Key](KeyIndices[Key]) + else + Result := tkIdentifier; +end; + +procedure TSynHTMLSyn.InitIdent; +var + i: Integer; +begin + for i := Low(FIdentFuncTable) to High(FIdentFuncTable) do + if KeyIndices[i] = -1 then + FIdentFuncTable[i] := AltFunc; + + for i := Low(FIdentFuncTable) to High(FIdentFuncTable) do + if @FIdentFuncTable[i] = nil then + FIdentFuncTable[i] := KeyWordFunc; +end; + +function TSynHTMLSyn.AltFunc(Index: Integer): TtkTokenKind; +begin + Result := tkUndefKey; +end; + +function TSynHTMLSyn.KeyWordFunc(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkUndefKey; +end; + +constructor TSynHTMLSyn.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + + FCaseSensitive := False; + + FCommentAttri := TSynHighlighterAttributes.Create(SYNS_AttrComment, SYNS_FriendlyAttrComment); + AddAttribute(FCommentAttri); + + FIdentifierAttri := TSynHighlighterAttributes.Create(SYNS_AttrIdentifier, SYNS_FriendlyAttrIdentifier); + FIdentifierAttri.Style := [fsBold]; + AddAttribute(FIdentifierAttri); + + FKeyAttri := TSynHighlighterAttributes.Create(SYNS_AttrReservedWord, SYNS_FriendlyAttrReservedWord); + FKeyAttri.Style := [fsBold]; + FKeyAttri.Foreground := $00ff0080; + AddAttribute(FKeyAttri); + + FSpaceAttri := TSynHighlighterAttributes.Create(SYNS_AttrSpace, SYNS_FriendlyAttrSpace); + AddAttribute(FSpaceAttri); + + FSymbolAttri := TSynHighlighterAttributes.Create(SYNS_AttrSymbol, SYNS_FriendlyAttrSymbol); + FSymbolAttri.Style := [fsBold]; + AddAttribute(FSymbolAttri); + + FTextAttri := TSynHighlighterAttributes.Create(SYNS_AttrText, SYNS_FriendlyAttrText); + AddAttribute(FTextAttri); + + FUndefKeyAttri := TSynHighlighterAttributes.Create(SYNS_AttrUnknownWord, SYNS_FriendlyAttrUnknownWord); + FUndefKeyAttri.Style := [fsBold]; + FUndefKeyAttri.Foreground := clRed; + AddAttribute(FUndefKeyAttri); + + FValueAttri := TSynHighlighterAttributes.Create(SYNS_AttrValue, SYNS_FriendlyAttrValue); + FValueAttri.Foreground := $00ff8000; + AddAttribute(FValueAttri); + + FAndAttri := TSynHighlighterAttributes.Create(SYNS_AttrEscapeAmpersand, SYNS_FriendlyAttrEscapeAmpersand); + FAndAttri.Style := [fsBold]; + FAndAttri.Foreground := $0000ff00; + AddAttribute(FAndAttri); + SetAttributesOnChange(DefHighlightChange); + + InitIdent; + FRange := rsText; + FDefaultFilter := SYNS_FilterHTML; + FAndCode := -1; +end; + +procedure TSynHTMLSyn.BraceCloseProc; +begin + FRange := rsText; + FTokenID := tkSymbol; + Inc(Run); +end; + +procedure TSynHTMLSyn.CommentProc; +begin + FTokenID := tkComment; + + if IsLineEnd(Run) then + begin + NextProcedure; + Exit; + end; + + while not IsLineEnd(Run) do + begin + if (FLine[Run] = '>') and (FLine[Run - 1] = '-') and (FLine[Run - 2] = '-') then + begin + FRange := rsText; + Inc(Run); + Break; + end; + Inc(Run); + end; +end; + +procedure TSynHTMLSyn.BraceOpenProc; +begin + Inc(Run); + if (FLine[Run] = '!') and (FLine[Run + 1] = '-') and (FLine[Run + 2] = '-') then + begin + FRange := rsComment; + FTokenID := tkComment; + Inc(Run, 3); + end + else + begin + FRange := rsKey; + FTokenID := tkSymbol; + end; +end; + +procedure TSynHTMLSyn.CRProc; +begin + FTokenID := tkSpace; + Inc(Run); + if FLine[Run] = #10 then Inc(Run); +end; + +procedure TSynHTMLSyn.EqualProc; +begin + FRange := rsValue; + FTokenID := tkSymbol; + Inc(Run); +end; + +procedure TSynHTMLSyn.IdentProc; +begin + case FRange of + rsKey: + begin + FRange := rsParam; + FTokenID := IdentKind((FLine + Run)); + Inc(Run, FStringLen); + end; + rsValue: + begin + FRange := rsParam; + FTokenID := tkValue; + repeat + Inc(Run); + until (FLine[Run] <= #32) or (FLine[Run] = '>'); + end; + else + FTokenID := tkIdentifier; + repeat + Inc(Run); + until (FLine[Run] <= #32) or (FLine[Run] = '=') or (FLine[Run] = '"') or + (FLine[Run] = '>'); + end; +end; + +procedure TSynHTMLSyn.LFProc; +begin + FTokenID := tkSpace; + Inc(Run); +end; + +procedure TSynHTMLSyn.NullProc; +begin + FTokenID := tkNull; + Inc(Run); +end; + +procedure TSynHTMLSyn.TextProc; + + function IsStopChar: Boolean; + begin + case FLine[Run] of + #0..#31, '<', '&': + Result := True; + else + Result := False; + end; + end; + + function IsNumberChar: Boolean; + begin + case FLine[Run] of + '0'..'9', 'A'..'F', 'a'..'f': + Result := True; + else + Result := False; + end; + end; + +var + i: Integer; +begin + if CharInSet(FLine[Run], [#0..#31, '<']) then + begin + NextProcedure; + Exit; + end; + + FTokenID := tkText; + + while True do + begin + while not IsStopChar do Inc(Run); + + if (FLine[Run] = '&') then + begin + if (FLine[Run + 1] = '#') then + begin + FAndCode := -1; + i := Run; + Inc(Run, 2); + if CharInSet(FLine[Run], ['X', 'x']) then + begin + Inc(Run); + while IsNumberChar do + Inc(Run); + end + else + while CharInSet(FLine[Run], ['0'..'9']) do + Inc(Run); + if (FLine[Run] = ';') then + begin + Inc(Run); + Run := i; + FRange := rsAmpersand; + end; + Break; + end + else + for i := Low(EscapeAmps) To High(EscapeAmps) do + if (WStrLComp((FLine + Run), EscapeAmps[i], WStrLen(EscapeAmps[i])) = 0) then + begin + FAndCode := i; + FRange := rsAmpersand; + Exit; + end; + + Inc(Run); + end + else + Break; + end; +end; + +procedure TSynHTMLSyn.AmpersandProc; + + function IsNumberChar: Boolean; + begin + case FLine[Run] of + '0'..'9', 'A'..'F', 'a'..'f': + Result := True; + else + Result := False; + end; + end; + +begin + if FRange <> rsAmpersand then + begin + if FRange = rsKey then + begin + Inc(Run); + FRange := rsText; + FTokenID := tkText; + end + else + IdentProc; + Exit; + end; + + case FAndCode of + Low(EscapeAmps)..High(EscapeAmps): + begin + FTokenID := tkAmpersand; + Inc(Run, WStrLen(EscapeAmps[FAndCode])); + end; + else begin + if (FLine[Run + 1] = '#') then + begin + FAndCode := -1; + Inc(Run, 2); + if CharInSet(FLine[Run], ['X', 'x']) then + begin + Inc(Run); + while IsNumberChar do + Inc(Run); + end + else + while CharInSet(FLine[Run], ['0'..'9']) do + Inc(Run); + if (FLine[Run] = ';') then begin + Inc(Run); + FTokenID := tkAmpersand; + end else + FTokenID := tkText; + end; + end; + end; + FAndCode := -1; + FRange := rsText; +end; + +procedure TSynHTMLSyn.SpaceProc; +begin + Inc(Run); + FTokenID := tkSpace; + while FLine[Run] <= #32 do + begin + if CharInSet(FLine[Run], [#0, #9, #10, #13]) then + Break; + Inc(Run); + end; +end; + +procedure TSynHTMLSyn.StringProc; +var + iOpenChar: WideChar; +begin + case FRange of + rsQuoteValue: + begin + iOpenChar := #39; + FTokenID := tkValue; + end; + rsDoubleQuoteValue: + begin + iOpenChar := '"'; + FTokenID := tkValue; + end; + else + begin + iOpenChar := FLine[Run]; + if FRange = rsValue then + begin + if iOpenChar = '"' then + FRange := rsDoubleQuoteValue + else + FRange := rsQuoteValue; + FTokenID := tkValue; + end else + begin + IdentProc; + Exit; + end; + Inc(Run); { jumps over the opening char } + end; + end; + + while not IsLineEnd(Run) do + begin + if FLine[Run] = iOpenChar then + begin + Inc(Run); { jumps over the closing char } + if FRange in [rsDoubleQuoteValue, rsQuoteValue] then + FRange := rsParam + else + FRange := rsText; + Break; + end; + Inc(Run); + end; +end; + +function TSynHTMLSyn.IsIdentChar(AChar: WideChar): Boolean; +begin + case AChar of + '_', '/', '0'..'9', 'A'..'Z', 'a'..'z': + Result := True; + else + Result := False; + end; +end; + + +procedure TSynHTMLSyn.Next; +begin + FTokenPos := Run; + case FRange of + rsText: + TextProc; + rsComment: + CommentProc; + rsQuoteValue, rsDoubleQuoteValue: + if IsLineEnd(Run) then + NextProcedure + else + StringProc; + else + NextProcedure; + end; + + // ensure that one call of Next is enough to reach next token + if (fOldRun = Run) and not GetEol then Next; + + inherited; +end; + +procedure TSynHTMLSyn.NextProcedure; +begin + case FLine[Run] of + #0: NullProc; + #10: LFProc; + #13: CRProc; + #1..#9, #11, #12, #14..#32: SpaceProc; + '&': AmpersandProc; + '"', #39: StringProc; + '<': BraceOpenProc; + '>': BraceCloseProc; + '=': EqualProc; + else IdentProc; + end; +end; + +function TSynHTMLSyn.GetDefaultAttribute(Index: Integer): TSynHighlighterAttributes; +begin + case Index of + SYN_ATTR_COMMENT: Result := FCommentAttri; + SYN_ATTR_IDENTIFIER: Result := FIdentifierAttri; + SYN_ATTR_KEYWORD: Result := FKeyAttri; + SYN_ATTR_WHITESPACE: Result := FSpaceAttri; + SYN_ATTR_SYMBOL: Result := FSymbolAttri; + else + Result := nil; + end; +end; + +function TSynHTMLSyn.GetEol: Boolean; +begin + Result := Run = FLineLen + 1; +end; + +function TSynHTMLSyn.GetTokenID: TtkTokenKind; +begin + Result := FTokenID; +end; + +function TSynHTMLSyn.GetTokenAttribute: TSynHighlighterAttributes; +begin + case FTokenID of + tkAmpersand: Result := FAndAttri; + tkComment: Result := FCommentAttri; + tkIdentifier: Result := FIdentifierAttri; + tkKey: Result := FKeyAttri; + tkSpace: Result := FSpaceAttri; + tkSymbol: Result := FSymbolAttri; + tkText: Result := FTextAttri; + tkUndefKey: Result := FUndefKeyAttri; + tkValue: Result := FValueAttri; + else Result := nil; + end; +end; + +function TSynHTMLSyn.GetTokenKind: Integer; +begin + Result := Ord(FTokenID); +end; + +function TSynHTMLSyn.GetRange: Pointer; +begin + Result := Pointer(FRange); +end; + +procedure TSynHTMLSyn.SetRange(Value: Pointer); +begin + FRange := TRangeState(Value); +end; + +procedure TSynHTMLSyn.ResetRange; +begin + FRange:= rsText; +end; + +function TSynHTMLSyn.IsFilterStored: Boolean; +begin + Result := FDefaultFilter <> SYNS_FilterHTML; +end; + +class function TSynHTMLSyn.GetLanguageName: string; +begin + Result := SYNS_LangHTML; +end; + +function TSynHTMLSyn.GetSampleSource: UnicodeString; +begin + Result := + ''#13#10 + + #13#10 + + ''#13#10 + + ''#13#10 + + '
'#13#10 + + ' '#13#10 + + '
'#13#10 + + ' Sample HTML code © 2001'#13#10 + + ''#13#10 + + ''; +end; + +class function TSynHTMLSyn.GetFriendlyLanguageName: UnicodeString; +begin + Result := SYNS_FriendlyLangHTML; +end; + +initialization +{$IFNDEF SYN_CPPB_1} + RegisterPlaceableHighlighter(TSynHTMLSyn); +{$ENDIF} +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterJScript.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterJScript.pas new file mode 100644 index 000000000..4b06b2716 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterJScript.pas @@ -0,0 +1,4900 @@ +{------------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: uRESTDWPrivSynHighlighterJScript.pas, released 2000-04-14. +The Original Code is based on the mwJScript.pas file from the +mwEdit component suite by Martin Waldenburg and other developers, the Initial +Author of this file is Tony de Buys. +Unicode translation by Mal Hrz. +All Rights Reserved. + +Contributors to the uRESTDWPrivSynEdit and mwEdit projects are listed in the +Contributors.txt file. + +Alternatively, the contents of this file may be used under the terms of the +GNU General Public License Version 2 or later (the "GPL"), in which case +the provisions of the GPL are applicable instead of those above. +If you wish to allow use of your version of this file only under the terms +of the GPL and not to allow others to use your version of this file +under the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the GPL. +If you do not delete the provisions above, a recipient may use your version +of this file under either the MPL or the GPL. + +$Id: uRESTDWPrivSynHighlighterJScript.pas,v 1.21.2.8 2008/09/14 16:25:00 maelh Exp $ + +You may retrieve the latest version of this file at the uRESTDWPrivSynEdit home page, +located at http://uRESTDWPrivSynEdit.SourceForge.net + +Known Issues: +-------------------------------------------------------------------------------} +{ +@abstract(Provides a JavaScript/JScript highlighter for uRESTDWPrivSynEdit) +@author(Tony De Buys [tony@lad.co.za], converted to uRESTDWPrivSynEdit by David Muir ) +@created(December 1999, converted to uRESTDWPrivSynEdit April 14, 2000) +@lastmod(2000-06-23) +The uRESTDWPrivSynHighlighterJScript unit provides uRESTDWPrivSynEdit with a JScript/JavaScript (.js) highlighter. +The highlighter formats JavaScript source code highlighting keywords, strings, numbers and characters. +} + +unit uRESTDWPrivSynHighlighterJScript; + +{$I uRESTDWPrivSynEdit.inc} + +interface + +uses + Graphics, + Registry, + uRESTDWPrivSynEditTypes, + uRESTDWPrivSynEditHighlighter, + uRESTDWPrivSynUnicode, +{$IFDEF SYN_CodeFolding} + uRESTDWPrivSynEditCodeFolding, +{$ENDIF} + SysUtils, + Classes; + +type + TtkTokenKind = (tkComment, tkIdentifier, tkKey, tkNull, tkNumber, tkSpace, + tkString, tkSymbol, tkUnknown, tkNonReservedKey, tkEvent); + + TRangeState = (rsUnknown, rsANSI); + + PIdentFuncTableFunc = ^TIdentFuncTableFunc; + TIdentFuncTableFunc = function (Index: Integer): TtkTokenKind of object; + +type +{$IFDEF SYN_CodeFolding} + TSynJScriptSyn = class(TSynCustomCodeFoldingHighlighter) +{$ELSE} + TSynJScriptSyn = class(TSynCustomHighLighter) +{$ENDIF} + private + FRange: TRangeState; + FTokenID: TtkTokenKind; + FIdentFuncTable: array[0..5152] of TIdentFuncTableFunc; + FCommentAttri: TSynHighlighterAttributes; + FIdentifierAttri: TSynHighlighterAttributes; + FKeyAttri: TSynHighlighterAttributes; + FNonReservedKeyAttri: TSynHighlighterAttributes; + FEventAttri: TSynHighlighterAttributes; + FNumberAttri: TSynHighlighterAttributes; + FSpaceAttri: TSynHighlighterAttributes; + FStringAttri: TSynHighlighterAttributes; + FSymbolAttri: TSynHighlighterAttributes; + function AltFunc(Index: Integer): TtkTokenKind; + function FuncAbs(Index: Integer): TtkTokenKind; + function FuncAbstract(Index: Integer): TtkTokenKind; + function FuncAcos(Index: Integer): TtkTokenKind; + function FuncAction(Index: Integer): TtkTokenKind; + function FuncAlert(Index: Integer): TtkTokenKind; + function FuncAlign(Index: Integer): TtkTokenKind; + function FuncAlinkcolor(Index: Integer): TtkTokenKind; + function FuncAll(Index: Integer): TtkTokenKind; + function FuncAnchor(Index: Integer): TtkTokenKind; + function FuncAnchors(Index: Integer): TtkTokenKind; + function FuncAppcodename(Index: Integer): TtkTokenKind; + function FuncApplet(Index: Integer): TtkTokenKind; + function FuncApplets(Index: Integer): TtkTokenKind; + function FuncAppname(Index: Integer): TtkTokenKind; + function FuncAppversion(Index: Integer): TtkTokenKind; + function FuncArea(Index: Integer): TtkTokenKind; + function FuncArguments(Index: Integer): TtkTokenKind; + function FuncArray(Index: Integer): TtkTokenKind; + function FuncAsin(Index: Integer): TtkTokenKind; + function FuncAtan(Index: Integer): TtkTokenKind; + function FuncAtan2(Index: Integer): TtkTokenKind; + function FuncBack(Index: Integer): TtkTokenKind; + function FuncBackground(Index: Integer): TtkTokenKind; + function FuncBgcolor(Index: Integer): TtkTokenKind; + function FuncBig(Index: Integer): TtkTokenKind; + function FuncBlink(Index: Integer): TtkTokenKind; + function FuncBlur(Index: Integer): TtkTokenKind; + function FuncBody(Index: Integer): TtkTokenKind; + function FuncBold(Index: Integer): TtkTokenKind; + function FuncBoolean(Index: Integer): TtkTokenKind; + function FuncBoolean2(Index: Integer): TtkTokenKind; + function FuncBorder(Index: Integer): TtkTokenKind; + function FuncBottom(Index: Integer): TtkTokenKind; + function FuncBreak(Index: Integer): TtkTokenKind; + function FuncButton(Index: Integer): TtkTokenKind; + function FuncByte(Index: Integer): TtkTokenKind; + function FuncCall(Index: Integer): TtkTokenKind; + function FuncCallee(Index: Integer): TtkTokenKind; + function FuncCaller(Index: Integer): TtkTokenKind; + function FuncCaptureevents(Index: Integer): TtkTokenKind; + function FuncCase(Index: Integer): TtkTokenKind; + function FuncCatch(Index: Integer): TtkTokenKind; + function FuncCeil(Index: Integer): TtkTokenKind; + function FuncChar(Index: Integer): TtkTokenKind; + function FuncCharat(Index: Integer): TtkTokenKind; + function FuncCharcodeat(Index: Integer): TtkTokenKind; + function FuncCheckbox(Index: Integer): TtkTokenKind; + function FuncChecked(Index: Integer): TtkTokenKind; + function FuncClass(Index: Integer): TtkTokenKind; + function FuncClear(Index: Integer): TtkTokenKind; + function FuncClearinterval(Index: Integer): TtkTokenKind; + function FuncCleartimeout(Index: Integer): TtkTokenKind; + function FuncClick(Index: Integer): TtkTokenKind; + function FuncClose(Index: Integer): TtkTokenKind; + function FuncClosed(Index: Integer): TtkTokenKind; + function FuncColor(Index: Integer): TtkTokenKind; + function FuncComplete(Index: Integer): TtkTokenKind; + function FuncConcat(Index: Integer): TtkTokenKind; + function FuncConfirm(Index: Integer): TtkTokenKind; + function FuncConst(Index: Integer): TtkTokenKind; + function FuncConstructor(Index: Integer): TtkTokenKind; + function FuncContinue(Index: Integer): TtkTokenKind; + function FuncCookie(Index: Integer): TtkTokenKind; + function FuncCos(Index: Integer): TtkTokenKind; + function FuncCurrent(Index: Integer): TtkTokenKind; + function FuncDate(Index: Integer): TtkTokenKind; + function FuncDebugger(Index: Integer): TtkTokenKind; + function FuncDefault(Index: Integer): TtkTokenKind; + function FuncDefaultchecked(Index: Integer): TtkTokenKind; + function FuncDefaultselected(Index: Integer): TtkTokenKind; + function FuncDefaultstatus(Index: Integer): TtkTokenKind; + function FuncDefaultvalue(Index: Integer): TtkTokenKind; + function FuncDelete(Index: Integer): TtkTokenKind; + function FuncDescription(Index: Integer): TtkTokenKind; + function FuncDisplay(Index: Integer): TtkTokenKind; + function FuncDo(Index: Integer): TtkTokenKind; + function FuncDocument(Index: Integer): TtkTokenKind; + function FuncDomain(Index: Integer): TtkTokenKind; + function FuncDouble(Index: Integer): TtkTokenKind; + function FuncE(Index: Integer): TtkTokenKind; + function FuncElements(Index: Integer): TtkTokenKind; + function FuncElse(Index: Integer): TtkTokenKind; + function FuncEmbed(Index: Integer): TtkTokenKind; + function FuncEmbeds(Index: Integer): TtkTokenKind; + function FuncEnabledplugin(Index: Integer): TtkTokenKind; + function FuncEncoding(Index: Integer): TtkTokenKind; + function FuncEnum(Index: Integer): TtkTokenKind; + function FuncEscape(Index: Integer): TtkTokenKind; + function FuncEval(Index: Integer): TtkTokenKind; + function FuncEvent(Index: Integer): TtkTokenKind; + function FuncExp(Index: Integer): TtkTokenKind; + function FuncExport(Index: Integer): TtkTokenKind; + function FuncExtends(Index: Integer): TtkTokenKind; + function FuncFalse(Index: Integer): TtkTokenKind; + function FuncFgcolor(Index: Integer): TtkTokenKind; + function FuncFilename(Index: Integer): TtkTokenKind; + function FuncFileupload(Index: Integer): TtkTokenKind; + function FuncFinal(Index: Integer): TtkTokenKind; + function FuncFinally(Index: Integer): TtkTokenKind; + function FuncFind(Index: Integer): TtkTokenKind; + function FuncFixed(Index: Integer): TtkTokenKind; + function FuncFloat(Index: Integer): TtkTokenKind; + function FuncFloat2(Index: Integer): TtkTokenKind; + function FuncFloor(Index: Integer): TtkTokenKind; + function FuncFocus(Index: Integer): TtkTokenKind; + function FuncFontcolor(Index: Integer): TtkTokenKind; + function FuncFontsize(Index: Integer): TtkTokenKind; + function FuncFor(Index: Integer): TtkTokenKind; + function FuncForm(Index: Integer): TtkTokenKind; + function FuncForms(Index: Integer): TtkTokenKind; + function FuncForward(Index: Integer): TtkTokenKind; + function FuncFrame(Index: Integer): TtkTokenKind; + function FuncFrames(Index: Integer): TtkTokenKind; + function FuncFromcharcode(Index: Integer): TtkTokenKind; + function FuncFunction(Index: Integer): TtkTokenKind; + function FuncFunction2(Index: Integer): TtkTokenKind; + function FuncGetdate(Index: Integer): TtkTokenKind; + function FuncGetday(Index: Integer): TtkTokenKind; + function FuncGetelementbyid(Index: Integer): TtkTokenKind; + function FuncGetfullyear(Index: Integer): TtkTokenKind; + function FuncGethours(Index: Integer): TtkTokenKind; + function FuncGetmilliseconds(Index: Integer): TtkTokenKind; + function FuncGetminutes(Index: Integer): TtkTokenKind; + function FuncGetmonth(Index: Integer): TtkTokenKind; + function FuncGetseconds(Index: Integer): TtkTokenKind; + function FuncGettime(Index: Integer): TtkTokenKind; + function FuncGettimezoneoffset(Index: Integer): TtkTokenKind; + function FuncGetutcdate(Index: Integer): TtkTokenKind; + function FuncGetutcday(Index: Integer): TtkTokenKind; + function FuncGetutcfullyear(Index: Integer): TtkTokenKind; + function FuncGetutchours(Index: Integer): TtkTokenKind; + function FuncGetutcmilliseconds(Index: Integer): TtkTokenKind; + function FuncGetutcminutes(Index: Integer): TtkTokenKind; + function FuncGetutcmonth(Index: Integer): TtkTokenKind; + function FuncGetutcseconds(Index: Integer): TtkTokenKind; + function FuncGetyear(Index: Integer): TtkTokenKind; + function FuncGlobal(Index: Integer): TtkTokenKind; + function FuncGo(Index: Integer): TtkTokenKind; + function FuncGoto(Index: Integer): TtkTokenKind; + function FuncHandleevent(Index: Integer): TtkTokenKind; + function FuncHash(Index: Integer): TtkTokenKind; + function FuncHeight(Index: Integer): TtkTokenKind; + function FuncHidden(Index: Integer): TtkTokenKind; + function FuncHistory(Index: Integer): TtkTokenKind; + function FuncHome(Index: Integer): TtkTokenKind; + function FuncHost(Index: Integer): TtkTokenKind; + function FuncHostname(Index: Integer): TtkTokenKind; + function FuncHref(Index: Integer): TtkTokenKind; + function FuncHspace(Index: Integer): TtkTokenKind; + function FuncIf(Index: Integer): TtkTokenKind; + function FuncImage(Index: Integer): TtkTokenKind; + function FuncImages(Index: Integer): TtkTokenKind; + function FuncImplements(Index: Integer): TtkTokenKind; + function FuncImport(Index: Integer): TtkTokenKind; + function FuncIn(Index: Integer): TtkTokenKind; + function FuncIndex(Index: Integer): TtkTokenKind; + function FuncIndexof(Index: Integer): TtkTokenKind; + function FuncInfinity(Index: Integer): TtkTokenKind; + function FuncInnerheight(Index: Integer): TtkTokenKind; + function FuncInnerwidth(Index: Integer): TtkTokenKind; + function FuncInput(Index: Integer): TtkTokenKind; + function FuncInstanceof(Index: Integer): TtkTokenKind; + function FuncInt(Index: Integer): TtkTokenKind; + function FuncInterface(Index: Integer): TtkTokenKind; + function FuncIsfinite(Index: Integer): TtkTokenKind; + function FuncIsnan(Index: Integer): TtkTokenKind; + function FuncItalics(Index: Integer): TtkTokenKind; + function FuncJava(Index: Integer): TtkTokenKind; + function FuncJavaenabled(Index: Integer): TtkTokenKind; + function FuncJoin(Index: Integer): TtkTokenKind; + function FuncLastindexof(Index: Integer): TtkTokenKind; + function FuncLastmodified(Index: Integer): TtkTokenKind; + function FuncLayer(Index: Integer): TtkTokenKind; + function FuncLayers(Index: Integer): TtkTokenKind; + function FuncLeft(Index: Integer): TtkTokenKind; + function FuncLength(Index: Integer): TtkTokenKind; + function FuncLink(Index: Integer): TtkTokenKind; + function FuncLinkcolor(Index: Integer): TtkTokenKind; + function FuncLinks(Index: Integer): TtkTokenKind; + function FuncLn10(Index: Integer): TtkTokenKind; + function FuncLn2(Index: Integer): TtkTokenKind; + function FuncLocation(Index: Integer): TtkTokenKind; + function FuncLocationbar(Index: Integer): TtkTokenKind; + function FuncLog(Index: Integer): TtkTokenKind; + function FuncLog10e(Index: Integer): TtkTokenKind; + function FuncLog2e(Index: Integer): TtkTokenKind; + function FuncLogon(Index: Integer): TtkTokenKind; + function FuncLong(Index: Integer): TtkTokenKind; + function FuncLowsrc(Index: Integer): TtkTokenKind; + function FuncMatch(Index: Integer): TtkTokenKind; + function FuncMath(Index: Integer): TtkTokenKind; + function FuncMax(Index: Integer): TtkTokenKind; + function FuncMax_value(Index: Integer): TtkTokenKind; + function FuncMenubar(Index: Integer): TtkTokenKind; + function FuncMethod(Index: Integer): TtkTokenKind; + function FuncMimetype(Index: Integer): TtkTokenKind; + function FuncMimetypes(Index: Integer): TtkTokenKind; + function FuncMin(Index: Integer): TtkTokenKind; + function FuncMin_value(Index: Integer): TtkTokenKind; + function FuncMoveby(Index: Integer): TtkTokenKind; + function FuncMoveto(Index: Integer): TtkTokenKind; + function FuncName(Index: Integer): TtkTokenKind; + function FuncNan(Index: Integer): TtkTokenKind; + function FuncNative(Index: Integer): TtkTokenKind; + function FuncNavigator(Index: Integer): TtkTokenKind; + function FuncNegative_infinity(Index: Integer): TtkTokenKind; + function FuncNetscape(Index: Integer): TtkTokenKind; + function FuncNew(Index: Integer): TtkTokenKind; + function FuncNext(Index: Integer): TtkTokenKind; + function FuncNull(Index: Integer): TtkTokenKind; + function FuncNull2(Index: Integer): TtkTokenKind; + function FuncNumber(Index: Integer): TtkTokenKind; + function FuncObject(Index: Integer): TtkTokenKind; + function FuncOnabort(Index: Integer): TtkTokenKind; + function FuncOnblur(Index: Integer): TtkTokenKind; + function FuncOnchange(Index: Integer): TtkTokenKind; + function FuncOnclick(Index: Integer): TtkTokenKind; + function FuncOndblclick(Index: Integer): TtkTokenKind; + function FuncOnerror(Index: Integer): TtkTokenKind; + function FuncOnfocus(Index: Integer): TtkTokenKind; + function FuncOnkeydown(Index: Integer): TtkTokenKind; + function FuncOnkeypress(Index: Integer): TtkTokenKind; + function FuncOnkeyup(Index: Integer): TtkTokenKind; + function FuncOnload(Index: Integer): TtkTokenKind; + function FuncOnmousedown(Index: Integer): TtkTokenKind; + function FuncOnmousemove(Index: Integer): TtkTokenKind; + function FuncOnmouseout(Index: Integer): TtkTokenKind; + function FuncOnmouseover(Index: Integer): TtkTokenKind; + function FuncOnmouseup(Index: Integer): TtkTokenKind; + function FuncOnreset(Index: Integer): TtkTokenKind; + function FuncOnselect(Index: Integer): TtkTokenKind; + function FuncOnsubmit(Index: Integer): TtkTokenKind; + function FuncOnunload(Index: Integer): TtkTokenKind; + function FuncOpen(Index: Integer): TtkTokenKind; + function FuncOpener(Index: Integer): TtkTokenKind; + function FuncOption(Index: Integer): TtkTokenKind; + function FuncOptions(Index: Integer): TtkTokenKind; + function FuncOuterheight(Index: Integer): TtkTokenKind; + function FuncOuterwidth(Index: Integer): TtkTokenKind; + function FuncPackage(Index: Integer): TtkTokenKind; + function FuncPackages(Index: Integer): TtkTokenKind; + function FuncPagex(Index: Integer): TtkTokenKind; + function FuncPagexoffset(Index: Integer): TtkTokenKind; + function FuncPagey(Index: Integer): TtkTokenKind; + function FuncPageyoffset(Index: Integer): TtkTokenKind; + function FuncParent(Index: Integer): TtkTokenKind; + function FuncParse(Index: Integer): TtkTokenKind; + function FuncParsefloat(Index: Integer): TtkTokenKind; + function FuncParseint(Index: Integer): TtkTokenKind; + function FuncPassword(Index: Integer): TtkTokenKind; + function FuncPathname(Index: Integer): TtkTokenKind; + function FuncPersonalbar(Index: Integer): TtkTokenKind; + function FuncPi(Index: Integer): TtkTokenKind; + function FuncPlatform(Index: Integer): TtkTokenKind; + function FuncPlugin(Index: Integer): TtkTokenKind; + function FuncPlugins(Index: Integer): TtkTokenKind; + function FuncPort(Index: Integer): TtkTokenKind; + function FuncPositive_infinity(Index: Integer): TtkTokenKind; + function FuncPow(Index: Integer): TtkTokenKind; + function FuncPrevious(Index: Integer): TtkTokenKind; + function FuncPrint(Index: Integer): TtkTokenKind; + function FuncPrivate(Index: Integer): TtkTokenKind; + function FuncPrompt(Index: Integer): TtkTokenKind; + function FuncProtected(Index: Integer): TtkTokenKind; + function FuncProtocol(Index: Integer): TtkTokenKind; + function FuncPrototype(Index: Integer): TtkTokenKind; + function FuncPublic(Index: Integer): TtkTokenKind; + function FuncRadio(Index: Integer): TtkTokenKind; + function FuncRandom(Index: Integer): TtkTokenKind; + function FuncReferrer(Index: Integer): TtkTokenKind; + function FuncRefresh(Index: Integer): TtkTokenKind; + function FuncRegexp(Index: Integer): TtkTokenKind; + function FuncReleaseevents(Index: Integer): TtkTokenKind; + function FuncReload(Index: Integer): TtkTokenKind; + function FuncReplace(Index: Integer): TtkTokenKind; + function FuncReset(Index: Integer): TtkTokenKind; + function FuncResizeby(Index: Integer): TtkTokenKind; + function FuncResizeto(Index: Integer): TtkTokenKind; + function FuncReturn(Index: Integer): TtkTokenKind; + function FuncReverse(Index: Integer): TtkTokenKind; + function FuncRight(Index: Integer): TtkTokenKind; + function FuncRound(Index: Integer): TtkTokenKind; + function FuncRouteevent(Index: Integer): TtkTokenKind; + function FuncScreen(Index: Integer): TtkTokenKind; + function FuncScroll(Index: Integer): TtkTokenKind; + function FuncScrollbars(Index: Integer): TtkTokenKind; + function FuncScrollby(Index: Integer): TtkTokenKind; + function FuncScrollto(Index: Integer): TtkTokenKind; + function FuncSearch(Index: Integer): TtkTokenKind; + function FuncSelect(Index: Integer): TtkTokenKind; + function FuncSelected(Index: Integer): TtkTokenKind; + function FuncSelectedindex(Index: Integer): TtkTokenKind; + function FuncSelf(Index: Integer): TtkTokenKind; + function FuncSetdate(Index: Integer): TtkTokenKind; + function FuncSetfullyear(Index: Integer): TtkTokenKind; + function FuncSethours(Index: Integer): TtkTokenKind; + function FuncSetinterval(Index: Integer): TtkTokenKind; + function FuncSetmilliseconds(Index: Integer): TtkTokenKind; + function FuncSetminutes(Index: Integer): TtkTokenKind; + function FuncSetmonth(Index: Integer): TtkTokenKind; + function FuncSetseconds(Index: Integer): TtkTokenKind; + function FuncSettime(Index: Integer): TtkTokenKind; + function FuncSettimeout(Index: Integer): TtkTokenKind; + function FuncSetutcdate(Index: Integer): TtkTokenKind; + function FuncSetutcfullyear(Index: Integer): TtkTokenKind; + function FuncSetutchours(Index: Integer): TtkTokenKind; + function FuncSetutcmilliseconds(Index: Integer): TtkTokenKind; + function FuncSetutcminutes(Index: Integer): TtkTokenKind; + function FuncSetutcmonth(Index: Integer): TtkTokenKind; + function FuncSetutcseconds(Index: Integer): TtkTokenKind; + function FuncSetyear(Index: Integer): TtkTokenKind; + function FuncShort(Index: Integer): TtkTokenKind; + function FuncSin(Index: Integer): TtkTokenKind; + function FuncSlice(Index: Integer): TtkTokenKind; + function FuncSmall(Index: Integer): TtkTokenKind; + function FuncSort(Index: Integer): TtkTokenKind; + function FuncSplit(Index: Integer): TtkTokenKind; + function FuncSqrt(Index: Integer): TtkTokenKind; + function FuncSqrt1_2(Index: Integer): TtkTokenKind; + function FuncSqrt2(Index: Integer): TtkTokenKind; + function FuncSrc(Index: Integer): TtkTokenKind; + function FuncStart(Index: Integer): TtkTokenKind; + function FuncStatic(Index: Integer): TtkTokenKind; + function FuncStatus(Index: Integer): TtkTokenKind; + function FuncStatusbar(Index: Integer): TtkTokenKind; + function FuncStop(Index: Integer): TtkTokenKind; + function FuncStrike(Index: Integer): TtkTokenKind; + function FuncString(Index: Integer): TtkTokenKind; + function FuncStyle(Index: Integer): TtkTokenKind; + function FuncSub(Index: Integer): TtkTokenKind; + function FuncSubmit(Index: Integer): TtkTokenKind; + function FuncSubstr(Index: Integer): TtkTokenKind; + function FuncSubstring(Index: Integer): TtkTokenKind; + function FuncSuffixes(Index: Integer): TtkTokenKind; + function FuncSup(Index: Integer): TtkTokenKind; + function FuncSuper(Index: Integer): TtkTokenKind; + function FuncSwitch(Index: Integer): TtkTokenKind; + function FuncSynchronized(Index: Integer): TtkTokenKind; + function FuncTags(Index: Integer): TtkTokenKind; + function FuncTaint(Index: Integer): TtkTokenKind; + function FuncTaintenabled(Index: Integer): TtkTokenKind; + function FuncTan(Index: Integer): TtkTokenKind; + function FuncTarget(Index: Integer): TtkTokenKind; + function FuncText(Index: Integer): TtkTokenKind; + function FuncTextarea(Index: Integer): TtkTokenKind; + function FuncThis(Index: Integer): TtkTokenKind; + function FuncThrow(Index: Integer): TtkTokenKind; + function FuncThrows(Index: Integer): TtkTokenKind; + function FuncTitle(Index: Integer): TtkTokenKind; + function FuncTogmtstring(Index: Integer): TtkTokenKind; + function FuncTolocalestring(Index: Integer): TtkTokenKind; + function FuncTolowercase(Index: Integer): TtkTokenKind; + function FuncToolbar(Index: Integer): TtkTokenKind; + function FuncTop(Index: Integer): TtkTokenKind; + function FuncTosource(Index: Integer): TtkTokenKind; + function FuncTostring(Index: Integer): TtkTokenKind; + function FuncTouppercase(Index: Integer): TtkTokenKind; + function FuncToutcstring(Index: Integer): TtkTokenKind; + function FuncTransient(Index: Integer): TtkTokenKind; + function FuncTrue(Index: Integer): TtkTokenKind; + function FuncTry(Index: Integer): TtkTokenKind; + function FuncType(Index: Integer): TtkTokenKind; + function FuncTypeof(Index: Integer): TtkTokenKind; + function FuncUndefined(Index: Integer): TtkTokenKind; + function FuncUnescape(Index: Integer): TtkTokenKind; + function FuncUntaint(Index: Integer): TtkTokenKind; + function FuncUnwatch(Index: Integer): TtkTokenKind; + function FuncUrl(Index: Integer): TtkTokenKind; + function FuncUseragent(Index: Integer): TtkTokenKind; + function FuncUtc(Index: Integer): TtkTokenKind; + function FuncValue(Index: Integer): TtkTokenKind; + function FuncValueof(Index: Integer): TtkTokenKind; + function FuncVar(Index: Integer): TtkTokenKind; + function FuncVisibility(Index: Integer): TtkTokenKind; + function FuncVlinkcolor(Index: Integer): TtkTokenKind; + function FuncVoid(Index: Integer): TtkTokenKind; + function FuncVspace(Index: Integer): TtkTokenKind; + function FuncWatch(Index: Integer): TtkTokenKind; + function FuncWhile(Index: Integer): TtkTokenKind; + function FuncWidth(Index: Integer): TtkTokenKind; + function FuncWindow(Index: Integer): TtkTokenKind; + function FuncWith(Index: Integer): TtkTokenKind; + function FuncWrite(Index: Integer): TtkTokenKind; + function FuncWriteln(Index: Integer): TtkTokenKind; + function FuncZindex(Index: Integer): TtkTokenKind; + function HashKey(Str: PWideChar): Cardinal; + function IdentKind(MayBe: PWideChar): TtkTokenKind; + procedure InitIdent; + procedure AndSymbolProc; + procedure CommentProc; + procedure CRProc; + procedure IdentProc; + procedure LFProc; + procedure MinusProc; + procedure ModSymbolProc; + procedure NullProc; + procedure NumberProc; + procedure OrSymbolProc; + procedure PlusProc; + procedure PointProc; + procedure SlashProc; + procedure SpaceProc; + procedure StarProc; + procedure StringProc; + procedure SymbolProc; + procedure UnknownProc; + protected + function GetSampleSource: UnicodeString; override; + function IsFilterStored: Boolean; override; + public + class function GetLanguageName: string; override; + class function GetFriendlyLanguageName: UnicodeString; override; + public + constructor Create(AOwner: TComponent); override; + function GetDefaultAttribute(Index: Integer): TSynHighlighterAttributes; + override; + function GetEol: Boolean; override; + function GetRange: Pointer; override; + function GetTokenID: TtkTokenKind; + function GetTokenAttribute: TSynHighlighterAttributes; override; + function GetTokenKind: Integer; override; + procedure Next; override; + procedure SetRange(Value: Pointer); override; + procedure ResetRange; override; +{$IFDEF SYN_CodeFolding} + procedure ScanForFoldRanges(FoldRanges: TSynFoldRanges; + LinesToScan: TStrings; FromLine: Integer; ToLine: Integer); override; +{$ENDIF} + published + property CommentAttri: TSynHighlighterAttributes read FCommentAttri + write FCommentAttri; + property IdentifierAttri: TSynHighlighterAttributes read FIdentifierAttri + write FIdentifierAttri; + property KeyAttri: TSynHighlighterAttributes read FKeyAttri write FKeyAttri; + property NonReservedKeyAttri: TSynHighlighterAttributes read FNonReservedKeyAttri write FNonReservedKeyAttri; + property EventAttri: TSynHighlighterAttributes read FEventAttri write FEventAttri; + property NumberAttri: TSynHighlighterAttributes read FNumberAttri + write FNumberAttri; + property SpaceAttri: TSynHighlighterAttributes read FSpaceAttri + write FSpaceAttri; + property StringAttri: TSynHighlighterAttributes read FStringAttri + write FStringAttri; + property SymbolAttri: TSynHighlighterAttributes read FSymbolAttri + write FSymbolAttri; + end; + +implementation + +uses + uRESTDWPrivSynEditStrConst; + +const + KeyWords: array[0..398] of UnicodeString = ( + 'abs', 'abstract', 'acos', 'action', 'alert', 'align', 'alinkColor', 'all', + 'All', 'anchor', 'Anchor', 'anchors', 'appCodeName', 'Applet', 'applets', + 'appName', 'appVersion', 'Area', 'arguments', 'Arguments', 'Array', 'asin', + 'atan', 'atan2', 'back', 'background', 'bgColor', 'big', 'blink', 'blur', + 'body', 'bold', 'boolean', 'Boolean', 'border', 'bottom', 'break', 'Button', + 'byte', 'call', 'callee', 'caller', 'captureEvents', 'case', 'catch', + 'ceil', 'char', 'charAt', 'charCodeAt', 'Checkbox', 'checked', 'class', + 'clear', 'clearInterval', 'clearTimeout', 'click', 'close', 'closed', + 'color', 'complete', 'concat', 'confirm', 'const', 'constructor', + 'continue', 'cookie', 'cos', 'current', 'Date', 'debugger', 'default', + 'defaultChecked', 'defaultSelected', 'defaultStatus', 'defaultValue', + 'delete', 'description', 'display', 'do', 'document', 'domain', 'double', + 'E', 'elements', 'else', 'Embed', 'embeds', 'enabledPlugin', 'encoding', + 'enum', 'escape', 'eval', 'event', 'exp', 'export', 'extends', 'false', + 'fgColor', 'filename', 'FileUpload', 'final', 'finally', 'find', 'fixed', + 'float', 'Float', 'floor', 'focus', 'fontcolor', 'fontsize', 'for', 'form', + 'Form', 'forms', 'forward', 'Frame', 'frames', 'fromCharCode', 'function', + 'Function', 'getDate', 'getDay', 'getElementById', 'getFullYear', + 'getHours', 'getMilliseconds', 'getMinutes', 'getMonth', 'getSeconds', + 'getTime', 'getTimezoneOffset', 'getUTCDate', 'getUTCDay', 'getUTCFullYear', + 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', + 'getUTCSeconds', 'getYear', 'Global', 'go', 'goto', 'handleEvent', 'hash', + 'height', 'Hidden', 'history', 'History', 'home', 'host', 'hostname', + 'href', 'hspace', 'if', 'Image', 'images', 'implements', 'import', 'in', + 'index', 'indexOf', 'Infinity', 'innerHeight', 'innerWidth', 'input', + 'instanceof', 'int', 'interface', 'isFinite', 'isNaN', 'italics', 'java', + 'javaEnabled', 'join', 'lastIndexOf', 'lastModified', 'Layer', 'layers', + 'left', 'length', 'link', 'Link', 'linkColor', 'links', 'LN10', 'LN2', + 'location', 'Location', 'locationbar', 'log', 'LOG10E', 'LOG2E', 'logon', + 'long', 'lowsrc', 'match', 'Math', 'max', 'MAX_VALUE', 'menubar', 'method', + 'MimeType', 'mimeTypes', 'min', 'MIN_VALUE', 'moveBy', 'moveTo', 'name', + 'NaN', 'native', 'navigator', 'Navigator', 'NEGATIVE_INFINITY', 'netscape', + 'new', 'next', 'null', 'Null', 'Number', 'Object', 'onAbort', 'onBlur', + 'onChange', 'onClick', 'onDblClick', 'onError', 'onFocus', 'onKeyDown', + 'onKeyPress', 'onKeyUp', 'onLoad', 'onMouseDown', 'onMouseMove', + 'onMouseOut', 'onMouseOver', 'onMouseUp', 'onReset', 'onSelect', 'onSubmit', + 'onUnload', 'open', 'opener', 'Option', 'options', 'outerHeight', + 'outerWidth', 'package', 'Packages', 'pageX', 'pageXOffset', 'pageY', + 'pageYOffset', 'parent', 'parse', 'parseFloat', 'parseInt', 'Password', + 'pathname', 'personalbar', 'PI', 'platform', 'Plugin', 'plugins', 'port', + 'POSITIVE_INFINITY', 'pow', 'previous', 'print', 'private', 'prompt', + 'protected', 'protocol', 'prototype', 'public', 'Radio', 'random', + 'referrer', 'refresh', 'RegExp', 'releaseEvents', 'reload', 'replace', + 'reset', 'Reset', 'resizeBy', 'resizeTo', 'return', 'reverse', 'right', + 'round', 'routeEvent', 'screen', 'scroll', 'scrollbars', 'scrollBy', + 'scrollTo', 'search', 'select', 'Select', 'selected', 'selectedIndex', + 'self', 'setDate', 'setFullYear', 'setHours', 'setInterval', + 'setMilliseconds', 'setMinutes', 'setMonth', 'setSeconds', 'setTime', + 'setTimeout', 'setUTCDate', 'setUTCFullYear', 'setUTCHours', + 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', + 'setYear', 'short', 'sin', 'slice', 'small', 'sort', 'split', 'sqrt', + 'SQRT1_2', 'SQRT2', 'src', 'start', 'static', 'status', 'statusbar', 'stop', + 'strike', 'String', 'style', 'sub', 'submit', 'Submit', 'substr', + 'substring', 'suffixes', 'sup', 'super', 'switch', 'synchronized', 'tags', + 'taint', 'taintEnabled', 'tan', 'target', 'text', 'Text', 'Textarea', + 'this', 'throw', 'throws', 'title', 'toGMTString', 'toLocaleString', + 'toLowerCase', 'toolbar', 'top', 'toSource', 'toString', 'toUpperCase', + 'toUTCString', 'transient', 'true', 'try', 'type', 'typeof', 'undefined', + 'Undefined', 'unescape', 'untaint', 'unwatch', 'URL', 'userAgent', 'UTC', + 'value', 'valueOf', 'var', 'visibility', 'vlinkColor', 'void', 'vspace', + 'watch', 'while', 'width', 'window', 'Window', 'with', 'write', 'writeln', + 'zIndex' + ); + + KeyIndices: array[0..5152] of Integer = ( + -1, -1, -1, -1, -1, -1, -1, -1, -1, 231, -1, -1, -1, -1, -1, 296, -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, 55, + -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, 292, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 168, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 208, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 200, -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, 295, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 75, 351, -1, -1, -1, -1, -1, -1, 315, 37, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 239, -1, -1, -1, -1, -1, 326, -1, -1, -1, 31, + -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, 143, -1, 99, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 339, -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, 241, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, + -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, 235, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 145, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 204, -1, -1, -1, -1, -1, -1, -1, -1, 110, -1, -1, -1, -1, -1, -1, + -1, -1, 16, 52, 389, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 259, -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, 331, 30, -1, -1, -1, -1, -1, -1, + -1, 10, -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, 304, -1, 396, 2, -1, -1, 323, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 167, + -1, -1, -1, -1, -1, -1, -1, 122, -1, -1, -1, -1, -1, -1, -1, -1, -1, 34, -1, + -1, -1, -1, 203, -1, -1, -1, -1, -1, -1, 38, -1, -1, -1, -1, -1, 83, -1, -1, + -1, -1, -1, 101, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 268, -1, -1, -1, -1, -1, -1, -1, -1, 182, -1, -1, -1, -1, -1, 246, 18, -1, + -1, -1, -1, -1, 209, -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, 220, 161, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 134, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 332, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 229, -1, -1, -1, -1, -1, -1, -1, 157, 319, -1, 210, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 234, -1, -1, -1, -1, -1, -1, -1, -1, -1, 105, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 381, 78, -1, + -1, -1, -1, -1, -1, -1, 257, -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, 219, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 196, -1, -1, -1, -1, -1, 379, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 363, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 309, -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, 386, 146, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 103, -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, 269, -1, -1, -1, 199, 172, -1, 15, 123, -1, -1, -1, -1, -1, -1, -1, 136, + -1, -1, -1, 128, -1, -1, -1, -1, 366, -1, -1, 185, -1, -1, -1, -1, 153, -1, + -1, -1, -1, 388, -1, -1, 165, -1, -1, -1, -1, -1, -1, 338, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 360, -1, -1, + 194, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 77, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 307, -1, -1, -1, -1, -1, -1, -1, 258, -1, + -1, -1, 96, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 180, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 69, -1, -1, -1, -1, -1, -1, 129, -1, -1, + -1, -1, -1, -1, -1, -1, 120, -1, -1, 95, -1, 233, -1, -1, -1, -1, -1, -1, + -1, -1, 40, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 160, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 90, 282, -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, 341, 232, 121, 155, -1, + -1, -1, -1, -1, 247, -1, -1, -1, -1, 67, -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, 327, -1, -1, -1, -1, -1, -1, -1, -1, -1, 74, -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, 170, -1, -1, -1, -1, 298, -1, + -1, -1, -1, -1, -1, -1, 114, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 94, -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, 271, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 324, -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, 70, -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, 197, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 91, -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, 106, -1, -1, 237, -1, -1, -1, -1, -1, 6, + -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, 240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 250, -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, 205, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 238, -1, -1, -1, + -1, -1, -1, -1, -1, 275, -1, -1, -1, -1, -1, -1, -1, -1, -1, 287, -1, -1, + -1, -1, -1, -1, -1, 227, -1, -1, 383, -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, + 58, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 29, 148, 171, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 392, -1, -1, -1, -1, -1, 125, -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, 201, -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, 135, -1, -1, 212, + -1, -1, -1, -1, -1, -1, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, 272, -1, -1, + -1, -1, -1, -1, -1, -1, 27, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 334, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 289, -1, -1, -1, -1, 312, -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, 385, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 51, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, -1, -1, -1, -1, -1, -1, 371, 76, + -1, -1, 330, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 68, -1, -1, -1, -1, -1, -1, 225, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 119, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 13, -1, -1, -1, 156, -1, 23, -1, -1, -1, -1, -1, -1, + -1, -1, 280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 178, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 277, -1, -1, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, 93, -1, + -1, -1, -1, -1, -1, -1, 202, -1, 5, 343, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 255, -1, -1, -1, -1, -1, -1, -1, + -1, 43, -1, -1, -1, 44, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 50, -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, 333, -1, -1, -1, -1, -1, 12, -1, -1, -1, -1, 139, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 320, -1, -1, -1, -1, -1, -1, + 214, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 152, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 278, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 302, 316, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 137, -1, -1, -1, + 254, -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, 86, -1, -1, -1, -1, -1, -1, -1, -1, 345, -1, -1, 144, -1, -1, -1, 7, + -1, -1, 306, -1, -1, -1, -1, 113, -1, -1, -1, -1, -1, -1, 308, -1, -1, -1, + -1, 357, -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, 36, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 361, -1, -1, -1, -1, -1, -1, -1, 195, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 387, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 169, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 376, -1, -1, -1, -1, 188, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 359, 98, -1, -1, -1, + -1, -1, -1, -1, 11, -1, -1, -1, -1, -1, 116, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 299, -1, -1, -1, 369, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 54, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 147, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 118, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 356, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 8, -1, 300, -1, -1, 228, 59, -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, 213, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 179, -1, -1, -1, -1, -1, + -1, -1, 176, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 350, -1, -1, -1, -1, + -1, -1, 284, -1, -1, -1, 256, -1, -1, 276, -1, -1, -1, -1, -1, -1, -1, -1, + 190, -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, 102, -1, 230, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 72, -1, 71, 26, -1, -1, -1, -1, + -1, -1, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 322, -1, -1, 175, -1, -1, 393, -1, 124, 85, -1, -1, -1, -1, + -1, -1, -1, -1, 150, -1, 236, -1, -1, -1, -1, -1, -1, -1, -1, -1, 140, -1, + -1, -1, -1, -1, -1, 183, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 111, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 20, -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, + 42, 244, -1, -1, -1, -1, -1, -1, -1, 47, 313, -1, 41, -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, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 64, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 294, -1, -1, -1, -1, -1, -1, -1, -1, 374, -1, -1, -1, -1, -1, -1, -1, 245, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 177, -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, 347, -1, -1, -1, -1, -1, -1, -1, 391, -1, -1, -1, -1, -1, -1, -1, + 217, -1, -1, -1, 87, -1, -1, -1, 329, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 39, -1, -1, -1, -1, -1, -1, -1, -1, 189, -1, -1, 222, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 174, -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, + 274, -1, -1, -1, -1, 33, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 382, -1, -1, -1, 138, 226, -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, 192, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 24, -1, -1, -1, -1, -1, -1, -1, -1, 100, -1, -1, -1, -1, -1, -1, + -1, -1, 318, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 260, -1, -1, -1, -1, -1, -1, 191, -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, 288, -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, 342, -1, -1, -1, -1, -1, -1, + 61, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 377, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 132, -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, 158, -1, -1, 166, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 73, -1, -1, -1, -1, -1, -1, -1, 57, + -1, -1, -1, 211, -1, -1, -1, -1, 243, -1, -1, -1, -1, -1, 264, -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, 321, -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, 207, -1, -1, + 216, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 149, -1, -1, -1, -1, -1, 89, -1, -1, -1, -1, -1, -1, -1, 48, -1, -1, 293, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 117, -1, -1, -1, -1, 242, -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, 56, + -1, 154, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 92, 193, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 325, 126, -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, 206, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 372, -1, -1, -1, 380, -1, -1, + 352, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 263, -1, -1, -1, -1, -1, -1, -1, 373, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 286, -1, 46, -1, -1, -1, -1, 184, -1, -1, -1, -1, -1, -1, 19, + -1, -1, -1, 25, -1, -1, -1, -1, -1, -1, -1, 367, -1, -1, -1, -1, -1, 270, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 283, + -1, -1, -1, -1, -1, -1, -1, -1, 151, -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, 65, -1, -1, -1, + -1, -1, -1, -1, 398, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 252, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 355, -1, -1, 365, -1, -1, -1, + -1, -1, -1, -1, -1, 28, -1, -1, 378, -1, -1, -1, -1, 354, -1, -1, -1, -1, + -1, -1, -1, -1, 349, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 97, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 107, -1, -1, -1, -1, 285, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 215, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 198, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 81, 394, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 358, -1, -1, -1, -1, -1, -1, -1, 173, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 224, -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, 181, -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, 375, + -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, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 9, -1, -1, -1, -1, -1, 305, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 141, + 281, 115, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, -1, -1, -1, -1, -1, + -1, -1, 261, -1, -1, -1, -1, 265, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 273, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 362, -1, 290, -1, 66, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 112, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 131, -1, 279, -1, -1, -1, 249, -1, -1, -1, -1, -1, -1, 223, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 49, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 297, -1, -1, -1, -1, + 127, -1, -1, 142, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 53, -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, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 88, -1, -1, -1, -1, -1, -1, 248, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 395, 251, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 45, -1, -1, -1, -1, -1, -1, -1, -1, 80, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 310, -1, 218, -1, -1, -1, -1, -1, -1, 187, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 130, 390, -1, -1, -1, -1, -1, -1, -1, + 328, -1, 221, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 336, -1, -1, -1, -1, -1, -1, 311, -1, -1, -1, -1, + -1, -1, -1, -1, 303, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 108, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 344, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 337, -1, -1, -1, -1, -1, 262, -1, -1, -1, -1, + -1, -1, -1, 267, -1, -1, -1, -1, -1, -1, -1, 253, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 397, -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, -1, -1, -1, 162, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 109, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 346, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 348, 159, -1, -1, -1, -1, -1, -1, -1, + 368, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 370, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 164, -1, 314, -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, 291, -1, -1, -1, -1, -1, -1, 384, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 82, -1, -1, -1, -1, -1, -1, 340, -1, -1, + -1, -1, -1, -1, 317, -1, 79, -1, -1, -1, -1, 133, -1, -1, -1, -1, -1, -1, + 353, -1, 301, -1, -1, -1, -1, -1, -1, 163, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 266, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 186, -1, -1, -1 + ); + +{$Q-} +function TSynJScriptSyn.HashKey(Str: PWideChar): Cardinal; +begin + Result := 0; + while IsIdentChar(Str^) do + begin + Result := Result * 751 + Ord(Str^) * 148; + Inc(Str); + end; + Result := Result mod 5153; + FStringLen := Str - FToIdent; +end; +{$Q+} + +function TSynJScriptSyn.IdentKind(MayBe: PWideChar): TtkTokenKind; +var + Key: Cardinal; +begin + FToIdent := MayBe; + Key := HashKey(MayBe); + if Key <= High(FIdentFuncTable) then + Result := FIdentFuncTable[Key](KeyIndices[Key]) + else + Result := tkIdentifier; +end; + +procedure TSynJScriptSyn.InitIdent; +var + i: Integer; +begin + for i := Low(FIdentFuncTable) to High(FIdentFuncTable) do + if KeyIndices[i] = -1 then + FIdentFuncTable[i] := AltFunc; + + FIdentFuncTable[4966] := FuncAbs; + FIdentFuncTable[2170] := FuncAbstract; + FIdentFuncTable[520] := FuncAcos; + FIdentFuncTable[319] := FuncAction; + FIdentFuncTable[4368] := FuncAlert; + FIdentFuncTable[2070] := FuncAlign; + FIdentFuncTable[1500] := FuncAlinkcolor; + FIdentFuncTable[2362] := FuncAll; + FIdentFuncTable[2706] := FuncAll; + FIdentFuncTable[4383] := FuncAnchor; + FIdentFuncTable[491] := FuncAnchor; + FIdentFuncTable[2516] := FuncAnchors; + FIdentFuncTable[2207] := FuncAppcodename; + FIdentFuncTable[1993] := FuncApplet; + FIdentFuncTable[1805] := FuncApplets; + FIdentFuncTable[965] := FuncAppname; + FIdentFuncTable[416] := FuncAppversion; + FIdentFuncTable[2052] := FuncArea; + FIdentFuncTable[618] := FuncArguments; + FIdentFuncTable[3950] := FuncArguments; + FIdentFuncTable[2987] := FuncArray; + FIdentFuncTable[4131] := FuncAsin; + FIdentFuncTable[5117] := FuncAtan; + FIdentFuncTable[1999] := FuncAtan2; + FIdentFuncTable[3356] := FuncBack; + FIdentFuncTable[3954] := FuncBackground; + FIdentFuncTable[2882] := FuncBgcolor; + FIdentFuncTable[1824] := FuncBig; + FIdentFuncTable[4067] := FuncBlink; + FIdentFuncTable[1709] := FuncBlur; + FIdentFuncTable[483] := FuncBody; + FIdentFuncTable[243] := FuncBold; + FIdentFuncTable[4200] := FuncBoolean; + FIdentFuncTable[3265] := FuncBoolean2; + FIdentFuncTable[563] := FuncBorder; + FIdentFuncTable[2857] := FuncBottom; + FIdentFuncTable[2410] := FuncBreak; + FIdentFuncTable[223] := FuncButton; + FIdentFuncTable[575] := FuncByte; + FIdentFuncTable[3204] := FuncCall; + FIdentFuncTable[1125] := FuncCallee; + FIdentFuncTable[3049] := FuncCaller; + FIdentFuncTable[3037] := FuncCaptureevents; + FIdentFuncTable[2101] := FuncCase; + FIdentFuncTable[2105] := FuncCatch; + FIdentFuncTable[4662] := FuncCeil; + FIdentFuncTable[3938] := FuncChar; + FIdentFuncTable[3046] := FuncCharat; + FIdentFuncTable[3724] := FuncCharcodeat; + FIdentFuncTable[4522] := FuncCheckbox; + FIdentFuncTable[2127] := FuncChecked; + FIdentFuncTable[1908] := FuncClass; + FIdentFuncTable[417] := FuncClear; + FIdentFuncTable[4574] := FuncClearinterval; + FIdentFuncTable[2626] := FuncCleartimeout; + FIdentFuncTable[55] := FuncClick; + FIdentFuncTable[3783] := FuncClose; + FIdentFuncTable[3615] := FuncClosed; + FIdentFuncTable[1688] := FuncColor; + FIdentFuncTable[2712] := FuncComplete; + FIdentFuncTable[2889] := FuncConcat; + FIdentFuncTable[3503] := FuncConfirm; + FIdentFuncTable[820] := FuncConst; + FIdentFuncTable[3079] := FuncConstructor; + FIdentFuncTable[3092] := FuncContinue; + FIdentFuncTable[4022] := FuncCookie; + FIdentFuncTable[4452] := FuncCos; + FIdentFuncTable[1188] := FuncCurrent; + FIdentFuncTable[1955] := FuncDate; + FIdentFuncTable[1095] := FuncDebugger; + FIdentFuncTable[1389] := FuncDefault; + FIdentFuncTable[2881] := FuncDefaultchecked; + FIdentFuncTable[2879] := FuncDefaultselected; + FIdentFuncTable[3607] := FuncDefaultstatus; + FIdentFuncTable[1234] := FuncDefaultvalue; + FIdentFuncTable[214] := FuncDelete; + FIdentFuncTable[1929] := FuncDescription; + FIdentFuncTable[1046] := FuncDisplay; + FIdentFuncTable[748] := FuncDo; + FIdentFuncTable[5075] := FuncDocument; + FIdentFuncTable[4671] := FuncDomain; + FIdentFuncTable[4176] := FuncDouble; + FIdentFuncTable[5059] := FuncE; + FIdentFuncTable[581] := FuncElements; + FIdentFuncTable[4413] := FuncElse; + FIdentFuncTable[2919] := FuncEmbed; + FIdentFuncTable[2346] := FuncEmbeds; + FIdentFuncTable[3190] := FuncEnabledplugin; + FIdentFuncTable[4627] := FuncEncoding; + FIdentFuncTable[3716] := FuncEnum; + FIdentFuncTable[1147] := FuncEscape; + FIdentFuncTable[1465] := FuncEval; + FIdentFuncTable[3807] := FuncEvent; + FIdentFuncTable[2060] := FuncExp; + FIdentFuncTable[1298] := FuncExport; + FIdentFuncTable[1114] := FuncExtends; + FIdentFuncTable[1069] := FuncFalse; + FIdentFuncTable[4097] := FuncFgcolor; + FIdentFuncTable[2508] := FuncFilename; + FIdentFuncTable[271] := FuncFileupload; + FIdentFuncTable[3365] := FuncFinal; + FIdentFuncTable[587] := FuncFinally; + FIdentFuncTable[2843] := FuncFind; + FIdentFuncTable[931] := FuncFixed; + FIdentFuncTable[1921] := FuncFloat; + FIdentFuncTable[730] := FuncFloat2; + FIdentFuncTable[1491] := FuncFloor; + FIdentFuncTable[4111] := FuncFocus; + FIdentFuncTable[4774] := FuncFontcolor; + FIdentFuncTable[4932] := FuncFontsize; + FIdentFuncTable[407] := FuncFor; + FIdentFuncTable[2968] := FuncForm; + FIdentFuncTable[4469] := FuncForm; + FIdentFuncTable[2370] := FuncForms; + FIdentFuncTable[1279] := FuncForward; + FIdentFuncTable[4402] := FuncFrame; + FIdentFuncTable[2522] := FuncFrames; + FIdentFuncTable[3737] := FuncFromcharcode; + FIdentFuncTable[2666] := FuncFunction; + FIdentFuncTable[1982] := FuncFunction2; + FIdentFuncTable[1111] := FuncGetdate; + FIdentFuncTable[1176] := FuncGetday; + FIdentFuncTable[553] := FuncGetelementbyid; + FIdentFuncTable[966] := FuncGetfullyear; + FIdentFuncTable[2918] := FuncGethours; + FIdentFuncTable[1735] := FuncGetmilliseconds; + FIdentFuncTable[3823] := FuncGetminutes; + FIdentFuncTable[4549] := FuncGetmonth; + FIdentFuncTable[978] := FuncGetseconds; + FIdentFuncTable[1102] := FuncGettime; + FIdentFuncTable[4707] := FuncGettimezoneoffset; + FIdentFuncTable[4493] := FuncGetutcdate; + FIdentFuncTable[3536] := FuncGetutcday; + FIdentFuncTable[5080] := FuncGetutcfullyear; + FIdentFuncTable[671] := FuncGetutchours; + FIdentFuncTable[1795] := FuncGetutcmilliseconds; + FIdentFuncTable[974] := FuncGetutcminutes; + FIdentFuncTable[2302] := FuncGetutcmonth; + FIdentFuncTable[3282] := FuncGetutcseconds; + FIdentFuncTable[2212] := FuncGetyear; + FIdentFuncTable[2940] := FuncGlobal; + FIdentFuncTable[4400] := FuncGo; + FIdentFuncTable[4552] := FuncGoto; + FIdentFuncTable[269] := FuncHandleevent; + FIdentFuncTable[2358] := FuncHash; + FIdentFuncTable[380] := FuncHeight; + FIdentFuncTable[911] := FuncHidden; + FIdentFuncTable[2645] := FuncHistory; + FIdentFuncTable[1710] := FuncHistory; + FIdentFuncTable[3710] := FuncHome; + FIdentFuncTable[2928] := FuncHost; + FIdentFuncTable[3996] := FuncHostname; + FIdentFuncTable[2246] := FuncHref; + FIdentFuncTable[991] := FuncHspace; + FIdentFuncTable[3785] := FuncIf; + FIdentFuncTable[1177] := FuncImage; + FIdentFuncTable[1997] := FuncImages; + FIdentFuncTable[706] := FuncImplements; + FIdentFuncTable[3582] := FuncImport; + FIdentFuncTable[4969] := FuncIn; + FIdentFuncTable[1137] := FuncIndex; + FIdentFuncTable[656] := FuncIndexof; + FIdentFuncTable[4918] := FuncInfinity; + FIdentFuncTable[5096] := FuncInnerheight; + FIdentFuncTable[5008] := FuncInnerwidth; + FIdentFuncTable[999] := FuncInput; + FIdentFuncTable[3585] := FuncInstanceof; + FIdentFuncTable[545] := FuncInt; + FIdentFuncTable[124] := FuncInterface; + FIdentFuncTable[2465] := FuncIsfinite; + FIdentFuncTable[1266] := FuncIsnan; + FIdentFuncTable[1711] := FuncItalics; + FIdentFuncTable[963] := FuncJava; + FIdentFuncTable[4225] := FuncJavaenabled; + FIdentFuncTable[3229] := FuncJoin; + FIdentFuncTable[2913] := FuncLastindexof; + FIdentFuncTable[2778] := FuncLastmodified; + FIdentFuncTable[3139] := FuncLayer; + FIdentFuncTable[2021] := FuncLayers; + FIdentFuncTable[2770] := FuncLeft; + FIdentFuncTable[1083] := FuncLength; + FIdentFuncTable[4263] := FuncLink; + FIdentFuncTable[611] := FuncLink; + FIdentFuncTable[2947] := FuncLinkcolor; + FIdentFuncTable[3943] := FuncLinks; + FIdentFuncTable[986] := FuncLn10; + FIdentFuncTable[5149] := FuncLn2; + FIdentFuncTable[4694] := FuncLocation; + FIdentFuncTable[2489] := FuncLocation; + FIdentFuncTable[3213] := FuncLocationbar; + FIdentFuncTable[2812] := FuncLog; + FIdentFuncTable[3420] := FuncLog10e; + FIdentFuncTable[3346] := FuncLog2e; + FIdentFuncTable[3808] := FuncLogon; + FIdentFuncTable[1030] := FuncLong; + FIdentFuncTable[2430] := FuncLowsrc; + FIdentFuncTable[830] := FuncMatch; + FIdentFuncTable[1454] := FuncMath; + FIdentFuncTable[4163] := FuncMax; + FIdentFuncTable[962] := FuncMax_value; + FIdentFuncTable[165] := FuncMenubar; + FIdentFuncTable[1767] := FuncMethod; + FIdentFuncTable[2068] := FuncMimetype; + FIdentFuncTable[568] := FuncMimetypes; + FIdentFuncTable[398] := FuncMin; + FIdentFuncTable[1580] := FuncMin_value; + FIdentFuncTable[3868] := FuncMoveby; + FIdentFuncTable[3688] := FuncMoveto; + FIdentFuncTable[147] := FuncName; + FIdentFuncTable[624] := FuncNan; + FIdentFuncTable[709] := FuncNative; + FIdentFuncTable[3619] := FuncNavigator; + FIdentFuncTable[1798] := FuncNavigator; + FIdentFuncTable[2749] := FuncNegative_infinity; + FIdentFuncTable[2232] := FuncNetscape; + FIdentFuncTable[4150] := FuncNew; + FIdentFuncTable[3691] := FuncNext; + FIdentFuncTable[3186] := FuncNull; + FIdentFuncTable[4687] := FuncNull2; + FIdentFuncTable[811] := FuncNumber; + FIdentFuncTable[655] := FuncObject; + FIdentFuncTable[4718] := FuncOnabort; + FIdentFuncTable[3216] := FuncOnblur; + FIdentFuncTable[4506] := FuncOnchange; + FIdentFuncTable[4236] := FuncOnclick; + FIdentFuncTable[1962] := FuncOndblclick; + FIdentFuncTable[3283] := FuncOnerror; + FIdentFuncTable[1618] := FuncOnfocus; + FIdentFuncTable[2711] := FuncOnkeydown; + FIdentFuncTable[698] := FuncOnkeypress; + FIdentFuncTable[2845] := FuncOnkeyup; + FIdentFuncTable[9] := FuncOnload; + FIdentFuncTable[1175] := FuncOnmousedown; + FIdentFuncTable[1116] := FuncOnmousemove; + FIdentFuncTable[720] := FuncOnmouseout; + FIdentFuncTable[356] := FuncOnmouseover; + FIdentFuncTable[2930] := FuncOnmouseup; + FIdentFuncTable[1494] := FuncOnreset; + FIdentFuncTable[1591] := FuncOnselect; + FIdentFuncTable[233] := FuncOnsubmit; + FIdentFuncTable[1527] := FuncOnunload; + FIdentFuncTable[309] := FuncOpen; + FIdentFuncTable[3742] := FuncOpener; + FIdentFuncTable[3624] := FuncOption; + FIdentFuncTable[3038] := FuncOptions; + FIdentFuncTable[3129] := FuncOuterheight; + FIdentFuncTable[617] := FuncOuterwidth; + FIdentFuncTable[1183] := FuncPackage; + FIdentFuncTable[4634] := FuncPackages; + FIdentFuncTable[4499] := FuncPagex; + FIdentFuncTable[1543] := FuncPagexoffset; + FIdentFuncTable[4647] := FuncPagey; + FIdentFuncTable[4043] := FuncPageyoffset; + FIdentFuncTable[4818] := FuncParent; + FIdentFuncTable[2306] := FuncParse; + FIdentFuncTable[2092] := FuncParsefloat; + FIdentFuncTable[2800] := FuncParseint; + FIdentFuncTable[756] := FuncPassword; + FIdentFuncTable[1065] := FuncPathname; + FIdentFuncTable[433] := FuncPersonalbar; + FIdentFuncTable[3413] := FuncPi; + FIdentFuncTable[4421] := FuncPlatform; + FIdentFuncTable[4802] := FuncPlugin; + FIdentFuncTable[3917] := FuncPlugins; + FIdentFuncTable[3630] := FuncPort; + FIdentFuncTable[4426] := FuncPositive_infinity; + FIdentFuncTable[5137] := FuncPow; + FIdentFuncTable[4810] := FuncPrevious; + FIdentFuncTable[602] := FuncPrint; + FIdentFuncTable[958] := FuncPrivate; + FIdentFuncTable[3968] := FuncPrompt; + FIdentFuncTable[1326] := FuncProtected; + FIdentFuncTable[1815] := FuncProtocol; + FIdentFuncTable[4437] := FuncPrototype; + FIdentFuncTable[3260] := FuncPublic; + FIdentFuncTable[1600] := FuncRadio; + FIdentFuncTable[2803] := FuncRandom; + FIdentFuncTable[2045] := FuncReferrer; + FIdentFuncTable[2270] := FuncRefresh; + FIdentFuncTable[4495] := FuncRegexp; + FIdentFuncTable[2008] := FuncReleaseevents; + FIdentFuncTable[4401] := FuncReload; + FIdentFuncTable[1148] := FuncReplace; + FIdentFuncTable[3987] := FuncReset; + FIdentFuncTable[2796] := FuncReset; + FIdentFuncTable[4116] := FuncResizeby; + FIdentFuncTable[3936] := FuncResizeto; + FIdentFuncTable[1610] := FuncReturn; + FIdentFuncTable[3457] := FuncReverse; + FIdentFuncTable[1857] := FuncRight; + FIdentFuncTable[4450] := FuncRound; + FIdentFuncTable[5041] := FuncRouteevent; + FIdentFuncTable[100] := FuncScreen; + FIdentFuncTable[3727] := FuncScroll; + FIdentFuncTable[3112] := FuncScrollbars; + FIdentFuncTable[195] := FuncScrollby; + FIdentFuncTable[15] := FuncScrollto; + FIdentFuncTable[4544] := FuncSearch; + FIdentFuncTable[1271] := FuncSelect; + FIdentFuncTable[2532] := FuncSelect; + FIdentFuncTable[2708] := FuncSelected; + FIdentFuncTable[5089] := FuncSelectedindex; + FIdentFuncTable[2283] := FuncSelf; + FIdentFuncTable[4756] := FuncSetdate; + FIdentFuncTable[517] := FuncSetfullyear; + FIdentFuncTable[4389] := FuncSethours; + FIdentFuncTable[2365] := FuncSetinterval; + FIdentFuncTable[1057] := FuncSetmilliseconds; + FIdentFuncTable[2377] := FuncSetminutes; + FIdentFuncTable[867] := FuncSetmonth; + FIdentFuncTable[4685] := FuncSetseconds; + FIdentFuncTable[4747] := FuncSettime; + FIdentFuncTable[1862] := FuncSettimeout; + FIdentFuncTable[3047] := FuncSetutcdate; + FIdentFuncTable[5010] := FuncSetutcfullyear; + FIdentFuncTable[222] := FuncSetutchours; + FIdentFuncTable[2284] := FuncSetutcmilliseconds; + FIdentFuncTable[5073] := FuncSetutcminutes; + FIdentFuncTable[3374] := FuncSetutcmonth; + FIdentFuncTable[707] := FuncSetutcseconds; + FIdentFuncTable[2225] := FuncSetyear; + FIdentFuncTable[3661] := FuncShort; + FIdentFuncTable[2910] := FuncSin; + FIdentFuncTable[523] := FuncSlice; + FIdentFuncTable[1345] := FuncSmall; + FIdentFuncTable[3822] := FuncSort; + FIdentFuncTable[239] := FuncSplit; + FIdentFuncTable[1224] := FuncSqrt; + FIdentFuncTable[4716] := FuncSqrt1_2; + FIdentFuncTable[3194] := FuncSqrt2; + FIdentFuncTable[1932] := FuncSrc; + FIdentFuncTable[482] := FuncStart; + FIdentFuncTable[684] := FuncStatic; + FIdentFuncTable[2201] := FuncStatus; + FIdentFuncTable[1836] := FuncStatusbar; + FIdentFuncTable[3389] := FuncStop; + FIdentFuncTable[4740] := FuncStrike; + FIdentFuncTable[4796] := FuncString; + FIdentFuncTable[1006] := FuncStyle; + FIdentFuncTable[283] := FuncSub; + FIdentFuncTable[5066] := FuncSubmit; + FIdentFuncTable[1174] := FuncSubmit; + FIdentFuncTable[3496] := FuncSubstr; + FIdentFuncTable[2071] := FuncSubstring; + FIdentFuncTable[4785] := FuncSuffixes; + FIdentFuncTable[2355] := FuncSup; + FIdentFuncTable[4953] := FuncSuper; + FIdentFuncTable[3170] := FuncSwitch; + FIdentFuncTable[4968] := FuncSynchronized; + FIdentFuncTable[4084] := FuncTags; + FIdentFuncTable[2789] := FuncTaint; + FIdentFuncTable[215] := FuncTaintenabled; + FIdentFuncTable[3896] := FuncTan; + FIdentFuncTable[5087] := FuncTarget; + FIdentFuncTable[4075] := FuncText; + FIdentFuncTable[4055] := FuncText; + FIdentFuncTable[2681] := FuncTextarea; + FIdentFuncTable[2382] := FuncThis; + FIdentFuncTable[4217] := FuncThrow; + FIdentFuncTable[2507] := FuncThrows; + FIdentFuncTable[1027] := FuncTitle; + FIdentFuncTable[2422] := FuncTogmtstring; + FIdentFuncTable[4448] := FuncTolocalestring; + FIdentFuncTable[857] := FuncTolowercase; + FIdentFuncTable[4611] := FuncToolbar; + FIdentFuncTable[4058] := FuncTop; + FIdentFuncTable[983] := FuncTosource; + FIdentFuncTable[3962] := FuncTostring; + FIdentFuncTable[4977] := FuncTouppercase; + FIdentFuncTable[2536] := FuncToutcstring; + FIdentFuncTable[4990] := FuncTransient; + FIdentFuncTable[1928] := FuncTrue; + FIdentFuncTable[3889] := FuncTry; + FIdentFuncTable[3925] := FuncType; + FIdentFuncTable[3121] := FuncTypeof; + FIdentFuncTable[4305] := FuncUndefined; + FIdentFuncTable[2484] := FuncUndefined; + FIdentFuncTable[3518] := FuncUnescape; + FIdentFuncTable[4070] := FuncUntaint; + FIdentFuncTable[836] := FuncUnwatch; + FIdentFuncTable[3893] := FuncUrl; + FIdentFuncTable[747] := FuncUseragent; + FIdentFuncTable[3278] := FuncUtc; + FIdentFuncTable[1621] := FuncValue; + FIdentFuncTable[5048] := FuncValueof; + FIdentFuncTable[1890] := FuncVar; + FIdentFuncTable[910] := FuncVisibility; + FIdentFuncTable[2454] := FuncVlinkcolor; + FIdentFuncTable[996] := FuncVoid; + FIdentFuncTable[418] := FuncVspace; + FIdentFuncTable[4708] := FuncWatch; + FIdentFuncTable[3178] := FuncWhile; + FIdentFuncTable[1729] := FuncWidth; + FIdentFuncTable[2916] := FuncWindow; + FIdentFuncTable[4177] := FuncWindow; + FIdentFuncTable[4646] := FuncWith; + FIdentFuncTable[519] := FuncWrite; + FIdentFuncTable[4841] := FuncWriteln; + FIdentFuncTable[4030] := FuncZindex; +end; + +function TSynJScriptSyn.AltFunc(Index: Integer): TtkTokenKind; +begin + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncAbs(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncAbstract(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncAcos(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncAction(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncAlert(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncAlign(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncAlinkcolor(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncAll(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncAnchor(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncAnchors(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncAppcodename(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncApplet(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncApplets(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncAppname(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncAppversion(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncArea(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncArguments(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncArray(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncAsin(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncAtan(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncAtan2(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncBack(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncBackground(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncBgcolor(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncBig(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncBlink(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncBlur(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncBody(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncBold(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncBoolean(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncBoolean2(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + + +function TSynJScriptSyn.FuncBorder(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncBottom(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncBreak(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncButton(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncByte(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncCall(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncCallee(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncCaller(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncCaptureevents(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncCase(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncCatch(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncCeil(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncChar(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncCharat(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncCharcodeat(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncCheckbox(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncChecked(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncClass(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncClear(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncClearinterval(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncCleartimeout(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncClick(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncClose(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncClosed(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncColor(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncComplete(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncConcat(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncConfirm(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncConst(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncConstructor(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncContinue(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncCookie(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncCos(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncCurrent(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncDate(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncDebugger(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncDefault(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncDefaultchecked(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncDefaultselected(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncDefaultstatus(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncDefaultvalue(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncDelete(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncDescription(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncDisplay(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncDo(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncDocument(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncDomain(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncDouble(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncE(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncElements(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncElse(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncEmbed(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncEmbeds(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncEnabledplugin(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncEncoding(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncEnum(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncEscape(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncEval(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncEvent(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncExp(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncExport(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncExtends(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFalse(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFgcolor(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFilename(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFileupload(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFinal(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFinally(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFind(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFixed(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFloat(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFloat2(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFloor(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFocus(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFontcolor(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFontsize(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFor(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncForm(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncForms(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncForward(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFrame(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFrames(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFromcharcode(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFunction(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncFunction2(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGetdate(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGetday(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGetelementbyid(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGetfullyear(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGethours(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGetmilliseconds(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGetminutes(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGetmonth(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGetseconds(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGettime(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGettimezoneoffset(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGetutcdate(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGetutcday(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGetutcfullyear(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGetutchours(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGetutcmilliseconds(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGetutcminutes(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGetutcmonth(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGetutcseconds(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGetyear(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGlobal(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGo(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncGoto(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncHandleevent(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncHash(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncHeight(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncHidden(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncHistory(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncHome(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncHost(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncHostname(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncHref(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncHspace(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncIf(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncImage(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncImages(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncImplements(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncImport(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncIn(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncIndex(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncIndexof(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncInfinity(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncInnerheight(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncInnerwidth(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncInput(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncInstanceof(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncInt(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncInterface(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncIsfinite(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncIsnan(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncItalics(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncJava(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncJavaenabled(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncJoin(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLastindexof(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLastmodified(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLayer(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLayers(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLeft(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLength(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLink(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLinkcolor(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLinks(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLn10(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLn2(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLocation(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLocationbar(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLog(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLog10e(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLog2e(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLogon(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLong(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncLowsrc(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncMatch(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncMath(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncMax(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncMax_value(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncMenubar(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncMethod(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncMimetype(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncMimetypes(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncMin(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncMin_value(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncMoveby(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncMoveto(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncName(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncNan(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncNative(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncNavigator(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncNegative_infinity(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncNetscape(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncNew(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncNext(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncNull(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncNull2(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncNumber(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncObject(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnabort(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnblur(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnchange(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnclick(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOndblclick(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnerror(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnfocus(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnkeydown(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnkeypress(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnkeyup(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnload(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnmousedown(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnmousemove(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnmouseout(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnmouseover(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnmouseup(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnreset(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnselect(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnsubmit(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOnunload(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkEvent + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOpen(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOpener(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOption(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOptions(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOuterheight(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncOuterwidth(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPackage(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPackages(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPagex(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPagexoffset(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPagey(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPageyoffset(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncParent(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncParse(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncParsefloat(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncParseint(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPassword(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPathname(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPersonalbar(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPi(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPlatform(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPlugin(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPlugins(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPort(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPositive_infinity(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPow(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPrevious(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPrint(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPrivate(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPrompt(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncProtected(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncProtocol(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPrototype(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncPublic(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncRadio(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncRandom(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncReferrer(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncRefresh(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncRegexp(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncReleaseevents(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncReload(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncReplace(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncReset(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncResizeby(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncResizeto(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncReturn(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncReverse(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncRight(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncRound(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncRouteevent(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncScreen(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncScroll(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncScrollbars(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncScrollby(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncScrollto(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSearch(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSelect(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSelected(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSelectedindex(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSelf(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSetdate(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSetfullyear(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSethours(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSetinterval(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSetmilliseconds(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSetminutes(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSetmonth(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSetseconds(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSettime(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSettimeout(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSetutcdate(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSetutcfullyear(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSetutchours(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSetutcmilliseconds(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSetutcminutes(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSetutcmonth(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSetutcseconds(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSetyear(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncShort(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSin(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSlice(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSmall(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSort(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSplit(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSqrt(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSqrt1_2(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSqrt2(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSrc(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncStart(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncStatic(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncStatus(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncStatusbar(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncStop(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncStrike(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncString(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncStyle(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSub(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSubmit(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSubstr(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSubstring(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSuffixes(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSup(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSuper(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSwitch(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncSynchronized(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncTags(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncTaint(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncTaintenabled(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncTan(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncTarget(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncText(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncTextarea(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncThis(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncThrow(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncThrows(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncTitle(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncTogmtstring(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncTolocalestring(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncTolowercase(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncToolbar(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncTop(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncTosource(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncTostring(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncTouppercase(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncToutcstring(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncTransient(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncTrue(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncTry(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncType(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncTypeof(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncUndefined(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncUnescape(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncUntaint(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncUnwatch(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncUrl(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncUseragent(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncUtc(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncValue(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncValueof(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncVar(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncVisibility(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncVlinkcolor(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncVoid(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncVspace(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncWatch(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncWhile(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncWidth(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncWindow(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncWith(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncWrite(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncWriteln(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +function TSynJScriptSyn.FuncZindex(Index: Integer): TtkTokenKind; +begin + if IsCurrentToken(KeyWords[Index]) then + Result := tkNonReservedKey + else + Result := tkIdentifier; +end; + +constructor TSynJScriptSyn.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + + FCaseSensitive := True; + + FCommentAttri := TSynHighlighterAttributes.Create(SYNS_AttrComment, SYNS_FriendlyAttrComment); + FCommentAttri.Style := [fsItalic]; + AddAttribute(FCommentAttri); + FIdentifierAttri := TSynHighlighterAttributes.Create(SYNS_AttrIdentifier, SYNS_FriendlyAttrIdentifier); + AddAttribute(FIdentifierAttri); + FKeyAttri := TSynHighlighterAttributes.Create(SYNS_AttrReservedWord, SYNS_FriendlyAttrReservedWord); + FKeyAttri.Style := [fsBold]; + AddAttribute(FKeyAttri); + FNonReservedKeyAttri := TSynHighlighterAttributes.Create(SYNS_AttrNonReservedKeyword, SYNS_FriendlyAttrNonReservedKeyword); + AddAttribute(FNonReservedKeyAttri); + FEventAttri := TSynHighlighterAttributes.Create(SYNS_AttrEvent, SYNS_FriendlyAttrEvent); + AddAttribute(FEventAttri); + FNumberAttri := TSynHighlighterAttributes.Create(SYNS_AttrNumber, SYNS_FriendlyAttrNumber); + AddAttribute(FNumberAttri); + FSpaceAttri := TSynHighlighterAttributes.Create(SYNS_AttrSpace, SYNS_FriendlyAttrSpace); + AddAttribute(FSpaceAttri); + FStringAttri := TSynHighlighterAttributes.Create(SYNS_AttrString, SYNS_FriendlyAttrString); + AddAttribute(FStringAttri); + FSymbolAttri := TSynHighlighterAttributes.Create(SYNS_AttrSymbol, SYNS_FriendlyAttrSymbol); + AddAttribute(FSymbolAttri); + SetAttributesOnChange(DefHighlightChange); + InitIdent; + FDefaultFilter := SYNS_FilterJScript; + FRange := rsUnknown; +end; + +procedure TSynJScriptSyn.AndSymbolProc; +begin + FTokenID := tkSymbol; + Inc(Run); + if CharInSet(FLine[Run], ['=', '&']) then Inc(Run); +end; + +procedure TSynJScriptSyn.CommentProc; +begin + if FLine[Run] = #0 then + NullProc + else + begin + FTokenID := tkComment; + repeat + if (FLine[Run] = '*') and (FLine[Run + 1] = '/') then + begin + FRange := rsUnknown; + Inc(Run, 2); + Break; + end; + Inc(Run); + until IsLineEnd(Run); + end; +end; + +procedure TSynJScriptSyn.CRProc; +begin + FTokenID := tkSpace; + Inc(Run); + if FLine[Run] = #10 then Inc(Run); +end; + +procedure TSynJScriptSyn.IdentProc; +begin + FTokenID := IdentKind((FLine + Run)); + Inc(Run, FStringLen); + while IsIdentChar(FLine[Run]) do Inc(Run); +end; + +procedure TSynJScriptSyn.LFProc; +begin + FTokenID := tkSpace; + Inc(Run); +end; + +procedure TSynJScriptSyn.MinusProc; +begin + FTokenID := tkSymbol; + Inc(Run); + if CharInSet(FLine[Run], ['=', '-', '>']) then Inc(Run); +end; + +procedure TSynJScriptSyn.ModSymbolProc; +begin + FTokenID := tkSymbol; + Inc(Run); + if FLine[Run] = '=' then Inc(Run); +end; + +procedure TSynJScriptSyn.NullProc; +begin + FTokenID := tkNull; + Inc(Run); +end; + +procedure TSynJScriptSyn.NumberProc; + + function IsNumberChar: Boolean; + begin + case FLine[Run] of + '0'..'9', '.', 'a'..'f', 'A'..'F', 'x', 'X': + Result := True; + else + Result := False; + end; + end; + + function IsHexChar(Run: Integer): Boolean; + begin + case FLine[Run] of + '0'..'9', 'a'..'f', 'A'..'F': + Result := True; + else + Result := False; + end; + end; + +var + idx1: Integer; // token[1] + isHex: Boolean; +begin + FTokenID := tkNumber; + isHex := False; + idx1 := Run; + Inc(Run); + while IsNumberChar do + begin + case FLine[Run] of + '.': + if FLine[Succ(Run)] = '.' then + Break; + 'a'..'f', 'A'..'F': + if not isHex then + Break; + 'x', 'X': + begin + if (FLine[idx1] <> '0') or (Run > Succ(idx1)) then + Break; + if not IsHexChar(Succ(Run)) then + Break; + isHex := True; + end; + end; + Inc(Run); + end; +end; + +procedure TSynJScriptSyn.OrSymbolProc; +begin + FTokenID := tkSymbol; + Inc(Run); + if CharInSet(FLine[Run], ['=', '|']) then Inc(Run); +end; + +procedure TSynJScriptSyn.PlusProc; +begin + FTokenID := tkSymbol; + Inc(Run); + if CharInSet(FLine[Run], ['=', '+']) then Inc(Run); +end; + +procedure TSynJScriptSyn.PointProc; +begin + FTokenID := tkSymbol; + Inc(Run); + if (FLine[Run] = '.') and (FLine[Run + 1] = '.') then Inc(Run, 2); +end; + +procedure TSynJScriptSyn.SlashProc; +begin + Inc(Run); + case FLine[Run] of + '/': begin + FTokenID := tkComment; + repeat + Inc(Run); + until IsLineEnd(Run); + end; + '*': begin + FTokenID := tkComment; + FRange := rsAnsi; + repeat + Inc(Run); + if (FLine[Run] = '*') and (FLine[Run + 1] = '/') then begin + FRange := rsUnknown; + Inc(Run, 2); + Break; + end; + until IsLineEnd(Run); + end; + '=': begin + Inc(Run); + FTokenID := tkSymbol; + end; + else + FTokenID := tkSymbol; + end; +end; + +procedure TSynJScriptSyn.SpaceProc; +begin + Inc(Run); + FTokenID := tkSpace; + while (FLine[Run] <= #32) and not IsLineEnd(Run) do Inc(Run); +end; + +procedure TSynJScriptSyn.StarProc; +begin + FTokenID := tkSymbol; + Inc(Run); + if FLine[Run] = '=' then Inc(Run); +end; + +procedure TSynJScriptSyn.StringProc; +var + l_strChar: UnicodeString; +begin + FTokenID := tkString; + l_strChar := FLine[Run]; // We could have '"' or #39 + if (FLine[Run + 1] = l_strChar) and (FLine[Run + 2] = l_strChar) then Inc(Run, 2); + repeat + if IsLineEnd(Run) then + Break; + Inc(Run); + until (FLine[Run] = l_strChar) and (FLine[Pred(Run)] <> '\'); + if not IsLineEnd(Run) then + Inc(Run); +end; + +procedure TSynJScriptSyn.SymbolProc; +begin + Inc(Run); + FTokenID := tkSymbol; +end; + +procedure TSynJScriptSyn.UnknownProc; +begin + Inc(Run); + FTokenID := tkUnknown; +end; + +procedure TSynJScriptSyn.Next; +begin + FTokenPos := Run; + if FRange = rsANSI then + CommentProc + else + case FLine[Run] of + '&': AndSymbolProc; + #13: CRProc; + 'A'..'Z', 'a'..'z', '_': IdentProc; + #10: LFProc; + '-': MinusProc; + '%': ModSymbolProc; + #0: NullProc; + '0'..'9': NumberProc; + '|': OrSymbolProc; + '+': PlusProc; + '.': PointProc; + '/': SlashProc; + #1..#9, #11, #12, #14..#32: SpaceProc; + '*': StarProc; + '"', #39: StringProc; + '~', '{', '}', ',', '(', ')', '[', ']', '<', '>', ':', '?', ';', '!', '=': + SymbolProc; + else UnknownProc; + end; + inherited; +end; + +function TSynJScriptSyn.GetDefaultAttribute(Index: Integer): TSynHighlighterAttributes; +begin + case Index of + SYN_ATTR_COMMENT: Result := FCommentAttri; + SYN_ATTR_IDENTIFIER: Result := FIdentifierAttri; + SYN_ATTR_KEYWORD: Result := FKeyAttri; + SYN_ATTR_STRING: Result := FStringAttri; + SYN_ATTR_WHITESPACE: Result := FSpaceAttri; + SYN_ATTR_SYMBOL: Result := FSymbolAttri; + else + Result := nil; + end; +end; + +function TSynJScriptSyn.GetEol: Boolean; +begin + Result := Run = FLineLen + 1; +end; + +function TSynJScriptSyn.GetRange: Pointer; +begin + Result := Pointer(FRange); +end; + +function TSynJScriptSyn.GetTokenID: TtkTokenKind; +begin + Result := FTokenID; +end; + +function TSynJScriptSyn.GetTokenAttribute: TSynHighlighterAttributes; +begin + case GetTokenID of + tkComment: Result := FCommentAttri; + tkIdentifier: Result := FIdentifierAttri; + tkKey: Result := FKeyAttri; + tkNonReservedKey: Result := FNonReservedKeyAttri; + tkEvent: Result := FEventAttri; + tkNumber: Result := FNumberAttri; + tkSpace: Result := FSpaceAttri; + tkString: Result := FStringAttri; + tkSymbol: Result := FSymbolAttri; + tkUnknown: Result := FIdentifierAttri; + else Result := nil; + end; +end; + +function TSynJScriptSyn.GetTokenKind: Integer; +begin + Result := Ord(FTokenID); +end; + +procedure TSynJScriptSyn.ResetRange; +begin + FRange := rsUnknown; +end; + +{$IFDEF SYN_CodeFolding} +procedure TSynJScriptSyn.ScanForFoldRanges(FoldRanges: TSynFoldRanges; + LinesToScan: TStrings; FromLine, ToLine: Integer); +var + CurLine: String; + Line: Integer; + + function LineHasChar(Line: Integer; character: char; + StartCol : Integer): boolean; // faster than Pos! + var + i: Integer; + begin + result := false; + for I := StartCol to Length(CurLine) do begin + if CurLine[i] = character then begin + // Char must have proper highlighting (ignore stuff inside comments...) + if GetHighlighterAttriAtRowCol(LinesToScan, Line, I) <> fCommentAttri then begin + result := true; + break; + end; + end; + end; + end; + + function FindBraces(Line: Integer) : Boolean; + Var + Col : Integer; + begin + Result := False; + + for Col := 1 to Length(CurLine) do + begin + // We've found a starting character + if CurLine[col] = '{' then + begin + // Char must have proper highlighting (ignore stuff inside comments...) + if GetHighlighterAttriAtRowCol(LinesToScan, Line, Col) <> fCommentAttri then + begin + // And ignore lines with both opening and closing chars in them + if not LineHasChar(Line, '}', col + 1) then begin + FoldRanges.StartFoldRange(Line + 1, 1); + Result := True; + end; + // Skip until a newline + break; + end; + end else if CurLine[col] = '}' then + begin + if GetHighlighterAttriAtRowCol(LinesToScan, Line, Col) <> fCommentAttri then + begin + // And ignore lines with both opening and closing chars in them + if not LineHasChar(Line, '{', col + 1) then begin + FoldRanges.StopFoldRange(Line + 1, 1); + Result := True; + end; + // Skip until a newline + break; + end; + end; + end; // for Col + end; + + function FoldRegion(Line: Integer): Boolean; + Var + S : string; + begin + Result := False; + S := TrimLeft(CurLine); + if Uppercase(Copy(S, 1, 9)) = '//#REGION' then + begin + FoldRanges.StartFoldRange(Line + 1, FoldRegionType); + Result := True; + end + else if Uppercase(Copy(S, 1, 12)) = '//#ENDREGION' then + begin + FoldRanges.StopFoldRange(Line + 1, FoldRegionType); + Result := True; + end; + end; + +begin + for Line := FromLine to ToLine do + begin + // Deal first with Multiline comments (Fold Type 2) + if TRangeState(GetLineRange(LinesToScan, Line)) = rsANSI then + begin + if TRangeState(GetLineRange(LinesToScan, Line - 1)) <> rsANSI then + FoldRanges.StartFoldRange(Line + 1, 2) + else + FoldRanges.NoFoldInfo(Line + 1); + Continue; + end + else if TRangeState(GetLineRange(LinesToScan, Line - 1)) = rsANSI then + begin + FoldRanges.StopFoldRange(Line + 1, 2); + Continue; + end; + + CurLine := LinesToScan[Line]; + + // Skip empty lines + if CurLine = '' then begin + FoldRanges.NoFoldInfo(Line + 1); + Continue; + end; + + // Find Fold regions + if FoldRegion(Line) then + Continue; + + // Find an braces on this line (Fold Type 1) + if not FindBraces(Line) then + FoldRanges.NoFoldInfo(Line + 1); + end; // while Line +end; +{$ENDIF} + +procedure TSynJScriptSyn.SetRange(Value: Pointer); +begin + FRange := TRangeState(Value); +end; + +function TSynJScriptSyn.IsFilterStored: Boolean; +begin + Result := FDefaultFilter <> SYNS_FilterJScript; +end; + +class function TSynJScriptSyn.GetLanguageName: string; +begin + Result := SYNS_LangJScript; +end; + +function TSynJScriptSyn.GetSampleSource: UnicodeString; +begin + Result := '// Syntax highlighting'#13#10+ + 'function printNumber()'#13#10+ + '{'#13#10+ + ' var number = 1234;'#13#10+ + ' var x;'#13#10+ + ' document.write("The number is " + number);'#13#10+ + ' for (var i = 0; i <= number; i++)'#13#10+ + ' {'#13#10+ + ' x++;'#13#10+ + ' x--;'#13#10+ + ' x += 1.0;'#13#10+ + ' }'#13#10+ + ' i += @; // illegal character'#13#10+ + '}'#13#10+ + 'body.onLoad = printNumber;'; +end; + +class function TSynJScriptSyn.GetFriendlyLanguageName: UnicodeString; +begin + Result := SYNS_FriendlyLangJScript; +end; + +initialization +{$IFNDEF SYN_CPPB_1} + RegisterPlaceableHighlighter(TSynJScriptSyn); +{$ENDIF} +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterMulti.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterMulti.pas new file mode 100644 index 000000000..1cc2bcda9 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynHighlighterMulti.pas @@ -0,0 +1,1113 @@ +{------------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: uRESTDWPrivSynHighlighterMulti.pas, released 2000-06-23. +The Original Code is based on mwMultiSyn.pas by Willo van der Merwe, part of the +mwEdit component suite. +Unicode translation by Mal Hrz. + +Contributors to the uRESTDWPrivSynEdit and mwEdit projects are listed in the +Contributors.txt file. + +Alternatively, the contents of this file may be used under the terms of the +GNU General Public License Version 2 or later (the "GPL"), in which case +the provisions of the GPL are applicable instead of those above. +If you wish to allow use of your version of this file only under the terms +of the GPL and not to allow others to use your version of this file +under the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the GPL. +If you do not delete the provisions above, a recipient may use your version +of this file under either the MPL or the GPL. + +$Id: uRESTDWPrivSynHighlighterMulti.pas,v 1.34.2.11 2008/09/14 16:25:00 maelh Exp $ + +You may retrieve the latest version of this file at the uRESTDWPrivSynEdit home page, +located at http://uRESTDWPrivSynEdit.SourceForge.net + +Known Issues: +-------------------------------------------------------------------------------} +{ +@abstract(Provides a Multiple-highlighter syntax highlighter for uRESTDWPrivSynEdit) +@author(Willo van der Merwe , converted to uRESTDWPrivSynEdit by David Muir ) +@created(1999, converted to uRESTDWPrivSynEdit 2000-06-23) +@lastmod(2000-06-23) +The uRESTDWPrivSynHighlighterMulti unit provides uRESTDWPrivSynEdit with a multiple-highlighter syntax highlighter. +This highlighter can be used to highlight text in which several languages are present, such as HTML. +For example, in HTML as well as HTML tags there can also be JavaScript and/or VBScript present. +} + +unit uRESTDWPrivSynHighlighterMulti; + +{$I uRESTDWPrivSynEdit.inc} + +interface + +uses + Windows, + uRESTDWPrivSynEditTypes, + uRESTDWPrivSynEditHighlighter, + uRESTDWPrivSynUnicode, + Classes; + +type + TOnCheckMarker = procedure (Sender: TObject; var StartPos, MarkerLen: Integer; + var MarkerText: UnicodeString; Line: Integer; const LineStr: string) of object; + + TScheme = class(TCollectionItem) + private + FEndExpr: UnicodeString; + FStartExpr: UnicodeString; + FHighlighter: TSynCustomHighLighter; + FMarkerAttri: TSynHighlighterAttributes; + FSchemeName: TComponentName; + FCaseSensitive: Boolean; + FOnCheckStartMarker: TOnCheckMarker; + FOnCheckEndMarker: TOnCheckMarker; + function ConvertExpression(const Value: UnicodeString): UnicodeString; + procedure MarkerAttriChanged(Sender: TObject); + procedure SetMarkerAttri(const Value: TSynHighlighterAttributes); + procedure SetHighlighter(const Value: TSynCustomHighlighter); + procedure SetEndExpr(const Value: UnicodeString); + procedure SetStartExpr(const Value: UnicodeString); + procedure SetCaseSensitive(const Value: Boolean); + protected + procedure DefineProperties(Filer: TFiler); override; +{$IFDEF SYN_COMPILER_3_UP} + function GetDisplayName: string; override; + procedure SetDisplayName(const Value: string); override; +{$ENDIF} + public + constructor Create(Collection: TCollection); override; + destructor Destroy; override; + published + property CaseSensitive: Boolean read FCaseSensitive write SetCaseSensitive + default True; + property StartExpr: UnicodeString read FStartExpr write SetStartExpr; + property EndExpr: UnicodeString read FEndExpr write SetEndExpr; + property Highlighter: TSynCustomHighlighter read FHighlighter + write SetHighlighter; + property MarkerAttri: TSynHighlighterAttributes read FMarkerAttri + write SetMarkerAttri; + property SchemeName: TComponentName read FSchemeName write FSchemeName; + property OnCheckStartMarker: TOnCheckMarker read FOnCheckStartMarker write FOnCheckStartMarker; + property OnCheckEndMarker: TOnCheckMarker read FOnCheckEndMarker write FOnCheckEndMarker; + end; + + TgmSchemeClass = class of TScheme; + + TSynMultiSyn = class; + + TSchemes = class(TCollection) + private + FOwner: TSynMultiSyn; + function GetItems(Index: Integer): TScheme; + procedure SetItems(Index: Integer; const Value: TScheme); +{$IFDEF SYN_COMPILER_3_UP} + protected + function GetOwner: TPersistent; override; + procedure Update(Item: TCollectionItem); override; +{$ENDIF} + public + constructor Create(aOwner: TSynMultiSyn); + property Items[aIndex: Integer]: TScheme read GetItems write SetItems; + default; + end; + + TMarker = class + protected + FScheme: Integer; + FStartPos: Integer; + FMarkerLen: Integer; + FMarkerText: UnicodeString; + FIsOpenMarker: Boolean; + public + constructor Create(aScheme, aStartPos, aMarkerLen: Integer; + aIsOpenMarker: Boolean; const aMarkerText: UnicodeString); + end; + + + TRangeOperation = (roGet, roSet); + +{$IFDEF SYN_COMPILER_16_UP} + TRangeUNativeInt = NativeUInt; +{$ELSE} + TRangeUNativeInt = Cardinal; +{$ENDIF} + TRangeProc = procedure (Operation: TRangeOperation; var Range: TRangeUNativeInt) of object; + + TCustomRangeEvent = procedure (Sender: TSynMultiSyn; Operation: TRangeOperation; + var Range: Pointer) of object; + + { + * Usage notes * + If you don't need to nest MultiSyns as Schemes, just as DefaultHighlighter, + you can nest up to 2 MultiSyns, each of them containing up to 7 Schemes. This + is the way MultiSyn works best. (implemented in NewRangeProc) + If you need to use a MultiSyn nested as Scheme, then you can nest up to + 5 MultiSyns, but Ranges aren't persisted across occurrences of Schemes that + have multiple lines. (implemented in OldRangeProc) + Clarification: when I say "you can nest up to X" MultiSyns, I mean having + X+1 levels of MultiSyns. + + MultiSyn doesn't work by default with dynamic highlighters; you must use + OnCustomRange. This is because dynamic highlighters' Ranges are pointers, + but MultiSyn needs Ranges to be ordinal values smaller than 16 (4 bits). + + OnCustomRange: + When Operation is roGet, user should store in the 'Range' parameter the + information to allow restoring the current state of the highlighter. + When Operation is roSet, user should restore highlighter state (CurrScheme, + DefaultHighlighter.Range and, if the case, Schemes[CurrScheme].Range) + according to 'Range' value. + CurrScheme: + Index of the scheme that is currently parsing. DefaultHighlighter maps to -1. + + * Implementation notes * + FTmpRange: + Using the OldRangeProc, FTmpRange was the only way to restore the Range + of the DefaultHighlighter after a Scheme spanned across multiple lines. + With the NewRangeProc, the only use for it is restoring DefaultHighLighter's + Range in case a nested MultiSyn uses the highlighter too. + } + + TSynMultiSyn = class(TSynCustomHighlighter) + private + FRangeProc: TRangeProc; + FDefaultLanguageName: string; + FMarkers: TList; + FMarker: TMarker; + FNextMarker: Integer; + FCurrScheme: Integer; + FTmpRange: Pointer; + FOnCustomRange: TCustomRangeEvent; + FLineStr: UnicodeString; + procedure SetDefaultHighlighter(const Value: TSynCustomHighLighter); + function GetMarkers(Index: Integer): TMarker; + property Markers[Index: Integer]: TMarker read GetMarkers; + procedure DoCheckMarker(Scheme:TScheme; StartPos, MarkerLen: Integer; + const MarkerText: UnicodeString; Start: Boolean; Line: Integer; + const LineStr: string); + procedure SetOnCustomRange(const Value: TCustomRangeEvent); + protected + FSchemes: TSchemes; + FDefaultHighlighter: TSynCustomHighLighter; + FLineNumber: Integer; + FSampleSource: UnicodeString; + procedure Loaded; override; + procedure SetSchemes(const Value: TSchemes); + procedure ClearMarkers; + function GetDefaultAttribute(Index: Integer): TSynHighlighterAttributes; override; + function GetAttribCount: Integer; override; + function GetAttribute(Index: Integer): TSynHighlighterAttributes; override; + procedure HookHighlighter(aHL: TSynCustomHighlighter); + procedure UnhookHighlighter(aHL: TSynCustomHighlighter); + procedure Notification(aComp: TComponent; aOp: TOperation); override; + function GetSampleSource: UnicodeString; override; + procedure SetSampleSource(Value: UnicodeString); override; + procedure DoSetLine(const Value: UnicodeString; LineNumber: Integer); override; + // + procedure OldRangeProc(Operation: TRangeOperation; var Range: TRangeUNativeInt); + procedure NewRangeProc(Operation: TRangeOperation; var Range: TRangeUNativeInt); + procedure UserRangeProc(Operation: TRangeOperation; var Range: TRangeUNativeInt); + public + class function GetLanguageName: string; override; + class function GetFriendlyLanguageName: UnicodeString; override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + function GetEol: Boolean; override; + function GetExpandedToken: UnicodeString; override; + function GetRange: Pointer; override; + function GetToken: UnicodeString; override; + function GetTokenAttribute: TSynHighlighterAttributes; override; + function GetTokenKind: Integer; override; + procedure Next; override; + procedure SetRange(Value: Pointer); override; + procedure ResetRange; override; + function UpdateRangeProcs: Boolean; + property CurrScheme: Integer read FCurrScheme write FCurrScheme; + property CurrLine: UnicodeString read FLineStr; + function LoadFromRegistry(RootKey: HKEY; Key: string): Boolean; override; + function SaveToRegistry(RootKey: HKEY; Key: string): Boolean; override; + function IsIdentChar(AChar: WideChar): Boolean; override; + published + property Schemes: TSchemes read FSchemes write SetSchemes; + property DefaultHighlighter: TSynCustomHighLighter read FDefaultHighlighter + write SetDefaultHighlighter; + property DefaultLanguageName: string read FDefaultLanguageName + write FDefaultLanguageName; + property OnCustomRange: TCustomRangeEvent read FOnCustomRange write SetOnCustomRange; + end; + +implementation + +uses + Graphics, + uRESTDWPrivSynEditMiscProcs, + uRESTDWPrivSynRegExpr, + uRESTDWPrivSynEditStrConst, + SysUtils; + +procedure CheckExpression(const Expr: UnicodeString); +var + Parser: TRegExpr; +begin + Parser := TRegExpr.Create; + try + Parser.Expression := Expr; + try + Parser.Compile; + except + on E: ERegExpr do + begin + if E.ErrorCode < 1000 then + E.Message := Format('"%s" is not a valid Regular Expression.'#13'Error (pos %d): %s', + [Expr, E.CompilerErrorPos, Copy(Parser.ErrorMsg(E.ErrorCode), 16, MaxInt)]); + raise; + end; + end; + finally + Parser.Free; + end; +end; + +{ TMarker } + +constructor TMarker.Create(aScheme, aStartPos, + aMarkerLen: Integer; aIsOpenMarker: Boolean; const aMarkerText: UnicodeString); +begin + FScheme := aScheme; + FStartPos := aStartPos; + FMarkerLen := aMarkerLen; + FIsOpenMarker := aIsOpenMarker; + FMarkerText := aMarkerText; +end; + +{ TSynMultiSyn } + +procedure TSynMultiSyn.ClearMarkers; +var + i: Integer; +begin + for i := 0 to FMarkers.Count - 1 do + TObject(FMarkers[i]).Free; + FMarkers.Clear; +end; + +constructor TSynMultiSyn.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + FSchemes := TSchemes.Create(Self); + FCurrScheme := -1; + FMarkers := TList.Create; + FRangeProc := NewRangeProc; +end; + +destructor TSynMultiSyn.Destroy; +begin + ClearMarkers; + { unhook notification handlers } + Schemes.Clear; + DefaultHighlighter := nil; + inherited Destroy; + FSchemes.Free; + FMarkers.Free; +end; + +function TSynMultiSyn.GetAttribCount: Integer; +var + i: Integer; +begin + Result := Schemes.Count; + if DefaultHighlighter <> nil then + Inc(Result, DefaultHighlighter.AttrCount); + for i := 0 to Schemes.Count - 1 do + if Schemes[i].Highlighter <> nil then + Inc(Result, Schemes[i].Highlighter.AttrCount); +end; + +function TSynMultiSyn.GetAttribute(Index: Integer): TSynHighlighterAttributes; +var + i: Integer; + HL: TSynCustomHighlighter; +begin + if Index < Schemes.Count then + Result := Schemes[Index].MarkerAttri + else + begin + Dec(Index, Schemes.Count); + if DefaultHighlighter <> nil then + if Index < DefaultHighlighter.AttrCount then + begin + Result := DefaultHighlighter.Attribute[Index]; + Exit; + end + else + Dec(Index, DefaultHighlighter.AttrCount); + for i := 0 to Schemes.Count - 1 do + begin + HL := Schemes[i].Highlighter; + if HL <> nil then + if Index < HL.AttrCount then + begin + Result := HL.Attribute[Index]; + Exit; + end + else + Dec(Index, HL.AttrCount); + end; + Result := nil; + end; +end; + +function TSynMultiSyn.GetDefaultAttribute(Index: Integer): TSynHighlighterAttributes; +var + HL: TSynCustomHighlighter; +begin + if (CurrScheme >= 0) and (Schemes[CurrScheme].Highlighter <> nil) then + HL := Schemes[CurrScheme].Highlighter + else + HL := DefaultHighlighter; + { the typecast to TSynMultiSyn is only necessary because the + GetDefaultAttribute method is protected. + And don't worry: this really works } + if HL <> nil then + Result := TSynMultiSyn(HL).GetDefaultAttribute(Index) + else + Result := nil; +end; + +function TSynMultiSyn.GetEol: Boolean; +begin + if FMarker <> nil then + Result := False + else if FCurrScheme >= 0 then + Result := Schemes[CurrScheme].Highlighter.GetEol + else if DefaultHighlighter <> nil then + Result := DefaultHighlighter.GetEol + else + Result := Run > FLineLen + 1; +end; + +class function TSynMultiSyn.GetLanguageName: string; +begin + Result := SYNS_LangGeneralMulti; +end; + +function TSynMultiSyn.GetMarkers(Index: Integer): TMarker; +begin + Result := TMarker(FMarkers[Index]); +end; + +procedure TSynMultiSyn.OldRangeProc(Operation: TRangeOperation; var Range: TRangeUNativeInt); +const + MaxNestedMultiSyn = 6; + { number of bits of the Range that will be used to store the SchemeIndex } + SchemeIndexSize = 4; + MaxSchemeCount = (1 shl SchemeIndexSize) - 1; + { number of bits of the Range that will be used to store the SchemeRange } + SchemeRangeSize = 8; + MaxSchemeRange = (1 shl SchemeRangeSize) - 1; +var + iHL: TSynCustomHighlighter; + iSchemeIndex: Cardinal; + iSchemeRange: Cardinal; +begin + if Operation = roGet then + begin + if (FCurrScheme < 0) then + iHL := DefaultHighlighter + else + iHL := Schemes[FCurrScheme].Highlighter; + iSchemeIndex := FCurrScheme + 2; + Assert(iSchemeIndex <= MaxSchemeCount); + if iHL <> nil then + begin + iSchemeRange := Cardinal(iHL.GetRange); + Assert((iSchemeRange <= MaxSchemeRange) or (iHL is TSynMultiSyn)); + end + else + iSchemeRange := 0; + { checks the limit of nested MultiSyns } + Assert(iSchemeRange shr ((MaxNestedMultiSyn - 1) * SchemeIndexSize + SchemeRangeSize) = 0); + iSchemeRange := (iSchemeRange shl SchemeIndexSize) or iSchemeIndex; + Range := iSchemeRange; + end + else + begin + if Range = 0 then + Exit; + iSchemeRange := Cardinal(Range); + FCurrScheme := Integer(iSchemeRange and MaxSchemeCount) - 2; + iSchemeRange := iSchemeRange shr SchemeIndexSize; + if (CurrScheme < 0) then + begin + if DefaultHighlighter <> nil then + DefaultHighlighter.SetRange(Pointer(iSchemeRange)); + end + else + Schemes[CurrScheme].Highlighter.SetRange(Pointer(iSchemeRange)); + end; +end; + +function TSynMultiSyn.GetToken: UnicodeString; +begin + if DefaultHighlighter = nil then + Result := FLineStr + else + Result := inherited GetToken; +end; + +function TSynMultiSyn.GetTokenAttribute: TSynHighlighterAttributes; +begin + if FMarker <> nil then + Result := Schemes[FMarker.FScheme].MarkerAttri + else if CurrScheme >= 0 then + Result := Schemes[CurrScheme].Highlighter.GetTokenAttribute + else if DefaultHighlighter <> nil then + Result := DefaultHighlighter.GetTokenAttribute + else + Result := nil; +end; + +function TSynMultiSyn.GetTokenKind: Integer; +begin + if FMarker <> nil then + Result := 0 + else if FCurrScheme >= 0 then + Result := Schemes[FCurrScheme].Highlighter.GetTokenKind + else if DefaultHighlighter <> nil then + Result := DefaultHighlighter.GetTokenKind + else + Result := 0; +end; + +procedure TSynMultiSyn.HookHighlighter(aHL: TSynCustomHighlighter); +begin + aHL.FreeNotification(Self); + aHL.HookAttrChangeEvent(DefHighlightChange); +end; + +procedure TSynMultiSyn.Next; +var + iToken, TmpLine, ExpandedTmpLine: UnicodeString; + iHL: TSynCustomHighlighter; +begin + if DefaultHighlighter = nil then + begin + if Run > 0 then + Inc(Run) + else + Run := Length(FLineStr) + 1; + inherited; + Exit; + end; + + if (FNextMarker < FMarkers.Count) and (Run + 1 >= Markers[FNextMarker].FStartPos) then + begin + FMarker := Markers[FNextMarker]; + if FMarker.FIsOpenMarker then + begin + FCurrScheme := FMarker.FScheme; + FTmpRange := DefaultHighlighter.GetRange; + Schemes[CurrScheme].Highlighter.ResetRange; + end; + Inc(FNextMarker); + FTokenPos := Run; + Inc(Run, FMarker.FMarkerLen); + inherited; + Exit; + end; + + if Run = 0 then + begin + if CurrScheme >= 0 then + iHL := Schemes[CurrScheme].Highlighter + else + iHL := DefaultHighlighter; + + if FMarkers.Count = 0 then + TmpLine := FLineStr + else + TmpLine := Copy(FLineStr, 1, Markers[FNextMarker].FStartPos - 1); + + if fExpandedLine <> nil then + begin + if FMarkers.Count = 0 then + ExpandedTmpLine := FExpandedLineStr + else + ExpandedTmpLine := Copy(FExpandedLineStr, 1, + PosToExpandedPos(Markers[FNextMarker].FStartPos - 1)); + iHL.SetLineExpandedAtWideGlyphs(TmpLine, ExpandedTmpLine, FLineNumber); + end + else + iHL.SetLine(TmpLine, FLineNumber); + end + else if FMarker <> nil then + begin + if not FMarker.FIsOpenMarker then + begin + FCurrScheme := -1; + DefaultHighlighter.SetRange(FTmpRange); + end; + FMarker := nil; + + if CurrScheme >= 0 then + iHL := Schemes[CurrScheme].Highlighter + else + iHL := DefaultHighlighter; + + if FNextMarker < FMarkers.Count then + TmpLine := Copy(FLineStr, Run + 1, Markers[FNextMarker].FStartPos - Run - 1) + else + TmpLine := Copy(FLineStr, Run + 1, MaxInt); + + if fExpandedLine <> nil then + begin + if FNextMarker < FMarkers.Count then + ExpandedTmpLine := Copy(FExpandedLineStr, FExpandedRun + 1, + PosToExpandedPos(Markers[FNextMarker].FStartPos - Run - 1)) + else + ExpandedTmpLine := Copy(FExpandedLineStr, FExpandedRun + 1, MaxInt); + + iHL.SetLineExpandedAtWideGlyphs(TmpLine, ExpandedTmpLine, FLineNumber); + end + else + iHL.SetLine(TmpLine, FLineNumber); + end + else + begin + if CurrScheme >= 0 then + iHL := Schemes[CurrScheme].Highlighter + else + iHL := DefaultHighlighter; + iHL.Next; + end; + + FTokenPos := iHL.GetTokenPos; + iToken := iHL.GetToken; + if FNextMarker > 0 then + with Markers[FNextMarker - 1] do + Inc(FTokenPos, FStartPos + FMarkerLen - 1); + Inc(Run, (FTokenPos - Run) + Length(iToken)); + inherited; +end; + +procedure TSynMultiSyn.Notification(aComp: TComponent; aOp: TOperation); +var + i: Integer; +begin + inherited; + // 'opRemove' doesn't mean the component is being destroyed. It means it's + // being removed from its Owner's list of Components. + if (aOp = opRemove) and (aComp is TSynCustomHighlighter) and + (csDestroying in aComp.ComponentState) then + begin + if DefaultHighlighter = aComp then + DefaultHighlighter := nil; + for i := 0 to Schemes.Count - 1 do + if Schemes[i].Highlighter = aComp then + Schemes[i].Highlighter := nil; + end; +end; + +procedure TSynMultiSyn.ResetRange; +begin + FCurrScheme := -1; + if DefaultHighlighter <> nil then + begin + DefaultHighlighter.ResetRange; + FTmpRange := DefaultHighlighter.GetRange; + end; +end; + +procedure TSynMultiSyn.SetDefaultHighlighter( + const Value: TSynCustomHighLighter); +const + sDefaultHlSetToSelf = 'A SynMultiSyn cannot be its own DefaultHighlighter.'; +begin + if DefaultHighlighter <> Value then begin + if Value = Self then + raise Exception.Create(sDefaultHlSetToSelf); + if DefaultHighlighter <> nil then + UnhookHighlighter(DefaultHighlighter); + FDefaultHighlighter := Value; + if DefaultHighlighter <> nil then + HookHighlighter(DefaultHighlighter); + DefHighlightChange(Self); + end; +end; + +procedure TSynMultiSyn.DoCheckMarker(Scheme:TScheme; StartPos, MarkerLen: Integer; + const MarkerText: UnicodeString; Start: Boolean; Line: Integer; + const LineStr: string); +var + aStartPos: Integer; + aMarkerLen: Integer; + aMarkerText: UnicodeString; +begin + aStartPos := StartPos; + aMarkerLen := MarkerLen; + aMarkerText := MarkerText; + if Start and Assigned(Scheme.OnCheckStartMarker) then + Scheme.OnCheckStartMarker(Self, aStartPos, aMarkerLen, aMarkerText, Line, LineStr) + else if not Start and Assigned(Scheme.OnCheckEndMarker) then + Scheme.OnCheckEndMarker(Self, aStartPos, aMarkerLen, aMarkerText, Line, LineStr); + if (aMarkerText <> '') and (aMarkerLen > 0) then + begin + FMarkers.Add(TMarker.Create(Scheme.Index, aStartPos, aMarkerLen, Start, + aMarkerText)); + end; +end; + +procedure TSynMultiSyn.SetSchemes(const Value: TSchemes); +begin + FSchemes.Assign(Value); +end; + +procedure TSynMultiSyn.UnhookHighlighter(aHL: TSynCustomHighlighter); +begin + aHL.UnhookAttrChangeEvent(DefHighlightChange); +{$IFDEF SYN_COMPILER_5_UP} + aHL.RemoveFreeNotification(Self); +{$ENDIF} +end; + +function TSynMultiSyn.GetSampleSource: UnicodeString; +begin + Result := FSampleSource; +end; + +procedure TSynMultiSyn.SetSampleSource(Value: UnicodeString); +begin + FSampleSource := Value; +end; + +function TSynMultiSyn.LoadFromRegistry(RootKey: HKEY; + Key: string): Boolean; +var + r: TBetterRegistry; + i: Integer; +begin + if DefaultHighlighter <> nil then + Result := DefaultHighlighter.LoadFromRegistry(RootKey, Key + '\DefaultHighlighter') + else + Result := False; + r := TBetterRegistry.Create; + try + r.RootKey := RootKey; + for i := 0 to Schemes.Count-1 do + if (Schemes[i].SchemeName <> '') and + r.OpenKeyReadOnly(Key + '\' + Schemes[i].SchemeName) then + begin + Result := Schemes[i].MarkerAttri.LoadFromRegistry(r) and Result; + r.CloseKey; + Result := (Schemes[i].Highlighter <> nil) and + Schemes[i].Highlighter.LoadFromRegistry(RootKey, + Key + '\' + Schemes[i].SchemeName) and Result; + end + else + Result := False; + finally + r.Free; + end; +end; + +function TSynMultiSyn.SaveToRegistry(RootKey: HKEY; Key: string): Boolean; +var + r: TBetterRegistry; + i: Integer; +begin + if DefaultHighlighter <> nil then + Result := DefaultHighlighter.SaveToRegistry(RootKey, Key + '\DefaultHighlighter') + else + Result := False; + r := TBetterRegistry.Create; + try + r.RootKey := RootKey; + for i := 0 to Schemes.Count-1 do + if (Schemes[i].SchemeName <> '') and + r.OpenKey(Key + '\' + Schemes[i].SchemeName, True) then + begin + Result := Schemes[i].MarkerAttri.SaveToRegistry(r) and Result; + r.CloseKey; + Result := (Schemes[i].Highlighter <> nil) and + Schemes[i].Highlighter.SaveToRegistry(RootKey, + Key + '\' + Schemes[i].SchemeName) and Result; + end + else + Result := False; + finally + r.Free; + end; +end; + +function TSynMultiSyn.GetRange: Pointer; +begin + Result := nil; + FRangeProc(roGet, TRangeUNativeInt(Result)); +end; + +procedure TSynMultiSyn.SetRange(Value: Pointer); +begin + FRangeProc(roSet, TRangeUNativeInt(Value)); +end; + +procedure TSynMultiSyn.NewRangeProc(Operation: TRangeOperation; var Range: TRangeUNativeInt); +const + SchemeIndexSize = 3; + MaxSchemeCount = (1 shl SchemeIndexSize) - 1; + SchemeRangeSize = 4; + MaxSchemeRange = (1 shl SchemeRangeSize) - 1; +begin + if Operation = roGet then + begin + if DefaultHighlighter <> nil then + Range := Cardinal(DefaultHighlighter.GetRange) + else + Range := 0; + if CurrScheme >= 0 then + begin + Assert(Cardinal(Schemes[CurrScheme].Highlighter.GetRange) <= MaxSchemeRange); + Range := Range shl SchemeRangeSize; + Range := Range or Cardinal(Schemes[CurrScheme].Highlighter.GetRange); + end; + Assert(CurrScheme <= MaxSchemeCount); + Range := Range shl SchemeIndexSize; + Range := Range or Cardinal(CurrScheme + 1); + end + else + begin + CurrScheme := Integer(Range and MaxSchemeCount) - 1; + Range := Range shr SchemeIndexSize; + if CurrScheme >= 0 then + begin + Schemes[CurrScheme].Highlighter.SetRange(Pointer(Range and MaxSchemeRange)); + Range := Range shr SchemeRangeSize; + end; + if DefaultHighlighter <> nil then + begin + FTmpRange := Pointer(Range); + DefaultHighlighter.SetRange(FTmpRange); + end; + end; +end; + +function TSynMultiSyn.UpdateRangeProcs: Boolean; +// determines the appropriate RangeProcs and returns whether they were changed +var + i: Integer; + OldProc: TRangeProc; +begin + OldProc := FRangeProc; + if Assigned(OnCustomRange) then + FRangeProc := UserRangeProc + else begin + FRangeProc := NewRangeProc; + for i := 0 to Schemes.Count -1 do + if Schemes[i].Highlighter is TSynMultiSyn then + begin + FRangeProc := OldRangeProc; + Break; + end; + end; + Result := TMethod(OldProc).Code <> TMethod(FRangeProc).Code; + if Result then + DefHighlightChange(Self); +end; + +procedure TSynMultiSyn.UserRangeProc(Operation: TRangeOperation; var Range: TRangeUNativeInt); +begin + OnCustomRange(Self, Operation, Pointer(Range)); + if (Operation = roSet) and (DefaultHighlighter <> nil) then + FTmpRange := DefaultHighlighter.GetRange; +end; + +procedure TSynMultiSyn.SetOnCustomRange(const Value: TCustomRangeEvent); +begin + if (TMethod(OnCustomRange).Code <> TMethod(Value).Code) or + (TMethod(OnCustomRange).Data <> TMethod(Value).Data) then + begin + FOnCustomRange := Value; + UpdateRangeProcs; + end; +end; + +procedure TSynMultiSyn.Loaded; +begin + inherited; + DefHighlightChange(Self); +end; + +function TSynMultiSyn.IsIdentChar(AChar: WideChar): Boolean; +begin + if CurrScheme >= 0 then + Result := Schemes[CurrScheme].Highlighter.IsIdentChar(AChar) + else if DefaultHighlighter <> nil then + Result := DefaultHighlighter.IsIdentChar(AChar) + else + Result := inherited IsIdentChar(AChar); +end; + +class function TSynMultiSyn.GetFriendlyLanguageName: UnicodeString; +begin + Result := SYNS_FriendlyLangGeneralMulti; +end; + +procedure TSynMultiSyn.DoSetLine(const Value: UnicodeString; LineNumber: Integer); +var + iParser: TRegExpr; + iScheme: TScheme; + iExpr: UnicodeString; + iLine: UnicodeString; + iEaten: Integer; + i: Integer; +begin + ClearMarkers; + + iParser := TRegExpr.Create; + try + iEaten := 0; + iLine := Value; + if CurrScheme >= 0 + then + iScheme := FSchemes[CurrScheme] + else + iScheme := nil; + while iLine <> '' do + if iScheme <> nil then + begin + iParser.Expression := iScheme.EndExpr; + iParser.ModifierI := not iScheme.CaseSensitive; + if iParser.Exec(iLine) then + begin + iExpr := Copy(Value, iParser.MatchPos[0] + iEaten, iParser.MatchLen[0]); + DoCheckMarker(iScheme, iParser.MatchPos[0] + iEaten, iParser.MatchLen[0], + iExpr, False, LineNumber, Value); + Delete(iLine, 1, iParser.MatchPos[0] - 1 + iParser.MatchLen[0]); + Inc(iEaten, iParser.MatchPos[0] - 1 + iParser.MatchLen[0]); + iScheme := nil; + end + else + Break; + end + else + begin + for i := 0 to Schemes.Count - 1 do + begin + iScheme := Schemes[i]; + if (iScheme.StartExpr = '') or (iScheme.EndExpr = '') or + (iScheme.Highlighter = nil) or (not iScheme.Highlighter.Enabled) then + begin + continue; + end; + iParser.Expression := iScheme.StartExpr; + iParser.ModifierI := not iScheme.CaseSensitive; + if iParser.Exec(iLine) then begin + iExpr := Copy(Value, iParser.MatchPos[0] + iEaten, iParser.MatchLen[0]); + DoCheckMarker(iScheme, iParser.MatchPos[0] + iEaten, iParser.MatchLen[0], + iExpr, True, LineNumber, Value); + Delete(iLine, 1, iParser.MatchPos[0] - 1 + iParser.MatchLen[0]); + Inc(iEaten, iParser.MatchPos[0] - 1 + iParser.MatchLen[0]); + Break; + end; + end; {for} + if i >= Schemes.Count then + Break; + end; {else} + + finally + iParser.Free; + end; + + FLineStr := Value; + fLine := PWideChar(FLineStr); + fCasedLineStr := ''; + fCasedLine := PWideChar(FLineStr); + + FMarker := nil; + Run := 0; + FExpandedRun := 0; + fOldRun := Run; + FTokenPos := 0; + fExpandedTokenPos := 0; + FNextMarker := 0; + FLineNumber := LineNumber; +end; + +function TSynMultiSyn.GetExpandedToken: UnicodeString; +begin + if (DefaultHighlighter = nil) and (fExpandedLine <> nil) then + Result := FExpandedLineStr + else + Result := inherited GetExpandedToken; +end; + +{ TSchemes } + +constructor TSchemes.Create(aOwner: TSynMultiSyn); +begin + inherited Create(TScheme); + FOwner := aOwner; +end; + +function TSchemes.GetItems(Index: Integer): TScheme; +begin + Result := inherited Items[Index] as TScheme; +end; + +{$IFDEF SYN_COMPILER_3_UP} +function TSchemes.GetOwner: TPersistent; +begin + Result := FOwner; +end; +{$ENDIF} + +procedure TSchemes.SetItems(Index: Integer; const Value: TScheme); +begin + inherited Items[Index] := Value; +end; + +{$IFDEF SYN_COMPILER_3_UP} +procedure TSchemes.Update(Item: TCollectionItem); +begin + if Item <> nil then + FOwner.DefHighlightChange(Item) + else // pass the MultiSyn as the Sender so Editors reparse their text + FOwner.DefHighlightChange(FOwner); +end; +{$ENDIF} + +{ TScheme } + +function TScheme.ConvertExpression(const Value: UnicodeString): UnicodeString; +begin + if not CaseSensitive then + Result := SynWideUpperCase(Value) + else + Result := Value; +end; + +constructor TScheme.Create(Collection: TCollection); +begin + inherited Create(Collection); + FCaseSensitive := True; + FMarkerAttri := TSynHighlighterAttributes.Create(SYNS_AttrMarker, SYNS_FriendlyAttrMarker); + FMarkerAttri.OnChange := MarkerAttriChanged; + MarkerAttri.Background := clYellow; + MarkerAttri.Style := [fsBold]; + MarkerAttri.InternalSaveDefaultValues; +end; + +destructor TScheme.Destroy; +begin + { unhook notification handlers } + Highlighter := nil; + inherited Destroy; + FMarkerAttri.Free; +end; + +procedure TScheme.DefineProperties(Filer: TFiler); +begin + inherited; +{$IFNDEF UNICODE} + UnicodeDefineProperties(Filer, Self); +{$ENDIF} +end; + +{$IFDEF SYN_COMPILER_3_UP} +function TScheme.GetDisplayName: string; +begin + if SchemeName <> '' then + Result := SchemeName + else + Result := inherited GetDisplayName; +end; +{$ENDIF SYN_COMPILER_3_UP} + +procedure TScheme.MarkerAttriChanged(Sender: TObject); +begin + Changed(False); +end; + +procedure TScheme.SetCaseSensitive(const Value: Boolean); +begin + if FCaseSensitive <> Value then + begin + FCaseSensitive := Value; + Changed(True); + end; +end; + +{$IFDEF SYN_COMPILER_3_UP} +procedure TScheme.SetDisplayName(const Value: string); +begin + SchemeName := Value; +end; +{$ENDIF SYN_COMPILER_3_UP} + +procedure TScheme.SetEndExpr(const Value: UnicodeString); +var + OldValue: UnicodeString; +begin + if FEndExpr <> Value then + begin + if Value <> '' then + CheckExpression(Value); + OldValue := FEndExpr; + FEndExpr := Value; + if ConvertExpression(OldValue) <> ConvertExpression(Value) then + Changed(True); + end; +end; + +procedure TScheme.SetHighlighter(const Value: TSynCustomHighLighter); +var + iOwner: TSynMultiSyn; + iAlreadyRepainted: Boolean; +begin + if Highlighter <> Value then + begin + iOwner := TSchemes(Collection).FOwner; + if (Highlighter <> nil) and (Highlighter <> iOwner) then + iOwner.UnhookHighlighter(Highlighter); + FHighlighter := Value; + if (Highlighter <> nil) and (Highlighter <> iOwner) then + iOwner.HookHighlighter(Highlighter); + if Highlighter is TSynMultiSyn then + iAlreadyRepainted := iOwner.UpdateRangeProcs + else + iAlreadyRepainted := False; + if not iAlreadyRepainted then + Changed(True); + end; +end; + +procedure TScheme.SetMarkerAttri(const Value: TSynHighlighterAttributes); +begin + FMarkerAttri.Assign(Value); +end; + +procedure TScheme.SetStartExpr(const Value: UnicodeString); +var + OldValue: UnicodeString; +begin + if FStartExpr <> Value then + begin + if Value <> '' then + CheckExpression(Value); + OldValue := FStartExpr; + FStartExpr := Value; + if ConvertExpression(Value) <> ConvertExpression(OldValue) then + Changed(True); + end; +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynRegExpr.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynRegExpr.pas new file mode 100644 index 000000000..1bfed4347 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynRegExpr.pas @@ -0,0 +1,4107 @@ +{$IFNDEF QSYNREGEXPR} +unit uRESTDWPrivSynRegExpr; +{$ENDIF} + +{ + TRegExpr class library + Delphi Regular Expressions + + Copyright (c) 1999-2004 Andrey V. Sorokin, St.Petersburg, Russia + + You may use this software in any kind of development, + including comercial, redistribute, and modify it freely, + under the following restrictions : + 1. This software is provided as it is, without any kind of + warranty given. Use it at Your own risk.The author is not + responsible for any consequences of use of this software. + 2. The origin of this software may not be mispresented, You + must not claim that You wrote the original software. If + You use this software in any kind of product, it would be + appreciated that there in a information box, or in the + documentation would be an acknowledgement like + + Partial Copyright (c) 2004 Andrey V. Sorokin + http://RegExpStudio.com + mailto:anso@mail.ru + + 3. You may not have any income from distributing this source + (or altered version of it) to other developers. When You + use this product in a comercial package, the source may + not be charged seperatly. + 4. Altered versions must be plainly marked as such, and must + not be misrepresented as being the original software. + 5. RegExp Studio application and all the visual components as + well as documentation is not part of the TRegExpr library + and is not free for usage. + + mailto:anso@mail.ru + http://RegExpStudio.com + http://anso.da.ru/ +} + +interface + +{$INCLUDE uRESTDWPrivSynEdit.inc} + +// ======== Determine compiler +{$IFDEF VER80} Sorry, TRegExpr is for 32-bits Delphi only. Delphi 1 is not supported (and whos really care today?!). {$ENDIF} + +// ======== Define base compiler options +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$LONGSTRINGS ON} +{$OPTIMIZATION ON} +{$IFDEF SYN_COMPILER_6_UP} + {$WARN SYMBOL_PLATFORM OFF} // Suppress .Net warnings +{$ENDIF} +{$IFDEF SYN_COMPILER_7_UP} + {$WARN UNSAFE_CAST OFF} // Suppress .Net warnings + {$WARN UNSAFE_TYPE OFF} // Suppress .Net warnings + {$WARN UNSAFE_CODE OFF} // Suppress .Net warnings +{$ENDIF} +{$IFDEF FPC} + {$MODE DELPHI} // Delphi-compatible mode in FreePascal +{$ENDIF} + +// ======== Define options for TRegExpr engine +{$DEFINE SynRegUniCode} // Unicode support +{$DEFINE RegExpPCodeDump} // p-code dumping (see Dump method) +{$IFNDEF FPC} // the option is not supported in FreePascal + {$DEFINE reRealExceptionAddr} // exceptions will point to appropriate source line, not to Error procedure +{$ENDIF} +{$DEFINE ComplexBraces} // support braces in complex cases +{$IFNDEF SynRegUniCode} // the option applicable only for non-UniCode mode + {$DEFINE UseSetOfChar} // Significant optimization by using set of char +{$ENDIF} +{$IFDEF UseSetOfChar} + {$DEFINE UseFirstCharSet} // Fast skip between matches for r.e. that starts with determined set of chars +{$ENDIF} + +// ======== Define Pascal-language options +// Define 'UseAsserts' option (do not edit this definitions). +// Asserts used to catch 'strange bugs' in TRegExpr implementation (when something goes +// completely wrong). You can swith asserts on/off with help of {$C+}/{$C-} compiler options. +{$IFDEF SYN_COMPILER_3_UP} {$DEFINE UseAsserts} {$ENDIF} +{$IFDEF FPC} {$DEFINE UseAsserts} {$ENDIF} + +// Define 'use subroutine parameters default values' option (do not edit this definition). +{$IFDEF SYN_COMPILER_4_UP} {$DEFINE DefParam} {$ENDIF} + +// Define 'OverMeth' options, to use method overloading (do not edit this definitions). +{$IFDEF SYN_COMPILER_5_UP} {$DEFINE OverMeth} {$ENDIF} +{$IFDEF FPC} {$DEFINE OverMeth} {$ENDIF} + +uses + uRESTDWPrivSynUnicode, + Classes, // TStrings in Split method + SysUtils; // Exception + +type + {$IFDEF SynRegUniCode} + PRegExprChar = PWideChar; + RegExprString = UnicodeString; + REChar = WideChar; + {$ELSE} + PRegExprChar = PChar; + RegExprString = AnsiString; //###0.952 was string + REChar = Char; + {$ENDIF} + TREOp = REChar; // internal p-code type //###0.933 + PREOp = ^TREOp; + TRENextOff = Integer; // internal Next "pointer" (offset to current p-code) //###0.933 + PRENextOff = ^TRENextOff; // used for extracting Next "pointers" from compiled r.e. //###0.933 + TREBracesArg = Integer; // type of {m,n} arguments + PREBracesArg = ^TREBracesArg; + +const + REOpSz = SizeOf (TREOp) div SizeOf (REChar); // size of p-code in RegExprString units + RENextOffSz = SizeOf (TRENextOff) div SizeOf (REChar); // size of Next 'pointer' -"- + REBracesArgSz = SizeOf (TREBracesArg) div SizeOf (REChar); // size of BRACES arguments -"- + +type + TRegExprInvertCaseFunction = function (const Ch: REChar): REChar of object; + +const + EscChar = '\'; // 'Escape'-char ('\' in common r.e.) used for escaping metachars (\w, \d etc). + RegExprModifierI: Boolean = False; // default value for ModifierI + RegExprModifierR: Boolean = True; // default value for ModifierR + RegExprModifierS: Boolean = True; // default value for ModifierS + RegExprModifierG: Boolean = True; // default value for ModifierG + RegExprModifierM: Boolean = False; // default value for ModifierM + RegExprModifierX: Boolean = False; // default value for ModifierX + RegExprSpaceChars: RegExprString = // default value for SpaceChars + ' '#$9#$A#$D#$C; + RegExprWordChars: RegExprString = // default value for WordChars + '0123456789' //###0.940 + + 'abcdefghijklmnopqrstuvwxyz' + + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'; + RegExprLineSeparators: RegExprString =// default value for LineSeparators + #$d#$a{$IFDEF SynRegUniCode}+#$b#$c#$2028#$2029#$85{$ENDIF}; //###0.947 + RegExprLinePairedSeparator : RegExprString =// default value for LinePairedSeparator + #$d#$a; + { if You need Unix-styled line separators (only \n), then use: + RegExprLineSeparators = #$a; + RegExprLinePairedSeparator = ''; + } + + +const + NSUBEXP = 15; // max number of subexpression //###0.929 + // Cannot be more than NSUBEXPMAX + // Be carefull - don't use values which overflow CLOSE opcode + // (in this case you'll get compiler erorr). + // Big NSUBEXP will cause more slow work and more stack required + NSUBEXPMAX = 255; // Max possible value for NSUBEXP. //###0.945 + // Don't change it! It's defined by internal TRegExpr design. + + MaxBracesArg = $7FFFFFFF - 1; // max value for {n,m} arguments //###0.933 + + {$IFDEF ComplexBraces} + LoopStackMax = 10; // max depth of loops stack //###0.925 + {$ENDIF} + + TinySetLen = 3; + // if range includes more then TinySetLen chars, //###0.934 + // then use full (32 bytes) ANYOFFULL instead of ANYOF[BUT]TINYSET + // !!! Attension ! If you change TinySetLen, you must + // change code marked as "//!!!TinySet" + +type +{$IFDEF UseSetOfChar} + PSetOfREChar = ^TSetOfREChar; + TSetOfREChar = set of REChar; +{$ENDIF} + + TRegExpr = class; + + TRegExprReplaceFunction = function (ARegExpr: TRegExpr): string of object; + + TRegExpr = class + private + startp : array [0 .. NSUBEXP - 1] of PRegExprChar; // founded expr starting points + endp : array [0 .. NSUBEXP - 1] of PRegExprChar; // founded expr end points + + {$IFDEF ComplexBraces} + LoopStack : array [1 .. LoopStackMax] of Integer; // state before entering loop + LoopStackIdx : Integer; // 0 - out of all loops + {$ENDIF} + + // The "internal use only" fields to pass info from compile + // to execute that permits the execute phase to run lots faster on + // simple cases. + regstart : REChar; // char that must begin a match; '\0' if none obvious + reganch : REChar; // is the match anchored (at beginning-of-line only)? + regmust : PRegExprChar; // string (pointer into program) that match must include, or nil + regmlen : Integer; // length of regmust string + // Regstart and reganch permit very fast decisions on suitable starting points + // for a match, cutting down the work a lot. Regmust permits fast rejection + // of lines that cannot possibly match. The regmust tests are costly enough + // that regcomp() supplies a regmust only if the r.e. contains something + // potentially expensive (at present, the only such thing detected is * or + + // at the start of the r.e., which can involve a lot of backup). Regmlen is + // supplied because the test in regexec() needs it and regcomp() is computing + // it anyway. + {$IFDEF UseFirstCharSet} //###0.929 + FirstCharSet : TSetOfREChar; + {$ENDIF} + + // work variables for Exec's routins - save stack in recursion} + reginput : PRegExprChar; // String-input pointer. + fInputStart : PRegExprChar; // Pointer to first char of input string. + fInputEnd : PRegExprChar; // Pointer to char AFTER last char of input string + + // work variables for compiler's routines + regparse : PRegExprChar; // Input-scan pointer. + regnpar : Integer; // count. + regdummy : REChar; + regcode : PRegExprChar; // Code-emit pointer; @regdummy = don't. + regsize : Integer; // Code size. + + regexpbeg : PRegExprChar; // only for error handling. Contains + // pointer to beginning of r.e. while compiling + fExprIsCompiled : Boolean; // True if r.e. successfully compiled + + // programm is essentially a linear encoding + // of a nondeterministic finite-state machine (aka syntax charts or + // "railroad normal form" in parsing technology). Each node is an opcode + // plus a "next" pointer, possibly plus an operand. "Next" pointers of + // all nodes except BRANCH implement concatenation; a "next" pointer with + // a BRANCH on both ends of it is connecting two alternatives. (Here we + // have one of the subtle syntax dependencies: an individual BRANCH (as + // opposed to a collection of them) is never concatenated with anything + // because of operator precedence.) The operand of some types of node is + // a literal string; for others, it is a node leading into a sub-FSM. In + // particular, the operand of a BRANCH node is the first node of the branch. + // (NB this is *not* a tree structure: the tail of the branch connects + // to the thing following the set of BRANCHes.) The opcodes are: + programm : PRegExprChar; // Unwarranted chumminess with compiler. + + fExpression : PRegExprChar; // source of compiled r.e. + fInputString : PRegExprChar; // input string + + FLastError : Integer; // see Error, LastError + + fModifiers : Integer; // modifiers + fCompModifiers : Integer; // compiler's copy of modifiers + fProgModifiers : Integer; // modifiers values from last programm compilation + + fSpaceChars : RegExprString; //###0.927 + fWordChars : RegExprString; //###0.929 + fInvertCase : TRegExprInvertCaseFunction; //###0.927 + + FLineSeparators : RegExprString; //###0.941 + fLinePairedSeparatorAssigned : Boolean; + fLinePairedSeparatorHead, + fLinePairedSeparatorTail : REChar; + {$IFNDEF SynRegUniCode} + FLineSeparatorsSet : set of REChar; + {$ENDIF} + + procedure InvalidateProgramm; + // Mark programm as have to be [re]compiled + + function IsProgrammOk : Boolean; //###0.941 + // Check if we can use precompiled r.e. or + // [re]compile it if something changed + + function GetExpression : RegExprString; + procedure SetExpression (const s : RegExprString); + + function GetModifierStr : RegExprString; + class function ParseModifiersStr (const AModifiers : RegExprString; + var AModifiersInt : Integer) : Boolean; //###0.941 class function now + // Parse AModifiers string and return True and set AModifiersInt + // if it's in format 'ismxrg-ismxrg'. + procedure SetModifierStr (const AModifiers : RegExprString); + + function GetModifier (AIndex : Integer) : Boolean; + procedure SetModifier (AIndex : Integer; ASet : Boolean); + + procedure Error (AErrorID : Integer); virtual; // error handler. + // Default handler raise exception ERegExpr with + // Message = ErrorMsg (AErrorID), ErrorCode = AErrorID + // and CompilerErrorPos = value of property CompilerErrorPos. + + + {==================== Compiler section ===================} + function CompileRegExpr (exp : PRegExprChar) : Boolean; + // compile a regular expression into internal code + + procedure Tail (p : PRegExprChar; val : PRegExprChar); + // set the next-pointer at the end of a node chain + + procedure OpTail (p : PRegExprChar; val : PRegExprChar); + // regoptail - regtail on operand of first argument; nop if operandless + + function EmitNode (op : TREOp) : PRegExprChar; + // regnode - emit a node, return location + + procedure EmitC (b : REChar); + // emit (if appropriate) a byte of code + + procedure InsertOperator (op : TREOp; opnd : PRegExprChar; sz : Integer); //###0.90 + // insert an operator in front of already-emitted operand + // Means relocating the operand. + + function ParseReg (paren : Integer; var flagp : Integer) : PRegExprChar; + // regular expression, i.e. main body or parenthesized thing + + function ParseBranch (var flagp : Integer) : PRegExprChar; + // one alternative of an | operator + + function ParsePiece (var flagp : Integer) : PRegExprChar; + // something followed by possible [*+?] + + function ParseAtom (var flagp : Integer) : PRegExprChar; + // the lowest level + + function GetCompilerErrorPos : Integer; + // current pos in r.e. - for error hanling + + {$IFDEF UseFirstCharSet} //###0.929 + procedure FillFirstCharSet (prog : PRegExprChar); + {$ENDIF} + + {===================== Mathing section ===================} + function regrepeat (p : PRegExprChar; AMax : Integer) : Integer; + // repeatedly match something simple, report how many + + function regnext (p : PRegExprChar) : PRegExprChar; + // dig the "next" pointer out of a node + + function MatchPrim (prog : PRegExprChar) : Boolean; + // recursively matching routine + + function ExecPrim (AOffset: Integer) : Boolean; + // Exec for stored InputString + + {$IFDEF RegExpPCodeDump} + function DumpOp (op : REChar) : RegExprString; + {$ENDIF} + + function GetSubExprMatchCount : Integer; + function GetMatchPos (Idx : Integer) : Integer; + function GetMatchLen (Idx : Integer) : Integer; + function GetMatch (Idx : Integer) : RegExprString; + + function GetInputString : RegExprString; + procedure SetInputString (const AInputString : RegExprString); + + {$IFNDEF UseSetOfChar} + function StrScanCI (s : PRegExprChar; ch : REChar) : PRegExprChar; //###0.928 + {$ENDIF} + + procedure SetLineSeparators (const AStr : RegExprString); + procedure SetLinePairedSeparator (const AStr : RegExprString); + function GetLinePairedSeparator : RegExprString; + + public + constructor Create; + destructor Destroy; override; + + class function VersionMajor : Integer; //###0.944 + class function VersionMinor : Integer; //###0.944 + + property Expression : RegExprString read GetExpression write SetExpression; + // Regular expression. + // For optimization, TRegExpr will automatically compiles it into 'P-code' + // (You can see it with help of Dump method) and stores in internal + // structures. Real [re]compilation occures only when it really needed - + // while calling Exec[Next], Substitute, Dump, etc + // and only if Expression or other P-code affected properties was changed + // after last [re]compilation. + // If any errors while [re]compilation occures, Error method is called + // (by default Error raises exception - see below) + + property ModifierStr : RegExprString read GetModifierStr write SetModifierStr; + // Set/get default values of r.e.syntax modifiers. Modifiers in + // r.e. (?ismx-ismx) will replace this default values. + // If you try to set unsupported modifier, Error will be called + // (by defaul Error raises exception ERegExpr). + + property ModifierI : Boolean index 1 read GetModifier write SetModifier; + // Modifier /i - caseinsensitive, initialized from RegExprModifierI + + property ModifierR : Boolean index 2 read GetModifier write SetModifier; + // Modifier /r - use r.e.syntax extended for russian, + // (was property ExtSyntaxEnabled in previous versions) + // If True, then - additional include russian letter '', + // - additional include '', and - include all russian symbols. + // You have to turn it off if it may interfere with you national alphabet. + // , initialized from RegExprModifierR + + property ModifierS : Boolean index 3 read GetModifier write SetModifier; + // Modifier /s - '.' works as any char (else as [^\n]), + // , initialized from RegExprModifierS + + property ModifierG : Boolean index 4 read GetModifier write SetModifier; + // Switching off modifier /g switchs all operators in + // non-greedy style, so if ModifierG = False, then + // all '*' works as '*?', all '+' as '+?' and so on. + // , initialized from RegExprModifierG + + property ModifierM : Boolean index 5 read GetModifier write SetModifier; + // Treat string as multiple lines. That is, change `^' and `$' from + // matching at only the very start or end of the string to the start + // or end of any line anywhere within the string. + // , initialized from RegExprModifierM + + property ModifierX : Boolean index 6 read GetModifier write SetModifier; + // Modifier /x - eXtended syntax, allow r.e. text formatting, + // see description in the help. Initialized from RegExprModifierX + + function Exec (const AInputString : RegExprString) : Boolean; {$IFDEF OverMeth} overload; + {$IFNDEF FPC} // I do not know why FreePascal cannot overload methods with empty param list + function Exec : Boolean; overload; //###0.949 + {$ENDIF} + function Exec (AOffset: Integer) : Boolean; overload; //###0.949 + {$ENDIF} + // match a programm against a string AInputString + // !!! Exec store AInputString into InputString property + // For Delphi 5 and higher available overloaded versions - first without + // parameter (uses already assigned to InputString property value) + // and second that has Integer parameter and is same as ExecPos + + function ExecNext : Boolean; + // find next match: + // ExecNext; + // works same as + // if MatchLen [0] = 0 then ExecPos (MatchPos [0] + 1) + // else ExecPos (MatchPos [0] + MatchLen [0]); + // but it's more simpler ! + // Raises exception if used without preceeding SUCCESSFUL call to + // Exec* (Exec, ExecPos, ExecNext). So You always must use something like + // if Exec (InputString) then repeat { proceed results} until not ExecNext; + + function ExecPos (AOffset: Integer {$IFDEF DefParam}= 1{$ENDIF}) : Boolean; + // find match for InputString starting from AOffset position + // (AOffset=1 - first char of InputString) + + property InputString : RegExprString read GetInputString write SetInputString; + // returns current input string (from last Exec call or last assign + // to this property). + // Any assignment to this property clear Match* properties ! + + function Substitute (const ATemplate : RegExprString) : RegExprString; + // Returns ATemplate with '$&' or '$0' replaced by whole r.e. + // occurence and '$n' replaced by occurence of subexpression #n. + // Since v.0.929 '$' used instead of '\' (for future extensions + // and for more Perl-compatibility) and accept more then one digit. + // If you want place into template raw '$' or '\', use prefix '\' + // Example: '1\$ is $2\\rub\\' -> '1$ is \rub\' + // If you want to place raw digit after '$n' you must delimit + // n with curly braces '{}'. + // Example: 'a$12bc' -> 'abc' + // 'a${1}2bc' -> 'a2bc'. + + procedure Split (AInputStr : RegExprString; APieces : TStrings); + // Split AInputStr into APieces by r.e. occurencies + // Internally calls Exec[Next] + + function Replace (AInputStr : RegExprString; + const AReplaceStr : RegExprString; + AUseSubstitution : Boolean{$IFDEF DefParam}= False{$ENDIF}) //###0.946 + : RegExprString; {$IFDEF OverMeth} overload; + function Replace (AInputStr : RegExprString; + AReplaceFunc : TRegExprReplaceFunction) + : RegExprString; overload; + {$ENDIF} + function ReplaceEx (AInputStr : RegExprString; + AReplaceFunc : TRegExprReplaceFunction) + : RegExprString; + // Returns AInputStr with r.e. occurencies replaced by AReplaceStr + // If AUseSubstitution is True, then AReplaceStr will be used + // as template for Substitution methods. + // For example: + // Expression := '({-i}block|var)\s*\(\s*([^ ]*)\s*\)\s*'; + // Replace ('BLOCK( test1)', 'def "$1" value "$2"', True); + // will return: def 'BLOCK' value 'test1' + // Replace ('BLOCK( test1)', 'def "$1" value "$2"') + // will return: def "$1" value "$2" + // Internally calls Exec[Next] + // Overloaded version and ReplaceEx operate with call-back function, + // so You can implement really complex functionality. + + property SubExprMatchCount : Integer read GetSubExprMatchCount; + // Number of subexpressions has been found in last Exec* call. + // If there are no subexpr. but whole expr was found (Exec* returned True), + // then SubExprMatchCount=0, if no subexpressions nor whole + // r.e. found (Exec* returned False) then SubExprMatchCount=-1. + // Note, that some subexpr. may be not found and for such + // subexpr. MathPos=MatchLen=-1 and Match=''. + // For example: Expression := '(1)?2(3)?'; + // Exec ('123'): SubExprMatchCount=2, Match[0]='123', [1]='1', [2]='3' + // Exec ('12'): SubExprMatchCount=1, Match[0]='12', [1]='1' + // Exec ('23'): SubExprMatchCount=2, Match[0]='23', [1]='', [2]='3' + // Exec ('2'): SubExprMatchCount=0, Match[0]='2' + // Exec ('7') - return False: SubExprMatchCount=-1 + + property MatchPos [Idx : Integer] : Integer read GetMatchPos; + // pos of entrance subexpr. #Idx into tested in last Exec* + // string. First subexpr. have Idx=1, last - MatchCount, + // whole r.e. have Idx=0. + // Returns -1 if in r.e. no such subexpr. or this subexpr. + // not found in input string. + + property MatchLen [Idx : Integer] : Integer read GetMatchLen; + // len of entrance subexpr. #Idx r.e. into tested in last Exec* + // string. First subexpr. have Idx=1, last - MatchCount, + // whole r.e. have Idx=0. + // Returns -1 if in r.e. no such subexpr. or this subexpr. + // not found in input string. + // Remember - MatchLen may be 0 (if r.e. match empty string) ! + + property Match [Idx : Integer] : RegExprString read GetMatch; + // == copy (InputString, MatchPos [Idx], MatchLen [Idx]) + // Returns '' if in r.e. no such subexpr. or this subexpr. + // not found in input string. + + function LastError : Integer; + // Returns ID of last error, 0 if no errors (unusable if + // Error method raises exception) and clear internal status + // into 0 (no errors). + + function ErrorMsg (AErrorID : Integer) : RegExprString; virtual; + // Returns Error message for error with ID = AErrorID. + + property CompilerErrorPos : Integer read GetCompilerErrorPos; + // Returns pos in r.e. there compiler stopped. + // Usefull for error diagnostics + + property SpaceChars : RegExprString read fSpaceChars write fSpaceChars; //###0.927 + // Contains chars, treated as /s (initially filled with RegExprSpaceChars + // global constant) + + property WordChars : RegExprString read fWordChars write fWordChars; //###0.929 + // Contains chars, treated as /w (initially filled with RegExprWordChars + // global constant) + + property LineSeparators : RegExprString read FLineSeparators write SetLineSeparators; //###0.941 + // line separators (like \n in Unix) + + property LinePairedSeparator : RegExprString read GetLinePairedSeparator write SetLinePairedSeparator; //###0.941 + // paired line separator (like \r\n in DOS and Windows). + // must contain exactly two chars or no chars at all + + class function InvertCaseFunction (const Ch : REChar) : REChar; + // Converts Ch into upper case if it in lower case or in lower + // if it in upper (uses current system local setings) + + property InvertCase : TRegExprInvertCaseFunction read fInvertCase write fInvertCase; //##0.935 + // Set this property if you want to override case-insensitive functionality. + // Create set it to RegExprInvertCaseFunction (InvertCaseFunction by default) + + procedure Compile; //###0.941 + // [Re]compile r.e. Usefull for example for GUI r.e. editors (to check + // all properties validity). + + {$IFDEF RegExpPCodeDump} + function Dump : RegExprString; + // dump a compiled regexp in vaguely comprehensible form + {$ENDIF} + end; + + ERegExpr = class (Exception) + public + ErrorCode : Integer; + CompilerErrorPos : Integer; + end; + +const + RegExprInvertCaseFunction : TRegExprInvertCaseFunction = {$IFDEF FPC} nil {$ELSE} TRegExpr.InvertCaseFunction{$ENDIF}; + // defaul for InvertCase property + +function ExecRegExpr (const ARegExpr, AInputStr : RegExprString) : Boolean; +// True if string AInputString match regular expression ARegExpr +// ! will raise exeption if syntax errors in ARegExpr + +procedure SplitRegExpr (const ARegExpr, AInputStr : RegExprString; APieces : TStrings); +// Split AInputStr into APieces by r.e. ARegExpr occurencies + +function ReplaceRegExpr (const ARegExpr, AInputStr, AReplaceStr : RegExprString; + AUseSubstitution : Boolean{$IFDEF DefParam}= False{$ENDIF}) : RegExprString; //###0.947 +// Returns AInputStr with r.e. occurencies replaced by AReplaceStr +// If AUseSubstitution is True, then AReplaceStr will be used +// as template for Substitution methods. +// For example: +// ReplaceRegExpr ('({-i}block|var)\s*\(\s*([^ ]*)\s*\)\s*', +// 'BLOCK( test1)', 'def "$1" value "$2"', True) +// will return: def 'BLOCK' value 'test1' +// ReplaceRegExpr ('({-i}block|var)\s*\(\s*([^ ]*)\s*\)\s*', +// 'BLOCK( test1)', 'def "$1" value "$2"') +// will return: def "$1" value "$2" + +function QuoteRegExprMetaChars (const AStr : RegExprString) : RegExprString; +// Replace all metachars with its safe representation, +// for example 'abc$cd.(' converts into 'abc\$cd\.\(' +// This function usefull for r.e. autogeneration from +// user input + +function RegExprSubExpressions (const ARegExpr : string; + ASubExprs : TStrings; AExtendedSyntax : Boolean{$IFDEF DefParam}= False{$ENDIF}) : Integer; +// Makes list of subexpressions found in ARegExpr r.e. +// In ASubExps every item represent subexpression, +// from first to last, in format: +// String - subexpression text (without '()') +// low word of Object - starting position in ARegExpr, including '(' +// if exists! (first position is 1) +// high word of Object - length, including starting '(' and ending ')' +// if exist! +// AExtendedSyntax - must be True if modifier /m will be On while +// using the r.e. +// Usefull for GUI editors of r.e. etc (You can find example of using +// in TestRExp.dpr project) +// Returns +// 0 Success. No unbalanced brackets was found; +// -1 There are not enough closing brackets ')'; +// -(n+1) At position n was found opening '[' without //###0.942 +// corresponding closing ']'; +// n At position n was found closing bracket ')' without +// corresponding opening '('. +// If Result <> 0, then ASubExpr can contain empty items or illegal ones + + +implementation + +uses +{$IFDEF MSWINDOWS} + Windows; // CharUpper/Lower +{$ELSE} + Libc; //Qt.pas from Borland does not expose char handling functions +{$ENDIF} + +const + TRegExprVersionMajor : Integer = 0; + TRegExprVersionMinor : Integer = 952; + // TRegExpr.VersionMajor/Minor return values of this constants + + MaskModI = 1; // modifier /i bit in fModifiers + MaskModR = 2; // -"- /r + MaskModS = 4; // -"- /s + MaskModG = 8; // -"- /g + MaskModM = 16; // -"- /m + MaskModX = 32; // -"- /x + +{$IFDEF SynRegUniCode} + XIgnoredChars = ' '#9#$d#$a; +{$ELSE} + XIgnoredChars = [' ', #9, #$d, #$a]; +{$ENDIF} + +{=============================================================} +{=================== UnicodeString functions ====================} +{=============================================================} + +{$IFDEF SynRegUniCode} + +function StrPCopy (Dest: PRegExprChar; const Source: RegExprString): PRegExprChar; +var + i, Len : Integer; +begin + Len := length (Source); //###0.932 + for i := 1 to Len do + Dest [i - 1] := Source [i]; + Dest [Len] := #0; + Result := Dest; +end; { of function StrPCopy +--------------------------------------------------------------} + +function StrLCopy (Dest, Source: PRegExprChar; MaxLen: Cardinal): PRegExprChar; +var + i: Integer; +begin + for i := 0 to MaxLen - 1 do + Dest [i] := Source [i]; + Result := Dest; +end; { of function StrLCopy +--------------------------------------------------------------} + +function StrLen (Str: PRegExprChar): Cardinal; +begin + Result := 0; + while Str [result] <> #0 do + Inc (Result); +end; { of function StrLen +--------------------------------------------------------------} + +function StrPos (Str1, Str2: PRegExprChar): PRegExprChar; +var + n: Integer; +begin + Result := nil; + n := Pos (RegExprString (Str2), RegExprString (Str1)); + if n = 0 then + Exit; + Result := Str1 + n - 1; +end; { of function StrPos +--------------------------------------------------------------} + +function StrLComp (Str1, Str2: PRegExprChar; MaxLen: Cardinal): Integer; +var + S1, S2: RegExprString; +begin + S1 := Str1; + S2 := Str2; + if Copy (S1, 1, MaxLen) > Copy (S2, 1, MaxLen) then + Result := 1 + else + if Copy (S1, 1, MaxLen) < Copy (S2, 1, MaxLen) then + Result := -1 + else + Result := 0; +end; { function StrLComp +--------------------------------------------------------------} + +function StrScan (Str: PRegExprChar; Chr: WideChar): PRegExprChar; +begin + Result := nil; + while (Str^ <> #0) and (Str^ <> Chr) do + Inc (Str); + if (Str^ <> #0) then + Result := Str; +end; { of function StrScan +--------------------------------------------------------------} + +{$ENDIF} + + +{=============================================================} +{===================== Global functions ======================} +{=============================================================} + +function ExecRegExpr (const ARegExpr, AInputStr : RegExprString) : Boolean; +var + r : TRegExpr; +begin + r := TRegExpr.Create; + try + r.Expression := ARegExpr; + Result := r.Exec (AInputStr); + finally + r.Free; + end; +end; { of function ExecRegExpr +--------------------------------------------------------------} + +procedure SplitRegExpr (const ARegExpr, AInputStr : RegExprString; APieces : TStrings); +var r : TRegExpr; +begin + APieces.Clear; + r := TRegExpr.Create; + try + r.Expression := ARegExpr; + r.Split (AInputStr, APieces); + finally + r.Free; + end; +end; { of procedure SplitRegExpr +--------------------------------------------------------------} + +function ReplaceRegExpr (const ARegExpr, AInputStr, AReplaceStr : RegExprString; + AUseSubstitution : Boolean{$IFDEF DefParam}= False{$ENDIF}) : RegExprString; +begin + with TRegExpr.Create do + try + Expression := ARegExpr; + Result := Replace (AInputStr, AReplaceStr, AUseSubstitution); + finally + Free; + end; +end; { of function ReplaceRegExpr +--------------------------------------------------------------} + +function QuoteRegExprMetaChars (const AStr : RegExprString) : RegExprString; +const + RegExprMetaSet : RegExprString = '^$.[()|?+*'+EscChar+'{' + + ']}'; // - this last are additional to META. + // Very similar to META array, but slighly changed. + // !Any changes in META array must be synchronized with this set. +var + i, i0, Len : Integer; +begin + Result := ''; + Len := length (AStr); + i := 1; + i0 := i; + while i <= Len do + begin + if Pos (AStr [i], RegExprMetaSet) > 0 then + begin + Result := Result + System.Copy (AStr, i0, i - i0) + + EscChar + AStr [i]; + i0 := i + 1; + end; + inc (i); + end; + Result := Result + System.Copy (AStr, i0, MaxInt); // Tail +end; { of function QuoteRegExprMetaChars +--------------------------------------------------------------} + +function RegExprSubExpressions (const ARegExpr : string; + ASubExprs : TStrings; AExtendedSyntax : Boolean{$IFDEF DefParam}= False{$ENDIF}) : Integer; +type + TStackItemRec = record //###0.945 + SubExprIdx : Integer; + StartPos : Integer; + end; + TStackArray = packed array [0 .. NSUBEXPMAX - 1] of TStackItemRec; +var + Len, SubExprLen : Integer; + i, i0 : Integer; + Modif : Integer; + Stack : ^TStackArray; //###0.945 + StackIdx, StackSz : Integer; +begin + Result := 0; // no unbalanced brackets found at this very moment + + ASubExprs.Clear; // I don't think that adding to non empty list + // can be usefull, so I simplified algorithm to work only with empty list + + Len := length (ARegExpr); // some optimization tricks + + // first we have to calculate number of subexpression to reserve + // space in Stack array (may be we'll reserve more then need, but + // it's faster then memory reallocation during parsing) + StackSz := 1; // add 1 for entire r.e. + for i := 1 to Len do + if ARegExpr [i] = '(' then + inc (StackSz); +// SetLength (Stack, StackSz); //###0.945 + GetMem (Stack, SizeOf (TStackItemRec) * StackSz); + try + StackIdx := 0; + i := 1; + while (i <= Len) do + begin + case ARegExpr [i] of + '(': + begin + if (i < Len) and (ARegExpr [i + 1] = '?') then + begin + // this is not subexpression, but comment or other + // Perl extension. We must check is it (?ismxrg-ismxrg) + // and change AExtendedSyntax if /x is changed. + inc (i, 2); // skip '(?' + i0 := i; + while (i <= Len) and (ARegExpr [i] <> ')') do + inc (i); + if i > Len then + Result := -1 // unbalansed '(' + else + if TRegExpr.ParseModifiersStr (System.Copy (ARegExpr, i, i - i0), Modif) then + AExtendedSyntax := (Modif and MaskModX) <> 0; + end + else + begin // subexpression starts + ASubExprs.Add (''); // just reserve space + with Stack [StackIdx] do + begin + SubExprIdx := ASubExprs.Count - 1; + StartPos := i; + end; + inc (StackIdx); + end; + end; + ')': + begin + if StackIdx = 0 then + Result := i // unbalanced ')' + else + begin + dec (StackIdx); + with Stack [StackIdx] do + begin + SubExprLen := i - StartPos + 1; + ASubExprs.Objects [SubExprIdx] := + TObject (StartPos or (SubExprLen shL 16)); + ASubExprs [SubExprIdx] := System.Copy ( + ARegExpr, StartPos + 1, SubExprLen - 2); // add without brackets + end; + end; + end; + EscChar: + inc (i); // skip quoted symbol + '[': + begin + // we have to skip character ranges at once, because they can + // contain '#', and '#' in it must NOT be recognized as eXtended + // comment beginning! + i0 := i; + inc (i); + if ARegExpr [i] = ']' // cannot be 'emty' ranges - this interpretes + then inc (i); // as ']' by itself + while (i <= Len) and (ARegExpr [i] <> ']') do + if ARegExpr [i] = EscChar then + inc (i, 2) // skip 'escaped' char to prevent stopping at '\]' + else + inc (i); + if (i > Len) or (ARegExpr [i] <> ']') then + Result := - (i0 + 1); // unbalansed '[' + end; + '#': + if AExtendedSyntax then + begin + // skip eXtended comments + while (i <= Len) and (ARegExpr [i] <> #$d) and (ARegExpr [i] <> #$a) + // do not use [#$d, #$a] due to UniCode compatibility + do inc (i); + while (i + 1 <= Len) and ((ARegExpr [i + 1] = #$d) or (ARegExpr [i + 1] = #$a)) + do inc (i); // attempt to work with different kinds of line separators + // now we are at the line separator that must be skipped. + end; + // here is no 'else' clause - we simply skip ordinary chars + end; // of case + inc (i); // skip scanned char + // ! can move after Len due to skipping quoted symbol + end; + + // check brackets balance + if StackIdx <> 0 then + Result := -1; // unbalansed '(' + + // check if entire r.e. added + if (ASubExprs.Count = 0) + or ((Integer (ASubExprs.Objects [0]) and $FFFF) <> 1) + or (((Integer (ASubExprs.Objects [0]) shr 16) and $FFFF) <> Len) + // whole r.e. wasn't added because it isn't bracketed + // well, we add it now: + then ASubExprs.InsertObject (0, ARegExpr, TObject ((Len ShL 16) or 1)); + + finally + FreeMem (Stack); + end; +end; { of function RegExprSubExpressions +--------------------------------------------------------------} + + + +const + MAGIC = TREOp (216);// programm signature + +// name opcode opnd? meaning + EEND = TREOp (0); // - End of program + BOL = TREOp (1); // - Match "" at beginning of line + EOL = TREOp (2); // - Match "" at end of line + ANY = TREOp (3); // - Match any one character + ANYOF = TREOp (4); // Str Match any character in string Str + ANYBUT = TREOp (5); // Str Match any char. not in string Str + BRANCH = TREOp (6); // Node Match this alternative, or the next + BACK = TREOp (7); // - Jump backward (Next < 0) + EXACTLY = TREOp (8); // Str Match string Str + NOTHING = TREOp (9); // - Match empty string + STAR = TREOp (10); // Node Match this (simple) thing 0 or more times + PLUS = TREOp (11); // Node Match this (simple) thing 1 or more times + ANYDIGIT = TREOp (12); // - Match any digit (equiv [0-9]) + NOTDIGIT = TREOp (13); // - Match not digit (equiv [0-9]) + ANYLETTER = TREOp (14); // - Match any letter from property WordChars + NOTLETTER = TREOp (15); // - Match not letter from property WordChars + ANYSPACE = TREOp (16); // - Match any space char (see property SpaceChars) + NOTSPACE = TREOp (17); // - Match not space char (see property SpaceChars) + BRACES = TREOp (18); // Node,Min,Max Match this (simple) thing from Min to Max times. + // Min and Max are TREBracesArg + COMMENT = TREOp (19); // - Comment ;) + EXACTLYCI = TREOp (20); // Str Match string Str case insensitive + ANYOFCI = TREOp (21); // Str Match any character in string Str, case insensitive + ANYBUTCI = TREOp (22); // Str Match any char. not in string Str, case insensitive + LOOPENTRY = TREOp (23); // Node Start of loop (Node - LOOP for this loop) + LOOP = TREOp (24); // Node,Min,Max,LoopEntryJmp - back jump for LOOPENTRY. + // Min and Max are TREBracesArg + // Node - next node in sequence, + // LoopEntryJmp - associated LOOPENTRY node addr + ANYOFTINYSET= TREOp (25); // Chrs Match any one char from Chrs (exactly TinySetLen chars) + ANYBUTTINYSET=TREOp (26); // Chrs Match any one char not in Chrs (exactly TinySetLen chars) + ANYOFFULLSET= TREOp (27); // Set Match any one char from set of char + // - very fast (one CPU instruction !) but takes 32 bytes of p-code + BSUBEXP = TREOp (28); // Idx Match previously matched subexpression #Idx (stored as REChar) //###0.936 + BSUBEXPCI = TREOp (29); // Idx -"- in case-insensitive mode + + // Non-Greedy Style Ops //###0.940 + STARNG = TREOp (30); // Same as START but in non-greedy mode + PLUSNG = TREOp (31); // Same as PLUS but in non-greedy mode + BRACESNG = TREOp (32); // Same as BRACES but in non-greedy mode + LOOPNG = TREOp (33); // Same as LOOP but in non-greedy mode + + // Multiline mode \m + BOLML = TREOp (34); // - Match "" at beginning of line + EOLML = TREOp (35); // - Match "" at end of line + ANYML = TREOp (36); // - Match any one character + + // Word boundary + BOUND = TREOp (37); // Match "" between words //###0.943 + NOTBOUND = TREOp (38); // Match "" not between words //###0.943 + + // !!! Change OPEN value if you add new opcodes !!! + + OPEN = TREOp (39); // - Mark this point in input as start of \n + // OPEN + 1 is \1, etc. + CLOSE = TREOp (ord (OPEN) + NSUBEXP); + // - Analogous to OPEN. + + // !!! Don't add new OpCodes after CLOSE !!! + +// We work with p-code thru pointers, compatible with PRegExprChar. +// Note: all code components (TRENextOff, TREOp, TREBracesArg, etc) +// must have lengths that can be divided by SizeOf (REChar) ! +// A node is TREOp of opcode followed Next "pointer" of TRENextOff type. +// The Next is a offset from the opcode of the node containing it. +// An operand, if any, simply follows the node. (Note that much of +// the code generation knows about this implicit relationship!) +// Using TRENextOff=Integer speed up p-code processing. + +// Opcodes description: +// +// BRANCH The set of branches constituting a single choice are hooked +// together with their "next" pointers, since precedence prevents +// anything being concatenated to any individual branch. The +// "next" pointer of the last BRANCH in a choice points to the +// thing following the whole choice. This is also where the +// final "next" pointer of each individual branch points; each +// branch starts with the operand node of a BRANCH node. +// BACK Normal "next" pointers all implicitly point forward; BACK +// exists to make loop structures possible. +// STAR,PLUS,BRACES '?', and complex '*' and '+', are implemented as +// circular BRANCH structures using BACK. Complex '{min,max}' +// - as pair LOOPENTRY-LOOP (see below). Simple cases (one +// character per match) are implemented with STAR, PLUS and +// BRACES for speed and to minimize recursive plunges. +// LOOPENTRY,LOOP {min,max} are implemented as special pair +// LOOPENTRY-LOOP. Each LOOPENTRY initialize loopstack for +// current level. +// OPEN,CLOSE are numbered at compile time. + + +{=============================================================} +{================== Error handling section ===================} +{=============================================================} + +const + reeOk = 0; + reeCompNullArgument = 100; + reeCompRegexpTooBig = 101; + reeCompParseRegTooManyBrackets = 102; + reeCompParseRegUnmatchedBrackets = 103; + reeCompParseRegUnmatchedBrackets2 = 104; + reeCompParseRegJunkOnEnd = 105; + reePlusStarOperandCouldBeEmpty = 106; + reeNestedSQP = 107; + reeBadHexDigit = 108; + reeInvalidRange = 109; + reeParseAtomTrailingBackSlash = 110; + reeNoHexCodeAfterBSlashX = 111; + reeHexCodeAfterBSlashXTooBig = 112; + reeUnmatchedSqBrackets = 113; + reeInternalUrp = 114; + reeQPSBFollowsNothing = 115; + reeTrailingBackSlash = 116; + reeRarseAtomInternalDisaster = 119; + reeBRACESArgTooBig = 122; + reeBracesMinParamGreaterMax = 124; + reeUnclosedComment = 125; + reeComplexBracesNotImplemented = 126; + reeUrecognizedModifier = 127; + reeBadLinePairedSeparator = 128; + reeRegRepeatCalledInappropriately = 1000; + reeMatchPrimMemoryCorruption = 1001; + reeMatchPrimCorruptedPointers = 1002; + reeNoExpression = 1003; + reeCorruptedProgram = 1004; + reeNoInpitStringSpecified = 1005; + reeOffsetMustBeGreaterThen0 = 1006; + reeExecNextWithoutExec = 1007; + reeGetInputStringWithoutInputString = 1008; + reeDumpCorruptedOpcode = 1011; + reeModifierUnsupported = 1013; + reeLoopStackExceeded = 1014; + reeLoopWithoutEntry = 1015; + reeBadPCodeImported = 2000; + +function TRegExpr.ErrorMsg (AErrorID : Integer) : RegExprString; +begin + case AErrorID of + reeOk: Result := 'No errors'; + reeCompNullArgument: Result := 'TRegExpr(comp): Null Argument'; + reeCompRegexpTooBig: Result := 'TRegExpr(comp): Regexp Too Big'; + reeCompParseRegTooManyBrackets: Result := 'TRegExpr(comp): ParseReg Too Many ()'; + reeCompParseRegUnmatchedBrackets: Result := 'TRegExpr(comp): ParseReg Unmatched ()'; + reeCompParseRegUnmatchedBrackets2: Result := 'TRegExpr(comp): ParseReg Unmatched ()'; + reeCompParseRegJunkOnEnd: Result := 'TRegExpr(comp): ParseReg Junk On End'; + reePlusStarOperandCouldBeEmpty: Result := 'TRegExpr(comp): *+ Operand Could Be Empty'; + reeNestedSQP: Result := 'TRegExpr(comp): Nested *?+'; + reeBadHexDigit: Result := 'TRegExpr(comp): Bad Hex Digit'; + reeInvalidRange: Result := 'TRegExpr(comp): Invalid [] Range'; + reeParseAtomTrailingBackSlash: Result := 'TRegExpr(comp): Parse Atom Trailing \'; + reeNoHexCodeAfterBSlashX: Result := 'TRegExpr(comp): No Hex Code After \x'; + reeHexCodeAfterBSlashXTooBig: Result := 'TRegExpr(comp): Hex Code After \x Is Too Big'; + reeUnmatchedSqBrackets: Result := 'TRegExpr(comp): Unmatched []'; + reeInternalUrp: Result := 'TRegExpr(comp): Internal Urp'; + reeQPSBFollowsNothing: Result := 'TRegExpr(comp): ?+*{ Follows Nothing'; + reeTrailingBackSlash: Result := 'TRegExpr(comp): Trailing \'; + reeRarseAtomInternalDisaster: Result := 'TRegExpr(comp): RarseAtom Internal Disaster'; + reeBRACESArgTooBig: Result := 'TRegExpr(comp): BRACES Argument Too Big'; + reeBracesMinParamGreaterMax: Result := 'TRegExpr(comp): BRACE Min Param Greater then Max'; + reeUnclosedComment: Result := 'TRegExpr(comp): Unclosed (?#Comment)'; + reeComplexBracesNotImplemented: Result := 'TRegExpr(comp): If you want take part in beta-testing BRACES ''{min,max}'' and non-greedy ops ''*?'', ''+?'', ''??'' for complex cases - remove ''.'' from {.$DEFINE ComplexBraces}'; + reeUrecognizedModifier: Result := 'TRegExpr(comp): Urecognized Modifier'; + reeBadLinePairedSeparator: Result := 'TRegExpr(comp): LinePairedSeparator must countain two different chars or no chars at all'; + + reeRegRepeatCalledInappropriately: Result := 'TRegExpr(exec): RegRepeat Called Inappropriately'; + reeMatchPrimMemoryCorruption: Result := 'TRegExpr(exec): MatchPrim Memory Corruption'; + reeMatchPrimCorruptedPointers: Result := 'TRegExpr(exec): MatchPrim Corrupted Pointers'; + reeNoExpression: Result := 'TRegExpr(exec): Not Assigned Expression Property'; + reeCorruptedProgram: Result := 'TRegExpr(exec): Corrupted Program'; + reeNoInpitStringSpecified: Result := 'TRegExpr(exec): No Input String Specified'; + reeOffsetMustBeGreaterThen0: Result := 'TRegExpr(exec): Offset Must Be Greater Then 0'; + reeExecNextWithoutExec: Result := 'TRegExpr(exec): ExecNext Without Exec[Pos]'; + reeGetInputStringWithoutInputString: Result := 'TRegExpr(exec): GetInputString Without InputString'; + reeDumpCorruptedOpcode: Result := 'TRegExpr(dump): Corrupted Opcode'; + reeLoopStackExceeded: Result := 'TRegExpr(exec): Loop Stack Exceeded'; + reeLoopWithoutEntry: Result := 'TRegExpr(exec): Loop Without LoopEntry !'; + + reeBadPCodeImported: Result := 'TRegExpr(misc): Bad p-code imported'; + else + Result := 'Unknown error'; + end; +end; { of procedure TRegExpr.Error +--------------------------------------------------------------} + +function TRegExpr.LastError : Integer; +begin + Result := FLastError; + FLastError := reeOk; +end; { of function TRegExpr.LastError +--------------------------------------------------------------} + + +{=============================================================} +{===================== Common section ========================} +{=============================================================} + +class function TRegExpr.VersionMajor : Integer; //###0.944 +begin + Result := TRegExprVersionMajor; +end; { of class function TRegExpr.VersionMajor +--------------------------------------------------------------} + +class function TRegExpr.VersionMinor : Integer; //###0.944 +begin + Result := TRegExprVersionMinor; +end; { of class function TRegExpr.VersionMinor +--------------------------------------------------------------} + +constructor TRegExpr.Create; +begin + inherited; + programm := nil; + fExpression := nil; + fInputString := nil; + + regexpbeg := nil; + fExprIsCompiled := False; + + ModifierI := RegExprModifierI; + ModifierR := RegExprModifierR; + ModifierS := RegExprModifierS; + ModifierG := RegExprModifierG; + ModifierM := RegExprModifierM; //###0.940 + + SpaceChars := RegExprSpaceChars; //###0.927 + WordChars := RegExprWordChars; //###0.929 + fInvertCase := RegExprInvertCaseFunction; //###0.927 + + FLineSeparators := RegExprLineSeparators; //###0.941 + LinePairedSeparator := RegExprLinePairedSeparator; //###0.941 +end; { of constructor TRegExpr.Create +--------------------------------------------------------------} + +destructor TRegExpr.Destroy; +begin + if programm <> nil then + FreeMem (programm); + if fExpression <> nil then + FreeMem (fExpression); + if fInputString <> nil then + FreeMem (fInputString); +end; { of destructor TRegExpr.Destroy +--------------------------------------------------------------} + +class function TRegExpr.InvertCaseFunction (const Ch : REChar) : REChar; +begin + {$IFDEF SynRegUniCode} + if Ch >= #128 then + Result := Ch + else + {$ENDIF} + begin + Result := {$IFDEF FPC}AnsiUpperCase (Ch) [1]{$ELSE} {$IFDEF MSWINDOWS}REChar (CharUpper (PChar (Ch))){$ELSE}REChar (toupper (Integer (Ch))){$ENDIF} {$ENDIF}; + if Result = Ch then + Result := {$IFDEF FPC}AnsiLowerCase (Ch) [1]{$ELSE} {$IFDEF MSWINDOWS}REChar (CharLower (PChar (Ch))){$ELSE}REChar(tolower (Integer (Ch))){$ENDIF} {$ENDIF}; + end; +end; { of function TRegExpr.InvertCaseFunction +--------------------------------------------------------------} + +function TRegExpr.GetExpression : RegExprString; +begin + if fExpression <> nil then + Result := fExpression + else + Result := ''; +end; { of function TRegExpr.GetExpression +--------------------------------------------------------------} + +procedure TRegExpr.SetExpression (const s : RegExprString); +var + Len : Integer; //###0.950 +begin + if (s <> fExpression) or not fExprIsCompiled then begin + fExprIsCompiled := False; + if fExpression <> nil then begin + FreeMem (fExpression); + fExpression := nil; + end; + if s <> '' then begin + Len := length (s); //###0.950 + GetMem (fExpression, (Len + 1) * SizeOf (REChar)); +// StrPCopy (fExpression, s); //###0.950 replaced due to StrPCopy limitation of 255 chars + {$IFDEF SynRegUniCode} + StrPCopy (fExpression, Copy (s, 1, Len)); //###0.950 + {$ELSE} + StrLCopy (fExpression, PRegExprChar (s), Len); //###0.950 + {$ENDIF SynRegUniCode} + + InvalidateProgramm; //###0.941 + end; + end; +end; { of procedure TRegExpr.SetExpression +--------------------------------------------------------------} + +function TRegExpr.GetSubExprMatchCount : Integer; +begin + if Assigned (fInputString) then begin + Result := NSUBEXP - 1; + while (Result > 0) and ((startp [Result] = nil) + or (endp [Result] = nil)) + do dec (Result); + end + else Result := -1; +end; { of function TRegExpr.GetSubExprMatchCount +--------------------------------------------------------------} + +function TRegExpr.GetMatchPos (Idx : Integer) : Integer; +begin + if (Idx >= 0) and (Idx < NSUBEXP) and Assigned (fInputString) + and Assigned (startp [Idx]) and Assigned (endp [Idx]) then begin + Result := (startp [Idx] - fInputString) + 1; + end + else Result := -1; +end; { of function TRegExpr.GetMatchPos +--------------------------------------------------------------} + +function TRegExpr.GetMatchLen (Idx : Integer) : Integer; +begin + if (Idx >= 0) and (Idx < NSUBEXP) and Assigned (fInputString) + and Assigned (startp [Idx]) and Assigned (endp [Idx]) then begin + Result := endp [Idx] - startp [Idx]; + end + else Result := -1; +end; { of function TRegExpr.GetMatchLen +--------------------------------------------------------------} + +function TRegExpr.GetMatch (Idx : Integer) : RegExprString; +begin + if (Idx >= 0) and (Idx < NSUBEXP) and Assigned (fInputString) + and Assigned (startp [Idx]) and Assigned (endp [Idx]) + //then Result := copy (fInputString, MatchPos [Idx], MatchLen [Idx]) //###0.929 + then SetString (Result, startp [idx], endp [idx] - startp [idx]) + else Result := ''; +end; { of function TRegExpr.GetMatch +--------------------------------------------------------------} + +function TRegExpr.GetModifierStr : RegExprString; +begin + Result := '-'; + + if ModifierI + then Result := 'i' + Result + else Result := Result + 'i'; + if ModifierR + then Result := 'r' + Result + else Result := Result + 'r'; + if ModifierS + then Result := 's' + Result + else Result := Result + 's'; + if ModifierG + then Result := 'g' + Result + else Result := Result + 'g'; + if ModifierM + then Result := 'm' + Result + else Result := Result + 'm'; + if ModifierX + then Result := 'x' + Result + else Result := Result + 'x'; + + if Result [length (Result)] = '-' // remove '-' if all modifiers are 'On' + then System.Delete (Result, length (Result), 1); +end; { of function TRegExpr.GetModifierStr +--------------------------------------------------------------} + +class function TRegExpr.ParseModifiersStr (const AModifiers : RegExprString; + var AModifiersInt: Integer) : Boolean; +// !!! Be carefull - this is class function and must not use object instance fields +var + i : Integer; + IsOn : Boolean; + Mask : Integer; +begin + Result := True; + IsOn := True; + {$IFNDEF SYN_COMPILER_24_UP} + {$IFDEF WIN32} + Mask := 0; // prevent compiler warning + {$ENDIF} + {$ENDIF} + for i := 1 to length (AModifiers) do + if AModifiers [i] = '-' + then IsOn := False + else begin + if Pos (AModifiers [i], 'iI') > 0 + then Mask := MaskModI + else if Pos (AModifiers [i], 'rR') > 0 + then Mask := MaskModR + else if Pos (AModifiers [i], 'sS') > 0 + then Mask := MaskModS + else if Pos (AModifiers [i], 'gG') > 0 + then Mask := MaskModG + else if Pos (AModifiers [i], 'mM') > 0 + then Mask := MaskModM + else if Pos (AModifiers [i], 'xX') > 0 + then Mask := MaskModX + else begin + Result := False; + Exit; + end; + if IsOn + then AModifiersInt := AModifiersInt or Mask + else AModifiersInt := AModifiersInt and not Mask; + end; +end; { of function TRegExpr.ParseModifiersStr +--------------------------------------------------------------} + +procedure TRegExpr.SetModifierStr (const AModifiers : RegExprString); +begin + if not ParseModifiersStr (AModifiers, fModifiers) + then Error (reeModifierUnsupported); +end; { of procedure TRegExpr.SetModifierStr +--------------------------------------------------------------} + +function TRegExpr.GetModifier (AIndex : Integer) : Boolean; +var + Mask : Integer; +begin + Result := False; + case AIndex of + 1: Mask := MaskModI; + 2: Mask := MaskModR; + 3: Mask := MaskModS; + 4: Mask := MaskModG; + 5: Mask := MaskModM; + 6: Mask := MaskModX; + else begin + Error (reeModifierUnsupported); + Exit; + end; + end; + Result := (fModifiers and Mask) <> 0; +end; { of function TRegExpr.GetModifier +--------------------------------------------------------------} + +procedure TRegExpr.SetModifier (AIndex : Integer; ASet : Boolean); +var + Mask : Integer; +begin + case AIndex of + 1: Mask := MaskModI; + 2: Mask := MaskModR; + 3: Mask := MaskModS; + 4: Mask := MaskModG; + 5: Mask := MaskModM; + 6: Mask := MaskModX; + else begin + Error (reeModifierUnsupported); + Exit; + end; + end; + if ASet + then fModifiers := fModifiers or Mask + else fModifiers := fModifiers and not Mask; +end; { of procedure TRegExpr.SetModifier +--------------------------------------------------------------} + + +{=============================================================} +{==================== Compiler section =======================} +{=============================================================} + +procedure TRegExpr.InvalidateProgramm; +begin + if programm <> nil then begin + FreeMem (programm); + programm := nil; + end; +end; { of procedure TRegExpr.InvalidateProgramm +--------------------------------------------------------------} + +procedure TRegExpr.Compile; //###0.941 +begin + if fExpression = nil then begin // No Expression assigned + Error (reeNoExpression); + Exit; + end; + CompileRegExpr (fExpression); +end; { of procedure TRegExpr.Compile +--------------------------------------------------------------} + +function TRegExpr.IsProgrammOk : Boolean; +{$IFNDEF SynRegUniCode} +var + i : Integer; + {$ENDIF} +begin + Result := False; + + // check modifiers + if fModifiers <> fProgModifiers //###0.941 + then InvalidateProgramm; + + // can we optimize line separators by using sets? + {$IFNDEF SynRegUniCode} + FLineSeparatorsSet := []; + for i := 1 to length (FLineSeparators) do + System.Include (FLineSeparatorsSet, FLineSeparators [i]); + {$ENDIF} + + // [Re]compile if needed + if programm = nil + then Compile; //###0.941 + + // check [re]compiled programm + if programm = nil + then Exit // error was set/raised by Compile (was reeExecAfterCompErr) + else if programm [0] <> MAGIC // Program corrupted. + then Error (reeCorruptedProgram) + else Result := True; +end; { of function TRegExpr.IsProgrammOk +--------------------------------------------------------------} + +procedure TRegExpr.Tail (p : PRegExprChar; val : PRegExprChar); +// set the next-pointer at the end of a node chain + var + scan : PRegExprChar; + temp : PRegExprChar; +// i : int64; + begin + if p = @regdummy + then Exit; + // Find last node. + scan := p; + REPEAT + temp := regnext (scan); + if temp = nil + then BREAK; + scan := temp; + UNTIL False; + // Set Next 'pointer' + if val < scan + then PRENextOff (scan + REOpSz)^ := - (scan - val) //###0.948 + // work around PWideChar subtraction bug (Delphi uses + // shr after subtraction to calculate widechar distance %-( ) + // so, if difference is negative we have .. the "feature" :( + // I could wrap it in $IFDEF UniCode, but I didn't because + // "P Q computes the difference between the address given + // by P (the higher address) and the address given by Q (the + // lower address)" - Delphi help quotation. + else PRENextOff (scan + REOpSz)^ := val - scan; //###0.933 + end; { of procedure TRegExpr.Tail +--------------------------------------------------------------} + +procedure TRegExpr.OpTail (p : PRegExprChar; val : PRegExprChar); +// regtail on operand of first argument; nop if operandless + begin + // "Operandless" and "op != BRANCH" are synonymous in practice. + if (p = nil) or (p = @regdummy) or (PREOp (p)^ <> BRANCH) + then Exit; + Tail (p + REOpSz + RENextOffSz, val); //###0.933 + end; { of procedure TRegExpr.OpTail +--------------------------------------------------------------} + +function TRegExpr.EmitNode (op : TREOp) : PRegExprChar; //###0.933 +// emit a node, return location + begin + Result := regcode; + if Result <> @regdummy then begin + PREOp (regcode)^ := op; + inc (regcode, REOpSz); + PRENextOff (regcode)^ := 0; // Next "pointer" := nil + inc (regcode, RENextOffSz); + end + else inc (regsize, REOpSz + RENextOffSz); // compute code size without code generation + end; { of function TRegExpr.EmitNode +--------------------------------------------------------------} + +procedure TRegExpr.EmitC (b : REChar); +// emit a byte to code + begin + if regcode <> @regdummy then begin + regcode^ := b; + inc (regcode); + end + else inc (regsize); // Type of p-code pointer always is ^REChar + end; { of procedure TRegExpr.EmitC +--------------------------------------------------------------} + +procedure TRegExpr.InsertOperator (op : TREOp; opnd : PRegExprChar; sz : Integer); +// insert an operator in front of already-emitted operand +// Means relocating the operand. + var + src, dst, place : PRegExprChar; + i : Integer; + begin + if regcode = @regdummy then begin + inc (regsize, sz); + Exit; + end; + src := regcode; + inc (regcode, sz); + dst := regcode; + while src > opnd do begin + dec (dst); + dec (src); + dst^ := src^; + end; + place := opnd; // Op node, where operand used to be. + PREOp (place)^ := op; + inc (place, REOpSz); + for i := 1 + REOpSz to sz do begin + place^ := #0; + inc (place); + end; + end; { of procedure TRegExpr.InsertOperator +--------------------------------------------------------------} + +function strcspn (s1 : PRegExprChar; s2 : PRegExprChar) : Integer; +// find length of initial segment of s1 consisting +// entirely of characters not from s2 + var scan1, scan2 : PRegExprChar; + begin + Result := 0; + scan1 := s1; + while scan1^ <> #0 do begin + scan2 := s2; + while scan2^ <> #0 do + if scan1^ = scan2^ + then Exit + else inc (scan2); + inc (Result); + inc (scan1) + end; + end; { of function strcspn +--------------------------------------------------------------} + +const +// Flags to be passed up and down. + HASWIDTH = 01; // Known never to match nil string. + SIMPLE = 02; // Simple enough to be STAR/PLUS/BRACES operand. + SPSTART = 04; // Starts with * or +. + WORST = 0; // Worst case. + META : array [0 .. 12] of REChar = ( + '^', '$', '.', '[', '(', ')', '|', '?', '+', '*', EscChar, '{', #0); + // Any modification must be synchronized with QuoteRegExprMetaChars !!! + +{$IFDEF SynRegUniCode} + RusRangeLo : array [0 .. 33] of REChar = + (#$430,#$431,#$432,#$433,#$434,#$435,#$451,#$436,#$437, + #$438,#$439,#$43A,#$43B,#$43C,#$43D,#$43E,#$43F, + #$440,#$441,#$442,#$443,#$444,#$445,#$446,#$447, + #$448,#$449,#$44A,#$44B,#$44C,#$44D,#$44E,#$44F,#0); + RusRangeHi : array [0 .. 33] of REChar = + (#$410,#$411,#$412,#$413,#$414,#$415,#$401,#$416,#$417, + #$418,#$419,#$41A,#$41B,#$41C,#$41D,#$41E,#$41F, + #$420,#$421,#$422,#$423,#$424,#$425,#$426,#$427, + #$428,#$429,#$42A,#$42B,#$42C,#$42D,#$42E,#$42F,#0); + RusRangeLoLow = #$430{''}; + RusRangeLoHigh = #$44F{''}; + RusRangeHiLow = #$410{''}; + RusRangeHiHigh = #$42F{''}; +{$ELSE} + RusRangeLo = ''; + RusRangeHi = 'Ũ'; + RusRangeLoLow = ''; + RusRangeLoHigh = ''; + RusRangeHiLow = ''; + RusRangeHiHigh = ''; +{$ENDIF} + +function TRegExpr.CompileRegExpr (exp : PRegExprChar) : Boolean; +// compile a regular expression into internal code +// We can't allocate space until we know how big the compiled form will be, +// but we can't compile it (and thus know how big it is) until we've got a +// place to put the code. So we cheat: we compile it twice, once with code +// generation turned off and size counting turned on, and once "for real". +// This also means that we don't allocate space until we are sure that the +// thing really will compile successfully, and we never have to move the +// code and thus invalidate pointers into it. (Note that it has to be in +// one piece because free() must be able to free it all.) +// Beware that the optimization-preparation code in here knows about some +// of the structure of the compiled regexp. + var + scan, longest : PRegExprChar; + len : cardinal; + flags : Integer; + begin + Result := False; // life too dark + + regparse := nil; // for correct error handling + regexpbeg := exp; + try + + if programm <> nil then begin + FreeMem (programm); + programm := nil; + end; + + if exp = nil then begin + Error (reeCompNullArgument); + Exit; + end; + + fProgModifiers := fModifiers; + // well, may it's paranoia. I'll check it later... !!!!!!!! + + // First pass: determine size, legality. + fCompModifiers := fModifiers; + regparse := exp; + regnpar := 1; + regsize := 0; + regcode := @regdummy; + EmitC (MAGIC); + if ParseReg (0, flags) = nil + then Exit; + + // Small enough for 2-bytes programm pointers ? + // ###0.933 no real p-code length limits now :))) +// if regsize >= 64 * 1024 then begin +// Error (reeCompRegexpTooBig); +// Exit; +// end; + + // Allocate space. + GetMem (programm, regsize * SizeOf (REChar)); + + // Second pass: emit code. + fCompModifiers := fModifiers; + regparse := exp; + regnpar := 1; + regcode := programm; + EmitC (MAGIC); + if ParseReg (0, flags) = nil + then Exit; + + // Dig out information for optimizations. + {$IFDEF UseFirstCharSet} //###0.929 + FirstCharSet := []; + FillFirstCharSet (programm + REOpSz); + {$ENDIF} + regstart := #0; // Worst-case defaults. + reganch := #0; + regmust := nil; + regmlen := 0; + scan := programm + REOpSz; // First BRANCH. + if PREOp (regnext (scan))^ = EEND then begin // Only one top-level choice. + scan := scan + REOpSz + RENextOffSz; + + // Starting-point info. + if PREOp (scan)^ = EXACTLY + then regstart := (scan + REOpSz + RENextOffSz)^ + else if PREOp (scan)^ = BOL + then inc (reganch); + + // If there's something expensive in the r.e., find the longest + // literal string that must appear and make it the regmust. Resolve + // ties in favor of later strings, since the regstart check works + // with the beginning of the r.e. and avoiding duplication + // strengthens checking. Not a strong reason, but sufficient in the + // absence of others. + if (flags and SPSTART) <> 0 then begin + longest := nil; + len := 0; + while scan <> nil do begin + if (PREOp (scan)^ = EXACTLY) + and (strlen (scan + REOpSz + RENextOffSz) >= len) then begin + longest := scan + REOpSz + RENextOffSz; + len := strlen (longest); + end; + scan := regnext (scan); + end; + regmust := longest; + regmlen := len; + end; + end; + + Result := True; + + finally begin + if not Result + then InvalidateProgramm; + regexpbeg := nil; + fExprIsCompiled := Result; //###0.944 + end; + end; + + end; { of function TRegExpr.CompileRegExpr +--------------------------------------------------------------} + +function TRegExpr.ParseReg (paren : Integer; var flagp : Integer) : PRegExprChar; +// regular expression, i.e. main body or parenthesized thing +// Caller must absorb opening parenthesis. +// Combining parenthesis handling with the base level of regular expression +// is a trifle forced, but the need to tie the tails of the branches to what +// follows makes it hard to avoid. + var + ret, br, ender : PRegExprChar; + parno : Integer; + flags : Integer; + SavedModifiers : Integer; + begin + Result := nil; + flagp := HASWIDTH; // Tentatively. + parno := 0; // eliminate compiler stupid warning + SavedModifiers := fCompModifiers; + + // Make an OPEN node, if parenthesized. + if paren <> 0 then begin + if regnpar >= NSUBEXP then begin + Error (reeCompParseRegTooManyBrackets); + Exit; + end; + parno := regnpar; + inc (regnpar); + ret := EmitNode (TREOp (ord (OPEN) + parno)); + end + else ret := nil; + + // Pick up the branches, linking them together. + br := ParseBranch (flags); + if br = nil then begin + Result := nil; + Exit; + end; + if ret <> nil + then Tail (ret, br) // OPEN -> first. + else ret := br; + if (flags and HASWIDTH) = 0 + then flagp := flagp and not HASWIDTH; + flagp := flagp or flags and SPSTART; + while (regparse^ = '|') do begin + inc (regparse); + br := ParseBranch (flags); + if br = nil then begin + Result := nil; + Exit; + end; + Tail (ret, br); // BRANCH -> BRANCH. + if (flags and HASWIDTH) = 0 + then flagp := flagp and not HASWIDTH; + flagp := flagp or flags and SPSTART; + end; + + // Make a closing node, and hook it on the end. + if paren <> 0 + then ender := EmitNode (TREOp (ord (CLOSE) + parno)) + else ender := EmitNode (EEND); + Tail (ret, ender); + + // Hook the tails of the branches to the closing node. + br := ret; + while br <> nil do begin + OpTail (br, ender); + br := regnext (br); + end; + + // Check for proper termination. + if paren <> 0 then + if regparse^ <> ')' then begin + Error (reeCompParseRegUnmatchedBrackets); + Exit; + end + else inc (regparse); // skip trailing ')' + if (paren = 0) and (regparse^ <> #0) then begin + if regparse^ = ')' + then Error (reeCompParseRegUnmatchedBrackets2) + else Error (reeCompParseRegJunkOnEnd); + Exit; + end; + fCompModifiers := SavedModifiers; // restore modifiers of parent + Result := ret; + end; { of function TRegExpr.ParseReg +--------------------------------------------------------------} + +function TRegExpr.ParseBranch (var flagp : Integer) : PRegExprChar; +// one alternative of an | operator +// Implements the concatenation operator. + var + ret, chain, latest : PRegExprChar; + flags : Integer; + begin + flagp := WORST; // Tentatively. + + ret := EmitNode (BRANCH); + chain := nil; + while (regparse^ <> #0) and (regparse^ <> '|') + and (regparse^ <> ')') do begin + latest := ParsePiece (flags); + if latest = nil then begin + Result := nil; + Exit; + end; + flagp := flagp or flags and HASWIDTH; + if chain = nil // First piece. + then flagp := flagp or flags and SPSTART + else Tail (chain, latest); + chain := latest; + end; + if chain = nil // Loop ran zero times. + then EmitNode (NOTHING); + Result := ret; + end; { of function TRegExpr.ParseBranch +--------------------------------------------------------------} + +function TRegExpr.ParsePiece (var flagp : Integer) : PRegExprChar; +// something followed by possible [*+?{] +// Note that the branching code sequences used for ? and the general cases +// of * and + and { are somewhat optimized: they use the same NOTHING node as +// both the endmarker for their branch list and the body of the last branch. +// It might seem that this node could be dispensed with entirely, but the +// endmarker role is not redundant. + function parsenum (AStart, AEnd : PRegExprChar) : TREBracesArg; + begin + Result := 0; + if AEnd - AStart + 1 > 8 then begin // prevent stupid scanning + Error (reeBRACESArgTooBig); + Exit; + end; + while AStart <= AEnd do begin + Result := Result * 10 + (ord (AStart^) - ord ('0')); + inc (AStart); + end; + if (Result > MaxBracesArg) or (Result < 0) then begin + Error (reeBRACESArgTooBig); + Exit; + end; + end; + + var + op : REChar; + NonGreedyOp, NonGreedyCh : Boolean; //###0.940 + TheOp : TREOp; //###0.940 + NextNode : PRegExprChar; + flags : Integer; + BracesMin, Bracesmax : TREBracesArg; + p, savedparse : PRegExprChar; + + procedure EmitComplexBraces (ABracesMin, ABracesMax : TREBracesArg; + ANonGreedyOp : Boolean); //###0.940 + {$IFDEF ComplexBraces} + var + off : Integer; + {$ENDIF} + begin + {$IFNDEF ComplexBraces} + Error (reeComplexBracesNotImplemented); + {$ELSE} + if ANonGreedyOp + then TheOp := LOOPNG + else TheOp := LOOP; + InsertOperator (LOOPENTRY, Result, REOpSz + RENextOffSz); + NextNode := EmitNode (TheOp); + if regcode <> @regdummy then begin + off := (Result + REOpSz + RENextOffSz) + - (regcode - REOpSz - RENextOffSz); // back to Atom after LOOPENTRY + PREBracesArg (regcode)^ := ABracesMin; + inc (regcode, REBracesArgSz); + PREBracesArg (regcode)^ := ABracesMax; + inc (regcode, REBracesArgSz); + PRENextOff (regcode)^ := off; + inc (regcode, RENextOffSz); + end + else inc (regsize, REBracesArgSz * 2 + RENextOffSz); + Tail (Result, NextNode); // LOOPENTRY -> LOOP + if regcode <> @regdummy then + Tail (Result + REOpSz + RENextOffSz, NextNode); // Atom -> LOOP + {$ENDIF} + end; + + procedure EmitSimpleBraces (ABracesMin, ABracesMax : TREBracesArg; + ANonGreedyOp : Boolean); //###0.940 + begin + if ANonGreedyOp //###0.940 + then TheOp := BRACESNG + else TheOp := BRACES; + InsertOperator (TheOp, Result, REOpSz + RENextOffSz + REBracesArgSz * 2); + if regcode <> @regdummy then begin + PREBracesArg (Result + REOpSz + RENextOffSz)^ := ABracesMin; + PREBracesArg (Result + REOpSz + RENextOffSz + REBracesArgSz)^ := ABracesMax; + end; + end; + + begin + Result := ParseAtom (flags); + if Result = nil + then Exit; + + op := regparse^; + if not ((op = '*') or (op = '+') or (op = '?') or (op = '{')) then begin + flagp := flags; + Exit; + end; + if ((flags and HASWIDTH) = 0) and (op <> '?') then begin + Error (reePlusStarOperandCouldBeEmpty); + Exit; + end; + + case op of + '*': begin + flagp := WORST or SPSTART; + NonGreedyCh := (regparse + 1)^ = '?'; //###0.940 + NonGreedyOp := NonGreedyCh or ((fCompModifiers and MaskModG) = 0); //###0.940 + if (flags and SIMPLE) = 0 then begin + if NonGreedyOp //###0.940 + then EmitComplexBraces (0, MaxBracesArg, NonGreedyOp) + else begin // Emit x* as (x&|), where & means "self". + InsertOperator (BRANCH, Result, REOpSz + RENextOffSz); // Either x + OpTail (Result, EmitNode (BACK)); // and loop + OpTail (Result, Result); // back + Tail (Result, EmitNode (BRANCH)); // or + Tail (Result, EmitNode (NOTHING)); // nil. + end + end + else begin // Simple + if NonGreedyOp //###0.940 + then TheOp := STARNG + else TheOp := STAR; + InsertOperator (TheOp, Result, REOpSz + RENextOffSz); + end; + if NonGreedyCh //###0.940 + then inc (regparse); // Skip extra char ('?') + end; { of case '*'} + '+': begin + flagp := WORST or SPSTART or HASWIDTH; + NonGreedyCh := (regparse + 1)^ = '?'; //###0.940 + NonGreedyOp := NonGreedyCh or ((fCompModifiers and MaskModG) = 0); //###0.940 + if (flags and SIMPLE) = 0 then begin + if NonGreedyOp //###0.940 + then EmitComplexBraces (1, MaxBracesArg, NonGreedyOp) + else begin // Emit x+ as x(&|), where & means "self". + NextNode := EmitNode (BRANCH); // Either + Tail (Result, NextNode); + Tail (EmitNode (BACK), Result); // loop back + Tail (NextNode, EmitNode (BRANCH)); // or + Tail (Result, EmitNode (NOTHING)); // nil. + end + end + else begin // Simple + if NonGreedyOp //###0.940 + then TheOp := PLUSNG + else TheOp := PLUS; + InsertOperator (TheOp, Result, REOpSz + RENextOffSz); + end; + if NonGreedyCh //###0.940 + then inc (regparse); // Skip extra char ('?') + end; { of case '+'} + '?': begin + flagp := WORST; + NonGreedyCh := (regparse + 1)^ = '?'; //###0.940 + NonGreedyOp := NonGreedyCh or ((fCompModifiers and MaskModG) = 0); //###0.940 + if NonGreedyOp then begin //###0.940 // We emit x?? as x{0,1}? + if (flags and SIMPLE) = 0 + then EmitComplexBraces (0, 1, NonGreedyOp) + else EmitSimpleBraces (0, 1, NonGreedyOp); + end + else begin // greedy '?' + InsertOperator (BRANCH, Result, REOpSz + RENextOffSz); // Either x + Tail (Result, EmitNode (BRANCH)); // or + NextNode := EmitNode (NOTHING); // nil. + Tail (Result, NextNode); + OpTail (Result, NextNode); + end; + if NonGreedyCh //###0.940 + then inc (regparse); // Skip extra char ('?') + end; { of case '?'} + '{': begin + savedparse := regparse; + // !!!!!!!!!!!! + // Filip Jirsak's note - what will happen, when we are at the end of regparse? + inc (regparse); + p := regparse; + while Pos (regparse^, '0123456789') > 0 // MUST appear + do inc (regparse); + if (regparse^ <> '}') and (regparse^ <> ',') or (p = regparse) then begin + regparse := savedparse; + flagp := flags; + Exit; + end; + BracesMin := parsenum (p, regparse - 1); + if regparse^ = ',' then begin + inc (regparse); + p := regparse; + while Pos (regparse^, '0123456789') > 0 + do inc (regparse); + if regparse^ <> '}' then begin + regparse := savedparse; + Exit; + end; + if p = regparse + then BracesMax := MaxBracesArg + else BracesMax := parsenum (p, regparse - 1); + end + else BracesMax := BracesMin; // {n} == {n,n} + if BracesMin > BracesMax then begin + Error (reeBracesMinParamGreaterMax); + Exit; + end; + if BracesMin > 0 + then flagp := WORST; + if BracesMax > 0 + then flagp := flagp or HASWIDTH or SPSTART; + + NonGreedyCh := (regparse + 1)^ = '?'; //###0.940 + NonGreedyOp := NonGreedyCh or ((fCompModifiers and MaskModG) = 0); //###0.940 + if (flags and SIMPLE) <> 0 + then EmitSimpleBraces (BracesMin, BracesMax, NonGreedyOp) + else EmitComplexBraces (BracesMin, BracesMax, NonGreedyOp); + if NonGreedyCh //###0.940 + then inc (regparse); // Skip extra char '?' + end; { of case '{'} +// else // here we can't be + end; { of case op} + + inc (regparse); + if (regparse^ = '*') or (regparse^ = '+') or (regparse^ = '?') or (regparse^ = '{') then begin + Error (reeNestedSQP); + Exit; + end; + end; { of function TRegExpr.ParsePiece +--------------------------------------------------------------} + +function TRegExpr.ParseAtom (var flagp : Integer) : PRegExprChar; +// the lowest level +// Optimization: gobbles an entire sequence of ordinary characters so that +// it can turn them into a single node, which is smaller to store and +// faster to run. Backslashed characters are exceptions, each becoming a +// separate node; the code is simpler that way and it's not worth fixing. + var + ret : PRegExprChar; + flags : Integer; + RangeBeg, RangeEnd : REChar; + CanBeRange : Boolean; + len : Integer; + ender : REChar; + begmodfs : PRegExprChar; + + {$IFDEF UseSetOfChar} //###0.930 + RangePCodeBeg : PRegExprChar; + RangePCodeIdx : Integer; + RangeIsCI : Boolean; + RangeSet : TSetOfREChar; + RangeLen : Integer; + RangeChMin, RangeChMax : REChar; + {$ENDIF} + + procedure EmitExactly (ch : REChar); + begin + if (fCompModifiers and MaskModI) <> 0 + then ret := EmitNode (EXACTLYCI) + else ret := EmitNode (EXACTLY); + EmitC (ch); + EmitC (#0); + flagp := flagp or HASWIDTH or SIMPLE; + end; + + procedure EmitStr (const s : RegExprString); + var i : Integer; + begin + for i := 1 to length (s) + do EmitC (s [i]); + end; + + function HexDig (ch : REChar) : Integer; + begin + Result := 0; + if (ch >= 'a') and (ch <= 'f') + then ch := REChar (ord (ch) - (ord ('a') - ord ('A'))); + if (ch < '0') or (ch > 'F') or ((ch > '9') and (ch < 'A')) then begin + Error (reeBadHexDigit); + Exit; + end; + Result := ord (ch) - ord ('0'); + if ch >= 'A' + then Result := Result - (ord ('A') - ord ('9') - 1); + end; + + function EmitRange (AOpCode : REChar) : PRegExprChar; + begin + {$IFDEF UseSetOfChar} + case AOpCode of + ANYBUTCI, ANYBUT: + Result := EmitNode (ANYBUTTINYSET); + else // ANYOFCI, ANYOF + Result := EmitNode (ANYOFTINYSET); + end; + case AOpCode of + ANYBUTCI, ANYOFCI: + RangeIsCI := True; + else // ANYBUT, ANYOF + RangeIsCI := False; + end; + RangePCodeBeg := regcode; + RangePCodeIdx := regsize; + RangeLen := 0; + RangeSet := []; + RangeChMin := #255; + RangeChMax := #0; + {$ELSE} + Result := EmitNode (AOpCode); + // ToDo: + // !!!!!!!!!!!!! Implement ANYOF[BUT]TINYSET generation for UniCode !!!!!!!!!! + {$ENDIF} + end; + +{$IFDEF UseSetOfChar} + procedure EmitRangeCPrim (b : REChar); //###0.930 + begin + if b in RangeSet + then Exit; + inc (RangeLen); + if b < RangeChMin + then RangeChMin := b; + if b > RangeChMax + then RangeChMax := b; + Include (RangeSet, b); + end; + {$ENDIF} + + procedure EmitRangeC (b : REChar); + {$IFDEF UseSetOfChar} + var + Ch : REChar; + {$ENDIF} + begin + CanBeRange := False; + {$IFDEF UseSetOfChar} + if b <> #0 then begin + EmitRangeCPrim (b); //###0.930 + if RangeIsCI + then EmitRangeCPrim (InvertCase (b)); //###0.930 + end + else begin + {$IFDEF UseAsserts} + Assert (RangeLen > 0, 'TRegExpr.ParseAtom(subroutine EmitRangeC): empty range'); // impossible, but who knows.. + Assert (RangeChMin <= RangeChMax, 'TRegExpr.ParseAtom(subroutine EmitRangeC): RangeChMin > RangeChMax'); // impossible, but who knows.. + {$ENDIF} + if RangeLen <= TinySetLen then begin // emit "tiny set" + if regcode = @regdummy then begin + regsize := RangePCodeIdx + TinySetLen; // RangeChMin/Max !!! + Exit; + end; + regcode := RangePCodeBeg; + for Ch := RangeChMin to RangeChMax do //###0.930 + if Ch in RangeSet then begin + regcode^ := Ch; + inc (regcode); + end; + // fill rest: + while regcode < RangePCodeBeg + TinySetLen do begin + regcode^ := RangeChMax; + inc (regcode); + end; + end + else begin + if regcode = @regdummy then begin + regsize := RangePCodeIdx + SizeOf (TSetOfREChar); + Exit; + end; + if (RangePCodeBeg - REOpSz - RENextOffSz)^ = ANYBUTTINYSET + then RangeSet := [#0 .. #255] - RangeSet; + PREOp (RangePCodeBeg - REOpSz - RENextOffSz)^ := ANYOFFULLSET; + regcode := RangePCodeBeg; + Move (RangeSet, regcode^, SizeOf (TSetOfREChar)); + inc (regcode, SizeOf (TSetOfREChar)); + end; + end; + {$ELSE} + EmitC (b); + {$ENDIF} + end; + + procedure EmitSimpleRangeC (b : REChar); + begin + RangeBeg := b; + EmitRangeC (b); + CanBeRange := True; + end; + + procedure EmitRangeStr (const s : RegExprString); + var i : Integer; + begin + for i := 1 to length (s) + do EmitRangeC (s [i]); + end; + + function UnQuoteChar (var APtr : PRegExprChar) : REChar; //###0.934 + begin + case APtr^ of + 't': Result := #$9; // tab (HT/TAB) + 'n': Result := #$a; // newline (NL) + 'r': Result := #$d; // car.return (CR) + 'f': Result := #$c; // form feed (FF) + 'a': Result := #$7; // alarm (bell) (BEL) + 'e': Result := #$1b; // escape (ESC) + 'x': begin // hex char + Result := #0; + inc (APtr); + if APtr^ = #0 then begin + Error (reeNoHexCodeAfterBSlashX); + Exit; + end; + if APtr^ = '{' then begin // \x{nnnn} //###0.936 + repeat + inc (APtr); + if APtr^ = #0 then begin + Error (reeNoHexCodeAfterBSlashX); + Exit; + end; + if APtr^ <> '}' then begin + if (Ord (Result) + shr (SizeOf (REChar) * 8 - 4)) and $F <> 0 then begin + Error (reeHexCodeAfterBSlashXTooBig); + Exit; + end; + Result := REChar ((Ord (Result) ShL 4) or HexDig (APtr^)); + // HexDig will cause Error if bad hex digit found + end + else BREAK; + until False; + end + else begin + Result := REChar (HexDig (APtr^)); + // HexDig will cause Error if bad hex digit found + inc (APtr); + if APtr^ = #0 then begin + Error (reeNoHexCodeAfterBSlashX); + Exit; + end; + Result := REChar ((Ord (Result) ShL 4) or HexDig (APtr^)); + // HexDig will cause Error if bad hex digit found + end; + end; + else Result := APtr^; + end; + end; + + begin + Result := nil; + flagp := WORST; // Tentatively. + + inc (regparse); + case (regparse - 1)^ of + '^': if ((fCompModifiers and MaskModM) = 0) + or ((FLineSeparators = '') and not fLinePairedSeparatorAssigned) + then ret := EmitNode (BOL) + else ret := EmitNode (BOLML); + '$': if ((fCompModifiers and MaskModM) = 0) + or ((FLineSeparators = '') and not fLinePairedSeparatorAssigned) + then ret := EmitNode (EOL) + else ret := EmitNode (EOLML); + '.': + if (fCompModifiers and MaskModS) <> 0 then begin + ret := EmitNode (ANY); + flagp := flagp or HASWIDTH or SIMPLE; + end + else begin // not /s, so emit [^:LineSeparators:] + ret := EmitNode (ANYML); + flagp := flagp or HASWIDTH; // not so simple ;) +// ret := EmitRange (ANYBUT); +// EmitRangeStr (LineSeparators); //###0.941 +// EmitRangeStr (LinePairedSeparator); // !!! isn't correct if have to accept only paired +// EmitRangeC (#0); +// flagp := flagp or HASWIDTH or SIMPLE; + end; + '[': begin + if regparse^ = '^' then begin // Complement of range. + if (fCompModifiers and MaskModI) <> 0 + then ret := EmitRange (ANYBUTCI) + else ret := EmitRange (ANYBUT); + inc (regparse); + end + else + if (fCompModifiers and MaskModI) <> 0 + then ret := EmitRange (ANYOFCI) + else ret := EmitRange (ANYOF); + + CanBeRange := False; + + if (regparse^ = ']') then begin + EmitSimpleRangeC (regparse^); // []-a] -> ']' .. 'a' + inc (regparse); + end; + + while (regparse^ <> #0) and (regparse^ <> ']') do begin + if (regparse^ = '-') + and ((regparse + 1)^ <> #0) and ((regparse + 1)^ <> ']') + and CanBeRange then begin + inc (regparse); + RangeEnd := regparse^; + if RangeEnd = EscChar then begin + {$IFDEF SynRegUniCode} //###0.935 + if (ord ((regparse + 1)^) < 256) + and (ansichar ((regparse + 1)^) + in ['d', 'D', 's', 'S', 'w', 'W']) then begin + {$ELSE} + if (regparse + 1)^ in ['d', 'D', 's', 'S', 'w', 'W'] then begin + {$ENDIF} + EmitRangeC ('-'); // or treat as error ?!! + CONTINUE; + end; + inc (regparse); + RangeEnd := UnQuoteChar (regparse); + end; + + // r.e.ranges extension for russian + if ((fCompModifiers and MaskModR) <> 0) + and (RangeBeg = RusRangeLoLow) and (RangeEnd = RusRangeLoHigh) then begin + EmitRangeStr (RusRangeLo); + end + else if ((fCompModifiers and MaskModR) <> 0) + and (RangeBeg = RusRangeHiLow) and (RangeEnd = RusRangeHiHigh) then begin + EmitRangeStr (RusRangeHi); + end + else if ((fCompModifiers and MaskModR) <> 0) + and (RangeBeg = RusRangeLoLow) and (RangeEnd = RusRangeHiHigh) then begin + EmitRangeStr (RusRangeLo); + EmitRangeStr (RusRangeHi); + end + else begin // standard r.e. handling + if RangeBeg > RangeEnd then begin + Error (reeInvalidRange); + Exit; + end; + inc (RangeBeg); + EmitRangeC (RangeEnd); // prevent infinite loop if RangeEnd=$ff + while RangeBeg < RangeEnd do begin //###0.929 + EmitRangeC (RangeBeg); + inc (RangeBeg); + end; + end; + inc (regparse); + end + else begin + if regparse^ = EscChar then begin + inc (regparse); + if regparse^ = #0 then begin + Error (reeParseAtomTrailingBackSlash); + Exit; + end; + case regparse^ of // r.e.extensions + 'd': EmitRangeStr ('0123456789'); + 'w': EmitRangeStr (WordChars); + 's': EmitRangeStr (SpaceChars); + else EmitSimpleRangeC (UnQuoteChar (regparse)); + end; { of case} + end + else EmitSimpleRangeC (regparse^); + inc (regparse); + end; + end; { of while} + EmitRangeC (#0); + if regparse^ <> ']' then begin + Error (reeUnmatchedSqBrackets); + Exit; + end; + inc (regparse); + flagp := flagp or HASWIDTH or SIMPLE; + end; + '(': begin + if regparse^ = '?' then begin + // check for extended Perl syntax : (?..) + if (regparse + 1)^ = '#' then begin // (?#comment) + inc (regparse, 2); // find closing ')' + while (regparse^ <> #0) and (regparse^ <> ')') + do inc (regparse); + if regparse^ <> ')' then begin + Error (reeUnclosedComment); + Exit; + end; + inc (regparse); // skip ')' + ret := EmitNode (COMMENT); // comment + end + else begin // modifiers ? + inc (regparse); // skip '?' + begmodfs := regparse; + while (regparse^ <> #0) and (regparse^ <> ')') + do inc (regparse); + if (regparse^ <> ')') + or not ParseModifiersStr (copy (begmodfs, 1, (regparse - begmodfs)), fCompModifiers) then begin + Error (reeUrecognizedModifier); + Exit; + end; + inc (regparse); // skip ')' + ret := EmitNode (COMMENT); // comment +// Error (reeQPSBFollowsNothing); +// Exit; + end; + end + else begin + ret := ParseReg (1, flags); + if ret = nil then begin + Result := nil; + Exit; + end; + flagp := flagp or flags and (HASWIDTH or SPSTART); + end; + end; + #0, '|', ')': begin // Supposed to be caught earlier. + Error (reeInternalUrp); + Exit; + end; + '?', '+', '*': begin + Error (reeQPSBFollowsNothing); + Exit; + end; + EscChar: begin + if regparse^ = #0 then begin + Error (reeTrailingBackSlash); + Exit; + end; + case regparse^ of // r.e.extensions + 'b': ret := EmitNode (BOUND); //###0.943 + 'B': ret := EmitNode (NOTBOUND); //###0.943 + 'A': ret := EmitNode (BOL); //###0.941 + 'Z': ret := EmitNode (EOL); //###0.941 + 'd': begin // r.e.extension - any digit ('0' .. '9') + ret := EmitNode (ANYDIGIT); + flagp := flagp or HASWIDTH or SIMPLE; + end; + 'D': begin // r.e.extension - not digit ('0' .. '9') + ret := EmitNode (NOTDIGIT); + flagp := flagp or HASWIDTH or SIMPLE; + end; + 's': begin // r.e.extension - any space char + {$IFDEF UseSetOfChar} + ret := EmitRange (ANYOF); + EmitRangeStr (SpaceChars); + EmitRangeC (#0); + {$ELSE} + ret := EmitNode (ANYSPACE); + {$ENDIF} + flagp := flagp or HASWIDTH or SIMPLE; + end; + 'S': begin // r.e.extension - not space char + {$IFDEF UseSetOfChar} + ret := EmitRange (ANYBUT); + EmitRangeStr (SpaceChars); + EmitRangeC (#0); + {$ELSE} + ret := EmitNode (NOTSPACE); + {$ENDIF} + flagp := flagp or HASWIDTH or SIMPLE; + end; + 'w': begin // r.e.extension - any english char / digit / '_' + {$IFDEF UseSetOfChar} + ret := EmitRange (ANYOF); + EmitRangeStr (WordChars); + EmitRangeC (#0); + {$ELSE} + ret := EmitNode (ANYLETTER); + {$ENDIF} + flagp := flagp or HASWIDTH or SIMPLE; + end; + 'W': begin // r.e.extension - not english char / digit / '_' + {$IFDEF UseSetOfChar} + ret := EmitRange (ANYBUT); + EmitRangeStr (WordChars); + EmitRangeC (#0); + {$ELSE} + ret := EmitNode (NOTLETTER); + {$ENDIF} + flagp := flagp or HASWIDTH or SIMPLE; + end; + '1' .. '9': begin //###0.936 + if (fCompModifiers and MaskModI) <> 0 + then ret := EmitNode (BSUBEXPCI) + else ret := EmitNode (BSUBEXP); + EmitC (REChar (ord (regparse^) - ord ('0'))); + flagp := flagp or HASWIDTH or SIMPLE; + end; + else EmitExactly (UnQuoteChar (regparse)); + end; { of case} + inc (regparse); + end; + else begin + dec (regparse); + if ((fCompModifiers and MaskModX) <> 0) and // check for eXtended syntax + ((regparse^ = '#') + or ({$IFDEF SynRegUniCode}StrScan (XIgnoredChars, regparse^) <> nil //###0.947 + {$ELSE}regparse^ in XIgnoredChars{$ENDIF})) then begin //###0.941 \x + if regparse^ = '#' then begin // Skip eXtended comment + // find comment terminator (group of \n and/or \r) + while (regparse^ <> #0) and (regparse^ <> #$d) and (regparse^ <> #$a) + do inc (regparse); + while (regparse^ = #$d) or (regparse^ = #$a) // skip comment terminator + do inc (regparse); // attempt to support different type of line separators + end + else begin // Skip the blanks! + while {$IFDEF SynRegUniCode}StrScan (XIgnoredChars, regparse^) <> nil //###0.947 + {$ELSE}regparse^ in XIgnoredChars{$ENDIF} + do inc (regparse); + end; + ret := EmitNode (COMMENT); // comment + end + else begin + len := strcspn (regparse, META); + if len <= 0 then + if regparse^ <> '{' then begin + Error (reeRarseAtomInternalDisaster); + Exit; + end + else len := strcspn (regparse + 1, META) + 1; // bad {n,m} - compile as EXATLY + ender := (regparse + len)^; + if (len > 1) + and ((ender = '*') or (ender = '+') or (ender = '?') or (ender = '{')) + then dec (len); // Back off clear of ?+*{ operand. + flagp := flagp or HASWIDTH; + if len = 1 + then flagp := flagp or SIMPLE; + if (fCompModifiers and MaskModI) <> 0 + then ret := EmitNode (EXACTLYCI) + else ret := EmitNode (EXACTLY); + while (len > 0) + and (((fCompModifiers and MaskModX) = 0) or (regparse^ <> '#')) do begin + if ((fCompModifiers and MaskModX) = 0) or not ( //###0.941 + {$IFDEF SynRegUniCode}StrScan (XIgnoredChars, regparse^) <> nil //###0.947 + {$ELSE}regparse^ in XIgnoredChars{$ENDIF} ) + then EmitC (regparse^); + inc (regparse); + dec (len); + end; + EmitC (#0); + end; { of if not comment} + end; { of case else} + end; { of case} + + Result := ret; + end; { of function TRegExpr.ParseAtom +--------------------------------------------------------------} + +function TRegExpr.GetCompilerErrorPos : Integer; + begin + Result := 0; + if (regexpbeg = nil) or (regparse = nil) + then Exit; // not in compiling mode ? + Result := regparse - regexpbeg; + end; { of function TRegExpr.GetCompilerErrorPos +--------------------------------------------------------------} + + +{=============================================================} +{===================== Matching section ======================} +{=============================================================} + +{$IFNDEF UseSetOfChar} +function TRegExpr.StrScanCI (s : PRegExprChar; ch : REChar) : PRegExprChar; //###0.928 - now method of TRegExpr + begin + while (s^ <> #0) and (s^ <> ch) and (s^ <> InvertCase (ch)) + do inc (s); + if s^ <> #0 + then Result := s + else Result := nil; + end; { of function TRegExpr.StrScanCI +--------------------------------------------------------------} +{$ENDIF} + +function TRegExpr.regrepeat (p : PRegExprChar; AMax : Integer) : Integer; +// repeatedly match something simple, report how many + var + scan : PRegExprChar; + opnd : PRegExprChar; + TheMax : Integer; + {Ch,} InvCh : REChar; //###0.931 + sestart, seend : PRegExprChar; //###0.936 + begin + Result := 0; + scan := reginput; + opnd := p + REOpSz + RENextOffSz; //OPERAND + TheMax := fInputEnd - scan; + if TheMax > AMax + then TheMax := AMax; + case PREOp (p)^ of + ANY: begin + // note - ANYML cannot be proceeded in regrepeat because can skip + // more than one char at once + Result := TheMax; + inc (scan, Result); + end; + EXACTLY: begin // in opnd can be only ONE char !!! +// Ch := opnd^; // store in register //###0.931 + while (Result < TheMax) and (opnd^ = scan^) do begin + inc (Result); + inc (scan); + end; + end; + EXACTLYCI: begin // in opnd can be only ONE char !!! +// Ch := opnd^; // store in register //###0.931 + while (Result < TheMax) and (opnd^ = scan^) do begin // prevent unneeded InvertCase //###0.931 + inc (Result); + inc (scan); + end; + if Result < TheMax then begin //###0.931 + InvCh := InvertCase (opnd^); // store in register + while (Result < TheMax) and + ((opnd^ = scan^) or (InvCh = scan^)) do begin + inc (Result); + inc (scan); + end; + end; + end; + BSUBEXP: begin //###0.936 + sestart := startp [ord (opnd^)]; + if sestart = nil + then Exit; + seend := endp [ord (opnd^)]; + if seend = nil + then Exit; + repeat + opnd := sestart; + while opnd < seend do begin + if (scan >= fInputEnd) or (scan^ <> opnd^) + then Exit; + inc (scan); + inc (opnd); + end; + inc (Result); + reginput := scan; + until Result >= AMax; + end; + BSUBEXPCI: begin //###0.936 + sestart := startp [ord (opnd^)]; + if sestart = nil + then Exit; + seend := endp [ord (opnd^)]; + if seend = nil + then Exit; + repeat + opnd := sestart; + while opnd < seend do begin + if (scan >= fInputEnd) or + ((scan^ <> opnd^) and (scan^ <> InvertCase (opnd^))) + then Exit; + inc (scan); + inc (opnd); + end; + inc (Result); + reginput := scan; + until Result >= AMax; + end; + ANYDIGIT: + while (Result < TheMax) and + (scan^ >= '0') and (scan^ <= '9') do begin + inc (Result); + inc (scan); + end; + NOTDIGIT: + while (Result < TheMax) and + ((scan^ < '0') or (scan^ > '9')) do begin + inc (Result); + inc (scan); + end; + {$IFNDEF UseSetOfChar} //###0.929 + ANYLETTER: + while (Result < TheMax) and + (Pos (scan^, fWordChars) > 0) //###0.940 + { ((scan^ >= 'a') and (scan^ <= 'z') !! I've forgotten (>='0') and (<='9') + or (scan^ >= 'A') and (scan^ <= 'Z') or (scan^ = '_'))} do begin + inc (Result); + inc (scan); + end; + NOTLETTER: + while (Result < TheMax) and + (Pos (scan^, fWordChars) <= 0) //###0.940 + { not ((scan^ >= 'a') and (scan^ <= 'z') !! I've forgotten (>='0') and (<='9') + or (scan^ >= 'A') and (scan^ <= 'Z') + or (scan^ = '_'))} do begin + inc (Result); + inc (scan); + end; + ANYSPACE: + while (Result < TheMax) and + (Pos (scan^, fSpaceChars) > 0) do begin + inc (Result); + inc (scan); + end; + NOTSPACE: + while (Result < TheMax) and + (Pos (scan^, fSpaceChars) <= 0) do begin + inc (Result); + inc (scan); + end; + {$ENDIF} + ANYOFTINYSET: begin + while (Result < TheMax) and //!!!TinySet + ((scan^ = opnd^) or (scan^ = (opnd + 1)^) + or (scan^ = (opnd + 2)^)) do begin + inc (Result); + inc (scan); + end; + end; + ANYBUTTINYSET: begin + while (Result < TheMax) and //!!!TinySet + (scan^ <> opnd^) and (scan^ <> (opnd + 1)^) + and (scan^ <> (opnd + 2)^) do begin + inc (Result); + inc (scan); + end; + end; + {$IFDEF UseSetOfChar} //###0.929 + ANYOFFULLSET: begin + while (Result < TheMax) and + (scan^ in PSetOfREChar (opnd)^) do begin + inc (Result); + inc (scan); + end; + end; + {$ELSE} + ANYOF: + while (Result < TheMax) and + (StrScan (opnd, scan^) <> nil) do begin + inc (Result); + inc (scan); + end; + ANYBUT: + while (Result < TheMax) and + (StrScan (opnd, scan^) = nil) do begin + inc (Result); + inc (scan); + end; + ANYOFCI: + while (Result < TheMax) and (StrScanCI (opnd, scan^) <> nil) do begin + inc (Result); + inc (scan); + end; + ANYBUTCI: + while (Result < TheMax) and (StrScanCI (opnd, scan^) = nil) do begin + inc (Result); + inc (scan); + end; + {$ENDIF} + else begin // Oh dear. Called inappropriately. + Result := 0; // Best compromise. + Error (reeRegRepeatCalledInappropriately); + Exit; + end; + end; { of case} + reginput := scan; + end; { of function TRegExpr.regrepeat +--------------------------------------------------------------} + +function TRegExpr.regnext (p : PRegExprChar) : PRegExprChar; +// dig the "next" pointer out of a node + var offset : TRENextOff; + begin + if p = @regdummy then begin + Result := nil; + Exit; + end; + offset := PRENextOff (p + REOpSz)^; //###0.933 inlined NEXT + if offset = 0 + then Result := nil + else Result := p + offset; + end; { of function TRegExpr.regnext +--------------------------------------------------------------} + +function TRegExpr.MatchPrim (prog : PRegExprChar) : Boolean; +// recursively matching routine +// Conceptually the strategy is simple: check to see whether the current +// node matches, call self recursively to see whether the rest matches, +// and then act accordingly. In practice we make some effort to avoid +// recursion, in particular by going through "ordinary" nodes (that don't +// need to know whether the rest of the match failed) by a loop instead of +// by recursion. + var + scan : PRegExprChar; // Current node. + next : PRegExprChar; // Next node. + len : Integer; + opnd : PRegExprChar; + no : Integer; + save : PRegExprChar; + nextch : REChar; + BracesMin, BracesMax : Integer; // we use Integer instead of TREBracesArg for better support */+ + {$IFDEF ComplexBraces} + SavedLoopStack : array [1 .. LoopStackMax] of Integer; // :(( very bad for recursion + SavedLoopStackIdx : Integer; //###0.925 + {$ENDIF} + begin + Result := False; + scan := prog; + + while scan <> nil do begin + len := PRENextOff (scan + 1)^; //###0.932 inlined regnext + if len = 0 + then next := nil + else next := scan + len; + + case scan^ of + NOTBOUND, //###0.943 //!!! think about UseSetOfChar !!! + BOUND: + if (scan^ = BOUND) + xor ( + ((reginput = fInputStart) or (Pos ((reginput - 1)^, fWordChars) <= 0)) + and (reginput^ <> #0) and (Pos (reginput^, fWordChars) > 0) + or + (reginput <> fInputStart) and (Pos ((reginput - 1)^, fWordChars) > 0) + and ((reginput^ = #0) or (Pos (reginput^, fWordChars) <= 0))) + then Exit; + + BOL: if reginput <> fInputStart + then Exit; + EOL: if reginput^ <> #0 + then Exit; + BOLML: if reginput > fInputStart then begin + nextch := (reginput - 1)^; + if (nextch <> fLinePairedSeparatorTail) + or ((reginput - 1) <= fInputStart) + or ((reginput - 2)^ <> fLinePairedSeparatorHead) + then begin + if (nextch = fLinePairedSeparatorHead) + and (reginput^ = fLinePairedSeparatorTail) + then Exit; // don't stop between paired separator + if + {$IFNDEF SynRegUniCode} + not (nextch in FLineSeparatorsSet) + {$ELSE} + (pos (nextch, FLineSeparators) <= 0) + {$ENDIF} + then Exit; + end; + end; + EOLML: if reginput^ <> #0 then begin + nextch := reginput^; + if (nextch <> fLinePairedSeparatorHead) + or ((reginput + 1)^ <> fLinePairedSeparatorTail) + then begin + if (nextch = fLinePairedSeparatorTail) + and (reginput > fInputStart) + and ((reginput - 1)^ = fLinePairedSeparatorHead) + then Exit; // don't stop between paired separator + if + {$IFNDEF SynRegUniCode} + not (nextch in FLineSeparatorsSet) + {$ELSE} + (pos (nextch, FLineSeparators) <= 0) + {$ENDIF} + then Exit; + end; + end; + ANY: begin + if reginput^ = #0 + then Exit; + inc (reginput); + end; + ANYML: begin //###0.941 + if (reginput^ = #0) + or ((reginput^ = fLinePairedSeparatorHead) + and ((reginput + 1)^ = fLinePairedSeparatorTail)) + or {$IFNDEF SynRegUniCode} (reginput^ in FLineSeparatorsSet) + {$ELSE} (pos (reginput^, FLineSeparators) > 0) {$ENDIF} + then Exit; + inc (reginput); + end; + ANYDIGIT: begin + if (reginput^ = #0) or (reginput^ < '0') or (reginput^ > '9') + then Exit; + inc (reginput); + end; + NOTDIGIT: begin + if (reginput^ = #0) or ((reginput^ >= '0') and (reginput^ <= '9')) + then Exit; + inc (reginput); + end; + {$IFNDEF UseSetOfChar} //###0.929 + ANYLETTER: begin + if (reginput^ = #0) or (Pos (reginput^, fWordChars) <= 0) //###0.943 + then Exit; + inc (reginput); + end; + NOTLETTER: begin + if (reginput^ = #0) or (Pos (reginput^, fWordChars) > 0) //###0.943 + then Exit; + inc (reginput); + end; + ANYSPACE: begin + if (reginput^ = #0) or not (Pos (reginput^, fSpaceChars) > 0) //###0.943 + then Exit; + inc (reginput); + end; + NOTSPACE: begin + if (reginput^ = #0) or (Pos (reginput^, fSpaceChars) > 0) //###0.943 + then Exit; + inc (reginput); + end; + {$ENDIF} + EXACTLYCI: begin + opnd := scan + REOpSz + RENextOffSz; // OPERAND + // Inline the first character, for speed. + if (opnd^ <> reginput^) + and (InvertCase (opnd^) <> reginput^) + then Exit; + len := strlen (opnd); + //###0.929 begin + no := len; + save := reginput; + while no > 1 do begin + inc (save); + inc (opnd); + if (opnd^ <> save^) + and (InvertCase (opnd^) <> save^) + then Exit; + dec (no); + end; + //###0.929 end + inc (reginput, len); + end; + EXACTLY: begin + opnd := scan + REOpSz + RENextOffSz; // OPERAND + // Inline the first character, for speed. + if opnd^ <> reginput^ + then Exit; + len := strlen (opnd); + //###0.929 begin + no := len; + save := reginput; + while no > 1 do begin + inc (save); + inc (opnd); + if opnd^ <> save^ + then Exit; + dec (no); + end; + //###0.929 end + inc (reginput, len); + end; + BSUBEXP: begin //###0.936 + no := ord ((scan + REOpSz + RENextOffSz)^); + if startp [no] = nil + then Exit; + if endp [no] = nil + then Exit; + save := reginput; + opnd := startp [no]; + while opnd < endp [no] do begin + if (save >= fInputEnd) or (save^ <> opnd^) + then Exit; + inc (save); + inc (opnd); + end; + reginput := save; + end; + BSUBEXPCI: begin //###0.936 + no := ord ((scan + REOpSz + RENextOffSz)^); + if startp [no] = nil + then Exit; + if endp [no] = nil + then Exit; + save := reginput; + opnd := startp [no]; + while opnd < endp [no] do begin + if (save >= fInputEnd) or + ((save^ <> opnd^) and (save^ <> InvertCase (opnd^))) + then Exit; + inc (save); + inc (opnd); + end; + reginput := save; + end; + ANYOFTINYSET: begin + if (reginput^ = #0) or //!!!TinySet + ((reginput^ <> (scan + REOpSz + RENextOffSz)^) + and (reginput^ <> (scan + REOpSz + RENextOffSz + 1)^) + and (reginput^ <> (scan + REOpSz + RENextOffSz + 2)^)) + then Exit; + inc (reginput); + end; + ANYBUTTINYSET: begin + if (reginput^ = #0) or //!!!TinySet + (reginput^ = (scan + REOpSz + RENextOffSz)^) + or (reginput^ = (scan + REOpSz + RENextOffSz + 1)^) + or (reginput^ = (scan + REOpSz + RENextOffSz + 2)^) + then Exit; + inc (reginput); + end; + {$IFDEF UseSetOfChar} //###0.929 + ANYOFFULLSET: begin + if (reginput^ = #0) + or not (reginput^ in PSetOfREChar (scan + REOpSz + RENextOffSz)^) + then Exit; + inc (reginput); + end; + {$ELSE} + ANYOF: begin + if (reginput^ = #0) or (StrScan (scan + REOpSz + RENextOffSz, reginput^) = nil) + then Exit; + inc (reginput); + end; + ANYBUT: begin + if (reginput^ = #0) or (StrScan (scan + REOpSz + RENextOffSz, reginput^) <> nil) + then Exit; + inc (reginput); + end; + ANYOFCI: begin + if (reginput^ = #0) or (StrScanCI (scan + REOpSz + RENextOffSz, reginput^) = nil) + then Exit; + inc (reginput); + end; + ANYBUTCI: begin + if (reginput^ = #0) or (StrScanCI (scan + REOpSz + RENextOffSz, reginput^) <> nil) + then Exit; + inc (reginput); + end; + {$ENDIF} + NOTHING: ; + COMMENT: ; + BACK: ; + Succ (OPEN) .. TREOp (Ord (OPEN) + NSUBEXP - 1) : begin //###0.929 + no := ord (scan^) - ord (OPEN); +// save := reginput; + save := startp [no]; //###0.936 + startp [no] := reginput; //###0.936 + Result := MatchPrim (next); + if not Result //###0.936 + then startp [no] := save; +// if Result and (startp [no] = nil) +// then startp [no] := save; + // Don't set startp if some later invocation of the same + // parentheses already has. + Exit; + end; + Succ (CLOSE) .. TREOp (Ord (CLOSE) + NSUBEXP - 1): begin //###0.929 + no := ord (scan^) - ord (CLOSE); +// save := reginput; + save := endp [no]; //###0.936 + endp [no] := reginput; //###0.936 + Result := MatchPrim (next); + if not Result //###0.936 + then endp [no] := save; +// if Result and (endp [no] = nil) +// then endp [no] := save; + // Don't set endp if some later invocation of the same + // parentheses already has. + Exit; + end; + BRANCH: begin + if (next^ <> BRANCH) // No choice. + then next := scan + REOpSz + RENextOffSz // Avoid recursion + else begin + repeat + save := reginput; + Result := MatchPrim (scan + REOpSz + RENextOffSz); + if Result + then Exit; + reginput := save; + scan := regnext (scan); + until (scan = nil) or (scan^ <> BRANCH); + Exit; + end; + end; + {$IFDEF ComplexBraces} + LOOPENTRY: begin //###0.925 + no := LoopStackIdx; + inc (LoopStackIdx); + if LoopStackIdx > LoopStackMax then begin + Error (reeLoopStackExceeded); + Exit; + end; + save := reginput; + LoopStack [LoopStackIdx] := 0; // init loop counter + Result := MatchPrim (next); // execute LOOP + LoopStackIdx := no; // cleanup + if Result + then Exit; + reginput := save; + Exit; + end; + LOOP, LOOPNG: begin //###0.940 + if LoopStackIdx <= 0 then begin + Error (reeLoopWithoutEntry); + Exit; + end; + opnd := scan + PRENextOff (scan + REOpSz + RENextOffSz + 2 * REBracesArgSz)^; + BracesMin := PREBracesArg (scan + REOpSz + RENextOffSz)^; + BracesMax := PREBracesArg (scan + REOpSz + RENextOffSz + REBracesArgSz)^; + save := reginput; + if LoopStack [LoopStackIdx] >= BracesMin then begin // Min alredy matched - we can work + if scan^ = LOOP then begin + // greedy way - first try to max deep of greed ;) + if LoopStack [LoopStackIdx] < BracesMax then begin + inc (LoopStack [LoopStackIdx]); + no := LoopStackIdx; + Result := MatchPrim (opnd); + LoopStackIdx := no; + if Result + then Exit; + reginput := save; + end; + dec (LoopStackIdx); // Fail. May be we are too greedy? ;) + Result := MatchPrim (next); + if not Result + then reginput := save; + Exit; + end + else begin + // non-greedy - try just now + Result := MatchPrim (next); + if Result + then Exit + else reginput := save; // failed - move next and try again + if LoopStack [LoopStackIdx] < BracesMax then begin + inc (LoopStack [LoopStackIdx]); + no := LoopStackIdx; + Result := MatchPrim (opnd); + LoopStackIdx := no; + if Result + then Exit; + reginput := save; + end; + dec (LoopStackIdx); // Failed - back up + Exit; + end + end + else begin // first match a min_cnt times + inc (LoopStack [LoopStackIdx]); + no := LoopStackIdx; + Result := MatchPrim (opnd); + LoopStackIdx := no; + if Result + then Exit; + dec (LoopStack [LoopStackIdx]); + reginput := save; + Exit; + end; + end; + {$ENDIF} + STAR, PLUS, BRACES, STARNG, PLUSNG, BRACESNG: begin + // Lookahead to avoid useless match attempts when we know + // what character comes next. + nextch := #0; + if next^ = EXACTLY + then nextch := (next + REOpSz + RENextOffSz)^; + BracesMax := MaxInt; // infinite loop for * and + //###0.92 + if (scan^ = STAR) or (scan^ = STARNG) + then BracesMin := 0 // STAR + else if (scan^ = PLUS) or (scan^ = PLUSNG) + then BracesMin := 1 // PLUS + else begin // BRACES + BracesMin := PREBracesArg (scan + REOpSz + RENextOffSz)^; + BracesMax := PREBracesArg (scan + REOpSz + RENextOffSz + REBracesArgSz)^; + end; + save := reginput; + opnd := scan + REOpSz + RENextOffSz; + if (scan^ = BRACES) or (scan^ = BRACESNG) + then inc (opnd, 2 * REBracesArgSz); + + if (scan^ = PLUSNG) or (scan^ = STARNG) or (scan^ = BRACESNG) then begin + // non-greedy mode + BracesMax := regrepeat (opnd, BracesMax); // don't repeat more than BracesMax + // Now we know real Max limit to move forward (for recursion 'back up') + // In some cases it can be faster to check only Min positions first, + // but after that we have to check every position separtely instead + // of fast scannig in loop. + no := BracesMin; + while no <= BracesMax do begin + reginput := save + no; + // If it could work, try it. + if (nextch = #0) or (reginput^ = nextch) then begin + {$IFDEF ComplexBraces} + System.Move (LoopStack, SavedLoopStack, SizeOf (LoopStack)); //###0.925 + SavedLoopStackIdx := LoopStackIdx; + {$ENDIF} + if MatchPrim (next) then begin + Result := True; + Exit; + end; + {$IFDEF ComplexBraces} + System.Move (SavedLoopStack, LoopStack, SizeOf (LoopStack)); + LoopStackIdx := SavedLoopStackIdx; + {$ENDIF} + end; + inc (no); // Couldn't or didn't - move forward. + end; { of while} + Exit; + end + else begin // greedy mode + no := regrepeat (opnd, BracesMax); // don't repeat more than max_cnt + while no >= BracesMin do begin + // If it could work, try it. + if (nextch = #0) or (reginput^ = nextch) then begin + {$IFDEF ComplexBraces} + System.Move (LoopStack, SavedLoopStack, SizeOf (LoopStack)); //###0.925 + SavedLoopStackIdx := LoopStackIdx; + {$ENDIF} + if MatchPrim (next) then begin + Result := True; + Exit; + end; + {$IFDEF ComplexBraces} + System.Move (SavedLoopStack, LoopStack, SizeOf (LoopStack)); + LoopStackIdx := SavedLoopStackIdx; + {$ENDIF} + end; + dec (no); // Couldn't or didn't - back up. + reginput := save + no; + end; { of while} + Exit; + end; + end; + EEND: begin + Result := True; // Success! + Exit; + end; + else begin + Error (reeMatchPrimMemoryCorruption); + Exit; + end; + end; { of case scan^} + scan := next; + end; { of while scan <> nil} + + // We get here only if there's trouble -- normally "case EEND" is the + // terminating point. + Error (reeMatchPrimCorruptedPointers); + end; { of function TRegExpr.MatchPrim +--------------------------------------------------------------} + +{$IFDEF UseFirstCharSet} //###0.929 +procedure TRegExpr.FillFirstCharSet (prog : PRegExprChar); + var + scan : PRegExprChar; // Current node. + next : PRegExprChar; // Next node. + opnd : PRegExprChar; + min_cnt : Integer; + begin + scan := prog; + while scan <> nil do begin + next := regnext (scan); + case PREOp (scan)^ of + BSUBEXP, BSUBEXPCI: begin //###0.938 + FirstCharSet := [#0 .. #255]; // :((( we cannot + // optimize r.e. if it starts with back reference + Exit; + end; + BOL, BOLML: ; // Exit; //###0.937 + EOL, EOLML: begin //###0.948 was empty in 0.947, was Exit in 0.937 + Include (FirstCharSet, #0); + if ModifierM + then begin + opnd := PRegExprChar (LineSeparators); + while opnd^ <> #0 do begin + Include (FirstCharSet, opnd^); + inc (opnd); + end; + end; + Exit; + end; + BOUND, NOTBOUND: ; //###0.943 ?!! + ANY, ANYML: begin // we can better define ANYML !!! + FirstCharSet := [#0 .. #255]; //###0.930 + Exit; + end; + ANYDIGIT: begin + FirstCharSet := FirstCharSet + ['0' .. '9']; + Exit; + end; + NOTDIGIT: begin + FirstCharSet := FirstCharSet + ([#0 .. #255] - ['0' .. '9']); //###0.948 FirstCharSet was forgotten + Exit; + end; + EXACTLYCI: begin + Include (FirstCharSet, (scan + REOpSz + RENextOffSz)^); + Include (FirstCharSet, InvertCase ((scan + REOpSz + RENextOffSz)^)); + Exit; + end; + EXACTLY: begin + Include (FirstCharSet, (scan + REOpSz + RENextOffSz)^); + Exit; + end; + ANYOFFULLSET: begin + FirstCharSet := FirstCharSet + PSetOfREChar (scan + REOpSz + RENextOffSz)^; + Exit; + end; + ANYOFTINYSET: begin + //!!!TinySet + Include (FirstCharSet, (scan + REOpSz + RENextOffSz)^); + Include (FirstCharSet, (scan + REOpSz + RENextOffSz + 1)^); + Include (FirstCharSet, (scan + REOpSz + RENextOffSz + 2)^); + // ... // up to TinySetLen + Exit; + end; + ANYBUTTINYSET: begin + //!!!TinySet + FirstCharSet := FirstCharSet + ([#0 .. #255] - [ //###0.948 FirstCharSet was forgotten + (scan + REOpSz + RENextOffSz)^, + (scan + REOpSz + RENextOffSz + 1)^, + (scan + REOpSz + RENextOffSz + 2)^]); + // ... // up to TinySetLen + Exit; + end; + NOTHING: ; + COMMENT: ; + BACK: ; + Succ (OPEN) .. TREOp (Ord (OPEN) + NSUBEXP - 1) : begin //###0.929 + FillFirstCharSet (next); + Exit; + end; + Succ (CLOSE) .. TREOp (Ord (CLOSE) + NSUBEXP - 1): begin //###0.929 + FillFirstCharSet (next); + Exit; + end; + BRANCH: begin + if (PREOp (next)^ <> BRANCH) // No choice. + then next := scan + REOpSz + RENextOffSz // Avoid recursion. + else begin + repeat + FillFirstCharSet (scan + REOpSz + RENextOffSz); + scan := regnext (scan); + until (scan = nil) or (PREOp (scan)^ <> BRANCH); + Exit; + end; + end; + {$IFDEF ComplexBraces} + LOOPENTRY: begin //###0.925 +// LoopStack [LoopStackIdx] := 0; //###0.940 line removed + FillFirstCharSet (next); // execute LOOP + Exit; + end; + LOOP, LOOPNG: begin //###0.940 + opnd := scan + PRENextOff (scan + REOpSz + RENextOffSz + REBracesArgSz * 2)^; + min_cnt := PREBracesArg (scan + REOpSz + RENextOffSz)^; + FillFirstCharSet (opnd); + if min_cnt = 0 + then FillFirstCharSet (next); + Exit; + end; + {$ENDIF} + STAR, STARNG: //###0.940 + FillFirstCharSet (scan + REOpSz + RENextOffSz); + PLUS, PLUSNG: begin //###0.940 + FillFirstCharSet (scan + REOpSz + RENextOffSz); + Exit; + end; + BRACES, BRACESNG: begin //###0.940 + opnd := scan + REOpSz + RENextOffSz + REBracesArgSz * 2; + min_cnt := PREBracesArg (scan + REOpSz + RENextOffSz)^; // BRACES + FillFirstCharSet (opnd); + if min_cnt > 0 + then Exit; + end; + EEND: begin + FirstCharSet := [#0 .. #255]; //###0.948 + Exit; + end; + else begin + Error (reeMatchPrimMemoryCorruption); + Exit; + end; + end; { of case scan^} + scan := next; + end; { of while scan <> nil} + end; { of procedure FillFirstCharSet +--------------------------------------------------------------} +{$ENDIF} + +function TRegExpr.Exec (const AInputString : RegExprString) : Boolean; + begin + InputString := AInputString; + Result := ExecPrim (1); + end; { of function TRegExpr.Exec +--------------------------------------------------------------} + +{$IFDEF OverMeth} +{$IFNDEF FPC} +function TRegExpr.Exec : Boolean; + begin + Result := ExecPrim (1); + end; { of function TRegExpr.Exec +--------------------------------------------------------------} +{$ENDIF} +function TRegExpr.Exec (AOffset: Integer) : Boolean; + begin + Result := ExecPrim (AOffset); + end; { of function TRegExpr.Exec +--------------------------------------------------------------} +{$ENDIF} + +function TRegExpr.ExecPos (AOffset: Integer {$IFDEF DefParam}= 1{$ENDIF}) : Boolean; + begin + Result := ExecPrim (AOffset); + end; { of function TRegExpr.ExecPos +--------------------------------------------------------------} + +function TRegExpr.ExecPrim (AOffset: Integer) : Boolean; + procedure ClearMatchs; + // Clears matchs array + var i : Integer; + begin + for i := 0 to NSUBEXP - 1 do begin + startp [i] := nil; + endp [i] := nil; + end; + end; { of procedure ClearMatchs; +..............................................................} + function RegMatch (str : PRegExprChar) : Boolean; + // try match at specific point + begin + //###0.949 removed clearing of start\endp + reginput := str; + Result := MatchPrim (programm + REOpSz); + if Result then begin + startp [0] := str; + endp [0] := reginput; + end; + end; { of function RegMatch +..............................................................} + var + s : PRegExprChar; + StartPtr: PRegExprChar; + InputLen : Integer; + begin + Result := False; // Be paranoid... + + ClearMatchs; //###0.949 + // ensure that Match cleared either if optimization tricks or some error + // will lead to leaving ExecPrim without actual search. That is + // importent for ExecNext logic and so on. + + if not IsProgrammOk //###0.929 + then Exit; + + // Check InputString presence + if not Assigned (fInputString) then begin + Error (reeNoInpitStringSpecified); + Exit; + end; + + InputLen := length (fInputString); + + //Check that the start position is not negative + if AOffset < 1 then begin + Error (reeOffsetMustBeGreaterThen0); + Exit; + end; + // Check that the start position is not longer than the line + // If so then Exit with nothing found + if AOffset > (InputLen + 1) // for matching empty string after last char. + then Exit; + + StartPtr := fInputString + AOffset - 1; + + // If there is a "must appear" string, look for it. + if regmust <> nil then begin + s := StartPtr; + repeat + s := StrScan (s, regmust [0]); + if s <> nil then begin + if StrLComp (s, regmust, regmlen) = 0 + then BREAK; // Found it. + inc (s); + end; + until s = nil; + if s = nil // Not present. + then Exit; + end; + + // Mark beginning of line for ^ . + fInputStart := fInputString; + + // Pointer to end of input stream - for + // pascal-style string processing (may include #0) + fInputEnd := fInputString + InputLen; + + {$IFDEF ComplexBraces} + // no loops started + LoopStackIdx := 0; //###0.925 + {$ENDIF} + + // Simplest case: anchored match need be tried only once. + if reganch <> #0 then begin + Result := RegMatch (StartPtr); + Exit; + end; + + // Messy cases: unanchored match. + s := StartPtr; + if regstart <> #0 then // We know what char it must start with. + repeat + s := StrScan (s, regstart); + if s <> nil then begin + Result := RegMatch (s); + if Result + then Exit + else ClearMatchs; //###0.949 + inc (s); + end; + until s = nil + else begin // We don't - general case. + repeat //###0.948 + {$IFDEF UseFirstCharSet} + if s^ in FirstCharSet + then Result := RegMatch (s); + {$ELSE} + Result := RegMatch (s); + {$ENDIF} + if Result or (s^ = #0) // Exit on a match or after testing the end-of-string. + then Exit + else ClearMatchs; //###0.949 + inc (s); + until False; +(* optimized and fixed by Martin Fuller - empty strings + were not allowed to pass thru in UseFirstCharSet mode + {$IFDEF UseFirstCharSet} //###0.929 + while s^ <> #0 do begin + if s^ in FirstCharSet + then Result := RegMatch (s); + if Result + then Exit; + inc (s); + end; + {$ELSE} + repeat + Result := RegMatch (s); + if Result + then Exit; + inc (s); + until s^ = #0; + {$ENDIF} +*) + end; + // Failure +end; { of function TRegExpr.ExecPrim +--------------------------------------------------------------} + +function TRegExpr.ExecNext : Boolean; +var + offset : Integer; +begin + Result := False; + if not Assigned (startp[0]) or not Assigned (endp[0]) then + begin + Error (reeExecNextWithoutExec); + Exit; + end; +// Offset := MatchPos [0] + MatchLen [0]; +// if MatchLen [0] = 0 + Offset := endp [0] - fInputString + 1; //###0.929 + if endp [0] = startp [0] then //###0.929 + inc (Offset); // prevent infinite looping if empty string match r.e. + Result := ExecPrim (Offset); +end; { of function TRegExpr.ExecNext +--------------------------------------------------------------} + +function TRegExpr.GetInputString : RegExprString; +begin + if not Assigned (fInputString) then + begin + Error (reeGetInputStringWithoutInputString); + Exit; + end; + Result := fInputString; +end; { of function TRegExpr.GetInputString +--------------------------------------------------------------} + +procedure TRegExpr.SetInputString (const AInputString : RegExprString); +var + Len : Integer; + i : Integer; +begin + // clear Match* - before next Exec* call it's undefined + for i := 0 to NSUBEXP - 1 do + begin + startp [i] := nil; + endp [i] := nil; + end; + + // need reallocation of input string buffer ? + Len := length (AInputString); + if Assigned (fInputString) and (Length (fInputString) <> Len) then + begin + FreeMem (fInputString); + fInputString := nil; + end; + // buffer [re]allocation + if not Assigned (fInputString) then + GetMem (fInputString, (Len + 1) * SizeOf (REChar)); + + // copy input string into buffer + {$IFDEF SynRegUniCode} +// StrPCopy (fInputString, Copy (AInputString, 1, Len)); //###0.927 + StrPCopy (fInputString, AInputString); //KV Copy above is wastefull. Do not really understand why is there. + {$ELSE} + StrLCopy (fInputString, PRegExprChar (AInputString), Len); + {$ENDIF} + + { + fInputString : string; + fInputStart, fInputEnd : PRegExprChar; + + SetInputString: + fInputString := AInputString; + UniqueString (fInputString); + fInputStart := PChar (fInputString); + Len := length (fInputString); + fInputEnd := PRegExprChar (Integer (fInputStart) + Len); ?? + !! startp/endp ? + } +end; { of procedure TRegExpr.SetInputString +--------------------------------------------------------------} + +procedure TRegExpr.SetLineSeparators (const AStr : RegExprString); +begin + if AStr <> FLineSeparators then + begin + FLineSeparators := AStr; + InvalidateProgramm; + end; +end; { of procedure TRegExpr.SetLineSeparators +--------------------------------------------------------------} + +procedure TRegExpr.SetLinePairedSeparator (const AStr : RegExprString); +begin + if length (AStr) = 2 then + begin + if AStr [1] = AStr [2] then + begin + // it's impossible for our 'one-point' checking to support + // two chars separator for identical chars + Error (reeBadLinePairedSeparator); + Exit; + end; + if not fLinePairedSeparatorAssigned + or (AStr [1] <> fLinePairedSeparatorHead) + or (AStr [2] <> fLinePairedSeparatorTail) then + begin + fLinePairedSeparatorAssigned := True; + fLinePairedSeparatorHead := AStr [1]; + fLinePairedSeparatorTail := AStr [2]; + InvalidateProgramm; + end; + end + else if length (AStr) = 0 then + begin + if fLinePairedSeparatorAssigned then + begin + fLinePairedSeparatorAssigned := False; + InvalidateProgramm; + end; + end + else + Error (reeBadLinePairedSeparator); +end; { of procedure TRegExpr.SetLinePairedSeparator +--------------------------------------------------------------} + +function TRegExpr.GetLinePairedSeparator : RegExprString; + begin + if fLinePairedSeparatorAssigned then begin + {$IFDEF SynRegUniCode} + // Here is some UniCode 'magic' + // If You do know better decision to concatenate + // two WideChars, please, let me know! + Result := fLinePairedSeparatorHead; //###0.947 + Result := Result + fLinePairedSeparatorTail; + {$ELSE} + Result := fLinePairedSeparatorHead + fLinePairedSeparatorTail; + {$ENDIF} + end + else Result := ''; + end; { of function TRegExpr.GetLinePairedSeparator +--------------------------------------------------------------} + +function TRegExpr.Substitute (const ATemplate : RegExprString) : RegExprString; +// perform substitutions after a regexp match +// completely rewritten in 0.929 + var + TemplateLen : Integer; + TemplateBeg, TemplateEnd : PRegExprChar; + p, p0, ResultPtr : PRegExprChar; + ResultLen : Integer; + n : Integer; + Ch : REChar; + + function ParseVarName (var APtr : PRegExprChar) : Integer; + // extract name of variable (digits, may be enclosed with + // curly braces) from APtr^, uses TemplateEnd !!! + const + Digits = ['0' .. '9']; + var + p : PRegExprChar; + Delimited : Boolean; + begin + Result := 0; + p := APtr; + Delimited := (p < TemplateEnd) and (p^ = '{'); + if Delimited then + inc (p); // skip left curly brace + if (p < TemplateEnd) and (p^ = '&') then + inc (p) // this is '$&' or '${&}' + else + while (p < TemplateEnd) and + {$IFDEF SynRegUniCode} //###0.935 + (ord (p^) < 256) and (ansichar (p^) in Digits) + {$ELSE} + (p^ in Digits) + {$ENDIF} do + begin + Result := Result * 10 + (ord (p^) - ord ('0')); //###0.939 + inc (p); + end; + if Delimited then + if (p < TemplateEnd) and (p^ = '}') then + inc (p) // skip right curly brace + else + p := APtr; // isn't properly terminated + if p = APtr then + Result := -1; // no valid digits found or no right curly brace + APtr := p; + end; + +begin + // Check programm and input string + if not IsProgrammOk then + Exit; + if not Assigned (fInputString) then + begin + Error (reeNoInpitStringSpecified); + Exit; + end; + // Prepare for working + TemplateLen := length (ATemplate); + if TemplateLen = 0 then // prevent nil pointers + begin + Result := ''; + Exit; + end; + TemplateBeg := Pointer (ATemplate); + TemplateEnd := TemplateBeg + TemplateLen; + // Count result length for speed optimization. + ResultLen := 0; + p := TemplateBeg; + while p < TemplateEnd do begin + Ch := p^; + inc (p); + if Ch = '$' + then n := ParseVarName (p) + else n := -1; + if n >= 0 then begin + if (n < NSUBEXP) and Assigned (startp [n]) and Assigned (endp [n]) + then inc (ResultLen, endp [n] - startp [n]); + end + else begin + if (Ch = EscChar) and (p < TemplateEnd) + then inc (p); // quoted or special char followed + inc (ResultLen); + end; + end; + // Get memory. We do it once and it significant speed up work ! + if ResultLen = 0 then begin + Result := ''; + Exit; + end; + SetString (Result, nil, ResultLen); + // Fill Result + ResultPtr := Pointer (Result); + p := TemplateBeg; + while p < TemplateEnd do + begin + Ch := p^; + inc (p); + if Ch = '$' then + n := ParseVarName (p) + else + n := -1; + if n >= 0 then + begin + p0 := startp [n]; + if (n < NSUBEXP) and Assigned (p0) and Assigned (endp [n]) then + while p0 < endp [n] do + begin + ResultPtr^ := p0^; + inc (ResultPtr); + inc (p0); + end; + end + else + begin + if (Ch = EscChar) and (p < TemplateEnd) then // quoted or special char followed + begin + Ch := p^; + inc (p); + end; + ResultPtr^ := Ch; + inc (ResultPtr); + end; + end; +end; { of function TRegExpr.Substitute +--------------------------------------------------------------} + +procedure TRegExpr.Split (AInputStr : RegExprString; APieces : TStrings); +var + PrevPos: Integer; +begin + PrevPos := 1; + if Exec (AInputStr) then + repeat + APieces.Add (System.Copy (AInputStr, PrevPos, MatchPos [0] - PrevPos)); + PrevPos := MatchPos [0] + MatchLen [0]; + until not ExecNext; + APieces.Add (System.Copy (AInputStr, PrevPos, MaxInt)); // Tail +end; { of procedure TRegExpr.Split +--------------------------------------------------------------} + +function TRegExpr.Replace (AInputStr : RegExprString; const AReplaceStr : RegExprString; + AUseSubstitution : Boolean{$IFDEF DefParam}= False{$ENDIF}) : RegExprString; +var + PrevPos : Integer; +begin + Result := ''; + PrevPos := 1; + if Exec (AInputStr) then + repeat + Result := Result + System.Copy (AInputStr, PrevPos, MatchPos [0] - PrevPos); + if AUseSubstitution then //###0.946 + Result := Result + Substitute (AReplaceStr) + else + Result := Result + AReplaceStr; + PrevPos := MatchPos [0] + MatchLen [0]; + until not ExecNext; + Result := Result + System.Copy (AInputStr, PrevPos, MaxInt); // Tail +end; { of function TRegExpr.Replace +--------------------------------------------------------------} + +function TRegExpr.ReplaceEx (AInputStr : RegExprString; + AReplaceFunc : TRegExprReplaceFunction) + : RegExprString; +var + PrevPos : Integer; +begin + Result := ''; + PrevPos := 1; + if Exec (AInputStr) then + repeat + Result := Result + System.Copy (AInputStr, PrevPos, MatchPos [0] - PrevPos) + + AReplaceFunc (Self); + PrevPos := MatchPos [0] + MatchLen [0]; + until not ExecNext; + Result := Result + System.Copy (AInputStr, PrevPos, MaxInt); // Tail +end; { of function TRegExpr.ReplaceEx +--------------------------------------------------------------} + + +{$IFDEF OverMeth} +function TRegExpr.Replace (AInputStr: RegExprString; + AReplaceFunc: TRegExprReplaceFunction): RegExprString; +begin + ReplaceEx (AInputStr, AReplaceFunc); +end; { of function TRegExpr.Replace +--------------------------------------------------------------} +{$ENDIF} + +{=============================================================} +{====================== Debug section ========================} +{=============================================================} + +{$IFDEF RegExpPCodeDump} +function TRegExpr.DumpOp (op : TREOp) : RegExprString; +// printable representation of opcode +begin + case op of + BOL: Result := 'BOL'; + EOL: Result := 'EOL'; + BOLML: Result := 'BOLML'; + EOLML: Result := 'EOLML'; + BOUND: Result := 'BOUND'; //###0.943 + NOTBOUND: Result := 'NOTBOUND'; //###0.943 + ANY: Result := 'ANY'; + ANYML: Result := 'ANYML'; //###0.941 + ANYLETTER: Result := 'ANYLETTER'; + NOTLETTER: Result := 'NOTLETTER'; + ANYDIGIT: Result := 'ANYDIGIT'; + NOTDIGIT: Result := 'NOTDIGIT'; + ANYSPACE: Result := 'ANYSPACE'; + NOTSPACE: Result := 'NOTSPACE'; + ANYOF: Result := 'ANYOF'; + ANYBUT: Result := 'ANYBUT'; + ANYOFCI: Result := 'ANYOF/CI'; + ANYBUTCI: Result := 'ANYBUT/CI'; + BRANCH: Result := 'BRANCH'; + EXACTLY: Result := 'EXACTLY'; + EXACTLYCI: Result := 'EXACTLY/CI'; + NOTHING: Result := 'NOTHING'; + COMMENT: Result := 'COMMENT'; + BACK: Result := 'BACK'; + EEND: Result := 'END'; + BSUBEXP: Result := 'BSUBEXP'; + BSUBEXPCI: Result := 'BSUBEXP/CI'; + Succ (OPEN) .. TREOp (Ord (OPEN) + NSUBEXP - 1): //###0.929 + Result := Format ('OPEN[%d]', [ord (op) - ord (OPEN)]); + Succ (CLOSE) .. TREOp (Ord (CLOSE) + NSUBEXP - 1): //###0.929 + Result := Format ('CLOSE[%d]', [ord (op) - ord (CLOSE)]); + STAR: Result := 'STAR'; + PLUS: Result := 'PLUS'; + BRACES: Result := 'BRACES'; + {$IFDEF ComplexBraces} + LOOPENTRY: Result := 'LOOPENTRY'; //###0.925 + LOOP: Result := 'LOOP'; //###0.925 + LOOPNG: Result := 'LOOPNG'; //###0.940 + {$ENDIF} + ANYOFTINYSET: Result:= 'ANYOFTINYSET'; + ANYBUTTINYSET:Result:= 'ANYBUTTINYSET'; + {$IFDEF UseSetOfChar} //###0.929 + ANYOFFULLSET: Result:= 'ANYOFFULLSET'; + {$ENDIF} + STARNG: Result := 'STARNG'; //###0.940 + PLUSNG: Result := 'PLUSNG'; //###0.940 + BRACESNG: Result := 'BRACESNG'; //###0.940 + else Error (reeDumpCorruptedOpcode); + end; {of case op} + Result := ':' + Result; +end; { of function TRegExpr.DumpOp +--------------------------------------------------------------} + +function TRegExpr.Dump : RegExprString; +// dump a regexp in vaguely comprehensible form +var + s : PRegExprChar; + op : TREOp; // Arbitrary non-END op. + next : PRegExprChar; + i : Integer; + Diff : Integer; +{$IFDEF UseSetOfChar} //###0.929 + Ch : REChar; +{$ENDIF} +begin + if not IsProgrammOk then //###0.929 + Exit; + + op := EXACTLY; + Result := ''; + s := programm + REOpSz; + while op <> EEND do // While that wasn't END last time... + begin + op := s^; + Result := Result + Format ('%2d%s', [s - programm, DumpOp (s^)]); // Where, what. + next := regnext (s); + if next = nil then // Next ptr. + Result := Result + ' (0)' + else + begin + if next > s then //###0.948 PWideChar subtraction workaround (see comments in Tail method for details) + Diff := next - s + else + Diff := - (s - next); + Result := Result + Format (' (%d) ', [(s - programm) + Diff]); + end; + inc (s, REOpSz + RENextOffSz); + if (op = ANYOF) or (op = ANYOFCI) or (op = ANYBUT) or (op = ANYBUTCI) + or (op = EXACTLY) or (op = EXACTLYCI) then + begin + // Literal string, where present. + while s^ <> #0 do + begin + Result := Result + s^; + inc (s); + end; + inc (s); + end; + if (op = ANYOFTINYSET) or (op = ANYBUTTINYSET) then + begin + for i := 1 to TinySetLen do + begin + Result := Result + s^; + inc (s); + end; + end; + if (op = BSUBEXP) or (op = BSUBEXPCI) then + begin + Result := Result + ' \' + IntToStr (Ord (s^)); + inc (s); + end; + {$IFDEF UseSetOfChar} //###0.929 + if op = ANYOFFULLSET then + begin + for Ch := #0 to #255 do + if Ch in PSetOfREChar (s)^ then + if Ch < ' ' then + Result := Result + '#' + IntToStr (Ord (Ch)) //###0.936 + else + Result := Result + Ch; + inc (s, SizeOf (TSetOfREChar)); + end; + {$ENDIF} + if (op = BRACES) or (op = BRACESNG) then + begin //###0.941 + // show min/max argument of BRACES operator + Result := Result + Format ('{%d,%d}', [PREBracesArg (s)^, PREBracesArg (s + REBracesArgSz)^]); + inc (s, REBracesArgSz * 2); + end; + {$IFDEF ComplexBraces} + if (op = LOOP) or (op = LOOPNG) then + begin //###0.940 + Result := Result + Format (' -> (%d) {%d,%d}', [(s - programm - + (REOpSz + RENextOffSz)) + PRENextOff (s + 2 * REBracesArgSz)^, + PREBracesArg (s)^, PREBracesArg (s + REBracesArgSz)^]); + inc (s, 2 * REBracesArgSz + RENextOffSz); + end; + {$ENDIF} + Result := Result + #$d#$a; + end; { of while} + + // Header fields of interest. + + if regstart <> #0 then + Result := Result + 'start ' + regstart; + if reganch <> #0 then + Result := Result + 'anchored '; + if regmust <> nil then + Result := Result + 'must have ' + regmust; + {$IFDEF UseFirstCharSet} //###0.929 + Result := Result + #$d#$a'FirstCharSet:'; + for Ch := #0 to #255 do + if Ch in FirstCharSet then + begin + if Ch < ' ' then + Result := Result + '#' + IntToStr(Ord(Ch)) //###0.948 + else + Result := Result + Ch; + end; + {$ENDIF} + Result := Result + #$d#$a; +end; { of function TRegExpr.Dump +--------------------------------------------------------------} +{$ENDIF} + +{$IFDEF reRealExceptionAddr} +{$OPTIMIZATION ON} +// ReturnAddr works correctly only if compiler optimization is ON +// I placed this method at very end of unit because there are no +// way to restore compiler optimization flag ... +{$ENDIF} +procedure TRegExpr.Error (AErrorID : Integer); + +{$IFDEF reRealExceptionAddr} + function ReturnAddr : Pointer; //###0.938 + asm + mov eax,[ebp+4] + end; +{$ENDIF} + +var + e : ERegExpr; +begin + FLastError := AErrorID; // dummy stub - useless because will raise exception + if AErrorID < 1000 then // compilation error ? + e := ERegExpr.Create (ErrorMsg (AErrorID) // yes - show error pos + + ' (pos ' + IntToStr (CompilerErrorPos) + ')') + else + e := ERegExpr.Create (ErrorMsg (AErrorID)); + e.ErrorCode := AErrorID; + e.CompilerErrorPos := CompilerErrorPos; + raise + e +{$IFDEF reRealExceptionAddr} + At ReturnAddr; //###0.938 +{$ENDIF} +end; { of procedure TRegExpr.Error +--------------------------------------------------------------} + +(* + PCode persistence: + FirstCharSet + programm, regsize + regstart // -> programm + reganch // -> programm + regmust, regmlen // -> programm + fExprIsCompiled +*) + +// be carefull - placed here code will be always compiled with +// compiler optimization flag + +{$IFDEF FPC} +initialization + RegExprInvertCaseFunction := TRegExpr.InvertCaseFunction; + +{$ENDIF} +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynTextDrawer.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynTextDrawer.pas new file mode 100644 index 000000000..096809c3f --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynTextDrawer.pas @@ -0,0 +1,1043 @@ +{============================================================================== + Content: TSynTextDrawer, a helper class for drawing of + fixed-pitched font characters + ============================================================================== + The contents of this file are subject to the Mozilla Public License Ver. 1.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" basis, + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + the specific language governing rights and limitations under the License. + ============================================================================== + The Original Code is HANAI Tohru's private delphi library. + ============================================================================== + The Initial Developer of the Original Code is HANAI Tohru (Japan) + Portions created by HANAI Tohru are Copyright (C) 1999. + All Rights Reserved. + ============================================================================== + Contributor(s): HANAI Tohru + Unicode translation by Mal Hrz. + ============================================================================== + History: 01/19/1999 HANAI Tohru + Initial Version + 02/13/1999 HANAI Tohru + Changed default intercharacter spacing + 09/09/1999 HANAI Tohru + Redesigned all. Simplified interfaces. + When drawing text now it uses TextOut + SetTextCharacter- + Extra insted ExtTextOut since ExtTextOut has a little + heavy behavior. + 09/10/1999 HANAI Tohru + Added code to call ExtTextOut because there is a problem + when TextOut called with italicized raster type font. + After this changing, ExtTextOut is called without the + last parameter `lpDx' and be with SetTextCharacterExtra. + This pair performs faster than with `lpDx'. + 09/14/1999 HANAI Tohru + Changed code for saving/restoring DC + 09/15/1999 HANAI Tohru + Added X/Y parameters to ExtTextOut. + 09/16/1999 HANAI Tohru + Redesigned for multi-bytes character drawing. + 09/19/1999 HANAI Tohru + Since TSynTextDrawer grew fat it was split into three + classes - TSynFontStock, TSynTextDrawer and TheTextDrawerEx. + Currently it should avoid TSynTextDrawer because it is + slower than TSynTextDrawer. + 09/25/1999 HANAI Tohru + Added internally definition of LeadBytes for Delphi 2 + 10/01/1999 HANAI Tohru + To save font resources, now all fonts data are shared + among all of TSynFontStock instances. With this changing, + there added a new class `TSynFontsInfoManager' to manage + those shared data. + 10/09/1999 HANAI Tohru + Added BaseStyle property to TheFontFont class. + ==============================================================================} + +// $Id: uRESTDWPrivSynTextDrawer.pas,v 1.6.2.17 2008/09/17 13:59:12 maelh Exp $ + +// uRESTDWPrivSynEdit note: The name had to be changed to get uRESTDWPrivSynEdit to install +// together with mwEdit into the same Delphi installation + +unit uRESTDWPrivSynTextDrawer; + +{$I uRESTDWPrivSynEdit.inc} + +interface + +uses + {$IFDEF SYN_COMPILER_17_UP} + Types, UITypes, + {$ENDIF} + uRESTDWPrivSynUnicode, + uRESTDWPrivSynEditTypes, + SysUtils, + Classes, + Windows, + Graphics; + +const + FontStyleCount = Ord(High(TFontStyle)) + 1; + FontStyleCombineCount = (1 shl FontStyleCount); + +type + PIntegerArray = ^TIntegerArray; + TIntegerArray = array[0..MaxInt div SizeOf(Integer) - 1] of Integer; + + TSynStockFontPatterns = 0..FontStyleCombineCount - 1; + + PSynFontData = ^TSynFontData; + TSynFontData = record + Style: TFontStyles; + Handle: HFont; + CharAdv: Integer; + CharHeight: Integer; + end; + + PSynFontsData = ^TSynFontsData; + TSynFontsData = array[TSynStockFontPatterns] of TSynFontData; + + PSynSharedFontsInfo = ^TSynSharedFontsInfo; + TSynSharedFontsInfo = record + // reference counters + RefCount: Integer; + LockCount: Integer; + // font information + BaseFont: TFont; + BaseLF: TLogFont; + IsTrueType: Boolean; + FontsData: TSynFontsData; + end; + + { TSynStockFontManager } + + TSynFontsInfoManager = class + private + FFontsInfo: TList; + function FindFontsInfo(const LF: TLogFont): PSynSharedFontsInfo; + function CreateFontsInfo(ABaseFont: TFont; + const LF: TLogFont): PSynSharedFontsInfo; + procedure DestroyFontHandles(pFontsInfo: PSynSharedFontsInfo); + procedure RetrieveLogFontForComparison(ABaseFont: TFont; var LF: TLogFont); + public + constructor Create; + destructor Destroy; override; + + procedure LockFontsInfo(pFontsInfo: PSynSharedFontsInfo); + procedure UnLockFontsInfo(pFontsInfo: PSynSharedFontsInfo); + function GetFontsInfo(ABaseFont: TFont): PSynSharedFontsInfo; + procedure ReleaseFontsInfo(pFontsInfo: PSynSharedFontsInfo); + end; + + { TSynFontStock } + + TTextOutOptions = set of (tooOpaque, tooClipped); + + TSynExtTextOutProc = procedure (X, Y: Integer; fuOptions: TTextOutOptions; + const ARect: TRect; const Text: UnicodeString; Length: Integer) of object; + + ESynFontStockException = class(ESynError); + + TSynFontStock = class + private + // Private DC + FDC: HDC; + FDCRefCount: Integer; + + // Shared fonts + FpInfo: PSynSharedFontsInfo; + FUsingFontHandles: Boolean; + + // Current font + FCrntFont: HFONT; + FCrntStyle: TFontStyles; + FpCrntFontData: PSynFontData; + + // Local font info + FBaseLF: TLogFont; + function GetBaseFont: TFont; + function GetIsTrueType: Boolean; + protected + function InternalGetDC: HDC; virtual; + procedure InternalReleaseDC(Value: HDC); virtual; + function InternalCreateFont(Style: TFontStyles): HFONT; virtual; + function CalcFontAdvance(DC: HDC; pCharHeight: PInteger): Integer; virtual; + function GetCharAdvance: Integer; virtual; + function GetCharHeight: Integer; virtual; + function GetFontData(idx: Integer): PSynFontData; virtual; + procedure UseFontHandles; + procedure ReleaseFontsInfo; + procedure SetBaseFont(Value: TFont); virtual; + procedure SetStyle(Value: TFontStyles); virtual; + + property FontData[idx: Integer]: PSynFontData read GetFontData; + property FontsInfo: PSynSharedFontsInfo read FpInfo; + public + constructor Create(InitialFont: TFont); virtual; + destructor Destroy; override; + + procedure ReleaseFontHandles; virtual; + + property BaseFont: TFont read GetBaseFont; + property Style: TFontStyles read FCrntStyle write SetStyle; + property FontHandle: HFONT read FCrntFont; + property CharAdvance: Integer read GetCharAdvance; + property CharHeight: Integer read GetCharHeight; + property IsTrueType: Boolean read GetIsTrueType; + end; + + { TSynTextDrawer } + ESynTextDrawerException = class(ESynError); + + TSynTextDrawer = class(TObject) + private + FDC: HDC; + FSaveDC: Integer; + + // Font information + FFontStock: TSynFontStock; + FStockBitmap: TBitmap; + FCalcExtentBaseStyle: TFontStyles; + FBaseCharWidth: Integer; + FBaseCharHeight: Integer; + + // Current font and properties + FCrntFont: HFONT; + FETODist: PIntegerArray; + + // Current font attributes + FColor: TColor; + FBkColor: TColor; + FCharExtra: Integer; + + // Begin/EndDrawing calling count + FDrawingCount: Integer; + + // GetCharABCWidthsW cache + FCharABCWidthCache: array [0..127] of TABC; + FCharWidthCache: array [0..127] of Integer; + protected + procedure ReleaseETODist; virtual; + procedure AfterStyleSet; virtual; + procedure DoSetCharExtra(Value: Integer); virtual; + procedure FlushCharABCWidthCache; + function GetCachedABCWidth(c : Cardinal; var abc : TABC) : Boolean; + + property StockDC: HDC read FDC; + property DrawingCount: Integer read FDrawingCount; + property FontStock: TSynFontStock read FFontStock; + property BaseCharWidth: Integer read FBaseCharWidth; + property BaseCharHeight: Integer read FBaseCharHeight; + public + constructor Create(CalcExtentBaseStyle: TFontStyles; BaseFont: TFont); virtual; + destructor Destroy; override; + + function GetCharWidth: Integer; virtual; + function GetCharHeight: Integer; virtual; + + procedure BeginDrawing(DC: HDC); virtual; + procedure EndDrawing; virtual; + + procedure TextOut(X, Y: Integer; Text: PWideChar; Length: Integer); virtual; + procedure ExtTextOut(X, Y: Integer; Options: TTextOutOptions; ARect: TRect; + Text: PWideChar; Length: Integer); virtual; + function TextExtent(const Text: UnicodeString): TSize; overload; + function TextExtent(Text: PWideChar; Count: Integer): TSize; overload; + function TextWidth(const Char: WideChar): Integer; overload; + function TextWidth(const Text: UnicodeString): Integer; overload; + function TextWidth(Text: PWideChar; Count: Integer): Integer; overload; + procedure SetBaseFont(Value: TFont); virtual; + procedure SetBaseStyle(const Value: TFontStyles); virtual; + procedure SetStyle(Value: TFontStyles); virtual; + procedure SetForeColor(Value: TColor); virtual; + procedure SetBackColor(Value: TColor); virtual; + procedure SetCharExtra(Value: Integer); virtual; + procedure ReleaseTemporaryResources; virtual; + + property CharWidth: Integer read GetCharWidth; + property CharHeight: Integer read GetCharHeight; + property BaseFont: TFont write SetBaseFont; + property BaseStyle: TFontStyles write SetBaseStyle; + property ForeColor: TColor write SetForeColor; + property BackColor: TColor write SetBackColor; + property Style: TFontStyles write SetStyle; + property CharExtra: Integer read FCharExtra write SetCharExtra; + end; + +function GetFontsInfoManager: TSynFontsInfoManager; + +function UniversalExtTextOut(DC: HDC; X, Y: Integer; Options: TTextOutOptions; + Rect: TRect; Str: PWideChar; Count: Integer; ETODist: PIntegerArray): Boolean; + +implementation + +uses + Math +{$IFDEF SYN_UNISCRIBE} + , uRESTDWPrivSynUsp10 +{$ENDIF} + ; + +var + GFontsInfoManager: TSynFontsInfoManager; + +{ utility routines } + +function GetFontsInfoManager: TSynFontsInfoManager; +begin + if not Assigned(GFontsInfoManager) then + GFontsInfoManager := TSynFontsInfoManager.Create; + Result := GFontsInfoManager; +end; + +// UniversalExtTextOut uses UniScribe where available for the best possible +// output quality. This also avoids a bug in (Ext)TextOut that surfaces when +// displaying a combination of Chinese and Korean text. +// +// See here for details: http://groups.google.com/group/microsoft.public.win32.programmer.international/browse_thread/thread/77cd596f2b96dc76/146300208098285c?lnk=st&q=font+substitution+problem#146300208098285c +function UniversalExtTextOut(DC: HDC; X, Y: Integer; Options: TTextOutOptions; + Rect: TRect; Str: PWideChar; Count: Integer; ETODist: PIntegerArray): Boolean; +{$IFDEF SYN_UNISCRIBE} +const + SSAnalyseFlags = SSA_GLYPHS or SSA_FALLBACK or SSA_LINK; + SpaceString: UnicodeString = ' '; +{$ENDIF} +var + TextOutFlags: DWORD; +{$IFDEF SYN_UNISCRIBE} + GlyphBufferSize: Integer; + saa: TScriptStringAnalysis; +{$ENDIF} +begin + TextOutFlags := 0; + if tooOpaque in Options then + TextOutFlags := TextOutFlags or ETO_OPAQUE; + if tooClipped in Options then + TextOutFlags := TextOutFlags or ETO_CLIPPED; + +{$IFDEF SYN_UNISCRIBE} + if Usp10IsInstalled then + begin + // UniScribe requires that the string contains at least one character. + // If UniversalExtTextOut should be used to fill the background we can just + // pass a string made of a space. + if Count <= 0 then + if tooOpaque in Options then + begin + // Clipping is necessary, since depending on X, Y the space will be + // printed outside Rect and potentially fill more than we want. + TextOutFlags := TextOutFlags or ETO_CLIPPED; + Str := PWideChar(SpaceString); + Count := 1; + end + else + begin + Result := False; + Exit; + end; + + // According to the MS Windows SDK (1.5 * Count + 16) is the recommended + // value for GlyphBufferSize (see documentation of cGlyphs parameter of + // ScriptStringAnalyse function) + GlyphBufferSize := (3 * Count) div 2 + 16; + + Result := Succeeded(ScriptStringAnalyse(DC, Str, Count, GlyphBufferSize, -1, + SSAnalyseFlags, 0, nil, nil, Pointer(ETODist), nil, nil, @saa)); + Result := Result and Succeeded(ScriptStringOut(saa, X, Y, TextOutFlags, + @Rect, 0, 0, False)); + Result := Result and Succeeded(ScriptStringFree(@saa)); + end + else +{$ENDIF} + begin + Result := ExtTextOutW(DC, X, Y, TextOutFlags, @Rect, Str, Count, + Pointer(ETODist)); + end; +end; + +{ TSynFontsInfoManager } + +procedure TSynFontsInfoManager.LockFontsInfo( + pFontsInfo: PSynSharedFontsInfo); +begin + Inc(pFontsInfo^.LockCount); +end; + +constructor TSynFontsInfoManager.Create; +begin + inherited; + + FFontsInfo := TList.Create; +end; + +function TSynFontsInfoManager.CreateFontsInfo(ABaseFont: TFont; + const LF: TLogFont): PSynSharedFontsInfo; +begin + New(Result); + FillChar(Result^, SizeOf(TSynSharedFontsInfo), 0); + with Result^ do + try + BaseFont := TFont.Create; + BaseFont.Assign(ABaseFont); + BaseLF := LF; + IsTrueType := (0 <> (TRUETYPE_FONTTYPE and LF.lfPitchAndFamily)); + except + Result^.BaseFont.Free; + Dispose(Result); + raise; + end; +end; + +procedure TSynFontsInfoManager.UnlockFontsInfo( + pFontsInfo: PSynSharedFontsInfo); +begin + with pFontsInfo^ do + begin + Dec(LockCount); + if 0 = LockCount then + DestroyFontHandles(pFontsInfo); + end; +end; + +destructor TSynFontsInfoManager.Destroy; +begin + GFontsInfoManager := nil; + + if Assigned(FFontsInfo) then + begin + while FFontsInfo.Count > 0 do + begin + Assert(1 = PSynSharedFontsInfo(FFontsInfo[FFontsInfo.Count - 1])^.RefCount); + ReleaseFontsInfo(PSynSharedFontsInfo(FFontsInfo[FFontsInfo.Count - 1])); + end; + FFontsInfo.Free; + end; + + inherited; +end; + +procedure TSynFontsInfoManager.DestroyFontHandles( + pFontsInfo: PSynSharedFontsInfo); +var + i: Integer; +begin + with pFontsInfo^ do + for i := Low(TSynStockFontPatterns) to High(TSynStockFontPatterns) do + with FontsData[i] do + if Handle <> 0 then + begin + DeleteObject(Handle); + Handle := 0; + end; +end; + +function TSynFontsInfoManager.FindFontsInfo( + const LF: TLogFont): PSynSharedFontsInfo; +var + i: Integer; +begin + for i := 0 to FFontsInfo.Count - 1 do + begin + Result := PSynSharedFontsInfo(FFontsInfo[i]); + if CompareMem(@(Result^.BaseLF), @LF, SizeOf(TLogFont)) then + Exit; + end; + Result := nil; +end; + +function TSynFontsInfoManager.GetFontsInfo(ABaseFont: TFont): PSynSharedFontsInfo; +var + LF: TLogFont; +begin + Assert(Assigned(ABaseFont)); + + RetrieveLogFontForComparison(ABaseFont, LF); + Result := FindFontsInfo(LF); + if not Assigned(Result) then + begin + Result := CreateFontsInfo(ABaseFont, LF); + FFontsInfo.Add(Result); + end; + + if Assigned(Result) then + Inc(Result^.RefCount); +end; + +procedure TSynFontsInfoManager.ReleaseFontsInfo(pFontsInfo: PSynSharedFontsInfo); +begin + Assert(Assigned(pFontsInfo)); + + with pFontsInfo^ do + begin + Assert(LockCount < RefCount, 'Call DeactivateFontsInfo before calling this.'); + if RefCount > 1 then + Dec(RefCount) + else + begin + FFontsInfo.Remove(pFontsInfo); + // free all objects + BaseFont.Free; + Dispose(pFontsInfo); + end; + end; +end; + +procedure TSynFontsInfoManager.RetrieveLogFontForComparison(ABaseFont: TFont; + var LF: TLogFont); +var + pEnd: PChar; +begin + GetObject(ABaseFont.Handle, SizeOf(TLogFont), @LF); + with LF do + begin + lfItalic := 0; + lfUnderline := 0; + lfStrikeOut := 0; + pEnd := StrEnd(lfFaceName); + FillChar(pEnd[1], @lfFaceName[High(lfFaceName)] - pEnd, 0); + end; +end; + +{ TSynFontStock } + +// CalcFontAdvance : Calculation a advance of a character of a font. +// [*]hCalcFont will be selected as FDC's font if FDC wouldn't be zero. +function TSynFontStock.CalcFontAdvance(DC: HDC; pCharHeight: PInteger): Integer; +var + TM: TTextMetric; + ABC: TABC; + HasABC: Boolean; +begin + // Calculate advance of a character. + // The following code uses ABC widths instead TextMetric.tmAveCharWidth + // because ABC widths always tells truth but tmAveCharWidth does not. + // A true-type font will have ABC widths but others like raster type will not + // so if the function fails then use TextMetric.tmAveCharWidth. + GetTextMetrics(DC, TM); + HasABC := GetCharABCWidths(DC, Ord('M'), Ord('M'), ABC); + if not HasABC then + begin + with ABC do + begin + abcA := 0; + abcB := TM.tmAveCharWidth; + abcC := 0; + end; + TM.tmOverhang := 0; + end; + + // Result(CharWidth) + with ABC do + Result := abcA + Integer(abcB) + abcC + TM.tmOverhang; + // pCharHeight + if Assigned(pCharHeight) then + pCharHeight^ := Abs(TM.tmHeight) {+ TM.tmInternalLeading}; +end; + +constructor TSynFontStock.Create(InitialFont: TFont); +begin + inherited Create; + + SetBaseFont(InitialFont); +end; + +destructor TSynFontStock.Destroy; +begin + ReleaseFontsInfo; + Assert(FDCRefCount = 0); + + inherited; +end; + +function TSynFontStock.GetBaseFont: TFont; +begin + Result := FpInfo^.BaseFont; +end; + +function TSynFontStock.GetCharAdvance: Integer; +begin + Result := FpCrntFontData^.CharAdv; +end; + +function TSynFontStock.GetCharHeight: Integer; +begin + Result := FpCrntFontData^.CharHeight; +end; + +function TSynFontStock.GetFontData(idx: Integer): PSynFontData; +begin + Result := @FpInfo^.FontsData[idx]; +end; + +function TSynFontStock.GetIsTrueType: Boolean; +begin + Result := FpInfo^.IsTrueType +end; + +function TSynFontStock.InternalCreateFont(Style: TFontStyles): HFONT; +const + Bolds: array[Boolean] of Integer = (400, 700); +begin + with FBaseLF do + begin + lfWeight := Bolds[fsBold in Style]; + lfItalic := Ord(BOOL(fsItalic in Style)); + lfUnderline := Ord(BOOL(fsUnderline in Style)); + lfStrikeOut := Ord(BOOL(fsStrikeOut in Style)); + end; + Result := CreateFontIndirect(FBaseLF); +end; + +function TSynFontStock.InternalGetDC: HDC; +begin + if FDCRefCount = 0 then + begin + Assert(FDC = 0); + FDC := GetDC(0); + end; + Inc(FDCRefCount); + Result := FDC; +end; + +procedure TSynFontStock.InternalReleaseDC(Value: HDC); +begin + Dec(FDCRefCount); + if FDCRefCount <= 0 then + begin + Assert((FDC <> 0) and (FDC = Value)); + ReleaseDC(0, FDC); + FDC := 0; + Assert(FDCRefCount = 0); + end; +end; + +procedure TSynFontStock.ReleaseFontHandles; +begin + if FUsingFontHandles then + with GetFontsInfoManager do + begin + UnlockFontsInfo(FpInfo); + FUsingFontHandles := False; + end; +end; + +procedure TSynFontStock.ReleaseFontsInfo; +begin + if Assigned(FpInfo) then + with GetFontsInfoManager do + begin + if FUsingFontHandles then + begin + UnlockFontsInfo(FpInfo); + FUsingFontHandles := False; + end; + ReleaseFontsInfo(FpInfo); + FpInfo := nil; + end; +end; + +procedure TSynFontStock.SetBaseFont(Value: TFont); +var + pInfo: PSynSharedFontsInfo; +begin + if Assigned(Value) then + begin + pInfo := GetFontsInfoManager.GetFontsInfo(Value); + if pInfo = FpInfo then + GetFontsInfoManager.ReleaseFontsInfo(pInfo) + else + begin + ReleaseFontsInfo; + FpInfo := pInfo; + FBaseLF := FpInfo^.BaseLF; + SetStyle(Value.Style); + end; + end + else + raise ESynFontStockException.Create('SetBaseFont: ''Value'' must be specified.'); +end; + +procedure TSynFontStock.SetStyle(Value: TFontStyles); +var + idx: Integer; + DC: HDC; + hOldFont: HFONT; + p: PSynFontData; +begin + Assert(SizeOf(TFontStyles) = 1, + 'TheTextDrawer.SetStyle: There''s more than four font styles but the current '+ + 'code expects only four styles.'); + + idx := Byte(Value); + Assert(idx <= High(TSynStockFontPatterns)); + + UseFontHandles; + p := FontData[idx]; + if FpCrntFontData = p then + Exit; + + FpCrntFontData := p; + with p^ do + if Handle <> 0 then + begin + FCrntFont := Handle; + FCrntStyle := Style; + Exit; + end; + + // create font + FCrntFont := InternalCreateFont(Value); + DC := InternalGetDC; + hOldFont := SelectObject(DC, FCrntFont); + + // retrieve height and advances of new font + with FpCrntFontData^ do + begin + Handle := FCrntFont; + CharAdv := CalcFontAdvance(DC, @CharHeight); + end; + + SelectObject(DC, hOldFont); + InternalReleaseDC(DC); +end; + +procedure TSynFontStock.UseFontHandles; +begin + if not FUsingFontHandles then + with GetFontsInfoManager do + begin + LockFontsInfo(FpInfo); + FUsingFontHandles := True; + end; +end; + +{ TSynTextDrawer } + +constructor TSynTextDrawer.Create(CalcExtentBaseStyle: TFontStyles; BaseFont: TFont); +begin + inherited Create; + + FFontStock := TSynFontStock.Create(BaseFont); + FStockBitmap := TBitmap.Create; + FCalcExtentBaseStyle := CalcExtentBaseStyle; + SetBaseFont(BaseFont); + FColor := clWindowText; + FBkColor := clWindow; +end; + +destructor TSynTextDrawer.Destroy; +begin + FStockBitmap.Free; + FFontStock.Free; + ReleaseETODist; + + inherited; +end; + +procedure TSynTextDrawer.ReleaseETODist; +begin + if Assigned(FETODist) then + begin + FreeMem(FETODist); + FETODist := nil; + end; +end; + +procedure TSynTextDrawer.BeginDrawing(DC: HDC); +begin + if (FDC = DC) then + Assert(FDC <> 0) + else + begin + Assert((FDC = 0) and (DC <> 0) and (FDrawingCount = 0)); + FDC := DC; + FSaveDC := SaveDC(DC); + SelectObject(DC, FCrntFont); + Windows.SetTextColor(DC, ColorToRGB(FColor)); + Windows.SetBkColor(DC, ColorToRGB(FBkColor)); + DoSetCharExtra(FCharExtra); + end; + Inc(FDrawingCount); +end; + +procedure TSynTextDrawer.EndDrawing; +begin + Assert(FDrawingCount >= 1); + Dec(FDrawingCount); + if FDrawingCount <= 0 then + begin + if FDC <> 0 then + RestoreDC(FDC, FSaveDC); + FSaveDC := 0; + FDC := 0; + FDrawingCount := 0; + end; +end; + +function TSynTextDrawer.GetCharWidth: Integer; +begin + Result := FBaseCharWidth + FCharExtra; +end; + +function TSynTextDrawer.GetCharHeight: Integer; +begin + Result := FBaseCharHeight; +end; + +procedure TSynTextDrawer.SetBaseFont(Value: TFont); +begin + if Assigned(Value) then + begin + FlushCharABCWidthCache; + ReleaseETODist; + FStockBitmap.Canvas.Font.Assign(Value); + FStockBitmap.Canvas.Font.Style := []; + with FFontStock do + begin + SetBaseFont(Value); + Style := FCalcExtentBaseStyle; + FBaseCharWidth := CharAdvance; + FBaseCharHeight := CharHeight; + end; + SetStyle(Value.Style); + end + else + raise ESynTextDrawerException.Create('SetBaseFont: ''Value'' must be specified.'); +end; + +procedure TSynTextDrawer.SetBaseStyle(const Value: TFontStyles); +begin + if FCalcExtentBaseStyle <> Value then + begin + FCalcExtentBaseStyle := Value; + FlushCharABCWidthCache; + ReleaseETODist; + with FFontStock do + begin + Style := Value; + FBaseCharWidth := CharAdvance; + FBaseCharHeight := CharHeight; + end; + end; +end; + +procedure TSynTextDrawer.SetStyle(Value: TFontStyles); +begin + with FFontStock do + begin + SetStyle(Value); + Self.FCrntFont := FontHandle; + end; + AfterStyleSet; +end; + +procedure TSynTextDrawer.AfterStyleSet; +begin + if FDC <> 0 then + SelectObject(FDC, FCrntFont); +end; + +procedure TSynTextDrawer.SetForeColor(Value: TColor); +begin + if FColor <> Value then + begin + FColor := Value; + if FDC <> 0 then + SetTextColor(FDC, ColorToRGB(Value)); + end; +end; + +procedure TSynTextDrawer.SetBackColor(Value: TColor); +begin + if FBkColor <> Value then + begin + FBkColor := Value; + if FDC <> 0 then + Windows.SetBkColor(FDC, ColorToRGB(Value)); + end; +end; + +procedure TSynTextDrawer.SetCharExtra(Value: Integer); +begin + if FCharExtra <> Value then + begin + FCharExtra := Value; + DoSetCharExtra(FCharExtra); + end; +end; + +procedure TSynTextDrawer.DoSetCharExtra(Value: Integer); +begin + if FDC <> 0 then + SetTextCharacterExtra(FDC, Value); +end; + +procedure TSynTextDrawer.FlushCharABCWidthCache; +begin + FillChar(FCharABCWidthCache, SizeOf(TABC) * Length(FCharABCWidthCache), 0); + FillChar(FCharWidthCache, SizeOf(Integer) * Length(FCharWidthCache), 0); +end; + +function TSynTextDrawer.GetCachedABCWidth(c: Cardinal; var abc: TABC) : Boolean; +begin + if c > High(FCharABCWidthCache) then + begin + Result := GetCharABCWidthsW(FDC, c, c, abc); + Exit; + end; + abc := FCharABCWidthCache[c]; + if (abc.abcA or Integer(abc.abcB) or abc.abcC) = 0 then + begin + Result := GetCharABCWidthsW(FDC, c, c, abc); + if Result then + FCharABCWidthCache[c] := abc; + end + else + Result := True; +end; + +procedure TSynTextDrawer.TextOut(X, Y: Integer; Text: PWideChar; + Length: Integer); +var + r: TRect; +begin + r := Rect(X, Y, X, Y); + UniversalExtTextOut(FDC, X, Y, [], r, Text, Length, nil); +end; + +procedure TSynTextDrawer.ExtTextOut(X, Y: Integer; Options: TTextOutOptions; + ARect: TRect; Text: PWideChar; Length: Integer); + + procedure InitETODist(CharWidth: Integer); + var + Size: TSize; + i: Integer; + begin + ReallocMem(FETODist, Length * SizeOf(Integer)); + for i := 0 to Length - 1 do + begin + Size := TextExtent(PWideChar(@Text[i]), 1); + if Size.cx <> CharWidth then + FETODist[i] := Ceil(Size.cx / CharWidth) * CharWidth + else FETODist[i] := CharWidth; + end; + end; + + procedure AdjustLastCharWidthAndRect; + var + LastChar: Cardinal; + RealCharWidth, CharWidth: Integer; + CharInfo: TABC; + tm: TTextMetricA; + begin + if Length <= 0 then Exit; + + LastChar := Ord(Text[Length - 1]); + CharWidth := FETODist[Length - 1]; + RealCharWidth := CharWidth; + if Win32PlatformIsUnicode then + begin + if GetCachedABCWidth(LastChar, CharInfo) then + begin + RealCharWidth := CharInfo.abcA + Integer(CharInfo.abcB); + if CharInfo.abcC >= 0 then + Inc(RealCharWidth, CharInfo.abcC); + end + else if LastChar < Ord(High(AnsiChar)) then + begin + GetTextMetricsA(FDC, tm); + RealCharWidth := tm.tmAveCharWidth + tm.tmOverhang; + end; + end + else if WideChar(LastChar) <= High(AnsiChar) then + begin + if GetCharABCWidthsA(FDC, LastChar, LastChar, CharInfo) then + begin + RealCharWidth := CharInfo.abcA + Integer(CharInfo.abcB); + if CharInfo.abcC >= 0 then + Inc(RealCharWidth, CharInfo.abcC); + end + else if LastChar < Ord(High(AnsiChar)) then + begin + GetTextMetricsA(FDC, tm); + RealCharWidth := tm.tmAveCharWidth + tm.tmOverhang; + end; + end; + if RealCharWidth > CharWidth then + Inc(ARect.Right, RealCharWidth - CharWidth); + FETODist[Length - 1] := Max(RealCharWidth, CharWidth); + end; + +begin + InitETODist(GetCharWidth); + AdjustLastCharWidthAndRect; + UniversalExtTextOut(FDC, X, Y, Options, ARect, Text, Length, FETODist); +end; + +procedure TSynTextDrawer.ReleaseTemporaryResources; +begin + FFontStock.ReleaseFontHandles; +end; + +function TSynTextDrawer.TextExtent(const Text: UnicodeString): TSize; +begin + Result := uRESTDWPrivSynUnicode.TextExtent(FStockBitmap.Canvas, Text); +end; + +function TSynTextDrawer.TextExtent(Text: PWideChar; Count: Integer): TSize; +begin + Result := uRESTDWPrivSynUnicode.GetTextSize(FStockBitmap.Canvas.Handle, Text, Count); +end; + +function TSynTextDrawer.TextWidth(const Char: WideChar): Integer; +var + c: Cardinal; +begin + c := Ord(Char); + if c <= High(FCharWidthCache) then + begin + Result := FCharWidthCache[c]; + if Result = 0 then + begin + Result := uRESTDWPrivSynUnicode.TextExtent(FStockBitmap.Canvas, Char).cX; + FCharWidthCache[c] := Result; + end; + end + else + Result := uRESTDWPrivSynUnicode.TextExtent(FStockBitmap.Canvas, Char).cX; +end; + +function TSynTextDrawer.TextWidth(const Text: UnicodeString): Integer; +var + c: Cardinal; +begin + if Length(Text) = 1 then + begin + c := Ord(Text[1]); + if c <= High(FCharWidthCache) then + begin + Result := FCharWidthCache[c]; + if Result = 0 then + begin + Result := uRESTDWPrivSynUnicode.TextExtent(FStockBitmap.Canvas, Text).cX; + FCharWidthCache[c] := Result; + end; + Exit; + end; + end; + Result := uRESTDWPrivSynUnicode.TextExtent(FStockBitmap.Canvas, Text).cX; +end; + +function TSynTextDrawer.TextWidth(Text: PWideChar; Count: Integer): Integer; +begin + Result := uRESTDWPrivSynUnicode.GetTextSize(FStockBitmap.Canvas.Handle, Text, Count).cX; +end; + +initialization + +finalization + GFontsInfoManager.Free; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynUnicode.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynUnicode.pas new file mode 100644 index 000000000..48beb0f7f --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynUnicode.pas @@ -0,0 +1,3708 @@ +{------------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is uRESTDWPrivSynUnicode.pas by Mal Hrz, released 2004-05-30. +All Rights Reserved. +TUnicodeStrings/TUnicodeStringList-code (originally written by Mike Lischke) is based +on JclUnicode.pas which is part of the JCL (www.delphi-jedi.org). + +Contributors to the uRESTDWPrivSynEdit and mwEdit projects are listed in the +Contributors.txt file. + +Alternatively, the contents of this file may be used under the terms of the +GNU General Public License Version 2 or later (the "GPL"), in which case +the provisions of the GPL are applicable instead of those above. +If you wish to allow use of your version of this file only under the terms +of the GPL and not to allow others to use your version of this file +under the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the GPL. +If you do not delete the provisions above, a recipient may use your version +of this file under either the MPL or the GPL. + +$Id: uRESTDWPrivSynUnicode.pas,v 1.1.3.19 2012/11/07 08:54:20 CodehunterWorks Exp $ + +You may retrieve the latest version of this file at the uRESTDWPrivSynEdit home page, +located at http://uRESTDWPrivSynEdit.SourceForge.net + +Provides: +- Unicode(PWideChar) versions of the most important PAnsiChar-functions in + SysUtils and some functions unavailable in Delphi 5. +- An adapted and lighter version of TUnicodeStrings/TUnicodeStringList taken + from JCL, but made portable. +- function for loading and saving of Unicode files, and detecting the encoding +- Unicode clipboard support +- Unicode-version of TCanvas-methods +- Some character constants like CR&LF. + +Last Changes: +- 1.1.3.19: Added TUnicodeStringList.CustomSort +-------------------------------------------------------------------------------} + +{$IFNDEF QSYNUNICODE} +unit uRESTDWPrivSynUnicode; +{$ENDIF} + +{$I uRESTDWPrivSynEdit.inc} + +interface + +uses + {$IFDEF MSWINDOWS} + Windows, + {$ENDIF} + Messages, + Controls, + Forms, + Graphics, + Clipbrd, + {$IFDEF SYN_COMPILER_6_UP} + Types, + {$ENDIF} + Classes, + SysUtils, + TypInfo; + +{$IFNDEF SYN_COMPILER_6_UP} +type + UTF8String = type string; + PUTF8String = ^UTF8String; +{$ENDIF} +{$IFNDEF UNICODE} +type + UnicodeString = WideString; +{$ENDIF} + +const + SLineBreak = {$IFDEF SYN_LINUX} #10 {$ELSE} #13#10 {$ENDIF}; + UTF8BOM: array[0..2] of Byte = ($EF, $BB, $BF); + UTF16BOMLE: array[0..1] of Byte = ($FF, $FE); + UTF16BOMBE: array[0..1] of Byte = ($FE, $FF); + UTF32BOMLE: array[0..3] of Byte = ($FF, $FE, $00, $00); + UTF32BOMBE: array[0..3] of Byte = ($00, $00, $FE, $FF); + +const + // constants describing range of the Unicode Private Use Area (Unicode 3.2) + PrivateUseLow = WideChar($E000); + PrivateUseHigh = WideChar($F8FF); + // filler char: helper for painting wide glyphs + FillerChar = PrivateUseLow; + +const + WideNull = WideChar(#0); + WideTabulator = WideChar(#9); + WideSpace = WideChar(#32); + + // logical line breaks + WideLF = WideChar(#10); + WideLineFeed = WideChar(#10); + WideVerticalTab = WideChar(#11); + WideFormFeed = WideChar(#12); + WideCR = WideChar(#13); + WideCarriageReturn = WideChar(#13); + WideCRLF = UnicodeString(#13#10); + WideLineSeparator = WideChar($2028); + WideParagraphSeparator = WideChar($2029); + + // byte order marks for Unicode files + // Unicode text files (in UTF-16 format) should contain $FFFE as first character to + // identify such a file clearly. Depending on the system where the file was created + // on this appears either in big endian or little endian style. + BOM_LSB_FIRST = WideChar($FEFF); + BOM_MSB_FIRST = WideChar($FFFE); + +type + TSaveFormat = (sfUTF16LSB, sfUTF16MSB, sfUTF8, sfAnsi); + +const + sfUnicodeLSB = sfUTF16LSB; + sfUnicodeMSB = sfUTF16MSB; + +type + TFontCharSet = 0..255; + +{$IFDEF UNICODE} + TUnicodeStrings = TStrings; +{$ELSE} +{ TUnicodeStrings } + + TUnicodeStrings = class; + + // Event used to give the application a chance to switch the way of how to save + // the text in TUnicodeStrings if the text contains characters not only from the + // ANSI block but the save type is ANSI. On triggering the event the application + // can change the property SaveUnicode as needed. This property is again checked + // after the callback returns. + TConfirmConversionEvent = procedure (Sender: TUnicodeStrings; var Allowed: Boolean) of object; + + TUnicodeStrings = class(TPersistent) + private + FUpdateCount: Integer; + FSaved: Boolean; // set in SaveToStream, True in case saving was successfull otherwise False + FOnConfirmConversion: TConfirmConversionEvent; + FSaveFormat: TSaveFormat; // overrides the FSaveUnicode flag, initialized when a file is loaded, + // expect losses if it is set to sfAnsi before saving + function GetCommaText: UnicodeString; + function GetName(Index: Integer): UnicodeString; + function GetValue(const Name: UnicodeString): UnicodeString; + procedure ReadData(Reader: TReader); + procedure SetCommaText(const Value: UnicodeString); + procedure SetValue(const Name, Value: UnicodeString); + procedure WriteData(Writer: TWriter); + function GetSaveUnicode: Boolean; + procedure SetSaveUnicode(const Value: Boolean); + protected + procedure DefineProperties(Filer: TFiler); override; + procedure DoConfirmConversion(var Allowed: Boolean); virtual; + procedure Error(const Msg: string; Data: Integer); + function Get(Index: Integer): UnicodeString; virtual; abstract; + function GetCapacity: Integer; virtual; + function GetCount: Integer; virtual; abstract; + function GetObject(Index: Integer): TObject; virtual; + function GetTextStr: UnicodeString; virtual; + procedure Put(Index: Integer; const S: UnicodeString); virtual; abstract; + procedure PutObject(Index: Integer; AObject: TObject); virtual; abstract; + procedure SetCapacity(NewCapacity: Integer); virtual; + procedure SetUpdateState(Updating: Boolean); virtual; + public + constructor Create; + + function Add(const S: UnicodeString): Integer; virtual; + function AddObject(const S: UnicodeString; AObject: TObject): Integer; virtual; + procedure Append(const S: UnicodeString); + procedure AddStrings(Strings: TStrings); overload; virtual; + procedure AddStrings(Strings: TUnicodeStrings); overload; virtual; + procedure Assign(Source: TPersistent); override; + procedure AssignTo(Dest: TPersistent); override; + procedure BeginUpdate; + procedure Clear; virtual; abstract; + procedure Delete(Index: Integer); virtual; abstract; + procedure EndUpdate; + function Equals(Strings: TUnicodeStrings): Boolean; + procedure Exchange(Index1, Index2: Integer); virtual; + function GetSeparatedText(Separators: UnicodeString): UnicodeString; virtual; + function GetText: PWideChar; virtual; + function IndexOf(const S: UnicodeString): Integer; virtual; + function IndexOfName(const Name: UnicodeString): Integer; + function IndexOfObject(AObject: TObject): Integer; + procedure Insert(Index: Integer; const S: UnicodeString); virtual; abstract; + procedure InsertObject(Index: Integer; const S: UnicodeString; AObject: TObject); + procedure LoadFromFile(const FileName: TFileName); virtual; + procedure LoadFromStream(Stream: TStream); virtual; + procedure Move(CurIndex, NewIndex: Integer); virtual; + procedure SaveToFile(const FileName: TFileName); overload; virtual; + procedure SaveToFile(const FileName: TFileName; WithBOM: Boolean); overload; virtual; + procedure SaveToStream(Stream: TStream; WithBOM: Boolean = True); virtual; + procedure SetTextStr(const Value: UnicodeString); virtual; + + property Capacity: Integer read GetCapacity write SetCapacity; + property CommaText: UnicodeString read GetCommaText write SetCommaText; + property Count: Integer read GetCount; + property Names[Index: Integer]: UnicodeString read GetName; + property Objects[Index: Integer]: TObject read GetObject write PutObject; + property Values[const Name: UnicodeString]: UnicodeString read GetValue write SetValue; + property Saved: Boolean read FSaved; + property SaveUnicode: Boolean read GetSaveUnicode write SetSaveUnicode default True; + property SaveFormat: TSaveFormat read FSaveFormat write FSaveFormat default sfUnicodeLSB; + property Strings[Index: Integer]: UnicodeString read Get write Put; default; + property Text: UnicodeString read GetTextStr write SetTextStr; + + property OnConfirmConversion: TConfirmConversionEvent read FOnConfirmConversion write FOnConfirmConversion; + end; +{$ENDIF} + +{$IFDEF UNICODE} + TUnicodeStringList = TStringList; +{$ELSE} +{ TUnicodeStringList } + + //----- TUnicodeStringList class + TDynWideCharArray = array of WideChar; + TUnicodeStringItem = record + {$IFDEF OWN_UnicodeString_MEMMGR} + FString: PWideChar; // "array of WideChar"; + {$ELSE} + FString: UnicodeString; + {$ENDIF OWN_UnicodeString_MEMMGR} + FObject: TObject; + end; + + TUnicodeStringList = class; + TUnicodeStringItemList = array of TUnicodeStringItem; + TUnicodeStringListSortCompare = function (AString1, AString2: UnicodeString): Integer; + + TUnicodeStringList = class(TUnicodeStrings) + private + FList: TUnicodeStringItemList; + FCount: Integer; + FSorted: Boolean; + FDuplicates: TDuplicates; + FOnChange: TNotifyEvent; + FOnChanging: TNotifyEvent; + procedure ExchangeItems(Index1, Index2: Integer); + procedure Grow; + procedure QuickSort(L, R: Integer); overload; + procedure QuickSort(L, R: Integer; SCompare: TUnicodeStringListSortCompare); overload; + procedure InsertItem(Index: Integer; const S: UnicodeString); + procedure SetSorted(Value: Boolean); + {$IFDEF OWN_UnicodeString_MEMMGR} + procedure SetListString(Index: Integer; const S: UnicodeString); + {$ENDIF OWN_UnicodeString_MEMMGR} + protected + procedure Changed; virtual; + procedure Changing; virtual; + function Get(Index: Integer): UnicodeString; override; + function GetCapacity: Integer; override; + function GetCount: Integer; override; + function GetObject(Index: Integer): TObject; override; + procedure Put(Index: Integer; const S: UnicodeString); override; + procedure PutObject(Index: Integer; AObject: TObject); override; + procedure SetCapacity(NewCapacity: Integer); override; + procedure SetUpdateState(Updating: Boolean); override; + public + destructor Destroy; override; + + function Add(const S: UnicodeString): Integer; override; + procedure Clear; override; + procedure Delete(Index: Integer); override; + procedure Exchange(Index1, Index2: Integer); override; + function Find(const S: UnicodeString; var Index: Integer): Boolean; virtual; + function IndexOf(const S: UnicodeString): Integer; override; + procedure Insert(Index: Integer; const S: UnicodeString); override; + procedure Sort; virtual; + procedure CustomSort(Compare: TUnicodeStringListSortCompare); virtual; + + property Duplicates: TDuplicates read FDuplicates write FDuplicates; + property Sorted: Boolean read FSorted write SetSorted; + property OnChange: TNotifyEvent read FOnChange write FOnChange; + property OnChanging: TNotifyEvent read FOnChanging write FOnChanging; + end; +{$ENDIF} + +{$IFNDEF UNICODE} +{ PWideChar versions of important PAnsiChar functions from SysUtils } +function WStrLen(const Str: PWideChar): Cardinal; +function WStrEnd(const Str: PWideChar): PWideChar; +function WStrMove(Dest: PWideChar; const Source: PWideChar; Count: Integer): PWideChar; +function WStrCopy(Dest: PWideChar; const Source: PWideChar): PWideChar; +function WStrLCopy(Dest: PWideChar; const Source: PWideChar; MaxLen: Cardinal): PWideChar; +function WStrCat(Dest: PWideChar; const Source: PWideChar): PWideChar; +function WStrScan(const Str: PWideChar; Chr: WideChar): PWideChar; +function WStrAlloc(Size: Cardinal): PWideChar; +function WStrNew(const Str: PWideChar): PWideChar; +procedure WStrDispose(Str: PWideChar); +{$ENDIF} + + +{$IFNDEF SYN_COMPILER_6_UP} +{$IFDEF MSWINDOWS} +function UnicodeToUtf8(Dest: PAnsiChar; MaxDestBytes: Cardinal; + Source: PWideChar; SourceChars: Cardinal): Cardinal; +function Utf8ToUnicode(Dest: PWideChar; MaxDestChars: Cardinal; + Source: PAnsiChar; SourceBytes: Cardinal): Cardinal; +function UTF8Encode(const WS: UnicodeString): UTF8String; +function UTF8Decode(const S: UTF8String): UnicodeString; +function AnsiToUtf8(const S: string): UTF8String; +function Utf8ToAnsi(const S: UTF8String): string; + +function WideCompareStr(const S1, S2: UnicodeString): Integer; +function WideCompareText(const S1, S2: UnicodeString): Integer; +{$ENDIF} +{$ENDIF} + +// Kylix has them, but Delphi 5 doesn't and Delphi 6&7 versions are buggy +// in Win9X (fix taken from Troy Wolbrinks TntUnicode-package) +{$IFDEF MSWINDOWS} +{$IFNDEF UNICODE} +var + DefaultSystemCodePage: Cardinal; // implicitly used when converting AnsiString <--> UnicodeString. +{$ENDIF} + +function WCharUpper(lpsz: PWideChar): PWideChar; +function WCharUpperBuff(lpsz: PWideChar; cchLength: DWORD): DWORD; +function WCharLower(lpsz: PWideChar): PWideChar; +function WCharLowerBuff(lpsz: PWideChar; cchLength: DWORD): DWORD; +{$ENDIF} +function SynWideUpperCase(const S: UnicodeString): UnicodeString; +function SynWideLowerCase(const S: UnicodeString): UnicodeString; +function SynIsCharAlpha(const C: WideChar): Boolean; +function SynIsCharAlphaNumeric(const C: WideChar): Boolean; +{$IFNDEF UNICODE} +function CharInSet(C: AnsiChar; const CharSet: TSysCharSet): Boolean; overload; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +function CharInSet(C: WideChar; const CharSet: TSysCharSet): Boolean; overload; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF} +{$ENDIF} + +function WideLastDelimiter(const Delimiters, S: UnicodeString): Integer; +function UnicodeStringReplace(const S, OldPattern, NewPattern: UnicodeString; + Flags: TReplaceFlags): UnicodeString; + +{ functions taken from JCLUnicode.pas } +function WStrComp(Str1, Str2: PWideChar): Integer; +function WStrLComp(Str1, Str2: PWideChar; MaxLen: Cardinal): Integer; +procedure StrSwapByteOrder(Str: PWideChar); +function WideQuotedStr(const S: UnicodeString; Quote: WideChar): UnicodeString; +function WideExtractQuotedStr(var Src: PWideChar; Quote: WideChar): UnicodeString; +function UnicodeStringOfChar(C: WideChar; Count: Cardinal): UnicodeString; +function WideTrim(const S: UnicodeString): UnicodeString; +function WideTrimLeft(const S: UnicodeString): UnicodeString; +function WideTrimRight(const S: UnicodeString): UnicodeString; +{$IFDEF MSWINDOWS} +function CharSetFromLocale(Language: LCID): TFontCharSet; +function CodePageFromLocale(Language: LCID): Integer; +function KeyboardCodePage: Word; +function KeyUnicode(C: AnsiChar): WideChar; +function StringToUnicodeStringEx(const S: AnsiString; CodePage: Word): UnicodeString; +function UnicodeStringToStringEx(const WS: UnicodeString; CodePage: Word): AnsiString; +{$ENDIF} + +{ functions providing same behavior on Win9x and WinNT based systems} +function GetTextSize(DC: HDC; Str: PWideChar; Count: Integer): TSize; + +{ Unicode versions of TCanvas-methods } +function TextExtent(ACanvas: TCanvas; const Text: UnicodeString): TSize; +function TextWidth(ACanvas: TCanvas; const Text: UnicodeString): Integer; +function TextHeight(ACanvas: TCanvas; const Text: UnicodeString): Integer; +procedure TextOut(ACanvas: TCanvas; X, Y: Integer; const Text: UnicodeString); +procedure TextRect(ACanvas: TCanvas; Rect: TRect; X, Y: Integer; + const Text: UnicodeString); + +{ Unicode streaming-support } +type + TSynEncoding = (seUTF8, seUTF16LE, seUTF16BE, seAnsi); + TSynEncodings = set of TSynEncoding; + +{$IFDEF UNICODE} + TWideFileStream = TFileStream; +{$ELSE} + TWideFileStream = class(THandleStream) + public + constructor Create(const FileName: UnicodeString; Mode: Word); overload; + constructor Create(const FileName: UnicodeString; Mode: Word; Rights: Cardinal); overload; + destructor Destroy; override; + end; + +function WideFileOpen(const FileName: UnicodeString; Mode: LongWord): Integer; +function WideFileCreate(const FileName: UnicodeString): Integer; overload; +function WideFileCreate(const FileName: UnicodeString; Rights: Integer): Integer; overload; +{$ENDIF} + +function IsAnsiOnly(const WS: UnicodeString): Boolean; +function IsUTF8(Stream: TStream; out WithBOM: Boolean): Boolean; overload; +function IsUTF8(const FileName: UnicodeString; out WithBOM: Boolean): Boolean; overload; +function GetEncoding(const FileName: UnicodeString; out WithBOM: Boolean): TSynEncoding; overload; +function GetEncoding(Stream: TStream; out WithBOM: Boolean): TSynEncoding; overload; +procedure SaveToFile(const WS: UnicodeString; const FileName: UnicodeString; + Encoding: TSynEncoding; WithBom: Boolean = True); overload; +procedure SaveToFile(UnicodeStrings: TUnicodeStrings; const FileName: UnicodeString; + Encoding: TSynEncoding; WithBom: Boolean = True); overload; +function LoadFromFile(UnicodeStrings: TUnicodeStrings; const FileName: UnicodeString; + out WithBOM: Boolean): TSynEncoding; overload; +function LoadFromFile(UnicodeStrings: TUnicodeStrings; const FileName: UnicodeString; + Encoding: TSynEncoding; out WithBOM: Boolean): TSynEncoding; overload; +procedure SaveToStream(const WS: UnicodeString; Stream: TStream; + Encoding: TSynEncoding; WithBom: Boolean = True); overload; +procedure SaveToStream(UnicodeStrings: TUnicodeStrings; Stream: TStream; + Encoding: TSynEncoding; WithBom: Boolean = True); overload; +function LoadFromStream(UnicodeStrings: TUnicodeStrings; Stream: TStream; + out WithBOM: Boolean): TSynEncoding; overload; +function LoadFromStream(UnicodeStrings: TUnicodeStrings; Stream: TStream; + Encoding: TSynEncoding; out WithBOM: Boolean): TSynEncoding; overload; +function LoadFromStream(UnicodeStrings: TUnicodeStrings; Stream: TStream; + Encoding: TSynEncoding): TSynEncoding; overload; + +function ClipboardProvidesText: Boolean; +function GetClipboardText: UnicodeString; +procedure SetClipboardText(const Text: UnicodeString); + +{ misc functions } +{$IFNDEF UNICODE} +{$IFNDEF SYN_COMPILER_6_UP} +function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString; +procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: UnicodeString); +{$ENDIF} +procedure UnicodeDefineProperties(Filer: TFiler; Instance: TPersistent); +{$ENDIF} +{$IFDEF MSWINDOWS} +function IsWideCharMappableToAnsi(const WC: WideChar): Boolean; +function IsUnicodeStringMappableToAnsi(const WS: UnicodeString): Boolean; +{$ENDIF} + +{$IFDEF MSWINDOWS} +var + Win32PlatformIsUnicode: Boolean; +{$ENDIF} + +implementation + +uses + uRESTDWPrivSynEditTextBuffer, + {$IFDEF SYN_UNISCRIBE} + uRESTDWPrivSynUsp10, + {$ENDIF} + Math, + {$IFDEF SYN_LINUX} + Libc, + {$ENDIF} + {$IFDEF USE_TNT_RUNTIME_SUPPORT} + TntSysUtils, TntClasses, + {$ENDIF} + SysConst, + {$IFDEF SYN_COMPILER_6_UP} + RTLConsts; + {$ELSE} + Consts; + {$ENDIF} + +{$IFNDEF UNICODE} +{ TUnicodeStrings } + +constructor TUnicodeStrings.Create; +begin + inherited; + FSaveFormat := sfUnicodeLSB; +end; + +function TUnicodeStrings.GetSaveUnicode: Boolean; +begin + Result := SaveFormat in [sfUTF16LSB, sfUTF16MSB, sfUTF8]; +end; + +procedure TUnicodeStrings.SetSaveUnicode(const Value: Boolean); +begin + if Value then + SaveFormat := sfUnicodeLSB + else + SaveFormat := sfAnsi; +end; + +function TUnicodeStrings.Add(const S: UnicodeString): Integer; +begin + Result := GetCount; + Insert(Result, S); +end; + +function TUnicodeStrings.AddObject(const S: UnicodeString; AObject: TObject): Integer; +begin + Result := Add(S); + PutObject(Result, AObject); +end; + +procedure TUnicodeStrings.Append(const S: UnicodeString); +begin + Add(S); +end; + +procedure TUnicodeStrings.AddStrings(Strings: TStrings); +var + I: Integer; +{$IFDEF MSWINDOWS} + S: UnicodeString; + CP: Integer; +{$ENDIF} +begin + BeginUpdate; + try + {$IFDEF MSWINDOWS} + CP := CodePageFromLocale(GetThreadLocale); + for I := 0 to Strings.Count - 1 do + begin + S := StringToUnicodeStringEx(Strings[I], CP); + AddObject(S, Strings.Objects[I]); + end; + {$ELSE} + for I := 0 to Strings.Count - 1 do + AddObject(Strings[I], Strings.Objects[I]); + {$ENDIF} + finally + EndUpdate; + end; +end; + +procedure TUnicodeStrings.AddStrings(Strings: TUnicodeStrings); +var + I: Integer; +begin + Assert(Strings <> nil); + + BeginUpdate; + try + for I := 0 to Strings.Count - 1 do + AddObject(Strings[I], Strings.Objects[I]); + finally + EndUpdate; + end; +end; + +procedure TUnicodeStrings.Assign(Source: TPersistent); +// usual assignment routine, but able to assign wide and small strings +begin + if Source is TUnicodeStrings then + begin + BeginUpdate; + try + Clear; + AddStrings(TUnicodeStrings(Source)); + finally + EndUpdate; + end; + end + else + begin + if Source is TStrings then + begin + BeginUpdate; + try + Clear; + AddStrings(TStrings(Source)); + finally + EndUpdate; + end; + end + else + inherited Assign(Source); + end; +end; + +procedure TUnicodeStrings.AssignTo(Dest: TPersistent); +// need to do also assignment to old style TStrings, but this class doesn't know +// TUnicodeStrings, so we need to do it from here +var + I: Integer; +begin + if Dest is TStrings then + begin + with Dest as TStrings do + begin + BeginUpdate; + try + Clear; + for I := 0 to Self.Count - 1 do + AddObject(Self[I], Self.Objects[I]); + finally + EndUpdate; + end; + end; + end + else + begin + if Dest is TUnicodeStrings then + begin + with Dest as TUnicodeStrings do + begin + BeginUpdate; + try + Clear; + AddStrings(Self); + finally + EndUpdate; + end; + end; + end + else + inherited; + end; +end; + +procedure TUnicodeStrings.BeginUpdate; +begin + if FUpdateCount = 0 then + SetUpdateState(True); + Inc(FUpdateCount); +end; + +procedure TUnicodeStrings.DefineProperties(Filer: TFiler); +// Defines a private property for the content of the list. +// There's a bug in the handling of text DFMs in Classes.pas which prevents +// UnicodeStrings from loading under some circumstances. Zbysek Hlinka +// (zhlinka att login dott cz) brought this to my attention and supplied also a solution. +// See ReadData and WriteData methods for implementation details. + + function DoWrite: Boolean; + begin + if Filer.Ancestor <> nil then + begin + Result := True; + if Filer.Ancestor is TUnicodeStrings then + Result := not Equals(TUnicodeStrings(Filer.Ancestor)) + end + else + Result := Count > 0; + end; + +begin + Filer.DefineProperty('UnicodeStrings', ReadData, WriteData, DoWrite); +end; + +procedure TUnicodeStrings.DoConfirmConversion(var Allowed: Boolean); +begin + if Assigned(FOnConfirmConversion) then + FOnConfirmConversion(Self, Allowed); +end; + +procedure TUnicodeStrings.EndUpdate; +begin + Dec(FUpdateCount); + if FUpdateCount = 0 then + SetUpdateState(False); +end; + +function TUnicodeStrings.Equals(Strings: TUnicodeStrings): Boolean; +var + I, Count: Integer; +begin + Assert(Strings <> nil); + + Result := False; + Count := GetCount; + if Count <> Strings.GetCount then + Exit; + for I := 0 to Count - 1 do + if Get(I) <> Strings.Get(I) then + Exit; + Result := True; +end; + +procedure TUnicodeStrings.Error(const Msg: string; Data: Integer); + + function ReturnAddr: Pointer; + asm + MOV EAX, [EBP + 4] + end; + +begin + raise EStringListError.CreateFmt(Msg, [Data]) at ReturnAddr; +end; + +procedure TUnicodeStrings.Exchange(Index1, Index2: Integer); +var + TempObject: TObject; + TempString: UnicodeString; +begin + BeginUpdate; + try + TempString := Strings[Index1]; + TempObject := Objects[Index1]; + Strings[Index1] := Strings[Index2]; + Objects[Index1] := Objects[Index2]; + Strings[Index2] := TempString; + Objects[Index2] := TempObject; + finally + EndUpdate; + end; +end; + +function TUnicodeStrings.GetCapacity: Integer; +// Descendants may optionally override/replace this default implementation. +begin + Result := Count; +end; + +function TUnicodeStrings.GetCommaText: UnicodeString; +var + S: UnicodeString; + P: PWideChar; + I, Count: Integer; +begin + Count := GetCount; + if (Count = 1) and (Get(0) = '') then + Result := '""' + else + begin + Result := ''; + for I := 0 to Count - 1 do + begin + S := Get(I); + P := PWideChar(S); + while not (P^ in [WideNull..WideSpace, WideChar('"'), WideChar(',')]) do + Inc(P); + if P^ <> WideNull then + S := WideQuotedStr(S, '"'); + Result := Result + S + ','; + end; + System.Delete(Result, Length(Result), 1); + end; +end; + +function TUnicodeStrings.GetName(Index: Integer): UnicodeString; +var + P: Integer; +begin + Result := Get(Index); + P := Pos('=', Result); + if P > 0 then + SetLength(Result, P - 1) + else + Result := ''; +end; + +function TUnicodeStrings.GetObject(Index: Integer): TObject; +begin + Result := nil; +end; + +function TUnicodeStrings.GetSeparatedText(Separators: UnicodeString): UnicodeString; +// Same as GetText but with customizable separator characters. +var + I, L, + Size, + Count, + SepSize: Integer; + P: PWideChar; + S: UnicodeString; +begin + Count := GetCount; + SepSize := Length(Separators); + Size := 0; + for I := 0 to Count - 1 do + Inc(Size, Length(Get(I)) + SepSize); + + // set one separator less, the last line does not need a trailing separator + SetLength(Result, Size - SepSize); + if Size > 0 then + begin + P := Pointer(Result); + I := 0; + while True do + begin + S := Get(I); + L := Length(S); + if L <> 0 then + begin + // add current string + System.Move(Pointer(S)^, P^, 2 * L); + Inc(P, L); + end; + Inc(I); + if I = Count then + Break; + + // add separators + System.Move(Pointer(Separators)^, P^, SizeOf(WideChar) * SepSize); + Inc(P, SepSize); + end; + end; +end; + +function TUnicodeStrings.GetTextStr: UnicodeString; +begin + Result := GetSeparatedText(WideCRLF); +end; + +function TUnicodeStrings.GetText: PWideChar; +begin + Result := WStrNew(PWideChar(GetTextStr)); +end; + +function TUnicodeStrings.GetValue(const Name: UnicodeString): UnicodeString; +var + I: Integer; +begin + I := IndexOfName(Name); + if I >= 0 then + Result := Copy(Get(I), Length(Name) + 2, MaxInt) + else + Result := ''; +end; + +function TUnicodeStrings.IndexOf(const S: UnicodeString): Integer; +begin + for Result := 0 to GetCount - 1 do + if WideCompareText(Get(Result), S) = 0 then + Exit; + Result := -1; +end; + +function TUnicodeStrings.IndexOfName(const Name: UnicodeString): Integer; +var + P: Integer; + S: UnicodeString; +begin + for Result := 0 to GetCount - 1 do + begin + S := Get(Result); + P := Pos('=', S); + if (P > 0) and (WideCompareText(Copy(S, 1, P - 1), Name) = 0) then + Exit; + end; + Result := -1; +end; + +function TUnicodeStrings.IndexOfObject(AObject: TObject): Integer; +begin + for Result := 0 to GetCount - 1 do + if GetObject(Result) = AObject then + Exit; + Result := -1; +end; + +procedure TUnicodeStrings.InsertObject(Index: Integer; const S: UnicodeString; AObject: TObject); +begin + Insert(Index, S); + PutObject(Index, AObject); +end; + +procedure TUnicodeStrings.LoadFromFile(const FileName: TFileName); +var + Stream: TStream; +begin + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone); + try + LoadFromStream(Stream); + finally + Stream.Free; + end; +end; + +procedure TUnicodeStrings.LoadFromStream(Stream: TStream); +// usual loader routine, but enhanced to handle byte order marks in stream +var + Size, + BytesRead: Integer; + ByteOrderMask: array[0..5] of Byte; // BOM size is max 5 bytes (cf: wikipedia) + // but it is easier to implement with a multiple of 2 + Loaded: Boolean; + SW: UnicodeString; + SA: AnsiString; +begin + BeginUpdate; + try + Loaded := False; + + Size := Stream.Size - Stream.Position; + BytesRead := Stream.Read(ByteOrderMask[0], SizeOf(ByteOrderMask)); + + // UTF16 LSB = Unicode LSB/LE + if (BytesRead >= 2) and (ByteOrderMask[0] = UTF16BOMLE[0]) + and (ByteOrderMask[1] = UTF16BOMLE[1]) then + begin + FSaveFormat := sfUTF16LSB; + SetLength(SW, (Size - 2) div SizeOf(WideChar)); + Assert((Size and 1) <> 1, 'Number of chars must be a multiple of 2'); + if BytesRead > 2 then + begin + System.Move(ByteOrderMask[2], SW[1], BytesRead - 2); // max 4 bytes = 2 widechars + if Size > BytesRead then + // first 2 chars (maximum) were copied by System.Move + Stream.Read(SW[3], Size - BytesRead); + end; + SetTextStr(SW); + Loaded := True; + end; + + // UTF16 MSB = Unicode MSB/BE + if (BytesRead >= 2) and (ByteOrderMask[0] = UTF16BOMBE[0]) + and (ByteOrderMask[1] = UTF16BOMBE[1]) then + begin + FSaveFormat := sfUTF16MSB; + SetLength(SW, (Size - 2) div SizeOf(WideChar)); + Assert((Size and 1) <> 1, 'Number of chars must be a multiple of 2'); + if BytesRead > 2 then + begin + System.Move(ByteOrderMask[2], SW[1] ,BytesRead - 2); // max 4 bytes = 2 widechars + if Size > BytesRead then + // first 2 chars (maximum) were copied by System.Move + Stream.Read(SW[3], Size - BytesRead); + StrSwapByteOrder(PWideChar(SW)); + end; + SetTextStr(SW); + Loaded := True; + end; + + // UTF8 + if (BytesRead >= 3) and (ByteOrderMask[0] = UTF8BOM[0]) + and (ByteOrderMask[1] = UTF8BOM[1]) and (ByteOrderMask[2] = UTF8BOM[2]) then + begin + FSaveFormat := sfUTF8; + SetLength(SA, (Size - 3) div SizeOf(AnsiChar)); + if BytesRead > 3 then + begin + System.Move(ByteOrderMask[3], SA[1], BytesRead - 3); // max 3 bytes = 3 chars + if Size > BytesRead then + // first 3 chars were copied by System.Move + Stream.Read(SA[4], Size - BytesRead); + SW := UTF8Decode(SA); + end; + SetTextStr(SW); + Loaded := True; + end; + + // default case (Ansi) + if not Loaded then + begin + FSaveFormat := sfAnsi; + SetLength(SA, Size div SizeOf(AnsiChar)); + if BytesRead > 0 then + begin + System.Move(ByteOrderMask[0], SA[1], BytesRead); // max 6 bytes = 6 chars + if Size > BytesRead then + Stream.Read(SA[7], Size - BytesRead); // first 6 chars were copied by System.Move + SW := UTF8Decode(SA); + if SW <> '' then + begin + FSaveFormat := sfUTF8; + SetTextStr(SW); + Loaded := True; + end; + end; + if not Loaded then + SetTextStr(SA); + end; + finally + EndUpdate; + end; +end; + +procedure TUnicodeStrings.Move(CurIndex, NewIndex: Integer); +var + TempObject: TObject; + TempString: UnicodeString; +begin + if CurIndex <> NewIndex then + begin + BeginUpdate; + try + TempString := Get(CurIndex); + TempObject := GetObject(CurIndex); + Delete(CurIndex); + InsertObject(NewIndex, TempString, TempObject); + finally + EndUpdate; + end; + end; +end; + +procedure TUnicodeStrings.ReadData(Reader: TReader); +begin + case Reader.NextValue of + vaLString, vaString: + SetTextStr(Reader.ReadString); + else + SetTextStr(Reader.ReadWideString); + end; +end; + +procedure TUnicodeStrings.SaveToFile(const FileName: TFileName); +var + Stream: TStream; +begin + Stream := TFileStream.Create(FileName, fmCreate); + try + SaveToStream(Stream); + finally + Stream.Free; + end; +end; + +procedure TUnicodeStrings.SaveToFile(const FileName: TFileName; WithBOM: Boolean); +var + Stream: TStream; +begin + Stream := TFileStream.Create(FileName, fmCreate); + try + SaveToStream(Stream, WithBOM); + finally + Stream.Free; + end; +end; + +procedure TUnicodeStrings.SaveToStream(Stream: TStream; WithBOM: Boolean = True); +// Saves the currently loaded text into the given stream. WithBOM determines whether to write a +// byte order mark or not. Note: when saved as ANSI text there will never be a BOM. +var + SW: UnicodeString; + SA: AnsiString; + Allowed: Boolean; + Run: PWideChar; +begin + // The application can decide in which format to save the content. + // If FSaveUnicode is False then all strings are saved in standard ANSI format + // which is also loadable by TStrings but you should be aware that all Unicode + // strings are then converted to ANSI based on the current system locale. + // An extra event is supplied to ask the user about the potential loss of + // information when converting Unicode to ANSI strings. + SW := GetTextStr; + Allowed := True; + FSaved := False; // be pessimistic + // A check for potential information loss makes only sense if the application has + // set an event to be used as call back to ask about the conversion. + if not SaveUnicode and Assigned(FOnConfirmConversion) then + begin + // application requests to save only ANSI characters, so check the text and + // call back in case information could be lost + Run := PWideChar(SW); + // only ask if there's at least one Unicode character in the text + while Run^ in [WideChar(#1)..WideChar(#255)] do + Inc(Run); + // Note: The application can still set FSaveUnicode to True in the callback. + if Run^ <> WideNull then + DoConfirmConversion(Allowed); + end; + + if Allowed then + begin + // only save if allowed + case SaveFormat of + sfUTF16LSB: + begin + if WithBOM then + Stream.WriteBuffer(UTF16BOMLE[0], SizeOf(UTF16BOMLE)); + Stream.WriteBuffer(SW[1], Length(SW) * SizeOf(WideChar)); + FSaved := True; + end; + sfUTF16MSB: + begin + if WithBOM then + Stream.WriteBuffer(UTF16BOMBE[0], SizeOf(UTF16BOMBE)); + StrSwapByteOrder(PWideChar(SW)); + Stream.WriteBuffer(SW[1], Length(SW) * SizeOf(WideChar)); + FSaved := True; + end; + sfUTF8: + begin + if WithBOM then + Stream.WriteBuffer(UTF8BOM[0], SizeOf(UTF8BOM)); + SA := UTF8Encode(SW); + Stream.WriteBuffer(SA[1], Length(SA) * SizeOf(AnsiChar)); + FSaved := True; + end; + sfAnsi: + begin + SA := SW; + Stream.WriteBuffer(SA[1], Length(SA) * SizeOf(AnsiChar)); + FSaved := True; + end; + end; + end; +end; + +procedure TUnicodeStrings.SetCapacity(NewCapacity: Integer); +begin + // do nothing - descendants may optionally implement this method +end; + +procedure TUnicodeStrings.SetCommaText(const Value: UnicodeString); +var + P, P1: PWideChar; + S: UnicodeString; +begin + BeginUpdate; + try + Clear; + P := PWideChar(Value); + while P^ in [WideChar(#1)..WideSpace] do + Inc(P); + while P^ <> WideNull do + begin + if P^ = '"' then + S := WideExtractQuotedStr(P, '"') + else + begin + P1 := P; + while (P^ > WideSpace) and (P^ <> ',') do + Inc(P); + SetString(S, P1, P - P1); + end; + Add(S); + + while P^ in [WideChar(#1)..WideSpace] do + Inc(P); + if P^ = ',' then + begin + repeat + Inc(P); + until not (P^ in [WideChar(#1)..WideSpace]); + end; + end; + finally + EndUpdate; + end; +end; + +procedure TUnicodeStrings.SetTextStr(const Value: UnicodeString); +var + Head, + Tail: PWideChar; + S: UnicodeString; +begin + BeginUpdate; + try + Clear; + Head := PWideChar(Value); + while Head^ <> WideNull do + begin + Tail := Head; + while not (Tail^ in [WideNull, WideLineFeed, WideCarriageReturn, WideVerticalTab, WideFormFeed]) and + (Tail^ <> WideLineSeparator) and (Tail^ <> WideParagraphSeparator) do + Inc(Tail); + SetString(S, Head, Tail - Head); + Add(S); + Head := Tail; + if Head^ <> WideNull then + begin + Inc(Head); + if (Tail^ = WideCarriageReturn) and (Head^ = WideLineFeed) then + Inc(Head); + end; + end; + finally + EndUpdate; + end; +end; + +procedure TUnicodeStrings.SetUpdateState(Updating: Boolean); +begin +end; + +procedure TUnicodeStrings.SetValue(const Name, Value: UnicodeString); +var + I : Integer; +begin + I := IndexOfName(Name); + if Value <> '' then + begin + if I < 0 then + I := Add(''); + Put(I, Name + '=' + Value); + end + else + begin + if I >= 0 then + Delete(I); + end; +end; + +procedure TUnicodeStrings.WriteData(Writer: TWriter); +begin + Writer.WriteWideString(GetTextStr); +end; + + +{ TUnicodeStringList } + +destructor TUnicodeStringList.Destroy; +begin + FOnChange := nil; + FOnChanging := nil; + Clear; + inherited; +end; + +function TUnicodeStringList.Add(const S: UnicodeString): Integer; +begin + if not Sorted then + Result := FCount + else + begin + if Find(S, Result) then + begin + case Duplicates of + dupIgnore: + Exit; + dupError: + Error(SDuplicateString, 0); + end; + end; + end; + InsertItem(Result, S); +end; + +procedure TUnicodeStringList.Changed; +begin + if (FUpdateCount = 0) and Assigned(FOnChange) then + FOnChange(Self); +end; + +procedure TUnicodeStringList.Changing; +begin + if (FUpdateCount = 0) and Assigned(FOnChanging) then + FOnChanging(Self); +end; + +procedure TUnicodeStringList.Clear; +{$IFDEF OWN_UnicodeString_MEMMGR} +var + I: Integer; +{$ENDIF OWN_UnicodeString_MEMMGR} +begin + if FCount <> 0 then + begin + Changing; + {$IFDEF OWN_UnicodeString_MEMMGR} + for I := 0 to FCount - 1 do + with FList[I] do + if TDynWideCharArray(FString) <> nil then + TDynWideCharArray(FString) := nil; + {$ENDIF OWN_UnicodeString_MEMMGR} + // this will automatically finalize the array + FList := nil; + FCount := 0; + SetCapacity(0); + Changed; + end; +end; + +procedure TUnicodeStringList.Delete(Index: Integer); +begin + if Cardinal(Index) >= Cardinal(FCount) then + Error(SListIndexError, Index); + Changing; + + {$IFDEF OWN_UnicodeString_MEMMGR} + SetListString(Index, ''); + {$ELSE} + FList[Index].FString := ''; + {$ENDIF OWN_UnicodeString_MEMMGR} + Dec(FCount); + if Index < FCount then + begin + System.Move(FList[Index + 1], FList[Index], (FCount - Index) * SizeOf(TUnicodeStringItem)); + Pointer(FList[FCount].FString) := nil; // avoid freeing the string, the address is now used in another element + end; + Changed; +end; + +procedure TUnicodeStringList.Exchange(Index1, Index2: Integer); +begin + if Cardinal(Index1) >= Cardinal(FCount) then + Error(SListIndexError, Index1); + if Cardinal(Index2) >= Cardinal(FCount) then + Error(SListIndexError, Index2); + Changing; + ExchangeItems(Index1, Index2); + Changed; +end; + +procedure TUnicodeStringList.ExchangeItems(Index1, Index2: Integer); +var + Temp: TUnicodeStringItem; +begin + Temp := FList[Index1]; + FList[Index1] := FList[Index2]; + FList[Index2] := Temp; +end; + +function TUnicodeStringList.Find(const S: UnicodeString; var Index: Integer): Boolean; +var + L, H, I, C: Integer; +begin + Result := False; + L := 0; + H := FCount - 1; + while L <= H do + begin + I := (L + H) shr 1; + C := WideCompareText(FList[I].FString, S); + if C < 0 then + L := I+1 + else + begin + H := I - 1; + if C = 0 then + begin + Result := True; + if Duplicates <> dupAccept then + L := I; + end; + end; + end; + Index := L; +end; + +function TUnicodeStringList.Get(Index: Integer): UnicodeString; +{$IFDEF OWN_UnicodeString_MEMMGR} +var + Len: Integer; +{$ENDIF OWN_UnicodeString_MEMMGR} +begin + if Cardinal(Index) >= Cardinal(FCount) then + Error(SListIndexError, Index); + {$IFDEF OWN_UnicodeString_MEMMGR} + with FList[Index] do + begin + Len := Length(TDynWideCharArray(FString)); + if Len > 0 then + begin + SetLength(Result, Len - 1); // exclude #0 + if Result <> '' then + System.Move(FString^, Result[1], Len * SizeOf(WideChar)); + end + else + Result := ''; + end; + {$ELSE} + Result := FList[Index].FString; + {$ENDIF OWN_UnicodeString_MEMMGR} +end; + +function TUnicodeStringList.GetCapacity: Integer; +begin + Result := Length(FList); +end; + +function TUnicodeStringList.GetCount: Integer; +begin + Result := FCount; +end; + +function TUnicodeStringList.GetObject(Index: Integer): TObject; +begin + if Cardinal(Index) >= Cardinal(FCount) then + Error(SListIndexError, Index); + Result := FList[Index].FObject; +end; + +procedure TUnicodeStringList.Grow; +var + Delta, + Len: Integer; +begin + Len := Length(FList); + if Len > 64 then + Delta := Len div 4 + else + begin + if Len > 8 then + Delta := 16 + else + Delta := 4; + end; + SetCapacity(Len + Delta); +end; + +function TUnicodeStringList.IndexOf(const S: UnicodeString): Integer; +begin + if not Sorted then + Result := inherited IndexOf(S) + else + if not Find(S, Result) then + Result := -1; +end; + +procedure TUnicodeStringList.Insert(Index: Integer; const S: UnicodeString); +begin + if Sorted then + Error(SSortedListError, 0); + if Cardinal(Index) > Cardinal(FCount) then + Error(SListIndexError, Index); + InsertItem(Index, S); +end; + +{$IFDEF OWN_UnicodeString_MEMMGR} +procedure TUnicodeStringList.SetListString(Index: Integer; const S: UnicodeString); +var + Len: Integer; + A: TDynWideCharArray; +begin + with FList[Index] do + begin + Pointer(A) := TDynWideCharArray(FString); + if A <> nil then + A := nil; // free memory + + Len := Length(S); + if Len > 0 then + begin + SetLength(A, Len + 1); // include #0 + System.Move(S[1], A[0], Len * SizeOf(WideChar)); + A[Len] := #0; + end; + + FString := PWideChar(A); + Pointer(A) := nil; // do not release the array on procedure exit + end; +end; +{$ENDIF OWN_UnicodeString_MEMMGR} + +procedure TUnicodeStringList.InsertItem(Index: Integer; const S: UnicodeString); +begin + Changing; + if FCount = Length(FList) then + Grow; + if Index < FCount then + System.Move(FList[Index], FList[Index + 1], (FCount - Index) * SizeOf(TUnicodeStringItem)); + with FList[Index] do + begin + Pointer(FString) := nil; // avoid freeing the string, the address is now used in another element + FObject := nil; + {$IFDEF OWN_UnicodeString_MEMMGR} + SetListString(Index, S); + {$ELSE} + FString := S; + {$ENDIF OWN_UnicodeString_MEMMGR} + end; + Inc(FCount); + Changed; +end; + +procedure TUnicodeStringList.Put(Index: Integer; const S: UnicodeString); +begin + if Sorted then + Error(SSortedListError, 0); + if Cardinal(Index) >= Cardinal(FCount) then + Error(SListIndexError, Index); + Changing; + + {$IFDEF OWN_UnicodeString_MEMMGR} + SetListString(Index, S); + {$ELSE} + FList[Index].FString := S; + {$ENDIF OWN_UnicodeString_MEMMGR} + Changed; +end; + +procedure TUnicodeStringList.PutObject(Index: Integer; AObject: TObject); +begin + if Cardinal(Index) >= Cardinal(FCount) then + Error(SListIndexError, Index); + Changing; + FList[Index].FObject := AObject; + Changed; +end; + +procedure TUnicodeStringList.QuickSort(L, R: Integer); +var + I, J: Integer; + P: UnicodeString; +begin + repeat + I := L; + J := R; + P := FList[(L + R) shr 1].FString; + repeat + while WideCompareText(FList[I].FString, P) < 0 do + Inc(I); + while WideCompareText(FList[J].FString, P) > 0 do + Dec(J); + if I <= J then + begin + ExchangeItems(I, J); + Inc(I); + Dec(J); + end; + until I > J; + if L < J then + QuickSort(L, J); + L := I; + until I >= R; +end; + +procedure TUnicodeStringList.QuickSort(L, R: Integer; SCompare: TUnicodeStringListSortCompare); +var + I, J: Integer; + P: UnicodeString; +begin + repeat + I := L; + J := R; + P := FList[(L + R) shr 1].FString; + repeat + while SCompare(FList[I].FString, P) < 0 do + Inc(I); + while SCompare(FList[J].FString, P) > 0 do + Dec(J); + if I <= J then + begin + ExchangeItems(I, J); + Inc(I); + Dec(J); + end; + until I > J; + if L < J then + QuickSort(L, J); + L := I; + until I >= R; +end; + +procedure TUnicodeStringList.CustomSort(Compare: TUnicodeStringListSortCompare); +begin + if not Sorted and (FCount > 1) then + begin + Changing; + QuickSort(0, FCount - 1, Compare); + Changed; + end; +end; + +procedure TUnicodeStringList.SetCapacity(NewCapacity: Integer); +begin + SetLength(FList, NewCapacity); + if NewCapacity < FCount then + FCount := NewCapacity; +end; + +procedure TUnicodeStringList.SetSorted(Value: Boolean); +begin + if FSorted <> Value then + begin + if Value then + Sort; + FSorted := Value; + end; +end; + +procedure TUnicodeStringList.SetUpdateState(Updating: Boolean); +begin + if Updating then + Changing + else + Changed; +end; + +procedure TUnicodeStringList.Sort; +begin + if not Sorted and (FCount > 1) then + begin + Changing; + QuickSort(0, FCount - 1); + Changed; + end; +end; +{$ENDIF} + +function WStrLen(const Str: PWideChar): Cardinal; +asm + MOV EDX,EDI + MOV EDI,EAX + MOV ECX,0FFFFFFFFH + XOR AX,AX + REPNE SCASW + MOV EAX,0FFFFFFFEH + SUB EAX,ECX + MOV EDI,EDX +end; + +function WStrEnd(const Str: PWideChar): PWideChar; +asm + MOV EDX,EDI + MOV EDI,EAX + MOV ECX,0FFFFFFFFH + XOR AX,AX + REPNE SCASW + LEA EAX,[EDI-2] + MOV EDI,EDX +end; + +function WStrMove(Dest: PWideChar; const Source: PWideChar; Count: Integer): PWideChar; +begin + Result := Dest; + System.Move(Source^, Dest^, Count * SizeOf(WideChar)); +end; + +function WStrCopy(Dest: PWideChar; const Source: PWideChar): PWideChar; +{$IFDEF SYN_COMPILER_16_UP} +begin + Result := SysUtils.StrCopy(Dest, Source) +{$ELSE} +asm + PUSH EDI + PUSH ESI + MOV ESI,EAX + MOV EDI,EDX + MOV ECX,0FFFFFFFFH + XOR AX,AX + REPNE SCASW + NOT ECX + MOV EDI,ESI + MOV ESI,EDX + MOV EDX,ECX + MOV EAX,EDI + SHR ECX,1 + REP MOVSD + MOV ECX,EDX + AND ECX,1 + REP MOVSW + POP ESI + POP EDI +{$ENDIF} +end; + +function WStrLCopy(Dest: PWideChar; const Source: PWideChar; MaxLen: Cardinal): PWideChar; +{$IFDEF SYN_COMPILER_16_UP} +begin + Result := SysUtils.StrLCopy(Dest, Source, MaxLen) +{$ELSE} +asm + PUSH EDI + PUSH ESI + PUSH EBX + MOV ESI,EAX + MOV EDI,EDX + MOV EBX,ECX + XOR AX,AX + TEST ECX,ECX + JZ @@1 + REPNE SCASW + JNE @@1 + Inc ECX +@@1: SUB EBX,ECX + MOV EDI,ESI + MOV ESI,EDX + MOV EDX,EDI + MOV ECX,EBX + SHR ECX,1 + REP MOVSD + MOV ECX,EBX + AND ECX,1 + REP MOVSW + STOSW + MOV EAX,EDX + POP EBX + POP ESI + POP EDI +{$ENDIF} +end; + +function WStrCat(Dest: PWideChar; const Source: PWideChar): PWideChar; +begin + WStrCopy(WStrEnd(Dest), Source); + Result := Dest; +end; + +function WStrScan(const Str: PWideChar; Chr: WideChar): PWideChar; +begin + Result := Str; + while Result^ <> Chr do + begin + if Result^ = #0 then + begin + Result := nil; + Exit; + end; + Inc(Result); + end; +end; + +function WStrAlloc(Size: Cardinal): PWideChar; +begin + Size := SizeOf(WideChar) * Size + SizeOf(Cardinal); + GetMem(Result, Size); + Cardinal(Pointer(Result)^) := Size; + Inc(PByte(Result), SizeOf(Cardinal)); +end; + +function WStrNew(const Str: PWideChar): PWideChar; +var + Size: Cardinal; +begin + if Str = nil then + Result := nil + else + begin + Size := WStrLen(Str) + 1; + Result := WStrMove(WStrAlloc(Size), Str, Size); + end; +end; + +procedure WStrDispose(Str: PWideChar); +begin + if Str <> nil then + begin + Dec(PByte(Str), SizeOf(Cardinal)); + FreeMem(Str, Cardinal(Pointer(Str)^)); + end; +end; + +{$IFNDEF SYN_COMPILER_6_UP} +{$IFDEF MSWINDOWS} +function UnicodeToUtf8(Dest: PAnsiChar; MaxDestBytes: Cardinal; + Source: PWideChar; SourceChars: Cardinal): Cardinal; +var + i, count: Cardinal; + c: Cardinal; +begin + Result := 0; + if Source = nil then Exit; + count := 0; + i := 0; + if Dest <> nil then + begin + while (i < SourceChars) and (count < MaxDestBytes) do + begin + c := Cardinal(Source[i]); + Inc(i); + if c <= $7F then + begin + Dest[count] := Char(c); + Inc(count); + end + else if c > $7FF then + begin + if count + 3 > MaxDestBytes then + Break; + Dest[count] := Char($E0 or (c shr 12)); + Dest[count+1] := Char($80 or ((c shr 6) and $3F)); + Dest[count+2] := Char($80 or (c and $3F)); + Inc(count,3); + end + else // $7F < Source[i] <= $7FF + begin + if count + 2 > MaxDestBytes then + Break; + Dest[count] := Char($C0 or (c shr 6)); + Dest[count+1] := Char($80 or (c and $3F)); + Inc(count,2); + end; + end; + if count >= MaxDestBytes then count := MaxDestBytes-1; + Dest[count] := #0; + end + else + begin + while i < SourceChars do + begin + c := Integer(Source[i]); + Inc(i); + if c > $7F then + begin + if c > $7FF then + Inc(count); + Inc(count); + end; + Inc(count); + end; + end; + Result := count+1; // convert zero based index to byte count +end; + +function Utf8ToUnicode(Dest: PWideChar; MaxDestChars: Cardinal; + Source: PAnsiChar; SourceBytes: Cardinal): Cardinal; +var + i, count: Cardinal; + c: Byte; + wc: Cardinal; +begin + if Source = nil then + begin + Result := 0; + Exit; + end; + Result := Cardinal(-1); + count := 0; + i := 0; + if Dest <> nil then + begin + while (i < SourceBytes) and (count < MaxDestChars) do + begin + wc := Cardinal(Source[i]); + Inc(i); + if (wc and $80) <> 0 then + begin + if i >= SourceBytes then Exit; // incomplete multibyte char + wc := wc and $3F; + if (wc and $20) <> 0 then + begin + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then Exit; // malformed trail byte or out of range char + if i >= SourceBytes then Exit; // incomplete multibyte char + wc := (wc shl 6) or (c and $3F); + end; + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then Exit; // malformed trail byte + + Dest[count] := WideChar((wc shl 6) or (c and $3F)); + end + else + Dest[count] := WideChar(wc); + Inc(count); + end; + if count >= MaxDestChars then count := MaxDestChars-1; + Dest[count] := #0; + end + else + begin + while (i < SourceBytes) do + begin + c := Byte(Source[i]); + Inc(i); + if (c and $80) <> 0 then + begin + if i >= SourceBytes then Exit; // incomplete multibyte char + c := c and $3F; + if (c and $20) <> 0 then + begin + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then Exit; // malformed trail byte or out of range char + if i >= SourceBytes then Exit; // incomplete multibyte char + end; + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then Exit; // malformed trail byte + end; + Inc(count); + end; + end; + Result := count+1; +end; + +function Utf8Encode(const WS: UnicodeString): UTF8String; +var + L: Integer; + Temp: UTF8String; +begin + Result := ''; + if WS = '' then Exit; + SetLength(Temp, Length(WS) * 3); // SetLength includes space for null terminator + + L := UnicodeToUtf8(PAnsiChar(Temp), Length(Temp)+1, PWideChar(WS), Length(WS)); + if L > 0 then + SetLength(Temp, L-1) + else + Temp := ''; + Result := Temp; +end; + +function Utf8Decode(const S: UTF8String): UnicodeString; +var + L: Integer; + Temp: UnicodeString; +begin + Result := ''; + if S = '' then Exit; + SetLength(Temp, Length(S)); + + L := Utf8ToUnicode(PWideChar(Temp), Length(Temp)+1, PAnsiChar(S), Length(S)); + if L > 0 then + SetLength(Temp, L-1) + else + Temp := ''; + Result := Temp; +end; + +function AnsiToUtf8(const S: string): UTF8String; +begin + Result := Utf8Encode(S); +end; + +function Utf8ToAnsi(const S: UTF8String): string; +begin + Result := Utf8Decode(S); +end; + +function DumbItDownFor95(const S1, S2: UnicodeString; CmpFlags: Integer): Integer; +var + a1, a2: AnsiString; +begin + a1 := s1; + a2 := s2; + Result := CompareStringA(LOCALE_USER_DEFAULT, CmpFlags, PAnsiChar(a1), + Length(a1), PAnsiChar(a2), Length(a2)) - 2; +end; + +function WideCompareStr(const S1, S2: UnicodeString): Integer; +begin + SetLastError(0); + Result := CompareStringW(LOCALE_USER_DEFAULT, 0, PWideChar(S1), Length(S1), + PWideChar(S2), Length(S2)) - 2; + case GetLastError of + 0: ; + ERROR_CALL_NOT_IMPLEMENTED: Result := DumbItDownFor95(S1, S2, 0); + else + RaiseLastWin32Error; + end; +end; + +function WideCompareText(const S1, S2: UnicodeString): Integer; +begin + SetLastError(0); + Result := CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, PWideChar(S1), + Length(S1), PWideChar(S2), Length(S2)) - 2; + case GetLastError of + 0: ; + ERROR_CALL_NOT_IMPLEMENTED: Result := DumbItDownFor95(S1, S2, NORM_IGNORECASE); + else + RaiseLastWin32Error; + end; +end; +{$ENDIF} +{$ENDIF} + +{$IFDEF MSWINDOWS} +// The Win9X fix for SynWideUpperCase and SynWideLowerCase was taken +// from Troy Wolbrinks, TntUnicode-package. + +function WCharUpper(lpsz: PWideChar): PWideChar; +var + AStr: AnsiString; + WStr: UnicodeString; +begin + if Win32PlatformIsUnicode then + Result := Windows.CharUpperW(lpsz) + else + begin + if HiWord(Cardinal(lpsz)) = 0 then + begin + // literal char mode + Result := lpsz; + if IsWideCharMappableToAnsi(WideChar(lpsz)) then + begin + AStr := AnsiString(WideChar(lpsz)); // single character may be more than one byte + Windows.CharUpperA(PAnsiChar(AStr)); + WStr := UnicodeString(AStr); // should always be single wide char + if Length(WStr) = 1 then + Result := PWideChar(WStr[1]); + end + end + else + begin + // null-terminated string mode + Result := lpsz; + while lpsz^ <> #0 do + begin + lpsz^ := WideChar(uRESTDWPrivSynUnicode.WCharUpper(PWideChar(lpsz^))); + Inc(lpsz); + end; + end; + end; +end; + +function WCharUpperBuff(lpsz: PWideChar; cchLength: DWORD): DWORD; +var + i: Integer; +begin + if Win32PlatformIsUnicode then + Result := Windows.CharUpperBuffW(lpsz, cchLength) + else + begin + Result := cchLength; + for i := 1 to cchLength do + begin + lpsz^ := WideChar(uRESTDWPrivSynUnicode.WCharUpper(PWideChar(lpsz^))); + Inc(lpsz); + end; + end; +end; + +function WCharLower(lpsz: PWideChar): PWideChar; +var + AStr: AnsiString; + WStr: UnicodeString; +begin + if Win32PlatformIsUnicode then + Result := Windows.CharLowerW(lpsz) + else + begin + if HiWord(Cardinal(lpsz)) = 0 then + begin + // literal char mode + Result := lpsz; + if IsWideCharMappableToAnsi(WideChar(lpsz)) then + begin + AStr := AnsiString(WideChar(lpsz)); // single character may be more than one byte + Windows.CharLowerA(PAnsiChar(AStr)); + WStr := UnicodeString(AStr); // should always be single wide char + if Length(WStr) = 1 then + Result := PWideChar(WStr[1]); + end + end + else + begin + // null-terminated string mode + Result := lpsz; + while lpsz^ <> #0 do + begin + lpsz^ := WideChar(uRESTDWPrivSynUnicode.WCharLower(PWideChar(lpsz^))); + Inc(lpsz); + end; + end; + end; +end; + +function WCharLowerBuff(lpsz: PWideChar; cchLength: DWORD): DWORD; +var + i: Integer; +begin + if Win32PlatformIsUnicode then + Result := Windows.CharLowerBuffW(lpsz, cchLength) + else + begin + Result := cchLength; + for i := 1 to cchLength do + begin + lpsz^ := WideChar(uRESTDWPrivSynUnicode.WCharLower(PWideChar(lpsz^))); + Inc(lpsz); + end; + end; +end; + +function SynWideUpperCase(const S: UnicodeString): UnicodeString; +var + Len: Integer; +begin + Len := Length(S); + SetString(Result, PWideChar(S), Len); + if Len > 0 then + uRESTDWPrivSynUnicode.WCharUpperBuff(Pointer(Result), Len); +end; + +function SynWideLowerCase(const S: UnicodeString): UnicodeString; +var + Len: Integer; +begin + Len := Length(S); + SetString(Result, PWideChar(S), Len); + if Len > 0 then + uRESTDWPrivSynUnicode.WCharLowerBuff(Pointer(Result), Len); +end; +{$ELSE} +function SynWideUpperCase(const S: UnicodeString): UnicodeString; +begin + Result := WideUpperCase(S); +end; + +function SynWideLowerCase(const S: UnicodeString): UnicodeString; +begin + Result := WideLowerCase(S); +end; +{$ENDIF} + +{$IFDEF MSWINDOWS} +function SynIsCharAlpha(const C: WideChar): Boolean; +begin + if Win32PlatformIsUnicode then + Result := IsCharAlphaW(C) + else + // returns false if C is not mappable to ANSI + Result := IsCharAlphaA(AnsiChar(C)); +end; + +function SynIsCharAlphaNumeric(const C: WideChar): Boolean; +begin + if Win32PlatformIsUnicode then + Result := IsCharAlphaNumericW(C) + else + // returns false if C is not mappable to ANSI + Result := IsCharAlphaNumericA(AnsiChar(C)); +end; +{$ELSE} +function SynIsCharAlpha(const C: WideChar): Boolean; +begin + Result := IsAlpha(Integer(ch)) <> 0; +end; + +function SynIsCharAlphaNumeric(const C: WideChar): Boolean; +begin + Result := IsAlNum(Integer(ch)) <> 0; +end; +{$ENDIF} + +{$IFNDEF UNICODE} +function CharInSet(C: AnsiChar; const CharSet: TSysCharSet): Boolean; +begin + Result := C in CharSet; +end; + +function CharInSet(C: WideChar; const CharSet: TSysCharSet): Boolean; +begin + Result := (C < #$0100) and (AnsiChar(C) in CharSet); +end; +{$ENDIF} + +function WideLastDelimiter(const Delimiters, S: UnicodeString): Integer; +var + P: PWideChar; +begin + Result := Length(S); + P := PWideChar(Delimiters); + while Result > 0 do + begin + if (S[Result] <> #0) and (WStrScan(P, S[Result]) <> nil) then + Exit; + Dec(Result); + end; +end; + +function UnicodeStringReplace(const S, OldPattern, NewPattern: UnicodeString; + Flags: TReplaceFlags): UnicodeString; +var + SearchStr, Patt, NewStr: UnicodeString; + Offset: Integer; +begin + if rfIgnoreCase in Flags then + begin + SearchStr := SynWideUpperCase(S); + Patt := SynWideUpperCase(OldPattern); + end + else + begin + SearchStr := S; + Patt := OldPattern; + end; + NewStr := S; + Result := ''; + while SearchStr <> '' do + begin + Offset := Pos(Patt, SearchStr); + if Offset = 0 then + begin + Result := Result + NewStr; + Break; + end; + Result := Result + Copy(NewStr, 1, Offset - 1) + NewPattern; + NewStr := Copy(NewStr, Offset + Length(OldPattern), MaxInt); + if not (rfReplaceAll in Flags) then + begin + Result := Result + NewStr; + Break; + end; + SearchStr := Copy(SearchStr, Offset + Length(Patt), MaxInt); + end; +end; + +const + // data used to bring UTF-16 coded strings into correct UTF-32 order for correct comparation + UTF16Fixup: array[0..31] of Word = ( + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + $2000, $F800, $F800, $F800, $F800 + ); + +// Binary comparation of Str1 and Str2 with surrogate fix-up. +// Returns < 0 if Str1 is smaller in binary order than Str2, = 0 if both strings are +// equal and > 0 if Str1 is larger than Str2. +// +// This code is based on an idea of Markus W. Scherer (IBM). +// Note: The surrogate fix-up is necessary because some single value code points have +// larger values than surrogates which are in UTF-32 actually larger. +function WStrComp(Str1, Str2: PWideChar): Integer; +var + C1, C2: Word; + Run1, Run2: PWideChar; +begin + Run1 := Str1; + Run2 := Str2; + repeat + C1 := Word(Run1^); + C1 := Word(C1 + UTF16Fixup[C1 shr 11]); + C2 := Word(Run2^); + C2 := Word(C2 + UTF16Fixup[C2 shr 11]); + + // now C1 and C2 are in UTF-32-compatible order + Result := Integer(C1) - Integer(C2); + if(Result <> 0) or (C1 = 0) or (C2 = 0) then + Break; + Inc(Run1); + Inc(Run2); + until False; + + // If the strings have different lengths but the comparation returned equity so far + // then adjust the result so that the longer string is marked as the larger one. + if Result = 0 then + Result := (Run1 - Str1) - (Run2 - Str2); +end; + +// compares strings up to MaxLen code points +// see also StrCompW +function WStrLComp(Str1, Str2: PWideChar; MaxLen: Cardinal): Integer; +var + C1, C2: Word; +begin + if MaxLen > 0 then + begin + repeat + C1 := Word(Str1^); + C1 := Word(C1 + UTF16Fixup[C1 shr 11]); + C2 := Word(Str2^); + C2 := Word(C2 + UTF16Fixup[C2 shr 11]); + + // now C1 and C2 are in UTF-32-compatible order + { TODO : surrogates take up 2 words and are counted twice here, count them only once } + Result := Integer(C1) - Integer(C2); + Dec(MaxLen); + if(Result <> 0) or (C1 = 0) or (C2 = 0) or (MaxLen = 0) then + Break; + Inc(Str1); + Inc(Str2); + until False; + end + else + Result := 0; +end; + +// exchanges in each character of the given string the low order and high order +// byte to go from LSB to MSB and vice versa. +// EAX contains address of string +procedure StrSwapByteOrder(Str: PWideChar); +{$IFDEF SYN_COMPILER_16_UP} +var + P: PWord; +begin + P := PWord(Str); + while P^ <> 0 do + begin + P^ := MakeWord(HiByte(P^), LoByte(P^)); + Inc(P); + end; +{$ELSE} +asm + PUSH ESI + PUSH EDI + MOV ESI, EAX + MOV EDI, ESI + XOR EAX, EAX // clear high order byte to be able to use 32bit operand below +@@1: + LODSW + OR EAX, EAX + JZ @@2 + XCHG AL, AH + STOSW + JMP @@1 + + +@@2: + POP EDI + POP ESI +{$ENDIF} +end; + +// works like QuotedStr from SysUtils.pas but can insert any quotation character +function WideQuotedStr(const S: UnicodeString; Quote: WideChar): UnicodeString; +var + P, Src, + Dest: PWideChar; + AddCount: Integer; +begin + AddCount := 0; + P := WStrScan(PWideChar(S), Quote); + while (P <> nil) do + begin + Inc(P); + Inc(AddCount); + P := WStrScan(P, Quote); + end; + + if AddCount = 0 then + Result := Quote + S + Quote + else + begin + SetLength(Result, Length(S) + AddCount + 2); + Dest := PWideChar(Result); + Dest^ := Quote; + Inc(Dest); + Src := PWideChar(S); + P := WStrScan(Src, Quote); + repeat + Inc(P); + Move(Src^, Dest^, 2 * (P - Src)); + Inc(Dest, P - Src); + Dest^ := Quote; + Inc(Dest); + Src := P; + P := WStrScan(Src, Quote); + until P = nil; + P := WStrEnd(Src); + Move(Src^, Dest^, 2 * (P - Src)); + Inc(Dest, P - Src); + Dest^ := Quote; + end; +end; + +// extracts a string enclosed in quote characters given by Quote +function WideExtractQuotedStr(var Src: PWideChar; Quote: WideChar): UnicodeString; +var + P, Dest: PWideChar; + DropCount: Integer; +begin + Result := ''; + if (Src = nil) or (Src^ <> Quote) then + Exit; + + Inc(Src); + DropCount := 1; + P := Src; + Src := WStrScan(Src, Quote); + + while Src <> nil do // count adjacent pairs of quote chars + begin + Inc(Src); + if Src^ <> Quote then + Break; + Inc(Src); + Inc(DropCount); + Src := WStrScan(Src, Quote); + end; + + if Src = nil then + Src := WStrEnd(P); + if (Src - P) <= 1 then + Exit; + + if DropCount = 1 then + SetString(Result, P, Src - P - 1) + else + begin + SetLength(Result, Src - P - DropCount); + Dest := PWideChar(Result); + Src := WStrScan(P, Quote); + while Src <> nil do + begin + Inc(Src); + if Src^ <> Quote then + Break; + Move(P^, Dest^, 2 * (Src - P)); + Inc(Dest, Src - P); + Inc(Src); + P := Src; + Src := WStrScan(Src, Quote); + end; + if Src = nil then + Src := WStrEnd(P); + Move(P^, Dest^, 2 * (Src - P - 1)); + end; +end; + +// returns a string of Count characters filled with C +function UnicodeStringOfChar(C: WideChar; Count: Cardinal): UnicodeString; +var + I: Integer; +begin + SetLength(Result, Count); + for I := 1 to Count do + Result[I] := C; +end; + +function WideTrim(const S: UnicodeString): UnicodeString; +var + I, L: Integer; +begin + L := Length(S); + I := 1; + while (I <= L) and (S[I] <= ' ') do Inc(I); + if I > L then + Result := '' + else + begin + while S[L] <= ' ' do Dec(L); + Result := Copy(S, I, L - I + 1); + end; +end; + +function WideTrimLeft(const S: UnicodeString): UnicodeString; +var + I, L: Integer; +begin + L := Length(S); + I := 1; + while (I <= L) and (S[I] <= ' ') do Inc(I); + Result := Copy(S, I, Maxint); +end; + +function WideTrimRight(const S: UnicodeString): UnicodeString; +var + I: Integer; +begin + I := Length(S); + while (I > 0) and (S[I] <= ' ') do Dec(I); + Result := Copy(S, 1, I); +end; + +{$IFDEF MSWINDOWS} +function TranslateCharsetInfoEx(lpSrc: PDWORD; var lpCs: TCharsetInfo; dwFlags: DWORD): BOOL; stdcall; + external 'gdi32.dll' name 'TranslateCharsetInfo'; + +function CharSetFromLocale(Language: LCID): TFontCharSet; +var + CP: Cardinal; + CSI: TCharsetInfo; +begin + CP:= CodePageFromLocale(Language); + TranslateCharsetInfoEx(Pointer(CP), CSI, TCI_SRCCODEPAGE); + Result:= CSI.ciCharset; +end; + +// determines the code page for a given locale +function CodePageFromLocale(Language: LCID): Integer; +var + Buf: array[0..6] of Char; +begin + GetLocaleInfo(Language, LOCALE_IDefaultAnsiCodePage, Buf, 6); + Result := StrToIntDef(Buf, GetACP); +end; + +function KeyboardCodePage: Word; +begin + Result := CodePageFromLocale(GetKeyboardLayout(0) and $FFFF); +end; + +// converts the given character (as it comes with a WM_CHAR message) into its +// corresponding Unicode character depending on the active keyboard layout +function KeyUnicode(C: AnsiChar): WideChar; +begin + MultiByteToWideChar(KeyboardCodePage, MB_USEGLYPHCHARS, @C, 1, @Result, 1); +end; + +function StringToUnicodeStringEx(const S: AnsiString; CodePage: Word): UnicodeString; +var + InputLength, + OutputLength: Integer; +begin + InputLength := Length(S); + OutputLength := MultiByteToWideChar(CodePage, 0, PAnsiChar(S), InputLength, + nil, 0); + SetLength(Result, OutputLength); + MultiByteToWideChar(CodePage, 0, PAnsiChar(S), InputLength, PWideChar(Result), + OutputLength); +end; + +function UnicodeStringToStringEx(const WS: UnicodeString; CodePage: Word): AnsiString; +var + InputLength, + OutputLength: Integer; +begin + InputLength := Length(WS); + OutputLength := WideCharToMultiByte(CodePage, 0, PWideChar(WS), InputLength, + nil, 0, nil, nil); + SetLength(Result, OutputLength); + WideCharToMultiByte(CodePage, 0, PWideChar(WS), InputLength, PAnsiChar(Result), + OutputLength, nil, nil); +end; +{$ENDIF} + +function GetTextSize(DC: HDC; Str: PWideChar; Count: Integer): TSize; +{$IFDEF SYN_UNISCRIBE} +const + SSAnalyseFlags = SSA_GLYPHS or SSA_FALLBACK or SSA_LINK; +{$ENDIF} +var + tm: TTextMetricA; + {$IFDEF SYN_UNISCRIBE} + GlyphBufferSize: Integer; + saa: TScriptStringAnalysis; + lpSize: PSize; + {$ENDIF} +begin + Result.cx := 0; + Result.cy := 0; + +{$IFDEF SYN_UNISCRIBE} + if Usp10IsInstalled then + begin + if Count <= 0 then Exit; + + // According to the MS Windows SDK (1.5 * Count + 16) is the recommended + // value for GlyphBufferSize (see documentation of cGlyphs parameter of + // ScriptStringAnalyse function) + GlyphBufferSize := (3 * Count) div 2 + 16; + + if Succeeded(ScriptStringAnalyse(DC, Str, Count, GlyphBufferSize, -1, + SSAnalyseFlags, 0, nil, nil, nil, nil, nil, @saa)) then + begin + lpSize := ScriptString_pSize(saa); + if lpSize <> nil then + begin + Result := lpSize^; + if Result.cx = 0 then + begin + GetTextMetricsA(DC, tm); + Result.cx := tm.tmAveCharWidth; + end; + end; + ScriptStringFree(@saa); + end; + end + else +{$ENDIF} + begin + GetTextExtentPoint32W(DC, Str, Count, Result); + if not Win32PlatformIsUnicode then + begin + GetTextMetricsA(DC, tm); + if tm.tmPitchAndFamily and TMPF_TRUETYPE <> 0 then + Result.cx := Result.cx - tm.tmOverhang + else + Result.cx := tm.tmAveCharWidth * Count; + end; + end; +end; + +type + TAccessCanvas = class(TCanvas) + end; + +function TextExtent(ACanvas: TCanvas; const Text: UnicodeString): TSize; +begin + with TAccessCanvas(ACanvas) do + begin + RequiredState([csHandleValid, csFontValid]); + Result := GetTextSize(Handle, PWideChar(Text), Length(Text)); + end; +end; + +function TextWidth(ACanvas: TCanvas; const Text: UnicodeString): Integer; +begin + Result := TextExtent(ACanvas, Text).cX; +end; + +function TextHeight(ACanvas: TCanvas; const Text: UnicodeString): Integer; +begin + Result := TextExtent(ACanvas, Text).cY; +end; + +procedure TextOut(ACanvas: TCanvas; X, Y: Integer; const Text: UnicodeString); +begin + with TAccessCanvas(ACanvas) do + begin + Changing; + RequiredState([csHandleValid, csFontValid, csBrushValid]); + if CanvasOrientation = coRightToLeft then + Inc(X, uRESTDWPrivSynUnicode.TextWidth(ACanvas, Text) + 1); + Windows.ExtTextOutW(Handle, X, Y, TextFlags, nil, PWideChar(Text), + Length(Text), nil); + MoveTo(X + uRESTDWPrivSynUnicode.TextWidth(ACanvas, Text), Y); + Changed; + end; +end; + +procedure TextRect(ACanvas: TCanvas; Rect: TRect; X, Y: Integer; + const Text: UnicodeString); +var + Options: Longint; +begin + with TAccessCanvas(ACanvas) do + begin + Changing; + RequiredState([csHandleValid, csFontValid, csBrushValid]); + Options := ETO_CLIPPED or TextFlags; + if Brush.Style <> bsClear then + Options := Options or ETO_OPAQUE; + if ((TextFlags and ETO_RTLREADING) <> 0) and + (CanvasOrientation = coRightToLeft) + then + Inc(X, uRESTDWPrivSynUnicode.TextWidth(ACanvas, Text) + 1); + Windows.ExtTextOutW(Handle, X, Y, Options, @Rect, PWideChar(Text), + Length(Text), nil); + Changed; + end; +end; + +{$IFNDEF UNICODE} +{ TWideFileStream } + +constructor TWideFileStream.Create(const FileName: UnicodeString; Mode: Word); +begin +{$IFDEF MSWINDOWS} + Create(Filename, Mode, 0); +{$ELSE} + Create(Filename, Mode, FileAccessRights); +{$ENDIF} +end; + +constructor TWideFileStream.Create(const FileName: UnicodeString; Mode: Word; + Rights: Cardinal); +{$IFDEF USE_TNT_RUNTIME_SUPPORT} +var + ErrorMessage: UnicodeString; +{$ENDIF} +begin + if ((Mode and fmCreate) = fmCreate) then + begin + inherited Create(WideFileCreate(FileName, Rights)); + if Handle < 0 then + begin +{$IFDEF USE_TNT_RUNTIME_SUPPORT} + {$IFDEF SYN_COMPILER_7_UP} + ErrorMessage := WideSysErrorMessage(GetLastError); + raise EWideFCreateError.CreateResFmt(PResStringRec(@SFCreateErrorEx), + [WideExpandFileName(FileName), ErrorMessage]); + {$ELSE} + raise EWideFCreateError.CreateResFmt(@SFCreateError, [FileName]); + {$ENDIF} +{$ELSE} + {$IFDEF SYN_COMPILER_7_UP} + raise EFCreateError.CreateResFmt(PResStringRec(@SFCreateErrorEx), + [ExpandFileName(FileName), SysErrorMessage(GetLastError)]); + {$ELSE} + raise EFCreateError.CreateResFmt(PResStringRec(@SFCreateError), [FileName]); + {$ENDIF} +{$ENDIF} + end + end + else + begin + inherited Create(WideFileOpen(FileName, Mode)); + if Handle < 0 then + begin +{$IFDEF USE_TNT_RUNTIME_SUPPORT} + {$IFDEF SYN_COMPILER_7_UP} + ErrorMessage := WideSysErrorMessage(GetLastError); + raise EWideFOpenError.CreateResFmt(PResStringRec(@SFOpenErrorEx), + [WideExpandFileName(FileName), ErrorMessage]); + {$ELSE} + raise EWideFOpenError.CreateResFmt(@SFOpenError, [FileName]); + {$ENDIF} +{$ELSE} + {$IFDEF SYN_COMPILER_7_UP} + raise EFOpenError.CreateResFmt(PResStringRec(@SFOpenErrorEx), + [ExpandFileName(FileName), SysErrorMessage(GetLastError)]); + {$ELSE} + raise EFOpenError.CreateResFmt(PResStringRec(@SFOpenError), [FileName]); + {$ENDIF} +{$ENDIF} + end; + end; +end; + +destructor TWideFileStream.Destroy; +begin + if Handle >= 0 then FileClose(Handle); + inherited Destroy; +end; + +function WideFileOpen(const FileName: UnicodeString; Mode: LongWord): Integer; +{$IFDEF MSWINDOWS} +const + AccessMode: array[0..2] of LongWord = ( + GENERIC_READ, + GENERIC_WRITE, + GENERIC_READ or GENERIC_WRITE); + ShareMode: array[0..4] of LongWord = ( + 0, + 0, + FILE_SHARE_READ, + FILE_SHARE_WRITE, + FILE_SHARE_READ or FILE_SHARE_WRITE); +begin + Result := -1; + if ((Mode and 3) <= fmOpenReadWrite) and + ((Mode and $F0) <= fmShareDenyNone) then + begin + if Win32PlatformIsUnicode then + Result := Integer(CreateFileW(PWideChar(FileName), AccessMode[Mode and 3], + ShareMode[(Mode and $F0) shr 4], nil, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, 0)) + else + Result := Integer(CreateFileA(PAnsiChar(AnsiString(FileName)), AccessMode[Mode and 3], + ShareMode[(Mode and $F0) shr 4], nil, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, 0)); + end; +end; +{$ENDIF} +{$IFDEF SYN_LINUX} +const + ShareMode: array[0..fmShareDenyNone shr 4] of Byte = ( + 0, //No share mode specified + F_WRLCK, //fmShareExclusive + F_RDLCK, //fmShareDenyWrite + 0); //fmShareDenyNone +var + FileHandle, Tvar: Integer; + LockVar: TFlock; + smode: Byte; +begin + Result := -1; + if FileExists(FileName) and + ((Mode and 3) <= fmOpenReadWrite) and + ((Mode and $F0) <= fmShareDenyNone) then + begin + FileHandle := open(PChar(AnsiString(FileName)), (Mode and 3), FileAccessRights); + + if FileHandle = -1 then Exit; + + smode := Mode and $F0 shr 4; + if ShareMode[smode] <> 0 then + begin + with LockVar do + begin + l_whence := SEEK_SET; + l_start := 0; + l_len := 0; + l_type := ShareMode[smode]; + end; + Tvar := fcntl(FileHandle, F_SETLK, LockVar); + if Tvar = -1 then + begin + __close(FileHandle); + Exit; + end; + end; + Result := FileHandle; + end; +end; +{$ENDIF} + +function WideFileCreate(const FileName: UnicodeString): Integer; +{$IFDEF MSWINDOWS} +begin + if Win32PlatformIsUnicode then + Result := Integer(CreateFileW(PWideChar(FileName), GENERIC_READ or GENERIC_WRITE, + 0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)) + else + Result := Integer(CreateFileA(PAnsiChar(AnsiString(FileName)), GENERIC_READ or GENERIC_WRITE, + 0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)); +end; +{$ENDIF} +{$IFDEF SYN_LINUX} +begin + Result := FileCreate(FileName, FileAccessRights); +end; +{$ENDIF} + +function WideFileCreate(const FileName: UnicodeString; Rights: Integer): Integer; +{$IFDEF MSWINDOWS} +begin + Result := WideFileCreate(FileName); +end; +{$ENDIF} +{$IFDEF SYN_LINUX} +begin + Result := Integer(open(PChar(AnsiString(FileName)), O_RDWR or O_CREAT or O_TRUNC, Rights)); +end; +{$ENDIF} +{$ENDIF} + +function IsAnsiOnly(const WS: UnicodeString): Boolean; +{$IFDEF MSWINDOWS} +begin + Result := IsUnicodeStringMappableToAnsi(WS); +end; +{$ELSE} +var + Run: PWideChar; +begin + Run := PWideChar(WS); + while Run^ in [WideChar(#1)..WideChar(#255)] do + Inc(Run); + Result := Run^ = WideNull; +end; +{$ENDIF} + +function IsUTF8(const FileName: UnicodeString; out WithBOM: Boolean): Boolean; +var + Stream: TStream; +begin + Stream := TWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + Result := IsUTF8(Stream, WithBOM); + finally + Stream.Free; + end; +end; + +// checks for a BOM in UTF-8 format or searches the first 4096 bytes for +// typical UTF-8 octet sequences +function IsUTF8(Stream: TStream; out WithBOM: Boolean): Boolean; +const + MinimumCountOfUTF8Strings = 1; + MaxBufferSize = $4000; +var + Buffer: array of Byte; + BufferSize, i, FoundUTF8Strings: Integer; + + // 3 trailing bytes are the maximum in valid UTF-8 streams, + // so a count of 4 trailing bytes is enough to detect invalid UTF-8 streams + function CountOfTrailingBytes: Integer; + begin + Result := 0; + Inc(i); + while (i < BufferSize) and (Result < 4) do + begin + if Buffer[i] in [$80..$BF] then + Inc(Result) + else + Break; + Inc(i); + end; + end; + +begin + // if Stream is nil, let Delphi raise the exception, by accessing Stream, + // to signal an invalid result + + // start analysis at actual Stream.Position + BufferSize := Min(MaxBufferSize, Stream.Size - Stream.Position); + + // if no special characteristics are found it is not UTF-8 + Result := False; + WithBOM := False; + + if BufferSize > 0 then + begin + SetLength(Buffer, BufferSize); + Stream.ReadBuffer(Buffer[0], BufferSize); + Stream.Seek(-BufferSize, soFromCurrent); + + { first search for BOM } + + if (BufferSize >= Length(UTF8BOM)) and CompareMem(@Buffer[0], @UTF8BOM[0], Length(UTF8BOM)) then + begin + WithBOM := True; + Result := True; + Exit; + end; + + { If no BOM was found, check for leading/trailing byte sequences, + which are uncommon in usual non UTF-8 encoded text. + + NOTE: There is no 100% save way to detect UTF-8 streams. The bigger + MinimumCountOfUTF8Strings, the lower is the probability of + a false positive. On the other hand, a big MinimumCountOfUTF8Strings + makes it unlikely to detect files with only little usage of non + US-ASCII chars, like usual in European languages. } + + FoundUTF8Strings := 0; + i := 0; + while i < BufferSize do + begin + case Buffer[i] of + $00..$7F: // skip US-ASCII characters as they could belong to various charsets + ; + $C2..$DF: + if CountOfTrailingBytes = 1 then + Inc(FoundUTF8Strings) + else + Break; + $E0: + begin + Inc(i); + if (i < BufferSize) and (Buffer[i] in [$A0..$BF]) and (CountOfTrailingBytes = 1) then + Inc(FoundUTF8Strings) + else + Break; + end; + $E1..$EC, $EE..$EF: + if CountOfTrailingBytes = 2 then + Inc(FoundUTF8Strings) + else + Break; + $ED: + begin + Inc(i); + if (i < BufferSize) and (Buffer[i] in [$80..$9F]) and (CountOfTrailingBytes = 1) then + Inc(FoundUTF8Strings) + else + Break; + end; + $F0: + begin + Inc(i); + if (i < BufferSize) and (Buffer[i] in [$90..$BF]) and (CountOfTrailingBytes = 2) then + Inc(FoundUTF8Strings) + else + Break; + end; + $F1..$F3: + if CountOfTrailingBytes = 3 then + Inc(FoundUTF8Strings) + else + Break; + $F4: + begin + Inc(i); + if (i < BufferSize) and (Buffer[i] in [$80..$8F]) and (CountOfTrailingBytes = 2) then + Inc(FoundUTF8Strings) + else + Break; + end; + $C0, $C1, $F5..$FF: // invalid UTF-8 bytes + Break; + $80..$BF: // trailing bytes are consumed when handling leading bytes, + // any occurence of "orphaned" trailing bytes is invalid UTF-8 + Break; + end; + + if FoundUTF8Strings = MinimumCountOfUTF8Strings then + begin + Result := True; + Break; + end; + + Inc(i); + end; + end; +end; + +function GetEncoding(const FileName: UnicodeString; out WithBOM: Boolean): TSynEncoding; +var + Stream: TStream; +begin + Stream := TWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + Result := GetEncoding(Stream, WithBOM); + finally + Stream.Free; + end; +end; + +function GetEncoding(Stream: TStream; out WithBOM: Boolean): TSynEncoding; +var + BOM: WideChar; + Size: Integer; +begin + // if Stream is nil, let Delphi raise the exception, by accessing Stream, + // to signal an invalid result + + // start analysis at actual Stream.Position + Size := Stream.Size - Stream.Position; + + // if no special characteristics are found it is probably ANSI + Result := seAnsi; + + if IsUTF8(Stream, WithBOM) then + begin + Result := seUTF8; + Exit; + end; + + { try to detect UTF-16 by finding a BOM in UTF-16 format } + + if Size >= 2 then + begin + Stream.ReadBuffer(BOM, sizeof(BOM)); + Stream.Seek(-sizeof(BOM), soFromCurrent); + if BOM = WideChar(UTF16BOMLE) then + begin + Result := seUTF16LE; + WithBOM := True; + Exit; + end + else if BOM = WideChar(UTF16BOMBE) then + begin + Result := seUTF16BE; + WithBOM := True; + Exit; + end + end; +end; + +procedure SaveToFile(const WS: UnicodeString; const FileName: UnicodeString; + Encoding: TSynEncoding; WithBom: Boolean = True); +var + Stream: TStream; +begin + Stream := TWideFileStream.Create(FileName, fmCreate); + try + SaveToStream(WS, Stream, Encoding, WithBom); + finally + Stream.Free; + end; +end; + +procedure SaveToFile(UnicodeStrings: TUnicodeStrings; const FileName: UnicodeString; + Encoding: TSynEncoding; WithBom: Boolean = True); +var + Stream: TStream; +begin + Stream := TWideFileStream.Create(FileName, fmCreate); + try + SaveToStream(UnicodeStrings, Stream, Encoding, WithBom); + finally + Stream.Free; + end; +end; + +function LoadFromFile(UnicodeStrings: TUnicodeStrings; const FileName: UnicodeString; + out WithBOM: Boolean): TSynEncoding; +var + Stream: TStream; +begin + Stream := TWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + Result := LoadFromStream(UnicodeStrings, Stream, WithBOM); + finally + Stream.Free; + end; +end; + +function LoadFromFile(UnicodeStrings: TUnicodeStrings; const FileName: UnicodeString; + Encoding: TSynEncoding; out WithBOM: Boolean): TSynEncoding; +var + Stream: TStream; +begin + Stream := TWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + Result := LoadFromStream(UnicodeStrings, Stream, Encoding, WithBOM); + finally + Stream.Free; + end; +end; + +procedure SaveToStream(const WS: UnicodeString; Stream: TStream; Encoding: TSynEncoding; + WithBom: Boolean = True); +var + UTF16BOM: UnicodeString; + + UTF8Str: UTF8String; + AnsiStr: AnsiString; +begin + if WithBom then + case Encoding of + seUTF8: + Stream.WriteBuffer(UTF8BOM, 3); + seUTF16LE: + begin + UTF16BOM := BOM_LSB_FIRST; + Stream.WriteBuffer(PWideChar(UTF16BOM)^, 2); + end; + seUTF16BE: + begin + UTF16BOM := BOM_MSB_FIRST; + Stream.WriteBuffer(PWideChar(UTF16BOM)^, 2); + end; + end; + + case Encoding of + seUTF8: + begin + UTF8Str := UTF8Encode(WS); + Stream.WriteBuffer(UTF8Str[1], Length(UTF8Str)); + end; + seUTF16LE: + Stream.WriteBuffer(WS[1], Length(WS) * sizeof(WideChar)); + seUTF16BE: + begin + StrSwapByteOrder(PWideChar(WS)); + Stream.WriteBuffer(WS[1], Length(WS) * sizeof(WideChar)); + end; + seAnsi: + begin + AnsiStr := AnsiString(PWideChar(WS)); + Stream.WriteBuffer(AnsiStr[1], Length(AnsiStr)); + end; + end; +end; + +type + TSynEditStringListAccess = class(TSynEditStringList); + +procedure SaveToStream(UnicodeStrings: TUnicodeStrings; Stream: TStream; + Encoding: TSynEncoding; WithBom: Boolean = True); +var + SText: UnicodeString; + SaveFStreaming: Boolean; +begin + // if UnicodeStrings or Stream is nil, let Delphi raise the exception to flag the error + + if UnicodeStrings is TSynEditStringList then + begin + SaveFStreaming := TSynEditStringListAccess(UnicodeStrings).FStreaming; + TSynEditStringListAccess(UnicodeStrings).FStreaming := True; + SText := UnicodeStrings.Text; + TSynEditStringListAccess(UnicodeStrings).FStreaming := SaveFStreaming; + end + else + SText := UnicodeStrings.Text; + SaveToStream(SText, Stream, Encoding, WithBom); +end; + +function LoadFromStream(UnicodeStrings: TUnicodeStrings; Stream: TStream; + out WithBOM: Boolean): TSynEncoding; +var + Dummy: Boolean; +begin + Result := LoadFromStream(UnicodeStrings, Stream, GetEncoding(Stream, WithBOM), + Dummy); +end; + +function LoadFromStream(UnicodeStrings: TUnicodeStrings; Stream: TStream; + Encoding: TSynEncoding): TSynEncoding; overload; +var + Dummy: Boolean; +begin + Result := LoadFromStream(UnicodeStrings, Stream, Encoding, Dummy); +end; + +function LoadFromStream(UnicodeStrings: TUnicodeStrings; Stream: TStream; + Encoding: TSynEncoding; out WithBOM: Boolean): TSynEncoding; +var + WideStr: UnicodeString; + UTF8Str: UTF8String; + AnsiStr: AnsiString; + Size: Integer; + + function SkipBOM: Boolean; + var + BOM: array of Byte; + begin + Result := False; + case Encoding of + seUTF8: + begin + SetLength(BOM, Min(Length(UTF8BOM), Size)); + Stream.ReadBuffer(BOM[0], Length(BOM)); + if (Length(BOM) <> Length(UTF8BOM)) or + not CompareMem(@BOM[0], @UTF8BOM[0], Length(UTF8BOM)) + then + Stream.Seek(-Length(BOM), {$IFDEF SYN_DELPHI_XE4_UP}soCurrent{$ELSE}soFromCurrent{$ENDIF}) + else + Result := True; + end; + seUTF16LE: + begin + SetLength(BOM, Min(Length(UTF16BOMLE), Size)); + Stream.ReadBuffer(BOM[0], Length(BOM)); + if (Length(BOM) <> Length(UTF16BOMLE)) or + not CompareMem(@BOM[0], @UTF16BOMLE[0], Length(UTF16BOMLE)) + then + Stream.Seek(-Length(BOM), {$IFDEF SYN_DELPHI_XE4_UP}soCurrent{$ELSE}soFromCurrent{$ENDIF}) + else + Result := True; + end; + seUTF16BE: + begin + SetLength(BOM, Min(Length(UTF16BOMBE), Size)); + Stream.ReadBuffer(BOM[0], Length(BOM)); + if (Length(BOM) <> Length(UTF16BOMBE)) or + not CompareMem(@BOM[0], @UTF16BOMBE[0], Length(UTF16BOMBE)) + then + Stream.Seek(-Length(BOM), {$IFDEF SYN_DELPHI_XE4_UP}soCurrent{$ELSE}soFromCurrent{$ENDIF}) + else + Result := True; + end; + end; + Size := Stream.Size - Stream.Position; + end; + +begin + // if UnicodeStrings or Stream is nil, let Delphi raise the exception to + // signal an invalid result + UnicodeStrings.BeginUpdate; + try + Result := Encoding; + // start decoding at actual Stream.Position + Size := Stream.Size - Stream.Position; + + // skip BOM, if it exists + WithBOM := SkipBOM; + + case Result of + seUTF8: + begin + SetLength(UTF8Str, Size); + Stream.ReadBuffer(UTF8Str[1], Size); +{$IFDEF UNICODE} + UnicodeStrings.Text := UTF8ToUnicodeString(UTF8Str); +{$ELSE} + UnicodeStrings.Text := UTF8Decode(UTF8Str); + UnicodeStrings.SaveFormat := sfUTF8; +{$ENDIF} + end; + seUTF16LE: + begin + SetLength(WideStr, Size div 2); + Stream.ReadBuffer(WideStr[1], Size); + UnicodeStrings.Text := WideStr; +{$IFNDEF UNICODE} + UnicodeStrings.SaveFormat := sfUTF16LSB; +{$ENDIF} + end; + seUTF16BE: + begin + SetLength(WideStr, Size div 2); + Stream.ReadBuffer(WideStr[1], Size); + StrSwapByteOrder(PWideChar(WideStr)); + UnicodeStrings.Text := WideStr; +{$IFNDEF UNICODE} + UnicodeStrings.SaveFormat := sfUTF16MSB; +{$ENDIF} + end; + seAnsi: + begin + SetLength(AnsiStr, Size); + Stream.ReadBuffer(AnsiStr[1], Size); + UnicodeStrings.Text := UnicodeString(AnsiStr); +{$IFNDEF UNICODE} + UnicodeStrings.SaveFormat := sfAnsi; +{$ENDIF} + end; + end; + finally + UnicodeStrings.EndUpdate + end +end; + +function ClipboardProvidesText: Boolean; +begin + Result := IsClipboardFormatAvailable(CF_TEXT) or IsClipboardFormatAvailable(CF_UNICODETEXT); +end; + +function GetClipboardText: UnicodeString; +var + Mem: HGLOBAL; + LocaleID: LCID; + P: PByte; +begin + Result := ''; + Clipboard.Open; + try + if Clipboard.HasFormat(CF_UNICODETEXT) then + begin + Mem := Clipboard.GetAsHandle(CF_UNICODETEXT); + try + if Mem <> 0 then + Result := PWideChar(GlobalLock(Mem)); + finally + if Mem <> 0 then GlobalUnlock(Mem); + end; + end + else + begin + LocaleID := 0; + Mem := Clipboard.GetAsHandle(CF_LOCALE); + try + if Mem <> 0 then LocaleID := PInteger(GlobalLock(Mem))^; + finally + if Mem <> 0 then GlobalUnlock(Mem); + end; + + Mem := Clipboard.GetAsHandle(CF_TEXT); + try + if Mem <> 0 then + begin + P := GlobalLock(Mem); + Result := StringToUnicodeStringEx(PAnsiChar(P), CodePageFromLocale(LocaleID)); + end + finally + if Mem <> 0 then GlobalUnlock(Mem); + end; + end; + finally + Clipboard.Close; + end; +end; + +procedure SetClipboardText(const Text: UnicodeString); +var + Mem: HGLOBAL; + P: PByte; + SLen: Integer; +begin + if Text = '' then Exit; + SLen := Length(Text); + Clipboard.Open; + try + Clipboard.Clear; + + // set ANSI text only on Win9X, WinNT automatically creates ANSI from Unicode + if Win32Platform <> VER_PLATFORM_WIN32_NT then + begin + Mem := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, SLen + 1); + if Mem <> 0 then + begin + P := GlobalLock(Mem); + try + if P <> nil then + begin + Move(PAnsiChar(AnsiString(Text))^, P^, SLen + 1); + Clipboard.SetAsHandle(CF_TEXT, Mem); + end; + finally + GlobalUnlock(Mem); + end; + end; + end; + + // set unicode text, this also works on Win9X, even if the clipboard-viewer + // can't show it, Word 2000+ can paste it including the unicode only characters + Mem := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, + (SLen + 1) * sizeof(WideChar)); + if Mem <> 0 then + begin + P := GlobalLock(Mem); + try + if P <> nil then + begin + Move(PWideChar(Text)^, P^, (SLen + 1) * sizeof(WideChar)); + Clipboard.SetAsHandle(CF_UNICODETEXT, Mem); + end; + finally + GlobalUnlock(Mem); + end; + end; + // Don't free Mem! It belongs to the clipboard now, and it will free it + // when it is done with it. + finally + Clipboard.Close; + end; +end; + +{$IFNDEF UNICODE} +{$IFNDEF SYN_COMPILER_6_UP} +procedure AssignWideStr(var Dest: UnicodeString; const Source: UnicodeString); +begin + Dest := Source; +end; + +procedure IntGetWideStrProp(Instance: TObject; PropInfo: PPropInfo; + var Value: UnicodeString); assembler; +asm + { -> EAX Pointer to instance } + { EDX Pointer to property info } + { ECX Pointer to result string } + + PUSH ESI + PUSH EDI + MOV EDI,EDX + + MOV EDX,[EDI].TPropInfo.Index { pass index in EDX } + CMP EDX,$80000000 + JNE @@hasIndex + MOV EDX,ECX { pass value in EDX } +@@hasIndex: + MOV ESI,[EDI].TPropInfo.GetProc + CMP [EDI].TPropInfo.GetProc.Byte[3],$FE + JA @@isField + JB @@isStaticMethod + +@@isVirtualMethod: + MOVSX ESI,SI { sign extend slot offset } + ADD ESI,[EAX] { vmt + slot offset } + CALL DWORD PTR [ESI] + JMP @@exit + +@@isStaticMethod: + CALL ESI + JMP @@exit + +@@isField: + AND ESI,$00FFFFFF + MOV EDX,[EAX+ESI] + MOV EAX,ECX + CALL AssignWideStr + +@@exit: + POP EDI + POP ESI +end; + +function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString; +begin + IntGetWideStrProp(Instance, PropInfo, Result); +end; + +procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; + const Value: UnicodeString); assembler; +asm + { -> EAX Pointer to instance } + { EDX Pointer to property info } + { ECX Pointer to string value } + + PUSH ESI + PUSH EDI + MOV ESI,EDX + + MOV EDX,[ESI].TPropInfo.Index { pass index in EDX } + CMP EDX,$80000000 + JNE @@hasIndex + MOV EDX,ECX { pass value in EDX } +@@hasIndex: + MOV EDI,[ESI].TPropInfo.SetProc + CMP [ESI].TPropInfo.SetProc.Byte[3],$FE + JA @@isField + JB @@isStaticMethod + +@@isVirtualMethod: + MOVSX EDI,DI + ADD EDI,[EAX] + CALL DWORD PTR [EDI] + JMP @@exit + +@@isStaticMethod: + CALL EDI + JMP @@exit + +@@isField: + AND EDI,$00FFFFFF + ADD EAX,EDI + MOV EDX,ECX + CALL AssignWideStr + +@@exit: + POP EDI + POP ESI +end; +{$ENDIF} + +type + TUnicodeStringPropertyFiler = class + private + FInstance: TPersistent; + FPropInfo: PPropInfo; + procedure ReadData(Reader: TReader); + procedure WriteData(Writer: TWriter); + public + procedure DefineProperties(Filer: TFiler; Instance: TPersistent; PropName: AnsiString); + end; + + TWideCharPropertyFiler = class + private + FInstance: TPersistent; + FPropInfo: PPropInfo; + FWriter: TWriter; + procedure GetLookupInfo(var Ancestor: TPersistent; + var Root, LookupRoot, RootAncestor: TComponent); + procedure ReadData(Reader: TReader); + procedure WriteData(Writer: TWriter); + function ReadChar(Reader: TReader): WideChar; + public + procedure DefineProperties(Filer: TFiler; Instance: TPersistent; PropName: AnsiString); + end; + +type + TGetLookupInfoEvent = procedure(var Ancestor: TPersistent; + var Root, LookupRoot, RootAncestor: TComponent) of object; + +function AncestorIsValid(Ancestor: TPersistent; Root, RootAncestor: TComponent): Boolean; +begin + Result := (Ancestor <> nil) and (RootAncestor <> nil) and + Root.InheritsFrom(RootAncestor.ClassType); +end; + +function IsDefaultOrdPropertyValue(Instance: TObject; PropInfo: PPropInfo; + OnGetLookupInfo: TGetLookupInfoEvent): Boolean; +var + Ancestor: TPersistent; + LookupRoot: TComponent; + RootAncestor: TComponent; + Root: TComponent; + AncestorValid: Boolean; + Value: Longint; + Default: LongInt; +begin + Ancestor := nil; + Root := nil; + LookupRoot := nil; + RootAncestor := nil; + + if Assigned(OnGetLookupInfo) then + OnGetLookupInfo(Ancestor, Root, LookupRoot, RootAncestor); + + AncestorValid := AncestorIsValid(Ancestor, Root, RootAncestor); + + Result := True; + if (PropInfo^.GetProc <> nil) and (PropInfo^.SetProc <> nil) then + begin + Value := GetOrdProp(Instance, PropInfo); + if AncestorValid then + Result := Value = GetOrdProp(Ancestor, PropInfo) + else + begin + Default := PPropInfo(PropInfo)^.Default; + Result := (Default <> LongInt($80000000)) and (Value = Default); + end; + end; +end; + +procedure ReadError(S: string); +begin + raise EReadError.Create(S); +end; + +procedure PropValueError; +begin + ReadError(SInvalidPropertyValue); +end; + +{ TUnicodeStringPropertyFiler } + +procedure TUnicodeStringPropertyFiler.DefineProperties(Filer: TFiler; Instance: TPersistent; + PropName: AnsiString); + + function HasData: Boolean; + var + CurrPropValue: UnicodeString; + begin + // must be stored + Result := IsStoredProp(Instance, FPropInfo); + if Result + and (Filer.Ancestor <> nil) + and (GetPropInfo(Filer.Ancestor, PropName, [tkWString]) <> nil) then + begin + // must be different than ancestor + CurrPropValue := GetWideStrProp(Instance, FPropInfo); + Result := CurrPropValue <> GetWideStrProp(Filer.Ancestor, GetPropInfo(Filer.Ancestor, PropName)); + end; + if Result then + Result := GetWideStrProp(Instance, FPropInfo) <> ''; + end; + +begin + FInstance := Instance; + FPropInfo := GetPropInfo(Instance, PropName, [tkWString]); + if FPropInfo <> nil then + // must be published (and of type UnicodeString) + Filer.DefineProperty(PropName + 'W', ReadData, WriteData, HasData); + FInstance := nil; + FPropInfo := nil; +end; + +procedure TUnicodeStringPropertyFiler.ReadData(Reader: TReader); +begin + case Reader.NextValue of + vaLString, vaString: + SetWideStrProp(FInstance, FPropInfo, Reader.ReadString); + else + SetWideStrProp(FInstance, FPropInfo, Reader.ReadWideString); + end; +end; + +procedure TUnicodeStringPropertyFiler.WriteData(Writer: TWriter); +begin + Writer.WriteWideString(GetWideStrProp(FInstance, FPropInfo)); +end; + +{ TWideCharPropertyFiler } + +procedure TWideCharPropertyFiler.GetLookupInfo(var Ancestor: TPersistent; + var Root, LookupRoot, RootAncestor: TComponent); +begin + Ancestor := FWriter.Ancestor; + Root := FWriter.Root; + LookupRoot := FWriter.LookupRoot; + RootAncestor := FWriter.RootAncestor; +end; + +function TWideCharPropertyFiler.ReadChar(Reader: TReader): WideChar; +var + Temp: UnicodeString; +begin + case Reader.NextValue of + vaWString: + Temp := Reader.ReadWideString; + vaString: + Temp := Reader.ReadString; + else + PropValueError; + end; + + if Length(Temp) > 1 then + PropValueError; + Result := Temp[1]; +end; + +procedure TWideCharPropertyFiler.ReadData(Reader: TReader); +begin + SetOrdProp(FInstance, FPropInfo, Ord(ReadChar(Reader))); +end; + +type + TAccessWriter = class(TWriter) + end; + +procedure TWideCharPropertyFiler.WriteData(Writer: TWriter); +var + L: Integer; + Temp: UnicodeString; +begin + Temp := WideChar(GetOrdProp(FInstance, FPropInfo)); + + TAccessWriter(Writer).WriteValue(vaWString); + L := Length(Temp); + Writer.Write(L, SizeOf(Integer)); + Writer.Write(Pointer(@Temp[1])^, L * 2); +end; + +procedure TWideCharPropertyFiler.DefineProperties(Filer: TFiler; + Instance: TPersistent; PropName: AnsiString); + + function HasData: Boolean; + var + CurrPropValue: Integer; + begin + // must be stored + Result := IsStoredProp(Instance, FPropInfo); + if Result and (Filer.Ancestor <> nil) and + (GetPropInfo(Filer.Ancestor, PropName, [tkWChar]) <> nil) then + begin + // must be different than ancestor + CurrPropValue := GetOrdProp(Instance, FPropInfo); + Result := CurrPropValue <> GetOrdProp(Filer.Ancestor, GetPropInfo(Filer.Ancestor, PropName)); + end; + + if Result and (Filer is TWriter) then + begin + FWriter := TWriter(Filer); + Result := not IsDefaultOrdPropertyValue(Instance, FPropInfo, GetLookupInfo); + end; + end; + +begin + FInstance := Instance; + FPropInfo := GetPropInfo(Instance, PropName, [tkWChar]); + if FPropInfo <> nil then // must be published (and of type WideChar) + begin + // W suffix causes Delphi's native streaming system to ignore the property + // and let us do the reading. + Filer.DefineProperty(PropName + 'W', ReadData, WriteData, HasData); + end; + FInstance := nil; + FPropInfo := nil; +end; + +procedure UnicodeDefineProperties(Filer: TFiler; Instance: TPersistent); +var + I, Count: Integer; + PropInfo: PPropInfo; + PropList: PPropList; + UnicodeStringFiler: TUnicodeStringPropertyFiler; + WideCharFiler: TWideCharPropertyFiler; +begin + Count := GetTypeData(Instance.ClassInfo)^.PropCount; + if Count > 0 then + begin + UnicodeStringFiler := TUnicodeStringPropertyFiler.Create; + try + WideCharFiler := TWideCharPropertyFiler.Create; + try + GetMem(PropList, Count * SizeOf(Pointer)); + try + GetPropInfos(Instance.ClassInfo, PropList); + for I := 0 to Count - 1 do + begin + PropInfo := PropList^[I]; + if (PropInfo = nil) then + Break; + if (PropInfo.PropType^.Kind = tkWString) then + UnicodeStringFiler.DefineProperties(Filer, Instance, PropInfo.Name) + else if (PropInfo.PropType^.Kind = tkWChar) then + WideCharFiler.DefineProperties(Filer, Instance, PropInfo.Name) + end; + finally + FreeMem(PropList, Count * SizeOf(Pointer)); + end; + finally + WideCharFiler.Free; + end; + finally + UnicodeStringFiler.Free; + end; + end; +end; +{$ENDIF} + +{$IFDEF MSWINDOWS} +function IsWideCharMappableToAnsi(const WC: WideChar): Boolean; +var + UsedDefaultChar: BOOL; +begin + WideCharToMultiByte(DefaultSystemCodePage, 0, PWideChar(@WC), 1, nil, 0, nil, + @UsedDefaultChar); + Result := not UsedDefaultChar; +end; + +function IsUnicodeStringMappableToAnsi(const WS: UnicodeString): Boolean; +var + UsedDefaultChar: BOOL; +begin + WideCharToMultiByte(DefaultSystemCodePage, 0, PWideChar(WS), Length(WS), nil, 0, + nil, @UsedDefaultChar); + Result := not UsedDefaultChar; +end; +{$ENDIF} + +initialization +{$IFDEF MSWINDOWS} + Win32PlatformIsUnicode := (Win32Platform = VER_PLATFORM_WIN32_NT); + {$IFNDEF UNICODE} + DefaultSystemCodePage := GetACP; + {$ENDIF} +{$ENDIF} + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynUsp10.pas b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynUsp10.pas new file mode 100644 index 000000000..e857266a6 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/PrivateSynEdit/uRESTDWPrivSynUsp10.pas @@ -0,0 +1,2631 @@ +{******************************************************************************} +{* *} +{* Copyright (c) Microsoft Corporation. All rights reserved. *} +{* *} +{* File: usp10.h *} +{* Content: USP - Unicode Complex Script processor *} +{* *} +{* Delphi / FreePascal adaptation by Alexey Barkovoy (clootie@clootie.ru) *} +(* *) +{* The original version from Alexey Barkovoy can be downloaded from: *} +{* http://clootie.ru *} +(* *) +(* Dynamic linking logic (similar to what the JCL does) by Mal Hrz. *) +(* *) +(* Latest version can be downloaded from http://mh-nexus.de/unisynedit.htm *) +(* or checked out from the Unicode branch of uRESTDWPrivSynEdit CVS. *) +(* *) +{******************************************************************************} +{ } +{ The contents of this file are used with permission, subject to the Mozilla } +{ Public License Version 1.1 (the "License"); you may not use this file except } +{ in compliance with the License. You may obtain a copy of the License at } +{ http://www.mozilla.org/MPL/MPL-1.1.html } +{ } +{ Software distributed under the License is distributed on an "AS IS" basis, } +{ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for } +{ the specific language governing rights and limitations under the License. } +{ } +{ Alternatively, the contents of this file may be used under the terms of the } +{ GNU Lesser General Public License (the "LGPL License"), in which case the } +{ provisions of the LGPL License are applicable instead of those above. } +{ If you wish to allow use of your version of this file only under the terms } +{ of the LGPL License and not to allow others to use your version of this file } +{ under the MPL, indicate your decision by deleting the provisions above and } +{ replace them with the notice and other provisions required by the LGPL } +{ License. If you do not delete the provisions above, a recipient may use } +{ your version of this file under either the MPL or the LGPL License. } +{ } +{ For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html } +{ } +{******************************************************************************} + +// $Id: uRESTDWPrivSynUsp10.pas,v 1.1.2.2 2008/09/17 13:59:12 maelh Exp $ + +{$IFDEF FPC} +{$mode objfpc} +{$ENDIF} + +// necessary for dynamic linking +{$STACKFRAMES ON} +{$WARNINGS OFF} + +unit uRESTDWPrivSynUsp10; + +interface + +uses + Windows; + +const + ///// Uniscribe build number + USPBUILD = 0400; + + + + ///// USP - Unicode Complex Script processor + // + // Copyright (c) Microsoft Corporation. All rights reserved. + + + + + ///// SCRIPT + // + // The SCRIPT enum is an opaque type used internally to identify + // which shaping engine functions are used to process a given run. + // + // + SCRIPT_UNDEFINED = 0; + // + //p SCRIPT_UNDEFINED: This is the only public script ordinal. May be + // forced into the eScript field of a SCRIPT_ANALYSIS to disable shaping. + // SCRIPT_UNDEFINED is supported by all fonts - ScriptShape will display + // whatever glyph is defined in the font CMAP table, or, if none, the + // missing glyph. + + + + ///// USP Status Codes + // + USP_E_SCRIPT_NOT_IN_FONT = DWord((SEVERITY_ERROR shl 31) or + (FACILITY_ITF shl 16)) or $200; // MAKE_HRESULT(SEVERITY_ERROR,FACILITY_ITF,0x200) // Script doesn't exist in font + + + + + + + ///// SCRIPT_CACHE + // + // Many script APIs take a combination of HDC and SCRIPT_CACHE parameter. + // + // A SCRIPT_CACHE is an opaque pointer to a Uniscribe font metric cache + // structure. + +type + SCRIPT_CACHE = Pointer; + {$EXTERNALSYM SCRIPT_CACHE} + TScriptCache = SCRIPT_CACHE; + PScriptCache = ^TScriptCache; + + +// The client must allocate and retain one SCRIPT_CACHE variable for each +// character style used. It must be initialised by the client to NULL. +// +// APIs are passed an HDC and the address of a SCRIPT_CACHE variable. +// Uniscribe will first attempt to access font data via the SCRIPT_CACHE +// and will only inspect the HDC if the required data is not already +// cached. +// +// The HDC may be passed as NULL. If data required by Uniscribe is +// already cached, the HDC won't be accessed and operation continues +// normally. +// +// If the HDC is passed as NULL, and Uniscribe needs to access it for +// any reason, Uniscribe will return E_PENDING. +// +// E_PENDING is returned quickly, allowing the client to avoid time +// consuming SelectObject calls. The following example applies to all +// APIs that take a SCRIPT_CACHE and an optional HDC. +// +//c hr = ScriptShape(NULL, &sc, ..); +//c if (hr == E_PENDING) { +//c ... select font into hdc ... +//c hr = ScriptShape(hdc, &sc, ...); +//c } + + + + +///// ScriptFreeCache +// +// The client may free a SCRIPT_CACHE at any time. Uniscribe maintains +// reference counts in it's font and shaper caches, and frees font data +// only when all sizes of the font are free, and shaper data only when +// all fonts it supports are freed. +// +// The client should free the SCRIPT_CACHE for a style when it discards +// that style. +// +// ScriptFreeCache always sets it's parameter to NULL to help avoid +// mis-referencing. + + +function ScriptFreeCache( + psc: PScriptCache //InOut Cache handle + ): HRESULT; stdcall; + + +type + ///// SCRIPT_CONTROL + // + // The SCRIPT_CONTROL structure provides itemization control flags to the + // ScriptItemize function. + // + // + + TScriptControlFlag = ( + scContextDigits, // Means use previous script instead of uDefaultLanguage + // The following flags provide legacy support for GetCharacterPlacement features + scInvertPreBoundDir, // Reading order of virtual item immediately prior to string + scInvertPostBoundDir, // Reading order of virtual item immediately following string + scLinkStringBefore, // Equivalent to presence of ZWJ before string + scLinkStringAfter, // Equivalent to presence of ZWJ after string + scNeutralOverride, // Causes all neutrals to be strong in the current embedding direction + scNumericOverride, // Causes all numerals to be strong in the current embedding direction + scLegacyBidiClass // Causes plus and minus to be reated as neutrals, slash as a common separator + ); + TScriptControlFlags = set of TScriptControlFlag; + + PScriptControl = ^TScriptControl; + tag_SCRIPT_CONTROL = packed record + uDefaultLanguage: Word; // For NADS, also default for context + fFlags: TScriptControlFlags; + fReserved: Byte; + end; +(* uDefaultLanguage: DWORD {:16}; // For NADS, also default for context + fContextDigits: DWORD {:1}; // Means use previous script instead of uDefaultLanguage + + // The following flags provide legacy support for GetCharacterPlacement features + fInvertPreBoundDir: DWORD {:1}; // Reading order of virtual item immediately prior to string + fInvertPostBoundDir: DWORD {:1}; // Reading order of virtual item immediately following string + fLinkStringBefore: DWORD {:1}; // Equivalent to presence of ZWJ before string + fLinkStringAfter: DWORD {:1}; // Equivalent to presence of ZWJ after string + fNeutralOverride: DWORD {:1}; // Causes all neutrals to be strong in the current embedding direction + fNumericOverride: DWORD {:1}; // Causes all numerals to be strong in the current embedding direction + fLegacyBidiClass: DWORD {:1}; // Causes plus and minus to be reated as neutrals, slash as a common separator + fReserved: DWORD {:8}; + end; *) + {$EXTERNALSYM tag_SCRIPT_CONTROL} + SCRIPT_CONTROL = tag_SCRIPT_CONTROL; + {$EXTERNALSYM SCRIPT_CONTROL} + TScriptControl = tag_SCRIPT_CONTROL; + +// +// +//p uDefaultLanguage: Language to use when Unicode values are ambiguous. +// Used by numeric processing to select digit shape when +// ssDigitSubstitute (see SCRIPT_STATE) is in force. +// +//p scContextDigits: Specifies that national digits are chosen according to +// the nearest previous strong text, rather than using +// uDefaultLanguage. +// +//p scInvertPreBoundDir: By default text at the start of the string is +// laid out as if it follows strong text of the same direction +// as the base embedding level. Set scInvertPreBoundDir to change +// the initial context to the opposite of the base embedding +// level. This flag is for GetCharacterPlacement legacy support. +// +//p scInvertPostBoundDir: By default text at the end of the string is +// laid out as if it preceeds strong text of the same direction +// as the base embedding level. Set scInvertPostBoundDir to change +// the final context to the opposite of the base embedding +// level. This flag is for GetCharacterPlacement legacy support. +// +//p scLinkStringBefore: Causes the first character of the string to be +// shaped as if were joined to a previous character. +// +//p scLinkStringAfter: Causes the last character of the string to be +// shaped as if were joined to a following character. +// +//p scNeutralOverride: Causes all neutral characters in the string to be +// treated as if they were strong characters of their enclosing +// embedding level. This effectively locks neutrals in place, +// reordering occuring only between neutrals. +// +//p scNumericOverride: Causes all numeric characters in the string to be +// treated as if they were strong characters of their enclosing +// embedding level. This effectively locks numerics in place, +// reordering occuring only between numerics. +// +//p fReserved: Reserved. Always initialise to 0. + + + + ///// SCRIPT_STATE + // + // The SCRIPT_STATE structure is used both to initialise the unicode + // algorithm state as an input parameter to ScriptItemize, and is also + // a component of each item analysis returned by ScriptItemize. + // + // + TScriptStateFlag = ( + uBidiLevel_reserved1, uBidiLevel_r2, uBidiLevel_r3, uBidiLevel_r4, uBidiLevel_r5, + ssOverrideDirection, // Set when in LRO/RLO embedding + ssInhibitSymSwap, // Set by U+206A (ISS), cleared by U+206B (ASS) + ssCharShape, // Set by U+206D (AAFS), cleared by U+206C (IAFS) + ssDigitSubstitute, // Set by U+206E (NADS), cleared by U+206F (NODS) + ssInhibitLigate, // Equiv !GCP_Ligate, no Unicode control chars yet + ssDisplayZWG, // Equiv GCP_DisplayZWG, no Unicode control characters yet + ssArabicNumContext, // For EN->AN Unicode rule + ssGcpClusters // For Generating Backward Compatible GCP Clusters (legacy Apps) + ); + TScriptStateFlags = set of TScriptStateFlag; + + PScriptState = ^TScriptState; + tag_SCRIPT_STATE = packed record + case Byte of + 0: (uBidiLevel: Byte) {:5}; // Unicode Bidi algorithm embedding level (0-16) + 1: (fFlags: TScriptStateFlags) + end; +(* uBidiLevel: Word {:5}; // Unicode Bidi algorithm embedding level (0-16) + fOverrideDirection: Word {:1}; // Set when in LRO/RLO embedding + fInhibitSymSwap: Word {:1}; // Set by U+206A (ISS), cleared by U+206B (ASS) + fCharShape: Word {:1}; // Set by U+206D (AAFS), cleared by U+206C (IAFS) + fDigitSubstitute: Word {:1}; // Set by U+206E (NADS), cleared by U+206F (NODS) + fInhibitLigate: Word {:1}; // Equiv !GCP_Ligate, no Unicode control chars yet + fDisplayZWG: Word {:1}; // Equiv GCP_DisplayZWG, no Unicode control characters yet + fArabicNumContext: Word {:1}; // For EN->AN Unicode rule + fcpClusters: Word {:1}; // For Generating Backward Compatible GCP Clusters (legacy Apps) + fReserved: Word {:1}; + fEngineReserved: Word {:2}; // For use by shaping engine + end; *) + {$EXTERNALSYM tag_SCRIPT_STATE} + SCRIPT_STATE = tag_SCRIPT_STATE; + {$EXTERNALSYM SCRIPT_STATE} + TScriptState = tag_SCRIPT_STATE; + +const + MASK_uBidiLevel = $1F; // Mask to apply to TScriptState.uBidiLevel +type + +// +// +//p uBidiLevel: The embedding level associated with all characters in this +// run according to the Unicode bidi algorithm. When passed to +// ScriptItemize, should be initialised to 0 for an LTR base +// embedding level, or 1 for RTL. +// +//p ssOverrideDirection: TRUE if this level is an override level (LRO/RLO). +// In an override level, characters are layed out purely +// left to right, or purely right to left. No reordering of digits +// or strong characters of opposing direction takes place. +// Note that this initial value is reset by LRE, RLE, LRO or +// RLO codes in the string. +// +//p ssInhibitSymSwap: TRUE if the shaping engine is to bypass mirroring of +// Unicode Mirrored glyphs such as brackets. Set by Unicode +// character ISS, cleared by ASS. +// +//p ssCharShape: TRUE if character codes in the Arabic Presentation Forms +// areas of Unicode should be shaped. (Not implemented). +// +//p ssDigitSubstitute: TRUE if character codes U+0030 through U+0039 +// (European digits) are to be substituted by national digits. +// Set by Unicode NADS, Cleared by NODS. +// +//p ssInhibitLigate: TRUE if ligatures are not to be used in the shaping +// of Arabic or Hebrew characters. +// +//p ssDisplayZWG: TRUE if control characters are to be shaped as +// representational glyphs. (Normally, control characters are +// shaped to the blank glyph and given a width of zero). +// +//p ssArabicNumContext: TRUE indicates prior strong characters were Arabic +// for the purposes of rule P0 on page 3-19 of 'The Unicode +// Standard, version 2.0'. Should normally be set TRUE before +// itemizing an RTL paragraph in an Arabic language, FALSE +// otherwise. +// +//p ssGcpClusters: For GetCharaterPlacement legacy support only. +// Initialise to TRUE to request ScriptShape to generate +// the LogClust array the same way as GetCharacterPlacement +// does in Arabic and Hebrew Windows95. Affects only Arabic +// and Hebrew items. +// +//p fReserved: Reserved. Always initialise to 0. +// +//p fEngineReserved: Reserved. Always initialise to 0. + + + + + + + ///// SCRIPT_ANALYSIS + // + // Each analysed item is described by a SCRIPT_ANALYSIS structure. + // It also includes a copy of the Unicode algorithm state (SCRIPT_STATE). + // + // + TScriptAnalysis_enum = ( + eScript_r1, eScript_r2, eScript_r3, eScript_r4, eScript_r5, // first 10 bits + eScript_r6, eScript_r7, eScript_r8, eScript_r9, eScript_r10, // are reserved + fRTL, // Rendering direction + fLayoutRTL, // Set for GCP classes ARABIC/HEBREW and LOCALNUMBER + fLinkBefore, // Implies there was a ZWJ before this item + fLinkAfter, // Implies there is a ZWJ following this item. + fLogicalOrder, // Set by client as input to ScriptShape/Place + fNoGlyphIndex // Generated by ScriptShape/Place - this item does not use glyph indices + ); + TScriptAnalysis_set = set of TScriptAnalysis_enum; + + PScriptAnalysis = ^TScriptAnalysis; + tag_SCRIPT_ANALYSIS = packed record + case Byte of + 0: (eScript: Word) {:10}; // Shaping engine + 1: (fFlags: TScriptAnalysis_set; + s: TScriptState) + end; +(* eScript: Word {:10}; // Shaping engine + fRTL: Word {:1}; // Rendering direction + fLayoutRTL: Word {:1}; // Set for GCP classes ARABIC/HEBREW and LOCALNUMBER + fLinkBefore: Word {:1}; // Implies there was a ZWJ before this item + fLinkAfter: Word {:1}; // Implies there is a ZWJ following this item. + fLogicalOrder: Word {:1}; // Set by client as input to ScriptShape/Place + fNoGlyphIndex: Word {:1}; // Generated by ScriptShape/Place - this item does not use glyph indices + s: TScriptState; + end; *) + {$EXTERNALSYM tag_SCRIPT_ANALYSIS} + SCRIPT_ANALYSIS = tag_SCRIPT_ANALYSIS; + {$EXTERNALSYM SCRIPT_ANALYSIS} + TScriptAnalysis = tag_SCRIPT_ANALYSIS; + +const + MASK_eScript = $3FF; // Mask to apply to TScriptAnalysis.eScript +type + +// +// +//p eScript: Opaque value identifying which engine Uniscribe will use to +// Shape, Place and TextOut this item. The value of eScript is +// undefined, and will change in future releases, but attributes +// of eScript may be obtained by calling ScriptGetProperties. +// +//p fRTL: Rendering direction. Normally identical to the parity of the +// Unicode embedding level, but may differ if overridden by +// GetCharacterPlacement legacy support. +// +//p fLayoutRTL: Logical direction - whether conceptually part of a +// left-to-right sequenece or a right-to-left sequence. Although +// this is usually the same as fRTL, for a number in a +// right-to-left run, fRTL is False (because digits are always +// displayed LTR), but fLayoutRTL is True (because the number is +// read as part of the right-to-left sequence). +// +//p fLinkBefore: If set, the shaping engine will shape the first character +// of this item as if it were joining with a previous character. +// Set by ScriptItemize, may be overriden before calling ScriptShape. +// +//p fLinkAfter: If set, the shaping engine will shape the last character +// of this item as if it were joining with a subsequient character. +// Set by ScriptItemize, may be overriden before calling ScriptShape. +// +//p fLogicalOrder: If set, the shaping engine will generate all glyph +// related arrays in logical order. By default glyph related +// arrays are in visual order, the first array entry corresponding +// to the leftmost glyph. +// Set to FALSE by ScriptItemize, may be overriden before calling +// ScriptShape. +// +//p fNoGlyphIndex: May be set TRUE on input to ScriptShape to disable use +// of glyphs for this item. Additionally, ScriptShape will set it +// TRUE for hdcs containing symbolic, unrecognised and device fonts. +// Disabling glyphing disables complex script shaping. When set, +// shaping and placing for this item is implemented directly by +// calls to GetTextExtentExPoint and ExtTextOut. +///// SCRIPT_ITEM +// +// The SCRIPT_ITEM structure includes a SCRIPT_ANALYSIS with the string +// ofset of the first character of the item. +// +// + + PScriptItem = ^TScriptItem; + tag_SCRIPT_ITEM = record + iCharPos: Integer; // Logical offset to first character in this item + a: TScriptAnalysis; + end; + {$EXTERNALSYM tag_SCRIPT_ITEM} + SCRIPT_ITEM = tag_SCRIPT_ITEM; + {$EXTERNALSYM SCRIPT_ITEM} + TScriptItem = SCRIPT_ITEM; + +// +// +//p iCharPos: Offset from beginning of itemised string to first character +// of this item, counted in Unicode codepoints (i.e. words). +// +//p a: Script analysis structure containing analysis specific to this +// item, to be passed to ScriptShape, ScriptPlace etc. + + + +///// ScriptItemize - break text into items +// +// Breaks a run of unicode into individually shapeable items. +// Items are delimited by +// +// o Change of shaping engine +// o Change of direction +// +// The client may create multiple runs from each item returned by +// ScriptItemize, but should not combine multiple items into a single run. +// +// Later the client will call ScriptShape for each run (when measuring or +// rendering), and must pass the SCRIPT_ANALYSIS that ScriptItemize +// returned. + + +function ScriptItemize( + const pwcInChars: PWideChar; // In Unicode string to be itemized + cInChars: Integer; // In Codepoint count to itemize + cMaxItems: Integer; // In Max length of itemization array + const psControl: PScriptControl; // In Analysis control (optional) + const psState: PScriptState; // In Initial bidi algorithm state (optional) + pItems: PScriptItem; // Out Array to receive itemization + pcItems: PInteger // Out Count of items processed (optional) + ): HRESULT; stdcall; +{$EXTERNALSYM ScriptItemize} + + + +///// +// +// +// Returns E_INVALIDARG if pwcInChars == NULL or cInChars == 0 +// or pItems == NULL or cMaxItems < 2. +// +// Returns E_OUTOFMEMORY if the output buffer length (cMaxItems) is +// insufficient. Note that in this case, as in all error cases, no +// items have been fully processed so no part of the output array +// contains defined values. +// +// If psControl and psState are NULL on entry, ScriptItemize +// breaks the unicode string purely by character code. If they are all +// non-null, it performs a full Unicode bidi analysis. +// +// ScriptItemize always adds a terminal item to the item analysis array +// (pItems) such that the length of an item at pItem is always available as: +// +//c pItem[1].iCharPos - pItem[0].iCharPos +// +// For this reason, it is invalid to call ScriptItemize with a buffer +// of less than two SCRIPT_ANALYSIS items. +// +// To perform a correct Unicode Bidi analysis, the SCRIPT_STATE should +// be initialised according to the paragraph reading order at paragraph +// start, and ScriptItemize should be passed the whole paragraph. +// +// fRTL and fNumeric together provide the same classification as +// the lpClass output from GetCharacterPlacement. +// +// European digits U+0030 through U+0039 may be rendered as national +// digits as follows: +// +//t ssDigitSubstitute | scContextDigits | Digit shapes displayed for Unicode U+0030 through U+0039 +//t ---------------- | -------------- | ------------------------------------ +//t False | Any | Western (European / American) digits +//t True | False | As specified in SCRIPT_CONTROL.uDefaultLanguage +//t True | True | As prior strong text, defaulting to SCRIPT_CONTROL.uDefaultLanguage +// +// +// For scContextDigits, any Western digits (U+0030 - U+0039) encountered +// before the first strongly directed character are substituted by the +// traditional digits of the SCRIPT_CONTROL.uDefaultLanguage when that +// language is written in the same direction as SCRIPT_STATE.uBidiLevel. +// +// Thus, in a right-to-left string, if SCRIPT_CONTROL.uDefaultLanguage is +// 1 (LANG_ARABIC), then leading Western digits will be substituted by +// traditional Arabic digits. +// +// However, also in a right-to-left string, if SCRIPT_CONTROL.uDefaultLanguage +// is 0x1e (LANG_THAI), then no substitution occurs on leading Western +// digits because the Thai language is written left-to-right. +// +// Following strongly directed characters, digits are substituted +// by the traditional digits associated with the closest prior strongly +// directed character. +// +// The left-to-right mark (LRM) and right-to-left mark (RLM) are strong +// characters whose language depends on the SCRIPT_CONTROL.uDefaultLangauge. +// +// If SCRIPT_CONTROL.uDefaultLangauge is a left-to-right langauge, then +// LRM causes subsequent Western digits to be substituted by the +// traditional digits associated with that language, while Western +// digits following RLM are not substituted. +// +// Conversly, if SCRIPT_CONTROL.uDefaultLangauge is a right-to-left +// langauge, then Western digits following LRM are not substituted, while +// Western digits following RLM are substituted by the traditional digits +// associated with that language. +// +// +// +// Effect of Unicode control characters on SCRIPT_STATE: +// +//t SCRIPT_STATE flag | Set by | Cleared by +//t ----------------- | ------ ---------- +//t ssDigitSubstitute | NADS | NODS +//t ssInhibitSymSwap | ISS | ASS +//t ssCharShape | AAFS | IAFS +// +// SCRIPT_STATE.ssArabicNumContext controls the Unicode EN->AN rule. +// It should normally be initialised to TRUE +// before itemizing an RTL paragraph in an Arabic language, FALSE +// otherwise. +///// ScriptLayout +// +// The ScriptLayout function converts an array of run embedding levels to +// a map of visual to logical position, and/or logical to visual position. +// +// pbLevel must contain the embedding levels for all runs on the line, +// ordered logically. +// +// On output, piVisualToLogical[0] is the logical index of the run to +// display at the far left. Subsequent entries should be displayed +// progressing from left to right. +// +// piLogicalToVisual[0] is the relative visual position where the first +// logical run should be displayed - the leftmost display position being zero. +// +// The caller may request either piLogicalToVisual or piVisualToLogical +// or both. +// +// Note: No other input is required since the embedding levels give all +// necessary information for layout. + + +function ScriptLayout( + cRuns: Integer; // In Number of runs to process + const pbLevel: PByte; // In Array of run embedding levels + piVisualToLogical: PInteger; // Out List of run indices in visual order + piLogicalToVisual: PInteger // Out List of visual run positions + ): HRESULT; stdcall; +{$EXTERNALSYM ScriptLayout} + + + + + +type + + ///// SCRIPT_JUSTIFY + // + // The script justification enumeration provides the client with the + // glyph characteristic information it needs to implement justification. + + PScriptJustify = ^TScriptJustify; + tag_SCRIPT_JUSTIFY = ( + SCRIPT_JUSTIFY_NONE {= 0}, // Justification can't be applied at this glyph + SCRIPT_JUSTIFY_ARABIC_BLANK {= 1}, // This glyph represents a blank in an Arabic run + SCRIPT_JUSTIFY_CHARACTER {= 2}, // Inter-character justification point follows this glyph + SCRIPT_JUSTIFY_RESERVED1 {= 3}, // Reserved #1 + SCRIPT_JUSTIFY_BLANK {= 4}, // This glyph represents a blank outside an Arabic run + SCRIPT_JUSTIFY_RESERVED2 {= 5}, // Reserved #2 + SCRIPT_JUSTIFY_RESERVED3 {= 6}, // Reserved #3 + SCRIPT_JUSTIFY_ARABIC_NORMAL {= 7}, // Normal Middle-Of-Word glyph that connects to the right (begin) + SCRIPT_JUSTIFY_ARABIC_KASHIDA {= 8}, // Kashida(U+640) in middle of word + SCRIPT_JUSTIFY_ARABIC_ALEF {= 9}, // Final form of Alef-like (U+627, U+625, U+623, U+632) + SCRIPT_JUSTIFY_ARABIC_HA {= 10}, // Final form of Ha (U+647) + SCRIPT_JUSTIFY_ARABIC_RA {= 11}, // Final form of Ra (U+631) + SCRIPT_JUSTIFY_ARABIC_BA {= 12}, // Middle-Of-Word form of Ba (U+628) + SCRIPT_JUSTIFY_ARABIC_BARA {= 13}, // Ligature of alike (U+628,U+631) + SCRIPT_JUSTIFY_ARABIC_SEEN {= 14}, // Highest priority: Initial shape of Seen(U+633) (end) + SCRIPT_JUSTIFY_RESERVED4 {= 15} // Reserved #4 + ); + SCRIPT_JUSTIFY = tag_SCRIPT_JUSTIFY; + {$EXTERNALSYM SCRIPT_JUSTIFY} + TScriptJustify = SCRIPT_JUSTIFY; + + + + ///// SCRIPT_VISATTR + // + // The visual (glyph) attribute buffer generated by ScriptShape + // identifies clusters and justification points: + + TScriptVisAttr_enum = ( + uJustification_r1, uJustification_r2, uJustification_r3, uJustification_r4, + fClusterStart, {:1} // First glyph of representation of cluster + fDiacritic, {:1} // Diacritic + fZeroWidth, {:1} // Blank, ZWJ, ZWNJ etc, with no width + fReserved {:1} // General reserved + ); + TScriptVisAttr_set = set of TScriptVisAttr_enum; + + PScriptVisAttr = ^TScriptVisAttr; + tag_SCRIPT_VISATTR = packed record + case Byte of + 0: (uJustification: Byte) {:4}; // Justification class + 1: (fFlags: TScriptVisAttr_set; + fShapeReserved: Byte) {:8}; // Reserved for use by shaping engines + end; +(* uJustification: Word {:4}; // Justification class + fClusterStart: Word {:1}; // First glyph of representation of cluster + fDiacritic: Word {:1}; // Diacritic + fZeroWidth: Word {:1}; // Blank, ZWJ, ZWNJ etc, with no width + fReserved: Word {:1}; // General reserved + fShapeReserved: Word {:8}; // Reserved for use by shaping engines + end; *) + SCRIPT_VISATTR = tag_SCRIPT_VISATTR; + {$EXTERNALSYM SCRIPT_VISATTR} + TScriptVisAttr = SCRIPT_VISATTR; + +const + MASK_uJustification = $F; // Mask to apply to TScriptVisAttr.uJustification + +// +// +//p uJustification: Justification class for this glyph. See SCRIPT_JUSTIFY. +// +//p fClusterStart: Set for the logically first glyph in every cluster, +// even for clusters containing just one glyph. +// +//p fDiacritic: Set for glyphs that combine with base characters. +// +//p fZeroWidth: Set by the shaping engine for some, but not all, zero +// width characters. + + +///// ScriptShape +// +// The ScriptShape function takes a Unicode run and generates glyphs and +// visual attributes. +// +// The number of glyphs generated varies according to the script and the +// font. Only for simple scripts and fonts does each Unicode code point +// generates a single glyph. +// +// There is no limit on the number of glyphs generated by a codepoint. +// For example, a sophisticated complex script font might choose to +// constuct characters from components, and so generate many times as +// many glyphs as characters. +// +// There are also special cases like invalid character representations, +// where extra glyphs are added to represent the invalid sequence. +// +// A reasonable guess might be to provide a glyph buffer 1.5 times the +// length of the character buffer, plus a 16 glyph fixed addition for +// rare cases like invalid sequenece representation. +// +// If ScriptShape returns E_OUTOFMEMORY it will be necessary to recall +// it, possibly more than once, until a large enough buffer is found. + + +function ScriptShape( + hdc: HDC; // In Optional (see under caching) + psc: PScriptCache; // InOut Cache handle + const pwcChars: PWideChar; // In Logical unicode run + cChars: Integer; // In Length of unicode run + cMaxGlyphs: Integer; // In Max glyphs to generate + psa: PScriptAnalysis; // InOut Result of ScriptItemize (may have fNoGlyphIndex set) + pwOutGlyphs: PWord; // Out Output glyph buffer + pwLogClust: PWord; // Out Logical clusters + psva: PScriptVisAttr; // Out Visual glyph attributes + pcGlyphs: PInteger // Out Count of glyphs generated + ): HRESULT; stdcall; +{$EXTERNALSYM ScriptShape} + + + + + + +///// +// +// Returns E_OUTOFMEMORY if the output buffer length (cMaxGlyphs) is +// insufficient. Note that in this case, as in all error cases, the +// content of all output parameters are undefined. +// +//p psa: Pass the SCRIPT_ANALYSIS field of the SCRIPT_ITEM entry for this +// item. (The SCRIPT_ITEM array is returned by ScriptItemize.) +// +// Clusters are sequenced uniformly within the run, as are glyphs within +// the cluster - the fRTL item flag (from ScriptItemize) identifies +// whether left to right, or right to left. +// +//p pwLogClust: has cChars elements - each entry in pwLogClust corresponds +// to a character in the input string (pwcChars). The value in each +// pwLogCLust entry is the offset of the first glyph in the cluster +// that contains this character. +// +// Example: In the following example, there are four clusters: +// 1st cluster: one character represented by one glyph +// 2nd cluster: one character represented by 3 glyphs +// 3rd cluster: three characters represented by one glyph +// 4th cluster: 2 characters represented by three glyphs +// +// Glyph array: (cg means cluster n glyph m) +//c 0 1 2 3 4 5 6 7 +//c ------------------------------------------------- +//c | c1g1 | c2g1 c2g2 c2g3 | c3g1 | c4g1 c4g2 c4g3 | +//c ------------------------------------------------- +// +// Character array: (cu means cluster n Unicode codepoint m) +//c 0 1 2 3 4 5 6 +//c -------------------------------------------- +//c | c1u1 | c2u1 | c3u1 c3u2 c3u3 | c4u1 c4u2 | +//c -------------------------------------------- +// +// LogClust: (one entry per character gives 1st glyph in cluster +//c -------------------------------------------- +//c | 0 | 1 | 4 4 4 | 5 5 | +//c -------------------------------------------- +// +// Note that for an RTL run (SCRIPT_ANALYSIS.a.fRTL == TRUE) and when +// fLogicalOrder == FALSE (the default), glyphs are generated in visual +// order - the reverse of the codepoint order, and the values in the +// LogClust array will be descending. +// +// +//p psva: has one visual attribute per glyph and so has maxGlyphs entries. +// +// +// ScriptShape may set the fNoGlyphIndex flag in psa if the font or +// OS cannot support glyph indices. +// +// If fLogicalOrder is requested in psa, glyphs will be always be +// generated in the same order as the original Unicode characters. +// +// If fLogicalOrder is not set, right to left items are generated in +// reverse order, so ScriptTextOut does not need to reverse them before +// calling ExtTextOut. +///// ScriptPlace +// +// The ScriptPlace function takes the output of a ScriptShape call and +// generates glyph advance width and 2D offset information. +// +// The composite ABC width for the whole item identifies how much the +// glyphs overhang to the left of the start position and to the right of +// the length implied by the sum of the advance widths. +// +// The total advance width of the line is exactly abcA + abcB + abcC. +// +// abcA and abcC are maintained internally by Uniscribe as proportions +// of the cell height represented in 8 bits and are thus roughly +/- 1%. +// The total width returned (as the sum of piAdvance, and as the sum of +// abcA+abcB+abcC) is accurate to the resolution of the TrueType shaping +// engine. +// +// All glyph related arrays are in visual order unless the fLogicalOrder +// flag is set in psa. + +type + PGOffset = ^TGOffset; + tagGOFFSET = record + du: Longint; + dv: Longint; + end; + GOFFSET = tagGOFFSET; + {$EXTERNALSYM GOFFSET} + TGOffset = tagGOFFSET; + + +function ScriptPlace( + hdc: HDC; // In Optional (see under caching) + psc: PScriptCache; // InOut Cache handle + const pwGlyphs: PWord; // In Glyph buffer from prior ScriptShape call + cGlyphs: Integer; // In Number of glyphs + const psva: PScriptVisAttr; // In Visual glyph attributes + psa: PScriptAnalysis; // InOut Result of ScriptItemize (may have fNoGlyphIndex set) + piAdvance: PInteger; // Out Advance wdiths + pGoffset: PGOffset; // Out x,y offset for combining glyph + pABC: PABC // Out Composite ABC for the whole run (Optional) + ): HRESULT; stdcall; +{$EXTERNALSYM ScriptPlace} + + + + + + +///// ScriptTextOut +// +// The ScriptTextOut function takes the output of both ScriptShape and +// ScriptPlace calls and calls the operating system ExtTextOut function +// appropriately. If the last parameter is not null, GDI's ExtTextOutW calls +// are routed to this function. +// +// All arrays are in visual order unless the fLogicalOrder flag is set in +// psa. + + +function ScriptTextOut( + const hdc: HDC; // In OS handle to device context (required) + psc: PScriptCache; // InOut Cache handle + x: Integer; // In x,y position for first glyph + y: Integer; // In + fuOptions: LongWord; // In ExtTextOut options + const lprc: PRect; // In optional clipping/opaquing rectangle + const psa: PScriptAnalysis; // In Result of ScriptItemize + const pwcReserved: PWideChar; // In Reserved (requires NULL) + iReserved: Integer; // In Reserved (requires 0) + const pwGlyphs: PWord; // In Glyph buffer from prior ScriptShape call + cGlyphs: Integer; // In Number of glyphs + const piAdvance: PInteger; // In Advance widths from ScriptPlace + const piJustify: PInteger; // In Justified advance widths (optional) + const pGoffset: PGOffset // In x,y offset for combining glyph + ): HRESULT; stdcall; + + + + + + +///// +// +// The caller should normally use SetTextAlign(hdc, TA_RIGHT) before +// calling ScriptTextOut with an RTL item inlogical order. +// +// The piJustify array provides requested cell widths for each glyph. +// When the piJustify width of a glyph differs from the unjustified +// width (in PiAdvance), space is added to or removed from the glyph +// cell at it's trailing edge. The glyph is always aligned with the +// leading edge of it's cell. (This rule applies even in visual order.) +// +// When a glyph cell is extended the extra space is uaually made up by +// the addition of white space, however for Arabic scripts, the extra +// space is made up by one or more kashida glyphs, unless the extra space +// is insufficient for the shortest kashida glyph in the font. (The +// width of the shortest kashida is available by calling +// ScriptGetFontProperties.) +// +// piJustify should only be passed if re-justification of the string is +// required. Normally pass NULL to this parameter. +// +// fuOptions may contain ETO_CLIPPED or ETO_OPAQUE (or neither or both). +// +// Do not use ScriptTextOut to write to a metafile unless you are sure +// that the metafile will eventually be played back without any font +// substitution. ScriptTextOut record glyph numbers in the metafile. +// Since glyph numbers vary considerably from one font to another +// such a metafile is unlikely to play back correctly when differant +// fonts are substituted. +// +// For example when a metafile is played back at a different scale +// CreateFont requests recorded in the metafile may resolve to bitmap +// instead of truetype fonts, or if the metafile is played back on +// a different machine requested fonts may not be installed.// +// +// To write complex scripts in a metafile in a font independant manner, +// use ExtTextOut to write the logical characters directly, so that +// glyph generation and placement does not occur until the text is +// played back. +///// ScriptJustify +// +// ScriptJustify provides a simple minded implementation of multilingual +// justification. +// +// Sophisticated text formatters may prefer to generate their own delta +// dx array by combining their own features with the information returned +// by ScriptShape in the SCRIPT_VISATTR array. +// +// ScriptJustify establishes how much adjustment to make at each glyph +// position on the line. It interprets the SCRIPT_VISATTR array generated +// by a call to ScriptShape, and gives top priority to kashida, then uses +// inter word spacing if there's no kashida points, then uses +// intercharacter spacing if there are no inter-word points. +// +// The justified advance widths generated in ScriptJustify should be +// passed to ScriptTextOut in the piJustify paramter. +// +// ScriptJustify creates a justify array containing updated advance +// widths for each glyph. Where a glyphs advance width is increased, it +// is expected that the extra width will be rendered to the right of the +// glyph, with as white space or, for Arabic text, as kashida. +///// +function ScriptJustify( + const psva: PScriptVisAttr; // In Collected visual attributes for entire line + const piAdvance: PInteger; // In Advance widths from ScriptPlace + cGlyphs: Integer; // In Size of all arrays + iDx: Integer; // In Desired width change, either increase or descrease + iMinKashida: Integer; // In Minimum length of continuous kashida glyph to generate + piJustify: PInteger // Out Updated advance widths to pass to ScriptTextOut + ): HRESULT; stdcall; + + + + +type + ///// SCRIPT_LOGATTR + // + // The SCRIPT_LOGATTR structure describes attributes of logical + // characters useful when editing and formatting text. + // + // Note that for wordbreaking and linebreaking, if the first character of + // the run passed in is not whitespace, the client needs to check whether + // the last character of the previous run is whitespace to determine if + // the first character of this run is the start of a word. + // + // + TScriptLogAttr_enum = ( + fSoftBreak, // Potential linebreak point + fWhiteSpace, // A unicode whitespace character, except NBSP, ZWNBSP + fCharStop, // Valid cursor position (for left/right arrow) + fWordStop, // Valid cursor position (for ctrl + left/right arrow) + fInvalid // Invalid character sequence + ); + + PScriptLogAttr = ^TScriptLogAttr; + tag_SCRIPT_LOGATTR = set of TScriptLogAttr_enum; +(* fSoftBreak: Byte {:1}; // Potential linebreak point + fWhiteSpace: Byte {:1}; // A unicode whitespace character, except NBSP, ZWNBSP + fCharStop: Byte {:1}; // Valid cursor position (for left/right arrow) + fWordStop: Byte {:1}; // Valid cursor position (for ctrl + left/right arrow) + fInvalid: Byte {:1}; // Invalid character sequence + fReserved: Byte {:3;} + end; *) + {$EXTERNALSYM tag_SCRIPT_LOGATTR} + SCRIPT_LOGATTR = tag_SCRIPT_LOGATTR; + {$EXTERNALSYM SCRIPT_LOGATTR} + TScriptLogAttr = SCRIPT_LOGATTR; + + +// +// +//p fSoftBreak: It would be valid to break the line in front of this +// character. This flag is set on the first character of +// South-East Asian words. Note that when linebreaking the +// client would usually also treat any nonblank following a blank +// as a softbreak position, by inspecting the fWhiteSPace flag +// below. +// +//p fWhiteSpace: This character is one of the many Unicode character +// that are classified as breakable whitespace. +// +//p fCharStop: Valid cursor position. Set on most characters, but not +// on codepoints inside Indian and South East Asian character +// clusters. May be used to implement left and right arrow +// operation in editors. +// +//p fWordStop: Valid position following word advance/retire commonly +// implemented at ctrl/left-arrow and ctrl/right-arrow. +// May be used to implement ctrl+left and ctrl+right arrow +// operation in editors. As with fSoftBreak clients should +// normally also inspect the fWhiteSpace flag and treat the +// first character after a run of whitespace as the start of a +// word. +// +//p fInvalid: Marks characters which form an invalid or undisplayable +// combination. Scripts which can set this flag have the flag +// fInvalidLogAttr set in their SCRIPT_PROPERTIES. + + + + + + +///// ScriptBreak +// +// The ScriptBreak function returns cursor movement and formatting break +// positions for an item as an array of SCRIPT_LOGATTRs. To support +// mixed formatting within a single word correctly, ScriptBreak should +// be passed whole items as returned by ScriptItemize. +// +// ScriptBreak does not require an hdc and does not execute glyph shaping. +// +// The fCharStop flag marks cluster boundaries for those scripts where +// it is conventional to restrict from moving inside clusters. The same +// boundaries could also be inferred by inspecting the pLogCLust array +// returned by ScriptShape, however ScriptBreak is considerably faster in +// implementation and does not require an hdc to be prepared. +// +// The fWordStop, fSoftBreak and fWhiteSpace flags are only available +// through ScriptBreak. +// +// Most shaping engines that identify invalid sequences do so by setting +// the fInvalid flag in ScriptBreak. The fInvalidLogAttr flag in +// ScriptProperties identifies which scripts do this. + + +function ScriptBreak( + const pwcChars: PWideChar; // In Logical unicode item + cChars: Integer; // In Length of unicode item + const psa: PScriptAnalysis; // In Result of earlier ScriptItemize call + psla: PScriptLogAttr // Out Logical character attributes + ): HRESULT; stdcall; +{$EXTERNALSYM ScriptBreak} + + + + + +///// ScriptCPtoX +// +// The ScriptCPtoX function returns the x offset from the left end +// (!fLogical) or leading edge (fLogical) of a run to either the leading +// or the trailing edge of a logical character cluster. +// +// iCP is the offset of any logical character in the cluster. +// +// For scripts where the caret may conventionally be placed into the +// middle of clusters (e.g. Arabic, Hebrew), the returned X may be +// an interpolated position for any codepoint in the line. +// +// For scripts where the caret is conventionally snapped to the boundaries +// of clusters, (e.g. Thai, Indian), the resulting X position will be +// snapped to the requested edge of the cluster containing CP. + + +function ScriptCPtoX( + iCP: Integer; // In Logical character position in run + fTrailing: BOOL; // In Which edge (default - leading) + cChars: Integer; // In Count of logical codepoints in run + cGlyphs: Integer; // In Count of glyphs in run + const pwLogClust: PWord; // In Logical clusters + const psva: PScriptVisAttr; // In Visual glyph attributes array + const piAdvance: PInteger; // In Advance widths + const psa: PScriptAnalysis; // In Script analysis from item attributes + piX: PInteger // Out Resulting X position + ): HRESULT; stdcall; + + + + + + +///// ScriptXtoCP +// +// The ScriptXtoCP function converts an x offset from the left end +// (!fLogical) or leading edge (fLogical) of a run to a logical +// character position and a flag that indicates whether the X position +// fell in the leading or the trailing half of the character. +// +// For scripts where the cursor may conventionally be placed into the +// middle of clusters (e.g. Arabic, Hebrew), the returned CP may be +// for any codepoint in the line, and fTrailing will be either zero +// or one. +// +// For scripts where the cursor is conventionally snapped to the +// boundaries of a cluster, the returned CP is always the position of +// the logically first codepoint in a cluster, and fTrailing is either +// zero, or the number of codepoints in the cluster. +// +// Thus the appropriate cursor position for a mouse hit is always the +// returned CP plus the value of fTrailing. +// +// If the X positition passed is not in the item at all, the resulting +// position will be the trailing edge of character -1 (for X positions +// before the item), or the leading edge of character 'cChars' (for +// X positions following the item). + + +function ScriptXtoCP( + iX: Integer; // In X offset from left of run + cChars: Integer; // In Count of logical codepoints in run + cGlyphs: Integer; // In Count of glyphs in run + const pwLogClust: PWord; // In Logical clusters + const psva: PScriptVisAttr; // In Visual glyph attributes + const piAdvance: Integer; // In Advance widths + const psa: PScriptAnalysis; // In Script analysis from item attributes + piCP: PInteger; // Out Resulting character position + piTrailing: PInteger // Out Leading or trailing half flag + ): HRESULT; stdcall; + + + + + + +///// Relationship between caret positions, justifications points and clusters +// +// +//t Job | Uniscribe support +//t -------------------------------- | -------------------------------------------------------- +//t Caret move by character cluster | LogClust or VISATTR.fClusterStart or LOGATTR.fCharStop +//t Line breaking between characters | LogClust or VISATTR.fClusterStart or LOGATTR.fCharStop +//t Caret move by word | LOGATTR.fWordStop +//t Line breaking between words | LOGATTR.fWordStop +//t Justification | VISATTR.uJustification +// +// +// +///// Character clusters +// +// Character clusters are glyph sequences that cannot be split between +// lines. +// +// Some languages (e.g. Thai, Indic) restrict caret placement to points +// betwen clusters. This applies both to keyboard initiated caret +// movement (e.g. cursor keys) and pointing and clicking with the mouse +// (hit testing). +// +// Uniscribe provides cluster information in both the visual and logical +// attributes. If you've called ScriptShape you'll find the cluster +// information represented both by sequences of the same value in the +// pwLogClust array, and by the fClusterStart flag in the psva +// SCRIPT_VISATTR array. +// +// ScriptBreak also returns the fCharStop flag in the SCRIPT_LOGATTR +// array to identify cluster positions. +// +// +// +///// Word break points +// +// Valid positions for moving the caret when moving in whole words are +// marked by the fWordStop flag returned by ScriptBreak. +// +// Valid positions for breaking lines between words are marked by the +// fSoftBreak flag returned by ScriptBreak. +// +// +// +///// Justification +// +// Justification space or kashida should be inserted where identified by +// the uJustificaion field of the SCRIPT_VISATTR. +// +// When performing inter-character justification, insert extra space +// only after glyphs marked with uJustify == SCRIPT_JUSTIFY_CHARACTER. +// +// +// +///// Script specific processing +// +// Uniscribe provides information about special processing for each +// script in the SCRIPT_PROPERTIES array. +// +// Use the following code during initialisation to get a pointer to +// the SCRIPT_PROPERTIES array: +// +//c const SCRIPT_PROPERTIES **g_ppScriptProperties; // Array of pointers to properties +//c int iMaxScript; +//c HRESULT hr; +// +//c hr = ScriptGetProperties(&g_ppScriptProperties, &g_iMaxScript); +// +// Then inspect the properties of the script of an item 'iItem' as follows: +// +//c hr = ScriptItemize( ... , pItems, ... ); +//c ... +//c if (g_ppScriptProperties[pItems[iItem].a.eScript]->fNeedsCaretInfo) { +//c // Use ScriptBreak to restrict the caret from entering clusters (for example). +//c } +// +// +// SCRIPT_PROPERTIES.fNeedsCaretInfo +// +// Caret placement should be restricted to cluster +// edges for scripts such as Thai and Indian. The fNeedsCaretInfo flag +// in SCRIPT_PROPERTIES identifies such languages. +// +// Note that ScriptXtoCP and ScriptCPtoX automatically apply caret +// placement restictions. +// +// +// SCRIPT_PROPERTIES.fNeedsWordBreaking +// +// For most scripts, word break placement may be +// identified by scanning for characters marked as fWhiteSpace in +// SCRIPT_LOGATTR, or for glyphs marked as uJustify == +// SCRIPT_JUSTIFY_BLANK or SCRIPT_JUSTIFY_ARABIC_BLANK in SCRIPT_VISATTR. +// +// For languages such as Thai, it is also necessary to call ScriptBreak, +// and include character positions marked as fWordStop in SCRIPT_LOGATTR. +// Such scripts are marked as fNeedsWordbreaking in SCRIPT_PROPERTIES. +// +// +// SCRIPT_PROPERTIES.fNeedsCharacterJustify +// +// Languages such as Thai also require inter-character spacing when +// justifying (where uJustify == SCRIPT_JUSTIFY_CHARACTER in the +// SCRIPT_VISATTR). Such languages are marked as fNeedsCharacterJustify +// in SCRIPT_PROPERTIES. +// +// +// SCRIPT_PROPERTIES.fAmbiguousCharSet +// +// Many Uniscribe scripts do not correspond directly to 8 bit character +// sets. For example Unicode characters in the range U+100 through U+024F +// represent extended latin shapes used for many languages, including +// those supported by EASTEUROPE_CHARSET, TURKISH_CHARSET and +// VIETNAMESE_CHARSET. However many of these characters are supported by +// more han one of thsese charsets. +// fAmbiguousCharset is set for any script token which could contain +// characters from a number of these charsets. In these cases the bCharSet +// field may contain ANSI_CHARSET or DEFAULT_CHARSET. The Uniscribe client +// will generally need to apply futher processing to determine which charset +// to use when requesting a font suitable for this run. For example it +// determine that the run consists of multiple languages and split it up +// to use a different font for each language. + + + + + + +///// Notes on ScriptXtoCP and ScriptCPtoX +// +// Both functions work only within runs and require the results of a +// previous ScriptShape call. +// +// The client must establish which run a given cursor offset or x +// position is within before passing it to ScriptCPtoX or ScriptXtoCP. +// +// Cluster information in the logical cluster array is used to share +// the width of a cluster of glyphs equally among the logical characters +// they represent. +// +// For example, the lam alif glyph is divided into four areas: the +// leading half of the lam, the trailing half of the lam, the leading +// half of the alif and the trailing half of the alif. +// +// ScriptXtoCP Understands the caret position conventions of each script. +// For Indian and Thai, caret positions are snapped to cluster boundaries, +// for Arabic and Hebrew, caret positions are interpolated within clusters. +// +// +///// Translating mouse hit 'x' offset to caret position +// +// Conventionally, caret position 'cp' may be selected by clicking either +// on the trailing half of character 'cp-1' or on the leading half of +// character 'cp'. This may easily be implemented as follows: +// +//c int iCharPos; +//c int iCaretPos +//c int fTrailing; +// +//c ScriptXtoCP(iMouseX, ..., &iCharPos, &fTrailing); +//c iCaretPos = iCharPos + fTrailing; +// +// For scripts that snap the caret to cluster boundaries, ScriptXtoCP +// returns ftrailing set to either 0, or the width of the cluster in +// codepoints. Thus the above code correctly returns only valid +// caret positions. +// +// +///// Displaying the caret in bidi strings +// +// In unidirectional text, the leading edge of a character is at the same +// place as the trailing edge of the previous character, so there is no +// ambiguity in placing the caret between characters. +// +// In bidirectional text, the caret position between runs of opposing +// direction may be ambiguous. +// +// For example in the left to right paragraph 'helloMAALAS', the last +// letter of 'hello' immediately preceeds the first letter of 'salaam'. +// The best position to display the caret depends on whether it is +// considered to follow the 'o' of 'hello', or to preceed the 's' of +// 'salaam'. +// +///// Commonly used caret positioning conventions +// +//t Situation | Visual caret placement +//t --------- | ------------------------------------------- +//t Typing | Trailing edge of last character typed +//t Pasting | Trailing edge of last character pasted +//t Caret advancing | Trailing edge of last character passed over +//t Caret retiring | Leading edge of last character passed over +//t Home | Leading edge of line +//t End | Trailing edge of line +// +// The caret may be positioned as follows: +// +//c if (advancing) { +//c ScriptCPtoX(iCharPos-1, TRUE, ..., &iCaretX); +//c } else { +//c ScriptCPtoX(iCharPos, FALSE, ..., &iCaretX); +//c } +// +// Or, more simply, given an fAdvancing BOOL restricted to TRUE or FALSE: +// +//c ScriptCPtoX(iCharPos-fAdvancing, fAdvancing, ..., &iCaretX); +// +// ScriptCPtoX handles out of range positions logically: it returns the +// leading edge of the run for iCharPos <0, and the trailing edge of the +// run for iCharPos >=length. +///// ScriptGetLogicalWidths +// +// Converts visual withs in piAdvance into logical widths, +// one per original character, in logical order. +// +// Ligature glyphs widths are divided evenly amongst the characters +// they represent. + + +function ScriptGetLogicalWidths( + const psa: PScriptAnalysis; // In Script analysis from item attributes + cChars: Integer; // In Count of logical codepoints in run + cGlyphs: Integer; // In Count of glyphs in run + const piGlyphWidth: PInteger; // In Advance widths + const pwLogClust: PWord; // In Logical clusters + const psva: PScriptVisAttr; // In Visual glyph attributes + piDx: PInteger // Out Logical widths + ): HRESULT; stdcall; + + + + + + +///// +// ScriptGetLogicalWidths is useful for recording widths in a +// font independant manner. By passing the recorded logical widths +// to ScriptApplyLogicalWidths, a block of text can be replayed in the +// same boundaries with acceptable loss of quality even when the original +// font is not available. +///// ScriptApplyLogicalWidth +// +// Accepts an array of advance widths in logical order, corresponding +// one to one with codepoints, and generates an array of glyph widths +// suitable for passing to the piJustify parameter of ScriptTextOut. +// +// ScriptApplyLogicalWidth may be used to reapply logical widths +// obtained with ScriptGetLogicalWidths. It may be useful in situations +// such as metafiling, where it is necessary to record and reapply +// advance width information in a font independant manner. + + + +function ScriptApplyLogicalWidth( + const piDx: PInteger; // In Logical dx array to apply + cChars: Integer; // In Count of logical codepoints in run + cGlyphs: Integer; // In Glyph count + const pwLogClust: PWORD; // In Logical clusters + const psva: PScriptVisAttr; // In Visual attributes from ScriptShape/Place + const piAdvance: PInteger; // In Glyph advance widths from ScriptPlace + const psa: PScriptAnalysis; // In Script analysis from item attributes + pABC: PABC; // InOut Updated item ABC width (optional) + piJustify: PInteger // Out Resulting glyph advance widths for ScriptTextOut + ): HRESULT; stdcall; + + + + + + +///// +//p piDx: Pointer to an array of dx widths in logical order, one per codepoint. +// +//p cChars: Count of the logical codepoints in the run. +// +//p cGlyphs: Glyph count. +// +//p pwLogClust: Pointer to an array of logical clusters from ScriptShape +// +//p psva: Pointer to an array of visual attributes from ScriptShape and +// updated by ScriptPlace. +// +//p piAdvance: Pointer to an array of glyph advance widths from ScriptPlace. +// +//p psa: Pointer to a SCRIPT_ANALYSIS structure from ScriptItemize and +// updated by ScriptShape and SriptPlace.. +// +//p pABC: Pointer to the run overall ABC width (optional). If present, +// when the function is called, it should contain the run ABC width +// returned by ScriptPlace; when the function returns, the ABC width +// has been updated to match the new widths. +// +//p piJustify:Pointer to an array of the resulting glyph advance widths. +// This is suitable for passing to the piJustify parameter of ScriptTextOut. +///// ScriptGetCMap +// +// ScriptGetCMap may be used to determine which characters in a run +// are supported by the selected font. +// +// It returns glyph indices of Unicode characters according to Truetype +// Cmap table, or standard Cmap implemented for old style fonts. The +// glyph indices are returned in the same order as the input string. +// +// The caller may scan the returned glyph buffer looking for the default +// glyph to determine which characters are not available. (The default +// glyph index for the selected font should be determined by calling +// ScriptGetFontProperties). +// +// The return value indicates the presence of any missing glyphs. + +const + SGCM_RTL = $00000001; // Return mirrored glyph for mirrorable Unicode codepoints + + +function ScriptGetCMap( + hdc: HDC; // In Optional (see notes on caching) + psc: PScriptCache; // InOut Address of Cache handle + const pwcInChars: PWideChar; // In Unicode codepoint(s) to look up + cChars: Integer; // In Number of characters + dwFlags: DWORD; // In Flags such as SGCM_RTL + pwOutGlyphs: PWord // Out Array of glyphs, one per input character + ): HRESULT; stdcall; + + + + + +///// +// returns S_OK - All unicode codepoints were present in the font +// S_FALSE - Some of the Unicode codepoints were mapped to the default glyph +// E_HANDLE - font or system does not support glyph indices +///// ScriptGetGlyphABCWidth +// +// Returns ABC width of a given glyph. +// May be useful for drawing glyph charts. Should not be used for +// run of the mill complex script text formatting. + + +function ScriptGetGlyphABCWidth( + hdc: HDC; // In Optional (see notes on caching) + psc: PScriptCache; // InOut Address of Cache handle + wGlyph: Word; // In Glyph + pABC: PABC // Out ABC width + ): HRESULT; stdcall; + + + + + +type + ///// + // returns S_OK - Glyph width returned + // E_HANDLE - font or system does not support glyph indices + ///// SCRIPT_PROPERTIES + // + + TScriptProperties_enum = ( + fNumeric, {:1} + fComplex, {:1} // Script requires special shaping or layout + fNeedsWordBreaking, {:1} // Requires ScriptBreak for word breaking information + fNeedsCaretInfo, {:1} // Requires caret restriction to cluster boundaries + bCharSet, {:8} // Charset to use when creating font + fControl, {:1} // Contains only control characters + fPrivateUseArea, {:1} // This item is from the Unicode range U+E000 through U+F8FF + fNeedsCharacterJustify,{:1} // Requires inter-character justification + fInvalidGlyph, {:1} // Invalid combinations generate glyph wgInvalid in the glyph buffer + fInvalidLogAttr, {:1} // Invalid combinations are marked by fInvalid in the logical attributes + fCDM, {:1} // Contains Combining Diacritical Marks + fAmbiguousCharSet, {:1} // Script does not correspond 1//:1 with a charset + fClusterSizeVaries, {:1} // Measured cluster width depends on adjacent clusters + fRejectInvalid {:1} // Invalid combinations should be rejected + ); + TScriptProperties_set = set of TScriptProperties_enum; + + PScriptProperties = ^TScriptProperties; + SCRIPT_PROPERTIES = packed record + langid: Word {:16}; // Primary and sublanguage associated with script + fFlags: TScriptProperties_set; + end; +(* langid: DWORD {:16}; // Primary and sublanguage associated with script + fNumeric: DWORD {:1}; + fComplex: DWORD {:1}; // Script requires special shaping or layout + fNeedsWordBreaking: DWORD {:1}; // Requires ScriptBreak for word breaking information + fNeedsCaretInfo: DWORD {:1}; // Requires caret restriction to cluster boundaries + bCharSet: DWORD {:8}; // Charset to use when creating font + fControl: DWORD {:1}; // Contains only control characters + fPrivateUseArea: DWORD {:1}; // This item is from the Unicode range U+E000 through U+F8FF + fNeedsCharacterJustify: DWORD {:1}; // Requires inter-character justification + fInvalidGlyph: DWORD {:1}; // Invalid combinations generate glyph wgInvalid in the glyph buffer + fInvalidLogAttr: DWORD {:1}; // Invalid combinations are marked by fInvalid in the logical attributes + fCDM: DWORD {:1}; // Contains Combining Diacritical Marks + fAmbiguousCharSet: DWORD {:1}; // Script does not correspond 1//:1 with a charset + fClusterSizeVaries: DWORD {:1}; // Measured cluster width depends on adjacent clusters + fRejectInvalid: DWORD {:1}; // Invalid combinations should be rejected + end; *) + {$EXTERNALSYM SCRIPT_PROPERTIES} + TScriptProperties = SCRIPT_PROPERTIES; + +// +//p langid: Language associated with this script. When a script is used for many languages, +// langid id represents a default language. For example, Western script is represented +// by LANG_ENGLISH although it is also used for French, German, Spanish etc. +// +//p fNumeric: Script contains numerics and characters used in conjunction with numerics +// by the rules of the Unicode bidirectional algorithm. For example +// dollar sign and period are classified as numeric when adjacent to or in between +// digits. +// +//p fComplex: Indicates a script that requires complex script handling. If fComplex is false +// the script contains no combining characters and requires no contextual shaping or reordering. +// +//p fNeedsWordBreaking: A script, such as Thai, which requires algorithmic wordbreaking. +// Use ScriptBreak to obtain a wordbreak points using the standard system wordbreaker. +// +//p fNeedsCaretInfo: A script, such as Thai and Indian, where the caret may not be placed +// inside a cluster. To determine valid caret positions inspect the fCharStop flag in the +// logical attributes returned by ScriptBreak, or compare adjacent values in the pwLogClust +// array returned by ScriptShape. +// +//p bCharSet: Nominal charset associated with script. May be used in a logfont when creating +// a font suitable for displaying this script. Note that for new scripts where there +// is no charset defined, bCharSet may be innapropriate and DEFAULT_CHARSET should +// be used instead - see the description of fAmbiguousCharSet below. +// +//p fControl: contains control characters. +// +//p fPrivateUseArea: The Unicode range U+E000 through U+F8FF. +// +//p fNeedsCharacterJustify: A script, such as Thai, where justification is conventionally +// achieved by increasing the space between all letters, not just between words. +// +//p fInvalidGlyph: A script for which ScriptShape generates an invalid glyph +// to represent invalid sequences. The glyph index of the invalid glyph for +// a particular font may be obtained by calling ScriptGetFontProperties. +// +//p fInvalidLogAttr: A script for which ScriptBreak sets the fInvalid flag +// in the logical attributes to mark invalid sequences. +// +//p fCDM: Implies that an item analysed by ScriptItemize included combining +// diacritical marks (U+0300 through U+36F). +// +//p fAmbiguousCharSet: No single legacy charset supports this script. +// For example the extended Latin Extended-A Unicode range includes +// characters from the EASTUROPE_CHARSET, the TURKISH_CHARSET and the +// BALTIC_CHARSET. It also contains characters that are not available +// in any legacy charset. Use DEFAULT_CHARSET when creating fonts to +// display parts of this run. +// +//p fClusterSizeVaries: A script, such as Arabic, where contextual shaping +// may cause a string to increase in size when removing characters. +// +//p fRejectInvalid: A script, such as Thai, where invalid sequences conventionally +// cause an editor such as notepad to beep, and ignore keypresses. + + +///// ScriptGetProperties +// +// ScriptGetProperties returns the address of a table that maps a +// script in a SCRIPT_ANALYSIS uScript field to properties including +// the primary language associated with that script, whether it's +// numeric and whether it's complex. + + +function ScriptGetProperties( + out ppSp: PScriptProperties; // Out Receives pointer to table of pointers to properties indexed by script + out piNumScripts: Integer // Out Receives number of scripts (valid values are 0 through NumScripts-1) + ): HRESULT; stdcall; + + + + + +type + ///// SCRIPT_FONTPROPERTIES + // + PScriptFontProperties = ^TScriptFontProperties; + SCRIPT_FONTPROPERTIES = record + cBytes: Integer; // Structure length + wgBlank: Word; // Blank glyph + wgDefault: Word; // Glyph used for Unicode values not present in the font + wgInvalid: Word; // Glyph used for invalid character combinations (especially in Thai) + wgKashida: Word; // Shortest continuous kashida glyph in the font, -1 if doesn't exist + iKashidaWidth: Integer;// Widths of shortest continuous kashida glyph in the font + end; + {$EXTERNALSYM SCRIPT_FONTPROPERTIES} + TScriptFontProperties = SCRIPT_FONTPROPERTIES; + + +///// ScriptGetFontProperties +// +// Returns information from the font cache + + +function ScriptGetFontProperties( + hdc: HDC; // In Optional (see notes on caching) + psc: PScriptCache; // InOut Address of Cache handle + sfp: PScriptFontProperties // Out Receives properties for this font + ): HRESULT; stdcall; + + + + + + +///// ScriptCacheGetHeight +// +// + + +function ScriptCacheGetHeight( + hdc: HDC; // In Optional (see notes on caching) + psc: PScriptCache; // InOut Address of Cache handle + tmHeight: PLongint // Out Receives font height in pixels + ): HRESULT; stdcall; + + + + +const + ///// ScriptStringAnalyse + // + // + SSA_PASSWORD = $00000001; // Input string contains a single character to be duplicated iLength times + SSA_TAB = $00000002; // Expand tabs + SSA_CLIP = $00000004; // Clip string at iReqWidth + SSA_FIT = $00000008; // Justify string to iReqWidth + SSA_DZWG = $00000010; // Provide representation glyphs for control characters + SSA_FALLBACK = $00000020; // Use fallback fonts + SSA_BREAK = $00000040; // Return break flags (character and word stops) + SSA_GLYPHS = $00000080; // Generate glyphs, positions and attributes + SSA_RTL = $00000100; // Base embedding level 1 + SSA_GCP = $00000200; // Return missing glyphs and LogCLust with GetCharacterPlacement conventions + SSA_HOTKEY = $00000400; // Replace '&' with underline on subsequent codepoint + SSA_METAFILE = $00000800; // Write items with ExtTextOutW Unicode calls, not glyphs + SSA_LINK = $00001000; // Apply FE font linking/association to non-complex text + SSA_HIDEHOTKEY = $00002000; // Remove first '&' from displayed string + SSA_HOTKEYONLY = $00002400; // Display underline only. + + SSA_FULLMEASURE = $04000000; // Internal - calculate full width and out the number of chars can fit in iReqWidth. + SSA_LPKANSIFALLBACK = $08000000; // Internal - enable FallBack for all LPK Ansi calls Except BiDi hDC calls + SSA_PIDX = $10000000; // Internal + SSA_LAYOUTRTL = $20000000; // Internal - Used when DC is mirrored + SSA_DONTGLYPH = $40000000; // Internal - Used only by GDI during metafiling - Use ExtTextOutA for positioning + SSA_NOKASHIDA = $80000000; // Internal - Used by GCP to justify the non Arabic glyphs only. +// +// +//p SSA_HOTKEY: Note that SSA_HOTKEY and SSA_HIDEHOTKEY remove the +// hotkey '&' character from further processing, so functions +// such as ScriptString_pLogAttr return arrays based on a string +// which excludes the '&'. + + + +type + ///// SCRIPT_TABDEF + // + // Defines tabstop positions for ScriptStringAnalyse (ignored unless SSA_TAB passed) + // + PScriptTabDef = ^TScriptTabDef; + tag_SCRIPT_TABDEF = record + cTabStops: Integer; // Number of entries in pTabStops array + iScale: Integer; // Scale factor for pTabStops (see below) + pTabStops: PInteger; // Pointer to array of one or more tab stops + iTabOrigin: Integer; // Initial offset for tab stops (logical units) + end; + {$EXTERNALSYM tag_SCRIPT_TABDEF} + SCRIPT_TABDEF = tag_SCRIPT_TABDEF; + {$EXTERNALSYM SCRIPT_TABDEF} + TScriptTabDef = tag_SCRIPT_TABDEF; + +// +// +//p cTabStops: Number of entries in the pTabStops array. If zero, tabstops +// are every 8 average character widths. If one, all tabstops are +// the length of the first entry in pTabStops. If more than one, +// the first cTabStops are as specified in the pTabStops array, +// subsequent tabstops are every 8 average characters from the last +// tabstop in the array. +// +//p iScale: Scale factor for iTabOrigin and pTabStops entries. Values are +// converted to device coordinates by multiplying by iScale then +// dividing by 4. If values are already in device units, set iScale to +// 4. If values are in dialog units, set iScale to the average char +// width of the dialog font. If values are multiples of the average +// character width for the selected font, set iScale to 0. +// +//p pTabStops: Array of cTabStops entries. Each entry specifies a +// tabstop position. Positive values give nearedge alignment, +// negative values give faredge alignment. +// +//p iTabOrigin: Tabs are considered to start iTabOrigin before the +// beginning of the string. Helps with multiple tabbed +// outputs on the same line. + + + + + + +///// ScriptStringAnalyse +// +// cString - Input string must contain at least one character +// +// hdc - required if SSA_GLYPH requested. Optional for SSA_BREAK. +// If present the current font in the hdc is inspected and if a symbolic +// font the character string is treated as a single neutral SCRIPT_UNDEFINED item. +// +// Note that the uBidiLevel field in the initial SCRIPT_STATE value +// is ignored - the uBidiLevel used is derived from the SSA_RTL +// flag in combination with the layout of the hdc. + + + SCRIPT_STRING_ANALYSIS = Pointer; + {$EXTERNALSYM SCRIPT_STRING_ANALYSIS} + TScriptStringAnalysis = SCRIPT_STRING_ANALYSIS; + PScriptStringAnalysis = ^TScriptStringAnalysis; + + +function ScriptStringAnalyse( + hdc: HDC; //In Device context (required) + const pString: Pointer; //In String in 8 or 16 bit characters + cString: Integer; //In Length in characters (Must be at least 1) + cGlyphs: Integer; //In Required glyph buffer size (default cString*1.5 + 16) + iCharset: Integer; //In Charset if an ANSI string, -1 for a Unicode string + dwFlags: DWORD; //In Analysis required + iReqWidth: Integer; //In Required width for fit and/or clip + psControl: PScriptControl; //In Analysis control (optional) + psState: PScriptState; //In Analysis initial state (optional) + const piDx: PInteger; //In Requested logical dx array + pTabdef: PScriptTabDef; //In Tab positions (optional) + const pbInClass: PByte; //In Legacy GetCharacterPlacement character classifications (deprecated) + + pssa: PScriptStringAnalysis //Out Analysis of string + ): HRESULT; stdcall; + + + + + + +///// ScriptStringFree - free a string analysis +// +// + + +function ScriptStringFree( + pssa: PScriptStringAnalysis //InOut Address of pointer to analysis + ): HRESULT; stdcall; + + + + + + +///// ScriptStringSize +// +// returns a pointer to the size (width and height) of an analysed string +// +// Note that the SIZE pointer remains valid only until the +// SCRIPT_STRING_ANALYSIS is passed to ScriptStringFree. + + +function ScriptString_pSize( + ssa: TScriptStringAnalysis + ): {const} PSize; stdcall; + + + + + + +///// ScriptString_pcOutChars +// +// returns pointer to length of string after clipping (requires SSA_CLIP set) +// +// Note that the int pointer remains valid only until the +// SCRIPT_STRING_ANALYSIS is passed to ScriptStringFree. + + +function ScriptString_pcOutChars( + ssa: TScriptStringAnalysis + ): {const} PInteger; stdcall; + + + + + + +///// ScriptString_pLogAttr +// +// returns pointer to logical attributes buffer in a SCRIPT_STRING_ANALYSIS +// +// Note that the buffer pointer remains valid only until the +// SCRIPT_STRING_ANALYSIS is passed to ScriptStringFree. +// +// The logical attribute array contains *ScriptString_pcOutChars(ssa) +// entries. + + +function ScriptString_pLogAttr( + ssa: TScriptStringAnalysis + ): {const} PScriptLogAttr; stdcall; + + + + + + +///// ScriptStringGetOrder +// +// Creates an array mapping original character position to glyph position. +// +// Treats clusters as they were in legacy systems - Unless a cluster +// contains more glyphs than codepoints, each glyph is referenced at +// least once from the puOrder array. +// +// Requires SSA_GLYPHS requested in original ScriptStringAnalyse call. +// +// The puOrder parameter should address a buffer containing room for +// at least *ScriptString_pcOutChars(ssa) ints. + + +function ScriptStringGetOrder( + ssa: TScriptStringAnalysis; + puOrder: PLongWord + ): HRESULT; stdcall; + + + + + + +///// ScriptStringCPtoX +// +// Return x coordinate for leading or trailing edge of character icp. + + +function ScriptStringCPtoX( + ssa: TScriptStringAnalysis; //In String analysis + icp: Integer; //In Caret character position + fTrailing: BOOL; //In Which edge of icp + out pX: Integer //Out Corresponding x offset + ): HRESULT; stdcall; + + + + + +///// ScriptStringXtoCP +// +// + + +function ScriptStringXtoCP( + ssa: TScriptStringAnalysis; // In + iX: Integer; // In + piCh: PInteger; // Out + piTrailing: PInteger // Out + ): HRESULT; stdcall; + + + + + +///// ScriptStringGetLogicalWidths +// +// Converts visual withs in psa->piAdvance into logical widths, +// one per original character, in logical order. +// +// Requires SSA_GLYPHS requested in original ScriptStringAnalyse call. +// +// The piDx parameter should address a buffer containing room for +// at least *ScriptString_pcOutChars(ssa) ints. + + +function ScriptStringGetLogicalWidths( + ssa: TScriptStringAnalysis; + out piDx: Integer): HRESULT; stdcall; + + + + + + +///// ScriptStringValidate +// +// Scans the string analysis for invalid glyphs. +// +// Only glyphs generated by scripts that can generate invalid glyphs +// are scanned. +// +// returns S_OK - no invalid glyphs are present +// S_FALSE - one or more invalid glyphs are present + + +function ScriptStringValidate( + ssa: TScriptStringAnalysis): HRESULT; stdcall; + + + + + + +///// ScriptStringOut +// +// Displays the string generated by a prior ScriptStringAnalyze call, +// then optionally adds highlighting corresponding to a logical selection. +// +// Requires SSA_GLYPHS requested in original ScriptStringAnalyse call. + + +function ScriptStringOut( + ssa: TScriptStringAnalysis; //In Analysis with glyphs + iX: Integer; //In + iY: Integer; //In + uOptions: LongWord; //In ExtTextOut options + const prc: PRect; //In Clipping rectangle (iff ETO_CLIPPED) + iMinSel: Integer; //In Logical selection. Set iMinSel>=iMaxSel for no selection + iMaxSel: Integer; //In + fDisabled: BOOL //In If disabled, only the background is highlighted. + ): HRESULT; stdcall; + + + + + +const + ///// + // uOptions may nclude only ETO_CLIPPED or ETO_OPAQUE. + ///// ScriptIsComplex + // + // Determines whether a Unicode string requires complex script processing + // + // The dwFlags parameter may include the following requests + // + SIC_COMPLEX = 1; // Treat complex script letters as complex + SIC_ASCIIDIGIT = 2; // Treat digits U+0030 through U+0039 as complex + SIC_NEUTRAL = 4; // Treat neutrals as complex + +// +// SIC_COMPLEX: Should normally set. Causes complex script letters to +// be treated as complex. +// +// SIC_ASCIIDIGIT: Set this flag if the string would be displayed with +// digit substitution enabled. If you are following the users NLS +// settings using the ScriptRecordDigitSubstitution API, you can pass +// scriptDigitSubstitute.DigitSubstitute != SCRIPT_DIGITSUBSTITUTE_NONE. +// +// SIC_NEUTRAL: Set this flag if you may be displaying the string with +// right-to-left reading order. When this flag is set, neutral characters +// are considered as complex. +// +// +// Returns S_OK if string requires complex script processing, +// S_FALSE if string contains only characters laid out side by +// side from left to right. + + +function ScriptIsComplex( + const pwcInChars: PWideChar; //In String to be tested + cInChars: Integer; //In Length in characters + dwFlags: DWORD //In Flags (see above) + ): HRESULT; stdcall; + + + + + +type + ///// ScriptRecordDigitSubstitution + // + // Reads NLS native digit and digit substitution settings and records + // them in the SCRIPT_DIGITSUBSTITUTE structure. + // + // + PScriptDigitSubstitute = ^TScriptDigitSubstitute; + tag_SCRIPT_DIGITSUBSTITUTE = packed record + NationalDigitLanguage: Word {:16}; // Language for native substitution + TraditionalDigitLanguage: Word {:16}; // Language for traditional substitution + DigitSubstitute: Byte {:8}; // Substitution type + bReserved: Byte; + wReserved: Word; + dwReserved: DWORD; // Reserved + end; +(* NationalDigitLanguage: DWORD {:16}; // Language for native substitution + TraditionalDigitLanguage: DWORD {:16}; // Language for traditional substitution + DigitSubstitute: DWORD {:8}; // Substitution type + dwReserved: DWORD; // Reserved + end; *) + {$EXTERNALSYM tag_SCRIPT_DIGITSUBSTITUTE} + SCRIPT_DIGITSUBSTITUTE = tag_SCRIPT_DIGITSUBSTITUTE; + {$EXTERNALSYM SCRIPT_DIGITSUBSTITUTE} + TScriptDigitSubstitute = tag_SCRIPT_DIGITSUBSTITUTE; + +// +// +//p NationalDigitLanguage: Standard digits for the selected locale as +// defined by the countries standard setting authority. +// +//p TraditionalDigitLangauge: Digits originally used with the locales +// script. +// +//p DigitSubstitute: Selects between None, Context, National and +// Traditional. See ScriptApplyDigitSubstitution below for +// constant definitions. +// +// Although most complex scripts have their own associated digits, many +// countries using those scripts use western (so called +// 'Arabic') digits as their standard. NationalDigitLanguage reflects the +// digits used as standard, and is set from +// the NLS data for the locale. +// On Windows 2000 the national digit langauge can be +// adjusted to any digit script with the control panel/regional +// options/numbers/Standard digits listbox. +// +// The TraditionalDigitLanguage for a locale is derived directly from the +// script used by that locale. + + +function ScriptRecordDigitSubstitution( + Locale: LCID; // In LOCALE_USER_DEFAULT or desired locale + out psds: TScriptDigitSubstitute // Out Digit substitution settings + ): HRESULT; stdcall; + + + + + +///// +//p Locale: NLS locale to be queried. Should usually be set to +// LOCALE_USER_DEFAULT. Alternatively may be passed as a locale +// combined with LOCALE_NOUSEROVERRIDE to obtain default settings +// for a given locale. Note that context digit substitution is +// supported only in ARABIC and FARSI locales. In other locales, +// context digit is mapped to no substitution. +// +//p psds: Pointer to SCRIPT_DIGITSUBSTITUTE. This structure may be passed +// later to ScriptApplyDigitSubstitution. +// +//p returns: E_INVALIDARG if Locale is invalid or not installed. E_POINTER +// if psds is NULL. Otherwise S_OK. +// +// For performance reasons, you should not call +// ScriptRecordDigitSubstitution frequently. In particular it would be a +// considerable overhead to call it every time you call ScriptItemize +// or ScriptStringAnalyse. +// +// Instead, you may choose to save the SCRIPT_DIGITSUBSTITUTE +// structure, and update it only when you receive a +// WM_SETTINGCHANGE message or when a RegNotifyChangeKeyValue +// call in a dedicated thread indicates a change in the registry +// under HKCU\Control Panel\\International. +// +// The normal way to call this function is simply +// +//c SCRIPT_DIGITSUBSTITUTE sds; +//c ScriptRecordDigitSubstitution(LOCALE_USER_DEFAULT, &sds); +// +// Then every time you itemize, you'd use the results like this: +// +//c SCRIPT_CONTROL sc = {0}; +//c SCRIPT_STATE ss = {0}; +// +//c ScriptApplyDigitSubstitution(&sds, &sc, &ss); +// +// +///// ScriptApplyDigitSubstitution +// +// Aplies the digit substitution settings recorded in a +// SCRIPT_DIGIT_SUBSTITUTE structure to the SCRIPT_CONTROL and +// SCRIPT_STATE structures. +// +// The DigitSubstitute field of the SCRIPT_DIGITSUBSTITUTE structure +// is normally set by ScriptRecordDigitSubstitution, however it may +// be replaced by any one of the following values: +// +// +const + SCRIPT_DIGITSUBSTITUTE_CONTEXT = 0; // Substitute to match preceeding letters + SCRIPT_DIGITSUBSTITUTE_NONE = 1; // No substitution + SCRIPT_DIGITSUBSTITUTE_NATIONAL = 2; // Substitute with official national digits + SCRIPT_DIGITSUBSTITUTE_TRADITIONAL = 3; // Substitute with traditional digits of the locale +// +// +//p SCRIPT_DIGITSUBSTITUTE_CONTEXT: Digits U+0030 - U+0039 will be +// substituted according to the language of prior letters. Before +// any letters, digits will be substituted according to the +// TraditionalDigitLangauge field of the SCRIPT_DIGIT_SUBSTITUTE +// structure. This field is normally set to the primary language of +// the Locale passed to ScriptRecordDigitSubstitution. +// +//p SCRIPT_DIGITSUBSTITUTE_NONE: Digits will not be substituted. Unicode +// values U+0030 to U+0039 will be displayed with Arabic (i.e. +// Western) numerals. +// +//p SCRIPT_DIGITSUBSTITUTE_NATIONAL: Digits U+0030 - U+0039 will be +// substituted according to the NationalDigitLangauge field of +// the SCRIPT_DIGIT_SUBSTITUTE structure. This field is normally +// set to the national digits returned for the NLS LCTYPE +// LOCALE_SNATIVEDIGITS by ScriptRecordDigitSubstitution. +// +//p SCRIPT_DIGITSUBSTITUTE_TRADITIONAL: Digits U+0030 - U+0039 will be +// substituted according to the TraditionalDigitLangauge field of +// the SCRIPT_DIGIT_SUBSTITUTE structure. This field is normally +// set to the primary language of the Locale passed to +// ScriptRecordDigitSubstitution. + + +function ScriptApplyDigitSubstitution( + const psds: PScriptDigitSubstitute; // In Digit substitution settings + psc: PScriptControl; // Out Script control structure + pss: PScriptState // Out Script state structure + ): HRESULT; stdcall; + + + + + + +///// +//p psds: Pointer to SCRIPT_DIGITSUBSTITUTE structure recorded earlier. +// If NULL, ScriptApplyDigitSubstitution calls +// ScriptRecordDigitSubstitution with LOCALE_USER_DEFAULT. +// +//p psc: SCRIPT_CONTROL structure. The scContextDigits and uDefaultLanguage +// fields will be updated. +// +//p pss: SCRIPT_CONTROL structure. The ssDigitSubstitute field will be +// updated. +// +//p returns: E_INVALIDARG if the DigitSubstitute field of the +// SCRIPT_DIGITSUBSTITUTE structure is unrecognised, else S_OK; + +var + Usp10IsInstalled: Boolean; + +implementation + +uses + SysUtils; + +const + Usp10DLL = 'usp10.dll'; + +var + Usp10DllModule: HMODULE = 0; + +function GetUsp10DllModule: HMODULE; +begin + if Usp10DllModule = 0 then + begin + Usp10DllModule := SafeLoadLibrary(Usp10DLL); + if Usp10DllModule <= HINSTANCE_ERROR then + Usp10DllModule := 0; + end; + Result := Usp10DllModule; +end; + +procedure GetProcedureAddress(var P: Pointer; const ModuleName, ProcName: string); +begin + if not Assigned(P) then + begin + P := Pointer(GetProcAddress(Usp10DllModule, PAnsiChar(AnsiString(ProcName)))); + if not Assigned(P) or (Usp10DllModule = 0) then + RaiseLastOSError; + end; +end; + +var + _ScriptFreeCache: Pointer = nil; + +function ScriptFreeCache; +begin + if _ScriptFreeCache = nil then + GetProcedureAddress(_ScriptFreeCache, Usp10DLL, 'ScriptFreeCache'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptFreeCache] + end; +end; + +var + _ScriptItemize: Pointer = nil; + +function ScriptItemize; +begin + if _ScriptItemize = nil then + GetProcedureAddress(_ScriptItemize, Usp10DLL, 'ScriptItemize'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptItemize] + end; +end; + +var + _ScriptLayout: Pointer = nil; + +function ScriptLayout; +begin + if _ScriptLayout = nil then + GetProcedureAddress(_ScriptLayout, Usp10DLL, 'ScriptLayout'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptLayout] + end; +end; + +var + _ScriptShape: Pointer = nil; + +function ScriptShape; +begin + if _ScriptShape = nil then + GetProcedureAddress(_ScriptShape, Usp10DLL, 'ScriptShape'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptShape] + end; +end; + +var + _ScriptPlace: Pointer = nil; + +function ScriptPlace; +begin + if _ScriptPlace = nil then + GetProcedureAddress(_ScriptPlace, Usp10DLL, 'ScriptPlace'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptPlace] + end; +end; + +var + _ScriptTextOut: Pointer = nil; + +function ScriptTextOut; +begin + if _ScriptTextOut = nil then + GetProcedureAddress(_ScriptTextOut, Usp10DLL, 'ScriptTextOut'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptTextOut] + end; +end; + +var + _ScriptJustify: Pointer = nil; + +function ScriptJustify; +begin + if _ScriptJustify = nil then + GetProcedureAddress(_ScriptJustify, Usp10DLL, 'ScriptJustify'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptJustify] + end; +end; + +var + _ScriptBreak: Pointer = nil; + +function ScriptBreak; +begin + if _ScriptBreak = nil then + GetProcedureAddress(_ScriptBreak, Usp10DLL, 'ScriptBreak'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptBreak] + end; +end; + +var + _ScriptCPtoX: Pointer = nil; + +function ScriptCPtoX; +begin + if _ScriptCPtoX = nil then + GetProcedureAddress(_ScriptCPtoX, Usp10DLL, 'ScriptCPtoX'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptCPtoX] + end; +end; + +var + _ScriptXtoCP: Pointer = nil; + +function ScriptXtoCP; +begin + if _ScriptXtoCP = nil then + GetProcedureAddress(_ScriptXtoCP, Usp10DLL, 'ScriptXtoCP'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptXtoCP] + end; +end; + +var + _ScriptGetLogicalWidths: Pointer = nil; + +function ScriptGetLogicalWidths; +begin + if _ScriptGetLogicalWidths = nil then + GetProcedureAddress(_ScriptGetLogicalWidths, Usp10DLL, 'ScriptGetLogicalWidths'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptGetLogicalWidths] + end; +end; + +var + _ScriptApplyLogicalWidth: Pointer = nil; + +function ScriptApplyLogicalWidth; +begin + if _ScriptApplyLogicalWidth = nil then + GetProcedureAddress(_ScriptApplyLogicalWidth, Usp10DLL, 'ScriptApplyLogicalWidth'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptApplyLogicalWidth] + end; +end; + +var + _ScriptGetCMap: Pointer = nil; + +function ScriptGetCMap; +begin + if _ScriptGetCMap = nil then + GetProcedureAddress(_ScriptGetCMap, Usp10DLL, 'ScriptGetCMap'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptGetCMap] + end; +end; + +var + _ScriptGetGlyphABCWidth: Pointer = nil; + +function ScriptGetGlyphABCWidth; +begin + if _ScriptGetGlyphABCWidth = nil then + GetProcedureAddress(_ScriptGetGlyphABCWidth, Usp10DLL, 'ScriptGetGlyphABCWidth'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptGetGlyphABCWidth] + end; +end; + +var + _ScriptGetProperties: Pointer = nil; + +function ScriptGetProperties; +begin + if _ScriptGetProperties = nil then + GetProcedureAddress(_ScriptGetProperties, Usp10DLL, 'ScriptGetProperties'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptGetProperties] + end; +end; + +var + _ScriptGetFontProperties: Pointer = nil; + +function ScriptGetFontProperties; +begin + if _ScriptGetFontProperties = nil then + GetProcedureAddress(_ScriptGetFontProperties, Usp10DLL, 'ScriptGetFontProperties'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptGetFontProperties] + end; +end; + +var + _ScriptCacheGetHeight: Pointer = nil; + +function ScriptCacheGetHeight; +begin + if _ScriptCacheGetHeight = nil then + GetProcedureAddress(_ScriptCacheGetHeight, Usp10DLL, 'ScriptCacheGetHeight'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptCacheGetHeight] + end; +end; + +var + _ScriptStringAnalyse: Pointer = nil; + +function ScriptStringAnalyse; +begin + if _ScriptStringAnalyse = nil then + GetProcedureAddress(_ScriptStringAnalyse, Usp10DLL, 'ScriptStringAnalyse'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptStringAnalyse] + end; +end; + +var + _ScriptStringFree: Pointer = nil; + +function ScriptStringFree; +begin + if _ScriptStringFree = nil then + GetProcedureAddress(_ScriptStringFree, Usp10DLL, 'ScriptStringFree'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptStringFree] + end; +end; + +var + _ScriptString_pSize: Pointer = nil; + +function ScriptString_pSize; +begin + if _ScriptString_pSize = nil then + GetProcedureAddress(_ScriptString_pSize, Usp10DLL, 'ScriptString_pSize'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptString_pSize] + end; +end; + +var + _ScriptString_pcOutChars: Pointer = nil; + +function ScriptString_pcOutChars; +begin + if _ScriptString_pcOutChars = nil then + GetProcedureAddress(_ScriptString_pcOutChars, Usp10DLL, 'ScriptString_pcOutChars'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptString_pcOutChars] + end; +end; + +var + _ScriptString_pLogAttr: Pointer = nil; + +function ScriptString_pLogAttr; +begin + if _ScriptString_pLogAttr = nil then + GetProcedureAddress(_ScriptString_pLogAttr, Usp10DLL, 'ScriptString_pLogAttr'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptString_pLogAttr] + end; +end; + +var + _ScriptStringGetOrder: Pointer = nil; + +function ScriptStringGetOrder; +begin + if _ScriptStringGetOrder = nil then + GetProcedureAddress(_ScriptStringGetOrder, Usp10DLL, 'ScriptStringGetOrder'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptStringGetOrder] + end; +end; + +var + _ScriptStringCPtoX: Pointer = nil; + +function ScriptStringCPtoX; +begin + if _ScriptStringCPtoX = nil then + GetProcedureAddress(_ScriptStringCPtoX, Usp10DLL, 'ScriptStringCPtoX'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptStringCPtoX] + end; +end; + +var + _ScriptStringXtoCP: Pointer = nil; + +function ScriptStringXtoCP; +begin + if _ScriptStringXtoCP = nil then + GetProcedureAddress(_ScriptStringXtoCP, Usp10DLL, 'ScriptStringXtoCP'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptStringXtoCP] + end; +end; + +var + _ScriptStringGetLogicalWidths: Pointer = nil; + +function ScriptStringGetLogicalWidths; +begin + if _ScriptStringGetLogicalWidths = nil then + GetProcedureAddress(_ScriptStringGetLogicalWidths, Usp10DLL, 'ScriptStringGetLogicalWidths'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptStringGetLogicalWidths] + end; +end; + +var + _ScriptStringValidate: Pointer = nil; + +function ScriptStringValidate; +begin + if _ScriptStringValidate = nil then + GetProcedureAddress(_ScriptStringValidate, Usp10DLL, 'ScriptStringValidate'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptStringValidate] + end; +end; + +var + _ScriptStringOut: Pointer = nil; + +function ScriptStringOut; +begin + if _ScriptStringOut = nil then + GetProcedureAddress(_ScriptStringOut, Usp10DLL, 'ScriptStringOut'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptStringOut] + end; +end; + +var + _ScriptIsComplex: Pointer = nil; + +function ScriptIsComplex; +begin + if _ScriptIsComplex = nil then + GetProcedureAddress(_ScriptIsComplex, Usp10DLL, 'ScriptIsComplex'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptIsComplex] + end; +end; + +var + _ScriptRecordDigitSubstitution: Pointer = nil; + +function ScriptRecordDigitSubstitution; +begin + if _ScriptRecordDigitSubstitution = nil then + GetProcedureAddress(_ScriptRecordDigitSubstitution, Usp10DLL, 'ScriptRecordDigitSubstitution'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptRecordDigitSubstitution] + end; +end; + +var + _ScriptApplyDigitSubstitution: Pointer = nil; + +function ScriptApplyDigitSubstitution; +begin + if _ScriptApplyDigitSubstitution = nil then + GetProcedureAddress(_ScriptApplyDigitSubstitution, Usp10DLL, 'ScriptApplyDigitSubstitution'); + asm + MOV ESP, EBP + POP EBP + JMP [_ScriptApplyDigitSubstitution] + end; +end; + +initialization + Usp10DllModule := GetUsp10DllModule; + Usp10IsInstalled := Usp10DllModule <> 0; + +finalization + if Usp10DllModule <> 0 then FreeLibrary(Usp10DllModule); + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVBrowser.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVBrowser.pas new file mode 100644 index 000000000..751d90671 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVBrowser.pas @@ -0,0 +1,272 @@ +unit uRESTDWPrivWVBrowser; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + System.Classes, System.Types, Vcl.Forms, System.Math, + {$ELSE} + Classes, Types, Forms, Math, + {$ENDIF} + uRESTDWPrivWVBrowserBase; + +type + {$IFNDEF FPC}{$IFDEF DELPHI16_UP}[ComponentPlatformsAttribute(pidWin32 or pidWin64)]{$ENDIF}{$ENDIF} + /// + /// VCL and LCL version of TWVBrowserBase that puts together all browser procedures, functions, properties and events in one place. + /// It has all you need to create, modify and destroy a web browser. + /// + TWVBrowser = class(TWVBrowserBase) + protected + function GetParentForm : TCustomForm; + + public + procedure MoveFormTo(const x, y: Integer); override; + procedure MoveFormBy(const x, y: Integer); override; + procedure ResizeFormWidthTo(const x : Integer); override; + procedure ResizeFormHeightTo(const y : Integer); override; + procedure SetFormLeftTo(const x : Integer); override; + procedure SetFormTopTo(const y : Integer); override; + + published + property BrowserExecPath; + property UserDataFolder; + property DefaultURL; + property AdditionalBrowserArguments; + property Language; + property TargetCompatibleBrowserVersion; + property AllowSingleSignOnUsingOSPrimaryAccount; + property OnInitializationError; + property OnEnvironmentCompleted; + property OnControllerCompleted; + property OnAfterCreated; + property OnExecuteScriptCompleted; + property OnCapturePreviewCompleted; + property OnNavigationStarting; + property OnNavigationCompleted; + property OnFrameNavigationStarting; + property OnFrameNavigationCompleted; + property OnSourceChanged; + property OnHistoryChanged; + property OnContentLoading; + property OnDocumentTitleChanged; + property OnNewWindowRequested; + property OnWebResourceRequested; + property OnScriptDialogOpening; + property OnPermissionRequested; + property OnProcessFailed; + property OnWebMessageReceived; + property OnContainsFullScreenElementChanged; + property OnWindowCloseRequested; + property OnDevToolsProtocolEventReceived; + property OnZoomFactorChanged; + property OnMoveFocusRequested; + property OnAcceleratorKeyPressed; + property OnGotFocus; + property OnLostFocus; + property OnCursorChanged; + property OnBrowserProcessExited; + property OnRasterizationScaleChanged; + property OnWebResourceResponseReceived; + property OnDOMContentLoaded; + property OnWebResourceResponseViewGetContentCompleted; + property OnGetCookiesCompleted; + property OnTrySuspendCompleted; + property OnFrameCreated; + property OnDownloadStarting; + property OnClientCertificateRequested; + property OnPrintToPdfCompleted; + property OnBytesReceivedChanged; + property OnEstimatedEndTimeChanged; + property OnDownloadStateChanged; + property OnFrameNameChanged; + property OnFrameDestroyed; + property OnCompositionControllerCompleted; + property OnCallDevToolsProtocolMethodCompleted; + property OnAddScriptToExecuteOnDocumentCreatedCompleted; + property OnWidget0CompMsg; + property OnWidget1CompMsg; + property OnRenderCompMsg; + property OnD3DWindowCompMsg; + property OnPrintCompleted; + property OnRetrieveHTMLCompleted; + property OnRetrieveTextCompleted; + property OnRetrieveMHTMLCompleted; + property OnClearCacheCompleted; + property OnClearDataForOriginCompleted; + property OnOfflineCompleted; + property OnIgnoreCertificateErrorsCompleted; + property OnRefreshIgnoreCacheCompleted; + property OnSimulateKeyEventCompleted; + property OnIsMutedChanged; + property OnIsDocumentPlayingAudioChanged; + property OnIsDefaultDownloadDialogOpenChanged; + property OnProcessInfosChanged; + property OnFrameNavigationStarting2; + property OnFrameNavigationCompleted2; + property OnFrameContentLoading; + property OnFrameDOMContentLoaded; + property OnFrameWebMessageReceived; + property OnBasicAuthenticationRequested; + property OnContextMenuRequested; + property OnCustomItemSelected; + property OnStatusBarTextChanged; + property OnFramePermissionRequested; + property OnClearBrowsingDataCompleted; + property OnServerCertificateErrorActionsCompleted; + property OnServerCertificateErrorDetected; + property OnFaviconChanged; + property OnGetFaviconCompleted; + property OnPrintToPdfStreamCompleted; + property OnGetCustomSchemes; + property OnGetNonDefaultPermissionSettingsCompleted; + property OnSetPermissionStateCompleted; + property OnLaunchingExternalUriScheme; + property OnGetProcessExtendedInfosCompleted; + property OnBrowserExtensionRemoveCompleted; + property OnBrowserExtensionEnableCompleted; + property OnProfileAddBrowserExtensionCompleted; + property OnProfileGetBrowserExtensionsCompleted; + property OnProfileDeleted; + property OnExecuteScriptWithResultCompleted; + property OnNonClientRegionChanged; + property OnNotificationReceived; + property OnNotificationCloseRequested; + property OnSaveAsUIShowing; + property OnShowSaveAsUICompleted; + property OnSaveFileSecurityCheckStarting; + property OnScreenCaptureStarting; + property OnFrameScreenCaptureStarting; + property OnFrameChildFrameCreated; + property OnFindActiveMatchIndexChanged; + property OnFindMatchCountChanged; + property OnFindStartCompleted; + property OnDragStarting; + property OnDedicatedWorkerCreated; + property OnDedicatedWorkerCreated2; + property OnDedicatedWorkerDestroying; + property OnDedicatedWorkerWebMessageReceived; + property OnFrameDedicatedWorkerCreated; + property OnServiceWorkerDestroying; + property OnServiceWorkerWebMessageReceived; + property OnServiceWorkerRegistered; + property OnGetServiceWorkerRegistrationsCompleted; + property OnServiceWorkerActivated; + property OnServiceWorkerRegistrationUnregistering; + property OnSharedWorkerCreated; + property OnGetSharedWorkersCompleted; + property OnSharedWorkerDestroying; + end; + +implementation + +function TWVBrowser.GetParentForm : TCustomForm; +var + TempComp : TComponent; +begin + Result := nil; + TempComp := Owner; + + while (TempComp <> nil) do + if (TempComp is TCustomForm) then + begin + Result := TCustomForm(TempComp); + exit; + end + else + TempComp := TempComp.owner; +end; + +procedure TWVBrowser.MoveFormTo(const x, y: Integer); +var + TempForm : TCustomForm; + TempRect : TRect; +begin + TempForm := GetParentForm; + + if (TempForm <> nil) then + begin + TempRect.Left := min(max(x, max(screen.DesktopLeft, 0)), screen.DesktopWidth - TempForm.Width); + TempRect.Top := min(max(y, max(screen.DesktopTop, 0)), screen.DesktopHeight - TempForm.Height); + TempRect.Right := TempRect.Left + TempForm.Width - 1; + TempRect.Bottom := TempRect.Top + TempForm.Height - 1; + + TempForm.SetBounds(TempRect.Left, TempRect.Top, TempRect.Right - TempRect.Left + 1, TempRect.Bottom - TempRect.Top + 1); + end; +end; + +procedure TWVBrowser.MoveFormBy(const x, y: Integer); +var + TempForm : TCustomForm; + TempRect : TRect; +begin + TempForm := GetParentForm; + + if (TempForm <> nil) then + begin + TempRect.Left := min(max(TempForm.Left + x, max(screen.DesktopLeft, 0)), screen.DesktopWidth - TempForm.Width); + TempRect.Top := min(max(TempForm.Top + y, max(screen.DesktopTop, 0)), screen.DesktopHeight - TempForm.Height); + TempRect.Right := TempRect.Left + TempForm.Width - 1; + TempRect.Bottom := TempRect.Top + TempForm.Height - 1; + + TempForm.SetBounds(TempRect.Left, TempRect.Top, TempRect.Right - TempRect.Left + 1, TempRect.Bottom - TempRect.Top + 1); + end; +end; + +procedure TWVBrowser.ResizeFormWidthTo(const x : Integer); +var + TempForm : TCustomForm; + TempX, TempDeltaX : integer; +begin + TempForm := GetParentForm; + + if (TempForm <> nil) then + begin + TempX := max(x, 100); + TempDeltaX := TempForm.Width - TempForm.ClientWidth; + TempForm.Width := TempX + TempDeltaX; + end; +end; + +procedure TWVBrowser.ResizeFormHeightTo(const y : Integer); +var + TempForm : TCustomForm; + TempY, TempDeltaY : integer; +begin + TempForm := GetParentForm; + + if (TempForm <> nil) then + begin + TempY := max(y, 100); + TempDeltaY := TempForm.Height - TempForm.ClientHeight; + TempForm.Height := TempY + TempDeltaY; + end; +end; + +procedure TWVBrowser.SetFormLeftTo(const x : Integer); +var + TempForm : TCustomForm; +begin + TempForm := GetParentForm; + + if (TempForm <> nil) then + TempForm.Left := min(max(x, max(screen.DesktopLeft, 0)), screen.DesktopWidth - TempForm.Width); +end; + +procedure TWVBrowser.SetFormTopTo(const y : Integer); +var + TempForm : TCustomForm; +begin + TempForm := GetParentForm; + + if (TempForm <> nil) then + TempForm.Top := min(max(y, max(screen.DesktopTop, 0)), screen.DesktopHeight - TempForm.Height); +end; + + + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVBrowserBase.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVBrowserBase.pas new file mode 100644 index 000000000..7958cdf35 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVBrowserBase.pas @@ -0,0 +1,8702 @@ +unit uRESTDWPrivWVBrowserBase; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + Winapi.Windows, System.Classes, System.Types, System.UITypes, System.SysUtils, + Winapi.ActiveX, Winapi.Messages, {$IFDEF DELPHI20_UP}System.JSON,{$ENDIF} + {$IFDEF DELPHI21_UP}System.NetEncoding,{$ELSE}Web.HTTPApp,{$ENDIF} + {$ELSE} + Windows, Classes, Types, SysUtils, Graphics, ActiveX, Messages, + {$IFDEF FPC}httpprotocol, CommCtrl, fpjson, jsonparser,{$ENDIF} + {$ENDIF} + uRESTDWPrivWVTypes, uRESTDWPrivWVConstants, uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVLibFunctions, uRESTDWPrivWVLoader, + uRESTDWPrivWVInterfaces, uRESTDWPrivWVEvents, uRESTDWPrivWVCoreWebView2, uRESTDWPrivWVCoreWebView2Settings, + uRESTDWPrivWVCoreWebView2Environment, uRESTDWPrivWVCoreWebView2Controller, + uRESTDWPrivWVCoreWebView2PrintSettings, uRESTDWPrivWVCoreWebView2CompositionController, + uRESTDWPrivWVCoreWebView2CookieManager, uRESTDWPrivWVCoreWebView2Delegates, + uRESTDWPrivWVCoreWebView2Profile, uRESTDWPrivWVCoreWebView2FindOptions, uRESTDWPrivWVCoreWebView2Find; + +type + /// + /// Parent class of TWVBrowser and TWVFMXBrowser that puts together all browser procedures, functions, properties and events in one place. + /// It has all you need to create, modify and destroy a web browser. + /// + TWVBrowserBase = class(TComponent, IWVBrowserEvents) + protected + FCoreWebView2PrintSettings : TCoreWebView2PrintSettings; + FCoreWebView2Settings : TCoreWebView2Settings; + FCoreWebView2Environment : TCoreWebView2Environment; + FCoreWebView2Controller : TCoreWebView2Controller; + FCoreWebView2CompositionController : TCoreWebView2CompositionController; + FCoreWebView2 : TCoreWebView2; + FCoreWebView2Profile : TCoreWebView2Profile; + FCoreWebView2FindOptions : TCoreWebView2FindOptions; + FCoreWebView2Find : TCoreWebView2Find; + FWindowParentHandle : THandle; + FUseDefaultEnvironment : boolean; + FUseCompositionController : boolean; + FDefaultURL : wvstring; + FBrowserExecPath : wvstring; + FUserDataFolder : wvstring; + FIgnoreCertificateErrors : boolean; + FZoomStep : byte; + FOffline : boolean; + FIsNavigating : boolean; + FProfileName : wvstring; + FIsInPrivateModeEnabled : boolean; + FClearBrowsingDataCompletedHandler : ICoreWebView2ClearBrowsingDataCompletedHandler; + FSetPermissionStateCompletedHandler : ICoreWebView2SetPermissionStateCompletedHandler; + FGetNonDefaultPermissionSettingsCompletedHandler : ICoreWebView2GetNonDefaultPermissionSettingsCompletedHandler; + FProfileAddBrowserExtensionCompletedHandler : ICoreWebView2ProfileAddBrowserExtensionCompletedHandler; + FProfileGetBrowserExtensionsCompletedHandler : ICoreWebView2ProfileGetBrowserExtensionsCompletedHandler; + FPreferredTrackingPreventionLevel : TWVTrackingPreventionLevel; + FScriptLocale : wvstring; + FDefaultBackgroundColor : TColor; + FAllowHostInputProcessing : boolean; + + // Fields used to create the environment + FAdditionalBrowserArguments : wvstring; + FLanguage : wvstring; + FTargetCompatibleBrowserVersion : wvstring; + FAllowSingleSignOnUsingOSPrimaryAccount : boolean; + FExclusiveUserDataFolderAccess : boolean; + FCustomCrashReportingEnabled : boolean; + FEnableTrackingPrevention : boolean; + FAreBrowserExtensionsEnabled : boolean; + FChannelSearchKind : TWVChannelSearchKind; + FReleaseChannels : TWVReleaseChannels; + FScrollBarStyle : TWVScrollBarStyle; + + FOldWidget0CompWndPrc : TFNWndProc; + FOldWidget1CompWndPrc : TFNWndProc; + FOldRenderCompWndPrc : TFNWndProc; + FOldD3DWindowCompWndPrc : TFNWndProc; + FWidget0CompStub : Pointer; + FWidget1CompStub : Pointer; + FRenderCompStub : Pointer; + FD3DWindowCompStub : Pointer; + FWidget0CompHWND : THandle; + FWidget1CompHWND : THandle; + FRenderCompHWND : THandle; + FD3DWindowCompHWND : THandle; + + FOnInitializationError : TOnInitializationErrorEvent; + FOnEnvironmentCompleted : TNotifyEvent; + FOnControllerCompleted : TNotifyEvent; + FOnAfterCreated : TNotifyEvent; + FOnExecuteScriptCompleted : TOnExecuteScriptCompletedEvent; + FOnCapturePreviewCompleted : TOnCapturePreviewCompletedEvent; + FOnNavigationStarting : TOnNavigationStartingEvent; + FOnNavigationCompleted : TOnNavigationCompletedEvent; + FOnFrameNavigationStarting : TOnNavigationStartingEvent; + FOnFrameNavigationCompleted : TOnNavigationCompletedEvent; + FOnSourceChanged : TOnSourceChangedEvent; + FOnHistoryChanged : TNotifyEvent; + FOnContentLoading : TOnContentLoadingEvent; + FOnDocumentTitleChanged : TNotifyEvent; + FOnNewWindowRequested : TOnNewWindowRequestedEvent; + FOnWebResourceRequested : TOnWebResourceRequestedEvent; + FOnScriptDialogOpening : TOnScriptDialogOpeningEvent; + FOnPermissionRequested : TOnPermissionRequestedEvent; + FOnProcessFailed : TOnProcessFailedEvent; + FOnWebMessageReceived : TOnWebMessageReceivedEvent; + FOnContainsFullScreenElementChanged : TNotifyEvent; + FOnWindowCloseRequested : TNotifyEvent; + FOnDevToolsProtocolEventReceived : TOnDevToolsProtocolEventReceivedEvent; + FOnZoomFactorChanged : TNotifyEvent; + FOnMoveFocusRequested : TOnMoveFocusRequestedEvent; + FOnAcceleratorKeyPressed : TOnAcceleratorKeyPressedEvent; + FOnGotFocus : TNotifyEvent; + FOnLostFocus : TNotifyEvent; + FOnCursorChanged : TNotifyEvent; + FOnBrowserProcessExited : TOnBrowserProcessExitedEvent; + FOnRasterizationScaleChanged : TNotifyEvent; + FOnWebResourceResponseReceived : TOnWebResourceResponseReceivedEvent; + FOnDOMContentLoaded : TOnDOMContentLoadedEvent; + FOnWebResourceResponseViewGetContentCompleted : TOnWebResourceResponseViewGetContentCompletedEvent; + FOnGetCookiesCompleted : TOnGetCookiesCompletedEvent; + FOnTrySuspendCompleted : TOnTrySuspendCompletedEvent; + FOnFrameCreated : TOnFrameCreatedEvent; + FOnDownloadStarting : TOnDownloadStartingEvent; + FOnClientCertificateRequested : TOnClientCertificateRequestedEvent; + FOnPrintToPdfCompleted : TOnPrintToPdfCompletedEvent; + FOnBytesReceivedChanged : TOnBytesReceivedChangedEvent; + FOnEstimatedEndTimeChanged : TOnEstimatedEndTimeChangedEvent; + FOnDownloadStateChanged : TOnDownloadStateChangedEvent; + FOnFrameNameChanged : TOnFrameNameChangedEvent; + FOnFrameDestroyed : TOnFrameDestroyedEvent; + FOnCompositionControllerCompleted : TNotifyEvent; + FOnCallDevToolsProtocolMethodCompleted : TOnCallDevToolsProtocolMethodCompletedEvent; + FOnAddScriptToExecuteOnDocumentCreatedCompleted : TOnAddScriptToExecuteOnDocumentCreatedCompletedEvent; + FOnWidget0CompMsg : TOnCompMsgEvent; + FOnWidget1CompMsg : TOnCompMsgEvent; + FOnRenderCompMsg : TOnCompMsgEvent; + FOnD3DWindowCompMsg : TOnCompMsgEvent; + FOnPrintCompleted : TOnPrintCompletedEvent; + FOnRetrieveHTMLCompleted : TOnRetrieveHTMLCompletedEvent; + FOnRetrieveTextCompleted : TOnRetrieveTextCompletedEvent; + FOnRetrieveMHTMLCompleted : TOnRetrieveMHTMLCompletedEvent; + FOnClearCacheCompleted : TOnClearCacheCompletedEvent; + FOnClearDataForOriginCompleted : TOnClearDataForOriginCompletedEvent; + FOnOfflineCompleted : TOnOfflineCompletedEvent; + FOnIgnoreCertificateErrorsCompleted : TOnIgnoreCertificateErrorsCompletedEvent; + FOnRefreshIgnoreCacheCompleted : TOnRefreshIgnoreCacheCompletedEvent; + FOnSimulateKeyEventCompleted : TOnSimulateKeyEventCompletedEvent; + FOnIsMutedChanged : TOnIsMutedChangedEvent; + FOnIsDocumentPlayingAudioChanged : TOnIsDocumentPlayingAudioChangedEvent; + FOnIsDefaultDownloadDialogOpenChanged : TOnIsDefaultDownloadDialogOpenChangedEvent; + FOnProcessInfosChanged : TOnProcessInfosChangedEvent; + FOnFrameNavigationStarting2 : TOnFrameNavigationStartingEvent; + FOnFrameNavigationCompleted2 : TOnFrameNavigationCompletedEvent; + FOnFrameContentLoading : TOnFrameContentLoadingEvent; + FOnFrameDOMContentLoaded : TOnFrameDOMContentLoadedEvent; + FOnFrameWebMessageReceived : TOnFrameWebMessageReceivedEvent; + FOnBasicAuthenticationRequested : TOnBasicAuthenticationRequestedEvent; + FOnContextMenuRequested : TOnContextMenuRequestedEvent; + FOnCustomItemSelected : TOnCustomItemSelectedEvent; + FOnStatusBarTextChanged : TOnStatusBarTextChangedEvent; + FOnFramePermissionRequested : TOnFramePermissionRequestedEvent; + FOnClearBrowsingDataCompleted : TOnClearBrowsingDataCompletedEvent; + FOnServerCertificateErrorActionsCompleted : TOnServerCertificateErrorActionsCompletedEvent; + FOnServerCertificateErrorDetected : TOnServerCertificateErrorDetectedEvent; + FOnFaviconChanged : TOnFaviconChangedEvent; + FOnGetFaviconCompleted : TOnGetFaviconCompletedEvent; + FOnPrintToPdfStreamCompleted : TOnPrintToPdfStreamCompletedEvent; + FOnGetCustomSchemes : TOnGetCustomSchemesEvent; + FOnGetNonDefaultPermissionSettingsCompleted : TOnGetNonDefaultPermissionSettingsCompletedEvent; + FOnSetPermissionStateCompleted : TOnSetPermissionStateCompletedEvent; + FOnLaunchingExternalUriScheme : TOnLaunchingExternalUriSchemeEvent; + FOnGetProcessExtendedInfosCompleted : TOnGetProcessExtendedInfosCompletedEvent; + FOnBrowserExtensionRemoveCompleted : TOnBrowserExtensionRemoveCompletedEvent; + FOnBrowserExtensionEnableCompleted : TOnBrowserExtensionEnableCompletedEvent; + FOnProfileAddBrowserExtensionCompleted : TOnProfileAddBrowserExtensionCompletedEvent; + FOnProfileGetBrowserExtensionsCompleted : TOnProfileGetBrowserExtensionsCompletedEvent; + FOnProfileDeleted : TOnProfileDeletedEvent; + FOnExecuteScriptWithResultCompleted : TOnExecuteScriptWithResultCompletedEvent; + FOnNonClientRegionChanged : TOnNonClientRegionChangedEvent; + FOnNotificationReceived : TOnNotificationReceivedEvent; + FOnNotificationCloseRequested : TOnNotificationCloseRequestedEvent; + FOnSaveAsUIShowing : TOnSaveAsUIShowingEvent; + FOnShowSaveAsUICompleted : TOnShowSaveAsUICompletedEvent; + FOnSaveFileSecurityCheckStarting : TOnSaveFileSecurityCheckStartingEvent; + FOnScreenCaptureStarting : TOnScreenCaptureStartingEvent; + FOnFrameScreenCaptureStarting : TOnFrameScreenCaptureStartingEvent; + FOnFrameChildFrameCreated : TOnFrameChildFrameCreatedEvent; + FOnFindActiveMatchIndexChanged : TOnFindActiveMatchIndexChangedEvent; + FOnFindMatchCountChanged : TOnFindMatchCountChangedEvent; + FOnFindStartCompleted : TOnFindStartCompletedEvent; + FOnDragStarting : TOnDragStartingEvent; + FOnDedicatedWorkerCreated : TOnDedicatedWorkerCreatedEvent; + FOnDedicatedWorkerCreated2 : TOnDedicatedWorkerCreated2Event; + FOnDedicatedWorkerDestroying : TOnDedicatedWorkerDestroyingEvent; + FOnDedicatedWorkerWebMessageReceived : TOnDedicatedWorkerWebMessageReceivedEvent; + FOnFrameDedicatedWorkerCreated : TOnFrameDedicatedWorkerCreatedEvent; + FOnServiceWorkerDestroying : TOnServiceWorkerDestroyingEvent; + FOnServiceWorkerWebMessageReceived : TOnServiceWorkerWebMessageReceivedEvent; + FOnServiceWorkerRegistered : TOnServiceWorkerRegisteredEvent; + FOnGetServiceWorkerRegistrationsCompleted : TOnGetServiceWorkerRegistrationsCompletedEvent; + FOnServiceWorkerActivated : TOnServiceWorkerActivatedEvent; + FOnServiceWorkerRegistrationUnregistering : TOnServiceWorkerRegistrationUnregisteringEvent; + FOnSharedWorkerCreated : TOnSharedWorkerCreatedEvent; + FOnGetSharedWorkersCompleted : TOnGetSharedWorkersCompletedEvent; + FOnSharedWorkerDestroying : TOnSharedWorkerDestroyingEvent; + + function GetBrowserProcessID : cardinal; + function GetBrowserVersionInfo : wvstring; + function GetCanGoBack : boolean; + function GetCanGoForward : boolean; + function GetContainsFullScreenElement : boolean; + function GetDocumentTitle : wvstring; + function GetSource : wvstring; + function GetCookieManager : ICoreWebView2CookieManager; + function GetInitialized : boolean; + function GetZoomFactor : double; + function GetZoomPct : double; + function GetBuiltInErrorPageEnabled : boolean; + function GetDefaultContextMenusEnabled : boolean; + function GetDefaultScriptDialogsEnabled : boolean; + function GetDevToolsEnabled : boolean; + function GetScriptEnabled : boolean; + function GetStatusBarEnabled : boolean; + function GetWebMessageEnabled : boolean; + function GetZoomControlEnabled : boolean; + function GetIsVisible : boolean; + function GetBounds : TRect; + function GetParentWindow : THandle; + function GetDefaultBackgroundColor : TColor; + function GetRasterizationScale : double; + function GetShouldDetectMonitorScaleChanges : boolean; + function GetBoundsMode : TWVBoundsMode; + function GetAreHostObjectsAllowed : boolean; + function GetUserAgent : wvstring; + function GetAreBrowserAcceleratorKeysEnabled : boolean; + function GetIsPasswordAutosaveEnabled : boolean; + function GetIsGeneralAutofillEnabled : boolean; + function GetIsPinchZoomEnabled : boolean; + function GetIsSwipeNavigationEnabled : boolean; + function GetIsSuspended: boolean; + function GetUserDataFolder: wvstring; + function GetRootVisualTarget : IUnknown; + function GetCursor : HCURSOR; + function GetSystemCursorID : cardinal; + function GetAutomationProvider : IUnknown; + function GetProcessInfos : ICoreWebView2ProcessInfoCollection; + function GetIsMuted : boolean; + function GetIsDocumentPlayingAudio : boolean; + function GetIsDefaultDownloadDialogOpen : boolean; + function GetDefaultDownloadDialogCornerAlignment : TWVDefaultDownloadDialogCornerAlignment; + function GetDefaultDownloadDialogMargin : TPoint; + function GetStatusBarText : wvstring; + function GetAllowExternalDrop : boolean; + function GetHiddenPdfToolbarItems : TWVPDFToolbarItems; + function GetIsReputationCheckingRequired : boolean; + function GetIsNonClientRegionSupportEnabled : boolean; + function GetFaviconURI : wvstring; + function GetScreenScale : single; virtual; + function GetProfileName : wvstring; + function GetIsInPrivateModeEnabled : boolean; + function GetProfilePath : wvstring; + function GetDefaultDownloadFolderPath : wvstring; + function GetPreferredColorScheme : TWVPreferredColorScheme; + function GetPreferredTrackingPreventionLevel : TWVTrackingPreventionLevel; + function GetProfileCookieManager : ICoreWebView2CookieManager; + function GetProfileIsPasswordAutosaveEnabled : boolean; + function GetProfileIsGeneralAutofillEnabled : boolean; + function GetMemoryUsageTargetLevel : TWVMemoryUsageTargetLevel; + function GetFrameID : cardinal; + function GetAreWebViewScriptApisEnabledForServiceWorkers : boolean; + function GetServiceWorkerManager : ICoreWebView2ServiceWorkerManager; + function GetSharedWorkerManager : ICoreWebView2SharedWorkerManager; + + procedure SetBuiltInErrorPageEnabled(aValue: boolean); + procedure SetDefaultContextMenusEnabled(aValue: boolean); + procedure SetDefaultScriptDialogsEnabled(aValue: boolean); + procedure SetDevToolsEnabled(aValue: boolean); + procedure SetScriptEnabled(aValue: boolean); + procedure SetStatusBarEnabled(aValue: boolean); + procedure SetWebMessageEnabled(aValue: boolean); + procedure SetZoomControlEnabled(aValue: boolean); + procedure SetZoomFactor(const aValue: Double); + procedure SetZoomPct(const aValue : double); + procedure SetZoomStep(aValue : byte); + procedure SetIsVisible(aValue : boolean); + procedure SetBounds(aValue : TRect); + procedure SetParentWindow(aValue : THandle); + procedure SetDefaultBackgroundColor(const aValue : TColor); + procedure SetRasterizationScale(const aValue : double); + procedure SetShouldDetectMonitorScaleChanges(aValue : boolean); + procedure SetBoundsMode(aValue : TWVBoundsMode); + procedure SetAreHostObjectsAllowed(aValue : boolean); + procedure SetUserAgent(const aValue : wvstring); + procedure SetAreBrowserAcceleratorKeysEnabled(aValue : boolean); + procedure SetIsPasswordAutosaveEnabled(aValue : boolean); + procedure SetIsGeneralAutofillEnabled(aValue : boolean); + procedure SetIsPinchZoomEnabled(aValue : boolean); + procedure SetIsSwipeNavigationEnabled(aValue : boolean); + procedure SetOffline(aValue : boolean); + procedure SetIgnoreCertificateErrors(aValue : boolean); + procedure SetRootVisualTarget(const aValue : IUnknown); + procedure SetIsMuted(aValue : boolean); + procedure SetDefaultDownloadDialogCornerAlignment(aValue : TWVDefaultDownloadDialogCornerAlignment); + procedure SetDefaultDownloadDialogMargin(aValue : TPoint); + procedure SetAllowExternalDrop(aValue : boolean); + procedure SetHiddenPdfToolbarItems(aValue : TWVPDFToolbarItems); + procedure SetIsReputationCheckingRequired(aValue : boolean); + procedure SetIsNonClientRegionSupportEnabled(aValue : boolean); + procedure SetProfileName(const aValue : wvstring); + procedure SetDefaultDownloadFolderPath(const aValue : wvstring); + procedure SetPreferredColorScheme(const aValue : TWVPreferredColorScheme); + procedure SetPreferredTrackingPreventionLevel(const aValue : TWVTrackingPreventionLevel); + procedure SetProfileIsPasswordAutosaveEnabled(aValue : boolean); + procedure SetProfileIsGeneralAutofillEnabled(aValue : boolean); + procedure SetMemoryUsageTargetLevel(aValue : TWVMemoryUsageTargetLevel); + procedure SetAreWebViewScriptApisEnabledForServiceWorkers(aValue : boolean); + + function CreateEnvironment : boolean; + function CreateCompositionController: boolean; + function CreateController : boolean; + + procedure DestroyEnvironment; + procedure DestroyController; + procedure DestroyCompositionController; + procedure DestroyWebView; + procedure DestroyProfile; + procedure DestroyFindOptions; + procedure DestroyFind; + procedure DestroySettings; + procedure DestroyPrintSettings; + + procedure CalculateZoomStep; + procedure UpdateZoomStep(aInc : boolean); + procedure UpdateZoomPct(const aValue : double); + + procedure CreateStub(const aMethod : TWndMethod; var aStub : Pointer); + procedure FreeAndNilStub(var aStub : pointer); + function InstallCompWndProc(aWnd: THandle; aStub: Pointer): TFNWndProc; + procedure RestoreCompWndProc(var aOldWnd: THandle; aNewWnd: THandle; var aProc: TFNWndProc); + procedure CallOldCompWndProc(aProc: TFNWndProc; aWnd: THandle; var aMessage: TMessage); + procedure Widget0CompWndProc(var aMessage: TMessage); + procedure Widget1CompWndProc(var aMessage: TMessage); + procedure RenderCompWndProc(var aMessage: TMessage); + procedure D3DWindowCompWndProc(var aMessage: TMessage); + procedure RestoreOldCompWndProc; + procedure ReplaceWndProcs; + + function ExtractJSONData(const aJSON: wvstring; var aData: wvstring) : boolean; virtual; + function ExtractEncodedJSON(const aJSON: wvstring): wvstring; + + function EnvironmentCompletedHandler_Invoke(errorCode: HRESULT; const result_: ICoreWebView2Environment): HRESULT; + function ControllerCompletedHandler_Invoke(errorCode: HRESULT; const result_: ICoreWebView2Controller): HRESULT; + function ExecuteScriptCompletedHandler_Invoke(errorCode: HRESULT; result_: PWideChar; aExecutionID : integer): HRESULT; + function CapturePreviewCompletedHandler_Invoke(errorCode: HRESULT): HRESULT; + function NavigationStartingEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NavigationStartingEventArgs): HRESULT; + function NavigationCompletedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NavigationCompletedEventArgs): HRESULT; + function FrameNavigationStartingEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NavigationStartingEventArgs): HRESULT; + function FrameNavigationCompletedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NavigationCompletedEventArgs): HRESULT; + function SourceChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2SourceChangedEventArgs): HRESULT; + function HistoryChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HRESULT; + function ContentLoadingEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ContentLoadingEventArgs): HRESULT; + function DocumentTitleChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HRESULT; + function NewWindowRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NewWindowRequestedEventArgs): HRESULT; + function WebResourceRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2WebResourceRequestedEventArgs): HRESULT; + function ScriptDialogOpeningEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ScriptDialogOpeningEventArgs): HRESULT; + function PermissionRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2PermissionRequestedEventArgs): HRESULT; + function ProcessFailedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ProcessFailedEventArgs): HRESULT; + function WebMessageReceivedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2WebMessageReceivedEventArgs): HRESULT; + function ContainsFullScreenElementChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HRESULT; + function WindowCloseRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HRESULT; + function DevToolsProtocolEventReceivedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DevToolsProtocolEventReceivedEventArgs; const aEventName : wvstring; aEventID : integer): HRESULT; + function ZoomFactorChangedEventHandler_Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HRESULT; + function MoveFocusRequestedEventHandler_Invoke(const sender: ICoreWebView2Controller; const args: ICoreWebView2MoveFocusRequestedEventArgs): HRESULT; + function AcceleratorKeyPressedEventHandler_Invoke(const sender: ICoreWebView2Controller; const args: ICoreWebView2AcceleratorKeyPressedEventArgs): HRESULT; + function GotFocusEventHandler_Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HRESULT; + function LostFocusEventHandler_Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HRESULT; + function CreateCoreWebView2CompositionControllerCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2CompositionController): HRESULT; + function CursorChangedEventHandler_Invoke(const sender: ICoreWebView2CompositionController; const args: IUnknown): HRESULT; + function BrowserProcessExitedEventHandler_Invoke(const sender: ICoreWebView2Environment; const args: ICoreWebView2BrowserProcessExitedEventArgs): HRESULT; + function RasterizationScaleChangedEventHandler_Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HRESULT; + function WebResourceResponseReceivedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2WebResourceResponseReceivedEventArgs): HRESULT; + function DOMContentLoadedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DOMContentLoadedEventArgs): HRESULT; + function WebResourceResponseViewGetContentCompletedHandler_Invoke(errorCode: HResult; const result_: IStream; aResourceID : integer): HRESULT; + function GetCookiesCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2CookieList): HRESULT; + function TrySuspendCompletedHandler_Invoke(errorCode: HResult; result_: Integer): HRESULT; + function FrameCreatedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2FrameCreatedEventArgs): HRESULT; + function DownloadStartingEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DownloadStartingEventArgs): HRESULT; + function ClientCertificateRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ClientCertificateRequestedEventArgs): HRESULT; + function PrintToPdfCompletedHandler_Invoke(errorCode: HResult; result_: Integer): HRESULT; + function BytesReceivedChangedEventHandler_Invoke(const sender: ICoreWebView2DownloadOperation; const args: IUnknown; aDownloadID : integer): HRESULT; + function EstimatedEndTimeChangedEventHandler_Invoke(const sender: ICoreWebView2DownloadOperation; const args: IUnknown; aDownloadID : integer): HRESULT; + function StateChangedEventHandler_Invoke(const sender: ICoreWebView2DownloadOperation; const args: IUnknown; aDownloadID : integer): HRESULT; + function FrameNameChangedEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: IUnknown; aFrameID : cardinal): HRESULT; + function FrameDestroyedEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: IUnknown; aFrameID : cardinal): HRESULT; + function CallDevToolsProtocolMethodCompletedHandler_Invoke(errorCode: HResult; result_: PWideChar; aExecutionID : integer): HRESULT; + function AddScriptToExecuteOnDocumentCreatedCompletedHandler_Invoke(errorCode: HResult; result_: PWideChar): HRESULT; + function IsMutedChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HRESULT; + function IsDocumentPlayingAudioChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HRESULT; + function IsDefaultDownloadDialogOpenChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HRESULT; + function ProcessInfosChangedEventHandler_Invoke(const sender: ICoreWebView2Environment; const args: IUnknown): HRESULT; + function FrameNavigationStartingEventHandler2_Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2NavigationStartingEventArgs; aFrameID: cardinal): HRESULT; + function FrameNavigationCompletedEventHandler2_Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2NavigationCompletedEventArgs; aFrameID: cardinal): HRESULT; + function FrameContentLoadingEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2ContentLoadingEventArgs; aFrameID: cardinal): HRESULT; + function FrameDOMContentLoadedEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2DOMContentLoadedEventArgs; aFrameID: cardinal): HRESULT; + function FrameWebMessageReceivedEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2WebMessageReceivedEventArgs; aFrameID: cardinal): HRESULT; + function BasicAuthenticationRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2BasicAuthenticationRequestedEventArgs): HRESULT; + function ContextMenuRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ContextMenuRequestedEventArgs): HRESULT; + function CustomItemSelectedEventHandler_Invoke(const sender: ICoreWebView2ContextMenuItem; const args: IUnknown): HRESULT; + function StatusBarTextChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HRESULT; + function FramePermissionRequestedEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2PermissionRequestedEventArgs2; aFrameID: cardinal): HRESULT; + function ClearBrowsingDataCompletedHandler_Invoke(errorCode: HResult): HRESULT; + function ClearServerCertificateErrorActionsCompletedHandler_Invoke(errorCode: HResult): HRESULT; + function ServerCertificateErrorDetectedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ServerCertificateErrorDetectedEventArgs): HRESULT; + function FaviconChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HRESULT; + function GetFaviconCompletedHandler_Invoke(errorCode: HResult; const result_: IStream): HRESULT; + function PrintCompletedHandler_Invoke(errorCode: HResult; result_: COREWEBVIEW2_PRINT_STATUS): HRESULT; + function PrintToPdfStreamCompletedHandler_Invoke(errorCode: HResult; const result_: IStream): HRESULT; + function GetNonDefaultPermissionSettingsCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2PermissionSettingCollectionView): HRESULT; + function SetPermissionStateCompletedHandler_Invoke(errorCode: HResult): HRESULT; + function LaunchingExternalUriSchemeEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2LaunchingExternalUriSchemeEventArgs): HRESULT; + function GetProcessExtendedInfosCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2ProcessExtendedInfoCollection): HRESULT; + function BrowserExtensionRemoveCompletedHandler_Invoke(errorCode: HResult; const aExtensionID: wvstring): HRESULT; + function BrowserExtensionEnableCompletedHandler_Invoke(errorCode: HResult; const aExtensionID: wvstring): HRESULT; + function ProfileAddBrowserExtensionCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2BrowserExtension): HRESULT; + function ProfileGetBrowserExtensionsCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2BrowserExtensionList): HRESULT; + function ProfileDeletedEventHandler_Invoke(const sender: ICoreWebView2Profile; const args: IUnknown): HRESULT; + function ExecuteScriptWithResultCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2ExecuteScriptResult; aExecutionID : integer): HRESULT; + function NonClientRegionChangedEventHandler_Invoke(const sender: ICoreWebView2CompositionController; const args: ICoreWebView2NonClientRegionChangedEventArgs): HRESULT; + function NotificationReceivedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NotificationReceivedEventArgs): HRESULT; + function NotificationCloseRequestedEventHandler_Invoke(const sender: ICoreWebView2Notification; const args: IUnknown): HRESULT; + function SaveAsUIShowingEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2SaveAsUIShowingEventArgs): HRESULT; + function ShowSaveAsUICompletedHandler_Invoke(errorCode: HResult; result_: COREWEBVIEW2_SAVE_AS_UI_RESULT): HRESULT; + function SaveFileSecurityCheckStartingEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2SaveFileSecurityCheckStartingEventArgs): HRESULT; + function ScreenCaptureStartingEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ScreenCaptureStartingEventArgs): HRESULT; + function FrameScreenCaptureStartingEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2ScreenCaptureStartingEventArgs; aFrameID: cardinal): HRESULT; + function FrameChildFrameCreatedEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2FrameCreatedEventArgs; aFrameID: cardinal): HRESULT; + function FindActiveMatchIndexChangedEventHandler_Invoke(const sender: ICoreWebView2Find; const args: IUnknown): HRESULT; + function FindMatchCountChangedEventHandler_Invoke(const sender: ICoreWebView2Find; const args: IUnknown): HRESULT; + function FindStartCompletedHandler_Invoke(errorCode: HResult): HRESULT; + function DragStartingEventHandler_Invoke(const sender: ICoreWebView2CompositionController; const args: ICoreWebView2DragStartingEventArgs): HRESULT; + function DedicatedWorkerCreatedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DedicatedWorkerCreatedEventArgs): HRESULT; + function DedicatedWorkerDedicatedWorkerCreatedEventHandler_Invoke(const sender: ICoreWebView2DedicatedWorker; const args: ICoreWebView2DedicatedWorkerCreatedEventArgs; aWorkerID: cardinal): HRESULT; + function DedicatedWorkerDestroyingEventHandler_Invoke(const sender: ICoreWebView2DedicatedWorker; const args: IUnknown; aWorkerID: cardinal): HRESULT; + function DedicatedWorkerWebMessageReceivedEventHandler_Invoke(const sender: ICoreWebView2DedicatedWorker; const args: ICoreWebView2WebMessageReceivedEventArgs; aWorkerID: cardinal): HRESULT; + function FrameDedicatedWorkerCreatedEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2DedicatedWorkerCreatedEventArgs; aFrameID: cardinal): HRESULT; + function ServiceWorkerDestroyingEventHandler_Invoke(const sender: ICoreWebView2ServiceWorker; const args: IUnknown; aWorkerID: cardinal): HRESULT; + function ServiceWorkerWebMessageReceivedEventHandler_Invoke(const sender: ICoreWebView2ServiceWorker; const args: ICoreWebView2WebMessageReceivedEventArgs; aWorkerID: cardinal): HRESULT; + function ServiceWorkerRegisteredEventHandler_Invoke(const sender: ICoreWebView2ServiceWorkerManager; const args: ICoreWebView2ServiceWorkerRegisteredEventArgs): HRESULT; + function GetServiceWorkerRegistrationsCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2ServiceWorkerRegistrationCollectionView): HRESULT; + function ServiceWorkerActivatedEventHandler_Invoke(const sender: ICoreWebView2ServiceWorkerRegistration; const args: ICoreWebView2ServiceWorkerActivatedEventArgs): HRESULT; + function ServiceWorkerRegistrationUnregisteringEventHandler_Invoke(const sender: ICoreWebView2ServiceWorkerRegistration; const args: IUnknown): HRESULT; + function SharedWorkerCreatedEventHandler_Invoke(const sender: ICoreWebView2SharedWorkerManager; const args: ICoreWebView2SharedWorkerCreatedEventArgs): HRESULT; + function GetSharedWorkersCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2SharedWorkerCollectionView): HRESULT; + function SharedWorkerDestroyingEventHandler_Invoke(const sender: ICoreWebView2SharedWorker; const args: IUnknown; aWorkerID: cardinal): HRESULT; + + procedure doOnInitializationError(aErrorCode: HRESULT; const aErrorMessage: wvstring); virtual; + procedure doOnEnvironmentCompleted; virtual; + procedure doOnControllerCompleted; virtual; + procedure doOnAfterCreated; virtual; + procedure doOnExecuteScriptCompleted(aErrorCode: HRESULT; const aResultObjectAsJson: wvstring; aExecutionID : integer); virtual; + procedure doCapturePreviewCompleted(aErrorCode: HRESULT); virtual; + procedure doOnNavigationStarting(const sender: ICoreWebView2; const args: ICoreWebView2NavigationStartingEventArgs); virtual; + procedure doOnNavigationCompleted(const sender: ICoreWebView2; const args: ICoreWebView2NavigationCompletedEventArgs); virtual; + procedure doOnFrameNavigationStarting(const sender: ICoreWebView2; const args: ICoreWebView2NavigationStartingEventArgs); virtual; + procedure doOnFrameNavigationCompleted(const sender: ICoreWebView2; const args: ICoreWebView2NavigationCompletedEventArgs); virtual; + procedure doOnSourceChanged(const sender: ICoreWebView2; const args: ICoreWebView2SourceChangedEventArgs); virtual; + procedure doOnHistoryChanged(const sender: ICoreWebView2); virtual; + procedure doOnContentLoading(const sender: ICoreWebView2; const args: ICoreWebView2ContentLoadingEventArgs); virtual; + procedure doOnDocumentTitleChanged(const sender: ICoreWebView2); virtual; + procedure doOnNewWindowRequested(const sender: ICoreWebView2; const args: ICoreWebView2NewWindowRequestedEventArgs); virtual; + procedure doOnWebResourceRequested(const sender: ICoreWebView2; const args: ICoreWebView2WebResourceRequestedEventArgs); virtual; + procedure doOnScriptDialogOpening(const sender: ICoreWebView2; const args: ICoreWebView2ScriptDialogOpeningEventArgs); virtual; + procedure doOnPermissionRequested(const sender: ICoreWebView2; const args: ICoreWebView2PermissionRequestedEventArgs); virtual; + procedure doOnProcessFailed(const sender: ICoreWebView2; const args: ICoreWebView2ProcessFailedEventArgs); virtual; + procedure doOnWebMessageReceived(const sender: ICoreWebView2; const args: ICoreWebView2WebMessageReceivedEventArgs); virtual; + procedure doOnContainsFullScreenElementChanged(const sender: ICoreWebView2); virtual; + procedure doOnWindowCloseRequested(const sender: ICoreWebView2); virtual; + procedure doOnDevToolsProtocolEventReceived(const sender: ICoreWebView2; const args: ICoreWebView2DevToolsProtocolEventReceivedEventArgs; const aEventName : wvstring; aEventID : integer); virtual; + procedure doOnZoomFactorChanged(const sender: ICoreWebView2Controller); virtual; + procedure doOnMoveFocusRequested(const sender: ICoreWebView2Controller; const args: ICoreWebView2MoveFocusRequestedEventArgs); virtual; + procedure doOnAcceleratorKeyPressed(const sender: ICoreWebView2Controller; const args: ICoreWebView2AcceleratorKeyPressedEventArgs); virtual; + procedure doOnGotFocus(const sender: ICoreWebView2Controller); virtual; + procedure doOnLostFocus(const sender: ICoreWebView2Controller); virtual; + procedure doOnCompositionControllerCompleted; virtual; + procedure doOnCursorChangedEvent(const sender: ICoreWebView2CompositionController); virtual; + procedure doOnBrowserProcessExitedEvent(const sender: ICoreWebView2Environment; const args: ICoreWebView2BrowserProcessExitedEventArgs); virtual; + procedure doOnRasterizationScaleChangedEvent(const sender: ICoreWebView2Controller); virtual; + procedure doOnWebResourceResponseReceivedEvent(const sender: ICoreWebView2; const args: ICoreWebView2WebResourceResponseReceivedEventArgs); virtual; + procedure doOnDOMContentLoadedEvent(const sender: ICoreWebView2; const args: ICoreWebView2DOMContentLoadedEventArgs); virtual; + procedure doOnWebResourceResponseViewGetContentCompletedEvent(errorCode: HResult; const result_: IStream; aResourceID : integer); virtual; + procedure doOnGetCookiesCompletedEvent(errorCode: HResult; const result_: ICoreWebView2CookieList); virtual; + procedure doOnTrySuspendCompletedEvent(errorCode: HResult; result_: Integer); virtual; + procedure doOnFrameCreatedEvent(const sender: ICoreWebView2; const args: ICoreWebView2FrameCreatedEventArgs); virtual; + procedure doOnDownloadStartingEvent(const sender: ICoreWebView2; const args: ICoreWebView2DownloadStartingEventArgs); virtual; + procedure doOnClientCertificateRequestedEvent(const sender: ICoreWebView2; const args: ICoreWebView2ClientCertificateRequestedEventArgs); virtual; + procedure doOnPrintToPdfCompletedEvent(errorCode: HResult; result_: Integer); virtual; + procedure doOnBytesReceivedChangedEventEvent(const sender: ICoreWebView2DownloadOperation; const args: IUnknown; aDownloadID : integer); virtual; + procedure doOnEstimatedEndTimeChangedEvent(const sender: ICoreWebView2DownloadOperation; const args: IUnknown; aDownloadID : integer); virtual; + procedure doOnStateChangedEvent(const sender: ICoreWebView2DownloadOperation; const args: IUnknown; aDownloadID : integer); virtual; + procedure doOnFrameNameChangedEvent(const sender: ICoreWebView2Frame; const args: IUnknown; aFrameID : cardinal); virtual; + procedure doOnFrameDestroyedEvent(const sender: ICoreWebView2Frame; const args: IUnknown; aFrameID : cardinal); virtual; + procedure doOnCallDevToolsProtocolMethodCompletedEvent(aErrorCode: HRESULT; const aResult: wvstring; aExecutionID : integer); virtual; + procedure doOnAddScriptToExecuteOnDocumentCreatedCompletedEvent(aErrorCode: HRESULT; const aResult : wvstring); virtual; + procedure doOnRetrieveHTMLCompleted(aErrorCode: HRESULT; const aResultObjectAsJson: wvstring); virtual; + procedure doOnRetrieveTextCompleted(aErrorCode: HRESULT; const aResultObjectAsJson: wvstring); virtual; + procedure doOnRetrieveMHTMLCompleted(aErrorCode: HRESULT; const aReturnObjectAsJson: wvstring); virtual; + procedure doOnClearCacheCompleted(aErrorCode: HRESULT); virtual; + procedure doOnClearDataForOriginCompleted(aErrorCode: HRESULT); virtual; + procedure doOnOfflineCompleted(aErrorCode: HRESULT); virtual; + procedure doOnIgnoreCertificateErrorsCompleted(aErrorCode: HRESULT); virtual; + procedure doOnRefreshIgnoreCacheCompleted(aErrorCode: HRESULT; const aResultObjectAsJson: wvstring); virtual; + procedure doOnSimulateKeyEventCompleted(aErrorCode: HRESULT); virtual; + procedure doOnIsMutedChanged(const sender: ICoreWebView2); virtual; + procedure doOnIsDocumentPlayingAudioChanged(const sender: ICoreWebView2); virtual; + procedure doOnIsDefaultDownloadDialogOpenChanged(const sender: ICoreWebView2); virtual; + procedure doOnProcessInfosChangedEvent(const sender: ICoreWebView2Environment); virtual; + procedure doOnFrameNavigationStarting2(const sender: ICoreWebView2Frame; const args: ICoreWebView2NavigationStartingEventArgs; aFrameID : cardinal); virtual; + procedure doOnFrameNavigationCompleted2(const sender: ICoreWebView2Frame; const args: ICoreWebView2NavigationCompletedEventArgs; aFrameID : cardinal); virtual; + procedure doOnFrameContentLoadingEvent(const sender: ICoreWebView2Frame; const args: ICoreWebView2ContentLoadingEventArgs; aFrameID: cardinal); virtual; + procedure doOnFrameDOMContentLoadedEvent(const sender: ICoreWebView2Frame; const args: ICoreWebView2DOMContentLoadedEventArgs; aFrameID: cardinal); virtual; + procedure doOnFrameWebMessageReceivedEvent(const sender: ICoreWebView2Frame; const args: ICoreWebView2WebMessageReceivedEventArgs; aFrameID: cardinal); virtual; + procedure doOnBasicAuthenticationRequestedEvent(const sender: ICoreWebView2; const args: ICoreWebView2BasicAuthenticationRequestedEventArgs); virtual; + procedure doOnContextMenuRequestedEvent(const sender: ICoreWebView2; const args: ICoreWebView2ContextMenuRequestedEventArgs); virtual; + procedure doOnCustomItemSelectedEvent(const sender: ICoreWebView2ContextMenuItem; const args: IUnknown); virtual; + procedure doOnStatusBarTextChangedEvent(const sender: ICoreWebView2; const args: IUnknown); virtual; + procedure doOnFramePermissionRequestedEvent(const sender: ICoreWebView2Frame; const args: ICoreWebView2PermissionRequestedEventArgs2; aFrameID: cardinal); virtual; + procedure doOnClearBrowsingDataCompletedEvent(aErrorCode: HRESULT); virtual; + procedure doOnServerCertificateErrorActionsCompletedEvent(aErrorCode: HRESULT); virtual; + procedure doOnServerCertificateErrorDetectedEvent(const sender: ICoreWebView2; const args: ICoreWebView2ServerCertificateErrorDetectedEventArgs); virtual; + procedure doOnFaviconChangedEvent(const sender: ICoreWebView2; const args: IUnknown); virtual; + procedure doOnGetFaviconCompletedEvent(errorCode: HResult; const result_: IStream); virtual; + procedure doOnPrintCompletedEvent(errorCode: HResult; result_: COREWEBVIEW2_PRINT_STATUS); virtual; + procedure doOnPrintToPdfStreamCompletedEvent(errorCode: HResult; const result_: IStream); virtual; + procedure doOnGetCustomSchemes(var aSchemeRegistrations : TWVCustomSchemeRegistrationArray); virtual; + procedure doOnGetNonDefaultPermissionSettingsCompleted(errorCode: HResult; const result_: ICoreWebView2PermissionSettingCollectionView); virtual; + procedure doOnSetPermissionStateCompleted(errorCode: HResult); virtual; + procedure doOnLaunchingExternalUriSchemeEvent(const sender: ICoreWebView2; const args: ICoreWebView2LaunchingExternalUriSchemeEventArgs); virtual; + procedure doOnGetProcessExtendedInfosCompletedEvent(errorCode: HResult; const result_: ICoreWebView2ProcessExtendedInfoCollection); virtual; + procedure doOnBrowserExtensionRemoveCompletedEvent(errorCode: HResult; const aExtensionID: wvstring); virtual; + procedure doOnBrowserExtensionEnableCompletedEvent(errorCode: HResult; const aExtensionID: wvstring); virtual; + procedure doOnProfileAddBrowserExtensionCompletedEvent(errorCode: HResult; const result_: ICoreWebView2BrowserExtension); virtual; + procedure doOnProfileGetBrowserExtensionsCompletedEvent(errorCode: HResult; const result_: ICoreWebView2BrowserExtensionList); virtual; + procedure doOnProfileDeletedEvent(const sender: ICoreWebView2Profile; const args: IUnknown); virtual; + procedure doOnExecuteScriptWithResultCompletedEvent(errorCode: HResult; const result_: ICoreWebView2ExecuteScriptResult; aExecutionID : integer); virtual; + procedure doOnNonClientRegionChangedEvent(const sender: ICoreWebView2CompositionController; const args: ICoreWebView2NonClientRegionChangedEventArgs); virtual; + procedure doOnNotificationReceivedEvent(const sender: ICoreWebView2; const args: ICoreWebView2NotificationReceivedEventArgs); virtual; + procedure doOnNotificationCloseRequestedEvent(const sender: ICoreWebView2Notification; const args: IUnknown); virtual; + procedure doOnSaveAsUIShowingEvent(const sender: ICoreWebView2; const args: ICoreWebView2SaveAsUIShowingEventArgs); virtual; + procedure doOnShowSaveAsUICompletedEvent(errorCode: HResult; result_: COREWEBVIEW2_SAVE_AS_UI_RESULT); virtual; + procedure doOnSaveFileSecurityCheckStartingEvent(const sender: ICoreWebView2; const args: ICoreWebView2SaveFileSecurityCheckStartingEventArgs); virtual; + procedure doOnScreenCaptureStartingEvent(const sender: ICoreWebView2; const args: ICoreWebView2ScreenCaptureStartingEventArgs); virtual; + procedure doOnFrameScreenCaptureStartingEvent(const sender: ICoreWebView2Frame; const args: ICoreWebView2ScreenCaptureStartingEventArgs; aFrameID: cardinal); virtual; + procedure doOnFrameChildFrameCreatedEvent(const sender: ICoreWebView2Frame; const args: ICoreWebView2FrameCreatedEventArgs; aFrameID: cardinal); virtual; + procedure doOnFindActiveMatchIndexChangedEvent(const sender: ICoreWebView2Find; const args: IUnknown); virtual; + procedure doOnFindMatchCountChangedEvent(const sender: ICoreWebView2Find; const args: IUnknown); virtual; + procedure doOnFindStartCompletedEvent(errorCode: HResult); virtual; + procedure doOnDragStartingEvent(const sender: ICoreWebView2CompositionController; const args: ICoreWebView2DragStartingEventArgs); virtual; + procedure doOnDedicatedWorkerCreatedEvent(const sender: ICoreWebView2; const args: ICoreWebView2DedicatedWorkerCreatedEventArgs); virtual; + procedure doOnDedicatedWorkerCreatedEvent2(const sender: ICoreWebView2DedicatedWorker; const args: ICoreWebView2DedicatedWorkerCreatedEventArgs; aWorkerID: cardinal); virtual; + procedure doOnDedicatedWorkerDestroyingEvent(const sender: ICoreWebView2DedicatedWorker; const args: IUnknown; aWorkerID: cardinal); virtual; + procedure doOnDedicatedWorkerWebMessageReceivedEvent(const sender: ICoreWebView2DedicatedWorker; const args: ICoreWebView2WebMessageReceivedEventArgs; aWorkerID: cardinal); virtual; + procedure doOnFrameDedicatedWorkerCreatedEvent(const sender: ICoreWebView2Frame; const args: ICoreWebView2DedicatedWorkerCreatedEventArgs; aFrameID: cardinal); virtual; + procedure doOnServiceWorkerDestroyingEvent(const sender: ICoreWebView2ServiceWorker; const args: IUnknown; aWorkerID: cardinal); virtual; + procedure doOnServiceWorkerWebMessageReceivedEvent(const sender: ICoreWebView2ServiceWorker; const args: ICoreWebView2WebMessageReceivedEventArgs; aWorkerID: cardinal); virtual; + procedure doOnServiceWorkerRegisteredEvent(const sender: ICoreWebView2ServiceWorkerManager; const args: ICoreWebView2ServiceWorkerRegisteredEventArgs); virtual; + procedure doOnGetServiceWorkerRegistrationsCompletedEvent(errorCode: HResult; const result_: ICoreWebView2ServiceWorkerRegistrationCollectionView); virtual; + procedure doOnServiceWorkerActivatedEvent(const sender: ICoreWebView2ServiceWorkerRegistration; const args: ICoreWebView2ServiceWorkerActivatedEventArgs); virtual; + procedure doOnServiceWorkerRegistrationUnregisteringEvent(const sender: ICoreWebView2ServiceWorkerRegistration; const args: IUnknown); virtual; + procedure doOnSharedWorkerCreatedEvent(const sender: ICoreWebView2SharedWorkerManager; const args: ICoreWebView2SharedWorkerCreatedEventArgs); virtual; + procedure doOnGetSharedWorkersCompletedEvent(errorCode: HResult; const result_: ICoreWebView2SharedWorkerCollectionView); virtual; + procedure doOnSharedWorkerDestroyingEvent(const sender: ICoreWebView2SharedWorker; const args: IUnknown; aWorkerID: cardinal); virtual; + + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure AfterConstruction; override; + /// + /// Used to create the browser using the global environment by default. + /// The browser will be fully initialized when the TWVBrowserBase.OnAfterCreated + /// event is triggered. + /// + /// The TWVWindowParent handle. + /// Use the global environment or create a new one for this browser. + function CreateBrowser(aHandle : THandle; aUseDefaultEnvironment : boolean = True) : boolean; overload; + /// + /// Used to create the browser using a custom environment. The browser will be + /// fully initialized when the TWVBrowserBase.OnAfterCreated event is triggered. + /// + /// The TWVWindowParent handle. + /// Custom environment to be used by this browser. + function CreateBrowser(aHandle : THandle; const aEnvironment : ICoreWebView2Environment) : boolean; overload; + /// + /// Used to create a windowless browser using the global environment by default. + /// The browser will be fully initialized when the TWVBrowserBase.OnAfterCreated + /// event is triggered. + /// + /// The TWVDirectCompositionHost handle. + /// Use the global environment or create a new one for this browser. + function CreateWindowlessBrowser(aHandle : THandle; aUseDefaultEnvironment : boolean = True) : boolean; overload; + /// + /// Used to create a windowless browser using a custom environment. The browser will be + /// fully initialized when the TWVBrowserBase.OnAfterCreated event is triggered. + /// + /// The TWVDirectCompositionHost handle. + /// Custom environment to be used by this browser. + function CreateWindowlessBrowser(aHandle : THandle; const aEnvironment : ICoreWebView2Environment) : boolean; overload; + /// + /// Used to create an invisible browser using the global environment by default. + /// You are not able to reparent the window after you have created the browser. + /// The browser will be fully initialized when the TWVBrowserBase.OnAfterCreated + /// event is triggered. + /// + /// Use the global environment or create a new one for this browser. + function CreateInvisibleBrowser(aUseDefaultEnvironment : boolean = True) : boolean; overload; + /// + /// Used to create an invisible browser using a custom environment. + /// You are not able to reparent the window after you have created the browser. + /// The browser will be fully initialized when the TWVBrowserBase.OnAfterCreated + /// event is triggered. + /// + /// Custom environment to be used by this browser. + function CreateInvisibleBrowser(const aEnvironment : ICoreWebView2Environment) : boolean; overload; + /// + /// Navigates the WebView to the previous page in the navigation history. + /// + /// + /// See the ICoreWebView2 article. + /// + function GoBack : boolean; + /// + /// Navigates the WebView to the next page in the navigation history. + /// + /// + /// See the ICoreWebView2 article. + /// + function GoForward : boolean; + /// + /// Reload the current page. This is similar to navigating to the URI of + /// current top level document including all navigation events firing and + /// respecting any entries in the HTTP cache. But, the back or forward + /// history are not modified. + /// + /// + /// See the ICoreWebView2 article. + /// + function Refresh : boolean; + /// + /// Reload the current page. Browser cache is ignored as if the user pressed Shift+refresh. + /// This function is asynchronous and it triggers the TWVBrowserBase.OnRefreshIgnoreCacheCompleted event when it finishes executing. + /// + /// + /// See the Page Domain article. + /// + function RefreshIgnoreCache : boolean; + /// + /// Stop all navigations and pending resource fetches. Does not stop scripts. + /// + /// + /// See the ICoreWebView2 article. + /// + function Stop : boolean; + /// + /// Cause a navigation of the top-level document to run to the specified URI. + /// + /// + /// See the ICoreWebView2 article. + /// + function Navigate(const aURI : wvstring) : boolean; + /// + /// Initiates a navigation to aHTMLContent as source HTML of a new document. + /// The origin of the new page is `about:blank`. + /// + /// Source HTML. It may not be larger than 2 MB (2 * 1024 * 1024 bytes) in total size. + /// + /// See the ICoreWebView2 article. + /// + function NavigateToString(const aHTMLContent: wvstring) : boolean; + /// + /// Navigates using a constructed ICoreWebView2WebResourceRequest object. This lets you + /// provide post data or additional request headers during navigation. + /// The headers in aRequest override headers added by WebView2 runtime except for Cookie headers. + /// Method can only be either "GET" or "POST". Provided post data will only + /// be sent only if the method is "POST" and the uri scheme is HTTP(S). + /// + /// + /// See the ICoreWebView2_2 article. + /// + function NavigateWithWebResourceRequest(const aRequest : ICoreWebView2WebResourceRequest) : boolean; + /// + /// Subscribe to a DevTools protocol event. The TWVBrowserBase.OnDevToolsProtocolEventReceived + /// event will be triggered on each DevTools event. + /// + /// The DevTools protocol event name. + /// A custom event ID that will be passed as a parameter in the TWVBrowserBase event. + /// + /// See the ICoreWebView2DevToolsProtocolEventReceiver article. + /// + function SubscribeToDevToolsProtocolEvent(const aEventName : wvstring; aEventID : integer = 0) : boolean; + /// + /// Runs an asynchronous `DevToolsProtocol` method. + /// The TWVBrowserBase.OnCallDevToolsProtocolMethodCompleted event is triggered + /// when it finishes executing. This function returns E_INVALIDARG if the `aMethodName` is + /// unknown or the `aParametersAsJson` has an error. In the case of such an error, the + /// `aReturnObjectAsJson` parameter of the event will include information + /// about the error. + /// Note even though WebView2 dispatches the CDP messages in the order called, + /// CDP method calls may be processed out of order. + /// If you require CDP methods to run in a particular order, you should wait + /// for the previous method is finished before calling the next method. + /// If the method is to run in add_NewWindowRequested handler it should be called + /// before the new window is set if the cdp message should affect the initial navigation. If + /// called after setting the NewWindow property, the cdp messages + /// may or may not apply to the initial navigation and may only apply to the subsequent navigation. + /// For more details see `ICoreWebView2NewWindowRequestedEventArgs::put_NewWindow`. + /// + /// The DevTools protocol full method name. + /// JSON formatted string containing the parameters for the corresponding method. + /// A custom event ID that will be passed as a parameter in the TWVBrowserBase event. + /// + /// See the Chrome DevTools Protocol web page. + /// See the ICoreWebView2 article. + /// + function CallDevToolsProtocolMethod(const aMethodName, aParametersAsJson : wvstring; aExecutionID : integer = 0) : boolean; + /// + /// Runs an asynchronous `DevToolsProtocol` method for a specific session of + /// an attached target. + /// There could be multiple `DevToolsProtocol` targets in a WebView. + /// Besides the top level page, iframes from different origin and web workers + /// are also separate targets. Attaching to these targets allows interaction with them. + /// When the DevToolsProtocol is attached to a target, the connection is identified + /// by a sessionId. + /// To use this API, you must set the `flatten` parameter to true when calling + /// `Target.attachToTarget` or `Target.setAutoAttach` `DevToolsProtocol` method. + /// Using `Target.setAutoAttach` is recommended as that would allow you to attach + /// to dedicated worker targets, which are not discoverable via other APIs like + /// `Target.getTargets`. + /// The TWVBrowserBase.OnCallDevToolsProtocolMethodCompleted event is triggered + /// when it finishes executing. This function returns E_INVALIDARG if the `aMethodName` is + /// unknown or the `aParametersAsJson` has an error. In the case of such an error, the + /// `aReturnObjectAsJson` parameter of the event will include information + /// about the error. + /// Note even though WebView2 dispatches the CDP messages in the order called, + /// CDP method calls may be processed out of order. + /// If you require CDP methods to run in a particular order, you should wait + /// for the previous method is finished before calling the next method. + /// + /// The sessionId for an attached target. An empty string is treated as the session for the default target for the top page. + /// The DevTools protocol full method name. + /// JSON formatted string containing the parameters for the corresponding method. + /// A custom event ID that will be passed as a parameter in the TWVBrowserBase event. + /// + /// See the Chrome DevTools Protocol web page. + /// Information about targets and sessions. + /// See the ICoreWebView2_11 article. + /// + function CallDevToolsProtocolMethodForSession(const aSessionId, aMethodName, aParametersAsJson : wvstring; aExecutionID : integer = 0) : boolean; + /// + /// Moves focus into WebView. + /// + /// + /// See the ICoreWebView2Controller article. + /// + function SetFocus : boolean; + /// + /// Moves the focus to the next element. + /// + /// + /// See the ICoreWebView2Controller article. + /// + function FocusNext : boolean; + /// + /// Moves the focus to the previous element. + /// + /// + /// See the ICoreWebView2Controller article. + /// + function FocusPrevious : boolean; + /// + /// Run JavaScript code from the JavaScript parameter in the current + /// top-level document rendered in the WebView. + /// The TWVBrowserBase.OnExecuteScriptWithResultCompleted event is triggered + /// when it finishes executing. + /// The result of the execution is returned asynchronously in the ICoreWebView2ExecuteScriptResult object + /// which has methods and properties to obtain the successful result of script execution as well as any + /// unhandled JavaScript exceptions. + /// If this method is run after the NavigationStarting event during a navigation, the script + /// runs in the new document when loading it, around the time + /// ContentLoading is run. This operation executes the script even if + /// ICoreWebView2Settings.IsScriptEnabled is set to FALSE. + /// + /// The JavaScript code. + /// A custom event ID that will be passed as a parameter in the TWVBrowserBase event. + /// + /// See the icorewebview2_21 article. + /// + function ExecuteScriptWithResult(const aJavaScript: wvstring; aExecutionID : integer = 0): boolean; + /// + /// Run JavaScript code from the aJavaScript parameter in the current + /// top-level document rendered in the WebView. + /// The TWVBrowserBase.OnExecuteScriptCompleted event is triggered + /// when it finishes executing. + /// The result of evaluating the provided JavaScript is available in the + /// aResultObjectAsJson parameter of the TWVBrowserBase.OnExecuteScriptCompleted + /// event as a JSON encoded string. If the result is undefined, contains a reference + /// cycle, or otherwise is not able to be encoded into JSON, then the result + /// is considered to be null, which is encoded in JSON as the string "null". + /// If the script that was run throws an unhandled exception, then the result is + /// also "null". + /// If the method is run after the `NavigationStarting` event during a navigation, + /// the script runs in the new document when loading it, around the time + /// `ContentLoading` is run. This operation executes the script even if + /// `ICoreWebView2Settings.IsScriptEnabled` is set to `FALSE`. + /// + /// The JavaScript code. + /// A custom event ID that will be passed as a parameter in the TWVBrowserBase event. + /// + /// See the ICoreWebView2 article. + /// + function ExecuteScript(const aJavaScript : wvstring; aExecutionID : integer = 0) : boolean; + /// + /// Capture an image of what WebView is displaying. Specify the format of + /// the image with the aImageFormat parameter. The resulting image binary + /// data is written to the provided aImageStream parameter. This method fails if called + /// before the first ContentLoading event. For example if this is called in + /// the NavigationStarting event for the first navigation it will fail. + /// For subsequent navigations, the method may not fail, but will not capture + /// an image of a given webpage until the ContentLoading event has been fired + /// for it. Any call to this method prior to that will result in a capture of + /// the page being navigated away from. When this function finishes writing to the stream, + /// the TWVBrowserBase.OnCapturePreviewCompleted event is triggered. + /// + /// The format of the image. + /// The resulting image binary data is written to this stream. + /// + /// See the ICoreWebView2 article. + /// + function CapturePreview(aImageFormat: TWVCapturePreviewImageFormat; const aImageStream: IStream) : boolean; + /// + /// This is a notification that tells WebView that the main WebView parent + /// (or any ancestor) `HWND` moved. This is needed for accessibility and + /// certain dialogs in WebView to work correctly. + /// + /// + /// See the ICoreWebView2Controller article. + /// + function NotifyParentWindowPositionChanged : boolean; + /// + /// Sets permission state for the given permission kind and origin + /// asynchronously. The change persists across sessions until it is changed by + /// another call to `SetPermissionState`, or by setting the `State` property + /// in `PermissionRequestedEventArgs`. + /// Setting the state to `COREWEBVIEW2_PERMISSION_STATE_DEFAULT` will + /// erase any state saved in the profile and restore the default behavior. + /// The origin should have a valid scheme and host (e.g. "https://www.example.com"), + /// otherwise the method fails with `E_INVALIDARG`. Additional URI parts like + /// path and fragment are ignored. For example, "https://wwww.example.com/app1/index.html/" + /// is treated the same as "https://wwww.example.com". + /// This function triggers the TWVBrowserBase.OnSetPermissionStateCompleted event. + /// + /// + /// See the MDN origin definition. + /// See the ICoreWebView2Profile4 article. + /// + function SetPermissionState(aPermissionKind: TWVPermissionKind; const aOrigin: wvstring; aState: TWVPermissionState) : boolean; + /// + /// Invokes the handler with a collection of all nondefault permission settings. + /// Use this method to get the permission state set in the current and previous + /// sessions. + /// This function triggers the TWVBrowserBase.OnGetNonDefaultPermissionSettingsCompleted event. + /// + /// + /// See the ICoreWebView2Profile4 article. + /// + function GetNonDefaultPermissionSettings: boolean; + /// + /// Adds the [browser extension](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions) + /// using the extension path for unpacked extensions from the local device. Extension is + /// running right after installation. + /// The extension folder path is the topmost folder of an unpacked browser extension and + /// contains the browser extension manifest file. + /// If the `extensionFolderPath` is an invalid path or doesn't contain the extension manifest.json + /// file, this function will return `ERROR_FILE_NOT_FOUND` to callers. + /// Installed extension will default `IsEnabled` to true. + /// When `AreBrowserExtensionsEnabled` is `FALSE`, `AddBrowserExtension` will fail and return + /// HRESULT `ERROR_NOT_SUPPORTED`. + /// During installation, the content of the extension is not copied to the user data folder. + /// Once the extension is installed, changing the content of the extension will cause the + /// extension to be removed from the installed profile. + /// When an extension is added the extension is persisted in the corresponding profile. The + /// extension will still be installed the next time you use this profile. + /// When an extension is installed from a folder path, adding the same extension from the same + /// folder path means reinstalling this extension. When two extensions with the same Id are + /// installed, only the later installed extension will be kept. + /// Extensions that are designed to include any UI interactions (e.g. icon, badge, pop up, etc.) + /// can be loaded and used but will have missing UI entry points due to the lack of browser + /// UI elements to host these entry points in WebView2. + /// The following summarizes the possible error values that can be returned from + /// `AddBrowserExtension` and a description of why these errors occur. + /// + /// Error value | Description + /// ----------------------------------------------- | -------------------------- + /// `HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)` | Extensions are disabled. + /// `HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)` | Cannot find `manifest.json` file or it is not a valid extension manifest. + /// `E_ACCESSDENIED` | Cannot load extension with file or directory name starting with \"_\", reserved for use by the system. + /// `E_FAIL` | Extension failed to install with other unknown reasons. + /// + /// + /// + /// See the ICoreWebView2Profile7 article. + /// The TWVBrowserBase.OnProfileAddBrowserExtensionCompleted event is triggered when TWVBrowserBase.AddBrowserExtension finishes executing. + /// + function AddBrowserExtension(const extensionFolderPath: wvstring): boolean; + /// + /// Gets a snapshot of the set of extensions installed at the time `GetBrowserExtensions` is + /// called. If an extension is installed or uninstalled after `GetBrowserExtensions` completes, + /// the list returned by `GetBrowserExtensions` remains the same. + /// When `AreBrowserExtensionsEnabled` is `FALSE`, `GetBrowserExtensions` won't return any + /// extensions on current user profile. + /// + /// + /// See the ICoreWebView2Profile7 article. + /// The TWVBrowserBase.OnProfileGetBrowserExtensionsCompleted event is triggered when TWVBrowserBase.GetBrowserExtensions finishes executing. + /// + function GetBrowserExtensions: boolean; + /// + /// After the API is called, the profile will be marked for deletion. The + /// local profile's directory will be deleted at browser process exit. If it + /// fails to delete, because something else is holding the files open, + /// WebView2 will try to delete the profile at all future browser process + /// starts until successful. + /// The corresponding CoreWebView2s will be closed and the + /// CoreWebView2Profile.Deleted event will be raised. See + /// `CoreWebView2Profile.Deleted` for more information. + /// If you try to create a new profile with the same name as an existing + /// profile that has been marked as deleted but hasn't yet been deleted, + /// profile creation will fail with HRESULT_FROM_WIN32(ERROR_DELETE_PENDING). + /// + /// + /// See the ICoreWebView2Profile8 article. + /// + function DeleteProfile: boolean; + /// + /// An app may call the `TrySuspend` API to have the WebView2 consume less memory. + /// This is useful when a Win32 app becomes invisible, or when a Universal Windows + /// Platform app is being suspended, during the suspended event handler before completing + /// the suspended event. + /// The IsVisible property must be false when the API is called. + /// Otherwise, the API fails with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`. + /// Suspending is similar to putting a tab to sleep in the Edge browser. Suspending pauses + /// WebView script timers and animations, minimizes CPU usage for the associated + /// browser renderer process and allows the operating system to reuse the memory that was + /// used by the renderer process for other processes. + /// Note that Suspend is best effort and considered completed successfully once the request + /// is sent to browser renderer process. If there is a running script, the script will continue + /// to run and the renderer process will be suspended after that script is done. + /// for conditions that might prevent WebView from being suspended. In those situations, + /// the completed handler will be invoked with isSuccessful as false and errorCode as S_OK. + /// The WebView will be automatically resumed when it becomes visible. Therefore, the + /// app normally does not have to call `Resume` explicitly. + /// The app can call `Resume` and then `TrySuspend` periodically for an invisible WebView so that + /// the invisible WebView can sync up with latest data and the page ready to show fresh content + /// when it becomes visible. + /// All WebView APIs can still be accessed when a WebView is suspended. Some APIs like Navigate + /// will auto resume the WebView. To avoid unexpected auto resume, check `IsSuspended` property + /// before calling APIs that might change WebView state. + /// This function is asynchronous and it triggers the TWVBrowserBase.OnTrySuspendCompleted event when it finishes executing. + /// + /// + /// See the sleeping Tabs FAQ. + /// See the ICoreWebView2_3 article. + /// + function TrySuspend : boolean; + /// + /// Resumes the WebView so that it resumes activities on the web page. + /// This API can be called while the WebView2 controller is invisible. + /// The app can interact with the WebView immediately after `Resume`. + /// WebView will be automatically resumed when it becomes visible. + /// + /// + /// See the ICoreWebView2_3 article. + /// + function Resume : boolean; + /// + /// Sets a mapping between a virtual host name and a folder path to make available to web sites + /// via that host name. + /// After setting the mapping, documents loaded in the WebView can use HTTP or HTTPS URLs at + /// the specified host name specified by hostName to access files in the local folder specified + /// by folderPath. + /// + /// Host name to access files in the local folder specified by aFolderPath. + /// The path to the local files. Both absolute and relative paths are supported. Relative paths are interpreted as relative to the folder where the exe of the app is in. Note that the aFolderPath length must not exceed the Windows MAX_PATH limit. + /// aAccessKind specifies the level of access to resources under the virtual host from other sites. + /// + /// See the ICoreWebView2_3 article. + /// + function SetVirtualHostNameToFolderMapping(const aHostName, aFolderPath : wvstring; aAccessKind : TWVHostResourceAcccessKind): boolean; + /// + /// Clears a host name mapping for local folder that was added by `SetVirtualHostNameToFolderMapping`. + /// + /// Host name used previously with SetVirtualHostNameToFolderMapping to access files in the local folder. + /// + /// See the ICoreWebView2_3 article. + /// + function ClearVirtualHostNameToFolderMapping(const aHostName : wvstring) : boolean; + /// + /// Retrieve the HTML contents. The TWVBrowserBase.OnRetrieveHTMLCompleted event is triggered asynchronously with the HTML contents. + /// + function RetrieveHTML : boolean; + /// + /// Retrieve the text contents. The TWVBrowserBase.OnRetrieveTextCompleted event is triggered asynchronously with the text contents. + /// + /// Exclude text that is hidden with CSS or rendered as invisible due to its parent's visibility settings. + function RetrieveText(aVisibleTextOnly: boolean = False) : boolean; + /// + /// Retrieve the web page contents in MHTML format. The TWVBrowserBase.OnRetrieveMHTMLCompleted event is triggered asynchronously with the MHTML contents. + /// + function RetrieveMHTML : boolean; + /// + /// Print the current web page asynchronously to the specified printer with the TWVBrowserBase.CoreWebView2PrintSettings settings. + /// This function is asynchronous and it triggers the TWVBrowserBase.OnPrintCompleted event when it finishes executing. + /// + /// + /// See the ICoreWebView2_16 article. + /// + function Print : boolean; + /// + /// Opens the print dialog to print the current web page using the system print dialog or the browser print preview dialog. + /// + /// + /// See the ICoreWebView2_16 article. + /// + function ShowPrintUI(aUseSystemPrintDialog : boolean = False): boolean; + /// + /// Print the current page to PDF asynchronously with the TWVBrowserBase.CoreWebView2PrintSettings settings. + /// This function is asynchronous and it triggers the TWVBrowserBase.OnPrintToPdfCompleted event when it finishes executing. + /// + /// The path to the PDF file. + /// + /// See the ICoreWebView2_7 article. + /// + function PrintToPdf(const aResultFilePath : wvstring) : boolean; + /// + /// Provides the Pdf data of current web page asynchronously for the TWVBrowserBase.CoreWebView2PrintSettings settings. + /// Stream will be rewound to the start of the pdf data. + /// This function is asynchronous and it triggers the TWVBrowserBase.OnPrintToPdfStreamCompleted event. + /// + /// + /// See the ICoreWebView2_16 article. + /// + function PrintToPdfStream : boolean; + /// + /// Opens the DevTools window for the current document in the WebView. Does + /// nothing if run when the DevTools window is already open. + /// + /// + /// See the ICoreWebView2 article. + /// + function OpenDevToolsWindow : boolean; + /// + /// Opens the Browser Task Manager view as a new window in the foreground. + /// If the Browser Task Manager is already open, this will bring it into + /// the foreground. WebView2 currently blocks the Shift+Esc shortcut for + /// opening the task manager. An end user can open the browser task manager + /// manually via the `Browser task manager` entry of the DevTools window's + /// title bar's context menu. + /// + /// + /// See the ICoreWebView2_6 article. + /// + function OpenTaskManagerWindow : boolean; + /// + /// Post the specified webMessage to the top level document in this WebView. + /// The main page receives the message by subscribing to the `message` event of the + /// `window.chrome.webview` of the page document. + /// + /// ```cpp + /// window.chrome.webview.addEventListener('message', handler) + /// window.chrome.webview.removeEventListener('message', handler) + /// ``` + /// + /// The event args is an instance of `MessageEvent`. The + /// `ICoreWebView2Settings.IsWebMessageEnabled` setting must be `TRUE` or + /// the web message will not be sent. The `data` property of the event + /// arg is the `webMessage` string parameter parsed as a JSON string into a + /// JavaScript object. The `source` property of the event arg is a reference + /// to the `window.chrome.webview` object. For information about sending + /// messages from the HTML document in the WebView to the host, navigate to + /// [add_WebMessageReceived](/microsoft-edge/webview2/reference/win32/icorewebview2#add_webmessagereceived). + /// The message is delivered asynchronously. If a navigation occurs before + /// the message is posted to the page, the message is discarded. + /// + /// + /// See the ICoreWebView2 article. + /// + function PostWebMessageAsJson(const aWebMessageAsJson : wvstring) : boolean; + /// + /// Posts a message that is a simple string rather than a JSON string + /// representation of a JavaScript object. This behaves in exactly the same + /// manner as `PostWebMessageAsJson`, but the `data` property of the event + /// arg of the `window.chrome.webview` message is a string with the same + /// value as `aWebMessageAsString`. Use this instead of + /// `PostWebMessageAsJson` if you want to communicate using simple strings + /// rather than JSON objects. + /// + /// + /// See the ICoreWebView2 article. + /// + function PostWebMessageAsString(const aWebMessageAsString : wvstring) : boolean; + /// + /// Warning: This method is deprecated and does not behave as expected for + /// iframes. It will cause the WebResourceRequested event to fire only for the + /// main frame and its same-origin iframes. Please use + /// `AddWebResourceRequestedFilterWithRequestSourceKinds` + /// instead, which will let the event to fire for all iframes on the + /// document. + /// Adds a URI and resource context filter for the `WebResourceRequested` + /// event. A web resource request with a resource context that matches this + /// filter's resource context and a URI that matches this filter's URI + /// wildcard string will be raised via the `WebResourceRequested` event. + /// The `aURI` parameter value is a wildcard string matched against the URI + /// of the web resource request. This is a glob style + /// wildcard string in which a `*` matches zero or more characters and a `?` + /// matches exactly one character. + /// These wildcard characters can be escaped using a backslash just before + /// the wildcard character in order to represent the literal `*` or `?`. + /// The matching occurs over the URI as a whole string and not limiting + /// wildcard matches to particular parts of the URI. + /// The wildcard filter is compared to the URI after the URI has been + /// normalized, any URI fragment has been removed, and non-ASCII hostnames + /// have been converted to punycode. + /// Specifying an empty string for aURI matches no URIs. + /// For more information about resource context filters, navigate to + /// [COREWEBVIEW2_WEB_RESOURCE_CONTEXT](/microsoft-edge/webview2/reference/win32/webview2-idl#corewebview2_web_resource_context). + /// + /// | URI Filter String | Request URI | Match | Notes | + /// | ---- | ---- | ---- | ---- | + /// | `*` | `https://contoso.com/a/b/c` | Yes | A single * will match all URIs | + /// | `*://contoso.com/*` | `https://contoso.com/a/b/c` | Yes | Matches everything in contoso.com across all schemes | + /// | `*://contoso.com/*` | `https://example.com/?https://contoso.com/` | Yes | But also matches a URI with just the same text anywhere in the URI | + /// | `example` | `https://contoso.com/example` | No | The filter does not perform partial matches | + /// | `*example` | `https://contoso.com/example` | Yes | The filter matches across URI parts | + /// | `*example` | `https://contoso.com/path/?example` | Yes | The filter matches across URI parts | + /// | `*example` | `https://contoso.com/path/?query#example` | No | The filter is matched against the URI with no fragment | + /// | `*example` | `https://example` | No | The URI is normalized before filter matching so the actual URI used for comparison is `https://example/` | + /// | `*example/` | `https://example` | Yes | Just like above, but this time the filter ends with a / just like the normalized URI | + /// | `https://xn--qei.example/` | `https://❤.example/` | Yes | Non-ASCII hostnames are normalized to punycode before wildcard comparison | + /// | `https://❤.example/` | `https://xn--qei.example/` | No | Non-ASCII hostnames are normalized to punycode before wildcard comparison | + /// + /// + /// + /// See the ICoreWebView2 article. + /// + function AddWebResourceRequestedFilter(const aURI: wvstring; aResourceContext: TWVWebResourceContext) : boolean; + /// Warning: This method and `AddWebResourceRequestedFilter` are deprecated. + /// Please use `AddWebResourceRequestedFilterWithRequestSourceKinds` and + /// `RemoveWebResourceRequestedFilterWithRequestSourceKinds` instead. + /// Removes a matching WebResource filter that was previously added for the + /// `WebResourceRequested` event. If the same filter was added multiple + /// times, then it must be removed as many times as it was added for the + /// removal to be effective. Returns `E_INVALIDARG` for a filter that was + /// never added. + /// + /// See the ICoreWebView2 article. + /// + function RemoveWebResourceRequestedFilter(const aURI: wvstring; aResourceContext: TWVWebResourceContext) : boolean; + /// + /// A web resource request with a resource context that matches this + /// filter's resource context and a URI that matches this filter's URI + /// wildcard string for corresponding request sources will be raised via + /// the `WebResourceRequested` event. To receive all raised events filters + /// have to be added before main page navigation. + /// The `uri` parameter value is a wildcard string matched against the URI + /// of the web resource request. This is a glob style + /// wildcard string in which a `*` matches zero or more characters and a `?` + /// matches exactly one character. + /// These wildcard characters can be escaped using a backslash just before + /// the wildcard character in order to represent the literal `*` or `?`. + /// The matching occurs over the URI as a whole string and not limiting + /// wildcard matches to particular parts of the URI. + /// The wildcard filter is compared to the URI after the URI has been + /// normalized, any URI fragment has been removed, and non-ASCII hostnames + /// have been converted to punycode. + /// Specifying a `nullptr` for the uri is equivalent to an empty string which + /// matches no URIs. + /// For more information about resource context filters, navigate to + /// [COREWEBVIEW2_WEB_RESOURCE_CONTEXT](/microsoft-edge/webview2/reference/win32/icorewebview2#corewebview2_web_resource_context). + /// The `requestSourceKinds` is a mask of one or more + /// `COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS`. OR operation(s) can be + /// applied to multiple `COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS` to + /// create a mask representing those data types. API returns `E_INVALIDARG` if + /// `requestSourceKinds` equals to zero. For more information about request + /// source kinds, navigate to + /// [COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS](/microsoft-edge/webview2/reference/win32/icorewebview2#corewebview2_web_resource_request_source_kinds). + /// Because service workers and shared workers run separately from any one + /// HTML document their WebResourceRequested will be raised for all + /// CoreWebView2s that have appropriate filters added in the corresponding + /// CoreWebView2Environment. You should only add a WebResourceRequested filter + /// for COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_SERVICE_WORKER or + /// COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_SHARED_WORKER on + /// one CoreWebView2 to avoid handling the same WebResourceRequested + /// event multiple times. + /// + /// | URI Filter String | Request URI | Match | Notes | + /// | ---- | ---- | ---- | ---- | + /// | `*` | `https://contoso.com/a/b/c` | Yes | A single * will match all URIs | + /// | `*://contoso.com/*` | `https://contoso.com/a/b/c` | Yes | Matches everything in contoso.com across all schemes | + /// | `*://contoso.com/*` | `https://example.com/?https://contoso.com/` | Yes | But also matches a URI with just the same text anywhere in the URI | + /// | `example` | `https://contoso.com/example` | No | The filter does not perform partial matches | + /// | `*example` | `https://contoso.com/example` | Yes | The filter matches across URI parts | + /// | `*example` | `https://contoso.com/path/?example` | Yes | The filter matches across URI parts | + /// | `*example` | `https://contoso.com/path/?query#example` | No | The filter is matched against the URI with no fragment | + /// | `*example` | `https://example` | No | The URI is normalized before filter matching so the actual URI used for comparison is `https://example/` | + /// | `*example/` | `https://example` | Yes | Just like above, but this time the filter ends with a / just like the normalized URI | + /// | `https://xn--qei.example/` | `https://❤.example/` | Yes | Non-ASCII hostnames are normalized to punycode before wildcard comparison | + /// | `https://❤.example/` | `https://xn--qei.example/` | No | Non-ASCII hostnames are normalized to punycode before wildcard comparison | + /// + /// + /// + /// See the ICoreWebView2_22 article. + /// + function AddWebResourceRequestedFilterWithRequestSourceKinds(const uri: wvstring; + ResourceContext: TWVWebResourceContext; + requestSourceKinds: TWVWebResourceRequestSourceKind): boolean; + /// + /// Removes a matching WebResource filter that was previously added for the + /// `WebResourceRequested` event. If the same filter was added multiple + /// times, then it must be removed as many times as it was added for the + /// removal to be effective. Returns `E_INVALIDARG` for a filter that was + /// not added or is already removed. + /// If the filter was added for multiple requestSourceKinds and removed just for one of them + /// the filter remains for the non-removed requestSourceKinds. + /// + /// + /// See the ICoreWebView2_22 article. + /// + function RemoveWebResourceRequestedFilterWithRequestSourceKinds(const uri: wvstring; + ResourceContext: TWVWebResourceContext; + requestSourceKinds: TWVWebResourceRequestSourceKind): boolean; + /// + /// Same as `PostWebMessageAsJson`, but also has support for posting DOM objects + /// to page content. The `additionalObjects` property in the DOM MessageEvent + /// fired on the page content is an array-like list of DOM objects that can + /// be posted to the web content. Currently these can be the following + /// types of objects: + /// + /// | Win32 | DOM type | + /// |-------------------|-------------| + /// | ICoreWebView2FileSystemHandle | [FileSystemHandle](https://developer.mozilla.org/docs/Web/API/FileSystemHandle) | + /// | nullptr | null | + /// + /// The objects are posted to the web content, following the + /// [structured-clone](https://developer.mozilla.org/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) + /// semantics, meaning only objects that can be cloned can be posted. + /// They will also behave as if they had been created by the web content they are + /// posted to. For example, if a FileSystemFileHandle is posted to a web content + /// it can only be re-transferred via postMessage to other web content + /// [with the same origin](https://fs.spec.whatwg.org/#filesystemhandle). + /// Warning: An app needs to be mindful when using this API to post DOM objects + /// as this API provides the web content with unusual access to sensitive Web + /// Platform features such as filesystem access! Similar to PostWebMessageAsJson + /// the app should check the `Source` property of WebView2 right before posting the message + /// to ensure the message and objects will only be sent to the target web content + /// that it expects to receive the DOM objects. Additionally, the order + /// of messages that are posted between `PostWebMessageAsJson` and `PostWebMessageAsJsonWithAdditionalObjects` + /// may not be preserved. + /// + /// + /// See the ICoreWebView2_23 article. + /// + function PostWebMessageAsJsonWithAdditionalObjects(const webMessageAsJson: wvstring; + const additionalObjects: ICoreWebView2ObjectCollectionView): boolean; + /// + /// Add the provided host object to script running in the WebView with the + /// specified name. Host objects are exposed as host object proxies using + /// `window.chrome.webview.hostObjects.{name}`. Host object proxies are + /// promises and resolves to an object representing the host object. The + /// promise is rejected if the app has not added an object with the name. + /// When JavaScript code access a property or method of the object, a promise + /// is return, which resolves to the value returned from the host for the + /// property or method, or rejected in case of error, for example, no + /// property or method on the object or parameters are not valid. + /// + /// NOTE: While simple types, `IDispatch` and array are supported, and + /// `IUnknown` objects that also implement `IDispatch` are treated as `IDispatch`, + /// generic `IUnknown`, `VT_DECIMAL`, or `VT_RECORD` variant is not supported. + /// Remote JavaScript objects like callback functions are represented as an + /// `VT_DISPATCH` `VARIANT` with the object implementing `IDispatch`. The + /// JavaScript callback method may be invoked using `DISPID_VALUE` for the + /// `DISPID`. Such callback method invocations will return immediately and will + /// not wait for the JavaScript function to run and so will not provide the return + /// value of the JavaScript function. + /// Nested arrays are supported up to a depth of 3. Arrays of by + /// reference types are not supported. `VT_EMPTY` and `VT_NULL` are mapped + /// into JavaScript as `null`. In JavaScript, `null` and undefined are + /// mapped to `VT_EMPTY`. + /// + /// Additionally, all host objects are exposed as + /// `window.chrome.webview.hostObjects.sync.{name}`. Here the host objects + /// are exposed as synchronous host object proxies. These are not promises + /// and function runtimes or property access synchronously block running + /// script waiting to communicate cross process for the host code to run. + /// Accordingly the result may have reliability issues and it is recommended + /// that you use the promise-based asynchronous + /// `window.chrome.webview.hostObjects.{name}` API. + /// + /// Synchronous host object proxies and asynchronous host object proxies may + /// both use a proxy to the same host object. Remote changes made by one + /// proxy propagates to any other proxy of that same host object whether + /// the other proxies and synchronous or asynchronous. + /// + /// While JavaScript is blocked on a synchronous run to native code, that + /// native code is unable to run back to JavaScript. Attempts to do so fail + /// with `HRESULT_FROM_WIN32(ERROR_POSSIBLE_DEADLOCK)`. + /// + /// Host object proxies are JavaScript Proxy objects that intercept all + /// property get, property set, and method invocations. Properties or methods + /// that are a part of the Function or Object prototype are run locally. + /// Additionally any property or method in the + /// `chrome.webview.hostObjects.options.forceLocalProperties` + /// array are also run locally. This defaults to including optional methods + /// that have meaning in JavaScript like `toJSON` and `Symbol.toPrimitive`. + /// Add more to the array as required. + /// + /// The `chrome.webview.hostObjects.cleanupSome` method performs a best + /// effort garbage collection on host object proxies. + /// + /// The `chrome.webview.hostObjects.options` object provides the ability to + /// change some functionality of host objects. + /// + /// Options property | Details + /// ---|--- + /// `forceLocalProperties` | This is an array of host object property names that will be run locally, instead of being called on the native host object. This defaults to `then`, `toJSON`, `Symbol.toString`, and `Symbol.toPrimitive`. You can add other properties to specify that they should be run locally on the javascript host object proxy. + /// `log` | This is a callback that will be called with debug information. For example, you can set this to `console.log.bind(console)` to have it print debug information to the console to help when troubleshooting host object usage. By default this is null. + /// `shouldSerializeDates` | By default this is false, and javascript Date objects will be sent to host objects as a string using `JSON.stringify`. You can set this property to true to have Date objects properly serialize as a `VT_DATE` when sending to the native host object, and have `VT_DATE` properties and return values create a javascript Date object. + /// `defaultSyncProxy` | When calling a method on a synchronous proxy, the result should also be a synchronous proxy. But in some cases, the sync/async context is lost (for example, when providing to native code a reference to a function, and then calling that function in native code). In these cases, the proxy will be asynchronous, unless this property is set. + /// `forceAsyncMethodMatches ` | This is an array of regular expressions. When calling a method on a synchronous proxy, the method call will be performed asynchronously if the method name matches a string or regular expression in this array. Setting this value to `Async` will make any method that ends with Async be an asynchronous method call. If an async method doesn't match here and isn't forced to be asynchronous, the method will be invoked synchronously, blocking execution of the calling JavaScript and then returning the resolution of the promise, rather than returning a promise. + /// `ignoreMemberNotFoundError` | By default, an exception is thrown when attempting to get the value of a proxy property that doesn't exist on the corresponding native class. Setting this property to `true` switches the behavior to match Chakra WinRT projection (and general JavaScript) behavior of returning `undefined` with no error. + /// `shouldPassTypedArraysAsArrays` | By default, typed arrays are passed to the host as `IDispatch`. To instead pass typed arrays to the host as `array`, set this to `true`. + /// + /// Host object proxies additionally have the following methods which run + /// locally. + /// + /// Method name | Details + /// ---|--- + ///`applyHostFunction`, `getHostProperty`, `setHostProperty` | Perform a method invocation, property get, or property set on the host object. Use the methods to explicitly force a method or property to run remotely if a conflicting local method or property exists. For instance, `proxy.toString()` runs the local `toString` method on the proxy object. But proxy.applyHostFunction('toString') runs `toString` on the host proxied object instead. + ///`getLocalProperty`, `setLocalProperty` | Perform property get, or property set locally. Use the methods to force getting or setting a property on the host object proxy rather than on the host object it represents. For instance, `proxy.unknownProperty` gets the property named `unknownProperty` from the host proxied object. But proxy.getLocalProperty('unknownProperty') gets the value of the property `unknownProperty` on the proxy object. + ///`sync` | Asynchronous host object proxies expose a sync method which returns a promise for a synchronous host object proxy for the same host object. For example, `chrome.webview.hostObjects.sample.methodCall()` returns an asynchronous host object proxy. Use the `sync` method to obtain a synchronous host object proxy instead: `const syncProxy = await chrome.webview.hostObjects.sample.methodCall().sync()`. + ///`async` | Synchronous host object proxies expose an async method which blocks and returns an asynchronous host object proxy for the same host object. For example, `chrome.webview.hostObjects.sync.sample.methodCall()` returns a synchronous host object proxy. Running the `async` method on this blocks and then returns an asynchronous host object proxy for the same host object: `const asyncProxy = chrome.webview.hostObjects.sync.sample.methodCall().async()`. + ///`then` | Asynchronous host object proxies have a `then` method. Allows proxies to be awaitable. `then` returns a promise that resolves with a representation of the host object. If the proxy represents a JavaScript literal, a copy of that is returned locally. If the proxy represents a function, a non-awaitable proxy is returned. If the proxy represents a JavaScript object with a mix of literal properties and function properties, the a copy of the object is returned with some properties as host object proxies. + /// + /// All other property and method invocations (other than the above Remote + /// object proxy methods, `forceLocalProperties` list, and properties on + /// Function and Object prototypes) are run remotely. Asynchronous host + /// object proxies return a promise representing asynchronous completion of + /// remotely invoking the method, or getting the property. The promise + /// resolves after the remote operations complete and the promises resolve to + /// the resulting value of the operation. Synchronous host object proxies + /// work similarly, but block running JavaScript and wait for the remote + /// operation to complete. + /// + /// Setting a property on an asynchronous host object proxy works slightly + /// differently. The set returns immediately and the return value is the + /// value that is set. This is a requirement of the JavaScript Proxy object. + /// If you need to asynchronously wait for the property set to complete, use + /// the `setHostProperty` method which returns a promise as described above. + /// Synchronous object property set property synchronously blocks until the + /// property is set. + /// + /// + /// See the ICoreWebView2 article. + /// + function AddHostObjectToScript(const aName : wvstring; const aObject : OleVariant): boolean; + /// + /// Remove the host object specified by the name so that it is no longer + /// accessible from JavaScript code in the WebView. While new access + /// attempts are denied, if the object is already obtained by JavaScript code + /// in the WebView, the JavaScript code continues to have access to that + /// object. Run this method for a name that is already removed or never + /// added fails. + /// + /// + /// See the ICoreWebView2 article. + /// + function RemoveHostObjectFromScript(const aName : wvstring) : boolean; + /// + /// Add the provided JavaScript to a list of scripts that should be run after + /// the global object has been created, but before the HTML document has + /// been parsed and before any other script included by the HTML document is + /// run. This method injects a script that runs on all top-level document + /// and child frame page navigations. This method runs asynchronously, and + /// you must wait for the completion handler to finish before the injected + /// script is ready to run. When this method completes, the `Invoke` method + /// of the handler is run with the `id` of the injected script. `id` is a + /// string. To remove the injected script, use + /// `RemoveScriptToExecuteOnDocumentCreated`. + /// This function is asynchronous and it triggers the TWVBrowserBase.OnAddScriptToExecuteOnDocumentCreatedCompleted event when it finishes executing. + /// + /// + /// See the ICoreWebView2 article. + /// + function AddScriptToExecuteOnDocumentCreated(const JavaScript : wvstring) : boolean; + /// + /// Remove the corresponding JavaScript added using + /// `AddScriptToExecuteOnDocumentCreated` with the specified script ID. The + /// script ID should be the one returned by the `AddScriptToExecuteOnDocumentCreated`. + /// Both use `AddScriptToExecuteOnDocumentCreated` and this method in `NewWindowRequested` + /// event handler at the same time sometimes causes trouble. Since invalid scripts will + /// be ignored, the script IDs you got may not be valid anymore. + /// + /// + /// See the ICoreWebView2 article. + /// + function RemoveScriptToExecuteOnDocumentCreated(const aID : wvstring) : boolean; + /// + /// Create a cookie object with a specified name, value, domain, and path. + /// One can set other optional properties after cookie creation. + /// This only creates a cookie object and it is not added to the cookie + /// manager until you call AddOrUpdateCookie. + /// Leading or trailing whitespace(s), empty string, and special characters + /// are not allowed for name. + /// See ICoreWebView2Cookie for more details. + /// + /// + /// See the ICoreWebView2CookieManager article. + /// + function CreateCookie(const aName, aValue, aDomain, aPath : wvstring) : ICoreWebView2Cookie; + /// + /// Creates a cookie whose params matches those of the specified cookie. + /// + /// + /// See the ICoreWebView2CookieManager article. + /// + function CopyCookie(const aCookie : ICoreWebView2Cookie) : ICoreWebView2Cookie; + /// + /// Gets a list of cookies matching the specific URI. + /// If uri is empty string or null, all cookies under the same profile are + /// returned. + /// You can modify the cookie objects by calling + /// ICoreWebView2CookieManager.AddOrUpdateCookie, and the changes + /// will be applied to the webview. + /// The TWVBrowserBase.OnGetCookiesCompleted event is triggered asynchronously with the cookies. + /// + /// + /// See the ICoreWebView2CookieManager article. + /// + function GetCookies(const aURI : wvstring = ''): boolean; + /// + /// Adds or updates a cookie with the given cookie data; may overwrite + /// cookies with matching name, domain, and path if they exist. + /// This method will fail if the domain of the given cookie is not specified. + /// + /// + /// See the ICoreWebView2CookieManager article. + /// + function AddOrUpdateCookie(const aCookie : ICoreWebView2Cookie): boolean; + /// + /// Deletes a cookie whose name and domain/path pair + /// match those of the specified cookie. + /// + /// + /// See the ICoreWebView2CookieManager article. + /// + function DeleteCookie(const aCookie : ICoreWebView2Cookie): boolean; + /// + /// Deletes cookies with matching name and uri. + /// Cookie name is required. + /// All cookies with the given name where domain + /// and path match provided URI are deleted. + /// + /// + /// See the ICoreWebView2CookieManager article. + /// + function DeleteCookies(const aName, aURI : wvstring): boolean; + /// + /// Deletes cookies with matching name and domain/path pair. + /// Cookie name is required. + /// If domain is specified, deletes only cookies with the exact domain. + /// If path is specified, deletes only cookies with the exact path. + /// + /// + /// See the ICoreWebView2CookieManager article. + /// + function DeleteCookiesWithDomainAndPath(const aName, aDomain, aPath : wvstring): boolean; + /// + /// Deletes all cookies under the same profile. + /// This could affect other WebViews under the same user profile. + /// + /// + /// See the ICoreWebView2CookieManager article. + /// + function DeleteAllCookies : boolean; + /// + /// Move the parent form to the x and y coordinates. + /// + procedure MoveFormTo(const x, y: Integer); virtual; abstract; + /// + /// Move the parent form adding x and y to the coordinates. + /// + procedure MoveFormBy(const x, y: Integer); virtual; abstract; + /// + /// Add x to the parent form width. + /// + procedure ResizeFormWidthTo(const x : Integer); virtual; abstract; + /// + /// Add y to the parent form height. + /// + procedure ResizeFormHeightTo(const y : Integer); virtual; abstract; + /// + /// Set the parent form left property to x. + /// + procedure SetFormLeftTo(const x : Integer); virtual; abstract; + /// + /// Set the parent form top property to y. + /// + procedure SetFormTopTo(const y : Integer); virtual; abstract; + /// + /// Increments the browser zoom. + /// + /// + /// See the ICoreWebView2Controller article. + /// + procedure IncZoomStep; + /// + /// Decrements the browser zoom. + /// + /// + /// See the ICoreWebView2Controller article. + /// + procedure DecZoomStep; + /// + /// Sets the browser zoom to 100%. + /// + /// + /// See the ICoreWebView2Controller article. + /// + procedure ResetZoom; + /// + /// Updates `Bounds` and `ZoomFactor` properties at the same time. This + /// operation is atomic from the perspective of the host. After returning + /// from this function, the `Bounds` and `ZoomFactor` properties are both + /// updated if the function is successful, or neither is updated if the + /// function fails. If `Bounds` and `ZoomFactor` are both updated by the + /// same scale (for example, `Bounds` and `ZoomFactor` are both doubled), + /// then the page does not display a change in `window.innerWidth` or + /// `window.innerHeight` and the WebView renders the content at the new size + /// and zoom without intermediate renderings. This function also updates + /// just one of `ZoomFactor` or `Bounds` by passing in the new value for one + /// and the current value for the other. + /// + /// + /// See the ICoreWebView2Controller article. + /// + function SetBoundsAndZoomFactor(aBounds: TRect; const aZoomFactor: double) : boolean; + /// + /// Enables or disables all audio output from this browser. + /// + /// + /// See the ICoreWebView2_8 article. + /// + procedure ToggleMuteState; + /// + /// Open the default download dialog. If the dialog is opened before there + /// are recent downloads, the dialog shows all past downloads for the + /// current profile. Otherwise, the dialog shows only the recent downloads + /// with a "See more" button for past downloads. Calling this method raises + /// the `IsDefaultDownloadDialogOpenChanged` event if the dialog was closed. + /// No effect if the dialog is already open. + /// + /// + /// See the ICoreWebView2_9 article. + /// + function OpenDefaultDownloadDialog : boolean; + /// + /// Close the default download dialog. Calling this method raises the + /// IsDefaultDownloadDialogOpenChanged event if the dialog was open. + /// No effect if the dialog is already closed. + /// + /// + /// See the ICoreWebView2_9 article. + /// + function CloseDefaultDownloadDialog : boolean; + /// + /// Simulate editing commands using the "Input.dispatchKeyEvent" DevTools method. + /// + /// + /// See the "Input.dispatchKeyEvent" DevTools method. + /// See the Chromium sources. + /// + function SimulateEditingCommand(aEditingCommand : TWV2EditingCommand): boolean; + /// + /// Dispatches a key event to the page using the "Input.dispatchKeyEvent" + /// DevTools method. The browser has to be focused before simulating any + /// key event. This function is asynchronous and it triggers the + /// TWVBrowserBase.OnSimulateKeyEventCompleted event when it finishes executing. + /// + /// Type of the key event. + /// Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8. + /// Windows virtual key code. + /// Native virtual key code. + /// Time at which the event occurred. + /// Whether the event was from the left or right side of the keyboard. 1=Left, 2=Right. + /// Whether the event was generated from auto repeat. + /// Whether the event was generated from the keypad. + /// Whether the event was a system key event. + /// Text as generated by processing a virtual key code with a keyboard layout. Not needed for for keyUp and rawKeyDown events. + /// Text that would have been generated by the keyboard if no modifiers were pressed (except for shift). Useful for shortcut (accelerator) key handling. + /// Unique key identifier (e.g., 'U+0041'). + /// Unique DOM defined string value for each physical key (e.g., 'KeyA'). + /// Unique DOM defined string value describing the meaning of the key in the context of active modifiers, keyboard layout, etc (e.g., 'AltGr'). + /// + /// See the "Input.dispatchKeyEvent" DevTools method. + /// + function SimulateKeyEvent(type_: TWV2KeyEventType; modifiers, windowsVirtualKeyCode, nativeVirtualKeyCode: integer; timestamp: integer = 0; location: integer = 0; autoRepeat: boolean = False; isKeypad: boolean = False; isSystemKey: boolean = False; const text: wvstring = ''; const unmodifiedtext: wvstring = ''; const keyIdentifier: wvstring = ''; const code: wvstring = ''; const key: wvstring = ''): boolean; virtual; + /// + /// Simulate that the F3 key was pressed and released. + /// The browser has to be focused before simulating any key event. + /// This key information was logged using a Spanish keyboard. It might not work with different keyboard layouts. + /// This function is asynchronous and it triggers the TWVBrowserBase.OnSimulateKeyEventCompleted event several times. + /// + /// + /// See the "Input.dispatchKeyEvent" DevTools method. + /// + function KeyboardShortcutSearch : boolean; virtual; + /// + /// Simulate that SHIFT + F5 keys were pressed and released. + /// The browser has to be focused before simulating any key event. + /// This key information was logged using a Spanish keyboard. It might not work with different keyboard layouts. + /// This function is asynchronous and it triggers the TWVBrowserBase.OnSimulateKeyEventCompleted event several times. + /// + /// + /// See the "Input.dispatchKeyEvent" DevTools method. + /// + function KeyboardShortcutRefreshIgnoreCache : boolean; virtual; + /// + /// This function is only available in "Windowless mode" and provides mouse input meant for the WebView. + /// If eventKind is COREWEBVIEW2_MOUSE_EVENT_KIND_HORIZONTAL_WHEEL or + /// COREWEBVIEW2_MOUSE_EVENT_KIND_WHEEL, then mouseData specifies the amount of + /// wheel movement. A positive value indicates that the wheel was rotated + /// forward, away from the user; a negative value indicates that the wheel was + /// rotated backward, toward the user. One wheel click is defined as + /// WHEEL_DELTA, which is 120. + /// If eventKind is COREWEBVIEW2_MOUSE_EVENT_KIND_X_BUTTON_DOUBLE_CLICK + /// COREWEBVIEW2_MOUSE_EVENT_KIND_X_BUTTON_DOWN, or + /// COREWEBVIEW2_MOUSE_EVENT_KIND_X_BUTTON_UP, then mouseData specifies which X + /// buttons were pressed or released. This value should be 1 if the first X + /// button is pressed/released and 2 if the second X button is + /// pressed/released. + /// If eventKind is COREWEBVIEW2_MOUSE_EVENT_KIND_LEAVE, then virtualKeys, + /// mouseData, and point should all be zero. + /// If eventKind is any other value, then mouseData should be zero. + /// Point is expected to be in the client coordinate space of the WebView. + /// To track mouse events that start in the WebView and can potentially move + /// outside of the WebView and host application, calling SetCapture and + /// ReleaseCapture is recommended. + /// To dismiss hover popups, it is also recommended to send + /// COREWEBVIEW2_MOUSE_EVENT_KIND_LEAVE messages. + /// + /// + /// See the ICoreWebView2CompositionController article. + /// + function SendMouseInput(aEventKind : TWVMouseEventKind; aVirtualKeys : TWVMouseEventVirtualKeys; aMouseData : cardinal; aPoint : TPoint) : boolean; + /// + /// This function is only available in "Windowless mode" and provides pointer input meant for the WebView. + /// SendPointerInput accepts touch or pen pointer input of types defined in + /// COREWEBVIEW2_POINTER_EVENT_KIND. Any pointer input from the system must be + /// converted into an ICoreWebView2PointerInfo first. + /// + /// + /// See the ICoreWebView2CompositionController article. + /// + function SendPointerInput(aEventKind : TWVPointerEventKind; const aPointerInfo : ICoreWebView2PointerInfo) : boolean; + /// + /// This function is only available in "Windowless mode" and corresponds to + /// [IDropTarget::DragEnter](/windows/win32/api/oleidl/nf-oleidl-idroptarget-dragenter). + /// This function has a dependency on AllowExternalDrop property of + /// CoreWebView2Controller and return E_FAIL to callers to indicate this + /// operation is not allowed if AllowExternalDrop property is set to false. + /// The hosting application must register as an IDropTarget and implement + /// and forward DragEnter calls to this function. + /// point parameter must be modified to include the WebView's offset and be in + /// the WebView's client coordinates (Similar to how SendMouseInput works). + /// + /// + /// See the ICoreWebView2CompositionController3 article. + /// + function DragEnter(const dataObject: IDataObject; keyState: LongWord; point: TPoint; out effect: LongWord) : HResult; + /// + /// This function is only available in "Windowless mode" and corresponds to + /// [IDropTarget::DragLeave](/windows/win32/api/oleidl/nf-oleidl-idroptarget-dragleave). + /// This function has a dependency on AllowExternalDrop property of + /// CoreWebView2Controller and return E_FAIL to callers to indicate this + /// operation is not allowed if AllowExternalDrop property is set to false. + /// The hosting application must register as an IDropTarget and implement + /// and forward DragLeave calls to this function. + /// + /// + /// See the ICoreWebView2CompositionController3 article. + /// + function DragLeave : HResult; + /// + /// This function is only available in "Windowless mode" and corresponds to + /// [IDropTarget::DragOver](/windows/win32/api/oleidl/nf-oleidl-idroptarget-dragover). + /// This function has a dependency on AllowExternalDrop property of + /// CoreWebView2Controller and return E_FAIL to callers to indicate this + /// operation is not allowed if AllowExternalDrop property is set to false. + /// The hosting application must register as an IDropTarget and implement + /// and forward DragOver calls to this function. + /// point parameter must be modified to include the WebView's offset and be in + /// the WebView's client coordinates (Similar to how SendMouseInput works). + /// + /// + /// See the ICoreWebView2CompositionController3 article. + /// + function DragOver(keyState: LongWord; point: TPoint; out effect: LongWord) : HResult; + /// + /// This function is only available in "Windowless mode" and corresponds to + /// [IDropTarget::Drop](/windows/win32/api/oleidl/nf-oleidl-idroptarget-drop). + /// This function has a dependency on AllowExternalDrop property of + /// CoreWebView2Controller and return E_FAIL to callers to indicate this + /// operation is not allowed if AllowExternalDrop property is set to false. + /// The hosting application must register as an IDropTarget and implement + /// and forward Drop calls to this function. + /// point parameter must be modified to include the WebView's offset and be in + /// the WebView's client coordinates (Similar to how SendMouseInput works). + /// + /// + /// See the ICoreWebView2CompositionController3 article. + /// + function Drop(const dataObject: IDataObject; keyState: LongWord; point: TPoint; out effect: LongWord) : HResult; + /// + /// If you are hosting a WebView2 using CoreWebView2CompositionController, you can call + /// this method in your Win32 WndProc to determine if the mouse is moving over or + /// clicking on WebView2 web content that should be considered part of a non-client region. + /// The point parameter is expected to be in the client coordinate space of WebView2. + /// The method sets the out parameter value as follows: + /// + /// - COREWEBVIEW2_NON_CLIENT_REGION_KIND_CAPTION when point corresponds to + /// a region (HTML element) within the WebView2 with + /// `-webkit-app-region: drag` CSS style set. + /// - COREWEBVIEW2_NON_CLIENT_REGION_KIND_CLIENT when point corresponds to + /// a region (HTML element) within the WebView2 without + /// `-webkit-app-region: drag` CSS style set. + /// - COREWEBVIEW2_NON_CLIENT_REGION_KIND_NOWHERE when point is not within the WebView2. + /// + /// NOTE: in order for WebView2 to properly handle the title bar system menu, + /// the app needs to send WM_NCRBUTTONDOWN and WM_NCRBUTTONUP to SendMouseInput. + /// + /// + /// See the ICoreWebView2CompositionController4 article. + /// + function GetNonClientRegionAtPoint(point: TPoint) : TWVNonClientRegionKind; + /// + /// This method is used to get the collection of rects that correspond + /// to a particular TWVNonClientRegionKind. This is to be used in + /// the callback of add_NonClientRegionChanged whose event args object contains + /// a region property of type TWVNonClientRegionKind. + /// + /// + /// See the ICoreWebView2CompositionController4 article. + /// + function QueryNonClientRegion(Kind: TWVNonClientRegionKind): ICoreWebView2RegionRectCollectionView; + /// + /// Clears the browser cache. This function is asynchronous and it triggers the TWVBrowserBase.OnClearCacheCompleted event when it finishes executing. + /// + /// + /// See the Chrome DevTools Protocol page about the Network.clearBrowserCache method. + /// + function ClearCache : boolean; + /// + /// Clears the storage for origin. This function is asynchronous and it triggers the TWVBrowserBase.OnClearDataForOriginCompleted event when it finishes executing. + /// + /// + /// See the documentation for the Storage.clearDataForOrigin DevTools method. + /// See the documentation for the Storage.StorageType type. + /// + function ClearDataForOrigin(const aOrigin : wvstring; aStorageTypes : TWVClearDataStorageTypes = cdstAll) : boolean; + /// + /// Clear browsing data based on a data type. This method takes two parameters, + /// the first being a mask of one or more `COREWEBVIEW2_BROWSING_DATA_KINDS`. OR + /// operation(s) can be applied to multiple `COREWEBVIEW2_BROWSING_DATA_KINDS` to + /// create a mask representing those data types. + /// This function is asynchronous and it triggers the TWVBrowserBase.OnClearBrowsingDataCompleted event when it finishes executing. + /// + /// + /// See the ICoreWebView2Profile2 article. + /// + function ClearBrowsingData(dataKinds: TWVBrowsingDataKinds): boolean; + /// + /// ClearBrowsingDataInTimeRange behaves like ClearBrowsingData except that it + /// takes in two additional parameters for the start and end time for which it + /// should clear the data between. The `startTime` and `endTime` + /// parameters correspond to the number of seconds since the UNIX epoch. + /// `startTime` is inclusive while `endTime` is exclusive, therefore the data will + /// be cleared between startTime and endTime. + /// This function is asynchronous and it triggers the TWVBrowserBase.OnClearBrowsingDataCompleted event when it finishes executing. + /// + /// + /// See the ICoreWebView2Profile2 article. + /// + function ClearBrowsingDataInTimeRange(dataKinds: TWVBrowsingDataKinds; const startTime, endTime: TDateTime): boolean; + /// + /// ClearBrowsingDataAll behaves like ClearBrowsingData except that it + /// clears the entirety of the data associated with the profile it is called on. + /// It clears the data regardless of timestamp. + /// This function is asynchronous and it triggers the TWVBrowserBase.OnClearBrowsingDataCompleted event when it finishes executing. + /// + /// + /// See the ICoreWebView2Profile2 article. + /// + function ClearBrowsingDataAll: boolean; + /// + /// Clears all cached decisions to proceed with TLS certificate errors from the + /// OnServerCertificateErrorDetected event for all WebView2's sharing the same session. + /// This function is asynchronous and it triggers the TWVBrowserBase.OnServerCertificateErrorActionsCompleted event when it finishes executing. + /// + /// + /// See the ICoreWebView2_14 article. + /// + function ClearServerCertificateErrorActions : boolean; + /// + /// Async function for getting the actual image data of the favicon. + /// This function is asynchronous and it triggers the TWVBrowserBase.OnGetFaviconCompleted event when it finishes executing. + /// + /// + /// See the ICoreWebView2_15 article. + /// + function GetFavicon(aFormat: TWVFaviconImageFormat = COREWEBVIEW2_FAVICON_IMAGE_FORMAT_PNG) : boolean; + /// + /// Create a shared memory based buffer with the specified size in bytes. + /// The buffer can be shared with web contents in WebView by calling + /// `PostSharedBufferToScript` on `CoreWebView2` or `CoreWebView2Frame` object. + /// Once shared, the same content of the buffer will be accessible from both + /// the app process and script in WebView. Modification to the content will be visible + /// to all parties that have access to the buffer. + /// The shared buffer is presented to the script as ArrayBuffer. All JavaScript APIs + /// that work for ArrayBuffer including Atomics APIs can be used on it. + /// There is currently a limitation that only size less than 2GB is supported. + /// + /// + /// See the ICoreWebView2Environment12 article. + /// + function CreateSharedBuffer(aSize : Largeuint; var aSharedBuffer : ICoreWebView2SharedBuffer) : boolean; + /// + /// Share a shared buffer object with script of the main frame in the WebView. + /// The script will receive a `sharedbufferreceived` event from chrome.webview. + /// Read the linked article for all the details. + /// + /// + /// See the ICoreWebView2_17 article. + /// + function PostSharedBufferToScript(const aSharedBuffer: ICoreWebView2SharedBuffer; aAccess: TWVSharedBufferAccess; const aAdditionalDataAsJson: wvstring): boolean; + /// + /// Gets a snapshot collection of `ProcessExtendedInfo`s corresponding to all + /// currently running processes associated with this `ICoreWebView2Environment` + /// excludes crashpad process. + /// This provides the same list of `ProcessInfo`s as what's provided in + /// `GetProcessInfos`, but additionally provides a list of associated `FrameInfo`s + /// which are actively running (showing or hiding UI elements) in the renderer + /// process. See `AssociatedFrameInfos` for more information. + /// + /// True if successfull. + /// + /// See the ICoreWebView2Environment13 article. + /// This function triggers the TWVBrowserBase.OnGetProcessExtendedInfosCompleted event. + /// + function GetProcessExtendedInfos : boolean; + /// + /// Programmatically trigger a Save As action for the currently loaded document. + /// Opens a system modal dialog by default. If the `SuppressDefaultDialog` property + /// is `TRUE`, the system dialog is not opened. + /// This method returns `COREWEBVIEW2_SAVE_AS_UI_RESULT`. See + /// `COREWEBVIEW2_SAVE_AS_UI_RESULT` for details. + /// + /// True if successfull. + /// + /// See the ICoreWebView2_25 article. + /// This function triggers the TWVBrowserBase.OnSaveAsUIShowing and TWVBrowserBase.OnShowSaveAsUICompleted events. + /// + function ShowSaveAsUI : boolean; + /// + /// Initiates a find using the specified find options asynchronously. + /// Displays the Find bar and starts the find session. If a find session was already ongoing, it will be stopped and replaced with this new instance. + /// If called with an empty string, the Find bar is displayed but no finding occurs. Changing the FindOptions object after initiation won't affect the ongoing find session. + /// To change the ongoing find session, Start must be called again with a new or modified FindOptions object. + /// Start supports HTML and TXT document queries. In general, this API is designed for text-based find sessions. + /// If you start a find session programmatically on another file format that doesn't have text fields, the find session will try to execute but will fail to find any matches. (It will silently fail) + /// Note: The asynchronous action completes when the UI has been displayed with the find term in the UI bar, and the matches have populated on the counter on the find bar. + /// There may be a slight latency between the UI display and the matches populating in the counter. + /// The MatchCountChanged and ActiveMatchIndexChanged events are only raised after Start has completed; otherwise, they will have their default values (-1 for active match index and 0 for match count). + /// To start a new find session (beginning the search from the first match), call `Stop` before invoking `Start`. + /// If `Start` is called consecutively with the same options and without calling `Stop`, the find session + /// will continue from the current position in the existing session. + /// Calling `Start` without altering its parameters will behave either as `FindNext` or `FindPrevious`, depending on the most recent search action performed. + /// Start will default to forward if neither have been called. + /// However, calling Start again during an ongoing find session does not resume from the point + /// of the current active match. For example, given the text "1 1 A 1 1" and initiating a find session for "A", + /// then starting another find session for "1", it will start searching from the beginning of the document, + /// regardless of the previous active match. This behavior indicates that changing the find query initiates a + /// completely new find session, rather than continuing from the previous match index. + /// + /// + /// See the ICoreWebView2Find article. + /// + function FindStart(const aFindTerm : wvstring) : boolean; + /// + /// Navigates to the next match in the document. + /// If there are no matches to find, FindNext will wrap around to the first match's index. + /// If called when there is no find session active, FindNext will silently fail. + /// + /// + /// See the ICoreWebView2Find article. + /// + function FindNext : boolean; + /// + /// Navigates to the previous match in the document. + /// If there are no matches to find, FindPrevious will wrap around to the last match's index. + /// If called when there is no find session active, FindPrevious will silently fail. + /// + /// + /// See the ICoreWebView2Find article. + /// + function FindPrevious : boolean; + /// + /// Stops the current 'Find' session and hides the Find bar. + /// If called with no Find session active, it will silently do nothing. + /// + /// + /// See the ICoreWebView2Find article. + /// + function FindStop : boolean; + + // Custom properties + property Initialized : boolean read GetInitialized; + /// + /// Settings used for printing. + /// + /// + /// See the ICoreWebView2PrintSettings article. + /// + property CoreWebView2PrintSettings : TCoreWebView2PrintSettings read FCoreWebView2PrintSettings; + /// + /// CoreWebView2Settings contains various modifiable settings for the running WebView. + /// + /// + /// See the ICoreWebView2Settings article. + /// + property CoreWebView2Settings : TCoreWebView2Settings read FCoreWebView2Settings; + /// + /// Represents the WebView2 Environment. + /// + /// + /// See the ICoreWebView2Environment article. + /// + property CoreWebView2Environment : TCoreWebView2Environment read FCoreWebView2Environment; + /// + /// The owner of the `CoreWebView2` object that provides support for resizing, + /// showing and hiding, focusing, and other functionality related to + /// windowing and composition. The `CoreWebView2Controller` owns the + /// `CoreWebView2`, and if all references to the `CoreWebView2Controller` go + /// away, the WebView is closed. + /// + /// + /// See the ICoreWebView2Controller article. + /// + property CoreWebView2Controller : TCoreWebView2Controller read FCoreWebView2Controller; + /// + /// ICoreWebView2CompositionController wrapper used by this browser. + /// This interface is an extension of the ICoreWebView2Controller interface to + /// support visual hosting. An object implementing the + /// ICoreWebView2CompositionController interface will also implement + /// ICoreWebView2Controller. Callers are expected to use + /// ICoreWebView2Controller for resizing, visibility, focus, and so on, and + /// then use ICoreWebView2CompositionController to connect to a composition + /// tree and provide input meant for the WebView. + /// + /// + /// See the ICoreWebView2CompositionController article. + /// + property CoreWebView2CompositionController : TCoreWebView2CompositionController read FCoreWebView2CompositionController; + /// + /// ICoreWebView2 wrapper used by this browser. + /// + /// + /// See the ICoreWebView2 article. + /// + property CoreWebView2 : TCoreWebView2 read FCoreWebView2; + /// + /// The associated `ICoreWebView2Profile` object. If this CoreWebView2 was created with a + /// CoreWebView2ControllerOptions, the CoreWebView2Profile will match those specified options. + /// Otherwise if this CoreWebView2 was created without a CoreWebView2ControllerOptions, then + /// this will be the default CoreWebView2Profile for the corresponding CoreWebView2Environment. + /// + /// + /// See the ICoreWebView2_13 article. + /// + property Profile : TCoreWebView2Profile read FCoreWebView2Profile; + /// + /// First URL loaded by the browser after its creation. + /// + property DefaultURL : wvstring read FDefaultURL write FDefaultURL; + /// + /// Returns true after OnNavigationStarting and before OnNavigationCompleted. + /// + property IsNavigating : boolean read FIsNavigating; + /// + /// Returns the current zoom value. + /// + /// + /// See the ICoreWebView2Controller article. + /// + property ZoomPct : double read GetZoomPct write SetZoomPct; + /// + /// Returns the current zoom value. + /// + /// + /// See the ICoreWebView2Controller article. + /// + property ZoomStep : byte read FZoomStep write SetZoomStep; + /// + /// Handle of one to the child controls created automatically by the browser to show the web contents. + /// + property Widget0CompHWND : THandle read FWidget0CompHWND; + /// + /// Handle of one to the child controls created automatically by the browser to show the web contents. + /// + property Widget1CompHWND : THandle read FWidget1CompHWND; + /// + /// Handle of one to the child controls created automatically by the browser to show the web contents. + /// + property RenderCompHWND : THandle read FRenderCompHWND; + /// + /// Handle of one to the child controls created automatically by the browser to show the web contents. + /// + property D3DWindowCompHWND : THandle read FD3DWindowCompHWND; + /// + /// Returns the GlobalWebView2Loader.DeviceScaleFactor value. + /// + property ScreenScale : single read GetScreenScale; + /// + /// Uses the Network.emulateNetworkConditions DevTool method to set the browser in offline mode. + /// The TWVBrowserBase.OnOfflineCompleted event is triggered asynchronously after setting this property. + /// + /// + /// See the Network Domain article. + /// + property Offline : boolean read FOffline write SetOffline; + /// + /// Uses the Security.setIgnoreCertificateErrors DevTool method to enable/disable whether all certificate errors should be ignored. + /// The TWVBrowserBase.OnIgnoreCertificateErrorsCompleted event is triggered asynchronously after setting this property. + /// + /// + /// See the Security Domain article. + /// + property IgnoreCertificateErrors : boolean read FIgnoreCertificateErrors write SetIgnoreCertificateErrors; + + // Properties used in the ICoreWebView2Environment creation + property BrowserExecPath : wvstring read FBrowserExecPath write FBrowserExecPath; + /// + /// Returns the user data folder that all CoreWebView2's created from this + /// environment are using. + /// This could be either the value passed in by the developer when creating + /// the environment object or the calculated one for default handling. It + /// will always be an absolute path. + /// + /// + /// See the ICoreWebView2Environment7 article. + /// + property UserDataFolder : wvstring read GetUserDataFolder write FUserDataFolder; + /// + /// Additional command line switches. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions.get_AdditionalBrowserArguments. + /// See the ICoreWebView2EnvironmentOptions article. + /// + property AdditionalBrowserArguments : wvstring read FAdditionalBrowserArguments write FAdditionalBrowserArguments; + /// + /// The default display language for WebView. It applies to browser UI such as + /// context menu and dialogs. It also applies to the `accept-languages` HTTP + /// header that WebView sends to websites. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions.get_Language. + /// See the ICoreWebView2EnvironmentOptions article. + /// + property Language : wvstring read FLanguage write FLanguage; + /// + /// Specifies the version of the WebView2 Runtime binaries required to be + /// compatible with your app. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions.get_TargetCompatibleBrowserVersion. + /// See the ICoreWebView2EnvironmentOptions article. + /// + property TargetCompatibleBrowserVersion : wvstring read FTargetCompatibleBrowserVersion write FTargetCompatibleBrowserVersion; + /// + /// Used to enable single sign on with Azure Active Directory (AAD) and personal Microsoft + /// Account (MSA) resources inside WebView. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions.get_AllowSingleSignOnUsingOSPrimaryAccount. + /// See the ICoreWebView2EnvironmentOptions article. + /// + property AllowSingleSignOnUsingOSPrimaryAccount : boolean read FAllowSingleSignOnUsingOSPrimaryAccount write FAllowSingleSignOnUsingOSPrimaryAccount; + /// + /// Whether other processes can create WebView2 from WebView2Environment created with the + /// same user data folder and therefore sharing the same WebView browser process instance. + /// Default is FALSE. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions2.Get_ExclusiveUserDataFolderAccess. + /// See the ICoreWebView2EnvironmentOptions2 article. + /// + property ExclusiveUserDataFolderAccess : boolean read FExclusiveUserDataFolderAccess write FExclusiveUserDataFolderAccess; + /// + /// When `CustomCrashReportingEnabled` is set to `TRUE`, Windows won't send crash data to Microsoft endpoint. + /// `CustomCrashReportingEnabled` is default to be `FALSE`, in this case, WebView will respect OS consent. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions3.Get_IsCustomCrashReportingEnabled. + /// See the ICoreWebView2EnvironmentOptions3 article. + /// + property CustomCrashReportingEnabled : boolean read FCustomCrashReportingEnabled write FCustomCrashReportingEnabled; + /// + /// The `EnableTrackingPrevention` property is used to enable/disable tracking prevention + /// feature in WebView2. This property enable/disable tracking prevention for all the + /// WebView2's created in the same environment. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions5.Get_EnableTrackingPrevention. + /// See the ICoreWebView2EnvironmentOptions5 article. + /// + property EnableTrackingPrevention : boolean read FEnableTrackingPrevention write FEnableTrackingPrevention; + /// + /// When `AreBrowserExtensionsEnabled` is set to `TRUE`, new extensions can be added to user + /// profile and used. `AreBrowserExtensionsEnabled` is default to be `FALSE`, in this case, + /// new extensions can't be installed, and already installed extension won't be + /// available to use in user profile. + /// If connecting to an already running environment with a different value for `AreBrowserExtensionsEnabled` + /// property, it will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions6.Get_AreBrowserExtensionsEnabled. + /// See the ICoreWebView2EnvironmentOptions6 article. + /// See the ICoreWebView2BrowserExtension article for Extensions API details. + /// + property AreBrowserExtensionsEnabled : boolean read FAreBrowserExtensionsEnabled write FAreBrowserExtensionsEnabled; + /// + /// The `ChannelSearchKind` property is `COREWEBVIEW2_CHANNEL_SEARCH_KIND_MOST_STABLE` + /// by default; environment creation searches for a release channel on the machine + /// from most to least stable using the first channel found. The default search order is: + /// WebView2 Runtime -> Beta -> Dev -> Canary. Set `ChannelSearchKind` to + /// `COREWEBVIEW2_CHANNEL_SEARCH_KIND_LEAST_STABLE` to reverse the search order + /// so that environment creation searches for a channel from least to most stable. If + /// `ReleaseChannels` has been provided, the loader will only search + /// for channels in the set. See `COREWEBVIEW2_RELEASE_CHANNELS` for more details + /// on channels. + /// This property can be overridden by the corresponding + /// registry key `ChannelSearchKind` or the environment variable + /// `WEBVIEW2_CHANNEL_SEARCH_KIND`. Set the value to `1` to set the search kind to + /// `COREWEBVIEW2_CHANNEL_SEARCH_KIND_LEAST_STABLE`. See + /// `CreateCoreWebView2EnvironmentWithOptions` for more details on overrides. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions7.Get_ChannelSearchKind. + /// See the ICoreWebView2EnvironmentOptions7 article. + /// + property ChannelSearchKind : TWVChannelSearchKind read FChannelSearchKind write FChannelSearchKind; + /// + /// Sets the `ReleaseChannels`, which is a mask of one or more + /// `COREWEBVIEW2_RELEASE_CHANNELS` indicating which channels environment + /// creation should search for. OR operation(s) can be applied to multiple + /// `COREWEBVIEW2_RELEASE_CHANNELS` to create a mask. The default value is a + /// a mask of all the channels. By default, environment creation searches for + /// channels from most to least stable, using the first channel found on the + /// device. When `ReleaseChannels` is provided, environment creation will only + /// search for the channels specified in the set. Set `ChannelSearchKind` to + /// `COREWEBVIEW2_CHANNEL_SEARCH_KIND_LEAST_STABLE` to reverse the search order + /// so environment creation searches for least stable build first. See + /// `COREWEBVIEW2_RELEASE_CHANNELS` for descriptions of each channel. + /// `CreateCoreWebView2EnvironmentWithOptions` fails with + /// `HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)` if environment creation is unable + /// to find any channel from the `ReleaseChannels` installed on the device. + /// Use `GetAvailableCoreWebView2BrowserVersionStringWithOptions` on + /// `ICoreWebView2Environment` to verify which channel is used when this option + /// is set. + /// Examples: + /// + /// | ReleaseChannels | Channel Search Kind: Most Stable (default) | Channel Search Kind: Least Stable | + /// | --- | --- | --- | + /// |COREWEBVIEW2_RELEASE_CHANNELS_BETA \| COREWEBVIEW2_RELEASE_CHANNELS_STABLE| WebView2 Runtime -> Beta | Beta -> WebView2 Runtime| + /// |COREWEBVIEW2_RELEASE_CHANNELS_CANARY \| COREWEBVIEW2_RELEASE_CHANNELS_DEV \| COREWEBVIEW2_RELEASE_CHANNELS_BETA \| COREWEBVIEW2_RELEASE_CHANNELS_STABLE| WebView2 Runtime -> Beta -> Dev -> Canary | Canary -> Dev -> Beta -> WebView2 Runtime | + /// |COREWEBVIEW2_RELEASE_CHANNELS_CANARY| Canary | Canary | + /// |COREWEBVIEW2_RELEASE_CHANNELS_BETA \| COREWEBVIEW2_RELEASE_CHANNELS_CANARY \| COREWEBVIEW2_RELEASE_CHANNELS_STABLE | WebView2 Runtime -> Beta -> Canary | Canary -> Beta -> WebView2 Runtime | + /// + /// If both `BrowserExecutableFolder` and `ReleaseChannels` are provided, the + /// `BrowserExecutableFolder` takes precedence, regardless of whether or not the + /// channel of `BrowserExecutableFolder` is included in the `ReleaseChannels`. + /// `ReleaseChannels` can be overridden by the corresponding registry override + /// `ReleaseChannels` or the environment variable `WEBVIEW2_RELEASE_CHANNELS`. + /// Set the value to a comma-separated string of integers, which map to the + /// following release channel values: Stable (0), Beta (1), Dev (2), and + /// Canary (3). For example, the values "0,2" and "2,0" indicate that environment + /// creation should only search for Dev channel and the WebView2 Runtime, using the + /// order indicated by `ChannelSearchKind`. Environment creation attempts to + /// interpret each integer and treats any invalid entry as Stable channel. See + /// `CreateCoreWebView2EnvironmentWithOptions` for more details on overrides. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions7.Get_ReleaseChannels. + /// See the ICoreWebView2EnvironmentOptions7 article. + /// + property ReleaseChannels : TWVReleaseChannels read FReleaseChannels write FReleaseChannels; + /// + /// The ScrollBar style being set on the WebView2 Environment. + /// The default value is `COREWEBVIEW2_SCROLLBAR_STYLE_DEFAULT` + /// which specifies the default browser ScrollBar style. + /// The `color-scheme` CSS property needs to be set on the corresponding page + /// to allow ScrollBar to follow light or dark theme. Please see + /// [color-scheme](https://developer.mozilla.org/docs/Web/CSS/color-scheme#declaring_color_scheme_preferences) + /// for how `color-scheme` can be set. + /// CSS styles that modify the ScrollBar applied on top of native ScrollBar styling + /// that is selected with `ScrollBarStyle`. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions8.Get_ScrollBarStyle. + /// See the ICoreWebView2EnvironmentOptions8 article. + /// + property ScrollBarStyle : TWVScrollBarStyle read FScrollBarStyle write FScrollBarStyle; + /// + /// The browser version info of the current `ICoreWebView2Environment`, + /// including channel name if it is not the WebView2 Runtime. It matches the + /// format of the `GetAvailableCoreWebView2BrowserVersionString` API. + /// Channel names are `beta`, `dev`, and `canary`. + /// + /// + /// See the ICoreWebView2Environment article. + /// + property BrowserVersionInfo : wvstring read GetBrowserVersionInfo; + /// + /// The process ID of the browser process that hosts the WebView. + /// + /// + /// See the ICoreWebView2 article. + /// + property BrowserProcessID : cardinal read GetBrowserProcessID; + /// + /// `TRUE` if the WebView is able to navigate to a previous page in the + /// navigation history. If `CanGoBack` changes value, the `HistoryChanged` + /// event runs. + /// + /// + /// See the ICoreWebView2 article. + /// + property CanGoBack : boolean read GetCanGoBack; + /// + /// `TRUE` if the WebView is able to navigate to a next page in the + /// navigation history. If `CanGoForward` changes value, the + /// `HistoryChanged` event runs. + /// + /// + /// See the ICoreWebView2 article. + /// + property CanGoForward : boolean read GetCanGoForward; + /// + /// Indicates if the WebView contains a fullscreen HTML element. + /// + /// + /// See the ICoreWebView2 article. + /// + property ContainsFullScreenElement : boolean read GetContainsFullScreenElement; + /// + /// The title for the current top-level document. If the document has no + /// explicit title or is otherwise empty, a default that may or may not match + /// the URI of the document is used. + /// + /// + /// See the ICoreWebView2 article. + /// + property DocumentTitle : wvstring read GetDocumentTitle; + /// + /// The URI of the current top level document. This value potentially + /// changes as a part of the `SourceChanged` event that runs for some cases + /// such as navigating to a different site or fragment navigations. It + /// remains the same for other types of navigations such as page refreshes + /// or `history.pushState` with the same URL as the current page. + /// + /// + /// See the ICoreWebView2 article. + /// + property Source : wvstring read GetSource; + /// + /// Gets the cookie manager object associated with this ICoreWebView2. + /// See ICoreWebView2CookieManager. + /// + /// + /// See the ICoreWebView2_2 article. + /// + property CookieManager : ICoreWebView2CookieManager read GetCookieManager; + /// + /// Whether WebView is suspended. + /// `TRUE` when WebView is suspended, from the time when TrySuspend has completed + /// successfully until WebView is resumed. + /// + /// + /// See the ICoreWebView2_3 article. + /// + property IsSuspended : boolean read GetIsSuspended; + /// + /// Indicates whether any audio output from this CoreWebView2 is playing. + /// This property will be true if audio is playing even if IsMuted is true. + /// + /// + /// See the ICoreWebView2_8 article. + /// + property IsDocumentPlayingAudio : boolean read GetIsDocumentPlayingAudio; + /// + /// Indicates whether all audio output from this CoreWebView2 is muted or not. + /// + /// + /// See the ICoreWebView2_8 article. + /// + property IsMuted : boolean read GetIsMuted write SetIsMuted; + /// + /// Get the default download dialog corner alignment. + /// + /// + /// See the ICoreWebView2_9 article. + /// + property DefaultDownloadDialogCornerAlignment : TWVDefaultDownloadDialogCornerAlignment read GetDefaultDownloadDialogCornerAlignment write SetDefaultDownloadDialogCornerAlignment; + /// + /// Get the default download dialog margin. + /// + /// + /// See the ICoreWebView2_9 article. + /// + property DefaultDownloadDialogMargin : TPoint read GetDefaultDownloadDialogMargin write SetDefaultDownloadDialogMargin; + /// + /// `TRUE` if the default download dialog is currently open. The value of this + /// property changes only when the default download dialog is explicitly + /// opened or closed. Hiding the WebView implicitly hides the dialog, but does + /// not change the value of this property. + /// + /// + /// See the ICoreWebView2_9 article. + /// + property IsDefaultDownloadDialogOpen : boolean read GetIsDefaultDownloadDialogOpen; + /// + /// The status message text. + /// + /// + /// See the ICoreWebView2_12 article. + /// + property StatusBarText : wvstring read GetStatusBarText; + /// + /// Get the current Uri of the favicon as a string. + /// If the value is null, then the return value is `E_POINTER`, otherwise it is `S_OK`. + /// If a page has no favicon then the value is an empty string. + /// + /// + /// See the ICoreWebView2_15 article. + /// + property FaviconURI : wvstring read GetFaviconURI; + /// + /// `MemoryUsageTargetLevel` indicates desired memory consumption level of + /// WebView. + /// + /// + /// See the ICoreWebView2_19 article. + /// + property MemoryUsageTargetLevel : TWVMemoryUsageTargetLevel read GetMemoryUsageTargetLevel write SetMemoryUsageTargetLevel; + /// + /// The WebView bounds. Bounds are relative to the parent `HWND`. The app + /// has two ways to position a WebView. + /// * Create a child `HWND` that is the WebView parent `HWND`. Position + /// the window where the WebView should be. Use `(0, 0)` for the + /// top-left corner (the offset) of the `Bounds` of the WebView. + /// * Use the top-most window of the app as the WebView parent HWND. For + /// example, to position WebView correctly in the app, set the top-left + /// corner of the Bound of the WebView. + /// The values of `Bounds` are limited by the coordinate space of the host. + /// + /// + /// See the ICoreWebView2Controller article. + /// + property Bounds : TRect read GetBounds write SetBounds; + /// + /// The `IsVisible` property determines whether to show or hide the WebView2. + /// If `IsVisible` is set to `FALSE`, the WebView2 is transparent and is + /// not rendered. However, this does not affect the window containing the + /// WebView2 (the `HWND` parameter that was passed to + /// `CreateCoreWebView2Controller`). If you want that window to disappear + /// too, run `ShowWindow` on it directly in addition to modifying the + /// `IsVisible` property. WebView2 as a child window does not get window + /// messages when the top window is minimized or restored. For performance + /// reasons, developers should set the `IsVisible` property of the WebView to + /// `FALSE` when the app window is minimized and back to `TRUE` when the app + /// window is restored. The app window does this by handling + /// `SIZE_MINIMIZED and SIZE_RESTORED` command upon receiving `WM_SIZE` + /// message. + /// There are CPU and memory benefits when the page is hidden. For instance, + /// Chromium has code that throttles activities on the page like animations + /// and some tasks are run less frequently. Similarly, WebView2 will + /// purge some caches to reduce memory usage. + /// + /// + /// See the ICoreWebView2Controller article. + /// + property IsVisible : boolean read GetIsVisible write SetIsVisible; + /// + /// The parent window provided by the app that this WebView is using to + /// render content. This API initially returns the window passed into + /// `CreateCoreWebView2Controller`. + /// + /// + /// See the ICoreWebView2Controller article. + /// See the WebView4Delphi issue #13 to know how to reparent a browser. + /// + property ParentWindow : THandle read GetParentWindow write SetParentWindow; + /// + /// The zoom factor for the WebView. + /// + /// + /// See the ICoreWebView2Controller article. + /// + property ZoomFactor : double read GetZoomFactor write SetZoomFactor; + /// + /// The `DefaultBackgroundColor` property is the color WebView renders + /// underneath all web content. This means WebView renders this color when + /// there is no web content loaded such as before the initial navigation or + /// between navigations. This also means web pages with undefined css + /// background properties or background properties containing transparent + /// pixels will render their contents over this color. Web pages with defined + /// and opaque background properties that span the page will obscure the + /// `DefaultBackgroundColor` and display normally. The default value for this + /// property is white to resemble the native browser experience. + /// The Color is specified by the COREWEBVIEW2_COLOR that represents an RGBA + /// value. The `A` represents an Alpha value, meaning + /// `DefaultBackgroundColor` can be transparent. In the case of a transparent + /// `DefaultBackgroundColor` WebView will render hosting app content as the + /// background. This Alpha value is not supported on Windows 7. Any `A` value + /// other than 255 will result in E_INVALIDARG on Windows 7. + /// It is supported on all other WebView compatible platforms. + /// Semi-transparent colors are not currently supported by this API and + /// setting `DefaultBackgroundColor` to a semi-transparent color will fail + /// with E_INVALIDARG. The only supported alpha values are 0 and 255, all + /// other values will result in E_INVALIDARG. + /// `DefaultBackgroundColor` can only be an opaque color or transparent. + /// This value may also be set by using the + /// `WEBVIEW2_DEFAULT_BACKGROUND_COLOR` environment variable. There is a + /// known issue with background color where setting the color by API can + /// still leave the app with a white flicker before the + /// `DefaultBackgroundColor` takes effect. Setting the color via environment + /// variable solves this issue. The value must be a hex value that can + /// optionally prepend a 0x. The value must account for the alpha value + /// which is represented by the first 2 digits. So any hex value fewer than 8 + /// digits will assume a prepended 00 to the hex value and result in a + /// transparent color. + /// `get_DefaultBackgroundColor` will return the result of this environment + /// variable if used. This environment variable can only set the + /// `DefaultBackgroundColor` once. Subsequent updates to background color + /// must be done through API call. + /// + /// + /// The only supported alpha values are 0 (transparent) and 255 (opaque). Remember to set the alpha channel manually when using predefined TColor values. + /// See the ICoreWebView2Controller2 article. + /// + property DefaultBackgroundColor : TColor read GetDefaultBackgroundColor write SetDefaultBackgroundColor; + /// + /// BoundsMode affects how setting the Bounds and RasterizationScale + /// properties work. Bounds mode can either be in COREWEBVIEW2_BOUNDS_MODE_USE_RAW_PIXELS + /// mode or COREWEBVIEW2_BOUNDS_MODE_USE_RASTERIZATION_SCALE mode. + /// When the mode is in COREWEBVIEW2_BOUNDS_MODE_USE_RAW_PIXELS, setting the bounds + /// property will set the size of the WebView in raw screen pixels. Changing + /// the rasterization scale in this mode won't change the raw pixel size of + /// the WebView and will only change the rasterization scale. + /// When the mode is in COREWEBVIEW2_BOUNDS_MODE_USE_RASTERIZATION_SCALE, setting the + /// bounds property will change the logical size of the WebView which can be + /// described by the following equation: Logical size * rasterization scale = Raw Pixel size + /// In this case, changing the rasterization scale will keep the logical size + /// the same and change the raw pixel size. + /// + /// + /// See the ICoreWebView2Controller3 article. + /// + property BoundsMode : TWVBoundsMode read GetBoundsMode write SetBoundsMode; + /// + /// The rasterization scale for the WebView. The rasterization scale is the + /// combination of the monitor DPI scale and text scaling set by the user. + /// This value should be updated when the DPI scale of the app's top level + /// window changes (i.e. monitor DPI scale changes or window changes monitor) + /// or when the text scale factor of the system changes. + /// Rasterization scale applies to the WebView content, as well as + /// popups, context menus, scroll bars, and so on. Normal app scaling + /// scenarios should use the ZoomFactor property or SetBoundsAndZoomFactor + /// API which only scale the rendered HTML content and not popups, context + /// menus, scroll bars, and so on. + /// + /// + /// See the ICoreWebView2Controller3 article. + /// + property RasterizationScale : double read GetRasterizationScale write SetRasterizationScale; + /// + /// ShouldDetectMonitorScaleChanges property determines whether the WebView + /// attempts to track monitor DPI scale changes. When true, the WebView will + /// track monitor DPI scale changes, update the RasterizationScale property, + /// and raises RasterizationScaleChanged event. When false, the WebView will + /// not track monitor DPI scale changes, and the app must update the + /// RasterizationScale property itself. RasterizationScaleChanged event will + /// never raise when ShouldDetectMonitorScaleChanges is false. Apps that want + /// to set their own rasterization scale should set this property to false to + /// avoid the WebView2 updating the RasterizationScale property to match the + /// monitor DPI scale. + /// + /// + /// See the ICoreWebView2Controller3 article. + /// + property ShouldDetectMonitorScaleChanges : boolean read GetShouldDetectMonitorScaleChanges write SetShouldDetectMonitorScaleChanges; + /// + /// Gets the `AllowExternalDrop` property which is used to configure the + /// capability that dragging objects from outside the bounds of webview2 and + /// dropping into webview2 is allowed or disallowed. The default value is + /// TRUE. + /// + /// + /// See the ICoreWebView2Controller4 article. + /// + property AllowExternalDrop : boolean read GetAllowExternalDrop write SetAllowExternalDrop; + /// + /// The `DefaultContextMenusEnabled` property is used to prevent default + /// context menus from being shown to user in WebView. + /// The default value is `TRUE`. + /// + /// + /// See the ICoreWebView2Settings article. + /// + property DefaultContextMenusEnabled : boolean read GetDefaultContextMenusEnabled write SetDefaultContextMenusEnabled; + /// + /// `DefaultScriptDialogsEnabled` is used when loading a new HTML + /// document. If set to `FALSE`, WebView2 does not render the default JavaScript + /// dialog box (Specifically those displayed by the JavaScript alert, + /// confirm, prompt functions and `beforeunload` event). Instead, if an + /// event handler is set using `add_ScriptDialogOpening`, WebView sends an + /// event that contains all of the information for the dialog and allow the + /// host app to show a custom UI. The default value is `TRUE`. + /// + /// + /// See the ICoreWebView2Settings article. + /// + property DefaultScriptDialogsEnabled : boolean read GetDefaultScriptDialogsEnabled write SetDefaultScriptDialogsEnabled; + /// + /// `DevToolsEnabled` controls whether the user is able to use the context + /// menu or keyboard shortcuts to open the DevTools window. + /// The default value is `TRUE`. + /// + /// + /// See the ICoreWebView2Settings article. + /// + property DevToolsEnabled : boolean read GetDevToolsEnabled write SetDevToolsEnabled; + /// + /// The `AreHostObjectsAllowed` property is used to control whether host + /// objects are accessible from the page in WebView. + /// The default value is `TRUE`. + /// + /// + /// See the ICoreWebView2Settings article. + /// + property AreHostObjectsAllowed : boolean read GetAreHostObjectsAllowed write SetAreHostObjectsAllowed; + /// + /// The `BuiltInErrorPageEnabled` property is used to disable built in + /// error page for navigation failure and render process failure. When + /// disabled, a blank page is displayed when the related error happens. + /// The default value is `TRUE`. + /// + /// + /// See the ICoreWebView2Settings article. + /// + property BuiltInErrorPageEnabled : boolean read GetBuiltInErrorPageEnabled write SetBuiltInErrorPageEnabled; + /// + /// Controls if running JavaScript is enabled in all future navigations in + /// the WebView. This only affects scripts in the document. Scripts + /// injected with `ExecuteScript` runs even if script is disabled. + /// The default value is `TRUE`. + /// + /// + /// See the ICoreWebView2Settings article. + /// + property ScriptEnabled : boolean read GetScriptEnabled write SetScriptEnabled; + /// + /// `StatusBarEnabled` controls whether the status bar is displayed. The + /// status bar is usually displayed in the lower left of the WebView and + /// shows things such as the URI of a link when the user hovers over it and + /// other information. The default value is `TRUE`. The status bar UI can be + /// altered by web content and should not be considered secure. + /// + /// + /// See the ICoreWebView2Settings article. + /// + property StatusBarEnabled : boolean read GetStatusBarEnabled write SetStatusBarEnabled; + /// + /// The `WebMessageEnabled` property is used when loading a new HTML + /// document. If set to `TRUE`, communication from the host to the top-level + /// HTML document of the WebView is allowed using `PostWebMessageAsJson`, + /// `PostWebMessageAsString`, and message event of `window.chrome.webview`. + /// For more information, navigate to PostWebMessageAsJson. Communication + /// from the top-level HTML document of the WebView to the host is allowed + /// using the postMessage function of `window.chrome.webview` and + /// `add_WebMessageReceived` method. + /// If set to false, then communication is disallowed. `PostWebMessageAsJson` + /// and `PostWebMessageAsString` fails with `E_ACCESSDENIED` and + /// `window.chrome.webview.postMessage` fails by throwing an instance of an + /// `Error` object. The default value is `TRUE`. + /// + /// + /// See the add_WebMessageReceived method article. + /// See the ICoreWebView2Settings article. + /// + property WebMessageEnabled : boolean read GetWebMessageEnabled write SetWebMessageEnabled; + /// + /// The `ZoomControlEnabled` property is used to prevent the user from + /// impacting the zoom of the WebView. When disabled, the user is not able + /// to zoom using Ctrl++, Ctrl+-, or Ctrl+mouse wheel, but the zoom + /// is set using `ZoomFactor` API. The default value is `TRUE`. + /// + /// + /// See the ICoreWebView2Settings article. + /// + property ZoomControlEnabled : boolean read GetZoomControlEnabled write SetZoomControlEnabled; + /// + /// Returns the User Agent. The default value is the default User Agent of the + /// Microsoft Edge browser. + /// This property may be overridden if + /// the User-Agent header is set in a request. If the parameter is empty + /// the User Agent will not be updated and the current User Agent will remain. + /// Setting this property may clear User Agent Client Hints headers + /// Sec-CH-UA-* and script values from navigator.userAgentData. Current + /// implementation behavior is subject to change. + /// The User Agent set will also be effective on service workers + /// and shared workers associated with the WebView. If there are + /// multiple WebViews associated with the same service worker or + /// shared worker, the last User Agent set will be used. + /// + /// + /// See the ICoreWebView2Settings2 article. + /// + property UserAgent : wvstring read GetUserAgent write SetUserAgent; + /// + /// When this setting is set to FALSE, it disables all accelerator keys that + /// access features specific to a web browser. + /// The default value for `AreBrowserAcceleratorKeysEnabled` is TRUE. + /// + /// + /// See the ICoreWebView2Settings3 article. + /// + property AreBrowserAcceleratorKeysEnabled : boolean read GetAreBrowserAcceleratorKeysEnabled write SetAreBrowserAcceleratorKeysEnabled; + /// + /// IsGeneralAutofillEnabled controls whether autofill for information + /// like names, street and email addresses, phone numbers, and arbitrary input + /// is enabled. This excludes password and credit card information. When + /// IsGeneralAutofillEnabled is false, no suggestions appear, and no new information + /// is saved. When IsGeneralAutofillEnabled is true, information is saved, suggestions + /// appear and clicking on one will populate the form fields. It will take effect + /// immediately after setting. The default value is `TRUE`. + /// This property has the same value as + /// `CoreWebView2Profile.IsGeneralAutofillEnabled`, and changing one will + /// change the other. All `CoreWebView2`s with the same `CoreWebView2Profile` + /// will share the same value for this property, so for the `CoreWebView2`s + /// with the same profile, their + /// `CoreWebView2Settings.IsGeneralAutofillEnabled` and + /// `CoreWebView2Profile.IsGeneralAutofillEnabled` will always have the same + /// value. + /// + /// + /// See the ICoreWebView2Settings4 article. + /// + property IsGeneralAutofillEnabled : boolean read GetIsGeneralAutofillEnabled write SetIsGeneralAutofillEnabled; + /// + /// IsPasswordAutosaveEnabled controls whether autosave for password + /// information is enabled. The IsPasswordAutosaveEnabled property behaves + /// independently of the IsGeneralAutofillEnabled property. When IsPasswordAutosaveEnabled is + /// false, no new password data is saved and no Save/Update Password prompts are displayed. + /// However, if there was password data already saved before disabling this setting, + /// then that password information is auto-populated, suggestions are shown and clicking on + /// one will populate the fields. + /// When IsPasswordAutosaveEnabled is true, password information is auto-populated, + /// suggestions are shown and clicking on one will populate the fields, new data + /// is saved, and a Save/Update Password prompt is displayed. + /// It will take effect immediately after setting. The default value is `FALSE`. + /// This property has the same value as + /// `CoreWebView2Profile.IsPasswordAutosaveEnabled`, and changing one will + /// change the other. All `CoreWebView2`s with the same `CoreWebView2Profile` + /// will share the same value for this property, so for the `CoreWebView2`s + /// with the same profile, their + /// `CoreWebView2Settings.IsPasswordAutosaveEnabled` and + /// `CoreWebView2Profile.IsPasswordAutosaveEnabled` will always have the same + /// value. + /// + /// + /// See the ICoreWebView2Settings4 article. + /// + property IsPasswordAutosaveEnabled : boolean read GetIsPasswordAutosaveEnabled write SetIsPasswordAutosaveEnabled; + /// + /// Pinch-zoom, referred to as "Page Scale" zoom, is performed as a post-rendering step, + /// it changes the page scale factor property and scales the surface the web page is + /// rendered onto when user performs a pinch zooming action. It does not change the layout + /// but rather changes the viewport and clips the web content, the content outside of the + /// viewport isn't visible onscreen and users can't reach this content using mouse. + /// The `IsPinchZoomEnabled` property enables or disables the ability of + /// the end user to use a pinching motion on touch input enabled devices + /// to scale the web content in the WebView2. It defaults to `TRUE`. + /// When set to `FALSE`, the end user cannot pinch zoom after the next navigation. + /// Disabling/Enabling `IsPinchZoomEnabled` only affects the end user's ability to use + /// pinch motions and does not change the page scale factor. + /// This API only affects the Page Scale zoom and has no effect on the + /// existing browser zoom properties (`IsZoomControlEnabled` and `ZoomFactor`) + /// or other end user mechanisms for zooming. + /// + /// + /// See the ICoreWebView2Settings5 article. + /// + property IsPinchZoomEnabled : boolean read GetIsPinchZoomEnabled write SetIsPinchZoomEnabled; + /// + /// The `IsSwipeNavigationEnabled` property enables or disables the ability of the + /// end user to use swiping gesture on touch input enabled devices to + /// navigate in WebView2. It defaults to `TRUE`. + /// When this property is `TRUE`, then all configured navigation gestures are enabled: + /// 1. Swiping left and right to navigate forward and backward is always configured. + /// 2. Swiping down to refresh is off by default and not exposed via our API currently, + /// it requires the "--pull-to-refresh" option to be included in the additional browser + /// arguments to be configured. (See put_AdditionalBrowserArguments.) + /// When set to `FALSE`, the end user cannot swipe to navigate or pull to refresh. + /// This API only affects the overscrolling navigation functionality and has no + /// effect on the scrolling interaction used to explore the web content shown + /// in WebView2. + /// Disabling/Enabling IsSwipeNavigationEnabled takes effect after the + /// next navigation. + /// + /// + /// See the ICoreWebView2Settings6 article. + /// + property IsSwipeNavigationEnabled : boolean read GetIsSwipeNavigationEnabled write SetIsSwipeNavigationEnabled; + /// + /// `HiddenPdfToolbarItems` is used to customize the PDF toolbar items. By default, it is COREWEBVIEW2_PDF_TOOLBAR_ITEMS_NONE and so it displays all of the items. + /// Changes to this property apply to all CoreWebView2s in the same environment and using the same profile. + /// Changes to this setting apply only after the next navigation. + /// + /// + /// See the ICoreWebView2Settings7 article. + /// + property HiddenPdfToolbarItems : TWVPDFToolbarItems read GetHiddenPdfToolbarItems write SetHiddenPdfToolbarItems; + /// + /// SmartScreen helps webviews identify reported phishing and malware websites + /// and also helps users make informed decisions about downloads. + /// `IsReputationCheckingRequired` is used to control whether SmartScreen + /// enabled or not. SmartScreen is enabled or disabled for all CoreWebView2s + /// using the same user data folder. If + /// CoreWebView2Setting.IsReputationCheckingRequired is true for any + /// CoreWebView2 using the same user data folder, then SmartScreen is enabled. + /// If CoreWebView2Setting.IsReputationCheckingRequired is false for all + /// CoreWebView2 using the same user data folder, then SmartScreen is + /// disabled. When it is changed, the change will be applied to all WebViews + /// using the same user data folder on the next navigation or download. The + /// default value for `IsReputationCheckingRequired` is true. If the newly + /// created CoreWebview2 does not set SmartScreen to false, when + /// navigating(Such as Navigate(), LoadDataUrl(), ExecuteScript(), etc.), the + /// default value will be applied to all CoreWebview2 using the same user data + /// folder. + /// SmartScreen of WebView2 apps can be controlled by Windows system setting + /// "SmartScreen for Microsoft Edge", specially, for WebView2 in Windows + /// Store apps, SmartScreen is controlled by another Windows system setting + /// "SmartScreen for Microsoft Store apps". When the Windows setting is enabled, the + /// SmartScreen operates under the control of the `IsReputationCheckingRequired`. + /// When the Windows setting is disabled, the SmartScreen will be disabled + /// regardless of the `IsReputationCheckingRequired` value set in WebView2 apps. + /// In other words, under this circumstance the value of + /// `IsReputationCheckingRequired` will be saved but overridden by system setting. + /// Upon re-enabling the Windows setting, the CoreWebview2 will reference the + /// `IsReputationCheckingRequired` to determine the SmartScreen status. + /// + /// + /// See the ICoreWebView2Settings8 article. + /// + property IsReputationCheckingRequired : boolean read GetIsReputationCheckingRequired write SetIsReputationCheckingRequired; + /// + /// The `IsNonClientRegionSupportEnabled` property enables web pages to use the + /// `app-region` CSS style. Disabling/Enabling the `IsNonClientRegionSupportEnabled` + /// takes effect after the next navigation. Defaults to `FALSE`. + /// When this property is `TRUE`, then all the non-client region features + /// will be enabled: + /// Draggable Regions will be enabled, they are regions on a webpage that + /// are marked with the CSS attribute `app-region: drag/no-drag`. When set to + /// `drag`, these regions will be treated like the window's title bar, supporting + /// dragging of the entire WebView and its host app window; the system menu shows + /// upon right click, and a double click will trigger maximizing/restoration of the + /// window size. + /// When set to `FALSE`, all non-client region support will be disabled. + /// The `app-region` CSS style will be ignored on web pages. + /// + /// + /// See the ICoreWebView2Settings9 article. + /// + property IsNonClientRegionSupportEnabled : boolean read GetIsNonClientRegionSupportEnabled write SetIsNonClientRegionSupportEnabled; + /// + /// The current cursor that WebView thinks it should be. The cursor should be + /// set in WM_SETCURSOR through \::SetCursor or set on the corresponding + /// parent/ancestor HWND of the WebView through \::SetClassLongPtr. The HCURSOR + /// can be freed so CopyCursor/DestroyCursor is recommended to keep your own + /// copy if you are doing more than immediately setting the cursor. + /// + /// + /// See the ICoreWebView2CompositionController article. + /// + property Cursor : HCURSOR read GetCursor; + /// + /// The RootVisualTarget is a visual in the hosting app's visual tree. This + /// visual is where the WebView will connect its visual tree. The app uses + /// this visual to position the WebView within the app. The app still needs + /// to use the Bounds property to size the WebView. The RootVisualTarget + /// property can be an IDCompositionVisual or a + /// Windows::UI::Composition::ContainerVisual. WebView will connect its visual + /// tree to the provided visual before returning from the property setter. The + /// app needs to commit on its device setting the RootVisualTarget property. + /// The RootVisualTarget property supports being set to nullptr to disconnect + /// the WebView from the app's visual tree. + /// + /// + /// See the ICoreWebView2CompositionController article. + /// + property RootVisualTarget : IUnknown read GetRootVisualTarget write SetRootVisualTarget; + /// + /// The current system cursor ID reported by the underlying rendering engine + /// for WebView. For example, most of the time, when the cursor is over text, + /// this will return the int value for IDC_IBEAM. The systemCursorId is only + /// valid if the rendering engine reports a default Windows cursor resource + /// value. Navigate to + /// [LoadCursorW](/windows/win32/api/winuser/nf-winuser-loadcursorw) for more + /// details. Otherwise, if custom CSS cursors are being used, this will return + /// 0. To actually use systemCursorId in LoadCursor or LoadImage, + /// MAKEINTRESOURCE must be called on it first. + /// + /// + /// See the ICoreWebView2CompositionController article. + /// + property SystemCursorID : cardinal read GetSystemCursorID; + /// + /// Returns the Automation Provider for the WebView. This object implements + /// IRawElementProviderSimple. + /// + /// + /// See the ICoreWebView2CompositionController2 article. + /// + property AutomationProvider : IUnknown read GetAutomationProvider; + /// + /// Returns the `ICoreWebView2ProcessInfoCollection`. Provide a list of all + /// process using same user data folder except for crashpad process. + /// + /// + /// See the ICoreWebView2Environment8 article. + /// + property ProcessInfos : ICoreWebView2ProcessInfoCollection read GetProcessInfos; + /// + /// `ProfileName` property is to specify a profile name, which is only allowed to contain + /// the following ASCII characters. It has a maximum length of 64 characters excluding the null-terminator. + /// It is ASCII case insensitive. + /// * alphabet characters: a-z and A-Z + /// * digit characters: 0-9 + /// * and '#', '@', '$', '(', ')', '+', '-', '_', '~', '.', ' ' (space). + /// Note: the text must not end with a period '.' or ' ' (space). And, although upper-case letters are + /// allowed, they're treated just as lower-case counterparts because the profile name will be mapped to + /// the real profile directory path on disk and Windows file system handles path names in a case-insensitive way. + /// + /// + /// See the ICoreWebView2ControllerOptions article. + /// + property ProfileName : wvstring read GetProfileName write SetProfileName; + /// + /// `IsInPrivateModeEnabled` property is to enable/disable InPrivate mode. + /// + /// + /// See the ICoreWebView2ControllerOptions article. + /// + property IsInPrivateModeEnabled : boolean read GetIsInPrivateModeEnabled write FIsInPrivateModeEnabled; + /// + /// The default locale for the WebView2. It sets the default locale for all + /// Intl JavaScript APIs and other JavaScript APIs that depend on it, namely + /// `Intl.DateTimeFormat()` which affects string formatting like + /// in the time/date formats. Example: `Intl.DateTimeFormat().format(new Date())` + /// The intended locale value is in the format of + /// BCP 47 Language Tags. More information can be found from + /// [IETF BCP47](https://www.ietf.org/rfc/bcp/bcp47.html). + /// This property sets the locale for a CoreWebView2Environment used to create the + /// WebView2ControllerOptions object, which is passed as a parameter in + /// `CreateCoreWebView2ControllerWithOptions`. + /// Changes to the ScriptLocale property apply to renderer processes created after + /// the change. Any existing renderer processes will continue to use the previous + /// ScriptLocale value. To ensure changes are applied to all renderer process, + /// close and restart the CoreWebView2Environment and all associated WebView2 objects. + /// The default value for ScriptLocale will depend on the WebView2 language + /// and OS region. If the language portions of the WebView2 language and OS region + /// match, then it will use the OS region. Otherwise, it will use the WebView2 + /// language. + /// + /// + /// See the ICoreWebView2ControllerOptions2 article. + /// + property ScriptLocale : wvstring read FScriptLocale write FScriptLocale; + /// + /// `AllowHostInputProcessing` property is to enable/disable input passing through + /// the app before being delivered to the WebView2. This property is only applicable + /// to controllers created with `CoreWebView2Environment.CreateCoreWebView2ControllerAsync` and not + /// composition controllers created with `CoreWebView2Environment.CreateCoreWebView2CompositionControllerAsync`. + /// By default the value is `FALSE`. + /// Setting this property has no effect when using visual hosting. + /// + /// + /// See the ICoreWebView2Controller4 article. + /// + property AllowHostInputProcessing : boolean read FAllowHostInputProcessing write FAllowHostInputProcessing; + /// + /// Full path of the profile directory. + /// + /// + /// See the ICoreWebView2Profile article. + /// + property ProfilePath : wvstring read GetProfilePath; + /// + /// Gets the `DefaultDownloadFolderPath` property. The default value is the + /// system default download folder path for the user. + /// + /// + /// See the ICoreWebView2Profile article. + /// + property DefaultDownloadFolderPath : wvstring read GetDefaultDownloadFolderPath write SetDefaultDownloadFolderPath; + /// + /// The PreferredColorScheme property sets the overall color scheme of the + /// WebView2s associated with this profile. This sets the color scheme for + /// WebView2 UI like dialogs, prompts, and context menus by setting the + /// media feature `prefers-color-scheme` for websites to respond to. + /// The default value for this is COREWEBVIEW2_PREFERRED_COLOR_AUTO, + /// which will follow whatever theme the OS is currently set to. + /// Returns the value of the `PreferredColorScheme` property. + /// + /// + /// See the ICoreWebView2Profile article. + /// + property PreferredColorScheme : TWVPreferredColorScheme read GetPreferredColorScheme write SetPreferredColorScheme; + /// + /// The `PreferredTrackingPreventionLevel` property allows you to control levels of tracking prevention for WebView2 + /// which are associated with a profile. This level would apply to the context of the profile. That is, all WebView2s + /// sharing the same profile will be affected and also the value is persisted in the user data folder. + /// See `COREWEBVIEW2_TRACKING_PREVENTION_LEVEL` for descriptions of levels. + /// If tracking prevention feature is enabled when creating the WebView2 environment, you can also disable tracking + /// prevention later using this property and `COREWEBVIEW2_TRACKING_PREVENTION_LEVEL_NONE` value but that doesn't + /// improves runtime performance. + /// There is `ICoreWebView2EnvironmentOptions5.EnableTrackingPrevention` property to enable/disable tracking prevention feature + /// for all the WebView2's created in the same environment. If enabled, `PreferredTrackingPreventionLevel` is set to + /// `COREWEBVIEW2_TRACKING_PREVENTION_LEVEL_BALANCED` by default for all the WebView2's and profiles created in the same + /// environment or is set to the level whatever value was last changed/persisted to the profile. If disabled + /// `PreferredTrackingPreventionLevel` is not respected by WebView2. If `PreferredTrackingPreventionLevel` is set when the + /// feature is disabled, the property value get changed and persisted but it will takes effect only if + /// `ICoreWebView2EnvironmentOptions5.EnableTrackingPrevention` is true. + /// + /// + /// See the ICoreWebView2Profile3 article. + /// + property PreferredTrackingPreventionLevel : TWVTrackingPreventionLevel read GetPreferredTrackingPreventionLevel write SetPreferredTrackingPreventionLevel; + /// + /// Get the cookie manager for the profile. All CoreWebView2s associated with this + /// profile share the same cookie values. Changes to cookies in this cookie manager apply to all + /// CoreWebView2s associated with this profile. See ICoreWebView2CookieManager. + /// + /// + /// See the ICoreWebView2Profile5 article. + /// + property ProfileCookieManager : ICoreWebView2CookieManager read GetProfileCookieManager; + /// + /// IsPasswordAutosaveEnabled controls whether autosave for password + /// information is enabled. The IsPasswordAutosaveEnabled property behaves + /// independently of the IsGeneralAutofillEnabled property. When IsPasswordAutosaveEnabled is + /// false, no new password data is saved and no Save/Update Password prompts are displayed. + /// However, if there was password data already saved before disabling this setting, + /// then that password information is auto-populated, suggestions are shown and clicking on + /// one will populate the fields. + /// When IsPasswordAutosaveEnabled is true, password information is auto-populated, + /// suggestions are shown and clicking on one will populate the fields, new data + /// is saved, and a Save/Update Password prompt is displayed. + /// It will take effect immediately after setting. The default value is `FALSE`. + /// This property has the same value as + /// `CoreWebView2Settings.IsPasswordAutosaveEnabled`, and changing one will + /// change the other. All `CoreWebView2`s with the same `CoreWebView2Profile` + /// will share the same value for this property, so for the `CoreWebView2`s + /// with the same profile, their + /// `CoreWebView2Settings.IsPasswordAutosaveEnabled` and + /// `CoreWebView2Profile.IsPasswordAutosaveEnabled` will always have the same + /// value. + /// + /// + /// See the ICoreWebView2Profile6 article. + /// + property ProfileIsPasswordAutosaveEnabled : boolean read GetProfileIsPasswordAutosaveEnabled write SetProfileIsPasswordAutosaveEnabled; + /// + /// IsGeneralAutofillEnabled controls whether autofill for information + /// like names, street and email addresses, phone numbers, and arbitrary input + /// is enabled. This excludes password and credit card information. When + /// IsGeneralAutofillEnabled is false, no suggestions appear, and no new information + /// is saved. When IsGeneralAutofillEnabled is true, information is saved, suggestions + /// appear and clicking on one will populate the form fields. + /// It will take effect immediately after setting. The default value is `TRUE`. + /// This property has the same value as + /// `CoreWebView2Settings.IsGeneralAutofillEnabled`, and changing one will + /// change the other. All `CoreWebView2`s with the same `CoreWebView2Profile` + /// will share the same value for this property, so for the `CoreWebView2`s + /// with the same profile, their + /// `CoreWebView2Settings.IsGeneralAutofillEnabled` and + /// `CoreWebView2Profile.IsGeneralAutofillEnabled` will always have the same + /// value. + /// + /// + /// See the ICoreWebView2Profile6 article. + /// + property ProfileIsGeneralAutofillEnabled : boolean read GetProfileIsGeneralAutofillEnabled write SetProfileIsGeneralAutofillEnabled; + /// + /// The unique identifier of the main frame. It's the same kind of ID as + /// with the `FrameId` in `ICoreWebView2Frame` and via `ICoreWebView2FrameInfo`. + /// Note that `FrameId` may not be valid if `ICoreWebView2` has not done + /// any navigation. It's safe to get this value during or after the first + /// `ContentLoading` event. Otherwise, it could return the invalid frame Id 0. + /// + /// + /// See the ICoreWebView2_20 article. + /// + property FrameId : cardinal read GetFrameID; + /// + /// Options used to configure a find session. + /// + /// + /// See the ICoreWebView2FindOptions article. + /// + property FindOptions : TCoreWebView2FindOptions read FCoreWebView2FindOptions; + /// + /// FindSession allows for finding text, navigation between matches, and customization of the find UI. + /// + /// + /// See the ICoreWebView2Find article. + /// + property FindSession : TCoreWebView2Find read FCoreWebView2Find; + /// + /// Enables or disables webview2 specific Service Worker JS APIs in the + /// WebView2s associated with this Profile. When set to `TRUE`, chrome and + /// webview objects are available in Service Workers. chrome.webview exposes + /// APIs to interact with the WebView from Service Workers. The default value + /// is `FALSE`. This setting applies to all newly installed Service Workers + /// within the profile and is not persisted across WebView2 sessions. + /// + /// + /// See the ICoreWebView2Profile9 article. + /// + property AreWebViewScriptApisEnabledForServiceWorkers : boolean read GetAreWebViewScriptApisEnabledForServiceWorkers write SetAreWebViewScriptApisEnabledForServiceWorkers; + /// + /// Get the service worker manager to monitor service worker registrations and + /// interact with the service workers associated with the current profile. + /// + /// + /// See the ICoreWebView2Profile9 article. + /// + property ServiceWorkerManager : ICoreWebView2ServiceWorkerManager read GetServiceWorkerManager; + /// + /// Get the shared worker manager to monitor shared worker creations and interact + /// with the shared workers associated with the current profile. + /// + /// + /// See the ICoreWebView2Profile9 article. + /// + property SharedWorkerManager : ICoreWebView2SharedWorkerManager read GetSharedWorkerManager; + + /// + /// The OnBrowserProcessExited event is triggered when the collection of WebView2 + /// Runtime processes for the browser process of this environment terminate + /// due to browser process failure or normal shutdown (for example, when all + /// associated WebViews are closed), after all resources have been released + /// (including the user data folder). + /// + /// + /// See the ICoreWebView2Environment5 article. + /// + property OnBrowserProcessExited : TOnBrowserProcessExitedEvent read FOnBrowserProcessExited write FOnBrowserProcessExited; + /// + /// OnProcessInfosChanged is triggered when the ProcessInfos property has changed. + /// + /// + /// See the ICoreWebView2Environment8 article. + /// + property OnProcessInfosChanged : TOnProcessInfosChangedEvent read FOnProcessInfosChanged write FOnProcessInfosChanged; + /// + /// `OnContainsFullScreenElementChanged` triggers when the + /// `ContainsFullScreenElement` property changes. An HTML element inside the + /// WebView may enter fullscreen to the size of the WebView or leave + /// fullscreen. This event is useful when, for example, a video element + /// requests to go fullscreen. The listener of + /// `ContainsFullScreenElementChanged` may resize the WebView in response. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnContainsFullScreenElementChanged : TNotifyEvent read FOnContainsFullScreenElementChanged write FOnContainsFullScreenElementChanged; + /// + /// `OnContentLoading` triggers before any content is loaded, including scripts added with + /// `AddScriptToExecuteOnDocumentCreated`. `ContentLoading` does not trigger + /// if a same page navigation occurs (such as through `fragment` + /// navigations or `history.pushState` navigations). This operation + /// follows the `NavigationStarting` and `SourceChanged` events and precedes + /// the `HistoryChanged` and `NavigationCompleted` events. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnContentLoading : TOnContentLoadingEvent read FOnContentLoading write FOnContentLoading; + /// + /// `OnDocumentTitleChanged` runs when the `DocumentTitle` property of the + /// WebView changes and may run before or after the `NavigationCompleted` + /// event. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnDocumentTitleChanged : TNotifyEvent read FOnDocumentTitleChanged write FOnDocumentTitleChanged; + /// + /// `OnFrameNavigationCompleted` triggers when a child frame has completely + /// loaded (concurrently when `body.onload` has triggered) or loading stopped with error. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnFrameNavigationCompleted : TOnNavigationCompletedEvent read FOnFrameNavigationCompleted write FOnFrameNavigationCompleted; + /// + /// `OnFrameNavigationStarting` triggers when a child frame in the WebView + /// requests permission to navigate to a different URI. Redirects trigger + /// this operation as well, and the navigation id is the same as the original + /// one. Navigations will be blocked until all `FrameNavigationStarting` event + /// handlers return. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnFrameNavigationStarting : TOnNavigationStartingEvent read FOnFrameNavigationStarting write FOnFrameNavigationStarting; + /// + /// `OnHistoryChanged` is raised for changes to joint session history, which consists of top-level + /// and manual frame navigations. Use `HistoryChanged` to verify that the + /// `CanGoBack` or `CanGoForward` value has changed. `HistoryChanged` also + /// runs for using `GoBack` or `GoForward`. `HistoryChanged` runs after + /// `SourceChanged` and `ContentLoading`. `CanGoBack` is false for + /// navigations initiated through ICoreWebView2Frame APIs if there has not yet + /// been a user gesture. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnHistoryChanged : TNotifyEvent read FOnHistoryChanged write FOnHistoryChanged; + /// + /// `OnNavigationCompleted` runs when the WebView has completely loaded + /// (concurrently when `body.onload` runs) or loading stopped with error. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnNavigationCompleted : TOnNavigationCompletedEvent read FOnNavigationCompleted write FOnNavigationCompleted; + /// + /// `OnNavigationStarting` runs when the WebView main frame is requesting + /// permission to navigate to a different URI. Redirects trigger this + /// operation as well, and the navigation id is the same as the original + /// one. Navigations will be blocked until all `NavigationStarting` event handlers + /// return. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnNavigationStarting : TOnNavigationStartingEvent read FOnNavigationStarting write FOnNavigationStarting; + /// + /// `OnNewWindowRequested` runs when content inside the WebView requests to + /// open a new window, such as through `window.open`. The app can pass a + /// target WebView that is considered the opened window or mark the event as + /// `Handled`, in which case WebView2 does not open a window. + /// If either `Handled` or `NewWindow` properties are not set, the target + /// content will be opened on a popup window. + /// If a deferral is not taken on the event args, scripts that resulted in the + /// new window that are requested are blocked until the event handler returns. + /// If a deferral is taken, then scripts are blocked until the deferral is + /// completed or new window is set. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnNewWindowRequested : TOnNewWindowRequestedEvent read FOnNewWindowRequested write FOnNewWindowRequested; + /// + /// `OnPermissionRequested` runs when content in a WebView requests permission + /// to access some privileged resources. If a deferral is not taken on the event + /// args, the subsequent scripts are blocked until the event handler returns. + /// If a deferral is taken, the scripts are blocked until the deferral is completed. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnPermissionRequested : TOnPermissionRequestedEvent read FOnPermissionRequested write FOnPermissionRequested; + /// + /// `OnProcessFailed` runs when any of the processes in the + /// [WebView2 Process Group](https://learn.microsoft.com/microsoft-edge/webview2/concepts/process-model?tabs=csharp#processes-in-the-webview2-runtime) + /// encounters one of the following conditions: + /// + /// Condition | Details + /// ---|--- + /// Unexpected exit | The process indicated by the event args has exited unexpectedly (usually due to a crash). The failure might or might not be recoverable and some failures are auto-recoverable. + /// Unresponsiveness | The process indicated by the event args has become unresponsive to user input. This is only reported for renderer processes, and will run every few seconds until the process becomes responsive again. + /// + /// NOTE: When the failing process is the browser process, a + /// `ICoreWebView2Environment5.BrowserProcessExited` event will run too. + /// Your application can use `ICoreWebView2ProcessFailedEventArgs` and + /// `ICoreWebView2ProcessFailedEventArgs2` to identify which condition and + /// process the event is for, and to collect diagnostics and handle recovery + /// if necessary. For more details about which cases need to be handled by + /// your application, see `COREWEBVIEW2_PROCESS_FAILED_KIND`. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnProcessFailed : TOnProcessFailedEvent read FOnProcessFailed write FOnProcessFailed; + /// + /// `OnScriptDialogOpening` runs when a JavaScript dialog (`alert`, `confirm`, + /// `prompt`, or `beforeunload`) displays for the webview. This event only + /// triggers if the `ICoreWebView2Settings.AreDefaultScriptDialogsEnabled` + /// property is set to `FALSE`. The `ScriptDialogOpening` event suppresses + /// dialogs or replaces default dialogs with custom dialogs. + /// If a deferral is not taken on the event args, the subsequent scripts are + /// blocked until the event handler returns. If a deferral is taken, the + /// scripts are blocked until the deferral is completed. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnScriptDialogOpening : TOnScriptDialogOpeningEvent read FOnScriptDialogOpening write FOnScriptDialogOpening; + /// + /// `OnSourceChanged` triggers when the `Source` property changes. `SourceChanged` runs when + /// navigating to a different site or fragment navigations. It does not + /// trigger for other types of navigations such as page refreshes or + /// `history.pushState` with the same URL as the current page. + /// `SourceChanged` runs before `ContentLoading` for navigation to a new + /// document. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnSourceChanged : TOnSourceChangedEvent read FOnSourceChanged write FOnSourceChanged; + /// + /// `OnWebMessageReceived` runs when the `ICoreWebView2Settings.IsWebMessageEnabled` + /// setting is set and the top-level document of the WebView runs + /// `window.chrome.webview.postMessage`. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnWebMessageReceived : TOnWebMessageReceivedEvent read FOnWebMessageReceived write FOnWebMessageReceived; + /// + /// `OnWebResourceRequested` runs when the WebView is performing a URL request + /// to a matching URL and resource context and source kind filter that was + /// added with `AddWebResourceRequestedFilterWithRequestSourceKinds`. + /// At least one filter must be added for the event to run. + /// The web resource requested may be blocked until the event handler returns + /// if a deferral is not taken on the event args. If a deferral is taken, + /// then the web resource requested is blocked until the deferral is + /// completed. + /// If this event is subscribed in the add_NewWindowRequested handler it should be called + /// after the new window is set. For more details see `ICoreWebView2NewWindowRequestedEventArgs.put_NewWindow`. + /// This event is by default raised for file, http, and https URI schemes. + /// This is also raised for registered custom URI schemes. For more details + /// see `ICoreWebView2CustomSchemeRegistration`. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnWebResourceRequested : TOnWebResourceRequestedEvent read FOnWebResourceRequested write FOnWebResourceRequested; + /// + /// `OnWindowCloseRequested` triggers when content inside the WebView + /// requested to close the window, such as after `window.close` is run. The + /// app should close the WebView and related app window if that makes sense + /// to the app. After the first window.close() call, this event may not fire + /// for any immediate back to back window.close() calls. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnWindowCloseRequested : TNotifyEvent read FOnWindowCloseRequested write FOnWindowCloseRequested; + /// + /// OnDOMContentLoaded is raised when the initial html document has been parsed. + /// This aligns with the document's DOMContentLoaded event in html. + /// + /// + /// See the ICoreWebView2_2 article. + /// + property OnDOMContentLoaded : TOnDOMContentLoadedEvent read FOnDOMContentLoaded write FOnDOMContentLoaded; + /// + /// OnWebResourceResponseReceived is raised when the WebView receives the + /// response for a request for a web resource (any URI resolution performed by + /// the WebView; such as HTTP/HTTPS, file and data requests from redirects, + /// navigations, declarations in HTML, implicit favicon lookups, and fetch API + /// usage in the document). The host app can use this event to view the actual + /// request and response for a web resource. There is no guarantee about the + /// order in which the WebView processes the response and the host app's + /// handler runs. The app's handler will not block the WebView from processing + /// the response. + /// + /// + /// See the ICoreWebView2_2 article. + /// + property OnWebResourceResponseReceived : TOnWebResourceResponseReceivedEvent read FOnWebResourceResponseReceived write FOnWebResourceResponseReceived; + /// + /// This event is raised when a download has begun, blocking the default download dialog, + /// but not blocking the progress of the download. + /// The host can choose to cancel a download, change the result file path, + /// and hide the default download dialog. + /// If the host chooses to cancel the download, the download is not saved, no + /// dialog is shown, and the state is changed to + /// COREWEBVIEW2_DOWNLOAD_STATE_INTERRUPTED with interrupt reason + /// COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_USER_CANCELED. Otherwise, the + /// download is saved to the default path after the event completes, + /// and default download dialog is shown if the host did not choose to hide it. + /// The host can change the visibility of the download dialog using the + /// `Handled` property. If the event is not handled, downloads complete + /// normally with the default dialog shown. + /// + /// + /// See the ICoreWebView2_4 article. + /// + property OnDownloadStarting : TOnDownloadStartingEvent read FOnDownloadStarting write FOnDownloadStarting; + /// + /// Raised when a new iframe is created. + /// + /// + /// See the ICoreWebView2_4 article. + /// + property OnFrameCreated : TOnFrameCreatedEvent read FOnFrameCreated write FOnFrameCreated; + /// + /// The OnClientCertificateRequested event is raised when the WebView2 + /// is making a request to an HTTP server that needs a client certificate + /// for HTTP authentication. + /// + /// + /// See the ICoreWebView2_5 article. + /// + property OnClientCertificateRequested : TOnClientCertificateRequestedEvent read FOnClientCertificateRequested write FOnClientCertificateRequested; + /// + /// `OnIsDocumentPlayingAudioChanged` is raised when the IsDocumentPlayingAudio property changes value. + /// + /// + /// See the ICoreWebView2_8 article. + /// + property OnIsDocumentPlayingAudioChanged : TOnIsDocumentPlayingAudioChangedEvent read FOnIsDocumentPlayingAudioChanged write FOnIsDocumentPlayingAudioChanged; + /// + /// `OnIsMutedChanged` is raised when the IsMuted property changes value. + /// + /// + /// See the ICoreWebView2_8 article. + /// + property OnIsMutedChanged : TOnIsMutedChangedEvent read FOnIsMutedChanged write FOnIsMutedChanged; + /// + /// Raised when the `IsDefaultDownloadDialogOpen` property changes. This event + /// comes after the `DownloadStarting` event. Setting the `Handled` property + /// on the `DownloadStartingEventArgs` disables the default download dialog + /// and ensures that this event is never raised. + /// + /// + /// See the ICoreWebView2_9 article. + /// + property OnIsDefaultDownloadDialogOpenChanged : TOnIsDefaultDownloadDialogOpenChangedEvent read FOnIsDefaultDownloadDialogOpenChanged write FOnIsDefaultDownloadDialogOpenChanged; + /// + /// Add an event handler for the BasicAuthenticationRequested event. + /// BasicAuthenticationRequested event is raised when WebView encounters a + /// Basic HTTP Authentication request as described in + /// https://developer.mozilla.org/docs/Web/HTTP/Authentication, a Digest + /// HTTP Authentication request as described in + /// https://developer.mozilla.org/docs/Web/HTTP/Headers/Authorization#digest, + /// an NTLM authentication or a Proxy Authentication request. + /// The host can provide a response with credentials for the authentication or + /// cancel the request. If the host sets the Cancel property to false but does not + /// provide either UserName or Password properties on the Response property, then + /// WebView2 will show the default authentication challenge dialog prompt to + /// the user. + /// + /// + /// See the ICoreWebView2_10 article. + /// + property OnBasicAuthenticationRequested : TOnBasicAuthenticationRequestedEvent read FOnBasicAuthenticationRequested write FOnBasicAuthenticationRequested; + /// + /// `OnContextMenuRequested` event is raised when a context menu is requested by the user + /// and the content inside WebView hasn't disabled context menus. + /// The host has the option to create their own context menu with the information provided in + /// the event or can add items to or remove items from WebView context menu. + /// If the host doesn't handle the event, WebView will display the default context menu. + /// + /// + /// See the ICoreWebView2_11 article. + /// + property OnContextMenuRequested : TOnContextMenuRequestedEvent read FOnContextMenuRequested write FOnContextMenuRequested; + /// + /// `OnStatusBarTextChanged` fires when the WebView is showing a status message, + /// a URL, or an empty string (an indication to hide the status bar). + /// + /// + /// See the ICoreWebView2_12 article. + /// + property OnStatusBarTextChanged : TOnStatusBarTextChangedEvent read FOnStatusBarTextChanged write FOnStatusBarTextChanged; + /// + /// Event triggered when TWVBrowserBase.ClearServerCertificateErrorActions finishes executing. + /// + /// + /// See the ICoreWebView2_14 article. + /// + property OnServerCertificateErrorActionsCompleted : TOnServerCertificateErrorActionsCompletedEvent read FOnServerCertificateErrorActionsCompleted write FOnServerCertificateErrorActionsCompleted; + /// + /// The OnServerCertificateErrorDetected event is raised when the WebView2 + /// cannot verify server's digital certificate while loading a web page. + /// This event will raise for all web resources and follows the `WebResourceRequested` event. + /// If you don't handle the event, WebView2 will show the default TLS interstitial error page to the user + /// for navigations, and for non-navigations the web request is cancelled. + /// Note that WebView2 before raising `OnServerCertificateErrorDetected` raises a `OnNavigationCompleted` event + /// with `IsSuccess` as FALSE and any of the below WebErrorStatuses that indicate a certificate failure. + /// + /// + /// See the ICoreWebView2_14 article. + /// + property OnServerCertificateErrorDetected : TOnServerCertificateErrorDetectedEvent read FOnServerCertificateErrorDetected write FOnServerCertificateErrorDetected; + /// + /// The `OnFaviconChanged` event is raised when the + /// [favicon](https://developer.mozilla.org/docs/Glossary/Favicon) + /// had a different URL then the previous URL. + /// The OnFaviconChanged event will be raised for first navigating to a new + /// document, whether or not a document declares a Favicon in HTML if the + /// favicon is different from the previous fav icon. The event will + /// be raised again if a favicon is declared in its HTML or has script + /// to set its favicon. The favicon information can then be retrieved with + /// `GetFavicon` and `FaviconUri`. + /// + /// + /// See the ICoreWebView2_15 article. + /// + property OnFaviconChanged : TOnFaviconChangedEvent read FOnFaviconChanged write FOnFaviconChanged; + /// + /// The TWVBrowserBase.OnGetFaviconCompleted event is triggered when the TWVBrowserBase.GetFavicon call finishes executing. + /// + /// + /// See the ICoreWebView2_15 article. + /// + property OnGetFaviconCompleted : TOnGetFaviconCompletedEvent read FOnGetFaviconCompleted write FOnGetFaviconCompleted; + /// + /// The TWVBrowserBase.OnPrintCompleted event is triggered when the TWVBrowserBase.Print call finishes executing. + /// + /// + /// See the ICoreWebView2_16 article. + /// + property OnPrintCompleted : TOnPrintCompletedEvent read FOnPrintCompleted write FOnPrintCompleted; + /// + /// The TWVBrowserBase.OnPrintCompleted event is triggered when the TWVBrowserBase.PrintToPdfStream call finishes executing. + /// + /// + /// See the ICoreWebView2_16 article. + /// + property OnPrintToPdfStreamCompleted : TOnPrintToPdfStreamCompletedEvent read FOnPrintToPdfStreamCompleted write FOnPrintToPdfStreamCompleted; + /// + /// `OnAcceleratorKeyPressed` runs when an accelerator key or key combo is + /// pressed or released while the WebView is focused. A key is considered an + /// accelerator if either of the following conditions are true. + /// * Ctrl or Alt is currently being held. + /// * The pressed key does not map to a character. + /// A few specific keys are never considered accelerators, such as Shift. + /// The `Escape` key is always considered an accelerator. + /// Auto-repeated key events caused by holding the key down also triggers + /// this event. Filter out the auto-repeated key events by verifying the + /// `KeyEventLParam` or `PhysicalKeyStatus` event args. + /// + /// + /// See the ICoreWebView2Controller article. + /// + property OnAcceleratorKeyPressed : TOnAcceleratorKeyPressedEvent read FOnAcceleratorKeyPressed write FOnAcceleratorKeyPressed; + /// + /// `OnGotFocus` runs when WebView has focus. + /// + /// + /// See the ICoreWebView2Controller article. + /// + property OnGotFocus : TNotifyEvent read FOnGotFocus write FOnGotFocus; + /// + /// `OnLostFocus` runs when WebView loses focus. In the case where `OnMoveFocusRequested` event is + /// run, the focus is still on WebView when `OnMoveFocusRequested` event runs. + /// `LostFocus` only runs afterwards when code of the app or default action + /// of `OnMoveFocusRequested` event set focus away from WebView. + /// + /// + /// See the ICoreWebView2Controller article. + /// + property OnLostFocus : TNotifyEvent read FOnLostFocus write FOnLostFocus; + /// + /// `OnMoveFocusRequested` runs when user tries to tab out of the WebView. The + /// focus of the WebView has not changed when this event is run. + /// + /// + /// See the ICoreWebView2Controller article. + /// + property OnMoveFocusRequested : TOnMoveFocusRequestedEvent read FOnMoveFocusRequested write FOnMoveFocusRequested; + /// + /// `OnZoomFactorChanged` runs when the `ZoomFactor` property of the WebView + /// changes. The event may run because the `ZoomFactor` property was + /// modified, or due to the user manually modifying the zoom. When it is + /// modified using the `ZoomFactor` property, the internal zoom factor is + /// updated immediately and no `OnZoomFactorChanged` event is triggered. + /// WebView associates the last used zoom factor for each site. It is + /// possible for the zoom factor to change when navigating to a different + /// page. When the zoom factor changes due to a navigation change, the + /// `OnZoomFactorChanged` event runs right after the `ContentLoading` event. + /// + /// + /// See the ICoreWebView2Controller article. + /// + property OnZoomFactorChanged : TNotifyEvent read FOnZoomFactorChanged write FOnZoomFactorChanged; + /// + /// The event is raised when the WebView detects that the monitor DPI scale + /// has changed, ShouldDetectMonitorScaleChanges is true, and the WebView has + /// changed the RasterizationScale property. + /// + /// + /// See the ICoreWebView2Controller3 article. + /// + property OnRasterizationScaleChanged : TNotifyEvent read FOnRasterizationScaleChanged write FOnRasterizationScaleChanged; + /// + /// The event is raised when WebView thinks the cursor should be changed. For + /// example, when the mouse cursor is currently the default cursor but is then + /// moved over text, it may try to change to the IBeam cursor. + /// It is expected for the developer to send + /// COREWEBVIEW2_MOUSE_EVENT_KIND_LEAVE messages (in addition to + /// COREWEBVIEW2_MOUSE_EVENT_KIND_MOVE messages) through the SendMouseInput + /// API. This is to ensure that the mouse is actually within the WebView that + /// sends out CursorChanged events. + /// + /// + /// See the ICoreWebView2CompositionController article. + /// + property OnCursorChanged : TNotifyEvent read FOnCursorChanged write FOnCursorChanged; + /// + /// The event is raised when the number of received bytes for a download operation changes. + /// + /// + /// See the ICoreWebView2DownloadOperation article. + /// + property OnBytesReceivedChanged : TOnBytesReceivedChangedEvent read FOnBytesReceivedChanged write FOnBytesReceivedChanged; + /// + /// The event is raised when the estimated end time for a download operation changes. + /// + /// + /// See the ICoreWebView2DownloadOperation article. + /// + property OnEstimatedEndTimeChanged : TOnEstimatedEndTimeChangedEvent read FOnEstimatedEndTimeChanged write FOnEstimatedEndTimeChanged; + /// + /// The event is raised when the download operation state changes. + /// + /// + /// See the ICoreWebView2DownloadOperation article. + /// + property OnDownloadStateChanged : TOnDownloadStateChangedEvent read FOnDownloadStateChanged write FOnDownloadStateChanged; + /// + /// The OnFrameDestroyed event is raised when the iframe corresponding + /// to this CoreWebView2Frame object is removed or the document + /// containing that iframe is destroyed. + /// + /// + /// See the ICoreWebView2Frame article. + /// + property OnFrameDestroyed : TOnFrameDestroyedEvent read FOnFrameDestroyed write FOnFrameDestroyed; + /// + /// Raised when the iframe changes its window.name property. + /// + /// + /// See the ICoreWebView2Frame article. + /// + property OnFrameNameChanged : TOnFrameNameChangedEvent read FOnFrameNameChanged write FOnFrameNameChanged; + /// + /// A frame navigation will raise a `OnFrameNavigationStarting2` event and + /// a `OnFrameNavigationStarting` event. All of the + /// `FrameNavigationStarting` event handlers for the current frame will be + /// run before the `OnFrameNavigationStarting2` event handlers. All of the event handlers + /// share a common `NavigationStartingEventArgs` object. Whichever event handler is + /// last to change the `NavigationStartingEventArgs.Cancel` property will + /// decide if the frame navigation will be cancelled. Redirects raise this + /// event as well, and the navigation id is the same as the original one. + /// Navigations will be blocked until all `OnFrameNavigationStarting2` and + /// `OnFrameNavigationStarting` event handlers return. + /// + /// + /// See the ICoreWebView2Frame2 article. + /// + property OnFrameNavigationStarting2 : TOnFrameNavigationStartingEvent read FOnFrameNavigationStarting2 write FOnFrameNavigationStarting2; + /// + /// `OnFrameNavigationCompleted2` runs when the CoreWebView2Frame has completely + /// loaded (concurrently when `body.onload` runs) or loading stopped with error. + /// + /// + /// See the ICoreWebView2Frame2 article. + /// + property OnFrameNavigationCompleted2 : TOnFrameNavigationCompletedEvent read FOnFrameNavigationCompleted2 write FOnFrameNavigationCompleted2; + /// + /// `OnFrameContentLoading` triggers before any content is loaded, including scripts added with + /// `AddScriptToExecuteOnDocumentCreated`. `OnFrameContentLoading` does not trigger + /// if a same page navigation occurs (such as through `fragment` + /// navigations or `history.pushState` navigations). This operation + /// follows the `OnFrameNavigationStarting2` and precedes `OnFrameNavigationCompleted2` events. + /// + /// + /// See the ICoreWebView2Frame2 article. + /// + property OnFrameContentLoading : TOnFrameContentLoadingEvent read FOnFrameContentLoading write FOnFrameContentLoading; + /// + /// OnFrameDOMContentLoaded is raised when the iframe html document has been parsed. + /// This aligns with the document's DOMContentLoaded event in html. + /// + /// + /// See the ICoreWebView2Frame2 article. + /// + property OnFrameDOMContentLoaded : TOnFrameDOMContentLoadedEvent read FOnFrameDOMContentLoaded write FOnFrameDOMContentLoaded; + /// + /// `OnFrameWebMessageReceived` runs when the + /// `ICoreWebView2Settings.IsWebMessageEnabled` setting is set and the + /// frame document runs `window.chrome.webview.postMessage`. + /// + /// + /// See the ICoreWebView2Frame2 article. + /// + property OnFrameWebMessageReceived : TOnFrameWebMessageReceivedEvent read FOnFrameWebMessageReceived write FOnFrameWebMessageReceived; + /// + /// `OnFramePermissionRequested` is raised when content in an iframe any of its + /// descendant iframes requests permission to privileged resources. + /// This relates to the `OnPermissionRequested` event on the `CoreWebView2`. + /// Both these events will be raised in the case of an iframe requesting + /// permission. The `CoreWebView2Frame`'s event handlers will be invoked + /// before the event handlers on the `CoreWebView2`. If the `Handled` property + /// of the `PermissionRequestedEventArgs` is set to TRUE within the + /// `CoreWebView2Frame` event handler, then the event will not be + /// raised on the `CoreWebView2`, and it's event handlers will not be invoked. + /// In the case of nested iframes, if the `PermissionRequested` event is handled + /// in the current nested iframe (i.e., the Handled property of the + /// `PermissionRequestedEventArgs` is set to TRUE), the event will not be raised + /// on the parent `CoreWebView2Frame`. However, if the `PermissionRequested` event is + /// not handled in that nested iframe, the event will be raised from its nearest + /// tracked parent `CoreWebView2Frame`. It will iterate through the parent frame + /// chain up to the main frame until a parent frame handles the request. + /// If a deferral is not taken on the event args, the subsequent scripts are + /// blocked until the event handler returns. If a deferral is taken, the + /// scripts are blocked until the deferral is completed. + /// + /// + /// See the ICoreWebView2Frame3 article. + /// + property OnFramePermissionRequested : TOnFramePermissionRequestedEvent read FOnFramePermissionRequested write FOnFramePermissionRequested; + /// + /// OnDevToolsProtocolEventReceived is triggered when a DevTools protocol + /// event runs. It's necessary to subscribe to that event with a + /// SubscribeToDevToolsProtocolEvent call. + /// + /// + /// See the ICoreWebView2DevToolsProtocolEventReceiver article. + /// + property OnDevToolsProtocolEventReceived : TOnDevToolsProtocolEventReceivedEvent read FOnDevToolsProtocolEventReceived write FOnDevToolsProtocolEventReceived; + /// + /// `OnCustomItemSelected` event is raised when the user selects a custom `ContextMenuItem`. + /// Will only be raised for end developer created context menu items. + /// + /// + /// See the ICoreWebView2ContextMenuItem article. + /// + property OnCustomItemSelected : TOnCustomItemSelectedEvent read FOnCustomItemSelected write FOnCustomItemSelected; + /// + /// This event is triggered when the TWVBrowserBase.ClearBrowsingData call finishes executing. + /// + /// + /// See the ICoreWebView2Profile2 article. + /// + property OnClearBrowsingDataCompleted : TOnClearBrowsingDataCompletedEvent read FOnClearBrowsingDataCompleted write FOnClearBrowsingDataCompleted; + + /// + /// Called if any of the browser initialization steps fail. + /// + property OnInitializationError : TOnInitializationErrorEvent read FOnInitializationError write FOnInitializationError; + /// + /// Called when the environment was created successfully. + /// + property OnEnvironmentCompleted : TNotifyEvent read FOnEnvironmentCompleted write FOnEnvironmentCompleted; + /// + /// Called when the controller was created successfully. + /// + property OnControllerCompleted : TNotifyEvent read FOnControllerCompleted write FOnControllerCompleted; + /// + /// Called after a new browser is created and it's ready to navigate to the default URL. + /// + property OnAfterCreated : TNotifyEvent read FOnAfterCreated write FOnAfterCreated; + /// + /// Triggered when a TWVBrowserBase.ExecuteScript call finishes executing. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnExecuteScriptCompleted : TOnExecuteScriptCompletedEvent read FOnExecuteScriptCompleted write FOnExecuteScriptCompleted; + /// + /// Triggered when a TWVBrowserBase.CapturePreview call finishes writting the image to the stream. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnCapturePreviewCompleted : TOnCapturePreviewCompletedEvent read FOnCapturePreviewCompleted write FOnCapturePreviewCompleted; + /// + /// Triggered when a TWVBrowserBase.GetCookies call finishes executing. This event includes the requested cookies. + /// + /// + /// See the ICoreWebView2CookieManager article. + /// + property OnGetCookiesCompleted : TOnGetCookiesCompletedEvent read FOnGetCookiesCompleted write FOnGetCookiesCompleted; + /// + /// The TWVBrowserBase.OnTrySuspendCompleted event is triggered when a TWVBrowserBase.TrySuspend call finishes executing. + /// + /// + /// See the ICoreWebView2_3 article. + /// + property OnTrySuspendCompleted : TOnTrySuspendCompletedEvent read FOnTrySuspendCompleted write FOnTrySuspendCompleted; + /// + /// The TWVBrowserBase.OnPrintToPdfCompleted event is triggered when the TWVBrowserBase.PrintToPdf call finishes executing. + /// + /// + /// See the ICoreWebView2_7 article. + /// + property OnPrintToPdfCompleted : TOnPrintToPdfCompletedEvent read FOnPrintToPdfCompleted write FOnPrintToPdfCompleted; + /// + /// Called when the composition controller was created successfully. + /// + property OnCompositionControllerCompleted : TNotifyEvent read FOnCompositionControllerCompleted write FOnCompositionControllerCompleted; + /// + /// The TWVBrowserBase.OnCallDevToolsProtocolMethodCompleted event is triggered + /// when TWVBrowserBase.CallDevToolsProtocolMethod finishes executing. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnCallDevToolsProtocolMethodCompleted : TOnCallDevToolsProtocolMethodCompletedEvent read FOnCallDevToolsProtocolMethodCompleted write FOnCallDevToolsProtocolMethodCompleted; + /// + /// The TWVBrowserBase.OnAddScriptToExecuteOnDocumentCreatedCompleted event is triggered + /// when TWVBrowserBase.AddScriptToExecuteOnDocumentCreated finishes executing. + /// + /// + /// See the ICoreWebView2 article. + /// + property OnAddScriptToExecuteOnDocumentCreatedCompleted : TOnAddScriptToExecuteOnDocumentCreatedCompletedEvent read FOnAddScriptToExecuteOnDocumentCreatedCompleted write FOnAddScriptToExecuteOnDocumentCreatedCompleted; + /// + /// The TWVBrowserBase.OnWebResourceResponseViewGetContentCompleted event is triggered + /// when TCoreWebView2WebResourceResponseView.GetContent finishes executing. This event includes the resource contents. + /// + /// + /// See the MiniBrowser demo for an example. + /// See the ICoreWebView2WebResourceResponseView article. + /// + property OnWebResourceResponseViewGetContentCompleted : TOnWebResourceResponseViewGetContentCompletedEvent read FOnWebResourceResponseViewGetContentCompleted write FOnWebResourceResponseViewGetContentCompleted; + /// + /// Event triggered when the window called 'Chrome_WidgetWin_0' receives a message. + /// + property OnWidget0CompMsg : TOnCompMsgEvent read FOnWidget0CompMsg write FOnWidget0CompMsg; + /// + /// Event triggered when the window called 'Chrome_WidgetWin_1' receives a message. + /// + property OnWidget1CompMsg : TOnCompMsgEvent read FOnWidget1CompMsg write FOnWidget1CompMsg; + /// + /// Event triggered when the window called 'Chrome_RenderWidgetHostHWND' receives a message. + /// + property OnRenderCompMsg : TOnCompMsgEvent read FOnRenderCompMsg write FOnRenderCompMsg; + /// + /// Event triggered when the window called 'Intermediate D3D Window' receives a message. + /// + property OnD3DWindowCompMsg : TOnCompMsgEvent read FOnD3DWindowCompMsg write FOnD3DWindowCompMsg; + /// + /// The TWVBrowserBase.OnRetrieveHTMLCompleted event is triggered when TWVBrowserBase.RetrieveHTML finishes executing. It includes the HTML contents. + /// + property OnRetrieveHTMLCompleted : TOnRetrieveHTMLCompletedEvent read FOnRetrieveHTMLCompleted write FOnRetrieveHTMLCompleted; + /// + /// The TWVBrowserBase.OnRetrieveTextCompleted event is triggered when TWVBrowserBase.RetrieveText finishes executing. It includes the text contents. + /// + property OnRetrieveTextCompleted : TOnRetrieveTextCompletedEvent read FOnRetrieveTextCompleted write FOnRetrieveTextCompleted; + /// + /// The TWVBrowserBase.OnRetrieveMHTMLCompleted event is triggered when TWVBrowserBase.RetrieveMHTML finishes executing. It includes the MHTML contents. + /// + property OnRetrieveMHTMLCompleted : TOnRetrieveMHTMLCompletedEvent read FOnRetrieveMHTMLCompleted write FOnRetrieveMHTMLCompleted; + /// + /// The TWVBrowserBase.OnClearCacheCompleted event is triggered when TWVBrowserBase.ClearCache finishes executing. + /// + /// + /// See the Chrome DevTools Protocol page about the Network.clearBrowserCache method. + /// + property OnClearCacheCompleted : TOnClearCacheCompletedEvent read FOnClearCacheCompleted write FOnClearCacheCompleted; + /// + /// The TWVBrowserBase.OnClearDataForOriginCompleted event is triggered when TWVBrowserBase.ClearDataForOrigin finishes executing. + /// + /// + /// See the Chrome DevTools Protocol page about the Storage.clearDataForOrigin method. + /// + property OnClearDataForOriginCompleted : TOnClearDataForOriginCompletedEvent read FOnClearDataForOriginCompleted write FOnClearDataForOriginCompleted; + /// + /// The TWVBrowserBase.OnOfflineCompleted event is triggered after setting the TWVBrowserBase.Offline property. + /// + /// + /// See the Network Domain article. + /// + property OnOfflineCompleted : TOnOfflineCompletedEvent read FOnOfflineCompleted write FOnOfflineCompleted; + /// + /// The TWVBrowserBase.OnIgnoreCertificateErrorsCompleted event is triggered after setting the TWVBrowserBase.IgnoreCertificateErrors property. + /// + /// + /// See the Security Domain article. + /// + property OnIgnoreCertificateErrorsCompleted : TOnIgnoreCertificateErrorsCompletedEvent read FOnIgnoreCertificateErrorsCompleted write FOnIgnoreCertificateErrorsCompleted; + /// + /// The TWVBrowserBase.OnRefreshIgnoreCacheCompleted event is triggered when TWVBrowserBase.RefreshIgnoreCache finishes executing. + /// + /// + /// See the Page Domain article. + /// + property OnRefreshIgnoreCacheCompleted : TOnRefreshIgnoreCacheCompletedEvent read FOnRefreshIgnoreCacheCompleted write FOnRefreshIgnoreCacheCompleted; + /// + /// The TWVBrowserBase.OnSimulateKeyEventCompleted event is triggered when TWVBrowserBase.SimulateKeyEvent or TWVBrowserBase.SimulateEditingCommand finish executing. + /// + /// + /// See the "Input.dispatchKeyEvent" DevTools method. + /// + property OnSimulateKeyEventCompleted : TOnSimulateKeyEventCompletedEvent read FOnSimulateKeyEventCompleted write FOnSimulateKeyEventCompleted; + /// + /// OnGetCustomSchemes is triggered automatically before creaing the environment to register custom schemes. + /// Fill the aCustomSchemes event parameter with all the information to create one or more + /// ICoreWebView2CustomSchemeRegistration instances that will be used during the creation of the Environment. + /// + /// + /// See TWVCustomSchemeInfo. + /// See the ICoreWebView2CustomSchemeRegistration article. + /// See the ICoreWebView2EnvironmentOptions4 article. + /// + property OnGetCustomSchemes : TOnGetCustomSchemesEvent read FOnGetCustomSchemes write FOnGetCustomSchemes; + /// + /// The TWVBrowserBase.OnGetNonDefaultPermissionSettingsCompleted event is triggered when TWVBrowserBase.GetNonDefaultPermissionSettings finishes executing. + /// + /// + /// See the ICoreWebView2Profile4 article. + /// + property OnGetNonDefaultPermissionSettingsCompleted : TOnGetNonDefaultPermissionSettingsCompletedEvent read FOnGetNonDefaultPermissionSettingsCompleted write FOnGetNonDefaultPermissionSettingsCompleted; + /// + /// The TWVBrowserBase.OnSetPermissionStateCompleted event is triggered when TWVBrowserBase.SetPermissionState finishes executing. + /// + /// + /// See the ICoreWebView2Profile4 article. + /// + property OnSetPermissionStateCompleted : TOnSetPermissionStateCompletedEvent read FOnSetPermissionStateCompleted write FOnSetPermissionStateCompleted; + /// + /// The `OnLaunchingExternalUriScheme` event is raised when a navigation request is made to + /// a URI scheme that is registered with the OS. + /// + /// The `OnLaunchingExternalUriScheme` event handler may suppress the default dialog + /// or replace the default dialog with a custom dialog. + /// + /// If a deferral is not taken on the event args, the external URI scheme launch is + /// blocked until the event handler returns. If a deferral is taken, the + /// external URI scheme launch is blocked until the deferral is completed. + /// The host also has the option to cancel the URI scheme launch. + /// + /// The `OnNavigationStarting` and `OnNavigationCompleted` events will be raised, + /// regardless of whether the `Cancel` property is set to `TRUE` or + /// `FALSE`. The `OnNavigationCompleted` event will be raised with the `IsSuccess` property + /// set to `FALSE` and the `WebErrorStatus` property set to `ConnectionAborted` regardless of + /// whether the host sets the `Cancel` property on the + /// `ICoreWebView2LaunchingExternalUriSchemeEventArgs`. The `OnSourceChanged`, `OnContentLoading`, + /// and `OnHistoryChanged` events will not be raised for this navigation to the external URI + /// scheme regardless of the `Cancel` property. + /// + /// The `OnLaunchingExternalUriScheme` event will be raised after the + /// `OnNavigationStarting` event and before the `OnNavigationCompleted` event. + /// + /// The default `CoreWebView2Settings` will also be updated upon navigation to an external + /// URI scheme. If a setting on the `CoreWebView2Settings` interface has been changed, + /// navigating to an external URI scheme will trigger the `CoreWebView2Settings` to update. + /// + /// The WebView2 may not display the default dialog based on user settings, browser settings, + /// and whether the origin is determined as a + /// [trustworthy origin](https://w3c.github.io/webappsec-secure-contexts# + /// potentially-trustworthy-origin); however, the event will still be raised. + /// + /// If the request is initiated by a cross-origin frame without a user gesture, + /// the request will be blocked and the `OnLaunchingExternalUriScheme` event will not + /// be raised. + /// + /// + /// See the ICoreWebView2_18 article. + /// + property OnLaunchingExternalUriScheme : TOnLaunchingExternalUriSchemeEvent read FOnLaunchingExternalUriScheme write FOnLaunchingExternalUriScheme; + /// + /// The TWVBrowserBase.OnGetProcessExtendedInfosCompleted event is triggered when TWVBrowserBase.GetProcessExtendedInfos finishes executing. + /// + /// + /// See the ICoreWebView2Environment13 article. + /// + property OnGetProcessExtendedInfosCompleted : TOnGetProcessExtendedInfosCompletedEvent read FOnGetProcessExtendedInfosCompleted write FOnGetProcessExtendedInfosCompleted; + /// + /// The TWVBrowserBase.OnBrowserExtensionRemoveCompleted event is triggered when TCoreWebView2BrowserExtension.Remove finishes executing. + /// + /// + /// See the ICoreWebView2BrowserExtension article. + /// + property OnBrowserExtensionRemoveCompleted : TOnBrowserExtensionRemoveCompletedEvent read FOnBrowserExtensionRemoveCompleted write FOnBrowserExtensionRemoveCompleted; + /// + /// The TWVBrowserBase.OnBrowserExtensionEnableCompleted event is triggered when TCoreWebView2BrowserExtension.Enable finishes executing. + /// + /// + /// See the ICoreWebView2BrowserExtension article. + /// + property OnBrowserExtensionEnableCompleted : TOnBrowserExtensionEnableCompletedEvent read FOnBrowserExtensionEnableCompleted write FOnBrowserExtensionEnableCompleted; + /// + /// The TWVBrowserBase.OnProfileAddBrowserExtensionCompleted event is triggered when TWVBrowserBase.AddBrowserExtension finishes executing. + /// + /// + /// See the ICoreWebView2Profile7 article. + /// + property OnProfileAddBrowserExtensionCompleted : TOnProfileAddBrowserExtensionCompletedEvent read FOnProfileAddBrowserExtensionCompleted write FOnProfileAddBrowserExtensionCompleted; + /// + /// The TWVBrowserBase.OnProfileGetBrowserExtensionsCompleted event is triggered when TWVBrowserBase.GetBrowserExtensions finishes executing. + /// + /// + /// See the ICoreWebView2Profile7 article. + /// + property OnProfileGetBrowserExtensionsCompleted : TOnProfileGetBrowserExtensionsCompletedEvent read FOnProfileGetBrowserExtensionsCompleted write FOnProfileGetBrowserExtensionsCompleted; + /// + /// The TWVBrowserBase.OnProfileDeleted event is triggered when TWVBrowserBase.Delete finishes executing. + /// + /// + /// See the ICoreWebView2Profile8 article. + /// + property OnProfileDeleted : TOnProfileDeletedEvent read FOnProfileDeleted write FOnProfileDeleted; + /// + /// Provides the result of ExecuteScriptWithResult. + /// + /// + /// See the ICoreWebView2_21 article. + /// + property OnExecuteScriptWithResultCompleted : TOnExecuteScriptWithResultCompletedEvent read FOnExecuteScriptWithResultCompleted write FOnExecuteScriptWithResultCompleted; + /// + /// This event is fired when regions which are marked as non-client in the + /// app html have changed. So either when new regions have been marked, + /// or unmarked, or the region(s) have been changed to a different kind. + /// + /// + /// See the ICoreWebView2CompositionController4 article. + /// + property OnNonClientRegionChanged : TOnNonClientRegionChangedEvent read FOnNonClientRegionChanged write FOnNonClientRegionChanged; + /// + /// Event for non-persistent notifications. + /// + /// If a deferral is not taken on the event args, the subsequent scripts after + /// the DOM notification creation call (i.e. `Notification()`) are blocked + /// until the event handler returns. If a deferral is taken, the scripts are + /// blocked until the deferral is completed. + /// + /// + /// See the ICoreWebView2_24 article. + /// + property OnNotificationReceived : TOnNotificationReceivedEvent read FOnNotificationReceived write FOnNotificationReceived; + /// + /// This event is raised when the notification is closed by the web code, such as through + /// `notification.close()`. You don't need to call `ReportClosed` since this is + /// coming from the web code. + /// + /// + /// See the ICoreWebView2Notification article. + /// + property OnNotificationCloseRequested : TOnNotificationCloseRequestedEvent read FOnNotificationCloseRequested write FOnNotificationCloseRequested; + /// + /// This event is raised when save as is triggered, programmatically or manually. + /// + /// + /// See the ICoreWebView2_25 article. + /// + property OnSaveAsUIShowing : TOnSaveAsUIShowingEvent read FOnSaveAsUIShowing write FOnSaveAsUIShowing; + /// + /// This event receives the result of the `ShowSaveAsUI` method. + /// + /// + /// See the ICoreWebView2_25 article. + /// + property OnShowSaveAsUICompleted : TOnShowSaveAsUICompletedEvent read FOnShowSaveAsUICompleted write FOnShowSaveAsUICompleted; + /// + /// This event will be raised during system FileTypePolicy + /// checking the dangerous file extension list. + /// Developers can specify their own logic for determining whether + /// to allow a particular type of file to be saved from the document origin URI. + /// Developers can also determine the save decision based on other criteria. + /// Here are two properties in `ICoreWebView2SaveFileSecurityCheckStartingEventArgs` + /// to manage the decision: `CancelSave` and `SuppressDefaultPolicy`. + /// Table of Properties' value and result: + /// + /// | CancelSave | SuppressDefaultPolicy | Result + /// | ---------- | ------ | --------------------- + /// | False | False | Perform the default policy check. It may show the + /// | | | security warning UI if the file extension is + /// | | | dangerous. + /// | ---------- | ------ | --------------------- + /// | False | True | Skip the default policy check and the possible + /// | | | security warning. Start saving or downloading. + /// | ---------- | ------ | --------------------- + /// | True | Any | Skip the default policy check and the possible + /// | | | security warning. Abort save or download. + /// + /// + /// + /// See the ICoreWebView2_26 article. + /// See the FileTypePolicy API article. + /// + property OnSaveFileSecurityCheckStarting : TOnSaveFileSecurityCheckStartingEvent read FOnSaveFileSecurityCheckStarting write FOnSaveFileSecurityCheckStarting; + /// + /// `OnScreenCaptureStarting` event is raised when the [Screen Capture API](https://www.w3.org/TR/screen-capture/) + /// is requested by the user using getDisplayMedia(). + /// + /// + /// See the ICoreWebView2_27 article. + /// + property OnScreenCaptureStarting : TOnScreenCaptureStartingEvent read FOnScreenCaptureStarting write FOnScreenCaptureStarting; + /// + /// `OnFrameScreenCaptureStarting` is raised when content in an iframe or any of its + /// descendant iframes requests permission to use the Screen Capture + /// API from getDisplayMedia(). + /// + /// This relates to the `ScreenCaptureStarting` event on the + /// `CoreWebView2`. + /// Both these events will be raised in the case of an iframe requesting + /// screen capture. The `CoreWebView2Frame`'s event handlers will be invoked + /// before the event handlers on the `CoreWebView2`. If the `Handled` + /// property of the `ScreenCaptureStartingEventArgs` is set to TRUE + /// within the`CoreWebView2Frame` event handler, then the event will not + /// be raised on the `CoreWebView2`, and its event handlers will not be + /// invoked. + /// + /// + /// See the ICoreWebView2Frame6 article. + /// + property OnFrameScreenCaptureStarting : TOnFrameScreenCaptureStartingEvent read FOnFrameScreenCaptureStarting write FOnFrameScreenCaptureStarting; + /// + /// Raised when a new direct descendant iframe is created. + /// Handle this event to get access to ICoreWebView2Frame objects. + /// Use `OnFrameDestroyed` to listen for when this iframe goes away. + /// + /// + /// See the ICoreWebView2Frame7 article. + /// + property OnFrameChildFrameCreated : TOnFrameChildFrameCreatedEvent read FOnFrameChildFrameCreated write FOnFrameChildFrameCreated; + /// + /// This event is raised when the index of the currently active match changes. + /// This can happen when the user navigates to a different match or when the active match is changed programmatically. + /// + /// + /// See the ICoreWebView2Find article. + /// + property OnFindActiveMatchIndexChanged : TOnFindActiveMatchIndexChangedEvent read FOnFindActiveMatchIndexChanged write FOnFindActiveMatchIndexChanged; + /// + /// This event is raised when the total count of matches in the document changes due to a new find session or changes in the document. + /// + /// + /// See the ICoreWebView2Find article. + /// + property OnFindMatchCountChanged : TOnFindMatchCountChangedEvent read FOnFindMatchCountChanged write FOnFindMatchCountChanged; + /// + /// This event receives the result of the FindStart method. + /// + /// + /// See the ICoreWebView2Find article. + /// See the ICoreWebView2FindStartCompletedHandler article. + /// + property OnFindStartCompleted : TOnFindStartCompletedEvent read FOnFindStartCompleted write FOnFindStartCompleted; + /// + /// `DragStarting` is a deferrable event that is raised when the WebView2 + /// detects a drag started within the WebView2. + /// WebView2's default drag behavior is to synchronously call DoDragDrop when + /// it detects drag. This event's args expose the data WebView2 uses to call + /// DoDragDrop to allow users to implement their own drag logic and override + /// WebView2's. + /// Handlers of this event must set the `Handled` event to true in order to + /// override WebView2's default logic. When invoking drag logic asynchronously + /// using a deferral, handlers must take care to follow these steps in order: + /// + /// * Invoke asynchronous drag logic + /// * Set the event args `Handled` property true + /// * Complete the deferral + /// + /// In the asynchronous case, WebView2 decides whether or not to invoke its + /// default drag logic when the deferral completes. So the event args' + /// `Handled` property must be true when the deferral is completed. + /// + /// + /// See the ICoreWebView2CompositionController5 article. + /// + property OnDragStarting : TOnDragStartingEvent read FOnDragStarting write FOnDragStarting; + /// + /// Subscribe to this event that gets raised when a new dedicated worker is created. + /// + /// A Dedicated Worker is a type of web worker that allows you to run Javascript + /// code in the background without blocking the main thread, making them useful + /// for tasks like heavy computations, data processing, and parallel execution. + /// It is "dedicated" because it is linked to a single parent document and cannot + /// be shared with other scripts. + /// + /// This event is raised when a web application creates a dedicated worker using the + /// `new Worker("/worker.js")` method. See the + /// [Worker](https://developer.mozilla.org/docs/Web/API/Worker/Worker) + /// for more information. + /// + /// + /// See the ICoreWebView2_29 article. + /// + property OnDedicatedWorkerCreated : TOnDedicatedWorkerCreatedEvent read FOnDedicatedWorkerCreated write FOnDedicatedWorkerCreated; + /// + /// Subscribe to this event that gets raised when a new dedicated worker is created from a + /// dedicated worker. + /// + /// A Dedicated Worker is a type of web worker that allows you to run Javascript + /// code in the background without blocking the main thread, making them useful + /// for tasks like heavy computations, data processing, and parallel execution. + /// It is "dedicated" because it is linked to a single parent document and cannot + /// be shared with other scripts. + /// + /// This event is raised when a dedicated creates a dedicated worker using the + /// `new Worker("/worker.js")` method. See the + /// [Worker](https://developer.mozilla.org/docs/Web/API/Worker/Worker) + /// for more information. + /// + /// + /// See the ICoreWebView2DedicatedWorker article. + /// + property OnDedicatedWorkerCreated2 : TOnDedicatedWorkerCreated2Event read FOnDedicatedWorkerCreated2 write FOnDedicatedWorkerCreated2; + /// + /// Add an event handler for the `Destroying` event that is raised when the + /// worker object is Destroying. + /// + /// A worker object is Destroying when the worker script is terminated or when + /// the `CoreWebView2DedicatedWorker` object is Destroying. + /// + /// If the worker has already been destroyed before the event handler is registered, + /// the handler will never be called. + /// + /// + /// See the ICoreWebView2DedicatedWorker article. + /// + property OnDedicatedWorkerDestroying : TOnDedicatedWorkerDestroyingEvent read FOnDedicatedWorkerDestroying write FOnDedicatedWorkerDestroying; + /// + /// `OnWebMessageReceived` is fired, when the + /// `ICoreWebView2Settings.IsWebMessageEnabled` setting is set TRUE and the + /// worker runs `self.chrome.webview.postMessage`. The `postMessage` function + /// is `void postMessage(object)` where object is any object supported by JSON + /// conversion. + /// + /// If the worker calls `postMessage` multiple times, the corresponding + /// `OnWebMessageReceived` events are guaranteed to be fired in the same order. + /// + /// + /// See the ICoreWebView2DedicatedWorker article. + /// + property OnDedicatedWorkerWebMessageReceived : TOnDedicatedWorkerWebMessageReceivedEvent read FOnDedicatedWorkerWebMessageReceived write FOnDedicatedWorkerWebMessageReceived; + /// + /// Subscribe to this event that gets raised when a new dedicated worker is created + /// from an iframe. + /// + /// A Dedicated Worker is a type of web worker that allows you to run Javascript + /// code in the background without blocking the main thread, making them useful + /// for tasks like heavy computations, data processing, and parallel execution. + /// It is "dedicated" because it is linked to a single parent document and cannot + /// be shared with other scripts. + /// + /// This event is raised when a web application creates a dedicated worker using the + /// `new Worker("/worker.js")` method. See the + /// [Worker](https://developer.mozilla.org/docs/Web/API/Worker/Worker) + /// for more information. + /// + /// + /// See the ICoreWebView2Frame8 article. + /// + property OnFrameDedicatedWorkerCreated : TOnFrameDedicatedWorkerCreatedEvent read FOnFrameDedicatedWorkerCreated write FOnFrameDedicatedWorkerCreated; + /// + /// Add an event handler for the `Destroying` event that is raised when the + /// worker object is Destroying. + /// A worker object is Destroying when the worker script is terminated or when + /// the `CoreWebView2ServiceWorker` object is Destroying. + /// If the worker has already been destroyed before the event handler is registered, + /// the handler will never be called. + /// + /// + /// See the ICoreWebView2ServiceWorker article. + /// + property OnServiceWorkerDestroying : TOnServiceWorkerDestroyingEvent read FOnServiceWorkerDestroying write FOnServiceWorkerDestroying; + /// + /// `OnWebMessageReceived` is fired, when the + /// `ICoreWebView2Settings.IsWebMessageEnabled` setting is set TRUE and the + /// worker runs `self.chrome.webview.postMessage`. The `postMessage` function + /// is `void postMessage(object)` where object is any object supported by JSON + /// conversion. + /// If the worker calls `postMessage` multiple times, the corresponding + /// `WebMessageReceived` events are guaranteed to be fired in the same order. + /// + /// + /// See the ICoreWebView2ServiceWorker article. + /// + property OnServiceWorkerWebMessageReceived : TOnServiceWorkerWebMessageReceivedEvent read FOnServiceWorkerWebMessageReceived write FOnServiceWorkerWebMessageReceived; + /// + /// A ServiceWorker is a specific type of worker that takes a JavaScript file + /// that can control the web-page/site that it is associated with, + /// intercepting and modifying navigation and resource requests, and caching + /// resources in a very granular fashion to give you complete control + /// over how app behaves in certain situations. + /// + /// Service workers essentially act as proxy servers that sit between web + /// applications, the browser, and the network (when available). They run in + /// a different context from the web page, which means they have no direct access + /// to the DOM. Unlike dedicated and shared workers, which may have direct access to a + /// global scope shared with other scripts, service workers operate in isolation + /// from the DOM, ensuring a more secure and controlled environment. + /// + /// This event is raised when a web application registers a service worker using the + /// `navigator.serviceWorker.register("/sw.js")` method. See the + /// [Service Worker Registration](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration) + /// for more information. + /// + /// + /// See the ICoreWebView2ServiceWorkerManager article. + /// + property OnServiceWorkerRegistered : TOnServiceWorkerRegisteredEvent read FOnServiceWorkerRegistered write FOnServiceWorkerRegistered; + /// + /// Receives the result of the TCoreWebView2ServiceWorkerManager.GetServiceWorkerRegistrations and TCoreWebView2ServiceWorkerManager.GetServiceWorkerRegistrationsForScope methods. + /// + /// + /// See the ICoreWebView2ServiceWorkerManager article. + /// + property OnGetServiceWorkerRegistrationsCompleted : TOnGetServiceWorkerRegistrationsCompletedEvent read FOnGetServiceWorkerRegistrationsCompleted write FOnGetServiceWorkerRegistrationsCompleted; + /// + /// This event is raised when a service worker is activated. A service worker is + /// activated when its script has been successfully registered and it is ready to + /// control the pages within the scope of the registration. + /// + /// This event is also raised when an updated version of a service worker reaches the active state. + /// In such a case, the existing CoreWebView2ServiceWorker object is destroying, and this event is + /// raised with a new CoreWebView2ServiceWorker object representing the updated service worker. + /// The active service worker is the one that receives fetch and message events for the pages it controls. + /// See the [Service Worker](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/active) + /// documentation for more information. + /// + /// If you register for the `OnServiceWorkerActivated` event and the registration already + /// has an active worker, the event handler is not called immediately. Instead, it waits + /// for the next activation event to occur. Therefore, you should first check if an active + /// service worker is running by using the `TCoreWebView2ServiceWorkerRegistration.ActiveServiceWorker` property. + /// + /// + /// See the ICoreWebView2ServiceWorkerRegistration article. + /// + property OnServiceWorkerActivated : TOnServiceWorkerActivatedEvent read FOnServiceWorkerActivated write FOnServiceWorkerActivated; + /// + /// This event is raised when the worker registration is + /// unregistered using the JS api `registration.unregister()`. See the + /// [Unregister](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/unregister) + /// for more information. + /// + /// + /// See the ICoreWebView2ServiceWorkerRegistration article. + /// + property OnServiceWorkerRegistrationUnregistering : TOnServiceWorkerRegistrationUnregisteringEvent read FOnServiceWorkerRegistrationUnregistering write FOnServiceWorkerRegistrationUnregistering; + /// + /// A SharedWorker is a specific type of worker that can be accessed from several + /// browsing contexts, such as multiple windows, iframes, or even other workers. + /// Unlike Dedicated Workers, which have their own separate global scope, SharedWorkers + /// share a common global scope called SharedWorkerGlobalScope. + /// + /// This event is raised when a web application creates a shared worker using the + /// `new SharedWorker("worker.js")` method. See the + /// [Shared Worker](https://developer.mozilla.org/docs/Web/API/SharedWorker) + /// for more information. + /// + /// + /// See the ICoreWebView2SharedWorkerManager article. + /// + property OnSharedWorkerCreated : TOnSharedWorkerCreatedEvent read FOnSharedWorkerCreated write FOnSharedWorkerCreated; + /// + /// Receives the result of the TCoreWebView2SharedWorkerManager.GetSharedWorkers method. + /// + /// + /// See the ICoreWebView2GetSharedWorkersCompletedHandler article. + /// + property OnGetSharedWorkersCompleted : TOnGetSharedWorkersCompletedEvent read FOnGetSharedWorkersCompleted write FOnGetSharedWorkersCompleted; + /// + /// This event is raised when the worker object is Destroying. + /// + /// A worker object is Destroying when the worker script is terminated or when + /// the `CoreWebView2SharedWorker` object is Destroying. + /// + /// If the worker has already been destroyed before the event handler is registered, + /// the handler will never be called. + /// + /// + /// See the ICoreWebView2SharedWorker article. + /// + property OnSharedWorkerDestroying : TOnSharedWorkerDestroyingEvent read FOnSharedWorkerDestroying write FOnSharedWorkerDestroying; + end; + +implementation + +uses + uRESTDWPrivWVMiscFunctions, uRESTDWPrivWVCoreWebView2EnvironmentOptions, uRESTDWPrivWVCoreWebView2ControllerOptions, + uRESTDWPrivWVCoreWebView2CustomSchemeRegistration; + +constructor TWVBrowserBase.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + + FCoreWebView2PrintSettings := nil; + FCoreWebView2Settings := nil; + FCoreWebView2Environment := nil; + FCoreWebView2Controller := nil; + FCoreWebView2CompositionController := nil; + FCoreWebView2 := nil; + FCoreWebView2Profile := nil; + FCoreWebView2FindOptions := nil; + FCoreWebView2Find := nil; + FDefaultURL := ''; + FUseDefaultEnvironment := False; + FUseCompositionController := False; + FZoomStep := ZOOM_STEP_DEF; + FOffline := False; + FIsNavigating := False; + FProfileName := ''; + FIsInPrivateModeEnabled := False; + FScriptLocale := ''; + FDefaultBackgroundColor := TColor($FFFFFFFF); // opaque white + FAllowHostInputProcessing := False; + FClearBrowsingDataCompletedHandler := nil; + FSetPermissionStateCompletedHandler := nil; + FGetNonDefaultPermissionSettingsCompletedHandler := nil; + FProfileAddBrowserExtensionCompletedHandler := nil; + FProfileGetBrowserExtensionsCompletedHandler := nil; + + // Fields used to create the environment + FAdditionalBrowserArguments := ''; + FLanguage := ''; + FTargetCompatibleBrowserVersion := LowestChromiumVersion; + FAllowSingleSignOnUsingOSPrimaryAccount := False; + FExclusiveUserDataFolderAccess := False; + FCustomCrashReportingEnabled := False; + FEnableTrackingPrevention := True; + FAreBrowserExtensionsEnabled := False; + FChannelSearchKind := COREWEBVIEW2_CHANNEL_SEARCH_KIND_MOST_STABLE; + FReleaseChannels := COREWEBVIEW2_RELEASE_CHANNELS_STABLE or + COREWEBVIEW2_RELEASE_CHANNELS_BETA or + COREWEBVIEW2_RELEASE_CHANNELS_DEV or + COREWEBVIEW2_RELEASE_CHANNELS_CANARY; + FScrollBarStyle := COREWEBVIEW2_SCROLLBAR_STYLE_DEFAULT; + + FOldWidget0CompWndPrc := nil; + FOldWidget1CompWndPrc := nil; + FOldRenderCompWndPrc := nil; + FOldD3DWindowCompWndPrc := nil; + FWidget0CompStub := nil; + FWidget1CompStub := nil; + FRenderCompStub := nil; + FD3DWindowCompStub := nil; + FWidget0CompHWND := 0; + FWidget1CompHWND := 0; + FRenderCompHWND := 0; + FD3DWindowCompHWND := 0; + + FOnInitializationError := nil; + FOnEnvironmentCompleted := nil; + FOnControllerCompleted := nil; + FOnAfterCreated := nil; + FOnExecuteScriptCompleted := nil; + FOnCapturePreviewCompleted := nil; + FOnNavigationStarting := nil; + FOnNavigationCompleted := nil; + FOnFrameNavigationStarting := nil; + FOnFrameNavigationCompleted := nil; + FOnSourceChanged := nil; + FOnHistoryChanged := nil; + FOnContentLoading := nil; + FOnDocumentTitleChanged := nil; + FOnNewWindowRequested := nil; + FOnWebResourceRequested := nil; + FOnScriptDialogOpening := nil; + FOnPermissionRequested := nil; + FOnProcessFailed := nil; + FOnWebMessageReceived := nil; + FOnContainsFullScreenElementChanged := nil; + FOnWindowCloseRequested := nil; + FOnDevToolsProtocolEventReceived := nil; + FOnZoomFactorChanged := nil; + FOnMoveFocusRequested := nil; + FOnAcceleratorKeyPressed := nil; + FOnGotFocus := nil; + FOnLostFocus := nil; + FOnCursorChanged := nil; + FOnBrowserProcessExited := nil; + FOnProcessInfosChanged := nil; + FOnFrameNavigationStarting2 := nil; + FOnFrameNavigationCompleted2 := nil; + FOnFrameContentLoading := nil; + FOnFrameDOMContentLoaded := nil; + FOnFrameWebMessageReceived := nil; + FOnRasterizationScaleChanged := nil; + FOnWebResourceResponseReceived := nil; + FOnDOMContentLoaded := nil; + FOnWebResourceResponseViewGetContentCompleted := nil; + FOnGetCookiesCompleted := nil; + FOnTrySuspendCompleted := nil; + FOnFrameCreated := nil; + FOnDownloadStarting := nil; + FOnClientCertificateRequested := nil; + FOnPrintToPdfCompleted := nil; + FOnBytesReceivedChanged := nil; + FOnEstimatedEndTimeChanged := nil; + FOnDownloadStateChanged := nil; + FOnFrameNameChanged := nil; + FOnFrameDestroyed := nil; + FOnCompositionControllerCompleted := nil; + FOnCallDevToolsProtocolMethodCompleted := nil; + FOnAddScriptToExecuteOnDocumentCreatedCompleted := nil; + FOnWidget0CompMsg := nil; + FOnWidget1CompMsg := nil; + FOnRenderCompMsg := nil; + FOnD3DWindowCompMsg := nil; + FOnPrintCompleted := nil; + FOnRetrieveHTMLCompleted := nil; + FOnRetrieveTextCompleted := nil; + FOnRetrieveMHTMLCompleted := nil; + FOnClearCacheCompleted := nil; + FOnClearDataForOriginCompleted := nil; + FOnOfflineCompleted := nil; + FOnIgnoreCertificateErrorsCompleted := nil; + FOnRefreshIgnoreCacheCompleted := nil; + FOnSimulateKeyEventCompleted := nil; + FOnIsMutedChanged := nil; + FOnIsDocumentPlayingAudioChanged := nil; + FOnIsDefaultDownloadDialogOpenChanged := nil; + FOnBasicAuthenticationRequested := nil; + FOnContextMenuRequested := nil; + FOnCustomItemSelected := nil; + FOnStatusBarTextChanged := nil; + FOnFramePermissionRequested := nil; + FOnClearBrowsingDataCompleted := nil; + FOnServerCertificateErrorActionsCompleted := nil; + FOnServerCertificateErrorDetected := nil; + FOnFaviconChanged := nil; + FOnGetFaviconCompleted := nil; + FOnPrintToPdfStreamCompleted := nil; + FOnGetCustomSchemes := nil; + FOnGetNonDefaultPermissionSettingsCompleted := nil; + FOnSetPermissionStateCompleted := nil; + FOnLaunchingExternalUriScheme := nil; + FOnGetProcessExtendedInfosCompleted := nil; + FOnBrowserExtensionRemoveCompleted := nil; + FOnBrowserExtensionEnableCompleted := nil; + FOnProfileAddBrowserExtensionCompleted := nil; + FOnProfileGetBrowserExtensionsCompleted := nil; + FOnProfileDeleted := nil; + FOnExecuteScriptWithResultCompleted := nil; + FOnNonClientRegionChanged := nil; + FOnNotificationReceived := nil; + FOnNotificationCloseRequested := nil; + FOnSaveAsUIShowing := nil; + FOnShowSaveAsUICompleted := nil; + FOnSaveFileSecurityCheckStarting := nil; + FOnScreenCaptureStarting := nil; + FOnFrameScreenCaptureStarting := nil; + FOnFrameChildFrameCreated := nil; + FOnFindActiveMatchIndexChanged := nil; + FOnFindMatchCountChanged := nil; + FOnFindStartCompleted := nil; + FOnDragStarting := nil; + FOnDedicatedWorkerCreated := nil; + FOnDedicatedWorkerCreated2 := nil; + FOnDedicatedWorkerDestroying := nil; + FOnDedicatedWorkerWebMessageReceived := nil; + FOnFrameDedicatedWorkerCreated := nil; + FOnServiceWorkerDestroying := nil; + FOnServiceWorkerWebMessageReceived := nil; + FOnServiceWorkerRegistered := nil; + FOnGetServiceWorkerRegistrationsCompleted := nil; + FOnServiceWorkerActivated := nil; + FOnServiceWorkerRegistrationUnregistering := nil; + FOnSharedWorkerCreated := nil; + FOnGetSharedWorkersCompleted := nil; + FOnSharedWorkerDestroying := nil; +end; + +destructor TWVBrowserBase.Destroy; +begin + try + RestoreOldCompWndProc; + DestroyProfile; + DestroyFindOptions; + DestroyFind; + DestroyPrintSettings; + DestroySettings; + DestroyEnvironment; + DestroyWebView; + DestroyController; + DestroyCompositionController; + + FClearBrowsingDataCompletedHandler := nil; + FSetPermissionStateCompletedHandler := nil; + FGetNonDefaultPermissionSettingsCompletedHandler := nil; + FProfileAddBrowserExtensionCompletedHandler := nil; + FProfileGetBrowserExtensionsCompletedHandler := nil; + finally + inherited Destroy; + end; +end; + +procedure TWVBrowserBase.DestroyEnvironment; +begin + if assigned(FCoreWebView2Environment) then + FreeAndNil(FCoreWebView2Environment); +end; + +procedure TWVBrowserBase.DestroyController; +begin + if assigned(FCoreWebView2Controller) then + FreeAndNil(FCoreWebView2Controller); +end; + +procedure TWVBrowserBase.DestroyCompositionController; +begin + if assigned(FCoreWebView2CompositionController) then + FreeAndNil(FCoreWebView2CompositionController); +end; + +procedure TWVBrowserBase.DestroyWebView; +begin + if assigned(FCoreWebView2) then + FreeAndNil(FCoreWebView2); +end; + +procedure TWVBrowserBase.DestroyProfile; +begin + if assigned(FCoreWebView2Profile) then + FreeAndNil(FCoreWebView2Profile); +end; + +procedure TWVBrowserBase.DestroyFindOptions; +begin + if assigned(FCoreWebView2FindOptions) then + FreeAndNil(FCoreWebView2FindOptions); +end; + +procedure TWVBrowserBase.DestroyFind; +begin + if assigned(FCoreWebView2Find) then + FreeAndNil(FCoreWebView2Find); +end; + +procedure TWVBrowserBase.DestroySettings; +begin + if assigned(FCoreWebView2Settings) then + FreeAndNil(FCoreWebView2Settings); +end; + +procedure TWVBrowserBase.DestroyPrintSettings; +begin + if assigned(FCoreWebView2PrintSettings) then + FreeAndNil(FCoreWebView2PrintSettings); +end; + +procedure TWVBrowserBase.AfterConstruction; +begin + inherited AfterConstruction; + + FClearBrowsingDataCompletedHandler := TCoreWebView2ClearBrowsingDataCompletedHandler.Create(self); + FSetPermissionStateCompletedHandler := TCoreWebView2SetPermissionStateCompletedHandler.Create(self); + FGetNonDefaultPermissionSettingsCompletedHandler := TCoreWebView2GetNonDefaultPermissionSettingsCompletedHandler.Create(self); + FProfileAddBrowserExtensionCompletedHandler := TCoreWebView2ProfileAddBrowserExtensionCompletedHandler.Create(self); + FProfileGetBrowserExtensionsCompletedHandler := TCoreWebView2ProfileGetBrowserExtensionsCompletedHandler.Create(self); +end; + +{$IFNDEF FPC} +// Windows XP and newer (older Delphi version < XE don't have them and newer +// require a call to InitCommonControl what isn't necessary. +{type + SUBCLASSPROC = function(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM; + uIdSubclass: UINT_PTR; dwRefData: DWORD_PTR): LRESULT; stdcall; + TSubClassProc = SUBCLASSPROC; + +function SetWindowSubclass(hWnd: HWND; pfnSubclass: SUBCLASSPROC; uIdSubclass: UINT_PTR; dwRefData: DWORD_PTR): BOOL; stdcall; + external comctl32 name 'SetWindowSubclass'; +//function GetWindowSubclass(hWnd: HWND; pfnSubclass: SUBCLASSPROC; uIdSubclass: UINT_PTR; var pdwRefData: DWORD_PTR): BOOL; stdcall; +// external comctl32 name 'GetWindowSubclass'; +function RemoveWindowSubclass(hWnd: HWND; pfnSubclass: SUBCLASSPROC; uIdSubclass: UINT_PTR): BOOL; stdcall; + external comctl32 name 'RemoveWindowSubclass'; +function DefSubclassProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; + external comctl32 name 'DefSubclassProc'; + +// We stick with the original implementation because the WndProc stub is a lot +// faster than the WindowSubClass stub that uses the slow GetProp(hWnd). Which +// is extremly slow in Windows 10 1809 and newer. +} + +procedure TWVBrowserBase.CreateStub(const aMethod : TWndMethod; var aStub : Pointer); +begin + if (aStub = nil) then aStub := MakeObjectInstance(aMethod); +end; + +procedure TWVBrowserBase.FreeAndNilStub(var aStub : pointer); +begin + if (aStub <> nil) then + begin + FreeObjectInstance(aStub); + aStub := nil; + end; +end; + +function TWVBrowserBase.InstallCompWndProc(aWnd: THandle; aStub: Pointer): TFNWndProc; +begin + Result := TFNWndProc(SetWindowLongPtr(aWnd, GWLP_WNDPROC, NativeInt(aStub))); +end; + +procedure TWVBrowserBase.RestoreCompWndProc(var aOldWnd: THandle; aNewWnd: THandle; var aProc: TFNWndProc); +begin + if (aOldWnd <> 0) and (aOldWnd <> aNewWnd) and (aProc <> nil) then + begin + SetWindowLongPtr(aOldWnd, GWLP_WNDPROC, NativeInt(aProc)); + aProc := nil; + aOldWnd := 0; + end; +end; + +procedure TWVBrowserBase.CallOldCompWndProc(aProc: TFNWndProc; aWnd: THandle; var aMessage: TMessage); +begin + if (aProc <> nil) and (aWnd <> 0) then + aMessage.Result := CallWindowProc(aProc, aWnd, aMessage.Msg, aMessage.wParam, aMessage.lParam); +end; + +{$ELSE} + +procedure TWVBrowserBase.CreateStub(const aMethod : TWndMethod; var aStub : Pointer); +begin + if (aStub = nil) then + begin + GetMem(aStub, SizeOf(TWndMethod)); + TWndMethod(aStub^) := aMethod; + end; +end; + +procedure TWVBrowserBase.FreeAndNilStub(var aStub : pointer); +begin + if (aStub <> nil) then + begin + FreeMem(aStub); + aStub := nil; + end; +end; + +function CompSubClassProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM; + uIdSubclass: UINT_PTR; dwRefData: DWORD_PTR): LRESULT; stdcall; +var + m: TWndMethod; + Msg: TMessage; +begin + Msg.msg := uMsg; + Msg.wParam := wparam; + Msg.lParam := lParam; + Msg.Result := 0; + + m := TWndMethod(Pointer(dwRefData)^); + m(Msg); + Result := Msg.Result; +end; + +function TWVBrowserBase.InstallCompWndProc(aWnd: THandle; aStub: Pointer): TFNWndProc; +begin + Result := nil; + if (aWnd <> 0) and (aStub <> nil) then + begin + SetWindowSubclass(aWnd, @CompSubClassProc, 1, NativeInt(aStub)); + Result := TFNWndProc(1); // IdSubClass + end; +end; + +procedure TWVBrowserBase.RestoreCompWndProc(var aOldWnd: THandle; aNewWnd: THandle; var aProc: TFNWndProc); +begin + if (aOldWnd <> 0) and (aOldWnd <> aNewWnd) and (aProc <> nil) then + begin + RemoveWindowSubclass(aOldWnd, @CompSubClassProc, 1); + aProc := nil; + aOldWnd := 0; + end; +end; + +procedure TWVBrowserBase.CallOldCompWndProc(aProc: TFNWndProc; aWnd: THandle; var aMessage: TMessage); +begin + if (aProc <> nil) and (aWnd <> 0) then + aMessage.Result := DefSubclassProc(aWnd, aMessage.Msg, aMessage.wParam, aMessage.lParam); +end; +{$ENDIF} + +procedure TWVBrowserBase.Widget0CompWndProc(var aMessage: TMessage); +var + TempHandled : boolean; +begin + try + TempHandled := False; + + try + if assigned(FOnWidget0CompMsg) then + FOnWidget0CompMsg(self, aMessage, TempHandled); + + if not(TempHandled) then + CallOldCompWndProc(FOldWidget0CompWndPrc, FWidget0CompHWND, aMessage); + finally + if aMessage.Msg = WM_DESTROY then + RestoreCompWndProc(FWidget0CompHWND, 0, FOldWidget0CompWndPrc); + end; + except + on e : exception do + if CustomExceptionHandler('TWVBrowserBase.Widget0CompWndProc', e) then raise; + end; +end; + +procedure TWVBrowserBase.Widget1CompWndProc(var aMessage: TMessage); +var + TempHandled : boolean; +begin + try + TempHandled := False; + + try + if assigned(FOnWidget1CompMsg) then + FOnWidget1CompMsg(self, aMessage, TempHandled); + + if not(TempHandled) then + CallOldCompWndProc(FOldWidget1CompWndPrc, FWidget1CompHWND, aMessage); + finally + if aMessage.Msg = WM_DESTROY then + RestoreCompWndProc(FWidget1CompHWND, 0, FOldWidget1CompWndPrc); + end; + except + on e : exception do + if CustomExceptionHandler('TWVBrowserBase.Widget1CompWndProc', e) then raise; + end; +end; + +procedure TWVBrowserBase.RenderCompWndProc(var aMessage: TMessage); +var + TempHandled : boolean; +begin + try + TempHandled := False; + + try + if assigned(FOnRenderCompMsg) then + FOnRenderCompMsg(self, aMessage, TempHandled); + + if not(TempHandled) then + CallOldCompWndProc(FOldRenderCompWndPrc, FRenderCompHWND, aMessage); + finally + if aMessage.Msg = WM_DESTROY then + RestoreCompWndProc(FRenderCompHWND, 0, FOldRenderCompWndPrc); + end; + except + on e : exception do + if CustomExceptionHandler('TWVBrowserBase.RenderCompWndProc', e) then raise; + end; +end; + +procedure TWVBrowserBase.D3DWindowCompWndProc(var aMessage: TMessage); +var + TempHandled : boolean; +begin + try + TempHandled := False; + + try + if assigned(FOnD3DWindowCompMsg) then + FOnD3DWindowCompMsg(self, aMessage, TempHandled); + + if not(TempHandled) then + CallOldCompWndProc(FOldD3DWindowCompWndPrc, FD3DWindowCompHWND, aMessage); + finally + if aMessage.Msg = WM_DESTROY then + RestoreCompWndProc(FD3DWindowCompHWND, 0, FOldD3DWindowCompWndPrc); + end; + except + on e : exception do + if CustomExceptionHandler('TWVBrowserBase.D3DWindowCompWndProc', e) then raise; + end; +end; + +procedure TWVBrowserBase.RestoreOldCompWndProc; +begin + RestoreCompWndProc(FWidget0CompHWND, 0, FOldWidget0CompWndPrc); + FreeAndNilStub(FWidget0CompStub); + + RestoreCompWndProc(FWidget1CompHWND, 0, FOldWidget1CompWndPrc); + FreeAndNilStub(FWidget1CompStub); + + RestoreCompWndProc(FRenderCompHWND, 0, FOldRenderCompWndPrc); + FreeAndNilStub(FRenderCompStub); + + RestoreCompWndProc(FD3DWindowCompHWND, 0, FOldD3DWindowCompWndPrc); + FreeAndNilStub(FD3DWindowCompStub); +end; + +function TWVBrowserBase.AddWebResourceRequestedFilter(const aURI: wvstring; aResourceContext: TWVWebResourceContext) : boolean; +begin + Result := Initialized and + FCoreWebView2.AddWebResourceRequestedFilter(aURI, aResourceContext); +end; + +function TWVBrowserBase.RemoveWebResourceRequestedFilter(const aURI: wvstring; aResourceContext: TWVWebResourceContext) : boolean; +begin + Result := Initialized and + FCoreWebView2.RemoveWebResourceRequestedFilter(aURI, aResourceContext); +end; + +function TWVBrowserBase.AddWebResourceRequestedFilterWithRequestSourceKinds(const uri : wvstring; + ResourceContext : TWVWebResourceContext; + requestSourceKinds : TWVWebResourceRequestSourceKind): boolean; +begin + Result := Initialized and + FCoreWebView2.AddWebResourceRequestedFilterWithRequestSourceKinds(uri, ResourceContext, requestSourceKinds); +end; + +function TWVBrowserBase.RemoveWebResourceRequestedFilterWithRequestSourceKinds(const uri : wvstring; + ResourceContext : TWVWebResourceContext; + requestSourceKinds : TWVWebResourceRequestSourceKind): boolean; +begin + Result := Initialized and + FCoreWebView2.RemoveWebResourceRequestedFilterWithRequestSourceKinds(uri, ResourceContext, requestSourceKinds); +end; + +function TWVBrowserBase.PostWebMessageAsJsonWithAdditionalObjects(const webMessageAsJson: wvstring; + const additionalObjects: ICoreWebView2ObjectCollectionView): boolean; +begin + Result := Initialized and + FCoreWebView2.PostWebMessageAsJsonWithAdditionalObjects(webMessageAsJson, additionalObjects); +end; + +function TWVBrowserBase.CapturePreview(aImageFormat: TWVCapturePreviewImageFormat; const aImageStream: IStream) : boolean; +begin + Result := Initialized and + FCoreWebView2.CapturePreview(aImageFormat, aImageStream, self); +end; + +function TWVBrowserBase.EnvironmentCompletedHandler_Invoke(errorCode: HRESULT; const result_: ICoreWebView2Environment): HRESULT; +var + TempError : wvstring; +begin + Result := S_OK; + + if succeeded(errorCode) and assigned(result_) then + begin + DestroyEnvironment; + FCoreWebView2Environment := TCoreWebView2Environment.Create(result_); + + doOnEnvironmentCompleted; + + if FUseCompositionController then + CreateCompositionController + else + CreateController; + end + else + begin + TempError := 'There was an error creating the browser environment. (3)' + CRLF + + 'Error code : 0x' + + {$IFDEF FPC} + UTF8Decode(inttohex(errorCode, 8)) + {$ELSE} + inttohex(errorCode, 8) + {$ENDIF} + + CRLF + EnvironmentCreationErrorToString(errorCode); + + doOnInitializationError(errorCode, TempError); + end; +end; + +function TWVBrowserBase.ControllerCompletedHandler_Invoke(errorCode: HRESULT; const result_: ICoreWebView2Controller): HRESULT; +var + TempSettings : ICoreWebView2Settings; + TempPrintSettings : ICoreWebView2PrintSettings; + TempCoreWebView2 : ICoreWebView2; + TempFindOptions : ICoreWebView2FindOptions; + TempError : wvstring; +begin + Result := S_OK; + TempSettings := nil; + TempCoreWebView2 := nil; + TempPrintSettings := nil; + TempFindOptions := nil; + + try + if succeeded(errorCode) and assigned(result_) then + begin + DestroyController; + FCoreWebView2Controller := TCoreWebView2Controller.Create(result_); + + doOnControllerCompleted; + + TempCoreWebView2 := FCoreWebView2Controller.CoreWebView2; + + if assigned(TempCoreWebView2) then + begin + DestroyWebView; + FCoreWebView2 := TCoreWebView2.Create(TempCoreWebView2); + TempSettings := FCoreWebView2.Settings; + + if assigned(TempSettings) then + begin + DestroyProfile; + FCoreWebView2Profile := TCoreWebView2Profile.Create(FCoreWebView2.Profile); + FCoreWebView2Profile.AddAllBrowserEvents(self); + + DestroySettings; + FCoreWebView2Settings := TCoreWebView2Settings.Create(TempSettings); + + if FCoreWebView2Environment.CreatePrintSettings(TempPrintSettings) then + begin + DestroyPrintSettings; + FCoreWebView2PrintSettings := TCoreWebView2PrintSettings.Create(TempPrintSettings); + end; + + if not(FUseDefaultEnvironment) then + FCoreWebView2Environment.AddAllBrowserEvents(self); + + FCoreWebView2.AddAllBrowserEvents(self); + FCoreWebView2Controller.AddAllBrowserEvents(self); + + if assigned(FCoreWebView2CompositionController) then + FCoreWebView2CompositionController.AddAllBrowserEvents(self); + + if FCoreWebView2Environment.CreateFindOptions(TempFindOptions) then + begin + DestroyFindOptions; + FCoreWebView2FindOptions := TCoreWebView2FindOptions.Create(TempFindOptions); + end; + + doOnAfterCreated; + + if (Length(FDefaultURL) > 0) then + Navigate(FDefaultURL); + end + else + doOnInitializationError(E_FAIL, 'There was an error getting the browser settings.'); + end + else + doOnInitializationError(E_FAIL, 'There was an error getting the browser webview.'); + end + else + begin + TempError := 'There was an error creating the controller. (2)' + CRLF + + 'Error code : 0x' + + {$IFDEF FPC} + UTF8Decode(inttohex(errorCode, 8)) + {$ELSE} + inttohex(errorCode, 8) + {$ENDIF} + + CRLF + ControllerCreationErrorToString(errorCode); + + doOnInitializationError(errorCode, TempError); + end; + finally + TempSettings := nil; + TempCoreWebView2 := nil; + TempPrintSettings := nil; + end; +end; + +procedure TWVBrowserBase.ReplaceWndProcs; +var + OldWidget0CompHWND, OldWidget1CompHWND, OldRenderCompHWND, OldD3DWindowCompHWND: THandle; + NewWidget0CompHWND, NewWidget1CompHWND, NewRenderCompHWND, NewD3DWindowCompHWND: THandle; +begin + if (FWindowParentHandle <> 0) then + begin + NewWidget0CompHWND := FindWindowEx(FWindowParentHandle, 0, 'Chrome_WidgetWin_0', ''); + + if (FWidget0CompHWND <> NewWidget0CompHWND) then + begin + OldWidget0CompHWND := FWidget0CompHWND; + FWidget0CompHWND := NewWidget0CompHWND; + RestoreCompWndProc(OldWidget0CompHWND, FWidget0CompHWND, FOldWidget0CompWndPrc); + + if assigned(FOnWidget0CompMsg) and (FWidget0CompHWND <> 0) and (FOldWidget0CompWndPrc = nil) then + begin + CreateStub(Widget0CompWndProc, FWidget0CompStub); + FOldWidget0CompWndPrc := InstallCompWndProc(FWidget0CompHWND, FWidget0CompStub); + end; + end; + end; + + + if (FWidget0CompHWND <> 0) then + begin + NewWidget1CompHWND := FindWindowEx(FWidget0CompHWND, 0, 'Chrome_WidgetWin_1', nil); + + if (FWidget1CompHWND <> NewWidget1CompHWND) then + begin + OldWidget1CompHWND := FWidget1CompHWND; + FWidget1CompHWND := NewWidget1CompHWND; + RestoreCompWndProc(OldWidget1CompHWND, FWidget1CompHWND, FOldWidget1CompWndPrc); + + if assigned(FOnWidget1CompMsg) and (FWidget1CompHWND <> 0) and (FOldWidget1CompWndPrc = nil) then + begin + CreateStub(Widget1CompWndProc, FWidget1CompStub); + FOldWidget1CompWndPrc := InstallCompWndProc(FWidget1CompHWND, FWidget1CompStub); + end; + end; + end; + + + if (FWidget1CompHWND <> 0) then + begin + NewRenderCompHWND := FindWindowEx(FWidget1CompHWND, 0, 'Chrome_RenderWidgetHostHWND', 'Chrome Legacy Window'); + + if (FRenderCompHWND <> NewRenderCompHWND) then + begin + OldRenderCompHWND := FRenderCompHWND; + FRenderCompHWND := NewRenderCompHWND; + RestoreCompWndProc(OldRenderCompHWND, FRenderCompHWND, FOldRenderCompWndPrc); + + if assigned(FOnRenderCompMsg) and (FRenderCompHWND <> 0) and (FOldRenderCompWndPrc = nil) then + begin + CreateStub(RenderCompWndProc, FRenderCompStub); + FOldRenderCompWndPrc := InstallCompWndProc(FRenderCompHWND, FRenderCompStub); + end; + end; + + + NewD3DWindowCompHWND := FindWindowEx(FWidget1CompHWND, 0, 'Intermediate D3D Window', nil); + + if (FD3DWindowCompHWND <> NewD3DWindowCompHWND) then + begin + OldD3DWindowCompHWND := FD3DWindowCompHWND; + FD3DWindowCompHWND := NewD3DWindowCompHWND; + RestoreCompWndProc(OldD3DWindowCompHWND, FD3DWindowCompHWND, FOldD3DWindowCompWndPrc); + + if assigned(FOnD3DWindowCompMsg) and (FD3DWindowCompHWND <> 0) and (FOldD3DWindowCompWndPrc = nil) then + begin + CreateStub(D3DWindowCompWndProc, FD3DWindowCompStub); + FOldD3DWindowCompWndPrc := InstallCompWndProc(FD3DWindowCompHWND, FD3DWindowCompStub); + end; + end; + end; +end; + +function TWVBrowserBase.NavigationStartingEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NavigationStartingEventArgs): HRESULT; +begin + Result := S_OK; + FIsNavigating := True; + + ReplaceWndProcs; + + doOnNavigationStarting(sender, args); +end; + +function TWVBrowserBase.NavigationCompletedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NavigationCompletedEventArgs): HRESULT; +begin + Result := S_OK; + FIsNavigating := False; + + doOnNavigationCompleted(sender, args); +end; + +function TWVBrowserBase.SourceChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2SourceChangedEventArgs): HRESULT; +begin + Result := S_OK; + doOnSourceChanged(sender, args); +end; + +function TWVBrowserBase.HistoryChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HRESULT; +begin + Result := S_OK; + doOnHistoryChanged(sender); +end; + +function TWVBrowserBase.ContentLoadingEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ContentLoadingEventArgs): HRESULT; +begin + Result := S_OK; + doOnContentLoading(sender, args); +end; + +function TWVBrowserBase.DocumentTitleChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HRESULT; +begin + Result := S_OK; + doOnDocumentTitleChanged(sender); +end; + +function TWVBrowserBase.NewWindowRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NewWindowRequestedEventArgs): HRESULT; +begin + Result := S_OK; + doOnNewWindowRequested(sender, args); +end; + +function TWVBrowserBase.FrameNavigationStartingEventHandler_Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2NavigationStartingEventArgs): HRESULT; +begin + Result := S_OK; + doOnFrameNavigationStarting(sender, args); +end; + +function TWVBrowserBase.FrameNavigationCompletedEventHandler_Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2NavigationCompletedEventArgs): HRESULT; +begin + Result := S_OK; + doOnFrameNavigationCompleted(sender, args); +end; + +function TWVBrowserBase.WebResourceRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2WebResourceRequestedEventArgs): HRESULT; +begin + Result := S_OK; + doOnWebResourceRequested(sender, args); +end; + +function TWVBrowserBase.ScriptDialogOpeningEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ScriptDialogOpeningEventArgs): HRESULT; +begin + Result := S_OK; + doOnScriptDialogOpening(sender, args); +end; + +function TWVBrowserBase.PermissionRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2PermissionRequestedEventArgs): HRESULT; +begin + Result := S_OK; + doOnPermissionRequested(sender, args); +end; + +function TWVBrowserBase.ProcessFailedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ProcessFailedEventArgs): HRESULT; +begin + Result := S_OK; + doOnProcessFailed(sender, args); +end; + +function TWVBrowserBase.WebMessageReceivedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2WebMessageReceivedEventArgs): HRESULT; +begin + Result := S_OK; + doOnWebMessageReceived(sender, args); +end; + +function TWVBrowserBase.ContainsFullScreenElementChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HRESULT; +begin + Result := S_OK; + doOnContainsFullScreenElementChanged(sender); +end; + +function TWVBrowserBase.WindowCloseRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HRESULT; +begin + Result := S_OK; + doOnWindowCloseRequested(sender); +end; + +function TWVBrowserBase.ZoomFactorChangedEventHandler_Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HRESULT; +begin + Result := S_OK; + CalculateZoomStep; + doOnZoomFactorChanged(sender); +end; + +function TWVBrowserBase.MoveFocusRequestedEventHandler_Invoke(const sender: ICoreWebView2Controller; const args: ICoreWebView2MoveFocusRequestedEventArgs): HRESULT; +begin + Result := S_OK; + doOnMoveFocusRequested(sender, args); +end; + +function TWVBrowserBase.AcceleratorKeyPressedEventHandler_Invoke(const sender: ICoreWebView2Controller; const args: ICoreWebView2AcceleratorKeyPressedEventArgs): HRESULT; +begin + Result := S_OK; + doOnAcceleratorKeyPressed(sender, args); +end; + +function TWVBrowserBase.GotFocusEventHandler_Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HRESULT; +begin + Result := S_OK; + doOnGotFocus(sender); +end; + +function TWVBrowserBase.LostFocusEventHandler_Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HRESULT; +begin + Result := S_OK; + doOnLostFocus(sender); +end; + +function TWVBrowserBase.CreateCoreWebView2CompositionControllerCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2CompositionController): HRESULT; +var + TempControllerIntf : ICoreWebView2Controller; + TempError : wvstring; + TempHResult : HRESULT; +begin + Result := S_OK; + + if succeeded(errorCode) and assigned(result_) then + begin + DestroyCompositionController; + FCoreWebView2CompositionController := TCoreWebView2CompositionController.Create(result_); + + doOnCompositionControllerCompleted; + + TempHResult := result_.QueryInterface(IID_ICoreWebView2Controller, TempControllerIntf); + + if succeeded(TempHResult) then + Result := ControllerCompletedHandler_Invoke(errorCode, TempControllerIntf) + else + doOnInitializationError(TempHResult, 'There was an error creating the controller. (3)'); + end + else + begin + TempError := 'There was an error creating the composition controller. (2)' + CRLF + + 'Error code : 0x' + + {$IFDEF FPC} + UTF8Decode(inttohex(errorCode, 8)) + {$ELSE} + inttohex(errorCode, 8) + {$ENDIF} + + CRLF + CompositionControllerCreationErrorToString(errorCode); + + doOnInitializationError(errorCode, TempError); + end; +end; + +function TWVBrowserBase.CursorChangedEventHandler_Invoke(const sender: ICoreWebView2CompositionController; const args: IUnknown): HRESULT; +begin + Result := S_OK; + doOnCursorChangedEvent(sender); +end; + +function TWVBrowserBase.BrowserProcessExitedEventHandler_Invoke(const sender : ICoreWebView2Environment; + const args : ICoreWebView2BrowserProcessExitedEventArgs): HRESULT; +begin + Result := S_OK; + doOnBrowserProcessExitedEvent(sender, args); +end; + +function TWVBrowserBase.RasterizationScaleChangedEventHandler_Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HRESULT; +begin + Result := S_OK; + doOnRasterizationScaleChangedEvent(sender); +end; + +function TWVBrowserBase.WebResourceResponseReceivedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2WebResourceResponseReceivedEventArgs): HRESULT; +begin + Result := S_OK; + doOnWebResourceResponseReceivedEvent(sender, args); +end; + +function TWVBrowserBase.DOMContentLoadedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DOMContentLoadedEventArgs): HRESULT; +begin + Result := S_OK; + doOnDOMContentLoadedEvent(sender, args); +end; + +function TWVBrowserBase.WebResourceResponseViewGetContentCompletedHandler_Invoke(errorCode: HResult; const result_: IStream; aResourceID : integer): HRESULT; +begin + Result := S_OK; + doOnWebResourceResponseViewGetContentCompletedEvent(errorCode, result_, aResourceID); +end; + +function TWVBrowserBase.GetCookiesCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2CookieList): HRESULT; +begin + Result := S_OK; + doOnGetCookiesCompletedEvent(errorCode, result_); +end; + +function TWVBrowserBase.TrySuspendCompletedHandler_Invoke(errorCode: HResult; result_: Integer): HRESULT; +begin + Result := S_OK; + doOnTrySuspendCompletedEvent(errorCode, result_); +end; + +function TWVBrowserBase.FrameCreatedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2FrameCreatedEventArgs): HRESULT; +begin + Result := S_OK; + doOnFrameCreatedEvent(sender, args); +end; + +function TWVBrowserBase.DownloadStartingEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DownloadStartingEventArgs): HRESULT; +begin + Result := S_OK; + doOnDownloadStartingEvent(sender, args); +end; + +function TWVBrowserBase.ClientCertificateRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ClientCertificateRequestedEventArgs): HRESULT; +begin + Result := S_OK; + doOnClientCertificateRequestedEvent(sender, args); +end; + +function TWVBrowserBase.PrintToPdfCompletedHandler_Invoke(errorCode: HResult; result_: Integer): HRESULT; +begin + Result := S_OK; + doOnPrintToPdfCompletedEvent(errorCode, result_); +end; + +function TWVBrowserBase.BytesReceivedChangedEventHandler_Invoke(const sender: ICoreWebView2DownloadOperation; const args: IUnknown; aDownloadID : integer): HRESULT; +begin + Result := S_OK; + doOnBytesReceivedChangedEventEvent(sender, args, aDownloadID); +end; + +function TWVBrowserBase.EstimatedEndTimeChangedEventHandler_Invoke(const sender: ICoreWebView2DownloadOperation; const args: IUnknown; aDownloadID : integer): HRESULT; +begin + Result := S_OK; + doOnEstimatedEndTimeChangedEvent(sender, args, aDownloadID); +end; + +function TWVBrowserBase.StateChangedEventHandler_Invoke(const sender: ICoreWebView2DownloadOperation; const args: IUnknown; aDownloadID : integer): HRESULT; +begin + Result := S_OK; + doOnStateChangedEvent(sender, args, aDownloadID); +end; + +function TWVBrowserBase.FrameNameChangedEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: IUnknown; aFrameID : cardinal): HRESULT; +begin + Result := S_OK; + doOnFrameNameChangedEvent(sender, args, aFrameID); +end; + +function TWVBrowserBase.FrameDestroyedEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: IUnknown; aFrameID : cardinal): HRESULT; +begin + Result := S_OK; + doOnFrameDestroyedEvent(sender, args, aFrameID); +end; + +function TWVBrowserBase.CallDevToolsProtocolMethodCompletedHandler_Invoke(errorCode: HResult; result_: PWideChar; aExecutionID : integer): HRESULT; +begin + Result := S_OK; + + case aExecutionID of + WEBVIEW4DELPHI_DEVTOOLS_RETRIEVEMHTML_ID : + doOnRetrieveMHTMLCompleted(errorCode, wvstring(result_)); + + WEBVIEW4DELPHI_DEVTOOLS_CLEARBROWSERCACHE_ID : + doOnClearCacheCompleted(errorCode); + + WEBVIEW4DELPHI_DEVTOOLS_CLEARDATAFORORIGIN_ID : + doOnClearDataForOriginCompleted(errorCode); + + WEBVIEW4DELPHI_DEVTOOLS_EMULATENETWORKCONDITIONS_ID : + doOnOfflineCompleted(errorCode); + + WEBVIEW4DELPHI_DEVTOOLS_SETIGNORECERTIFICATEERRORS_ID : + doOnIgnoreCertificateErrorsCompleted(errorCode); + + WEBVIEW4DELPHI_DEVTOOLS_SIMULATEKEYEVENT_ID : + doOnSimulateKeyEventCompleted(errorCode); + + WEBVIEW4DELPHI_DEVTOOLS_REFRESH_ID : + doOnRefreshIgnoreCacheCompleted(errorCode, wvstring(result_)); + + else + doOnCallDevToolsProtocolMethodCompletedEvent(errorCode, wvstring(result_), aExecutionID); + end; +end; + +procedure TWVBrowserBase.doOnClearCacheCompleted(aErrorCode: HRESULT); +begin + if assigned(FOnClearCacheCompleted) then + FOnClearCacheCompleted(self, succeeded(aErrorCode)); +end; + +procedure TWVBrowserBase.doOnClearDataForOriginCompleted(aErrorCode: HRESULT); +begin + if assigned(FOnClearDataForOriginCompleted) then + FOnClearDataForOriginCompleted(self, succeeded(aErrorCode)); +end; + +procedure TWVBrowserBase.doOnOfflineCompleted(aErrorCode: HRESULT); +begin + if assigned(FOnOfflineCompleted) then + FOnOfflineCompleted(self, succeeded(aErrorCode)); +end; + +procedure TWVBrowserBase.doOnIgnoreCertificateErrorsCompleted(aErrorCode: HRESULT); +begin + if assigned(FOnIgnoreCertificateErrorsCompleted) then + FOnIgnoreCertificateErrorsCompleted(self, succeeded(aErrorCode)); +end; + +procedure TWVBrowserBase.doOnSimulateKeyEventCompleted(aErrorCode: HRESULT); +begin + if assigned(FOnSimulateKeyEventCompleted) then + FOnSimulateKeyEventCompleted(self, succeeded(aErrorCode)); +end; + +procedure TWVBrowserBase.doOnIsMutedChanged(const sender: ICoreWebView2); +begin + if assigned(FOnIsMutedChanged) then + FOnIsMutedChanged(self, sender); +end; + +procedure TWVBrowserBase.doOnIsDocumentPlayingAudioChanged(const sender: ICoreWebView2); +begin + if assigned(FOnIsDocumentPlayingAudioChanged) then + FOnIsDocumentPlayingAudioChanged(self, sender); +end; + +procedure TWVBrowserBase.doOnIsDefaultDownloadDialogOpenChanged(const sender: ICoreWebView2); +begin + if assigned(FOnIsDefaultDownloadDialogOpenChanged) then + FOnIsDefaultDownloadDialogOpenChanged(self, sender); +end; + +procedure TWVBrowserBase.doOnProcessInfosChangedEvent(const sender: ICoreWebView2Environment); +begin + if assigned(FOnProcessInfosChanged) then + FOnProcessInfosChanged(self, sender); +end; + +procedure TWVBrowserBase.doOnFrameNavigationStarting2(const sender : ICoreWebView2Frame; + const args : ICoreWebView2NavigationStartingEventArgs; + aFrameID : cardinal); +begin + if assigned(FOnFrameNavigationStarting2) then + FOnFrameNavigationStarting2(self, sender, args, aFrameID); +end; + +procedure TWVBrowserBase.doOnFrameNavigationCompleted2(const sender : ICoreWebView2Frame; + const args : ICoreWebView2NavigationCompletedEventArgs; + aFrameID : cardinal); +begin + if assigned(FOnFrameNavigationCompleted2) then + FOnFrameNavigationCompleted2(self, sender, args, aFrameID); +end; + +procedure TWVBrowserBase.doOnFrameContentLoadingEvent(const sender : ICoreWebView2Frame; + const args : ICoreWebView2ContentLoadingEventArgs; + aFrameID : cardinal); +begin + if assigned(FOnFrameContentLoading) then + FOnFrameContentLoading(self, sender, args, aFrameID); +end; + +procedure TWVBrowserBase.doOnFrameDOMContentLoadedEvent(const sender : ICoreWebView2Frame; + const args : ICoreWebView2DOMContentLoadedEventArgs; + aFrameID : cardinal); +begin + if assigned(FOnFrameDOMContentLoaded) then + FOnFrameDOMContentLoaded(self, sender, args, aFrameID); +end; + +procedure TWVBrowserBase.doOnFrameWebMessageReceivedEvent(const sender : ICoreWebView2Frame; + const args : ICoreWebView2WebMessageReceivedEventArgs; + aFrameID : cardinal); +begin + if assigned(FOnFrameWebMessageReceived) then + FOnFrameWebMessageReceived(self, sender, args, aFrameID); +end; + +procedure TWVBrowserBase.doOnBasicAuthenticationRequestedEvent(const sender : ICoreWebView2; + const args : ICoreWebView2BasicAuthenticationRequestedEventArgs); +begin + if assigned(FOnBasicAuthenticationRequested) then + FOnBasicAuthenticationRequested(self, sender, args); +end; + +procedure TWVBrowserBase.doOnContextMenuRequestedEvent(const sender : ICoreWebView2; + const args : ICoreWebView2ContextMenuRequestedEventArgs); +begin + if assigned(FOnContextMenuRequested) then + FOnContextMenuRequested(self, sender, args); +end; + +procedure TWVBrowserBase.doOnCustomItemSelectedEvent(const sender : ICoreWebView2ContextMenuItem; + const args : IUnknown); +begin + if assigned(FOnCustomItemSelected) then + FOnCustomItemSelected(self, sender); +end; + +procedure TWVBrowserBase.doOnStatusBarTextChangedEvent(const sender : ICoreWebView2; + const args : IUnknown); +begin + if assigned(FOnStatusBarTextChanged) then + FOnStatusBarTextChanged(self, sender); +end; + +procedure TWVBrowserBase.doOnFramePermissionRequestedEvent(const sender : ICoreWebView2Frame; + const args : ICoreWebView2PermissionRequestedEventArgs2; + aFrameID : cardinal); +begin + if assigned(FOnFramePermissionRequested) then + FOnFramePermissionRequested(self, sender, args, aFrameID); +end; + +procedure TWVBrowserBase.doOnClearBrowsingDataCompletedEvent(aErrorCode: HRESULT); +begin + if assigned(FOnClearBrowsingDataCompleted) then + FOnClearBrowsingDataCompleted(self, aErrorCode); +end; + +procedure TWVBrowserBase.doOnServerCertificateErrorActionsCompletedEvent(aErrorCode: HRESULT); +begin + if assigned(FOnServerCertificateErrorActionsCompleted) then + FOnServerCertificateErrorActionsCompleted(self, aErrorCode); +end; + +procedure TWVBrowserBase.doOnServerCertificateErrorDetectedEvent(const sender : ICoreWebView2; + const args : ICoreWebView2ServerCertificateErrorDetectedEventArgs); +begin + if assigned(FOnServerCertificateErrorDetected) then + FOnServerCertificateErrorDetected(self, sender, args); +end; + +procedure TWVBrowserBase.doOnFaviconChangedEvent(const sender : ICoreWebView2; + const args : IUnknown); +begin + if assigned(FOnFaviconChanged) then + FOnFaviconChanged(self, sender, args); +end; + +procedure TWVBrowserBase.doOnGetFaviconCompletedEvent( errorCode : HResult; + const result_ : IStream); +begin + if assigned(FOnGetFaviconCompleted) then + FOnGetFaviconCompleted(self, errorCode, result_); +end; + +procedure TWVBrowserBase.doOnPrintCompletedEvent(errorCode : HResult; + result_ : COREWEBVIEW2_PRINT_STATUS); +begin + if assigned(FOnPrintCompleted) then + FOnPrintCompleted(self, errorCode, result_); +end; + +procedure TWVBrowserBase.doOnPrintToPdfStreamCompletedEvent( errorCode : HResult; + const result_ : IStream); +begin + if assigned(FOnPrintToPdfStreamCompleted) then + FOnPrintToPdfStreamCompleted(self, errorCode, result_); +end; + +procedure TWVBrowserBase.doOnGetCustomSchemes(var aSchemeRegistrations : TWVCustomSchemeRegistrationArray); +var + TempArray : TWVCustomSchemeInfoArray; + i, TempLen : integer; +begin + if not(assigned(FOnGetCustomSchemes)) then exit; + + TempArray := nil; + FOnGetCustomSchemes(self, TempArray); + TempLen := length(TempArray); + + if (TempLen = 0) then exit; + + SetLength(aSchemeRegistrations, TempLen); + ZeroMemory(aSchemeRegistrations, TempLen * SizeOf(ICoreWebView2CustomSchemeRegistration)); + + i := 0; + while (i < TempLen) do + begin + aSchemeRegistrations[i] := TCoreWebView2CustomSchemeRegistration.Create(TempArray[i]); + inc(i); + end; +end; + +procedure TWVBrowserBase.doOnGetNonDefaultPermissionSettingsCompleted( errorCode : HResult; + const result_ : ICoreWebView2PermissionSettingCollectionView); +begin + if assigned(FOnGetNonDefaultPermissionSettingsCompleted) then + FOnGetNonDefaultPermissionSettingsCompleted(self, errorCode, result_); +end; + +procedure TWVBrowserBase.doOnSetPermissionStateCompleted(errorCode: HResult); +begin + if assigned(FOnSetPermissionStateCompleted) then + FOnSetPermissionStateCompleted(self, errorCode); +end; + +procedure TWVBrowserBase.doOnLaunchingExternalUriSchemeEvent(const sender : ICoreWebView2; + const args : ICoreWebView2LaunchingExternalUriSchemeEventArgs); +begin + if assigned(FOnLaunchingExternalUriScheme) then + FOnLaunchingExternalUriScheme(self, sender, args); +end; + +procedure TWVBrowserBase.doOnGetProcessExtendedInfosCompletedEvent( errorCode : HResult; + const result_ : ICoreWebView2ProcessExtendedInfoCollection); +begin + if assigned(FOnGetProcessExtendedInfosCompleted) then + FOnGetProcessExtendedInfosCompleted(self, errorCode, result_); +end; + +procedure TWVBrowserBase.doOnBrowserExtensionRemoveCompletedEvent( errorCode : HResult; + const aExtensionID : wvstring); +begin + if assigned(FOnBrowserExtensionRemoveCompleted) then + FOnBrowserExtensionRemoveCompleted(self, errorCode, aExtensionID); +end; + +procedure TWVBrowserBase.doOnBrowserExtensionEnableCompletedEvent( errorCode : HResult; + const aExtensionID : wvstring); +begin + if assigned(FOnBrowserExtensionEnableCompleted) then + FOnBrowserExtensionEnableCompleted(self, errorCode, aExtensionID); +end; + +procedure TWVBrowserBase.doOnProfileAddBrowserExtensionCompletedEvent( errorCode : HResult; + const result_ : ICoreWebView2BrowserExtension); +begin + if assigned(FOnProfileAddBrowserExtensionCompleted) then + FOnProfileAddBrowserExtensionCompleted(self, errorCode, result_); +end; + +procedure TWVBrowserBase.doOnProfileGetBrowserExtensionsCompletedEvent( errorCode : HResult; + const result_ : ICoreWebView2BrowserExtensionList); +begin + if assigned(FOnProfileGetBrowserExtensionsCompleted) then + FOnProfileGetBrowserExtensionsCompleted(self, errorCode, result_); +end; + +procedure TWVBrowserBase.doOnProfileDeletedEvent(const sender : ICoreWebView2Profile; + const args : IUnknown); +begin + if assigned(FOnProfileDeleted) then + FOnProfileDeleted(self, sender); +end; + +procedure TWVBrowserBase.doOnExecuteScriptWithResultCompletedEvent( errorCode : HResult; + const result_ : ICoreWebView2ExecuteScriptResult; + aExecutionID : integer); +begin + if assigned(FOnExecuteScriptWithResultCompleted) then + FOnExecuteScriptWithResultCompleted(self, errorCode, result_, aExecutionID); +end; + +procedure TWVBrowserBase.doOnNonClientRegionChangedEvent(const sender : ICoreWebView2CompositionController; + const args : ICoreWebView2NonClientRegionChangedEventArgs); +begin + if assigned(FOnNonClientRegionChanged) then + FOnNonClientRegionChanged(self, sender, args); +end; + +procedure TWVBrowserBase.doOnNotificationReceivedEvent(const sender : ICoreWebView2; + const args : ICoreWebView2NotificationReceivedEventArgs); +begin + if assigned(FOnNotificationReceived) then + FOnNotificationReceived(self, sender, args); +end; + +procedure TWVBrowserBase.doOnNotificationCloseRequestedEvent(const sender : ICoreWebView2Notification; + const args : IUnknown); +begin + if assigned(FOnNotificationCloseRequested) then + FOnNotificationCloseRequested(self, sender, args); +end; + +procedure TWVBrowserBase.doOnSaveAsUIShowingEvent(const sender : ICoreWebView2; + const args : ICoreWebView2SaveAsUIShowingEventArgs); +begin + if assigned(FOnSaveAsUIShowing) then + FOnSaveAsUIShowing(self, sender, args); +end; + +procedure TWVBrowserBase.doOnShowSaveAsUICompletedEvent(errorCode : HResult; + result_ : COREWEBVIEW2_SAVE_AS_UI_RESULT); +begin + if assigned(FOnShowSaveAsUICompleted) then + FOnShowSaveAsUICompleted(self, errorCode, result_); +end; + +procedure TWVBrowserBase.doOnSaveFileSecurityCheckStartingEvent(const sender : ICoreWebView2; + const args : ICoreWebView2SaveFileSecurityCheckStartingEventArgs); +begin + if assigned(FOnSaveFileSecurityCheckStarting) then + FOnSaveFileSecurityCheckStarting(self, sender, args); +end; + +procedure TWVBrowserBase.doOnScreenCaptureStartingEvent(const sender : ICoreWebView2; + const args : ICoreWebView2ScreenCaptureStartingEventArgs); +begin + if assigned(FOnScreenCaptureStarting) then + FOnScreenCaptureStarting(self, sender, args); +end; + +procedure TWVBrowserBase.doOnFrameScreenCaptureStartingEvent(const sender : ICoreWebView2Frame; + const args : ICoreWebView2ScreenCaptureStartingEventArgs; + aFrameID : cardinal); +begin + if assigned(FOnFrameScreenCaptureStarting) then + FOnFrameScreenCaptureStarting(self, sender, args, aFrameID); +end; + +procedure TWVBrowserBase.doOnFrameChildFrameCreatedEvent(const sender : ICoreWebView2Frame; + const args : ICoreWebView2FrameCreatedEventArgs; + aFrameID : cardinal); +begin + if assigned(FOnFrameChildFrameCreated) then + FOnFrameChildFrameCreated(self, sender, args, aFrameID); +end; + +procedure TWVBrowserBase.doOnFindActiveMatchIndexChangedEvent(const sender : ICoreWebView2Find; + const args : IUnknown); +begin + if assigned(FOnFindActiveMatchIndexChanged) then + FOnFindActiveMatchIndexChanged(self, sender, args); +end; + +procedure TWVBrowserBase.doOnFindMatchCountChangedEvent(const sender : ICoreWebView2Find; + const args : IUnknown); +begin + if assigned(FOnFindMatchCountChanged) then + FOnFindMatchCountChanged(self, sender, args); +end; + +procedure TWVBrowserBase.doOnFindStartCompletedEvent(errorCode: HResult); +begin + if assigned(FOnFindStartCompleted) then + FOnFindStartCompleted(self, errorCode); +end; + +procedure TWVBrowserBase.doOnDragStartingEvent(const sender : ICoreWebView2CompositionController; + const args : ICoreWebView2DragStartingEventArgs); +begin + if assigned(FOnDragStarting) then + FOnDragStarting(self, sender, args); +end; + +procedure TWVBrowserBase.doOnDedicatedWorkerCreatedEvent(const sender : ICoreWebView2; + const args : ICoreWebView2DedicatedWorkerCreatedEventArgs); +begin + if assigned(FOnDedicatedWorkerCreated) then + FOnDedicatedWorkerCreated(self, sender, args); +end; + +procedure TWVBrowserBase.doOnDedicatedWorkerCreatedEvent2(const sender : ICoreWebView2DedicatedWorker; + const args : ICoreWebView2DedicatedWorkerCreatedEventArgs; + aWorkerID : cardinal); +begin + if assigned(FOnDedicatedWorkerCreated2) then + FOnDedicatedWorkerCreated2(self, sender, args, aWorkerID); +end; + +procedure TWVBrowserBase.doOnDedicatedWorkerDestroyingEvent(const sender : ICoreWebView2DedicatedWorker; + const args : IUnknown; + aWorkerID : cardinal); +begin + if assigned(FOnDedicatedWorkerDestroying) then + FOnDedicatedWorkerDestroying(self, sender, args, aWorkerID); +end; + +procedure TWVBrowserBase.doOnDedicatedWorkerWebMessageReceivedEvent(const sender : ICoreWebView2DedicatedWorker; + const args : ICoreWebView2WebMessageReceivedEventArgs; + aWorkerID : cardinal); +begin + if assigned(FOnDedicatedWorkerWebMessageReceived) then + FOnDedicatedWorkerWebMessageReceived(self, sender, args, aWorkerID); +end; + +procedure TWVBrowserBase.doOnFrameDedicatedWorkerCreatedEvent(const sender: ICoreWebView2Frame; const args: ICoreWebView2DedicatedWorkerCreatedEventArgs; aFrameID: cardinal); +begin + if assigned(FOnFrameDedicatedWorkerCreated) then + FOnFrameDedicatedWorkerCreated(self, sender, args, aFrameID); +end; + +procedure TWVBrowserBase.doOnServiceWorkerDestroyingEvent(const sender: ICoreWebView2ServiceWorker; const args: IUnknown; aWorkerID: cardinal); +begin + if assigned(FOnServiceWorkerDestroying) then + FOnServiceWorkerDestroying(self, sender, args, aWorkerID); +end; + +procedure TWVBrowserBase.doOnServiceWorkerWebMessageReceivedEvent(const sender: ICoreWebView2ServiceWorker; const args: ICoreWebView2WebMessageReceivedEventArgs; aWorkerID: cardinal); +begin + if assigned(FOnServiceWorkerWebMessageReceived) then + FOnServiceWorkerWebMessageReceived(self, sender, args, aWorkerID); +end; + +procedure TWVBrowserBase.doOnServiceWorkerRegisteredEvent(const sender: ICoreWebView2ServiceWorkerManager; const args: ICoreWebView2ServiceWorkerRegisteredEventArgs); +begin + if assigned(FOnServiceWorkerRegistered) then + FOnServiceWorkerRegistered(self, sender, args); +end; + +procedure TWVBrowserBase.doOnGetServiceWorkerRegistrationsCompletedEvent(errorCode: HResult; const result_: ICoreWebView2ServiceWorkerRegistrationCollectionView); +begin + if assigned(FOnGetServiceWorkerRegistrationsCompleted) then + FOnGetServiceWorkerRegistrationsCompleted(self, errorCode, result_); +end; + +procedure TWVBrowserBase.doOnServiceWorkerActivatedEvent(const sender: ICoreWebView2ServiceWorkerRegistration; const args: ICoreWebView2ServiceWorkerActivatedEventArgs); +begin + if assigned(FOnServiceWorkerActivated) then + FOnServiceWorkerActivated(self, sender, args); +end; + +procedure TWVBrowserBase.doOnServiceWorkerRegistrationUnregisteringEvent(const sender: ICoreWebView2ServiceWorkerRegistration; const args: IUnknown); +begin + if assigned(FOnServiceWorkerRegistrationUnregistering) then + FOnServiceWorkerRegistrationUnregistering(self, sender, args); +end; + +procedure TWVBrowserBase.doOnSharedWorkerCreatedEvent(const sender: ICoreWebView2SharedWorkerManager; const args: ICoreWebView2SharedWorkerCreatedEventArgs); +begin + if assigned(FOnSharedWorkerCreated) then + FOnSharedWorkerCreated(self, sender, args); +end; + +procedure TWVBrowserBase.doOnGetSharedWorkersCompletedEvent(errorCode: HResult; const result_: ICoreWebView2SharedWorkerCollectionView); +begin + if assigned(FOnGetSharedWorkersCompleted) then + FOnGetSharedWorkersCompleted(self, errorCode, result_); +end; + +procedure TWVBrowserBase.doOnSharedWorkerDestroyingEvent(const sender: ICoreWebView2SharedWorker; const args: IUnknown; aWorkerID: cardinal); +begin + if assigned(FOnSharedWorkerDestroying) then + FOnSharedWorkerDestroying(self, sender, args, aWorkerID); +end; + +procedure TWVBrowserBase.doOnRetrieveMHTMLCompleted( aErrorCode : HRESULT; + const aReturnObjectAsJson : wvstring); +var + TempMHTML : wvstring; + TempResult : boolean; +begin + if assigned(FOnRetrieveMHTMLCompleted) then + begin + TempMHTML := ''; + TempResult := succeeded(aErrorCode) and + ExtractJSONData(aReturnObjectAsJson, TempMHTML); + + FOnRetrieveMHTMLCompleted(self, TempResult, TempMHTML); + end; +end; + +function TWVBrowserBase.ExtractJSONData(const aJSON: wvstring; var aData: wvstring) : boolean; +{$IFDEF FPC} +var + TempJSON, TempData : TJSONData; +begin + Result := False; + TempJSON := nil; + + if (length(aJSON) > 0) then + try + TempJSON := GetJSON(UTF8Encode(aJSON), False); + TempData := TempJSON.FindPath('data'); + + if assigned(TempData) then + begin + aData := UTF8Decode(TempData.AsString); + Result := True; + end; + finally + if assigned(TempJSON) then + FreeAndNil(TempJSON); + end; +end; +{$ELSE} +{$IFDEF DELPHI20_UP} +var + TempJSONObj : TJSONObject; + TempJSONVal : TJSONValue; +begin + Result := False; + TempJSONObj := nil; + + try + if (length(aJSON) > 0) then + begin + TempJSONObj := TJSONObject.Create; + + if (TempJSONObj.Parse(BytesOf(aJSON), 0) >= 0) then + begin + TempJSONVal := TempJSONObj.GetValue('data'); + + if assigned(TempJSONVal) then + begin + aData := TempJSONVal.Value; + Result := True; + end; + end; + end; + finally + if assigned(TempJSONObj) then + FreeAndNil(TempJSONObj); + end; +end; +{$ELSE} +var + TempJSON, TempKey, TempValue : wvstring; + TempLen, i : integer; +begin + Result := False; + TempJSON := trim(aJSON); + TempLen := length(TempJSON); + + if (TempLen > 0) and (TempJSON[1] = '{') and (TempJSON[TempLen] = '}') then + begin + TempJSON := trim(copy(TempJSON, 2, TempLen - 2)); + i := pos(':', TempJSON); + TempKey := trim(copy(TempJSON, 1, i - 1)); + TempValue := trim(copy(TempJSON, i + 1, TempLen)); + TempLen := length(TempKey); + + if (TempLen > 0) and (TempKey[1] = '"') and (TempKey[TempLen] = '"') then + begin + TempKey := copy(TempKey, 2, TempLen - 2); + + if (CompareText(TempKey, 'data') = 0) then + begin + TempLen := length(TempValue); + + if (TempLen > 0) and (TempValue[1] = '"') and (TempValue[TempLen] = '"') then + begin + aData := JSONUnescape(copy(TempValue, 2, TempLen - 2)); + Result := True; + end; + end; + end; + end; +end; +{$ENDIF} +{$ENDIF} + +function TWVBrowserBase.ExtractEncodedJSON(const aJSON: wvstring): wvstring; +begin + Result := ''; + + {$IFDEF DELPHI21_UP} + Result := TNetEncoding.URL.Decode(aJSON); + {$ELSE} + {$IFDEF FPC} + Result := UTF8Decode(HTTPDecode(UTF8Encode(aJSON))); + {$ELSE} + {$IFDEF DELPHI12_UP} + Result := UTF8ToWideString(CustomURLDecode(aJSON)); + {$ELSE} + Result := UTF8Decode(CustomURLDecode(aJSON)); + {$ENDIF} + {$ENDIF} + {$ENDIF} + + if (length(Result) > 0) and (Result[1] = '"') and (Result[length(Result)] = '"') then + Result := copy(Result, 2, length(Result) - 2); +end; + +function TWVBrowserBase.AddScriptToExecuteOnDocumentCreatedCompletedHandler_Invoke(errorCode: HResult; result_: PWideChar): HRESULT; +begin + Result := S_OK; + doOnAddScriptToExecuteOnDocumentCreatedCompletedEvent(errorCode, wvstring(result_)); +end; + +function TWVBrowserBase.IsMutedChangedEventHandler_Invoke(const sender : ICoreWebView2; + const args : IUnknown): HRESULT; +begin + Result := S_OK; + doOnIsMutedChanged(sender); +end; + +function TWVBrowserBase.IsDocumentPlayingAudioChangedEventHandler_Invoke(const sender : ICoreWebView2; + const args : IUnknown): HRESULT; +begin + Result := S_OK; + doOnIsDocumentPlayingAudioChanged(sender); +end; + +function TWVBrowserBase.IsDefaultDownloadDialogOpenChangedEventHandler_Invoke(const sender : ICoreWebView2; + const args : IUnknown): HRESULT; +begin + Result := S_OK; + doOnIsDefaultDownloadDialogOpenChanged(sender); +end; + +function TWVBrowserBase.ProcessInfosChangedEventHandler_Invoke(const sender : ICoreWebView2Environment; + const args : IUnknown): HRESULT; +begin + Result := S_OK; + doOnProcessInfosChangedEvent(sender); +end; + +function TWVBrowserBase.FrameNavigationStartingEventHandler2_Invoke(const sender : ICoreWebView2Frame; + const args : ICoreWebView2NavigationStartingEventArgs; + aFrameID : cardinal): HRESULT; +begin + Result := S_OK; + doOnFrameNavigationStarting2(sender, args, aFrameID); +end; + +function TWVBrowserBase.FrameNavigationCompletedEventHandler2_Invoke(const sender : ICoreWebView2Frame; + const args : ICoreWebView2NavigationCompletedEventArgs; + aFrameID : cardinal): HRESULT; +begin + Result := S_OK; + doOnFrameNavigationCompleted2(sender, args, aFrameID); +end; + +function TWVBrowserBase.FrameContentLoadingEventHandler_Invoke(const sender : ICoreWebView2Frame; + const args : ICoreWebView2ContentLoadingEventArgs; + aFrameID : cardinal): HRESULT; +begin + Result := S_OK; + doOnFrameContentLoadingEvent(sender, args, aFrameID); +end; + +function TWVBrowserBase.FrameDOMContentLoadedEventHandler_Invoke(const sender : ICoreWebView2Frame; + const args : ICoreWebView2DOMContentLoadedEventArgs; + aFrameID : cardinal): HRESULT; +begin + Result := S_OK; + doOnFrameDOMContentLoadedEvent(sender, args, aFrameID); +end; + +function TWVBrowserBase.FrameWebMessageReceivedEventHandler_Invoke(const sender : ICoreWebView2Frame; + const args : ICoreWebView2WebMessageReceivedEventArgs; + aFrameID : cardinal): HRESULT; +begin + Result := S_OK; + doOnFrameWebMessageReceivedEvent(sender, args, aFrameID); +end; + +function TWVBrowserBase.BasicAuthenticationRequestedEventHandler_Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2BasicAuthenticationRequestedEventArgs): HRESULT; +begin + Result := S_OK; + doOnBasicAuthenticationRequestedEvent(sender, args); +end; + +function TWVBrowserBase.ContextMenuRequestedEventHandler_Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2ContextMenuRequestedEventArgs): HRESULT; +begin + Result := S_OK; + doOnContextMenuRequestedEvent(sender, args); +end; + +function TWVBrowserBase.CustomItemSelectedEventHandler_Invoke(const sender : ICoreWebView2ContextMenuItem; + const args : IUnknown): HRESULT; +begin + Result := S_OK; + doOnCustomItemSelectedEvent(sender, args); +end; + +function TWVBrowserBase.StatusBarTextChangedEventHandler_Invoke(const sender : ICoreWebView2; + const args : IUnknown): HRESULT; +begin + Result := S_OK; + doOnStatusBarTextChangedEvent(sender, args); +end; + +function TWVBrowserBase.FramePermissionRequestedEventHandler_Invoke(const sender : ICoreWebView2Frame; + const args : ICoreWebView2PermissionRequestedEventArgs2; + aFrameID : cardinal): HRESULT; +begin + Result := S_OK; + doOnFramePermissionRequestedEvent(sender, args, aFrameID); +end; + +function TWVBrowserBase.ClearBrowsingDataCompletedHandler_Invoke(errorCode: HResult): HRESULT; +begin + Result := S_OK; + doOnClearBrowsingDataCompletedEvent(errorCode); +end; + +function TWVBrowserBase.ClearServerCertificateErrorActionsCompletedHandler_Invoke(errorCode: HResult): HRESULT; +begin + Result := S_OK; + doOnServerCertificateErrorActionsCompletedEvent(errorCode); +end; + +function TWVBrowserBase.ServerCertificateErrorDetectedEventHandler_Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2ServerCertificateErrorDetectedEventArgs): HRESULT; +begin + Result := S_OK; + doOnServerCertificateErrorDetectedEvent(sender, args); +end; + +function TWVBrowserBase.FaviconChangedEventHandler_Invoke(const sender : ICoreWebView2; + const args : IUnknown): HRESULT; +begin + Result := S_OK; + doOnFaviconChangedEvent(sender, args); +end; + +function TWVBrowserBase.GetFaviconCompletedHandler_Invoke( errorCode : HResult; + const result_ : IStream): HRESULT; +begin + Result := S_OK; + doOnGetFaviconCompletedEvent(errorCode, result_); +end; + +function TWVBrowserBase.PrintCompletedHandler_Invoke(errorCode : HResult; + result_ : COREWEBVIEW2_PRINT_STATUS): HRESULT; +begin + Result := S_OK; + doOnPrintCompletedEvent(errorCode, result_); +end; + +function TWVBrowserBase.PrintToPdfStreamCompletedHandler_Invoke( errorCode : HResult; + const result_ : IStream): HRESULT; +begin + Result := S_OK; + doOnPrintToPdfStreamCompletedEvent(errorCode, result_); +end; + +function TWVBrowserBase.GetNonDefaultPermissionSettingsCompletedHandler_Invoke( errorCode : HResult; + const result_ : ICoreWebView2PermissionSettingCollectionView): HRESULT; +begin + Result := S_OK; + doOnGetNonDefaultPermissionSettingsCompleted(errorCode, result_); +end; + +function TWVBrowserBase.SetPermissionStateCompletedHandler_Invoke(errorCode: HResult): HRESULT; +begin + Result := S_OK; + doOnSetPermissionStateCompleted(errorCode); +end; + +function TWVBrowserBase.LaunchingExternalUriSchemeEventHandler_Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2LaunchingExternalUriSchemeEventArgs): HRESULT; +begin + Result := S_OK; + doOnLaunchingExternalUriSchemeEvent(sender, args); +end; + +function TWVBrowserBase.GetProcessExtendedInfosCompletedHandler_Invoke( errorCode : HResult; + const result_ : ICoreWebView2ProcessExtendedInfoCollection): HRESULT; +begin + Result := S_OK; + doOnGetProcessExtendedInfosCompletedEvent(errorCode, result_); +end; + +function TWVBrowserBase.BrowserExtensionRemoveCompletedHandler_Invoke( errorCode : HResult; + const aExtensionID : wvstring): HRESULT; +begin + Result := S_OK; + doOnBrowserExtensionRemoveCompletedEvent(errorCode, aExtensionID); +end; + +function TWVBrowserBase.BrowserExtensionEnableCompletedHandler_Invoke( errorCode : HResult; + const aExtensionID : wvstring): HRESULT; +begin + Result := S_OK; + doOnBrowserExtensionEnableCompletedEvent(errorCode, aExtensionID); +end; + +function TWVBrowserBase.ProfileAddBrowserExtensionCompletedHandler_Invoke( errorCode : HResult; + const result_ : ICoreWebView2BrowserExtension): HRESULT; +begin + Result := S_OK; + doOnProfileAddBrowserExtensionCompletedEvent(errorCode, result_); +end; + +function TWVBrowserBase.ProfileGetBrowserExtensionsCompletedHandler_Invoke( errorCode : HResult; + const result_ : ICoreWebView2BrowserExtensionList): HRESULT; +begin + Result := S_OK; + doOnProfileGetBrowserExtensionsCompletedEvent(errorCode, result_); +end; + +function TWVBrowserBase.ProfileDeletedEventHandler_Invoke(const sender : ICoreWebView2Profile; + const args : IUnknown): HRESULT; +begin + Result := S_OK; + doOnProfileDeletedEvent(sender, args); +end; + +function TWVBrowserBase.ExecuteScriptWithResultCompletedHandler_Invoke( errorCode : HResult; + const result_ : ICoreWebView2ExecuteScriptResult; + aExecutionID : integer): HRESULT; +begin + Result := S_OK; + doOnExecuteScriptWithResultCompletedEvent(errorCode, result_, aExecutionID); +end; + +function TWVBrowserBase.NonClientRegionChangedEventHandler_Invoke(const sender : ICoreWebView2CompositionController; + const args : ICoreWebView2NonClientRegionChangedEventArgs): HRESULT; +begin + Result := S_OK; + doOnNonClientRegionChangedEvent(sender, args); +end; + +function TWVBrowserBase.NotificationReceivedEventHandler_Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2NotificationReceivedEventArgs): HRESULT; +begin + Result := S_OK; + doOnNotificationReceivedEvent(sender, args); +end; + +function TWVBrowserBase.NotificationCloseRequestedEventHandler_Invoke(const sender : ICoreWebView2Notification; + const args : IUnknown): HRESULT; +begin + Result := S_OK; + doOnNotificationCloseRequestedEvent(sender, args); +end; + +function TWVBrowserBase.SaveAsUIShowingEventHandler_Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2SaveAsUIShowingEventArgs): HRESULT; +begin + Result := S_OK; + doOnSaveAsUIShowingEvent(sender, args); +end; + +function TWVBrowserBase.ShowSaveAsUICompletedHandler_Invoke(errorCode : HResult; + result_ : COREWEBVIEW2_SAVE_AS_UI_RESULT): HRESULT; +begin + Result := S_OK; + doOnShowSaveAsUICompletedEvent(errorCode, result_); +end; + +function TWVBrowserBase.SaveFileSecurityCheckStartingEventHandler_Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2SaveFileSecurityCheckStartingEventArgs): HRESULT; +begin + Result := S_OK; + doOnSaveFileSecurityCheckStartingEvent(sender, args); +end; + +function TWVBrowserBase.ScreenCaptureStartingEventHandler_Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2ScreenCaptureStartingEventArgs): HRESULT; +begin + Result := S_OK; + doOnScreenCaptureStartingEvent(sender, args); +end; + +function TWVBrowserBase.FrameScreenCaptureStartingEventHandler_Invoke(const sender : ICoreWebView2Frame; + const args : ICoreWebView2ScreenCaptureStartingEventArgs; + aFrameID : cardinal): HRESULT; +begin + Result := S_OK; + doOnFrameScreenCaptureStartingEvent(sender, args, aFrameID); +end; + +function TWVBrowserBase.FrameChildFrameCreatedEventHandler_Invoke(const sender : ICoreWebView2Frame; + const args : ICoreWebView2FrameCreatedEventArgs; + aFrameID : cardinal): HRESULT; +begin + Result := S_OK; + doOnFrameChildFrameCreatedEvent(sender, args, aFrameID); +end; + +function TWVBrowserBase.FindActiveMatchIndexChangedEventHandler_Invoke(const sender : ICoreWebView2Find; + const args : IUnknown): HRESULT; +begin + Result := S_OK; + doOnFindActiveMatchIndexChangedEvent(sender, args); +end; + +function TWVBrowserBase.FindMatchCountChangedEventHandler_Invoke(const sender : ICoreWebView2Find; + const args : IUnknown): HRESULT; +begin + Result := S_OK; + doOnFindMatchCountChangedEvent(sender, args); +end; + +function TWVBrowserBase.FindStartCompletedHandler_Invoke(errorCode: HResult): HRESULT; +begin + Result := S_OK; + doOnFindStartCompletedEvent(errorCode); +end; + +function TWVBrowserBase.DragStartingEventHandler_Invoke(const sender : ICoreWebView2CompositionController; + const args : ICoreWebView2DragStartingEventArgs): HRESULT; +begin + Result := S_OK; + doOnDragStartingEvent(sender, args); +end; + +function TWVBrowserBase.DedicatedWorkerCreatedEventHandler_Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2DedicatedWorkerCreatedEventArgs): HRESULT; +begin + Result := S_OK; + doOnDedicatedWorkerCreatedEvent(sender, args); +end; + +function TWVBrowserBase.DedicatedWorkerDedicatedWorkerCreatedEventHandler_Invoke(const sender : ICoreWebView2DedicatedWorker; + const args : ICoreWebView2DedicatedWorkerCreatedEventArgs; + aWorkerID : cardinal): HRESULT; +begin + Result := S_OK; + doOnDedicatedWorkerCreatedEvent2(sender, args, aWorkerID); +end; + +function TWVBrowserBase.DedicatedWorkerDestroyingEventHandler_Invoke(const sender : ICoreWebView2DedicatedWorker; + const args : IUnknown; + aWorkerID : cardinal): HRESULT; +begin + Result := S_OK; + doOnDedicatedWorkerDestroyingEvent(sender, args, aWorkerID); +end; + +function TWVBrowserBase.DedicatedWorkerWebMessageReceivedEventHandler_Invoke(const sender : ICoreWebView2DedicatedWorker; + const args : ICoreWebView2WebMessageReceivedEventArgs; + aWorkerID : cardinal): HRESULT; +begin + Result := S_OK; + doOnDedicatedWorkerWebMessageReceivedEvent(sender, args, aWorkerID); +end; + +function TWVBrowserBase.FrameDedicatedWorkerCreatedEventHandler_Invoke(const sender : ICoreWebView2Frame; + const args : ICoreWebView2DedicatedWorkerCreatedEventArgs; + aFrameID : cardinal): HRESULT; +begin + Result := S_OK; + doOnFrameDedicatedWorkerCreatedEvent(sender, args, aFrameID); +end; + +function TWVBrowserBase.ServiceWorkerDestroyingEventHandler_Invoke(const sender : ICoreWebView2ServiceWorker; + const args : IUnknown; + aWorkerID : cardinal): HRESULT; +begin + Result := S_OK; + doOnServiceWorkerDestroyingEvent(sender, args, aWorkerID); +end; + +function TWVBrowserBase.ServiceWorkerWebMessageReceivedEventHandler_Invoke(const sender : ICoreWebView2ServiceWorker; + const args : ICoreWebView2WebMessageReceivedEventArgs; + aWorkerID : cardinal): HRESULT; +begin + Result := S_OK; + doOnServiceWorkerWebMessageReceivedEvent(sender, args, aWorkerID); +end; + +function TWVBrowserBase.ServiceWorkerRegisteredEventHandler_Invoke(const sender : ICoreWebView2ServiceWorkerManager; + const args : ICoreWebView2ServiceWorkerRegisteredEventArgs): HRESULT; +begin + Result := S_OK; + doOnServiceWorkerRegisteredEvent(sender, args); +end; + +function TWVBrowserBase.GetServiceWorkerRegistrationsCompletedHandler_Invoke( errorCode : HResult; + const result_ : ICoreWebView2ServiceWorkerRegistrationCollectionView): HRESULT; +begin + Result := S_OK; + doOnGetServiceWorkerRegistrationsCompletedEvent(errorCode, result_); +end; + +function TWVBrowserBase.ServiceWorkerActivatedEventHandler_Invoke(const sender : ICoreWebView2ServiceWorkerRegistration; + const args : ICoreWebView2ServiceWorkerActivatedEventArgs): HRESULT; +begin + Result := S_OK; + doOnServiceWorkerActivatedEvent(sender, args); +end; + +function TWVBrowserBase.ServiceWorkerRegistrationUnregisteringEventHandler_Invoke(const sender : ICoreWebView2ServiceWorkerRegistration; + const args : IUnknown): HRESULT; +begin + Result := S_OK; + doOnServiceWorkerRegistrationUnregisteringEvent(sender, args); +end; + +function TWVBrowserBase.SharedWorkerCreatedEventHandler_Invoke(const sender : ICoreWebView2SharedWorkerManager; + const args : ICoreWebView2SharedWorkerCreatedEventArgs): HRESULT; +begin + Result := S_OK; + doOnSharedWorkerCreatedEvent(sender, args); +end; + +function TWVBrowserBase.GetSharedWorkersCompletedHandler_Invoke( errorCode : HResult; + const result_ : ICoreWebView2SharedWorkerCollectionView): HRESULT; +begin + Result := S_OK; + doOnGetSharedWorkersCompletedEvent(errorCode, result_); +end; + +function TWVBrowserBase.SharedWorkerDestroyingEventHandler_Invoke(const sender: ICoreWebView2SharedWorker; const args: IUnknown; aWorkerID: cardinal): HRESULT; +begin + Result := S_OK; + doOnSharedWorkerDestroyingEvent(sender, args, aWorkerID); +end; + +function TWVBrowserBase.ExecuteScriptCompletedHandler_Invoke(errorCode : HRESULT; + result_ : PWideChar; + aExecutionID : integer): HRESULT; +begin + Result := S_OK; + + case aExecutionID of + WEBVIEW4DELPHI_JS_RETRIEVEHTMLJOB_ID : + doOnRetrieveHTMLCompleted(errorCode, wvstring(result_)); + + WEBVIEW4DELPHI_JS_RETRIEVETEXTJOB_ID : + doOnRetrieveTextCompleted(errorCode, wvstring(result_)); + + else + doOnExecuteScriptCompleted(errorCode, wvstring(result_), aExecutionID); + end; +end; + +function TWVBrowserBase.DevToolsProtocolEventReceivedEventHandler_Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2DevToolsProtocolEventReceivedEventArgs; + const aEventName : wvstring; + aEventID : integer): HRESULT; +begin + Result := S_OK; + doOnDevToolsProtocolEventReceived(sender, args, aEventName, aEventID); +end; + +function TWVBrowserBase.CapturePreviewCompletedHandler_Invoke(errorCode: HRESULT): HRESULT; +begin + Result := S_OK; + doCapturePreviewCompleted(errorCode); +end; + +function TWVBrowserBase.CreateBrowser(aHandle : THandle; aUseDefaultEnvironment : boolean) : boolean; +begin + if aUseDefaultEnvironment and assigned(GlobalWebView2Loader) then + Result := CreateBrowser(aHandle, GlobalWebView2Loader.Environment) + else + Result := CreateBrowser(aHandle, nil); +end; + +function TWVBrowserBase.CreateBrowser(aHandle : THandle; const aEnvironment : ICoreWebView2Environment) : boolean; +begin + Result := False; + + if (aHandle = 0) or + (GlobalWebView2Loader = nil) or + not(GlobalWebView2Loader.Initialized) or + Initialized then + exit; + + FWindowParentHandle := aHandle; + + if assigned(aEnvironment) then + begin + DestroyEnvironment; + FUseDefaultEnvironment := True; + FCoreWebView2Environment := TCoreWebView2Environment.Create(aEnvironment); + Result := CreateController; + end + else + Result := CreateEnvironment; +end; + +function TWVBrowserBase.CreateInvisibleBrowser(aUseDefaultEnvironment : boolean) : boolean; +begin + Result := CreateBrowser(HWND_MESSAGE, aUseDefaultEnvironment); +end; + +function TWVBrowserBase.CreateInvisibleBrowser(const aEnvironment : ICoreWebView2Environment) : boolean; +begin + Result := CreateBrowser(HWND_MESSAGE, aEnvironment); +end; + +function TWVBrowserBase.CreateWindowlessBrowser(aHandle : THandle; aUseDefaultEnvironment : boolean) : boolean; +begin + if aUseDefaultEnvironment and assigned(GlobalWebView2Loader) then + Result := CreateWindowlessBrowser(aHandle, GlobalWebView2Loader.Environment) + else + Result := CreateWindowlessBrowser(aHandle, nil); +end; + +function TWVBrowserBase.CreateCompositionController: boolean; +var + TempError : wvstring; + TempHResult : HRESULT; + TempOptions : TCoreWebView2ControllerOptions; + TempOptionsIntf : ICoreWebView2ControllerOptions; + TempOldWinVer : boolean; +begin + Result := False; + TempOldWinVer := False; + TempHResult := S_OK; + TempOptionsIntf := nil; + + if (Win32MajorVersion < 10) then + TempOldWinVer := True + else + if FCoreWebView2Environment.CreateCoreWebView2ControllerOptions(TempOptionsIntf, TempHResult) then + try + TempOptions := TCoreWebView2ControllerOptions.Create(TempOptionsIntf); + TempOptions.ProfileName := FProfileName; + TempOptions.IsInPrivateModeEnabled := FIsInPrivateModeEnabled; + TempOptions.ScriptLocale := FScriptLocale; + TempOptions.DefaultBackgroundColor := FDefaultBackgroundColor; + TempOptions.AllowHostInputProcessing := FAllowHostInputProcessing; + + Result := FCoreWebView2Environment.CreateCoreWebView2CompositionControllerWithOptions(FWindowParentHandle, + TempOptions.BaseIntf, + self, + TempHResult); + finally + FreeAndNil(TempOptions); + TempOptionsIntf := nil; + end + else + if (TempHResult = E_NOTIMPL) then + begin + FProfileName := ''; + FIsInPrivateModeEnabled := False; + + Result := FCoreWebView2Environment.CreateCoreWebView2CompositionController(FWindowParentHandle, + self, + TempHResult); + end + else + begin + TempError := 'There was an error creating the controller options. (1)' + CRLF + + 'Error code : 0x' + + {$IFDEF FPC} + UTF8Decode(inttohex(TempHResult, 8)) + {$ELSE} + inttohex(TempHResult, 8) + {$ENDIF} + + CRLF + ControllerOptionsCreationErrorToString(TempHResult); + + doOnInitializationError(TempHResult, TempError); + exit; + end; + + if not(Result) then + begin + TempError := 'There was an error creating the composition controller. (3)' + CRLF; + + if TempOldWinVer then + TempError := TempError + 'The composition controller requires at least Windows 10 or Windows Server 2016.' + else + TempError := TempError + 'Error code : 0x' + + {$IFDEF FPC} + UTF8Decode(inttohex(TempHResult, 8)) + {$ELSE} + inttohex(TempHResult, 8) + {$ENDIF} + + CRLF + CompositionControllerCreationErrorToString(TempHResult); + + doOnInitializationError(TempHResult, TempError); + end; +end; + +function TWVBrowserBase.CreateController : boolean; +var + TempError : wvstring; + TempHResult : HRESULT; + TempOptions : TCoreWebView2ControllerOptions; + TempOptionsIntf : ICoreWebView2ControllerOptions; +begin + Result := False; + TempHResult := S_OK; + TempOptionsIntf := nil; + + if FCoreWebView2Environment.CreateCoreWebView2ControllerOptions(TempOptionsIntf, TempHResult) then + try + TempOptions := TCoreWebView2ControllerOptions.Create(TempOptionsIntf); + TempOptions.ProfileName := FProfileName; + TempOptions.IsInPrivateModeEnabled := FIsInPrivateModeEnabled; + TempOptions.ScriptLocale := FScriptLocale; + TempOptions.DefaultBackgroundColor := FDefaultBackgroundColor; + TempOptions.AllowHostInputProcessing := FAllowHostInputProcessing; + + Result := FCoreWebView2Environment.CreateCoreWebView2ControllerWithOptions(FWindowParentHandle, + TempOptions.BaseIntf, + self, + TempHResult); + finally + FreeAndNil(TempOptions); + TempOptionsIntf := nil; + end + else + if (TempHResult = E_NOTIMPL) then + begin + FProfileName := ''; + FIsInPrivateModeEnabled := False; + + Result := FCoreWebView2Environment.CreateCoreWebView2Controller(FWindowParentHandle, + self, + TempHResult); + end + else + begin + TempError := 'There was an error creating the controller options. (2)' + CRLF + + 'Error code : 0x' + + {$IFDEF FPC} + UTF8Decode(inttohex(TempHResult, 8)) + {$ELSE} + inttohex(TempHResult, 8) + {$ENDIF} + + CRLF + ControllerOptionsCreationErrorToString(TempHResult); + + doOnInitializationError(TempHResult, TempError); + exit; + end; + + if not(Result) then + begin + TempError := 'There was an error creating the controller. (4)' + CRLF + + 'Error code : 0x' + + {$IFDEF FPC} + UTF8Decode(inttohex(TempHResult, 8)) + {$ELSE} + inttohex(TempHResult, 8) + {$ENDIF} + + CRLF + ControllerCreationErrorToString(TempHResult); + + doOnInitializationError(TempHResult, TempError); + end; +end; + +function TWVBrowserBase.CreateWindowlessBrowser(aHandle : THandle; const aEnvironment : ICoreWebView2Environment) : boolean; +begin + Result := False; + + if (aHandle = 0) or + (GlobalWebView2Loader = nil) or + not(GlobalWebView2Loader.Initialized) or + Initialized then + exit; + + FWindowParentHandle := aHandle; + FUseCompositionController := True; + + if assigned(aEnvironment) then + begin + DestroyEnvironment; + FUseDefaultEnvironment := True; + FCoreWebView2Environment := TCoreWebView2Environment.Create(aEnvironment); + + if FCoreWebView2Environment.SupportsCompositionController then + Result := CreateCompositionController + else + doOnInitializationError(E_FAIL, 'The environment doesn' + #39 + 't support a composition controller.'); + end + else + Result := CreateEnvironment; +end; + +function TWVBrowserBase.ExecuteScriptWithResult(const aJavaScript: wvstring; aExecutionID : integer): boolean; +begin + Result := Initialized and + FCoreWebView2.ExecuteScriptWithResult(aJavaScript, aExecutionID, self); +end; + +function TWVBrowserBase.ExecuteScript(const aJavaScript : wvstring; aExecutionID : integer) : boolean; +begin + Result := Initialized and + FCoreWebView2.ExecuteScript(aJavaScript, aExecutionID, self); +end; + +function TWVBrowserBase.GetBrowserProcessID: cardinal; +begin + if Initialized then + Result := FCoreWebView2.BrowserProcessID + else + Result := 0; +end; + +function TWVBrowserBase.GetBrowserVersionInfo: wvstring; +begin + if Initialized then + Result := FCoreWebView2Environment.BrowserVersionInfo + else + Result := ''; +end; + +function TWVBrowserBase.GetUserDataFolder: wvstring; +begin + if Initialized then + Result := FCoreWebView2Environment.UserDataFolder + else + Result := FUserDataFolder; +end; + +function TWVBrowserBase.GetRootVisualTarget : IUnknown; +begin + if FUseCompositionController and Initialized then + Result := FCoreWebView2CompositionController.RootVisualTarget + else + Result := nil; +end; + +function TWVBrowserBase.GetCursor : HCURSOR; +begin + if FUseCompositionController and Initialized then + Result := FCoreWebView2CompositionController.Cursor + else + Result := 0; +end; + +function TWVBrowserBase.GetSystemCursorID : cardinal; +begin + if FUseCompositionController and Initialized then + Result := FCoreWebView2CompositionController.SystemCursorID + else + Result := 0; +end; + +function TWVBrowserBase.GetAutomationProvider : IUnknown; +begin + if FUseCompositionController and Initialized then + Result := FCoreWebView2CompositionController.AutomationProvider + else + Result := nil; +end; + +function TWVBrowserBase.GetProcessInfos : ICoreWebView2ProcessInfoCollection; +begin + if Initialized then + Result := FCoreWebView2Environment.ProcessInfos + else + Result := nil; +end; + +function TWVBrowserBase.GetIsMuted : boolean; +begin + Result := Initialized and + FCoreWebView2.IsMuted; +end; + +function TWVBrowserBase.GetIsDocumentPlayingAudio : boolean; +begin + Result := Initialized and + FCoreWebView2.IsDocumentPlayingAudio; +end; + +function TWVBrowserBase.GetIsDefaultDownloadDialogOpen : boolean; +begin + Result := Initialized and + FCoreWebView2.IsDefaultDownloadDialogOpen; +end; + +function TWVBrowserBase.GetStatusBarText : wvstring; +begin + if Initialized then + Result := FCoreWebView2.StatusBarText + else + Result := ''; +end; + +function TWVBrowserBase.GetDefaultDownloadDialogCornerAlignment : TWVDefaultDownloadDialogCornerAlignment; +begin + if Initialized then + Result := FCoreWebView2.DefaultDownloadDialogCornerAlignment + else + Result := 0; +end; + +function TWVBrowserBase.GetDefaultDownloadDialogMargin : TPoint; +begin + if Initialized then + Result := FCoreWebView2.DefaultDownloadDialogMargin + else + Result := point(0, 0); +end; + +function TWVBrowserBase.GetCanGoBack: boolean; +begin + Result := Initialized and + FCoreWebView2.CanGoBack; +end; + +function TWVBrowserBase.GetIsSuspended: boolean; +begin + Result := Initialized and + FCoreWebView2.IsSuspended; +end; + +function TWVBrowserBase.GetCanGoForward: boolean; +begin + Result := Initialized and + FCoreWebView2.CanGoForward; +end; + +function TWVBrowserBase.GetContainsFullScreenElement: boolean; +begin + Result := Initialized and + FCoreWebView2.ContainsFullScreenElement; +end; + +function TWVBrowserBase.GetBuiltInErrorPageEnabled: boolean; +begin + Result := Initialized and + FCoreWebView2Settings.IsBuiltInErrorPageEnabled; +end; + +function TWVBrowserBase.GetDefaultContextMenusEnabled: boolean; +begin + Result := Initialized and + FCoreWebView2Settings.AreDefaultContextMenusEnabled; +end; + +function TWVBrowserBase.GetDefaultScriptDialogsEnabled: boolean; +begin + Result := Initialized and + FCoreWebView2Settings.AreDefaultScriptDialogsEnabled; +end; + +function TWVBrowserBase.GetDevToolsEnabled: boolean; +begin + Result := Initialized and + FCoreWebView2Settings.AreDevToolsEnabled; +end; + +function TWVBrowserBase.GetDocumentTitle: wvstring; +begin + if Initialized then + Result := FCoreWebView2.DocumentTitle + else + Result := ''; +end; + +function TWVBrowserBase.GetSource: wvstring; +begin + if Initialized then + Result := FCoreWebView2.Source + else + Result := ''; +end; + +function TWVBrowserBase.GetCookieManager : ICoreWebView2CookieManager; +begin + if Initialized then + Result := FCoreWebView2.CookieManager + else + Result := nil; +end; + +function TWVBrowserBase.GetScriptEnabled: boolean; +begin + Result := Initialized and + FCoreWebView2Settings.IsScriptEnabled; +end; + +function TWVBrowserBase.GetStatusBarEnabled: boolean; +begin + Result := Initialized and + FCoreWebView2Settings.IsStatusBarEnabled; +end; + +function TWVBrowserBase.GetWebMessageEnabled: boolean; +begin + Result := Initialized and + FCoreWebView2Settings.IsWebMessageEnabled; +end; + +function TWVBrowserBase.GetInitialized: boolean; +begin + Result := (FCoreWebView2Environment <> nil) and FCoreWebView2Environment.Initialized and + (FCoreWebView2 <> nil) and FCoreWebView2.Initialized and + (FCoreWebView2Settings <> nil) and FCoreWebView2Settings.Initialized and + (FCoreWebView2Controller <> nil) and FCoreWebView2Controller.Initialized and + (not(FUseCompositionController) or ((FCoreWebView2CompositionController <> nil) and FCoreWebView2CompositionController.Initialized)); +end; + +function TWVBrowserBase.GetZoomControlEnabled: boolean; +begin + Result := Initialized and + FCoreWebView2Settings.IsZoomControlEnabled; +end; + +function TWVBrowserBase.GetIsVisible : boolean; +begin + Result := Initialized and + FCoreWebView2Controller.IsVisible; +end; + +function TWVBrowserBase.GetBounds : TRect; +begin + if Initialized then + Result := FCoreWebView2Controller.Bounds + else + Result := rect(0, 0, 0, 0); +end; + +function TWVBrowserBase.GetParentWindow : THandle; +begin + if Initialized then + Result := FCoreWebView2Controller.ParentWindow + else + Result := 0; +end; + +function TWVBrowserBase.GetDefaultBackgroundColor : TColor; +begin + if Initialized then + Result := FCoreWebView2Controller.DefaultBackgroundColor + else + Result := FDefaultBackgroundColor; +end; + +function TWVBrowserBase.GetRasterizationScale : double; +begin + if Initialized then + Result := FCoreWebView2Controller.RasterizationScale + else + Result := 0; +end; + +function TWVBrowserBase.GetShouldDetectMonitorScaleChanges : boolean; +begin + Result := Initialized and + FCoreWebView2Controller.ShouldDetectMonitorScaleChanges; +end; + +function TWVBrowserBase.GetAllowExternalDrop : boolean; +begin + Result := Initialized and + FCoreWebView2Controller.AllowExternalDrop; +end; + +function TWVBrowserBase.GetBoundsMode : TWVBoundsMode; +begin + if Initialized then + Result := FCoreWebView2Controller.BoundsMode + else + Result := 0; +end; + +function TWVBrowserBase.GetAreHostObjectsAllowed : boolean; +begin + Result := Initialized and + FCoreWebView2Settings.AreHostObjectsAllowed; +end; + +function TWVBrowserBase.GetUserAgent : wvstring; +begin + if Initialized then + Result := FCoreWebView2Settings.UserAgent + else + Result := ''; +end; + +function TWVBrowserBase.GetAreBrowserAcceleratorKeysEnabled : boolean; +begin + Result := Initialized and + FCoreWebView2Settings.AreBrowserAcceleratorKeysEnabled; +end; + +function TWVBrowserBase.GetIsPasswordAutosaveEnabled : boolean; +begin + Result := Initialized and + FCoreWebView2Settings.IsPasswordAutosaveEnabled; +end; + +function TWVBrowserBase.GetIsGeneralAutofillEnabled : boolean; +begin + Result := Initialized and + FCoreWebView2Settings.IsGeneralAutofillEnabled; +end; + +function TWVBrowserBase.GetIsPinchZoomEnabled : boolean; +begin + Result := Initialized and + FCoreWebView2Settings.IsPinchZoomEnabled; +end; + +function TWVBrowserBase.GetIsSwipeNavigationEnabled : boolean; +begin + Result := Initialized and + FCoreWebView2Settings.IsSwipeNavigationEnabled; +end; + +function TWVBrowserBase.GetHiddenPdfToolbarItems : TWVPDFToolbarItems; +begin + if Initialized then + Result := FCoreWebView2Settings.HiddenPdfToolbarItems + else + Result := 0; +end; + +function TWVBrowserBase.GetIsReputationCheckingRequired : boolean; +begin + if Initialized then + Result := FCoreWebView2Settings.IsReputationCheckingRequired + else + Result := True; +end; + +function TWVBrowserBase.GetIsNonClientRegionSupportEnabled : boolean; +begin + Result := Initialized and + FCoreWebView2Settings.IsNonClientRegionSupportEnabled; +end; + +function TWVBrowserBase.GetFaviconURI : wvstring; +begin + if Initialized then + Result := FCoreWebView2.FaviconURI + else + Result := ''; +end; + +function TWVBrowserBase.GetMemoryUsageTargetLevel : TWVMemoryUsageTargetLevel; +begin + if Initialized then + Result := FCoreWebView2.MemoryUsageTargetLevel + else + Result := COREWEBVIEW2_MEMORY_USAGE_TARGET_LEVEL_NORMAL; +end; + +function TWVBrowserBase.GetFrameID : cardinal; +begin + if Initialized then + Result := FCoreWebView2.FrameId + else + Result := WEBVIEW4DELPHI_INVALID_FRAMEID; +end; + +function TWVBrowserBase.GetAreWebViewScriptApisEnabledForServiceWorkers : boolean; +begin + Result := Initialized and + assigned(FCoreWebView2Profile) and + FCoreWebView2Profile.AreWebViewScriptApisEnabledForServiceWorkers; +end; + +function TWVBrowserBase.GetServiceWorkerManager : ICoreWebView2ServiceWorkerManager; +begin + if Initialized and assigned(FCoreWebView2Profile) then + Result := FCoreWebView2Profile.ServiceWorkerManager + else + Result := nil; +end; + +function TWVBrowserBase.GetSharedWorkerManager : ICoreWebView2SharedWorkerManager; +begin + if Initialized and assigned(FCoreWebView2Profile) then + Result := FCoreWebView2Profile.SharedWorkerManager + else + Result := nil; +end; + +function TWVBrowserBase.GetScreenScale : single; +begin + if (GlobalWebView2Loader <> nil) then + Result := GlobalWebView2Loader.DeviceScaleFactor + else + Result := 1; +end; + +function TWVBrowserBase.GetZoomFactor: Double; +begin + if Initialized then + Result := FCoreWebView2Controller.ZoomFactor + else + Result := 0; +end; + +function TWVBrowserBase.GetZoomPct : double; +begin + Result := ZoomFactor * 100; +end; + +function TWVBrowserBase.GoBack : boolean; +begin + Result := Initialized and + FCoreWebView2.GoBack; +end; + +function TWVBrowserBase.GoForward : boolean; +begin + Result := Initialized and + FCoreWebView2.GoForward; +end; + +function TWVBrowserBase.CreateEnvironment : boolean; +var + TempOptions : ICoreWebView2EnvironmentOptions; + TempHandler : ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler; + TempError : wvstring; + TempHResult : HRESULT; + TempSchemeRegistrations : TWVCustomSchemeRegistrationArray; + i : integer; +begin + Result := False; + TempSchemeRegistrations := nil; + + try + doOnGetCustomSchemes(TempSchemeRegistrations); + + TempHandler := TCoreWebView2EnvironmentCompletedHandler.Create(self); + + TempOptions := TCoreWebView2EnvironmentOptions.Create(FAdditionalBrowserArguments, + FLanguage, + FTargetCompatibleBrowserVersion, + FAllowSingleSignOnUsingOSPrimaryAccount, + FExclusiveUserDataFolderAccess, + FCustomCrashReportingEnabled, + TempSchemeRegistrations, + FEnableTrackingPrevention, + FAreBrowserExtensionsEnabled, + FChannelSearchKind, + FReleaseChannels, + FScrollBarStyle); + + TempHResult := CreateCoreWebView2EnvironmentWithOptions(PWideChar(FBrowserExecPath), + PWideChar(FUserDataFolder), + TempOptions, + TempHandler); + + if succeeded(TempHResult) then + Result := True + else + begin + TempError := 'There was an error creating the browser environment. (2)' + CRLF + + 'Error code : 0x' + + {$IFDEF FPC} + UTF8Decode(inttohex(TempHResult, 8)) + {$ELSE} + inttohex(TempHResult, 8) + {$ENDIF} + + CRLF + EnvironmentCreationErrorToString(TempHResult); + + doOnInitializationError(TempHResult, TempError); + end; + finally + TempOptions := nil; + TempHandler := nil; + + if assigned(TempSchemeRegistrations) then + begin + i := pred(length(TempSchemeRegistrations)); + while (i >= 0) do + begin + TempSchemeRegistrations[i] := nil; + dec(i); + end; + end; + end; +end; + +function TWVBrowserBase.Navigate(const aURI : wvstring): boolean; +begin + Result := Initialized and + FCoreWebView2.Navigate(aURI); +end; + +function TWVBrowserBase.NavigateToString(const aHTMLContent: wvstring): boolean; +begin + Result := Initialized and + FCoreWebView2.NavigateToString(PWideChar(aHTMLContent)); +end; + +function TWVBrowserBase.NavigateWithWebResourceRequest(const aRequest : ICoreWebView2WebResourceRequest) : boolean; +begin + Result := Initialized and + FCoreWebView2.NavigateWithWebResourceRequest(aRequest); +end; + +function TWVBrowserBase.Refresh : boolean; +begin + Result := Initialized and + FCoreWebView2.Reload; +end; + +function TWVBrowserBase.RefreshIgnoreCache : boolean; +begin + Result := CallDevToolsProtocolMethod('Page.reload', '{"ignoreCache": true}', WEBVIEW4DELPHI_DEVTOOLS_REFRESH_ID); +end; + +procedure TWVBrowserBase.SetBounds(aValue : TRect); +begin + if Initialized then + FCoreWebView2Controller.Bounds := aValue; +end; + +procedure TWVBrowserBase.SetParentWindow(aValue : THandle); +begin + if Initialized then + FCoreWebView2Controller.ParentWindow := aValue; +end; + +procedure TWVBrowserBase.SetDefaultBackgroundColor(const aValue : TColor); +begin + FDefaultBackgroundColor := aValue; + + if Initialized then + FCoreWebView2Controller.DefaultBackgroundColor := aValue; +end; + +procedure TWVBrowserBase.SetRasterizationScale(const aValue : double); +begin + if Initialized then + FCoreWebView2Controller.RasterizationScale := aValue; +end; + +procedure TWVBrowserBase.SetShouldDetectMonitorScaleChanges(aValue : boolean); +begin + if Initialized then + FCoreWebView2Controller.ShouldDetectMonitorScaleChanges := aValue; +end; + +procedure TWVBrowserBase.SetAllowExternalDrop(aValue : boolean); +begin + if Initialized then + FCoreWebView2Controller.AllowExternalDrop := aValue; +end; + +procedure TWVBrowserBase.SetBoundsMode(aValue : TWVBoundsMode); +begin + if Initialized then + FCoreWebView2Controller.BoundsMode := aValue; +end; + +procedure TWVBrowserBase.SetAreHostObjectsAllowed(aValue : boolean); +begin + if Initialized then + FCoreWebView2Settings.AreHostObjectsAllowed := aValue; +end; + +procedure TWVBrowserBase.SetUserAgent(const aValue : wvstring); +begin + if Initialized then + FCoreWebView2Settings.UserAgent := aValue; +end; + +procedure TWVBrowserBase.SetAreBrowserAcceleratorKeysEnabled(aValue : boolean); +begin + if Initialized then + FCoreWebView2Settings.AreBrowserAcceleratorKeysEnabled := aValue; +end; + +procedure TWVBrowserBase.SetIsPasswordAutosaveEnabled(aValue : boolean); +begin + if Initialized then + FCoreWebView2Settings.IsPasswordAutosaveEnabled := aValue; +end; + +procedure TWVBrowserBase.SetIsGeneralAutofillEnabled(aValue : boolean); +begin + if Initialized then + FCoreWebView2Settings.IsGeneralAutofillEnabled := aValue; +end; + +procedure TWVBrowserBase.SetIsPinchZoomEnabled(aValue : boolean); +begin + if Initialized then + FCoreWebView2Settings.IsPinchZoomEnabled := aValue; +end; + +procedure TWVBrowserBase.SetIsSwipeNavigationEnabled(aValue : boolean); +begin + if Initialized then + FCoreWebView2Settings.IsSwipeNavigationEnabled := aValue; +end; + +procedure TWVBrowserBase.SetHiddenPdfToolbarItems(aValue : TWVPDFToolbarItems); +begin + if Initialized then + FCoreWebView2Settings.HiddenPdfToolbarItems := aValue; +end; + +procedure TWVBrowserBase.SetIsReputationCheckingRequired(aValue : boolean); +begin + if Initialized then + FCoreWebView2Settings.IsReputationCheckingRequired := aValue; +end; + +procedure TWVBrowserBase.SetIsNonClientRegionSupportEnabled(aValue : boolean); +begin + if Initialized then + FCoreWebView2Settings.IsNonClientRegionSupportEnabled := aValue; +end; + +procedure TWVBrowserBase.SetProfileName(const aValue : wvstring); +const + PROFILENAME_VALID_CHARS = ['a'..'z', 'A'..'Z', '0'..'9', '#', '@', '$', '(', ')', '+', '-', '_', '~', '.', ' ']; + PROFILENAME_INVALID_ENDCHARS = ['.', ' ']; + PROFILENAME_MAX_LENGTH = 64; +var + i : integer; + TempValue : wvstring; +begin + TempValue := ''; + i := 1; + + while (i <= length(aValue)) do + begin + {$IFDEF DELPHI12_UP} + if CharInSet(aValue[i], PROFILENAME_VALID_CHARS) then + {$ELSE} + if (Char(aValue[i]) in PROFILENAME_VALID_CHARS) then + {$ENDIF} + TempValue := TempValue + aValue[i]; + + inc(i); + end; + + TempValue := copy(TempValue, 1, PROFILENAME_MAX_LENGTH); + + while (length(TempValue) > 0) and + {$IFDEF DELPHI12_UP} + CharInSet(TempValue[length(TempValue)], PROFILENAME_INVALID_ENDCHARS) do + {$ELSE} + (Char(TempValue[length(TempValue)]) in PROFILENAME_INVALID_ENDCHARS) do + {$ENDIF} + TempValue := copy(TempValue, 1, pred(length(TempValue))); + + FProfileName := TempValue; +end; + +procedure TWVBrowserBase.SetBuiltInErrorPageEnabled(aValue: boolean); +begin + if Initialized then + FCoreWebView2Settings.IsBuiltInErrorPageEnabled := aValue; +end; + +procedure TWVBrowserBase.SetDefaultContextMenusEnabled(aValue: boolean); +begin + if Initialized then + FCoreWebView2Settings.AreDefaultContextMenusEnabled := aValue; +end; + +procedure TWVBrowserBase.SetDefaultScriptDialogsEnabled(aValue: boolean); +begin + if Initialized then + FCoreWebView2Settings.AreDefaultScriptDialogsEnabled := aValue; +end; + +procedure TWVBrowserBase.SetDevToolsEnabled(aValue: boolean); +begin + if Initialized then + FCoreWebView2Settings.AreDevToolsEnabled := aValue; +end; + +function TWVBrowserBase.SetFocus : boolean; +begin + Result := Initialized and + FCoreWebView2Controller.MoveFocus(COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC); +end; + +function TWVBrowserBase.FocusNext : boolean; +begin + Result := Initialized and + FCoreWebView2Controller.MoveFocus(COREWEBVIEW2_MOVE_FOCUS_REASON_NEXT); +end; + +function TWVBrowserBase.FocusPrevious : boolean; +begin + Result := Initialized and + FCoreWebView2Controller.MoveFocus(COREWEBVIEW2_MOVE_FOCUS_REASON_PREVIOUS); +end; + +function TWVBrowserBase.SetBoundsAndZoomFactor(aBounds: TRect; const aZoomFactor: double) : boolean; +begin + Result := Initialized and + FCoreWebView2Controller.SetBoundsAndZoomFactor(aBounds, aZoomFactor); +end; + +function TWVBrowserBase.NotifyParentWindowPositionChanged : boolean; +begin + Result := Initialized and + FCoreWebView2Controller.NotifyParentWindowPositionChanged; +end; + +procedure TWVBrowserBase.ToggleMuteState; +begin + if Initialized then + FCoreWebView2.IsMuted := not(FCoreWebView2.IsMuted); +end; + +function TWVBrowserBase.OpenDefaultDownloadDialog : boolean; +begin + Result := Initialized and + FCoreWebView2.OpenDefaultDownloadDialog; +end; + +function TWVBrowserBase.CloseDefaultDownloadDialog : boolean; +begin + Result := Initialized and + FCoreWebView2.CloseDefaultDownloadDialog; +end; + +function TWVBrowserBase.ClearServerCertificateErrorActions : boolean; +begin + Result := Initialized and + FCoreWebView2.ClearServerCertificateErrorActions(self); +end; + +function TWVBrowserBase.GetFavicon(aFormat: TWVFaviconImageFormat) : boolean; +begin + Result := Initialized and + FCoreWebView2.GetFavicon(aFormat, self); +end; + +function TWVBrowserBase.PostSharedBufferToScript(const aSharedBuffer : ICoreWebView2SharedBuffer; + aAccess : TWVSharedBufferAccess; + const aAdditionalDataAsJson : wvstring): boolean; +begin + Result := Initialized and + FCoreWebView2.PostSharedBufferToScript(aSharedBuffer, aAccess, aAdditionalDataAsJson); +end; + +function TWVBrowserBase.GetProcessExtendedInfos : boolean; +begin + Result := Initialized and + FCoreWebView2Environment.GetProcessExtendedInfos(self); +end; + +function TWVBrowserBase.ShowSaveAsUI : boolean; +begin + Result := Initialized and + FCoreWebView2.ShowSaveAsUI(self); +end; + +function TWVBrowserBase.FindStart(const aFindTerm : wvstring) : boolean; +var + TempHandler : ICoreWebView2FindStartCompletedHandler; +begin + Result := False; + + if Initialized and assigned(FCoreWebView2FindOptions) then + try + FCoreWebView2FindOptions.FindTerm := aFindTerm; + + TempHandler := TCoreWebView2FindStartCompletedHandler.Create(self); + + DestroyFind; + FCoreWebView2Find := TCoreWebView2Find.Create(FCoreWebView2.Find); + FCoreWebView2Find.AddAllBrowserEvents(self); + Result := FCoreWebView2Find.Start(FCoreWebView2FindOptions.BaseIntf, TempHandler); + finally + TempHandler := nil; + end; +end; + +function TWVBrowserBase.FindNext : boolean; +begin + Result := False; + + if Initialized then + begin + DestroyFind; + FCoreWebView2Find := TCoreWebView2Find.Create(FCoreWebView2.Find); + FCoreWebView2Find.AddAllBrowserEvents(self); + Result := FCoreWebView2Find.FindNext; + end; +end; + +function TWVBrowserBase.FindPrevious : boolean; +begin + Result := False; + + if Initialized then + begin + DestroyFind; + FCoreWebView2Find := TCoreWebView2Find.Create(FCoreWebView2.Find); + FCoreWebView2Find.AddAllBrowserEvents(self); + Result := FCoreWebView2Find.FindPrevious; + end; +end; + +function TWVBrowserBase.FindStop : boolean; +begin + Result := False; + + if Initialized then + begin + DestroyFind; + FCoreWebView2Find := TCoreWebView2Find.Create(FCoreWebView2.Find); + FCoreWebView2Find.AddAllBrowserEvents(self); + Result := FCoreWebView2Find.Stop; + end; +end; + +function TWVBrowserBase.TrySuspend : boolean; +var + TempHandler : ICoreWebView2TrySuspendCompletedHandler; +begin + Result := False; + + if Initialized then + try + TempHandler := TCoreWebView2TrySuspendCompletedHandler.Create(self); + Result := FCoreWebView2.TrySuspend(TempHandler); + finally + TempHandler := nil; + end; +end; + +function TWVBrowserBase.Resume : boolean; +begin + Result := Initialized and + FCoreWebView2.Resume; +end; + +function TWVBrowserBase.SetVirtualHostNameToFolderMapping(const aHostName, aFolderPath : wvstring; aAccessKind : TWVHostResourceAcccessKind): boolean; +begin + Result := Initialized and + FCoreWebView2.SetVirtualHostNameToFolderMapping(aHostName, aFolderPath, aAccessKind); +end; + +function TWVBrowserBase.ClearVirtualHostNameToFolderMapping(const aHostName : wvstring) : boolean; +begin + Result := Initialized and + FCoreWebView2.ClearVirtualHostNameToFolderMapping(aHostName); +end; + +function TWVBrowserBase.OpenTaskManagerWindow : boolean; +begin + Result := Initialized and + FCoreWebView2.OpenTaskManagerWindow; +end; + +function TWVBrowserBase.RetrieveHTML : boolean; +begin + // JS code created by Alessandro Mancini + Result := ExecuteScript('encodeURIComponent(document.documentElement.outerHTML);', WEBVIEW4DELPHI_JS_RETRIEVEHTMLJOB_ID); +end; + +function TWVBrowserBase.RetrieveText(aVisibleTextOnly: boolean) : boolean; +begin + if aVisibleTextOnly then + Result := ExecuteScript('encodeURIComponent(document.body.innerText);', WEBVIEW4DELPHI_JS_RETRIEVETEXTJOB_ID) + else + Result := ExecuteScript('encodeURIComponent(document.body.textContent);', WEBVIEW4DELPHI_JS_RETRIEVETEXTJOB_ID); +end; + +function TWVBrowserBase.RetrieveMHTML : boolean; +begin + Result := CallDevToolsProtocolMethod('Page.captureSnapshot', '{"format": "mhtml"}', WEBVIEW4DELPHI_DEVTOOLS_RETRIEVEMHTML_ID); +end; + +function TWVBrowserBase.Print : boolean; +var + TempHandler : ICoreWebView2PrintCompletedHandler; +begin + Result := False; + + if Initialized and + assigned(FCoreWebView2PrintSettings) and + FCoreWebView2PrintSettings.Initialized then + try + TempHandler := TCoreWebView2PrintCompletedHandler.Create(self); + Result := FCoreWebView2.Print(FCoreWebView2PrintSettings.BaseIntf, TempHandler); + finally + TempHandler := nil; + end; +end; + +function TWVBrowserBase.ShowPrintUI(aUseSystemPrintDialog : boolean): boolean; +begin + if Initialized then + begin + if aUseSystemPrintDialog then + Result := FCoreWebView2.ShowPrintUI(COREWEBVIEW2_PRINT_DIALOG_KIND_SYSTEM) + else + Result := FCoreWebView2.ShowPrintUI(COREWEBVIEW2_PRINT_DIALOG_KIND_BROWSER); + end + else + Result := False; +end; + +function TWVBrowserBase.PrintToPdf(const aResultFilePath : wvstring) : boolean; +var + TempHandler : ICoreWebView2PrintToPdfCompletedHandler; +begin + Result := False; + + if Initialized and + assigned(FCoreWebView2PrintSettings) and + FCoreWebView2PrintSettings.Initialized then + try + TempHandler := TCoreWebView2PrintToPdfCompletedHandler.Create(self); + Result := FCoreWebView2.PrintToPdf(aResultFilePath, FCoreWebView2PrintSettings.BaseIntf, TempHandler); + finally + TempHandler := nil; + end; +end; + +function TWVBrowserBase.PrintToPdfStream : boolean; +var + TempHandler : ICoreWebView2PrintToPdfStreamCompletedHandler; +begin + Result := False; + + if Initialized and + assigned(FCoreWebView2PrintSettings) and + FCoreWebView2PrintSettings.Initialized then + try + TempHandler := TCoreWebView2PrintToPdfStreamCompletedHandler.Create(self); + Result := FCoreWebView2.PrintToPdfStream(FCoreWebView2PrintSettings.BaseIntf, TempHandler); + finally + TempHandler := nil; + end; +end; + +function TWVBrowserBase.OpenDevToolsWindow : boolean; +begin + Result := Initialized and + FCoreWebView2.OpenDevToolsWindow; +end; + +function TWVBrowserBase.PostWebMessageAsJson(const aWebMessageAsJson : wvstring) : boolean; +begin + Result := Initialized and + FCoreWebView2.PostWebMessageAsJson(aWebMessageAsJson); +end; + +function TWVBrowserBase.PostWebMessageAsString(const aWebMessageAsString : wvstring) : boolean; +begin + Result := Initialized and + FCoreWebView2.PostWebMessageAsString(aWebMessageAsString); +end; + +function TWVBrowserBase.CallDevToolsProtocolMethod(const aMethodName, aParametersAsJson : wvstring; aExecutionID : integer) : boolean; +begin + Result := Initialized and + FCoreWebView2.CallDevToolsProtocolMethod(aMethodName, aParametersAsJson, aExecutionID, self); +end; + +function TWVBrowserBase.CallDevToolsProtocolMethodForSession(const aSessionId, aMethodName, aParametersAsJson : wvstring; aExecutionID : integer) : boolean; +begin + Result := Initialized and + FCoreWebView2.CallDevToolsProtocolMethodForSession(aSessionId, aMethodName, aParametersAsJson, aExecutionID, self); +end; + +function TWVBrowserBase.AddHostObjectToScript(const aName : wvstring; const aObject : OleVariant): boolean; +begin + Result := Initialized and + FCoreWebView2.AddHostObjectToScript(aName, aObject); +end; + +function TWVBrowserBase.RemoveHostObjectFromScript(const aName : wvstring) : boolean; +begin + Result := Initialized and + FCoreWebView2.RemoveHostObjectFromScript(aName); +end; + +function TWVBrowserBase.AddScriptToExecuteOnDocumentCreated(const JavaScript : wvstring) : boolean; +begin + Result := Initialized and + FCoreWebView2.AddScriptToExecuteOnDocumentCreated(JavaScript, self); +end; + +function TWVBrowserBase.RemoveScriptToExecuteOnDocumentCreated(const aID : wvstring) : boolean; +begin + Result := Initialized and + FCoreWebView2.RemoveScriptToExecuteOnDocumentCreated(aID); +end; + +function TWVBrowserBase.CreateCookie(const aName, aValue, aDomain, aPath : wvstring) : ICoreWebView2Cookie; +var + TempManager : TCoreWebView2CookieManager; +begin + Result := nil; + + if Initialized then + try + TempManager := TCoreWebView2CookieManager.Create(FCoreWebView2.CookieManager); + Result := TempManager.CreateCookie(aName, aValue, aDomain, aPath); + finally + FreeAndNil(TempManager); + end; +end; + +function TWVBrowserBase.CopyCookie(const aCookie : ICoreWebView2Cookie) : ICoreWebView2Cookie; +var + TempManager : TCoreWebView2CookieManager; +begin + Result := nil; + + if Initialized then + try + TempManager := TCoreWebView2CookieManager.Create(FCoreWebView2.CookieManager); + Result := TempManager.CopyCookie(aCookie); + finally + FreeAndNil(TempManager); + end; +end; + +// This function is asynchronous and it triggers the TWVBrowserBase.OnGetCookiesCompleted event when it finishes +function TWVBrowserBase.GetCookies(const aURI : wvstring): boolean; +var + TempHandler : ICoreWebView2GetCookiesCompletedHandler; + TempManager : TCoreWebView2CookieManager; +begin + Result := False; + + if Initialized then + try + TempManager := TCoreWebView2CookieManager.Create(FCoreWebView2.CookieManager); + TempHandler := TCoreWebView2GetCookiesCompletedHandler.Create(self); + Result := TempManager.GetCookies(aURI, TempHandler); + finally + TempHandler := nil; + FreeAndNil(TempManager); + end; +end; + +function TWVBrowserBase.AddOrUpdateCookie(const aCookie : ICoreWebView2Cookie): boolean; +var + TempManager : TCoreWebView2CookieManager; +begin + Result := False; + + if Initialized then + try + TempManager := TCoreWebView2CookieManager.Create(FCoreWebView2.CookieManager); + Result := TempManager.AddOrUpdateCookie(aCookie); + finally + FreeAndNil(TempManager); + end; +end; + +function TWVBrowserBase.DeleteCookie(const aCookie : ICoreWebView2Cookie): boolean; +var + TempManager : TCoreWebView2CookieManager; +begin + Result := False; + + if Initialized then + try + TempManager := TCoreWebView2CookieManager.Create(FCoreWebView2.CookieManager); + Result := TempManager.DeleteCookie(aCookie); + finally + FreeAndNil(TempManager); + end; +end; + +function TWVBrowserBase.DeleteCookies(const aName, aURI : wvstring): boolean; +var + TempManager : TCoreWebView2CookieManager; +begin + Result := False; + + if Initialized then + try + TempManager := TCoreWebView2CookieManager.Create(FCoreWebView2.CookieManager); + Result := TempManager.DeleteCookies(aName, aURI); + finally + FreeAndNil(TempManager); + end; +end; + +function TWVBrowserBase.DeleteCookiesWithDomainAndPath(const aName, aDomain, aPath : wvstring): boolean; +var + TempManager : TCoreWebView2CookieManager; +begin + Result := False; + + if Initialized then + try + TempManager := TCoreWebView2CookieManager.Create(FCoreWebView2.CookieManager); + Result := TempManager.DeleteCookiesWithDomainAndPath(aName, aDomain, aPath); + finally + FreeAndNil(TempManager); + end; +end; + +function TWVBrowserBase.DeleteAllCookies : boolean; +var + TempManager : TCoreWebView2CookieManager; +begin + Result := False; + + if Initialized then + try + TempManager := TCoreWebView2CookieManager.Create(FCoreWebView2.CookieManager); + Result := TempManager.DeleteAllCookies; + finally + FreeAndNil(TempManager); + end; +end; + +function TWVBrowserBase.ClearCache : boolean; +begin + Result := CallDevToolsProtocolMethod('Network.clearBrowserCache', '{}', WEBVIEW4DELPHI_DEVTOOLS_CLEARBROWSERCACHE_ID); +end; + +function TWVBrowserBase.ClearDataForOrigin(const aOrigin : wvstring; aStorageTypes : TWVClearDataStorageTypes) : boolean; +var + TempParams : wvstring; +begin + TempParams := '{"origin": "' + aOrigin + '", '; + + case aStorageTypes of + cdstCookies : TempParams := TempParams + '"storageTypes": "cookies"}'; + cdstFileSystems : TempParams := TempParams + '"storageTypes": "file_systems"}'; + cdstIndexeddb : TempParams := TempParams + '"storageTypes": "indexeddb"}'; + cdstLocalStorage : TempParams := TempParams + '"storageTypes": "local_storage"}'; + cdstShaderCache : TempParams := TempParams + '"storageTypes": "shader_cache"}'; + cdstWebsql : TempParams := TempParams + '"storageTypes": "websql"}'; + cdstServiceWorkers : TempParams := TempParams + '"storageTypes": "service_workers"}'; + cdstCacheStorage : TempParams := TempParams + '"storageTypes": "cache_storage"}'; + cdstInterestGroups : TempParams := TempParams + '"storageTypes": "interest_groups"}'; + cdstSharedStorage : TempParams := TempParams + '"storageTypes": "shared_storage"}'; + cdstStorageBuckets : TempParams := TempParams + '"storageTypes": "storage_buckets"}'; + cdstOther : TempParams := TempParams + '"storageTypes": "other"}'; + else TempParams := TempParams + '"storageTypes": "all"}'; + end; + + Result := CallDevToolsProtocolMethod('Storage.clearDataForOrigin', TempParams, WEBVIEW4DELPHI_DEVTOOLS_CLEARDATAFORORIGIN_ID); +end; + +procedure TWVBrowserBase.SetOffline(aValue : boolean); +var + TempParams : wvstring; +begin + if (FOffline <> aValue) then + begin + FOffline := aValue; + TempParams := '{"offline": ' + + {$IFDEF FPC} + UTF8Decode(lowercase(BoolToStr(FOffline, True))) + {$ELSE} + lowercase(BoolToStr(FOffline, True)) + {$ENDIF} + + ', "latency": 0, "downloadThroughput": 0, "uploadThroughput": 0}'; + + CallDevToolsProtocolMethod('Network.emulateNetworkConditions', TempParams, WEBVIEW4DELPHI_DEVTOOLS_EMULATENETWORKCONDITIONS_ID); + end; +end; + +procedure TWVBrowserBase.SetIgnoreCertificateErrors(aValue : boolean); +var + TempParams : wvstring; +begin + if (FIgnoreCertificateErrors <> aValue) then + begin + FIgnoreCertificateErrors := aValue; + TempParams := '{"ignore": ' + + {$IFDEF FPC} + UTF8Decode(lowercase(BoolToStr(FIgnoreCertificateErrors, True))) + {$ELSE} + lowercase(BoolToStr(FIgnoreCertificateErrors, True)) + {$ENDIF} + + '}'; + + CallDevToolsProtocolMethod('Security.setIgnoreCertificateErrors', TempParams, WEBVIEW4DELPHI_DEVTOOLS_SETIGNORECERTIFICATEERRORS_ID); + end; +end; + +procedure TWVBrowserBase.SetRootVisualTarget(const aValue : IUnknown); +begin + if FUseCompositionController and Initialized then + FCoreWebView2CompositionController.RootVisualTarget := aValue; +end; + +procedure TWVBrowserBase.SetIsMuted(aValue : boolean); +begin + if Initialized then + FCoreWebView2.IsMuted := aValue; +end; + +procedure TWVBrowserBase.SetDefaultDownloadDialogCornerAlignment(aValue : TWVDefaultDownloadDialogCornerAlignment); +begin + if Initialized then + FCoreWebView2.DefaultDownloadDialogCornerAlignment := aValue; +end; + +procedure TWVBrowserBase.SetDefaultDownloadDialogMargin(aValue : TPoint); +begin + if Initialized then + FCoreWebView2.DefaultDownloadDialogMargin := aValue; +end; + +procedure TWVBrowserBase.IncZoomStep; +begin + UpdateZoomStep(True); +end; + +procedure TWVBrowserBase.DecZoomStep; +begin + UpdateZoomStep(False); +end; + +procedure TWVBrowserBase.ResetZoom; +begin + ZoomStep := ZOOM_STEP_DEF; +end; + +procedure TWVBrowserBase.SetScriptEnabled(aValue: boolean); +begin + if Initialized then + FCoreWebView2Settings.IsScriptEnabled := aValue; +end; + +procedure TWVBrowserBase.SetStatusBarEnabled(aValue: boolean); +begin + if Initialized then + FCoreWebView2Settings.IsStatusBarEnabled := aValue; +end; + +procedure TWVBrowserBase.SetWebMessageEnabled(aValue: boolean); +begin + if Initialized then + FCoreWebView2Settings.IsWebMessageEnabled := aValue; +end; + +procedure TWVBrowserBase.SetZoomControlEnabled(aValue: boolean); +begin + if Initialized then + FCoreWebView2Settings.IsZoomControlEnabled := aValue; +end; + +procedure TWVBrowserBase.SetZoomFactor(const aValue: Double); +begin + if Initialized then + FCoreWebView2Controller.ZoomFactor := aValue; +end; + +procedure TWVBrowserBase.SetZoomPct(const aValue : double); +var + TempZoom : double; + i : integer; +begin + if not(Initialized) then exit; + + if (aValue >= ZoomStepValues[ZOOM_STEP_MIN]) and + (aValue <= ZoomStepValues[ZOOM_STEP_MAX]) then + begin + UpdateZoomPct(aValue); + TempZoom := ZoomPct; + + for i := ZOOM_STEP_MIN to ZOOM_STEP_MAX do + if (TempZoom = ZoomStepValues[i]) then break; + + FZoomStep := i; + end; +end; + +procedure TWVBrowserBase.SetZoomStep(aValue : byte); +begin + if not(Initialized) then exit; + + if (aValue in [ZOOM_STEP_MIN..ZOOM_STEP_MAX]) then + begin + FZoomStep := aValue; + UpdateZoomPct(ZoomStepValues[aValue]); + end; +end; + +procedure TWVBrowserBase.SetIsVisible(aValue : boolean); +begin + if Initialized then + FCoreWebView2Controller.IsVisible := aValue; +end; + +function TWVBrowserBase.Stop : boolean; +begin + Result := Initialized and + FCoreWebView2.Stop; +end; + +function TWVBrowserBase.SubscribeToDevToolsProtocolEvent(const aEventName : wvstring; aEventID : integer) : boolean; +begin + Result := Initialized and + FCoreWebView2.SubscribeToDevToolsProtocolEvent(aEventName, aEventID, self); +end; + +procedure TWVBrowserBase.doOnInitializationError(aErrorCode: HRESULT; const aErrorMessage: wvstring); +begin + if assigned(FOnInitializationError) then + FOnInitializationError(self, aErrorCode, aErrorMessage); +end; + +procedure TWVBrowserBase.doOnEnvironmentCompleted; +begin + if assigned(FOnEnvironmentCompleted) then + FOnEnvironmentCompleted(self); +end; + +procedure TWVBrowserBase.doOnControllerCompleted; +begin + if assigned(FOnControllerCompleted) then + FOnControllerCompleted(self); +end; + +procedure TWVBrowserBase.doOnAfterCreated; +begin + if assigned(FOnAfterCreated) then + FOnAfterCreated(self); +end; + +procedure TWVBrowserBase.doOnExecuteScriptCompleted(aErrorCode: HRESULT; const aResultObjectAsJson: wvstring; aExecutionID : integer); +begin + if assigned(FOnExecuteScriptCompleted) then + FOnExecuteScriptCompleted(self, aErrorCode, aResultObjectAsJson, aExecutionID); +end; + +procedure TWVBrowserBase.doOnRefreshIgnoreCacheCompleted(aErrorCode: HRESULT; const aResultObjectAsJson: wvstring); +begin + if assigned(FOnRefreshIgnoreCacheCompleted) then + FOnRefreshIgnoreCacheCompleted(self, aErrorCode, aResultObjectAsJson); +end; + +procedure TWVBrowserBase.doOnRetrieveHTMLCompleted(aErrorCode: HRESULT; const aResultObjectAsJson: wvstring); +var + TempResult : wvstring; +begin + if succeeded(aErrorCode) and assigned(FOnRetrieveHTMLCompleted) then + begin + TempResult := ExtractEncodedJSON(aResultObjectAsJson); + FOnRetrieveHTMLCompleted(self, length(TempResult) > 0, TempResult); + end; +end; + +procedure TWVBrowserBase.doOnRetrieveTextCompleted(aErrorCode: HRESULT; const aResultObjectAsJson: wvstring); +var + TempResult : wvstring; +begin + if succeeded(aErrorCode) and assigned(FOnRetrieveTextCompleted) then + begin + TempResult := ExtractEncodedJSON(aResultObjectAsJson); + FOnRetrieveTextCompleted(self, length(TempResult) > 0, TempResult); + end; +end; + +procedure TWVBrowserBase.doCapturePreviewCompleted(aErrorCode: HRESULT); +begin + if assigned(FOnCapturePreviewCompleted) then + FOnCapturePreviewCompleted(self, aErrorCode); +end; + +procedure TWVBrowserBase.doOnNavigationStarting(const sender: ICoreWebView2; const args: ICoreWebView2NavigationStartingEventArgs); +begin + if assigned(FOnNavigationStarting) then + FOnNavigationStarting(self, sender, args); +end; + +procedure TWVBrowserBase.doOnNavigationCompleted(const sender: ICoreWebView2; const args: ICoreWebView2NavigationCompletedEventArgs); +begin + if assigned(FOnNavigationCompleted) then + FOnNavigationCompleted(self, sender, args); +end; + +procedure TWVBrowserBase.doOnFrameNavigationStarting(const sender: ICoreWebView2; const args: ICoreWebView2NavigationStartingEventArgs); +begin + if assigned(FOnFrameNavigationStarting) then + FOnFrameNavigationStarting(self, sender, args); +end; + +procedure TWVBrowserBase.doOnFrameNavigationCompleted(const sender: ICoreWebView2; const args: ICoreWebView2NavigationCompletedEventArgs); +begin + if assigned(FOnFrameNavigationCompleted) then + FOnFrameNavigationCompleted(self, sender, args); +end; + +procedure TWVBrowserBase.doOnSourceChanged(const sender: ICoreWebView2; const args: ICoreWebView2SourceChangedEventArgs); +begin + if assigned(FOnSourceChanged) then + FOnSourceChanged(self, sender, args); +end; + +procedure TWVBrowserBase.doOnHistoryChanged(const sender: ICoreWebView2); +begin + if assigned(FOnHistoryChanged) then + FOnHistoryChanged(self); +end; + +procedure TWVBrowserBase.doOnContentLoading(const sender: ICoreWebView2; const args: ICoreWebView2ContentLoadingEventArgs); +begin + if assigned(FOnContentLoading) then + FOnContentLoading(self, sender, args); +end; + +procedure TWVBrowserBase.doOnDocumentTitleChanged(const sender: ICoreWebView2); +begin + if assigned(FOnDocumentTitleChanged) then + FOnDocumentTitleChanged(self); +end; + +procedure TWVBrowserBase.doOnNewWindowRequested(const sender: ICoreWebView2; const args: ICoreWebView2NewWindowRequestedEventArgs); +begin + if assigned(FOnNewWindowRequested) then + FOnNewWindowRequested(self, sender, args); +end; + +procedure TWVBrowserBase.doOnWebResourceRequested(const sender: ICoreWebView2; const args: ICoreWebView2WebResourceRequestedEventArgs); +begin + if assigned(FOnWebResourceRequested) then + FOnWebResourceRequested(self, sender, args); +end; + +procedure TWVBrowserBase.doOnScriptDialogOpening(const sender: ICoreWebView2; const args: ICoreWebView2ScriptDialogOpeningEventArgs); +begin + if assigned(FOnScriptDialogOpening) then + FOnScriptDialogOpening(self, sender, args); +end; + +procedure TWVBrowserBase.doOnPermissionRequested(const sender: ICoreWebView2; const args: ICoreWebView2PermissionRequestedEventArgs); +begin + if assigned(FOnPermissionRequested) then + FOnPermissionRequested(self, sender, args); +end; + +procedure TWVBrowserBase.doOnProcessFailed(const sender: ICoreWebView2; const args: ICoreWebView2ProcessFailedEventArgs); +begin + if assigned(FOnProcessFailed) then + FOnProcessFailed(self, sender, args); +end; + +procedure TWVBrowserBase.doOnWebMessageReceived(const sender: ICoreWebView2; const args: ICoreWebView2WebMessageReceivedEventArgs); +begin + if assigned(FOnWebMessageReceived) then + FOnWebMessageReceived(self, sender, args); +end; + +procedure TWVBrowserBase.doOnContainsFullScreenElementChanged(const sender: ICoreWebView2); +begin + if assigned(FOnContainsFullScreenElementChanged) then + FOnContainsFullScreenElementChanged(self); +end; + +procedure TWVBrowserBase.doOnWindowCloseRequested(const sender: ICoreWebView2); +begin + if assigned(FOnWindowCloseRequested) then + FOnWindowCloseRequested(self); +end; + +procedure TWVBrowserBase.doOnDevToolsProtocolEventReceived(const sender: ICoreWebView2; const args: ICoreWebView2DevToolsProtocolEventReceivedEventArgs; const aEventName : wvstring; aEventID : integer); +begin + if assigned(FOnDevToolsProtocolEventReceived) then + FOnDevToolsProtocolEventReceived(self, sender, args, aEventName, aEventID); +end; + +procedure TWVBrowserBase.doOnZoomFactorChanged(const sender: ICoreWebView2Controller); +begin + if assigned(FOnZoomFactorChanged) then + FOnZoomFactorChanged(self); +end; + +procedure TWVBrowserBase.doOnMoveFocusRequested(const sender: ICoreWebView2Controller; const args: ICoreWebView2MoveFocusRequestedEventArgs); +begin + if assigned(FOnMoveFocusRequested) then + FOnMoveFocusRequested(self, sender, args); +end; + +procedure TWVBrowserBase.doOnAcceleratorKeyPressed(const sender: ICoreWebView2Controller; const args: ICoreWebView2AcceleratorKeyPressedEventArgs); +begin + if assigned(FOnAcceleratorKeyPressed) then + FOnAcceleratorKeyPressed(self, sender, args); +end; + +procedure TWVBrowserBase.doOnGotFocus(const sender: ICoreWebView2Controller); +begin + if assigned(FOnGotFocus) then + FOnGotFocus(self); +end; + +procedure TWVBrowserBase.doOnLostFocus(const sender: ICoreWebView2Controller); +begin + if assigned(FOnLostFocus) then + FOnLostFocus(self); +end; + +procedure TWVBrowserBase.doOnCompositionControllerCompleted; +begin + if assigned(FOnCompositionControllerCompleted) then + FOnCompositionControllerCompleted(self); +end; + +procedure TWVBrowserBase.doOnCursorChangedEvent(const sender: ICoreWebView2CompositionController); +begin + if assigned(FOnCursorChanged) then + FOnCursorChanged(self); +end; + +procedure TWVBrowserBase.doOnBrowserProcessExitedEvent(const sender: ICoreWebView2Environment; const args: ICoreWebView2BrowserProcessExitedEventArgs); +begin + if assigned(FOnBrowserProcessExited) then + FOnBrowserProcessExited(self, sender, args); +end; + +procedure TWVBrowserBase.doOnRasterizationScaleChangedEvent(const sender: ICoreWebView2Controller); +begin + if assigned(FOnRasterizationScaleChanged) then + FOnRasterizationScaleChanged(self); +end; + +procedure TWVBrowserBase.doOnWebResourceResponseReceivedEvent(const sender: ICoreWebView2; const args: ICoreWebView2WebResourceResponseReceivedEventArgs); +begin + if assigned(FOnWebResourceResponseReceived) then + FOnWebResourceResponseReceived(self, sender, args); +end; + +procedure TWVBrowserBase.doOnDOMContentLoadedEvent(const sender: ICoreWebView2; const args: ICoreWebView2DOMContentLoadedEventArgs); +begin + if assigned(FOnDOMContentLoaded) then + FOnDOMContentLoaded(self, sender, args); +end; + +procedure TWVBrowserBase.doOnWebResourceResponseViewGetContentCompletedEvent(errorCode: HResult; const result_: IStream; aResourceID : integer); +begin + if assigned(FOnWebResourceResponseViewGetContentCompleted) then + FOnWebResourceResponseViewGetContentCompleted(self, errorCode, result_, aResourceID); +end; + +procedure TWVBrowserBase.doOnGetCookiesCompletedEvent(errorCode: HResult; const result_ : ICoreWebView2CookieList); +begin + if assigned(FOnGetCookiesCompleted) then + FOnGetCookiesCompleted(self, errorCode, result_); +end; + +procedure TWVBrowserBase.doOnTrySuspendCompletedEvent(errorCode: HResult; result_: Integer); +begin + if assigned(FOnTrySuspendCompleted) then + FOnTrySuspendCompleted(self, errorCode, (result_ <> 0)); +end; + +procedure TWVBrowserBase.doOnFrameCreatedEvent(const sender: ICoreWebView2; const args: ICoreWebView2FrameCreatedEventArgs); +begin + if assigned(FOnFrameCreated) then + FOnFrameCreated(self, sender, args); +end; + +procedure TWVBrowserBase.doOnDownloadStartingEvent(const sender: ICoreWebView2; const args: ICoreWebView2DownloadStartingEventArgs); +begin + if assigned(FOnDownloadStarting) then + FOnDownloadStarting(self, sender, args); +end; + +procedure TWVBrowserBase.doOnClientCertificateRequestedEvent(const sender: ICoreWebView2; const args: ICoreWebView2ClientCertificateRequestedEventArgs); +begin + if assigned(FOnClientCertificateRequested) then + FOnClientCertificateRequested(self, sender, args); +end; + +procedure TWVBrowserBase.doOnPrintToPdfCompletedEvent(errorCode: HResult; result_: Integer); +begin + if assigned(FOnPrintToPdfCompleted) then + FOnPrintToPdfCompleted(self, errorCode, (result_ <> 0)); +end; + +procedure TWVBrowserBase.doOnBytesReceivedChangedEventEvent(const sender: ICoreWebView2DownloadOperation; const args: IUnknown; aDownloadID : integer); +begin + if assigned(FOnBytesReceivedChanged) then + FOnBytesReceivedChanged(self, sender, aDownloadID); +end; + +procedure TWVBrowserBase.doOnEstimatedEndTimeChangedEvent(const sender: ICoreWebView2DownloadOperation; const args: IUnknown; aDownloadID : integer); +begin + if assigned(FOnEstimatedEndTimeChanged) then + FOnEstimatedEndTimeChanged(self, sender, aDownloadID); +end; + +procedure TWVBrowserBase.doOnStateChangedEvent(const sender: ICoreWebView2DownloadOperation; const args: IUnknown; aDownloadID : integer); +begin + if assigned(FOnDownloadStateChanged) then + FOnDownloadStateChanged(self, sender, aDownloadID); +end; + +procedure TWVBrowserBase.doOnFrameNameChangedEvent(const sender: ICoreWebView2Frame; const args: IUnknown; aFrameID : cardinal); +begin + if assigned(FOnFrameNameChanged) then + FOnFrameNameChanged(self, sender, aFrameID); +end; + +procedure TWVBrowserBase.doOnFrameDestroyedEvent(const sender: ICoreWebView2Frame; const args: IUnknown; aFrameID : cardinal); +begin + if assigned(FOnFrameDestroyed) then + FOnFrameDestroyed(self, sender, aFrameID); +end; + +procedure TWVBrowserBase.doOnCallDevToolsProtocolMethodCompletedEvent(aErrorCode: HRESULT; const aResult: wvstring; aExecutionID : integer); +begin + if assigned(FOnCallDevToolsProtocolMethodCompleted) then + FOnCallDevToolsProtocolMethodCompleted(self, aErrorCode, aResult, aExecutionID); +end; + +procedure TWVBrowserBase.doOnAddScriptToExecuteOnDocumentCreatedCompletedEvent(aErrorCode: HRESULT; const aResult : wvstring); +begin + if assigned(FOnAddScriptToExecuteOnDocumentCreatedCompleted) then + FOnAddScriptToExecuteOnDocumentCreatedCompleted(self, aErrorCode, aResult); +end; + +procedure TWVBrowserBase.CalculateZoomStep; +var + TempPct, TempDelta, TempBest : double; + i, TempStep : integer; +begin + TempPct := ZoomPct; + TempStep := ZOOM_STEP_DEF; + TempBest := 10000; + i := ZOOM_STEP_MIN; + + while (i <= ZOOM_STEP_MAX) do + begin + TempDelta := abs(ZoomStepValues[i] - TempPCt); + + if (TempBest > TempDelta) then + begin + TempBest := TempDelta; + TempStep := i; + end + else + if (TempBest < TempDelta) then + break; + + inc(i); + end; + + FZoomStep := TempStep; +end; + +procedure TWVBrowserBase.UpdateZoomStep(aInc : boolean); +var + TempPct, TempPrev, TempNext : double; + i : integer; +begin + if not(Initialized) then exit; + + if (FZoomStep in [ZOOM_STEP_MIN..ZOOM_STEP_MAX]) then + begin + if aInc then + begin + if (FZoomStep < ZOOM_STEP_MAX) then + begin + inc(FZoomStep); + UpdateZoomPct(ZoomStepValues[FZoomStep]); + end; + end + else + if (FZoomStep > ZOOM_STEP_MIN) then + begin + dec(FZoomStep); + UpdateZoomPct(ZoomStepValues[FZoomStep]); + end; + end + else + begin + TempPct := ZoomPct; + TempPrev := 0; + i := ZOOM_STEP_MIN; + + repeat + if (i <= ZOOM_STEP_MAX) then + TempNext := ZoomStepValues[i] + else + TempNext := ZoomStepValues[ZOOM_STEP_MAX] * 2; + + if (TempPct > TempPrev) and (TempPct < TempNext) then + begin + if aInc then + begin + if (i <= ZOOM_STEP_MAX) then + begin + FZoomStep := i; + UpdateZoomPct(ZoomStepValues[FZoomStep]); + end; + end + else + if (i > ZOOM_STEP_MIN) then + begin + FZoomStep := pred(i); + UpdateZoomPct(ZoomStepValues[FZoomStep]); + end; + + i := ZOOM_STEP_MAX + 2; + end + else + begin + TempPrev := TempNext; + inc(i); + end; + + until (i > succ(ZOOM_STEP_MAX)); + end; +end; + +procedure TWVBrowserBase.UpdateZoomPct(const aValue : double); +begin + if (aValue > 0) then + ZoomFactor := aValue / 100; +end; + +function TWVBrowserBase.SimulateEditingCommand(aEditingCommand : TWV2EditingCommand): boolean; +var + TempParams : wvstring; +begin + TempParams := '{"type": "char", "commands": ["' + EditingCommandToString(aEditingCommand) + '"]}'; + Result := CallDevToolsProtocolMethod('Input.dispatchKeyEvent', TempParams, WEBVIEW4DELPHI_DEVTOOLS_SIMULATEKEYEVENT_ID); +end; + +function TWVBrowserBase.SimulateKeyEvent( type_ : TWV2KeyEventType; + modifiers : integer; + windowsVirtualKeyCode : integer; + nativeVirtualKeyCode : integer; + timestamp : integer; + location : integer; + autoRepeat : boolean; + isKeypad : boolean; + isSystemKey : boolean; + const text : wvstring; + const unmodifiedtext : wvstring; + const keyIdentifier : wvstring; + const code : wvstring; + const key : wvstring): boolean; +var + TempParams : wvstring; +begin + TempParams := '{"type": '; + + case type_ of + ketKeyDown : TempParams := TempParams + '"keyDown"'; + ketKeyUp : TempParams := TempParams + '"keyUp"'; + ketRawKeyDown : TempParams := TempParams + '"rawKeyDown"'; + ketChar : TempParams := TempParams + '"char"'; + end; + + if (modifiers <> 0) then + TempParams := TempParams + ', "modifiers": ' + {$IFDEF FPC}UTF8Decode({$ENDIF}inttostr(modifiers){$IFDEF FPC}){$ENDIF}; + + if (timestamp <> 0) then + TempParams := TempParams + ', "timestamp": ' + {$IFDEF FPC}UTF8Decode({$ENDIF}inttostr(timestamp){$IFDEF FPC}){$ENDIF}; + + if (length(text) > 0) then + TempParams := TempParams + ', "text": "' + JSONEscape(text) + '"'; + + if (length(unmodifiedtext) > 0) then + TempParams := TempParams + ', "unmodifiedtext": "' + JSONEscape(unmodifiedtext) + '"'; + + if (length(keyIdentifier) > 0) then + TempParams := TempParams + ', "keyIdentifier": "' + JSONEscape(keyIdentifier) + '"'; + + if (length(code) > 0) then + TempParams := TempParams + ', "code": "' + JSONEscape(code) + '"'; + + if (length(key) > 0) then + TempParams := TempParams + ', "key": "' + JSONEscape(key) + '"'; + + if (windowsVirtualKeyCode <> 0) then + TempParams := TempParams + ', "windowsVirtualKeyCode": ' + {$IFDEF FPC}UTF8Decode({$ENDIF}inttostr(windowsVirtualKeyCode){$IFDEF FPC}){$ENDIF}; + + if (nativeVirtualKeyCode <> 0) then + TempParams := TempParams + ', "nativeVirtualKeyCode": ' + {$IFDEF FPC}UTF8Decode({$ENDIF}inttostr(nativeVirtualKeyCode){$IFDEF FPC}){$ENDIF}; + + if autoRepeat then + TempParams := TempParams + ', "autoRepeat": true'; + + if isKeypad then + TempParams := TempParams + ', "isKeypad": true'; + + if isSystemKey then + TempParams := TempParams + ', "isSystemKey": true'; + + if (location <> 0) then + TempParams := TempParams + ', "location": ' + {$IFDEF FPC}UTF8Decode({$ENDIF}inttostr(location){$IFDEF FPC}){$ENDIF}; + + TempParams := TempParams + '}'; + + Result := CallDevToolsProtocolMethod('Input.dispatchKeyEvent', TempParams, WEBVIEW4DELPHI_DEVTOOLS_SIMULATEKEYEVENT_ID); +end; + +function TWVBrowserBase.KeyboardShortcutSearch : boolean; +begin + Result := SimulateKeyEvent(ketRawKeyDown, $100, VK_F3, integer($003D0001)) and + SimulateKeyEvent(ketKeyUp, $100, VK_F3, integer($C03D0001)); +end; + +function TWVBrowserBase.KeyboardShortcutRefreshIgnoreCache : boolean; +begin + Result := SimulateKeyEvent(ketRawKeyDown, $502, VK_Shift, integer($002A0001)) and + SimulateKeyEvent(ketRawKeyDown, $102, VK_F5, integer($003F0001)) and + SimulateKeyEvent(ketKeyUp, $102, VK_F5, integer($C03F0001)) and + SimulateKeyEvent(ketKeyUp, $100, VK_Shift, integer($C02A0001)); +end; + +function TWVBrowserBase.SendMouseInput(aEventKind : TWVMouseEventKind; aVirtualKeys : TWVMouseEventVirtualKeys; aMouseData : cardinal; aPoint : TPoint) : boolean; +begin + Result := FUseCompositionController and + Initialized and + FCoreWebView2CompositionController.SendMouseInput(aEventKind, aVirtualKeys, aMouseData, aPoint); +end; + +function TWVBrowserBase.SendPointerInput(aEventKind : TWVPointerEventKind; const aPointerInfo : ICoreWebView2PointerInfo) : boolean; +begin + Result := FUseCompositionController and + Initialized and + FCoreWebView2CompositionController.SendPointerInput(aEventKind, aPointerInfo); +end; + +function TWVBrowserBase.DragLeave : HResult; +begin + Result := S_OK; + + if FUseCompositionController and Initialized then + Result := FCoreWebView2CompositionController.DragLeave; +end; + +{$WARN SYMBOL_DEPRECATED OFF} +function TWVBrowserBase.DragEnter(const dataObject: IDataObject; keyState: LongWord; point: TPoint; out effect: LongWord) : HResult; +var + TempPoint : tagPoint; // ICoreWebView2CompositionController3 uses tagPoint. We ignore the warning. +begin + Result := S_OK; + effect := DROPEFFECT_NONE; + + TempPoint.x := point.X; + TempPoint.y := point.Y; + + if FUseCompositionController and Initialized then + Result := FCoreWebView2CompositionController.DragEnter(dataObject, keyState, TempPoint, effect); +end; + +function TWVBrowserBase.DragOver(keyState: LongWord; point: TPoint; out effect: LongWord) : HResult; +var + TempPoint : tagPoint; // ICoreWebView2CompositionController3 uses tagPoint. We ignore the warning. +begin + Result := S_OK; + effect := DROPEFFECT_NONE; + + TempPoint.x := point.X; + TempPoint.y := point.Y; + + if FUseCompositionController and Initialized then + Result := FCoreWebView2CompositionController.DragOver(keyState, TempPoint, effect); +end; + +function TWVBrowserBase.Drop(const dataObject: IDataObject; keyState: LongWord; point: TPoint; out effect: LongWord) : HResult; +var + TempPoint : tagPoint; // ICoreWebView2CompositionController3 uses tagPoint. We ignore the warning. +begin + Result := S_OK; + effect := DROPEFFECT_NONE; + + if FUseCompositionController and Initialized then + begin + TempPoint.x := point.X; + TempPoint.y := point.Y; + Result := FCoreWebView2CompositionController.Drop(dataObject, keyState, TempPoint, effect); + end; +end; +{$WARN SYMBOL_DEPRECATED ON} + +function TWVBrowserBase.GetNonClientRegionAtPoint(point: TPoint) : TWVNonClientRegionKind; +begin + if FUseCompositionController and Initialized then + Result := FCoreWebView2CompositionController.GetNonClientRegionAtPoint(point) + else + Result := COREWEBVIEW2_NON_CLIENT_REGION_KIND_NOWHERE; +end; + +function TWVBrowserBase.QueryNonClientRegion(Kind: TWVNonClientRegionKind): ICoreWebView2RegionRectCollectionView; +begin + if FUseCompositionController and Initialized then + Result := FCoreWebView2CompositionController.QueryNonClientRegion(Kind) + else + Result := nil; +end; + +function TWVBrowserBase.ClearBrowsingData(dataKinds: TWVBrowsingDataKinds): boolean; +begin + Result := Initialized and + assigned(FCoreWebView2Profile) and + FCoreWebView2Profile.ClearBrowsingData(dataKinds, FClearBrowsingDataCompletedHandler); +end; + +function TWVBrowserBase.ClearBrowsingDataInTimeRange(dataKinds: TWVBrowsingDataKinds; const startTime, endTime: TDateTime): boolean; +begin + Result := Initialized and + assigned(FCoreWebView2Profile) and + FCoreWebView2Profile.ClearBrowsingDataInTimeRange(dataKinds, startTime, endTime, FClearBrowsingDataCompletedHandler); +end; + +function TWVBrowserBase.ClearBrowsingDataAll: boolean; +begin + Result := Initialized and + assigned(FCoreWebView2Profile) and + FCoreWebView2Profile.ClearBrowsingDataAll(FClearBrowsingDataCompletedHandler); +end; + +function TWVBrowserBase.SetPermissionState(aPermissionKind: TWVPermissionKind; const aOrigin: wvstring; aState: TWVPermissionState) : boolean; +begin + Result := Initialized and + assigned(FCoreWebView2Profile) and + FCoreWebView2Profile.SetPermissionState(aPermissionKind, aOrigin, aState, FSetPermissionStateCompletedHandler); +end; + +function TWVBrowserBase.GetNonDefaultPermissionSettings: boolean; +begin + Result := Initialized and + assigned(FCoreWebView2Profile) and + FCoreWebView2Profile.GetNonDefaultPermissionSettings(FGetNonDefaultPermissionSettingsCompletedHandler); +end; + +function TWVBrowserBase.AddBrowserExtension(const extensionFolderPath: wvstring): boolean; +begin + Result := Initialized and + assigned(FCoreWebView2Profile) and + FCoreWebView2Profile.AddBrowserExtension(extensionFolderPath, FProfileAddBrowserExtensionCompletedHandler); +end; + +function TWVBrowserBase.GetBrowserExtensions: boolean; +begin + Result := Initialized and + assigned(FCoreWebView2Profile) and + FCoreWebView2Profile.GetBrowserExtensions(FProfileGetBrowserExtensionsCompletedHandler); +end; + +function TWVBrowserBase.DeleteProfile: boolean; +begin + Result := Initialized and + assigned(FCoreWebView2Profile) and + FCoreWebView2Profile.Delete; +end; + +function TWVBrowserBase.GetProfileName : wvstring; +begin + if Initialized and assigned(FCoreWebView2Profile) then + Result := FCoreWebView2Profile.ProfileName + else + Result := ''; +end; + +function TWVBrowserBase.GetIsInPrivateModeEnabled : boolean; +begin + if Initialized and assigned(FCoreWebView2Profile) then + Result := FCoreWebView2Profile.IsInPrivateModeEnabled + else + Result := FIsInPrivateModeEnabled; +end; + +function TWVBrowserBase.GetProfilePath : wvstring; +begin + if Initialized and assigned(FCoreWebView2Profile) then + Result := FCoreWebView2Profile.ProfilePath + else + Result := ''; +end; + +function TWVBrowserBase.GetDefaultDownloadFolderPath : wvstring; +begin + if Initialized and assigned(FCoreWebView2Profile) then + Result := FCoreWebView2Profile.DefaultDownloadFolderPath + else + Result := ''; +end; + +procedure TWVBrowserBase.SetDefaultDownloadFolderPath(const aValue : wvstring); +begin + if Initialized and assigned(FCoreWebView2Profile) then + FCoreWebView2Profile.DefaultDownloadFolderPath := aValue; +end; + +function TWVBrowserBase.GetPreferredColorScheme : TWVPreferredColorScheme; +begin + if Initialized and assigned(FCoreWebView2Profile) then + Result := FCoreWebView2Profile.PreferredColorScheme + else + Result := COREWEBVIEW2_PREFERRED_COLOR_SCHEME_AUTO; +end; + +procedure TWVBrowserBase.SetPreferredColorScheme(const aValue : TWVPreferredColorScheme); +begin + if Initialized and assigned(FCoreWebView2Profile) then + FCoreWebView2Profile.PreferredColorScheme := aValue; +end; + +function TWVBrowserBase.GetPreferredTrackingPreventionLevel : TWVTrackingPreventionLevel; +begin + if Initialized and assigned(FCoreWebView2Profile) then + Result := FCoreWebView2Profile.PreferredTrackingPreventionLevel + else + Result := COREWEBVIEW2_TRACKING_PREVENTION_LEVEL_BALANCED; +end; + +function TWVBrowserBase.GetProfileCookieManager : ICoreWebView2CookieManager; +begin + if Initialized and assigned(FCoreWebView2Profile) then + Result := FCoreWebView2Profile.CookieManager + else + Result := nil; +end; + +function TWVBrowserBase.GetProfileIsPasswordAutosaveEnabled : boolean; +begin + Result := Initialized and + assigned(FCoreWebView2Profile) and + FCoreWebView2Profile.IsPasswordAutosaveEnabled; +end; + +function TWVBrowserBase.GetProfileIsGeneralAutofillEnabled : boolean; +begin + Result := Initialized and + assigned(FCoreWebView2Profile) and + FCoreWebView2Profile.IsGeneralAutofillEnabled; +end; + +procedure TWVBrowserBase.SetPreferredTrackingPreventionLevel(const aValue : TWVTrackingPreventionLevel); +begin + if Initialized and assigned(FCoreWebView2Profile) then + FCoreWebView2Profile.PreferredTrackingPreventionLevel := aValue; +end; + +procedure TWVBrowserBase.SetProfileIsPasswordAutosaveEnabled(aValue : boolean); +begin + if Initialized and assigned(FCoreWebView2Profile) then + FCoreWebView2Profile.IsPasswordAutosaveEnabled := aValue; +end; + +procedure TWVBrowserBase.SetProfileIsGeneralAutofillEnabled(aValue : boolean); +begin + if Initialized and assigned(FCoreWebView2Profile) then + FCoreWebView2Profile.IsGeneralAutofillEnabled := aValue; +end; + +procedure TWVBrowserBase.SetMemoryUsageTargetLevel(aValue : TWVMemoryUsageTargetLevel); +begin + if Initialized then + FCoreWebView2.MemoryUsageTargetLevel := aValue; +end; + +procedure TWVBrowserBase.SetAreWebViewScriptApisEnabledForServiceWorkers(aValue : boolean); +begin + if Initialized and assigned(FCoreWebView2Profile) then + FCoreWebView2Profile.AreWebViewScriptApisEnabledForServiceWorkers := aValue; +end; + +function TWVBrowserBase.CreateSharedBuffer(aSize : Largeuint; var aSharedBuffer : ICoreWebView2SharedBuffer) : boolean; +begin + Result := Initialized and + FCoreWebView2Environment.CreateSharedBuffer(aSize, aSharedBuffer); +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVConstants.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVConstants.pas new file mode 100644 index 000000000..e836e20e4 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVConstants.pas @@ -0,0 +1,98 @@ +unit uRESTDWPrivWVConstants; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +interface + +const + {$I uWVVersion.inc} + + CRLF = #13 + #10; + + {$IF NOT DECLARED(USER_DEFAULT_SCREEN_DPI)} + USER_DEFAULT_SCREEN_DPI = 96; + {$IFEND} + + {* + These constants are declared in the "Windows" unit but + some old Delphi versions don't have them. + We have to add "WV2_" to be compatible with C++ Builder. + *} + WV2_IMAGE_FILE_MACHINE_I386 = $014C; + WV2_IMAGE_FILE_MACHINE_AMD64 = $8664; + + ZOOM_STEP_25 = 0; + ZOOM_STEP_33 = 1; + ZOOM_STEP_50 = 2; + ZOOM_STEP_67 = 3; + ZOOM_STEP_75 = 4; + ZOOM_STEP_90 = 5; + ZOOM_STEP_100 = 6; + ZOOM_STEP_110 = 7; + ZOOM_STEP_125 = 8; + ZOOM_STEP_150 = 9; + ZOOM_STEP_175 = 10; + ZOOM_STEP_200 = 11; + ZOOM_STEP_250 = 12; + ZOOM_STEP_300 = 13; + ZOOM_STEP_400 = 14; + ZOOM_STEP_500 = 15; + ZOOM_STEP_UNK = 16; + ZOOM_STEP_MIN = ZOOM_STEP_25; + ZOOM_STEP_MAX = ZOOM_STEP_500; + ZOOM_STEP_DEF = ZOOM_STEP_100; + + ZOOM_PCT_DELTA = 5; + + ZoomStepValues : array[ZOOM_STEP_MIN..ZOOM_STEP_MAX] of integer = (25, 33, 50, 67, 75, 90, 100, 110, 125, 150, 175, 200, 250, 300, 400, 500); + + URI_ABOUTBLANK = 'about:blank'; + + {* Reserved IDs used in some JavaScript functions *} + WEBVIEW4DELPHI_JS_FIRST_ID = 10000; + WEBVIEW4DELPHI_JS_RETRIEVEHTMLJOB_ID = WEBVIEW4DELPHI_JS_FIRST_ID; + WEBVIEW4DELPHI_JS_RETRIEVETEXTJOB_ID = WEBVIEW4DELPHI_JS_FIRST_ID + 1; + WEBVIEW4DELPHI_JS_LAST_ID = WEBVIEW4DELPHI_JS_FIRST_ID + 100; + + {* Reserved IDs used in some DevTools functions *} + WEBVIEW4DELPHI_DEVTOOLS_FIRST_ID = 10000; + WEBVIEW4DELPHI_DEVTOOLS_RETRIEVEMHTML_ID = WEBVIEW4DELPHI_DEVTOOLS_FIRST_ID; + WEBVIEW4DELPHI_DEVTOOLS_CLEARBROWSERCACHE_ID = WEBVIEW4DELPHI_DEVTOOLS_FIRST_ID + 1; + WEBVIEW4DELPHI_DEVTOOLS_CLEARDATAFORORIGIN_ID = WEBVIEW4DELPHI_DEVTOOLS_FIRST_ID + 2; + WEBVIEW4DELPHI_DEVTOOLS_EMULATENETWORKCONDITIONS_ID = WEBVIEW4DELPHI_DEVTOOLS_FIRST_ID + 3; + WEBVIEW4DELPHI_DEVTOOLS_SETIGNORECERTIFICATEERRORS_ID = WEBVIEW4DELPHI_DEVTOOLS_FIRST_ID + 4; + WEBVIEW4DELPHI_DEVTOOLS_SIMULATEKEYEVENT_ID = WEBVIEW4DELPHI_DEVTOOLS_FIRST_ID + 5; + WEBVIEW4DELPHI_DEVTOOLS_REFRESH_ID = WEBVIEW4DELPHI_DEVTOOLS_FIRST_ID + 6; + WEBVIEW4DELPHI_DEVTOOLS_LAST_ID = WEBVIEW4DELPHI_DEVTOOLS_FIRST_ID + 100; + + WEBVIEW4DELPHI_PRINT_PAGESPERSIDE_1 = 1; + WEBVIEW4DELPHI_PRINT_PAGESPERSIDE_2 = 2; + WEBVIEW4DELPHI_PRINT_PAGESPERSIDE_4 = 4; + WEBVIEW4DELPHI_PRINT_PAGESPERSIDE_6 = 6; + WEBVIEW4DELPHI_PRINT_PAGESPERSIDE_9 = 9; + WEBVIEW4DELPHI_PRINT_PAGESPERSIDE_16 = 16; + WEBVIEW4DELPHI_PRINT_PAGESPERSIDE_DEFAULT = WEBVIEW4DELPHI_PRINT_PAGESPERSIDE_1; + WEBVIEW4DELPHI_PRINT_PAGESPERSIDE_VALID = [WEBVIEW4DELPHI_PRINT_PAGESPERSIDE_1, + WEBVIEW4DELPHI_PRINT_PAGESPERSIDE_2, + WEBVIEW4DELPHI_PRINT_PAGESPERSIDE_4, + WEBVIEW4DELPHI_PRINT_PAGESPERSIDE_6, + WEBVIEW4DELPHI_PRINT_PAGESPERSIDE_9, + WEBVIEW4DELPHI_PRINT_PAGESPERSIDE_16]; + + WEBVIEW4DELPHI_PRINT_COPIES_DEFAULT = 1; + + WEBVIEW4DELPHI_INVALID_FRAMEID = 0; + + {$IF NOT DECLARED(HWND_MESSAGE)} + HWND_MESSAGE = System.THandle(-3); + {$IFEND} + + WV_URLS_URL = 'edge://edge-urls'; + WV_FLAGS_URL = 'edge://flags'; + WV_DOWNLOADS_URL = 'edge://downloads'; + WV_EXTENSIONS_URL = 'edge://extensions'; + WV_CRASHES_URL = 'edge://crashes'; + +implementation + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2.pas new file mode 100644 index 000000000..84fcb0a02 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2.pas @@ -0,0 +1,2652 @@ +unit uRESTDWPrivWVCoreWebView2; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + System.Classes, Winapi.ActiveX, System.SysUtils, System.Types, + {$ELSE} + Classes, ActiveX, SysUtils, Types, + {$ENDIF} + uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVTypes; + +type + TCoreWebView2 = class + protected + FBaseIntf : ICoreWebView2; + FBaseIntf2 : ICoreWebView2_2; + FBaseIntf3 : ICoreWebView2_3; + FBaseIntf4 : ICoreWebView2_4; + FBaseIntf5 : ICoreWebView2_5; + FBaseIntf6 : ICoreWebView2_6; + FBaseIntf7 : ICoreWebView2_7; + FBaseIntf8 : ICoreWebView2_8; + FBaseIntf9 : ICoreWebView2_9; + FBaseIntf10 : ICoreWebView2_10; + FBaseIntf11 : ICoreWebView2_11; + FBaseIntf12 : ICoreWebView2_12; + FBaseIntf13 : ICoreWebView2_13; + FBaseIntf14 : ICoreWebView2_14; + FBaseIntf15 : ICoreWebView2_15; + FBaseIntf16 : ICoreWebView2_16; + FBaseIntf17 : ICoreWebView2_17; + FBaseIntf18 : ICoreWebView2_18; + FBaseIntf19 : ICoreWebView2_19; + FBaseIntf20 : ICoreWebView2_20; + FBaseIntf21 : ICoreWebView2_21; + FBaseIntf22 : ICoreWebView2_22; + FBaseIntf23 : ICoreWebView2_23; + FBaseIntf24 : ICoreWebView2_24; + FBaseIntf25 : ICoreWebView2_25; + FBaseIntf26 : ICoreWebView2_26; + FBaseIntf27 : ICoreWebView2_27; + FBaseIntf28 : ICoreWebView2_28; + FBaseIntf29 : ICoreWebView2_29; + FContainsFullScreenElementChangedToken : EventRegistrationToken; + FContentLoadingToken : EventRegistrationToken; + FDocumentTitleChangedToken : EventRegistrationToken; + FFrameNavigationStartingToken : EventRegistrationToken; + FFrameNavigationCompletedToken : EventRegistrationToken; + FHistoryChangedToken : EventRegistrationToken; + FNavigationStartingToken : EventRegistrationToken; + FNavigationCompletedToken : EventRegistrationToken; + FNewWindowRequestedToken : EventRegistrationToken; + FPermissionRequestedToken : EventRegistrationToken; + FProcessFailedToken : EventRegistrationToken; + FScriptDialogOpeningToken : EventRegistrationToken; + FSourceChangedToken : EventRegistrationToken; + FWebResourceRequestedToken : EventRegistrationToken; + FWebMessageReceivedToken : EventRegistrationToken; + FWindowCloseRequestedToken : EventRegistrationToken; + FWebResourceResponseReceivedToken : EventRegistrationToken; + FDOMContentLoadedToken : EventRegistrationToken; + FFrameCreatedToken : EventRegistrationToken; + FDownloadStartingToken : EventRegistrationToken; + FClientCertificateRequestedToken : EventRegistrationToken; + FIsMutedChangedToken : EventRegistrationToken; + FIsDocumentPlayingAudioChangedToken : EventRegistrationToken; + FIsDefaultDownloadDialogOpenChangedToken : EventRegistrationToken; + FBasicAuthenticationRequestedToken : EventRegistrationToken; + FContextMenuRequestedToken : EventRegistrationToken; + FStatusBarTextChangedToken : EventRegistrationToken; + FServerCertificateErrorDetectedToken : EventRegistrationToken; + FFaviconChangedToken : EventRegistrationToken; + FLaunchingExternalUriSchemeToken : EventRegistrationToken; + FNotificationReceivedToken : EventRegistrationToken; + FSaveAsUIShowingToken : EventRegistrationToken; + FSaveFileSecurityCheckStartingToken : EventRegistrationToken; + FScreenCaptureStartingToken : EventRegistrationToken; + FDedicatedWorkerCreatedToken : EventRegistrationToken; + FFrameIDCopy : cardinal; + FDevToolsEventNames : TStringList; + FDevToolsEventTokens : array of EventRegistrationToken; + + function GetInitialized : boolean; + function GetBrowserProcessID : cardinal; + function GetCanGoBack : boolean; + function GetCanGoForward : boolean; + function GetContainsFullScreenElement : boolean; + function GetDocumentTitle : wvstring; + function GetSource : wvstring; + function GetCookieManager : ICoreWebView2CookieManager; + function GetEnvironment : ICoreWebView2Environment; + function GetIsSuspended : boolean; + function GetSettings : ICoreWebView2Settings; + function GetIsMuted : boolean; + function GetIsDocumentPlayingAudio : boolean; + function GetIsDefaultDownloadDialogOpen : boolean; + function GetDefaultDownloadDialogCornerAlignment : TWVDefaultDownloadDialogCornerAlignment; + function GetDefaultDownloadDialogMargin : TPoint; + function GetStatusBarText : wvstring; + function GetProfile : ICoreWebView2Profile; + function GetFaviconURI : wvstring; + function GetMemoryUsageTargetLevel : TWVMemoryUsageTargetLevel; + function GetFrameID : cardinal; + function GetFind : ICoreWebView2Find; + + procedure SetIsMuted(aValue : boolean); + procedure SetDefaultDownloadDialogCornerAlignment(aValue : TWVDefaultDownloadDialogCornerAlignment); + procedure SetDefaultDownloadDialogMargin(aValue : TPoint); + procedure SetMemoryUsageTargetLevel(aValue : TWVMemoryUsageTargetLevel); + + procedure InitializeFields; + procedure InitializeTokens; + procedure UnsubscribeAllDevToolsProtocolEvents; + procedure RemoveAllEvents; + + function AddNavigationStartingEvent(const aBrowserComponent : TComponent) : boolean; + function AddNavigationCompletedEvent(const aBrowserComponent : TComponent) : boolean; + function AddSourceChangedEvent(const aBrowserComponent : TComponent) : boolean; + function AddHistoryChangedEvent(const aBrowserComponent : TComponent) : boolean; + function AddContentLoadingEvent(const aBrowserComponent : TComponent) : boolean; + function AddDocumentTitleChangedEvent(const aBrowserComponent : TComponent) : boolean; + function AddNewWindowRequestedEvent(const aBrowserComponent : TComponent) : boolean; + function AddFrameNavigationStartingEvent(const aBrowserComponent : TComponent) : boolean; + function AddFrameNavigationCompletedEvent(const aBrowserComponent : TComponent) : boolean; + function AddWebResourceRequestedEvent(const aBrowserComponent : TComponent) : boolean; + function AddScriptDialogOpeningEvent(const aBrowserComponent : TComponent) : boolean; + function AddPermissionRequestedEvent(const aBrowserComponent : TComponent) : boolean; + function AddProcessFailedEvent(const aBrowserComponent : TComponent) : boolean; + function AddWebMessageReceivedEvent(const aBrowserComponent : TComponent) : boolean; + function AddContainsFullScreenElementChangedEvent(const aBrowserComponent : TComponent) : boolean; + function AddWindowCloseRequestedEvent(const aBrowserComponent : TComponent) : boolean; + function AddWebResourceResponseReceivedEvent(const aBrowserComponent : TComponent) : boolean; + function AddDOMContentLoadedEvent(const aBrowserComponent : TComponent) : boolean; + function AddFrameCreatedEvent(const aBrowserComponent : TComponent) : boolean; + function AddDownloadStartingEvent(const aBrowserComponent : TComponent) : boolean; + function AddClientCertificateRequestedEvent(const aBrowserComponent : TComponent) : boolean; + function AddIsMutedChangedEvent(const aBrowserComponent : TComponent) : boolean; + function AddIsDocumentPlayingAudioChangedEvent(const aBrowserComponent : TComponent) : boolean; + function AddIsDefaultDownloadDialogOpenChangedEvent(const aBrowserComponent : TComponent) : boolean; + function AddBasicAuthenticationRequestedEvent(const aBrowserComponent : TComponent) : boolean; + function AddContextMenuRequestedEvent(const aBrowserComponent : TComponent) : boolean; + function AddStatusBarTextChangedEvent(const aBrowserComponent : TComponent) : boolean; + function AddServerCertificateErrorDetectedEvent(const aBrowserComponent : TComponent) : boolean; + function AddFaviconChanged(const aBrowserComponent : TComponent) : boolean; + function AddLaunchingExternalUriScheme(const aBrowserComponent : TComponent) : boolean; + function AddNotificationReceived(const aBrowserComponent : TComponent) : boolean; + function AddSaveAsUIShowing(const aBrowserComponent : TComponent) : boolean; + function AddSaveFileSecurityCheckStarting(const aBrowserComponent : TComponent) : boolean; + function AddScreenCaptureStarting(const aBrowserComponent : TComponent) : boolean; + function AddDedicatedWorkerCreated(const aBrowserComponent : TComponent) : boolean; + + public + constructor Create(const aBaseIntf : ICoreWebView2); reintroduce; + destructor Destroy; override; + procedure AfterConstruction; override; + /// + /// Adds all the events of this class to an existing TWVBrowserBase instance. + /// + /// The TWVBrowserBase instance. + function AddAllBrowserEvents(const aBrowserComponent : TComponent) : boolean; + /// + /// Subscribe to a DevTools protocol event. The TWVBrowserBase.OnDevToolsProtocolEventReceived + /// event will be triggered on each DevTools event. + /// + /// The DevTools protocol event name. + /// A custom event ID that will be passed as a parameter in the TWVBrowserBase event. + /// The TWVBrowserBase instance. + function SubscribeToDevToolsProtocolEvent(const aEventName: wvstring; aEventID : integer; const aBrowserComponent : TComponent) : boolean; + /// + /// Capture an image of what WebView is displaying. Specify the format of + /// the image with the aImageFormat parameter. The resulting image binary + /// data is written to the provided aImageStream parameter. This method fails if called + /// before the first ContentLoading event. For example if this is called in + /// the NavigationStarting event for the first navigation it will fail. + /// For subsequent navigations, the method may not fail, but will not capture + /// an image of a given webpage until the ContentLoading event has been fired + /// for it. Any call to this method prior to that will result in a capture of + /// the page being navigated away from. When this function finishes writing to the stream, + /// the TWVBrowserBase.OnCapturePreviewCompleted event is triggered. + /// + /// The format of the image. + /// The resulting image binary data is written to this stream. + /// The TWVBrowserBase instance. + function CapturePreview(aImageFormat: TWVCapturePreviewImageFormat; const aImageStream: IStream; const aBrowserComponent : TComponent) : boolean; + /// + /// Run JavaScript code from the JavaScript parameter in the current + /// top-level document rendered in the WebView. + /// The TWVBrowserBase.OnExecuteScriptCompleted event is triggered + /// when it finishes. + /// The result of evaluating the provided JavaScript is available in the + /// aResultObjectAsJson parameter of the TWVBrowserBase.OnExecuteScriptCompleted + /// event as a JSON encoded string. If the result is undefined, contains a reference + /// cycle, or otherwise is not able to be encoded into JSON, then the result + /// is considered to be null, which is encoded in JSON as the string "null". + /// If the script that was run throws an unhandled exception, then the result is + /// also "null". + /// If the method is run after the `NavigationStarting` event during a navigation, + /// the script runs in the new document when loading it, around the time + /// `ContentLoading` is run. This operation executes the script even if + /// `ICoreWebView2Settings.IsScriptEnabled` is set to `FALSE`. + /// + /// The JavaScript code. + /// A custom event ID that will be passed as a parameter in the TWVBrowserBase event. + /// The TWVBrowserBase instance. + function ExecuteScript(const JavaScript : wvstring; aExecutionID : integer; const aBrowserComponent : TComponent) : boolean; + /// + /// Navigates the WebView to the previous page in the navigation history. + /// + function GoBack : boolean; + /// + /// Navigates the WebView to the next page in the navigation history. + /// + function GoForward : boolean; + /// + /// Cause a navigation of the top-level document to run to the specified URI. + /// + function Navigate(const aURI : wvstring) : boolean; + /// + /// Initiates a navigation to aHTMLContent as source HTML of a new document. + /// The `aHTMLContent` parameter may not be larger than 2 MB (2 * 1024 * 1024 bytes) in total size. + /// The origin of the new page is `about:blank`. + /// + function NavigateToString(const aHTMLContent : wvstring) : boolean; + /// + /// Navigates using a constructed ICoreWebView2WebResourceRequest object. This lets you + /// provide post data or additional request headers during navigation. + /// The headers in aRequest override headers added by WebView2 runtime except for Cookie headers. + /// Method can only be either "GET" or "POST". Provided post data will only + /// be sent only if the method is "POST" and the uri scheme is HTTP(S). + /// + function NavigateWithWebResourceRequest(const aRequest : ICoreWebView2WebResourceRequest) : boolean; + /// + /// Reload the current page. This is similar to navigating to the URI of + /// current top level document including all navigation events firing and + /// respecting any entries in the HTTP cache. But, the back or forward + /// history are not modified. + /// + function Reload : boolean; + /// + /// Stop all navigations and pending resource fetches. Does not stop scripts. + /// + function Stop : boolean; + /// + /// An app may call the `TrySuspend` API to have the WebView2 consume less memory. + /// This is useful when a Win32 app becomes invisible, or when a Universal Windows + /// Platform app is being suspended, during the suspended event handler before completing + /// the suspended event. + /// The CoreWebView2Controller's IsVisible property must be false when the API is called. + /// Otherwise, the API fails with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`. + /// Suspending is similar to putting a tab to sleep in the Edge browser. Suspending pauses + /// WebView script timers and animations, minimizes CPU usage for the associated + /// browser renderer process and allows the operating system to reuse the memory that was + /// used by the renderer process for other processes. + /// Note that Suspend is best effort and considered completed successfully once the request + /// is sent to browser renderer process. If there is a running script, the script will continue + /// to run and the renderer process will be suspended after that script is done. + /// See [Sleeping Tabs FAQ](https://techcommunity.microsoft.com/t5/articles/sleeping-tabs-faq/m-p/1705434) + /// for conditions that might prevent WebView from being suspended. In those situations, + /// the completed handler will be invoked with isSuccessful as false and errorCode as S_OK. + /// The WebView will be automatically resumed when it becomes visible. Therefore, the + /// app normally does not have to call `Resume` explicitly. + /// The app can call `Resume` and then `TrySuspend` periodically for an invisible WebView so that + /// the invisible WebView can sync up with latest data and the page ready to show fresh content + /// when it becomes visible. + /// All WebView APIs can still be accessed when a WebView is suspended. Some APIs like Navigate + /// will auto resume the WebView. To avoid unexpected auto resume, check `IsSuspended` property + /// before calling APIs that might change WebView state. + /// + function TrySuspend(const aHandler: ICoreWebView2TrySuspendCompletedHandler) : boolean; + /// + /// Resumes the WebView so that it resumes activities on the web page. + /// This API can be called while the WebView2 controller is invisible. + /// The app can interact with the WebView immediately after `Resume`. + /// WebView will be automatically resumed when it becomes visible. + /// + function Resume : boolean; + /// + /// Sets a mapping between a virtual host name and a folder path to make available to web sites + /// via that host name. + /// + /// After setting the mapping, documents loaded in the WebView can use HTTP or HTTPS URLs at + /// the specified host name specified by hostName to access files in the local folder specified + /// by folderPath. + /// + /// This mapping applies to both top-level document and iframe navigations as well as subresource + /// references from a document. This also applies to web workers including dedicated/shared worker + /// and service worker, for loading either worker scripts or subresources + /// (importScripts(), fetch(), XHR, etc.) issued from within a worker. + /// For virtual host mapping to work with service worker, please keep the virtual host name + /// mappings consistent among all WebViews sharing the same browser instance. As service worker + /// works independently of WebViews, we merge mappings from all WebViews when resolving virtual + /// host name, inconsistent mappings between WebViews would lead unexpected behavior. + /// + /// Due to a current implementation limitation, media files accessed using virtual host name can be + /// very slow to load. + /// As the resource loaders for the current page might have already been created and running, + /// changes to the mapping might not be applied to the current page and a reload of the page is + /// needed to apply the new mapping. + /// + /// Both absolute and relative paths are supported for folderPath. Relative paths are interpreted + /// as relative to the folder where the exe of the app is in. + /// + /// Note that the folderPath length must not exceed the Windows MAX_PATH limit. + /// + /// accessKind specifies the level of access to resources under the virtual host from other sites. + /// + /// For example, after calling + /// + /// ```cpp + /// SetVirtualHostNameToFolderMapping( + /// L"appassets.example", L"assets", + /// COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_DENY); + /// ``` + /// + /// navigating to `https://appassets.example/my-local-file.html` will + /// show the content from my-local-file.html in the assets subfolder located on disk under + /// the same path as the app's executable file. + /// + /// DOM elements that want to reference local files will have their host reference virtual host in the source. + /// If there are multiple folders being used, define one unique virtual host per folder. + /// For example, you can embed a local image like this + /// + /// ```cpp + /// WCHAR c_navString[] = L""; + /// m_webView->NavigateToString(c_navString); + /// ``` + /// + /// The example above shows the image wv2.png by resolving the folder mapping above. + /// + /// You should typically choose virtual host names that are never used by real sites. + /// If you own a domain such as example.com, another option is to use a subdomain reserved for + /// the app (like my-app.example.com). + /// + /// [RFC 6761](https://tools.ietf.org/html/rfc6761) has reserved several special-use domain + /// names that are guaranteed to not be used by real sites (for example, .example, .test, and + /// .invalid.) + /// + /// Note that using `.local` as the top-level domain name will work but can cause a delay + /// during navigations. You should avoid using `.local` if you can. + /// + /// Apps should use distinct domain names when mapping folder from different sources that + /// should be isolated from each other. For instance, the app might use app-file.example for + /// files that ship as part of the app, and book1.example might be used for files containing + /// books from a less trusted source that were previously downloaded and saved to the disk by + /// the app. + /// + /// The host name used in the APIs is canonicalized using Chromium's host name parsing logic + /// before being used internally. For more information see [HTML5 2.6 URLs](https://dev.w3.org/html5/spec-LC/urls.html). + /// + /// All host names that are canonicalized to the same string are considered identical. + /// For example, `EXAMPLE.COM` and `example.com` are treated as the same host name. + /// An international host name and its Punycode-encoded host name are considered the same host + /// name. There is no DNS resolution for host name and the trailing '.' is not normalized as + /// part of canonicalization. + /// + /// Therefore `example.com` and `example.com.` are treated as different host names. Similarly, + /// `virtual-host-name` and `virtual-host-name.example.com` are treated as different host names + /// even if the machine has a DNS suffix of `example.com`. + /// + /// Specify the minimal cross-origin access necessary to run the app. If there is not a need to + /// access local resources from other origins, use COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_DENY. + /// + function SetVirtualHostNameToFolderMapping(const aHostName, aFolderPath : wvstring; aAccessKind : TWVHostResourceAcccessKind): boolean; + /// + /// Clears a host name mapping for local folder that was added by `SetVirtualHostNameToFolderMapping`. + /// + function ClearVirtualHostNameToFolderMapping(const aHostName : wvstring) : boolean; + /// + /// Opens the Browser Task Manager view as a new window in the foreground. + /// If the Browser Task Manager is already open, this will bring it into + /// the foreground. WebView2 currently blocks the Shift+Esc shortcut for + /// opening the task manager. An end user can open the browser task manager + /// manually via the `Browser task manager` entry of the DevTools window's + /// title bar's context menu. + /// + function OpenTaskManagerWindow : boolean; + /// + /// Print the current page to PDF asynchronously with the provided settings. + /// See `ICoreWebView2PrintSettings` for description of settings. Passing + /// nullptr for `printSettings` results in default print settings used. + /// + /// Use `resultFilePath` to specify the path to the PDF file. The host should + /// provide an absolute path, including file name. If the path + /// points to an existing file, the file will be overwritten. If the path is + /// not valid, the method fails with `E_INVALIDARG`. + /// + /// The async `PrintToPdf` operation completes when the data has been written + /// to the PDF file. At this time the + /// `ICoreWebView2PrintToPdfCompletedHandler` is invoked. If the + /// application exits before printing is complete, the file is not saved. + /// Only one `Printing` operation can be in progress at a time. If + /// `PrintToPdf` is called while a `PrintToPdf` or `PrintToPdfStream` or `Print` or + /// `ShowPrintUI` job is in progress, the completed handler is immediately invoked + /// with `isSuccessful` set to FALSE. + /// + function PrintToPdf(const aResultFilePath : wvstring; const aPrintSettings : ICoreWebView2PrintSettings; const aHandler : ICoreWebView2PrintToPdfCompletedHandler) : boolean; + /// + /// Opens the DevTools window for the current document in the WebView. Does + /// nothing if run when the DevTools window is already open. + /// + function OpenDevToolsWindow : boolean; + /// + /// Post the specified webMessage to the top level document in this WebView. + /// The main page receives the message by subscribing to the `message` event of the + /// `window.chrome.webview` of the page document. + /// + /// ```cpp + /// window.chrome.webview.addEventListener('message', handler) + /// window.chrome.webview.removeEventListener('message', handler) + /// ``` + /// + /// The event args is an instance of `MessageEvent`. The + /// `ICoreWebView2Settings::IsWebMessageEnabled` setting must be `TRUE` or + /// the web message will not be sent. The `data` property of the event + /// arg is the `webMessage` string parameter parsed as a JSON string into a + /// JavaScript object. The `source` property of the event arg is a reference + /// to the `window.chrome.webview` object. For information about sending + /// messages from the HTML document in the WebView to the host, navigate to + /// [add_WebMessageReceived](/microsoft-edge/webview2/reference/win32/icorewebview2#add_webmessagereceived). + /// The message is delivered asynchronously. If a navigation occurs before + /// the message is posted to the page, the message is discarded. + /// + function PostWebMessageAsJson(const aWebMessageAsJson : wvstring) : boolean; + /// + /// Posts a message that is a simple string rather than a JSON string + /// representation of a JavaScript object. This behaves in exactly the same + /// manner as `PostWebMessageAsJson`, but the `data` property of the event + /// arg of the `window.chrome.webview` message is a string with the same + /// value as `webMessageAsString`. Use this instead of + /// `PostWebMessageAsJson` if you want to communicate using simple strings + /// rather than JSON objects. + /// + function PostWebMessageAsString(const aWebMessageAsString : wvstring) : boolean; + /// + /// Runs an asynchronous `DevToolsProtocol` method. For more information + /// about available methods, navigate to + /// [DevTools Protocol Viewer](https://chromedevtools.github.io/devtools-protocol/tot). + /// The `methodName` parameter is the full name of the method in the + /// `{domain}.{method}` format. The `parametersAsJson` parameter is a JSON + /// formatted string containing the parameters for the corresponding method. + /// The `Invoke` method of the `handler` is run when the method + /// asynchronously completes. `Invoke` is run with the return object of the + /// method as a JSON string. This function returns E_INVALIDARG if the `methodName` is + /// unknown or the `parametersAsJson` has an error. In the case of such an error, the + /// `returnObjectAsJson` parameter of the handler will include information + /// about the error. + /// Note even though WebView2 dispatches the CDP messages in the order called, + /// CDP method calls may be processed out of order. + /// If you require CDP methods to run in a particular order, you should wait + /// for the previous method's completed handler to run before calling the + /// next method. + /// If the method is to run in add_NewWindowRequested handler it should be called + /// before the new window is set if the cdp message should affect the initial navigation. If + /// called after setting the NewWindow property, the cdp messages + /// may or may not apply to the initial navigation and may only apply to the subsequent navigation. + /// For more details see `ICoreWebView2NewWindowRequestedEventArgs::put_NewWindow`. + /// + function CallDevToolsProtocolMethod(const aMethodName, aParametersAsJson : wvstring; aExecutionID : integer; const aBrowserComponent : TComponent) : boolean; + /// + /// Runs an asynchronous `DevToolsProtocol` method for a specific session of + /// an attached target. + /// There could be multiple `DevToolsProtocol` targets in a WebView. + /// Besides the top level page, iframes from different origin and web workers + /// are also separate targets. Attaching to these targets allows interaction with them. + /// When the DevToolsProtocol is attached to a target, the connection is identified + /// by a sessionId. + /// To use this API, you must set the `flatten` parameter to true when calling + /// `Target.attachToTarget` or `Target.setAutoAttach` `DevToolsProtocol` method. + /// Using `Target.setAutoAttach` is recommended as that would allow you to attach + /// to dedicated worker targets, which are not discoverable via other APIs like + /// `Target.getTargets`. + /// For more information about targets and sessions, navigate to + /// [DevTools Protocol Viewer](https://chromedevtools.github.io/devtools-protocol/tot/Target). + /// For more information about available methods, navigate to + /// [DevTools Protocol Viewer](https://chromedevtools.github.io/devtools-protocol/tot) + /// The `sessionId` parameter is the sessionId for an attached target. + /// nullptr or empty string is treated as the session for the default target for the top page. + /// The `methodName` parameter is the full name of the method in the + /// `{domain}.{method}` format. The `parametersAsJson` parameter is a JSON + /// formatted string containing the parameters for the corresponding method. + /// The `Invoke` method of the `handler` is run when the method + /// asynchronously completes. `Invoke` is run with the return object of the + /// method as a JSON string. This function returns E_INVALIDARG if the `methodName` is + /// unknown or the `parametersAsJson` has an error. In the case of such an error, the + /// `returnObjectAsJson` parameter of the handler will include information + /// about the error. + /// + function CallDevToolsProtocolMethodForSession(const aSessionId, aMethodName, aParametersAsJson : wvstring; aExecutionID : integer; const aBrowserComponent : TComponent) : boolean; + /// + /// Warning: This method is deprecated and does not behave as expected for + /// iframes. It will cause the WebResourceRequested event to fire only for the + /// main frame and its same-origin iframes. Please use + /// `AddWebResourceRequestedFilterWithRequestSourceKinds` + /// instead, which will let the event to fire for all iframes on the + /// document. + /// + /// Adds a URI and resource context filter for the `WebResourceRequested` + /// event. A web resource request with a resource context that matches this + /// filter's resource context and a URI that matches this filter's URI + /// wildcard string will be raised via the `WebResourceRequested` event. + /// + /// The `uri` parameter value is a wildcard string matched against the URI + /// of the web resource request. This is a glob style + /// wildcard string in which a `*` matches zero or more characters and a `?` + /// matches exactly one character. + /// These wildcard characters can be escaped using a backslash just before + /// the wildcard character in order to represent the literal `*` or `?`. + /// + /// The matching occurs over the URI as a whole string and not limiting + /// wildcard matches to particular parts of the URI. + /// The wildcard filter is compared to the URI after the URI has been + /// normalized, any URI fragment has been removed, and non-ASCII hostnames + /// have been converted to punycode. + /// + /// Specifying a `nullptr` for the uri is equivalent to an empty string which + /// matches no URIs. + /// + /// For more information about resource context filters, navigate to + /// [COREWEBVIEW2_WEB_RESOURCE_CONTEXT](/microsoft-edge/webview2/reference/win32/webview2-idl#corewebview2_web_resource_context). + /// + /// | URI Filter String | Request URI | Match | Notes | + /// | ---- | ---- | ---- | ---- | + /// | `*` | `https://contoso.com/a/b/c` | Yes | A single * will match all URIs | + /// | `*://contoso.com/*` | `https://contoso.com/a/b/c` | Yes | Matches everything in contoso.com across all schemes | + /// | `*://contoso.com/*` | `https://example.com/?https://contoso.com/` | Yes | But also matches a URI with just the same text anywhere in the URI | + /// | `example` | `https://contoso.com/example` | No | The filter does not perform partial matches | + /// | `*example` | `https://contoso.com/example` | Yes | The filter matches across URI parts | + /// | `*example` | `https://contoso.com/path/?example` | Yes | The filter matches across URI parts | + /// | `*example` | `https://contoso.com/path/?query#example` | No | The filter is matched against the URI with no fragment | + /// | `*example` | `https://example` | No | The URI is normalized before filter matching so the actual URI used for comparison is `https://example/` | + /// | `*example/` | `https://example` | Yes | Just like above, but this time the filter ends with a / just like the normalized URI | + /// | `https://xn--qei.example/` | `https://❤.example/` | Yes | Non-ASCII hostnames are normalized to punycode before wildcard comparison | + /// | `https://❤.example/` | `https://xn--qei.example/` | No | Non-ASCII hostnames are normalized to punycode before wildcard comparison | + /// + /// + function AddWebResourceRequestedFilter(const URI : wvstring; ResourceContext: TWVWebResourceContext) : boolean; + /// + /// Warning: This method and `AddWebResourceRequestedFilter` are deprecated. + /// Please use `AddWebResourceRequestedFilterWithRequestSourceKinds` and + /// `RemoveWebResourceRequestedFilterWithRequestSourceKinds` instead. + /// Removes a matching WebResource filter that was previously added for the + /// `WebResourceRequested` event. If the same filter was added multiple + /// times, then it must be removed as many times as it was added for the + /// removal to be effective. Returns `E_INVALIDARG` for a filter that was + /// never added. + /// + function RemoveWebResourceRequestedFilter(const URI : wvstring; ResourceContext: TWVWebResourceContext) : boolean; + /// + /// Add the provided host object to script running in the WebView with the + /// specified name. Host objects are exposed as host object proxies using + /// `window.chrome.webview.hostObjects.{name}`. Host object proxies are + /// promises and resolves to an object representing the host object. The + /// promise is rejected if the app has not added an object with the name. + /// When JavaScript code access a property or method of the object, a promise + /// is return, which resolves to the value returned from the host for the + /// property or method, or rejected in case of error, for example, no + /// property or method on the object or parameters are not valid. + /// + /// NOTE: While simple types, `IDispatch` and array are supported, and + /// `IUnknown` objects that also implement `IDispatch` are treated as `IDispatch`, + /// generic `IUnknown`, `VT_DECIMAL`, or `VT_RECORD` variant is not supported. + /// Remote JavaScript objects like callback functions are represented as an + /// `VT_DISPATCH` `VARIANT` with the object implementing `IDispatch`. The + /// JavaScript callback method may be invoked using `DISPID_VALUE` for the + /// `DISPID`. Such callback method invocations will return immediately and will + /// not wait for the JavaScript function to run and so will not provide the return + /// value of the JavaScript function. + /// Nested arrays are supported up to a depth of 3. Arrays of by + /// reference types are not supported. `VT_EMPTY` and `VT_NULL` are mapped + /// into JavaScript as `null`. In JavaScript, `null` and undefined are + /// mapped to `VT_EMPTY`. + /// + /// Additionally, all host objects are exposed as + /// `window.chrome.webview.hostObjects.sync.{name}`. Here the host objects + /// are exposed as synchronous host object proxies. These are not promises + /// and function runtimes or property access synchronously block running + /// script waiting to communicate cross process for the host code to run. + /// Accordingly the result may have reliability issues and it is recommended + /// that you use the promise-based asynchronous + /// `window.chrome.webview.hostObjects.{name}` API. + /// + /// Synchronous host object proxies and asynchronous host object proxies may + /// both use a proxy to the same host object. Remote changes made by one + /// proxy propagates to any other proxy of that same host object whether + /// the other proxies and synchronous or asynchronous. + /// + /// While JavaScript is blocked on a synchronous run to native code, that + /// native code is unable to run back to JavaScript. Attempts to do so fail + /// with `HRESULT_FROM_WIN32(ERROR_POSSIBLE_DEADLOCK)`. + /// + /// Host object proxies are JavaScript Proxy objects that intercept all + /// property get, property set, and method invocations. Properties or methods + /// that are a part of the Function or Object prototype are run locally. + /// Additionally any property or method in the + /// `chrome.webview.hostObjects.options.forceLocalProperties` + /// array are also run locally. This defaults to including optional methods + /// that have meaning in JavaScript like `toJSON` and `Symbol.toPrimitive`. + /// Add more to the array as required. + /// + /// The `chrome.webview.hostObjects.cleanupSome` method performs a best + /// effort garbage collection on host object proxies. + /// + /// The `chrome.webview.hostObjects.options` object provides the ability to + /// change some functionality of host objects. + /// + /// Options property | Details + /// ---|--- + /// `forceLocalProperties` | This is an array of host object property names that will be run locally, instead of being called on the native host object. This defaults to `then`, `toJSON`, `Symbol.toString`, and `Symbol.toPrimitive`. You can add other properties to specify that they should be run locally on the javascript host object proxy. + /// `log` | This is a callback that will be called with debug information. For example, you can set this to `console.log.bind(console)` to have it print debug information to the console to help when troubleshooting host object usage. By default this is null. + /// `shouldSerializeDates` | By default this is false, and javascript Date objects will be sent to host objects as a string using `JSON.stringify`. You can set this property to true to have Date objects properly serialize as a `VT_DATE` when sending to the native host object, and have `VT_DATE` properties and return values create a javascript Date object. + /// `defaultSyncProxy` | When calling a method on a synchronous proxy, the result should also be a synchronous proxy. But in some cases, the sync/async context is lost (for example, when providing to native code a reference to a function, and then calling that function in native code). In these cases, the proxy will be asynchronous, unless this property is set. + /// `forceAsyncMethodMatches ` | This is an array of regular expressions. When calling a method on a synchronous proxy, the method call will be performed asynchronously if the method name matches a string or regular expression in this array. Setting this value to `Async` will make any method that ends with Async be an asynchronous method call. If an async method doesn't match here and isn't forced to be asynchronous, the method will be invoked synchronously, blocking execution of the calling JavaScript and then returning the resolution of the promise, rather than returning a promise. + /// `ignoreMemberNotFoundError` | By default, an exception is thrown when attempting to get the value of a proxy property that doesn't exist on the corresponding native class. Setting this property to `true` switches the behavior to match Chakra WinRT projection (and general JavaScript) behavior of returning `undefined` with no error. + /// `shouldPassTypedArraysAsArrays` | By default, typed arrays are passed to the host as `IDispatch`. To instead pass typed arrays to the host as `array`, set this to `true`. + /// + /// Host object proxies additionally have the following methods which run + /// locally. + /// + /// Method name | Details + /// ---|--- + ///`applyHostFunction`, `getHostProperty`, `setHostProperty` | Perform a method invocation, property get, or property set on the host object. Use the methods to explicitly force a method or property to run remotely if a conflicting local method or property exists. For instance, `proxy.toString()` runs the local `toString` method on the proxy object. But proxy.applyHostFunction('toString') runs `toString` on the host proxied object instead. + ///`getLocalProperty`, `setLocalProperty` | Perform property get, or property set locally. Use the methods to force getting or setting a property on the host object proxy rather than on the host object it represents. For instance, `proxy.unknownProperty` gets the property named `unknownProperty` from the host proxied object. But proxy.getLocalProperty('unknownProperty') gets the value of the property `unknownProperty` on the proxy object. + ///`sync` | Asynchronous host object proxies expose a sync method which returns a promise for a synchronous host object proxy for the same host object. For example, `chrome.webview.hostObjects.sample.methodCall()` returns an asynchronous host object proxy. Use the `sync` method to obtain a synchronous host object proxy instead: `const syncProxy = await chrome.webview.hostObjects.sample.methodCall().sync()`. + ///`async` | Synchronous host object proxies expose an async method which blocks and returns an asynchronous host object proxy for the same host object. For example, `chrome.webview.hostObjects.sync.sample.methodCall()` returns a synchronous host object proxy. Running the `async` method on this blocks and then returns an asynchronous host object proxy for the same host object: `const asyncProxy = chrome.webview.hostObjects.sync.sample.methodCall().async()`. + ///`then` | Asynchronous host object proxies have a `then` method. Allows proxies to be awaitable. `then` returns a promise that resolves with a representation of the host object. If the proxy represents a JavaScript literal, a copy of that is returned locally. If the proxy represents a function, a non-awaitable proxy is returned. If the proxy represents a JavaScript object with a mix of literal properties and function properties, the a copy of the object is returned with some properties as host object proxies. + /// + /// All other property and method invocations (other than the above Remote + /// object proxy methods, `forceLocalProperties` list, and properties on + /// Function and Object prototypes) are run remotely. Asynchronous host + /// object proxies return a promise representing asynchronous completion of + /// remotely invoking the method, or getting the property. The promise + /// resolves after the remote operations complete and the promises resolve to + /// the resulting value of the operation. Synchronous host object proxies + /// work similarly, but block running JavaScript and wait for the remote + /// operation to complete. + /// + /// Setting a property on an asynchronous host object proxy works slightly + /// differently. The set returns immediately and the return value is the + /// value that is set. This is a requirement of the JavaScript Proxy object. + /// If you need to asynchronously wait for the property set to complete, use + /// the `setHostProperty` method which returns a promise as described above. + /// Synchronous object property set property synchronously blocks until the + /// property is set. + /// + function AddHostObjectToScript(const aName : wvstring; const aObject : OleVariant): boolean; + /// + /// Remove the host object specified by the name so that it is no longer + /// accessible from JavaScript code in the WebView. While new access + /// attempts are denied, if the object is already obtained by JavaScript code + /// in the WebView, the JavaScript code continues to have access to that + /// object. Run this method for a name that is already removed or never + /// added fails. + /// + function RemoveHostObjectFromScript(const aName : wvstring) : boolean; + /// + /// Add the provided JavaScript to a list of scripts that should be run after + /// the global object has been created, but before the HTML document has + /// been parsed and before any other script included by the HTML document is + /// run. This method injects a script that runs on all top-level document + /// and child frame page navigations. This method runs asynchronously, and + /// you must wait for the completion handler to finish before the injected + /// script is ready to run. When this method completes, the `Invoke` method + /// of the handler is run with the `id` of the injected script. `id` is a + /// string. To remove the injected script, use + /// `RemoveScriptToExecuteOnDocumentCreated`. + /// If the method is run in add_NewWindowRequested handler it should be called + /// before the new window is set. If called after setting the NewWindow property, the initial script + /// may or may not apply to the initial navigation and may only apply to the subsequent navigation. + /// For more details see `ICoreWebView2NewWindowRequestedEventArgs::put_NewWindow`. + /// NOTE: If an HTML document is running in a sandbox of some kind using + /// [sandbox](https://developer.mozilla.org/docs/Web/HTML/Element/iframe#attr-sandbox) + /// properties or the + /// [Content-Security-Policy](https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Security-Policy) + /// HTTP header affects the script that runs. For example, if the + /// `allow-modals` keyword is not set then requests to run the `alert` + /// function are ignored. + /// + function AddScriptToExecuteOnDocumentCreated(const JavaScript : wvstring; const aBrowserComponent : TComponent) : boolean; + /// + /// Remove the corresponding JavaScript added using + /// `AddScriptToExecuteOnDocumentCreated` with the specified script ID. The + /// script ID should be the one returned by the `AddScriptToExecuteOnDocumentCreated`. + /// Both use `AddScriptToExecuteOnDocumentCreated` and this method in `NewWindowRequested` + /// event handler at the same time sometimes causes trouble. Since invalid scripts will + /// be ignored, the script IDs you got may not be valid anymore. + /// + function RemoveScriptToExecuteOnDocumentCreated(const aID : wvstring) : boolean; + /// + /// Open the default download dialog. If the dialog is opened before there + /// are recent downloads, the dialog shows all past downloads for the + /// current profile. Otherwise, the dialog shows only the recent downloads + /// with a "See more" button for past downloads. Calling this method raises + /// the `IsDefaultDownloadDialogOpenChanged` event if the dialog was closed. + /// No effect if the dialog is already open. + /// + function OpenDefaultDownloadDialog : boolean; + /// + /// Close the default download dialog. Calling this method raises the + /// `IsDefaultDownloadDialogOpenChanged` event if the dialog was open. No + /// effect if the dialog is already closed. + /// + function CloseDefaultDownloadDialog : boolean; + /// + /// Clears all cached decisions to proceed with TLS certificate errors from the + /// ServerCertificateErrorDetected event for all WebView2's sharing the same session. + /// + function ClearServerCertificateErrorActions(const aBrowserComponent : TComponent) : boolean; + /// + /// Async function for getting the actual image data of the favicon. + /// The image is copied to the `imageStream` object in `ICoreWebView2GetFaviconCompletedHandler`. + /// If there is no image then no data would be copied into the imageStream. + /// The `format` is the file format to return the image stream. + /// `completedHandler` is executed at the end of the operation. + /// + function GetFavicon(aFormat: TWVFaviconImageFormat; const aBrowserComponent : TComponent) : boolean; + /// + /// Print the current web page asynchronously to the specified printer with the provided settings. + /// See `ICoreWebView2PrintSettings` for description of settings. Passing + /// nullptr for `printSettings` results in default print settings used. + /// The handler will return `errorCode` as `S_OK` and `printStatus` as COREWEBVIEW2_PRINT_STATUS_PRINTER_UNAVAILABLE + /// if `printerName` doesn't match with the name of any installed printers on the user OS. The handler + /// will return `errorCode` as `E_INVALIDARG` and `printStatus` as COREWEBVIEW2_PRINT_STATUS_OTHER_ERROR + /// if the caller provides invalid settings for a given printer. + /// The async `Print` operation completes when it finishes printing to the printer. + /// At this time the `ICoreWebView2PrintCompletedHandler` is invoked. + /// Only one `Printing` operation can be in progress at a time. If `Print` is called while a `Print` or `PrintToPdf` + /// or `PrintToPdfStream` or `ShowPrintUI` job is in progress, the completed handler is immediately invoked + /// with `E_ABORT` and `printStatus` is COREWEBVIEW2_PRINT_STATUS_OTHER_ERROR. + /// This is only for printing operation on one webview. + /// + /// | errorCode | printStatus | Notes | + /// | --- | --- | --- | + /// | S_OK | COREWEBVIEW2_PRINT_STATUS_SUCCEEDED | Print operation succeeded. | + /// | S_OK | COREWEBVIEW2_PRINT_STATUS_PRINTER_UNAVAILABLE | If specified printer is not found or printer status is not available, offline or error state. | + /// | S_OK | COREWEBVIEW2_PRINT_STATUS_OTHER_ERROR | Print operation is failed. | + /// | E_INVALIDARG | COREWEBVIEW2_PRINT_STATUS_OTHER_ERROR | If the caller provides invalid settings for the specified printer. | + /// | E_ABORT | COREWEBVIEW2_PRINT_STATUS_OTHER_ERROR | Print operation is failed as printing job already in progress. | + /// + /// + function Print(const aPrintSettings: ICoreWebView2PrintSettings; const aHandler: ICoreWebView2PrintCompletedHandler): boolean; + /// + /// Opens the print dialog to print the current web page. See `COREWEBVIEW2_PRINT_DIALOG_KIND` + /// for descriptions of print dialog kinds. + /// Invoking browser or system print dialog doesn't open new print dialog if + /// it is already open. + /// + function ShowPrintUI(aPrintDialogKind: TWVPrintDialogKind): boolean; + /// + /// Provides the Pdf data of current web page asynchronously for the provided settings. + /// Stream will be rewound to the start of the pdf data. + /// See `ICoreWebView2PrintSettings` for description of settings. Passing + /// nullptr for `printSettings` results in default print settings used. + /// The async `PrintToPdfStream` operation completes when it finishes + /// writing to the stream. At this time the `ICoreWebView2PrintToPdfStreamCompletedHandler` + /// is invoked. Only one `Printing` operation can be in progress at a time. If + /// `PrintToPdfStream` is called while a `PrintToPdfStream` or `PrintToPdf` or `Print` + /// or `ShowPrintUI` job is in progress, the completed handler is immediately invoked with `E_ABORT`. + /// This is only for printing operation on one webview. + /// + function PrintToPdfStream(const aPrintSettings: ICoreWebView2PrintSettings; const aHandler: ICoreWebView2PrintToPdfStreamCompletedHandler): boolean; + /// + /// Share a shared buffer object with script of the main frame in the WebView. + /// The script will receive a `sharedbufferreceived` event from chrome.webview. + /// The event arg for that event will have the following methods and properties: + /// `getBuffer()`: return an ArrayBuffer object with the backing content from the shared buffer. + /// `additionalData`: an object as the result of parsing `additionalDataAsJson` as JSON string. + /// This property will be `undefined` if `additionalDataAsJson` is nullptr or empty string. + /// `source`: with a value set as `chrome.webview` object. + /// If a string is provided as `additionalDataAsJson` but it is not a valid JSON string, + /// the API will fail with `E_INVALIDARG`. + /// If `access` is COREWEBVIEW2_SHARED_BUFFER_ACCESS_READ_ONLY, the script will only have read access to the buffer. + /// If the script tries to modify the content in a read only buffer, it will cause an access + /// violation in WebView renderer process and crash the renderer process. + /// If the shared buffer is already closed, the API will fail with `RO_E_CLOSED`. + /// The script code should call `chrome.webview.releaseBuffer` with + /// the shared buffer as the parameter to release underlying resources as soon + /// as it does not need access to the shared buffer any more. + /// The application can post the same shared buffer object to multiple web pages or iframes, or + /// post to the same web page or iframe multiple times. Each `PostSharedBufferToScript` will + /// create a separate ArrayBuffer object with its own view of the memory and is separately + /// released. The underlying shared memory will be released when all the views are released. + /// + function PostSharedBufferToScript(const aSharedBuffer: ICoreWebView2SharedBuffer; aAccess: TWVSharedBufferAccess; const aAdditionalDataAsJson: wvstring): boolean; + /// + /// Run JavaScript code from the JavaScript parameter in the current + /// top-level document rendered in the WebView. + /// The result of the execution is returned asynchronously in the CoreWebView2ExecuteScriptResult object + /// which has methods and properties to obtain the successful result of script execution as well as any + /// unhandled JavaScript exceptions. + /// If this method is + /// run after the NavigationStarting event during a navigation, the script + /// runs in the new document when loading it, around the time + /// ContentLoading is run. This operation executes the script even if + /// ICoreWebView2Settings::IsScriptEnabled is set to FALSE. + /// + /// \snippet ScriptComponent.cpp ExecuteScriptWithResult + /// + function ExecuteScriptWithResult(const JavaScript: wvstring; aExecutionID : integer; const aBrowserComponent : TComponent): boolean; + /// + /// A web resource request with a resource context that matches this + /// filter's resource context and a URI that matches this filter's URI + /// wildcard string for corresponding request sources will be raised via + /// the `WebResourceRequested` event. To receive all raised events filters + /// have to be added before main page navigation. + /// + /// The `uri` parameter value is a wildcard string matched against the URI + /// of the web resource request. This is a glob style + /// wildcard string in which a `*` matches zero or more characters and a `?` + /// matches exactly one character. + /// These wildcard characters can be escaped using a backslash just before + /// the wildcard character in order to represent the literal `*` or `?`. + /// + /// The matching occurs over the URI as a whole string and not limiting + /// wildcard matches to particular parts of the URI. + /// The wildcard filter is compared to the URI after the URI has been + /// normalized, any URI fragment has been removed, and non-ASCII hostnames + /// have been converted to punycode. + /// + /// Specifying a `nullptr` for the uri is equivalent to an empty string which + /// matches no URIs. + /// + /// For more information about resource context filters, navigate to + /// [COREWEBVIEW2_WEB_RESOURCE_CONTEXT](/microsoft-edge/webview2/reference/win32/icorewebview2#corewebview2_web_resource_context). + /// + /// The `requestSourceKinds` is a mask of one or more + /// `COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS`. OR operation(s) can be + /// applied to multiple `COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS` to + /// create a mask representing those data types. API returns `E_INVALIDARG` if + /// `requestSourceKinds` equals to zero. For more information about request + /// source kinds, navigate to + /// [COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS](/microsoft-edge/webview2/reference/win32/icorewebview2#corewebview2_web_resource_request_source_kinds). + /// + /// Because service workers and shared workers run separately from any one + /// HTML document their WebResourceRequested will be raised for all + /// CoreWebView2s that have appropriate filters added in the corresponding + /// CoreWebView2Environment. You should only add a WebResourceRequested filter + /// for COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_SERVICE_WORKER or + /// COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_SHARED_WORKER on + /// one CoreWebView2 to avoid handling the same WebResourceRequested + /// event multiple times. + /// + /// | URI Filter String | Request URI | Match | Notes | + /// | ---- | ---- | ---- | ---- | + /// | `*` | `https://contoso.com/a/b/c` | Yes | A single * will match all URIs | + /// | `*://contoso.com/*` | `https://contoso.com/a/b/c` | Yes | Matches everything in contoso.com across all schemes | + /// | `*://contoso.com/*` | `https://example.com/?https://contoso.com/` | Yes | But also matches a URI with just the same text anywhere in the URI | + /// | `example` | `https://contoso.com/example` | No | The filter does not perform partial matches | + /// | `*example` | `https://contoso.com/example` | Yes | The filter matches across URI parts | + /// | `*example` | `https://contoso.com/path/?example` | Yes | The filter matches across URI parts | + /// | `*example` | `https://contoso.com/path/?query#example` | No | The filter is matched against the URI with no fragment | + /// | `*example` | `https://example` | No | The URI is normalized before filter matching so the actual URI used for comparison is `https://example/` | + /// | `*example/` | `https://example` | Yes | Just like above, but this time the filter ends with a / just like the normalized URI | + /// | `https://xn--qei.example/` | `https://❤.example/` | Yes | Non-ASCII hostnames are normalized to punycode before wildcard comparison | + /// | `https://❤.example/` | `https://xn--qei.example/` | No | Non-ASCII hostnames are normalized to punycode before wildcard comparison | + /// + /// \snippet ScenarioSharedWorkerWRR.cpp WebResourceRequested2 + /// + function AddWebResourceRequestedFilterWithRequestSourceKinds(const uri: wvstring; + ResourceContext: TWVWebResourceContext; + requestSourceKinds: TWVWebResourceRequestSourceKind): boolean; + /// + /// Removes a matching WebResource filter that was previously added for the + /// `WebResourceRequested` event. If the same filter was added multiple + /// times, then it must be removed as many times as it was added for the + /// removal to be effective. Returns `E_INVALIDARG` for a filter that was + /// not added or is already removed. + /// If the filter was added for multiple requestSourceKinds and removed just for one of them + /// the filter remains for the non-removed requestSourceKinds. + /// + function RemoveWebResourceRequestedFilterWithRequestSourceKinds(const uri: wvstring; + ResourceContext: TWVWebResourceContext; + requestSourceKinds: TWVWebResourceRequestSourceKind): boolean; + + /// + /// Same as `PostWebMessageAsJson`, but also has support for posting DOM objects + /// to page content. The `additionalObjects` property in the DOM MessageEvent + /// fired on the page content is an array-like list of DOM objects that can + /// be posted to the web content. Currently these can be the following + /// types of objects: + /// + /// | Win32 | DOM type | + /// |-------------------|-------------| + /// | ICoreWebView2FileSystemHandle | [FileSystemHandle](https://developer.mozilla.org/docs/Web/API/FileSystemHandle) | + /// | nullptr | null | + /// + /// The objects are posted to the web content, following the + /// [structured-clone](https://developer.mozilla.org/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) + /// semantics, meaning only objects that can be cloned can be posted. + /// They will also behave as if they had been created by the web content they are + /// posted to. For example, if a FileSystemFileHandle is posted to a web content + /// it can only be re-transferred via postMessage to other web content + /// [with the same origin](https://fs.spec.whatwg.org/#filesystemhandle). + /// Warning: An app needs to be mindful when using this API to post DOM objects + /// as this API provides the web content with unusual access to sensitive Web + /// Platform features such as filesystem access! Similar to PostWebMessageAsJson + /// the app should check the `Source` property of WebView2 right before posting the message + /// to ensure the message and objects will only be sent to the target web content + /// that it expects to receive the DOM objects. Additionally, the order + /// of messages that are posted between `PostWebMessageAsJson` and `PostWebMessageAsJsonWithAdditionalObjects` + /// may not be preserved. + /// + function PostWebMessageAsJsonWithAdditionalObjects(const webMessageAsJson: wvstring; + const additionalObjects: ICoreWebView2ObjectCollectionView): boolean; + /// + /// Programmatically trigger a Save As action for the currently loaded document. + /// The `SaveAsUIShowing` event is raised. + /// + /// Opens a system modal dialog by default. If the `SuppressDefaultDialog` property + /// is `TRUE`, the system dialog is not opened. + /// + /// This method returns `COREWEBVIEW2_SAVE_AS_UI_RESULT`. See + /// `COREWEBVIEW2_SAVE_AS_UI_RESULT` for details. + /// + function ShowSaveAsUI(const aBrowserComponent : TComponent) : boolean; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2 read FBaseIntf; + /// + /// The `ICoreWebView2Settings` object contains various modifiable settings + /// for the running WebView. + /// + /// + /// See the ICoreWebView2 article. + /// + property Settings : ICoreWebView2Settings read GetSettings; + /// + /// The process ID of the browser process that hosts the WebView. + /// + /// + /// See the ICoreWebView2 article. + /// + property BrowserProcessID : DWORD read GetBrowserProcessID; + /// + /// `TRUE` if the WebView is able to navigate to a previous page in the + /// navigation history. If `CanGoBack` changes value, the `HistoryChanged` + /// event runs. + /// + /// + /// See the ICoreWebView2 article. + /// + property CanGoBack : boolean read GetCanGoBack; + /// + /// `TRUE` if the WebView is able to navigate to a next page in the + /// navigation history. If `CanGoForward` changes value, the + /// `HistoryChanged` event runs. + /// + /// + /// See the ICoreWebView2 article. + /// + property CanGoForward : boolean read GetCanGoForward; + /// + /// Indicates if the WebView contains a fullscreen HTML element. + /// + /// + /// See the ICoreWebView2 article. + /// + property ContainsFullScreenElement : boolean read GetContainsFullScreenElement; + /// + /// The title for the current top-level document. If the document has no + /// explicit title or is otherwise empty, a default that may or may not match + /// the URI of the document is used. + /// + /// + /// See the ICoreWebView2 article. + /// + property DocumentTitle : wvstring read GetDocumentTitle; + /// + /// The URI of the current top level document. This value potentially + /// changes as a part of the `SourceChanged` event that runs for some cases + /// such as navigating to a different site or fragment navigations. It + /// remains the same for other types of navigations such as page refreshes + /// or `history.pushState` with the same URL as the current page. + /// + /// + /// See the ICoreWebView2 article. + /// + property Source : wvstring read GetSource; + /// + /// Gets the cookie manager object associated with this ICoreWebView2. + /// See ICoreWebView2CookieManager. + /// + /// + /// See the ICoreWebView2_2 article. + /// + property CookieManager : ICoreWebView2CookieManager read GetCookieManager; + /// + /// Exposes the CoreWebView2Environment used to create this CoreWebView2. + /// + /// + /// See the ICoreWebView2_2 article. + /// + property Environment : ICoreWebView2Environment read GetEnvironment; + /// + /// Whether WebView is suspended. + /// `TRUE` when WebView is suspended, from the time when TrySuspend has completed + /// successfully until WebView is resumed. + /// + /// + /// See the ICoreWebView2_3 article. + /// + property IsSuspended : boolean read GetIsSuspended; + /// + /// Indicates whether all audio output from this CoreWebView2 is muted or not. + /// + /// + /// See the ICoreWebView2_8 article. + /// + property IsMuted : boolean read GetIsMuted write SetIsMuted; + /// + /// Indicates whether any audio output from this CoreWebView2 is playing. + /// This property will be true if audio is playing even if IsMuted is true. + /// + /// + /// See the ICoreWebView2_8 article. + /// + property IsDocumentPlayingAudio : boolean read GetIsDocumentPlayingAudio; + /// + /// `TRUE` if the default download dialog is currently open. The value of this + /// property changes only when the default download dialog is explicitly + /// opened or closed. Hiding the WebView implicitly hides the dialog, but does + /// not change the value of this property. + /// + /// + /// See the ICoreWebView2_9 article. + /// + property IsDefaultDownloadDialogOpen : boolean read GetIsDefaultDownloadDialogOpen; + /// + /// Get the default download dialog corner alignment. + /// + /// + /// See the ICoreWebView2_9 article. + /// + property DefaultDownloadDialogCornerAlignment : TWVDefaultDownloadDialogCornerAlignment read GetDefaultDownloadDialogCornerAlignment write SetDefaultDownloadDialogCornerAlignment; + /// + /// Get the default download dialog margin. + /// + /// + /// See the ICoreWebView2_9 article. + /// + property DefaultDownloadDialogMargin : TPoint read GetDefaultDownloadDialogMargin write SetDefaultDownloadDialogMargin; + /// + /// The status message text. + /// + /// + /// See the ICoreWebView2_12 article. + /// + property StatusBarText : wvstring read GetStatusBarText; + /// + /// The associated `ICoreWebView2Profile` object. If this CoreWebView2 was created with a + /// CoreWebView2ControllerOptions, the CoreWebView2Profile will match those specified options. + /// Otherwise if this CoreWebView2 was created without a CoreWebView2ControllerOptions, then + /// this will be the default CoreWebView2Profile for the corresponding CoreWebView2Environment. + /// + /// + /// See the ICoreWebView2_13 article. + /// + property Profile : ICoreWebView2Profile read GetProfile; + /// + /// Get the current Uri of the favicon as a string. + /// If the value is null, then the return value is `E_POINTER`, otherwise it is `S_OK`. + /// If a page has no favicon then the value is an empty string. + /// + /// + /// See the ICoreWebView2_15 article. + /// + property FaviconURI : wvstring read GetFaviconURI; + /// + /// `MemoryUsageTargetLevel` indicates desired memory consumption level of + /// WebView. + /// + /// + /// See the ICoreWebView2_19 article. + /// + property MemoryUsageTargetLevel : TWVMemoryUsageTargetLevel read GetMemoryUsageTargetLevel write SetMemoryUsageTargetLevel; + /// + /// The unique identifier of the main frame. It's the same kind of ID as + /// with the `FrameId` in `ICoreWebView2Frame` and via `ICoreWebView2FrameInfo`. + /// Note that `FrameId` may not be valid if `ICoreWebView2` has not done + /// any navigation. It's safe to get this value during or after the first + /// `ContentLoading` event. Otherwise, it could return the invalid frame Id 0. + /// + /// + /// See the ICoreWebView2_20 article. + /// + property FrameId : cardinal read GetFrameID; + /// + /// Retrieves the find session interface for the current web view. + /// + /// + /// See the ICoreWebView2_28 article. + /// + property Find : ICoreWebView2Find read GetFind; + end; + +implementation + +uses + uRESTDWPrivWVBrowserBase, uRESTDWPrivWVCoreWebView2Delegates, uRESTDWPrivWVMiscFunctions, uRESTDWPrivWVConstants; + +constructor TCoreWebView2.Create(const aBaseIntf : ICoreWebView2); +begin + inherited Create; + + InitializeFields; + + FBaseIntf := aBaseIntf; + + if Initialized and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_2, FBaseIntf2) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_3, FBaseIntf3) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_4, FBaseIntf4) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_5, FBaseIntf5) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_6, FBaseIntf6) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_7, FBaseIntf7) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_8, FBaseIntf8) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_9, FBaseIntf9) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_10, FBaseIntf10) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_11, FBaseIntf11) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_12, FBaseIntf12) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_13, FBaseIntf13) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_14, FBaseIntf14) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_15, FBaseIntf15) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_16, FBaseIntf16) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_17, FBaseIntf17) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_18, FBaseIntf18) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_19, FBaseIntf19) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_20, FBaseIntf20) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_21, FBaseIntf21) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_22, FBaseIntf22) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_23, FBaseIntf23) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_24, FBaseIntf24) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_25, FBaseIntf25) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_26, FBaseIntf26) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_27, FBaseIntf27) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_28, FBaseIntf28) then + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2_29, FBaseIntf29); +end; + +destructor TCoreWebView2.Destroy; +begin + try + RemoveAllEvents; + + if (FDevToolsEventTokens <> nil) then + begin + Finalize(FDevToolsEventTokens); + FDevToolsEventTokens := nil; + end; + + if (FDevToolsEventNames <> nil) then + FreeAndNil(FDevToolsEventNames); + + InitializeFields; + finally + inherited Destroy; + end; +end; + +procedure TCoreWebView2.AfterConstruction; +begin + inherited AfterConstruction; + + FDevToolsEventNames := TStringList.Create; +end; + +procedure TCoreWebView2.InitializeFields; +begin + FBaseIntf := nil; + FBaseIntf2 := nil; + FBaseIntf3 := nil; + FBaseIntf4 := nil; + FBaseIntf5 := nil; + FBaseIntf6 := nil; + FBaseIntf7 := nil; + FBaseIntf8 := nil; + FBaseIntf9 := nil; + FBaseIntf10 := nil; + FBaseIntf11 := nil; + FBaseIntf12 := nil; + FBaseIntf13 := nil; + FBaseIntf14 := nil; + FBaseIntf15 := nil; + FBaseIntf16 := nil; + FBaseIntf17 := nil; + FBaseIntf18 := nil; + FBaseIntf19 := nil; + FBaseIntf20 := nil; + FBaseIntf21 := nil; + FBaseIntf22 := nil; + FBaseIntf23 := nil; + FBaseIntf24 := nil; + FBaseIntf25 := nil; + FBaseIntf26 := nil; + FBaseIntf27 := nil; + FBaseIntf28 := nil; + FBaseIntf29 := nil; + FDevToolsEventTokens := nil; + FDevToolsEventNames := nil; + FFrameIDCopy := WEBVIEW4DELPHI_INVALID_FRAMEID; + + InitializeTokens; +end; + +procedure TCoreWebView2.InitializeTokens; +begin + FContainsFullScreenElementChangedToken.value := 0; + FContentLoadingToken.value := 0; + FDocumentTitleChangedToken.value := 0; + FFrameNavigationStartingToken.value := 0; + FFrameNavigationCompletedToken.value := 0; + FHistoryChangedToken.value := 0; + FNavigationStartingToken.value := 0; + FNavigationCompletedToken.value := 0; + FNewWindowRequestedToken.value := 0; + FPermissionRequestedToken.value := 0; + FProcessFailedToken.value := 0; + FScriptDialogOpeningToken.value := 0; + FSourceChangedToken.value := 0; + FWebResourceRequestedToken.value := 0; + FWebMessageReceivedToken.value := 0; + FWindowCloseRequestedToken.value := 0; + FWebResourceResponseReceivedToken.value := 0; + FDOMContentLoadedToken.value := 0; + FFrameCreatedToken.value := 0; + FDownloadStartingToken.value := 0; + FClientCertificateRequestedToken.value := 0; + FIsMutedChangedToken.value := 0; + FIsDocumentPlayingAudioChangedToken.value := 0; + FIsDefaultDownloadDialogOpenChangedToken.value := 0; + FBasicAuthenticationRequestedToken.value := 0; + FContextMenuRequestedToken.value := 0; + FStatusBarTextChangedToken.value := 0; + FServerCertificateErrorDetectedToken.value := 0; + FFaviconChangedToken.value := 0; + FLaunchingExternalUriSchemeToken.value := 0; + FNotificationReceivedToken.value := 0; + FSaveAsUIShowingToken.value := 0; + FSaveFileSecurityCheckStartingToken.value := 0; + FScreenCaptureStartingToken.value := 0; + FDedicatedWorkerCreatedToken.value := 0; +end; + +function TCoreWebView2.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +procedure TCoreWebView2.RemoveAllEvents; +begin + try + try + if Initialized then + begin + if (FNavigationStartingToken.value <> 0) then + FBaseIntf.remove_NavigationStarting(FNavigationStartingToken); + + if (FNavigationCompletedToken.value <> 0) then + FBaseIntf.remove_NavigationCompleted(FNavigationCompletedToken); + + if (FSourceChangedToken.value <> 0) then + FBaseIntf.remove_SourceChanged(FSourceChangedToken); + + if (FHistoryChangedToken.value <> 0) then + FBaseIntf.remove_HistoryChanged(FHistoryChangedToken); + + if (FContentLoadingToken.value <> 0) then + FBaseIntf.remove_ContentLoading(FContentLoadingToken); + + if (FDocumentTitleChangedToken.value <> 0) then + FBaseIntf.remove_DocumentTitleChanged(FDocumentTitleChangedToken); + + if (FNewWindowRequestedToken.value <> 0) then + FBaseIntf.remove_NewWindowRequested(FNewWindowRequestedToken); + + if (FFrameNavigationStartingToken.value <> 0) then + FBaseIntf.remove_FrameNavigationStarting(FFrameNavigationStartingToken); + + if (FFrameNavigationCompletedToken.value <> 0) then + FBaseIntf.remove_FrameNavigationCompleted(FFrameNavigationCompletedToken); + + if (FWebResourceRequestedToken.value <> 0) then + FBaseIntf.remove_WebResourceRequested(FWebResourceRequestedToken); + + if (FScriptDialogOpeningToken.value <> 0) then + FBaseIntf.remove_ScriptDialogOpening(FScriptDialogOpeningToken); + + if (FPermissionRequestedToken.value <> 0) then + FBaseIntf.remove_PermissionRequested(FPermissionRequestedToken); + + if (FProcessFailedToken.value <> 0) then + FBaseIntf.remove_ProcessFailed(FProcessFailedToken); + + if (FWebMessageReceivedToken.value <> 0) then + FBaseIntf.remove_WebMessageReceived(FWebMessageReceivedToken); + + if (FWindowCloseRequestedToken.value <> 0) then + FBaseIntf.remove_WindowCloseRequested(FWindowCloseRequestedToken); + + if (FContainsFullScreenElementChangedToken.value <> 0) then + FBaseIntf.remove_ContainsFullScreenElementChanged(FContainsFullScreenElementChangedToken); + + if assigned(FBaseIntf2) then + begin + if (FWebResourceResponseReceivedToken.value <> 0) then + FBaseIntf2.remove_WebResourceResponseReceived(FWebResourceResponseReceivedToken); + + if (FDOMContentLoadedToken.value <> 0) then + FBaseIntf2.remove_DOMContentLoaded(FDOMContentLoadedToken); + end; + + if assigned(FBaseIntf4) then + begin + if (FFrameCreatedToken.value <> 0) then + FBaseIntf4.remove_FrameCreated(FFrameCreatedToken); + + if (FDownloadStartingToken.value <> 0) then + FBaseIntf4.remove_DownloadStarting(FDownloadStartingToken); + end; + +// Access violation when we try to remove this event +// if assigned(FBaseIntf5) and +// (FClientCertificateRequestedToken.value <> 0) then +// FBaseIntf5.remove_ClientCertificateRequested(FClientCertificateRequestedToken); + + if assigned(FBaseIntf8) then + begin + if (FIsMutedChangedToken.value <> 0) then + FBaseIntf8.remove_IsMutedChanged(FIsMutedChangedToken); + + if (FIsDocumentPlayingAudioChangedToken.value <> 0) then + FBaseIntf8.remove_IsDocumentPlayingAudioChanged(FIsDocumentPlayingAudioChangedToken); + end; + + if assigned(FBaseIntf9) and + (FIsDefaultDownloadDialogOpenChangedToken.value <> 0) then + FBaseIntf9.remove_IsDefaultDownloadDialogOpenChanged(FIsDefaultDownloadDialogOpenChangedToken); + + if assigned(FBaseIntf10) and + (FBasicAuthenticationRequestedToken.Value <> 0) then + FBaseIntf10.remove_BasicAuthenticationRequested(FBasicAuthenticationRequestedToken); + + if assigned(FBaseIntf11) and + (FContextMenuRequestedToken.Value <> 0) then + FBaseIntf11.remove_ContextMenuRequested(FContextMenuRequestedToken); + + if assigned(FBaseIntf12) and + (FStatusBarTextChangedToken.Value <> 0) then + FBaseIntf12.remove_StatusBarTextChanged(FStatusBarTextChangedToken); + +// Access violation when we try to remove this event +// if assigned(FBaseIntf14) and +// (FServerCertificateErrorDetectedToken.Value <> 0) then +// FBaseIntf14.remove_ServerCertificateErrorDetected(FServerCertificateErrorDetectedToken); + + if assigned(FBaseIntf15) and + (FFaviconChangedToken.Value <> 0) then + FBaseIntf15.remove_FaviconChanged(FFaviconChangedToken); + + if assigned(FBaseIntf18) and + (FLaunchingExternalUriSchemeToken.Value <> 0) then + FBaseIntf18.remove_LaunchingExternalUriScheme(FLaunchingExternalUriSchemeToken); + + if assigned(FBaseIntf24) and + (FNotificationReceivedToken.value <> 0) then + FBaseIntf24.remove_NotificationReceived(FNotificationReceivedToken); + + if assigned(FBaseIntf25) and + (FSaveAsUIShowingToken.value <> 0) then + FBaseIntf25.remove_SaveAsUIShowing(FSaveAsUIShowingToken); + + if assigned(FBaseIntf26) and + (FSaveFileSecurityCheckStartingToken.value <> 0) then + FBaseIntf26.remove_SaveFileSecurityCheckStarting(FSaveFileSecurityCheckStartingToken); + + if assigned(FBaseIntf27) and + (FScreenCaptureStartingToken.value <> 0) then + FBaseIntf27.remove_ScreenCaptureStarting(FScreenCaptureStartingToken); + + if assigned(FBaseIntf29) and + (FDedicatedWorkerCreatedToken.value <> 0) then + FBaseIntf29.remove_DedicatedWorkerCreated(FDedicatedWorkerCreatedToken); + + UnsubscribeAllDevToolsProtocolEvents; + end; + except + on e : exception do + if CustomExceptionHandler('TCoreWebView2.RemoveAllEvents', e) then raise; + end; + finally + InitializeTokens; + end; +end; + +function TCoreWebView2.AddNavigationStartingEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2NavigationStartingEventHandler; +begin + Result := False; + + if Initialized and (FNavigationStartingToken.value = 0) then + try + TempHandler := TCoreWebView2NavigationStartingEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_NavigationStarting(TempHandler, FNavigationStartingToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddNavigationCompletedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2NavigationCompletedEventHandler; +begin + Result := False; + + if Initialized and (FNavigationCompletedToken.value = 0) then + try + TempHandler := TCoreWebView2NavigationCompletedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_NavigationCompleted(TempHandler, FNavigationCompletedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddSourceChangedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2SourceChangedEventHandler; +begin + Result := False; + + if Initialized and (FSourceChangedToken.value = 0) then + try + TempHandler := TCoreWebView2SourceChangedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_SourceChanged(TempHandler, FSourceChangedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddHistoryChangedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2HistoryChangedEventHandler; +begin + Result := False; + + if Initialized and (FHistoryChangedToken.value = 0) then + try + TempHandler := TCoreWebView2HistoryChangedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_HistoryChanged(TempHandler, FHistoryChangedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddContentLoadingEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2ContentLoadingEventHandler; +begin + Result := False; + + if Initialized and (FContentLoadingToken.value = 0) then + try + TempHandler := TCoreWebView2ContentLoadingEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_ContentLoading(TempHandler, FContentLoadingToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddDocumentTitleChangedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2DocumentTitleChangedEventHandler; +begin + Result := False; + + if Initialized and (FDocumentTitleChangedToken.value = 0) then + try + TempHandler := TCoreWebView2DocumentTitleChangedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_DocumentTitleChanged(TempHandler, FDocumentTitleChangedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddNewWindowRequestedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2NewWindowRequestedEventHandler; +begin + Result := False; + + if Initialized and (FNewWindowRequestedToken.value = 0) then + try + TempHandler := TCoreWebView2NewWindowRequestedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_NewWindowRequested(TempHandler, FNewWindowRequestedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddFrameNavigationStartingEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2NavigationStartingEventHandler; +begin + Result := False; + + if Initialized and (FFrameNavigationStartingToken.value = 0) then + try + TempHandler := TCoreWebView2FrameNavigationStartingEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_FrameNavigationStarting(TempHandler, FFrameNavigationStartingToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddFrameNavigationCompletedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2NavigationCompletedEventHandler; +begin + Result := False; + + if Initialized and (FFrameNavigationCompletedToken.value = 0) then + try + TempHandler := TCoreWebView2FrameNavigationCompletedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_FrameNavigationCompleted(TempHandler, FFrameNavigationCompletedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddWebResourceRequestedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2WebResourceRequestedEventHandler; +begin + Result := False; + + if Initialized and (FWebResourceRequestedToken.value = 0) then + try + TempHandler := TCoreWebView2WebResourceRequestedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_WebResourceRequested(TempHandler, FWebResourceRequestedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddScriptDialogOpeningEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2ScriptDialogOpeningEventHandler; +begin + Result := False; + + if Initialized and (FScriptDialogOpeningToken.value = 0) then + try + TempHandler := TCoreWebView2ScriptDialogOpeningEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_ScriptDialogOpening(TempHandler, FScriptDialogOpeningToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddPermissionRequestedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2PermissionRequestedEventHandler; +begin + Result := False; + + if Initialized and (FPermissionRequestedToken.value = 0) then + try + TempHandler := TCoreWebView2PermissionRequestedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_PermissionRequested(TempHandler, FPermissionRequestedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddProcessFailedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2ProcessFailedEventHandler; +begin + Result := False; + + if Initialized and (FProcessFailedToken.value = 0) then + try + TempHandler := TCoreWebView2ProcessFailedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_ProcessFailed(TempHandler, FProcessFailedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddWebMessageReceivedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2WebMessageReceivedEventHandler; +begin + Result := False; + + if Initialized and (FWebMessageReceivedToken.value = 0) then + try + TempHandler := TCoreWebView2WebMessageReceivedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_WebMessageReceived(TempHandler, FWebMessageReceivedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddContainsFullScreenElementChangedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2ContainsFullScreenElementChangedEventHandler; +begin + Result := False; + + if Initialized and (FContainsFullScreenElementChangedToken.value = 0) then + try + TempHandler := TCoreWebView2ContainsFullScreenElementChangedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_ContainsFullScreenElementChanged(TempHandler, FContainsFullScreenElementChangedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddWindowCloseRequestedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2WindowCloseRequestedEventHandler; +begin + Result := False; + + if Initialized and (FWindowCloseRequestedToken.value = 0) then + try + TempHandler := TCoreWebView2WindowCloseRequestedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_WindowCloseRequested(TempHandler, FWindowCloseRequestedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddWebResourceResponseReceivedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2WebResourceResponseReceivedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf2) and (FWebResourceResponseReceivedToken.value = 0) then + try + TempHandler := TCoreWebView2WebResourceResponseReceivedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf2.add_WebResourceResponseReceived(TempHandler, FWebResourceResponseReceivedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddDOMContentLoadedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2DOMContentLoadedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf2) and (FDOMContentLoadedToken.value = 0) then + try + TempHandler := TCoreWebView2DOMContentLoadedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf2.add_DOMContentLoaded(TempHandler, FDOMContentLoadedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddFrameCreatedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2FrameCreatedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf4) and (FFrameCreatedToken.value = 0) then + try + TempHandler := TCoreWebView2FrameCreatedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf4.add_FrameCreated(TempHandler, FFrameCreatedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddDownloadStartingEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2DownloadStartingEventHandler; +begin + Result := False; + + if assigned(FBaseIntf4) and (FDownloadStartingToken.value = 0) then + try + TempHandler := TCoreWebView2DownloadStartingEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf4.add_DownloadStarting(TempHandler, FDownloadStartingToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddClientCertificateRequestedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2ClientCertificateRequestedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf5) and (FClientCertificateRequestedToken.value = 0) then + try + TempHandler := TCoreWebView2ClientCertificateRequestedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf5.add_ClientCertificateRequested(TempHandler, FClientCertificateRequestedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddIsMutedChangedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2IsMutedChangedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf8) and (FIsMutedChangedToken.value = 0) then + try + TempHandler := TCoreWebView2IsMutedChangedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf8.add_IsMutedChanged(TempHandler, FIsMutedChangedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddIsDocumentPlayingAudioChangedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2IsDocumentPlayingAudioChangedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf8) and (FIsDocumentPlayingAudioChangedToken.value = 0) then + try + TempHandler := TCoreWebView2IsDocumentPlayingAudioChangedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf8.add_IsDocumentPlayingAudioChanged(TempHandler, FIsDocumentPlayingAudioChangedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddIsDefaultDownloadDialogOpenChangedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2IsDefaultDownloadDialogOpenChangedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf9) and (FIsDefaultDownloadDialogOpenChangedToken.value = 0) then + try + TempHandler := TCoreWebView2IsDefaultDownloadDialogOpenChangedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf9.add_IsDefaultDownloadDialogOpenChanged(TempHandler, FIsDefaultDownloadDialogOpenChangedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddBasicAuthenticationRequestedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2BasicAuthenticationRequestedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf10) and (FBasicAuthenticationRequestedToken.value = 0) then + try + TempHandler := TCoreWebView2BasicAuthenticationRequestedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf10.add_BasicAuthenticationRequested(TempHandler, FBasicAuthenticationRequestedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddContextMenuRequestedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2ContextMenuRequestedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf11) and (FContextMenuRequestedToken.value = 0) then + try + TempHandler := TCoreWebView2ContextMenuRequestedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf11.add_ContextMenuRequested(TempHandler, FContextMenuRequestedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddStatusBarTextChangedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2StatusBarTextChangedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf12) and (FStatusBarTextChangedToken.value = 0) then + try + TempHandler := TCoreWebView2StatusBarTextChangedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf12.add_StatusBarTextChanged(TempHandler, FStatusBarTextChangedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddServerCertificateErrorDetectedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2ServerCertificateErrorDetectedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf14) and (FServerCertificateErrorDetectedToken.value = 0) then + try + TempHandler := TCoreWebView2ServerCertificateErrorDetectedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf14.add_ServerCertificateErrorDetected(TempHandler, FServerCertificateErrorDetectedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddFaviconChanged(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2FaviconChangedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf15) and (FFaviconChangedToken.value = 0) then + try + TempHandler := TCoreWebView2FaviconChangedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf15.add_FaviconChanged(TempHandler, FFaviconChangedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddLaunchingExternalUriScheme(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2LaunchingExternalUriSchemeEventHandler; +begin + Result := False; + + if assigned(FBaseIntf18) and (FLaunchingExternalUriSchemeToken.value = 0) then + try + TempHandler := TCoreWebView2LaunchingExternalUriSchemeEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf18.add_LaunchingExternalUriScheme(TempHandler, FLaunchingExternalUriSchemeToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddNotificationReceived(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2NotificationReceivedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf24) and (FNotificationReceivedToken.value = 0) then + try + TempHandler := TCoreWebView2NotificationReceivedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf24.add_NotificationReceived(TempHandler, FNotificationReceivedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddSaveAsUIShowing(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2SaveAsUIShowingEventHandler; +begin + Result := False; + + if assigned(FBaseIntf25) and (FSaveAsUIShowingToken.value = 0) then + try + TempHandler := TCoreWebView2SaveAsUIShowingEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf25.add_SaveAsUIShowing(TempHandler, FSaveAsUIShowingToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddSaveFileSecurityCheckStarting(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2SaveFileSecurityCheckStartingEventHandler; +begin + Result := False; + + if assigned(FBaseIntf26) and (FSaveFileSecurityCheckStartingToken.value = 0) then + try + TempHandler := TCoreWebView2SaveFileSecurityCheckStartingEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf26.add_SaveFileSecurityCheckStarting(TempHandler, FSaveFileSecurityCheckStartingToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddScreenCaptureStarting(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2ScreenCaptureStartingEventHandler; +begin + Result := False; + + if assigned(FBaseIntf27) and (FScreenCaptureStartingToken.value = 0) then + try + TempHandler := TCoreWebView2ScreenCaptureStartingEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf27.add_ScreenCaptureStarting(TempHandler, FScreenCaptureStartingToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddDedicatedWorkerCreated(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2DedicatedWorkerCreatedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf29) and (FDedicatedWorkerCreatedToken.value = 0) then + try + TempHandler := TCoreWebView2DedicatedWorkerCreatedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf29.add_DedicatedWorkerCreated(TempHandler, FDedicatedWorkerCreatedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddAllBrowserEvents(const aBrowserComponent : TComponent) : boolean; +begin + Result := AddNavigationStartingEvent(aBrowserComponent) and + AddNavigationCompletedEvent(aBrowserComponent) and + AddSourceChangedEvent(aBrowserComponent) and + AddHistoryChangedEvent(aBrowserComponent) and + AddContentLoadingEvent(aBrowserComponent) and + AddDocumentTitleChangedEvent(aBrowserComponent) and + AddNewWindowRequestedEvent(aBrowserComponent) and + AddFrameNavigationStartingEvent(aBrowserComponent) and + AddFrameNavigationCompletedEvent(aBrowserComponent) and + AddWebResourceRequestedEvent(aBrowserComponent) and + AddScriptDialogOpeningEvent(aBrowserComponent) and + AddPermissionRequestedEvent(aBrowserComponent) and + AddProcessFailedEvent(aBrowserComponent) and + AddWebMessageReceivedEvent(aBrowserComponent) and + AddContainsFullScreenElementChangedEvent(aBrowserComponent) and + AddWindowCloseRequestedEvent(aBrowserComponent) and + AddWebResourceResponseReceivedEvent(aBrowserComponent) and + AddDOMContentLoadedEvent(aBrowserComponent) and + AddFrameCreatedEvent(aBrowserComponent) and + AddDownloadStartingEvent(aBrowserComponent) and + AddClientCertificateRequestedEvent(aBrowserComponent) and + AddIsMutedChangedEvent(aBrowserComponent) and + AddIsDocumentPlayingAudioChangedEvent(aBrowserComponent) and + AddIsDefaultDownloadDialogOpenChangedEvent(aBrowserComponent) and + AddBasicAuthenticationRequestedEvent(aBrowserComponent) and + AddContextMenuRequestedEvent(aBrowserComponent) and + AddStatusBarTextChangedEvent(aBrowserComponent) and + AddServerCertificateErrorDetectedEvent(aBrowserComponent) and + AddFaviconChanged(aBrowserComponent) and + AddLaunchingExternalUriScheme(aBrowserComponent) and + AddNotificationReceived(aBrowserComponent) and + AddSaveAsUIShowing(aBrowserComponent) and + AddSaveFileSecurityCheckStarting(aBrowserComponent) and + AddScreenCaptureStarting(aBrowserComponent) and + AddDedicatedWorkerCreated(aBrowserComponent); +end; + +function TCoreWebView2.AddWebResourceRequestedFilter(const URI : wvstring; + ResourceContext : TWVWebResourceContext) : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.AddWebResourceRequestedFilter(PWideChar(URI), ResourceContext)); +end; + +function TCoreWebView2.RemoveWebResourceRequestedFilter(const URI : wvstring; + ResourceContext : TWVWebResourceContext) : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.RemoveWebResourceRequestedFilter(PWideChar(URI), ResourceContext)); +end; + +function TCoreWebView2.CapturePreview( aImageFormat : TWVCapturePreviewImageFormat; + const aImageStream : IStream; + const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2CapturePreviewCompletedHandler; +begin + Result := False; + + if Initialized then + try + TempHandler := TCoreWebView2CapturePreviewCompletedHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.CapturePreview(aImageFormat, aImageStream, TempHandler)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.SubscribeToDevToolsProtocolEvent(const aEventName : wvstring; + aEventID : integer; + const aBrowserComponent : TComponent) : boolean; +var + TempReceiver : ICoreWebView2DevToolsProtocolEventReceiver; + TempHandler : ICoreWebView2DevToolsProtocolEventReceivedEventHandler; + TempToken : EventRegistrationToken; + i : integer; +begin + Result := False; + + if Initialized and + (FDevToolsEventNames <> nil) and + {$IFDEF FPC} + (FDevToolsEventNames.IndexOf(UTF8Encode(aEventName)) < 0) and + {$ELSE} + (FDevToolsEventNames.IndexOf(aEventName) < 0) and + {$ENDIF} + succeeded(FBaseIntf.GetDevToolsProtocolEventReceiver(PWideChar(aEventName), TempReceiver)) then + try + TempHandler := TCoreWebView2DevToolsProtocolEventReceivedEventHandler.Create(TWVBrowserBase(aBrowserComponent), aEventName, aEventID); + + if succeeded(TempReceiver.add_DevToolsProtocolEventReceived(TempHandler, TempToken)) then + begin + {$IFDEF FPC} + FDevToolsEventNames.Add(UTF8Encode(aEventName)); + {$ELSE} + FDevToolsEventNames.Add(aEventName); + {$ENDIF} + i := length(FDevToolsEventTokens); + SetLength(FDevToolsEventTokens, succ(i)); + FDevToolsEventTokens[i] := TempToken; + Result := True; + end; + finally + TempHandler := nil; + end; +end; + +procedure TCoreWebView2.UnsubscribeAllDevToolsProtocolEvents; +var + TempReceiver : ICoreWebView2DevToolsProtocolEventReceiver; + i : integer; + TempEventName : wvstring; +begin + if (FDevToolsEventNames = nil) or (FDevToolsEventNames.Count = 0) or not(Initialized) then + exit; + + try + try + i := pred(FDevToolsEventNames.Count); + + while (i >= 0) do + begin + {$IFDEF FPC} + TempEventName := UTF8Decode(FDevToolsEventNames[i]); + {$ELSE} + TempEventName := FDevToolsEventNames[i]; + {$ENDIF} + if succeeded(FBaseIntf.GetDevToolsProtocolEventReceiver(PWideChar(TempEventName), TempReceiver)) then + TempReceiver.remove_DevToolsProtocolEventReceived(FDevToolsEventTokens[i]); + + dec(i); + end; + except + on e : exception do + if CustomExceptionHandler('TCoreWebView2.UnsubscribeAllDevToolsProtocolEvents', e) then raise; + end; + finally + FDevToolsEventNames.Clear; + SetLength(FDevToolsEventTokens, 0); + end; +end; + +function TCoreWebView2.ExecuteScript(const JavaScript: wvstring; aExecutionID : integer; const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2ExecuteScriptCompletedHandler; +begin + Result := False; + + if Initialized and (length(JavaScript) > 0) then + try + TempHandler := TCoreWebView2ExecuteScriptCompletedHandler.Create(TWVBrowserBase(aBrowserComponent), aExecutionID); + Result := succeeded(FBaseIntf.ExecuteScript(PWideChar(JavaScript), TempHandler)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.GoBack : boolean; +begin + Result := CanGoBack and + succeeded(FBaseIntf.GoBack); +end; + +function TCoreWebView2.GoForward : boolean; +begin + Result := CanGoForward and + succeeded(FBaseIntf.GoForward); +end; + +function TCoreWebView2.Navigate(const aURI : wvstring) : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.Navigate(PWideChar(aURI))); +end; + +function TCoreWebView2.NavigateToString(const aHTMLContent : wvstring) : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.NavigateToString(PWideChar(aHTMLContent))); +end; + +function TCoreWebView2.NavigateWithWebResourceRequest(const aRequest : ICoreWebView2WebResourceRequest) : boolean; +begin + Result := assigned(FBaseIntf2) and + succeeded(FBaseIntf2.NavigateWithWebResourceRequest(aRequest)); +end; + +function TCoreWebView2.Reload : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.Reload); +end; + +function TCoreWebView2.Stop : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.Stop); +end; + +function TCoreWebView2.TrySuspend(const aHandler: ICoreWebView2TrySuspendCompletedHandler) : boolean; +begin + Result := assigned(FBaseIntf3) and + succeeded(FBaseIntf3.TrySuspend(aHandler)); +end; + +function TCoreWebView2.Resume : boolean; +begin + Result := assigned(FBaseIntf3) and + succeeded(FBaseIntf3.Resume); +end; + +function TCoreWebView2.SetVirtualHostNameToFolderMapping(const aHostName, aFolderPath : wvstring; aAccessKind : TWVHostResourceAcccessKind): boolean; +begin + Result := assigned(FBaseIntf3) and + succeeded(FBaseIntf3.SetVirtualHostNameToFolderMapping(PWideChar(aHostName), PWideChar(aFolderPath), aAccessKind)); +end; + +function TCoreWebView2.ClearVirtualHostNameToFolderMapping(const aHostName : wvstring) : boolean; +begin + Result := assigned(FBaseIntf3) and + succeeded(FBaseIntf3.ClearVirtualHostNameToFolderMapping(PWideChar(aHostName))); +end; + +function TCoreWebView2.OpenTaskManagerWindow : boolean; +begin + Result := assigned(FBaseIntf6) and + succeeded(FBaseIntf6.OpenTaskManagerWindow); +end; + +function TCoreWebView2.PrintToPdf(const aResultFilePath : wvstring; + const aPrintSettings : ICoreWebView2PrintSettings; + const aHandler : ICoreWebView2PrintToPdfCompletedHandler) : boolean; +begin + Result := False; + + if assigned(FBaseIntf7) and + (length(aResultFilePath) > 0) and + assigned(aPrintSettings) and + assigned(aHandler) then + Result := succeeded(FBaseIntf7.PrintToPdf(PWideChar(aResultFilePath), aPrintSettings, aHandler)); +end; + +function TCoreWebView2.OpenDevToolsWindow : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.OpenDevToolsWindow); +end; + +function TCoreWebView2.PostWebMessageAsJson(const aWebMessageAsJson : wvstring) : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.PostWebMessageAsJson(PWideChar(aWebMessageAsJson))); +end; + +function TCoreWebView2.PostWebMessageAsString(const aWebMessageAsString : wvstring) : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.PostWebMessageAsString(PWideChar(aWebMessageAsString))); +end; + +function TCoreWebView2.CallDevToolsProtocolMethod(const aMethodName, aParametersAsJson : wvstring; aExecutionID : integer; const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2CallDevToolsProtocolMethodCompletedHandler; +begin + Result := False; + + if Initialized then + try + TempHandler := TCoreWebView2CallDevToolsProtocolMethodCompletedHandler.Create(TWVBrowserBase(aBrowserComponent), aExecutionID); + Result := succeeded(FBaseIntf.CallDevToolsProtocolMethod(PWideChar(aMethodName), PWideChar(aParametersAsJson), TempHandler)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.CallDevToolsProtocolMethodForSession(const aSessionId, aMethodName, aParametersAsJson : wvstring; aExecutionID : integer; const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2CallDevToolsProtocolMethodCompletedHandler; +begin + Result := False; + + if assigned(FBaseIntf11) then + try + TempHandler := TCoreWebView2CallDevToolsProtocolMethodCompletedHandler.Create(TWVBrowserBase(aBrowserComponent), aExecutionID); + Result := succeeded(FBaseIntf11.CallDevToolsProtocolMethodForSession(PWideChar(aSessionId), PWideChar(aMethodName), PWideChar(aParametersAsJson), TempHandler)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddHostObjectToScript(const aName : wvstring; const aObject : OleVariant) : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.AddHostObjectToScript(PWideChar(aName), aObject)); +end; + +function TCoreWebView2.RemoveHostObjectFromScript(const aName : wvstring) : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.RemoveHostObjectFromScript(PWideChar(aName))); +end; + +function TCoreWebView2.AddScriptToExecuteOnDocumentCreated(const JavaScript : wvstring; const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler; +begin + Result := False; + + if Initialized then + try + TempHandler := TCoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.AddScriptToExecuteOnDocumentCreated(PWideChar(JavaScript), TempHandler)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.RemoveScriptToExecuteOnDocumentCreated(const aID : wvstring) : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.RemoveScriptToExecuteOnDocumentCreated(PWideChar(aID))); +end; + +function TCoreWebView2.OpenDefaultDownloadDialog : boolean; +begin + Result := assigned(FBaseIntf9) and + succeeded(FBaseIntf9.OpenDefaultDownloadDialog); +end; + +function TCoreWebView2.CloseDefaultDownloadDialog : boolean; +begin + Result := assigned(FBaseIntf9) and + succeeded(FBaseIntf9.CloseDefaultDownloadDialog); +end; + +function TCoreWebView2.ClearServerCertificateErrorActions(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2ClearServerCertificateErrorActionsCompletedHandler; +begin + Result := False; + + if assigned(FBaseIntf14) then + try + TempHandler := TCoreWebView2ClearServerCertificateErrorActionsCompletedHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf14.ClearServerCertificateErrorActions(TempHandler)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.GetFavicon(aFormat: TWVFaviconImageFormat; const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2GetFaviconCompletedHandler; +begin + Result := False; + + if assigned(FBaseIntf15) then + try + TempHandler := TCoreWebView2GetFaviconCompletedHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf15.GetFavicon(aFormat, TempHandler)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.Print(const aPrintSettings : ICoreWebView2PrintSettings; + const aHandler : ICoreWebView2PrintCompletedHandler): boolean; +begin + Result := assigned(FBaseIntf16) and + succeeded(FBaseIntf16.Print(aPrintSettings, aHandler)); +end; + +function TCoreWebView2.ShowPrintUI(aPrintDialogKind: TWVPrintDialogKind): boolean; +begin + Result := assigned(FBaseIntf16) and + succeeded(FBaseIntf16.ShowPrintUI(aPrintDialogKind)); +end; + +function TCoreWebView2.PrintToPdfStream(const aPrintSettings : ICoreWebView2PrintSettings; + const aHandler : ICoreWebView2PrintToPdfStreamCompletedHandler): boolean; +begin + Result := assigned(FBaseIntf16) and + succeeded(FBaseIntf16.PrintToPdfStream(aPrintSettings, aHandler)); +end; + +function TCoreWebView2.PostSharedBufferToScript(const aSharedBuffer : ICoreWebView2SharedBuffer; + aAccess : TWVSharedBufferAccess; + const aAdditionalDataAsJson : wvstring): boolean; +begin + Result := assigned(FBaseIntf17) and + succeeded(FBaseIntf17.PostSharedBufferToScript(aSharedBuffer, aAccess, PWideChar(aAdditionalDataAsJson))); +end; + +function TCoreWebView2.ExecuteScriptWithResult(const JavaScript: wvstring; aExecutionID : integer; const aBrowserComponent : TComponent): boolean; +var + TempHandler : ICoreWebView2ExecuteScriptWithResultCompletedHandler; +begin + Result := False; + + if assigned(FBaseIntf21) then + try + TempHandler := TCoreWebView2ExecuteScriptWithResultCompletedHandler.Create(TWVBrowserBase(aBrowserComponent), aExecutionID); + Result := succeeded(FBaseIntf21.ExecuteScriptWithResult(PWideChar(JavaScript), TempHandler)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.AddWebResourceRequestedFilterWithRequestSourceKinds(const uri : wvstring; + ResourceContext : TWVWebResourceContext; + requestSourceKinds : TWVWebResourceRequestSourceKind): boolean; +begin + Result := assigned(FBaseIntf22) and + succeeded(FBaseIntf22.AddWebResourceRequestedFilterWithRequestSourceKinds(PWideChar(uri), ResourceContext, requestSourceKinds)); +end; + +function TCoreWebView2.RemoveWebResourceRequestedFilterWithRequestSourceKinds(const uri : wvstring; + ResourceContext : TWVWebResourceContext; + requestSourceKinds : TWVWebResourceRequestSourceKind): boolean; +begin + Result := assigned(FBaseIntf22) and + succeeded(FBaseIntf22.RemoveWebResourceRequestedFilterWithRequestSourceKinds(PWideChar(uri), ResourceContext, requestSourceKinds)); +end; + +function TCoreWebView2.PostWebMessageAsJsonWithAdditionalObjects(const webMessageAsJson : wvstring; + const additionalObjects : ICoreWebView2ObjectCollectionView): boolean; +begin + Result := assigned(FBaseIntf23) and + succeeded(FBaseIntf23.PostWebMessageAsJsonWithAdditionalObjects(PWideChar(webMessageAsJson), additionalObjects)); +end; + +function TCoreWebView2.ShowSaveAsUI(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2ShowSaveAsUICompletedHandler; +begin + Result := False; + + if assigned(FBaseIntf25) then + try + TempHandler := TCoreWebView2ShowSaveAsUICompletedHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf25.ShowSaveAsUI(TempHandler)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2.GetBrowserProcessID : cardinal; +var + TempID : DWORD; +begin + if Initialized and succeeded(FBaseIntf.Get_BrowserProcessId(TempID)) then + Result := TempID + else + Result := 0; +end; + +function TCoreWebView2.GetCanGoBack : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_CanGoBack(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2.GetCanGoForward : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_CanGoForward(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2.GetContainsFullScreenElement : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_ContainsFullScreenElement(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2.GetDocumentTitle : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.get_DocumentTitle(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2.GetSource : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.get_Source(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2.GetCookieManager : ICoreWebView2CookieManager; +var + TempResult : ICoreWebView2CookieManager; +begin + Result := nil; + TempResult := nil; + + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_CookieManager(TempResult)) and + assigned(TempResult) then + Result := TempResult; +end; + +function TCoreWebView2.GetEnvironment : ICoreWebView2Environment; +var + TempResult : ICoreWebView2Environment; +begin + Result := nil; + TempResult := nil; + + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_Environment(TempResult)) and + assigned(TempResult) then + Result := TempResult; +end; + +function TCoreWebView2.GetIsSuspended : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf3) and + succeeded(FBaseIntf3.Get_IsSuspended(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2.GetSettings : ICoreWebView2Settings; +var + TempResult : ICoreWebView2Settings; +begin + Result := nil; + TempResult := nil; + + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_Settings(TempResult)) and + assigned(TempResult) then + Result := TempResult; +end; + +function TCoreWebView2.GetIsMuted : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf8) and + succeeded(FBaseIntf8.Get_IsMuted(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2.GetIsDocumentPlayingAudio : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf8) and + succeeded(FBaseIntf8.Get_IsDocumentPlayingAudio(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2.GetIsDefaultDownloadDialogOpen : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf9) and + succeeded(FBaseIntf9.Get_IsDefaultDownloadDialogOpen(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2.GetDefaultDownloadDialogCornerAlignment : TWVDefaultDownloadDialogCornerAlignment; +var + TempResult : COREWEBVIEW2_DEFAULT_DOWNLOAD_DIALOG_CORNER_ALIGNMENT; +begin + if assigned(FBaseIntf9) and + succeeded(FBaseIntf9.Get_DefaultDownloadDialogCornerAlignment(TempResult)) then + Result := TempResult + else + Result := 0; +end; + +{$WARN SYMBOL_DEPRECATED OFF} +function TCoreWebView2.GetDefaultDownloadDialogMargin : TPoint; +var + TempResult : tagPOINT; // ICoreWebView2_9 uses tagPoint. We ignore the warning. +begin + if assigned(FBaseIntf9) and + succeeded(FBaseIntf9.Get_DefaultDownloadDialogMargin(TempResult)) then + Result := TPoint(TempResult) + else + Result := point(0, 0); +end; +{$WARN SYMBOL_DEPRECATED ON} + +function TCoreWebView2.GetStatusBarText : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if assigned(FBaseIntf12) and + succeeded(FBaseIntf12.Get_StatusBarText(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2.GetProfile : ICoreWebView2Profile; +var + TempResult : ICoreWebView2Profile; +begin + Result := nil; + TempResult := nil; + + if assigned(FBaseIntf13) and + succeeded(FBaseIntf13.Get_Profile(TempResult)) and + assigned(TempResult) then + Result := TempResult; +end; + +function TCoreWebView2.GetFaviconURI : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if assigned(FBaseIntf15) and + succeeded(FBaseIntf15.Get_FaviconUri(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2.GetMemoryUsageTargetLevel : TWVMemoryUsageTargetLevel; +var + TempResult : COREWEBVIEW2_MEMORY_USAGE_TARGET_LEVEL; +begin + if assigned(FBaseIntf19) and + succeeded(FBaseIntf19.Get_MemoryUsageTargetLevel(TempResult)) then + Result := TempResult + else + Result := COREWEBVIEW2_MEMORY_USAGE_TARGET_LEVEL_NORMAL; +end; + +function TCoreWebView2.GetFrameID : cardinal; +var + TempResult : SYSUINT; +begin + if assigned(FBaseIntf20) and + succeeded(FBaseIntf20.Get_FrameId(TempResult)) then + begin + Result := TempResult; + FFrameIDCopy := TempResult; + end + else + Result := FFrameIDCopy; +end; + +function TCoreWebView2.GetFind : ICoreWebView2Find; +var + TempResult : ICoreWebView2Find; +begin + Result := nil; + TempResult := nil; + + if assigned(FBaseIntf28) and + succeeded(FBaseIntf28.Get_Find(TempResult)) and + assigned(TempResult) then + Result := TempResult; +end; + +procedure TCoreWebView2.SetIsMuted(aValue : boolean); +begin + if assigned(FBaseIntf8) then + FBaseIntf8.Set_IsMuted(ord(aValue)); +end; + +procedure TCoreWebView2.SetDefaultDownloadDialogCornerAlignment(aValue : TWVDefaultDownloadDialogCornerAlignment); +begin + if assigned(FBaseIntf9) then + FBaseIntf9.Set_DefaultDownloadDialogCornerAlignment(aValue); +end; + +procedure TCoreWebView2.SetDefaultDownloadDialogMargin(aValue : TPoint); +begin + {$WARN SYMBOL_DEPRECATED OFF} + // ICoreWebView2_9 uses tagPoint. We ignore the warning. + if assigned(FBaseIntf9) then + FBaseIntf9.Set_DefaultDownloadDialogMargin(tagPOINT(aValue)); + {$WARN SYMBOL_DEPRECATED ON} +end; + +procedure TCoreWebView2.SetMemoryUsageTargetLevel(aValue : TWVMemoryUsageTargetLevel); +begin + if assigned(FBaseIntf19) then + FBaseIntf19.Set_MemoryUsageTargetLevel(aValue); +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Args.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Args.pas new file mode 100644 index 000000000..2303912cb --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Args.pas @@ -0,0 +1,5131 @@ +unit uRESTDWPrivWVCoreWebView2Args; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + System.Types, Winapi.ActiveX, + {$ELSE} + Types, ActiveX, + {$ENDIF} + uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVTypes; + +type + /// + /// Event args for the AcceleratorKeyPressed event. + /// + /// + /// See the ICoreWebView2AcceleratorKeyPressedEventArgs article. + /// + TCoreWebView2AcceleratorKeyPressedEventArgs = class + protected + FBaseIntf : ICoreWebView2AcceleratorKeyPressedEventArgs; + FBaseIntf2 : ICoreWebView2AcceleratorKeyPressedEventArgs2; + + function GetInitialized : boolean; + function GetKeyEventKind : TWVKeyEventKind; + function GetVirtualKey : LongWord; + function GetKeyEventLParam : integer; + function GetHandled : boolean; + function GetRepeatCount : LongWord; + function GetScanCode : LongWord; + function GetIsExtendedKey : boolean; + function GetIsMenuKeyDown : boolean; + function GetWasKeyDown : boolean; + function GetIsKeyReleased : boolean; + function GetIsBrowserAcceleratorKeyEnabled : boolean; + + procedure SetHandled(aValue : boolean); + procedure SetIsBrowserAcceleratorKeyEnabled(aValue : boolean); + + procedure InitializeFields; + + public + constructor Create(const aArgs: ICoreWebView2AcceleratorKeyPressedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2AcceleratorKeyPressedEventArgs read FBaseIntf; + /// + /// The key event type that caused the event to run. + /// + /// + /// See the ICoreWebView2AcceleratorKeyPressedEventArgs article. + /// + property KeyEventKind : TWVKeyEventKind read GetKeyEventKind; + /// + /// The Win32 virtual key code of the key that was pressed or released. It + /// is one of the Win32 virtual key constants such as `VK_RETURN` or an + /// (uppercase) ASCII value such as `A`. Verify whether Ctrl or Alt + /// are pressed by running `GetKeyState(VK_CONTROL)` or + /// `GetKeyState(VK_MENU)`. + /// + /// + /// See the ICoreWebView2AcceleratorKeyPressedEventArgs article. + /// + property VirtualKey : LongWord read GetVirtualKey; + /// + /// The `LPARAM` value that accompanied the window message. For more + /// information, navigate to [WM_KEYDOWN](/windows/win32/inputdev/wm-keydown) + /// and [WM_KEYUP](/windows/win32/inputdev/wm-keyup). + /// + /// + /// See the ICoreWebView2AcceleratorKeyPressedEventArgs article. + /// + property KeyEventLParam : integer read GetKeyEventLParam; + /// + /// Specifies the repeat count for the current message. + /// + /// + /// See the ICoreWebView2AcceleratorKeyPressedEventArgs article. + /// See the CoreWebView2PhysicalKeyStatus Struct article. + /// + property RepeatCount : LongWord read GetRepeatCount; + /// + /// Specifies the scan code. + /// + /// + /// See the ICoreWebView2AcceleratorKeyPressedEventArgs article. + /// See the CoreWebView2PhysicalKeyStatus Struct article. + /// + property ScanCode : LongWord read GetScanCode; + /// + /// Indicates that the key is an extended key. + /// + /// + /// See the ICoreWebView2AcceleratorKeyPressedEventArgs article. + /// See the CoreWebView2PhysicalKeyStatus Struct article. + /// + property IsExtendedKey : boolean read GetIsExtendedKey; + /// + /// Indicates that a menu key is held down (context code). + /// + /// + /// See the ICoreWebView2AcceleratorKeyPressedEventArgs article. + /// See the CoreWebView2PhysicalKeyStatus Struct article. + /// + property IsMenuKeyDown : boolean read GetIsMenuKeyDown; + /// + /// Indicates that the key was held down. + /// + /// + /// See the ICoreWebView2AcceleratorKeyPressedEventArgs article. + /// See the CoreWebView2PhysicalKeyStatus Struct article. + /// + property WasKeyDown : boolean read GetWasKeyDown; + /// + /// Indicates that the key was released. + /// + /// + /// See the ICoreWebView2AcceleratorKeyPressedEventArgs article. + /// See the CoreWebView2PhysicalKeyStatus Struct article. + /// + property IsKeyReleased : boolean read GetIsKeyReleased; + /// + /// During `AcceleratorKeyPressedEvent` handler invocation the WebView is + /// blocked waiting for the decision of if the accelerator is handled by the + /// host (or not). If the `Handled` property is set to `TRUE` then this + /// prevents the WebView from performing the default action for this + /// accelerator key. Otherwise the WebView performs the default action for + /// the accelerator key. + /// + /// + /// See the ICoreWebView2AcceleratorKeyPressedEventArgs article. + /// + property Handled : boolean read GetHandled write SetHandled; + /// + /// This property allows developers to enable or disable the browser from handling a specific + /// browser accelerator key such as Ctrl+P or F3, etc. + /// Browser accelerator keys are the keys/key combinations that access features specific to + /// a web browser, including but not limited to: + /// + /// - Ctrl-F and F3 for Find on Page + /// - Ctrl-P for Print + /// - Ctrl-R and F5 for Reload + /// - Ctrl-Plus and Ctrl-Minus for zooming + /// - Ctrl-Shift-C and F12 for DevTools + /// - Special keys for browser functions, such as Back, Forward, and Search + /// + /// This property does not disable accelerator keys related to movement and text editing, + /// such as: + /// + /// - Home, End, Page Up, and Page Down + /// - Ctrl-X, Ctrl-C, Ctrl-V + /// - Ctrl-A for Select All + /// - Ctrl-Z for Undo + /// + /// The `ICoreWebView2Settings.AreBrowserAcceleratorKeysEnabled` API is a convenient setting + /// for developers to disable all the browser accelerator keys together, and sets the default + /// value for the `IsBrowserAcceleratorKeyEnabled` property. + /// By default, `ICoreWebView2Settings.AreBrowserAcceleratorKeysEnabled` is `TRUE` and + /// `IsBrowserAcceleratorKeyEnabled` is `TRUE`. + /// When developers change `ICoreWebView2Settings.AreBrowserAcceleratorKeysEnabled` setting to `FALSE`, + /// this will change default value for `IsBrowserAcceleratorKeyEnabled` to `FALSE`. + /// If developers want specific keys to be handled by the browser after changing the + /// `ICoreWebView2Settings.AreBrowserAcceleratorKeysEnabled` setting to `FALSE`, they need to enable + /// these keys by setting `IsBrowserAcceleratorKeyEnabled` to `TRUE`. + /// This API will give the event arg higher priority over the + /// `ICoreWebView2Settings.AreBrowserAcceleratorKeysEnabled` setting when we handle the keys. + /// For browser accelerator keys, when an accelerator key is pressed, the propagation and + /// processing order is: + /// + /// 1. A ICoreWebView2Controller.AcceleratorKeyPressed event is raised + /// 2. WebView2 browser feature accelerator key handling + /// 3. Web Content Handling: If the key combination isn't reserved for browser actions, + /// the key event propagates to the web content, where JavaScript event listeners can + /// capture and respond to it. + /// + /// `ICoreWebView2AcceleratorKeyPressedEventArgs` has a `Handled` property, that developers + /// can use to mark a key as handled. When the key is marked as handled anywhere along + /// the path, the event propagation stops, and web content will not receive the key. + /// With `IsBrowserAcceleratorKeyEnabled` property, if developers mark + /// `IsBrowserAcceleratorKeyEnabled` as `FALSE`, the browser will skip the WebView2 + /// browser feature accelerator key handling process, but the event propagation + /// continues, and web content will receive the key combination. + /// + /// + /// See the ICoreWebView2AcceleratorKeyPressedEventArgs2 article. + /// + property IsBrowserAcceleratorKeyEnabled : boolean read GetIsBrowserAcceleratorKeyEnabled write SetIsBrowserAcceleratorKeyEnabled; + end; + + /// + /// Receives ContentLoading events. + /// + /// + /// See the ICoreWebView2ContentLoadingEventArgs article. + /// + TCoreWebView2ContentLoadingEventArgs = class + protected + FBaseIntf : ICoreWebView2ContentLoadingEventArgs; + + function GetInitialized : boolean; + function GetIsErrorPage : boolean; + function GetNavigationId : uint64; + + public + constructor Create(const aArgs: ICoreWebView2ContentLoadingEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2ContentLoadingEventArgs read FBaseIntf; + /// + /// `TRUE` if the loaded content is an error page. + /// + /// + /// See the ICoreWebView2ContentLoadingEventArgs article. + /// + property IsErrorPage : boolean read GetIsErrorPage; + /// + /// The ID of the navigation. + /// + /// + /// See the ICoreWebView2ContentLoadingEventArgs article. + /// + property NavigationId : uint64 read GetNavigationId; + end; + + /// + /// Event args for the DevToolsProtocolEventReceived event. + /// + /// + /// See the ICoreWebView2DevToolsProtocolEventReceivedEventArgs article. + /// + TCoreWebView2DevToolsProtocolEventReceivedEventArgs = class + protected + FBaseIntf : ICoreWebView2DevToolsProtocolEventReceivedEventArgs; + FBaseIntf2 : ICoreWebView2DevToolsProtocolEventReceivedEventArgs2; + + function GetInitialized : boolean; + function GetParameterObjectAsJson : wvstring; + function GetSessionId : wvstring; + + procedure InitializeFields; + + public + constructor Create(const aArgs: ICoreWebView2DevToolsProtocolEventReceivedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2DevToolsProtocolEventReceivedEventArgs read FBaseIntf; + /// + /// The parameter object of the corresponding `DevToolsProtocol` event + /// represented as a JSON string. + /// + /// + /// See the ICoreWebView2DevToolsProtocolEventReceivedEventArgs article. + /// + property ParameterObjectAsJson : wvstring read GetParameterObjectAsJson; + /// + /// The sessionId of the target where the event originates from. + /// Empty string is returned as sessionId if the event comes from the default + /// session for the top page. + /// + /// + /// See the ICoreWebView2DevToolsProtocolEventReceivedEventArgs2 article. + /// + property SessionId : wvstring read GetSessionId; + end; + + /// + /// Event args for the MoveFocusRequested event. + /// + /// + /// See the ICoreWebView2MoveFocusRequestedEventArgs article. + /// + TCoreWebView2MoveFocusRequestedEventArgs = class + protected + FBaseIntf : ICoreWebView2MoveFocusRequestedEventArgs; + + function GetInitialized : boolean; + function GetReason : TWVMoveFocusReason; + function GetHandled : boolean; + + procedure SetHandled(aValue : boolean); + + public + constructor Create(const aArgs: ICoreWebView2MoveFocusRequestedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2MoveFocusRequestedEventArgs read FBaseIntf; + /// + /// The reason for WebView to run the `MoveFocusRequested` event. + /// + /// + /// See the ICoreWebView2MoveFocusRequestedEventArgs article. + /// + property Reason : TWVMoveFocusReason read GetReason; + /// + /// Indicates whether the event has been handled by the app. If the app has + /// moved the focus to another desired location, it should set the `Handled` + /// property to `TRUE`. When the `Handled` property is `FALSE` after the + /// event handler returns, default action is taken. The default action is to + /// try to find the next tab stop child window in the app and try to move + /// focus to that window. If no other window exists to move focus, focus is + /// cycled within the web content of the WebView. + /// + /// + /// See the ICoreWebView2MoveFocusRequestedEventArgs article. + /// + property Handled : boolean read GetHandled write SetHandled; + end; + + /// + /// Event args for the NavigationCompleted event. + /// + /// + /// See the ICoreWebView2NavigationCompletedEventArgs article. + /// + TCoreWebView2NavigationCompletedEventArgs = class + protected + FBaseIntf : ICoreWebView2NavigationCompletedEventArgs; + FBaseIntf2 : ICoreWebView2NavigationCompletedEventArgs2; + + function GetInitialized : boolean; + function GetIsSuccess : boolean; + function GetWebErrorStatus : TWVWebErrorStatus; + function GetNavigationID : uint64; + function GetHttpStatusCode : integer; + + procedure InitializeFields; + + public + constructor Create(const aArgs: ICoreWebView2NavigationCompletedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2NavigationCompletedEventArgs read FBaseIntf; + /// + /// `TRUE` when the navigation is successful. `FALSE` for a navigation that + /// ended up in an error page (failures due to no network, DNS lookup + /// failure, HTTP server responds with 4xx), but may also be `FALSE` for + /// additional scenarios such as `window.stop()` run on navigated page. + /// Note that WebView2 will report the navigation as 'unsuccessful' if the load + /// for the navigation did not reach the expected completion for any reason. Such + /// reasons include potentially catastrophic issues such network and certificate + /// issues, but can also be the result of intended actions such as the app canceling a navigation or + /// navigating away before the original navigation completed. Applications should not + /// just rely on this flag, but also consider the reported WebErrorStatus to + /// determine whether the failure is indeed catastrophic in their context. + /// WebErrorStatuses that may indicate a non-catastrophic failure include: + /// - COREWEBVIEW2_WEB_ERROR_STATUS_OPERATION_CANCELED + /// - COREWEBVIEW2_WEB_ERROR_STATUS_VALID_AUTHENTICATION_CREDENTIALS_REQUIRED + /// - COREWEBVIEW2_WEB_ERROR_STATUS_VALID_PROXY_AUTHENTICATION_REQUIRED + /// + /// + /// See the ICoreWebView2NavigationCompletedEventArgs article. + /// + property IsSuccess : boolean read GetIsSuccess; + /// + /// The error code if the navigation failed. + /// + /// + /// See the ICoreWebView2NavigationCompletedEventArgs article. + /// + property WebErrorStatus : TWVWebErrorStatus read GetWebErrorStatus; + /// + /// The ID of the navigation. + /// + /// + /// See the ICoreWebView2NavigationCompletedEventArgs article. + /// + property NavigationID : uint64 read GetNavigationID; + /// + /// The HTTP status code of the navigation if it involved an HTTP request. + /// For instance, this will usually be 200 if the request was successful, 404 + /// if a page was not found, etc. See + /// https://developer.mozilla.org/docs/Web/HTTP/Status for a list of + /// common status codes. + /// The `HttpStatusCode` property will be 0 in the following cases: + /// * The navigation did not involve an HTTP request. For instance, if it was + /// a navigation to a file:// URL, or if it was a same-document navigation. + /// * The navigation failed before a response was received. For instance, if + /// the hostname was not found, or if there was a network error. + /// In those cases, you can get more information from the `IsSuccess` and + /// `WebErrorStatus` properties. + /// If the navigation receives a successful HTTP response, but the navigated + /// page calls `window.stop()` before it finishes loading, then + /// `HttpStatusCode` may contain a success code like 200, but `IsSuccess` will + /// be FALSE and `WebErrorStatus` will be + /// `COREWEBVIEW2_WEB_ERROR_STATUS_CONNECTION_ABORTED`. + /// Since WebView2 handles HTTP continuations and redirects automatically, it + /// is unlikely for `HttpStatusCode` to ever be in the 1xx or 3xx ranges. + /// + /// + /// See the ICoreWebView2NavigationCompletedEventArgs2 article. + /// + property HttpStatusCode : integer read GetHttpStatusCode; + end; + + /// + /// Event args for the NavigationStarting event. + /// + /// + /// See the ICoreWebView2NavigationStartingEventArgs article. + /// + TCoreWebView2NavigationStartingEventArgs = class + protected + FBaseIntf : ICoreWebView2NavigationStartingEventArgs; + FBaseIntf2 : ICoreWebView2NavigationStartingEventArgs2; + FBaseIntf3 : ICoreWebView2NavigationStartingEventArgs3; + + function GetInitialized : boolean; + function GetURI : wvstring; + function GetIsUserInitiated : boolean; + function GetIsRedirected : boolean; + function GetCancel : boolean; + function GetNavigationID : uint64; + function GetRequestHeaders : ICoreWebView2HttpRequestHeaders; + function GetAdditionalAllowedFrameAncestors : wvstring; + function GetNavigationKind : TWVNavigationKind; + + procedure SetAdditionalAllowedFrameAncestors(const aValue : wvstring); + procedure SetCancel(aValue : boolean); + + procedure InitializeFields; + + public + constructor Create(const aArgs: ICoreWebView2NavigationStartingEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2NavigationStartingEventArgs read FBaseIntf; + /// + /// The uri of the requested navigation. + /// + /// + /// See the ICoreWebView2NavigationStartingEventArgs article. + /// + property URI : wvstring read GetURI; + /// + /// `TRUE` when the navigation was initiated through a user gesture as + /// opposed to programmatic navigation by page script. Navigations initiated + /// via WebView2 APIs are considered as user initiated. + /// + /// + /// See the ICoreWebView2NavigationStartingEventArgs article. + /// + property IsUserInitiated : boolean read GetIsUserInitiated; + /// + /// `TRUE` when the navigation is redirected. + /// + /// + /// See the ICoreWebView2NavigationStartingEventArgs article. + /// + property IsRedirected : boolean read GetIsRedirected; + /// + /// The host may set this flag to cancel the navigation. If set, the + /// navigation is not longer present and the content of the current page is + /// intact. For performance reasons, `GET` HTTP requests may happen, while + /// the host is responding. You may set cookies and use part of a request + /// for the navigation. Navigations to about schemes are cancellable, unless + /// `msWebView2CancellableAboutNavigations` feature flag is disabled. + /// Cancellation of frame navigation to `srcdoc` is not supported and + /// wil be ignored. A cancelled navigation will fire a `NavigationCompleted` + /// event with a `WebErrorStatus` of + /// `COREWEBVIEW2_WEB_ERROR_STATUS_OPERATION_CANCELED`. + /// + /// + /// See the ICoreWebView2NavigationStartingEventArgs article. + /// + property Cancel : boolean read GetCancel write SetCancel; + /// + /// The ID of the navigation. + /// + /// + /// See the ICoreWebView2NavigationStartingEventArgs article. + /// + property NavigationID : uint64 read GetNavigationID; + /// + /// The HTTP request headers for the navigation. + /// \>NOTE: You are not able to modify the HTTP request headers in a + /// `NavigationStarting` event. + /// + /// + /// See the ICoreWebView2NavigationStartingEventArgs article. + /// + property RequestHeaders : ICoreWebView2HttpRequestHeaders read GetRequestHeaders; + /// + /// Get additional allowed frame ancestors set by the host app. + /// + /// + /// See the ICoreWebView2NavigationStartingEventArgs3 article. + /// + property AdditionalAllowedFrameAncestors : wvstring read GetAdditionalAllowedFrameAncestors write SetAdditionalAllowedFrameAncestors; + /// + /// Get the navigation kind of this navigation. + /// + /// + /// See the ICoreWebView2NavigationStartingEventArgs3 article. + /// + property NavigationKind : TWVNavigationKind read GetNavigationKind; + end; + + /// + /// Event args for the NewWindowRequested event. The event is run when + /// content inside webview requested to a open a new window (through + /// window.open() and so on). + /// + /// + /// See the ICoreWebView2NewWindowRequestedEventArgs article. + /// + TCoreWebView2NewWindowRequestedEventArgs = class + protected + FBaseIntf : ICoreWebView2NewWindowRequestedEventArgs; + FBaseIntf2 : ICoreWebView2NewWindowRequestedEventArgs2; + FBaseIntf3 : ICoreWebView2NewWindowRequestedEventArgs3; + + function GetInitialized : boolean; + function GetURI : wvstring; + function GetNewWindow : ICoreWebView2; + function GetHandled : boolean; + function GetIsUserInitiated : boolean; + function GetDeferral : ICoreWebView2Deferral; + function GetWindowFeatures : ICoreWebView2WindowFeatures; + function GetName : wvstring; + function GetOriginalSourceFrameInfo : ICoreWebView2FrameInfo; + + procedure SetNewWindow(const aValue : ICoreWebView2); + procedure SetHandled(aValue : boolean); + + procedure InitializeFields; + + public + constructor Create(const aArgs: ICoreWebView2NewWindowRequestedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2NewWindowRequestedEventArgs read FBaseIntf; + /// + /// The target uri of the new window requested. + /// + /// + /// See the ICoreWebView2NewWindowRequestedEventArgs article. + /// + property URI : wvstring read GetURI; + /// + /// Gets the new window. + /// + /// + /// See the ICoreWebView2NewWindowRequestedEventArgs article. + /// + property NewWindow : ICoreWebView2 read GetNewWindow write SetNewWindow; + /// + /// Gets whether the `NewWindowRequested` event is handled by host. + /// + /// + /// See the ICoreWebView2NewWindowRequestedEventArgs article. + /// + property Handled : boolean read GetHandled write SetHandled; + /// + /// `TRUE` when the new window request was initiated through a user gesture. + /// Examples of user initiated requests are: + /// - Selecting an anchor tag with target + /// - Programmatic window open from a script that directly run as a result of + /// user interaction such as via onclick handlers. + /// Non-user initiated requests are programmatic window opens from a script + /// that are not directly triggered by user interaction, such as those that + /// run while loading a new page or via timers. + /// The Microsoft Edge popup blocker is disabled for WebView so the app is + /// able to use this flag to block non-user initiated popups. + /// + /// + /// See the ICoreWebView2NewWindowRequestedEventArgs article. + /// + property IsUserInitiated : boolean read GetIsUserInitiated; + /// + /// Obtain an `ICoreWebView2Deferral` object and put the event into a + /// deferred state. Use the `ICoreWebView2Deferral` object to complete the + /// window open request at a later time. While this event is deferred the + /// opener window returns a `WindowProxy` to an un-navigated window, which + /// navigates when the deferral is complete. + /// + /// + /// See the ICoreWebView2NewWindowRequestedEventArgs article. + /// + property Deferral : ICoreWebView2Deferral read GetDeferral; + /// + /// Window features specified by the `window.open`. The features should be + /// considered for positioning and sizing of new webview windows. + /// + /// + /// See the ICoreWebView2NewWindowRequestedEventArgs article. + /// + property WindowFeatures : ICoreWebView2WindowFeatures read GetWindowFeatures; + ///
+ /// + /// See the ICoreWebView2NewWindowRequestedEventArgs2 article. + /// + property Name : wvstring read GetName; + /// + /// The frame info of the frame where the new window request originated. The + /// `OriginalSourceFrameInfo` is a snapshot of frame information at the time when the + /// new window was requested. See `ICoreWebView2FrameInfo` for details on frame + /// properties. + /// + /// + /// See the ICoreWebView2NewWindowRequestedEventArgs3 article. + /// + property OriginalSourceFrameInfo : ICoreWebView2FrameInfo read GetOriginalSourceFrameInfo; + end; + + /// + /// Event args for the PermissionRequested event. + /// + /// + /// See the ICoreWebView2PermissionRequestedEventArgs article. + /// + TCoreWebView2PermissionRequestedEventArgs = class + protected + FBaseIntf : ICoreWebView2PermissionRequestedEventArgs; + FBaseIntf2 : ICoreWebView2PermissionRequestedEventArgs2; + FBaseIntf3 : ICoreWebView2PermissionRequestedEventArgs3; + + function GetInitialized : boolean; + function GetURI : wvstring; + function GetPermissionKind : TWVPermissionKind; + function GetIsUserInitiated : boolean; + function GetState : TWVPermissionState; + function GetDeferral : ICoreWebView2Deferral; + function GetHandled : boolean; + function GetSavesInProfile : boolean; + + procedure SetState(aValue : TWVPermissionState); + procedure SetHandled(aValue : boolean); + procedure SetSavesInProfile(aValue : boolean); + + procedure InitializeFields; + + public + constructor Create(const aArgs: ICoreWebView2PermissionRequestedEventArgs); reintroduce; overload; + constructor Create(const aArgs: ICoreWebView2PermissionRequestedEventArgs2); reintroduce; overload; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2PermissionRequestedEventArgs read FBaseIntf; + /// + /// The origin of the web content that requests the permission. + /// + /// + /// See the ICoreWebView2PermissionRequestedEventArgs article. + /// + property URI : wvstring read GetURI; + /// + /// The status of a permission request, (for example is the request is granted). + /// The default value is `COREWEBVIEW2_PERMISSION_STATE_DEFAULT`. + /// + /// + /// See the ICoreWebView2PermissionRequestedEventArgs article. + /// + property State : TWVPermissionState read GetState write SetState; + /// + /// The type of the permission that is requested. + /// + /// + /// See the ICoreWebView2PermissionRequestedEventArgs article. + /// + property PermissionKind : TWVPermissionKind read GetPermissionKind; + /// + /// `TRUE` when the permission request was initiated through a user gesture. + /// NOTE: Being initiated through a user gesture does not mean that user intended + /// to access the associated resource. + /// + /// + /// See the ICoreWebView2PermissionRequestedEventArgs article. + /// + property IsUserInitiated : boolean read GetIsUserInitiated; + /// + /// Gets an `ICoreWebView2Deferral` object. Use the deferral object to make + /// the permission decision at a later time. The deferral only applies to the + /// current request, and does not prevent the `OnPermissionRequested` event from + /// getting raised for new requests. However, for some permission kinds the + /// WebView will avoid creating a new request if there is a pending request of + /// the same kind. + /// + /// + /// See the ICoreWebView2PermissionRequestedEventArgs article. + /// + property Deferral : ICoreWebView2Deferral read GetDeferral; + /// + /// By default, both the `OnPermissionRequested` event handlers on the + /// `CoreWebView2Frame` and the `CoreWebView2` will be invoked, with the + /// `CoreWebView2Frame` event handlers invoked first. The host may + /// set this flag to `TRUE` within the `CoreWebView2Frame` event handlers + /// to prevent the remaining `CoreWebView2` event handlers from being invoked. + /// If a deferral is taken on the event args, then you must synchronously + /// set `Handled` to TRUE prior to taking your deferral to prevent the + /// `CoreWebView2`s event handlers from being invoked. + /// + /// + /// See the ICoreWebView2PermissionRequestedEventArgs2 article. + /// + property Handled : boolean read GetHandled write SetHandled; + /// + /// The permission state set from the `PermissionRequested` event is saved in + /// the profile by default; it persists across sessions and becomes the new + /// default behavior for future `PermissionRequested` events. Browser + /// heuristics can affect whether the event continues to be raised when the + /// state is saved in the profile. Set the `SavesInProfile` property to + /// `FALSE` to not persist the state beyond the current request, and to + /// continue to receive `PermissionRequested` + /// events for this origin and permission kind. + /// + /// + /// See the ICoreWebView2PermissionRequestedEventArgs3 article. + /// + property SavesInProfile : boolean read GetSavesInProfile write SetSavesInProfile; + end; + + /// + /// Event args for the ProcessFailed event. + /// + /// + /// See the ICoreWebView2ProcessFailedEventArgs article. + /// + TCoreWebView2ProcessFailedEventArgs = class + protected + FBaseIntf : ICoreWebView2ProcessFailedEventArgs; + FBaseIntf2 : ICoreWebView2ProcessFailedEventArgs2; + FBaseIntf3 : ICoreWebView2ProcessFailedEventArgs3; + + function GetInitialized : boolean; + function GetProcessFailedKind : TWVProcessFailedKind; + function GetReason : TWVProcessFailedReason; + function GetExtiCode : integer; + function GetProcessDescription : wvstring; + function GetFrameInfosForFailedProcess : ICoreWebView2FrameInfoCollection; + function GetFailureSourceModulePath : wvstring; + + procedure InitializeFields; + + public + constructor Create(const aArgs: ICoreWebView2ProcessFailedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2ProcessFailedEventArgs read FBaseIntf; + /// + /// The kind of process failure that has occurred. This is a combination of + /// process kind (for example, browser, renderer, gpu) and failure (exit, + /// unresponsiveness). Renderer processes are further divided in _main frame_ + /// renderer (`RenderProcessExited`, `RenderProcessUnresponsive`) and + /// _subframe_ renderer (`FrameRenderProcessExited`). To learn about the + /// conditions under which each failure kind occurs, see + /// `COREWEBVIEW2_PROCESS_FAILED_KIND`. + /// + /// + /// See the ICoreWebView2ProcessFailedEventArgs article. + /// + property ProcessFailedKind : TWVProcessFailedKind read GetProcessFailedKind; + /// + /// The reason for the process failure. Some of the reasons are only + /// applicable to specific values of + /// `ICoreWebView2ProcessFailedEventArgs.ProcessFailedKind`, and the + /// following `ProcessFailedKind` values always return the indicated reason + /// value: + /// + /// ProcessFailedKind | Reason + /// ---|--- + /// COREWEBVIEW2_PROCESS_FAILED_KIND_BROWSER_PROCESS_EXITED | COREWEBVIEW2_PROCESS_FAILED_REASON_UNEXPECTED + /// COREWEBVIEW2_PROCESS_FAILED_KIND_RENDER_PROCESS_UNRESPONSIVE | COREWEBVIEW2_PROCESS_FAILED_REASON_UNRESPONSIVE + /// + /// For other `ProcessFailedKind` values, the reason may be any of the reason + /// values. To learn about what these values mean, see + /// `COREWEBVIEW2_PROCESS_FAILED_REASON`. + /// + /// + /// See the ICoreWebView2ProcessFailedEventArgs2 article. + /// + property Reason : TWVProcessFailedReason read GetReason; + /// + /// The exit code of the failing process, for telemetry purposes. The exit + /// code is always `STILL_ACTIVE` (`259`) when `ProcessFailedKind` is + /// `COREWEBVIEW2_PROCESS_FAILED_KIND_RENDER_PROCESS_UNRESPONSIVE`. + /// + /// + /// See the ICoreWebView2ProcessFailedEventArgs2 article. + /// + property ExtiCode : integer read GetExtiCode; + /// + /// Description of the process assigned by the WebView2 Runtime. This is a + /// technical English term appropriate for logging or development purposes, + /// and not localized for the end user. It applies to utility processes (for + /// example, "Audio Service", "Video Capture") and plugin processes (for + /// example, "Flash"). The returned `processDescription` is empty if the + /// WebView2 Runtime did not assign a description to the process. + /// + /// + /// See the ICoreWebView2ProcessFailedEventArgs2 article. + /// + property ProcessDescription : wvstring read GetProcessDescription; + /// + /// The collection of `FrameInfo`s for frames in the `ICoreWebView2` that were + /// being rendered by the failed process. The content in these frames is + /// replaced with an error page. + /// This is only available when `ProcessFailedKind` is + /// `COREWEBVIEW2_PROCESS_FAILED_KIND_FRAME_RENDER_PROCESS_EXITED`; + /// `frames` is `null` for all other process failure kinds, including the case + /// in which the failed process was the renderer for the main frame and + /// subframes within it, for which the failure kind is + /// `COREWEBVIEW2_PROCESS_FAILED_KIND_RENDER_PROCESS_EXITED`. + /// + /// + /// See the ICoreWebView2ProcessFailedEventArgs2 article. + /// + property FrameInfosForFailedProcess : ICoreWebView2FrameInfoCollection read GetFrameInfosForFailedProcess; + /// + /// This property is the full path of the module that caused the + /// crash in cases of Windows Code Integrity failures. + /// [Windows Code Integrity](/mem/intune/user-help/you-need-to-enable-code-integrity) + /// is a feature that verifies the integrity and + /// authenticity of dynamic-link libraries (DLLs) + /// on Windows systems. It ensures that only trusted + /// code can run on the system and prevents unauthorized or + /// malicious modifications. + /// When ProcessFailed occurred due to a failed Code Integrity check, + /// this property returns the full path of the file that was prevented from + /// loading on the system. + /// The webview2 process which tried to load the DLL will fail with + /// exit code STATUS_INVALID_IMAGE_HASH(-1073740760). + /// A file can fail integrity check for various + /// reasons, such as: + /// + /// - It has an invalid or missing signature that does + /// not match the publisher or signer of the file. + /// - It has been tampered with or corrupted by malware or other software. + /// - It has been blocked by an administrator or a security policy. + /// + /// This property always will be the empty string if failure is not caused by + /// STATUS_INVALID_IMAGE_HASH. + /// + property FailureSourceModulePath : wvstring read GetFailureSourceModulePath; + end; + + /// + /// Event args for the ScriptDialogOpening event. + /// + /// + /// See the ICoreWebView2ScriptDialogOpeningEventArgs article. + /// + TCoreWebView2ScriptDialogOpeningEventArgs = class + protected + FBaseIntf : ICoreWebView2ScriptDialogOpeningEventArgs; + + function GetInitialized : boolean; + function GetURI : wvstring; + function GetKind : TWVScriptDialogKind; + function GetMessage : wvstring; + function GetDefaultText : wvstring; + function GetResultText : wvstring; + function GetDeferral : ICoreWebView2Deferral; + + procedure SetResultText(const aValue : wvstring); + + public + constructor Create(const aArgs: ICoreWebView2ScriptDialogOpeningEventArgs); reintroduce; + destructor Destroy; override; + /// + /// The host may run this to respond with **OK** to `confirm`, `prompt`, and + /// `beforeunload` dialogs. Do not run this method to indicate cancel. + /// From JavaScript, this means that the `confirm` and `beforeunload` function + /// returns `TRUE` if `Accept` is run. And for the prompt function it returns + /// the value of `ResultText` if `Accept` is run and otherwise returns + /// `FALSE`. + /// + /// + /// See the ICoreWebView2ScriptDialogOpeningEventArgs article. + /// + function Accept : boolean; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2ScriptDialogOpeningEventArgs read FBaseIntf; + /// + /// The URI of the page that requested the dialog box. + /// + /// + /// See the ICoreWebView2ScriptDialogOpeningEventArgs article. + /// + property URI : wvstring read GetURI; + /// + /// The kind of JavaScript dialog box. `alert`, `confirm`, `prompt`, or + /// `beforeunload`. + /// + /// + /// See the ICoreWebView2ScriptDialogOpeningEventArgs article. + /// + property Kind : TWVScriptDialogKind read GetKind; + /// + /// The message of the dialog box. From JavaScript this is the first + /// parameter passed to `alert`, `confirm`, and `prompt` and is empty for + /// `beforeunload`. + /// + /// + /// See the ICoreWebView2ScriptDialogOpeningEventArgs article. + /// + property Message_ : wvstring read GetMessage; + /// + /// The second parameter passed to the JavaScript prompt dialog. + /// The result of the prompt JavaScript function uses this value as the + /// default value. + /// + /// + /// See the ICoreWebView2ScriptDialogOpeningEventArgs article. + /// + property DefaultText : wvstring read GetDefaultText; + /// + /// The return value from the JavaScript prompt function if `Accept` is run. + /// This value is ignored for dialog kinds other than prompt. If `Accept` + /// is not run, this value is ignored and `FALSE` is returned from prompt. + /// + /// + /// See the ICoreWebView2ScriptDialogOpeningEventArgs article. + /// + property ResultText : wvstring read GetResultText write SetResultText; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this operation to + /// complete the event at a later time. + /// + /// + /// See the ICoreWebView2ScriptDialogOpeningEventArgs article. + /// + property Deferral : ICoreWebView2Deferral read GetDeferral; + end; + + /// + /// Event args for the SourceChanged event. + /// + /// + /// See the ICoreWebView2SourceChangedEventArgs article. + /// + TCoreWebView2SourceChangedEventArgs = class + protected + FBaseIntf : ICoreWebView2SourceChangedEventArgs; + + function GetInitialized : boolean; + function GetIsNewDocument : boolean; + + public + constructor Create(const aArgs: ICoreWebView2SourceChangedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2SourceChangedEventArgs read FBaseIntf; + /// + /// `TRUE` if the page being navigated to is a new document. + /// + /// + /// See the ICoreWebView2SourceChangedEventArgs article. + /// + property IsNewDocument : boolean read GetIsNewDocument; + end; + + /// + /// Event args for the WebMessageReceived event. + /// + /// + /// See the ICoreWebView2WebMessageReceivedEventArgs article. + /// + TCoreWebView2WebMessageReceivedEventArgs = class + protected + FBaseIntf : ICoreWebView2WebMessageReceivedEventArgs; + FBaseIntf2 : ICoreWebView2WebMessageReceivedEventArgs2; + + function GetInitialized : boolean; + function GetSource : wvstring; + function GetWebMessageAsJson : wvstring; + function GetWebMessageAsString : wvstring; + function GetAdditionalObjects : ICoreWebView2ObjectCollectionView; + + procedure InitializeFields; + + public + constructor Create(const aArgs: ICoreWebView2WebMessageReceivedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2WebMessageReceivedEventArgs read FBaseIntf; + /// + /// The URI of the document that sent this web message. + /// + /// + /// See the ICoreWebView2WebMessageReceivedEventArgs article. + /// + property Source : wvstring read GetSource; + /// + /// The message posted from the WebView content to the host converted to a + /// JSON string. Run this operation to communicate using JavaScript objects. + /// + /// + /// See the ICoreWebView2WebMessageReceivedEventArgs article. + /// + property WebMessageAsJson : wvstring read GetWebMessageAsJson; + /// + /// If the message posted from the WebView content to the host is a string + /// type, this method returns the value of that string. If the message + /// posted is some other kind of JavaScript type this method fails with the + /// following error. + /// + /// + /// See the ICoreWebView2WebMessageReceivedEventArgs article. + /// + property WebMessageAsString : wvstring read GetWebMessageAsString; + /// + /// Additional received WebMessage objects. To pass `additionalObjects` via + /// WebMessage to the app, use the + /// `chrome.webview.postMessageWithAdditionalObjects` content API. + /// Any DOM object type that can be natively representable that has been + /// passed in to `additionalObjects` parameter will be accessible here. + /// Currently a WebMessage object can be the `ICoreWebView2File` type. + /// Entries in the collection can be `nullptr` if `null` or `undefined` was + /// passed. + /// + /// + /// See the ICoreWebView2WebMessageReceivedEventArgs2 article. + /// + property AdditionalObjects : ICoreWebView2ObjectCollectionView read GetAdditionalObjects; + end; + + /// + /// Event args for the WebResourceRequested event. + /// + /// + /// See the ICoreWebView2WebResourceRequestedEventArgs article. + /// + TCoreWebView2WebResourceRequestedEventArgs = class + protected + FBaseIntf : ICoreWebView2WebResourceRequestedEventArgs; + FBaseIntf2 : ICoreWebView2WebResourceRequestedEventArgs2; + + function GetInitialized : boolean; + function GetRequest : ICoreWebView2WebResourceRequest; + function GetResponse : ICoreWebView2WebResourceResponse; + function GetDeferral : ICoreWebView2Deferral; + function GetResourceContext : TWVWebResourceContext; + function GetRequestedSourceKind : TWVWebResourceRequestSourceKind; + + procedure SetResponse(const aValue : ICoreWebView2WebResourceResponse); + + procedure InitializeFields; + + public + constructor Create(const aArgs: ICoreWebView2WebResourceRequestedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2WebResourceRequestedEventArgs read FBaseIntf; + /// + /// The Web resource request. The request object may be missing some headers + /// that are added by network stack at a later time. + /// + /// + /// See the ICoreWebView2WebResourceRequestedEventArgs article. + /// + property Request : ICoreWebView2WebResourceRequest read GetRequest; + /// + /// A placeholder for the web resource response object. If this object is + /// set, the web resource request is completed with the specified response. + /// + /// + /// See the ICoreWebView2WebResourceRequestedEventArgs article. + /// + property Response : ICoreWebView2WebResourceResponse read GetResponse write SetResponse; + /// + /// Obtain an `ICoreWebView2Deferral` object and put the event into a + /// deferred state. Use the `ICoreWebView2Deferral` object to complete the + /// request at a later time. + /// + /// + /// See the ICoreWebView2WebResourceRequestedEventArgs article. + /// + property Deferral : ICoreWebView2Deferral read GetDeferral; + /// + /// The web resource request context. + /// + /// + /// See the ICoreWebView2WebResourceRequestedEventArgs article. + /// + property ResourceContext : TWVWebResourceContext read GetResourceContext; + /// + /// The web resource requested source. + /// + /// + /// See the ICoreWebView2WebResourceRequestedEventArgs2 article. + /// + property RequestedSourceKind : TWVWebResourceRequestSourceKind read GetRequestedSourceKind; + end; + + /// + /// Event args for the BrowserProcessExited event. + /// + /// + /// See the ICoreWebView2BrowserProcessExitedEventArgs article. + /// + TCoreWebView2BrowserProcessExitedEventArgs = class + protected + FBaseIntf : ICoreWebView2BrowserProcessExitedEventArgs; + + function GetInitialized : boolean; + function GetBrowserProcessExitKind : TWVBrowserProcessExitKind; + function GetBrowserProcessId : cardinal; + + public + constructor Create(const aArgs: ICoreWebView2BrowserProcessExitedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2BrowserProcessExitedEventArgs read FBaseIntf; + /// + /// The kind of browser process exit that has occurred. + /// + /// + /// See the ICoreWebView2BrowserProcessExitedEventArgs article. + /// + property BrowserProcessExitKind : TWVBrowserProcessExitKind read GetBrowserProcessExitKind; + /// + /// The process ID of the browser process that has exited. + /// + /// + /// See the ICoreWebView2BrowserProcessExitedEventArgs article. + /// + property BrowserProcessId : cardinal read GetBrowserProcessId; + end; + + /// + /// Event args for the WebResourceResponseReceived event. + /// + /// + /// See the ICoreWebView2WebResourceResponseReceivedEventArgs article. + /// + TCoreWebView2WebResourceResponseReceivedEventArgs = class + protected + FBaseIntf : ICoreWebView2WebResourceResponseReceivedEventArgs; + + function GetInitialized : boolean; + function GetRequest : ICoreWebView2WebResourceRequest; + function GetResponse : ICoreWebView2WebResourceResponseView; + + public + constructor Create(const aArgs: ICoreWebView2WebResourceResponseReceivedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2WebResourceResponseReceivedEventArgs read FBaseIntf; + /// + /// The request object for the web resource, as committed. This includes + /// headers added by the network stack that were not be included during the + /// associated WebResourceRequested event, such as Authentication headers. + /// Modifications to this object have no effect on how the request is + /// processed as it has already been sent. + /// + /// + /// See the ICoreWebView2WebResourceResponseReceivedEventArgs article. + /// + property Request : ICoreWebView2WebResourceRequest read GetRequest; + /// + /// View of the response object received for the web resource. + /// + /// + /// See the ICoreWebView2WebResourceResponseReceivedEventArgs article. + /// + property Response : ICoreWebView2WebResourceResponseView read GetResponse; + end; + + /// + /// Event args for the DOMContentLoaded event. + /// + /// + /// See the ICoreWebView2DOMContentLoadedEventArgs article. + /// + TCoreWebView2DOMContentLoadedEventArgs = class + protected + FBaseIntf : ICoreWebView2DOMContentLoadedEventArgs; + + function GetInitialized : boolean; + function GetNavigationId : uint64; + + public + constructor Create(const aArgs: ICoreWebView2DOMContentLoadedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2DOMContentLoadedEventArgs read FBaseIntf; + /// + /// The ID of the navigation which corresponds to other navigation ID properties on other navigation events. + /// + /// + /// See the ICoreWebView2DOMContentLoadedEventArgs article. + /// + property NavigationId : uint64 read GetNavigationId; + end; + + /// + /// Event args for the FrameCreated events. + /// + /// + /// See the ICoreWebView2FrameCreatedEventArgs article. + /// + TCoreWebView2FrameCreatedEventArgs = class + protected + FBaseIntf : ICoreWebView2FrameCreatedEventArgs; + + function GetInitialized : boolean; + function GetFrame : ICoreWebView2Frame; + + public + constructor Create(const aArgs: ICoreWebView2FrameCreatedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2FrameCreatedEventArgs read FBaseIntf; + /// + /// The frame which was created. + /// + /// + /// See the ICoreWebView2FrameCreatedEventArgs article. + /// + property Frame : ICoreWebView2Frame read GetFrame; + end; + + /// + /// Event args for the DownloadStarting event. + /// + /// + /// See the ICoreWebView2DownloadStartingEventArgs article. + /// + TCoreWebView2DownloadStartingEventArgs = class + protected + FBaseIntf : ICoreWebView2DownloadStartingEventArgs; + + function GetInitialized : boolean; + function GetDownloadOperation : ICoreWebView2DownloadOperation; + function GetCancel : boolean; + function GetResultFilePath : wvstring; + function GetHandled : boolean; + function GetDeferral : ICoreWebView2Deferral; + + procedure SetCancel(aValue : boolean); + procedure SetResultFilePath(const aValue : wvstring); + procedure SetHandled(aValue : boolean); + + public + constructor Create(const aArgs: ICoreWebView2DownloadStartingEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2DownloadStartingEventArgs read FBaseIntf; + /// + /// Returns the `ICoreWebView2DownloadOperation` for the download that + /// has started. + /// + /// + /// See the ICoreWebView2DownloadStartingEventArgs article. + /// + property DownloadOperation : ICoreWebView2DownloadOperation read GetDownloadOperation; + /// + /// The host may set this flag to cancel the download. If canceled, the + /// download save dialog is not displayed regardless of the + /// `Handled` property. + /// + /// + /// See the ICoreWebView2DownloadStartingEventArgs article. + /// + property Cancel : boolean read GetCancel write SetCancel; + /// + /// The path to the file. If setting the path, the host should ensure that it + /// is an absolute path, including the file name, and that the path does not + /// point to an existing file. If the path points to an existing file, the + /// file will be overwritten. If the directory does not exist, it is created. + /// + /// + /// See the ICoreWebView2DownloadStartingEventArgs article. + /// + property ResultFilePath : wvstring read GetResultFilePath write SetResultFilePath; + /// + /// The host may set this flag to `TRUE` to hide the default download dialog + /// for this download. The download will progress as normal if it is not + /// canceled, there will just be no default UI shown. By default the value is + /// `FALSE` and the default download dialog is shown. + /// + /// + /// See the ICoreWebView2DownloadStartingEventArgs article. + /// + property Handled : boolean read GetHandled write SetHandled; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this operation to + /// complete the event at a later time. + /// + /// + /// See the ICoreWebView2DownloadStartingEventArgs article. + /// + property Deferral : ICoreWebView2Deferral read GetDeferral; + end; + + /// + /// Event args for the ClientCertificateRequested event. + /// + /// + /// See the ICoreWebView2ClientCertificateRequestedEventArgs article. + /// + TCoreWebView2ClientCertificateRequestedEventArgs = class + protected + FBaseIntf : ICoreWebView2ClientCertificateRequestedEventArgs; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + function GetInitialized : boolean; + function GetHost : wvstring; + function GetPort : integer; + function GetIsProxy : boolean; + function GetAllowedCertificateAuthorities : ICoreWebView2StringCollection; + function GetMutuallyTrustedCertificates : ICoreWebView2ClientCertificateCollection; + function GetSelectedCertificate : ICoreWebView2ClientCertificate; + function GetCancel : boolean; + function GetHandled : boolean; + function GetDeferral : ICoreWebView2Deferral; + + procedure SetSelectedCertificate(const aValue : ICoreWebView2ClientCertificate); + procedure SetCancel(aValue : boolean); + procedure SetHandled(aValue : boolean); + + public + constructor Create(const aArgs: ICoreWebView2ClientCertificateRequestedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2ClientCertificateRequestedEventArgs read FBaseIntf; + /// + /// Host name of the server that requested client certificate authentication. + /// Normalization rules applied to the hostname are: + /// * Convert to lowercase characters for ascii characters. + /// * Punycode is used for representing non ascii characters. + /// * Strip square brackets for IPV6 address. + /// + /// + /// See the ICoreWebView2ClientCertificateRequestedEventArgs article. + /// + property Host : wvstring read GetHost; + /// + /// Port of the server that requested client certificate authentication. + /// + /// + /// See the ICoreWebView2ClientCertificateRequestedEventArgs article. + /// + property Port : integer read GetPort; + /// + /// Returns true if the server that issued this request is an http proxy. + /// Returns false if the server is the origin server. + /// + /// + /// See the ICoreWebView2ClientCertificateRequestedEventArgs article. + /// + property IsProxy : boolean read GetIsProxy; + /// + /// Returns the `ICoreWebView2StringCollection`. + /// The collection contains Base64 encoding of DER encoded distinguished names of + /// certificate authorities allowed by the server. + /// + /// + /// See the ICoreWebView2ClientCertificateRequestedEventArgs article. + /// + property AllowedCertificateAuthorities : ICoreWebView2StringCollection read GetAllowedCertificateAuthorities; + /// + /// Returns the `ICoreWebView2ClientCertificateCollection` when client + /// certificate authentication is requested. The collection contains mutually + /// trusted CA certificates. + /// + /// + /// See the ICoreWebView2ClientCertificateRequestedEventArgs article. + /// + property MutuallyTrustedCertificates : ICoreWebView2ClientCertificateCollection read GetMutuallyTrustedCertificates; + /// + /// Returns the selected certificate. + /// + /// + /// See the ICoreWebView2ClientCertificateRequestedEventArgs article. + /// + property SelectedCertificate : ICoreWebView2ClientCertificate read GetSelectedCertificate write SetSelectedCertificate; + /// + /// You may set this flag to cancel the certificate selection. If canceled, + /// the request is aborted regardless of the `Handled` property. By default the + /// value is `FALSE`. + /// + /// + /// See the ICoreWebView2ClientCertificateRequestedEventArgs article. + /// + property Cancel : boolean read GetCancel write SetCancel; + /// + /// You may set this flag to `TRUE` to respond to the server with or + /// without a certificate. If this flag is `TRUE` with a `SelectedCertificate` + /// it responds to the server with the selected certificate otherwise respond to the + /// server without a certificate. By default the value of `Handled` and `Cancel` are `FALSE` + /// and display default client certificate selection dialog prompt to allow the user to + /// choose a certificate. The `SelectedCertificate` is ignored unless `Handled` is set `TRUE`. + /// + /// + /// See the ICoreWebView2ClientCertificateRequestedEventArgs article. + /// + property Handled : boolean read GetHandled write SetHandled; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this operation to + /// complete the event at a later time. + /// + /// + /// See the ICoreWebView2ClientCertificateRequestedEventArgs article. + /// + property Deferral : ICoreWebView2Deferral read GetDeferral; + end; + + /// + /// Event args for the BasicAuthenticationRequested event. Will contain the + /// request that led to the HTTP authorization challenge, the challenge + /// and allows the host to provide authentication response or cancel the request. + /// + /// + /// See the ICoreWebView2BasicAuthenticationRequestedEventArgs article. + /// + TCoreWebView2BasicAuthenticationRequestedEventArgs = class + protected + FBaseIntf : ICoreWebView2BasicAuthenticationRequestedEventArgs; + + function GetInitialized : boolean; + function GetUri : wvstring; + function GetChallenge : wvstring; + function GetResponse : ICoreWebView2BasicAuthenticationResponse; + function GetCancel : boolean; + function GetDeferral : ICoreWebView2Deferral; + + procedure SetCancel(aValue : boolean); + + public + constructor Create(const aArgs: ICoreWebView2BasicAuthenticationRequestedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2BasicAuthenticationRequestedEventArgs read FBaseIntf; + /// + /// The URI that led to the authentication challenge. For proxy authentication + /// requests, this will be the URI of the proxy server. + /// + /// + /// See the ICoreWebView2BasicAuthenticationRequestedEventArgs article. + /// + property Uri : wvstring read GetUri; + /// + /// The authentication challenge string. + /// + /// + /// See the ICoreWebView2BasicAuthenticationRequestedEventArgs article. + /// + property Challenge : wvstring read GetChallenge; + /// + /// Response to the authentication request with credentials. This object will be populated by the app + /// if the host would like to provide authentication credentials. + /// + /// + /// See the ICoreWebView2BasicAuthenticationRequestedEventArgs article. + /// + property Response : ICoreWebView2BasicAuthenticationResponse read GetResponse; + /// + /// Cancel the authentication request. False by default. + /// If set to true, Response will be ignored. + /// + /// + /// See the ICoreWebView2BasicAuthenticationRequestedEventArgs article. + /// + property Cancel : boolean read GetCancel write SetCancel; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this deferral to + /// defer the decision to show the Basic Authentication dialog. + /// + /// + /// See the ICoreWebView2BasicAuthenticationRequestedEventArgs article. + /// + property Deferral : ICoreWebView2Deferral read GetDeferral; + end; + + /// + /// Event args for the ContextMenuRequested event. Will contain the selection information + /// and a collection of all of the default context menu items that the WebView + /// would show. Allows the app to draw its own context menu or add/remove + /// from the default context menu. + /// + /// + /// See the ICoreWebView2ContextMenuRequestedEventArgs article. + /// + TCoreWebView2ContextMenuRequestedEventArgs = class + protected + FBaseIntf : ICoreWebView2ContextMenuRequestedEventArgs; + + function GetInitialized : boolean; + function GetMenuItems : ICoreWebView2ContextMenuItemCollection; + function GetContextMenuTarget : ICoreWebView2ContextMenuTarget; + function GetLocation : TPoint; + function GetSelectedCommandId : Integer; + function GetDeferral : ICoreWebView2Deferral; + function GetHandled : boolean; + + procedure SetSelectedCommandId(aValue: Integer); + procedure SetHandled(aValue : boolean); + + public + constructor Create(const aArgs: ICoreWebView2ContextMenuRequestedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2ContextMenuRequestedEventArgs read FBaseIntf; + /// + /// Gets the collection of `ContextMenuItem` objects. + /// See `ICoreWebView2ContextMenuItemCollection` for more details. + /// + /// + /// See the ICoreWebView2ContextMenuRequestedEventArgs article. + /// + property MenuItems : ICoreWebView2ContextMenuItemCollection read GetMenuItems; + /// + /// Gets the target information associated with the requested context menu. + /// See `ICoreWebView2ContextMenuTarget` for more details. + /// + /// + /// See the ICoreWebView2ContextMenuRequestedEventArgs article. + /// + property ContextMenuTarget : ICoreWebView2ContextMenuTarget read GetContextMenuTarget; + /// + /// Gets the coordinates where the context menu request occurred in relation to the upper + /// left corner of the WebView bounds. + /// + /// + /// See the ICoreWebView2ContextMenuRequestedEventArgs article. + /// + property Location : TPoint read GetLocation; + /// + /// Gets the selected CommandId. + /// + /// + /// See the ICoreWebView2ContextMenuRequestedEventArgs article. + /// + property SelectedCommandId : integer read GetSelectedCommandId write SetSelectedCommandId; + /// + /// Gets whether the `ContextMenuRequested` event is handled by host. + /// + /// + /// See the ICoreWebView2ContextMenuRequestedEventArgs article. + /// + property Handled : boolean read GetHandled write SetHandled; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this operation to + /// complete the event when the custom context menu is closed. + /// + /// + /// See the ICoreWebView2ContextMenuRequestedEventArgs article. + /// + property Deferral : ICoreWebView2Deferral read GetDeferral; + end; + + /// + /// Event args for the ServerCertificateErrorDetected event. + /// + /// + /// See the ICoreWebView2ServerCertificateErrorDetectedEventArgs article. + /// + TCoreWebView2ServerCertificateErrorDetectedEventArgs = class + protected + FBaseIntf : ICoreWebView2ServerCertificateErrorDetectedEventArgs; + + function GetInitialized : boolean; + function GetErrorStatus : TWVWebErrorStatus; + function GetRequestUri : wvstring; + function GetServerCertificate : ICoreWebView2Certificate; + function GetAction : TWVServerCertificateErrorAction; + function GetDeferral : ICoreWebView2Deferral; + + procedure SetAction(aValue: TWVServerCertificateErrorAction); + + public + constructor Create(const aArgs: ICoreWebView2ServerCertificateErrorDetectedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2ServerCertificateErrorDetectedEventArgs read FBaseIntf; + /// + /// The TLS error code for the invalid certificate. + /// + /// + /// See the ICoreWebView2ServerCertificateErrorDetectedEventArgs article. + /// + property ErrorStatus : TWVWebErrorStatus read GetErrorStatus; + /// + /// URI associated with the request for the invalid certificate. + /// + /// + /// See the ICoreWebView2ServerCertificateErrorDetectedEventArgs article. + /// + property RequestUri : wvstring read GetRequestUri; + /// + /// Returns the server certificate. + /// + /// + /// See the ICoreWebView2ServerCertificateErrorDetectedEventArgs article. + /// + property ServerCertificate : ICoreWebView2Certificate read GetServerCertificate; + /// + /// The action of the server certificate error detection. + /// The default value is `COREWEBVIEW2_SERVER_CERTIFICATE_ERROR_ACTION_DEFAULT`. + /// + /// + /// See the ICoreWebView2ServerCertificateErrorDetectedEventArgs article. + /// + property Action : TWVServerCertificateErrorAction read GetAction write SetAction; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this operation to + /// complete the event at a later time. + /// + /// + /// See the ICoreWebView2ServerCertificateErrorDetectedEventArgs article. + /// + property Deferral : ICoreWebView2Deferral read GetDeferral; + end; + + /// + /// Event args for LaunchingExternalUriScheme event. + /// + /// + /// See the ICoreWebView2LaunchingExternalUriSchemeEventArgs article. + /// + TCoreWebView2LaunchingExternalUriSchemeEventArgs = class + protected + FBaseIntf : ICoreWebView2LaunchingExternalUriSchemeEventArgs; + + function GetInitialized : boolean; + function GetUri : wvstring; + function GetInitiatingOrigin : wvstring; + function GetIsUserInitiated : boolean; + function GetCancel : boolean; + function GetDeferral : ICoreWebView2Deferral; + + procedure SetCancel(aValue : boolean); + + public + constructor Create(const aArgs: ICoreWebView2LaunchingExternalUriSchemeEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2LaunchingExternalUriSchemeEventArgs read FBaseIntf; + /// + /// The URI with the external URI scheme to be launched. + /// + /// + /// See the ICoreWebView2LaunchingExternalUriSchemeEventArgs article. + /// + property Uri : wvstring read GetUri; + /// + /// The origin initiating the external URI scheme launch. + /// The origin will be an empty string if the request is initiated by calling + /// `CoreWebView2.Navigate` on the external URI scheme. If a script initiates + /// the navigation, the `InitiatingOrigin` will be the top-level document's + /// `Source`, for example, if `window.location` is set to `"calculator://"`, the + /// `InitiatingOrigin` will be set to `calculator://`. If the request is initiated + /// from a child frame, the `InitiatingOrigin` will be the source of that child frame. + /// If the `InitiatingOrigin` is + /// [opaque](https://html.spec.whatwg.org/multipage/origin.html#concept-origin-opaque), + /// the `InitiatingOrigin` reported in the event args will be its precursor origin. + /// The precursor origin is the origin that created the opaque origin. For example, if + /// a frame on example.com opens a subframe with a different opaque origin, the subframe's + /// precursor origin is example.com. + /// + /// + /// See the ICoreWebView2LaunchingExternalUriSchemeEventArgs article. + /// + property InitiatingOrigin : wvstring read GetInitiatingOrigin; + /// + /// `TRUE` when the external URI scheme request was initiated through a user gesture. + /// \>NOTE: Being initiated through a user gesture does not mean that user intended + /// to access the associated resource. + /// + /// + /// See the ICoreWebView2LaunchingExternalUriSchemeEventArgs article. + /// + property IsUserInitiated : boolean read GetIsUserInitiated; + /// + /// The event handler may set this property to `TRUE` to cancel the external URI scheme + /// launch. If set to `TRUE`, the external URI scheme will not be launched, and the default + /// dialog is not displayed. This property can be used to replace the normal + /// handling of launching an external URI scheme. + /// The initial value of the `Cancel` property is `FALSE`. + /// + /// + /// See the ICoreWebView2LaunchingExternalUriSchemeEventArgs article. + /// + property Cancel : boolean read GetCancel write SetCancel; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this operation to + /// complete the event at a later time. + /// + /// + /// See the ICoreWebView2LaunchingExternalUriSchemeEventArgs article. + /// + property Deferral : ICoreWebView2Deferral read GetDeferral; + end; + + /// + /// This is the Interface for non-client region change event args. + /// + /// + /// See the ICoreWebView2NonClientRegionChangedEventArgs article. + /// + TCoreWebView2NonClientRegionChangedEventArgs = class + protected + FBaseIntf : ICoreWebView2NonClientRegionChangedEventArgs; + + function GetInitialized : boolean; + function GetRegionKind : TWVNonClientRegionKind; + + public + constructor Create(const aArgs: ICoreWebView2NonClientRegionChangedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2NonClientRegionChangedEventArgs read FBaseIntf; + /// + /// This property represents the COREWEBVIEW2_NON_CLIENT_REGION_KIND which the + /// region changed event corresponds to. With this property an app can query + /// for a collection of rects which have that region kind by using + /// QueryNonClientRegion on the composition controller. + /// + /// + /// See the ICoreWebView2NonClientRegionChangedEventArgs article. + /// + property RegionKind : TWVNonClientRegionKind read GetRegionKind; + end; + + /// + /// Event args for the `NotificationReceived` event. + /// + /// + /// See the ICoreWebView2NotificationReceivedEventArgs article. + /// + TCoreWebView2NotificationReceivedEventArgs = class + protected + FBaseIntf : ICoreWebView2NotificationReceivedEventArgs; + + function GetInitialized : boolean; + function GetSenderOrigin : wvstring; + function GetNotification : ICoreWebView2Notification; + function GetHandled : boolean; + function GetDeferral : ICoreWebView2Deferral; + + procedure SetHandled(aValue: boolean); + + public + constructor Create(const aArgs: ICoreWebView2NotificationReceivedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2NotificationReceivedEventArgs read FBaseIntf; + /// + /// The origin of the web content that sends the notification, such as + /// `https://example.com/` or `https://www.example.com/`. + /// + property SenderOrigin : wvstring read GetSenderOrigin; + /// + /// The notification that was received. You can access the + /// properties on the Notification object to show your own notification. + /// + property Notification : ICoreWebView2Notification read GetNotification; + /// + /// Sets whether the `NotificationReceived` event is handled by the host after + /// the event handler completes or if there is a deferral then after the + /// deferral is completed. + /// + /// If `Handled` is set to TRUE then WebView will not display the notification + /// with the default UI, and the host will be responsible for handling the + /// notification and for letting the web content know that the notification + /// has been displayed, clicked, or closed. You must set `Handled` to `TRUE` + /// before you call `ReportShown`, `ReportClicked`, + /// `ReportClickedWithActionIndex` and `ReportClosed`, otherwise they will + /// fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`. If after the event + /// handler or deferral completes `Handled` is set to FALSE then WebView will + /// display the default notification UI. Note that you cannot un-handle this + /// event once you have set `Handled` to be `TRUE`. The initial value is + /// FALSE. + /// + property Handled : boolean read GetHandled write SetHandled; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this operation to complete + /// the event at a later time. + /// + property Deferral : ICoreWebView2Deferral read GetDeferral; + end; + + /// + /// The event args for `SaveAsUIShowing` event. + /// + /// + /// See the ICoreWebView2SaveAsUIShowingEventArgs article. + /// + TCoreWebView2SaveAsUIShowingEventArgs = class + protected + FBaseIntf : ICoreWebView2SaveAsUIShowingEventArgs; + + function GetInitialized : boolean; + function GetContentMimeType : wvstring; + function GetCancel : boolean; + function GetSuppressDefaultDialog : boolean; + function GetDeferral : ICoreWebView2Deferral; + function GetSaveAsFilePath : wvstring; + function GetAllowReplace : boolean; + function GetKind : TWVSaveAsKind; + + procedure SetCancel(aValue : boolean); + procedure SetSuppressDefaultDialog(aValue : boolean); + procedure SetSaveAsFilePath(const aValue : wvstring); + procedure SetAllowReplace(aValue : boolean); + procedure SetKind(aValue : TWVSaveAsKind); + + public + constructor Create(const aArgs: ICoreWebView2SaveAsUIShowingEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2SaveAsUIShowingEventArgs read FBaseIntf; + /// + /// Get the Mime type of content to be saved. + /// + property ContentMimeType : wvstring read GetContentMimeType; + /// + /// Sets the `Cancel` property. Set this property to `TRUE` to cancel the Save As action + /// and prevent the download from starting. ShowSaveAsUI returns + /// `COREWEBVIEW2_SAVE_AS_UI_RESULT_CANCELLED` in this case. The default value is `FALSE`. + /// + property Cancel : boolean read GetCancel write SetCancel; + /// + /// Sets the `SuppressDefaultDialog` property, which indicates whether the system + /// default dialog is suppressed. When `SuppressDefaultDialog` is `FALSE`, the default + /// Save As dialog is shown and the values assigned through `SaveAsFilePath`, `AllowReplace` + /// and `Kind` are ignored when the event args invoke completed. + /// + /// Set `SuppressDefaultDialog` to `TRUE` to perform a silent Save As. When + /// `SuppressDefaultDialog` is `TRUE`, the system dialog is skipped and the + /// `SaveAsFilePath`, `AllowReplace` and `Kind` values are used. + /// + /// The default value is FALSE. + /// + property SuppressDefaultDialog : boolean read GetSuppressDefaultDialog write SetSuppressDefaultDialog; + /// + /// Returns an `ICoreWebView2Deferral` object. This will defer showing the + /// default Save As dialog and performing the Save As operation. + /// + property Deferral : ICoreWebView2Deferral read GetDeferral; + /// + /// Set the `SaveAsFilePath` property for Save As. `SaveAsFilePath` is an absolute path + /// of the location. It includes the file name and extension. If `SaveAsFilePath` is not + /// valid (for example, the root drive does not exist), Save As is denied and + /// `COREWEBVIEW2_SAVE_AS_INVALID_PATH` is returned. + /// + /// If the associated download completes successfully, a target file is saved at + /// this location. If the Kind property is `COREWEBVIEW2_SAVE_AS_KIND_COMPLETE`, + /// there will be an additional directory with resources files. + /// + /// The default value is a system suggested path, based on users' local environment. + /// + property SaveAsFilePath : wvstring read GetSaveAsFilePath write SetSaveAsFilePath; + /// + /// `AllowReplace` allows user to control what happens when a file already + /// exists in the file path to which the Save As operation is saving. + /// Setting this property to `TRUE` allows existing files to be replaced. + /// Setting this property to `FALSE` will not replace existing files and will return + /// `COREWEBVIEW2_SAVE_AS_UI_RESULT_FILE_ALREADY_EXISTS`. + /// + /// The default value is `FALSE`. + /// + property AllowReplace : boolean read GetAllowReplace write SetAllowReplace; + /// + /// Sets the `Kind` property to save documents of different kinds. See the + /// `COREWEBVIEW2_SAVE_AS_KIND` enum for a description of the different options. + /// If the kind is not allowed for the current document, ShowSaveAsUI returns + /// `COREWEBVIEW2_SAVE_AS_UI_RESULT_KIND_NOT_SUPPORTED`. + /// + /// The default value is `COREWEBVIEW2_SAVE_AS_KIND_DEFAULT`. + /// + property Kind : TWVSaveAsKind read GetKind write SetKind; + end; + + /// + /// The event args for `SaveFileSecurityCheckStarting` event. + /// + /// + /// See the ICoreWebView2SaveFileSecurityCheckStartingEventArgs article. + /// + TCoreWebView2SaveFileSecurityCheckStartingEventArgs = class + protected + FBaseIntf : ICoreWebView2SaveFileSecurityCheckStartingEventArgs; + + function GetInitialized : boolean; + function GetCancelSave : boolean; + function GetDocumentOriginUri : wvstring; + function GetFileExtension : wvstring; + function GetFilePath : wvstring; + function GetSuppressDefaultPolicy : boolean; + function GetDeferral : ICoreWebView2Deferral; + + procedure SetCancelSave(aValue: boolean); + procedure SetSuppressDefaultPolicy(aValue: boolean); + + public + constructor Create(const aArgs: ICoreWebView2SaveFileSecurityCheckStartingEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2SaveFileSecurityCheckStartingEventArgs read FBaseIntf; + /// + /// Set if cancel the upcoming save/download. `TRUE` means the action + /// will be cancelled before validations in default policy. + /// The default value is `FALSE`. + /// + property CancelSave : boolean read GetCancelSave write SetCancelSave; + /// + /// Get the document origin URI of this file save operation. + /// + property DocumentOriginUri : wvstring read GetDocumentOriginUri; + /// + /// Get the extension of file to be saved. + /// The file extension is the extension portion of the FilePath, + /// preserving original case. + /// Only final extension with period "." will be provided. For example, + /// "*.tar.gz" is a double extension, where the ".gz" will be its + /// final extension. + /// File extension can be empty, if the file name has no extension + /// at all. + /// + property FileExtension : wvstring read GetFileExtension; + /// + /// Get the full path of file to be saved. This includes the + /// file name and extension. + /// This method doesn't provide path validation, the returned + /// string may longer than MAX_PATH. + /// + property FilePath : wvstring read GetFilePath; + /// + /// Set if the default policy checking and security warning will be + /// suppressed. `TRUE` means it will be suppressed. + /// The default value is `FALSE`. + /// + property SuppressDefaultPolicy : boolean read GetSuppressDefaultPolicy write SetSuppressDefaultPolicy; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this operation to complete + /// the SaveFileSecurityCheckStartingEvent. + /// The default policy checking and any default UI will be blocked temporarily, + /// saving file to local won't start, until the deferral is completed. + /// + property Deferral : ICoreWebView2Deferral read GetDeferral; + end; + + /// + /// Event args for the `ScreenCaptureStarting` event. + /// + /// + /// See the TCoreWebView2ScreenCaptureStartingEventArgs article. + /// + TCoreWebView2ScreenCaptureStartingEventArgs = class + protected + FBaseIntf : ICoreWebView2ScreenCaptureStartingEventArgs; + + function GetInitialized : boolean; + function GetCancel : boolean; + function GetHandled : boolean; + function GetCoreWebView2FrameInfo : ICoreWebView2FrameInfo; + function GetDeferral : ICoreWebView2Deferral; + + procedure SetCancel(aValue: boolean); + procedure SetHandled(aValue: boolean); + + public + constructor Create(const aArgs: ICoreWebView2ScreenCaptureStartingEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2ScreenCaptureStartingEventArgs read FBaseIntf; + /// + /// The host may set this flag to cancel the screen capture. If canceled, + /// the screen capture UI is not displayed regardless of the + /// `Handled` property. + /// On the script side, it will return with a NotAllowedError as Permission denied. + /// + property Cancel : boolean read GetCancel write SetCancel; + /// + /// By default, both the `ScreenCaptureStarting` event handlers on the + /// `CoreWebView2Frame` and the `CoreWebView2` will be invoked, with the + /// `CoreWebView2Frame` event handlers invoked first. The host may + /// set this flag to `TRUE` within the `CoreWebView2Frame` event handlers + /// to prevent the remaining `CoreWebView2` event handlers from being + /// invoked. If the flag is set to `FALSE` within the `CoreWebView2Frame` + /// event handlers, downstream handlers can update the `Cancel` property. + /// + /// If a deferral is taken on the event args, then you must synchronously + /// set `Handled` to TRUE prior to taking your deferral to prevent the + /// `CoreWebView2`s event handlers from being invoked. + /// + property Handled : boolean read GetHandled write SetHandled; + /// + /// The associated frame information that requests the screen capture + /// permission. This can be used to get the frame source, name, frameId, + /// and parent frame information. + /// + property OriginalSourceFrameInfo : ICoreWebView2FrameInfo read GetCoreWebView2FrameInfo; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this deferral to + /// defer the decision to show the Screen Capture UI. getDisplayMedia() + /// won't call its callbacks until the deferral is completed. + /// + property Deferral : ICoreWebView2Deferral read GetDeferral; + end; + + /// + /// Event args for the `DragStarting` event. + /// + /// + /// See the ICoreWebView2DragStartingEventArgs article. + /// + TCoreWebView2DragStartingEventArgs = class + protected + FBaseIntf : ICoreWebView2DragStartingEventArgs; + + function GetInitialized : boolean; + function GetAllowedDropEffects : cardinal; + function GetData : IDataObject; + function GetHandled : boolean; + function GetPosition : TPoint; + function GetDeferral : ICoreWebView2Deferral; + + procedure SetHandled(aValue: boolean); + + public + constructor Create(const aArgs: ICoreWebView2DragStartingEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2DragStartingEventArgs read FBaseIntf; + /// + /// The [OLE DROPEFFECT](/windows/win32/com/dropeffect-constants) + /// values this drag data supports. + /// + /// + /// See the DROPEFFECT Constants article. + /// + property AllowedDropEffects : cardinal read GetAllowedDropEffects; + /// + /// The data to be dragged. + /// + property Data : IDataObject read GetData; + /// + /// Indicates whether this event has been handled by the app. If the + /// app handles this event, WebView2 will not initiate drag drop. If + /// the app does not handle the event, WebView2 will initiate its own + /// drag drop logic. + /// + property Handled : boolean read GetHandled write SetHandled; + /// + /// The position at which drag was detected given in WebView2 relative + /// coordinates. + /// + property Position : TPoint read GetPosition; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this operation to complete + /// the CoreWebView2DragStartingEventArgs. + /// + /// Until the deferral is completed, subsequent attempts to initiate drag + /// in the WebView2 will fail and if the cursor was changed as part of + /// drag it will not restore. + /// + property Deferral : ICoreWebView2Deferral read GetDeferral; + end; + + /// + /// Event args for the `DedicatedWorkerCreated` event. + /// + /// + /// See the ICoreWebView2DedicatedWorkerCreatedEventArgs article. + /// + TCoreWebView2DedicatedWorkerCreatedEventArgs = class + protected + FBaseIntf : ICoreWebView2DedicatedWorkerCreatedEventArgs; + + function GetInitialized : boolean; + function GetOriginalSourceFrameInfo : ICoreWebView2FrameInfo; + function GetWorker : ICoreWebView2DedicatedWorker; + + public + constructor Create(const aArgs: ICoreWebView2DedicatedWorkerCreatedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2DedicatedWorkerCreatedEventArgs read FBaseIntf; + /// + /// The associated frame information that created the dedicated worker. + /// This can be used to get the frame source, name, frameId, + /// and parent frame information. + /// + property OriginalSourceFrameInfo : ICoreWebView2FrameInfo read GetOriginalSourceFrameInfo; + /// + /// The dedicated worker that was created. + /// + property Worker : ICoreWebView2DedicatedWorker read GetWorker; + end; + + /// + /// Event args for the `ServiceWorkerRegistered` event. + /// + /// + /// See the ICoreWebView2ServiceWorkerRegisteredEventArgs article. + /// + TCoreWebView2ServiceWorkerRegisteredEventArgs = class + protected + FBaseIntf : ICoreWebView2ServiceWorkerRegisteredEventArgs; + + function GetInitialized : boolean; + function GetServiceWorkerRegistration : ICoreWebView2ServiceWorkerRegistration; + + public + constructor Create(const aArgs: ICoreWebView2ServiceWorkerRegisteredEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2ServiceWorkerRegisteredEventArgs read FBaseIntf; + /// + /// The service worker that was registered. + /// + property ServiceWorkerRegistration : ICoreWebView2ServiceWorkerRegistration read GetServiceWorkerRegistration; + end; + + /// + /// Event args for the `ServiceWorkerActivated` event. + /// + /// + /// See the ICoreWebView2ServiceWorkerActivatedEventArgs article. + /// + TCoreWebView2ServiceWorkerActivatedEventArgs = class + protected + FBaseIntf : ICoreWebView2ServiceWorkerActivatedEventArgs; + + function GetInitialized : boolean; + function GetActiveServiceWorker : ICoreWebView2ServiceWorker; + + public + constructor Create(const aArgs: ICoreWebView2ServiceWorkerActivatedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2ServiceWorkerActivatedEventArgs read FBaseIntf; + /// + /// The service worker that was activated. + /// + property ActiveServiceWorker : ICoreWebView2ServiceWorker read GetActiveServiceWorker; + end; + + /// + /// Event args for the `SharedWorkerCreated` event. + /// + /// + /// See the ICoreWebView2SharedWorkerCreatedEventArgs article. + /// + TCoreWebView2SharedWorkerCreatedEventArgs = class + protected + FBaseIntf : ICoreWebView2SharedWorkerCreatedEventArgs; + + function GetInitialized : boolean; + function GetWorker : ICoreWebView2SharedWorker; + + public + constructor Create(const aArgs: ICoreWebView2SharedWorkerCreatedEventArgs); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2SharedWorkerCreatedEventArgs read FBaseIntf; + /// + /// The shared worker that was created. + /// + property Worker : ICoreWebView2SharedWorker read GetWorker; + end; + +implementation + +uses + uRESTDWPrivWVMiscFunctions; + +// TCoreWebView2AcceleratorKeyPressedEventArgs + +constructor TCoreWebView2AcceleratorKeyPressedEventArgs.Create(const aArgs: ICoreWebView2AcceleratorKeyPressedEventArgs); +begin + inherited Create; + + InitializeFields; + + FBaseIntf := aArgs; + + if Initialized then + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2AcceleratorKeyPressedEventArgs2, FBaseIntf2); +end; + +destructor TCoreWebView2AcceleratorKeyPressedEventArgs.Destroy; +begin + InitializeFields; + + inherited Destroy; +end; + +procedure TCoreWebView2AcceleratorKeyPressedEventArgs.InitializeFields; +begin + FBaseIntf := nil; + FBaseIntf2 := nil; +end; + +function TCoreWebView2AcceleratorKeyPressedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2AcceleratorKeyPressedEventArgs.GetKeyEventKind : TWVKeyEventKind; +var + TempType : COREWEBVIEW2_KEY_EVENT_KIND; +begin + if Initialized and succeeded(FBaseIntf.Get_KeyEventKind(TempType)) then + Result := TempType + else + Result := 0; +end; + +function TCoreWebView2AcceleratorKeyPressedEventArgs.GetVirtualKey : LongWord; +var + TempKey : LongWord; +begin + if Initialized and succeeded(FBaseIntf.Get_VirtualKey(TempKey)) then + Result := TempKey + else + Result := 0; +end; + +function TCoreWebView2AcceleratorKeyPressedEventArgs.GetKeyEventLParam : integer; +var + TempParam : Integer; +begin + if Initialized and succeeded(FBaseIntf.Get_KeyEventLParam(TempParam)) then + Result := TempParam + else + Result := 0; +end; + +function TCoreWebView2AcceleratorKeyPressedEventArgs.GetHandled : boolean; +var + TempHandled : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_Handled(TempHandled)) and + (TempHandled <> 0); +end; + +function TCoreWebView2AcceleratorKeyPressedEventArgs.GetRepeatCount : LongWord; +var + TempStatus : COREWEBVIEW2_PHYSICAL_KEY_STATUS; +begin + if Initialized and succeeded(FBaseIntf.Get_PhysicalKeyStatus(TempStatus)) then + Result := TempStatus.RepeatCount + else + Result := 0; +end; + +function TCoreWebView2AcceleratorKeyPressedEventArgs.GetScanCode : LongWord; +var + TempStatus : COREWEBVIEW2_PHYSICAL_KEY_STATUS; +begin + if Initialized and succeeded(FBaseIntf.Get_PhysicalKeyStatus(TempStatus)) then + Result := TempStatus.ScanCode + else + Result := 0; +end; + +function TCoreWebView2AcceleratorKeyPressedEventArgs.GetIsExtendedKey : boolean; +var + TempStatus : COREWEBVIEW2_PHYSICAL_KEY_STATUS; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_PhysicalKeyStatus(TempStatus)) and + (TempStatus.IsExtendedKey <> 0); +end; + +function TCoreWebView2AcceleratorKeyPressedEventArgs.GetIsMenuKeyDown : boolean; +var + TempStatus : COREWEBVIEW2_PHYSICAL_KEY_STATUS; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_PhysicalKeyStatus(TempStatus)) and + (TempStatus.IsMenuKeyDown <> 0); +end; + +function TCoreWebView2AcceleratorKeyPressedEventArgs.GetWasKeyDown : boolean; +var + TempStatus : COREWEBVIEW2_PHYSICAL_KEY_STATUS; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_PhysicalKeyStatus(TempStatus)) and + (TempStatus.WasKeyDown <> 0); +end; + +function TCoreWebView2AcceleratorKeyPressedEventArgs.GetIsKeyReleased : boolean; +var + TempStatus : COREWEBVIEW2_PHYSICAL_KEY_STATUS; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_PhysicalKeyStatus(TempStatus)) and + (TempStatus.IsKeyReleased <> 0); +end; + +function TCoreWebView2AcceleratorKeyPressedEventArgs.GetIsBrowserAcceleratorKeyEnabled : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_IsBrowserAcceleratorKeyEnabled(TempResult)) and + (TempResult <> 0); +end; + +procedure TCoreWebView2AcceleratorKeyPressedEventArgs.SetHandled(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_Handled(ord(aValue)); +end; + +procedure TCoreWebView2AcceleratorKeyPressedEventArgs.SetIsBrowserAcceleratorKeyEnabled(aValue : boolean); +begin + if assigned(FBaseIntf2) then + FBaseIntf2.Set_IsBrowserAcceleratorKeyEnabled(ord(aValue)); +end; + + +// TCoreWebView2ContentLoadingEventArgs + +constructor TCoreWebView2ContentLoadingEventArgs.Create(const aArgs: ICoreWebView2ContentLoadingEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2ContentLoadingEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2ContentLoadingEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2ContentLoadingEventArgs.GetIsErrorPage : boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_IsErrorPage(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2ContentLoadingEventArgs.GetNavigationId : uint64; +var + TempID : Largeuint; +begin + if Initialized and succeeded(FBaseIntf.Get_NavigationId(TempID)) then + Result := uint64(TempID) + else + Result := 0; +end; + + +// TCoreWebView2DevToolsProtocolEventReceivedEventArgs + +constructor TCoreWebView2DevToolsProtocolEventReceivedEventArgs.Create(const aArgs: ICoreWebView2DevToolsProtocolEventReceivedEventArgs); +begin + inherited Create; + + InitializeFields; + + FBaseIntf := aArgs; + + if Initialized then + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2DevToolsProtocolEventReceivedEventArgs2, FBaseIntf2); +end; + +destructor TCoreWebView2DevToolsProtocolEventReceivedEventArgs.Destroy; +begin + InitializeFields; + + inherited Destroy; +end; + +procedure TCoreWebView2DevToolsProtocolEventReceivedEventArgs.InitializeFields; +begin + FBaseIntf := nil; + FBaseIntf2 := nil; +end; + +function TCoreWebView2DevToolsProtocolEventReceivedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2DevToolsProtocolEventReceivedEventArgs.GetParameterObjectAsJson : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + + if Initialized and + succeeded(FBaseIntf.Get_ParameterObjectAsJson(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2DevToolsProtocolEventReceivedEventArgs.GetSessionId : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_sessionId(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + + + +// TCoreWebView2MoveFocusRequestedEventArgs + +constructor TCoreWebView2MoveFocusRequestedEventArgs.Create(const aArgs: ICoreWebView2MoveFocusRequestedEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2MoveFocusRequestedEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2MoveFocusRequestedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2MoveFocusRequestedEventArgs.GetReason : TWVMoveFocusReason; +var + TempReason : COREWEBVIEW2_MOVE_FOCUS_REASON; +begin + if Initialized and succeeded(FBaseIntf.Get_reason(TempReason)) then + Result := TempReason + else + Result := 0; +end; + +function TCoreWebView2MoveFocusRequestedEventArgs.GetHandled : boolean; +var + TempHandled : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_Handled(TempHandled)) and + (TempHandled <> 0); +end; + +procedure TCoreWebView2MoveFocusRequestedEventArgs.SetHandled(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_Handled(ord(aValue)); +end; + + +// TCoreWebView2NavigationCompletedEventArgs + +constructor TCoreWebView2NavigationCompletedEventArgs.Create(const aArgs: ICoreWebView2NavigationCompletedEventArgs); +begin + inherited Create; + + InitializeFields; + + FBaseIntf := aArgs; + + if Initialized then + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2NavigationCompletedEventArgs2, FBaseIntf2); +end; + +destructor TCoreWebView2NavigationCompletedEventArgs.Destroy; +begin + InitializeFields; + + inherited Destroy; +end; + +procedure TCoreWebView2NavigationCompletedEventArgs.InitializeFields; +begin + FBaseIntf := nil; + FBaseIntf2 := nil; +end; + +function TCoreWebView2NavigationCompletedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2NavigationCompletedEventArgs.GetIsSuccess : boolean; +var + TempSuccess : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_IsSuccess(TempSuccess)) and + (TempSuccess <> 0); +end; + +function TCoreWebView2NavigationCompletedEventArgs.GetWebErrorStatus : TWVWebErrorStatus; +var + TempStatus : COREWEBVIEW2_WEB_ERROR_STATUS; +begin + if Initialized and succeeded(FBaseIntf.Get_WebErrorStatus(TempStatus)) then + Result := TempStatus + else + Result := 0; +end; + +function TCoreWebView2NavigationCompletedEventArgs.GetNavigationID : uint64; +var + TempID : Largeuint; +begin + if Initialized and succeeded(FBaseIntf.Get_NavigationId(TempID)) then + Result := uint64(TempID) + else + Result := 0; +end; + +function TCoreWebView2NavigationCompletedEventArgs.GetHttpStatusCode : integer; +var + TempResult : SYSINT; +begin + Result := 0; + TempResult := 0; + + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_HttpStatusCode(TempResult)) then + Result := TempResult; +end; + + +// TCoreWebView2NavigationStartingEventArgs + +constructor TCoreWebView2NavigationStartingEventArgs.Create(const aArgs: ICoreWebView2NavigationStartingEventArgs); +begin + inherited Create; + + InitializeFields; + + FBaseIntf := aArgs; + + if Initialized and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2NavigationStartingEventArgs2, FBaseIntf2) then + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2NavigationStartingEventArgs3, FBaseIntf3); +end; + +destructor TCoreWebView2NavigationStartingEventArgs.Destroy; +begin + InitializeFields; + + inherited Destroy; +end; + +procedure TCoreWebView2NavigationStartingEventArgs.InitializeFields; +begin + FBaseIntf := nil; + FBaseIntf2 := nil; + FBaseIntf3 := nil; +end; + +function TCoreWebView2NavigationStartingEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2NavigationStartingEventArgs.GetURI : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_uri(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2NavigationStartingEventArgs.GetIsUserInitiated : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_IsUserInitiated(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2NavigationStartingEventArgs.GetIsRedirected : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_IsRedirected(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2NavigationStartingEventArgs.GetRequestHeaders : ICoreWebView2HttpRequestHeaders; +var + TempResult : ICoreWebView2HttpRequestHeaders; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_RequestHeaders(TempResult)) and + assigned(TempResult) then + Result := TempResult; +end; + +function TCoreWebView2NavigationStartingEventArgs.GetCancel : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_Cancel(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2NavigationStartingEventArgs.GetNavigationID : uint64; +var + TempID : Largeuint; +begin + if Initialized and succeeded(FBaseIntf.Get_NavigationId(TempID)) then + Result := uint64(TempID) + else + Result := 0; +end; + +function TCoreWebView2NavigationStartingEventArgs.GetAdditionalAllowedFrameAncestors : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_AdditionalAllowedFrameAncestors(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2NavigationStartingEventArgs.GetNavigationKind : TWVNavigationKind; +var + TempResult : COREWEBVIEW2_NAVIGATION_KIND; +begin + TempResult := COREWEBVIEW2_NAVIGATION_KIND_RELOAD; + Result := TempResult; + + if assigned(FBaseIntf3) and + succeeded(FBaseIntf3.Get_NavigationKind(TempResult)) then + Result := TempResult; +end; + +procedure TCoreWebView2NavigationStartingEventArgs.SetAdditionalAllowedFrameAncestors(const aValue : wvstring); +begin + if assigned(FBaseIntf2) then + FBaseIntf2.Set_AdditionalAllowedFrameAncestors(PWideChar(aValue)); +end; + +procedure TCoreWebView2NavigationStartingEventArgs.SetCancel(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_Cancel(ord(aValue)); +end; + + +// TCoreWebView2NewWindowRequestedEventArgs + +constructor TCoreWebView2NewWindowRequestedEventArgs.Create(const aArgs: ICoreWebView2NewWindowRequestedEventArgs); +begin + inherited Create; + + InitializeFields; + + FBaseIntf := aArgs; + + if Initialized and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2NewWindowRequestedEventArgs2, FBaseIntf2) then + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2NewWindowRequestedEventArgs3, FBaseIntf3); +end; + +destructor TCoreWebView2NewWindowRequestedEventArgs.Destroy; +begin + InitializeFields; + + inherited Destroy; +end; + +procedure TCoreWebView2NewWindowRequestedEventArgs.InitializeFields; +begin + FBaseIntf := nil; + FBaseIntf2 := nil; + FBaseIntf3 := nil; +end; + +function TCoreWebView2NewWindowRequestedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2NewWindowRequestedEventArgs.GetURI : wvstring; +var + TempURI : PWideChar; +begin + Result := ''; + TempURI := nil; + + if Initialized and + succeeded(FBaseIntf.Get_uri(TempURI)) and + (TempURI <> nil) then + begin + Result := TempURI; + CoTaskMemFree(TempURI); + end; +end; + +function TCoreWebView2NewWindowRequestedEventArgs.GetNewWindow : ICoreWebView2; +var + TempNewWindow : ICoreWebView2; +begin + Result := nil; + TempNewWindow := nil; + + if Initialized and + succeeded(FBaseIntf.Get_NewWindow(TempNewWindow)) and + (TempNewWindow <> nil) then + Result := TempNewWindow; +end; + +function TCoreWebView2NewWindowRequestedEventArgs.GetHandled : boolean; +var + TempHandled : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_Handled(TempHandled)) and + (TempHandled <> 0); +end; + +function TCoreWebView2NewWindowRequestedEventArgs.GetIsUserInitiated : boolean; +var + TempIsUserInitiated : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_IsUserInitiated(TempIsUserInitiated)) and + (TempIsUserInitiated <> 0); +end; + +function TCoreWebView2NewWindowRequestedEventArgs.GetDeferral : ICoreWebView2Deferral; +var + TempDeferral : ICoreWebView2Deferral; +begin + Result := nil; + TempDeferral := nil; + + if Initialized and + succeeded(FBaseIntf.GetDeferral(TempDeferral)) and + (TempDeferral <> nil) then + Result := TempDeferral; +end; + +function TCoreWebView2NewWindowRequestedEventArgs.GetWindowFeatures : ICoreWebView2WindowFeatures; +var + TempWindowFeatures : ICoreWebView2WindowFeatures; +begin + Result := nil; + TempWindowFeatures := nil; + + if Initialized and + succeeded(FBaseIntf.Get_WindowFeatures(TempWindowFeatures)) and + (TempWindowFeatures <> nil) then + Result := TempWindowFeatures; +end; + +function TCoreWebView2NewWindowRequestedEventArgs.GetName : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if (FBaseIntf2 <> nil) and + succeeded(FBaseIntf2.Get_name(TempString)) and + (TempString <> nil) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2NewWindowRequestedEventArgs.GetOriginalSourceFrameInfo : ICoreWebView2FrameInfo; +var + TempFrameInfo : ICoreWebView2FrameInfo; +begin + Result := nil; + TempFrameInfo := nil; + + if (FBaseIntf3 <> nil) and + succeeded(FBaseIntf3.Get_OriginalSourceFrameInfo(TempFrameInfo)) and + (TempFrameInfo <> nil) then + Result := TempFrameInfo; +end; + +procedure TCoreWebView2NewWindowRequestedEventArgs.SetNewWindow(const aValue : ICoreWebView2); +begin + if Initialized then + FBaseIntf.Set_NewWindow(aValue); +end; + +procedure TCoreWebView2NewWindowRequestedEventArgs.SetHandled(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_Handled(ord(aValue)); +end; + + +// TCoreWebView2PermissionRequestedEventArgs + +constructor TCoreWebView2PermissionRequestedEventArgs.Create(const aArgs: ICoreWebView2PermissionRequestedEventArgs); +begin + inherited Create; + + InitializeFields; + + FBaseIntf := aArgs; + + if assigned(aArgs) and + LoggedQueryInterface(aArgs, IID_ICoreWebView2PermissionRequestedEventArgs2, FBaseIntf2) then + LoggedQueryInterface(aArgs, IID_ICoreWebView2PermissionRequestedEventArgs3, FBaseIntf3); +end; + +constructor TCoreWebView2PermissionRequestedEventArgs.Create(const aArgs: ICoreWebView2PermissionRequestedEventArgs2); +begin + inherited Create; + + InitializeFields; + + FBaseIntf2 := aArgs; + + if assigned(aArgs) and + LoggedQueryInterface(aArgs, IID_ICoreWebView2PermissionRequestedEventArgs, FBaseIntf) then + LoggedQueryInterface(aArgs, IID_ICoreWebView2PermissionRequestedEventArgs3, FBaseIntf3); +end; + +destructor TCoreWebView2PermissionRequestedEventArgs.Destroy; +begin + InitializeFields; + + inherited Destroy; +end; + +procedure TCoreWebView2PermissionRequestedEventArgs.InitializeFields; +begin + FBaseIntf := nil; + FBaseIntf2 := nil; + FBaseIntf3 := nil; +end; + +function TCoreWebView2PermissionRequestedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2PermissionRequestedEventArgs.GetURI : wvstring; +var + TempURI : PWideChar; +begin + Result := ''; + TempURI := nil; + + if Initialized and + succeeded(FBaseIntf.Get_uri(TempURI)) and + (TempURI <> nil) then + begin + Result := TempURI; + CoTaskMemFree(TempURI); + end; +end; + +function TCoreWebView2PermissionRequestedEventArgs.GetState : TWVPermissionState; +var + TempState : COREWEBVIEW2_PERMISSION_STATE; +begin + if Initialized and + succeeded(FBaseIntf.Get_State(TempState)) then + Result := TempState + else + Result := 0; +end; + +function TCoreWebView2PermissionRequestedEventArgs.GetPermissionKind : TWVPermissionKind; +var + TempKind : COREWEBVIEW2_PERMISSION_KIND; +begin + if Initialized and + succeeded(FBaseIntf.Get_PermissionKind(TempKind)) then + Result := TempKind + else + Result := 0; +end; + +function TCoreWebView2PermissionRequestedEventArgs.GetIsUserInitiated : boolean; +var + TempIsUserInitiated : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_IsUserInitiated(TempIsUserInitiated)) and + (TempIsUserInitiated <> 0); +end; + +function TCoreWebView2PermissionRequestedEventArgs.GetDeferral : ICoreWebView2Deferral; +var + TempDeferral : ICoreWebView2Deferral; +begin + Result := nil; + TempDeferral := nil; + + if Initialized and + succeeded(FBaseIntf.GetDeferral(TempDeferral)) and + (TempDeferral <> nil) then + Result := TempDeferral; +end; + +function TCoreWebView2PermissionRequestedEventArgs.GetHandled : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_Handled(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2PermissionRequestedEventArgs.GetSavesInProfile : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf3) and + succeeded(FBaseIntf3.Get_SavesInProfile(TempResult)) and + (TempResult <> 0); +end; + +procedure TCoreWebView2PermissionRequestedEventArgs.SetState(aValue : TWVPermissionState); +begin + if Initialized then + FBaseIntf.Set_State(aValue); +end; + +procedure TCoreWebView2PermissionRequestedEventArgs.SetHandled(aValue : boolean); +begin + if assigned(FBaseIntf2) then + FBaseIntf2.Set_Handled(ord(aValue)); +end; + +procedure TCoreWebView2PermissionRequestedEventArgs.SetSavesInProfile(aValue : boolean); +begin + if assigned(FBaseIntf3) then + FBaseIntf3.Set_SavesInProfile(ord(aValue)); +end; + + +// TCoreWebView2ProcessFailedEventArgs + +constructor TCoreWebView2ProcessFailedEventArgs.Create(const aArgs: ICoreWebView2ProcessFailedEventArgs); +begin + inherited Create; + + InitializeFields; + + FBaseIntf := aArgs; + + if Initialized and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2ProcessFailedEventArgs2, FBaseIntf2) then + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2ProcessFailedEventArgs3, FBaseIntf3); +end; + +destructor TCoreWebView2ProcessFailedEventArgs.Destroy; +begin + InitializeFields; + + inherited Destroy; +end; + +procedure TCoreWebView2ProcessFailedEventArgs.InitializeFields; +begin + FBaseIntf := nil; + FBaseIntf2 := nil; + FBaseIntf3 := nil; +end; + +function TCoreWebView2ProcessFailedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2ProcessFailedEventArgs.GetProcessFailedKind : TWVProcessFailedKind; +var + TempKind : COREWEBVIEW2_PROCESS_FAILED_KIND; +begin + if Initialized and + succeeded(FBaseIntf.Get_ProcessFailedKind(TempKind)) then + Result := TempKind + else + Result := 0; +end; + +function TCoreWebView2ProcessFailedEventArgs.GetReason : TWVProcessFailedReason; +var + TempResult : COREWEBVIEW2_PROCESS_FAILED_REASON; +begin + Result := 0; + TempResult := 0; + + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_reason(TempResult)) then + Result := TempResult; +end; + +function TCoreWebView2ProcessFailedEventArgs.GetExtiCode : integer; +var + TempResult : SYSINT; +begin + Result := 0; + TempResult := 0; + + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_ExitCode(TempResult)) then + Result := TempResult; +end; + +function TCoreWebView2ProcessFailedEventArgs.GetProcessDescription : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_ProcessDescription(TempString)) and + (TempString <> nil) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2ProcessFailedEventArgs.GetFrameInfosForFailedProcess : ICoreWebView2FrameInfoCollection; +var + TempResult : ICoreWebView2FrameInfoCollection; +begin + Result := nil; + TempResult := nil; + + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_FrameInfosForFailedProcess(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +function TCoreWebView2ProcessFailedEventArgs.GetFailureSourceModulePath : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if assigned(FBaseIntf3) and + succeeded(FBaseIntf3.Get_FailureSourceModulePath(TempString)) and + (TempString <> nil) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + + +// TCoreWebView2ScriptDialogOpeningEventArgs + +constructor TCoreWebView2ScriptDialogOpeningEventArgs.Create(const aArgs: ICoreWebView2ScriptDialogOpeningEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2ScriptDialogOpeningEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2ScriptDialogOpeningEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2ScriptDialogOpeningEventArgs.GetURI : wvstring; +var + TempURI : PWideChar; +begin + Result := ''; + TempURI := nil; + + if Initialized and + succeeded(FBaseIntf.Get_uri(TempURI)) and + (TempURI <> nil) then + begin + Result := TempURI; + CoTaskMemFree(TempURI); + end; +end; + +function TCoreWebView2ScriptDialogOpeningEventArgs.GetKind : TWVScriptDialogKind; +var + TempKind : COREWEBVIEW2_SCRIPT_DIALOG_KIND; +begin + if Initialized and + succeeded(FBaseIntf.Get_Kind(TempKind)) then + Result := TempKind + else + Result := 0; +end; + +function TCoreWebView2ScriptDialogOpeningEventArgs.GetMessage : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_Message(TempString)) and + (TempString <> nil) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2ScriptDialogOpeningEventArgs.Accept : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.Accept); +end; + +function TCoreWebView2ScriptDialogOpeningEventArgs.GetDefaultText : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_DefaultText(TempString)) and + (TempString <> nil) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2ScriptDialogOpeningEventArgs.GetResultText : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_ResultText(TempString)) and + (TempString <> nil) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2ScriptDialogOpeningEventArgs.GetDeferral : ICoreWebView2Deferral; +var + TempDeferral : ICoreWebView2Deferral; +begin + Result := nil; + TempDeferral := nil; + + if Initialized and + succeeded(FBaseIntf.GetDeferral(TempDeferral)) and + (TempDeferral <> nil) then + Result := TempDeferral; +end; + +procedure TCoreWebView2ScriptDialogOpeningEventArgs.SetResultText(const aValue : wvstring); +begin + if Initialized then + FBaseIntf.Set_ResultText(PWideChar(aValue)); +end; + + +// TCoreWebView2SourceChangedEventArgs + +constructor TCoreWebView2SourceChangedEventArgs.Create(const aArgs: ICoreWebView2SourceChangedEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2SourceChangedEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2SourceChangedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2SourceChangedEventArgs.GetIsNewDocument : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_IsNewDocument(TempInt)) and + (TempInt <> 0); +end; + + +// TCoreWebView2WebMessageReceivedEventArgs1 + +constructor TCoreWebView2WebMessageReceivedEventArgs.Create(const aArgs: ICoreWebView2WebMessageReceivedEventArgs); +begin + inherited Create; + + InitializeFields; + + FBaseIntf := aArgs; + + if Initialized then + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2WebMessageReceivedEventArgs2, FBaseIntf2); +end; + +destructor TCoreWebView2WebMessageReceivedEventArgs.Destroy; +begin + InitializeFields; + + inherited Destroy; +end; + +procedure TCoreWebView2WebMessageReceivedEventArgs.InitializeFields; +begin + FBaseIntf := nil; + FBaseIntf2 := nil; +end; + +function TCoreWebView2WebMessageReceivedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2WebMessageReceivedEventArgs.GetSource : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_Source(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2WebMessageReceivedEventArgs.GetWebMessageAsJson : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_webMessageAsJson(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2WebMessageReceivedEventArgs.GetWebMessageAsString : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.TryGetWebMessageAsString(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2WebMessageReceivedEventArgs.GetAdditionalObjects : ICoreWebView2ObjectCollectionView; +var + TempCollectionView : ICoreWebView2ObjectCollectionView; +begin + Result := nil; + TempCollectionView := nil; + + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_AdditionalObjects(TempCollectionView)) and + (TempCollectionView <> nil) then + Result := TempCollectionView; +end; + + +// TCoreWebView2WebResourceRequestedEventArgs + +constructor TCoreWebView2WebResourceRequestedEventArgs.Create(const aArgs: ICoreWebView2WebResourceRequestedEventArgs); +begin + inherited Create; + + InitializeFields; + + FBaseIntf := aArgs; + + if Initialized then + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2WebResourceRequestedEventArgs2, FBaseIntf2); +end; + +destructor TCoreWebView2WebResourceRequestedEventArgs.Destroy; +begin + InitializeFields; + + inherited Destroy; +end; + +procedure TCoreWebView2WebResourceRequestedEventArgs.InitializeFields; +begin + FBaseIntf := nil; + FBaseIntf2 := nil; +end; + +function TCoreWebView2WebResourceRequestedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2WebResourceRequestedEventArgs.GetRequest : ICoreWebView2WebResourceRequest; +var + TempRequest : ICoreWebView2WebResourceRequest; +begin + Result := nil; + TempRequest := nil; + + if Initialized and + succeeded(FBaseIntf.Get_Request(TempRequest)) and + (TempRequest <> nil) then + Result := TempRequest; +end; + +function TCoreWebView2WebResourceRequestedEventArgs.GetResponse : ICoreWebView2WebResourceResponse; +var + TempResponse : ICoreWebView2WebResourceResponse; +begin + Result := nil; + TempResponse := nil; + + if Initialized and + succeeded(FBaseIntf.Get_Response(TempResponse)) and + (TempResponse <> nil) then + Result := TempResponse; +end; + +function TCoreWebView2WebResourceRequestedEventArgs.GetDeferral : ICoreWebView2Deferral; +var + TempDeferral : ICoreWebView2Deferral; +begin + Result := nil; + TempDeferral := nil; + + if Initialized and + succeeded(FBaseIntf.GetDeferral(TempDeferral)) and + (TempDeferral <> nil) then + Result := TempDeferral; +end; + +function TCoreWebView2WebResourceRequestedEventArgs.GetResourceContext : TWVWebResourceContext; +var + TempContext : COREWEBVIEW2_WEB_RESOURCE_CONTEXT; +begin + if Initialized and + succeeded(FBaseIntf.Get_ResourceContext(TempContext)) then + Result := TempContext + else + Result := COREWEBVIEW2_WEB_RESOURCE_CONTEXT_ALL; +end; + +function TCoreWebView2WebResourceRequestedEventArgs.GetRequestedSourceKind : TWVWebResourceRequestSourceKind; +var + TempResult : COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS; +begin + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_RequestedSourceKind(TempResult)) then + Result := TempResult + else + Result := COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_NONE; +end; + +procedure TCoreWebView2WebResourceRequestedEventArgs.SetResponse(const aValue : ICoreWebView2WebResourceResponse); +begin + if Initialized then + FBaseIntf.Set_Response(aValue); +end; + + +// TCoreWebView2BrowserProcessExitedEventArgs + +constructor TCoreWebView2BrowserProcessExitedEventArgs.Create(const aArgs: ICoreWebView2BrowserProcessExitedEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2BrowserProcessExitedEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2BrowserProcessExitedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2BrowserProcessExitedEventArgs.GetBrowserProcessExitKind : TWVBrowserProcessExitKind; +var + TempResult : COREWEBVIEW2_BROWSER_PROCESS_EXIT_KIND; +begin + if Initialized and + succeeded(FBaseIntf.Get_BrowserProcessExitKind(TempResult)) then + Result := TempResult + else + Result := 0; +end; + +function TCoreWebView2BrowserProcessExitedEventArgs.GetBrowserProcessId : cardinal; +var + TempResult : SYSUINT; +begin + if Initialized and + succeeded(FBaseIntf.Get_BrowserProcessId(TempResult)) then + Result := TempResult + else + Result := 0; +end; + + +// TCoreWebView2WebResourceResponseReceivedEventArgs + +constructor TCoreWebView2WebResourceResponseReceivedEventArgs.Create(const aArgs: ICoreWebView2WebResourceResponseReceivedEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2WebResourceResponseReceivedEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2WebResourceResponseReceivedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2WebResourceResponseReceivedEventArgs.GetRequest : ICoreWebView2WebResourceRequest; +var + TempRequest : ICoreWebView2WebResourceRequest; +begin + Result := nil; + TempRequest := nil; + + if Initialized and + succeeded(FBaseIntf.Get_Request(TempRequest)) and + (TempRequest <> nil) then + Result := TempRequest; +end; + +function TCoreWebView2WebResourceResponseReceivedEventArgs.GetResponse : ICoreWebView2WebResourceResponseView; +var + TempResponse : ICoreWebView2WebResourceResponseView; +begin + Result := nil; + TempResponse := nil; + + if Initialized and + succeeded(FBaseIntf.Get_Response(TempResponse)) and + (TempResponse <> nil) then + Result := TempResponse; +end; + + +// TCoreWebView2DOMContentLoadedEventArgs + +constructor TCoreWebView2DOMContentLoadedEventArgs.Create(const aArgs: ICoreWebView2DOMContentLoadedEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2DOMContentLoadedEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2DOMContentLoadedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2DOMContentLoadedEventArgs.GetNavigationID : uint64; +var + TempID : Largeuint; +begin + if Initialized and succeeded(FBaseIntf.Get_NavigationId(TempID)) then + Result := uint64(TempID) + else + Result := 0; +end; + + +// TCoreWebView2FrameCreatedEventArgs + +constructor TCoreWebView2FrameCreatedEventArgs.Create(const aArgs: ICoreWebView2FrameCreatedEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2FrameCreatedEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2FrameCreatedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2FrameCreatedEventArgs.GetFrame : ICoreWebView2Frame; +var + TempResult : ICoreWebView2Frame; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_Frame(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + + +// TCoreWebView2DownloadStartingEventArgs + +constructor TCoreWebView2DownloadStartingEventArgs.Create(const aArgs: ICoreWebView2DownloadStartingEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2DownloadStartingEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2DownloadStartingEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2DownloadStartingEventArgs.GetDownloadOperation : ICoreWebView2DownloadOperation; +var + TempResult : ICoreWebView2DownloadOperation; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_DownloadOperation(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +function TCoreWebView2DownloadStartingEventArgs.GetCancel : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_Cancel(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2DownloadStartingEventArgs.GetResultFilePath : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_ResultFilePath(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2DownloadStartingEventArgs.GetHandled : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_Handled(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2DownloadStartingEventArgs.GetDeferral : ICoreWebView2Deferral; +var + TempResult : ICoreWebView2Deferral; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.GetDeferral(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +procedure TCoreWebView2DownloadStartingEventArgs.SetCancel(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_Cancel(ord(aValue)); +end; + +procedure TCoreWebView2DownloadStartingEventArgs.SetResultFilePath(const aValue : wvstring); +begin + if Initialized then + FBaseIntf.Set_ResultFilePath(PWideChar(aValue)); +end; + +procedure TCoreWebView2DownloadStartingEventArgs.SetHandled(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_Handled(ord(aValue)); +end; + + +// TCoreWebView2ClientCertificateRequestedEventArgs + +constructor TCoreWebView2ClientCertificateRequestedEventArgs.Create(const aArgs: ICoreWebView2ClientCertificateRequestedEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2ClientCertificateRequestedEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2ClientCertificateRequestedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2ClientCertificateRequestedEventArgs.GetHost : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_Host(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2ClientCertificateRequestedEventArgs.GetPort : integer; +var + TempPort : Integer; +begin + if Initialized and succeeded(FBaseIntf.Get_Port(TempPort)) then + Result := TempPort + else + Result := 0; +end; + +function TCoreWebView2ClientCertificateRequestedEventArgs.GetIsProxy : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_IsProxy(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2ClientCertificateRequestedEventArgs.GetAllowedCertificateAuthorities : ICoreWebView2StringCollection; +var + TempResult : ICoreWebView2StringCollection; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_AllowedCertificateAuthorities(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +function TCoreWebView2ClientCertificateRequestedEventArgs.GetMutuallyTrustedCertificates : ICoreWebView2ClientCertificateCollection; +var + TempResult : ICoreWebView2ClientCertificateCollection; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_MutuallyTrustedCertificates(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +function TCoreWebView2ClientCertificateRequestedEventArgs.GetSelectedCertificate : ICoreWebView2ClientCertificate; +var + TempResult : ICoreWebView2ClientCertificate; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_SelectedCertificate(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +function TCoreWebView2ClientCertificateRequestedEventArgs.GetCancel : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_Cancel(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2ClientCertificateRequestedEventArgs.GetHandled : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_Handled(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2ClientCertificateRequestedEventArgs.GetDeferral : ICoreWebView2Deferral; +var + TempResult : ICoreWebView2Deferral; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.GetDeferral(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +procedure TCoreWebView2ClientCertificateRequestedEventArgs.SetSelectedCertificate(const aValue : ICoreWebView2ClientCertificate); +begin + if Initialized then + FBaseIntf.Set_SelectedCertificate(aValue); +end; + +procedure TCoreWebView2ClientCertificateRequestedEventArgs.SetCancel(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_Cancel(ord(aValue)); +end; + +procedure TCoreWebView2ClientCertificateRequestedEventArgs.SetHandled(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_Handled(ord(aValue)); +end; + + +// TCoreWebView2BasicAuthenticationRequestedEventArgs + +constructor TCoreWebView2BasicAuthenticationRequestedEventArgs.Create(const aArgs: ICoreWebView2BasicAuthenticationRequestedEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2BasicAuthenticationRequestedEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2BasicAuthenticationRequestedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2BasicAuthenticationRequestedEventArgs.GetUri : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_uri(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2BasicAuthenticationRequestedEventArgs.GetChallenge : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_Challenge(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2BasicAuthenticationRequestedEventArgs.GetResponse : ICoreWebView2BasicAuthenticationResponse; +var + TempResult : ICoreWebView2BasicAuthenticationResponse; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_Response(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +function TCoreWebView2BasicAuthenticationRequestedEventArgs.GetCancel : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_Cancel(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2BasicAuthenticationRequestedEventArgs.GetDeferral : ICoreWebView2Deferral; +var + TempResult : ICoreWebView2Deferral; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.GetDeferral(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +procedure TCoreWebView2BasicAuthenticationRequestedEventArgs.SetCancel(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_Cancel(ord(aValue)); +end; + + +// TCoreWebView2ContextMenuRequestedEventArgs + +constructor TCoreWebView2ContextMenuRequestedEventArgs.Create(const aArgs: ICoreWebView2ContextMenuRequestedEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2ContextMenuRequestedEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2ContextMenuRequestedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2ContextMenuRequestedEventArgs.GetMenuItems : ICoreWebView2ContextMenuItemCollection; +var + TempResult : ICoreWebView2ContextMenuItemCollection; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_MenuItems(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +function TCoreWebView2ContextMenuRequestedEventArgs.GetContextMenuTarget : ICoreWebView2ContextMenuTarget; +var + TempResult : ICoreWebView2ContextMenuTarget; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_ContextMenuTarget(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +{$WARN SYMBOL_DEPRECATED OFF} +function TCoreWebView2ContextMenuRequestedEventArgs.GetLocation : TPoint; +var + TempResult : tagPOINT; // ICoreWebView2ContextMenuRequestedEventArgs uses tagPoint. We ignore the warning. +begin + Result.x := low(integer); + Result.y := low(integer); + + if Initialized and + succeeded(FBaseIntf.Get_Location(TempResult)) then + begin + Result.x := TempResult.x; + Result.y := TempResult.y; + end; +end; +{$WARN SYMBOL_DEPRECATED ON} + +function TCoreWebView2ContextMenuRequestedEventArgs.GetSelectedCommandId : Integer; +var + TempResult : integer; +begin + Result := -1; + TempResult := -1; + + if Initialized and + succeeded(FBaseIntf.Get_SelectedCommandId(TempResult)) then + Result := TempResult; +end; + +function TCoreWebView2ContextMenuRequestedEventArgs.GetHandled : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_Handled(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2ContextMenuRequestedEventArgs.GetDeferral : ICoreWebView2Deferral; +var + TempResult : ICoreWebView2Deferral; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.GetDeferral(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +procedure TCoreWebView2ContextMenuRequestedEventArgs.SetSelectedCommandId(aValue: Integer); +begin + if Initialized then + FBaseIntf.Set_SelectedCommandId(aValue); +end; + +procedure TCoreWebView2ContextMenuRequestedEventArgs.SetHandled(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_Handled(ord(aValue)); +end; + + +// TCoreWebView2ServerCertificateErrorDetectedEventArgs + +constructor TCoreWebView2ServerCertificateErrorDetectedEventArgs.Create(const aArgs: ICoreWebView2ServerCertificateErrorDetectedEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2ServerCertificateErrorDetectedEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2ServerCertificateErrorDetectedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2ServerCertificateErrorDetectedEventArgs.GetErrorStatus : TWVWebErrorStatus; +var + TempResult : COREWEBVIEW2_WEB_ERROR_STATUS; +begin + Result := 0; + + if Initialized and + succeeded(FBaseIntf.Get_ErrorStatus(TempResult)) then + Result := TempResult; +end; + +function TCoreWebView2ServerCertificateErrorDetectedEventArgs.GetRequestUri : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_RequestUri(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2ServerCertificateErrorDetectedEventArgs.GetServerCertificate : ICoreWebView2Certificate; +var + TempResult : ICoreWebView2Certificate; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_ServerCertificate(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +function TCoreWebView2ServerCertificateErrorDetectedEventArgs.GetAction : TWVServerCertificateErrorAction; +var + TempResult : COREWEBVIEW2_SERVER_CERTIFICATE_ERROR_ACTION; +begin + Result := 0; + + if Initialized and + succeeded(FBaseIntf.Get_Action(TempResult)) then + Result := TempResult; +end; + +function TCoreWebView2ServerCertificateErrorDetectedEventArgs.GetDeferral : ICoreWebView2Deferral; +var + TempResult : ICoreWebView2Deferral; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.GetDeferral(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +procedure TCoreWebView2ServerCertificateErrorDetectedEventArgs.SetAction(aValue: TWVServerCertificateErrorAction); +begin + if Initialized then + FBaseIntf.Set_Action(aValue); +end; + + +// TCoreWebView2LaunchingExternalUriSchemeEventArgs + +constructor TCoreWebView2LaunchingExternalUriSchemeEventArgs.Create(const aArgs: ICoreWebView2LaunchingExternalUriSchemeEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2LaunchingExternalUriSchemeEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2LaunchingExternalUriSchemeEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2LaunchingExternalUriSchemeEventArgs.GetUri : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_Uri(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2LaunchingExternalUriSchemeEventArgs.GetInitiatingOrigin : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_InitiatingOrigin(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2LaunchingExternalUriSchemeEventArgs.GetIsUserInitiated: boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_IsUserInitiated(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2LaunchingExternalUriSchemeEventArgs.GetCancel: boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_Cancel(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2LaunchingExternalUriSchemeEventArgs.GetDeferral: ICoreWebView2Deferral; +var + TempResult : ICoreWebView2Deferral; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.GetDeferral(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +procedure TCoreWebView2LaunchingExternalUriSchemeEventArgs.SetCancel(aValue: boolean); +begin + if Initialized then + FBaseIntf.Set_Cancel(ord(aValue)); +end; + + +// TCoreWebView2NonClientRegionChangedEventArgs + +constructor TCoreWebView2NonClientRegionChangedEventArgs.Create(const aArgs: ICoreWebView2NonClientRegionChangedEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2NonClientRegionChangedEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2NonClientRegionChangedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2NonClientRegionChangedEventArgs.GetRegionKind : TWVNonClientRegionKind; +var + TempResult : COREWEBVIEW2_NON_CLIENT_REGION_KIND; +begin + Result := COREWEBVIEW2_NON_CLIENT_REGION_KIND_NOWHERE; + + if Initialized and + succeeded(FBaseIntf.Get_RegionKind(TempResult)) then + Result := TempResult; +end; + + +// TCoreWebView2NotificationReceivedEventArgs + +constructor TCoreWebView2NotificationReceivedEventArgs.Create(const aArgs: ICoreWebView2NotificationReceivedEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2NotificationReceivedEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2NotificationReceivedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2NotificationReceivedEventArgs.GetSenderOrigin : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_SenderOrigin(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2NotificationReceivedEventArgs.GetNotification : ICoreWebView2Notification; +var + TempResult : ICoreWebView2Notification; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_Notification(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +function TCoreWebView2NotificationReceivedEventArgs.GetHandled : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_Handled(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2NotificationReceivedEventArgs.GetDeferral : ICoreWebView2Deferral; +var + TempResult : ICoreWebView2Deferral; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.GetDeferral(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +procedure TCoreWebView2NotificationReceivedEventArgs.SetHandled(aValue: boolean); +begin + if Initialized then + FBaseIntf.Set_Handled(ord(aValue)); +end; + + +// TCoreWebView2SaveAsUIShowingEventArgs + +constructor TCoreWebView2SaveAsUIShowingEventArgs.Create(const aArgs: ICoreWebView2SaveAsUIShowingEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2SaveAsUIShowingEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2SaveAsUIShowingEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2SaveAsUIShowingEventArgs.GetContentMimeType : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_ContentMimeType(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2SaveAsUIShowingEventArgs.GetCancel : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_Cancel(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2SaveAsUIShowingEventArgs.GetSuppressDefaultDialog : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_SuppressDefaultDialog(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2SaveAsUIShowingEventArgs.GetDeferral : ICoreWebView2Deferral; +var + TempResult : ICoreWebView2Deferral; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.GetDeferral(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +function TCoreWebView2SaveAsUIShowingEventArgs.GetSaveAsFilePath : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_SaveAsFilePath(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2SaveAsUIShowingEventArgs.GetAllowReplace : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_AllowReplace(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2SaveAsUIShowingEventArgs.GetKind : TWVSaveAsKind; +var + TempResult : COREWEBVIEW2_SAVE_AS_KIND; +begin + Result := COREWEBVIEW2_SAVE_AS_KIND_DEFAULT; + + if Initialized and + succeeded(FBaseIntf.Get_Kind(TempResult)) then + Result := TempResult; +end; + +procedure TCoreWebView2SaveAsUIShowingEventArgs.SetCancel(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_Cancel(ord(aValue)); +end; + +procedure TCoreWebView2SaveAsUIShowingEventArgs.SetSuppressDefaultDialog(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_SuppressDefaultDialog(ord(aValue)); +end; + +procedure TCoreWebView2SaveAsUIShowingEventArgs.SetSaveAsFilePath(const aValue : wvstring); +begin + if Initialized then + FBaseIntf.Set_SaveAsFilePath(PWideChar(aValue)); +end; + +procedure TCoreWebView2SaveAsUIShowingEventArgs.SetAllowReplace(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_AllowReplace(ord(aValue)); +end; + +procedure TCoreWebView2SaveAsUIShowingEventArgs.SetKind(aValue : TWVSaveAsKind); +begin + if Initialized then + FBaseIntf.Set_Kind(aValue); +end; + + +// TCoreWebView2SaveFileSecurityCheckStartingEventArgs + +constructor TCoreWebView2SaveFileSecurityCheckStartingEventArgs.Create(const aArgs: ICoreWebView2SaveFileSecurityCheckStartingEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2SaveFileSecurityCheckStartingEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2SaveFileSecurityCheckStartingEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2SaveFileSecurityCheckStartingEventArgs.GetCancelSave : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_CancelSave(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2SaveFileSecurityCheckStartingEventArgs.GetDocumentOriginUri : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_DocumentOriginUri(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2SaveFileSecurityCheckStartingEventArgs.GetFileExtension : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_FileExtension(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2SaveFileSecurityCheckStartingEventArgs.GetFilePath : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_FilePath(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2SaveFileSecurityCheckStartingEventArgs.GetSuppressDefaultPolicy : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_SuppressDefaultPolicy(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2SaveFileSecurityCheckStartingEventArgs.GetDeferral : ICoreWebView2Deferral; +var + TempResult : ICoreWebView2Deferral; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.GetDeferral(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +procedure TCoreWebView2SaveFileSecurityCheckStartingEventArgs.SetCancelSave(aValue: boolean); +begin + if Initialized then + FBaseIntf.Set_CancelSave(ord(aValue)); +end; + +procedure TCoreWebView2SaveFileSecurityCheckStartingEventArgs.SetSuppressDefaultPolicy(aValue: boolean); +begin + if Initialized then + FBaseIntf.Set_SuppressDefaultPolicy(ord(aValue)); +end; + + +// TCoreWebView2ScreenCaptureStartingEventArgs + +constructor TCoreWebView2ScreenCaptureStartingEventArgs.Create(const aArgs: ICoreWebView2ScreenCaptureStartingEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2ScreenCaptureStartingEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2ScreenCaptureStartingEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2ScreenCaptureStartingEventArgs.GetCancel : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_Cancel(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2ScreenCaptureStartingEventArgs.GetHandled : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_Handled(TempInt)) and + (TempInt <> 0); +end; + +function TCoreWebView2ScreenCaptureStartingEventArgs.GetCoreWebView2FrameInfo : ICoreWebView2FrameInfo; +var + TempResult : ICoreWebView2FrameInfo; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_OriginalSourceFrameInfo(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +function TCoreWebView2ScreenCaptureStartingEventArgs.GetDeferral : ICoreWebView2Deferral; +var + TempResult : ICoreWebView2Deferral; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.GetDeferral(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +procedure TCoreWebView2ScreenCaptureStartingEventArgs.SetCancel(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_Cancel(ord(aValue)); +end; + +procedure TCoreWebView2ScreenCaptureStartingEventArgs.SetHandled(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_Handled(ord(aValue)); +end; + + +// TCoreWebView2DragStartingEventArgs + +constructor TCoreWebView2DragStartingEventArgs.Create(const aArgs: ICoreWebView2DragStartingEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2DragStartingEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2DragStartingEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2DragStartingEventArgs.GetAllowedDropEffects : cardinal; +var + TempResult : LongWord; +begin + if Initialized and + succeeded(FBaseIntf.Get_AllowedDropEffects(TempResult)) then + Result := TempResult + else + Result := DROPEFFECT_NONE; +end; + +function TCoreWebView2DragStartingEventArgs.GetData : IDataObject; +var + TempResult : IDataObject; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_Data(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +function TCoreWebView2DragStartingEventArgs.GetHandled : boolean; +var + TempInt : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_Handled(TempInt)) and + (TempInt <> 0); +end; + +{$WARN SYMBOL_DEPRECATED OFF} +function TCoreWebView2DragStartingEventArgs.GetPosition : TPoint; +var + TempResult : tagPOINT; // ICoreWebView2DragStartingEventArgs uses tagPoint. We ignore the warning. +begin + if Initialized and + succeeded(FBaseIntf.Get_Position(TempResult)) then + Result := TPoint(TempResult) + else + Result := point(0, 0); +end; +{$WARN SYMBOL_DEPRECATED ON} + +function TCoreWebView2DragStartingEventArgs.GetDeferral : ICoreWebView2Deferral; +var + TempResult : ICoreWebView2Deferral; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.GetDeferral(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +procedure TCoreWebView2DragStartingEventArgs.SetHandled(aValue: boolean); +begin + if Initialized then + FBaseIntf.Set_Handled(ord(aValue)); +end; + + +// TCoreWebView2DedicatedWorkerCreatedEventArgs + +constructor TCoreWebView2DedicatedWorkerCreatedEventArgs.Create(const aArgs: ICoreWebView2DedicatedWorkerCreatedEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2DedicatedWorkerCreatedEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2DedicatedWorkerCreatedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2DedicatedWorkerCreatedEventArgs.GetOriginalSourceFrameInfo : ICoreWebView2FrameInfo; +var + TempResult : ICoreWebView2FrameInfo; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_OriginalSourceFrameInfo(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +function TCoreWebView2DedicatedWorkerCreatedEventArgs.GetWorker : ICoreWebView2DedicatedWorker; +var + TempResult : ICoreWebView2DedicatedWorker; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_Worker(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + + +// TCoreWebView2ServiceWorkerRegisteredEventArgs + +constructor TCoreWebView2ServiceWorkerRegisteredEventArgs.Create(const aArgs: ICoreWebView2ServiceWorkerRegisteredEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2ServiceWorkerRegisteredEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2ServiceWorkerRegisteredEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2ServiceWorkerRegisteredEventArgs.GetServiceWorkerRegistration : ICoreWebView2ServiceWorkerRegistration; +var + TempResult : ICoreWebView2ServiceWorkerRegistration; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_ServiceWorkerRegistration(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + + +// TCoreWebView2ServiceWorkerActivatedEventArgs + +constructor TCoreWebView2ServiceWorkerActivatedEventArgs.Create(const aArgs: ICoreWebView2ServiceWorkerActivatedEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2ServiceWorkerActivatedEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2ServiceWorkerActivatedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2ServiceWorkerActivatedEventArgs.GetActiveServiceWorker : ICoreWebView2ServiceWorker; +var + TempResult : ICoreWebView2ServiceWorker; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_ActiveServiceWorker(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + + +// TCoreWebView2SharedWorkerCreatedEventArgs + +constructor TCoreWebView2SharedWorkerCreatedEventArgs.Create(const aArgs: ICoreWebView2SharedWorkerCreatedEventArgs); +begin + inherited Create; + + FBaseIntf := aArgs; +end; + +destructor TCoreWebView2SharedWorkerCreatedEventArgs.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2SharedWorkerCreatedEventArgs.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2SharedWorkerCreatedEventArgs.GetWorker : ICoreWebView2SharedWorker; +var + TempResult : ICoreWebView2SharedWorker; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_Worker(TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + + + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2CompositionController.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2CompositionController.pas new file mode 100644 index 000000000..12696c33b --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2CompositionController.pas @@ -0,0 +1,502 @@ +unit uRESTDWPrivWVCoreWebView2CompositionController; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + System.Classes, System.Types, Winapi.Windows, Winapi.ActiveX, + {$ELSE} + Classes, Windows, ActiveX, + {$ENDIF} + uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVTypes; + +type + /// + /// This interface is an extension of the ICoreWebView2Controller interface to + /// support visual hosting. An object implementing the + /// ICoreWebView2CompositionController interface will also implement + /// ICoreWebView2Controller. Callers are expected to use + /// ICoreWebView2Controller for resizing, visibility, focus, and so on, and + /// then use ICoreWebView2CompositionController to connect to a composition + /// tree and provide input meant for the WebView. + /// + /// + /// See the ICoreWebView2CompositionController article. + /// + TCoreWebView2CompositionController = class + protected + FBaseIntf : ICoreWebView2CompositionController; + FBaseIntf2 : ICoreWebView2CompositionController2; + FBaseIntf3 : ICoreWebView2CompositionController3; + FBaseIntf4 : ICoreWebView2CompositionController4; + FBaseIntf5 : ICoreWebView2CompositionController5; + + FCursorChangedToken : EventRegistrationToken; + FNonClientRegionChanged : EventRegistrationToken; + FDragStartingToken : EventRegistrationToken; + + function GetInitialized : boolean; + function GetRootVisualTarget : IUnknown; + function GetCursor : HCURSOR; + function GetSystemCursorID : cardinal; + function GetAutomationProvider : IUnknown; + + procedure SetRootVisualTarget(const aValue : IUnknown); + + procedure InitializeFields; + procedure InitializeTokens; + procedure RemoveAllEvents; + + function AddCursorChangedEvent(const aBrowserComponent : TComponent) : boolean; + function AddNonClientRegionChangedEvent(const aBrowserComponent : TComponent) : boolean; + function AddDragStartingEvent(const aBrowserComponent : TComponent) : boolean; + + public + constructor Create(const aBaseIntf : ICoreWebView2CompositionController); reintroduce; + destructor Destroy; override; + /// + /// Adds all the events of this class to an existing TWVBrowserBase instance. + /// + /// The TWVBrowserBase instance. + function AddAllBrowserEvents(const aBrowserComponent : TComponent) : boolean; + /// + /// If eventKind is COREWEBVIEW2_MOUSE_EVENT_KIND_HORIZONTAL_WHEEL or + /// COREWEBVIEW2_MOUSE_EVENT_KIND_WHEEL, then mouseData specifies the amount of + /// wheel movement. A positive value indicates that the wheel was rotated + /// forward, away from the user; a negative value indicates that the wheel was + /// rotated backward, toward the user. One wheel click is defined as + /// WHEEL_DELTA, which is 120. + /// If eventKind is COREWEBVIEW2_MOUSE_EVENT_KIND_X_BUTTON_DOUBLE_CLICK + /// COREWEBVIEW2_MOUSE_EVENT_KIND_X_BUTTON_DOWN, or + /// COREWEBVIEW2_MOUSE_EVENT_KIND_X_BUTTON_UP, then mouseData specifies which X + /// buttons were pressed or released. This value should be 1 if the first X + /// button is pressed/released and 2 if the second X button is + /// pressed/released. + /// If eventKind is COREWEBVIEW2_MOUSE_EVENT_KIND_LEAVE, then virtualKeys, + /// mouseData, and point should all be zero. + /// If eventKind is any other value, then mouseData should be zero. + /// Point is expected to be in the client coordinate space of the WebView. + /// To track mouse events that start in the WebView and can potentially move + /// outside of the WebView and host application, calling SetCapture and + /// ReleaseCapture is recommended. + /// To dismiss hover popups, it is also recommended to send + /// COREWEBVIEW2_MOUSE_EVENT_KIND_LEAVE messages. + /// + function SendMouseInput(aEventKind : TWVMouseEventKind; aVirtualKeys : TWVMouseEventVirtualKeys; aMouseData : cardinal; aPoint : TPoint) : boolean; + /// + /// SendPointerInput accepts touch or pen pointer input of types defined in + /// COREWEBVIEW2_POINTER_EVENT_KIND. Any pointer input from the system must be + /// converted into an ICoreWebView2PointerInfo first. + /// + function SendPointerInput(aEventKind : TWVPointerEventKind; const aPointerInfo : ICoreWebView2PointerInfo) : boolean; + /// + /// This function corresponds to [IDropTarget::DragEnter](/windows/win32/api/oleidl/nf-oleidl-idroptarget-dragenter). + /// + /// This function has a dependency on AllowExternalDrop property of + /// CoreWebView2Controller and return E_FAIL to callers to indicate this + /// operation is not allowed if AllowExternalDrop property is set to false. + /// + /// The hosting application must register as an IDropTarget and implement + /// and forward DragEnter calls to this function. + /// + /// point parameter must be modified to include the WebView's offset and be in + /// the WebView's client coordinates (Similar to how SendMouseInput works). + /// + function DragEnter(const dataObject: IDataObject; keyState: LongWord; point: tagPOINT; out effect: LongWord) : HResult; + /// + /// This function corresponds to [IDropTarget::DragLeave](/windows/win32/api/oleidl/nf-oleidl-idroptarget-dragleave). + /// + /// This function has a dependency on AllowExternalDrop property of + /// CoreWebView2Controller and return E_FAIL to callers to indicate this + /// operation is not allowed if AllowExternalDrop property is set to false. + /// + /// The hosting application must register as an IDropTarget and implement + /// and forward DragLeave calls to this function. + /// + function DragLeave : HResult; + /// + /// This function corresponds to [IDropTarget::DragOver](/windows/win32/api/oleidl/nf-oleidl-idroptarget-dragover). + /// + /// This function has a dependency on AllowExternalDrop property of + /// CoreWebView2Controller and return E_FAIL to callers to indicate this + /// operation is not allowed if AllowExternalDrop property is set to false. + /// + /// The hosting application must register as an IDropTarget and implement + /// and forward DragOver calls to this function. + /// + /// point parameter must be modified to include the WebView's offset and be in + /// the WebView's client coordinates (Similar to how SendMouseInput works). + /// + function DragOver(keyState: LongWord; point: tagPOINT; out effect: LongWord) : HResult; + /// + /// This function corresponds to [IDropTarget::Drop](/windows/win32/api/oleidl/nf-oleidl-idroptarget-drop). + /// + /// This function has a dependency on AllowExternalDrop property of + /// CoreWebView2Controller and return E_FAIL to callers to indicate this + /// operation is not allowed if AllowExternalDrop property is set to false. + /// + /// The hosting application must register as an IDropTarget and implement + /// and forward Drop calls to this function. + /// + /// point parameter must be modified to include the WebView's offset and be in + /// the WebView's client coordinates (Similar to how SendMouseInput works). + /// + function Drop(const dataObject: IDataObject; keyState: LongWord; point: tagPOINT; out effect: LongWord) : HResult; + /// + /// If you are hosting a WebView2 using CoreWebView2CompositionController, you can call + /// this method in your Win32 WndProc to determine if the mouse is moving over or + /// clicking on WebView2 web content that should be considered part of a non-client region. + + /// The point parameter is expected to be in the client coordinate space of WebView2. + /// The method sets the out parameter value as follows: + /// - COREWEBVIEW2_NON_CLIENT_REGION_KIND_CAPTION when point corresponds to + /// a region (HTML element) within the WebView2 with + /// `-webkit-app-region: drag` CSS style set. + /// - COREWEBVIEW2_NON_CLIENT_REGION_KIND_CLIENT when point corresponds to + /// a region (HTML element) within the WebView2 without + /// `-webkit-app-region: drag` CSS style set. + /// - COREWEBVIEW2_NON_CLIENT_REGION_KIND_NOWHERE when point is not within the WebView2. + /// + /// NOTE: in order for WebView2 to properly handle the title bar system menu, + /// the app needs to send WM_NCRBUTTONDOWN and WM_NCRBUTTONUP to SendMouseInput. + /// See sample code below. + /// \snippet ViewComponent.cpp DraggableRegions2 + /// + /// \snippet ViewComponent.cpp DraggableRegions1 + /// + function GetNonClientRegionAtPoint(point: TPoint) : TWVNonClientRegionKind; + /// + /// This method is used to get the collection of rects that correspond + /// to a particular COREWEBVIEW2_NON_CLIENT_REGION_KIND. This is to be used in + /// the callback of add_NonClientRegionChanged whose event args object contains + /// a region property of type COREWEBVIEW2_NON_CLIENT_REGION_KIND. + /// + /// \snippet ScenarioNonClientRegionSupport.cpp AddChangeListener + /// + function QueryNonClientRegion(Kind: TWVNonClientRegionKind): ICoreWebView2RegionRectCollectionView; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2CompositionController read FBaseIntf; + /// + /// The RootVisualTarget is a visual in the hosting app's visual tree. This + /// visual is where the WebView will connect its visual tree. The app uses + /// this visual to position the WebView within the app. The app still needs + /// to use the Bounds property to size the WebView. The RootVisualTarget + /// property can be an IDCompositionVisual or a + /// Windows::UI::Composition::ContainerVisual. WebView will connect its visual + /// tree to the provided visual before returning from the property setter. The + /// app needs to commit on its device setting the RootVisualTarget property. + /// The RootVisualTarget property supports being set to nullptr to disconnect + /// the WebView from the app's visual tree. + /// + /// + /// See the ICoreWebView2CompositionController article. + /// + property RootVisualTarget : IUnknown read GetRootVisualTarget write SetRootVisualTarget; + /// + /// The current cursor that WebView thinks it should be. The cursor should be + /// set in WM_SETCURSOR through \::SetCursor or set on the corresponding + /// parent/ancestor HWND of the WebView through \::SetClassLongPtr. The HCURSOR + /// can be freed so CopyCursor/DestroyCursor is recommended to keep your own + /// copy if you are doing more than immediately setting the cursor. + /// + /// + /// See the ICoreWebView2CompositionController article. + /// + property Cursor : HCURSOR read GetCursor; + /// + /// The current system cursor ID reported by the underlying rendering engine + /// for WebView. For example, most of the time, when the cursor is over text, + /// this will return the int value for IDC_IBEAM. The systemCursorId is only + /// valid if the rendering engine reports a default Windows cursor resource + /// value. Navigate to + /// [LoadCursorW](/windows/win32/api/winuser/nf-winuser-loadcursorw) for more + /// details. Otherwise, if custom CSS cursors are being used, this will return + /// 0. To actually use systemCursorId in LoadCursor or LoadImage, + /// MAKEINTRESOURCE must be called on it first. + /// + /// + /// See the ICoreWebView2CompositionController article. + /// + property SystemCursorID : cardinal read GetSystemCursorID; + /// + /// Returns the Automation Provider for the WebView. This object implements + /// IRawElementProviderSimple. + /// + /// + /// See the ICoreWebView2CompositionController2 article. + /// + property AutomationProvider : IUnknown read GetAutomationProvider; + end; + +implementation + +uses + uRESTDWPrivWVMiscFunctions, uRESTDWPrivWVBrowserBase, uRESTDWPrivWVCoreWebView2Delegates; + +constructor TCoreWebView2CompositionController.Create(const aBaseIntf: ICoreWebView2CompositionController); +begin + inherited Create; + + InitializeFields; + + FBaseIntf := aBaseIntf; + + if Initialized and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2CompositionController2, FBaseIntf2) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2CompositionController3, FBaseIntf3) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2CompositionController4, FBaseIntf4) then + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2CompositionController5, FBaseIntf5); +end; + +destructor TCoreWebView2CompositionController.Destroy; +begin + try + RemoveAllEvents; + InitializeFields; + finally + inherited Destroy; + end; +end; + +procedure TCoreWebView2CompositionController.InitializeFields; +begin + FBaseIntf := nil; + FBaseIntf2 := nil; + FBaseIntf3 := nil; + FBaseIntf4 := nil; + FBaseIntf5 := nil; + + InitializeTokens; +end; + +procedure TCoreWebView2CompositionController.InitializeTokens; +begin + FCursorChangedToken.value := 0; + FNonClientRegionChanged.value := 0; + FDragStartingToken.value := 0; +end; + +function TCoreWebView2CompositionController.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2CompositionController.GetRootVisualTarget : IUnknown; +var + TempResult : IUnknown; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_RootVisualTarget(TempResult)) and + assigned(TempResult) then + Result := TempResult; +end; + +function TCoreWebView2CompositionController.GetCursor : HCURSOR; +var + TempResult : HCURSOR; +begin + if Initialized and + succeeded(FBaseIntf.Get_Cursor(TempResult)) then + Result := TempResult + else + Result := 0; +end; + +function TCoreWebView2CompositionController.GetSystemCursorID : cardinal; +var + TempResult : SYSUINT; +begin + if Initialized and + succeeded(FBaseIntf.Get_SystemCursorId(TempResult)) then + Result := TempResult + else + Result := 0; +end; + +function TCoreWebView2CompositionController.GetAutomationProvider : IUnknown; +var + TempResult : IUnknown; +begin + Result := nil; + TempResult := nil; + + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_AutomationProvider(TempResult)) and + assigned(TempResult) then + Result := TempResult; +end; + +procedure TCoreWebView2CompositionController.SetRootVisualTarget(const aValue : IUnknown); +begin + if Initialized then + FBaseIntf.Set_RootVisualTarget(aValue); +end; + +procedure TCoreWebView2CompositionController.RemoveAllEvents; +begin + if Initialized then + begin + if (FCursorChangedToken.value <> 0) then + FBaseIntf.remove_CursorChanged(FCursorChangedToken); + + if (FNonClientRegionChanged.value <> 0) then + FBaseIntf4.remove_NonClientRegionChanged(FNonClientRegionChanged); + + if (FDragStartingToken.value <> 0) then + FBaseIntf5.remove_DragStarting(FDragStartingToken); + + InitializeTokens; + end; +end; + +function TCoreWebView2CompositionController.AddAllBrowserEvents(const aBrowserComponent : TComponent) : boolean; +begin + Result := AddCursorChangedEvent(aBrowserComponent) and + AddNonClientRegionChangedEvent(aBrowserComponent) and + AddDragStartingEvent(aBrowserComponent); +end; + +function TCoreWebView2CompositionController.AddCursorChangedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2CursorChangedEventHandler; +begin + Result := False; + + if Initialized and (FCursorChangedToken.value = 0) then + try + TempHandler := TCoreWebView2CursorChangedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_CursorChanged(TempHandler, FCursorChangedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2CompositionController.AddNonClientRegionChangedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2NonClientRegionChangedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf4) and (FNonClientRegionChanged.value = 0) then + try + TempHandler := TCoreWebView2NonClientRegionChangedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf4.add_NonClientRegionChanged(TempHandler, FNonClientRegionChanged)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2CompositionController.AddDragStartingEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2DragStartingEventHandler; +begin + Result := False; + + if assigned(FBaseIntf5) and (FDragStartingToken.value = 0) then + try + TempHandler := TCoreWebView2DragStartingEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf5.add_DragStarting(TempHandler, FDragStartingToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2CompositionController.SendMouseInput(aEventKind : TWVMouseEventKind; + aVirtualKeys : TWVMouseEventVirtualKeys; + aMouseData : cardinal; + aPoint : TPoint) : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.SendMouseInput(aEventKind, aVirtualKeys, aMouseData, tagPOINT(aPoint))); +end; + +function TCoreWebView2CompositionController.SendPointerInput( aEventKind : TWVPointerEventKind; + const aPointerInfo : ICoreWebView2PointerInfo) : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.SendPointerInput(aEventKind, aPointerInfo)); +end; + +function TCoreWebView2CompositionController.DragEnter(const dataObject : IDataObject; + keyState : LongWord; + point : tagPOINT; + out effect : LongWord) : HResult; +begin + Result := S_OK; + effect := DROPEFFECT_NONE; + + if assigned(FBaseIntf3) then + Result := FBaseIntf3.DragEnter(dataObject, keyState, point, effect); +end; + +function TCoreWebView2CompositionController.DragLeave : HResult; +begin + Result := S_OK; + + if assigned(FBaseIntf3) then + Result := FBaseIntf3.DragLeave; +end; + +function TCoreWebView2CompositionController.DragOver( keyState : LongWord; + point : tagPOINT; + out effect : LongWord) : HResult; +begin + Result := S_OK; + effect := DROPEFFECT_NONE; + + if assigned(FBaseIntf3) then + Result := FBaseIntf3.DragOver(keyState, point, effect); +end; + +function TCoreWebView2CompositionController.Drop(const dataObject : IDataObject; + keyState : LongWord; + point : tagPOINT; + out effect : LongWord) : HResult; +begin + Result := S_OK; + effect := DROPEFFECT_NONE; + + if assigned(FBaseIntf3) then + Result := FBaseIntf3.Drop(dataObject, keyState, point, effect); +end; + +function TCoreWebView2CompositionController.GetNonClientRegionAtPoint(point: TPoint) : TWVNonClientRegionKind; +var + TempResult : COREWEBVIEW2_NON_CLIENT_REGION_KIND; +begin + Result := COREWEBVIEW2_NON_CLIENT_REGION_KIND_NOWHERE; + + if assigned(FBaseIntf4) and + succeeded(FBaseIntf4.GetNonClientRegionAtPoint(point, TempResult)) then + Result := TempResult; +end; + +function TCoreWebView2CompositionController.QueryNonClientRegion(Kind: TWVNonClientRegionKind): ICoreWebView2RegionRectCollectionView; +var + TempResult : ICoreWebView2RegionRectCollectionView; +begin + TempResult := nil; + + if assigned(FBaseIntf4) and + succeeded(FBaseIntf4.QueryNonClientRegion(Kind, TempResult)) and + (TempResult <> nil) then + Result := TempResult + else + Result := nil; +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Controller.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Controller.pas new file mode 100644 index 000000000..a439d273a --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Controller.pas @@ -0,0 +1,699 @@ +unit uRESTDWPrivWVCoreWebView2Controller; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + System.Classes, System.Types, System.UITypes, Winapi.Windows, System.SysUtils, + {$ELSE} + Classes, Graphics, Windows, SysUtils, + {$ENDIF} + uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVTypes; + +type + /// + /// The owner of the `CoreWebView2` object that provides support for resizing, + /// showing and hiding, focusing, and other functionality related to + /// windowing and composition. The `CoreWebView2Controller` owns the + /// `CoreWebView2`, and if all references to the `CoreWebView2Controller` go + /// away, the WebView is closed. + /// + /// + /// See the ICoreWebView2Controller article. + /// + TCoreWebView2Controller = class + protected + FBaseIntf : ICoreWebView2Controller; + FBaseIntf2 : ICoreWebView2Controller2; + FBaseIntf3 : ICoreWebView2Controller3; + FBaseIntf4 : ICoreWebView2Controller4; + FAcceleratorKeyPressedToken : EventRegistrationToken; + FGotFocusToken : EventRegistrationToken; + FLostFocusToken : EventRegistrationToken; + FMoveFocusRequestedToken : EventRegistrationToken; + FZoomFactorChangedToken : EventRegistrationToken; + FRasterizationScaleChangedToken : EventRegistrationToken; + + function GetInitialized : boolean; + function GetZoomFactor : double; + function GetIsVisible : boolean; + function GetBounds : TRect; + function GetParentWindow : THandle; + function GetDefaultBackgroundColor : TColor; + function GetRasterizationScale : double; + function GetShouldDetectMonitorScaleChanges : boolean; + function GetBoundsMode : TWVBoundsMode; + function GetCoreWebView2 : ICoreWebView2; + function GetAllowExternalDrop : boolean; + + procedure SetZoomFactor(const aValue : double); + procedure SetIsVisible(const aValue : boolean); + procedure SetBounds(aValue : TRect); + procedure SetParentWindow(aValue : THandle); + procedure SetDefaultBackgroundColor(const aValue : TColor); + procedure SetRasterizationScale(const aValue : double); + procedure SetShouldDetectMonitorScaleChanges(aValue : boolean); + procedure SetBoundsMode(aValue : TWVBoundsMode); + procedure SetAllowExternalDrop(aValue : boolean); + + procedure InitializeFields; + procedure InitializeTokens; + procedure RemoveAllEvents; + + function AddAcceleratorKeyPressedEvent(const aBrowserComponent : TComponent) : boolean; + function AddGotFocusEvent(const aBrowserComponent : TComponent) : boolean; + function AddLostFocusEvent(const aBrowserComponent : TComponent) : boolean; + function AddMoveFocusRequestedEvent(const aBrowserComponent : TComponent) : boolean; + function AddZoomFactorChangedEvent(const aBrowserComponent : TComponent) : boolean; + function AddRasterizationScaleChangedEvent(const aBrowserComponent : TComponent) : boolean; + + public + constructor Create(const aBaseIntf : ICoreWebView2Controller); reintroduce; + destructor Destroy; override; + /// + /// Adds all the events of this class to an existing TWVBrowserBase instance. + /// + /// The TWVBrowserBase instance. + function AddAllBrowserEvents(const aBrowserComponent : TComponent) : boolean; + /// + /// Moves focus into WebView. WebView gets focus and focus is set to + /// correspondent element in the page hosted in the WebView. For + /// Programmatic reason, focus is set to previously focused element or the + /// default element if no previously focused element exists. For `Next` + /// reason, focus is set to the first element. For `Previous` reason, focus + /// is set to the last element. WebView changes focus through user + /// interaction including selecting into a WebView or Tab into it. For + /// tabbing, the app runs MoveFocus with Next or Previous to align with Tab + /// and Shift+Tab respectively when it decides the WebView is the next + /// element that may exist in a tab. Or, the app runs `IsDialogMessage` + /// as part of the associated message loop to allow the platform to auto + /// handle tabbing. The platform rotates through all windows with + /// `WS_TABSTOP`. When the WebView gets focus from `IsDialogMessage`, it is + /// internally put the focus on the first or last element for tab and + /// Shift+Tab respectively. + /// + function MoveFocus(aReason : TWVMoveFocusReason) : boolean; + /// + /// Closes the WebView and cleans up the underlying browser instance. + /// Cleaning up the browser instance releases the resources powering the + /// WebView. The browser instance is shut down if no other WebViews are + /// using it. + /// + /// After running `Close`, most methods will fail and event handlers stop + /// running. Specifically, the WebView releases the associated references to + /// any associated event handlers when `Close` is run. + /// + /// `Close` is implicitly run when the `CoreWebView2Controller` loses the + /// final reference and is destructed. But it is best practice to + /// explicitly run `Close` to avoid any accidental cycle of references + /// between the WebView and the app code. Specifically, if you capture a + /// reference to the WebView in an event handler you create a reference cycle + /// between the WebView and the event handler. Run `Close` to break the + /// cycle by releasing all event handlers. But to avoid the situation, it is + /// best to both explicitly run `Close` on the WebView and to not capture a + /// reference to the WebView to ensure the WebView is cleaned up correctly. + /// `Close` is synchronous and won't trigger the `beforeunload` event. + /// + function Close : boolean; + /// + /// Updates `aBounds` and `aZoomFactor` properties at the same time. This + /// operation is atomic from the perspective of the host. After returning + /// from this function, the `aBounds` and `aZoomFactor` properties are both + /// updated if the function is successful, or neither is updated if the + /// function fails. If `aBounds` and `aZoomFactor` are both updated by the + /// same scale (for example, `aBounds` and `aZoomFactor` are both doubled), + /// then the page does not display a change in `window.innerWidth` or + /// `window.innerHeight` and the WebView renders the content at the new size + /// and zoom without intermediate renderings. This function also updates + /// just one of `aZoomFactor` or `aBounds` by passing in the new value for one + /// and the current value for the other. + /// + function SetBoundsAndZoomFactor(aBounds: TRect; const aZoomFactor: double) : boolean; + /// + /// This is a notification separate from `Bounds` that tells WebView that the + /// main WebView parent (or any ancestor) `HWND` moved. This is needed + /// for accessibility and certain dialogs in WebView to work correctly. + /// + function NotifyParentWindowPositionChanged : boolean; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2Controller read FBaseIntf; + /// + /// The zoom factor for the WebView. + /// + /// + /// See the ICoreWebView2Controller article. + /// + property ZoomFactor : double read GetZoomFactor write SetZoomFactor; + /// + /// The `IsVisible` property determines whether to show or hide the WebView2. + /// If `IsVisible` is set to `FALSE`, the WebView2 is transparent and is + /// not rendered. However, this does not affect the window containing the + /// WebView2 (the `HWND` parameter that was passed to + /// `CreateCoreWebView2Controller`). If you want that window to disappear + /// too, run `ShowWindow` on it directly in addition to modifying the + /// `IsVisible` property. WebView2 as a child window does not get window + /// messages when the top window is minimized or restored. For performance + /// reasons, developers should set the `IsVisible` property of the WebView to + /// `FALSE` when the app window is minimized and back to `TRUE` when the app + /// window is restored. The app window does this by handling + /// `SIZE_MINIMIZED and SIZE_RESTORED` command upon receiving `WM_SIZE` + /// message. + /// There are CPU and memory benefits when the page is hidden. For instance, + /// Chromium has code that throttles activities on the page like animations + /// and some tasks are run less frequently. Similarly, WebView2 will + /// purge some caches to reduce memory usage. + /// + /// + /// See the ICoreWebView2Controller article. + /// + property IsVisible : boolean read GetIsVisible write SetIsVisible; + /// + /// The WebView bounds. Bounds are relative to the parent `HWND`. The app + /// has two ways to position a WebView. + /// * Create a child `HWND` that is the WebView parent `HWND`. Position + /// the window where the WebView should be. Use `(0, 0)` for the + /// top-left corner (the offset) of the `Bounds` of the WebView. + /// * Use the top-most window of the app as the WebView parent HWND. For + /// example, to position WebView correctly in the app, set the top-left + /// corner of the Bound of the WebView. + /// The values of `Bounds` are limited by the coordinate space of the host. + /// + /// + /// See the ICoreWebView2Controller article. + /// + property Bounds : TRect read GetBounds write SetBounds; + /// + /// The parent window provided by the app that this WebView is using to + /// render content. This API initially returns the window passed into + /// `CreateCoreWebView2Controller`. + /// + /// + /// See the ICoreWebView2Controller article. + /// + property ParentWindow : THandle read GetParentWindow write SetParentWindow; + /// + /// The `DefaultBackgroundColor` property is the color WebView renders + /// underneath all web content. This means WebView renders this color when + /// there is no web content loaded such as before the initial navigation or + /// between navigations. This also means web pages with undefined css + /// background properties or background properties containing transparent + /// pixels will render their contents over this color. Web pages with defined + /// and opaque background properties that span the page will obscure the + /// `DefaultBackgroundColor` and display normally. The default value for this + /// property is white to resemble the native browser experience. + /// The Color is specified by the COREWEBVIEW2_COLOR that represents an RGBA + /// value. The `A` represents an Alpha value, meaning + /// `DefaultBackgroundColor` can be transparent. In the case of a transparent + /// `DefaultBackgroundColor` WebView will render hosting app content as the + /// background. This Alpha value is not supported on Windows 7. Any `A` value + /// other than 255 will result in E_INVALIDARG on Windows 7. + /// It is supported on all other WebView compatible platforms. + /// Semi-transparent colors are not currently supported by this API and + /// setting `DefaultBackgroundColor` to a semi-transparent color will fail + /// with E_INVALIDARG. The only supported alpha values are 0 and 255, all + /// other values will result in E_INVALIDARG. + /// `DefaultBackgroundColor` can only be an opaque color or transparent. + /// This value may also be set by using the + /// `WEBVIEW2_DEFAULT_BACKGROUND_COLOR` environment variable. There is a + /// known issue with background color where setting the color by API can + /// still leave the app with a white flicker before the + /// `DefaultBackgroundColor` takes effect. Setting the color via environment + /// variable solves this issue. The value must be a hex value that can + /// optionally prepend a 0x. The value must account for the alpha value + /// which is represented by the first 2 digits. So any hex value fewer than 8 + /// digits will assume a prepended 00 to the hex value and result in a + /// transparent color. + /// `get_DefaultBackgroundColor` will return the result of this environment + /// variable if used. This environment variable can only set the + /// `DefaultBackgroundColor` once. Subsequent updates to background color + /// must be done through API call. + /// + /// + /// See the ICoreWebView2Controller2 article. + /// + property DefaultBackgroundColor : TColor read GetDefaultBackgroundColor write SetDefaultBackgroundColor; + /// + /// The rasterization scale for the WebView. The rasterization scale is the + /// combination of the monitor DPI scale and text scaling set by the user. + /// This value should be updated when the DPI scale of the app's top level + /// window changes (i.e. monitor DPI scale changes or window changes monitor) + /// or when the text scale factor of the system changes. + /// Rasterization scale applies to the WebView content, as well as + /// popups, context menus, scroll bars, and so on. Normal app scaling + /// scenarios should use the ZoomFactor property or SetBoundsAndZoomFactor + /// API which only scale the rendered HTML content and not popups, context + /// menus, scroll bars, and so on. + /// + /// + /// See the ICoreWebView2Controller3 article. + /// + property RasterizationScale : double read GetRasterizationScale write SetRasterizationScale; + /// + /// ShouldDetectMonitorScaleChanges property determines whether the WebView + /// attempts to track monitor DPI scale changes. When true, the WebView will + /// track monitor DPI scale changes, update the RasterizationScale property, + /// and raises RasterizationScaleChanged event. When false, the WebView will + /// not track monitor DPI scale changes, and the app must update the + /// RasterizationScale property itself. RasterizationScaleChanged event will + /// never raise when ShouldDetectMonitorScaleChanges is false. Apps that want + /// to set their own rasterization scale should set this property to false to + /// avoid the WebView2 updating the RasterizationScale property to match the + /// monitor DPI scale. + /// + /// + /// See the ICoreWebView2Controller3 article. + /// + property ShouldDetectMonitorScaleChanges : boolean read GetShouldDetectMonitorScaleChanges write SetShouldDetectMonitorScaleChanges; + /// + /// BoundsMode affects how setting the Bounds and RasterizationScale + /// properties work. Bounds mode can either be in COREWEBVIEW2_BOUNDS_MODE_USE_RAW_PIXELS + /// mode or COREWEBVIEW2_BOUNDS_MODE_USE_RASTERIZATION_SCALE mode. + /// When the mode is in COREWEBVIEW2_BOUNDS_MODE_USE_RAW_PIXELS, setting the bounds + /// property will set the size of the WebView in raw screen pixels. Changing + /// the rasterization scale in this mode won't change the raw pixel size of + /// the WebView and will only change the rasterization scale. + /// When the mode is in COREWEBVIEW2_BOUNDS_MODE_USE_RASTERIZATION_SCALE, setting the + /// bounds property will change the logical size of the WebView which can be + /// described by the following equation: Logical size * rasterization scale = Raw Pixel size + /// In this case, changing the rasterization scale will keep the logical size + /// the same and change the raw pixel size. + /// + /// + /// See the ICoreWebView2Controller3 article. + /// + property BoundsMode : TWVBoundsMode read GetBoundsMode write SetBoundsMode; + /// + /// Gets the `CoreWebView2` associated with this `CoreWebView2Controller`. + /// + /// + /// See the ICoreWebView2Controller article. + /// + property CoreWebView2 : ICoreWebView2 read GetCoreWebView2; + /// + /// Gets the `AllowExternalDrop` property which is used to configure the + /// capability that dragging objects from outside the bounds of webview2 and + /// dropping into webview2 is allowed or disallowed. The default value is + /// TRUE. + /// + /// + /// See the ICoreWebView2Controller4 article. + /// + property AllowExternalDrop : boolean read GetAllowExternalDrop write SetAllowExternalDrop; + end; + +implementation + +uses + uRESTDWPrivWVMiscFunctions, uRESTDWPrivWVBrowserBase, uRESTDWPrivWVCoreWebView2Delegates; + +constructor TCoreWebView2Controller.Create(const aBaseIntf : ICoreWebView2Controller); +begin + inherited Create; + + InitializeFields; + + FBaseIntf := aBaseIntf; + + if Initialized and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Controller2, FBaseIntf2) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Controller3, FBaseIntf3) then + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Controller4, FBaseIntf4); +end; + +destructor TCoreWebView2Controller.Destroy; +begin + try + RemoveAllEvents; + Close; + InitializeFields; + finally + inherited Destroy; + end; +end; + +procedure TCoreWebView2Controller.InitializeFields; +begin + FBaseIntf := nil; + FBaseIntf2 := nil; + FBaseIntf3 := nil; + FBaseIntf4 := nil; + + InitializeTokens; +end; + +procedure TCoreWebView2Controller.InitializeTokens; +begin + FAcceleratorKeyPressedToken.value := 0; + FGotFocusToken.value := 0; + FLostFocusToken.value := 0; + FMoveFocusRequestedToken.value := 0; + FZoomFactorChangedToken.value := 0; + FRasterizationScaleChangedToken.value := 0; +end; + +function TCoreWebView2Controller.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +procedure TCoreWebView2Controller.RemoveAllEvents; +begin + if Initialized then + begin + if (FAcceleratorKeyPressedToken.value <> 0) then + FBaseIntf.remove_AcceleratorKeyPressed(FAcceleratorKeyPressedToken); + + if (FGotFocusToken.value <> 0) then + FBaseIntf.remove_GotFocus(FGotFocusToken); + + if (FLostFocusToken.value <> 0) then + FBaseIntf.remove_LostFocus(FLostFocusToken); + + if (FMoveFocusRequestedToken.value <> 0) then + FBaseIntf.remove_MoveFocusRequested(FMoveFocusRequestedToken); + + if (FZoomFactorChangedToken.value <> 0) then + FBaseIntf.remove_ZoomFactorChanged(FZoomFactorChangedToken); + + if assigned(FBaseIntf3) and (FRasterizationScaleChangedToken.value <> 0) then + FBaseIntf3.remove_RasterizationScaleChanged(FRasterizationScaleChangedToken); + + InitializeTokens; + end; +end; + +function TCoreWebView2Controller.AddAllBrowserEvents(const aBrowserComponent : TComponent) : boolean; +begin + Result := AddAcceleratorKeyPressedEvent(aBrowserComponent) and + AddGotFocusEvent(aBrowserComponent) and + AddLostFocusEvent(aBrowserComponent) and + AddMoveFocusRequestedEvent(aBrowserComponent) and + AddZoomFactorChangedEvent(aBrowserComponent) and + AddRasterizationScaleChangedEvent(aBrowserComponent); +end; + +function TCoreWebView2Controller.AddAcceleratorKeyPressedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2AcceleratorKeyPressedEventHandler; +begin + Result := False; + + if Initialized and (FAcceleratorKeyPressedToken.value = 0) then + try + TempHandler := TCoreWebView2AcceleratorKeyPressedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_AcceleratorKeyPressed(TempHandler, FAcceleratorKeyPressedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Controller.AddGotFocusEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2FocusChangedEventHandler; +begin + Result := False; + + if Initialized and (FGotFocusToken.value = 0) then + try + TempHandler := TCoreWebView2GotFocusEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_GotFocus(TempHandler, FGotFocusToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Controller.AddLostFocusEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2FocusChangedEventHandler; +begin + Result := False; + + if Initialized and (FLostFocusToken.value = 0) then + try + TempHandler := TCoreWebView2LostFocusEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_LostFocus(TempHandler, FLostFocusToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Controller.AddMoveFocusRequestedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2MoveFocusRequestedEventHandler; +begin + Result := False; + + if Initialized and (FMoveFocusRequestedToken.value = 0) then + try + TempHandler := TCoreWebView2MoveFocusRequestedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_MoveFocusRequested(TempHandler, FMoveFocusRequestedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Controller.AddZoomFactorChangedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2ZoomFactorChangedEventHandler; +begin + Result := False; + + if Initialized and (FZoomFactorChangedToken.value = 0) then + try + TempHandler := TCoreWebView2ZoomFactorChangedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_ZoomFactorChanged(TempHandler, FZoomFactorChangedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Controller.AddRasterizationScaleChangedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2RasterizationScaleChangedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf3) and (FRasterizationScaleChangedToken.value = 0) then + try + TempHandler := TCoreWebView2RasterizationScaleChangedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf3.add_RasterizationScaleChanged(TempHandler, FRasterizationScaleChangedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Controller.MoveFocus(aReason : TWVMoveFocusReason) : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.MoveFocus(aReason)); +end; + +function TCoreWebView2Controller.Close : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.Close); +end; + +function TCoreWebView2Controller.GetCoreWebView2 : ICoreWebView2; +var + TempResult : ICoreWebView2; +begin + Result := nil; + TempResult := nil; + + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_CoreWebView2(TempResult)) and + assigned(TempResult) then + Result := TempResult; +end; + +function TCoreWebView2Controller.GetAllowExternalDrop : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf4) and + succeeded(FBaseIntf4.Get_AllowExternalDrop(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Controller.SetBoundsAndZoomFactor(aBounds: TRect; const aZoomFactor: double) : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.SetBoundsAndZoomFactor(tagRECT(aBounds), aZoomFactor)); +end; + +function TCoreWebView2Controller.NotifyParentWindowPositionChanged : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.NotifyParentWindowPositionChanged); +end; + +function TCoreWebView2Controller.GetZoomFactor : double; +var + TempResult : double; +begin + if Initialized and succeeded(FBaseIntf.Get_ZoomFactor(TempResult)) then + Result := TempResult + else + Result := 0; +end; + +procedure TCoreWebView2Controller.SetZoomFactor(const aValue : double); +begin + if Initialized then + FBaseIntf.Set_ZoomFactor(aValue); +end; + +procedure TCoreWebView2Controller.SetBounds(aValue : TRect); +begin + if Initialized then + FBaseIntf.Set_Bounds(tagRECT(aValue)); +end; + +procedure TCoreWebView2Controller.SetParentWindow(aValue : THandle); +begin + if Initialized then + FBaseIntf.Set_ParentWindow(aValue); +end; + +procedure TCoreWebView2Controller.SetDefaultBackgroundColor(const aValue : TColor); +var + TempColor : COREWEBVIEW2_COLOR; +begin + if assigned(FBaseIntf2) then + begin + TempColor := DelphiColorToCoreWebViewColor(aValue); + + // The only supported alpha values are 0 (transparent) and 255 (opaque). + if not(TempColor.A in [0, 255]) then + TempColor.A := 255; + + FBaseIntf2.Set_DefaultBackgroundColor(TempColor); + end; +end; + +procedure TCoreWebView2Controller.SetRasterizationScale(const aValue : double); +begin + if assigned(FBaseIntf3) then + FBaseIntf3.Set_RasterizationScale(aValue); +end; + +procedure TCoreWebView2Controller.SetShouldDetectMonitorScaleChanges(aValue : boolean); +begin + if assigned(FBaseIntf3) then + FBaseIntf3.Set_ShouldDetectMonitorScaleChanges(ord(aValue)); +end; + +procedure TCoreWebView2Controller.SetBoundsMode(aValue : TWVBoundsMode); +begin + if assigned(FBaseIntf3) then + FBaseIntf3.Set_BoundsMode(aValue); +end; + +procedure TCoreWebView2Controller.SetAllowExternalDrop(aValue : boolean); +begin + if assigned(FBaseIntf4) then + FBaseIntf4.Set_AllowExternalDrop(ord(aValue)); +end; + +function TCoreWebView2Controller.GetIsVisible : boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_IsVisible(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Controller.GetBounds : TRect; +var + TempRect : tagRECT; +begin + TempRect.left := 0; + TempRect.top := 0; + TempRect.right := 0; + TempRect.bottom := 0; + + if Initialized and succeeded(FBaseIntf.Get_Bounds(TempRect)) then + Result := TRect(TempRect); +end; + +function TCoreWebView2Controller.GetParentWindow : THandle; +var + TempHandle : HWND; +begin + if Initialized and + succeeded(FBaseIntf.Get_ParentWindow(TempHandle)) then + Result := TempHandle + else + Result := 0; +end; + +function TCoreWebView2Controller.GetDefaultBackgroundColor : TColor; +var + TempResult : COREWEBVIEW2_COLOR; +begin + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_DefaultBackgroundColor(TempResult)) then + Result := CoreWebViewColorToDelphiColor(TempResult) + else + {$IFDEF DELPHI16_UP} + Result := TColors.SysNone; // clNone + {$ELSE} + Result := clNone; + {$ENDIF} +end; + +function TCoreWebView2Controller.GetRasterizationScale : double; +var + TempResult : double; +begin + TempResult := 0; + + if assigned(FBaseIntf3) and + succeeded(FBaseIntf3.Get_RasterizationScale(TempResult)) then + Result := TempResult + else + Result := 0; +end; + +function TCoreWebView2Controller.GetShouldDetectMonitorScaleChanges : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf3) and + succeeded(FBaseIntf3.Get_ShouldDetectMonitorScaleChanges(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Controller.GetBoundsMode : TWVBoundsMode; +var + TempResult : COREWEBVIEW2_BOUNDS_MODE; +begin + TempResult := 0; + + if assigned(FBaseIntf3) and + succeeded(FBaseIntf3.Get_BoundsMode(TempResult)) then + Result := TempResult + else + Result := 0; +end; + +procedure TCoreWebView2Controller.SetIsVisible(const aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_IsVisible(ord(aValue)); +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2ControllerOptions.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2ControllerOptions.pas new file mode 100644 index 000000000..5951372c7 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2ControllerOptions.pas @@ -0,0 +1,296 @@ +unit uRESTDWPrivWVCoreWebView2ControllerOptions; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + System.Classes, System.Types, System.UITypes, System.SysUtils, + {$ELSE} + Classes, Graphics, SysUtils, + {$ENDIF} + uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVTypes; + +type + /// + /// This class is a ICoreWebView2ControllerOptions wrapper. + /// ICoreWebView2ControllerOptions is used to manage profile options that created by 'CreateCoreWebView2ControllerOptions'. + /// + /// + /// See the ICoreWebView2ControllerOptions article. + /// + TCoreWebView2ControllerOptions = class + protected + FBaseIntf : ICoreWebView2ControllerOptions; + FBaseIntf2 : ICoreWebView2ControllerOptions2; + FBaseIntf3 : ICoreWebView2ControllerOptions3; + FBaseIntf4 : ICoreWebView2ControllerOptions4; + + function GetInitialized : boolean; + function GetProfileName : wvstring; + function GetIsInPrivateModeEnabled : boolean; + function GetScriptLocale : wvstring; + function GetDefaultBackgroundColor : TColor; + function GetAllowHostInputProcessing : boolean; + + procedure SetProfileName(const aValue : wvstring); + procedure SetIsInPrivateModeEnabled(aValue : boolean); + procedure SetScriptLocale(const aValue : wvstring); + procedure SetDefaultBackgroundColor(const aValue : TColor); + procedure SetAllowHostInputProcessing(aValue : boolean); + + procedure InitializeFields; + + public + constructor Create(const aBaseIntf : ICoreWebView2ControllerOptions); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2ControllerOptions read FBaseIntf write FBaseIntf; + /// + /// `ProfileName` property is to specify a profile name, which is only allowed to contain + /// the following ASCII characters. It has a maximum length of 64 characters excluding the null-terminator. + /// It is ASCII case insensitive. + /// * alphabet characters: a-z and A-Z + /// * digit characters: 0-9 + /// * and '#', '@', '$', '(', ')', '+', '-', '_', '~', '.', ' ' (space). + /// Note: the text must not end with a period '.' or ' ' (space). And, although upper-case letters are + /// allowed, they're treated just as lower-case counterparts because the profile name will be mapped to + /// the real profile directory path on disk and Windows file system handles path names in a case-insensitive way. + /// + /// + /// See the ICoreWebView2ControllerOptions article. + /// + property ProfileName : wvstring read GetProfileName write SetProfileName; + /// + /// `IsInPrivateModeEnabled` property is to enable/disable InPrivate mode. + /// + /// + /// See the ICoreWebView2ControllerOptions article. + /// + property IsInPrivateModeEnabled : boolean read GetIsInPrivateModeEnabled write SetIsInPrivateModeEnabled; + /// + /// The default locale for the WebView2. It sets the default locale for all + /// Intl JavaScript APIs and other JavaScript APIs that depend on it, namely + /// `Intl.DateTimeFormat()` which affects string formatting like + /// in the time/date formats. Example: `Intl.DateTimeFormat().format(new Date())` + /// The intended locale value is in the format of + /// BCP 47 Language Tags. More information can be found from + /// [IETF BCP47](https://www.ietf.org/rfc/bcp/bcp47.html). + /// This property sets the locale for a CoreWebView2Environment used to create the + /// WebView2ControllerOptions object, which is passed as a parameter in + /// `CreateCoreWebView2ControllerWithOptions`. + /// Changes to the ScriptLocale property apply to renderer processes created after + /// the change. Any existing renderer processes will continue to use the previous + /// ScriptLocale value. To ensure changes are applied to all renderer process, + /// close and restart the CoreWebView2Environment and all associated WebView2 objects. + /// The default value for ScriptLocale will depend on the WebView2 language + /// and OS region. If the language portions of the WebView2 language and OS region + /// match, then it will use the OS region. Otherwise, it will use the WebView2 + /// language. + /// + /// + /// See the ICoreWebView2ControllerOptions2 article. + /// + property ScriptLocale : wvstring read GetScriptLocale write SetScriptLocale; + /// + /// This property allows users to initialize the `DefaultBackgroundColor` early, + /// preventing a white flash that can occur while WebView2 is loading when + /// the background color is set to something other than white. With early + /// initialization, the color remains consistent from the start. After + /// initialization, `CoreWebView2Controller.DefaultBackgroundColor` will return the value set using this API. + /// + /// The `CoreWebView2Controller.DefaultBackgroundColor` can be set via the WEBVIEW2_DEFAULT_BACKGROUND_COLOR environment variable, + /// which will remain supported for cases where this solution is being used. + /// It is encouraged to transition away from the environment variable and use this API solution to + /// apply the property. It is important to highlight that when set, the enviroment variable overrides + /// ControllerOptions::DefaultBackgroundColor and becomes the initial value of Controller::DefaultBackgroundColor. + /// + /// The `DefaultBackgroundColor` is the color that renders underneath all web + /// content. This means WebView2 renders this color when there is no web + /// content loaded. When no background color is defined in WebView2, it uses + /// the `DefaultBackgroundColor` property to render the background. + /// By default, this color is set to white. + /// + /// This API only supports opaque colors and full transparency. It will + /// fail for colors with alpha values that don't equal 0 or 255. + /// When WebView2 is set to be fully transparent, it does not render a background, + /// allowing the content from windows behind it to be visible. + /// + /// + /// See the ICoreWebView2Controller3 article. + /// + property DefaultBackgroundColor : TColor read GetDefaultBackgroundColor write SetDefaultBackgroundColor; + /// + /// `AllowHostInputProcessing` property is to enable/disable input passing through + /// the app before being delivered to the WebView2. This property is only applicable + /// to controllers created with `CoreWebView2Environment.CreateCoreWebView2ControllerAsync` and not + /// composition controllers created with `CoreWebView2Environment.CreateCoreWebView2CompositionControllerAsync`. + /// By default the value is `FALSE`. + /// Setting this property has no effect when using visual hosting. + /// + /// + /// See the ICoreWebView2Controller4 article. + /// + property AllowHostInputProcessing : boolean read GetAllowHostInputProcessing write SetAllowHostInputProcessing; + end; + +implementation + +uses + {$IFDEF DELPHI16_UP} + Winapi.ActiveX, + {$ELSE} + ActiveX, + {$ENDIF} + uRESTDWPrivWVMiscFunctions; + +constructor TCoreWebView2ControllerOptions.Create(const aBaseIntf : ICoreWebView2ControllerOptions); +begin + inherited Create; + + InitializeFields; + + FBaseIntf := aBaseIntf; + + if Initialized and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2ControllerOptions2, FBaseIntf2) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2ControllerOptions3, FBaseIntf3) then + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2ControllerOptions4, FBaseIntf4); +end; + +destructor TCoreWebView2ControllerOptions.Destroy; +begin + InitializeFields; + + inherited Destroy; +end; + +procedure TCoreWebView2ControllerOptions.InitializeFields; +begin + FBaseIntf := nil; + FBaseIntf2 := nil; + FBaseIntf3 := nil; + FBaseIntf4 := nil; +end; + +function TCoreWebView2ControllerOptions.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2ControllerOptions.GetProfileName : wvstring; +var + TempResult : PWideChar; +begin + Result := ''; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_ProfileName(TempResult)) and + (TempResult <> nil) then + begin + Result := TempResult; + CoTaskMemFree(TempResult); + end; +end; + +function TCoreWebView2ControllerOptions.GetIsInPrivateModeEnabled : boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_IsInPrivateModeEnabled(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2ControllerOptions.GetScriptLocale : wvstring; +var + TempResult : PWideChar; +begin + Result := ''; + TempResult := nil; + + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_ScriptLocale(TempResult)) and + (TempResult <> nil) then + begin + Result := TempResult; + CoTaskMemFree(TempResult); + end; +end; + +function TCoreWebView2ControllerOptions.GetDefaultBackgroundColor : TColor; +var + TempResult : COREWEBVIEW2_COLOR; +begin + if assigned(FBaseIntf3) and + succeeded(FBaseIntf3.Get_DefaultBackgroundColor(TempResult)) then + Result := CoreWebViewColorToDelphiColor(TempResult) + else + {$IFDEF DELPHI16_UP} + Result := TColors.SysNone; // clNone + {$ELSE} + Result := clNone; + {$ENDIF} +end; + +function TCoreWebView2ControllerOptions.GetAllowHostInputProcessing : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf4) and + succeeded(FBaseIntf4.Get_AllowHostInputProcessing(TempResult)) and + (TempResult <> 0); +end; + +procedure TCoreWebView2ControllerOptions.SetProfileName(const aValue : wvstring); +begin + if Initialized then + FBaseIntf.Set_ProfileName(PWideChar(aValue)); +end; + +procedure TCoreWebView2ControllerOptions.SetIsInPrivateModeEnabled(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_IsInPrivateModeEnabled(ord(aValue)); +end; + +procedure TCoreWebView2ControllerOptions.SetScriptLocale(const aValue : wvstring); +begin + if assigned(FBaseIntf2) then + FBaseIntf2.Set_ScriptLocale(PWideChar(aValue)); +end; + +procedure TCoreWebView2ControllerOptions.SetDefaultBackgroundColor(const aValue : TColor); +var + TempColor : COREWEBVIEW2_COLOR; +begin + if assigned(FBaseIntf3) then + begin + TempColor := DelphiColorToCoreWebViewColor(aValue); + + // The only supported alpha values are 0 (transparent) and 255 (opaque). + if not(TempColor.A in [0, 255]) then + TempColor.A := 255; + + FBaseIntf3.Set_DefaultBackgroundColor(TempColor); + end; +end; + +procedure TCoreWebView2ControllerOptions.SetAllowHostInputProcessing(aValue : boolean); +begin + if assigned(FBaseIntf4) then + FBaseIntf4.Set_AllowHostInputProcessing(ord(aValue)); +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2CookieManager.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2CookieManager.pas new file mode 100644 index 000000000..e7a9a8ffd --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2CookieManager.pas @@ -0,0 +1,185 @@ +unit uRESTDWPrivWVCoreWebView2CookieManager; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVTypes; + +type + /// + /// Creates, adds or updates, gets, or or view the cookies. The changes would + /// apply to the context of the user profile. That is, other WebViews under the + /// same user profile could be affected. + /// + /// + /// See the ICoreWebView2CookieManager article. + /// + TCoreWebView2CookieManager = class + protected + FBaseIntf : ICoreWebView2CookieManager; + + function GetInitialized : boolean; + + public + constructor Create(const aBaseIntf : ICoreWebView2CookieManager); reintroduce; + destructor Destroy; override; + /// + /// Create a cookie object with a specified name, value, domain, and path. + /// One can set other optional properties after cookie creation. + /// This only creates a cookie object and it is not added to the cookie + /// manager until you call AddOrUpdateCookie. + /// Leading or trailing whitespace(s), empty string, and special characters + /// are not allowed for name. + /// See ICoreWebView2Cookie for more details. + /// + function CreateCookie(const aName, aValue, aDomain, aPath: wvstring) : ICoreWebView2Cookie; + /// + /// Creates a cookie whose params matches those of the specified cookie. + /// + function CopyCookie(const aCookie : ICoreWebView2Cookie) : ICoreWebView2Cookie; + /// + /// Gets a list of cookies matching the specific URI. + /// If uri is empty string or null, all cookies under the same profile are + /// returned. + /// You can modify the cookie objects by calling + /// ICoreWebView2CookieManager::AddOrUpdateCookie, and the changes + /// will be applied to the webview. + /// + function GetCookies(const aURI : wvstring; const aHandler: ICoreWebView2GetCookiesCompletedHandler): boolean; + /// + /// Adds or updates a cookie with the given cookie data; may overwrite + /// cookies with matching name, domain, and path if they exist. + /// This method will fail if the domain of the given cookie is not specified. + /// + function AddOrUpdateCookie(const aCookie : ICoreWebView2Cookie): boolean; + /// + /// Deletes a cookie whose name and domain/path pair + /// match those of the specified cookie. + /// + function DeleteCookie(const aCookie : ICoreWebView2Cookie): boolean; + /// + /// Deletes cookies with matching name and uri. + /// Cookie name is required. + /// All cookies with the given name where domain + /// and path match provided URI are deleted. + /// + function DeleteCookies(const aName, aURI : wvstring): boolean; + /// + /// Deletes cookies with matching name and domain/path pair. + /// Cookie name is required. + /// If domain is specified, deletes only cookies with the exact domain. + /// If path is specified, deletes only cookies with the exact path. + /// + function DeleteCookiesWithDomainAndPath(const aName, aDomain, aPath : wvstring): boolean; + /// + /// Deletes all cookies under the same profile. + /// This could affect other WebViews under the same user profile. + /// + function DeleteAllCookies : boolean; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2CookieManager read FBaseIntf; + end; + +implementation + +uses + {$IFDEF DELPHI16_UP} + Winapi.ActiveX; + {$ELSE} + ActiveX; + {$ENDIF} + +constructor TCoreWebView2CookieManager.Create(const aBaseIntf: ICoreWebView2CookieManager); +begin + inherited Create; + + FBaseIntf := aBaseIntf; +end; + +destructor TCoreWebView2CookieManager.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2CookieManager.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2CookieManager.CreateCookie(const aName, aValue, aDomain, aPath: wvstring) : ICoreWebView2Cookie; +var + TempResult : ICoreWebView2Cookie; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.CreateCookie(PWideChar(aName), PWideChar(aValue), PWideChar(aDomain), PWideChar(aPath), TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +function TCoreWebView2CookieManager.CopyCookie(const aCookie : ICoreWebView2Cookie) : ICoreWebView2Cookie; +var + TempResult : ICoreWebView2Cookie; +begin + Result := nil; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.CopyCookie(aCookie, TempResult)) and + (TempResult <> nil) then + Result := TempResult; +end; + +function TCoreWebView2CookieManager.GetCookies(const aURI : wvstring; const aHandler: ICoreWebView2GetCookiesCompletedHandler) : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.GetCookies(PWideChar(aURI), aHandler)); +end; + +function TCoreWebView2CookieManager.AddOrUpdateCookie(const aCookie : ICoreWebView2Cookie): boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.AddOrUpdateCookie(aCookie)); +end; + +function TCoreWebView2CookieManager.DeleteCookie(const aCookie : ICoreWebView2Cookie): boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.DeleteCookie(aCookie)); +end; + +function TCoreWebView2CookieManager.DeleteCookies(const aName, aURI : wvstring): boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.DeleteCookies(PWideChar(aName), PWideChar(aURI))); +end; + +function TCoreWebView2CookieManager.DeleteCookiesWithDomainAndPath(const aName, aDomain, aPath : wvstring): boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.DeleteCookiesWithDomainAndPath(PWideChar(aName), PWideChar(aDomain), PWideChar(aPath))); +end; + +function TCoreWebView2CookieManager.DeleteAllCookies : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.DeleteAllCookies); +end; + +end. + diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2CustomSchemeRegistration.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2CustomSchemeRegistration.pas new file mode 100644 index 000000000..534844bc9 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2CustomSchemeRegistration.pas @@ -0,0 +1,198 @@ +unit uRESTDWPrivWVCoreWebView2CustomSchemeRegistration; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + System.SysUtils, Winapi.ActiveX, + {$ELSE} + SysUtils, ActiveX, + {$ENDIF} + uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVTypes; + +type + /// + /// Represents the registration of a custom scheme with the + /// CoreWebView2Environment. + /// This allows the WebView2 app to be able to handle WebResourceRequested + /// event for requests with the specified scheme and be able to navigate the + /// WebView2 to the custom scheme. + /// + /// + /// See the ICoreWebView2CustomSchemeRegistration article. + /// + TCoreWebView2CustomSchemeRegistration = class(TInterfacedObject, ICoreWebView2CustomSchemeRegistration) + protected + FCustomSchemeInfo : TWVCustomSchemeInfo; + + // ICoreWebView2CustomSchemeRegistration + function Get_SchemeName(out SchemeName: PWideChar): HResult; stdcall; + function Get_TreatAsSecure(out TreatAsSecure: Integer): HResult; stdcall; + function Set_TreatAsSecure(TreatAsSecure: Integer): HResult; stdcall; + function GetAllowedOrigins(out allowedOriginsCount: SYSUINT; out allowedOrigins: PPWideChar): HResult; stdcall; + function SetAllowedOrigins(allowedOriginsCount: SYSUINT; allowedOrigins: PPWideChar): HResult; stdcall; + function Get_HasAuthorityComponent(out HasAuthorityComponent: Integer): HResult; stdcall; + function Set_HasAuthorityComponent(HasAuthorityComponent: Integer): HResult; stdcall; + + public + /// + /// Constructor of the ICoreWebView2CustomSchemeRegistration wrapper. + /// + /// Record with all the information to register a custom scheme. + /// + /// See the TWVCustomSchemeInfo comments + /// See the ICoreWebView2CustomSchemeRegistration article. + /// + constructor Create(const aCustomSchemeInfo : TWVCustomSchemeInfo); reintroduce; overload; + /// + /// Constructor of the ICoreWebView2CustomSchemeRegistration wrapper. + /// + /// The name of the custom scheme to register. + /// Comma separated list of origins that are allowed to issue requests with the custom scheme, such as XHRs and subresource requests that have an Origin header. + /// Whether the sites with this scheme will be treated as a Secure Context like an HTTPS site. + /// Set this property to true if the URIs with this custom scheme will have an authority component (a host for custom schemes) + /// + /// See the ICoreWebView2CustomSchemeRegistration article. + /// + constructor Create(const aSchemeName, aAllowedDomains : wvstring; aTreatAsSecure, aHasAuthorityComponent : boolean); reintroduce; overload; + end; + +implementation + +uses + uRESTDWPrivWVMiscFunctions; + +constructor TCoreWebView2CustomSchemeRegistration.Create(const aCustomSchemeInfo : TWVCustomSchemeInfo); +begin + inherited Create; + + FCustomSchemeInfo := aCustomSchemeInfo; +end; + +constructor TCoreWebView2CustomSchemeRegistration.Create(const aSchemeName, aAllowedDomains : wvstring; aTreatAsSecure, aHasAuthorityComponent : boolean); +begin + inherited Create; + + FCustomSchemeInfo.SchemeName := aSchemeName; + FCustomSchemeInfo.TreatAsSecure := aTreatAsSecure; + FCustomSchemeInfo.AllowedDomains := aAllowedDomains; + FCustomSchemeInfo.HasAuthorityComponent := aHasAuthorityComponent; +end; + +function TCoreWebView2CustomSchemeRegistration.Get_SchemeName(out SchemeName: PWideChar): HResult; stdcall; +begin + Result := S_OK; + SchemeName := AllocCoTaskMemStr(FCustomSchemeInfo.SchemeName); +end; + +function TCoreWebView2CustomSchemeRegistration.Get_TreatAsSecure(out TreatAsSecure: Integer): HResult; stdcall; +begin + Result := S_OK; + TreatAsSecure := ord(FCustomSchemeInfo.TreatAsSecure); +end; + +function TCoreWebView2CustomSchemeRegistration.Set_TreatAsSecure(TreatAsSecure: Integer): HResult; stdcall; +begin + Result := S_OK; + FCustomSchemeInfo.TreatAsSecure := (TreatAsSecure <> 0); +end; + +function TCoreWebView2CustomSchemeRegistration.GetAllowedOrigins(out allowedOriginsCount: SYSUINT; out allowedOrigins: PPWideChar): HResult; stdcall; +var + i, j, TempSize : integer; + TempOrigin : wvstring; + TempArray : array of PWideChar; +begin + Result := S_OK; + allowedOriginsCount := 0; + allowedOrigins := nil; + + if (FCustomSchemeInfo.AllowedDomains <> '') then + begin + j := 1; + + for i := 1 to Length(FCustomSchemeInfo.AllowedDomains) do + if (FCustomSchemeInfo.AllowedDomains[i] = ',') or (i = Length(FCustomSchemeInfo.AllowedDomains)) then + begin + if (i > j) then + begin + if (i = Length(FCustomSchemeInfo.AllowedDomains)) then + TempOrigin := trim(copy(FCustomSchemeInfo.AllowedDomains, j, i - j + 1)) + else + TempOrigin := trim(copy(FCustomSchemeInfo.AllowedDomains, j, i - j)); + + if (length(TempOrigin) > 0) then + begin + SetLength(TempArray, succ(length(TempArray))); + TempArray[pred(length(TempArray))] := AllocCoTaskMemStr(TempOrigin); + end; + end; + + j := succ(i); + end; + + allowedOriginsCount := length(TempArray); + + if (allowedOriginsCount > 0) then + begin + TempSize := allowedOriginsCount * SizeOf(PWideChar); + allowedOrigins := CoTaskMemAlloc(TempSize); + Move(TempArray[0], allowedOrigins^, TempSize); + end; + end; +end; + +function TCoreWebView2CustomSchemeRegistration.SetAllowedOrigins(allowedOriginsCount: SYSUINT; allowedOrigins: PPWideChar): HResult; stdcall; +var + TempArray : PPWideChar; + TempOriginPtr : PWideChar; + TempOrigin : wvstring; + i : SYSUINT; +begin + Result := S_OK; + i := 0; + TempArray := allowedOrigins; + + FCustomSchemeInfo.AllowedDomains := ''; + + while (i < allowedOriginsCount) do + begin + TempOriginPtr := TempArray^; + + if (TempOriginPtr <> nil) then + begin + TempOrigin := TempOriginPtr; + + if (FCustomSchemeInfo.AllowedDomains = '') then + FCustomSchemeInfo.AllowedDomains := TempOrigin + else + FCustomSchemeInfo.AllowedDomains := ',' + TempOrigin; + + CoTaskMemFree(TempOriginPtr); + end; + + inc(TempArray); + inc(i); + end; + + CoTaskMemFree(allowedOrigins); +end; + +function TCoreWebView2CustomSchemeRegistration.Get_HasAuthorityComponent(out HasAuthorityComponent: Integer): HResult; stdcall; +begin + Result := S_OK; + HasAuthorityComponent := ord(FCustomSchemeInfo.HasAuthorityComponent); +end; + +function TCoreWebView2CustomSchemeRegistration.Set_HasAuthorityComponent(HasAuthorityComponent: Integer): HResult; stdcall; +begin + Result := S_OK; + FCustomSchemeInfo.HasAuthorityComponent := (HasAuthorityComponent <> 0); +end; + + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Delegates.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Delegates.pas new file mode 100644 index 000000000..bdce21489 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Delegates.pas @@ -0,0 +1,4630 @@ +unit uRESTDWPrivWVCoreWebView2Delegates; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + WinApi.Windows, Winapi.ActiveX, + {$ELSE} + Windows, ActiveX, + {$ENDIF} + uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVInterfaces, uRESTDWPrivWVTypes; + +type + /// + /// Receives AcceleratorKeyPressed events. + /// + /// + /// See the ICoreWebView2AcceleratorKeyPressedEventHandler article. + /// + TCoreWebView2AcceleratorKeyPressedEventHandler = class(TInterfacedObject, ICoreWebView2AcceleratorKeyPressedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2Controller; const args: ICoreWebView2AcceleratorKeyPressedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives the result of the CapturePreview method. The result is written + /// to the stream provided in the CapturePreview method. + /// + /// + /// See the ICoreWebView2CapturePreviewCompletedHandler article. + /// + TCoreWebView2CapturePreviewCompletedHandler = class(TInterfacedObject, ICoreWebView2CapturePreviewCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives ContainsFullScreenElementChanged events. + /// + /// + /// See the ICoreWebView2ContainsFullScreenElementChangedEventHandler article. + /// + TCoreWebView2ContainsFullScreenElementChangedEventHandler = class(TInterfacedObject, ICoreWebView2ContainsFullScreenElementChangedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `ContentLoading` events. + /// + /// + /// See the ICoreWebView2ContentLoadingEventHandler article. + /// + TCoreWebView2ContentLoadingEventHandler = class(TInterfacedObject, ICoreWebView2ContentLoadingEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ContentLoadingEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives the CoreWebView2Controller created using CreateCoreWebView2Controller. + /// + /// + /// See the ICoreWebView2CreateCoreWebView2ControllerCompletedHandler article. + /// + TCoreWebView2CreateCoreWebView2ControllerCompletedHandler = class(TInterfacedObject, ICoreWebView2CreateCoreWebView2ControllerCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult; const result_: ICoreWebView2Controller): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives DevToolsProtocolEventReceived events from the WebView. + /// + /// + /// See the ICoreWebView2DevToolsProtocolEventReceivedEventHandler article. + /// + TCoreWebView2DevToolsProtocolEventReceivedEventHandler = class(TInterfacedObject, ICoreWebView2DevToolsProtocolEventReceivedEventHandler) + protected + FEvents : Pointer; + FEventName : wvstring; + FEventID : integer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DevToolsProtocolEventReceivedEventArgs): HResult; stdcall; + + public + Token : EventRegistrationToken; + + constructor Create(const aEvents: IWVBrowserEvents; const aEventName : wvstring; aEventID : integer); reintroduce; + destructor Destroy; override; + + property EventName : wvstring read FEventName; + property EventID : integer read FEventID; + end; + + /// + /// Receives DocumentTitleChanged events. Use the DocumentTitle property + /// to get the modified title. + /// + /// + /// See the ICoreWebView2DocumentTitleChangedEventHandler article. + /// + TCoreWebView2DocumentTitleChangedEventHandler = class(TInterfacedObject, ICoreWebView2DocumentTitleChangedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives the WebView2Environment created using + /// CreateCoreWebView2Environment. + /// + /// + /// See the ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler article. + /// + TCoreWebView2EnvironmentCompletedHandler = class(TInterfacedObject, ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) + protected + FBrowserEvents : Pointer; + FLoaderEvents : Pointer; + + function Invoke(errorCode: HResult; const result_: ICoreWebView2Environment): HResult; stdcall; + + public + constructor Create(const aBrowserEvents: IWVBrowserEvents); reintroduce; overload; + constructor Create(const aLoaderEvents: IWVLoaderEvents); reintroduce; overload; + destructor Destroy; override; + end; + + /// + /// Receives the result of the ExecuteScript method. + /// + /// + /// See the ICoreWebView2ExecuteScriptCompletedHandler article. + /// + TCoreWebView2ExecuteScriptCompletedHandler = class(TInterfacedObject, ICoreWebView2ExecuteScriptCompletedHandler) + protected + FEvents : Pointer; + FID : integer; + + function Invoke(errorCode: HResult; result_: PWideChar): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aExecutionID : integer); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives NavigationCompleted events. + /// + /// + /// See the ICoreWebView2NavigationCompletedEventHandler article. + /// + TCoreWebView2FrameNavigationCompletedEventHandler = class(TInterfacedObject, ICoreWebView2NavigationCompletedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NavigationCompletedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives NavigationStarting events. + /// + /// + /// See the ICoreWebView2NavigationStartingEventHandler article. + /// + TCoreWebView2FrameNavigationStartingEventHandler = class(TInterfacedObject, ICoreWebView2NavigationStartingEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NavigationStartingEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives GotFocus and LostFocus events. + /// + /// + /// See the ICoreWebView2FocusChangedEventHandler article. + /// + TCoreWebView2GotFocusEventHandler = class(TInterfacedObject, ICoreWebView2FocusChangedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives HistoryChanged events. + /// + /// + /// See the ICoreWebView2HistoryChangedEventHandler article. + /// + TCoreWebView2HistoryChangedEventHandler = class(TInterfacedObject, ICoreWebView2HistoryChangedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives GotFocus and LostFocus events. + /// + /// + /// See the ICoreWebView2FocusChangedEventHandler article. + /// + TCoreWebView2LostFocusEventHandler = class(TInterfacedObject, ICoreWebView2FocusChangedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives MoveFocusRequested events. + /// + /// + /// See the ICoreWebView2MoveFocusRequestedEventHandler article. + /// + TCoreWebView2MoveFocusRequestedEventHandler = class(TInterfacedObject, ICoreWebView2MoveFocusRequestedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2Controller; const args: ICoreWebView2MoveFocusRequestedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives NavigationCompleted events. + /// + /// + /// See the ICoreWebView2NavigationCompletedEventHandler article. + /// + TCoreWebView2NavigationCompletedEventHandler = class(TInterfacedObject, ICoreWebView2NavigationCompletedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NavigationCompletedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives NavigationStarting events. + /// + /// + /// See the ICoreWebView2NavigationStartingEventHandler article. + /// + TCoreWebView2NavigationStartingEventHandler = class(TInterfacedObject, ICoreWebView2NavigationStartingEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NavigationStartingEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives NewBrowserVersionAvailable events. + /// + /// + /// See the ICoreWebView2NewBrowserVersionAvailableEventHandler article. + /// + TCoreWebView2NewBrowserVersionAvailableEventHandler = class(TInterfacedObject, ICoreWebView2NewBrowserVersionAvailableEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2Environment; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVLoaderEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives NewWindowRequested events. + /// + /// + /// See the ICoreWebView2NewWindowRequestedEventHandler article. + /// + TCoreWebView2NewWindowRequestedEventHandler = class(TInterfacedObject, ICoreWebView2NewWindowRequestedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NewWindowRequestedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives PermissionRequested events. + /// + /// + /// See the ICoreWebView2PermissionRequestedEventHandler article. + /// + TCoreWebView2PermissionRequestedEventHandler = class(TInterfacedObject, ICoreWebView2PermissionRequestedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2PermissionRequestedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives ProcessFailed events. + /// + /// + /// See the ICoreWebView2ProcessFailedEventHandler article. + /// + TCoreWebView2ProcessFailedEventHandler = class(TInterfacedObject, ICoreWebView2ProcessFailedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ProcessFailedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives ScriptDialogOpening events. + /// + /// + /// See the ICoreWebView2ScriptDialogOpeningEventHandler article. + /// + TCoreWebView2ScriptDialogOpeningEventHandler = class(TInterfacedObject, ICoreWebView2ScriptDialogOpeningEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ScriptDialogOpeningEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives SourceChanged events. + /// + /// + /// See the ICoreWebView2SourceChangedEventHandler article. + /// + TCoreWebView2SourceChangedEventHandler = class(TInterfacedObject, ICoreWebView2SourceChangedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2SourceChangedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives WebMessageReceived events. + /// + /// + /// See the ICoreWebView2WebMessageReceivedEventHandler article. + /// + TCoreWebView2WebMessageReceivedEventHandler = class(TInterfacedObject, ICoreWebView2WebMessageReceivedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2WebMessageReceivedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Runs when a URL request (through network, file, and so on) is made in + /// the webview for a Web resource matching resource context filter and URL + /// specified in AddWebResourceRequestedFilter. The host views and modifies + /// the request or provide a response in a similar pattern to HTTP, in which + /// case the request immediately completed. This may not contain any request + /// headers that are added by the network stack, such as an Authorization + /// header. + /// + /// + /// See the ICoreWebView2WebResourceRequestedEventHandler article. + /// + TCoreWebView2WebResourceRequestedEventHandler = class(TInterfacedObject, ICoreWebView2WebResourceRequestedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2WebResourceRequestedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives WindowCloseRequested events. + /// + /// + /// See the ICoreWebView2WindowCloseRequestedEventHandler article. + /// + TCoreWebView2WindowCloseRequestedEventHandler = class(TInterfacedObject, ICoreWebView2WindowCloseRequestedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Implements the interface to receive ZoomFactorChanged events. Use the + /// ICoreWebView2Controller.ZoomFactor property to get the modified zoom + /// factor. + /// + /// + /// See the ICoreWebView2ZoomFactorChangedEventHandler article. + /// + TCoreWebView2ZoomFactorChangedEventHandler = class(TInterfacedObject, ICoreWebView2ZoomFactorChangedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// The caller implements this interface to receive the CoreWebView2Controller + /// created via CreateCoreWebView2CompositionController. + /// + /// + /// See the ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler article. + /// + TCoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler = class(TInterfacedObject, ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult; const result_: ICoreWebView2CompositionController): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// The caller implements this interface to receive CursorChanged events. Use + /// the Cursor property to get the new cursor. + /// + /// + /// See the ICoreWebView2CursorChangedEventHandler article. + /// + TCoreWebView2CursorChangedEventHandler = class(TInterfacedObject, ICoreWebView2CursorChangedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2CompositionController; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives BrowserProcessExited events. + /// + /// + /// See the ICoreWebView2BrowserProcessExitedEventHandler article. + /// + TCoreWebView2BrowserProcessExitedEventHandler = class(TInterfacedObject, ICoreWebView2BrowserProcessExitedEventHandler) + protected + FBrowserEvents : Pointer; + FLoaderEvents : Pointer; + + function Invoke(const sender: ICoreWebView2Environment; const args: ICoreWebView2BrowserProcessExitedEventArgs): HResult; stdcall; + + public + constructor Create(const aBrowserEvents: IWVBrowserEvents); reintroduce; overload; + constructor Create(const aLoaderEvents: IWVLoaderEvents); reintroduce; overload; + destructor Destroy; override; + end; + + /// + /// Receives RasterizationScaleChanged events. Use the RasterizationScale + /// property to get the modified scale. + /// + /// + /// See the ICoreWebView2RasterizationScaleChangedEventHandler article. + /// + TCoreWebView2RasterizationScaleChangedEventHandler = class(TInterfacedObject, ICoreWebView2RasterizationScaleChangedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives WebResourceResponseReceived events. + /// + /// + /// See the ICoreWebView2WebResourceResponseReceivedEventHandler article. + /// + TCoreWebView2WebResourceResponseReceivedEventHandler = class(TInterfacedObject, ICoreWebView2WebResourceResponseReceivedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2WebResourceResponseReceivedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives DOMContentLoaded events. + /// + /// + /// See the ICoreWebView2DOMContentLoadedEventHandler article. + /// + TCoreWebView2DOMContentLoadedEventHandler = class(TInterfacedObject, ICoreWebView2DOMContentLoadedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DOMContentLoadedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives the result of the ICoreWebView2WebResourceResponseView.GetContent method. + /// + /// + /// See the ICoreWebView2WebResourceResponseViewGetContentCompletedHandler article. + /// + TCoreWebView2WebResourceResponseViewGetContentCompletedHandler = class(TInterfacedObject, ICoreWebView2WebResourceResponseViewGetContentCompletedHandler) + protected + FEvents : Pointer; + FResourceID : integer; + + function Invoke(errorCode: HResult; const result_: IStream): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aResourceID : integer = 0); reintroduce; + destructor Destroy; override; + + property ResourceID : integer read FResourceID; + end; + + /// + /// Receives the result of the GetCookies method. The result is written to + /// the cookie list provided in the GetCookies method call. + /// + /// + /// See the ICoreWebView2GetCookiesCompletedHandler article. + /// + TCoreWebView2GetCookiesCompletedHandler = class(TInterfacedObject, ICoreWebView2GetCookiesCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode : HResult; const result_ : ICoreWebView2CookieList): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// The caller implements this interface to receive the TrySuspend result. + /// + /// + /// See the ICoreWebView2TrySuspendCompletedHandler article. + /// + TCoreWebView2TrySuspendCompletedHandler = class(TInterfacedObject, ICoreWebView2TrySuspendCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult; result_: Integer): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives FrameCreated event. + /// + /// + /// See the ICoreWebView2FrameCreatedEventHandler article. + /// + TCoreWebView2FrameCreatedEventHandler = class(TInterfacedObject, ICoreWebView2FrameCreatedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2FrameCreatedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Add an event handler for the DownloadStarting event. + /// + /// + /// See the ICoreWebView2DownloadStartingEventHandler article. + /// + TCoreWebView2DownloadStartingEventHandler = class(TInterfacedObject, ICoreWebView2DownloadStartingEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DownloadStartingEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// An event handler for the ClientCertificateRequested event. + /// + /// + /// See the ICoreWebView2ClientCertificateRequestedEventHandler article. + /// + TCoreWebView2ClientCertificateRequestedEventHandler = class(TInterfacedObject, ICoreWebView2ClientCertificateRequestedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ClientCertificateRequestedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives the result of the PrintToPdf method. If the print to PDF + /// operation succeeds, isSuccessful is true. Otherwise, if the operation + /// failed, isSuccessful is set to false. An invalid path returns + /// E_INVALIDARG. + /// + /// + /// See the ICoreWebView2PrintToPdfCompletedHandler article. + /// + TCoreWebView2PrintToPdfCompletedHandler = class(TInterfacedObject, ICoreWebView2PrintToPdfCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult; result_: Integer): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Implements the interface to receive BytesReceivedChanged event. Use the + /// ICoreWebView2DownloadOperation.BytesReceived property to get the received + /// bytes count. + /// + /// + /// See the ICoreWebView2BytesReceivedChangedEventHandler article. + /// + TCoreWebView2BytesReceivedChangedEventHandler = class(TInterfacedObject, ICoreWebView2BytesReceivedChangedEventHandler) + protected + FEvents : Pointer; + FDownloadID : integer; + + function Invoke(const sender: ICoreWebView2DownloadOperation; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aDownloadID : integer); reintroduce; + destructor Destroy; override; + end; + + /// + /// Implements the interface to receive EstimatedEndTimeChanged event. Use the + /// ICoreWebView2DownloadOperation.EstimatedEndTime property to get the new + /// estimated end time. + /// + /// + /// See the ICoreWebView2EstimatedEndTimeChangedEventHandler article. + /// + TCoreWebView2EstimatedEndTimeChangedEventHandler = class(TInterfacedObject, ICoreWebView2EstimatedEndTimeChangedEventHandler) + protected + FEvents : Pointer; + FDownloadID : integer; + + function Invoke(const sender: ICoreWebView2DownloadOperation; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aDownloadID : integer); reintroduce; + destructor Destroy; override; + end; + + /// + /// Implements the interface to receive StateChanged event. Use the + /// ICoreWebView2DownloadOperation.State property to get the current state, + /// which can be in progress, interrupted, or completed. Use the + /// ICoreWebView2DownloadOperation.InterruptReason property to get the + /// interrupt reason if the download is interrupted. + /// + /// + /// See the ICoreWebView2StateChangedEventHandler article. + /// + TCoreWebView2StateChangedEventHandler = class(TInterfacedObject, ICoreWebView2StateChangedEventHandler) + protected + FEvents : Pointer; + FDownloadID : integer; + + function Invoke(const sender: ICoreWebView2DownloadOperation; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aDownloadID : integer); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives FrameNameChanged event. + /// + /// + /// See the ICoreWebView2FrameNameChangedEventHandler article. + /// + TCoreWebView2FrameNameChangedEventHandler = class(TInterfacedObject, ICoreWebView2FrameNameChangedEventHandler) + protected + FEvents : Pointer; + FFrameID : cardinal; + + function Invoke(const sender: ICoreWebView2Frame; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives FrameDestroyed event. + /// + /// + /// See the ICoreWebView2FrameDestroyedEventHandler article. + /// + TCoreWebView2FrameDestroyedEventHandler = class(TInterfacedObject, ICoreWebView2FrameDestroyedEventHandler) + protected + FEvents : Pointer; + FFrameID : cardinal; + + function Invoke(const sender: ICoreWebView2Frame; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives CallDevToolsProtocolMethod completion results. + /// + /// + /// See the ICoreWebView2CallDevToolsProtocolMethodCompletedHandler article. + /// + TCoreWebView2CallDevToolsProtocolMethodCompletedHandler = class(TInterfacedObject, ICoreWebView2CallDevToolsProtocolMethodCompletedHandler) + protected + FEvents : Pointer; + FID : integer; + + function Invoke(errorCode: HResult; result_: PWideChar): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aExecutionID : integer); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives the result of the AddScriptToExecuteOnDocumentCreated method. + /// + /// + /// See the ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler article. + /// + TCoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler = class(TInterfacedObject, ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult; result_: PWideChar): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Implements the interface to receive IsMutedChanged events. Use the + /// IsMuted property to get the mute state. + /// + /// + /// See the ICoreWebView2IsMutedChangedEventHandler article. + /// + TCoreWebView2IsMutedChangedEventHandler = class(TInterfacedObject, ICoreWebView2IsMutedChangedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Implements the interface to receive IsDocumentPlayingAudioChanged events. Use the + /// IsDocumentPlayingAudio property to get the audio playing state. + /// + /// + /// See the ICoreWebView2IsDocumentPlayingAudioChangedEventHandler article. + /// + TCoreWebView2IsDocumentPlayingAudioChangedEventHandler = class(TInterfacedObject, ICoreWebView2IsDocumentPlayingAudioChangedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Implements the interface to receive IsDefaultDownloadDialogOpenChanged + /// events. + /// + /// + /// See the ICoreWebView2IsDefaultDownloadDialogOpenChangedEventHandler article. + /// + TCoreWebView2IsDefaultDownloadDialogOpenChangedEventHandler = class(TInterfacedObject, ICoreWebView2IsDefaultDownloadDialogOpenChangedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// An event handler for the ProcessInfosChanged event. + /// + /// + /// See the ICoreWebView2ProcessInfosChangedEventHandler article. + /// + TCoreWebView2ProcessInfosChangedEventHandler = class(TInterfacedObject, ICoreWebView2ProcessInfosChangedEventHandler) + protected + FBrowserEvents : Pointer; + FLoaderEvents : Pointer; + + function Invoke(const sender: ICoreWebView2Environment; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aBrowserEvents: IWVBrowserEvents); reintroduce; overload; + constructor Create(const aLoaderEvents: IWVLoaderEvents); reintroduce; overload; + destructor Destroy; override; + end; + + /// + /// Receives NavigationCompleted events for iframe. + /// + /// + /// See the ICoreWebView2FrameNavigationCompletedEventHandler article. + /// + TCoreWebView2FrameNavigationCompletedEventHandler2 = class(TInterfacedObject, ICoreWebView2FrameNavigationCompletedEventHandler) + protected + FEvents : Pointer; + FFrameID : cardinal; + + function Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2NavigationCompletedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives NavigationStarting events for iframe. + /// + /// + /// See the ICoreWebView2FrameNavigationStartingEventHandler article. + /// + TCoreWebView2FrameNavigationStartingEventHandler2 = class(TInterfacedObject, ICoreWebView2FrameNavigationStartingEventHandler) + protected + FEvents : Pointer; + FFrameID : cardinal; + + function Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2NavigationStartingEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives ContentLoading events for iframe. + /// + /// + /// See the ICoreWebView2FrameContentLoadingEventHandler article. + /// + TCoreWebView2FrameContentLoadingEventHandler = class(TInterfacedObject, ICoreWebView2FrameContentLoadingEventHandler) + protected + FEvents : Pointer; + FFrameID : cardinal; + + function Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2ContentLoadingEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives DOMContentLoaded events for iframe. + /// + /// + /// See the ICoreWebView2FrameDOMContentLoadedEventHandler article. + /// + TCoreWebView2FrameDOMContentLoadedEventHandler = class(TInterfacedObject, ICoreWebView2FrameDOMContentLoadedEventHandler) + protected + FEvents : Pointer; + FFrameID : cardinal; + + function Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2DOMContentLoadedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives WebMessageReceived events for iframe. + /// + /// + /// See the ICoreWebView2FrameWebMessageReceivedEventHandler article. + /// + TCoreWebView2FrameWebMessageReceivedEventHandler = class(TInterfacedObject, ICoreWebView2FrameWebMessageReceivedEventHandler) + protected + FEvents : Pointer; + FFrameID : cardinal; + + function Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2WebMessageReceivedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); reintroduce; + destructor Destroy; override; + end; + + /// + /// The caller implements this interface to handle the BasicAuthenticationRequested event. + /// + /// + /// See the ICoreWebView2BasicAuthenticationRequestedEventHandler article. + /// + TCoreWebView2BasicAuthenticationRequestedEventHandler = class(TInterfacedObject, ICoreWebView2BasicAuthenticationRequestedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2BasicAuthenticationRequestedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives ContextMenuRequested events. + /// + /// + /// See the ICoreWebView2ContextMenuRequestedEventHandler article. + /// + TCoreWebView2ContextMenuRequestedEventHandler = class(TInterfacedObject, ICoreWebView2ContextMenuRequestedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ContextMenuRequestedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Raised to notify the host that the end user selected a custom + /// ContextMenuItem. CustomItemSelected event is raised on the specific + /// ContextMenuItem that the end user selected. + /// + /// + /// See the ICoreWebView2CustomItemSelectedEventHandler article. + /// + TCoreWebView2CustomItemSelectedEventHandler = class(TInterfacedObject, ICoreWebView2CustomItemSelectedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2ContextMenuItem; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives StatusBarTextChanged events. + /// + /// + /// See the ICoreWebView2StatusBarTextChangedEventHandler article. + /// + TCoreWebView2StatusBarTextChangedEventHandler = class(TInterfacedObject, ICoreWebView2StatusBarTextChangedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives PermissionRequested events for iframes. + /// + /// + /// See the ICoreWebView2FramePermissionRequestedEventHandler article. + /// + TCoreWebView2FramePermissionRequestedEventHandler = class(TInterfacedObject, ICoreWebView2FramePermissionRequestedEventHandler) + protected + FEvents : Pointer; + FFrameID : cardinal; + + function Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2PermissionRequestedEventArgs2): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); reintroduce; + destructor Destroy; override; + end; + + /// + /// The caller implements this interface to receive the ClearBrowsingData result. + /// + /// + /// See the ICoreWebView2ClearBrowsingDataCompletedHandler article. + /// + TCoreWebView2ClearBrowsingDataCompletedHandler = class(TInterfacedObject, ICoreWebView2ClearBrowsingDataCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives the result of the ClearServerCertificateErrorActions method. + /// + /// + /// See the ICoreWebView2ClearServerCertificateErrorActionsCompletedHandler article. + /// + TCoreWebView2ClearServerCertificateErrorActionsCompletedHandler = class(TInterfacedObject, ICoreWebView2ClearServerCertificateErrorActionsCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// An event handler for the ServerCertificateErrorDetected event. + /// + /// + /// See the ICoreWebView2ServerCertificateErrorDetectedEventHandler article. + /// + TCoreWebView2ServerCertificateErrorDetectedEventHandler = class(TInterfacedObject, ICoreWebView2ServerCertificateErrorDetectedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ServerCertificateErrorDetectedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// This interface is a handler for when the Favicon is changed. + /// The sender is the ICoreWebView2 object the top-level document of + /// which has changed favicon and the eventArgs is nullptr. Use the + /// FaviconUri property and GetFavicon method to obtain the favicon + /// data. The second argument is always null. + /// For more information see add_FaviconChanged. + /// + /// + /// See the ICoreWebView2FaviconChangedEventHandler article. + /// + TCoreWebView2FaviconChangedEventHandler = class(TInterfacedObject, ICoreWebView2FaviconChangedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// This interface is a handler for when the Favicon is changed. + /// The sender is the ICoreWebView2 object the top-level document of + /// which has changed favicon and the eventArgs is nullptr. Use the + /// FaviconUri property and GetFavicon method to obtain the favicon + /// data. The second argument is always null. + /// For more information see add_FaviconChanged. + /// + /// + /// See the ICoreWebView2FaviconChangedEventHandler article. + /// + TCoreWebView2GetFaviconCompletedHandler = class(TInterfacedObject, ICoreWebView2GetFaviconCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult; const result_: IStream): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives the result of the Print method. + /// + /// + /// See the ICoreWebView2PrintCompletedHandler article. + /// + TCoreWebView2PrintCompletedHandler = class(TInterfacedObject, ICoreWebView2PrintCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult; result_: COREWEBVIEW2_PRINT_STATUS): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives the result of the PrintToPdfStream method. + /// errorCode returns S_OK if the PrintToPdfStream operation succeeded. + /// The printable pdf data is returned in the pdfStream object. + /// + /// + /// See the ICoreWebView2PrintToPdfStreamCompletedHandler article. + /// + TCoreWebView2PrintToPdfStreamCompletedHandler = class(TInterfacedObject, ICoreWebView2PrintToPdfStreamCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult; const result_: IStream): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// The caller implements this interface to handle the result of + /// GetNonDefaultPermissionSettings. + /// + /// + /// See the ICoreWebView2GetNonDefaultPermissionSettingsCompletedHandler article. + /// + TCoreWebView2GetNonDefaultPermissionSettingsCompletedHandler = class(TInterfacedObject, ICoreWebView2GetNonDefaultPermissionSettingsCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult; const result_: ICoreWebView2PermissionSettingCollectionView): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// The caller implements this interface to handle the result of + /// SetPermissionState. + /// + /// + /// See the ICoreWebView2SetPermissionStateCompletedHandler article. + /// + TCoreWebView2SetPermissionStateCompletedHandler = class(TInterfacedObject, ICoreWebView2SetPermissionStateCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Event handler for the LaunchingExternalUriScheme event. + /// + /// + /// See the ICoreWebView2LaunchingExternalUriSchemeEventHandler article. + /// + TCoreWebView2LaunchingExternalUriSchemeEventHandler = class(TInterfacedObject, ICoreWebView2LaunchingExternalUriSchemeEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2LaunchingExternalUriSchemeEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives the result of the `GetProcessExtendedInfos` method. + /// The result is written to the collection of `ProcessExtendedInfo`s provided + /// in the `GetProcessExtendedInfos` method call. + /// + /// + /// See the ICoreWebView2GetProcessExtendedInfosCompletedHandler article. + /// + TCoreWebView2GetProcessExtendedInfosCompletedHandler = class(TInterfacedObject, ICoreWebView2GetProcessExtendedInfosCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult; const result_: ICoreWebView2ProcessExtendedInfoCollection): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// The caller implements this interface to receive the result of removing + /// the browser Extension from the Profile. + /// + /// + /// See the ICoreWebView2BrowserExtensionRemoveCompletedHandler article. + /// + TCoreWebView2BrowserExtensionRemoveCompletedHandler = class(TInterfacedObject, ICoreWebView2BrowserExtensionRemoveCompletedHandler) + protected + FEvents : Pointer; + FID : wvstring; + + function Invoke(errorCode: HResult): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; const aExtensionID: wvstring); reintroduce; + destructor Destroy; override; + end; + + /// + /// The caller implements this interface to receive the result of setting the + /// browser Extension as enabled or disabled. If enabled, the browser Extension is + /// running in WebView instances. If disabled, the browser Extension is not running in WebView instances. + /// + /// + /// See the ICoreWebView2BrowserExtensionEnableCompletedHandler article. + /// + TCoreWebView2BrowserExtensionEnableCompletedHandler = class(TInterfacedObject, ICoreWebView2BrowserExtensionEnableCompletedHandler) + protected + FEvents : Pointer; + FID : wvstring; + + function Invoke(errorCode: HResult): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; const aExtensionID: wvstring); reintroduce; + destructor Destroy; override; + end; + + /// + /// The caller implements this interface to receive the result + /// of loading an browser Extension. + /// + /// + /// See the ICoreWebView2ProfileAddBrowserExtensionCompletedHandler article. + /// + TCoreWebView2ProfileAddBrowserExtensionCompletedHandler = class(TInterfacedObject, ICoreWebView2ProfileAddBrowserExtensionCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult; const result_: ICoreWebView2BrowserExtension): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// The caller implements this interface to receive the result of + /// getting the browser Extensions. + /// + /// + /// See the ICoreWebView2ProfileGetBrowserExtensionsCompletedHandler article. + /// + TCoreWebView2ProfileGetBrowserExtensionsCompletedHandler = class(TInterfacedObject, ICoreWebView2ProfileGetBrowserExtensionsCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult; const result_: ICoreWebView2BrowserExtensionList): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives the `CoreWebView2Profile.Deleted` event. + /// + /// + /// See the ICoreWebView2ProfileDeletedEventHandler article. + /// + TCoreWebView2ProfileDeletedEventHandler = class(TInterfacedObject, ICoreWebView2ProfileDeletedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2Profile; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// This is the callback for ExecuteScriptWithResult + /// + /// + /// See the ICoreWebView2ExecuteScriptWithResultCompletedHandler article. + /// + TCoreWebView2ExecuteScriptWithResultCompletedHandler = class(TInterfacedObject, ICoreWebView2ExecuteScriptWithResultCompletedHandler) + protected + FEvents : Pointer; + FID : integer; + + function Invoke(errorCode: HResult; const result_: ICoreWebView2ExecuteScriptResult): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aExecutionID : integer); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `NonClientRegionChanged` events. + /// event. + /// + /// + /// See the ICoreWebView2NonClientRegionChangedEventHandler article. + /// + TCoreWebView2NonClientRegionChangedEventHandler = class(TInterfacedObject, ICoreWebView2NonClientRegionChangedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2CompositionController; + const args: ICoreWebView2NonClientRegionChangedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `NotificationReceived` events. + /// + /// + /// See the ICoreWebView2NotificationReceivedEventHandler article. + /// + TCoreWebView2NotificationReceivedEventHandler = class(TInterfacedObject, ICoreWebView2NotificationReceivedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2NotificationReceivedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `CloseRequested` events. + /// + /// + /// See the ICoreWebView2NotificationCloseRequestedEventHandler article. + /// + TCoreWebView2NotificationCloseRequestedEventHandler = class(TInterfacedObject, ICoreWebView2NotificationCloseRequestedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2Notification; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `SaveAsUIShowing` events. + /// + /// + /// See the ICoreWebView2SaveAsUIShowingEventHandler article. + /// + TCoreWebView2SaveAsUIShowingEventHandler = class(TInterfacedObject, ICoreWebView2SaveAsUIShowingEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2SaveAsUIShowingEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives the result of the `ShowSaveAsUI` method. + /// + /// + /// See the ICoreWebView2ShowSaveAsUICompletedHandler article. + /// + TCoreWebView2ShowSaveAsUICompletedHandler = class(TInterfacedObject, ICoreWebView2ShowSaveAsUICompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult; result_: COREWEBVIEW2_SAVE_AS_UI_RESULT): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `SaveFileSecurityCheckStarting` events. + /// + /// + /// See the ICoreWebView2SaveFileSecurityCheckStartingEventHandler article. + /// + TCoreWebView2SaveFileSecurityCheckStartingEventHandler = class(TInterfacedObject, ICoreWebView2SaveFileSecurityCheckStartingEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2SaveFileSecurityCheckStartingEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `ScreenCaptureStarting` events. + /// + /// + /// See the ICoreWebView2ScreenCaptureStartingEventHandler article. + /// + TCoreWebView2ScreenCaptureStartingEventHandler = class(TInterfacedObject, ICoreWebView2ScreenCaptureStartingEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ScreenCaptureStartingEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `ScreenCaptureStarting` events. + /// + /// + /// See the ICoreWebView2FrameScreenCaptureStartingEventHandler article. + /// + TCoreWebView2FrameScreenCaptureStartingEventHandler = class(TInterfacedObject, ICoreWebView2FrameScreenCaptureStartingEventHandler) + protected + FEvents : Pointer; + FFrameID : cardinal; + + function Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2ScreenCaptureStartingEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `FrameCreated` events. + /// + /// + /// See the ICoreWebView2FrameChildFrameCreatedEventHandler article. + /// + TCoreWebView2FrameChildFrameCreatedEventHandler = class(TInterfacedObject, ICoreWebView2FrameChildFrameCreatedEventHandler) + protected + FEvents : Pointer; + FFrameID : cardinal; + + function Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2FrameCreatedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `ActiveMatchIndexChanged` events. + /// + /// + /// See the ICoreWebView2FindActiveMatchIndexChangedEventHandler article. + /// + TCoreWebView2FindActiveMatchIndexChangedEventHandler = class(TInterfacedObject, ICoreWebView2FindActiveMatchIndexChangedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2Find; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `MatchCountChanged` events. + /// + /// + /// See the ICoreWebView2FindMatchCountChangedEventHandler article. + /// + TCoreWebView2FindMatchCountChangedEventHandler = class(TInterfacedObject, ICoreWebView2FindMatchCountChangedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2Find; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives the result of the `Start` method. + /// + /// + /// See the ICoreWebView2FindStartCompletedHandler article. + /// + TCoreWebView2FindStartCompletedHandler = class(TInterfacedObject, ICoreWebView2FindStartCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `DragStarting` events. + /// + /// + /// See the ICoreWebView2DragStartingEventHandler article. + /// + TCoreWebView2DragStartingEventHandler = class(TInterfacedObject, ICoreWebView2DragStartingEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2CompositionController; + const args: ICoreWebView2DragStartingEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `DedicatedWorkerCreated` events. + /// + /// + /// See the ICoreWebView2DedicatedWorkerCreatedEventHandler article. + /// + TCoreWebView2DedicatedWorkerCreatedEventHandler = class(TInterfacedObject, ICoreWebView2DedicatedWorkerCreatedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2DedicatedWorkerCreatedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `DedicatedWorkerCreated` events. + /// + /// + /// See the ICoreWebView2DedicatedWorkerDedicatedWorkerCreatedEventHandler article. + /// + TCoreWebView2DedicatedWorkerDedicatedWorkerCreatedEventHandler = class(TInterfacedObject, ICoreWebView2DedicatedWorkerDedicatedWorkerCreatedEventHandler) + protected + FEvents : Pointer; + FWorkerID : cardinal; + + function Invoke(const sender: ICoreWebView2DedicatedWorker; + const args: ICoreWebView2DedicatedWorkerCreatedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aWorkerID: cardinal); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `Destroying` events. + /// + /// + /// See the ICoreWebView2DedicatedWorkerDestroyingEventHandler article. + /// + TCoreWebView2DedicatedWorkerDestroyingEventHandler = class(TInterfacedObject, ICoreWebView2DedicatedWorkerDestroyingEventHandler) + protected + FEvents : Pointer; + FWorkerID : cardinal; + + function Invoke(const sender: ICoreWebView2DedicatedWorker; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aWorkerID: cardinal); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `WebMessageReceived` events. + /// + /// + /// See the ICoreWebView2DedicatedWorkerWebMessageReceivedEventHandler article. + /// + TCoreWebView2DedicatedWorkerWebMessageReceivedEventHandler = class(TInterfacedObject, ICoreWebView2DedicatedWorkerWebMessageReceivedEventHandler) + protected + FEvents : Pointer; + FWorkerID : cardinal; + + function Invoke(const sender: ICoreWebView2DedicatedWorker; const args: ICoreWebView2WebMessageReceivedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aWorkerID: cardinal); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `DedicatedWorkerCreated` events. + /// + /// + /// See the ICoreWebView2FrameDedicatedWorkerCreatedEventHandler article. + /// + TCoreWebView2FrameDedicatedWorkerCreatedEventHandler = class(TInterfacedObject, ICoreWebView2FrameDedicatedWorkerCreatedEventHandler) + protected + FEvents : Pointer; + FFrameID : cardinal; + + function Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2DedicatedWorkerCreatedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `Destroying` events. + /// + /// + /// See the ICoreWebView2ServiceWorkerDestroyingEventHandler article. + /// + TCoreWebView2ServiceWorkerDestroyingEventHandler = class(TInterfacedObject, ICoreWebView2ServiceWorkerDestroyingEventHandler) + protected + FEvents : Pointer; + FWorkerID : cardinal; + + function Invoke(const sender: ICoreWebView2ServiceWorker; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aWorkerID : cardinal); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `WebMessageReceived` events. + /// + /// + /// See the ICoreWebView2ServiceWorkerWebMessageReceivedEventHandler article. + /// + TCoreWebView2ServiceWorkerWebMessageReceivedEventHandler = class(TInterfacedObject, ICoreWebView2ServiceWorkerWebMessageReceivedEventHandler) + protected + FEvents : Pointer; + FWorkerID : cardinal; + + function Invoke(const sender: ICoreWebView2ServiceWorker; const args: ICoreWebView2WebMessageReceivedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aWorkerID : cardinal); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `ServiceWorkerRegistered` events. + /// + /// + /// See the ICoreWebView2ServiceWorkerRegisteredEventHandler article. + /// + TCoreWebView2ServiceWorkerRegisteredEventHandler = class(TInterfacedObject, ICoreWebView2ServiceWorkerRegisteredEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2ServiceWorkerManager; const args: ICoreWebView2ServiceWorkerRegisteredEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives the result of the `GetServiceWorkerRegistrations` method. + /// + /// + /// See the ICoreWebView2GetServiceWorkerRegistrationsCompletedHandler article. + /// + TCoreWebView2GetServiceWorkerRegistrationsCompletedHandler = class(TInterfacedObject, ICoreWebView2GetServiceWorkerRegistrationsCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult; const result_: ICoreWebView2ServiceWorkerRegistrationCollectionView): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `ServiceWorkerActivated` events. + /// + /// + /// See the ICoreWebView2ServiceWorkerActivatedEventHandler article. + /// + TCoreWebView2ServiceWorkerActivatedEventHandler = class(TInterfacedObject, ICoreWebView2ServiceWorkerActivatedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2ServiceWorkerRegistration; const args: ICoreWebView2ServiceWorkerActivatedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `Unregistering` events. + /// + /// + /// See the ICoreWebView2ServiceWorkerRegistrationUnregisteringEventHandler article. + /// + TCoreWebView2ServiceWorkerRegistrationUnregisteringEventHandler = class(TInterfacedObject, ICoreWebView2ServiceWorkerRegistrationUnregisteringEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2ServiceWorkerRegistration; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `SharedWorkerCreated` events. + /// + /// + /// See the ICoreWebView2SharedWorkerCreatedEventHandler article. + /// + TCoreWebView2SharedWorkerCreatedEventHandler = class(TInterfacedObject, ICoreWebView2SharedWorkerCreatedEventHandler) + protected + FEvents : Pointer; + + function Invoke(const sender: ICoreWebView2SharedWorkerManager; const args: ICoreWebView2SharedWorkerCreatedEventArgs): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives the result of the `GetSharedWorkers` method. + /// + /// + /// See the ICoreWebView2GetSharedWorkersCompletedHandler article. + /// + TCoreWebView2GetSharedWorkersCompletedHandler = class(TInterfacedObject, ICoreWebView2GetSharedWorkersCompletedHandler) + protected + FEvents : Pointer; + + function Invoke(errorCode: HResult; const result_: ICoreWebView2SharedWorkerCollectionView): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents); reintroduce; + destructor Destroy; override; + end; + + /// + /// Receives `Destroying` events. + /// + /// + /// See the ICoreWebView2SharedWorkerDestroyingEventHandler article. + /// + TCoreWebView2SharedWorkerDestroyingEventHandler = class(TInterfacedObject, ICoreWebView2SharedWorkerDestroyingEventHandler) + protected + FEvents : Pointer; + FWorkerID : cardinal; + + function Invoke(const sender: ICoreWebView2SharedWorker; const args: IUnknown): HResult; stdcall; + + public + constructor Create(const aEvents: IWVBrowserEvents; aWorkerID : cardinal); reintroduce; + destructor Destroy; override; + end; + + +implementation + + +// TCoreWebView2AcceleratorKeyPressedEventHandler + +constructor TCoreWebView2AcceleratorKeyPressedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2AcceleratorKeyPressedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2AcceleratorKeyPressedEventHandler.Invoke(const sender: ICoreWebView2Controller; const args: ICoreWebView2AcceleratorKeyPressedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).AcceleratorKeyPressedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2CapturePreviewCompletedHandler + +constructor TCoreWebView2CapturePreviewCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2CapturePreviewCompletedHandler.Destroy; +begin + inherited Destroy; + + FEvents := nil; +end; + +function TCoreWebView2CapturePreviewCompletedHandler.Invoke(errorCode: HResult): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).CapturePreviewCompletedHandler_Invoke(errorCode) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ContainsFullScreenElementChangedEventHandler + +constructor TCoreWebView2ContainsFullScreenElementChangedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2ContainsFullScreenElementChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ContainsFullScreenElementChangedEventHandler.Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ContainsFullScreenElementChangedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ContentLoadingEventHandler + +constructor TCoreWebView2ContentLoadingEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2ContentLoadingEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ContentLoadingEventHandler.Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2ContentLoadingEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ContentLoadingEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2CreateCoreWebView2ControllerCompletedHandler + +constructor TCoreWebView2CreateCoreWebView2ControllerCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2CreateCoreWebView2ControllerCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2CreateCoreWebView2ControllerCompletedHandler.Invoke(errorCode: HResult; const result_: ICoreWebView2Controller): HResult; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ControllerCompletedHandler_Invoke(errorCode, result_) + else + Result := E_FAIL; +end; + + +// TCoreWebView2DevToolsProtocolEventReceivedEventHandler + +constructor TCoreWebView2DevToolsProtocolEventReceivedEventHandler.Create(const aEvents: IWVBrowserEvents; const aEventName : wvstring; aEventID : integer); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FEventName := aEventName; + FEventID := aEventID; +end; + +destructor TCoreWebView2DevToolsProtocolEventReceivedEventHandler.Destroy; +begin + inherited Destroy; + + FEvents := nil; +end; + +function TCoreWebView2DevToolsProtocolEventReceivedEventHandler.Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DevToolsProtocolEventReceivedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).DevToolsProtocolEventReceivedEventHandler_Invoke(sender, args, FEventName, FEventID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2DocumentTitleChangedEventHandler + +constructor TCoreWebView2DocumentTitleChangedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2DocumentTitleChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2DocumentTitleChangedEventHandler.Invoke(const sender : ICoreWebView2; + const args : IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).DocumentTitleChangedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2EnvironmentCompletedHandler + +constructor TCoreWebView2EnvironmentCompletedHandler.Create(const aBrowserEvents: IWVBrowserEvents); +begin + inherited Create; + + FBrowserEvents := Pointer(aBrowserEvents); + FLoaderEvents := nil; +end; + +constructor TCoreWebView2EnvironmentCompletedHandler.Create(const aLoaderEvents: IWVLoaderEvents); +begin + inherited Create; + + FBrowserEvents := nil; + FLoaderEvents := Pointer(aLoaderEvents); +end; + +destructor TCoreWebView2EnvironmentCompletedHandler.Destroy; +begin + FBrowserEvents := nil; + FLoaderEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2EnvironmentCompletedHandler.Invoke( errorCode : HResult; + const result_ : ICoreWebView2Environment): HResult; +begin + if (FBrowserEvents <> nil) then + Result := IWVBrowserEvents(FBrowserEvents).EnvironmentCompletedHandler_Invoke(errorCode, result_) + else + if (FLoaderEvents <> nil) then + Result := IWVLoaderEvents(FLoaderEvents).EnvironmentCompletedHandler_Invoke(errorCode, result_) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ExecuteScriptCompletedHandler + +constructor TCoreWebView2ExecuteScriptCompletedHandler.Create(const aEvents: IWVBrowserEvents; aExecutionID : integer); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FID := aExecutionID; +end; + +destructor TCoreWebView2ExecuteScriptCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ExecuteScriptCompletedHandler.Invoke(errorCode: HResult; result_: PWideChar): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ExecuteScriptCompletedHandler_Invoke(errorCode, result_, FID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2FrameNavigationCompletedEventHandler + +constructor TCoreWebView2FrameNavigationCompletedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2FrameNavigationCompletedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2FrameNavigationCompletedEventHandler.Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NavigationCompletedEventArgs): HResult; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).FrameNavigationCompletedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2FrameNavigationStartingEventHandler + +constructor TCoreWebView2FrameNavigationStartingEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2FrameNavigationStartingEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2FrameNavigationStartingEventHandler.Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2NavigationStartingEventArgs): HResult; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).FrameNavigationStartingEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2GotFocusEventHandler + +constructor TCoreWebView2GotFocusEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2GotFocusEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2GotFocusEventHandler.Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).GotFocusEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2HistoryChangedEventHandler + +constructor TCoreWebView2HistoryChangedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2HistoryChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2HistoryChangedEventHandler.Invoke(const sender : ICoreWebView2; + const args : IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).HistoryChangedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2LostFocusEventHandler + +constructor TCoreWebView2LostFocusEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2LostFocusEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2LostFocusEventHandler.Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).LostFocusEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2MoveFocusRequestedEventHandler + +constructor TCoreWebView2MoveFocusRequestedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2MoveFocusRequestedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2MoveFocusRequestedEventHandler.Invoke(const sender: ICoreWebView2Controller; const args: ICoreWebView2MoveFocusRequestedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).MoveFocusRequestedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2NavigationCompletedEventHandler + +constructor TCoreWebView2NavigationCompletedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2NavigationCompletedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2NavigationCompletedEventHandler.Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NavigationCompletedEventArgs): HResult; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).NavigationCompletedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2NavigationStartingEventHandler + +constructor TCoreWebView2NavigationStartingEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2NavigationStartingEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2NavigationStartingEventHandler.Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2NavigationStartingEventArgs): HResult; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).NavigationStartingEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2NewBrowserVersionAvailableEventHandler + +constructor TCoreWebView2NewBrowserVersionAvailableEventHandler.Create(const aEvents: IWVLoaderEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2NewBrowserVersionAvailableEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2NewBrowserVersionAvailableEventHandler.Invoke(const sender: ICoreWebView2Environment; const args: IUnknown): HResult; +begin + if (FEvents <> nil) then + Result := IWVLoaderEvents(FEvents).NewBrowserVersionAvailableEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2NewWindowRequestedEventHandler + +constructor TCoreWebView2NewWindowRequestedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2NewWindowRequestedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2NewWindowRequestedEventHandler.Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2NewWindowRequestedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).NewWindowRequestedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2PermissionRequestedEventHandler + +constructor TCoreWebView2PermissionRequestedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2PermissionRequestedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2PermissionRequestedEventHandler.Invoke(const sender: ICoreWebView2; const args: ICoreWebView2PermissionRequestedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).PermissionRequestedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ProcessFailedEventHandler + +constructor TCoreWebView2ProcessFailedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2ProcessFailedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ProcessFailedEventHandler.Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ProcessFailedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ProcessFailedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ScriptDialogOpeningEventHandler + +constructor TCoreWebView2ScriptDialogOpeningEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2ScriptDialogOpeningEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ScriptDialogOpeningEventHandler.Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ScriptDialogOpeningEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ScriptDialogOpeningEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2SourceChangedEventHandler + +constructor TCoreWebView2SourceChangedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2SourceChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2SourceChangedEventHandler.Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2SourceChangedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).SourceChangedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2WebMessageReceivedEventHandler + +constructor TCoreWebView2WebMessageReceivedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2WebMessageReceivedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2WebMessageReceivedEventHandler.Invoke(const sender: ICoreWebView2; const args: ICoreWebView2WebMessageReceivedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).WebMessageReceivedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2WebResourceRequestedEventHandler + +constructor TCoreWebView2WebResourceRequestedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2WebResourceRequestedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2WebResourceRequestedEventHandler.Invoke(const sender: ICoreWebView2; const args: ICoreWebView2WebResourceRequestedEventArgs): HResult; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).WebResourceRequestedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2WindowCloseRequestedEventHandler + +constructor TCoreWebView2WindowCloseRequestedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2WindowCloseRequestedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2WindowCloseRequestedEventHandler.Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).WindowCloseRequestedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ZoomFactorChangedEventHandler + +constructor TCoreWebView2ZoomFactorChangedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2ZoomFactorChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ZoomFactorChangedEventHandler.Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ZoomFactorChangedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler + +constructor TCoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler.Invoke(errorCode: HResult; const result_: ICoreWebView2CompositionController): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).CreateCoreWebView2CompositionControllerCompletedHandler_Invoke(errorCode, result_) + else + Result := E_FAIL; +end; + + +// ICoreWebView2CursorChangedEventHandler + +constructor TCoreWebView2CursorChangedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2CursorChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2CursorChangedEventHandler.Invoke(const sender: ICoreWebView2CompositionController; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).CursorChangedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2BrowserProcessExitedEventHandler + +constructor TCoreWebView2BrowserProcessExitedEventHandler.Create(const aBrowserEvents: IWVBrowserEvents); +begin + inherited Create; + + FBrowserEvents := Pointer(aBrowserEvents); + FLoaderEvents := nil; +end; + +constructor TCoreWebView2BrowserProcessExitedEventHandler.Create(const aLoaderEvents: IWVLoaderEvents); +begin + inherited Create; + + FBrowserEvents := nil; + FLoaderEvents := Pointer(aLoaderEvents); +end; + +destructor TCoreWebView2BrowserProcessExitedEventHandler.Destroy; +begin + FBrowserEvents := nil; + FLoaderEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2BrowserProcessExitedEventHandler.Invoke(const sender: ICoreWebView2Environment; const args: ICoreWebView2BrowserProcessExitedEventArgs): HResult; stdcall; +begin + if (FBrowserEvents <> nil) then + Result := IWVBrowserEvents(FBrowserEvents).BrowserProcessExitedEventHandler_Invoke(sender, args) + else + if (FLoaderEvents <> nil) then + Result := IWVLoaderEvents(FLoaderEvents).BrowserProcessExitedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2RasterizationScaleChangedEventHandler + +constructor TCoreWebView2RasterizationScaleChangedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2RasterizationScaleChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2RasterizationScaleChangedEventHandler.Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).RasterizationScaleChangedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + + +// TCoreWebView2WebResourceResponseReceivedEventHandler + +constructor TCoreWebView2WebResourceResponseReceivedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2WebResourceResponseReceivedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2WebResourceResponseReceivedEventHandler.Invoke(const sender: ICoreWebView2; const args: ICoreWebView2WebResourceResponseReceivedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).WebResourceResponseReceivedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2DOMContentLoadedEventHandler + +constructor TCoreWebView2DOMContentLoadedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2DOMContentLoadedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2DOMContentLoadedEventHandler.Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DOMContentLoadedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).DOMContentLoadedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2WebResourceResponseViewGetContentCompletedHandler + +constructor TCoreWebView2WebResourceResponseViewGetContentCompletedHandler.Create(const aEvents: IWVBrowserEvents; aResourceID : integer); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FResourceID := aResourceID; +end; + +destructor TCoreWebView2WebResourceResponseViewGetContentCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2WebResourceResponseViewGetContentCompletedHandler.Invoke(errorCode: HResult; const result_: IStream): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).WebResourceResponseViewGetContentCompletedHandler_Invoke(errorCode, result_, FResourceID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2GetCookiesCompletedHandler + +constructor TCoreWebView2GetCookiesCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2GetCookiesCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2GetCookiesCompletedHandler.Invoke(errorCode : HResult; const result_ : ICoreWebView2CookieList): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).GetCookiesCompletedHandler_Invoke(errorCode, result_) + else + Result := E_FAIL; +end; + + +// TCoreWebView2TrySuspendCompletedHandler + +constructor TCoreWebView2TrySuspendCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2TrySuspendCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2TrySuspendCompletedHandler.Invoke(errorCode: HResult; result_: Integer): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).TrySuspendCompletedHandler_Invoke(errorCode, result_) + else + Result := E_FAIL; +end; + + +// TCoreWebView2FrameCreatedEventHandler + +constructor TCoreWebView2FrameCreatedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2FrameCreatedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2FrameCreatedEventHandler.Invoke(const sender: ICoreWebView2; const args: ICoreWebView2FrameCreatedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).FrameCreatedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2DownloadStartingEventHandler + +constructor TCoreWebView2DownloadStartingEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2DownloadStartingEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2DownloadStartingEventHandler.Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DownloadStartingEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).DownloadStartingEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ClientCertificateRequestedEventHandler + +constructor TCoreWebView2ClientCertificateRequestedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2ClientCertificateRequestedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ClientCertificateRequestedEventHandler.Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ClientCertificateRequestedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ClientCertificateRequestedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2PrintToPdfCompletedHandler + +constructor TCoreWebView2PrintToPdfCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2PrintToPdfCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2PrintToPdfCompletedHandler.Invoke(errorCode: HResult; result_: Integer): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).PrintToPdfCompletedHandler_Invoke(errorCode, result_) + else + Result := E_FAIL; +end; + + +// TCoreWebView2BytesReceivedChangedEventHandler + +constructor TCoreWebView2BytesReceivedChangedEventHandler.Create(const aEvents: IWVBrowserEvents; aDownloadID : integer); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FDownloadID := aDownloadID; +end; + +destructor TCoreWebView2BytesReceivedChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2BytesReceivedChangedEventHandler.Invoke(const sender: ICoreWebView2DownloadOperation; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).BytesReceivedChangedEventHandler_Invoke(sender, args, FDownloadID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2EstimatedEndTimeChangedEventHandler + +constructor TCoreWebView2EstimatedEndTimeChangedEventHandler.Create(const aEvents: IWVBrowserEvents; aDownloadID : integer); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FDownloadID := aDownloadID; +end; + +destructor TCoreWebView2EstimatedEndTimeChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2EstimatedEndTimeChangedEventHandler.Invoke(const sender: ICoreWebView2DownloadOperation; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).EstimatedEndTimeChangedEventHandler_Invoke(sender, args, FDownloadID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2StateChangedEventHandler + +constructor TCoreWebView2StateChangedEventHandler.Create(const aEvents: IWVBrowserEvents; aDownloadID : integer); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FDownloadID := aDownloadID; +end; + +destructor TCoreWebView2StateChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2StateChangedEventHandler.Invoke(const sender: ICoreWebView2DownloadOperation; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).StateChangedEventHandler_Invoke(sender, args, FDownloadID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2FrameNameChangedEventHandler + +constructor TCoreWebView2FrameNameChangedEventHandler.Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FFrameID := aFrameID; +end; + +destructor TCoreWebView2FrameNameChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2FrameNameChangedEventHandler.Invoke(const sender: ICoreWebView2Frame; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).FrameNameChangedEventHandler_Invoke(sender, args, FFrameID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2FrameDestroyedEventHandler + +constructor TCoreWebView2FrameDestroyedEventHandler.Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FFrameID := aFrameID; +end; + +destructor TCoreWebView2FrameDestroyedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2FrameDestroyedEventHandler.Invoke(const sender: ICoreWebView2Frame; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).FrameDestroyedEventHandler_Invoke(sender, args, FFrameID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2CallDevToolsProtocolMethodCompletedHandler + +constructor TCoreWebView2CallDevToolsProtocolMethodCompletedHandler.Create(const aEvents: IWVBrowserEvents; aExecutionID : integer); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FID := aExecutionID; +end; + +destructor TCoreWebView2CallDevToolsProtocolMethodCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2CallDevToolsProtocolMethodCompletedHandler.Invoke(errorCode: HResult; result_: PWideChar): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).CallDevToolsProtocolMethodCompletedHandler_Invoke(errorCode, result_, FID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler + +constructor TCoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler.Invoke(errorCode: HResult; result_: PWideChar): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).AddScriptToExecuteOnDocumentCreatedCompletedHandler_Invoke(errorCode, result_) + else + Result := E_FAIL; +end; + + +// TCoreWebView2IsMutedChangedEventHandler + +constructor TCoreWebView2IsMutedChangedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2IsMutedChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2IsMutedChangedEventHandler.Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).IsMutedChangedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2IsDocumentPlayingAudioChangedEventHandler + +constructor TCoreWebView2IsDocumentPlayingAudioChangedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2IsDocumentPlayingAudioChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2IsDocumentPlayingAudioChangedEventHandler.Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).IsDocumentPlayingAudioChangedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2IsDefaultDownloadDialogOpenChangedEventHandler + +constructor TCoreWebView2IsDefaultDownloadDialogOpenChangedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2IsDefaultDownloadDialogOpenChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2IsDefaultDownloadDialogOpenChangedEventHandler.Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).IsDefaultDownloadDialogOpenChangedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ProcessInfosChangedEventHandler + +constructor TCoreWebView2ProcessInfosChangedEventHandler.Create(const aBrowserEvents: IWVBrowserEvents); +begin + inherited Create; + + FBrowserEvents := Pointer(aBrowserEvents); + FLoaderEvents := nil; +end; + +constructor TCoreWebView2ProcessInfosChangedEventHandler.Create(const aLoaderEvents: IWVLoaderEvents); +begin + inherited Create; + + FBrowserEvents := nil; + FLoaderEvents := Pointer(aLoaderEvents); +end; + +destructor TCoreWebView2ProcessInfosChangedEventHandler.Destroy; +begin + FBrowserEvents := nil; + FLoaderEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ProcessInfosChangedEventHandler.Invoke(const sender: ICoreWebView2Environment; const args: IUnknown): HResult; stdcall; +begin + if (FBrowserEvents <> nil) then + Result := IWVBrowserEvents(FBrowserEvents).ProcessInfosChangedEventHandler_Invoke(sender, args) + else + if (FLoaderEvents <> nil) then + Result := IWVLoaderEvents(FLoaderEvents).ProcessInfosChangedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2FrameNavigationCompletedEventHandler2 + +constructor TCoreWebView2FrameNavigationCompletedEventHandler2.Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FFrameID := aFrameID; +end; + +destructor TCoreWebView2FrameNavigationCompletedEventHandler2.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2FrameNavigationCompletedEventHandler2.Invoke(const sender : ICoreWebView2Frame; + const args : ICoreWebView2NavigationCompletedEventArgs): HResult; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).FrameNavigationCompletedEventHandler2_Invoke(sender, args, FFrameID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2FrameNavigationStartingEventHandler2 + +constructor TCoreWebView2FrameNavigationStartingEventHandler2.Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FFrameID := aFrameID; +end; + +destructor TCoreWebView2FrameNavigationStartingEventHandler2.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2FrameNavigationStartingEventHandler2.Invoke(const sender : ICoreWebView2Frame; + const args : ICoreWebView2NavigationStartingEventArgs): HResult; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).FrameNavigationStartingEventHandler2_Invoke(sender, args, FFrameID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2FrameContentLoadingEventHandler + +constructor TCoreWebView2FrameContentLoadingEventHandler.Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FFrameID := aFrameID; +end; + +destructor TCoreWebView2FrameContentLoadingEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2FrameContentLoadingEventHandler.Invoke(const sender : ICoreWebView2Frame; + const args : ICoreWebView2ContentLoadingEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).FrameContentLoadingEventHandler_Invoke(sender, args, FFrameID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2FrameDOMContentLoadedEventHandler + +constructor TCoreWebView2FrameDOMContentLoadedEventHandler.Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FFrameID := aFrameID; +end; + +destructor TCoreWebView2FrameDOMContentLoadedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2FrameDOMContentLoadedEventHandler.Invoke(const sender : ICoreWebView2Frame; + const args : ICoreWebView2DOMContentLoadedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).FrameDOMContentLoadedEventHandler_Invoke(sender, args, FFrameID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2FrameWebMessageReceivedEventHandler + +constructor TCoreWebView2FrameWebMessageReceivedEventHandler.Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FFrameID := aFrameID; +end; + +destructor TCoreWebView2FrameWebMessageReceivedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2FrameWebMessageReceivedEventHandler.Invoke(const sender : ICoreWebView2Frame; + const args : ICoreWebView2WebMessageReceivedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).FrameWebMessageReceivedEventHandler_Invoke(sender, args, FFrameID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2BasicAuthenticationRequestedEventHandler + +constructor TCoreWebView2BasicAuthenticationRequestedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2BasicAuthenticationRequestedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2BasicAuthenticationRequestedEventHandler.Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2BasicAuthenticationRequestedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).BasicAuthenticationRequestedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ContextMenuRequestedEventHandler + +constructor TCoreWebView2ContextMenuRequestedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2ContextMenuRequestedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ContextMenuRequestedEventHandler.Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2ContextMenuRequestedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ContextMenuRequestedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2CustomItemSelectedEventHandler + +constructor TCoreWebView2CustomItemSelectedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2CustomItemSelectedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2CustomItemSelectedEventHandler.Invoke(const sender : ICoreWebView2ContextMenuItem; + const args : IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).CustomItemSelectedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2StatusBarTextChangedEventHandler + +constructor TCoreWebView2StatusBarTextChangedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2StatusBarTextChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2StatusBarTextChangedEventHandler.Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).StatusBarTextChangedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2FramePermissionRequestedEventHandler + +constructor TCoreWebView2FramePermissionRequestedEventHandler.Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FFrameID := aFrameID; +end; + +destructor TCoreWebView2FramePermissionRequestedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2FramePermissionRequestedEventHandler.Invoke(const sender : ICoreWebView2Frame; + const args : ICoreWebView2PermissionRequestedEventArgs2): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).FramePermissionRequestedEventHandler_Invoke(sender, args, FFrameID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ClearBrowsingDataCompletedHandler + +constructor TCoreWebView2ClearBrowsingDataCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2ClearBrowsingDataCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ClearBrowsingDataCompletedHandler.Invoke(errorCode: HResult): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ClearBrowsingDataCompletedHandler_Invoke(errorCode) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ClearServerCertificateErrorActionsCompletedHandler + +constructor TCoreWebView2ClearServerCertificateErrorActionsCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2ClearServerCertificateErrorActionsCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ClearServerCertificateErrorActionsCompletedHandler.Invoke(errorCode: HResult): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ClearServerCertificateErrorActionsCompletedHandler_Invoke(errorCode) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ServerCertificateErrorDetectedEventHandler + +constructor TCoreWebView2ServerCertificateErrorDetectedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2ServerCertificateErrorDetectedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ServerCertificateErrorDetectedEventHandler.Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2ServerCertificateErrorDetectedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ServerCertificateErrorDetectedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2FaviconChangedEventHandler + +constructor TCoreWebView2FaviconChangedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2FaviconChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2FaviconChangedEventHandler.Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).FaviconChangedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2GetFaviconCompletedHandler + +constructor TCoreWebView2GetFaviconCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2GetFaviconCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2GetFaviconCompletedHandler.Invoke(errorCode: HResult; const result_: IStream): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).GetFaviconCompletedHandler_Invoke(errorCode, result_) + else + Result := E_FAIL; +end; + + +// TCoreWebView2PrintToPdfStreamCompletedHandler + +constructor TCoreWebView2PrintCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2PrintCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2PrintCompletedHandler.Invoke(errorCode: HResult; result_: COREWEBVIEW2_PRINT_STATUS): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).PrintCompletedHandler_Invoke(errorCode, result_) + else + Result := E_FAIL; +end; + + +// TCoreWebView2PrintToPdfStreamCompletedHandler + +constructor TCoreWebView2PrintToPdfStreamCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2PrintToPdfStreamCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2PrintToPdfStreamCompletedHandler.Invoke(errorCode: HResult; const result_: IStream): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).PrintToPdfStreamCompletedHandler_Invoke(errorCode, result_) + else + Result := E_FAIL; +end; + + +// TCoreWebView2GetNonDefaultPermissionSettingsCompletedHandler + +constructor TCoreWebView2GetNonDefaultPermissionSettingsCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2GetNonDefaultPermissionSettingsCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2GetNonDefaultPermissionSettingsCompletedHandler.Invoke(errorCode: HResult; const result_: ICoreWebView2PermissionSettingCollectionView): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).GetNonDefaultPermissionSettingsCompletedHandler_Invoke(errorCode, result_) + else + Result := E_FAIL; +end; + + +// TCoreWebView2SetPermissionStateCompletedHandler + +constructor TCoreWebView2SetPermissionStateCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2SetPermissionStateCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2SetPermissionStateCompletedHandler.Invoke(errorCode: HResult): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).SetPermissionStateCompletedHandler_Invoke(errorCode) + else + Result := E_FAIL; +end; + + +// TCoreWebView2LaunchingExternalUriSchemeEventHandler + +constructor TCoreWebView2LaunchingExternalUriSchemeEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2LaunchingExternalUriSchemeEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2LaunchingExternalUriSchemeEventHandler.Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2LaunchingExternalUriSchemeEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).LaunchingExternalUriSchemeEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2GetProcessExtendedInfosCompletedHandler + +constructor TCoreWebView2GetProcessExtendedInfosCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2GetProcessExtendedInfosCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2GetProcessExtendedInfosCompletedHandler.Invoke(errorCode: HResult; const result_: ICoreWebView2ProcessExtendedInfoCollection): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).GetProcessExtendedInfosCompletedHandler_Invoke(errorCode, result_) + else + Result := E_FAIL; +end; + + +// TCoreWebView2BrowserExtensionRemoveCompletedHandler + +constructor TCoreWebView2BrowserExtensionRemoveCompletedHandler.Create(const aEvents: IWVBrowserEvents; const aExtensionID: wvstring); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FID := aExtensionID; +end; + +destructor TCoreWebView2BrowserExtensionRemoveCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2BrowserExtensionRemoveCompletedHandler.Invoke(errorCode: HResult): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).BrowserExtensionRemoveCompletedHandler_Invoke(errorCode, FID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2BrowserExtensionEnableCompletedHandler + +constructor TCoreWebView2BrowserExtensionEnableCompletedHandler.Create(const aEvents: IWVBrowserEvents; const aExtensionID: wvstring); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FID := aExtensionID; +end; + +destructor TCoreWebView2BrowserExtensionEnableCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2BrowserExtensionEnableCompletedHandler.Invoke(errorCode: HResult): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).BrowserExtensionEnableCompletedHandler_Invoke(errorCode, FID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ProfileAddBrowserExtensionCompletedHandler + +constructor TCoreWebView2ProfileAddBrowserExtensionCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2ProfileAddBrowserExtensionCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ProfileAddBrowserExtensionCompletedHandler.Invoke(errorCode: HResult; const result_: ICoreWebView2BrowserExtension): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ProfileAddBrowserExtensionCompletedHandler_Invoke(errorCode, result_) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ProfileGetBrowserExtensionsCompletedHandler + +constructor TCoreWebView2ProfileGetBrowserExtensionsCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2ProfileGetBrowserExtensionsCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ProfileGetBrowserExtensionsCompletedHandler.Invoke(errorCode: HResult; const result_: ICoreWebView2BrowserExtensionList): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ProfileGetBrowserExtensionsCompletedHandler_Invoke(errorCode, result_) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ProfileDeletedEventHandler + +constructor TCoreWebView2ProfileDeletedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2ProfileDeletedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ProfileDeletedEventHandler.Invoke(const sender: ICoreWebView2Profile; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ProfileDeletedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ExecuteScriptWithResultCompletedHandler + +constructor TCoreWebView2ExecuteScriptWithResultCompletedHandler.Create(const aEvents: IWVBrowserEvents; aExecutionID : integer); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FID := aExecutionID; +end; + +destructor TCoreWebView2ExecuteScriptWithResultCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ExecuteScriptWithResultCompletedHandler.Invoke(errorCode: HResult; const result_: ICoreWebView2ExecuteScriptResult): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ExecuteScriptWithResultCompletedHandler_Invoke(errorCode, result_, FID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2NonClientRegionChangedEventHandler + +constructor TCoreWebView2NonClientRegionChangedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2NonClientRegionChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2NonClientRegionChangedEventHandler.Invoke(const sender : ICoreWebView2CompositionController; + const args : ICoreWebView2NonClientRegionChangedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).NonClientRegionChangedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2NotificationReceivedEventHandler + +constructor TCoreWebView2NotificationReceivedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2NotificationReceivedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2NotificationReceivedEventHandler.Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2NotificationReceivedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).NotificationReceivedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2NotificationCloseRequestedEventHandler + +constructor TCoreWebView2NotificationCloseRequestedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2NotificationCloseRequestedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2NotificationCloseRequestedEventHandler.Invoke(const sender: ICoreWebView2Notification; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).NotificationCloseRequestedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2SaveAsUIShowingEventHandler + +constructor TCoreWebView2SaveAsUIShowingEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2SaveAsUIShowingEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2SaveAsUIShowingEventHandler.Invoke(const sender: ICoreWebView2; const args: ICoreWebView2SaveAsUIShowingEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).SaveAsUIShowingEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ShowSaveAsUICompletedHandler + +constructor TCoreWebView2ShowSaveAsUICompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2ShowSaveAsUICompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ShowSaveAsUICompletedHandler.Invoke(errorCode: HResult; result_: COREWEBVIEW2_SAVE_AS_UI_RESULT): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ShowSaveAsUICompletedHandler_Invoke(errorCode, result_) + else + Result := E_FAIL; +end; + + +// TCoreWebView2SaveFileSecurityCheckStartingEventHandler + +constructor TCoreWebView2SaveFileSecurityCheckStartingEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2SaveFileSecurityCheckStartingEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2SaveFileSecurityCheckStartingEventHandler.Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2SaveFileSecurityCheckStartingEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).SaveFileSecurityCheckStartingEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ScreenCaptureStartingEventHandler + +constructor TCoreWebView2ScreenCaptureStartingEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2ScreenCaptureStartingEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ScreenCaptureStartingEventHandler.Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ScreenCaptureStartingEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ScreenCaptureStartingEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2FrameScreenCaptureStartingEventHandler + +constructor TCoreWebView2FrameScreenCaptureStartingEventHandler.Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FFrameID := aFrameID; +end; + +destructor TCoreWebView2FrameScreenCaptureStartingEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2FrameScreenCaptureStartingEventHandler.Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2ScreenCaptureStartingEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).FrameScreenCaptureStartingEventHandler_Invoke(sender, args, FFrameID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2FrameChildFrameCreatedEventHandler + +constructor TCoreWebView2FrameChildFrameCreatedEventHandler.Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FFrameID := aFrameID; +end; + +destructor TCoreWebView2FrameChildFrameCreatedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2FrameChildFrameCreatedEventHandler.Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2FrameCreatedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).FrameChildFrameCreatedEventHandler_Invoke(sender, args, FFrameID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2FindActiveMatchIndexChangedEventHandler + +constructor TCoreWebView2FindActiveMatchIndexChangedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2FindActiveMatchIndexChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2FindActiveMatchIndexChangedEventHandler.Invoke(const sender : ICoreWebView2Find; + const args : IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).FindActiveMatchIndexChangedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2FindMatchCountChangedEventHandler + +constructor TCoreWebView2FindMatchCountChangedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2FindMatchCountChangedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2FindMatchCountChangedEventHandler.Invoke(const sender : ICoreWebView2Find; + const args : IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).FindMatchCountChangedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2FindStartCompletedHandler + +constructor TCoreWebView2FindStartCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2FindStartCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2FindStartCompletedHandler.Invoke(errorCode: HResult): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).FindStartCompletedHandler_Invoke(errorCode) + else + Result := E_FAIL; +end; + + +// TCoreWebView2DragStartingEventHandler + +constructor TCoreWebView2DragStartingEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2DragStartingEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2DragStartingEventHandler.Invoke(const sender : ICoreWebView2CompositionController; + const args : ICoreWebView2DragStartingEventArgs): HResult; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).DragStartingEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2DedicatedWorkerCreatedEventHandler + +constructor TCoreWebView2DedicatedWorkerCreatedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2DedicatedWorkerCreatedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2DedicatedWorkerCreatedEventHandler.Invoke(const sender : ICoreWebView2; + const args : ICoreWebView2DedicatedWorkerCreatedEventArgs): HResult; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).DedicatedWorkerCreatedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2DedicatedWorkerDedicatedWorkerCreatedEventHandler + +constructor TCoreWebView2DedicatedWorkerDedicatedWorkerCreatedEventHandler.Create(const aEvents: IWVBrowserEvents; aWorkerID: cardinal); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FWorkerID := aWorkerID; +end; + +destructor TCoreWebView2DedicatedWorkerDedicatedWorkerCreatedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2DedicatedWorkerDedicatedWorkerCreatedEventHandler.Invoke(const sender : ICoreWebView2DedicatedWorker; + const args : ICoreWebView2DedicatedWorkerCreatedEventArgs): HResult; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).DedicatedWorkerDedicatedWorkerCreatedEventHandler_Invoke(sender, args, FWorkerID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2DedicatedWorkerDestroyingEventHandler + +constructor TCoreWebView2DedicatedWorkerDestroyingEventHandler.Create(const aEvents: IWVBrowserEvents; aWorkerID: cardinal); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FWorkerID := aWorkerID; +end; + +destructor TCoreWebView2DedicatedWorkerDestroyingEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2DedicatedWorkerDestroyingEventHandler.Invoke(const sender : ICoreWebView2DedicatedWorker; + const args : IUnknown): HResult; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).DedicatedWorkerDestroyingEventHandler_Invoke(sender, args, FWorkerID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2DedicatedWorkerWebMessageReceivedEventHandler + +constructor TCoreWebView2DedicatedWorkerWebMessageReceivedEventHandler.Create(const aEvents: IWVBrowserEvents; aWorkerID: cardinal); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FWorkerID := aWorkerID; +end; + +destructor TCoreWebView2DedicatedWorkerWebMessageReceivedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2DedicatedWorkerWebMessageReceivedEventHandler.Invoke(const sender : ICoreWebView2DedicatedWorker; + const args : ICoreWebView2WebMessageReceivedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).DedicatedWorkerWebMessageReceivedEventHandler_Invoke(sender, args, FWorkerID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2FrameDedicatedWorkerCreatedEventHandler + +constructor TCoreWebView2FrameDedicatedWorkerCreatedEventHandler.Create(const aEvents: IWVBrowserEvents; aFrameID : cardinal); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FFrameID := aFrameID; +end; + +destructor TCoreWebView2FrameDedicatedWorkerCreatedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2FrameDedicatedWorkerCreatedEventHandler.Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2DedicatedWorkerCreatedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).FrameDedicatedWorkerCreatedEventHandler_Invoke(sender, args, FFrameID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ServiceWorkerDestroyingEventHandler + +constructor TCoreWebView2ServiceWorkerDestroyingEventHandler.Create(const aEvents: IWVBrowserEvents; aWorkerID: cardinal); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FWorkerID := aWorkerID; +end; + +destructor TCoreWebView2ServiceWorkerDestroyingEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ServiceWorkerDestroyingEventHandler.Invoke(const sender : ICoreWebView2ServiceWorker; + const args : IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ServiceWorkerDestroyingEventHandler_Invoke(sender, args, FWorkerID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ServiceWorkerWebMessageReceivedEventHandler + +constructor TCoreWebView2ServiceWorkerWebMessageReceivedEventHandler.Create(const aEvents: IWVBrowserEvents; aWorkerID: cardinal); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FWorkerID := aWorkerID; +end; + +destructor TCoreWebView2ServiceWorkerWebMessageReceivedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ServiceWorkerWebMessageReceivedEventHandler.Invoke(const sender : ICoreWebView2ServiceWorker; + const args : ICoreWebView2WebMessageReceivedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ServiceWorkerWebMessageReceivedEventHandler_Invoke(sender, args, FWorkerID) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ServiceWorkerRegisteredEventHandler + +constructor TCoreWebView2ServiceWorkerRegisteredEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2ServiceWorkerRegisteredEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ServiceWorkerRegisteredEventHandler.Invoke(const sender : ICoreWebView2ServiceWorkerManager; + const args : ICoreWebView2ServiceWorkerRegisteredEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ServiceWorkerRegisteredEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2GetServiceWorkerRegistrationsCompletedHandler + +constructor TCoreWebView2GetServiceWorkerRegistrationsCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2GetServiceWorkerRegistrationsCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2GetServiceWorkerRegistrationsCompletedHandler.Invoke(errorCode: HResult; const result_: ICoreWebView2ServiceWorkerRegistrationCollectionView): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).GetServiceWorkerRegistrationsCompletedHandler_Invoke(errorCode, result_) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ServiceWorkerActivatedEventHandler + +constructor TCoreWebView2ServiceWorkerActivatedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2ServiceWorkerActivatedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ServiceWorkerActivatedEventHandler.Invoke(const sender: ICoreWebView2ServiceWorkerRegistration; const args: ICoreWebView2ServiceWorkerActivatedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ServiceWorkerActivatedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2ServiceWorkerRegistrationUnregisteringEventHandler + +constructor TCoreWebView2ServiceWorkerRegistrationUnregisteringEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2ServiceWorkerRegistrationUnregisteringEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2ServiceWorkerRegistrationUnregisteringEventHandler.Invoke(const sender: ICoreWebView2ServiceWorkerRegistration; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).ServiceWorkerRegistrationUnregisteringEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2SharedWorkerCreatedEventHandler + +constructor TCoreWebView2SharedWorkerCreatedEventHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2SharedWorkerCreatedEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2SharedWorkerCreatedEventHandler.Invoke(const sender: ICoreWebView2SharedWorkerManager; const args: ICoreWebView2SharedWorkerCreatedEventArgs): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).SharedWorkerCreatedEventHandler_Invoke(sender, args) + else + Result := E_FAIL; +end; + + +// TCoreWebView2GetSharedWorkersCompletedHandler + +constructor TCoreWebView2GetSharedWorkersCompletedHandler.Create(const aEvents: IWVBrowserEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCoreWebView2GetSharedWorkersCompletedHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2GetSharedWorkersCompletedHandler.Invoke(errorCode: HResult; const result_: ICoreWebView2SharedWorkerCollectionView): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).GetSharedWorkersCompletedHandler_Invoke(errorCode, result_) + else + Result := E_FAIL; +end; + + +// TCoreWebView2SharedWorkerDestroyingEventHandler + +constructor TCoreWebView2SharedWorkerDestroyingEventHandler.Create(const aEvents: IWVBrowserEvents; aWorkerID : cardinal); +begin + inherited Create; + + FEvents := Pointer(aEvents); + FWorkerID := aWorkerID; +end; + +destructor TCoreWebView2SharedWorkerDestroyingEventHandler.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +function TCoreWebView2SharedWorkerDestroyingEventHandler.Invoke(const sender: ICoreWebView2SharedWorker; const args: IUnknown): HResult; stdcall; +begin + if (FEvents <> nil) then + Result := IWVBrowserEvents(FEvents).SharedWorkerDestroyingEventHandler_Invoke(sender, args, FWorkerID) + else + Result := E_FAIL; +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Environment.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Environment.pas new file mode 100644 index 000000000..6ad3f9cb0 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Environment.pas @@ -0,0 +1,962 @@ +unit uRESTDWPrivWVCoreWebView2Environment; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + Winapi.Windows, System.Classes, System.Types, Winapi.ActiveX, System.SysUtils, + {$ELSE} + Windows, Classes, ActiveX, SysUtils, + {$ENDIF} + uRESTDWPrivWVInterfaces, uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVTypes; + +type + /// + /// Represents the WebView2 Environment. WebViews created from an environment + /// run on the browser process specified with environment parameters and + /// objects created from an environment should be used in the same + /// environment. Using it in different environments are not guaranteed to be + /// compatible and may fail. + /// + /// + /// See the ICoreWebView2Environment article. + /// + TCoreWebView2Environment = class + protected + FBaseIntf : ICoreWebView2Environment; + FBaseIntf2 : ICoreWebView2Environment2; + FBaseIntf3 : ICoreWebView2Environment3; + FBaseIntf4 : ICoreWebView2Environment4; + FBaseIntf5 : ICoreWebView2Environment5; + FBaseIntf6 : ICoreWebView2Environment6; + FBaseIntf7 : ICoreWebView2Environment7; + FBaseIntf8 : ICoreWebView2Environment8; + FBaseIntf9 : ICoreWebView2Environment9; + FBaseIntf10 : ICoreWebView2Environment10; + FBaseIntf11 : ICoreWebView2Environment11; + FBaseIntf12 : ICoreWebView2Environment12; + FBaseIntf13 : ICoreWebView2Environment13; + FBaseIntf14 : ICoreWebView2Environment14; + FBaseIntf15 : ICoreWebView2Environment15; + FNewBrowserVersionAvailableEventToken : EventRegistrationToken; + FBrowserProcessExitedEventToken : EventRegistrationToken; + FProcessInfosChangedEventToken : EventRegistrationToken; + + function GetInitialized : boolean; + function GetBrowserVersionInfo : wvstring; + function GetSupportsCompositionController : boolean; + function GetSupportsControllerOptions : boolean; + function GetUserDataFolder : wvstring; + function GetProcessInfos : ICoreWebView2ProcessInfoCollection; + function GetFailureReportFolderPath : wvstring; + + procedure InitializeFields; + procedure InitializeTokens; + procedure RemoveAllEvents; + + function AddNewBrowserVersionAvailableEvent(const aLoaderComponent : TComponent) : boolean; + function AddBrowserProcessExitedLoaderEvent(const aLoaderComponent : TComponent) : boolean; + function AddBrowserProcessExitedBrowserEvent(const aBrowserComponent : TComponent) : boolean; + function AddProcessInfosChangedLoaderEvent(const aLoaderComponent : TComponent) : boolean; + function AddProcessInfosChangedBrowserEvent(const aBrowserComponent : TComponent) : boolean; + + public + constructor Create(const aBaseIntf : ICoreWebView2Environment); reintroduce; + destructor Destroy; override; + /// + /// Adds all the events of this class to an existing TWVLoader instance. + /// + /// The TWVLoader instance. + function AddAllLoaderEvents(const aLoaderComponent : TComponent) : boolean; + /// + /// Adds all the events of this class to an existing TWVBrowserBase instance. + /// + /// The TWVBrowserBase instance. + function AddAllBrowserEvents(const aBrowserComponent : TComponent) : boolean; + /// + /// Asynchronously create a new WebView. + /// + /// Handle of the control in which the WebView should be displayed. + /// The TWVBrowserBase instance that will receive all the events. + /// Result code. + /// True if successfull. + /// + /// See the ICoreWebView2Environment article. + /// + function CreateCoreWebView2Controller(aParentWindow : THandle; const aBrowserEvents : IWVBrowserEvents; var aResult: HRESULT) : boolean; + /// + /// Create a new web resource response object. + /// + /// HTTP response content as stream. + /// The HTTP response status code. + /// The HTTP response reason phrase. + /// Overridden HTTP response headers. + /// The new ICoreWebView2WebResourceResponse instance. + /// True if successfull. + /// + /// See the ICoreWebView2Environment article. + /// + function CreateWebResourceResponse(const aContent : IStream; aStatusCode : integer; aReasonPhrase, aHeaders : wvstring; var aResponse : ICoreWebView2WebResourceResponse) : boolean; + /// + /// Create a new web resource request object. + /// URI parameter must be absolute URI. + /// The headers string is the raw request header string delimited by CRLF + /// (optional in last header). + /// It's also possible to create this object with null headers string + /// and then use the ICoreWebView2HttpRequestHeaders to construct the headers + /// line by line. + /// + /// The request URI. + /// The HTTP request method. + /// The HTTP request message body as stream. + /// The mutable HTTP request headers. + /// The new ICoreWebView2WebResourceRequest instance. + /// True if successfull. + /// + /// See the ICoreWebView2Environment2 article. + /// + function CreateWebResourceRequest(const aURI, aMethod : wvstring; const aPostData : IStream; const aHeaders : wvstring; var aRequest : ICoreWebView2WebResourceRequest): boolean; + /// + /// Asynchronously create a new WebView for use with visual hosting. + /// + /// Handle of the control in which the app will connect the visual tree of the WebView. + /// The TWVBrowserBase instance that will receive all the events. + /// Result code. + /// True if successfull. + /// + /// See the ICoreWebView2Environment3 article. + /// + function CreateCoreWebView2CompositionController(aParentWindow : THandle; const aBrowserEvents : IWVBrowserEvents; var aResult: HRESULT) : boolean; + /// + /// Create an empty ICoreWebView2PointerInfo. The returned + /// ICoreWebView2PointerInfo needs to be populated with all of the relevant + /// info before calling SendPointerInput. + /// + /// The new ICoreWebView2PointerInfo instance. + /// True if successfull. + /// + /// See the ICoreWebView2Environment3 article. + /// + function CreateCoreWebView2PointerInfo(var aPointerInfo : ICoreWebView2PointerInfo) : boolean; + /// + /// Returns the Automation Provider for the WebView that matches the provided + /// window. Host apps are expected to implement + /// IRawElementProviderHwndOverride. When GetOverrideProviderForHwnd is + /// called, the app can pass the HWND to GetAutomationProviderForWindow to + /// find the matching WebView Automation Provider. + /// + /// Handle used to find the matching WebView Automation Provider. + /// The Automation Provider for the WebView that matches the provided window. + /// True if successfull. + /// + /// See the ICoreWebView2Environment4 article. + /// + function GetAutomationProviderForWindow(aHandle : THandle; var aProvider : IUnknown) : boolean; + /// + /// Creates the `ICoreWebView2PrintSettings` used by the `PrintToPdf` method. + /// + /// The new ICoreWebView2PrintSettings instance. + /// True if successfull. + /// + /// See the ICoreWebView2Environment6 article. + /// + function CreatePrintSettings(var aPrintSettings : ICoreWebView2PrintSettings) : boolean; + /// + /// Create a custom `ContextMenuItem` object to insert into the WebView context menu. + /// CoreWebView2 will rewind the icon stream before decoding. + /// There is a limit of 1000 active custom context menu items at a given time. + /// Attempting to create more before deleting existing ones will fail with + /// ERROR_NOT_ENOUGH_QUOTA. + /// It is recommended to reuse ContextMenuItems across ContextMenuRequested events + /// for performance. + /// The returned ContextMenuItem object's `IsEnabled` property will default to `TRUE` + /// and `IsChecked` property will default to `FALSE`. A `CommandId` will be assigned + /// to the ContextMenuItem object that's unique across active custom context menu items, + /// but command ID values of deleted ContextMenuItems can be reassigned. + /// + /// Context menu item label. + /// Context menu item icon as stream. + /// Context menu item kind. + /// The new ICoreWebView2ContextMenuItem instance. + /// True if successfull. + /// + /// See the ICoreWebView2Environment9 article. + /// + function CreateContextMenuItem(const aLabel : wvstring; const aIconStream : IStream; aKind : TWVMenuItemKind; var aMenuItem : ICoreWebView2ContextMenuItem) : boolean; + /// + /// Create a new ICoreWebView2ControllerOptions to be passed as a parameter of + /// CreateCoreWebView2ControllerWithOptions and CreateCoreWebView2CompositionControllerWithOptions. + /// The 'options' is settable and in it the default value for profile name is the empty string, + /// and the default value for IsInPrivateModeEnabled is false. + /// Also the profile name can be reused. + /// + /// The new ICoreWebView2ControllerOptions instance. + /// Result code. + /// True if successfull. + /// + /// See the ICoreWebView2Environment10 article. + /// + function CreateCoreWebView2ControllerOptions(var aOptions: ICoreWebView2ControllerOptions; var aResult: HResult): boolean; + /// + /// Create a new WebView with options. + /// + /// Handle of the control in which the WebView should be displayed. + /// The ICoreWebView2ControllerOptions instance created with CreateCoreWebView2ControllerOptions. + /// The TWVBrowserBase instance that will receive all the events. + /// Result code. + /// True if successfull. + /// + /// See the ICoreWebView2Environment10 article. + /// + function CreateCoreWebView2ControllerWithOptions(aParentWindow: HWND; const aOptions: ICoreWebView2ControllerOptions; const aBrowserEvents: IWVBrowserEvents; var aResult: HResult): boolean; + /// + /// Create a new WebView in visual hosting mode with options. + /// + /// Handle of the control in which the app will connect the visual tree of the WebView. + /// The ICoreWebView2ControllerOptions instance created with CreateCoreWebView2ControllerOptions. + /// The TWVBrowserBase instance that will receive all the events. + /// Result code. + /// True if successfull. + /// + /// See the ICoreWebView2Environment10 article. + /// + function CreateCoreWebView2CompositionControllerWithOptions(aParentWindow: HWND; const aOptions: ICoreWebView2ControllerOptions; const aBrowserEvents: IWVBrowserEvents; var aResult: HResult): boolean; + /// + /// Create a shared memory based buffer with the specified size in bytes. + /// The buffer can be shared with web contents in WebView by calling + /// `PostSharedBufferToScript` on `CoreWebView2` or `CoreWebView2Frame` object. + /// Once shared, the same content of the buffer will be accessible from both + /// the app process and script in WebView. Modification to the content will be visible + /// to all parties that have access to the buffer. + /// The shared buffer is presented to the script as ArrayBuffer. All JavaScript APIs + /// that work for ArrayBuffer including Atomics APIs can be used on it. + /// There is currently a limitation that only size less than 2GB is supported. + /// + /// Buffer size in bytes. + /// The new ICoreWebView2SharedBuffer instance. + /// True if successfull. + /// + /// See the ICoreWebView2Environment12 article. + /// + function CreateSharedBuffer(aSize : Largeuint; var aSharedBuffer : ICoreWebView2SharedBuffer) : boolean; + /// + /// Gets a snapshot collection of `ProcessExtendedInfo`s corresponding to all + /// currently running processes associated with this `ICoreWebView2Environment` + /// excludes crashpad process. + /// This provides the same list of `ProcessInfo`s as what's provided in + /// `GetProcessInfos`, but additionally provides a list of associated `FrameInfo`s + /// which are actively running (showing or hiding UI elements) in the renderer + /// process. See `AssociatedFrameInfos` for more information. + /// + /// The TWVBrowserBase instance that will receive all the events. + /// True if successfull. + /// + /// See the ICoreWebView2Environment13 article. + /// + function GetProcessExtendedInfos(const aBrowserEvents : IWVBrowserEvents) : boolean; + /// + /// Create a `ICoreWebView2FileSystemHandle` object from a path that represents a Web + /// [FileSystemFileHandle](https://developer.mozilla.org/docs/Web/API/FileSystemFileHandle). + /// + /// The `path` is the path pointed by the file and must be a syntactically correct fully qualified + /// path, but it is not checked here whether it currently points to a file. If an invalid path is + /// passed, an E_INVALIDARG will be returned and the object will fail to create. Any other state + /// validation will be done when this handle is accessed from web content + /// and will cause the DOM exceptions described in + /// [FileSystemFileHandle methods](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryHandle#instance_methods) + /// if access operations fail. + /// + /// `Permission` property is used to specify whether the Handle should be created with a Read-only or + /// Read-and-write web permission. For the `permission` value specified here, the DOM + /// [PermissionStatus](https://developer.mozilla.org/docs/Web/API/PermissionStatus) property + /// will be [granted](https://developer.mozilla.org/docs/Web/API/PermissionStatus/state) + /// and the unspecified permission will be + /// [prompt](https://developer.mozilla.org/docs/Web/API/PermissionStatus/state). Therefore, + /// the web content then does not need to call + /// [requestPermission](https://developer.mozilla.org/docs/Web/API/FileSystemHandle/requestPermission) + /// for the permission that was specified before attempting the permitted operation, + /// but if it does, the promise will immediately be resolved + /// with 'granted' PermissionStatus without firing the WebView2 + /// [PermissionRequested](/microsoft-edge/webview2/reference/win32/icorewebview2permissionrequestedeventargs) + /// event or prompting the user for permission. Otherwise, `requestPermission` will behave as the + /// status of permission is currently `prompt`, which means the `PermissionRequested` event will fire + /// or the user will be prompted. + /// Additionally, the app must have the same OS permissions that have propagated to the + /// [WebView2 browser process](/microsoft-edge/webview2/concepts/process-model) + /// for the path it wishes to give the web content to read/write the file. + /// Specifically, the WebView2 browser process will run in same user, package identity, and app + /// container of the app, but other means such as security context impersonations do not get + /// propagated, so such permissions that the app has, will not be effective in WebView2. + /// Note: An exception to this is, if there is a parent directory handle that + /// has broader permissions in the same page context than specified in here, the handle will automatically + /// inherit the most permissive permission of the parent handle when posted to that page context. + /// i.e. If there is already a `FileSystemDirectoryHandle` to `C:\example` that has write permission on + /// a page, even though a WebFileSystemHandle to file `C:\example\file.txt` is created with + /// `COREWEBVIEW2_FILE_SYSTEM_HANDLE_PERMISSION_READ_ONLY` permission, when posted to that page, write permission + /// will be automatically granted to the created handle. + /// + /// An app needs to be mindful that this object, when posted to the web content, provides it with unusual + /// access to OS file system via the Web FileSystem API! The app should therefore only post objects + /// for paths that it wants to allow access to the web content and it is not recommended that the web content + /// "asks" for this path. The app should also check the source property of the target to ensure + /// that it is sending to the web content of intended origin. + /// + /// Once the object is passed to web content, if the content is attempting a read, + /// the file must be existing and available to read similar to a file chosen by + /// [open file picker](https://developer.mozilla.org/docs/Web/API/Window/showOpenFilePicker), + /// otherwise the read operation will + /// [throw a DOM exception](https://developer.mozilla.org/docs/Web/API/FileSystemFileHandle/getFile#exceptions). + /// For write operations, the file does not need to exist as `FileSystemFileHandle` will behave + /// as a file path chosen by + /// [save file picker](https://developer.mozilla.org/docs/Web/API/Window/showSaveFilePicker) + /// and will create or overwrite the file, but the parent directory structure pointed + /// by the file must exist and an existing file must be available to write and delete + /// or the write operation will + /// [throw a DOM exception](https://developer.mozilla.org/docs/Web/API/FileSystemFileHandle/createWritable#exceptions). + /// + /// The path pointed by the file. + /// Used to specify whether the Handle should be created with a Read-only or Read-and-write web permission. + /// The ICoreWebView2FileSystemHandle object created from a path that represents a Web FileSystemFileHandle. + /// True if successfull. + /// + /// See the ICoreWebView2Environment14 article. + /// + function CreateWebFileSystemFileHandle(const aPath : wvstring; + aPermission : TWVFileSystemHandlePermission; + var aValue : ICoreWebView2FileSystemHandle): boolean; + /// + /// Create a `ICoreWebView2FileSystemHandle` object from a path that represents a Web + /// [FileSystemDirectoryHandle](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryHandle). + /// + /// The `path` is the path pointed by the directory and must be a syntactically correct fully qualified + /// path, but it is not checked here whether it currently points to a directory. Any other state + /// validation will be done when this handle is accessed from web content + /// and will cause DOM exceptions if access operations fail. If an invalid path is + /// passed, an E_INVALIDARG will be returned and the object will fail to create. + /// + /// `Permission` property is used to specify whether the Handle should be created with a Read-only or + /// Read-and-write web permission. For the `permission` value specified here, the Web + /// [PermissionStatus](https://developer.mozilla.org/docs/Web/API/PermissionStatus) + /// will be [granted](https://developer.mozilla.org/docs/Web/API/PermissionStatus/state) + /// and the unspecified permission will be + /// [prompt](https://developer.mozilla.org/docs/Web/API/PermissionStatus/state). Therefore, + /// the web content then does not need to call + /// [requestPermission](https://developer.mozilla.org/docs/Web/API/FileSystemHandle/requestPermission) + /// for the permission that was specified before attempting the permitted operation, + /// but if it does, the promise will immediately be resolved + /// with 'granted' PermissionStatus without firing the WebView2 + /// [PermissionRequested](/microsoft-edge/webview2/reference/win32/icorewebview2permissionrequestedeventargs) + /// event or prompting the user for permission. Otherwise, `requestPermission` will behave as the + /// status of permission is currently `Prompt`, which means the `PermissionRequested` event will fire + /// or the user will be prompted. + /// Additionally, the app must have the same OS permissions that have propagated to the + /// [WebView2 browser process](/microsoft-edge/webview2/concepts/process-model) + /// for the path it wishes to give the web content to make any operations on the directory. + /// Specifically, the WebView2 browser process will run in same user, package identity, and app + /// container of the app, but other means such as security context impersonations do not get + /// propagated, so such permissions that the app has, will not be effective in WebView2. + /// Note: An exception to this is, if there is a parent directory handle that + /// has broader permissions in the same page context than specified in here, the handle will automatically + /// inherit the most permissive permission of the parent handle when posted to that page context. + /// i.e. If there is already a `FileSystemDirectoryHandle` to `C:\example` that has write permission on + /// a page, even though a WebFileSystemHandle to directory `C:\example\directory` is created with + /// `COREWEBVIEW2_FILE_SYSTEM_HANDLE_PERMISSION_READ_ONLY` permission, when posted to that page, write permission + /// will be automatically granted to the created handle. + /// + /// An app needs to be mindful that this object, when posted to the web content, provides it with unusual + /// access to OS file system via the Web FileSystem API! The app should therefore only post objects + /// for paths that it wants to allow access to the web content and it is not recommended that the web content + /// "asks" for this path. The app should also check the source property of the target to ensure + /// that it is sending to the web content of intended origin. + /// + /// Once the object is passed to web content, the path must point to a directory as if it was chosen via + /// [directory picker](https://developer.mozilla.org/docs/Web/API/Window/showDirectoryPicker) + /// otherwise any IO operation done on the `FileSystemDirectoryHandle` will throw a DOM exception. + /// + /// The path pointed by the directory. + /// Used to specify whether the Handle should be created with a Read-only or Read-and-write web permission. + /// The ICoreWebView2FileSystemHandle object created from a path that represents a Web FileSystemDirectoryHandle. + /// True if successfull. + /// + /// See the ICoreWebView2Environment14 article. + /// + function CreateWebFileSystemDirectoryHandle(const aPath : wvstring; + aPermission : TWVFileSystemHandlePermission; + var aValue : ICoreWebView2FileSystemHandle): boolean; + /// + /// Create a generic object collection. + /// + /// Amount of items. + /// Used to specify whether the Handle should be created with a Read-only or Read-and-write web permission. + /// The ICoreWebView2ObjectCollection object created with aItems. + /// True if successfull. + /// + /// See the ICoreWebView2Environment14 article. + /// + function CreateObjectCollection( aLength : cardinal; + var aItems : IUnknown; + var aObjectCollection : ICoreWebView2ObjectCollection): boolean; + /// + /// Creates a new instance of a CoreWebView2FindOptions object. + /// This find options object can be used to define parameters for a find session. + /// Returns the newly created FindOptions object. + /// + /// + /// See the ICoreWebView2Environment15 article. + /// + function CreateFindOptions(var aFindOptions : ICoreWebView2FindOptions): boolean; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2Environment read FBaseIntf; + /// + /// The browser version info of the current `ICoreWebView2Environment`, + /// including channel name if it is not the WebView2 Runtime. It matches the + /// format of the `GetAvailableCoreWebView2BrowserVersionString` API. + /// Channel names are `beta`, `dev`, and `canary`. + /// + /// + /// See the ICoreWebView2Environment article. + /// + property BrowserVersionInfo : wvstring read GetBrowserVersionInfo; + /// + /// Returns true if the current WebView2 runtime version supports Composition Controllers. + /// + /// + /// See the ICoreWebView2Environment3 article. + /// + property SupportsCompositionController : boolean read GetSupportsCompositionController; + /// + /// Returns true if the current WebView2 runtime version supports Controller Options. + /// + /// + /// See the ICoreWebView2Environment10 article. + /// + property SupportsControllerOptions : boolean read GetSupportsControllerOptions; + /// + /// Returns the user data folder that all CoreWebView2's created from this + /// environment are using. + /// This could be either the value passed in by the developer when creating + /// the environment object or the calculated one for default handling. It + /// will always be an absolute path. + /// + /// + /// See the ICoreWebView2Environment7 article. + /// + property UserDataFolder : wvstring read GetUserDataFolder; + /// + /// Returns the `ICoreWebView2ProcessInfoCollection`. Provide a list of all + /// process using same user data folder except for crashpad process. + /// + /// + /// See the ICoreWebView2Environment8 article. + /// + property ProcessInfos : ICoreWebView2ProcessInfoCollection read GetProcessInfos; + /// + /// `FailureReportFolderPath` returns the path of the folder where minidump files are written. + /// Whenever a WebView2 process crashes, a crash dump file will be created in the crash dump folder. + /// The crash dump format is minidump files. Please see + /// [Minidump Files documentation](/windows/win32/debug/minidump-files) for detailed information. + /// Normally when a single child process fails, a minidump will be generated and written to disk, + /// then the `ProcessFailed` event is raised. But for unexpected crashes, a minidump file might not be generated + /// at all, despite whether `ProcessFailed` event is raised. If there are multiple + /// process failures at once, multiple minidump files could be generated. Thus `FailureReportFolderPath` + /// could contain old minidump files that are not associated with a specific `ProcessFailed` event. + /// + /// + /// See the ICoreWebView2Environment11 article. + /// + property FailureReportFolderPath : wvstring read GetFailureReportFolderPath; + end; + +implementation + +uses + uRESTDWPrivWVMiscFunctions, uRESTDWPrivWVCoreWebView2Delegates, uRESTDWPrivWVBrowserBase, uRESTDWPrivWVLoader; + +constructor TCoreWebView2Environment.Create(const aBaseIntf : ICoreWebView2Environment); +begin + inherited Create; + + InitializeFields; + + FBaseIntf := aBaseIntf; + + if Initialized and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Environment2, FBaseIntf2) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Environment3, FBaseIntf3) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Environment4, FBaseIntf4) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Environment5, FBaseIntf5) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Environment6, FBaseIntf6) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Environment7, FBaseIntf7) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Environment8, FBaseIntf8) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Environment9, FBaseIntf9) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Environment10, FBaseIntf10) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Environment11, FBaseIntf11) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Environment12, FBaseIntf12) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Environment13, FBaseIntf13) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Environment14, FBaseIntf14) then + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Environment15, FBaseIntf15); +end; + +destructor TCoreWebView2Environment.Destroy; +begin + try + RemoveAllEvents; + InitializeFields; + finally + inherited Destroy; + end; +end; + +procedure TCoreWebView2Environment.InitializeFields; +begin + FBaseIntf := nil; + FBaseIntf2 := nil; + FBaseIntf3 := nil; + FBaseIntf4 := nil; + FBaseIntf5 := nil; + FBaseIntf6 := nil; + FBaseIntf7 := nil; + FBaseIntf8 := nil; + FBaseIntf9 := nil; + FBaseIntf10 := nil; + FBaseIntf11 := nil; + FBaseIntf12 := nil; + FBaseIntf13 := nil; + FBaseIntf14 := nil; + FBaseIntf15 := nil; + + InitializeTokens; +end; + +procedure TCoreWebView2Environment.InitializeTokens; +begin + FNewBrowserVersionAvailableEventToken.value := 0; + FBrowserProcessExitedEventToken.value := 0; + FProcessInfosChangedEventToken.value := 0; +end; + +function TCoreWebView2Environment.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +procedure TCoreWebView2Environment.RemoveAllEvents; +begin + if Initialized then + begin + if (FNewBrowserVersionAvailableEventToken.value <> 0) then + FBaseIntf.remove_NewBrowserVersionAvailable(FNewBrowserVersionAvailableEventToken); + + if assigned(FBaseIntf5) and (FBrowserProcessExitedEventToken.value <> 0) then + FBaseIntf5.remove_BrowserProcessExited(FBrowserProcessExitedEventToken); + + if assigned(FBaseIntf8) and (FProcessInfosChangedEventToken.value <> 0) then + FBaseIntf8.remove_ProcessInfosChanged(FProcessInfosChangedEventToken); + + InitializeTokens; + end; +end; + +function TCoreWebView2Environment.AddAllLoaderEvents(const aLoaderComponent : TComponent) : boolean; +begin + Result := AddNewBrowserVersionAvailableEvent(aLoaderComponent) and + AddBrowserProcessExitedLoaderEvent(aLoaderComponent) and + AddProcessInfosChangedLoaderEvent(aLoaderComponent); +end; + +function TCoreWebView2Environment.AddAllBrowserEvents(const aBrowserComponent : TComponent) : boolean; +begin + Result := AddBrowserProcessExitedBrowserEvent(aBrowserComponent) and + AddProcessInfosChangedBrowserEvent(aBrowserComponent); +end; + +function TCoreWebView2Environment.AddNewBrowserVersionAvailableEvent(const aLoaderComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2NewBrowserVersionAvailableEventHandler; +begin + Result := False; + + if Initialized and (FNewBrowserVersionAvailableEventToken.value = 0) then + try + TempHandler := TCoreWebView2NewBrowserVersionAvailableEventHandler.Create(TWVLoader(aLoaderComponent)); + Result := succeeded(FBaseIntf.add_NewBrowserVersionAvailable(TempHandler, FNewBrowserVersionAvailableEventToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Environment.AddBrowserProcessExitedLoaderEvent(const aLoaderComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2BrowserProcessExitedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf5) and (FBrowserProcessExitedEventToken.value = 0) then + try + TempHandler := TCoreWebView2BrowserProcessExitedEventHandler.Create(TWVLoader(aLoaderComponent)); + Result := succeeded(FBaseIntf5.add_BrowserProcessExited(TempHandler, FBrowserProcessExitedEventToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Environment.AddBrowserProcessExitedBrowserEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2BrowserProcessExitedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf5) and (FBrowserProcessExitedEventToken.value = 0) then + try + TempHandler := TCoreWebView2BrowserProcessExitedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf5.add_BrowserProcessExited(TempHandler, FBrowserProcessExitedEventToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Environment.AddProcessInfosChangedLoaderEvent(const aLoaderComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2ProcessInfosChangedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf8) and (FProcessInfosChangedEventToken.value = 0) then + try + TempHandler := TCoreWebView2ProcessInfosChangedEventHandler.Create(TWVLoader(aLoaderComponent)); + Result := succeeded(FBaseIntf8.add_ProcessInfosChanged(TempHandler, FProcessInfosChangedEventToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Environment.AddProcessInfosChangedBrowserEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2ProcessInfosChangedEventHandler; +begin + Result := False; + + if assigned(FBaseIntf8) and (FProcessInfosChangedEventToken.value = 0) then + try + TempHandler := TCoreWebView2ProcessInfosChangedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf8.add_ProcessInfosChanged(TempHandler, FProcessInfosChangedEventToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Environment.CreateCoreWebView2Controller( aParentWindow : THandle; + const aBrowserEvents : IWVBrowserEvents; + var aResult : HRESULT) : boolean; +var + TempHandler : ICoreWebView2CreateCoreWebView2ControllerCompletedHandler; +begin + Result := False; + aResult := E_FAIL; + + if Initialized then + try + TempHandler := TCoreWebView2CreateCoreWebView2ControllerCompletedHandler.Create(aBrowserEvents); + aResult := FBaseIntf.CreateCoreWebView2Controller(aParentWindow, TempHandler); + Result := succeeded(aResult); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Environment.CreateWebResourceResponse(const aContent : IStream; + aStatusCode : integer; + aReasonPhrase : wvstring; + aHeaders : wvstring; + var aResponse : ICoreWebView2WebResourceResponse) : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.CreateWebResourceResponse(aContent, + aStatusCode, + PWideChar(aReasonPhrase), + PWideChar(aHeaders), + aResponse)); +end; + +function TCoreWebView2Environment.CreateWebResourceRequest(const aURI : wvstring; + const aMethod : wvstring; + const aPostData : IStream; + const aHeaders : wvstring; + var aRequest : ICoreWebView2WebResourceRequest): boolean; +begin + aRequest := nil; + Result := assigned(FBaseIntf2) and + succeeded(FBaseIntf2.CreateWebResourceRequest(PWideChar(aURI), + PWideChar(aMethod), + aPostData, + PWideChar(aHeaders), + aRequest)); +end; + +function TCoreWebView2Environment.GetBrowserVersionInfo: wvstring; +var + TempVersionInfo : PWideChar; +begin + Result := ''; + + if Initialized then + begin + TempVersionInfo := nil; + + if succeeded(FBaseIntf.Get_BrowserVersionString(TempVersionInfo)) then + begin + Result := TempVersionInfo; + CoTaskMemFree(TempVersionInfo); + end; + end; +end; + +function TCoreWebView2Environment.GetSupportsCompositionController : boolean; +begin + Result := assigned(FBaseIntf3); +end; + +function TCoreWebView2Environment.GetSupportsControllerOptions : boolean; +begin + Result := assigned(FBaseIntf10); +end; + +function TCoreWebView2Environment.CreateCoreWebView2CompositionController( aParentWindow : THandle; + const aBrowserEvents : IWVBrowserEvents; + var aResult : HRESULT) : boolean; +var + TempHandler : ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler; +begin + Result := False; + aResult := E_FAIL; + + if assigned(FBaseIntf3) then + try + TempHandler := TCoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler.Create(aBrowserEvents); + aResult := FBaseIntf3.CreateCoreWebView2CompositionController(aParentWindow, TempHandler); + Result := succeeded(aResult); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Environment.CreateCoreWebView2PointerInfo(var aPointerInfo: ICoreWebView2PointerInfo) : boolean; +begin + Result := assigned(FBaseIntf3) and + succeeded(FBaseIntf3.CreateCoreWebView2PointerInfo(aPointerInfo)) and + assigned(aPointerInfo); +end; + +function TCoreWebView2Environment.GetAutomationProviderForWindow(aHandle : THandle; var aProvider: IUnknown) : boolean; +begin + aProvider := nil; + Result := assigned(FBaseIntf4) and + succeeded(FBaseIntf4.GetAutomationProviderForWindow(aHandle, aProvider)); +end; + +function TCoreWebView2Environment.CreatePrintSettings(var aPrintSettings: ICoreWebView2PrintSettings): boolean; +begin + aPrintSettings := nil; + Result := assigned(FBaseIntf6) and + succeeded(FBaseIntf6.CreatePrintSettings(aPrintSettings)) and + assigned(aPrintSettings); +end; + +function TCoreWebView2Environment.CreateContextMenuItem(const aLabel : wvstring; + const aIconStream : IStream; + aKind : TWVMenuItemKind; + var aMenuItem : ICoreWebView2ContextMenuItem) : boolean; +begin + aMenuItem := nil; + Result := assigned(FBaseIntf9) and + succeeded(FBaseIntf9.CreateContextMenuItem(PWideChar(aLabel), aIconStream, aKind, aMenuItem)) and + assigned(aMenuItem); +end; + +function TCoreWebView2Environment.CreateCoreWebView2ControllerOptions(var aOptions : ICoreWebView2ControllerOptions; + var aResult : HResult): boolean; +begin + Result := False; + aOptions := nil; + aResult := E_FAIL; + + if assigned(FBaseIntf10) then + begin + aResult := FBaseIntf10.CreateCoreWebView2ControllerOptions(aOptions); + Result := succeeded(aResult); + end + else + aResult := E_NOTIMPL; +end; + +function TCoreWebView2Environment.CreateCoreWebView2ControllerWithOptions( aParentWindow : HWND; + const aOptions : ICoreWebView2ControllerOptions; + const aBrowserEvents : IWVBrowserEvents; + var aResult : HResult): boolean; +var + TempHandler : ICoreWebView2CreateCoreWebView2ControllerCompletedHandler; +begin + Result := False; + aResult := E_FAIL; + + if assigned(FBaseIntf10) then + try + TempHandler := TCoreWebView2CreateCoreWebView2ControllerCompletedHandler.Create(aBrowserEvents); + aResult := FBaseIntf10.CreateCoreWebView2ControllerWithOptions(aParentWindow, aOptions, TempHandler); + Result := succeeded(aResult); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Environment.CreateCoreWebView2CompositionControllerWithOptions( aParentWindow : HWND; + const aOptions : ICoreWebView2ControllerOptions; + const aBrowserEvents : IWVBrowserEvents; + var aResult : HResult): boolean; +var + TempHandler: ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler; +begin + Result := False; + aResult := E_FAIL; + + if assigned(FBaseIntf10) then + try + TempHandler := TCoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler.Create(aBrowserEvents); + aResult := FBaseIntf10.CreateCoreWebView2CompositionControllerWithOptions(aParentWindow, aOptions, TempHandler); + Result := succeeded(aResult); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Environment.CreateSharedBuffer( aSize : Largeuint; + var aSharedBuffer : ICoreWebView2SharedBuffer) : boolean; +var + TempBuffer : ICoreWebView2SharedBuffer; +begin + Result := False; + TempBuffer := nil; + aSharedBuffer := nil; + + if assigned(FBaseIntf12) and + succeeded(FBaseIntf12.CreateSharedBuffer(aSize, TempBuffer)) and + (TempBuffer <> nil) then + begin + aSharedBuffer := TempBuffer; + Result := True; + end; +end; + +function TCoreWebView2Environment.GetProcessExtendedInfos(const aBrowserEvents : IWVBrowserEvents) : boolean; +var + TempHandler: ICoreWebView2GetProcessExtendedInfosCompletedHandler; +begin + Result := False; + + if assigned(FBaseIntf13) then + try + TempHandler := TCoreWebView2GetProcessExtendedInfosCompletedHandler.Create(aBrowserEvents); + Result := succeeded(FBaseIntf13.GetProcessExtendedInfos(TempHandler)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Environment.CreateWebFileSystemFileHandle(const aPath : wvstring; + aPermission : TWVFileSystemHandlePermission; + var aValue : ICoreWebView2FileSystemHandle): boolean; +begin + aValue := nil; + Result := assigned(FBaseIntf14) and + succeeded(FBaseIntf14.CreateWebFileSystemFileHandle(PWideChar(aPath), aPermission, aValue)) and + assigned(aValue); +end; + +function TCoreWebView2Environment.CreateWebFileSystemDirectoryHandle(const aPath : wvstring; + aPermission : TWVFileSystemHandlePermission; + var aValue : ICoreWebView2FileSystemHandle): boolean; +begin + aValue := nil; + Result := assigned(FBaseIntf14) and + succeeded(FBaseIntf14.CreateWebFileSystemDirectoryHandle(PWideChar(aPath), aPermission, aValue)) and + assigned(aValue); +end; + +function TCoreWebView2Environment.CreateObjectCollection( aLength : cardinal; + var aItems : IUnknown; + var aObjectCollection : ICoreWebView2ObjectCollection): boolean; +begin + aObjectCollection := nil; + Result := assigned(FBaseIntf14) and + succeeded(FBaseIntf14.CreateObjectCollection(aLength, aItems, aObjectCollection)) and + assigned(aObjectCollection); +end; + +function TCoreWebView2Environment.CreateFindOptions(var aFindOptions : ICoreWebView2FindOptions): boolean; +begin + Result := assigned(FBaseIntf15) and + succeeded(FBaseIntf15.CreateFindOptions(aFindOptions)) and + assigned(aFindOptions); +end; + +function TCoreWebView2Environment.GetUserDataFolder : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + + if assigned(FBaseIntf7) then + begin + TempString := nil; + + if succeeded(FBaseIntf7.Get_UserDataFolder(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; + end; +end; + +function TCoreWebView2Environment.GetProcessInfos : ICoreWebView2ProcessInfoCollection; +var + TempResult : ICoreWebView2ProcessInfoCollection; +begin + Result := nil; + TempResult := nil; + + if assigned(FBaseIntf8) and + succeeded(FBaseIntf8.GetProcessInfos(TempResult)) and + assigned(TempResult) then + Result := TempResult; +end; + +function TCoreWebView2Environment.GetFailureReportFolderPath : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + + if assigned(FBaseIntf11) then + begin + TempString := nil; + + if succeeded(FBaseIntf11.Get_FailureReportFolderPath(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; + end; +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2EnvironmentOptions.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2EnvironmentOptions.pas new file mode 100644 index 000000000..e5f162489 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2EnvironmentOptions.pas @@ -0,0 +1,402 @@ +unit uRESTDWPrivWVCoreWebView2EnvironmentOptions; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + WinApi.Windows, Winapi.ActiveX, + {$ELSE} + Windows, ActiveX, + {$ENDIF} + uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVTypes; + +type + /// + /// Options used to create WebView2 Environment. A default implementation is + /// provided in WebView2EnvironmentOptions.h. + /// + /// + /// See the ICoreWebView2EnvironmentOptions article. + /// + TCoreWebView2EnvironmentOptions = class(TInterfacedObject, + ICoreWebView2EnvironmentOptions, + ICoreWebView2EnvironmentOptions2, + ICoreWebView2EnvironmentOptions3, + ICoreWebView2EnvironmentOptions4, + ICoreWebView2EnvironmentOptions5, + ICoreWebView2EnvironmentOptions6, + ICoreWebView2EnvironmentOptions7, + ICoreWebView2EnvironmentOptions8) + protected + FAdditionalBrowserArguments : wvstring; + FLanguage : wvstring; + FTargetCompatibleBrowserVersion : wvstring; + FAllowSingleSignOnUsingOSPrimaryAccount : boolean; + FExclusiveUserDataFolderAccess : boolean; + FCustomCrashReportingEnabled : boolean; + FSchemeRegistrations : TWVCustomSchemeRegistrationArray; + FEnableTrackingPrevention : boolean; + FAreBrowserExtensionsEnabled : boolean; + FChannelSearchKind : TWVChannelSearchKind; + FReleaseChannels : TWVReleaseChannels; + FScrollBarStyle : TWVScrollBarStyle; + + // ICoreWebView2EnvironmentOptions + function Get_AdditionalBrowserArguments(out value: PWideChar): HResult; stdcall; + function Set_AdditionalBrowserArguments(value: PWideChar): HResult; stdcall; + function Get_Language(out value: PWideChar): HResult; stdcall; + function Set_Language(value: PWideChar): HResult; stdcall; + function Get_TargetCompatibleBrowserVersion(out value: PWideChar): HResult; stdcall; + function Set_TargetCompatibleBrowserVersion(value: PWideChar): HResult; stdcall; + function Get_AllowSingleSignOnUsingOSPrimaryAccount(out allow: Integer): HResult; stdcall; + function Set_AllowSingleSignOnUsingOSPrimaryAccount(allow: Integer): HResult; stdcall; + + // ICoreWebView2EnvironmentOptions2 + function Get_ExclusiveUserDataFolderAccess(out value: Integer): HResult; stdcall; + function Set_ExclusiveUserDataFolderAccess(value: Integer): HResult; stdcall; + + // ICoreWebView2EnvironmentOptions3 + function Get_IsCustomCrashReportingEnabled(out value: Integer): HResult; stdcall; + function Set_IsCustomCrashReportingEnabled(value: Integer): HResult; stdcall; + + // ICoreWebView2EnvironmentOptions4 + function GetCustomSchemeRegistrations(out Count: SYSUINT; out schemeRegistrations: PPCoreWebView2CustomSchemeRegistration): HResult; stdcall; + function SetCustomSchemeRegistrations(Count: SYSUINT; schemeRegistrations: PPCoreWebView2CustomSchemeRegistration): HResult; stdcall; + + // ICoreWebView2EnvironmentOptions5 + function Get_EnableTrackingPrevention(out value: Integer): HResult; stdcall; + function Set_EnableTrackingPrevention(value: Integer): HResult; stdcall; + + // ICoreWebView2EnvironmentOptions6 + function Get_AreBrowserExtensionsEnabled(out value: Integer): HResult; stdcall; + function Set_AreBrowserExtensionsEnabled(value: Integer): HResult; stdcall; + + // ICoreWebView2EnvironmentOptions7 + function Get_ChannelSearchKind(out value: COREWEBVIEW2_CHANNEL_SEARCH_KIND): HResult; stdcall; + function Set_ChannelSearchKind(value: COREWEBVIEW2_CHANNEL_SEARCH_KIND): HResult; stdcall; + function Get_ReleaseChannels(out value: COREWEBVIEW2_RELEASE_CHANNELS): HResult; stdcall; + function Set_ReleaseChannels(value: COREWEBVIEW2_RELEASE_CHANNELS): HResult; stdcall; + + // ICoreWebView2EnvironmentOptions8 + function Get_ScrollBarStyle(out value: COREWEBVIEW2_SCROLLBAR_STYLE): HResult; stdcall; + function Set_ScrollBarStyle(value: COREWEBVIEW2_SCROLLBAR_STYLE): HResult; stdcall; + + procedure DestroySchemeRegistrations; + + public + /// + /// Constructor of the ICoreWebView2EnvironmentOptions wrapper. + /// + /// Additional command line switches. + /// The default display language for WebView. It applies to browser UI such as context menu and dialogs. It also applies to the `accept-languages` HTTP header that WebView sends to websites. + /// Specifies the version of the WebView2 Runtime binaries required to be compatible with your app. + /// Used to enable single sign on with Azure Active Directory (AAD) and personal Microsoft Account (MSA) resources inside WebView. + /// Whether other processes can create WebView2 from WebView2Environment created with the same user data folder and therefore sharing the same WebView browser process instance. + /// Send crash data to Microsoft endpoint or respect OS consent. + /// Array of custom scheme registrations. + /// Enable tracking prevention. + /// If it's set to True, new extensions can be added to user profile and used. + /// WebView2 Runtime channel search order. + /// Indicates which channels environment creation should search for. + /// The ScrollBar style being set on the WebView2 Environment. + /// + /// See the ICoreWebView2EnvironmentOptions article. + /// See the ICoreWebView2EnvironmentOptions2 article. + /// See the ICoreWebView2EnvironmentOptions3 article. + /// See the ICoreWebView2EnvironmentOptions4 article. + /// See the ICoreWebView2EnvironmentOptions5 article. + /// See the ICoreWebView2EnvironmentOptions6 article. + /// See the ICoreWebView2EnvironmentOptions7 article. + /// See the ICoreWebView2EnvironmentOptions8 article. + /// + constructor Create(const aAdditionalBrowserArguments, aLanguage, aTargetCompatibleBrowserVersion : wvstring; aAllowSingleSignOnUsingOSPrimaryAccount, aExclusiveUserDataFolderAccess, aCustomCrashReportingEnabled : boolean; const aSchemeRegistrations: TWVCustomSchemeRegistrationArray; aEnableTrackingPrevention, aAreBrowserExtensionsEnabled: boolean; aChannelSearchKind : TWVChannelSearchKind; aReleaseChannels : TWVReleaseChannels; aScrollBarStyle: TWVScrollBarStyle); + destructor Destroy; override; + end; + +implementation + +uses + uRESTDWPrivWVMiscFunctions; + +constructor TCoreWebView2EnvironmentOptions.Create(const aAdditionalBrowserArguments : wvstring; + const aLanguage : wvstring; + const aTargetCompatibleBrowserVersion : wvstring; + aAllowSingleSignOnUsingOSPrimaryAccount : boolean; + aExclusiveUserDataFolderAccess : boolean; + aCustomCrashReportingEnabled : boolean; + const aSchemeRegistrations : TWVCustomSchemeRegistrationArray; + aEnableTrackingPrevention : boolean; + aAreBrowserExtensionsEnabled : boolean; + aChannelSearchKind : TWVChannelSearchKind; + aReleaseChannels : TWVReleaseChannels; + aScrollBarStyle : TWVScrollBarStyle); +var + i : integer; +begin + inherited Create; + + FAdditionalBrowserArguments := aAdditionalBrowserArguments; + FLanguage := aLanguage; + FTargetCompatibleBrowserVersion := aTargetCompatibleBrowserVersion; + FAllowSingleSignOnUsingOSPrimaryAccount := aAllowSingleSignOnUsingOSPrimaryAccount; + FExclusiveUserDataFolderAccess := aExclusiveUserDataFolderAccess; + FCustomCrashReportingEnabled := aCustomCrashReportingEnabled; + FSchemeRegistrations := nil; + FEnableTrackingPrevention := aEnableTrackingPrevention; + FAreBrowserExtensionsEnabled := aAreBrowserExtensionsEnabled; + FChannelSearchKind := aChannelSearchKind; + FReleaseChannels := aReleaseChannels; + FScrollBarStyle := aScrollBarStyle; + + if assigned(aSchemeRegistrations) then + begin + i := length(aSchemeRegistrations); + SetLength(FSchemeRegistrations, i); + ZeroMemory(FSchemeRegistrations, i * SizeOf(ICoreWebView2CustomSchemeRegistration)); + + dec(i); + while (i >= 0) do + begin + FSchemeRegistrations[i] := aSchemeRegistrations[i]; + dec(i); + end; + end; +end; + +destructor TCoreWebView2EnvironmentOptions.Destroy; +begin + DestroySchemeRegistrations; + + inherited Destroy; +end; + +procedure TCoreWebView2EnvironmentOptions.DestroySchemeRegistrations; +var + i : integer; +begin + if assigned(FSchemeRegistrations) then + try + i := pred(length(FSchemeRegistrations)); + + while (i >= 0) do + begin + FSchemeRegistrations[i] := nil; + dec(i); + end; + finally + SetLength(FSchemeRegistrations, 0); + end; +end; + +function TCoreWebView2EnvironmentOptions.Get_AdditionalBrowserArguments(out value: PWideChar): HResult; stdcall; +begin + Result := S_OK; + value := AllocCoTaskMemStr(FAdditionalBrowserArguments); +end; + +function TCoreWebView2EnvironmentOptions.Set_AdditionalBrowserArguments(value: PWideChar): HResult; stdcall; +begin + Result := S_OK; + + if (value <> nil) then + begin + FAdditionalBrowserArguments := value; + CoTaskMemFree(value); + end + else + FAdditionalBrowserArguments := ''; +end; + +function TCoreWebView2EnvironmentOptions.Get_Language(out value: PWideChar): HResult; stdcall; +begin + Result := S_OK; + value := AllocCoTaskMemStr(FLanguage); +end; + +function TCoreWebView2EnvironmentOptions.Set_Language(value: PWideChar): HResult; stdcall; +begin + Result := S_OK; + + if (value <> nil) then + begin + FLanguage := value; + CoTaskMemFree(value); + end + else + FLanguage := ''; +end; + +function TCoreWebView2EnvironmentOptions.Get_TargetCompatibleBrowserVersion(out value: PWideChar): HResult; stdcall; +begin + Result := S_OK; + value := AllocCoTaskMemStr(FTargetCompatibleBrowserVersion); +end; + +function TCoreWebView2EnvironmentOptions.Set_TargetCompatibleBrowserVersion(value: PWideChar): HResult; stdcall; +begin + Result := S_OK; + + if (value <> nil) then + begin + FTargetCompatibleBrowserVersion := value; + CoTaskMemFree(value); + end + else + FTargetCompatibleBrowserVersion := ''; +end; + +function TCoreWebView2EnvironmentOptions.Get_AllowSingleSignOnUsingOSPrimaryAccount(out allow: Integer): HResult; stdcall; +begin + Result := S_OK; + allow := ord(FAllowSingleSignOnUsingOSPrimaryAccount); +end; + +function TCoreWebView2EnvironmentOptions.Set_AllowSingleSignOnUsingOSPrimaryAccount(allow: Integer): HResult; stdcall; +begin + Result := S_OK; + FAllowSingleSignOnUsingOSPrimaryAccount := (allow <> 0); +end; + +function TCoreWebView2EnvironmentOptions.Get_ExclusiveUserDataFolderAccess(out value: Integer): HResult; stdcall; +begin + Result := S_OK; + value := ord(FExclusiveUserDataFolderAccess); +end; + +function TCoreWebView2EnvironmentOptions.Set_ExclusiveUserDataFolderAccess(value: Integer): HResult; stdcall; +begin + Result := S_OK; + FExclusiveUserDataFolderAccess := (value <> 0); +end; + +function TCoreWebView2EnvironmentOptions.Get_IsCustomCrashReportingEnabled(out value: Integer): HResult; stdcall; +begin + Result := S_OK; + value := ord(FCustomCrashReportingEnabled); +end; + +function TCoreWebView2EnvironmentOptions.Set_IsCustomCrashReportingEnabled(value: Integer): HResult; stdcall; +begin + Result := S_OK; + FCustomCrashReportingEnabled := (value <> 0); +end; + +function TCoreWebView2EnvironmentOptions.GetCustomSchemeRegistrations(out Count : SYSUINT; + out schemeRegistrations : PPCoreWebView2CustomSchemeRegistration): HResult; stdcall; +var + TempArray : PPCoreWebView2CustomSchemeRegistration; + i : SYSUINT; + TempLen : integer; +begin + Result := S_OK; + Count := length(FSchemeRegistrations); + schemeRegistrations := nil; + + if (Count = 0) then exit; + + TempLen := Count * SizeOf(ICoreWebView2CustomSchemeRegistration); + schemeRegistrations := CoTaskMemAlloc(TempLen); + TempArray := schemeRegistrations; + ZeroMemory(TempArray, TempLen); + + i := 0; + while (i < count) do + begin + TempArray^ := FSchemeRegistrations[i]; + inc(TempArray); + inc(i); + end; +end; + +function TCoreWebView2EnvironmentOptions.SetCustomSchemeRegistrations(Count : SYSUINT; + schemeRegistrations : PPCoreWebView2CustomSchemeRegistration): HResult; stdcall; +var + TempArray : PPCoreWebView2CustomSchemeRegistration; + i : SYSUINT; +begin + Result := S_OK; + DestroySchemeRegistrations; + + if (Count = 0) then exit; + + SetLength(FSchemeRegistrations, Count); + ZeroMemory(FSchemeRegistrations, Count * SizeOf(ICoreWebView2CustomSchemeRegistration)); + + TempArray := schemeRegistrations; + i := 0; + + while (i < Count) do + begin + FSchemeRegistrations[i] := TempArray^; + inc(TempArray); + inc(i); + end; + + CoTaskMemFree(schemeRegistrations); +end; + +function TCoreWebView2EnvironmentOptions.Get_EnableTrackingPrevention(out value: Integer): HResult; stdcall; +begin + Result := S_OK; + value := ord(FEnableTrackingPrevention); +end; + +function TCoreWebView2EnvironmentOptions.Set_EnableTrackingPrevention(value: Integer): HResult; stdcall; +begin + Result := S_OK; + FEnableTrackingPrevention := (value <> 0); +end; + +function TCoreWebView2EnvironmentOptions.Get_AreBrowserExtensionsEnabled(out value: Integer): HResult; stdcall; +begin + Result := S_OK; + value := ord(FAreBrowserExtensionsEnabled); +end; + +function TCoreWebView2EnvironmentOptions.Set_AreBrowserExtensionsEnabled(value: Integer): HResult; stdcall; +begin + Result := S_OK; + FAreBrowserExtensionsEnabled := (value <> 0); +end; + +function TCoreWebView2EnvironmentOptions.Get_ChannelSearchKind(out value: COREWEBVIEW2_CHANNEL_SEARCH_KIND): HResult; stdcall; +begin + Result := S_OK; + value := FChannelSearchKind; +end; + +function TCoreWebView2EnvironmentOptions.Set_ChannelSearchKind(value: COREWEBVIEW2_CHANNEL_SEARCH_KIND): HResult; stdcall; +begin + Result := S_OK; + FChannelSearchKind := value; +end; + +function TCoreWebView2EnvironmentOptions.Get_ReleaseChannels(out value: COREWEBVIEW2_RELEASE_CHANNELS): HResult; stdcall; +begin + Result := S_OK; + value := FReleaseChannels; +end; + +function TCoreWebView2EnvironmentOptions.Set_ReleaseChannels(value: COREWEBVIEW2_RELEASE_CHANNELS): HResult; stdcall; +begin + Result := S_OK; + FReleaseChannels := value; +end; + +function TCoreWebView2EnvironmentOptions.Get_ScrollBarStyle(out value: COREWEBVIEW2_SCROLLBAR_STYLE): HResult; stdcall; +begin + Result := S_OK; + value := FScrollBarStyle; +end; + +function TCoreWebView2EnvironmentOptions.Set_ScrollBarStyle(value: COREWEBVIEW2_SCROLLBAR_STYLE): HResult; stdcall; +begin + Result := S_OK; + FScrollBarStyle := value; +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Find.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Find.pas new file mode 100644 index 000000000..a59e92096 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Find.pas @@ -0,0 +1,272 @@ +unit uRESTDWPrivWVCoreWebView2Find; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + System.Classes, System.Types, System.UITypes, System.SysUtils, Winapi.ActiveX, + {$ELSE} + Classes, Graphics, SysUtils, ActiveX, + {$ENDIF} + uRESTDWPrivWVTypeLibrary; + +type + /// + /// Class providing methods and properties for finding and navigating through text in the web view. + /// This class allows for finding text, navigation between matches, and customization of the find UI. + /// + /// + /// See the ICoreWebView2Find article. + /// + TCoreWebView2Find = class + protected + FBaseIntf : ICoreWebView2Find; + FActiveMatchIndexChangedToken : EventRegistrationToken; + FMatchCountChangedToken : EventRegistrationToken; + + function GetInitialized : boolean; + function GetActiveMatchIndex : integer; + function GetMatchCount : integer; + + procedure InitializeFields; + procedure InitializeTokens; + procedure RemoveAllEvents; + + function AddActiveMatchIndexChangedEvent(const aBrowserComponent : TComponent) : boolean; + function AddMatchCountChangedEvent(const aBrowserComponent : TComponent) : boolean; + + public + constructor Create(const aBaseIntf : ICoreWebView2Find); reintroduce; + destructor Destroy; override; + /// + /// Adds all the events of this class to an existing TWVBrowserBase instance. + /// + /// The TWVBrowserBase instance. + function AddAllBrowserEvents(const aBrowserComponent : TComponent) : boolean; + /// + /// Initiates a find using the specified find options asynchronously. + /// Displays the Find bar and starts the find session. If a find session was already ongoing, it will be stopped and replaced with this new instance. + /// If called with an empty string, the Find bar is displayed but no finding occurs. Changing the FindOptions object after initiation won't affect the ongoing find session. + /// To change the ongoing find session, Start must be called again with a new or modified FindOptions object. + /// Start supports HTML and TXT document queries. In general, this API is designed for text-based find sessions. + /// If you start a find session programmatically on another file format that doesn't have text fields, the find session will try to execute but will fail to find any matches. (It will silently fail) + /// Note: The asynchronous action completes when the UI has been displayed with the find term in the UI bar, and the matches have populated on the counter on the find bar. + /// There may be a slight latency between the UI display and the matches populating in the counter. + /// The MatchCountChanged and ActiveMatchIndexChanged events are only raised after Start has completed; otherwise, they will have their default values (-1 for active match index and 0 for match count). + /// To start a new find session (beginning the search from the first match), call `Stop` before invoking `Start`. + /// If `Start` is called consecutively with the same options and without calling `Stop`, the find session + /// will continue from the current position in the existing session. + /// Calling `Start` without altering its parameters will behave either as `FindNext` or `FindPrevious`, depending on the most recent search action performed. + /// Start will default to forward if neither have been called. + /// However, calling Start again during an ongoing find session does not resume from the point + /// of the current active match. For example, given the text "1 1 A 1 1" and initiating a find session for "A", + /// then starting another find session for "1", it will start searching from the beginning of the document, + /// regardless of the previous active match. This behavior indicates that changing the find query initiates a + /// completely new find session, rather than continuing from the previous match index. + /// + /// + /// See the ICoreWebView2Find article. + /// + function Start(const options: ICoreWebView2FindOptions; + const handler: ICoreWebView2FindStartCompletedHandler) : boolean; + /// + /// Navigates to the next match in the document. + /// If there are no matches to find, FindNext will wrap around to the first match's index. + /// If called when there is no find session active, FindNext will silently fail. + /// + /// + /// See the ICoreWebView2Find article. + /// + function FindNext : boolean; + /// + /// Navigates to the previous match in the document. + /// If there are no matches to find, FindPrevious will wrap around to the last match's index. + /// If called when there is no find session active, FindPrevious will silently fail. + /// + /// + /// See the ICoreWebView2Find article. + /// + function FindPrevious : boolean; + /// + /// Stops the current 'Find' session and hides the Find bar. + /// If called with no Find session active, it will silently do nothing. + /// + /// + /// See the ICoreWebView2Find article. + /// + function Stop : boolean; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2Find read FBaseIntf; + /// + /// Retrieves the index of the currently active match in the find session. Returns the index of the currently active match, or -1 if there is no active match. + /// The index starts at 1 for the first match. + /// + /// + /// See the ICoreWebView2Find article. + /// + property ActiveMatchIndex : integer read GetActiveMatchIndex; + /// + /// Gets the total count of matches found in the current document based on the last find sessions criteria. Returns the total count of matches. + /// + /// + /// See the ICoreWebView2Find article. + /// + property MatchCount : integer read GetMatchCount; + end; + +implementation + +uses + uRESTDWPrivWVMiscFunctions, uRESTDWPrivWVBrowserBase, uRESTDWPrivWVCoreWebView2Delegates; + +constructor TCoreWebView2Find.Create(const aBaseIntf: ICoreWebView2Find); +begin + inherited Create; + + InitializeFields; + + FBaseIntf := aBaseIntf; +end; + +destructor TCoreWebView2Find.Destroy; +begin + try + RemoveAllEvents; + InitializeFields; + finally + inherited Destroy; + end; +end; + +procedure TCoreWebView2Find.InitializeFields; +begin + FBaseIntf := nil; + + InitializeTokens; +end; + +procedure TCoreWebView2Find.InitializeTokens; +begin + FActiveMatchIndexChangedToken.value := 0; + FMatchCountChangedToken.value := 0; +end; + +procedure TCoreWebView2Find.RemoveAllEvents; +begin + if Initialized then + try + try + if (FActiveMatchIndexChangedToken.value <> 0) then + FBaseIntf.remove_ActiveMatchIndexChanged(FActiveMatchIndexChangedToken); + + if (FMatchCountChangedToken.value <> 0) then + FBaseIntf.remove_MatchCountChanged(FMatchCountChangedToken); + except + on e : exception do + if CustomExceptionHandler('TCoreWebView2Find.RemoveAllEvents', e) then raise; + end; + finally + InitializeTokens; + end; +end; + +function TCoreWebView2Find.AddActiveMatchIndexChangedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2FindActiveMatchIndexChangedEventHandler; +begin + Result := False; + + if Initialized and (FActiveMatchIndexChangedToken.value = 0) then + try + TempHandler := TCoreWebView2FindActiveMatchIndexChangedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_ActiveMatchIndexChanged(TempHandler, FActiveMatchIndexChangedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Find.AddMatchCountChangedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2FindMatchCountChangedEventHandler; +begin + Result := False; + + if Initialized and (FMatchCountChangedToken.value = 0) then + try + TempHandler := TCoreWebView2FindMatchCountChangedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf.add_MatchCountChanged(TempHandler, FMatchCountChangedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Find.AddAllBrowserEvents(const aBrowserComponent : TComponent) : boolean; +begin + Result := AddActiveMatchIndexChangedEvent(aBrowserComponent) and + AddMatchCountChangedEvent(aBrowserComponent); +end; + +function TCoreWebView2Find.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2Find.GetActiveMatchIndex : integer; +var + TempResult : SYSINT; +begin + if Initialized and + succeeded(FBaseIntf.Get_ActiveMatchIndex(TempResult)) then + Result := TempResult + else + Result := -1; +end; + +function TCoreWebView2Find.GetMatchCount : integer; +var + TempResult : SYSINT; +begin + if Initialized and + succeeded(FBaseIntf.Get_MatchCount(TempResult)) then + Result := TempResult + else + Result := 0; +end; + +function TCoreWebView2Find.Start(const options: ICoreWebView2FindOptions; + const handler: ICoreWebView2FindStartCompletedHandler) : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.Start(options, handler)); +end; + +function TCoreWebView2Find.FindNext : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.FindNext); +end; + +function TCoreWebView2Find.FindPrevious : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.FindPrevious); +end; + +function TCoreWebView2Find.Stop : boolean; +begin + Result := Initialized and + succeeded(FBaseIntf.Stop); +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2FindOptions.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2FindOptions.pas new file mode 100644 index 000000000..e85351ba7 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2FindOptions.pas @@ -0,0 +1,210 @@ +unit uRESTDWPrivWVCoreWebView2FindOptions; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + Winapi.ActiveX, + {$ELSE} + ActiveX, + {$ENDIF} + uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVTypes; + +type + /// + /// Class defining the find options. + /// This class provides the necessary methods and properties to configure a find session. + /// + /// + /// See the ICoreWebView2FindOptions article. + /// + TCoreWebView2FindOptions = class + protected + FBaseIntf : ICoreWebView2FindOptions; + + function GetInitialized: boolean; + function GetFindTerm: wvstring; + function GetIsCaseSensitive: boolean; + function GetShouldHighlightAllMatches: boolean; + function GetShouldMatchWord: boolean; + function GetSuppressDefaultFindDialog: boolean; + + procedure SetFindTerm(const aValue: wvstring); + procedure SetIsCaseSensitive(aValue: boolean); + procedure SetShouldHighlightAllMatches(aValue: boolean); + procedure SetShouldMatchWord(aValue: boolean); + procedure SetSuppressDefaultFindDialog(aValue: boolean); + + public + constructor Create(const aBaseIntf : ICoreWebView2FindOptions); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2FindOptions read FBaseIntf; + /// + /// Gets or sets the word or phrase to be searched in the current page. + /// You can set `FindTerm` to any text you want to find on the page. + /// This will take effect the next time you call the `Start()` method. + /// + /// + /// See the ICoreWebView2FindOptions article. + /// + property FindTerm : wvstring read GetFindTerm write SetFindTerm; + /// + /// Determines if the find session is case sensitive. Returns TRUE if the find is case sensitive, FALSE otherwise. + /// When toggling case sensitivity, the behavior can vary by locale, which may be influenced by both the browser's UI locale and the document's language settings. The browser's UI locale + /// typically provides a default handling approach, while the document's language settings (e.g., specified using the HTML lang attribute) can override these defaults to apply locale-specific rules. This dual consideration + /// ensures that text is processed in a manner consistent with user expectations and the linguistic context of the content. + /// + /// + /// See the ICoreWebView2FindOptions article. + /// + property IsCaseSensitive : boolean read GetIsCaseSensitive write SetIsCaseSensitive; + /// + /// Gets or sets the state of whether all matches are highlighted. + /// Returns TRUE if all matches are highlighted, FALSE otherwise. + /// Note: Changes to this property take effect only when Start, FindNext, or FindPrevious is called. + /// Preferences for the session cannot be updated unless another call to the Start function on the server-side is made. + /// Therefore, changes will not take effect until one of these functions is called. + /// + /// + /// See the ICoreWebView2FindOptions article. + /// + property ShouldHighlightAllMatches : boolean read GetShouldHighlightAllMatches write SetShouldHighlightAllMatches; + /// + /// Similar to case sensitivity, word matching also can vary by locale, which may be influenced by both the browser's UI locale and the document's language settings. The browser's UI locale + /// typically provides a default handling approach, while the document's language settings (e.g., specified using the HTML lang attribute) can override these defaults to apply locale-specific rules. This dual consideration + /// ensures that text is processed in a manner consistent with user expectations and the linguistic context of the content. + /// ShouldMatchWord determines if only whole words should be matched during the find session. Returns TRUE if only whole words should be matched, FALSE otherwise. + /// + /// + /// See the ICoreWebView2FindOptions article. + /// + property ShouldMatchWord : boolean read GetShouldMatchWord write SetShouldMatchWord; + /// + /// Sets this property to hide the default Find UI. + /// You can use this to hide the default UI so that you can show your own custom UI or programmatically interact with the Find API while showing no Find UI. + /// Returns TRUE if hiding the default Find UI and FALSE if using showing the default Find UI. + /// Note: Changes to this property take effect only when Start, FindNext, or FindPrevious is called. + /// Preferences for the session cannot be updated unless another call to the Start function on the server-side is made. + /// Therefore, changes will not take effect until one of these functions is called. + /// + /// + /// See the ICoreWebView2FindOptions article. + /// + property SuppressDefaultFindDialog : boolean read GetSuppressDefaultFindDialog write SetSuppressDefaultFindDialog; + end; + +implementation + +constructor TCoreWebView2FindOptions.Create(const aBaseIntf: ICoreWebView2FindOptions); +begin + inherited Create; + + FBaseIntf := aBaseIntf; +end; + +destructor TCoreWebView2FindOptions.Destroy; +begin + FBaseIntf := nil; + + inherited Destroy; +end; + +function TCoreWebView2FindOptions.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2FindOptions.GetFindTerm: wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.Get_FindTerm(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2FindOptions.GetIsCaseSensitive: boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_IsCaseSensitive(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2FindOptions.GetShouldHighlightAllMatches: boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_ShouldHighlightAllMatches(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2FindOptions.GetShouldMatchWord: boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_ShouldMatchWord(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2FindOptions.GetSuppressDefaultFindDialog: boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_SuppressDefaultFindDialog(TempResult)) and + (TempResult <> 0); +end; + +procedure TCoreWebView2FindOptions.SetFindTerm(const aValue: wvstring); +begin + if Initialized then + FBaseIntf.Set_FindTerm(PWideChar(aValue)); +end; + +procedure TCoreWebView2FindOptions.SetIsCaseSensitive(aValue: boolean); +begin + if Initialized then + FBaseIntf.Set_IsCaseSensitive(ord(aValue)); +end; + +procedure TCoreWebView2FindOptions.SetShouldHighlightAllMatches(aValue: boolean); +begin + if Initialized then + FBaseIntf.Set_ShouldHighlightAllMatches(ord(aValue)); +end; + +procedure TCoreWebView2FindOptions.SetShouldMatchWord(aValue: boolean); +begin + if Initialized then + FBaseIntf.Set_ShouldMatchWord(ord(aValue)); +end; + +procedure TCoreWebView2FindOptions.SetSuppressDefaultFindDialog(aValue: boolean); +begin + if Initialized then + FBaseIntf.Set_SuppressDefaultFindDialog(ord(aValue)); +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2PrintSettings.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2PrintSettings.pas new file mode 100644 index 000000000..638480c9a --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2PrintSettings.pas @@ -0,0 +1,661 @@ +unit uRESTDWPrivWVCoreWebView2PrintSettings; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + System.Types, Winapi.ActiveX, + {$ELSE} + ActiveX, + {$ENDIF} + uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVTypes; + +type + /// + /// Settings used by the PrintToPdf method. + /// + /// + /// See the ICoreWebView2PrintSettings article. + /// + TCoreWebView2PrintSettings = class + protected + FBaseIntf : ICoreWebView2PrintSettings; + FBaseIntf2 : ICoreWebView2PrintSettings2; + + function GetInitialized : boolean; + function GetOrientation : TWVPrintOrientation; + function GetScaleFactor : double; + function GetPageWidth : double; + function GetPageHeight : double; + function GetMarginTop : double; + function GetMarginBottom : double; + function GetMarginLeft : double; + function GetMarginRight : double; + function GetShouldPrintBackgrounds : boolean; + function GetShouldPrintSelectionOnly : boolean; + function GetShouldPrintHeaderAndFooter : boolean; + function GetHeaderTitle : wvstring; + function GetFooterUri : wvstring; + function GetPageRanges : wvstring; + function GetPagesPerSide : integer; + function GetCopies : integer; + function GetCollation : TWVPrintCollation; + function GetColorMode : TWVPrintColorMode; + function GetDuplex : TWVPrintDuplex; + function GetMediaSize : TWVPrintMediaSize; + function GetPrinterName : wvstring; + + procedure SetOrientation(aValue : TWVPrintOrientation); + procedure SetScaleFactor(const aValue : double); + procedure SetPageWidth(const aValue : double); + procedure SetPageHeight(const aValue : double); + procedure SetMarginTop(const aValue : double); + procedure SetMarginBottom(const aValue : double); + procedure SetMarginLeft(const aValue : double); + procedure SetMarginRight(const aValue : double); + procedure SetShouldPrintBackgrounds(aValue : boolean); + procedure SetShouldPrintSelectionOnly(aValue : boolean); + procedure SetShouldPrintHeaderAndFooter(aValue : boolean); + procedure SetHeaderTitle(const aValue : wvstring); + procedure SetFooterUri(const aValue : wvstring); + procedure SetPageRanges(const aValue : wvstring); + procedure SetPagesPerSide(aValue : integer); + procedure SetCopies(aValue : integer); + procedure SetCollation(aValue : TWVPrintCollation); + procedure SetColorMode(aValue : TWVPrintColorMode); + procedure SetDuplex(aValue : TWVPrintDuplex); + procedure SetMediaSize(aValue : TWVPrintMediaSize); + procedure SetPrinterName(const aValue : wvstring); + + public + constructor Create(const aBaseIntf : ICoreWebView2PrintSettings); reintroduce; + destructor Destroy; override; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2PrintSettings read FBaseIntf; + + /// + /// The orientation can be portrait or landscape. The default orientation is + /// portrait. See `COREWEBVIEW2_PRINT_ORIENTATION`. + /// + /// + /// See the ICoreWebView2PrintSettings article. + /// + property Orientation : TWVPrintOrientation read GetOrientation write SetOrientation; + /// + /// The scale factor is a value between 0.1 and 2.0. The default is 1.0. + /// + /// + /// See the ICoreWebView2PrintSettings article. + /// + property ScaleFactor : double read GetScaleFactor write SetScaleFactor; + /// + /// The page width in inches. The default width is 8.5 inches. + /// + /// + /// See the ICoreWebView2PrintSettings article. + /// + property PageWidth : double read GetPageWidth write SetPageWidth; + /// + /// The page height in inches. The default height is 11 inches. + /// + /// + /// See the ICoreWebView2PrintSettings article. + /// + property PageHeight : double read GetPageHeight write SetPageHeight; + /// + /// The top margin in inches. The default is 1 cm, or ~0.4 inches. + /// + /// + /// See the ICoreWebView2PrintSettings article. + /// + property MarginTop : double read GetMarginTop write SetMarginTop; + /// + /// The bottom margin in inches. The default is 1 cm, or ~0.4 inches. + /// + /// + /// See the ICoreWebView2PrintSettings article. + /// + property MarginBottom : double read GetMarginBottom write SetMarginBottom; + /// + /// The left margin in inches. The default is 1 cm, or ~0.4 inches. + /// + /// + /// See the ICoreWebView2PrintSettings article. + /// + property MarginLeft : double read GetMarginLeft write SetMarginLeft; + /// + /// The right margin in inches. The default is 1 cm, or ~0.4 inches. + /// + /// + /// See the ICoreWebView2PrintSettings article. + /// + property MarginRight : double read GetMarginRight write SetMarginRight; + /// + /// `TRUE` if background colors and images should be printed. The default value + /// is `FALSE`. + /// + /// + /// See the ICoreWebView2PrintSettings article. + /// + property ShouldPrintBackgrounds : boolean read GetShouldPrintBackgrounds write SetShouldPrintBackgrounds; + /// + /// `TRUE` if only the current end user's selection of HTML in the document + /// should be printed. The default value is `FALSE`. + /// + /// + /// See the ICoreWebView2PrintSettings article. + /// + property ShouldPrintSelectionOnly : boolean read GetShouldPrintSelectionOnly write SetShouldPrintSelectionOnly; + /// + /// `TRUE` if header and footer should be printed. The default value is `FALSE`. + /// The header consists of the date and time of printing, and the title of the + /// page. The footer consists of the URI and page number. The height of the + /// header and footer is 0.5 cm, or ~0.2 inches. + /// + /// + /// See the ICoreWebView2PrintSettings article. + /// + property ShouldPrintHeaderAndFooter : boolean read GetShouldPrintHeaderAndFooter write SetShouldPrintHeaderAndFooter; + /// + /// The title in the header if `ShouldPrintHeaderAndFooter` is `TRUE`. The + /// default value is the title of the current document. + /// + /// + /// See the ICoreWebView2PrintSettings article. + /// + property HeaderTitle : wvstring read GetHeaderTitle write SetHeaderTitle; + /// + /// The URI in the footer if `ShouldPrintHeaderAndFooter` is `TRUE`. The + /// default value is the current URI. + /// + /// + /// See the ICoreWebView2PrintSettings article. + /// + property FooterUri : wvstring read GetFooterUri write SetFooterUri; + /// + /// Page range to print. + /// + /// + /// See the ICoreWebView2PrintSettings2 article. + /// + property PageRanges : wvstring read GetPageRanges write SetPageRanges; + /// + /// Prints multiple pages of a document on a single piece of paper. Choose from 1, 2, 4, 6, 9 or 16. + /// The default value is 1. + /// + /// + /// See the ICoreWebView2PrintSettings2 article. + /// + property PagesPerSide : integer read GetPagesPerSide write SetPagesPerSide; + /// + /// Number of copies to print. Minimum value is `1` and the maximum copies count is `999`. + /// The default value is 1. + /// This value is ignored in PrintToPdfStream method. + /// + /// + /// See the ICoreWebView2PrintSettings2 article. + /// + property Copies : integer read GetCopies write SetCopies; + /// + /// Printer collation. See `COREWEBVIEW2_PRINT_COLLATION` for descriptions of + /// collation. The default value is `COREWEBVIEW2_PRINT_COLLATION_DEFAULT`. + /// Printing uses default value of printer's collation if an invalid value is provided + /// for the specific printer. This value is ignored in PrintToPdfStream method. + /// + /// + /// See the ICoreWebView2PrintSettings2 article. + /// + property Collation : TWVPrintCollation read GetCollation write SetCollation; + /// + /// Printer color mode. See `COREWEBVIEW2_PRINT_COLOR_MODE` for descriptions + /// of color modes. The default value is `COREWEBVIEW2_PRINT_COLOR_MODE_DEFAULT`. + /// Printing uses default value of printer supported color if an invalid value is provided + /// for the specific printer. + /// + /// + /// See the ICoreWebView2PrintSettings2 article. + /// + property ColorMode : TWVPrintColorMode read GetColorMode write SetColorMode; + /// + /// Printer duplex settings. See `COREWEBVIEW2_PRINT_DUPLEX` for descriptions of duplex. + /// The default value is `COREWEBVIEW2_PRINT_DUPLEX_DEFAULT`. + /// Printing uses default value of printer's duplex if an invalid value is provided + /// for the specific printer. This value is ignored in PrintToPdfStream method. + /// + /// + /// See the ICoreWebView2PrintSettings2 article. + /// + property Duplex : TWVPrintDuplex read GetDuplex write SetDuplex; + /// + /// Printer media size. See `COREWEBVIEW2_PRINT_MEDIA_SIZE` for descriptions of media size. + /// The default value is `COREWEBVIEW2_PRINT_MEDIA_SIZE_DEFAULT`. + /// If media size is `COREWEBVIEW2_PRINT_MEDIA_SIZE_CUSTOM`, you should set the `PageWidth` + /// and `PageHeight`. + /// Printing uses default value of printer supported media size if an invalid value is provided + /// for the specific printer. This value is ignored in PrintToPdfStream method. + /// + /// + /// See the ICoreWebView2PrintSettings2 article. + /// + property MediaSize : TWVPrintMediaSize read GetMediaSize write SetMediaSize; + /// + /// The name of the printer to use. Defaults to empty string. + /// If the printer name is empty string or null, then it prints to the default + /// printer on the user OS. This value is ignored in PrintToPdfStream method. + /// + /// + /// See the ICoreWebView2PrintSettings2 article. + /// + property PrinterName : wvstring read GetPrinterName write SetPrinterName; + end; + +implementation + +uses + uRESTDWPrivWVMiscFunctions, uRESTDWPrivWVConstants; + +constructor TCoreWebView2PrintSettings.Create(const aBaseIntf: ICoreWebView2PrintSettings); +begin + inherited Create; + + FBaseIntf := aBaseIntf; + + if Initialized then + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2PrintSettings2, FBaseIntf2); +end; + +destructor TCoreWebView2PrintSettings.Destroy; +begin + FBaseIntf := nil; + FBaseIntf2 := nil; + + inherited Destroy; +end; + +function TCoreWebView2PrintSettings.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2PrintSettings.GetOrientation : TWVPrintOrientation; +var + TempResult : COREWEBVIEW2_PRINT_ORIENTATION; +begin + if Initialized and + succeeded(FBaseIntf.Get_Orientation(TempResult)) then + Result := TempResult + else + Result := 0; +end; + +function TCoreWebView2PrintSettings.GetScaleFactor : double; +var + TempResult : double; +begin + if Initialized and + succeeded(FBaseIntf.Get_ScaleFactor(TempResult)) then + Result := TempResult + else + Result := 0; +end; + +function TCoreWebView2PrintSettings.GetPageWidth : double; +var + TempResult : double; +begin + if Initialized and + succeeded(FBaseIntf.Get_PageWidth(TempResult)) then + Result := TempResult + else + Result := 0; +end; + +function TCoreWebView2PrintSettings.GetPageHeight : double; +var + TempResult : double; +begin + if Initialized and + succeeded(FBaseIntf.Get_PageHeight(TempResult)) then + Result := TempResult + else + Result := 0; +end; + +function TCoreWebView2PrintSettings.GetMarginTop : double; +var + TempResult : double; +begin + if Initialized and + succeeded(FBaseIntf.Get_MarginTop(TempResult)) then + Result := TempResult + else + Result := 0; +end; + +function TCoreWebView2PrintSettings.GetMarginBottom : double; +var + TempResult : double; +begin + if Initialized and + succeeded(FBaseIntf.Get_MarginBottom(TempResult)) then + Result := TempResult + else + Result := 0; +end; + +function TCoreWebView2PrintSettings.GetMarginLeft : double; +var + TempResult : double; +begin + if Initialized and + succeeded(FBaseIntf.Get_MarginLeft(TempResult)) then + Result := TempResult + else + Result := 0; +end; + +function TCoreWebView2PrintSettings.GetMarginRight : double; +var + TempResult : double; +begin + if Initialized and + succeeded(FBaseIntf.Get_MarginRight(TempResult)) then + Result := TempResult + else + Result := 0; +end; + +function TCoreWebView2PrintSettings.GetShouldPrintBackgrounds : boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_ShouldPrintBackgrounds(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2PrintSettings.GetShouldPrintSelectionOnly : boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_ShouldPrintSelectionOnly(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2PrintSettings.GetShouldPrintHeaderAndFooter : boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_ShouldPrintHeaderAndFooter(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2PrintSettings.GetHeaderTitle : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.get_HeaderTitle(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2PrintSettings.GetFooterUri : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if Initialized and + succeeded(FBaseIntf.get_FooterUri(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2PrintSettings.GetPageRanges : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_PageRanges(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +function TCoreWebView2PrintSettings.GetPagesPerSide : integer; +var + TempResult : SYSINT; +begin + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_PagesPerSide(TempResult)) then + Result := TempResult + else + Result := WEBVIEW4DELPHI_PRINT_PAGESPERSIDE_DEFAULT; +end; + +function TCoreWebView2PrintSettings.GetCopies : integer; +var + TempResult : SYSINT; +begin + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_Copies(TempResult)) then + Result := TempResult + else + Result := WEBVIEW4DELPHI_PRINT_COPIES_DEFAULT; +end; + +function TCoreWebView2PrintSettings.GetCollation : TWVPrintCollation; +var + TempResult : COREWEBVIEW2_PRINT_COLLATION; +begin + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_Collation(TempResult)) then + Result := TempResult + else + Result := COREWEBVIEW2_PRINT_COLLATION_DEFAULT; +end; + +function TCoreWebView2PrintSettings.GetColorMode : TWVPrintColorMode; +var + TempResult : COREWEBVIEW2_PRINT_COLOR_MODE; +begin + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_ColorMode(TempResult)) then + Result := TempResult + else + Result := COREWEBVIEW2_PRINT_COLOR_MODE_DEFAULT; +end; + +function TCoreWebView2PrintSettings.GetDuplex : TWVPrintDuplex; +var + TempResult : COREWEBVIEW2_PRINT_DUPLEX; +begin + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_Duplex(TempResult)) then + Result := TempResult + else + Result := COREWEBVIEW2_PRINT_DUPLEX_DEFAULT; +end; + +function TCoreWebView2PrintSettings.GetMediaSize : TWVPrintMediaSize; +var + TempResult : COREWEBVIEW2_PRINT_MEDIA_SIZE; +begin + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_MediaSize(TempResult)) then + Result := TempResult + else + Result := COREWEBVIEW2_PRINT_MEDIA_SIZE_DEFAULT; +end; + +function TCoreWebView2PrintSettings.GetPrinterName : wvstring; +var + TempString : PWideChar; +begin + Result := ''; + TempString := nil; + + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_PrinterName(TempString)) then + begin + Result := TempString; + CoTaskMemFree(TempString); + end; +end; + +procedure TCoreWebView2PrintSettings.SetOrientation(aValue : TWVPrintOrientation); +begin + if Initialized then + FBaseIntf.Set_Orientation(aValue); +end; + +procedure TCoreWebView2PrintSettings.SetScaleFactor(const aValue : double); +begin + if Initialized then + FBaseIntf.Set_ScaleFactor(aValue); +end; + +procedure TCoreWebView2PrintSettings.SetPageWidth(const aValue : double); +begin + if Initialized then + FBaseIntf.Set_PageWidth(aValue); +end; + +procedure TCoreWebView2PrintSettings.SetPageHeight(const aValue : double); +begin + if Initialized then + FBaseIntf.Set_PageHeight(aValue); +end; + +procedure TCoreWebView2PrintSettings.SetMarginTop(const aValue : double); +begin + if Initialized then + FBaseIntf.Set_MarginTop(aValue); +end; + +procedure TCoreWebView2PrintSettings.SetMarginBottom(const aValue : double); +begin + if Initialized then + FBaseIntf.Set_MarginBottom(aValue); +end; + +procedure TCoreWebView2PrintSettings.SetMarginLeft(const aValue : double); +begin + if Initialized then + FBaseIntf.Set_MarginLeft(aValue); +end; + +procedure TCoreWebView2PrintSettings.SetMarginRight(const aValue : double); +begin + if Initialized then + FBaseIntf.Set_MarginRight(aValue); +end; + +procedure TCoreWebView2PrintSettings.SetShouldPrintBackgrounds(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_ShouldPrintBackgrounds(ord(aValue)); +end; + +procedure TCoreWebView2PrintSettings.SetShouldPrintSelectionOnly(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_ShouldPrintSelectionOnly(ord(aValue)); +end; + +procedure TCoreWebView2PrintSettings.SetShouldPrintHeaderAndFooter(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_ShouldPrintHeaderAndFooter(ord(aValue)); +end; + +procedure TCoreWebView2PrintSettings.SetHeaderTitle(const aValue : wvstring); +begin + if Initialized then + FBaseIntf.Set_HeaderTitle(PWideChar(aValue)); +end; + +procedure TCoreWebView2PrintSettings.SetFooterUri(const aValue : wvstring); +begin + if Initialized then + FBaseIntf.Set_FooterUri(PWideChar(aValue)); +end; + +procedure TCoreWebView2PrintSettings.SetPageRanges(const aValue : wvstring); +begin + if assigned(FBaseIntf2) then + FBaseIntf2.Set_PageRanges(PWideChar(aValue)); +end; + +procedure TCoreWebView2PrintSettings.SetPagesPerSide(aValue : integer); +begin + if assigned(FBaseIntf2) and (aValue in WEBVIEW4DELPHI_PRINT_PAGESPERSIDE_VALID) then + FBaseIntf2.Set_PagesPerSide(aValue); +end; + +procedure TCoreWebView2PrintSettings.SetCopies(aValue : integer); +begin + if assigned(FBaseIntf2) then + FBaseIntf2.Set_Copies(aValue); +end; + +procedure TCoreWebView2PrintSettings.SetCollation(aValue : TWVPrintCollation); +begin + if assigned(FBaseIntf2) then + FBaseIntf2.Set_Collation(aValue); +end; + +procedure TCoreWebView2PrintSettings.SetColorMode(aValue : TWVPrintColorMode); +begin + if assigned(FBaseIntf2) then + FBaseIntf2.Set_ColorMode(aValue); +end; + +procedure TCoreWebView2PrintSettings.SetDuplex(aValue : TWVPrintDuplex); +begin + if assigned(FBaseIntf2) then + FBaseIntf2.Set_Duplex(aValue); +end; + +procedure TCoreWebView2PrintSettings.SetMediaSize(aValue : TWVPrintMediaSize); +begin + if assigned(FBaseIntf2) then + FBaseIntf2.Set_MediaSize(aValue); +end; + +procedure TCoreWebView2PrintSettings.SetPrinterName(const aValue : wvstring); +begin + // Use EnumPrinters to enumerate available printers. + // https://learn.microsoft.com/en-us/windows/win32/printdocs/enumprinters + + if assigned(FBaseIntf2) then + FBaseIntf2.Set_PrinterName(PWideChar(aValue)); +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Profile.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Profile.pas new file mode 100644 index 000000000..f8bc9c6d8 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Profile.pas @@ -0,0 +1,724 @@ +unit uRESTDWPrivWVCoreWebView2Profile; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + System.Classes, + {$ELSE} + Classes, + {$ENDIF} + uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVTypes; + +type + /// + /// Provides a set of properties to configure a Profile object. + /// + /// + /// See the ICoreWebView2Profile article. + /// + TCoreWebView2Profile = class + protected + FBaseIntf : ICoreWebView2Profile; + FBaseIntf2 : ICoreWebView2Profile2; + FBaseIntf3 : ICoreWebView2Profile3; + FBaseIntf4 : ICoreWebView2Profile4; + FBaseIntf5 : ICoreWebView2Profile5; + FBaseIntf6 : ICoreWebView2Profile6; + FBaseIntf7 : ICoreWebView2Profile7; + FBaseIntf8 : ICoreWebView2Profile8; + FBaseIntf9 : ICoreWebView2Profile9; + + FProfileDeletedToken : EventRegistrationToken; + + function GetInitialized : boolean; + function GetProfileName : wvstring; + function GetIsInPrivateModeEnabled : boolean; + function GetProfilePath : wvstring; + function GetDefaultDownloadFolderPath : wvstring; + function GetPreferredColorScheme : TWVPreferredColorScheme; + function GetPreferredTrackingPreventionLevel : TWVTrackingPreventionLevel; + function GetCookieManager : ICoreWebView2CookieManager; + function GetIsPasswordAutosaveEnabled : boolean; + function GetIsGeneralAutofillEnabled : boolean; + function GetAreWebViewScriptApisEnabledForServiceWorkers : boolean; + function GetServiceWorkerManager : ICoreWebView2ServiceWorkerManager; + function GetSharedWorkerManager : ICoreWebView2SharedWorkerManager; + + procedure SetDefaultDownloadFolderPath(const aValue : wvstring); + procedure SetPreferredColorScheme(aValue : TWVPreferredColorScheme); + procedure SetPreferredTrackingPreventionLevel(aValue : TWVTrackingPreventionLevel); + procedure SetIsPasswordAutosaveEnabled(aValue : boolean); + procedure SetIsGeneralAutofillEnabled(aValue : boolean); + procedure SetAreWebViewScriptApisEnabledForServiceWorkers(aValue : boolean); + + procedure InitializeFields; + procedure InitializeTokens; + procedure RemoveAllEvents; + function AddProfileDeletedEvent(const aBrowserComponent : TComponent) : boolean; + + public + constructor Create(const aBaseIntf : ICoreWebView2Profile); reintroduce; + destructor Destroy; override; + /// + /// Adds all the events of this class to an existing TWVBrowserBase instance. + /// + /// The TWVBrowserBase instance. + function AddAllBrowserEvents(const aBrowserComponent : TComponent) : boolean; + /// + /// Clear browsing data based on a data type. This method takes two parameters, + /// the first being a mask of one or more `COREWEBVIEW2_BROWSING_DATA_KINDS`. OR + /// operation(s) can be applied to multiple `COREWEBVIEW2_BROWSING_DATA_KINDS` to + /// create a mask representing those data types. The browsing data kinds that are + /// supported are listed below. These data kinds follow a hierarchical structure in + /// which nested bullet points are included in their parent bullet point's data kind. + /// Ex: All DOM storage is encompassed in all site data which is encompassed in + /// all profile data. + /// * All Profile + /// * All Site Data + /// * All DOM Storage: File Systems, Indexed DB, Local Storage, Web SQL, Cache + /// Storage + /// * Cookies + /// * Disk Cache + /// * Download History + /// * General Autofill + /// * Password Autosave + /// * Browsing History + /// * Settings + /// The completed handler will be invoked when the browsing data has been cleared and + /// will indicate if the specified data was properly cleared. In the case in which + /// the operation is interrupted and the corresponding data is not fully cleared + /// the handler will return `E_ABORT` and otherwise will return `S_OK`. + /// Because this is an asynchronous operation, code that is dependent on the cleared + /// data must be placed in the callback of this operation. + /// If the WebView object is closed before the clear browsing data operation + /// has completed, the handler will be released, but not invoked. In this case + /// the clear browsing data operation may or may not be completed. + /// ClearBrowsingData clears the `dataKinds` regardless of timestamp. + /// + /// + /// See the ICoreWebView2Profile2 article. + /// + function ClearBrowsingData(dataKinds: TWVBrowsingDataKinds; const handler: ICoreWebView2ClearBrowsingDataCompletedHandler): boolean; + /// + /// ClearBrowsingDataInTimeRange behaves like ClearBrowsingData except that it + /// takes in two additional parameters for the start and end time for which it + /// should clear the data between. The `startTime` and `endTime` + /// parameters correspond to the number of seconds since the UNIX epoch. + /// `startTime` is inclusive while `endTime` is exclusive, therefore the data will + /// be cleared between [startTime, endTime). + /// + /// + /// See the ICoreWebView2Profile2 article. + /// + function ClearBrowsingDataInTimeRange(dataKinds: TWVBrowsingDataKinds; const startTime, endTime: TDateTime; const handler: ICoreWebView2ClearBrowsingDataCompletedHandler): boolean; + /// + /// ClearBrowsingDataAll behaves like ClearBrowsingData except that it + /// clears the entirety of the data associated with the profile it is called on. + /// It clears the data regardless of timestamp. + /// + /// + /// See the ICoreWebView2Profile2 article. + /// + function ClearBrowsingDataAll(const handler: ICoreWebView2ClearBrowsingDataCompletedHandler): boolean; + /// + /// Sets permission state for the given permission kind and origin + /// asynchronously. The change persists across sessions until it is changed by + /// another call to `SetPermissionState`, or by setting the `State` property + /// in `PermissionRequestedEventArgs`. Setting the state to + /// `COREWEBVIEW2_PERMISSION_STATE_DEFAULT` will erase any state saved in the + /// profile and restore the default behavior. + /// The origin should have a valid scheme and host (e.g. "https://www.example.com"), + /// otherwise the method fails with `E_INVALIDARG`. Additional URI parts like + /// path and fragment are ignored. For example, "https://wwww.example.com/app1/index.html/" + /// is treated the same as "https://wwww.example.com". See the + /// [MDN origin definition](https://developer.mozilla.org/docs/Glossary/Origin) + /// for more details. + /// + /// + /// See the ICoreWebView2Profile4 article. + /// + function SetPermissionState(PermissionKind: TWVPermissionKind; const origin: wvstring; State: TWVPermissionState; const completedHandler: ICoreWebView2SetPermissionStateCompletedHandler): boolean; + /// + /// Invokes the handler with a collection of all nondefault permission settings. + /// Use this method to get the permission state set in the current and previous + /// sessions. + /// + /// + /// See the ICoreWebView2Profile4 article. + /// + function GetNonDefaultPermissionSettings(const completedHandler: ICoreWebView2GetNonDefaultPermissionSettingsCompletedHandler): boolean; + /// + /// Adds the [browser extension](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions) + /// using the extension path for unpacked extensions from the local device. Extension is + /// running right after installation. + /// The extension folder path is the topmost folder of an unpacked browser extension and + /// contains the browser extension manifest file. + /// If the `extensionFolderPath` is an invalid path or doesn't contain the extension manifest.json + /// file, this function will return `ERROR_FILE_NOT_FOUND` to callers. + /// Installed extension will default `IsEnabled` to true. + /// When `AreBrowserExtensionsEnabled` is `FALSE`, `AddBrowserExtension` will fail and return + /// HRESULT `ERROR_NOT_SUPPORTED`. + /// During installation, the content of the extension is not copied to the user data folder. + /// Once the extension is installed, changing the content of the extension will cause the + /// extension to be removed from the installed profile. + /// When an extension is added the extension is persisted in the corresponding profile. The + /// extension will still be installed the next time you use this profile. + /// When an extension is installed from a folder path, adding the same extension from the same + /// folder path means reinstalling this extension. When two extensions with the same Id are + /// installed, only the later installed extension will be kept. + /// Extensions that are designed to include any UI interactions (e.g. icon, badge, pop up, etc.) + /// can be loaded and used but will have missing UI entry points due to the lack of browser + /// UI elements to host these entry points in WebView2. + /// The following summarizes the possible error values that can be returned from + /// `AddBrowserExtension` and a description of why these errors occur. + /// + /// Error value | Description + /// ----------------------------------------------- | -------------------------- + /// `HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)` | Extensions are disabled. + /// `HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)` | Cannot find `manifest.json` file or it is not a valid extension manifest. + /// `E_ACCESSDENIED` | Cannot load extension with file or directory name starting with \"_\", reserved for use by the system. + /// `E_FAIL` | Extension failed to install with other unknown reasons. + /// + /// + /// + /// See the ICoreWebView2Profile7 article. + /// + function AddBrowserExtension(const extensionFolderPath: wvstring; const completedHandler: ICoreWebView2ProfileAddBrowserExtensionCompletedHandler): boolean; + /// + /// Gets a snapshot of the set of extensions installed at the time `GetBrowserExtensions` is + /// called. If an extension is installed or uninstalled after `GetBrowserExtensions` completes, + /// the list returned by `GetBrowserExtensions` remains the same. + /// When `AreBrowserExtensionsEnabled` is `FALSE`, `GetBrowserExtensions` won't return any + /// extensions on current user profile. + /// + /// + /// See the ICoreWebView2Profile7 article. + /// + function GetBrowserExtensions(const completedHandler: ICoreWebView2ProfileGetBrowserExtensionsCompletedHandler): boolean; + /// + /// After the API is called, the profile will be marked for deletion. The + /// local profile's directory will be deleted at browser process exit. If it + /// fails to delete, because something else is holding the files open, + /// WebView2 will try to delete the profile at all future browser process + /// starts until successful. + /// The corresponding CoreWebView2s will be closed and the + /// ICoreWebView2Profile.Deleted event will be raised. See + /// `ICoreWebView2Profile.Deleted` for more information. + /// If you try to create a new profile with the same name as an existing + /// profile that has been marked as deleted but hasn't yet been deleted, + /// profile creation will fail with HRESULT_FROM_WIN32(ERROR_DELETE_PENDING). + /// + /// + /// See the ICoreWebView2Profile8 article. + /// + function Delete: boolean; + + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2Profile read FBaseIntf write FBaseIntf; + /// + /// Name of the profile. + /// + /// + /// See the ICoreWebView2Profile article. + /// + property ProfileName : wvstring read GetProfileName; + /// + /// InPrivate mode is enabled or not. + /// + /// + /// See the ICoreWebView2Profile article. + /// + property IsInPrivateModeEnabled : boolean read GetIsInPrivateModeEnabled; + /// + /// Full path of the profile directory. + /// + /// + /// See the ICoreWebView2Profile article. + /// + property ProfilePath : wvstring read GetProfilePath; + /// + /// Gets the `DefaultDownloadFolderPath` property. The default value is the + /// system default download folder path for the user. + /// + /// + /// See the ICoreWebView2Profile article. + /// + property DefaultDownloadFolderPath : wvstring read GetDefaultDownloadFolderPath write SetDefaultDownloadFolderPath; + /// + /// The PreferredColorScheme property sets the overall color scheme of the + /// WebView2s associated with this profile. This sets the color scheme for + /// WebView2 UI like dialogs, prompts, and context menus by setting the + /// media feature `prefers-color-scheme` for websites to respond to. + /// The default value for this is COREWEBVIEW2_PREFERRED_COLOR_AUTO, + /// which will follow whatever theme the OS is currently set to. + /// Returns the value of the `PreferredColorScheme` property. + /// + /// + /// See the ICoreWebView2Profile article. + /// + property PreferredColorScheme : TWVPreferredColorScheme read GetPreferredColorScheme write SetPreferredColorScheme; + /// + /// The `PreferredTrackingPreventionLevel` property allows you to control levels of tracking prevention for WebView2 + /// which are associated with a profile. This level would apply to the context of the profile. That is, all WebView2s + /// sharing the same profile will be affected and also the value is persisted in the user data folder. + /// See `COREWEBVIEW2_TRACKING_PREVENTION_LEVEL` for descriptions of levels. + /// If tracking prevention feature is enabled when creating the WebView2 environment, you can also disable tracking + /// prevention later using this property and `COREWEBVIEW2_TRACKING_PREVENTION_LEVEL_NONE` value but that doesn't + /// improves runtime performance. + /// There is `ICoreWebView2EnvironmentOptions5::EnableTrackingPrevention` property to enable/disable tracking prevention feature + /// for all the WebView2's created in the same environment. If enabled, `PreferredTrackingPreventionLevel` is set to + /// `COREWEBVIEW2_TRACKING_PREVENTION_LEVEL_BALANCED` by default for all the WebView2's and profiles created in the same + /// environment or is set to the level whatever value was last changed/persisted to the profile. If disabled + /// `PreferredTrackingPreventionLevel` is not respected by WebView2. If `PreferredTrackingPreventionLevel` is set when the + /// feature is disabled, the property value get changed and persisted but it will takes effect only if + /// `ICoreWebView2EnvironmentOptions5::EnableTrackingPrevention` is true. + /// + /// + /// See the ICoreWebView2Profile3 article. + /// + property PreferredTrackingPreventionLevel : TWVTrackingPreventionLevel read GetPreferredTrackingPreventionLevel write SetPreferredTrackingPreventionLevel; + /// + /// Get the cookie manager for the profile. All CoreWebView2s associated with this + /// profile share the same cookie values. Changes to cookies in this cookie manager apply to all + /// CoreWebView2s associated with this profile. See ICoreWebView2CookieManager. + /// + /// + /// See the ICoreWebView2Profile5 article. + /// + property CookieManager : ICoreWebView2CookieManager read GetCookieManager; + /// + /// IsPasswordAutosaveEnabled controls whether autosave for password + /// information is enabled. The IsPasswordAutosaveEnabled property behaves + /// independently of the IsGeneralAutofillEnabled property. When IsPasswordAutosaveEnabled is + /// false, no new password data is saved and no Save/Update Password prompts are displayed. + /// However, if there was password data already saved before disabling this setting, + /// then that password information is auto-populated, suggestions are shown and clicking on + /// one will populate the fields. + /// When IsPasswordAutosaveEnabled is true, password information is auto-populated, + /// suggestions are shown and clicking on one will populate the fields, new data + /// is saved, and a Save/Update Password prompt is displayed. + /// It will take effect immediately after setting. The default value is `FALSE`. + /// This property has the same value as + /// `CoreWebView2Settings.IsPasswordAutosaveEnabled`, and changing one will + /// change the other. All `CoreWebView2`s with the same `CoreWebView2Profile` + /// will share the same value for this property, so for the `CoreWebView2`s + /// with the same profile, their + /// `CoreWebView2Settings.IsPasswordAutosaveEnabled` and + /// `CoreWebView2Profile.IsPasswordAutosaveEnabled` will always have the same + /// value. + /// + /// + /// See the ICoreWebView2Profile6 article. + /// + property IsPasswordAutosaveEnabled : boolean read GetIsPasswordAutosaveEnabled write SetIsPasswordAutosaveEnabled; + /// + /// IsGeneralAutofillEnabled controls whether autofill for information + /// like names, street and email addresses, phone numbers, and arbitrary input + /// is enabled. This excludes password and credit card information. When + /// IsGeneralAutofillEnabled is false, no suggestions appear, and no new information + /// is saved. When IsGeneralAutofillEnabled is true, information is saved, suggestions + /// appear and clicking on one will populate the form fields. + /// It will take effect immediately after setting. The default value is `TRUE`. + /// This property has the same value as + /// `CoreWebView2Settings.IsGeneralAutofillEnabled`, and changing one will + /// change the other. All `CoreWebView2`s with the same `CoreWebView2Profile` + /// will share the same value for this property, so for the `CoreWebView2`s + /// with the same profile, their + /// `CoreWebView2Settings.IsGeneralAutofillEnabled` and + /// `CoreWebView2Profile.IsGeneralAutofillEnabled` will always have the same + /// value. + /// + /// + /// See the ICoreWebView2Profile6 article. + /// + property IsGeneralAutofillEnabled : boolean read GetIsGeneralAutofillEnabled write SetIsGeneralAutofillEnabled; + /// + /// Enables or disables webview2 specific Service Worker JS APIs in the + /// WebView2s associated with this Profile. When set to `TRUE`, chrome and + /// webview objects are available in Service Workers. chrome.webview exposes + /// APIs to interact with the WebView from Service Workers. The default value + /// is `FALSE`. This setting applies to all newly installed Service Workers + /// within the profile and is not persisted across WebView2 sessions. + /// + /// + /// See the ICoreWebView2Profile9 article. + /// + property AreWebViewScriptApisEnabledForServiceWorkers : boolean read GetAreWebViewScriptApisEnabledForServiceWorkers write SetAreWebViewScriptApisEnabledForServiceWorkers; + /// + /// Get the service worker manager to monitor service worker registrations and + /// interact with the service workers associated with the current profile. + /// + /// + /// See the ICoreWebView2Profile9 article. + /// + property ServiceWorkerManager : ICoreWebView2ServiceWorkerManager read GetServiceWorkerManager; + /// + /// Get the shared worker manager to monitor shared worker creations and interact + /// with the shared workers associated with the current profile. + /// + /// + /// See the ICoreWebView2Profile9 article. + /// + property SharedWorkerManager : ICoreWebView2SharedWorkerManager read GetSharedWorkerManager; + end; + +implementation + +uses + {$IFDEF DELPHI16_UP} + System.DateUtils, Winapi.ActiveX, + {$ELSE} + DateUtils, ActiveX, + {$ENDIF} + uRESTDWPrivWVMiscFunctions, uRESTDWPrivWVCoreWebView2Delegates, uRESTDWPrivWVBrowserBase; + +constructor TCoreWebView2Profile.Create(const aBaseIntf: ICoreWebView2Profile); +begin + inherited Create; + + InitializeFields; + + FBaseIntf := aBaseIntf; + + if Initialized and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Profile2, FBaseIntf2) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Profile3, FBaseIntf3) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Profile4, FBaseIntf4) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Profile5, FBaseIntf5) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Profile6, FBaseIntf6) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Profile7, FBaseIntf7) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Profile8, FBaseIntf8) then + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Profile9, FBaseIntf9); +end; + +destructor TCoreWebView2Profile.Destroy; +begin + try + RemoveAllEvents; + InitializeFields; + finally + inherited Destroy; + end; +end; + +procedure TCoreWebView2Profile.InitializeFields; +begin + FBaseIntf := nil; + FBaseIntf2 := nil; + FBaseIntf3 := nil; + FBaseIntf4 := nil; + FBaseIntf5 := nil; + FBaseIntf6 := nil; + FBaseIntf7 := nil; + FBaseIntf8 := nil; + FBaseIntf9 := nil; + + InitializeTokens; +end; + +procedure TCoreWebView2Profile.InitializeTokens; +begin + FProfileDeletedToken.value := 0; +end; + +procedure TCoreWebView2Profile.RemoveAllEvents; +begin + if Initialized then + begin + if assigned(FBaseIntf8) and (FProfileDeletedToken.value <> 0) then + FBaseIntf8.remove_Deleted(FProfileDeletedToken); + + InitializeTokens; + end; +end; + +function TCoreWebView2Profile.AddProfileDeletedEvent(const aBrowserComponent : TComponent) : boolean; +var + TempHandler : ICoreWebView2ProfileDeletedEventHandler; +begin + Result := False; + + if Initialized and assigned(FBaseIntf8) and (FProfileDeletedToken.value = 0) then + try + TempHandler := TCoreWebView2ProfileDeletedEventHandler.Create(TWVBrowserBase(aBrowserComponent)); + Result := succeeded(FBaseIntf8.add_Deleted(TempHandler, FProfileDeletedToken)); + finally + TempHandler := nil; + end; +end; + +function TCoreWebView2Profile.AddAllBrowserEvents(const aBrowserComponent : TComponent) : boolean; +begin + Result := AddProfileDeletedEvent(aBrowserComponent); +end; + +function TCoreWebView2Profile.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2Profile.GetProfileName : wvstring; +var + TempResult : PWideChar; +begin + Result := ''; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_ProfileName(TempResult)) and + (TempResult <> nil) then + begin + Result := TempResult; + CoTaskMemFree(TempResult); + end; +end; + +function TCoreWebView2Profile.GetIsInPrivateModeEnabled : boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_IsInPrivateModeEnabled(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Profile.GetProfilePath : wvstring; +var + TempResult : PWideChar; +begin + Result := ''; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_ProfilePath(TempResult)) and + (TempResult <> nil) then + begin + Result := TempResult; + CoTaskMemFree(TempResult); + end; +end; + +function TCoreWebView2Profile.GetDefaultDownloadFolderPath : wvstring; +var + TempResult : PWideChar; +begin + Result := ''; + TempResult := nil; + + if Initialized and + succeeded(FBaseIntf.Get_DefaultDownloadFolderPath(TempResult)) and + (TempResult <> nil) then + begin + Result := TempResult; + CoTaskMemFree(TempResult); + end; +end; + +function TCoreWebView2Profile.GetPreferredColorScheme : TWVPreferredColorScheme; +var + TempResult : COREWEBVIEW2_PREFERRED_COLOR_SCHEME; +begin + Result := 0; + TempResult := 0; + + if Initialized and + succeeded(FBaseIntf.Get_PreferredColorScheme(TempResult)) then + Result := TempResult; +end; + +function TCoreWebView2Profile.GetPreferredTrackingPreventionLevel : TWVTrackingPreventionLevel; +var + TempResult : COREWEBVIEW2_TRACKING_PREVENTION_LEVEL; +begin + Result := COREWEBVIEW2_TRACKING_PREVENTION_LEVEL_BALANCED; + + if assigned(FBaseIntf3) and + succeeded(FBaseIntf3.Get_PreferredTrackingPreventionLevel(TempResult)) then + Result := TempResult; +end; + +function TCoreWebView2Profile.GetCookieManager : ICoreWebView2CookieManager; +var + TempResult : ICoreWebView2CookieManager; +begin + Result := nil; + TempResult := nil; + + if assigned(FBaseIntf5) and + succeeded(FBaseIntf5.Get_CookieManager(TempResult)) and + assigned(TempResult) then + Result := TempResult; +end; + +function TCoreWebView2Profile.GetIsPasswordAutosaveEnabled : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf6) and + succeeded(FBaseIntf6.Get_IsPasswordAutosaveEnabled(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Profile.GetIsGeneralAutofillEnabled : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf6) and + succeeded(FBaseIntf6.Get_IsGeneralAutofillEnabled(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Profile.GetAreWebViewScriptApisEnabledForServiceWorkers : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf9) and + succeeded(FBaseIntf9.Get_AreWebViewScriptApisEnabledForServiceWorkers(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Profile.GetServiceWorkerManager : ICoreWebView2ServiceWorkerManager; +var + TempResult : ICoreWebView2ServiceWorkerManager; +begin + Result := nil; + TempResult := nil; + + if assigned(FBaseIntf9) and + succeeded(FBaseIntf9.Get_ServiceWorkerManager(TempResult)) and + assigned(TempResult) then + Result := TempResult; +end; + +function TCoreWebView2Profile.GetSharedWorkerManager : ICoreWebView2SharedWorkerManager; +var + TempResult : ICoreWebView2SharedWorkerManager; +begin + Result := nil; + TempResult := nil; + + if assigned(FBaseIntf9) and + succeeded(FBaseIntf9.Get_SharedWorkerManager(TempResult)) and + assigned(TempResult) then + Result := TempResult; +end; + +procedure TCoreWebView2Profile.SetDefaultDownloadFolderPath(const aValue : wvstring); +begin + if Initialized then + FBaseIntf.Set_DefaultDownloadFolderPath(PWideChar(aValue)); +end; + +procedure TCoreWebView2Profile.SetPreferredColorScheme(aValue : TWVPreferredColorScheme); +begin + if Initialized then + FBaseIntf.Set_PreferredColorScheme(aValue); +end; + +procedure TCoreWebView2Profile.SetPreferredTrackingPreventionLevel(aValue : TWVTrackingPreventionLevel); +begin + if assigned(FBaseIntf3) then + FBaseIntf3.Set_PreferredTrackingPreventionLevel(aValue); +end; + +procedure TCoreWebView2Profile.SetIsPasswordAutosaveEnabled(aValue: boolean); +begin + if assigned(FBaseIntf6) then + FBaseIntf6.Set_IsPasswordAutosaveEnabled(ord(aValue)); +end; + +procedure TCoreWebView2Profile.SetIsGeneralAutofillEnabled(aValue: boolean); +begin + if assigned(FBaseIntf6) then + FBaseIntf6.Set_IsGeneralAutofillEnabled(ord(aValue)); +end; + +procedure TCoreWebView2Profile.SetAreWebViewScriptApisEnabledForServiceWorkers(aValue : boolean); +begin + if assigned(FBaseIntf9) then + FBaseIntf9.Set_AreWebViewScriptApisEnabledForServiceWorkers(ord(aValue)); +end; + +function TCoreWebView2Profile.ClearBrowsingData( dataKinds : TWVBrowsingDataKinds; + const handler : ICoreWebView2ClearBrowsingDataCompletedHandler): boolean; +begin + Result := assigned(FBaseIntf2) and + assigned(handler) and + succeeded(FBaseIntf2.ClearBrowsingData(dataKinds, handler)); +end; + +function TCoreWebView2Profile.ClearBrowsingDataInTimeRange( dataKinds : TWVBrowsingDataKinds; + const startTime : TDateTime; + const endTime : TDateTime; + const handler : ICoreWebView2ClearBrowsingDataCompletedHandler): boolean; +var + TempStart, TempEnd : int64; +begin + Result := False; + + if assigned(FBaseIntf2) and + assigned(handler) then + begin + TempStart := DateTimeToUnix(startTime{$IFDEF DELPHI20_UP}, False{$ENDIF}); + TempEnd := DateTimeToUnix(endTime{$IFDEF DELPHI20_UP}, False{$ENDIF}); + Result := succeeded(FBaseIntf2.ClearBrowsingDataInTimeRange(dataKinds, TempStart, TempEnd, handler)); + end; +end; + +function TCoreWebView2Profile.ClearBrowsingDataAll(const handler: ICoreWebView2ClearBrowsingDataCompletedHandler): boolean; +begin + Result := assigned(FBaseIntf2) and + assigned(handler) and + succeeded(FBaseIntf2.ClearBrowsingDataAll(handler)); +end; + +function TCoreWebView2Profile.SetPermissionState( PermissionKind : TWVPermissionKind; + const origin : wvstring; + State : TWVPermissionState; + const completedHandler : ICoreWebView2SetPermissionStateCompletedHandler): boolean; +begin + Result := assigned(FBaseIntf4) and + assigned(completedHandler) and + succeeded(FBaseIntf4.SetPermissionState(PermissionKind, PWideChar(origin), State, completedHandler)); +end; + +function TCoreWebView2Profile.GetNonDefaultPermissionSettings(const completedHandler: ICoreWebView2GetNonDefaultPermissionSettingsCompletedHandler): boolean; +begin + Result := assigned(FBaseIntf4) and + assigned(completedHandler) and + succeeded(FBaseIntf4.GetNonDefaultPermissionSettings(completedHandler)); +end; + +function TCoreWebView2Profile.AddBrowserExtension(const extensionFolderPath: wvstring; const completedHandler: ICoreWebView2ProfileAddBrowserExtensionCompletedHandler): boolean; +begin + Result := assigned(FBaseIntf7) and + assigned(completedHandler) and + succeeded(FBaseIntf7.AddBrowserExtension(PWideChar(extensionFolderPath), completedHandler)); +end; + +function TCoreWebView2Profile.GetBrowserExtensions(const completedHandler: ICoreWebView2ProfileGetBrowserExtensionsCompletedHandler): boolean; +begin + Result := assigned(FBaseIntf7) and + assigned(completedHandler) and + succeeded(FBaseIntf7.GetBrowserExtensions(completedHandler)); +end; + +function TCoreWebView2Profile.Delete: boolean; +begin + Result := assigned(FBaseIntf8) and + succeeded(FBaseIntf8.Delete); +end; + +end. + diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Settings.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Settings.pas new file mode 100644 index 000000000..2c2e3545c --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVCoreWebView2Settings.pas @@ -0,0 +1,728 @@ +unit uRESTDWPrivWVCoreWebView2Settings; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVTypes; + +type + /// + /// Defines properties that enable, disable, or modify WebView features. + /// Changes to IsGeneralAutofillEnabled and IsPasswordAutosaveEnabled + /// apply immediately, while other setting changes made after NavigationStarting + /// event do not apply until the next top-level navigation. + /// + /// + /// See the ICoreWebView2Settings article. + /// + TCoreWebView2Settings = class + protected + FBaseIntf : ICoreWebView2Settings; + FBaseIntf2 : ICoreWebView2Settings2; + FBaseIntf3 : ICoreWebView2Settings3; + FBaseIntf4 : ICoreWebView2Settings4; + FBaseIntf5 : ICoreWebView2Settings5; + FBaseIntf6 : ICoreWebView2Settings6; + FBaseIntf7 : ICoreWebView2Settings7; + FBaseIntf8 : ICoreWebView2Settings8; + FBaseIntf9 : ICoreWebView2Settings9; + + function GetInitialized : boolean; + function GetIsBuiltInErrorPageEnabled : boolean; + function GetAreDefaultContextMenusEnabled : boolean; + function GetAreDefaultScriptDialogsEnabled : boolean; + function GetAreDevToolsEnabled : boolean; + function GetIsScriptEnabled : boolean; + function GetIsStatusBarEnabled : boolean; + function GetIsWebMessageEnabled : boolean; + function GetIsZoomControlEnabled : boolean; + function GetAreHostObjectsAllowed : boolean; + function GetUserAgent : wvstring; + function GetAreBrowserAcceleratorKeysEnabled : boolean; + function GetIsPasswordAutosaveEnabled : boolean; + function GetIsGeneralAutofillEnabled : boolean; + function GetIsPinchZoomEnabled : boolean; + function GetIsSwipeNavigationEnabled : boolean; + function GetHiddenPdfToolbarItems : TWVPDFToolbarItems; + function GetIsReputationCheckingRequired : boolean; + function GetIsNonClientRegionSupportEnabled : boolean; + + procedure SetIsBuiltInErrorPageEnabled(aValue : boolean); + procedure SetAreDefaultContextMenusEnabled(aValue : boolean); + procedure SetAreDefaultScriptDialogsEnabled(aValue : boolean); + procedure SetAreDevToolsEnabled(aValue : boolean); + procedure SetIsScriptEnabled(aValue : boolean); + procedure SetIsStatusBarEnabled(aValue : boolean); + procedure SetIsWebMessageEnabled(aValue : boolean); + procedure SetIsZoomControlEnabled(aValue : boolean); + procedure SetAreHostObjectsAllowed(aValue : boolean); + procedure SetUserAgent(const aValue : wvstring); + procedure SetAreBrowserAcceleratorKeysEnabled(aValue : boolean); + procedure SetIsPasswordAutosaveEnabled(aValue : boolean); + procedure SetIsGeneralAutofillEnabled(aValue : boolean); + procedure SetIsPinchZoomEnabled(aValue : boolean); + procedure SetIsSwipeNavigationEnabled(aValue : boolean); + procedure SetHiddenPdfToolbarItems(aValue : TWVPDFToolbarItems); + procedure SetIsReputationCheckingRequired(aValue : boolean); + procedure SetIsNonClientRegionSupportEnabled(aValue : boolean); + + procedure InitializeFields; + + public + constructor Create(const aBaseIntf : ICoreWebView2Settings); reintroduce; + destructor Destroy; override; + /// + /// Returns true when the interface implemented by this class is fully initialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns the interface implemented by this class. + /// + property BaseIntf : ICoreWebView2Settings read FBaseIntf; + /// + /// The `IsBuiltInErrorPageEnabled` property is used to disable built in + /// error page for navigation failure and render process failure. When + /// disabled, a blank page is displayed when the related error happens. + /// The default value is `TRUE`. + /// + /// + /// See the ICoreWebView2Settings article. + /// + property IsBuiltInErrorPageEnabled : boolean read GetIsBuiltInErrorPageEnabled write SetIsBuiltInErrorPageEnabled; + /// + /// The `AreDefaultContextMenusEnabled` property is used to prevent default + /// context menus from being shown to user in WebView. + /// The default value is `TRUE`. + /// + /// + /// See the ICoreWebView2Settings article. + /// + property AreDefaultContextMenusEnabled : boolean read GetAreDefaultContextMenusEnabled write SetAreDefaultContextMenusEnabled; + /// + /// `AreDefaultScriptDialogsEnabled` is used when loading a new HTML + /// document. If set to `FALSE`, WebView2 does not render the default JavaScript + /// dialog box (Specifically those displayed by the JavaScript alert, + /// confirm, prompt functions and `beforeunload` event). Instead, if an + /// event handler is set using `add_ScriptDialogOpening`, WebView sends an + /// event that contains all of the information for the dialog and allow the + /// host app to show a custom UI. + /// The default value is `TRUE`. + /// + /// + /// See the ICoreWebView2Settings article. + /// + property AreDefaultScriptDialogsEnabled : boolean read GetAreDefaultScriptDialogsEnabled write SetAreDefaultScriptDialogsEnabled; + /// + /// `AreDevToolsEnabled` controls whether the user is able to use the context + /// menu or keyboard shortcuts to open the DevTools window. + /// The default value is `TRUE`. + /// + /// + /// See the ICoreWebView2Settings article. + /// + property AreDevToolsEnabled : boolean read GetAreDevToolsEnabled write SetAreDevToolsEnabled; + /// + /// Controls if running JavaScript is enabled in all future navigations in + /// the WebView. This only affects scripts in the document. Scripts + /// injected with `ExecuteScript` runs even if script is disabled. + /// The default value is `TRUE`. + /// + /// + /// See the ICoreWebView2Settings article. + /// + property IsScriptEnabled : boolean read GetIsScriptEnabled write SetIsScriptEnabled; + /// + /// `IsStatusBarEnabled` controls whether the status bar is displayed. The + /// status bar is usually displayed in the lower left of the WebView and + /// shows things such as the URI of a link when the user hovers over it and + /// other information. The default value is `TRUE`. The status bar UI can be + /// altered by web content and should not be considered secure. + /// + /// + /// See the ICoreWebView2Settings article. + /// + property IsStatusBarEnabled : boolean read GetIsStatusBarEnabled write SetIsStatusBarEnabled; + /// + /// The `IsWebMessageEnabled` property is used when loading a new HTML + /// document. If set to `TRUE`, communication from the host to the top-level + /// HTML document of the WebView is allowed using `PostWebMessageAsJson`, + /// `PostWebMessageAsString`, and message event of `window.chrome.webview`. + /// For more information, navigate to PostWebMessageAsJson. Communication + /// from the top-level HTML document of the WebView to the host is allowed + /// using the postMessage function of `window.chrome.webview` and + /// `add_WebMessageReceived` method. For more information, navigate to + /// [add_WebMessageReceived](/microsoft-edge/webview2/reference/win32/icorewebview2#add_webmessagereceived). + /// If set to false, then communication is disallowed. `PostWebMessageAsJson` + /// and `PostWebMessageAsString` fails with `E_ACCESSDENIED` and + /// `window.chrome.webview.postMessage` fails by throwing an instance of an + /// `Error` object. The default value is `TRUE`. + /// + /// + /// See the ICoreWebView2Settings article. + /// + property IsWebMessageEnabled : boolean read GetIsWebMessageEnabled write SetIsWebMessageEnabled; + /// + /// The `IsZoomControlEnabled` property is used to prevent the user from + /// impacting the zoom of the WebView. When disabled, the user is not able + /// to zoom using Ctrl++, Ctrl+-, or Ctrl+mouse wheel, but the zoom + /// is set using `ZoomFactor` API. The default value is `TRUE`. + /// + /// + /// See the ICoreWebView2Settings article. + /// + property IsZoomControlEnabled : boolean read GetIsZoomControlEnabled write SetIsZoomControlEnabled; + /// + /// The `AreHostObjectsAllowed` property is used to control whether host + /// objects are accessible from the page in WebView. + /// The default value is `TRUE`. + /// + /// + /// See the ICoreWebView2Settings article. + /// + property AreHostObjectsAllowed : boolean read GetAreHostObjectsAllowed write SetAreHostObjectsAllowed; + /// + /// Returns the User Agent. The default value is the default User Agent of the + /// Microsoft Edge browser. + /// This property may be overridden if + /// the User-Agent header is set in a request. If the parameter is empty + /// the User Agent will not be updated and the current User Agent will remain. + /// Setting this property may clear User Agent Client Hints headers + /// Sec-CH-UA-* and script values from navigator.userAgentData. Current + /// implementation behavior is subject to change. + /// The User Agent set will also be effective on service workers + /// and shared workers associated with the WebView. If there are + /// multiple WebViews associated with the same service worker or + /// shared worker, the last User Agent set will be used. + /// + /// + /// See the ICoreWebView2Settings2 article. + /// + property UserAgent : wvstring read GetUserAgent write SetUserAgent; + /// + /// When this setting is set to FALSE, it disables all accelerator keys that + /// access features specific to a web browser, including but not limited to: + /// - Ctrl-F and F3 for Find on Page + /// - Ctrl-P for Print + /// - Ctrl-R and F5 for Reload + /// - Ctrl-Plus and Ctrl-Minus for zooming + /// - Ctrl-Shift-C and F12 for DevTools + /// - Special keys for browser functions, such as Back, Forward, and Search + /// + /// It does not disable accelerator keys related to movement and text editing, + /// such as: + /// - Home, End, Page Up, and Page Down + /// - Ctrl-X, Ctrl-C, Ctrl-V + /// - Ctrl-A for Select All + /// - Ctrl-Z for Undo + /// + /// Those accelerator keys will always be enabled unless they are handled in + /// the `AcceleratorKeyPressed` event. + /// + /// This setting has no effect on the `AcceleratorKeyPressed` event. The event + /// will be fired for all accelerator keys, whether they are enabled or not. + /// + /// The default value for `AreBrowserAcceleratorKeysEnabled` is TRUE. + /// + /// + /// See the ICoreWebView2Settings3 article. + /// + property AreBrowserAcceleratorKeysEnabled : boolean read GetAreBrowserAcceleratorKeysEnabled write SetAreBrowserAcceleratorKeysEnabled; + /// + /// IsPasswordAutosaveEnabled controls whether autosave for password + /// information is enabled. The IsPasswordAutosaveEnabled property behaves + /// independently of the IsGeneralAutofillEnabled property. When IsPasswordAutosaveEnabled is + /// false, no new password data is saved and no Save/Update Password prompts are displayed. + /// However, if there was password data already saved before disabling this setting, + /// then that password information is auto-populated, suggestions are shown and clicking on + /// one will populate the fields. + /// When IsPasswordAutosaveEnabled is true, password information is auto-populated, + /// suggestions are shown and clicking on one will populate the fields, new data + /// is saved, and a Save/Update Password prompt is displayed. + /// It will take effect immediately after setting. + /// The default value is `FALSE`. + /// This property has the same value as + /// `CoreWebView2Profile.IsPasswordAutosaveEnabled`, and changing one will + /// change the other. All `CoreWebView2`s with the same `CoreWebView2Profile` + /// will share the same value for this property, so for the `CoreWebView2`s + /// with the same profile, their + /// `CoreWebView2Settings.IsPasswordAutosaveEnabled` and + /// `CoreWebView2Profile.IsPasswordAutosaveEnabled` will always have the same + /// value. + /// + /// + /// See the ICoreWebView2Settings4 article. + /// + property IsPasswordAutosaveEnabled : boolean read GetIsPasswordAutosaveEnabled write SetIsPasswordAutosaveEnabled; + /// + /// IsGeneralAutofillEnabled controls whether autofill for information + /// like names, street and email addresses, phone numbers, and arbitrary input + /// is enabled. This excludes password and credit card information. When + /// IsGeneralAutofillEnabled is false, no suggestions appear, and no new information + /// is saved. When IsGeneralAutofillEnabled is true, information is saved, suggestions + /// appear and clicking on one will populate the form fields. + /// It will take effect immediately after setting. + /// The default value is `TRUE`. + /// This property has the same value as + /// `CoreWebView2Profile.IsGeneralAutofillEnabled`, and changing one will + /// change the other. All `CoreWebView2`s with the same `CoreWebView2Profile` + /// will share the same value for this property, so for the `CoreWebView2`s + /// with the same profile, their + /// `CoreWebView2Settings.IsGeneralAutofillEnabled` and + /// `CoreWebView2Profile.IsGeneralAutofillEnabled` will always have the same + /// value. + /// + /// + /// See the ICoreWebView2Settings4 article. + /// + property IsGeneralAutofillEnabled : boolean read GetIsGeneralAutofillEnabled write SetIsGeneralAutofillEnabled; + /// + /// Pinch-zoom, referred to as "Page Scale" zoom, is performed as a post-rendering step, + /// it changes the page scale factor property and scales the surface the web page is + /// rendered onto when user performs a pinch zooming action. It does not change the layout + /// but rather changes the viewport and clips the web content, the content outside of the + /// viewport isn't visible onscreen and users can't reach this content using mouse. + /// + /// The `IsPinchZoomEnabled` property enables or disables the ability of + /// the end user to use a pinching motion on touch input enabled devices + /// to scale the web content in the WebView2. It defaults to `TRUE`. + /// When set to `FALSE`, the end user cannot pinch zoom after the next navigation. + /// Disabling/Enabling `IsPinchZoomEnabled` only affects the end user's ability to use + /// pinch motions and does not change the page scale factor. + /// This API only affects the Page Scale zoom and has no effect on the + /// existing browser zoom properties (`IsZoomControlEnabled` and `ZoomFactor`) + /// or other end user mechanisms for zooming. + /// + /// + /// See the ICoreWebView2Settings5 article. + /// + property IsPinchZoomEnabled : boolean read GetIsPinchZoomEnabled write SetIsPinchZoomEnabled; + /// + /// The `IsSwipeNavigationEnabled` property enables or disables the ability of the + /// end user to use swiping gesture on touch input enabled devices to + /// navigate in WebView2. It defaults to `TRUE`. + /// + /// When this property is `TRUE`, then all configured navigation gestures are enabled: + /// 1. Swiping left and right to navigate forward and backward is always configured. + /// 2. Swiping down to refresh is off by default and not exposed via our API currently, + /// it requires the "--pull-to-refresh" option to be included in the additional browser + /// arguments to be configured. (See put_AdditionalBrowserArguments.) + /// + /// When set to `FALSE`, the end user cannot swipe to navigate or pull to refresh. + /// This API only affects the overscrolling navigation functionality and has no + /// effect on the scrolling interaction used to explore the web content shown + /// in WebView2. + /// + /// Disabling/Enabling IsSwipeNavigationEnabled takes effect after the + /// next navigation. + /// + /// + /// See the ICoreWebView2Settings6 article. + /// + property IsSwipeNavigationEnabled : boolean read GetIsSwipeNavigationEnabled write SetIsSwipeNavigationEnabled; + /// + /// `HiddenPdfToolbarItems` is used to customize the PDF toolbar items. By default, it is COREWEBVIEW2_PDF_TOOLBAR_ITEMS_NONE and so it displays all of the items. + /// Changes to this property apply to all CoreWebView2s in the same environment and using the same profile. + /// Changes to this setting apply only after the next navigation. + /// + /// + /// See the ICoreWebView2Settings7 article. + /// + property HiddenPdfToolbarItems : TWVPDFToolbarItems read GetHiddenPdfToolbarItems write SetHiddenPdfToolbarItems; + /// + /// SmartScreen helps webviews identify reported phishing and malware websites + /// and also helps users make informed decisions about downloads. + /// `IsReputationCheckingRequired` is used to control whether SmartScreen + /// enabled or not. SmartScreen is enabled or disabled for all CoreWebView2s + /// using the same user data folder. If + /// CoreWebView2Setting.IsReputationCheckingRequired is true for any + /// CoreWebView2 using the same user data folder, then SmartScreen is enabled. + /// If CoreWebView2Setting.IsReputationCheckingRequired is false for all + /// CoreWebView2 using the same user data folder, then SmartScreen is + /// disabled. When it is changed, the change will be applied to all WebViews + /// using the same user data folder on the next navigation or download. The + /// default value for `IsReputationCheckingRequired` is true. If the newly + /// created CoreWebview2 does not set SmartScreen to false, when + /// navigating(Such as Navigate(), LoadDataUrl(), ExecuteScript(), etc.), the + /// default value will be applied to all CoreWebview2 using the same user data + /// folder. + /// SmartScreen of WebView2 apps can be controlled by Windows system setting + /// "SmartScreen for Microsoft Edge", specially, for WebView2 in Windows + /// Store apps, SmartScreen is controlled by another Windows system setting + /// "SmartScreen for Microsoft Store apps". When the Windows setting is enabled, the + /// SmartScreen operates under the control of the `IsReputationCheckingRequired`. + /// When the Windows setting is disabled, the SmartScreen will be disabled + /// regardless of the `IsReputationCheckingRequired` value set in WebView2 apps. + /// In other words, under this circumstance the value of + /// `IsReputationCheckingRequired` will be saved but overridden by system setting. + /// Upon re-enabling the Windows setting, the CoreWebview2 will reference the + /// `IsReputationCheckingRequired` to determine the SmartScreen status. + /// + /// + /// See the ICoreWebView2Settings8 article. + /// + property IsReputationCheckingRequired : boolean read GetIsReputationCheckingRequired write SetIsReputationCheckingRequired; + /// + /// The `IsNonClientRegionSupportEnabled` property enables web pages to use the + /// `app-region` CSS style. Disabling/Enabling the `IsNonClientRegionSupportEnabled` + /// takes effect after the next navigation. Defaults to `FALSE`. + /// + /// When this property is `TRUE`, then all the non-client region features + /// will be enabled: + /// Draggable Regions will be enabled, they are regions on a webpage that + /// are marked with the CSS attribute `app-region: drag/no-drag`. When set to + /// `drag`, these regions will be treated like the window's title bar, supporting + /// dragging of the entire WebView and its host app window; the system menu shows + /// upon right click, and a double click will trigger maximizing/restoration of the + /// window size. + /// + /// When set to `FALSE`, all non-client region support will be disabled. + /// The `app-region` CSS style will be ignored on web pages. + /// \snippet SettingsComponent.cpp ToggleNonClientRegionSupportEnabled + /// + /// + /// See the ICoreWebView2Settings9 article. + /// + property IsNonClientRegionSupportEnabled : boolean read GetIsNonClientRegionSupportEnabled write SetIsNonClientRegionSupportEnabled; + end; + +implementation + +uses + {$IFDEF DELPHI16_UP} + Winapi.ActiveX, + {$ELSE} + ActiveX, + {$ENDIF} + uRESTDWPrivWVMiscFunctions; + + +constructor TCoreWebView2Settings.Create(const aBaseIntf : ICoreWebView2Settings); +begin + inherited Create; + + InitializeFields; + + FBaseIntf := aBaseIntf; + + if Initialized and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Settings2, FBaseIntf2) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Settings3, FBaseIntf3) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Settings4, FBaseIntf4) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Settings5, FBaseIntf5) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Settings6, FBaseIntf6) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Settings7, FBaseIntf7) and + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Settings8, FBaseIntf8) then + LoggedQueryInterface(FBaseIntf, IID_ICoreWebView2Settings9, FBaseIntf9); +end; + +destructor TCoreWebView2Settings.Destroy; +begin + InitializeFields; + + inherited Destroy; +end; + +procedure TCoreWebView2Settings.InitializeFields; +begin + FBaseIntf := nil; + FBaseIntf2 := nil; + FBaseIntf3 := nil; + FBaseIntf4 := nil; + FBaseIntf5 := nil; + FBaseIntf6 := nil; + FBaseIntf7 := nil; + FBaseIntf8 := nil; + FBaseIntf9 := nil; +end; + +function TCoreWebView2Settings.GetInitialized : boolean; +begin + Result := assigned(FBaseIntf); +end; + +function TCoreWebView2Settings.GetIsBuiltInErrorPageEnabled : boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_IsBuiltInErrorPageEnabled(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Settings.GetAreDefaultContextMenusEnabled : boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_AreDefaultContextMenusEnabled(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Settings.GetAreDefaultScriptDialogsEnabled : boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_AreDefaultScriptDialogsEnabled(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Settings.GetAreDevToolsEnabled : boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_AreDevToolsEnabled(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Settings.GetIsScriptEnabled : boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_IsScriptEnabled(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Settings.GetIsStatusBarEnabled : boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_IsStatusBarEnabled(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Settings.GetIsWebMessageEnabled : boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_IsWebMessageEnabled(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Settings.GetIsZoomControlEnabled : boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_IsZoomControlEnabled(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Settings.GetAreHostObjectsAllowed : boolean; +var + TempResult : integer; +begin + Result := Initialized and + succeeded(FBaseIntf.Get_AreHostObjectsAllowed(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Settings.GetUserAgent : wvstring; + +var + TempResult : PWideChar; +begin + Result := ''; + TempResult := nil; + + if assigned(FBaseIntf2) and + succeeded(FBaseIntf2.Get_UserAgent(TempResult)) and + (TempResult <> nil) then + begin + Result := TempResult; + CoTaskMemFree(TempResult); + end; +end; + +function TCoreWebView2Settings.GetAreBrowserAcceleratorKeysEnabled : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf3) and + succeeded(FBaseIntf3.Get_AreBrowserAcceleratorKeysEnabled(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Settings.GetIsPasswordAutosaveEnabled : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf4) and + succeeded(FBaseIntf4.Get_IsPasswordAutosaveEnabled(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Settings.GetIsGeneralAutofillEnabled : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf4) and + succeeded(FBaseIntf4.Get_IsGeneralAutofillEnabled(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Settings.GetIsPinchZoomEnabled : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf5) and + succeeded(FBaseIntf5.Get_IsPinchZoomEnabled(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Settings.GetIsSwipeNavigationEnabled : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf6) and + succeeded(FBaseIntf6.Get_IsSwipeNavigationEnabled(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Settings.GetHiddenPdfToolbarItems : TWVPDFToolbarItems; +var + TempResult : COREWEBVIEW2_PDF_TOOLBAR_ITEMS; +begin + if assigned(FBaseIntf7) and + succeeded(FBaseIntf7.Get_HiddenPdfToolbarItems(TempResult)) then + Result := TempResult + else + Result := 0; +end; + +function TCoreWebView2Settings.GetIsReputationCheckingRequired : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf8) and + succeeded(FBaseIntf8.Get_IsReputationCheckingRequired(TempResult)) and + (TempResult <> 0); +end; + +function TCoreWebView2Settings.GetIsNonClientRegionSupportEnabled : boolean; +var + TempResult : integer; +begin + Result := assigned(FBaseIntf9) and + succeeded(FBaseIntf9.Get_IsNonClientRegionSupportEnabled(TempResult)) and + (TempResult <> 0); +end; + +procedure TCoreWebView2Settings.SetIsBuiltInErrorPageEnabled(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_IsBuiltInErrorPageEnabled(ord(aValue)); +end; + +procedure TCoreWebView2Settings.SetAreDefaultContextMenusEnabled(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_AreDefaultContextMenusEnabled(ord(aValue)); +end; + +procedure TCoreWebView2Settings.SetAreDefaultScriptDialogsEnabled(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_AreDefaultScriptDialogsEnabled(ord(aValue)); +end; + +procedure TCoreWebView2Settings.SetAreDevToolsEnabled(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_AreDevToolsEnabled(ord(aValue)); +end; + +procedure TCoreWebView2Settings.SetIsScriptEnabled(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_IsScriptEnabled(ord(aValue)); +end; + +procedure TCoreWebView2Settings.SetIsStatusBarEnabled(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_IsStatusBarEnabled(ord(aValue)); +end; + +procedure TCoreWebView2Settings.SetIsWebMessageEnabled(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_IsWebMessageEnabled(ord(aValue)); +end; + +procedure TCoreWebView2Settings.SetIsZoomControlEnabled(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_IsZoomControlEnabled(ord(aValue)); +end; + +procedure TCoreWebView2Settings.SetAreHostObjectsAllowed(aValue : boolean); +begin + if Initialized then + FBaseIntf.Set_AreHostObjectsAllowed(ord(aValue)); +end; + +procedure TCoreWebView2Settings.SetUserAgent(const aValue : wvstring); +begin + if assigned(FBaseIntf2) then + FBaseIntf2.Set_UserAgent(PWideChar(aValue)); +end; + +procedure TCoreWebView2Settings.SetAreBrowserAcceleratorKeysEnabled(aValue : boolean); +begin + if assigned(FBaseIntf3) then + FBaseIntf3.Set_AreBrowserAcceleratorKeysEnabled(ord(aValue)); +end; + +procedure TCoreWebView2Settings.SetIsPasswordAutosaveEnabled(aValue : boolean); +begin + if assigned(FBaseIntf4) then + FBaseIntf4.Set_IsPasswordAutosaveEnabled(ord(aValue)); +end; + +procedure TCoreWebView2Settings.SetIsGeneralAutofillEnabled(aValue : boolean); +begin + if assigned(FBaseIntf4) then + FBaseIntf4.Set_IsGeneralAutofillEnabled(ord(aValue)); +end; + +procedure TCoreWebView2Settings.SetIsPinchZoomEnabled(aValue : boolean); +begin + if assigned(FBaseIntf5) then + FBaseIntf5.Set_IsPinchZoomEnabled(ord(aValue)); +end; + +procedure TCoreWebView2Settings.SetIsSwipeNavigationEnabled(aValue : boolean); +begin + if assigned(FBaseIntf6) then + FBaseIntf6.Set_IsSwipeNavigationEnabled(ord(aValue)); +end; + +procedure TCoreWebView2Settings.SetHiddenPdfToolbarItems(aValue : TWVPDFToolbarItems); +begin + if assigned(FBaseIntf7) then + FBaseIntf7.Set_HiddenPdfToolbarItems(aValue); +end; + +procedure TCoreWebView2Settings.SetIsReputationCheckingRequired(aValue : boolean); +begin + if assigned(FBaseIntf8) then + FBaseIntf8.Set_IsReputationCheckingRequired(ord(aValue)); +end; + +procedure TCoreWebView2Settings.SetIsNonClientRegionSupportEnabled(aValue : boolean); +begin + if assigned(FBaseIntf9) then + FBaseIntf9.Set_IsNonClientRegionSupportEnabled(ord(aValue)); +end; + + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVEvents.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVEvents.pas new file mode 100644 index 000000000..7348c9fcb --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVEvents.pas @@ -0,0 +1,133 @@ +unit uRESTDWPrivWVEvents; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + Winapi.ActiveX, Winapi.Messages, + {$ELSE} + ActiveX, Messages, + {$ENDIF} + uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVTypes; + +type + // Loader events + TLoaderNotifyEvent = {$IFDEF DELPHI12_UP}reference to{$ENDIF} procedure(Sender: TObject) {$IFNDEF DELPHI12_UP}{$IFNDEF FPC} of object{$ENDIF}{$ENDIF}; + TLoaderBrowserProcessExitedEvent = {$IFDEF DELPHI12_UP}reference to{$ENDIF} procedure(Sender: TObject; const aEnvironment: ICoreWebView2Environment; const aArgs: ICoreWebView2BrowserProcessExitedEventArgs) {$IFNDEF DELPHI12_UP}{$IFNDEF FPC} of object{$ENDIF}{$ENDIF}; + TLoaderNewBrowserVersionAvailableEvent = {$IFDEF DELPHI12_UP}reference to{$ENDIF} procedure(Sender: TObject; const aEnvironment: ICoreWebView2Environment) {$IFNDEF DELPHI12_UP}{$IFNDEF FPC} of object{$ENDIF}{$ENDIF}; + TLoaderProcessInfosChangedEvent = {$IFDEF DELPHI12_UP}reference to{$ENDIF} procedure(Sender: TObject; const aEnvironment: ICoreWebView2Environment) {$IFNDEF DELPHI12_UP}{$IFNDEF FPC} of object{$ENDIF}{$ENDIF}; + TLoaderGetCustomSchemesEvent = {$IFDEF DELPHI12_UP}reference to{$ENDIF} procedure(Sender: TObject; var aCustomSchemes: TWVCustomSchemeInfoArray) {$IFNDEF DELPHI12_UP}{$IFNDEF FPC} of object{$ENDIF}{$ENDIF}; + + // Browser events + TOnExecuteScriptCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT; const aResultObjectAsJson: wvstring; aExecutionID: integer) of object; + TOnCapturePreviewCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT) of object; + TOnWebResourceResponseViewGetContentCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT; const aResult: IStream; aResourceID : integer) of object; + TOnGetCookiesCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT; const aResult: ICoreWebView2CookieList) of object; + TOnTrySuspendCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT; aResult: boolean) of object; + TOnPrintToPdfCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT; aResult: boolean) of object; + TOnCallDevToolsProtocolMethodCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT; const aResult: wvstring; aExecutionID: integer) of object; + TOnAddScriptToExecuteOnDocumentCreatedCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT; const aResult: wvstring) of object; + TOnMoveFocusRequestedEvent = procedure(Sender: TObject; const aController: ICoreWebView2Controller; const aArgs: ICoreWebView2MoveFocusRequestedEventArgs) of object; + TOnAcceleratorKeyPressedEvent = procedure(Sender: TObject; const aController: ICoreWebView2Controller; const aArgs: ICoreWebView2AcceleratorKeyPressedEventArgs) of object; + TOnBrowserProcessExitedEvent = procedure(Sender: TObject; const aEnvironment: ICoreWebView2Environment; const aArgs: ICoreWebView2BrowserProcessExitedEventArgs) of object; + TOnNavigationStartingEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2NavigationStartingEventArgs) of object; + TOnNavigationCompletedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2NavigationCompletedEventArgs) of object; + TOnSourceChangedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2SourceChangedEventArgs) of object; + TOnContentLoadingEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2ContentLoadingEventArgs) of object; + TOnNewWindowRequestedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2NewWindowRequestedEventArgs) of object; + TOnWebResourceRequestedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2WebResourceRequestedEventArgs) of object; + TOnScriptDialogOpeningEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2ScriptDialogOpeningEventArgs) of object; + TOnPermissionRequestedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2PermissionRequestedEventArgs) of object; + TOnProcessFailedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2ProcessFailedEventArgs) of object; + TOnWebMessageReceivedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2WebMessageReceivedEventArgs) of object; + TOnDevToolsProtocolEventReceivedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2DevToolsProtocolEventReceivedEventArgs; const aEventName : wvstring; aEventID : integer) of object; + TOnWebResourceResponseReceivedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2WebResourceResponseReceivedEventArgs) of object; + TOnDOMContentLoadedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2DOMContentLoadedEventArgs) of object; + TOnFrameCreatedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2FrameCreatedEventArgs) of object; + TOnDownloadStartingEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2DownloadStartingEventArgs) of object; + TOnClientCertificateRequestedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2ClientCertificateRequestedEventArgs) of object; + TOnBytesReceivedChangedEvent = procedure(Sender: TObject; const aDownloadOperation: ICoreWebView2DownloadOperation; aDownloadID: integer) of object; + TOnEstimatedEndTimeChangedEvent = procedure(Sender: TObject; const aDownloadOperation: ICoreWebView2DownloadOperation; aDownloadID: integer) of object; + TOnDownloadStateChangedEvent = procedure(Sender: TObject; const aDownloadOperation: ICoreWebView2DownloadOperation; aDownloadID: integer) of object; + TOnFrameNameChangedEvent = procedure(Sender: TObject; const aFrame: ICoreWebView2Frame; aFrameID: cardinal) of object; + TOnFrameDestroyedEvent = procedure(Sender: TObject; const aFrame: ICoreWebView2Frame; aFrameID: cardinal) of object; + TOnInitializationErrorEvent = procedure(Sender: TObject; aErrorCode: HRESULT; const aErrorMessage: wvstring) of object; + TOnPrintCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT; aResult: TWVPrintStatus) of object; + TOnRefreshIgnoreCacheCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT; const aResultObjectAsJson: wvstring) of object; + TOnRetrieveHTMLCompletedEvent = procedure(Sender: TObject; aResult: boolean; const aHTML: wvstring) of object; + TOnRetrieveTextCompletedEvent = procedure(Sender: TObject; aResult: boolean; const aText: wvstring) of object; + TOnRetrieveMHTMLCompletedEvent = procedure(Sender: TObject; aResult: boolean; const aMHTML: wvstring) of object; + TOnClearCacheCompletedEvent = procedure(Sender: TObject; aResult: boolean) of object; + TOnClearDataForOriginCompletedEvent = procedure(Sender: TObject; aResult: boolean) of object; + TOnOfflineCompletedEvent = procedure(Sender: TObject; aResult: boolean) of object; + TOnIgnoreCertificateErrorsCompletedEvent = procedure(Sender: TObject; aResult: boolean) of object; + TOnSimulateKeyEventCompletedEvent = procedure(Sender: TObject; aResult: boolean) of object; + TOnIsMutedChangedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2) of object; + TOnIsDocumentPlayingAudioChangedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2) of object; + TOnIsDefaultDownloadDialogOpenChangedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2) of object; + TOnProcessInfosChangedEvent = procedure(Sender: TObject; const aEnvironment: ICoreWebView2Environment) of object; + TOnFrameNavigationStartingEvent = procedure(Sender: TObject; const aFrame: ICoreWebView2Frame; const aArgs: ICoreWebView2NavigationStartingEventArgs; aFrameID: cardinal) of object; + TOnFrameNavigationCompletedEvent = procedure(Sender: TObject; const aFrame: ICoreWebView2Frame; const aArgs: ICoreWebView2NavigationCompletedEventArgs; aFrameID: cardinal) of object; + TOnFrameContentLoadingEvent = procedure(Sender: TObject; const aFrame: ICoreWebView2Frame; const aArgs: ICoreWebView2ContentLoadingEventArgs; aFrameID: cardinal) of object; + TOnFrameDOMContentLoadedEvent = procedure(Sender: TObject; const aFrame: ICoreWebView2Frame; const aArgs: ICoreWebView2DOMContentLoadedEventArgs; aFrameID: cardinal) of object; + TOnFrameWebMessageReceivedEvent = procedure(Sender: TObject; const aFrame: ICoreWebView2Frame; const aArgs: ICoreWebView2WebMessageReceivedEventArgs; aFrameID: cardinal) of object; + TOnBasicAuthenticationRequestedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2BasicAuthenticationRequestedEventArgs) of object; + TOnContextMenuRequestedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2ContextMenuRequestedEventArgs) of object; + TOnCustomItemSelectedEvent = procedure(Sender: TObject; const aMenuItem: ICoreWebView2ContextMenuItem) of object; + TOnStatusBarTextChangedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2) of object; + TOnFramePermissionRequestedEvent = procedure(Sender: TObject; const aFrame: ICoreWebView2Frame; const aArgs: ICoreWebView2PermissionRequestedEventArgs2; aFrameID: cardinal) of object; + TOnClearBrowsingDataCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT) of object; + TOnServerCertificateErrorActionsCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT) of object; + TOnServerCertificateErrorDetectedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2ServerCertificateErrorDetectedEventArgs) of object; + TOnFaviconChangedEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: IUnknown) of object; + TOnGetFaviconCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT; const aResult: IStream) of object; + TOnPrintToPdfStreamCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT; const aResult: IStream) of object; + TOnGetCustomSchemesEvent = procedure(Sender: TObject; var aCustomSchemes: TWVCustomSchemeInfoArray) of object; + TOnGetNonDefaultPermissionSettingsCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT; const aResult: ICoreWebView2PermissionSettingCollectionView) of object; + TOnSetPermissionStateCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT) of object; + TOnLaunchingExternalUriSchemeEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2LaunchingExternalUriSchemeEventArgs) of object; + TOnGetProcessExtendedInfosCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT; const aResult: ICoreWebView2ProcessExtendedInfoCollection) of object; + TOnBrowserExtensionRemoveCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT; const aExtensionID: wvstring) of object; + TOnBrowserExtensionEnableCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT; const aExtensionID: wvstring) of object; + TOnProfileAddBrowserExtensionCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT; const aResult: ICoreWebView2BrowserExtension) of object; + TOnProfileGetBrowserExtensionsCompletedEvent = procedure(Sender: TObject; aErrorCode: HRESULT; const aResult: ICoreWebView2BrowserExtensionList) of object; + TOnProfileDeletedEvent = procedure(Sender: TObject; const aProfile: ICoreWebView2Profile) of object; + TOnExecuteScriptWithResultCompletedEvent = procedure(Sender: TObject; errorCode: HResult; const aResult: ICoreWebView2ExecuteScriptResult; aExecutionID : integer) of object; + TOnNonClientRegionChangedEvent = procedure(Sender: TObject; const aController : ICoreWebView2CompositionController; const aArgs : ICoreWebView2NonClientRegionChangedEventArgs) of object; + TOnNotificationReceivedEvent = procedure(Sender: TObject; const aWebView : ICoreWebView2; const aArgs : ICoreWebView2NotificationReceivedEventArgs) of object; + TOnNotificationCloseRequestedEvent = procedure(Sender: TObject; const aNotification: ICoreWebView2Notification; const aArgs: IUnknown) of object; + TOnSaveAsUIShowingEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2SaveAsUIShowingEventArgs) of object; + TOnShowSaveAsUICompletedEvent = procedure(Sender: TObject; aErrorCode: HResult; aResult: TWVSaveAsUIResult) of object; + TOnSaveFileSecurityCheckStartingEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2SaveFileSecurityCheckStartingEventArgs) of object; + TOnScreenCaptureStartingEvent = procedure(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2ScreenCaptureStartingEventArgs) of object; + TOnFrameScreenCaptureStartingEvent = procedure(Sender: TObject; const aFrame: ICoreWebView2Frame; const aArgs: ICoreWebView2ScreenCaptureStartingEventArgs; aFrameID: cardinal) of object; + TOnFrameChildFrameCreatedEvent = procedure(Sender: TObject; const aFrame: ICoreWebView2Frame; const aArgs: ICoreWebView2FrameCreatedEventArgs; aFrameID: cardinal) of object; + TOnFindActiveMatchIndexChangedEvent = procedure(Sender: TObject; const aFindSession: ICoreWebView2Find; const aArgs: IUnknown) of object; + TOnFindMatchCountChangedEvent = procedure(Sender: TObject; const aFindSession: ICoreWebView2Find; const aArgs: IUnknown) of object; + TOnFindStartCompletedEvent = procedure(Sender: TObject; aErrorCode: HResult) of object; + TOnDragStartingEvent = procedure(Sender: TObject; const aController: ICoreWebView2CompositionController; const aArgs: ICoreWebView2DragStartingEventArgs) of object; + TOnDedicatedWorkerCreatedEvent = procedure(Sender: TObject; const aWebView : ICoreWebView2; const aArgs : ICoreWebView2DedicatedWorkerCreatedEventArgs) of object; + TOnDedicatedWorkerCreated2Event = procedure(Sender: TObject; const aDedicatedWorker: ICoreWebView2DedicatedWorker; const aArgs: ICoreWebView2DedicatedWorkerCreatedEventArgs; aWorkerID: cardinal) of object; + TOnDedicatedWorkerDestroyingEvent = procedure(Sender: TObject; const aDedicatedWorker: ICoreWebView2DedicatedWorker; const aArgs: IUnknown; aWorkerID: cardinal) of object; + TOnDedicatedWorkerWebMessageReceivedEvent = procedure(Sender: TObject; const aDedicatedWorker: ICoreWebView2DedicatedWorker; const aArgs: ICoreWebView2WebMessageReceivedEventArgs; aWorkerID: cardinal) of object; + TOnFrameDedicatedWorkerCreatedEvent = procedure(Sender: TObject; const aFrame: ICoreWebView2Frame; const aArgs: ICoreWebView2DedicatedWorkerCreatedEventArgs; aFrameID: cardinal) of object; + TOnServiceWorkerDestroyingEvent = procedure(Sender: TObject; const aServiceWorker: ICoreWebView2ServiceWorker; const aArgs: IUnknown; aWorkerID: cardinal) of object; + TOnServiceWorkerWebMessageReceivedEvent = procedure(Sender: TObject; const aServiceWorker: ICoreWebView2ServiceWorker; const aArgs: ICoreWebView2WebMessageReceivedEventArgs; aWorkerID: cardinal) of object; + TOnServiceWorkerRegisteredEvent = procedure(Sender: TObject; const aServiceWorkerManager: ICoreWebView2ServiceWorkerManager; const aArgs: ICoreWebView2ServiceWorkerRegisteredEventArgs) of object; + TOnGetServiceWorkerRegistrationsCompletedEvent = procedure(Sender: TObject; errorCode: HResult; const result_: ICoreWebView2ServiceWorkerRegistrationCollectionView) of object; + TOnServiceWorkerActivatedEvent = procedure(Sender: TObject; const aServiceWorkerRegistration: ICoreWebView2ServiceWorkerRegistration; const aArgs: ICoreWebView2ServiceWorkerActivatedEventArgs) of object; + TOnServiceWorkerRegistrationUnregisteringEvent = procedure(Sender: TObject; const aServiceWorkerRegistration: ICoreWebView2ServiceWorkerRegistration; const aArgs: IUnknown) of object; + TOnSharedWorkerCreatedEvent = procedure(Sender: TObject; const aSharedWorkerManager: ICoreWebView2SharedWorkerManager; const aArgs: ICoreWebView2SharedWorkerCreatedEventArgs) of object; + TOnGetSharedWorkersCompletedEvent = procedure(Sender: TObject; errorCode: HResult; const result_: ICoreWebView2SharedWorkerCollectionView) of object; + TOnSharedWorkerDestroyingEvent = procedure(Sender: TObject; const aSharedWorker: ICoreWebView2SharedWorker; const aArgs: IUnknown; aWorkerID: cardinal) of object; + + // Custom events + TOnCompMsgEvent = procedure(Sender: TObject; var aMessage: TMessage; var aHandled: Boolean) of object; + +implementation + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVInterfaces.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVInterfaces.pas new file mode 100644 index 000000000..e0233118f --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVInterfaces.pas @@ -0,0 +1,352 @@ +unit uRESTDWPrivWVInterfaces; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + Winapi.ActiveX, + {$ELSE} + ActiveX, + {$ENDIF} + uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVTypes; + +type + IWVLoaderEvents = Interface + ['{5B91E1BB-CA98-476E-A2F0-10BDED27A916}'] + + // ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler + function EnvironmentCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2Environment): HResult; + + // ICoreWebView2NewBrowserVersionAvailableEventHandler + function NewBrowserVersionAvailableEventHandler_Invoke(const sender: ICoreWebView2Environment; const args: IUnknown): HResult; + + // ICoreWebView2BrowserProcessExitedEventHandler + function BrowserProcessExitedEventHandler_Invoke(const sender: ICoreWebView2Environment; const args: ICoreWebView2BrowserProcessExitedEventArgs): HResult; + + // ICoreWebView2ProcessInfosChangedEventHandler + function ProcessInfosChangedEventHandler_Invoke(const sender: ICoreWebView2Environment; const args: IUnknown): HResult; + end; + + IWVBrowserEvents = Interface + ['{4E06D91F-1213-46C1-ABB8-D41D8CC19E81}'] + + // ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler + function EnvironmentCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2Environment): HResult; + + // ICoreWebView2CreateCoreWebView2ControllerCompletedHandler + function ControllerCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2Controller): HResult; + + // ICoreWebView2ExecuteScriptCompletedHandler + function ExecuteScriptCompletedHandler_Invoke(errorCode: HResult; result_: PWideChar; aExecutionID : integer): HResult; + + // ICoreWebView2CapturePreviewCompletedHandler + function CapturePreviewCompletedHandler_Invoke(errorCode: HResult): HResult; + + // ICoreWebView2NavigationStartingEventHandler + function NavigationStartingEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NavigationStartingEventArgs): HResult; + + // ICoreWebView2NavigationCompletedEventHandler + function NavigationCompletedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NavigationCompletedEventArgs): HResult; + + // ICoreWebView2SourceChangedEventHandler + function SourceChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2SourceChangedEventArgs): HResult; + + // ICoreWebView2HistoryChangedEventHandler + function HistoryChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; + + // ICoreWebView2ContentLoadingEventHandler + function ContentLoadingEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ContentLoadingEventArgs): HResult; + + // ICoreWebView2DocumentTitleChangedEventHandler + function DocumentTitleChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; + + // ICoreWebView2NewWindowRequestedEventHandler + function NewWindowRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NewWindowRequestedEventArgs): HResult; + + // ICoreWebView2NavigationStartingEventHandler (Frame navigation) + function FrameNavigationStartingEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NavigationStartingEventArgs): HResult; + + // ICoreWebView2NavigationCompletedEventArgs (Frame navigation) + function FrameNavigationCompletedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NavigationCompletedEventArgs): HResult; + + // ICoreWebView2WebResourceRequestedEventHandler + function WebResourceRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2WebResourceRequestedEventArgs): HResult; + + // ICoreWebView2ScriptDialogOpeningEventHandler + function ScriptDialogOpeningEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ScriptDialogOpeningEventArgs): HResult; + + // ICoreWebView2PermissionRequestedEventHandler + function PermissionRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2PermissionRequestedEventArgs): HResult; + + // ICoreWebView2ProcessFailedEventHandler + function ProcessFailedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ProcessFailedEventArgs): HResult; + + // ICoreWebView2WebMessageReceivedEventHandler + function WebMessageReceivedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2WebMessageReceivedEventArgs): HResult; + + // ICoreWebView2ContainsFullScreenElementChangedEventHandler + function ContainsFullScreenElementChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; + + // ICoreWebView2WindowCloseRequestedEventHandler + function WindowCloseRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; + + // ICoreWebView2ZoomFactorChangedEventHandler + function ZoomFactorChangedEventHandler_Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HResult; + + // ICoreWebView2MoveFocusRequestedEventHandler + function MoveFocusRequestedEventHandler_Invoke(const sender: ICoreWebView2Controller; const args: ICoreWebView2MoveFocusRequestedEventArgs): HResult; + + // ICoreWebView2AcceleratorKeyPressedEventHandler + function AcceleratorKeyPressedEventHandler_Invoke(const sender: ICoreWebView2Controller; const args: ICoreWebView2AcceleratorKeyPressedEventArgs): HResult; + + // ICoreWebView2FocusChangedEventHandler + function GotFocusEventHandler_Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HResult; + + // ICoreWebView2FocusChangedEventHandler + function LostFocusEventHandler_Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HResult; + + // ICoreWebView2DevToolsProtocolEventReceivedEventHandler + function DevToolsProtocolEventReceivedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DevToolsProtocolEventReceivedEventArgs; const aEventName : wvstring; aEventID : integer): HResult; + + // ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler + function CreateCoreWebView2CompositionControllerCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2CompositionController): HResult; + + // ICoreWebView2CursorChangedEventHandler + function CursorChangedEventHandler_Invoke(const sender: ICoreWebView2CompositionController; const args: IUnknown): HResult; + + // ICoreWebView2BrowserProcessExitedEventHandler + function BrowserProcessExitedEventHandler_Invoke(const sender: ICoreWebView2Environment; const args: ICoreWebView2BrowserProcessExitedEventArgs): HResult; + + // ICoreWebView2RasterizationScaleChangedEventHandler + function RasterizationScaleChangedEventHandler_Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HResult; + + // ICoreWebView2WebResourceResponseReceivedEventHandler + function WebResourceResponseReceivedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2WebResourceResponseReceivedEventArgs): HResult; + + // ICoreWebView2DOMContentLoadedEventHandler + function DOMContentLoadedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DOMContentLoadedEventArgs): HResult; + + // ICoreWebView2WebResourceResponseViewGetContentCompletedHandler + function WebResourceResponseViewGetContentCompletedHandler_Invoke(errorCode: HResult; const result_: IStream; aResourceID : integer): HResult; + + // ICoreWebView2GetCookiesCompletedHandler + function GetCookiesCompletedHandler_Invoke(errorCode : HResult; const result_ : ICoreWebView2CookieList): HResult; + + // ICoreWebView2TrySuspendCompletedHandler + function TrySuspendCompletedHandler_Invoke(errorCode: HResult; result_: Integer): HResult; + + // ICoreWebView2FrameCreatedEventHandler + function FrameCreatedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2FrameCreatedEventArgs): HResult; + + // ICoreWebView2DownloadStartingEventHandler + function DownloadStartingEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DownloadStartingEventArgs): HResult; + + // ICoreWebView2ClientCertificateRequestedEventHandler + function ClientCertificateRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ClientCertificateRequestedEventArgs): HResult; + + // ICoreWebView2PrintToPdfCompletedHandler + function PrintToPdfCompletedHandler_Invoke(errorCode: HResult; result_: Integer): HResult; + + // ICoreWebView2BytesReceivedChangedEventHandler + function BytesReceivedChangedEventHandler_Invoke(const sender: ICoreWebView2DownloadOperation; const args: IUnknown; aDownloadID : integer): HResult; + + // ICoreWebView2EstimatedEndTimeChangedEventHandler + function EstimatedEndTimeChangedEventHandler_Invoke(const sender: ICoreWebView2DownloadOperation; const args: IUnknown; aDownloadID : integer): HResult; + + // ICoreWebView2StateChangedEventHandler + function StateChangedEventHandler_Invoke(const sender: ICoreWebView2DownloadOperation; const args: IUnknown; aDownloadID : integer): HResult; + + // ICoreWebView2FrameNameChangedEventHandler + function FrameNameChangedEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: IUnknown; aFrameID : cardinal): HResult; + + // ICoreWebView2FrameDestroyedEventHandler + function FrameDestroyedEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: IUnknown; aFrameID : cardinal): HResult; + + // ICoreWebView2CallDevToolsProtocolMethodCompletedHandler + function CallDevToolsProtocolMethodCompletedHandler_Invoke(errorCode: HResult; result_: PWideChar; aExecutionID : integer): HResult; + + // ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler + function AddScriptToExecuteOnDocumentCreatedCompletedHandler_Invoke(errorCode: HResult; id: PWideChar): HResult; + + // ICoreWebView2IsMutedChangedEventHandler + function IsMutedChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; + + // ICoreWebView2IsDocumentPlayingAudioChangedEventHandler + function IsDocumentPlayingAudioChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; + + // ICoreWebView2IsDefaultDownloadDialogOpenChangedEventHandler + function IsDefaultDownloadDialogOpenChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; + + // ICoreWebView2ProcessInfosChangedEventHandler + function ProcessInfosChangedEventHandler_Invoke(const sender: ICoreWebView2Environment; const args: IUnknown): HResult; + + // ICoreWebView2NavigationStartingEventHandler (Frame navigation) + function FrameNavigationStartingEventHandler2_Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2NavigationStartingEventArgs; aFrameID: cardinal): HResult; + + // ICoreWebView2NavigationCompletedEventArgs (Frame navigation) + function FrameNavigationCompletedEventHandler2_Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2NavigationCompletedEventArgs; aFrameID: cardinal): HResult; + + // ICoreWebView2FrameContentLoadingEventHandler + function FrameContentLoadingEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2ContentLoadingEventArgs; aFrameID: cardinal): HResult; + + // ICoreWebView2FrameDOMContentLoadedEventHandler + function FrameDOMContentLoadedEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2DOMContentLoadedEventArgs; aFrameID: cardinal): HResult; + + // ICoreWebView2FrameWebMessageReceivedEventHandler + function FrameWebMessageReceivedEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2WebMessageReceivedEventArgs; aFrameID: cardinal): HResult; + + // ICoreWebView2BasicAuthenticationRequestedEventHandler + function BasicAuthenticationRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2BasicAuthenticationRequestedEventArgs): HResult; + + // ICoreWebView2ContextMenuRequestedEventHandler + function ContextMenuRequestedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ContextMenuRequestedEventArgs): HResult; + + // ICoreWebView2CustomItemSelectedEventHandler + function CustomItemSelectedEventHandler_Invoke(const sender: ICoreWebView2ContextMenuItem; const args: IUnknown): HResult; + + // ICoreWebView2StatusBarTextChangedEventHandler + function StatusBarTextChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; + + // ICoreWebView2FramePermissionRequestedEventHandler + function FramePermissionRequestedEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2PermissionRequestedEventArgs2; aFrameID: cardinal): HResult; + + // ICoreWebView2ClearBrowsingDataCompletedHandler + function ClearBrowsingDataCompletedHandler_Invoke(errorCode: HResult): HResult; + + // ICoreWebView2ClearServerCertificateErrorActionsCompletedHandler + function ClearServerCertificateErrorActionsCompletedHandler_Invoke(errorCode: HResult): HResult; + + // ICoreWebView2ServerCertificateErrorDetectedEventHandler + function ServerCertificateErrorDetectedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ServerCertificateErrorDetectedEventArgs): HResult; + + // ICoreWebView2FaviconChangedEventHandler + function FaviconChangedEventHandler_Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; + + // ICoreWebView2GetFaviconCompletedHandler + function GetFaviconCompletedHandler_Invoke(errorCode: HResult; const result_: IStream): HResult; + + // ICoreWebView2PrintCompletedHandler + function PrintCompletedHandler_Invoke(errorCode: HResult; result_: COREWEBVIEW2_PRINT_STATUS): HResult; + + // ICoreWebView2PrintToPdfStreamCompletedHandler + function PrintToPdfStreamCompletedHandler_Invoke(errorCode: HResult; const result_: IStream): HResult; + + // ICoreWebView2GetNonDefaultPermissionSettingsCompletedHandler + function GetNonDefaultPermissionSettingsCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2PermissionSettingCollectionView): HResult; + + // ICoreWebView2SetPermissionStateCompletedHandler + function SetPermissionStateCompletedHandler_Invoke(errorCode: HResult): HResult; + + // ICoreWebView2LaunchingExternalUriSchemeEventHandler + function LaunchingExternalUriSchemeEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2LaunchingExternalUriSchemeEventArgs): HResult; + + // ICoreWebView2GetProcessExtendedInfosCompletedHandler + function GetProcessExtendedInfosCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2ProcessExtendedInfoCollection): HResult; + + // ICoreWebView2BrowserExtensionRemoveCompletedHandler + function BrowserExtensionRemoveCompletedHandler_Invoke(errorCode: HResult; const aExtensionID: wvstring): HResult; + + // ICoreWebView2BrowserExtensionEnableCompletedHandler + function BrowserExtensionEnableCompletedHandler_Invoke(errorCode: HResult; const aExtensionID: wvstring): HResult; + + // ICoreWebView2ProfileAddBrowserExtensionCompletedHandler + function ProfileAddBrowserExtensionCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2BrowserExtension): HResult; + + // ICoreWebView2ProfileGetBrowserExtensionsCompletedHandler + function ProfileGetBrowserExtensionsCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2BrowserExtensionList): HResult; + + // ICoreWebView2ProfileDeletedEventHandler + function ProfileDeletedEventHandler_Invoke(const sender: ICoreWebView2Profile; const args: IUnknown): HResult; + + // ICoreWebView2ExecuteScriptWithResultCompletedHandler + function ExecuteScriptWithResultCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2ExecuteScriptResult; aExecutionID : integer): HResult; + + // ICoreWebView2NonClientRegionChangedEventHandler + function NonClientRegionChangedEventHandler_Invoke(const sender: ICoreWebView2CompositionController; const args: ICoreWebView2NonClientRegionChangedEventArgs): HResult; + + // ICoreWebView2NonClientRegionChangedEventHandler + function NotificationReceivedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2NotificationReceivedEventArgs): HResult; + + // ICoreWebView2NotificationCloseRequestedEventHandler + function NotificationCloseRequestedEventHandler_Invoke(const sender: ICoreWebView2Notification; const args: IUnknown): HResult; + + // ICoreWebView2SaveAsUIShowingEventHandler + function SaveAsUIShowingEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2SaveAsUIShowingEventArgs): HResult; + + // ICoreWebView2ShowSaveAsUICompletedHandler + function ShowSaveAsUICompletedHandler_Invoke(errorCode: HResult; result_: COREWEBVIEW2_SAVE_AS_UI_RESULT): HResult; + + // ICoreWebView2SaveFileSecurityCheckStartingEventHandler + function SaveFileSecurityCheckStartingEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2SaveFileSecurityCheckStartingEventArgs): HResult; + + // ICoreWebView2ScreenCaptureStartingEventHandler + function ScreenCaptureStartingEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ScreenCaptureStartingEventArgs): HResult; + + // ICoreWebView2FrameScreenCaptureStartingEventHandler + function FrameScreenCaptureStartingEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2ScreenCaptureStartingEventArgs; aFrameID: cardinal): HResult; + + // ICoreWebView2FrameChildFrameCreatedEventHandler + function FrameChildFrameCreatedEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2FrameCreatedEventArgs; aFrameID: cardinal): HResult; + + // ICoreWebView2FindActiveMatchIndexChangedEventHandler + function FindActiveMatchIndexChangedEventHandler_Invoke(const sender: ICoreWebView2Find; const args: IUnknown): HResult; + + // ICoreWebView2FindMatchCountChangedEventHandler + function FindMatchCountChangedEventHandler_Invoke(const sender: ICoreWebView2Find; const args: IUnknown): HResult; + + // ICoreWebView2FindStartCompletedHandler + function FindStartCompletedHandler_Invoke(errorCode: HResult): HResult; + + // ICoreWebView2DragStartingEventHandler + function DragStartingEventHandler_Invoke(const sender: ICoreWebView2CompositionController; const args: ICoreWebView2DragStartingEventArgs): HResult; + + // ICoreWebView2DedicatedWorkerCreatedEventHandler + function DedicatedWorkerCreatedEventHandler_Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DedicatedWorkerCreatedEventArgs): HResult; + + // ICoreWebView2DedicatedWorkerDedicatedWorkerCreatedEventHandler + function DedicatedWorkerDedicatedWorkerCreatedEventHandler_Invoke(const sender: ICoreWebView2DedicatedWorker; const args: ICoreWebView2DedicatedWorkerCreatedEventArgs; aWorkerID: cardinal): HResult; + + // ICoreWebView2DedicatedWorkerDestroyingEventHandler + function DedicatedWorkerDestroyingEventHandler_Invoke(const sender: ICoreWebView2DedicatedWorker; const args: IUnknown; aWorkerID: cardinal): HResult; + + // ICoreWebView2DedicatedWorkerWebMessageReceivedEventHandler + function DedicatedWorkerWebMessageReceivedEventHandler_Invoke(const sender: ICoreWebView2DedicatedWorker; const args: ICoreWebView2WebMessageReceivedEventArgs; aWorkerID: cardinal): HResult; + + // ICoreWebView2FrameDedicatedWorkerCreatedEventHandler + function FrameDedicatedWorkerCreatedEventHandler_Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2DedicatedWorkerCreatedEventArgs; aFrameID: cardinal): HResult; + + // ICoreWebView2ServiceWorkerDestroyingEventHandler + function ServiceWorkerDestroyingEventHandler_Invoke(const sender: ICoreWebView2ServiceWorker; const args: IUnknown; aWorkerID: cardinal): HResult; + + // ICoreWebView2ServiceWorkerWebMessageReceivedEventHandler + function ServiceWorkerWebMessageReceivedEventHandler_Invoke(const sender: ICoreWebView2ServiceWorker; const args: ICoreWebView2WebMessageReceivedEventArgs; aWorkerID: cardinal): HResult; + + // ICoreWebView2ServiceWorkerRegisteredEventHandler + function ServiceWorkerRegisteredEventHandler_Invoke(const sender: ICoreWebView2ServiceWorkerManager; const args: ICoreWebView2ServiceWorkerRegisteredEventArgs): HResult; + + // ICoreWebView2GetServiceWorkerRegistrationsCompletedHandler + function GetServiceWorkerRegistrationsCompletedHandler_Invoke(errorCode: HResult; const result: ICoreWebView2ServiceWorkerRegistrationCollectionView): HResult; + + // ICoreWebView2ServiceWorkerActivatedEventHandler + function ServiceWorkerActivatedEventHandler_Invoke(const sender: ICoreWebView2ServiceWorkerRegistration; const args: ICoreWebView2ServiceWorkerActivatedEventArgs): HResult; + + // ICoreWebView2ServiceWorkerRegistrationUnregisteringEventHandler + function ServiceWorkerRegistrationUnregisteringEventHandler_Invoke(const sender: ICoreWebView2ServiceWorkerRegistration; const args: IUnknown): HResult; + + // ICoreWebView2SharedWorkerCreatedEventHandler + function SharedWorkerCreatedEventHandler_Invoke(const sender: ICoreWebView2SharedWorkerManager; const args: ICoreWebView2SharedWorkerCreatedEventArgs): HResult; + + // ICoreWebView2GetSharedWorkersCompletedHandler + function GetSharedWorkersCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2SharedWorkerCollectionView): HResult; + + // ICoreWebView2SharedWorkerDestroyingEventHandler + function SharedWorkerDestroyingEventHandler_Invoke(const sender: ICoreWebView2SharedWorker; const args: IUnknown; aWorkerID: cardinal): HResult; + end; + +implementation + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVLibFunctions.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVLibFunctions.pas new file mode 100644 index 000000000..fb352adee --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVLibFunctions.pas @@ -0,0 +1,100 @@ +unit uRESTDWPrivWVLibFunctions; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + WinApi.Windows, + {$ELSE} + Windows, + {$ENDIF} + uRESTDWPrivWVTypeLibrary; + +var + {* + Exported functions in WebView2Loader.dll + https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.1020.30 + *} + + /// + /// This method is for anyone want to compare version correctly to determine + /// which version is newer, older or same. Use it to determine whether + /// to use webview2 or certain feature based upon version. + /// Sets the value of result to `-1`, `0` or `1` if `version1` is less than, + /// equal or greater than `version2` respectively. Returns `E_INVALIDARG` if it + /// fails to parse any of the version strings or any input parameter is `null`. + /// Directly use the `versionInfo` obtained from + /// `GetAvailableCoreWebView2BrowserVersionString` with input, channel information is ignored. + /// + /// + /// See the Globals article. + /// + CompareBrowserVersions : function(version1, version2: LPCWSTR; result: PInteger): HRESULT; stdcall; + /// + /// Creates an evergreen WebView2 Environment using the installed WebView2 + /// Runtime version. This is equivalent to running + /// `CreateCoreWebView2EnvironmentWithOptions` with `nullptr` for + /// `browserExecutableFolder`, `userDataFolder`, `additionalBrowserArguments`. + /// For more information, navigate to `CreateCoreWebView2EnvironmentWithOptions`. + /// + /// + /// See the Globals article. + /// + CreateCoreWebView2Environment : function(const environmentCreatedHandler: ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler): HRESULT; stdcall; + /// + /// DLL export to create a WebView2 environment with a custom version of + /// WebView2 Runtime, user data folder, and with or without additional options. + /// + /// + /// See the Globals article. + /// + CreateCoreWebView2EnvironmentWithOptions : function(browserExecutableFolder, userDataFolder: LPCWSTR; const environmentOptions: ICoreWebView2EnvironmentOptions; const environmentCreatedHandler: ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler): HRESULT; stdcall; + /// + /// Get the browser version info including channel name if it is not the + /// WebView2 Runtime. Channel names are Beta, Dev, and Canary. + /// If an override exists for the `browserExecutableFolder` or the channel + /// preference, the override is used. If an override is not specified, then + /// the parameter value passed to + /// `GetAvailableCoreWebView2BrowserVersionString` is used. + /// Returns `HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)` if it fails to find an + /// installed WebView2 runtime or non-stable Microsoft Edge installation. + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + /// + /// See the Globals article. + /// + GetAvailableCoreWebView2BrowserVersionString : function(browserExecutableFolder: LPCWSTR; versionInfo: PLPWSTR): HRESULT; stdcall; + /// + /// This function will tell you the browser version info of the release channel + /// used when creating an environment with the same options. Browser version + /// info includes channel name if it is not the WebView2 Runtime. Channel names + /// are Beta, Dev, and Canary. The format of the return string matches the format of + /// `BrowserVersionString` on `ICoreWebView2Environment`. + /// If an override exists for `browserExecutableFolder`, `releaseChannels`, + /// or `ChannelSearchKind`, the override is used. The presence of an override + /// can result in a different channel used than the one expected based on the + /// environment options object. `browserExecutableFolder` takes precedence over + /// the other options, regardless of whether or not its channel is included in + /// the `releaseChannels`. See `CreateCoreWebView2EnvironmentWithOptions` + /// for more details on overrides. If an override is not specified, then the + /// parameters passed to `GetAvailableCoreWebView2BrowserVersionStringWithOptions` + /// are used. Returns `HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)` if it fails to find + /// an installed WebView2 Runtime or non-stable Microsoft Edge installation. Use + /// `GetAvailableCoreWebView2BrowserVersionString` to get the version info without + /// the environment options. + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + /// + /// See the Globals article. + /// + GetAvailableCoreWebView2BrowserVersionStringWithOptions : function(browserExecutableFolder: LPCWSTR; const environmentOptions: ICoreWebView2EnvironmentOptions; versionInfo: PLPWSTR): HRESULT; stdcall; + +implementation + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVLoader.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVLoader.pas new file mode 100644 index 000000000..aac59d127 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVLoader.pas @@ -0,0 +1,2247 @@ +unit uRESTDWPrivWVLoader; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + WinApi.Windows, System.Classes, System.SysUtils, WinApi.ActiveX, System.Win.Registry, Winapi.ShlObj, System.Math, System.SyncObjs, + {$ELSE} + Windows, Classes, SysUtils, ActiveX, Registry, ShlObj, Math, Dialogs, SyncObjs, + {$ENDIF} + uRESTDWPrivWVLibFunctions, uRESTDWPrivWVInterfaces, uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVTypes, uRESTDWPrivWVEvents, uRESTDWPrivWVCoreWebView2Environment; + +type + TWVProxySettings = class; + /// + /// Class used to simplify the WebView2 initialization and destruction. + /// + TWVLoader = class(TComponent, IWVLoaderEvents) + protected + FCoreWebView2Environment : TCoreWebView2Environment; + FOnEnvironmentCreated : TLoaderNotifyEvent; + FOnNewBrowserVersionAvailable : TLoaderNewBrowserVersionAvailableEvent; + FOnInitializationError : TLoaderNotifyEvent; + FOnBrowserProcessExited : TLoaderBrowserProcessExitedEvent; + FOnProcessInfosChanged : TLoaderProcessInfosChangedEvent; + FOnGetCustomSchemes : TLoaderGetCustomSchemesEvent; + FLibHandle : THandle; + FSyncObj : TCriticalSection; + FErrorLog : TStringList; + FError : int64; + FBrowserExecPath : wvstring; + FUserDataFolder : wvstring; + FStatus : TWV2LoaderStatus; + FSetCurrentDir : boolean; + FCheckFiles : boolean; + FShowMessageDlg : boolean; + FInitCOMLibrary : boolean; + FLocalCOMInitMade : boolean; + FDeviceScaleFactor : single; + FForcedDeviceScaleFactor : single; + FReRaiseExceptions : boolean; + FLoaderDllPath : wvstring; + FUseInternalLoader : boolean; + FAllowOldRuntime : boolean; + FWorkerIDGen : cardinal; + + // Fields used to create the environment + FAdditionalBrowserArguments : wvstring; + FLanguage : wvstring; + FTargetCompatibleBrowserVersion : wvstring; + FAllowSingleSignOnUsingOSPrimaryAccount : boolean; + FExclusiveUserDataFolderAccess : boolean; + FCustomCrashReportingEnabled : boolean; + FEnableTrackingPrevention : boolean; + FAreBrowserExtensionsEnabled : boolean; + FChannelSearchKind : TWVChannelSearchKind; + FReleaseChannels : TWVReleaseChannels; + FScrollBarStyle : TWVScrollBarStyle; + + // Fields used to set command line switches + FEnableGPU : boolean; + FEnableFeatures : wvstring; + FDisableFeatures : wvstring; + FEnableBlinkFeatures : wvstring; + FDisableBlinkFeatures : wvstring; + FBlinkSettings : wvstring; + FForceFieldTrials : wvstring; + FForceFieldTrialParams : wvstring; + FSmartScreenProtectionEnabled : boolean; + FAllowInsecureLocalhost : boolean; + FDisableWebSecurity : boolean; + FTouchEvents : TWVState; + FHyperlinkAuditing : boolean; + FAutoplayPolicy : TWVAutoplayPolicy; + FMuteAudio : boolean; + FDefaultEncoding : wvstring; + FKioskPrinting : boolean; + FProxySettings : TWVProxySettings; + FAllowFileAccessFromFiles : boolean; + FAllowRunningInsecureContent : boolean; + FDisableBackgroundNetworking : boolean; + FRemoteDebuggingPort : integer; + FRemoteAllowOrigins : wvstring; + FDebugLog : TWV2DebugLog; + FDebugLogLevel : TWV2DebugLogLevel; + FJavaScriptFlags : wvstring; + FDisableEdgePitchNotification : boolean; + FTreatInsecureOriginAsSecure : wvstring; + FOpenOfficeDocumentsInWebViewer : boolean; + FMicrosoftSignIn : boolean; + FPostQuantumKyber : TWVState; + FUserAgent : wvstring; + + FAutoAcceptCamAndMicCapture : boolean; + + function GetInternalAvailableBrowserVersion : wvstring; + function GetAvailableBrowserVersion : wvstring; + function GetAvailableBrowserVersionWithOptions : wvstring; + function GetInitialized : boolean; + function GetInitializationError : boolean; + function GetEnvironmentIsInitialized : boolean; + function GetDefaultUserDataPath : string; + function GetEnvironment : ICoreWebView2Environment; + function GetProcessInfos : ICoreWebView2ProcessInfoCollection; + function GetSupportsCompositionController : boolean; + function GetSupportsControllerOptions : boolean; + function GetCustomCommandLineSwitches : wvstring; + function GetInstalledRuntimeVersion : wvstring; + function GetErrorMessage : wvstring; + function GetFailureReportFolderPath : wvstring; + + function CreateEnvironment : boolean; + procedure DestroyEnvironment; + + function Lock: boolean; + procedure UnLock; + function GetFileVersion(const aFile : wvstring; var aVersionInfo : TFileVersionInfo) : boolean; + function GetExtendedFileVersion(const aFileName : wvstring) : uint64; + function LoadLibProcedures : boolean; + function LoadWebView2Library : boolean; + procedure UnLoadWebView2Library; + function CheckWV2Library : boolean; + function CheckBrowserExecPath : boolean; + function CheckWebViewRuntimeVersion : boolean; + function CheckWV2DLL : boolean; + function CheckFileVersion(const aFile : wvstring; aMajor, aMinor, aRelease, aBuild : word) : boolean; + function GetDLLHeaderMachine(const aDLLFile : string; var aMachine : integer) : boolean; + function Is32BitProcess : boolean; + function CheckInstalledRuntimeRegEntry(aLocalMachine : boolean; const aPath : string; var aVersion : wvstring) : boolean; + procedure ShowErrorMessageDlg(const aError : wvstring); + function SearchInstalledProgram(const aDisplayName, aPublisher : string) : boolean; + function SearchInstalledProgramInPath(const aRegPath, aDisplayName, aPublisher : string; aLocalMachine : boolean) : boolean; + + procedure doOnInitializationError; virtual; + procedure doOnEnvironmentCreated; virtual; + procedure doOnNewBrowserVersionAvailable(const aEnvironment: ICoreWebView2Environment); virtual; + procedure doOnBrowserProcessExitedEvent(const sender: ICoreWebView2Environment; const args: ICoreWebView2BrowserProcessExitedEventArgs); virtual; + procedure doProcessInfosChangedEvent(const sender: ICoreWebView2Environment); virtual; + procedure doOnGetCustomSchemes(var aSchemeRegistrations : TWVCustomSchemeRegistrationArray); virtual; + + function EnvironmentCompletedHandler_Invoke(errorCode: HResult; const result_: ICoreWebView2Environment): HRESULT; + function NewBrowserVersionAvailableEventHandler_Invoke(const sender: ICoreWebView2Environment; const args: IUnknown): HRESULT; + function BrowserProcessExitedEventHandler_Invoke(const sender: ICoreWebView2Environment; const args: ICoreWebView2BrowserProcessExitedEventArgs): HRESULT; + function ProcessInfosChangedEventHandler_Invoke(const sender: ICoreWebView2Environment; const args: IUnknown): HRESULT; + /// + /// Default value of the user data path. + /// + property DefaultUserDataPath : string read GetDefaultUserDataPath; + /// + /// Returns true if the environment is initialized. + /// + property EnvironmentIsInitialized : boolean read GetEnvironmentIsInitialized; + + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure AfterConstruction; override; + /// + /// This function is used to initialize WebView2. + /// + /// + /// See the Globals article. + /// + function StartWebView2 : boolean; + /// + /// This method is for anyone want to compare version correctly to determine + /// which version is newer, older or same.Use it to determine whether + /// to use webview2 or certain feature based upon version. Sets the value of + /// aCompRslt to -1, 0 or 1 if aVersion1 is less than, equal or greater + /// than aVersion2 respectively. Returns false if it fails to parse + /// any of the version strings. + /// + /// + /// See the Globals article. + /// + function CompareVersions(const aVersion1, aVersion2 : wvstring; var aCompRslt : integer): boolean; + /// + /// Update the DeviceScaleFactor property value with the current scale or the ForcedDeviceScaleFactor value. + /// + procedure UpdateDeviceScaleFactor; virtual; + /// + /// Append aText to the ErrorMessage property. + /// + procedure AppendErrorLog(const aText : wvstring); + /// + /// Custom ID generator for the web workers. + /// + function NextWorkerID: cardinal; + + /// + /// Represents the global WebView2 Environment. + /// + property Environment : ICoreWebView2Environment read GetEnvironment; + /// + /// Returns the TWVLoader initialization status. + /// + property Status : TWV2LoaderStatus read FStatus; + /// + /// Get the browser version info including channel name if it is not the + /// WebView2 Runtime. Channel names are Beta, Dev, and Canary. + /// + property AvailableBrowserVersion : wvstring read GetAvailableBrowserVersion; + /// + /// Get the browser version info of the release channel used when creating + /// an environment with the same options. Channel names are Beta, Dev, and + /// Canary. + /// + property AvailableBrowserVersionWithOptions : wvstring read GetAvailableBrowserVersionWithOptions; + /// + /// Returns all the text appended to the error log with AppendErrorLog. + /// + property ErrorMessage : wvstring read GetErrorMessage; + /// + /// Returns the last initialization error code. + /// + property ErrorCode : int64 read FError; + /// + /// Used to set the current directory when the WebView2 library is loaded. This is required if the application is launched from a different application. + /// + property SetCurrentDir : boolean read FSetCurrentDir write FSetCurrentDir; + /// + /// Returns true if the Status is wvlsInitialized. + /// + property Initialized : boolean read GetInitialized; + /// + /// Returns true if the Status is wvlsError. + /// + property InitializationError : boolean read GetInitializationError; + /// + /// Checks if the WebView2 library is present and the DLL version. + /// + property CheckFiles : boolean read FCheckFiles write FCheckFiles; + /// + /// Set to true when you need to use a showmessage dialog to show the error messages. + /// + property ShowMessageDlg : boolean read FShowMessageDlg write FShowMessageDlg; + /// + /// Set to true to call CoInitializeEx and CoUnInitialize in TWVLoader.Create and TWVLoader.Destroy. + /// + property InitCOMLibrary : boolean read FInitCOMLibrary write FInitCOMLibrary; + /// + /// Custom command line switches used by TCoreWebView2EnvironmentOptions.Create to initialize WebView2. + /// + property CustomCommandLineSwitches : wvstring read GetCustomCommandLineSwitches; + /// + /// Returns the device scale factor. + /// + property DeviceScaleFactor : single read FDeviceScaleFactor; + /// + /// Set to true to raise all exceptions. + /// + property ReRaiseExceptions : boolean read FReRaiseExceptions write FReRaiseExceptions; + /// + /// Returns the installed WebView2 runtime version. + /// + property InstalledRuntimeVersion : wvstring read GetInstalledRuntimeVersion; + /// + /// Full path to WebView2Loader.dll. Leave empty to load WebView2Loader.dll from the current directory. + /// + property LoaderDllPath : wvstring read FLoaderDllPath write FLoaderDllPath; + /// + /// Use a WebView2Loader.dll replacement based on the OpenWebView2Loader project. + /// + /// + /// See the OpenWebView2Loader project repository at GitHub. + /// + property UseInternalLoader : boolean read FUseInternalLoader write FUseInternalLoader; + /// + /// Allow using old WebView2 Runtime versions. + /// + property AllowOldRuntime : boolean read FAllowOldRuntime write FAllowOldRuntime; + /// + /// Use BrowserExecPath to specify whether WebView2 controls use a fixed or + /// installed version of the WebView2 Runtime that exists on a user machine. + /// To use a fixed version of the WebView2 Runtime, pass the folder path that + /// contains the fixed version of the WebView2 Runtime to BrowserExecPath. + /// BrowserExecPath supports both relative (to the application's executable) + /// and absolute files paths. To create WebView2 controls that use the installed + /// version of the WebView2 Runtime that exists on user machines, + /// pass an empty string to BrowserExecPath. + /// + /// + /// Property used to create the environment. Used as the browserExecutableFolder parameter of CreateCoreWebView2EnvironmentWithOptions. + /// See the Globals article. + /// + property BrowserExecPath : wvstring read FBrowserExecPath write FBrowserExecPath; + /// + /// You may specify the userDataFolder to change the default user data folder + /// location for WebView2. The path is either an absolute file path or a relative + /// file path that is interpreted as relative to the compiled code for the + /// current process. + /// + /// + /// Property used to create the environment. Used as the userDataFolder parameter of CreateCoreWebView2EnvironmentWithOptions. + /// See the Globals article. + /// + property UserDataFolder : wvstring read FUserDataFolder write FUserDataFolder; + /// + /// Additional command line switches. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions.get_AdditionalBrowserArguments. + /// See the ICoreWebView2EnvironmentOptions article. + /// + property AdditionalBrowserArguments : wvstring read FAdditionalBrowserArguments write FAdditionalBrowserArguments; + /// + /// The default display language for WebView. It applies to browser UI such as + /// context menu and dialogs. It also applies to the `accept-languages` HTTP + /// header that WebView sends to websites. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions.get_Language. + /// See the ICoreWebView2EnvironmentOptions article. + /// + property Language : wvstring read FLanguage write FLanguage; + /// + /// Specifies the version of the WebView2 Runtime binaries required to be + /// compatible with your app. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions.get_TargetCompatibleBrowserVersion. + /// See the ICoreWebView2EnvironmentOptions article. + /// + property TargetCompatibleBrowserVersion : wvstring read FTargetCompatibleBrowserVersion write FTargetCompatibleBrowserVersion; + /// + /// Used to enable single sign on with Azure Active Directory (AAD) and personal Microsoft + /// Account (MSA) resources inside WebView. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions.get_AllowSingleSignOnUsingOSPrimaryAccount. + /// See the ICoreWebView2EnvironmentOptions article. + /// + property AllowSingleSignOnUsingOSPrimaryAccount : boolean read FAllowSingleSignOnUsingOSPrimaryAccount write FAllowSingleSignOnUsingOSPrimaryAccount; + /// + /// Whether other processes can create WebView2 from WebView2Environment created with the + /// same user data folder and therefore sharing the same WebView browser process instance. + /// Default is FALSE. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions2.Get_ExclusiveUserDataFolderAccess. + /// See the ICoreWebView2EnvironmentOptions2 article. + /// + property ExclusiveUserDataFolderAccess : boolean read FExclusiveUserDataFolderAccess write FExclusiveUserDataFolderAccess; + /// + /// When `CustomCrashReportingEnabled` is set to `TRUE`, Windows won't send crash data to Microsoft endpoint. + /// `CustomCrashReportingEnabled` is default to be `FALSE`, in this case, WebView will respect OS consent. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions3.Get_IsCustomCrashReportingEnabled. + /// See the ICoreWebView2EnvironmentOptions3 article. + /// + property CustomCrashReportingEnabled : boolean read FCustomCrashReportingEnabled write FCustomCrashReportingEnabled; + /// + /// The `EnableTrackingPrevention` property is used to enable/disable tracking prevention + /// feature in WebView2. This property enable/disable tracking prevention for all the + /// WebView2's created in the same environment. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions5.Get_EnableTrackingPrevention. + /// See the ICoreWebView2EnvironmentOptions5 article. + /// + property EnableTrackingPrevention : boolean read FEnableTrackingPrevention write FEnableTrackingPrevention; + /// + /// When `AreBrowserExtensionsEnabled` is set to `TRUE`, new extensions can be added to user + /// profile and used. `AreBrowserExtensionsEnabled` is default to be `FALSE`, in this case, + /// new extensions can't be installed, and already installed extension won't be + /// available to use in user profile. + /// If connecting to an already running environment with a different value for `AreBrowserExtensionsEnabled` + /// property, it will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions6.Get_AreBrowserExtensionsEnabled. + /// See the ICoreWebView2EnvironmentOptions6 article. + /// See the ICoreWebView2BrowserExtension article for Extensions API details. + /// + property AreBrowserExtensionsEnabled : boolean read FAreBrowserExtensionsEnabled write FAreBrowserExtensionsEnabled; + /// + /// The `ChannelSearchKind` property is `COREWEBVIEW2_CHANNEL_SEARCH_KIND_MOST_STABLE` + /// by default; environment creation searches for a release channel on the machine + /// from most to least stable using the first channel found. The default search order is: + /// WebView2 Runtime -> Beta -> Dev -> Canary. Set `ChannelSearchKind` to + /// `COREWEBVIEW2_CHANNEL_SEARCH_KIND_LEAST_STABLE` to reverse the search order + /// so that environment creation searches for a channel from least to most stable. If + /// `ReleaseChannels` has been provided, the loader will only search + /// for channels in the set. See `COREWEBVIEW2_RELEASE_CHANNELS` for more details + /// on channels. + /// This property can be overridden by the corresponding + /// registry key `ChannelSearchKind` or the environment variable + /// `WEBVIEW2_CHANNEL_SEARCH_KIND`. Set the value to `1` to set the search kind to + /// `COREWEBVIEW2_CHANNEL_SEARCH_KIND_LEAST_STABLE`. See + /// `CreateCoreWebView2EnvironmentWithOptions` for more details on overrides. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions7.Get_ChannelSearchKind. + /// See the ICoreWebView2EnvironmentOptions7 article. + /// + property ChannelSearchKind : TWVChannelSearchKind read FChannelSearchKind write FChannelSearchKind; + /// + /// Sets the `ReleaseChannels`, which is a mask of one or more + /// `COREWEBVIEW2_RELEASE_CHANNELS` indicating which channels environment + /// creation should search for. OR operation(s) can be applied to multiple + /// `COREWEBVIEW2_RELEASE_CHANNELS` to create a mask. The default value is a + /// a mask of all the channels. By default, environment creation searches for + /// channels from most to least stable, using the first channel found on the + /// device. When `ReleaseChannels` is provided, environment creation will only + /// search for the channels specified in the set. Set `ChannelSearchKind` to + /// `COREWEBVIEW2_CHANNEL_SEARCH_KIND_LEAST_STABLE` to reverse the search order + /// so environment creation searches for least stable build first. See + /// `COREWEBVIEW2_RELEASE_CHANNELS` for descriptions of each channel. + /// `CreateCoreWebView2EnvironmentWithOptions` fails with + /// `HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)` if environment creation is unable + /// to find any channel from the `ReleaseChannels` installed on the device. + /// Use `GetAvailableCoreWebView2BrowserVersionStringWithOptions` on + /// `ICoreWebView2Environment` to verify which channel is used when this option + /// is set. + /// Examples: + /// + /// | ReleaseChannels | Channel Search Kind: Most Stable (default) | Channel Search Kind: Least Stable | + /// | --- | --- | --- | + /// |COREWEBVIEW2_RELEASE_CHANNELS_BETA \| COREWEBVIEW2_RELEASE_CHANNELS_STABLE| WebView2 Runtime -> Beta | Beta -> WebView2 Runtime| + /// |COREWEBVIEW2_RELEASE_CHANNELS_CANARY \| COREWEBVIEW2_RELEASE_CHANNELS_DEV \| COREWEBVIEW2_RELEASE_CHANNELS_BETA \| COREWEBVIEW2_RELEASE_CHANNELS_STABLE| WebView2 Runtime -> Beta -> Dev -> Canary | Canary -> Dev -> Beta -> WebView2 Runtime | + /// |COREWEBVIEW2_RELEASE_CHANNELS_CANARY| Canary | Canary | + /// |COREWEBVIEW2_RELEASE_CHANNELS_BETA \| COREWEBVIEW2_RELEASE_CHANNELS_CANARY \| COREWEBVIEW2_RELEASE_CHANNELS_STABLE | WebView2 Runtime -> Beta -> Canary | Canary -> Beta -> WebView2 Runtime | + /// + /// If both `BrowserExecutableFolder` and `ReleaseChannels` are provided, the + /// `BrowserExecutableFolder` takes precedence, regardless of whether or not the + /// channel of `BrowserExecutableFolder` is included in the `ReleaseChannels`. + /// `ReleaseChannels` can be overridden by the corresponding registry override + /// `ReleaseChannels` or the environment variable `WEBVIEW2_RELEASE_CHANNELS`. + /// Set the value to a comma-separated string of integers, which map to the + /// following release channel values: Stable (0), Beta (1), Dev (2), and + /// Canary (3). For example, the values "0,2" and "2,0" indicate that environment + /// creation should only search for Dev channel and the WebView2 Runtime, using the + /// order indicated by `ChannelSearchKind`. Environment creation attempts to + /// interpret each integer and treats any invalid entry as Stable channel. See + /// `CreateCoreWebView2EnvironmentWithOptions` for more details on overrides. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions7.Get_ReleaseChannels. + /// See the ICoreWebView2EnvironmentOptions7 article. + /// + property ReleaseChannels : TWVReleaseChannels read FReleaseChannels write FReleaseChannels; + /// + /// The ScrollBar style being set on the WebView2 Environment. + /// The default value is `COREWEBVIEW2_SCROLLBAR_STYLE_DEFAULT` + /// which specifies the default browser ScrollBar style. + /// The `color-scheme` CSS property needs to be set on the corresponding page + /// to allow ScrollBar to follow light or dark theme. Please see + /// [color-scheme](https://developer.mozilla.org/docs/Web/CSS/color-scheme#declaring_color_scheme_preferences) + /// for how `color-scheme` can be set. + /// CSS styles that modify the ScrollBar applied on top of native ScrollBar styling + /// that is selected with `ScrollBarStyle`. + /// + /// + /// Property used to create the environment. Used as ICoreWebView2EnvironmentOptions8.Get_ScrollBarStyle. + /// See the ICoreWebView2EnvironmentOptions8 article. + /// + property ScrollBarStyle : TWVScrollBarStyle read FScrollBarStyle write FScrollBarStyle; + /// + /// Enable GPU hardware acceleration. + /// + /// + /// Uses the following command line switch: --disable-gpu + /// Uses the following command line switch: --disable-gpu-compositing + /// + property EnableGPU : boolean read FEnableGPU write FEnableGPU; + /// + /// List of feature names to enable. + /// + /// + /// Uses the following command line switch: --enable-features + /// See the WebView2 browser flags article. + /// The list of features you can enable is here: + /// https://chromium.googlesource.com/chromium/src/+/master/chrome/common/chrome_features.cc + /// https://source.chromium.org/chromium/chromium/src/+/main:content/public/common/content_features.cc + /// https://source.chromium.org/search?q=base::Feature + /// + property EnableFeatures : wvstring read FEnableFeatures write FEnableFeatures; + /// + /// List of feature names to disable. + /// + /// + /// Uses the following command line switch: --disable-features + /// The list of features you can disable is here: + /// https://chromium.googlesource.com/chromium/src/+/master/chrome/common/chrome_features.cc + /// https://source.chromium.org/chromium/chromium/src/+/main:content/public/common/content_features.cc + /// https://source.chromium.org/search?q=base::Feature + /// + property DisableFeatures : wvstring read FDisableFeatures write FDisableFeatures; + /// + /// Enable one or more Blink runtime-enabled features. + /// + /// + /// Uses the following command line switch: --enable-blink-features + /// The list of Blink features you can enable is here: + /// https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5 + /// + property EnableBlinkFeatures : wvstring read FEnableBlinkFeatures write FEnableBlinkFeatures; + /// + /// Disable one or more Blink runtime-enabled features. + /// + /// + /// Uses the following command line switch: --disable-blink-features + /// The list of Blink features you can disable is here: + /// https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5 + /// + property DisableBlinkFeatures : wvstring read FDisableBlinkFeatures write FDisableBlinkFeatures; + /// + /// Set blink settings. Format is [=[=],... + /// The names are declared in Settings.json5. For boolean type, use "true", "false", + /// or omit '=' part to set to true. For enum type, use the int value of the + /// enum value. Applied after other command line flags and prefs. + /// + /// + /// Uses the following command line switch: --blink-settings + /// The list of Blink settings you can disable is here: + /// https://source.chromium.org/chromium/chromium/src/+/master:third_party/blink/renderer/core/frame/settings.json5 + /// + property BlinkSettings : wvstring read FBlinkSettings write FBlinkSettings; + /// + /// This option can be used to force field trials when testing changes locally. + /// The argument is a list of name and value pairs, separated by slashes. + /// If a trial name is prefixed with an asterisk, that trial will start activated. + /// For example, the following argument defines two trials, with the second one + /// activated: "GoogleNow/Enable/*MaterialDesignNTP/Default/" This option can also + /// be used by the browser process to send the list of trials to a non-browser + /// process, using the same format. See FieldTrialList::CreateTrialsFromString() + /// in field_trial.h for details. + /// + /// + /// Uses the following command line switch: --force-fieldtrials + /// https://source.chromium.org/chromium/chromium/src/+/master:base/base_switches.cc + /// + property ForceFieldTrials : wvstring read FForceFieldTrials write FForceFieldTrials; + /// + /// This option can be used to force parameters of field trials when testing + /// changes locally. The argument is a param list of (key, value) pairs prefixed + /// by an associated (trial, group) pair. You specify the param list for multiple + /// (trial, group) pairs with a comma separator. + /// Example: "Trial1.Group1:k1/v1/k2/v2,Trial2.Group2:k3/v3/k4/v4" + /// Trial names, groups names, parameter names, and value should all be URL + /// escaped for all non-alphanumeric characters. + /// + /// + /// Uses the following command line switch: --force-fieldtrial-params + /// https://source.chromium.org/chromium/chromium/src/+/master:components/variations/variations_switches.cc + /// + property ForceFieldTrialParams : wvstring read FForceFieldTrialParams write FForceFieldTrialParams; + /// + /// Workaround given my Microsoft to disable the SmartScreen protection. + /// + property SmartScreenProtectionEnabled : boolean read FSmartScreenProtectionEnabled write FSmartScreenProtectionEnabled; + /// + /// Enables TLS/SSL errors on localhost to be ignored (no interstitial, no blocking of requests). + /// + /// + /// Uses the following command line switch: --allow-insecure-localhost + /// + property AllowInsecureLocalhost : boolean read FAllowInsecureLocalhost write FAllowInsecureLocalhost; + /// + /// Don't enforce the same-origin policy. + /// + /// + /// Uses the following command line switch: --disable-web-security + /// + property DisableWebSecurity : boolean read FDisableWebSecurity write FDisableWebSecurity; + /// + /// Enable support for touch event feature detection. + /// + /// + /// Uses the following command line switch: --touch-events + /// + property TouchEvents : TWVState read FTouchEvents write FTouchEvents; + /// + /// Don't send hyperlink auditing pings. + /// + /// + /// Uses the following command line switch: --no-pings + /// + property HyperlinkAuditing : boolean read FHyperlinkAuditing write FHyperlinkAuditing; + /// + /// Autoplay policy. + /// + /// + /// Uses the following command line switch: --autoplay-policy + /// + property AutoplayPolicy : TWVAutoplayPolicy read FAutoplayPolicy write FAutoplayPolicy; + /// + /// Mutes audio sent to the audio device so it is not audible during automated testing. + /// + /// + /// Uses the following command line switch: --mute-audio + /// + property MuteAudio : boolean read FMuteAudio write FMuteAudio; + /// + /// Default encoding. + /// + /// + /// Uses the following command line switch: --default-encoding + /// + property DefaultEncoding : wvstring read FDefaultEncoding write FDefaultEncoding; + /// + /// Enable automatically pressing the print button in print preview. + /// + /// + /// Uses the following command line switch: --kiosk-printing + /// + property KioskPrinting : boolean read FKioskPrinting write FKioskPrinting; + /// + /// Configure the browser to use a proxy server. + /// + /// + /// Uses the following command line switch: --no-proxy-server + /// Uses the following command line switch: --proxy-auto-detect + /// Uses the following command line switch: --proxy-bypass-list + /// Uses the following command line switch: --proxy-pac-url + /// Uses the following command line switch: --proxy-server + /// See the Network Settings article. + /// See the Proxy Support article. + /// See the chrome.proxy API article. + /// + property ProxySettings : TWVProxySettings read FProxySettings; + /// + /// By default, file:// URIs cannot read other file:// URIs. This is an override for developers who need the old behavior for testing. + /// + /// + /// Uses the following command line switch: --allow-file-access-from-files + /// + property AllowFileAccessFromFiles : boolean read FAllowFileAccessFromFiles write FAllowFileAccessFromFiles; + /// + /// By default, an https page cannot run JavaScript, CSS or plugins from http URLs. This provides an override to get the old insecure behavior. + /// + /// + /// Uses the following command line switch: --allow-running-insecure-content + /// + property AllowRunningInsecureContent : boolean read FAllowRunningInsecureContent write FAllowRunningInsecureContent; + /// + /// Disable several subsystems which run network requests in the background. + /// + /// + /// Uses the following command line switch: --disable-background-networking + /// + property DisableBackgroundNetworking : boolean read FDisableBackgroundNetworking write FDisableBackgroundNetworking; + /// + /// Overrides the device scale factor for the browser UI and the contents. + /// + /// + /// Uses the following command line switch: --force-device-scale-factor + /// + property ForcedDeviceScaleFactor : single read FForcedDeviceScaleFactor write FForcedDeviceScaleFactor; + /// + /// Set to a value between 1024 and 65535 to enable remote debugging on the + /// specified port. Also configurable using the "remote-debugging-port" + /// command-line switch. Remote debugging can be accessed by loading the + /// chrome://inspect page in Google Chrome. Port numbers 9222 and 9229 are + /// discoverable by default. Other port numbers may need to be configured via + /// "Discover network targets" on the Devices tab. + /// + /// + /// Uses the following command line switch: --remote-debugging-port + /// + property RemoteDebuggingPort : integer read FRemoteDebuggingPort write FRemoteDebuggingPort; + /// + /// Enables web socket connections from the specified origins only. '*' allows any origin. + /// + /// + /// Uses the following command line switch: --remote-allow-origins + /// + property RemoteAllowOrigins : wvstring read FRemoteAllowOrigins write FRemoteAllowOrigins; + /// + /// Force logging to be enabled. Logging is disabled by default in release builds. + /// + /// + /// Uses the following command line switch: --enable-logging + /// + property DebugLog : TWV2DebugLog read FDebugLog write FDebugLog; + /// + /// Sets the minimum log level. + /// + /// + /// Uses the following command line switch: --log-level + /// + property DebugLogLevel : TWV2DebugLogLevel read FDebugLogLevel write FDebugLogLevel; + /// + /// Specifies the flags passed to JS engine. + /// + /// + /// Uses the following command line switch: --js-flags + /// + property JavaScriptFlags : wvstring read FJavaScriptFlags write FJavaScriptFlags; + /// + /// Workaround given my Microsoft to disable the "Download Edge" notifications. + /// + property DisableEdgePitchNotification : boolean read FDisableEdgePitchNotification write FDisableEdgePitchNotification; + /// + /// Treat given (insecure) origins as secure origins. + /// Multiple origins can be supplied as a comma-separated list. + /// For the definition of secure contexts, see https://w3c.github.io/webappsec-secure-contexts/ + /// and https://www.w3.org/TR/powerful-features/#is-origin-trustworthy + /// Example: --unsafely-treat-insecure-origin-as-secure=http://a.test,http://b.test + /// + /// + /// Uses the following command line switch: --unsafely-treat-insecure-origin-as-secure + /// + property TreatInsecureOriginAsSecure : wvstring read FTreatInsecureOriginAsSecure write FTreatInsecureOriginAsSecure; + /// + /// Enable the MS Office file viewer in the browser. + /// This is a workaround given by Microsoft to open MS Office documents in the web browser instead of downloading the files. + /// + property OpenOfficeDocumentsInWebViewer : boolean read FOpenOfficeDocumentsInWebViewer write FOpenOfficeDocumentsInWebViewer; + /// + /// If enabled, allows implicit sign-in to Microsoft webpages using any account, by using the information from the primary OS account. + /// + /// + /// This property uses the msSingleSignOnOSForPrimaryAccountIsShared flag. + /// See the WebView2 browser flags article. + /// + property MicrosoftSignIn : boolean read FMicrosoftSignIn write FMicrosoftSignIn; + /// + /// This option enables a combination of X25519 and Kyber in TLS 1.3. + /// + property TLS13HybridizedKyberSupport : TWVState read FPostQuantumKyber write FPostQuantumKyber; + /// + /// A string used to override the default user agent with a custom one. + /// + /// + /// Uses the following command line switch: --user-agent + /// + property UserAgent : wvstring read FUserAgent write FUserAgent; + /// + /// Bypasses the dialog prompting the user for permission to capture cameras and microphones. + /// Useful in automatic tests of video-conferencing Web applications. This is nearly + /// identical to kUseFakeUIForMediaStream, with the exception being that this flag does NOT + /// affect screen-capture. + /// + /// + /// Uses the following command line switch: --auto-accept-camera-and-microphone-capture + /// + property AutoAcceptCamAndMicCapture : boolean read FAutoAcceptCamAndMicCapture write FAutoAcceptCamAndMicCapture; + /// + /// Returns true if the current WebView2 runtime version supports Composition Controllers. + /// + /// + /// See the ICoreWebView2Environment3 article. + /// + property SupportsCompositionController : boolean read GetSupportsCompositionController; + /// + /// Returns the `ICoreWebView2ProcessInfoCollection` + /// Provide a list of all process using same user data folder except for crashpad process. + /// + /// + /// See the ICoreWebView2Environment8 article. + /// + property ProcessInfos : ICoreWebView2ProcessInfoCollection read GetProcessInfos; + /// + /// Returns true if the current WebView2 runtime version supports Controller Options. + /// + /// + /// See the ICoreWebView2Environment10 article. + /// + property SupportsControllerOptions : boolean read GetSupportsControllerOptions; + /// + /// `FailureReportFolderPath` returns the path of the folder where minidump files are written. + /// Whenever a WebView2 process crashes, a crash dump file will be created in the crash dump folder. + /// The crash dump format is minidump files. + /// Please see [Minidump Files documentation](/windows/win32/debug/minidump-files) for detailed information. + /// Normally when a single child process fails, a minidump will be generated and written to disk, + /// then the `ProcessFailed` event is raised. But for unexpected crashes, a minidump file might not be generated + /// at all, despite whether `ProcessFailed` event is raised. If there are multiple + /// process failures at once, multiple minidump files could be generated. Thus `FailureReportFolderPath` + /// could contain old minidump files that are not associated with a specific `ProcessFailed` event. + /// + /// + /// See the ICoreWebView2Environment11 article. + /// + property FailureReportFolderPath : wvstring read GetFailureReportFolderPath; + /// + /// OnEnvironmentCreated is triggered when the Environment is successfully created and Status is wvlsInitialized. + /// + property OnEnvironmentCreated : TLoaderNotifyEvent read FOnEnvironmentCreated write FOnEnvironmentCreated; + /// + /// OnInitializationError is triggered when there was a problem creating the Environment ans Status is wvlsError. ErrorCode and ErrorMessage have more details about this error. + /// + property OnInitializationError : TLoaderNotifyEvent read FOnInitializationError write FOnInitializationError; + /// + /// OnGetCustomSchemes is triggered automatically before creaing the environment to register custom schemes. + /// Fill the aCustomSchemes event parameter with all the information to create one or more + /// ICoreWebView2CustomSchemeRegistration instances that will be used during the creation of the Environment. + /// + /// + /// See TWVCustomSchemeInfo. + /// See the ICoreWebView2CustomSchemeRegistration article. + /// See the ICoreWebView2EnvironmentOptions4 article. + /// + property OnGetCustomSchemes : TLoaderGetCustomSchemesEvent read FOnGetCustomSchemes write FOnGetCustomSchemes; + /// + /// OnNewBrowserVersionAvailable runs when a newer version of the WebView2 + /// Runtime is installed and available using WebView2. + /// + /// + /// See the ICoreWebView2Environment article. + /// + property OnNewBrowserVersionAvailable : TLoaderNewBrowserVersionAvailableEvent read FOnNewBrowserVersionAvailable write FOnNewBrowserVersionAvailable; + /// + /// The OnBrowserProcessExited event is triggered when the collection of WebView2 + /// Runtime processes for the browser process of this environment terminate + /// due to browser process failure or normal shutdown (for example, when all + /// associated WebViews are closed), after all resources have been released + /// (including the user data folder). + /// + /// + /// See the ICoreWebView2Environment5 article. + /// + property OnBrowserProcessExited : TLoaderBrowserProcessExitedEvent read FOnBrowserProcessExited write FOnBrowserProcessExited; + /// + /// OnProcessInfosChanged is triggered when the ProcessInfos property has changed. + /// + /// + /// See the ICoreWebView2Environment8 article. + /// + property OnProcessInfosChanged : TLoaderProcessInfosChangedEvent read FOnProcessInfosChanged write FOnProcessInfosChanged; + end; + + /// + /// Class used by the TWVLoader.ProxySettigns property to configure + /// a custom proxy server using the following command line switches: + /// --no-proxy-server, --proxy-auto-detect, --proxy-bypass-list, + /// --proxy-pac-url and --proxy-server. + /// + /// + /// Uses the following command line switch: --no-proxy-server + /// Uses the following command line switch: --proxy-auto-detect + /// Uses the following command line switch: --proxy-bypass-list + /// Uses the following command line switch: --proxy-pac-url + /// Uses the following command line switch: --proxy-server + /// See the Network Settings article. + /// See the Proxy Support article. + /// See the chrome.proxy API article. + /// + TWVProxySettings = class + protected + FNoProxyServer : boolean; + FAutoDetect : boolean; + FByPassList : wvstring; + FPacUrl : wvstring; + FServer : wvstring; + + public + constructor Create; + + property NoProxyServer : boolean read FNoProxyServer write FNoProxyServer; + property AutoDetect : boolean read FAutoDetect write FAutoDetect; + property ByPassList : wvstring read FByPassList write FByPassList; + property PacUrl : wvstring read FPacUrl write FPacUrl; + property Server : wvstring read FServer write FServer; + end; + +var + /// + /// Global instance of TWVLoader used to simplify the WebView2 initialization and destruction. + /// + /// + /// See TWVLoader. + /// + GlobalWebView2Loader : TWVLoader = nil; + +procedure DestroyGlobalWebView2Loader; + +implementation + +uses + uRESTDWPrivWVConstants, uRESTDWPrivWVMiscFunctions, uRESTDWPrivWVCoreWebView2Delegates, + uRESTDWPrivWVCoreWebView2EnvironmentOptions, uRESTDWPrivWVLoaderInternal, uRESTDWPrivWVCoreWebView2CustomSchemeRegistration; + +const + WEBVIEW2LOADERLIB = 'WebView2Loader.dll'; + +procedure DestroyGlobalWebView2Loader; +begin + if assigned(GlobalWebView2Loader) then + FreeAndNil(GlobalWebView2Loader); +end; + +constructor TWVLoader.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + + FCoreWebView2Environment := nil; + FOnEnvironmentCreated := nil; + FOnNewBrowserVersionAvailable := nil; + FOnProcessInfosChanged := nil; + FOnInitializationError := nil; + FOnBrowserProcessExited := nil; + FOnGetCustomSchemes := nil; + FStatus := wvlsCreated; + FSyncObj := nil; + FWorkerIDGen := 0; + FLibHandle := 0; + FError := 0; + FBrowserExecPath := ''; + FUserDataFolder := ''; + FSetCurrentDir := True; + FCheckFiles := True; + FShowMessageDlg := True; + FInitCOMLibrary := {$IFDEF DELPHI16_UP}False{$ELSE}True{$ENDIF}; + FLocalCOMInitMade := False; + FForcedDeviceScaleFactor := 0; + FReRaiseExceptions := False; + FLoaderDllPath := ''; + FUseInternalLoader := False; + FAllowOldRuntime := True; + FRemoteDebuggingPort := 0; + FRemoteAllowOrigins := ''; + + UpdateDeviceScaleFactor; + + // Fields used to create the environment + FAdditionalBrowserArguments := ''; + FLanguage := ''; + FTargetCompatibleBrowserVersion := LowestChromiumVersion; + FAllowSingleSignOnUsingOSPrimaryAccount := False; + FExclusiveUserDataFolderAccess := False; + FCustomCrashReportingEnabled := False; + FEnableTrackingPrevention := True; + FAreBrowserExtensionsEnabled := False; + FChannelSearchKind := COREWEBVIEW2_CHANNEL_SEARCH_KIND_MOST_STABLE; + FReleaseChannels := COREWEBVIEW2_RELEASE_CHANNELS_STABLE or + COREWEBVIEW2_RELEASE_CHANNELS_BETA or + COREWEBVIEW2_RELEASE_CHANNELS_DEV or + COREWEBVIEW2_RELEASE_CHANNELS_CANARY; + FScrollBarStyle := COREWEBVIEW2_SCROLLBAR_STYLE_DEFAULT; + + // Fields used to set command line switches + FEnableGPU := True; + FEnableFeatures := ''; + FDisableFeatures := ''; + FEnableBlinkFeatures := ''; + FDisableBlinkFeatures := ''; + FBlinkSettings := ''; + FForceFieldTrials := ''; + FForceFieldTrialParams := ''; + FSmartScreenProtectionEnabled := True; + FAllowInsecureLocalhost := False; + FDisableWebSecurity := False; + FTouchEvents := STATE_DEFAULT; + FHyperlinkAuditing := True; + FAutoplayPolicy := appDefault; + FMuteAudio := False; + FDefaultEncoding := ''; + FKioskPrinting := False; + FAllowFileAccessFromFiles := False; + FAllowRunningInsecureContent := False; + FDisableBackgroundNetworking := False; + FDebugLog := dlDisabled; + FDebugLogLevel := dllDefault; + FJavaScriptFlags := ''; + FDisableEdgePitchNotification := True; + FTreatInsecureOriginAsSecure := ''; + FOpenOfficeDocumentsInWebViewer := False; + FAutoAcceptCamAndMicCapture := False; + FMicrosoftSignIn := False; + FPostQuantumKyber := STATE_DEFAULT; + FUserAgent := ''; + FProxySettings := nil; + FErrorLog := nil; + + SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]); +end; + +destructor TWVLoader.Destroy; +begin + try + DestroyEnvironment; + UnLoadWebView2Library; + + if FLocalCOMInitMade then + CoUnInitialize; + + if assigned(FProxySettings) then + FreeAndNil(FProxySettings); + + if assigned(FErrorLog) then + FreeAndNil(FErrorLog); + + if assigned(FSyncObj) then + FreeAndNil(FSyncObj); + finally + inherited Destroy; + end; +end; + +procedure TWVLoader.AfterConstruction; +begin + inherited AfterConstruction; + + FProxySettings := TWVProxySettings.Create; + FErrorLog := TStringList.Create; +end; + +procedure TWVLoader.DestroyEnvironment; +begin + if (FCoreWebView2Environment <> nil) then + FreeAndNil(FCoreWebView2Environment); +end; + +procedure TWVLoader.doOnInitializationError; +begin + if assigned(FOnInitializationError) then + FOnInitializationError(self); +end; + +procedure TWVLoader.doOnEnvironmentCreated; +begin + if assigned(FOnEnvironmentCreated) then + FOnEnvironmentCreated(self); +end; + +procedure TWVLoader.doOnNewBrowserVersionAvailable(const aEnvironment: ICoreWebView2Environment); +begin + if assigned(FOnNewBrowserVersionAvailable) then + FOnNewBrowserVersionAvailable(self, aEnvironment); +end; + +procedure TWVLoader.doOnBrowserProcessExitedEvent(const sender: ICoreWebView2Environment; const args: ICoreWebView2BrowserProcessExitedEventArgs); +begin + if assigned(FOnBrowserProcessExited) then + FOnBrowserProcessExited(self, sender, args); +end; + +procedure TWVLoader.doProcessInfosChangedEvent(const sender: ICoreWebView2Environment); +begin + if assigned(FOnProcessInfosChanged) then + FOnProcessInfosChanged(self, sender); +end; + +procedure TWVLoader.doOnGetCustomSchemes(var aSchemeRegistrations : TWVCustomSchemeRegistrationArray); +var + TempArray : TWVCustomSchemeInfoArray; + i, TempLen : integer; +begin + if not(assigned(FOnGetCustomSchemes)) then exit; + + TempArray := nil; + FOnGetCustomSchemes(self, TempArray); + TempLen := length(TempArray); + + if (TempLen = 0) then exit; + + SetLength(aSchemeRegistrations, TempLen); + ZeroMemory(aSchemeRegistrations, TempLen * SizeOf(ICoreWebView2CustomSchemeRegistration)); + + i := 0; + while (i < TempLen) do + begin + aSchemeRegistrations[i] := TCoreWebView2CustomSchemeRegistration.Create(TempArray[i]); + inc(i); + end; +end; + +function TWVLoader.GetExtendedFileVersion(const aFileName : wvstring) : uint64; +var + TempSize : DWORD; + TempBuffer : pointer; + TempLen : UINT; + TempHandle : cardinal; + TempInfo : PVSFixedFileInfo; +begin + Result := 0; + TempBuffer := nil; + TempInfo := nil; + TempHandle := 0; + TempLen := 0; + + try + try + TempSize := GetFileVersionInfoSizeW(PWideChar(aFileName), TempHandle); + + if (TempSize > 0) then + begin + GetMem(TempBuffer, TempSize); + + if GetFileVersionInfoW(PWideChar(aFileName), TempHandle, TempSize, TempBuffer) and + VerQueryValue(TempBuffer, '\', Pointer(TempInfo), TempLen) then + begin + Result := TempInfo^.dwFileVersionMS; + Result := Result shl 32; + Result := Result or TempInfo^.dwFileVersionLS; + end; + end + else + OutputDebugMessage('TWVLoader.GetExtendedFileVersion error: ' + SysErrorMessage(GetLastError())); + except + on e : exception do + if CustomExceptionHandler('TWVLoader.GetExtendedFileVersion', e) then raise; + end; + finally + if (TempBuffer <> nil) then FreeMem(TempBuffer); + end; +end; + +function TWVLoader.GetFileVersion(const aFile : wvstring; var aVersionInfo : TFileVersionInfo) : boolean; +var + TempVersion : uint64; +begin + Result := False; + + try + if FileExists(aFile) then + begin + TempVersion := GetExtendedFileVersion(aFile); + + if (TempVersion <> 0) then + begin + aVersionInfo.MajorVer := word(TempVersion shr 48); + aVersionInfo.MinorVer := word((TempVersion shr 32) and $FFFF); + aVersionInfo.Release := word((TempVersion shr 16) and $FFFF); + aVersionInfo.Build := word(TempVersion and $FFFF); + + Result := True; + end; + end; + except + on e : exception do + if CustomExceptionHandler('TWVLoader.GetFileVersion', e) then raise; + end; +end; + +function TWVLoader.Lock: boolean; +begin + if assigned(FSyncObj) then + begin + FSyncObj.Acquire; + Result := True; + end + else + Result := False; +end; + +procedure TWVLoader.UnLock; +begin + if assigned(FSyncObj) then + FSyncObj.Release; +end; + +function TWVLoader.LoadWebView2Library : boolean; +var + TempOldDir : string; + TempLoaderLibPath : wvstring; +begin + Result := False; + + if FUseInternalLoader then + begin + Result := True; + exit; + end; + + try + if (FLibHandle <> 0) then + Result := True + else + try + if FSetCurrentDir then + begin + TempOldDir := GetCurrentDir; + chdir(GetModulePath); + end; + + FStatus := wvlsLoading; + + if (FLoaderDllPath <> '') then + TempLoaderLibPath := FLoaderDllPath + else + TempLoaderLibPath := WEBVIEW2LOADERLIB; + + FLibHandle := LoadLibraryW(PWideChar(TempLoaderLibPath)); + + if (FLibHandle = 0) then + begin + FStatus := wvlsError; + FError := GetLastError; + + AppendErrorLog('Error loading ' + TempLoaderLibPath); + AppendErrorLog('Error code : 0x' + {$IFDEF FPC}UTF8Decode({$ENDIF}inttohex(cardinal(FError), 8){$IFDEF FPC}){$ENDIF}); + AppendErrorLog({$IFDEF FPC}UTF8Decode({$ENDIF}SysErrorMessage(cardinal(FError)){$IFDEF FPC}){$ENDIF}); + + ShowErrorMessageDlg(ErrorMessage); + end + else + begin + FStatus := wvlsLoaded; + Result := True; + end; + finally + if FSetCurrentDir then + chdir(TempOldDir); + end; + except + on e : exception do + if CustomExceptionHandler('TWVLoader.LoadWebView2Library', e) then raise; + end; +end; + +procedure TWVLoader.UnLoadWebView2Library; +begin + if FUseInternalLoader then + exit; + + try + if (FLibHandle <> 0) then + begin + FreeLibrary(FLibHandle); + FLibHandle := 0; + FStatus := wvlsUnloaded; + end; + except + on e : exception do + if CustomExceptionHandler('TWVLoader.UnLoadWebView2Library', e) then raise; + end; +end; + +function TWVLoader.CheckFileVersion(const aFile : wvstring; aMajor, aMinor, aRelease, aBuild : word) : boolean; +var + TempVersionInfo : TFileVersionInfo; +begin + Result := False; + + if GetFileVersion(aFile, TempVersionInfo) then + begin + if (TempVersionInfo.MajorVer > aMajor) then + Result := True + else + if (TempVersionInfo.MajorVer = aMajor) then + begin + if (TempVersionInfo.MinorVer > aMinor) then + Result := True + else + if (TempVersionInfo.MinorVer = aMinor) then + begin + if (TempVersionInfo.Release > aRelease) then + Result := True + else + if (TempVersionInfo.Release = aRelease) then + Result := (TempVersionInfo.Build >= aBuild); + end; + end; + end; +end; + +// This function is based on the answer given by 'Alex' in StackOverflow +// https://stackoverflow.com/questions/2748474/how-to-determine-if-dll-file-was-compiled-as-x64-or-x86-bit-using-either-delphi +function TWVLoader.GetDLLHeaderMachine(const aDLLFile : string; var aMachine : integer) : boolean; +var + TempHeader : TImageDosHeader; + TempImageNtHeaders : TImageNtHeaders; + TempStream : TFileStream; +begin + Result := False; + aMachine := IMAGE_FILE_MACHINE_UNKNOWN; + TempStream := nil; + + try + try + if FileExists(aDLLFile) then + begin + TempStream := TFileStream.Create(aDLLFile, fmOpenRead or fmShareDenyWrite); + TempStream.seek(0, soFromBeginning); + TempStream.ReadBuffer(TempHeader, SizeOf(TempHeader)); + + if (TempHeader.e_magic = IMAGE_DOS_SIGNATURE) and + (TempHeader._lfanew <> 0) then + begin + TempStream.Position := TempHeader._lfanew; + TempStream.ReadBuffer(TempImageNtHeaders, SizeOf(TempImageNtHeaders)); + + if (TempImageNtHeaders.Signature = IMAGE_NT_SIGNATURE) then + begin + aMachine := TempImageNtHeaders.FileHeader.Machine; + Result := True; + end; + end; + end; + except + on e : exception do + if CustomExceptionHandler('TWVLoader.GetDLLHeaderMachine', e) then raise; + end; + finally + if (TempStream <> nil) then FreeAndNil(TempStream); + end; +end; + +function TWVLoader.CheckBrowserExecPath : boolean; +begin + Result := False; + + if (length(FBrowserExecPath) = 0) then + begin + if (length(InstalledRuntimeVersion) > 0) or + SearchInstalledProgram('WebView2 Runtime', 'Microsoft Corporation') or + (length(GetInternalAvailableBrowserVersion) > 0) then + Result := True + else + begin + FStatus := wvlsError; + AppendErrorLog('WebView2 Runtime is not installed correctly.'); + AppendErrorLog('Download and run the Evergreen Standalone Installer from '); + AppendErrorLog('https://developer.microsoft.com/en-us/microsoft-edge/webview2/#download-section'); + + ShowErrorMessageDlg(ErrorMessage); + end; + end + else + try + if FileExists(IncludeTrailingPathDelimiter(FBrowserExecPath) + 'msedgewebview2.exe') then + Result := True + else + begin + FStatus := wvlsError; + AppendErrorLog('The Browser Executable Folder doesn' + #39 + 't exist.'); + + ShowErrorMessageDlg(ErrorMessage); + end; + except + on e : exception do + if CustomExceptionHandler('TWVLoader.CheckBrowserExecPath', e) then raise; + end; +end; + +function TWVLoader.CheckWebViewRuntimeVersion : boolean; +var + TempCompRslt : integer; +begin + Result := False; + + if (length(FBrowserExecPath) = 0) then + Result := CompareVersions(InstalledRuntimeVersion, LowestChromiumVersion, TempCompRslt) and + (TempCompRslt >= 0) + else + if CheckFileVersion(IncludeTrailingPathDelimiter(FBrowserExecPath) + 'msedgewebview2.exe', + CHROMIUM_VERSION_MAJOR, + CHROMIUM_VERSION_MINOR, + CHROMIUM_VERSION_RELEASE, + CHROMIUM_VERSION_BUILD) then + Result := True; + + if not(Result) then + begin + AppendErrorLog('The WebView Runtime version is older than expected! Some WebView4Delphi features won' + #39 + 't work.'); + + if FAllowOldRuntime then + Result := True + else + FStatus := wvlsError; + end; +end; + +function TWVLoader.Is32BitProcess : boolean; +begin +{$IFDEF TARGET_32BITS} + Result := True; +{$ELSE} + Result := False; +{$ENDIF} +end; + +procedure TWVLoader.ShowErrorMessageDlg(const aError : wvstring); +begin + if FShowMessageDlg then + MessageBoxW(0, PWideChar(aError + #0), PWideChar(WideString('Error') + #0), MB_ICONERROR or MB_OK or MB_TOPMOST); +end; + +function TWVLoader.CheckWV2DLL : boolean; +var + TempMachine : integer; + TempVersionInfo : TFileVersionInfo; + TempLoaderLibPath : wvstring; +begin + Result := False; + + if FUseInternalLoader then + begin + Result := True; + exit; + end; + + if FLoaderDllPath <> '' then + TempLoaderLibPath := FLoaderDllPath + else + TempLoaderLibPath := WEBVIEW2LOADERLIB; + + if CheckFileVersion(TempLoaderLibPath, + WEBVIEW2LOADERLIB_VERSION_MAJOR, + WEBVIEW2LOADERLIB_VERSION_MINOR, + WEBVIEW2LOADERLIB_VERSION_RELEASE, + WEBVIEW2LOADERLIB_VERSION_BUILD) then + begin + TempMachine := 0; + + if GetDLLHeaderMachine({$IFDEF FPC}UTF8Encode({$ENDIF}TempLoaderLibPath{$IFDEF FPC}){$ENDIF}, TempMachine) then + case TempMachine of + WV2_IMAGE_FILE_MACHINE_I386 : + if Is32BitProcess then + Result := True + else + begin + FStatus := wvlsError; + AppendErrorLog('Wrong WebView2Loader.dll !'); + AppendErrorLog('Use the 32 bit loader DLL with 32 bits applications only.'); + + ShowErrorMessageDlg(ErrorMessage); + end; + + WV2_IMAGE_FILE_MACHINE_AMD64 : + if not(Is32BitProcess) then + Result := True + else + + begin + FStatus := wvlsError; + AppendErrorLog('Wrong WebView2Loader.dll !'); + AppendErrorLog('Use the 64 bit loader DLL with 64 bits applications only.'); + + ShowErrorMessageDlg(ErrorMessage); + end; + + else + begin + FStatus := wvlsError; + AppendErrorLog('Unknown WebView2Loader.dll !'); + + ShowErrorMessageDlg(ErrorMessage); + end; + end + else + Result := True; + end + else + begin + FStatus := wvlsError; + + if GetFileVersion(TempLoaderLibPath, TempVersionInfo) then + begin + AppendErrorLog('Unsupported WebView2Loader.dll version !'); + AppendErrorLog('Expected WebView2Loader.dll version : ' + LowestLoaderDLLVersion); + AppendErrorLog('Found WebView2Loader.dll version : ' + + {$IFDEF FPC}UTF8Decode({$ENDIF} + IntToStr(TempVersionInfo.MajorVer) + '.' + + IntToStr(TempVersionInfo.MinorVer) + '.' + + IntToStr(TempVersionInfo.Release) + '.' + + IntToStr(TempVersionInfo.Build){$IFDEF FPC}){$ENDIF}); + end + else + AppendErrorLog('WebView2Loader.dll file not found !'); + + ShowErrorMessageDlg(ErrorMessage); + end; +end; + +function TWVLoader.CheckWV2Library : boolean; +var + TempOldDir : string; +begin + if not(FCheckFiles) then + begin + Result := True; + exit; + end; + + if FSetCurrentDir then + begin + TempOldDir := GetCurrentDir; + chdir(GetModulePath); + end; + + Result := CheckBrowserExecPath and + (FUseInternalLoader or CheckWV2DLL); + + if FSetCurrentDir then chdir(TempOldDir); +end; + +function TWVLoader.SearchInstalledProgram(const aDisplayName, aPublisher : string) : boolean; +const + UNINST_PATH_32BIT = 'SOFTWARE\Microsoft\Windows\CurrentVersion\UnInstall'; + UNINST_PATH_64BIT = 'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'; +begin + Result := SearchInstalledProgramInPath(UNINST_PATH_32BIT, aDisplayName, aPublisher, True) or + SearchInstalledProgramInPath(UNINST_PATH_32BIT, aDisplayName, aPublisher, False) or + SearchInstalledProgramInPath(UNINST_PATH_64BIT, aDisplayName, aPublisher, True) or + SearchInstalledProgramInPath(UNINST_PATH_64BIT, aDisplayName, aPublisher, False); +end; + +function TWVLoader.SearchInstalledProgramInPath(const aRegPath, aDisplayName, aPublisher : string; aLocalMachine : boolean) : boolean; +const + DISPLAYNAME_KEY = 'DisplayName'; + PUBLISHER_KEY = 'Publisher'; +var + TempReg : TRegistry; + TempKeys : TStringList; + i, j : integer; + TempDisplayName, TempPublisher, TempKey : string; +begin + Result := False; + TempReg := nil; + TempKeys := nil; + + try + try + TempReg := TRegistry.Create; + + if aLocalMachine then + TempReg.RootKey := HKEY_LOCAL_MACHINE + else + TempReg.RootKey := HKEY_CURRENT_USER; + + if TempReg.OpenKeyReadOnly(aRegPath) then + begin + TempKeys := TStringList.Create; + TempReg.GetKeyNames(TStrings(TempKeys)); + TempReg.CloseKey; + + i := 0; + j := TempKeys.Count; + + while (i < j) and not(Result) do + begin + TempKey := TempKeys[i]; + + if TempReg.OpenKeyReadOnly(aRegPath + '\' + TempKey) then + begin + if TempReg.ValueExists(DISPLAYNAME_KEY) then + TempDisplayName := lowercase(TempReg.ReadString(DISPLAYNAME_KEY)) + else + TempDisplayName := ''; + + if TempReg.ValueExists(PUBLISHER_KEY) then + TempPublisher := lowercase(TempReg.ReadString(PUBLISHER_KEY)) + else + TempPublisher := ''; + + Result := (Pos(lowercase(aDisplayName), TempDisplayName) > 0) and + (Pos(lowercase(aPublisher), TempPublisher) > 0); + + TempReg.CloseKey; + end; + + inc(i); + end; + end; + except + on e : exception do + if CustomExceptionHandler('TWVLoader.SearchInstalledProgram', e) then raise; + end; + finally + if (TempReg <> nil) then FreeAndNil(TempReg); + if (TempKeys <> nil) then FreeAndNil(TempKeys); + end; +end; + +function TWVLoader.LoadLibProcedures : boolean; +begin + Result := False; + + if FUseInternalLoader then + begin + CreateCoreWebView2EnvironmentWithOptions := Internal_CreateCoreWebView2EnvironmentWithOptions; + CreateCoreWebView2Environment := Internal_CreateCoreWebView2Environment; + GetAvailableCoreWebView2BrowserVersionString := Internal_GetAvailableCoreWebView2BrowserVersionString; + GetAvailableCoreWebView2BrowserVersionStringWithOptions := Internal_GetAvailableCoreWebView2BrowserVersionStringWithOptions; + CompareBrowserVersions := Internal_CompareBrowserVersions; + FStatus := wvlsImported; + Result := True; + end + else + if (FLibHandle <> 0) then + try + begin + CreateCoreWebView2EnvironmentWithOptions := GetProcAddress(FLibHandle, 'CreateCoreWebView2EnvironmentWithOptions'); + CreateCoreWebView2Environment := GetProcAddress(FLibHandle, 'CreateCoreWebView2Environment'); + GetAvailableCoreWebView2BrowserVersionString := GetProcAddress(FLibHandle, 'GetAvailableCoreWebView2BrowserVersionString'); + GetAvailableCoreWebView2BrowserVersionStringWithOptions := GetProcAddress(FLibHandle, 'GetAvailableCoreWebView2BrowserVersionStringWithOptions'); + CompareBrowserVersions := GetProcAddress(FLibHandle, 'CompareBrowserVersions'); + + if assigned(CreateCoreWebView2EnvironmentWithOptions) and + assigned(CreateCoreWebView2Environment) and + assigned(GetAvailableCoreWebView2BrowserVersionString) and + assigned(GetAvailableCoreWebView2BrowserVersionStringWithOptions) and + assigned(CompareBrowserVersions) then + begin + Result := True; + FStatus := wvlsImported; + end + else + begin + FStatus := wvlsError; + AppendErrorLog('There was a problem loading the library procedures'); + + ShowErrorMessageDlg(ErrorMessage); + end; + end; + except + on e : exception do + if CustomExceptionHandler('TWVLoader.LoadLibProcedures', e) then raise; + end; +end; + +function TWVLoader.GetCustomCommandLineSwitches : wvstring; +var + TempFeatures : wvstring; + {$IFDEF VER140} + TempDecimalSeparator : char; // Only for Delphi 6 + {$ELSE} + TempFormatSettings : TFormatSettings; + {$ENDIF} +begin + if not(FEnableGPU) then + Result := '--disable-gpu --disable-gpu-compositing '; + + // The list of features you can enable is here : + // https://chromium.googlesource.com/chromium/src/+/master/chrome/common/chrome_features.cc + // https://source.chromium.org/chromium/chromium/src/+/main:content/public/common/content_features.cc + // https://source.chromium.org/search?q=base::Feature + TempFeatures := FEnableFeatures; + + // This is a workaround given by Microsoft to open MS Office documents in the web browser instead of downloading the files. + if FOpenOfficeDocumentsInWebViewer then + begin + if (length(TempFeatures) > 0) then + TempFeatures := TempFeatures + ',msOpenOfficeDocumentsInWebViewer' + else + TempFeatures := 'msOpenOfficeDocumentsInWebViewer'; + end; + + if FMicrosoftSignIn then + begin + if (length(TempFeatures) > 0) then + TempFeatures := TempFeatures + ',msSingleSignOnOSForPrimaryAccountIsShared' + else + TempFeatures := 'msSingleSignOnOSForPrimaryAccountIsShared'; + end; + + if (FPostQuantumKyber = STATE_ENABLED) then + begin + if (length(TempFeatures) > 0) then + TempFeatures := TempFeatures + ',PostQuantumKyber' + else + TempFeatures := 'PostQuantumKyber'; + end; + + if (length(TempFeatures) > 0) then + Result := Result + '--enable-features=' + TempFeatures + ' '; + + // The list of features you can disable is here : + // https://chromium.googlesource.com/chromium/src/+/master/chrome/common/chrome_features.cc + // https://source.chromium.org/chromium/chromium/src/+/main:content/public/common/content_features.cc + // https://source.chromium.org/search?q=base::Feature + TempFeatures := FDisableFeatures; + + // This is the workaround given my Microsoft to disable the SmartScreen protection. + if not(FSmartScreenProtectionEnabled) then + begin + if (length(TempFeatures) > 0) then + TempFeatures := TempFeatures + ',msSmartScreenProtection' + else + TempFeatures := 'msSmartScreenProtection'; + end; + + // This is the workaround given my Microsoft to disable the "Download Edge" notifications. + if FDisableEdgePitchNotification then + begin + if (length(TempFeatures) > 0) then + TempFeatures := TempFeatures + ',msEdgeRose' + else + TempFeatures := 'msEdgeRose'; + end; + + if (FPostQuantumKyber = STATE_DISABLED) then + begin + if (length(TempFeatures) > 0) then + TempFeatures := TempFeatures + ',PostQuantumKyber' + else + TempFeatures := 'PostQuantumKyber'; + end; + + if (length(TempFeatures) > 0) then + Result := Result + '--disable-features=' + TempFeatures + ' '; + + // The list of Blink features you can enable is here : + // https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5 + if (length(FEnableBlinkFeatures) > 0) then + Result := Result + '--enable-blink-features=' + FEnableBlinkFeatures + ' '; + + // The list of Blink features you can disable is here : + // https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5 + if (length(FDisableBlinkFeatures) > 0) then + Result := Result + '--disable-blink-features=' + FDisableBlinkFeatures + ' '; + + // The list of Blink settings you can modify is here : + // https://source.chromium.org/chromium/chromium/src/+/master:third_party/blink/renderer/core/frame/settings.json5 + if (length(FBlinkSettings) > 0) then + Result := Result + '--blink-settings=' + FBlinkSettings + ' '; + + // https://source.chromium.org/chromium/chromium/src/+/master:base/base_switches.cc + if (length(FForceFieldTrials) > 0) then + Result := Result + '--force-fieldtrials=' + FForceFieldTrials + ' '; + + // https://source.chromium.org/chromium/chromium/src/+/master:components/variations/variations_switches.cc + if (length(FForceFieldTrialParams) > 0) then + Result := Result + '--force-fieldtrial-params=' + FForceFieldTrialParams + ' '; + + if FAllowInsecureLocalhost then + Result := Result + '--allow-insecure-localhost '; + + if FDisableWebSecurity then + Result := Result + '--disable-web-security '; + + case FTouchEvents of + STATE_ENABLED : Result := Result + '--touch-events=enabled '; + STATE_DISABLED : Result := Result + '--touch-events=disabled '; + end; + + if not(FHyperlinkAuditing) then + Result := Result + '--no-pings '; + + case FAutoplayPolicy of + appDocumentUserActivationRequired : + Result := Result + '--autoplay-policy=document-user-activation-required '; + + appNoUserGestureRequired : + Result := Result + '--autoplay-policy=no-user-gesture-required '; + + appUserGestureRequired : + Result := Result + '--autoplay-policy=user-gesture-required '; + end; + + if FMuteAudio then + Result := Result + '--mute-audio '; + + if (length(FDefaultEncoding) > 0) then + Result := Result + '--default-encoding=' + FDefaultEncoding + ' '; + + if FKioskPrinting then + Result := Result + '--kiosk-printing '; + + if FProxySettings.NoProxyServer then + Result := Result + '--no-proxy-server ' + else + begin + if FProxySettings.AutoDetect then + Result := Result + '--proxy-auto-detect '; + + if (length(FProxySettings.ByPassList) > 0) then + Result := Result + '--proxy-bypass-list=' + FProxySettings.ByPassList + ' '; + + if (length(FProxySettings.PacUrl) > 0) then + Result := Result + '--proxy-pac-url=' + FProxySettings.PacUrl + ' '; + + if (length(FProxySettings.Server) > 0) then + Result := Result + '--proxy-server=' + FProxySettings.Server + ' '; + end; + + if FAllowFileAccessFromFiles then + Result := Result + '--allow-file-access-from-files '; + + if FAllowRunningInsecureContent then + Result := Result + '--allow-running-insecure-content '; + + if FDisableBackgroundNetworking then + Result := Result + '--disable-background-networking '; + + if (FForcedDeviceScaleFactor <> 0) then + begin + {$IFDEF VER140} // Only for Delphi 6 + TempDecimalSeparator := DecimalSeparator; + DecimalSeparator := '.'; + Result := Result + '--force-device-scale-factor=' + FloatToStr(FForcedDeviceScaleFactor) + ' '; + DecimalSeparator := TempDecimalSeparator; + {$ELSE} + TempFormatSettings.DecimalSeparator := '.'; + Result := Result + '--force-device-scale-factor=' + + {$IFDEF FPC}UTF8Decode({$ENDIF}FloatToStr(FForcedDeviceScaleFactor, TempFormatSettings){$IFDEF FPC}){$ENDIF} + ' '; + {$ENDIF} + end; + + if (FRemoteDebuggingPort > 0) then + Result := Result + '--remote-debugging-port=' + {$IFDEF FPC}UTF8Decode({$ENDIF}inttostr(FRemoteDebuggingPort){$IFDEF FPC}){$ENDIF} + ' '; + + if (length(FRemoteAllowOrigins) > 0) then + Result := Result + '--remote-allow-origins=' + FRemoteAllowOrigins + ' '; + + case FDebugLog of + dlEnabled : Result := Result + '--enable-logging '; + dlEnabledStdOut : Result := Result + '--enable-logging=stdout '; + dlEnabledStdErr : Result := Result + '--enable-logging=stderr '; + end; + + case FDebugLogLevel of + dllInfo : Result := Result + '--log-level=0 '; + dllWarning : Result := Result + '--log-level=1 '; + dllError : Result := Result + '--log-level=2 '; + dllFatal : Result := Result + '--log-level=3 '; + end; + + if (length(FTreatInsecureOriginAsSecure) > 0) then + Result := Result + '--unsafely-treat-insecure-origin-as-secure=' + FTreatInsecureOriginAsSecure + ' '; + + if FAutoAcceptCamAndMicCapture then + Result := Result + '--auto-accept-camera-and-microphone-capture '; + + // The list of JavaScript flags is here : + // https://chromium.googlesource.com/v8/v8/+/master/src/flags/flag-definitions.h + if (length(FJavaScriptFlags) > 0) then + Result := Result + '--js-flags="' + FJavaScriptFlags + '" '; + + if (length(FUserAgent) > 0) then + Result := Result + '--user-agent="' + FUserAgent + '" '; + + if (length(FAdditionalBrowserArguments) > 0) then + Result := Result + FAdditionalBrowserArguments + else + Result := trim(Result); +end; + +function TWVLoader.CheckInstalledRuntimeRegEntry(aLocalMachine : boolean; const aPath : string; var aVersion : wvstring) : boolean; +const + RUNTIME_REG_VERSION = 'pv'; +var + TempReg : TRegistry; +begin + Result := false; + TempReg := nil; + aVersion := ''; + + try + try + TempReg := TRegistry.Create; + + if aLocalMachine then + TempReg.RootKey := HKEY_LOCAL_MACHINE + else + TempReg.RootKey := HKEY_CURRENT_USER; + + if TempReg.KeyExists(aPath) and + TempReg.OpenKeyReadOnly(aPath) then + begin + if TempReg.ValueExists(RUNTIME_REG_VERSION) then + begin + aVersion := {$IFDEF FPC}UTF8Decode({$ENDIF}TempReg.ReadString(RUNTIME_REG_VERSION){$IFDEF FPC}){$ENDIF}; + Result := length(aVersion) > 0; + end; + + TempReg.CloseKey; + end; + except + on e : exception do + if CustomExceptionHandler('TWVLoader.CheckInstalledRuntimeRegEntry', e) then raise; + end; + finally + if (TempReg <> nil) then FreeAndNil(TempReg); + end; +end; + +function TWVLoader.GetInstalledRuntimeVersion : wvstring; +const + RUNTIME_REG_PATH_32BIT = 'SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}'; + RUNTIME_REG_PATH_64BIT = 'SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}'; +var + TempResult : wvstring; +begin + Result := ''; + + if CheckInstalledRuntimeRegEntry(False, RUNTIME_REG_PATH_32BIT, TempResult) or + CheckInstalledRuntimeRegEntry(False, RUNTIME_REG_PATH_64BIT, TempResult) or + CheckInstalledRuntimeRegEntry(True, RUNTIME_REG_PATH_32BIT, TempResult) or + CheckInstalledRuntimeRegEntry(True, RUNTIME_REG_PATH_64BIT, TempResult) then + Result := TempResult; +end; + +function TWVLoader.GetErrorMessage : wvstring; +begin + if assigned(FErrorLog) then + Result := {$IFDEF FPC}UTF8Decode({$ENDIF}FErrorLog.Text{$IFDEF FPC}){$ENDIF} + else + Result := ''; +end; + +function TWVLoader.GetFailureReportFolderPath : wvstring; +begin + if EnvironmentIsInitialized then + Result := FCoreWebView2Environment.FailureReportFolderPath + else + Result := ''; +end; + +function TWVLoader.CreateEnvironment : boolean; +var + TempOptions : ICoreWebView2EnvironmentOptions; + TempHandler : ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler; + TempHResult : HRESULT; + TempSchemeRegistrations : TWVCustomSchemeRegistrationArray; + i : integer; +begin + Result := False; + TempSchemeRegistrations := nil; + + try + if (FStatus = wvlsImported) and not(EnvironmentIsInitialized) then + begin + doOnGetCustomSchemes(TempSchemeRegistrations); + + TempHandler := TCoreWebView2EnvironmentCompletedHandler.Create(self); + + TempOptions := TCoreWebView2EnvironmentOptions.Create(CustomCommandLineSwitches, + FLanguage, + FTargetCompatibleBrowserVersion, + FAllowSingleSignOnUsingOSPrimaryAccount, + FExclusiveUserDataFolderAccess, + FCustomCrashReportingEnabled, + TempSchemeRegistrations, + FEnableTrackingPrevention, + FAreBrowserExtensionsEnabled, + FChannelSearchKind, + FReleaseChannels, + FScrollBarStyle); + + TempHResult := CreateCoreWebView2EnvironmentWithOptions(PWideChar(FBrowserExecPath), + PWideChar(FUserDataFolder), + TempOptions, + TempHandler); + + if succeeded(TempHResult) then + Result := True + else + begin + FStatus := wvlsError; + FError := TempHResult; + AppendErrorLog('There was an error creating the browser environment. (1)'); + AppendErrorLog('Error code : 0x' + {$IFDEF FPC}UTF8Decode({$ENDIF}inttohex(TempHResult, 8){$IFDEF FPC}){$ENDIF}); + AppendErrorLog(EnvironmentCreationErrorToString(TempHResult)); + + ShowErrorMessageDlg(ErrorMessage); + end; + end; + finally + TempOptions := nil; + TempHandler := nil; + + if assigned(TempSchemeRegistrations) then + begin + i := pred(length(TempSchemeRegistrations)); + while (i >= 0) do + begin + TempSchemeRegistrations[i] := nil; + dec(i); + end; + end; + end; +end; + +function TWVLoader.GetInitialized : boolean; +begin + Result := (FStatus = wvlsInitialized); +end; + +function TWVLoader.GetInitializationError : boolean; +begin + Result := (FStatus = wvlsError); +end; + +function TWVLoader.GetEnvironmentIsInitialized : boolean; +begin + Result := assigned(FCoreWebView2Environment) and + FCoreWebView2Environment.Initialized; +end; + +function TWVLoader.GetDefaultUserDataPath : string; +const + CSIDL_LOCAL_APPDATA = $001c; +var + TempPath : array [0..MAX_PATH] of char; +begin + System.FillChar(TempPath, SizeOf(TempPath), 0); + + if SHGetSpecialFolderPath(0, TempPath, CSIDL_LOCAL_APPDATA, False) then + Result := IncludeTrailingPathDelimiter(TempPath) + 'WebView2\UserData' + else + Result := ''; +end; + +function TWVLoader.GetEnvironment : ICoreWebView2Environment; +begin + if EnvironmentIsInitialized then + Result := FCoreWebView2Environment.BaseIntf + else + Result := nil; +end; + +function TWVLoader.GetProcessInfos : ICoreWebView2ProcessInfoCollection; +begin + if EnvironmentIsInitialized then + Result := FCoreWebView2Environment.ProcessInfos + else + Result := nil; +end; + +function TWVLoader.GetSupportsCompositionController : boolean; +begin + Result := EnvironmentIsInitialized and + FCoreWebView2Environment.SupportsCompositionController; +end; + +function TWVLoader.GetSupportsControllerOptions : boolean; +begin + Result := EnvironmentIsInitialized and + FCoreWebView2Environment.SupportsControllerOptions; +end; + +function TWVLoader.GetAvailableBrowserVersion : wvstring; +var + TempVersion : PWideChar; +begin + Result := ''; + TempVersion := nil; + + if Initialized and + succeeded(GetAvailableCoreWebView2BrowserVersionString(PWideChar(FBrowserExecPath), @TempVersion)) and + assigned(TempVersion) then + begin + Result := TempVersion; + CoTaskMemFree(TempVersion); + end; +end; + +function TWVLoader.GetInternalAvailableBrowserVersion : wvstring; +var + TempVersion : PWideChar; +begin + Result := ''; + TempVersion := nil; + + if succeeded(Internal_GetAvailableCoreWebView2BrowserVersionString(PWideChar(FBrowserExecPath), @TempVersion)) and + assigned(TempVersion) then + begin + Result := TempVersion; + CoTaskMemFree(TempVersion); + end; +end; + +function TWVLoader.GetAvailableBrowserVersionWithOptions : wvstring; +var + TempVersion : PWideChar; + TempOptions : ICoreWebView2EnvironmentOptions; + TempSchemeRegistrations : TWVCustomSchemeRegistrationArray; + i : integer; +begin + Result := ''; + TempVersion := nil; + TempOptions := nil; + TempSchemeRegistrations := nil; + + if Initialized then + try + TempOptions := TCoreWebView2EnvironmentOptions.Create(CustomCommandLineSwitches, + FLanguage, + FTargetCompatibleBrowserVersion, + FAllowSingleSignOnUsingOSPrimaryAccount, + FExclusiveUserDataFolderAccess, + FCustomCrashReportingEnabled, + TempSchemeRegistrations, + FEnableTrackingPrevention, + FAreBrowserExtensionsEnabled, + FChannelSearchKind, + FReleaseChannels, + FScrollBarStyle); + + if succeeded(GetAvailableCoreWebView2BrowserVersionStringWithOptions(PWideChar(FBrowserExecPath), TempOptions, @TempVersion)) and + assigned(TempVersion) then + begin + Result := TempVersion; + CoTaskMemFree(TempVersion); + end; + finally + TempOptions := nil; + + if assigned(TempSchemeRegistrations) then + begin + i := pred(length(TempSchemeRegistrations)); + while (i >= 0) do + begin + TempSchemeRegistrations[i] := nil; + dec(i); + end; + end; + end; +end; + +function TWVLoader.CompareVersions(const aVersion1, aVersion2 : wvstring; var aCompRslt : integer) : boolean; +begin + aCompRslt := 0; + Result := (FStatus in [wvlsImported, wvlsInitialized]) and + succeeded(CompareBrowserVersions(PWideChar(aVersion1), PWideChar(aVersion2), @aCompRslt)); +end; + +procedure TWVLoader.AppendErrorLog(const aText : wvstring); +begin + OutputDebugMessage({$IFDEF FPC}UTF8Encode({$ENDIF}aText{$IFDEF FPC}){$ENDIF}); + if assigned(FErrorLog) then + FErrorLog.Add({$IFDEF FPC}UTF8Encode({$ENDIF}aText{$IFDEF FPC}){$ENDIF}); +end; + +function TWVLoader.NextWorkerID: cardinal; +begin + Result := 0; + + if Lock then + try + if (FWorkerIDGen < pred(high(cardinal))) then + inc(FWorkerIDGen) + else + FWorkerIDGen := 1; + + Result := FWorkerIDGen; + finally + UnLock; + end; +end; + +procedure TWVLoader.UpdateDeviceScaleFactor; +begin + if (FForcedDeviceScaleFactor <> 0) then + FDeviceScaleFactor := FForcedDeviceScaleFactor + else + FDeviceScaleFactor := GetDeviceScaleFactor; +end; + +function TWVLoader.StartWebView2 : boolean; +begin + Result := False; + + if FInitCOMLibrary and not(FLocalCOMInitMade) then + begin + case CoInitializeEx(nil, COINIT_APARTMENTTHREADED) of + S_OK, S_FALSE : + begin + // To uninitialize the COM library gracefully on a thread, each + // successful call to CoInitialize or CoInitializeEx, including any + // call that returns S_FALSE, must be balanced by a corresponding + // call to CoUninitialize. + FLocalCOMInitMade := True; + Result := True; + end; + + RPC_E_CHANGED_MODE : AppendErrorLog('A previous call to CoInitializeEx specified an incompatible concurrency model for this thread.'); + E_INVALIDARG : AppendErrorLog('CoInitializeEx failed. One or more arguments are not valid.'); + E_OUTOFMEMORY : AppendErrorLog('CoInitializeEx failed to allocate necessary memory.'); + E_UNEXPECTED : AppendErrorLog('Unexpected CoInitializeEx failure.'); + else AppendErrorLog('Unknown CoInitializeEx failure.'); + end; + + if not(Result) then + begin + ShowErrorMessageDlg(ErrorMessage); + exit; + end; + end; + + Result := CheckWV2Library and + LoadWebView2Library and + LoadLibProcedures and + CheckWebViewRuntimeVersion and + CreateEnvironment; +end; + +function TWVLoader.EnvironmentCompletedHandler_Invoke( errorCode : HResult; + const result_ : ICoreWebView2Environment) : HRESULT; +begin + Result := S_OK; + + if succeeded(errorCode) and assigned(result_) then + begin + DestroyEnvironment; + + FCoreWebView2Environment := TCoreWebView2Environment.Create(result_); + FCoreWebView2Environment.AddAllLoaderEvents(self); + + FStatus := wvlsInitialized; + + doOnEnvironmentCreated; + end + else + begin + FStatus := wvlsError; + FError := errorCode; + AppendErrorLog('There was a problem initializing the browser environment.'); + AppendErrorLog('Error code : 0x' + {$IFDEF FPC}UTF8Decode({$ENDIF}inttohex(errorCode, 8){$IFDEF FPC}){$ENDIF}); + AppendErrorLog(EnvironmentCreationErrorToString(errorCode)); + + doOnInitializationError; + end; +end; + +function TWVLoader.NewBrowserVersionAvailableEventHandler_Invoke(const sender : ICoreWebView2Environment; + const args : IUnknown): HRESULT; +begin + Result := S_OK; + doOnNewBrowserVersionAvailable(sender); +end; + +function TWVLoader.BrowserProcessExitedEventHandler_Invoke(const sender : ICoreWebView2Environment; + const args : ICoreWebView2BrowserProcessExitedEventArgs): HRESULT; +begin + Result := S_OK; + doOnBrowserProcessExitedEvent(sender, args); +end; + +function TWVLoader.ProcessInfosChangedEventHandler_Invoke(const sender : ICoreWebView2Environment; + const args : IUnknown): HRESULT; +begin + Result := S_OK; + doProcessInfosChangedEvent(sender); +end; + +// TWVProxySettings + +constructor TWVProxySettings.Create; +begin + inherited Create; + + FNoProxyServer := False; + FAutoDetect := False; + FByPassList := ''; + FPacUrl := ''; + FServer := ''; +end; + +initialization + +{ GlobalWebView2Loader is deliberately destroyed by TRESTDWHTMLWebView when + the last designer WebView closes. A design-time BPL can be rebuilt/unloaded + by the IDE, and destroying WebView2 from unit finalization is unsafe there. } + +finalization + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVLoaderInternal.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVLoaderInternal.pas new file mode 100644 index 000000000..8038ce8fa --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVLoaderInternal.pas @@ -0,0 +1,978 @@ +unit uRESTDWPrivWVLoaderInternal; +// Based on +// https://github.com/YWtheGod/DRT/blob/main/SOURCE/DRT.WIN.WebView2Loader.pas +// https://github.com/jchv/OpenWebView2Loader + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + WinApi.Windows, WinApi.ShlObj, WinApi.ActiveX, + {$ELSE} + Windows, + {$ENDIF} + uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVTypes; + +function Internal_CreateCoreWebView2EnvironmentWithOptions(browserExecutableFolder, userDataFolder: LPCWSTR; const environmentOptions: ICoreWebView2EnvironmentOptions; const environment_created_handler: ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler): HRESULT; stdcall; +function Internal_CreateCoreWebView2Environment(const environment_created_handler: ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler): HRESULT; stdcall; +function Internal_GetAvailableCoreWebView2BrowserVersionString(browserExecutableFolder: LPCWSTR; pVersionInfo: PLPWSTR): HRESULT; stdcall; +function Internal_GetAvailableCoreWebView2BrowserVersionStringWithOptions(browserExecutableFolder: LPCWSTR; const environmentOptions: ICoreWebView2EnvironmentOptions; pVersionInfo: PLPWSTR): HRESULT; stdcall; +function Internal_CompareBrowserVersions(version1, version2: LPCWSTR; pRet: PInteger): HRESULT; stdcall; + +implementation + +uses + {$IFDEF DELPHI16_UP} + IOUtils, System.Win.Registry, + {$ELSE} + ActiveX, Registry, + {$ENDIF} + SysUtils, + uRESTDWPrivWVMiscFunctions; + +type + TWebView2ReleaseChannelPreference = (kStable = 0, kCanary = 1); + + TWebView2EnvironmentParams = record + embeddedEdgeSubFolder : wvstring; + userDataDir : wvstring; + environmentOptions : ICoreWebView2EnvironmentOptions; + releaseChannelPreference : TWebView2ReleaseChannelPreference; + end; + +function DoesPolicyExistInRoot(aRootKey : HKEY): boolean; +const + REDIST_OVERRIDE_KEY = 'Software\Policies\Microsoft\Edge\WebView2\'; +var + TempReg : TRegistry; +begin + Result := False; + TempReg := nil; + + try + try + TempReg := TRegistry.Create(KEY_READ); + TempReg.RootKey := aRootKey; + Result := TempReg.KeyExists(REDIST_OVERRIDE_KEY) and + TempReg.OpenKey(REDIST_OVERRIDE_KEY, False); + except + on e : exception do + if CustomExceptionHandler('DoesPolicyExistInRoot', e) then raise; + end; + finally + if assigned(TempReg) then FreeAndNil(TempReg); + end; +end; + +function ReadEnvironmentVariable(const aName : wvstring; + var aValue : wvstring): boolean; +var + TempValue : wvstring; +begin + TempValue := GetEnvironmentVariable(aName); + + if (TempValue <> '') then + begin + aValue := TempValue; + Result := True; + end + else + Result := False; +end; + +function GetAppUserModelIdForCurrentProcess(var idOut: wvstring): HRESULT; +type + GetCurrentApplicationUserModelIdProc = function(var applicationUserModelIdLength: Cardinal; applicationUserModelId: PWideChar): HRESULT; stdcall; + GetCurrentProcessExplicitAppUserModelIDProc = function(var AppID: LPWSTR): HRESULT; stdcall; +var + LGetCurrentApplicationUserModelId : GetCurrentApplicationUserModelIdProc; + LGetCurrentProcessExplicitAppUserModelID : GetCurrentProcessExplicitAppUserModelIDProc; + TempLen : Cardinal; + TempAppID : PWideChar; +begin + Result := E_NOTIMPL; + idOut := ''; + + // GetCurrentApplicationUserModelId is only available in Windows 8 or newer + if (Win32MajorVersion > 6) or + ((Win32MajorVersion = 6) and (Win32MinorVersion >= 2)) then + begin + LGetCurrentApplicationUserModelId := GetProcAddress(GetModuleHandleW('Kernel32.dll'), 'GetCurrentApplicationUserModelId'); + TempLen := 0; + + if assigned(LGetCurrentApplicationUserModelId) and + (LGetCurrentApplicationUserModelId(TempLen, nil) = ERROR_INSUFFICIENT_BUFFER) then + begin + SetLength(idOut, TempLen); + if (LGetCurrentApplicationUserModelId(TempLen, PWideChar(idOut)) = ERROR_SUCCESS) then + begin + idOut := trim(idOut); + Result := S_OK; + exit; + end; + end; + end; + + // GetCurrentProcessExplicitAppUserModelID is only available in Windows 7 or newer + if (Win32MajorVersion > 6) or + ((Win32MajorVersion = 6) and (Win32MinorVersion >= 1)) then + begin + LGetCurrentProcessExplicitAppUserModelID := GetProcAddress(GetModuleHandleW('shell32.dll'), 'GetCurrentProcessExplicitAppUserModelID'); + TempLen := 0; + + if assigned(LGetCurrentProcessExplicitAppUserModelID) then + begin + TempAppID := nil; + Result := LGetCurrentProcessExplicitAppUserModelID(TempAppID); + + if succeeded(Result) then + idOut := TempAppID; + + if assigned(TempAppID) then + CoTaskMemFree(TempAppID); + end; + end; +end; + +function GetModulePath(h: HModule; var outPath: wvstring): HRESULT; +const + CUSTOM_MAX_PATH = $1000; +var + TempLen : Cardinal; +begin + SetLength(outPath, MAX_PATH); + TempLen := GetModuleFileNameW(h, PWideChar(outPath), MAX_PATH); + + if (GetLastError() = ERROR_INSUFFICIENT_BUFFER) then + begin + SetLength(outPath, CUSTOM_MAX_PATH); + TempLen := GetModuleFileNameW(h, PWideChar(outPath), CUSTOM_MAX_PATH); + end; + + if (TempLen = 0) or (TempLen > CUSTOM_MAX_PATH) then + Result := HResultFromWin32(GetLastError()) + else + begin + Result := S_OK; + outPath := copy(outPath, 1, TempLen); + end; +end; + +var + gShouldCheckPolicyOverride : boolean = True; + gShouldCheckRegistryOverride : boolean = True; + +function ReadOverrideFromRegistry(const aKey : wvstring; + aRootKey : HKEY; + const aValue : wvstring; + var aResult : boolean; + aRedist : boolean): boolean; overload; +var + TempKey : wvstring; + TempReg : TRegistry; +begin + Result := False; + TempReg := nil; + + try + try + if (aKey <> '') then + begin + TempReg := TRegistry.Create(KEY_READ); + TempReg.RootKey := aRootKey; + + if aRedist then + TempKey := 'Software\Policies\Microsoft\Edge\WebView2\' + aKey + else + TempKey := 'Software\Policies\Microsoft\EmbeddedBrowserWebView\LoaderOverride\' + aKey; + + if TempReg.KeyExists(TempKey) and + TempReg.OpenKey(TempKey, False) then + begin + gShouldCheckRegistryOverride := True; + + case TempReg.GetDataType(aValue) of + rdInteger : + begin + aResult := TempReg.ReadInteger(aValue) = 1; + Result := True; + end; + + rdString : + begin + aResult := TempReg.ReadString(aValue) = '1'; + Result := True; + end; + end; + end; + end; + except + on e : exception do + if CustomExceptionHandler('ReadOverrideFromRegistry', e) then raise; + end; + finally + if assigned(TempReg) then FreeAndNil(TempReg); + end; +end; + +function ReadOverrideFromRegistry(const aKey : wvstring; + aRootKey : HKEY; + const aValue : wvstring; + var aResult : wvstring; + aRedist : boolean): boolean; overload; +var + TempKey : wvstring; + TempReg : TRegistry; +begin + Result := False; + TempReg := nil; + + try + try + if (aKey <> '') then + begin + TempReg := TRegistry.Create(KEY_READ); + TempReg.RootKey := aRootKey; + + if aRedist then + TempKey := 'Software\Policies\Microsoft\Edge\WebView2\' + aKey + else + TempKey := 'Software\Policies\Microsoft\EmbeddedBrowserWebView\LoaderOverride\' + aKey; + + if TempReg.KeyExists(TempKey) and + TempReg.OpenKey(TempKey, False) then + begin + gShouldCheckRegistryOverride := True; + + if (TempReg.GetDataType(aValue) = rdString) then + begin + aResult := TempReg.ReadString(aValue); + Result := (aResult <> ''); + end; + end; + end; + except + on e : exception do + if CustomExceptionHandler('ReadOverrideFromRegistry', e) then raise; + end; + finally + if assigned(TempReg) then FreeAndNil(TempReg); + end; +end; + +function UpdateParamsWithRegOverrides(const aKey : wvstring; + aRootKey : HKEY; + var aResult : boolean; + aRedist : boolean): boolean; overload; +var + TempExe, TempID, TempPath: wvstring; +begin + Result := False; + GetAppUserModelIdForCurrentProcess(TempID); + + if succeeded(GetModulePath(0, TempPath)) then + TempExe := ExtractFileName(TempPath) + else + TempExe := ''; + + if gShouldCheckPolicyOverride and aRedist then + begin + if ReadOverrideFromRegistry(aKey, aRootKey, TempID, aResult, aRedist) or + ReadOverrideFromRegistry(aKey, aRootKey, TempExe, aResult, aRedist) or + ReadOverrideFromRegistry(aKey, aRootKey, '*', aResult, aRedist) then + Result := True; + end + else + if ReadOverrideFromRegistry(TempID, aRootKey, aKey, aResult, aRedist) or + ReadOverrideFromRegistry(TempExe, aRootKey, aKey, aResult, aRedist) or + ReadOverrideFromRegistry('*', aRootKey, aKey, aResult, aRedist) then + Result := True; +end; + +function UpdateParamsWithRegOverrides(const aKey : wvstring; + aRootKey : HKEY; + var aResult : wvstring; + aRedist : boolean): boolean; overload; +var + TempExe, TempID, TempPath: wvstring; +begin + Result := False; + GetAppUserModelIdForCurrentProcess(TempID); + + if succeeded(GetModulePath(0, TempPath)) then + TempExe := ExtractFileName(TempPath) + else + TempExe := ''; + + if gShouldCheckPolicyOverride and aRedist then + begin + if ReadOverrideFromRegistry(aKey, aRootKey, TempID, aResult, aRedist) or + ReadOverrideFromRegistry(aKey, aRootKey, TempExe, aResult, aRedist) or + ReadOverrideFromRegistry(aKey, aRootKey, '*', aResult, aRedist) then + Result := True; + end + else + if ReadOverrideFromRegistry(TempID, aRootKey, aKey, aResult, aRedist) or + ReadOverrideFromRegistry(TempExe, aRootKey, aKey, aResult, aRedist) or + ReadOverrideFromRegistry('*', aRootKey, aKey, aResult, aRedist) then + Result := True; +end; + +function UpdateParamsWithOverrides(const env : wvstring; + const key : wvstring; + var ret : boolean; + checkOverride : boolean): boolean; overload; +var + outStr: wvstring; +begin + if checkOverride then + begin + gShouldCheckPolicyOverride := True; + gShouldCheckRegistryOverride := True; + end; + + if ReadEnvironmentVariable(env, outStr) then + Result := True + else + if not(gShouldCheckRegistryOverride) and + not(gShouldCheckPolicyOverride) and + not(checkOverride) then + Result := False + else + begin + gShouldCheckRegistryOverride := False; + gShouldCheckPolicyOverride := DoesPolicyExistInRoot(HKEY_CURRENT_USER) or + DoesPolicyExistInRoot(HKEY_LOCAL_MACHINE); + + Result := UpdateParamsWithRegOverrides(key, HKEY_LOCAL_MACHINE, outStr, True) or + UpdateParamsWithRegOverrides(key, HKEY_CURRENT_USER, outStr, True) or + UpdateParamsWithRegOverrides(key, HKEY_LOCAL_MACHINE, outStr, False) or + UpdateParamsWithRegOverrides(key, HKEY_CURRENT_USER, outStr, False); + end; +end; + +function UpdateParamsWithOverrides(const env : wvstring; + const key : wvstring; + var outStr : wvstring; + checkOverride : boolean): boolean; overload; +begin + if checkOverride then + begin + gShouldCheckPolicyOverride := True; + gShouldCheckRegistryOverride := True; + end; + + if ReadEnvironmentVariable(env, outStr) then + Result := True + else + if not(gShouldCheckRegistryOverride) and + not(gShouldCheckPolicyOverride) and + not(checkOverride) then + Result := False + else + begin + gShouldCheckRegistryOverride := False; + gShouldCheckPolicyOverride := DoesPolicyExistInRoot(HKEY_CURRENT_USER) or + DoesPolicyExistInRoot(HKEY_LOCAL_MACHINE); + + Result := UpdateParamsWithRegOverrides(key, HKEY_LOCAL_MACHINE, outStr, True) or + UpdateParamsWithRegOverrides(key, HKEY_CURRENT_USER, outStr, True) or + UpdateParamsWithRegOverrides(key, HKEY_LOCAL_MACHINE, outStr, False) or + UpdateParamsWithRegOverrides(key, HKEY_CURRENT_USER, outStr, False); + end; +end; + +procedure UpdateWebViewEnvironmentParamsWithOverrideValues(var aParams : TWebView2EnvironmentParams); +begin + UpdateParamsWithOverrides('WEBVIEW2_BROWSER_EXECUTABLE_FOLDER', + 'browserExecutableFolder', + aParams.embeddedEdgeSubFolder, + True); + + UpdateParamsWithOverrides('WEBVIEW2_USER_DATA_FOLDER', + 'userDataFolder', + aParams.userDataDir, + True); + + UpdateParamsWithOverrides('WEBVIEW2_RELEASE_CHANNEL_PREFERENCE', + 'releaseChannelPreference', + boolean(aParams.releaseChannelPreference), + True); +end; + +const + kChannelUuid: array [0 .. 4] of wvstring = ('{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}', + '{2CD8A007-E189-409D-A2C8-9AF4EF3C72AA}', + '{0D50BFEC-CD6A-4F9A-964C-C7416E3ACB10}', + '{65C35B14-6C1D-4122-AC46-7148CC9D6497}', + '{BE59E8FD-089A-411B-A3B0-051D9E417818}'); + +procedure GetInstallKeyPathForChannel(channel: Cardinal; var outRegistryKey: wvstring); +begin + outRegistryKey := 'Software\Microsoft\EdgeUpdate\ClientState\' + kChannelUuid[channel]; +end; + +procedure GetInstallKeyPathForChannel2(channel: Cardinal; var outRegistryKey: wvstring); +begin + outRegistryKey := 'Software\WOW6432Node\Microsoft\EdgeUpdate\ClientState\' + kChannelUuid[channel]; +end; + +type + TVersionRec = array [0 .. 3] of Cardinal; + +function ParseVersionNumbers(s: wvstring; var o: TVersionRec): boolean; +var + i: integer; + E: integer; + t: wvstring; +begin + Result := False; + + for i := 0 to 3 do + begin + if (s = '') then exit; + + val(s, o[i], E); + + if (E = 0) then + begin + t := s; + s := ''; + end + else + begin + t := copy(s, 1, E - 1); + s := copy(s, E + 1, length(s)); + end; + + val(t, o[i], E); + end; + + Result := True; +end; + +function FindClientDllInFolder(var folder: wvstring): boolean; +const +{$IFDEF WIN64} + EMBEDDED_WEBVIEW_PATH = 'EBWebView\x64\EmbeddedBrowserWebView.dll'; +{$ELSE} + {$IFDEF CPUARM64} + EMBEDDED_WEBVIEW_PATH = 'EBWebView\arm64\EmbeddedBrowserWebView.dll'; + {$ELSE} + EMBEDDED_WEBVIEW_PATH = 'EBWebView\x86\EmbeddedBrowserWebView.dll'; + {$ENDIF} +{$ENDIF} +begin + folder := IncludeTrailingPathDelimiter(folder) + EMBEDDED_WEBVIEW_PATH; + Result := FileExists(folder); +end; + +function CheckVersionAndFindClientDllInFolder(const version: TVersionRec; var path: wvstring): boolean; +const + kMinimumCompatibleVersion: array [0 .. 3] of Cardinal = (86, 0, 616, 0); +var + i: integer; +begin + Result := False; + + for i := 0 to 3 do + if (version[i] < kMinimumCompatibleVersion[i]) then + exit + else + if (version[i] > kMinimumCompatibleVersion[i]) then + break; + + Result := FindClientDllInFolder(path); +end; + +function FindInstalledClientDllForChannel(const aSubKey : wvstring; + aSystem : boolean; + var aVersion : wvstring; + var aClientPath : wvstring): boolean; +var + TempReg : TRegistry; + TempVer : TVersionRec; +begin + Result := False; + TempReg := nil; + + try + try + TempReg := TRegistry.Create(KEY_READ); + + if aSystem then + TempReg.RootKey := HKEY_LOCAL_MACHINE + else + TempReg.RootKey := HKEY_CURRENT_USER; + + if TempReg.KeyExists(aSubKey) and + TempReg.OpenKey(aSubKey, False) then + begin + aClientPath := {$IFDEF FPC}UTF8Decode({$ENDIF}TempReg.ReadString('EBWebView'){$IFDEF FPC}){$ENDIF}; + + if (aClientPath <> '') then + begin + aVersion := ExtractFileName(aClientPath); + + if ParseVersionNumbers(aVersion, TempVer) then + Result := CheckVersionAndFindClientDllInFolder(TempVer, aClientPath); + end; + end; + except + on e : exception do + if CustomExceptionHandler('FindInstalledClientDllForChannel', e) then raise; + end; + finally + if assigned(TempReg) then FreeAndNil(TempReg); + end; +end; + +type + TGetCurrentPackageInfoProc = function(flags: Cardinal; var bufferlength: Cardinal; buffer: pointer; var count: Cardinal): HRESULT; + + TPACKAGE_VERSION = record + case integer of + 0: (version: UInt64); + 1: (Revision, Build, Minor, Major: Word) + end; + + TPACKAGE_ID = record + reserved, processorArchitecture: Cardinal; + version: TPACKAGE_VERSION; + name, publisher, resourceId, publisherId: PWideChar; + end; + + TPACKAGE_INFO = record + reserved, flags: Cardinal; + path, packageFullName, packageFamilyName: PWideChar; + packageId: TPACKAGE_ID; + end; + PPACKAGE_INFO = ^TPACKAGE_INFO; + +const + kChannelPackageFamilyName: array [0 .. 4] of wvstring = + ('Microsoft.WebView2Runtime.Stable_8wekyb3d8bbwe', + 'Microsoft.WebView2Runtime.Beta_8wekyb3d8bbwe', + 'Microsoft.WebView2Runtime.Dev_8wekyb3d8bbwe', + 'Microsoft.WebView2Runtime.Canary_8wekyb3d8bbwe', + 'Microsoft.WebView2Runtime.Internal_8wekyb3d8bbwe'); + + kChannelName: array [0 .. 4] of wvstring = ('', 'beta', 'dev', 'canary', 'internal'); + +function FindInstalledClientDll(var clientPath : wvstring; + preference : TWebView2ReleaseChannelPreference; + var versionStr : wvstring; + var channelStr : wvstring): integer; +const + APPMODEL_ERROR_NO_PACKAGE = $00003D54; +var + channel: Cardinal; + lpSubKey: wvstring; + version: TVersionRec; + pkBuf: array of byte; + i, j: integer; + len, cPackages: Cardinal; + packages, package: PPACKAGE_INFO; + GetCurrentPackageInfo: TGetCurrentPackageInfoProc; + TempResult : integer; +begin + // GetCurrentPackageInfo is only available in Windows 8 or newer + if (Win32MajorVersion > 6) or + ((Win32MajorVersion = 6) and (Win32MinorVersion >= 2)) then + GetCurrentPackageInfo := TGetCurrentPackageInfoProc(GetProcAddress(GetModuleHandleW('kernelbase.dll'), 'GetCurrentPackageInfo')) + else + GetCurrentPackageInfo := nil; + + for i := 0 to 4 do + begin + if (preference = kCanary) then + channel := 4 - i + else + channel := i; + + GetInstallKeyPathForChannel(channel, lpSubKey); + + if FindInstalledClientDllForChannel(lpSubKey, False, versionStr, clientPath) then + break; + + if FindInstalledClientDllForChannel(lpSubKey, True, versionStr, clientPath) then + break; + + GetInstallKeyPathForChannel2(channel, lpSubKey); + + if FindInstalledClientDllForChannel(lpSubKey, False, versionStr, clientPath) then + break; + + if FindInstalledClientDllForChannel(lpSubKey, True, versionStr, clientPath) then + break; + + if not assigned(GetCurrentPackageInfo) then + continue; + + len := 0; + TempResult := GetCurrentPackageInfo(1, len, nil, cPackages); + if (TempResult = APPMODEL_ERROR_NO_PACKAGE) then + begin + Result := E_FAIL; + exit; + end; + + if (TempResult <> ERROR_INSUFFICIENT_BUFFER) or (len = 0) then + continue; + + SetLength(pkBuf, len); + if (GetCurrentPackageInfo(1, len, @pkBuf[0], cPackages) <> 0) or (cPackages = 0) then + continue; + + packages := PPACKAGE_INFO(pkBuf); + package := nil; + + for j := 0 to cPackages - 1 do + begin + if (UpperCase(packages.packageFamilyName) = UpperCase(kChannelPackageFamilyName[j])) then + begin + package := packages; + break; + end; + + inc(packages); + end; + + if (package = nil) then + continue; + + version[0] := package.packageId.version.Major; + version[1] := package.packageId.version.Minor; + version[2] := package.packageId.version.Build; + version[3] := package.packageId.version.Revision; + clientPath := package.path; + + if CheckVersionAndFindClientDllInFolder(version, clientPath) then + begin + versionStr := {$IFDEF FPC}UTF8Decode({$ENDIF}format('%d.%d.%d.%d', [version[0], version[1], version[2], version[3]]){$IFDEF FPC}){$ENDIF}; + break; + end; + end; + + channelStr := kChannelName[channel]; + Result := S_OK; +end; + +function FindEmbeddedClientDll(const embeddedEdgeSubFolder : wvstring; + var outClientPath : wvstring): HRESULT; +var + TempPath : wvstring; +begin + Result := S_OK; + outClientPath := embeddedEdgeSubFolder; + + if (Length(outClientPath) >= 3) and + ((DWORD(outClientPath[1]) and $FFDF) - Ord('A') < $1A) and + (outClientPath[2] = ':') and + (outClientPath[3] = '\') then + begin + if not(FindClientDllInFolder(outClientPath)) then + Result := HResultFromWin32(ERROR_FILE_NOT_FOUND); + end + else + if (Length(outClientPath) < 3) or + (outClientPath[2] = ':') or + (outClientPath[1] <> '\') or + (outClientPath[2] <> '\') then + begin + Result := GetModulePath(0, TempPath); + if (Result < 0) then exit; + + outClientPath := IncludeTrailingPathDelimiter(TempPath) + embeddedEdgeSubFolder; + + if not(FindClientDllInFolder(outClientPath)) then + Result := HResultFromWin32(ERROR_FILE_NOT_FOUND); + end + else + if not(FindClientDllInFolder(outClientPath)) then + Result := HResultFromWin32(ERROR_FILE_NOT_FOUND); +end; + +type + TWebView2RunTimeType = (kInstalled = 0, kRedistributable = 1); + + TCreateWebViewEnvironmentWithOptionsInternal = function(a: boolean; b: TWebView2RunTimeType; c: PWideChar; d: System.IUnKnown; E: ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler): HRESULT; stdcall; + TDllCanUnloadNow = function: HRESULT; stdcall; + +function CreateWebViewEnvironmentWithClientDll( lplibfilename : wvstring; + unknown : boolean; + runtimeType : TWebView2RunTimeType; + unknown2 : PWideChar; + const unknown3 : System.IUnKnown; + envCompletedHandler : ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler): HRESULT; +var + clientDLL : HModule; + createProc : TCreateWebViewEnvironmentWithOptionsInternal; + canUnLoadProc : TDllCanUnloadNow; +begin + clientDLL := LoadLibraryW(PWideChar(lplibfilename)); + + if (clientDLL = 0) then + begin + Result := HResultFromWin32(GetLastError); + exit; + end; + + createProc := GetProcAddress(clientDLL, 'CreateWebViewEnvironmentWithOptionsInternal'); // Undocumented function + canUnLoadProc := GetProcAddress(clientDLL, 'DllCanUnloadNow'); + + if not(assigned(createProc)) then + begin + Result := HResultFromWin32(GetLastError); + exit; + end; + + Result := createProc(unknown, runtimeType, unknown2, unknown3, envCompletedHandler); + + if assigned(canUnLoadProc) and (canUnLoadProc() = 0) then + FreeLibrary(clientDLL); +end; + +type + TEnvironmentCreatedRetryHandler = class(TInterfacedObject, ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) + private + mEnvironmentParams : TWebView2EnvironmentParams; + mOriginalHandler : ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler; + mRetries : integer; + public + constructor Create(environmentParams: TWebView2EnvironmentParams; const originalHandler: ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler; retries: integer); + function Invoke(ret: HRESULT; const created_environment: ICoreWebView2Environment): HRESULT; stdcall; + end; + +function TryCreateWebViewEnvironment( aParams : TWebView2EnvironmentParams; + const aEnvironmentCreatedHandler : ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler): HRESULT; +var + runtimeType: TWebView2RunTimeType; + dllPath, v, c: wvstring; +begin + if (aParams.embeddedEdgeSubFolder <> '') then + begin + runtimeType := kRedistributable; + Result := FindEmbeddedClientDll(aParams.embeddedEdgeSubFolder, dllPath); + end + else + begin + runtimeType := kInstalled; + Result := FindInstalledClientDll(dllPath, aParams.releaseChannelPreference, v, c); + end; + + if succeeded(Result) then + Result := CreateWebViewEnvironmentWithClientDll(dllPath, + True, + runtimeType, + PWideChar(aParams.userDataDir), + aParams.environmentOptions as System.IUnKnown, + aEnvironmentCreatedHandler); +end; + +function Internal_CreateCoreWebView2EnvironmentWithOptions( browserExecutableFolder : LPCWSTR; + userDataFolder : LPCWSTR; + const environmentOptions : ICoreWebView2EnvironmentOptions; + const environment_created_handler : ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler): HRESULT; stdcall; +var + TempParams : TWebView2EnvironmentParams; + TempHandler : ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler; +begin + if assigned(environment_created_handler) then + begin + TempParams.embeddedEdgeSubFolder := browserExecutableFolder; + TempParams.userDataDir := userDataFolder; + TempParams.environmentOptions := environmentOptions; + TempParams.releaseChannelPreference := kStable; + + UpdateWebViewEnvironmentParamsWithOverrideValues(TempParams); + + try + TempHandler := TEnvironmentCreatedRetryHandler.Create(TempParams, environment_created_handler, 1); + Result := TryCreateWebViewEnvironment(TempParams, TempHandler); + finally + TempHandler := nil; + end; + end + else + Result := E_POINTER; +end; + +function Internal_CreateCoreWebView2Environment(const environment_created_handler: ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler): HRESULT; stdcall; +begin + Result := Internal_CreateCoreWebView2EnvironmentWithOptions(nil, nil, nil, environment_created_handler); +end; + +function FindEmbeddedBrowserVersion(const aFilename: wvstring; var aVersion: wvstring): HRESULT; +var + TempBlockSize : cardinal; + TempHandle : cardinal; + TempBlock : pointer; + TempBuffer : pointer; + TempBufferSize : cardinal; + TempSubBlock : wvstring; +begin + TempBuffer := nil; + TempHandle := 0; + TempBlockSize := GetFileVersionInfoSizeW(PWideChar(aFilename), TempHandle); + + if TempBlockSize = 0 then + Result := HResultFromWin32(GetLastError) + else + begin + GetMem(TempBlock, TempBlockSize); + + try + TempSubBlock := '\StringFileInfo\040904B0\ProductVersion'; + + if not(GetFileVersionInfoW(PWideChar(aFilename), TempHandle, TempBlockSize, TempBlock)) or + not(VerQueryValueW(TempBlock, PWideChar(TempSubBlock), TempBuffer, TempBufferSize)) or + not(assigned(TempBuffer)) then + Result := HResultFromWin32(GetLastError) + else + begin + aVersion := PWideChar(TempBuffer); + Result := S_OK; + end; + finally + FreeMem(TempBlock); + end; + end; +end; + +function Internal_GetAvailableCoreWebView2BrowserVersionString(browserExecutableFolder: LPCWSTR; pVersionInfo: PLPWSTR): HRESULT; stdcall; +var + TempParams : TWebView2EnvironmentParams; + hr: HRESULT; + TempChannelStr, TempVersionStr, TempClientPath: wvstring; + TempSize : integer; +begin + if (pVersionInfo = nil) then + begin + Result := E_POINTER; + exit; + end; + + TempParams.embeddedEdgeSubFolder := browserExecutableFolder; + TempParams.userDataDir := ''; + TempParams.environmentOptions := nil; + TempParams.releaseChannelPreference := kStable; + + UpdateWebViewEnvironmentParamsWithOverrideValues(TempParams); + + if (TempParams.embeddedEdgeSubFolder <> '') then + begin + hr := FindEmbeddedClientDll(TempParams.embeddedEdgeSubFolder, TempClientPath); + + if (hr < 0) then + begin + pVersionInfo^ := nil; + Result := hr; + exit; + end; + + hr := FindEmbeddedBrowserVersion(TempClientPath, TempVersionStr); + end + else + hr := FindInstalledClientDll(TempClientPath, TempParams.releaseChannelPreference, TempVersionStr, TempChannelStr); + + if (hr < 0) then + begin + pVersionInfo^ := nil; + Result := hr; + exit; + end; + + if (TempVersionStr <> '') then + begin + if (TempChannelStr <> '') then + TempVersionStr := TempVersionStr + ' ' + TempChannelStr; + + TempVersionStr := TempVersionStr + #0; + TempSize := Length(TempVersionStr) * SizeOf(WideChar); + + pVersionInfo^ := CoTaskMemAlloc(TempSize); + move(TempVersionStr[1], pVersionInfo^^, TempSize); + Result := S_OK; + end + else + Result := E_FAIL; +end; + +function Internal_GetAvailableCoreWebView2BrowserVersionStringWithOptions(browserExecutableFolder: LPCWSTR; const environmentOptions: ICoreWebView2EnvironmentOptions; pVersionInfo: PLPWSTR): HRESULT; stdcall; +begin + // TO-DO: Implement GetAvailableCoreWebView2BrowserVersionStringWithOptions + Result := E_NOTIMPL; +end; + +function Internal_CompareBrowserVersions(version1, version2: LPCWSTR; pRet: PInteger): HRESULT; stdcall; +var + TempVersion1, TempVersion2: TVersionRec; + i: integer; +begin + if (pRet = nil) then + Result := E_POINTER + else + if (version1 = nil) or + (version2 = nil) or + not(ParseVersionNumbers(version1, TempVersion1)) or + not(ParseVersionNumbers(version2, TempVersion2)) then + Result := E_INVALIDARG + else + begin + Result := S_OK; + + for i := 0 to 3 do + if (TempVersion2[i] < TempVersion1[i]) then + begin + pRet^ := 1; + exit; + end + else + if (TempVersion2[i] > TempVersion1[i]) then + begin + pRet^ := -1; + exit; + end; + + pRet^ := 0; + end; +end; + +{ TEnvironmentCreatedRetryHandler } + +constructor TEnvironmentCreatedRetryHandler.Create( environmentParams : TWebView2EnvironmentParams; + const originalHandler : ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler; + retries : integer); +begin + inherited Create; + + mEnvironmentParams := environmentParams; + mOriginalHandler := originalHandler; + mRetries := retries; +end; + +function TEnvironmentCreatedRetryHandler.Invoke; +begin + if (ret >= 0) or (mRetries <= 0) then + begin + if assigned(created_environment) and assigned(mOriginalHandler) then + mOriginalHandler.Invoke(S_OK, created_environment); + end + else + begin + dec(mRetries); + ret := TryCreateWebViewEnvironment(mEnvironmentParams, self); + + if (ret < 0) then + mOriginalHandler.Invoke(ret, nil); + end; + + Result := S_OK; +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVMiscFunctions.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVMiscFunctions.pas new file mode 100644 index 000000000..80df2f9d3 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVMiscFunctions.pas @@ -0,0 +1,740 @@ +unit uRESTDWPrivWVMiscFunctions; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + Winapi.Windows, System.Classes, System.UITypes, Winapi.ActiveX, System.SysUtils, System.StrUtils, + {$ELSE} + Windows, Classes, ActiveX, SysUtils, Graphics, Controls, StrUtils, + {$ENDIF} + uRESTDWPrivWVConstants, uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVTypes; + +const + SHLWAPIDLL = 'shlwapi.dll'; + +function AllocCoTaskMemStr(const aString : wvstring): PWideChar; +function LowestChromiumVersion : wvstring; +function LowestLoaderDLLVersion : wvstring; +function EnvironmentCreationErrorToString(aErrorCode : HRESULT) : wvstring; +function ControllerCreationErrorToString(aErrorCode : HRESULT) : wvstring; +function ControllerOptionsCreationErrorToString(aErrorCode : HRESULT) : wvstring; +function CompositionControllerCreationErrorToString(aErrorCode : HRESULT) : wvstring; +function GetScreenDPI : integer; +function GetDeviceScaleFactor : single; +function EditingCommandToString(aEditingCommand : TWV2EditingCommand): wvstring; +function DeleteDirContents(const aDirectory : string; const aExcludeFiles : TStringList = nil) : boolean; +function SystemCursorIDToDelphiCursor(aSystemCursorID : cardinal) : TCursor; +function LoggedQueryInterface(const aBaseIntf: IInterface; const aGUID: TGUID; out Obj): boolean; + +procedure OutputDebugMessage(const aMessage : string); +function CustomExceptionHandler(const aFunctionName : string; const aException : exception) : boolean; +procedure LogMouseEvent(aEventKind : TWVMouseEventKind; aVirtualKeys : TWVMouseEventVirtualKeys; aMouseData : cardinal; aPoint : TPoint); + +function CoreWebViewColorToDelphiColor(const aColor : COREWEBVIEW2_COLOR) : TColor; +function DelphiColorToCoreWebViewColor(const aColor : TColor) : COREWEBVIEW2_COLOR; + +function TryIso8601BasicToDate(const Str: string; out Date: TDateTime): Boolean; +function JSONUnescape(const Source: wvstring): wvstring; +function JSONEscape(const Source: wvstring): wvstring; +function CustomURLDecode(const aEncodedStr : wvstring) : AnsiString; + +function CustomPathIsRelative(const aPath : wvstring) : boolean; +function CustomPathCanonicalize(const aOriginalPath : wvstring; var aCanonicalPath : wvstring) : boolean; +function CustomAbsolutePath(const aPath : wvstring; aMustExist : boolean = False) : wvstring; +function CustomPathIsURL(const aPath : wvstring) : boolean; +function CustomPathIsUNC(const aPath : wvstring) : boolean; +function GetModulePath : wvstring; +function EscapeCommandLineParameter(const aParameter : wvstring) : wvstring; + +function PathIsRelativeAnsi(pszPath: LPCSTR): BOOL; stdcall; external SHLWAPIDLL name 'PathIsRelativeA'; +function PathIsRelativeUnicode(pszPath: LPCWSTR): BOOL; stdcall; external SHLWAPIDLL name 'PathIsRelativeW'; +function PathCanonicalizeAnsi(pszBuf: LPSTR; pszPath: LPCSTR): BOOL; stdcall; external SHLWAPIDLL name 'PathCanonicalizeA'; +function PathCanonicalizeUnicode(pszBuf: LPWSTR; pszPath: LPCWSTR): BOOL; stdcall; external SHLWAPIDLL name 'PathCanonicalizeW'; +function PathIsUNCAnsi(pszPath: LPCSTR): BOOL; stdcall; external SHLWAPIDLL name 'PathIsUNCA'; +function PathIsUNCUnicode(pszPath: LPCWSTR): BOOL; stdcall; external SHLWAPIDLL name 'PathIsUNCW'; +function PathIsURLAnsi(pszPath: LPCSTR): BOOL; stdcall; external SHLWAPIDLL name 'PathIsURLA'; +function PathIsURLUnicode(pszPath: LPCWSTR): BOOL; stdcall; external SHLWAPIDLL name 'PathIsURLW'; + +{$IFNDEF DELPHI12_UP} +const + GWLP_WNDPROC = GWL_WNDPROC; + GWLP_HWNDPARENT = GWL_HWNDPARENT; + {$IFDEF WIN64} + function SetWindowLongPtr(hWnd: HWND; nIndex: Integer; dwNewLong: int64): int64; stdcall; external user32 name 'SetWindowLongPtrW'; + {$ELSE} + function SetWindowLongPtr(hWnd: HWND; nIndex: Integer; dwNewLong: LongInt): LongInt; stdcall; external user32 name 'SetWindowLongW'; + {$ENDIF} +{$ENDIF} + +{$IFNDEF FPC}{$IFNDEF DELPHI7_UP} +function PosEx(const SubStr, S: string; Offset: Cardinal = 1): Integer; +{$ENDIF}{$ENDIF} + +implementation + +uses + uRESTDWPrivWVLoader; + +function AllocCoTaskMemStr(const aString : wvstring): PWideChar; +var + TempLen : integer; + TempString : wvstring; +begin + TempLen := Length(aString); + + if (TempLen > 0) then + begin + TempLen := succ(TempLen) * SizeOf(WideChar); + TempString := aString + #0; + Result := CoTaskMemAlloc(TempLen); + + Move(TempString[1], Result^, TempLen); + end + else + Result := nil; +end; + +function LowestChromiumVersion : wvstring; +begin + Result := wvstring(inttostr(CHROMIUM_VERSION_MAJOR) + '.' + + inttostr(CHROMIUM_VERSION_MINOR) + '.' + + inttostr(CHROMIUM_VERSION_RELEASE) + '.' + + inttostr(CHROMIUM_VERSION_BUILD)); +end; + +function LowestLoaderDLLVersion : wvstring; +begin + Result := wvstring(inttostr(WEBVIEW2LOADERLIB_VERSION_MAJOR) + '.' + + inttostr(WEBVIEW2LOADERLIB_VERSION_MINOR) + '.' + + inttostr(WEBVIEW2LOADERLIB_VERSION_RELEASE) + '.' + + inttostr(WEBVIEW2LOADERLIB_VERSION_BUILD)); +end; + +function EnvironmentCreationErrorToString(aErrorCode : HRESULT) : wvstring; +const + // Undefined GetLastError error values + ERROR_INVALID_STATE = 5023; + ERROR_PRODUCT_UNINSTALLED = 1614; +begin + case aErrorCode of + CO_E_NOTINITIALIZED : Result := 'CoInitializeEx was not called.'; + RPC_E_CHANGED_MODE : Result := 'CoInitializeEx was previously called with COINIT_MULTITHREADED.'; + E_ACCESSDENIED : Result := 'Unable to create user data folder, Access Denied.'; + E_FAIL : Result := 'Edge runtime unable to start.'; + else + if (aErrorCode = HResultFromWin32(ERROR_NOT_SUPPORTED)) then + Result := '\Edge\Application path used in browserExecutableFolder.' + else + if (aErrorCode = HResultFromWin32(ERROR_INVALID_STATE)) then + Result := 'Specified options do not match the options of the WebViews that are currently running in the shared browser process.' + else + if (aErrorCode = HResultFromWin32(ERROR_DISK_FULL)) then + Result := 'There are too many previous WebView2 Runtime versions.' + else + if (aErrorCode = HResultFromWin32(ERROR_PRODUCT_UNINSTALLED)) then + Result := 'Webview depends upon an installed WebView2 Runtime version and it is uninstalled.' + else + if (aErrorCode = HResultFromWin32(ERROR_FILE_NOT_FOUND)) then + Result := 'Could not find Edge installation.' + else + if (aErrorCode = HResultFromWin32(ERROR_FILE_EXISTS)) then + Result := 'User data folder cannot be created because a file with the same name already exists.' + else + Result := 'Unexpected error result.'; + end; +end; + +function ControllerCreationErrorToString(aErrorCode : HRESULT) : wvstring; +const + // Undefined GetLastError error values + ERROR_INVALID_STATE = 5023; + ERROR_CORRUPTED_CBS = $0490; +begin + case aErrorCode of + E_ABORT : Result := 'The parent window was destroyed before the controller creation was finished.'; + E_UNEXPECTED : Result := 'The runtime does not have permissions to the user data folder.'; + + else + if (aErrorCode = HResultFromWin32(ERROR_INVALID_STATE)) then + Result := 'Another browser is using the same user data folder.' + else + if (aErrorCode = HResultFromWin32(ERROR_NOT_SUPPORTED)) then + Result := 'The request is not supported.' + else + if (aErrorCode = HResultFromWin32(ERROR_FILE_NOT_FOUND)) then + Result := 'The system cannot find the file specified.' + else + if (aErrorCode = HResultFromWin32(ERROR_CORRUPTED_CBS)) then + Result := 'Not found. A corrupted Component-Based Servicing (CBS) manifest or corrupted system files that prevent Windows from locating necessary update components.' + else + Result := 'Unexpected error result.'; + end; +end; + +function ControllerOptionsCreationErrorToString(aErrorCode : HRESULT) : wvstring; +const + UI_E_WRONG_THREAD = HRESULT($802A000C); +begin + case aErrorCode of + E_INVALIDARG : Result := 'Invalid profile name.'; + E_NOTIMPL : Result := 'Not implemented.'; // This error code is not documented. It's caused by an outdated WebView2 Runtime installation. + UI_E_WRONG_THREAD : Result := 'This method can only be called from the thread that created the object.'; + else Result := 'Unexpected error result.'; + end; +end; + +function CompositionControllerCreationErrorToString(aErrorCode : HRESULT) : wvstring; +const + // Undefined GetLastError error values + ERROR_INVALID_STATE = 5023; +begin + case aErrorCode of + E_ABORT : Result := 'The parent window was destroyed before the composition controller creation was finished.'; + E_UNEXPECTED : Result := 'The runtime does not have permissions to the user data folder.'; + + else + if (aErrorCode = HResultFromWin32(ERROR_INVALID_STATE)) then + Result := 'Another browser is using the same user data folder.' + else + Result := 'Unexpected error result.'; + end; +end; + +function CoreWebViewColorToDelphiColor(const aColor : COREWEBVIEW2_COLOR) : TColor; +begin + Result := (aColor.R or (aColor.G shl 8) or (aColor.B shl 16) or (aColor.A shl 24)); +end; + +function DelphiColorToCoreWebViewColor(const aColor : TColor) : COREWEBVIEW2_COLOR; +begin + Result.R := byte(aColor and $000000FF); + Result.G := byte((aColor and $0000FF00) shr 8); + Result.B := byte((aColor and $00FF0000) shr 16); + Result.A := byte(aColor shr 24); +end; + +function GetScreenDPI : integer; +var + TempDC : HDC; +begin + TempDC := GetDC(0); + Result := GetDeviceCaps(TempDC, LOGPIXELSX); + ReleaseDC(0, TempDC); +end; + +function GetDeviceScaleFactor : single; +begin + Result := GetScreenDPI / USER_DEFAULT_SCREEN_DPI; +end; + +procedure OutputDebugMessage(const aMessage : string); +begin + {$IFDEF DEBUG} + OutputDebugString({$IFDEF DELPHI12_UP}PWideChar{$ELSE}PAnsiChar{$ENDIF}(aMessage + #0)); + {$ENDIF} +end; + +function CustomExceptionHandler(const aFunctionName : string; const aException : exception) : boolean; +begin + OutputDebugMessage(aFunctionName + ' error : ' + aException.message); + + Result := (GlobalWebView2Loader <> nil) and GlobalWebView2Loader.ReRaiseExceptions; +end; + +procedure LogMouseEvent(aEventKind : TWVMouseEventKind; aVirtualKeys : TWVMouseEventVirtualKeys; aMouseData : cardinal; aPoint : TPoint); +begin + OutputDebugMessage('aEventKind: $' + IntToHex(integer(aEventKind), 4) + ', ' + + 'aVirtualKeys: $' + IntToHex(Integer(aVirtualKeys), 2) + ', ' + + 'aMouseData: ' + IntToStr(integer(aMouseData)) + ', ' + + 'aPoint: (' + IntToStr(aPoint.x) + ',' + IntToStr(aPoint.y) + ')'); +end; + +// Basic ISO8601ToDate alternative written by David Heffernan +// https://stackoverflow.com/questions/24108718/is-there-a-delphi-rtl-function-that-can-convert-the-iso-8601-basic-date-format-t +// Use ISO8601ToDate in Delphi XE6 or later versions. +function TryIso8601BasicToDate(const Str: string; out Date: TDateTime): Boolean; +var + Year, Month, Day: Integer; +begin + Assert(Length(Str)=8); + Result := TryStrToInt(Copy(Str, 1, 4), Year); + if not Result then + exit; + Result := TryStrToInt(Copy(Str, 5, 2), Month); + if not Result then + exit; + Result := TryStrToInt(Copy(Str, 7, 2), Day); + if not Result then + exit; + Result := TryEncodeDate(Year, Month, Day, Date); +end; + +// This function is a modified version of the JSONUnescape function created by Olvin Roght in stackoverflow : +// https://stackoverflow.com/questions/9713491/delphi-decode-json-utf8-escaped-text +function JSONUnescape(const Source: wvstring): wvstring; +const + ESCAPE_CHAR = '\'; + QUOTE_CHAR = '"'; +var + EscapeCharPos, TempPos: Integer; + Temp: string; + IsQuotedString: Boolean; +begin + result := ''; + IsQuotedString := (Source[1] = QUOTE_CHAR) and + (Source[Length(Source)] = QUOTE_CHAR); + EscapeCharPos := Pos(ESCAPE_CHAR, Source); + TempPos := 1; + while EscapeCharPos > 0 do + begin + result := result + Copy(Source, TempPos, EscapeCharPos - TempPos); + TempPos := EscapeCharPos; + if EscapeCharPos < Length(Source) - Integer(IsQuotedString) then + case Source[EscapeCharPos + 1] of + 't': + Temp := #9; + 'n': + Temp := #10; + 'r': + Temp := #13; + '\': + Temp := '\'; + '"': + Temp := '"'; + 'u': + begin + if EscapeCharPos + 4 < Length(Source) - Integer(IsQuotedString) then + Temp := Chr(StrToInt('$' + Copy(Source, EscapeCharPos + 2, 4))); + Inc(TempPos, 4); + end; + end; + Inc(TempPos, 2); + result := result + Temp; + EscapeCharPos := PosEx(ESCAPE_CHAR, Source, TempPos); + end; + result := result + Copy(Source, TempPos, Length(Source) - TempPos + 1); +end; + +function JSONEscape(const Source: wvstring): wvstring; +const + CHAR_DBLQUOTE = #34; + CHAR_BACKWARDSSLASH = #92; + CHAR_FORWARDSSLASH = #47; + CHAR_BACKSPACE = #8; + CHAR_FORMFEED = #12; + CHAR_LINEFEED = #10; + CHAR_CARRIAGERETURN = #13; + CHAR_HORIZONTALTAB = #9; +var + i, TempLen : integer; +begin + Result := ''; + TempLen := length(Source); + i := 1; + + while (i <= TempLen) do + begin + case Source[i] of + CHAR_DBLQUOTE, + CHAR_BACKWARDSSLASH, + CHAR_FORWARDSSLASH : Result := Result + '\' + Source[i]; + CHAR_BACKSPACE : Result := Result + '\b'; + CHAR_FORMFEED : Result := Result + '\f'; + CHAR_LINEFEED : Result := Result + '\n'; + CHAR_CARRIAGERETURN : Result := Result + '\r'; + CHAR_HORIZONTALTAB : Result := Result + '\t'; + + else + if (ord(Source[i]) < 32) or (ord(Source[i]) > 126) then + Result := Result + '\u' + {$IFDEF FPC}UTF8Decode({$ENDIF}IntToHex(ord(Source[i]), 4){$IFDEF FPC}){$ENDIF} + else + Result := Result + Source[i]; + end; + + inc(i); + end; +end; + +function EditingCommandToString(aEditingCommand : TWV2EditingCommand): wvstring; +begin + case aEditingCommand of + ecAlignCenter : Result := 'AlignCenter'; + ecAlignJustified : Result := 'AlignJustified'; + ecAlignLeft : Result := 'AlignLeft'; + ecAlignRight : Result := 'AlignRight'; + ecBackColor : Result := 'BackColor'; + ecBackwardDelete : Result := 'BackwardDelete'; + ecBold : Result := 'Bold'; + ecCopy : Result := 'Copy'; + ecCreateLink : Result := 'CreateLink'; + ecCut : Result := 'Cut'; + ecDefaultParagraphSeparator : Result := 'DefaultParagraphSeparator'; + ecDelete : Result := 'Delete'; + ecDeleteBackward : Result := 'DeleteBackward'; + ecDeleteBackwardByDecomposingPreviousCharacter : Result := 'DeleteBackwardByDecomposingPreviousCharacter'; + ecDeleteForward : Result := 'DeleteForward'; + ecDeleteToBeginningOfLine : Result := 'DeleteToBeginningOfLine'; + ecDeleteToBeginningOfParagraph : Result := 'DeleteToBeginningOfParagraph'; + ecDeleteToEndOfLine : Result := 'DeleteToEndOfLine'; + ecDeleteToEndOfParagraph : Result := 'DeleteToEndOfParagraph'; + ecDeleteToMark : Result := 'DeleteToMark'; + ecDeleteWordBackward : Result := 'DeleteWordBackward'; + ecDeleteWordForward : Result := 'DeleteWordForward'; + ecFindString : Result := 'FindString'; + ecFontName : Result := 'FontName'; + ecFontSize : Result := 'FontSize'; + ecFontSizeDelta : Result := 'FontSizeDelta'; + ecForeColor : Result := 'ForeColor'; + ecFormatBlock : Result := 'FormatBlock'; + ecForwardDelete : Result := 'ForwardDelete'; + ecHiliteColor : Result := 'HiliteColor'; + ecIgnoreSpelling : Result := 'IgnoreSpelling'; + ecIndent : Result := 'Indent'; + ecInsertBacktab : Result := 'InsertBacktab'; + ecInsertHorizontalRule : Result := 'InsertHorizontalRule'; + ecInsertHTML : Result := 'InsertHTML'; + ecInsertImage : Result := 'InsertImage'; + ecInsertLineBreak : Result := 'InsertLineBreak'; + ecInsertNewline : Result := 'InsertNewline'; + ecInsertNewlineInQuotedContent : Result := 'InsertNewlineInQuotedContent'; + ecInsertOrderedList : Result := 'InsertOrderedList'; + ecInsertParagraph : Result := 'InsertParagraph'; + ecInsertTab : Result := 'InsertTab'; + ecInsertText : Result := 'InsertText'; + ecInsertUnorderedList : Result := 'InsertUnorderedList'; + ecItalic : Result := 'Italic'; + ecJustifyCenter : Result := 'JustifyCenter'; + ecJustifyFull : Result := 'JustifyFull'; + ecJustifyLeft : Result := 'JustifyLeft'; + ecJustifyNone : Result := 'JustifyNone'; + ecJustifyRight : Result := 'JustifyRight'; + ecMakeTextWritingDirectionLeftToRight : Result := 'MakeTextWritingDirectionLeftToRight'; + ecMakeTextWritingDirectionNatural : Result := 'MakeTextWritingDirectionNatural'; + ecMakeTextWritingDirectionRightToLeft : Result := 'MakeTextWritingDirectionRightToLeft'; + ecMoveBackward : Result := 'MoveBackward'; + ecMoveBackwardAndModifySelection : Result := 'MoveBackwardAndModifySelection'; + ecMoveDown : Result := 'MoveDown'; + ecMoveDownAndModifySelection : Result := 'MoveDownAndModifySelection'; + ecMoveForward : Result := 'MoveForward'; + ecMoveForwardAndModifySelection : Result := 'MoveForwardAndModifySelection'; + ecMoveLeft : Result := 'MoveLeft'; + ecMoveLeftAndModifySelection : Result := 'MoveLeftAndModifySelection'; + ecMovePageDown : Result := 'MovePageDown'; + ecMovePageDownAndModifySelection : Result := 'MovePageDownAndModifySelection'; + ecMovePageUp : Result := 'MovePageUp'; + ecMovePageUpAndModifySelection : Result := 'MovePageUpAndModifySelection'; + ecMoveParagraphBackward : Result := 'MoveParagraphBackward'; + ecMoveParagraphBackwardAndModifySelection : Result := 'MoveParagraphBackwardAndModifySelection'; + ecMoveParagraphForward : Result := 'MoveParagraphForward'; + ecMoveParagraphForwardAndModifySelection : Result := 'MoveParagraphForwardAndModifySelection'; + ecMoveRight : Result := 'MoveRight'; + ecMoveRightAndModifySelection : Result := 'MoveRightAndModifySelection'; + ecMoveToBeginningOfDocument : Result := 'MoveToBeginningOfDocument'; + ecMoveToBeginningOfDocumentAndModifySelection : Result := 'MoveToBeginningOfDocumentAndModifySelection'; + ecMoveToBeginningOfLine : Result := 'MoveToBeginningOfLine'; + ecMoveToBeginningOfLineAndModifySelection : Result := 'MoveToBeginningOfLineAndModifySelection'; + ecMoveToBeginningOfParagraph : Result := 'MoveToBeginningOfParagraph'; + ecMoveToBeginningOfParagraphAndModifySelection : Result := 'MoveToBeginningOfParagraphAndModifySelection'; + ecMoveToBeginningOfSentence : Result := 'MoveToBeginningOfSentence'; + ecMoveToBeginningOfSentenceAndModifySelection : Result := 'MoveToBeginningOfSentenceAndModifySelection'; + ecMoveToEndOfDocument : Result := 'MoveToEndOfDocument'; + ecMoveToEndOfDocumentAndModifySelection : Result := 'MoveToEndOfDocumentAndModifySelection'; + ecMoveToEndOfLine : Result := 'MoveToEndOfLine'; + ecMoveToEndOfLineAndModifySelection : Result := 'MoveToEndOfLineAndModifySelection'; + ecMoveToEndOfParagraph : Result := 'MoveToEndOfParagraph'; + ecMoveToEndOfParagraphAndModifySelection : Result := 'MoveToEndOfParagraphAndModifySelection'; + ecMoveToEndOfSentence : Result := 'MoveToEndOfSentence'; + ecMoveToEndOfSentenceAndModifySelection : Result := 'MoveToEndOfSentenceAndModifySelection'; + ecMoveToLeftEndOfLine : Result := 'MoveToLeftEndOfLine'; + ecMoveToLeftEndOfLineAndModifySelection : Result := 'MoveToLeftEndOfLineAndModifySelection'; + ecMoveToRightEndOfLine : Result := 'MoveToRightEndOfLine'; + ecMoveToRightEndOfLineAndModifySelection : Result := 'MoveToRightEndOfLineAndModifySelection'; + ecMoveUp : Result := 'MoveUp'; + ecMoveUpAndModifySelection : Result := 'MoveUpAndModifySelection'; + ecMoveWordBackward : Result := 'MoveWordBackward'; + ecMoveWordBackwardAndModifySelection : Result := 'MoveWordBackwardAndModifySelection'; + ecMoveWordForward : Result := 'MoveWordForward'; + ecMoveWordForwardAndModifySelection : Result := 'MoveWordForwardAndModifySelection'; + ecMoveWordLeft : Result := 'MoveWordLeft'; + ecMoveWordLeftAndModifySelection : Result := 'MoveWordLeftAndModifySelection'; + ecMoveWordRight : Result := 'MoveWordRight'; + ecMoveWordRightAndModifySelection : Result := 'MoveWordRightAndModifySelection'; + ecOutdent : Result := 'Outdent'; + ecOverWrite : Result := 'OverWrite'; + ecPaste : Result := 'Paste'; + ecPasteAndMatchStyle : Result := 'PasteAndMatchStyle'; + ecPasteGlobalSelection : Result := 'PasteGlobalSelection'; + ecPrint : Result := 'Print'; + ecRedo : Result := 'Redo'; + ecRemoveFormat : Result := 'RemoveFormat'; + ecScrollLineDown : Result := 'ScrollLineDown'; + ecScrollLineUp : Result := 'ScrollLineUp'; + ecScrollPageBackward : Result := 'ScrollPageBackward'; + ecScrollPageForward : Result := 'ScrollPageForward'; + ecScrollToBeginningOfDocument : Result := 'ScrollToBeginningOfDocument'; + ecScrollToEndOfDocument : Result := 'ScrollToEndOfDocument'; + ecSelectAll : Result := 'SelectAll'; + ecSelectLine : Result := 'SelectLine'; + ecSelectParagraph : Result := 'SelectParagraph'; + ecSelectSentence : Result := 'SelectSentence'; + ecSelectToMark : Result := 'SelectToMark'; + ecSelectWord : Result := 'SelectWord'; + ecSetMark : Result := 'SetMark'; + ecStrikethrough : Result := 'Strikethrough'; + ecStyleWithCSS : Result := 'StyleWithCSS'; + ecSubscript : Result := 'Subscript'; + ecSuperscript : Result := 'Superscript'; + ecSwapWithMark : Result := 'SwapWithMark'; + ecToggleBold : Result := 'ToggleBold'; + ecToggleItalic : Result := 'ToggleItalic'; + ecToggleUnderline : Result := 'ToggleUnderline'; + ecTranspose : Result := 'Transpose'; + ecUnderline : Result := 'Underline'; + ecUndo : Result := 'Undo'; + ecUnlink : Result := 'Unlink'; + ecUnscript : Result := 'Unscript'; + ecUnselect : Result := 'Unselect'; + ecUseCSS : Result := 'UseCSS'; + ecYank : Result := 'Yank'; + ecYankAndSelect : Result := 'YankAndSelect'; + else Result := ''; + end; +end; + +function DeleteDirContents(const aDirectory : string; const aExcludeFiles : TStringList) : boolean; +var + TempRec : TSearchRec; + TempPath : string; + TempIdx : integer; +begin + Result := True; + + try + if (length(aDirectory) > 0) and + DirectoryExists(aDirectory) and + (FindFirst(aDirectory + '\*', faAnyFile, TempRec) = 0) then + try + repeat + TempPath := aDirectory + PathDelim + TempRec.Name; + + if ((TempRec.Attr and faDirectory) <> 0) then + begin + if (TempRec.Name <> '.') and (TempRec.Name <> '..') then + begin + if DeleteDirContents(TempPath, aExcludeFiles) then + Result := RemoveDir(TempPath) and Result + else + Result := False; + end; + end + else + if (aExcludeFiles <> nil) then + begin + TempIdx := aExcludeFiles.IndexOf(TempRec.Name); + Result := ((TempIdx >= 0) or + ((TempIdx < 0) and DeleteFile(TempPath))) and + Result; + end + else + Result := DeleteFile(TempPath) and Result; + + until (FindNext(TempRec) <> 0) or not(Result); + finally + FindClose(TempRec); + end; + except + on e : exception do + if CustomExceptionHandler('DeleteDirContents', e) then raise; + end; +end; + +function SystemCursorIDToDelphiCursor(aSystemCursorID : cardinal) : TCursor; +begin + // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadcursorw + case aSystemCursorId of + 32650 : Result := crAppStart; + 32512 : Result := crArrow; + 32515 : Result := crCross; + 32649 : Result := crHandPoint; + 32651 : Result := crHelp; + 32513 : Result := crIBeam; + 32648 : Result := crNoDrop; + 32640, + 32646 : Result := crSizeAll; + 32643 : Result := crSizeNESW; + 32645 : Result := crSizeNS; + 32642 : Result := crSizeNWSE; + 32644 : Result := crSizeWE; + 32516 : Result := crUpArrow; + 32514 : Result := crHourGlass; + else Result := crDefault; + end; +end; + +function LoggedQueryInterface(const aBaseIntf: IInterface; const aGUID: TGUID; out Obj): boolean; +var + TempResult : HRESULT; + TempMessage : wvstring; +begin + TempResult := aBaseIntf.QueryInterface(aGUID, Obj); + Result := succeeded(TempResult); + + if not(Result) and assigned(GlobalWebView2Loader) then + begin + TempMessage := 'The QueryInterface call for ' + {$IFDEF FPC}UTF8Decode({$ENDIF}GUIDToString(aGUID){$IFDEF FPC}){$ENDIF} + + ' failed. ' + + 'Error code : 0x' + {$IFDEF FPC}UTF8Decode({$ENDIF}inttohex(cardinal(TempResult), 8){$IFDEF FPC}){$ENDIF}; + GlobalWebView2Loader.AppendErrorLog(TempMessage); + end; +end; + +function CustomPathIsRelative(const aPath : wvstring) : boolean; +begin + Result := PathIsRelativeUnicode(PWideChar(aPath)); +end; + +function CustomPathIsURL(const aPath : wvstring) : boolean; +begin + Result := PathIsURLUnicode(PWideChar(aPath + #0)); +end; + +function CustomPathIsUNC(const aPath : wvstring) : boolean; +begin + Result := PathIsUNCUnicode(PWideChar(aPath + #0)); +end; + +function CustomPathCanonicalize(const aOriginalPath : wvstring; var aCanonicalPath : wvstring) : boolean; +var + TempBuffer: array [0..pred(MAX_PATH)] of WideChar; +begin + Result := False; + aCanonicalPath := ''; + + if (length(aOriginalPath) > MAX_PATH) or + (Copy(aOriginalPath, 1, 4) = '\\?\') or + CustomPathIsUNC(aOriginalPath) then + exit; + + FillChar(TempBuffer, MAX_PATH * SizeOf(WideChar), 0); + + if PathCanonicalizeUnicode(@TempBuffer[0], PWideChar(aOriginalPath + #0)) then + begin + aCanonicalPath := TempBuffer; + Result := True; + end; +end; + +function CustomAbsolutePath(const aPath : wvstring; aMustExist : boolean) : wvstring; +var + TempNewPath, TempOldPath : wvstring; +begin + if (length(aPath) > 0) then + begin + if CustomPathIsRelative(aPath) then + TempOldPath := GetModulePath + aPath + else + TempOldPath := aPath; + + if not(CustomPathCanonicalize(TempOldPath, TempNewPath)) then + TempNewPath := TempOldPath; + + if aMustExist and not(DirectoryExists(TempNewPath)) then + Result := '' + else + Result := TempNewPath; + end + else + Result := ''; +end; + +function GetModulePath : wvstring; +begin + {$IFDEF FPC} + Result := UTF8Decode(IncludeTrailingPathDelimiter(ExtractFileDir(GetModuleName(HINSTANCE)))); + {$ELSE} + Result := IncludeTrailingPathDelimiter(ExtractFileDir(GetModuleName(HINSTANCE))); + {$ENDIF} +end; + +function EscapeCommandLineParameter(const aParameter : wvstring) : wvstring; +const + RESERVEDCHARS = ['`', '~', '!', '#', '$', '&', '*', '(', ')', #9, '{', '[', '|', '\', ';', #39, '"', #10, '<', '>', '?', ' ']; +var + i : integer; +begin + i := 1; + Result := ''; + + while (i <= length(aParameter)) do + begin + {$IFDEF DELPHI12_UP} + if CharInSet(aParameter[i], RESERVEDCHARS) then + {$ELSE} + if (char(aParameter[i]) in RESERVEDCHARS) then + {$ENDIF} + Result := Result + '\' + aParameter[i] + else + Result := Result + aParameter[i]; + + inc(i); + end; +end; + +function CustomURLDecode(const aEncodedStr : wvstring) : AnsiString; +const + HEXCHARS = ['A'..'F', 'a'..'z', '0'..'9']; +var + i, TempLen : integer; +begin + Result := ''; + i := 1; + TempLen := length(aEncodedStr); + + while (i <= TempLen) do + if (aEncodedStr[i] = '+') then + begin + Result := Result + ' '; + inc(i); + end + else + if (aEncodedStr[i] = '%') then + begin + if (i + 2 <= TempLen) and + {$IFDEF DELPHI12_UP} + CharInSet(aEncodedStr[i + 1], HEXCHARS) and CharInSet(aEncodedStr[i + 2], HEXCHARS) then + {$ELSE} + (char(aEncodedStr[i + 1]) in HEXCHARS) and (char(aEncodedStr[i + 2]) in HEXCHARS) then + {$ENDIF} + Result := Result + AnsiChar(StrToInt('$' + char(aEncodedStr[i + 1]) + char(aEncodedStr[i + 2]))); + + inc(i, 3); + end + else + begin + Result := Result + AnsiChar(aEncodedStr[i]); + inc(i); + end; +end; + +{$IFNDEF FPC}{$IFNDEF DELPHI7_UP} +function PosEx(const SubStr, S: string; Offset: Cardinal = 1): Integer; +var + TempString : string; +begin + if Offset <= 1 then + Result := Pos(SubStr, S) + else + begin + TempString := copy(S, Offset, length(S)); + Result := Pos(SubStr, TempString); + if (Result > 0) then inc(Result, Offset - 1); + end; +end; +{$ENDIF}{$ENDIF} + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVTypeLibrary.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVTypeLibrary.pas new file mode 100644 index 000000000..fe34da295 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVTypeLibrary.pas @@ -0,0 +1,15641 @@ +unit uRESTDWPrivWVTypeLibrary; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +{$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers. +{$WARN SYMBOL_PLATFORM OFF} +{$WRITEABLECONST ON} +{$VARPROPSETTER ON} // If you use Delphi 6 you'll need to download and install the second D6 patch in order for this to compile. +{$ALIGN 4} + +interface + +uses + {$IFDEF DELPHI16_UP} + Winapi.Windows, System.Classes, System.Variants, System.Win.StdVCL, Vcl.Graphics, Winapi.ActiveX; + {$ELSE} + Windows, Classes, Variants, Graphics, ActiveX; + {$ENDIF} + +const + /// + /// TypeLibrary major version + /// + WebView2MajorVersion = 1; + /// + /// TypeLibrary minor version + /// + WebView2MinorVersion = 0; + + LIBID_WebView2: TGUID = '{26D34152-879F-4065-BEA2-3DAA2CFADFB8}'; + + IID_ICoreWebView2: TGUID = '{76ECEACB-0462-4D94-AC83-423A6793775E}'; + IID_ICoreWebView2Settings: TGUID = '{E562E4F0-D7FA-43AC-8D71-C05150499F00}'; + IID_ICoreWebView2NavigationStartingEventHandler: TGUID = '{9ADBE429-F36D-432B-9DDC-F8881FBD76E3}'; + IID_ICoreWebView2NavigationStartingEventArgs: TGUID = '{5B495469-E119-438A-9B18-7604F25F2E49}'; + IID_ICoreWebView2HttpRequestHeaders: TGUID = '{E86CAC0E-5523-465C-B536-8FB9FC8C8C60}'; + IID_ICoreWebView2HttpHeadersCollectionIterator: TGUID = '{0702FC30-F43B-47BB-AB52-A42CB552AD9F}'; + IID_ICoreWebView2ContentLoadingEventHandler: TGUID = '{364471E7-F2BE-4910-BDBA-D72077D51C4B}'; + IID_ICoreWebView2ContentLoadingEventArgs: TGUID = '{0C8A1275-9B6B-4901-87AD-70DF25BAFA6E}'; + IID_ICoreWebView2SourceChangedEventHandler: TGUID = '{3C067F9F-5388-4772-8B48-79F7EF1AB37C}'; + IID_ICoreWebView2SourceChangedEventArgs: TGUID = '{31E0E545-1DBA-4266-8914-F63848A1F7D7}'; + IID_ICoreWebView2HistoryChangedEventHandler: TGUID = '{C79A420C-EFD9-4058-9295-3E8B4BCAB645}'; + IID_ICoreWebView2NavigationCompletedEventHandler: TGUID = '{D33A35BF-1C49-4F98-93AB-006E0533FE1C}'; + IID_ICoreWebView2NavigationCompletedEventArgs: TGUID = '{30D68B7D-20D9-4752-A9CA-EC8448FBB5C1}'; + IID_ICoreWebView2ScriptDialogOpeningEventHandler: TGUID = '{EF381BF9-AFA8-4E37-91C4-8AC48524BDFB}'; + IID_ICoreWebView2ScriptDialogOpeningEventArgs: TGUID = '{7390BB70-ABE0-4843-9529-F143B31B03D6}'; + IID_ICoreWebView2Deferral: TGUID = '{C10E7F7B-B585-46F0-A623-8BEFBF3E4EE0}'; + IID_ICoreWebView2PermissionRequestedEventHandler: TGUID = '{15E1C6A3-C72A-4DF3-91D7-D097FBEC6BFD}'; + IID_ICoreWebView2PermissionRequestedEventArgs: TGUID = '{973AE2EF-FF18-4894-8FB2-3C758F046810}'; + IID_ICoreWebView2ProcessFailedEventHandler: TGUID = '{79E0AEA4-990B-42D9-AA1D-0FCC2E5BC7F1}'; + IID_ICoreWebView2ProcessFailedEventArgs: TGUID = '{8155A9A4-1474-4A86-8CAE-151B0FA6B8CA}'; + IID_ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler: TGUID = '{B99369F3-9B11-47B5-BC6F-8E7895FCEA17}'; + IID_ICoreWebView2ExecuteScriptCompletedHandler: TGUID = '{49511172-CC67-4BCA-9923-137112F4C4CC}'; + IID_ICoreWebView2CapturePreviewCompletedHandler: TGUID = '{697E05E9-3D8F-45FA-96F4-8FFE1EDEDAF5}'; + IID_ICoreWebView2WebMessageReceivedEventHandler: TGUID = '{57213F19-00E6-49FA-8E07-898EA01ECBD2}'; + IID_ICoreWebView2WebMessageReceivedEventArgs: TGUID = '{0F99A40C-E962-4207-9E92-E3D542EFF849}'; + IID_ICoreWebView2CallDevToolsProtocolMethodCompletedHandler: TGUID = '{5C4889F0-5EF6-4C5A-952C-D8F1B92D0574}'; + IID_ICoreWebView2DevToolsProtocolEventReceiver: TGUID = '{B32CA51A-8371-45E9-9317-AF021D080367}'; + IID_ICoreWebView2DevToolsProtocolEventReceivedEventHandler: TGUID = '{E2FDA4BE-5456-406C-A261-3D452138362C}'; + IID_ICoreWebView2DevToolsProtocolEventReceivedEventArgs: TGUID = '{653C2959-BB3A-4377-8632-B58ADA4E66C4}'; + IID_ICoreWebView2NewWindowRequestedEventHandler: TGUID = '{D4C185FE-C81C-4989-97AF-2D3FA7AB5651}'; + IID_ICoreWebView2NewWindowRequestedEventArgs: TGUID = '{34ACB11C-FC37-4418-9132-F9C21D1EAFB9}'; + IID_ICoreWebView2WindowFeatures: TGUID = '{5EAF559F-B46E-4397-8860-E422F287FF1E}'; + IID_ICoreWebView2DocumentTitleChangedEventHandler: TGUID = '{F5F2B923-953E-4042-9F95-F3A118E1AFD4}'; + IID_ICoreWebView2ContainsFullScreenElementChangedEventHandler: TGUID = '{E45D98B1-AFEF-45BE-8BAF-6C7728867F73}'; + IID_ICoreWebView2WebResourceRequestedEventHandler: TGUID = '{AB00B74C-15F1-4646-80E8-E76341D25D71}'; + IID_ICoreWebView2WebResourceRequestedEventArgs: TGUID = '{453E667F-12C7-49D4-BE6D-DDBE7956F57A}'; + IID_ICoreWebView2WebResourceRequest: TGUID = '{97055CD4-512C-4264-8B5F-E3F446CEA6A5}'; + IID_ICoreWebView2WebResourceResponse: TGUID = '{AAFCC94F-FA27-48FD-97DF-830EF75AAEC9}'; + IID_ICoreWebView2HttpResponseHeaders: TGUID = '{03C5FF5A-9B45-4A88-881C-89A9F328619C}'; + IID_ICoreWebView2WindowCloseRequestedEventHandler: TGUID = '{5C19E9E0-092F-486B-AFFA-CA8231913039}'; + IID_ICoreWebView2_2: TGUID = '{9E8F0CF8-E670-4B5E-B2BC-73E061E3184C}'; + IID_ICoreWebView2WebResourceResponseReceivedEventHandler: TGUID = '{7DE9898A-24F5-40C3-A2DE-D4F458E69828}'; + IID_ICoreWebView2WebResourceResponseReceivedEventArgs: TGUID = '{D1DB483D-6796-4B8B-80FC-13712BB716F4}'; + IID_ICoreWebView2WebResourceResponseView: TGUID = '{79701053-7759-4162-8F7D-F1B3F084928D}'; + IID_ICoreWebView2WebResourceResponseViewGetContentCompletedHandler: TGUID = '{875738E1-9FA2-40E3-8B74-2E8972DD6FE7}'; + IID_ICoreWebView2DOMContentLoadedEventHandler: TGUID = '{4BAC7E9C-199E-49ED-87ED-249303ACF019}'; + IID_ICoreWebView2DOMContentLoadedEventArgs: TGUID = '{16B1E21A-C503-44F2-84C9-70ABA5031283}'; + IID_ICoreWebView2CookieManager: TGUID = '{177CD9E7-B6F5-451A-94A0-5D7A3A4C4141}'; + IID_ICoreWebView2Cookie: TGUID = '{AD26D6BE-1486-43E6-BF87-A2034006CA21}'; + IID_ICoreWebView2GetCookiesCompletedHandler: TGUID = '{5A4F5069-5C15-47C3-8646-F4DE1C116670}'; + IID_ICoreWebView2CookieList: TGUID = '{F7F6F714-5D2A-43C6-9503-346ECE02D186}'; + IID_ICoreWebView2Environment: TGUID = '{B96D755E-0319-4E92-A296-23436F46A1FC}'; + IID_ICoreWebView2CreateCoreWebView2ControllerCompletedHandler: TGUID = '{6C4819F3-C9B7-4260-8127-C9F5BDE7F68C}'; + IID_ICoreWebView2Controller: TGUID = '{4D00C0D1-9434-4EB6-8078-8697A560334F}'; + IID_ICoreWebView2ZoomFactorChangedEventHandler: TGUID = '{B52D71D6-C4DF-4543-A90C-64A3E60F38CB}'; + IID_ICoreWebView2MoveFocusRequestedEventHandler: TGUID = '{69035451-6DC7-4CB8-9BCE-B2BD70AD289F}'; + IID_ICoreWebView2MoveFocusRequestedEventArgs: TGUID = '{2D6AA13B-3839-4A15-92FC-D88B3C0D9C9D}'; + IID_ICoreWebView2FocusChangedEventHandler: TGUID = '{05EA24BD-6452-4926-9014-4B82B498135D}'; + IID_ICoreWebView2AcceleratorKeyPressedEventHandler: TGUID = '{B29C7E28-FA79-41A8-8E44-65811C76DCB2}'; + IID_ICoreWebView2AcceleratorKeyPressedEventArgs: TGUID = '{9F760F8A-FB79-42BE-9990-7B56900FA9C7}'; + IID_ICoreWebView2NewBrowserVersionAvailableEventHandler: TGUID = '{F9A2976E-D34E-44FC-ADEE-81B6B57CA914}'; + IID_ICoreWebView2_3: TGUID = '{A0D6DF20-3B92-416D-AA0C-437A9C727857}'; + IID_ICoreWebView2TrySuspendCompletedHandler: TGUID = '{00F206A7-9D17-4605-91F6-4E8E4DE192E3}'; + IID_ICoreWebView2_4: TGUID = '{20D02D59-6DF2-42DC-BD06-F98A694B1302}'; + IID_ICoreWebView2FrameCreatedEventHandler: TGUID = '{38059770-9BAA-11EB-A8B3-0242AC130003}'; + IID_ICoreWebView2FrameCreatedEventArgs: TGUID = '{4D6E7B5E-9BAA-11EB-A8B3-0242AC130003}'; + IID_ICoreWebView2Frame: TGUID = '{F1131A5E-9BA9-11EB-A8B3-0242AC130003}'; + IID_ICoreWebView2FrameNameChangedEventHandler: TGUID = '{435C7DC8-9BAA-11EB-A8B3-0242AC130003}'; + IID_ICoreWebView2FrameDestroyedEventHandler: TGUID = '{59DD7B4C-9BAA-11EB-A8B3-0242AC130003}'; + IID_ICoreWebView2DownloadStartingEventHandler: TGUID = '{EFEDC989-C396-41CA-83F7-07F845A55724}'; + IID_ICoreWebView2DownloadStartingEventArgs: TGUID = '{E99BBE21-43E9-4544-A732-282764EAFA60}'; + IID_ICoreWebView2DownloadOperation: TGUID = '{3D6B6CF2-AFE1-44C7-A995-C65117714336}'; + IID_ICoreWebView2BytesReceivedChangedEventHandler: TGUID = '{828E8AB6-D94C-4264-9CEF-5217170D6251}'; + IID_ICoreWebView2EstimatedEndTimeChangedEventHandler: TGUID = '{28F0D425-93FE-4E63-9F8D-2AEEC6D3BA1E}'; + IID_ICoreWebView2StateChangedEventHandler: TGUID = '{81336594-7EDE-4BA9-BF71-ACF0A95B58DD}'; + IID_ICoreWebView2_5: TGUID = '{BEDB11B8-D63C-11EB-B8BC-0242AC130003}'; + IID_ICoreWebView2ClientCertificateRequestedEventHandler: TGUID = '{D7175BA2-BCC3-11EB-8529-0242AC130003}'; + IID_ICoreWebView2ClientCertificateRequestedEventArgs: TGUID = '{BC59DB28-BCC3-11EB-8529-0242AC130003}'; + IID_ICoreWebView2StringCollection: TGUID = '{F41F3F8A-BCC3-11EB-8529-0242AC130003}'; + IID_ICoreWebView2ClientCertificateCollection: TGUID = '{EF5674D2-BCC3-11EB-8529-0242AC130003}'; + IID_ICoreWebView2ClientCertificate: TGUID = '{E7188076-BCC3-11EB-8529-0242AC130003}'; + IID_ICoreWebView2_6: TGUID = '{499AADAC-D92C-4589-8A75-111BFC167795}'; + IID_ICoreWebView2_7: TGUID = '{79C24D83-09A3-45AE-9418-487F32A58740}'; + IID_ICoreWebView2PrintSettings: TGUID = '{377F3721-C74E-48CA-8DB1-DF68E51D60E2}'; + IID_ICoreWebView2PrintToPdfCompletedHandler: TGUID = '{CCF1EF04-FD8E-4D5F-B2DE-0983E41B8C36}'; + IID_ICoreWebView2_8: TGUID = '{E9632730-6E1E-43AB-B7B8-7B2C9E62E094}'; + IID_ICoreWebView2IsMutedChangedEventHandler: TGUID = '{57D90347-CD0E-4952-A4A2-7483A2756F08}'; + IID_ICoreWebView2IsDocumentPlayingAudioChangedEventHandler: TGUID = '{5DEF109A-2F4B-49FA-B7F6-11C39E513328}'; + IID_ICoreWebView2_9: TGUID = '{4D7B2EAB-9FDC-468D-B998-A9260B5ED651}'; + IID_ICoreWebView2IsDefaultDownloadDialogOpenChangedEventHandler: TGUID = '{3117DA26-AE13-438D-BD46-EDBEB2C4CE81}'; + IID_ICoreWebView2_10: TGUID = '{B1690564-6F5A-4983-8E48-31D1143FECDB}'; + IID_ICoreWebView2BasicAuthenticationRequestedEventHandler: TGUID = '{58B4D6C2-18D4-497E-B39B-9A96533FA278}'; + IID_ICoreWebView2BasicAuthenticationRequestedEventArgs: TGUID = '{EF05516F-D897-4F9E-B672-D8E2307A3FB0}'; + IID_ICoreWebView2BasicAuthenticationResponse: TGUID = '{07023F7D-2D77-4D67-9040-6E7D428C6A40}'; + IID_ICoreWebView2_11: TGUID = '{0BE78E56-C193-4051-B943-23B460C08BDB}'; + IID_ICoreWebView2ContextMenuRequestedEventHandler: TGUID = '{04D3FE1D-AB87-42FB-A898-DA241D35B63C}'; + IID_ICoreWebView2ContextMenuRequestedEventArgs: TGUID = '{A1D309EE-C03F-11EB-8529-0242AC130003}'; + IID_ICoreWebView2ContextMenuItemCollection: TGUID = '{F562A2F5-C415-45CF-B909-D4B7C1E276D3}'; + IID_ICoreWebView2ContextMenuItem: TGUID = '{7AED49E3-A93F-497A-811C-749C6B6B6C65}'; + IID_ICoreWebView2CustomItemSelectedEventHandler: TGUID = '{49E1D0BC-FE9E-4481-B7C2-32324AA21998}'; + IID_ICoreWebView2ContextMenuTarget: TGUID = '{B8611D99-EED6-4F3F-902C-A198502AD472}'; + IID_ICoreWebView2_12: TGUID = '{35D69927-BCFA-4566-9349-6B3E0D154CAC}'; + IID_ICoreWebView2StatusBarTextChangedEventHandler: TGUID = '{A5E3B0D0-10DF-4156-BFAD-3B43867ACAC6}'; + IID_ICoreWebView2_13: TGUID = '{F75F09A8-667E-4983-88D6-C8773F315E84}'; + IID_ICoreWebView2Profile: TGUID = '{79110AD3-CD5D-4373-8BC3-C60658F17A5F}'; + IID_ICoreWebView2_14: TGUID = '{6DAA4F10-4A90-4753-8898-77C5DF534165}'; + IID_ICoreWebView2ServerCertificateErrorDetectedEventHandler: TGUID = '{969B3A26-D85E-4795-8199-FEF57344DA22}'; + IID_ICoreWebView2ServerCertificateErrorDetectedEventArgs: TGUID = '{012193ED-7C13-48FF-969D-A84C1F432A14}'; + IID_ICoreWebView2Certificate: TGUID = '{C5FB2FCE-1CAC-4AEE-9C79-5ED0362EAAE0}'; + IID_ICoreWebView2ClearServerCertificateErrorActionsCompletedHandler: TGUID = '{3B40AAC6-ACFE-4FFD-8211-F607B96E2D5B}'; + IID_ICoreWebView2_15: TGUID = '{517B2D1D-7DAE-4A66-A4F4-10352FFB9518}'; + IID_ICoreWebView2FaviconChangedEventHandler: TGUID = '{2913DA94-833D-4DE0-8DCA-900FC524A1A4}'; + IID_ICoreWebView2GetFaviconCompletedHandler: TGUID = '{A2508329-7DA8-49D7-8C05-FA125E4AEE8D}'; + IID_ICoreWebView2_16: TGUID = '{0EB34DC9-9F91-41E1-8639-95CD5943906B}'; + IID_ICoreWebView2PrintCompletedHandler: TGUID = '{8FD80075-ED08-42DB-8570-F5D14977461E}'; + IID_ICoreWebView2PrintToPdfStreamCompletedHandler: TGUID = '{4C9F8229-8F93-444F-A711-2C0DFD6359D5}'; + IID_ICoreWebView2_17: TGUID = '{702E75D4-FD44-434D-9D70-1A68A6B1192A}'; + IID_ICoreWebView2SharedBuffer: TGUID = '{B747A495-0C6F-449E-97B8-2F81E9D6AB43}'; + IID_ICoreWebView2_18: TGUID = '{7A626017-28BE-49B2-B865-3BA2B3522D90}'; + IID_ICoreWebView2LaunchingExternalUriSchemeEventHandler: TGUID = '{74F712E0-8165-43A9-A13F-0CCE597E75DF}'; + IID_ICoreWebView2LaunchingExternalUriSchemeEventArgs: TGUID = '{07D1A6C3-7175-4BA1-9306-E593CA07E46C}'; + IID_ICoreWebView2_19: TGUID = '{6921F954-79B0-437F-A997-C85811897C68}'; + IID_ICoreWebView2_20: TGUID = '{B4BC1926-7305-11EE-B962-0242AC120002}'; + IID_ICoreWebView2_21: TGUID = '{C4980DEA-587B-43B9-8143-3EF3BF552D95}'; + IID_ICoreWebView2ExecuteScriptWithResultCompletedHandler: TGUID = '{1BB5317B-8238-4C67-A7FF-BAF6558F289D}'; + IID_ICoreWebView2ExecuteScriptResult: TGUID = '{0CE15963-3698-4DF7-9399-71ED6CDD8C9F}'; + IID_ICoreWebView2ScriptException: TGUID = '{054DAE00-84A3-49FF-BC17-4012A90BC9FD}'; + IID_ICoreWebView2_22: TGUID = '{DB75DFC7-A857-4632-A398-6969DDE26C0A}'; + IID_ICoreWebView2_23: TGUID = '{508F0DB5-90C4-5872-90A7-267A91377502}'; + IID_ICoreWebView2ObjectCollectionView: TGUID = '{0F36FD87-4F69-4415-98DA-888F89FB9A33}'; + IID_ICoreWebView2_24: TGUID = '{39A7AD55-4287-5CC1-88A1-C6F458593824}'; + IID_ICoreWebView2NotificationReceivedEventHandler: TGUID = '{89C5D598-8788-423B-BE97-E6E01C0F9EE3}'; + IID_ICoreWebView2NotificationReceivedEventArgs: TGUID = '{1512DD5B-5514-4F85-886E-21C3A4C9CFE6}'; + IID_ICoreWebView2Notification: TGUID = '{B7434D98-6BC8-419D-9DA5-FB5A96D4DACD}'; + IID_ICoreWebView2NotificationCloseRequestedEventHandler: TGUID = '{47C32D23-1E94-4733-85F1-D9BF4ACD0974}'; + IID_ICoreWebView2_25: TGUID = '{B5A86092-DF50-5B4F-A17B-6C8F8B40B771}'; + IID_ICoreWebView2SaveAsUIShowingEventHandler: TGUID = '{6BAA177E-3A2E-5CCF-9A13-FAD676CD0522}'; + IID_ICoreWebView2SaveAsUIShowingEventArgs: TGUID = '{55902952-0E0D-5AAA-A7D0-E833CDB34F62}'; + IID_ICoreWebView2ShowSaveAsUICompletedHandler: TGUID = '{E24B07E3-8169-5C34-994A-7F6478946A3C}'; + IID_ICoreWebView2_26: TGUID = '{806268B8-F897-5685-88E5-C45FCA0B1A48}'; + IID_ICoreWebView2SaveFileSecurityCheckStartingEventHandler: TGUID = '{7899576C-19E3-57C8-B7D1-55808292DE57}'; + IID_ICoreWebView2SaveFileSecurityCheckStartingEventArgs: TGUID = '{CF4FF1D1-5A67-5660-8D63-EF699881EA65}'; + IID_ICoreWebView2_27: TGUID = '{00FBE33B-8C07-517C-AA23-0DDD4B5F6FA0}'; + IID_ICoreWebView2ScreenCaptureStartingEventHandler: TGUID = '{E24FF05A-1DB5-59D9-89F3-3C864268DB4A}'; + IID_ICoreWebView2ScreenCaptureStartingEventArgs: TGUID = '{892C03FD-AEE3-5EBA-A1FA-6FD2F6484B2B}'; + IID_ICoreWebView2FrameInfo: TGUID = '{DA86B8A1-BDF3-4F11-9955-528CEFA59727}'; + IID_ICoreWebView2_28: TGUID = '{62E50381-5BF5-51A8-AAE0-F20A3A9C8A90}'; + IID_ICoreWebView2Find: TGUID = '{A3EC0F5F-DDBC-54ED-8546-AF75A785B9A6}'; + IID_ICoreWebView2FindActiveMatchIndexChangedEventHandler: TGUID = '{0054F514-9A8E-5876-AED5-30B37F8C86A5}'; + IID_ICoreWebView2FindMatchCountChangedEventHandler: TGUID = '{DA0D6827-4254-5B10-A6D9-412076AFC9F3}'; + IID_ICoreWebView2FindOptions: TGUID = '{E82E3B2B-A4AF-5BC6-94C6-18B44157A16C}'; + IID_ICoreWebView2FindStartCompletedHandler: TGUID = '{6A90ECAF-44B0-5BD9-8F07-1967E17BE9FB}'; + IID_ICoreWebView2_29: TGUID = '{650F917E-CC16-5C8C-9287-B0BBC8A4AB2C}'; + IID_ICoreWebView2DedicatedWorkerCreatedEventHandler: TGUID = '{CBA7462C-52C1-5706-8BBC-E9FC36476DE4}'; + IID_ICoreWebView2DedicatedWorkerCreatedEventArgs: TGUID = '{910C52AF-8129-516D-AB9A-B524E377D8AC}'; + IID_ICoreWebView2DedicatedWorker: TGUID = '{66833876-EDBA-5A60-8508-7DA64504A9D2}'; + IID_ICoreWebView2DedicatedWorkerDedicatedWorkerCreatedEventHandler: TGUID = '{A85B1B35-F6D7-5AE6-9FD7-57905DEFF79F}'; + IID_ICoreWebView2DedicatedWorkerDestroyingEventHandler: TGUID = '{72473D5F-CBA2-57CA-A42E-03610A349FEF}'; + IID_ICoreWebView2DedicatedWorkerWebMessageReceivedEventHandler: TGUID = '{B366218B-0BB8-58A3-AC33-F40A2235366E}'; + IID_ICoreWebView2AcceleratorKeyPressedEventArgs2: TGUID = '{03B2C8C8-7799-4E34-BD66-ED26AA85F2BF}'; + IID_ICoreWebView2BrowserExtension: TGUID = '{7EF7FFA0-FAC5-462C-B189-3D9EDBE575DA}'; + IID_ICoreWebView2BrowserExtensionRemoveCompletedHandler: TGUID = '{8E41909A-9B18-4BB1-8CDF-930F467A50BE}'; + IID_ICoreWebView2BrowserExtensionEnableCompletedHandler: TGUID = '{30C186CE-7FAD-421F-A3BC-A8EAF071DDB8}'; + IID_ICoreWebView2BrowserProcessExitedEventArgs: TGUID = '{1F00663F-AF8C-4782-9CDD-DD01C52E34CB}'; + IID_ICoreWebView2CompositionController: TGUID = '{3DF9B733-B9AE-4A15-86B4-EB9EE9826469}'; + IID_ICoreWebView2PointerInfo: TGUID = '{E6995887-D10D-4F5D-9359-4CE46E4F96B9}'; + IID_ICoreWebView2CursorChangedEventHandler: TGUID = '{9DA43CCC-26E1-4DAD-B56C-D8961C94C571}'; + IID_ICoreWebView2CompositionController2: TGUID = '{0B6A3D24-49CB-4806-BA20-B5E0734A7B26}'; + IID_ICoreWebView2CompositionController3: TGUID = '{9570570E-4D76-4361-9EE1-F04D0DBDFB1E}'; + IID_ICoreWebView2CompositionController4: TGUID = '{7C367B9B-3D2B-450F-9E58-D61A20F486AA}'; + IID_ICoreWebView2RegionRectCollectionView: TGUID = '{333353B8-48BF-4449-8FCC-22697FAF5753}'; + IID_ICoreWebView2NonClientRegionChangedEventHandler: TGUID = '{4A794E66-AA6C-46BD-93A3-382196837680}'; + IID_ICoreWebView2NonClientRegionChangedEventArgs: TGUID = '{AB71D500-0820-4A52-809C-48DB04FF93BF}'; + IID_ICoreWebView2CompositionController5: TGUID = '{8D0F82EB-7C33-5A4C-9108-84CA28CCC3B4}'; + IID_ICoreWebView2DragStartingEventHandler: TGUID = '{3B149321-83C3-5D1F-B03F-A42899BC1C15}'; + IID_ICoreWebView2DragStartingEventArgs: TGUID = '{8B8D9C7E-2F1A-4E6B-9D5A-3C8F7B9E1A2D}'; + IID_ICoreWebView2Controller2: TGUID = '{C979903E-D4CA-4228-92EB-47EE3FA96EAB}'; + IID_ICoreWebView2Controller3: TGUID = '{F9614724-5D2B-41DC-AEF7-73D62B51543B}'; + IID_ICoreWebView2RasterizationScaleChangedEventHandler: TGUID = '{9C98C8B1-AC53-427E-A345-3049B5524BBE}'; + IID_ICoreWebView2Controller4: TGUID = '{97D418D5-A426-4E49-A151-E1A10F327D9E}'; + IID_ICoreWebView2ControllerOptions: TGUID = '{12AAE616-8CCB-44EC-BCB3-EB1831881635}'; + IID_ICoreWebView2ControllerOptions2: TGUID = '{06C991D8-9E7E-11ED-A8FC-0242AC120002}'; + IID_ICoreWebView2ControllerOptions3: TGUID = '{B32B191A-8998-57CA-B7CB-E04617E4CE4A}'; + IID_ICoreWebView2ControllerOptions4: TGUID = '{21EB052F-AD39-555E-824A-C87B091D4D36}'; + IID_ICoreWebView2CustomSchemeRegistration: TGUID = '{D60AC92C-37A6-4B26-A39E-95CFE59047BB}'; + IID_ICoreWebView2DevToolsProtocolEventReceivedEventArgs2: TGUID = '{2DC4959D-1494-4393-95BA-BEA4CB9EBD1B}'; + IID_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler: TGUID = '{4E8A3389-C9D8-4BD2-B6B5-124FEE6CC14D}'; + IID_ICoreWebView2Environment2: TGUID = '{41F3632B-5EF4-404F-AD82-2D606C5A9A21}'; + IID_ICoreWebView2Environment3: TGUID = '{80A22AE3-BE7C-4CE2-AFE1-5A50056CDEEB}'; + IID_ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler: TGUID = '{02FAB84B-1428-4FB7-AD45-1B2E64736184}'; + IID_ICoreWebView2Environment4: TGUID = '{20944379-6DCF-41D6-A0A0-ABC0FC50DE0D}'; + IID_ICoreWebView2Environment5: TGUID = '{319E423D-E0D7-4B8D-9254-AE9475DE9B17}'; + IID_ICoreWebView2BrowserProcessExitedEventHandler: TGUID = '{FA504257-A216-4911-A860-FE8825712861}'; + IID_ICoreWebView2Environment6: TGUID = '{E59EE362-ACBD-4857-9A8E-D3644D9459A9}'; + IID_ICoreWebView2Environment7: TGUID = '{43C22296-3BBD-43A4-9C00-5C0DF6DD29A2}'; + IID_ICoreWebView2Environment8: TGUID = '{D6EB91DD-C3D2-45E5-BD29-6DC2BC4DE9CF}'; + IID_ICoreWebView2ProcessInfosChangedEventHandler: TGUID = '{F4AF0C39-44B9-40E9-8B11-0484CFB9E0A1}'; + IID_ICoreWebView2ProcessInfoCollection: TGUID = '{402B99CD-A0CC-4FA5-B7A5-51D86A1D2339}'; + IID_ICoreWebView2ProcessInfo: TGUID = '{84FA7612-3F3D-4FBF-889D-FAD000492D72}'; + IID_ICoreWebView2Environment9: TGUID = '{F06F41BF-4B5A-49D8-B9F6-FA16CD29F274}'; + IID_ICoreWebView2Environment10: TGUID = '{EE0EB9DF-6F12-46CE-B53F-3F47B9C928E0}'; + IID_ICoreWebView2Environment11: TGUID = '{F0913DC6-A0EC-42EF-9805-91DFF3A2966A}'; + IID_ICoreWebView2Environment12: TGUID = '{F503DB9B-739F-48DD-B151-FDFCF253F54E}'; + IID_ICoreWebView2Environment13: TGUID = '{AF641F58-72B2-11EE-B962-0242AC120002}'; + IID_ICoreWebView2GetProcessExtendedInfosCompletedHandler: TGUID = '{F45E55AA-3BC2-11EE-BE56-0242AC120002}'; + IID_ICoreWebView2ProcessExtendedInfoCollection: TGUID = '{32EFA696-407A-11EE-BE56-0242AC120002}'; + IID_ICoreWebView2ProcessExtendedInfo: TGUID = '{AF4C4C2E-45DB-11EE-BE56-0242AC120002}'; + IID_ICoreWebView2FrameInfoCollection: TGUID = '{8F834154-D38E-4D90-AFFB-6800A7272839}'; + IID_ICoreWebView2FrameInfoCollectionIterator: TGUID = '{1BF89E2D-1B2B-4629-B28F-05099B41BB03}'; + IID_ICoreWebView2Environment14: TGUID = '{A5E9FAD9-C875-59DA-9BD7-473AA5CA1CEF}'; + IID_ICoreWebView2FileSystemHandle: TGUID = '{C65100AC-0DE2-5551-A362-23D9BD1D0E1F}'; + IID_ICoreWebView2ObjectCollection: TGUID = '{5CFEC11C-25BD-4E8D-9E1A-7ACDAEEEC047}'; + IID_ICoreWebView2Environment15: TGUID = '{2AC5EBFB-E654-5961-A667-7971885C7B27}'; + IID_ICoreWebView2EnvironmentOptions: TGUID = '{2FDE08A8-1E9A-4766-8C05-95A9CEB9D1C5}'; + IID_ICoreWebView2EnvironmentOptions2: TGUID = '{FF85C98A-1BA7-4A6B-90C8-2B752C89E9E2}'; + IID_ICoreWebView2EnvironmentOptions3: TGUID = '{4A5C436E-A9E3-4A2E-89C3-910D3513F5CC}'; + IID_ICoreWebView2EnvironmentOptions4: TGUID = '{AC52D13F-0D38-475A-9DCA-876580D6793E}'; + IID_ICoreWebView2EnvironmentOptions5: TGUID = '{0AE35D64-C47F-4464-814E-259C345D1501}'; + IID_ICoreWebView2EnvironmentOptions6: TGUID = '{57D29CC3-C84F-42A0-B0E2-EFFBD5E179DE}'; + IID_ICoreWebView2EnvironmentOptions7: TGUID = '{C48D539F-E39F-441C-AE68-1F66E570BDC5}'; + IID_ICoreWebView2EnvironmentOptions8: TGUID = '{7C7ECF51-E918-5CAF-853C-E9A2BCC27775}'; + IID_ICoreWebView2File: TGUID = '{F2C19559-6BC1-4583-A757-90021BE9AFEC}'; + IID_ICoreWebView2Frame2: TGUID = '{7A6A5834-D185-4DBF-B63F-4A9BC43107D4}'; + IID_ICoreWebView2FrameNavigationStartingEventHandler: TGUID = '{E79908BF-2D5D-4968-83DB-263FEA2C1DA3}'; + IID_ICoreWebView2FrameContentLoadingEventHandler: TGUID = '{0D6156F2-D332-49A7-9E03-7D8F2FEEEE54}'; + IID_ICoreWebView2FrameNavigationCompletedEventHandler: TGUID = '{609302AD-0E36-4F9A-A210-6A45272842A9}'; + IID_ICoreWebView2FrameDOMContentLoadedEventHandler: TGUID = '{38D9520D-340F-4D1E-A775-43FCE9753683}'; + IID_ICoreWebView2FrameWebMessageReceivedEventHandler: TGUID = '{E371E005-6D1D-4517-934B-A8F1629C62A5}'; + IID_ICoreWebView2Frame3: TGUID = '{B50D82CC-CC28-481D-9614-CB048895E6A0}'; + IID_ICoreWebView2FramePermissionRequestedEventHandler: TGUID = '{845D0EDD-8BD8-429B-9915-4821789F23E9}'; + IID_ICoreWebView2PermissionRequestedEventArgs2: TGUID = '{74D7127F-9DE6-4200-8734-42D6FB4FF741}'; + IID_ICoreWebView2Frame4: TGUID = '{188782DC-92AA-4732-AB3C-FCC59F6F68B9}'; + IID_ICoreWebView2Frame5: TGUID = '{99D199C4-7305-11EE-B962-0242AC120002}'; + IID_ICoreWebView2Frame6: TGUID = '{0DE611FD-31E9-5DDC-9D71-95EDA26EFF32}'; + IID_ICoreWebView2FrameScreenCaptureStartingEventHandler: TGUID = '{A6C1D8AD-BB80-59C5-895B-FBA1698B9309}'; + IID_ICoreWebView2Frame7: TGUID = '{3598CFA2-D85D-5A9F-9228-4DDE1F59EC64}'; + IID_ICoreWebView2FrameChildFrameCreatedEventHandler: TGUID = '{569E40E7-46B7-563D-83AE-1073155664D7}'; + IID_ICoreWebView2Frame8: TGUID = '{9DEFF655-E3D5-5B8F-9107-52E66B3EC3FC}'; + IID_ICoreWebView2FrameDedicatedWorkerCreatedEventHandler: TGUID = '{3E28D307-9D58-5306-8097-A79301DE4F05}'; + IID_ICoreWebView2FrameInfo2: TGUID = '{56F85CFA-72C4-11EE-B962-0242AC120002}'; + IID_ICoreWebView2NavigationCompletedEventArgs2: TGUID = '{FDF8B738-EE1E-4DB2-A329-8D7D7B74D792}'; + IID_ICoreWebView2NavigationStartingEventArgs2: TGUID = '{9086BE93-91AA-472D-A7E0-579F2BA006AD}'; + IID_ICoreWebView2NavigationStartingEventArgs3: TGUID = '{DDFFE494-4942-4BD2-AB73-35B8FF40E19F}'; + IID_ICoreWebView2NewWindowRequestedEventArgs2: TGUID = '{BBC7BAED-74C6-4C92-B63A-7F5AEAE03DE3}'; + IID_ICoreWebView2NewWindowRequestedEventArgs3: TGUID = '{842BED3C-6AD6-4DD9-B938-28C96667AD66}'; + IID_ICoreWebView2PermissionRequestedEventArgs3: TGUID = '{E61670BC-3DCE-4177-86D2-C629AE3CB6AC}'; + IID_ICoreWebView2PermissionSetting: TGUID = '{792B6ECA-5576-421C-9119-74EBB3A4FFB3}'; + IID_ICoreWebView2PrintSettings2: TGUID = '{CA7F0E1F-3484-41D1-8C1A-65CD44A63F8D}'; + IID_ICoreWebView2ProcessFailedEventArgs2: TGUID = '{4DAB9422-46FA-4C3E-A5D2-41D2071D3680}'; + IID_ICoreWebView2ProcessFailedEventArgs3: TGUID = '{AB667428-094D-5FD1-B480-8B4C0FDBDF2F}'; + IID_ICoreWebView2Profile2: TGUID = '{FA740D4B-5EAE-4344-A8AD-74BE31925397}'; + IID_ICoreWebView2ClearBrowsingDataCompletedHandler: TGUID = '{E9710A06-1D1D-49B2-8234-226F35846AE5}'; + IID_ICoreWebView2Profile3: TGUID = '{B188E659-5685-4E05-BDBA-FC640E0F1992}'; + IID_ICoreWebView2Profile4: TGUID = '{8F4AE680-192E-4EC8-833A-21CFADAEF628}'; + IID_ICoreWebView2SetPermissionStateCompletedHandler: TGUID = '{FC77FB30-9C9E-4076-B8C7-7644A703CA1B}'; + IID_ICoreWebView2GetNonDefaultPermissionSettingsCompletedHandler: TGUID = '{38274481-A15C-4563-94CF-990EDC9AEB95}'; + IID_ICoreWebView2PermissionSettingCollectionView: TGUID = '{F5596F62-3DE5-47B1-91E8-A4104B596B96}'; + IID_ICoreWebView2Profile5: TGUID = '{2EE5B76E-6E80-4DF2-BCD3-D4EC3340A01B}'; + IID_ICoreWebView2Profile6: TGUID = '{BD82FA6A-1D65-4C33-B2B4-0393020CC61B}'; + IID_ICoreWebView2Profile7: TGUID = '{7B4C7906-A1AA-4CB4-B723-DB09F813D541}'; + IID_ICoreWebView2ProfileAddBrowserExtensionCompletedHandler: TGUID = '{DF1AAB27-82B9-4AB6-AAE8-017A49398C14}'; + IID_ICoreWebView2ProfileGetBrowserExtensionsCompletedHandler: TGUID = '{FCE16A1C-F107-4601-8B75-FC4940AE25D0}'; + IID_ICoreWebView2BrowserExtensionList: TGUID = '{2EF3D2DC-BD5F-4F4D-90AF-FD67798F0C2F}'; + IID_ICoreWebView2Profile8: TGUID = '{FBF70C2F-EB1F-4383-85A0-163E92044011}'; + IID_ICoreWebView2ProfileDeletedEventHandler: TGUID = '{DF35055D-772E-4DBE-B743-5FBF74A2B258}'; + IID_ICoreWebView2Profile9: TGUID = '{40C764D0-12FC-5D23-816D-971B353174C1}'; + IID_ICoreWebView2ServiceWorkerManager: TGUID = '{A2D52FD4-9B10-5971-8499-C67D1560F47A}'; + IID_ICoreWebView2ServiceWorkerRegisteredEventHandler: TGUID = '{C024C910-4DF2-54A3-B5C1-6152CA0E4577}'; + IID_ICoreWebView2ServiceWorkerRegisteredEventArgs: TGUID = '{C6172932-407A-553B-B4D1-CDD12605EB6A}'; + IID_ICoreWebView2ServiceWorkerRegistration: TGUID = '{06003F5E-AF92-5E7E-B497-3FA167DD37C2}'; + IID_ICoreWebView2ServiceWorker: TGUID = '{245A7BB7-7C31-582D-95EE-0F2D99D2F5B0}'; + IID_ICoreWebView2ServiceWorkerDestroyingEventHandler: TGUID = '{C7528449-5674-5E34-B990-FF4CEF046214}'; + IID_ICoreWebView2ServiceWorkerWebMessageReceivedEventHandler: TGUID = '{65F0A1A6-A295-5A9F-8041-70DB71566F98}'; + IID_ICoreWebView2ServiceWorkerActivatedEventHandler: TGUID = '{ECAA9897-769D-5ECE-A1E5-8859818CAF86}'; + IID_ICoreWebView2ServiceWorkerActivatedEventArgs: TGUID = '{5685C4B6-A514-58B2-9721-B61EF4CCD9D8}'; + IID_ICoreWebView2ServiceWorkerRegistrationUnregisteringEventHandler: TGUID = '{BEC01D14-6AD9-5257-9FF6-84F01BAA0CCA}'; + IID_ICoreWebView2GetServiceWorkerRegistrationsCompletedHandler: TGUID = '{EA83432F-6528-592F-903B-0917EB0FD9C7}'; + IID_ICoreWebView2ServiceWorkerRegistrationCollectionView: TGUID = '{83D8CFA9-EF83-5447-9431-91C203C4C9D8}'; + IID_ICoreWebView2SharedWorkerManager: TGUID = '{9B897103-D035-551F-892E-3E8F2916D03E}'; + IID_ICoreWebView2SharedWorkerCreatedEventHandler: TGUID = '{79CB8524-B842-551A-8D31-5F824B6955ED}'; + IID_ICoreWebView2SharedWorkerCreatedEventArgs: TGUID = '{9F6615B0-08F1-5BAA-9C95-A02A1DC56D3F}'; + IID_ICoreWebView2SharedWorker: TGUID = '{BCD39C8D-48BB-5F1B-BE22-89F9C0C4484A}'; + IID_ICoreWebView2SharedWorkerDestroyingEventHandler: TGUID = '{5A459F84-FD04-5CCE-A998-6FAB56F09EEB}'; + IID_ICoreWebView2GetSharedWorkersCompletedHandler: TGUID = '{1F3179AE-15E5-51E4-8583-BE0CAF85ADC7}'; + IID_ICoreWebView2SharedWorkerCollectionView: TGUID = '{F8842B09-0108-5575-A965-3D76FD267050}'; + IID_ICoreWebView2Settings2: TGUID = '{EE9A0F68-F46C-4E32-AC23-EF8CAC224D2A}'; + IID_ICoreWebView2Settings3: TGUID = '{FDB5AB74-AF33-4854-84F0-0A631DEB5EBA}'; + IID_ICoreWebView2Settings4: TGUID = '{CB56846C-4168-4D53-B04F-03B6D6796FF2}'; + IID_ICoreWebView2Settings5: TGUID = '{183E7052-1D03-43A0-AB99-98E043B66B39}'; + IID_ICoreWebView2Settings6: TGUID = '{11CB3ACD-9BC8-43B8-83BF-F40753714F87}'; + IID_ICoreWebView2Settings7: TGUID = '{488DC902-35EF-42D2-BC7D-94B65C4BC49C}'; + IID_ICoreWebView2Settings8: TGUID = '{9E6B0E8F-86AD-4E81-8147-A9B5EDB68650}'; + IID_ICoreWebView2Settings9: TGUID = '{0528A73B-E92D-49F4-927A-E547DDDAA37D}'; + IID_ICoreWebView2WebMessageReceivedEventArgs2: TGUID = '{06FC7AB7-C90C-4297-9389-33CA01CF6D5E}'; + IID_ICoreWebView2WebResourceRequestedEventArgs2: TGUID = '{9C562C24-B219-4D7F-92F6-B187FBBADD56}'; + +{* + ********************************************************************* + Declaration of Enumerations defined in Type Library + ********************************************************************* +*} + +type + /// + /// Specifies the key event type that triggered an AcceleratorKeyPressed + /// event. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_KEY_EVENT_KIND = TOleEnum; +const + /// + /// Specifies that the key event type corresponds to window message + /// WM_KEYDOWN. + /// + /// + /// This is one of the COREWEBVIEW2_KEY_EVENT_KIND values. + /// + COREWEBVIEW2_KEY_EVENT_KIND_KEY_DOWN = $00000000; + /// + /// Specifies that the key event type corresponds to window message + /// WM_KEYUP. + /// + /// + /// This is one of the COREWEBVIEW2_KEY_EVENT_KIND values. + /// + COREWEBVIEW2_KEY_EVENT_KIND_KEY_UP = $00000001; + /// + /// Specifies that the key event type corresponds to window message + /// WM_SYSKEYDOWN. + /// + /// + /// This is one of the COREWEBVIEW2_KEY_EVENT_KIND values. + /// + COREWEBVIEW2_KEY_EVENT_KIND_SYSTEM_KEY_DOWN = $00000002; + /// + /// Specifies that the key event type corresponds to window message + /// WM_SYSKEYUP. + /// + /// + /// This is one of the COREWEBVIEW2_KEY_EVENT_KIND values. + /// + COREWEBVIEW2_KEY_EVENT_KIND_SYSTEM_KEY_UP = $00000003; + +type + /// + /// Specifies the reason for moving focus. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_MOVE_FOCUS_REASON = TOleEnum; +const + /// + /// Specifies that the code is setting focus into WebView. + /// + /// + /// This is one of the COREWEBVIEW2_MOVE_FOCUS_REASON values. + /// + COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC = $00000000; + /// + /// Specifies that the focus is moving due to Tab traversal forward. + /// + /// + /// This is one of the COREWEBVIEW2_MOVE_FOCUS_REASON values. + /// + COREWEBVIEW2_MOVE_FOCUS_REASON_NEXT = $00000001; + /// + /// Specifies that the focus is moving due to Tab traversal backward. + /// + /// + /// This is one of the COREWEBVIEW2_MOVE_FOCUS_REASON values. + /// + COREWEBVIEW2_MOVE_FOCUS_REASON_PREVIOUS = $00000002; + +type + /// + /// Indicates the error status values for web navigations. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_WEB_ERROR_STATUS = TOleEnum; +const + /// + /// Indicates that an unknown error occurred. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_ERROR_STATUS values. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_UNKNOWN = $00000000; + /// + /// Indicates that the SSL certificate common name does not match the web + /// address. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_ERROR_STATUS values. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_CERTIFICATE_COMMON_NAME_IS_INCORRECT = $00000001; + /// + /// Indicates that the SSL certificate has expired. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_ERROR_STATUS values. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_CERTIFICATE_EXPIRED = $00000002; + /// + /// Indicates that the SSL client certificate contains errors. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_ERROR_STATUS values. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_CLIENT_CERTIFICATE_CONTAINS_ERRORS = $00000003; + /// + /// Indicates that the SSL certificate has been revoked. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_ERROR_STATUS values. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_CERTIFICATE_REVOKED = $00000004; + /// + /// Indicates that the SSL certificate is not valid. The certificate may not + /// match the public key pins for the host name, the certificate is signed + /// by an untrusted authority or using a weak sign algorithm, the certificate + /// claimed DNS names violate name constraints, the certificate contains a + /// weak key, the validity period of the certificate is too long, lack of + /// revocation information or revocation mechanism, non-unique host name, + /// lack of certificate transparency information, or the certificate is + /// chained to a + /// [legacy Symantec root](https://security.googleblog.com/2018/03/distrust-of-symantec-pki-immediate.html). + /// + /// + /// This is one of the COREWEBVIEW2_WEB_ERROR_STATUS values. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_CERTIFICATE_IS_INVALID = $00000005; + /// + /// Indicates that the host is unreachable. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_ERROR_STATUS values. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_SERVER_UNREACHABLE = $00000006; + /// + /// Indicates that the connection has timed out. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_ERROR_STATUS values. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_TIMEOUT = $00000007; + /// + /// Indicates that the server returned an invalid or unrecognized response. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_ERROR_STATUS values. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_ERROR_HTTP_INVALID_SERVER_RESPONSE = $00000008; + /// + /// Indicates that the connection was stopped. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_ERROR_STATUS values. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_CONNECTION_ABORTED = $00000009; + /// + /// Indicates that the connection was reset. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_ERROR_STATUS values. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_CONNECTION_RESET = $0000000A; + /// + /// Indicates that the Internet connection has been lost. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_ERROR_STATUS values. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_DISCONNECTED = $0000000B; + /// + /// Indicates that a connection to the destination was not established. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_ERROR_STATUS values. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_CANNOT_CONNECT = $0000000C; + /// + /// Indicates that the provided host name was not able to be resolved. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_ERROR_STATUS values. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_HOST_NAME_NOT_RESOLVED = $0000000D; + /// + /// Indicates that the operation was canceled. This status code is also used + /// in the following cases: + /// 1) when the app cancels a navigation via NavigationStarting event. + /// 2) For original navigation if the app navigates the WebView2 in a rapid succession + /// away after the load for original navigation commenced, but before it completed. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_ERROR_STATUS values. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_OPERATION_CANCELED = $0000000E; + /// + /// Indicates that the request redirect failed. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_ERROR_STATUS values. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_REDIRECT_FAILED = $0000000F; + /// + /// Indicates that an unexpected error occurred. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_UNEXPECTED_ERROR = $00000010; + /// + /// Indicates that user is prompted with a login, waiting on user action. + /// Initial navigation to a login site will always return this even if app provides + /// credential using BasicAuthenticationRequested. + /// HTTP response status code in this case is 401. + /// See status code reference here: https://developer.mozilla.org/docs/Web/HTTP/Status. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_ERROR_STATUS values. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_VALID_AUTHENTICATION_CREDENTIALS_REQUIRED = $00000011; + /// + /// Indicates that user lacks proper authentication credentials for a proxy server. + /// HTTP response status code in this case is 407. + /// See status code reference here: https://developer.mozilla.org/docs/Web/HTTP/Status. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_ERROR_STATUS values. + /// + COREWEBVIEW2_WEB_ERROR_STATUS_VALID_PROXY_AUTHENTICATION_REQUIRED = $00000012; + +type + /// + /// Specifies the JavaScript dialog type used in the + /// ICoreWebView2ScriptDialogOpeningEventHandler interface. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_SCRIPT_DIALOG_KIND = TOleEnum; +const + /// + /// Indicates that the dialog uses the window.alert JavaScript function. + /// + /// + /// This is one of the COREWEBVIEW2_SCRIPT_DIALOG_KIND values. + /// + COREWEBVIEW2_SCRIPT_DIALOG_KIND_ALERT = $00000000; + /// + /// Indicates that the dialog uses the window.confirm JavaScript function. + /// + /// + /// This is one of the COREWEBVIEW2_SCRIPT_DIALOG_KIND values. + /// + COREWEBVIEW2_SCRIPT_DIALOG_KIND_CONFIRM = $00000001; + /// + /// Indicates that the dialog uses the window.prompt JavaScript function. + /// + /// + /// This is one of the COREWEBVIEW2_SCRIPT_DIALOG_KIND values. + /// + COREWEBVIEW2_SCRIPT_DIALOG_KIND_PROMPT = $00000002; + /// + /// Indicates that the dialog uses the beforeunload JavaScript event. + /// + /// + /// This is one of the COREWEBVIEW2_SCRIPT_DIALOG_KIND values. + /// + COREWEBVIEW2_SCRIPT_DIALOG_KIND_BEFOREUNLOAD = $00000003; + +type + /// + /// Indicates the type of a permission request. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_PERMISSION_KIND = TOleEnum; +const + /// + /// Indicates an unknown permission. + /// + /// + /// This is one of the COREWEBVIEW2_PERMISSION_KIND values. + /// + COREWEBVIEW2_PERMISSION_KIND_UNKNOWN_PERMISSION = $00000000; + /// + /// Indicates permission to capture audio. + /// + /// + /// This is one of the COREWEBVIEW2_PERMISSION_KIND values. + /// + COREWEBVIEW2_PERMISSION_KIND_MICROPHONE = $00000001; + /// + /// Indicates permission to capture video. + /// + /// + /// This is one of the COREWEBVIEW2_PERMISSION_KIND values. + /// + COREWEBVIEW2_PERMISSION_KIND_CAMERA = $00000002; + /// + /// Indicates permission to access geolocation. + /// + /// + /// This is one of the COREWEBVIEW2_PERMISSION_KIND values. + /// + COREWEBVIEW2_PERMISSION_KIND_GEOLOCATION = $00000003; + /// + /// Indicates permission to send web notifications. Apps that would like to + /// show notifications should handle PermissionRequested events + /// and no browser permission prompt will be shown for notification requests. + /// Note that push notifications are currently unavailable in WebView2. + /// + /// + /// This is one of the COREWEBVIEW2_PERMISSION_KIND values. + /// + COREWEBVIEW2_PERMISSION_KIND_NOTIFICATIONS = $00000004; + /// + /// Indicates permission to access generic sensor. Generic Sensor covering + /// ambient-light-sensor, accelerometer, gyroscope, and magnetometer. + /// + /// + /// This is one of the COREWEBVIEW2_PERMISSION_KIND values. + /// + COREWEBVIEW2_PERMISSION_KIND_OTHER_SENSORS = $00000005; + /// + /// Indicates permission to read the system clipboard without a user gesture. + /// + /// + /// This is one of the COREWEBVIEW2_PERMISSION_KIND values. + /// + COREWEBVIEW2_PERMISSION_KIND_CLIPBOARD_READ = $00000006; + /// + /// Indicates permission to automatically download multiple files. Permission + /// is requested when multiple downloads are triggered in quick succession. + /// + /// + /// This is one of the COREWEBVIEW2_PERMISSION_KIND values. + /// + COREWEBVIEW2_PERMISSION_KIND_MULTIPLE_AUTOMATIC_DOWNLOADS = $00000007; + /// + /// Indicates permission to read and write to files or folders on the device. + /// Permission is requested when developers use the [File System Access API](https://developer.mozilla.org/docs/Web/API/File_System_Access_API) + /// to show the file or folder picker to the end user, and then request + /// "readwrite" permission for the user's selection. + /// + /// + /// This is one of the COREWEBVIEW2_PERMISSION_KIND values. + /// + COREWEBVIEW2_PERMISSION_KIND_FILE_READ_WRITE = $00000008; + /// + /// Indicates permission to play audio and video automatically on sites. This + /// permission affects the autoplay attribute and play method of the audio and + /// video HTML elements, and the start method of the Web Audio API. See the + /// [Autoplay guide for media and Web Audio APIs](https://developer.mozilla.org/docs/Web/Media/Autoplay_guide) for details. + /// + /// + /// This is one of the COREWEBVIEW2_PERMISSION_KIND values. + /// + COREWEBVIEW2_PERMISSION_KIND_AUTOPLAY = $00000009; + /// + /// Indicates permission to use fonts on the device. Permission is requested + /// when developers use the [Local Font Access API](https://wicg.github.io/local-font-access/) + /// to query the system fonts available for styling web content. + /// + /// + /// This is one of the COREWEBVIEW2_PERMISSION_KIND values. + /// + COREWEBVIEW2_PERMISSION_KIND_LOCAL_FONTS = $0000000A; + /// + /// Indicates permission to send and receive system exclusive messages to/from MIDI + /// (Musical Instrument Digital Interface) devices. Permission is requested + /// when developers use the [Web MIDI API](https://developer.mozilla.org/docs/Web/API/Web_MIDI_API) + /// to request access to system exclusive MIDI messages. + /// + /// + /// This is one of the COREWEBVIEW2_PERMISSION_KIND values. + /// + COREWEBVIEW2_PERMISSION_KIND_MIDI_SYSTEM_EXCLUSIVE_MESSAGES = $0000000B; + /// + /// Indicates permission to open and place windows on the screen. Permission is + /// requested when developers use the [Multi-Screen Window Placement API](https://www.w3.org/TR/window-placement/) + /// to get screen details. + /// + /// + /// This is one of the COREWEBVIEW2_PERMISSION_KIND values. + /// + COREWEBVIEW2_PERMISSION_KIND_WINDOW_MANAGEMENT = $0000000C; + /// + /// Indicates permission to persist storage created by the Storage APIs, + /// service workers, etc. If the persistent storage permission is granted, + /// the browser will not evict data in case of low disk space. Permission + /// for a site can be checked using Storage Manager API. + /// + /// + /// This is one of the COREWEBVIEW2_PERMISSION_KIND values. + /// See the Storage Manager API article. + /// + COREWEBVIEW2_PERMISSION_KIND_PERSISTENT_STORAGE = $0000000D; +type + /// + /// Specifies the response to a permission request. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_PERMISSION_STATE = TOleEnum; +const + /// + /// Specifies that the default browser behavior is used, which normally + /// prompt users for decision. + /// + /// + /// This is one of the COREWEBVIEW2_PERMISSION_STATE values. + /// + COREWEBVIEW2_PERMISSION_STATE_DEFAULT = $00000000; + /// + /// Specifies that the permission request is granted. + /// + /// + /// This is one of the COREWEBVIEW2_PERMISSION_STATE values. + /// + COREWEBVIEW2_PERMISSION_STATE_ALLOW = $00000001; + /// + /// Specifies that the permission request is denied. + /// + /// + /// This is one of the COREWEBVIEW2_PERMISSION_STATE values. + /// + COREWEBVIEW2_PERMISSION_STATE_DENY = $00000002; + +type + /// + /// Specifies the process failure type used in the + /// `ICoreWebView2ProcessFailedEventArgs` interface. The values in this enum + /// make reference to the process kinds in the Chromium architecture. For more + /// information about what these processes are and what they do, see + /// [Browser Architecture - Inside look at modern web browser](https://developers.google.com/web/updates/2018/09/inside-browser-part1). + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_PROCESS_FAILED_KIND = TOleEnum; +const + /// + /// Indicates that the browser process ended unexpectedly. The WebView + /// automatically moves to the Closed state. The app has to recreate a new + /// WebView to recover from this failure. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_KIND values. + /// + COREWEBVIEW2_PROCESS_FAILED_KIND_BROWSER_PROCESS_EXITED = $00000000; + /// + /// Indicates that the main frame's render process ended unexpectedly. Any + /// subframes in the WebView will be gone too. A new render process is + /// created automatically and navigated to an error page. You can use the + /// `Reload` method to try to recover from this failure. Alternatively, you + /// can `Close` and recreate the WebView. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_KIND values. + /// + COREWEBVIEW2_PROCESS_FAILED_KIND_RENDER_PROCESS_EXITED = $00000001; + /// + /// Indicates that the main frame's render process is unresponsive. Renderer + /// process unresponsiveness can happen for the following reasons: + /// There is a **long-running script** being executed. For example, the + /// web content in your WebView might be performing a synchronous XHR, or have + /// entered an infinite loop. Or, the **system is busy**. + /// The `ProcessFailed` event will continue to be raised every few seconds + /// until the renderer process has become responsive again. The application + /// can consider taking action if the event keeps being raised. For example, + /// the application might show UI for the user to decide to keep waiting or + /// reload the page, or navigate away. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_KIND values. + /// + COREWEBVIEW2_PROCESS_FAILED_KIND_RENDER_PROCESS_UNRESPONSIVE = $00000002; + /// + /// Indicates that a frame-only render process ended unexpectedly. The process + /// exit does not affect the top-level document, only a subset of the + /// subframes within it. The content in these frames is replaced with an error + /// page in the frame. Your application can communicate with the main frame to + /// recover content in the impacted frames, using + /// `ICoreWebView2ProcessFailedEventArgs2.FrameInfosForFailedProcess` to get + /// information about the impacted frames. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_KIND values. + /// + COREWEBVIEW2_PROCESS_FAILED_KIND_FRAME_RENDER_PROCESS_EXITED = $00000003; + /// + /// Indicates that a utility process ended unexpectedly. The failed process + /// is recreated automatically. Your application does **not** need to handle + /// recovery for this event, but can use `ICoreWebView2ProcessFailedEventArgs` + /// and `ICoreWebView2ProcessFailedEventArgs2` to collect information about + /// the failure, including `ProcessDescription`. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_KIND values. + /// + COREWEBVIEW2_PROCESS_FAILED_KIND_UTILITY_PROCESS_EXITED = $00000004; + /// + /// Indicates that a sandbox helper process ended unexpectedly. This failure + /// is not fatal. Your application does **not** need to handle recovery for + /// this event, but can use `ICoreWebView2ProcessFailedEventArgs` and + /// `ICoreWebView2ProcessFailedEventArgs2` to collect information about + /// the failure. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_KIND values. + /// + COREWEBVIEW2_PROCESS_FAILED_KIND_SANDBOX_HELPER_PROCESS_EXITED = $00000005; + /// + /// Indicates that the GPU process ended unexpectedly. The failed process + /// is recreated automatically. Your application does **not** need to handle + /// recovery for this event, but can use `ICoreWebView2ProcessFailedEventArgs` + /// and `ICoreWebView2ProcessFailedEventArgs2` to collect information about + /// the failure. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_KIND values. + /// + COREWEBVIEW2_PROCESS_FAILED_KIND_GPU_PROCESS_EXITED = $00000006; + /// + /// Indicates that a PPAPI plugin process ended unexpectedly. This failure + /// is not fatal. Your application does **not** need to handle recovery for + /// this event, but can use `ICoreWebView2ProcessFailedEventArgs` and + /// `ICoreWebView2ProcessFailedEventArgs2` to collect information about + /// the failure, including `ProcessDescription`. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_KIND values. + /// + COREWEBVIEW2_PROCESS_FAILED_KIND_PPAPI_PLUGIN_PROCESS_EXITED = $00000007; + /// + /// Indicates that a PPAPI plugin broker process ended unexpectedly. This failure + /// is not fatal. Your application does **not** need to handle recovery for + /// this event, but can use `ICoreWebView2ProcessFailedEventArgs` and + /// `ICoreWebView2ProcessFailedEventArgs2` to collect information about + /// the failure. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_KIND values. + /// + COREWEBVIEW2_PROCESS_FAILED_KIND_PPAPI_BROKER_PROCESS_EXITED = $00000008; + /// + /// Indicates that a process of unspecified kind ended unexpectedly. Your + /// application can use `ICoreWebView2ProcessFailedEventArgs` and + /// `ICoreWebView2ProcessFailedEventArgs2` to collect information about + /// the failure. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_KIND values. + /// + COREWEBVIEW2_PROCESS_FAILED_KIND_UNKNOWN_PROCESS_EXITED = $00000009; + +type + /// + /// Specifies the image format for the ICoreWebView2.CapturePreview method. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_CAPTURE_PREVIEW_IMAGE_FORMAT = TOleEnum; +const + /// + /// Indicates that the PNG image format is used. + /// + /// + /// This is one of the COREWEBVIEW2_CAPTURE_PREVIEW_IMAGE_FORMAT values. + /// + COREWEBVIEW2_CAPTURE_PREVIEW_IMAGE_FORMAT_PNG = $00000000; + /// + /// Indicates the JPEG image format is used. + /// + /// + /// This is one of the COREWEBVIEW2_CAPTURE_PREVIEW_IMAGE_FORMAT values. + /// + COREWEBVIEW2_CAPTURE_PREVIEW_IMAGE_FORMAT_JPEG = $00000001; + +type + /// + /// Specifies the web resource request contexts. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_WEB_RESOURCE_CONTEXT = TOleEnum; +const + /// + /// Specifies all resources. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_CONTEXT values. + /// + COREWEBVIEW2_WEB_RESOURCE_CONTEXT_ALL = $00000000; + /// + /// Specifies a document resource. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_CONTEXT values. + /// + COREWEBVIEW2_WEB_RESOURCE_CONTEXT_DOCUMENT = $00000001; + /// + /// Specifies a CSS resource. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_CONTEXT values. + /// + COREWEBVIEW2_WEB_RESOURCE_CONTEXT_STYLESHEET = $00000002; + /// + /// Specifies an image resource. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_CONTEXT values. + /// + COREWEBVIEW2_WEB_RESOURCE_CONTEXT_IMAGE = $00000003; + /// + /// Specifies another media resource such as a video. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_CONTEXT values. + /// + COREWEBVIEW2_WEB_RESOURCE_CONTEXT_MEDIA = $00000004; + /// + /// Specifies a font resource. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_CONTEXT values. + /// + COREWEBVIEW2_WEB_RESOURCE_CONTEXT_FONT = $00000005; + /// + /// Specifies a script resource. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_CONTEXT values. + /// + COREWEBVIEW2_WEB_RESOURCE_CONTEXT_SCRIPT = $00000006; + /// + /// Specifies an XML HTTP request, Fetch and EventSource API communication. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_CONTEXT values. + /// + COREWEBVIEW2_WEB_RESOURCE_CONTEXT_XML_HTTP_REQUEST = $00000007; + /// + /// Specifies a Fetch API communication. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_CONTEXT values. + /// + COREWEBVIEW2_WEB_RESOURCE_CONTEXT_FETCH = $00000008; + /// + /// Specifies a TextTrack resource. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_CONTEXT values. + /// + COREWEBVIEW2_WEB_RESOURCE_CONTEXT_TEXT_TRACK = $00000009; + /// + /// Specifies an EventSource API communication. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_CONTEXT values. + /// + COREWEBVIEW2_WEB_RESOURCE_CONTEXT_EVENT_SOURCE = $0000000A; + /// + /// Specifies a WebSocket API communication. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_CONTEXT values. + /// + COREWEBVIEW2_WEB_RESOURCE_CONTEXT_WEBSOCKET = $0000000B; + /// + /// Specifies a Web App Manifest. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_CONTEXT values. + /// + COREWEBVIEW2_WEB_RESOURCE_CONTEXT_MANIFEST = $0000000C; + /// + /// Specifies a Signed HTTP Exchange. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_CONTEXT values. + /// + COREWEBVIEW2_WEB_RESOURCE_CONTEXT_SIGNED_EXCHANGE = $0000000D; + /// + /// Specifies a Ping request. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_CONTEXT values. + /// + COREWEBVIEW2_WEB_RESOURCE_CONTEXT_PING = $0000000E; + /// + /// Specifies a CSP Violation Report. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_CONTEXT values. + /// + COREWEBVIEW2_WEB_RESOURCE_CONTEXT_CSP_VIOLATION_REPORT = $0000000F; + /// + /// Specifies an other resource. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_CONTEXT values. + /// + COREWEBVIEW2_WEB_RESOURCE_CONTEXT_OTHER = $00000010; + +type + /// + /// Kind of cookie SameSite status used in the ICoreWebView2Cookie interface. + /// These fields match those as specified in https://developer.mozilla.org/docs/Web/HTTP/Cookies#. + /// Learn more about SameSite cookies here: https://tools.ietf.org/html/draft-west-first-party-cookies-07 + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_COOKIE_SAME_SITE_KIND = TOleEnum; +const + /// + /// None SameSite type. No restrictions on cross-site requests. + /// + /// + /// This is one of the COREWEBVIEW2_COOKIE_SAME_SITE_KIND values. + /// + COREWEBVIEW2_COOKIE_SAME_SITE_KIND_NONE = $00000000; + /// + /// Lax SameSite type. The cookie will be sent with "same-site" requests, and with "cross-site" top level navigation. + /// + /// + /// This is one of the COREWEBVIEW2_COOKIE_SAME_SITE_KIND values. + /// + COREWEBVIEW2_COOKIE_SAME_SITE_KIND_LAX = $00000001; + /// + /// Strict SameSite type. The cookie will only be sent along with "same-site" requests. + /// + /// + /// This is one of the COREWEBVIEW2_COOKIE_SAME_SITE_KIND values. + /// + COREWEBVIEW2_COOKIE_SAME_SITE_KIND_STRICT = $00000002; + +type + /// + /// Kind of cross origin resource access allowed for host resources during download. + /// Note that other normal access checks like same origin DOM access check and [Content + /// Security Policy](https://developer.mozilla.org/docs/Web/HTTP/CSP) still apply. + /// + /// The following table illustrates the host resource cross origin access according to + /// access context and COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND. + /// + /// Cross Origin Access Context | DENY | ALLOW | DENY_CORS + /// --- | --- | --- | --- + /// From DOM like src of img, script or iframe element| Deny | Allow | Allow + /// From Script like Fetch or XMLHttpRequest| Deny | Allow | Deny + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND = TOleEnum; +const + /// + /// All cross origin resource access is denied, including normal sub resource access + /// as src of a script or image element. + /// + /// + /// This is one of the COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND values. + /// + COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_DENY = $00000000; + /// + /// All cross origin resource access is allowed, including accesses that are + /// subject to Cross-Origin Resource Sharing(CORS) check. The behavior is similar to + /// a web site sends back http header Access-Control-Allow-Origin: *. + /// + /// + /// This is one of the COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND values. + /// + COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_ALLOW = $00000001; + /// + /// Cross origin resource access is allowed for normal sub resource access like + /// as src of a script or image element, while any access that subjects to CORS check + /// will be denied. + /// See [Cross-Origin Resource Sharing](https://developer.mozilla.org/docs/Web/HTTP/CORS) + /// for more information. + /// + /// + /// This is one of the COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND values. + /// + COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_DENY_CORS = $00000002; + +type + /// + /// State of the download operation. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_DOWNLOAD_STATE = TOleEnum; +const + /// + /// The download is in progress. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_STATE values. + /// + COREWEBVIEW2_DOWNLOAD_STATE_IN_PROGRESS = $00000000; + /// + /// The connection with the file host was broken. The InterruptReason property + /// can be accessed from ICoreWebView2DownloadOperation. See + /// COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON for descriptions of kinds of + /// interrupt reasons. Host can check whether an interrupted download can be + /// resumed with the CanResume property on the ICoreWebView2DownloadOperation. + /// Once resumed, a download is in the COREWEBVIEW2_DOWNLOAD_STATE_IN_PROGRESS state. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_STATE values. + /// + COREWEBVIEW2_DOWNLOAD_STATE_INTERRUPTED = $00000001; + /// + /// The download completed successfully. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_STATE values. + /// + COREWEBVIEW2_DOWNLOAD_STATE_COMPLETED = $00000002; + +type + /// + /// Reason why a download was interrupted. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON = TOleEnum; +const + /// + /// No reason. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_NONE = $00000000; + /// + /// Generic file error. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_FILE_FAILED = $00000001; + /// + /// Access denied due to security restrictions. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED = $00000002; + /// + /// Disk full. User should free some space or choose a different location to + /// store the file. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE = $00000003; + /// + /// Result file path with file name is too long. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_FILE_NAME_TOO_LONG = $00000004; + /// + /// File is too large for file system. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_FILE_TOO_LARGE = $00000005; + /// + /// Microsoft Defender Smartscreen detected a virus in the file. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_FILE_MALICIOUS = $00000006; + /// + /// File was in use, too many files opened, or out of memory. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR = $00000007; + /// + /// File blocked by local policy. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED_BY_POLICY = $00000008; + /// + /// Security check failed unexpectedly. Microsoft Defender SmartScreen could + /// not scan this file. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_FILE_SECURITY_CHECK_FAILED = $00000009; + /// + /// Seeking past the end of a file in opening a file, as part of resuming an + /// interrupted download. The file did not exist or was not as large as + /// expected. Partially downloaded file was truncated or deleted, and download + /// will be restarted automatically. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT = $0000000A; + /// + /// Partial file did not match the expected hash and was deleted. Download + /// will be restarted automatically. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH = $0000000B; + /// + /// Generic network error. User can retry the download manually. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED = $0000000C; + /// + /// Network operation timed out. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT = $0000000D; + /// + /// Network connection lost. User can retry the download manually. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED = $0000000E; + /// + /// Server has gone down. User can retry the download manually. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN = $0000000F; + /// + /// Network request invalid because original or redirected URI is invalid, has + /// an unsupported scheme, or is disallowed by network policy. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_NETWORK_INVALID_REQUEST = $00000010; + /// + /// Generic server error. User can retry the download manually. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED = $00000011; + /// + /// Server does not support range requests. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE = $00000012; + /// + /// Server does not have the requested data. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT = $00000013; + /// + /// Server did not authorize access to resource. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_SERVER_UNAUTHORIZED = $00000014; + /// + /// Server certificate problem. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_SERVER_CERTIFICATE_PROBLEM = $00000015; + /// + /// Server access forbidden. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_SERVER_FORBIDDEN = $00000016; + /// + /// Unexpected server response. Responding server may not be intended server. + /// User can retry the download manually. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_SERVER_UNEXPECTED_RESPONSE = $00000017; + /// + /// Server sent fewer bytes than the Content-Length header. Content-length + /// header may be invalid or connection may have closed. Download is treated + /// as complete unless there are + /// [strong validators](https://tools.ietf.org/html/rfc7232#section-2) present + /// to interrupt the download. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_SERVER_CONTENT_LENGTH_MISMATCH = $00000018; + /// + /// Unexpected cross-origin redirect. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_SERVER_CROSS_ORIGIN_REDIRECT = $00000019; + /// + /// User canceled the download. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_USER_CANCELED = $0000001A; + /// + /// User shut down the WebView. Resuming downloads that were interrupted + /// during shutdown is not yet supported. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN = $0000001B; + /// + /// User paused the download. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_USER_PAUSED = $0000001C; + /// + /// WebView crashed. + /// + /// + /// This is one of the COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON values. + /// + COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_DOWNLOAD_PROCESS_CRASHED = $0000001D; + +type + /// + /// Specifies the client certificate kind. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_CLIENT_CERTIFICATE_KIND = TOleEnum; +const + /// + /// Specifies smart card certificate. + /// + /// + /// This is one of the COREWEBVIEW2_CLIENT_CERTIFICATE_KIND values. + /// + COREWEBVIEW2_CLIENT_CERTIFICATE_KIND_SMART_CARD = $00000000; + /// + /// Specifies PIN certificate. + /// + /// + /// This is one of the COREWEBVIEW2_CLIENT_CERTIFICATE_KIND values. + /// + COREWEBVIEW2_CLIENT_CERTIFICATE_KIND_PIN = $00000001; + /// + /// Specifies other certificate. + /// + /// + /// This is one of the COREWEBVIEW2_CLIENT_CERTIFICATE_KIND values. + /// + COREWEBVIEW2_CLIENT_CERTIFICATE_KIND_OTHER = $00000002; + +type + /// + /// The orientation for printing, used by the Orientation property on + /// ICoreWebView2PrintSettings. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_PRINT_ORIENTATION = TOleEnum; +const + /// + /// Print the page(s) in portrait orientation. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_ORIENTATION values. + /// + COREWEBVIEW2_PRINT_ORIENTATION_PORTRAIT = $00000000; + /// + /// Print the page(s) in landscape orientation. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_ORIENTATION values. + /// + COREWEBVIEW2_PRINT_ORIENTATION_LANDSCAPE = $00000001; + +type + /// + /// The default download dialog can be aligned to any of the WebView corners + /// by setting the DefaultDownloadDialogCornerAlignment property. The default + /// position is top-right corner. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_DEFAULT_DOWNLOAD_DIALOG_CORNER_ALIGNMENT = TOleEnum; +const + /// + /// Top-left corner of the WebView. + /// + /// + /// This is one of the COREWEBVIEW2_DEFAULT_DOWNLOAD_DIALOG_CORNER_ALIGNMENT values. + /// + COREWEBVIEW2_DEFAULT_DOWNLOAD_DIALOG_CORNER_ALIGNMENT_TOP_LEFT = $00000000; + /// + /// Top-right corner of the WebView. + /// + /// + /// This is one of the COREWEBVIEW2_DEFAULT_DOWNLOAD_DIALOG_CORNER_ALIGNMENT values. + /// + COREWEBVIEW2_DEFAULT_DOWNLOAD_DIALOG_CORNER_ALIGNMENT_TOP_RIGHT = $00000001; + /// + /// Bottom-left corner of the WebView. + /// + /// + /// This is one of the COREWEBVIEW2_DEFAULT_DOWNLOAD_DIALOG_CORNER_ALIGNMENT values. + /// + COREWEBVIEW2_DEFAULT_DOWNLOAD_DIALOG_CORNER_ALIGNMENT_BOTTOM_LEFT = $00000002; + /// + /// Bottom-right corner of the WebView. + /// + /// + /// This is one of the COREWEBVIEW2_DEFAULT_DOWNLOAD_DIALOG_CORNER_ALIGNMENT values. + /// + COREWEBVIEW2_DEFAULT_DOWNLOAD_DIALOG_CORNER_ALIGNMENT_BOTTOM_RIGHT = $00000003; + +type + /// + /// Specifies the menu item kind + /// for the ICoreWebView2ContextMenuItem.get_Kind method + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND = TOleEnum; +const + /// + /// Specifies a command menu item kind. + /// + /// + /// This is one of the COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND values. + /// + COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND_COMMAND = $00000000; + /// + /// Specifies a check box menu item kind. ContextMenuItem objects of this kind + /// will need the IsChecked property to determine current state of the check box. + /// + /// + /// This is one of the COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND values. + /// + COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND_CHECK_BOX = $00000001; + /// + /// Specifies a radio button menu item kind. ContextMenuItem objects of this kind + /// will need the IsChecked property to determine current state of the radio button. + /// + /// + /// This is one of the COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND values. + /// + COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND_RADIO = $00000002; + /// + /// Specifies a separator menu item kind. ContextMenuItem objects of this kind + /// are used to signal a visual separator with no functionality. + /// + /// + /// This is one of the COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND values. + /// + COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND_SEPARATOR = $00000003; + /// + /// Specifies a submenu menu item kind. ContextMenuItem objects of this kind will contain + /// a ContextMenuItemCollection of its children ContextMenuItem objects. + /// + /// + /// This is one of the COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND values. + /// + COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND_SUBMENU = $00000004; + +type + /// + /// Indicates the kind of context for which the context menu was created + /// for the ICoreWebView2ContextMenuTarget::get_Kind method. + /// This enum will always represent the active element that caused the context menu request. + /// If there is a selection with multiple images, audio and text, for example, the element that + /// the end user right clicks on within this selection will be the option represented by this enum. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND = TOleEnum; +const + /// + /// Indicates that the context menu was created for the page without any additional content. + /// + /// + /// This is one of the COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND values. + /// + COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND_PAGE = $00000000; + /// + /// Indicates that the context menu was created for an image element. + /// + /// + /// This is one of the COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND values. + /// + COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND_IMAGE = $00000001; + /// + /// Indicates that the context menu was created for selected text. + /// + /// + /// This is one of the COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND values. + /// + COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND_SELECTED_TEXT = $00000002; + /// + /// Indicates that the context menu was created for an audio element. + /// + /// + /// This is one of the COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND values. + /// + COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND_AUDIO = $00000003; + /// + /// Indicates that the context menu was created for a video element. + /// + /// + /// This is one of the COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND values. + /// + COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND_VIDEO = $00000004; + +type + /// + /// An enum to represent the options for WebView2 color scheme: auto, light, or dark. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_PREFERRED_COLOR_SCHEME = TOleEnum; +const + /// + /// Auto color scheme. + /// + /// + /// This is one of the COREWEBVIEW2_PREFERRED_COLOR_SCHEME values. + /// + COREWEBVIEW2_PREFERRED_COLOR_SCHEME_AUTO = $00000000; + /// + /// Light color scheme. + /// + /// + /// This is one of the COREWEBVIEW2_PREFERRED_COLOR_SCHEME values. + /// + COREWEBVIEW2_PREFERRED_COLOR_SCHEME_LIGHT = $00000001; + /// + /// Dark color scheme. + /// + /// + /// This is one of the COREWEBVIEW2_PREFERRED_COLOR_SCHEME values. + /// + COREWEBVIEW2_PREFERRED_COLOR_SCHEME_DARK = $00000002; + +type + /// + /// Specifies the action type when server certificate error is detected to be + /// used in the ICoreWebView2ServerCertificateErrorDetectedEventArgs + /// interface. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_SERVER_CERTIFICATE_ERROR_ACTION = TOleEnum; +const + /// + /// Indicates to ignore the warning and continue the request with the TLS + /// certificate. This decision is cached for the RequestUri's host and the + /// server certificate in the session. + /// + /// + /// This is one of the COREWEBVIEW2_SERVER_CERTIFICATE_ERROR_ACTION values. + /// + COREWEBVIEW2_SERVER_CERTIFICATE_ERROR_ACTION_ALWAYS_ALLOW = $00000000; + /// + /// Indicates to reject the certificate and cancel the request. + /// + /// + /// This is one of the COREWEBVIEW2_SERVER_CERTIFICATE_ERROR_ACTION values. + /// + COREWEBVIEW2_SERVER_CERTIFICATE_ERROR_ACTION_CANCEL = $00000001; + /// + /// Indicates to display the default TLS interstitial error page to user for + /// page navigations. + /// For others TLS certificate is rejected and the request is cancelled. + /// + /// + /// This is one of the COREWEBVIEW2_SERVER_CERTIFICATE_ERROR_ACTION values. + /// + COREWEBVIEW2_SERVER_CERTIFICATE_ERROR_ACTION_DEFAULT = $00000002; + +type + /// + /// Specifies the image format to use for favicon. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_FAVICON_IMAGE_FORMAT = TOleEnum; +const + /// + /// Indicates that the PNG image format is used. + /// + /// + /// This is one of the COREWEBVIEW2_FAVICON_IMAGE_FORMAT values. + /// + COREWEBVIEW2_FAVICON_IMAGE_FORMAT_PNG = $00000000; + /// + /// Indicates the JPEG image format is used. + /// + /// + /// This is one of the COREWEBVIEW2_FAVICON_IMAGE_FORMAT values. + /// + COREWEBVIEW2_FAVICON_IMAGE_FORMAT_JPEG = $00000001; + +type + /// + /// Indicates the status for printing. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_PRINT_STATUS = TOleEnum; +const + /// + /// Indicates that the print operation is succeeded. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_STATUS values. + /// + COREWEBVIEW2_PRINT_STATUS_SUCCEEDED = $00000000; + /// + /// Indicates that the printer is not available. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_STATUS values. + /// + COREWEBVIEW2_PRINT_STATUS_PRINTER_UNAVAILABLE = $00000001; + /// + /// Indicates that the print operation is failed. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_STATUS values. + /// + COREWEBVIEW2_PRINT_STATUS_OTHER_ERROR = $00000002; + +type + /// + /// Specifies the print dialog kind. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_PRINT_DIALOG_KIND = TOleEnum; +const + /// + /// Opens the browser print preview dialog. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_DIALOG_KIND values. + /// + COREWEBVIEW2_PRINT_DIALOG_KIND_BROWSER = $00000000; + /// + /// Opens the system print dialog. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_DIALOG_KIND values. + /// + COREWEBVIEW2_PRINT_DIALOG_KIND_SYSTEM = $00000001; + +type + /// + /// Specifies the desired access from script to CoreWebView2SharedBuffer. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_SHARED_BUFFER_ACCESS = TOleEnum; +const + /// + /// Script from web page only has read access to the shared buffer. + /// + /// + /// This is one of the COREWEBVIEW2_SHARED_BUFFER_ACCESS values. + /// + COREWEBVIEW2_SHARED_BUFFER_ACCESS_READ_ONLY = $00000000; + /// + /// Script from web page has read and write access to the shared buffer. + /// + /// + /// This is one of the COREWEBVIEW2_SHARED_BUFFER_ACCESS values. + /// + COREWEBVIEW2_SHARED_BUFFER_ACCESS_READ_WRITE = $00000001; + +type + /// + /// Indicates the text direction of the notification. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_TEXT_DIRECTION_KIND = TOleEnum; +const + /// + /// Indicates that the notification text direction adopts the browser's language setting behavior. + /// + /// + /// This is one of the COREWEBVIEW2_TEXT_DIRECTION_KIND values. + /// + COREWEBVIEW2_TEXT_DIRECTION_KIND_DEFAULT = $00000000; + /// + /// Indicates that the notification text is left-to-right. + /// + /// + /// This is one of the COREWEBVIEW2_TEXT_DIRECTION_KIND values. + /// + COREWEBVIEW2_TEXT_DIRECTION_KIND_LEFT_TO_RIGHT = $00000001; + /// + /// Indicates that the notification text is right-to-left. + /// + /// + /// This is one of the COREWEBVIEW2_TEXT_DIRECTION_KIND values. + /// + COREWEBVIEW2_TEXT_DIRECTION_KIND_RIGHT_TO_LEFT = $00000002; + +type + /// + /// Specifies Save As kind selection options for + /// `ICoreWebView2SaveAsUIShowingEventArgs`. + /// + /// For HTML documents, we support 3 Save As kinds: HTML_ONLY, SINGLE_FILE and + /// COMPLETE. For non-HTML documents, you must use DEFAULT. MIME types of `text/html` and + /// `application/xhtml+xml` are considered HTML documents. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_SAVE_AS_KIND = TOleEnum; +const + /// + /// Default kind to save non-HTML content. If this kind is selected for an HTML + /// page, the behavior is the same as the `HTML_ONLY` kind. + /// + /// + /// This is one of the COREWEBVIEW2_SAVE_AS_KIND values. + /// + COREWEBVIEW2_SAVE_AS_KIND_DEFAULT = $00000000; + /// + /// Save the page as HTML. Only the top-level document is saved, excluding + /// subresources. + /// + /// + /// This is one of the COREWEBVIEW2_SAVE_AS_KIND values. + /// + COREWEBVIEW2_SAVE_AS_KIND_HTML_ONLY = $00000001; + /// + /// Save the page as [MHTML](https://en.wikipedia.org/wiki/MHTML). + /// + /// + /// This is one of the COREWEBVIEW2_SAVE_AS_KIND values. + /// + COREWEBVIEW2_SAVE_AS_KIND_SINGLE_FILE = $00000002; + /// + /// Save the page as HTML and download the page-related source files + /// (for example: CSS, JavaScript, images, etc.) in a directory with + /// the same filename prefix. + /// + /// + /// This is one of the COREWEBVIEW2_SAVE_AS_KIND values. + /// + COREWEBVIEW2_SAVE_AS_KIND_COMPLETE = $00000003; + +type + /// + /// Status of a programmatic Save As call. Indicates the result + /// of the `ShowSaveAsUI` method. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_SAVE_AS_UI_RESULT = TOleEnum; +const + /// + /// The ShowSaveAsUI method call completed successfully. By default, the system + /// Save As dialog opens. If `SuppressDefaultDialog` is set to TRUE, the system + /// dialog is skipped. + /// + /// + /// This is one of the COREWEBVIEW2_SAVE_AS_UI_RESULT values. + /// + COREWEBVIEW2_SAVE_AS_UI_RESULT_SUCCESS = $00000000; + /// + /// Could not perform Save As because the destination file path is an invalid path. + /// + /// The path is invalid when it is empty, a relative path, or a directory, + /// or when the parent path does not exist. + /// + /// + /// This is one of the COREWEBVIEW2_SAVE_AS_UI_RESULT values. + /// + COREWEBVIEW2_SAVE_AS_UI_RESULT_INVALID_PATH = $00000001; + /// + /// Could not perform Save As because the destination file path already exists and + /// replacing files was not allowed by the `AllowReplace` property. + /// + /// + /// This is one of the COREWEBVIEW2_SAVE_AS_UI_RESULT values. + /// + COREWEBVIEW2_SAVE_AS_UI_RESULT_FILE_ALREADY_EXISTS = $00000002; + /// + /// Could not perform Save As because the `Kind` property selection is not + /// supported due to content MIME type or system limits. + /// + /// See the `COREWEBVIEW2_SAVE_AS_KIND` enum for MIME type limits. + /// + /// System limits include when the `HTML_ONLY` kind is selected for an error page + /// at child mode, or when the `COMPLETE` kind is selected and the WebView is + /// running in an App Container. + /// + /// + /// This is one of the COREWEBVIEW2_SAVE_AS_UI_RESULT values. + /// + COREWEBVIEW2_SAVE_AS_UI_RESULT_KIND_NOT_SUPPORTED = $00000003; + /// + /// Did not perform Save As because the end user cancelled or the + /// `Cancel` property on `ICoreWebView2SaveAsUIShowingEventArgs` was set to TRUE. + /// + /// + /// This is one of the COREWEBVIEW2_SAVE_AS_UI_RESULT values. + /// + COREWEBVIEW2_SAVE_AS_UI_RESULT_CANCELLED = $00000004; + +type + /// + /// Specifies the browser process exit type used in the + /// ICoreWebView2BrowserProcessExitedEventArgs interface. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_BROWSER_PROCESS_EXIT_KIND = TOleEnum; +const + /// + /// Indicates that the browser process ended normally. + /// + /// + /// This is one of the COREWEBVIEW2_BROWSER_PROCESS_EXIT_KIND values. + /// + COREWEBVIEW2_BROWSER_PROCESS_EXIT_KIND_NORMAL = $00000000; + /// + /// Indicates that the browser process ended unexpectedly. + /// A ProcessFailed event will also be sent to listening WebViews from the + /// ICoreWebView2Environment associated to the failed process. + /// + /// + /// This is one of the COREWEBVIEW2_BROWSER_PROCESS_EXIT_KIND values. + /// + COREWEBVIEW2_BROWSER_PROCESS_EXIT_KIND_FAILED = $00000001; + +type + /// + /// Mouse event type used by SendMouseInput to convey the type of mouse event + /// being sent to WebView. The values of this enum align with the matching + /// WM_* window messages. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND = TOleEnum; +const + /// + /// Mouse horizontal wheel scroll event, WM_MOUSEHWHEEL. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_KIND values. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND_HORIZONTAL_WHEEL = 526; + /// + /// Left button double click mouse event, WM_LBUTTONDBLCLK. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_KIND values. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND_LEFT_BUTTON_DOUBLE_CLICK = 515; + /// + /// Left button down mouse event, WM_LBUTTONDOWN. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_KIND values. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND_LEFT_BUTTON_DOWN = 513; + /// + /// Left button up mouse event, WM_LBUTTONUP. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_KIND values. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND_LEFT_BUTTON_UP = 514; + /// + /// Mouse leave event, WM_MOUSELEAVE. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_KIND values. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND_LEAVE = 675; + /// + /// Middle button double click mouse event, WM_MBUTTONDBLCLK. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_KIND values. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND_MIDDLE_BUTTON_DOUBLE_CLICK = 521; + /// + /// Middle button down mouse event, WM_MBUTTONDOWN. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_KIND values. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND_MIDDLE_BUTTON_DOWN = 519; + /// + /// Middle button up mouse event, WM_MBUTTONUP. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_KIND values. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND_MIDDLE_BUTTON_UP = 520; + /// + /// Mouse move event, WM_MOUSEMOVE. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_KIND values. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND_MOVE = 512; + /// + /// Right button double click mouse event, WM_RBUTTONDBLCLK. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_KIND values. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND_RIGHT_BUTTON_DOUBLE_CLICK = 518; + /// + /// Right button down mouse event, WM_RBUTTONDOWN. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_KIND values. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND_RIGHT_BUTTON_DOWN = 516; + /// + /// Right button up mouse event, WM_RBUTTONUP. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_KIND values. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND_RIGHT_BUTTON_UP = 517; + /// + /// Mouse wheel scroll event, WM_MOUSEWHEEL. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_KIND values. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND_WHEEL = 522; + /// + /// First or second X button double click mouse event, WM_XBUTTONDBLCLK. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_KIND values. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND_X_BUTTON_DOUBLE_CLICK = 525; + /// + /// First or second X button down mouse event, WM_XBUTTONDOWN. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_KIND values. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND_X_BUTTON_DOWN = 523; + /// + /// First or second X button up mouse event, WM_XBUTTONUP. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_KIND values. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND_X_BUTTON_UP = 524; + /// + /// Mouse Right Button Down event over a nonclient area, WM_NCRBUTTONDOWN. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_KIND values. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND_NON_CLIENT_RIGHT_BUTTON_DOWN = 164; + /// + /// Mouse Right Button up event over a nonclient area, WM_NCRBUTTONUP. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_KIND values. + /// + COREWEBVIEW2_MOUSE_EVENT_KIND_NON_CLIENT_RIGHT_BUTTON_UP = 165; + +type + /// + /// Mouse event virtual keys associated with a COREWEBVIEW2_MOUSE_EVENT_KIND for + /// SendMouseInput. These values can be combined into a bit flag if more than + /// one virtual key is pressed for the event. The values of this enum align + /// with the matching MK_* mouse keys. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS = TOleEnum; +const + /// + /// No additional keys pressed. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS values. + /// + COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS_NONE = $00000000; + /// + /// Left mouse button is down, MK_LBUTTON. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS values. + /// + COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS_LEFT_BUTTON = $00000001; + /// + /// Right mouse button is down, MK_RBUTTON. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS values. + /// + COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS_RIGHT_BUTTON = $00000002; + /// + /// SHIFT key is down, MK_SHIFT. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS values. + /// + COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS_SHIFT = $00000004; + /// + /// CTRL key is down, MK_CONTROL. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS values. + /// + COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS_CONTROL = $00000008; + /// + /// Middle mouse button is down, MK_MBUTTON. + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS values. + /// + COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS_MIDDLE_BUTTON = $00000010; + /// + /// First X button is down, MK_XBUTTON1 + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS values. + /// + COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS_X_BUTTON1 = $00000020; + /// + /// Second X button is down, MK_XBUTTON2 + /// + /// + /// This is one of the COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS values. + /// + COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS_X_BUTTON2 = $00000040; + +type + /// + /// Pointer event type used by SendPointerInput to convey the type of pointer + /// event being sent to WebView. The values of this enum align with the + /// matching WM_POINTER* window messages. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_POINTER_EVENT_KIND = TOleEnum; +const + /// + /// Corresponds to WM_POINTERACTIVATE. + /// + /// + /// This is one of the COREWEBVIEW2_POINTER_EVENT_KIND values. + /// + COREWEBVIEW2_POINTER_EVENT_KIND_ACTIVATE = $0000024B; + /// + /// Corresponds to WM_POINTERDOWN. + /// + /// + /// This is one of the COREWEBVIEW2_POINTER_EVENT_KIND values. + /// + COREWEBVIEW2_POINTER_EVENT_KIND_DOWN = $00000246; + /// + /// Corresponds to WM_POINTERENTER. + /// + /// + /// This is one of the COREWEBVIEW2_POINTER_EVENT_KIND values. + /// + COREWEBVIEW2_POINTER_EVENT_KIND_ENTER = $00000249; + /// + /// Corresponds to WM_POINTERLEAVE. + /// + /// + /// This is one of the COREWEBVIEW2_POINTER_EVENT_KIND values. + /// + COREWEBVIEW2_POINTER_EVENT_KIND_LEAVE = $0000024A; + /// + /// Corresponds to WM_POINTERUP. + /// + /// + /// This is one of the COREWEBVIEW2_POINTER_EVENT_KIND values. + /// + COREWEBVIEW2_POINTER_EVENT_KIND_UP = $00000247; + /// + /// Corresponds to WM_POINTERUPDATE. + /// + /// + /// This is one of the COREWEBVIEW2_POINTER_EVENT_KIND values. + /// + COREWEBVIEW2_POINTER_EVENT_KIND_UPDATE = $00000245; + +type + /// + /// Mode for how the Bounds property is interpreted in relation to the RasterizationScale property. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_BOUNDS_MODE = TOleEnum; +const + /// + /// Bounds property represents raw pixels. Physical size of Webview is not impacted by RasterizationScale. + /// + /// + /// This is one of the COREWEBVIEW2_BOUNDS_MODE values. + /// + COREWEBVIEW2_BOUNDS_MODE_USE_RAW_PIXELS = $00000000; + /// + /// Bounds property represents logical pixels and the RasterizationScale property is used to get the physical size of the WebView. + /// + /// + /// This is one of the COREWEBVIEW2_BOUNDS_MODE values. + /// + COREWEBVIEW2_BOUNDS_MODE_USE_RASTERIZATION_SCALE = $00000001; + +type + /// + /// Indicates the process type used in the ICoreWebView2ProcessInfo interface. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_PROCESS_KIND = TOleEnum; +const + /// + /// Indicates the browser process kind. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_KIND values. + /// + COREWEBVIEW2_PROCESS_KIND_BROWSER = $00000000; + /// + /// Indicates the render process kind. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_KIND values. + /// + COREWEBVIEW2_PROCESS_KIND_RENDERER = $00000001; + /// + /// Indicates the utility process kind. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_KIND values. + /// + COREWEBVIEW2_PROCESS_KIND_UTILITY = $00000002; + /// + /// Indicates the sandbox helper process kind. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_KIND values. + /// + COREWEBVIEW2_PROCESS_KIND_SANDBOX_HELPER = $00000003; + /// + /// Indicates the GPU process kind. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_KIND values. + /// + COREWEBVIEW2_PROCESS_KIND_GPU = $00000004; + /// + /// Indicates the PPAPI plugin process kind. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_KIND values. + /// + COREWEBVIEW2_PROCESS_KIND_PPAPI_PLUGIN = $00000005; + /// + /// Indicates the PPAPI plugin broker process kind. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_KIND values. + /// + COREWEBVIEW2_PROCESS_KIND_PPAPI_BROKER = $00000006; + +type + /// + /// Allowed permissions of a CoreWebView2FileSystemHandle as described in + /// [FileSystemHandle.requestPermission()](https://developer.mozilla.org/docs/Web/API/FileSystemHandle/requestPermission) + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_FILE_SYSTEM_HANDLE_PERMISSION = TOleEnum; +const + /// + /// Read-only permission for FileSystemHandle. + /// + /// + /// This is one of the COREWEBVIEW2_FILE_SYSTEM_HANDLE_PERMISSION values. + /// + COREWEBVIEW2_FILE_SYSTEM_HANDLE_PERMISSION_READ_ONLY = $00000000; + /// + /// Read and write permissions for FileSystemHandle. + /// + /// + /// This is one of the COREWEBVIEW2_FILE_SYSTEM_HANDLE_PERMISSION values. + /// + COREWEBVIEW2_FILE_SYSTEM_HANDLE_PERMISSION_READ_WRITE = $00000001; + +type + /// + /// Kind of CoreWebView2FileSystemHandle as described in + /// [FileSystemHandle.kind](https://developer.mozilla.org/docs/Web/API/FileSystemHandle/kind) + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_FILE_SYSTEM_HANDLE_KIND = TOleEnum; +const + /// + /// FileSystemHandle is for a file + /// (i.e. [FileSystemFileHandle](https://developer.mozilla.org/docs/Web/API/FileSystemFileHandle)) + /// + /// + /// This is one of the COREWEBVIEW2_FILE_SYSTEM_HANDLE_KIND values. + /// + COREWEBVIEW2_FILE_SYSTEM_HANDLE_KIND_FILE = $00000000; + /// + /// FileSystemHandle is for a directory + /// (i.e. [FileSystemDirectoryHandle](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryHandle)) + /// + /// + /// This is one of the COREWEBVIEW2_FILE_SYSTEM_HANDLE_KIND values. + /// + COREWEBVIEW2_FILE_SYSTEM_HANDLE_KIND_DIRECTORY = $00000001; + +type + /// + /// The channel search kind determines the order that release channels are + /// searched for during environment creation. The default behavior is to search + /// for and use the most stable channel found on the device. The order from most + /// to least stable is: WebView2 Runtime -> Beta -> Dev -> Canary. Switch the + /// order to prefer the least stable channel in order to perform pre-release + /// testing. See `COREWEBVIEW2_RELEASE_CHANNELS` for descriptions of channels. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_CHANNEL_SEARCH_KIND = TOleEnum; +const + /// + /// Search for a release channel from most to least stable: + /// WebView2 Runtime -> Beta -> Dev -> Canary. This is the default behavior. + /// + /// + /// This is one of the COREWEBVIEW2_CHANNEL_SEARCH_KIND values. + /// + COREWEBVIEW2_CHANNEL_SEARCH_KIND_MOST_STABLE = $00000000; + /// + /// Search for a release channel from least to most stable: + /// Canary -> Dev -> Beta -> WebView2 Runtime. + /// + /// + /// This is one of the COREWEBVIEW2_CHANNEL_SEARCH_KIND values. + /// + COREWEBVIEW2_CHANNEL_SEARCH_KIND_LEAST_STABLE = $00000001; + +type + /// + /// The WebView2 release channels. Use `ReleaseChannels` and `ChannelSearchKind` + /// on `ICoreWebView2EnvironmentOptions` to control which channel is searched + /// for during environment creation. + /// + /// |Channel|Primary purpose|How often updated with new features| + /// |:---:|---|:---:| + /// |Stable (WebView2 Runtime)|Broad Deployment|Monthly| + /// |Beta|Flighting with inner rings, automated testing|Monthly| + /// |Dev|Automated testing, selfhosting to test new APIs and features|Weekly| + /// |Canary|Automated testing, selfhosting to test new APIs and features|Daily| + /// + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_RELEASE_CHANNELS = TOleEnum; +const + /// + /// No release channel. Passing only this value to `ReleaseChannels` results + /// in HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND). + /// + /// + /// This is one of the COREWEBVIEW2_RELEASE_CHANNELS values. + /// + COREWEBVIEW2_RELEASE_CHANNELS_NONE = $00000000; + /// + /// The stable WebView2 Runtime that is released every 4 weeks. + /// + /// + /// This is one of the COREWEBVIEW2_RELEASE_CHANNELS values. + /// + COREWEBVIEW2_RELEASE_CHANNELS_STABLE = $00000001; + /// + /// The Beta release channel that is released every 4 weeks, a week before the + /// stable release. + /// + /// + /// This is one of the COREWEBVIEW2_RELEASE_CHANNELS values. + /// + COREWEBVIEW2_RELEASE_CHANNELS_BETA = $00000002; + /// + /// The Dev release channel that is released weekly. + /// + /// + /// This is one of the COREWEBVIEW2_RELEASE_CHANNELS values. + /// + COREWEBVIEW2_RELEASE_CHANNELS_DEV = $00000004; + /// + /// The Canary release channel that is released daily. + /// + /// + /// This is one of the COREWEBVIEW2_RELEASE_CHANNELS values. + /// + COREWEBVIEW2_RELEASE_CHANNELS_CANARY = $00000008; + +type + /// + /// Set ScrollBar style on `ICoreWebView2EnvironmentOptions` during environment creation. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_SCROLLBAR_STYLE = TOleEnum; +const + /// + /// Browser default ScrollBar style. + /// + /// + /// This is one of the COREWEBVIEW2_SCROLLBAR_STYLE values. + /// + COREWEBVIEW2_SCROLLBAR_STYLE_DEFAULT = $00000000; + /// + /// Window style fluent overlay scroll bar. + /// Please see [Fluent UI](https://developer.microsoft.com/fluentui#/) + /// for more details on fluent UI. + /// + /// + /// This is one of the COREWEBVIEW2_SCROLLBAR_STYLE values. + /// + COREWEBVIEW2_SCROLLBAR_STYLE_FLUENT_OVERLAY = $00000001; + +type + /// + /// Indicates the frame type used in the `ICoreWebView2FrameInfo` interface. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_FRAME_KIND = TOleEnum; +const + /// + /// Indicates that the frame is an unknown type frame. We may extend this enum + /// type to identify more frame kinds in the future. + /// + /// + /// This is one of the COREWEBVIEW2_FRAME_KIND values. + /// + COREWEBVIEW2_FRAME_KIND_UNKNOWN = $00000000; + /// + /// Indicates that the frame is a primary main frame(webview). + /// + /// + /// This is one of the COREWEBVIEW2_FRAME_KIND values. + /// + COREWEBVIEW2_FRAME_KIND_MAIN_FRAME = $00000001; + /// + /// Indicates that the frame is an iframe. + /// + /// + /// This is one of the COREWEBVIEW2_FRAME_KIND values. + /// + COREWEBVIEW2_FRAME_KIND_IFRAME = $00000002; + /// + /// Indicates that the frame is an embed element. + /// + /// + /// This is one of the COREWEBVIEW2_FRAME_KIND values. + /// + COREWEBVIEW2_FRAME_KIND_EMBED = $00000003; + /// + /// Indicates that the frame is an object element. + /// + /// + /// This is one of the COREWEBVIEW2_FRAME_KIND values. + /// + COREWEBVIEW2_FRAME_KIND_OBJECT = $00000004; + + +type + /// + /// Specifies the navigation kind of each navigation. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_NAVIGATION_KIND = TOleEnum; +const + /// + /// A navigation caused by CoreWebView2.Reload(), location.reload(), the end user + /// using F5 or other UX, or other reload mechanisms to reload the current document + /// without modifying the navigation history. + /// + /// + /// This is one of the COREWEBVIEW2_NAVIGATION_KIND values. + /// + COREWEBVIEW2_NAVIGATION_KIND_RELOAD = $00000000; + /// + /// A navigation back or forward to a different entry in the session navigation history, + /// like via CoreWebView2.Back(), location.back(), the end user pressing Alt+Left + /// or other UX, or other mechanisms to navigate back or forward in the current + /// session navigation history. + /// + /// + /// This is one of the COREWEBVIEW2_NAVIGATION_KIND values. + /// + COREWEBVIEW2_NAVIGATION_KIND_BACK_OR_FORWARD = $00000001; + /// + /// A navigation to another document, which can be caused by CoreWebView2.Navigate(), + /// window.location.href = ..., or other WebView2 or DOM APIs that navigate to a new URI. + /// + /// + /// This is one of the COREWEBVIEW2_NAVIGATION_KIND values. + /// + COREWEBVIEW2_NAVIGATION_KIND_NEW_DOCUMENT = $00000002; + +type + /// + /// Specifies the collation for a print. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_PRINT_COLLATION = TOleEnum; +const + /// + /// The default collation for a printer. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_COLLATION values. + /// + COREWEBVIEW2_PRINT_COLLATION_DEFAULT = $00000000; + /// + /// Indicate that the collation has been selected for the printed output. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_COLLATION values. + /// + COREWEBVIEW2_PRINT_COLLATION_COLLATED = $00000001; + /// + /// Indicate that the collation has not been selected for the printed output. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_COLLATION values. + /// + COREWEBVIEW2_PRINT_COLLATION_UNCOLLATED = $00000002; + +type + /// + /// Specifies the color mode for a print. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_PRINT_COLOR_MODE = TOleEnum; +const + /// + /// The default color mode for a printer. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_COLOR_MODE values. + /// + COREWEBVIEW2_PRINT_COLOR_MODE_DEFAULT = $00000000; + /// + /// Indicate that the printed output will be in color. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_COLOR_MODE values. + /// + COREWEBVIEW2_PRINT_COLOR_MODE_COLOR = $00000001; + /// + /// Indicate that the printed output will be in shades of gray. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_COLOR_MODE values. + /// + COREWEBVIEW2_PRINT_COLOR_MODE_GRAYSCALE = $00000002; + +type + /// + /// Specifies the duplex option for a print. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_PRINT_DUPLEX = TOleEnum; +const + /// + /// The default duplex for a printer. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_DUPLEX values. + /// + COREWEBVIEW2_PRINT_DUPLEX_DEFAULT = $00000000; + /// + /// Print on only one side of the sheet. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_DUPLEX values. + /// + COREWEBVIEW2_PRINT_DUPLEX_ONE_SIDED = $00000001; + /// + /// Print on both sides of the sheet, flipped along the long edge. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_DUPLEX values. + /// + COREWEBVIEW2_PRINT_DUPLEX_TWO_SIDED_LONG_EDGE = $00000002; + /// + /// Print on both sides of the sheet, flipped along the short edge. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_DUPLEX values. + /// + COREWEBVIEW2_PRINT_DUPLEX_TWO_SIDED_SHORT_EDGE = $00000003; + +type + /// + /// Specifies the media size for a print. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_PRINT_MEDIA_SIZE = TOleEnum; +const + /// + /// The default media size for a printer. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_MEDIA_SIZE values. + /// + COREWEBVIEW2_PRINT_MEDIA_SIZE_DEFAULT = $00000000; + /// + /// Indicate custom media size that is specific to the printer. + /// + /// + /// This is one of the COREWEBVIEW2_PRINT_MEDIA_SIZE values. + /// + COREWEBVIEW2_PRINT_MEDIA_SIZE_CUSTOM = $00000001; + +type + /// + /// Specifies the process failure reason used in the + /// ICoreWebView2ProcessFailedEventHandler interface. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_PROCESS_FAILED_REASON = TOleEnum; +const + /// + /// An unexpected process failure occurred. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_REASON values. + /// + COREWEBVIEW2_PROCESS_FAILED_REASON_UNEXPECTED = $00000000; + /// + /// The process became unresponsive. + /// This only applies to the main frame's render process. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_REASON values. + /// + COREWEBVIEW2_PROCESS_FAILED_REASON_UNRESPONSIVE = $00000001; + /// + /// The process was terminated. For example, from Task Manager. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_REASON values. + /// + COREWEBVIEW2_PROCESS_FAILED_REASON_TERMINATED = $00000002; + /// + /// The process crashed. Most crashes will generate dumps in the location + /// indicated by `ICoreWebView2Environment11.get_FailureReportFolderPath`. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_REASON values. + /// + COREWEBVIEW2_PROCESS_FAILED_REASON_CRASHED = $00000003; + /// + /// The process failed to launch. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_REASON values. + /// + COREWEBVIEW2_PROCESS_FAILED_REASON_LAUNCH_FAILED = $00000004; + /// + /// The process terminated due to running out of memory. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_REASON values. + /// + COREWEBVIEW2_PROCESS_FAILED_REASON_OUT_OF_MEMORY = $00000005; + /// + /// Deprecated. This value is unused. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_REASON values. + /// + COREWEBVIEW2_PROCESS_FAILED_REASON_PROFILE_DELETED = $00000006; + /// + /// The process exited normally (exit code 0). This typically indicates + /// a clean or transparent process shutdown. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_REASON values. + /// + COREWEBVIEW2_PROCESS_FAILED_REASON_NORMAL_EXIT = $00000007; + /// + /// The process exited abnormally (non-zero exit code). This indicates + /// an unexpected termination that is not a crash or kill. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_REASON values. + /// + COREWEBVIEW2_PROCESS_FAILED_REASON_ABNORMAL_EXIT = $00000008; + /// + /// The OS terminated the process due to a code integrity failure. + /// This indicates a DLL failed Windows Code Integrity verification. + /// + /// + /// This is one of the COREWEBVIEW2_PROCESS_FAILED_REASON values. + /// + COREWEBVIEW2_PROCESS_FAILED_REASON_INTEGRITY_FAILURE = $00000009; + +type + /// + /// Specifies the datatype for the + /// ICoreWebView2Profile2.ClearBrowsingData method. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_BROWSING_DATA_KINDS = TOleEnum; +const + /// + /// Specifies file systems data. + /// + /// + /// This is one of the COREWEBVIEW2_BROWSING_DATA_KINDS values. + /// + COREWEBVIEW2_BROWSING_DATA_KINDS_FILE_SYSTEMS = $0001; + /// + /// Specifies data stored by the IndexedDB DOM feature. + /// + /// + /// This is one of the COREWEBVIEW2_BROWSING_DATA_KINDS values. + /// + COREWEBVIEW2_BROWSING_DATA_KINDS_INDEXED_DB = $0002; + /// + /// Specifies data stored by the localStorage DOM API. + /// + /// + /// This is one of the COREWEBVIEW2_BROWSING_DATA_KINDS values. + /// + COREWEBVIEW2_BROWSING_DATA_KINDS_LOCAL_STORAGE = $0004; + /// + /// Specifies data stored by the Web SQL database DOM API. + /// + /// + /// This is one of the COREWEBVIEW2_BROWSING_DATA_KINDS values. + /// + COREWEBVIEW2_BROWSING_DATA_KINDS_WEB_SQL = $0008; + /// + /// Specifies data stored by the CacheStorage DOM API. + /// + /// + /// This is one of the COREWEBVIEW2_BROWSING_DATA_KINDS values. + /// + COREWEBVIEW2_BROWSING_DATA_KINDS_CACHE_STORAGE = $0010; + /// + /// Specifies DOM storage data, now and future. This browsing data kind is + /// inclusive of COREWEBVIEW2_BROWSING_DATA_KINDS_FILE_SYSTEMS, + /// COREWEBVIEW2_BROWSING_DATA_KINDS_INDEXED_DB, + /// COREWEBVIEW2_BROWSING_DATA_KINDS_LOCAL_STORAGE, + /// COREWEBVIEW2_BROWSING_DATA_KINDS_WEB_SQL, + /// COREWEBVIEW2_BROWSING_DATA_KINDS_SERVICE_WORKERS, + /// COREWEBVIEW2_BROWSING_DATA_KINDS_CACHE_STORAGE, + /// and some other data kinds not listed yet to keep consistent with + /// [DOM-accessible storage](https://www.w3.org/TR/clear-site-data/#storage). + /// + /// + /// This is one of the COREWEBVIEW2_BROWSING_DATA_KINDS values. + /// + COREWEBVIEW2_BROWSING_DATA_KINDS_ALL_DOM_STORAGE = $0020; + /// + /// Specifies HTTP cookies data. + /// + /// + /// This is one of the COREWEBVIEW2_BROWSING_DATA_KINDS values. + /// + COREWEBVIEW2_BROWSING_DATA_KINDS_COOKIES = $0040; + /// + /// Specifies all site data, now and future. This browsing data kind + /// is inclusive of COREWEBVIEW2_BROWSING_DATA_KINDS_ALL_DOM_STORAGE and + /// COREWEBVIEW2_BROWSING_DATA_KINDS_COOKIES. New site data types + /// may be added to this data kind in the future. + /// + /// + /// This is one of the COREWEBVIEW2_BROWSING_DATA_KINDS values. + /// + COREWEBVIEW2_BROWSING_DATA_KINDS_ALL_SITE = $0080; + /// + /// Specifies disk cache. + /// + /// + /// This is one of the COREWEBVIEW2_BROWSING_DATA_KINDS values. + /// + COREWEBVIEW2_BROWSING_DATA_KINDS_DISK_CACHE = $0100; + /// + /// Specifies download history data. + /// + /// + /// This is one of the COREWEBVIEW2_BROWSING_DATA_KINDS values. + /// + COREWEBVIEW2_BROWSING_DATA_KINDS_DOWNLOAD_HISTORY = $0200; + /// + /// Specifies general autofill form data. + /// This excludes password information and includes information like: + /// names, street and email addresses, phone numbers, and arbitrary input. + /// This also includes payment data. + /// + /// + /// This is one of the COREWEBVIEW2_BROWSING_DATA_KINDS values. + /// + COREWEBVIEW2_BROWSING_DATA_KINDS_GENERAL_AUTOFILL = $0400; + /// + /// Specifies password autosave data. + /// + /// + /// This is one of the COREWEBVIEW2_BROWSING_DATA_KINDS values. + /// + COREWEBVIEW2_BROWSING_DATA_KINDS_PASSWORD_AUTOSAVE = $0800; + /// + /// Specifies browsing history data. + /// + /// + /// This is one of the COREWEBVIEW2_BROWSING_DATA_KINDS values. + /// + COREWEBVIEW2_BROWSING_DATA_KINDS_BROWSING_HISTORY = $1000; + /// + /// Specifies settings data. + /// + /// + /// This is one of the COREWEBVIEW2_BROWSING_DATA_KINDS values. + /// + COREWEBVIEW2_BROWSING_DATA_KINDS_SETTINGS = $2000; + /// + /// Specifies profile data that should be wiped to make it look like a new profile. + /// This does not delete account-scoped data like passwords but will remove access + /// to account-scoped data by signing the user out. + /// Specifies all profile data, now and future. New profile data types may be added + /// to this data kind in the future. + /// This browsing data kind is inclusive of COREWEBVIEW2_BROWSING_DATA_KINDS_ALL_SITE, + /// COREWEBVIEW2_BROWSING_DATA_KINDS_DISK_CACHE, + /// COREWEBVIEW2_BROWSING_DATA_KINDS_DOWNLOAD_HISTORY, + /// COREWEBVIEW2_BROWSING_DATA_KINDS_GENERAL_AUTOFILL, + /// COREWEBVIEW2_BROWSING_DATA_KINDS_PASSWORD_AUTOSAVE, + /// COREWEBVIEW2_BROWSING_DATA_KINDS_BROWSING_HISTORY, and + /// COREWEBVIEW2_BROWSING_DATA_KINDS_SETTINGS. + /// + /// + /// This is one of the COREWEBVIEW2_BROWSING_DATA_KINDS values. + /// + COREWEBVIEW2_BROWSING_DATA_KINDS_ALL_PROFILE = $4000; + /// + /// Specifies service workers registered for an origin, and clear will result in + /// termination and deregistration of them. + /// + /// + /// This is one of the COREWEBVIEW2_BROWSING_DATA_KINDS values. + /// + COREWEBVIEW2_BROWSING_DATA_KINDS_SERVICE_WORKERS = $8000; + +type + /// + /// Tracking prevention levels. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_TRACKING_PREVENTION_LEVEL = TOleEnum; +const + /// + /// Tracking prevention is turned off. + /// + /// + /// This is one of the COREWEBVIEW2_TRACKING_PREVENTION_LEVEL values. + /// + COREWEBVIEW2_TRACKING_PREVENTION_LEVEL_NONE = $00000000; + /// + /// The least restrictive level of tracking prevention. Set to this level to + /// protect against malicious trackers but allows most other trackers and + /// personalize content and ads. + /// + /// See [Current tracking prevention + /// behavior](/microsoft-edge/web-platform/tracking-prevention#current-tracking-prevention-behavior) + /// for fine-grained information on what is being blocked with this level and + /// can change with different Edge versions. + /// + /// + /// This is one of the COREWEBVIEW2_TRACKING_PREVENTION_LEVEL values. + /// + COREWEBVIEW2_TRACKING_PREVENTION_LEVEL_BASIC = $00000001; + /// + /// The default level of tracking prevention. Set to this level to + /// protect against social media tracking on top of malicious trackers. + /// Content and ads will likely be less personalized. + /// + /// See [Current tracking prevention + /// behavior](/microsoft-edge/web-platform/tracking-prevention#current-tracking-prevention-behavior) + /// for fine-grained information on what is being blocked with this level and + /// can change with different Edge versions. + /// + /// + /// This is one of the COREWEBVIEW2_TRACKING_PREVENTION_LEVEL values. + /// + COREWEBVIEW2_TRACKING_PREVENTION_LEVEL_BALANCED = $00000002; + /// + /// The most restrictive level of tracking prevention. Set to this level to + /// protect + /// against malicious trackers and most trackers across sites. Content and ads + /// will likely have minimal personalization. + /// + /// This level blocks the most trackers but could cause some websites to not + /// behave as expected. + /// + /// See [Current tracking prevention + /// behavior](/microsoft-edge/web-platform/tracking-prevention#current-tracking-prevention-behavior) + /// for fine-grained information on what is being blocked with this level and + /// can change with different Edge versions. + /// + /// + /// This is one of the COREWEBVIEW2_TRACKING_PREVENTION_LEVEL values. + /// + COREWEBVIEW2_TRACKING_PREVENTION_LEVEL_STRICT = $00000003; + +type + /// + /// Specifies the PDF toolbar item types used for the ICoreWebView2Settings.put_HiddenPdfToolbarItems method. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_PDF_TOOLBAR_ITEMS = TOleEnum; +const + /// + /// No item + /// + /// + /// This is one of the COREWEBVIEW2_PDF_TOOLBAR_ITEMS values. + /// + COREWEBVIEW2_PDF_TOOLBAR_ITEMS_NONE = $00000000; + /// + /// The save button + /// + /// + /// This is one of the COREWEBVIEW2_PDF_TOOLBAR_ITEMS values. + /// + COREWEBVIEW2_PDF_TOOLBAR_ITEMS_SAVE = $00000001; + /// + /// The print button + /// + /// + /// This is one of the COREWEBVIEW2_PDF_TOOLBAR_ITEMS values. + /// + COREWEBVIEW2_PDF_TOOLBAR_ITEMS_PRINT = $00000002; + /// + /// The save as button + /// + /// + /// This is one of the COREWEBVIEW2_PDF_TOOLBAR_ITEMS values. + /// + COREWEBVIEW2_PDF_TOOLBAR_ITEMS_SAVE_AS = $00000004; + /// + /// The zoom in button + /// + /// + /// This is one of the COREWEBVIEW2_PDF_TOOLBAR_ITEMS values. + /// + COREWEBVIEW2_PDF_TOOLBAR_ITEMS_ZOOM_IN = $00000008; + /// + /// The zoom out button + /// + /// + /// This is one of the COREWEBVIEW2_PDF_TOOLBAR_ITEMS values. + /// + COREWEBVIEW2_PDF_TOOLBAR_ITEMS_ZOOM_OUT = $00000010; + /// + /// The rotate button + /// + /// + /// This is one of the COREWEBVIEW2_PDF_TOOLBAR_ITEMS values. + /// + COREWEBVIEW2_PDF_TOOLBAR_ITEMS_ROTATE = $00000020; + /// + /// The fit page button + /// + /// + /// This is one of the COREWEBVIEW2_PDF_TOOLBAR_ITEMS values. + /// + COREWEBVIEW2_PDF_TOOLBAR_ITEMS_FIT_PAGE = $00000040; + /// + /// The page layout button + /// + /// + /// This is one of the COREWEBVIEW2_PDF_TOOLBAR_ITEMS values. + /// + COREWEBVIEW2_PDF_TOOLBAR_ITEMS_PAGE_LAYOUT = $00000080; + /// + /// The bookmarks button + /// + /// + /// This is one of the COREWEBVIEW2_PDF_TOOLBAR_ITEMS values. + /// + COREWEBVIEW2_PDF_TOOLBAR_ITEMS_BOOKMARKS = $00000100; + /// + /// The page select button + /// + /// + /// This is one of the COREWEBVIEW2_PDF_TOOLBAR_ITEMS values. + /// + COREWEBVIEW2_PDF_TOOLBAR_ITEMS_PAGE_SELECTOR = $00000200; + /// + /// The search button + /// + /// + /// This is one of the COREWEBVIEW2_PDF_TOOLBAR_ITEMS values. + /// + COREWEBVIEW2_PDF_TOOLBAR_ITEMS_SEARCH = $00000400; + /// + /// The full screen button + /// + /// + /// This is one of the COREWEBVIEW2_PDF_TOOLBAR_ITEMS values. + /// + COREWEBVIEW2_PDF_TOOLBAR_ITEMS_FULL_SCREEN = $00000800; + /// + /// The more settings button + /// + /// + /// This is one of the COREWEBVIEW2_PDF_TOOLBAR_ITEMS values. + /// + COREWEBVIEW2_PDF_TOOLBAR_ITEMS_MORE_SETTINGS = $00001000; + + /// + /// This enum contains values representing possible regions a given + /// point lies within. The values of this enum align with the + /// matching WM_NCHITTEST* window message return values. + /// + /// + /// See the Globals article. + /// +type + COREWEBVIEW2_NON_CLIENT_REGION_KIND = TOleEnum; +const + /// + /// A hit test region out of bounds of the WebView2. + /// This has the same value as the Win32 HTNOWHERE + /// + /// + /// This is one of the COREWEBVIEW2_NON_CLIENT_REGION_KIND values. + /// + COREWEBVIEW2_NON_CLIENT_REGION_KIND_NOWHERE = $00000000; + /// + /// A hit test region in the WebView2 which does not have the CSS style + /// `-webkit-app-region: drag` set. This is normal web content that should not be + /// considered part of the app window's title bar. This has the same value + /// as the Win32 HTCLIENT constant. + /// + /// + /// This is one of the COREWEBVIEW2_NON_CLIENT_REGION_KIND values. + /// + COREWEBVIEW2_NON_CLIENT_REGION_KIND_CLIENT = $00000001; + /// + /// A hit test region in the WebView2 which has the CSS style + /// `-webkit-app-region: drag` set. Web content should use this CSS + /// style to identify regions that should be treated like the app + /// window's title bar. This has the same value as the Win32 HTCAPTION + /// constant. + /// + /// + /// This is one of the COREWEBVIEW2_NON_CLIENT_REGION_KIND values. + /// + COREWEBVIEW2_NON_CLIENT_REGION_KIND_CAPTION = $00000002; + /// + /// A hit test region in the Webview2 which corresponds to the minimize + /// window control button. + /// + /// + /// This is one of the COREWEBVIEW2_NON_CLIENT_REGION_KIND values. + /// + COREWEBVIEW2_NON_CLIENT_REGION_KIND_MINIMIZE = $00000008; + /// + /// A hit test region in the Webview2 which corresponds to the maximize + /// window control button. + /// + /// + /// This is one of the COREWEBVIEW2_NON_CLIENT_REGION_KIND values. + /// + COREWEBVIEW2_NON_CLIENT_REGION_KIND_MAXIMIZE = $00000009; + /// + /// A hit test region in the Webview2 which corresponds to the close + /// window control button. + /// + /// + /// This is one of the COREWEBVIEW2_NON_CLIENT_REGION_KIND values. + /// + COREWEBVIEW2_NON_CLIENT_REGION_KIND_CLOSE = $00000014; + +type + /// + /// Specifies memory usage target level of WebView. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_MEMORY_USAGE_TARGET_LEVEL = TOleEnum; +const + /// + /// Specifies normal memory usage target level. + /// + /// + /// This is one of the COREWEBVIEW2_MEMORY_USAGE_TARGET_LEVEL values. + /// + COREWEBVIEW2_MEMORY_USAGE_TARGET_LEVEL_NORMAL = $00000000; + /// + /// Specifies low memory usage target level. + /// Used for inactivate WebView for reduced memory consumption. + /// + /// + /// This is one of the COREWEBVIEW2_MEMORY_USAGE_TARGET_LEVEL values. + /// + COREWEBVIEW2_MEMORY_USAGE_TARGET_LEVEL_LOW = $00000001; + +type + /// + /// Specifies the source of `WebResourceRequested` event. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS = TOleEnum; +const + /// + /// Indicates that no web resource is requested. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS values. + /// + COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_NONE = $00000000; + /// + /// Indicates that web resource is requested from main page including dedicated workers and iframes. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS values. + /// + COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_DOCUMENT = $00000001; + /// + /// Indicates that web resource is requested from shared worker. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS values. + /// + COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_SHARED_WORKER = $00000002; + /// + /// Indicates that web resource is requested from service worker. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS values. + /// + COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_SERVICE_WORKER = $00000004; + /// + /// Indicates that web resource is requested from any supported source. + /// + /// + /// This is one of the COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS values. + /// + COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_ALL = $FFFFFFFF; + + +type +{* + ********************************************************************* + Forward declaration of types defined in TypeLibrary + ********************************************************************* +*} + ICoreWebView2 = interface; + ICoreWebView2Settings = interface; + ICoreWebView2NavigationStartingEventHandler = interface; + ICoreWebView2NavigationStartingEventArgs = interface; + ICoreWebView2HttpRequestHeaders = interface; + ICoreWebView2HttpHeadersCollectionIterator = interface; + ICoreWebView2ContentLoadingEventHandler = interface; + ICoreWebView2ContentLoadingEventArgs = interface; + ICoreWebView2SourceChangedEventHandler = interface; + ICoreWebView2SourceChangedEventArgs = interface; + ICoreWebView2HistoryChangedEventHandler = interface; + ICoreWebView2NavigationCompletedEventHandler = interface; + ICoreWebView2NavigationCompletedEventArgs = interface; + ICoreWebView2ScriptDialogOpeningEventHandler = interface; + ICoreWebView2ScriptDialogOpeningEventArgs = interface; + ICoreWebView2Deferral = interface; + ICoreWebView2PermissionRequestedEventHandler = interface; + ICoreWebView2PermissionRequestedEventArgs = interface; + ICoreWebView2ProcessFailedEventHandler = interface; + ICoreWebView2ProcessFailedEventArgs = interface; + ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler = interface; + ICoreWebView2ExecuteScriptCompletedHandler = interface; + ICoreWebView2CapturePreviewCompletedHandler = interface; + ICoreWebView2WebMessageReceivedEventHandler = interface; + ICoreWebView2WebMessageReceivedEventArgs = interface; + ICoreWebView2CallDevToolsProtocolMethodCompletedHandler = interface; + ICoreWebView2DevToolsProtocolEventReceiver = interface; + ICoreWebView2DevToolsProtocolEventReceivedEventHandler = interface; + ICoreWebView2DevToolsProtocolEventReceivedEventArgs = interface; + ICoreWebView2NewWindowRequestedEventHandler = interface; + ICoreWebView2NewWindowRequestedEventArgs = interface; + ICoreWebView2WindowFeatures = interface; + ICoreWebView2DocumentTitleChangedEventHandler = interface; + ICoreWebView2ContainsFullScreenElementChangedEventHandler = interface; + ICoreWebView2WebResourceRequestedEventHandler = interface; + ICoreWebView2WebResourceRequestedEventArgs = interface; + ICoreWebView2WebResourceRequest = interface; + ICoreWebView2WebResourceResponse = interface; + ICoreWebView2HttpResponseHeaders = interface; + ICoreWebView2WindowCloseRequestedEventHandler = interface; + ICoreWebView2_2 = interface; + ICoreWebView2WebResourceResponseReceivedEventHandler = interface; + ICoreWebView2WebResourceResponseReceivedEventArgs = interface; + ICoreWebView2WebResourceResponseView = interface; + ICoreWebView2WebResourceResponseViewGetContentCompletedHandler = interface; + ICoreWebView2DOMContentLoadedEventHandler = interface; + ICoreWebView2DOMContentLoadedEventArgs = interface; + ICoreWebView2CookieManager = interface; + ICoreWebView2Cookie = interface; + ICoreWebView2GetCookiesCompletedHandler = interface; + ICoreWebView2CookieList = interface; + ICoreWebView2Environment = interface; + ICoreWebView2CreateCoreWebView2ControllerCompletedHandler = interface; + ICoreWebView2Controller = interface; + ICoreWebView2ZoomFactorChangedEventHandler = interface; + ICoreWebView2MoveFocusRequestedEventHandler = interface; + ICoreWebView2MoveFocusRequestedEventArgs = interface; + ICoreWebView2FocusChangedEventHandler = interface; + ICoreWebView2AcceleratorKeyPressedEventHandler = interface; + ICoreWebView2AcceleratorKeyPressedEventArgs = interface; + ICoreWebView2NewBrowserVersionAvailableEventHandler = interface; + ICoreWebView2_3 = interface; + ICoreWebView2TrySuspendCompletedHandler = interface; + ICoreWebView2_4 = interface; + ICoreWebView2FrameCreatedEventHandler = interface; + ICoreWebView2FrameCreatedEventArgs = interface; + ICoreWebView2Frame = interface; + ICoreWebView2FrameNameChangedEventHandler = interface; + ICoreWebView2FrameDestroyedEventHandler = interface; + ICoreWebView2DownloadStartingEventHandler = interface; + ICoreWebView2DownloadStartingEventArgs = interface; + ICoreWebView2DownloadOperation = interface; + ICoreWebView2BytesReceivedChangedEventHandler = interface; + ICoreWebView2EstimatedEndTimeChangedEventHandler = interface; + ICoreWebView2StateChangedEventHandler = interface; + ICoreWebView2_5 = interface; + ICoreWebView2ClientCertificateRequestedEventHandler = interface; + ICoreWebView2ClientCertificateRequestedEventArgs = interface; + ICoreWebView2StringCollection = interface; + ICoreWebView2ClientCertificateCollection = interface; + ICoreWebView2ClientCertificate = interface; + ICoreWebView2_6 = interface; + ICoreWebView2_7 = interface; + ICoreWebView2PrintSettings = interface; + ICoreWebView2PrintToPdfCompletedHandler = interface; + ICoreWebView2_8 = interface; + ICoreWebView2IsMutedChangedEventHandler = interface; + ICoreWebView2IsDocumentPlayingAudioChangedEventHandler = interface; + ICoreWebView2_9 = interface; + ICoreWebView2IsDefaultDownloadDialogOpenChangedEventHandler = interface; + ICoreWebView2_10 = interface; + ICoreWebView2BasicAuthenticationRequestedEventHandler = interface; + ICoreWebView2BasicAuthenticationRequestedEventArgs = interface; + ICoreWebView2BasicAuthenticationResponse = interface; + ICoreWebView2_11 = interface; + ICoreWebView2ContextMenuRequestedEventHandler = interface; + ICoreWebView2ContextMenuRequestedEventArgs = interface; + ICoreWebView2ContextMenuItemCollection = interface; + ICoreWebView2ContextMenuItem = interface; + ICoreWebView2CustomItemSelectedEventHandler = interface; + ICoreWebView2ContextMenuTarget = interface; + ICoreWebView2_12 = interface; + ICoreWebView2StatusBarTextChangedEventHandler = interface; + ICoreWebView2_13 = interface; + ICoreWebView2Profile = interface; + ICoreWebView2_14 = interface; + ICoreWebView2ServerCertificateErrorDetectedEventHandler = interface; + ICoreWebView2ServerCertificateErrorDetectedEventArgs = interface; + ICoreWebView2Certificate = interface; + ICoreWebView2ClearServerCertificateErrorActionsCompletedHandler = interface; + ICoreWebView2_15 = interface; + ICoreWebView2FaviconChangedEventHandler = interface; + ICoreWebView2GetFaviconCompletedHandler = interface; + ICoreWebView2_16 = interface; + ICoreWebView2PrintCompletedHandler = interface; + ICoreWebView2PrintToPdfStreamCompletedHandler = interface; + ICoreWebView2_17 = interface; + ICoreWebView2SharedBuffer = interface; + ICoreWebView2_18 = interface; + ICoreWebView2LaunchingExternalUriSchemeEventHandler = interface; + ICoreWebView2LaunchingExternalUriSchemeEventArgs = interface; + ICoreWebView2_19 = interface; + ICoreWebView2_20 = interface; + ICoreWebView2_21 = interface; + ICoreWebView2ExecuteScriptWithResultCompletedHandler = interface; + ICoreWebView2ExecuteScriptResult = interface; + ICoreWebView2ScriptException = interface; + ICoreWebView2_22 = interface; + ICoreWebView2_23 = interface; + ICoreWebView2ObjectCollectionView = interface; + ICoreWebView2_24 = interface; + ICoreWebView2NotificationReceivedEventHandler = interface; + ICoreWebView2NotificationReceivedEventArgs = interface; + ICoreWebView2Notification = interface; + ICoreWebView2NotificationCloseRequestedEventHandler = interface; + ICoreWebView2_25 = interface; + ICoreWebView2SaveAsUIShowingEventHandler = interface; + ICoreWebView2SaveAsUIShowingEventArgs = interface; + ICoreWebView2ShowSaveAsUICompletedHandler = interface; + ICoreWebView2_26 = interface; + ICoreWebView2SaveFileSecurityCheckStartingEventHandler = interface; + ICoreWebView2SaveFileSecurityCheckStartingEventArgs = interface; + ICoreWebView2_27 = interface; + ICoreWebView2ScreenCaptureStartingEventHandler = interface; + ICoreWebView2ScreenCaptureStartingEventArgs = interface; + ICoreWebView2FrameInfo = interface; + ICoreWebView2_28 = interface; + ICoreWebView2Find = interface; + ICoreWebView2FindActiveMatchIndexChangedEventHandler = interface; + ICoreWebView2FindMatchCountChangedEventHandler = interface; + ICoreWebView2FindOptions = interface; + ICoreWebView2FindStartCompletedHandler = interface; + ICoreWebView2_29 = interface; + ICoreWebView2DedicatedWorkerCreatedEventHandler = interface; + ICoreWebView2DedicatedWorkerCreatedEventArgs = interface; + ICoreWebView2DedicatedWorker = interface; + ICoreWebView2DedicatedWorkerDedicatedWorkerCreatedEventHandler = interface; + ICoreWebView2DedicatedWorkerDestroyingEventHandler = interface; + ICoreWebView2DedicatedWorkerWebMessageReceivedEventHandler = interface; + ICoreWebView2AcceleratorKeyPressedEventArgs2 = interface; + ICoreWebView2BrowserExtension = interface; + ICoreWebView2BrowserExtensionRemoveCompletedHandler = interface; + ICoreWebView2BrowserExtensionEnableCompletedHandler = interface; + ICoreWebView2BrowserProcessExitedEventArgs = interface; + ICoreWebView2CompositionController = interface; + ICoreWebView2PointerInfo = interface; + ICoreWebView2CursorChangedEventHandler = interface; + ICoreWebView2CompositionController2 = interface; + ICoreWebView2CompositionController3 = interface; + ICoreWebView2CompositionController4 = interface; + ICoreWebView2RegionRectCollectionView = interface; + ICoreWebView2NonClientRegionChangedEventHandler = interface; + ICoreWebView2NonClientRegionChangedEventArgs = interface; + ICoreWebView2CompositionController5 = interface; + ICoreWebView2DragStartingEventHandler = interface; + ICoreWebView2DragStartingEventArgs = interface; + ICoreWebView2Controller2 = interface; + ICoreWebView2Controller3 = interface; + ICoreWebView2RasterizationScaleChangedEventHandler = interface; + ICoreWebView2Controller4 = interface; + ICoreWebView2ControllerOptions = interface; + ICoreWebView2ControllerOptions2 = interface; + ICoreWebView2ControllerOptions3 = interface; + ICoreWebView2ControllerOptions4 = interface; + ICoreWebView2CustomSchemeRegistration = interface; + ICoreWebView2DevToolsProtocolEventReceivedEventArgs2 = interface; + ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler = interface; + ICoreWebView2Environment2 = interface; + ICoreWebView2Environment3 = interface; + ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler = interface; + ICoreWebView2Environment4 = interface; + ICoreWebView2Environment5 = interface; + ICoreWebView2BrowserProcessExitedEventHandler = interface; + ICoreWebView2Environment6 = interface; + ICoreWebView2Environment7 = interface; + ICoreWebView2Environment8 = interface; + ICoreWebView2ProcessInfosChangedEventHandler = interface; + ICoreWebView2ProcessInfoCollection = interface; + ICoreWebView2ProcessInfo = interface; + ICoreWebView2Environment9 = interface; + ICoreWebView2Environment10 = interface; + ICoreWebView2Environment11 = interface; + ICoreWebView2Environment12 = interface; + ICoreWebView2Environment13 = interface; + ICoreWebView2GetProcessExtendedInfosCompletedHandler = interface; + ICoreWebView2ProcessExtendedInfoCollection = interface; + ICoreWebView2ProcessExtendedInfo = interface; + ICoreWebView2FrameInfoCollection = interface; + ICoreWebView2FrameInfoCollectionIterator = interface; + ICoreWebView2Environment14 = interface; + ICoreWebView2FileSystemHandle = interface; + ICoreWebView2ObjectCollection = interface; + ICoreWebView2Environment15 = interface; + ICoreWebView2EnvironmentOptions = interface; + ICoreWebView2EnvironmentOptions2 = interface; + ICoreWebView2EnvironmentOptions3 = interface; + ICoreWebView2EnvironmentOptions4 = interface; + ICoreWebView2EnvironmentOptions5 = interface; + ICoreWebView2EnvironmentOptions6 = interface; + ICoreWebView2EnvironmentOptions7 = interface; + ICoreWebView2EnvironmentOptions8 = interface; + ICoreWebView2File = interface; + ICoreWebView2Frame2 = interface; + ICoreWebView2FrameNavigationStartingEventHandler = interface; + ICoreWebView2FrameContentLoadingEventHandler = interface; + ICoreWebView2FrameNavigationCompletedEventHandler = interface; + ICoreWebView2FrameDOMContentLoadedEventHandler = interface; + ICoreWebView2FrameWebMessageReceivedEventHandler = interface; + ICoreWebView2Frame3 = interface; + ICoreWebView2FramePermissionRequestedEventHandler = interface; + ICoreWebView2PermissionRequestedEventArgs2 = interface; + ICoreWebView2Frame4 = interface; + ICoreWebView2Frame5 = interface; + ICoreWebView2Frame6 = interface; + ICoreWebView2FrameScreenCaptureStartingEventHandler = interface; + ICoreWebView2Frame7 = interface; + ICoreWebView2FrameChildFrameCreatedEventHandler = interface; + ICoreWebView2Frame8 = interface; + ICoreWebView2FrameDedicatedWorkerCreatedEventHandler = interface; + ICoreWebView2FrameInfo2 = interface; + ICoreWebView2NavigationCompletedEventArgs2 = interface; + ICoreWebView2NavigationStartingEventArgs2 = interface; + ICoreWebView2NavigationStartingEventArgs3 = interface; + ICoreWebView2NewWindowRequestedEventArgs2 = interface; + ICoreWebView2NewWindowRequestedEventArgs3 = interface; + ICoreWebView2PermissionRequestedEventArgs3 = interface; + ICoreWebView2PermissionSetting = interface; + ICoreWebView2PrintSettings2 = interface; + ICoreWebView2ProcessFailedEventArgs2 = interface; + ICoreWebView2ProcessFailedEventArgs3 = interface; + ICoreWebView2Profile2 = interface; + ICoreWebView2ClearBrowsingDataCompletedHandler = interface; + ICoreWebView2Profile3 = interface; + ICoreWebView2Profile4 = interface; + ICoreWebView2SetPermissionStateCompletedHandler = interface; + ICoreWebView2GetNonDefaultPermissionSettingsCompletedHandler = interface; + ICoreWebView2PermissionSettingCollectionView = interface; + ICoreWebView2Profile5 = interface; + ICoreWebView2Profile6 = interface; + ICoreWebView2Profile7 = interface; + ICoreWebView2ProfileAddBrowserExtensionCompletedHandler = interface; + ICoreWebView2ProfileGetBrowserExtensionsCompletedHandler = interface; + ICoreWebView2BrowserExtensionList = interface; + ICoreWebView2Profile8 = interface; + ICoreWebView2ProfileDeletedEventHandler = interface; + ICoreWebView2Profile9 = interface; + ICoreWebView2ServiceWorkerManager = interface; + ICoreWebView2ServiceWorkerRegisteredEventHandler = interface; + ICoreWebView2ServiceWorkerRegisteredEventArgs = interface; + ICoreWebView2ServiceWorkerRegistration = interface; + ICoreWebView2ServiceWorker = interface; + ICoreWebView2ServiceWorkerDestroyingEventHandler = interface; + ICoreWebView2ServiceWorkerWebMessageReceivedEventHandler = interface; + ICoreWebView2ServiceWorkerActivatedEventHandler = interface; + ICoreWebView2ServiceWorkerActivatedEventArgs = interface; + ICoreWebView2ServiceWorkerRegistrationUnregisteringEventHandler = interface; + ICoreWebView2GetServiceWorkerRegistrationsCompletedHandler = interface; + ICoreWebView2ServiceWorkerRegistrationCollectionView = interface; + ICoreWebView2SharedWorkerManager = interface; + ICoreWebView2SharedWorkerCreatedEventHandler = interface; + ICoreWebView2SharedWorkerCreatedEventArgs = interface; + ICoreWebView2SharedWorker = interface; + ICoreWebView2SharedWorkerDestroyingEventHandler = interface; + ICoreWebView2GetSharedWorkersCompletedHandler = interface; + ICoreWebView2SharedWorkerCollectionView = interface; + ICoreWebView2Settings2 = interface; + ICoreWebView2Settings3 = interface; + ICoreWebView2Settings4 = interface; + ICoreWebView2Settings5 = interface; + ICoreWebView2Settings6 = interface; + ICoreWebView2Settings7 = interface; + ICoreWebView2Settings8 = interface; + ICoreWebView2Settings9 = interface; + ICoreWebView2WebMessageReceivedEventArgs2 = interface; + ICoreWebView2WebResourceRequestedEventArgs2 = interface; + +{* + ********************************************************************* + Declaration of structures, unions and aliases. + ********************************************************************* +*} + + {* Missing NativeUInt declaration ************** WEBVIEW4DELPHI ************** *} + {$IFNDEF FPC}{$IFNDEF DELPHI15_UP}NativeUInt = Cardinal;{$ENDIF}{$ENDIF} + + {* Missing HANDLE declaration ************** WEBVIEW4DELPHI ************** *} + {$IFNDEF FPC}HANDLE = type NativeUInt;{$ENDIF} + + {$IFNDEF FPC}{$IFNDEF DELPHI7_UP} + uint64 = type int64; + PPAnsiChar = array of PChar; + NativeInt = integer; + {$ENDIF}{$ENDIF} + + Uint64Array = array of Uint64; + + PPCoreWebView2CustomSchemeRegistration = ^ICoreWebView2CustomSchemeRegistration; + + /// + /// Contains the information packed into the LPARAM sent to a Win32 key + /// event. For more information about WM_KEYDOWN, navigate to + /// [WM_KEYDOWN message](/windows/win32/inputdev/wm-keydown). + /// + COREWEBVIEW2_PHYSICAL_KEY_STATUS = record + /// + /// Specifies the repeat count for the current message. + /// + RepeatCount: SYSUINT; + /// + /// Specifies the scan code. + /// + ScanCode: SYSUINT; + /// + /// Indicates that the key is an extended key. + /// + IsExtendedKey: Integer; + /// + /// Indicates that a menu key is held down (context code). + /// + IsMenuKeyDown: Integer; + /// + /// Indicates that the key was held down. + /// + WasKeyDown: Integer; + /// + /// Indicates that the key was released. + /// + IsKeyReleased: Integer; + end; + + {* tagRect is identical to TRect. ************** WEBVIEW4DELPHI ************** *} + tagRECT = TRect; + + /// + /// Represents a reference to a delegate that receives change notifications. + /// + /// + /// Windows.Foundation.EventRegistrationToken. Also defined in Winapi.CommonTypes + /// + EventRegistrationToken = record + value: Int64; + end; + + /// + /// A value representing RGBA color (Red, Green, Blue, Alpha) for WebView2. + /// Each component takes a value from 0 to 255, with 0 being no intensity and 255 being the highest intensity. + /// + /// + /// See the Globals article. + /// + COREWEBVIEW2_COLOR = packed record + /// + /// Specifies the intensity of the Alpha ie. opacity value. 0 is transparent, 255 is opaque. + /// + A: Byte; + /// + /// Specifies the intensity of the Red color. + /// + R: Byte; + /// + /// Specifies the intensity of the Green color. + /// + G: Byte; + /// + /// Specifies the intensity of the Blue color. + /// + B: Byte; + end; + + + /// + /// Event args for the AcceleratorKeyPressed event. + /// + /// + /// See the ICoreWebView2AcceleratorKeyPressedEventArgs article. + /// + ICoreWebView2AcceleratorKeyPressedEventArgs = interface(IUnknown) + ['{9F760F8A-FB79-42BE-9990-7B56900FA9C7}'] + /// + /// The key event type that caused the event to run. + /// + function Get_KeyEventKind(out KeyEventKind: COREWEBVIEW2_KEY_EVENT_KIND): HResult; stdcall; + /// + /// The Win32 virtual key code of the key that was pressed or released. It + /// is one of the Win32 virtual key constants such as `VK_RETURN` or an + /// (uppercase) ASCII value such as `A`. Verify whether Ctrl or Alt + /// are pressed by running `GetKeyState(VK_CONTROL)` or + /// `GetKeyState(VK_MENU)`. + /// + function Get_VirtualKey(out VirtualKey: SYSUINT): HResult; stdcall; + /// + /// The `LPARAM` value that accompanied the window message. For more + /// information, navigate to [WM_KEYDOWN](/windows/win32/inputdev/wm-keydown) + /// and [WM_KEYUP](/windows/win32/inputdev/wm-keyup). + /// + function Get_KeyEventLParam(out lParam: SYSINT): HResult; stdcall; + /// + /// A structure representing the information passed in the `LPARAM` of the + /// window message. + /// + function Get_PhysicalKeyStatus(out PhysicalKeyStatus: COREWEBVIEW2_PHYSICAL_KEY_STATUS): HResult; stdcall; + /// + /// During `AcceleratorKeyPressedEvent` handler invocation the WebView is + /// blocked waiting for the decision of if the accelerator is handled by the + /// host (or not). If the `Handled` property is set to `TRUE` then this + /// prevents the WebView from performing the default action for this + /// accelerator key. Otherwise the WebView performs the default action for + /// the accelerator key. + /// + function Get_Handled(out Handled: Integer): HResult; stdcall; + /// + /// Sets the `Handled` property. + /// + function Set_Handled(Handled: Integer): HResult; stdcall; + end; + + /// + /// This is a continuation of the ICoreWebView2AcceleratorKeyPressedEventArgs interface. + /// + /// + /// See the ICoreWebView2AcceleratorKeyPressedEventArgs2 article. + /// + ICoreWebView2AcceleratorKeyPressedEventArgs2 = interface(ICoreWebView2AcceleratorKeyPressedEventArgs) + ['{03B2C8C8-7799-4E34-BD66-ED26AA85F2BF}'] + /// + /// This property allows developers to enable or disable the browser from handling a specific + /// browser accelerator key such as Ctrl+P or F3, etc. + /// + /// Browser accelerator keys are the keys/key combinations that access features specific to + /// a web browser, including but not limited to: + /// - Ctrl-F and F3 for Find on Page + /// - Ctrl-P for Print + /// - Ctrl-R and F5 for Reload + /// - Ctrl-Plus and Ctrl-Minus for zooming + /// - Ctrl-Shift-C and F12 for DevTools + /// - Special keys for browser functions, such as Back, Forward, and Search + /// + /// This property does not disable accelerator keys related to movement and text editing, + /// such as: + /// - Home, End, Page Up, and Page Down + /// - Ctrl-X, Ctrl-C, Ctrl-V + /// - Ctrl-A for Select All + /// - Ctrl-Z for Undo + /// + /// The `CoreWebView2Settings.AreBrowserAcceleratorKeysEnabled` API is a convenient setting + /// for developers to disable all the browser accelerator keys together, and sets the default + /// value for the `IsBrowserAcceleratorKeyEnabled` property. + /// By default, `CoreWebView2Settings.AreBrowserAcceleratorKeysEnabled` is `TRUE` and + /// `IsBrowserAcceleratorKeyEnabled` is `TRUE`. + /// When developers change `CoreWebView2Settings.AreBrowserAcceleratorKeysEnabled` setting to `FALSE`, + /// this will change default value for `IsBrowserAcceleratorKeyEnabled` to `FALSE`. + /// If developers want specific keys to be handled by the browser after changing the + /// `CoreWebView2Settings.AreBrowserAcceleratorKeysEnabled` setting to `FALSE`, they need to enable + /// these keys by setting `IsBrowserAcceleratorKeyEnabled` to `TRUE`. + /// This API will give the event arg higher priority over the + /// `CoreWebView2Settings.AreBrowserAcceleratorKeysEnabled` setting when we handle the keys. + /// + /// For browser accelerator keys, when an accelerator key is pressed, the propagation and + /// processing order is: + /// 1. A CoreWebView2Controller.AcceleratorKeyPressed event is raised + /// 2. WebView2 browser feature accelerator key handling + /// 3. Web Content Handling: If the key combination isn't reserved for browser actions, + /// the key event propagates to the web content, where JavaScript event listeners can + /// capture and respond to it. + /// + /// `ICoreWebView2AcceleratorKeyPressedEventArgs` has a `Handled` property, that developers + /// can use to mark a key as handled. When the key is marked as handled anywhere along + /// the path, the event propagation stops, and web content will not receive the key. + /// With `IsBrowserAcceleratorKeyEnabled` property, if developers mark + /// `IsBrowserAcceleratorKeyEnabled` as `FALSE`, the browser will skip the WebView2 + /// browser feature accelerator key handling process, but the event propagation + /// continues, and web content will receive the key combination. + /// + /// \snippet ScenarioAcceleratorKeyPressed.cpp IsBrowserAcceleratorKeyEnabled + /// Gets the `IsBrowserAcceleratorKeyEnabled` property. + /// + function Get_IsBrowserAcceleratorKeyEnabled(out value: Integer): HResult; stdcall; + /// + /// Sets the `IsBrowserAcceleratorKeyEnabled` property. + /// + function Set_IsBrowserAcceleratorKeyEnabled(value: Integer): HResult; stdcall; + end; + + /// + /// Receives AcceleratorKeyPressed events. + /// + /// + /// See the ICoreWebView2AcceleratorKeyPressedEventHandler article. + /// + ICoreWebView2AcceleratorKeyPressedEventHandler = interface(IUnknown) + ['{B29C7E28-FA79-41A8-8E44-65811C76DCB2}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Controller; + const args: ICoreWebView2AcceleratorKeyPressedEventArgs): HResult; stdcall; + end; + + /// + /// The owner of the `CoreWebView2` object that provides support for resizing, + /// showing and hiding, focusing, and other functionality related to + /// windowing and composition. The `CoreWebView2Controller` owns the + /// `CoreWebView2`, and if all references to the `CoreWebView2Controller` go + /// away, the WebView is closed. + /// + /// + /// See the ICoreWebView2Controller article. + /// + ICoreWebView2Controller = interface(IUnknown) + ['{4D00C0D1-9434-4EB6-8078-8697A560334F}'] + /// + /// The `IsVisible` property determines whether to show or hide the WebView2. + /// If `IsVisible` is set to `FALSE`, the WebView2 is transparent and is + /// not rendered. However, this does not affect the window containing the + /// WebView2 (the `HWND` parameter that was passed to + /// `CreateCoreWebView2Controller`). If you want that window to disappear + /// too, run `ShowWindow` on it directly in addition to modifying the + /// `IsVisible` property. WebView2 as a child window does not get window + /// messages when the top window is minimized or restored. For performance + /// reasons, developers should set the `IsVisible` property of the WebView to + /// `FALSE` when the app window is minimized and back to `TRUE` when the app + /// window is restored. The app window does this by handling + /// `SIZE_MINIMIZED and SIZE_RESTORED` command upon receiving `WM_SIZE` + /// message. + /// + /// There are CPU and memory benefits when the page is hidden. For instance, + /// Chromium has code that throttles activities on the page like animations + /// and some tasks are run less frequently. Similarly, WebView2 will + /// purge some caches to reduce memory usage. + /// + /// \snippet ViewComponent.cpp ToggleIsVisible + /// + function Get_IsVisible(out IsVisible: Integer): HResult; stdcall; + /// + /// Sets the `IsVisible` property. + /// + /// \snippet ViewComponent.cpp ToggleIsVisibleOnMinimize + /// + function Set_IsVisible(IsVisible: Integer): HResult; stdcall; + /// + /// The WebView bounds. Bounds are relative to the parent `HWND`. The app + /// has two ways to position a WebView. + /// + /// * Create a child `HWND` that is the WebView parent `HWND`. Position + /// the window where the WebView should be. Use `(0, 0)` for the + /// top-left corner (the offset) of the `Bounds` of the WebView. + /// * Use the top-most window of the app as the WebView parent HWND. For + /// example, to position WebView correctly in the app, set the top-left + /// corner of the Bound of the WebView. + /// + /// The values of `Bounds` are limited by the coordinate space of the host. + /// + function Get_Bounds(out Bounds: tagRECT): HResult; stdcall; + /// + /// Sets the `Bounds` property. + /// + /// \snippet ViewComponent.cpp ResizeWebView + /// + function Set_Bounds(Bounds: tagRECT): HResult; stdcall; + /// + /// The zoom factor for the WebView. + /// + /// \> [!NOTE]\n\> Changing zoom factor may cause `window.innerWidth`, + /// `window.innerHeight`, both, and page layout to change. A zoom factor + /// that is applied by the host by running `ZoomFactor` becomes the new + /// default zoom for the WebView. The zoom factor applies across navigations + /// and is the zoom factor WebView is returned to when the user chooses + /// Ctrl+0. When the zoom factor is changed by the user (resulting in + /// the app receiving `ZoomFactorChanged`), that zoom applies only for the + /// current page. Any user applied zoom is only for the current page and is + /// reset on a navigation. Specifying a `zoomFactor` less than or equal to + /// `0` is not allowed. WebView also has an internal supported zoom factor + /// range. When a specified zoom factor is out of that range, it is + /// normalized to be within the range, and a `ZoomFactorChanged` event is + /// triggered for the real applied zoom factor. When the range normalization + /// happens, the `ZoomFactor` property reports the zoom factor specified + /// during the previous modification of the `ZoomFactor` property until the + /// `ZoomFactorChanged` event is received after WebView applies the + /// normalized zoom factor. + /// + function Get_ZoomFactor(out ZoomFactor: Double): HResult; stdcall; + /// + /// Sets the `ZoomFactor` property. + /// + function Set_ZoomFactor(ZoomFactor: Double): HResult; stdcall; + /// + /// Adds an event handler for the `ZoomFactorChanged` event. + /// `ZoomFactorChanged` runs when the `ZoomFactor` property of the WebView + /// changes. The event may run because the `ZoomFactor` property was + /// modified, or due to the user manually modifying the zoom. When it is + /// modified using the `ZoomFactor` property, the internal zoom factor is + /// updated immediately and no `ZoomFactorChanged` event is triggered. + /// WebView associates the last used zoom factor for each site. It is + /// possible for the zoom factor to change when navigating to a different + /// page. When the zoom factor changes due to a navigation change, the + /// `ZoomFactorChanged` event runs right after the `ContentLoading` event. + /// + /// \snippet ViewComponent.cpp ZoomFactorChanged + /// + function add_ZoomFactorChanged(const eventHandler: ICoreWebView2ZoomFactorChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_ZoomFactorChanged`. + /// + function remove_ZoomFactorChanged(token: EventRegistrationToken): HResult; stdcall; + /// + /// Updates `Bounds` and `ZoomFactor` properties at the same time. This + /// operation is atomic from the perspective of the host. After returning + /// from this function, the `Bounds` and `ZoomFactor` properties are both + /// updated if the function is successful, or neither is updated if the + /// function fails. If `Bounds` and `ZoomFactor` are both updated by the + /// same scale (for example, `Bounds` and `ZoomFactor` are both doubled), + /// then the page does not display a change in `window.innerWidth` or + /// `window.innerHeight` and the WebView renders the content at the new size + /// and zoom without intermediate renderings. This function also updates + /// just one of `ZoomFactor` or `Bounds` by passing in the new value for one + /// and the current value for the other. + /// + /// \snippet ViewComponent.cpp SetBoundsAndZoomFactor + /// + function SetBoundsAndZoomFactor(Bounds: tagRECT; ZoomFactor: Double): HResult; stdcall; + /// + /// Moves focus into WebView. WebView gets focus and focus is set to + /// correspondent element in the page hosted in the WebView. For + /// Programmatic reason, focus is set to previously focused element or the + /// default element if no previously focused element exists. For `Next` + /// reason, focus is set to the first element. For `Previous` reason, focus + /// is set to the last element. WebView changes focus through user + /// interaction including selecting into a WebView or Tab into it. For + /// tabbing, the app runs MoveFocus with Next or Previous to align with Tab + /// and Shift+Tab respectively when it decides the WebView is the next + /// element that may exist in a tab. Or, the app runs `IsDialogMessage` + /// as part of the associated message loop to allow the platform to auto + /// handle tabbing. The platform rotates through all windows with + /// `WS_TABSTOP`. When the WebView gets focus from `IsDialogMessage`, it is + /// internally put the focus on the first or last element for tab and + /// Shift+Tab respectively. + /// + /// \snippet App.cpp MoveFocus0 + /// + /// \snippet ControlComponent.cpp MoveFocus1 + /// + /// \snippet ControlComponent.cpp MoveFocus2 + /// + function MoveFocus(reason: COREWEBVIEW2_MOVE_FOCUS_REASON): HResult; stdcall; + /// + /// Adds an event handler for the `MoveFocusRequested` event. + /// `MoveFocusRequested` runs when user tries to tab out of the WebView. The + /// focus of the WebView has not changed when this event is run. + /// + /// \snippet ControlComponent.cpp MoveFocusRequested + /// + function add_MoveFocusRequested(const eventHandler: ICoreWebView2MoveFocusRequestedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_MoveFocusRequested`. + /// + function remove_MoveFocusRequested(token: EventRegistrationToken): HResult; stdcall; + /// + /// Adds an event handler for the `GotFocus` event. `GotFocus` runs when + /// WebView has focus. + /// + function add_GotFocus(const eventHandler: ICoreWebView2FocusChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_GotFocus`. + /// + function remove_GotFocus(token: EventRegistrationToken): HResult; stdcall; + /// + /// Adds an event handler for the `LostFocus` event. `LostFocus` runs when + /// WebView loses focus. In the case where `MoveFocusRequested` event is + /// run, the focus is still on WebView when `MoveFocusRequested` event runs. + /// `LostFocus` only runs afterwards when code of the app or default action + /// of `MoveFocusRequested` event set focus away from WebView. + /// + function add_LostFocus(const eventHandler: ICoreWebView2FocusChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_LostFocus`. + /// + function remove_LostFocus(token: EventRegistrationToken): HResult; stdcall; + /// + /// Adds an event handler for the `AcceleratorKeyPressed` event. + /// `AcceleratorKeyPressed` runs when an accelerator key or key combo is + /// pressed or released while the WebView is focused. A key is considered an + /// accelerator if either of the following conditions are true. + /// + /// * Ctrl or Alt is currently being held. + /// * The pressed key does not map to a character. + /// + /// A few specific keys are never considered accelerators, such as Shift. + /// The `Escape` key is always considered an accelerator. + /// + /// Auto-repeated key events caused by holding the key down also triggers + /// this event. Filter out the auto-repeated key events by verifying the + /// `KeyEventLParam` or `PhysicalKeyStatus` event args. + /// + /// In windowed mode, the event handler is run synchronously. Until you + /// run `Handled()` on the event args or the event handler returns, the + /// browser process is blocked and outgoing cross-process COM requests fail + /// with `RPC_E_CANTCALLOUT_ININPUTSYNCCALL`. All `CoreWebView2` API methods + /// work, however. + /// + /// In windowless mode, the event handler is run asynchronously. Further + /// input do not reach the browser until the event handler returns or + /// `Handled()` is run, but the browser process is not blocked, and outgoing + /// COM requests work normally. + /// + /// It is recommended to run `Handled(TRUE)` as early as are able to know + /// that you want to handle the accelerator key. + /// + /// \snippet ControlComponent.cpp AcceleratorKeyPressed + /// + function add_AcceleratorKeyPressed(const eventHandler: ICoreWebView2AcceleratorKeyPressedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with + /// `add_AcceleratorKeyPressed`. + /// + function remove_AcceleratorKeyPressed(token: EventRegistrationToken): HResult; stdcall; + /// + /// The parent window provided by the app that this WebView is using to + /// render content. This API initially returns the window passed into + /// `CreateCoreWebView2Controller`. + /// + {* ParentWindow: wireHWND --> ParentWindow: HWND ************** WEBVIEW4DELPHI ************** *} + function Get_ParentWindow(out ParentWindow: HWND): HResult; stdcall; + /// + /// Sets the parent window for the WebView. This causes the WebView to + /// re-parent the main WebView window to the newly provided window. + /// + {* ParentWindow: wireHWND --> ParentWindow: HWND ************** WEBVIEW4DELPHI ************** *} + function Set_ParentWindow(ParentWindow: HWND): HResult; stdcall; + /// + /// This is a notification separate from `Bounds` that tells WebView that the + /// main WebView parent (or any ancestor) `HWND` moved. This is needed + /// for accessibility and certain dialogs in WebView to work correctly. + /// + /// \snippet ViewComponent.cpp NotifyParentWindowPositionChanged + /// + function NotifyParentWindowPositionChanged: HResult; stdcall; + /// + /// Closes the WebView and cleans up the underlying browser instance. + /// Cleaning up the browser instance releases the resources powering the + /// WebView. The browser instance is shut down if no other WebViews are + /// using it. + /// + /// After running `Close`, most methods will fail and event handlers stop + /// running. Specifically, the WebView releases the associated references to + /// any associated event handlers when `Close` is run. + /// + /// `Close` is implicitly run when the `CoreWebView2Controller` loses the + /// final reference and is destructed. But it is best practice to + /// explicitly run `Close` to avoid any accidental cycle of references + /// between the WebView and the app code. Specifically, if you capture a + /// reference to the WebView in an event handler you create a reference cycle + /// between the WebView and the event handler. Run `Close` to break the + /// cycle by releasing all event handlers. But to avoid the situation, it is + /// best to both explicitly run `Close` on the WebView and to not capture a + /// reference to the WebView to ensure the WebView is cleaned up correctly. + /// `Close` is synchronous and won't trigger the `beforeunload` event. + /// + /// \snippet AppWindow.cpp Close + /// + function Close: HResult; stdcall; + /// + /// Gets the `CoreWebView2` associated with this `CoreWebView2Controller`. + /// + function Get_CoreWebView2(out CoreWebView2: ICoreWebView2): HResult; stdcall; + end; + + /// + /// Receives `ZoomFactorChanged` events. + /// + /// + /// See the ICoreWebView2ZoomFactorChangedEventHandler article. + /// + ICoreWebView2ZoomFactorChangedEventHandler = interface(IUnknown) + ['{B52D71D6-C4DF-4543-A90C-64A3E60F38CB}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HResult; stdcall; + end; + + /// + /// Receives MoveFocusRequested events. + /// + /// + /// See the ICoreWebView2MoveFocusRequestedEventHandler article. + /// + ICoreWebView2MoveFocusRequestedEventHandler = interface(IUnknown) + ['{69035451-6DC7-4CB8-9BCE-B2BD70AD289F}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Controller; + const args: ICoreWebView2MoveFocusRequestedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the MoveFocusRequested event. + /// + /// + /// See the ICoreWebView2MoveFocusRequestedEventArgs article. + /// + ICoreWebView2MoveFocusRequestedEventArgs = interface(IUnknown) + ['{2D6AA13B-3839-4A15-92FC-D88B3C0D9C9D}'] + /// + /// The reason for WebView to run the `MoveFocusRequested` event. + /// + function Get_reason(out reason: COREWEBVIEW2_MOVE_FOCUS_REASON): HResult; stdcall; + /// + /// Indicates whether the event has been handled by the app. If the app has + /// moved the focus to another desired location, it should set the `Handled` + /// property to `TRUE`. When the `Handled` property is `FALSE` after the + /// event handler returns, default action is taken. The default action is to + /// try to find the next tab stop child window in the app and try to move + /// focus to that window. If no other window exists to move focus, focus is + /// cycled within the web content of the WebView. + /// + function Get_Handled(out value: Integer): HResult; stdcall; + /// + /// Sets the `Handled` property. + /// + function Set_Handled(value: Integer): HResult; stdcall; + end; + + /// + /// Receives `GotFocus` events. + /// + /// + /// See the ICoreWebView2FocusChangedEventHandler article. + /// + ICoreWebView2FocusChangedEventHandler = interface(IUnknown) + ['{05EA24BD-6452-4926-9014-4B82B498135D}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HResult; stdcall; + end; + + /// + /// WebView2 enables you to host web content using the latest Microsoft Edge + /// browser and web technology. + /// + /// + /// See the ICoreWebView2 article. + /// + ICoreWebView2 = interface(IUnknown) + ['{76ECEACB-0462-4D94-AC83-423A6793775E}'] + /// + /// The `ICoreWebView2Settings` object contains various modifiable settings + /// for the running WebView. + /// + function Get_Settings(out Settings: ICoreWebView2Settings): HResult; stdcall; + /// + /// The URI of the current top level document. This value potentially + /// changes as a part of the `SourceChanged` event that runs for some cases + /// such as navigating to a different site or fragment navigations. It + /// remains the same for other types of navigations such as page refreshes + /// or `history.pushState` with the same URL as the current page. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + /// \snippet ControlComponent.cpp SourceChanged + /// + function Get_Source(out uri: PWideChar): HResult; stdcall; + /// + /// Cause a navigation of the top-level document to run to the specified URI. + /// For more information, navigate to [Navigation + /// events](/microsoft-edge/webview2/concepts/navigation-events). + /// + /// \> [!NOTE]\n\> This operation starts a navigation and the corresponding + /// `NavigationStarting` event triggers sometime after `Navigate` runs. + /// + /// \snippet ControlComponent.cpp Navigate + /// + function Navigate(uri: PWideChar): HResult; stdcall; + /// + /// Initiates a navigation to htmlContent as source HTML of a new document. + /// The `htmlContent` parameter may not be larger than 2 MB (2 * 1024 * 1024 bytes) in total size. + /// The origin of the new page is `about:blank`. + /// + /// ```cpp + /// SetVirtualHostNameToFolderMapping( + /// L"appassets.example", L"assets", + /// COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_DENY); + /// + /// WCHAR c_navString[] = LR" + /// + /// + /// + ///

Click me

+ /// "; + /// m_webView->NavigateToString(c_navString); + /// ``` + /// \snippet SettingsComponent.cpp NavigateToString + ///
+ function NavigateToString(htmlContent: PWideChar): HResult; stdcall; + /// + /// Add an event handler for the `NavigationStarting` event. + /// `NavigationStarting` runs when the WebView main frame is requesting + /// permission to navigate to a different URI. Redirects trigger this + /// operation as well, and the navigation id is the same as the original + /// one. + /// + /// Navigations will be blocked until all `NavigationStarting` event handlers + /// return. + /// + /// \snippet SettingsComponent.cpp NavigationStarting + /// + function add_NavigationStarting(const eventHandler: ICoreWebView2NavigationStartingEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_NavigationStarting`. + /// + function remove_NavigationStarting(token: EventRegistrationToken): HResult; stdcall; + /// + /// Add an event handler for the `ContentLoading` event. `ContentLoading` + /// triggers before any content is loaded, including scripts added with + /// `AddScriptToExecuteOnDocumentCreated`. `ContentLoading` does not trigger + /// if a same page navigation occurs (such as through `fragment` + /// navigations or `history.pushState` navigations). This operation + /// follows the `NavigationStarting` and `SourceChanged` events and precedes + /// the `HistoryChanged` and `NavigationCompleted` events. + /// + function add_ContentLoading(const eventHandler: ICoreWebView2ContentLoadingEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_ContentLoading`. + /// + function remove_ContentLoading(token: EventRegistrationToken): HResult; stdcall; + /// + /// Add an event handler for the `SourceChanged` event. `SourceChanged` + /// triggers when the `Source` property changes. `SourceChanged` runs when + /// navigating to a different site or fragment navigations. It does not + /// trigger for other types of navigations such as page refreshes or + /// `history.pushState` with the same URL as the current page. + /// `SourceChanged` runs before `ContentLoading` for navigation to a new + /// document. + /// + /// \snippet ControlComponent.cpp SourceChanged + /// + function add_SourceChanged(const eventHandler: ICoreWebView2SourceChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_SourceChanged`. + /// + function remove_SourceChanged(token: EventRegistrationToken): HResult; stdcall; + /// + /// Add an event handler for the `HistoryChanged` event. `HistoryChanged` is + /// raised for changes to joint session history, which consists of top-level + /// and manual frame navigations. Use `HistoryChanged` to verify that the + /// `CanGoBack` or `CanGoForward` value has changed. `HistoryChanged` also + /// runs for using `GoBack` or `GoForward`. `HistoryChanged` runs after + /// `SourceChanged` and `ContentLoading`. `CanGoBack` is false for + /// navigations initiated through ICoreWebView2Frame APIs if there has not yet + /// been a user gesture. + /// + /// \snippet ControlComponent.cpp HistoryChanged + /// + function add_HistoryChanged(const eventHandler: ICoreWebView2HistoryChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_HistoryChanged`. + /// + function remove_HistoryChanged(token: EventRegistrationToken): HResult; stdcall; + /// + /// Add an event handler for the `NavigationCompleted` event. + /// `NavigationCompleted` runs when the WebView has completely loaded + /// (concurrently when `body.onload` runs) or loading stopped with error. + /// + /// \snippet ControlComponent.cpp NavigationCompleted + /// + function add_NavigationCompleted(const eventHandler: ICoreWebView2NavigationCompletedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_NavigationCompleted`. + /// + function remove_NavigationCompleted(token: EventRegistrationToken): HResult; stdcall; + /// + /// Add an event handler for the `FrameNavigationStarting` event. + /// `FrameNavigationStarting` triggers when a child frame in the WebView + /// requests permission to navigate to a different URI. Redirects trigger + /// this operation as well, and the navigation id is the same as the original + /// one. + /// + /// Navigations will be blocked until all `FrameNavigationStarting` event + /// handlers return. + /// + /// \snippet SettingsComponent.cpp FrameNavigationStarting + /// + function add_FrameNavigationStarting(const eventHandler: ICoreWebView2NavigationStartingEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with + /// `add_FrameNavigationStarting`. + /// + function remove_FrameNavigationStarting(token: EventRegistrationToken): HResult; stdcall; + /// + /// Add an event handler for the `FrameNavigationCompleted` event. + /// `FrameNavigationCompleted` triggers when a child frame has completely + /// loaded (concurrently when `body.onload` has triggered) or loading stopped with error. + /// + /// \snippet ControlComponent.cpp FrameNavigationCompleted + /// + function add_FrameNavigationCompleted(const eventHandler: ICoreWebView2NavigationCompletedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with + /// `add_FrameNavigationCompleted`. + /// + function remove_FrameNavigationCompleted(token: EventRegistrationToken): HResult; stdcall; + /// + /// Add an event handler for the `ScriptDialogOpening` event. + /// `ScriptDialogOpening` runs when a JavaScript dialog (`alert`, `confirm`, + /// `prompt`, or `beforeunload`) displays for the webview. This event only + /// triggers if the `ICoreWebView2Settings::AreDefaultScriptDialogsEnabled` + /// property is set to `FALSE`. The `ScriptDialogOpening` event suppresses + /// dialogs or replaces default dialogs with custom dialogs. + /// + /// If a deferral is not taken on the event args, the subsequent scripts are + /// blocked until the event handler returns. If a deferral is taken, the + /// scripts are blocked until the deferral is completed. + /// + /// \snippet SettingsComponent.cpp ScriptDialogOpening + /// + function add_ScriptDialogOpening(const eventHandler: ICoreWebView2ScriptDialogOpeningEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_ScriptDialogOpening`. + /// + function remove_ScriptDialogOpening(token: EventRegistrationToken): HResult; stdcall; + /// + /// Add an event handler for the `PermissionRequested` event. + /// `PermissionRequested` runs when content in a WebView requests permission + /// to access some privileged resources. + /// + /// If a deferral is not taken on the event args, the subsequent scripts are + /// blocked until the event handler returns. If a deferral is taken, the + /// scripts are blocked until the deferral is completed. + /// + /// \snippet SettingsComponent.cpp PermissionRequested0 + /// \snippet SettingsComponent.cpp PermissionRequested1 + /// + function add_PermissionRequested(const eventHandler: ICoreWebView2PermissionRequestedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_PermissionRequested`. + /// + function remove_PermissionRequested(token: EventRegistrationToken): HResult; stdcall; + /// + /// Add an event handler for the `ProcessFailed` event. + /// `ProcessFailed` runs when any of the processes in the + /// [WebView2 Process Group](https://learn.microsoft.com/microsoft-edge/webview2/concepts/process-model?tabs=csharp#processes-in-the-webview2-runtime) + /// encounters one of the following conditions: + /// + /// Condition | Details + /// ---|--- + /// Unexpected exit | The process indicated by the event args has exited unexpectedly (usually due to a crash). The failure might or might not be recoverable and some failures are auto-recoverable. + /// Unresponsiveness | The process indicated by the event args has become unresponsive to user input. This is only reported for renderer processes, and will run every few seconds until the process becomes responsive again. + /// + /// \> [!NOTE]\n\> When the failing process is the browser process, a + /// `ICoreWebView2Environment5::BrowserProcessExited` event will run too. + /// + /// Your application can use `ICoreWebView2ProcessFailedEventArgs` and + /// `ICoreWebView2ProcessFailedEventArgs2` to identify which condition and + /// process the event is for, and to collect diagnostics and handle recovery + /// if necessary. For more details about which cases need to be handled by + /// your application, see `COREWEBVIEW2_PROCESS_FAILED_KIND`. + /// + /// \snippet ProcessComponent.cpp ProcessFailed + /// + function add_ProcessFailed(const eventHandler: ICoreWebView2ProcessFailedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_ProcessFailed`. + /// + function remove_ProcessFailed(token: EventRegistrationToken): HResult; stdcall; + /// + /// Add the provided JavaScript to a list of scripts that should be run after + /// the global object has been created, but before the HTML document has + /// been parsed and before any other script included by the HTML document is + /// run. This method injects a script that runs on all top-level document + /// and child frame page navigations. This method runs asynchronously, and + /// you must wait for the completion handler to finish before the injected + /// script is ready to run. When this method completes, the `Invoke` method + /// of the handler is run with the `id` of the injected script. `id` is a + /// string. To remove the injected script, use + /// `RemoveScriptToExecuteOnDocumentCreated`. + /// + /// If the method is run in add_NewWindowRequested handler it should be called + /// before the new window is set. If called after setting the NewWindow property, the initial script + /// may or may not apply to the initial navigation and may only apply to the subsequent navigation. + /// For more details see `ICoreWebView2NewWindowRequestedEventArgs::put_NewWindow`. + /// + /// \> [!NOTE]\n\> If an HTML document is running in a sandbox of some kind using + /// [sandbox](https://developer.mozilla.org/docs/Web/HTML/Element/iframe#attr-sandbox) + /// properties or the + /// [Content-Security-Policy](https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Security-Policy) + /// HTTP header affects the script that runs. For example, if the + /// `allow-modals` keyword is not set then requests to run the `alert` + /// function are ignored. + /// + /// \snippet ScriptComponent.cpp AddScriptToExecuteOnDocumentCreated + /// + function AddScriptToExecuteOnDocumentCreated(javaScript: PWideChar; + const handler: ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler): HResult; stdcall; + /// + /// Remove the corresponding JavaScript added using + /// `AddScriptToExecuteOnDocumentCreated` with the specified script ID. The + /// script ID should be the one returned by the `AddScriptToExecuteOnDocumentCreated`. + /// Both use `AddScriptToExecuteOnDocumentCreated` and this method in `NewWindowRequested` + /// event handler at the same time sometimes causes trouble. Since invalid scripts will + /// be ignored, the script IDs you got may not be valid anymore. + /// + function RemoveScriptToExecuteOnDocumentCreated(id: PWideChar): HResult; stdcall; + /// + /// Run JavaScript code from the javascript parameter in the current + /// top-level document rendered in the WebView. The result of evaluating + /// the provided JavaScript is used in this parameter. The result value is + /// a JSON encoded string. If the result is undefined, contains a reference + /// cycle, or otherwise is not able to be encoded into JSON, then the result + /// is considered to be null, which is encoded in JSON as the string "null". + /// + /// \> [!NOTE]\n\> A function that has no explicit return value returns undefined. If the + /// script that was run throws an unhandled exception, then the result is + /// also "null". This method is applied asynchronously. If the method is + /// run after the `NavigationStarting` event during a navigation, the script + /// runs in the new document when loading it, around the time + /// `ContentLoading` is run. This operation executes the script even if + /// `ICoreWebView2Settings::IsScriptEnabled` is set to `FALSE`. + /// + /// \snippet ScriptComponent.cpp ExecuteScript + /// + function ExecuteScript(javaScript: PWideChar; + const handler: ICoreWebView2ExecuteScriptCompletedHandler): HResult; stdcall; + /// + /// Capture an image of what WebView is displaying. Specify the format of + /// the image with the `imageFormat` parameter. The resulting image binary + /// data is written to the provided `imageStream` parameter. When + /// `CapturePreview` finishes writing to the stream, the `Invoke` method on + /// the provided `handler` parameter is run. This method fails if called + /// before the first ContentLoading event. For example if this is called in + /// the NavigationStarting event for the first navigation it will fail. + /// For subsequent navigations, the method may not fail, but will not capture + /// an image of a given webpage until the ContentLoading event has been fired + /// for it. Any call to this method prior to that will result in a capture of + /// the page being navigated away from. + /// + /// \snippet FileComponent.cpp CapturePreview + /// + function CapturePreview(imageFormat: COREWEBVIEW2_CAPTURE_PREVIEW_IMAGE_FORMAT; + const imageStream: IStream; + const handler: ICoreWebView2CapturePreviewCompletedHandler): HResult; stdcall; + /// + /// Reload the current page. This is similar to navigating to the URI of + /// current top level document including all navigation events firing and + /// respecting any entries in the HTTP cache. But, the back or forward + /// history are not modified. + /// + function Reload: HResult; stdcall; + /// + /// Post the specified webMessage to the top level document in this WebView. + /// The main page receives the message by subscribing to the `message` event of the + /// `window.chrome.webview` of the page document. + /// + /// ```cpp + /// window.chrome.webview.addEventListener('message', handler) + /// window.chrome.webview.removeEventListener('message', handler) + /// ``` + /// + /// The event args is an instance of `MessageEvent`. The + /// `ICoreWebView2Settings::IsWebMessageEnabled` setting must be `TRUE` or + /// the web message will not be sent. The `data` property of the event + /// arg is the `webMessage` string parameter parsed as a JSON string into a + /// JavaScript object. The `source` property of the event arg is a reference + /// to the `window.chrome.webview` object. For information about sending + /// messages from the HTML document in the WebView to the host, navigate to + /// [add_WebMessageReceived](/microsoft-edge/webview2/reference/win32/icorewebview2#add_webmessagereceived). + /// The message is delivered asynchronously. If a navigation occurs before + /// the message is posted to the page, the message is discarded. + /// + /// \snippet ScenarioWebMessage.cpp WebMessageReceived + /// + function PostWebMessageAsJson(webMessageAsJson: PWideChar): HResult; stdcall; + /// + /// Posts a message that is a simple string rather than a JSON string + /// representation of a JavaScript object. This behaves in exactly the same + /// manner as `PostWebMessageAsJson`, but the `data` property of the event + /// arg of the `window.chrome.webview` message is a string with the same + /// value as `webMessageAsString`. Use this instead of + /// `PostWebMessageAsJson` if you want to communicate using simple strings + /// rather than JSON objects. + /// + function PostWebMessageAsString(webMessageAsString: PWideChar): HResult; stdcall; + /// + /// Add an event handler for the `WebMessageReceived` event. + /// `WebMessageReceived` runs when the + /// `ICoreWebView2Settings::IsWebMessageEnabled` setting is set and the + /// top-level document of the WebView runs + /// `window.chrome.webview.postMessage`. The `postMessage` function is + /// `void postMessage(object)` where object is any object supported by JSON + /// conversion. + /// + /// \snippet assets\ScenarioWebMessage.html chromeWebView + /// + /// When the page calls `postMessage`, the object parameter is converted to a + /// JSON string and is posted asynchronously to the host process. This will + /// result in the handler's `Invoke` method being called with the JSON string + /// as a parameter. + /// + /// \snippet ScenarioWebMessage.cpp WebMessageReceived + /// + /// If the same page calls `postMessage` multiple times, the corresponding + /// `WebMessageReceived` events are guaranteed to be fired in the same order. + /// However, if multiple frames call `postMessage`, there is no guaranteed + /// order. In addition, `WebMessageReceived` events caused by calls to + /// `postMessage` are not guaranteed to be sequenced with events caused by DOM + /// APIs. For example, if the page runs + /// + /// ```javascript + /// chrome.webview.postMessage("message"); + /// window.open(); + /// ``` + /// + /// then the `NewWindowRequested` event might be fired before the + /// `WebMessageReceived` event. If you need the `WebMessageReceived` event + /// to happen before anything else, then in the `WebMessageReceived` handler + /// you can post a message back to the page and have the page wait until it + /// receives that message before continuing. + /// + function add_WebMessageReceived(const handler: ICoreWebView2WebMessageReceivedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_WebMessageReceived`. + /// + function remove_WebMessageReceived(token: EventRegistrationToken): HResult; stdcall; + /// + /// Runs an asynchronous `DevToolsProtocol` method. For more information + /// about available methods, navigate to + /// [DevTools Protocol Viewer](https://chromedevtools.github.io/devtools-protocol/tot) + /// . The `methodName` parameter is the full name of the method in the + /// `{domain}.{method}` format. The `parametersAsJson` parameter is a JSON + /// formatted string containing the parameters for the corresponding method. + /// The `Invoke` method of the `handler` is run when the method + /// asynchronously completes. `Invoke` is run with the return object of the + /// method as a JSON string. This function returns E_INVALIDARG if the `methodName` is + /// unknown or the `parametersAsJson` has an error. In the case of such an error, the + /// `returnObjectAsJson` parameter of the handler will include information + /// about the error. + /// Note even though WebView2 dispatches the CDP messages in the order called, + /// CDP method calls may be processed out of order. + /// If you require CDP methods to run in a particular order, you should wait + /// for the previous method's completed handler to run before calling the + /// next method. + /// If the method is to run in add_NewWindowRequested handler it should be called + /// before the new window is set if the cdp message should affect the initial navigation. If + /// called after setting the NewWindow property, the cdp messages + /// may or may not apply to the initial navigation and may only apply to the subsequent navigation. + /// For more details see `ICoreWebView2NewWindowRequestedEventArgs::put_NewWindow`. + /// + /// \snippet ScriptComponent.cpp CallDevToolsProtocolMethod + /// + function CallDevToolsProtocolMethod(methodName: PWideChar; parametersAsJson: PWideChar; + const handler: ICoreWebView2CallDevToolsProtocolMethodCompletedHandler): HResult; stdcall; + /// + /// The process ID of the browser process that hosts the WebView. + /// + function Get_BrowserProcessId(out value: SYSUINT): HResult; stdcall; + /// + /// `TRUE` if the WebView is able to navigate to a previous page in the + /// navigation history. If `CanGoBack` changes value, the `HistoryChanged` + /// event runs. + /// + function Get_CanGoBack(out CanGoBack: Integer): HResult; stdcall; + /// + /// `TRUE` if the WebView is able to navigate to a next page in the + /// navigation history. If `CanGoForward` changes value, the + /// `HistoryChanged` event runs. + /// + function Get_CanGoForward(out CanGoForward: Integer): HResult; stdcall; + /// + /// Navigates the WebView to the previous page in the navigation history. + /// + function GoBack: HResult; stdcall; + /// + /// Navigates the WebView to the next page in the navigation history. + /// + function GoForward: HResult; stdcall; + /// + /// Get a DevTools Protocol event receiver that allows you to subscribe to a + /// DevTools Protocol event. The `eventName` parameter is the full name of + /// the event in the format `{domain}.{event}`. For more information about + /// DevTools Protocol events description and event args, navigate to + /// [DevTools Protocol Viewer](https://chromedevtools.github.io/devtools-protocol/tot). + /// + /// \snippet ScriptComponent.cpp DevToolsProtocolEventReceived + /// + function GetDevToolsProtocolEventReceiver(eventName: PWideChar; + out receiver: ICoreWebView2DevToolsProtocolEventReceiver): HResult; stdcall; + /// + /// Stop all navigations and pending resource fetches. Does not stop scripts. + /// + function Stop: HResult; stdcall; + /// + /// Add an event handler for the `NewWindowRequested` event. + /// `NewWindowRequested` runs when content inside the WebView requests to + /// open a new window, such as through `window.open`. The app can pass a + /// target WebView that is considered the opened window or mark the event as + /// `Handled`, in which case WebView2 does not open a window. + /// If either `Handled` or `NewWindow` properties are not set, the target + /// content will be opened on a popup window. + /// + /// If a deferral is not taken on the event args, scripts that resulted in the + /// new window that are requested are blocked until the event handler returns. + /// If a deferral is taken, then scripts are blocked until the deferral is + /// completed or new window is set. + /// + /// For more details and considerations on the target WebView to be supplied + /// at the opened window, see `ICoreWebView2NewWindowRequestedEventArgs::put_NewWindow`. + /// + /// \snippet AppWindow.cpp NewWindowRequested + /// + function add_NewWindowRequested(const eventHandler: ICoreWebView2NewWindowRequestedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_NewWindowRequested`. + /// + function remove_NewWindowRequested(token: EventRegistrationToken): HResult; stdcall; + /// + /// Add an event handler for the `DocumentTitleChanged` event. + /// `DocumentTitleChanged` runs when the `DocumentTitle` property of the + /// WebView changes and may run before or after the `NavigationCompleted` + /// event. + /// + /// \snippet FileComponent.cpp DocumentTitleChanged + /// + function add_DocumentTitleChanged(const eventHandler: ICoreWebView2DocumentTitleChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_DocumentTitleChanged`. + /// + function remove_DocumentTitleChanged(token: EventRegistrationToken): HResult; stdcall; + /// + /// The title for the current top-level document. If the document has no + /// explicit title or is otherwise empty, a default that may or may not match + /// the URI of the document is used. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_DocumentTitle(out title: PWideChar): HResult; stdcall; + /// + /// Add the provided host object to script running in the WebView with the + /// specified name. Host objects are exposed as host object proxies using + /// `window.chrome.webview.hostObjects.{name}`. Host object proxies are + /// promises and resolves to an object representing the host object. The + /// promise is rejected if the app has not added an object with the name. + /// When JavaScript code access a property or method of the object, a promise + /// is return, which resolves to the value returned from the host for the + /// property or method, or rejected in case of error, for example, no + /// property or method on the object or parameters are not valid. + /// + /// \> [!NOTE]\n\> While simple types, `IDispatch` and array are supported, and + /// `IUnknown` objects that also implement `IDispatch` are treated as `IDispatch`, + /// generic `IUnknown`, `VT_DECIMAL`, or `VT_RECORD` variant is not supported. + /// Remote JavaScript objects like callback functions are represented as an + /// `VT_DISPATCH` `VARIANT` with the object implementing `IDispatch`. The + /// JavaScript callback method may be invoked using `DISPID_VALUE` for the + /// `DISPID`. Such callback method invocations will return immediately and will + /// not wait for the JavaScript function to run and so will not provide the return + /// value of the JavaScript function. + /// Nested arrays are supported up to a depth of 3. Arrays of by + /// reference types are not supported. `VT_EMPTY` and `VT_NULL` are mapped + /// into JavaScript as `null`. In JavaScript, `null` and undefined are + /// mapped to `VT_EMPTY`. + /// + /// Additionally, all host objects are exposed as + /// `window.chrome.webview.hostObjects.sync.{name}`. Here the host objects + /// are exposed as synchronous host object proxies. These are not promises + /// and function runtimes or property access synchronously block running + /// script waiting to communicate cross process for the host code to run. + /// Accordingly the result may have reliability issues and it is recommended + /// that you use the promise-based asynchronous + /// `window.chrome.webview.hostObjects.{name}` API. + /// + /// Synchronous host object proxies and asynchronous host object proxies may + /// both use a proxy to the same host object. Remote changes made by one + /// proxy propagates to any other proxy of that same host object whether + /// the other proxies and synchronous or asynchronous. + /// + /// While JavaScript is blocked on a synchronous run to native code, that + /// native code is unable to run back to JavaScript. Attempts to do so fail + /// with `HRESULT_FROM_WIN32(ERROR_POSSIBLE_DEADLOCK)`. + /// + /// Host object proxies are JavaScript Proxy objects that intercept all + /// property get, property set, and method invocations. Properties or methods + /// that are a part of the Function or Object prototype are run locally. + /// Additionally any property or method in the + /// `chrome.webview.hostObjects.options.forceLocalProperties` + /// array are also run locally. This defaults to including optional methods + /// that have meaning in JavaScript like `toJSON` and `Symbol.toPrimitive`. + /// Add more to the array as required. + /// + /// The `chrome.webview.hostObjects.cleanupSome` method performs a best + /// effort garbage collection on host object proxies. + /// + /// The `chrome.webview.hostObjects.options` object provides the ability to + /// change some functionality of host objects. + /// + /// Options property | Details + /// ---|--- + /// `forceLocalProperties` | This is an array of host object property names that will be run locally, instead of being called on the native host object. This defaults to `then`, `toJSON`, `Symbol.toString`, and `Symbol.toPrimitive`. You can add other properties to specify that they should be run locally on the javascript host object proxy. + /// `log` | This is a callback that will be called with debug information. For example, you can set this to `console.log.bind(console)` to have it print debug information to the console to help when troubleshooting host object usage. By default this is null. + /// `shouldSerializeDates` | By default this is false, and javascript Date objects will be sent to host objects as a string using `JSON.stringify`. You can set this property to true to have Date objects properly serialize as a `VT_DATE` when sending to the native host object, and have `VT_DATE` properties and return values create a javascript Date object. + /// `defaultSyncProxy` | When calling a method on a synchronous proxy, the result should also be a synchronous proxy. But in some cases, the sync/async context is lost (for example, when providing to native code a reference to a function, and then calling that function in native code). In these cases, the proxy will be asynchronous, unless this property is set. + /// `forceAsyncMethodMatches ` | This is an array of regular expressions. When calling a method on a synchronous proxy, the method call will be performed asynchronously if the method name matches a string or regular expression in this array. Setting this value to `Async` will make any method that ends with Async be an asynchronous method call. If an async method doesn't match here and isn't forced to be asynchronous, the method will be invoked synchronously, blocking execution of the calling JavaScript and then returning the resolution of the promise, rather than returning a promise. + /// `ignoreMemberNotFoundError` | By default, an exception is thrown when attempting to get the value of a proxy property that doesn't exist on the corresponding native class. Setting this property to `true` switches the behavior to match Chakra WinRT projection (and general JavaScript) behavior of returning `undefined` with no error. + /// `shouldPassTypedArraysAsArrays` | By default, typed arrays are passed to the host as `IDispatch`. To instead pass typed arrays to the host as `array`, set this to `true`. + /// + /// Host object proxies additionally have the following methods which run + /// locally. + /// + /// Method name | Details + /// ---|--- + ///`applyHostFunction`, `getHostProperty`, `setHostProperty` | Perform a method invocation, property get, or property set on the host object. Use the methods to explicitly force a method or property to run remotely if a conflicting local method or property exists. For instance, `proxy.toString()` runs the local `toString` method on the proxy object. But proxy.applyHostFunction('toString') runs `toString` on the host proxied object instead. + ///`getLocalProperty`, `setLocalProperty` | Perform property get, or property set locally. Use the methods to force getting or setting a property on the host object proxy rather than on the host object it represents. For instance, `proxy.unknownProperty` gets the property named `unknownProperty` from the host proxied object. But proxy.getLocalProperty('unknownProperty') gets the value of the property `unknownProperty` on the proxy object. + ///`sync` | Asynchronous host object proxies expose a sync method which returns a promise for a synchronous host object proxy for the same host object. For example, `chrome.webview.hostObjects.sample.methodCall()` returns an asynchronous host object proxy. Use the `sync` method to obtain a synchronous host object proxy instead: `const syncProxy = await chrome.webview.hostObjects.sample.methodCall().sync()`. + ///`async` | Synchronous host object proxies expose an async method which blocks and returns an asynchronous host object proxy for the same host object. For example, `chrome.webview.hostObjects.sync.sample.methodCall()` returns a synchronous host object proxy. Running the `async` method on this blocks and then returns an asynchronous host object proxy for the same host object: `const asyncProxy = chrome.webview.hostObjects.sync.sample.methodCall().async()`. + ///`then` | Asynchronous host object proxies have a `then` method. Allows proxies to be awaitable. `then` returns a promise that resolves with a representation of the host object. If the proxy represents a JavaScript literal, a copy of that is returned locally. If the proxy represents a function, a non-awaitable proxy is returned. If the proxy represents a JavaScript object with a mix of literal properties and function properties, the a copy of the object is returned with some properties as host object proxies. + /// + /// All other property and method invocations (other than the above Remote + /// object proxy methods, `forceLocalProperties` list, and properties on + /// Function and Object prototypes) are run remotely. Asynchronous host + /// object proxies return a promise representing asynchronous completion of + /// remotely invoking the method, or getting the property. The promise + /// resolves after the remote operations complete and the promises resolve to + /// the resulting value of the operation. Synchronous host object proxies + /// work similarly, but block running JavaScript and wait for the remote + /// operation to complete. + /// + /// Setting a property on an asynchronous host object proxy works slightly + /// differently. The set returns immediately and the return value is the + /// value that is set. This is a requirement of the JavaScript Proxy object. + /// If you need to asynchronously wait for the property set to complete, use + /// the `setHostProperty` method which returns a promise as described above. + /// Synchronous object property set property synchronously blocks until the + /// property is set. + /// + /// For example, suppose you have a COM object with the following interface. + /// + /// \snippet HostObjectSample.idl AddHostObjectInterface + /// + /// Add an instance of this interface into your JavaScript with + /// `AddHostObjectToScript`. In this case, name it `sample`. + /// + /// \snippet ScenarioAddHostObject.cpp AddHostObjectToScript + /// + /// In the HTML document, use the COM object using + /// `chrome.webview.hostObjects.sample`. + /// Note that `CoreWebView2.AddHostObjectToScript` only applies to the + /// top-level document and not to frames. To add host objects to frames use + /// `CoreWebView2Frame.AddHostObjectToScript`. + /// + /// \snippet assets\ScenarioAddHostObject.html HostObjectUsage + /// + /// Exposing host objects to script has security risk. For more information + /// about best practices, navigate to + /// [Best practices for developing secure WebView2 applications](/microsoft-edge/webview2/concepts/security). + /// + function AddHostObjectToScript(name: PWideChar; const object_: OleVariant): HResult; stdcall; + /// + /// Remove the host object specified by the name so that it is no longer + /// accessible from JavaScript code in the WebView. While new access + /// attempts are denied, if the object is already obtained by JavaScript code + /// in the WebView, the JavaScript code continues to have access to that + /// object. Run this method for a name that is already removed or never + /// added fails. + /// + function RemoveHostObjectFromScript(name: PWideChar): HResult; stdcall; + /// + /// Opens the DevTools window for the current document in the WebView. Does + /// nothing if run when the DevTools window is already open. + /// + function OpenDevToolsWindow: HResult; stdcall; + /// + /// Add an event handler for the `ContainsFullScreenElementChanged` event. + /// `ContainsFullScreenElementChanged` triggers when the + /// `ContainsFullScreenElement` property changes. An HTML element inside the + /// WebView may enter fullscreen to the size of the WebView or leave + /// fullscreen. This event is useful when, for example, a video element + /// requests to go fullscreen. The listener of + /// `ContainsFullScreenElementChanged` may resize the WebView in response. + /// + /// \snippet AppWindow.cpp ContainsFullScreenElementChanged + /// + function add_ContainsFullScreenElementChanged(const eventHandler: ICoreWebView2ContainsFullScreenElementChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with + /// `add_ContainsFullScreenElementChanged`. + /// + function remove_ContainsFullScreenElementChanged(token: EventRegistrationToken): HResult; stdcall; + /// + /// Indicates if the WebView contains a fullscreen HTML element. + /// + function Get_ContainsFullScreenElement(out ContainsFullScreenElement: Integer): HResult; stdcall; + /// + /// Add an event handler for the `WebResourceRequested` event. + /// `WebResourceRequested` runs when the WebView is performing a URL request + /// to a matching URL and resource context and source kind filter that was + /// added with `AddWebResourceRequestedFilterWithRequestSourceKinds`. + /// At least one filter must be added for the event to run. + /// + /// The web resource requested may be blocked until the event handler returns + /// if a deferral is not taken on the event args. If a deferral is taken, + /// then the web resource requested is blocked until the deferral is + /// completed. + /// + /// If this event is subscribed in the add_NewWindowRequested handler it should be called + /// after the new window is set. For more details see `ICoreWebView2NewWindowRequestedEventArgs::put_NewWindow`. + /// + /// This event is by default raised for file, http, and https URI schemes. + /// This is also raised for registered custom URI schemes. For more details + /// see `ICoreWebView2CustomSchemeRegistration`. + /// + /// \snippet SettingsComponent.cpp WebResourceRequested0 + /// \snippet SettingsComponent.cpp WebResourceRequested1 + /// + function add_WebResourceRequested(const eventHandler: ICoreWebView2WebResourceRequestedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_WebResourceRequested`. + /// + function remove_WebResourceRequested(token: EventRegistrationToken): HResult; stdcall; + /// + /// Warning: This method is deprecated and does not behave as expected for + /// iframes. It will cause the WebResourceRequested event to fire only for the + /// main frame and its same-origin iframes. Please use + /// `AddWebResourceRequestedFilterWithRequestSourceKinds` + /// instead, which will let the event to fire for all iframes on the + /// document. + /// + /// Adds a URI and resource context filter for the `WebResourceRequested` + /// event. A web resource request with a resource context that matches this + /// filter's resource context and a URI that matches this filter's URI + /// wildcard string will be raised via the `WebResourceRequested` event. + /// + /// The `uri` parameter value is a wildcard string matched against the URI + /// of the web resource request. This is a glob style + /// wildcard string in which a `*` matches zero or more characters and a `?` + /// matches exactly one character. + /// These wildcard characters can be escaped using a backslash just before + /// the wildcard character in order to represent the literal `*` or `?`. + /// + /// The matching occurs over the URI as a whole string and not limiting + /// wildcard matches to particular parts of the URI. + /// The wildcard filter is compared to the URI after the URI has been + /// normalized, any URI fragment has been removed, and non-ASCII hostnames + /// have been converted to punycode. + /// + /// Specifying a `nullptr` for the uri is equivalent to an empty string which + /// matches no URIs. + /// + /// For more information about resource context filters, navigate to + /// [COREWEBVIEW2_WEB_RESOURCE_CONTEXT](/microsoft-edge/webview2/reference/win32/webview2-idl#corewebview2_web_resource_context). + /// + /// | URI Filter String | Request URI | Match | Notes | + /// | ---- | ---- | ---- | ---- | + /// | `*` | `https://contoso.com/a/b/c` | Yes | A single * will match all URIs | + /// | `*://contoso.com/*` | `https://contoso.com/a/b/c` | Yes | Matches everything in contoso.com across all schemes | + /// | `*://contoso.com/*` | `https://example.com/?https://contoso.com/` | Yes | But also matches a URI with just the same text anywhere in the URI | + /// | `example` | `https://contoso.com/example` | No | The filter does not perform partial matches | + /// | `*example` | `https://contoso.com/example` | Yes | The filter matches across URI parts | + /// | `*example` | `https://contoso.com/path/?example` | Yes | The filter matches across URI parts | + /// | `*example` | `https://contoso.com/path/?query#example` | No | The filter is matched against the URI with no fragment | + /// | `*example` | `https://example` | No | The URI is normalized before filter matching so the actual URI used for comparison is `https://example/` | + /// | `*example/` | `https://example` | Yes | Just like above, but this time the filter ends with a / just like the normalized URI | + /// | `https://xn--qei.example/` | `https://❤.example/` | Yes | Non-ASCII hostnames are normalized to punycode before wildcard comparison | + /// | `https://❤.example/` | `https://xn--qei.example/` | No | Non-ASCII hostnames are normalized to punycode before wildcard comparison | + /// + function AddWebResourceRequestedFilter(uri: PWideChar; + ResourceContext: COREWEBVIEW2_WEB_RESOURCE_CONTEXT): HResult; stdcall; + /// + /// Warning: This method and `AddWebResourceRequestedFilter` are deprecated. + /// Please use `AddWebResourceRequestedFilterWithRequestSourceKinds` and + /// `RemoveWebResourceRequestedFilterWithRequestSourceKinds` instead. + /// + /// Removes a matching WebResource filter that was previously added for the + /// `WebResourceRequested` event. If the same filter was added multiple + /// times, then it must be removed as many times as it was added for the + /// removal to be effective. Returns `E_INVALIDARG` for a filter that was + /// never added. + /// + function RemoveWebResourceRequestedFilter(uri: PWideChar; + ResourceContext: COREWEBVIEW2_WEB_RESOURCE_CONTEXT): HResult; stdcall; + /// + /// Add an event handler for the `WindowCloseRequested` event. + /// `WindowCloseRequested` triggers when content inside the WebView + /// requested to close the window, such as after `window.close` is run. The + /// app should close the WebView and related app window if that makes sense + /// to the app. After the first window.close() call, this event may not fire + /// for any immediate back to back window.close() calls. + /// + /// \snippet AppWindow.cpp WindowCloseRequested + /// + function add_WindowCloseRequested(const eventHandler: ICoreWebView2WindowCloseRequestedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_WindowCloseRequested`. + /// + function remove_WindowCloseRequested(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Defines properties that enable, disable, or modify WebView features. + /// Changes to IsGeneralAutofillEnabled and IsPasswordAutosaveEnabled + /// apply immediately, while other setting changes made after NavigationStarting + /// event do not apply until the next top-level navigation. + /// + /// + /// See the ICoreWebView2Settings article. + /// + ICoreWebView2Settings = interface(IUnknown) + ['{E562E4F0-D7FA-43AC-8D71-C05150499F00}'] + /// + /// Controls if running JavaScript is enabled in all future navigations in + /// the WebView. This only affects scripts in the document. Scripts + /// injected with `ExecuteScript` runs even if script is disabled. + /// The default value is `TRUE`. + /// + /// \snippet SettingsComponent.cpp IsScriptEnabled + /// + function Get_IsScriptEnabled(out IsScriptEnabled: Integer): HResult; stdcall; + /// + /// Sets the `IsScriptEnabled` property. + /// + function Set_IsScriptEnabled(IsScriptEnabled: Integer): HResult; stdcall; + /// + /// The `IsWebMessageEnabled` property is used when loading a new HTML + /// document. If set to `TRUE`, communication from the host to the top-level + /// HTML document of the WebView is allowed using `PostWebMessageAsJson`, + /// `PostWebMessageAsString`, and message event of `window.chrome.webview`. + /// For more information, navigate to PostWebMessageAsJson. Communication + /// from the top-level HTML document of the WebView to the host is allowed + /// using the postMessage function of `window.chrome.webview` and + /// `add_WebMessageReceived` method. For more information, navigate to + /// [add_WebMessageReceived](/microsoft-edge/webview2/reference/win32/icorewebview2#add_webmessagereceived). + /// If set to false, then communication is disallowed. `PostWebMessageAsJson` + /// and `PostWebMessageAsString` fails with `E_ACCESSDENIED` and + /// `window.chrome.webview.postMessage` fails by throwing an instance of an + /// `Error` object. The default value is `TRUE`. + /// + /// \snippet ScenarioWebMessage.cpp IsWebMessageEnabled + /// + function Get_IsWebMessageEnabled(out IsWebMessageEnabled: Integer): HResult; stdcall; + /// + /// Sets the `IsWebMessageEnabled` property. + /// + function Set_IsWebMessageEnabled(IsWebMessageEnabled: Integer): HResult; stdcall; + /// + /// `AreDefaultScriptDialogsEnabled` is used when loading a new HTML + /// document. If set to `FALSE`, WebView2 does not render the default JavaScript + /// dialog box (Specifically those displayed by the JavaScript alert, + /// confirm, prompt functions and `beforeunload` event). Instead, if an + /// event handler is set using `add_ScriptDialogOpening`, WebView sends an + /// event that contains all of the information for the dialog and allow the + /// host app to show a custom UI. + /// The default value is `TRUE`. + /// + function Get_AreDefaultScriptDialogsEnabled(out AreDefaultScriptDialogsEnabled: Integer): HResult; stdcall; + /// + /// Sets the `AreDefaultScriptDialogsEnabled` property. + /// + function Set_AreDefaultScriptDialogsEnabled(AreDefaultScriptDialogsEnabled: Integer): HResult; stdcall; + /// + /// `IsStatusBarEnabled` controls whether the status bar is displayed. The + /// status bar is usually displayed in the lower left of the WebView and + /// shows things such as the URI of a link when the user hovers over it and + /// other information. + /// The default value is `TRUE`. + /// The status bar UI can be altered by web content and should not be considered secure. + /// + function Get_IsStatusBarEnabled(out IsStatusBarEnabled: Integer): HResult; stdcall; + /// + /// Sets the `IsStatusBarEnabled` property. + /// + function Set_IsStatusBarEnabled(IsStatusBarEnabled: Integer): HResult; stdcall; + /// + /// `AreDevToolsEnabled` controls whether the user is able to use the context + /// menu or keyboard shortcuts to open the DevTools window. + /// The default value is `TRUE`. + /// + function Get_AreDevToolsEnabled(out AreDevToolsEnabled: Integer): HResult; stdcall; + /// + /// Sets the `AreDevToolsEnabled` property. + /// + function Set_AreDevToolsEnabled(AreDevToolsEnabled: Integer): HResult; stdcall; + /// + /// The `AreDefaultContextMenusEnabled` property is used to prevent default + /// context menus from being shown to user in WebView. + /// The default value is `TRUE`. + /// + /// \snippet SettingsComponent.cpp DisableContextMenu + /// + function Get_AreDefaultContextMenusEnabled(out enabled: Integer): HResult; stdcall; + /// + /// Sets the `AreDefaultContextMenusEnabled` property. + /// + function Set_AreDefaultContextMenusEnabled(enabled: Integer): HResult; stdcall; + /// + /// The `AreHostObjectsAllowed` property is used to control whether host + /// objects are accessible from the page in WebView. + /// The default value is `TRUE`. + /// + /// \snippet SettingsComponent.cpp HostObjectsAccess + /// + function Get_AreHostObjectsAllowed(out allowed: Integer): HResult; stdcall; + /// + /// Sets the `AreHostObjectsAllowed` property. + /// + function Set_AreHostObjectsAllowed(allowed: Integer): HResult; stdcall; + /// + /// The `IsZoomControlEnabled` property is used to prevent the user from + /// impacting the zoom of the WebView. When disabled, the user is not able + /// to zoom using Ctrl++, Ctrl+-, or Ctrl+mouse wheel, but the zoom + /// is set using `ZoomFactor` API. The default value is `TRUE`. + /// + /// \snippet SettingsComponent.cpp DisableZoomControl + /// + function Get_IsZoomControlEnabled(out enabled: Integer): HResult; stdcall; + /// + /// Sets the `IsZoomControlEnabled` property. + /// + function Set_IsZoomControlEnabled(enabled: Integer): HResult; stdcall; + /// + /// The `IsBuiltInErrorPageEnabled` property is used to disable built in + /// error page for navigation failure and render process failure. When + /// disabled, a blank page is displayed when the related error happens. + /// The default value is `TRUE`. + /// + /// \snippet SettingsComponent.cpp BuiltInErrorPageEnabled + /// + function Get_IsBuiltInErrorPageEnabled(out enabled: Integer): HResult; stdcall; + /// + /// Sets the `IsBuiltInErrorPageEnabled` property. + /// + function Set_IsBuiltInErrorPageEnabled(enabled: Integer): HResult; stdcall; + end; + + /// + /// Receives NavigationStarting events. + /// + /// + /// See the ICoreWebView2NavigationStartingEventHandler article. + /// + ICoreWebView2NavigationStartingEventHandler = interface(IUnknown) + ['{9ADBE429-F36D-432B-9DDC-F8881FBD76E3}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2NavigationStartingEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the NavigationStarting event. + /// + /// + /// See the ICoreWebView2NavigationStartingEventArgs article. + /// + ICoreWebView2NavigationStartingEventArgs = interface(IUnknown) + ['{5B495469-E119-438A-9B18-7604F25F2E49}'] + /// + /// The uri of the requested navigation. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_uri(out uri: PWideChar): HResult; stdcall; + /// + /// `TRUE` when the navigation was initiated through a user gesture as + /// opposed to programmatic navigation by page script. Navigations initiated + /// via WebView2 APIs are considered as user initiated. + /// + function Get_IsUserInitiated(out IsUserInitiated: Integer): HResult; stdcall; + /// + /// `TRUE` when the navigation is redirected. + /// + function Get_IsRedirected(out IsRedirected: Integer): HResult; stdcall; + /// + /// The HTTP request headers for the navigation. + /// + /// \> [!NOTE]\n\> You are not able to modify the HTTP request headers in a + /// `NavigationStarting` event. + /// + function Get_RequestHeaders(out RequestHeaders: ICoreWebView2HttpRequestHeaders): HResult; stdcall; + /// + /// The host may set this flag to cancel the navigation. If set, the + /// navigation is not longer present and the content of the current page is + /// intact. For performance reasons, `GET` HTTP requests may happen, while + /// the host is responding. You may set cookies and use part of a request + /// for the navigation. Navigations to about schemes are cancellable, unless + /// `msWebView2CancellableAboutNavigations` feature flag is disabled. + /// Cancellation of frame navigation to `srcdoc` is not supported and + /// wil be ignored. A cancelled navigation will fire a `NavigationCompleted` + /// event with a `WebErrorStatus` of + /// `COREWEBVIEW2_WEB_ERROR_STATUS_OPERATION_CANCELED`. + /// + function Get_Cancel(out Cancel: Integer): HResult; stdcall; + /// + /// Sets the `Cancel` property. + /// + function Set_Cancel(Cancel: Integer): HResult; stdcall; + /// + /// The ID of the navigation. + /// + function Get_NavigationId(out NavigationId: Largeuint): HResult; stdcall; + end; + + /// + /// HTTP request headers. Used to inspect the HTTP request on + /// WebResourceRequested event and NavigationStarting event. + /// + /// + /// It is possible to modify the HTTP request from a WebResourceRequested event, but not from a NavigationStarting event. + /// See the ICoreWebView2HttpRequestHeaders article. + /// + ICoreWebView2HttpRequestHeaders = interface(IUnknown) + ['{E86CAC0E-5523-465C-B536-8FB9FC8C8C60}'] + /// + /// Gets the header value matching the name. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function GetHeader(name: PWideChar; out value: PWideChar): HResult; stdcall; + /// + /// Gets the header value matching the name using an iterator. + /// + function GetHeaders(name: PWideChar; out value: ICoreWebView2HttpHeadersCollectionIterator): HResult; stdcall; + /// + /// Checks whether the headers contain an entry that matches the header name. + /// + function Contains(name: PWideChar; out value: Integer): HResult; stdcall; + /// + /// Adds or updates header that matches the name. + /// + function SetHeader(name: PWideChar; value: PWideChar): HResult; stdcall; + /// + /// Removes header that matches the name. + /// + function RemoveHeader(name: PWideChar): HResult; stdcall; + /// + /// Gets an iterator over the collection of request headers. + /// + function GetIterator(out value: ICoreWebView2HttpHeadersCollectionIterator): HResult; stdcall; + end; + + /// + /// Iterator for a collection of HTTP headers. For more information, navigate + /// to ICoreWebView2HttpRequestHeaders and ICoreWebView2HttpResponseHeaders. + /// + /// + /// See the ICoreWebView2HttpHeadersCollectionIterator article. + /// + ICoreWebView2HttpHeadersCollectionIterator = interface(IUnknown) + ['{0702FC30-F43B-47BB-AB52-A42CB552AD9F}'] + /// + /// Get the name and value of the current HTTP header of the iterator. If + /// the previous `MoveNext` operation set the `hasNext` parameter to `FALSE`, + /// this method fails. + /// + /// The caller must free the returned strings with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function GetCurrentHeader(out name: PWideChar; out value: PWideChar): HResult; stdcall; + /// + /// `TRUE` when the iterator has not run out of headers. If the collection + /// over which the iterator is iterating is empty or if the iterator has gone + /// past the end of the collection then this is `FALSE`. + /// + function Get_HasCurrentHeader(out hasCurrent: Integer): HResult; stdcall; + /// + /// Move the iterator to the next HTTP header in the collection. + /// + /// \> [!NOTE]\n \> If no more HTTP headers exist, the `hasNext` parameter is set to + /// `FALSE`. After this occurs the `GetCurrentHeader` method fails. + /// + function MoveNext(out hasNext: Integer): HResult; stdcall; + end; + + /// + /// Receives `ContentLoading` events. + /// + /// + /// See the ICoreWebView2ContentLoadingEventHandler article. + /// + ICoreWebView2ContentLoadingEventHandler = interface(IUnknown) + ['{364471E7-F2BE-4910-BDBA-D72077D51C4B}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ContentLoadingEventArgs): HResult; stdcall; + end; + + /// + /// Receives ContentLoading events. + /// + /// + /// See the ICoreWebView2ContentLoadingEventArgs article. + /// + ICoreWebView2ContentLoadingEventArgs = interface(IUnknown) + ['{0C8A1275-9B6B-4901-87AD-70DF25BAFA6E}'] + /// + /// `TRUE` if the loaded content is an error page. + /// + function Get_IsErrorPage(out value: Integer): HResult; stdcall; + /// + /// The ID of the navigation. + /// + function Get_NavigationId(out value: Largeuint): HResult; stdcall; + end; + + /// + /// Receives SourceChanged events. + /// + /// + /// See the ICoreWebView2SourceChangedEventHandler article. + /// + ICoreWebView2SourceChangedEventHandler = interface(IUnknown) + ['{3C067F9F-5388-4772-8B48-79F7EF1AB37C}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2SourceChangedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the SourceChanged event. + /// + /// + /// See the ICoreWebView2SourceChangedEventArgs article. + /// + ICoreWebView2SourceChangedEventArgs = interface(IUnknown) + ['{31E0E545-1DBA-4266-8914-F63848A1F7D7}'] + /// + /// `TRUE` if the page being navigated to is a new document. + /// + function Get_IsNewDocument(out value: Integer): HResult; stdcall; + end; + + /// + /// Receives HistoryChanged events. + /// + /// + /// See the ICoreWebView2HistoryChangedEventHandler article. + /// + ICoreWebView2HistoryChangedEventHandler = interface(IUnknown) + ['{C79A420C-EFD9-4058-9295-3E8B4BCAB645}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; + end; + + /// + /// Receives NavigationCompleted events. + /// + /// + /// See the ICoreWebView2NavigationCompletedEventHandler article. + /// + ICoreWebView2NavigationCompletedEventHandler = interface(IUnknown) + ['{D33A35BF-1C49-4F98-93AB-006E0533FE1C}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2NavigationCompletedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the NavigationCompleted event. + /// + /// + /// See the ICoreWebView2NavigationCompletedEventArgs article. + /// + ICoreWebView2NavigationCompletedEventArgs = interface(IUnknown) + ['{30D68B7D-20D9-4752-A9CA-EC8448FBB5C1}'] + /// + /// `TRUE` when the navigation is successful. `FALSE` for a navigation that + /// ended up in an error page (failures due to no network, DNS lookup + /// failure, HTTP server responds with 4xx), but may also be `FALSE` for + /// additional scenarios such as `window.stop()` run on navigated page. + /// Note that WebView2 will report the navigation as 'unsuccessful' if the load + /// for the navigation did not reach the expected completion for any reason. Such + /// reasons include potentially catastrophic issues such network and certificate + /// issues, but can also be the result of intended actions such as the app canceling a navigation or + /// navigating away before the original navigation completed. Applications should not + /// just rely on this flag, but also consider the reported WebErrorStatus to + /// determine whether the failure is indeed catastrophic in their context. + /// WebErrorStatuses that may indicate a non-catastrophic failure include: + /// - COREWEBVIEW2_WEB_ERROR_STATUS_OPERATION_CANCELED + /// - COREWEBVIEW2_WEB_ERROR_STATUS_VALID_AUTHENTICATION_CREDENTIALS_REQUIRED + /// - COREWEBVIEW2_WEB_ERROR_STATUS_VALID_PROXY_AUTHENTICATION_REQUIRED + /// + function Get_IsSuccess(out IsSuccess: Integer): HResult; stdcall; + /// + /// The error code if the navigation failed. + /// + function Get_WebErrorStatus(out WebErrorStatus: COREWEBVIEW2_WEB_ERROR_STATUS): HResult; stdcall; + /// + /// The ID of the navigation. + /// + function Get_NavigationId(out NavigationId: Largeuint): HResult; stdcall; + end; + + /// + /// Receives ScriptDialogOpening events. + /// + /// + /// See the ICoreWebView2ScriptDialogOpeningEventHandler article. + /// + ICoreWebView2ScriptDialogOpeningEventHandler = interface(IUnknown) + ['{EF381BF9-AFA8-4E37-91C4-8AC48524BDFB}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2ScriptDialogOpeningEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the ScriptDialogOpening event. + /// + /// + /// See the ICoreWebView2ScriptDialogOpeningEventArgs article. + /// + ICoreWebView2ScriptDialogOpeningEventArgs = interface(IUnknown) + ['{7390BB70-ABE0-4843-9529-F143B31B03D6}'] + /// + /// The URI of the page that requested the dialog box. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_uri(out uri: PWideChar): HResult; stdcall; + /// + /// The kind of JavaScript dialog box. `alert`, `confirm`, `prompt`, or + /// `beforeunload`. + /// + function Get_Kind(out Kind: COREWEBVIEW2_SCRIPT_DIALOG_KIND): HResult; stdcall; + /// + /// The message of the dialog box. From JavaScript this is the first + /// parameter passed to `alert`, `confirm`, and `prompt` and is empty for + /// `beforeunload`. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Message(out Message: PWideChar): HResult; stdcall; + /// + /// The host may run this to respond with **OK** to `confirm`, `prompt`, and + /// `beforeunload` dialogs. Do not run this method to indicate cancel. + /// From JavaScript, this means that the `confirm` and `beforeunload` function + /// returns `TRUE` if `Accept` is run. And for the prompt function it returns + /// the value of `ResultText` if `Accept` is run and otherwise returns + /// `FALSE`. + /// + function Accept: HResult; stdcall; + /// + /// The second parameter passed to the JavaScript prompt dialog. + /// The result of the prompt JavaScript function uses this value as the + /// default value. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_DefaultText(out DefaultText: PWideChar): HResult; stdcall; + /// + /// The return value from the JavaScript prompt function if `Accept` is run. + /// This value is ignored for dialog kinds other than prompt. If `Accept` + /// is not run, this value is ignored and `FALSE` is returned from prompt. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_ResultText(out ResultText: PWideChar): HResult; stdcall; + /// + /// Sets the `ResultText` property. + /// + function Set_ResultText(ResultText: PWideChar): HResult; stdcall; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this operation to + /// complete the event at a later time. + /// + function GetDeferral(out deferral: ICoreWebView2Deferral): HResult; stdcall; + end; + + /// + /// This interface is used to complete deferrals on event args that support + /// getting deferrals using the GetDeferral method. + /// + /// + /// See the ICoreWebView2Deferral article. + /// + ICoreWebView2Deferral = interface(IUnknown) + ['{C10E7F7B-B585-46F0-A623-8BEFBF3E4EE0}'] + /// + /// Completes the associated deferred event. Complete should only be run + /// once for each deferral taken. + /// + function Complete: HResult; stdcall; + end; + + /// + /// Receives PermissionRequested events. + /// + /// + /// See the ICoreWebView2PermissionRequestedEventHandler article. + /// + ICoreWebView2PermissionRequestedEventHandler = interface(IUnknown) + ['{15E1C6A3-C72A-4DF3-91D7-D097FBEC6BFD}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2PermissionRequestedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the PermissionRequested event. + /// + /// + /// See the ICoreWebView2PermissionRequestedEventArgs article. + /// + ICoreWebView2PermissionRequestedEventArgs = interface(IUnknown) + ['{973AE2EF-FF18-4894-8FB2-3C758F046810}'] + /// + /// The origin of the web content that requests the permission. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_uri(out uri: PWideChar): HResult; stdcall; + /// + /// The type of the permission that is requested. + /// + function Get_PermissionKind(out PermissionKind: COREWEBVIEW2_PERMISSION_KIND): HResult; stdcall; + /// + /// `TRUE` when the permission request was initiated through a user gesture. + /// + /// \> [!NOTE]\n\> Being initiated through a user gesture does not mean that user intended + /// to access the associated resource. + /// + function Get_IsUserInitiated(out IsUserInitiated: Integer): HResult; stdcall; + /// + /// The status of a permission request, (for example is the request is granted). + /// The default value is `COREWEBVIEW2_PERMISSION_STATE_DEFAULT`. + /// + function Get_State(out State: COREWEBVIEW2_PERMISSION_STATE): HResult; stdcall; + /// + /// Sets the `State` property. + /// + function Set_State(State: COREWEBVIEW2_PERMISSION_STATE): HResult; stdcall; + /// + /// Gets an `ICoreWebView2Deferral` object. Use the deferral object to make + /// the permission decision at a later time. The deferral only applies to the + /// current request, and does not prevent the `PermissionRequested` event from + /// getting raised for new requests. However, for some permission kinds the + /// WebView will avoid creating a new request if there is a pending request of + /// the same kind. + /// + function GetDeferral(out deferral: ICoreWebView2Deferral): HResult; stdcall; + end; + + /// + /// Receives ProcessFailed events. + /// + /// + /// See the ICoreWebView2ProcessFailedEventHandler article. + /// + ICoreWebView2ProcessFailedEventHandler = interface(IUnknown) + ['{79E0AEA4-990B-42D9-AA1D-0FCC2E5BC7F1}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2ProcessFailedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the ProcessFailed event. + /// + /// + /// See the ICoreWebView2ProcessFailedEventArgs article. + /// + ICoreWebView2ProcessFailedEventArgs = interface(IUnknown) + ['{8155A9A4-1474-4A86-8CAE-151B0FA6B8CA}'] + /// + /// The kind of process failure that has occurred. This is a combination of + /// process kind (for example, browser, renderer, gpu) and failure (exit, + /// unresponsiveness). Renderer processes are further divided in _main frame_ + /// renderer (`RenderProcessExited`, `RenderProcessUnresponsive`) and + /// _subframe_ renderer (`FrameRenderProcessExited`). To learn about the + /// conditions under which each failure kind occurs, see + /// `COREWEBVIEW2_PROCESS_FAILED_KIND`. + /// + function Get_ProcessFailedKind(out value: COREWEBVIEW2_PROCESS_FAILED_KIND): HResult; stdcall; + end; + + /// + /// Receives the result of the AddScriptToExecuteOnDocumentCreated method. + /// + /// + /// See the ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler article. + /// + ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler = interface(IUnknown) + ['{B99369F3-9B11-47B5-BC6F-8E7895FCEA17}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; result_: PWideChar): HResult; stdcall; + end; + + /// + /// Receives the result of the ExecuteScript method. + /// + /// + /// See the ICoreWebView2ExecuteScriptCompletedHandler article. + /// + ICoreWebView2ExecuteScriptCompletedHandler = interface(IUnknown) + ['{49511172-CC67-4BCA-9923-137112F4C4CC}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; result_: PWideChar): HResult; stdcall; + end; + + /// + /// Receives the result of the CapturePreview method. The result is written + /// to the stream provided in the CapturePreview method. + /// + /// + /// See the ICoreWebView2CapturePreviewCompletedHandler article. + /// + ICoreWebView2CapturePreviewCompletedHandler = interface(IUnknown) + ['{697E05E9-3D8F-45FA-96F4-8FFE1EDEDAF5}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult): HResult; stdcall; + end; + + /// + /// Receives WebMessageReceived events. + /// + /// + /// See the ICoreWebView2WebMessageReceivedEventHandler article. + /// + ICoreWebView2WebMessageReceivedEventHandler = interface(IUnknown) + ['{57213F19-00E6-49FA-8E07-898EA01ECBD2}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2WebMessageReceivedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the WebMessageReceived event. + /// + /// + /// See the ICoreWebView2WebMessageReceivedEventArgs article. + /// + ICoreWebView2WebMessageReceivedEventArgs = interface(IUnknown) + ['{0F99A40C-E962-4207-9E92-E3D542EFF849}'] + /// + /// The URI of the document that sent this web message. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Source(out value: PWideChar): HResult; stdcall; + /// + /// The message posted from the WebView content to the host converted to a + /// JSON string. Run this operation to communicate using JavaScript objects. + /// + /// For example, the following `postMessage` runs result in the following + /// `WebMessageAsJson` values. + /// + /// ```json + /// postMessage({'a': 'b'}) L"{\"a\": \"b\"}" + /// postMessage(1.2) L"1.2" + /// postMessage('example') L"\"example\"" + /// ``` + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_webMessageAsJson(out value: PWideChar): HResult; stdcall; + /// + /// If the message posted from the WebView content to the host is a string + /// type, this method returns the value of that string. If the message + /// posted is some other kind of JavaScript type this method fails with the + /// following error. + /// + /// ```text + /// E_INVALIDARG + /// ``` + /// + /// Run this operation to communicate using simple strings. + /// + /// For example, the following `postMessage` runs result in the following + /// `WebMessageAsString` values. + /// + /// ```json + /// postMessage({'a': 'b'}) E_INVALIDARG + /// postMessage(1.2) E_INVALIDARG + /// postMessage('example') L"example" + /// ``` + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function TryGetWebMessageAsString(out value: PWideChar): HResult; stdcall; + end; + + /// + /// Receives the result of the `CallDevToolsProtocolMethod` method. + /// + /// + /// See the ICoreWebView2CallDevToolsProtocolMethodCompletedHandler article. + /// + ICoreWebView2CallDevToolsProtocolMethodCompletedHandler = interface(IUnknown) + ['{5C4889F0-5EF6-4C5A-952C-D8F1B92D0574}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; result_: PWideChar): HResult; stdcall; + end; + + /// + /// A Receiver is created for a particular DevTools Protocol event and allows + /// you to subscribe and unsubscribe from that event. Obtained from the + /// WebView object using GetDevToolsProtocolEventReceiver. + /// + /// + /// See the ICoreWebView2DevToolsProtocolEventReceiver article. + /// + ICoreWebView2DevToolsProtocolEventReceiver = interface(IUnknown) + ['{B32CA51A-8371-45E9-9317-AF021D080367}'] + /// + /// Adds an event handler for the `DevToolsProtocolEventReceived` event. + /// Subscribe to a `DevToolsProtocol` event. The `Invoke` method of the + /// `handler` runs whenever the corresponding `DevToolsProtocol` event runs. + /// `Invoke` runs with an event args object containing the parameter object + /// of the DevTools Protocol event as a JSON string. + /// + /// \snippet ScriptComponent.cpp DevToolsProtocolEventReceived + /// + function add_DevToolsProtocolEventReceived(const eventHandler: ICoreWebView2DevToolsProtocolEventReceivedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_DevToolsProtocolEventReceived`. + /// + function remove_DevToolsProtocolEventReceived(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives `DevToolsProtocolEventReceived` events. + /// + /// + /// See the ICoreWebView2DevToolsProtocolEventReceivedEventHandler article. + /// + ICoreWebView2DevToolsProtocolEventReceivedEventHandler = interface(IUnknown) + ['{E2FDA4BE-5456-406C-A261-3D452138362C}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2DevToolsProtocolEventReceivedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the DevToolsProtocolEventReceived event. + /// + /// + /// See the ICoreWebView2DevToolsProtocolEventReceivedEventArgs article. + /// + ICoreWebView2DevToolsProtocolEventReceivedEventArgs = interface(IUnknown) + ['{653C2959-BB3A-4377-8632-B58ADA4E66C4}'] + /// + /// The parameter object of the corresponding `DevToolsProtocol` event + /// represented as a JSON string. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_ParameterObjectAsJson(out value: PWideChar): HResult; stdcall; + end; + + /// + /// Receives NewWindowRequested events. + /// + /// + /// See the ICoreWebView2NewWindowRequestedEventHandler article. + /// + ICoreWebView2NewWindowRequestedEventHandler = interface(IUnknown) + ['{D4C185FE-C81C-4989-97AF-2D3FA7AB5651}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2NewWindowRequestedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the NewWindowRequested event. The event is run when + /// content inside webview requested to a open a new window (through + /// window.open() and so on). + /// + /// + /// See the ICoreWebView2NewWindowRequestedEventArgs article. + /// + ICoreWebView2NewWindowRequestedEventArgs = interface(IUnknown) + ['{34ACB11C-FC37-4418-9132-F9C21D1EAFB9}'] + /// + /// The target uri of the new window requested. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_uri(out uri: PWideChar): HResult; stdcall; + /// + /// Sets a CoreWebView2 as a result of the NewWindowRequested event. Provides + /// a WebView as the target for a `window.open()` from inside the + /// requesting WebView. If this is set, the top-level window of this WebView + /// is returned as the opened + /// [WindowProxy](https://developer.mozilla.org/docs/glossary/windowproxy) + /// to the opener script. If this is not set, then `Handled` is checked to + /// determine behavior for NewWindowRequested event. + /// CoreWebView2 provided in the `NewWindow` property must be on the same + /// Environment as the opener WebView and should not have been navigated + /// previously. Don't use methods that cause navigation or interact with the + /// DOM on this CoreWebView2 until the target content has loaded. Setting event + /// handlers, changing Settings properties, or other methods are fine to call. + /// Changes to settings should be made before `put_NewWindow` is called to + /// ensure that those settings take effect for the newly setup WebView. Once the + /// NewWindow is set the underlying web contents of this CoreWebView2 will be + /// replaced and navigated as appropriate for the new window. After setting + /// new window it cannot be changed and error will be return otherwise. + /// + /// The methods which should affect the new web contents like + /// AddScriptToExecuteOnDocumentCreated has to be called and completed before setting NewWindow. + /// Other methods which should affect the new web contents like add_WebResourceRequested have to be called after setting NewWindow. + /// It is best not to use RemoveScriptToExecuteOnDocumentCreated before setting NewWindow, otherwise it may not work for later added scripts. + /// + /// The new WebView must have the same profile as the opener WebView. + /// + function Set_NewWindow(const NewWindow: ICoreWebView2): HResult; stdcall; + /// + /// Gets the new window. + /// + function Get_NewWindow(out NewWindow: ICoreWebView2): HResult; stdcall; + /// + /// Sets whether the `NewWindowRequested` event is handled by host. If this + /// is `FALSE` and no `NewWindow` is set, the WebView opens a popup window + /// and it returns as opened `WindowProxy`. If set to `TRUE` and no + /// `NewWindow` is set for `window.open`, the opened `WindowProxy` is for an + /// testing window object and no window loads. + /// The default value is `FALSE`. + /// + function Set_Handled(Handled: Integer): HResult; stdcall; + /// + /// Gets whether the `NewWindowRequested` event is handled by host. + /// + function Get_Handled(out Handled: Integer): HResult; stdcall; + /// + /// `TRUE` when the new window request was initiated through a user gesture. + /// Examples of user initiated requests are: + /// + /// - Selecting an anchor tag with target + /// - Programmatic window open from a script that directly run as a result of + /// user interaction such as via onclick handlers. + /// + /// Non-user initiated requests are programmatic window opens from a script + /// that are not directly triggered by user interaction, such as those that + /// run while loading a new page or via timers. + /// The Microsoft Edge popup blocker is disabled for WebView so the app is + /// able to use this flag to block non-user initiated popups. + /// + function Get_IsUserInitiated(out IsUserInitiated: Integer): HResult; stdcall; + /// + /// Obtain an `ICoreWebView2Deferral` object and put the event into a + /// deferred state. Use the `ICoreWebView2Deferral` object to complete the + /// window open request at a later time. While this event is deferred the + /// opener window returns a `WindowProxy` to an un-navigated window, which + /// navigates when the deferral is complete. + /// + function GetDeferral(out deferral: ICoreWebView2Deferral): HResult; stdcall; + /// + /// Window features specified by the `window.open`. The features should be + /// considered for positioning and sizing of new webview windows. + /// + function Get_WindowFeatures(out value: ICoreWebView2WindowFeatures): HResult; stdcall; + end; + + /// + /// The window features for a WebView popup window. The fields match the + /// windowFeatures passed to window.open as specified in + /// [Window features](https://developer.mozilla.org/docs/Web/API/Window/open#Window_features) + /// on MDN. + /// There is no requirement for you to respect the values. If your app does + /// not have corresponding UI features (for example, no toolbar) or if all + /// instance of WebView are opened in tabs and do not have distinct size or + /// positions, then your app does not respect the values. You may want to + /// respect values, but perhaps only some apply to the UI of you app. + /// Accordingly, you may respect all, some, or none of the properties as + /// appropriate for your app. For all numeric properties, if the value that is + /// passed to window.open is outside the range of an unsigned 32bit int, the + /// resulting value is the absolute value of the maximum for unsigned 32bit + /// integer. If you are not able to parse the value an integer, it is + /// considered 0. If the value is a floating point value, it is rounded down + /// to an integer. + /// In runtime versions 98 or later, the values of ShouldDisplayMenuBar, + /// ShouldDisplayStatus, ShouldDisplayToolbar, and ShouldDisplayScrollBars + /// will not directly depend on the equivalent fields in the windowFeatures + /// string. Instead, they will all be false if the window is expected to be a + /// popup, and true if it is not. + /// + /// + /// See the ICoreWebView2WindowFeatures article. + /// + ICoreWebView2WindowFeatures = interface(IUnknown) + ['{5EAF559F-B46E-4397-8860-E422F287FF1E}'] + /// + /// Specifies left and top values. + /// + function Get_HasPosition(out value: Integer): HResult; stdcall; + /// + /// Specifies height and width values. + /// + function Get_HasSize(out value: Integer): HResult; stdcall; + /// + /// Specifies the left position of the window. If `HasPosition` is set to + /// `FALSE`, this field is ignored. + /// + function Get_left(out value: SYSUINT): HResult; stdcall; + /// + /// Specifies the top position of the window. If `HasPosition` is set to + /// `FALSE`, this field is ignored. + /// + function Get_top(out value: SYSUINT): HResult; stdcall; + /// + /// Specifies the height of the window. Minimum value is `100`. If + /// `HasSize` is set to `FALSE`, this field is ignored. + /// + function Get_Height(out value: SYSUINT): HResult; stdcall; + /// + /// Specifies the width of the window. Minimum value is `100`. If `HasSize` + /// is set to `FALSE`, this field is ignored. + /// + function Get_Width(out value: SYSUINT): HResult; stdcall; + /// + /// Indicates that the menu bar is displayed. + /// + function Get_ShouldDisplayMenuBar(out value: Integer): HResult; stdcall; + /// + /// Indicates that the status bar is displayed. + /// + function Get_ShouldDisplayStatus(out value: Integer): HResult; stdcall; + /// + /// Indicates that the browser toolbar is displayed. + /// + function Get_ShouldDisplayToolbar(out value: Integer): HResult; stdcall; + /// + /// Indicates that the scroll bars are displayed. + /// + function Get_ShouldDisplayScrollBars(out value: Integer): HResult; stdcall; + end; + + /// + /// Receives DocumentTitleChanged events. Use the DocumentTitle property + /// to get the modified title. + /// + /// + /// See the ICoreWebView2DocumentTitleChangedEventHandler article. + /// + ICoreWebView2DocumentTitleChangedEventHandler = interface(IUnknown) + ['{F5F2B923-953E-4042-9F95-F3A118E1AFD4}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; + end; + + /// + /// Receives ContainsFullScreenElementChanged events. + /// + /// + /// See the ICoreWebView2ContainsFullScreenElementChangedEventHandler article. + /// + ICoreWebView2ContainsFullScreenElementChangedEventHandler = interface(IUnknown) + ['{E45D98B1-AFEF-45BE-8BAF-6C7728867F73}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; + end; + + /// + /// Receives `WebResourceRequested` events. + /// + /// + /// See the ICoreWebView2WebResourceRequestedEventHandler article. + /// + ICoreWebView2WebResourceRequestedEventHandler = interface(IUnknown) + ['{AB00B74C-15F1-4646-80E8-E76341D25D71}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2WebResourceRequestedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the WebResourceRequested event. + /// + /// + /// See the ICoreWebView2WebResourceRequestedEventArgs article. + /// + ICoreWebView2WebResourceRequestedEventArgs = interface(IUnknown) + ['{453E667F-12C7-49D4-BE6D-DDBE7956F57A}'] + /// + /// The Web resource request. The request object may be missing some headers + /// that are added by network stack at a later time. + /// + function Get_Request(out Request: ICoreWebView2WebResourceRequest): HResult; stdcall; + /// + /// A placeholder for the web resource response object. If this object is + /// set, the web resource request is completed with the specified response. + /// + function Get_Response(out Response: ICoreWebView2WebResourceResponse): HResult; stdcall; + /// + /// Sets the `Response` property. Create an empty web resource response + /// object with `CreateWebResourceResponse` and then modify it to construct + /// the response. + /// + function Set_Response(const Response: ICoreWebView2WebResourceResponse): HResult; stdcall; + /// + /// Obtain an `ICoreWebView2Deferral` object and put the event into a + /// deferred state. Use the `ICoreWebView2Deferral` object to complete the + /// request at a later time. + /// + function GetDeferral(out deferral: ICoreWebView2Deferral): HResult; stdcall; + /// + /// The web resource request context. + /// + function Get_ResourceContext(out context: COREWEBVIEW2_WEB_RESOURCE_CONTEXT): HResult; stdcall; + end; + + /// + /// An HTTP request used with the WebResourceRequested event. + /// + /// + /// See the ICoreWebView2WebResourceRequest article. + /// + ICoreWebView2WebResourceRequest = interface(IUnknown) + ['{97055CD4-512C-4264-8B5F-E3F446CEA6A5}'] + /// + /// The request URI. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_uri(out uri: PWideChar): HResult; stdcall; + /// + /// Sets the `Uri` property. + /// + function Set_uri(uri: PWideChar): HResult; stdcall; + /// + /// The HTTP request method. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Method(out Method: PWideChar): HResult; stdcall; + /// + /// Sets the `Method` property. + /// + function Set_Method(Method: PWideChar): HResult; stdcall; + /// + /// The HTTP request message body as stream. POST data should be here. If a + /// stream is set, which overrides the message body, the stream must have + /// all the content data available by the time the `WebResourceRequested` + /// event deferral of this response is completed. Stream should be agile or + /// be created from a background STA to prevent performance impact to the UI + /// thread. `Null` means no content data. `IStream` semantics apply + /// (return `S_OK` to `Read` runs until all data is exhausted). + /// + function Get_Content(out Content: IStream): HResult; stdcall; + /// + /// Sets the `Content` property. + /// + function Set_Content(const Content: IStream): HResult; stdcall; + /// + /// The mutable HTTP request headers + /// + function Get_Headers(out Headers: ICoreWebView2HttpRequestHeaders): HResult; stdcall; + end; + + /// + /// An HTTP response used with the WebResourceRequested event. + /// + /// + /// See the ICoreWebView2WebResourceResponse article. + /// + ICoreWebView2WebResourceResponse = interface(IUnknown) + ['{AAFCC94F-FA27-48FD-97DF-830EF75AAEC9}'] + /// + /// HTTP response content as stream. Stream must have all the content data + /// available by the time the `WebResourceRequested` event deferral of this + /// response is completed. Stream should be agile or be created from a + /// background thread to prevent performance impact to the UI thread. `Null` + /// means no content data. `IStream` semantics apply (return `S_OK` to + /// `Read` runs until all data is exhausted). + /// When providing the response data, you should consider relevant HTTP + /// request headers just like an HTTP server would do. For example, if the + /// request was for a video resource in a HTML video element, the request may + /// contain the [Range](https://developer.mozilla.org/docs/Web/HTTP/Headers/Range) + /// header to request only a part of the video that is streaming. In this + /// case, your response stream should be only the portion of the video + /// specified by the range HTTP request headers and you should set the + /// appropriate + /// [Content-Range](https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Range) + /// header in the response. + /// + function Get_Content(out Content: IStream): HResult; stdcall; + /// + /// Sets the `Content` property. + /// + function Set_Content(const Content: IStream): HResult; stdcall; + /// + /// Overridden HTTP response headers. + /// + function Get_Headers(out Headers: ICoreWebView2HttpResponseHeaders): HResult; stdcall; + /// + /// The HTTP response status code. + /// + function Get_StatusCode(out StatusCode: SYSINT): HResult; stdcall; + /// + /// Sets the `StatusCode` property. + /// + function Set_StatusCode(StatusCode: SYSINT): HResult; stdcall; + /// + /// The HTTP response reason phrase. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_ReasonPhrase(out ReasonPhrase: PWideChar): HResult; stdcall; + /// + /// Sets the `ReasonPhrase` property. + /// + function Set_ReasonPhrase(ReasonPhrase: PWideChar): HResult; stdcall; + end; + + /// + /// HTTP response headers. Used to construct a WebResourceResponse for the + /// WebResourceRequested event. + /// + /// + /// See the ICoreWebView2HttpResponseHeaders article. + /// + ICoreWebView2HttpResponseHeaders = interface(IUnknown) + ['{03C5FF5A-9B45-4A88-881C-89A9F328619C}'] + /// + /// Appends header line with name and value. + /// + function AppendHeader(name: PWideChar; value: PWideChar): HResult; stdcall; + /// + /// Verifies that the headers contain entries that match the header name. + /// + function Contains(name: PWideChar; out value: Integer): HResult; stdcall; + /// + /// Gets the first header value in the collection matching the name. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function GetHeader(name: PWideChar; out value: PWideChar): HResult; stdcall; + /// + /// Gets the header values matching the name. + /// + function GetHeaders(name: PWideChar; out value: ICoreWebView2HttpHeadersCollectionIterator): HResult; stdcall; + /// + /// Gets an iterator over the collection of entire response headers. + /// + function GetIterator(out value: ICoreWebView2HttpHeadersCollectionIterator): HResult; stdcall; + end; + + /// + /// Receives WindowCloseRequested events. + /// + /// + /// See the ICoreWebView2WindowCloseRequestedEventHandler article. + /// + ICoreWebView2WindowCloseRequestedEventHandler = interface(IUnknown) + ['{5C19E9E0-092F-486B-AFFA-CA8231913039}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2 interface. + /// + /// + /// See the ICoreWebView2_2 article. + /// + ICoreWebView2_2 = interface(ICoreWebView2) + ['{9E8F0CF8-E670-4B5E-B2BC-73E061E3184C}'] + /// + /// Add an event handler for the WebResourceResponseReceived event. + /// WebResourceResponseReceived is raised when the WebView receives the + /// response for a request for a web resource (any URI resolution performed by + /// the WebView; such as HTTP/HTTPS, file and data requests from redirects, + /// navigations, declarations in HTML, implicit favicon lookups, and fetch API + /// usage in the document). The host app can use this event to view the actual + /// request and response for a web resource. There is no guarantee about the + /// order in which the WebView processes the response and the host app's + /// handler runs. The app's handler will not block the WebView from processing + /// the response. + /// \snippet ScenarioAuthentication.cpp WebResourceResponseReceived + /// + function add_WebResourceResponseReceived(const eventHandler: ICoreWebView2WebResourceResponseReceivedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with + /// add_WebResourceResponseReceived. + /// + function remove_WebResourceResponseReceived(token: EventRegistrationToken): HResult; stdcall; + /// + /// Navigates using a constructed WebResourceRequest object. This lets you + /// provide post data or additional request headers during navigation. + /// The headers in the WebResourceRequest override headers + /// added by WebView2 runtime except for Cookie headers. + /// Method can only be either "GET" or "POST". Provided post data will only + /// be sent only if the method is "POST" and the uri scheme is HTTP(S). + /// \snippet ScenarioNavigateWithWebResourceRequest.cpp NavigateWithWebResourceRequest + /// + function NavigateWithWebResourceRequest(const Request: ICoreWebView2WebResourceRequest): HResult; stdcall; + /// + /// Add an event handler for the DOMContentLoaded event. + /// DOMContentLoaded is raised when the initial html document has been parsed. + /// This aligns with the document's DOMContentLoaded event in html. + /// + /// \snippet ScenarioDOMContentLoaded.cpp DOMContentLoaded + /// + function add_DOMContentLoaded(const eventHandler: ICoreWebView2DOMContentLoadedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with add_DOMContentLoaded. + /// + function remove_DOMContentLoaded(token: EventRegistrationToken): HResult; stdcall; + /// + /// Gets the cookie manager object associated with this ICoreWebView2. + /// See ICoreWebView2CookieManager. + /// + /// \snippet ScenarioCookieManagement.cpp CookieManager + /// + function Get_CookieManager(out CookieManager: ICoreWebView2CookieManager): HResult; stdcall; + /// + /// Exposes the CoreWebView2Environment used to create this CoreWebView2. + /// + function Get_Environment(out Environment: ICoreWebView2Environment): HResult; stdcall; + end; + + /// + /// Receives WebResourceResponseReceived events. + /// + /// + /// See the ICoreWebView2WebResourceResponseReceivedEventHandler article. + /// + ICoreWebView2WebResourceResponseReceivedEventHandler = interface(IUnknown) + ['{7DE9898A-24F5-40C3-A2DE-D4F458E69828}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2WebResourceResponseReceivedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the WebResourceResponseReceived event. + /// + /// + /// See the ICoreWebView2WebResourceResponseReceivedEventArgs article. + /// + ICoreWebView2WebResourceResponseReceivedEventArgs = interface(IUnknown) + ['{D1DB483D-6796-4B8B-80FC-13712BB716F4}'] + /// + /// The request object for the web resource, as committed. This includes + /// headers added by the network stack that were not be included during the + /// associated WebResourceRequested event, such as Authentication headers. + /// Modifications to this object have no effect on how the request is + /// processed as it has already been sent. + /// + function Get_Request(out value: ICoreWebView2WebResourceRequest): HResult; stdcall; + /// + /// View of the response object received for the web resource. + /// + function Get_Response(out value: ICoreWebView2WebResourceResponseView): HResult; stdcall; + end; + + /// + /// View of the HTTP representation for a web resource response. The properties + /// of this object are not mutable. This response view is used with the + /// WebResourceResponseReceived event. + /// + /// + /// See the ICoreWebView2WebResourceResponseView article. + /// + ICoreWebView2WebResourceResponseView = interface(IUnknown) + ['{79701053-7759-4162-8F7D-F1B3F084928D}'] + /// + /// The HTTP response headers as received. + /// + function Get_Headers(out Headers: ICoreWebView2HttpResponseHeaders): HResult; stdcall; + /// + /// The HTTP response status code. + /// + function Get_StatusCode(out StatusCode: SYSINT): HResult; stdcall; + /// + /// The HTTP response reason phrase. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_ReasonPhrase(out ReasonPhrase: PWideChar): HResult; stdcall; + /// + /// Get the response content asynchronously. The handler will receive the + /// response content stream. + /// + /// This method returns null if content size is more than 123MB or for navigations that become downloads + /// or if response is downloadable content type (e.g., application/octet-stream). + /// See `add_DownloadStarting` event to handle the response. + /// + /// If this method is being called again before a first call has completed, + /// the handler will be invoked at the same time the handlers from prior calls + /// are invoked. + /// If this method is being called after a first call has completed, the + /// handler will be invoked immediately. + /// \snippet ScenarioWebViewEventMonitor.cpp GetContent + /// + function GetContent(const handler: ICoreWebView2WebResourceResponseViewGetContentCompletedHandler): HResult; stdcall; + end; + + /// + /// Receives the result of the `GetContent` method. + /// + /// + /// See the ICoreWebView2WebResourceResponseViewGetContentCompletedHandler article. + /// + ICoreWebView2WebResourceResponseViewGetContentCompletedHandler = interface(IUnknown) + ['{875738E1-9FA2-40E3-8B74-2E8972DD6FE7}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; const result_: IStream): HResult; stdcall; + end; + + /// + /// Receives DOMContentLoaded events. + /// + /// + /// See the ICoreWebView2DOMContentLoadedEventHandler article. + /// + ICoreWebView2DOMContentLoadedEventHandler = interface(IUnknown) + ['{4BAC7E9C-199E-49ED-87ED-249303ACF019}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DOMContentLoadedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the DOMContentLoaded event. + /// + /// + /// See the ICoreWebView2DOMContentLoadedEventArgs article. + /// + ICoreWebView2DOMContentLoadedEventArgs = interface(IUnknown) + ['{16B1E21A-C503-44F2-84C9-70ABA5031283}'] + /// + /// The ID of the navigation which corresponds to other navigation ID properties on other navigation events. + /// + function Get_NavigationId(out value: Largeuint): HResult; stdcall; + end; + + /// + /// Creates, adds or updates, gets, or or view the cookies. The changes would + /// apply to the context of the user profile. That is, other WebViews under the + /// same user profile could be affected. + /// + /// + /// See the ICoreWebView2CookieManager article. + /// + ICoreWebView2CookieManager = interface(IUnknown) + ['{177CD9E7-B6F5-451A-94A0-5D7A3A4C4141}'] + /// + /// Create a cookie object with a specified name, value, domain, and path. + /// One can set other optional properties after cookie creation. + /// This only creates a cookie object and it is not added to the cookie + /// manager until you call AddOrUpdateCookie. + /// Leading or trailing whitespace(s), empty string, and special characters + /// are not allowed for name. + /// See ICoreWebView2Cookie for more details. + /// + function CreateCookie(name: PWideChar; value: PWideChar; Domain: PWideChar; Path: PWideChar; + out cookie: ICoreWebView2Cookie): HResult; stdcall; + /// + /// Creates a cookie whose params matches those of the specified cookie. + /// + function CopyCookie(const cookieParam: ICoreWebView2Cookie; out cookie: ICoreWebView2Cookie): HResult; stdcall; + /// + /// Gets a list of cookies matching the specific URI. + /// If uri is empty string or null, all cookies under the same profile are + /// returned. + /// You can modify the cookie objects by calling + /// ICoreWebView2CookieManager::AddOrUpdateCookie, and the changes + /// will be applied to the webview. + /// \snippet ScenarioCookieManagement.cpp GetCookies + /// + function GetCookies(uri: PWideChar; const handler: ICoreWebView2GetCookiesCompletedHandler): HResult; stdcall; + /// + /// Adds or updates a cookie with the given cookie data; may overwrite + /// cookies with matching name, domain, and path if they exist. + /// This method will fail if the domain of the given cookie is not specified. + /// \snippet ScenarioCookieManagement.cpp AddOrUpdateCookie + /// + function AddOrUpdateCookie(const cookie: ICoreWebView2Cookie): HResult; stdcall; + /// + /// Deletes a cookie whose name and domain/path pair + /// match those of the specified cookie. + /// + function DeleteCookie(const cookie: ICoreWebView2Cookie): HResult; stdcall; + /// + /// Deletes cookies with matching name and uri. + /// Cookie name is required. + /// All cookies with the given name where domain + /// and path match provided URI are deleted. + /// + function DeleteCookies(name: PWideChar; uri: PWideChar): HResult; stdcall; + /// + /// Deletes cookies with matching name and domain/path pair. + /// Cookie name is required. + /// If domain is specified, deletes only cookies with the exact domain. + /// If path is specified, deletes only cookies with the exact path. + /// + function DeleteCookiesWithDomainAndPath(name: PWideChar; Domain: PWideChar; Path: PWideChar): HResult; stdcall; + /// + /// Deletes all cookies under the same profile. + /// This could affect other WebViews under the same user profile. + /// + function DeleteAllCookies: HResult; stdcall; + end; + + /// + /// Provides a set of properties that are used to manage an + /// ICoreWebView2Cookie. + /// + /// + /// See the ICoreWebView2Cookie article. + /// + ICoreWebView2Cookie = interface(IUnknown) + ['{AD26D6BE-1486-43E6-BF87-A2034006CA21}'] + /// + /// Cookie name. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_name(out name: PWideChar): HResult; stdcall; + /// + /// Cookie value. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_value(out value: PWideChar): HResult; stdcall; + /// + /// Set the cookie value property. + /// + function Set_value(value: PWideChar): HResult; stdcall; + /// + /// The domain for which the cookie is valid. + /// The default is the host that this cookie has been received from. + /// Note that, for instance, ".bing.com", "bing.com", and "www.bing.com" are + /// considered different domains. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Domain(out Domain: PWideChar): HResult; stdcall; + /// + /// The path for which the cookie is valid. The default is "/", which means + /// this cookie will be sent to all pages on the Domain. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Path(out Path: PWideChar): HResult; stdcall; + /// + /// The expiration date and time for the cookie as the number of seconds since the UNIX epoch. + /// The default is -1.0, which means cookies are session cookies by default. + /// + function Get_Expires(out Expires: Double): HResult; stdcall; + /// + /// Set the Expires property. Cookies are session cookies and will not be + /// persistent if Expires is set to -1.0. NaN, infinity, and any negative + /// value set other than -1.0 is disallowed. + /// + function Set_Expires(Expires: Double): HResult; stdcall; + /// + /// Whether this cookie is http-only. + /// True if a page script or other active content cannot access this + /// cookie. The default is false. + /// + function Get_IsHttpOnly(out IsHttpOnly: Integer): HResult; stdcall; + /// + /// Set the IsHttpOnly property. + /// + function Set_IsHttpOnly(IsHttpOnly: Integer): HResult; stdcall; + /// + /// SameSite status of the cookie which represents the enforcement mode of the cookie. + /// The default is COREWEBVIEW2_COOKIE_SAME_SITE_KIND_LAX. + /// + function Get_SameSite(out SameSite: COREWEBVIEW2_COOKIE_SAME_SITE_KIND): HResult; stdcall; + /// + /// Set the SameSite property. + /// + function Set_SameSite(SameSite: COREWEBVIEW2_COOKIE_SAME_SITE_KIND): HResult; stdcall; + /// + /// The security level of this cookie. True if the client is only to return + /// the cookie in subsequent requests if those requests use HTTPS. + /// The default is false. + /// Note that cookie that requests COREWEBVIEW2_COOKIE_SAME_SITE_KIND_NONE but + /// is not marked Secure will be rejected. + /// + function Get_IsSecure(out IsSecure: Integer): HResult; stdcall; + /// + /// Set the IsSecure property. + /// + function Set_IsSecure(IsSecure: Integer): HResult; stdcall; + /// + /// Whether this is a session cookie. The default is false. + /// + function Get_IsSession(out IsSession: Integer): HResult; stdcall; + end; + + /// + /// Receives the result of the GetCookies method. + /// + /// + /// See the ICoreWebView2GetCookiesCompletedHandler article. + /// + ICoreWebView2GetCookiesCompletedHandler = interface(IUnknown) + ['{5A4F5069-5C15-47C3-8646-F4DE1C116670}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; const result_: ICoreWebView2CookieList): HResult; stdcall; + end; + + /// + /// A collection of ICoreWebView2Cookie. + /// + /// + /// See the ICoreWebView2CookieList article. + /// + ICoreWebView2CookieList = interface(IUnknown) + ['{F7F6F714-5D2A-43C6-9503-346ECE02D186}'] + /// + /// The number of elements contained in the collection. + /// + function Get_Count(out value: SYSUINT): HResult; stdcall; + /// + /// Gets the element at the given index. + /// + function GetValueAtIndex(index: SYSUINT; out value: ICoreWebView2Cookie): HResult; stdcall; + end; + + /// + /// Represents the WebView2 Environment. WebViews created from an environment + /// run on the browser process specified with environment parameters and + /// objects created from an environment should be used in the same + /// environment. Using it in different environments are not guaranteed to be + /// compatible and may fail. + /// + /// + /// See the ICoreWebView2Environment article. + /// + ICoreWebView2Environment = interface(IUnknown) + ['{B96D755E-0319-4E92-A296-23436F46A1FC}'] + /// + /// Asynchronously create a new WebView. + /// + /// `parentWindow` is the `HWND` in which the WebView should be displayed and + /// from which receive input. The WebView adds a child window to the + /// provided window before this function returns. Z-order and other things + /// impacted by sibling window order are affected accordingly. If you want to + /// move the WebView to a different parent after it has been created, you must + /// call put_ParentWindow to update tooltip positions, accessibility trees, + /// and such. + /// + /// HWND_MESSAGE is a valid parameter for `parentWindow` for an invisible + /// WebView for Windows 8 and above. In this case the window will never + /// become visible. You are not able to reparent the window after you have + /// created the WebView. This is not supported in Windows 7 or below. + /// Passing this parameter in Windows 7 or below will return + /// ERROR_INVALID_WINDOW_HANDLE in the controller callback. + /// + /// It is recommended that the app set Application User Model ID for the + /// process or the app window. If none is set, during WebView creation a + /// generated Application User Model ID is set to root window of + /// `parentWindow`. + /// + /// \snippet AppWindow.cpp CreateCoreWebView2Controller + /// + /// It is recommended that the app handles restart manager messages, to + /// gracefully restart it in the case when the app is using the WebView2 + /// Runtime from a certain installation and that installation is being + /// uninstalled. For example, if a user installs a version of the WebView2 + /// Runtime and opts to use another version of the WebView2 Runtime for + /// testing the app, and then uninstalls the 1st version of the WebView2 + /// Runtime without closing the app, the app restarts to allow + /// un-installation to succeed. + /// + /// \snippet AppWindow.cpp RestartManager + /// + /// The app should retry `CreateCoreWebView2Controller` upon failure, unless the + /// error code is `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`. + /// When the app retries `CreateCoreWebView2Controller` upon failure, it is + /// recommended that the app restarts from creating a new WebView2 + /// Environment. If a WebView2 Runtime update happens, the version + /// associated with a WebView2 Environment may have been removed and causing + /// the object to no longer work. Creating a new WebView2 Environment works + /// since it uses the latest version. + /// + /// WebView creation fails with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)` if a + /// running instance using the same user data folder exists, and the Environment + /// objects have different `EnvironmentOptions`. For example, if a WebView was + /// created with one language, an attempt to create a WebView with a different + /// language using the same user data folder will fail. + /// + /// The creation will fail with `E_ABORT` if `parentWindow` is destroyed + /// before the creation is finished. If this is caused by a call to + /// `DestroyWindow`, the creation completed handler will be invoked before + /// `DestroyWindow` returns, so you can use this to cancel creation and clean + /// up resources synchronously when quitting a thread. + /// + /// In rare cases the creation can fail with `E_UNEXPECTED` if runtime does not have + /// permissions to the user data folder. + /// + function CreateCoreWebView2Controller(ParentWindow: HWND; + const handler: ICoreWebView2CreateCoreWebView2ControllerCompletedHandler): HResult; stdcall; + /// + /// Create a new web resource response object. The `headers` parameter is + /// the raw response header string delimited by newline. It is also possible + /// to create this object with null headers string and then use the + /// `ICoreWebView2HttpResponseHeaders` to construct the headers line by line. + /// For more information about other parameters, navigate to + /// [ICoreWebView2WebResourceResponse](/microsoft-edge/webview2/reference/win32/icorewebview2webresourceresponse). + /// + /// \snippet SettingsComponent.cpp WebResourceRequested0 + /// \snippet SettingsComponent.cpp WebResourceRequested1 + /// + function CreateWebResourceResponse(const Content: IStream; StatusCode: SYSINT; + ReasonPhrase: PWideChar; Headers: PWideChar; + out Response: ICoreWebView2WebResourceResponse): HResult; stdcall; + /// + /// The browser version info of the current `ICoreWebView2Environment`, + /// including channel name if it is not the WebView2 Runtime. It matches the + /// format of the `GetAvailableCoreWebView2BrowserVersionString` API. + /// Channel names are `beta`, `dev`, and `canary`. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + /// \snippet AppWindow.cpp GetBrowserVersionString + /// + function Get_BrowserVersionString(out versionInfo: PWideChar): HResult; stdcall; + /// + /// Add an event handler for the `NewBrowserVersionAvailable` event. + /// `NewBrowserVersionAvailable` runs when a newer version of the WebView2 + /// Runtime is installed and available using WebView2. To use the newer + /// version of the browser you must create a new environment and WebView. + /// The event only runs for new version from the same WebView2 Runtime from + /// which the code is running. When not running with installed WebView2 + /// Runtime, no event is run. + /// + /// Because a user data folder is only able to be used by one browser + /// process at a time, if you want to use the same user data folder in the + /// WebView using the new version of the browser, you must close the + /// environment and instance of WebView that are using the older version of + /// the browser first. Or simply prompt the user to restart the app. + /// + /// \snippet AppWindow.cpp NewBrowserVersionAvailable + /// + function add_NewBrowserVersionAvailable(const eventHandler: ICoreWebView2NewBrowserVersionAvailableEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_NewBrowserVersionAvailable`. + /// + function remove_NewBrowserVersionAvailable(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives the result of the `CreateCoreWebView2Controller` method. + /// + /// + /// See the ICoreWebView2CreateCoreWebView2ControllerCompletedHandler article. + /// + ICoreWebView2CreateCoreWebView2ControllerCompletedHandler = interface(IUnknown) + ['{6C4819F3-C9B7-4260-8127-C9F5BDE7F68C}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; const result_: ICoreWebView2Controller): HResult; stdcall; + end; + + /// + /// Receives NewBrowserVersionAvailable events. + /// + /// + /// See the ICoreWebView2NewBrowserVersionAvailableEventHandler article. + /// + ICoreWebView2NewBrowserVersionAvailableEventHandler = interface(IUnknown) + ['{F9A2976E-D34E-44FC-ADEE-81B6B57CA914}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Environment; const args: IUnknown): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2_2 interface. + /// + /// + /// See the ICoreWebView2_3 article. + /// + ICoreWebView2_3 = interface(ICoreWebView2_2) + ['{A0D6DF20-3B92-416D-AA0C-437A9C727857}'] + /// + /// An app may call the `TrySuspend` API to have the WebView2 consume less memory. + /// This is useful when a Win32 app becomes invisible, or when a Universal Windows + /// Platform app is being suspended, during the suspended event handler before completing + /// the suspended event. + /// The CoreWebView2Controller's IsVisible property must be false when the API is called. + /// Otherwise, the API fails with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`. + /// Suspending is similar to putting a tab to sleep in the Edge browser. Suspending pauses + /// WebView script timers and animations, minimizes CPU usage for the associated + /// browser renderer process and allows the operating system to reuse the memory that was + /// used by the renderer process for other processes. + /// Note that Suspend is best effort and considered completed successfully once the request + /// is sent to browser renderer process. If there is a running script, the script will continue + /// to run and the renderer process will be suspended after that script is done. + /// See [Sleeping Tabs FAQ](https://techcommunity.microsoft.com/t5/articles/sleeping-tabs-faq/m-p/1705434) + /// for conditions that might prevent WebView from being suspended. In those situations, + /// the completed handler will be invoked with isSuccessful as false and errorCode as S_OK. + /// The WebView will be automatically resumed when it becomes visible. Therefore, the + /// app normally does not have to call `Resume` explicitly. + /// The app can call `Resume` and then `TrySuspend` periodically for an invisible WebView so that + /// the invisible WebView can sync up with latest data and the page ready to show fresh content + /// when it becomes visible. + /// All WebView APIs can still be accessed when a WebView is suspended. Some APIs like Navigate + /// will auto resume the WebView. To avoid unexpected auto resume, check `IsSuspended` property + /// before calling APIs that might change WebView state. + /// + /// \snippet ViewComponent.cpp ToggleIsVisibleOnMinimize + /// + /// \snippet ViewComponent.cpp Suspend + /// + function TrySuspend(const handler: ICoreWebView2TrySuspendCompletedHandler): HResult; stdcall; + /// + /// Resumes the WebView so that it resumes activities on the web page. + /// This API can be called while the WebView2 controller is invisible. + /// The app can interact with the WebView immediately after `Resume`. + /// WebView will be automatically resumed when it becomes visible. + /// + /// \snippet ViewComponent.cpp ToggleIsVisibleOnMinimize + /// + /// \snippet ViewComponent.cpp Resume + /// + function Resume: HResult; stdcall; + /// + /// Whether WebView is suspended. + /// `TRUE` when WebView is suspended, from the time when TrySuspend has completed + /// successfully until WebView is resumed. + /// + function Get_IsSuspended(out IsSuspended: Integer): HResult; stdcall; + /// + /// Sets a mapping between a virtual host name and a folder path to make available to web sites + /// via that host name. + /// + /// After setting the mapping, documents loaded in the WebView can use HTTP or HTTPS URLs at + /// the specified host name specified by hostName to access files in the local folder specified + /// by folderPath. + /// + /// This mapping applies to both top-level document and iframe navigations as well as subresource + /// references from a document. This also applies to web workers including dedicated/shared worker + /// and service worker, for loading either worker scripts or subresources + /// (importScripts(), fetch(), XHR, etc.) issued from within a worker. + /// For virtual host mapping to work with service worker, please keep the virtual host name + /// mappings consistent among all WebViews sharing the same browser instance. As service worker + /// works independently of WebViews, we merge mappings from all WebViews when resolving virtual + /// host name, inconsistent mappings between WebViews would lead unexpected behavior. + /// + /// Due to a current implementation limitation, media files accessed using virtual host name can be + /// very slow to load. + /// As the resource loaders for the current page might have already been created and running, + /// changes to the mapping might not be applied to the current page and a reload of the page is + /// needed to apply the new mapping. + /// + /// Both absolute and relative paths are supported for folderPath. Relative paths are interpreted + /// as relative to the folder where the exe of the app is in. + /// + /// Note that the folderPath length must not exceed the Windows MAX_PATH limit. + /// + /// accessKind specifies the level of access to resources under the virtual host from other sites. + /// + /// For example, after calling + /// ```cpp + /// SetVirtualHostNameToFolderMapping( + /// L"appassets.example", L"assets", + /// COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_DENY); + /// ``` + /// navigating to `https://appassets.example/my-local-file.html` will + /// show the content from my-local-file.html in the assets subfolder located on disk under + /// the same path as the app's executable file. + /// + /// DOM elements that want to reference local files will have their host reference virtual host in the source. + /// If there are multiple folders being used, define one unique virtual host per folder. + /// For example, you can embed a local image like this + /// ```cpp + /// WCHAR c_navString[] = L""; + /// m_webView->NavigateToString(c_navString); + /// ``` + /// The example above shows the image wv2.png by resolving the folder mapping above. + /// + /// You should typically choose virtual host names that are never used by real sites. + /// If you own a domain such as example.com, another option is to use a subdomain reserved for + /// the app (like my-app.example.com). + /// + /// [RFC 6761](https://tools.ietf.org/html/rfc6761) has reserved several special-use domain + /// names that are guaranteed to not be used by real sites (for example, .example, .test, and + /// .invalid.) + /// + /// Note that using `.local` as the top-level domain name will work but can cause a delay + /// during navigations. You should avoid using `.local` if you can. + /// + /// Apps should use distinct domain names when mapping folder from different sources that + /// should be isolated from each other. For instance, the app might use app-file.example for + /// files that ship as part of the app, and book1.example might be used for files containing + /// books from a less trusted source that were previously downloaded and saved to the disk by + /// the app. + /// + /// The host name used in the APIs is canonicalized using Chromium's host name parsing logic + /// before being used internally. For more information see [HTML5 2.6 URLs](https://dev.w3.org/html5/spec-LC/urls.html). + /// + /// All host names that are canonicalized to the same string are considered identical. + /// For example, `EXAMPLE.COM` and `example.com` are treated as the same host name. + /// An international host name and its Punycode-encoded host name are considered the same host + /// name. There is no DNS resolution for host name and the trailing '.' is not normalized as + /// part of canonicalization. + /// + /// Therefore `example.com` and `example.com.` are treated as different host names. Similarly, + /// `virtual-host-name` and `virtual-host-name.example.com` are treated as different host names + /// even if the machine has a DNS suffix of `example.com`. + /// + /// Specify the minimal cross-origin access necessary to run the app. If there is not a need to + /// access local resources from other origins, use COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_DENY. + /// + /// \snippet AppWindow.cpp AddVirtualHostNameToFolderMapping + /// + /// \snippet AppWindow.cpp LocalUrlUsage + /// + function SetVirtualHostNameToFolderMapping(hostName: PWideChar; folderPath: PWideChar; + accessKind: COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND): HResult; stdcall; + /// + /// Clears a host name mapping for local folder that was added by `SetVirtualHostNameToFolderMapping`. + /// + function ClearVirtualHostNameToFolderMapping(hostName: PWideChar): HResult; stdcall; + end; + + /// + /// Receives the result of the `TrySuspend` method. + /// + /// + /// See the ICoreWebView2TrySuspendCompletedHandler article. + /// + ICoreWebView2TrySuspendCompletedHandler = interface(IUnknown) + ['{00F206A7-9D17-4605-91F6-4E8E4DE192E3}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; result_: Integer): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2_3 interface to support FrameCreated and + /// DownloadStarting events. + /// + /// + /// See the ICoreWebView2_4 article. + /// + ICoreWebView2_4 = interface(ICoreWebView2_3) + ['{20D02D59-6DF2-42DC-BD06-F98A694B1302}'] + /// + /// Raised when a new iframe is created. + /// Handle this event to get access to ICoreWebView2Frame objects. + /// Use ICoreWebView2Frame.add_Destroyed to listen for when this iframe goes + /// away. + /// + function add_FrameCreated(const eventHandler: ICoreWebView2FrameCreatedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with add_FrameCreated. + /// + function remove_FrameCreated(token: EventRegistrationToken): HResult; stdcall; + /// + /// Add an event handler for the `DownloadStarting` event. This event is + /// raised when a download has begun, blocking the default download dialog, + /// but not blocking the progress of the download. + /// + /// The host can choose to cancel a download, change the result file path, + /// and hide the default download dialog. + /// If the host chooses to cancel the download, the download is not saved, no + /// dialog is shown, and the state is changed to + /// COREWEBVIEW2_DOWNLOAD_STATE_INTERRUPTED with interrupt reason + /// COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_USER_CANCELED. Otherwise, the + /// download is saved to the default path after the event completes, + /// and default download dialog is shown if the host did not choose to hide it. + /// The host can change the visibility of the download dialog using the + /// `Handled` property. If the event is not handled, downloads complete + /// normally with the default dialog shown. + /// + /// \snippet ScenarioCustomDownloadExperience.cpp DownloadStarting + /// + function add_DownloadStarting(const eventHandler: ICoreWebView2DownloadStartingEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_DownloadStarting`. + /// + function remove_DownloadStarting(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives `FrameCreated` events. + /// + /// + /// See the ICoreWebView2FrameCreatedEventHandler article. + /// + ICoreWebView2FrameCreatedEventHandler = interface(IUnknown) + ['{38059770-9BAA-11EB-A8B3-0242AC130003}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2FrameCreatedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the FrameCreated events. + /// + /// + /// See the ICoreWebView2FrameCreatedEventArgs article. + /// + ICoreWebView2FrameCreatedEventArgs = interface(IUnknown) + ['{4D6E7B5E-9BAA-11EB-A8B3-0242AC130003}'] + /// + /// The frame which was created. + /// + function Get_Frame(out value: ICoreWebView2Frame): HResult; stdcall; + end; + + /// + /// ICoreWebView2Frame provides direct access to the iframes information. + /// You can get an ICoreWebView2Frame by handling the ICoreWebView2_4.add_FrameCreated event. + /// + /// + /// See the ICoreWebView2Frame article. + /// + ICoreWebView2Frame = interface(IUnknown) + ['{F1131A5E-9BA9-11EB-A8B3-0242AC130003}'] + /// + /// The value of iframe's window.name property. The default value equals to + /// iframe html tag declaring it. You can access this property even if the + /// iframe is destroyed. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_name(out name: PWideChar): HResult; stdcall; + /// + /// Raised when the iframe changes its window.name property. + /// + function add_NameChanged(const eventHandler: ICoreWebView2FrameNameChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with add_NameChanged. + /// + function remove_NameChanged(token: EventRegistrationToken): HResult; stdcall; + /// + /// Add the provided host object to script running in the iframe with the + /// specified name for the list of the specified origins. The host object + /// will be accessible for this iframe only if the iframe's origin during + /// access matches one of the origins which are passed. The provided origins + /// will be normalized before comparing to the origin of the document. + /// So the scheme name is made lower case, the host will be punycode decoded + /// as appropriate, default port values will be removed, and so on. + /// This means the origin's host may be punycode encoded or not and will match + /// regardless. If list contains malformed origin the call will fail. + /// The method can be called multiple times in a row without calling + /// RemoveHostObjectFromScript for the same object name. It will replace + /// the previous object with the new object and new list of origins. + /// List of origins will be treated as following: + /// 1. empty list - call will succeed and object will be added for the iframe + /// but it will not be exposed to any origin; + /// 2. list with origins - during access to host object from iframe the + /// origin will be checked that it belongs to this list; + /// 3. list with "*" element - host object will be available for iframe for + /// all origins. We suggest not to use this feature without understanding + /// security implications of giving access to host object from from iframes + /// with unknown origins. + /// 4. list with "file://" element - host object will be available for iframes + /// loaded via file protocol. + /// Calling this method fails if it is called after the iframe is destroyed. + /// \snippet ScenarioAddHostObject.cpp AddHostObjectToScriptWithOrigins + /// For more information about host objects navigate to + /// ICoreWebView2::AddHostObjectToScript. + /// + function AddHostObjectToScriptWithOrigins(name: PWideChar; const object_: OleVariant; + originsCount: SYSUINT; var origins: PWideChar): HResult; stdcall; + /// + /// Remove the host object specified by the name so that it is no longer + /// accessible from JavaScript code in the iframe. While new access + /// attempts are denied, if the object is already obtained by JavaScript code + /// in the iframe, the JavaScript code continues to have access to that + /// object. Calling this method for a name that is already removed or was + /// never added fails. If the iframe is destroyed this method will return fail + /// also. + /// + function RemoveHostObjectFromScript(name: PWideChar): HResult; stdcall; + /// + /// The Destroyed event is raised when the iframe corresponding + /// to this CoreWebView2Frame object is removed or the document + /// containing that iframe is destroyed. + /// + function add_Destroyed(const eventHandler: ICoreWebView2FrameDestroyedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with add_Destroyed. + /// + function remove_Destroyed(token: EventRegistrationToken): HResult; stdcall; + /// + /// Check whether a frame is destroyed. Returns true during + /// the Destroyed event. + /// + function IsDestroyed(out destroyed: Integer): HResult; stdcall; + end; + + /// + /// Receives `NameChanged` events. + /// + /// + /// See the ICoreWebView2FrameNameChangedEventHandler article. + /// + ICoreWebView2FrameNameChangedEventHandler = interface(IUnknown) + ['{435C7DC8-9BAA-11EB-A8B3-0242AC130003}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Frame; const args: IUnknown): HResult; stdcall; + end; + + /// + /// Receives `Destroyed` events. + /// + /// + /// See the ICoreWebView2FrameDestroyedEventHandler article. + /// + ICoreWebView2FrameDestroyedEventHandler = interface(IUnknown) + ['{59DD7B4C-9BAA-11EB-A8B3-0242AC130003}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Frame; const args: IUnknown): HResult; stdcall; + end; + + /// + /// Receives `DownloadStarting` events. + /// + /// + /// See the ICoreWebView2DownloadStartingEventHandler article. + /// + ICoreWebView2DownloadStartingEventHandler = interface(IUnknown) + ['{EFEDC989-C396-41CA-83F7-07F845A55724}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DownloadStartingEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the DownloadStarting event. + /// + /// + /// See the ICoreWebView2DownloadStartingEventArgs article. + /// + ICoreWebView2DownloadStartingEventArgs = interface(IUnknown) + ['{E99BBE21-43E9-4544-A732-282764EAFA60}'] + /// + /// Returns the `ICoreWebView2DownloadOperation` for the download that + /// has started. + /// + function Get_DownloadOperation(out DownloadOperation: ICoreWebView2DownloadOperation): HResult; stdcall; + /// + /// The host may set this flag to cancel the download. If canceled, the + /// download save dialog is not displayed regardless of the + /// `Handled` property. + /// + function Get_Cancel(out Cancel: Integer): HResult; stdcall; + /// + /// Sets the `Cancel` property. + /// + function Set_Cancel(Cancel: Integer): HResult; stdcall; + /// + /// The path to the file. If setting the path, the host should ensure that it + /// is an absolute path, including the file name, and that the path does not + /// point to an existing file. If the path points to an existing file, the + /// file will be overwritten. If the directory does not exist, it is created. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_ResultFilePath(out ResultFilePath: PWideChar): HResult; stdcall; + /// + /// Sets the `ResultFilePath` property. + /// + function Set_ResultFilePath(ResultFilePath: PWideChar): HResult; stdcall; + /// + /// The host may set this flag to `TRUE` to hide the default download dialog + /// for this download. The download will progress as normal if it is not + /// canceled, there will just be no default UI shown. By default the value is + /// `FALSE` and the default download dialog is shown. + /// + function Get_Handled(out Handled: Integer): HResult; stdcall; + /// + /// Sets the `Handled` property. + /// + function Set_Handled(Handled: Integer): HResult; stdcall; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this operation to + /// complete the event at a later time. + /// + function GetDeferral(out deferral: ICoreWebView2Deferral): HResult; stdcall; + end; + + /// + /// Represents a download operation. Gives access to the download's metadata + /// and supports a user canceling, pausing, or resuming the download. + /// + /// + /// See the ICoreWebView2DownloadOperation article. + /// + ICoreWebView2DownloadOperation = interface(IUnknown) + ['{3D6B6CF2-AFE1-44C7-A995-C65117714336}'] + /// + /// Add an event handler for the `BytesReceivedChanged` event. + /// + /// \snippet ScenarioCustomDownloadExperience.cpp BytesReceivedChanged + /// + function add_BytesReceivedChanged(const eventHandler: ICoreWebView2BytesReceivedChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_BytesReceivedChanged`. + /// + function remove_BytesReceivedChanged(token: EventRegistrationToken): HResult; stdcall; + /// + /// Add an event handler for the `EstimatedEndTimeChanged` event. + /// + function add_EstimatedEndTimeChanged(const eventHandler: ICoreWebView2EstimatedEndTimeChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_EstimatedEndTimeChanged`. + /// + function remove_EstimatedEndTimeChanged(token: EventRegistrationToken): HResult; stdcall; + /// + /// Add an event handler for the `StateChanged` event. + /// + /// \snippet ScenarioCustomDownloadExperience.cpp StateChanged + /// + function add_StateChanged(const eventHandler: ICoreWebView2StateChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_StateChanged`. + /// + function remove_StateChanged(token: EventRegistrationToken): HResult; stdcall; + /// + /// The URI of the download. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_uri(out uri: PWideChar): HResult; stdcall; + /// + /// The Content-Disposition header value from the download's HTTP response. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_ContentDisposition(out ContentDisposition: PWideChar): HResult; stdcall; + /// + /// MIME type of the downloaded content. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_MimeType(out MimeType: PWideChar): HResult; stdcall; + /// + /// The expected size of the download in total number of bytes based on the + /// HTTP Content-Length header. Returns -1 if the size is unknown. + /// + function Get_TotalBytesToReceive(out TotalBytesToReceive: Int64): HResult; stdcall; + /// + /// The number of bytes that have been written to the download file. + /// + function Get_BytesReceived(out BytesReceived: Int64): HResult; stdcall; + /// + /// The estimated end time in [ISO 8601 Date and Time Format](https://www.iso.org/iso-8601-date-and-time-format.html). + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_EstimatedEndTime(out EstimatedEndTime: PWideChar): HResult; stdcall; + /// + /// The absolute path to the download file, including file name. Host can change + /// this from `ICoreWebView2DownloadStartingEventArgs`. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_ResultFilePath(out ResultFilePath: PWideChar): HResult; stdcall; + /// + /// The state of the download. A download can be in progress, interrupted, or + /// completed. See `COREWEBVIEW2_DOWNLOAD_STATE` for descriptions of states. + /// + function Get_State(out downloadState: COREWEBVIEW2_DOWNLOAD_STATE): HResult; stdcall; + /// + /// The reason why connection with file host was broken. + /// + function Get_InterruptReason(out InterruptReason: COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON): HResult; stdcall; + /// + /// Cancels the download. If canceled, the default download dialog shows + /// that the download was canceled. Host should set the `Cancel` property from + /// `ICoreWebView2SDownloadStartingEventArgs` if the download should be + /// canceled without displaying the default download dialog. + /// + function Cancel: HResult; stdcall; + /// + /// Pauses the download. If paused, the default download dialog shows that the + /// download is paused. No effect if download is already paused. Pausing a + /// download changes the state to `COREWEBVIEW2_DOWNLOAD_STATE_INTERRUPTED` + /// with `InterruptReason` set to `COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_USER_PAUSED`. + /// + function Pause: HResult; stdcall; + /// + /// Resumes a paused download. May also resume a download that was interrupted + /// for another reason, if `CanResume` returns true. Resuming a download changes + /// the state from `COREWEBVIEW2_DOWNLOAD_STATE_INTERRUPTED` to + /// `COREWEBVIEW2_DOWNLOAD_STATE_IN_PROGRESS`. + /// + function Resume: HResult; stdcall; + /// + /// Returns true if an interrupted download can be resumed. Downloads with + /// the following interrupt reasons may automatically resume without you + /// calling any methods: + /// `COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE`, + /// `COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH`, + /// `COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT`. + /// In these cases download progress may be restarted with `BytesReceived` + /// reset to 0. + /// + function Get_CanResume(out CanResume: Integer): HResult; stdcall; + end; + + /// + /// Receives `BytesReceivedChanged` events. + /// + /// + /// See the ICoreWebView2BytesReceivedChangedEventHandler article. + /// + ICoreWebView2BytesReceivedChangedEventHandler = interface(IUnknown) + ['{828E8AB6-D94C-4264-9CEF-5217170D6251}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2DownloadOperation; const args: IUnknown): HResult; stdcall; + end; + + /// + /// Receives `EstimatedEndTimeChanged` events. + /// + /// + /// See the ICoreWebView2EstimatedEndTimeChangedEventHandler article. + /// + ICoreWebView2EstimatedEndTimeChangedEventHandler = interface(IUnknown) + ['{28F0D425-93FE-4E63-9F8D-2AEEC6D3BA1E}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2DownloadOperation; const args: IUnknown): HResult; stdcall; + end; + + /// + /// Receives `StateChanged` events. + /// + /// + /// See the ICoreWebView2StateChangedEventHandler article. + /// + ICoreWebView2StateChangedEventHandler = interface(IUnknown) + ['{81336594-7EDE-4BA9-BF71-ACF0A95B58DD}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2DownloadOperation; const args: IUnknown): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2_4 interface to support ClientCertificateRequested + /// event. + /// + /// + /// See the ICoreWebView2_5 article. + /// + ICoreWebView2_5 = interface(ICoreWebView2_4) + ['{BEDB11B8-D63C-11EB-B8BC-0242AC130003}'] + /// + /// Adds an event handler for the ClientCertificateRequested event. + /// The ClientCertificateRequested event is raised when the WebView2 + /// is making a request to an HTTP server that needs a client certificate + /// for HTTP authentication. + /// Read more about HTTP client certificates at + /// [RFC 8446 The Transport Layer Security (TLS) Protocol Version 1.3](https://tools.ietf.org/html/rfc8446). + /// + /// With this event you have several options for responding to client certificate requests: + /// + /// Scenario | Handled | Cancel | SelectedCertificate + /// ---------------------------------------------------------- | ------- | ------ | ------------------- + /// Respond to server with a certificate | True | False | MutuallyTrustedCertificate value + /// Respond to server without certificate | True | False | null + /// Display default client certificate selection dialog prompt | False | False | n/a + /// Cancel the request | n/a | True | n/a + /// + /// If you don't handle the event, WebView2 will + /// show the default client certificate selection dialog prompt to user. + /// + /// \snippet SettingsComponent.cpp ClientCertificateRequested1 + /// \snippet ScenarioClientCertificateRequested.cpp ClientCertificateRequested2 + /// + function add_ClientCertificateRequested(const eventHandler: ICoreWebView2ClientCertificateRequestedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with add_ClientCertificateRequested. + /// + function remove_ClientCertificateRequested(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives `ClientCertificateRequested` events. + /// + /// + /// See the ICoreWebView2ClientCertificateRequestedEventHandler article. + /// + ICoreWebView2ClientCertificateRequestedEventHandler = interface(IUnknown) + ['{D7175BA2-BCC3-11EB-8529-0242AC130003}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2ClientCertificateRequestedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the ClientCertificateRequested event. + /// + /// + /// See the ICoreWebView2ClientCertificateRequestedEventArgs article. + /// + ICoreWebView2ClientCertificateRequestedEventArgs = interface(IUnknown) + ['{BC59DB28-BCC3-11EB-8529-0242AC130003}'] + /// + /// Host name of the server that requested client certificate authentication. + /// Normalization rules applied to the hostname are: + /// * Convert to lowercase characters for ascii characters. + /// * Punycode is used for representing non ascii characters. + /// * Strip square brackets for IPV6 address. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Host(out value: PWideChar): HResult; stdcall; + /// + /// Port of the server that requested client certificate authentication. + /// + function Get_Port(out value: SYSINT): HResult; stdcall; + /// + /// Returns true if the server that issued this request is an http proxy. + /// Returns false if the server is the origin server. + /// + function Get_IsProxy(out value: Integer): HResult; stdcall; + /// + /// Returns the `ICoreWebView2StringCollection`. + /// The collection contains Base64 encoding of DER encoded distinguished names of + /// certificate authorities allowed by the server. + /// + function Get_AllowedCertificateAuthorities(out value: ICoreWebView2StringCollection): HResult; stdcall; + /// + /// Returns the `ICoreWebView2ClientCertificateCollection` when client + /// certificate authentication is requested. The collection contains mutually + /// trusted CA certificates. + /// + function Get_MutuallyTrustedCertificates(out value: ICoreWebView2ClientCertificateCollection): HResult; stdcall; + /// + /// Returns the selected certificate. + /// + function Get_SelectedCertificate(out value: ICoreWebView2ClientCertificate): HResult; stdcall; + /// + /// Sets the certificate to respond to the server. + /// + function Set_SelectedCertificate(const value: ICoreWebView2ClientCertificate): HResult; stdcall; + /// + /// You may set this flag to cancel the certificate selection. If canceled, + /// the request is aborted regardless of the `Handled` property. By default the + /// value is `FALSE`. + /// + function Get_Cancel(out value: Integer): HResult; stdcall; + /// + /// Sets the `Cancel` property. + /// + function Set_Cancel(value: Integer): HResult; stdcall; + /// + /// You may set this flag to `TRUE` to respond to the server with or + /// without a certificate. If this flag is `TRUE` with a `SelectedCertificate` + /// it responds to the server with the selected certificate otherwise respond to the + /// server without a certificate. By default the value of `Handled` and `Cancel` are `FALSE` + /// and display default client certificate selection dialog prompt to allow the user to + /// choose a certificate. The `SelectedCertificate` is ignored unless `Handled` is set `TRUE`. + /// + function Get_Handled(out value: Integer): HResult; stdcall; + /// + /// Sets the `Handled` property. + /// + function Set_Handled(value: Integer): HResult; stdcall; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this operation to + /// complete the event at a later time. + /// + function GetDeferral(out deferral: ICoreWebView2Deferral): HResult; stdcall; + end; + + /// + /// A collection of strings. + /// + /// + /// See the ICoreWebView2StringCollection article. + /// + ICoreWebView2StringCollection = interface(IUnknown) + ['{F41F3F8A-BCC3-11EB-8529-0242AC130003}'] + /// + /// The number of elements contained in the collection. + /// + function Get_Count(out value: SYSUINT): HResult; stdcall; + /// + /// Gets the element at the given index. + /// + function GetValueAtIndex(index: SYSUINT; out value: PWideChar): HResult; stdcall; + end; + + /// + /// A collection of ICoreWebView2ClientCertificate. + /// + /// + /// See the ICoreWebView2ClientCertificateCollection article. + /// + ICoreWebView2ClientCertificateCollection = interface(IUnknown) + ['{EF5674D2-BCC3-11EB-8529-0242AC130003}'] + /// + /// The number of elements contained in the collection. + /// + function Get_Count(out value: SYSUINT): HResult; stdcall; + /// + /// Gets the element at the given index. + /// + function GetValueAtIndex(index: SYSUINT; out value: ICoreWebView2ClientCertificate): HResult; stdcall; + end; + + /// + /// Provides access to the client certificate metadata. + /// + /// + /// See the ICoreWebView2ClientCertificate article. + /// + ICoreWebView2ClientCertificate = interface(IUnknown) + ['{E7188076-BCC3-11EB-8529-0242AC130003}'] + /// + /// Subject of the certificate. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Subject(out value: PWideChar): HResult; stdcall; + /// + /// Name of the certificate authority that issued the certificate. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Issuer(out value: PWideChar): HResult; stdcall; + /// + /// The valid start date and time for the certificate as the number of seconds since + /// the UNIX epoch. + /// + function Get_ValidFrom(out value: Double): HResult; stdcall; + /// + /// The valid expiration date and time for the certificate as the number of seconds since + /// the UNIX epoch. + /// + function Get_ValidTo(out value: Double): HResult; stdcall; + /// + /// Base64 encoding of DER encoded serial number of the certificate. + /// Read more about DER at [RFC 7468 DER] + /// (https://tools.ietf.org/html/rfc7468#appendix-B). + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_DerEncodedSerialNumber(out value: PWideChar): HResult; stdcall; + /// + /// Display name for a certificate. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_DisplayName(out value: PWideChar): HResult; stdcall; + /// + /// PEM encoded data for the certificate. + /// Returns Base64 encoding of DER encoded certificate. + /// Read more about PEM at [RFC 1421 Privacy Enhanced Mail] + /// (https://tools.ietf.org/html/rfc1421). + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function ToPemEncoding(out pemEncodedData: PWideChar): HResult; stdcall; + /// + /// Collection of PEM encoded client certificate issuer chain. + /// In this collection first element is the current certificate followed by + /// intermediate1, intermediate2...intermediateN-1. Root certificate is the + /// last element in collection. + /// + function Get_PemEncodedIssuerCertificateChain(out value: ICoreWebView2StringCollection): HResult; stdcall; + /// + /// Kind of a certificate (eg., smart card, pin, other). + /// + function Get_Kind(out value: COREWEBVIEW2_CLIENT_CERTIFICATE_KIND): HResult; stdcall; + end; + + /// + /// This interface is an extension of `ICoreWebView2_5` that manages opening + /// the browser task manager window. + /// + /// + /// See the ICoreWebView2_6 article. + /// + ICoreWebView2_6 = interface(ICoreWebView2_5) + ['{499AADAC-D92C-4589-8A75-111BFC167795}'] + /// + /// Opens the Browser Task Manager view as a new window in the foreground. + /// If the Browser Task Manager is already open, this will bring it into + /// the foreground. WebView2 currently blocks the Shift+Esc shortcut for + /// opening the task manager. An end user can open the browser task manager + /// manually via the `Browser task manager` entry of the DevTools window's + /// title bar's context menu. + /// + function OpenTaskManagerWindow: HResult; stdcall; + end; + + /// + /// This interface is an extension of ICoreWebView2_5 that manages opening + /// the browser task manager window. + /// + /// + /// See the ICoreWebView2_7 article. + /// + ICoreWebView2_7 = interface(ICoreWebView2_6) + ['{79C24D83-09A3-45AE-9418-487F32A58740}'] + /// + /// Print the current page to PDF asynchronously with the provided settings. + /// See `ICoreWebView2PrintSettings` for description of settings. Passing + /// nullptr for `printSettings` results in default print settings used. + /// + /// Use `resultFilePath` to specify the path to the PDF file. The host should + /// provide an absolute path, including file name. If the path + /// points to an existing file, the file will be overwritten. If the path is + /// not valid, the method fails with `E_INVALIDARG`. + /// + /// The async `PrintToPdf` operation completes when the data has been written + /// to the PDF file. At this time the + /// `ICoreWebView2PrintToPdfCompletedHandler` is invoked. If the + /// application exits before printing is complete, the file is not saved. + /// Only one `Printing` operation can be in progress at a time. If + /// `PrintToPdf` is called while a `PrintToPdf` or `PrintToPdfStream` or `Print` or + /// `ShowPrintUI` job is in progress, the completed handler is immediately invoked + /// with `isSuccessful` set to FALSE. + /// + /// \snippet FileComponent.cpp PrintToPdf + /// + function PrintToPdf(ResultFilePath: PWideChar; const printSettings: ICoreWebView2PrintSettings; + const handler: ICoreWebView2PrintToPdfCompletedHandler): HResult; stdcall; + end; + + /// + /// Settings used by the PrintToPdf method. + /// + /// + /// See the ICoreWebView2PrintSettings article. + /// + ICoreWebView2PrintSettings = interface(IUnknown) + ['{377F3721-C74E-48CA-8DB1-DF68E51D60E2}'] + /// + /// The orientation can be portrait or landscape. The default orientation is + /// portrait. See `COREWEBVIEW2_PRINT_ORIENTATION`. + /// + function Get_Orientation(out Orientation: COREWEBVIEW2_PRINT_ORIENTATION): HResult; stdcall; + /// + /// Sets the `Orientation` property. + /// + function Set_Orientation(Orientation: COREWEBVIEW2_PRINT_ORIENTATION): HResult; stdcall; + /// + /// The scale factor is a value between 0.1 and 2.0. The default is 1.0. + /// + function Get_ScaleFactor(out ScaleFactor: Double): HResult; stdcall; + /// + /// Sets the `ScaleFactor` property. Returns `E_INVALIDARG` if an invalid + /// value is provided, and the current value is not changed. + /// + function Set_ScaleFactor(ScaleFactor: Double): HResult; stdcall; + /// + /// The page width in inches. The default width is 8.5 inches. + /// + function Get_PageWidth(out PageWidth: Double): HResult; stdcall; + /// + /// Sets the `PageWidth` property. Returns `E_INVALIDARG` if the page width is + /// less than or equal to zero, and the current value is not changed. + /// + function Set_PageWidth(PageWidth: Double): HResult; stdcall; + /// + /// The page height in inches. The default height is 11 inches. + /// + function Get_PageHeight(out PageHeight: Double): HResult; stdcall; + /// + /// Sets the `PageHeight` property. Returns `E_INVALIDARG` if the page height + /// is less than or equal to zero, and the current value is not changed. + /// + function Set_PageHeight(PageHeight: Double): HResult; stdcall; + /// + /// The top margin in inches. The default is 1 cm, or ~0.4 inches. + /// + function Get_MarginTop(out MarginTop: Double): HResult; stdcall; + /// + /// Sets the `MarginTop` property. A margin cannot be less than zero. + /// Returns `E_INVALIDARG` if an invalid value is provided, and the current + /// value is not changed. + /// + function Set_MarginTop(MarginTop: Double): HResult; stdcall; + /// + /// The bottom margin in inches. The default is 1 cm, or ~0.4 inches. + /// + function Get_MarginBottom(out MarginBottom: Double): HResult; stdcall; + /// + /// Sets the `MarginBottom` property. A margin cannot be less than zero. + /// Returns `E_INVALIDARG` if an invalid value is provided, and the current + /// value is not changed. + /// + function Set_MarginBottom(MarginBottom: Double): HResult; stdcall; + /// + /// The left margin in inches. The default is 1 cm, or ~0.4 inches. + /// + function Get_MarginLeft(out MarginLeft: Double): HResult; stdcall; + /// + /// Sets the `MarginLeft` property. A margin cannot be less than zero. + /// Returns `E_INVALIDARG` if an invalid value is provided, and the current + /// value is not changed. + /// + function Set_MarginLeft(MarginLeft: Double): HResult; stdcall; + /// + /// The right margin in inches. The default is 1 cm, or ~0.4 inches. + /// + function Get_MarginRight(out MarginRight: Double): HResult; stdcall; + /// + /// Set the `MarginRight` property.A margin cannot be less than zero. + /// Returns `E_INVALIDARG` if an invalid value is provided, and the current + /// value is not changed. + /// + function Set_MarginRight(MarginRight: Double): HResult; stdcall; + /// + /// `TRUE` if background colors and images should be printed. The default value + /// is `FALSE`. + /// + function Get_ShouldPrintBackgrounds(out ShouldPrintBackgrounds: Integer): HResult; stdcall; + /// + /// Set the `ShouldPrintBackgrounds` property. + /// + function Set_ShouldPrintBackgrounds(ShouldPrintBackgrounds: Integer): HResult; stdcall; + /// + /// `TRUE` if only the current end user's selection of HTML in the document + /// should be printed. The default value is `FALSE`. + /// + function Get_ShouldPrintSelectionOnly(out ShouldPrintSelectionOnly: Integer): HResult; stdcall; + /// + /// Set the `ShouldPrintSelectionOnly` property. + /// + function Set_ShouldPrintSelectionOnly(ShouldPrintSelectionOnly: Integer): HResult; stdcall; + /// + /// `TRUE` if header and footer should be printed. The default value is `FALSE`. + /// The header consists of the date and time of printing, and the title of the + /// page. The footer consists of the URI and page number. The height of the + /// header and footer is 0.5 cm, or ~0.2 inches. + /// + function Get_ShouldPrintHeaderAndFooter(out ShouldPrintHeaderAndFooter: Integer): HResult; stdcall; + /// + /// Set the `ShouldPrintHeaderAndFooter` property. + /// + function Set_ShouldPrintHeaderAndFooter(ShouldPrintHeaderAndFooter: Integer): HResult; stdcall; + /// + /// The title in the header if `ShouldPrintHeaderAndFooter` is `TRUE`. The + /// default value is the title of the current document. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_HeaderTitle(out HeaderTitle: PWideChar): HResult; stdcall; + /// + /// Set the `HeaderTitle` property. If an empty string or null value is + /// provided, no title is shown in the header. + /// + function Set_HeaderTitle(HeaderTitle: PWideChar): HResult; stdcall; + /// + /// The URI in the footer if `ShouldPrintHeaderAndFooter` is `TRUE`. The + /// default value is the current URI. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_FooterUri(out FooterUri: PWideChar): HResult; stdcall; + /// + /// Set the `FooterUri` property. If an empty string or null value is + /// provided, no URI is shown in the footer. + /// + function Set_FooterUri(FooterUri: PWideChar): HResult; stdcall; + end; + + /// + /// Receives the result of the `PrintToPdf` method. + /// + /// + /// See the ICoreWebView2PrintToPdfCompletedHandler article. + /// + ICoreWebView2PrintToPdfCompletedHandler = interface(IUnknown) + ['{CCF1EF04-FD8E-4D5F-B2DE-0983E41B8C36}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; result_: Integer): HResult; stdcall; + end; + + /// + /// This interface is an extension of ICoreWebView2_7 that supports media features. + /// + /// + /// See the ICoreWebView2_8 article. + /// + ICoreWebView2_8 = interface(ICoreWebView2_7) + ['{E9632730-6E1E-43AB-B7B8-7B2C9E62E094}'] + /// + /// Adds an event handler for the `IsMutedChanged` event. + /// `IsMutedChanged` is raised when the IsMuted property changes value. + /// + /// \snippet AudioComponent.cpp IsMutedChanged + /// + function add_IsMutedChanged(const eventHandler: ICoreWebView2IsMutedChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_IsMutedChanged`. + /// + function remove_IsMutedChanged(token: EventRegistrationToken): HResult; stdcall; + /// + /// Indicates whether all audio output from this CoreWebView2 is muted or not. + /// + /// \snippet AudioComponent.cpp ToggleIsMuted + /// + function Get_IsMuted(out value: Integer): HResult; stdcall; + /// + /// Sets the `IsMuted` property. + /// + /// \snippet AudioComponent.cpp ToggleIsMuted + /// + function Set_IsMuted(value: Integer): HResult; stdcall; + /// + /// Adds an event handler for the `IsDocumentPlayingAudioChanged` event. + /// `IsDocumentPlayingAudioChanged` is raised when the IsDocumentPlayingAudio property changes value. + /// + /// \snippet AudioComponent.cpp IsDocumentPlayingAudioChanged + /// + function add_IsDocumentPlayingAudioChanged(const eventHandler: ICoreWebView2IsDocumentPlayingAudioChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_IsDocumentPlayingAudioChanged`. + /// + function remove_IsDocumentPlayingAudioChanged(token: EventRegistrationToken): HResult; stdcall; + /// + /// Indicates whether any audio output from this CoreWebView2 is playing. + /// This property will be true if audio is playing even if IsMuted is true. + /// + /// \snippet AudioComponent.cpp IsDocumentPlayingAudio + /// + function Get_IsDocumentPlayingAudio(out value: Integer): HResult; stdcall; + end; + + /// + /// Receives `IsMutedChanged` events. + /// + /// + /// See the ICoreWebView2IsMutedChangedEventHandler article. + /// + ICoreWebView2IsMutedChangedEventHandler = interface(IUnknown) + ['{57D90347-CD0E-4952-A4A2-7483A2756F08}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; + end; + + /// + /// Receives `IsDocumentPlayingAudioChanged` events. + /// + /// + /// See the ICoreWebView2IsDocumentPlayingAudioChangedEventHandler article. + /// + ICoreWebView2IsDocumentPlayingAudioChangedEventHandler = interface(IUnknown) + ['{5DEF109A-2F4B-49FA-B7F6-11C39E513328}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; + end; + + /// + /// This interface is an extension of ICoreWebView2_8 that default download + /// dialog positioning and anchoring. + /// + /// + /// See the ICoreWebView2_9 article. + /// + ICoreWebView2_9 = interface(ICoreWebView2_8) + ['{4D7B2EAB-9FDC-468D-B998-A9260B5ED651}'] + /// + /// Raised when the `IsDefaultDownloadDialogOpen` property changes. This event + /// comes after the `DownloadStarting` event. Setting the `Handled` property + /// on the `DownloadStartingEventArgs` disables the default download dialog + /// and ensures that this event is never raised. + /// + function add_IsDefaultDownloadDialogOpenChanged(const handler: ICoreWebView2IsDefaultDownloadDialogOpenChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with + /// `add_IsDefaultDownloadDialogOpenChanged`. + /// + function remove_IsDefaultDownloadDialogOpenChanged(token: EventRegistrationToken): HResult; stdcall; + /// + /// `TRUE` if the default download dialog is currently open. The value of this + /// property changes only when the default download dialog is explicitly + /// opened or closed. Hiding the WebView implicitly hides the dialog, but does + /// not change the value of this property. + /// + function Get_IsDefaultDownloadDialogOpen(out value: Integer): HResult; stdcall; + /// + /// Open the default download dialog. If the dialog is opened before there + /// are recent downloads, the dialog shows all past downloads for the + /// current profile. Otherwise, the dialog shows only the recent downloads + /// with a "See more" button for past downloads. Calling this method raises + /// the `IsDefaultDownloadDialogOpenChanged` event if the dialog was closed. + /// No effect if the dialog is already open. + /// + /// \snippet ViewComponent.cpp ToggleDefaultDownloadDialog + /// + function OpenDefaultDownloadDialog: HResult; stdcall; + /// + /// Close the default download dialog. Calling this method raises the + /// `IsDefaultDownloadDialogOpenChanged` event if the dialog was open. No + /// effect if the dialog is already closed. + /// + function CloseDefaultDownloadDialog: HResult; stdcall; + /// + /// Get the default download dialog corner alignment. + /// + function Get_DefaultDownloadDialogCornerAlignment(out value: COREWEBVIEW2_DEFAULT_DOWNLOAD_DIALOG_CORNER_ALIGNMENT): HResult; stdcall; + /// + /// Set the default download dialog corner alignment. The dialog can be + /// aligned to any of the WebView corners (see + /// COREWEBVIEW2_DEFAULT_DOWNLOAD_DIALOG_CORNER_ALIGNMENT). When the WebView + /// or dialog changes size, the dialog keeps its position relative to the + /// corner. The dialog may become partially or completely outside of the + /// WebView bounds if the WebView is small enough. Set the margin relative to + /// the corner with the `DefaultDownloadDialogMargin` property. The corner + /// alignment and margin should be set during initialization to ensure that + /// they are correctly applied when the layout is first computed, otherwise + /// they will not take effect until the next time the WebView position or size + /// is updated. + /// + /// \snippet ViewComponent.cpp SetDefaultDownloadDialogPosition + /// + function Set_DefaultDownloadDialogCornerAlignment(value: COREWEBVIEW2_DEFAULT_DOWNLOAD_DIALOG_CORNER_ALIGNMENT): HResult; stdcall; + /// + /// Get the default download dialog margin. + /// + function Get_DefaultDownloadDialogMargin(out value: tagPOINT): HResult; stdcall; + /// + /// Set the default download dialog margin relative to the WebView corner + /// specified by `DefaultDownloadDialogCornerAlignment`. The margin is a + /// point that describes the vertical and horizontal distances between the + /// chosen WebView corner and the default download dialog corner nearest to + /// it. Positive values move the dialog towards the center of the WebView from + /// the chosen WebView corner, and negative values move the dialog away from + /// it. Use (0, 0) to align the dialog to the WebView corner with no margin. + /// The corner alignment and margin should be set during initialization to + /// ensure that they are correctly applied when the layout is first computed, + /// otherwise they will not take effect until the next time the WebView + /// position or size is updated. + /// + function Set_DefaultDownloadDialogMargin(value: tagPOINT): HResult; stdcall; + end; + + /// + /// Receives `IsDefaultDownloadDialogOpenChanged` events. + /// + /// + /// See the ICoreWebView2IsDefaultDownloadDialogOpenChangedEventHandler article. + /// + ICoreWebView2IsDefaultDownloadDialogOpenChangedEventHandler = interface(IUnknown) + ['{3117DA26-AE13-438D-BD46-EDBEB2C4CE81}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; + end; + + /// + /// This interface is an extension of ICoreWebView2_9 that supports + /// BasicAuthenticationRequested event. + /// + /// + /// See the ICoreWebView2_10 article. + /// + ICoreWebView2_10 = interface(ICoreWebView2_9) + ['{B1690564-6F5A-4983-8E48-31D1143FECDB}'] + /// + /// Adds an event handler for the BasicAuthenticationRequested event. + /// BasicAuthenticationRequested event is raised when WebView encounters a + /// Basic HTTP Authentication request as described in + /// https://developer.mozilla.org/docs/Web/HTTP/Authentication, a Digest + /// HTTP Authentication request as described in + /// https://developer.mozilla.org/docs/Web/HTTP/Headers/Authorization#digest, + /// an NTLM authentication or a Proxy Authentication request. + /// + /// The host can provide a response with credentials for the authentication or + /// cancel the request. If the host sets the Cancel property to false but does not + /// provide either UserName or Password properties on the Response property, then + /// WebView2 will show the default authentication challenge dialog prompt to + /// the user. + /// + /// \snippet ScenarioAuthentication.cpp BasicAuthenticationRequested + /// + function add_BasicAuthenticationRequested(const eventHandler: ICoreWebView2BasicAuthenticationRequestedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with add_BasicAuthenticationRequested. + /// + function remove_BasicAuthenticationRequested(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives `BasicAuthenticationRequested` events. + /// + /// + /// See the ICoreWebView2BasicAuthenticationRequestedEventHandler article. + /// + ICoreWebView2BasicAuthenticationRequestedEventHandler = interface(IUnknown) + ['{58B4D6C2-18D4-497E-B39B-9A96533FA278}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2BasicAuthenticationRequestedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the BasicAuthenticationRequested event. Will contain the + /// request that led to the HTTP authorization challenge, the challenge + /// and allows the host to provide authentication response or cancel the request. + /// + /// + /// See the ICoreWebView2BasicAuthenticationRequestedEventArgs article. + /// + ICoreWebView2BasicAuthenticationRequestedEventArgs = interface(IUnknown) + ['{EF05516F-D897-4F9E-B672-D8E2307A3FB0}'] + /// + /// The URI that led to the authentication challenge. For proxy authentication + /// requests, this will be the URI of the proxy server. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_uri(out value: PWideChar): HResult; stdcall; + /// + /// The authentication challenge string + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Challenge(out Challenge: PWideChar): HResult; stdcall; + /// + /// Response to the authentication request with credentials. This object will be populated by the app + /// if the host would like to provide authentication credentials. + /// + function Get_Response(out Response: ICoreWebView2BasicAuthenticationResponse): HResult; stdcall; + /// + /// Cancel the authentication request. False by default. + /// If set to true, Response will be ignored. + /// + function Get_Cancel(out Cancel: Integer): HResult; stdcall; + /// + /// Set the Cancel property. + /// + function Set_Cancel(Cancel: Integer): HResult; stdcall; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this deferral to + /// defer the decision to show the Basic Authentication dialog. + /// + function GetDeferral(out deferral: ICoreWebView2Deferral): HResult; stdcall; + end; + + /// + /// Represents a Basic HTTP authentication response that contains a user name + /// and a password as according to RFC7617 (https://tools.ietf.org/html/rfc7617) + /// + /// + /// See the ICoreWebView2BasicAuthenticationResponse article. + /// + ICoreWebView2BasicAuthenticationResponse = interface(IUnknown) + ['{07023F7D-2D77-4D67-9040-6E7D428C6A40}'] + /// + /// User name provided for authentication. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_UserName(out UserName: PWideChar): HResult; stdcall; + /// + /// Set user name property + /// + function Set_UserName(UserName: PWideChar): HResult; stdcall; + /// + /// Password provided for authentication. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Password(out Password: PWideChar): HResult; stdcall; + /// + /// Set password property + /// + function Set_Password(Password: PWideChar): HResult; stdcall; + end; + + /// + /// This interface is an extension of ICoreWebView2_10 that supports sessionId + /// for CDP method calls and ContextMenuRequested event. + /// + /// + /// See the ICoreWebView2_11 article. + /// + ICoreWebView2_11 = interface(ICoreWebView2_10) + ['{0BE78E56-C193-4051-B943-23B460C08BDB}'] + /// + /// Runs an asynchronous `DevToolsProtocol` method for a specific session of + /// an attached target. + /// There could be multiple `DevToolsProtocol` targets in a WebView. + /// Besides the top level page, iframes from different origin and web workers + /// are also separate targets. Attaching to these targets allows interaction with them. + /// When the DevToolsProtocol is attached to a target, the connection is identified + /// by a sessionId. + /// To use this API, you must set the `flatten` parameter to true when calling + /// `Target.attachToTarget` or `Target.setAutoAttach` `DevToolsProtocol` method. + /// Using `Target.setAutoAttach` is recommended as that would allow you to attach + /// to dedicated worker targets, which are not discoverable via other APIs like + /// `Target.getTargets`. + /// For more information about targets and sessions, navigate to + /// [DevTools Protocol Viewer](https://chromedevtools.github.io/devtools-protocol/tot/Target). + /// For more information about available methods, navigate to + /// [DevTools Protocol Viewer](https://chromedevtools.github.io/devtools-protocol/tot) + /// The `sessionId` parameter is the sessionId for an attached target. + /// nullptr or empty string is treated as the session for the default target for the top page. + /// The `methodName` parameter is the full name of the method in the + /// `{domain}.{method}` format. The `parametersAsJson` parameter is a JSON + /// formatted string containing the parameters for the corresponding method. + /// The `Invoke` method of the `handler` is run when the method + /// asynchronously completes. `Invoke` is run with the return object of the + /// method as a JSON string. This function returns E_INVALIDARG if the `methodName` is + /// unknown or the `parametersAsJson` has an error. In the case of such an error, the + /// `returnObjectAsJson` parameter of the handler will include information + /// about the error. + /// + /// \snippet ScriptComponent.cpp DevToolsProtocolMethodMultiSession + /// + /// \snippet ScriptComponent.cpp CallDevToolsProtocolMethodForSession + /// + function CallDevToolsProtocolMethodForSession(sessionId: PWideChar; methodName: PWideChar; + parametersAsJson: PWideChar; + const handler: ICoreWebView2CallDevToolsProtocolMethodCompletedHandler): HResult; stdcall; + /// + /// Add an event handler for the `ContextMenuRequested` event. + /// `ContextMenuRequested` event is raised when a context menu is requested by the user + /// and the content inside WebView hasn't disabled context menus. + /// The host has the option to create their own context menu with the information provided in + /// the event or can add items to or remove items from WebView context menu. + /// If the host doesn't handle the event, WebView will display the default context menu. + /// + /// \snippet SettingsComponent.cpp EnableCustomMenu + /// + function add_ContextMenuRequested(const eventHandler: ICoreWebView2ContextMenuRequestedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_ContextMenuRequested`. + /// + function remove_ContextMenuRequested(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives ContextMenuRequested events. + /// + /// + /// See the ICoreWebView2ContextMenuRequestedEventHandler article. + /// + ICoreWebView2ContextMenuRequestedEventHandler = interface(IUnknown) + ['{04D3FE1D-AB87-42FB-A898-DA241D35B63C}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2ContextMenuRequestedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the ContextMenuRequested event. Will contain the selection information + /// and a collection of all of the default context menu items that the WebView + /// would show. Allows the app to draw its own context menu or add/remove + /// from the default context menu. + /// + /// + /// See the ICoreWebView2ContextMenuRequestedEventArgs article. + /// + ICoreWebView2ContextMenuRequestedEventArgs = interface(IUnknown) + ['{A1D309EE-C03F-11EB-8529-0242AC130003}'] + /// + /// Gets the collection of `ContextMenuItem` objects. + /// See `ICoreWebView2ContextMenuItemCollection` for more details. + /// + function Get_MenuItems(out value: ICoreWebView2ContextMenuItemCollection): HResult; stdcall; + /// + /// Gets the target information associated with the requested context menu. + /// See `ICoreWebView2ContextMenuTarget` for more details. + /// + function Get_ContextMenuTarget(out value: ICoreWebView2ContextMenuTarget): HResult; stdcall; + /// + /// Gets the coordinates where the context menu request occurred in relation to the upper + /// left corner of the WebView bounds. + /// + function Get_Location(out value: tagPOINT): HResult; stdcall; + /// + /// Sets the selected context menu item's command ID. When this is set, + /// WebView will execute the selected command. This + /// value should always be obtained via the selected `ContextMenuItem`'s `CommandId` property. + /// The default value is -1 which means that no selection occurred. The app can + /// also report the selected command ID for a custom context menu item, which + /// will cause the `CustomItemSelected` event to be fired for the custom item, however + /// while command IDs for each custom context menu item is unique + /// during a ContextMenuRequested event, CoreWebView2 may reassign command ID + /// values of deleted custom ContextMenuItems to new objects and the command + /// ID assigned to the same custom item can be different between each app runtime. + /// + function Set_SelectedCommandId(value: SYSINT): HResult; stdcall; + /// + /// Gets the selected CommandId. + /// + function Get_SelectedCommandId(out value: SYSINT): HResult; stdcall; + /// + /// Sets whether the `ContextMenuRequested` event is handled by host after + /// the event handler completes or if there is a deferral then after the deferral is completed. + /// If `Handled` is set to TRUE then WebView will not display a context menu and will instead + /// use the `SelectedCommandId` property to indicate which, if any, context menu item command to invoke. + /// If after the event handler or deferral completes `Handled` is set to FALSE then WebView + /// will display a context menu based on the contents of the `MenuItems` property. + /// The default value is FALSE. + /// + function Set_Handled(value: Integer): HResult; stdcall; + /// + /// Gets whether the `ContextMenuRequested` event is handled by host. + /// + function Get_Handled(out value: Integer): HResult; stdcall; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this operation to + /// complete the event when the custom context menu is closed. + /// + function GetDeferral(out deferral: ICoreWebView2Deferral): HResult; stdcall; + end; + + /// + /// Represents a collection of ContextMenuItem objects. Used to get, remove and add + /// ContextMenuItem objects at the specified index. + /// + /// + /// See the ICoreWebView2ContextMenuItemCollection article. + /// + ICoreWebView2ContextMenuItemCollection = interface(IUnknown) + ['{F562A2F5-C415-45CF-B909-D4B7C1E276D3}'] + /// + /// Gets the number of `ContextMenuItem` objects contained in the `ContextMenuItemCollection`. + /// + function Get_Count(out value: SYSUINT): HResult; stdcall; + /// + /// Gets the `ContextMenuItem` at the specified index. + /// + function GetValueAtIndex(index: SYSUINT; out value: ICoreWebView2ContextMenuItem): HResult; stdcall; + /// + /// Removes the `ContextMenuItem` at the specified index. + /// + function RemoveValueAtIndex(index: SYSUINT): HResult; stdcall; + /// + /// Inserts the `ContextMenuItem` at the specified index. + /// + function InsertValueAtIndex(index: SYSUINT; const value: ICoreWebView2ContextMenuItem): HResult; stdcall; + end; + + /// + /// Represents a context menu item of a context menu displayed by WebView. + /// + /// + /// See the ICoreWebView2ContextMenuItem article. + /// + ICoreWebView2ContextMenuItem = interface(IUnknown) + ['{7AED49E3-A93F-497A-811C-749C6B6B6C65}'] + /// + /// Gets the unlocalized name for the `ContextMenuItem`. Use this to + /// distinguish between context menu item types. This will be the English + /// label of the menu item in lower camel case. For example, the "Save as" + /// menu item will be "saveAs". Extension menu items will be "extension", + /// custom menu items will be "custom" and spellcheck items will be + /// "spellCheck". + /// Some example context menu item names are: + /// - "saveAs" + /// - "copyImage" + /// - "openLinkInNewWindow" + /// - "cut" + /// - "copy" + /// - "paste" + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_name(out value: PWideChar): HResult; stdcall; + /// + /// Gets the localized label for the `ContextMenuItem`. Will contain an + /// ampersand for characters to be used as keyboard accelerator. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Label_(out value: PWideChar): HResult; stdcall; + /// + /// Gets the Command ID for the `ContextMenuItem`. Use this to report the + /// `SelectedCommandId` in `ContextMenuRequested` event. + /// + function Get_CommandId(out value: SYSINT): HResult; stdcall; + /// + /// Gets the localized keyboard shortcut for this ContextMenuItem. It will be + /// the empty string if there is no keyboard shortcut. This is text intended + /// to be displayed to the end user to show the keyboard shortcut. For example + /// this property is Ctrl+Shift+I for the "Inspect" `ContextMenuItem`. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_ShortcutKeyDescription(out value: PWideChar): HResult; stdcall; + /// + /// Gets the Icon for the `ContextMenuItem` in PNG, Bitmap or SVG formats in the form of an IStream. + /// Stream will be rewound to the start of the image data. + /// + function Get_Icon(out value: IStream): HResult; stdcall; + /// + /// Gets the `ContextMenuItem` kind. + /// + function Get_Kind(out value: COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND): HResult; stdcall; + /// + /// Sets the enabled property of the `ContextMenuItem`. Must only be used in the case of a + /// custom context menu item. The default value for this is `TRUE`. + /// + function Set_IsEnabled(value: Integer): HResult; stdcall; + /// + /// Gets the enabled property of the `ContextMenuItem`. + /// + function Get_IsEnabled(out value: Integer): HResult; stdcall; + /// + /// Sets the checked property of the `ContextMenuItem`. Must only be used for custom context + /// menu items that are of kind Check box or Radio. + /// + function Set_IsChecked(value: Integer): HResult; stdcall; + /// + /// Gets the checked property of the `ContextMenuItem`, used if the kind is Check box or Radio. + /// + function Get_IsChecked(out value: Integer): HResult; stdcall; + /// + /// Gets the list of children menu items through a `ContextMenuItemCollection` + /// if the kind is Submenu. If the kind is not submenu, will return null. + /// + function Get_Children(out value: ICoreWebView2ContextMenuItemCollection): HResult; stdcall; + /// + /// Add an event handler for the `CustomItemSelected` event. + /// `CustomItemSelected` event is raised when the user selects this `ContextMenuItem`. + /// Will only be raised for end developer created context menu items + /// + function add_CustomItemSelected(const eventHandler: ICoreWebView2CustomItemSelectedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_CustomItemSelected`. + /// + function remove_CustomItemSelected(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives `CustomItemSelected` events. + /// + /// + /// See the ICoreWebView2CustomItemSelectedEventHandler article. + /// + ICoreWebView2CustomItemSelectedEventHandler = interface(IUnknown) + ['{49E1D0BC-FE9E-4481-B7C2-32324AA21998}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2ContextMenuItem; const args: IUnknown): HResult; stdcall; + end; + + /// + /// Represents the information regarding the context menu target. + /// Includes the context selected and the appropriate data used for the actions of a context menu. + /// + /// + /// See the ICoreWebView2ContextMenuTarget article. + /// + ICoreWebView2ContextMenuTarget = interface(IUnknown) + ['{B8611D99-EED6-4F3F-902C-A198502AD472}'] + /// + /// Gets the kind of context that the user selected. + /// + function Get_Kind(out value: COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND): HResult; stdcall; + /// + /// Returns TRUE if the context menu is requested on an editable component. + /// + function Get_IsEditable(out value: Integer): HResult; stdcall; + /// + /// Returns TRUE if the context menu was requested on the main frame and + /// FALSE if invoked on another frame. + /// + function Get_IsRequestedForMainFrame(out value: Integer): HResult; stdcall; + /// + /// Gets the uri of the page. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_PageUri(out value: PWideChar): HResult; stdcall; + /// + /// Gets the uri of the frame. Will match the PageUri if `IsRequestedForMainFrame` is TRUE. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_FrameUri(out value: PWideChar): HResult; stdcall; + /// + /// Returns TRUE if the context menu is requested on HTML containing an anchor tag. + /// + function Get_HasLinkUri(out value: Integer): HResult; stdcall; + /// + /// Gets the uri of the link (if `HasLinkUri` is TRUE, null otherwise). + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_LinkUri(out value: PWideChar): HResult; stdcall; + /// + /// Returns TRUE if the context menu is requested on text element that contains an anchor tag. + /// + function Get_HasLinkText(out value: Integer): HResult; stdcall; + /// + /// Gets the text of the link (if `HasLinkText` is TRUE, null otherwise). + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_LinkText(out value: PWideChar): HResult; stdcall; + /// + /// Returns TRUE if the context menu is requested on HTML containing a source uri. + /// + function Get_HasSourceUri(out value: Integer): HResult; stdcall; + /// + /// Gets the active source uri of element (if `HasSourceUri` is TRUE, null otherwise). + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_SourceUri(out value: PWideChar): HResult; stdcall; + /// + /// Returns TRUE if the context menu is requested on a selection. + /// + function Get_HasSelection(out value: Integer): HResult; stdcall; + /// + /// Gets the selected text (if `HasSelection` is TRUE, null otherwise). + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_SelectionText(out value: PWideChar): HResult; stdcall; + end; + + /// + /// This interface is an extension of ICoreWebView2_11 that supports + /// StatusBarTextChanged event. + /// + /// + /// See the ICoreWebView2_12 article. + /// + ICoreWebView2_12 = interface(ICoreWebView2_11) + ['{35D69927-BCFA-4566-9349-6B3E0D154CAC}'] + /// + /// Add an event handler for the `StatusBarTextChanged` event. + /// `StatusBarTextChanged` fires when the WebView is showing a status message, + /// a URL, or an empty string (an indication to hide the status bar). + /// \snippet SettingsComponent.cpp StatusBarTextChanged + /// + function add_StatusBarTextChanged(const eventHandler: ICoreWebView2StatusBarTextChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_StatusBarTextChanged`. + /// + function remove_StatusBarTextChanged(token: EventRegistrationToken): HResult; stdcall; + /// + /// The status message text. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_StatusBarText(out value: PWideChar): HResult; stdcall; + end; + + /// + /// Receives StatusBarTextChanged events. + /// + /// + /// See the ICoreWebView2StatusBarTextChangedEventHandler article. + /// + ICoreWebView2StatusBarTextChangedEventHandler = interface(IUnknown) + ['{A5E3B0D0-10DF-4156-BFAD-3B43867ACAC6}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; + end; + + /// + /// This interface is an extension of ICoreWebView2_12 that supports Profile + /// API. + /// + /// + /// See the ICoreWebView2_13 article. + /// + ICoreWebView2_13 = interface(ICoreWebView2_12) + ['{F75F09A8-667E-4983-88D6-C8773F315E84}'] + /// + /// The associated `ICoreWebView2Profile` object. If this CoreWebView2 was created with a + /// CoreWebView2ControllerOptions, the CoreWebView2Profile will match those specified options. + /// Otherwise if this CoreWebView2 was created without a CoreWebView2ControllerOptions, then + /// this will be the default CoreWebView2Profile for the corresponding CoreWebView2Environment. + /// + /// \snippet AppWindow.cpp CoreWebView2Profile + /// + function Get_Profile(out value: ICoreWebView2Profile): HResult; stdcall; + end; + + /// + /// Provides a set of properties to configure a Profile object. + /// + /// + /// See the ICoreWebView2Profile article. + /// + ICoreWebView2Profile = interface(IUnknown) + ['{79110AD3-CD5D-4373-8BC3-C60658F17A5F}'] + /// + /// Name of the profile. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_ProfileName(out value: PWideChar): HResult; stdcall; + /// + /// InPrivate mode is enabled or not. + /// + function Get_IsInPrivateModeEnabled(out value: Integer): HResult; stdcall; + /// + /// Full path of the profile directory. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_ProfilePath(out value: PWideChar): HResult; stdcall; + /// + /// Gets the `DefaultDownloadFolderPath` property. The default value is the + /// system default download folder path for the user. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_DefaultDownloadFolderPath(out value: PWideChar): HResult; stdcall; + /// + /// Sets the `DefaultDownloadFolderPath` property. The default download folder + /// path is persisted in the user data folder across sessions. The value + /// should be an absolute path to a folder that the user and application can + /// write to. Returns `E_INVALIDARG` if the value is invalid, and the default + /// download folder path is not changed. Otherwise the path is changed + /// immediately. If the directory does not yet exist, it is created at the + /// time of the next download. If the host application does not have + /// permission to create the directory, then the user is prompted to provide a + /// new path through the Save As dialog. The user can override the default + /// download folder path for a given download by choosing a different path in + /// the Save As dialog. + /// + function Set_DefaultDownloadFolderPath(value: PWideChar): HResult; stdcall; + /// + /// The PreferredColorScheme property sets the overall color scheme of the + /// WebView2s associated with this profile. This sets the color scheme for + /// WebView2 UI like dialogs, prompts, and context menus by setting the + /// media feature `prefers-color-scheme` for websites to respond to. + /// + /// The default value for this is COREWEBVIEW2_PREFERRED_COLOR_AUTO, + /// which will follow whatever theme the OS is currently set to. + /// + /// \snippet ViewComponent.cpp SetPreferredColorScheme + /// Returns the value of the `PreferredColorScheme` property. + /// + function Get_PreferredColorScheme(out value: COREWEBVIEW2_PREFERRED_COLOR_SCHEME): HResult; stdcall; + /// + /// Sets the `PreferredColorScheme` property. + /// + function Set_PreferredColorScheme(value: COREWEBVIEW2_PREFERRED_COLOR_SCHEME): HResult; stdcall; + end; + + /// + /// This interface is an extension of ICoreWebView2_13 that adds + /// ServerCertificate support. + /// + /// + /// See the ICoreWebView2_14 article. + /// + ICoreWebView2_14 = interface(ICoreWebView2_13) + ['{6DAA4F10-4A90-4753-8898-77C5DF534165}'] + /// + /// Adds an event handler for the ServerCertificateErrorDetected event. + /// The ServerCertificateErrorDetected event is raised when the WebView2 + /// cannot verify server's digital certificate while loading a web page. + /// + /// This event will raise for all web resources and follows the `WebResourceRequested` event. + /// + /// If you don't handle the event, WebView2 will show the default TLS interstitial error page to the user + /// for navigations, and for non-navigations the web request is cancelled. + /// + /// Note that WebView2 before raising `ServerCertificateErrorDetected` raises a `NavigationCompleted` event + /// with `IsSuccess` as FALSE and any of the below WebErrorStatuses that indicate a certificate failure. + /// + /// - COREWEBVIEW2_WEB_ERROR_STATUS_CERTIFICATE_COMMON_NAME_IS_INCORRECT + /// - COREWEBVIEW2_WEB_ERROR_STATUS_CERTIFICATE_EXPIRED + /// - COREWEBVIEW2_WEB_ERROR_STATUS_CLIENT_CERTIFICATE_CONTAINS_ERRORS + /// - COREWEBVIEW2_WEB_ERROR_STATUS_CERTIFICATE_REVOKED + /// - COREWEBVIEW2_WEB_ERROR_STATUS_CERTIFICATE_IS_INVALID + /// + /// For more details see `ICoreWebView2NavigationCompletedEventArgs::get_IsSuccess` and handle + /// ServerCertificateErrorDetected event or show the default TLS interstitial error page to the user + /// according to the app needs. + /// + /// WebView2 caches the response when action is `COREWEBVIEW2_SERVER_CERTIFICATE_ERROR_ACTION_ALWAYS_ALLOW` + /// for the RequestUri's host and the server certificate in the session and the `ServerCertificateErrorDetected` + /// event won't be raised again. + /// + /// To raise the event again you must clear the cache using `ClearServerCertificateErrorActions`. + /// + /// \snippet SettingsComponent.cpp ServerCertificateErrorDetected1 + /// + function add_ServerCertificateErrorDetected(const eventHandler: ICoreWebView2ServerCertificateErrorDetectedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with add_ServerCertificateErrorDetected. + /// + function remove_ServerCertificateErrorDetected(token: EventRegistrationToken): HResult; stdcall; + /// + /// Clears all cached decisions to proceed with TLS certificate errors from the + /// ServerCertificateErrorDetected event for all WebView2's sharing the same session. + /// + function ClearServerCertificateErrorActions(const handler: ICoreWebView2ClearServerCertificateErrorActionsCompletedHandler): HResult; stdcall; + end; + + /// + /// Receives `ServerCertificateErrorDetected` events. + /// + /// + /// See the ICoreWebView2ServerCertificateErrorDetectedEventHandler article. + /// + ICoreWebView2ServerCertificateErrorDetectedEventHandler = interface(IUnknown) + ['{969B3A26-D85E-4795-8199-FEF57344DA22}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2ServerCertificateErrorDetectedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the ServerCertificateErrorDetected event. + /// + /// + /// See the ICoreWebView2ServerCertificateErrorDetectedEventArgs article. + /// + ICoreWebView2ServerCertificateErrorDetectedEventArgs = interface(IUnknown) + ['{012193ED-7C13-48FF-969D-A84C1F432A14}'] + /// + /// The TLS error code for the invalid certificate. + /// + function Get_ErrorStatus(out value: COREWEBVIEW2_WEB_ERROR_STATUS): HResult; stdcall; + /// + /// URI associated with the request for the invalid certificate. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_RequestUri(out value: PWideChar): HResult; stdcall; + /// + /// Returns the server certificate. + /// + function Get_ServerCertificate(out value: ICoreWebView2Certificate): HResult; stdcall; + /// + /// The action of the server certificate error detection. + /// The default value is `COREWEBVIEW2_SERVER_CERTIFICATE_ERROR_ACTION_DEFAULT`. + /// + function Get_Action(out value: COREWEBVIEW2_SERVER_CERTIFICATE_ERROR_ACTION): HResult; stdcall; + /// + /// Sets the `Action` property. + /// + function Set_Action(value: COREWEBVIEW2_SERVER_CERTIFICATE_ERROR_ACTION): HResult; stdcall; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this operation to + /// complete the event at a later time. + /// + function GetDeferral(out deferral: ICoreWebView2Deferral): HResult; stdcall; + end; + + /// + /// Provides access to the certificate metadata. + /// + /// + /// See the ICoreWebView2Certificate article. + /// + ICoreWebView2Certificate = interface(IUnknown) + ['{C5FB2FCE-1CAC-4AEE-9C79-5ED0362EAAE0}'] + /// + /// Subject of the certificate. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Subject(out value: PWideChar): HResult; stdcall; + /// + /// Name of the certificate authority that issued the certificate. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Issuer(out value: PWideChar): HResult; stdcall; + /// + /// The valid start date and time for the certificate as the number of seconds since + /// the UNIX epoch. + /// + function Get_ValidFrom(out value: Double): HResult; stdcall; + /// + /// The valid expiration date and time for the certificate as the number of seconds since + /// the UNIX epoch. + /// + function Get_ValidTo(out value: Double): HResult; stdcall; + /// + /// Base64 encoding of DER encoded serial number of the certificate. + /// Read more about DER at [RFC 7468 DER] + /// (https://tools.ietf.org/html/rfc7468#appendix-B). + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_DerEncodedSerialNumber(out value: PWideChar): HResult; stdcall; + /// + /// Display name for a certificate. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings) + /// + function Get_DisplayName(out value: PWideChar): HResult; stdcall; + /// + /// PEM encoded data for the certificate. + /// Returns Base64 encoding of DER encoded certificate. + /// Read more about PEM at [RFC 1421 Privacy Enhanced Mail] + /// (https://tools.ietf.org/html/rfc1421). + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings) + /// + function ToPemEncoding(out pemEncodedData: PWideChar): HResult; stdcall; + /// + /// Collection of PEM encoded certificate issuer chain. + /// In this collection first element is the current certificate followed by + /// intermediate1, intermediate2...intermediateN-1. Root certificate is the + /// last element in collection. + /// + function Get_PemEncodedIssuerCertificateChain(out value: ICoreWebView2StringCollection): HResult; stdcall; + end; + + /// + /// Receives the result of the ClearServerCertificateErrorActions method. + /// + /// + /// See the ICoreWebView2ClearServerCertificateErrorActionsCompletedHandler article. + /// + ICoreWebView2ClearServerCertificateErrorActionsCompletedHandler = interface(IUnknown) + ['{3B40AAC6-ACFE-4FFD-8211-F607B96E2D5B}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult): HResult; stdcall; + end; + + /// + /// This interface is an extension of ICoreWebView2_14 that supports status Favicons. + /// + /// + /// See the ICoreWebView2_15 article. + /// + ICoreWebView2_15 = interface(ICoreWebView2_14) + ['{517B2D1D-7DAE-4A66-A4F4-10352FFB9518}'] + /// + /// Add an event handler for the `FaviconChanged` event. + /// The `FaviconChanged` event is raised when the + /// [favicon](https://developer.mozilla.org/docs/Glossary/Favicon) + /// had a different URL then the previous URL. + /// The FaviconChanged event will be raised for first navigating to a new + /// document, whether or not a document declares a Favicon in HTML if the + /// favicon is different from the previous fav icon. The event will + /// be raised again if a favicon is declared in its HTML or has script + /// to set its favicon. The favicon information can then be retrieved with + /// `GetFavicon` and `FaviconUri`. + /// + function add_FaviconChanged(const eventHandler: ICoreWebView2FaviconChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove the event handler for `FaviconChanged` event. + /// + function remove_FaviconChanged(token: EventRegistrationToken): HResult; stdcall; + /// + /// Get the current Uri of the favicon as a string. + /// If the value is null, then the return value is `E_POINTER`, otherwise it is `S_OK`. + /// If a page has no favicon then the value is an empty string. + /// + function Get_FaviconUri(out value: PWideChar): HResult; stdcall; + /// + /// Async function for getting the actual image data of the favicon. + /// The image is copied to the `imageStream` object in `ICoreWebView2GetFaviconCompletedHandler`. + /// If there is no image then no data would be copied into the imageStream. + /// The `format` is the file format to return the image stream. + /// `completedHandler` is executed at the end of the operation. + /// + /// \snippet SettingsComponent.cpp FaviconChanged + /// + function GetFavicon(format: COREWEBVIEW2_FAVICON_IMAGE_FORMAT; + const completedHandler: ICoreWebView2GetFaviconCompletedHandler): HResult; stdcall; + end; + + /// + /// Receives `FaviconChanged` events. + /// + /// + /// See the ICoreWebView2FaviconChangedEventHandler article. + /// + ICoreWebView2FaviconChangedEventHandler = interface(IUnknown) + ['{2913DA94-833D-4DE0-8DCA-900FC524A1A4}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; const args: IUnknown): HResult; stdcall; + end; + + /// + /// Receives the result of the `GetFavicon` method. + /// + /// + /// See the ICoreWebView2GetFaviconCompletedHandler article. + /// + ICoreWebView2GetFaviconCompletedHandler = interface(IUnknown) + ['{A2508329-7DA8-49D7-8C05-FA125E4AEE8D}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; const result_: IStream): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2 interface to support printing. + /// + /// + /// See the ICoreWebView2_16 article. + /// + ICoreWebView2_16 = interface(ICoreWebView2_15) + ['{0EB34DC9-9F91-41E1-8639-95CD5943906B}'] + /// + /// Print the current web page asynchronously to the specified printer with the provided settings. + /// See `ICoreWebView2PrintSettings` for description of settings. Passing + /// nullptr for `printSettings` results in default print settings used. + /// + /// The handler will return `errorCode` as `S_OK` and `printStatus` as COREWEBVIEW2_PRINT_STATUS_PRINTER_UNAVAILABLE + /// if `printerName` doesn't match with the name of any installed printers on the user OS. The handler + /// will return `errorCode` as `E_INVALIDARG` and `printStatus` as COREWEBVIEW2_PRINT_STATUS_OTHER_ERROR + /// if the caller provides invalid settings for a given printer. + /// + /// The async `Print` operation completes when it finishes printing to the printer. + /// At this time the `ICoreWebView2PrintCompletedHandler` is invoked. + /// Only one `Printing` operation can be in progress at a time. If `Print` is called while a `Print` or `PrintToPdf` + /// or `PrintToPdfStream` or `ShowPrintUI` job is in progress, the completed handler is immediately invoked + /// with `E_ABORT` and `printStatus` is COREWEBVIEW2_PRINT_STATUS_OTHER_ERROR. + /// This is only for printing operation on one webview. + /// + /// | errorCode | printStatus | Notes | + /// | --- | --- | --- | + /// | S_OK | COREWEBVIEW2_PRINT_STATUS_SUCCEEDED | Print operation succeeded. | + /// | S_OK | COREWEBVIEW2_PRINT_STATUS_PRINTER_UNAVAILABLE | If specified printer is not found or printer status is not available, offline or error state. | + /// | S_OK | COREWEBVIEW2_PRINT_STATUS_OTHER_ERROR | Print operation is failed. | + /// | E_INVALIDARG | COREWEBVIEW2_PRINT_STATUS_OTHER_ERROR | If the caller provides invalid settings for the specified printer. | + /// | E_ABORT | COREWEBVIEW2_PRINT_STATUS_OTHER_ERROR | Print operation is failed as printing job already in progress. | + /// + /// \snippet AppWindow.cpp PrintToPrinter + /// + function Print(const printSettings: ICoreWebView2PrintSettings; + const handler: ICoreWebView2PrintCompletedHandler): HResult; stdcall; + /// + /// Opens the print dialog to print the current web page. See `COREWEBVIEW2_PRINT_DIALOG_KIND` + /// for descriptions of print dialog kinds. + /// + /// Invoking browser or system print dialog doesn't open new print dialog if + /// it is already open. + /// + /// \snippet AppWindow.cpp ShowPrintUI + /// + function ShowPrintUI(printDialogKind: COREWEBVIEW2_PRINT_DIALOG_KIND): HResult; stdcall; + /// + /// Provides the Pdf data of current web page asynchronously for the provided settings. + /// Stream will be rewound to the start of the pdf data. + /// + /// See `ICoreWebView2PrintSettings` for description of settings. Passing + /// nullptr for `printSettings` results in default print settings used. + /// + /// The async `PrintToPdfStream` operation completes when it finishes + /// writing to the stream. At this time the `ICoreWebView2PrintToPdfStreamCompletedHandler` + /// is invoked. Only one `Printing` operation can be in progress at a time. If + /// `PrintToPdfStream` is called while a `PrintToPdfStream` or `PrintToPdf` or `Print` + /// or `ShowPrintUI` job is in progress, the completed handler is immediately invoked with `E_ABORT`. + /// This is only for printing operation on one webview. + /// + /// \snippet AppWindow.cpp PrintToPdfStream + /// + function PrintToPdfStream(const printSettings: ICoreWebView2PrintSettings; + const handler: ICoreWebView2PrintToPdfStreamCompletedHandler): HResult; stdcall; + end; + + /// + /// Receives the result of the Print method. + /// + /// + /// See the ICoreWebView2PrintCompletedHandler article. + /// + ICoreWebView2PrintCompletedHandler = interface(IUnknown) + ['{8FD80075-ED08-42DB-8570-F5D14977461E}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; result_: COREWEBVIEW2_PRINT_STATUS): HResult; stdcall; + end; + + /// + /// Receives the result of the PrintToPdfStream method. + /// errorCode returns S_OK if the PrintToPdfStream operation succeeded. + /// The printable pdf data is returned in the pdfStream object. + /// + /// + /// See the ICoreWebView2PrintToPdfStreamCompletedHandler article. + /// + ICoreWebView2PrintToPdfStreamCompletedHandler = interface(IUnknown) + ['{4C9F8229-8F93-444F-A711-2C0DFD6359D5}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; const result_: IStream): HResult; stdcall; + end; + + /// + /// This interface is an extension of ICoreWebView2_16 that supports shared buffer based on file mapping. + /// + /// + /// See the ICoreWebView2_17 article. + /// + ICoreWebView2_17 = interface(ICoreWebView2_16) + ['{702E75D4-FD44-434D-9D70-1A68A6B1192A}'] + /// + /// Share a shared buffer object with script of the main frame in the WebView. + /// The script will receive a `sharedbufferreceived` event from chrome.webview. + /// The event arg for that event will have the following methods and properties: + /// `getBuffer()`: return an ArrayBuffer object with the backing content from the shared buffer. + /// `additionalData`: an object as the result of parsing `additionalDataAsJson` as JSON string. + /// This property will be `undefined` if `additionalDataAsJson` is nullptr or empty string. + /// `source`: with a value set as `chrome.webview` object. + /// If a string is provided as `additionalDataAsJson` but it is not a valid JSON string, + /// the API will fail with `E_INVALIDARG`. + /// If `access` is COREWEBVIEW2_SHARED_BUFFER_ACCESS_READ_ONLY, the script will only have read access to the buffer. + /// If the script tries to modify the content in a read only buffer, it will cause an access + /// violation in WebView renderer process and crash the renderer process. + /// If the shared buffer is already closed, the API will fail with `RO_E_CLOSED`. + /// + /// The script code should call `chrome.webview.releaseBuffer` with + /// the shared buffer as the parameter to release underlying resources as soon + /// as it does not need access to the shared buffer any more. + /// + /// The application can post the same shared buffer object to multiple web pages or iframes, or + /// post to the same web page or iframe multiple times. Each `PostSharedBufferToScript` will + /// create a separate ArrayBuffer object with its own view of the memory and is separately + /// released. The underlying shared memory will be released when all the views are released. + /// + /// For example, if we want to send data to script for one time read only consumption. + /// + /// \snippet ScenarioSharedBuffer.cpp OneTimeShareBuffer + /// + /// In the HTML document, + /// + /// \snippet assets\ScenarioSharedBuffer.html ShareBufferScriptCode_1 + /// + /// \snippet assets\ScenarioSharedBuffer.html ShareBufferScriptCode_2 + /// + /// Sharing a buffer to script has security risk. You should only share buffer with trusted site. + /// If a buffer is shared to a untrusted site, possible sensitive information could be leaked. + /// If a buffer is shared as modifiable by the script and the script modifies it in an unexpected way, + /// it could result in corrupted data that might even crash the application. + /// + function PostSharedBufferToScript(const sharedBuffer: ICoreWebView2SharedBuffer; + access: COREWEBVIEW2_SHARED_BUFFER_ACCESS; + additionalDataAsJson: PWideChar): HResult; stdcall; + end; + + /// + /// The shared buffer object that is created by [CreateSharedBuffer](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2environment12#createsharedbuffer). + /// The object is presented to script as ArrayBuffer when posted to script with + /// [PostSharedBufferToScript](/microsoft-edge/webview2/reference/win32/icorewebview2_17#postsharedbuffertoscript). + /// + /// + /// See the ICoreWebView2SharedBuffer article. + /// + ICoreWebView2SharedBuffer = interface(IUnknown) + ['{B747A495-0C6F-449E-97B8-2F81E9D6AB43}'] + /// + /// The size of the shared buffer in bytes. + /// + function Get_Size(out value: Largeuint): HResult; stdcall; + /// + /// The memory address of the shared buffer. + /// + {* out value: PByte1 --> out value: PByte ************** WEBVIEW4DELPHI ************** *} + function Get_Buffer(out value: PByte): HResult; stdcall; + /// + /// Get an IStream object that can be used to access the shared buffer. + /// + function OpenStream(out value: IStream): HResult; stdcall; + /// + /// Returns a handle to the file mapping object that backs this shared buffer. + /// The returned handle is owned by the shared buffer object. You should not + /// call CloseHandle on it. + /// Normal app should use `Buffer` or `OpenStream` to get memory address + /// or IStream object to access the buffer. + /// For advanced scenarios, you could use file mapping APIs to obtain other views + /// or duplicate this handle to another application process and create a view from + /// the duplicated handle in that process to access the buffer from that separate process. + /// + {* out value: Pointer --> out value: HANDLE ************** WEBVIEW4DELPHI ************** *} + function Get_FileMappingHandle(out value: HANDLE): HResult; stdcall; + /// + /// Release the backing shared memory. The application should call this API when no + /// access to the buffer is needed any more, to ensure that the underlying resources + /// are released timely even if the shared buffer object itself is not released due to + /// some leaked reference. + /// After the shared buffer is closed, the buffer address and file mapping handle previously + /// obtained becomes invalid and cannot be used anymore. Accessing properties of the object + /// will fail with `RO_E_CLOSED`. Operations like Read or Write on the IStream objects returned + /// from `OpenStream` will fail with `RO_E_CLOSED`. `PostSharedBufferToScript` will also + /// fail with `RO_E_CLOSED`. + /// + /// The script code should call `chrome.webview.releaseBuffer` with + /// the shared buffer as the parameter to release underlying resources as soon + /// as it does not need access the shared buffer any more. + /// When script tries to access the buffer after calling `chrome.webview.releaseBuffer`, + /// JavaScript `TypeError` exception will be raised complaining about accessing a + /// detached ArrayBuffer, the same exception when trying to access a transferred ArrayBuffer. + /// + /// Closing the buffer object on native side doesn't impact access from Script and releasing + /// the buffer from script doesn't impact access to the buffer from native side. + /// The underlying shared memory will be released by the OS when both native and script side + /// release the buffer. + /// + function Close: HResult; stdcall; + end; + + /// + /// This interface is an extension of ICoreWebView2_17 that manages + /// navigation requests to URI schemes registered with the OS. + /// + /// + /// See the ICoreWebView2_18 article. + /// + ICoreWebView2_18 = interface(ICoreWebView2_17) + ['{7A626017-28BE-49B2-B865-3BA2B3522D90}'] + /// + /// Adds an event handler for the `LaunchingExternalUriScheme` event. + /// The `LaunchingExternalUriScheme` event is raised when a navigation request is made to + /// a URI scheme that is registered with the OS. + /// The `LaunchingExternalUriScheme` event handler may suppress the default dialog + /// or replace the default dialog with a custom dialog. + /// + /// If a deferral is not taken on the event args, the external URI scheme launch is + /// blocked until the event handler returns. If a deferral is taken, the + /// external URI scheme launch is blocked until the deferral is completed. + /// The host also has the option to cancel the URI scheme launch. + /// + /// The `NavigationStarting` and `NavigationCompleted` events will be raised, + /// regardless of whether the `Cancel` property is set to `TRUE` or + /// `FALSE`. The `NavigationCompleted` event will be raised with the `IsSuccess` property + /// set to `FALSE` and the `WebErrorStatus` property set to `ConnectionAborted` regardless of + /// whether the host sets the `Cancel` property on the + /// `ICoreWebView2LaunchingExternalUriSchemeEventArgs`. The `SourceChanged`, `ContentLoading`, + /// and `HistoryChanged` events will not be raised for this navigation to the external URI + /// scheme regardless of the `Cancel` property. + /// The `LaunchingExternalUriScheme` event will be raised after the + /// `NavigationStarting` event and before the `NavigationCompleted` event. + /// The default `CoreWebView2Settings` will also be updated upon navigation to an external + /// URI scheme. If a setting on the `CoreWebView2Settings` interface has been changed, + /// navigating to an external URI scheme will trigger the `CoreWebView2Settings` to update. + /// + /// The WebView2 may not display the default dialog based on user settings, browser settings, + /// and whether the origin is determined as a + /// [trustworthy origin](https://w3c.github.io/webappsec-secure-contexts# + /// potentially-trustworthy-origin); however, the event will still be raised. + /// + /// If the request is initiated by a cross-origin frame without a user gesture, + /// the request will be blocked and the `LaunchingExternalUriScheme` event will not + /// be raised. + /// + /// \snippet SettingsComponent.cpp ToggleLaunchingExternalUriScheme + /// + function add_LaunchingExternalUriScheme(const eventHandler: ICoreWebView2LaunchingExternalUriSchemeEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with + /// `add_LaunchingExternalUriScheme`. + /// + function remove_LaunchingExternalUriScheme(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives `LaunchingExternalUriScheme` events. + /// + /// + /// See the ICoreWebView2LaunchingExternalUriSchemeEventHandler article. + /// + ICoreWebView2LaunchingExternalUriSchemeEventHandler = interface(IUnknown) + ['{74F712E0-8165-43A9-A13F-0CCE597E75DF}'] + /// + /// Receives the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2LaunchingExternalUriSchemeEventArgs): HResult; stdcall; + end; + + /// + /// Event args for LaunchingExternalUriScheme event. + /// + /// + /// See the ICoreWebView2LaunchingExternalUriSchemeEventArgs article. + /// + ICoreWebView2LaunchingExternalUriSchemeEventArgs = interface(IUnknown) + ['{07D1A6C3-7175-4BA1-9306-E593CA07E46C}'] + /// + /// The URI with the external URI scheme to be launched. + /// + function Get_uri(out value: PWideChar): HResult; stdcall; + /// + /// The origin initiating the external URI scheme launch. + /// The origin will be an empty string if the request is initiated by calling + /// `CoreWebView2.Navigate` on the external URI scheme. If a script initiates + /// the navigation, the `InitiatingOrigin` will be the top-level document's + /// `Source`, for example, if `window.location` is set to `"calculator://"`, the + /// `InitiatingOrigin` will be set to `calculator://`. If the request is initiated + /// from a child frame, the `InitiatingOrigin` will be the source of that child frame. + /// If the `InitiatingOrigin` is + /// [opaque](https://html.spec.whatwg.org/multipage/origin.html#concept-origin-opaque), + /// the `InitiatingOrigin` reported in the event args will be its precursor origin. + /// The precursor origin is the origin that created the opaque origin. For example, if + /// a frame on example.com opens a subframe with a different opaque origin, the subframe's + /// precursor origin is example.com. + /// + function Get_InitiatingOrigin(out value: PWideChar): HResult; stdcall; + /// + /// `TRUE` when the external URI scheme request was initiated through a user gesture. + /// + /// \> [!NOTE]\n\> Being initiated through a user gesture does not mean that user intended + /// to access the associated resource. + /// + function Get_IsUserInitiated(out value: Integer): HResult; stdcall; + /// + /// The event handler may set this property to `TRUE` to cancel the external URI scheme + /// launch. If set to `TRUE`, the external URI scheme will not be launched, and the default + /// dialog is not displayed. This property can be used to replace the normal + /// handling of launching an external URI scheme. + /// The initial value of the `Cancel` property is `FALSE`. + /// + function Get_Cancel(out value: Integer): HResult; stdcall; + /// + /// Sets the `Cancel` property. + /// + function Set_Cancel(value: Integer): HResult; stdcall; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this operation to + /// complete the event at a later time. + /// + function GetDeferral(out value: ICoreWebView2Deferral): HResult; stdcall; + end; + + /// + /// This interface is an extension of ICoreWebView2_18 that manages memory usage + /// target level. + /// + /// + /// See the ICoreWebView2_19 article. + /// + ICoreWebView2_19 = interface(ICoreWebView2_18) + ['{6921F954-79B0-437F-A997-C85811897C68}'] + /// + /// `MemoryUsageTargetLevel` indicates desired memory consumption level of + /// WebView. + /// + function Get_MemoryUsageTargetLevel(out value: COREWEBVIEW2_MEMORY_USAGE_TARGET_LEVEL): HResult; stdcall; + /// + /// An app may set `MemoryUsageTargetLevel` to indicate desired memory + /// consumption level of WebView. Scripts will not be impacted and continue + /// to run. This is useful for inactive apps that still want to run scripts + /// and/or keep network connections alive and therefore could not call + /// `TrySuspend` and `Resume` to reduce memory consumption. These apps can + /// set memory usage target level to `COREWEBVIEW2_MEMORY_USAGE_TARGET_LEVEL_LOW` + /// when the app becomes inactive, and set back to + /// `COREWEBVIEW2_MEMORY_USAGE_TARGET_LEVEL_NORMAL` when the app becomes + /// active. It is not necessary to set CoreWebView2Controller's IsVisible + /// property to false when setting the property. + /// It is a best effort operation to change memory usage level, and the + /// API will return before the operation completes. + /// Setting the level to `COREWEBVIEW2_MEMORY_USAGE_TARGET_LEVEL_LOW` + /// could potentially cause memory for some WebView browser processes to be + /// swapped out to disk in some circumstances. + /// It is a best effort to reduce memory usage as much as possible. If a script + /// runs after its related memory has been swapped out, the memory will be swapped + /// back in to ensure the script can still run, but performance might be impacted. + /// Therefore, the app should set the level back to + /// `COREWEBVIEW2_MEMORY_USAGE_TARGET_LEVEL_NORMAL` when the app becomes + /// active again. Setting memory usage target level back to normal will not happen + /// automatically. + /// An app should choose to use either the combination of `TrySuspend` and `Resume` + /// or the combination of setting MemoryUsageTargetLevel to low and normal. It is + /// not advisable to mix them. + /// Trying to set `MemoryUsageTargetLevel` while suspended will be ignored. + /// The `TrySuspend` and `Resume` methods will change the `MemoryUsageTargetLevel`. + /// `TrySuspend` will automatically set `MemoryUsageTargetLevel` to low while + /// `Resume` on suspended WebView will automatically set `MemoryUsageTargetLevel` + /// to normal. Calling `Resume` when the WebView is not suspended would not change + /// `MemoryUsageTargetLevel`. + /// + /// \snippet ViewComponent.cpp MemoryUsageTargetLevel + /// + function Set_MemoryUsageTargetLevel(value: COREWEBVIEW2_MEMORY_USAGE_TARGET_LEVEL): HResult; stdcall; + end; + + /// + /// This interface is an extension of `ICoreWebView2_19` that provides the `FrameId` property. + /// + /// + /// See the ICoreWebView2_20 article. + /// + ICoreWebView2_20 = interface(ICoreWebView2_19) + ['{B4BC1926-7305-11EE-B962-0242AC120002}'] + /// + /// The unique identifier of the main frame. It's the same kind of ID as + /// with the `FrameId` in `CoreWebView2Frame` and via `CoreWebView2FrameInfo`. + /// Note that `FrameId` may not be valid if `CoreWebView2` has not done + /// any navigation. It's safe to get this value during or after the first + /// `ContentLoading` event. Otherwise, it could return the invalid frame Id 0. + /// + function Get_FrameId(out value: SYSUINT): HResult; stdcall; + end; + + /// + /// This is the interface for getting string and exception with ExecuteScriptWithResult. + /// + /// + /// See the ICoreWebView2_21 article. + /// + ICoreWebView2_21 = interface(ICoreWebView2_20) + ['{C4980DEA-587B-43B9-8143-3EF3BF552D95}'] + /// + /// Run JavaScript code from the JavaScript parameter in the current + /// top-level document rendered in the WebView. + /// The result of the execution is returned asynchronously in the CoreWebView2ExecuteScriptResult object + /// which has methods and properties to obtain the successful result of script execution as well as any + /// unhandled JavaScript exceptions. + /// If this method is + /// run after the NavigationStarting event during a navigation, the script + /// runs in the new document when loading it, around the time + /// ContentLoading is run. This operation executes the script even if + /// ICoreWebView2Settings::IsScriptEnabled is set to FALSE. + /// + /// \snippet ScriptComponent.cpp ExecuteScriptWithResult + /// + function ExecuteScriptWithResult(javaScript: PWideChar; + const handler: ICoreWebView2ExecuteScriptWithResultCompletedHandler): HResult; stdcall; + end; + + /// + /// Receives the result of the `ExecuteScriptWithResult` method. + /// + /// + /// See the ICoreWebView2ExecuteScriptWithResultCompletedHandler article. + /// + ICoreWebView2ExecuteScriptWithResultCompletedHandler = interface(IUnknown) + ['{1BB5317B-8238-4C67-A7FF-BAF6558F289D}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; const result: ICoreWebView2ExecuteScriptResult): HResult; stdcall; + end; + + /// + /// This is the result for ExecuteScriptWithResult. + /// + /// + /// See the ICoreWebView2ExecuteScriptResult article. + /// + ICoreWebView2ExecuteScriptResult = interface(IUnknown) + ['{0CE15963-3698-4DF7-9399-71ED6CDD8C9F}'] + /// + /// This property is true if ExecuteScriptWithResult successfully executed script with + /// no unhandled exceptions and the result is available in the ResultAsJson property + /// or via the TryGetResultAsString method. + /// If it is false then the script execution had an unhandled exception which you + /// can get via the Exception property. + /// + function Get_Succeeded(out value: Integer): HResult; stdcall; + /// + /// A function that has no explicit return value returns undefined. If the + /// script that was run throws an unhandled exception, then the result is + /// also "null". This method is applied asynchronously. If the method is + /// run before `ContentLoading`, the script will not be executed + /// and the string "null" will be returned. + /// The return value description is as follows + /// 1. S_OK: Execution succeeds. + /// 2. E_POINTER: When the `jsonResult` is nullptr. + /// + function Get_ResultAsJson(out jsonResult: PWideChar): HResult; stdcall; + /// + /// If Succeeded is true and the result of script execution is a string, this method provides the value of the string result, + /// and we will get the `FALSE` var value when the js result is not string type. + /// The return value description is as follows + /// 1. S_OK: Execution succeeds. + /// 2. E_POINTER: When the `stringResult` or `value` is nullptr. + /// NOTE: If the `value` returns `FALSE`, the `stringResult` will be set to a empty string. + /// + function TryGetResultAsString(out stringResult: PWideChar; out value: Integer): HResult; stdcall; + /// + /// If Succeeded is false, you can use this property to get the unhandled exception thrown by script execution + /// Note that due to the compatibility of the WinRT/.NET interface, + /// S_OK will be returned even if the acquisition fails. + /// We can determine whether the acquisition is successful by judging whether the `exception` is nullptr. + /// + function Get_Exception(out Exception: ICoreWebView2ScriptException): HResult; stdcall; + end; + + /// + /// This interface represents a JavaScript exception. + /// If the CoreWebView2.ExecuteScriptWithResult result has Succeeded as false, + /// you can use the result's Exception property to get the script exception. + /// + /// + /// See the ICoreWebView2ScriptException article. + /// + ICoreWebView2ScriptException = interface(IUnknown) + ['{054DAE00-84A3-49FF-BC17-4012A90BC9FD}'] + /// + /// The line number of the source where the exception occurred. + /// In the JSON it is `exceptionDetail.lineNumber`. + /// Note that this position starts at 0. + /// + function Get_LineNumber(out value: SYSUINT): HResult; stdcall; + /// + /// The column number of the source where the exception occurred. + /// In the JSON it is `exceptionDetail.columnNumber`. + /// Note that this position starts at 0. + /// + function Get_ColumnNumber(out value: SYSUINT): HResult; stdcall; + /// + /// The Name is the exception's class name. + /// In the JSON it is `exceptionDetail.exception.className`. + /// This is the empty string if the exception doesn't have a class name. + /// This can happen if the script throws a non-Error object such as `throw "abc";` + /// + function Get_name(out value: PWideChar): HResult; stdcall; + /// + /// The Message is the exception's message and potentially stack. + /// In the JSON it is exceptionDetail.exception.description. + /// This is the empty string if the exception doesn't have a description. + /// This can happen if the script throws a non-Error object such as throw "abc";. + /// + function Get_Message(out value: PWideChar): HResult; stdcall; + /// + /// This will return all details of the exception as a JSON string. + /// In the case that script has thrown a non-Error object such as `throw "abc";` + /// or any other non-Error object, you can get object specific properties. + /// + function Get_ToJson(out value: PWideChar): HResult; stdcall; + end; + + /// + /// This interface is an extension of `ICoreWebView2` that allows to + /// set filters in order to receive WebResourceRequested events for + /// service workers, shared workers and different origin iframes. + /// + /// + /// See the ICoreWebView2_22 article. + /// + ICoreWebView2_22 = interface(ICoreWebView2_21) + ['{DB75DFC7-A857-4632-A398-6969DDE26C0A}'] + /// + /// A web resource request with a resource context that matches this + /// filter's resource context and a URI that matches this filter's URI + /// wildcard string for corresponding request sources will be raised via + /// the `WebResourceRequested` event. To receive all raised events filters + /// have to be added before main page navigation. + /// + /// The `uri` parameter value is a wildcard string matched against the URI + /// of the web resource request. This is a glob style + /// wildcard string in which a `*` matches zero or more characters and a `?` + /// matches exactly one character. + /// These wildcard characters can be escaped using a backslash just before + /// the wildcard character in order to represent the literal `*` or `?`. + /// + /// The matching occurs over the URI as a whole string and not limiting + /// wildcard matches to particular parts of the URI. + /// The wildcard filter is compared to the URI after the URI has been + /// normalized, any URI fragment has been removed, and non-ASCII hostnames + /// have been converted to punycode. + /// + /// Specifying a `nullptr` for the uri is equivalent to an empty string which + /// matches no URIs. + /// + /// For more information about resource context filters, navigate to + /// [COREWEBVIEW2_WEB_RESOURCE_CONTEXT](/microsoft-edge/webview2/reference/win32/icorewebview2#corewebview2_web_resource_context). + /// + /// The `requestSourceKinds` is a mask of one or more + /// `COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS`. OR operation(s) can be + /// applied to multiple `COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS` to + /// create a mask representing those data types. API returns `E_INVALIDARG` if + /// `requestSourceKinds` equals to zero. For more information about request + /// source kinds, navigate to + /// [COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS](/microsoft-edge/webview2/reference/win32/icorewebview2#corewebview2_web_resource_request_source_kinds). + /// + /// Because service workers and shared workers run separately from any one + /// HTML document their WebResourceRequested will be raised for all + /// CoreWebView2s that have appropriate filters added in the corresponding + /// CoreWebView2Environment. You should only add a WebResourceRequested filter + /// for COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_SERVICE_WORKER or + /// COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_SHARED_WORKER on + /// one CoreWebView2 to avoid handling the same WebResourceRequested + /// event multiple times. + /// + /// | URI Filter String | Request URI | Match | Notes | + /// | ---- | ---- | ---- | ---- | + /// | `*` | `https://contoso.com/a/b/c` | Yes | A single * will match all URIs | + /// | `*://contoso.com/*` | `https://contoso.com/a/b/c` | Yes | Matches everything in contoso.com across all schemes | + /// | `*://contoso.com/*` | `https://example.com/?https://contoso.com/` | Yes | But also matches a URI with just the same text anywhere in the URI | + /// | `example` | `https://contoso.com/example` | No | The filter does not perform partial matches | + /// | `*example` | `https://contoso.com/example` | Yes | The filter matches across URI parts | + /// | `*example` | `https://contoso.com/path/?example` | Yes | The filter matches across URI parts | + /// | `*example` | `https://contoso.com/path/?query#example` | No | The filter is matched against the URI with no fragment | + /// | `*example` | `https://example` | No | The URI is normalized before filter matching so the actual URI used for comparison is `https://example/` | + /// | `*example/` | `https://example` | Yes | Just like above, but this time the filter ends with a / just like the normalized URI | + /// | `https://xn--qei.example/` | `https://❤.example/` | Yes | Non-ASCII hostnames are normalized to punycode before wildcard comparison | + /// | `https://❤.example/` | `https://xn--qei.example/` | No | Non-ASCII hostnames are normalized to punycode before wildcard comparison | + /// + /// \snippet ScenarioSharedWorkerWRR.cpp WebResourceRequested2 + /// + function AddWebResourceRequestedFilterWithRequestSourceKinds(uri: PWideChar; + ResourceContext: COREWEBVIEW2_WEB_RESOURCE_CONTEXT; + requestSourceKinds: COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS): HResult; stdcall; + /// + /// Removes a matching WebResource filter that was previously added for the + /// `WebResourceRequested` event. If the same filter was added multiple + /// times, then it must be removed as many times as it was added for the + /// removal to be effective. Returns `E_INVALIDARG` for a filter that was + /// not added or is already removed. + /// If the filter was added for multiple requestSourceKinds and removed just for one of them + /// the filter remains for the non-removed requestSourceKinds. + /// + function RemoveWebResourceRequestedFilterWithRequestSourceKinds(uri: PWideChar; + ResourceContext: COREWEBVIEW2_WEB_RESOURCE_CONTEXT; + requestSourceKinds: COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS): HResult; stdcall; + end; + + /// + /// This is the ICoreWebView_23 interface for + /// PostWebMessageAsJsonWithAdditionalObjects. + /// + /// + /// See the ICoreWebView2_23 article. + /// + ICoreWebView2_23 = interface(ICoreWebView2_22) + ['{508F0DB5-90C4-5872-90A7-267A91377502}'] + /// + /// Same as `PostWebMessageAsJson`, but also has support for posting DOM objects + /// to page content. The `additionalObjects` property in the DOM MessageEvent + /// fired on the page content is an array-like list of DOM objects that can + /// be posted to the web content. Currently these can be the following + /// types of objects: + /// + /// | Win32 | DOM type | + /// |-------------------|-------------| + /// | ICoreWebView2FileSystemHandle | [FileSystemHandle](https://developer.mozilla.org/docs/Web/API/FileSystemHandle) | + /// | nullptr | null | + /// + /// The objects are posted to the web content, following the + /// [structured-clone](https://developer.mozilla.org/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) + /// semantics, meaning only objects that can be cloned can be posted. + /// They will also behave as if they had been created by the web content they are + /// posted to. For example, if a FileSystemFileHandle is posted to a web content + /// it can only be re-transferred via postMessage to other web content + /// [with the same origin](https://fs.spec.whatwg.org/#filesystemhandle). + /// Warning: An app needs to be mindful when using this API to post DOM objects + /// as this API provides the web content with unusual access to sensitive Web + /// Platform features such as filesystem access! Similar to PostWebMessageAsJson + /// the app should check the `Source` property of WebView2 right before posting the message + /// to ensure the message and objects will only be sent to the target web content + /// that it expects to receive the DOM objects. Additionally, the order + /// of messages that are posted between `PostWebMessageAsJson` and `PostWebMessageAsJsonWithAdditionalObjects` + /// may not be preserved. + /// \snippet ScenarioFileSystemHandleShare.cpp PostWebMessageWithAdditionalObjects + /// + function PostWebMessageAsJsonWithAdditionalObjects(webMessageAsJson: PWideChar; + const additionalObjects: ICoreWebView2ObjectCollectionView): HResult; stdcall; + end; + + /// + /// This is the ICoreWebView2_24 interface that manages WebView2 Web + /// Notification functionality. + /// + /// + /// See the ICoreWebView2_24 article. + /// + ICoreWebView2_24 = interface(ICoreWebView2_23) + ['{39A7AD55-4287-5CC1-88A1-C6F458593824}'] + /// + /// Adds an event handler for the `NotificationReceived` event for + /// non-persistent notifications. + /// + /// If a deferral is not taken on the event args, the subsequent scripts after + /// the DOM notification creation call (i.e. `Notification()`) are blocked + /// until the event handler returns. If a deferral is taken, the scripts are + /// blocked until the deferral is completed. + /// + function add_NotificationReceived(const eventHandler: ICoreWebView2NotificationReceivedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_NotificationReceived`. + /// + function remove_NotificationReceived(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives `NotificationReceived` events. + /// + /// + /// See the ICoreWebView2NotificationReceivedEventHandler article. + /// + ICoreWebView2NotificationReceivedEventHandler = interface(IUnknown) + ['{89C5D598-8788-423B-BE97-E6E01C0F9EE3}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2NotificationReceivedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the `NotificationReceived` event. + /// \snippet ScenarioNotificationReceived.cpp NotificationReceived + /// + /// + /// See the ICoreWebView2NotificationReceivedEventArgs article. + /// + ICoreWebView2NotificationReceivedEventArgs = interface(IUnknown) + ['{1512DD5B-5514-4F85-886E-21C3A4C9CFE6}'] + /// + /// The origin of the web content that sends the notification, such as + /// `https://example.com/` or `https://www.example.com/`. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_SenderOrigin(out value: PWideChar): HResult; stdcall; + /// + /// The notification that was received. You can access the + /// properties on the Notification object to show your own notification. + /// + function Get_Notification(out value: ICoreWebView2Notification): HResult; stdcall; + /// + /// Sets whether the `NotificationReceived` event is handled by the host after + /// the event handler completes or if there is a deferral then after the + /// deferral is completed. + /// + /// If `Handled` is set to TRUE then WebView will not display the notification + /// with the default UI, and the host will be responsible for handling the + /// notification and for letting the web content know that the notification + /// has been displayed, clicked, or closed. You must set `Handled` to `TRUE` + /// before you call `ReportShown`, `ReportClicked`, + /// `ReportClickedWithActionIndex` and `ReportClosed`, otherwise they will + /// fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`. If after the event + /// handler or deferral completes `Handled` is set to FALSE then WebView will + /// display the default notification UI. Note that you cannot un-handle this + /// event once you have set `Handled` to be `TRUE`. The initial value is + /// FALSE. + /// + function Set_Handled(value: Integer): HResult; stdcall; + /// + /// Gets whether the `NotificationReceived` event is handled by host. + /// + function Get_Handled(out value: Integer): HResult; stdcall; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this operation to complete + /// the event at a later time. + /// + function GetDeferral(out deferral: ICoreWebView2Deferral): HResult; stdcall; + end; + + /// + /// This is the ICoreWebView2Notification that represents a [HTML Notification + /// object](https://developer.mozilla.org/docs/Web/API/Notification). + /// + /// + /// See the ICoreWebView2Notification article. + /// + ICoreWebView2Notification = interface(IUnknown) + ['{B7434D98-6BC8-419D-9DA5-FB5A96D4DACD}'] + /// + /// Add an event handler for the `CloseRequested` event. This event is raised + /// when the notification is closed by the web code, such as through + /// `notification.close()`. You don't need to call `ReportClosed` since this is + /// coming from the web code. + /// + function add_CloseRequested(const eventHandler: ICoreWebView2NotificationCloseRequestedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_CloseRequested`. + /// + function remove_CloseRequested(token: EventRegistrationToken): HResult; stdcall; + /// + /// The host may run this to report the notification has been displayed and it + /// will cause the + /// [show](https://developer.mozilla.org/docs/Web/API/Notification/show_event) + /// event to be raised for non-persistent notifications. You must not run this + /// unless you are handling the `NotificationReceived` event. Returns + /// `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)` if `Handled` is `FALSE` when + /// this is called. + /// + function ReportShown: HResult; stdcall; + /// + /// The host may run this to report the notification has been clicked, and it + /// will cause the + /// [click](https://developer.mozilla.org/docs/Web/API/Notification/click_event) + /// event to be raised for non-persistent notifications and the + /// [notificationclick](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope/notificationclick_event) + /// event for persistent notifications. Use `ReportClickedWithActionIndex` to + /// specify an action to activate a persistent notification. You must not run + /// this unless you are handling the `NotificationReceived` event. Returns + /// `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)` if `Handled` is `FALSE` or + /// `ReportShown` has not been run when this is called. + /// + function ReportClicked: HResult; stdcall; + /// + /// The host may run this to report the notification was dismissed, and it + /// will cause the + /// [close](https://developer.mozilla.org/docs/Web/API/Notification/close_event) + /// event to be raised for non-persistent notifications and the + /// [notificationclose](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope/notificationclose_event) + /// event for persistent notifications. You must not run this unless you are + /// handling the `NotificationReceived` event. Returns + /// `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)` if `Handled` is `FALSE` or + /// `ReportShown` has not been run when this is called. + /// + function ReportClosed: HResult; stdcall; + /// + /// A string representing the body text of the notification. + /// The default value is an empty string. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Body(out value: PWideChar): HResult; stdcall; + /// + /// The text direction in which to display the notification. + /// This corresponds to + /// [Notification.dir](https://developer.mozilla.org/docs/Web/API/Notification/dir) + /// DOM API. + /// The default value is `COREWEBVIEW2_TEXT_DIRECTION_KIND_DEFAULT`. + /// + function Get_Direction(out value: COREWEBVIEW2_TEXT_DIRECTION_KIND): HResult; stdcall; + /// + /// The notification's language, as intended to be specified using a string + /// representing a language tag (such as `en-US`) according to + /// [BCP47](https://datatracker.ietf.org/doc/html/rfc5646). Note that no + /// validation is performed on this property and it can be any string the + /// notification sender specifies. + /// This corresponds to + /// [Notification.lang](https://developer.mozilla.org/docs/Web/API/Notification/lang) + /// DOM API. + /// The default value is an empty string. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Language(out value: PWideChar): HResult; stdcall; + /// + /// A string representing an identifying tag for the notification. + /// This corresponds to + /// [Notification.tag](https://developer.mozilla.org/docs/Web/API/Notification/tag) + /// DOM API. + /// The default value is an empty string. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Tag(out value: PWideChar): HResult; stdcall; + /// + /// A string containing the URI of an icon to be displayed in the + /// notification. + /// The default value is an empty string. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_IconUri(out value: PWideChar): HResult; stdcall; + /// + /// The title of the notification. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_title(out value: PWideChar): HResult; stdcall; + /// + /// A string containing the URI of the image used to represent the + /// notification when there isn't enough space to display the notification + /// itself. + /// The default value is an empty string. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_BadgeUri(out value: PWideChar): HResult; stdcall; + /// + /// A string containing the URI of an image to be displayed in the + /// notification. + /// The default value is an empty string. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_BodyImageUri(out value: PWideChar): HResult; stdcall; + /// + /// Indicates whether the user should be notified after a new notification + /// replaces an old one. + /// This corresponds to + /// [Notification.renotify](https://developer.mozilla.org/docs/Web/API/Notification/renotify) + /// DOM API. + /// The default value is `FALSE`. + /// + function Get_ShouldRenotify(out value: Integer): HResult; stdcall; + /// + /// A boolean value indicating that a notification should remain active until + /// the user clicks or dismisses it, rather than closing automatically. + /// This corresponds to + /// [Notification.requireInteraction](https://developer.mozilla.org/docs/Web/API/Notification/requireInteraction) + /// DOM API. Note that you may not be able to necessarily implement this due to native API limitations. + /// The default value is `FALSE`. + /// + function Get_RequiresInteraction(out value: Integer): HResult; stdcall; + /// + /// Indicates whether the notification should be silent -- i.e., no sounds or + /// vibrations should be issued, regardless of the device settings. + /// This corresponds to + /// [Notification.silent](https://developer.mozilla.org/docs/Web/API/Notification/silent) + /// DOM API. + /// The default value is `FALSE`. + /// + function Get_IsSilent(out value: Integer): HResult; stdcall; + /// + /// Indicates the time at which a notification is created or applicable (past, + /// present, or future) as the number of milliseconds since the UNIX epoch. + /// + function Get_Timestamp(out value: Double): HResult; stdcall; + /// + /// Gets the vibration pattern for devices with vibration hardware to emit. + /// The vibration pattern can be represented by an array of 64-bit unsigned integers + /// describing a pattern of vibrations and pauses. See [Vibration + /// API](https://developer.mozilla.org/docs/Web/API/Vibration_API) for more + /// information. + /// This corresponds to + /// [Notification.vibrate](https://developer.mozilla.org/docs/Web/API/Notification/vibrate) + /// DOM API. + /// An empty array is returned if no vibration patterns are + /// specified. + /// + {* vibrationPattern: PLargeuint1 --> vibrationPattern: Uint64Array ************** WEBVIEW4DELPHI ************** *} + function GetVibrationPattern(out Count: SYSUINT; out vibrationPattern: Uint64Array): HResult; stdcall; + end; + + /// + /// Receives `CloseRequested` events. + /// + /// + /// See the ICoreWebView2NotificationCloseRequestedEventHandler article. + /// + ICoreWebView2NotificationCloseRequestedEventHandler = interface(IUnknown) + ['{47C32D23-1E94-4733-85F1-D9BF4ACD0974}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Notification; const args: IUnknown): HResult; stdcall; + end; + + /// + /// This is the ICoreWebView2_25 interface. + /// + /// + /// See the ICoreWebView2_25 article. + /// + ICoreWebView2_25 = interface(ICoreWebView2_24) + ['{B5A86092-DF50-5B4F-A17B-6C8F8B40B771}'] + /// + /// Adds an event handler for the `SaveAsUIShowing` event. + /// This event is raised when save as is triggered, programmatically or manually. + /// + /// \snippet ScenarioSaveAs.cpp ToggleSilent + /// + function add_SaveAsUIShowing(const eventHandler: ICoreWebView2SaveAsUIShowingEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_SaveAsUIShowing`. + /// + function remove_SaveAsUIShowing(token: EventRegistrationToken): HResult; stdcall; + /// + /// Programmatically trigger a Save As action for the currently loaded document. + /// The `SaveAsUIShowing` event is raised. + /// + /// Opens a system modal dialog by default. If the `SuppressDefaultDialog` property + /// is `TRUE`, the system dialog is not opened. + /// + /// This method returns `COREWEBVIEW2_SAVE_AS_UI_RESULT`. See + /// `COREWEBVIEW2_SAVE_AS_UI_RESULT` for details. + /// + /// \snippet ScenarioSaveAs.cpp ProgrammaticSaveAs + /// + function ShowSaveAsUI(const handler: ICoreWebView2ShowSaveAsUICompletedHandler): HResult; stdcall; + end; + + /// + /// Receives `SaveAsUIShowing` events. + /// + /// + /// See the ICoreWebView2SaveAsUIShowingEventHandler article. + /// + ICoreWebView2SaveAsUIShowingEventHandler = interface(IUnknown) + ['{6BAA177E-3A2E-5CCF-9A13-FAD676CD0522}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2SaveAsUIShowingEventArgs): HResult; stdcall; + end; + + /// + /// The event args for `SaveAsUIShowing` event. + /// + /// + /// See the ICoreWebView2SaveAsUIShowingEventArgs article. + /// + ICoreWebView2SaveAsUIShowingEventArgs = interface(IUnknown) + ['{55902952-0E0D-5AAA-A7D0-E833CDB34F62}'] + /// + /// Get the Mime type of content to be saved. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_ContentMimeType(out value: PWideChar): HResult; stdcall; + /// + /// Sets the `Cancel` property. Set this property to `TRUE` to cancel the Save As action + /// and prevent the download from starting. ShowSaveAsUI returns + /// `COREWEBVIEW2_SAVE_AS_UI_RESULT_CANCELLED` in this case. The default value is `FALSE`. + /// + function Set_Cancel(value: Integer): HResult; stdcall; + /// + /// Gets the `Cancel` property. + /// + function Get_Cancel(out value: Integer): HResult; stdcall; + /// + /// Sets the `SuppressDefaultDialog` property, which indicates whether the system + /// default dialog is suppressed. When `SuppressDefaultDialog` is `FALSE`, the default + /// Save As dialog is shown and the values assigned through `SaveAsFilePath`, `AllowReplace` + /// and `Kind` are ignored when the event args invoke completed. + /// + /// Set `SuppressDefaultDialog` to `TRUE` to perform a silent Save As. When + /// `SuppressDefaultDialog` is `TRUE`, the system dialog is skipped and the + /// `SaveAsFilePath`, `AllowReplace` and `Kind` values are used. + /// + /// The default value is FALSE. + /// + function Set_SuppressDefaultDialog(value: Integer): HResult; stdcall; + /// + /// Gets the `SuppressDefaultDialog` property. + /// + function Get_SuppressDefaultDialog(out value: Integer): HResult; stdcall; + /// + /// Returns an `ICoreWebView2Deferral` object. This will defer showing the + /// default Save As dialog and performing the Save As operation. + /// + function GetDeferral(out value: ICoreWebView2Deferral): HResult; stdcall; + /// + /// Set the `SaveAsFilePath` property for Save As. `SaveAsFilePath` is an absolute path + /// of the location. It includes the file name and extension. If `SaveAsFilePath` is not + /// valid (for example, the root drive does not exist), Save As is denied and + /// `COREWEBVIEW2_SAVE_AS_INVALID_PATH` is returned. + /// + /// If the associated download completes successfully, a target file is saved at + /// this location. If the Kind property is `COREWEBVIEW2_SAVE_AS_KIND_COMPLETE`, + /// there will be an additional directory with resources files. + /// + /// The default value is a system suggested path, based on users' local environment. + /// + function Set_SaveAsFilePath(value: PWideChar): HResult; stdcall; + /// + /// Gets the `SaveAsFilePath` property. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_SaveAsFilePath(out value: PWideChar): HResult; stdcall; + /// + /// `AllowReplace` allows user to control what happens when a file already + /// exists in the file path to which the Save As operation is saving. + /// Setting this property to `TRUE` allows existing files to be replaced. + /// Setting this property to `FALSE` will not replace existing files and will return + /// `COREWEBVIEW2_SAVE_AS_UI_RESULT_FILE_ALREADY_EXISTS`. + /// + /// The default value is `FALSE`. + /// + function Set_AllowReplace(value: Integer): HResult; stdcall; + /// + /// Gets the `AllowReplace` property. + /// + function Get_AllowReplace(out value: Integer): HResult; stdcall; + /// + /// Sets the `Kind` property to save documents of different kinds. See the + /// `COREWEBVIEW2_SAVE_AS_KIND` enum for a description of the different options. + /// If the kind is not allowed for the current document, ShowSaveAsUI returns + /// `COREWEBVIEW2_SAVE_AS_UI_RESULT_KIND_NOT_SUPPORTED`. + /// + /// The default value is `COREWEBVIEW2_SAVE_AS_KIND_DEFAULT`. + /// + function Set_Kind(value: COREWEBVIEW2_SAVE_AS_KIND): HResult; stdcall; + /// + /// Gets the `Kind` property. + /// + function Get_Kind(out value: COREWEBVIEW2_SAVE_AS_KIND): HResult; stdcall; + end; + + /// + /// Receives the result of the `ShowSaveAsUI` method. + /// + /// + /// See the ICoreWebView2ShowSaveAsUICompletedHandler article. + /// + ICoreWebView2ShowSaveAsUICompletedHandler = interface(IUnknown) + ['{E24B07E3-8169-5C34-994A-7F6478946A3C}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; result_: COREWEBVIEW2_SAVE_AS_UI_RESULT): HResult; stdcall; + end; + + /// + /// This is the ICoreWebView2_26 interface. + /// + /// + /// See the ICoreWebView2_26 article. + /// + ICoreWebView2_26 = interface(ICoreWebView2_25) + ['{806268B8-F897-5685-88E5-C45FCA0B1A48}'] + /// + /// Adds an event handler for the `SaveFileSecurityCheckStarting` event. + /// This event will be raised during system FileTypePolicy + /// checking the dangerous file extension list. + /// + /// Developers can specify their own logic for determining whether + /// to allow a particular type of file to be saved from the document origin URI. + /// Developers can also determine the save decision based on other criteria. + /// + /// Here are two properties in `ICoreWebView2SaveFileSecurityCheckStartingEventArgs` + /// to manage the decision: `CancelSave` and `SuppressDefaultPolicy`. + /// Table of Properties' value and result: + /// + /// | CancelSave | SuppressDefaultPolicy | Result + /// | ---------- | ------ | --------------------- + /// | False | False | Perform the default policy check. It may show the + /// | | | security warning UI if the file extension is + /// | | | dangerous. + /// | ---------- | ------ | --------------------- + /// | False | True | Skip the default policy check and the possible + /// | | | security warning. Start saving or downloading. + /// | ---------- | ------ | --------------------- + /// | True | Any | Skip the default policy check and the possible + /// | | | security warning. Abort save or download. + /// + /// \snippet ScenarioFileTypePolicy.cpp SuppressPolicyForExtension + /// + function add_SaveFileSecurityCheckStarting(const eventHandler: ICoreWebView2SaveFileSecurityCheckStartingEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_SaveFileSecurityCheckStarting`. + /// + function remove_SaveFileSecurityCheckStarting(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives `SaveFileSecurityCheckStarting` events. + /// + /// + /// See the ICoreWebView2SaveFileSecurityCheckStartingEventHandler article. + /// + ICoreWebView2SaveFileSecurityCheckStartingEventHandler = interface(IUnknown) + ['{7899576C-19E3-57C8-B7D1-55808292DE57}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2SaveFileSecurityCheckStartingEventArgs): HResult; stdcall; + end; + + /// + /// The event args for `SaveFileSecurityCheckStarting` event. + /// + /// + /// See the ICoreWebView2SaveFileSecurityCheckStartingEventArgs article. + /// + ICoreWebView2SaveFileSecurityCheckStartingEventArgs = interface(IUnknown) + ['{CF4FF1D1-5A67-5660-8D63-EF699881EA65}'] + /// + /// Gets the `CancelSave` property. + /// + function Get_CancelSave(out value: Integer): HResult; stdcall; + /// + /// Set if cancel the upcoming save/download. `TRUE` means the action + /// will be cancelled before validations in default policy. + /// + /// The default value is `FALSE`. + /// + function Set_CancelSave(value: Integer): HResult; stdcall; + /// + /// Get the document origin URI of this file save operation. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_DocumentOriginUri(out value: PWideChar): HResult; stdcall; + /// + /// Get the extension of file to be saved. + /// + /// The file extension is the extension portion of the FilePath, + /// preserving original case. + /// + /// Only final extension with period "." will be provided. For example, + /// "*.tar.gz" is a double extension, where the ".gz" will be its + /// final extension. + /// + /// File extension can be empty, if the file name has no extension + /// at all. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_FileExtension(out value: PWideChar): HResult; stdcall; + /// + /// Get the full path of file to be saved. This includes the + /// file name and extension. + /// + /// This method doesn't provide path validation, the returned + /// string may longer than MAX_PATH. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_FilePath(out value: PWideChar): HResult; stdcall; + /// + /// Gets the `SuppressDefaultPolicy` property. + /// + function Get_SuppressDefaultPolicy(out value: Integer): HResult; stdcall; + /// + /// Set if the default policy checking and security warning will be + /// suppressed. `TRUE` means it will be suppressed. + /// + /// The default value is `FALSE`. + /// + function Set_SuppressDefaultPolicy(value: Integer): HResult; stdcall; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this operation to complete + /// the SaveFileSecurityCheckStartingEvent. + /// + /// The default policy checking and any default UI will be blocked temporarily, + /// saving file to local won't start, until the deferral is completed. + /// + function GetDeferral(out value: ICoreWebView2Deferral): HResult; stdcall; + end; + + /// + /// This interface is an extension of `ICoreWebView2` that supports the ScreenCaptureStarting event. + /// + /// + /// See the ICoreWebView2_27 article. + /// + ICoreWebView2_27 = interface(ICoreWebView2_26) + ['{00FBE33B-8C07-517C-AA23-0DDD4B5F6FA0}'] + /// + /// Adds an event handler for the `ScreenCaptureStarting` event. + /// Add an event handler for the `ScreenCaptureStarting` event. + /// `ScreenCaptureStarting` event is raised when the [Screen Capture API](https://www.w3.org/TR/screen-capture/) + /// is requested by the user using getDisplayMedia(). + /// \snippet ScenarioScreenCapture.cpp ScreenCaptureStarting0 + /// + function add_ScreenCaptureStarting(const eventHandler: ICoreWebView2ScreenCaptureStartingEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_ScreenCaptureStarting`. + /// + function remove_ScreenCaptureStarting(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives `ScreenCaptureStarting` events. + /// + /// + /// See the ICoreWebView2ScreenCaptureStartingEventHandler article. + /// + ICoreWebView2ScreenCaptureStartingEventHandler = interface(IUnknown) + ['{E24FF05A-1DB5-59D9-89F3-3C864268DB4A}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2ScreenCaptureStartingEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the `ScreenCaptureStarting` event. + /// + /// + /// See the ICoreWebView2ScreenCaptureStartingEventArgs article. + /// + ICoreWebView2ScreenCaptureStartingEventArgs = interface(IUnknown) + ['{892C03FD-AEE3-5EBA-A1FA-6FD2F6484B2B}'] + /// + /// Gets the `Cancel` property. + /// + function Get_Cancel(out value: Integer): HResult; stdcall; + /// + /// The host may set this flag to cancel the screen capture. If canceled, + /// the screen capture UI is not displayed regardless of the + /// `Handled` property. + /// On the script side, it will return with a NotAllowedError as Permission denied. + /// + function Set_Cancel(value: Integer): HResult; stdcall; + /// + /// Gets the `Handled` property. + /// + function Get_Handled(out value: Integer): HResult; stdcall; + /// + /// By default, both the `ScreenCaptureStarting` event handlers on the + /// `CoreWebView2Frame` and the `CoreWebView2` will be invoked, with the + /// `CoreWebView2Frame` event handlers invoked first. The host may + /// set this flag to `TRUE` within the `CoreWebView2Frame` event handlers + /// to prevent the remaining `CoreWebView2` event handlers from being + /// invoked. If the flag is set to `FALSE` within the `CoreWebView2Frame` + /// event handlers, downstream handlers can update the `Cancel` property. + /// + /// If a deferral is taken on the event args, then you must synchronously + /// set `Handled` to TRUE prior to taking your deferral to prevent the + /// `CoreWebView2`s event handlers from being invoked. + /// + function Set_Handled(value: Integer): HResult; stdcall; + /// + /// The associated frame information that requests the screen capture + /// permission. This can be used to get the frame source, name, frameId, + /// and parent frame information. + /// + function Get_OriginalSourceFrameInfo(out value: ICoreWebView2FrameInfo): HResult; stdcall; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this deferral to + /// defer the decision to show the Screen Capture UI. getDisplayMedia() + /// won't call its callbacks until the deferral is completed. + /// + function GetDeferral(out value: ICoreWebView2Deferral): HResult; stdcall; + end; + + /// + /// Provides a set of properties for a frame in the ICoreWebView2. + /// + /// + /// See the ICoreWebView2FrameInfo article. + /// + ICoreWebView2FrameInfo = interface(IUnknown) + ['{DA86B8A1-BDF3-4F11-9955-528CEFA59727}'] + /// + /// The value of iframe's window.name property. The default value equals to + /// iframe html tag declaring it, as in ``. + /// The returned string is empty when the frame has no name attribute and + /// no assigned value for window.name. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_name(out value: PWideChar): HResult; stdcall; + /// + /// The URI of the document in the frame. + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Source(out value: PWideChar): HResult; stdcall; + end; + + /// + /// Interface providing methods to access the find session functionalities in the CoreWebView2. + /// + /// + /// See the ICoreWebView2_28 article. + /// + ICoreWebView2_28 = interface(ICoreWebView2_27) + ['{62E50381-5BF5-51A8-AAE0-F20A3A9C8A90}'] + /// + /// Retrieves the find session interface for the current web view. + /// + function Get_Find(out value: ICoreWebView2Find): HResult; stdcall; + end; + + /// + /// Interface providing methods and properties for finding and navigating through text in the web view. + /// This interface allows for finding text, navigation between matches, and customization of the find UI. + /// + /// + /// See the ICoreWebView2Find article. + /// + ICoreWebView2Find = interface(IUnknown) + ['{A3EC0F5F-DDBC-54ED-8546-AF75A785B9A6}'] + /// + /// Retrieves the index of the currently active match in the find session. Returns the index of the currently active match, or -1 if there is no active match. + /// The index starts at 1 for the first match. + /// + /// \snippet AppWindow.cpp ActiveMatchIndex + /// + function Get_ActiveMatchIndex(out value: SYSINT): HResult; stdcall; + /// + /// Gets the total count of matches found in the current document based on the last find sessions criteria. Returns the total count of matches. + /// + /// \snippet AppWindow.cpp MatchCount + /// + function Get_MatchCount(out value: SYSINT): HResult; stdcall; + /// + /// Adds an event handler for the `ActiveMatchIndexChanged` event. + /// Registers an event handler for the ActiveMatchIndexChanged event. This event is raised when the index of the currently active match changes. + /// This can happen when the user navigates to a different match or when the active match is changed programmatically. + /// The parameter is the event handler to be added. Returns a token representing the added event handler. + /// This token can be used to unregister the event handler. + /// + function add_ActiveMatchIndexChanged(const eventHandler: ICoreWebView2FindActiveMatchIndexChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_ActiveMatchIndexChanged`. + /// + function remove_ActiveMatchIndexChanged(token: EventRegistrationToken): HResult; stdcall; + /// + /// Adds an event handler for the `MatchCountChanged` event. + /// Registers an event handler for the MatchCountChanged event. + /// This event is raised when the total count of matches in the document changes due to a new find session or changes in the document. + /// The parameter is the event handler to be added. Returns a token representing the added event handler. This token can be used to unregister the event handler. + /// + function add_MatchCountChanged(const eventHandler: ICoreWebView2FindMatchCountChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_MatchCountChanged`. + /// + function remove_MatchCountChanged(token: EventRegistrationToken): HResult; stdcall; + /// + /// Initiates a find using the specified find options asynchronously. + /// Displays the Find bar and starts the find session. If a find session was already ongoing, it will be stopped and replaced with this new instance. + /// If called with an empty string, the Find bar is displayed but no finding occurs. Changing the FindOptions object after initiation won't affect the ongoing find session. + /// To change the ongoing find session, Start must be called again with a new or modified FindOptions object. + /// Start supports HTML and TXT document queries. In general, this API is designed for text-based find sessions. + /// If you start a find session programmatically on another file format that doesn't have text fields, the find session will try to execute but will fail to find any matches. (It will silently fail) + /// Note: The asynchronous action completes when the UI has been displayed with the find term in the UI bar, and the matches have populated on the counter on the find bar. + /// There may be a slight latency between the UI display and the matches populating in the counter. + /// The MatchCountChanged and ActiveMatchIndexChanged events are only raised after Start has completed; otherwise, they will have their default values (-1 for active match index and 0 for match count). + /// To start a new find session (beginning the search from the first match), call `Stop` before invoking `Start`. + /// If `Start` is called consecutively with the same options and without calling `Stop`, the find session + /// will continue from the current position in the existing session. + /// Calling `Start` without altering its parameters will behave either as `FindNext` or `FindPrevious`, depending on the most recent search action performed. + /// Start will default to forward if neither have been called. + /// However, calling Start again during an ongoing find session does not resume from the point + /// of the current active match. For example, given the text "1 1 A 1 1" and initiating a find session for "A", + /// then starting another find session for "1", it will start searching from the beginning of the document, + /// regardless of the previous active match. This behavior indicates that changing the find query initiates a + /// completely new find session, rather than continuing from the previous match index. + /// + /// \snippet AppWindow.cpp Start + /// + function Start(const options: ICoreWebView2FindOptions; + const handler: ICoreWebView2FindStartCompletedHandler): HResult; stdcall; + /// + /// Navigates to the next match in the document. + /// If there are no matches to find, FindNext will wrap around to the first match's index. + /// If called when there is no find session active, FindNext will silently fail. + /// + /// \snippet AppWindow.cpp FindNext + /// + function FindNext: HResult; stdcall; + /// + /// Navigates to the previous match in the document. + /// If there are no matches to find, FindPrevious will wrap around to the last match's index. + /// If called when there is no find session active, FindPrevious will silently fail. + /// + /// \snippet AppWindow.cpp FindPrevious + /// + function FindPrevious: HResult; stdcall; + /// + /// Stops the current 'Find' session and hides the Find bar. + /// If called with no Find session active, it will silently do nothing. + /// + /// \snippet AppWindow.cpp Stop + /// + function Stop: HResult; stdcall; + end; + + /// + /// Receives `ActiveMatchIndexChanged` events. + /// + /// + /// See the ICoreWebView2FindActiveMatchIndexChangedEventHandler article. + /// + ICoreWebView2FindActiveMatchIndexChangedEventHandler = interface(IUnknown) + ['{0054F514-9A8E-5876-AED5-30B37F8C86A5}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Find; const args: IUnknown): HResult; stdcall; + end; + + /// + /// Receives `MatchCountChanged` events. + /// + /// + /// See the ICoreWebView2FindMatchCountChangedEventHandler article. + /// + ICoreWebView2FindMatchCountChangedEventHandler = interface(IUnknown) + ['{DA0D6827-4254-5B10-A6D9-412076AFC9F3}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Find; const args: IUnknown): HResult; stdcall; + end; + + /// + /// Interface defining the find options. + /// This interface provides the necessary methods and properties to configure a find session. + /// + /// + /// See the ICoreWebView2FindOptions article. + /// + ICoreWebView2FindOptions = interface(IUnknown) + ['{E82E3B2B-A4AF-5BC6-94C6-18B44157A16C}'] + /// + /// Gets the `FindTerm` property. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_FindTerm(out value: PWideChar): HResult; stdcall; + /// + /// Gets or sets the word or phrase to be searched in the current page. + /// You can set `FindTerm` to any text you want to find on the page. + /// This will take effect the next time you call the `Start()` method. + /// + /// \snippet AppWindow.cpp FindTerm + /// + function Set_FindTerm(value: PWideChar): HResult; stdcall; + /// + /// Gets the `IsCaseSensitive` property. + /// + function Get_IsCaseSensitive(out value: Integer): HResult; stdcall; + /// + /// Determines if the find session is case sensitive. Returns TRUE if the find is case sensitive, FALSE otherwise. + /// When toggling case sensitivity, the behavior can vary by locale, which may be influenced by both the browser's UI locale and the document's language settings. The browser's UI locale + /// typically provides a default handling approach, while the document's language settings (e.g., specified using the HTML lang attribute) can override these defaults to apply locale-specific rules. This dual consideration + /// ensures that text is processed in a manner consistent with user expectations and the linguistic context of the content. + /// + /// \snippet AppWindow.cpp IsCaseSensitive + /// + function Set_IsCaseSensitive(value: Integer): HResult; stdcall; + /// + /// Gets the `ShouldHighlightAllMatches` property. + /// + function Get_ShouldHighlightAllMatches(out value: Integer): HResult; stdcall; + /// + /// Gets or sets the state of whether all matches are highlighted. + /// Returns TRUE if all matches are highlighted, FALSE otherwise. + /// Note: Changes to this property take effect only when Start, FindNext, or FindPrevious is called. + /// Preferences for the session cannot be updated unless another call to the Start function on the server-side is made. + /// Therefore, changes will not take effect until one of these functions is called. + /// + /// \snippet AppWindow.cpp ShouldHighlightAllMatches + /// + function Set_ShouldHighlightAllMatches(value: Integer): HResult; stdcall; + /// + /// Gets the `ShouldMatchWord` property. + /// + function Get_ShouldMatchWord(out value: Integer): HResult; stdcall; + /// + /// Similar to case sensitivity, word matching also can vary by locale, which may be influenced by both the browser's UI locale and the document's language settings. The browser's UI locale + /// typically provides a default handling approach, while the document's language settings (e.g., specified using the HTML lang attribute) can override these defaults to apply locale-specific rules. This dual consideration + /// ensures that text is processed in a manner consistent with user expectations and the linguistic context of the content. + /// ShouldMatchWord determines if only whole words should be matched during the find session. Returns TRUE if only whole words should be matched, FALSE otherwise. + /// + /// \snippet AppWindow.cpp ShouldMatchWord + /// + function Set_ShouldMatchWord(value: Integer): HResult; stdcall; + /// + /// Gets the `SuppressDefaultFindDialog` property. + /// + function Get_SuppressDefaultFindDialog(out value: Integer): HResult; stdcall; + /// + /// Sets this property to hide the default Find UI. + /// You can use this to hide the default UI so that you can show your own custom UI or programmatically interact with the Find API while showing no Find UI. + /// Returns TRUE if hiding the default Find UI and FALSE if using showing the default Find UI. + /// Note: Changes to this property take effect only when Start, FindNext, or FindPrevious is called. + /// Preferences for the session cannot be updated unless another call to the Start function on the server-side is made. + /// Therefore, changes will not take effect until one of these functions is called. + /// + /// \snippet AppWindow.cpp SuppressDefaultFindDialog + /// + function Set_SuppressDefaultFindDialog(value: Integer): HResult; stdcall; + end; + + /// + /// Receives the result of the `Start` method. + /// + /// + /// See the ICoreWebView2FindStartCompletedHandler article. + /// + ICoreWebView2FindStartCompletedHandler = interface(IUnknown) + ['{6A90ECAF-44B0-5BD9-8F07-1967E17BE9FB}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2 interface to manage dedicated + /// workers. + /// + /// + /// See the ICoreWebView2_29 article. + /// + ICoreWebView2_29 = interface(ICoreWebView2_28) + ['{650F917E-CC16-5C8C-9287-B0BBC8A4AB2C}'] + /// + /// Adds an event handler for the `DedicatedWorkerCreated` event. + /// Subscribe to this event that gets raised when a new dedicated worker is created. + /// + /// A Dedicated Worker is a type of web worker that allows you to run Javascript + /// code in the background without blocking the main thread, making them useful + /// for tasks like heavy computations, data processing, and parallel execution. + /// It is "dedicated" because it is linked to a single parent document and cannot + /// be shared with other scripts. + /// + /// This event is raised when a web application creates a dedicated worker using the + /// `new Worker("/worker.js")` method. See the + /// [Worker](https://developer.mozilla.org/docs/Web/API/Worker/Worker) + /// for more information. + /// + /// + /// \snippet ScenarioDedicatedWorker.cpp DedicatedWorkerCreated + /// + function add_DedicatedWorkerCreated(const eventHandler: ICoreWebView2DedicatedWorkerCreatedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_DedicatedWorkerCreated`. + /// + function remove_DedicatedWorkerCreated(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives `DedicatedWorkerCreated` events. + /// + /// + /// See the ICoreWebView2DedicatedWorkerCreatedEventHandler article. + /// + ICoreWebView2DedicatedWorkerCreatedEventHandler = interface(IUnknown) + ['{CBA7462C-52C1-5706-8BBC-E9FC36476DE4}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2; + const args: ICoreWebView2DedicatedWorkerCreatedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the `DedicatedWorkerCreated` event. + /// + /// + /// See the ICoreWebView2DedicatedWorkerCreatedEventArgs article. + /// + ICoreWebView2DedicatedWorkerCreatedEventArgs = interface(IUnknown) + ['{910C52AF-8129-516D-AB9A-B524E377D8AC}'] + /// + /// The associated frame information that created the dedicated worker. + /// This can be used to get the frame source, name, frameId, + /// and parent frame information. + /// + function Get_OriginalSourceFrameInfo(out value: ICoreWebView2FrameInfo): HResult; stdcall; + /// + /// The dedicated worker that was created. + /// + function Get_Worker(out value: ICoreWebView2DedicatedWorker): HResult; stdcall; + end; + + /// + /// This interface represents a dedicated worker in WebView2 and provides methods + /// and properties for interacting with it, such as getting the script uri, + /// posting messages, managing events related to the creation of child workers, + /// termination etc. + /// + /// + /// See the ICoreWebView2DedicatedWorker article. + /// + ICoreWebView2DedicatedWorker = interface(IUnknown) + ['{66833876-EDBA-5A60-8508-7DA64504A9D2}'] + /// + /// A string representing the Uri of the script that the worker is executing. + /// + /// The `scriptUri` is a fully qualified URI, including the scheme, host, and path. + /// In contrast, the `scriptURL` property of the `Worker` object in the DOM returns the relative + /// URL of the script being executed by the worker. For more details on DOM API, see the + /// [DOM API documentation](https://developer.mozilla.org/docs/Web/API/Worker/scriptURL). + /// + /// Refer to the Host Name Canonicalization for + /// details on how normalization is performed. + /// The same process applies to the `scriptURL` when a worker is created from DOM API. + /// The `scriptUri` property reflects this normalization, ensuring that the URL is standardized. For example, + /// `HTTPS://EXAMPLE.COM/worker.js` is canonicalized to `https://example.com/worker.js`; + /// `https://bücher.de/worker.js` is canonicalized to `https://xn--bcher-kva.de/worker.js`. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_ScriptUri(out value: PWideChar): HResult; stdcall; + /// + /// Adds an event handler for the `DedicatedWorkerCreated` event. + /// Subscribe to this event that gets raised when a new dedicated worker is created from a + /// dedicated worker. + /// + /// A Dedicated Worker is a type of web worker that allows you to run Javascript + /// code in the background without blocking the main thread, making them useful + /// for tasks like heavy computations, data processing, and parallel execution. + /// It is "dedicated" because it is linked to a single parent document and cannot + /// be shared with other scripts. + /// + /// This event is raised when a dedicated creates a dedicated worker using the + /// `new Worker("/worker.js")` method. See the + /// [Worker](https://developer.mozilla.org/docs/Web/API/Worker/Worker) + /// for more information. + /// + function add_DedicatedWorkerCreated(const eventHandler: ICoreWebView2DedicatedWorkerDedicatedWorkerCreatedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_DedicatedWorkerCreated`. + /// + function remove_DedicatedWorkerCreated(token: EventRegistrationToken): HResult; stdcall; + /// + /// Adds an event handler for the `Destroying` event. + /// Add an event handler for the `Destroying` event that is raised when the + /// worker object is Destroying. + /// + /// A worker object is Destroying when the worker script is terminated or when + /// the `CoreWebView2DedicatedWorker` object is Destroying. + /// + /// If the worker has already been destroyed before the event handler is registered, + /// the handler will never be called. + /// + function add_Destroying(const eventHandler: ICoreWebView2DedicatedWorkerDestroyingEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_Destroying`. + /// + function remove_Destroying(token: EventRegistrationToken): HResult; stdcall; + /// + /// Adds an event handler for the `WebMessageReceived` event. + /// Add an event handler for the `WebMessageReceived` event. + /// `WebMessageReceived` is fired, when the + /// `ICoreWebView2Settings::IsWebMessageEnabled` setting is set TRUE and the + /// worker runs `self.chrome.webview.postMessage`. The `postMessage` function + /// is `void postMessage(object)` where object is any object supported by JSON + /// conversion. + /// + /// If the worker calls `postMessage` multiple times, the corresponding + /// `WebMessageReceived` events are guaranteed to be fired in the same order. + /// + /// + /// \snippet ScenarioDedicatedWorkerPostMessage.cpp WebMessageReceived + /// + function add_WebMessageReceived(const eventHandler: ICoreWebView2DedicatedWorkerWebMessageReceivedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_WebMessageReceived`. + /// + function remove_WebMessageReceived(token: EventRegistrationToken): HResult; stdcall; + /// + /// Posts the specified webMessageAsJson to this worker. + /// The worker receives the message by subscribing to the `message` event of the + /// `self.chrome.webview` of the worker. + /// + /// ```cpp + /// self.chrome.webview.addEventListener('message', handler) + /// self.chrome.webview.removeEventListener('message', handler) + /// ``` + /// + /// The event args is an instance of `MessageEvent`. The + /// `ICoreWebView2Settings::IsWebMessageEnabled` setting must be `TRUE` or + /// the web message will not be sent. The `data` property of the event arg + /// is the `webMessageAsJson` string parameter parsed as a JSON string into a + /// JS object. The `source` property of the event arg is the path + /// to the worker script. The message is delivered asynchronously. + /// If the worker is terminated or destroyed before the message is posted, + /// the message is discarded. + /// Worker Javascript may subscribe and unsubscribe to the event + /// using the following code: + /// ```javascript + /// self.chrome.webview.addEventListener('message', handler) + /// self.chrome.webview.removeEventListener('message', handler) + /// ``` + /// ```cpp + /// See also the equivalent methods: `ICoreWebView2::PostWebMessageAsJson`, + /// `ICoreWebView2Frame::PostWebMessageAsJson`, + /// `ICoreWebView2ServiceWorker::PostWebMessageAsJson`. + /// ``` + /// + /// + /// \snippet ScenarioDedicatedWorkerPostMessage.cpp PostWebMessageAsJson + /// + function PostWebMessageAsJson(webMessageAsJson: PWideChar): HResult; stdcall; + /// + /// Posts a message that is a simple string rather than a JSON string + /// representation of a JavaScript object. This behaves exactly the same + /// manner as `PostWebMessageAsJson`, but the `data` property of the event + /// arg of the `self.chrome.webview` message is a string with the same + /// value as `webMessageAsString`. Use this instead of + /// `PostWebMessageAsJson` if you want to communicate using simple strings + /// rather than JSON objects. Please see `PostWebMessageAsJson` for + /// additional information. + /// ```cpp + /// See also the equivalent methods: `ICoreWebView2::PostWebMessageAsString`, + /// `ICoreWebView2Frame::PostWebMessageAsString`, + /// `ICoreWebView2ServiceWorker::PostWebMessageAsString`. + /// ``` + /// + function PostWebMessageAsString(webMessageAsString: PWideChar): HResult; stdcall; + end; + + /// + /// Receives `DedicatedWorkerCreated` events. + /// + /// + /// See the ICoreWebView2DedicatedWorkerDedicatedWorkerCreatedEventHandler article. + /// + ICoreWebView2DedicatedWorkerDedicatedWorkerCreatedEventHandler = interface(IUnknown) + ['{A85B1B35-F6D7-5AE6-9FD7-57905DEFF79F}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2DedicatedWorker; + const args: ICoreWebView2DedicatedWorkerCreatedEventArgs): HResult; stdcall; + end; + + /// + /// Receives `Destroying` events. + /// + /// + /// See the ICoreWebView2DedicatedWorkerDestroyingEventHandler article. + /// + ICoreWebView2DedicatedWorkerDestroyingEventHandler = interface(IUnknown) + ['{72473D5F-CBA2-57CA-A42E-03610A349FEF}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2DedicatedWorker; const args: IUnknown): HResult; stdcall; + end; + + /// + /// Receives `WebMessageReceived` events. + /// + /// + /// See the ICoreWebView2DedicatedWorkerWebMessageReceivedEventHandler article. + /// + ICoreWebView2DedicatedWorkerWebMessageReceivedEventHandler = interface(IUnknown) + ['{B366218B-0BB8-58A3-AC33-F40A2235366E}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2DedicatedWorker; + const args: ICoreWebView2WebMessageReceivedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the BrowserProcessExited event. + /// + /// + /// See the ICoreWebView2BrowserProcessExitedEventArgs article. + /// + ICoreWebView2BrowserProcessExitedEventArgs = interface(IUnknown) + ['{1F00663F-AF8C-4782-9CDD-DD01C52E34CB}'] + /// + /// The kind of browser process exit that has occurred. + /// + function Get_BrowserProcessExitKind(out value: COREWEBVIEW2_BROWSER_PROCESS_EXIT_KIND): HResult; stdcall; + /// + /// The process ID of the browser process that has exited. + /// + function Get_BrowserProcessId(out value: SYSUINT): HResult; stdcall; + end; + + /// + /// Receives BrowserProcessExited events. + /// + /// + /// See the ICoreWebView2BrowserProcessExitedEventHandler article. + /// + ICoreWebView2BrowserProcessExitedEventHandler = interface(IUnknown) + ['{FA504257-A216-4911-A860-FE8825712861}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Environment; + const args: ICoreWebView2BrowserProcessExitedEventArgs): HResult; stdcall; + end; + + /// + /// This interface is an extension of the ICoreWebView2Controller interface to + /// support visual hosting. An object implementing the + /// ICoreWebView2CompositionController interface will also implement + /// ICoreWebView2Controller. Callers are expected to use + /// ICoreWebView2Controller for resizing, visibility, focus, and so on, and + /// then use ICoreWebView2CompositionController to connect to a composition + /// tree and provide input meant for the WebView. + /// + /// + /// See the ICoreWebView2CompositionController article. + /// + ICoreWebView2CompositionController = interface(IUnknown) + ['{3DF9B733-B9AE-4A15-86B4-EB9EE9826469}'] + /// + /// The RootVisualTarget is a visual in the hosting app's visual tree. This + /// visual is where the WebView will connect its visual tree. The app uses + /// this visual to position the WebView within the app. The app still needs + /// to use the Bounds property to size the WebView. The RootVisualTarget + /// property can be an IDCompositionVisual or a + /// Windows::UI::Composition::ContainerVisual. WebView will connect its visual + /// tree to the provided visual before returning from the property setter. The + /// app needs to commit on its device setting the RootVisualTarget property. + /// The RootVisualTarget property supports being set to nullptr to disconnect + /// the WebView from the app's visual tree. + /// \snippet ViewComponent.cpp SetRootVisualTarget + /// \snippet ViewComponent.cpp BuildDCompTree + /// + function Get_RootVisualTarget(out target: IUnknown): HResult; stdcall; + /// + /// Set the RootVisualTarget property. + /// + function Set_RootVisualTarget(const target: IUnknown): HResult; stdcall; + /// + /// If eventKind is COREWEBVIEW2_MOUSE_EVENT_KIND_HORIZONTAL_WHEEL or + /// COREWEBVIEW2_MOUSE_EVENT_KIND_WHEEL, then mouseData specifies the amount of + /// wheel movement. A positive value indicates that the wheel was rotated + /// forward, away from the user; a negative value indicates that the wheel was + /// rotated backward, toward the user. One wheel click is defined as + /// WHEEL_DELTA, which is 120. + /// If eventKind is COREWEBVIEW2_MOUSE_EVENT_KIND_X_BUTTON_DOUBLE_CLICK + /// COREWEBVIEW2_MOUSE_EVENT_KIND_X_BUTTON_DOWN, or + /// COREWEBVIEW2_MOUSE_EVENT_KIND_X_BUTTON_UP, then mouseData specifies which X + /// buttons were pressed or released. This value should be 1 if the first X + /// button is pressed/released and 2 if the second X button is + /// pressed/released. + /// If eventKind is COREWEBVIEW2_MOUSE_EVENT_KIND_LEAVE, then virtualKeys, + /// mouseData, and point should all be zero. + /// If eventKind is any other value, then mouseData should be zero. + /// Point is expected to be in the client coordinate space of the WebView. + /// To track mouse events that start in the WebView and can potentially move + /// outside of the WebView and host application, calling SetCapture and + /// ReleaseCapture is recommended. + /// To dismiss hover popups, it is also recommended to send + /// COREWEBVIEW2_MOUSE_EVENT_KIND_LEAVE messages. + /// \snippet ViewComponent.cpp SendMouseInput + /// + function SendMouseInput(eventKind: COREWEBVIEW2_MOUSE_EVENT_KIND; + virtualKeys: COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS; mouseData: SYSUINT; + point: tagPOINT): HResult; stdcall; + /// + /// SendPointerInput accepts touch or pen pointer input of types defined in + /// COREWEBVIEW2_POINTER_EVENT_KIND. Any pointer input from the system must be + /// converted into an ICoreWebView2PointerInfo first. + /// + function SendPointerInput(eventKind: COREWEBVIEW2_POINTER_EVENT_KIND; + const pointerInfo: ICoreWebView2PointerInfo): HResult; stdcall; + /// + /// The current cursor that WebView thinks it should be. The cursor should be + /// set in WM_SETCURSOR through \::SetCursor or set on the corresponding + /// parent/ancestor HWND of the WebView through \::SetClassLongPtr. The HCURSOR + /// can be freed so CopyCursor/DestroyCursor is recommended to keep your own + /// copy if you are doing more than immediately setting the cursor. + /// + {* function Get_Cursor(out Cursor: wireHICON): HResult; stdcall; wireHICON -> HCURSOR ************** WEBVIEW4DELPHI ************** *} + function Get_Cursor(out Cursor: HCURSOR): HResult; stdcall; + /// + /// The current system cursor ID reported by the underlying rendering engine + /// for WebView. For example, most of the time, when the cursor is over text, + /// this will return the int value for IDC_IBEAM. The systemCursorId is only + /// valid if the rendering engine reports a default Windows cursor resource + /// value. Navigate to + /// [LoadCursorW](/windows/win32/api/winuser/nf-winuser-loadcursorw) for more + /// details. Otherwise, if custom CSS cursors are being used, this will return + /// 0. To actually use systemCursorId in LoadCursor or LoadImage, + /// MAKEINTRESOURCE must be called on it first. + /// + /// \snippet ViewComponent.cpp SystemCursorId + /// + function Get_SystemCursorId(out SystemCursorId: SYSUINT): HResult; stdcall; + /// + /// Add an event handler for the CursorChanged event. + /// The event is raised when WebView thinks the cursor should be changed. For + /// example, when the mouse cursor is currently the default cursor but is then + /// moved over text, it may try to change to the IBeam cursor. + /// + /// It is expected for the developer to send + /// COREWEBVIEW2_MOUSE_EVENT_KIND_LEAVE messages (in addition to + /// COREWEBVIEW2_MOUSE_EVENT_KIND_MOVE messages) through the SendMouseInput + /// API. This is to ensure that the mouse is actually within the WebView that + /// sends out CursorChanged events. + /// + /// \snippet ViewComponent.cpp CursorChanged + /// + function add_CursorChanged(const eventHandler: ICoreWebView2CursorChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with add_CursorChanged. + /// + function remove_CursorChanged(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// This mostly represents a combined win32 + /// POINTER_INFO/POINTER_TOUCH_INFO/POINTER_PEN_INFO object. It takes fields + /// from all three and excludes some win32 specific data types like HWND and + /// HANDLE. Note, sourceDevice is taken out but we expect the PointerDeviceRect + /// and DisplayRect to cover the existing use cases of sourceDevice. + /// Another big difference is that any of the point or rect locations are + /// expected to be in WebView physical coordinates. That is, coordinates + /// relative to the WebView and no DPI scaling applied. + /// The PointerId, PointerFlags, ButtonChangeKind, PenFlags, PenMask, TouchFlags, + /// and TouchMask are all #defined flags or enums in the + /// POINTER_INFO/POINTER_TOUCH_INFO/POINTER_PEN_INFO structure. We define those + /// properties here as UINT32 or INT32 and expect the developer to know how to + /// populate those values based on the Windows definitions. + /// + /// + /// See the ICoreWebView2PointerInfo article. + /// + ICoreWebView2PointerInfo = interface(IUnknown) + ['{E6995887-D10D-4F5D-9359-4CE46E4F96B9}'] + /// + /// Get the PointerKind of the pointer event. This corresponds to the + /// pointerKind property of the POINTER_INFO struct. The values are defined by + /// the POINTER_INPUT_KIND enum in the Windows SDK (winuser.h). Supports + /// PT_PEN and PT_TOUCH. + /// + function Get_PointerKind(out PointerKind: LongWord): HResult; stdcall; + /// + /// Set the PointerKind of the pointer event. This corresponds to the + /// pointerKind property of the POINTER_INFO struct. The values are defined by + /// the POINTER_INPUT_KIND enum in the Windows SDK (winuser.h). Supports + /// PT_PEN and PT_TOUCH. + /// + function Set_PointerKind(PointerKind: LongWord): HResult; stdcall; + /// + /// Get the PointerId of the pointer event. This corresponds to the pointerId + /// property of the POINTER_INFO struct as defined in the Windows SDK + /// (winuser.h). + /// + function Get_PointerId(out PointerId: SYSUINT): HResult; stdcall; + /// + /// Set the PointerId of the pointer event. This corresponds to the pointerId + /// property of the POINTER_INFO struct as defined in the Windows SDK + /// (winuser.h). + /// + function Set_PointerId(PointerId: SYSUINT): HResult; stdcall; + /// + /// Get the FrameID of the pointer event. This corresponds to the frameId + /// property of the POINTER_INFO struct as defined in the Windows SDK + /// (winuser.h). + /// + function Get_FrameId(out FrameId: SYSUINT): HResult; stdcall; + /// + /// Set the FrameID of the pointer event. This corresponds to the frameId + /// property of the POINTER_INFO struct as defined in the Windows SDK + /// (winuser.h). + /// + function Set_FrameId(FrameId: SYSUINT): HResult; stdcall; + /// + /// Get the PointerFlags of the pointer event. This corresponds to the + /// pointerFlags property of the POINTER_INFO struct. The values are defined + /// by the POINTER_FLAGS constants in the Windows SDK (winuser.h). + /// + function Get_PointerFlags(out PointerFlags: SYSUINT): HResult; stdcall; + /// + /// Set the PointerFlags of the pointer event. This corresponds to the + /// pointerFlags property of the POINTER_INFO struct. The values are defined + /// by the POINTER_FLAGS constants in the Windows SDK (winuser.h). + /// + function Set_PointerFlags(PointerFlags: SYSUINT): HResult; stdcall; + /// + /// Get the PointerDeviceRect of the sourceDevice property of the + /// POINTER_INFO struct as defined in the Windows SDK (winuser.h). + /// + function Get_PointerDeviceRect(out PointerDeviceRect: tagRECT): HResult; stdcall; + /// + /// Set the PointerDeviceRect of the sourceDevice property of the + /// POINTER_INFO struct as defined in the Windows SDK (winuser.h). + /// + function Set_PointerDeviceRect(PointerDeviceRect: tagRECT): HResult; stdcall; + /// + /// Get the DisplayRect of the sourceDevice property of the POINTER_INFO + /// struct as defined in the Windows SDK (winuser.h). + /// + function Get_DisplayRect(out DisplayRect: tagRECT): HResult; stdcall; + /// + /// Set the DisplayRect of the sourceDevice property of the POINTER_INFO + /// struct as defined in the Windows SDK (winuser.h). + /// + function Set_DisplayRect(DisplayRect: tagRECT): HResult; stdcall; + /// + /// Get the PixelLocation of the pointer event. This corresponds to the + /// ptPixelLocation property of the POINTER_INFO struct as defined in the + /// Windows SDK (winuser.h). + /// + function Get_PixelLocation(out PixelLocation: tagPOINT): HResult; stdcall; + /// + /// Set the PixelLocation of the pointer event. This corresponds to the + /// ptPixelLocation property of the POINTER_INFO struct as defined in the + /// Windows SDK (winuser.h). + /// + function Set_PixelLocation(PixelLocation: tagPOINT): HResult; stdcall; + /// + /// Get the HimetricLocation of the pointer event. This corresponds to the + /// ptHimetricLocation property of the POINTER_INFO struct as defined in the + /// Windows SDK (winuser.h). + /// + function Get_HimetricLocation(out HimetricLocation: tagPOINT): HResult; stdcall; + /// + /// Set the HimetricLocation of the pointer event. This corresponds to the + /// ptHimetricLocation property of the POINTER_INFO struct as defined in the + /// Windows SDK (winuser.h). + /// + function Set_HimetricLocation(HimetricLocation: tagPOINT): HResult; stdcall; + /// + /// Get the PixelLocationRaw of the pointer event. This corresponds to the + /// ptPixelLocationRaw property of the POINTER_INFO struct as defined in the + /// Windows SDK (winuser.h). + /// + function Get_PixelLocationRaw(out PixelLocationRaw: tagPOINT): HResult; stdcall; + /// + /// Set the PixelLocationRaw of the pointer event. This corresponds to the + /// ptPixelLocationRaw property of the POINTER_INFO struct as defined in the + /// Windows SDK (winuser.h). + /// + function Set_PixelLocationRaw(PixelLocationRaw: tagPOINT): HResult; stdcall; + /// + /// Get the HimetricLocationRaw of the pointer event. This corresponds to the + /// ptHimetricLocationRaw property of the POINTER_INFO struct as defined in + /// the Windows SDK (winuser.h). + /// + function Get_HimetricLocationRaw(out HimetricLocationRaw: tagPOINT): HResult; stdcall; + /// + /// Set the HimetricLocationRaw of the pointer event. This corresponds to the + /// ptHimetricLocationRaw property of the POINTER_INFO struct as defined in + /// the Windows SDK (winuser.h). + /// + function Set_HimetricLocationRaw(HimetricLocationRaw: tagPOINT): HResult; stdcall; + /// + /// Get the Time of the pointer event. This corresponds to the dwTime property + /// of the POINTER_INFO struct as defined in the Windows SDK (winuser.h). + /// + function Get_Time(out Time: LongWord): HResult; stdcall; + /// + /// Set the Time of the pointer event. This corresponds to the dwTime property + /// of the POINTER_INFO struct as defined in the Windows SDK (winuser.h). + /// + function Set_Time(Time: LongWord): HResult; stdcall; + /// + /// Get the HistoryCount of the pointer event. This corresponds to the + /// historyCount property of the POINTER_INFO struct as defined in the Windows + /// SDK (winuser.h). + /// + function Get_HistoryCount(out HistoryCount: SYSUINT): HResult; stdcall; + /// + /// Set the HistoryCount of the pointer event. This corresponds to the + /// historyCount property of the POINTER_INFO struct as defined in the Windows + /// SDK (winuser.h). + /// + function Set_HistoryCount(HistoryCount: SYSUINT): HResult; stdcall; + /// + /// Get the InputData of the pointer event. This corresponds to the InputData + /// property of the POINTER_INFO struct as defined in the Windows SDK + /// (winuser.h). + /// + function Get_InputData(out InputData: SYSINT): HResult; stdcall; + /// + /// Set the InputData of the pointer event. This corresponds to the InputData + /// property of the POINTER_INFO struct as defined in the Windows SDK + /// (winuser.h). + /// + function Set_InputData(InputData: SYSINT): HResult; stdcall; + /// + /// Get the KeyStates of the pointer event. This corresponds to the + /// dwKeyStates property of the POINTER_INFO struct as defined in the Windows + /// SDK (winuser.h). + /// + function Get_KeyStates(out KeyStates: LongWord): HResult; stdcall; + /// + /// Set the KeyStates of the pointer event. This corresponds to the + /// dwKeyStates property of the POINTER_INFO struct as defined in the Windows + /// SDK (winuser.h). + /// + function Set_KeyStates(KeyStates: LongWord): HResult; stdcall; + /// + /// Get the PerformanceCount of the pointer event. This corresponds to the + /// PerformanceCount property of the POINTER_INFO struct as defined in the + /// Windows SDK (winuser.h). + /// + function Get_PerformanceCount(out PerformanceCount: Largeuint): HResult; stdcall; + /// + /// Set the PerformanceCount of the pointer event. This corresponds to the + /// PerformanceCount property of the POINTER_INFO struct as defined in the + /// Windows SDK (winuser.h). + /// + function Set_PerformanceCount(PerformanceCount: Largeuint): HResult; stdcall; + /// + /// Get the ButtonChangeKind of the pointer event. This corresponds to the + /// ButtonChangeKind property of the POINTER_INFO struct. The values are + /// defined by the POINTER_BUTTON_CHANGE_KIND enum in the Windows SDK + /// (winuser.h). + /// + function Get_ButtonChangeKind(out ButtonChangeKind: SYSINT): HResult; stdcall; + /// + /// Set the ButtonChangeKind of the pointer event. This corresponds to the + /// ButtonChangeKind property of the POINTER_INFO struct. The values are + /// defined by the POINTER_BUTTON_CHANGE_KIND enum in the Windows SDK + /// (winuser.h). + /// + function Set_ButtonChangeKind(ButtonChangeKind: SYSINT): HResult; stdcall; + /// + /// Get the PenFlags of the pointer event. This corresponds to the penFlags + /// property of the POINTER_PEN_INFO struct. The values are defined by the + /// PEN_FLAGS constants in the Windows SDK (winuser.h). + /// + /// + /// This is a Pen specific attribute. + /// + function Get_PenFlags(out PenFlags: SYSUINT): HResult; stdcall; + /// + /// Set the PenFlags of the pointer event. This corresponds to the penFlags + /// property of the POINTER_PEN_INFO struct. The values are defined by the + /// PEN_FLAGS constants in the Windows SDK (winuser.h). + /// + /// + /// This is a Pen specific attribute. + /// + function Set_PenFlags(PenFlags: SYSUINT): HResult; stdcall; + /// + /// Get the PenMask of the pointer event. This corresponds to the penMask + /// property of the POINTER_PEN_INFO struct. The values are defined by the + /// PEN_MASK constants in the Windows SDK (winuser.h). + /// + /// + /// This is a Pen specific attribute. + /// + function Get_PenMask(out PenMask: SYSUINT): HResult; stdcall; + /// + /// Set the PenMask of the pointer event. This corresponds to the penMask + /// property of the POINTER_PEN_INFO struct. The values are defined by the + /// PEN_MASK constants in the Windows SDK (winuser.h). + /// + /// + /// This is a Pen specific attribute. + /// + function Set_PenMask(PenMask: SYSUINT): HResult; stdcall; + /// + /// Get the PenPressure of the pointer event. This corresponds to the pressure + /// property of the POINTER_PEN_INFO struct as defined in the Windows SDK + /// (winuser.h). + /// + /// + /// This is a Pen specific attribute. + /// + function Get_PenPressure(out PenPressure: SYSUINT): HResult; stdcall; + /// + /// Set the PenPressure of the pointer event. This corresponds to the pressure + /// property of the POINTER_PEN_INFO struct as defined in the Windows SDK + /// (winuser.h). + /// + /// + /// This is a Pen specific attribute. + /// + function Set_PenPressure(PenPressure: SYSUINT): HResult; stdcall; + /// + /// Get the PenRotation of the pointer event. This corresponds to the rotation + /// property of the POINTER_PEN_INFO struct as defined in the Windows SDK + /// (winuser.h). + /// + /// + /// This is a Pen specific attribute. + /// + function Get_PenRotation(out PenRotation: SYSUINT): HResult; stdcall; + /// + /// Set the PenRotation of the pointer event. This corresponds to the rotation + /// property of the POINTER_PEN_INFO struct as defined in the Windows SDK + /// (winuser.h). + /// + /// + /// This is a Pen specific attribute. + /// + function Set_PenRotation(PenRotation: SYSUINT): HResult; stdcall; + /// + /// Get the PenTiltX of the pointer event. This corresponds to the tiltX + /// property of the POINTER_PEN_INFO struct as defined in the Windows SDK + /// (winuser.h). + /// + /// + /// This is a Pen specific attribute. + /// + function Get_PenTiltX(out PenTiltX: SYSINT): HResult; stdcall; + /// + /// Set the PenTiltX of the pointer event. This corresponds to the tiltX + /// property of the POINTER_PEN_INFO struct as defined in the Windows SDK + /// (winuser.h). + /// + /// + /// This is a Pen specific attribute. + /// + function Set_PenTiltX(PenTiltX: SYSINT): HResult; stdcall; + /// + /// Get the PenTiltY of the pointer event. This corresponds to the tiltY + /// property of the POINTER_PEN_INFO struct as defined in the Windows SDK + /// (winuser.h). + /// + /// + /// This is a Pen specific attribute. + /// + function Get_PenTiltY(out PenTiltY: SYSINT): HResult; stdcall; + /// + /// Set the PenTiltY of the pointer event. This corresponds to the tiltY + /// property of the POINTER_PEN_INFO struct as defined in the Windows SDK + /// (winuser.h). + /// + /// + /// This is a Pen specific attribute. + /// + function Set_PenTiltY(PenTiltY: SYSINT): HResult; stdcall; + /// + /// Get the TouchFlags of the pointer event. This corresponds to the + /// touchFlags property of the POINTER_TOUCH_INFO struct. The values are + /// defined by the TOUCH_FLAGS constants in the Windows SDK (winuser.h). + /// + /// + /// This is a Touch specific attribute. + /// + function Get_TouchFlags(out TouchFlags: SYSUINT): HResult; stdcall; + /// + /// Set the TouchFlags of the pointer event. This corresponds to the + /// touchFlags property of the POINTER_TOUCH_INFO struct. The values are + /// defined by the TOUCH_FLAGS constants in the Windows SDK (winuser.h). + /// + /// + /// This is a Touch specific attribute. + /// + function Set_TouchFlags(TouchFlags: SYSUINT): HResult; stdcall; + /// + /// Get the TouchMask of the pointer event. This corresponds to the + /// touchMask property of the POINTER_TOUCH_INFO struct. The values are + /// defined by the TOUCH_MASK constants in the Windows SDK (winuser.h). + /// + /// + /// This is a Touch specific attribute. + /// + function Get_TouchMask(out TouchMask: SYSUINT): HResult; stdcall; + /// + /// Set the TouchMask of the pointer event. This corresponds to the + /// touchMask property of the POINTER_TOUCH_INFO struct. The values are + /// defined by the TOUCH_MASK constants in the Windows SDK (winuser.h). + /// + /// + /// This is a Touch specific attribute. + /// + function Set_TouchMask(TouchMask: SYSUINT): HResult; stdcall; + /// + /// Get the TouchContact of the pointer event. This corresponds to the + /// rcContact property of the POINTER_TOUCH_INFO struct as defined in the + /// Windows SDK (winuser.h). + /// + /// + /// This is a Touch specific attribute. + /// + function Get_TouchContact(out TouchContact: tagRECT): HResult; stdcall; + /// + /// Set the TouchContact of the pointer event. This corresponds to the + /// rcContact property of the POINTER_TOUCH_INFO struct as defined in the + /// Windows SDK (winuser.h). + /// + /// + /// This is a Touch specific attribute. + /// + function Set_TouchContact(TouchContact: tagRECT): HResult; stdcall; + /// + /// Get the TouchContactRaw of the pointer event. This corresponds to the + /// rcContactRaw property of the POINTER_TOUCH_INFO struct as defined in the + /// Windows SDK (winuser.h). + /// + /// + /// This is a Touch specific attribute. + /// + function Get_TouchContactRaw(out TouchContactRaw: tagRECT): HResult; stdcall; + /// + /// Set the TouchContactRaw of the pointer event. This corresponds to the + /// rcContactRaw property of the POINTER_TOUCH_INFO struct as defined in the + /// Windows SDK (winuser.h). + /// + /// + /// This is a Touch specific attribute. + /// + function Set_TouchContactRaw(TouchContactRaw: tagRECT): HResult; stdcall; + /// + /// Get the TouchOrientation of the pointer event. This corresponds to the + /// orientation property of the POINTER_TOUCH_INFO struct as defined in the + /// Windows SDK (winuser.h). + /// + /// + /// This is a Touch specific attribute. + /// + function Get_TouchOrientation(out TouchOrientation: SYSUINT): HResult; stdcall; + /// + /// Set the TouchOrientation of the pointer event. This corresponds to the + /// orientation property of the POINTER_TOUCH_INFO struct as defined in the + /// Windows SDK (winuser.h). + /// + /// + /// This is a Touch specific attribute. + /// + function Set_TouchOrientation(TouchOrientation: SYSUINT): HResult; stdcall; + /// + /// Get the TouchPressure of the pointer event. This corresponds to the + /// pressure property of the POINTER_TOUCH_INFO struct as defined in the + /// Windows SDK (winuser.h). + /// + /// + /// This is a Touch specific attribute. + /// + function Get_TouchPressure(out TouchPressure: SYSUINT): HResult; stdcall; + /// + /// Set the TouchPressure of the pointer event. This corresponds to the + /// pressure property of the POINTER_TOUCH_INFO struct as defined in the + /// Windows SDK (winuser.h). + /// + /// + /// This is a Touch specific attribute. + /// + function Set_TouchPressure(TouchPressure: SYSUINT): HResult; stdcall; + end; + + /// + /// Receives `CursorChanged` events. + /// + /// + /// See the ICoreWebView2CursorChangedEventHandler article. + /// + ICoreWebView2CursorChangedEventHandler = interface(IUnknown) + ['{9DA43CCC-26E1-4DAD-B56C-D8961C94C571}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2CompositionController; const args: IUnknown): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2CompositionController interface. + /// + /// + /// See the ICoreWebView2CompositionController2 article. + /// + ICoreWebView2CompositionController2 = interface(ICoreWebView2CompositionController) + ['{0B6A3D24-49CB-4806-BA20-B5E0734A7B26}'] + /// + /// Returns the Automation Provider for the WebView. This object implements + /// IRawElementProviderSimple. + /// + function Get_AutomationProvider(out value: IUnknown): HResult; stdcall; + end; + + /// + /// This interface is the continuation of the + /// ICoreWebView2CompositionController2 interface to manage drag and drop. + /// + /// + /// See the ICoreWebView2CompositionController3 article. + /// + ICoreWebView2CompositionController3 = interface(ICoreWebView2CompositionController2) + ['{9570570E-4D76-4361-9EE1-F04D0DBDFB1E}'] + /// + /// This function corresponds to [IDropTarget::DragEnter](/windows/win32/api/oleidl/nf-oleidl-idroptarget-dragenter). + /// + /// This function has a dependency on AllowExternalDrop property of + /// CoreWebView2Controller and return E_FAIL to callers to indicate this + /// operation is not allowed if AllowExternalDrop property is set to false. + /// + /// The hosting application must register as an IDropTarget and implement + /// and forward DragEnter calls to this function. + /// + /// point parameter must be modified to include the WebView's offset and be in + /// the WebView's client coordinates (Similar to how SendMouseInput works). + /// + /// \snippet DropTarget.cpp DragEnter + /// + function DragEnter(const dataObject: IDataObject; keyState: LongWord; point: tagPOINT; + out effect: LongWord): HResult; stdcall; + /// + /// This function corresponds to [IDropTarget::DragLeave](/windows/win32/api/oleidl/nf-oleidl-idroptarget-dragleave). + /// + /// This function has a dependency on AllowExternalDrop property of + /// CoreWebView2Controller and return E_FAIL to callers to indicate this + /// operation is not allowed if AllowExternalDrop property is set to false. + /// + /// The hosting application must register as an IDropTarget and implement + /// and forward DragLeave calls to this function. + /// + /// \snippet DropTarget.cpp DragLeave + /// + function DragLeave: HResult; stdcall; + /// + /// This function corresponds to [IDropTarget::DragOver](/windows/win32/api/oleidl/nf-oleidl-idroptarget-dragover). + /// + /// This function has a dependency on AllowExternalDrop property of + /// CoreWebView2Controller and return E_FAIL to callers to indicate this + /// operation is not allowed if AllowExternalDrop property is set to false. + /// + /// The hosting application must register as an IDropTarget and implement + /// and forward DragOver calls to this function. + /// + /// point parameter must be modified to include the WebView's offset and be in + /// the WebView's client coordinates (Similar to how SendMouseInput works). + /// + /// \snippet DropTarget.cpp DragOver + /// + function DragOver(keyState: LongWord; point: tagPOINT; out effect: LongWord): HResult; stdcall; + /// + /// This function corresponds to [IDropTarget::Drop](/windows/win32/api/oleidl/nf-oleidl-idroptarget-drop). + /// + /// This function has a dependency on AllowExternalDrop property of + /// CoreWebView2Controller and return E_FAIL to callers to indicate this + /// operation is not allowed if AllowExternalDrop property is set to false. + /// + /// The hosting application must register as an IDropTarget and implement + /// and forward Drop calls to this function. + /// + /// point parameter must be modified to include the WebView's offset and be in + /// the WebView's client coordinates (Similar to how SendMouseInput works). + /// + /// \snippet DropTarget.cpp Drop + /// + function Drop(const dataObject: IDataObject; keyState: LongWord; point: tagPOINT; + out effect: LongWord): HResult; stdcall; + end; + + /// + /// This Interface includes an API which enables non-client hit-testing support for WebView2. + /// + /// + /// See the ICoreWebView2CompositionController4 article. + /// + ICoreWebView2CompositionController4 = interface(ICoreWebView2CompositionController3) + ['{7C367B9B-3D2B-450F-9E58-D61A20F486AA}'] + /// + /// If you are hosting a WebView2 using CoreWebView2CompositionController, you can call + /// this method in your Win32 WndProc to determine if the mouse is moving over or + /// clicking on WebView2 web content that should be considered part of a non-client region. + + /// The point parameter is expected to be in the client coordinate space of WebView2. + /// The method sets the out parameter value as follows: + /// - COREWEBVIEW2_NON_CLIENT_REGION_KIND_CAPTION when point corresponds to + /// a region (HTML element) within the WebView2 with + /// `-webkit-app-region: drag` CSS style set. + /// - COREWEBVIEW2_NON_CLIENT_REGION_KIND_CLIENT when point corresponds to + /// a region (HTML element) within the WebView2 without + /// `-webkit-app-region: drag` CSS style set. + /// - COREWEBVIEW2_NON_CLIENT_REGION_KIND_NOWHERE when point is not within the WebView2. + /// + /// NOTE: in order for WebView2 to properly handle the title bar system menu, + /// the app needs to send WM_NCRBUTTONDOWN and WM_NCRBUTTONUP to SendMouseInput. + /// See sample code below. + /// \snippet ViewComponent.cpp DraggableRegions2 + /// + /// \snippet ViewComponent.cpp DraggableRegions1 + /// + function GetNonClientRegionAtPoint(point: tagPOINT; + out value: COREWEBVIEW2_NON_CLIENT_REGION_KIND): HResult; stdcall; + /// + /// This method is used to get the collection of rects that correspond + /// to a particular COREWEBVIEW2_NON_CLIENT_REGION_KIND. This is to be used in + /// the callback of add_NonClientRegionChanged whose event args object contains + /// a region property of type COREWEBVIEW2_NON_CLIENT_REGION_KIND. + /// + /// \snippet ScenarioNonClientRegionSupport.cpp AddChangeListener + /// + function QueryNonClientRegion(Kind: COREWEBVIEW2_NON_CLIENT_REGION_KIND; + out rects: ICoreWebView2RegionRectCollectionView): HResult; stdcall; + /// + /// This method is used to add a listener for NonClientRegionChanged. + /// The event is fired when regions which are marked as non-client in the + /// app html have changed. So either when new regions have been marked, + /// or unmarked, or the region(s) have been changed to a different kind. + /// + /// \snippet ScenarioNonClientRegionSupport.cpp AddChangeListener + /// + function add_NonClientRegionChanged(const eventHandler: ICoreWebView2NonClientRegionChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// This method is used to remove an event handler previously added with + /// add_NonClientRegionChanged + /// + function remove_NonClientRegionChanged(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Controller interface. + /// + /// + /// See the ICoreWebView2Controller2 article. + /// + ICoreWebView2Controller2 = interface(ICoreWebView2Controller) + ['{C979903E-D4CA-4228-92EB-47EE3FA96EAB}'] + /// + /// The `DefaultBackgroundColor` property is the color WebView renders + /// underneath all web content. This means WebView renders this color when + /// there is no web content loaded such as before the initial navigation or + /// between navigations. This also means web pages with undefined css + /// background properties or background properties containing transparent + /// pixels will render their contents over this color. Web pages with defined + /// and opaque background properties that span the page will obscure the + /// `DefaultBackgroundColor` and display normally. The default value for this + /// property is white to resemble the native browser experience. + /// + /// The Color is specified by the COREWEBVIEW2_COLOR that represents an RGBA + /// value. The `A` represents an Alpha value, meaning + /// `DefaultBackgroundColor` can be transparent. In the case of a transparent + /// `DefaultBackgroundColor` WebView will render hosting app content as the + /// background. This Alpha value is not supported on Windows 7. Any `A` value + /// other than 255 will result in E_INVALIDARG on Windows 7. + /// It is supported on all other WebView compatible platforms. + /// + /// Semi-transparent colors are not currently supported by this API and + /// setting `DefaultBackgroundColor` to a semi-transparent color will fail + /// with E_INVALIDARG. The only supported alpha values are 0 and 255, all + /// other values will result in E_INVALIDARG. + /// `DefaultBackgroundColor` can only be an opaque color or transparent. + /// + /// This value may also be set by using the + /// `WEBVIEW2_DEFAULT_BACKGROUND_COLOR` environment variable. There is a + /// known issue with background color where setting the color by API can + /// still leave the app with a white flicker before the + /// `DefaultBackgroundColor` takes effect. Setting the color via environment + /// variable solves this issue. The value must be a hex value that can + /// optionally prepend a 0x. The value must account for the alpha value + /// which is represented by the first 2 digits. So any hex value fewer than 8 + /// digits will assume a prepended 00 to the hex value and result in a + /// transparent color. + /// `get_DefaultBackgroundColor` will return the result of this environment + /// variable if used. This environment variable can only set the + /// `DefaultBackgroundColor` once. Subsequent updates to background color + /// must be done through API call. + /// + /// \snippet ViewComponent.cpp DefaultBackgroundColor + /// + function Get_DefaultBackgroundColor(out value: COREWEBVIEW2_COLOR): HResult; stdcall; + /// + /// Sets the `DefaultBackgroundColor` property. + /// + function Set_DefaultBackgroundColor(value: COREWEBVIEW2_COLOR): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Controller2 interface. + /// + /// + /// See the ICoreWebView2Controller3 article. + /// + ICoreWebView2Controller3 = interface(ICoreWebView2Controller2) + ['{F9614724-5D2B-41DC-AEF7-73D62B51543B}'] + /// + /// The rasterization scale for the WebView. The rasterization scale is the + /// combination of the monitor DPI scale and text scaling set by the user. + /// This value should be updated when the DPI scale of the app's top level + /// window changes (i.e. monitor DPI scale changes or window changes monitor) + /// or when the text scale factor of the system changes. + /// + /// \snippet AppWindow.cpp DPIChanged + /// + /// \snippet AppWindow.cpp TextScaleChanged1 + /// + /// \snippet AppWindow.cpp TextScaleChanged2 + /// + /// Rasterization scale applies to the WebView content, as well as + /// popups, context menus, scroll bars, and so on. Normal app scaling + /// scenarios should use the ZoomFactor property or SetBoundsAndZoomFactor + /// API which only scale the rendered HTML content and not popups, context + /// menus, scroll bars, and so on. + /// + /// \snippet ViewComponent.cpp RasterizationScale + /// + function Get_RasterizationScale(out scale: Double): HResult; stdcall; + /// + /// Set the rasterization scale property. + /// + function Set_RasterizationScale(scale: Double): HResult; stdcall; + /// + /// ShouldDetectMonitorScaleChanges property determines whether the WebView + /// attempts to track monitor DPI scale changes. When true, the WebView will + /// track monitor DPI scale changes, update the RasterizationScale property, + /// and raises RasterizationScaleChanged event. When false, the WebView will + /// not track monitor DPI scale changes, and the app must update the + /// RasterizationScale property itself. RasterizationScaleChanged event will + /// never raise when ShouldDetectMonitorScaleChanges is false. Apps that want + /// to set their own rasterization scale should set this property to false to + /// avoid the WebView2 updating the RasterizationScale property to match the + /// monitor DPI scale. + /// + function Get_ShouldDetectMonitorScaleChanges(out value: Integer): HResult; stdcall; + /// + /// Set the ShouldDetectMonitorScaleChanges property. + /// + function Set_ShouldDetectMonitorScaleChanges(value: Integer): HResult; stdcall; + /// + /// Add an event handler for the RasterizationScaleChanged event. + /// The event is raised when the WebView detects that the monitor DPI scale + /// has changed, ShouldDetectMonitorScaleChanges is true, and the WebView has + /// changed the RasterizationScale property. + /// + /// \snippet ViewComponent.cpp RasterizationScaleChanged + /// + function add_RasterizationScaleChanged(const eventHandler: ICoreWebView2RasterizationScaleChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with + /// add_RasterizationScaleChanged. + /// + function remove_RasterizationScaleChanged(token: EventRegistrationToken): HResult; stdcall; + /// + /// BoundsMode affects how setting the Bounds and RasterizationScale + /// properties work. Bounds mode can either be in COREWEBVIEW2_BOUNDS_MODE_USE_RAW_PIXELS + /// mode or COREWEBVIEW2_BOUNDS_MODE_USE_RASTERIZATION_SCALE mode. + /// + /// When the mode is in COREWEBVIEW2_BOUNDS_MODE_USE_RAW_PIXELS, setting the bounds + /// property will set the size of the WebView in raw screen pixels. Changing + /// the rasterization scale in this mode won't change the raw pixel size of + /// the WebView and will only change the rasterization scale. + /// + /// When the mode is in COREWEBVIEW2_BOUNDS_MODE_USE_RASTERIZATION_SCALE, setting the + /// bounds property will change the logical size of the WebView which can be + /// described by the following equation: + /// ```text + /// Logical size * rasterization scale = Raw Pixel size + /// ``` + /// In this case, changing the rasterization scale will keep the logical size + /// the same and change the raw pixel size. + /// + /// \snippet ViewComponent.cpp BoundsMode + /// + function Get_BoundsMode(out BoundsMode: COREWEBVIEW2_BOUNDS_MODE): HResult; stdcall; + /// + /// Set the BoundsMode property. + /// + function Set_BoundsMode(BoundsMode: COREWEBVIEW2_BOUNDS_MODE): HResult; stdcall; + end; + + /// + /// Receives `RasterizationScaleChanged` events. + /// + /// + /// See the ICoreWebView2RasterizationScaleChangedEventHandler article. + /// + ICoreWebView2RasterizationScaleChangedEventHandler = interface(IUnknown) + ['{9C98C8B1-AC53-427E-A345-3049B5524BBE}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Controller; const args: IUnknown): HResult; stdcall; + end; + + /// + /// This is the ICoreWebView2Controller4 interface. + /// The ICoreWebView2Controller4 provides interface to enable/disable external drop. + /// + /// + /// See the ICoreWebView2Controller4 article. + /// + ICoreWebView2Controller4 = interface(ICoreWebView2Controller3) + ['{97D418D5-A426-4E49-A151-E1A10F327D9E}'] + /// + /// Gets the `AllowExternalDrop` property which is used to configure the + /// capability that dragging objects from outside the bounds of webview2 and + /// dropping into webview2 is allowed or disallowed. The default value is + /// TRUE. + /// + /// \snippet SettingsComponent.cpp ToggleAllowExternalDrop + /// + function Get_AllowExternalDrop(out value: Integer): HResult; stdcall; + /// + /// Sets the `AllowExternalDrop` property which is used to configure the + /// capability that dragging objects from outside the bounds of webview2 and + /// dropping into webview2 is allowed or disallowed. + /// + /// \snippet SettingsComponent.cpp ToggleAllowExternalDrop + /// + function Set_AllowExternalDrop(value: Integer): HResult; stdcall; + end; + + /// + /// This interface is used to manage profile options that created by 'CreateCoreWebView2ControllerOptions'. + /// + /// + /// See the ICoreWebView2ControllerOptions article. + /// + ICoreWebView2ControllerOptions = interface(IUnknown) + ['{12AAE616-8CCB-44EC-BCB3-EB1831881635}'] + /// + /// `ProfileName` property is to specify a profile name, which is only allowed to contain + /// the following ASCII characters. It has a maximum length of 64 characters excluding the null-terminator. + /// It is ASCII case insensitive. + /// + /// * alphabet characters: a-z and A-Z + /// * digit characters: 0-9 + /// * and '#', '@', '$', '(', ')', '+', '-', '_', '~', '.', ' ' (space). + /// + /// Note: the text must not end with a period '.' or ' ' (space). And, although upper-case letters are + /// allowed, they're treated just as lower-case counterparts because the profile name will be mapped to + /// the real profile directory path on disk and Windows file system handles path names in a case-insensitive way. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_ProfileName(out value: PWideChar): HResult; stdcall; + /// + /// Sets the `ProfileName` property. + /// + function Set_ProfileName(value: PWideChar): HResult; stdcall; + /// + /// `IsInPrivateModeEnabled` property is to enable/disable InPrivate mode. + /// + function Get_IsInPrivateModeEnabled(out value: Integer): HResult; stdcall; + /// + /// Sets the `IsInPrivateModeEnabled` property. + /// + function Set_IsInPrivateModeEnabled(value: Integer): HResult; stdcall; + end; + + /// + /// This is the interface in ControllerOptions for ScriptLocale. + /// + /// + /// See the ICoreWebView2ControllerOptions2 article. + /// + ICoreWebView2ControllerOptions2 = interface(ICoreWebView2ControllerOptions) + ['{06C991D8-9E7E-11ED-A8FC-0242AC120002}'] + /// + /// The default locale for the WebView2. It sets the default locale for all + /// Intl JavaScript APIs and other JavaScript APIs that depend on it, namely + /// `Intl.DateTimeFormat()` which affects string formatting like + /// in the time/date formats. Example: `Intl.DateTimeFormat().format(new Date())` + /// The intended locale value is in the format of + /// BCP 47 Language Tags. More information can be found from + /// [IETF BCP47](https://www.ietf.org/rfc/bcp/bcp47.html). + /// + /// This property sets the locale for a CoreWebView2Environment used to create the + /// WebView2ControllerOptions object, which is passed as a parameter in + /// `CreateCoreWebView2ControllerWithOptions`. + /// + /// Changes to the ScriptLocale property apply to renderer processes created after + /// the change. Any existing renderer processes will continue to use the previous + /// ScriptLocale value. To ensure changes are applied to all renderer process, + /// close and restart the CoreWebView2Environment and all associated WebView2 objects. + /// + /// The default value for ScriptLocale will depend on the WebView2 language + /// and OS region. If the language portions of the WebView2 language and OS region + /// match, then it will use the OS region. Otherwise, it will use the WebView2 + /// language. + /// + /// | OS Region | WebView2 Language | Default WebView2 ScriptLocale | + /// |-----------|-------------------|-------------------------------| + /// | en-GB | en-US | en-GB | + /// | es-MX | en-US | en-US | + /// | en-US | en-GB | en-US | + /// + /// You can set the ScriptLocale to the empty string to get the default ScriptLocale value. + /// + /// Use OS specific APIs to determine the OS region to use with this property + /// if you want to match the OS. For example: + /// + /// Win32 C++: + /// ```cpp + /// wchar_t osLocale[LOCALE_NAME_MAX_LENGTH] = {0}; + /// GetUserDefaultLocaleName(osLocale, LOCALE_NAME_MAX_LENGTH); + /// ``` + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// \snippet AppWindow.cpp ScriptLocaleSetting + /// + function Get_ScriptLocale(out locale: PWideChar): HResult; stdcall; + /// + /// Sets the `ScriptLocale` property. + /// + function Set_ScriptLocale(locale: PWideChar): HResult; stdcall; + end; + + /// + /// Controller option used to expose the DefaultBackgroundColor property early in the loading process. + /// + /// + /// See the ICoreWebView2ControllerOptions3 article. + /// + ICoreWebView2ControllerOptions3 = interface(ICoreWebView2ControllerOptions2) + ['{B32B191A-8998-57CA-B7CB-E04617E4CE4A}'] + /// + /// Gets the `DefaultBackgroundColor` property. + /// + function Get_DefaultBackgroundColor(out value: COREWEBVIEW2_COLOR): HResult; stdcall; + /// + /// This property allows users to initialize the `DefaultBackgroundColor` early, + /// preventing a white flash that can occur while WebView2 is loading when + /// the background color is set to something other than white. With early + /// initialization, the color remains consistent from the start. After + /// initialization, `CoreWebView2Controller.DefaultBackgroundColor` will return the value set using this API. + /// + /// The `CoreWebView2Controller.DefaultBackgroundColor` can be set via the WEBVIEW2_DEFAULT_BACKGROUND_COLOR environment variable, + /// which will remain supported for cases where this solution is being used. + /// It is encouraged to transition away from the environment variable and use this API solution to + /// apply the property. It is important to highlight that when set, the enviroment variable overrides + /// ControllerOptions::DefaultBackgroundColor and becomes the initial value of Controller::DefaultBackgroundColor. + /// + /// The `DefaultBackgroundColor` is the color that renders underneath all web + /// content. This means WebView2 renders this color when there is no web + /// content loaded. When no background color is defined in WebView2, it uses + /// the `DefaultBackgroundColor` property to render the background. + /// By default, this color is set to white. + /// + /// This API only supports opaque colors and full transparency. It will + /// fail for colors with alpha values that don't equal 0 or 255. + /// When WebView2 is set to be fully transparent, it does not render a background, + /// allowing the content from windows behind it to be visible. + /// + function Set_DefaultBackgroundColor(value: COREWEBVIEW2_COLOR): HResult; stdcall; + end; + + /// + /// Controller option used to allow user input pass through the browser and make + /// them received in the host app process. + /// + /// + /// See the ICoreWebView2ControllerOptions4 article. + /// + ICoreWebView2ControllerOptions4 = interface(ICoreWebView2ControllerOptions3) + ['{21EB052F-AD39-555E-824A-C87B091D4D36}'] + /// + /// Gets the `AllowHostInputProcessing` property. + /// + function Get_AllowHostInputProcessing(out value: Integer): HResult; stdcall; + /// + /// `AllowHostInputProcessing` property is to enable/disable input passing through + /// the app before being delivered to the WebView2. This property is only applicable + /// to controllers created with `CoreWebView2Environment.CreateCoreWebView2ControllerAsync` and not + /// composition controllers created with `CoreWebView2Environment.CreateCoreWebView2CompositionControllerAsync`. + /// By default the value is `FALSE`. + /// Setting this property has no effect when using visual hosting. + /// \snippet AppWindow.cpp AllowHostInputProcessing + /// + function Set_AllowHostInputProcessing(value: Integer): HResult; stdcall; + end; + + /// + /// Receives the result of the `ClearBrowsingData` method. + /// + /// + /// See the ICoreWebView2ClearBrowsingDataCompletedHandler article. + /// + ICoreWebView2ClearBrowsingDataCompletedHandler = interface(IUnknown) + ['{E9710A06-1D1D-49B2-8234-226F35846AE5}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult): HResult; stdcall; + end; + + /// + /// Receives the result of the `CreateCoreWebView2CompositionController` method. + /// + /// + /// See the ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler article. + /// + ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler = interface(IUnknown) + ['{02FAB84B-1428-4FB7-AD45-1B2E64736184}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; const result_: ICoreWebView2CompositionController): HResult; stdcall; + end; + + /// + /// Receives the result of the `CreateCoreWebView2Environment` method. + /// + /// + /// See the ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler article. + /// + ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler = interface(IUnknown) + ['{4E8A3389-C9D8-4BD2-B6B5-124FEE6CC14D}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; const result_: ICoreWebView2Environment): HResult; stdcall; + end; + + /// + /// Represents the registration of a custom scheme with the + /// CoreWebView2Environment. + /// This allows the WebView2 app to be able to handle WebResourceRequested + /// event for requests with the specified scheme and be able to navigate the + /// WebView2 to the custom scheme. Once the environment is created, the + /// registrations are valid and immutable throughout the lifetime of the + /// associated WebView2s' browser process and any WebView2 environments + /// sharing the browser process must be created with identical custom scheme + /// registrations, otherwise the environment creation will fail. + /// Any further attempts to register the same scheme will fail during environment creation. + /// The URIs of registered custom schemes will be treated similar to http + /// URIs for their origins. + /// They will have tuple origins for URIs with host and opaque origins for + /// URIs without host as specified in + /// [7.5 Origin - HTML Living Standard](https://html.spec.whatwg.org/multipage/origin.html) + /// + /// Example: + /// custom-scheme-with-host://hostname/path/to/resource has origin of + /// custom-scheme-with-host://hostname. + /// custom-scheme-without-host:path/to/resource has origin of + /// custom-scheme-without-host:path/to/resource. + /// For WebResourceRequested event, the cases of request URIs and filter URIs + /// with custom schemes will be normalized according to generic URI syntax + /// rules. Any non-ASCII characters will be preserved. + /// The registered custom schemes also participate in + /// [CORS](https://developer.mozilla.org/docs/Web/HTTP/CORS) and + /// adheres to [CSP](https://developer.mozilla.org/docs/Web/HTTP/CSP). + /// The app needs to set the appropriate access headers in its + /// WebResourceRequested event handler to allow CORS requests. + /// + /// + /// See the ICoreWebView2CustomSchemeRegistration article. + /// + ICoreWebView2CustomSchemeRegistration = interface(IUnknown) + ['{D60AC92C-37A6-4B26-A39E-95CFE59047BB}'] + /// + /// The name of the custom scheme to register. + /// + function Get_SchemeName(out SchemeName: PWideChar): HResult; stdcall; + /// + /// Whether the sites with this scheme will be treated as a + /// [Secure Context](https://developer.mozilla.org/docs/Web/Security/Secure_Contexts) + /// like an HTTPS site. This flag is only effective when HasAuthorityComponent + /// is also set to `true`. + /// `false` by default. + /// + function Get_TreatAsSecure(out TreatAsSecure: Integer): HResult; stdcall; + /// + /// Set if the scheme will be treated as a Secure Context. + /// + function Set_TreatAsSecure(TreatAsSecure: Integer): HResult; stdcall; + /// + /// List of origins that are allowed to issue requests with the custom + /// scheme, such as XHRs and subresource requests that have an Origin header. + /// The origin of any request (requests that have the + /// [Origin header](https://developer.mozilla.org/docs/Web/HTTP/Headers/Origin)) + /// to the custom scheme URI needs to be in this list. No-origin requests + /// are requests that do not have an Origin header, such as link + /// navigations, embedded images and are always allowed. + /// Note: POST requests always contain an Origin header, therefore + /// AllowedOrigins must be set for even for same origin POST requests. + /// Note that cross-origin restrictions still apply. + /// From any opaque origin (Origin header is null), no cross-origin requests + /// are allowed. + /// If the list is empty, no cross-origin request to this scheme is + /// allowed. + /// Origins are specified as a string in the format of + /// scheme://host:port. + /// The origins are string pattern matched with `*` (matches 0 or more + /// characters) and `?` (matches 0 or 1 character) wildcards just like + /// the URI matching in the + /// [AddWebResourceRequestedFilter API](/dotnet/api/microsoft.web.webview2.core.corewebview2.addwebresourcerequestedfilter). + /// For example, "http://*.example.com:80". + /// Here's a set of examples of what is allowed and not: + /// + /// | Request URI | Originating URL | AllowedOrigins | Allowed | + /// | -- | -- | -- | -- | + /// | `custom-scheme:request` | `https://www.example.com` | {"https://www.example.com"} | Yes | + /// | `custom-scheme:request` | `https://www.example.com` | {"https://*.example.com"} | Yes | + /// | `custom-scheme:request` | `https://www.example.com` | {"https://www.example2.com"} | No | + /// | `custom-scheme-with-authority://host/path` | `custom-scheme-with-authority://host2` | {""} | No | + /// | `custom-scheme-with-authority://host/path` | `custom-scheme-with-authority2://host` | {"custom-scheme-with-authority2://*"} | Yes | + /// | `custom-scheme-without-authority:path` | custom-scheme-without-authority:path2 | {"custom-scheme-without-authority:*"} | No | + /// | `custom-scheme-without-authority:path` | custom-scheme-without-authority:path2 | {"*"} | Yes | + /// + /// The returned strings and the array itself must be deallocated with + /// CoTaskMemFree. + /// + {* out allowedOrigins: PPWideChar1 --> out allowedOrigins: PPWideChar ************** WEBVIEW4DELPHI ************** *} + function GetAllowedOrigins(out allowedOriginsCount: SYSUINT; out allowedOrigins: PPWideChar): HResult; stdcall; + /// + /// Set the array of origins that are allowed to use the scheme. + /// + {* var allowedOrigins: PWideChar --> allowedOrigins: PPWideChar ************** WEBVIEW4DELPHI ************** *} + function SetAllowedOrigins(allowedOriginsCount: SYSUINT; allowedOrigins: PPWideChar): HResult; stdcall; + /// + /// Set this property to `true` if the URIs with this custom + /// scheme will have an authority component (a host for custom schemes). + /// Specifically, if you have a URI of the following form you should set the + /// `HasAuthorityComponent` value as listed. + /// + /// | URI | Recommended HasAuthorityComponent value | + /// | -- | -- | + /// | `custom-scheme-with-authority://host/path` | `true` | + /// | `custom-scheme-without-authority:path` | `false` | + /// + /// When this property is set to `true`, the URIs with this scheme will be + /// interpreted as having a + /// [scheme and host](https://html.spec.whatwg.org/multipage/origin.html#concept-origin-tuple) + /// origin similar to an http URI. Note that the port and user + /// information are never included in the computation of origins for + /// custom schemes. + /// If this property is set to `false`, URIs with this scheme will have an + /// [opaque origin](https://html.spec.whatwg.org/multipage/origin.html#concept-origin-opaque) + /// similar to a data URI. + /// This property is `false` by default. + /// + /// Note: For custom schemes registered as having authority component, + /// navigations to URIs without authority of such custom schemes will fail. + /// However, if the content inside WebView2 references + /// a subresource with a URI that does not have + /// an authority component, but of a custom scheme that is registered as + /// having authority component, the URI will be interpreted as a relative path + /// as specified in [RFC3986](https://www.rfc-editor.org/rfc/rfc3986). + /// For example, `custom-scheme-with-authority:path` will be interpreted + /// as `custom-scheme-with-authority://host/path`. + /// However, this behavior cannot be guaranteed to remain in future + /// releases so it is recommended not to rely on this behavior. + /// + function Get_HasAuthorityComponent(out HasAuthorityComponent: Integer): HResult; stdcall; + /// + /// Get has authority component. + /// + function Set_HasAuthorityComponent(HasAuthorityComponent: Integer): HResult; stdcall; + end; + + /// + /// This is a continuation of the ICoreWebView2DevToolsProtocolEventReceivedEventArgs + /// interface that provides the session ID of the target where the event originates from. + /// + /// + /// See the ICoreWebView2DevToolsProtocolEventReceivedEventArgs2 article. + /// + ICoreWebView2DevToolsProtocolEventReceivedEventArgs2 = interface(ICoreWebView2DevToolsProtocolEventReceivedEventArgs) + ['{2DC4959D-1494-4393-95BA-BEA4CB9EBD1B}'] + /// + /// The sessionId of the target where the event originates from. + /// Empty string is returned as sessionId if the event comes from the default + /// session for the top page. + /// + /// \snippet ScriptComponent.cpp DevToolsProtocolEventReceivedSessionId + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_sessionId(out value: PWideChar): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Environment interface. + /// + /// + /// See the ICoreWebView2Environment2 article. + /// + ICoreWebView2Environment2 = interface(ICoreWebView2Environment) + ['{41F3632B-5EF4-404F-AD82-2D606C5A9A21}'] + /// + /// Create a new web resource request object. + /// URI parameter must be absolute URI. + /// The headers string is the raw request header string delimited by CRLF + /// (optional in last header). + /// It's also possible to create this object with null headers string + /// and then use the ICoreWebView2HttpRequestHeaders to construct the headers + /// line by line. + /// For information on other parameters see ICoreWebView2WebResourceRequest. + /// + /// \snippet ScenarioNavigateWithWebResourceRequest.cpp NavigateWithWebResourceRequest + /// + function CreateWebResourceRequest(uri: PWideChar; Method: PWideChar; const postData: IStream; + Headers: PWideChar; + out value: ICoreWebView2WebResourceRequest): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Environment2 interface. + /// + /// + /// See the ICoreWebView2Environment3 article. + /// + ICoreWebView2Environment3 = interface(ICoreWebView2Environment2) + ['{80A22AE3-BE7C-4CE2-AFE1-5A50056CDEEB}'] + /// + /// Asynchronously create a new WebView for use with visual hosting. + /// + /// parentWindow is the HWND in which the app will connect the visual tree of + /// the WebView. This will be the HWND that the app will receive pointer/ + /// mouse input meant for the WebView (and will need to use SendMouseInput/ + /// SendPointerInput to forward). If the app moves the WebView visual tree to + /// underneath a different window, then it needs to call put_ParentWindow to + /// update the new parent HWND of the visual tree. + /// + /// HWND_MESSAGE is not a valid parameter for `parentWindow` for visual hosting. + /// The underlying implementation of supporting HWND_MESSAGE would break + /// accessibility for visual hosting. This is supported in windowed + /// WebViews - see CreateCoreWebView2Controller. + /// + /// Use put_RootVisualTarget on the created CoreWebView2CompositionController to + /// provide a visual to host the browser's visual tree. + /// + /// It is recommended that the application set Application User Model ID for + /// the process or the application window. If none is set, during WebView + /// creation a generated Application User Model ID is set to root window of + /// parentWindow. + /// \snippet AppWindow.cpp CreateCoreWebView2Controller + /// + /// It is recommended that the application handles restart manager messages + /// so that it can be restarted gracefully in the case when the app is using + /// Edge for WebView from a certain installation and that installation is + /// being uninstalled. For example, if a user installs Edge from Dev channel + /// and opts to use Edge from that channel for testing the app, and then + /// uninstalls Edge from that channel without closing the app, the app will + /// be restarted to allow uninstallation of the dev channel to succeed. + /// \snippet AppWindow.cpp RestartManager + /// + /// The app should retry `CreateCoreWebView2CompositionController` upon failure, + /// unless the error code is `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`. + /// When the app retries `CreateCoreWebView2CompositionController` + /// upon failure, it is recommended that the app restarts from creating a new + /// WebView2 Environment. If a WebView2 Runtime update happens, the version + /// associated with a WebView2 Environment may have been removed and causing + /// the object to no longer work. Creating a new WebView2 Environment works + /// since it uses the latest version. + /// + /// WebView creation fails with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)` if a + /// running instance using the same user data folder exists, and the Environment + /// objects have different `EnvironmentOptions`. For example, if a WebView was + /// created with one language, an attempt to create a WebView with a different + /// language using the same user data folder will fail. + /// + /// The creation will fail with `E_ABORT` if `parentWindow` is destroyed + /// before the creation is finished. If this is caused by a call to + /// `DestroyWindow`, the creation completed handler will be invoked before + /// `DestroyWindow` returns, so you can use this to cancel creation and clean + /// up resources synchronously when quitting a thread. + /// + /// In rare cases the creation can fail with `E_UNEXPECTED` if runtime does not have + /// permissions to the user data folder. + /// + /// CreateCoreWebView2CompositionController is supported in the following versions of Windows: + /// + /// - Windows 11 + /// - Windows 10 + /// - Windows Server 2019 + /// - Windows Server 2016 + /// + function CreateCoreWebView2CompositionController(ParentWindow: HWND; + const handler: ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler): HResult; stdcall; + /// + /// Create an empty ICoreWebView2PointerInfo. The returned + /// ICoreWebView2PointerInfo needs to be populated with all of the relevant + /// info before calling SendPointerInput. + /// + function CreateCoreWebView2PointerInfo(out value: ICoreWebView2PointerInfo): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Environment3 interface. + /// + /// + /// See the ICoreWebView2Environment4 article. + /// + ICoreWebView2Environment4 = interface(ICoreWebView2Environment3) + ['{20944379-6DCF-41D6-A0A0-ABC0FC50DE0D}'] + /// + /// Returns the Automation Provider for the WebView that matches the provided + /// window. Host apps are expected to implement + /// IRawElementProviderHwndOverride. When GetOverrideProviderForHwnd is + /// called, the app can pass the HWND to GetAutomationProviderForWindow to + /// find the matching WebView Automation Provider. + /// + function GetAutomationProviderForWindow(HWND_: HWND; out value: IUnknown): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Environment4 interface that supports + /// the BrowserProcessExited event. + /// + /// + /// See the ICoreWebView2Environment5 article. + /// + ICoreWebView2Environment5 = interface(ICoreWebView2Environment4) + ['{319E423D-E0D7-4B8D-9254-AE9475DE9B17}'] + /// + /// Adds an event handler for the `BrowserProcessExited` event. + /// The `BrowserProcessExited` event is raised when the collection of WebView2 + /// Runtime processes for the browser process of this environment terminate + /// due to browser process failure or normal shutdown (for example, when all + /// associated WebViews are closed), after all resources have been released + /// (including the user data folder). To learn about what these processes are, + /// go to [Process model](/microsoft-edge/webview2/concepts/process-model). + /// + /// A handler added with this method is called until removed with + /// `remove_BrowserProcessExited`, even if a new browser process is bound to + /// this environment after earlier `BrowserProcessExited` events are raised. + /// + /// Multiple app processes can share a browser process by creating their webviews + /// from a `ICoreWebView2Environment` with the same user data folder. When the entire + /// collection of WebView2Runtime processes for the browser process exit, all + /// associated `ICoreWebView2Environment` objects receive the `BrowserProcessExited` + /// event. Multiple processes sharing the same browser process need to coordinate + /// their use of the shared user data folder to avoid race conditions and + /// unnecessary waits. For example, one process should not clear the user data + /// folder at the same time that another process recovers from a crash by recreating + /// its WebView controls; one process should not block waiting for the event if + /// other app processes are using the same browser process (the browser process will + /// not exit until those other processes have closed their webviews too). + /// + /// Note this is an event from the `ICoreWebView2Environment3` interface, not + /// the `ICoreWebView2` one. The difference between `BrowserProcessExited` and + /// `ICoreWebView2`'s `ProcessFailed` is that `BrowserProcessExited` is + /// raised for any **browser process** exit (expected or unexpected, after all + /// associated processes have exited too), while `ProcessFailed` is raised for + /// **unexpected** process exits of any kind (browser, render, GPU, and all + /// other types), or for main frame **render process** unresponsiveness. To + /// learn more about the WebView2 Process Model, go to + /// [Process model](/microsoft-edge/webview2/concepts/process-model). + /// + /// In the case the browser process crashes, both `BrowserProcessExited` and + /// `ProcessFailed` events are raised, but the order is not guaranteed. These + /// events are intended for different scenarios. It is up to the app to + /// coordinate the handlers so they do not try to perform reliability recovery + /// while also trying to move to a new WebView2 Runtime version or remove the + /// user data folder. + /// + /// \snippet AppWindow.cpp Close + /// + function add_BrowserProcessExited(const eventHandler: ICoreWebView2BrowserProcessExitedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_BrowserProcessExited`. + /// + function remove_BrowserProcessExited(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// This interface is an extension of the ICoreWebView2Environment that supports + /// creating print settings for printing to PDF. + /// + /// + /// See the ICoreWebView2Environment6 article. + /// + ICoreWebView2Environment6 = interface(ICoreWebView2Environment5) + ['{E59EE362-ACBD-4857-9A8E-D3644D9459A9}'] + /// + /// Creates the `ICoreWebView2PrintSettings` used by the `PrintToPdf` + /// method. + /// + function CreatePrintSettings(out value: ICoreWebView2PrintSettings): HResult; stdcall; + end; + + /// + /// This interface is an extension of the ICoreWebView2Environment. An object + /// implementing the ICoreWebView2Environment7 interface will also + /// implement ICoreWebView2Environment. + /// + /// + /// See the ICoreWebView2Environment7 article. + /// + ICoreWebView2Environment7 = interface(ICoreWebView2Environment6) + ['{43C22296-3BBD-43A4-9C00-5C0DF6DD29A2}'] + /// + /// Returns the user data folder that all CoreWebView2's created from this + /// environment are using. + /// This could be either the value passed in by the developer when creating + /// the environment object or the calculated one for default handling. It + /// will always be an absolute path. + /// + /// \snippet AppWindow.cpp GetUserDataFolder + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_UserDataFolder(out value: PWideChar): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Environment7 interface that supports + /// the ProcessInfosChanged event. + /// + /// + /// See the ICoreWebView2Environment8 article. + /// + ICoreWebView2Environment8 = interface(ICoreWebView2Environment7) + ['{D6EB91DD-C3D2-45E5-BD29-6DC2BC4DE9CF}'] + /// + /// Adds an event handler for the `ProcessInfosChanged` event. + /// + /// \snippet ProcessComponent.cpp ProcessInfosChanged + /// \snippet ProcessComponent.cpp ProcessInfosChanged1 + /// + function add_ProcessInfosChanged(const eventHandler: ICoreWebView2ProcessInfosChangedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_ProcessInfosChanged`. + /// + function remove_ProcessInfosChanged(token: EventRegistrationToken): HResult; stdcall; + /// + /// Returns the `ICoreWebView2ProcessInfoCollection` + /// Provide a list of all process using same user data folder except for crashpad process. + /// + function GetProcessInfos(out value: ICoreWebView2ProcessInfoCollection): HResult; stdcall; + end; + + /// + /// eceives `ProcessInfosChanged` events. + /// + /// + /// See the ICoreWebView2ProcessInfosChangedEventHandler article. + /// + ICoreWebView2ProcessInfosChangedEventHandler = interface(IUnknown) + ['{F4AF0C39-44B9-40E9-8B11-0484CFB9E0A1}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Environment; const args: IUnknown): HResult; stdcall; + end; + + /// + /// A collection of ICoreWebView2ProcessInfo. + /// + /// + /// See the ICoreWebView2ProcessInfoCollection article. + /// + ICoreWebView2ProcessInfoCollection = interface(IUnknown) + ['{402B99CD-A0CC-4FA5-B7A5-51D86A1D2339}'] + /// + /// The number of elements contained in the collection. + /// + function Get_Count(out value: SYSUINT): HResult; stdcall; + /// + /// Gets the element at the given index. + /// + function GetValueAtIndex(index: SYSUINT; out value: ICoreWebView2ProcessInfo): HResult; stdcall; + end; + + /// + /// Provides a set of properties for a process in the ICoreWebView2Environment. + /// + /// + /// See the ICoreWebView2ProcessInfo article. + /// + ICoreWebView2ProcessInfo = interface(IUnknown) + ['{84FA7612-3F3D-4FBF-889D-FAD000492D72}'] + /// + /// The process id of the process. + /// + function Get_ProcessId(out value: SYSINT): HResult; stdcall; + /// + /// The kind of the process. + /// + function Get_Kind(out Kind: COREWEBVIEW2_PROCESS_KIND): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Environment interface for + /// creating CoreWebView2 ContextMenuItem objects. + /// + /// + /// See the ICoreWebView2Environment9 article. + /// + ICoreWebView2Environment9 = interface(ICoreWebView2Environment8) + ['{F06F41BF-4B5A-49D8-B9F6-FA16CD29F274}'] + /// + /// Create a custom `ContextMenuItem` object to insert into the WebView context menu. + /// CoreWebView2 will rewind the icon stream before decoding. + /// There is a limit of 1000 active custom context menu items at a given time. + /// Attempting to create more before deleting existing ones will fail with + /// ERROR_NOT_ENOUGH_QUOTA. + /// It is recommended to reuse ContextMenuItems across ContextMenuRequested events + /// for performance. + /// The returned ContextMenuItem object's `IsEnabled` property will default to `TRUE` + /// and `IsChecked` property will default to `FALSE`. A `CommandId` will be assigned + /// to the ContextMenuItem object that's unique across active custom context menu items, + /// but command ID values of deleted ContextMenuItems can be reassigned. + /// + function CreateContextMenuItem(Label_: PWideChar; const iconStream: IStream; + Kind: COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND; + out value: ICoreWebView2ContextMenuItem): HResult; stdcall; + end; + + /// + /// This interface is used to create ICoreWebView2ControllerOptions object, which + /// can be passed as a parameter in CreateCoreWebView2ControllerWithOptions and + /// CreateCoreWebView2CompositionControllerWithOptions function for multiple profiles support. + /// The profile will be created on disk or opened when calling CreateCoreWebView2ControllerWithOptions or + /// CreateCoreWebView2CompositionControllerWithOptions no matter InPrivate mode is enabled or not, and + /// it will be released in memory when the corresponding controller is closed but still remain on disk. + /// If you create a WebView2Controller with {ProfileName="name", InPrivate=false} and then later create another + /// one with {ProfileName="name", InPrivate=true}, these two controllers using the same profile would be allowed to + /// run at the same time. + /// As WebView2 is built on top of Edge browser, it follows Edge's behavior pattern. To create an InPrivate WebView, + /// we gets an off-the-record profile (an InPrivate profile) from a regular profile, then create the WebView with the + /// off-the-record profile. + /// + /// + /// See the ICoreWebView2Environment10 article. + /// + ICoreWebView2Environment10 = interface(ICoreWebView2Environment9) + ['{EE0EB9DF-6F12-46CE-B53F-3F47B9C928E0}'] + /// + /// Create a new ICoreWebView2ControllerOptions to be passed as a parameter of + /// CreateCoreWebView2ControllerWithOptions and CreateCoreWebView2CompositionControllerWithOptions. + /// The 'options' is settable and in it the default value for profile name is the empty string, + /// and the default value for IsInPrivateModeEnabled is false. + /// Also the profile name can be reused. + /// + function CreateCoreWebView2ControllerOptions(out value: ICoreWebView2ControllerOptions): HResult; stdcall; + /// + /// Create a new WebView with options. + /// + function CreateCoreWebView2ControllerWithOptions(ParentWindow: HWND; + const options: ICoreWebView2ControllerOptions; + const handler: ICoreWebView2CreateCoreWebView2ControllerCompletedHandler): HResult; stdcall; + /// + /// Create a new WebView in visual hosting mode with options. + /// + function CreateCoreWebView2CompositionControllerWithOptions(ParentWindow: HWND; + const options: ICoreWebView2ControllerOptions; + const handler: ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Environment interface for + /// getting the crash dump folder path. + /// + /// + /// See the ICoreWebView2Environment11 article. + /// + ICoreWebView2Environment11 = interface(ICoreWebView2Environment10) + ['{F0913DC6-A0EC-42EF-9805-91DFF3A2966A}'] + /// + /// `FailureReportFolderPath` returns the path of the folder where minidump files are written. + /// Whenever a WebView2 process crashes, a crash dump file will be created in the crash dump folder. + /// The crash dump format is minidump files. Please see + /// [Minidump Files documentation](/windows/win32/debug/minidump-files) for detailed information. + /// Normally when a single child process fails, a minidump will be generated and written to disk, + /// then the `ProcessFailed` event is raised. But for unexpected crashes, a minidump file might not be generated + /// at all, despite whether `ProcessFailed` event is raised. If there are multiple + /// process failures at once, multiple minidump files could be generated. Thus `FailureReportFolderPath` + /// could contain old minidump files that are not associated with a specific `ProcessFailed` event. + /// \snippet AppWindow.cpp GetFailureReportFolder + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_FailureReportFolderPath(out value: PWideChar): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Environment interface for creating shared buffer object. + /// + /// + /// See the ICoreWebView2Environment12 article. + /// + ICoreWebView2Environment12 = interface(ICoreWebView2Environment11) + ['{F503DB9B-739F-48DD-B151-FDFCF253F54E}'] + /// + /// Create a shared memory based buffer with the specified size in bytes. + /// The buffer can be shared with web contents in WebView by calling + /// `PostSharedBufferToScript` on `CoreWebView2` or `CoreWebView2Frame` object. + /// Once shared, the same content of the buffer will be accessible from both + /// the app process and script in WebView. Modification to the content will be visible + /// to all parties that have access to the buffer. + /// The shared buffer is presented to the script as ArrayBuffer. All JavaScript APIs + /// that work for ArrayBuffer including Atomics APIs can be used on it. + /// There is currently a limitation that only size less than 2GB is supported. + /// + function CreateSharedBuffer(Size: Largeuint; out value: ICoreWebView2SharedBuffer): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Environment interface for getting process + /// with associated information. + /// + /// + /// See the ICoreWebView2Environment13 article. + /// + ICoreWebView2Environment13 = interface(ICoreWebView2Environment12) + ['{AF641F58-72B2-11EE-B962-0242AC120002}'] + /// + /// Gets a snapshot collection of `ProcessExtendedInfo`s corresponding to all + /// currently running processes associated with this `CoreWebView2Environment` + /// excludes crashpad process. + /// This provides the same list of `ProcessInfo`s as what's provided in + /// `GetProcessInfos`, but additionally provides a list of associated `FrameInfo`s + /// which are actively running (showing or hiding UI elements) in the renderer + /// process. See `AssociatedFrameInfos` for more information. + /// + /// \snippet ProcessComponent.cpp GetProcessExtendedInfos + /// + function GetProcessExtendedInfos(const handler: ICoreWebView2GetProcessExtendedInfosCompletedHandler): HResult; stdcall; + end; + + /// + /// Receives the result of the `GetProcessExtendedInfos` method. + /// + /// + /// See the ICoreWebView2GetProcessExtendedInfosCompletedHandler article. + /// + ICoreWebView2GetProcessExtendedInfosCompletedHandler = interface(IUnknown) + ['{F45E55AA-3BC2-11EE-BE56-0242AC120002}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; const result_: ICoreWebView2ProcessExtendedInfoCollection): HResult; stdcall; + end; + + /// + /// A collection of ICoreWebView2ProcessExtendedInfo. + /// + /// + /// See the ICoreWebView2ProcessExtendedInfoCollection article. + /// + ICoreWebView2ProcessExtendedInfoCollection = interface(IUnknown) + ['{32EFA696-407A-11EE-BE56-0242AC120002}'] + /// + /// The number of elements contained in the collection. + /// + function Get_Count(out value: SYSUINT): HResult; stdcall; + /// + /// Gets the element at the given index. + /// + function GetValueAtIndex(index: SYSUINT; out value: ICoreWebView2ProcessExtendedInfo): HResult; stdcall; + end; + + /// + /// Provides process with associated extended information in the `ICoreWebView2Environment`. + /// + /// + /// See the ICoreWebView2ProcessExtendedInfo article. + /// + ICoreWebView2ProcessExtendedInfo = interface(IUnknown) + ['{AF4C4C2E-45DB-11EE-BE56-0242AC120002}'] + /// + /// The process info of the current process. + /// + function Get_processInfo(out processInfo: ICoreWebView2ProcessInfo): HResult; stdcall; + /// + /// The collection of associated `FrameInfo`s which are actively running + /// (showing or hiding UI elements) in this renderer process. `AssociatedFrameInfos` + /// will only be populated when this `CoreWebView2ProcessExtendedInfo` + /// corresponds to a renderer process. Non-renderer processes will always + /// have an empty `AssociatedFrameInfos`. The `AssociatedFrameInfos` may + /// also be empty for renderer processes that have no active frames. + /// + /// \snippet ProcessComponent.cpp AssociatedFrameInfos + /// + function Get_AssociatedFrameInfos(out frames: ICoreWebView2FrameInfoCollection): HResult; stdcall; + end; + + /// + /// Collection of FrameInfos (name and source). Used to list the affected + /// frames' info when a frame-only render process failure occurs in the + /// ICoreWebView2. + /// + /// + /// See the ICoreWebView2FrameInfoCollection article. + /// + ICoreWebView2FrameInfoCollection = interface(IUnknown) + ['{8F834154-D38E-4D90-AFFB-6800A7272839}'] + /// + /// Gets an iterator over the collection of `FrameInfo`s. + /// + function GetIterator(out value: ICoreWebView2FrameInfoCollectionIterator): HResult; stdcall; + end; + + /// + /// Iterator for a collection of FrameInfos. For more info, see + /// ICoreWebView2ProcessFailedEventArgs2 and + /// ICoreWebView2FrameInfoCollection. + /// + /// + /// See the ICoreWebView2FrameInfoCollectionIterator article. + /// + ICoreWebView2FrameInfoCollectionIterator = interface(IUnknown) + ['{1BF89E2D-1B2B-4629-B28F-05099B41BB03}'] + /// + /// `TRUE` when the iterator has not run out of `FrameInfo`s. If the + /// collection over which the iterator is iterating is empty or if the + /// iterator has gone past the end of the collection, then this is `FALSE`. + /// + function Get_hasCurrent(out value: Integer): HResult; stdcall; + /// + /// Get the current `ICoreWebView2FrameInfo` of the iterator. + /// Returns `HRESULT_FROM_WIN32(ERROR_INVALID_INDEX)` if HasCurrent is + /// `FALSE`. + /// + function GetCurrent(out value: ICoreWebView2FrameInfo): HResult; stdcall; + /// + /// Move the iterator to the next `FrameInfo` in the collection. + /// + function MoveNext(out value: Integer): HResult; stdcall; + end; + + /// + /// This is ICoreWebView2Environment14 that exposes new methods to + /// create Filesystem access related DOM objects. + /// + /// + /// See the ICoreWebView2Environment14 article. + /// + ICoreWebView2Environment14 = interface(ICoreWebView2Environment13) + ['{A5E9FAD9-C875-59DA-9BD7-473AA5CA1CEF}'] + /// + /// Create a `ICoreWebView2FileSystemHandle` object from a path that represents a Web + /// [FileSystemFileHandle](https://developer.mozilla.org/docs/Web/API/FileSystemFileHandle). + /// + /// The `path` is the path pointed by the file and must be a syntactically correct fully qualified + /// path, but it is not checked here whether it currently points to a file. If an invalid path is + /// passed, an E_INVALIDARG will be returned and the object will fail to create. Any other state + /// validation will be done when this handle is accessed from web content + /// and will cause the DOM exceptions described in + /// [FileSystemFileHandle methods](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryHandle#instance_methods) + /// if access operations fail. + /// + /// `Permission` property is used to specify whether the Handle should be created with a Read-only or + /// Read-and-write web permission. For the `permission` value specified here, the DOM + /// [PermissionStatus](https://developer.mozilla.org/docs/Web/API/PermissionStatus) property + /// will be [granted](https://developer.mozilla.org/docs/Web/API/PermissionStatus/state) + /// and the unspecified permission will be + /// [prompt](https://developer.mozilla.org/docs/Web/API/PermissionStatus/state). Therefore, + /// the web content then does not need to call + /// [requestPermission](https://developer.mozilla.org/docs/Web/API/FileSystemHandle/requestPermission) + /// for the permission that was specified before attempting the permitted operation, + /// but if it does, the promise will immediately be resolved + /// with 'granted' PermissionStatus without firing the WebView2 + /// [PermissionRequested](/microsoft-edge/webview2/reference/win32/icorewebview2permissionrequestedeventargs) + /// event or prompting the user for permission. Otherwise, `requestPermission` will behave as the + /// status of permission is currently `prompt`, which means the `PermissionRequested` event will fire + /// or the user will be prompted. + /// Additionally, the app must have the same OS permissions that have propagated to the + /// [WebView2 browser process](/microsoft-edge/webview2/concepts/process-model) + /// for the path it wishes to give the web content to read/write the file. + /// Specifically, the WebView2 browser process will run in same user, package identity, and app + /// container of the app, but other means such as security context impersonations do not get + /// propagated, so such permissions that the app has, will not be effective in WebView2. + /// Note: An exception to this is, if there is a parent directory handle that + /// has broader permissions in the same page context than specified in here, the handle will automatically + /// inherit the most permissive permission of the parent handle when posted to that page context. + /// i.e. If there is already a `FileSystemDirectoryHandle` to `C:\example` that has write permission on + /// a page, even though a WebFileSystemHandle to file `C:\example\file.txt` is created with + /// `COREWEBVIEW2_FILE_SYSTEM_HANDLE_PERMISSION_READ_ONLY` permission, when posted to that page, write permission + /// will be automatically granted to the created handle. + /// + /// An app needs to be mindful that this object, when posted to the web content, provides it with unusual + /// access to OS file system via the Web FileSystem API! The app should therefore only post objects + /// for paths that it wants to allow access to the web content and it is not recommended that the web content + /// "asks" for this path. The app should also check the source property of the target to ensure + /// that it is sending to the web content of intended origin. + /// + /// Once the object is passed to web content, if the content is attempting a read, + /// the file must be existing and available to read similar to a file chosen by + /// [open file picker](https://developer.mozilla.org/docs/Web/API/Window/showOpenFilePicker), + /// otherwise the read operation will + /// [throw a DOM exception](https://developer.mozilla.org/docs/Web/API/FileSystemFileHandle/getFile#exceptions). + /// For write operations, the file does not need to exist as `FileSystemFileHandle` will behave + /// as a file path chosen by + /// [save file picker](https://developer.mozilla.org/docs/Web/API/Window/showSaveFilePicker) + /// and will create or overwrite the file, but the parent directory structure pointed + /// by the file must exist and an existing file must be available to write and delete + /// or the write operation will + /// [throw a DOM exception](https://developer.mozilla.org/docs/Web/API/FileSystemFileHandle/createWritable#exceptions). + /// + function CreateWebFileSystemFileHandle(Path: PWideChar; + Permission: COREWEBVIEW2_FILE_SYSTEM_HANDLE_PERMISSION; + out value: ICoreWebView2FileSystemHandle): HResult; stdcall; + /// + /// Create a `ICoreWebView2FileSystemHandle` object from a path that represents a Web + /// [FileSystemDirectoryHandle](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryHandle). + /// + /// The `path` is the path pointed by the directory and must be a syntactically correct fully qualified + /// path, but it is not checked here whether it currently points to a directory. Any other state + /// validation will be done when this handle is accessed from web content + /// and will cause DOM exceptions if access operations fail. If an invalid path is + /// passed, an E_INVALIDARG will be returned and the object will fail to create. + /// + /// `Permission` property is used to specify whether the Handle should be created with a Read-only or + /// Read-and-write web permission. For the `permission` value specified here, the Web + /// [PermissionStatus](https://developer.mozilla.org/docs/Web/API/PermissionStatus) + /// will be [granted](https://developer.mozilla.org/docs/Web/API/PermissionStatus/state) + /// and the unspecified permission will be + /// [prompt](https://developer.mozilla.org/docs/Web/API/PermissionStatus/state). Therefore, + /// the web content then does not need to call + /// [requestPermission](https://developer.mozilla.org/docs/Web/API/FileSystemHandle/requestPermission) + /// for the permission that was specified before attempting the permitted operation, + /// but if it does, the promise will immediately be resolved + /// with 'granted' PermissionStatus without firing the WebView2 + /// [PermissionRequested](/microsoft-edge/webview2/reference/win32/icorewebview2permissionrequestedeventargs) + /// event or prompting the user for permission. Otherwise, `requestPermission` will behave as the + /// status of permission is currently `Prompt`, which means the `PermissionRequested` event will fire + /// or the user will be prompted. + /// Additionally, the app must have the same OS permissions that have propagated to the + /// [WebView2 browser process](/microsoft-edge/webview2/concepts/process-model) + /// for the path it wishes to give the web content to make any operations on the directory. + /// Specifically, the WebView2 browser process will run in same user, package identity, and app + /// container of the app, but other means such as security context impersonations do not get + /// propagated, so such permissions that the app has, will not be effective in WebView2. + /// Note: An exception to this is, if there is a parent directory handle that + /// has broader permissions in the same page context than specified in here, the handle will automatically + /// inherit the most permissive permission of the parent handle when posted to that page context. + /// i.e. If there is already a `FileSystemDirectoryHandle` to `C:\example` that has write permission on + /// a page, even though a WebFileSystemHandle to directory `C:\example\directory` is created with + /// `COREWEBVIEW2_FILE_SYSTEM_HANDLE_PERMISSION_READ_ONLY` permission, when posted to that page, write permission + /// will be automatically granted to the created handle. + /// + /// An app needs to be mindful that this object, when posted to the web content, provides it with unusual + /// access to OS file system via the Web FileSystem API! The app should therefore only post objects + /// for paths that it wants to allow access to the web content and it is not recommended that the web content + /// "asks" for this path. The app should also check the source property of the target to ensure + /// that it is sending to the web content of intended origin. + /// + /// Once the object is passed to web content, the path must point to a directory as if it was chosen via + /// [directory picker](https://developer.mozilla.org/docs/Web/API/Window/showDirectoryPicker) + /// otherwise any IO operation done on the `FileSystemDirectoryHandle` will throw a DOM exception. + /// + function CreateWebFileSystemDirectoryHandle(Path: PWideChar; + Permission: COREWEBVIEW2_FILE_SYSTEM_HANDLE_PERMISSION; + out value: ICoreWebView2FileSystemHandle): HResult; stdcall; + /// + /// Create a generic object collection. + /// + function CreateObjectCollection(length: SYSUINT; var items: IUnknown; + out objectCollection: ICoreWebView2ObjectCollection): HResult; stdcall; + end; + + /// + /// Representation of a DOM + /// [FileSystemHandle](https://developer.mozilla.org/docs/Web/API/FileSystemHandle) + /// object. + /// + /// + /// See the ICoreWebView2FileSystemHandle article. + /// + ICoreWebView2FileSystemHandle = interface(IUnknown) + ['{C65100AC-0DE2-5551-A362-23D9BD1D0E1F}'] + /// + /// The kind of the FileSystemHandle. It can either be a file or a directory. + /// + function Get_Kind(out value: COREWEBVIEW2_FILE_SYSTEM_HANDLE_KIND): HResult; stdcall; + /// + /// The path to the FileSystemHandle. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Path(out value: PWideChar): HResult; stdcall; + /// + /// The permissions granted to the FileSystemHandle. + /// + function Get_Permission(out value: COREWEBVIEW2_FILE_SYSTEM_HANDLE_PERMISSION): HResult; stdcall; + end; + + /// + /// Options used to create WebView2 Environment. A default implementation is + /// provided in WebView2EnvironmentOptions.h. + /// + /// + /// See the ICoreWebView2EnvironmentOptions article. + /// + ICoreWebView2EnvironmentOptions = interface(IUnknown) + ['{2FDE08A8-1E9A-4766-8C05-95A9CEB9D1C5}'] + /// + /// Changes the behavior of the WebView. The arguments are passed to the + /// browser process as part of the command. For more information about + /// using command-line switches with Chromium browser processes, navigate to + /// [Run Chromium with Flags](https://www.chromium.org/developers/how-tos/run-chromium-with-flags). + /// The value appended to a switch is appended to the browser process, for + /// example, in `--edge-webview-switches=xxx` the value is `xxx`. If you + /// specify a switch that is important to WebView functionality, it is + /// ignored, for example, `--user-data-dir`. Specific features are disabled + /// internally and blocked from being enabled. If a switch is specified + /// multiple times, only the last instance is used. + /// + /// \> [!NOTE]\n\> A merge of the different values of the same switch is not attempted, + /// except for disabled and enabled features. The features specified by + /// `--enable-features` and `--disable-features` are merged with simple + /// logic.\n\> * The features is the union of the specified features + /// and built-in features. If a feature is disabled, it is removed from the + /// enabled features list. + /// + /// If you specify command-line switches and use the + /// `additionalBrowserArguments` parameter, the `--edge-webview-switches` + /// value takes precedence and is processed last. If a switch fails to + /// parse, the switch is ignored. The default state for the operation is + /// to run the browser process with no extra flags. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_AdditionalBrowserArguments(out value: PWideChar): HResult; stdcall; + /// + /// Sets the `AdditionalBrowserArguments` property. + /// + /// Please note that calling this API twice will replace the previous value + /// rather than appending to it. If there are multiple switches, there + /// should be a space in between them. The one exception is if multiple + /// features are being enabled/disabled for a single switch, in which + /// case the features should be comma-seperated. + /// Ex. "--disable-features=feature1,feature2 --some-other-switch --do-something" + /// + function Set_AdditionalBrowserArguments(value: PWideChar): HResult; stdcall; + /// + /// The default display language for WebView. It applies to browser UI such as + /// context menu and dialogs. It also applies to the `accept-languages` HTTP + /// header that WebView sends to websites. The intended locale value is in the + /// format of BCP 47 Language Tags. More information can be found from + /// [IETF BCP47](https://www.ietf.org/rfc/bcp/bcp47.html). + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Language(out value: PWideChar): HResult; stdcall; + /// + /// Sets the `Language` property. + /// + function Set_Language(value: PWideChar): HResult; stdcall; + /// + /// Specifies the version of the WebView2 Runtime binaries required to be + /// compatible with your app. This defaults to the WebView2 Runtime version + /// that corresponds with the version of the SDK the app is using. The + /// format of this value is the same as the format of the + /// `BrowserVersionString` property and other `BrowserVersion` values. Only + /// the version part of the `BrowserVersion` value is respected. The channel + /// suffix, if it exists, is ignored. The version of the WebView2 Runtime + /// binaries actually used may be different from the specified + /// `TargetCompatibleBrowserVersion`. The binaries are only guaranteed to be + /// compatible. Verify the actual version on the `BrowserVersionString` + /// property on the `ICoreWebView2Environment`. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_TargetCompatibleBrowserVersion(out value: PWideChar): HResult; stdcall; + /// + /// Sets the `TargetCompatibleBrowserVersion` property. + /// + function Set_TargetCompatibleBrowserVersion(value: PWideChar): HResult; stdcall; + /// + /// The `AllowSingleSignOnUsingOSPrimaryAccount` property is used to enable + /// single sign on with Azure Active Directory (AAD) and personal Microsoft + /// Account (MSA) resources inside WebView. All AAD accounts, connected to + /// Windows and shared for all apps, are supported. For MSA, SSO is only enabled + /// for the account associated for Windows account login, if any. + /// Default is disabled. Universal Windows Platform apps must also declare + /// `enterpriseCloudSSO` + /// [Restricted capabilities](/windows/uwp/packaging/app-capability-declarations\#restricted-capabilities) + /// for the single sign on (SSO) to work. + /// + function Get_AllowSingleSignOnUsingOSPrimaryAccount(out allow: Integer): HResult; stdcall; + /// + /// Sets the `AllowSingleSignOnUsingOSPrimaryAccount` property. + /// + function Set_AllowSingleSignOnUsingOSPrimaryAccount(allow: Integer): HResult; stdcall; + end; + + /// + /// Additional options used to create WebView2 Environment. A default implementation is + /// provided in WebView2EnvironmentOptions.h. + /// + /// + /// See the ICoreWebView2EnvironmentOptions2 article. + /// ICoreWebView2EnvironmentOptions* interfaces derive from IUnknown to make moving + /// the API from experimental to public smoothier. These interfaces are mostly internal to + /// WebView's own code. Normal apps just use the objects we provided and never interact + /// with the interfaces. Advanced apps might implement their own options object. In that + /// case, it is also easier for them to implement the interface if it is derived from IUnknown. + /// + ICoreWebView2EnvironmentOptions2 = interface(IUnknown) + ['{FF85C98A-1BA7-4A6B-90C8-2B752C89E9E2}'] + /// + /// Whether other processes can create WebView2 from WebView2Environment created with the + /// same user data folder and therefore sharing the same WebView browser process instance. + /// Default is FALSE. + /// + function Get_ExclusiveUserDataFolderAccess(out value: Integer): HResult; stdcall; + /// + /// Sets the `ExclusiveUserDataFolderAccess` property. + /// The `ExclusiveUserDataFolderAccess` property specifies that the WebView environment + /// obtains exclusive access to the user data folder. + /// If the user data folder is already being used by another WebView environment with a + /// different value for `ExclusiveUserDataFolderAccess` property, the creation of a WebView2Controller + /// using the environment object will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`. + /// When set as TRUE, no other WebView can be created from other processes using WebView2Environment + /// objects with the same UserDataFolder. This prevents other processes from creating WebViews + /// which share the same browser process instance, since sharing is performed among + /// WebViews that have the same UserDataFolder. When another process tries to create a + /// WebView2Controller from an WebView2Environment object created with the same user data folder, + /// it will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`. + /// + function Set_ExclusiveUserDataFolderAccess(value: Integer): HResult; stdcall; + end; + + /// + /// Additional options used to create WebView2 Environment to manage crash + /// reporting. + /// + /// + /// See the ICoreWebView2EnvironmentOptions3 article. + /// + ICoreWebView2EnvironmentOptions3 = interface(IUnknown) + ['{4A5C436E-A9E3-4A2E-89C3-910D3513F5CC}'] + /// + /// When `IsCustomCrashReportingEnabled` is set to `TRUE`, Windows won't send crash data to Microsoft endpoint. + /// `IsCustomCrashReportingEnabled` is default to be `FALSE`, in this case, WebView will respect OS consent. + /// + function Get_IsCustomCrashReportingEnabled(out value: Integer): HResult; stdcall; + /// + /// Sets the `IsCustomCrashReportingEnabled` property. + /// + function Set_IsCustomCrashReportingEnabled(value: Integer): HResult; stdcall; + end; + + /// + /// Additional options used to create WebView2 Environment that manages custom scheme registration. + /// + /// + /// See the ICoreWebView2EnvironmentOptions4 article. + /// + ICoreWebView2EnvironmentOptions4 = interface(IUnknown) + ['{AC52D13F-0D38-475A-9DCA-876580D6793E}'] + /// + /// Array of custom scheme registrations. The returned + /// ICoreWebView2CustomSchemeRegistration pointers must be released, and the + /// array itself must be deallocated with CoTaskMemFree. + /// + {* out schemeRegistrations: PPUserType3 --> out schemeRegistrations: PPCoreWebView2CustomSchemeRegistration ************** WEBVIEW4DELPHI ************** *} + function GetCustomSchemeRegistrations(out Count: SYSUINT; out schemeRegistrations: PPCoreWebView2CustomSchemeRegistration): HResult; stdcall; + /// + /// Set the array of custom scheme registrations to be used. + /// \snippet AppWindow.cpp CoreWebView2CustomSchemeRegistration + /// + {* var schemeRegistrations: ICoreWebView2CustomSchemeRegistration --> schemeRegistrations: PPCoreWebView2CustomSchemeRegistration ************** WEBVIEW4DELPHI ************** *} + function SetCustomSchemeRegistrations(Count: SYSUINT; schemeRegistrations: PPCoreWebView2CustomSchemeRegistration): HResult; stdcall; + end; + + /// + /// Additional options used to create WebView2 Environment to manage tracking + /// prevention. + /// + /// + /// See the ICoreWebView2EnvironmentOptions5 article. + /// + ICoreWebView2EnvironmentOptions5 = interface(IUnknown) + ['{0AE35D64-C47F-4464-814E-259C345D1501}'] + /// + /// The `EnableTrackingPrevention` property is used to enable/disable tracking prevention + /// feature in WebView2. This property enable/disable tracking prevention for all the + /// WebView2's created in the same environment. By default this feature is enabled to block + /// potentially harmful trackers and trackers from sites that aren't visited before and set to + /// `COREWEBVIEW2_TRACKING_PREVENTION_LEVEL_BALANCED` or whatever value was last changed/persisted + /// on the profile. + /// + /// You can set this property to false to disable the tracking prevention feature if the app only + /// renders content in the WebView2 that is known to be safe. Disabling this feature when creating + /// environment also improves runtime performance by skipping related code. + /// + /// You shouldn't disable this property if WebView2 is being used as a "full browser" with arbitrary + /// navigation and should protect end user privacy. + /// + /// There is `ICoreWebView2Profile3::PreferredTrackingPreventionLevel` property to control levels of + /// tracking prevention of the WebView2's associated with a same profile. However, you can also disable + /// tracking prevention later using `ICoreWebView2Profile3::PreferredTrackingPreventionLevel` property and + /// `COREWEBVIEW2_TRACKING_PREVENTION_LEVEL_NONE` value but that doesn't improves runtime performance. + /// + /// See `ICoreWebView2Profile3::PreferredTrackingPreventionLevel` for more details. + /// + /// Tracking prevention protects users from online tracking by restricting the ability of trackers to + /// access browser-based storage as well as the network. See [Tracking prevention](/microsoft-edge/web-platform/tracking-prevention). + /// + function Get_EnableTrackingPrevention(out value: Integer): HResult; stdcall; + /// + /// Sets the `EnableTrackingPrevention` property. + /// + function Set_EnableTrackingPrevention(value: Integer): HResult; stdcall; + end; + + /// + /// Additional options used to create WebView2 Environment to manage browser extensions. + /// + /// + /// See the ICoreWebView2EnvironmentOptions6 article. + /// + ICoreWebView2EnvironmentOptions6 = interface(IUnknown) + ['{57D29CC3-C84F-42A0-B0E2-EFFBD5E179DE}'] + /// + /// When `AreBrowserExtensionsEnabled` is set to `TRUE`, new extensions can be added to user + /// profile and used. `AreBrowserExtensionsEnabled` is default to be `FALSE`, in this case, + /// new extensions can't be installed, and already installed extension won't be + /// available to use in user profile. + /// If connecting to an already running environment with a different value for `AreBrowserExtensionsEnabled` + /// property, it will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`. + /// See `ICoreWebView2BrowserExtension` for Extensions API details. + /// + function Get_AreBrowserExtensionsEnabled(out value: Integer): HResult; stdcall; + /// + /// Sets the `AreBrowserExtensionsEnabled` property. + /// + function Set_AreBrowserExtensionsEnabled(value: Integer): HResult; stdcall; + end; + + /// + /// Additional options used to create the WebView2 Environment that support + /// specifying the `ReleaseChannels` and `ChannelSearchKind`. + /// + /// + /// See the ICoreWebView2EnvironmentOptions7 article. + /// + ICoreWebView2EnvironmentOptions7 = interface(IUnknown) + ['{C48D539F-E39F-441C-AE68-1F66E570BDC5}'] + /// + /// Gets the `ChannelSearchKind` property. + /// + function Get_ChannelSearchKind(out value: COREWEBVIEW2_CHANNEL_SEARCH_KIND): HResult; stdcall; + /// + /// The `ChannelSearchKind` property is `COREWEBVIEW2_CHANNEL_SEARCH_KIND_MOST_STABLE` + /// by default; environment creation searches for a release channel on the machine + /// from most to least stable using the first channel found. The default search order is: + /// WebView2 Runtime -> Beta -> Dev -> Canary. Set `ChannelSearchKind` to + /// `COREWEBVIEW2_CHANNEL_SEARCH_KIND_LEAST_STABLE` to reverse the search order + /// so that environment creation searches for a channel from least to most stable. If + /// `ReleaseChannels` has been provided, the loader will only search + /// for channels in the set. See `COREWEBVIEW2_RELEASE_CHANNELS` for more details + /// on channels. + /// This property can be overridden by the corresponding + /// registry key `ChannelSearchKind` or the environment variable + /// `WEBVIEW2_CHANNEL_SEARCH_KIND`. Set the value to `1` to set the search kind to + /// `COREWEBVIEW2_CHANNEL_SEARCH_KIND_LEAST_STABLE`. See + /// `CreateCoreWebView2EnvironmentWithOptions` for more details on overrides. + /// + function Set_ChannelSearchKind(value: COREWEBVIEW2_CHANNEL_SEARCH_KIND): HResult; stdcall; + /// + /// Gets the `ReleaseChannels` property. + /// + function Get_ReleaseChannels(out value: COREWEBVIEW2_RELEASE_CHANNELS): HResult; stdcall; + /// + /// Sets the `ReleaseChannels`, which is a mask of one or more + /// `COREWEBVIEW2_RELEASE_CHANNELS` indicating which channels environment + /// creation should search for. OR operation(s) can be applied to multiple + /// `COREWEBVIEW2_RELEASE_CHANNELS` to create a mask. The default value is a + /// a mask of all the channels. By default, environment creation searches for + /// channels from most to least stable, using the first channel found on the + /// device. When `ReleaseChannels` is provided, environment creation will only + /// search for the channels specified in the set. Set `ChannelSearchKind` to + /// `COREWEBVIEW2_CHANNEL_SEARCH_KIND_LEAST_STABLE` to reverse the search order + /// so environment creation searches for least stable build first. See + /// `COREWEBVIEW2_RELEASE_CHANNELS` for descriptions of each channel. + /// `CreateCoreWebView2EnvironmentWithOptions` fails with + /// `HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)` if environment creation is unable + /// to find any channel from the `ReleaseChannels` installed on the device. + /// Use `GetAvailableCoreWebView2BrowserVersionStringWithOptions` on + /// `ICoreWebView2Environment` to verify which channel is used when this option + /// is set. + /// Examples: + /// + /// | ReleaseChannels | Channel Search Kind: Most Stable (default) | Channel Search Kind: Least Stable | + /// | --- | --- | --- | + /// |COREWEBVIEW2_RELEASE_CHANNELS_BETA \| COREWEBVIEW2_RELEASE_CHANNELS_STABLE| WebView2 Runtime -> Beta | Beta -> WebView2 Runtime| + /// |COREWEBVIEW2_RELEASE_CHANNELS_CANARY \| COREWEBVIEW2_RELEASE_CHANNELS_DEV \| COREWEBVIEW2_RELEASE_CHANNELS_BETA \| COREWEBVIEW2_RELEASE_CHANNELS_STABLE| WebView2 Runtime -> Beta -> Dev -> Canary | Canary -> Dev -> Beta -> WebView2 Runtime | + /// |COREWEBVIEW2_RELEASE_CHANNELS_CANARY| Canary | Canary | + /// |COREWEBVIEW2_RELEASE_CHANNELS_BETA \| COREWEBVIEW2_RELEASE_CHANNELS_CANARY \| COREWEBVIEW2_RELEASE_CHANNELS_STABLE | WebView2 Runtime -> Beta -> Canary | Canary -> Beta -> WebView2 Runtime | + /// + /// If both `BrowserExecutableFolder` and `ReleaseChannels` are provided, the + /// `BrowserExecutableFolder` takes precedence, regardless of whether or not the + /// channel of `BrowserExecutableFolder` is included in the `ReleaseChannels`. + /// `ReleaseChannels` can be overridden by the corresponding registry override + /// `ReleaseChannels` or the environment variable `WEBVIEW2_RELEASE_CHANNELS`. + /// Set the value to a comma-separated string of integers, which map to the + /// following release channel values: Stable (0), Beta (1), Dev (2), and + /// Canary (3). For example, the values "0,2" and "2,0" indicate that environment + /// creation should only search for Dev channel and the WebView2 Runtime, using the + /// order indicated by `ChannelSearchKind`. Environment creation attempts to + /// interpret each integer and treats any invalid entry as Stable channel. See + /// `CreateCoreWebView2EnvironmentWithOptions` for more details on overrides. + /// + function Set_ReleaseChannels(value: COREWEBVIEW2_RELEASE_CHANNELS): HResult; stdcall; + end; + + /// + /// Additional options used to create WebView2 Environment. + /// + /// + /// See the ICoreWebView2EnvironmentOptions8 article. + /// + ICoreWebView2EnvironmentOptions8 = interface(IUnknown) + ['{7C7ECF51-E918-5CAF-853C-E9A2BCC27775}'] + /// + /// Gets the `ScrollBarStyle` property. + /// + function Get_ScrollBarStyle(out value: COREWEBVIEW2_SCROLLBAR_STYLE): HResult; stdcall; + /// + /// The ScrollBar style being set on the WebView2 Environment. + /// The default value is `COREWEBVIEW2_SCROLLBAR_STYLE_DEFAULT` + /// which specifies the default browser ScrollBar style. + /// The `color-scheme` CSS property needs to be set on the corresponding page + /// to allow ScrollBar to follow light or dark theme. Please see + /// [color-scheme](https://developer.mozilla.org/docs/Web/CSS/color-scheme#declaring_color_scheme_preferences) + /// for how `color-scheme` can be set. + /// CSS styles that modify the ScrollBar applied on top of native ScrollBar styling + /// that is selected with `ScrollBarStyle`. + /// + function Set_ScrollBarStyle(value: COREWEBVIEW2_SCROLLBAR_STYLE): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Frame interface with navigation events, + /// executing script and posting web messages. + /// + /// + /// See the ICoreWebView2Frame2 article. + /// + ICoreWebView2Frame2 = interface(ICoreWebView2Frame) + ['{7A6A5834-D185-4DBF-B63F-4A9BC43107D4}'] + /// + /// Add an event handler for the `NavigationStarting` event. + /// A frame navigation will raise a `NavigationStarting` event and + /// a `CoreWebView2.FrameNavigationStarting` event. All of the + /// `FrameNavigationStarting` event handlers for the current frame will be + /// run before the `NavigationStarting` event handlers. All of the event handlers + /// share a common `NavigationStartingEventArgs` object. Whichever event handler is + /// last to change the `NavigationStartingEventArgs.Cancel` property will + /// decide if the frame navigation will be cancelled. Redirects raise this + /// event as well, and the navigation id is the same as the original one. + /// + /// Navigations will be blocked until all `NavigationStarting` and + /// `CoreWebView2.FrameNavigationStarting` event handlers return. + /// + function add_NavigationStarting(const eventHandler: ICoreWebView2FrameNavigationStartingEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_NavigationStarting`. + /// + function remove_NavigationStarting(token: EventRegistrationToken): HResult; stdcall; + /// + /// Add an event handler for the `ContentLoading` event. `ContentLoading` + /// triggers before any content is loaded, including scripts added with + /// `AddScriptToExecuteOnDocumentCreated`. `ContentLoading` does not trigger + /// if a same page navigation occurs (such as through `fragment` + /// navigations or `history.pushState` navigations). This operation + /// follows the `NavigationStarting` and precedes `NavigationCompleted` events. + /// + function add_ContentLoading(const eventHandler: ICoreWebView2FrameContentLoadingEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_ContentLoading`. + /// + function remove_ContentLoading(token: EventRegistrationToken): HResult; stdcall; + /// + /// Add an event handler for the `NavigationCompleted` event. + /// `NavigationCompleted` runs when the CoreWebView2Frame has completely + /// loaded (concurrently when `body.onload` runs) or loading stopped with error. + /// + function add_NavigationCompleted(const eventHandler: ICoreWebView2FrameNavigationCompletedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_NavigationCompleted`. + /// + function remove_NavigationCompleted(token: EventRegistrationToken): HResult; stdcall; + /// + /// Add an event handler for the DOMContentLoaded event. + /// DOMContentLoaded is raised when the iframe html document has been parsed. + /// This aligns with the document's DOMContentLoaded event in html. + /// + function add_DOMContentLoaded(const eventHandler: ICoreWebView2FrameDOMContentLoadedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with add_DOMContentLoaded. + /// + function remove_DOMContentLoaded(token: EventRegistrationToken): HResult; stdcall; + /// + /// Run JavaScript code from the javascript parameter in the current frame. + /// The result of evaluating the provided JavaScript is passed to the completion handler. + /// The result value is a JSON encoded string. If the result is undefined, + /// contains a reference cycle, or otherwise is not able to be encoded into + /// JSON, then the result is considered to be null, which is encoded + /// in JSON as the string "null". + /// + /// \> [!NOTE]\n\> A function that has no explicit return value returns undefined. If the + /// script that was run throws an unhandled exception, then the result is + /// also "null". This method is applied asynchronously. If the method is + /// run before `ContentLoading`, the script will not be executed + /// and the string "null" will be returned. + /// This operation executes the script even if `ICoreWebView2Settings::IsScriptEnabled` is + /// set to `FALSE`. + /// + /// \snippet ScenarioDOMContentLoaded.cpp ExecuteScriptFrame + /// + function ExecuteScript(javaScript: PWideChar; + const handler: ICoreWebView2ExecuteScriptCompletedHandler): HResult; stdcall; + /// + /// Posts the specified webMessage to the frame. + /// The frame receives the message by subscribing to the `message` event of + /// the `window.chrome.webview` of the frame document. + /// + /// ```cpp + /// window.chrome.webview.addEventListener('message', handler) + /// window.chrome.webview.removeEventListener('message', handler) + /// ``` + /// + /// The event args is an instances of `MessageEvent`. The + /// `ICoreWebView2Settings::IsWebMessageEnabled` setting must be `TRUE` or + /// the message will not be sent. The `data` property of the event + /// args is the `webMessage` string parameter parsed as a JSON string into a + /// JavaScript object. The `source` property of the event args is a reference + /// to the `window.chrome.webview` object. For information about sending + /// messages from the HTML document in the WebView to the host, navigate to + /// [add_WebMessageReceived](/microsoft-edge/webview2/reference/win32/icorewebview2#add_webmessagereceived). + /// The message is delivered asynchronously. If a navigation occurs before the + /// message is posted to the page, the message is discarded. + /// + function PostWebMessageAsJson(webMessageAsJson: PWideChar): HResult; stdcall; + /// + /// Posts a message that is a simple string rather than a JSON string + /// representation of a JavaScript object. This behaves in exactly the same + /// manner as `PostWebMessageAsJson`, but the `data` property of the event + /// args of the `window.chrome.webview` message is a string with the same + /// value as `webMessageAsString`. Use this instead of + /// `PostWebMessageAsJson` if you want to communicate using simple strings + /// rather than JSON objects. + /// + function PostWebMessageAsString(webMessageAsString: PWideChar): HResult; stdcall; + /// + /// Add an event handler for the `WebMessageReceived` event. + /// `WebMessageReceived` runs when the + /// `ICoreWebView2Settings::IsWebMessageEnabled` setting is set and the + /// frame document runs `window.chrome.webview.postMessage`. + /// The `postMessage` function is `void postMessage(object)` + /// where object is any object supported by JSON conversion. + /// + /// \snippet assets\ScenarioWebMessage.html chromeWebView + /// + /// When the frame calls `postMessage`, the object parameter is converted to a + /// JSON string and is posted asynchronously to the host process. This will + /// result in the handlers `Invoke` method being called with the JSON string + /// as its parameter. + /// + /// \snippet ScenarioWebMessage.cpp WebMessageReceivedIFrame + /// + function add_WebMessageReceived(const handler: ICoreWebView2FrameWebMessageReceivedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Remove an event handler previously added with `add_WebMessageReceived`. + /// + function remove_WebMessageReceived(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives `NavigationStarting` events. + /// + /// + /// See the ICoreWebView2FrameNavigationStartingEventHandler article. + /// + ICoreWebView2FrameNavigationStartingEventHandler = interface(IUnknown) + ['{E79908BF-2D5D-4968-83DB-263FEA2C1DA3}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Frame; + const args: ICoreWebView2NavigationStartingEventArgs): HResult; stdcall; + end; + + /// + /// Receives `ContentLoading` events. + /// + /// + /// See the ICoreWebView2FrameContentLoadingEventHandler article. + /// + ICoreWebView2FrameContentLoadingEventHandler = interface(IUnknown) + ['{0D6156F2-D332-49A7-9E03-7D8F2FEEEE54}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Frame; + const args: ICoreWebView2ContentLoadingEventArgs): HResult; stdcall; + end; + + /// + /// Receives `NavigationCompleted` events. + /// + /// + /// See the ICoreWebView2FrameNavigationCompletedEventHandler article. + /// + ICoreWebView2FrameNavigationCompletedEventHandler = interface(IUnknown) + ['{609302AD-0E36-4F9A-A210-6A45272842A9}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Frame; + const args: ICoreWebView2NavigationCompletedEventArgs): HResult; stdcall; + end; + + /// + /// Receives `DOMContentLoaded` events. + /// + /// + /// See the ICoreWebView2FrameDOMContentLoadedEventHandler article. + /// + ICoreWebView2FrameDOMContentLoadedEventHandler = interface(IUnknown) + ['{38D9520D-340F-4D1E-A775-43FCE9753683}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Frame; + const args: ICoreWebView2DOMContentLoadedEventArgs): HResult; stdcall; + end; + + /// + /// Receives `WebMessageReceived` events. + /// + /// + /// See the ICoreWebView2FrameWebMessageReceivedEventHandler article. + /// + ICoreWebView2FrameWebMessageReceivedEventHandler = interface(IUnknown) + ['{E371E005-6D1D-4517-934B-A8F1629C62A5}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Frame; + const args: ICoreWebView2WebMessageReceivedEventArgs): HResult; stdcall; + end; + + /// + /// This is an extension of the ICoreWebView2Frame interface that supports PermissionRequested + /// + /// + /// See the ICoreWebView2Frame3 article. + /// + ICoreWebView2Frame3 = interface(ICoreWebView2Frame2) + ['{B50D82CC-CC28-481D-9614-CB048895E6A0}'] + /// + /// Adds an event handler for the `PermissionRequested` event. + /// `PermissionRequested` is raised when content in an iframe any of its + /// descendant iframes requests permission to privileged resources. + /// + /// This relates to the `PermissionRequested` event on the `CoreWebView2`. + /// Both these events will be raised in the case of an iframe requesting + /// permission. The `CoreWebView2Frame`'s event handlers will be invoked + /// before the event handlers on the `CoreWebView2`. If the `Handled` property + /// of the `PermissionRequestedEventArgs` is set to TRUE within the + /// `CoreWebView2Frame` event handler, then the event will not be + /// raised on the `CoreWebView2`, and it's event handlers will not be invoked. + /// + /// In the case of nested iframes, if the `PermissionRequested` event is handled + /// in the current nested iframe (i.e., the Handled property of the + /// `PermissionRequestedEventArgs` is set to TRUE), the event will not be raised + /// on the parent `CoreWebView2Frame`. However, if the `PermissionRequested` event is + /// not handled in that nested iframe, the event will be raised from its nearest + /// tracked parent `CoreWebView2Frame`. It will iterate through the parent frame + /// chain up to the main frame until a parent frame handles the request. + /// + /// If a deferral is not taken on the event args, the subsequent scripts are + /// blocked until the event handler returns. If a deferral is taken, the + /// scripts are blocked until the deferral is completed. + /// + /// \snippet ScenarioIFrameDevicePermission.cpp PermissionRequested0 + /// \snippet ScenarioIFrameDevicePermission.cpp PermissionRequested1 + /// + function add_PermissionRequested(const eventHandler: ICoreWebView2FramePermissionRequestedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_PermissionRequested` + /// + function remove_PermissionRequested(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives `PermissionRequested` events. + /// + /// + /// See the ICoreWebView2FramePermissionRequestedEventHandler article. + /// + ICoreWebView2FramePermissionRequestedEventHandler = interface(IUnknown) + ['{845D0EDD-8BD8-429B-9915-4821789F23E9}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Frame; + const args: ICoreWebView2PermissionRequestedEventArgs2): HResult; stdcall; + end; + + /// + /// This is a continuation of the ICoreWebView2PermissionRequestedEventArgs interface. + /// + /// + /// See the ICoreWebView2PermissionRequestedEventArgs2 article. + /// + ICoreWebView2PermissionRequestedEventArgs2 = interface(ICoreWebView2PermissionRequestedEventArgs) + ['{74D7127F-9DE6-4200-8734-42D6FB4FF741}'] + /// + /// By default, both the `PermissionRequested` event handlers on the + /// `CoreWebView2Frame` and the `CoreWebView2` will be invoked, with the + /// `CoreWebView2Frame` event handlers invoked first. The host may + /// set this flag to `TRUE` within the `CoreWebView2Frame` event handlers + /// to prevent the remaining `CoreWebView2` event handlers from being invoked. + /// + /// If a deferral is taken on the event args, then you must synchronously + /// set `Handled` to TRUE prior to taking your deferral to prevent the + /// `CoreWebView2`s event handlers from being invoked. + /// + function Get_Handled(out value: Integer): HResult; stdcall; + /// + /// Sets the `Handled` property. + /// + function Set_Handled(value: Integer): HResult; stdcall; + end; + + /// + /// This is an extension of the ICoreWebView2Frame interface that supports shared buffer based on file mapping. + /// + /// + /// See the ICoreWebView2Frame4 article. + /// + ICoreWebView2Frame4 = interface(ICoreWebView2Frame3) + ['{188782DC-92AA-4732-AB3C-FCC59F6F68B9}'] + /// + /// Share a shared buffer object with script of the iframe in the WebView. + /// The script will receive a `sharedbufferreceived` event from chrome.webview. + /// The event arg for that event will have the following methods and properties: + /// `getBuffer()`: return an ArrayBuffer object with the backing content from the shared buffer. + /// `additionalData`: an object as the result of parsing `additionalDataAsJson` as JSON string. + /// This property will be `undefined` if `additionalDataAsJson` is nullptr or empty string. + /// `source`: with a value set as `chrome.webview` object. + /// If a string is provided as `additionalDataAsJson` but it is not a valid JSON string, + /// the API will fail with `E_INVALIDARG`. + /// If `access` is COREWEBVIEW2_SHARED_BUFFER_ACCESS_READ_ONLY, the script will only have read access to the buffer. + /// If the script tries to modify the content in a read only buffer, it will cause an access + /// violation in WebView renderer process and crash the renderer process. + /// If the shared buffer is already closed, the API will fail with `RO_E_CLOSED`. + /// + /// The script code should call `chrome.webview.releaseBuffer` with + /// the shared buffer as the parameter to release underlying resources as soon + /// as it does not need access to the shared buffer any more. + /// + /// The application can post the same shared buffer object to multiple web pages or iframes, or + /// post to the same web page or iframe multiple times. Each `PostSharedBufferToScript` will + /// create a separate ArrayBuffer object with its own view of the memory and is separately + /// released. The underlying shared memory will be released when all the views are released. + /// + /// For example, if we want to send data to script for one time read only consumption. + /// + /// \snippet ScenarioSharedBuffer.cpp OneTimeShareBuffer + /// + /// In the HTML document, + /// + /// \snippet assets\ScenarioSharedBuffer.html ShareBufferScriptCode_1 + /// + /// \snippet assets\ScenarioSharedBuffer.html ShareBufferScriptCode_2 + /// + /// Sharing a buffer to script has security risk. You should only share buffer with trusted site. + /// If a buffer is shared to a untrusted site, possible sensitive information could be leaked. + /// If a buffer is shared as modifiable by the script and the script modifies it in an unexpected way, + /// it could result in corrupted data that might even crash the application. + /// + function PostSharedBufferToScript(const sharedBuffer: ICoreWebView2SharedBuffer; + access: COREWEBVIEW2_SHARED_BUFFER_ACCESS; + additionalDataAsJson: PWideChar): HResult; stdcall; + end; + + /// + /// This is an extension of the ICoreWebView2Frame interface that provides the `FrameId` property. + /// + /// + /// See the ICoreWebView2Frame5 article. + /// + ICoreWebView2Frame5 = interface(ICoreWebView2Frame4) + ['{99D199C4-7305-11EE-B962-0242AC120002}'] + /// + /// The unique identifier of the current frame. It's the same kind of ID as + /// with the `FrameId` in `CoreWebView2` and via `CoreWebView2FrameInfo`. + /// + function Get_FrameId(out value: SYSUINT): HResult; stdcall; + end; + + /// + /// This is an extension of the ICoreWebView2Frame interface that supports ScreenCaptureStarting. + /// + /// + /// See the ICoreWebView2Frame6 article. + /// + ICoreWebView2Frame6 = interface(ICoreWebView2Frame5) + ['{0DE611FD-31E9-5DDC-9D71-95EDA26EFF32}'] + /// + /// Adds an event handler for the `ScreenCaptureStarting` event. + /// Add an event handler for the `ScreenCaptureStarting` event. + /// `ScreenCaptureStarting` is raised when content in an iframe or any of its + /// descendant iframes requests permission to use the Screen Capture + /// API from getDisplayMedia(). + /// + /// This relates to the `ScreenCaptureStarting` event on the + /// `CoreWebView2`. + /// Both these events will be raised in the case of an iframe requesting + /// screen capture. The `CoreWebView2Frame`'s event handlers will be invoked + /// before the event handlers on the `CoreWebView2`. If the `Handled` + /// property of the `ScreenCaptureStartingEventArgs` is set to TRUE + /// within the`CoreWebView2Frame` event handler, then the event will not + /// be raised on the `CoreWebView2`, and its event handlers will not be + /// invoked. + /// + /// \snippet ScenarioScreenCapture.cpp ScreenCaptureStarting1 + /// + function add_ScreenCaptureStarting(const eventHandler: ICoreWebView2FrameScreenCaptureStartingEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_ScreenCaptureStarting`. + /// + function remove_ScreenCaptureStarting(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives `ScreenCaptureStarting` events. + /// + /// + /// See the ICoreWebView2FrameScreenCaptureStartingEventHandler article. + /// + ICoreWebView2FrameScreenCaptureStartingEventHandler = interface(IUnknown) + ['{A6C1D8AD-BB80-59C5-895B-FBA1698B9309}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Frame; + const args: ICoreWebView2ScreenCaptureStartingEventArgs): HResult; stdcall; + end; + + /// + /// This is the `ICoreWebView2Frame` interface to support tracking + /// of nested iframes. + /// + /// + /// See the ICoreWebView2Frame7 article. + /// + ICoreWebView2Frame7 = interface(ICoreWebView2Frame6) + ['{3598CFA2-D85D-5A9F-9228-4DDE1F59EC64}'] + /// + /// Adds an event handler for the `FrameCreated` event. + /// Raised when a new direct descendant iframe is created. + /// Handle this event to get access to ICoreWebView2Frame objects. + /// Use `ICoreWebView2Frame.add_Destroyed` to listen for when this + /// iframe goes away. + /// + /// \snippet ScenarioWebViewEventMonitor.cpp FrameCreated + /// + function add_FrameCreated(const eventHandler: ICoreWebView2FrameChildFrameCreatedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_FrameCreated`. + /// + function remove_FrameCreated(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives `FrameCreated` events. + /// + /// + /// See the ICoreWebView2FrameChildFrameCreatedEventHandler article. + /// + ICoreWebView2FrameChildFrameCreatedEventHandler = interface(IUnknown) + ['{569E40E7-46B7-563D-83AE-1073155664D7}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Frame; const args: ICoreWebView2FrameCreatedEventArgs): HResult; stdcall; + end; + + /// + /// A continuation of the `ICoreWebView2Frame` interface to manage dedicated + /// workers. + /// + /// + /// See the ICoreWebView2Frame8 article. + /// + ICoreWebView2Frame8 = interface(ICoreWebView2Frame7) + ['{9DEFF655-E3D5-5B8F-9107-52E66B3EC3FC}'] + /// + /// Adds an event handler for the `DedicatedWorkerCreated` event. + /// Subscribe to this event that gets raised when a new dedicated worker is created + /// from an iframe. + /// + /// A Dedicated Worker is a type of web worker that allows you to run Javascript + /// code in the background without blocking the main thread, making them useful + /// for tasks like heavy computations, data processing, and parallel execution. + /// It is "dedicated" because it is linked to a single parent document and cannot + /// be shared with other scripts. + /// + /// This event is raised when a web application creates a dedicated worker using the + /// `new Worker("/worker.js")` method. See the + /// [Worker](https://developer.mozilla.org/docs/Web/API/Worker/Worker) + /// for more information. + /// + function add_DedicatedWorkerCreated(const eventHandler: ICoreWebView2FrameDedicatedWorkerCreatedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_DedicatedWorkerCreated`. + /// + function remove_DedicatedWorkerCreated(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives `DedicatedWorkerCreated` events. + /// + /// + /// See the ICoreWebView2FrameDedicatedWorkerCreatedEventHandler article. + /// + ICoreWebView2FrameDedicatedWorkerCreatedEventHandler = interface(IUnknown) + ['{3E28D307-9D58-5306-8097-A79301DE4F05}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Frame; + const args: ICoreWebView2DedicatedWorkerCreatedEventArgs): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2FrameInfo interface that provides + /// `ParentFrameInfo`, `FrameId` and `FrameKind` properties. + /// + /// + /// See the ICoreWebView2FrameInfo2 article. + /// + ICoreWebView2FrameInfo2 = interface(ICoreWebView2FrameInfo) + ['{56F85CFA-72C4-11EE-B962-0242AC120002}'] + /// + /// This parent frame's `FrameInfo`. `ParentFrameInfo` will only be + /// populated when obtained via calling + ///`CoreWebView2ProcessExtendedInfo.AssociatedFrameInfos`. + /// `CoreWebView2FrameInfo` objects obtained via `CoreWebView2.ProcessFailed` will + /// always have a `null` `ParentFrameInfo`. This property is also `null` for the + /// main frame in the WebView2 which has no parent frame. + /// Note that this `ParentFrameInfo` could be out of date as it's a snapshot. + /// + function Get_ParentFrameInfo(out frameInfo: ICoreWebView2FrameInfo): HResult; stdcall; + /// + /// The unique identifier of the frame associated with the current `FrameInfo`. + /// It's the same kind of ID as with the `FrameId` in `CoreWebView2` and via + /// `CoreWebView2Frame`. `FrameId` will only be populated (non-zero) when obtained + /// calling `CoreWebView2ProcessExtendedInfo.AssociatedFrameInfos`. + /// `CoreWebView2FrameInfo` objects obtained via `CoreWebView2.ProcessFailed` will + /// always have an invalid frame Id 0. + /// Note that this `FrameId` could be out of date as it's a snapshot. + /// If there's WebView2 created or destroyed or `FrameCreated/FrameDestroyed` events + /// after the asynchronous call `CoreWebView2Environment.GetProcessExtendedInfos` + /// starts, you may want to call asynchronous method again to get the updated `FrameInfo`s. + /// + function Get_FrameId(out id: SYSUINT): HResult; stdcall; + /// + /// The frame kind of the frame. `FrameKind` will only be populated when + /// obtained calling `CoreWebView2ProcessExtendedInfo.AssociatedFrameInfos`. + /// `CoreWebView2FrameInfo` objects obtained via `CoreWebView2.ProcessFailed` + /// will always have the default value `COREWEBVIEW2_FRAME_KIND_UNKNOWN`. + /// Note that this `FrameKind` could be out of date as it's a snapshot. + /// + function Get_FrameKind(out Kind: COREWEBVIEW2_FRAME_KIND): HResult; stdcall; + end; + + /// + /// Receives the result of the `GetNonDefaultPermissionSettings` method. + /// + /// + /// See the ICoreWebView2GetNonDefaultPermissionSettingsCompletedHandler article. + /// + ICoreWebView2GetNonDefaultPermissionSettingsCompletedHandler = interface(IUnknown) + ['{38274481-A15C-4563-94CF-990EDC9AEB95}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; const result_: ICoreWebView2PermissionSettingCollectionView): HResult; stdcall; + end; + + /// + /// Read-only collection of PermissionSettings (origin, kind, and state). Used to list + /// the nondefault permission settings on the profile that are persisted across + /// sessions. + /// + /// + /// See the ICoreWebView2PermissionSettingCollectionView article. + /// + ICoreWebView2PermissionSettingCollectionView = interface(IUnknown) + ['{F5596F62-3DE5-47B1-91E8-A4104B596B96}'] + /// + /// Gets the `ICoreWebView2PermissionSetting` at the specified index. + /// + function GetValueAtIndex(index: SYSUINT; out permissionSetting: ICoreWebView2PermissionSetting): HResult; stdcall; + /// + /// The number of `ICoreWebView2PermissionSetting`s in the collection. + /// + function Get_Count(out value: SYSUINT): HResult; stdcall; + end; + + /// + /// Provides a set of properties for a permission setting. + /// + /// + /// See the ICoreWebView2PermissionSetting article. + /// + ICoreWebView2PermissionSetting = interface(IUnknown) + ['{792B6ECA-5576-421C-9119-74EBB3A4FFB3}'] + /// + /// The kind of the permission setting. See `COREWEBVIEW2_PERMISSION_KIND` for + /// more details. + /// + function Get_PermissionKind(out value: COREWEBVIEW2_PERMISSION_KIND): HResult; stdcall; + /// + /// The origin of the permission setting. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_PermissionOrigin(out value: PWideChar): HResult; stdcall; + /// + /// The state of the permission setting. + /// + function Get_PermissionState(out value: COREWEBVIEW2_PERMISSION_STATE): HResult; stdcall; + end; + + /// + /// This is an interface for the StatusCode property of + /// ICoreWebView2NavigationCompletedEventArgs + /// + /// + /// See the ICoreWebView2NavigationCompletedEventArgs2 article. + /// + ICoreWebView2NavigationCompletedEventArgs2 = interface(ICoreWebView2NavigationCompletedEventArgs) + ['{FDF8B738-EE1E-4DB2-A329-8D7D7B74D792}'] + /// + /// The HTTP status code of the navigation if it involved an HTTP request. + /// For instance, this will usually be 200 if the request was successful, 404 + /// if a page was not found, etc. See + /// https://developer.mozilla.org/docs/Web/HTTP/Status for a list of + /// common status codes. + /// + /// The `HttpStatusCode` property will be 0 in the following cases: + /// * The navigation did not involve an HTTP request. For instance, if it was + /// a navigation to a file:// URL, or if it was a same-document navigation. + /// * The navigation failed before a response was received. For instance, if + /// the hostname was not found, or if there was a network error. + /// + /// In those cases, you can get more information from the `IsSuccess` and + /// `WebErrorStatus` properties. + /// + /// If the navigation receives a successful HTTP response, but the navigated + /// page calls `window.stop()` before it finishes loading, then + /// `HttpStatusCode` may contain a success code like 200, but `IsSuccess` will + /// be FALSE and `WebErrorStatus` will be + /// `COREWEBVIEW2_WEB_ERROR_STATUS_CONNECTION_ABORTED`. + /// + /// Since WebView2 handles HTTP continuations and redirects automatically, it + /// is unlikely for `HttpStatusCode` to ever be in the 1xx or 3xx ranges. + /// + function Get_HttpStatusCode(out value: SYSINT): HResult; stdcall; + end; + + /// + /// The AdditionalAllowedFrameAncestors API that enable developers to provide additional allowed frame ancestors. + /// + /// + /// See the ICoreWebView2NavigationStartingEventArgs2 article. + /// + ICoreWebView2NavigationStartingEventArgs2 = interface(ICoreWebView2NavigationStartingEventArgs) + ['{9086BE93-91AA-472D-A7E0-579F2BA006AD}'] + /// + /// Get additional allowed frame ancestors set by the host app. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_AdditionalAllowedFrameAncestors(out value: PWideChar): HResult; stdcall; + /// + /// The app may set this property to allow a frame to be embedded by additional ancestors besides what is allowed by + /// http header [X-Frame-Options](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Frame-Options) + /// and [Content-Security-Policy frame-ancestors directive](https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors). + /// If set, a frame ancestor is allowed if it is allowed by the additional allowed frame + /// ancestors or original http header from the site. + /// Whether an ancestor is allowed by the additional allowed frame ancestors is done the same way as if the site provided + /// it as the source list of the Content-Security-Policy frame-ancestors directive. + /// For example, if `https://example.com` and `https://www.example.com` are the origins of the top + /// page and intermediate iframes that embed a nested site-embedding iframe, and you fully trust + /// those origins, you should set this property to `https://example.com https://www.example.com`. + /// This property gives the app the ability to use iframe to embed sites that otherwise + /// could not be embedded in an iframe in trusted app pages. + /// This could potentially subject the embedded sites to [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking) + /// attack from the code running in the embedding web page. Therefore, you should only + /// set this property with origins of fully trusted embedding page and any intermediate iframes. + /// Whenever possible, you should use the list of specific origins of the top and intermediate + /// frames instead of wildcard characters for this property. + /// This API is to provide limited support for app scenarios that used to be supported by + /// `` element in other solutions like JavaScript UWP apps and Electron. + /// You should limit the usage of this property to trusted pages, and specific navigation + /// target url, by checking the `Source` of the WebView2, and `Uri` of the event args. + /// + /// This property is ignored for top level document navigation. + /// + /// \snippet ScriptComponent.cpp AdditionalAllowedFrameAncestors_1 + /// + /// \snippet ScriptComponent.cpp AdditionalAllowedFrameAncestors_2 + /// + function Set_AdditionalAllowedFrameAncestors(value: PWideChar): HResult; stdcall; + end; + + /// + /// The NavigationKind API that enables developers to get more information about + /// navigation type. + /// + /// + /// See the ICoreWebView2NavigationStartingEventArgs3 article. + /// + ICoreWebView2NavigationStartingEventArgs3 = interface(ICoreWebView2NavigationStartingEventArgs2) + ['{DDFFE494-4942-4BD2-AB73-35B8FF40E19F}'] + /// + /// Get the navigation kind of this navigation. + /// + function Get_NavigationKind(out value: COREWEBVIEW2_NAVIGATION_KIND): HResult; stdcall; + end; + + /// + /// This is a continuation of the ICoreWebView2NewWindowRequestedEventArgs interface. + /// + /// + /// See the ICoreWebView2NewWindowRequestedEventArgs2 article. + /// + ICoreWebView2NewWindowRequestedEventArgs2 = interface(ICoreWebView2NewWindowRequestedEventArgs) + ['{BBC7BAED-74C6-4C92-B63A-7F5AEAE03DE3}'] + /// + /// Gets the name of the new window. This window can be created via `window.open(url, windowName)`, + /// where the windowName parameter corresponds to `Name` property. + /// If no windowName is passed to `window.open`, then the `Name` property + /// will be set to an empty string. Additionally, if window is opened through other means, + /// such as `...` or ``, + /// then the `Name` property will be set accordingly. In the case of target=_blank, + /// the `Name` property will be an empty string. + /// Opening a window via ctrl+clicking a link would result in the `Name` property + /// being set to an empty string. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_name(out value: PWideChar): HResult; stdcall; + end; + + /// + /// This is a continuation of the ICoreWebView2NewWindowRequestedEventArgs interface. + /// + /// + /// See the ICoreWebView2NewWindowRequestedEventArgs3 article. + /// + ICoreWebView2NewWindowRequestedEventArgs3 = interface(ICoreWebView2NewWindowRequestedEventArgs2) + ['{842BED3C-6AD6-4DD9-B938-28C96667AD66}'] + /// + /// The frame info of the frame where the new window request originated. The + /// `OriginalSourceFrameInfo` is a snapshot of frame information at the time when the + /// new window was requested. See `ICoreWebView2FrameInfo` for details on frame + /// properties. + /// + function Get_OriginalSourceFrameInfo(out value: ICoreWebView2FrameInfo): HResult; stdcall; + end; + + /// + /// This is a continuation of the ICoreWebView2PermissionRequestedEventArgs + /// interface. + /// + /// + /// See the ICoreWebView2PermissionRequestedEventArgs3 article. + /// + ICoreWebView2PermissionRequestedEventArgs3 = interface(ICoreWebView2PermissionRequestedEventArgs2) + ['{E61670BC-3DCE-4177-86D2-C629AE3CB6AC}'] + /// + /// The permission state set from the `PermissionRequested` event is saved in + /// the profile by default; it persists across sessions and becomes the new + /// default behavior for future `PermissionRequested` events. Browser + /// heuristics can affect whether the event continues to be raised when the + /// state is saved in the profile. Set the `SavesInProfile` property to + /// `FALSE` to not persist the state beyond the current request, and to + /// continue to receive `PermissionRequested` + /// events for this origin and permission kind. + /// + function Get_SavesInProfile(out value: Integer): HResult; stdcall; + /// + /// Sets the `SavesInProfile` property. + /// + function Set_SavesInProfile(value: Integer): HResult; stdcall; + end; + + /// + /// Settings used by the Print method. + /// + /// + /// See the ICoreWebView2PrintSettings2 article. + /// + ICoreWebView2PrintSettings2 = interface(ICoreWebView2PrintSettings) + ['{CA7F0E1F-3484-41D1-8C1A-65CD44A63F8D}'] + /// + /// Page range to print. Defaults to empty string, which means print all pages. + /// If the Page range is empty string or null, then it applies the default. + /// + /// The PageRanges property is a list of page ranges specifying one or more pages that + /// should be printed separated by commas. Any whitespace between page ranges is ignored. + /// A valid page range is either a single integer identifying the page to print, or a range + /// in the form `[start page]-[last page]` where `start page` and `last page` are integers + /// identifying the first and last inclusive pages respectively to print. + /// Every page identifier is an integer greater than 0 unless wildcards are used (see below examples). + /// The first page is 1. + /// + /// In a page range of the form `[start page]-[last page]` the start page number must be + /// larger than 0 and less than or equal to the document's total page count. + /// If the `start page` is not present, then 1 is used as the `start page`. + /// The `last page` must be larger than the `start page`. + /// If the `last page` is not present, then the document total page count is used as the `last page`. + /// + /// Repeating a page does not print it multiple times. To print multiple times, use the `Copies` property. + /// + /// The pages are always printed in ascending order, even if specified in non-ascending order. + /// + /// If page range is not valid or if a page is greater than document total page count, + /// `ICoreWebView2PrintCompletedHandler` or `ICoreWebView2PrintToPdfStreamCompletedHandler` + /// handler will return `E_INVALIDARG`. + /// + /// The following examples assume a document with 20 total pages. + /// + /// | Example | Result | Notes | + /// | --- | --- | --- | + /// | "2" | Page 2 | | + /// | "1-4, 9, 3-6, 10, 11" | Pages 1-6, 9-11 | | + /// | "1-4, -6" | Pages 1-6 | The "-6" is interpreted as "1-6". | + /// | "2-" | Pages 2-20 | The "2-" is interpreted as "pages 2 to the end of the document". | + /// | "4-2, 11, -6" | Invalid | "4-2" is an invalid range. | + /// | "-" | Pages 1-20 | The "-" is interpreted as "page 1 to the end of the document". | + /// | "1-4dsf, 11" | Invalid | | + /// | "2-2" | Page 2 | | + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings) + /// + function Get_PageRanges(out value: PWideChar): HResult; stdcall; + /// + /// Set the `PageRanges` property. + /// + function Set_PageRanges(value: PWideChar): HResult; stdcall; + /// + /// Prints multiple pages of a document on a single piece of paper. Choose from 1, 2, 4, 6, 9 or 16. + /// The default value is 1. + /// + function Get_PagesPerSide(out value: SYSINT): HResult; stdcall; + /// + /// Set the `PagesPerSide` property. Returns `E_INVALIDARG` if an invalid value is + /// provided, and the current value is not changed. + /// + /// Below examples shows print output for PagesPerSide and Duplex. + /// + /// | PagesPerSide | Total pages | Two-sided printing | Result | + /// | --- | --- | --- | --- | + /// | 1 | 1 | - | 1 page on the front side. | + /// | 2 | 1 | Yes | 1 page on the front side. | + /// | 2 | 4 | - | 2 pages on the first paper and 2 pages on the next paper. | + /// | 2 | 4 | Yes | 2 pages on the front side and 2 pages on back side. | + /// | 4 | 4 | Yes | 4 pages on the front side. | + /// | 4 | 8 | Yes | 4 pages on the front side and 4 pages on the back side. | + /// + function Set_PagesPerSide(value: SYSINT): HResult; stdcall; + /// + /// Number of copies to print. Minimum value is `1` and the maximum copies count is `999`. + /// The default value is 1. + /// + /// This value is ignored in PrintToPdfStream method. + /// + function Get_Copies(out value: SYSINT): HResult; stdcall; + /// + /// Set the `Copies` property. Returns `E_INVALIDARG` if an invalid value is provided + /// and the current value is not changed. + /// + function Set_Copies(value: SYSINT): HResult; stdcall; + /// + /// Printer collation. See `COREWEBVIEW2_PRINT_COLLATION` for descriptions of + /// collation. The default value is `COREWEBVIEW2_PRINT_COLLATION_DEFAULT`. + /// + /// Printing uses default value of printer's collation if an invalid value is provided + /// for the specific printer. + /// + /// This value is ignored in PrintToPdfStream method. + /// + function Get_Collation(out value: COREWEBVIEW2_PRINT_COLLATION): HResult; stdcall; + /// + /// Set the `Collation` property. + /// + function Set_Collation(value: COREWEBVIEW2_PRINT_COLLATION): HResult; stdcall; + /// + /// Printer color mode. See `COREWEBVIEW2_PRINT_COLOR_MODE` for descriptions + /// of color modes. The default value is `COREWEBVIEW2_PRINT_COLOR_MODE_DEFAULT`. + /// + /// Printing uses default value of printer supported color if an invalid value is provided + /// for the specific printer. + /// + function Get_ColorMode(out value: COREWEBVIEW2_PRINT_COLOR_MODE): HResult; stdcall; + /// + /// Set the `ColorMode` property. + /// + function Set_ColorMode(value: COREWEBVIEW2_PRINT_COLOR_MODE): HResult; stdcall; + /// + /// Printer duplex settings. See `COREWEBVIEW2_PRINT_DUPLEX` for descriptions of duplex. + /// The default value is `COREWEBVIEW2_PRINT_DUPLEX_DEFAULT`. + /// + /// Printing uses default value of printer's duplex if an invalid value is provided + /// for the specific printer. + /// + /// This value is ignored in PrintToPdfStream method. + /// + function Get_Duplex(out value: COREWEBVIEW2_PRINT_DUPLEX): HResult; stdcall; + /// + /// Set the `Duplex` property. + /// + function Set_Duplex(value: COREWEBVIEW2_PRINT_DUPLEX): HResult; stdcall; + /// + /// Printer media size. See `COREWEBVIEW2_PRINT_MEDIA_SIZE` for descriptions of media size. + /// The default value is `COREWEBVIEW2_PRINT_MEDIA_SIZE_DEFAULT`. + /// + /// If media size is `COREWEBVIEW2_PRINT_MEDIA_SIZE_CUSTOM`, you should set the `PageWidth` + /// and `PageHeight`. + /// + /// Printing uses default value of printer supported media size if an invalid value is provided + /// for the specific printer. + /// + /// This value is ignored in PrintToPdfStream method. + /// + function Get_MediaSize(out value: COREWEBVIEW2_PRINT_MEDIA_SIZE): HResult; stdcall; + /// + /// Set the `MediaSize` property. + /// + function Set_MediaSize(value: COREWEBVIEW2_PRINT_MEDIA_SIZE): HResult; stdcall; + /// + /// The name of the printer to use. Defaults to empty string. + /// If the printer name is empty string or null, then it prints to the default + /// printer on the user OS. + /// + /// This value is ignored in PrintToPdfStream method. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings) + /// + function Get_PrinterName(out value: PWideChar): HResult; stdcall; + /// + /// Set the `PrinterName` property. If provided printer name doesn't match + /// with the name of any installed printers on the user OS, + /// `ICoreWebView2PrintCompletedHandler` handler will return `errorCode` as + /// `S_OK` and `printStatus` as COREWEBVIEW2_PRINT_STATUS_PRINTER_UNAVAILABLE. + /// + /// Use [Enum Printers](/windows/win32/printdocs/enumprinters) + /// to enumerate available printers. + /// + function Set_PrinterName(value: PWideChar): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2ProcessFailedEventArgs interface. + /// + /// + /// See the ICoreWebView2ProcessFailedEventArgs2 article. + /// + ICoreWebView2ProcessFailedEventArgs2 = interface(ICoreWebView2ProcessFailedEventArgs) + ['{4DAB9422-46FA-4C3E-A5D2-41D2071D3680}'] + /// + /// The reason for the process failure. Some of the reasons are only + /// applicable to specific values of + /// `ICoreWebView2ProcessFailedEventArgs::ProcessFailedKind`, and the + /// following `ProcessFailedKind` values always return the indicated reason + /// value: + /// + /// ProcessFailedKind | Reason + /// ---|--- + /// COREWEBVIEW2_PROCESS_FAILED_KIND_BROWSER_PROCESS_EXITED | COREWEBVIEW2_PROCESS_FAILED_REASON_UNEXPECTED + /// COREWEBVIEW2_PROCESS_FAILED_KIND_RENDER_PROCESS_UNRESPONSIVE | COREWEBVIEW2_PROCESS_FAILED_REASON_UNRESPONSIVE + /// + /// For other `ProcessFailedKind` values, the reason may be any of the reason + /// values. To learn about what these values mean, see + /// `COREWEBVIEW2_PROCESS_FAILED_REASON`. + /// + function Get_reason(out reason: COREWEBVIEW2_PROCESS_FAILED_REASON): HResult; stdcall; + /// + /// The exit code of the failing process, for telemetry purposes. The exit + /// code is always `STILL_ACTIVE` (`259`) when `ProcessFailedKind` is + /// `COREWEBVIEW2_PROCESS_FAILED_KIND_RENDER_PROCESS_UNRESPONSIVE`. + /// + function Get_ExitCode(out ExitCode: SYSINT): HResult; stdcall; + /// + /// Description of the process assigned by the WebView2 Runtime. This is a + /// technical English term appropriate for logging or development purposes, + /// and not localized for the end user. It applies to utility processes (for + /// example, "Audio Service", "Video Capture") and plugin processes (for + /// example, "Flash"). The returned `processDescription` is empty if the + /// WebView2 Runtime did not assign a description to the process. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_ProcessDescription(out ProcessDescription: PWideChar): HResult; stdcall; + /// + /// The collection of `FrameInfo`s for frames in the `ICoreWebView2` that were + /// being rendered by the failed process. The content in these frames is + /// replaced with an error page. + /// This is only available when `ProcessFailedKind` is + /// `COREWEBVIEW2_PROCESS_FAILED_KIND_FRAME_RENDER_PROCESS_EXITED`; + /// `frames` is `null` for all other process failure kinds, including the case + /// in which the failed process was the renderer for the main frame and + /// subframes within it, for which the failure kind is + /// `COREWEBVIEW2_PROCESS_FAILED_KIND_RENDER_PROCESS_EXITED`. + /// + function Get_FrameInfosForFailedProcess(out frames: ICoreWebView2FrameInfoCollection): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2ProcessFailedEventArgs2 interface + /// for getting blocked file for code integrity process failures. + /// + /// + /// See the icorewebview2processfailedeventargs3 article. + /// + ICoreWebView2ProcessFailedEventArgs3 = interface(ICoreWebView2ProcessFailedEventArgs2) + ['{AB667428-094D-5FD1-B480-8B4C0FDBDF2F}'] + /// + /// This property is the full path of the module that caused the + /// crash in cases of Windows Code Integrity failures. + /// [Windows Code Integrity](/mem/intune/user-help/you-need-to-enable-code-integrity) + /// is a feature that verifies the integrity and + /// authenticity of dynamic-link libraries (DLLs) + /// on Windows systems. It ensures that only trusted + /// code can run on the system and prevents unauthorized or + /// malicious modifications. + /// When ProcessFailed occurred due to a failed Code Integrity check, + /// this property returns the full path of the file that was prevented from + /// loading on the system. + /// The webview2 process which tried to load the DLL will fail with + /// exit code STATUS_INVALID_IMAGE_HASH(-1073740760). + /// A file can fail integrity check for various + /// reasons, such as: + /// - It has an invalid or missing signature that does + /// not match the publisher or signer of the file. + /// - It has been tampered with or corrupted by malware or other software. + /// - It has been blocked by an administrator or a security policy. + /// This property always will be the empty string if failure is not caused by + /// STATUS_INVALID_IMAGE_HASH. + /// + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_FailureSourceModulePath(out value: PWideChar): HResult; stdcall; + end; + + /// + /// Profile2 interface. + /// + /// + /// See the ICoreWebView2Profile2 article. + /// + ICoreWebView2Profile2 = interface(ICoreWebView2Profile) + ['{FA740D4B-5EAE-4344-A8AD-74BE31925397}'] + /// + /// Clear browsing data based on a data type. This method takes two parameters, + /// the first being a mask of one or more `COREWEBVIEW2_BROWSING_DATA_KINDS`. OR + /// operation(s) can be applied to multiple `COREWEBVIEW2_BROWSING_DATA_KINDS` to + /// create a mask representing those data types. The browsing data kinds that are + /// supported are listed below. These data kinds follow a hierarchical structure in + /// which nested bullet points are included in their parent bullet point's data kind. + /// Ex: All DOM storage is encompassed in all site data which is encompassed in + /// all profile data. + /// + /// * All Profile + /// * All Site Data + /// * All DOM Storage: File Systems, Indexed DB, Local Storage, Web SQL, Cache + /// Storage + /// * Cookies + /// * Disk Cache + /// * Download History + /// * General Autofill + /// * Password Autosave + /// * Browsing History + /// * Settings + /// + /// The completed handler will be invoked when the browsing data has been cleared and + /// will indicate if the specified data was properly cleared. In the case in which + /// the operation is interrupted and the corresponding data is not fully cleared + /// the handler will return `E_ABORT` and otherwise will return `S_OK`. + /// Because this is an asynchronous operation, code that is dependent on the cleared + /// data must be placed in the callback of this operation. + /// If the WebView object is closed before the clear browsing data operation + /// has completed, the handler will be released, but not invoked. In this case + /// the clear browsing data operation may or may not be completed. + /// ClearBrowsingData clears the `dataKinds` regardless of timestamp. + /// + function ClearBrowsingData(dataKinds: COREWEBVIEW2_BROWSING_DATA_KINDS; + const handler: ICoreWebView2ClearBrowsingDataCompletedHandler): HResult; stdcall; + /// + /// ClearBrowsingDataInTimeRange behaves like ClearBrowsingData except that it + /// takes in two additional parameters for the start and end time for which it + /// should clear the data between. The `startTime` and `endTime` + /// parameters correspond to the number of seconds since the UNIX epoch. + /// `startTime` is inclusive while `endTime` is exclusive, therefore the data will + /// be cleared between [startTime, endTime). + /// + function ClearBrowsingDataInTimeRange(dataKinds: COREWEBVIEW2_BROWSING_DATA_KINDS; + startTime: Double; endTime: Double; + const handler: ICoreWebView2ClearBrowsingDataCompletedHandler): HResult; stdcall; + /// + /// ClearBrowsingDataAll behaves like ClearBrowsingData except that it + /// clears the entirety of the data associated with the profile it is called on. + /// It clears the data regardless of timestamp. + /// + /// \snippet AppWindow.cpp ClearBrowsingData + /// + function ClearBrowsingDataAll(const handler: ICoreWebView2ClearBrowsingDataCompletedHandler): HResult; stdcall; + end; + + /// + /// This is an extension of the ICoreWebView2Profile interface to control levels of tracking prevention. + /// + /// + /// See the ICoreWebView2Profile3 article. + /// + ICoreWebView2Profile3 = interface(ICoreWebView2Profile2) + ['{B188E659-5685-4E05-BDBA-FC640E0F1992}'] + /// + /// The `PreferredTrackingPreventionLevel` property allows you to control levels of tracking prevention for WebView2 + /// which are associated with a profile. This level would apply to the context of the profile. That is, all WebView2s + /// sharing the same profile will be affected and also the value is persisted in the user data folder. + /// + /// See `COREWEBVIEW2_TRACKING_PREVENTION_LEVEL` for descriptions of levels. + /// + /// If tracking prevention feature is enabled when creating the WebView2 environment, you can also disable tracking + /// prevention later using this property and `COREWEBVIEW2_TRACKING_PREVENTION_LEVEL_NONE` value but that doesn't + /// improves runtime performance. + /// + /// There is `ICoreWebView2EnvironmentOptions5::EnableTrackingPrevention` property to enable/disable tracking prevention feature + /// for all the WebView2's created in the same environment. If enabled, `PreferredTrackingPreventionLevel` is set to + /// `COREWEBVIEW2_TRACKING_PREVENTION_LEVEL_BALANCED` by default for all the WebView2's and profiles created in the same + /// environment or is set to the level whatever value was last changed/persisted to the profile. If disabled + /// `PreferredTrackingPreventionLevel` is not respected by WebView2. If `PreferredTrackingPreventionLevel` is set when the + /// feature is disabled, the property value get changed and persisted but it will takes effect only if + /// `ICoreWebView2EnvironmentOptions5::EnableTrackingPrevention` is true. + /// + /// See `ICoreWebView2EnvironmentOptions5::EnableTrackingPrevention` for more details. + /// \snippet SettingsComponent.cpp SetTrackingPreventionLevel + /// + function Get_PreferredTrackingPreventionLevel(out value: COREWEBVIEW2_TRACKING_PREVENTION_LEVEL): HResult; stdcall; + /// + /// Set the `PreferredTrackingPreventionLevel` property. + /// + /// If `ICoreWebView2EnvironmentOptions5::EnableTrackingPrevention` is false, this property will be changed and persisted + /// to the profile but the WebView2 ignores the level silently. + /// + function Set_PreferredTrackingPreventionLevel(value: COREWEBVIEW2_TRACKING_PREVENTION_LEVEL): HResult; stdcall; + end; + + /// + /// This is the ICoreWebView2Profile interface for the permission management APIs. + /// + /// + /// See the ICoreWebView2Profile4 article. + /// + ICoreWebView2Profile4 = interface(ICoreWebView2Profile3) + ['{8F4AE680-192E-4EC8-833A-21CFADAEF628}'] + /// + /// Sets permission state for the given permission kind and origin + /// asynchronously. The change persists across sessions until it is changed by + /// another call to `SetPermissionState`, or by setting the `State` property + /// in `PermissionRequestedEventArgs`. Setting the state to + /// `COREWEBVIEW2_PERMISSION_STATE_DEFAULT` will erase any state saved in the + /// profile and restore the default behavior. + /// The origin should have a valid scheme and host (e.g. "https://www.example.com"), + /// otherwise the method fails with `E_INVALIDARG`. Additional URI parts like + /// path and fragment are ignored. For example, "https://wwww.example.com/app1/index.html/" + /// is treated the same as "https://wwww.example.com". See the + /// [MDN origin definition](https://developer.mozilla.org/docs/Glossary/Origin) + /// for more details. + /// + /// \snippet ScenarioPermissionManagement.cpp SetPermissionState + /// + function SetPermissionState(PermissionKind: COREWEBVIEW2_PERMISSION_KIND; origin: PWideChar; + State: COREWEBVIEW2_PERMISSION_STATE; + const handler: ICoreWebView2SetPermissionStateCompletedHandler): HResult; stdcall; + /// + /// Invokes the handler with a collection of all nondefault permission settings. + /// Use this method to get the permission state set in the current and previous + /// sessions. + /// + /// \snippet ScenarioPermissionManagement.cpp GetNonDefaultPermissionSettings + /// + function GetNonDefaultPermissionSettings(const handler: ICoreWebView2GetNonDefaultPermissionSettingsCompletedHandler): HResult; stdcall; + end; + + /// + /// Receives the result of the `SetPermissionState` method. + /// + /// + /// See the ICoreWebView2SetPermissionStateCompletedHandler article. + /// + ICoreWebView2SetPermissionStateCompletedHandler = interface(IUnknown) + ['{FC77FB30-9C9E-4076-B8C7-7644A703CA1B}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult): HResult; stdcall; + end; + + /// + /// This is the ICoreWebView2Profile interface for cookie manager. + /// + /// + /// See the ICoreWebView2Profile5 article. + /// + ICoreWebView2Profile5 = interface(ICoreWebView2Profile4) + ['{2EE5B76E-6E80-4DF2-BCD3-D4EC3340A01B}'] + /// + /// Get the cookie manager for the profile. All CoreWebView2s associated with this + /// profile share the same cookie values. Changes to cookies in this cookie manager apply to all + /// CoreWebView2s associated with this profile. + /// See ICoreWebView2CookieManager. + /// + /// \snippet ScenarioCookieManagement.cpp CookieManagerProfile + /// + function Get_CookieManager(out value: ICoreWebView2CookieManager): HResult; stdcall; + end; + + /// + /// Interfaces in profile for managing password-autosave and general-autofill. + /// + /// + /// See the ICoreWebView2Profile6 article. + /// + ICoreWebView2Profile6 = interface(ICoreWebView2Profile5) + ['{BD82FA6A-1D65-4C33-B2B4-0393020CC61B}'] + /// + /// IsPasswordAutosaveEnabled controls whether autosave for password + /// information is enabled. The IsPasswordAutosaveEnabled property behaves + /// independently of the IsGeneralAutofillEnabled property. When IsPasswordAutosaveEnabled is + /// false, no new password data is saved and no Save/Update Password prompts are displayed. + /// However, if there was password data already saved before disabling this setting, + /// then that password information is auto-populated, suggestions are shown and clicking on + /// one will populate the fields. + /// When IsPasswordAutosaveEnabled is true, password information is auto-populated, + /// suggestions are shown and clicking on one will populate the fields, new data + /// is saved, and a Save/Update Password prompt is displayed. + /// It will take effect immediately after setting. + /// The default value is `FALSE`. + /// This property has the same value as + /// `CoreWebView2Settings.IsPasswordAutosaveEnabled`, and changing one will + /// change the other. All `CoreWebView2`s with the same `CoreWebView2Profile` + /// will share the same value for this property, so for the `CoreWebView2`s + /// with the same profile, their + /// `CoreWebView2Settings.IsPasswordAutosaveEnabled` and + /// `CoreWebView2Profile.IsPasswordAutosaveEnabled` will always have the same + /// value. + /// + /// \snippet SettingsComponent.cpp ToggleProfilePasswordAutosaveEnabled + /// + function Get_IsPasswordAutosaveEnabled(out value: Integer): HResult; stdcall; + /// + /// Set the IsPasswordAutosaveEnabled property. + /// + function Set_IsPasswordAutosaveEnabled(value: Integer): HResult; stdcall; + /// + /// IsGeneralAutofillEnabled controls whether autofill for information + /// like names, street and email addresses, phone numbers, and arbitrary input + /// is enabled. This excludes password and credit card information. When + /// IsGeneralAutofillEnabled is false, no suggestions appear, and no new information + /// is saved. When IsGeneralAutofillEnabled is true, information is saved, suggestions + /// appear and clicking on one will populate the form fields. + /// It will take effect immediately after setting. + /// The default value is `TRUE`. + /// This property has the same value as + /// `CoreWebView2Settings.IsGeneralAutofillEnabled`, and changing one will + /// change the other. All `CoreWebView2`s with the same `CoreWebView2Profile` + /// will share the same value for this property, so for the `CoreWebView2`s + /// with the same profile, their + /// `CoreWebView2Settings.IsGeneralAutofillEnabled` and + /// `CoreWebView2Profile.IsGeneralAutofillEnabled` will always have the same + /// value. + /// + /// \snippet SettingsComponent.cpp ToggleProfileGeneralAutofillEnabled + /// + function Get_IsGeneralAutofillEnabled(out value: Integer): HResult; stdcall; + /// + /// Set the IsGeneralAutofillEnabled property. + /// + function Set_IsGeneralAutofillEnabled(value: Integer): HResult; stdcall; + end; + + /// + /// Interfaces in profile for managing browser extensions. + /// + /// + /// See the ICoreWebView2Profile7 article. + /// + ICoreWebView2Profile7 = interface(ICoreWebView2Profile6) + ['{7B4C7906-A1AA-4CB4-B723-DB09F813D541}'] + /// + /// Adds the [browser extension](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions) + /// using the extension path for unpacked extensions from the local device. Extension is + /// running right after installation. + /// The extension folder path is the topmost folder of an unpacked browser extension and + /// contains the browser extension manifest file. + /// If the `extensionFolderPath` is an invalid path or doesn't contain the extension manifest.json + /// file, this function will return `ERROR_FILE_NOT_FOUND` to callers. + /// Installed extension will default `IsEnabled` to true. + /// When `AreBrowserExtensionsEnabled` is `FALSE`, `AddBrowserExtension` will fail and return + /// HRESULT `ERROR_NOT_SUPPORTED`. + /// During installation, the content of the extension is not copied to the user data folder. + /// Once the extension is installed, changing the content of the extension will cause the + /// extension to be removed from the installed profile. + /// When an extension is added the extension is persisted in the corresponding profile. The + /// extension will still be installed the next time you use this profile. + /// When an extension is installed from a folder path, adding the same extension from the same + /// folder path means reinstalling this extension. When two extensions with the same Id are + /// installed, only the later installed extension will be kept. + /// + /// Extensions that are designed to include any UI interactions (e.g. icon, badge, pop up, etc.) + /// can be loaded and used but will have missing UI entry points due to the lack of browser + /// UI elements to host these entry points in WebView2. + /// + /// The following summarizes the possible error values that can be returned from + /// `AddBrowserExtension` and a description of why these errors occur. + /// + /// Error value | Description + /// ----------------------------------------------- | -------------------------- + /// `HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)` | Extensions are disabled. + /// `HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)` | Cannot find `manifest.json` file or it is not a valid extension manifest. + /// `E_ACCESSDENIED` | Cannot load extension with file or directory name starting with \"_\", reserved for use by the system. + /// `E_FAIL` | Extension failed to install with other unknown reasons. + /// + function AddBrowserExtension(extensionFolderPath: PWideChar; + const handler: ICoreWebView2ProfileAddBrowserExtensionCompletedHandler): HResult; stdcall; + /// + /// Gets a snapshot of the set of extensions installed at the time `GetBrowserExtensions` is + /// called. If an extension is installed or uninstalled after `GetBrowserExtensions` completes, + /// the list returned by `GetBrowserExtensions` remains the same. + /// When `AreBrowserExtensionsEnabled` is `FALSE`, `GetBrowserExtensions` won't return any + /// extensions on current user profile. + /// + function GetBrowserExtensions(const handler: ICoreWebView2ProfileGetBrowserExtensionsCompletedHandler): HResult; stdcall; + end; + + /// + /// Receives the result of the `AddBrowserExtension` method. + /// + /// + /// See the ICoreWebView2ProfileAddBrowserExtensionCompletedHandler article. + /// + ICoreWebView2ProfileAddBrowserExtensionCompletedHandler = interface(IUnknown) + ['{DF1AAB27-82B9-4AB6-AAE8-017A49398C14}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; const result_: ICoreWebView2BrowserExtension): HResult; stdcall; + end; + + /// + /// Provides a set of properties for managing an Extension, which includes + /// an ID, name, and whether it is enabled or not, and the ability to Remove + /// the Extension, and enable or disable it. + /// + /// + /// See the ICoreWebView2BrowserExtension article. + /// + ICoreWebView2BrowserExtension = interface(IUnknown) + ['{7EF7FFA0-FAC5-462C-B189-3D9EDBE575DA}'] + /// + /// This is the browser extension's ID. This is the same browser extension ID returned by + /// the browser extension API [`chrome.runtime.id`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/runtime/id). + /// Please see that documentation for more details on how the ID is generated. + /// After an extension is removed, calling `Id` will return the id of the extension that is removed. + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_id(out value: PWideChar): HResult; stdcall; + /// + /// This is the browser extension's name. This value is defined in this browser extension's + /// manifest.json file. If manifest.json define extension's localized name, this value will + /// be the localized version of the name. + /// Please see [Manifest.json name](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/name) + /// for more details. + /// After an extension is removed, calling `Name` will return the name of the extension that is removed. + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_name(out value: PWideChar): HResult; stdcall; + /// + /// Removes this browser extension from its WebView2 Profile. The browser extension is removed + /// immediately including from all currently running HTML documents associated with this + /// WebView2 Profile. The removal is persisted and future uses of this profile will not have this + /// extension installed. After an extension is removed, calling `Remove` again will cause an exception. + /// + function Remove(const handler: ICoreWebView2BrowserExtensionRemoveCompletedHandler): HResult; stdcall; + /// + /// If `isEnabled` is true then the Extension is enabled and running in WebView instances. + /// If it is false then the Extension is disabled and not running in WebView instances. + /// When a Extension is first installed, `IsEnable` are default to be `TRUE`. + /// `isEnabled` is persisted per profile. + /// After an extension is removed, calling `isEnabled` will return the value at the time it was removed. + /// + function Get_IsEnabled(out value: Integer): HResult; stdcall; + /// + /// Sets whether this browser extension is enabled or disabled. This change applies immediately + /// to the extension in all HTML documents in all WebView2s associated with this profile. + /// After an extension is removed, calling `Enable` will not change the value of `IsEnabled`. + /// + function Enable(IsEnabled: Integer; + const handler: ICoreWebView2BrowserExtensionEnableCompletedHandler): HResult; stdcall; + end; + + /// + /// Receives the result of the `Remove` method. + /// + /// + /// See the ICoreWebView2BrowserExtensionRemoveCompletedHandler article. + /// + ICoreWebView2BrowserExtensionRemoveCompletedHandler = interface(IUnknown) + ['{8E41909A-9B18-4BB1-8CDF-930F467A50BE}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult): HResult; stdcall; + end; + + /// + /// Receives the result of the `Enable` method. + /// + /// + /// See the ICoreWebView2BrowserExtensionEnableCompletedHandler article. + /// + ICoreWebView2BrowserExtensionEnableCompletedHandler = interface(IUnknown) + ['{30C186CE-7FAD-421F-A3BC-A8EAF071DDB8}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult): HResult; stdcall; + end; + + /// + /// Receives the result of the `GetBrowserExtensions` method. + /// + /// + /// See the ICoreWebView2ProfileGetBrowserExtensionsCompletedHandler article. + /// + ICoreWebView2ProfileGetBrowserExtensionsCompletedHandler = interface(IUnknown) + ['{FCE16A1C-F107-4601-8B75-FC4940AE25D0}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; const result_: ICoreWebView2BrowserExtensionList): HResult; stdcall; + end; + + /// + /// A collection of ICoreWebView2BrowserExtension. + /// + /// + /// See the ICoreWebView2BrowserExtensionList article. + /// + ICoreWebView2BrowserExtensionList = interface(IUnknown) + ['{2EF3D2DC-BD5F-4F4D-90AF-FD67798F0C2F}'] + /// + /// The number of elements contained in the collection. + /// + function Get_Count(out value: SYSUINT): HResult; stdcall; + /// + /// Gets the element at the given index. + /// + function GetValueAtIndex(index: SYSUINT; out value: ICoreWebView2BrowserExtension): HResult; stdcall; + end; + + /// + /// This is the profile interface that manages profile deletion. + /// + /// + /// See the ICoreWebView2Profile8 article. + /// + ICoreWebView2Profile8 = interface(ICoreWebView2Profile7) + ['{FBF70C2F-EB1F-4383-85A0-163E92044011}'] + /// + /// After the API is called, the profile will be marked for deletion. The + /// local profile's directory will be deleted at browser process exit. If it + /// fails to delete, because something else is holding the files open, + /// WebView2 will try to delete the profile at all future browser process + /// starts until successful. + /// The corresponding CoreWebView2s will be closed and the + /// CoreWebView2Profile.Deleted event will be raised. See + /// `CoreWebView2Profile.Deleted` for more information. + /// If you try to create a new profile with the same name as an existing + /// profile that has been marked as deleted but hasn't yet been deleted, + /// profile creation will fail with HRESULT_FROM_WIN32(ERROR_DELETE_PENDING). + /// + /// \snippet SettingsComponent.cpp DeleteProfile + /// + function Delete: HResult; stdcall; + /// + /// Add an event handler for the `Deleted` event. The `Deleted` event is + /// raised when the profile is marked for deletion. When this event is + /// raised, the CoreWebView2Profile and its corresponding CoreWebView2s have + /// been closed, and cannot be used anymore. + /// + /// \snippet AppWindow.cpp ProfileDeleted + /// + function add_Deleted(const eventHandler: ICoreWebView2ProfileDeletedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_Deleted`. + /// + function remove_Deleted(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives `Deleted` events. + /// + /// + /// See the ICoreWebView2ProfileDeletedEventHandler article. + /// + ICoreWebView2ProfileDeletedEventHandler = interface(IUnknown) + ['{DF35055D-772E-4DBE-B743-5FBF74A2B258}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2Profile; const args: IUnknown): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Profile interface to manage service workers, + /// shared workers, and service worker script API settings. + /// + /// + /// See the ICoreWebView2Profile9 article. + /// + ICoreWebView2Profile9 = interface(ICoreWebView2Profile8) + ['{40C764D0-12FC-5D23-816D-971B353174C1}'] + /// + /// Gets the `AreWebViewScriptApisEnabledForServiceWorkers` property. + /// + function Get_AreWebViewScriptApisEnabledForServiceWorkers(out value: Integer): HResult; stdcall; + /// + /// Enables or disables webview2 specific Service Worker JS APIs in the + /// WebView2s associated with this Profile. When set to `TRUE`, chrome and + /// webview objects are available in Service Workers. chrome.webview exposes + /// APIs to interact with the WebView from Service Workers. The default value + /// is `FALSE`. This setting applies to all newly installed Service Workers + /// within the profile and is not persisted across WebView2 sessions. + /// \snippet ScenarioServiceWorkerPostMessageSetting.cpp AreWebViewScriptApisEnabledForServiceWorkers + /// + function Set_AreWebViewScriptApisEnabledForServiceWorkers(value: Integer): HResult; stdcall; + /// + /// Get the service worker manager to monitor service worker registrations and + /// interact with the service workers associated with the current profile. + /// + /// \snippet ScenarioServiceWorkerManager.cpp ServiceWorkerManager + /// + function Get_ServiceWorkerManager(out value: ICoreWebView2ServiceWorkerManager): HResult; stdcall; + /// + /// Get the shared worker manager to monitor shared worker creations and interact + /// with the shared workers associated with the current profile. + /// + /// \snippet ScenarioSharedWorkerManager.cpp SharedWorkerManager + /// + function Get_SharedWorkerManager(out value: ICoreWebView2SharedWorkerManager): HResult; stdcall; + end; + + /// + /// This interface manages registrations for service workers in WebView2. + /// + /// + /// See the ICoreWebView2ServiceWorkerManager article. + /// + ICoreWebView2ServiceWorkerManager = interface(IUnknown) + ['{A2D52FD4-9B10-5971-8499-C67D1560F47A}'] + /// + /// Adds an event handler for the `ServiceWorkerRegistered` event. + /// A ServiceWorker is a specific type of worker that takes a JavaScript file + /// that can control the web-page/site that it is associated with, + /// intercepting and modifying navigation and resource requests, and caching + /// resources in a very granular fashion to give you complete control + /// over how app behaves in certain situations. + /// + /// Service workers essentially act as proxy servers that sit between web + /// applications, the browser, and the network (when available). They run in + /// a different context from the web page, which means they have no direct access + /// to the DOM. Unlike dedicated and shared workers, which may have direct access to a + /// global scope shared with other scripts, service workers operate in isolation + /// from the DOM, ensuring a more secure and controlled environment. + /// + /// This event is raised when a web application registers a service worker using the + /// `navigator.serviceWorker.register("/sw.js")` method. See the + /// [Service Worker Registration](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration) + /// for more information. + /// + /// \snippet ScenarioServiceWorkerManager.cpp ServiceWorkerRegistered + /// + function add_ServiceWorkerRegistered(const eventHandler: ICoreWebView2ServiceWorkerRegisteredEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_ServiceWorkerRegistered`. + /// + function remove_ServiceWorkerRegistered(token: EventRegistrationToken): HResult; stdcall; + /// + /// Gets a list of the service worker registrations under the same profile. + /// + /// This method returns a list of `CoreWebView2ServiceWorkerRegistration` objects, + /// each representing a service worker registration. + /// + /// This method corresponds to the `getRegistrations` method of the `ServiceWorkerContainer` + /// object in the DOM which returns a Promise that resolves to an array of + /// `ServiceWorkerRegistration` objects. See the [MDN documentation] + /// (https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer/getRegistrations) for more information. + /// + function GetServiceWorkerRegistrations(const handler: ICoreWebView2GetServiceWorkerRegistrationsCompletedHandler): HResult; stdcall; + /// + /// Gets the service worker registrations associated with the specified scope. + /// If a service worker has been registered for the given scope, it gets the + /// list of `CoreWebView2ServiceWorkerRegistration` objects otherwise returns + /// empty list. + /// + /// If the service worker is registered with a `scope` of '/app/' for an application + /// at https://example.com/, you should specify the full qualified URI i.e., + /// https://example.com/app/ when calling this method. If the scope was not explicitly + /// specified during registration, you should use the directory where the service worker + /// script resides, for example, https://example.com/app/. + /// + /// Refer to the Host Name Canonicalization for + /// details on how provided `scriptUri` normalization is performed. For example, `HTTPS://münchen.de/` + /// will be normalized to `https://www.xn--kfk.com` for comparison. + /// + /// This corresponds to the `getRegistration` method of the `ServiceWorkerContainer` + /// object in the DOM which returns a Promise that resolves to a `ServiceWorkerRegistration` + /// object. See the [MDN documentation] + /// (https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer/getRegistration) for more information. + /// + /// If scopeUri is empty string or null or invalid, the completed handler immediately returns + /// `E_INVALIDARG` and with a null pointer. + /// + function GetServiceWorkerRegistrationsForScope(ScopeUri: PWideChar; + const handler: ICoreWebView2GetServiceWorkerRegistrationsCompletedHandler): HResult; stdcall; + end; + + /// + /// Receives `ServiceWorkerRegistered` events. + /// + /// + /// See the ICoreWebView2ServiceWorkerRegisteredEventHandler article. + /// + ICoreWebView2ServiceWorkerRegisteredEventHandler = interface(IUnknown) + ['{C024C910-4DF2-54A3-B5C1-6152CA0E4577}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2ServiceWorkerManager; + const args: ICoreWebView2ServiceWorkerRegisteredEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the `ServiceWorkerRegistered` event. + /// + /// + /// See the ICoreWebView2ServiceWorkerRegisteredEventArgs article. + /// + ICoreWebView2ServiceWorkerRegisteredEventArgs = interface(IUnknown) + ['{C6172932-407A-553B-B4D1-CDD12605EB6A}'] + /// + /// The service worker that was registered. + /// + function Get_ServiceWorkerRegistration(out value: ICoreWebView2ServiceWorkerRegistration): HResult; stdcall; + end; + + /// + /// This interface represents a service worker registration in WebView2 and provides methods + /// and properties for interacting with it, such as getting the scope uri, active service worker, + /// listening for service worker activation, unregistering events etc. + /// + /// + /// See the ICoreWebView2ServiceWorkerRegistration article. + /// + ICoreWebView2ServiceWorkerRegistration = interface(IUnknown) + ['{06003F5E-AF92-5E7E-B497-3FA167DD37C2}'] + /// + /// The active service worker that was created. If there is no active service worker, + /// it returns a null pointer. + /// The active service worker is the service worker that controls the pages within + /// the scope of the registration. See the [Service Worker] + /// (https://developer.mozilla.org/docs/Web/API/ServiceWorker) for more information. + /// + /// This corresponds to the `active` property of the `ServiceWorkerRegistration` object in the DOM. + /// For more information, see the [MDN documentation] + /// (https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/active). + /// + function Get_ActiveServiceWorker(out value: ICoreWebView2ServiceWorker): HResult; stdcall; + /// + /// A string representing the URI of the origin where the worker is executing. + /// + /// If a worker created with `ScriptUri` set to https://example.com/worker.js, the origin + /// will be https://example.com/. + /// + /// Refer to the Host Name Canonicalization for + /// details on how normalization is performed. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_origin(out value: PWideChar): HResult; stdcall; + /// + /// The `scopeUri` is a fully qualified URI, including the scheme, host and path, + /// that specifies the range of URLs a service worker can control. + /// + /// When registering a service worker, if no scope is specified, it defaults to the + /// directory where the service worker script resides. For example, if the script is + /// located at https://example.com/app/sw.js, the default `scopeUri` would be + /// https://example.com/app/. However, if a scope is provided, it is defined relative + /// to the application's base URI. For instance, if an application at + /// https://example.com/ registers a service worker with a scope of /app/, the resulting + /// `scopeUri` is https://example.com/app/. + /// + /// Refer to the Host Name Canonicalization for + /// details on how normalization is performed. + /// The same process applies to the `Scope` when a service worker is registered from DOM API. + /// The `scopeUri` property reflects this normalization, ensuring that the URI is standardized. For example, + /// `HTTPS://EXAMPLE.COM/app/` is canonicalized to `https://example.com/app/`; + /// `https://bücher.de/` is canonicalized to `https://xn--bcher-kva.de/`. + /// + /// The `scope` property of the `ServiceWorkerRegistration` object in the DOM returns + /// the relative URL based on the application's base URI, while this property always + /// returns a fully qualified URI. For more information on DOM API, see the + /// [MDN documentation](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/scope). + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_ScopeUri(out value: PWideChar): HResult; stdcall; + /// + /// A string representing the URI of the top-level document that the worker is associated with. + /// + /// If a worker is created with `ScriptUri` set to https://example.com/worker.js, the top-level origin + /// is https://example.com/. If the same worker is created from a iframe at https://example.com/ which is hosted on + /// https://example2.com/, the top-level origin is https://example2.com/. + /// + /// Refer to the Host Name Canonicalization for + /// details on how normalization is performed. + /// + /// When CustomDataPartitionId is set, the `TopLevelOrigin` will be a generated + /// site like guid.invalid. For example, if the top-level document is https://example.com/worker.js, + /// the top-level origin will be `https://guid.invalid/`. + /// + /// For more details see `ICoreWebView2Experimental20::CustomDataPartitionId`. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_TopLevelOrigin(out value: PWideChar): HResult; stdcall; + /// + /// Adds an event handler for the `ServiceWorkerActivated` event. + /// Adds an event handler for the `ServiceWorkerActivated` event. + /// + /// This event is raised when a service worker is activated. A service worker is + /// activated when its script has been successfully registered and it is ready to + /// control the pages within the scope of the registration. + /// + /// This event is also raised when an updated version of a service worker reaches the active state. + /// In such a case, the existing CoreWebView2ServiceWorker object is destroying, and this event is + /// raised with a new CoreWebView2ServiceWorker object representing the updated service worker. + /// The active service worker is the one that receives fetch and message events for the pages it controls. + /// See the [Service Worker](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/active) + /// documentation for more information. + /// + /// If you register for the `ServiceWorkerActivated` event and the registration already + /// has an active worker, the event handler is not called immediately. Instead, it waits + /// for the next activation event to occur. Therefore, you should first check if an active + /// service worker is running by using the `ActiveServiceWorker` property. + /// + function add_ServiceWorkerActivated(const eventHandler: ICoreWebView2ServiceWorkerActivatedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_ServiceWorkerActivated`. + /// + function remove_ServiceWorkerActivated(token: EventRegistrationToken): HResult; stdcall; + /// + /// Adds an event handler for the `Unregistering` event. + /// Add an event handler for the `Unregistering` event that is raised when the worker registration is + /// unregistered using the JS api `registration.unregister()`. See the + /// [Unregister](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/unregister) + /// for more information. + /// + function add_Unregistering(const eventHandler: ICoreWebView2ServiceWorkerRegistrationUnregisteringEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_Unregistering`. + /// + function remove_Unregistering(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// This interface represents a service worker in WebView2 and provides methods and properties + /// for interacting with it, such as getting the script uri, posting messages to it etc. + /// + /// + /// See the ICoreWebView2ServiceWorker article. + /// + ICoreWebView2ServiceWorker = interface(IUnknown) + ['{245A7BB7-7C31-582D-95EE-0F2D99D2F5B0}'] + /// + /// A string representing the Uri of the script that the worker is executing. + /// + /// The `scriptUri` is a fully qualified URI, including the scheme, host, and path. + /// In contrast, the `scriptURL` property of the `Worker` object in the DOM returns the relative + /// URL of the script being executed by the worker. For more details on DOM API, see the + /// [DOM API documentation](https://developer.mozilla.org/docs/Web/API/Worker/scriptURL). + /// + /// Refer to the Host Name Canonicalization for + /// details on how normalization is performed. + /// The same process applies to the `scriptURL` when a worker is registered from DOM API. + /// The `scriptUri` property reflects this normalization, ensuring that the URL is standardized. For example, + /// `HTTPS://EXAMPLE.COM/worker.js` is canonicalized to `https://example.com/worker.js`; + /// `https://bücher.de/worker.js` is canonicalized to `https://xn--bcher-kva.de/worker.js`. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_ScriptUri(out value: PWideChar): HResult; stdcall; + /// + /// Adds an event handler for the `Destroying` event. + /// Add an event handler for the `Destroying` event that is raised when the + /// worker object is Destroying. + /// + /// A worker object is Destroying when the worker script is terminated or when + /// the `CoreWebView2ServiceWorker` object is Destroying. + /// + /// If the worker has already been destroyed before the event handler is registered, + /// the handler will never be called. + /// + function add_Destroying(const eventHandler: ICoreWebView2ServiceWorkerDestroyingEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_Destroying`. + /// + function remove_Destroying(token: EventRegistrationToken): HResult; stdcall; + /// + /// Adds an event handler for the `WebMessageReceived` event. + /// Add an event handler for the `WebMessageReceived` event. + /// `WebMessageReceived` is fired, when the + /// `ICoreWebView2Settings::IsWebMessageEnabled` setting is set TRUE and the + /// worker runs `self.chrome.webview.postMessage`. The `postMessage` function + /// is `void postMessage(object)` where object is any object supported by JSON + /// conversion. + /// + /// If the worker calls `postMessage` multiple times, the corresponding + /// `WebMessageReceived` events are guaranteed to be fired in the same order. + /// + /// + /// \snippet ScenarioServiceWorkerPostMessage.cpp WebMessageReceived + /// + function add_WebMessageReceived(const eventHandler: ICoreWebView2ServiceWorkerWebMessageReceivedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_WebMessageReceived`. + /// + function remove_WebMessageReceived(token: EventRegistrationToken): HResult; stdcall; + /// + /// Posts the specified webMessageAsJson to this worker. + /// The worker receives the message by subscribing to the `message` event of the + /// `self.chrome.webview` of the worker. + /// + /// ```cpp + /// self.chrome.webview.addEventListener('message', handler) + /// self.chrome.webview.removeEventListener('message', handler) + /// ``` + /// + /// The event args is an instance of `MessageEvent`. Both the + /// `ICoreWebView2Profile::AreWebViewScriptApisEnabledForServiceWorkers` and + /// `ICoreWebView2Settings::IsWebMessageEnabled` settings must be `TRUE` or + /// the web message will not be sent. The `data` property of the event arg + /// is the `webMessageAsJson` string parameter parsed as a JSON string into a + /// JS object. The `source` property of the event arg is the path + /// to the worker script. The message is delivered asynchronously. + /// If the worker is terminated or destroyed before the message is posted, + /// the message is discarded. + /// Worker Javascript may subscribe and unsubscribe to the event + /// using the following code: + /// ```javascript + /// self.chrome.webview.addEventListener('message', handler) + /// self.chrome.webview.removeEventListener('message', handler) + /// ``` + /// ```cpp + /// See also the equivalent methods: `ICoreWebView2::PostWebMessageAsJson`, + /// `ICoreWebView2Frame::PostWebMessageAsJson`, + /// `ICoreWebView2DedicatedWorker::PostWebMessageAsJson`. + /// ``` + /// + /// + /// \snippet ScenarioServiceWorkerPostMessage.cpp PostWebMessageAsJson + /// + function PostWebMessageAsJson(webMessageAsJson: PWideChar): HResult; stdcall; + /// + /// Posts a message that is a simple string rather than a JSON string + /// representation of a JavaScript object. This behaves exactly the same + /// manner as `PostWebMessageAsJson`, but the `data` property of the event + /// arg of the `self.chrome.webview` message is a string with the same + /// value as `webMessageAsString`. Use this instead of + /// `PostWebMessageAsJson` if you want to communicate using simple strings + /// rather than JSON objects. Please see `PostWebMessageAsJson` for + /// additional information. + /// ```cpp + /// See also the equivalent methods: `ICoreWebView2::PostWebMessageAsString` + /// `ICoreWebView2Frame::PostWebMessageAsString`, + /// `ICoreWebView2DedicatedWorker::PostWebMessageAsString`. + /// ``` + /// + function PostWebMessageAsString(webMessageAsString: PWideChar): HResult; stdcall; + end; + + /// + /// Receives `Destroying` events. + /// + /// + /// See the ICoreWebView2ServiceWorkerDestroyingEventHandler article. + /// + ICoreWebView2ServiceWorkerDestroyingEventHandler = interface(IUnknown) + ['{C7528449-5674-5E34-B990-FF4CEF046214}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2ServiceWorker; const args: IUnknown): HResult; stdcall; + end; + + /// + /// Receives `WebMessageReceived` events. + /// + /// + /// See the ICoreWebView2ServiceWorkerWebMessageReceivedEventHandler article. + /// + ICoreWebView2ServiceWorkerWebMessageReceivedEventHandler = interface(IUnknown) + ['{65F0A1A6-A295-5A9F-8041-70DB71566F98}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2ServiceWorker; + const args: ICoreWebView2WebMessageReceivedEventArgs): HResult; stdcall; + end; + + /// + /// Receives `ServiceWorkerActivated` events. + /// + /// + /// See the ICoreWebView2ServiceWorkerActivatedEventHandler article. + /// + ICoreWebView2ServiceWorkerActivatedEventHandler = interface(IUnknown) + ['{ECAA9897-769D-5ECE-A1E5-8859818CAF86}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2ServiceWorkerRegistration; + const args: ICoreWebView2ServiceWorkerActivatedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the `ServiceWorkerActivated` event. + /// + /// + /// See the ICoreWebView2ServiceWorkerActivatedEventArgs article. + /// + ICoreWebView2ServiceWorkerActivatedEventArgs = interface(IUnknown) + ['{5685C4B6-A514-58B2-9721-B61EF4CCD9D8}'] + /// + /// The service worker that was activated. + /// + function Get_ActiveServiceWorker(out value: ICoreWebView2ServiceWorker): HResult; stdcall; + end; + + /// + /// Receives `Unregistering` events. + /// + /// + /// See the ICoreWebView2ServiceWorkerRegistrationUnregisteringEventHandler article. + /// + ICoreWebView2ServiceWorkerRegistrationUnregisteringEventHandler = interface(IUnknown) + ['{BEC01D14-6AD9-5257-9FF6-84F01BAA0CCA}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2ServiceWorkerRegistration; const args: IUnknown): HResult; stdcall; + end; + + /// + /// Receives the result of the `GetServiceWorkerRegistrations` method. + /// + /// + /// See the ICoreWebView2GetServiceWorkerRegistrationsCompletedHandler article. + /// + ICoreWebView2GetServiceWorkerRegistrationsCompletedHandler = interface(IUnknown) + ['{EA83432F-6528-592F-903B-0917EB0FD9C7}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; + const result: ICoreWebView2ServiceWorkerRegistrationCollectionView): HResult; stdcall; + end; + + /// + /// A collection of ICoreWebView2ServiceWorkerRegistration. + /// + /// + /// See the ICoreWebView2ServiceWorkerRegistrationCollectionView article. + /// + ICoreWebView2ServiceWorkerRegistrationCollectionView = interface(IUnknown) + ['{83D8CFA9-EF83-5447-9431-91C203C4C9D8}'] + /// + /// The number of elements contained in the collection. + /// + function Get_Count(out value: SYSUINT): HResult; stdcall; + /// + /// Gets the element at the given index. + /// + function GetValueAtIndex(index: SYSUINT; out value: ICoreWebView2ServiceWorkerRegistration): HResult; stdcall; + end; + + /// + /// This interface manages shared workers in WebView2. + /// + /// + /// See the ICoreWebView2SharedWorkerManager article. + /// + ICoreWebView2SharedWorkerManager = interface(IUnknown) + ['{9B897103-D035-551F-892E-3E8F2916D03E}'] + /// + /// Adds an event handler for the `SharedWorkerCreated` event. + /// Add an event handler for the `SharedWorkerCreated` event. + /// + /// A SharedWorker is a specific type of worker that can be accessed from several + /// browsing contexts, such as multiple windows, iframes, or even other workers. + /// Unlike Dedicated Workers, which have their own separate global scope, SharedWorkers + /// share a common global scope called SharedWorkerGlobalScope. + /// + /// This event is raised when a web application creates a shared worker using the + /// `new SharedWorker("worker.js")` method. See the + /// [Shared Worker](https://developer.mozilla.org/docs/Web/API/SharedWorker) + /// for more information. + /// + /// + /// \snippet ScenarioSharedWorkerManager.cpp SharedWorkerCreated + /// + function add_SharedWorkerCreated(const eventHandler: ICoreWebView2SharedWorkerCreatedEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_SharedWorkerCreated`. + /// + function remove_SharedWorkerCreated(token: EventRegistrationToken): HResult; stdcall; + /// + /// Gets a list of the shared workers created under the same profile. + /// + function GetSharedWorkers(const handler: ICoreWebView2GetSharedWorkersCompletedHandler): HResult; stdcall; + end; + + /// + /// Receives `SharedWorkerCreated` events. + /// + /// + /// See the ICoreWebView2SharedWorkerCreatedEventHandler article. + /// + ICoreWebView2SharedWorkerCreatedEventHandler = interface(IUnknown) + ['{79CB8524-B842-551A-8D31-5F824B6955ED}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2SharedWorkerManager; + const args: ICoreWebView2SharedWorkerCreatedEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the `SharedWorkerCreated` event. + /// + /// + /// See the ICoreWebView2SharedWorkerCreatedEventArgs article. + /// + ICoreWebView2SharedWorkerCreatedEventArgs = interface(IUnknown) + ['{9F6615B0-08F1-5BAA-9C95-A02A1DC56D3F}'] + /// + /// The shared worker that was created. + /// + function Get_Worker(out value: ICoreWebView2SharedWorker): HResult; stdcall; + end; + + /// + /// This interface represents a shared worker in WebView2 and provides methods and + /// properties for interacting with it, such as listening to destroying events, + /// getting the script URI, origin, and top-level origin of the worker etc. + /// + /// + /// See the ICoreWebView2SharedWorker article. + /// + ICoreWebView2SharedWorker = interface(IUnknown) + ['{BCD39C8D-48BB-5F1B-BE22-89F9C0C4484A}'] + /// + /// A string representing the URI of the origin where the worker is executing. + /// + /// If a worker created with `ScriptUri` set to https://example.com/worker.js, the origin + /// will be https://example.com/. + /// + /// Refer to the Host Name Canonicalization for + /// details on how normalization is performed. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_origin(out value: PWideChar): HResult; stdcall; + /// + /// A string representing the Uri of the script that the worker is executing. + /// + /// The `scriptUri` is a fully qualified URI, including the scheme, host, and path. + /// In contrast, the `scriptURL` property of the `Worker` object in the DOM returns the relative + /// URL of the script being executed by the worker. For more details on DOM API, see the + /// [DOM API documentation](https://developer.mozilla.org/docs/Web/API/Worker/scriptURL). + /// + /// Refer to the Host Name Canonicalization for + /// details on how normalization is performed. + /// The same process applies to the `scriptURL` when a worker is created from DOM API. + /// The `scriptUri` property reflects this normalization, ensuring that the URL is standardized. For example, + /// `HTTPS://EXAMPLE.COM/worker.js` is canonicalized to `https://example.com/worker.js`; + /// `https://bücher.de/worker.js` is canonicalized to `https://xn--bcher-kva.de/worker.js`. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_ScriptUri(out value: PWideChar): HResult; stdcall; + /// + /// A string representing the URI of the top-level document that the worker is associated with. + /// + /// If a worker is created with `ScriptUri` set to https://example.com/worker.js, the top-level origin + /// is https://example.com/. If the same worker is created from a iframe at https://example.com/ which is hosted on + /// https://example2.com/, the top-level origin is https://example2.com/. + /// + /// Refer to the Host Name Canonicalization for + /// details on how normalization is performed. + /// + /// When CustomDataPartitionId is set, the `TopLevelOrigin` will be a generated + /// site like guid.invalid. For example, if the top-level document is https://example.com/worker.js, + /// the top-level origin will be https://guid.invalid/. + /// + /// For more details see `ICoreWebView2Experimental20::CustomDataPartitionId`. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_TopLevelOrigin(out value: PWideChar): HResult; stdcall; + /// + /// Adds an event handler for the `Destroying` event. + /// Add an event handler for the `Destroying` event that is raised when the + /// worker object is Destroying. + /// + /// A worker object is Destroying when the worker script is terminated or when + /// the `CoreWebView2SharedWorker` object is Destroying. + /// + /// If the worker has already been destroyed before the event handler is registered, + /// the handler will never be called. + /// + function add_Destroying(const eventHandler: ICoreWebView2SharedWorkerDestroyingEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_Destroying`. + /// + function remove_Destroying(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives `Destroying` events. + /// + /// + /// See the ICoreWebView2SharedWorkerDestroyingEventHandler article. + /// + ICoreWebView2SharedWorkerDestroyingEventHandler = interface(IUnknown) + ['{5A459F84-FD04-5CCE-A998-6FAB56F09EEB}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2SharedWorker; const args: IUnknown): HResult; stdcall; + end; + + /// + /// Receives the result of the `GetSharedWorkers` method. + /// + /// + /// See the ICoreWebView2GetSharedWorkersCompletedHandler article. + /// + ICoreWebView2GetSharedWorkersCompletedHandler = interface(IUnknown) + ['{1F3179AE-15E5-51E4-8583-BE0CAF85ADC7}'] + /// + /// Provides the result of the corresponding asynchronous method. + /// + function Invoke(errorCode: HResult; const result: ICoreWebView2SharedWorkerCollectionView): HResult; stdcall; + end; + + /// + /// A collection of ICoreWebView2SharedWorker. + /// + /// + /// See the ICoreWebView2SharedWorkerCollectionView article. + /// + ICoreWebView2SharedWorkerCollectionView = interface(IUnknown) + ['{F8842B09-0108-5575-A965-3D76FD267050}'] + /// + /// The number of elements contained in the collection. + /// + function Get_Count(out value: SYSUINT): HResult; stdcall; + /// + /// Gets the element at the given index. + /// + function GetValueAtIndex(index: SYSUINT; out value: ICoreWebView2SharedWorker): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Settings interface that manages the user agent. + /// + /// + /// See the ICoreWebView2Settings2 article. + /// + ICoreWebView2Settings2 = interface(ICoreWebView2Settings) + ['{EE9A0F68-F46C-4E32-AC23-EF8CAC224D2A}'] + /// + /// Returns the User Agent. The default value is the default User Agent of the + /// Microsoft Edge browser. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_UserAgent(out value: PWideChar): HResult; stdcall; + /// + /// This setting determines the UserAgent of WebView. This property may be overridden if + /// the User-Agent header is set in a request. If the parameter is empty + /// the User Agent will not be updated and the current User Agent will remain. + /// Setting this property may clear User Agent Client Hints headers + /// Sec-CH-UA-* and script values from navigator.userAgentData. Current + /// implementation behavior is subject to change. + /// The User Agent set will also be effective on service workers + /// and shared workers associated with the WebView. If there are + /// multiple WebViews associated with the same service worker or + /// shared worker, the last User Agent set will be used. + /// + /// \snippet SettingsComponent.cpp UserAgent + /// + function Set_UserAgent(value: PWideChar): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Settings interface that manages whether + /// browser accelerator keys are enabled. + /// + /// + /// See the ICoreWebView2Settings3 article. + /// + ICoreWebView2Settings3 = interface(ICoreWebView2Settings2) + ['{FDB5AB74-AF33-4854-84F0-0A631DEB5EBA}'] + /// + /// When this setting is set to FALSE, it disables all accelerator keys that + /// access features specific to a web browser, including but not limited to: + /// - Ctrl-F and F3 for Find on Page + /// - Ctrl-P for Print + /// - Ctrl-R and F5 for Reload + /// - Ctrl-Plus and Ctrl-Minus for zooming + /// - Ctrl-Shift-C and F12 for DevTools + /// - Special keys for browser functions, such as Back, Forward, and Search + /// + /// It does not disable accelerator keys related to movement and text editing, + /// such as: + /// - Home, End, Page Up, and Page Down + /// - Ctrl-X, Ctrl-C, Ctrl-V + /// - Ctrl-A for Select All + /// - Ctrl-Z for Undo + /// + /// Those accelerator keys will always be enabled unless they are handled in + /// the `AcceleratorKeyPressed` event. + /// + /// This setting has no effect on the `AcceleratorKeyPressed` event. The event + /// will be fired for all accelerator keys, whether they are enabled or not. + /// + /// The default value for `AreBrowserAcceleratorKeysEnabled` is TRUE. + /// + /// \snippet SettingsComponent.cpp AreBrowserAcceleratorKeysEnabled + /// + function Get_AreBrowserAcceleratorKeysEnabled(out value: Integer): HResult; stdcall; + /// + /// Sets the `AreBrowserAcceleratorKeysEnabled` property. + /// + function Set_AreBrowserAcceleratorKeysEnabled(value: Integer): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Settings interface to manage autofill. + /// + /// + /// See the ICoreWebView2Settings4 article. + /// + ICoreWebView2Settings4 = interface(ICoreWebView2Settings3) + ['{CB56846C-4168-4D53-B04F-03B6D6796FF2}'] + /// + /// IsPasswordAutosaveEnabled controls whether autosave for password + /// information is enabled. The IsPasswordAutosaveEnabled property behaves + /// independently of the IsGeneralAutofillEnabled property. When IsPasswordAutosaveEnabled is + /// false, no new password data is saved and no Save/Update Password prompts are displayed. + /// However, if there was password data already saved before disabling this setting, + /// then that password information is auto-populated, suggestions are shown and clicking on + /// one will populate the fields. + /// When IsPasswordAutosaveEnabled is true, password information is auto-populated, + /// suggestions are shown and clicking on one will populate the fields, new data + /// is saved, and a Save/Update Password prompt is displayed. + /// It will take effect immediately after setting. + /// The default value is `FALSE`. + /// This property has the same value as + /// `CoreWebView2Profile.IsPasswordAutosaveEnabled`, and changing one will + /// change the other. All `CoreWebView2`s with the same `CoreWebView2Profile` + /// will share the same value for this property, so for the `CoreWebView2`s + /// with the same profile, their + /// `CoreWebView2Settings.IsPasswordAutosaveEnabled` and + /// `CoreWebView2Profile.IsPasswordAutosaveEnabled` will always have the same + /// value. + /// + /// \snippet SettingsComponent.cpp PasswordAutosaveEnabled + /// + function Get_IsPasswordAutosaveEnabled(out value: Integer): HResult; stdcall; + /// + /// Set the IsPasswordAutosaveEnabled property. + /// + function Set_IsPasswordAutosaveEnabled(value: Integer): HResult; stdcall; + /// + /// IsGeneralAutofillEnabled controls whether autofill for information + /// like names, street and email addresses, phone numbers, and arbitrary input + /// is enabled. This excludes password and credit card information. When + /// IsGeneralAutofillEnabled is false, no suggestions appear, and no new information + /// is saved. When IsGeneralAutofillEnabled is true, information is saved, suggestions + /// appear and clicking on one will populate the form fields. + /// It will take effect immediately after setting. + /// The default value is `TRUE`. + /// This property has the same value as + /// `CoreWebView2Profile.IsGeneralAutofillEnabled`, and changing one will + /// change the other. All `CoreWebView2`s with the same `CoreWebView2Profile` + /// will share the same value for this property, so for the `CoreWebView2`s + /// with the same profile, their + /// `CoreWebView2Settings.IsGeneralAutofillEnabled` and + /// `CoreWebView2Profile.IsGeneralAutofillEnabled` will always have the same + /// value. + /// + /// \snippet SettingsComponent.cpp GeneralAutofillEnabled + /// + function Get_IsGeneralAutofillEnabled(out value: Integer): HResult; stdcall; + /// + /// Set the IsGeneralAutofillEnabled property. + /// + function Set_IsGeneralAutofillEnabled(value: Integer): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Settings interface to manage pinch zoom. + /// + /// + /// See the ICoreWebView2Settings5 article. + /// + ICoreWebView2Settings5 = interface(ICoreWebView2Settings4) + ['{183E7052-1D03-43A0-AB99-98E043B66B39}'] + /// + /// Pinch-zoom, referred to as "Page Scale" zoom, is performed as a post-rendering step, + /// it changes the page scale factor property and scales the surface the web page is + /// rendered onto when user performs a pinch zooming action. It does not change the layout + /// but rather changes the viewport and clips the web content, the content outside of the + /// viewport isn't visible onscreen and users can't reach this content using mouse. + /// + /// The `IsPinchZoomEnabled` property enables or disables the ability of + /// the end user to use a pinching motion on touch input enabled devices + /// to scale the web content in the WebView2. It defaults to `TRUE`. + /// When set to `FALSE`, the end user cannot pinch zoom after the next navigation. + /// Disabling/Enabling `IsPinchZoomEnabled` only affects the end user's ability to use + /// pinch motions and does not change the page scale factor. + /// This API only affects the Page Scale zoom and has no effect on the + /// existing browser zoom properties (`IsZoomControlEnabled` and `ZoomFactor`) + /// or other end user mechanisms for zooming. + /// + /// \snippet SettingsComponent.cpp TogglePinchZoomEnabled + /// + function Get_IsPinchZoomEnabled(out value: Integer): HResult; stdcall; + /// + /// Set the `IsPinchZoomEnabled` property + /// + function Set_IsPinchZoomEnabled(value: Integer): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Settings interface to manage swipe navigation. + /// + /// + /// See the ICoreWebView2Settings6 article. + /// + ICoreWebView2Settings6 = interface(ICoreWebView2Settings5) + ['{11CB3ACD-9BC8-43B8-83BF-F40753714F87}'] + /// + /// The `IsSwipeNavigationEnabled` property enables or disables the ability of the + /// end user to use swiping gesture on touch input enabled devices to + /// navigate in WebView2. It defaults to `TRUE`. + /// + /// When this property is `TRUE`, then all configured navigation gestures are enabled: + /// 1. Swiping left and right to navigate forward and backward is always configured. + /// 2. Swiping down to refresh is off by default and not exposed via our API currently, + /// it requires the "--pull-to-refresh" option to be included in the additional browser + /// arguments to be configured. (See put_AdditionalBrowserArguments.) + /// + /// When set to `FALSE`, the end user cannot swipe to navigate or pull to refresh. + /// This API only affects the overscrolling navigation functionality and has no + /// effect on the scrolling interaction used to explore the web content shown + /// in WebView2. + /// + /// Disabling/Enabling IsSwipeNavigationEnabled takes effect after the + /// next navigation. + /// + /// \snippet SettingsComponent.cpp ToggleSwipeNavigationEnabled + /// + function Get_IsSwipeNavigationEnabled(out value: Integer): HResult; stdcall; + /// + /// Set the `IsSwipeNavigationEnabled` property + /// + function Set_IsSwipeNavigationEnabled(value: Integer): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Settings interface to hide Pdf toolbar items. + /// + /// + /// See the ICoreWebView2Settings7 article. + /// + ICoreWebView2Settings7 = interface(ICoreWebView2Settings6) + ['{488DC902-35EF-42D2-BC7D-94B65C4BC49C}'] + /// + /// `HiddenPdfToolbarItems` is used to customize the PDF toolbar items. By default, it is COREWEBVIEW2_PDF_TOOLBAR_ITEMS_NONE and so it displays all of the items. + /// Changes to this property apply to all CoreWebView2s in the same environment and using the same profile. + /// Changes to this setting apply only after the next navigation. + /// \snippet SettingsComponent.cpp ToggleHidePdfToolbarItems + /// + function Get_HiddenPdfToolbarItems(out value: COREWEBVIEW2_PDF_TOOLBAR_ITEMS): HResult; stdcall; + /// + /// Set the `HiddenPdfToolbarItems` property. + /// + function Set_HiddenPdfToolbarItems(value: COREWEBVIEW2_PDF_TOOLBAR_ITEMS): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Settings interface to manage smartscreen. + /// + /// + /// See the ICoreWebView2Settings8 article. + /// + ICoreWebView2Settings8 = interface(ICoreWebView2Settings7) + ['{9E6B0E8F-86AD-4E81-8147-A9B5EDB68650}'] + /// + /// SmartScreen helps webviews identify reported phishing and malware websites + /// and also helps users make informed decisions about downloads. + /// `IsReputationCheckingRequired` is used to control whether SmartScreen + /// enabled or not. SmartScreen is enabled or disabled for all CoreWebView2s + /// using the same user data folder. If + /// CoreWebView2Setting.IsReputationCheckingRequired is true for any + /// CoreWebView2 using the same user data folder, then SmartScreen is enabled. + /// If CoreWebView2Setting.IsReputationCheckingRequired is false for all + /// CoreWebView2 using the same user data folder, then SmartScreen is + /// disabled. When it is changed, the change will be applied to all WebViews + /// using the same user data folder on the next navigation or download. The + /// default value for `IsReputationCheckingRequired` is true. If the newly + /// created CoreWebview2 does not set SmartScreen to false, when + /// navigating(Such as Navigate(), LoadDataUrl(), ExecuteScript(), etc.), the + /// default value will be applied to all CoreWebview2 using the same user data + /// folder. + /// SmartScreen of WebView2 apps can be controlled by Windows system setting + /// "SmartScreen for Microsoft Edge", specially, for WebView2 in Windows + /// Store apps, SmartScreen is controlled by another Windows system setting + /// "SmartScreen for Microsoft Store apps". When the Windows setting is enabled, the + /// SmartScreen operates under the control of the `IsReputationCheckingRequired`. + /// When the Windows setting is disabled, the SmartScreen will be disabled + /// regardless of the `IsReputationCheckingRequired` value set in WebView2 apps. + /// In other words, under this circumstance the value of + /// `IsReputationCheckingRequired` will be saved but overridden by system setting. + /// Upon re-enabling the Windows setting, the CoreWebview2 will reference the + /// `IsReputationCheckingRequired` to determine the SmartScreen status. + /// \snippet SettingsComponent.cpp ToggleSmartScreen + /// + function Get_IsReputationCheckingRequired(out value: Integer): HResult; stdcall; + /// + /// Sets whether this webview2 instance needs SmartScreen protection for its content. + /// Set the `IsReputationCheckingRequired` property. + /// + function Set_IsReputationCheckingRequired(value: Integer): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2Settings interface to manage non-client + /// regions. + /// + /// + /// See the ICoreWebView2Settings9 article. + /// + ICoreWebView2Settings9 = interface(ICoreWebView2Settings8) + ['{0528A73B-E92D-49F4-927A-E547DDDAA37D}'] + /// + /// The `IsNonClientRegionSupportEnabled` property enables web pages to use the + /// `app-region` CSS style. Disabling/Enabling the `IsNonClientRegionSupportEnabled` + /// takes effect after the next navigation. Defaults to `FALSE`. + /// + /// When this property is `TRUE`, then all the non-client region features + /// will be enabled: + /// Draggable Regions will be enabled, they are regions on a webpage that + /// are marked with the CSS attribute `app-region: drag/no-drag`. When set to + /// `drag`, these regions will be treated like the window's title bar, supporting + /// dragging of the entire WebView and its host app window; the system menu shows + /// upon right click, and a double click will trigger maximizing/restoration of the + /// window size. + /// + /// When set to `FALSE`, all non-client region support will be disabled. + /// The `app-region` CSS style will be ignored on web pages. + /// \snippet SettingsComponent.cpp ToggleNonClientRegionSupportEnabled + /// + function Get_IsNonClientRegionSupportEnabled(out value: Integer): HResult; stdcall; + /// + /// Set the IsNonClientRegionSupportEnabled property + /// + function Set_IsNonClientRegionSupportEnabled(value: Integer): HResult; stdcall; + end; + + /// + /// Event args for the `WebResourceRequested` event. + /// + /// + /// See the ICoreWebView2WebResourceRequestedEventArgs2 article. + /// + ICoreWebView2WebResourceRequestedEventArgs2 = interface(ICoreWebView2WebResourceRequestedEventArgs) + ['{9C562C24-B219-4D7F-92F6-B187FBBADD56}'] + /// + /// The web resource requested source. + /// + function Get_RequestedSourceKind(out value: COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS): HResult; stdcall; + end; + + /// + /// Receives `NonClientRegionChanged` events. + /// + /// + /// See the ICoreWebView2NonClientRegionChangedEventHandler article. + /// + ICoreWebView2NonClientRegionChangedEventHandler = interface(IUnknown) + ['{4A794E66-AA6C-46BD-93A3-382196837680}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2CompositionController; + const args: ICoreWebView2NonClientRegionChangedEventArgs): HResult; stdcall; + end; + + /// + /// This is the Interface for non-client region change event args. + /// + /// + /// See the ICoreWebView2NonClientRegionChangedEventArgs article. + /// + ICoreWebView2NonClientRegionChangedEventArgs = interface(IUnknown) + ['{AB71D500-0820-4A52-809C-48DB04FF93BF}'] + /// + /// This property represents the COREWEBVIEW2_NON_CLIENT_REGION_KIND which the + /// region changed event corresponds to. With this property an app can query + /// for a collection of rects which have that region kind by using + /// QueryNonClientRegion on the composition controller. + /// + function Get_RegionKind(out value: COREWEBVIEW2_NON_CLIENT_REGION_KIND): HResult; stdcall; + end; + + /// + /// A continuation of the ICoreWebView2CompositionController4 interface. + /// This interface includes an API which exposes the DragStarting event. + /// + /// + /// See the ICoreWebView2CompositionController5 article. + /// + ICoreWebView2CompositionController5 = interface(ICoreWebView2CompositionController4) + ['{8D0F82EB-7C33-5A4C-9108-84CA28CCC3B4}'] + /// + /// Adds an event handler for the `DragStarting` event. + /// `DragStarting` is a deferrable event that is raised when the WebView2 + /// detects a drag started within the WebView2. + /// WebView2's default drag behavior is to synchronously call DoDragDrop when + /// it detects drag. This event's args expose the data WebView2 uses to call + /// DoDragDrop to allow users to implement their own drag logic and override + /// WebView2's. + /// Handlers of this event must set the `Handled` event to true in order to + /// override WebView2's default logic. When invoking drag logic asynchronously + /// using a deferral, handlers must take care to follow these steps in order: + /// * Invoke asynchronous drag logic + /// * Set the event args `Handled` property true + /// * Complete the deferral + /// In the asynchronous case, WebView2 decides whether or not to invoke its + /// default drag logic when the deferral completes. So the event args' + /// `Handled` property must be true when the deferral is completed. + /// \snippet ScenarioDragDropOverride.cpp DragStarting + /// + /// + /// See the ICoreWebView2CompositionController5 article. + /// + function add_DragStarting(const eventHandler: ICoreWebView2DragStartingEventHandler; + out token: EventRegistrationToken): HResult; stdcall; + /// + /// Removes an event handler previously added with `add_DragStarting`. + /// + /// + /// See the ICoreWebView2CompositionController5 article. + /// + function remove_DragStarting(token: EventRegistrationToken): HResult; stdcall; + end; + + /// + /// Receives `DragStarting` events. + /// + /// + /// See the ICoreWebView2DragStartingEventHandler article. + /// + ICoreWebView2DragStartingEventHandler = interface(IUnknown) + ['{3B149321-83C3-5D1F-B03F-A42899BC1C15}'] + /// + /// Provides the event args for the corresponding event. + /// + function Invoke(const sender: ICoreWebView2CompositionController; + const args: ICoreWebView2DragStartingEventArgs): HResult; stdcall; + end; + + /// + /// Event args for the `DragStarting` event. + /// + /// + /// See the ICoreWebView2DragStartingEventArgs article. + /// + ICoreWebView2DragStartingEventArgs = interface(IUnknown) + ['{8B8D9C7E-2F1A-4E6B-9D5A-3C8F7B9E1A2D}'] + /// + /// The [OLE DROPEFFECT](/windows/win32/com/dropeffect-constants) + /// values this drag data supports. + /// + function Get_AllowedDropEffects(out value: LongWord): HResult; stdcall; + /// + /// The data to be dragged. + /// + function Get_Data(out value: IDataObject): HResult; stdcall; + /// + /// Gets the `Handled` property. + /// + function Get_Handled(out value: Integer): HResult; stdcall; + /// + /// Indicates whether this event has been handled by the app. If the + /// app handles this event, WebView2 will not initiate drag drop. If + /// the app does not handle the event, WebView2 will initiate its own + /// drag drop logic. + /// + function Set_Handled(value: Integer): HResult; stdcall; + /// + /// The position at which drag was detected given in WebView2 relative + /// coordinates. + /// + function Get_Position(out value: tagPOINT): HResult; stdcall; + /// + /// Returns an `ICoreWebView2Deferral` object. Use this operation to complete + /// the CoreWebView2DragStartingEventArgs. + /// + /// Until the deferral is completed, subsequent attempts to initiate drag + /// in the WebView2 will fail and if the cursor was changed as part of + /// drag it will not restore. + /// + function GetDeferral(out value: ICoreWebView2Deferral): HResult; stdcall; + end; + + /// + /// A collection of RECT. + /// + /// + /// See the ICoreWebView2RegionRectCollectionView article. + /// + ICoreWebView2RegionRectCollectionView = interface(IUnknown) + ['{333353B8-48BF-4449-8FCC-22697FAF5753}'] + /// + /// The number of elements contained in the collection. + /// + function Get_Count(out value: SYSUINT): HResult; stdcall; + /// + /// Gets the element at the given index. + /// + function GetValueAtIndex(index: SYSUINT; out value: tagRECT): HResult; stdcall; + end; + + /// + /// Representation of a DOM + /// [File](https://developer.mozilla.org/docs/Web/API/File) object + /// passed via WebMessage. You can use this object to obtain the path of a + /// File dropped on WebView2. + /// + /// + /// See the ICoreWebView2File article. + /// + ICoreWebView2File = interface(IUnknown) + ['{F2C19559-6BC1-4583-A757-90021BE9AFEC}'] + /// + /// Get the absolute file path. + /// + /// The caller must free the returned string with `CoTaskMemFree`. See + /// [API Conventions](/microsoft-edge/webview2/concepts/win32-api-conventions#strings). + /// + function Get_Path(out value: PWideChar): HResult; stdcall; + end; + + /// + /// A collection of objects. + /// + /// + /// See the ICoreWebView2ObjectCollectionView article. + /// + ICoreWebView2ObjectCollectionView = interface(IUnknown) + ['{0F36FD87-4F69-4415-98DA-888F89FB9A33}'] + /// + /// The number of elements contained in the collection. + /// + function Get_Count(out value: SYSUINT): HResult; stdcall; + /// + /// Gets the element at the given index. + /// + function GetValueAtIndex(index: SYSUINT; out value: IUnknown): HResult; stdcall; + end; + + /// + /// Represents a collection of generic objects. Used to get, remove and add + /// objects at the specified index. + /// + /// + /// See the ICoreWebView2ObjectCollection article. + /// + ICoreWebView2ObjectCollection = interface(ICoreWebView2ObjectCollectionView) + ['{5CFEC11C-25BD-4E8D-9E1A-7ACDAEEEC047}'] + /// + /// Removes the object at the specified index. + /// + function RemoveValueAtIndex(index: SYSUINT): HResult; stdcall; + /// + /// Inserts the object at the specified index. + /// + function InsertValueAtIndex(index: SYSUINT; const value: IUnknown): HResult; stdcall; + end; + + /// + /// Interface that provides methods related to the environment settings of CoreWebView2. + /// This interface allows for the creation of new `FindOptions` objects. + /// + /// + /// See the ICoreWebView2Environment15 article. + /// + ICoreWebView2Environment15 = interface(ICoreWebView2Environment14) + ['{2AC5EBFB-E654-5961-A667-7971885C7B27}'] + /// + /// Creates a new instance of a CoreWebView2FindOptions object. + /// This find options object can be used to define parameters for a find session. + /// Returns the newly created FindOptions object. + /// + function CreateFindOptions(out value: ICoreWebView2FindOptions): HResult; stdcall; + end; + + /// + /// Extension of WebMessageReceivedEventArgs to provide access to additional + /// WebMessage objects. + /// + /// + /// See the ICoreWebView2WebMessageReceivedEventArgs2 article. + /// + ICoreWebView2WebMessageReceivedEventArgs2 = interface(ICoreWebView2WebMessageReceivedEventArgs) + ['{06FC7AB7-C90C-4297-9389-33CA01CF6D5E}'] + /// + /// Additional received WebMessage objects. To pass `additionalObjects` via + /// WebMessage to the app, use the + /// `chrome.webview.postMessageWithAdditionalObjects` content API. + /// Any DOM object type that can be natively representable that has been + /// passed in to `additionalObjects` parameter will be accessible here. + /// Currently a WebMessage object can be the `ICoreWebView2File` type. + /// Entries in the collection can be `nullptr` if `null` or `undefined` was + /// passed. + /// + function Get_AdditionalObjects(out value: ICoreWebView2ObjectCollectionView): HResult; stdcall; + end; + +implementation + +uses + {$IFDEF DELPHI16_UP} + System.Win.ComObj; + {$ELSE} + ComObj; + {$ENDIF} + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVTypes.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVTypes.pas new file mode 100644 index 000000000..80a1163ab --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVTypes.pas @@ -0,0 +1,738 @@ +unit uRESTDWPrivWVTypes; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + System.Classes, + {$ELSE} + Classes, + {$ENDIF} + uRESTDWPrivWVTypeLibrary; + +type + {$IFDEF DELPHI12_UP} + wvstring = type string; + {$ELSE} + {$IFDEF FPC} + wvstring = type UnicodeString; + {$ELSE} + wvstring = type WideString; + {$ENDIF} + {$ENDIF} + + /// + /// Specifies the key event type that triggered an AcceleratorKeyPressed + /// event. + /// + /// + /// Renamed COREWEBVIEW2_KEY_EVENT_KIND type. + /// + TWVKeyEventKind = type COREWEBVIEW2_KEY_EVENT_KIND; + /// + /// Specifies the reason for moving focus. + /// + /// + /// Renamed COREWEBVIEW2_MOVE_FOCUS_REASON type. + /// + TWVMoveFocusReason = type COREWEBVIEW2_MOVE_FOCUS_REASON; + /// + /// Indicates the error status values for web navigations. + /// + /// + /// Renamed COREWEBVIEW2_WEB_ERROR_STATUS type. + /// + TWVWebErrorStatus = type COREWEBVIEW2_WEB_ERROR_STATUS; + /// + /// Specifies the JavaScript dialog type used in the + /// ICoreWebView2ScriptDialogOpeningEventHandler interface. + /// + /// + /// Renamed COREWEBVIEW2_SCRIPT_DIALOG_KIND type. + /// + TWVScriptDialogKind = type COREWEBVIEW2_SCRIPT_DIALOG_KIND; + /// + /// Specifies the response to a permission request. + /// + /// + /// Renamed COREWEBVIEW2_PERMISSION_STATE type. + /// + TWVPermissionState = type COREWEBVIEW2_PERMISSION_STATE; + /// + /// Indicates the type of a permission request. + /// + /// + /// Renamed COREWEBVIEW2_PERMISSION_KIND type. + /// + TWVPermissionKind = type COREWEBVIEW2_PERMISSION_KIND; + /// + /// Specifies the process failure type used in the + /// `ICoreWebView2ProcessFailedEventArgs` interface. The values in this enum + /// make reference to the process kinds in the Chromium architecture. For more + /// information about what these processes are and what they do, see + /// [Browser Architecture - Inside look at modern web browser](https://developers.google.com/web/updates/2018/09/inside-browser-part1). + /// + /// + /// Renamed COREWEBVIEW2_PROCESS_FAILED_KIND type. + /// + TWVProcessFailedKind = type COREWEBVIEW2_PROCESS_FAILED_KIND; + /// + /// Specifies the image format for the ICoreWebView2.CapturePreview method. + /// + /// + /// Renamed COREWEBVIEW2_CAPTURE_PREVIEW_IMAGE_FORMAT type. + /// + TWVCapturePreviewImageFormat = type COREWEBVIEW2_CAPTURE_PREVIEW_IMAGE_FORMAT; + /// + /// Specifies the web resource request contexts. + /// + /// + /// Renamed COREWEBVIEW2_WEB_RESOURCE_CONTEXT type. + /// + TWVWebResourceContext = type COREWEBVIEW2_WEB_RESOURCE_CONTEXT; + /// + /// Kind of cookie SameSite status used in the ICoreWebView2Cookie interface. + /// These fields match those as specified in https://developer.mozilla.org/docs/Web/HTTP/Cookies#. + /// Learn more about SameSite cookies here: https://tools.ietf.org/html/draft-west-first-party-cookies-07 + /// + /// + /// Renamed COREWEBVIEW2_COOKIE_SAME_SITE_KIND type. + /// + TWVCookieSameSiteKind = type COREWEBVIEW2_COOKIE_SAME_SITE_KIND; + /// + /// Kind of cross origin resource access allowed for host resources during download. + /// Note that other normal access checks like same origin DOM access check and [Content + /// Security Policy](https://developer.mozilla.org/docs/Web/HTTP/CSP) still apply. + /// The following table illustrates the host resource cross origin access according to + /// access context and COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND. + /// + /// Cross Origin Access Context | DENY | ALLOW | DENY_CORS + /// --- | --- | --- | --- + /// From DOM like src of img, script or iframe element| Deny | Allow | Allow + /// From Script like Fetch or XMLHttpRequest| Deny | Allow | Deny + /// + /// + /// Renamed COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND type. + /// + TWVHostResourceAcccessKind = type COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND; + /// + /// State of the download operation. + /// + /// + /// Renamed COREWEBVIEW2_DOWNLOAD_STATE type. + /// + TWVDownloadState = type COREWEBVIEW2_DOWNLOAD_STATE; + /// + /// Reason why a download was interrupted. + /// + /// + /// Renamed COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON type. + /// + TWVDownloadInterruptReason = type COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON; + /// + /// Specifies the client certificate kind. + /// + /// + /// Renamed COREWEBVIEW2_CLIENT_CERTIFICATE_KIND type. + /// + TWVClientCertificateKind = type COREWEBVIEW2_CLIENT_CERTIFICATE_KIND; + /// + /// Specifies the browser process exit type used in the + /// ICoreWebView2BrowserProcessExitedEventArgs interface. + /// + /// + /// Renamed COREWEBVIEW2_BROWSER_PROCESS_EXIT_KIND type. + /// + TWVBrowserProcessExitKind = type COREWEBVIEW2_BROWSER_PROCESS_EXIT_KIND; + /// + /// Mouse event type used by SendMouseInput to convey the type of mouse event + /// being sent to WebView. The values of this enum align with the matching + /// WM_* window messages. + /// + /// + /// Renamed COREWEBVIEW2_MOUSE_EVENT_KIND type. + /// + TWVMouseEventKind = type COREWEBVIEW2_MOUSE_EVENT_KIND; + /// + /// Mouse event virtual keys associated with a COREWEBVIEW2_MOUSE_EVENT_KIND for + /// SendMouseInput. These values can be combined into a bit flag if more than + /// one virtual key is pressed for the event. The values of this enum align + /// with the matching MK_* mouse keys. + /// + /// + /// Renamed COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS type. + /// + TWVMouseEventVirtualKeys = type COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS; + /// + /// Pointer event type used by SendPointerInput to convey the type of pointer + /// event being sent to WebView. The values of this enum align with the + /// matching WM_POINTER* window messages. + /// + /// + /// Renamed COREWEBVIEW2_POINTER_EVENT_KIND type. + /// + TWVPointerEventKind = type COREWEBVIEW2_POINTER_EVENT_KIND; + /// + /// Mode for how the Bounds property is interpreted in relation to the RasterizationScale property. + /// + /// + /// Renamed COREWEBVIEW2_BOUNDS_MODE type. + /// + TWVBoundsMode = type COREWEBVIEW2_BOUNDS_MODE; + /// + /// Specifies the process failure reason used in the + /// ICoreWebView2ProcessFailedEventHandler interface. + /// + /// + /// Renamed COREWEBVIEW2_PROCESS_FAILED_REASON type. + /// + TWVProcessFailedReason = type COREWEBVIEW2_PROCESS_FAILED_REASON; + /// + /// The orientation for printing, used by the Orientation property on + /// ICoreWebView2PrintSettings. + /// + /// + /// Renamed COREWEBVIEW2_PRINT_ORIENTATION type. + /// + TWVPrintOrientation = type COREWEBVIEW2_PRINT_ORIENTATION; + /// + /// A value representing RGBA color (Red, Green, Blue, Alpha) for WebView2. + /// Each component takes a value from 0 to 255, with 0 being no intensity and 255 being the highest intensity. + /// + /// + /// Renamed COREWEBVIEW2_COLOR type. + /// + TWVColor = type COREWEBVIEW2_COLOR; + /// + /// The default download dialog can be aligned to any of the WebView corners + /// by setting the DefaultDownloadDialogCornerAlignment property. The default + /// position is top-right corner. + /// + /// + /// Renamed COREWEBVIEW2_DEFAULT_DOWNLOAD_DIALOG_CORNER_ALIGNMENT type. + /// + TWVDefaultDownloadDialogCornerAlignment = type COREWEBVIEW2_DEFAULT_DOWNLOAD_DIALOG_CORNER_ALIGNMENT; + /// + /// Indicates the process type used in the ICoreWebView2ProcessInfo interface. + /// + /// + /// Renamed COREWEBVIEW2_PROCESS_KIND type. + /// + TWVProcessKind = type COREWEBVIEW2_PROCESS_KIND; + /// + /// Specifies the menu item kind + /// for the ICoreWebView2ContextMenuItem.get_Kind method + /// + /// + /// Renamed COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND type. + /// + TWVMenuItemKind = type COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND; + /// + /// Indicates the kind of context for which the context menu was created + /// for the `ICoreWebView2ContextMenuTarget::get_Kind` method. + /// This enum will always represent the active element that caused the context menu request. + /// If there is a selection with multiple images, audio and text, for example, the element that + /// the end user right clicks on within this selection will be the option represented by this enum. + /// + /// + /// Renamed COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND type. + /// + TWVMenuTargetKind = type COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND; + /// + /// PDF toolbar item. This enum must be in sync with ToolBarItem in pdf-store-data-types.ts + /// Specifies the PDF toolbar item types used for the ICoreWebView2Settings.put_HiddenPdfToolbarItems method. + /// + /// + /// Renamed COREWEBVIEW2_PDF_TOOLBAR_ITEMS type. + /// + TWVPDFToolbarItems = type COREWEBVIEW2_PDF_TOOLBAR_ITEMS; + /// + /// An enum to represent the options for WebView2 color scheme: auto, light, or dark. + /// + /// + /// Renamed COREWEBVIEW2_PREFERRED_COLOR_SCHEME type. + /// + TWVPreferredColorScheme = type COREWEBVIEW2_PREFERRED_COLOR_SCHEME; + /// + /// Specifies the datatype for the + /// ICoreWebView2Profile2.ClearBrowsingData method. + /// + /// + /// Renamed COREWEBVIEW2_BROWSING_DATA_KINDS type. + /// + TWVBrowsingDataKinds = type COREWEBVIEW2_BROWSING_DATA_KINDS; + /// + /// Specifies the action type when server certificate error is detected to be + /// used in the ICoreWebView2ServerCertificateErrorDetectedEventArgs + /// interface. + /// + /// + /// Renamed COREWEBVIEW2_SERVER_CERTIFICATE_ERROR_ACTION type. + /// + TWVServerCertificateErrorAction = type COREWEBVIEW2_SERVER_CERTIFICATE_ERROR_ACTION; + /// + /// Specifies the image format to use for favicon. + /// + /// + /// Renamed COREWEBVIEW2_FAVICON_IMAGE_FORMAT type. + /// + TWVFaviconImageFormat = type COREWEBVIEW2_FAVICON_IMAGE_FORMAT; + /// + /// Specifies the collation for a print. + /// + /// + /// Renamed COREWEBVIEW2_PRINT_COLLATION type. + /// + TWVPrintCollation = type COREWEBVIEW2_PRINT_COLLATION; + /// + /// Specifies the color mode for a print. + /// + /// + /// Renamed COREWEBVIEW2_PRINT_COLOR_MODE type. + /// + TWVPrintColorMode = type COREWEBVIEW2_PRINT_COLOR_MODE; + /// + /// Specifies the duplex option for a print. + /// + /// + /// Renamed COREWEBVIEW2_PRINT_DUPLEX type. + /// + TWVPrintDuplex = type COREWEBVIEW2_PRINT_DUPLEX; + /// + /// Specifies the media size for a print. + /// + /// + /// Renamed COREWEBVIEW2_PRINT_MEDIA_SIZE type. + /// + TWVPrintMediaSize = type COREWEBVIEW2_PRINT_MEDIA_SIZE; + /// + /// Indicates the status for printing. + /// + /// + /// Renamed COREWEBVIEW2_PRINT_STATUS type. + /// + TWVPrintStatus = type COREWEBVIEW2_PRINT_STATUS; + /// + /// Specifies the print dialog kind. + /// + /// + /// Renamed COREWEBVIEW2_PRINT_DIALOG_KIND type. + /// + TWVPrintDialogKind = type COREWEBVIEW2_PRINT_DIALOG_KIND; + /// + /// Specifies the desired access from script to CoreWebView2SharedBuffer. + /// + /// + /// Renamed COREWEBVIEW2_SHARED_BUFFER_ACCESS type. + /// + TWVSharedBufferAccess = type COREWEBVIEW2_SHARED_BUFFER_ACCESS; + /// + /// Tracking prevention levels. + /// + /// + /// Renamed COREWEBVIEW2_TRACKING_PREVENTION_LEVEL type. + /// + TWVTrackingPreventionLevel = type COREWEBVIEW2_TRACKING_PREVENTION_LEVEL; + /// + /// Specifies memory usage target level of WebView. + /// + /// + /// Renamed COREWEBVIEW2_MEMORY_USAGE_TARGET_LEVEL type. + /// + TWVMemoryUsageTargetLevel = type COREWEBVIEW2_MEMORY_USAGE_TARGET_LEVEL; + /// + /// Specifies the navigation kind of each navigation. + /// + /// + /// Renamed COREWEBVIEW2_NAVIGATION_KIND type. + /// + TWVNavigationKind = type COREWEBVIEW2_NAVIGATION_KIND; + /// + /// Indicates the frame type used in the `ICoreWebView2FrameInfo` interface. + /// + /// + /// Renamed COREWEBVIEW2_FRAME_KIND type. + /// + TWVFrameKind = type COREWEBVIEW2_FRAME_KIND; + /// + /// Specifies the source of `WebResourceRequested` event. + /// + /// + /// Renamed COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS type. + /// + TWVWebResourceRequestSourceKind = type COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS; + /// + /// This enum contains values representing possible regions a given + /// point lies within. The values of this enum align with the + /// matching WM_NCHITTEST* window message return values. + /// + /// + /// Renamed COREWEBVIEW2_NON_CLIENT_REGION_KIND type. + /// + TWVNonClientRegionKind = type COREWEBVIEW2_NON_CLIENT_REGION_KIND; + /// + /// The channel search kind determines the order that release channels are + /// searched for during environment creation. The default behavior is to search + /// for and use the most stable channel found on the device. The order from most + /// to least stable is: WebView2 Runtime -> Beta -> Dev -> Canary. Switch the + /// order to prefer the least stable channel in order to perform pre-release + /// testing. See `COREWEBVIEW2_RELEASE_CHANNELS` for descriptions of channels. + /// + /// + /// Renamed COREWEBVIEW2_CHANNEL_SEARCH_KIND type. + /// + TWVChannelSearchKind = type COREWEBVIEW2_CHANNEL_SEARCH_KIND; + /// + /// The WebView2 release channels. Use `ReleaseChannels` and `ChannelSearchKind` + /// on `ICoreWebView2EnvironmentOptions` to control which channel is searched + /// for during environment creation. + /// + /// |Channel|Primary purpose|How often updated with new features| + /// |:---:|---|:---:| + /// |Stable (WebView2 Runtime)|Broad Deployment|Monthly| + /// |Beta|Flighting with inner rings, automated testing|Monthly| + /// |Dev|Automated testing, selfhosting to test new APIs and features|Weekly| + /// |Canary|Automated testing, selfhosting to test new APIs and features|Daily| + /// + /// + /// + /// Renamed COREWEBVIEW2_RELEASE_CHANNELS type. + /// + TWVReleaseChannels = type COREWEBVIEW2_RELEASE_CHANNELS; + /// + /// Set ScrollBar style on `ICoreWebView2EnvironmentOptions` during environment creation. + /// + /// + /// Renamed COREWEBVIEW2_SCROLLBAR_STYLE type. + /// + TWVScrollBarStyle = type COREWEBVIEW2_SCROLLBAR_STYLE; + /// + /// Allowed permissions of a CoreWebView2FileSystemHandle as described in + /// [FileSystemHandle.requestPermission()](https://developer.mozilla.org/docs/Web/API/FileSystemHandle/requestPermission) + /// + /// + /// Renamed COREWEBVIEW2_FILE_SYSTEM_HANDLE_PERMISSION type. + /// + TWVFileSystemHandlePermission = type COREWEBVIEW2_FILE_SYSTEM_HANDLE_PERMISSION; + /// + /// Kind of CoreWebView2FileSystemHandle as described in + /// [FileSystemHandle.kind](https://developer.mozilla.org/docs/Web/API/FileSystemHandle/kind) + /// + /// + /// Renamed COREWEBVIEW2_FILE_SYSTEM_HANDLE_KIND type. + /// + TWVFileSystemHandleKind = type COREWEBVIEW2_FILE_SYSTEM_HANDLE_KIND; + /// + /// Indicates the text direction of the notification. + /// + /// + /// Renamed COREWEBVIEW2_TEXT_DIRECTION_KIND type. + /// + TWVTextDirectionKind = type COREWEBVIEW2_TEXT_DIRECTION_KIND; + /// + /// Specifies Save As kind selection options for + /// `ICoreWebView2SaveAsUIShowingEventArgs`. + /// + /// For HTML documents, we support 3 Save As kinds: HTML_ONLY, SINGLE_FILE and + /// COMPLETE. For non-HTML documents, you must use DEFAULT. MIME types of `text/html` and + /// `application/xhtml+xml` are considered HTML documents. + /// + /// + /// Renamed COREWEBVIEW2_SAVE_AS_KIND type. + /// + TWVSaveAsKind = type COREWEBVIEW2_SAVE_AS_KIND; + /// + /// Status of a programmatic Save As call. Indicates the result + /// of the `ShowSaveAsUI` method. + /// + /// + /// Renamed COREWEBVIEW2_SAVE_AS_UI_RESULT type. + /// + TWVSaveAsUIResult = type COREWEBVIEW2_SAVE_AS_UI_RESULT; + + /// + /// TWVLoader status values + /// + TWV2LoaderStatus = (wvlsCreated, + wvlsLoading, + wvlsLoaded, + wvlsImported, + wvlsInitialized, + wvlsError, + wvlsUnloaded); + /// + /// Event type used by TWVBrowserBase.SimulateKeyEvent + /// + TWV2KeyEventType = (ketKeyDown, + ketKeyUp, + ketRawKeyDown, + ketChar); + + /// + /// Debug log values used by TWVLoader.DebugLog + /// + TWV2DebugLog = (dlDisabled, + dlEnabled, + dlEnabledStdOut, + dlEnabledStdErr); + + /// + /// Debug log level used when the logging is enabled + /// + TWV2DebugLogLevel = (dllDefault, + dllInfo, + dllWarning, + dllError, + dllFatal); + + /// + /// Blink editing commands used by the "Input.dispatchKeyEvent" DevTools method. + /// + /// + /// See the "Input.dispatchKeyEvent" DevTools method. + /// See the Chromium sources. + /// + TWV2EditingCommand = (ecAlignCenter, + ecAlignJustified, + ecAlignLeft, + ecAlignRight, + ecBackColor, + ecBackwardDelete, + ecBold, + ecCopy, + ecCreateLink, + ecCut, + ecDefaultParagraphSeparator, + ecDelete, + ecDeleteBackward, + ecDeleteBackwardByDecomposingPreviousCharacter, + ecDeleteForward, + ecDeleteToBeginningOfLine, + ecDeleteToBeginningOfParagraph, + ecDeleteToEndOfLine, + ecDeleteToEndOfParagraph, + ecDeleteToMark, + ecDeleteWordBackward, + ecDeleteWordForward, + ecFindString, + ecFontName, + ecFontSize, + ecFontSizeDelta, + ecForeColor, + ecFormatBlock, + ecForwardDelete, + ecHiliteColor, + ecIgnoreSpelling, + ecIndent, + ecInsertBacktab, + ecInsertHorizontalRule, + ecInsertHTML, + ecInsertImage, + ecInsertLineBreak, + ecInsertNewline, + ecInsertNewlineInQuotedContent, + ecInsertOrderedList, + ecInsertParagraph, + ecInsertTab, + ecInsertText, + ecInsertUnorderedList, + ecItalic, + ecJustifyCenter, + ecJustifyFull, + ecJustifyLeft, + ecJustifyNone, + ecJustifyRight, + ecMakeTextWritingDirectionLeftToRight, + ecMakeTextWritingDirectionNatural, + ecMakeTextWritingDirectionRightToLeft, + ecMoveBackward, + ecMoveBackwardAndModifySelection, + ecMoveDown, + ecMoveDownAndModifySelection, + ecMoveForward, + ecMoveForwardAndModifySelection, + ecMoveLeft, + ecMoveLeftAndModifySelection, + ecMovePageDown, + ecMovePageDownAndModifySelection, + ecMovePageUp, + ecMovePageUpAndModifySelection, + ecMoveParagraphBackward, + ecMoveParagraphBackwardAndModifySelection, + ecMoveParagraphForward, + ecMoveParagraphForwardAndModifySelection, + ecMoveRight, + ecMoveRightAndModifySelection, + ecMoveToBeginningOfDocument, + ecMoveToBeginningOfDocumentAndModifySelection, + ecMoveToBeginningOfLine, + ecMoveToBeginningOfLineAndModifySelection, + ecMoveToBeginningOfParagraph, + ecMoveToBeginningOfParagraphAndModifySelection, + ecMoveToBeginningOfSentence, + ecMoveToBeginningOfSentenceAndModifySelection, + ecMoveToEndOfDocument, + ecMoveToEndOfDocumentAndModifySelection, + ecMoveToEndOfLine, + ecMoveToEndOfLineAndModifySelection, + ecMoveToEndOfParagraph, + ecMoveToEndOfParagraphAndModifySelection, + ecMoveToEndOfSentence, + ecMoveToEndOfSentenceAndModifySelection, + ecMoveToLeftEndOfLine, + ecMoveToLeftEndOfLineAndModifySelection, + ecMoveToRightEndOfLine, + ecMoveToRightEndOfLineAndModifySelection, + ecMoveUp, + ecMoveUpAndModifySelection, + ecMoveWordBackward, + ecMoveWordBackwardAndModifySelection, + ecMoveWordForward, + ecMoveWordForwardAndModifySelection, + ecMoveWordLeft, + ecMoveWordLeftAndModifySelection, + ecMoveWordRight, + ecMoveWordRightAndModifySelection, + ecOutdent, + ecOverWrite, + ecPaste, + ecPasteAndMatchStyle, + ecPasteGlobalSelection, + ecPrint, + ecRedo, + ecRemoveFormat, + ecScrollLineDown, + ecScrollLineUp, + ecScrollPageBackward, + ecScrollPageForward, + ecScrollToBeginningOfDocument, + ecScrollToEndOfDocument, + ecSelectAll, + ecSelectLine, + ecSelectParagraph, + ecSelectSentence, + ecSelectToMark, + ecSelectWord, + ecSetMark, + ecStrikethrough, + ecStyleWithCSS, + ecSubscript, + ecSuperscript, + ecSwapWithMark, + ecToggleBold, + ecToggleItalic, + ecToggleUnderline, + ecTranspose, + ecUnderline, + ecUndo, + ecUnlink, + ecUnscript, + ecUnselect, + ecUseCSS, + ecYank, + ecYankAndSelect); + + /// + /// Record used by GetDLLVersion to get the DLL version information + /// + TFileVersionInfo = record + MajorVer : word; + MinorVer : word; + Release : word; + Build : word; + end; + + /// + /// Record used by TCoreWebView2WindowFeatures.CopyToRecord to copy the windows featres + /// + TWVWindowFeatures = record + HasPosition : boolean; + HasSize : boolean; + Left : cardinal; + Top : cardinal; + Width : cardinal; + Height : cardinal; + ShouldDisplayMenuBar : boolean; + ShouldDisplayStatus : boolean; + ShouldDisplayToolbar : boolean; + ShouldDisplayScrollBars : boolean; + end; + + /// + /// Used by TWVBrowserBase.ClearDataForOrigin to clear the storage + /// + /// + /// See the documentation for the Storage.StorageType type. + /// + TWVClearDataStorageTypes = (cdstCookies, + cdstFileSystems, + cdstIndexeddb, + cdstLocalStorage, + cdstShaderCache, + cdstWebsql, + cdstServiceWorkers, + cdstCacheStorage, + cdstInterestGroups, + cdstSharedStorage, + cdstStorageBuckets, + cdstAll, + cdstOther); + + /// + /// Represents the state of a setting. + /// + TWVState = ( + /// + /// Use the default state for the setting. + /// + STATE_DEFAULT = 0, + /// + /// Enable or allow the setting. + /// + STATE_ENABLED, + /// + /// Disable or disallow the setting. + /// + STATE_DISABLED + ); + + /// + /// Autoplay policy types used by TWVLoader.AutoplayPolicy. See the --autoplay-policy switch. + /// + TWVAutoplayPolicy = (appDefault, + appDocumentUserActivationRequired, + appNoUserGestureRequired, + appUserGestureRequired); + + /// + /// Record with all the information to create a TCoreWebView2CustomSchemeRegistration instance to register a custom scheme. + /// + TWVCustomSchemeInfo = record + /// + /// The name of the custom scheme to register. + /// + SchemeName : wvstring; + /// + /// Whether the sites with this scheme will be treated as a Secure Context like an HTTPS site. + /// + TreatAsSecure : boolean; + /// + /// Comma separated list of origins that are allowed to issue requests with the custom scheme, such as XHRs and subresource requests that have an Origin header. + /// + AllowedDomains : wvstring; + /// + /// Set this property to true if the URIs with this custom scheme will have an authority component (a host for custom schemes). + /// + HasAuthorityComponent : boolean; + end; + TWVCustomSchemeInfoArray = array of TWVCustomSchemeInfo; + + TWVCustomSchemeRegistrationArray = array of ICoreWebView2CustomSchemeRegistration; + +implementation + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVWinControl.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVWinControl.pas new file mode 100644 index 000000000..30c77bad2 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVWinControl.pas @@ -0,0 +1,120 @@ +unit uRESTDWPrivWVWinControl; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + WinApi.Windows, System.Classes, Vcl.Controls, Vcl.Graphics; + {$ELSE} + Windows, Classes, Controls, Graphics; + {$ENDIF} + +type + /// + /// Parent control that will be used by TWVWindowParent in VCL and LCL applications to show the web contents. + /// + TWVWinControl = class(TWinControl) + protected + function GetChildWindowHandle : THandle; + procedure Resize; override; + + public + /// + /// Creates underlying screen object. + /// + procedure CreateHandle; override; + /// + /// Invalidates all child controls created by the browser. + /// + procedure InvalidateChildren; + /// + /// Updates the size of the child controls created by the browser. + /// + procedure UpdateSize; virtual; + /// + /// Handle of the first child control created by the browser. + /// + property ChildWindowHandle : THandle read GetChildWindowHandle; + + published + property Align; + property Anchors; + property Color; + property Constraints; + property TabStop; + property TabOrder; + property Visible; + property Enabled; + property ShowHint; + property Hint; + property DragKind; + property DragCursor; + property DragMode; + property OnResize; + property OnEnter; + property OnExit; + property OnDragDrop; + property OnDragOver; + property OnStartDrag; + property OnEndDrag; + {$IFNDEF FPC} + property OnCanResize; + {$ENDIF} + {$IFDEF DELPHI14_UP} + property Touch; + property OnGesture; + {$ENDIF} + property DoubleBuffered; + {$IFDEF DELPHI12_UP} + property ParentDoubleBuffered; + {$ENDIF} + end; + +implementation + +function TWVWinControl.GetChildWindowHandle : THandle; +begin + if not(csDesigning in ComponentState) and HandleAllocated then + Result := GetWindow(Handle, GW_CHILD) + else + Result := 0; +end; + +procedure TWVWinControl.CreateHandle; +begin + inherited CreateHandle; +end; + +procedure TWVWinControl.InvalidateChildren; +begin + if HandleAllocated then + RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_ALLCHILDREN); +end; + +procedure TWVWinControl.UpdateSize; +var + TempRect : TRect; + TempHWND : THandle; +begin + TempHWND := ChildWindowHandle; + if (TempHWND = 0) then exit; + + TempRect := GetClientRect; + + SetWindowPos(TempHWND, 0, + 0, 0, TempRect.right, TempRect.bottom, + SWP_NOZORDER); +end; + +procedure TWVWinControl.Resize; +begin + inherited Resize; + + UpdateSize; +end; + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVWindowParent.pas b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVWindowParent.pas new file mode 100644 index 000000000..5a1497b8a --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/WebView/uRESTDWPrivWVWindowParent.pas @@ -0,0 +1,151 @@ +unit uRESTDWPrivWVWindowParent; + +{$IFDEF FPC}{$MODE Delphi}{$ENDIF} + +{$I webview2.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + WinApi.Windows, System.Classes, Vcl.Controls, WinApi.Messages, + {$ELSE} + Windows, Classes, Controls, {$IFNDEF FPC}Messages,{$ENDIF} + {$ENDIF} + uRESTDWPrivWVWinControl, uRESTDWPrivWVBrowserBase; + +type + {$IFNDEF FPC}{$IFDEF DELPHI16_UP}[ComponentPlatformsAttribute(pidWin32 or pidWin64)]{$ENDIF}{$ENDIF} + /// + /// Parent control used by VCL and LCL applications to show the web contents. + /// + TWVWindowParent = class(TWVWinControl) + protected + FBrowser : TWVBrowserBase; + + function GetBrowser : TWVBrowserBase; + + procedure SetBrowser(const aValue : TWVBrowserBase); + + procedure WndProc(var aMessage: TMessage); override; + procedure Notification(AComponent: TComponent; Operation: TOperation); override; + procedure Resize; override; + + public + constructor Create(AOwner : TComponent); override; + procedure UpdateSize; override; + /// + /// Moves focus into WebView. + /// + procedure SetFocus; override; + + published + /// + /// Browser associated to this control to show web contents. + /// + property Browser : TWVBrowserBase read GetBrowser write SetBrowser; + end; + +implementation + +constructor TWVWindowParent.Create(AOwner : TComponent); +begin + inherited Create(AOwner); + + FBrowser := nil; +end; + +procedure TWVWindowParent.Notification(AComponent: TComponent; Operation: TOperation); +begin + inherited Notification(AComponent, Operation); + + if (Operation = opRemove) and (AComponent = FBrowser) then + FBrowser := nil; +end; + +procedure TWVWindowParent.Resize; +begin + inherited Resize; + + UpdateSize; +end; + +function TWVWindowParent.GetBrowser: TWVBrowserBase; +begin + Result := FBrowser; +end; + +procedure TWVWindowParent.SetBrowser(const aValue : TWVBrowserBase); +begin + FBrowser := aValue; + + if (aValue <> nil) then + aValue.FreeNotification(Self); +end; + +procedure TWVWindowParent.UpdateSize; +begin + if (FBrowser <> nil) then + FBrowser.Bounds := ClientRect + else + inherited UpdateSize; +end; + +procedure TWVWindowParent.SetFocus; +begin + inherited SetFocus; + + if (FBrowser <> nil) then + FBrowser.SetFocus; +end; + +procedure TWVWindowParent.WndProc(var aMessage: TMessage); +{$IFNDEF FPC} +var + tmpVisible: boolean; +{$ENDIF} +begin + case aMessage.Msg of + WM_SETFOCUS: + begin + if (FBrowser <> nil) then + FBrowser.SetFocus; + + inherited WndProc(aMessage); + end; + + WM_ERASEBKGND: + if (ChildWindowHandle = 0) then + inherited WndProc(aMessage); + + {$IFNDEF FPC} + //CM_RECREATEWND is not implemented in Lazarus/FPC + CM_RECREATEWND: // #75: this VCL quirk kills CEF/WebView2 instantly + begin + if (FBrowser <> nil) then + begin + tmpVisible := FBrowser.IsVisible; + if tmpVisible then + FBrowser.IsVisible := False; // avoid flicker, 0 is GetDesktopHWND + FBrowser.ParentWindow := 0; + end + else + tmpVisible := False; // avoid compiler warning + try + inherited WndProc(aMessage); + finally + if (FBrowser <> nil) then + begin + FBrowser.ParentWindow := Self.Handle; + FBrowser.IsVisible := tmpVisible; + end; + end; + end; + {$ENDIF} + + else inherited WndProc(aMessage); + end; +end; + + +end. diff --git a/CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLComponentManager.pas b/CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLComponentManager.pas new file mode 100644 index 000000000..84c45e6b6 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLComponentManager.pas @@ -0,0 +1,1136 @@ +unit uRESTDWHTMLComponentManager; + +{$I uRESTDW.inc} +{$IFDEF FPC} +{$mode delphi}{$H+} +{$ENDIF} + +Interface + +uses + Classes, SysUtils, StrUtils, Forms, Controls, StdCtrls, ExtCtrls, ComCtrls, Dialogs, + Graphics, IniFiles, ImgList, Buttons, Grids, + {$IFDEF FPC} + EditBtn, Zipper, + {$ELSE} + {$IFDEF DELPHIXE2UP} + System.Zip, + {$ENDIF} + {$ENDIF} + uRESTDWHTMLIDECompat; + +const + CRESTDWHTMLProject = 'REST Dataware HTML Designer'; + CRESTDWHTMLVersion = '2.1'; + CRESTDWHTMLCreator = 'REST Dataware'; + CRESTDWHTMLTester = 'Gledson Prego'; + +type + {$IFDEF FPC} + TRESTDWHTMLFileNameEdit = class(TEditButton) + {$ELSE} + {$IFDEF DELPHI2009UP} + TRESTDWHTMLFileNameEdit = class(TButtonedEdit) + {$ELSE} + TRESTDWHTMLFileNameEdit = class(TEdit) + {$ENDIF} + {$ENDIF} + private + FFilter : String; + procedure BrowseClick(Sender : TObject); + public + constructor Create(AOwner : TComponent); override; + published + property Filter : String read FFilter write FFilter; + end; + +Procedure RESTDWCopyFileClassic( + const ASource, + ADestination : String); + +Function RESTDWHTMLComponentsPath(const AEditorLibrariesPath : String) : String; +Function RESTDWHTMLResolveJSClass(const AEditorLibrariesPath, + AJsFileName, AClassName : String; Out AHTML : String; + Out AVisual : Boolean; Out APlacement : String) : Boolean; + +Procedure InstallRESTDWHTMLComponent(const AEditorLibrariesPath : String); + +Procedure ConfigureRESTDWHTMLComponents(const AEditorLibrariesPath : String); + +Procedure ConfigureRESTDWHTMLProject(AProducer : TObject; const AEditorLibrariesPath : String); + +implementation + +uses + uRESTDWHTMLPageProducerAdapter; + +procedure RESTDWHTMLExtractZipFile(const AFileName, ADestination : String); +{$IFDEF FPC} +var + LUnZipper : TUnZipper; +{$ENDIF} +begin + {$IFDEF FPC} + LUnZipper := TUnZipper.Create; + try + LUnZipper.FileName := AFileName; + LUnZipper.OutputPath := ADestination; + LUnZipper.Examine; + LUnZipper.UnZipAllFiles; + finally + LUnZipper.Free; + end; + {$ELSE} + {$IFDEF DELPHIXE2UP} + TZipFile.ExtractZipFile(AFileName, ADestination); + {$ELSE} + Raise Exception.Create('ZIP extraction requires Delphi XE2 or newer.'); + {$ENDIF} + {$ENDIF} +end; + +Procedure RESTDWCopyFileClassic( + const ASource, + ADestination : String); +Var + LSource, + LDestination : TFileStream; +Begin + LSource := TFileStream.Create( + ASource, + fmOpenRead Or fmShareDenyWrite + ); + Try + LDestination := TFileStream.Create( + ADestination, + fmCreate + ); + Try + LDestination.CopyFrom( + LSource, + 0 + ); + Finally + LDestination.Free; + End; + Finally + LSource.Free; + End; +End; + +constructor TRESTDWHTMLFileNameEdit.Create(AOwner : TComponent); +begin + inherited Create(AOwner); + {$IFDEF FPC} + Button.Visible := True; + Button.Hint := 'Browse...'; + OnButtonClick := BrowseClick; + {$ELSE} + {$IFDEF DELPHI2009UP} + RightButton.Visible := True; + RightButton.Hint := 'Browse...'; + OnRightButtonClick := BrowseClick; + {$ELSE} + Hint := 'Double-click to browse...'; + ShowHint := True; + OnDblClick := BrowseClick; + {$ENDIF} + {$ENDIF} +end; + +procedure TRESTDWHTMLFileNameEdit.BrowseClick(Sender : TObject); +var + D : TOpenDialog; +begin + D := TOpenDialog.Create(nil); + try + D.Filter := FFilter; + if D.Execute then + Text := D.FileName; + finally + D.Free; + end; +end; + +Function SafeName(const AValue : String) : String; +Var + I : Integer; +Begin + Result := Trim(AValue); + For I := Length(Result) DownTo 1 Do + If Not ( + ((Result[I] >= 'a') And (Result[I] <= 'z')) Or + ((Result[I] >= 'A') And (Result[I] <= 'Z')) Or + ((Result[I] >= '0') And (Result[I] <= '9')) Or + (Result[I] = '_') Or + (Result[I] = '-') + ) Then + Delete(Result,I,1); + If Result = '' Then + Result := 'Component'; +End; + +Function RESTDWHTMLComponentsPath( + const AEditorLibrariesPath : String) : String; +Begin + Result := + IncludeTrailingPathDelimiter( + AEditorLibrariesPath + ) + + 'Packages'; + ForceDirectories(Result); +End; + +Function RESTDWHTMLReadAllText(const AFileName : String) : String; +Var + L : TStringList; +Begin + Result := ''; + If Not FileExists(AFileName) Then + Exit; + L := TStringList.Create; + Try + L.LoadFromFile(AFileName); + Result := L.Text; + Finally + L.Free; + End; +End; + +Function RESTDWHTMLJSUnescape(const AValue : String) : String; +Begin + Result := StringReplace(AValue,'\`','`',[rfReplaceAll]); + Result := StringReplace(Result,'\n',sLineBreak,[rfReplaceAll]); + Result := StringReplace(Result,'\r','',[rfReplaceAll]); + Result := StringReplace(Result,'\\','\',[rfReplaceAll]); +End; + +Function RESTDWHTMLExtractJSValue( + const AClassText, AName, ADefault : String) : String; +Var + LLower,LNeedle : String; + P,Q,R : Integer; + C : Char; +Begin + Result := ADefault; + LLower := LowerCase(AClassText); + LNeedle := LowerCase('static ' + AName); + P := Pos(LNeedle,LLower); + If P = 0 Then Exit; + P := PosEx('=',AClassText,P + Length(LNeedle)); + If P = 0 Then Exit; + Inc(P); + While (P <= Length(AClassText)) And (AClassText[P] <= ' ') Do Inc(P); + If P > Length(AClassText) Then Exit; + C := AClassText[P]; + If Not (C In ['''','"','`']) Then + Begin + Q := P; + While (Q <= Length(AClassText)) And + Not (AClassText[Q] In [';','}',#13,#10]) Do Inc(Q); + Result := Trim(Copy(AClassText,P,Q - P)); + Exit; + End; + Q := P + 1; + R := Q; + While R <= Length(AClassText) Do + Begin + If (AClassText[R] = C) And + ((R = Q) Or (AClassText[R - 1] <> '\')) Then Break; + Inc(R); + End; + If R <= Length(AClassText) Then + Result := RESTDWHTMLJSUnescape(Copy(AClassText,Q,R - Q)); +End; + +Function RESTDWHTMLExtractJSHTML(const AClassText : String) : String; +Var + LLower : String; + P,Q,R : Integer; + C : Char; +Begin + Result := ''; + LLower := LowerCase(AClassText); + P := Pos('static createhtml',LLower); + If P = 0 Then Exit; + P := PosEx('return',LLower,P); + If P = 0 Then Exit; + Inc(P,Length('return')); + While (P <= Length(AClassText)) And (AClassText[P] <= ' ') Do Inc(P); + If P > Length(AClassText) Then Exit; + C := AClassText[P]; + If Not (C In ['''','"','`']) Then Exit; + Q := P + 1; + R := Q; + While R <= Length(AClassText) Do + Begin + If (AClassText[R] = C) And + ((R = Q) Or (AClassText[R - 1] <> '\')) Then Break; + Inc(R); + End; + If R <= Length(AClassText) Then + Result := RESTDWHTMLJSUnescape(Copy(AClassText,Q,R - Q)); +End; + +Function RESTDWHTMLResolveJSClass( + const AEditorLibrariesPath,AJsFileName,AClassName : String; + Out AHTML : String; Out AVisual : Boolean; + Out APlacement : String) : Boolean; +Var + LFileName,LText,LLower,LClassText,LNeedle,LVisual : String; + P,B,I,Depth : Integer; + C, + Quote : Char; + InString, + Escaped : Boolean; +Begin + Result := False; + AHTML := ''; + AVisual := True; + APlacement := 'body'; + If (Trim(AJsFileName) = '') Or (Trim(AClassName) = '') Then Exit; + LFileName := AJsFileName; + If Not FileExists(LFileName) Then + LFileName := + IncludeTrailingPathDelimiter( + RESTDWHTMLComponentsPath(AEditorLibrariesPath) + ) + AJsFileName; + If Not FileExists(LFileName) Then Exit; + LText := RESTDWHTMLReadAllText(LFileName); + LLower := LowerCase(LText); + LNeedle := LowerCase('class ' + AClassName); + P := Pos(LNeedle,LLower); + If P = 0 Then Exit; + B := PosEx('{',LText,P + Length(LNeedle)); + If B = 0 Then Exit; + Depth := 0; + InString := False; + Escaped := False; + Quote := #0; + I := B; + While I <= Length(LText) Do + Begin + C := LText[I]; + If InString Then + Begin + If Escaped Then + Escaped := False + Else If C = '\' Then + Escaped := True + Else If C = Quote Then + InString := False; + End + Else If C In ['''','"','`'] Then + Begin + InString := True; + Quote := C; + End + Else If C = '{' Then + Inc(Depth) + Else If C = '}' Then + Begin + Dec(Depth); + If Depth = 0 Then + Break; + End; + Inc(I); + End; + If Depth <> 0 Then Exit; + LClassText := Copy(LText,B + 1,I - B - 1); + AHTML := RESTDWHTMLExtractJSHTML(LClassText); + LVisual := LowerCase( + RESTDWHTMLExtractJSValue(LClassText,'visual','true') + ); + AVisual := Not SameText(LVisual,'false'); + APlacement := + RESTDWHTMLExtractJSValue(LClassText,'placement','body'); + If Trim(APlacement) = '' Then APlacement := 'body'; + Result := True; +End; + +Procedure AddLabeledEdit(AOwner : TComponent; AParent : TWinControl; + const ACaption : String; ATop : Integer; Var AEdit : TEdit); +Var + L : TLabel; +Begin + L := TLabel.Create(AOwner); + L.Parent := AParent; + L.Left := 16; + L.Top := ATop; + L.Caption := ACaption; + AEdit := TEdit.Create(AOwner); + AEdit.Parent := AParent; + AEdit.Left := 190; + AEdit.Top := ATop - 4; + AEdit.Width := 430; +End; + +Procedure InstallRESTDWHTMLComponent( + const AEditorLibrariesPath : String); +Var + F : TForm; + EPackage,EURL,EPalette,EName,EType,ELabel,EHint,EFile,EExtension : TEdit; + EZip,EIcon,EJS : TRESTDWHTMLFileNameEdit; + LOptions : TLabel; + MOptions : TMemo; + BOk,BCancel : TButton; + R : Integer; + Root,PackageFile,ComponentSection,OptionsSection,LibRoot, + LJsFileName,LIconFileName : String; + Ini : TIniFile; + I : Integer; +Begin + F := TForm.CreateNew(Nil,1); + Try + F.Caption := 'REST Dataware - Install Component'; + F.Position := poScreenCenter; + F.Width := 690; + F.Height := 720; + F.BorderStyle := bsDialog; + AddLabeledEdit(F,F,'Package',24,EPackage); + EPackage.Text := 'Custom'; + AddLabeledEdit(F,F,'Palette',62,EPalette); + EPalette.Text := 'Custom'; + AddLabeledEdit(F,F,'Name Class',100,EName); + With TLabel.Create(F) Do Begin Parent:=F; Left:=16; Top:=142; Caption:='JsFileName'; End; + EJS:=TRESTDWHTMLFileNameEdit.Create(F); EJS.Parent:=F; EJS.Left:=190; EJS.Top:=138; + EJS.Width:=474; EJS.Filter:='JavaScript|*.js|All files|*.*'; + AddLabeledEdit(F,F,'Class Type',180,EType); + EType.Text := 'div'; + AddLabeledEdit(F,F,'Label Class',218,ELabel); + AddLabeledEdit(F,F,'Palette Hint',256,EHint); + AddLabeledEdit(F,F,'html_extension',294,EExtension); + With TLabel.Create(F) Do Begin Parent:=F; Left:=16; Top:=336; Caption:='Local library ZIP'; End; + EZip:=TRESTDWHTMLFileNameEdit.Create(F); EZip.Parent:=F; EZip.Left:=190; EZip.Top:=332; + EZip.Width:=474; EZip.Filter:='ZIP library|*.zip'; + AddLabeledEdit(F,F,'External library URL',374,EURL); + AddLabeledEdit(F,F,'LibFilename',412,EFile); + With TLabel.Create(F) Do Begin Parent:=F; Left:=16; Top:=454; Caption:='Class Icon'; End; + EIcon:=TRESTDWHTMLFileNameEdit.Create(F); EIcon.Parent:=F; EIcon.Left:=190; EIcon.Top:=450; + EIcon.Width:=474; EIcon.Filter:='Images|*.png;*.bmp;*.ico;*.jpg;*.jpeg|All files|*.*'; + LOptions := TLabel.Create(F); LOptions.Parent := F; LOptions.Left := 16; LOptions.Top := 496; + LOptions.Caption := 'Component options (Name=DefaultValue, one per line)'; + MOptions := TMemo.Create(F); MOptions.Parent := F; MOptions.Left := 16; MOptions.Top := 516; + MOptions.Width := 648; MOptions.Height := 120; MOptions.ScrollBars := ssVertical; + BOk := TButton.Create(F); BOk.Parent := F; BOk.Left := 480; BOk.Top := 650; BOk.Width := 88; + BOk.Caption := 'OK'; BOk.ModalResult := mrOk; BOk.Default := True; + BCancel := TButton.Create(F); BCancel.Parent := F; BCancel.Left := 576; BCancel.Top := 650; BCancel.Width := 88; + BCancel.Caption := 'Cancel'; BCancel.ModalResult := mrCancel; BCancel.Cancel := True; + R := F.ShowModal; + If R <> mrOk Then Exit; + If Trim(EPackage.Text) = '' Then Raise Exception.Create('Package is required.'); + If Trim(EName.Text) = '' Then Raise Exception.Create('Name Class is required.'); + If Trim(EPalette.Text) = '' Then EPalette.Text := 'Custom'; + If Trim(EType.Text) = '' Then EType.Text := 'div'; + Root := RESTDWHTMLComponentsPath(AEditorLibrariesPath); + PackageFile := IncludeTrailingPathDelimiter(Root) + SafeName(EPackage.Text) + '.ini'; + ComponentSection := 'Component.' + SafeName(EName.Text); + OptionsSection := 'Options.' + SafeName(EName.Text); + Ini := TIniFile.Create(PackageFile); + Try + LJsFileName := Trim(EJS.Text); + If (LJsFileName <> '') And FileExists(LJsFileName) Then + Begin + RESTDWCopyFileClassic(LJsFileName,IncludeTrailingPathDelimiter(Root)+ExtractFileName(LJsFileName)); + LJsFileName := ExtractFileName(LJsFileName); + End; + If LJsFileName = '' Then + LJsFileName := Ini.ReadString('Package','JsFileName',''); + If LJsFileName = '' Then + Raise Exception.Create('JsFileName is required. The JavaScript package must export NameClass and createHTML().'); + Ini.WriteString('Package','Name',EPackage.Text); + Ini.WriteBool('Package','Enabled',True); + Ini.WriteString('Package','JsFileName',LJsFileName); + Ini.WriteString('Package','FormatVersion','1'); + If Ini.ReadString('Package','Order','') = '' Then + Ini.WriteInteger('Package','Order',1000); + Ini.WriteString(ComponentSection,'Name',EName.Text); + Ini.WriteString(ComponentSection,'NameClass',EName.Text); + Ini.WriteString(ComponentSection,'Palette',EPalette.Text); + Ini.WriteString(ComponentSection,'JsFileName',LJsFileName); + Ini.WriteString(ComponentSection,'ClassType',EType.Text); + Ini.WriteString(ComponentSection,'LabelClass',ELabel.Text); + Ini.WriteString(ComponentSection,'Hint',EHint.Text); + Ini.WriteString(ComponentSection,'html_extension',EExtension.Text); + Ini.WriteString(ComponentSection,'LibFilename',EFile.Text); + Ini.WriteString(ComponentSection,'URL',EURL.Text); + Ini.WriteString(ComponentSection,'InstallerVersion','Phoenix'); + Ini.WriteBool(ComponentSection,'Installed',True); + LibRoot := IncludeTrailingPathDelimiter(Root)+SafeName(EPackage.Text)+'_'+SafeName(EName.Text)+'_libs'; + If Trim(EZip.Text) <> '' Then + Begin + If Not FileExists(EZip.Text) Then Raise Exception.Create('Local library ZIP not found: '+EZip.Text); + ForceDirectories(LibRoot); + RESTDWHTMLExtractZipFile(EZip.Text,IncludeTrailingPathDelimiter(LibRoot)); + Ini.WriteString(ComponentSection,'LocalPath',LibRoot); + End + Else Ini.WriteString(ComponentSection,'LocalPath',''); + LIconFileName := ''; + If (Trim(EIcon.Text) <> '') And FileExists(EIcon.Text) Then + Begin + LIconFileName := SafeName(EPackage.Text)+'_'+SafeName(EName.Text)+ExtractFileExt(EIcon.Text); + RESTDWCopyFileClassic(EIcon.Text,IncludeTrailingPathDelimiter(Root)+LIconFileName); + End; + Ini.WriteString(ComponentSection,'ClassIcon',LIconFileName); + Ini.EraseSection(OptionsSection); + For I := 0 To MOptions.Lines.Count - 1 Do + If Pos('=',MOptions.Lines[I]) > 1 Then + Ini.WriteString(OptionsSection, + Trim(Copy(MOptions.Lines[I],1,Pos('=',MOptions.Lines[I])-1)), + Trim(Copy(MOptions.Lines[I],Pos('=',MOptions.Lines[I])+1,MaxInt))); + Finally + Ini.Free; + End; + Finally + F.Free; + End; +End; + +Type + TComponentOptionsForm = Class(TForm) + Private + FRoot : String; + FPackages : TListView; + FComponents : TListView; + FOptions : TStringGrid; + FSettingsPanel : TPanel; + FApplyPanel : TPanel; + FApplyButton : TButton; + FStatusLabel : TLabel; + FOriginalValues : TStringList; + FCurrentFile : String; + FCurrentSection : String; + FImages : TImageList; + Function AddComponentIcon(const AFileName : String) : Integer; + Procedure LoadPackages; + Procedure PackageClick(Sender : TObject); + Procedure ComponentClick(Sender : TObject); + Procedure OptionSetEditText(Sender : TObject; ACol, ARow : Integer; const Value : String); + Procedure ApplyOptionClick(Sender : TObject); + Procedure SaveChangedValues; + Procedure UpdateApplyState; + Public + Constructor CreateOptions(const ARoot : String); + Destructor Destroy; Override; + End; + +Constructor TComponentOptionsForm.CreateOptions(const ARoot : String); +Var + B : TButton; + LButtons, + LListsPanel : TPanel; +Begin + Inherited CreateNew(Nil,1); + FRoot := ARoot; + FCurrentFile := ''; + FCurrentSection := ''; + FOriginalValues := TStringList.Create; + Caption := 'REST Dataware - Configure Packages'; + Position := poScreenCenter; + Width := 1060; + Height := 640; + BorderStyle := bsSizeable; + FImages := TImageList.Create(Self); + FImages.Width := 24; + FImages.Height := 24; + LListsPanel := TPanel.Create(Self); + LListsPanel.Parent := Self; + LListsPanel.Align := alLeft; + LListsPanel.Width := 520; + LListsPanel.BevelOuter := bvNone; + LListsPanel.Caption := ''; + FPackages := TListView.Create(LListsPanel); + FPackages.Parent := LListsPanel; + FPackages.Align := alLeft; + FPackages.Width := 220; + FPackages.ViewStyle := vsReport; + FPackages.ReadOnly := True; + FPackages.RowSelect := True; + FPackages.HideSelection := False; + FPackages.Columns.Add.Caption := 'Package / Palette'; + FPackages.Columns[0].Width := 190; + FPackages.OnClick := PackageClick; + FComponents := TListView.Create(LListsPanel); + FComponents.Parent := LListsPanel; + FComponents.Align := alClient; + FComponents.ViewStyle := vsReport; + FComponents.ReadOnly := True; + FComponents.RowSelect := True; + FComponents.HideSelection := False; + FComponents.SmallImages := FImages; + FComponents.Columns.Add.Caption := 'Component'; + FComponents.Columns[0].Width := 270; + FComponents.OnClick := ComponentClick; + LButtons := TPanel.Create(Self); + LButtons.Parent := Self; + LButtons.Align := alBottom; + LButtons.Height := 42; + LButtons.BevelOuter := bvNone; + LButtons.Caption := ''; + B := TButton.Create(LButtons); + B.Parent := LButtons; + B.Align := alRight; + B.Width := 96; + B.Caption := 'Close'; + B.ModalResult := mrOk; + B.Default := True; + FSettingsPanel := TPanel.Create(Self); + FSettingsPanel.Parent := Self; + FSettingsPanel.Align := alClient; + FSettingsPanel.BevelOuter := bvNone; + FSettingsPanel.Caption := ''; + FApplyPanel := TPanel.Create(FSettingsPanel); + FApplyPanel.Parent := FSettingsPanel; + FApplyPanel.Align := alBottom; + FApplyPanel.Height := 38; + FApplyPanel.BevelOuter := bvNone; + FApplyPanel.Caption := ''; + FApplyButton := TButton.Create(FApplyPanel); + FApplyButton.Parent := FApplyPanel; + FApplyButton.Align := alRight; + FApplyButton.Width := 86; + FApplyButton.Caption := 'OK'; + FApplyButton.Enabled := False; + FApplyButton.OnClick := ApplyOptionClick; + FStatusLabel := TLabel.Create(FApplyPanel); + FStatusLabel.Parent := FApplyPanel; + FStatusLabel.Align := alClient; + FStatusLabel.Layout := tlCenter; + FStatusLabel.Caption := ''; + FOptions := TStringGrid.Create(FSettingsPanel); + FOptions.Parent := FSettingsPanel; + FOptions.Align := alClient; + FOptions.ColCount := 2; + FOptions.RowCount := 1; + FOptions.FixedRows := 0; + FOptions.FixedCols := 1; + FOptions.DefaultRowHeight := 21; + FOptions.ColWidths[0] := 190; + FOptions.ColWidths[1] := 330; + FOptions.Cells[0,0] := 'Component Setting'; + FOptions.Cells[1,0] := 'Value'; + FOptions.Options := FOptions.Options + [goEditing,goColSizing,goDrawFocusSelected]; + FOptions.OnSetEditText := OptionSetEditText; + LoadPackages; + If FPackages.Items.Count = 0 Then + FStatusLabel.Caption := 'No package INI found in Packages.' + Else + FStatusLabel.Caption := 'Select a package and a component.'; +End; + +Destructor TComponentOptionsForm.Destroy; +Begin + FOriginalValues.Free; + Inherited Destroy; +End; + +Function TComponentOptionsForm.AddComponentIcon(const AFileName : String) : Integer; +Var + P : TPicture; + B : TBitmap; + LFileName : String; +Begin + Result := -1; + LFileName := AFileName; + If (Trim(LFileName) <> '') And Not FileExists(LFileName) Then + Begin + If FileExists(ExpandFileName(IncludeTrailingPathDelimiter(FRoot) + LFileName)) Then + LFileName := ExpandFileName(IncludeTrailingPathDelimiter(FRoot) + LFileName) + Else + LFileName := ExpandFileName(IncludeTrailingPathDelimiter(ExtractFileDir(FRoot)) + LFileName); + End; + If (Trim(LFileName) = '') Or Not FileExists(LFileName) Then Exit; + P := TPicture.Create; + B := TBitmap.Create; + Try + Try + P.LoadFromFile(LFileName); + B.SetSize(24,24); + B.Canvas.StretchDraw(Rect(0,0,24,24),P.Graphic); + Result := FImages.Add(B,Nil); + Except + Result := -1; + End; + Finally + B.Free; + P.Free; + End; +End; + +Procedure TComponentOptionsForm.LoadPackages; +Var + S : TSearchRec; + I : TIniFile; + Item : TListItem; + LName : String; +Begin + FPackages.Items.Clear; + If FindFirst(IncludeTrailingPathDelimiter(FRoot)+'*.ini',faAnyFile,S)<>0 Then Exit; + Try + Repeat + I := TIniFile.Create(IncludeTrailingPathDelimiter(FRoot)+S.Name); + Try + LName := I.ReadString('Package','Name',ChangeFileExt(S.Name,'')); + Item := FPackages.Items.Add; + Item.Caption := LName; + Item.SubItems.Add(S.Name); + Finally + I.Free; + End; + Until FindNext(S)<>0; + Finally + FindClose(S); + End; + If FPackages.Items.Count > 0 Then + Begin + FPackages.ItemIndex := 0; + FPackages.Items[0].Selected := True; + FPackages.Items[0].Focused := True; + PackageClick(FPackages); + End; +End; + +Procedure TComponentOptionsForm.PackageClick(Sender : TObject); +Var + I : TIniFile; + Sections : TStringList; + K : Integer; + S,N,LIcon : String; + Item : TListItem; +Begin + FComponents.Items.Clear; + FOptions.FixedRows := 0; + FOptions.RowCount := 1; + FOriginalValues.Clear; + FApplyButton.Enabled := False; + FCurrentFile := ''; + FCurrentSection := ''; + If FPackages.Selected = Nil Then + If (FPackages.ItemIndex >= 0) And (FPackages.ItemIndex < FPackages.Items.Count) Then + FPackages.Items[FPackages.ItemIndex].Selected := True; + If (FPackages.Selected=Nil) Or (FPackages.Selected.SubItems.Count=0) Then Exit; + FCurrentFile := IncludeTrailingPathDelimiter(FRoot)+FPackages.Selected.SubItems[0]; + I := TIniFile.Create(FCurrentFile); + Sections := TStringList.Create; + Try + I.ReadSections(Sections); + For K := 0 To Sections.Count - 1 Do + Begin + S := Sections[K]; + If Pos('Component.',S) <> 1 Then Continue; + N := I.ReadString(S,'Name',Copy(S,Length('Component.')+1,MaxInt)); + Item := FComponents.Items.Add; + Item.Caption := N; + Item.SubItems.Add(S); + LIcon := I.ReadString(S,'ClassIcon',''); + Item.ImageIndex := AddComponentIcon(LIcon); + End; + Finally + Sections.Free; + I.Free; + End; + If FComponents.Items.Count > 0 Then + Begin + FComponents.ItemIndex := 0; + FComponents.Items[0].Selected := True; + FComponents.Items[0].Focused := True; + ComponentClick(FComponents); + End; +End; + +Procedure TComponentOptionsForm.ComponentClick(Sender : TObject); +Var + I : TIniFile; + Keys : TStringList; + K,R : Integer; + LOptionsSection : String; + Procedure AddField(const AName,AValue : String); + Begin + R := FOptions.RowCount; + FOptions.RowCount := R+1; + FOptions.Cells[0,R] := AName; + FOptions.Cells[1,R] := AValue; + FOriginalValues.Values[AName] := AValue; + End; +Begin + FOptions.FixedRows := 0; + FOptions.RowCount := 1; + FOriginalValues.Clear; + FApplyButton.Enabled := False; + FCurrentSection := ''; + If FComponents.Selected = Nil Then + If (FComponents.ItemIndex >= 0) And (FComponents.ItemIndex < FComponents.Items.Count) Then + FComponents.Items[FComponents.ItemIndex].Selected := True; + If (FComponents.Selected=Nil) Or (FComponents.Selected.SubItems.Count=0) Or (FCurrentFile='') Then Exit; + FCurrentSection := FComponents.Selected.SubItems[0]; + I := TIniFile.Create(FCurrentFile); + Keys := TStringList.Create; + Try + AddField('Name',I.ReadString(FCurrentSection,'Name','')); + AddField('NameClass',I.ReadString(FCurrentSection,'NameClass','')); + AddField('Palette',I.ReadString(FCurrentSection,'Palette','Custom')); + AddField('JsFileName',I.ReadString(FCurrentSection,'JsFileName',I.ReadString('Package','JsFileName',''))); + AddField('ClassType',I.ReadString(FCurrentSection,'ClassType','')); + AddField('LabelClass',I.ReadString(FCurrentSection,'LabelClass','')); + AddField('Hint',I.ReadString(FCurrentSection,'Hint','')); + AddField('html_extension',I.ReadString(FCurrentSection,'html_extension','')); + AddField('LibFilename',I.ReadString(FCurrentSection,'LibFilename','')); + AddField('URL',I.ReadString(FCurrentSection,'URL','')); + AddField('LocalPath',I.ReadString(FCurrentSection,'LocalPath','')); + AddField('ClassIcon',I.ReadString(FCurrentSection,'ClassIcon','')); + AddField('Order',IntToStr(I.ReadInteger(FCurrentSection,'Order',1000))); + If I.ReadBool(FCurrentSection,'Installed',True) Then AddField('Installed','True') + Else AddField('Installed','False'); + LOptionsSection := 'Options.'+Copy(FCurrentSection,Length('Component.')+1,MaxInt); + I.ReadSection(LOptionsSection,Keys); + For K := 0 To Keys.Count - 1 Do + AddField('Option.'+Keys[K],I.ReadString(LOptionsSection,Keys[K],'')); + Finally + Keys.Free; + I.Free; + End; + If FOptions.RowCount > 1 Then + FOptions.FixedRows := 1; + FStatusLabel.Caption := IntToStr(FOptions.RowCount-1)+' field(s) loaded from package INI.'; +End; + +Procedure TComponentOptionsForm.UpdateApplyState; +Var + R : Integer; +Begin + FApplyButton.Enabled := False; + For R := 1 To FOptions.RowCount - 1 Do + If FOptions.Cells[1,R] <> FOriginalValues.Values[FOptions.Cells[0,R]] Then + Begin + FApplyButton.Enabled := True; + Exit; + End; +End; + +Procedure TComponentOptionsForm.OptionSetEditText(Sender : TObject; ACol, ARow : Integer; const Value : String); +Begin + If (ACol = 1) And (ARow > 0) Then + UpdateApplyState; +End; + +Procedure TComponentOptionsForm.SaveChangedValues; +Var + I : TIniFile; + R : Integer; + LField,LValue,LOptionsSection,LKey : String; +Begin + If (FCurrentFile='') Or (FCurrentSection='') Then Exit; + I := TIniFile.Create(FCurrentFile); + Try + For R := 1 To FOptions.RowCount - 1 Do + Begin + LField := FOptions.Cells[0,R]; + LValue := FOptions.Cells[1,R]; + If LValue = FOriginalValues.Values[LField] Then Continue; + If SameText(LField,'Order') Then + I.WriteInteger(FCurrentSection,'Order',StrToIntDef(LValue,1000)) + Else If Pos('Option.',LField) = 1 Then + Begin + LKey := Copy(LField,Length('Option.')+1,MaxInt); + LOptionsSection := 'Options.'+Copy(FCurrentSection,Length('Component.')+1,MaxInt); + I.WriteString(LOptionsSection,LKey,LValue); + End + Else If SameText(LField,'Installed') Then + I.WriteBool(FCurrentSection,'Installed',SameText(LValue,'True') Or SameText(LValue,'1') Or SameText(LValue,'Yes')) + Else + I.WriteString(FCurrentSection,LField,LValue); + FOriginalValues.Values[LField] := LValue; + End; + Finally + I.Free; + End; + FApplyButton.Enabled := False; + FStatusLabel.Caption := 'Saved to '+ExtractFileName(FCurrentFile); +End; + +Procedure TComponentOptionsForm.ApplyOptionClick(Sender : TObject); +Begin + SaveChangedValues; +End; + +Procedure ConfigureRESTDWHTMLComponents( + const AEditorLibrariesPath : String); +Var + F : TComponentOptionsForm; +Begin + F:=TComponentOptionsForm.CreateOptions(RESTDWHTMLComponentsPath(AEditorLibrariesPath)); + Try + F.ShowModal; + Finally F.Free; End; +End; + +Function ActiveProjectINIFileName : String; +Var + LPath : String; +Begin + LPath := ''; + If (RESTDWActiveProjectDir <> '') Then + LPath := + RESTDWActiveProjectDir; + If LPath = '' Then + LPath := GetCurrentDir; + Result := + IncludeTrailingPathDelimiter(LPath) + + 'RESTDataware.project.ini'; +End; + +Type + TProjectOptionsForm = Class(TForm) + Private + FProducer : TRESTDWHTMLPageProducerAdapter; + FEditorLibrariesPath : String; + FTopics : TListView; + FPage : TPanel; + FGeneralPage : TPanel; + FAdditionalPage : TPanel; + FURL : TRadioButton; + FLocal : TRadioButton; + FURLRoot : TEdit; + FLocalRoot : TEdit; + FTempMode : TRESTDWHTMLLibraryMode; + FTempURL : String; + Procedure TopicClick(Sender : TObject); + Procedure ShowGeneral; + Procedure ShowAdditional; + Procedure AboutClick(Sender : TObject); + Procedure CaptureGeneralValues; + Public + Constructor CreateOptions(AProducer : TRESTDWHTMLPageProducerAdapter; + const AEditorLibrariesPath : String); + Procedure SaveOptions; + End; + +Constructor TProjectOptionsForm.CreateOptions( + AProducer : TRESTDWHTMLPageProducerAdapter; + const AEditorLibrariesPath : String); +Var + B : TButton; + I : TListItem; + L : TLabel; +Begin + Inherited CreateNew(Nil,1); + FProducer := AProducer; + FEditorLibrariesPath := AEditorLibrariesPath; + FTempMode := FProducer.LibraryMode; + FTempURL := FProducer.LibraryURL; + With TIniFile.Create(ActiveProjectINIFileName) Do + Try + If SameText( + ReadString('Libraries','Mode','Local'), + 'URL' + ) Then + FTempMode := lmURL + Else + FTempMode := lmLocal; + FTempURL := + ReadString( + 'Libraries', + 'URL', + FTempURL + ); + Finally + Free; + End; + Caption := 'REST Dataware - Project Options'; + Position := poScreenCenter; + Width := 720; + Height := 440; + BorderStyle := bsDialog; + FTopics := TListView.Create(Self); + FTopics.Parent := Self; + FTopics.Align := alLeft; + FTopics.Width := 180; + FTopics.ViewStyle := vsReport; + FTopics.ReadOnly := True; + FTopics.RowSelect := True; + FTopics.Columns.Add.Caption := 'Options'; + FTopics.Columns[0].Width := 160; + FTopics.OnClick := TopicClick; + I := FTopics.Items.Add; + I.Caption := 'General'; + I := FTopics.Items.Add; + I.Caption := 'Additional'; + FPage := TPanel.Create(Self); + FPage.Parent := Self; + FPage.Align := alClient; + FPage.BevelOuter := bvNone; + { Pages are created once and only shown/hidden. The former implementation + freed child controls when switching topics, leaving field references that + could be reused after About and cause an access violation. } + FGeneralPage := TPanel.Create(Self); + FGeneralPage.Parent := FPage; + FGeneralPage.Align := alClient; + FGeneralPage.BevelOuter := bvNone; + L := TLabel.Create(Self); + L.Parent := FGeneralPage; + L.Left := 24; + L.Top := 24; + L.Caption := 'Libraries'; + FURL := TRadioButton.Create(Self); + FURL.Parent := FGeneralPage; + FURL.Left := 24; + FURL.Top := 60; + FURL.Caption := 'Use URL / external library'; + FURL.Checked := FTempMode = lmURL; + FURLRoot := TEdit.Create(Self); + FURLRoot.Parent := FGeneralPage; + FURLRoot.Left := 240; + FURLRoot.Top := 56; + FURLRoot.Width := 400; + FURLRoot.Text := FTempURL; + FLocal := TRadioButton.Create(Self); + FLocal.Parent := FGeneralPage; + FLocal.Left := 24; + FLocal.Top := 100; + FLocal.Caption := 'Use local library'; + FLocal.Checked := FTempMode = lmLocal; + FLocalRoot := TEdit.Create(Self); + FLocalRoot.Parent := FGeneralPage; + FLocalRoot.Left := 240; + FLocalRoot.Top := 96; + FLocalRoot.Width := 400; + FLocalRoot.Text := FProducer.LocalHTMLLibrariesPath; + FLocalRoot.ReadOnly := True; + FAdditionalPage := TPanel.Create(Self); + FAdditionalPage.Parent := FPage; + FAdditionalPage.Align := alClient; + FAdditionalPage.BevelOuter := bvNone; + L := TLabel.Create(Self); + L.Parent := FAdditionalPage; + L.Left := 24; + L.Top := 24; + L.Caption := 'Additional'; + B := TButton.Create(Self); + B.Parent := FAdditionalPage; + B.Left := 24; + B.Top := 58; + B.Width := 160; + B.Caption := 'About...'; + B.OnClick := AboutClick; + B := TButton.Create(Self); + B.Parent := Self; + B.Align := alBottom; + B.Height := 32; + B.Caption := 'OK'; + B.ModalResult := mrOk; + B.Default := True; + B := TButton.Create(Self); + B.Parent := Self; + B.Align := alBottom; + B.Height := 32; + B.Caption := 'Cancel'; + B.ModalResult := mrCancel; + B.Cancel := True; + FTopics.ItemIndex := 0; + FTopics.Items[0].Selected := True; + FTopics.Items[0].Focused := True; + ShowGeneral; +End; + +Procedure TProjectOptionsForm.CaptureGeneralValues; +Begin + If FURL.Checked Then + FTempMode := lmURL + Else + FTempMode := lmLocal; + FTempURL := FURLRoot.Text; +End; + +Procedure TProjectOptionsForm.ShowGeneral; +Begin + FAdditionalPage.Visible := False; + FGeneralPage.Visible := True; + FGeneralPage.BringToFront; +End; + +Procedure TProjectOptionsForm.ShowAdditional; +Begin + CaptureGeneralValues; + FGeneralPage.Visible := False; + FAdditionalPage.Visible := True; + FAdditionalPage.BringToFront; +End; + +Procedure TProjectOptionsForm.TopicClick( + Sender : TObject); +Begin + If FTopics.Selected = Nil Then + Exit; + If SameText( + FTopics.Selected.Caption, + 'General' + ) Then + ShowGeneral + Else + ShowAdditional; +End; + +Procedure TProjectOptionsForm.AboutClick( + Sender : TObject); +Begin + ShowMessage( + CRESTDWHTMLProject + sLineBreak + + 'Version: ' + CRESTDWHTMLVersion + sLineBreak + + 'Creator: ' + CRESTDWHTMLCreator + sLineBreak + + 'Tester: ' + CRESTDWHTMLTester + sLineBreak + sLineBreak + + 'HTML Project / PageProducer visual project.' + ); +End; + +Procedure TProjectOptionsForm.SaveOptions; +Begin + CaptureGeneralValues; + FProducer.LibraryMode := FTempMode; + FProducer.LibraryURL := Trim(FTempURL); + If FTempMode = lmLocal Then + Begin + If DirectoryExists(FEditorLibrariesPath) Then + RESTDWCopyDirTree(FEditorLibrariesPath,IncludeTrailingPathDelimiter( + ExtractFilePath(ActiveProjectINIFileName) + ) + + 'html' + + PathDelim + + 'libs'); + End; + With TIniFile.Create(ActiveProjectINIFileName) Do + Try + If FTempMode = lmURL Then + WriteString('Libraries','Mode','URL') + Else + WriteString('Libraries','Mode','Local'); + WriteString( + 'Libraries', + 'URL', + Trim(FTempURL) + ); + WriteString( + 'Libraries', + 'EditorLocalPath', + FEditorLibrariesPath + ); + WriteString( + 'Libraries', + 'HTMLLocalPath', + FProducer.LocalHTMLLibrariesPath + ); + Finally + Free; + End; +End; + +Procedure ConfigureRESTDWHTMLProject(AProducer : TObject; const AEditorLibrariesPath : String); +Var + F : TProjectOptionsForm; +Begin + If Not (AProducer Is TRESTDWHTMLPageProducerAdapter) Then Exit; + F:=TProjectOptionsForm.CreateOptions(TRESTDWHTMLPageProducerAdapter(AProducer),AEditorLibrariesPath); + Try + If F.ShowModal=mrOk Then F.SaveOptions; + Finally F.Free; End; +End; +End. diff --git a/CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLDesigner.pas b/CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLDesigner.pas new file mode 100644 index 000000000..6fbf7f93c --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLDesigner.pas @@ -0,0 +1,9457 @@ +unit uRESTDWHTMLDesigner; + +{$IFDEF FPC} +{$mode delphi}{$H+} +{$ENDIF} + +Interface +uses + Classes, StrUtils, Types, Forms, Controls, StdCtrls, ExtCtrls, ComCtrls, + Dialogs, + {$IFDEF FPC} + LCLType, LCLIntf, LMessages, IniFiles, Menus, Grids, Graphics, Buttons, ImgList, + Clipbrd, + {$ELSE} + Windows, Messages, IniFiles, Menus, Grids, Graphics, Buttons, ImgList, + Clipbrd, ShellAPI, Registry, + {$ENDIF} + SysUtils, + + {$IFDEF FPC} + SynEdit, SynEditTypes, SynEditMarks, SynHighlighterHtml, SynHighlighterCss, + SynHighlighterJScript, SynHighlighterMulti, + {$ELSE} + uRESTDWPrivSynEdit, uRESTDWPrivSynEditTypes, uRESTDWPrivSynHighlighterHtml, + uRESTDWPrivSynHighlighterCss, uRESTDWPrivSynHighlighterJScript, + uRESTDWPrivSynHighlighterMulti, + {$ENDIF} + uRESTDWHTMLPageProducerAdapter, uRESTDWHTMLWebView, + uRESTDWHTMLComponentManager, uRESTDWHTMLDesignerAI, uRESTDWHTMLDesignerIcons, uRESTDWHTMLWebAssets, uRESTDWHTMLIDECompat, + uRESTDWHTMLJSONCompat, uRESTDWServerContext; +Type + TRESTDWHTMLWebComponentInfo = Class + Public + Name : String; + ClassName : String; + PackageName : String; + Category : String; + JsFileName : String; + HTML : String; + HTMLExtension : String; + IsVisual : Boolean; + Placement : String; + CSSFile : String; + JSFile : String; + IconFile : String; + ExternalURL : String; + LocalLibPath : String; + FileName : String; + Hint : String; + Options : TStringList; + Constructor Create; + Destructor Destroy; Override; + End; + TRESTDWHTMLProjectNodeInfo = Class + Public + Name : String; + SearchText : String; + End; + TRESTDWHTMLObjectBrowserNodeInfo = Class + Public + ElementID : String; + TagName : String; + End; + TRESTDWHTMLDesignerForm = Class(TForm) + Private + FProducer : TRESTDWHTMLPageProducerAdapter; + FComponents : TList; + FGeneratedInstanceNames : TStringList; + FDesignComponents : TList; + FProjectItems : TList; + FDesignMode : Boolean; + FUpdating : Boolean; + FSelectedInfo : TRESTDWHTMLWebComponentInfo; + FInsertInfo : TRESTDWHTMLWebComponentInfo; + FSelectedElementID : String; + FSelectedElementTag : String; + FSelectedElementOuterHTML : String; + FPendingCodeElement : Boolean; + FIgnoreNextInsertedSelection : Boolean; + FPendingCodeTagName : String; + FPendingCodeText : String; + FPendingCodeID : String; + FPendingCodeClass : String; + FPendingCodeOuterHTML : String; + FPageOptionsSelected : Boolean; + FEditingEventCode : Boolean; + FEventOriginalValues : TStringList; + FSelectedFromCode : Boolean; + FSelectedCodeTagStart : Integer; + FSelectedCodeTagEnd : Integer; + FUpdatingInspector : Boolean; + FMenu : TMainMenu; + FPaletteTabs : TPageControl; + FWorkPanel : TPanel; + FModeBar : TPanel; + FFormDesignButton : TSpeedButton; + FCodeEditorButton : TSpeedButton; + FDesign : TScrollBox; + FCodePages : TPageControl; + FFullCodeTab : TTabSheet; + FHTMLTab : TTabSheet; + FCSSTab : TTabSheet; + FJSTab : TTabSheet; + FFullCode : TSynEdit; + FHTML : TSynEdit; + FCSS : TSynEdit; + FJS : TSynEdit; + FHTMLHighlighter : TSynHTMLSyn; + FCSSHighlighter : TSynCssSyn; + FJSHighlighter : TSynJScriptSyn; + FFullHTMLHighlighter : TSynHTMLSyn; + FFullCSSHighlighter : TSynCssSyn; + FFullJSHighlighter : TSynJScriptSyn; + FFullHighlighter : TSynMultiSyn; + FPreviewPanel : TPanel; + FPreviewHeader : TPanel; + FPreviewFloatForm : TForm; + FLeftDockHost : TPanel; + FRightDockHost : TPanel; + FObjectBrowserPanel : TPanel; + FObjectBrowserHeader : TPanel; + FObjectBrowserFloatForm : TForm; + FObjectBrowserTree : TTreeView; + FObjectBrowserImages : TImageList; + FObjectBrowserSplitter : TSplitter; + FUpdatingObjectBrowser : Boolean; + FObjectBrowserSelectionID : String; + FProjectPanel : TPanel; + FProjectHeader : TPanel; + FProjectSplitter : TSplitter; + FProjectFloatForm : TForm; + FProjectTree : TTreeView; + FColorToolPanel : TPanel; + FColorToolHeader : TPanel; + FColorToolFloatForm : TForm; + FColorPreview : TPanel; + FColorR : TEdit; + FColorG : TEdit; + FColorB : TEdit; + FColorHex : TEdit; + FColorCopyHex : TButton; + FColorCopyRGB : TButton; + FUpdatingColor : Boolean; + FInspectorPanel : TPanel; + FInspectorHeader : TPanel; + FInspectorSplitter : TSplitter; + FInspectorFloatForm : TForm; + FInspectorPages : TPageControl; + FProperties : TStringGrid; + FEvents : TStringGrid; + FMessagesPanel : TPanel; + FMessagesHeader : TPanel; + FMessagesSplitter : TSplitter; + FMessagesFloatForm : TForm; + FMessages : TStringGrid; + FMessagesPopup : TPopupMenu; + FAIPanel : TPanel; + FAIHeader : TPanel; + FAISplitter : TSplitter; + FAIFloatForm : TForm; + FAIConsole : TRESTDWHTMLAIConsolePanel; + FPreviewTimer : TTimer; + FWebViewFirstTimer : TTimer; + FWebViewFirstReady : Boolean; + FToolbar : TPanel; + FToolButtonPanel : TPanel; + FToolButtonSeparator : TPanel; + FNewButton : TSpeedButton; + FOpenButton : TSpeedButton; + FSaveButton : TSpeedButton; + FRefreshButton : TSpeedButton; + FHelpButton : TSpeedButton; + FDebugStartButton : TSpeedButton; + FDebugStopButton : TSpeedButton; + FDebugBreakpointButton : TSpeedButton; + FDebugClearButton : TSpeedButton; + FDebugDevToolsButton : TSpeedButton; + FFileMenuItem : TMenuItem; + FEditMenuItem : TMenuItem; + FSearchMenuItem : TMenuItem; + FViewMenuItem : TMenuItem; + FDebugMenuItem : TMenuItem; + FComponentsMenuItem : TMenuItem; + FProjectOptionsMenuItem : TMenuItem; + FAIMenuItem : TMenuItem; + FDebugStartMenuItem : TMenuItem; + FDebugPauseMenuItem : TMenuItem; + FDebugRunToCursorMenuItem : TMenuItem; + FDebugStopMenuItem : TMenuItem; + FDebugStepIntoMenuItem : TMenuItem; + FDebugStepOverMenuItem : TMenuItem; + FDebugStepOutMenuItem : TMenuItem; + FDebugEvaluateMenuItem : TMenuItem; + FDebugBreakpointMenuItem : TMenuItem; + FDebugClearMenuItem : TMenuItem; + FDebugReleaseAllMenuItem : TMenuItem; + FDebugDevToolsMenuItem : TMenuItem; + FNewMenuItem : TMenuItem; + FOpenMenuItem : TMenuItem; + FSaveMenuItem : TMenuItem; + FModified : Boolean; + FDebugging : Boolean; + FDebugPaused : Boolean; + FDebugBreakpoints : TStringList; + FFullCodeOriginalWndProc : TWndMethod; + FJSOriginalWndProc : TWndMethod; + FCodeWndProcHooked : Boolean; + FDebugMarkImages : TImageList; + FDebugCurrentLine : Integer; + FLastGutterClickLine : Integer; + FLastGutterClickTick : UInt64; + FDebugHoverExpression : String; + FDebugHoverRequestID : Integer; + FDebugEvaluateRequestID : Integer; + FDebugHintForm : TForm; + FDebugHintLabel : TLabel; + FDebugEvaluateForm : TForm; + FDebugEvaluateExpression : TEdit; + FDebugEvaluateValueLabel : TLabel; + FDebugEvaluateNewValue : TEdit; + FCurrentFileName : String; + FNewPageActive : Boolean; + FPreviousFileName : String; + FPreviousTitle : String; + FPreviousRoute : String; + FPreviousAutoDataTables : Boolean; + FPreviousAutoCharts : Boolean; + FPreviousHTML : TStringList; + FPreviousCSS : TStringList; + FPreviousJS : TStringList; + FLanguageCode : String; + FEditorTitle : String; + FWebView : TRESTDWHTMLWebView; + FWebDropOverlay : TForm; + Procedure BuildUI; + Procedure BuildMenus; + Procedure InstallComponentClick(Sender : TObject); + Procedure ComponentOptionsClick(Sender : TObject); + Procedure ProjectOptionsClick(Sender : TObject); + Procedure AIConfigureClick(Sender : TObject); + Procedure AIConsoleClick(Sender : TObject); + Procedure AIDockFloatClick(Sender : TObject); + Function AIPageContext : String; + Procedure BuildDockHeader(APanel : TPanel; Var AHeader : TPanel; + const ACaption : String; APanelID : Integer); + Procedure DockCloseClick(Sender : TObject); + Procedure DockFloatClick(Sender : TObject); + Procedure FloatingFormClose(Sender : TObject; Var CloseAction : TCloseAction); + Procedure ShowProjectPanelClick(Sender : TObject); + Procedure ShowInspectorPanelClick(Sender : TObject); + Procedure ShowObjectBrowserPanelClick(Sender : TObject); + Procedure ShowMessagesPanelClick(Sender : TObject); + Procedure ShowFormDesignPanelClick(Sender : TObject); + Procedure SetDockPanelVisible(APanelID : Integer; AVisible : Boolean); + Procedure ToggleFloatDock(APanelID : Integer); + Procedure ResetIDELayoutClick(Sender : TObject); + Procedure BringFloatingFormsToFront; + Procedure UpdateLeftDockHost; + Procedure UpdateRightDockHost; + Procedure ColorRGBChange(Sender : TObject); + Procedure ColorHexChange(Sender : TObject); + Procedure ColorCopyHexClick(Sender : TObject); + Procedure ColorCopyRGBClick(Sender : TObject); + Procedure ColorPreviewClick(Sender : TObject); + Procedure UpdateColorFromRGB; + Procedure UpdateColorFromHex; + Procedure BuildProjectExplorer; + Function ProjectNodeKey(ANode : TTreeNode) : String; + Procedure SaveProjectExplorerState(AState : TStrings); + Procedure RestoreProjectExplorerState(AState : TStrings; + AFirstBuild : Boolean); + Procedure AddProjectNode(AParent : TTreeNode; + const ACaption, ASearchText : String); + Procedure ParseCSSProjectNodes(AParent : TTreeNode); + Procedure ParseJavaScriptProjectNodes(AParent : TTreeNode); + Procedure ShowFormDesign; + Procedure ShowCodeEditor; + Procedure FormDesignButtonClick(Sender : TObject); + Procedure CodeEditorButtonClick(Sender : TObject); + Procedure WebViewDevToolsClick(Sender : TObject); + Procedure NavigateCode(const ASearchText : String); + Procedure PositionCode(const ASearchText : String; ASwitchToCode : Boolean); + Procedure PositionElementCode(const ATagName, AText, AID, + AClassName, AOuterHTML : String; ASwitchToCode : Boolean); + Procedure ScanPackagePalette; + Procedure LoadIDESettings; + Procedure SaveIDESettings; + Function IDESettingsFileName : String; + Function ResolveEditorLibrariesPath : String; + Procedure MessagesResize(Sender : TObject); + Procedure MessagesDblClick(Sender : TObject); + Procedure MessagesCopyLineClick(Sender : TObject); + Procedure MessagesCopySelectionClick(Sender : TObject); + Procedure MessagesSelectAllClick(Sender : TObject); + Procedure MessagesCopyAllClick(Sender : TObject); + Procedure MessagesKeyDown(Sender : TObject; Var Key : Word; + Shift : TShiftState); + Procedure OpenWebViewInBrowserClick(Sender : TObject); + Procedure RefreshWebViewButtonClick(Sender : TObject); + Procedure FocusCodeError(ALine, AColumn : Integer); + Procedure AddPaletteItem(const ACategory, AName, AHTML : String; + const AIconFile : String = ''); + Procedure PaletteMouseDown(Sender : TObject; Button : TMouseButton; + Shift : TShiftState; X, Y : Integer); + Procedure PaletteClick(Sender : TObject); + Procedure InsertNonVisualComponent(AInfo : TRESTDWHTMLWebComponentInfo); + Procedure PaletteEndDrag(Sender, Target : TObject; X, Y : Integer); + Procedure ShowWebDropOverlay; + Procedure HideWebDropOverlay; + Procedure WebDropOverlayDragOver(Sender, Source : TObject; + X, Y : Integer; State : TDragState; Var Accept : Boolean); + Procedure WebDropOverlayDragDrop(Sender, Source : TObject; + X, Y : Integer); + Procedure DesignDragOver(Sender, Source : TObject; X, Y : Integer; + State : TDragState; Var Accept : Boolean); + Procedure DesignDragDrop(Sender, Source : TObject; X, Y : Integer); + Procedure CodeDragOver(Sender, Source : TObject; X, Y : Integer; + State : TDragState; Var Accept : Boolean); + Procedure CodeDragDrop(Sender, Source : TObject; X, Y : Integer); + Procedure ComponentClick(Sender : TObject); + Procedure SourceChanged(Sender : TObject); + Procedure FullCodeChanged(Sender : TObject); + Procedure CodeEditorClick(Sender : TObject); + Procedure CodeEditorKeyUp(Sender : TObject; Var Key : Word; + Shift : TShiftState); + Procedure CodeEditorMouseMove(Sender : TObject; + Shift : TShiftState; X, Y : Integer); + Procedure CodeEditorDblClick(Sender : TObject); + Procedure InstallCodeWndProcHooks; + {$IFDEF FPC}Procedure FullCodeWndProc(Var AMessage : TLMessage);{$ELSE}Procedure FullCodeWndProc(Var AMessage : TMessage);{$ENDIF} + {$IFDEF FPC}Procedure JSCodeWndProc(Var AMessage : TLMessage);{$ELSE}Procedure JSCodeWndProc(Var AMessage : TMessage);{$ENDIF} + {$IFDEF FPC} + Procedure CodeGutterClick(Sender : TObject; X, Y, Line : Integer; Mark : TSynEditMark); + {$ELSE} + Procedure CodeGutterClick(Sender : TObject; Button : TMouseButton; + X, Y, Line : Integer; Mark : TSynEditMark); + {$ENDIF} + Procedure ToggleBreakpointClick(Sender : TObject); + Procedure DebugStartClick(Sender : TObject); + Procedure DebugPauseClick(Sender : TObject); + Procedure DebugRunToCursorClick(Sender : TObject); + Procedure DebugStopClick(Sender : TObject); + Procedure DebugStepIntoClick(Sender : TObject); + Procedure DebugStepOverClick(Sender : TObject); + Procedure DebugStepOutClick(Sender : TObject); + Procedure DebugEvaluateClick(Sender : TObject); + Procedure DebugClearBreakpointsClick(Sender : TObject); + Procedure DebugReleaseAllBreakpointsClick(Sender : TObject); + Procedure DebugDevToolsClick(Sender : TObject); + Procedure DebugBreakpointHit(Sender : TObject; ALine : Integer); + Procedure DebugEvaluateResult(Sender : TObject; ARequestID : Integer; + const AExpression, AValue, AError : String; ASuccess : Boolean); + Procedure DebugHintDblClick(Sender : TObject); + Procedure EvaluateDialogEvaluateClick(Sender : TObject); + Procedure EvaluateDialogModifyClick(Sender : TObject); + Procedure ToggleBreakpoint(ALine : Integer); + Procedure SyncBreakpointMarks; + Procedure BuildDebugMarkImages; + Function BreakpointIndex(ALine : Integer) : Integer; + Function BuildDebugPreviewHTML : String; + Function IsJavaScriptLine(ALine : Integer) : Boolean; + Function DebugExpressionAtMouse(X, Y : Integer) : String; + Procedure ShowEvaluateDialog(const AExpression : String); + Procedure UpdateDebugMenuState; + Procedure InspectCodeAtCaret; + Procedure UpdateSelectedCodeElement(const AProperty, AValue : String); + Procedure PreviewTimerTimer(Sender : TObject); + Procedure WebViewFirstTimerTimer(Sender : TObject); + Procedure RebuildVisualDesign; + Procedure RebuildFullCode; + Procedure SaveToProducer; + Procedure ParseFullCodeToProducer; + Procedure ToggleSourceDesign; + Procedure FormKeyDownHandler(Sender : TObject; Var Key : Word; + Shift : TShiftState); + Procedure FormShowHandler(Sender : TObject); + Procedure FormActivateHandler(Sender : TObject); + Procedure FormCloseQueryHandler(Sender : TObject; Var CanClose : Boolean); + Procedure NewClick(Sender : TObject); + Procedure OpenClick(Sender : TObject); + Procedure SaveClick(Sender : TObject); + Procedure RefreshClick(Sender : TObject); + Procedure HelpClick(Sender : TObject); + Function BuildHelpHTML : String; + Function HelpLang(const AKey : String) : String; + Function SaveDocument : Boolean; + Function ConfirmSaveChanges : Boolean; + Procedure CapturePreviousPage; + Procedure RestorePreviousPage; + Procedure ClearPreviousPage; + Procedure MarkModified; + Procedure SetModified(AValue : Boolean); + Procedure UpdateDocumentCaption; + Procedure ApplyLazarusLanguage; + Procedure SetDockHeaderLanguage(AHeader : TPanel; const ACaption : String); + Function DetectLazarusLanguage : String; + Function Lang(const AKey : String) : String; + Procedure ProjectTreeClick(Sender : TObject); + Procedure InspectorSetComponent(AInfo : TRESTDWHTMLWebComponentInfo); + Procedure InspectorSetPageOptions; + Procedure InspectorSetElement(const AElementID, ATagName, AText, + AID, AClassName, AOuterHTML : String); + Procedure InspectorGridDrawCell(Sender : TObject; ACol, ARow : Integer; + ARect : TRect; AState : TGridDrawState); + Procedure PropertiesEditingDone(Sender : TObject); + Procedure PropertiesSetEditText(Sender : TObject; ACol, ARow : Integer; const Value : String); + Procedure ApplyPropertyValue(const AProperty, AValue : String); + Procedure EventsEditingDone(Sender : TObject); + Procedure EventsDblClick(Sender : TObject); + Procedure NavigateEventCode(const ASearchText : String; + AInsideBody : Boolean); + Procedure OpenOrCreateEventHandler(const AEventName, AHandlerText : String); + Procedure OpenOrCreatePageEvent(const AEventName, AHandlerText : String); + Procedure RemovePageEvent(const AEventName, AHandlerName : String); + Function PageEventListener(const AEventName, AHandlerName : String) : String; + Function PageEventDefaultHandler(const AEventName : String) : String; + Function PageEventCurrentHandler(const AEventName : String) : String; + Function ExtractHandlerName(const AHandlerText : String) : String; + Function MakeEventHandlerName(const AEventName : String) : String; + Function JavaScriptHandlerReferenceCount(const AHandlerName : String) : Integer; + Procedure RemoveEmptyJavaScriptHandler(const AHandlerName : String); + Procedure WebViewElementSelected(Sender : TObject; + const AElementID, ATagName, AText, AID, AClassName, + AOuterHTML : String); + Procedure WebViewHTMLChanged(Sender : TObject; const AHTML : String); + Procedure WebViewObjectTree(Sender : TObject; const AJSON : String); + Procedure ObjectBrowserClick(Sender : TObject); + Procedure SelectObjectBrowserElement(const AElementID : String); + Procedure ClearObjectBrowserNodeData; + Function ObjectBrowserIconIndex(const ATagName, AClassName, AElementName : String) : Integer; + Procedure DeleteSelectedVisualElement; + Procedure AddMessage(const AKind, AFile, AText : String; + ALine, AColumn : Integer); + Procedure ClearMessages; + Procedure ValidateDocument; + Procedure FindClick(Sender : TObject); + Procedure ReplaceClick(Sender : TObject); + Procedure UndoClick(Sender : TObject); + Procedure CutClick(Sender : TObject); + Procedure CopyClick(Sender : TObject); + Procedure PasteClick(Sender : TObject); + Function ActiveMemo : TSynEdit; + Function ComponentHTML(const AName : String) : String; + Function ApplyComponentOptions(AInfo : TRESTDWHTMLWebComponentInfo; + const AHTML : String) : String; + Function ComponentLibraryHTML(AInfo : TRESTDWHTMLWebComponentInfo) : String; + Function ComponentInstanceHTML(AInfo : TRESTDWHTMLWebComponentInfo) : String; + Function ComponentJSClassSource(AInfo : TRESTDWHTMLWebComponentInfo) : String; + Function ComponentOptionsJSON(AInfo : TRESTDWHTMLWebComponentInfo) : String; + Procedure InsertVisualComponent(AInfo : TRESTDWHTMLWebComponentInfo; + X, Y : Integer; AAtPoint : Boolean); + Function ComponentInstanceBaseName(AInfo : TRESTDWHTMLWebComponentInfo) : String; + Function NextComponentInstanceName(const ABaseName : String) : String; + Function ApplyComponentIdentity(const AHTML, AIdentity : String) : String; + Function FindComponentByButton(AButton : TObject) : TRESTDWHTMLWebComponentInfo; + Function FindCategoryTab(const ACategory : String) : TTabSheet; + Function ExtractBetween(const AText, AStart, AEnd : String) : String; + Procedure WebViewReady(Sender : TObject); + Procedure WebViewError(Sender : TObject; const AMessage : String); + Procedure WebViewPageError(Sender : TObject; + const AKind, ASource, AMessage : String; + ALine, AColumn : Integer); + Procedure RefreshWebView; + Function BuildPreviewHTML : String; + Function NormalizePreviewHTML(const AHTML : String) : String; + Function JSLineToFullCodeLine(AJSLine : Integer) : Integer; + Function FullCodeLineToJSLine(AFullLine : Integer) : Integer; + Public + Constructor CreateDesigner(AProducer : TRESTDWHTMLPageProducerAdapter; + const AEditorTitle : String = ''); + Function ExecuteModal : Boolean; + Destructor Destroy; Override; + End; +Function RESTDWExecuteContextRulesHTMLDesigner( + AContextRules : TRESTDWContextRules; + const AEditorTitle : String = '') : Boolean; +Implementation +Procedure BuildBrowserRefreshGlyph(ABitmap : TBitmap); +Begin + ABitmap.SetSize(24,24); + ABitmap.PixelFormat := pf24bit; + {$IFDEF FPC} + ABitmap.Transparent := False; + ABitmap.Canvas.Brush.Color := clBtnFace; + {$ELSE} + ABitmap.Transparent := True; + ABitmap.TransparentColor := clFuchsia; + ABitmap.Canvas.Brush.Color := clFuchsia; + {$ENDIF} + ABitmap.Canvas.FillRect(Rect(0,0,24,24)); + ABitmap.Canvas.Pen.Color := clWindowText; + ABitmap.Canvas.Pen.Width := 2; + ABitmap.Canvas.Arc(4,4,20,20,5,16,18,5); + ABitmap.Canvas.MoveTo(17,4); + ABitmap.Canvas.LineTo(21,5); + ABitmap.Canvas.LineTo(19,9); + ABitmap.Canvas.Arc(4,4,20,20,19,8,6,19); + ABitmap.Canvas.MoveTo(6,20); + ABitmap.Canvas.LineTo(2,18); + ABitmap.Canvas.LineTo(4,14); +End; + +Procedure BuildBrowserWWWGlyph(ABitmap : TBitmap); +Begin + ABitmap.SetSize(38,24); + ABitmap.PixelFormat := pf24bit; + {$IFDEF FPC} + ABitmap.Transparent := False; + ABitmap.Canvas.Brush.Color := clBtnFace; + {$ELSE} + ABitmap.Transparent := True; + ABitmap.TransparentColor := clFuchsia; + ABitmap.Canvas.Brush.Color := clFuchsia; + {$ENDIF} + ABitmap.Canvas.FillRect(Rect(0,0,38,24)); + ABitmap.Canvas.Brush.Style := bsClear; + ABitmap.Canvas.Font.Name := 'Arial'; + ABitmap.Canvas.Font.Size := 7; + ABitmap.Canvas.Font.Style := [fsBold]; + ABitmap.Canvas.Font.Color := clWindowText; + ABitmap.Canvas.TextOut(2,6,'http://'); + ABitmap.Canvas.Pen.Color := clWindowText; + ABitmap.Canvas.MoveTo(2,19); + ABitmap.Canvas.LineTo(35,19); +End; + +Function RESTDWRPos( + const ASubText, + AText : String) : Integer; +Var + I, + LSubLen : Integer; +Begin + Result := 0; + LSubLen := Length(ASubText); + If (LSubLen = 0) Or + (LSubLen > Length(AText)) Then + Exit; + For I := Length(AText) - LSubLen + 1 DownTo 1 Do + If Copy(AText,I,LSubLen) = ASubText Then + Begin + Result := I; + Exit; + End; +End; +Constructor TRESTDWHTMLWebComponentInfo.Create; +Begin + Inherited Create; + Options := TStringList.Create; + Options.NameValueSeparator := '='; +End; +Destructor TRESTDWHTMLWebComponentInfo.Destroy; +Begin + Options.Free; + Inherited Destroy; +End; +Constructor TRESTDWHTMLDesignerForm.CreateDesigner( + AProducer : TRESTDWHTMLPageProducerAdapter; + const AEditorTitle : String); +Begin + Inherited CreateNew(Nil, 1); + FProducer := AProducer; + FEditorTitle := Trim(AEditorTitle); + FComponents := TList.Create; + FGeneratedInstanceNames := TStringList.Create; + FGeneratedInstanceNames.CaseSensitive := False; + FGeneratedInstanceNames.Sorted := True; + FGeneratedInstanceNames.Duplicates := dupIgnore; + FDesignComponents := TList.Create; + FProjectItems := TList.Create; + FEventOriginalValues := TStringList.Create; + FDebugBreakpoints := TStringList.Create; + FDebugging := False; + FDebugPaused := False; + FDebugCurrentLine := 0; + FCodeWndProcHooked := False; + FLastGutterClickLine := 0; + FLastGutterClickTick := 0; + FDebugHoverExpression := ''; + FDebugHoverRequestID := 0; + FDebugEvaluateRequestID := 100; + FDebugHintForm := Nil; + FDebugHintLabel := Nil; + FDebugEvaluateForm := Nil; + FPreviousHTML := TStringList.Create; + FPreviousCSS := TStringList.Create; + FPreviousJS := TStringList.Create; + FNewPageActive := False; + FDesignMode := True; + FUpdating := True; + FUpdatingInspector := False; + FSelectedElementID := ''; + FSelectedElementTag := ''; + FPendingCodeElement := False; + FPendingCodeTagName := ''; + FPendingCodeText := ''; + FPendingCodeID := ''; + FPendingCodeClass := ''; + FPendingCodeOuterHTML := ''; + FPageOptionsSelected := False; + FEditingEventCode := False; + FSelectedFromCode := False; + FSelectedCodeTagStart := 0; + FSelectedCodeTagEnd := 0; + FInsertInfo := Nil; + FModified := False; + FCurrentFileName := ''; + FLanguageCode := ''; + BuildUI; + ScanPackagePalette; + FHTML.Text := FProducer.HTML.Text; + FCSS.Text := FProducer.CSS.Text; + FJS.Text := FProducer.JavaScript.Text; + FUpdating := False; + BuildProjectExplorer; + RebuildVisualDesign; + RebuildFullCode; + LoadIDESettings; + ApplyLazarusLanguage; + SetModified(False); + UpdateDocumentCaption; +End; +Function TRESTDWHTMLDesignerForm.ExecuteModal : Boolean; +Begin + ShowModal; + SaveToProducer; + Result := True; +End; +Destructor TRESTDWHTMLDesignerForm.Destroy; +Var + I : Integer; +Begin + SaveIDESettings; + For I := 0 To FProjectItems.Count - 1 Do + TObject(FProjectItems[I]).Free; + FProjectItems.Free; + FEventOriginalValues.Free; + FDebugBreakpoints.Free; + If Assigned(FDebugHintForm) Then + FDebugHintForm.Free; + FPreviousHTML.Free; + FPreviousCSS.Free; + FPreviousJS.Free; + For I := 0 To FDesignComponents.Count - 1 Do + TObject(FDesignComponents[I]).Free; + FDesignComponents.Free; + For I := 0 To FComponents.Count - 1 Do + TObject(FComponents[I]).Free; + FComponents.Free; + FGeneratedInstanceNames.Free; + Inherited Destroy; +End; +Procedure TRESTDWHTMLDesignerForm.BuildMenus; +Var + M : TMenuItem; + Procedure AddItem( + AParent : TMenuItem; + const ACaption : String; + AHandler : TNotifyEvent; + AShortcut : TShortCut); + Var + I : TMenuItem; + Begin + I := TMenuItem.Create(FMenu); + I.Caption := ACaption; + I.OnClick := AHandler; + I.ShortCut := AShortcut; + AParent.Add(I); + End; +Begin + FMenu := TMainMenu.Create(Self); + Menu := FMenu; + M := TMenuItem.Create(FMenu); + M.Caption := '&File'; + FMenu.Items.Add(M); + FFileMenuItem := M; + FNewMenuItem := TMenuItem.Create(FMenu); + FNewMenuItem.Caption := '&New'; + FNewMenuItem.OnClick := NewClick; + FNewMenuItem.ShortCut := ShortCut(Ord('N'),[ssCtrl]); + M.Add(FNewMenuItem); + FOpenMenuItem := TMenuItem.Create(FMenu); + FOpenMenuItem.Caption := '&Open...'; + FOpenMenuItem.OnClick := OpenClick; + FOpenMenuItem.ShortCut := ShortCut(Ord('O'),[ssCtrl]); + M.Add(FOpenMenuItem); + FSaveMenuItem := TMenuItem.Create(FMenu); + FSaveMenuItem.Caption := '&Save'; + FSaveMenuItem.OnClick := SaveClick; + FSaveMenuItem.ShortCut := ShortCut(Ord('S'),[ssCtrl]); + FSaveMenuItem.Enabled := False; + M.Add(FSaveMenuItem); + M := TMenuItem.Create(FMenu); + M.Caption := '&Edit'; + FMenu.Items.Add(M); + FEditMenuItem := M; + AddItem(M,'&Undo',UndoClick,ShortCut(Ord('Z'),[ssCtrl])); + AddItem(M,'Cu&t',CutClick,ShortCut(Ord('X'),[ssCtrl])); + AddItem(M,'&Copy',CopyClick,ShortCut(Ord('C'),[ssCtrl])); + AddItem(M,'&Paste',PasteClick,ShortCut(Ord('V'),[ssCtrl])); + M := TMenuItem.Create(FMenu); + M.Caption := '&Search'; + FMenu.Items.Add(M); + FSearchMenuItem := M; + AddItem(M,'&Find...',FindClick,ShortCut(Ord('F'),[ssCtrl])); + AddItem(M,'&Replace...',ReplaceClick,ShortCut(Ord('H'),[ssCtrl])); + M := TMenuItem.Create(FMenu); + M.Caption := '&Components'; + FMenu.Items.Add(M); + FComponentsMenuItem := M; + AddItem(M,'&Install Component...',InstallComponentClick,0); + AddItem(M,'Configure &Packages...',ComponentOptionsClick,0); + M := TMenuItem.Create(FMenu); + M.Caption := '&Project'; + FMenu.Items.Add(M); + FProjectOptionsMenuItem := M; + AddItem(M,'&Options...',ProjectOptionsClick,0); + M := TMenuItem.Create(FMenu); + M.Caption := '&AI'; + FMenu.Items.Add(M); + FAIMenuItem := M; + AddItem(M,'&Configuration...',AIConfigureClick,0); + AddItem(M,'&Show Floating Console',AIConsoleClick,0); + AddItem(M,'&Float / Dock Console',AIDockFloatClick,0); + M := TMenuItem.Create(FMenu); + M.Caption := '&Debug'; + FMenu.Items.Add(M); + FDebugMenuItem := M; + FDebugStartMenuItem := TMenuItem.Create(FMenu); + FDebugStartMenuItem.Caption := '&Run / Continue'; + FDebugStartMenuItem.OnClick := DebugStartClick; + FDebugStartMenuItem.ShortCut := ShortCut(VK_F9,[]); + M.Add(FDebugStartMenuItem); + FDebugPauseMenuItem := TMenuItem.Create(FMenu); + FDebugPauseMenuItem.Caption := '&Pause'; + FDebugPauseMenuItem.OnClick := DebugPauseClick; + M.Add(FDebugPauseMenuItem); + FDebugRunToCursorMenuItem := TMenuItem.Create(FMenu); + FDebugRunToCursorMenuItem.Caption := 'Run to &Cursor'; + FDebugRunToCursorMenuItem.OnClick := DebugRunToCursorClick; + FDebugRunToCursorMenuItem.ShortCut := ShortCut(VK_F4,[]); + M.Add(FDebugRunToCursorMenuItem); + FDebugStopMenuItem := TMenuItem.Create(FMenu); + FDebugStopMenuItem.Caption := 'S&top Program'; + FDebugStopMenuItem.OnClick := DebugStopClick; + FDebugStopMenuItem.ShortCut := ShortCut(VK_F2,[ssCtrl]); + M.Add(FDebugStopMenuItem); + FDebugStepIntoMenuItem := TMenuItem.Create(FMenu); + FDebugStepIntoMenuItem.Caption := 'Step &Into'; + FDebugStepIntoMenuItem.OnClick := DebugStepIntoClick; + FDebugStepIntoMenuItem.ShortCut := ShortCut(VK_F7,[]); + M.Add(FDebugStepIntoMenuItem); + FDebugStepOverMenuItem := TMenuItem.Create(FMenu); + FDebugStepOverMenuItem.Caption := 'Step &Over'; + FDebugStepOverMenuItem.OnClick := DebugStepOverClick; + FDebugStepOverMenuItem.ShortCut := ShortCut(VK_F8,[]); + M.Add(FDebugStepOverMenuItem); + FDebugStepOutMenuItem := TMenuItem.Create(FMenu); + FDebugStepOutMenuItem.Caption := 'Step O&ut'; + FDebugStepOutMenuItem.OnClick := DebugStepOutClick; + FDebugStepOutMenuItem.ShortCut := ShortCut(VK_F8,[ssShift]); + M.Add(FDebugStepOutMenuItem); + FDebugEvaluateMenuItem := TMenuItem.Create(FMenu); + FDebugEvaluateMenuItem.Caption := '&Evaluate/Modify...'; + FDebugEvaluateMenuItem.OnClick := DebugEvaluateClick; + FDebugEvaluateMenuItem.ShortCut := ShortCut(VK_F7,[ssCtrl]); + M.Add(FDebugEvaluateMenuItem); + FDebugBreakpointMenuItem := TMenuItem.Create(FMenu); + FDebugBreakpointMenuItem.Caption := 'Toggle &Breakpoint'; + FDebugBreakpointMenuItem.OnClick := ToggleBreakpointClick; + FDebugBreakpointMenuItem.ShortCut := ShortCut(VK_F5,[]); + M.Add(FDebugBreakpointMenuItem); + FDebugClearMenuItem := TMenuItem.Create(FMenu); + FDebugClearMenuItem.Caption := '&Clear Breakpoints'; + FDebugClearMenuItem.OnClick := DebugClearBreakpointsClick; + M.Add(FDebugClearMenuItem); + FDebugReleaseAllMenuItem := TMenuItem.Create(FMenu); + FDebugReleaseAllMenuItem.Caption := '&Release All Breakpoints'; + FDebugReleaseAllMenuItem.OnClick := DebugReleaseAllBreakpointsClick; + M.Add(FDebugReleaseAllMenuItem); + FDebugDevToolsMenuItem := TMenuItem.Create(FMenu); + FDebugDevToolsMenuItem.Caption := 'WebView &DevTools'; + FDebugDevToolsMenuItem.OnClick := DebugDevToolsClick; + M.Add(FDebugDevToolsMenuItem); + M := TMenuItem.Create(FMenu); + M.Caption := '&View'; + FMenu.Items.Add(M); + FViewMenuItem := M; + AddItem(M,'&FormDesign',FormDesignButtonClick,0); + AddItem(M,'&Code Editor',CodeEditorButtonClick,0); + AddItem(M,'WebView &DevTools',WebViewDevToolsClick,0); + AddItem(M,'Project &Explorer',ShowProjectPanelClick,0); + AddItem(M,'Object &Inspector',ShowInspectorPanelClick,0); + AddItem(M,'Object &Browser',ShowObjectBrowserPanelClick,0); + AddItem(M,'Show &Errors',ShowMessagesPanelClick,0); + AddItem(M,'Form Designer &Panel',ShowFormDesignPanelClick,0); + AddItem(M,'AI &Console',AIConsoleClick,0); + M := TMenuItem.Create(FMenu); + M.Caption := '&Window'; + FMenu.Items.Add(M); + AddItem(M,'&Reset IDE Layout',ResetIDELayoutClick,0); +End; +Procedure TRESTDWHTMLDesignerForm.InstallComponentClick( + Sender : TObject); +Begin + InstallRESTDWHTMLComponent( + ResolveEditorLibrariesPath + ); + ScanPackagePalette; +End; +Procedure TRESTDWHTMLDesignerForm.ComponentOptionsClick( + Sender : TObject); +Begin + ConfigureRESTDWHTMLComponents( + ResolveEditorLibrariesPath + ); + ScanPackagePalette; +End; +Procedure TRESTDWHTMLDesignerForm.ProjectOptionsClick( + Sender : TObject); +Begin + ConfigureRESTDWHTMLProject( + FProducer, + ResolveEditorLibrariesPath + ); + RefreshWebView; + MarkModified; +End; +Procedure TRESTDWHTMLDesignerForm.AIConfigureClick( + Sender : TObject); +Begin + ConfigureRESTDWHTMLAI( + Self + ); +End; +Procedure TRESTDWHTMLDesignerForm.AIConsoleClick( + Sender : TObject); +Begin + SetDockPanelVisible( + 5, + True + ); + { The AI console opens floating by default so it does not consume designer + space. The user can dock it explicitly from the AI menu or [] header. } + If (FAIFloatForm = Nil) And + (FAIPanel.Parent = Self) Then + ToggleFloatDock( + 5 + ); +End; +Procedure TRESTDWHTMLDesignerForm.AIDockFloatClick( + Sender : TObject); +Begin + SetDockPanelVisible( + 5, + True + ); + ToggleFloatDock( + 5 + ); +End; +Function TRESTDWHTMLDesignerForm.AIPageContext : String; +Begin + Result := + FFullCode.Text; +End; +Procedure TRESTDWHTMLDesignerForm.BuildDockHeader( + APanel : TPanel; + Var AHeader : TPanel; + const ACaption : String; + APanelID : Integer); +Var + LLabel : TLabel; + LClose, + LWWW, + LRefresh, + LFloat : TSpeedButton; +Begin + AHeader := TPanel.Create(APanel); + AHeader.Parent := APanel; + AHeader.Align := alTop; + AHeader.Height := 25; + AHeader.BevelOuter := bvLowered; + AHeader.Caption := ''; + LLabel := TLabel.Create(AHeader); + LLabel.Parent := AHeader; + LLabel.Align := alClient; + LLabel.Layout := tlCenter; + {$IFDEF FPC} + LLabel.BorderSpacing.Left := 6; + {$ELSE} + LLabel.Margins.Left := 6; + {$ENDIF} + LLabel.Caption := ACaption; + LClose := TSpeedButton.Create(AHeader); + LClose.Parent := AHeader; + LClose.Align := alRight; + LClose.Width := 25; + LClose.Caption := 'X'; + LClose.Flat := True; + LClose.Hint := Lang('Close'); + LClose.ShowHint := True; + LClose.Tag := APanelID; + LClose.OnClick := DockCloseClick; + If APanelID = 4 Then + Begin + LWWW := TSpeedButton.Create(AHeader); + LWWW.Parent := AHeader; + LWWW.Align := alRight; + LWWW.Width := 38; + LWWW.Caption := ''; + BuildBrowserWWWGlyph(LWWW.Glyph); + LWWW.Flat := True; + LWWW.Hint := 'Open current WebView page in default browser'; + LWWW.ShowHint := True; + LWWW.OnClick := OpenWebViewInBrowserClick; + LRefresh := TSpeedButton.Create(AHeader); + LRefresh.Parent := AHeader; + LRefresh.Align := alRight; + LRefresh.Width := 32; + LRefresh.Caption := ''; + BuildBrowserRefreshGlyph(LRefresh.Glyph); + LRefresh.Flat := True; + LRefresh.Hint := 'Refresh current WebView with current editor code'; + LRefresh.ShowHint := True; + LRefresh.OnClick := RefreshWebViewButtonClick; + End; + LFloat := TSpeedButton.Create(AHeader); + LFloat.Parent := AHeader; + LFloat.Align := alRight; + LFloat.Width := 27; + LFloat.Caption := '[]'; + LFloat.Flat := True; + LFloat.Hint := Lang('FloatDock'); + LFloat.ShowHint := True; + LFloat.Tag := APanelID; + LFloat.OnClick := DockFloatClick; +End; +Procedure TRESTDWHTMLDesignerForm.FocusCodeError( + ALine, + AColumn : Integer); +Begin + If ALine < 1 Then + ALine := 1; + If AColumn < 1 Then + AColumn := 1; + If FDesignMode Then + ShowCodeEditor; + FCodePages.ActivePage := FFullCodeTab; + {$IFDEF FPC} + FFullCode.CaretXY := Point(AColumn,ALine); + {$ELSE} + FFullCode.CaretXY := BufferCoord(AColumn,ALine); + {$ENDIF} + FFullCode.SetFocus; +End; +Procedure TRESTDWHTMLDesignerForm.RefreshWebViewButtonClick( + Sender : TObject); +Begin + If Not FDesignMode Then + Begin + ShowFormDesign; + Exit; + End; + SaveToProducer; + ValidateDocument; + BuildProjectExplorer; + RebuildVisualDesign; +End; +Procedure TRESTDWHTMLDesignerForm.UpdateColorFromRGB; +Var + R, G, B : Integer; + LHex : String; +Begin + If FUpdatingColor Then + Exit; + If Not TryStrToInt(Trim(FColorR.Text),R) Then + Exit; + If Not TryStrToInt(Trim(FColorG.Text),G) Then + Exit; + If Not TryStrToInt(Trim(FColorB.Text),B) Then + Exit; + If R < 0 Then R := 0 Else If R > 255 Then R := 255; + If G < 0 Then G := 0 Else If G > 255 Then G := 255; + If B < 0 Then B := 0 Else If B > 255 Then B := 255; + LHex := + '#' + + IntToHex(R,2) + + IntToHex(G,2) + + IntToHex(B,2); + FUpdatingColor := True; + Try + FColorR.Text := IntToStr(R); + FColorG.Text := IntToStr(G); + FColorB.Text := IntToStr(B); + FColorHex.Text := LHex; + FColorPreview.Color := + TColor( + R Or + (G Shl 8) Or + (B Shl 16) + ); + Finally + FUpdatingColor := False; + End; +End; +Procedure TRESTDWHTMLDesignerForm.UpdateColorFromHex; +Var + H : String; + V, R, G, B, + LCaret : Integer; +Begin + If FUpdatingColor Then + Exit; + H := Trim(FColorHex.Text); + If Copy(H,1,1) = '#' Then + Delete(H,1,1); + If Length(H) <> 6 Then + Exit; + If Not TryStrToInt('$' + H,V) Then + Exit; + R := (V Shr 16) And $FF; + G := (V Shr 8) And $FF; + B := V And $FF; + LCaret := FColorHex.SelStart; + FUpdatingColor := True; + Try + FColorR.Text := IntToStr(R); + FColorG.Text := IntToStr(G); + FColorB.Text := IntToStr(B); + If FColorHex.Text <> '#' + UpperCase(H) Then + FColorHex.Text := '#' + UpperCase(H); + If LCaret > Length(FColorHex.Text) Then + LCaret := Length(FColorHex.Text); + FColorHex.SelStart := LCaret; + FColorPreview.Color := + TColor( + R Or + (G Shl 8) Or + (B Shl 16) + ); + Finally + FUpdatingColor := False; + End; +End; +Procedure TRESTDWHTMLDesignerForm.ColorRGBChange(Sender : TObject); +Begin + UpdateColorFromRGB; +End; +Procedure TRESTDWHTMLDesignerForm.ColorHexChange(Sender : TObject); +Begin + UpdateColorFromHex; +End; +Procedure TRESTDWHTMLDesignerForm.ColorCopyHexClick(Sender : TObject); +Begin + Clipboard.AsText := FColorHex.Text; +End; +Procedure TRESTDWHTMLDesignerForm.ColorCopyRGBClick(Sender : TObject); +Begin + Clipboard.AsText := + 'rgb(' + FColorR.Text + ', ' + FColorG.Text + ', ' + FColorB.Text + ')'; +End; +Procedure TRESTDWHTMLDesignerForm.ColorPreviewClick(Sender : TObject); +Var + D : TColorDialog; + C : TColor; + R, G, B : Integer; + LRGB : Longint; +Begin + D := TColorDialog.Create(Self); + Try + D.Options := + D.Options + + [cdFullOpen,cdAnyColor]; + D.Color := ColorToRGB(FColorPreview.Color); + LRGB := ColorToRGB(D.Color); + D.CustomColors.Values['ColorA'] := + IntToHex(GetRValue(LRGB),2) + + IntToHex(GetGValue(LRGB),2) + + IntToHex(GetBValue(LRGB),2); + If Not D.Execute Then + Exit; + C := ColorToRGB(D.Color); + R := GetRValue(C); + G := GetGValue(C); + B := GetBValue(C); + FUpdatingColor := True; + Try + FColorR.Text := IntToStr(R); + FColorG.Text := IntToStr(G); + FColorB.Text := IntToStr(B); + FColorHex.Text := + '#' + + IntToHex(R,2) + + IntToHex(G,2) + + IntToHex(B,2); + FColorPreview.Color := RGB(R,G,B); + Finally + FUpdatingColor := False; + End; + Finally + D.Free; + End; +End; +Procedure TRESTDWHTMLDesignerForm.UpdateRightDockHost; +Var + LInspectorDocked, + LObjectBrowserDocked : Boolean; +Begin + If Not Assigned(FRightDockHost) Then + Exit; + LInspectorDocked := + Assigned(FInspectorPanel) And FInspectorPanel.Visible And + (FInspectorPanel.Parent = FRightDockHost); + LObjectBrowserDocked := + Assigned(FObjectBrowserPanel) And FObjectBrowserPanel.Visible And + (FObjectBrowserPanel.Parent = FRightDockHost); + FRightDockHost.Visible := LInspectorDocked Or LObjectBrowserDocked; + If Assigned(FInspectorSplitter) Then + FInspectorSplitter.Visible := FRightDockHost.Visible; + If Assigned(FObjectBrowserSplitter) Then + FObjectBrowserSplitter.Visible := LObjectBrowserDocked And LInspectorDocked; +End; +Procedure TRESTDWHTMLDesignerForm.UpdateLeftDockHost; +Var + LProjectDocked, + LColorDocked : Boolean; +Begin + LProjectDocked := + Assigned(FProjectPanel) And + (FProjectPanel.Parent = FLeftDockHost) And + FProjectPanel.Visible; + LColorDocked := + Assigned(FColorToolPanel) And + (FColorToolPanel.Parent = FLeftDockHost) And + FColorToolPanel.Visible; + FLeftDockHost.Visible := + LProjectDocked Or + LColorDocked; + FProjectSplitter.Visible := + FLeftDockHost.Visible; + If LColorDocked Then + Begin + FColorToolPanel.Align := alTop; + FColorToolPanel.Height := 172; + FColorToolPanel.BringToFront; + End; + If LProjectDocked Then + Begin + FProjectPanel.Align := alClient; + FProjectPanel.BringToFront; + End; +End; +Procedure TRESTDWHTMLDesignerForm.BringFloatingFormsToFront; + Procedure BringForm(AForm : TForm); + Begin + If Assigned(AForm) And + AForm.Visible Then + Begin + AForm.FormStyle := fsStayOnTop; + AForm.BringToFront; + End; + End; +Begin + BringForm(FProjectFloatForm); + BringForm(FInspectorFloatForm); + BringForm(FMessagesFloatForm); + BringForm(FPreviewFloatForm); + BringForm(FAIFloatForm); + BringForm(FColorToolFloatForm); +End; +Procedure TRESTDWHTMLDesignerForm.ResetIDELayoutClick( + Sender : TObject); + Procedure DockPanel( + APanelID : Integer; + APanel : TPanel; + AFloatForm : TForm); + Begin + If Assigned(AFloatForm) Then + ToggleFloatDock(APanelID) + Else + Begin + APanel.Visible := True; + Case APanelID Of + 1 : + Begin + APanel.Parent := FLeftDockHost; + APanel.Align := alClient; + FProjectSplitter.Visible := True; + End; + 2 : + Begin + APanel.Parent := FRightDockHost; + APanel.Align := alClient; + FInspectorSplitter.Visible := True; + End; + 3 : + Begin + APanel.Parent := Self; + APanel.Align := alBottom; + FMessagesSplitter.Visible := True; + End; + 4 : + Begin + APanel.Parent := FWorkPanel; + APanel.Align := alClient; + End; + 5 : + Begin + APanel.Parent := Self; + APanel.Align := alBottom; + FAISplitter.Visible := True; + End; + 6 : + Begin + APanel.Parent := FLeftDockHost; + APanel.Align := alTop; + End; + 7 : + Begin + APanel.Parent := FRightDockHost; + APanel.Align := alTop; + FObjectBrowserSplitter.Visible := True; + End; + End; + End; + End; +Begin + DockPanel(1,FProjectPanel,FProjectFloatForm); + DockPanel(2,FInspectorPanel,FInspectorFloatForm); + DockPanel(3,FMessagesPanel,FMessagesFloatForm); + DockPanel(4,FPreviewPanel,FPreviewFloatForm); + DockPanel(5,FAIPanel,FAIFloatForm); + DockPanel(6,FColorToolPanel,FColorToolFloatForm); + DockPanel(7,FObjectBrowserPanel,FObjectBrowserFloatForm); + If Assigned(FLeftDockHost) Then + FLeftDockHost.Width := 280; + If Assigned(FColorToolPanel) Then + Begin + FColorToolPanel.Height := 172; + FColorToolPanel.BringToFront; + End; + If Assigned(FProjectPanel) Then + FProjectPanel.BringToFront; + If Assigned(FRightDockHost) Then + FRightDockHost.Width := 320; + If Assigned(FObjectBrowserPanel) Then + FObjectBrowserPanel.Height := 220; + If Assigned(FMessagesPanel) Then + FMessagesPanel.Height := 180; + If Assigned(FAIPanel) Then + FAIPanel.Height := 250; + If Assigned(FWebView) Then + Begin + FWebView.Parent := FPreviewPanel; + FWebView.Align := alClient; + FWebView.Visible := True; + FWebView.BringToFront; + End; + BuildProjectExplorer; + UpdateLeftDockHost; + UpdateRightDockHost; + SaveIDESettings; +End; +Procedure TRESTDWHTMLDesignerForm.SetDockPanelVisible( + APanelID : Integer; + AVisible : Boolean); +Var + LPanel : TPanel; + LForm : TForm; +Begin + LPanel := Nil; + LForm := Nil; + Case APanelID Of + 1 : + Begin + LPanel := FProjectPanel; + LForm := FProjectFloatForm; + If Assigned(FProjectSplitter) Then + FProjectSplitter.Visible := + AVisible And (FProjectPanel.Parent = FLeftDockHost); + End; + 2 : + Begin + LPanel := FInspectorPanel; + LForm := FInspectorFloatForm; + If Assigned(FInspectorSplitter) Then + FInspectorSplitter.Visible := + AVisible And (FInspectorPanel.Parent = FRightDockHost); + End; + 3 : + Begin + LPanel := FMessagesPanel; + LForm := FMessagesFloatForm; + If Assigned(FMessagesSplitter) Then + FMessagesSplitter.Visible := + AVisible And (FMessagesPanel.Parent = Self); + End; + 4 : + Begin + LPanel := FPreviewPanel; + LForm := FPreviewFloatForm; + End; + 5 : + Begin + LPanel := FAIPanel; + LForm := FAIFloatForm; + If Assigned(FAISplitter) Then + FAISplitter.Visible := + AVisible And + (FAIPanel.Parent = Self); + End; + 6 : + Begin + LPanel := FColorToolPanel; + LForm := FColorToolFloatForm; + End; + 7 : + Begin + LPanel := FObjectBrowserPanel; + LForm := FObjectBrowserFloatForm; + If Assigned(FObjectBrowserSplitter) Then + FObjectBrowserSplitter.Visible := + AVisible And (FObjectBrowserPanel.Parent = FRightDockHost); + End; + End; + If LPanel = Nil Then + Exit; + LPanel.Visible := AVisible; + If Assigned(LForm) Then + Begin + If AVisible Then + Begin + LForm.Show; + LForm.BringToFront; + LForm.SetFocus; + End + Else + LForm.Hide; + End; + If (APanelID = 1) Or + (APanelID = 6) Then + UpdateLeftDockHost; + UpdateRightDockHost; +End; +Procedure TRESTDWHTMLDesignerForm.DockCloseClick( + Sender : TObject); +Begin + If Sender Is TSpeedButton Then + SetDockPanelVisible( + TSpeedButton(Sender).Tag, + False + ); +End; +Procedure TRESTDWHTMLDesignerForm.DockFloatClick( + Sender : TObject); +Begin + If Sender Is TSpeedButton Then + ToggleFloatDock( + TSpeedButton(Sender).Tag + ); +End; +Procedure TRESTDWHTMLDesignerForm.FloatingFormClose( + Sender : TObject; + Var CloseAction : TCloseAction); +Begin + CloseAction := caHide; + If Sender = FProjectFloatForm Then + FProjectPanel.Visible := False + Else If Sender = FInspectorFloatForm Then + FInspectorPanel.Visible := False + Else If Sender = FMessagesFloatForm Then + FMessagesPanel.Visible := False + Else If Sender = FPreviewFloatForm Then + FPreviewPanel.Visible := False + Else If Sender = FAIFloatForm Then + FAIPanel.Visible := False + Else If Sender = FColorToolFloatForm Then + FColorToolPanel.Visible := False + Else If Sender = FObjectBrowserFloatForm Then + FObjectBrowserPanel.Visible := False; + UpdateRightDockHost; +End; +Procedure TRESTDWHTMLDesignerForm.ToggleFloatDock( + APanelID : Integer); +Var + LPanel : TPanel; + LFloatForm : TForm; + LDockParent : TWinControl; + LDockAlign : TAlign; + LCaption : String; + LWidth, + LHeight : Integer; +Begin + LPanel := Nil; + LFloatForm := Nil; + LDockParent := Self; + LDockAlign := alNone; + LCaption := ''; + LWidth := 420; + LHeight := 500; + Case APanelID Of + 1 : + Begin + LPanel := FProjectPanel; + LFloatForm := FProjectFloatForm; + LDockParent := FLeftDockHost; + LDockAlign := alClient; + LCaption := Lang('ProjectExplorer'); + LWidth := FProjectPanel.Width; + End; + 2 : + Begin + LPanel := FInspectorPanel; + LFloatForm := FInspectorFloatForm; + LDockParent := FRightDockHost; + LDockAlign := alClient; + LCaption := Lang('ObjectInspector'); + LWidth := FInspectorPanel.Width; + End; + 3 : + Begin + LPanel := FMessagesPanel; + LFloatForm := FMessagesFloatForm; + LDockAlign := alBottom; + LCaption := Lang('ShowErrors'); + LWidth := 850; + LHeight := FMessagesPanel.Height + 80; + End; + 4 : + Begin + LPanel := FPreviewPanel; + LFloatForm := FPreviewFloatForm; + LDockParent := FWorkPanel; + LDockAlign := alClient; + LCaption := Lang('FormDesign'); + LWidth := 900; + LHeight := 650; + End; + 5 : + Begin + LPanel := FAIPanel; + LFloatForm := FAIFloatForm; + LDockParent := Self; + LDockAlign := alBottom; + LCaption := 'REST Dataware AI Console'; + LWidth := 850; + LHeight := 430; + End; + 6 : + Begin + LPanel := FColorToolPanel; + LFloatForm := FColorToolFloatForm; + LDockParent := FLeftDockHost; + LDockAlign := alTop; + LCaption := 'CSS Color Tool'; + LWidth := 300; + LHeight := 190; + End; + 7 : + Begin + LPanel := FObjectBrowserPanel; + LFloatForm := FObjectBrowserFloatForm; + LDockParent := FRightDockHost; + LDockAlign := alTop; + LCaption := 'Object Browser'; + LWidth := 360; + LHeight := 420; + End; + End; + If LPanel = Nil Then + Exit; + If Assigned(LFloatForm) Then + Begin + If (APanelID = 4) And + Assigned(FWebView) Then + FWebView.DetachHost; + LPanel.Parent := LDockParent; + LPanel.Align := LDockAlign; + LPanel.Visible := True; + Case APanelID Of + 1 : + Begin + FProjectFloatForm.Free; + FProjectFloatForm := Nil; + FProjectSplitter.Visible := True; + End; + 2 : + Begin + FInspectorFloatForm.Free; + FInspectorFloatForm := Nil; + FInspectorSplitter.Visible := True; + End; + 3 : + Begin + FMessagesFloatForm.Free; + FMessagesFloatForm := Nil; + FMessagesSplitter.Visible := True; + End; + 4 : + Begin + FPreviewFloatForm.Free; + FPreviewFloatForm := Nil; + End; + 5 : + Begin + FAIFloatForm.Free; + FAIFloatForm := Nil; + FAISplitter.Visible := True; + End; + 6 : + Begin + FColorToolFloatForm.Free; + FColorToolFloatForm := Nil; + End; + 7 : + Begin + FObjectBrowserFloatForm.Free; + FObjectBrowserFloatForm := Nil; + FObjectBrowserSplitter.Visible := True; + End; + End; + If (APanelID = 4) And + Assigned(FWebView) Then + Begin + FWebView.Parent := FPreviewPanel; + FWebView.Align := alClient; + FWebView.Visible := True; + FWebView.BringToFront; + Application.ProcessMessages; + FWebView.RebindHost; + End; + UpdateLeftDockHost; + UpdateRightDockHost; + Exit; + End; + LFloatForm := TForm.CreateNew(Self,1); + LFloatForm.Caption := LCaption; + LFloatForm.Position := poDesigned; + LFloatForm.BorderStyle := bsSizeable; + LFloatForm.FormStyle := fsStayOnTop; + LFloatForm.Width := LWidth; + LFloatForm.Height := LHeight; + LFloatForm.Left := Left + 80; + LFloatForm.Top := Top + 80; + If LFloatForm.Left < Screen.WorkAreaRect.Left Then + LFloatForm.Left := Screen.WorkAreaRect.Left + 20; + If LFloatForm.Top < Screen.WorkAreaRect.Top Then + LFloatForm.Top := Screen.WorkAreaRect.Top + 20; + If LFloatForm.Left + LFloatForm.Width > Screen.WorkAreaRect.Right Then + LFloatForm.Left := Screen.WorkAreaRect.Right - LFloatForm.Width - 20; + If LFloatForm.Top + LFloatForm.Height > Screen.WorkAreaRect.Bottom Then + LFloatForm.Top := Screen.WorkAreaRect.Bottom - LFloatForm.Height - 20; + LFloatForm.OnClose := FloatingFormClose; + If (APanelID = 4) And + Assigned(FWebView) Then + FWebView.DetachHost; + LPanel.Align := alClient; + LPanel.Parent := LFloatForm; + LPanel.Visible := True; + Case APanelID Of + 1 : + Begin + FProjectFloatForm := LFloatForm; + FProjectSplitter.Visible := False; + End; + 2 : + Begin + FInspectorFloatForm := LFloatForm; + FInspectorSplitter.Visible := False; + End; + 3 : + Begin + FMessagesFloatForm := LFloatForm; + FMessagesSplitter.Visible := False; + End; + 4 : + FPreviewFloatForm := LFloatForm; + 5 : + Begin + FAIFloatForm := LFloatForm; + FAISplitter.Visible := False; + End; + 6 : + FColorToolFloatForm := LFloatForm; + 7 : + Begin + FObjectBrowserFloatForm := LFloatForm; + FObjectBrowserSplitter.Visible := False; + End; + End; + LFloatForm.Show; + LFloatForm.BringToFront; + LFloatForm.SetFocus; + If (APanelID = 4) And + Assigned(FWebView) Then + Begin + { WebView/WebView2 keeps a native child window. After the preview panel is + reparented to a floating form, force its host back onto the preview panel + and navigate the current generated page again. Without this, some widgetsets + and WebView2 controllers retain the old parent handle and show a gray area. } + FWebView.Parent := FPreviewPanel; + FWebView.Align := alClient; + FWebView.Visible := True; + FWebView.BringToFront; + Application.ProcessMessages; + FWebView.RebindHost; + End; + UpdateLeftDockHost; + UpdateRightDockHost; +End; +Procedure TRESTDWHTMLDesignerForm.ShowProjectPanelClick( + Sender : TObject); +Begin + SetDockPanelVisible(1,True); +End; +Procedure TRESTDWHTMLDesignerForm.ShowInspectorPanelClick( + Sender : TObject); +Begin + SetDockPanelVisible(2,True); +End; +Procedure TRESTDWHTMLDesignerForm.ShowObjectBrowserPanelClick( + Sender : TObject); +Begin + SetDockPanelVisible(7,True); +End; +Procedure TRESTDWHTMLDesignerForm.ShowMessagesPanelClick( + Sender : TObject); +Begin + SetDockPanelVisible(3,True); +End; +Procedure TRESTDWHTMLDesignerForm.ShowFormDesignPanelClick( + Sender : TObject); +Begin + SetDockPanelVisible(4,True); + ShowFormDesign; +End; +Procedure TRESTDWHTMLDesignerForm.BuildUI; +Var + LMessagesMenuItem : TMenuItem; + LSplit : TSplitter; + LTab : TTabSheet; + LLabel : TLabel; + {$IFDEF FPC} + LScheme : TSynHighlighterMultiScheme; + {$ELSE} + LScheme : TScheme; + {$ENDIF} +Begin + If FEditorTitle <> '' Then + Caption := FEditorTitle + Else + Caption := 'REST Dataware - Visual Web IDE'; + BorderStyle := bsSizeable; + BorderIcons := [biSystemMenu,biMinimize,biMaximize]; + FormStyle := fsNormal; + WindowState := wsNormal; + Position := poScreenCenter; + Width := 1500; + Height := 900; + KeyPreview := True; + OnKeyDown := FormKeyDownHandler; + OnShow := FormShowHandler; + OnActivate := FormActivateHandler; + OnCloseQuery := FormCloseQueryHandler; + BuildMenus; + FToolbar := TPanel.Create(Self); + FToolbar.Parent := Self; + FToolbar.Align := alTop; + FToolbar.Height := 66; + FToolbar.Caption := ''; + FToolbar.BevelOuter := bvNone; + FToolbar.Visible := True; + FToolButtonPanel := TPanel.Create(FToolbar); + FToolButtonPanel.Parent := FToolbar; + FToolButtonPanel.Align := alLeft; + FToolButtonPanel.Height := 66; + FToolButtonPanel.Width := 156; + FToolButtonPanel.Caption := ''; + FToolButtonPanel.BevelOuter := bvNone; + FToolButtonSeparator := TPanel.Create(FToolbar); + FToolButtonSeparator.Parent := FToolbar; + FToolButtonSeparator.Align := alLeft; + FToolButtonSeparator.Width := 1; + FToolButtonSeparator.Caption := ''; + FToolButtonSeparator.BevelOuter := bvNone; + FToolButtonSeparator.Color := clBtnShadow; + FNewButton := TSpeedButton.Create(FToolButtonPanel); + FNewButton.Parent := FToolButtonPanel; + FNewButton.SetBounds(5,4,28,28); + FNewButton.Caption := ''; + FNewButton.Flat := True; + FNewButton.Hint := 'Create a new blank PageProducer page. If the current page has unsaved changes, you will be asked to save them first.'; + FNewButton.ShowHint := True; + FNewButton.OnClick := NewClick; + RESTDWLoadHTMLDesignerIcon( + FNewButton.Glyph, + 'toolbar_new.bmp' + ); + FNewButton.Caption := ''; + FOpenButton := TSpeedButton.Create(FToolButtonPanel); + FOpenButton.Parent := FToolButtonPanel; + FOpenButton.SetBounds(35,4,28,28); + FOpenButton.Caption := ''; + FOpenButton.Flat := True; + FOpenButton.Hint := 'Open an HTML page from disk and load it into the PageProducer visual editor. Unsaved changes are confirmed first. Shortcut: Ctrl+O.'; + FOpenButton.ShowHint := True; + FOpenButton.OnClick := OpenClick; + RESTDWLoadHTMLDesignerIcon( + FOpenButton.Glyph, + 'toolbar_open.bmp' + ); + FOpenButton.Caption := ''; + FSaveButton := TSpeedButton.Create(FToolButtonPanel); + FSaveButton.Parent := FToolButtonPanel; + FSaveButton.SetBounds(65,4,28,28); + FSaveButton.Caption := ''; + FSaveButton.Flat := True; + FSaveButton.Hint := 'Save the complete generated PageProducer page to disk. This command is enabled only when the document has been modified. Shortcut: Ctrl+S.'; + FSaveButton.ShowHint := True; + FSaveButton.Enabled := False; + FSaveButton.OnClick := SaveClick; + RESTDWLoadHTMLDesignerSaveIcon( + FSaveButton.Glyph + ); + FSaveButton.NumGlyphs := 2; + FSaveButton.Caption := ''; + FRefreshButton := TSpeedButton.Create(FToolButtonPanel); + FRefreshButton.Parent := FToolButtonPanel; + FRefreshButton.SetBounds(95,4,28,28); + FRefreshButton.Caption := ''; + FRefreshButton.Flat := True; + FRefreshButton.Hint := 'Refresh the WebViewer with the current PageProducer source.'; + FRefreshButton.ShowHint := True; + FRefreshButton.OnClick := RefreshClick; + BuildBrowserRefreshGlyph(FRefreshButton.Glyph); + FRefreshButton.Caption := ''; + FHelpButton := TSpeedButton.Create(FToolButtonPanel); + FHelpButton.Parent := FToolButtonPanel; + FHelpButton.SetBounds(125,4,28,28); + FHelpButton.Caption := ''; + FHelpButton.Font.Style := [fsBold]; + FHelpButton.Flat := True; + FHelpButton.Hint := 'Open the complete REST Dataware Visual Web IDE help.'; + FHelpButton.ShowHint := True; + FHelpButton.OnClick := HelpClick; + RESTDWLoadHTMLDesignerIcon( + FHelpButton.Glyph, + 'toolbar_help.bmp' + ); + FDebugStartButton := TSpeedButton.Create(FToolButtonPanel); + FDebugStartButton.Parent := FToolButtonPanel; + FDebugStartButton.SetBounds(5,35,28,26); + FDebugStartButton.Caption := ''; + FDebugStartButton.Flat := True; + FDebugStartButton.Hint := 'Run/Continue JavaScript debugging. Lazarus shortcut: F9.'; + FDebugStartButton.ShowHint := True; + FDebugStartButton.OnClick := DebugStartClick; + FDebugStopButton := TSpeedButton.Create(FToolButtonPanel); + FDebugStopButton.Parent := FToolButtonPanel; + FDebugStopButton.SetBounds(35,35,28,26); + FDebugStopButton.Caption := ''; + FDebugStopButton.Flat := True; + FDebugStopButton.Hint := 'Stop debugging. Lazarus shortcut: Ctrl+F2.'; + FDebugStopButton.ShowHint := True; + FDebugStopButton.Enabled := False; + FDebugStopButton.OnClick := DebugStopClick; + FDebugBreakpointButton := TSpeedButton.Create(FToolButtonPanel); + FDebugBreakpointButton.Parent := FToolButtonPanel; + FDebugBreakpointButton.SetBounds(65,35,28,26); + FDebugBreakpointButton.Caption := ''; + FDebugBreakpointButton.Flat := True; + FDebugBreakpointButton.Hint := 'Toggle breakpoint. Lazarus shortcut: F5; double-click the line-number gutter.'; + FDebugBreakpointButton.ShowHint := True; + FDebugBreakpointButton.OnClick := ToggleBreakpointClick; + FDebugClearButton := TSpeedButton.Create(FToolButtonPanel); + FDebugClearButton.Parent := FToolButtonPanel; + FDebugClearButton.SetBounds(95,35,28,26); + FDebugClearButton.Caption := ''; + FDebugClearButton.Flat := True; + FDebugClearButton.Hint := 'Clear all breakpoints.'; + FDebugClearButton.ShowHint := True; + FDebugClearButton.OnClick := DebugClearBreakpointsClick; + FDebugDevToolsButton := TSpeedButton.Create(FToolButtonPanel); + FDebugDevToolsButton.Parent := FToolButtonPanel; + FDebugDevToolsButton.SetBounds(125,35,28,26); + FDebugDevToolsButton.Caption := ''; + FDebugDevToolsButton.Flat := True; + FDebugDevToolsButton.Hint := 'Open WebView DevTools.'; + FDebugDevToolsButton.ShowHint := True; + FDebugDevToolsButton.OnClick := DebugDevToolsClick; + RESTDWLoadHTMLDesignerIcon(FDebugStartButton.Glyph,'toolbar_debug_start.bmp'); + RESTDWLoadHTMLDesignerStopDebugIcon(FDebugStopButton.Glyph); + FDebugStopButton.NumGlyphs := 2; + RESTDWLoadHTMLDesignerIcon(FDebugBreakpointButton.Glyph,'toolbar_debug_breakpoint.bmp'); + RESTDWLoadHTMLDesignerIcon(FDebugClearButton.Glyph,'toolbar_debug_clear.bmp'); + RESTDWLoadHTMLDesignerIcon(FDebugDevToolsButton.Glyph,'toolbar_debug_devtools.bmp'); + FPaletteTabs := TPageControl.Create(FToolbar); + FPaletteTabs.Parent := FToolbar; + FPaletteTabs.Align := alClient; + FPaletteTabs.Height := 60; + { Standard is intentionally the first component palette, matching + Lazarus/Delphi and containing the most frequently used page controls. } + LTab := TTabSheet.Create(FPaletteTabs); + LTab.PageControl := FPaletteTabs; + LTab.Caption := 'Standard'; + FMessagesPanel := TPanel.Create(Self); + FMessagesPanel.Parent := Self; + FMessagesPanel.Align := alBottom; + FMessagesPanel.Height := 145; + FMessagesPanel.Caption := ''; + BuildDockHeader( + FMessagesPanel, + FMessagesHeader, + 'Show Errors', + 3 + ); + FMessages := TStringGrid.Create(FMessagesPanel); + FMessages.Parent := FMessagesPanel; + FMessages.Align := alClient; + FMessages.ColCount := 5; + FMessages.RowCount := 1; + FMessages.FixedRows := 0; + FMessages.FixedCols := 0; + FMessages.Options := [ + goFixedVertLine, + goVertLine, + goColSizing, + goRangeSelect + ]; + FMessages.Cells[0,0] := 'Type'; + FMessages.Cells[1,0] := 'File'; + FMessages.Cells[2,0] := 'Line'; + FMessages.Cells[3,0] := 'Column'; + FMessages.Cells[4,0] := 'Message'; + FMessages.ColWidths[0] := 80; + FMessages.ColWidths[1] := 180; + FMessages.ColWidths[2] := 60; + FMessages.ColWidths[3] := 70; + FMessagesPanel.OnResize := MessagesResize; + FMessages.OnDblClick := MessagesDblClick; + FMessages.OnKeyDown := MessagesKeyDown; + FMessagesPopup := TPopupMenu.Create(Self); + LMessagesMenuItem := TMenuItem.Create(FMessagesPopup); + LMessagesMenuItem.Caption := 'Copy selected error(s)'; + LMessagesMenuItem.OnClick := MessagesCopySelectionClick; + FMessagesPopup.Items.Add(LMessagesMenuItem); + LMessagesMenuItem := TMenuItem.Create(FMessagesPopup); + LMessagesMenuItem.Caption := '-'; + FMessagesPopup.Items.Add(LMessagesMenuItem); + LMessagesMenuItem := TMenuItem.Create(FMessagesPopup); + LMessagesMenuItem.Caption := 'Select all'; + LMessagesMenuItem.ShortCut := ShortCut(Ord('A'),[ssCtrl]); + LMessagesMenuItem.OnClick := MessagesSelectAllClick; + FMessagesPopup.Items.Add(LMessagesMenuItem); + LMessagesMenuItem := TMenuItem.Create(FMessagesPopup); + LMessagesMenuItem.Caption := 'Copy all errors'; + LMessagesMenuItem.ShortCut := ShortCut(Ord('C'),[ssCtrl,ssShift]); + LMessagesMenuItem.OnClick := MessagesCopyAllClick; + FMessagesPopup.Items.Add(LMessagesMenuItem); + FMessages.PopupMenu := FMessagesPopup; + FMessagesSplitter := TSplitter.Create(Self); + FMessagesSplitter.Parent := Self; + FMessagesSplitter.Align := alBottom; + FMessagesSplitter.Height := 5; + FAIConsole := Nil; + FAIPanel := TPanel.Create(Self); + FAIPanel.Parent := Self; + FAIPanel.Align := alBottom; + FAIPanel.Height := 225; + FAIPanel.Caption := ''; + FAIPanel.Visible := False; + BuildDockHeader( + FAIPanel, + FAIHeader, + 'AI Console', + 5 + ); + FAIConsole := TRESTDWHTMLAIConsolePanel.Create(Self); + FAIConsole.Parent := FAIPanel; + FAIConsole.Align := alClient; + FAIConsole.OnBuildContext := AIPageContext; + FAISplitter := TSplitter.Create(Self); + FAISplitter.Parent := Self; + FAISplitter.Align := alBottom; + FAISplitter.Height := 5; + FAISplitter.Visible := False; + FLeftDockHost := TPanel.Create(Self); + FLeftDockHost.Parent := Self; + FLeftDockHost.Align := alLeft; + FLeftDockHost.Width := 280; + FLeftDockHost.Caption := ''; + FLeftDockHost.BevelOuter := bvNone; + FColorToolPanel := TPanel.Create(FLeftDockHost); + FColorToolPanel.Parent := FLeftDockHost; + FColorToolPanel.Align := alTop; + FColorToolPanel.Height := 172; + FColorToolPanel.Caption := ''; + FColorToolPanel.BevelOuter := bvLowered; + BuildDockHeader( + FColorToolPanel, + FColorToolHeader, + 'CSS Color Tool', + 6 + ); + With TLabel.Create(FColorToolPanel) Do + Begin Parent := FColorToolPanel; SetBounds(8,34,16,20); Caption := 'R'; End; + FColorR := TEdit.Create(FColorToolPanel); + FColorR.Parent := FColorToolPanel; + FColorR.SetBounds(24,31,42,22); + FColorR.Text := '0'; + FColorR.OnChange := ColorRGBChange; + With TLabel.Create(FColorToolPanel) Do + Begin Parent := FColorToolPanel; SetBounds(70,34,16,20); Caption := 'G'; End; + FColorG := TEdit.Create(FColorToolPanel); + FColorG.Parent := FColorToolPanel; + FColorG.SetBounds(86,31,42,22); + FColorG.Text := '0'; + FColorG.OnChange := ColorRGBChange; + With TLabel.Create(FColorToolPanel) Do + Begin Parent := FColorToolPanel; SetBounds(132,34,16,20); Caption := 'B'; End; + FColorB := TEdit.Create(FColorToolPanel); + FColorB.Parent := FColorToolPanel; + FColorB.SetBounds(148,31,42,22); + FColorB.Text := '0'; + FColorB.OnChange := ColorRGBChange; + FColorPreview := TPanel.Create(FColorToolPanel); + FColorPreview.Parent := FColorToolPanel; + FColorPreview.SetBounds(8,60,58,54); + FColorPreview.Caption := ''; + FColorPreview.BevelOuter := bvLowered; + FColorPreview.ParentBackground := False; + FColorPreview.Color := 0; + FColorPreview.Hint := 'Click to choose a color'; + FColorPreview.ShowHint := True; + FColorPreview.OnClick := ColorPreviewClick; + With TLabel.Create(FColorToolPanel) Do + Begin Parent := FColorToolPanel; SetBounds(74,62,34,20); Caption := 'HEX'; End; + FColorHex := TEdit.Create(FColorToolPanel); + FColorHex.Parent := FColorToolPanel; + FColorHex.SetBounds(108,59,82,22); + FColorHex.Text := '#000000'; + FColorHex.OnChange := ColorHexChange; + FColorCopyHex := TButton.Create(FColorToolPanel); + FColorCopyHex.Parent := FColorToolPanel; + FColorCopyHex.SetBounds(74,88,116,25); + FColorCopyHex.Caption := 'Copy HEX'; + FColorCopyHex.OnClick := ColorCopyHexClick; + FColorCopyRGB := TButton.Create(FColorToolPanel); + FColorCopyRGB.Parent := FColorToolPanel; + FColorCopyRGB.SetBounds(8,122,182,25); + FColorCopyRGB.Caption := 'Copy RGB'; + FColorCopyRGB.OnClick := ColorCopyRGBClick; + FProjectPanel := TPanel.Create(FLeftDockHost); + FProjectPanel.Parent := FLeftDockHost; + FProjectPanel.Align := alClient; + FProjectPanel.Caption := ''; + BuildDockHeader( + FProjectPanel, + FProjectHeader, + 'Project Explorer', + 1 + ); + FProjectTree := TTreeView.Create(FProjectPanel); + FProjectTree.Parent := FProjectPanel; + FProjectTree.Align := alClient; + FProjectTree.OnClick := ProjectTreeClick; + FProjectSplitter := TSplitter.Create(Self); + FProjectSplitter.Parent := Self; + FProjectSplitter.Align := alLeft; + FProjectSplitter.Width := 5; + FInspectorSplitter := TSplitter.Create(Self); + FInspectorSplitter.Parent := Self; + FInspectorSplitter.Align := alRight; + FInspectorSplitter.Width := 5; + FRightDockHost := TPanel.Create(Self); + FRightDockHost.Parent := Self; + FRightDockHost.Align := alRight; + FRightDockHost.Width := 320; + FRightDockHost.BevelOuter := bvNone; + FRightDockHost.Caption := ''; + FObjectBrowserPanel := TPanel.Create(FRightDockHost); + FObjectBrowserPanel.Parent := FRightDockHost; + FObjectBrowserPanel.Align := alTop; + FObjectBrowserPanel.Height := 220; + FObjectBrowserPanel.Constraints.MinHeight := 80; + FObjectBrowserPanel.Caption := ''; + BuildDockHeader( + FObjectBrowserPanel, + FObjectBrowserHeader, + 'Object Browser', + 7 + ); + FObjectBrowserImages := TImageList.Create(Self); + FObjectBrowserImages.Width := 16; + FObjectBrowserImages.Height := 16; + FObjectBrowserTree := TTreeView.Create(FObjectBrowserPanel); + FObjectBrowserTree.Parent := FObjectBrowserPanel; + FObjectBrowserTree.Align := alClient; + FObjectBrowserTree.Images := FObjectBrowserImages; + FObjectBrowserTree.AutoExpand := False; + FObjectBrowserTree.OnClick := ObjectBrowserClick; + FInspectorPanel := TPanel.Create(FRightDockHost); + FInspectorPanel.Parent := FRightDockHost; + FInspectorPanel.Align := alClient; + FInspectorPanel.Constraints.MinHeight := 100; + FInspectorPanel.Caption := ''; + FObjectBrowserSplitter := TSplitter.Create(FRightDockHost); + FObjectBrowserSplitter.Parent := FRightDockHost; + FObjectBrowserSplitter.Align := alTop; + FObjectBrowserSplitter.Top := FObjectBrowserPanel.Height; + FObjectBrowserSplitter.Height := 6; + FObjectBrowserSplitter.AutoSnap := False; + FObjectBrowserSplitter.MinSize := 80; + FObjectBrowserSplitter.ResizeStyle := rsUpdate; + BuildDockHeader( + FInspectorPanel, + FInspectorHeader, + 'Object Inspector', + 2 + ); + FInspectorPages := TPageControl.Create(FInspectorPanel); FInspectorPages.Parent := FInspectorPanel; + FInspectorPages.Align := alClient; + LTab := TTabSheet.Create(FInspectorPages); LTab.PageControl := FInspectorPages; LTab.Caption := 'Properties'; + FProperties := TStringGrid.Create(LTab); + FProperties.Parent := LTab; + FProperties.Align := alClient; + FProperties.ColCount := 2; + FProperties.RowCount := 1; + FProperties.FixedRows := 0; + FProperties.FixedCols := 1; + FProperties.DefaultRowHeight := 21; + FProperties.ColWidths[0] := 118; + FProperties.ColWidths[1] := 145; + FProperties.GridLineWidth := 0; + FProperties.DefaultDrawing := False; + FProperties.Options := + FProperties.Options + + [goEditing,goColSizing,goDrawFocusSelected]; + FProperties.Cells[0,0] := 'Property'; + FProperties.Cells[1,0] := 'Value'; + FProperties.OnDrawCell := InspectorGridDrawCell; + FProperties.OnExit := PropertiesEditingDone; + FProperties.OnSetEditText := PropertiesSetEditText; + LTab := TTabSheet.Create(FInspectorPages); LTab.PageControl := FInspectorPages; LTab.Caption := 'Events'; + FEvents := TStringGrid.Create(LTab); + FEvents.Parent := LTab; + FEvents.Align := alClient; + FEvents.ColCount := 2; + FEvents.RowCount := 1; + FEvents.FixedRows := 0; + FEvents.FixedCols := 1; + FEvents.DefaultRowHeight := 21; + FEvents.ColWidths[0] := 118; + FEvents.ColWidths[1] := 145; + FEvents.GridLineWidth := 0; + FEvents.DefaultDrawing := False; + FEvents.Options := + FEvents.Options + + [goEditing,goColSizing,goDrawFocusSelected]; + FEvents.Cells[0,0] := 'Event'; + FEvents.Cells[1,0] := 'Handler'; + FEvents.OnDrawCell := InspectorGridDrawCell; + FEvents.OnExit := EventsEditingDone; + FEvents.OnDblClick := EventsDblClick; + FWorkPanel := TPanel.Create(Self); + FWorkPanel.Parent := Self; + FWorkPanel.Align := alClient; + FWorkPanel.Caption := ''; + FModeBar := TPanel.Create(FWorkPanel); + FModeBar.Parent := FWorkPanel; + FModeBar.Align := alTop; + FModeBar.Height := 34; + FModeBar.BevelOuter := bvLowered; + FModeBar.Caption := ''; + FFormDesignButton := TSpeedButton.Create(FModeBar); + FFormDesignButton.Parent := FModeBar; + FFormDesignButton.SetBounds(6,4,105,26); + FFormDesignButton.Caption := 'FormDesign'; + FFormDesignButton.GroupIndex := 1; + FFormDesignButton.AllowAllUp := False; + FFormDesignButton.Down := True; + FFormDesignButton.OnClick := FormDesignButtonClick; + FCodeEditorButton := TSpeedButton.Create(FModeBar); + FCodeEditorButton.Parent := FModeBar; + FCodeEditorButton.SetBounds(112,4,105,26); + FCodeEditorButton.Caption := 'Code Editor'; + FCodeEditorButton.GroupIndex := 1; + FCodeEditorButton.AllowAllUp := False; + FCodeEditorButton.OnClick := CodeEditorButtonClick; + { FDesign is kept only as an internal compatibility holder. + The real Form Designer surface is TRESTDWHTMLWebView. } + FDesign := TScrollBox.Create(FWorkPanel); + FDesign.Parent := FWorkPanel; + FDesign.Visible := False; + FDesign.SetBounds(0,0,0,0); + FPreviewPanel := TPanel.Create(FWorkPanel); + FPreviewPanel.Parent := FWorkPanel; + FPreviewPanel.Align := alClient; + FPreviewPanel.Caption := ''; + BuildDockHeader( + FPreviewPanel, + FPreviewHeader, + 'FormDesign', + 4 + ); + FCodePages := TPageControl.Create(FWorkPanel); + FCodePages.Parent := FWorkPanel; + FCodePages.Align := alClient; + FCodePages.Visible := False; + FFullCodeTab := TTabSheet.Create(FCodePages); FFullCodeTab.PageControl := FCodePages; FFullCodeTab.Caption := 'Full Page'; FFullCodeTab.TabVisible := False; + FHTMLTab := TTabSheet.Create(FCodePages); FHTMLTab.PageControl := FCodePages; FHTMLTab.Caption := 'HTML'; FHTMLTab.TabVisible := False; + FCSSTab := TTabSheet.Create(FCodePages); FCSSTab.PageControl := FCodePages; FCSSTab.Caption := 'CSS'; FCSSTab.TabVisible := False; + FJSTab := TTabSheet.Create(FCodePages); FJSTab.PageControl := FCodePages; FJSTab.Caption := 'JavaScript'; FJSTab.TabVisible := False; + FHTMLHighlighter := TSynHTMLSyn.Create(Self); + FCSSHighlighter := TSynCssSyn.Create(Self); + FJSHighlighter := TSynJScriptSyn.Create(Self); + FFullHTMLHighlighter := TSynHTMLSyn.Create(Self); + FFullCSSHighlighter := TSynCssSyn.Create(Self); + FFullJSHighlighter := TSynJScriptSyn.Create(Self); + FFullHighlighter := TSynMultiSyn.Create(Self); + FFullHighlighter.DefaultHighlighter := FFullHTMLHighlighter; + {$IFDEF FPC} + LScheme := TSynHighlighterMultiScheme( + FFullHighlighter.Schemes.Add + ); + {$ELSE} + LScheme := TScheme( + FFullHighlighter.Schemes.Add + ); + {$ENDIF} + LScheme.SchemeName := 'CSS'; + LScheme.CaseSensitive := False; + LScheme.StartExpr := ']*>'; + LScheme.EndExpr := ''; + LScheme.Highlighter := FFullCSSHighlighter; + {$IFDEF FPC} + LScheme := TSynHighlighterMultiScheme( + FFullHighlighter.Schemes.Add + ); + {$ELSE} + LScheme := TScheme( + FFullHighlighter.Schemes.Add + ); + {$ENDIF} + LScheme.SchemeName := 'JavaScript'; + LScheme.CaseSensitive := False; + LScheme.StartExpr := ']*>'; + LScheme.EndExpr := ''; + LScheme.Highlighter := FFullJSHighlighter; + FFullCode := TSynEdit.Create(FFullCodeTab); + FFullCode.Parent := FFullCodeTab; + FFullCode.Align := alClient; + FFullCode.Highlighter := FFullHighlighter; + FFullCode.Font.Name := 'Courier New'; + FFullCode.Font.Size := 10; + FFullCode.OnChange := FullCodeChanged; + FFullCode.OnClick := CodeEditorClick; + FFullCode.OnKeyUp := CodeEditorKeyUp; + FFullCode.OnGutterClick := CodeGutterClick; + FFullCode.OnMouseMove := CodeEditorMouseMove; + FFullCode.OnDblClick := CodeEditorDblClick; + FFullCode.Gutter.Visible := True; + FFullCode.Gutter.AutoSize := True; + {$IFNDEF FPC} + FFullCode.Gutter.ShowLineNumbers := True; + {$ENDIF} + FHTML := TSynEdit.Create(FHTMLTab); + FHTML.Parent := FHTMLTab; + FHTML.Align := alClient; + FHTML.Highlighter := FHTMLHighlighter; + FHTML.Font.Name := 'Courier New'; + FHTML.Font.Size := 10; + FHTML.Gutter.Visible := True; + FHTML.Gutter.AutoSize := True; + {$IFNDEF FPC} + FHTML.Gutter.ShowLineNumbers := True; + {$ENDIF} + FHTML.OnChange := SourceChanged; + FCSS := TSynEdit.Create(FCSSTab); + FCSS.Parent := FCSSTab; + FCSS.Align := alClient; + FCSS.Highlighter := FCSSHighlighter; + FCSS.Font.Name := 'Courier New'; + FCSS.Font.Size := 10; + FCSS.Gutter.Visible := True; + FCSS.Gutter.AutoSize := True; + {$IFNDEF FPC} + FCSS.Gutter.ShowLineNumbers := True; + {$ENDIF} + FCSS.OnChange := SourceChanged; + FJS := TSynEdit.Create(FJSTab); + FJS.Parent := FJSTab; + FJS.Align := alClient; + FJS.Highlighter := FJSHighlighter; + FJS.Font.Name := 'Courier New'; + FJS.Font.Size := 10; + FJS.Gutter.Visible := True; + FJS.Gutter.AutoSize := True; + {$IFNDEF FPC} + FJS.Gutter.ShowLineNumbers := True; + {$ENDIF} + FJS.OnGutterClick := CodeGutterClick; + FJS.OnDblClick := CodeEditorDblClick; + FJS.OnChange := SourceChanged; + FHTML.OnDragOver := CodeDragOver; FHTML.OnDragDrop := CodeDragDrop; + FFullCode.OnDragOver := CodeDragOver; FFullCode.OnDragDrop := CodeDragDrop; + FPreviewTimer := TTimer.Create(Self); FPreviewTimer.Enabled := False; + FPreviewTimer.Interval := 250; FPreviewTimer.OnTimer := PreviewTimerTimer; + FWebViewFirstTimer := TTimer.Create(Self); + FWebViewFirstTimer.Enabled := False; + FWebViewFirstTimer.Interval := 180; + FWebViewFirstTimer.OnTimer := WebViewFirstTimerTimer; + FWebViewFirstReady := False; + FWebView := TRESTDWHTMLWebView.Create(Self); + FWebView.Parent := FPreviewPanel; + FWebView.Align := alClient; + FWebView.OnReady := WebViewReady; + FWebView.OnError := WebViewError; + FWebView.OnPageError := WebViewPageError; + FWebView.OnElementSelected := WebViewElementSelected; + FWebView.OnHTMLChanged := WebViewHTMLChanged; + FWebView.OnObjectTree := WebViewObjectTree; + FWebView.OnDesignDragOver := DesignDragOver; + FWebView.OnDesignDragDrop := DesignDragDrop; + FPreviewPanel.OnDragOver := DesignDragOver; + FPreviewPanel.OnDragDrop := DesignDragDrop; + { WebView2 owns a native HWND and stays above normal sibling LCL controls. + Use an owned borderless form as the drag target so Windows/LCL can accept + palette drags while the rendered page remains visible underneath. } + FWebDropOverlay := TForm.CreateNew(Self,1); + FWebDropOverlay.BorderStyle := bsNone; + FWebDropOverlay.FormStyle := fsStayOnTop; + FWebDropOverlay.Caption := ''; + FWebDropOverlay.Color := clWhite; + FWebDropOverlay.AlphaBlend := True; + FWebDropOverlay.AlphaBlendValue := 1; + FWebDropOverlay.Visible := False; + FWebDropOverlay.OnDragOver := WebDropOverlayDragOver; + FWebDropOverlay.OnDragDrop := WebDropOverlayDragDrop; +End; +Function TRESTDWHTMLDesignerForm.ProjectNodeKey( + ANode : TTreeNode) : String; +Begin + Result := ''; + While ANode <> Nil Do + Begin + If Result = '' Then + Result := ANode.Text + Else + Result := ANode.Text + '/' + Result; + ANode := ANode.Parent; + End; +End; +Procedure TRESTDWHTMLDesignerForm.SaveProjectExplorerState( + AState : TStrings); +Var + I : Integer; + LNode : TTreeNode; +Begin + If AState = Nil Then + Exit; + AState.Clear; + If Not Assigned(FProjectTree) Then + Exit; + For I := 0 To FProjectTree.Items.Count - 1 Do + Begin + LNode := + FProjectTree.Items[I]; + If LNode.Expanded Then + AState.Add( + ProjectNodeKey( + LNode + ) + ); + End; +End; +Procedure TRESTDWHTMLDesignerForm.RestoreProjectExplorerState( + AState : TStrings; + AFirstBuild : Boolean); +Var + I : Integer; + LNode : TTreeNode; + LKey : String; +Begin + If Not Assigned(FProjectTree) Then + Exit; + If AFirstBuild Then + Begin + { Initial IDE layout only. After this first build the user's own collapsed / + expanded state is always preserved exactly. } + If FProjectTree.Items.Count > 0 Then + FProjectTree.Items[0].Expand(False); + For I := 0 To FProjectTree.Items.Count - 1 Do + Begin + LNode := + FProjectTree.Items[I]; + If SameText( + LNode.Text, + 'HTML' + ) And + (LNode.Parent <> Nil) Then + Begin + LNode.Expand(False); + Break; + End; + End; + Exit; + End; + If AState = Nil Then + Exit; + For I := 0 To FProjectTree.Items.Count - 1 Do + Begin + LNode := + FProjectTree.Items[I]; + LKey := + ProjectNodeKey( + LNode + ); + If AState.IndexOf(LKey) >= 0 Then + LNode.Expand(False) + Else + LNode.Collapse(False); + End; +End; +Procedure TRESTDWHTMLDesignerForm.AddProjectNode( + AParent : TTreeNode; + const ACaption, ASearchText : String); +Var + LNode : TTreeNode; + LInfo : TRESTDWHTMLProjectNodeInfo; +Begin + LInfo := TRESTDWHTMLProjectNodeInfo.Create; + LInfo.Name := ACaption; + LInfo.SearchText := ASearchText; + FProjectItems.Add(LInfo); + LNode := FProjectTree.Items.AddChild( + AParent, + ACaption + ); + LNode.Data := LInfo; +End; +Procedure TRESTDWHTMLDesignerForm.ParseCSSProjectNodes( + AParent : TTreeNode); +Var + LLines : TStringList; + I, + P : Integer; + LLine, + LSelector : String; +Begin + LLines := TStringList.Create; + Try + LLines.Text := FCSS.Text; + For I := 0 To LLines.Count - 1 Do + Begin + LLine := Trim(LLines[I]); + If LLine = '' Then + Continue; + P := Pos('{', LLine); + If P > 1 Then + Begin + LSelector := Trim( + Copy(LLine,1,P-1) + ); + If LSelector <> '' Then + AddProjectNode( + AParent, + LSelector, + LSelector + ); + End; + End; + Finally + LLines.Free; + End; +End; +Procedure TRESTDWHTMLDesignerForm.ParseJavaScriptProjectNodes( + AParent : TTreeNode); +Var + LLines : TStringList; + I, + P1, + P2 : Integer; + LLine, + LLower, + LName : String; +Begin + LLines := TStringList.Create; + Try + LLines.Text := FJS.Text; + For I := 0 To LLines.Count - 1 Do + Begin + LLine := Trim(LLines[I]); + LLower := LowerCase(LLine); + LName := ''; + P1 := Pos('function ', LLower); + If P1 > 0 Then + Begin + Inc(P1, Length('function ')); + P2 := PosEx('(', LLine, P1); + If P2 > P1 Then + LName := Trim( + Copy(LLine,P1,P2-P1) + ); + End; + If LName <> '' Then + AddProjectNode( + AParent, + LName + '()', + 'function ' + LName + ); + End; + Finally + LLines.Free; + End; +End; +Procedure TRESTDWHTMLDesignerForm.BuildProjectExplorer; +Var + I : Integer; + LRoot, + LHTML, + LCSS, + LJS : TTreeNode; + LState : TStringList; + LFirstBuild : Boolean; +Begin + LFirstBuild := + FProjectTree.Items.Count = 0; + LState := TStringList.Create; + FProjectTree.Items.BeginUpdate; + Try + If Not LFirstBuild Then + SaveProjectExplorerState( + LState + ); + For I := 0 To FProjectItems.Count - 1 Do + TObject(FProjectItems[I]).Free; + FProjectItems.Clear; + FProjectTree.Items.Clear; + LRoot := FProjectTree.Items.Add( + Nil, + Lang('PageProducerProject') + ); + AddProjectNode( + LRoot, + Lang('FullPage'), + '' + ); + LHTML := FProjectTree.Items.AddChild( + LRoot, + 'HTML' + ); + AddProjectNode( + LHTML, + Lang('PageOptions'), + '' + ); + AddProjectNode( + LHTML, + Lang('IncludeScripts'), + '',LLine) = 0 Then + LInsideScript := True + Else + LInsideScript := False; + End; + If I = ALine - 1 Then + Begin + Result := + LInsideScript And + (Pos('',LLine) = 0); + Exit; + End; + If Pos('',LLine) > 0 Then + LInsideScript := False; + End; +End; +Procedure TRESTDWHTMLDesignerForm.BuildDebugMarkImages; +Var + LBitmap : TBitmap; + I : Integer; +Begin + If Assigned(FDebugMarkImages) Then + Exit; + FDebugMarkImages := + TImageList.Create( + Self + ); + FDebugMarkImages.Width := 16; + FDebugMarkImages.Height := 16; + LBitmap := TBitmap.Create; + Try + LBitmap.Width := 16; + LBitmap.Height := 16; + For I := 0 To 8 Do + Begin + LBitmap.Canvas.Brush.Color := clFuchsia; + LBitmap.Canvas.FillRect(Rect(0,0,16,16)); + LBitmap.Canvas.Pen.Color := TColor($003030A0); + LBitmap.Canvas.Brush.Color := TColor($003838D8); + LBitmap.Canvas.Ellipse(2,2,14,14); + FDebugMarkImages.AddMasked( + LBitmap, + clFuchsia + ); + End; + LBitmap.Canvas.Brush.Color := clFuchsia; + LBitmap.Canvas.FillRect(Rect(0,0,16,16)); + LBitmap.Canvas.Pen.Color := TColor($00406020); + LBitmap.Canvas.Brush.Color := TColor($0060B040); + LBitmap.Canvas.Polygon([Point(3,2),Point(13,8),Point(3,14)]); + FDebugMarkImages.AddMasked( + LBitmap, + clFuchsia + ); + Finally + LBitmap.Free; + End; + FFullCode.BookMarkOptions.BookmarkImages := + FDebugMarkImages; + FJS.BookMarkOptions.BookmarkImages := + FDebugMarkImages; +End; +Procedure TRESTDWHTMLDesignerForm.SyncBreakpointMarks; +Var + I, + LLine, + LJSLine : Integer; +Begin + If Not Assigned(FFullCode) Then + Exit; + For I := 0 To 9 Do + Begin + FFullCode.ClearBookMark( + I + ); + If Assigned(FJS) Then + FJS.ClearBookMark( + I + ); + End; + For I := 0 To FDebugBreakpoints.Count - 1 Do + Begin + If I > 8 Then + Break; + LLine := + StrToIntDef( + FDebugBreakpoints[I], + 0 + ); + If (LLine > 0) And + (LLine <= FFullCode.Lines.Count) Then + Begin + FFullCode.SetBookMark( + I, + 1, + LLine + ); + If Assigned(FJS) Then + Begin + LJSLine := + FullCodeLineToJSLine( + LLine + ); + If LJSLine > 0 Then + FJS.SetBookMark( + I, + 1, + LJSLine + ); + End; + End; + End; + If FDebugPaused And + (FDebugCurrentLine > 0) And + (FDebugCurrentLine <= FFullCode.Lines.Count) Then + Begin + FFullCode.SetBookMark( + 9, + 1, + FDebugCurrentLine + ); + If Assigned(FJS) Then + Begin + LJSLine := + FullCodeLineToJSLine( + FDebugCurrentLine + ); + If LJSLine > 0 Then + FJS.SetBookMark( + 9, + 1, + LJSLine + ); + End; + End; +End; +Procedure TRESTDWHTMLDesignerForm.ToggleBreakpoint( + ALine : Integer); +Var + LIndex : Integer; +Begin + If (ALine < 1) Or + (ALine > FFullCode.Lines.Count) Then + Exit; + BuildDebugMarkImages; + LIndex := + BreakpointIndex( + ALine + ); + If LIndex >= 0 Then + FDebugBreakpoints.Delete( + LIndex + ) + Else + Begin + If FDebugBreakpoints.Count >= 9 Then + Begin + AddMessage( + 'Debug', + FCurrentFileName, + 'The visual editor supports up to 9 simultaneous breakpoints; the final gutter marker is reserved for the current debug line.', + ALine, + 1 + ); + Exit; + End; + FDebugBreakpoints.Add( + IntToStr(ALine) + ); + End; + SyncBreakpointMarks; + { Force an immediate gutter repaint, matching the visible Lazarus behavior. } + FFullCode.Invalidate; + If Assigned(FJS) Then + FJS.Invalidate; +End; +Procedure TRESTDWHTMLDesignerForm.CodeGutterClick( + Sender : TObject; + {$IFNDEF FPC}Button : TMouseButton;{$ENDIF} + X, Y, Line : Integer; + Mark : TSynEditMark); +{$IFDEF FPC} +Var + LLine : Integer; +{$ENDIF} +Begin + {$IFDEF FPC} + LLine := Line; + If Sender = FJS Then + LLine := JSLineToFullCodeLine(Line); + If LLine > 0 Then + ToggleBreakpoint(LLine); + {$ELSE} + { Single gutter clicks remain standard SynEdit behavior. + Native double-click is intercepted through WindowProc. } + {$ENDIF} +End; +Procedure TRESTDWHTMLDesignerForm.ToggleBreakpointClick( + Sender : TObject); +Var + LLine : Integer; +Begin + If FDesignMode Then + ShowCodeEditor; + If FCodePages.ActivePage = FJSTab Then + LLine := + JSLineToFullCodeLine( + FJS.CaretY + ) + Else + LLine := + FFullCode.CaretY; + If LLine > 0 Then + ToggleBreakpoint( + LLine + ); +End; +Function TRESTDWHTMLDesignerForm.BuildDebugPreviewHTML : String; +Var + LText : TStringList; + I, + LLine, + LSpaces : Integer; + LOriginal, + LTrimmed, + LDebuggerLine : String; +Begin + Result := + BuildPreviewHTML; + If FDebugBreakpoints.Count = 0 Then + Exit; + LText := TStringList.Create; + Try + LText.Text := Result; + { Insert from bottom to top so stored source line numbers stay stable. } + For I := FDebugBreakpoints.Count - 1 Downto 0 Do + Begin + LLine := + StrToIntDef( + FDebugBreakpoints[I], + 0 + ); + If (LLine < 1) Or + (LLine > LText.Count) Or + Not IsJavaScriptLine(LLine) Then + Continue; + LOriginal := + LText[LLine - 1]; + LTrimmed := + TrimLeft( + LOriginal + ); + LSpaces := + Length(LOriginal) - + Length(LTrimmed); + LDebuggerLine := + StringOfChar( + ' ', + LSpaces + ) + + 'try{window.chrome.webview.postMessage("RESTDWBREAK\t' + + IntToStr(LLine) + + '");}catch(e){} debugger; // REST Dataware breakpoint'; + LText.Insert( + LLine - 1, + LDebuggerLine + ); + End; + Result := + LText.Text; + Finally + LText.Free; + End; +End; +Procedure TRESTDWHTMLDesignerForm.UpdateDebugMenuState; +Begin + If Assigned(FDebugStartMenuItem) Then + FDebugStartMenuItem.Enabled := + (Not FDebugging) Or + FDebugPaused; + If Assigned(FDebugPauseMenuItem) Then + FDebugPauseMenuItem.Enabled := + FDebugging And + Not FDebugPaused; + If Assigned(FDebugStopMenuItem) Then + FDebugStopMenuItem.Enabled := + FDebugging; + If Assigned(FDebugRunToCursorMenuItem) Then + FDebugRunToCursorMenuItem.Enabled := + FDebugging And + FDebugPaused; + If Assigned(FDebugStepIntoMenuItem) Then + FDebugStepIntoMenuItem.Enabled := + FDebugging And + FDebugPaused; + If Assigned(FDebugStepOverMenuItem) Then + FDebugStepOverMenuItem.Enabled := + FDebugging And + FDebugPaused; + If Assigned(FDebugStepOutMenuItem) Then + FDebugStepOutMenuItem.Enabled := + FDebugging And + FDebugPaused; + If Assigned(FDebugEvaluateMenuItem) Then + FDebugEvaluateMenuItem.Enabled := + FDebugging And + FDebugPaused; + If Assigned(FDebugStartButton) Then + FDebugStartButton.Enabled := + (Not FDebugging) Or + FDebugPaused; + If Assigned(FDebugStopButton) Then + FDebugStopButton.Enabled := + FDebugging; +End; +Procedure TRESTDWHTMLDesignerForm.DebugStartClick( + Sender : TObject); +Begin + If FDebugging Then + Begin + If FDebugPaused And + Assigned(FWebView) Then + Begin + FDebugPaused := False; + FWebView.DebugResume; + UpdateDebugMenuState; + End; + Exit; + End; + If Not FDesignMode Then + ParseFullCodeToProducer + Else + SaveToProducer; + RebuildFullCode; + SyncBreakpointMarks; + ShowFormDesign; + FDebugging := True; + FDebugPaused := False; + FDebugCurrentLine := 0; + FPreviewTimer.Enabled := False; + If Assigned(FWebView) Then + Begin + FWebView.AssetsFolder := + ResolveEditorLibrariesPath; + FWebView.OnDebugBreakpoint := DebugBreakpointHit; + FWebView.OnDebugEvaluate := DebugEvaluateResult; + FWebView.EnableDebugger; + FWebView.HTML := + BuildDebugPreviewHTML; + End; + UpdateDebugMenuState; +End; +Procedure TRESTDWHTMLDesignerForm.DebugPauseClick( + Sender : TObject); +Begin + If Not FDebugging Or + FDebugPaused Or + Not Assigned(FWebView) Then + Exit; + FWebView.DebugPause; +End; +Procedure TRESTDWHTMLDesignerForm.DebugRunToCursorClick( + Sender : TObject); +Begin + If Not FDebugging Or + Not FDebugPaused Or + Not Assigned(FWebView) Then + Exit; + If Not IsJavaScriptLine( + FFullCode.CaretY + ) Then + Exit; + FDebugPaused := False; + SyncBreakpointMarks; + FWebView.DebugContinueToLine( + FFullCode.CaretY + ); + UpdateDebugMenuState; +End; +Procedure TRESTDWHTMLDesignerForm.DebugStopClick( + Sender : TObject); +Begin + If Assigned(FWebView) Then + Begin + If FDebugPaused Then + FWebView.DebugResume; + FWebView.DisableDebugger; + FWebView.OnDebugBreakpoint := Nil; + FWebView.OnDebugEvaluate := Nil; + End; + FDebugging := False; + FDebugPaused := False; + SyncBreakpointMarks; + FDebugCurrentLine := 0; + FPreviewTimer.Enabled := True; + If Assigned(FDebugHintForm) Then + FDebugHintForm.Hide; + UpdateDebugMenuState; + RefreshWebView; +End; +Procedure TRESTDWHTMLDesignerForm.DebugStepIntoClick( + Sender : TObject); +Begin + If FDebugging And + FDebugPaused And + Assigned(FWebView) Then + Begin + FDebugPaused := False; + SyncBreakpointMarks; + FWebView.DebugStepInto; + UpdateDebugMenuState; + End; +End; +Procedure TRESTDWHTMLDesignerForm.DebugStepOverClick( + Sender : TObject); +Begin + If FDebugging And + FDebugPaused And + Assigned(FWebView) Then + Begin + FDebugPaused := False; + SyncBreakpointMarks; + FWebView.DebugStepOver; + UpdateDebugMenuState; + End; +End; +Procedure TRESTDWHTMLDesignerForm.DebugStepOutClick( + Sender : TObject); +Begin + If FDebugging And + FDebugPaused And + Assigned(FWebView) Then + Begin + FDebugPaused := False; + SyncBreakpointMarks; + FWebView.DebugStepOut; + UpdateDebugMenuState; + End; +End; +Procedure TRESTDWHTMLDesignerForm.DebugEvaluateClick( + Sender : TObject); +Begin + If Not FDebugging Or + Not FDebugPaused Then + Exit; + ShowEvaluateDialog( + FDebugHoverExpression + ); +End; +Procedure TRESTDWHTMLDesignerForm.DebugClearBreakpointsClick( + Sender : TObject); +Begin + FDebugBreakpoints.Clear; + SyncBreakpointMarks; + If FDebugging Then + Begin + { Restart only the rendered debug page so the current list of injected + breakpoints exactly matches the editor. } + If Assigned(FWebView) Then + FWebView.HTML := + BuildDebugPreviewHTML; + End; +End; +Procedure TRESTDWHTMLDesignerForm.DebugReleaseAllBreakpointsClick( + Sender : TObject); +Begin + If FDebugging And + FDebugPaused And + Assigned(FWebView) Then + FWebView.DebugResume; + FDebugPaused := False; + FDebugBreakpoints.Clear; + SyncBreakpointMarks; + If Assigned(FWebView) Then + Begin + FWebView.DisableDebugger; + If FDebugging Then + Begin + FWebView.EnableDebugger; + FWebView.HTML := + BuildDebugPreviewHTML; + End; + End; + UpdateDebugMenuState; +End; +Procedure TRESTDWHTMLDesignerForm.DebugDevToolsClick( + Sender : TObject); +Begin + If Assigned(FWebView) Then + FWebView.OpenDevTools; +End; +Procedure TRESTDWHTMLDesignerForm.DebugBreakpointHit( + Sender : TObject; + ALine : Integer); +Begin + If Not FDebugging Then + Exit; + FDebugPaused := True; + If ALine > 0 Then + FDebugCurrentLine := ALine; + { A debugger stop belongs in source. Keep the WebView alive/paused in the + background and move the IDE work area to Full Code without rebuilding the + running page. } + FDesignMode := False; + FPreviewPanel.Visible := False; + FCodePages.Visible := True; + FCodePages.ActivePage := FFullCodeTab; + FCodeEditorButton.Down := True; + If (FDebugCurrentLine > 0) And + (FDebugCurrentLine <= FFullCode.Lines.Count) Then + Begin + FFullCode.CaretY := + FDebugCurrentLine; + FFullCode.CaretX := 1; + end; + SyncBreakpointMarks; + FFullCode.SetFocus; + UpdateDebugMenuState; +End; +Procedure TRESTDWHTMLDesignerForm.DebugEvaluateResult( + Sender : TObject; + ARequestID : Integer; + const AExpression, AValue, AError : String; + ASuccess : Boolean); +Var + LText : String; + LPoint : TPoint; +Begin + If ARequestID = FDebugHoverRequestID Then + Begin + If Not ASuccess Then + Exit; + LText := + AExpression + + ' = ' + + AValue; + FDebugHoverExpression := + AExpression; + If FDebugHintForm = Nil Then + Begin + FDebugHintForm := + TForm.CreateNew(Self); + FDebugHintForm.BorderStyle := bsNone; + FDebugHintForm.FormStyle := fsStayOnTop; + FDebugHintForm.AutoSize := True; + FDebugHintLabel := + TLabel.Create(FDebugHintForm); + FDebugHintLabel.Parent := + FDebugHintForm; + {$IFDEF FPC} + FDebugHintLabel.BorderSpacing.Around := 6; + {$ELSE} + FDebugHintLabel.Margins.SetBounds(6,6,6,6); + {$ENDIF} + FDebugHintLabel.OnDblClick := + DebugHintDblClick; + End; + FDebugHintLabel.Caption := + LText; + LPoint := + Mouse.CursorPos; + FDebugHintForm.Left := + LPoint.X + 12; + FDebugHintForm.Top := + LPoint.Y + 18; + FDebugHintForm.Show; + Exit; + End; + If (FDebugEvaluateForm <> Nil) And + (ARequestID = FDebugEvaluateRequestID) Then + Begin + If ASuccess Then + FDebugEvaluateValueLabel.Caption := + AValue + Else + FDebugEvaluateValueLabel.Caption := + AError; + End; +End; +Function TRESTDWHTMLDesignerForm.DebugExpressionAtMouse( + X, Y : Integer) : String; +Begin + Result := ''; + If Not FDebugging Or + Not FDebugPaused Then + Exit; + { SynEdit already resolves the lexical word under the current mouse + position. This keeps hover evaluation aligned with the code-editor + gutter/layout and avoids altering the caret just to inspect a value. } + Result := + Trim( + FFullCode.GetWordAtRowCol( + {$IFDEF FPC} + FFullCode.PixelsToRowColumn(Point(X,Y)) + {$ELSE} + FFullCode.DisplayToBufferPos( + FFullCode.PixelsToRowColumn(X,Y) + ) + {$ENDIF} + ) + ); +End; +Procedure TRESTDWHTMLDesignerForm.CodeEditorMouseMove( + Sender : TObject; + Shift : TShiftState; + X, Y : Integer); +Var + LExpression : String; +Begin + If Sender <> FFullCode Then + Exit; + If Not FDebugging Or + Not FDebugPaused Then + Begin + If Assigned(FDebugHintForm) Then + FDebugHintForm.Hide; + Exit; + End; + LExpression := + DebugExpressionAtMouse( + X, + Y + ); + If LExpression = '' Then + Begin + If Assigned(FDebugHintForm) Then + FDebugHintForm.Hide; + Exit; + End; + If SameText( + LExpression, + FDebugHoverExpression + ) And + Assigned(FDebugHintForm) And + FDebugHintForm.Visible Then + Exit; + FDebugHoverExpression := + LExpression; + Inc( + FDebugHoverRequestID + ); + If FDebugHoverRequestID < 1000 Then + FDebugHoverRequestID := 1000; + If Assigned(FWebView) Then + FWebView.EvaluateDebugExpression( + FDebugHoverRequestID, + LExpression + ); +End; +Procedure TRESTDWHTMLDesignerForm.CodeEditorDblClick( + Sender : TObject); +Begin + { Preserve normal source-text double-click behavior. } +End; +Procedure TRESTDWHTMLDesignerForm.InstallCodeWndProcHooks; +Begin + If FCodeWndProcHooked Then + Exit; + If Assigned(FFullCode) Then + Begin + FFullCodeOriginalWndProc := + FFullCode.WindowProc; + FFullCode.WindowProc := + FullCodeWndProc; + End; + If Assigned(FJS) Then + Begin + FJSOriginalWndProc := + FJS.WindowProc; + FJS.WindowProc := + JSCodeWndProc; + End; + FCodeWndProcHooked := True; +End; +Procedure TRESTDWHTMLDesignerForm.FullCodeWndProc( + {$IFDEF FPC}Var AMessage : TLMessage{$ELSE}Var AMessage : TMessage{$ENDIF}); +{$IFNDEF FPC} +Var + LMouse : TWMMouse; + LLine : Integer; +{$ENDIF} +Begin + {$IFNDEF FPC} + If AMessage.Msg = WM_LBUTTONDBLCLK Then + Begin + LMouse := TWMMouse(AMessage); + If (LMouse.XPos >= 0) And (LMouse.XPos < FFullCode.Gutter.Width) Then + Begin + LLine := FFullCode.DisplayToBufferPos(FFullCode.PixelsToRowColumn(LMouse.XPos,LMouse.YPos)).Line; + If LLine > 0 Then + Begin + ToggleBreakpoint(LLine); + AMessage.Result := 1; + Exit; + End; + End; + End; + {$ENDIF} + If Assigned(FFullCodeOriginalWndProc) Then + FFullCodeOriginalWndProc(AMessage); +End; +Procedure TRESTDWHTMLDesignerForm.JSCodeWndProc( + {$IFDEF FPC}Var AMessage : TLMessage{$ELSE}Var AMessage : TMessage{$ENDIF}); +{$IFNDEF FPC} +Var + LMouse : TWMMouse; + LLine, LFullLine : Integer; +{$ENDIF} +Begin + {$IFNDEF FPC} + If AMessage.Msg = WM_LBUTTONDBLCLK Then + Begin + LMouse := TWMMouse(AMessage); + If (LMouse.XPos >= 0) And (LMouse.XPos < FJS.Gutter.Width) Then + Begin + LLine := FJS.DisplayToBufferPos(FJS.PixelsToRowColumn(LMouse.XPos,LMouse.YPos)).Line; + If LLine > 0 Then + Begin + LFullLine := JSLineToFullCodeLine(LLine); + If LFullLine > 0 Then + Begin + ToggleBreakpoint(LFullLine); + AMessage.Result := 1; + Exit; + End; + End; + End; + End; + {$ENDIF} + If Assigned(FJSOriginalWndProc) Then + FJSOriginalWndProc(AMessage); +End; +Procedure TRESTDWHTMLDesignerForm.DebugHintDblClick( + Sender : TObject); +Begin + If Assigned(FDebugHintForm) Then + FDebugHintForm.Hide; + ShowEvaluateDialog( + FDebugHoverExpression + ); +End; +Procedure TRESTDWHTMLDesignerForm.ShowEvaluateDialog( + const AExpression : String); +Var + LExpressionLabel, + LValueTitle, + LNewValueLabel : TLabel; + LEvaluate, + LModify, + LClose : TButton; +Begin + If Not FDebugging Or + Not FDebugPaused Then + Exit; + If FDebugEvaluateForm <> Nil Then + Begin + FDebugEvaluateForm.BringToFront; + Exit; + End; + FDebugEvaluateForm := + TForm.CreateNew(Self); + Try + FDebugEvaluateForm.Caption := + 'Evaluate/Modify'; + FDebugEvaluateForm.SetBounds( + 0, + 0, + 520, + 245 + ); + FDebugEvaluateForm.Position := + poScreenCenter; + LExpressionLabel := + TLabel.Create( + FDebugEvaluateForm + ); + LExpressionLabel.Parent := + FDebugEvaluateForm; + LExpressionLabel.SetBounds( + 12, + 14, + 110, + 20 + ); + LExpressionLabel.Caption := + 'Expression:'; + FDebugEvaluateExpression := + TEdit.Create( + FDebugEvaluateForm + ); + FDebugEvaluateExpression.Parent := + FDebugEvaluateForm; + FDebugEvaluateExpression.SetBounds( + 12, + 35, + 490, + 25 + ); + FDebugEvaluateExpression.Text := + AExpression; + LValueTitle := + TLabel.Create( + FDebugEvaluateForm + ); + LValueTitle.Parent := + FDebugEvaluateForm; + LValueTitle.SetBounds( + 12, + 70, + 110, + 20 + ); + LValueTitle.Caption := + 'Current value:'; + FDebugEvaluateValueLabel := + TLabel.Create( + FDebugEvaluateForm + ); + FDebugEvaluateValueLabel.Parent := + FDebugEvaluateForm; + FDebugEvaluateValueLabel.SetBounds( + 12, + 92, + 490, + 24 + ); + FDebugEvaluateValueLabel.Caption := + ''; + LNewValueLabel := + TLabel.Create( + FDebugEvaluateForm + ); + LNewValueLabel.Parent := + FDebugEvaluateForm; + LNewValueLabel.SetBounds( + 12, + 122, + 110, + 20 + ); + LNewValueLabel.Caption := + 'New value:'; + FDebugEvaluateNewValue := + TEdit.Create( + FDebugEvaluateForm + ); + FDebugEvaluateNewValue.Parent := + FDebugEvaluateForm; + FDebugEvaluateNewValue.SetBounds( + 12, + 143, + 490, + 25 + ); + LEvaluate := + TButton.Create( + FDebugEvaluateForm + ); + LEvaluate.Parent := + FDebugEvaluateForm; + LEvaluate.SetBounds( + 12, + 185, + 100, + 28 + ); + LEvaluate.Caption := + 'Evaluate'; + LEvaluate.OnClick := + EvaluateDialogEvaluateClick; + LModify := + TButton.Create( + FDebugEvaluateForm + ); + LModify.Parent := + FDebugEvaluateForm; + LModify.SetBounds( + 122, + 185, + 100, + 28 + ); + LModify.Caption := + 'Modify'; + LModify.OnClick := + EvaluateDialogModifyClick; + LClose := + TButton.Create( + FDebugEvaluateForm + ); + LClose.Parent := + FDebugEvaluateForm; + LClose.SetBounds( + 402, + 185, + 100, + 28 + ); + LClose.Caption := + 'Close'; + LClose.ModalResult := + mrClose; + If Trim(AExpression) <> '' Then + EvaluateDialogEvaluateClick( + LEvaluate + ); + FDebugEvaluateForm.ShowModal; + Finally + FDebugEvaluateForm.Free; + FDebugEvaluateForm := Nil; + FDebugEvaluateExpression := Nil; + FDebugEvaluateValueLabel := Nil; + FDebugEvaluateNewValue := Nil; + End; +End; +Procedure TRESTDWHTMLDesignerForm.EvaluateDialogEvaluateClick( + Sender : TObject); +Begin + If (FDebugEvaluateForm = Nil) Or + Not Assigned(FWebView) Then + Exit; + Inc( + FDebugEvaluateRequestID + ); + FWebView.EvaluateDebugExpression( + FDebugEvaluateRequestID, + Trim( + FDebugEvaluateExpression.Text + ) + ); +End; +Procedure TRESTDWHTMLDesignerForm.EvaluateDialogModifyClick( + Sender : TObject); +Begin + If (FDebugEvaluateForm = Nil) Or + Not Assigned(FWebView) Then + Exit; + If Trim( + FDebugEvaluateExpression.Text + ) = '' Then + Exit; + If Trim( + FDebugEvaluateNewValue.Text + ) = '' Then + Exit; + Inc( + FDebugEvaluateRequestID + ); + FWebView.ModifyDebugExpression( + FDebugEvaluateRequestID, + Trim( + FDebugEvaluateExpression.Text + ), + Trim( + FDebugEvaluateNewValue.Text + ) + ); +End; +Procedure TRESTDWHTMLDesignerForm.InspectCodeAtCaret; +Var + LText, + LTag, + LTagName, + LTextValue, + LID, + LClass : String; + LCaretOffset, + I, + PStart, + PEnd, + PName, + PTextEnd : Integer; + Function Attr(const AName : String) : String; + Var + LLow, + LNeedle : String; + P1, + P2 : Integer; + Q : Char; + Begin + Result := ''; + LLow := LowerCase(LTag); + LNeedle := LowerCase(AName) + '='; + P1 := Pos(LNeedle,LLow); + If P1 = 0 Then + Exit; + Inc(P1,Length(LNeedle)); + While (P1 <= Length(LTag)) And + (LTag[P1] = ' ') Do + Inc(P1); + If P1 > Length(LTag) Then + Exit; + If (LTag[P1] = #39) Or + (LTag[P1] = '"') Then + Begin + Q := LTag[P1]; + Inc(P1); + P2 := P1; + While (P2 <= Length(LTag)) And + (LTag[P2] <> Q) Do + Inc(P2); + Result := Copy(LTag,P1,P2-P1); + End + Else + Begin + P2 := P1; + While (P2 <= Length(LTag)) And + (LTag[P2] > ' ') And + (LTag[P2] <> '>') Do + Inc(P2); + Result := Copy(LTag,P1,P2-P1); + End; + End; +Begin + If FDesignMode Then + Exit; + LText := FFullCode.Text; + If LText = '' Then + Exit; + LCaretOffset := 1; + For I := 0 To FFullCode.CaretY - 2 Do + Inc( + LCaretOffset, + Length(FFullCode.Lines[I]) + + Length(sLineBreak) + ); + Inc( + LCaretOffset, + FFullCode.CaretX - 1 + ); + If LCaretOffset > Length(LText) + 1 Then + LCaretOffset := Length(LText) + 1; + PStart := LCaretOffset - 1; + While (PStart > 0) And + (LText[PStart] <> '<') Do + Dec(PStart); + If PStart <= 0 Then + Exit; + PEnd := PStart; + While (PEnd <= Length(LText)) And + (LText[PEnd] <> '>') Do + Inc(PEnd); + If PEnd > Length(LText) Then + Exit; + LTag := Copy( + LText, + PStart, + PEnd-PStart+1 + ); + If (Length(LTag) < 3) Or + (Copy(LTag,1,2) = ' ' ') And + (LTag[I] <> '>') And + (LTag[I] <> '/') Do + Inc(I); + LTagName := Copy( + LTag, + PName, + I-PName + ); + If LTagName = '' Then + Exit; + LID := Attr('id'); + LClass := Attr('class'); + LTextValue := ''; + If PEnd < Length(LText) Then + Begin + PTextEnd := PEnd + 1; + While (PTextEnd <= Length(LText)) And + (LText[PTextEnd] <> '<') Do + Inc(PTextEnd); + LTextValue := Trim( + Copy( + LText, + PEnd + 1, + PTextEnd - PEnd - 1 + ) + ); + End; + FSelectedFromCode := True; + FSelectedCodeTagStart := PStart; + FSelectedCodeTagEnd := PEnd; + FSelectedElementID := 'code'; + FSelectedElementTag := LowerCase(LTagName); + SetDockPanelVisible( + 2, + True + ); + If FEditingEventCode Then + Begin + If FInspectorPages.PageCount > 1 Then + FInspectorPages.ActivePageIndex := 1; + End + Else + FInspectorPages.ActivePageIndex := 0; + InspectorSetElement( + 'code', + LTagName, + LTextValue, + LID, + LClass, + LTag + ); + { InspectorSetElement identifies a live DOM selection by default; + restore the source flag for code editing. } + FSelectedFromCode := True; + FSelectedCodeTagStart := PStart; + FSelectedCodeTagEnd := PEnd; +End; +Procedure TRESTDWHTMLDesignerForm.UpdateSelectedCodeElement( + const AProperty, AValue : String); +Var + LText, + LTag, + LNewTag, + LProperty, + LAttrName, + LLower, + LNeedle, + LBefore, + LAfter : String; + P, + PValueStart, + PValueEnd : Integer; + Q : Char; +Begin + If Not FSelectedFromCode Or + (FSelectedCodeTagStart <= 0) Or + (FSelectedCodeTagEnd < FSelectedCodeTagStart) Then + Exit; + LText := FFullCode.Text; + LTag := Copy( + LText, + FSelectedCodeTagStart, + FSelectedCodeTagEnd-FSelectedCodeTagStart+1 + ); + LNewTag := LTag; + LProperty := Trim(AProperty); + If SameText(LProperty,'Tag') Or + SameText(LProperty,'HTML') Then + Exit; + If SameText(LProperty,'Text') Then + Begin + P := FSelectedCodeTagEnd + 1; + While (P <= Length(LText)) And + (LText[P] <> '<') Do + Inc(P); + LBefore := Copy( + LText, + 1, + FSelectedCodeTagEnd + ); + LAfter := Copy( + LText, + P, + MaxInt + ); + FUpdating := True; + Try + FFullCode.Text := + LBefore + + AValue + + LAfter; + Finally + FUpdating := False; + End; + ParseFullCodeToProducer; + MarkModified; + RefreshWebView; + InspectCodeAtCaret; + Exit; + End; + If SameText(LProperty,'Class') Then + LAttrName := 'class' + Else If SameText(LProperty,'ID') Then + LAttrName := 'id' + Else If Pos('On',LProperty) = 1 Then + LAttrName := LowerCase(LProperty) + Else + LAttrName := LowerCase(LProperty); + LLower := LowerCase(LNewTag); + LNeedle := LAttrName + '='; + P := Pos(LNeedle,LLower); + If (P > 0) And + (AValue = '') Then + Begin + { Remove the complete attribute when its Object Inspector value is cleared. } + PValueStart := P; + While (PValueStart > 1) And + (LNewTag[PValueStart-1] = ' ') Do + Dec(PValueStart); + PValueEnd := P + Length(LNeedle); + While (PValueEnd <= Length(LNewTag)) And + (LNewTag[PValueEnd] = ' ') Do + Inc(PValueEnd); + If (PValueEnd <= Length(LNewTag)) And + ((LNewTag[PValueEnd] = #39) Or + (LNewTag[PValueEnd] = '"')) Then + Begin + Q := LNewTag[PValueEnd]; + Inc(PValueEnd); + While (PValueEnd <= Length(LNewTag)) And + (LNewTag[PValueEnd] <> Q) Do + Inc(PValueEnd); + If PValueEnd <= Length(LNewTag) Then + Inc(PValueEnd); + End + Else + While (PValueEnd <= Length(LNewTag)) And + (LNewTag[PValueEnd] > ' ') And + (LNewTag[PValueEnd] <> '>') Do + Inc(PValueEnd); + Delete( + LNewTag, + PValueStart, + PValueEnd-PValueStart + ); + End + Else If P > 0 Then + Begin + PValueStart := P + Length(LNeedle); + While (PValueStart <= Length(LNewTag)) And + (LNewTag[PValueStart] = ' ') Do + Inc(PValueStart); + If (PValueStart <= Length(LNewTag)) And + ((LNewTag[PValueStart] = #39) Or + (LNewTag[PValueStart] = '"')) Then + Begin + Q := LNewTag[PValueStart]; + Inc(PValueStart); + PValueEnd := PValueStart; + While (PValueEnd <= Length(LNewTag)) And + (LNewTag[PValueEnd] <> Q) Do + Inc(PValueEnd); + Delete( + LNewTag, + PValueStart, + PValueEnd-PValueStart + ); + Insert( + AValue, + LNewTag, + PValueStart + ); + End + Else + Begin + PValueEnd := PValueStart; + While (PValueEnd <= Length(LNewTag)) And + (LNewTag[PValueEnd] > ' ') And + (LNewTag[PValueEnd] <> '>') Do + Inc(PValueEnd); + Delete( + LNewTag, + PValueStart, + PValueEnd-PValueStart + ); + Insert( + AValue, + LNewTag, + PValueStart + ); + End; + End + Else If AValue <> '' Then + Begin + P := Length(LNewTag); + If (P > 1) And + (LNewTag[P-1] = '/') Then + Dec(P); + Insert( + ' ' + LAttrName + '="' + AValue + '"', + LNewTag, + P + ); + End; + LBefore := Copy( + LText, + 1, + FSelectedCodeTagStart-1 + ); + LAfter := Copy( + LText, + FSelectedCodeTagEnd+1, + MaxInt + ); + FUpdating := True; + Try + FFullCode.Text := + LBefore + + LNewTag + + LAfter; + Finally + FUpdating := False; + End; + FSelectedCodeTagEnd := + FSelectedCodeTagStart + + Length(LNewTag) - 1; + ParseFullCodeToProducer; + MarkModified; + RefreshWebView; + InspectCodeAtCaret; +End; +Procedure TRESTDWHTMLDesignerForm.PreviewTimerTimer( + Sender : TObject); +Begin + FPreviewTimer.Enabled := False; + If Not FDesignMode And + (FCodePages.ActivePage = FFullCodeTab) Then + ParseFullCodeToProducer + Else + SaveToProducer; + ValidateDocument; + BuildProjectExplorer; + RefreshWebView; +End; +Procedure TRESTDWHTMLDesignerForm.SaveToProducer; +Begin If FUpdating Then Exit; FProducer.HTML.Assign(FHTML.Lines); FProducer.CSS.Assign(FCSS.Lines); FProducer.JavaScript.Assign(FJS.Lines); End; +Procedure TRESTDWHTMLDesignerForm.RebuildFullCode; +Begin FUpdating:=True; Try SaveToProducer; FFullCode.Text:=FProducer.Produce; Finally FUpdating:=False; End; End; +Function TRESTDWHTMLDesignerForm.ExtractBetween(const AText,AStart,AEnd:String):String; +Var P1,P2:Integer; +Begin Result:=''; P1:=Pos(LowerCase(AStart),LowerCase(AText)); If P1=0 Then Exit; Inc(P1,Length(AStart)); P2:=PosEx(LowerCase(AEnd),LowerCase(AText),P1); If P2=0 Then Exit; Result:=Copy(AText,P1,P2-P1); End; +Procedure TRESTDWHTMLDesignerForm.ParseFullCodeToProducer; +Var T,B,C,J:String; P1,P2:Integer; +Begin + T:=FFullCode.Text; B:=ExtractBetween(T,'',''); C:=ExtractBetween(T,''); + P1:=RESTDWRPos('',LowerCase(T)); J:=''; If (P1>0) And (P2>P1) Then J:=Copy(T,P1+8,P2-(P1+8)); + { remove generated external script tags from body } + P1:=Pos(''; +End; +Procedure TRESTDWHTMLDesignerForm.RefreshClick( + Sender : TObject); +Begin + RefreshWebView; +End; +Procedure TRESTDWHTMLDesignerForm.HelpClick( + Sender : TObject); +Var + LHelpDir, + LHelpFile : String; + LText : TStringList; +Begin + LHelpDir := + IncludeTrailingPathDelimiter( + ResolveEditorLibrariesPath + ) + + 'help'; + If Not DirectoryExists(LHelpDir) Then + ForceDirectories(LHelpDir); + LHelpFile := + IncludeTrailingPathDelimiter( + LHelpDir + ) + + 'index.html'; + LText := TStringList.Create; + Try + LText.Text := + BuildHelpHTML; + LText.SaveToFile( + LHelpFile + ); + Finally + LText.Free; + End; + If Not RESTDWOpenDocument(LHelpFile) Then + MessageDlg( + HelpLang('OpenError') + LHelpFile, + mtError, + [mbOK], + 0 + ); +End; +Procedure TRESTDWHTMLDesignerForm.SaveClick( + Sender : TObject); +Begin + SaveDocument; +End; +Procedure TRESTDWHTMLDesignerForm.PositionCode( + const ASearchText : String; + ASwitchToCode : Boolean); +Var + P, + LineNo, + ColNo, + I : Integer; + TextAll : String; +Begin + If Trim(ASearchText) = '' Then + Exit; + If ASwitchToCode Then + ShowCodeEditor; + TextAll := FFullCode.Text; + P := Pos( + LowerCase(ASearchText), + LowerCase(TextAll) + ); + If P = 0 Then + Exit; + LineNo := 1; + ColNo := 1; + For I := 1 To P - 1 Do + Begin + If TextAll[I] = #10 Then + Begin + Inc(LineNo); + ColNo := 1; + End + Else If TextAll[I] <> #13 Then + Inc(ColNo); + End; + {$IFDEF FPC} + FFullCode.CaretXY := Point(ColNo,LineNo); + {$ELSE} + FFullCode.CaretXY := BufferCoord(ColNo,LineNo); + {$ENDIF} + FFullCode.BlockBegin := FFullCode.CaretXY; + FFullCode.BlockEnd := FFullCode.CaretXY; + If ASwitchToCode Then + FFullCode.SetFocus; +End; +Procedure TRESTDWHTMLDesignerForm.PositionElementCode( + const ATagName, AText, AID, AClassName, AOuterHTML : String; + ASwitchToCode : Boolean); +Var + LSearch, + LTag, + LClassToken : String; + P : Integer; +Begin + LSearch := Trim(AOuterHTML); + { Prefer exact outer HTML. } + If (LSearch <> '') And + (Pos(LowerCase(LSearch),LowerCase(FProducer.Produce)) > 0) Then + Begin + PositionCode( + LSearch, + ASwitchToCode + ); + Exit; + End; + { ID is the most reliable fallback. } + If Trim(AID) <> '' Then + Begin + LSearch := 'id="' + AID + '"'; + If Pos(LowerCase(LSearch),LowerCase(FProducer.Produce)) > 0 Then + Begin + PositionCode( + LSearch, + ASwitchToCode + ); + Exit; + End; + LSearch := 'id=''' + AID + ''''; + If Pos(LowerCase(LSearch),LowerCase(FProducer.Produce)) > 0 Then + Begin + PositionCode( + LSearch, + ASwitchToCode + ); + Exit; + End; + End; + { First class token is another stable fallback. } + LClassToken := Trim(AClassName); + P := Pos(' ',LClassToken); + If P > 0 Then + LClassToken := Copy(LClassToken,1,P-1); + If LClassToken <> '' Then + Begin + LSearch := 'class="' + LClassToken; + If Pos(LowerCase(LSearch),LowerCase(FProducer.Produce)) > 0 Then + Begin + PositionCode( + LSearch, + ASwitchToCode + ); + Exit; + End; + End; + { Last fallback uses visible text only. A generic ' '' Then + Begin + LSearch := Copy(Trim(AText),1,40); + If Pos( + LowerCase(LSearch), + LowerCase(FProducer.Produce) + ) > 0 Then + PositionCode( + LSearch, + ASwitchToCode + ); + End; +End; +Procedure TRESTDWHTMLDesignerForm.NavigateCode( + const ASearchText : String); +Begin + PositionCode( + ASearchText, + True + ); +End; +Procedure TRESTDWHTMLDesignerForm.ProjectTreeClick( + Sender : TObject); +Var + LNode : TTreeNode; + LInfo : TRESTDWHTMLProjectNodeInfo; + LSearchText : String; +Begin + LNode := FProjectTree.Selected; + If LNode = Nil Then + Exit; + { Copy navigation text BEFORE changing to Code Editor. ShowCodeEditor rebuilds + the Project Explorer and therefore frees/recreates TRESTDWHTMLProjectNodeInfo. A + const reference directly to LInfo.SearchText would otherwise point to the + old freed node data and navigation could fall back to the beginning. } + LSearchText := ''; + If LNode.Data <> Nil Then + Begin + LInfo := + TRESTDWHTMLProjectNodeInfo( + LNode.Data + ); + LSearchText := + LInfo.SearchText; + End; + If SameText( + LNode.Text, + Lang('PageOptions') + ) Then + Begin + InspectorSetPageOptions; + SetDockPanelVisible( + 2, + True + ); + If LSearchText = '' Then + LSearchText := ''; + NavigateCode( + LSearchText + ); + Exit; + End; + If LSearchText <> '' Then + Begin + NavigateCode( + LSearchText + ); + Exit; + End; + { Structural nodes navigate to their equivalent source section without + changing the user's expanded/collapsed tree state. } + If SameText(LNode.Text,'HTML') Then + NavigateCode(''); +End; +Procedure TRESTDWHTMLDesignerForm.ClearMessages; +Begin + FMessages.RowCount := 1; +End; +Procedure TRESTDWHTMLDesignerForm.AddMessage( + const AKind, + AFile, + AText : String; + ALine, + AColumn : Integer); +Var + R : Integer; +Begin + R := FMessages.RowCount; + FMessages.RowCount := R + 1; + FMessages.Cells[0,R] := AKind; + FMessages.Cells[1,R] := AFile; + FMessages.Cells[2,R] := IntToStr(ALine); + FMessages.Cells[3,R] := IntToStr(AColumn); + FMessages.Cells[4,R] := AText; +End; +Procedure TRESTDWHTMLDesignerForm.ValidateDocument; +Var + T : String; +Begin + ClearMessages; + T := LowerCase(FProducer.Produce); + If Pos(' element', + 1, + 1 + ); + If Pos(' element', + 1, + 1 + ); + If Pos('',T) = 0 Then + AddMessage( + 'Error', + 'Full Page', + 'Missing ', + 1, + 1 + ); +End; +Function TRESTDWHTMLDesignerForm.ActiveMemo : TSynEdit; +Begin + Result := Nil; + If Not FDesignMode Then + Begin + If FCodePages.ActivePage = FFullCodeTab Then + Result := FFullCode + Else If FCodePages.ActivePage = FHTMLTab Then + Result := FHTML + Else If FCodePages.ActivePage = FCSSTab Then + Result := FCSS + Else If FCodePages.ActivePage = FJSTab Then + Result := FJS; + End; +End; +Procedure TRESTDWHTMLDesignerForm.FindClick(Sender:TObject); +Var + S : String; + M : TSynEdit; + P, + StartOffset, + LineNo, + ColNo, + I, + L : Integer; + TextAll : String; +Begin + M := ActiveMemo; + If M = Nil Then + Exit; + S := ''; + If Not InputQuery('Find','Text:',S) Then + Exit; + TextAll := M.Text; + StartOffset := 1; + { Convert current caret to a character offset without SelStart/SelLength. } + For I := 0 To M.CaretY - 2 Do + Inc(StartOffset,Length(M.Lines[I]) + Length(sLineBreak)); + Inc(StartOffset,M.CaretX - 1); + P := Pos( + LowerCase(S), + LowerCase(Copy(TextAll,StartOffset,MaxInt)) + ); + If P = 0 Then + Exit; + P := StartOffset + P - 1; + LineNo := 1; + ColNo := 1; + For I := 1 To P - 1 Do + Begin + If TextAll[I] = #10 Then + Begin + Inc(LineNo); + ColNo := 1; + End + Else If TextAll[I] <> #13 Then + Inc(ColNo); + End; + {$IFDEF FPC} + M.BlockBegin := Point(ColNo,LineNo); + {$ELSE} + M.BlockBegin := BufferCoord(ColNo,LineNo); + {$ENDIF} + L := Length(S); + For I := 1 To L Do + Begin + If (P + I - 1 <= Length(TextAll)) And + (TextAll[P + I - 1] = #10) Then + Begin + Inc(LineNo); + ColNo := 1; + End + Else If (P + I - 1 <= Length(TextAll)) And + (TextAll[P + I - 1] <> #13) Then + Inc(ColNo); + End; + {$IFDEF FPC} + M.BlockEnd := Point(ColNo,LineNo); + {$ELSE} + M.BlockEnd := BufferCoord(ColNo,LineNo); + {$ENDIF} + M.CaretXY := M.BlockEnd; + M.SetFocus; +End; +Procedure TRESTDWHTMLDesignerForm.ReplaceClick(Sender:TObject); Var A,B:String; M:TSynEdit; +Begin M:=ActiveMemo; If M=Nil Then Exit; A:='';B:=''; If InputQuery('Replace','Find:',A) And InputQuery('Replace','Replace with:',B) Then M.Text:=StringReplace(M.Text,A,B,[rfReplaceAll]); End; +Procedure TRESTDWHTMLDesignerForm.UndoClick(Sender:TObject); Begin If ActiveMemo<>Nil Then ActiveMemo.Undo; End; +Procedure TRESTDWHTMLDesignerForm.CutClick(Sender:TObject); Begin If ActiveMemo<>Nil Then ActiveMemo.CutToClipboard; End; +Procedure TRESTDWHTMLDesignerForm.CopyClick(Sender:TObject); Begin If ActiveMemo<>Nil Then ActiveMemo.CopyToClipboard; End; +Procedure TRESTDWHTMLDesignerForm.PasteClick(Sender:TObject); Begin If ActiveMemo<>Nil Then ActiveMemo.PasteFromClipboard; End; +Function TRESTDWHTMLDesignerForm.ComponentInstanceBaseName( + AInfo : TRESTDWHTMLWebComponentInfo) : String; +Var + LSource : String; + I : Integer; + C : Char; +Begin + Result := ''; + If AInfo = Nil Then + Exit; + LSource := Trim(AInfo.ClassName); + If LSource = '' Then + LSource := Trim(AInfo.Name); + For I := 1 To Length(LSource) Do + Begin + C := LSource[I]; + If C In ['A'..'Z','a'..'z','0'..'9','_'] Then + Result := Result + C; + End; + If Result = '' Then + Result := 'TComponent'; + If Not (Result[1] In ['A'..'Z','a'..'z','_']) Then + Result := 'T' + Result; + If (AInfo.ClassName = AInfo.Name) And + (UpCase(Result[1]) <> 'T') Then + Result := 'T' + Result; +End; +Function TRESTDWHTMLDesignerForm.NextComponentInstanceName( + const ABaseName : String) : String; +Var + LAll, + LCandidate, + LNeedleID1, + LNeedleID2, + LNeedleName1, + LNeedleName2 : String; + N : Integer; +Begin + LAll := + LowerCase( + FProducer.HTML.Text + + sLineBreak + + FHTML.Text + + sLineBreak + + FFullCode.Text + ); + N := 1; + Repeat + LCandidate := + ABaseName + + IntToStr(N); + LNeedleID1 := + 'id="' + + LowerCase(LCandidate) + + '"'; + LNeedleID2 := + 'id=''' + + LowerCase(LCandidate) + + ''''; + LNeedleName1 := + 'name="' + + LowerCase(LCandidate) + + '"'; + LNeedleName2 := + 'name=''' + + LowerCase(LCandidate) + + ''''; + If (Pos(LNeedleID1,LAll) = 0) And + (Pos(LNeedleID2,LAll) = 0) And + (Pos(LNeedleName1,LAll) = 0) And + (Pos(LNeedleName2,LAll) = 0) And + (FGeneratedInstanceNames.IndexOf(LCandidate) < 0) Then + Begin + FGeneratedInstanceNames.Add( + LCandidate + ); + Result := LCandidate; + Exit; + End; + Inc(N); + Until N = MaxInt; + Result := + ABaseName + + IntToStr(N); +End; +Function TRESTDWHTMLDesignerForm.ApplyComponentIdentity( + const AHTML, + AIdentity : String) : String; +Var + LOpenEnd, + LTagStart, + LPos : Integer; + LTag, + LTail, + LLower : String; + Procedure ReplaceAttribute( + const AAttribute : String); + Var + P, + V1, + V2 : Integer; + Quote : Char; + Prefix, + Suffix : String; + Begin + LLower := LowerCase(LTag); + P := + Pos( + LowerCase(AAttribute) + '=', + LLower + ); + If P > 0 Then + Begin + V1 := + P + + Length(AAttribute) + + 1; + If V1 <= Length(LTag) Then + Begin + Quote := LTag[V1]; + If (Quote = '''') Or + (Quote = '"') Then + Begin + V2 := V1 + 1; + While (V2 <= Length(LTag)) And + (LTag[V2] <> Quote) Do + Inc(V2); + If V2 <= Length(LTag) Then + Begin + Prefix := Copy(LTag,1,V1); + Suffix := Copy(LTag,V2,MaxInt); + LTag := + Prefix + + AIdentity + + Suffix; + Exit; + End; + End; + End; + End; + If (Length(LTag) > 0) And + (LTag[Length(LTag)] = '>') Then + Begin + If (Length(LTag) > 1) And + (LTag[Length(LTag) - 1] = '/') Then + Insert( + ' ' + + AAttribute + + '="' + + AIdentity + + '"', + LTag, + Length(LTag) - 1 + ) + Else + Insert( + ' ' + + AAttribute + + '="' + + AIdentity + + '"', + LTag, + Length(LTag) + ); + End; + End; +Begin + Result := AHTML; + LTagStart := + Pos( + '<', + Result + ); + While (LTagStart > 0) And + (LTagStart < Length(Result)) And + (Result[LTagStart + 1] In ['!','?','/']) Do + Begin + LPos := + PosEx( + '<', + Result, + LTagStart + 1 + ); + If LPos = 0 Then + Exit; + LTagStart := LPos; + End; + If LTagStart = 0 Then + Exit; + LOpenEnd := + PosEx( + '>', + Result, + LTagStart + 1 + ); + If LOpenEnd = 0 Then + Exit; + LTag := + Copy( + Result, + LTagStart, + LOpenEnd - LTagStart + 1 + ); + LTail := + Copy( + Result, + LOpenEnd + 1, + MaxInt + ); + ReplaceAttribute( + 'id' + ); + ReplaceAttribute( + 'name' + ); + Result := + Copy( + Result, + 1, + LTagStart - 1 + ) + + LTag + + LTail; +End; +Function TRESTDWHTMLDesignerForm.ComponentInstanceHTML( + AInfo : TRESTDWHTMLWebComponentInfo) : String; +Var + LBase, + LIdentity : String; +Begin + Result := ''; + If AInfo = Nil Then + Exit; + LBase := + ComponentInstanceBaseName( + AInfo + ); + LIdentity := + NextComponentInstanceName( + LBase + ); + Result := + ApplyComponentIdentity( + ComponentHTML(AInfo.Name), + LIdentity + ); +End; +Function TRESTDWHTMLDesignerForm.ComponentJSClassSource( + AInfo : TRESTDWHTMLWebComponentInfo) : String; +Var + LFileName : String; + L : TStringList; +Begin + Result := ''; + If (AInfo = Nil) Or + (Trim(AInfo.JsFileName) = '') Then + Exit; + LFileName := AInfo.JsFileName; + If Not FileExists(LFileName) Then + LFileName := + IncludeTrailingPathDelimiter( + RESTDWHTMLComponentsPath( + ResolveEditorLibrariesPath + ) + ) + + AInfo.JsFileName; + If Not FileExists(LFileName) Then + Exit; + L := TStringList.Create; + Try + L.LoadFromFile(LFileName); + Result := L.Text; + Finally + L.Free; + End; +End; + +Function TRESTDWHTMLDesignerForm.ComponentOptionsJSON( + AInfo : TRESTDWHTMLWebComponentInfo) : String; +Var + I : Integer; + LName, + LValue : String; + Function EscapeJSON(const AValue : String) : String; + Begin + Result := StringReplace(AValue,'\','\\',[rfReplaceAll]); + Result := StringReplace(Result,'"','\"',[rfReplaceAll]); + Result := StringReplace(Result,#13,'\r',[rfReplaceAll]); + Result := StringReplace(Result,#10,'\n',[rfReplaceAll]); + End; +Begin + Result := '{'; + If (AInfo <> Nil) And + (AInfo.Options <> Nil) Then + For I := 0 To AInfo.Options.Count - 1 Do + Begin + LName := Trim(AInfo.Options.Names[I]); + If LName = '' Then + Continue; + LValue := AInfo.Options.ValueFromIndex[I]; + If Length(Result) > 1 Then + Result := Result + ','; + Result := + Result + + '"' + EscapeJSON(LName) + '":"' + + EscapeJSON(LValue) + '"'; + End; + Result := Result + '}'; +End; + +Procedure TRESTDWHTMLDesignerForm.InsertVisualComponent( + AInfo : TRESTDWHTMLWebComponentInfo; + X, Y : Integer; + AAtPoint : Boolean); +Var + LBase, + LIdentity, + LSource, + LExtra, + LLibrary, + LFallback : String; +Begin + If (AInfo = Nil) Or + Not Assigned(FWebView) Or + Not FWebView.Ready Then + Exit; + LBase := ComponentInstanceBaseName(AInfo); + LIdentity := NextComponentInstanceName(LBase); + LSource := ComponentJSClassSource(AInfo); + LExtra := AInfo.HTMLExtension; + LLibrary := ComponentLibraryHTML(AInfo); + If Trim(LLibrary) <> '' Then + Begin + If LExtra <> '' Then + LExtra := LExtra + sLineBreak; + LExtra := LExtra + LLibrary; + End; + If Trim(LSource) <> '' Then + Begin + If AAtPoint Then + FWebView.InsertJSClassAt( + LSource, + AInfo.ClassName, + ComponentOptionsJSON(AInfo), + LExtra, + LIdentity, + X, + Y + ) + Else + FWebView.InsertJSClass( + LSource, + AInfo.ClassName, + ComponentOptionsJSON(AInfo), + LExtra, + LIdentity + ); + End + Else + Begin + LFallback := + ApplyComponentIdentity( + ComponentHTML(AInfo.Name), + LIdentity + ); + If AAtPoint Then + FWebView.InsertHTMLAt(LFallback,X,Y) + Else + FWebView.InsertHTML(LFallback); + End; +End; + +Function TRESTDWHTMLDesignerForm.ApplyComponentOptions( + AInfo : TRESTDWHTMLWebComponentInfo; + const AHTML : String) : String; +Var + I : Integer; + LName, + LValue, + LAttrName, + LOpenEnd : String; + P : Integer; +Begin + Result := AHTML; + If (AInfo = Nil) Or + (AInfo.Options = Nil) Then + Exit; + For I := 0 To AInfo.Options.Count - 1 Do + Begin + LName := + Trim( + AInfo.Options.Names[I] + ); + LValue := + AInfo.Options.ValueFromIndex[I]; + If LName = '' Then + Continue; + { Template placeholders allow component authors to decide exactly where + an option is consumed by their HTML. } + Result := + StringReplace( + Result, + '{{' + LName + '}}', + LValue, + [rfReplaceAll,rfIgnoreCase] + ); + Result := + StringReplace( + Result, + '%' + LName + '%', + LValue, + [rfReplaceAll,rfIgnoreCase] + ); + { Also expose every configured option as a data attribute on the root + element, giving the local/external JS library a generic access path. } + LAttrName := + LowerCase( + StringReplace( + LName, + '_', + '-', + [rfReplaceAll] + ) + ); + P := + Pos( + '>', + Result + ); + If P > 0 Then + Begin + LOpenEnd := + ' data-laz-' + + LAttrName + + '="' + + StringReplace( + LValue, + '"', + '"', + [rfReplaceAll] + ) + + '"'; + Insert( + LOpenEnd, + Result, + P + ); + End; + End; +End; +Function TRESTDWHTMLDesignerForm.ComponentLibraryHTML( + AInfo : TRESTDWHTMLWebComponentInfo) : String; +Var + LSource, + LProjectDir, + LDest, + LClassFolder : String; +Begin + Result := ''; + If (AInfo = Nil) Or + (Trim(AInfo.FileName) = '') Then + Exit; + LClassFolder := + Trim( + AInfo.ClassName + ); + If LClassFolder = '' Then + LClassFolder := AInfo.Name; + If (FProducer.LibraryMode = lmURL) And + (Trim(AInfo.ExternalURL) <> '') Then + Begin + LSource := + Trim( + AInfo.ExternalURL + ); + While (Length(LSource) > 0) And + (LSource[Length(LSource)] = '/') Do + Delete( + LSource, + Length(LSource), + 1 + ); + LSource := + LSource + + '/' + + AInfo.FileName; + End + Else + Begin + {$IFDEF Windows} + LSource := + '.\html\libs\' + + LClassFolder + + '\' + + AInfo.FileName; + {$ELSE} + LSource := + './html/libs/' + + LClassFolder + + '/' + + AInfo.FileName; + {$ENDIF} + If (Trim(AInfo.LocalLibPath) <> '') And + DirectoryExists(AInfo.LocalLibPath) And + (RESTDWActiveProjectDir <> '') Then + Begin + LProjectDir := + RESTDWActiveProjectDir; + LDest := + IncludeTrailingPathDelimiter(LProjectDir) + + 'html' + + PathDelim + + 'libs' + + PathDelim + + LClassFolder; + ForceDirectories( + LDest + ); + RESTDWCopyDirTree(AInfo.LocalLibPath,LDest); + End; + End; + If SameText( + ExtractFileExt(AInfo.FileName), + '.css' + ) Then + Result := + '' + Else + Result := + ''; +End; +Function TRESTDWHTMLDesignerForm.ComponentHTML( + const AName : String) : String; +Var + I : Integer; + Info : TRESTDWHTMLWebComponentInfo; + LLibraryHTML : String; +Begin + Result := ''; + For I := 0 To FComponents.Count - 1 Do + Begin + Info := + TRESTDWHTMLWebComponentInfo( + FComponents[I] + ); + If SameText( + Info.Name, + AName + ) Then + Begin + Result := + ApplyComponentOptions( + Info, + Info.HTML + ); + LLibraryHTML := + ComponentLibraryHTML( + Info + ); + If Trim(LLibraryHTML) <> '' Then + Result := + Result + + sLineBreak + + LLibraryHTML; + Exit; + End; + End; +End; +Function TRESTDWHTMLDesignerForm.ResolveEditorLibrariesPath : String; +Var + LConfigured, + LProjectDir, + LModuleDir, + LCandidate : String; + {$IFDEF FPC} + LSourceDir : String; + {$ENDIF} + Function HasPackages(const APath : String) : Boolean; + Var + LSearch : TSearchRec; + Begin + Result := False; + If Not DirectoryExists(APath) Then Exit; + If FindFirst( + IncludeTrailingPathDelimiter(APath) + + 'Packages' + PathDelim + '*.ini', + faAnyFile,LSearch)=0 Then + Begin + Result := True; + FindClose(LSearch); + End; + End; + Function SearchFrom(const AStartDir : String) : String; + Var + LBase, + LParent, + LTry : String; + I : Integer; + Begin + Result := ''; + If Trim(AStartDir) = '' Then Exit; + LBase := ExpandFileName(AStartDir); + For I := 0 To 12 Do + Begin + {$IFDEF FPC} + LTry := IncludeTrailingPathDelimiter(LBase) + + 'Packages' + PathDelim + 'Lazarus' + PathDelim + + 'html' + PathDelim + 'libs'; + If HasPackages(LTry) Then Begin Result := ExpandFileName(LTry); Exit; End; + {$ENDIF} + LTry := IncludeTrailingPathDelimiter(LBase) + + 'Source' + PathDelim + 'Includes' + PathDelim + + 'HTMLEditor' + PathDelim + 'libs' + PathDelim + 'editor'; + If HasPackages(LTry) Then Begin Result := ExpandFileName(LTry); Exit; End; + LTry := IncludeTrailingPathDelimiter(LBase) + + 'Source' + PathDelim + 'Includes' + PathDelim + + 'HTMLEditor' + PathDelim + 'editor'; + If HasPackages(LTry) Then Begin Result := ExpandFileName(LTry); Exit; End; + LTry := IncludeTrailingPathDelimiter(LBase) + + 'libs' + PathDelim + 'editor'; + If HasPackages(LTry) Then Begin Result := ExpandFileName(LTry); Exit; End; + {$IFNDEF FPC} + LTry := IncludeTrailingPathDelimiter(LBase) + + 'Packages' + PathDelim + 'Delphi' + PathDelim + + 'html' + PathDelim + 'libs'; + If HasPackages(LTry) Then Begin Result := ExpandFileName(LTry); Exit; End; + {$ENDIF} + LTry := IncludeTrailingPathDelimiter(LBase) + + 'html' + PathDelim + 'libs'; + If HasPackages(LTry) Then Begin Result := ExpandFileName(LTry); Exit; End; + LParent := ExcludeTrailingPathDelimiter(ExtractFileDir(LBase)); + If (LParent = '') Or SameText(LParent,LBase) Then Break; + LBase := LParent; + End; + End; + {$IFNDEF FPC} + Function SearchDelphiLibraryPaths : String; + Var + LRegistry : TRegistry; + LVersions, + LPaths : TStringList; + LVersion, + LValue, + LPath, + LFound : String; + I, + J : Integer; + Procedure SearchValue(const AKey,AValue : String); + Var + K : Integer; + Begin + If Result <> '' Then Exit; + If Not LRegistry.OpenKeyReadOnly(AKey) Then Exit; + Try + If Not LRegistry.ValueExists(AValue) Then Exit; + LValue := LRegistry.ReadString(AValue); + Finally + LRegistry.CloseKey; + End; + LPaths.StrictDelimiter := True; + LPaths.Delimiter := ';'; + LPaths.DelimitedText := LValue; + For K := 0 To LPaths.Count - 1 Do + Begin + LPath := Trim(LPaths[K]); + If LPath = '' Then Continue; + LPath := StringReplace(LPath,'$(BDS)',GetEnvironmentVariable('BDS'),[rfReplaceAll,rfIgnoreCase]); + LPath := StringReplace(LPath,'$(BDSCOMMONDIR)',GetEnvironmentVariable('BDSCOMMONDIR'),[rfReplaceAll,rfIgnoreCase]); + If Pos('$(',LPath) > 0 Then Continue; + LFound := SearchFrom(LPath); + If LFound <> '' Then + Begin + Result := LFound; + Exit; + End; + End; + End; + Begin + Result := ''; + LRegistry := TRegistry.Create(KEY_READ); + LVersions := TStringList.Create; + LPaths := TStringList.Create; + Try + LRegistry.RootKey := HKEY_CURRENT_USER; + If LRegistry.OpenKeyReadOnly('\Software\Embarcadero\BDS') Then + Begin + LRegistry.GetKeyNames(LVersions); + LRegistry.CloseKey; + End; + For I := LVersions.Count - 1 DownTo 0 Do + Begin + LVersion := LVersions[I]; + For J := 0 To 1 Do + Begin + If J = 0 Then + SearchValue('\Software\Embarcadero\BDS\' + LVersion + '\Library\Win32','Search Path') + Else + SearchValue('\Software\Embarcadero\BDS\' + LVersion + '\Library\Win32','Browsing Path'); + If Result <> '' Then Exit; + End; + End; + Finally + LPaths.Free; + LVersions.Free; + LRegistry.Free; + End; + End; + {$ENDIF} + +Begin + Result := ''; + LConfigured := Trim(FProducer.LibrariesPath); + If (LConfigured <> '') And HasPackages(LConfigured) Then + Begin + Result := ExpandFileName(LConfigured); + Exit; + End; + LProjectDir := RESTDWActiveProjectDir; + If LProjectDir <> '' Then + Begin + If LConfigured <> '' Then + Begin + LCandidate := ExpandFileName( + IncludeTrailingPathDelimiter(LProjectDir) + LConfigured); + If HasPackages(LCandidate) Then + Begin + Result := LCandidate; + Exit; + End; + End; + Result := SearchFrom(LProjectDir); + If Result <> '' Then Exit; + End; + {$IFDEF FPC} + LSourceDir := ExtractFilePath({$I %FILE%}); + If LSourceDir <> '' Then + Begin + Result := SearchFrom(LSourceDir); + If Result <> '' Then Exit; + End; + LModuleDir := ExtractFilePath(ParamStr(0)); + {$ELSE} + SetLength(LModuleDir,MAX_PATH); + SetLength( + LModuleDir, + GetModuleFileName( + FindClassHInstance(Self.ClassType), + PChar(LModuleDir), + MAX_PATH + ) + ); + LModuleDir := ExtractFilePath(LModuleDir); + {$ENDIF} + Result := SearchFrom(LModuleDir); + If Result <> '' Then Exit; + Result := SearchFrom(GetCurrentDir); + If Result <> '' Then Exit; + {$IFNDEF FPC} + Result := SearchDelphiLibraryPaths; + If Result <> '' Then Exit; + {$ENDIF} + LCandidate := FProducer.ResolveLibrariesPath; + If HasPackages(LCandidate) Then + Begin + Result := ExpandFileName(LCandidate); + Exit; + End; + LCandidate := RESTDWEnsureHTMLWebAssets; + If HasPackages(LCandidate) Then + Result := LCandidate; +End; + +Function TRESTDWHTMLDesignerForm.IDESettingsFileName : String; +Var + LPath : String; +Begin + LPath := RESTDWEditorConfigDir; + If Not DirectoryExists(LPath) Then + ForceDirectories(LPath); + Result := + IncludeTrailingPathDelimiter(LPath) + + 'RESTDWWebIDE_v2.ini'; +End; +Procedure TRESTDWHTMLDesignerForm.MessagesCopyLineClick( + Sender : TObject); +Var + LRow : Integer; + LText : String; +Begin + If FMessages = Nil Then + Exit; + LRow := FMessages.Row; + If (LRow < 1) Or (LRow >= FMessages.RowCount) Then + Exit; + LText := + FMessages.Cells[0,LRow] + #9 + + FMessages.Cells[1,LRow] + #9 + + FMessages.Cells[2,LRow] + #9 + + FMessages.Cells[3,LRow] + #9 + + FMessages.Cells[4,LRow]; + Clipboard.AsText := LText; +End; +Procedure TRESTDWHTMLDesignerForm.MessagesCopySelectionClick( + Sender : TObject); +Var + LTop, + LBottom, + I : Integer; + LText : TStringList; +Begin + If (FMessages = Nil) Or + (FMessages.RowCount <= 1) Then + Exit; + LTop := FMessages.Selection.Top; + LBottom := FMessages.Selection.Bottom; + If LTop < 1 Then + LTop := FMessages.Row; + If LBottom < LTop Then + LBottom := LTop; + If LTop < 1 Then + LTop := 1; + If LBottom > FMessages.RowCount - 1 Then + LBottom := FMessages.RowCount - 1; + LText := TStringList.Create; + Try + For I := LTop To LBottom Do + LText.Add( + FMessages.Cells[0,I] + #9 + + FMessages.Cells[1,I] + #9 + + FMessages.Cells[2,I] + #9 + + FMessages.Cells[3,I] + #9 + + FMessages.Cells[4,I] + ); + Clipboard.Clear; + Clipboard.AsText := LText.Text; + Finally + LText.Free; + End; +End; +Procedure TRESTDWHTMLDesignerForm.MessagesSelectAllClick( + Sender : TObject); +Var + LSelection : TGridRect; +Begin + If (FMessages = Nil) Or + (FMessages.RowCount <= 1) Then + Exit; + FMessages.Col := 0; + FMessages.Row := 1; + LSelection.Left := 0; + LSelection.Top := 1; + LSelection.Right := FMessages.ColCount - 1; + LSelection.Bottom := FMessages.RowCount - 1; + FMessages.Selection := LSelection; + FMessages.SetFocus; + FMessages.Invalidate; +End; +Procedure TRESTDWHTMLDesignerForm.MessagesCopyAllClick( + Sender : TObject); +Var + I : Integer; + LText : TStringList; +Begin + If (FMessages = Nil) Or + (FMessages.RowCount <= 1) Then + Exit; + MessagesSelectAllClick( + Sender + ); + LText := TStringList.Create; + Try + LText.Add( + 'Type'#9'File'#9'Line'#9'Column'#9'Message' + ); + For I := 1 To FMessages.RowCount - 1 Do + LText.Add( + FMessages.Cells[0,I] + #9 + + FMessages.Cells[1,I] + #9 + + FMessages.Cells[2,I] + #9 + + FMessages.Cells[3,I] + #9 + + FMessages.Cells[4,I] + ); + Clipboard.Clear; + Clipboard.AsText := LText.Text; + Finally + LText.Free; + End; +End; +Procedure TRESTDWHTMLDesignerForm.MessagesKeyDown( + Sender : TObject; + Var Key : Word; + Shift : TShiftState); +Begin + If (ssCtrl In Shift) And + (Key = Ord('A')) Then + Begin + MessagesSelectAllClick( + Sender + ); + Key := 0; + Exit; + End; + If (ssCtrl In Shift) And + (Key = Ord('C')) Then + Begin + MessagesCopySelectionClick( + Sender + ); + Key := 0; + End; +End; +Procedure TRESTDWHTMLDesignerForm.OpenWebViewInBrowserClick( + Sender : TObject); +Var + LFolder, + LAssetsFolder, + LSourceAssets, + LFileName, + LHTMLText : String; + LHTML : TStringList; +Begin + If FWebView = Nil Then + Exit; + LFolder := + IncludeTrailingPathDelimiter(GetEnvironmentVariable('TEMP')) + + 'RESTDWWebPreviewBrowser'; + LAssetsFolder := + IncludeTrailingPathDelimiter(LFolder) + + 'assets'; + ForceDirectories(LFolder); + LSourceAssets := + ResolveEditorLibrariesPath; + If (LSourceAssets <> '') And + DirectoryExists(LSourceAssets) Then + RESTDWCopyDirTree( + LSourceAssets, + LAssetsFolder + ); + LFileName := + IncludeTrailingPathDelimiter(LFolder) + + 'index.html'; + { Use the same preview HTML already prepared for the visual designer, then + translate the WebView-only virtual host to real relative files copied beside + index.html. The saved PageProducer/ContextRules HTML is never modified. } + LHTMLText := + BuildPreviewHTML; + LHTMLText := + StringReplace( + LHTMLText, + 'https://restdwassets.local/', + './assets/', + [rfReplaceAll,rfIgnoreCase] + ); + { The WebView intercepts REST calls during design. An external browser does + not have that bridge, so add the same harmless design-only fetch response. } + LHTMLText := + StringReplace( + LHTMLText, + '', + '' + + '', + [rfIgnoreCase] + ); + LHTML := TStringList.Create; + Try + LHTML.Text := LHTMLText; + LHTML.SaveToFile(LFileName); + Finally + LHTML.Free; + End; + If Not RESTDWOpenDocument(LFileName) Then + ShowMessage( + 'Unable to open the current WebView page in the default browser.' + ); +End; +Procedure TRESTDWHTMLDesignerForm.MessagesResize( + Sender : TObject); +Var + LWidth : Integer; +Begin + If FMessages = Nil Then + Exit; + LWidth := + FMessages.ClientWidth - + FMessages.ColWidths[0] - + FMessages.ColWidths[1] - + FMessages.ColWidths[2] - + FMessages.ColWidths[3] - + 8; + If LWidth < 120 Then + LWidth := 120; + FMessages.ColWidths[4] := LWidth; +End; +Procedure TRESTDWHTMLDesignerForm.MessagesDblClick( + Sender : TObject); +Var + LRow, + LLine, + LColumn : Integer; +Begin + LRow := FMessages.Row; + If LRow < 1 Then + Exit; + LLine := StrToIntDef( + FMessages.Cells[2,LRow], + 0 + ); + LColumn := StrToIntDef( + FMessages.Cells[3,LRow], + 0 + ); + If LLine <= 0 Then + Exit; + ShowCodeEditor; + If LLine > FFullCode.Lines.Count Then + LLine := FFullCode.Lines.Count; + If LLine < 1 Then + Exit; + FFullCode.CaretY := LLine; + If LColumn > 0 Then + FFullCode.CaretX := LColumn + Else + FFullCode.CaretX := 1; + FFullCode.SetFocus; +End; +Procedure TRESTDWHTMLDesignerForm.LoadIDESettings; +Var + LIni : TIniFile; + LProjectVisible, + LInspectorVisible, + LObjectBrowserVisible, + LMessagesVisible, + LFormDesignVisible, + LProjectFloating, + LInspectorFloating, + LObjectBrowserFloating, + LMessagesFloating, + LFormDesignFloating : Boolean; +Begin + LIni := TIniFile.Create( + IDESettingsFileName + ); + Try + Width := LIni.ReadInteger( + 'Window','Width',Width + ); + Height := LIni.ReadInteger( + 'Window','Height',Height + ); + Left := LIni.ReadInteger( + 'Window','Left',Left + ); + Top := LIni.ReadInteger( + 'Window','Top',Top + ); + WindowState := wsNormal; + If Width > (Screen.WorkAreaRect.Right - Screen.WorkAreaRect.Left) - 40 Then + Width := (Screen.WorkAreaRect.Right - Screen.WorkAreaRect.Left) - 40; + If Height > (Screen.WorkAreaRect.Bottom - Screen.WorkAreaRect.Top) - 40 Then + Height := (Screen.WorkAreaRect.Bottom - Screen.WorkAreaRect.Top) - 40; + If Left < Screen.WorkAreaRect.Left Then + Left := Screen.WorkAreaRect.Left + 20; + If Top < Screen.WorkAreaRect.Top Then + Top := Screen.WorkAreaRect.Top + 20; + If Left + Width > Screen.WorkAreaRect.Right Then + Left := Screen.WorkAreaRect.Right - Width - 20; + If Top + Height > Screen.WorkAreaRect.Bottom Then + Top := Screen.WorkAreaRect.Bottom - Height - 20; + FProjectPanel.Width := + LIni.ReadInteger( + 'Layout', + 'ProjectManagerWidth', + FProjectPanel.Width + ); + FRightDockHost.Width := + LIni.ReadInteger( + 'Layout', + 'ObjectInspectorWidth', + FRightDockHost.Width + ); + FRightDockHost.Width := + LIni.ReadInteger( + 'Layout', + 'RightDockWidth', + FRightDockHost.Width + ); + FObjectBrowserPanel.Height := + LIni.ReadInteger( + 'Layout', + 'ObjectBrowserHeight', + FObjectBrowserPanel.Height + ); + FMessagesPanel.Height := + LIni.ReadInteger( + 'Layout', + 'ErrorListHeight', + FMessagesPanel.Height + ); + FMessages.ColWidths[0] := + LIni.ReadInteger( + 'ErrorList','TypeWidth', + FMessages.ColWidths[0] + ); + FMessages.ColWidths[1] := + LIni.ReadInteger( + 'ErrorList','FileWidth', + FMessages.ColWidths[1] + ); + FMessages.ColWidths[2] := + LIni.ReadInteger( + 'ErrorList','LineWidth', + FMessages.ColWidths[2] + ); + FMessages.ColWidths[3] := + LIni.ReadInteger( + 'ErrorList','ColumnWidth', + FMessages.ColWidths[3] + ); + LProjectVisible := + LIni.ReadBool('Docking','ProjectExplorerVisible',True); + LInspectorVisible := + LIni.ReadBool('Docking','ObjectInspectorVisible',True); + LObjectBrowserVisible := + LIni.ReadBool('Docking','ObjectBrowserVisible',True); + LMessagesVisible := + LIni.ReadBool('Docking','ShowErrorsVisible',True); + LFormDesignVisible := + LIni.ReadBool('Docking','FormDesignVisible',True); + LProjectFloating := + LIni.ReadBool('Docking','ProjectExplorerFloating',False); + LInspectorFloating := + LIni.ReadBool('Docking','ObjectInspectorFloating',False); + LObjectBrowserFloating := + LIni.ReadBool('Docking','ObjectBrowserFloating',False); + LMessagesFloating := + LIni.ReadBool('Docking','ShowErrorsFloating',False); + LFormDesignFloating := + LIni.ReadBool('Docking','FormDesignFloating',False); + If LProjectFloating Then + ToggleFloatDock(1); + If LInspectorFloating Then + ToggleFloatDock(2); + If LObjectBrowserFloating Then + ToggleFloatDock(7); + If LMessagesFloating Then + ToggleFloatDock(3); + If LFormDesignFloating Then + ToggleFloatDock(4); + SetDockPanelVisible(1,LProjectVisible); + SetDockPanelVisible(2,LInspectorVisible); + SetDockPanelVisible(7,LObjectBrowserVisible); + SetDockPanelVisible(3,LMessagesVisible); + SetDockPanelVisible(4,LFormDesignVisible); + UpdateRightDockHost; +MessagesResize( + FMessages + ); + Finally + LIni.Free; + End; +End; +Procedure TRESTDWHTMLDesignerForm.SaveIDESettings; +Var + LIni : TIniFile; +Begin + If Not Assigned(FMessages) Or + Not Assigned(FProjectPanel) Or + Not Assigned(FInspectorPanel) Or + Not Assigned(FObjectBrowserPanel) Or + Not Assigned(FMessagesPanel) Or + Not Assigned(FPreviewPanel) Then + Exit; + LIni := TIniFile.Create( + IDESettingsFileName + ); + Try + LIni.WriteInteger( + 'Window','Width',Width + ); + LIni.WriteInteger( + 'Window','Height',Height + ); + LIni.WriteInteger( + 'Window','Left',Left + ); + LIni.WriteInteger( + 'Window','Top',Top + ); + LIni.WriteInteger( + 'Layout', + 'ProjectManagerWidth', + FLeftDockHost.Width + ); + LIni.WriteInteger( + 'Layout', + 'ObjectInspectorWidth', + FRightDockHost.Width + ); + LIni.WriteInteger( + 'Layout', + 'RightDockWidth', + FRightDockHost.Width + ); + LIni.WriteInteger( + 'Layout', + 'ObjectBrowserHeight', + FObjectBrowserPanel.Height + ); + LIni.WriteInteger( + 'Layout', + 'ErrorListHeight', + FMessagesPanel.Height + ); + LIni.WriteInteger( + 'ErrorList','TypeWidth', + FMessages.ColWidths[0] + ); + LIni.WriteInteger( + 'ErrorList','FileWidth', + FMessages.ColWidths[1] + ); + LIni.WriteInteger( + 'ErrorList','LineWidth', + FMessages.ColWidths[2] + ); + LIni.WriteInteger( + 'ErrorList','ColumnWidth', + FMessages.ColWidths[3] + ); + LIni.WriteBool( + 'Docking','ProjectExplorerVisible', + FProjectPanel.Visible + ); + LIni.WriteBool( + 'Docking','ObjectInspectorVisible', + FInspectorPanel.Visible + ); + LIni.WriteBool( + 'Docking','ObjectBrowserVisible', + FObjectBrowserPanel.Visible + ); + LIni.WriteBool( + 'Docking','ShowErrorsVisible', + FMessagesPanel.Visible + ); + LIni.WriteBool( + 'Docking','FormDesignVisible', + FPreviewPanel.Visible + ); + LIni.WriteBool( + 'Docking','ProjectExplorerFloating', + Assigned(FProjectFloatForm) + ); + LIni.WriteBool( + 'Docking','ObjectInspectorFloating', + Assigned(FInspectorFloatForm) + ); + LIni.WriteBool( + 'Docking','ObjectBrowserFloating', + Assigned(FObjectBrowserFloatForm) + ); + LIni.WriteBool( + 'Docking','ShowErrorsFloating', + Assigned(FMessagesFloatForm) + ); + LIni.WriteBool( + 'Docking','FormDesignFloating', + Assigned(FPreviewFloatForm) + ); +Finally + LIni.Free; + End; +End; +Procedure TRESTDWHTMLDesignerForm.WebViewFirstTimerTimer( + Sender : TObject); +Begin + FWebViewFirstTimer.Enabled := False; + If Not FWebViewFirstReady Or + Not Assigned(FWebView) Or + Not FWebView.Ready Then + Begin + FWebViewFirstTimer.Enabled := True; + Exit; + End; + FWebView.Parent := FPreviewPanel; + FWebView.Align := alClient; + FWebView.Visible := True; + FWebView.BringToFront; + Application.ProcessMessages; + FWebView.RebindHost; + RefreshWebView; + FWebViewFirstReady := False; +End; +Procedure TRESTDWHTMLDesignerForm.WebViewReady(Sender : TObject); +Begin + FWebViewFirstReady := True; + FWebViewFirstTimer.Enabled := False; + FWebViewFirstTimer.Enabled := True; +End; +Procedure TRESTDWHTMLDesignerForm.WebViewError( + Sender : TObject; + const AMessage : String); +Begin + AddMessage( + 'Error', + 'TRESTDWHTMLWebView', + AMessage, + 0, + 0 + ); +End; +Procedure TRESTDWHTMLDesignerForm.WebViewPageError( + Sender : TObject; + const AKind, ASource, AMessage : String; + ALine, AColumn : Integer); +Begin + AddMessage( + AKind, + ASource, + AMessage, + ALine, + AColumn + ); + If FDesignMode And + (ALine > 0) And + ( + SameText(AKind,'Error') Or + SameText(AKind,'Promise') Or + SameText(AKind,'Console Error') + ) Then + FocusCodeError( + ALine, + AColumn + ); +End; +Function TRESTDWHTMLDesignerForm.NormalizePreviewHTML( + const AHTML : String) : String; +Var + LText, + LLower, + LTag, + LTagLower, + LID, + LLabelOpen, + LBefore, + LAfter : String; + P, + Q, + R, + LFieldNo, + LLabelStart, + LLabelEnd, + LNextField, + LNextTagEnd : Integer; + Function AttrValue( + const ATag, + AName : String) : String; + Var + LLow, + LNeedle : String; + X, + Y : Integer; + C : Char; + Begin + Result := ''; + LLow := LowerCase(ATag); + LNeedle := LowerCase(AName) + '='; + X := Pos(LNeedle,LLow); + If X = 0 Then + Exit; + Inc(X,Length(LNeedle)); + While (X <= Length(ATag)) And + (ATag[X] = ' ') Do + Inc(X); + If X > Length(ATag) Then + Exit; + If (ATag[X] = '"') Or + (ATag[X] = #39) Then + Begin + C := ATag[X]; + Inc(X); + Y := X; + While (Y <= Length(ATag)) And + (ATag[Y] <> C) Do + Inc(Y); + Result := Copy(ATag,X,Y-X); + End; + End; + Function HasAttr( + const ATag, + AName : String) : Boolean; + Begin + Result := + Pos( + LowerCase(AName) + '=', + LowerCase(ATag) + ) > 0; + End; + Function InsertBeforeClose( + const ATag, + AText : String) : String; + Var + X : Integer; + Begin + Result := ATag; + X := RESTDWRPos('>',Result); + If X > 0 Then + Insert( + AText, + Result, + X + ); + End; +Begin + LText := AHTML; + { Stop Chromium from making an implicit /favicon.ico request. This is added + to the actual designer page before navigation, not after load. } + If Pos( + 'rel="icon"', + LowerCase(LText) + ) = 0 Then + Begin + P := Pos( + ' 0 Then + Begin + P := PosEx( + '>', + LText, + P + ); + If P > 0 Then + Insert( + '', + LText, + P + 1 + ); + End + Else + LText := + '' + + LText; + End; + { Give every form field id/name/aria-label before Chromium parses the page. + This avoids both DevTools form-field warnings on old pages as well as on + components created before IDs became mandatory. } + LFieldNo := 0; + P := 1; + While P <= Length(LText) Do + Begin + LLower := + LowerCase( + LText + ); + Q := PosEx(' 0) And (R < Q)) Then + Q := R; + R := PosEx(' 0) And (R < Q)) Then + Q := R; + If Q = 0 Then + Break; + R := PosEx('>',LText,Q); + If R = 0 Then + Break; + LTag := Copy(LText,Q,R-Q+1); + LID := AttrValue(LTag,'id'); + If LID = '' Then + Begin + Inc(LFieldNo); + LID := 'dsfield' + IntToStr(LFieldNo); + LTag := + InsertBeforeClose( + LTag, + ' id="' + LID + '"' + ); + End; + If Not HasAttr(LTag,'name') Then + LTag := + InsertBeforeClose( + LTag, + ' name="' + LID + '"' + ); + If Not HasAttr(LTag,'aria-label') And + Not HasAttr(LTag,'aria-labelledby') Then + LTag := + InsertBeforeClose( + LTag, + ' aria-label="' + LID + '"' + ); + Delete(LText,Q,R-Q+1); + Insert(LTag,LText,Q); + P := Q + Length(LTag); + End; + { Associate labels that do not already have for= with the next form field. + This is done on markup before navigation so Chromium never sees an + unassociated label. } + P := 1; + While P <= Length(LText) Do + Begin + LLower := LowerCase(LText); + LLabelStart := PosEx('',LText,LLabelStart); + If LLabelEnd = 0 Then + Break; + LLabelOpen := + Copy( + LText, + LLabelStart, + LLabelEnd-LLabelStart+1 + ); + If Pos( + ' for=', + LowerCase(LLabelOpen) + ) = 0 Then + Begin + LNextField := PosEx(' 0) And (Q < LNextField)) Then + LNextField := Q; + Q := PosEx(' 0) And (Q < LNextField)) Then + LNextField := Q; + If LNextField > 0 Then + Begin + LNextTagEnd := PosEx('>',LText,LNextField); + If LNextTagEnd > LNextField Then + Begin + LTag := + Copy( + LText, + LNextField, + LNextTagEnd-LNextField+1 + ); + LID := + AttrValue( + LTag, + 'id' + ); + If LID <> '' Then + Begin + LLabelOpen := + InsertBeforeClose( + LLabelOpen, + ' for="' + LID + '"' + ); + Delete( + LText, + LLabelStart, + LLabelEnd-LLabelStart+1 + ); + Insert( + LLabelOpen, + LText, + LLabelStart + ); + LLabelEnd := + LLabelStart + + Length(LLabelOpen) - 1; + End; + End; + End; + End; + P := LLabelEnd + 1; + End; + Result := LText; +End; +Function TRESTDWHTMLDesignerForm.JSLineToFullCodeLine( + AJSLine : Integer) : Integer; +Var + I, + LScriptLine : Integer; + LLine : String; +Begin + Result := 0; + If AJSLine < 1 Then + Exit; + LScriptLine := 0; + For I := 0 To FFullCode.Lines.Count - 1 Do + Begin + LLine := + LowerCase( + FFullCode.Lines[I] + ); + If Pos(' 0 Then + Begin + LScriptLine := I + 2; + Break; + End; + End; + If LScriptLine = 0 Then + Exit; + Result := + LScriptLine + + AJSLine - 1; + If Result > FFullCode.Lines.Count Then + Result := 0; +End; +Function TRESTDWHTMLDesignerForm.FullCodeLineToJSLine( + AFullLine : Integer) : Integer; +Var + I, + LScriptLine : Integer; + LLine : String; +Begin + Result := 0; + LScriptLine := 0; + For I := 0 To FFullCode.Lines.Count - 1 Do + Begin + LLine := + LowerCase( + FFullCode.Lines[I] + ); + If Pos(' 0 Then + Begin + LScriptLine := I + 2; + Break; + End; + End; + If (LScriptLine = 0) Or + (AFullLine < LScriptLine) Then + Exit; + Result := + AFullLine - + LScriptLine + 1; + If Result > FJS.Lines.Count Then + Result := 0; +End; +Function TRESTDWHTMLDesignerForm.BuildPreviewHTML : String; +Var + LHTML : String; + LBasePath : String; + PScript, + PBody : Integer; + Function LocalURL(const ARelativeName : String) : String; + Var + LRelative : String; + Begin + LRelative := StringReplace( + ARelativeName, + '\', + '/', + [rfReplaceAll] + ); + LRelative := StringReplace( + LRelative, + ' ', + '%20', + [rfReplaceAll] + ); + Result := + 'https://restdwassets.local/' + + LRelative; + End; +Begin + LHTML := FProducer.Produce; + LBasePath := + ResolveEditorLibrariesPath; + If FProducer.LibraryMode = lmLocal Then + Begin + LHTML := StringReplace( + LHTML, + FProducer.LocalHTMLLibrariesPath + '/bootstrap/css/bootstrap.min.css', + LocalURL('bootstrap/css/bootstrap.min.css'), + [rfReplaceAll] + ); + LHTML := StringReplace( + LHTML, + FProducer.LocalHTMLLibrariesPath + '/datatables/dataTables.dataTables.min.css', + LocalURL('datatables/dataTables.dataTables.min.css'), + [rfReplaceAll] + ); + LHTML := StringReplace( + LHTML, + FProducer.LocalHTMLLibrariesPath + '/bootstrap/js/bootstrap.bundle.min.js', + LocalURL('bootstrap/js/bootstrap.bundle.min.js'), + [rfReplaceAll] + ); + LHTML := StringReplace( + LHTML, + FProducer.LocalHTMLLibrariesPath + '/datatables/dataTables.min.js', + LocalURL('datatables/dataTables.min.js'), + [rfReplaceAll] + ); + LHTML := StringReplace( + LHTML, + FProducer.LocalHTMLLibrariesPath + '/chartjs/chart.umd.min.js', + LocalURL('chartjs/chart.umd.min.js'), + [rfReplaceAll] + ); + End; + LHTML := StringReplace( + LHTML, + '/RESTDataware/webassets/bootstrap/css/bootstrap.min.css', + LocalURL('bootstrap/css/bootstrap.min.css'), + [rfReplaceAll] + ); + LHTML := StringReplace( + LHTML, + '/RESTDataware/webassets/datatables/dataTables.dataTables.min.css', + LocalURL('datatables/dataTables.dataTables.min.css'), + [rfReplaceAll] + ); + LHTML := StringReplace( + LHTML, + '/RESTDataware/webassets/bootstrap/js/bootstrap.bundle.min.js', + LocalURL('bootstrap/js/bootstrap.bundle.min.js'), + [rfReplaceAll] + ); + LHTML := StringReplace( + LHTML, + '/RESTDataware/webassets/datatables/dataTables.min.js', + LocalURL('datatables/dataTables.min.js'), + [rfReplaceAll] + ); + LHTML := StringReplace( + LHTML, + '/RESTDataware/webassets/chartjs/chart.umd.min.js', + LocalURL('chartjs/chart.umd.min.js'), + [rfReplaceAll] + ); + { Preview-only asset resolver. + The authored HTML is not changed. Explicit /showcase paths are supported + even when FProducer.Route is "/" because Showcase keeps one server context. } + { The runtime-homologated form is relative to the single base context. } + LHTML := StringReplace( + LHTML, + './libs/bootstrap/css/bootstrap.min.css', + LocalURL('bootstrap/css/bootstrap.min.css'), + [rfReplaceAll,rfIgnoreCase] + ); + LHTML := StringReplace( + LHTML, + './libs/bootstrap/js/bootstrap.bundle.min.js', + LocalURL('bootstrap/js/bootstrap.bundle.min.js'), + [rfReplaceAll,rfIgnoreCase] + ); + LHTML := StringReplace( + LHTML, + './libs/datatables/dataTables.dataTables.min.css', + LocalURL('datatables/dataTables.dataTables.min.css'), + [rfReplaceAll,rfIgnoreCase] + ); + LHTML := StringReplace( + LHTML, + './libs/datatables/dataTables.min.js', + LocalURL('datatables/dataTables.min.js'), + [rfReplaceAll,rfIgnoreCase] + ); + LHTML := StringReplace( + LHTML, + './libs/chartjs/chart.umd.min.js', + LocalURL('chartjs/chart.umd.min.js'), + [rfReplaceAll,rfIgnoreCase] + ); + LHTML := StringReplace( + LHTML, + '/showcase/libs/bootstrap/css/bootstrap.min.css', + LocalURL('bootstrap/css/bootstrap.min.css'), + [rfReplaceAll,rfIgnoreCase] + ); + LHTML := StringReplace( + LHTML, + '/showcase/libs/bootstrap/js/bootstrap.bundle.min.js', + LocalURL('bootstrap/js/bootstrap.bundle.min.js'), + [rfReplaceAll,rfIgnoreCase] + ); + LHTML := StringReplace( + LHTML, + '/showcase/libs/datatables/dataTables.dataTables.min.css', + LocalURL('datatables/dataTables.dataTables.min.css'), + [rfReplaceAll,rfIgnoreCase] + ); + LHTML := StringReplace( + LHTML, + '/showcase/libs/datatables/dataTables.min.js', + LocalURL('datatables/dataTables.min.js'), + [rfReplaceAll,rfIgnoreCase] + ); + LHTML := StringReplace( + LHTML, + '/showcase/libs/chartjs/chart.umd.min.js', + LocalURL('chartjs/chart.umd.min.js'), + [rfReplaceAll,rfIgnoreCase] + ); + { Restrict banner replacement to complete src attributes. Replacing the bare + /rdw.jpg substring also matches inside restdwassets.local and + causes brandinghttps://... on a second replacement. } + LHTML := StringReplace( + LHTML, + 'src="logo-rdw-oficial.png"', + 'src="' + LocalURL('branding/logo-rdw-oficial.png') + '"', + [rfReplaceAll,rfIgnoreCase] + ); + LHTML := StringReplace( + LHTML, + 'src="./logo-rdw-oficial.png"', + 'src="' + LocalURL('branding/logo-rdw-oficial.png') + '"', + [rfReplaceAll,rfIgnoreCase] + ); + LHTML := StringReplace( + LHTML, + 'src="/logo-rdw-oficial.png"', + 'src="' + LocalURL('branding/logo-rdw-oficial.png') + '"', + [rfReplaceAll,rfIgnoreCase] + ); + LHTML := StringReplace( + LHTML, + 'src="./rdw.jpg"', + 'src="' + LocalURL('branding/rdw.jpg') + '"', + [rfReplaceAll,rfIgnoreCase] + ); + LHTML := StringReplace( + LHTML, + 'src="/rdw.jpg"', + 'src="' + LocalURL('branding/rdw.jpg') + '"', + [rfReplaceAll,rfIgnoreCase] + ); + { Mark only preview-generated library scripts. These attributes exist solely in + the WebView preview and are stripped from the HTML synchronized back to FHTML. } + LHTML := StringReplace( + LHTML, + '', + '', + [rfReplaceAll,rfIgnoreCase] + ); + LHTML := StringReplace( + LHTML, + '', + '', + [rfReplaceAll,rfIgnoreCase] + ); + LHTML := StringReplace( + LHTML, + '', + '', + [rfReplaceAll,rfIgnoreCase] + ); + { The final inline script before is FProducer.JavaScript, not authored + body HTML. Mark that preview node too so body synchronization cannot absorb it. } + PBody := + Pos( + '', + LowerCase(LHTML) + ); + If PBody > 0 Then + Begin + PScript := + RESTDWRPos( + '', L, P2 + 1); + if PEnd = 0 then + Break; + if Pos(' src=', LowerCase(Copy(S,P1,P2-P1+1))) > 0 then + begin + L := LowerCase(Copy(S,P1,PEnd+9-P1)); + if (Pos('/bootstrap/js/bootstrap.bundle.min.js',L) = 0) and + (Pos('/datatables/datatables.min.js',L) = 0) and + (Pos('/chartjs/chart.umd.min.js',L) = 0) then + FOriginalIncludeScripts.Add(Trim(Copy(S,P1,PEnd+9-P1))); + end + else + begin + if J <> '' then + J := J + sLineBreak; + J := J + Copy(S,P2+1,PEnd-P2-1); + end; + PStart := PEnd + 9; + until False; + if (Trim(J) = '') and (Pos(' '') then + begin + Result := Trim(FLibraryURL); + while (Length(Result) > 0) and + (Result[Length(Result)] = '/') do + Delete(Result,Length(Result),1); + end + else + Result := LocalHTMLLibrariesPath; +end; +function TRESTDWHTMLPageProducerAdapter.ContextLibraryRoot : String; +begin + if (FLibraryMode = lmURL) and (Trim(FLibraryURL) <> '') then + begin + Result := Trim(FLibraryURL); + while (Length(Result) > 0) and (Result[Length(Result)] = '/') do + Delete(Result,Length(Result),1); + end + else + Result := './html/libs'; +end; +function TRESTDWHTMLPageProducerAdapter.Produce : String; +var + LBody, + LRoot : String; +begin + LBody := FHTML.Text; + LRoot := LibraryRoot; + Result := + '' + sLineBreak + + '' + sLineBreak + + '' + sLineBreak + + ' ' + sLineBreak + + ' ' + sLineBreak + + ' ' + FTitle + '' + sLineBreak + + ' ' + sLineBreak + + ' ' + sLineBreak + + ' ' + sLineBreak + + '' + sLineBreak + + '' + sLineBreak + + LBody + sLineBreak + + ' ' + sLineBreak; + if FAutoDataTables then + Result := Result + + ' ' + sLineBreak; + if FAutoCharts then + Result := Result + + ' ' + sLineBreak; + Result := Result + + ' ' + sLineBreak + + '' + sLineBreak + + ''; +end; +function TRESTDWHTMLPageProducerAdapter.ResolveLibrariesPath : String; +begin + Result := Trim(FLibrariesPath); + if Result = '' then + begin + {$IFDEF FPC} + Result := 'Packages\Lazarus\html\libs'; + {$ELSE} + Result := 'html\libs'; + {$ENDIF} + end; + if not DirectoryExists(Result) then + Result := ExpandFileName( + IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) + Result + ); +end; +function TRESTDWHTMLPageProducerAdapter.LocalHTMLLibrariesPath : String; +begin + Result := '.\html\libs'; +end; +procedure TRESTDWHTMLPageProducerAdapter.SaveToContextRules; +var + LRoot : String; + LMaster, + LScripts : TStringList; + I : Integer; +begin + if FContextRules = nil then + Exit; + LRoot := ContextLibraryRoot; + LMaster := TStringList.Create; + LScripts := TStringList.Create; + try + LMaster.Add(''); + LMaster.Add(''); + LMaster.Add(''); + LMaster.Add(' '); + LMaster.Add(' '); + LMaster.Add(' ' + FTitle + ''); + LMaster.Add(' '); + LMaster.Add(' '); + LMaster.Add(' '); + LMaster.Add(''); + LMaster.Add(''); + LMaster.AddStrings(FHTML); + LMaster.Add('{%incscripts%}'); + LMaster.Add(''); + LMaster.Add(''); + LScripts.Add(''); + if FAutoDataTables then + LScripts.Add(''); + if FAutoCharts then + LScripts.Add(''); + for I := 0 to FOriginalIncludeScripts.Count - 1 do + if Trim(FOriginalIncludeScripts[I]) <> '' then + LScripts.Add(FOriginalIncludeScripts[I]); + LScripts.Add(''); + FContextRules.ContentType := 'text/html'; + FContextRules.MasterHtmlTag := '$body'; + FContextRules.IncludeScriptsHtmlTag := '{%incscripts%}'; + FContextRules.MasterHtml.Assign(LMaster); + FContextRules.IncludeScripts.Assign(LScripts); + finally + LScripts.Free; + LMaster.Free; + end; +end; +end. diff --git a/CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLWebAssets.pas b/CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLWebAssets.pas new file mode 100644 index 000000000..b1bc78ca7 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLWebAssets.pas @@ -0,0 +1,24516 @@ +unit uRESTDWHTMLWebAssets; +{$IFDEF FPC} +{$mode delphi}{$H+} +{$ENDIF} +interface +uses + Classes, SysUtils; +Function RESTDWEnsureHTMLWebAssets : String; +implementation +Const + CAsset0 : Array[0..4750] Of Byte = ( + 47, 42, 32, 82, 69, 83, 84, 68, 97, 116, 97, 119, 97, 114, 101, 32, 111, 102, 102, 108, 105, 110, 101, 32, + 66, 111, 111, 116, 115, 116, 114, 97, 112, 45, 99, 111, 109, 112, 97, 116, 105, 98, 108, 101, 32, 100, 101, + 115, 105, 103, 110, 101, 114, 32, 114, 117, 110, 116, 105, 109, 101, 46, 13, 10, 32, 32, 32, 82, 101, 112, + 108, 97, 99, 101, 32, 119, 105, 116, 104, 32, 111, 102, 102, 105, 99, 105, 97, 108, 32, 66, 111, 111, 116, + 115, 116, 114, 97, 112, 32, 100, 105, 115, 116, 114, 105, 98, 117, 116, 105, 111, 110, 32, 105, 110, 32, + 116, 104, 105, 115, 32, 115, 97, 109, 101, 32, 102, 111, 108, 100, 101, 114, 32, 97, 116, 32, 97, 110, 121, + 32, 116, 105, 109, 101, 46, 32, 42, 47, 13, 10, 58, 114, 111, 111, 116, 123, 45, 45, 98, 115, 45, 112, 114, + 105, 109, 97, 114, 121, 58, 35, 48, 100, 54, 101, 102, 100, 59, 45, 45, 98, 115, 45, 115, 101, 99, 111, + 110, 100, 97, 114, 121, 58, 35, 54, 99, 55, 53, 55, 100, 59, 45, 45, 98, 115, 45, 115, 117, 99, 99, 101, + 115, 115, 58, 35, 49, 57, 56, 55, 53, 52, 59, 45, 45, 98, 115, 45, 100, 97, 110, 103, 101, 114, 58, 35, + 100, 99, 51, 53, 52, 53, 59, 45, 45, 98, 115, 45, 119, 97, 114, 110, 105, 110, 103, 58, 35, 102, 102, 99, + 49, 48, 55, 59, 45, 45, 98, 115, 45, 105, 110, 102, 111, 58, 35, 48, 100, 99, 97, 102, 48, 59, 45, 45, 98, + 115, 45, 108, 105, 103, 104, 116, 58, 35, 102, 56, 102, 57, 102, 97, 59, 45, 45, 98, 115, 45, 100, 97, 114, + 107, 58, 35, 50, 49, 50, 53, 50, 57, 125, 13, 10, 42, 123, 98, 111, 120, 45, 115, 105, 122, 105, 110, 103, + 58, 98, 111, 114, 100, 101, 114, 45, 98, 111, 120, 125, 98, 111, 100, 121, 123, 109, 97, 114, 103, 105, + 110, 58, 48, 59, 102, 111, 110, 116, 45, 102, 97, 109, 105, 108, 121, 58, 65, 114, 105, 97, 108, 44, 115, + 97, 110, 115, 45, 115, 101, 114, 105, 102, 59, 99, 111, 108, 111, 114, 58, 35, 50, 49, 50, 53, 50, 57, 59, + 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, 35, 102, 102, 102, 125, 46, 99, 111, 110, 116, 97, 105, + 110, 101, 114, 123, 119, 105, 100, 116, 104, 58, 49, 48, 48, 37, 59, 109, 97, 120, 45, 119, 105, 100, 116, + 104, 58, 49, 49, 52, 48, 112, 120, 59, 109, 97, 114, 103, 105, 110, 58, 97, 117, 116, 111, 59, 112, 97, + 100, 100, 105, 110, 103, 58, 48, 32, 49, 50, 112, 120, 125, 46, 99, 111, 110, 116, 97, 105, 110, 101, 114, + 45, 102, 108, 117, 105, 100, 123, 119, 105, 100, 116, 104, 58, 49, 48, 48, 37, 59, 112, 97, 100, 100, 105, + 110, 103, 58, 48, 32, 49, 50, 112, 120, 125, 46, 114, 111, 119, 123, 100, 105, 115, 112, 108, 97, 121, 58, + 102, 108, 101, 120, 59, 102, 108, 101, 120, 45, 119, 114, 97, 112, 58, 119, 114, 97, 112, 59, 109, 97, 114, + 103, 105, 110, 58, 48, 32, 45, 54, 112, 120, 125, 46, 114, 111, 119, 62, 42, 123, 112, 97, 100, 100, 105, + 110, 103, 58, 48, 32, 54, 112, 120, 125, 46, 99, 111, 108, 123, 102, 108, 101, 120, 58, 49, 32, 48, 32, 48, + 125, 46, 99, 111, 108, 45, 49, 123, 119, 105, 100, 116, 104, 58, 56, 46, 51, 51, 51, 37, 125, 46, 99, 111, + 108, 45, 50, 123, 119, 105, 100, 116, 104, 58, 49, 54, 46, 54, 54, 54, 37, 125, 46, 99, 111, 108, 45, 51, + 123, 119, 105, 100, 116, 104, 58, 50, 53, 37, 125, 46, 99, 111, 108, 45, 52, 123, 119, 105, 100, 116, 104, + 58, 51, 51, 46, 51, 51, 51, 37, 125, 46, 99, 111, 108, 45, 54, 123, 119, 105, 100, 116, 104, 58, 53, 48, + 37, 125, 46, 99, 111, 108, 45, 56, 123, 119, 105, 100, 116, 104, 58, 54, 54, 46, 54, 54, 54, 37, 125, 46, + 99, 111, 108, 45, 57, 123, 119, 105, 100, 116, 104, 58, 55, 53, 37, 125, 46, 99, 111, 108, 45, 49, 50, 123, + 119, 105, 100, 116, 104, 58, 49, 48, 48, 37, 125, 13, 10, 46, 98, 116, 110, 123, 100, 105, 115, 112, 108, + 97, 121, 58, 105, 110, 108, 105, 110, 101, 45, 98, 108, 111, 99, 107, 59, 112, 97, 100, 100, 105, 110, 103, + 58, 46, 51, 55, 53, 114, 101, 109, 32, 46, 55, 53, 114, 101, 109, 59, 98, 111, 114, 100, 101, 114, 58, 49, + 112, 120, 32, 115, 111, 108, 105, 100, 32, 116, 114, 97, 110, 115, 112, 97, 114, 101, 110, 116, 59, 98, + 111, 114, 100, 101, 114, 45, 114, 97, 100, 105, 117, 115, 58, 46, 51, 55, 53, 114, 101, 109, 59, 116, 101, + 120, 116, 45, 100, 101, 99, 111, 114, 97, 116, 105, 111, 110, 58, 110, 111, 110, 101, 59, 99, 117, 114, + 115, 111, 114, 58, 112, 111, 105, 110, 116, 101, 114, 125, 46, 98, 116, 110, 45, 112, 114, 105, 109, 97, + 114, 121, 123, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, 118, 97, 114, 40, 45, 45, 98, 115, 45, + 112, 114, 105, 109, 97, 114, 121, 41, 59, 99, 111, 108, 111, 114, 58, 35, 102, 102, 102, 125, 46, 98, 116, + 110, 45, 115, 101, 99, 111, 110, 100, 97, 114, 121, 123, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, + 118, 97, 114, 40, 45, 45, 98, 115, 45, 115, 101, 99, 111, 110, 100, 97, 114, 121, 41, 59, 99, 111, 108, + 111, 114, 58, 35, 102, 102, 102, 125, 46, 98, 116, 110, 45, 115, 117, 99, 99, 101, 115, 115, 123, 98, 97, + 99, 107, 103, 114, 111, 117, 110, 100, 58, 118, 97, 114, 40, 45, 45, 98, 115, 45, 115, 117, 99, 99, 101, + 115, 115, 41, 59, 99, 111, 108, 111, 114, 58, 35, 102, 102, 102, 125, 46, 98, 116, 110, 45, 100, 97, 110, + 103, 101, 114, 123, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, 118, 97, 114, 40, 45, 45, 98, 115, + 45, 100, 97, 110, 103, 101, 114, 41, 59, 99, 111, 108, 111, 114, 58, 35, 102, 102, 102, 125, 46, 98, 116, + 110, 45, 119, 97, 114, 110, 105, 110, 103, 123, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, 118, 97, + 114, 40, 45, 45, 98, 115, 45, 119, 97, 114, 110, 105, 110, 103, 41, 59, 99, 111, 108, 111, 114, 58, 35, 49, + 49, 49, 125, 46, 98, 116, 110, 45, 111, 117, 116, 108, 105, 110, 101, 45, 112, 114, 105, 109, 97, 114, 121, + 123, 98, 111, 114, 100, 101, 114, 45, 99, 111, 108, 111, 114, 58, 118, 97, 114, 40, 45, 45, 98, 115, 45, + 112, 114, 105, 109, 97, 114, 121, 41, 59, 99, 111, 108, 111, 114, 58, 118, 97, 114, 40, 45, 45, 98, 115, + 45, 112, 114, 105, 109, 97, 114, 121, 41, 59, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, 116, 114, + 97, 110, 115, 112, 97, 114, 101, 110, 116, 125, 13, 10, 46, 99, 97, 114, 100, 123, 98, 111, 114, 100, 101, + 114, 58, 49, 112, 120, 32, 115, 111, 108, 105, 100, 32, 35, 100, 101, 101, 50, 101, 54, 59, 98, 111, 114, + 100, 101, 114, 45, 114, 97, 100, 105, 117, 115, 58, 46, 51, 55, 53, 114, 101, 109, 59, 98, 97, 99, 107, + 103, 114, 111, 117, 110, 100, 58, 35, 102, 102, 102, 125, 46, 99, 97, 114, 100, 45, 104, 101, 97, 100, 101, + 114, 44, 46, 99, 97, 114, 100, 45, 102, 111, 111, 116, 101, 114, 123, 112, 97, 100, 100, 105, 110, 103, 58, + 46, 55, 53, 114, 101, 109, 32, 49, 114, 101, 109, 59, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, + 35, 102, 56, 102, 57, 102, 97, 125, 46, 99, 97, 114, 100, 45, 98, 111, 100, 121, 123, 112, 97, 100, 100, + 105, 110, 103, 58, 49, 114, 101, 109, 125, 46, 97, 108, 101, 114, 116, 123, 112, 97, 100, 100, 105, 110, + 103, 58, 49, 114, 101, 109, 59, 98, 111, 114, 100, 101, 114, 45, 114, 97, 100, 105, 117, 115, 58, 46, 51, + 55, 53, 114, 101, 109, 59, 109, 97, 114, 103, 105, 110, 45, 98, 111, 116, 116, 111, 109, 58, 49, 114, 101, + 109, 125, 46, 97, 108, 101, 114, 116, 45, 112, 114, 105, 109, 97, 114, 121, 123, 98, 97, 99, 107, 103, 114, + 111, 117, 110, 100, 58, 35, 99, 102, 101, 50, 102, 102, 125, 46, 97, 108, 101, 114, 116, 45, 115, 117, 99, + 99, 101, 115, 115, 123, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, 35, 100, 49, 101, 55, 100, 100, + 125, 46, 97, 108, 101, 114, 116, 45, 100, 97, 110, 103, 101, 114, 123, 98, 97, 99, 107, 103, 114, 111, 117, + 110, 100, 58, 35, 102, 56, 100, 55, 100, 97, 125, 46, 98, 97, 100, 103, 101, 123, 100, 105, 115, 112, 108, + 97, 121, 58, 105, 110, 108, 105, 110, 101, 45, 98, 108, 111, 99, 107, 59, 112, 97, 100, 100, 105, 110, 103, + 58, 46, 51, 53, 101, 109, 32, 46, 54, 53, 101, 109, 59, 98, 111, 114, 100, 101, 114, 45, 114, 97, 100, 105, + 117, 115, 58, 46, 51, 55, 53, 114, 101, 109, 59, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, 118, + 97, 114, 40, 45, 45, 98, 115, 45, 112, 114, 105, 109, 97, 114, 121, 41, 59, 99, 111, 108, 111, 114, 58, 35, + 102, 102, 102, 125, 13, 10, 46, 102, 111, 114, 109, 45, 99, 111, 110, 116, 114, 111, 108, 44, 46, 102, 111, + 114, 109, 45, 115, 101, 108, 101, 99, 116, 123, 100, 105, 115, 112, 108, 97, 121, 58, 98, 108, 111, 99, + 107, 59, 119, 105, 100, 116, 104, 58, 49, 48, 48, 37, 59, 112, 97, 100, 100, 105, 110, 103, 58, 46, 51, 55, + 53, 114, 101, 109, 32, 46, 55, 53, 114, 101, 109, 59, 98, 111, 114, 100, 101, 114, 58, 49, 112, 120, 32, + 115, 111, 108, 105, 100, 32, 35, 99, 101, 100, 52, 100, 97, 59, 98, 111, 114, 100, 101, 114, 45, 114, 97, + 100, 105, 117, 115, 58, 46, 51, 55, 53, 114, 101, 109, 59, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, + 58, 35, 102, 102, 102, 125, 46, 102, 111, 114, 109, 45, 108, 97, 98, 101, 108, 123, 100, 105, 115, 112, + 108, 97, 121, 58, 98, 108, 111, 99, 107, 59, 109, 97, 114, 103, 105, 110, 45, 98, 111, 116, 116, 111, 109, + 58, 46, 53, 114, 101, 109, 125, 46, 102, 111, 114, 109, 45, 99, 104, 101, 99, 107, 123, 100, 105, 115, 112, + 108, 97, 121, 58, 98, 108, 111, 99, 107, 59, 109, 97, 114, 103, 105, 110, 45, 98, 111, 116, 116, 111, 109, + 58, 46, 53, 114, 101, 109, 125, 46, 105, 110, 112, 117, 116, 45, 103, 114, 111, 117, 112, 123, 100, 105, + 115, 112, 108, 97, 121, 58, 102, 108, 101, 120, 125, 46, 105, 110, 112, 117, 116, 45, 103, 114, 111, 117, + 112, 32, 46, 102, 111, 114, 109, 45, 99, 111, 110, 116, 114, 111, 108, 123, 102, 108, 101, 120, 58, 49, + 125, 46, 105, 110, 112, 117, 116, 45, 103, 114, 111, 117, 112, 45, 116, 101, 120, 116, 123, 112, 97, 100, + 100, 105, 110, 103, 58, 46, 51, 55, 53, 114, 101, 109, 32, 46, 55, 53, 114, 101, 109, 59, 98, 111, 114, + 100, 101, 114, 58, 49, 112, 120, 32, 115, 111, 108, 105, 100, 32, 35, 99, 101, 100, 52, 100, 97, 59, 98, + 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, 35, 101, 57, 101, 99, 101, 102, 125, 13, 10, 46, 116, 97, + 98, 108, 101, 123, 119, 105, 100, 116, 104, 58, 49, 48, 48, 37, 59, 98, 111, 114, 100, 101, 114, 45, 99, + 111, 108, 108, 97, 112, 115, 101, 58, 99, 111, 108, 108, 97, 112, 115, 101, 125, 46, 116, 97, 98, 108, 101, + 32, 116, 104, 44, 46, 116, 97, 98, 108, 101, 32, 116, 100, 123, 112, 97, 100, 100, 105, 110, 103, 58, 46, + 53, 114, 101, 109, 59, 98, 111, 114, 100, 101, 114, 45, 98, 111, 116, 116, 111, 109, 58, 49, 112, 120, 32, + 115, 111, 108, 105, 100, 32, 35, 100, 101, 101, 50, 101, 54, 125, 46, 116, 97, 98, 108, 101, 45, 115, 116, + 114, 105, 112, 101, 100, 32, 116, 98, 111, 100, 121, 32, 116, 114, 58, 110, 116, 104, 45, 99, 104, 105, + 108, 100, 40, 111, 100, 100, 41, 123, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, 35, 102, 56, 102, + 57, 102, 97, 125, 46, 116, 97, 98, 108, 101, 45, 98, 111, 114, 100, 101, 114, 101, 100, 32, 116, 104, 44, + 46, 116, 97, 98, 108, 101, 45, 98, 111, 114, 100, 101, 114, 101, 100, 32, 116, 100, 123, 98, 111, 114, 100, + 101, 114, 58, 49, 112, 120, 32, 115, 111, 108, 105, 100, 32, 35, 100, 101, 101, 50, 101, 54, 125, 13, 10, + 46, 110, 97, 118, 123, 100, 105, 115, 112, 108, 97, 121, 58, 102, 108, 101, 120, 59, 103, 97, 112, 58, 46, + 50, 53, 114, 101, 109, 59, 108, 105, 115, 116, 45, 115, 116, 121, 108, 101, 58, 110, 111, 110, 101, 59, + 112, 97, 100, 100, 105, 110, 103, 58, 48, 125, 46, 110, 97, 118, 45, 108, 105, 110, 107, 123, 100, 105, + 115, 112, 108, 97, 121, 58, 98, 108, 111, 99, 107, 59, 112, 97, 100, 100, 105, 110, 103, 58, 46, 53, 114, + 101, 109, 32, 49, 114, 101, 109, 59, 116, 101, 120, 116, 45, 100, 101, 99, 111, 114, 97, 116, 105, 111, + 110, 58, 110, 111, 110, 101, 125, 46, 110, 97, 118, 98, 97, 114, 123, 100, 105, 115, 112, 108, 97, 121, 58, + 102, 108, 101, 120, 59, 97, 108, 105, 103, 110, 45, 105, 116, 101, 109, 115, 58, 99, 101, 110, 116, 101, + 114, 59, 112, 97, 100, 100, 105, 110, 103, 58, 46, 53, 114, 101, 109, 32, 49, 114, 101, 109, 59, 98, 97, + 99, 107, 103, 114, 111, 117, 110, 100, 58, 35, 102, 56, 102, 57, 102, 97, 125, 46, 110, 97, 118, 98, 97, + 114, 45, 98, 114, 97, 110, 100, 123, 102, 111, 110, 116, 45, 119, 101, 105, 103, 104, 116, 58, 98, 111, + 108, 100, 59, 109, 97, 114, 103, 105, 110, 45, 114, 105, 103, 104, 116, 58, 49, 114, 101, 109, 125, 46, 98, + 114, 101, 97, 100, 99, 114, 117, 109, 98, 123, 100, 105, 115, 112, 108, 97, 121, 58, 102, 108, 101, 120, + 59, 108, 105, 115, 116, 45, 115, 116, 121, 108, 101, 58, 110, 111, 110, 101, 59, 103, 97, 112, 58, 46, 53, + 114, 101, 109, 59, 112, 97, 100, 100, 105, 110, 103, 58, 46, 53, 114, 101, 109, 32, 48, 125, 46, 112, 97, + 103, 105, 110, 97, 116, 105, 111, 110, 123, 100, 105, 115, 112, 108, 97, 121, 58, 102, 108, 101, 120, 59, + 108, 105, 115, 116, 45, 115, 116, 121, 108, 101, 58, 110, 111, 110, 101, 59, 112, 97, 100, 100, 105, 110, + 103, 58, 48, 125, 46, 112, 97, 103, 101, 45, 108, 105, 110, 107, 123, 112, 97, 100, 100, 105, 110, 103, 58, + 46, 51, 55, 53, 114, 101, 109, 32, 46, 55, 53, 114, 101, 109, 59, 98, 111, 114, 100, 101, 114, 58, 49, 112, + 120, 32, 115, 111, 108, 105, 100, 32, 35, 100, 101, 101, 50, 101, 54, 59, 116, 101, 120, 116, 45, 100, 101, + 99, 111, 114, 97, 116, 105, 111, 110, 58, 110, 111, 110, 101, 125, 13, 10, 46, 112, 114, 111, 103, 114, + 101, 115, 115, 123, 104, 101, 105, 103, 104, 116, 58, 49, 114, 101, 109, 59, 98, 97, 99, 107, 103, 114, + 111, 117, 110, 100, 58, 35, 101, 57, 101, 99, 101, 102, 59, 98, 111, 114, 100, 101, 114, 45, 114, 97, 100, + 105, 117, 115, 58, 46, 51, 55, 53, 114, 101, 109, 59, 111, 118, 101, 114, 102, 108, 111, 119, 58, 104, 105, + 100, 100, 101, 110, 125, 46, 112, 114, 111, 103, 114, 101, 115, 115, 45, 98, 97, 114, 123, 104, 101, 105, + 103, 104, 116, 58, 49, 48, 48, 37, 59, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, 118, 97, 114, 40, + 45, 45, 98, 115, 45, 112, 114, 105, 109, 97, 114, 121, 41, 125, 46, 115, 112, 105, 110, 110, 101, 114, 45, + 98, 111, 114, 100, 101, 114, 123, 100, 105, 115, 112, 108, 97, 121, 58, 105, 110, 108, 105, 110, 101, 45, + 98, 108, 111, 99, 107, 59, 119, 105, 100, 116, 104, 58, 50, 114, 101, 109, 59, 104, 101, 105, 103, 104, + 116, 58, 50, 114, 101, 109, 59, 98, 111, 114, 100, 101, 114, 58, 46, 50, 53, 101, 109, 32, 115, 111, 108, + 105, 100, 32, 99, 117, 114, 114, 101, 110, 116, 67, 111, 108, 111, 114, 59, 98, 111, 114, 100, 101, 114, + 45, 114, 105, 103, 104, 116, 45, 99, 111, 108, 111, 114, 58, 116, 114, 97, 110, 115, 112, 97, 114, 101, + 110, 116, 59, 98, 111, 114, 100, 101, 114, 45, 114, 97, 100, 105, 117, 115, 58, 53, 48, 37, 125, 13, 10, + 46, 97, 99, 99, 111, 114, 100, 105, 111, 110, 45, 105, 116, 101, 109, 123, 98, 111, 114, 100, 101, 114, 58, + 49, 112, 120, 32, 115, 111, 108, 105, 100, 32, 35, 100, 101, 101, 50, 101, 54, 125, 46, 97, 99, 99, 111, + 114, 100, 105, 111, 110, 45, 98, 117, 116, 116, 111, 110, 123, 119, 105, 100, 116, 104, 58, 49, 48, 48, 37, + 59, 112, 97, 100, 100, 105, 110, 103, 58, 49, 114, 101, 109, 59, 116, 101, 120, 116, 45, 97, 108, 105, 103, + 110, 58, 108, 101, 102, 116, 59, 98, 111, 114, 100, 101, 114, 58, 48, 59, 98, 97, 99, 107, 103, 114, 111, + 117, 110, 100, 58, 35, 102, 56, 102, 57, 102, 97, 125, 46, 97, 99, 99, 111, 114, 100, 105, 111, 110, 45, + 98, 111, 100, 121, 123, 112, 97, 100, 100, 105, 110, 103, 58, 49, 114, 101, 109, 125, 46, 108, 105, 115, + 116, 45, 103, 114, 111, 117, 112, 123, 108, 105, 115, 116, 45, 115, 116, 121, 108, 101, 58, 110, 111, 110, + 101, 59, 112, 97, 100, 100, 105, 110, 103, 58, 48, 125, 46, 108, 105, 115, 116, 45, 103, 114, 111, 117, + 112, 45, 105, 116, 101, 109, 123, 112, 97, 100, 100, 105, 110, 103, 58, 46, 53, 114, 101, 109, 32, 49, 114, + 101, 109, 59, 98, 111, 114, 100, 101, 114, 58, 49, 112, 120, 32, 115, 111, 108, 105, 100, 32, 35, 100, 101, + 101, 50, 101, 54, 125, 46, 109, 111, 100, 97, 108, 44, 46, 111, 102, 102, 99, 97, 110, 118, 97, 115, 44, + 46, 116, 111, 97, 115, 116, 44, 46, 112, 111, 112, 111, 118, 101, 114, 44, 46, 116, 111, 111, 108, 116, + 105, 112, 44, 46, 100, 114, 111, 112, 100, 111, 119, 110, 45, 109, 101, 110, 117, 123, 98, 111, 114, 100, + 101, 114, 58, 49, 112, 120, 32, 115, 111, 108, 105, 100, 32, 35, 100, 101, 101, 50, 101, 54, 59, 98, 97, + 99, 107, 103, 114, 111, 117, 110, 100, 58, 35, 102, 102, 102, 59, 112, 97, 100, 100, 105, 110, 103, 58, 49, + 114, 101, 109, 59, 98, 111, 114, 100, 101, 114, 45, 114, 97, 100, 105, 117, 115, 58, 46, 51, 55, 53, 114, + 101, 109, 125, 46, 100, 114, 111, 112, 100, 111, 119, 110, 45, 109, 101, 110, 117, 123, 100, 105, 115, 112, + 108, 97, 121, 58, 110, 111, 110, 101, 59, 112, 111, 115, 105, 116, 105, 111, 110, 58, 97, 98, 115, 111, + 108, 117, 116, 101, 125, 46, 100, 114, 111, 112, 100, 111, 119, 110, 58, 104, 111, 118, 101, 114, 32, 46, + 100, 114, 111, 112, 100, 111, 119, 110, 45, 109, 101, 110, 117, 123, 100, 105, 115, 112, 108, 97, 121, 58, + 98, 108, 111, 99, 107, 125, 46, 99, 111, 108, 108, 97, 112, 115, 101, 123, 100, 105, 115, 112, 108, 97, + 121, 58, 110, 111, 110, 101, 125, 46, 99, 111, 108, 108, 97, 112, 115, 101, 46, 115, 104, 111, 119, 123, + 100, 105, 115, 112, 108, 97, 121, 58, 98, 108, 111, 99, 107, 125, 13, 10, 46, 100, 45, 102, 108, 101, 120, + 123, 100, 105, 115, 112, 108, 97, 121, 58, 102, 108, 101, 120, 125, 46, 100, 45, 103, 114, 105, 100, 123, + 100, 105, 115, 112, 108, 97, 121, 58, 103, 114, 105, 100, 125, 46, 103, 97, 112, 45, 50, 123, 103, 97, 112, + 58, 46, 53, 114, 101, 109, 125, 46, 112, 45, 50, 123, 112, 97, 100, 100, 105, 110, 103, 58, 46, 53, 114, + 101, 109, 125, 46, 112, 45, 51, 123, 112, 97, 100, 100, 105, 110, 103, 58, 49, 114, 101, 109, 125, 46, 112, + 45, 52, 123, 112, 97, 100, 100, 105, 110, 103, 58, 49, 46, 53, 114, 101, 109, 125, 46, 109, 45, 50, 123, + 109, 97, 114, 103, 105, 110, 58, 46, 53, 114, 101, 109, 125, 46, 109, 98, 45, 51, 123, 109, 97, 114, 103, + 105, 110, 45, 98, 111, 116, 116, 111, 109, 58, 49, 114, 101, 109, 125, 46, 109, 116, 45, 51, 123, 109, 97, + 114, 103, 105, 110, 45, 116, 111, 112, 58, 49, 114, 101, 109, 125, 46, 116, 101, 120, 116, 45, 99, 101, + 110, 116, 101, 114, 123, 116, 101, 120, 116, 45, 97, 108, 105, 103, 110, 58, 99, 101, 110, 116, 101, 114, + 125, 46, 116, 101, 120, 116, 45, 101, 110, 100, 123, 116, 101, 120, 116, 45, 97, 108, 105, 103, 110, 58, + 114, 105, 103, 104, 116, 125, 46, 102, 119, 45, 98, 111, 108, 100, 123, 102, 111, 110, 116, 45, 119, 101, + 105, 103, 104, 116, 58, 98, 111, 108, 100, 125, 46, 98, 103, 45, 112, 114, 105, 109, 97, 114, 121, 123, 98, + 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, 118, 97, 114, 40, 45, 45, 98, 115, 45, 112, 114, 105, 109, + 97, 114, 121, 41, 33, 105, 109, 112, 111, 114, 116, 97, 110, 116, 125, 46, 98, 103, 45, 100, 97, 114, 107, + 123, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, 118, 97, 114, 40, 45, 45, 98, 115, 45, 100, 97, + 114, 107, 41, 33, 105, 109, 112, 111, 114, 116, 97, 110, 116, 125, 46, 98, 103, 45, 108, 105, 103, 104, + 116, 123, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, 118, 97, 114, 40, 45, 45, 98, 115, 45, 108, + 105, 103, 104, 116, 41, 33, 105, 109, 112, 111, 114, 116, 97, 110, 116, 125, 46, 116, 101, 120, 116, 45, + 119, 104, 105, 116, 101, 123, 99, 111, 108, 111, 114, 58, 35, 102, 102, 102, 33, 105, 109, 112, 111, 114, + 116, 97, 110, 116, 125, 46, 114, 111, 117, 110, 100, 101, 100, 123, 98, 111, 114, 100, 101, 114, 45, 114, + 97, 100, 105, 117, 115, 58, 46, 51, 55, 53, 114, 101, 109, 125, 46, 115, 104, 97, 100, 111, 119, 123, 98, + 111, 120, 45, 115, 104, 97, 100, 111, 119, 58, 48, 32, 46, 53, 114, 101, 109, 32, 49, 114, 101, 109, 32, + 114, 103, 98, 97, 40, 48, 44, 48, 44, 48, 44, 46, 49, 53, 41, 125, 13, 10, 64, 109, 101, 100, 105, 97, 40, + 109, 97, 120, 45, 119, 105, 100, 116, 104, 58, 55, 54, 56, 112, 120, 41, 123, 46, 99, 111, 108, 45, 51, 44, + 46, 99, 111, 108, 45, 52, 44, 46, 99, 111, 108, 45, 54, 44, 46, 99, 111, 108, 45, 56, 44, 46, 99, 111, 108, + 45, 57, 123, 119, 105, 100, 116, 104, 58, 49, 48, 48, 37, 125, 125, 13, 10, 13, 10, 13, 10, 46, 98, 116, + 110, 45, 105, 110, 102, 111, 123, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, 118, 97, 114, 40, 45, + 45, 98, 115, 45, 105, 110, 102, 111, 41, 59, 99, 111, 108, 111, 114, 58, 35, 49, 49, 49, 125, 46, 98, 116, + 110, 45, 108, 105, 103, 104, 116, 123, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, 118, 97, 114, 40, + 45, 45, 98, 115, 45, 108, 105, 103, 104, 116, 41, 59, 99, 111, 108, 111, 114, 58, 35, 49, 49, 49, 59, 98, + 111, 114, 100, 101, 114, 45, 99, 111, 108, 111, 114, 58, 35, 100, 101, 101, 50, 101, 54, 125, 46, 98, 116, + 110, 45, 100, 97, 114, 107, 123, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, 118, 97, 114, 40, 45, + 45, 98, 115, 45, 100, 97, 114, 107, 41, 59, 99, 111, 108, 111, 114, 58, 35, 102, 102, 102, 125, 46, 98, + 116, 110, 45, 108, 105, 110, 107, 123, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, 116, 114, 97, + 110, 115, 112, 97, 114, 101, 110, 116, 59, 99, 111, 108, 111, 114, 58, 118, 97, 114, 40, 45, 45, 98, 115, + 45, 112, 114, 105, 109, 97, 114, 121, 41, 59, 116, 101, 120, 116, 45, 100, 101, 99, 111, 114, 97, 116, 105, + 111, 110, 58, 117, 110, 100, 101, 114, 108, 105, 110, 101, 125, 46, 98, 116, 110, 45, 115, 109, 123, 112, + 97, 100, 100, 105, 110, 103, 58, 46, 50, 53, 114, 101, 109, 32, 46, 53, 114, 101, 109, 59, 102, 111, 110, + 116, 45, 115, 105, 122, 101, 58, 46, 56, 55, 53, 114, 101, 109, 125, 46, 98, 116, 110, 45, 108, 103, 123, + 112, 97, 100, 100, 105, 110, 103, 58, 46, 53, 114, 101, 109, 32, 49, 114, 101, 109, 59, 102, 111, 110, 116, + 45, 115, 105, 122, 101, 58, 49, 46, 50, 53, 114, 101, 109, 125, 13, 10, 46, 102, 111, 114, 109, 45, 114, + 97, 110, 103, 101, 123, 119, 105, 100, 116, 104, 58, 49, 48, 48, 37, 125, 46, 108, 101, 97, 100, 123, 102, + 111, 110, 116, 45, 115, 105, 122, 101, 58, 49, 46, 50, 53, 114, 101, 109, 59, 102, 111, 110, 116, 45, 119, + 101, 105, 103, 104, 116, 58, 51, 48, 48, 125, 46, 105, 109, 103, 45, 102, 108, 117, 105, 100, 123, 109, 97, + 120, 45, 119, 105, 100, 116, 104, 58, 49, 48, 48, 37, 59, 104, 101, 105, 103, 104, 116, 58, 97, 117, 116, + 111, 125, 46, 98, 116, 110, 58, 100, 105, 115, 97, 98, 108, 101, 100, 44, 46, 102, 111, 114, 109, 45, 99, + 111, 110, 116, 114, 111, 108, 58, 100, 105, 115, 97, 98, 108, 101, 100, 123, 111, 112, 97, 99, 105, 116, + 121, 58, 46, 54, 53, 125, 46, 112, 121, 45, 52, 123, 112, 97, 100, 100, 105, 110, 103, 45, 116, 111, 112, + 58, 49, 46, 53, 114, 101, 109, 59, 112, 97, 100, 100, 105, 110, 103, 45, 98, 111, 116, 116, 111, 109, 58, + 49, 46, 53, 114, 101, 109, 125, 46, 109, 98, 45, 51, 123, 109, 97, 114, 103, 105, 110, 45, 98, 111, 116, + 116, 111, 109, 58, 49, 114, 101, 109, 125, 46, 109, 116, 45, 51, 123, 109, 97, 114, 103, 105, 110, 45, 116, + 111, 112, 58, 49, 114, 101, 109, 125, 13, 10 + ); + CAsset1 : Array[0..121] Of Byte = ( + 46, 100, 116, 45, 99, 111, 110, 116, 97, 105, 110, 101, 114, 123, 119, 105, 100, 116, 104, 58, 49, 48, 48, + 37, 125, 46, 100, 116, 45, 115, 101, 97, 114, 99, 104, 123, 109, 97, 114, 103, 105, 110, 45, 98, 111, 116, + 116, 111, 109, 58, 46, 53, 114, 101, 109, 125, 46, 100, 116, 45, 105, 110, 102, 111, 123, 102, 111, 110, + 116, 45, 115, 105, 122, 101, 58, 46, 56, 55, 53, 114, 101, 109, 59, 99, 111, 108, 111, 114, 58, 35, 54, 54, + 54, 125, 46, 100, 116, 45, 112, 97, 103, 105, 110, 103, 123, 109, 97, 114, 103, 105, 110, 45, 116, 111, + 112, 58, 46, 53, 114, 101, 109, 125 + ); + CAsset2 : Array[0..574] Of Byte = ( + 47, 42, 32, 82, 69, 83, 84, 68, 97, 116, 97, 119, 97, 114, 101, 32, 111, 102, 102, 108, 105, 110, 101, 32, + 66, 111, 111, 116, 115, 116, 114, 97, 112, 45, 99, 111, 109, 112, 97, 116, 105, 98, 108, 101, 32, 98, 101, + 104, 97, 118, 105, 111, 114, 32, 42, 47, 13, 10, 100, 111, 99, 117, 109, 101, 110, 116, 46, 97, 100, 100, + 69, 118, 101, 110, 116, 76, 105, 115, 116, 101, 110, 101, 114, 40, 39, 99, 108, 105, 99, 107, 39, 44, 102, + 117, 110, 99, 116, 105, 111, 110, 40, 101, 41, 123, 118, 97, 114, 32, 116, 61, 101, 46, 116, 97, 114, 103, + 101, 116, 46, 99, 108, 111, 115, 101, 115, 116, 40, 39, 91, 100, 97, 116, 97, 45, 98, 115, 45, 116, 111, + 103, 103, 108, 101, 93, 39, 41, 59, 105, 102, 40, 33, 116, 41, 114, 101, 116, 117, 114, 110, 59, 118, 97, + 114, 32, 107, 105, 110, 100, 61, 116, 46, 103, 101, 116, 65, 116, 116, 114, 105, 98, 117, 116, 101, 40, 39, + 100, 97, 116, 97, 45, 98, 115, 45, 116, 111, 103, 103, 108, 101, 39, 41, 44, 115, 101, 108, 61, 116, 46, + 103, 101, 116, 65, 116, 116, 114, 105, 98, 117, 116, 101, 40, 39, 100, 97, 116, 97, 45, 98, 115, 45, 116, + 97, 114, 103, 101, 116, 39, 41, 124, 124, 116, 46, 103, 101, 116, 65, 116, 116, 114, 105, 98, 117, 116, + 101, 40, 39, 104, 114, 101, 102, 39, 41, 59, 105, 102, 40, 107, 105, 110, 100, 61, 61, 61, 39, 99, 111, + 108, 108, 97, 112, 115, 101, 39, 38, 38, 115, 101, 108, 41, 123, 118, 97, 114, 32, 120, 61, 100, 111, 99, + 117, 109, 101, 110, 116, 46, 113, 117, 101, 114, 121, 83, 101, 108, 101, 99, 116, 111, 114, 40, 115, 101, + 108, 41, 59, 105, 102, 40, 120, 41, 120, 46, 99, 108, 97, 115, 115, 76, 105, 115, 116, 46, 116, 111, 103, + 103, 108, 101, 40, 39, 115, 104, 111, 119, 39, 41, 125, 105, 102, 40, 107, 105, 110, 100, 61, 61, 61, 39, + 109, 111, 100, 97, 108, 39, 38, 38, 115, 101, 108, 41, 123, 118, 97, 114, 32, 109, 61, 100, 111, 99, 117, + 109, 101, 110, 116, 46, 113, 117, 101, 114, 121, 83, 101, 108, 101, 99, 116, 111, 114, 40, 115, 101, 108, + 41, 59, 105, 102, 40, 109, 41, 109, 46, 115, 116, 121, 108, 101, 46, 100, 105, 115, 112, 108, 97, 121, 61, + 39, 98, 108, 111, 99, 107, 39, 125, 105, 102, 40, 107, 105, 110, 100, 61, 61, 61, 39, 111, 102, 102, 99, + 97, 110, 118, 97, 115, 39, 38, 38, 115, 101, 108, 41, 123, 118, 97, 114, 32, 111, 61, 100, 111, 99, 117, + 109, 101, 110, 116, 46, 113, 117, 101, 114, 121, 83, 101, 108, 101, 99, 116, 111, 114, 40, 115, 101, 108, + 41, 59, 105, 102, 40, 111, 41, 111, 46, 115, 116, 121, 108, 101, 46, 100, 105, 115, 112, 108, 97, 121, 61, + 39, 98, 108, 111, 99, 107, 39, 125, 125, 41, 59, 119, 105, 110, 100, 111, 119, 46, 98, 111, 111, 116, 115, + 116, 114, 97, 112, 61, 119, 105, 110, 100, 111, 119, 46, 98, 111, 111, 116, 115, 116, 114, 97, 112, 124, + 124, 123, 125, 59 + ); + CAsset3 : Array[0..274] Of Byte = ( + 47, 42, 32, 82, 69, 83, 84, 68, 97, 116, 97, 119, 97, 114, 101, 32, 108, 111, 99, 97, 108, 32, 68, 97, 116, + 97, 84, 97, 98, 108, 101, 32, 108, 105, 103, 104, 116, 119, 101, 105, 103, 104, 116, 32, 114, 117, 110, + 116, 105, 109, 101, 32, 42, 47, 13, 10, 119, 105, 110, 100, 111, 119, 46, 68, 97, 116, 97, 84, 97, 98, 108, + 101, 61, 119, 105, 110, 100, 111, 119, 46, 68, 97, 116, 97, 84, 97, 98, 108, 101, 124, 124, 102, 117, 110, + 99, 116, 105, 111, 110, 40, 115, 101, 108, 44, 111, 112, 116, 41, 123, 116, 104, 105, 115, 46, 116, 97, 98, + 108, 101, 61, 116, 121, 112, 101, 111, 102, 32, 115, 101, 108, 61, 61, 61, 39, 115, 116, 114, 105, 110, + 103, 39, 63, 100, 111, 99, 117, 109, 101, 110, 116, 46, 113, 117, 101, 114, 121, 83, 101, 108, 101, 99, + 116, 111, 114, 40, 115, 101, 108, 41, 58, 115, 101, 108, 59, 116, 104, 105, 115, 46, 111, 112, 116, 105, + 111, 110, 115, 61, 111, 112, 116, 124, 124, 123, 125, 59, 105, 102, 40, 116, 104, 105, 115, 46, 116, 97, + 98, 108, 101, 41, 123, 116, 104, 105, 115, 46, 116, 97, 98, 108, 101, 46, 99, 108, 97, 115, 115, 76, 105, + 115, 116, 46, 97, 100, 100, 40, 39, 116, 97, 98, 108, 101, 39, 44, 39, 116, 97, 98, 108, 101, 45, 115, 116, + 114, 105, 112, 101, 100, 39, 41, 59, 125, 114, 101, 116, 117, 114, 110, 32, 116, 104, 105, 115, 59, 125, + 59 + ); + CAsset4 : Array[0..358] Of Byte = ( + 47, 42, 32, 82, 69, 83, 84, 68, 97, 116, 97, 119, 97, 114, 101, 32, 108, 111, 99, 97, 108, 32, 67, 104, 97, + 114, 116, 45, 99, 111, 109, 112, 97, 116, 105, 98, 108, 101, 32, 108, 105, 103, 104, 116, 119, 101, 105, + 103, 104, 116, 32, 114, 117, 110, 116, 105, 109, 101, 32, 42, 47, 13, 10, 119, 105, 110, 100, 111, 119, 46, + 67, 104, 97, 114, 116, 61, 119, 105, 110, 100, 111, 119, 46, 67, 104, 97, 114, 116, 124, 124, 102, 117, + 110, 99, 116, 105, 111, 110, 40, 99, 116, 120, 44, 99, 102, 103, 41, 123, 116, 104, 105, 115, 46, 99, 116, + 120, 61, 99, 116, 120, 59, 116, 104, 105, 115, 46, 99, 111, 110, 102, 105, 103, 61, 99, 102, 103, 124, 124, + 123, 125, 59, 118, 97, 114, 32, 99, 61, 99, 116, 120, 38, 38, 99, 116, 120, 46, 99, 97, 110, 118, 97, 115, + 63, 99, 116, 120, 46, 99, 97, 110, 118, 97, 115, 58, 99, 116, 120, 59, 105, 102, 40, 99, 38, 38, 99, 46, + 103, 101, 116, 67, 111, 110, 116, 101, 120, 116, 41, 123, 118, 97, 114, 32, 103, 61, 99, 46, 103, 101, 116, + 67, 111, 110, 116, 101, 120, 116, 40, 39, 50, 100, 39, 41, 59, 103, 46, 99, 108, 101, 97, 114, 82, 101, 99, + 116, 40, 48, 44, 48, 44, 99, 46, 119, 105, 100, 116, 104, 44, 99, 46, 104, 101, 105, 103, 104, 116, 41, 59, + 103, 46, 102, 111, 110, 116, 61, 39, 49, 54, 112, 120, 32, 115, 97, 110, 115, 45, 115, 101, 114, 105, 102, + 39, 59, 103, 46, 102, 105, 108, 108, 84, 101, 120, 116, 40, 40, 99, 102, 103, 38, 38, 99, 102, 103, 46, + 116, 121, 112, 101, 63, 99, 102, 103, 46, 116, 121, 112, 101, 58, 39, 99, 104, 97, 114, 116, 39, 41, 43, + 39, 32, 112, 114, 101, 118, 105, 101, 119, 39, 44, 50, 48, 44, 51, 48, 41, 59, 125, 114, 101, 116, 117, + 114, 110, 32, 116, 104, 105, 115, 59, 125, 59 + ); + CAsset5 : Array[0..12075] Of Byte = ( + 255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 2, 0, 28, 0, 28, 0, 0, 255, 225, 13, 82, 69, 120, 105, + 102, 0, 0, 73, 73, 42, 0, 8, 0, 0, 0, 7, 0, 18, 1, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, 26, 1, 5, 0, 1, 0, 0, 0, + 98, 0, 0, 0, 27, 1, 5, 0, 1, 0, 0, 0, 106, 0, 0, 0, 40, 1, 3, 0, 1, 0, 0, 0, 3, 0, 0, 0, 49, 1, 2, 0, 13, + 0, 0, 0, 114, 0, 0, 0, 50, 1, 2, 0, 20, 0, 0, 0, 128, 0, 0, 0, 105, 135, 4, 0, 1, 0, 0, 0, 148, 0, 0, 0, + 166, 0, 0, 0, 55, 2, 0, 0, 20, 0, 0, 0, 55, 2, 0, 0, 20, 0, 0, 0, 71, 73, 77, 80, 32, 50, 46, 49, 48, 46, + 51, 48, 0, 0, 50, 48, 50, 50, 58, 48, 55, 58, 50, 54, 32, 48, 51, 58, 51, 51, 58, 51, 55, 0, 1, 0, 1, 160, + 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 9, 0, 254, 0, 4, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 4, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 1, 1, 4, 0, 1, 0, 0, 0, 55, 0, 0, 0, 2, 1, 3, 0, 3, 0, 0, 0, 24, 1, 0, 0, 3, 1, 3, 0, 1, 0, + 0, 0, 6, 0, 0, 0, 6, 1, 3, 0, 1, 0, 0, 0, 6, 0, 0, 0, 21, 1, 3, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 2, 4, 0, 1, + 0, 0, 0, 30, 1, 0, 0, 2, 2, 4, 0, 1, 0, 0, 0, 43, 12, 0, 0, 0, 0, 0, 0, 8, 0, 8, 0, 8, 0, 255, 216, 255, + 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 255, 219, 0, 67, 0, 8, 6, 6, 7, 6, 5, 8, 7, 7, 7, + 9, 9, 8, 10, 12, 20, 13, 12, 11, 11, 12, 25, 18, 19, 15, 20, 29, 26, 31, 30, 29, 26, 28, 28, 32, 36, 46, + 39, 32, 34, 44, 35, 28, 28, 40, 55, 41, 44, 48, 49, 52, 52, 52, 31, 39, 57, 61, 56, 50, 60, 46, 51, 52, 50, + 255, 219, 0, 67, 1, 9, 9, 9, 12, 11, 12, 24, 13, 13, 24, 50, 33, 28, 33, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 255, 192, 0, 17, 8, 0, 55, 1, 0, 3, 1, 34, 0, + 2, 17, 1, 3, 17, 1, 255, 196, 0, 31, 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 255, 196, 0, 181, 16, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125, 1, 2, 3, 0, 4, + 17, 5, 18, 33, 49, 65, 6, 19, 81, 97, 7, 34, 113, 20, 50, 129, 145, 161, 8, 35, 66, 177, 193, 21, 82, 209, + 240, 36, 51, 98, 114, 130, 9, 10, 22, 23, 24, 25, 26, 37, 38, 39, 40, 41, 42, 52, 53, 54, 55, 56, 57, 58, + 67, 68, 69, 70, 71, 72, 73, 74, 83, 84, 85, 86, 87, 88, 89, 90, 99, 100, 101, 102, 103, 104, 105, 106, 115, + 116, 117, 118, 119, 120, 121, 122, 131, 132, 133, 134, 135, 136, 137, 138, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 162, 163, 164, 165, 166, 167, 168, 169, 170, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 194, 195, 196, 197, 198, 199, 200, 201, 202, 210, 211, 212, 213, 214, 215, 216, 217, 218, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 255, 196, 0, 31, 1, 0, + 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 255, 196, 0, 181, 17, 0, + 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119, 0, 1, 2, 3, 17, 4, 5, 33, 49, 6, 18, 65, 81, 7, 97, 113, 19, + 34, 50, 129, 8, 20, 66, 145, 161, 177, 193, 9, 35, 51, 82, 240, 21, 98, 114, 209, 10, 22, 36, 52, 225, 37, + 241, 23, 24, 25, 26, 38, 39, 40, 41, 42, 53, 54, 55, 56, 57, 58, 67, 68, 69, 70, 71, 72, 73, 74, 83, 84, + 85, 86, 87, 88, 89, 90, 99, 100, 101, 102, 103, 104, 105, 106, 115, 116, 117, 118, 119, 120, 121, 122, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 146, 147, 148, 149, 150, 151, 152, 153, 154, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 178, 179, 180, 181, 182, 183, 184, 185, 186, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 210, 211, 212, 213, 214, 215, 216, 217, 218, 226, 227, 228, 229, 230, 231, 232, 233, 234, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 255, 218, 0, 12, 3, 1, 0, 2, 17, 3, 17, 0, 63, 0, 242, 90, 42, 230, + 155, 165, 95, 107, 23, 98, 215, 79, 182, 146, 226, 99, 252, 40, 58, 123, 147, 208, 15, 173, 117, 3, 195, + 250, 23, 134, 113, 47, 136, 239, 133, 221, 226, 242, 52, 235, 54, 28, 31, 246, 223, 183, 208, 15, 198, 147, + 105, 106, 202, 132, 37, 55, 104, 171, 179, 157, 210, 52, 29, 79, 93, 185, 16, 105, 246, 175, 41, 61, 91, + 24, 85, 250, 154, 221, 188, 248, 123, 168, 197, 106, 243, 88, 93, 218, 106, 79, 15, 23, 17, 90, 201, 185, + 162, 63, 78, 245, 121, 188, 65, 168, 234, 8, 45, 141, 180, 86, 122, 60, 137, 136, 236, 236, 100, 242, 179, + 232, 93, 185, 102, 252, 78, 42, 156, 150, 166, 201, 124, 221, 14, 214, 123, 45, 69, 88, 126, 253, 46, 192, + 3, 232, 63, 250, 230, 179, 117, 87, 67, 182, 56, 25, 91, 222, 118, 103, 32, 232, 241, 185, 73, 21, 149, + 212, 224, 171, 12, 16, 105, 181, 219, 201, 174, 105, 218, 195, 125, 135, 197, 246, 169, 21, 232, 24, 93, + 78, 200, 5, 111, 171, 168, 249, 91, 240, 2, 179, 181, 127, 5, 95, 88, 91, 27, 251, 25, 99, 212, 244, 220, + 100, 92, 219, 115, 180, 127, 180, 189, 71, 234, 61, 234, 227, 37, 45, 142, 106, 180, 39, 73, 251, 200, 230, + 104, 162, 138, 163, 16, 162, 138, 40, 0, 162, 138, 40, 0, 162, 138, 40, 0, 162, 138, 40, 0, 162, 138, 40, + 0, 162, 138, 40, 0, 162, 138, 40, 0, 162, 138, 40, 0, 162, 138, 40, 0, 162, 138, 40, 0, 162, 138, 40, 0, + 162, 138, 40, 3, 179, 248, 115, 43, 157, 71, 84, 177, 142, 67, 28, 151, 122, 124, 177, 198, 202, 112, 67, + 246, 193, 252, 77, 63, 225, 237, 247, 135, 44, 245, 43, 159, 248, 73, 109, 228, 185, 23, 5, 35, 137, 60, + 189, 227, 113, 39, 44, 217, 250, 138, 231, 188, 55, 169, 157, 31, 196, 54, 87, 217, 226, 57, 6, 239, 161, + 224, 255, 0, 58, 237, 108, 236, 124, 63, 167, 248, 211, 200, 212, 34, 155, 45, 117, 246, 139, 87, 92, 121, + 108, 142, 1, 64, 221, 248, 53, 133, 107, 166, 153, 234, 229, 206, 50, 167, 82, 14, 251, 95, 77, 244, 61, + 34, 127, 134, 218, 36, 130, 237, 52, 253, 60, 90, 137, 225, 221, 5, 210, 72, 14, 199, 234, 6, 194, 56, 31, + 157, 114, 94, 0, 240, 61, 205, 220, 218, 148, 250, 220, 111, 44, 118, 178, 52, 81, 91, 240, 166, 70, 29, + 243, 233, 91, 9, 241, 18, 69, 241, 127, 246, 69, 210, 139, 59, 98, 26, 50, 206, 64, 216, 118, 229, 88, 31, + 127, 240, 162, 111, 18, 199, 225, 173, 27, 81, 187, 143, 84, 154, 230, 225, 220, 152, 162, 184, 24, 201, + 39, 239, 1, 220, 115, 154, 61, 198, 239, 216, 18, 196, 198, 62, 205, 173, 101, 107, 127, 195, 141, 215, + 116, 175, 4, 120, 55, 67, 142, 45, 75, 73, 242, 238, 238, 212, 128, 209, 15, 56, 198, 127, 222, 56, 226, + 188, 223, 193, 210, 53, 158, 151, 226, 107, 175, 57, 254, 207, 29, 151, 150, 20, 19, 181, 157, 156, 109, + 227, 215, 10, 213, 217, 107, 62, 33, 211, 188, 79, 224, 216, 239, 181, 219, 89, 145, 98, 155, 108, 44, 132, + 111, 149, 135, 92, 15, 79, 95, 198, 184, 253, 106, 72, 52, 143, 7, 199, 101, 110, 134, 57, 53, 91, 131, + 114, 84, 253, 229, 133, 114, 16, 31, 251, 233, 191, 42, 149, 239, 77, 91, 99, 89, 222, 150, 22, 126, 210, + 252, 205, 219, 93, 190, 95, 35, 138, 169, 225, 68, 49, 51, 178, 231, 21, 5, 89, 128, 41, 129, 195, 28, 47, + 115, 90, 86, 118, 137, 201, 151, 65, 74, 189, 154, 91, 61, 246, 219, 204, 68, 16, 202, 118, 133, 42, 123, + 26, 72, 163, 81, 230, 111, 25, 219, 82, 34, 197, 26, 153, 80, 150, 197, 54, 6, 4, 74, 205, 200, 60, 154, + 197, 201, 217, 218, 246, 208, 244, 33, 74, 62, 210, 159, 180, 81, 230, 124, 207, 75, 90, 214, 209, 187, + 105, 189, 198, 25, 33, 199, 250, 179, 249, 209, 12, 106, 81, 164, 124, 149, 29, 133, 43, 53, 190, 211, 132, + 108, 227, 143, 243, 154, 108, 82, 152, 193, 5, 119, 41, 234, 43, 75, 62, 87, 203, 115, 145, 78, 10, 180, + 93, 103, 22, 181, 217, 105, 126, 151, 86, 87, 30, 12, 50, 229, 118, 236, 61, 142, 106, 52, 104, 212, 16, + 233, 184, 250, 131, 82, 132, 130, 99, 132, 202, 183, 165, 87, 32, 171, 16, 122, 142, 41, 193, 39, 117, 169, + 56, 137, 78, 159, 45, 75, 69, 239, 170, 74, 207, 213, 91, 117, 232, 89, 144, 67, 26, 169, 49, 147, 184, + 103, 173, 86, 98, 11, 18, 6, 7, 97, 83, 220, 255, 0, 171, 139, 233, 254, 21, 94, 138, 43, 221, 184, 179, + 41, 254, 249, 211, 73, 36, 173, 178, 75, 162, 61, 19, 225, 134, 137, 163, 106, 118, 122, 253, 230, 177, + 103, 246, 164, 177, 138, 57, 17, 65, 193, 231, 118, 127, 144, 171, 118, 151, 255, 0, 12, 245, 217, 214, + 194, 77, 46, 247, 75, 121, 142, 200, 238, 9, 5, 85, 143, 3, 56, 52, 191, 10, 191, 228, 93, 241, 143, 253, + 122, 197, 255, 0, 179, 215, 152, 40, 44, 192, 40, 37, 137, 192, 3, 214, 182, 60, 227, 119, 197, 126, 23, + 186, 240, 191, 136, 37, 210, 229, 204, 157, 12, 46, 163, 253, 98, 158, 132, 83, 191, 225, 7, 241, 71, 216, + 254, 215, 253, 131, 125, 228, 227, 118, 124, 163, 156, 122, 227, 175, 233, 94, 151, 227, 84, 212, 91, 198, + 158, 21, 143, 78, 130, 41, 245, 104, 237, 129, 100, 148, 100, 103, 142, 77, 108, 88, 67, 172, 195, 226, + 248, 110, 53, 127, 25, 217, 44, 207, 38, 214, 211, 35, 96, 120, 199, 220, 3, 52, 1, 229, 62, 2, 240, 108, + 222, 44, 215, 214, 218, 104, 103, 91, 20, 220, 39, 153, 23, 253, 89, 193, 32, 31, 76, 145, 89, 126, 34, + 240, 229, 255, 0, 135, 245, 55, 182, 185, 180, 158, 36, 103, 97, 3, 72, 184, 50, 40, 61, 71, 233, 94, 159, + 225, 249, 230, 176, 248, 245, 121, 167, 91, 74, 209, 90, 77, 43, 188, 144, 175, 10, 199, 202, 206, 79, 226, + 77, 114, 75, 168, 120, 131, 84, 248, 146, 177, 218, 17, 125, 119, 111, 116, 226, 222, 59, 129, 185, 80, + 103, 244, 28, 80, 6, 33, 240, 55, 138, 86, 211, 237, 71, 65, 190, 16, 227, 57, 242, 142, 113, 244, 235, + 250, 86, 237, 151, 135, 244, 237, 83, 225, 69, 238, 165, 5, 182, 221, 87, 79, 186, 219, 51, 119, 41, 128, + 127, 174, 63, 10, 244, 125, 54, 13, 98, 47, 24, 65, 62, 175, 227, 59, 63, 57, 228, 33, 180, 200, 216, 28, + 255, 0, 178, 6, 107, 31, 67, 104, 63, 225, 96, 248, 215, 195, 101, 66, 193, 126, 140, 232, 131, 166, 245, + 231, 143, 174, 227, 249, 80, 6, 71, 194, 143, 4, 105, 158, 34, 211, 245, 11, 205, 94, 32, 209, 130, 33, + 128, 147, 143, 152, 247, 21, 203, 248, 119, 194, 255, 0, 111, 248, 137, 30, 135, 113, 17, 49, 71, 112, 68, + 171, 232, 128, 255, 0, 134, 43, 180, 212, 47, 159, 192, 126, 10, 240, 181, 152, 98, 179, 201, 126, 47, 39, + 3, 169, 68, 63, 48, 252, 200, 174, 149, 180, 216, 116, 47, 25, 120, 139, 197, 88, 30, 82, 105, 255, 0, 104, + 141, 187, 22, 32, 228, 15, 210, 128, 60, 143, 91, 208, 36, 213, 124, 99, 169, 217, 248, 103, 75, 158, 107, + 107, 121, 154, 37, 88, 80, 176, 27, 78, 50, 79, 65, 156, 86, 62, 173, 225, 253, 95, 66, 116, 93, 83, 78, + 184, 180, 47, 247, 76, 137, 128, 223, 67, 208, 215, 162, 248, 30, 63, 20, 93, 120, 66, 233, 173, 111, 173, + 52, 173, 58, 105, 217, 222, 254, 92, 43, 179, 127, 23, 61, 253, 43, 111, 196, 54, 193, 254, 17, 95, 165, + 206, 185, 14, 183, 37, 181, 192, 100, 185, 140, 131, 176, 227, 238, 231, 252, 245, 160, 15, 41, 181, 240, + 111, 136, 239, 68, 13, 109, 163, 93, 200, 179, 166, 248, 153, 99, 225, 151, 215, 61, 49, 85, 173, 124, 59, + 172, 95, 106, 18, 216, 90, 105, 215, 19, 221, 68, 118, 201, 28, 105, 187, 97, 247, 35, 129, 94, 161, 226, + 255, 0, 18, 106, 154, 23, 195, 207, 10, 69, 166, 93, 53, 177, 184, 182, 27, 221, 62, 241, 0, 14, 63, 90, + 214, 208, 45, 101, 79, 134, 86, 183, 48, 107, 182, 218, 85, 238, 165, 43, 73, 113, 123, 112, 64, 103, 57, + 60, 3, 199, 56, 20, 1, 227, 26, 182, 129, 171, 232, 110, 169, 170, 105, 215, 22, 165, 190, 233, 145, 8, 13, + 244, 61, 13, 102, 215, 186, 106, 11, 104, 62, 31, 234, 218, 118, 179, 226, 189, 55, 88, 153, 87, 204, 180, + 101, 145, 119, 171, 122, 117, 230, 188, 46, 128, 10, 237, 108, 8, 241, 71, 135, 214, 16, 71, 246, 182, 154, + 191, 187, 57, 249, 165, 135, 174, 62, 160, 147, 249, 138, 226, 170, 197, 141, 245, 198, 155, 123, 21, 221, + 172, 134, 57, 163, 57, 82, 63, 145, 246, 169, 156, 20, 227, 202, 205, 240, 216, 137, 225, 234, 170, 144, + 221, 29, 222, 200, 188, 97, 97, 28, 76, 203, 22, 187, 106, 187, 87, 121, 199, 218, 20, 118, 255, 0, 120, + 83, 34, 210, 245, 109, 110, 111, 59, 196, 23, 19, 69, 101, 100, 48, 242, 78, 199, 32, 119, 11, 158, 245, 8, + 22, 222, 41, 43, 123, 166, 72, 150, 122, 202, 243, 37, 177, 109, 162, 67, 253, 232, 219, 177, 246, 253, + 106, 196, 214, 190, 32, 214, 35, 7, 94, 187, 107, 59, 11, 115, 137, 36, 184, 27, 71, 29, 194, 143, 188, + 107, 134, 80, 146, 118, 146, 109, 254, 12, 250, 154, 88, 154, 82, 167, 207, 78, 105, 71, 207, 226, 141, + 247, 183, 123, 244, 20, 24, 252, 73, 169, 41, 9, 246, 109, 7, 77, 78, 1, 225, 66, 15, 95, 86, 61, 79, 212, + 215, 33, 226, 29, 88, 235, 90, 204, 183, 88, 219, 16, 196, 112, 167, 247, 80, 112, 7, 245, 252, 106, 246, + 185, 226, 24, 238, 45, 87, 73, 210, 163, 104, 52, 216, 207, 36, 253, 249, 207, 247, 155, 252, 43, 157, 174, + 186, 84, 249, 85, 222, 236, 249, 236, 126, 45, 87, 146, 140, 52, 132, 118, 255, 0, 55, 230, 194, 165, 73, + 2, 194, 232, 122, 154, 138, 138, 210, 81, 82, 86, 103, 37, 42, 178, 165, 46, 104, 246, 107, 239, 208, 150, + 9, 4, 108, 119, 125, 210, 57, 165, 137, 227, 82, 224, 231, 105, 233, 80, 209, 83, 42, 105, 223, 204, 218, + 150, 46, 165, 53, 20, 173, 238, 222, 215, 243, 221, 122, 19, 226, 223, 213, 233, 34, 145, 2, 20, 113, 242, + 158, 245, 13, 20, 189, 154, 181, 155, 15, 173, 201, 73, 74, 49, 75, 229, 189, 251, 150, 3, 193, 17, 220, + 155, 153, 187, 102, 160, 36, 177, 36, 245, 60, 210, 81, 78, 48, 81, 212, 154, 216, 137, 85, 74, 54, 73, 46, + 136, 150, 105, 3, 172, 96, 127, 8, 230, 162, 162, 138, 168, 197, 69, 89, 25, 213, 171, 42, 179, 115, 150, + 255, 0, 210, 59, 239, 135, 30, 39, 209, 180, 11, 93, 110, 215, 89, 105, 150, 43, 248, 227, 140, 121, 75, + 147, 129, 187, 63, 204, 86, 133, 174, 177, 240, 215, 195, 243, 45, 246, 159, 167, 222, 106, 23, 145, 29, + 208, 173, 201, 59, 85, 135, 67, 142, 7, 90, 243, 26, 41, 153, 157, 174, 159, 241, 10, 237, 60, 126, 190, + 37, 191, 79, 55, 118, 81, 163, 31, 195, 25, 236, 62, 149, 210, 219, 107, 63, 13, 244, 175, 16, 15, 16, 91, + 53, 253, 197, 227, 202, 101, 242, 100, 31, 36, 76, 221, 79, 78, 122, 158, 181, 228, 180, 80, 7, 118, 60, + 107, 105, 103, 241, 93, 252, 79, 110, 141, 45, 161, 147, 238, 145, 130, 84, 166, 211, 87, 219, 197, 126, + 26, 208, 60, 115, 103, 226, 13, 0, 92, 204, 146, 23, 55, 145, 202, 49, 141, 216, 251, 185, 252, 107, 205, + 104, 160, 15, 91, 178, 214, 126, 27, 232, 186, 242, 107, 182, 143, 168, 92, 93, 25, 55, 136, 164, 7, 108, + 68, 245, 61, 50, 127, 26, 230, 79, 139, 173, 160, 248, 170, 254, 36, 183, 47, 246, 70, 184, 222, 120, 228, + 161, 93, 167, 138, 226, 168, 160, 14, 207, 226, 87, 138, 237, 188, 89, 226, 40, 174, 44, 119, 11, 56, 97, + 17, 198, 24, 99, 156, 146, 78, 63, 47, 202, 182, 245, 175, 136, 214, 186, 135, 195, 11, 109, 10, 61, 255, + 0, 218, 37, 35, 138, 118, 43, 213, 87, 29, 253, 241, 250, 215, 152, 209, 64, 30, 141, 225, 239, 18, 248, + 107, 80, 240, 76, 94, 25, 241, 51, 93, 64, 150, 210, 180, 144, 207, 111, 212, 130, 115, 131, 193, 238, 106, + 222, 169, 226, 207, 9, 90, 248, 6, 255, 0, 195, 122, 18, 92, 141, 242, 6, 73, 37, 4, 153, 79, 118, 39, 181, + 121, 117, 20, 1, 218, 120, 191, 196, 214, 26, 215, 134, 60, 57, 97, 106, 95, 206, 176, 132, 164, 219, 151, + 3, 56, 29, 63, 42, 183, 225, 159, 22, 104, 147, 248, 92, 248, 99, 197, 48, 202, 214, 72, 229, 224, 158, 47, + 191, 17, 39, 60, 87, 1, 69, 0, 119, 250, 222, 167, 224, 125, 55, 195, 211, 105, 158, 31, 177, 123, 235, + 169, 206, 77, 237, 226, 2, 241, 255, 0, 186, 112, 49, 248, 87, 1, 69, 20, 0, 81, 69, 20, 0, 228, 119, 141, + 213, 209, 138, 186, 156, 134, 83, 130, 42, 221, 238, 173, 168, 106, 42, 139, 121, 119, 44, 202, 131, 10, + 25, 184, 20, 81, 64, 20, 168, 162, 138, 0, 40, 162, 138, 0, 40, 162, 138, 0, 40, 162, 138, 0, 40, 162, 138, + 0, 40, 162, 138, 0, 40, 162, 138, 0, 40, 162, 138, 0, 40, 162, 138, 0, 40, 162, 138, 0, 40, 162, 138, 0, + 40, 162, 138, 0, 40, 162, 138, 0, 40, 162, 138, 0, 255, 217, 0, 255, 225, 12, 117, 104, 116, 116, 112, 58, + 47, 47, 110, 115, 46, 97, 100, 111, 98, 101, 46, 99, 111, 109, 47, 120, 97, 112, 47, 49, 46, 48, 47, 0, 60, + 63, 120, 112, 97, 99, 107, 101, 116, 32, 98, 101, 103, 105, 110, 61, 34, 239, 187, 191, 34, 32, 105, 100, + 61, 34, 87, 53, 77, 48, 77, 112, 67, 101, 104, 105, 72, 122, 114, 101, 83, 122, 78, 84, 99, 122, 107, 99, + 57, 100, 34, 63, 62, 32, 60, 120, 58, 120, 109, 112, 109, 101, 116, 97, 32, 120, 109, 108, 110, 115, 58, + 120, 61, 34, 97, 100, 111, 98, 101, 58, 110, 115, 58, 109, 101, 116, 97, 47, 34, 32, 120, 58, 120, 109, + 112, 116, 107, 61, 34, 88, 77, 80, 32, 67, 111, 114, 101, 32, 52, 46, 52, 46, 48, 45, 69, 120, 105, 118, + 50, 34, 62, 32, 60, 114, 100, 102, 58, 82, 68, 70, 32, 120, 109, 108, 110, 115, 58, 114, 100, 102, 61, 34, + 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 119, 51, 46, 111, 114, 103, 47, 49, 57, 57, 57, 47, 48, + 50, 47, 50, 50, 45, 114, 100, 102, 45, 115, 121, 110, 116, 97, 120, 45, 110, 115, 35, 34, 62, 32, 60, 114, + 100, 102, 58, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 32, 114, 100, 102, 58, 97, 98, 111, 117, + 116, 61, 34, 34, 32, 120, 109, 108, 110, 115, 58, 120, 109, 112, 77, 77, 61, 34, 104, 116, 116, 112, 58, + 47, 47, 110, 115, 46, 97, 100, 111, 98, 101, 46, 99, 111, 109, 47, 120, 97, 112, 47, 49, 46, 48, 47, 109, + 109, 47, 34, 32, 120, 109, 108, 110, 115, 58, 115, 116, 69, 118, 116, 61, 34, 104, 116, 116, 112, 58, 47, + 47, 110, 115, 46, 97, 100, 111, 98, 101, 46, 99, 111, 109, 47, 120, 97, 112, 47, 49, 46, 48, 47, 115, 84, + 121, 112, 101, 47, 82, 101, 115, 111, 117, 114, 99, 101, 69, 118, 101, 110, 116, 35, 34, 32, 120, 109, 108, + 110, 115, 58, 100, 99, 61, 34, 104, 116, 116, 112, 58, 47, 47, 112, 117, 114, 108, 46, 111, 114, 103, 47, + 100, 99, 47, 101, 108, 101, 109, 101, 110, 116, 115, 47, 49, 46, 49, 47, 34, 32, 120, 109, 108, 110, 115, + 58, 71, 73, 77, 80, 61, 34, 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 103, 105, 109, 112, 46, 111, + 114, 103, 47, 120, 109, 112, 47, 34, 32, 120, 109, 108, 110, 115, 58, 120, 109, 112, 61, 34, 104, 116, 116, + 112, 58, 47, 47, 110, 115, 46, 97, 100, 111, 98, 101, 46, 99, 111, 109, 47, 120, 97, 112, 47, 49, 46, 48, + 47, 34, 32, 120, 109, 112, 77, 77, 58, 68, 111, 99, 117, 109, 101, 110, 116, 73, 68, 61, 34, 103, 105, 109, + 112, 58, 100, 111, 99, 105, 100, 58, 103, 105, 109, 112, 58, 99, 101, 49, 50, 50, 50, 57, 57, 45, 52, 102, + 100, 97, 45, 52, 102, 55, 97, 45, 97, 48, 101, 52, 45, 102, 55, 51, 54, 100, 102, 48, 100, 100, 57, 54, 54, + 34, 32, 120, 109, 112, 77, 77, 58, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 61, 34, 120, 109, 112, 46, + 105, 105, 100, 58, 101, 53, 49, 52, 97, 52, 52, 49, 45, 101, 51, 55, 57, 45, 52, 53, 56, 54, 45, 56, 101, + 56, 97, 45, 98, 49, 51, 100, 54, 101, 55, 57, 102, 98, 101, 55, 34, 32, 120, 109, 112, 77, 77, 58, 79, 114, + 105, 103, 105, 110, 97, 108, 68, 111, 99, 117, 109, 101, 110, 116, 73, 68, 61, 34, 120, 109, 112, 46, 100, + 105, 100, 58, 55, 51, 49, 100, 99, 56, 101, 56, 45, 55, 102, 53, 53, 45, 52, 52, 54, 49, 45, 97, 53, 50, + 99, 45, 53, 98, 55, 56, 100, 52, 56, 101, 102, 52, 53, 57, 34, 32, 100, 99, 58, 70, 111, 114, 109, 97, 116, + 61, 34, 105, 109, 97, 103, 101, 47, 106, 112, 101, 103, 34, 32, 71, 73, 77, 80, 58, 65, 80, 73, 61, 34, 50, + 46, 48, 34, 32, 71, 73, 77, 80, 58, 80, 108, 97, 116, 102, 111, 114, 109, 61, 34, 87, 105, 110, 100, 111, + 119, 115, 34, 32, 71, 73, 77, 80, 58, 84, 105, 109, 101, 83, 116, 97, 109, 112, 61, 34, 49, 54, 53, 56, 56, + 49, 55, 50, 49, 56, 52, 51, 56, 51, 53, 49, 34, 32, 71, 73, 77, 80, 58, 86, 101, 114, 115, 105, 111, 110, + 61, 34, 50, 46, 49, 48, 46, 51, 48, 34, 32, 120, 109, 112, 58, 67, 114, 101, 97, 116, 111, 114, 84, 111, + 111, 108, 61, 34, 71, 73, 77, 80, 32, 50, 46, 49, 48, 34, 62, 32, 60, 120, 109, 112, 77, 77, 58, 72, 105, + 115, 116, 111, 114, 121, 62, 32, 60, 114, 100, 102, 58, 83, 101, 113, 62, 32, 60, 114, 100, 102, 58, 108, + 105, 32, 115, 116, 69, 118, 116, 58, 97, 99, 116, 105, 111, 110, 61, 34, 115, 97, 118, 101, 100, 34, 32, + 115, 116, 69, 118, 116, 58, 99, 104, 97, 110, 103, 101, 100, 61, 34, 47, 34, 32, 115, 116, 69, 118, 116, + 58, 105, 110, 115, 116, 97, 110, 99, 101, 73, 68, 61, 34, 120, 109, 112, 46, 105, 105, 100, 58, 100, 97, + 102, 97, 54, 53, 101, 57, 45, 101, 56, 55, 51, 45, 52, 102, 99, 51, 45, 56, 57, 99, 100, 45, 55, 57, 50, + 53, 51, 98, 53, 55, 101, 56, 56, 56, 34, 32, 115, 116, 69, 118, 116, 58, 115, 111, 102, 116, 119, 97, 114, + 101, 65, 103, 101, 110, 116, 61, 34, 71, 105, 109, 112, 32, 50, 46, 49, 48, 32, 40, 87, 105, 110, 100, 111, + 119, 115, 41, 34, 32, 115, 116, 69, 118, 116, 58, 119, 104, 101, 110, 61, 34, 50, 48, 50, 50, 45, 48, 55, + 45, 50, 54, 84, 48, 51, 58, 51, 51, 58, 51, 56, 34, 47, 62, 32, 60, 47, 114, 100, 102, 58, 83, 101, 113, + 62, 32, 60, 47, 120, 109, 112, 77, 77, 58, 72, 105, 115, 116, 111, 114, 121, 62, 32, 60, 47, 114, 100, 102, + 58, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 62, 32, 60, 47, 114, 100, 102, 58, 82, 68, 70, 62, + 32, 60, 47, 120, 58, 120, 109, 112, 109, 101, 116, 97, 62, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 60, 63, 120, 112, 97, 99, 107, 101, 116, 32, 101, 110, 100, + 61, 34, 119, 34, 63, 62, 255, 226, 2, 176, 73, 67, 67, 95, 80, 82, 79, 70, 73, 76, 69, 0, 1, 1, 0, 0, 2, + 160, 108, 99, 109, 115, 4, 48, 0, 0, 109, 110, 116, 114, 82, 71, 66, 32, 88, 89, 90, 32, 7, 230, 0, 7, 0, + 26, 0, 6, 0, 28, 0, 24, 97, 99, 115, 112, 77, 83, 70, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 214, 0, 1, 0, 0, 0, 0, 211, 45, 108, 99, 109, 115, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 100, 101, 115, 99, 0, 0, 1, 32, 0, 0, 0, 64, 99, 112, 114, 116, 0, 0, 1, 96, 0, 0, 0, 54, + 119, 116, 112, 116, 0, 0, 1, 152, 0, 0, 0, 20, 99, 104, 97, 100, 0, 0, 1, 172, 0, 0, 0, 44, 114, 88, 89, + 90, 0, 0, 1, 216, 0, 0, 0, 20, 98, 88, 89, 90, 0, 0, 1, 236, 0, 0, 0, 20, 103, 88, 89, 90, 0, 0, 2, 0, 0, + 0, 0, 20, 114, 84, 82, 67, 0, 0, 2, 20, 0, 0, 0, 32, 103, 84, 82, 67, 0, 0, 2, 20, 0, 0, 0, 32, 98, 84, 82, + 67, 0, 0, 2, 20, 0, 0, 0, 32, 99, 104, 114, 109, 0, 0, 2, 52, 0, 0, 0, 36, 100, 109, 110, 100, 0, 0, 2, 88, + 0, 0, 0, 36, 100, 109, 100, 100, 0, 0, 2, 124, 0, 0, 0, 36, 109, 108, 117, 99, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 12, 101, 110, 85, 83, 0, 0, 0, 36, 0, 0, 0, 28, 0, 71, 0, 73, 0, 77, 0, 80, 0, 32, 0, 98, 0, 117, 0, + 105, 0, 108, 0, 116, 0, 45, 0, 105, 0, 110, 0, 32, 0, 115, 0, 82, 0, 71, 0, 66, 109, 108, 117, 99, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 12, 101, 110, 85, 83, 0, 0, 0, 26, 0, 0, 0, 28, 0, 80, 0, 117, 0, 98, 0, 108, 0, + 105, 0, 99, 0, 32, 0, 68, 0, 111, 0, 109, 0, 97, 0, 105, 0, 110, 0, 0, 88, 89, 90, 32, 0, 0, 0, 0, 0, 0, + 246, 214, 0, 1, 0, 0, 0, 0, 211, 45, 115, 102, 51, 50, 0, 0, 0, 0, 0, 1, 12, 66, 0, 0, 5, 222, 255, 255, + 243, 37, 0, 0, 7, 147, 0, 0, 253, 144, 255, 255, 251, 161, 255, 255, 253, 162, 0, 0, 3, 220, 0, 0, 192, + 110, 88, 89, 90, 32, 0, 0, 0, 0, 0, 0, 111, 160, 0, 0, 56, 245, 0, 0, 3, 144, 88, 89, 90, 32, 0, 0, 0, 0, + 0, 0, 36, 159, 0, 0, 15, 132, 0, 0, 182, 196, 88, 89, 90, 32, 0, 0, 0, 0, 0, 0, 98, 151, 0, 0, 183, 135, 0, + 0, 24, 217, 112, 97, 114, 97, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 102, 102, 0, 0, 242, 167, 0, 0, 13, 89, 0, 0, + 19, 208, 0, 0, 10, 91, 99, 104, 114, 109, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 163, 215, 0, 0, 84, 124, 0, 0, 76, + 205, 0, 0, 153, 154, 0, 0, 38, 103, 0, 0, 15, 92, 109, 108, 117, 99, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, + 101, 110, 85, 83, 0, 0, 0, 8, 0, 0, 0, 28, 0, 71, 0, 73, 0, 77, 0, 80, 109, 108, 117, 99, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 12, 101, 110, 85, 83, 0, 0, 0, 8, 0, 0, 0, 28, 0, 115, 0, 82, 0, 71, 0, 66, 255, 219, 0, 67, + 0, 3, 2, 2, 3, 2, 2, 3, 3, 3, 3, 4, 3, 3, 4, 5, 8, 5, 5, 4, 4, 5, 10, 7, 7, 6, 8, 12, 10, 12, 12, 11, 10, + 11, 11, 13, 14, 18, 16, 13, 14, 17, 14, 11, 11, 16, 22, 16, 17, 19, 20, 21, 21, 21, 12, 15, 23, 24, 22, 20, + 24, 18, 20, 21, 20, 255, 219, 0, 67, 1, 3, 4, 4, 5, 4, 5, 9, 5, 5, 9, 20, 13, 11, 13, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 255, 194, 0, 17, 8, 0, 50, 0, 230, + 3, 1, 17, 0, 2, 17, 1, 3, 17, 1, 255, 196, 0, 28, 0, 1, 0, 1, 5, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + 1, 2, 3, 4, 5, 7, 8, 255, 196, 0, 27, 1, 1, 0, 2, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 1, 2, 5, + 6, 7, 255, 218, 0, 12, 3, 1, 0, 2, 16, 3, 16, 0, 0, 1, 240, 112, 74, 113, 189, 8, 190, 116, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 238, 99, 110, 253, 79, 65, 146, 46, 134, 190, 54, 201, 63, 42, 51, 107, 131, 202, 206, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 148, 87, 166, 244, 61, 95, 167, 218, 224, 246, 119, 175, 243, 253, 15, 93, 30, 234, 120, + 56, 164, 29, 76, 145, 95, 186, 59, 184, 172, 113, 174, 142, 221, 178, 86, 186, 59, 52, 218, 28, 55, 60, + 247, 209, 100, 52, 208, 50, 24, 141, 224, 78, 136, 40, 35, 230, 115, 120, 243, 35, 162, 122, 183, 43, 222, + 211, 18, 11, 119, 173, 228, 29, 63, 15, 90, 189, 188, 213, 123, 246, 201, 75, 28, 220, 251, 118, 131, 53, + 126, 198, 27, 60, 90, 109, 13, 178, 209, 246, 66, 134, 249, 212, 34, 100, 224, 224, 29, 3, 158, 116, 141, + 226, 24, 72, 15, 2, 49, 147, 90, 189, 222, 191, 43, 221, 221, 157, 99, 157, 127, 158, 69, 39, 230, 87, 89, + 105, 157, 47, 138, 245, 218, 90, 178, 90, 23, 107, 53, 146, 82, 166, 112, 206, 158, 130, 67, 73, 73, 31, + 58, 7, 100, 139, 26, 38, 217, 42, 56, 71, 20, 152, 16, 112, 9, 117, 126, 174, 13, 161, 140, 77, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 255, 196, 0, 42, 16, 0, 1, 5, 0, 1, 2, 3, 8, 3, 0, 0, + 0, 0, 0, 0, 0, 5, 1, 2, 3, 4, 6, 0, 7, 19, 16, 17, 18, 20, 21, 22, 33, 34, 50, 51, 64, 23, 35, 80, 255, + 218, 0, 8, 1, 1, 0, 1, 5, 2, 240, 167, 159, 158, 122, 247, 128, 77, 86, 191, 236, 139, 19, 33, 71, 123, + 109, 1, 13, 108, 242, 93, 115, 229, 152, 109, 174, 240, 227, 8, 72, 108, 162, 172, 126, 190, 111, 251, 249, + 211, 195, 114, 82, 187, 174, 207, 85, 177, 158, 3, 159, 167, 64, 86, 212, 212, 231, 9, 235, 28, 158, 249, + 139, 242, 119, 62, 164, 111, 166, 94, 234, 241, 159, 98, 191, 212, 145, 191, 230, 247, 252, 249, 177, 212, + 88, 207, 149, 53, 5, 67, 217, 202, 216, 135, 173, 65, 57, 69, 131, 89, 165, 205, 182, 29, 3, 186, 127, 34, + 188, 164, 45, 189, 132, 96, 138, 255, 0, 199, 225, 161, 74, 120, 164, 233, 244, 141, 112, 172, 141, 194, + 164, 230, 200, 201, 239, 27, 24, 105, 18, 191, 7, 93, 112, 235, 244, 137, 184, 25, 90, 37, 38, 31, 102, 98, + 214, 75, 152, 144, 194, 144, 39, 44, 174, 158, 88, 127, 35, 95, 230, 248, 252, 210, 78, 227, 184, 212, 114, + 34, 47, 113, 177, 254, 71, 253, 233, 206, 164, 85, 154, 125, 12, 213, 95, 157, 193, 145, 30, 47, 59, 38, + 147, 233, 234, 29, 128, 170, 91, 168, 153, 137, 6, 252, 83, 154, 139, 223, 18, 169, 166, 55, 169, 90, 145, + 233, 73, 141, 128, 88, 205, 60, 107, 229, 176, 233, 171, 227, 246, 236, 249, 58, 176, 18, 145, 125, 82, + 112, 93, 152, 200, 84, 73, 153, 51, 125, 105, 51, 76, 93, 137, 34, 226, 47, 146, 243, 214, 190, 125, 215, + 241, 174, 86, 241, 207, 115, 184, 139, 229, 227, 241, 241, 239, 77, 219, 246, 8, 207, 87, 106, 102, 157, + 43, 197, 237, 146, 179, 123, 78, 76, 139, 228, 223, 29, 147, 148, 203, 219, 31, 125, 108, 202, 182, 72, + 149, 180, 86, 218, 239, 14, 173, 127, 136, 111, 165, 186, 246, 37, 169, 53, 221, 177, 162, 21, 124, 107, + 155, 100, 209, 93, 53, 220, 135, 253, 111, 255, 196, 0, 56, 17, 0, 1, 3, 3, 1, 4, 7, 5, 6, 7, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 4, 0, 5, 17, 33, 18, 19, 49, 81, 34, 50, 64, 65, 97, 113, 209, 16, 20, 52, 129, 145, 35, 36, + 51, 53, 66, 114, 80, 98, 146, 177, 193, 225, 240, 255, 218, 0, 8, 1, 3, 1, 1, 63, 1, 246, 33, 10, 112, 225, + 34, 150, 133, 54, 112, 161, 218, 146, 149, 44, 236, 164, 107, 76, 90, 73, 213, 227, 242, 173, 208, 111, + 162, 145, 138, 13, 165, 225, 176, 164, 231, 233, 82, 45, 74, 78, 172, 235, 68, 20, 156, 30, 209, 5, 123, + 185, 40, 81, 231, 87, 104, 96, 160, 200, 218, 198, 205, 64, 150, 164, 72, 78, 120, 29, 15, 173, 73, 150, + 183, 93, 82, 191, 236, 85, 182, 26, 88, 107, 120, 21, 144, 161, 154, 117, 123, 199, 20, 190, 117, 103, 72, + 92, 246, 130, 135, 125, 27, 171, 155, 242, 218, 219, 74, 147, 156, 99, 100, 84, 120, 205, 197, 186, 188, + 210, 6, 66, 82, 72, 206, 189, 217, 163, 120, 144, 70, 54, 83, 253, 34, 173, 200, 221, 195, 114, 83, 72, + 219, 112, 28, 115, 192, 231, 138, 114, 226, 153, 76, 169, 185, 72, 233, 126, 146, 0, 7, 231, 225, 86, 185, + 238, 23, 154, 140, 82, 157, 156, 129, 213, 21, 113, 184, 58, 167, 29, 143, 132, 236, 228, 142, 3, 184, 246, + 19, 29, 55, 56, 66, 74, 53, 80, 226, 51, 199, 31, 234, 159, 130, 151, 153, 110, 92, 44, 233, 203, 143, 151, + 202, 147, 1, 184, 145, 20, 236, 189, 74, 190, 190, 3, 206, 164, 178, 45, 112, 122, 95, 136, 189, 60, 179, + 199, 217, 101, 252, 193, 175, 63, 241, 80, 238, 13, 185, 52, 178, 166, 144, 146, 114, 2, 130, 117, 7, 186, + 173, 91, 230, 238, 14, 151, 122, 224, 43, 235, 75, 187, 92, 28, 73, 66, 149, 161, 254, 81, 233, 81, 218, + 148, 203, 62, 251, 28, 224, 3, 141, 56, 252, 252, 41, 183, 151, 115, 140, 242, 165, 164, 116, 70, 66, 241, + 131, 158, 94, 57, 171, 87, 199, 51, 251, 133, 79, 248, 183, 127, 113, 254, 253, 134, 211, 114, 54, 247, + 117, 234, 30, 62, 181, 187, 91, 7, 222, 224, 116, 144, 173, 74, 121, 248, 143, 26, 32, 163, 239, 247, 19, + 140, 117, 83, 203, 212, 213, 194, 114, 238, 15, 151, 85, 195, 184, 123, 26, 117, 108, 44, 56, 217, 193, 21, + 180, 162, 173, 190, 250, 19, 228, 135, 189, 224, 47, 167, 206, 141, 230, 224, 116, 222, 154, 141, 45, 248, + 138, 218, 97, 88, 169, 55, 25, 83, 6, 203, 203, 200, 166, 220, 83, 75, 14, 32, 224, 138, 90, 212, 226, 138, + 213, 196, 246, 40, 55, 41, 16, 15, 217, 29, 57, 119, 84, 185, 207, 206, 94, 211, 199, 211, 248, 191, 255, + 196, 0, 41, 17, 0, 2, 2, 1, 3, 2, 5, 4, 3, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 3, 17, 18, 33, 49, 19, 64, 4, 16, + 20, 51, 65, 35, 50, 82, 97, 66, 80, 145, 255, 218, 0, 8, 1, 2, 1, 1, 63, 1, 242, 36, 14, 96, 57, 227, 186, + 39, 28, 198, 191, 241, 153, 207, 51, 37, 119, 17, 111, 31, 203, 185, 176, 101, 12, 162, 205, 244, 98, 91, + 88, 41, 18, 176, 170, 4, 186, 205, 71, 24, 138, 48, 49, 60, 70, 213, 52, 232, 13, 57, 4, 199, 114, 244, 41, + 51, 211, 167, 239, 253, 151, 28, 216, 17, 142, 4, 20, 148, 96, 80, 237, 47, 168, 105, 103, 148, 212, 48, + 31, 177, 215, 209, 179, 65, 226, 45, 133, 88, 215, 100, 234, 151, 176, 45, 127, 17, 27, 175, 110, 220, 15, + 47, 19, 237, 52, 178, 162, 43, 212, 9, 50, 253, 38, 165, 199, 27, 65, 69, 64, 228, 71, 40, 205, 211, 120, + 84, 82, 234, 43, 60, 252, 75, 253, 166, 149, 123, 107, 216, 223, 79, 85, 127, 115, 33, 190, 157, 187, 17, + 57, 250, 84, 202, 106, 21, 46, 7, 147, 40, 97, 131, 49, 241, 58, 73, 167, 70, 54, 158, 158, 175, 198, 61, + 107, 102, 204, 34, 82, 149, 253, 162, 16, 24, 96, 192, 48, 48, 59, 43, 41, 75, 126, 233, 93, 75, 80, 194, + 255, 0, 111, 255, 196, 0, 63, 16, 0, 1, 3, 2, 3, 4, 5, 8, 8, 5, 5, 0, 0, 0, 0, 0, 2, 1, 3, 4, 0, 17, 5, 18, + 33, 19, 20, 34, 49, 65, 81, 97, 113, 129, 6, 16, 21, 35, 50, 98, 114, 145, 32, 36, 51, 64, 82, 83, 177, + 209, 66, 68, 80, 161, 193, 84, 146, 178, 225, 241, 255, 218, 0, 8, 1, 1, 0, 6, 63, 2, 243, 111, 82, 12, 32, + 66, 252, 249, 26, 102, 248, 83, 153, 120, 86, 244, 193, 132, 232, 63, 234, 24, 213, 19, 226, 78, 99, 227, + 247, 167, 84, 77, 182, 25, 101, 51, 58, 243, 197, 97, 4, 171, 225, 241, 214, 115, 201, 166, 251, 40, 61, + 88, 175, 186, 31, 189, 27, 210, 157, 111, 16, 53, 91, 237, 94, 18, 95, 4, 236, 173, 238, 35, 225, 135, 174, + 92, 185, 25, 18, 177, 119, 221, 53, 241, 164, 222, 218, 244, 76, 162, 229, 33, 144, 245, 39, 222, 61, 30, + 31, 42, 216, 186, 160, 87, 20, 49, 54, 203, 48, 144, 175, 37, 79, 188, 98, 49, 57, 172, 136, 135, 149, 58, + 200, 108, 105, 255, 0, 26, 111, 13, 24, 128, 235, 114, 142, 238, 25, 115, 181, 191, 234, 164, 113, 52, 142, + 178, 170, 235, 37, 144, 66, 221, 97, 167, 58, 130, 208, 43, 38, 131, 235, 28, 44, 130, 123, 83, 239, 173, + 131, 145, 5, 147, 140, 225, 52, 25, 121, 170, 95, 68, 90, 54, 7, 217, 140, 1, 31, 79, 116, 81, 23, 251, + 222, 146, 185, 39, 202, 137, 43, 163, 229, 74, 168, 151, 90, 226, 77, 122, 233, 19, 74, 84, 211, 204, 220, + 88, 209, 162, 43, 91, 17, 63, 88, 205, 235, 211, 113, 99, 4, 57, 44, 187, 178, 146, 211, 94, 202, 223, 145, + 37, 48, 244, 220, 70, 38, 26, 175, 166, 102, 155, 124, 184, 149, 41, 188, 63, 17, 113, 134, 242, 16, 149, + 141, 116, 121, 47, 200, 123, 235, 117, 195, 221, 102, 65, 62, 241, 8, 71, 101, 117, 107, 177, 104, 227, + 181, 138, 66, 123, 16, 4, 186, 196, 3, 226, 238, 172, 58, 74, 2, 11, 240, 158, 40, 206, 217, 44, 189, 151, + 254, 213, 185, 101, 29, 252, 162, 239, 252, 184, 173, 154, 255, 0, 166, 149, 138, 75, 217, 161, 61, 45, + 209, 138, 206, 154, 246, 219, 230, 180, 219, 15, 226, 112, 163, 207, 113, 56, 98, 153, 241, 119, 84, 200, + 8, 160, 204, 152, 194, 164, 72, 125, 139, 106, 141, 6, 28, 200, 248, 131, 238, 223, 54, 192, 174, 45, 219, + 173, 105, 227, 135, 136, 196, 196, 93, 97, 51, 58, 195, 7, 114, 68, 255, 0, 62, 102, 36, 135, 180, 209, 33, + 91, 174, 182, 40, 224, 132, 7, 135, 212, 188, 128, 153, 128, 11, 84, 91, 247, 212, 220, 59, 18, 217, 150, + 221, 126, 209, 244, 204, 2, 191, 138, 221, 55, 168, 205, 192, 81, 136, 212, 97, 182, 118, 180, 1, 78, 147, + 236, 74, 126, 105, 34, 110, 16, 236, 234, 92, 19, 51, 132, 154, 5, 215, 157, 213, 104, 220, 53, 204, 102, + 185, 149, 123, 105, 42, 214, 68, 237, 165, 191, 63, 54, 100, 162, 205, 209, 211, 67, 75, 223, 230, 107, + 102, 203, 142, 125, 92, 19, 132, 111, 215, 79, 177, 45, 54, 82, 177, 7, 197, 65, 149, 246, 144, 71, 165, + 106, 36, 67, 194, 228, 99, 50, 205, 161, 36, 50, 117, 80, 53, 232, 27, 86, 9, 113, 217, 240, 179, 195, 213, + 197, 79, 196, 117, 78, 56, 61, 36, 215, 58, 104, 182, 213, 116, 160, 143, 11, 4, 120, 92, 104, 139, 60, + 183, 221, 37, 33, 209, 117, 84, 175, 40, 176, 85, 43, 109, 201, 93, 110, 253, 4, 39, 255, 0, 148, 45, 127, + 40, 41, 184, 101, 236, 181, 173, 254, 234, 192, 124, 156, 23, 16, 120, 243, 153, 118, 145, 89, 23, 245, + 166, 112, 230, 48, 105, 19, 101, 182, 232, 38, 244, 251, 165, 217, 197, 110, 164, 175, 43, 45, 167, 212, + 143, 244, 26, 196, 91, 86, 246, 174, 185, 16, 144, 27, 205, 149, 79, 173, 47, 68, 88, 103, 146, 239, 12, + 166, 133, 115, 125, 101, 116, 78, 155, 222, 137, 81, 44, 138, 188, 188, 201, 135, 72, 52, 108, 197, 111, + 25, 210, 228, 139, 248, 23, 177, 107, 112, 197, 80, 152, 117, 158, 22, 228, 91, 80, 247, 75, 173, 43, 209, + 184, 80, 170, 129, 253, 179, 231, 162, 185, 251, 13, 4, 8, 133, 154, 59, 107, 152, 220, 252, 211, 235, 238, + 234, 250, 23, 190, 181, 206, 180, 90, 213, 126, 133, 189, 32, 72, 159, 0, 254, 212, 175, 73, 120, 223, 117, + 127, 136, 214, 244, 145, 90, 154, 72, 210, 38, 81, 209, 21, 81, 59, 22, 130, 68, 135, 213, 199, 129, 16, + 68, 249, 42, 91, 149, 70, 57, 18, 200, 220, 141, 171, 71, 100, 69, 31, 26, 110, 243, 149, 50, 117, 0, 165, + 251, 244, 165, 153, 29, 229, 110, 74, 223, 142, 221, 124, 235, 120, 206, 187, 108, 251, 76, 254, 247, 59, + 214, 243, 41, 229, 117, 253, 19, 63, 42, 22, 119, 242, 202, 157, 57, 83, 55, 206, 165, 73, 222, 23, 109, + 40, 54, 110, 149, 147, 137, 40, 30, 100, 201, 167, 65, 110, 38, 43, 170, 82, 199, 122, 105, 43, 68, 150, + 44, 162, 131, 127, 151, 208, 22, 49, 22, 150, 75, 98, 150, 7, 129, 108, 232, 120, 244, 248, 210, 198, 134, + 214, 233, 21, 125, 164, 189, 205, 207, 137, 127, 199, 245, 127, 255, 196, 0, 38, 16, 1, 0, 2, 2, 2, 1, 4, + 2, 2, 3, 0, 0, 0, 0, 0, 0, 1, 0, 17, 33, 49, 65, 81, 97, 113, 129, 145, 161, 16, 177, 32, 64, 80, 193, 240, + 255, 218, 0, 8, 1, 1, 0, 1, 63, 33, 252, 25, 239, 25, 30, 27, 207, 68, 190, 64, 225, 223, 15, 97, 224, 127, + 104, 112, 214, 203, 141, 11, 203, 110, 0, 22, 225, 104, 26, 222, 172, 107, 247, 191, 164, 169, 214, 21, + 143, 107, 27, 98, 143, 104, 80, 180, 0, 118, 96, 81, 111, 102, 35, 221, 23, 11, 124, 254, 188, 96, 234, + 178, 47, 100, 71, 15, 246, 43, 110, 194, 31, 39, 246, 49, 241, 68, 165, 39, 135, 20, 90, 92, 193, 55, 217, + 104, 22, 200, 98, 245, 184, 196, 211, 134, 140, 230, 52, 14, 10, 206, 12, 198, 79, 248, 189, 154, 118, 28, + 89, 93, 193, 48, 33, 184, 127, 172, 32, 221, 178, 248, 46, 93, 84, 16, 153, 1, 171, 158, 24, 26, 166, 47, + 196, 21, 3, 160, 34, 99, 210, 235, 81, 218, 116, 186, 212, 54, 70, 39, 220, 10, 86, 239, 56, 234, 83, 206, + 142, 172, 106, 28, 101, 62, 94, 166, 9, 195, 58, 180, 167, 4, 4, 163, 45, 190, 43, 185, 15, 211, 31, 104, + 216, 69, 42, 253, 111, 233, 139, 11, 8, 114, 11, 67, 223, 136, 137, 98, 48, 14, 126, 131, 57, 237, 3, 92, + 34, 7, 101, 153, 175, 219, 220, 62, 8, 93, 96, 171, 147, 165, 231, 230, 48, 85, 205, 165, 10, 9, 235, 184, + 243, 95, 235, 133, 226, 141, 250, 52, 38, 218, 29, 63, 25, 246, 240, 67, 147, 220, 178, 0, 112, 219, 218, + 210, 173, 161, 176, 217, 134, 16, 194, 54, 176, 71, 62, 133, 103, 156, 43, 29, 224, 8, 80, 182, 66, 104, + 15, 108, 115, 16, 55, 12, 128, 233, 237, 216, 117, 114, 232, 194, 174, 83, 107, 62, 220, 53, 78, 208, 14, + 103, 136, 140, 92, 69, 199, 164, 176, 245, 77, 98, 34, 129, 133, 149, 159, 114, 125, 148, 216, 139, 196, + 38, 191, 46, 24, 143, 79, 12, 186, 102, 142, 53, 246, 71, 141, 97, 179, 192, 220, 187, 199, 152, 42, 130, + 5, 14, 51, 98, 86, 28, 153, 96, 50, 222, 90, 251, 154, 146, 229, 128, 29, 28, 235, 222, 1, 119, 190, 64, + 255, 0, 157, 66, 253, 81, 234, 144, 203, 225, 116, 254, 24, 33, 132, 117, 182, 41, 194, 49, 70, 122, 196, + 103, 43, 10, 36, 137, 86, 139, 224, 41, 224, 189, 204, 146, 91, 159, 16, 211, 236, 195, 178, 33, 58, 120, + 252, 48, 10, 53, 74, 218, 124, 15, 15, 172, 31, 204, 45, 241, 159, 15, 39, 164, 229, 135, 11, 19, 151, 175, + 175, 153, 135, 165, 156, 112, 190, 134, 190, 92, 254, 18, 225, 166, 94, 111, 153, 251, 114, 121, 177, 91, + 162, 11, 86, 17, 16, 152, 72, 182, 219, 191, 192, 20, 128, 81, 80, 108, 198, 23, 222, 147, 46, 87, 157, 76, + 133, 147, 22, 171, 128, 60, 31, 184, 143, 33, 2, 102, 179, 64, 93, 27, 155, 115, 44, 110, 21, 94, 79, 120, + 209, 17, 164, 55, 224, 74, 138, 221, 159, 35, 47, 217, 19, 58, 22, 1, 81, 173, 68, 6, 23, 154, 174, 233, + 108, 4, 108, 155, 118, 2, 107, 26, 53, 48, 147, 0, 147, 196, 160, 248, 4, 143, 74, 5, 254, 24, 205, 74, 7, + 161, 96, 248, 249, 78, 167, 25, 234, 28, 254, 140, 127, 151, 255, 218, 0, 12, 3, 1, 0, 2, 0, 3, 0, 0, 0, + 16, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 43, 128, 0, 0, 0, 0, 0, 0, 0, 3, 39, 132, 226, 61, 51, 18, 73, + 0, 128, 1, 4, 34, 72, 226, 184, 210, 0, 146, 65, 0, 16, 64, 25, 224, 221, 41, 80, 0, 4, 128, 65, 36, 0, + 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 255, 196, 0, 38, 17, 1, 0, 1, 3, 3, + 3, 5, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 17, 0, 33, 49, 65, 81, 97, 113, 129, 145, 16, 64, 161, 177, 209, 240, + 80, 193, 255, 218, 0, 8, 1, 3, 1, 1, 63, 16, 244, 150, 229, 171, 39, 62, 232, 218, 149, 128, 166, 136, 92, + 51, 221, 252, 164, 98, 248, 137, 229, 189, 252, 246, 169, 110, 230, 182, 116, 135, 234, 164, 158, 38, 154, + 159, 180, 224, 225, 61, 192, 226, 144, 30, 141, 159, 186, 102, 76, 0, 57, 157, 243, 44, 213, 202, 48, 220, + 94, 151, 98, 51, 210, 105, 173, 36, 216, 37, 35, 163, 157, 102, 172, 42, 11, 139, 95, 238, 245, 200, 5, + 242, 209, 68, 69, 89, 185, 134, 175, 43, 54, 5, 38, 44, 132, 206, 206, 244, 24, 4, 128, 5, 128, 188, 226, + 98, 157, 43, 191, 222, 40, 70, 2, 2, 93, 18, 157, 76, 218, 82, 209, 214, 134, 83, 152, 193, 218, 16, 43, + 164, 158, 33, 125, 18, 37, 24, 93, 226, 103, 154, 128, 48, 36, 19, 22, 46, 19, 167, 176, 197, 78, 28, 38, + 116, 32, 9, 24, 22, 225, 47, 122, 181, 48, 227, 56, 165, 142, 146, 145, 47, 4, 129, 130, 134, 101, 226, 14, + 106, 93, 222, 77, 252, 233, 98, 178, 96, 97, 44, 11, 128, 76, 0, 65, 57, 152, 244, 249, 239, 181, 42, 164, + 8, 185, 100, 170, 229, 227, 46, 212, 153, 27, 218, 222, 205, 121, 191, 110, 213, 49, 160, 71, 101, 33, 197, + 26, 62, 65, 38, 22, 155, 55, 91, 50, 77, 53, 116, 240, 16, 112, 146, 14, 8, 249, 138, 254, 70, 245, 252, + 221, 222, 198, 127, 125, 145, 244, 57, 62, 78, 212, 171, 14, 106, 183, 39, 77, 198, 189, 105, 72, 90, 37, + 201, 253, 191, 26, 113, 108, 1, 109, 131, 245, 202, 239, 196, 122, 105, 214, 78, 212, 176, 156, 166, 121, + 204, 210, 246, 72, 134, 201, 140, 109, 176, 80, 138, 137, 233, 249, 72, 154, 220, 198, 189, 70, 207, 122, + 58, 176, 210, 193, 224, 1, 239, 82, 98, 82, 59, 37, 33, 50, 138, 187, 173, 215, 217, 75, 229, 121, 87, 95, + 143, 36, 115, 87, 167, 140, 5, 135, 67, 254, 229, 213, 255, 0, 95, 255, 196, 0, 39, 17, 1, 0, 2, 1, 3, 2, + 6, 2, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 17, 33, 49, 81, 97, 64, 65, 16, 113, 129, 145, 161, 209, 80, 177, 193, + 225, 240, 255, 218, 0, 8, 1, 2, 1, 1, 63, 16, 240, 6, 212, 3, 107, 170, 1, 107, 16, 204, 15, 89, 124, 213, + 197, 150, 87, 188, 102, 48, 130, 37, 157, 69, 80, 218, 48, 50, 92, 65, 90, 153, 62, 167, 248, 5, 196, 191, + 68, 106, 81, 236, 141, 64, 246, 133, 50, 154, 187, 182, 38, 84, 168, 53, 142, 245, 243, 2, 110, 253, 201, + 146, 196, 189, 173, 218, 231, 50, 96, 170, 122, 115, 6, 69, 186, 93, 88, 59, 205, 208, 234, 247, 58, 17, + 105, 235, 70, 180, 191, 238, 86, 46, 119, 211, 207, 214, 56, 224, 123, 57, 124, 163, 121, 139, 77, 107, 76, + 248, 124, 47, 230, 15, 8, 82, 139, 132, 239, 40, 218, 207, 178, 14, 12, 156, 191, 114, 153, 90, 150, 94, + 158, 156, 198, 97, 149, 54, 178, 183, 226, 167, 192, 103, 192, 63, 93, 9, 226, 209, 167, 212, 171, 178, 7, + 110, 30, 37, 130, 139, 189, 93, 254, 136, 15, 91, 187, 207, 130, 35, 177, 148, 13, 145, 107, 60, 136, 30, + 105, 2, 202, 137, 93, 12, 112, 86, 48, 11, 64, 232, 141, 195, 59, 247, 148, 67, 239, 242, 255, 0, 255, 196, + 0, 38, 16, 1, 1, 0, 2, 2, 2, 1, 4, 1, 5, 0, 0, 0, 0, 0, 0, 1, 17, 0, 33, 49, 65, 81, 97, 113, 16, 64, 145, + 161, 240, 32, 80, 129, 177, 209, 255, 218, 0, 8, 1, 1, 0, 1, 63, 16, 250, 50, 251, 176, 139, 202, 1, 143, + 129, 15, 41, 206, 60, 141, 139, 35, 177, 193, 195, 160, 223, 11, 207, 221, 30, 24, 52, 91, 204, 34, 8, 132, + 1, 188, 109, 224, 186, 2, 162, 164, 162, 42, 227, 92, 86, 208, 67, 128, 2, 147, 103, 72, 87, 76, 14, 26, + 111, 48, 27, 92, 0, 26, 82, 127, 4, 158, 49, 216, 93, 45, 187, 45, 197, 168, 192, 34, 21, 28, 188, 152, 54, + 80, 124, 135, 220, 81, 218, 2, 4, 71, 189, 31, 231, 39, 67, 178, 81, 57, 111, 163, 70, 212, 164, 50, 250, + 107, 165, 111, 67, 52, 160, 36, 106, 133, 71, 161, 197, 107, 17, 180, 77, 16, 23, 107, 165, 82, 51, 192, + 14, 185, 36, 13, 66, 111, 19, 85, 250, 169, 68, 124, 163, 0, 224, 69, 225, 248, 198, 174, 163, 13, 151, 11, + 129, 48, 22, 106, 226, 194, 115, 250, 100, 244, 48, 4, 177, 230, 98, 188, 116, 161, 31, 126, 177, 239, 102, + 21, 54, 124, 228, 165, 21, 161, 24, 62, 115, 247, 178, 38, 33, 55, 112, 135, 77, 63, 121, 196, 178, 44, + 207, 101, 14, 119, 177, 97, 72, 189, 150, 70, 68, 35, 83, 117, 148, 177, 214, 52, 229, 8, 33, 64, 10, 8, + 33, 192, 196, 196, 228, 29, 217, 46, 10, 69, 187, 1, 151, 89, 69, 25, 161, 168, 6, 200, 59, 4, 237, 13, + 225, 1, 13, 41, 188, 130, 168, 108, 118, 184, 170, 111, 82, 64, 99, 46, 226, 62, 112, 249, 28, 149, 229, + 117, 180, 13, 110, 229, 169, 243, 131, 26, 208, 211, 224, 2, 158, 23, 53, 216, 85, 196, 16, 155, 74, 112, + 155, 199, 78, 68, 233, 101, 236, 128, 86, 161, 196, 5, 102, 56, 139, 133, 210, 43, 78, 220, 61, 2, 235, + 232, 89, 243, 42, 0, 239, 245, 67, 210, 229, 51, 43, 232, 55, 108, 139, 249, 35, 89, 165, 148, 52, 65, 7, + 49, 150, 40, 228, 28, 186, 121, 104, 152, 162, 196, 137, 93, 170, 33, 71, 27, 65, 30, 73, 81, 98, 4, 38, + 177, 8, 242, 150, 105, 31, 42, 185, 252, 47, 88, 144, 50, 237, 39, 71, 27, 105, 155, 175, 156, 223, 192, + 71, 95, 249, 136, 144, 40, 86, 207, 159, 88, 168, 93, 32, 222, 139, 222, 126, 135, 253, 231, 242, 158, 115, + 246, 140, 120, 74, 133, 181, 162, 29, 236, 214, 108, 236, 224, 169, 219, 186, 89, 29, 155, 247, 65, 55, + 156, 157, 84, 57, 135, 67, 93, 149, 113, 106, 116, 177, 35, 47, 115, 139, 235, 1, 92, 102, 233, 36, 72, 0, + 119, 33, 142, 64, 34, 197, 20, 19, 85, 246, 121, 243, 203, 6, 139, 193, 10, 61, 163, 94, 178, 239, 234, 87, + 205, 58, 131, 252, 24, 192, 213, 126, 196, 223, 197, 83, 95, 140, 43, 212, 12, 136, 135, 96, 2, 200, 232, + 98, 54, 80, 17, 26, 211, 22, 210, 201, 66, 161, 246, 89, 166, 200, 189, 102, 179, 190, 170, 112, 12, 254, + 74, 104, 166, 7, 114, 117, 161, 85, 43, 215, 31, 74, 47, 17, 195, 173, 112, 145, 253, 14, 54, 216, 210, + 204, 112, 61, 237, 168, 228, 213, 90, 179, 52, 20, 22, 234, 190, 237, 53, 246, 211, 85, 124, 55, 10, 31, + 94, 143, 23, 151, 208, 98, 99, 132, 197, 59, 57, 91, 129, 176, 134, 71, 182, 40, 76, 146, 41, 188, 206, + 242, 161, 248, 56, 49, 26, 162, 143, 140, 102, 74, 154, 184, 49, 19, 156, 29, 52, 33, 161, 38, 156, 129, + 236, 136, 67, 161, 120, 15, 4, 50, 86, 188, 78, 80, 74, 65, 162, 58, 234, 100, 245, 79, 208, 150, 18, 108, + 85, 237, 239, 19, 225, 142, 41, 52, 131, 204, 158, 62, 115, 114, 107, 104, 160, 49, 210, 241, 69, 140, 160, + 227, 165, 43, 82, 189, 145, 181, 117, 62, 49, 221, 156, 187, 215, 230, 114, 200, 52, 104, 0, 194, 4, 9, + 232, 247, 149, 66, 103, 80, 66, 26, 118, 139, 86, 240, 219, 133, 97, 185, 90, 194, 105, 70, 224, 58, 194, + 114, 102, 5, 246, 142, 51, 83, 78, 80, 241, 26, 19, 73, 119, 221, 254, 128, 109, 128, 38, 240, 66, 30, 184, + 186, 25, 192, 240, 222, 243, 136, 68, 114, 128, 27, 195, 7, 251, 191, 255, 217 + ); + CAsset6 : Array[0..263171] Of Byte = ( + 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 2, 88, 0, 0, 2, 80, 8, 6, 0, 0, 0, 82, + 53, 26, 177, 0, 0, 0, 4, 115, 66, 73, 84, 8, 8, 8, 8, 124, 8, 100, 136, 0, 0, 0, 9, 112, 72, 89, 115, 0, 0, + 11, 18, 0, 0, 11, 18, 1, 210, 221, 126, 252, 0, 0, 0, 28, 116, 69, 88, 116, 83, 111, 102, 116, 119, 97, + 114, 101, 0, 65, 100, 111, 98, 101, 32, 70, 105, 114, 101, 119, 111, 114, 107, 115, 32, 67, 83, 52, 6, 178, + 211, 160, 0, 0, 14, 236, 112, 114, 86, 87, 120, 156, 229, 91, 221, 146, 212, 184, 21, 62, 216, 179, 2, 185, + 193, 29, 75, 241, 216, 219, 185, 161, 106, 43, 149, 171, 77, 96, 122, 6, 216, 75, 22, 216, 13, 21, 96, 183, + 138, 205, 38, 185, 162, 96, 232, 1, 54, 252, 21, 51, 75, 106, 67, 205, 131, 240, 50, 121, 128, 212, 188, + 75, 222, 32, 201, 57, 71, 63, 150, 100, 187, 127, 102, 171, 38, 23, 81, 183, 221, 110, 89, 210, 119, 254, + 37, 217, 210, 63, 255, 253, 143, 127, 193, 91, 120, 243, 31, 76, 39, 248, 61, 161, 19, 255, 156, 80, 250, + 136, 159, 147, 143, 31, 79, 14, 14, 78, 230, 243, 147, 57, 156, 192, 252, 4, 224, 35, 223, 160, 116, 112, + 240, 113, 62, 255, 56, 135, 143, 0, 7, 152, 230, 243, 3, 128, 57, 38, 0, 248, 18, 94, 194, 143, 240, 238, + 248, 246, 173, 239, 15, 63, 192, 57, 216, 61, 198, 116, 231, 171, 123, 239, 63, 220, 186, 249, 29, 230, 76, + 225, 33, 60, 135, 199, 240, 20, 222, 192, 223, 224, 50, 94, 189, 198, 235, 203, 240, 53, 214, 195, 156, + 227, 187, 15, 238, 219, 82, 111, 48, 231, 5, 223, 11, 107, 252, 150, 62, 199, 119, 190, 125, 248, 254, 195, + 237, 91, 119, 232, 244, 7, 44, 63, 129, 59, 112, 128, 159, 5, 236, 195, 17, 220, 199, 146, 143, 225, 46, + 220, 182, 84, 252, 26, 62, 192, 19, 248, 2, 174, 224, 221, 47, 96, 15, 127, 23, 240, 57, 92, 131, 93, 108, + 243, 0, 175, 174, 226, 231, 41, 220, 192, 171, 199, 248, 57, 128, 29, 44, 65, 159, 199, 92, 250, 6, 254, + 63, 128, 235, 88, 98, 23, 144, 151, 0, 245, 55, 240, 10, 254, 138, 45, 127, 133, 116, 190, 196, 54, 31, + 193, 159, 224, 29, 94, 31, 225, 245, 55, 200, 215, 75, 248, 9, 243, 190, 195, 127, 175, 72, 216, 120, 239, + 49, 30, 63, 69, 180, 254, 17, 203, 63, 192, 252, 87, 176, 176, 212, 174, 226, 61, 164, 224, 87, 200, 235, + 151, 136, 113, 192, 20, 16, 238, 59, 252, 247, 22, 207, 11, 120, 143, 121, 11, 172, 245, 8, 243, 29, 125, + 135, 120, 245, 119, 143, 244, 9, 243, 126, 153, 206, 81, 171, 23, 16, 239, 5, 150, 61, 98, 237, 236, 251, + 242, 25, 150, 222, 137, 74, 126, 130, 119, 223, 176, 230, 156, 198, 37, 124, 198, 220, 185, 15, 202, 49, + 169, 65, 109, 62, 35, 122, 124, 171, 187, 176, 151, 88, 201, 69, 184, 137, 52, 252, 128, 150, 68, 84, 92, + 134, 91, 30, 197, 216, 199, 4, 239, 255, 136, 119, 222, 224, 189, 123, 204, 235, 2, 239, 31, 110, 108, 23, + 103, 157, 82, 187, 56, 123, 252, 216, 30, 206, 58, 61, 99, 203, 92, 192, 107, 171, 129, 179, 78, 231, 18, + 107, 60, 235, 68, 50, 127, 142, 210, 127, 134, 231, 71, 40, 139, 51, 199, 247, 113, 217, 200, 225, 172, + 241, 157, 220, 47, 162, 119, 47, 208, 183, 79, 155, 170, 234, 116, 245, 28, 247, 46, 222, 157, 18, 189, + 153, 205, 26, 113, 154, 154, 207, 224, 201, 113, 72, 195, 105, 218, 16, 136, 62, 107, 103, 179, 237, 83, + 80, 240, 243, 237, 159, 208, 91, 76, 76, 65, 182, 105, 237, 67, 252, 252, 142, 163, 249, 107, 140, 66, 155, + 219, 191, 216, 158, 49, 188, 57, 102, 159, 170, 13, 235, 47, 176, 63, 218, 193, 94, 253, 42, 254, 62, 197, + 190, 125, 67, 116, 101, 120, 247, 105, 54, 251, 116, 51, 67, 36, 191, 63, 66, 222, 23, 86, 18, 155, 162, + 199, 240, 134, 2, 185, 65, 27, 78, 239, 83, 238, 183, 95, 111, 2, 175, 156, 222, 227, 163, 221, 200, 21, + 210, 30, 125, 237, 84, 17, 250, 172, 117, 36, 204, 186, 31, 162, 64, 173, 75, 1, 141, 243, 230, 56, 222, + 161, 209, 224, 14, 142, 5, 54, 67, 151, 82, 86, 109, 131, 231, 70, 211, 111, 219, 202, 198, 105, 97, 77, + 51, 72, 71, 132, 235, 161, 55, 86, 237, 32, 85, 38, 21, 84, 18, 52, 180, 10, 84, 11, 77, 103, 7, 107, 81, + 64, 62, 247, 35, 246, 2, 46, 6, 172, 81, 69, 54, 222, 234, 160, 82, 89, 165, 179, 89, 11, 74, 86, 50, 147, + 149, 8, 45, 177, 89, 131, 130, 120, 20, 183, 134, 229, 138, 38, 176, 121, 144, 2, 26, 133, 160, 160, 85, + 38, 148, 200, 84, 236, 10, 171, 13, 113, 193, 227, 250, 46, 10, 108, 130, 78, 176, 51, 146, 63, 82, 209, + 54, 144, 205, 50, 232, 57, 227, 170, 136, 120, 139, 230, 70, 60, 90, 61, 228, 209, 252, 210, 148, 109, 39, + 254, 94, 52, 173, 86, 90, 73, 165, 219, 182, 210, 173, 82, 109, 154, 144, 130, 165, 77, 62, 98, 171, 123, + 193, 209, 247, 240, 248, 235, 111, 151, 241, 158, 6, 187, 245, 210, 114, 67, 252, 243, 189, 91, 7, 31, 118, + 246, 246, 142, 255, 98, 46, 198, 209, 171, 246, 52, 232, 76, 193, 18, 67, 140, 185, 191, 247, 126, 172, + 156, 106, 58, 244, 186, 65, 113, 235, 6, 127, 26, 173, 233, 26, 181, 128, 63, 26, 127, 155, 26, 239, 240, + 77, 60, 66, 10, 198, 12, 241, 49, 143, 189, 41, 242, 154, 185, 220, 112, 41, 249, 105, 200, 59, 250, 26, + 126, 53, 158, 181, 64, 221, 139, 186, 146, 13, 254, 23, 104, 10, 66, 227, 111, 171, 42, 73, 5, 34, 25, 140, + 12, 14, 158, 242, 124, 246, 138, 159, 199, 14, 149, 241, 225, 166, 173, 249, 32, 100, 129, 102, 167, 170, + 186, 106, 171, 90, 41, 137, 144, 90, 9, 132, 174, 144, 0, 161, 148, 41, 224, 202, 155, 99, 56, 38, 175, + 230, 95, 58, 244, 218, 157, 20, 37, 100, 190, 146, 173, 108, 139, 170, 42, 42, 252, 175, 81, 38, 200, 62, + 50, 78, 238, 64, 5, 180, 175, 228, 148, 48, 48, 56, 224, 232, 19, 204, 129, 211, 251, 194, 162, 215, 65, + 91, 53, 11, 161, 213, 214, 24, 234, 4, 135, 254, 24, 51, 168, 219, 184, 238, 128, 33, 46, 31, 127, 25, 244, + 218, 125, 253, 47, 95, 107, 78, 246, 167, 49, 23, 20, 14, 180, 142, 75, 70, 74, 72, 13, 49, 157, 23, 71, + 232, 106, 214, 111, 161, 246, 28, 86, 40, 114, 84, 51, 6, 254, 74, 241, 25, 229, 79, 121, 178, 74, 73, 93, + 66, 65, 250, 188, 196, 99, 227, 209, 206, 122, 124, 116, 226, 109, 235, 74, 43, 212, 188, 68, 69, 55, 146, + 244, 77, 102, 32, 155, 2, 221, 67, 155, 34, 93, 157, 58, 104, 3, 59, 43, 211, 60, 167, 244, 233, 72, 136, + 223, 116, 173, 212, 173, 200, 68, 38, 11, 165, 93, 115, 248, 65, 183, 231, 11, 77, 70, 80, 179, 37, 216, + 124, 143, 173, 181, 148, 34, 203, 132, 14, 180, 216, 132, 248, 233, 147, 137, 16, 95, 7, 240, 173, 187, + 145, 73, 214, 47, 25, 152, 20, 181, 187, 29, 252, 8, 233, 192, 148, 244, 157, 79, 27, 52, 165, 67, 252, + 244, 137, 85, 136, 175, 60, 167, 212, 88, 51, 243, 149, 164, 194, 255, 212, 182, 136, 72, 52, 240, 68, 35, + 214, 212, 194, 131, 55, 51, 21, 146, 168, 66, 252, 244, 41, 85, 136, 47, 61, 56, 139, 45, 28, 28, 184, 198, + 179, 128, 194, 218, 193, 243, 141, 160, 112, 214, 132, 140, 180, 50, 196, 159, 218, 121, 231, 145, 157, + 135, 15, 226, 179, 212, 134, 59, 114, 25, 18, 96, 218, 30, 72, 42, 44, 20, 225, 243, 51, 78, 196, 126, 194, + 79, 73, 23, 62, 254, 81, 1, 17, 214, 26, 110, 24, 160, 8, 9, 24, 157, 253, 88, 46, 184, 144, 8, 224, 3, + 251, 155, 162, 20, 130, 241, 167, 176, 181, 220, 39, 97, 187, 235, 212, 117, 39, 37, 47, 35, 236, 22, 226, + 242, 58, 32, 192, 181, 206, 201, 201, 222, 201, 33, 194, 215, 174, 142, 49, 218, 46, 225, 136, 179, 117, + 113, 36, 235, 154, 182, 57, 162, 65, 39, 143, 227, 156, 118, 204, 39, 230, 31, 204, 191, 115, 28, 1, 6, + 195, 15, 227, 0, 190, 233, 8, 95, 80, 136, 241, 29, 90, 225, 202, 24, 233, 103, 219, 228, 247, 216, 5, 135, + 53, 148, 41, 211, 51, 127, 160, 49, 239, 51, 126, 218, 251, 10, 207, 9, 255, 210, 195, 215, 21, 142, 64, + 218, 118, 187, 83, 112, 166, 180, 237, 207, 114, 39, 88, 35, 253, 74, 227, 128, 208, 23, 171, 26, 28, 148, + 108, 27, 51, 53, 229, 34, 243, 3, 163, 251, 142, 134, 8, 95, 88, 170, 241, 100, 39, 54, 179, 88, 15, 38, + 73, 83, 166, 24, 184, 165, 76, 239, 217, 72, 7, 111, 168, 236, 240, 141, 214, 187, 167, 128, 17, 1, 153, + 67, 175, 57, 186, 240, 245, 208, 32, 194, 48, 54, 224, 160, 194, 213, 106, 189, 252, 99, 243, 231, 200, 67, + 179, 79, 243, 228, 248, 102, 88, 23, 172, 217, 56, 18, 76, 3, 67, 30, 174, 58, 237, 15, 74, 166, 238, 26, + 73, 204, 143, 231, 29, 215, 241, 124, 21, 71, 97, 244, 30, 34, 198, 47, 218, 58, 108, 96, 12, 38, 163, 2, + 67, 130, 177, 106, 15, 219, 136, 205, 47, 225, 62, 156, 127, 219, 8, 152, 52, 96, 180, 44, 146, 67, 215, + 198, 65, 210, 124, 101, 43, 6, 109, 196, 230, 135, 49, 119, 225, 103, 127, 5, 246, 66, 1, 62, 41, 170, 78, + 19, 201, 63, 69, 97, 71, 41, 6, 243, 219, 94, 3, 2, 68, 136, 191, 99, 223, 235, 144, 30, 118, 97, 63, 20, + 158, 101, 172, 87, 223, 202, 188, 147, 126, 78, 116, 166, 249, 25, 53, 208, 167, 63, 81, 63, 247, 187, 230, + 125, 215, 29, 60, 63, 139, 240, 177, 225, 34, 101, 64, 3, 219, 47, 222, 130, 60, 163, 175, 160, 19, 210, + 233, 243, 249, 139, 183, 58, 5, 132, 73, 197, 236, 123, 217, 111, 217, 247, 116, 17, 255, 89, 46, 211, 250, + 70, 252, 6, 203, 52, 196, 39, 165, 156, 200, 4, 11, 196, 156, 6, 4, 32, 141, 98, 125, 122, 138, 50, 191, 2, + 115, 156, 123, 31, 167, 207, 159, 5, 17, 224, 216, 238, 196, 231, 252, 215, 2, 80, 57, 73, 49, 175, 146, + 34, 55, 50, 33, 120, 186, 162, 11, 149, 52, 144, 39, 252, 167, 239, 204, 70, 12, 64, 42, 167, 125, 150, + 171, 80, 219, 78, 16, 216, 217, 208, 56, 149, 135, 182, 216, 235, 177, 70, 112, 128, 180, 157, 177, 252, + 50, 176, 240, 153, 21, 127, 22, 171, 31, 210, 247, 83, 49, 190, 0, 171, 0, 33, 44, 188, 81, 120, 46, 49, + 166, 86, 220, 190, 80, 157, 115, 105, 22, 25, 207, 152, 42, 99, 6, 185, 213, 128, 173, 223, 19, 63, 164, + 239, 45, 35, 124, 132, 18, 142, 111, 197, 181, 133, 181, 49, 242, 184, 86, 229, 140, 144, 89, 217, 104, 73, + 148, 101, 60, 108, 44, 88, 13, 134, 26, 99, 117, 174, 157, 88, 252, 189, 119, 149, 49, 1, 216, 154, 54, + 226, 67, 87, 80, 14, 62, 163, 174, 159, 98, 174, 2, 67, 129, 208, 134, 53, 22, 62, 201, 99, 130, 121, 74, + 8, 43, 66, 85, 96, 25, 237, 188, 39, 142, 147, 233, 219, 227, 158, 0, 100, 103, 245, 12, 38, 49, 79, 183, + 219, 76, 24, 234, 219, 50, 36, 11, 65, 212, 178, 102, 140, 184, 90, 236, 169, 112, 156, 144, 91, 143, 52, + 138, 164, 191, 49, 126, 250, 246, 56, 198, 199, 6, 89, 112, 100, 220, 220, 188, 192, 161, 149, 34, 225, 55, + 146, 229, 106, 224, 5, 155, 37, 221, 181, 122, 66, 163, 68, 153, 99, 159, 45, 140, 124, 100, 85, 41, 22, + 163, 72, 212, 223, 123, 127, 28, 167, 41, 86, 55, 49, 28, 237, 77, 177, 61, 0, 141, 188, 40, 71, 77, 172, + 60, 153, 74, 193, 252, 163, 7, 98, 113, 205, 81, 139, 230, 60, 69, 142, 55, 205, 208, 129, 90, 41, 122, + 236, 247, 222, 80, 199, 137, 228, 229, 67, 16, 26, 28, 73, 132, 134, 18, 218, 186, 180, 102, 126, 240, 91, + 169, 156, 238, 225, 23, 115, 75, 6, 211, 173, 49, 183, 170, 245, 49, 20, 13, 40, 97, 127, 233, 252, 23, + 184, 184, 208, 37, 86, 45, 153, 2, 38, 96, 82, 187, 255, 228, 87, 198, 75, 116, 107, 249, 183, 126, 110, + 238, 51, 191, 173, 255, 63, 201, 123, 226, 31, 157, 255, 58, 2, 176, 213, 194, 86, 167, 3, 21, 34, 164, + 107, 190, 100, 199, 34, 17, 33, 175, 186, 98, 248, 202, 228, 155, 242, 88, 155, 50, 74, 251, 173, 250, 236, + 35, 254, 27, 255, 4, 134, 102, 33, 67, 2, 240, 232, 37, 187, 188, 240, 2, 40, 113, 56, 70, 2, 98, 9, 163, + 89, 8, 246, 196, 210, 149, 39, 155, 197, 57, 140, 255, 47, 250, 236, 247, 214, 27, 244, 240, 51, 18, 64, + 233, 120, 104, 37, 217, 154, 229, 135, 154, 213, 36, 251, 186, 40, 36, 13, 213, 114, 161, 28, 97, 120, 158, + 16, 241, 170, 43, 139, 198, 8, 189, 231, 47, 233, 202, 145, 1, 1, 24, 60, 243, 161, 16, 219, 53, 74, 2, 80, + 170, 45, 101, 78, 129, 66, 215, 120, 221, 149, 68, 103, 199, 178, 109, 71, 170, 200, 250, 226, 135, 116, + 229, 72, 31, 31, 5, 48, 233, 240, 140, 18, 59, 20, 180, 117, 205, 64, 44, 234, 142, 208, 146, 172, 45, 67, + 121, 148, 46, 175, 224, 82, 99, 248, 174, 15, 236, 165, 169, 8, 241, 74, 22, 0, 250, 96, 151, 97, 128, 40, + 10, 56, 71, 49, 144, 57, 149, 107, 61, 157, 181, 24, 130, 231, 181, 49, 63, 249, 117, 31, 59, 125, 124, 43, + 128, 78, 172, 138, 4, 80, 132, 4, 176, 91, 199, 68, 149, 70, 250, 122, 21, 251, 24, 117, 226, 30, 160, 79, + 64, 149, 179, 0, 108, 187, 168, 113, 211, 178, 71, 42, 235, 134, 250, 4, 33, 155, 16, 95, 101, 206, 78, + 236, 135, 192, 7, 30, 67, 167, 235, 135, 134, 5, 128, 252, 122, 10, 234, 38, 75, 53, 208, 226, 84, 80, 183, + 29, 65, 165, 177, 125, 118, 253, 114, 41, 251, 144, 174, 28, 26, 72, 21, 214, 147, 161, 104, 85, 110, 156, + 210, 53, 94, 242, 236, 179, 236, 50, 152, 219, 156, 165, 239, 178, 152, 139, 129, 198, 143, 188, 238, 231, + 252, 36, 116, 80, 0, 34, 128, 43, 57, 8, 96, 206, 196, 53, 30, 252, 186, 75, 86, 145, 170, 147, 140, 33, + 252, 116, 117, 208, 160, 0, 200, 188, 9, 174, 116, 4, 112, 36, 179, 4, 4, 135, 163, 193, 116, 123, 109, + 119, 79, 103, 195, 214, 111, 198, 159, 225, 51, 184, 161, 148, 77, 51, 86, 120, 135, 160, 153, 157, 139, 9, + 124, 217, 193, 83, 228, 9, 8, 26, 101, 127, 244, 249, 91, 172, 129, 41, 153, 160, 107, 158, 244, 173, 136, + 195, 11, 23, 235, 178, 71, 66, 93, 78, 40, 22, 136, 90, 119, 153, 236, 178, 195, 239, 31, 214, 145, 191, 9, + 194, 34, 84, 51, 71, 129, 173, 11, 195, 240, 206, 243, 93, 97, 114, 6, 49, 242, 10, 104, 29, 249, 131, 143, + 47, 157, 144, 235, 138, 117, 92, 246, 36, 48, 225, 128, 165, 155, 78, 90, 101, 53, 206, 126, 111, 189, 222, + 18, 1, 176, 197, 123, 143, 50, 78, 32, 7, 185, 207, 173, 233, 155, 60, 54, 135, 177, 55, 96, 247, 113, 238, + 123, 136, 220, 187, 40, 184, 140, 0, 236, 248, 67, 27, 224, 152, 47, 39, 117, 159, 123, 19, 247, 108, 222, + 100, 36, 242, 153, 20, 206, 253, 150, 189, 127, 230, 118, 101, 192, 21, 141, 61, 88, 2, 147, 0, 158, 89, + 141, 225, 57, 20, 201, 209, 247, 192, 29, 239, 43, 214, 255, 84, 196, 109, 17, 9, 187, 101, 9, 4, 113, 128, + 252, 222, 10, 223, 231, 73, 202, 155, 142, 54, 155, 174, 196, 28, 77, 70, 3, 69, 20, 110, 120, 48, 144, 99, + 166, 135, 18, 185, 136, 116, 111, 36, 50, 29, 127, 9, 253, 5, 92, 91, 115, 253, 15, 219, 176, 55, 1, 43, 1, + 230, 142, 221, 128, 245, 140, 97, 2, 135, 67, 161, 66, 40, 175, 50, 51, 242, 193, 180, 150, 255, 7, 2, 16, + 191, 244, 205, 115, 103, 172, 114, 99, 153, 86, 245, 118, 252, 25, 199, 130, 101, 139, 0, 214, 243, 127, + 147, 42, 106, 234, 66, 28, 108, 113, 60, 196, 179, 31, 177, 69, 210, 193, 49, 64, 40, 124, 246, 134, 81, + 215, 227, 180, 158, 255, 7, 4, 248, 48, 228, 34, 97, 67, 106, 223, 250, 132, 99, 92, 27, 195, 203, 101, + 158, 111, 146, 89, 245, 123, 128, 81, 224, 37, 90, 224, 98, 228, 253, 179, 77, 38, 12, 201, 68, 2, 244, + 172, 129, 109, 67, 181, 113, 143, 200, 6, 177, 98, 13, 200, 216, 251, 175, 17, 2, 168, 35, 18, 62, 12, 56, + 17, 108, 211, 60, 177, 170, 99, 248, 139, 204, 253, 116, 197, 10, 144, 177, 247, 95, 99, 4, 144, 199, 129, + 12, 58, 219, 210, 136, 64, 210, 208, 191, 12, 252, 222, 140, 120, 170, 85, 11, 226, 210, 245, 217, 171, 9, + 32, 29, 200, 142, 251, 210, 14, 1, 131, 193, 14, 29, 151, 206, 147, 69, 84, 43, 215, 191, 72, 142, 128, + 180, 6, 105, 127, 189, 245, 87, 44, 1, 219, 239, 132, 161, 40, 176, 73, 99, 249, 91, 153, 248, 197, 185, + 149, 205, 165, 235, 177, 215, 33, 128, 199, 191, 186, 63, 242, 9, 225, 243, 181, 184, 135, 222, 58, 253, + 181, 8, 224, 56, 27, 71, 194, 232, 40, 172, 229, 175, 102, 127, 249, 243, 175, 81, 2, 120, 194, 85, 164, + 195, 207, 14, 158, 66, 210, 58, 220, 199, 207, 159, 228, 186, 235, 111, 5, 119, 134, 98, 96, 244, 99, 58, + 220, 173, 11, 91, 171, 252, 222, 165, 55, 188, 238, 177, 155, 131, 173, 79, 128, 240, 131, 242, 232, 176, + 33, 127, 61, 238, 1, 118, 81, 234, 225, 28, 108, 189, 90, 64, 0, 52, 7, 40, 226, 136, 135, 125, 176, 25, + 21, 45, 233, 113, 227, 180, 252, 249, 219, 146, 84, 217, 96, 28, 154, 97, 109, 34, 190, 144, 211, 53, 44, + 207, 164, 93, 187, 179, 133, 118, 77, 220, 57, 190, 251, 96, 51, 2, 120, 42, 238, 99, 49, 50, 159, 83, 222, + 186, 178, 167, 116, 13, 246, 240, 152, 35, 29, 87, 249, 188, 65, 50, 70, 144, 179, 35, 16, 124, 65, 215, + 232, 118, 155, 192, 131, 217, 161, 114, 159, 247, 225, 60, 217, 100, 253, 41, 88, 35, 200, 172, 18, 38, 98, + 51, 195, 179, 233, 14, 198, 222, 5, 175, 126, 53, 251, 158, 54, 75, 214, 10, 145, 2, 201, 188, 111, 12, + 207, 107, 31, 105, 63, 211, 85, 248, 28, 227, 208, 141, 13, 241, 129, 196, 109, 158, 80, 80, 64, 216, 24, + 29, 122, 251, 159, 54, 78, 172, 4, 51, 10, 173, 150, 142, 244, 134, 83, 186, 255, 233, 20, 137, 44, 142, + 36, 63, 93, 50, 204, 29, 77, 233, 62, 164, 211, 16, 64, 20, 76, 55, 23, 61, 167, 116, 127, 218, 41, 211, + 41, 36, 111, 82, 186, 35, 237, 172, 211, 62, 175, 252, 28, 121, 255, 115, 6, 105, 233, 251, 159, 51, 72, + 151, 163, 241, 215, 225, 233, 236, 239, 103, 164, 125, 212, 125, 188, 211, 83, 210, 58, 16, 204, 125, 192, + 43, 51, 105, 85, 204, 203, 129, 93, 124, 95, 242, 110, 191, 35, 126, 111, 241, 144, 247, 37, 30, 245, 246, + 50, 173, 191, 23, 244, 58, 223, 189, 198, 251, 62, 105, 37, 0, 237, 5, 221, 199, 156, 29, 191, 23, 148, + 226, 227, 13, 204, 187, 142, 119, 76, 143, 185, 215, 91, 187, 17, 63, 203, 149, 142, 47, 244, 49, 218, 185, + 121, 4, 207, 61, 125, 123, 73, 201, 135, 92, 242, 45, 34, 126, 135, 209, 240, 237, 18, 78, 194, 221, 159, + 221, 30, 72, 83, 250, 60, 124, 102, 105, 187, 210, 219, 101, 89, 160, 196, 220, 174, 200, 148, 30, 218, + 197, 153, 150, 190, 103, 247, 164, 29, 193, 205, 100, 119, 102, 206, 61, 245, 94, 66, 215, 239, 217, 127, + 77, 36, 25, 162, 43, 216, 1, 154, 32, 17, 71, 196, 205, 55, 216, 255, 254, 96, 116, 228, 163, 113, 55, 47, + 141, 229, 213, 241, 146, 202, 107, 247, 12, 246, 227, 110, 121, 139, 13, 177, 166, 81, 173, 187, 72, 245, + 247, 188, 103, 246, 5, 143, 43, 186, 186, 233, 142, 11, 170, 123, 41, 224, 168, 219, 11, 69, 79, 230, 186, + 231, 227, 215, 18, 153, 95, 234, 52, 195, 251, 131, 15, 186, 125, 68, 193, 251, 148, 184, 206, 69, 255, + 188, 111, 172, 70, 186, 159, 247, 146, 93, 151, 66, 150, 249, 156, 103, 169, 135, 172, 175, 151, 240, 244, + 56, 221, 59, 231, 106, 116, 182, 115, 123, 112, 215, 112, 206, 94, 22, 91, 92, 229, 189, 197, 120, 243, + 187, 209, 218, 169, 79, 144, 220, 95, 161, 140, 205, 76, 226, 43, 44, 189, 63, 96, 131, 50, 246, 141, 30, + 254, 37, 182, 224, 35, 94, 5, 179, 224, 145, 216, 80, 11, 225, 62, 230, 121, 98, 201, 211, 192, 139, 239, + 163, 134, 95, 114, 159, 246, 150, 189, 98, 17, 236, 127, 143, 165, 85, 34, 151, 196, 245, 235, 21, 200, 33, + 229, 125, 228, 111, 56, 26, 210, 252, 49, 182, 163, 212, 11, 159, 154, 253, 215, 134, 251, 104, 127, 245, + 121, 182, 219, 52, 22, 159, 255, 159, 249, 241, 149, 51, 240, 227, 9, 122, 233, 107, 246, 128, 119, 216, + 15, 122, 90, 206, 212, 171, 175, 111, 236, 213, 231, 96, 190, 145, 79, 167, 178, 92, 199, 163, 211, 26, + 255, 63, 30, 253, 95, 64, 253, 158, 70, 139, 88, 133, 229, 0, 0, 0, 72, 109, 107, 66, 70, 250, 222, 202, + 254, 0, 0, 0, 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, 41, + 164, 51, 161, 0, 0, 62, 205, 109, 107, 84, 83, 120, 156, 237, 125, 235, 115, 219, 198, 146, 47, 78, 78, 28, + 91, 126, 198, 201, 214, 217, 186, 181, 95, 84, 181, 187, 117, 63, 197, 7, 111, 146, 247, 27, 31, 162, 164, + 152, 146, 120, 72, 202, 150, 83, 91, 229, 2, 65, 34, 214, 70, 126, 172, 36, 43, 199, 203, 194, 255, 126, + 187, 123, 102, 240, 24, 14, 64, 0, 162, 94, 54, 172, 132, 3, 98, 6, 192, 224, 215, 61, 191, 238, 233, 121, + 112, 239, 101, 231, 98, 241, 106, 52, 62, 94, 120, 225, 171, 209, 222, 241, 194, 8, 251, 163, 110, 34, 25, + 253, 99, 255, 120, 97, 55, 117, 195, 15, 12, 35, 60, 26, 116, 131, 133, 30, 190, 97, 201, 235, 221, 94, + 176, 112, 117, 61, 220, 217, 157, 4, 11, 167, 101, 134, 163, 173, 113, 176, 104, 64, 58, 62, 60, 134, 2, + 157, 109, 184, 71, 64, 255, 194, 225, 96, 112, 177, 232, 12, 225, 163, 219, 158, 156, 45, 180, 13, 109, + 170, 249, 218, 91, 109, 168, 205, 181, 15, 112, 116, 172, 157, 132, 187, 251, 123, 144, 243, 16, 114, 62, + 64, 142, 161, 253, 2, 185, 199, 218, 63, 161, 196, 73, 56, 234, 29, 76, 241, 150, 237, 125, 186, 115, 27, + 170, 108, 205, 155, 97, 167, 183, 139, 213, 236, 236, 65, 221, 3, 72, 232, 77, 58, 227, 45, 42, 52, 238, + 83, 222, 120, 135, 146, 206, 128, 78, 118, 94, 82, 210, 221, 231, 55, 216, 234, 211, 247, 209, 132, 10, + 245, 59, 244, 173, 63, 162, 100, 159, 157, 28, 15, 143, 23, 45, 55, 236, 76, 88, 230, 132, 221, 125, 50, + 102, 15, 217, 99, 247, 99, 201, 110, 27, 107, 185, 143, 181, 210, 195, 222, 129, 113, 188, 104, 66, 98, + 226, 109, 122, 7, 22, 37, 125, 56, 105, 66, 98, 178, 196, 194, 36, 44, 132, 204, 191, 170, 144, 209, 54, + 181, 54, 156, 61, 135, 239, 191, 192, 209, 9, 164, 158, 118, 6, 57, 179, 235, 196, 204, 184, 36, 102, 198, + 85, 97, 246, 136, 99, 182, 173, 157, 2, 46, 159, 180, 119, 144, 119, 174, 205, 115, 177, 177, 25, 54, 243, + 28, 108, 116, 37, 54, 190, 159, 194, 70, 207, 193, 198, 111, 50, 108, 44, 179, 52, 58, 134, 205, 224, 241, + 24, 60, 30, 131, 167, 201, 224, 105, 50, 120, 154, 225, 120, 248, 27, 60, 101, 26, 142, 199, 60, 29, 30, 0, + 106, 142, 7, 39, 248, 65, 49, 0, 159, 115, 0, 187, 218, 71, 80, 174, 143, 0, 35, 168, 22, 40, 93, 178, 100, + 18, 76, 184, 49, 161, 105, 58, 121, 104, 122, 5, 208, 148, 52, 45, 15, 77, 73, 211, 188, 245, 182, 78, 130, + 208, 117, 21, 16, 142, 135, 29, 150, 51, 102, 105, 18, 210, 7, 28, 210, 14, 181, 199, 99, 205, 231, 128, + 62, 227, 128, 142, 1, 204, 0, 116, 113, 83, 27, 193, 209, 103, 56, 55, 91, 217, 106, 149, 88, 26, 129, 189, + 222, 118, 107, 249, 21, 219, 173, 87, 182, 221, 174, 194, 104, 7, 206, 159, 146, 186, 93, 18, 163, 53, 91, + 131, 18, 8, 233, 87, 131, 208, 227, 37, 132, 6, 144, 251, 225, 170, 152, 237, 78, 98, 19, 183, 176, 202, + 216, 200, 109, 171, 12, 58, 55, 220, 182, 4, 165, 247, 8, 157, 119, 212, 110, 24, 62, 63, 114, 124, 18, 57, + 244, 13, 91, 216, 20, 72, 62, 31, 39, 243, 150, 114, 144, 121, 77, 56, 77, 160, 189, 29, 131, 39, 113, 87, + 113, 178, 214, 142, 211, 51, 37, 78, 59, 144, 122, 218, 133, 246, 229, 78, 90, 52, 35, 237, 107, 57, 12, + 38, 135, 193, 228, 49, 152, 60, 6, 147, 218, 147, 90, 134, 233, 105, 6, 76, 68, 224, 229, 85, 233, 198, + 105, 219, 200, 81, 36, 135, 33, 228, 48, 132, 156, 75, 41, 82, 76, 239, 119, 177, 185, 229, 161, 84, 173, + 185, 109, 68, 40, 125, 4, 227, 118, 126, 141, 78, 99, 174, 11, 238, 219, 21, 45, 155, 206, 160, 209, 25, + 52, 58, 131, 70, 103, 208, 232, 12, 26, 61, 5, 205, 99, 14, 77, 27, 148, 226, 20, 172, 123, 7, 62, 63, 35, + 72, 28, 160, 7, 28, 160, 98, 138, 131, 34, 77, 224, 227, 218, 12, 32, 202, 95, 9, 80, 211, 206, 1, 136, + 250, 118, 9, 136, 102, 151, 244, 140, 76, 134, 144, 201, 16, 178, 25, 66, 54, 67, 200, 102, 29, 62, 20, + 107, 170, 199, 135, 175, 65, 221, 21, 56, 81, 6, 67, 209, 111, 158, 128, 122, 253, 19, 148, 236, 51, 235, + 248, 229, 35, 169, 108, 131, 249, 64, 26, 45, 14, 165, 57, 205, 235, 60, 203, 80, 150, 234, 62, 87, 6, 211, + 108, 21, 3, 243, 41, 7, 179, 11, 10, 119, 66, 33, 152, 223, 163, 112, 195, 23, 73, 41, 255, 1, 80, 30, 99, + 169, 20, 148, 182, 195, 176, 52, 166, 34, 62, 99, 167, 3, 52, 58, 3, 211, 207, 195, 50, 240, 138, 52, 91, + 210, 217, 4, 148, 46, 111, 183, 120, 117, 185, 134, 107, 54, 11, 67, 105, 53, 121, 55, 218, 50, 102, 49, + 150, 101, 49, 252, 129, 99, 248, 26, 84, 241, 60, 133, 95, 99, 198, 240, 107, 72, 240, 73, 164, 151, 231, + 204, 227, 165, 41, 244, 204, 213, 164, 87, 217, 155, 47, 10, 93, 135, 199, 112, 58, 151, 210, 57, 53, 17, + 10, 204, 154, 62, 195, 108, 190, 38, 47, 67, 207, 243, 50, 204, 43, 5, 172, 44, 64, 27, 9, 128, 222, 195, + 241, 71, 237, 99, 126, 212, 148, 171, 149, 97, 21, 142, 46, 24, 186, 93, 222, 152, 58, 58, 131, 137, 172, + 52, 2, 21, 228, 133, 180, 214, 211, 42, 171, 98, 55, 130, 220, 41, 97, 247, 33, 87, 189, 140, 214, 122, + 245, 235, 38, 26, 100, 18, 163, 71, 17, 70, 239, 200, 133, 247, 1, 1, 47, 10, 155, 222, 79, 199, 32, 10, + 105, 21, 71, 134, 56, 126, 165, 139, 102, 152, 62, 135, 7, 77, 96, 65, 120, 220, 57, 215, 43, 188, 24, 1, + 162, 192, 105, 49, 187, 89, 80, 175, 70, 160, 78, 230, 124, 14, 7, 157, 101, 146, 207, 199, 76, 104, 84, + 151, 124, 13, 108, 145, 249, 125, 71, 9, 55, 122, 41, 5, 205, 75, 184, 53, 252, 242, 106, 101, 243, 248, + 178, 199, 245, 202, 154, 217, 235, 198, 77, 97, 37, 59, 34, 218, 204, 153, 160, 60, 146, 67, 34, 254, 243, + 213, 35, 104, 18, 146, 129, 93, 128, 216, 2, 187, 130, 2, 10, 103, 131, 3, 73, 126, 220, 250, 113, 68, 248, + 198, 194, 131, 67, 111, 131, 185, 114, 226, 96, 216, 17, 190, 156, 56, 24, 149, 134, 184, 138, 131, 172, + 246, 74, 104, 164, 36, 27, 102, 223, 44, 175, 175, 145, 123, 236, 152, 12, 103, 214, 224, 139, 1, 109, 204, + 11, 251, 38, 17, 136, 102, 160, 236, 188, 118, 201, 106, 124, 33, 219, 144, 230, 197, 17, 156, 255, 99, 69, + 4, 173, 201, 208, 106, 49, 180, 200, 111, 77, 40, 165, 126, 217, 142, 171, 205, 176, 98, 208, 224, 59, 52, + 185, 7, 76, 125, 18, 4, 11, 199, 178, 16, 45, 51, 7, 45, 135, 119, 95, 193, 188, 177, 174, 125, 139, 225, + 229, 114, 192, 92, 142, 152, 203, 117, 147, 181, 104, 60, 152, 6, 210, 136, 18, 122, 122, 163, 29, 50, 246, + 197, 192, 44, 215, 209, 77, 247, 115, 169, 191, 85, 113, 104, 164, 72, 11, 95, 70, 179, 128, 234, 89, 166, + 74, 245, 92, 142, 36, 7, 50, 11, 199, 168, 141, 11, 28, 11, 43, 229, 131, 168, 45, 227, 240, 176, 175, 253, + 81, 166, 21, 23, 2, 178, 88, 215, 76, 141, 36, 53, 102, 52, 58, 211, 181, 27, 107, 34, 75, 106, 195, 2, + 200, 81, 146, 53, 25, 143, 102, 35, 42, 24, 178, 79, 19, 17, 112, 160, 101, 130, 161, 113, 169, 169, 51, + 84, 63, 172, 119, 208, 174, 96, 220, 64, 95, 207, 132, 4, 53, 156, 238, 210, 144, 123, 135, 163, 56, 238, + 44, 15, 177, 231, 131, 149, 12, 14, 159, 2, 51, 110, 106, 123, 252, 104, 174, 157, 22, 97, 201, 50, 218, + 104, 56, 243, 34, 241, 43, 181, 15, 116, 149, 224, 177, 240, 213, 114, 103, 55, 31, 59, 17, 54, 30, 80, 63, + 229, 29, 229, 103, 161, 39, 7, 10, 124, 101, 200, 202, 204, 233, 149, 196, 142, 119, 5, 7, 242, 202, 192, + 75, 218, 145, 216, 123, 20, 186, 104, 52, 231, 21, 116, 113, 135, 227, 121, 18, 225, 42, 163, 41, 38, 123, + 144, 147, 66, 220, 168, 167, 108, 54, 115, 109, 150, 108, 182, 178, 155, 71, 254, 100, 209, 254, 177, 119, + 165, 112, 38, 161, 250, 129, 67, 117, 144, 152, 19, 243, 179, 218, 247, 227, 97, 212, 99, 114, 185, 87, 13, + 15, 54, 42, 78, 83, 40, 196, 119, 220, 181, 9, 60, 41, 140, 192, 129, 178, 167, 41, 191, 198, 86, 33, 229, + 242, 145, 47, 66, 204, 98, 105, 159, 251, 59, 52, 180, 195, 67, 243, 144, 166, 131, 165, 204, 122, 140, + 200, 88, 140, 199, 35, 110, 60, 248, 119, 52, 34, 6, 166, 212, 203, 88, 9, 244, 243, 200, 193, 57, 37, 231, + 27, 33, 30, 211, 216, 171, 199, 135, 62, 242, 185, 209, 83, 118, 172, 139, 160, 12, 61, 216, 156, 16, 170, + 239, 49, 156, 77, 238, 66, 250, 166, 212, 175, 158, 113, 119, 155, 245, 164, 86, 24, 107, 48, 75, 74, 168, + 125, 62, 167, 203, 231, 138, 233, 55, 101, 215, 7, 15, 70, 226, 96, 121, 118, 210, 40, 58, 16, 190, 58, + 202, 133, 4, 132, 2, 97, 61, 159, 241, 114, 55, 93, 37, 138, 135, 9, 81, 20, 211, 112, 175, 162, 134, 147, + 159, 179, 74, 195, 45, 201, 121, 23, 78, 146, 232, 80, 18, 133, 47, 185, 238, 70, 129, 142, 14, 158, 237, + 115, 105, 244, 153, 52, 8, 99, 82, 227, 54, 53, 42, 130, 26, 167, 125, 161, 58, 219, 110, 97, 117, 126, 20, + 5, 133, 174, 65, 133, 173, 89, 33, 21, 150, 122, 140, 145, 6, 231, 70, 28, 51, 186, 64, 54, 239, 2, 217, + 12, 73, 203, 103, 72, 82, 106, 81, 74, 72, 50, 77, 84, 106, 43, 57, 0, 168, 164, 132, 238, 136, 161, 93, + 86, 69, 199, 0, 43, 186, 248, 56, 91, 236, 172, 136, 239, 36, 194, 185, 98, 236, 207, 240, 230, 151, 29, + 251, 227, 106, 234, 72, 106, 154, 54, 88, 232, 143, 142, 105, 214, 117, 54, 184, 130, 135, 139, 130, 43, + 128, 51, 130, 200, 101, 39, 0, 37, 215, 253, 9, 199, 239, 53, 169, 225, 156, 135, 55, 104, 130, 103, 5, + 247, 61, 224, 56, 6, 105, 28, 3, 111, 77, 173, 253, 178, 102, 95, 221, 210, 77, 85, 119, 136, 249, 76, 73, + 78, 141, 122, 65, 114, 148, 124, 53, 134, 15, 34, 79, 170, 200, 92, 24, 105, 252, 52, 114, 158, 138, 141, + 213, 99, 168, 167, 100, 63, 40, 106, 236, 196, 21, 151, 10, 15, 41, 167, 31, 71, 113, 184, 184, 143, 78, + 14, 190, 56, 24, 29, 36, 244, 85, 103, 250, 42, 205, 162, 45, 142, 113, 177, 206, 187, 217, 84, 134, 224, + 168, 215, 180, 70, 132, 69, 223, 221, 18, 241, 55, 167, 56, 192, 106, 31, 213, 82, 41, 43, 77, 61, 206, + 154, 156, 172, 138, 125, 140, 56, 45, 126, 212, 222, 75, 99, 170, 125, 244, 98, 85, 208, 77, 237, 148, 33, + 18, 109, 188, 140, 37, 202, 157, 23, 79, 106, 174, 138, 199, 169, 185, 146, 27, 116, 75, 133, 156, 223, 84, + 59, 82, 45, 238, 224, 183, 120, 8, 169, 229, 50, 83, 78, 38, 93, 132, 55, 58, 177, 167, 42, 194, 29, 82, + 47, 52, 27, 196, 251, 90, 114, 74, 78, 190, 205, 177, 84, 10, 40, 141, 235, 43, 59, 72, 150, 94, 220, 243, + 39, 80, 151, 65, 156, 218, 171, 3, 154, 145, 193, 145, 2, 154, 40, 23, 66, 145, 29, 88, 236, 128, 249, 254, + 208, 189, 100, 190, 63, 30, 144, 143, 233, 234, 204, 249, 39, 251, 61, 18, 237, 157, 185, 75, 229, 48, 125, + 67, 61, 249, 124, 251, 147, 110, 212, 133, 134, 47, 10, 233, 102, 26, 212, 169, 114, 134, 147, 212, 153, + 82, 218, 159, 44, 35, 158, 21, 36, 78, 15, 4, 113, 85, 36, 51, 94, 88, 37, 133, 175, 137, 235, 54, 62, 104, + 1, 206, 152, 192, 69, 66, 42, 24, 13, 135, 55, 113, 55, 221, 196, 189, 18, 86, 220, 85, 114, 163, 174, 226, + 70, 22, 16, 174, 50, 15, 74, 48, 99, 122, 229, 139, 201, 169, 145, 82, 139, 82, 166, 114, 46, 55, 41, 178, + 221, 206, 6, 45, 246, 32, 255, 7, 232, 208, 163, 110, 125, 126, 107, 118, 170, 14, 106, 151, 48, 38, 172, + 251, 158, 232, 228, 148, 24, 181, 5, 237, 84, 182, 102, 60, 223, 231, 231, 251, 236, 124, 68, 137, 100, + 168, 27, 220, 78, 55, 88, 131, 22, 212, 72, 237, 121, 135, 117, 34, 85, 243, 201, 14, 1, 191, 15, 100, 171, + 63, 147, 15, 46, 124, 243, 123, 28, 89, 75, 235, 85, 24, 34, 107, 20, 153, 139, 87, 36, 28, 103, 165, 205, + 115, 90, 3, 225, 93, 21, 97, 145, 98, 125, 29, 179, 169, 232, 53, 238, 48, 207, 167, 12, 78, 207, 35, 115, + 124, 66, 19, 197, 202, 70, 60, 212, 241, 204, 66, 115, 25, 5, 126, 134, 178, 191, 56, 179, 83, 33, 15, 79, + 233, 138, 27, 243, 226, 29, 26, 217, 72, 43, 17, 20, 54, 101, 20, 197, 45, 150, 77, 72, 81, 72, 113, 48, + 252, 152, 150, 74, 94, 57, 164, 75, 195, 61, 150, 18, 211, 86, 51, 29, 70, 10, 148, 106, 169, 14, 101, 72, + 3, 103, 190, 90, 45, 85, 158, 143, 188, 48, 48, 14, 32, 241, 118, 158, 12, 218, 49, 244, 225, 5, 27, 14, + 51, 64, 110, 57, 240, 159, 70, 222, 249, 71, 237, 159, 228, 159, 111, 146, 47, 127, 182, 114, 21, 166, 145, + 238, 13, 209, 44, 131, 18, 243, 73, 35, 232, 237, 213, 22, 169, 242, 226, 94, 52, 57, 5, 150, 98, 82, 23, + 200, 111, 40, 134, 41, 105, 208, 131, 78, 136, 3, 17, 41, 29, 114, 163, 143, 175, 200, 2, 117, 9, 47, 64, + 142, 134, 172, 146, 194, 147, 132, 20, 208, 67, 125, 7, 234, 95, 65, 6, 107, 159, 59, 206, 233, 184, 169, + 156, 21, 136, 93, 181, 132, 222, 155, 101, 162, 35, 89, 116, 204, 252, 169, 241, 178, 79, 176, 10, 193, + 199, 145, 59, 245, 142, 102, 38, 225, 184, 201, 124, 105, 206, 155, 140, 159, 91, 53, 4, 106, 20, 31, 11, + 137, 58, 243, 150, 91, 126, 192, 93, 116, 230, 87, 173, 37, 222, 17, 125, 203, 157, 229, 190, 229, 42, 232, + 30, 198, 166, 31, 26, 255, 54, 117, 222, 255, 204, 87, 59, 101, 31, 105, 13, 86, 44, 237, 207, 251, 202, + 62, 146, 176, 97, 233, 142, 166, 113, 173, 94, 128, 128, 236, 0, 206, 159, 211, 248, 219, 170, 213, 139, + 235, 128, 204, 41, 62, 162, 36, 65, 214, 90, 221, 5, 18, 83, 59, 36, 223, 125, 77, 128, 253, 141, 3, 246, + 138, 198, 38, 124, 90, 202, 120, 70, 91, 35, 32, 120, 184, 82, 125, 51, 182, 255, 229, 173, 61, 155, 90, + 88, 20, 71, 165, 177, 79, 51, 158, 164, 122, 20, 38, 90, 54, 245, 165, 60, 80, 139, 135, 51, 45, 190, 156, + 8, 82, 50, 245, 220, 254, 36, 189, 169, 33, 183, 62, 169, 64, 28, 153, 163, 196, 176, 93, 51, 61, 106, 135, + 29, 207, 176, 63, 232, 93, 44, 250, 201, 21, 184, 1, 137, 101, 76, 49, 185, 227, 196, 18, 165, 128, 196, + 177, 79, 27, 6, 188, 39, 65, 29, 102, 230, 112, 113, 244, 25, 32, 125, 198, 123, 125, 134, 67, 127, 139, + 152, 174, 63, 234, 81, 145, 209, 136, 229, 237, 176, 228, 8, 147, 176, 159, 236, 218, 177, 10, 241, 5, 191, + 216, 133, 147, 170, 148, 204, 57, 204, 204, 169, 86, 37, 147, 85, 9, 146, 237, 168, 70, 207, 161, 62, 126, + 180, 1, 197, 140, 107, 227, 121, 98, 63, 133, 179, 200, 72, 251, 124, 132, 13, 61, 83, 95, 251, 3, 28, 37, + 177, 93, 69, 127, 251, 21, 0, 191, 223, 101, 55, 223, 133, 227, 237, 33, 238, 193, 210, 103, 91, 172, 232, + 244, 47, 76, 100, 25, 34, 139, 239, 191, 130, 121, 111, 48, 79, 191, 252, 125, 140, 138, 183, 16, 89, 248, + 175, 159, 156, 140, 16, 240, 121, 89, 199, 20, 222, 253, 76, 239, 47, 203, 109, 196, 209, 91, 86, 165, 100, + 78, 53, 185, 89, 76, 110, 86, 45, 183, 50, 114, 123, 202, 229, 54, 2, 100, 124, 120, 91, 12, 166, 252, 46, + 73, 239, 105, 36, 35, 85, 153, 195, 2, 101, 170, 73, 212, 99, 18, 245, 106, 137, 150, 145, 232, 195, 168, + 37, 98, 204, 16, 59, 107, 73, 151, 36, 72, 196, 19, 69, 222, 97, 78, 94, 53, 201, 217, 76, 114, 118, 45, + 185, 42, 109, 145, 73, 224, 156, 252, 159, 83, 129, 151, 212, 22, 213, 101, 14, 11, 148, 185, 20, 187, 26, + 70, 45, 210, 50, 34, 141, 125, 43, 143, 118, 247, 138, 39, 43, 7, 60, 70, 45, 206, 31, 102, 156, 175, 38, + 46, 135, 137, 203, 169, 165, 85, 69, 90, 67, 114, 34, 253, 196, 90, 244, 128, 7, 31, 197, 249, 195, 140, + 243, 213, 164, 213, 96, 210, 106, 212, 210, 170, 34, 173, 62, 33, 50, 139, 240, 16, 82, 137, 207, 31, 102, + 156, 175, 38, 173, 38, 147, 86, 179, 150, 86, 25, 105, 61, 225, 210, 218, 226, 107, 81, 63, 17, 191, 37, + 157, 147, 39, 92, 62, 170, 18, 135, 43, 75, 84, 147, 101, 139, 201, 178, 85, 203, 178, 140, 44, 239, 115, + 89, 118, 104, 116, 245, 44, 26, 235, 15, 162, 133, 76, 167, 81, 171, 147, 207, 86, 147, 147, 207, 228, 228, + 215, 114, 42, 35, 167, 141, 168, 115, 135, 109, 133, 237, 118, 37, 119, 200, 227, 28, 185, 67, 30, 231, 84, + 147, 217, 140, 201, 108, 86, 203, 172, 138, 85, 123, 77, 115, 13, 231, 75, 86, 45, 62, 127, 152, 113, 190, + 154, 180, 230, 76, 90, 243, 90, 90, 85, 58, 219, 195, 120, 24, 58, 242, 241, 31, 70, 222, 97, 50, 239, 48, + 39, 175, 154, 228, 2, 38, 185, 32, 85, 177, 199, 145, 26, 205, 181, 169, 214, 35, 81, 188, 163, 81, 114, + 49, 20, 38, 212, 70, 206, 63, 92, 145, 95, 173, 146, 6, 143, 244, 98, 218, 51, 18, 136, 246, 123, 102, 234, + 155, 149, 250, 102, 167, 190, 77, 240, 174, 97, 184, 77, 1, 236, 42, 106, 250, 99, 66, 77, 63, 67, 169, 17, + 173, 248, 121, 67, 3, 129, 108, 68, 43, 86, 86, 75, 169, 33, 45, 93, 159, 154, 73, 13, 209, 95, 56, 177, + 154, 229, 105, 160, 79, 234, 35, 105, 242, 85, 61, 100, 13, 106, 94, 9, 224, 231, 18, 192, 9, 104, 197, + 185, 44, 136, 95, 196, 149, 152, 234, 166, 231, 101, 189, 255, 44, 128, 236, 116, 102, 75, 190, 50, 23, + 230, 53, 63, 232, 166, 160, 22, 186, 188, 69, 3, 217, 52, 142, 70, 19, 141, 182, 105, 194, 27, 92, 149, 0, + 218, 85, 213, 205, 212, 45, 63, 93, 55, 253, 133, 217, 20, 185, 198, 180, 213, 48, 166, 233, 92, 59, 2, + 199, 152, 219, 1, 124, 75, 229, 186, 34, 211, 245, 230, 190, 110, 164, 51, 27, 78, 246, 141, 13, 185, 70, + 178, 248, 238, 94, 245, 111, 74, 41, 54, 184, 82, 96, 14, 122, 111, 72, 216, 177, 26, 216, 170, 218, 180, + 26, 182, 107, 72, 141, 192, 138, 26, 193, 116, 214, 244, 37, 160, 154, 81, 174, 235, 155, 115, 195, 85, + 190, 200, 60, 152, 77, 253, 217, 178, 40, 111, 166, 10, 55, 45, 142, 49, 237, 22, 119, 33, 137, 67, 169, + 214, 45, 171, 5, 252, 159, 165, 214, 182, 137, 127, 89, 106, 61, 117, 166, 214, 212, 200, 82, 107, 250, + 151, 165, 214, 179, 57, 254, 41, 65, 104, 234, 248, 87, 176, 85, 222, 234, 234, 223, 148, 26, 60, 228, 106, + 144, 216, 201, 7, 242, 86, 40, 2, 123, 229, 44, 36, 241, 157, 208, 165, 85, 35, 233, 186, 204, 225, 85, 34, + 137, 23, 54, 130, 44, 36, 217, 131, 51, 252, 139, 6, 252, 87, 80, 17, 110, 117, 245, 111, 90, 17, 152, 223, + 185, 236, 16, 41, 235, 147, 227, 241, 9, 79, 81, 150, 200, 37, 238, 115, 83, 208, 60, 138, 168, 242, 19, + 31, 66, 198, 189, 76, 223, 175, 110, 37, 114, 141, 64, 205, 146, 153, 75, 90, 22, 87, 216, 244, 50, 149, + 12, 175, 147, 111, 219, 12, 19, 58, 150, 233, 130, 115, 20, 138, 53, 145, 219, 90, 247, 155, 82, 2, 17, 70, + 136, 130, 7, 113, 64, 97, 117, 43, 145, 57, 99, 185, 86, 197, 90, 73, 145, 251, 220, 20, 64, 79, 19, 254, + 221, 148, 92, 254, 115, 218, 176, 66, 38, 18, 165, 190, 233, 186, 213, 148, 181, 38, 166, 100, 208, 169, + 150, 215, 200, 162, 100, 224, 7, 55, 71, 227, 150, 47, 109, 228, 92, 106, 200, 53, 42, 212, 92, 110, 117, + 245, 111, 186, 197, 124, 11, 129, 183, 74, 0, 61, 227, 0, 225, 164, 210, 143, 52, 223, 251, 92, 59, 224, + 59, 11, 252, 190, 26, 36, 179, 165, 123, 78, 43, 203, 159, 80, 246, 86, 47, 113, 159, 155, 6, 137, 249, 37, + 81, 4, 97, 85, 200, 38, 207, 144, 37, 218, 79, 166, 197, 193, 171, 84, 106, 118, 85, 15, 89, 71, 240, 119, + 171, 223, 187, 88, 108, 245, 19, 227, 154, 115, 2, 121, 151, 38, 53, 99, 32, 166, 3, 159, 23, 180, 91, 167, + 24, 23, 155, 71, 171, 193, 60, 237, 60, 220, 26, 142, 47, 22, 189, 238, 22, 126, 188, 36, 207, 103, 75, 11, + 104, 113, 39, 122, 61, 123, 180, 71, 206, 174, 214, 11, 123, 221, 87, 144, 251, 159, 218, 66, 107, 80, 174, + 171, 25, 240, 167, 107, 166, 246, 11, 28, 251, 112, 6, 143, 240, 220, 140, 126, 77, 174, 9, 231, 26, 144, + 163, 211, 159, 67, 37, 27, 240, 105, 64, 14, 126, 131, 202, 39, 158, 186, 17, 215, 83, 155, 104, 95, 208, + 235, 226, 79, 252, 139, 166, 167, 74, 62, 76, 148, 124, 77, 171, 217, 206, 181, 119, 188, 236, 119, 88, + 163, 84, 233, 71, 180, 227, 212, 9, 55, 223, 145, 170, 241, 242, 247, 181, 127, 167, 119, 229, 127, 210, + 149, 99, 90, 151, 49, 163, 104, 161, 234, 74, 61, 254, 147, 222, 101, 76, 101, 209, 115, 204, 127, 151, 13, + 177, 116, 97, 233, 77, 150, 223, 58, 222, 137, 172, 77, 92, 113, 18, 221, 245, 175, 240, 214, 150, 230, 72, + 229, 177, 246, 120, 231, 3, 176, 204, 255, 205, 164, 201, 203, 223, 131, 119, 69, 91, 125, 6, 119, 72, 191, + 113, 135, 214, 6, 156, 211, 68, 173, 49, 77, 155, 60, 207, 172, 251, 179, 148, 158, 236, 194, 221, 216, 68, + 249, 99, 254, 123, 63, 236, 170, 239, 185, 231, 156, 126, 210, 19, 184, 118, 134, 124, 71, 59, 44, 208, + 138, 88, 170, 237, 137, 54, 203, 120, 218, 147, 248, 173, 163, 223, 96, 250, 64, 215, 157, 69, 87, 88, 169, + 43, 30, 211, 126, 109, 103, 96, 130, 178, 202, 203, 79, 136, 245, 74, 76, 85, 59, 101, 61, 228, 72, 187, + 26, 18, 202, 79, 18, 82, 233, 241, 45, 140, 60, 154, 123, 147, 148, 141, 172, 31, 207, 35, 169, 51, 140, + 79, 51, 175, 94, 198, 60, 214, 172, 61, 154, 206, 122, 206, 127, 55, 232, 152, 130, 57, 226, 42, 67, 186, + 138, 173, 249, 72, 177, 129, 82, 163, 103, 128, 147, 74, 163, 159, 81, 88, 23, 247, 227, 6, 252, 128, 57, + 60, 106, 239, 242, 29, 54, 210, 109, 98, 233, 46, 79, 105, 47, 131, 63, 57, 145, 35, 11, 205, 86, 222, 195, + 146, 90, 229, 19, 106, 207, 231, 43, 238, 144, 104, 211, 75, 119, 248, 191, 240, 38, 127, 192, 187, 244, + 137, 23, 230, 228, 222, 159, 114, 126, 56, 128, 59, 158, 64, 139, 101, 219, 176, 189, 7, 100, 63, 146, 14, + 156, 194, 185, 164, 182, 31, 66, 249, 125, 182, 102, 139, 63, 245, 81, 130, 113, 55, 19, 156, 75, 20, 93, + 129, 157, 71, 52, 135, 235, 247, 154, 157, 175, 149, 157, 157, 154, 157, 107, 118, 174, 217, 185, 102, 231, + 12, 118, 254, 137, 179, 243, 24, 238, 45, 86, 61, 179, 242, 52, 152, 162, 177, 31, 206, 170, 57, 251, 58, + 57, 219, 172, 57, 187, 230, 236, 154, 179, 107, 206, 206, 224, 236, 141, 101, 206, 174, 25, 250, 90, 25, + 218, 168, 25, 186, 102, 232, 154, 161, 107, 134, 94, 193, 208, 35, 144, 24, 62, 15, 91, 82, 205, 208, 215, + 201, 208, 110, 205, 208, 53, 67, 215, 12, 93, 51, 116, 6, 67, 63, 228, 12, 253, 27, 233, 213, 111, 240, + 140, 223, 161, 223, 93, 115, 244, 117, 114, 180, 93, 115, 116, 205, 209, 53, 71, 215, 28, 189, 194, 139, + 78, 112, 116, 205, 208, 215, 202, 208, 86, 205, 208, 53, 67, 215, 12, 253, 141, 51, 180, 66, 30, 119, 118, + 230, 157, 241, 21, 177, 115, 61, 243, 174, 102, 231, 154, 157, 191, 70, 118, 142, 49, 94, 7, 59, 223, 157, + 153, 119, 95, 19, 59, 215, 51, 239, 106, 118, 174, 217, 185, 102, 231, 44, 118, 254, 90, 102, 222, 125, 77, + 156, 93, 207, 188, 171, 57, 187, 230, 236, 154, 179, 179, 56, 251, 110, 206, 188, 251, 154, 24, 186, 158, + 121, 87, 51, 116, 205, 208, 53, 67, 175, 98, 232, 187, 53, 243, 238, 107, 98, 232, 122, 230, 93, 205, 208, + 53, 67, 215, 12, 157, 197, 208, 119, 117, 230, 221, 215, 196, 209, 245, 204, 187, 154, 163, 107, 142, 174, + 57, 122, 149, 23, 125, 183, 102, 222, 125, 77, 12, 93, 207, 188, 171, 25, 186, 102, 232, 111, 157, 161, + 123, 80, 10, 165, 152, 96, 24, 105, 110, 7, 215, 217, 10, 236, 236, 129, 150, 182, 52, 27, 254, 102, 240, + 150, 205, 181, 176, 115, 62, 23, 202, 50, 115, 165, 88, 193, 101, 152, 226, 105, 234, 201, 234, 86, 130, + 172, 111, 42, 216, 79, 92, 197, 54, 99, 140, 91, 71, 51, 231, 221, 150, 185, 213, 130, 187, 171, 184, 85, + 92, 145, 63, 123, 239, 170, 180, 77, 104, 208, 102, 74, 135, 202, 106, 219, 51, 174, 109, 241, 38, 168, + 111, 83, 165, 238, 162, 246, 121, 146, 46, 92, 181, 246, 253, 69, 107, 148, 208, 61, 251, 27, 209, 189, + 167, 92, 247, 146, 118, 67, 246, 70, 31, 104, 34, 166, 235, 17, 178, 119, 33, 162, 43, 243, 76, 182, 47, + 42, 151, 189, 109, 158, 104, 61, 203, 248, 246, 120, 162, 166, 244, 132, 218, 19, 173, 61, 209, 170, 252, + 252, 36, 230, 83, 13, 127, 214, 42, 129, 215, 37, 56, 26, 231, 175, 225, 29, 239, 194, 90, 16, 171, 230, + 232, 154, 163, 107, 142, 190, 99, 28, 109, 44, 249, 222, 95, 47, 71, 63, 142, 249, 52, 151, 161, 159, 165, + 88, 101, 147, 228, 205, 126, 170, 240, 36, 209, 139, 123, 152, 90, 245, 39, 242, 202, 243, 180, 73, 191, + 140, 210, 4, 189, 133, 254, 52, 32, 129, 156, 108, 194, 159, 30, 241, 52, 158, 195, 50, 88, 35, 129, 121, + 147, 152, 61, 160, 30, 31, 74, 81, 230, 233, 108, 206, 178, 215, 198, 16, 171, 91, 175, 93, 186, 245, 186, + 82, 235, 189, 76, 59, 44, 218, 162, 178, 108, 196, 213, 104, 161, 90, 111, 170, 104, 224, 51, 194, 253, + 132, 36, 156, 234, 21, 106, 47, 240, 175, 130, 46, 78, 181, 22, 160, 224, 195, 39, 218, 254, 57, 249, 12, + 54, 49, 142, 208, 69, 140, 45, 160, 38, 6, 164, 161, 172, 231, 143, 165, 81, 103, 3, 208, 225, 25, 148, 79, + 235, 226, 191, 193, 147, 58, 128, 83, 64, 40, 50, 121, 188, 5, 188, 78, 73, 38, 200, 137, 127, 194, 247, + 243, 8, 99, 212, 189, 255, 141, 208, 186, 71, 79, 222, 196, 207, 212, 93, 31, 104, 179, 130, 81, 169, 123, + 154, 39, 217, 226, 239, 160, 142, 142, 84, 198, 95, 193, 80, 215, 163, 27, 171, 36, 90, 69, 75, 30, 167, + 244, 237, 114, 113, 38, 135, 123, 138, 1, 249, 136, 232, 73, 54, 224, 207, 134, 242, 213, 185, 170, 108, + 156, 201, 89, 27, 127, 213, 113, 166, 44, 27, 169, 210, 150, 180, 238, 61, 134, 247, 153, 129, 207, 250, + 153, 48, 219, 76, 200, 141, 105, 221, 15, 201, 181, 55, 21, 52, 109, 6, 218, 229, 128, 198, 160, 77, 108, + 81, 79, 5, 53, 110, 6, 154, 36, 247, 94, 154, 145, 102, 160, 70, 162, 46, 206, 224, 127, 244, 74, 90, 215, + 194, 68, 87, 35, 135, 52, 126, 229, 176, 255, 27, 188, 229, 105, 228, 243, 114, 155, 172, 253, 93, 182, + 185, 149, 173, 132, 5, 40, 35, 186, 83, 106, 219, 172, 237, 183, 0, 123, 35, 197, 2, 152, 63, 131, 187, + 232, 100, 73, 116, 46, 71, 148, 161, 67, 50, 187, 14, 217, 60, 35, 94, 79, 190, 243, 91, 66, 249, 35, 96, + 247, 33, 242, 58, 228, 150, 245, 28, 106, 190, 140, 95, 145, 43, 175, 70, 23, 202, 201, 179, 156, 174, 60, + 7, 95, 29, 127, 249, 252, 239, 208, 214, 177, 39, 249, 153, 238, 134, 56, 227, 189, 215, 163, 33, 179, 72, + 67, 204, 91, 167, 33, 15, 1, 211, 207, 84, 126, 181, 116, 127, 36, 203, 92, 94, 43, 158, 67, 185, 101, 108, + 111, 78, 159, 138, 200, 60, 237, 231, 191, 163, 72, 196, 219, 216, 75, 146, 176, 77, 196, 42, 74, 105, 223, + 6, 156, 193, 167, 95, 16, 154, 235, 209, 182, 121, 164, 109, 214, 45, 212, 182, 83, 138, 15, 190, 37, 105, + 29, 83, 235, 61, 11, 183, 135, 0, 216, 246, 112, 114, 177, 56, 26, 116, 241, 39, 222, 222, 176, 36, 140, + 207, 153, 142, 195, 206, 226, 129, 236, 63, 77, 201, 11, 153, 175, 245, 174, 88, 211, 223, 225, 206, 235, + 188, 231, 213, 104, 179, 74, 135, 210, 218, 251, 187, 38, 126, 32, 240, 210, 111, 83, 74, 187, 31, 65, 254, + 103, 138, 212, 109, 106, 131, 168, 7, 122, 86, 201, 27, 210, 65, 199, 231, 80, 6, 237, 45, 243, 134, 12, + 64, 210, 86, 120, 67, 230, 141, 122, 67, 27, 128, 54, 74, 231, 61, 124, 190, 101, 58, 148, 17, 241, 146, + 75, 206, 19, 113, 69, 67, 210, 240, 100, 201, 72, 154, 25, 165, 31, 166, 74, 243, 182, 145, 81, 22, 153, + 249, 35, 105, 143, 79, 239, 248, 142, 243, 251, 242, 83, 254, 74, 254, 168, 35, 217, 131, 244, 213, 44, 78, + 161, 170, 161, 108, 71, 178, 158, 154, 174, 173, 234, 153, 87, 53, 186, 172, 214, 212, 116, 59, 154, 81, + 11, 59, 79, 188, 105, 90, 190, 242, 104, 207, 114, 249, 85, 200, 36, 175, 41, 131, 202, 211, 12, 73, 164, + 181, 74, 142, 86, 171, 158, 149, 188, 66, 245, 164, 103, 202, 171, 138, 104, 75, 214, 243, 98, 4, 87, 93, + 37, 222, 74, 214, 105, 189, 128, 156, 178, 113, 120, 150, 169, 141, 171, 234, 38, 95, 89, 172, 126, 217, + 178, 202, 214, 165, 188, 58, 42, 228, 85, 210, 7, 73, 104, 124, 101, 31, 36, 205, 208, 102, 196, 208, 78, + 205, 208, 53, 67, 175, 197, 203, 89, 214, 210, 154, 157, 107, 118, 254, 218, 217, 249, 97, 124, 6, 114, 89, + 155, 58, 169, 196, 207, 51, 138, 39, 122, 156, 109, 113, 20, 195, 164, 89, 147, 233, 200, 53, 246, 27, 189, + 212, 108, 8, 26, 157, 164, 121, 149, 115, 197, 108, 8, 49, 194, 137, 61, 249, 89, 38, 170, 247, 50, 103, + 53, 168, 198, 157, 238, 3, 79, 124, 162, 241, 91, 100, 141, 47, 17, 126, 203, 163, 212, 151, 137, 126, 95, + 213, 232, 150, 74, 94, 105, 153, 223, 131, 251, 227, 254, 76, 243, 72, 202, 63, 242, 88, 150, 216, 171, + 105, 147, 251, 162, 109, 184, 250, 19, 198, 160, 43, 141, 171, 182, 64, 114, 38, 201, 221, 35, 139, 236, + 67, 106, 211, 8, 86, 210, 34, 59, 52, 58, 81, 108, 254, 203, 93, 138, 32, 175, 198, 116, 149, 84, 30, 82, + 141, 62, 240, 249, 76, 108, 46, 72, 149, 222, 107, 64, 115, 140, 116, 146, 71, 64, 168, 7, 52, 102, 24, + 143, 26, 233, 36, 9, 108, 97, 55, 235, 27, 93, 85, 155, 80, 225, 152, 70, 255, 251, 104, 44, 137, 97, 31, + 127, 175, 130, 183, 1, 121, 1, 177, 177, 29, 69, 11, 68, 100, 236, 54, 249, 162, 87, 131, 119, 140, 93, 62, + 198, 79, 105, 206, 30, 142, 35, 99, 244, 114, 83, 228, 94, 162, 15, 128, 184, 91, 52, 174, 103, 19, 227, + 152, 116, 127, 100, 28, 155, 198, 71, 28, 178, 59, 136, 46, 74, 199, 129, 188, 22, 69, 47, 81, 18, 1, 33, + 239, 95, 11, 238, 63, 19, 146, 226, 205, 133, 79, 128, 119, 254, 31, 72, 61, 237, 36, 101, 121, 190, 67, + 45, 73, 93, 255, 83, 230, 245, 203, 49, 237, 239, 224, 13, 175, 35, 170, 157, 47, 205, 124, 77, 248, 81, + 219, 134, 171, 62, 83, 68, 255, 152, 70, 128, 215, 161, 13, 201, 30, 161, 30, 245, 8, 173, 91, 215, 10, + 255, 133, 250, 99, 201, 183, 79, 74, 84, 72, 250, 115, 52, 175, 231, 39, 168, 227, 11, 226, 243, 236, 63, + 247, 90, 44, 220, 42, 169, 229, 75, 125, 35, 42, 189, 73, 18, 60, 173, 180, 22, 34, 205, 182, 230, 55, 199, + 182, 42, 20, 243, 113, 127, 172, 253, 166, 225, 126, 111, 239, 215, 208, 202, 90, 124, 205, 19, 206, 12, + 112, 163, 113, 30, 147, 208, 199, 245, 80, 83, 154, 187, 132, 227, 59, 46, 121, 255, 83, 72, 231, 228, 207, + 207, 200, 55, 180, 200, 223, 187, 14, 244, 159, 67, 25, 246, 214, 229, 249, 246, 71, 229, 181, 55, 199, + 181, 217, 18, 92, 101, 113, 81, 134, 98, 164, 241, 242, 210, 119, 224, 125, 155, 228, 173, 187, 36, 217, + 95, 168, 60, 155, 37, 98, 83, 43, 12, 200, 226, 26, 100, 89, 29, 154, 221, 54, 39, 13, 152, 67, 30, 150, + 240, 150, 122, 117, 87, 197, 177, 239, 19, 111, 158, 148, 98, 246, 60, 54, 121, 20, 57, 235, 14, 203, 243, + 219, 90, 215, 100, 113, 243, 164, 153, 214, 132, 251, 124, 46, 209, 41, 205, 139, 254, 16, 173, 187, 77, + 159, 45, 175, 1, 62, 113, 42, 246, 38, 112, 30, 45, 235, 91, 176, 21, 13, 203, 125, 139, 198, 87, 200, 190, + 50, 130, 69, 80, 127, 156, 62, 123, 41, 235, 103, 208, 76, 208, 128, 98, 59, 108, 158, 86, 139, 248, 184, + 177, 100, 253, 196, 140, 192, 175, 11, 255, 108, 44, 139, 72, 226, 25, 220, 241, 3, 173, 171, 96, 57, 155, + 209, 140, 234, 170, 140, 152, 246, 70, 236, 91, 236, 141, 252, 76, 150, 43, 126, 247, 183, 52, 30, 112, 70, + 171, 161, 85, 150, 205, 145, 56, 45, 239, 250, 219, 235, 179, 174, 146, 120, 178, 6, 127, 203, 121, 195, + 243, 188, 53, 57, 82, 92, 103, 159, 230, 60, 224, 236, 28, 209, 254, 219, 228, 255, 108, 198, 57, 149, 245, + 109, 78, 154, 163, 211, 236, 222, 41, 69, 116, 124, 210, 41, 139, 44, 176, 207, 251, 59, 248, 233, 208, 10, + 40, 177, 182, 1, 189, 174, 57, 249, 110, 216, 23, 190, 30, 125, 243, 232, 173, 223, 2, 166, 226, 173, 223, + 82, 239, 1, 83, 121, 254, 119, 214, 250, 171, 31, 149, 119, 41, 162, 175, 87, 197, 63, 89, 178, 148, 249, + 135, 173, 58, 76, 207, 13, 23, 251, 94, 236, 208, 187, 126, 188, 3, 171, 12, 211, 51, 172, 239, 246, 174, + 68, 197, 215, 25, 202, 111, 253, 173, 173, 51, 52, 164, 43, 86, 173, 51, 196, 30, 84, 26, 131, 213, 107, + 149, 228, 145, 189, 34, 107, 149, 228, 49, 203, 171, 94, 105, 216, 148, 80, 191, 75, 43, 13, 191, 165, 213, + 224, 223, 103, 172, 235, 82, 179, 176, 216, 31, 110, 159, 238, 143, 54, 190, 202, 8, 103, 205, 196, 215, + 193, 196, 50, 179, 214, 76, 188, 110, 38, 94, 94, 193, 87, 101, 221, 104, 189, 234, 187, 230, 226, 124, 46, + 254, 1, 234, 119, 66, 94, 251, 12, 116, 79, 172, 90, 75, 158, 171, 210, 251, 14, 40, 174, 200, 34, 29, 62, + 143, 65, 183, 18, 243, 180, 217, 250, 89, 29, 56, 247, 102, 215, 207, 94, 213, 170, 181, 36, 126, 105, 22, + 243, 163, 156, 229, 222, 22, 106, 184, 232, 133, 91, 75, 187, 117, 34, 87, 124, 201, 185, 42, 160, 249, 4, + 173, 2, 242, 125, 78, 173, 153, 189, 193, 41, 105, 41, 182, 150, 205, 75, 74, 125, 70, 227, 13, 13, 178, + 171, 45, 146, 186, 75, 163, 186, 173, 148, 212, 167, 20, 123, 110, 165, 164, 142, 255, 7, 84, 246, 122, + 162, 208, 87, 181, 158, 104, 53, 170, 55, 171, 11, 63, 209, 204, 139, 47, 188, 86, 108, 157, 244, 23, 56, + 182, 185, 52, 112, 214, 251, 22, 215, 145, 164, 181, 193, 152, 54, 99, 214, 234, 163, 192, 77, 178, 51, + 115, 106, 225, 44, 62, 221, 164, 209, 138, 100, 124, 218, 165, 89, 72, 22, 141, 72, 224, 39, 251, 110, 147, + 62, 221, 109, 221, 200, 67, 179, 186, 140, 158, 73, 35, 15, 19, 170, 13, 214, 251, 166, 228, 196, 102, 23, + 222, 93, 57, 173, 66, 180, 186, 172, 54, 200, 223, 59, 101, 254, 231, 13, 202, 7, 207, 221, 93, 249, 168, + 80, 76, 203, 228, 103, 154, 217, 119, 172, 177, 81, 136, 49, 212, 225, 152, 31, 161, 23, 138, 125, 134, + 164, 84, 30, 196, 51, 209, 174, 88, 38, 13, 144, 68, 131, 102, 68, 53, 104, 102, 20, 126, 186, 100, 43, 29, + 242, 142, 238, 174, 76, 150, 49, 76, 75, 228, 17, 97, 63, 167, 121, 188, 216, 179, 19, 179, 97, 197, 42, + 253, 33, 245, 174, 206, 137, 19, 223, 105, 108, 111, 79, 236, 181, 92, 80, 187, 74, 62, 187, 138, 87, 130, + 99, 62, 115, 234, 41, 7, 212, 179, 199, 145, 185, 57, 93, 33, 164, 227, 145, 47, 218, 160, 246, 161, 243, + 125, 20, 76, 238, 185, 182, 32, 7, 103, 84, 164, 165, 243, 61, 89, 122, 63, 209, 239, 146, 123, 246, 183, + 111, 70, 114, 57, 156, 241, 223, 222, 24, 68, 24, 254, 70, 159, 195, 246, 228, 98, 209, 233, 14, 142, 23, + 65, 224, 210, 191, 176, 207, 190, 249, 244, 47, 236, 15, 35, 121, 63, 160, 113, 183, 183, 241, 30, 46, 17, + 3, 6, 75, 241, 157, 195, 204, 156, 81, 239, 96, 186, 208, 195, 254, 164, 115, 140, 201, 86, 159, 146, 241, + 222, 241, 194, 132, 111, 147, 227, 133, 17, 246, 71, 61, 42, 50, 26, 177, 188, 29, 150, 28, 97, 18, 78, + 142, 58, 23, 11, 246, 224, 123, 208, 245, 97, 52, 254, 1, 94, 234, 229, 197, 226, 245, 16, 202, 52, 245, + 112, 135, 167, 147, 241, 111, 112, 63, 29, 14, 118, 225, 45, 38, 187, 189, 227, 69, 35, 152, 217, 1, 141, + 33, 77, 142, 250, 235, 185, 81, 184, 117, 52, 188, 88, 244, 247, 38, 248, 10, 221, 193, 8, 147, 225, 128, + 222, 100, 216, 38, 144, 7, 251, 88, 245, 33, 102, 225, 77, 134, 19, 254, 29, 144, 48, 194, 246, 112, 192, + 146, 49, 190, 116, 187, 221, 165, 111, 237, 30, 37, 99, 184, 205, 28, 74, 246, 240, 130, 109, 188, 169, 30, + 254, 58, 252, 199, 241, 194, 193, 116, 204, 190, 30, 176, 100, 136, 215, 111, 247, 119, 49, 249, 117, 140, + 101, 60, 72, 183, 216, 215, 9, 222, 238, 215, 113, 135, 128, 29, 12, 9, 209, 125, 172, 220, 246, 120, 128, + 231, 6, 227, 67, 76, 122, 44, 25, 140, 73, 2, 221, 241, 30, 94, 182, 213, 29, 227, 203, 236, 191, 25, 227, + 183, 193, 152, 190, 237, 76, 246, 240, 38, 59, 19, 70, 5, 61, 162, 48, 84, 204, 63, 41, 165, 105, 217, 225, + 81, 159, 202, 30, 237, 81, 253, 39, 35, 186, 29, 92, 137, 201, 81, 175, 77, 55, 239, 31, 193, 13, 180, 112, + 127, 207, 190, 88, 192, 199, 241, 194, 13, 41, 9, 88, 98, 176, 68, 151, 18, 72, 251, 88, 30, 212, 199, 9, + 41, 1, 74, 220, 218, 239, 98, 58, 105, 15, 232, 113, 195, 215, 152, 28, 97, 69, 141, 176, 219, 57, 164, + 231, 116, 59, 164, 85, 221, 78, 155, 206, 246, 218, 244, 173, 183, 119, 177, 24, 244, 39, 193, 66, 127, + 225, 132, 147, 131, 33, 59, 24, 237, 242, 51, 157, 3, 126, 16, 118, 143, 8, 194, 112, 111, 31, 30, 191, + 183, 223, 163, 123, 134, 195, 237, 125, 234, 146, 13, 53, 143, 8, 115, 19, 8, 122, 119, 143, 4, 50, 220, + 29, 176, 4, 139, 254, 7, 117, 137, 102, 124, 8, 113, 70, 19, 102, 27, 20, 180, 116, 162, 9, 93, 51, 234, + 76, 177, 41, 251, 191, 80, 195, 109, 80, 249, 6, 223, 182, 202, 194, 201, 94, 32, 5, 168, 113, 184, 59, 96, + 194, 123, 3, 146, 28, 180, 223, 64, 83, 126, 185, 141, 39, 14, 71, 164, 83, 3, 222, 10, 95, 195, 109, 166, + 196, 10, 30, 121, 53, 167, 225, 96, 64, 16, 237, 141, 169, 220, 94, 151, 110, 211, 219, 37, 1, 119, 7, 216, + 228, 183, 240, 150, 221, 151, 120, 126, 107, 128, 207, 10, 195, 87, 187, 240, 206, 175, 88, 161, 48, 92, + 122, 158, 206, 159, 135, 177, 82, 182, 239, 55, 174, 76, 98, 227, 134, 179, 212, 19, 245, 66, 79, 156, 28, + 77, 184, 80, 76, 179, 197, 132, 98, 56, 214, 11, 203, 210, 245, 70, 147, 201, 198, 106, 152, 76, 54, 70, + 195, 9, 7, 253, 182, 40, 218, 198, 51, 58, 148, 105, 227, 130, 247, 206, 1, 37, 147, 62, 53, 159, 254, 65, + 155, 234, 202, 158, 84, 19, 224, 26, 8, 176, 51, 26, 18, 233, 77, 88, 237, 15, 38, 88, 251, 209, 62, 20, + 114, 26, 243, 150, 161, 27, 54, 200, 228, 8, 100, 210, 52, 225, 224, 13, 72, 201, 10, 15, 70, 187, 68, 130, + 221, 62, 106, 192, 112, 204, 179, 135, 99, 150, 61, 220, 18, 39, 182, 248, 137, 190, 56, 209, 103, 39, 142, + 250, 68, 64, 147, 118, 155, 37, 198, 241, 194, 199, 212, 60, 94, 216, 144, 30, 0, 243, 52, 195, 246, 100, + 139, 120, 116, 66, 194, 238, 31, 236, 243, 72, 30, 243, 233, 177, 215, 182, 77, 182, 179, 71, 125, 183, + 147, 176, 219, 103, 59, 143, 169, 74, 252, 194, 202, 128, 216, 135, 147, 49, 84, 1, 21, 139, 154, 207, 238, + 132, 148, 249, 112, 159, 164, 182, 51, 238, 66, 69, 195, 151, 163, 125, 84, 186, 209, 75, 74, 58, 131, 49, + 38, 131, 173, 30, 228, 189, 48, 195, 65, 143, 42, 255, 235, 152, 84, 114, 184, 75, 133, 134, 227, 14, 75, + 184, 186, 130, 75, 196, 106, 124, 221, 245, 73, 183, 0, 117, 237, 70, 251, 103, 108, 57, 212, 1, 184, 103, + 67, 248, 220, 7, 87, 99, 31, 220, 151, 49, 56, 61, 147, 54, 146, 211, 222, 118, 212, 160, 143, 14, 250, + 180, 3, 5, 75, 216, 222, 19, 186, 203, 246, 158, 48, 192, 150, 145, 190, 249, 13, 166, 111, 198, 140, 233, + 91, 51, 169, 110, 77, 219, 13, 160, 0, 83, 189, 249, 220, 245, 76, 241, 28, 212, 228, 136, 41, 108, 155, + 49, 69, 163, 245, 194, 117, 117, 195, 113, 57, 81, 216, 46, 39, 10, 208, 28, 70, 20, 84, 18, 137, 194, 176, + 46, 71, 20, 236, 95, 77, 20, 151, 37, 138, 134, 25, 204, 166, 156, 40, 136, 49, 222, 160, 184, 148, 68, 1, + 217, 68, 20, 134, 201, 137, 2, 79, 108, 241, 19, 125, 113, 162, 207, 78, 220, 52, 81, 216, 183, 140, 40, + 214, 88, 159, 116, 11, 200, 33, 138, 191, 106, 35, 168, 200, 235, 162, 212, 96, 242, 109, 105, 26, 22, 99, + 134, 86, 192, 20, 204, 106, 41, 152, 161, 17, 180, 244, 185, 193, 153, 33, 240, 3, 103, 170, 98, 6, 163, + 197, 153, 193, 48, 27, 47, 12, 215, 116, 90, 220, 135, 176, 117, 65, 13, 142, 253, 194, 228, 110, 4, 43, + 141, 7, 118, 179, 118, 35, 110, 3, 59, 36, 221, 8, 187, 193, 221, 8, 21, 57, 184, 13, 198, 13, 220, 135, + 192, 175, 91, 236, 107, 159, 127, 237, 211, 215, 155, 166, 5, 211, 185, 93, 180, 176, 198, 250, 20, 246, + 31, 30, 3, 45, 108, 65, 67, 152, 64, 117, 218, 240, 217, 134, 174, 74, 27, 207, 21, 36, 10, 195, 229, 187, + 90, 161, 89, 39, 101, 51, 76, 155, 105, 27, 164, 10, 170, 152, 79, 91, 83, 95, 80, 69, 179, 209, 180, 34, + 218, 240, 173, 89, 76, 27, 43, 30, 27, 109, 165, 69, 143, 52, 157, 38, 127, 164, 163, 171, 233, 201, 104, + 180, 196, 115, 26, 94, 96, 138, 227, 169, 219, 136, 104, 171, 57, 117, 227, 186, 144, 249, 99, 199, 182, + 229, 57, 209, 249, 89, 51, 170, 123, 96, 198, 247, 153, 233, 166, 112, 140, 130, 86, 211, 12, 162, 123, + 194, 131, 197, 177, 55, 181, 167, 226, 216, 154, 54, 163, 107, 91, 243, 24, 15, 63, 136, 203, 180, 76, 43, + 122, 174, 217, 112, 163, 50, 222, 12, 95, 146, 191, 203, 220, 136, 206, 207, 154, 179, 153, 56, 118, 221, + 70, 84, 198, 51, 102, 126, 228, 180, 233, 86, 84, 183, 192, 208, 163, 227, 185, 97, 251, 49, 246, 133, 251, + 153, 247, 227, 254, 44, 117, 184, 21, 61, 76, 163, 100, 159, 54, 220, 30, 245, 46, 22, 219, 72, 50, 122, + 184, 141, 20, 3, 9, 146, 138, 229, 66, 250, 134, 165, 41, 150, 15, 183, 123, 208, 204, 182, 123, 244, 204, + 237, 222, 75, 204, 210, 117, 50, 135, 219, 189, 29, 140, 175, 244, 94, 225, 131, 14, 198, 196, 211, 7, 99, + 98, 155, 112, 216, 235, 194, 99, 71, 192, 49, 94, 248, 106, 180, 199, 216, 186, 155, 72, 70, 255, 216, 7, + 30, 106, 234, 134, 31, 24, 134, 172, 117, 187, 208, 234, 92, 96, 209, 29, 180, 95, 78, 203, 12, 71, 91, + 208, 28, 161, 47, 60, 26, 31, 226, 237, 59, 219, 93, 97, 150, 195, 33, 190, 121, 39, 182, 62, 27, 52, 143, + 249, 45, 184, 236, 108, 36, 243, 56, 241, 91, 203, 83, 178, 50, 24, 233, 30, 194, 249, 127, 34, 91, 8, 59, + 211, 105, 83, 204, 170, 211, 134, 42, 91, 243, 102, 216, 233, 237, 98, 53, 59, 123, 123, 24, 169, 233, 236, + 209, 155, 116, 198, 91, 84, 104, 76, 225, 152, 14, 26, 28, 72, 58, 36, 150, 78, 231, 37, 37, 221, 125, 126, + 3, 102, 177, 58, 35, 34, 251, 78, 159, 224, 233, 244, 201, 84, 117, 246, 217, 201, 49, 216, 131, 22, 88, + 103, 102, 227, 58, 19, 118, 247, 201, 152, 61, 100, 143, 221, 143, 37, 187, 100, 141, 247, 123, 100, 14, + 122, 7, 6, 146, 119, 239, 192, 196, 219, 244, 14, 44, 74, 250, 6, 90, 151, 94, 223, 100, 137, 133, 73, 88, + 8, 153, 127, 85, 33, 67, 123, 13, 124, 160, 88, 253, 47, 124, 108, 194, 163, 249, 201, 179, 235, 196, 204, + 184, 36, 102, 198, 85, 97, 246, 136, 99, 198, 60, 130, 79, 180, 107, 10, 206, 235, 202, 195, 198, 102, 216, + 204, 115, 176, 209, 149, 216, 128, 149, 73, 98, 163, 231, 96, 227, 55, 25, 54, 150, 89, 26, 29, 96, 101, + 130, 199, 99, 240, 120, 12, 158, 38, 131, 167, 201, 224, 105, 134, 227, 33, 88, 0, 127, 26, 142, 199, 60, + 197, 248, 172, 233, 120, 112, 130, 31, 20, 3, 240, 57, 7, 48, 222, 112, 132, 253, 244, 78, 178, 100, 18, + 76, 184, 49, 161, 137, 230, 40, 27, 77, 175, 0, 154, 146, 166, 229, 161, 41, 105, 154, 183, 222, 214, 73, + 16, 2, 201, 46, 67, 56, 30, 118, 88, 206, 152, 165, 73, 72, 31, 112, 72, 59, 212, 30, 143, 53, 63, 26, 85, + 103, 128, 138, 121, 121, 155, 224, 104, 240, 232, 228, 202, 86, 171, 196, 210, 8, 236, 245, 182, 91, 203, + 175, 216, 110, 189, 178, 237, 118, 21, 70, 59, 52, 246, 52, 187, 60, 70, 107, 182, 6, 37, 16, 210, 175, 6, + 161, 199, 75, 8, 13, 104, 36, 250, 138, 152, 237, 78, 98, 19, 183, 176, 202, 216, 200, 109, 171, 12, 58, + 55, 220, 182, 4, 165, 247, 8, 157, 119, 212, 110, 196, 62, 28, 12, 159, 68, 14, 125, 195, 22, 198, 198, + 143, 243, 112, 50, 111, 41, 7, 153, 215, 132, 211, 132, 70, 203, 63, 221, 89, 156, 172, 181, 227, 244, 76, + 137, 211, 14, 31, 128, 253, 114, 39, 45, 154, 145, 246, 181, 28, 6, 147, 195, 96, 242, 24, 76, 30, 131, 73, + 237, 73, 45, 195, 244, 52, 3, 38, 34, 240, 242, 170, 116, 227, 180, 109, 228, 40, 146, 195, 16, 114, 24, + 66, 206, 165, 20, 41, 166, 247, 187, 216, 220, 242, 80, 170, 214, 220, 54, 34, 148, 62, 210, 130, 149, 235, + 115, 26, 115, 93, 112, 223, 174, 104, 217, 116, 6, 141, 206, 160, 209, 25, 52, 58, 131, 70, 103, 208, 232, + 41, 104, 30, 115, 104, 218, 160, 20, 236, 23, 233, 79, 105, 133, 241, 187, 104, 214, 29, 3, 168, 152, 226, + 160, 72, 19, 248, 184, 54, 3, 136, 242, 87, 2, 212, 180, 115, 0, 162, 190, 93, 2, 162, 217, 37, 61, 35, + 147, 33, 100, 50, 132, 108, 134, 144, 205, 16, 178, 89, 135, 15, 197, 154, 234, 241, 225, 107, 80, 119, 5, + 78, 148, 193, 80, 244, 155, 113, 30, 216, 63, 53, 246, 235, 21, 171, 20, 205, 82, 182, 193, 124, 32, 141, + 22, 135, 210, 156, 230, 117, 158, 101, 40, 75, 117, 159, 43, 131, 105, 182, 138, 129, 249, 148, 131, 217, + 165, 9, 136, 236, 231, 75, 68, 184, 225, 139, 164, 148, 255, 0, 40, 217, 4, 197, 36, 148, 182, 195, 176, + 52, 166, 34, 62, 99, 167, 3, 52, 58, 3, 211, 207, 195, 50, 240, 138, 52, 91, 210, 217, 4, 148, 46, 111, + 183, 120, 117, 185, 134, 107, 54, 11, 67, 105, 53, 121, 55, 218, 50, 102, 49, 150, 101, 49, 252, 129, 99, + 136, 19, 137, 206, 83, 248, 53, 102, 12, 191, 134, 4, 159, 68, 122, 121, 206, 60, 94, 154, 66, 207, 92, 77, + 122, 149, 189, 249, 162, 208, 117, 120, 12, 167, 115, 41, 157, 83, 19, 161, 192, 172, 233, 51, 204, 230, + 107, 242, 50, 244, 60, 47, 195, 188, 82, 192, 202, 2, 180, 145, 0, 136, 173, 239, 251, 152, 31, 53, 229, + 106, 101, 88, 133, 163, 11, 134, 110, 151, 55, 166, 142, 206, 96, 34, 43, 141, 64, 5, 121, 33, 173, 245, + 180, 202, 170, 216, 141, 104, 214, 49, 98, 247, 33, 87, 189, 140, 214, 122, 245, 235, 38, 26, 100, 18, 163, + 71, 17, 70, 108, 231, 24, 159, 102, 135, 139, 176, 233, 253, 116, 12, 162, 144, 86, 113, 100, 136, 227, 87, + 186, 104, 134, 233, 115, 120, 208, 4, 22, 132, 199, 157, 115, 189, 194, 139, 17, 32, 10, 156, 22, 179, 155, + 5, 245, 106, 4, 234, 100, 206, 231, 112, 208, 89, 38, 249, 124, 204, 132, 70, 117, 163, 73, 188, 249, 125, + 71, 9, 55, 122, 41, 5, 205, 75, 184, 53, 252, 242, 106, 101, 243, 248, 178, 199, 245, 202, 154, 217, 235, + 198, 77, 97, 37, 59, 34, 218, 204, 153, 160, 60, 146, 67, 182, 126, 123, 245, 8, 154, 132, 100, 96, 23, 32, + 182, 192, 174, 160, 128, 194, 217, 224, 64, 146, 31, 183, 126, 28, 17, 190, 177, 240, 224, 208, 219, 96, + 174, 156, 56, 24, 118, 132, 47, 39, 14, 70, 165, 33, 174, 226, 32, 171, 189, 18, 26, 41, 201, 134, 217, 55, + 203, 235, 107, 228, 30, 59, 38, 195, 153, 53, 248, 98, 64, 27, 243, 194, 190, 73, 4, 162, 25, 40, 59, 175, + 93, 178, 26, 95, 200, 54, 164, 121, 17, 119, 17, 254, 99, 69, 4, 173, 201, 208, 106, 49, 180, 200, 111, 77, + 40, 165, 126, 217, 142, 171, 205, 176, 98, 208, 224, 59, 52, 185, 7, 76, 125, 18, 4, 11, 199, 178, 216, 84, + 166, 108, 180, 28, 222, 125, 5, 243, 198, 186, 246, 45, 134, 151, 203, 1, 115, 57, 98, 46, 215, 77, 214, + 162, 241, 96, 26, 72, 35, 74, 232, 233, 141, 118, 200, 216, 23, 3, 179, 92, 71, 55, 221, 207, 165, 254, 86, + 197, 161, 145, 34, 45, 124, 25, 205, 2, 170, 103, 153, 42, 213, 115, 57, 146, 28, 200, 44, 28, 163, 54, 46, + 112, 44, 172, 148, 15, 162, 182, 252, 142, 22, 94, 253, 81, 166, 21, 23, 2, 178, 88, 215, 76, 141, 36, 53, + 102, 52, 58, 211, 181, 27, 107, 34, 75, 106, 195, 2, 200, 81, 146, 53, 25, 143, 102, 35, 42, 24, 178, 79, + 19, 17, 206, 105, 65, 235, 177, 246, 73, 106, 234, 12, 213, 15, 235, 29, 180, 43, 24, 55, 208, 215, 51, 33, + 65, 13, 167, 187, 52, 228, 222, 225, 40, 142, 59, 203, 67, 236, 249, 96, 37, 131, 195, 167, 192, 140, 155, + 124, 37, 234, 31, 180, 78, 166, 0, 75, 150, 209, 70, 195, 153, 23, 137, 95, 169, 125, 160, 171, 4, 143, + 133, 175, 150, 59, 187, 249, 216, 137, 176, 113, 188, 23, 77, 54, 122, 114, 160, 192, 87, 134, 172, 204, + 156, 94, 73, 236, 120, 87, 112, 32, 175, 12, 188, 164, 29, 137, 189, 71, 161, 139, 70, 115, 94, 65, 23, + 119, 56, 158, 241, 239, 241, 202, 104, 138, 201, 30, 228, 164, 16, 55, 234, 41, 155, 205, 92, 155, 37, 155, + 173, 236, 230, 145, 63, 89, 180, 127, 236, 93, 41, 156, 73, 168, 126, 224, 80, 29, 36, 230, 196, 252, 172, + 246, 253, 120, 24, 149, 109, 100, 180, 106, 120, 176, 81, 113, 154, 66, 33, 190, 227, 174, 77, 224, 73, 97, + 4, 14, 148, 61, 77, 249, 53, 182, 10, 41, 151, 143, 124, 17, 98, 22, 75, 251, 220, 223, 161, 161, 29, 30, + 154, 135, 52, 29, 44, 101, 214, 99, 68, 198, 98, 60, 30, 113, 227, 193, 191, 163, 17, 49, 48, 165, 94, 198, + 74, 160, 159, 71, 14, 206, 41, 57, 223, 179, 212, 74, 251, 101, 125, 148, 65, 246, 148, 29, 235, 34, 40, + 67, 15, 54, 39, 132, 234, 123, 12, 103, 147, 187, 144, 190, 41, 245, 171, 103, 220, 221, 102, 61, 169, 21, + 198, 26, 204, 146, 18, 106, 159, 207, 233, 242, 185, 98, 250, 77, 217, 245, 193, 131, 145, 56, 88, 158, + 157, 52, 138, 14, 132, 175, 142, 114, 33, 1, 161, 64, 88, 207, 103, 188, 220, 77, 87, 137, 226, 97, 66, 20, + 197, 52, 220, 171, 168, 225, 228, 231, 172, 210, 112, 75, 114, 222, 133, 147, 36, 58, 148, 68, 225, 75, + 174, 187, 81, 160, 163, 131, 103, 251, 92, 26, 125, 38, 13, 194, 152, 212, 184, 77, 141, 138, 160, 198, + 105, 95, 168, 206, 182, 91, 88, 157, 31, 69, 65, 161, 107, 80, 97, 107, 86, 72, 133, 165, 30, 99, 164, 193, + 185, 17, 199, 140, 46, 144, 205, 187, 64, 54, 67, 210, 242, 25, 146, 148, 90, 148, 18, 146, 76, 19, 149, + 218, 74, 14, 0, 42, 41, 161, 59, 98, 104, 151, 85, 209, 49, 223, 185, 238, 3, 237, 137, 84, 192, 119, 18, + 225, 92, 49, 246, 103, 120, 243, 203, 142, 253, 113, 53, 117, 36, 53, 77, 27, 44, 244, 71, 199, 52, 235, + 58, 27, 92, 193, 195, 69, 193, 21, 192, 25, 65, 228, 178, 19, 128, 146, 235, 254, 132, 227, 247, 154, 212, + 112, 206, 195, 27, 201, 223, 4, 44, 227, 190, 7, 28, 199, 32, 141, 99, 224, 173, 169, 181, 95, 214, 236, + 171, 91, 186, 169, 234, 14, 49, 159, 41, 201, 169, 81, 47, 72, 142, 146, 175, 198, 240, 65, 228, 73, 21, + 153, 11, 35, 141, 159, 70, 206, 83, 177, 177, 122, 12, 245, 148, 236, 7, 69, 141, 157, 184, 226, 82, 225, + 33, 229, 244, 227, 40, 14, 23, 247, 209, 201, 193, 23, 7, 163, 131, 132, 190, 234, 76, 95, 165, 89, 180, + 197, 49, 46, 214, 121, 55, 155, 202, 16, 28, 245, 154, 214, 136, 176, 232, 187, 91, 34, 254, 230, 20, 7, + 88, 237, 163, 90, 42, 101, 165, 169, 199, 89, 147, 147, 85, 177, 143, 17, 167, 197, 143, 218, 123, 105, 76, + 181, 79, 63, 32, 163, 128, 110, 106, 167, 12, 145, 104, 227, 101, 44, 81, 238, 188, 120, 82, 115, 85, 60, + 78, 205, 149, 220, 160, 91, 42, 228, 252, 166, 218, 145, 106, 113, 7, 191, 197, 67, 72, 45, 151, 153, 114, + 50, 233, 34, 188, 209, 137, 61, 85, 17, 238, 144, 122, 161, 217, 32, 222, 215, 146, 83, 114, 242, 109, 142, + 165, 82, 64, 105, 92, 95, 217, 65, 178, 244, 226, 158, 63, 129, 186, 12, 226, 212, 94, 29, 208, 140, 12, + 142, 20, 208, 68, 185, 16, 138, 236, 192, 98, 7, 204, 247, 135, 238, 37, 243, 253, 241, 128, 124, 76, 87, + 103, 206, 63, 217, 239, 145, 104, 239, 204, 93, 42, 135, 233, 27, 234, 201, 231, 219, 159, 116, 163, 46, + 52, 124, 81, 72, 55, 211, 160, 78, 149, 51, 156, 164, 206, 148, 210, 254, 100, 25, 241, 172, 32, 113, 122, + 32, 136, 171, 34, 153, 241, 194, 42, 41, 124, 77, 182, 149, 47, 110, 189, 132, 222, 230, 177, 10, 70, 195, + 225, 77, 220, 77, 55, 113, 175, 132, 21, 119, 149, 220, 168, 171, 184, 145, 5, 132, 171, 204, 131, 18, 204, + 152, 94, 249, 98, 114, 106, 164, 212, 162, 148, 169, 156, 203, 77, 138, 108, 183, 179, 65, 139, 61, 72, + 246, 139, 97, 180, 59, 115, 174, 230, 57, 85, 7, 181, 75, 24, 19, 214, 125, 79, 116, 114, 74, 140, 218, + 130, 118, 42, 91, 51, 158, 239, 243, 243, 125, 118, 62, 162, 68, 50, 212, 13, 110, 167, 27, 172, 65, 11, + 106, 164, 246, 188, 195, 58, 145, 170, 249, 100, 248, 187, 43, 31, 200, 86, 127, 38, 31, 92, 248, 230, 247, + 56, 178, 150, 214, 171, 48, 68, 214, 40, 50, 23, 175, 72, 56, 206, 74, 155, 231, 180, 6, 194, 187, 42, 194, + 34, 197, 250, 58, 102, 83, 209, 107, 220, 97, 158, 79, 25, 156, 158, 71, 230, 248, 132, 38, 138, 149, 141, + 120, 168, 227, 153, 133, 230, 50, 10, 252, 12, 101, 127, 113, 102, 167, 66, 30, 158, 210, 21, 55, 230, 197, + 59, 52, 178, 145, 86, 34, 40, 108, 202, 40, 138, 91, 44, 155, 144, 162, 144, 14, 217, 150, 0, 20, 238, 188, + 98, 72, 151, 134, 123, 44, 37, 166, 173, 102, 58, 140, 20, 40, 213, 82, 29, 202, 144, 6, 206, 124, 181, 90, + 170, 60, 31, 121, 97, 96, 28, 64, 226, 237, 60, 25, 180, 99, 232, 195, 11, 54, 28, 102, 128, 220, 114, 224, + 63, 141, 188, 243, 143, 218, 63, 201, 63, 223, 36, 95, 254, 108, 229, 42, 76, 35, 221, 27, 162, 89, 6, 37, + 230, 147, 70, 208, 219, 171, 45, 82, 229, 197, 189, 104, 114, 10, 44, 197, 164, 46, 144, 223, 80, 12, 83, + 210, 160, 7, 157, 16, 7, 34, 82, 58, 228, 70, 31, 95, 145, 5, 234, 18, 94, 128, 28, 13, 89, 37, 133, 39, 9, + 41, 160, 135, 250, 14, 212, 191, 130, 12, 214, 62, 119, 156, 211, 113, 83, 57, 43, 16, 187, 106, 9, 189, + 55, 203, 68, 71, 178, 232, 152, 249, 83, 227, 101, 159, 96, 21, 130, 143, 35, 119, 234, 29, 219, 247, 146, + 246, 206, 148, 231, 188, 201, 248, 185, 85, 67, 160, 70, 241, 177, 144, 168, 51, 111, 185, 229, 7, 220, 69, + 103, 126, 213, 90, 226, 29, 209, 183, 220, 89, 238, 91, 174, 130, 238, 97, 108, 250, 161, 241, 139, 159, 9, + 200, 85, 59, 101, 31, 105, 13, 86, 44, 237, 207, 251, 202, 62, 146, 176, 97, 233, 142, 166, 113, 173, 94, + 128, 128, 140, 253, 110, 197, 73, 129, 213, 139, 235, 128, 204, 41, 62, 162, 36, 65, 214, 90, 221, 5, 18, + 83, 59, 36, 223, 125, 77, 128, 253, 141, 3, 198, 182, 193, 245, 105, 41, 227, 25, 109, 141, 16, 111, 214, + 28, 217, 255, 242, 214, 158, 77, 45, 44, 138, 163, 210, 216, 167, 25, 79, 82, 61, 10, 19, 45, 155, 250, 82, + 30, 168, 197, 195, 153, 22, 95, 78, 4, 41, 153, 122, 110, 127, 146, 222, 212, 144, 91, 159, 84, 32, 142, + 204, 81, 98, 216, 174, 153, 30, 181, 195, 142, 103, 216, 31, 244, 46, 22, 183, 110, 15, 169, 126, 178, 107, + 199, 42, 196, 23, 252, 98, 23, 78, 170, 82, 50, 231, 48, 51, 167, 90, 149, 76, 86, 37, 72, 182, 163, 26, + 61, 135, 250, 248, 209, 6, 20, 51, 174, 141, 231, 137, 253, 20, 206, 34, 35, 237, 243, 17, 182, 19, 190, + 113, 233, 235, 104, 187, 138, 254, 246, 43, 0, 30, 247, 149, 197, 155, 239, 194, 241, 54, 110, 14, 11, 199, + 93, 182, 213, 11, 254, 11, 19, 89, 134, 200, 226, 251, 175, 96, 222, 27, 204, 211, 47, 127, 31, 163, 226, + 45, 68, 22, 254, 235, 39, 39, 35, 4, 124, 94, 214, 49, 133, 119, 63, 211, 251, 203, 114, 27, 113, 244, 150, + 85, 41, 153, 83, 77, 110, 22, 147, 155, 85, 203, 173, 140, 220, 158, 114, 185, 141, 248, 182, 222, 236, 7, + 178, 211, 210, 123, 26, 201, 72, 85, 230, 176, 64, 153, 106, 18, 245, 152, 68, 189, 90, 162, 101, 36, 250, + 48, 106, 137, 24, 51, 196, 206, 90, 210, 37, 9, 18, 241, 68, 145, 119, 152, 147, 87, 77, 114, 54, 147, 156, + 93, 75, 174, 74, 91, 20, 63, 220, 246, 145, 252, 35, 142, 151, 212, 22, 213, 101, 14, 11, 148, 185, 20, + 187, 26, 70, 45, 210, 50, 34, 141, 125, 43, 143, 118, 247, 138, 39, 43, 7, 60, 70, 45, 206, 31, 102, 156, + 175, 38, 46, 135, 137, 203, 169, 165, 85, 69, 90, 67, 114, 34, 253, 196, 90, 244, 128, 7, 31, 197, 249, + 195, 140, 243, 213, 164, 213, 96, 210, 106, 212, 210, 170, 34, 173, 62, 219, 121, 52, 194, 67, 72, 37, 62, + 127, 152, 113, 190, 154, 180, 154, 76, 90, 205, 90, 90, 101, 164, 245, 132, 75, 107, 139, 175, 69, 253, 68, + 252, 150, 116, 78, 158, 112, 249, 168, 74, 28, 174, 44, 81, 77, 150, 45, 38, 203, 86, 45, 203, 50, 178, + 188, 207, 101, 217, 161, 209, 213, 179, 104, 172, 63, 136, 22, 50, 157, 70, 173, 78, 62, 91, 77, 78, 62, + 147, 147, 95, 203, 169, 140, 156, 54, 162, 206, 29, 182, 21, 182, 219, 149, 220, 33, 143, 115, 228, 14, + 121, 156, 83, 77, 102, 51, 38, 179, 89, 45, 179, 42, 86, 237, 181, 198, 126, 248, 72, 182, 106, 241, 249, + 195, 140, 243, 213, 164, 53, 103, 210, 154, 215, 210, 170, 210, 217, 30, 198, 195, 208, 145, 143, 255, 48, + 242, 14, 147, 121, 135, 57, 121, 213, 36, 23, 48, 201, 5, 169, 138, 61, 142, 212, 8, 127, 174, 169, 71, + 162, 120, 71, 163, 228, 98, 40, 76, 168, 141, 156, 127, 184, 34, 191, 90, 37, 13, 30, 233, 197, 180, 103, + 36, 16, 237, 247, 204, 212, 55, 43, 245, 205, 78, 125, 163, 77, 252, 195, 112, 155, 2, 216, 85, 212, 244, + 199, 132, 154, 126, 134, 82, 35, 90, 241, 243, 134, 6, 2, 217, 136, 86, 172, 172, 150, 82, 67, 90, 186, 62, + 53, 147, 26, 130, 191, 228, 21, 169, 89, 158, 6, 250, 164, 62, 146, 38, 95, 213, 67, 214, 160, 230, 149, 0, + 126, 46, 1, 156, 128, 86, 156, 203, 130, 248, 69, 92, 137, 169, 110, 122, 94, 214, 251, 207, 2, 200, 78, + 103, 182, 228, 43, 115, 97, 94, 243, 131, 110, 10, 106, 161, 203, 91, 52, 144, 77, 227, 104, 52, 209, 104, + 155, 38, 188, 193, 85, 9, 160, 93, 85, 221, 76, 221, 242, 211, 117, 211, 95, 152, 77, 145, 107, 76, 91, 13, + 99, 154, 206, 181, 35, 112, 140, 185, 29, 192, 183, 84, 174, 43, 50, 93, 111, 238, 235, 70, 58, 179, 225, + 100, 223, 216, 144, 107, 36, 139, 239, 238, 85, 255, 166, 148, 98, 131, 43, 69, 151, 126, 187, 243, 19, 17, + 118, 172, 6, 182, 170, 54, 173, 134, 237, 26, 82, 35, 176, 162, 70, 48, 157, 53, 125, 9, 168, 102, 148, + 235, 250, 230, 220, 112, 149, 47, 50, 15, 102, 83, 127, 182, 44, 202, 155, 169, 194, 77, 139, 99, 76, 187, + 197, 93, 72, 226, 80, 170, 117, 203, 106, 1, 255, 103, 169, 181, 109, 226, 95, 150, 90, 79, 157, 169, 53, + 53, 178, 212, 154, 255, 200, 132, 90, 173, 103, 115, 252, 83, 130, 208, 212, 241, 175, 96, 171, 188, 213, + 213, 191, 41, 53, 120, 200, 213, 32, 177, 147, 15, 228, 173, 80, 4, 246, 202, 89, 72, 226, 59, 161, 75, + 171, 70, 210, 117, 153, 195, 171, 68, 18, 47, 108, 4, 89, 72, 178, 7, 103, 248, 23, 13, 248, 175, 160, 34, + 220, 234, 234, 223, 180, 34, 48, 191, 115, 217, 33, 82, 214, 39, 199, 227, 19, 158, 162, 44, 145, 75, 220, + 231, 166, 160, 121, 20, 81, 229, 39, 62, 132, 140, 123, 153, 190, 95, 221, 74, 228, 26, 129, 154, 37, 51, + 151, 180, 44, 174, 176, 233, 101, 42, 25, 94, 39, 223, 182, 25, 38, 116, 44, 211, 5, 231, 40, 20, 107, 34, + 183, 181, 238, 55, 165, 4, 34, 140, 16, 5, 15, 226, 128, 194, 234, 86, 34, 115, 198, 114, 173, 138, 181, + 146, 34, 247, 185, 41, 128, 158, 38, 252, 187, 41, 185, 252, 231, 180, 97, 133, 76, 36, 74, 125, 211, 117, + 171, 41, 107, 77, 76, 201, 160, 83, 45, 175, 145, 69, 201, 192, 15, 110, 142, 198, 45, 95, 218, 200, 185, + 212, 144, 107, 84, 168, 185, 220, 234, 234, 223, 116, 139, 249, 22, 2, 111, 149, 0, 122, 198, 1, 194, 73, + 165, 31, 105, 190, 247, 185, 118, 192, 119, 22, 248, 125, 53, 72, 102, 75, 247, 156, 86, 150, 63, 161, 236, + 173, 94, 226, 62, 55, 13, 18, 243, 75, 162, 8, 194, 170, 144, 77, 158, 33, 75, 180, 159, 76, 139, 131, 87, + 169, 212, 236, 170, 30, 178, 142, 224, 239, 86, 191, 119, 177, 216, 234, 39, 198, 53, 231, 4, 242, 46, 77, + 106, 198, 64, 76, 7, 62, 47, 104, 183, 78, 49, 46, 54, 143, 86, 131, 121, 218, 121, 184, 53, 28, 95, 44, + 122, 221, 45, 252, 120, 73, 158, 207, 150, 22, 208, 226, 78, 244, 122, 246, 104, 143, 156, 93, 173, 23, + 246, 186, 175, 32, 247, 63, 181, 133, 214, 160, 92, 87, 51, 224, 79, 215, 76, 237, 23, 56, 246, 225, 12, + 30, 225, 185, 25, 253, 154, 92, 19, 206, 53, 32, 71, 167, 63, 135, 74, 54, 224, 211, 128, 28, 252, 6, 149, + 79, 60, 117, 35, 174, 167, 54, 209, 190, 160, 215, 197, 159, 248, 23, 77, 79, 149, 124, 152, 40, 249, 154, + 86, 179, 157, 107, 239, 120, 217, 239, 176, 70, 169, 210, 143, 104, 199, 169, 19, 110, 190, 35, 85, 227, + 229, 239, 107, 255, 78, 239, 202, 255, 164, 43, 199, 180, 46, 99, 70, 209, 66, 213, 149, 122, 252, 39, 189, + 203, 152, 202, 162, 231, 152, 255, 46, 27, 98, 233, 194, 210, 155, 44, 191, 117, 188, 19, 89, 155, 184, + 226, 36, 186, 235, 95, 225, 173, 45, 205, 145, 202, 99, 237, 241, 206, 7, 96, 153, 255, 155, 73, 147, 151, + 191, 7, 239, 138, 182, 250, 12, 238, 144, 126, 227, 14, 173, 13, 56, 167, 137, 90, 99, 154, 54, 121, 158, + 89, 247, 103, 41, 61, 217, 133, 187, 177, 137, 242, 199, 252, 247, 126, 216, 85, 223, 115, 207, 57, 253, + 164, 39, 112, 237, 12, 249, 142, 118, 88, 160, 21, 177, 84, 91, 252, 197, 86, 245, 211, 158, 196, 111, 29, + 253, 6, 211, 7, 186, 238, 44, 186, 194, 74, 93, 241, 152, 246, 107, 59, 3, 19, 148, 85, 94, 126, 66, 172, + 87, 98, 170, 218, 41, 235, 33, 71, 218, 213, 144, 80, 126, 146, 144, 74, 143, 111, 97, 228, 209, 220, 155, + 164, 108, 100, 253, 120, 30, 73, 157, 97, 124, 154, 121, 245, 50, 230, 177, 102, 237, 209, 116, 214, 115, + 254, 187, 65, 199, 20, 204, 17, 87, 25, 210, 85, 108, 205, 71, 138, 13, 148, 26, 61, 3, 156, 84, 26, 253, + 140, 194, 186, 184, 31, 55, 224, 7, 204, 225, 81, 123, 151, 239, 176, 145, 110, 19, 75, 119, 121, 74, 123, + 25, 252, 201, 137, 28, 89, 104, 182, 242, 30, 150, 212, 42, 159, 80, 123, 62, 95, 113, 135, 68, 155, 94, + 186, 195, 255, 133, 55, 249, 3, 222, 165, 79, 188, 48, 39, 247, 254, 148, 243, 195, 1, 220, 241, 4, 90, 44, + 219, 134, 237, 61, 32, 251, 145, 116, 224, 20, 206, 37, 181, 253, 16, 202, 239, 179, 53, 91, 252, 169, 143, + 18, 140, 187, 153, 224, 92, 162, 232, 10, 236, 60, 162, 57, 92, 191, 215, 236, 124, 173, 236, 236, 212, + 236, 92, 179, 115, 205, 206, 53, 59, 103, 176, 243, 79, 156, 157, 199, 112, 111, 177, 234, 153, 149, 167, + 193, 20, 141, 253, 112, 86, 205, 217, 215, 201, 217, 102, 205, 217, 53, 103, 215, 156, 93, 115, 118, 6, + 103, 111, 44, 115, 118, 205, 208, 215, 202, 208, 70, 205, 208, 53, 67, 215, 12, 93, 51, 244, 10, 134, 30, + 129, 196, 240, 121, 216, 146, 106, 134, 190, 78, 134, 118, 107, 134, 174, 25, 186, 102, 232, 154, 161, 51, + 24, 250, 33, 103, 232, 223, 72, 175, 126, 131, 103, 252, 14, 253, 238, 154, 163, 175, 147, 163, 237, 154, + 163, 107, 142, 174, 57, 186, 230, 232, 21, 94, 116, 130, 163, 107, 134, 190, 86, 134, 182, 106, 134, 174, + 25, 186, 102, 232, 111, 156, 161, 21, 242, 184, 179, 51, 239, 140, 175, 136, 157, 235, 153, 119, 53, 59, + 215, 236, 252, 53, 178, 115, 140, 241, 58, 216, 249, 238, 204, 188, 251, 154, 216, 185, 158, 121, 87, 179, + 115, 205, 206, 53, 59, 103, 177, 243, 215, 50, 243, 238, 107, 226, 236, 122, 230, 93, 205, 217, 53, 103, + 215, 156, 157, 197, 217, 119, 115, 230, 221, 215, 196, 208, 245, 204, 187, 154, 161, 107, 134, 174, 25, + 122, 21, 67, 223, 173, 153, 119, 95, 19, 67, 215, 51, 239, 106, 134, 174, 25, 186, 102, 232, 44, 134, 190, + 171, 51, 239, 190, 38, 142, 174, 103, 222, 213, 28, 93, 115, 116, 205, 209, 171, 188, 232, 187, 53, 243, + 238, 107, 98, 232, 122, 230, 93, 205, 208, 53, 67, 127, 235, 12, 221, 131, 82, 40, 197, 4, 195, 72, 115, + 59, 184, 206, 86, 96, 103, 15, 180, 180, 165, 217, 240, 55, 131, 183, 108, 174, 133, 157, 243, 185, 80, + 150, 153, 43, 197, 10, 46, 195, 20, 79, 83, 79, 86, 183, 18, 100, 125, 83, 193, 126, 226, 42, 182, 25, 99, + 220, 58, 154, 57, 239, 182, 204, 173, 22, 220, 93, 197, 173, 226, 138, 252, 217, 123, 87, 165, 109, 66, + 131, 54, 83, 58, 84, 86, 219, 158, 113, 109, 139, 55, 65, 125, 155, 42, 117, 23, 181, 207, 147, 116, 225, + 170, 181, 239, 47, 90, 163, 132, 238, 217, 223, 136, 238, 61, 229, 186, 151, 180, 27, 178, 55, 250, 64, 19, + 49, 93, 143, 144, 189, 11, 17, 93, 153, 103, 178, 125, 81, 185, 236, 109, 243, 68, 235, 89, 198, 183, 199, + 19, 53, 165, 39, 212, 158, 104, 237, 137, 86, 229, 231, 39, 49, 159, 106, 248, 179, 86, 9, 188, 46, 193, + 209, 56, 127, 13, 239, 120, 23, 214, 130, 88, 53, 71, 215, 28, 93, 115, 244, 29, 227, 104, 99, 201, 247, + 254, 122, 57, 250, 113, 204, 167, 185, 12, 253, 44, 197, 42, 155, 36, 111, 246, 83, 133, 39, 137, 94, 220, + 195, 212, 170, 63, 145, 87, 158, 167, 77, 250, 101, 148, 38, 232, 45, 244, 167, 1, 9, 228, 100, 19, 254, + 244, 136, 167, 241, 28, 150, 193, 26, 9, 204, 155, 196, 236, 1, 245, 248, 80, 138, 50, 79, 103, 115, 150, + 189, 54, 134, 88, 221, 122, 237, 210, 173, 215, 149, 90, 239, 101, 218, 97, 209, 22, 149, 101, 35, 174, 70, + 11, 213, 122, 83, 69, 3, 159, 17, 238, 39, 36, 225, 84, 175, 80, 123, 129, 127, 21, 116, 113, 170, 181, 0, + 5, 31, 62, 209, 246, 207, 201, 103, 176, 137, 113, 132, 46, 98, 108, 1, 53, 49, 32, 13, 101, 61, 127, 44, + 141, 58, 27, 128, 14, 207, 160, 124, 90, 23, 255, 13, 158, 212, 1, 156, 2, 66, 145, 201, 227, 45, 224, 117, + 74, 50, 65, 78, 252, 19, 190, 159, 71, 24, 163, 238, 253, 111, 132, 214, 61, 122, 242, 38, 126, 166, 238, + 250, 64, 155, 21, 140, 74, 221, 211, 60, 201, 22, 127, 7, 117, 116, 164, 50, 254, 10, 134, 186, 30, 221, + 88, 37, 209, 42, 90, 242, 56, 165, 111, 151, 139, 51, 57, 220, 83, 12, 200, 71, 68, 79, 178, 1, 127, 54, + 148, 175, 206, 85, 101, 227, 76, 206, 218, 248, 171, 142, 51, 101, 217, 72, 149, 182, 164, 117, 239, 49, + 188, 207, 12, 124, 214, 207, 132, 217, 102, 66, 110, 76, 235, 126, 72, 174, 189, 169, 160, 105, 51, 208, + 46, 7, 52, 6, 109, 98, 139, 122, 42, 168, 113, 51, 208, 36, 185, 247, 210, 140, 52, 3, 53, 18, 117, 113, 6, + 255, 163, 87, 210, 186, 22, 38, 186, 26, 57, 164, 241, 43, 135, 253, 223, 224, 45, 79, 35, 159, 151, 219, + 100, 237, 239, 178, 205, 173, 108, 37, 44, 64, 25, 209, 157, 82, 219, 102, 109, 191, 5, 216, 27, 41, 22, + 192, 252, 25, 220, 69, 39, 75, 162, 115, 57, 162, 12, 29, 146, 217, 117, 200, 230, 25, 241, 122, 242, 157, + 223, 18, 202, 31, 1, 187, 15, 145, 215, 33, 183, 172, 231, 80, 243, 101, 252, 138, 92, 121, 53, 186, 80, + 78, 158, 229, 116, 229, 57, 248, 234, 248, 203, 231, 127, 135, 182, 142, 61, 201, 207, 116, 55, 196, 25, + 239, 189, 30, 13, 153, 69, 26, 98, 222, 58, 13, 121, 8, 152, 126, 166, 242, 171, 165, 251, 35, 89, 230, + 242, 90, 241, 28, 202, 45, 99, 123, 115, 250, 84, 68, 230, 105, 63, 255, 29, 69, 34, 222, 198, 94, 146, + 132, 109, 34, 86, 81, 74, 251, 54, 224, 12, 62, 253, 130, 208, 92, 143, 182, 205, 35, 109, 179, 110, 161, + 182, 157, 82, 124, 240, 45, 73, 235, 152, 90, 239, 89, 184, 61, 4, 192, 182, 135, 147, 139, 197, 209, 160, + 139, 63, 241, 246, 134, 37, 97, 124, 206, 116, 28, 118, 22, 15, 100, 255, 105, 74, 94, 200, 124, 173, 119, + 197, 154, 254, 14, 119, 94, 231, 61, 175, 70, 155, 85, 58, 148, 214, 222, 223, 53, 241, 3, 129, 151, 126, + 155, 82, 218, 253, 8, 242, 63, 83, 164, 110, 83, 27, 68, 61, 208, 179, 74, 222, 144, 14, 58, 62, 135, 50, + 104, 111, 153, 55, 100, 0, 146, 182, 194, 27, 50, 111, 212, 27, 218, 0, 180, 81, 58, 239, 225, 243, 45, + 211, 161, 140, 136, 151, 92, 114, 158, 136, 43, 26, 146, 134, 39, 75, 70, 210, 204, 40, 253, 48, 85, 154, + 183, 141, 140, 178, 200, 204, 31, 73, 123, 124, 122, 199, 119, 156, 223, 151, 159, 242, 87, 242, 71, 29, + 201, 30, 164, 175, 102, 113, 10, 85, 13, 101, 59, 146, 245, 212, 116, 109, 85, 207, 188, 170, 209, 101, + 181, 166, 166, 219, 209, 140, 90, 216, 121, 226, 77, 211, 242, 149, 71, 123, 150, 203, 175, 66, 38, 121, + 77, 25, 84, 158, 102, 72, 34, 173, 85, 114, 180, 90, 245, 172, 228, 21, 170, 39, 61, 83, 94, 85, 68, 91, + 178, 158, 23, 35, 184, 234, 42, 241, 86, 178, 78, 235, 5, 228, 148, 141, 195, 179, 76, 109, 92, 85, 55, + 249, 202, 98, 245, 203, 150, 85, 182, 46, 229, 213, 81, 33, 175, 146, 62, 72, 66, 227, 43, 251, 32, 105, + 134, 54, 35, 134, 118, 106, 134, 174, 25, 122, 45, 94, 206, 178, 150, 214, 236, 92, 179, 243, 215, 206, + 206, 15, 227, 51, 144, 203, 218, 212, 73, 37, 126, 158, 81, 60, 209, 227, 108, 139, 163, 24, 38, 205, 154, + 76, 71, 174, 177, 223, 232, 165, 102, 67, 208, 232, 36, 205, 171, 156, 43, 102, 67, 136, 17, 78, 236, 201, + 207, 50, 81, 189, 151, 57, 171, 65, 53, 238, 116, 31, 120, 226, 19, 141, 223, 34, 107, 124, 137, 240, 91, + 30, 165, 190, 76, 244, 251, 170, 70, 183, 84, 242, 74, 203, 252, 30, 220, 31, 247, 103, 154, 71, 82, 254, + 145, 199, 178, 196, 94, 77, 155, 220, 23, 109, 195, 213, 159, 48, 6, 93, 105, 92, 181, 5, 146, 51, 73, 238, + 30, 89, 100, 31, 82, 155, 70, 176, 146, 22, 217, 161, 209, 137, 98, 243, 95, 238, 82, 4, 121, 53, 166, 171, + 164, 242, 144, 106, 244, 129, 207, 103, 98, 115, 65, 170, 244, 94, 3, 154, 99, 164, 147, 60, 2, 66, 61, + 160, 49, 195, 120, 212, 72, 39, 73, 96, 11, 187, 89, 223, 232, 170, 218, 132, 10, 199, 52, 250, 223, 71, + 99, 73, 12, 251, 248, 123, 21, 188, 13, 200, 11, 136, 141, 237, 40, 90, 32, 34, 99, 183, 201, 23, 189, 26, + 188, 99, 236, 242, 49, 126, 74, 115, 246, 112, 28, 25, 163, 151, 155, 34, 247, 18, 125, 0, 196, 221, 162, + 113, 61, 155, 24, 199, 164, 251, 35, 227, 216, 52, 62, 226, 144, 221, 65, 116, 81, 58, 14, 228, 181, 40, + 122, 137, 146, 8, 8, 121, 255, 90, 112, 255, 153, 144, 20, 111, 46, 124, 2, 188, 243, 255, 64, 234, 105, + 39, 41, 203, 243, 29, 106, 73, 234, 250, 159, 50, 175, 95, 142, 105, 127, 7, 111, 120, 29, 81, 237, 124, + 105, 230, 107, 194, 143, 218, 54, 92, 245, 153, 34, 250, 199, 52, 2, 188, 14, 109, 72, 246, 8, 245, 168, + 71, 104, 221, 186, 86, 248, 47, 212, 31, 75, 190, 125, 82, 162, 66, 210, 159, 163, 121, 61, 63, 65, 29, 95, + 16, 159, 103, 255, 185, 215, 98, 225, 86, 73, 45, 95, 234, 27, 81, 233, 77, 146, 224, 105, 165, 181, 16, + 105, 182, 53, 191, 57, 182, 85, 161, 152, 143, 251, 99, 237, 55, 13, 247, 123, 123, 191, 134, 86, 214, 226, + 107, 158, 112, 102, 128, 27, 141, 243, 152, 132, 62, 174, 135, 154, 210, 220, 37, 28, 223, 113, 201, 251, + 159, 66, 58, 39, 127, 126, 70, 190, 161, 69, 254, 222, 117, 160, 255, 28, 202, 176, 183, 46, 207, 183, 63, + 42, 175, 189, 57, 174, 205, 150, 224, 42, 139, 139, 50, 20, 35, 141, 151, 151, 190, 3, 239, 219, 36, 111, + 221, 37, 201, 254, 66, 229, 217, 44, 17, 155, 90, 97, 64, 22, 215, 32, 203, 234, 208, 236, 182, 57, 105, + 192, 28, 242, 176, 132, 183, 212, 171, 187, 42, 142, 125, 159, 120, 243, 164, 20, 179, 231, 177, 201, 163, + 200, 89, 119, 88, 158, 223, 214, 186, 38, 139, 155, 39, 205, 180, 38, 220, 231, 115, 137, 78, 105, 94, 244, + 135, 104, 221, 109, 250, 108, 121, 13, 240, 137, 83, 177, 55, 129, 243, 104, 89, 223, 130, 173, 104, 88, + 238, 91, 52, 190, 66, 246, 149, 17, 44, 130, 250, 227, 244, 217, 75, 89, 63, 131, 102, 130, 6, 20, 219, 97, + 243, 180, 90, 196, 199, 141, 37, 235, 39, 102, 4, 126, 93, 248, 103, 99, 89, 68, 18, 207, 224, 142, 31, + 104, 93, 5, 203, 217, 140, 102, 84, 87, 101, 196, 180, 55, 98, 223, 98, 111, 228, 103, 178, 92, 241, 187, + 191, 165, 241, 128, 51, 90, 13, 173, 178, 108, 142, 196, 105, 121, 215, 223, 94, 159, 117, 149, 196, 147, + 53, 248, 91, 206, 27, 158, 231, 173, 201, 145, 226, 58, 251, 52, 231, 1, 103, 231, 136, 246, 223, 38, 255, + 103, 51, 206, 169, 172, 111, 115, 210, 28, 157, 102, 247, 78, 41, 162, 227, 147, 78, 89, 100, 129, 125, + 222, 223, 193, 79, 135, 86, 64, 137, 181, 13, 232, 117, 205, 201, 119, 195, 190, 240, 245, 232, 155, 71, + 111, 253, 22, 48, 21, 111, 253, 150, 122, 15, 152, 202, 243, 191, 179, 214, 95, 253, 168, 188, 75, 17, 125, + 189, 42, 254, 201, 146, 101, 90, 11, 126, 208, 186, 244, 126, 159, 161, 236, 89, 52, 71, 55, 121, 174, 10, + 215, 4, 228, 69, 49, 94, 247, 185, 199, 221, 74, 204, 74, 97, 171, 5, 116, 144, 245, 205, 174, 22, 184, + 170, 57, 186, 73, 252, 194, 20, 118, 126, 148, 179, 172, 91, 24, 251, 23, 156, 99, 45, 237, 77, 132, 237, + 251, 75, 206, 85, 1, 69, 79, 91, 5, 228, 251, 156, 230, 180, 179, 55, 56, 37, 235, 132, 86, 97, 243, 146, + 82, 159, 81, 239, 170, 65, 62, 86, 139, 164, 238, 82, 12, 171, 149, 146, 250, 148, 60, 237, 86, 74, 234, + 248, 127, 64, 101, 175, 199, 231, 190, 170, 217, 147, 171, 81, 189, 89, 93, 248, 137, 226, 204, 95, 120, + 173, 216, 170, 144, 47, 112, 108, 115, 105, 224, 28, 159, 45, 174, 35, 201, 53, 89, 232, 193, 179, 213, + 131, 213, 99, 94, 77, 234, 107, 205, 169, 133, 51, 111, 188, 73, 125, 179, 164, 55, 238, 210, 152, 139, 69, + 253, 47, 252, 100, 223, 109, 210, 167, 187, 173, 27, 121, 104, 86, 151, 209, 51, 169, 159, 53, 161, 218, + 96, 189, 111, 74, 78, 108, 44, 245, 238, 202, 105, 21, 162, 213, 101, 181, 65, 254, 220, 41, 27, 127, 189, + 65, 249, 216, 75, 235, 172, 238, 146, 124, 84, 40, 166, 101, 242, 51, 141, 99, 30, 243, 62, 215, 24, 234, + 112, 204, 143, 112, 165, 181, 71, 227, 157, 177, 84, 30, 196, 227, 110, 87, 44, 147, 6, 72, 162, 65, 227, + 63, 13, 26, 7, 194, 79, 151, 108, 165, 67, 222, 209, 221, 149, 201, 50, 134, 105, 137, 60, 34, 236, 231, + 52, 107, 1, 61, 103, 49, 246, 47, 214, 36, 13, 169, 167, 114, 78, 156, 136, 71, 159, 72, 66, 199, 196, 150, + 155, 169, 103, 87, 241, 74, 176, 135, 59, 39, 223, 60, 160, 113, 123, 140, 67, 204, 233, 10, 33, 29, 143, + 124, 209, 6, 181, 15, 157, 175, 26, 51, 185, 231, 218, 130, 28, 140, 31, 167, 165, 243, 61, 89, 122, 63, + 225, 211, 203, 49, 185, 219, 55, 255, 162, 28, 206, 114, 140, 130, 237, 76, 146, 94, 63, 42, 246, 198, 219, + 33, 169, 126, 188, 3, 59, 145, 164, 87, 97, 222, 237, 157, 75, 139, 239, 69, 34, 191, 245, 183, 182, 23, + 137, 33, 93, 177, 106, 47, 18, 28, 101, 73, 99, 176, 122, 63, 3, 121, 246, 95, 145, 253, 12, 228, 121, 141, + 87, 189, 27, 73, 83, 66, 253, 46, 237, 70, 242, 45, 237, 24, 245, 125, 198, 222, 15, 106, 22, 22, 123, 72, + 239, 211, 253, 49, 14, 88, 101, 22, 100, 205, 196, 215, 193, 196, 50, 179, 214, 76, 188, 110, 38, 94, 222, + 229, 163, 202, 222, 50, 245, 206, 80, 53, 23, 43, 184, 56, 28, 182, 39, 23, 139, 78, 119, 112, 188, 8, 2, + 151, 254, 133, 125, 246, 205, 167, 127, 97, 127, 24, 177, 245, 3, 26, 107, 123, 27, 239, 219, 18, 241, 117, + 176, 196, 215, 135, 153, 57, 163, 222, 193, 116, 161, 135, 253, 73, 231, 24, 147, 173, 62, 37, 227, 189, + 227, 133, 9, 223, 38, 199, 11, 35, 236, 143, 122, 84, 100, 52, 98, 121, 59, 44, 57, 194, 36, 156, 28, 117, + 46, 22, 236, 193, 247, 224, 85, 88, 48, 227, 67, 184, 55, 126, 121, 177, 120, 61, 132, 50, 77, 61, 220, + 225, 233, 100, 252, 27, 220, 79, 135, 131, 93, 120, 139, 201, 110, 239, 120, 209, 8, 102, 118, 64, 227, 70, + 147, 163, 254, 122, 110, 20, 110, 29, 13, 47, 22, 253, 189, 9, 190, 66, 119, 48, 194, 100, 56, 160, 55, 25, + 182, 161, 56, 124, 217, 199, 170, 15, 49, 11, 111, 50, 156, 240, 239, 128, 132, 17, 182, 135, 3, 150, 140, + 241, 165, 219, 237, 46, 125, 107, 247, 40, 25, 195, 109, 230, 80, 178, 135, 23, 108, 227, 77, 245, 240, + 215, 225, 63, 142, 23, 14, 166, 99, 246, 245, 128, 37, 67, 188, 126, 187, 191, 139, 201, 175, 99, 44, 227, + 65, 186, 197, 190, 78, 240, 118, 191, 142, 59, 4, 236, 96, 72, 136, 238, 99, 229, 182, 199, 3, 60, 55, 24, + 31, 98, 210, 99, 201, 96, 76, 18, 232, 142, 247, 240, 178, 173, 238, 24, 95, 102, 255, 205, 24, 191, 13, + 198, 244, 109, 103, 178, 135, 55, 217, 153, 176, 14, 113, 143, 8, 18, 21, 237, 79, 74, 105, 42, 118, 120, + 212, 167, 178, 71, 123, 84, 255, 201, 136, 110, 7, 87, 98, 114, 212, 107, 211, 205, 251, 71, 112, 3, 45, + 220, 223, 179, 47, 22, 240, 113, 188, 112, 67, 74, 2, 150, 24, 44, 209, 165, 4, 210, 62, 150, 7, 245, 113, + 66, 74, 128, 74, 182, 246, 187, 152, 78, 218, 3, 122, 220, 240, 53, 38, 71, 88, 81, 35, 236, 118, 14, 233, + 57, 221, 14, 105, 85, 183, 211, 166, 179, 189, 54, 125, 235, 237, 93, 44, 6, 253, 73, 176, 208, 95, 56, + 225, 228, 96, 200, 14, 70, 187, 252, 76, 231, 128, 31, 132, 221, 35, 130, 48, 220, 219, 135, 199, 239, 237, + 247, 232, 158, 225, 112, 123, 255, 12, 7, 38, 134, 154, 71, 6, 99, 19, 136, 109, 119, 143, 4, 50, 220, 29, + 176, 4, 139, 254, 7, 13, 40, 120, 20, 78, 51, 104, 242, 214, 47, 212, 80, 177, 251, 142, 67, 74, 1, 31, 92, + 106, 146, 3, 98, 242, 97, 38, 151, 54, 186, 198, 9, 64, 30, 77, 37, 183, 53, 148, 2, 212, 56, 28, 188, 1, + 17, 14, 218, 111, 160, 13, 191, 220, 198, 199, 28, 142, 152, 52, 249, 164, 246, 142, 198, 54, 221, 198, + 101, 65, 108, 208, 110, 22, 14, 6, 132, 206, 30, 147, 251, 94, 151, 146, 222, 46, 201, 182, 59, 192, 214, + 190, 133, 55, 237, 190, 196, 243, 91, 3, 120, 204, 228, 104, 194, 209, 49, 205, 22, 67, 199, 112, 172, 23, + 150, 165, 235, 141, 38, 3, 201, 106, 152, 12, 36, 163, 225, 132, 131, 126, 91, 20, 109, 227, 25, 29, 202, + 180, 113, 181, 121, 231, 128, 146, 73, 159, 244, 184, 127, 208, 166, 186, 178, 39, 213, 76, 180, 6, 38, + 234, 140, 134, 196, 62, 19, 86, 251, 131, 9, 214, 126, 180, 15, 133, 156, 198, 188, 101, 232, 134, 13, 50, + 57, 2, 153, 52, 77, 56, 120, 3, 82, 178, 194, 131, 209, 46, 177, 81, 183, 143, 26, 48, 28, 243, 236, 225, + 152, 101, 15, 183, 196, 137, 45, 126, 162, 47, 78, 244, 217, 137, 163, 62, 49, 193, 164, 221, 102, 137, + 113, 188, 240, 49, 53, 143, 23, 54, 164, 7, 64, 1, 205, 176, 61, 217, 34, 66, 155, 144, 176, 251, 7, 251, + 220, 68, 178, 16, 51, 154, 249, 109, 10, 229, 244, 104, 40, 225, 36, 236, 246, 217, 182, 95, 170, 18, 191, + 176, 50, 32, 246, 225, 100, 12, 85, 64, 197, 34, 14, 221, 157, 144, 50, 31, 238, 147, 212, 118, 198, 93, + 168, 104, 248, 114, 180, 143, 74, 55, 122, 73, 73, 103, 48, 198, 100, 176, 213, 131, 188, 23, 102, 56, 232, + 81, 229, 127, 29, 147, 74, 14, 119, 169, 208, 112, 220, 97, 9, 87, 87, 232, 123, 176, 26, 95, 119, 125, + 210, 45, 64, 93, 187, 209, 254, 25, 91, 139, 116, 0, 158, 214, 16, 62, 247, 193, 3, 216, 7, 191, 96, 12, + 222, 196, 164, 13, 44, 177, 187, 183, 29, 53, 232, 163, 131, 62, 109, 255, 192, 18, 182, 241, 131, 238, + 178, 141, 31, 12, 48, 42, 164, 111, 126, 131, 233, 155, 49, 99, 250, 214, 76, 170, 91, 211, 118, 3, 40, + 192, 84, 111, 62, 119, 61, 83, 60, 7, 53, 57, 98, 10, 219, 102, 76, 209, 104, 189, 112, 93, 221, 112, 92, + 78, 20, 182, 203, 137, 2, 52, 135, 17, 5, 149, 68, 162, 48, 172, 203, 17, 5, 251, 87, 19, 197, 101, 137, + 162, 97, 6, 179, 41, 39, 10, 98, 140, 55, 40, 46, 37, 81, 64, 54, 17, 133, 97, 114, 162, 192, 19, 91, 252, + 68, 95, 156, 232, 179, 19, 55, 77, 20, 246, 45, 35, 138, 53, 214, 39, 221, 2, 114, 136, 226, 175, 218, 8, + 42, 242, 186, 40, 53, 152, 124, 79, 152, 134, 197, 152, 161, 21, 48, 5, 179, 90, 10, 102, 104, 4, 45, 125, + 110, 112, 102, 8, 252, 192, 153, 170, 152, 193, 104, 113, 102, 48, 204, 198, 11, 195, 53, 157, 22, 247, 33, + 108, 93, 80, 131, 99, 191, 48, 185, 27, 193, 74, 227, 129, 221, 172, 221, 136, 219, 192, 14, 73, 55, 194, + 110, 112, 55, 66, 69, 14, 110, 131, 113, 3, 247, 33, 240, 235, 22, 251, 218, 231, 95, 251, 244, 245, 166, + 105, 193, 116, 110, 23, 45, 172, 177, 62, 133, 253, 135, 199, 64, 11, 91, 208, 16, 38, 80, 157, 54, 124, + 182, 181, 215, 240, 63, 156, 43, 72, 20, 134, 203, 183, 148, 66, 179, 78, 202, 102, 152, 54, 211, 54, 72, + 21, 84, 49, 159, 182, 166, 190, 160, 138, 102, 163, 105, 69, 180, 225, 91, 179, 152, 54, 86, 60, 54, 218, + 199, 138, 30, 105, 58, 77, 254, 72, 71, 87, 211, 147, 209, 104, 137, 231, 52, 188, 192, 20, 199, 83, 183, + 17, 209, 86, 115, 234, 198, 117, 33, 243, 199, 142, 109, 203, 115, 162, 243, 179, 102, 84, 247, 192, 140, + 239, 51, 211, 77, 225, 24, 5, 173, 166, 25, 68, 247, 132, 7, 139, 99, 111, 106, 79, 197, 177, 53, 109, 70, + 215, 182, 230, 49, 30, 126, 16, 151, 105, 153, 86, 244, 92, 179, 225, 70, 101, 188, 25, 190, 36, 127, 151, + 185, 17, 157, 159, 53, 103, 51, 113, 236, 186, 141, 168, 140, 103, 204, 252, 200, 105, 211, 173, 168, 110, + 129, 161, 71, 199, 115, 195, 246, 99, 236, 195, 240, 213, 46, 48, 202, 43, 214, 53, 12, 195, 204, 126, 230, + 125, 109, 0, 90, 253, 69, 99, 27, 169, 26, 170, 30, 166, 145, 223, 195, 92, 253, 44, 131, 63, 107, 3, 20, + 115, 14, 253, 225, 205, 248, 153, 169, 231, 25, 133, 122, 180, 75, 207, 11, 183, 123, 208, 72, 183, 123, + 59, 24, 17, 233, 189, 194, 18, 131, 35, 236, 177, 255, 31, 112, 172, 255, 159, 246, 95, 218, 33, 77, 55, + 61, 133, 207, 255, 162, 176, 34, 219, 54, 211, 167, 105, 53, 255, 5, 141, 102, 78, 33, 92, 12, 74, 127, + 130, 43, 251, 100, 93, 78, 161, 157, 255, 73, 147, 177, 63, 97, 88, 56, 60, 24, 147, 137, 56, 24, 19, 209, + 133, 255, 31, 210, 240, 246, 202, 151, 206, 44, 153, 0, 0, 0, 190, 109, 107, 66, 83, 120, 156, 93, 78, 203, + 14, 130, 48, 16, 236, 205, 223, 240, 19, 0, 131, 224, 17, 202, 195, 134, 173, 26, 168, 17, 188, 129, 177, + 9, 87, 77, 154, 152, 205, 254, 187, 45, 32, 7, 231, 50, 147, 153, 157, 205, 200, 42, 53, 88, 212, 124, 68, + 159, 90, 224, 26, 61, 234, 102, 186, 137, 76, 99, 16, 238, 233, 40, 148, 70, 63, 10, 168, 206, 27, 141, + 142, 155, 235, 104, 15, 210, 210, 182, 244, 2, 130, 14, 12, 66, 210, 25, 76, 171, 114, 176, 241, 181, 6, + 71, 112, 146, 111, 100, 27, 6, 172, 103, 31, 246, 100, 47, 182, 101, 62, 201, 102, 10, 57, 216, 18, 207, + 93, 147, 87, 206, 200, 65, 26, 20, 178, 92, 141, 246, 92, 76, 155, 102, 250, 91, 120, 105, 237, 108, 207, + 163, 163, 19, 253, 131, 84, 115, 31, 49, 246, 72, 9, 251, 81, 137, 108, 196, 72, 31, 130, 216, 167, 69, + 135, 209, 208, 255, 116, 31, 236, 246, 171, 14, 227, 144, 40, 83, 137, 65, 90, 240, 5, 167, 166, 95, 89, + 32, 237, 4, 88, 0, 0, 3, 76, 109, 107, 66, 84, 250, 206, 202, 254, 0, 126, 185, 188, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 217, 91, 113, + 227, 48, 20, 6, 224, 133, 16, 8, 129, 16, 8, 129, 80, 8, 129, 80, 8, 129, 80, 8, 133, 80, 8, 5, 144, 135, + 66, 8, 132, 48, 200, 70, 51, 241, 140, 86, 115, 228, 88, 190, 37, 221, 249, 254, 153, 239, 165, 145, 101, + 75, 199, 150, 47, 253, 243, 71, 68, 68, 68, 68, 68, 68, 68, 100, 189, 236, 78, 167, 211, 119, 131, 227, + 205, 219, 205, 163, 126, 55, 183, 54, 239, 55, 95, 3, 250, 44, 183, 221, 223, 254, 246, 209, 120, 92, 187, + 123, 63, 45, 219, 68, 125, 12, 157, 143, 175, 134, 185, 232, 178, 173, 140, 247, 153, 73, 115, 125, 29, + 225, 231, 102, 83, 25, 75, 154, 147, 75, 67, 95, 249, 182, 159, 35, 143, 103, 127, 239, 103, 204, 182, 121, + 31, 99, 230, 227, 156, 237, 191, 47, 199, 96, 188, 207, 206, 216, 250, 119, 231, 64, 217, 223, 219, 136, + 126, 166, 108, 251, 10, 245, 47, 143, 161, 150, 238, 154, 152, 191, 138, 227, 19, 141, 55, 90, 239, 206, + 149, 49, 231, 235, 95, 90, 15, 106, 215, 253, 79, 165, 223, 124, 61, 252, 170, 108, 59, 117, 253, 47, 143, + 253, 210, 211, 199, 144, 249, 168, 141, 241, 220, 83, 219, 67, 214, 110, 217, 138, 182, 37, 26, 111, 173, + 109, 84, 159, 99, 214, 254, 24, 252, 158, 234, 190, 29, 56, 230, 114, 219, 52, 207, 181, 123, 76, 75, 202, + 227, 234, 187, 7, 15, 157, 143, 247, 202, 57, 112, 168, 180, 255, 254, 15, 234, 31, 181, 205, 235, 31, 173, + 17, 45, 245, 139, 174, 187, 169, 227, 75, 89, 162, 254, 81, 191, 201, 103, 208, 126, 59, 176, 191, 103, + 164, 101, 188, 135, 160, 109, 87, 255, 77, 101, 221, 108, 57, 150, 232, 122, 122, 127, 209, 235, 63, 165, + 172, 107, 183, 222, 149, 237, 202, 103, 218, 169, 227, 153, 51, 209, 120, 247, 129, 195, 41, 190, 239, 117, + 247, 221, 168, 159, 218, 125, 182, 245, 254, 95, 147, 230, 250, 99, 192, 26, 179, 84, 253, 83, 162, 53, 47, + 255, 61, 122, 38, 26, 86, 153, 117, 50, 229, 121, 55, 159, 199, 41, 253, 76, 237, 227, 146, 157, 135, 81, + 150, 172, 255, 247, 131, 246, 209, 154, 57, 172, 50, 235, 100, 174, 247, 255, 57, 234, 159, 82, 91, 103, + 90, 206, 197, 50, 207, 172, 255, 79, 241, 91, 223, 59, 194, 51, 50, 182, 110, 31, 197, 56, 230, 88, 255, + 187, 164, 243, 42, 245, 119, 172, 168, 189, 139, 214, 238, 3, 75, 214, 63, 58, 87, 31, 205, 201, 227, 170, + 172, 151, 71, 247, 255, 183, 123, 173, 163, 249, 62, 22, 99, 41, 127, 95, 242, 92, 143, 174, 187, 253, 202, + 245, 223, 5, 109, 243, 190, 203, 231, 190, 223, 178, 254, 71, 237, 162, 177, 150, 231, 114, 185, 214, 245, + 213, 100, 106, 162, 115, 114, 237, 250, 71, 207, 171, 221, 251, 95, 244, 62, 244, 155, 235, 159, 18, 141, + 55, 159, 243, 232, 155, 200, 229, 190, 78, 244, 61, 159, 181, 166, 246, 255, 133, 218, 62, 230, 174, 127, + 218, 79, 237, 93, 165, 251, 30, 26, 205, 197, 249, 193, 190, 159, 145, 169, 223, 59, 242, 250, 111, 78, + 245, 123, 115, 159, 190, 99, 25, 170, 239, 190, 58, 181, 254, 67, 229, 247, 187, 104, 30, 90, 254, 87, 184, + 86, 90, 234, 31, 253, 127, 166, 252, 62, 179, 171, 92, 155, 75, 215, 191, 239, 59, 209, 90, 245, 239, 174, + 133, 104, 158, 94, 237, 185, 191, 203, 212, 239, 191, 229, 123, 64, 202, 246, 62, 199, 107, 213, 63, 58, + 134, 60, 75, 215, 255, 124, 250, 119, 29, 140, 238, 13, 115, 124, 199, 92, 34, 169, 86, 229, 251, 85, 95, + 251, 178, 237, 161, 167, 253, 246, 212, 255, 30, 87, 238, 47, 58, 150, 62, 105, 223, 219, 1, 243, 90, 30, + 195, 163, 99, 110, 217, 127, 244, 204, 113, 8, 218, 206, 241, 127, 44, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 249, 5, 185, 94, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 106, 254, 2, 20, 95, 99, 212, 250, 74, 192, 87, 0, + 0, 18, 191, 109, 107, 66, 84, 250, 206, 202, 254, 0, 126, 224, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 156, 121, 116, 85, 213, 21, 198, + 223, 37, 145, 96, 38, 136, 6, 2, 212, 60, 64, 104, 155, 64, 7, 104, 68, 16, 69, 140, 72, 81, 132, 138, 8, + 34, 20, 173, 34, 136, 150, 86, 50, 129, 56, 16, 169, 45, 83, 177, 88, 4, 113, 117, 0, 169, 40, 180, 82, 9, + 129, 36, 76, 137, 144, 16, 166, 0, 73, 152, 18, 32, 144, 129, 82, 170, 252, 211, 65, 75, 181, 74, 79, 247, + 119, 223, 217, 201, 201, 229, 190, 23, 134, 228, 221, 151, 112, 238, 90, 191, 181, 178, 48, 226, 59, 247, + 219, 103, 239, 111, 239, 115, 158, 98, 91, 43, 151, 208, 52, 13, 91, 45, 108, 38, 178, 93, 46, 177, 129, + 200, 127, 108, 172, 56, 90, 92, 44, 202, 171, 170, 196, 177, 163, 71, 253, 74, 117, 85, 213, 103, 69, 69, + 69, 43, 19, 19, 19, 205, 207, 229, 244, 123, 106, 137, 168, 186, 111, 33, 54, 25, 46, 177, 145, 116, 207, + 233, 16, 45, 138, 22, 47, 54, 117, 47, 59, 113, 194, 175, 186, 151, 29, 59, 38, 254, 114, 230, 204, 185, + 13, 153, 153, 191, 234, 209, 163, 199, 243, 46, 87, 253, 207, 233, 244, 59, 107, 9, 216, 237, 249, 28, 185, + 231, 243, 6, 39, 138, 195, 59, 118, 136, 242, 154, 26, 113, 140, 180, 240, 167, 246, 199, 203, 203, 197, + 153, 154, 154, 210, 55, 22, 45, 74, 143, 140, 140, 132, 246, 63, 53, 12, 195, 140, 77, 29, 3, 141, 175, 61, + 222, 235, 102, 218, 243, 89, 164, 123, 118, 120, 152, 216, 61, 235, 21, 81, 86, 81, 97, 226, 239, 124, 127, + 170, 162, 226, 226, 201, 19, 39, 54, 79, 121, 230, 153, 52, 210, 61, 137, 152, 74, 218, 79, 132, 254, 136, + 77, 107, 12, 232, 56, 184, 122, 221, 173, 123, 126, 91, 223, 4, 81, 154, 157, 37, 202, 207, 156, 17, 199, + 202, 202, 252, 174, 125, 77, 117, 245, 191, 246, 236, 222, 189, 98, 224, 192, 129, 73, 82, 251, 231, 72, + 247, 31, 17, 143, 66, 255, 236, 200, 8, 51, 70, 17, 171, 58, 23, 92, 155, 246, 91, 164, 246, 120, 159, 89, + 55, 182, 17, 187, 82, 83, 68, 25, 229, 221, 242, 211, 167, 253, 174, 123, 57, 197, 26, 213, 250, 170, 53, + 171, 87, 47, 112, 187, 221, 200, 247, 207, 147, 222, 83, 136, 199, 137, 71, 136, 7, 160, 127, 233, 150, + 205, 34, 247, 174, 59, 61, 222, 196, 229, 249, 252, 58, 23, 92, 153, 238, 172, 61, 222, 31, 222, 227, 214, + 222, 223, 17, 197, 31, 126, 40, 142, 211, 158, 135, 254, 254, 214, 158, 114, 189, 168, 170, 172, 164, 146, + 243, 202, 75, 33, 33, 33, 211, 100, 173, 159, 68, 252, 144, 120, 152, 24, 74, 220, 5, 253, 203, 79, 157, + 18, 101, 39, 79, 138, 61, 233, 179, 124, 230, 2, 29, 7, 222, 181, 175, 221, 243, 109, 66, 68, 225, 180, + 231, 77, 111, 87, 94, 89, 233, 119, 221, 1, 233, 254, 159, 210, 146, 146, 15, 30, 30, 57, 50, 197, 82, 235, + 31, 35, 126, 64, 220, 71, 12, 32, 122, 67, 127, 243, 223, 163, 92, 129, 250, 116, 104, 235, 86, 145, 151, + 56, 168, 54, 23, 232, 24, 240, 173, 187, 186, 231, 183, 245, 249, 46, 237, 249, 63, 59, 182, 231, 101, 111, + 247, 215, 204, 204, 204, 95, 199, 197, 197, 97, 207, 131, 103, 149, 90, 63, 156, 72, 36, 250, 17, 223, 33, + 190, 94, 171, 63, 255, 29, 200, 5, 228, 79, 247, 206, 157, 35, 114, 162, 111, 54, 215, 181, 73, 231, 2, 91, + 221, 217, 219, 103, 133, 222, 104, 214, 121, 115, 15, 57, 80, 231, 57, 223, 87, 87, 85, 29, 152, 59, 103, + 78, 122, 120, 120, 120, 146, 172, 245, 207, 16, 19, 148, 90, 63, 136, 232, 75, 124, 139, 232, 78, 124, 205, + 170, 191, 154, 11, 14, 231, 231, 139, 237, 35, 30, 52, 99, 32, 251, 58, 246, 5, 190, 246, 124, 238, 128, + 59, 68, 233, 198, 141, 30, 111, 239, 192, 158, 151, 249, 254, 243, 67, 165, 165, 31, 142, 25, 51, 38, 149, + 116, 79, 38, 126, 66, 186, 62, 77, 140, 39, 70, 18, 223, 151, 181, 62, 129, 136, 39, 186, 17, 157, 136, + 155, 109, 245, 231, 92, 64, 158, 0, 51, 170, 253, 111, 45, 21, 155, 187, 186, 175, 187, 92, 96, 167, 123, + 237, 12, 239, 166, 40, 177, 231, 103, 179, 205, 119, 84, 118, 202, 153, 61, 47, 243, 253, 217, 245, 25, 25, + 111, 198, 199, 199, 171, 189, 221, 147, 196, 88, 98, 4, 49, 88, 169, 245, 223, 36, 186, 16, 29, 137, 155, + 136, 8, 95, 250, 155, 192, 199, 84, 87, 139, 163, 7, 15, 136, 157, 79, 79, 20, 89, 173, 111, 184, 46, 114, + 129, 183, 126, 30, 218, 111, 127, 240, 1, 113, 104, 251, 118, 81, 94, 227, 76, 63, 15, 42, 40, 238, 42, 79, + 159, 222, 251, 106, 122, 250, 172, 176, 208, 80, 232, 62, 77, 230, 123, 244, 118, 163, 137, 97, 196, 61, + 196, 237, 196, 183, 101, 173, 143, 37, 58, 16, 237, 136, 112, 162, 77, 131, 250, 115, 172, 29, 63, 110, + 206, 44, 139, 63, 248, 64, 108, 187, 237, 123, 45, 214, 31, 250, 218, 243, 200, 129, 69, 75, 151, 152, 190, + 222, 137, 25, 30, 83, 83, 93, 253, 89, 209, 190, 125, 107, 134, 13, 27, 102, 205, 247, 106, 111, 55, 144, + 184, 141, 232, 69, 220, 42, 107, 125, 52, 209, 150, 8, 35, 66, 136, 27, 46, 87, 127, 198, 92, 59, 197, 2, + 114, 95, 78, 244, 77, 166, 255, 177, 171, 9, 78, 235, 216, 40, 123, 222, 240, 248, 158, 236, 144, 16, 177, + 115, 242, 36, 202, 129, 7, 205, 92, 232, 239, 185, 61, 131, 249, 61, 229, 251, 83, 43, 223, 121, 103, 161, + 219, 237, 78, 146, 218, 35, 223, 63, 101, 211, 219, 245, 33, 226, 136, 174, 74, 173, 71, 190, 15, 37, 90, + 19, 193, 68, 208, 149, 234, 111, 194, 254, 176, 160, 64, 228, 143, 126, 68, 100, 5, 181, 242, 212, 132, + 102, 26, 7, 190, 114, 125, 110, 255, 126, 162, 100, 221, 58, 51, 247, 149, 29, 247, 239, 89, 157, 10, 229, + 250, 175, 202, 203, 202, 114, 167, 78, 157, 250, 98, 112, 112, 112, 178, 226, 239, 159, 144, 249, 254, 65, + 155, 222, 14, 249, 62, 134, 136, 146, 218, 223, 40, 181, 135, 238, 173, 12, 207, 115, 213, 159, 201, 244, + 135, 180, 31, 14, 174, 90, 69, 189, 111, 239, 102, 87, 19, 188, 229, 122, 51, 167, 117, 234, 40, 246, 205, + 159, 231, 241, 119, 14, 245, 116, 230, 59, 246, 120, 188, 243, 155, 55, 109, 250, 77, 66, 66, 66, 178, 141, + 191, 231, 124, 127, 183, 146, 239, 185, 183, 107, 47, 107, 125, 152, 172, 245, 55, 88, 180, 191, 38, 253, + 25, 243, 254, 2, 229, 166, 189, 84, 19, 54, 197, 180, 247, 90, 19, 2, 41, 14, 236, 122, 121, 79, 174, 111, + 45, 10, 126, 244, 132, 56, 178, 119, 175, 231, 140, 214, 33, 127, 7, 78, 145, 199, 160, 125, 95, 244, 243, + 215, 94, 155, 29, 25, 25, 9, 221, 147, 72, 175, 103, 45, 254, 222, 87, 190, 143, 148, 249, 62, 68, 201, + 247, 234, 227, 194, 249, 127, 163, 124, 94, 156, 113, 80, 77, 56, 178, 123, 55, 189, 191, 199, 69, 22, 189, + 199, 64, 60, 83, 242, 213, 203, 231, 221, 53, 160, 46, 215, 251, 249, 94, 134, 117, 207, 159, 169, 169, + 249, 215, 174, 194, 194, 213, 67, 135, 14, 77, 147, 123, 30, 243, 251, 201, 70, 221, 217, 205, 48, 155, + 124, 239, 150, 249, 158, 123, 59, 206, 247, 193, 150, 61, 239, 82, 158, 198, 253, 236, 244, 222, 240, 254, + 74, 214, 103, 136, 188, 196, 123, 60, 103, 223, 50, 14, 156, 204, 5, 182, 185, 94, 234, 190, 165, 91, 23, + 81, 244, 198, 34, 211, 211, 59, 53, 191, 99, 228, 28, 239, 232, 146, 55, 223, 156, 23, 19, 19, 99, 230, + 123, 210, 235, 199, 134, 103, 126, 63, 206, 168, 155, 231, 192, 223, 39, 40, 249, 254, 150, 203, 204, 247, + 46, 203, 211, 36, 235, 192, 123, 196, 44, 121, 255, 219, 203, 196, 214, 248, 56, 51, 14, 156, 242, 6, 222, + 230, 182, 57, 109, 35, 197, 174, 164, 105, 158, 59, 120, 14, 250, 122, 222, 243, 212, 215, 93, 56, 176, + 127, 255, 186, 49, 99, 198, 204, 32, 93, 82, 100, 79, 63, 69, 122, 188, 49, 134, 103, 126, 127, 47, 113, + 135, 225, 153, 231, 52, 148, 239, 85, 221, 237, 180, 111, 50, 253, 77, 228, 236, 8, 63, 239, 121, 53, 157, + 60, 85, 140, 199, 27, 248, 41, 14, 188, 213, 248, 172, 224, 96, 177, 131, 250, 150, 67, 121, 121, 102, 205, + 66, 63, 235, 244, 158, 167, 124, 127, 252, 119, 191, 253, 237, 235, 212, 215, 177, 199, 195, 153, 157, 218, + 211, 223, 111, 120, 230, 247, 118, 243, 28, 171, 191, 175, 213, 158, 254, 30, 198, 219, 211, 244, 177, 13, + 111, 80, 67, 222, 96, 223, 62, 81, 248, 220, 179, 34, 39, 50, 188, 73, 231, 6, 118, 253, 156, 169, 187, 89, + 227, 239, 52, 103, 88, 136, 75, 120, 123, 39, 117, 7, 180, 231, 255, 83, 124, 240, 224, 134, 199, 39, 76, + 152, 217, 170, 85, 171, 20, 27, 143, 135, 158, 126, 8, 113, 39, 241, 61, 162, 167, 81, 55, 207, 65, 190, + 231, 121, 206, 37, 249, 30, 186, 135, 132, 132, 184, 34, 34, 34, 92, 97, 97, 97, 222, 240, 219, 90, 77, + 111, 128, 51, 230, 188, 92, 243, 238, 51, 230, 42, 222, 188, 193, 213, 196, 130, 55, 111, 7, 221, 183, 245, + 234, 105, 214, 162, 64, 168, 241, 181, 123, 190, 186, 186, 98, 197, 242, 229, 139, 110, 189, 245, 214, 100, + 153, 239, 249, 142, 134, 122, 102, 135, 25, 110, 127, 233, 241, 190, 97, 212, 205, 239, 57, 223, 223, 104, + 212, 247, 247, 181, 218, 15, 28, 56, 208, 117, 228, 200, 17, 215, 249, 243, 231, 93, 231, 206, 157, 243, + 134, 223, 215, 110, 106, 64, 251, 175, 36, 51, 83, 108, 127, 224, 126, 145, 173, 204, 143, 174, 38, 6, 188, + 121, 59, 232, 190, 197, 29, 43, 246, 206, 249, 69, 93, 45, 114, 176, 198, 155, 107, 135, 183, 175, 174, + 254, 247, 254, 162, 162, 204, 199, 198, 142, 157, 73, 82, 169, 123, 254, 41, 195, 51, 199, 123, 72, 241, + 120, 106, 79, 127, 139, 146, 239, 121, 126, 127, 201, 158, 71, 82, 79, 77, 77, 117, 125, 241, 197, 23, 46, + 33, 68, 67, 56, 247, 46, 200, 31, 98, 158, 92, 188, 102, 141, 248, 104, 208, 221, 34, 11, 119, 17, 175, 32, + 14, 124, 233, 190, 169, 67, 180, 216, 157, 150, 38, 142, 30, 44, 118, 188, 143, 103, 112, 102, 67, 222, + 190, 108, 217, 91, 111, 189, 238, 142, 141, 77, 81, 246, 60, 247, 117, 124, 110, 147, 40, 247, 60, 159, + 217, 169, 30, 175, 173, 226, 241, 46, 209, 190, 75, 151, 46, 174, 236, 236, 236, 203, 209, 221, 113, 253, + 77, 228, 61, 41, 204, 216, 14, 172, 88, 33, 242, 238, 232, 79, 113, 224, 189, 103, 180, 67, 213, 61, 167, + 93, 91, 81, 56, 245, 57, 115, 14, 1, 207, 225, 180, 183, 3, 184, 135, 137, 126, 190, 112, 231, 206, 181, + 35, 31, 122, 232, 5, 169, 59, 246, 188, 58, 187, 183, 238, 121, 220, 209, 232, 161, 120, 60, 175, 61, 61, + 123, 188, 225, 195, 135, 187, 206, 158, 61, 123, 37, 218, 59, 175, 191, 26, 7, 248, 62, 12, 213, 134, 3, + 203, 151, 83, 28, 244, 19, 217, 13, 196, 129, 233, 233, 89, 119, 242, 148, 59, 39, 61, 237, 249, 110, 5, + 60, 189, 131, 243, 27, 149, 211, 148, 227, 136, 226, 249, 243, 231, 207, 235, 208, 161, 131, 185, 231, 73, + 50, 235, 158, 199, 236, 222, 218, 215, 117, 35, 58, 27, 245, 207, 236, 108, 243, 125, 104, 104, 168, 139, + 254, 126, 215, 151, 95, 126, 121, 165, 218, 155, 250, 215, 80, 126, 60, 25, 32, 239, 171, 46, 14, 78, 82, + 28, 252, 222, 140, 3, 206, 7, 232, 23, 54, 75, 63, 95, 187, 223, 195, 67, 69, 193, 132, 31, 138, 67, 185, + 219, 60, 186, 7, 128, 167, 7, 242, 172, 238, 252, 166, 156, 156, 119, 7, 13, 26, 52, 29, 37, 217, 102, 207, + 99, 150, 195, 103, 181, 184, 151, 197, 125, 157, 175, 57, 158, 169, 61, 239, 249, 184, 184, 56, 215, 254, + 253, 251, 175, 70, 119, 102, 195, 248, 241, 227, 63, 219, 187, 103, 15, 114, 148, 153, 171, 156, 126, 119, + 245, 227, 192, 147, 15, 114, 7, 244, 23, 27, 91, 25, 230, 247, 41, 54, 152, 223, 167, 9, 21, 249, 208, 125, + 235, 86, 207, 188, 214, 193, 243, 120, 43, 84, 227, 191, 60, 122, 228, 200, 142, 148, 228, 228, 217, 225, + 225, 225, 92, 231, 127, 34, 247, 252, 4, 155, 61, 143, 217, 61, 223, 203, 226, 61, 175, 206, 241, 46, 201, + 247, 212, 43, 26, 201, 201, 201, 174, 79, 63, 253, 244, 90, 180, 7, 248, 108, 191, 236, 216, 177, 99, 201, + 130, 5, 11, 248, 204, 193, 241, 119, 88, 47, 14, 42, 101, 28, 188, 251, 7, 177, 109, 240, 189, 98, 199, 19, + 143, 139, 67, 219, 2, 79, 119, 248, 59, 234, 231, 79, 175, 92, 185, 114, 105, 124, 124, 124, 170, 220, 243, + 211, 140, 186, 126, 222, 90, 231, 125, 237, 121, 235, 185, 77, 173, 246, 157, 58, 117, 114, 101, 101, 101, + 93, 171, 238, 12, 230, 203, 248, 156, 200, 81, 239, 12, 24, 48, 224, 175, 25, 25, 25, 102, 46, 56, 25, 0, + 222, 169, 126, 28, 84, 154, 189, 187, 211, 247, 111, 172, 72, 127, 247, 207, 157, 5, 5, 235, 70, 141, 26, + 245, 162, 156, 227, 160, 206, 99, 134, 167, 246, 243, 236, 237, 121, 207, 171, 117, 158, 103, 247, 220, + 215, 217, 122, 60, 202, 213, 174, 143, 63, 254, 184, 177, 180, 7, 147, 165, 31, 73, 53, 60, 189, 232, 172, + 144, 144, 144, 77, 19, 159, 122, 234, 2, 245, 168, 129, 85, 19, 100, 28, 56, 254, 25, 20, 170, 42, 43, 47, + 82, 173, 223, 55, 123, 246, 236, 121, 209, 209, 209, 41, 114, 207, 243, 247, 172, 112, 239, 158, 103, 120, + 118, 222, 30, 123, 94, 189, 139, 233, 181, 175, 235, 220, 185, 179, 107, 237, 218, 181, 141, 169, 59, 51, + 78, 250, 17, 228, 40, 228, 170, 52, 185, 134, 133, 244, 223, 44, 158, 63, 111, 222, 255, 228, 119, 137, 28, + 127, 215, 129, 132, 204, 245, 213, 171, 223, 127, 255, 55, 125, 250, 244, 225, 119, 166, 158, 213, 225, + 110, 198, 40, 163, 254, 12, 79, 61, 179, 81, 189, 189, 207, 61, 63, 110, 220, 56, 215, 39, 159, 124, 210, + 20, 218, 131, 225, 210, 143, 76, 144, 185, 10, 57, 43, 69, 214, 4, 156, 67, 253, 254, 246, 190, 125, 107, + 254, 184, 102, 13, 214, 107, 250, 3, 167, 223, 189, 147, 72, 95, 255, 143, 252, 29, 59, 50, 70, 143, 30, + 253, 82, 80, 80, 144, 89, 231, 233, 125, 177, 191, 67, 79, 135, 179, 58, 190, 155, 193, 247, 238, 121, 134, + 199, 119, 178, 26, 172, 243, 109, 219, 182, 117, 45, 93, 186, 180, 169, 116, 103, 238, 150, 185, 233, 33, + 153, 171, 144, 179, 158, 225, 154, 32, 227, 250, 229, 224, 160, 160, 117, 143, 140, 26, 245, 143, 237, 31, + 125, 132, 245, 139, 19, 14, 125, 215, 193, 41, 228, 249, 236, 127, 143, 30, 62, 92, 56, 243, 133, 23, 230, + 68, 181, 107, 135, 92, 159, 102, 227, 239, 208, 211, 241, 89, 29, 223, 205, 224, 25, 158, 93, 63, 111, 187, + 231, 239, 187, 239, 62, 87, 69, 69, 69, 83, 107, 15, 122, 203, 220, 148, 40, 115, 21, 114, 150, 183, 154, + 240, 11, 138, 201, 29, 201, 73, 73, 95, 148, 150, 148, 4, 158, 55, 104, 34, 208, 15, 157, 62, 117, 170, + 252, 237, 101, 203, 150, 80, 191, 157, 38, 117, 231, 92, 207, 103, 180, 240, 119, 220, 211, 225, 62, 22, + 159, 213, 89, 231, 246, 118, 119, 112, 107, 181, 111, 223, 190, 189, 107, 245, 234, 213, 174, 175, 190, + 250, 202, 31, 218, 131, 30, 210, 143, 32, 71, 225, 140, 17, 223, 23, 81, 107, 194, 211, 114, 157, 201, 50, + 14, 192, 27, 93, 187, 118, 45, 125, 125, 225, 194, 139, 236, 13, 202, 2, 204, 151, 53, 6, 168, 241, 20, + 227, 231, 214, 103, 100, 172, 74, 76, 76, 156, 41, 247, 128, 154, 235, 113, 47, 3, 223, 171, 228, 51, 90, + 181, 167, 227, 179, 186, 78, 54, 123, 222, 238, 94, 142, 121, 110, 147, 146, 146, 226, 47, 221, 153, 206, + 50, 55, 125, 83, 230, 42, 220, 47, 224, 154, 240, 3, 185, 190, 39, 228, 122, 177, 238, 84, 25, 7, 240, 6, + 191, 187, 45, 33, 1, 253, 174, 25, 3, 1, 53, 55, 184, 6, 78, 80, 223, 75, 53, 238, 159, 249, 249, 249, 27, + 169, 223, 74, 167, 126, 40, 85, 198, 61, 251, 122, 107, 174, 191, 71, 230, 122, 117, 118, 203, 231, 243, + 124, 86, 119, 201, 12, 207, 34, 189, 249, 76, 159, 62, 221, 223, 250, 71, 201, 220, 132, 28, 133, 123, 5, + 152, 67, 245, 145, 53, 225, 30, 185, 190, 135, 101, 77, 120, 82, 174, 31, 239, 33, 205, 240, 248, 131, 151, + 168, 223, 93, 61, 100, 200, 144, 191, 101, 174, 95, 223, 172, 61, 162, 236, 227, 63, 47, 41, 46, 206, 79, + 77, 73, 153, 27, 21, 21, 197, 186, 243, 220, 118, 162, 143, 92, 15, 127, 199, 231, 53, 236, 239, 212, 251, + 88, 182, 123, 222, 176, 220, 201, 114, 64, 255, 48, 153, 155, 112, 182, 136, 94, 212, 45, 215, 129, 245, + 36, 200, 245, 221, 43, 215, 251, 136, 92, 255, 68, 249, 62, 84, 111, 144, 222, 186, 117, 235, 204, 177, + 143, 62, 250, 247, 188, 220, 92, 207, 252, 40, 80, 206, 20, 46, 67, 119, 138, 91, 124, 191, 2, 253, 238, + 34, 183, 219, 205, 117, 78, 157, 225, 168, 190, 254, 74, 114, 189, 234, 239, 124, 221, 195, 116, 74, 255, + 214, 50, 55, 33, 71, 181, 147, 57, 11, 235, 232, 42, 215, 245, 109, 185, 206, 129, 114, 221, 35, 228, 123, + 176, 122, 131, 233, 242, 157, 253, 60, 34, 60, 124, 203, 228, 73, 147, 62, 221, 85, 88, 232, 233, 21, 2, + 105, 142, 168, 0, 207, 66, 117, 235, 127, 84, 231, 143, 191, 77, 207, 183, 122, 245, 154, 33, 215, 128, 26, + 135, 254, 7, 125, 16, 207, 112, 208, 31, 225, 172, 134, 125, 253, 119, 141, 250, 185, 222, 234, 239, 46, + 233, 233, 88, 119, 111, 218, 59, 164, 127, 144, 204, 77, 33, 242, 115, 71, 200, 117, 168, 53, 33, 78, 174, + 183, 159, 92, 63, 222, 131, 213, 27, 76, 181, 196, 1, 230, 97, 219, 147, 166, 77, 51, 231, 136, 129, 22, 7, + 240, 42, 149, 149, 149, 85, 239, 173, 90, 245, 206, 29, 253, 251, 207, 148, 159, 25, 53, 13, 181, 141, 239, + 226, 160, 230, 161, 246, 161, 47, 74, 52, 60, 115, 91, 213, 215, 115, 174, 231, 187, 88, 234, 158, 111, 48, + 215, 7, 136, 254, 134, 252, 156, 193, 50, 14, 218, 200, 56, 136, 148, 235, 138, 145, 235, 236, 46, 215, + 221, 71, 190, 7, 188, 15, 120, 3, 120, 32, 120, 161, 39, 13, 101, 110, 32, 227, 0, 44, 236, 216, 177, 99, + 225, 11, 51, 102, 160, 174, 154, 117, 193, 201, 56, 192, 121, 124, 117, 85, 213, 217, 63, 175, 93, 251, 62, + 245, 216, 47, 147, 119, 73, 147, 159, 211, 91, 141, 71, 63, 132, 25, 14, 207, 109, 113, 86, 163, 230, 122, + 158, 217, 91, 253, 221, 21, 233, 238, 176, 254, 28, 3, 65, 242, 243, 91, 107, 66, 180, 92, 111, 23, 185, + 126, 171, 55, 192, 185, 134, 58, 55, 152, 98, 19, 7, 139, 220, 177, 177, 123, 102, 189, 242, 202, 231, 197, + 7, 15, 250, 61, 14, 160, 59, 213, 248, 143, 55, 110, 216, 176, 118, 196, 136, 17, 179, 130, 131, 131, 185, + 198, 67, 119, 212, 48, 62, 167, 177, 214, 120, 244, 67, 60, 195, 233, 102, 212, 247, 245, 94, 103, 246, 87, + 163, 189, 67, 250, 243, 127, 218, 46, 14, 66, 148, 56, 136, 146, 235, 230, 126, 81, 245, 6, 119, 201, 125, + 194, 30, 113, 188, 81, 55, 63, 122, 222, 26, 7, 177, 136, 131, 89, 179, 204, 124, 208, 212, 117, 161, 86, + 247, 204, 204, 15, 31, 30, 57, 242, 85, 242, 168, 188, 223, 81, 171, 84, 111, 135, 90, 102, 173, 241, 220, + 207, 161, 6, 162, 22, 170, 190, 94, 253, 14, 253, 229, 126, 215, 162, 193, 7, 179, 254, 146, 146, 18, 87, + 65, 65, 129, 223, 80, 30, 245, 243, 123, 171, 9, 236, 13, 190, 38, 247, 3, 207, 13, 84, 143, 200, 243, 35, + 238, 21, 56, 14, 210, 100, 28, 204, 48, 243, 129, 219, 189, 251, 165, 23, 95, 188, 80, 180, 111, 159, 25, + 7, 141, 217, 47, 200, 60, 111, 234, 62, 146, 116, 167, 30, 222, 170, 59, 60, 11, 123, 59, 181, 143, 231, + 179, 89, 181, 198, 243, 125, 107, 111, 103, 53, 151, 248, 187, 107, 33, 0, 30, 95, 113, 160, 246, 139, 49, + 70, 125, 143, 216, 91, 238, 27, 158, 31, 169, 189, 66, 189, 158, 209, 168, 203, 7, 175, 147, 63, 40, 72, + 77, 77, 253, 108, 247, 174, 93, 102, 28, 84, 92, 229, 29, 46, 248, 121, 248, 58, 232, 190, 193, 163, 251, + 108, 203, 126, 199, 252, 138, 61, 61, 60, 11, 123, 59, 238, 227, 81, 211, 184, 198, 163, 15, 110, 168, 198, + 55, 170, 238, 1, 164, 63, 30, 107, 12, 168, 222, 192, 26, 7, 216, 31, 170, 71, 228, 56, 24, 100, 212, 205, + 17, 213, 158, 81, 141, 3, 228, 2, 232, 179, 128, 250, 133, 220, 41, 83, 166, 152, 103, 76, 240, 7, 216, + 195, 151, 171, 187, 156, 63, 194, 215, 125, 48, 108, 216, 48, 117, 191, 167, 88, 116, 135, 71, 129, 87, + 129, 103, 65, 205, 194, 204, 27, 222, 142, 251, 120, 62, 167, 81, 107, 60, 127, 199, 194, 107, 141, 111, + 206, 92, 67, 28, 88, 61, 162, 58, 63, 226, 94, 161, 191, 81, 191, 103, 180, 198, 1, 215, 5, 142, 131, 57, + 17, 17, 17, 152, 187, 126, 66, 94, 77, 84, 147, 174, 222, 206, 23, 228, 220, 70, 84, 84, 84, 84, 174, 122, + 247, 221, 247, 7, 15, 30, 156, 78, 190, 142, 243, 138, 170, 251, 147, 138, 238, 236, 233, 89, 119, 245, + 124, 78, 237, 227, 47, 107, 118, 215, 18, 184, 134, 124, 96, 157, 27, 88, 123, 5, 158, 35, 170, 113, 96, + 205, 7, 170, 63, 72, 85, 226, 96, 54, 237, 225, 63, 61, 112, 255, 253, 85, 239, 189, 247, 30, 223, 183, 48, + 53, 151, 255, 31, 251, 139, 244, 115, 217, 210, 37, 75, 86, 244, 235, 215, 239, 101, 163, 174, 158, 120, + 211, 157, 247, 59, 188, 106, 95, 163, 190, 167, 183, 243, 118, 106, 141, 191, 164, 159, 107, 73, 52, 66, + 93, 176, 155, 31, 241, 28, 81, 237, 25, 173, 113, 0, 127, 96, 245, 137, 232, 27, 83, 148, 56, 128, 182, + 203, 111, 239, 219, 247, 200, 155, 139, 23, 95, 164, 60, 240, 223, 195, 165, 165, 7, 230, 205, 157, 187, + 172, 87, 175, 94, 51, 229, 239, 224, 119, 173, 245, 221, 186, 223, 85, 221, 237, 60, 189, 221, 204, 182, + 201, 106, 124, 11, 128, 31, 142, 1, 95, 113, 128, 122, 122, 57, 113, 192, 125, 227, 20, 169, 37, 159, 57, + 243, 93, 139, 197, 61, 123, 246, 252, 85, 247, 238, 221, 249, 94, 10, 247, 239, 240, 243, 170, 175, 179, + 211, 157, 231, 181, 170, 238, 170, 167, 247, 229, 237, 140, 0, 120, 223, 129, 10, 63, 220, 7, 169, 30, 241, + 74, 226, 128, 251, 70, 204, 15, 248, 172, 17, 61, 26, 102, 51, 200, 9, 240, 139, 63, 37, 189, 1, 126, 70, + 124, 192, 63, 160, 127, 199, 12, 154, 253, 188, 53, 207, 171, 186, 115, 47, 167, 222, 187, 99, 221, 91, + 116, 141, 111, 98, 212, 199, 174, 87, 80, 103, 7, 106, 28, 176, 79, 84, 251, 70, 220, 153, 195, 222, 133, + 150, 232, 205, 49, 155, 65, 44, 192, 47, 78, 150, 224, 103, 236, 117, 212, 13, 204, 109, 208, 191, 219, + 213, 119, 171, 238, 216, 239, 106, 47, 215, 226, 189, 157, 159, 81, 31, 111, 61, 163, 157, 63, 224, 56, + 192, 94, 197, 188, 21, 115, 36, 104, 137, 222, 28, 94, 17, 249, 28, 126, 113, 172, 4, 63, 35, 62, 80, 55, + 48, 183, 73, 52, 234, 251, 121, 187, 253, 174, 117, 15, 156, 56, 176, 243, 137, 232, 27, 49, 63, 192, 253, + 19, 196, 1, 246, 48, 102, 50, 168, 13, 152, 207, 192, 39, 12, 149, 12, 145, 127, 134, 124, 129, 121, 29, + 230, 54, 232, 223, 225, 231, 181, 238, 129, 131, 250, 248, 138, 3, 181, 111, 132, 118, 208, 16, 90, 98, 22, + 135, 218, 0, 125, 145, 23, 250, 73, 110, 151, 127, 134, 56, 129, 143, 192, 220, 166, 155, 225, 221, 215, + 105, 221, 3, 43, 14, 212, 153, 178, 221, 252, 0, 123, 23, 90, 162, 54, 32, 39, 64, 95, 228, 244, 120, 9, + 126, 254, 186, 252, 103, 248, 29, 204, 109, 180, 238, 129, 143, 250, 216, 197, 1, 207, 19, 121, 174, 140, + 218, 128, 88, 128, 95, 68, 60, 196, 74, 110, 145, 127, 22, 35, 127, 135, 231, 54, 218, 207, 55, 31, 212, + 199, 58, 71, 130, 134, 236, 21, 17, 11, 240, 9, 55, 91, 136, 146, 255, 44, 194, 168, 63, 183, 209, 186, 55, + 47, 212, 199, 234, 17, 56, 22, 80, 31, 194, 44, 224, 207, 218, 200, 223, 209, 115, 155, 230, 143, 250, 168, + 51, 69, 174, 15, 160, 181, 81, 183, 199, 249, 222, 5, 255, 158, 214, 189, 101, 96, 125, 90, 53, 128, 245, + 113, 250, 243, 55, 59, 154, 201, 99, 88, 208, 79, 35, 61, 177, 177, 177, 154, 235, 152, 11, 23, 46, 104, + 174, 99, 252, 125, 223, 88, 163, 209, 104, 52, 26, 141, 70, 163, 209, 104, 52, 26, 141, 70, 163, 209, 104, + 52, 26, 141, 70, 163, 209, 104, 52, 26, 141, 70, 163, 209, 104, 52, 26, 141, 70, 163, 209, 104, 52, 26, + 141, 70, 163, 209, 104, 52, 26, 141, 70, 163, 209, 104, 52, 26, 141, 70, 163, 209, 104, 52, 26, 141, 70, + 163, 209, 104, 52, 26, 141, 70, 163, 209, 104, 52, 26, 141, 70, 163, 209, 104, 52, 26, 141, 70, 163, 209, + 104, 52, 26, 141, 70, 163, 209, 104, 52, 26, 141, 70, 163, 209, 104, 52, 26, 141, 38, 192, 249, 63, 146, + 111, 102, 117, 190, 192, 186, 80, 0, 0, 2, 68, 109, 107, 66, 84, 250, 206, 202, 254, 0, 126, 230, 162, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, + 217, 97, 109, 234, 96, 24, 134, 225, 73, 64, 2, 18, 144, 80, 9, 72, 152, 132, 35, 1, 9, 71, 2, 18, 38, 161, + 2, 250, 99, 18, 144, 128, 131, 30, 190, 164, 203, 154, 47, 45, 148, 179, 210, 247, 205, 114, 61, 201, 149, + 45, 43, 176, 192, 13, 172, 219, 222, 222, 108, 118, 125, 223, 255, 122, 54, 191, 232, 54, 250, 199, 46, + 186, 141, 254, 177, 139, 110, 163, 127, 236, 162, 219, 232, 31, 187, 232, 54, 27, 104, 186, 174, 43, 118, + 55, 245, 221, 223, 15, 199, 138, 253, 112, 188, 25, 125, 109, 137, 185, 219, 91, 122, 157, 208, 37, 232, + 243, 106, 253, 237, 241, 46, 62, 38, 30, 247, 211, 112, 172, 56, 13, 199, 251, 209, 215, 150, 40, 215, 57, + 220, 62, 182, 79, 94, 39, 197, 18, 244, 217, 170, 127, 63, 241, 218, 91, 171, 255, 229, 63, 174, 147, 98, + 9, 250, 108, 217, 255, 178, 160, 255, 105, 248, 252, 203, 184, 109, 91, 29, 43, 142, 85, 219, 203, 196, + 101, 106, 49, 177, 39, 150, 160, 207, 150, 253, 139, 63, 163, 199, 127, 170, 127, 189, 246, 193, 101, 78, + 213, 237, 31, 51, 245, 125, 180, 4, 125, 182, 232, 63, 126, 13, 95, 187, 239, 115, 193, 87, 244, 63, 119, + 211, 231, 154, 41, 151, 160, 207, 22, 253, 143, 67, 247, 113, 163, 114, 247, 215, 232, 127, 88, 248, 51, + 255, 58, 124, 223, 125, 166, 231, 70, 130, 62, 91, 244, 111, 134, 247, 253, 113, 143, 195, 208, 243, 167, + 253, 203, 254, 62, 113, 238, 119, 205, 244, 28, 72, 208, 103, 171, 254, 229, 238, 126, 78, 156, 203, 173, + 209, 191, 172, 25, 94, 223, 237, 132, 250, 57, 144, 230, 28, 48, 65, 159, 45, 251, 55, 85, 135, 203, 138, + 253, 239, 173, 254, 190, 173, 254, 33, 253, 203, 206, 51, 239, 203, 175, 236, 191, 211, 63, 77, 255, 93, + 117, 46, 184, 70, 255, 247, 238, 254, 239, 251, 245, 223, 135, 206, 250, 135, 245, 47, 171, 207, 5, 127, + 218, 255, 153, 191, 253, 246, 206, 255, 194, 251, 151, 125, 6, 244, 47, 239, 59, 239, 89, 218, 151, 37, + 232, 243, 106, 165, 253, 163, 255, 253, 53, 119, 94, 147, 135, 39, 47, 51, 231, 144, 169, 251, 215, 18, + 244, 121, 57, 155, 95, 116, 27, 253, 99, 23, 221, 70, 255, 216, 69, 183, 209, 63, 118, 209, 109, 244, 143, + 93, 116, 27, 253, 99, 23, 221, 70, 255, 216, 69, 183, 209, 63, 118, 209, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 126, 177, 127, 239, 45, 215, 196, 249, 101, 129, 193, 0, 0, 25, 226, 109, 107, 66, 84, 250, 206, + 202, 254, 0, 127, 39, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 120, 156, 237, 93, 121, 112, 86, 85, 150, 207, 251, 72, 128, 160, 144, 12, 54, 48, 32, 40, + 202, 50, 42, 6, 197, 6, 23, 164, 93, 81, 195, 98, 139, 141, 210, 34, 136, 44, 66, 216, 9, 137, 16, 217, 81, + 64, 192, 8, 106, 92, 64, 17, 12, 40, 91, 86, 178, 144, 144, 176, 132, 64, 72, 2, 33, 193, 44, 100, 1, 2, 1, + 187, 166, 102, 166, 106, 170, 173, 234, 178, 102, 172, 233, 238, 51, 231, 220, 119, 239, 151, 155, 199, + 251, 146, 239, 35, 223, 125, 249, 22, 111, 213, 175, 248, 163, 187, 242, 204, 59, 191, 156, 229, 119, 206, + 185, 15, 46, 86, 85, 1, 161, 246, 250, 117, 56, 185, 98, 5, 236, 11, 8, 128, 84, 91, 0, 100, 32, 178, 16, + 71, 56, 114, 188, 28, 226, 247, 200, 70, 28, 70, 164, 35, 82, 16, 7, 16, 187, 17, 95, 35, 62, 69, 108, 212, + 2, 96, 21, 226, 93, 196, 59, 248, 46, 182, 79, 157, 10, 87, 26, 26, 224, 226, 197, 139, 32, 222, 149, 18, + 84, 87, 67, 77, 253, 85, 200, 125, 109, 60, 36, 6, 232, 239, 255, 48, 255, 239, 85, 105, 3, 241, 252, 234, + 154, 26, 252, 183, 18, 82, 7, 135, 193, 65, 124, 254, 33, 252, 223, 50, 45, 120, 126, 91, 112, 32, 139, + 255, 110, 244, 59, 38, 33, 246, 33, 190, 67, 108, 67, 108, 65, 172, 71, 219, 175, 64, 44, 198, 247, 48, 11, + 145, 246, 201, 39, 112, 5, 255, 62, 148, 218, 159, 108, 80, 87, 7, 23, 43, 43, 33, 243, 209, 97, 144, 100, + 17, 7, 228, 231, 215, 94, 187, 6, 197, 223, 237, 130, 253, 248, 236, 148, 128, 166, 62, 64, 252, 255, 115, + 189, 24, 50, 15, 100, 14, 36, 34, 246, 34, 118, 34, 190, 64, 196, 34, 222, 71, 251, 47, 67, 44, 192, 247, + 176, 176, 107, 87, 40, 204, 57, 2, 151, 234, 235, 149, 115, 160, 230, 202, 21, 40, 207, 207, 135, 180, 187, + 238, 98, 54, 200, 84, 108, 131, 38, 207, 71, 31, 71, 28, 56, 242, 234, 56, 230, 3, 210, 249, 179, 229, 103, + 30, 245, 114, 200, 92, 16, 177, 64, 112, 224, 7, 196, 183, 156, 3, 31, 161, 237, 215, 34, 98, 16, 115, 240, + 93, 172, 253, 253, 35, 80, 85, 81, 1, 53, 181, 181, 234, 57, 128, 54, 40, 77, 74, 132, 212, 206, 157, 33, + 45, 160, 209, 254, 178, 221, 220, 245, 62, 110, 242, 65, 151, 47, 195, 143, 121, 39, 32, 233, 142, 174, + 118, 254, 101, 251, 48, 7, 232, 221, 146, 159, 163, 156, 231, 32, 98, 15, 226, 27, 196, 103, 54, 61, 23, + 88, 141, 88, 130, 152, 137, 239, 226, 171, 201, 147, 225, 50, 230, 2, 213, 170, 115, 129, 42, 61, 31, 43, + 142, 139, 131, 100, 155, 6, 233, 10, 57, 96, 250, 236, 27, 55, 32, 127, 229, 10, 56, 64, 177, 143, 255, + 141, 168, 226, 95, 91, 218, 63, 215, 214, 24, 11, 136, 3, 201, 136, 253, 136, 120, 196, 118, 196, 86, 196, + 6, 180, 253, 74, 68, 20, 207, 5, 146, 55, 109, 130, 43, 248, 126, 84, 219, 95, 216, 225, 116, 76, 12, 36, + 83, 44, 214, 110, 254, 59, 116, 135, 29, 76, 243, 16, 202, 5, 49, 31, 77, 123, 228, 17, 123, 30, 226, 171, + 113, 128, 32, 226, 0, 113, 93, 228, 131, 187, 16, 95, 34, 62, 198, 247, 254, 1, 207, 5, 22, 226, 187, 152, + 127, 219, 109, 144, 159, 154, 2, 151, 174, 94, 85, 207, 1, 170, 9, 48, 22, 156, 152, 242, 22, 227, 64, 166, + 9, 7, 84, 216, 159, 197, 32, 252, 253, 206, 237, 219, 7, 7, 219, 181, 131, 84, 30, 7, 124, 201, 7, 200, 28, + 16, 185, 128, 200, 7, 19, 108, 141, 185, 192, 231, 136, 205, 134, 92, 96, 217, 192, 1, 240, 99, 73, 9, 212, + 94, 186, 164, 156, 3, 213, 152, 111, 16, 114, 95, 124, 129, 197, 99, 81, 15, 184, 139, 3, 205, 250, 31, + 140, 117, 71, 145, 123, 34, 23, 52, 198, 129, 182, 182, 159, 187, 57, 224, 108, 46, 64, 113, 32, 118, 84, + 56, 212, 97, 174, 84, 141, 127, 163, 202, 57, 128, 60, 171, 186, 112, 1, 178, 134, 12, 97, 127, 139, 194, + 14, 238, 224, 64, 179, 207, 197, 122, 180, 226, 236, 89, 72, 233, 211, 91, 143, 65, 110, 230, 158, 167, + 192, 152, 11, 16, 215, 141, 185, 192, 39, 182, 198, 92, 32, 58, 64, 215, 134, 190, 91, 180, 200, 18, 93, + 128, 249, 227, 43, 245, 80, 113, 250, 20, 100, 244, 189, 27, 14, 185, 49, 31, 108, 233, 185, 148, 135, 22, + 110, 221, 202, 124, 64, 154, 230, 123, 185, 160, 209, 7, 52, 155, 11, 32, 214, 225, 59, 88, 142, 136, 164, + 124, 16, 255, 205, 248, 226, 11, 203, 242, 65, 202, 5, 202, 50, 210, 33, 13, 107, 51, 119, 213, 133, 45, + 62, 23, 107, 29, 210, 36, 178, 94, 122, 9, 18, 124, 52, 23, 52, 227, 128, 89, 46, 32, 116, 1, 210, 134, + 222, 67, 204, 195, 247, 177, 32, 52, 20, 10, 50, 51, 173, 201, 7, 249, 223, 99, 201, 247, 123, 32, 181, 83, + 176, 91, 234, 66, 231, 124, 207, 21, 184, 144, 155, 11, 137, 161, 33, 246, 92, 208, 151, 227, 128, 156, 11, + 80, 143, 192, 152, 11, 108, 66, 219, 175, 65, 44, 69, 204, 198, 247, 177, 252, 254, 251, 45, 203, 7, 25, 7, + 208, 223, 20, 199, 125, 6, 41, 152, 155, 103, 180, 146, 3, 174, 60, 51, 127, 197, 114, 135, 113, 160, 173, + 109, 231, 78, 251, 27, 115, 1, 209, 39, 146, 115, 129, 15, 165, 62, 17, 105, 67, 155, 95, 124, 145, 217, + 95, 239, 163, 88, 16, 11, 208, 30, 103, 222, 95, 171, 107, 116, 1, 183, 174, 13, 56, 251, 60, 202, 115, + 233, 119, 203, 120, 236, 81, 159, 213, 4, 140, 28, 48, 203, 5, 68, 159, 136, 180, 33, 209, 39, 34, 109, + 104, 6, 98, 71, 196, 44, 61, 31, 180, 64, 31, 100, 113, 25, 159, 117, 42, 42, 74, 231, 192, 45, 234, 67, + 46, 113, 174, 254, 42, 148, 166, 166, 64, 66, 112, 71, 191, 137, 3, 114, 46, 32, 247, 137, 40, 31, 140, + 149, 180, 161, 72, 94, 19, 36, 109, 218, 104, 89, 62, 168, 235, 67, 13, 112, 242, 157, 25, 14, 57, 224, 78, + 251, 139, 56, 144, 135, 117, 143, 220, 31, 242, 181, 56, 96, 198, 1, 161, 11, 80, 62, 248, 61, 98, 135, 77, + 215, 134, 68, 159, 232, 61, 222, 43, 156, 211, 177, 35, 28, 219, 251, 131, 62, 51, 96, 1, 7, 200, 39, 87, + 99, 126, 118, 252, 207, 19, 116, 125, 200, 69, 14, 220, 202, 243, 168, 71, 157, 254, 80, 152, 79, 199, 1, + 153, 3, 114, 143, 64, 158, 25, 49, 203, 7, 73, 31, 92, 220, 179, 39, 20, 31, 59, 106, 73, 191, 152, 217, + 132, 52, 194, 186, 90, 56, 246, 242, 152, 38, 250, 144, 51, 113, 224, 86, 158, 71, 218, 112, 201, 193, 131, + 144, 16, 20, 200, 180, 8, 95, 212, 134, 101, 251, 11, 14, 136, 185, 33, 51, 109, 72, 228, 131, 66, 31, 92, + 25, 22, 6, 229, 165, 165, 150, 213, 4, 108, 118, 4, 255, 205, 125, 238, 89, 59, 7, 156, 241, 3, 183, 250, + 60, 170, 67, 79, 68, 68, 48, 77, 192, 31, 226, 128, 224, 0, 113, 221, 152, 15, 126, 133, 216, 170, 53, 230, + 131, 209, 124, 118, 108, 211, 200, 145, 80, 139, 118, 177, 98, 102, 128, 113, 128, 184, 86, 89, 1, 71, 134, + 63, 225, 180, 31, 104, 141, 207, 169, 42, 47, 135, 180, 7, 30, 208, 123, 83, 78, 242, 205, 27, 225, 108, + 62, 40, 235, 131, 139, 17, 211, 105, 102, 96, 202, 20, 184, 124, 237, 154, 37, 125, 2, 102, 151, 203, 151, + 161, 18, 253, 206, 17, 172, 211, 132, 78, 156, 221, 12, 7, 90, 243, 44, 210, 35, 75, 246, 237, 133, 68, 30, + 7, 124, 81, 27, 118, 196, 1, 99, 62, 40, 122, 133, 178, 62, 184, 40, 64, 231, 192, 247, 49, 49, 122, 77, + 96, 69, 93, 72, 28, 192, 124, 176, 178, 228, 28, 100, 13, 14, 107, 177, 87, 208, 218, 103, 177, 56, 48, + 111, 110, 147, 56, 224, 203, 62, 192, 44, 31, 148, 245, 193, 56, 91, 211, 126, 49, 213, 4, 51, 53, 13, 14, + 125, 178, 21, 234, 173, 170, 11, 171, 116, 205, 182, 162, 168, 16, 178, 195, 30, 108, 150, 3, 173, 230, + 154, 189, 30, 24, 236, 55, 113, 192, 145, 62, 104, 156, 35, 23, 53, 1, 245, 9, 230, 116, 234, 4, 71, 127, + 248, 30, 235, 66, 107, 250, 133, 140, 3, 88, 127, 84, 20, 21, 49, 14, 56, 234, 23, 185, 229, 57, 88, 15, + 156, 79, 74, 130, 196, 224, 142, 246, 122, 160, 185, 152, 227, 205, 144, 227, 128, 92, 19, 80, 62, 216, 92, + 77, 64, 125, 130, 133, 221, 186, 65, 193, 225, 195, 44, 31, 176, 154, 3, 89, 97, 230, 177, 192, 93, 207, + 33, 93, 232, 100, 84, 148, 207, 215, 3, 70, 14, 56, 210, 136, 89, 77, 96, 107, 156, 25, 120, 151, 215, 133, + 75, 238, 189, 23, 206, 159, 62, 13, 151, 208, 63, 91, 201, 129, 74, 238, 7, 140, 28, 112, 215, 51, 88, 28, + 64, 100, 62, 254, 152, 207, 235, 66, 102, 28, 112, 88, 19, 104, 141, 53, 129, 168, 11, 87, 61, 252, 48, + 148, 151, 149, 177, 249, 33, 107, 253, 192, 205, 249, 128, 91, 159, 113, 165, 30, 202, 178, 178, 32, 185, + 75, 151, 38, 26, 132, 47, 199, 1, 35, 7, 68, 77, 32, 207, 12, 136, 62, 129, 92, 23, 110, 120, 230, 105, 86, + 19, 214, 114, 221, 198, 50, 14, 20, 22, 98, 44, 104, 228, 128, 187, 159, 193, 102, 150, 223, 95, 171, 199, + 1, 77, 237, 238, 66, 91, 163, 165, 154, 192, 216, 39, 16, 117, 97, 36, 98, 26, 190, 159, 45, 175, 188, 194, + 124, 64, 141, 69, 61, 99, 153, 3, 217, 67, 30, 102, 28, 112, 251, 51, 168, 39, 133, 177, 237, 200, 168, + 112, 191, 138, 3, 174, 214, 133, 164, 13, 16, 7, 190, 124, 123, 10, 92, 198, 252, 217, 42, 125, 136, 64, + 250, 64, 85, 89, 41, 228, 96, 172, 174, 83, 160, 77, 146, 6, 85, 94, 80, 0, 169, 119, 246, 114, 73, 139, + 246, 86, 152, 205, 12, 136, 62, 129, 92, 23, 202, 189, 162, 24, 190, 79, 64, 28, 216, 57, 111, 30, 235, 23, + 90, 177, 87, 36, 219, 136, 56, 112, 67, 209, 252, 106, 45, 214, 185, 197, 219, 183, 177, 93, 230, 52, 31, + 215, 6, 101, 14, 200, 53, 129, 177, 87, 36, 107, 3, 171, 185, 54, 176, 128, 107, 132, 63, 44, 123, 207, 82, + 141, 144, 115, 224, 210, 254, 125, 251, 160, 65, 197, 236, 34, 205, 167, 32, 7, 142, 79, 159, 102, 223, + 103, 247, 229, 56, 224, 136, 3, 198, 186, 208, 76, 27, 152, 199, 231, 135, 18, 214, 173, 179, 154, 3, 27, + 6, 13, 26, 244, 191, 149, 21, 21, 106, 226, 0, 253, 76, 252, 217, 25, 131, 7, 251, 236, 46, 105, 75, 28, + 144, 235, 66, 227, 252, 216, 6, 105, 134, 112, 46, 205, 15, 209, 174, 213, 214, 45, 150, 237, 20, 32, 222, + 14, 8, 8, 72, 142, 136, 136, 80, 22, 7, 72, 27, 44, 61, 116, 8, 146, 111, 191, 205, 231, 123, 68, 178, 253, + 155, 211, 6, 104, 159, 64, 244, 140, 101, 125, 136, 102, 71, 102, 6, 5, 65, 230, 182, 109, 86, 245, 10, + 166, 160, 253, 103, 219, 108, 182, 154, 61, 123, 246, 64, 131, 34, 93, 146, 106, 194, 2, 172, 9, 19, 253, + 160, 38, 52, 114, 64, 174, 9, 100, 109, 64, 232, 67, 242, 125, 35, 209, 92, 39, 142, 8, 238, 8, 89, 59, + 118, 88, 193, 129, 55, 52, 77, 35, 14, 188, 63, 96, 192, 128, 95, 202, 74, 75, 225, 146, 10, 61, 130, 114, + 1, 172, 59, 115, 254, 248, 50, 171, 9, 253, 41, 14, 8, 63, 208, 28, 7, 132, 70, 40, 56, 16, 65, 253, 162, + 206, 157, 225, 40, 205, 17, 222, 80, 26, 11, 94, 65, 251, 79, 70, 80, 28, 216, 63, 105, 210, 36, 184, 174, + 168, 14, 161, 217, 148, 202, 179, 231, 32, 173, 127, 63, 159, 158, 29, 118, 214, 15, 8, 125, 72, 220, 57, + 99, 212, 137, 137, 3, 115, 67, 186, 192, 177, 189, 123, 85, 230, 3, 47, 160, 237, 199, 115, 251, 207, 66, + 92, 216, 134, 177, 71, 89, 46, 64, 243, 34, 251, 247, 65, 82, 251, 32, 229, 247, 154, 120, 10, 156, 209, 8, + 197, 236, 136, 172, 19, 71, 241, 126, 209, 156, 144, 16, 244, 3, 202, 56, 240, 7, 180, 253, 104, 196, 159, + 17, 83, 209, 254, 43, 122, 247, 238, 253, 115, 225, 153, 51, 112, 89, 209, 220, 34, 229, 2, 167, 222, 139, + 241, 155, 92, 192, 140, 3, 242, 253, 115, 142, 116, 226, 101, 156, 3, 180, 91, 52, 55, 52, 20, 78, 38, 39, + 171, 224, 192, 80, 180, 251, 179, 136, 63, 74, 113, 224, 219, 49, 99, 198, 192, 85, 140, 215, 74, 226, 0, + 215, 135, 115, 184, 62, 236, 15, 113, 160, 37, 14, 144, 70, 40, 116, 98, 51, 14, 144, 31, 88, 208, 173, 27, + 228, 167, 166, 186, 155, 3, 131, 208, 230, 143, 35, 40, 14, 252, 137, 219, 255, 29, 196, 233, 245, 235, + 215, 195, 79, 138, 242, 79, 150, 11, 20, 23, 67, 218, 61, 125, 253, 66, 31, 54, 114, 192, 168, 17, 26, 57, + 16, 103, 224, 192, 98, 238, 7, 22, 116, 239, 6, 39, 18, 18, 220, 201, 129, 254, 104, 243, 135, 16, 35, 16, + 163, 164, 56, 16, 213, 165, 75, 151, 191, 100, 103, 101, 49, 63, 160, 130, 3, 148, 11, 156, 63, 112, 0, + 146, 59, 118, 240, 11, 125, 184, 57, 14, 144, 70, 40, 122, 5, 198, 126, 145, 232, 25, 10, 14, 216, 243, 1, + 247, 252, 109, 246, 65, 123, 255, 27, 226, 247, 136, 103, 120, 28, 152, 196, 57, 176, 101, 216, 208, 161, + 255, 71, 49, 160, 86, 81, 127, 146, 245, 138, 87, 173, 212, 245, 97, 63, 204, 5, 204, 56, 64, 189, 2, 177, + 91, 100, 198, 1, 61, 39, 236, 194, 56, 224, 6, 125, 160, 7, 218, 186, 47, 130, 226, 192, 99, 136, 145, 136, + 87, 73, 19, 64, 76, 67, 14, 164, 205, 153, 51, 7, 126, 82, 85, 127, 176, 59, 111, 235, 33, 247, 213, 87, + 125, 126, 118, 212, 89, 63, 32, 230, 8, 69, 207, 208, 49, 7, 66, 32, 103, 247, 238, 214, 198, 130, 127, 65, + 59, 247, 68, 244, 67, 12, 70, 60, 137, 8, 71, 76, 224, 62, 96, 174, 205, 102, 187, 184, 107, 231, 78, 166, + 11, 168, 224, 0, 237, 45, 85, 149, 149, 65, 198, 160, 65, 74, 238, 183, 242, 84, 56, 210, 137, 93, 225, + 192, 172, 224, 96, 56, 252, 205, 215, 80, 255, 211, 79, 183, 250, 254, 111, 71, 59, 223, 129, 232, 141, 24, + 136, 120, 4, 241, 52, 98, 44, 98, 34, 247, 1, 171, 250, 244, 233, 243, 115, 81, 97, 161, 178, 154, 144, + 122, 4, 101, 153, 25, 144, 26, 26, 226, 87, 185, 64, 107, 253, 64, 4, 231, 64, 90, 92, 156, 30, 11, 92, + 175, 215, 130, 209, 198, 33, 136, 238, 136, 187, 17, 15, 32, 30, 69, 60, 143, 24, 135, 120, 139, 115, 96, + 199, 168, 81, 163, 160, 30, 235, 182, 26, 69, 115, 42, 180, 71, 82, 244, 233, 39, 172, 38, 84, 121, 223, + 169, 167, 161, 57, 63, 32, 231, 3, 98, 126, 196, 140, 3, 51, 130, 130, 32, 57, 246, 35, 198, 1, 23, 107, + 246, 246, 104, 223, 78, 8, 138, 3, 255, 138, 184, 23, 17, 134, 120, 2, 241, 18, 226, 53, 30, 7, 168, 38, + 60, 177, 98, 197, 10, 101, 53, 161, 184, 207, 34, 111, 246, 108, 125, 110, 76, 243, 253, 121, 129, 230, 56, + 224, 140, 31, 16, 250, 0, 113, 96, 154, 166, 193, 254, 181, 107, 88, 62, 224, 194, 44, 89, 32, 218, 183, 3, + 66, 196, 129, 59, 17, 3, 16, 15, 35, 100, 109, 112, 58, 218, 127, 81, 135, 14, 29, 234, 19, 14, 30, 84, + 214, 39, 100, 119, 25, 212, 213, 194, 145, 231, 159, 243, 219, 124, 80, 232, 67, 205, 249, 1, 51, 14, 80, + 239, 24, 255, 80, 33, 62, 58, 138, 237, 151, 56, 57, 83, 106, 67, 219, 6, 33, 58, 34, 186, 32, 186, 33, + 238, 66, 220, 135, 144, 181, 193, 73, 60, 14, 172, 31, 56, 112, 224, 47, 165, 231, 207, 171, 233, 19, 82, + 46, 112, 233, 50, 219, 87, 73, 191, 247, 158, 38, 243, 2, 254, 198, 129, 230, 252, 128, 81, 35, 90, 46, + 113, 96, 10, 98, 251, 204, 119, 216, 221, 19, 78, 236, 157, 163, 89, 181, 118, 8, 17, 7, 40, 23, 48, 171, + 9, 153, 54, 200, 57, 16, 63, 238, 149, 87, 224, 26, 230, 108, 170, 114, 1, 118, 255, 125, 74, 10, 164, 116, + 190, 221, 111, 250, 68, 206, 248, 1, 103, 56, 48, 151, 115, 224, 211, 9, 19, 216, 110, 65, 11, 247, 79, + 144, 253, 201, 7, 136, 56, 112, 27, 162, 171, 84, 19, 62, 36, 213, 132, 175, 115, 251, 207, 68, 228, 175, + 93, 179, 70, 93, 46, 80, 69, 249, 224, 13, 40, 218, 242, 49, 139, 3, 34, 31, 244, 7, 31, 224, 200, 15, 152, + 197, 2, 185, 95, 32, 250, 134, 209, 124, 158, 144, 56, 176, 233, 165, 151, 216, 55, 43, 234, 28, 239, 154, + 105, 252, 8, 14, 80, 28, 232, 108, 82, 19, 62, 37, 213, 132, 148, 11, 68, 6, 7, 7, 95, 77, 76, 72, 80, 150, + 11, 136, 124, 240, 228, 220, 57, 246, 124, 208, 95, 114, 1, 103, 56, 32, 223, 65, 36, 122, 199, 242, 12, + 201, 124, 77, 231, 192, 234, 199, 30, 133, 178, 226, 98, 71, 247, 147, 162, 41, 3, 4, 7, 218, 241, 92, 32, + 152, 231, 2, 221, 121, 46, 112, 63, 98, 24, 226, 57, 132, 152, 23, 33, 14, 172, 235, 223, 191, 255, 223, + 74, 206, 157, 83, 166, 11, 176, 124, 16, 127, 118, 78, 120, 184, 223, 229, 131, 142, 56, 96, 214, 47, 216, + 97, 107, 220, 51, 19, 179, 100, 52, 79, 184, 0, 241, 54, 190, 183, 165, 247, 221, 7, 197, 199, 142, 153, + 221, 73, 22, 192, 143, 240, 1, 114, 46, 16, 202, 107, 194, 123, 16, 15, 106, 141, 125, 194, 241, 60, 23, + 32, 14, 236, 26, 61, 122, 180, 82, 93, 128, 245, 10, 203, 74, 33, 243, 193, 65, 62, 191, 83, 232, 10, 7, + 140, 125, 67, 177, 107, 248, 49, 231, 128, 152, 41, 93, 200, 119, 205, 22, 246, 234, 9, 121, 137, 137, 70, + 189, 56, 64, 58, 198, 92, 224, 118, 158, 11, 244, 66, 24, 251, 132, 19, 184, 253, 41, 23, 56, 26, 19, 19, + 163, 52, 23, 160, 123, 39, 127, 204, 57, 2, 135, 186, 119, 243, 187, 124, 208, 25, 14, 200, 115, 68, 98, + 166, 84, 204, 150, 47, 225, 28, 160, 253, 130, 136, 206, 157, 237, 179, 197, 92, 39, 50, 218, 95, 142, 3, + 34, 23, 248, 29, 66, 244, 9, 141, 250, 48, 254, 216, 128, 5, 129, 129, 129, 213, 241, 241, 241, 202, 122, + 4, 122, 62, 120, 29, 206, 197, 127, 7, 41, 237, 219, 251, 149, 62, 232, 42, 7, 236, 115, 197, 154, 190, 99, + 34, 246, 140, 22, 241, 254, 241, 244, 192, 64, 216, 71, 58, 17, 218, 170, 166, 166, 38, 192, 112, 100, 14, + 180, 231, 185, 128, 81, 31, 54, 230, 2, 196, 129, 85, 189, 122, 245, 250, 239, 252, 147, 39, 89, 44, 80, + 198, 1, 186, 243, 120, 253, 58, 253, 91, 20, 173, 184, 243, 216, 91, 225, 12, 7, 196, 92, 177, 184, 127, + 226, 67, 105, 223, 48, 146, 107, 133, 76, 35, 152, 53, 139, 234, 2, 163, 253, 205, 114, 1, 170, 9, 101, + 125, 88, 206, 5, 132, 46, 64, 28, 136, 27, 62, 124, 56, 155, 23, 80, 177, 75, 196, 192, 118, 202, 26, 32, + 111, 214, 76, 101, 223, 67, 242, 116, 24, 57, 32, 102, 201, 140, 179, 229, 180, 99, 66, 123, 70, 180, 107, + 182, 81, 226, 192, 98, 174, 19, 189, 69, 119, 150, 143, 25, 237, 200, 254, 174, 228, 2, 164, 11, 76, 71, + 80, 143, 32, 233, 237, 41, 83, 148, 205, 144, 179, 124, 144, 215, 4, 71, 199, 142, 241, 155, 157, 178, 230, + 56, 96, 156, 43, 22, 28, 160, 61, 35, 177, 111, 72, 59, 167, 155, 248, 238, 185, 208, 139, 231, 105, 140, + 3, 142, 142, 204, 1, 99, 46, 208, 219, 144, 11, 140, 65, 188, 193, 125, 192, 108, 68, 209, 166, 141, 27, + 149, 230, 131, 236, 123, 72, 229, 229, 144, 53, 116, 168, 219, 191, 135, 228, 77, 112, 196, 1, 121, 223, + 80, 236, 29, 203, 189, 67, 161, 21, 206, 215, 28, 19, 192, 36, 31, 52, 230, 2, 66, 23, 120, 86, 107, 236, + 17, 144, 15, 136, 234, 212, 169, 83, 125, 130, 74, 109, 168, 138, 127, 39, 247, 212, 41, 72, 231, 223, 67, + 242, 167, 153, 1, 103, 57, 32, 246, 142, 101, 189, 216, 160, 19, 57, 99, 127, 99, 46, 96, 166, 11, 200, + 115, 99, 196, 129, 15, 250, 246, 237, 203, 246, 8, 174, 40, 188, 227, 136, 125, 15, 233, 80, 42, 28, 10, + 13, 245, 203, 186, 208, 140, 3, 98, 215, 204, 172, 103, 176, 195, 166, 107, 133, 146, 70, 208, 210, 49, + 203, 5, 68, 143, 128, 114, 1, 49, 55, 54, 92, 147, 230, 5, 56, 7, 190, 122, 234, 169, 167, 254, 78, 179, + 163, 202, 242, 193, 42, 94, 23, 238, 248, 6, 82, 130, 130, 252, 178, 46, 116, 228, 7, 204, 244, 98, 89, 39, + 226, 26, 129, 51, 71, 142, 3, 198, 30, 1, 205, 11, 80, 143, 96, 136, 214, 116, 94, 96, 6, 130, 180, 161, + 228, 41, 111, 189, 165, 52, 31, 100, 28, 192, 92, 163, 112, 227, 135, 250, 55, 235, 77, 122, 69, 254, 200, + 1, 179, 123, 72, 100, 141, 128, 215, 135, 206, 30, 179, 92, 192, 56, 47, 32, 102, 200, 95, 214, 116, 109, + 136, 124, 0, 150, 26, 1, 5, 235, 62, 248, 64, 105, 62, 200, 190, 91, 143, 126, 32, 63, 114, 145, 195, 186, + 240, 55, 14, 52, 213, 8, 120, 125, 232, 170, 253, 5, 7, 204, 230, 5, 196, 236, 160, 172, 13, 145, 15, 88, + 220, 190, 125, 251, 186, 239, 247, 236, 81, 182, 87, 74, 96, 123, 101, 87, 175, 194, 137, 201, 111, 222, + 242, 183, 112, 124, 5, 102, 26, 129, 131, 250, 208, 149, 227, 40, 23, 48, 106, 67, 52, 59, 40, 180, 161, + 41, 156, 3, 43, 123, 244, 232, 241, 95, 71, 115, 115, 149, 237, 19, 49, 14, 176, 239, 160, 212, 193, 209, + 81, 225, 126, 53, 75, 238, 42, 7, 164, 250, 208, 213, 99, 228, 0, 229, 2, 102, 218, 144, 152, 25, 161, 124, + 112, 26, 143, 5, 177, 131, 7, 15, 254, 229, 66, 89, 153, 178, 126, 49, 227, 0, 105, 3, 21, 21, 112, 228, + 137, 199, 93, 254, 22, 142, 47, 194, 172, 62, 20, 247, 209, 36, 185, 110, 127, 153, 3, 102, 125, 34, 49, + 51, 34, 231, 131, 172, 87, 200, 253, 192, 174, 240, 240, 240, 127, 146, 253, 85, 237, 148, 49, 14, 208, 55, + 48, 206, 158, 133, 195, 131, 30, 104, 114, 215, 173, 63, 250, 1, 51, 14, 72, 181, 193, 173, 30, 179, 124, + 48, 196, 65, 62, 40, 122, 133, 228, 3, 232, 142, 137, 116, 113, 223, 148, 202, 154, 128, 122, 198, 229, + 121, 121, 144, 113, 119, 31, 183, 126, 47, 219, 91, 225, 32, 47, 108, 173, 253, 205, 102, 70, 28, 229, 131, + 147, 184, 15, 152, 139, 56, 163, 188, 38, 168, 210, 245, 161, 11, 153, 153, 144, 238, 167, 115, 3, 78, 112, + 160, 53, 199, 217, 124, 80, 214, 7, 105, 159, 136, 124, 64, 36, 214, 4, 213, 180, 87, 168, 178, 38, 32, + 212, 54, 52, 64, 233, 193, 3, 144, 214, 165, 139, 95, 235, 67, 14, 56, 208, 218, 211, 82, 62, 104, 212, 7, + 197, 236, 24, 113, 96, 89, 215, 174, 93, 255, 146, 145, 158, 174, 180, 79, 192, 252, 0, 250, 153, 146, 93, + 59, 225, 80, 112, 199, 223, 56, 208, 244, 247, 118, 199, 145, 57, 32, 231, 131, 98, 134, 88, 236, 19, 141, + 208, 164, 57, 114, 206, 129, 13, 253, 251, 245, 99, 125, 2, 149, 115, 35, 204, 15, 32, 7, 206, 126, 30, 7, + 169, 129, 237, 252, 114, 118, 196, 1, 15, 220, 117, 228, 92, 192, 168, 15, 202, 179, 99, 52, 71, 78, 253, + 98, 161, 17, 19, 7, 226, 134, 13, 27, 246, 107, 69, 121, 185, 178, 157, 34, 6, 210, 8, 145, 3, 69, 155, 55, + 67, 170, 230, 159, 243, 67, 38, 112, 231, 49, 230, 131, 114, 191, 88, 204, 145, 15, 213, 12, 26, 49, 231, + 192, 238, 177, 99, 199, 254, 147, 122, 133, 42, 235, 66, 177, 83, 112, 102, 237, 90, 253, 14, 194, 223, 56, + 224, 110, 251, 203, 185, 128, 220, 47, 54, 171, 9, 196, 204, 0, 213, 4, 17, 136, 212, 105, 83, 167, 178, + 92, 64, 213, 44, 185, 157, 3, 116, 239, 204, 210, 37, 191, 113, 192, 189, 246, 55, 227, 128, 92, 19, 244, + 52, 169, 9, 232, 142, 129, 201, 220, 7, 80, 93, 120, 66, 204, 146, 43, 253, 22, 2, 247, 3, 167, 163, 163, + 116, 14, 248, 111, 175, 64, 197, 49, 227, 128, 89, 77, 64, 125, 130, 23, 181, 198, 62, 1, 249, 128, 133, + 248, 111, 73, 108, 108, 172, 114, 109, 128, 221, 61, 132, 190, 38, 127, 118, 132, 63, 115, 64, 213, 17, 28, + 48, 106, 196, 242, 29, 3, 162, 79, 32, 234, 194, 169, 156, 3, 81, 164, 13, 236, 180, 64, 27, 160, 239, 213, + 249, 57, 7, 84, 158, 230, 106, 2, 185, 79, 32, 207, 17, 79, 227, 28, 88, 22, 18, 18, 210, 144, 146, 156, + 172, 116, 167, 132, 80, 205, 57, 112, 114, 198, 116, 189, 95, 164, 249, 85, 175, 64, 245, 49, 227, 128, + 220, 39, 48, 171, 11, 167, 115, 14, 172, 237, 217, 179, 231, 127, 230, 230, 228, 176, 187, 6, 84, 115, 128, + 190, 137, 149, 55, 121, 146, 222, 55, 214, 252, 70, 31, 178, 194, 254, 198, 154, 64, 204, 141, 136, 57, 98, + 113, 215, 136, 232, 21, 189, 193, 235, 66, 226, 192, 166, 1, 3, 6, 252, 124, 166, 160, 64, 185, 62, 68, + 179, 3, 53, 156, 3, 126, 228, 7, 172, 56, 206, 214, 133, 98, 150, 92, 104, 3, 51, 57, 7, 62, 125, 100, 200, + 16, 246, 109, 10, 149, 179, 196, 130, 3, 213, 6, 14, 248, 120, 109, 104, 213, 105, 174, 46, 20, 179, 228, + 116, 223, 140, 220, 47, 124, 147, 234, 66, 4, 237, 148, 108, 255, 195, 136, 17, 191, 86, 85, 86, 42, 157, + 29, 113, 196, 1, 31, 246, 3, 86, 158, 230, 234, 194, 230, 180, 129, 8, 206, 129, 248, 240, 240, 240, 127, + 208, 44, 185, 202, 121, 114, 57, 22, 156, 156, 57, 195, 215, 235, 2, 171, 143, 89, 93, 104, 212, 6, 196, + 253, 131, 52, 67, 40, 122, 198, 130, 3, 251, 199, 143, 31, 207, 114, 1, 165, 58, 113, 85, 99, 93, 32, 106, + 67, 31, 245, 3, 109, 113, 140, 53, 129, 81, 27, 160, 25, 66, 209, 51, 150, 245, 33, 178, 63, 105, 132, 41, + 180, 83, 64, 58, 177, 213, 28, 240, 65, 173, 184, 173, 142, 209, 15, 8, 109, 64, 204, 16, 138, 158, 177, + 172, 15, 9, 14, 204, 67, 28, 158, 29, 17, 161, 190, 87, 80, 197, 231, 202, 27, 26, 224, 244, 187, 209, 190, + 200, 129, 182, 182, 191, 177, 95, 40, 56, 64, 61, 227, 129, 90, 211, 185, 1, 154, 37, 166, 217, 17, 218, + 41, 153, 143, 56, 26, 181, 120, 177, 242, 221, 34, 59, 7, 174, 55, 64, 65, 204, 82, 54, 75, 232, 67, 28, + 104, 203, 227, 136, 3, 66, 31, 18, 28, 16, 179, 196, 66, 35, 156, 42, 113, 32, 47, 102, 233, 82, 245, 253, + 34, 2, 159, 31, 40, 124, 127, 45, 28, 210, 52, 95, 225, 64, 91, 31, 51, 14, 200, 250, 144, 81, 35, 28, 173, + 53, 234, 196, 148, 11, 44, 66, 20, 172, 94, 189, 154, 125, 163, 194, 10, 14, 212, 92, 191, 1, 197, 177, 31, + 65, 90, 80, 160, 47, 112, 192, 19, 142, 204, 1, 89, 35, 12, 213, 154, 106, 132, 52, 79, 254, 180, 214, 116, + 167, 64, 112, 224, 140, 184, 143, 212, 42, 63, 112, 246, 171, 47, 33, 173, 83, 176, 183, 207, 17, 121, 202, + 49, 114, 64, 232, 67, 66, 35, 20, 247, 77, 12, 213, 26, 239, 28, 17, 189, 2, 138, 5, 139, 109, 54, 91, 73, + 236, 71, 31, 89, 195, 129, 42, 253, 126, 218, 243, 187, 227, 33, 61, 84, 159, 43, 246, 82, 14, 120, 210, + 105, 137, 3, 66, 39, 150, 123, 5, 98, 142, 144, 252, 64, 84, 96, 96, 224, 249, 143, 249, 236, 128, 21, 28, + 160, 25, 146, 178, 164, 68, 200, 236, 209, 221, 206, 1, 47, 235, 27, 121, 218, 113, 196, 1, 161, 19, 203, + 189, 2, 185, 95, 212, 132, 3, 177, 86, 114, 0, 235, 143, 31, 179, 179, 224, 240, 61, 125, 189, 113, 182, + 220, 19, 143, 224, 128, 124, 223, 132, 89, 175, 64, 244, 139, 228, 158, 33, 113, 32, 218, 114, 14, 92, 187, + 198, 238, 34, 202, 14, 123, 208, 219, 246, 140, 60, 245, 200, 28, 144, 117, 98, 179, 126, 17, 113, 64, 244, + 12, 201, 15, 144, 62, 20, 213, 174, 93, 59, 107, 57, 80, 95, 15, 149, 37, 37, 144, 59, 226, 73, 125, 223, + 208, 59, 102, 8, 60, 249, 56, 226, 128, 232, 23, 201, 28, 120, 78, 107, 58, 83, 206, 56, 128, 126, 160, + 212, 74, 14, 208, 222, 241, 197, 202, 74, 56, 254, 242, 88, 253, 78, 50, 19, 14, 120, 24, 15, 60, 249, 104, + 210, 49, 246, 10, 68, 191, 232, 222, 22, 56, 192, 98, 193, 230, 77, 155, 148, 239, 27, 219, 57, 80, 87, + 199, 120, 144, 63, 237, 109, 157, 3, 1, 55, 247, 141, 60, 136, 3, 222, 112, 154, 243, 3, 130, 3, 15, 106, + 77, 247, 10, 100, 14, 44, 70, 156, 89, 67, 26, 145, 85, 126, 128, 247, 141, 10, 150, 46, 129, 67, 154, 174, + 23, 123, 40, 7, 188, 225, 200, 53, 65, 115, 126, 128, 56, 240, 152, 3, 63, 16, 137, 56, 179, 122, 213, 42, + 198, 1, 213, 61, 35, 6, 214, 51, 32, 173, 48, 22, 210, 131, 59, 122, 170, 78, 228, 77, 199, 200, 129, 96, + 173, 177, 111, 108, 198, 1, 163, 31, 32, 14, 228, 189, 27, 29, 205, 98, 129, 37, 28, 224, 187, 70, 231, + 247, 236, 134, 204, 223, 221, 225, 137, 28, 240, 166, 211, 156, 31, 112, 196, 1, 163, 31, 32, 173, 248, 88, + 100, 100, 164, 37, 243, 3, 2, 53, 13, 215, 225, 199, 172, 44, 200, 238, 223, 207, 211, 116, 34, 111, 60, + 174, 250, 1, 185, 54, 164, 158, 225, 66, 196, 225, 136, 89, 179, 216, 92, 185, 101, 28, 192, 103, 85, 22, + 21, 65, 238, 19, 143, 235, 26, 129, 103, 212, 135, 222, 120, 92, 241, 3, 114, 93, 240, 134, 196, 129, 5, + 136, 148, 201, 147, 38, 177, 153, 98, 213, 243, 132, 246, 188, 144, 234, 195, 139, 85, 112, 226, 181, 63, + 233, 223, 185, 54, 153, 41, 179, 152, 7, 222, 122, 204, 56, 96, 230, 7, 140, 26, 17, 113, 96, 58, 143, 5, + 196, 129, 3, 175, 142, 27, 199, 238, 40, 86, 61, 87, 108, 231, 0, 205, 150, 214, 215, 67, 65, 228, 34, 72, + 179, 105, 246, 218, 160, 141, 52, 2, 111, 62, 45, 213, 5, 61, 77, 56, 32, 122, 70, 130, 3, 228, 11, 226, + 71, 142, 28, 249, 107, 101, 69, 133, 242, 253, 2, 59, 7, 48, 247, 100, 61, 228, 173, 91, 32, 227, 182, 78, + 109, 153, 23, 122, 251, 113, 133, 3, 195, 12, 28, 152, 70, 28, 224, 241, 224, 235, 225, 195, 135, 179, 239, + 26, 211, 253, 164, 85, 22, 112, 64, 204, 17, 148, 37, 38, 64, 214, 93, 189, 219, 170, 135, 236, 11, 199, + 25, 14, 220, 163, 53, 237, 27, 210, 252, 192, 4, 3, 7, 62, 11, 11, 11, 251, 235, 233, 83, 167, 148, 223, + 71, 213, 36, 47, 108, 104, 128, 138, 211, 167, 33, 247, 209, 97, 122, 255, 208, 218, 188, 208, 87, 142, 43, + 28, 144, 103, 72, 136, 3, 52, 79, 56, 151, 115, 96, 115, 223, 190, 125, 255, 35, 59, 59, 27, 110, 40, 222, + 59, 110, 18, 15, 248, 110, 99, 222, 132, 215, 245, 188, 208, 58, 189, 208, 151, 142, 35, 14, 200, 125, 195, + 190, 6, 14, 136, 121, 66, 54, 83, 202, 57, 240, 65, 143, 30, 61, 26, 18, 14, 30, 84, 127, 255, 128, 204, + 129, 218, 58, 86, 35, 22, 46, 127, 15, 210, 219, 7, 89, 165, 25, 251, 226, 113, 134, 3, 52, 75, 70, 243, + 132, 52, 83, 74, 115, 197, 246, 217, 114, 206, 129, 21, 157, 59, 119, 174, 222, 190, 109, 155, 101, 61, 3, + 145, 19, 48, 189, 112, 215, 78, 56, 220, 189, 155, 61, 47, 84, 24, 15, 124, 241, 104, 210, 145, 57, 32, + 102, 72, 196, 60, 161, 152, 41, 165, 217, 114, 218, 47, 176, 239, 152, 32, 168, 54, 92, 26, 20, 20, 116, + 110, 195, 134, 13, 214, 233, 197, 82, 78, 80, 126, 252, 56, 228, 12, 121, 216, 158, 19, 40, 242, 3, 190, + 124, 204, 56, 64, 126, 32, 212, 192, 1, 113, 7, 9, 237, 25, 209, 174, 153, 216, 55, 36, 14, 68, 33, 142, + 147, 94, 76, 90, 161, 85, 58, 17, 227, 0, 125, 39, 1, 107, 210, 188, 215, 95, 83, 153, 19, 248, 242, 49, + 243, 3, 242, 76, 169, 188, 95, 64, 28, 160, 93, 51, 218, 55, 164, 157, 83, 186, 151, 110, 22, 231, 0, 245, + 12, 82, 223, 156, 56, 241, 31, 116, 63, 165, 85, 58, 17, 203, 9, 234, 244, 156, 160, 104, 245, 42, 200, + 232, 216, 65, 197, 190, 129, 63, 28, 153, 3, 198, 185, 98, 226, 128, 188, 107, 70, 59, 167, 180, 119, 60, + 142, 115, 96, 38, 231, 0, 33, 126, 228, 243, 207, 255, 15, 125, 191, 66, 229, 55, 76, 110, 2, 215, 138, 74, + 247, 237, 133, 172, 62, 110, 215, 9, 252, 225, 200, 126, 64, 158, 43, 22, 123, 70, 98, 215, 76, 220, 73, + 70, 187, 231, 116, 255, 0, 221, 65, 33, 122, 135, 11, 56, 15, 62, 127, 104, 240, 224, 191, 158, 202, 207, + 183, 84, 35, 96, 241, 0, 159, 87, 89, 88, 8, 199, 158, 125, 198, 161, 78, 112, 11, 60, 240, 167, 211, 18, + 7, 104, 239, 88, 236, 158, 211, 29, 20, 207, 107, 77, 123, 6, 243, 57, 7, 54, 246, 238, 221, 251, 167, 228, + 164, 36, 245, 119, 20, 26, 227, 193, 229, 203, 236, 251, 54, 167, 23, 204, 135, 140, 118, 237, 220, 145, + 19, 248, 219, 49, 114, 64, 236, 154, 137, 189, 99, 186, 127, 128, 238, 160, 16, 253, 227, 103, 53, 93, 47, + 22, 90, 33, 233, 68, 212, 63, 94, 137, 245, 97, 229, 151, 95, 124, 97, 221, 60, 145, 0, 205, 150, 97, 61, + 114, 254, 219, 29, 112, 184, 71, 247, 214, 246, 14, 232, 133, 248, 27, 100, 14, 24, 119, 207, 141, 189, 67, + 161, 23, 27, 117, 34, 226, 192, 18, 155, 205, 118, 138, 238, 171, 165, 88, 96, 101, 109, 192, 226, 1, 114, + 160, 226, 100, 30, 28, 123, 114, 120, 107, 226, 65, 91, 219, 194, 211, 56, 32, 250, 199, 70, 189, 88, 214, + 137, 132, 70, 64, 28, 160, 153, 178, 212, 137, 19, 39, 254, 157, 124, 128, 85, 253, 67, 59, 7, 40, 30, 96, + 141, 64, 241, 32, 189, 157, 237, 86, 52, 195, 182, 182, 131, 39, 113, 64, 158, 33, 160, 158, 129, 172, 21, + 210, 254, 185, 208, 137, 132, 70, 48, 139, 115, 128, 240, 237, 136, 17, 35, 254, 86, 92, 84, 164, 252, 174, + 202, 155, 114, 2, 138, 7, 164, 25, 238, 220, 9, 89, 119, 246, 210, 235, 3, 231, 245, 162, 182, 182, 65, 91, + 195, 140, 3, 178, 94, 44, 116, 34, 163, 70, 32, 234, 67, 81, 27, 16, 7, 62, 238, 215, 175, 223, 191, 211, + 247, 108, 172, 206, 11, 153, 47, 160, 62, 226, 153, 51, 112, 252, 133, 145, 122, 60, 48, 153, 43, 249, 205, + 254, 46, 113, 64, 222, 61, 38, 157, 72, 104, 4, 162, 62, 20, 243, 197, 108, 166, 140, 115, 96, 117, 72, 72, + 72, 213, 231, 113, 113, 214, 231, 133, 85, 250, 183, 47, 169, 151, 88, 184, 124, 57, 100, 6, 7, 59, 19, 15, + 218, 250, 221, 123, 10, 228, 99, 182, 127, 46, 116, 34, 210, 8, 68, 125, 40, 230, 10, 197, 44, 9, 213, 6, + 139, 120, 94, 120, 34, 58, 42, 138, 233, 68, 74, 191, 105, 99, 6, 218, 59, 160, 185, 146, 148, 100, 200, + 121, 224, 254, 150, 226, 193, 255, 3, 237, 138, 117, 79, 91, 15, 199, 64, 0, 0, 39, 247, 109, 107, 66, 84, + 250, 206, 202, 254, 0, 127, 59, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 93, 121, 124, 149, 229, 149, 254, 192, 86, 176, 12, 86, 92, 234, + 111, 58, 232, 84, 199, 254, 172, 182, 214, 165, 206, 88, 157, 113, 220, 177, 142, 165, 45, 139, 32, 138, + 132, 125, 223, 183, 72, 144, 157, 144, 176, 67, 88, 146, 16, 8, 16, 18, 8, 145, 0, 2, 97, 145, 77, 41, 155, + 66, 13, 155, 144, 4, 8, 9, 97, 71, 16, 17, 212, 58, 203, 153, 243, 188, 57, 231, 222, 55, 31, 247, 38, 33, + 36, 249, 110, 144, 63, 158, 31, 16, 114, 239, 247, 190, 239, 115, 206, 115, 206, 121, 183, 143, 46, 94, + 188, 72, 161, 132, 191, 19, 209, 150, 25, 51, 232, 93, 199, 161, 72, 198, 24, 198, 4, 198, 36, 198, 100, + 11, 19, 25, 227, 24, 209, 140, 33, 140, 209, 247, 220, 67, 231, 78, 157, 162, 75, 223, 124, 227, 121, 31, + 170, 18, 190, 250, 234, 171, 144, 194, 165, 111, 191, 165, 130, 253, 251, 105, 68, 237, 218, 52, 194, 226, + 63, 134, 49, 69, 16, 35, 246, 48, 94, 248, 31, 200, 72, 109, 222, 156, 190, 253, 191, 255, 243, 188, 253, + 55, 112, 109, 128, 77, 94, 250, 238, 59, 74, 120, 225, 5, 26, 36, 252, 142, 23, 159, 143, 177, 248, 135, + 255, 143, 101, 140, 98, 68, 48, 62, 73, 74, 186, 193, 127, 89, 112, 225, 66, 200, 225, 59, 142, 1, 235, 34, + 35, 105, 0, 243, 26, 37, 58, 63, 81, 120, 143, 17, 91, 152, 32, 218, 48, 156, 49, 178, 78, 29, 58, 145, + 147, 99, 180, 223, 235, 182, 223, 192, 181, 227, 242, 223, 255, 78, 7, 55, 111, 166, 193, 213, 171, 211, + 72, 43, 6, 104, 236, 183, 181, 31, 26, 49, 171, 94, 61, 243, 153, 139, 33, 106, 207, 161, 140, 11, 33, 136, + 175, 56, 6, 124, 121, 254, 60, 77, 122, 248, 225, 194, 220, 78, 248, 214, 28, 208, 214, 126, 104, 196, 218, + 168, 40, 163, 253, 94, 183, 187, 74, 226, 203, 47, 67, 18, 223, 254, 239, 255, 210, 162, 246, 237, 77, 108, + 143, 182, 248, 159, 100, 241, 15, 109, 128, 70, 228, 176, 86, 32, 103, 240, 186, 205, 55, 80, 126, 248, + 230, 191, 255, 155, 118, 164, 164, 24, 254, 71, 9, 223, 19, 132, 251, 241, 162, 9, 67, 241, 239, 7, 31, + 164, 243, 95, 124, 97, 52, 195, 235, 54, 87, 69, 124, 25, 162, 184, 120, 249, 50, 21, 100, 101, 209, 200, + 219, 110, 51, 57, 222, 104, 201, 3, 199, 139, 45, 68, 73, 222, 191, 176, 85, 43, 250, 230, 127, 254, 199, + 243, 246, 222, 64, 249, 2, 177, 9, 54, 16, 247, 236, 179, 190, 58, 112, 172, 96, 140, 204, 13, 33, 246, + 111, 75, 76, 188, 193, 255, 181, 128, 243, 172, 80, 5, 120, 93, 17, 30, 110, 120, 30, 37, 26, 48, 90, 108, + 1, 154, 48, 236, 39, 63, 161, 188, 221, 187, 141, 157, 120, 221, 214, 170, 138, 243, 33, 140, 175, 185, + 166, 203, 92, 178, 196, 232, 252, 8, 209, 252, 104, 177, 5, 104, 194, 148, 199, 31, 167, 47, 89, 39, 0, + 175, 219, 122, 3, 229, 143, 11, 95, 127, 77, 199, 14, 30, 164, 200, 219, 111, 55, 185, 94, 164, 112, 63, + 82, 180, 127, 81, 135, 14, 116, 153, 53, 194, 235, 118, 86, 105, 156, 59, 23, 178, 128, 62, 125, 117, 233, + 18, 197, 255, 231, 127, 250, 52, 96, 132, 104, 63, 214, 135, 182, 207, 158, 77, 151, 190, 255, 222, 243, + 118, 86, 101, 156, 11, 113, 92, 226, 58, 112, 89, 191, 126, 212, 95, 234, 189, 97, 162, 253, 67, 110, 185, + 133, 114, 51, 51, 233, 2, 219, 135, 215, 109, 188, 129, 138, 3, 114, 128, 29, 105, 105, 134, 255, 193, 178, + 214, 11, 237, 159, 240, 200, 35, 116, 142, 235, 254, 243, 156, 195, 122, 221, 198, 42, 13, 30, 195, 80, + 198, 133, 139, 23, 41, 111, 239, 94, 26, 82, 187, 182, 137, 1, 240, 253, 190, 140, 148, 119, 222, 49, 182, + 225, 117, 251, 110, 160, 140, 56, 39, 49, 8, 181, 62, 214, 125, 57, 215, 251, 154, 235, 56, 172, 255, 95, + 254, 238, 59, 186, 204, 113, 29, 115, 128, 200, 239, 128, 152, 127, 251, 55, 234, 39, 107, 253, 189, 25, + 155, 226, 226, 232, 123, 34, 51, 239, 11, 96, 253, 231, 27, 254, 204, 183, 252, 153, 111, 241, 89, 254, + 247, 101, 254, 46, 124, 39, 190, 27, 207, 208, 124, 167, 42, 216, 125, 101, 225, 139, 10, 6, 198, 26, 245, + 217, 87, 204, 129, 225, 22, 60, 49, 71, 224, 12, 63, 63, 115, 250, 52, 229, 113, 142, 191, 127, 231, 78, + 218, 185, 97, 3, 109, 74, 79, 167, 53, 179, 102, 209, 178, 9, 19, 40, 125, 216, 48, 74, 227, 216, 255, 126, + 175, 94, 20, 117, 255, 253, 38, 6, 64, 3, 194, 81, 251, 253, 199, 127, 208, 172, 55, 223, 164, 196, 214, + 173, 41, 190, 85, 43, 138, 231, 90, 96, 86, 239, 222, 148, 52, 120, 48, 45, 28, 51, 134, 150, 199, 199, + 211, 250, 133, 11, 105, 199, 186, 117, 244, 249, 142, 29, 116, 36, 39, 199, 60, 11, 118, 160, 182, 98, 214, + 12, 217, 62, 240, 179, 115, 108, 27, 21, 61, 22, 33, 137, 179, 103, 203, 13, 224, 26, 99, 249, 245, 55, + 223, 20, 250, 31, 214, 100, 248, 223, 199, 243, 243, 13, 7, 31, 47, 94, 76, 139, 38, 78, 164, 216, 158, 61, + 105, 120, 163, 70, 212, 235, 153, 103, 168, 245, 3, 15, 80, 179, 187, 238, 162, 6, 53, 107, 82, 125, 230, + 245, 79, 140, 6, 140, 55, 24, 111, 49, 90, 51, 58, 137, 230, 15, 16, 254, 145, 251, 247, 100, 116, 96, 180, + 100, 52, 99, 52, 100, 252, 145, 241, 42, 227, 21, 65, 61, 198, 31, 24, 127, 174, 81, 131, 222, 188, 243, + 78, 106, 243, 203, 95, 82, 159, 103, 159, 165, 168, 102, 205, 104, 214, 128, 1, 180, 34, 33, 193, 216, 199, + 145, 236, 108, 211, 118, 216, 36, 236, 2, 237, 199, 252, 227, 185, 114, 30, 159, 235, 13, 208, 211, 139, + 156, 127, 95, 22, 174, 49, 134, 135, 246, 237, 163, 205, 203, 150, 209, 130, 232, 104, 26, 27, 22, 70, 189, + 158, 126, 154, 222, 249, 167, 127, 162, 63, 223, 124, 179, 225, 227, 37, 193, 203, 194, 213, 107, 140, 215, + 133, 119, 112, 216, 68, 120, 7, 175, 237, 25, 93, 69, 239, 195, 133, 251, 8, 177, 131, 126, 98, 3, 157, 25, + 109, 25, 45, 228, 115, 248, 124, 35, 177, 161, 63, 11, 234, 203, 51, 94, 19, 155, 120, 201, 194, 127, 85, + 171, 70, 77, 110, 187, 141, 58, 63, 250, 40, 69, 54, 105, 66, 201, 35, 71, 210, 150, 229, 203, 233, 72, 86, + 150, 177, 93, 216, 241, 37, 177, 135, 242, 246, 151, 80, 192, 217, 171, 1, 247, 255, 43, 225, 251, 34, 143, + 201, 241, 130, 2, 250, 219, 198, 141, 180, 104, 210, 36, 138, 126, 251, 109, 51, 134, 141, 111, 189, 213, + 240, 106, 115, 172, 252, 254, 69, 120, 105, 40, 28, 1, 141, 197, 215, 155, 136, 31, 55, 23, 238, 219, 10, + 183, 61, 132, 107, 112, 254, 158, 96, 160, 104, 64, 31, 70, 119, 209, 135, 54, 242, 185, 230, 242, 61, 111, + 50, 154, 202, 247, 54, 145, 103, 52, 150, 103, 54, 20, 168, 141, 252, 81, 116, 226, 101, 105, 55, 254, 222, + 164, 78, 29, 163, 79, 211, 186, 119, 167, 245, 169, 169, 148, 203, 26, 161, 125, 63, 207, 182, 112, 85, + 227, 22, 202, 56, 115, 166, 84, 128, 175, 35, 134, 103, 110, 218, 68, 11, 162, 162, 104, 112, 253, 250, + 212, 162, 110, 93, 122, 189, 122, 117, 31, 215, 127, 144, 177, 180, 121, 182, 249, 109, 42, 188, 52, 19, + 95, 5, 222, 22, 206, 222, 97, 132, 9, 143, 237, 45, 238, 251, 8, 215, 224, 125, 176, 96, 144, 216, 64, 184, + 104, 67, 119, 249, 253, 246, 242, 249, 86, 242, 93, 45, 228, 123, 223, 145, 103, 188, 45, 207, 116, 219, + 135, 109, 27, 13, 164, 253, 26, 75, 208, 55, 196, 18, 104, 68, 248, 139, 47, 210, 188, 225, 195, 77, 190, + 130, 24, 81, 218, 177, 11, 57, 64, 187, 57, 239, 134, 118, 151, 230, 247, 241, 123, 208, 190, 201, 29, 59, + 26, 142, 95, 20, 190, 255, 75, 252, 167, 129, 229, 203, 110, 158, 109, 126, 91, 8, 47, 240, 211, 214, 194, + 85, 91, 1, 184, 235, 40, 60, 118, 99, 244, 114, 249, 61, 230, 126, 134, 11, 48, 7, 52, 68, 126, 254, 174, + 252, 94, 47, 177, 131, 46, 242, 29, 248, 174, 14, 242, 189, 237, 173, 231, 168, 125, 180, 180, 108, 68, + 109, 195, 182, 139, 55, 44, 173, 80, 123, 128, 29, 60, 135, 239, 224, 60, 2, 186, 7, 45, 192, 184, 120, + 206, 103, 41, 0, 173, 199, 30, 9, 196, 105, 248, 113, 254, 161, 67, 180, 125, 213, 42, 58, 195, 255, 87, + 28, 190, 230, 156, 29, 185, 91, 175, 223, 255, 222, 240, 94, 223, 229, 219, 77, 92, 92, 43, 207, 45, 101, + 156, 91, 91, 252, 118, 176, 56, 6, 79, 93, 133, 235, 238, 226, 235, 189, 196, 223, 109, 222, 135, 8, 231, + 152, 243, 31, 101, 97, 164, 203, 14, 240, 251, 253, 229, 179, 248, 142, 222, 242, 125, 61, 229, 187, 187, + 203, 179, 212, 62, 58, 73, 91, 208, 174, 118, 46, 187, 112, 219, 68, 83, 233, 171, 198, 12, 228, 16, 127, + 169, 85, 139, 210, 198, 142, 165, 47, 121, 76, 81, 59, 148, 52, 142, 94, 1, 177, 234, 18, 236, 148, 115, + 179, 207, 88, 187, 147, 184, 166, 10, 127, 233, 37, 106, 246, 179, 159, 25, 95, 46, 238, 179, 95, 114, 254, + 179, 100, 242, 100, 122, 157, 115, 183, 87, 44, 206, 155, 58, 254, 88, 173, 92, 219, 60, 119, 148, 241, + 237, 34, 99, 222, 67, 120, 232, 45, 220, 244, 21, 174, 194, 197, 127, 53, 175, 135, 166, 15, 18, 78, 193, + 45, 230, 250, 177, 230, 131, 53, 63, 172, 249, 143, 117, 138, 238, 1, 208, 181, 192, 17, 242, 251, 208, 8, + 141, 15, 154, 39, 104, 190, 56, 64, 158, 165, 54, 210, 215, 178, 145, 30, 46, 219, 80, 221, 176, 99, 137, + 230, 21, 77, 100, 12, 224, 7, 207, 227, 25, 245, 234, 81, 193, 145, 35, 102, 124, 189, 230, 90, 1, 125, 71, + 174, 130, 28, 45, 123, 215, 46, 74, 30, 49, 130, 186, 61, 241, 4, 253, 241, 166, 155, 140, 15, 195, 126, + 145, 147, 65, 187, 81, 19, 7, 3, 242, 121, 212, 71, 195, 94, 123, 141, 26, 112, 156, 111, 32, 62, 17, 38, + 124, 183, 115, 138, 106, 182, 219, 135, 251, 203, 152, 43, 183, 26, 195, 135, 56, 254, 185, 252, 225, 194, + 223, 72, 199, 191, 190, 135, 117, 222, 209, 194, 51, 246, 251, 4, 58, 255, 163, 251, 0, 117, 63, 144, 218, + 67, 148, 124, 71, 164, 96, 164, 64, 215, 141, 212, 78, 134, 88, 118, 162, 54, 18, 238, 248, 245, 3, 246, + 170, 241, 164, 163, 244, 21, 182, 0, 123, 135, 253, 35, 159, 237, 204, 113, 96, 217, 244, 233, 116, 234, + 196, 9, 51, 230, 197, 141, 101, 101, 64, 99, 53, 252, 118, 219, 202, 149, 20, 217, 184, 49, 53, 102, 157, + 66, 172, 70, 237, 131, 56, 134, 152, 102, 231, 99, 167, 249, 115, 197, 225, 60, 206, 8, 93, 190, 76, 91, + 150, 44, 161, 65, 255, 250, 175, 134, 127, 140, 67, 39, 199, 31, 167, 213, 159, 149, 107, 155, 103, 229, + 216, 205, 111, 180, 96, 180, 83, 212, 183, 149, 239, 137, 22, 231, 122, 238, 99, 170, 5, 61, 7, 98, 219, + 194, 4, 1, 190, 99, 156, 192, 214, 11, 221, 59, 98, 219, 136, 218, 134, 198, 146, 193, 150, 77, 132, 75, + 223, 122, 73, 95, 161, 11, 208, 129, 78, 183, 223, 78, 169, 67, 135, 210, 201, 227, 199, 141, 143, 193, + 231, 74, 26, 199, 138, 4, 158, 143, 117, 48, 104, 253, 71, 233, 233, 20, 254, 220, 115, 244, 58, 215, 181, + 245, 196, 78, 149, 115, 196, 105, 205, 185, 53, 223, 46, 245, 247, 179, 13, 64, 227, 214, 198, 198, 210, + 160, 251, 238, 51, 252, 247, 118, 252, 113, 122, 176, 139, 107, 155, 103, 229, 88, 57, 177, 57, 182, 121, + 86, 174, 109, 190, 167, 49, 166, 23, 131, 105, 2, 181, 137, 41, 78, 209, 115, 34, 110, 189, 80, 59, 81, 27, + 113, 107, 71, 164, 227, 215, 10, 59, 199, 52, 49, 236, 199, 63, 166, 196, 176, 48, 58, 188, 119, 47, 93, + 228, 60, 10, 185, 159, 151, 188, 3, 240, 117, 227, 159, 25, 25, 134, 119, 248, 57, 226, 186, 206, 161, 53, + 21, 206, 155, 11, 223, 240, 93, 196, 181, 118, 98, 207, 167, 79, 157, 42, 53, 96, 7, 95, 177, 189, 159, + 200, 207, 167, 229, 3, 7, 210, 112, 174, 145, 7, 200, 88, 141, 114, 138, 198, 233, 96, 126, 108, 159, 227, + 83, 95, 118, 115, 28, 43, 136, 19, 196, 23, 131, 56, 11, 177, 22, 2, 217, 137, 173, 29, 193, 244, 99, 156, + 83, 52, 183, 128, 13, 32, 118, 197, 63, 255, 60, 237, 89, 187, 214, 244, 255, 28, 215, 78, 87, 51, 110, 21, + 1, 196, 27, 205, 205, 35, 27, 53, 162, 63, 114, 124, 6, 239, 58, 135, 166, 249, 89, 113, 177, 26, 49, 238, + 20, 127, 215, 213, 226, 12, 219, 253, 5, 126, 118, 238, 158, 61, 180, 184, 85, 43, 138, 230, 252, 48, 82, + 56, 159, 232, 20, 213, 108, 245, 207, 64, 188, 186, 185, 157, 225, 66, 66, 25, 224, 254, 142, 25, 65, 236, + 197, 182, 19, 91, 63, 244, 108, 41, 108, 24, 125, 138, 251, 213, 175, 232, 147, 185, 115, 233, 11, 204, 7, + 115, 44, 132, 207, 149, 101, 204, 202, 19, 208, 250, 147, 156, 115, 204, 97, 31, 124, 163, 118, 109, 51, + 79, 1, 222, 213, 215, 161, 237, 240, 243, 182, 194, 57, 114, 24, 228, 50, 208, 107, 196, 51, 59, 239, 190, + 150, 118, 156, 197, 122, 26, 251, 195, 1, 174, 133, 23, 190, 250, 170, 207, 231, 213, 167, 149, 235, 178, + 242, 59, 83, 224, 254, 247, 76, 215, 255, 5, 250, 89, 105, 109, 68, 109, 66, 109, 97, 138, 216, 241, 244, + 59, 238, 160, 141, 92, 43, 33, 198, 159, 103, 125, 13, 5, 222, 205, 252, 43, 143, 247, 150, 21, 43, 168, + 235, 35, 143, 20, 214, 161, 22, 239, 45, 132, 119, 248, 186, 59, 63, 211, 220, 76, 235, 171, 161, 130, 83, + 39, 79, 94, 51, 190, 224, 24, 4, 236, 74, 77, 165, 228, 71, 31, 53, 254, 51, 213, 226, 62, 24, 215, 129, + 248, 172, 104, 4, 178, 5, 181, 1, 248, 254, 52, 142, 241, 171, 90, 182, 164, 124, 142, 241, 231, 37, 183, + 43, 143, 49, 186, 86, 96, 158, 1, 182, 24, 219, 181, 43, 253, 233, 71, 63, 50, 245, 155, 234, 188, 250, + 187, 206, 155, 170, 175, 235, 122, 233, 32, 225, 90, 235, 105, 123, 31, 101, 185, 181, 145, 237, 243, 139, + 175, 191, 166, 83, 236, 39, 219, 39, 78, 164, 217, 117, 235, 154, 241, 140, 13, 194, 191, 23, 220, 7, 227, + 95, 245, 63, 253, 165, 151, 40, 139, 235, 221, 115, 236, 239, 103, 88, 219, 188, 230, 28, 128, 238, 160, + 198, 248, 219, 134, 13, 212, 237, 183, 191, 53, 90, 143, 124, 30, 185, 124, 115, 203, 223, 237, 249, 114, + 232, 251, 64, 199, 63, 119, 6, 190, 237, 154, 90, 115, 94, 252, 223, 73, 126, 70, 121, 226, 20, 230, 26, + 185, 189, 5, 135, 15, 211, 198, 190, 125, 105, 6, 199, 167, 41, 226, 99, 94, 218, 64, 32, 222, 97, 155, + 104, 91, 202, 67, 15, 81, 102, 82, 18, 157, 193, 186, 14, 235, 88, 121, 143, 73, 89, 113, 26, 99, 201, 185, + 102, 106, 116, 52, 53, 250, 201, 79, 204, 28, 52, 180, 94, 231, 96, 16, 223, 59, 89, 254, 174, 188, 171, + 175, 71, 57, 254, 186, 75, 107, 99, 173, 129, 240, 127, 41, 175, 188, 98, 242, 136, 138, 192, 105, 206, 79, + 225, 71, 185, 156, 159, 174, 108, 214, 140, 226, 88, 179, 166, 203, 216, 207, 10, 128, 196, 10, 130, 251, + 57, 51, 45, 159, 159, 125, 231, 157, 180, 101, 196, 8, 58, 113, 236, 88, 161, 118, 177, 134, 85, 212, 120, + 92, 45, 208, 150, 243, 108, 139, 83, 58, 116, 240, 229, 245, 26, 227, 81, 191, 117, 20, 222, 237, 245, 49, + 221, 35, 175, 103, 229, 220, 185, 184, 230, 184, 200, 111, 102, 220, 127, 63, 29, 61, 112, 160, 194, 251, + 113, 250, 220, 57, 58, 203, 99, 123, 96, 213, 42, 90, 204, 53, 148, 214, 1, 51, 43, 193, 6, 220, 223, 15, + 219, 195, 243, 227, 185, 94, 89, 211, 166, 141, 217, 87, 248, 5, 219, 40, 98, 150, 215, 124, 187, 129, 249, + 150, 121, 67, 134, 248, 226, 188, 106, 189, 238, 137, 64, 94, 215, 223, 242, 119, 55, 239, 49, 194, 183, + 93, 119, 77, 151, 159, 199, 212, 172, 73, 251, 86, 174, 52, 54, 127, 130, 159, 85, 25, 128, 182, 158, 230, + 152, 250, 25, 215, 82, 243, 31, 126, 216, 248, 95, 92, 5, 217, 65, 32, 159, 215, 254, 47, 173, 87, 143, + 178, 214, 175, 167, 179, 92, 67, 157, 226, 124, 186, 178, 250, 127, 53, 248, 146, 219, 182, 58, 49, 145, + 26, 96, 111, 138, 248, 124, 107, 203, 231, 117, 47, 20, 230, 220, 160, 243, 122, 54, 210, 205, 187, 93, + 123, 197, 138, 230, 33, 6, 124, 28, 25, 105, 98, 116, 165, 247, 141, 99, 26, 180, 0, 122, 187, 133, 219, + 48, 231, 238, 187, 77, 155, 102, 4, 176, 131, 242, 226, 61, 94, 250, 189, 128, 109, 46, 115, 222, 60, 58, + 205, 241, 244, 12, 195, 107, 142, 131, 1, 243, 237, 59, 57, 7, 125, 235, 214, 91, 205, 252, 157, 198, 121, + 228, 119, 61, 197, 231, 161, 245, 152, 107, 69, 14, 111, 223, 141, 98, 243, 238, 174, 113, 99, 197, 62, + 210, 235, 215, 55, 185, 237, 73, 142, 47, 230, 153, 92, 83, 84, 54, 240, 108, 248, 95, 62, 199, 159, 245, + 92, 207, 204, 172, 85, 203, 180, 91, 109, 192, 230, 116, 118, 41, 16, 200, 14, 84, 235, 231, 220, 117, 151, + 177, 181, 227, 252, 220, 51, 60, 182, 94, 245, 185, 52, 64, 125, 127, 104, 255, 126, 234, 252, 192, 3, 38, + 199, 183, 247, 192, 245, 17, 159, 71, 78, 143, 186, 77, 239, 68, 81, 222, 99, 29, 127, 173, 237, 206, 123, + 241, 115, 196, 253, 4, 174, 201, 242, 246, 237, 163, 211, 208, 61, 121, 230, 113, 15, 113, 18, 235, 149, + 108, 7, 7, 183, 110, 165, 21, 13, 27, 82, 124, 245, 234, 198, 118, 3, 249, 127, 105, 120, 79, 116, 252, 90, + 63, 163, 70, 13, 250, 176, 109, 91, 211, 95, 60, 227, 4, 219, 156, 151, 125, 45, 113, 44, 144, 131, 48, + 134, 188, 252, 178, 153, 187, 7, 247, 152, 159, 239, 38, 122, 63, 208, 242, 121, 213, 250, 41, 98, 227, 54, + 239, 129, 114, 93, 140, 7, 230, 100, 118, 162, 198, 97, 253, 245, 186, 175, 110, 156, 226, 28, 241, 52, + 231, 186, 123, 151, 46, 165, 69, 79, 63, 237, 179, 229, 226, 236, 32, 144, 207, 235, 220, 174, 137, 241, + 92, 47, 163, 175, 176, 49, 175, 251, 87, 34, 160, 251, 220, 214, 25, 221, 187, 155, 249, 60, 229, 30, 177, + 94, 207, 60, 160, 86, 143, 10, 226, 243, 118, 77, 101, 199, 193, 4, 25, 15, 216, 202, 242, 150, 45, 141, + 254, 225, 89, 69, 158, 205, 177, 56, 84, 128, 216, 12, 190, 118, 198, 199, 83, 10, 107, 224, 116, 177, 223, + 226, 242, 129, 89, 242, 59, 248, 221, 212, 223, 252, 134, 50, 147, 147, 233, 20, 230, 110, 216, 166, 188, + 238, 79, 105, 129, 152, 191, 122, 214, 44, 179, 175, 164, 133, 104, 126, 55, 225, 30, 177, 94, 115, 60, + 112, 31, 227, 248, 99, 188, 206, 161, 184, 199, 199, 206, 125, 240, 251, 51, 185, 214, 203, 207, 206, 54, + 250, 226, 126, 246, 177, 16, 3, 236, 243, 52, 143, 71, 65, 94, 30, 109, 26, 60, 152, 102, 223, 113, 71, + 208, 121, 3, 95, 140, 255, 217, 207, 104, 203, 168, 81, 116, 12, 90, 130, 243, 6, 252, 167, 215, 253, 40, + 45, 206, 176, 157, 238, 217, 182, 141, 90, 113, 63, 81, 223, 99, 46, 175, 171, 104, 190, 114, 143, 88, 63, + 193, 165, 247, 9, 1, 120, 183, 99, 160, 173, 251, 59, 88, 247, 49, 166, 94, 247, 245, 170, 236, 0, 243, 95, + 172, 137, 88, 99, 68, 28, 79, 224, 120, 30, 235, 248, 231, 239, 204, 223, 185, 142, 93, 219, 190, 61, 29, + 65, 78, 35, 218, 230, 117, 187, 175, 6, 168, 135, 96, 171, 17, 207, 60, 99, 234, 60, 229, 190, 143, 104, + 190, 222, 127, 59, 209, 241, 175, 167, 216, 188, 7, 203, 137, 212, 247, 193, 253, 146, 38, 77, 232, 20, + 235, 234, 177, 96, 62, 81, 80, 16, 210, 56, 129, 117, 55, 246, 233, 172, 141, 27, 233, 131, 215, 95, 247, + 173, 39, 127, 240, 218, 107, 230, 103, 200, 27, 240, 59, 94, 183, 179, 44, 56, 199, 109, 159, 217, 179, + 167, 201, 245, 49, 167, 135, 117, 90, 204, 227, 70, 72, 188, 143, 118, 113, 63, 163, 4, 238, 103, 91, 241, + 208, 124, 134, 107, 159, 195, 153, 153, 38, 166, 122, 221, 215, 107, 182, 3, 174, 89, 78, 178, 86, 254, + 141, 107, 248, 157, 115, 231, 210, 73, 212, 48, 12, 175, 219, 85, 86, 64, 247, 63, 74, 75, 163, 102, 92, + 243, 160, 198, 199, 60, 62, 230, 244, 80, 227, 13, 21, 238, 85, 243, 99, 45, 238, 75, 170, 131, 53, 231, + 51, 243, 60, 209, 209, 198, 63, 138, 107, 71, 65, 85, 2, 235, 21, 108, 0, 192, 223, 61, 111, 79, 25, 1, 45, + 62, 154, 159, 79, 125, 30, 125, 212, 172, 223, 106, 174, 143, 245, 27, 212, 247, 163, 172, 92, 79, 185, + 159, 25, 192, 239, 231, 4, 209, 125, 212, 7, 243, 158, 122, 170, 80, 243, 25, 193, 218, 113, 246, 194, 5, + 42, 56, 122, 244, 6, 42, 25, 136, 249, 185, 57, 57, 212, 253, 222, 123, 205, 156, 190, 230, 123, 88, 167, + 199, 220, 206, 88, 225, 80, 115, 189, 146, 184, 183, 117, 31, 159, 153, 84, 173, 26, 237, 90, 178, 164, + 208, 79, 2, 60, 223, 204, 195, 114, 78, 176, 62, 37, 197, 243, 177, 248, 33, 2, 121, 23, 252, 127, 224, + 175, 127, 109, 114, 190, 222, 174, 124, 111, 146, 240, 104, 107, 254, 28, 11, 115, 5, 115, 44, 59, 80, 223, + 71, 190, 176, 244, 173, 183, 76, 13, 28, 232, 217, 152, 251, 61, 204, 181, 224, 148, 176, 48, 106, 204, + 118, 114, 148, 127, 118, 3, 149, 11, 141, 1, 35, 159, 124, 210, 228, 124, 88, 191, 197, 220, 222, 104, 225, + 126, 154, 139, 251, 185, 22, 146, 4, 182, 13, 168, 246, 155, 181, 190, 219, 110, 163, 236, 237, 219, 233, + 56, 231, 196, 246, 51, 241, 60, 172, 193, 125, 204, 57, 71, 143, 251, 238, 243, 173, 39, 195, 14, 171, 18, + 96, 195, 94, 183, 161, 60, 250, 0, 62, 162, 152, 255, 30, 162, 251, 186, 127, 118, 138, 227, 95, 23, 85, + 191, 119, 115, 111, 243, 175, 218, 175, 190, 255, 97, 191, 126, 116, 146, 181, 221, 126, 222, 201, 179, + 103, 141, 13, 204, 238, 210, 133, 154, 115, 190, 137, 189, 67, 186, 87, 208, 235, 177, 184, 90, 228, 231, + 230, 22, 218, 116, 8, 180, 165, 204, 252, 179, 255, 163, 15, 81, 156, 255, 245, 113, 249, 190, 206, 117, + 37, 150, 130, 123, 245, 125, 252, 62, 234, 189, 132, 127, 254, 103, 202, 61, 112, 192, 151, 95, 226, 25, + 88, 235, 220, 253, 241, 199, 52, 140, 109, 13, 185, 166, 238, 7, 215, 189, 193, 249, 24, 211, 42, 128, 163, + 60, 102, 217, 123, 247, 26, 253, 58, 198, 249, 139, 215, 237, 185, 214, 190, 28, 57, 124, 152, 70, 61, 248, + 160, 169, 247, 212, 247, 167, 138, 238, 39, 10, 191, 243, 44, 36, 11, 244, 223, 106, 7, 137, 242, 25, 216, + 206, 166, 209, 163, 233, 4, 243, 157, 159, 151, 71, 5, 152, 11, 229, 88, 255, 225, 212, 169, 212, 227, 167, + 63, 53, 188, 35, 215, 192, 220, 50, 106, 77, 221, 67, 130, 223, 173, 10, 128, 77, 239, 216, 176, 129, 98, + 59, 119, 54, 243, 216, 94, 183, 231, 90, 0, 255, 63, 140, 187, 205, 239, 185, 199, 204, 241, 70, 11, 127, + 186, 47, 106, 142, 240, 235, 230, 222, 205, 255, 28, 209, 126, 228, 11, 115, 31, 126, 152, 242, 68, 27, + 143, 159, 58, 101, 254, 156, 215, 166, 141, 225, 186, 131, 112, 222, 89, 120, 199, 62, 2, 212, 27, 17, 85, + 136, 127, 204, 97, 173, 73, 74, 162, 30, 143, 61, 86, 168, 159, 240, 165, 16, 104, 87, 153, 248, 231, 252, + 31, 231, 114, 135, 112, 174, 134, 122, 31, 57, 127, 140, 196, 253, 89, 46, 223, 79, 14, 194, 191, 198, 254, + 25, 242, 217, 173, 236, 231, 199, 185, 222, 195, 156, 88, 78, 102, 38, 197, 252, 251, 191, 251, 206, 125, + 232, 25, 123, 240, 174, 251, 131, 97, 119, 152, 99, 204, 227, 246, 84, 5, 96, 239, 88, 98, 68, 4, 53, 248, + 209, 143, 232, 243, 207, 62, 51, 250, 230, 117, 155, 202, 138, 2, 142, 95, 187, 62, 250, 136, 222, 171, 81, + 195, 196, 254, 113, 146, 247, 197, 187, 180, 63, 24, 247, 110, 223, 79, 254, 221, 239, 40, 159, 253, 253, + 36, 231, 247, 153, 43, 87, 82, 52, 231, 1, 122, 14, 187, 183, 227, 63, 119, 175, 231, 1, 134, 56, 254, 253, + 130, 121, 71, 142, 84, 9, 64, 243, 7, 253, 225, 15, 230, 62, 150, 181, 11, 22, 152, 127, 123, 221, 166, + 178, 2, 181, 217, 86, 206, 99, 224, 135, 35, 173, 216, 175, 252, 39, 5, 224, 223, 29, 247, 225, 251, 9, 98, + 55, 219, 103, 206, 164, 51, 223, 127, 79, 91, 248, 207, 145, 181, 107, 251, 206, 119, 245, 119, 252, 247, + 44, 232, 57, 16, 221, 71, 0, 155, 155, 92, 69, 248, 71, 44, 59, 200, 121, 109, 171, 186, 117, 13, 255, 113, + 189, 122, 153, 125, 197, 94, 183, 171, 172, 56, 193, 245, 216, 154, 137, 19, 205, 250, 62, 252, 112, 130, + 248, 113, 130, 240, 154, 84, 130, 239, 107, 222, 135, 124, 97, 1, 231, 245, 39, 112, 238, 123, 204, 24, + 138, 100, 109, 196, 158, 80, 64, 239, 190, 24, 232, 248, 207, 102, 235, 251, 84, 117, 239, 80, 108, 21, + 225, 31, 123, 183, 112, 174, 29, 247, 85, 96, 63, 116, 159, 167, 158, 50, 49, 20, 177, 212, 235, 182, 149, + 5, 152, 151, 77, 229, 90, 28, 190, 57, 74, 248, 208, 253, 143, 115, 44, 223, 79, 177, 160, 118, 96, 107, + 63, 62, 179, 99, 206, 28, 179, 206, 19, 237, 248, 207, 174, 235, 93, 6, 122, 103, 146, 222, 161, 162, 123, + 135, 166, 57, 254, 121, 229, 35, 156, 51, 134, 58, 176, 79, 59, 182, 91, 55, 115, 254, 197, 156, 125, 186, + 229, 22, 218, 201, 53, 45, 114, 0, 175, 219, 118, 213, 96, 254, 17, 255, 167, 190, 242, 138, 209, 229, 168, + 32, 252, 167, 56, 197, 243, 143, 188, 47, 141, 125, 127, 93, 223, 190, 190, 59, 80, 212, 6, 244, 206, 19, + 61, 147, 111, 239, 23, 116, 175, 37, 122, 62, 30, 37, 0, 249, 18, 106, 229, 30, 15, 61, 100, 246, 71, 97, + 14, 3, 123, 228, 82, 134, 13, 51, 118, 225, 117, 251, 174, 186, 63, 92, 183, 28, 226, 218, 111, 4, 231, + 104, 3, 157, 162, 181, 223, 172, 32, 252, 219, 49, 192, 142, 253, 243, 126, 241, 11, 154, 198, 190, 160, + 239, 195, 4, 207, 122, 199, 137, 158, 245, 211, 189, 225, 122, 222, 194, 158, 91, 74, 170, 2, 252, 35, 87, + 90, 63, 127, 190, 57, 247, 134, 51, 48, 56, 235, 138, 189, 50, 253, 31, 127, 220, 204, 165, 24, 251, 8, + 129, 118, 150, 22, 208, 172, 157, 107, 215, 82, 127, 137, 213, 163, 133, 31, 229, 95, 115, 255, 146, 248, + 159, 41, 124, 130, 87, 125, 31, 242, 120, 11, 122, 246, 203, 222, 51, 102, 175, 39, 104, 142, 153, 203, + 109, 10, 101, 128, 255, 49, 13, 26, 24, 254, 91, 11, 176, 63, 22, 103, 32, 63, 90, 180, 136, 142, 113, 110, + 224, 117, 27, 175, 6, 199, 56, 247, 203, 24, 55, 206, 212, 226, 136, 211, 118, 237, 175, 181, 95, 176, 216, + 111, 243, 175, 235, 189, 122, 174, 103, 138, 83, 244, 14, 29, 251, 44, 136, 219, 231, 237, 218, 34, 151, + 181, 53, 84, 113, 20, 190, 178, 97, 3, 181, 169, 89, 211, 240, 222, 193, 241, 223, 205, 6, 254, 199, 212, + 175, 239, 231, 63, 4, 218, 91, 26, 28, 99, 123, 142, 107, 212, 200, 212, 228, 200, 213, 198, 57, 254, 121, + 223, 217, 150, 239, 207, 183, 96, 219, 129, 157, 255, 235, 62, 207, 56, 167, 232, 93, 55, 122, 238, 75, + 247, 10, 234, 58, 66, 160, 188, 194, 235, 241, 40, 14, 39, 206, 156, 161, 41, 205, 155, 27, 205, 215, 57, + 107, 189, 167, 15, 54, 208, 154, 53, 20, 119, 53, 99, 61, 192, 235, 182, 150, 6, 136, 85, 57, 251, 247, + 211, 224, 123, 239, 53, 185, 159, 206, 251, 107, 237, 103, 199, 254, 96, 252, 171, 6, 216, 235, 190, 238, + 59, 77, 116, 79, 184, 174, 31, 38, 57, 87, 114, 175, 223, 125, 152, 219, 21, 138, 64, 142, 188, 101, 217, + 50, 106, 251, 227, 31, 251, 206, 61, 98, 78, 11, 126, 211, 83, 108, 1, 235, 151, 35, 95, 120, 129, 242, + 185, 22, 204, 229, 188, 218, 235, 54, 151, 132, 163, 220, 167, 141, 41, 41, 166, 47, 152, 127, 117, 215, + 126, 182, 143, 22, 199, 191, 106, 128, 218, 128, 251, 220, 164, 189, 110, 172, 115, 9, 129, 184, 55, 252, + 31, 58, 20, 114, 56, 194, 92, 2, 67, 184, 206, 199, 190, 88, 172, 145, 219, 247, 22, 245, 23, 59, 128, 13, + 32, 23, 88, 194, 241, 244, 56, 199, 85, 175, 219, 93, 18, 160, 253, 51, 195, 194, 140, 134, 161, 62, 71, + 158, 62, 217, 241, 207, 251, 219, 92, 5, 226, 63, 144, 13, 216, 251, 128, 108, 206, 117, 190, 200, 173, + 247, 243, 157, 208, 230, 31, 58, 9, 46, 19, 185, 222, 15, 115, 252, 103, 160, 48, 151, 165, 115, 91, 131, + 28, 255, 253, 239, 230, 78, 179, 58, 117, 204, 61, 165, 5, 156, 11, 120, 221, 254, 226, 108, 58, 107, 223, + 62, 26, 88, 183, 174, 233, 15, 230, 101, 80, 159, 77, 113, 138, 198, 126, 229, 101, 129, 5, 55, 103, 182, + 29, 4, 66, 32, 27, 114, 127, 167, 226, 16, 183, 45, 84, 0, 141, 196, 250, 213, 226, 177, 99, 141, 95, 119, + 22, 142, 193, 189, 222, 105, 50, 82, 198, 110, 176, 227, 127, 15, 8, 114, 195, 254, 15, 61, 100, 214, 133, + 142, 158, 56, 225, 121, 63, 2, 1, 182, 185, 42, 54, 214, 244, 41, 194, 241, 207, 251, 219, 177, 63, 185, + 148, 252, 187, 99, 130, 34, 152, 143, 7, 227, 222, 240, 127, 240, 160, 247, 224, 241, 201, 195, 158, 40, + 214, 199, 69, 163, 71, 83, 24, 231, 117, 200, 239, 236, 253, 240, 250, 254, 95, 189, 155, 113, 132, 232, 0, + 124, 9, 122, 138, 253, 76, 225, 143, 60, 66, 187, 182, 110, 165, 227, 156, 55, 162, 38, 240, 188, 95, 118, + 255, 10, 10, 104, 12, 231, 42, 221, 164, 221, 58, 239, 167, 107, 254, 90, 247, 5, 227, 42, 16, 167, 165, + 65, 48, 222, 67, 129, 127, 104, 34, 234, 183, 124, 30, 155, 204, 109, 219, 104, 74, 203, 150, 102, 79, 34, + 98, 62, 116, 95, 223, 249, 135, 60, 89, 231, 178, 116, 158, 99, 180, 216, 192, 64, 209, 8, 212, 4, 152, 31, + 234, 252, 243, 159, 211, 138, 184, 56, 202, 193, 62, 40, 236, 131, 224, 220, 16, 186, 226, 101, 63, 145, + 159, 110, 229, 92, 182, 107, 245, 234, 198, 94, 135, 74, 251, 237, 186, 63, 201, 242, 221, 242, 226, 191, + 36, 238, 129, 131, 220, 190, 202, 6, 124, 29, 122, 184, 123, 199, 14, 115, 183, 213, 192, 103, 159, 165, + 176, 90, 181, 204, 28, 15, 246, 165, 217, 231, 31, 117, 63, 60, 230, 56, 245, 14, 163, 24, 177, 5, 232, + 192, 48, 209, 8, 196, 129, 78, 142, 255, 126, 238, 78, 28, 103, 199, 115, 237, 184, 118, 225, 194, 194, + 122, 2, 185, 1, 107, 130, 23, 253, 69, 222, 63, 181, 105, 83, 147, 171, 12, 112, 138, 214, 253, 186, 230, + 103, 231, 253, 37, 113, 118, 45, 124, 7, 228, 63, 39, 167, 82, 128, 185, 111, 196, 231, 109, 31, 126, 72, + 19, 56, 15, 14, 187, 253, 118, 179, 166, 103, 159, 123, 118, 159, 125, 29, 235, 20, 61, 7, 163, 247, 153, + 76, 19, 45, 136, 22, 127, 210, 92, 0, 54, 128, 124, 0, 58, 162, 239, 37, 233, 201, 113, 33, 149, 227, 202, + 1, 206, 191, 80, 87, 34, 31, 171, 172, 62, 31, 97, 91, 255, 132, 251, 219, 173, 102, 77, 83, 179, 12, 118, + 252, 115, 254, 182, 239, 131, 191, 84, 193, 194, 74, 68, 30, 107, 83, 69, 143, 1, 252, 15, 90, 140, 53, + 187, 209, 77, 154, 80, 147, 155, 111, 54, 247, 146, 99, 30, 255, 29, 225, 75, 239, 186, 208, 179, 175, 200, + 241, 16, 235, 117, 110, 92, 231, 48, 181, 222, 141, 23, 255, 129, 14, 32, 150, 14, 17, 27, 64, 206, 160, + 239, 4, 211, 121, 98, 236, 117, 199, 243, 58, 220, 123, 175, 209, 27, 240, 127, 180, 18, 250, 13, 192, 222, + 167, 114, 159, 59, 72, 251, 236, 188, 223, 158, 243, 89, 224, 1, 247, 0, 236, 243, 80, 5, 106, 0, 98, 95, + 78, 118, 54, 37, 244, 237, 75, 111, 215, 174, 109, 120, 120, 83, 120, 215, 247, 124, 193, 103, 181, 198, + 87, 238, 221, 251, 161, 237, 115, 16, 186, 254, 173, 247, 218, 32, 31, 208, 187, 186, 49, 198, 58, 55, 208, + 65, 108, 43, 76, 236, 160, 145, 216, 65, 175, 199, 30, 163, 117, 28, 23, 140, 22, 32, 38, 84, 148, 222, + 113, 223, 55, 47, 93, 74, 29, 57, 159, 133, 93, 66, 211, 144, 203, 216, 115, 62, 26, 247, 189, 226, 63, 99, + 250, 116, 202, 103, 27, 5, 71, 229, 9, 244, 31, 227, 251, 241, 7, 31, 24, 253, 197, 251, 82, 154, 90, 188, + 183, 17, 126, 116, 31, 50, 230, 118, 144, 23, 187, 207, 64, 169, 223, 219, 235, 22, 243, 130, 216, 0, 116, + 0, 249, 64, 132, 216, 18, 108, 10, 90, 208, 206, 101, 7, 230, 61, 54, 55, 221, 68, 49, 109, 219, 82, 118, + 86, 150, 241, 129, 114, 239, 63, 251, 84, 110, 94, 30, 141, 122, 254, 121, 19, 215, 244, 253, 229, 154, + 247, 197, 59, 69, 107, 126, 47, 180, 31, 232, 255, 47, 255, 66, 251, 247, 236, 161, 67, 172, 209, 229, 213, + 119, 124, 23, 252, 62, 101, 248, 112, 179, 87, 3, 227, 221, 220, 226, 189, 163, 19, 248, 14, 67, 189, 219, + 200, 62, 255, 102, 239, 135, 210, 252, 40, 197, 241, 207, 131, 187, 99, 129, 214, 5, 58, 63, 96, 219, 65, + 123, 203, 14, 176, 143, 64, 181, 224, 147, 245, 235, 141, 78, 151, 39, 255, 240, 169, 15, 38, 78, 52, 207, + 235, 37, 125, 12, 86, 243, 123, 229, 251, 0, 230, 208, 103, 180, 111, 111, 114, 212, 242, 232, 247, 97, + 174, 233, 192, 255, 4, 206, 189, 145, 127, 189, 233, 248, 117, 30, 188, 235, 157, 228, 238, 187, 43, 237, + 125, 105, 246, 249, 39, 205, 139, 117, 140, 82, 29, 127, 14, 156, 236, 20, 61, 3, 1, 155, 65, 190, 128, + 220, 90, 231, 8, 96, 7, 3, 44, 59, 240, 173, 29, 57, 133, 57, 39, 108, 179, 229, 29, 119, 208, 234, 164, + 164, 194, 49, 96, 221, 42, 143, 49, 216, 243, 233, 167, 212, 139, 107, 209, 78, 78, 81, 223, 159, 236, 4, + 246, 125, 112, 145, 230, 1, 224, 135, 109, 89, 11, 215, 205, 159, 79, 71, 176, 47, 157, 245, 176, 172, 64, + 191, 15, 236, 223, 79, 195, 94, 125, 213, 236, 209, 177, 115, 187, 226, 238, 44, 133, 223, 234, 189, 70, + 186, 55, 201, 94, 11, 11, 228, 31, 169, 150, 13, 36, 57, 69, 247, 68, 64, 11, 38, 137, 29, 68, 5, 177, 3, + 141, 11, 176, 77, 243, 190, 194, 26, 53, 40, 157, 253, 21, 126, 155, 205, 28, 150, 117, 12, 192, 255, 145, + 130, 2, 154, 208, 168, 145, 241, 45, 61, 219, 107, 175, 245, 233, 124, 79, 138, 171, 95, 94, 240, 223, 71, + 198, 161, 47, 199, 129, 125, 159, 125, 70, 135, 56, 31, 42, 75, 191, 241, 185, 44, 230, 30, 181, 60, 124, + 202, 190, 183, 82, 223, 225, 234, 222, 123, 174, 188, 219, 251, 17, 221, 122, 95, 156, 54, 170, 14, 104, + 60, 176, 207, 195, 197, 6, 176, 3, 228, 149, 186, 118, 0, 94, 244, 157, 78, 136, 73, 168, 23, 223, 168, 86, + 141, 210, 184, 78, 52, 54, 80, 70, 254, 241, 89, 157, 191, 198, 247, 135, 59, 87, 250, 126, 162, 19, 26, + 190, 159, 230, 248, 223, 109, 4, 45, 28, 247, 151, 191, 80, 46, 215, 232, 208, 192, 171, 233, 243, 65, 212, + 211, 140, 17, 175, 189, 102, 114, 108, 251, 158, 226, 222, 242, 12, 248, 159, 251, 222, 74, 155, 119, 123, + 127, 138, 114, 239, 158, 219, 118, 175, 133, 5, 218, 35, 169, 90, 96, 239, 143, 129, 29, 32, 182, 140, 117, + 252, 57, 34, 124, 178, 159, 244, 29, 26, 13, 91, 69, 142, 242, 38, 231, 234, 203, 99, 99, 203, 100, 3, 200, + 35, 183, 173, 94, 77, 29, 127, 250, 83, 99, 87, 240, 45, 205, 249, 97, 235, 246, 58, 175, 218, 182, 151, + 190, 15, 192, 31, 161, 201, 58, 135, 158, 244, 238, 187, 148, 199, 125, 207, 226, 254, 148, 6, 208, 202, + 92, 214, 187, 152, 176, 48, 115, 95, 109, 27, 25, 79, 189, 171, 86, 115, 122, 245, 119, 221, 131, 234, 222, + 147, 228, 230, 60, 149, 121, 88, 250, 192, 3, 180, 250, 245, 215, 233, 163, 46, 93, 104, 243, 144, 33, 180, + 149, 107, 247, 45, 35, 71, 210, 95, 35, 34, 104, 67, 235, 214, 180, 242, 133, 23, 104, 241, 61, 247, 80, + 42, 199, 47, 183, 45, 232, 26, 169, 125, 62, 122, 154, 227, 207, 15, 144, 107, 194, 47, 35, 132, 39, 213, + 2, 243, 94, 180, 90, 181, 232, 163, 197, 139, 77, 191, 74, 59, 14, 208, 191, 125, 187, 119, 83, 248, 175, + 127, 237, 203, 249, 34, 156, 162, 115, 125, 110, 221, 127, 223, 194, 34, 143, 48, 74, 108, 180, 143, 240, + 214, 138, 199, 50, 35, 62, 158, 242, 142, 31, 167, 172, 3, 7, 74, 4, 126, 111, 225, 168, 81, 38, 207, 179, + 239, 176, 122, 215, 241, 223, 101, 163, 103, 77, 236, 122, 206, 189, 31, 201, 240, 207, 250, 251, 1, 215, + 138, 155, 216, 6, 119, 101, 100, 152, 120, 114, 16, 103, 63, 48, 87, 195, 207, 57, 200, 124, 216, 127, 207, + 225, 250, 234, 0, 143, 121, 38, 215, 216, 155, 194, 195, 105, 217, 19, 79, 208, 124, 110, 191, 189, 142, + 234, 222, 51, 175, 181, 194, 68, 199, 95, 43, 160, 255, 170, 5, 200, 81, 161, 3, 221, 238, 187, 143, 118, + 115, 14, 135, 92, 182, 164, 49, 128, 94, 226, 247, 162, 89, 255, 116, 205, 218, 214, 125, 187, 222, 179, + 185, 87, 14, 210, 61, 4, 52, 17, 113, 113, 128, 216, 172, 57, 35, 204, 250, 5, 251, 71, 30, 83, 92, 191, + 15, 243, 248, 227, 189, 115, 173, 255, 225, 31, 140, 230, 43, 247, 129, 238, 176, 210, 61, 14, 238, 61, 78, + 134, 247, 234, 213, 105, 229, 139, 47, 210, 206, 228, 100, 202, 198, 220, 9, 230, 140, 144, 135, 176, 182, + 20, 59, 246, 208, 31, 228, 235, 156, 119, 226, 51, 217, 28, 131, 50, 185, 221, 235, 222, 126, 155, 22, 214, + 174, 125, 197, 115, 84, 15, 244, 222, 200, 201, 142, 255, 61, 95, 208, 169, 254, 150, 13, 160, 62, 140, 98, + 237, 65, 31, 161, 237, 193, 218, 96, 244, 143, 109, 116, 26, 235, 81, 115, 25, 3, 189, 203, 71, 247, 247, + 232, 222, 94, 157, 231, 91, 24, 66, 252, 79, 118, 252, 115, 232, 225, 98, 187, 134, 203, 127, 252, 71, 51, + 79, 143, 190, 29, 224, 126, 186, 145, 133, 28, 153, 199, 254, 189, 223, 255, 222, 104, 166, 205, 253, 48, + 199, 127, 119, 157, 222, 101, 226, 206, 235, 84, 163, 151, 61, 249, 36, 237, 76, 73, 161, 108, 228, 29, 12, + 112, 26, 232, 121, 165, 129, 177, 7, 182, 133, 28, 182, 133, 61, 27, 55, 210, 186, 22, 45, 104, 193, 45, + 183, 248, 244, 192, 61, 111, 16, 39, 182, 57, 78, 108, 96, 176, 216, 0, 198, 0, 177, 0, 115, 69, 139, 56, + 151, 203, 229, 239, 11, 246, 60, 212, 76, 179, 251, 244, 49, 220, 119, 116, 2, 235, 126, 130, 227, 215, + 253, 80, 226, 30, 128, 31, 76, 112, 252, 62, 0, 219, 69, 222, 6, 29, 235, 90, 183, 174, 223, 6, 88, 139, + 109, 32, 54, 206, 31, 58, 212, 140, 81, 103, 23, 247, 129, 230, 110, 109, 95, 196, 223, 83, 111, 187, 141, + 254, 58, 108, 24, 101, 193, 127, 153, 119, 51, 166, 174, 103, 92, 11, 160, 5, 176, 3, 196, 145, 21, 207, + 61, 119, 133, 22, 232, 188, 129, 123, 14, 217, 214, 1, 196, 179, 174, 236, 7, 159, 109, 219, 70, 57, 7, 15, + 22, 249, 126, 112, 143, 49, 152, 221, 175, 159, 25, 131, 246, 242, 153, 119, 157, 192, 181, 190, 206, 243, + 164, 133, 16, 247, 233, 142, 255, 238, 16, 244, 31, 249, 185, 189, 158, 142, 124, 176, 27, 231, 87, 219, + 214, 172, 41, 98, 3, 24, 11, 140, 73, 183, 187, 239, 46, 178, 79, 67, 185, 119, 159, 103, 176, 247, 181, + 24, 159, 127, 234, 41, 218, 189, 110, 157, 137, 227, 198, 223, 203, 145, 247, 43, 236, 128, 245, 32, 155, + 99, 201, 102, 206, 27, 83, 111, 189, 213, 199, 131, 106, 129, 158, 161, 215, 249, 67, 181, 1, 228, 3, 221, + 101, 12, 166, 179, 182, 131, 107, 223, 119, 74, 206, 59, 71, 184, 111, 231, 248, 247, 43, 232, 190, 62, 61, + 211, 163, 181, 158, 205, 189, 142, 253, 226, 16, 128, 246, 31, 62, 128, 88, 8, 221, 130, 126, 193, 159, 59, + 75, 255, 59, 51, 207, 27, 211, 211, 141, 14, 238, 231, 254, 31, 230, 190, 207, 228, 156, 28, 53, 46, 242, + 252, 112, 167, 168, 223, 7, 226, 94, 115, 188, 117, 237, 218, 209, 1, 196, 117, 230, 4, 223, 85, 25, 128, + 182, 64, 11, 50, 241, 14, 34, 206, 207, 237, 252, 80, 109, 0, 126, 48, 205, 241, 235, 0, 114, 194, 190, 50, + 6, 157, 56, 191, 217, 190, 118, 173, 209, 148, 108, 236, 233, 224, 156, 32, 190, 99, 71, 31, 247, 221, 196, + 94, 6, 203, 103, 237, 90, 79, 215, 118, 85, 247, 67, 137, 251, 197, 210, 127, 216, 40, 98, 33, 252, 22, + 243, 176, 154, 15, 194, 6, 160, 3, 230, 62, 122, 246, 157, 21, 211, 167, 83, 222, 169, 83, 198, 247, 123, + 222, 117, 151, 137, 19, 122, 103, 101, 160, 115, 140, 202, 189, 137, 249, 53, 107, 210, 102, 174, 223, 178, + 161, 35, 236, 243, 251, 63, 255, 188, 210, 1, 45, 248, 60, 51, 147, 50, 234, 213, 243, 241, 226, 214, 1, + 219, 15, 84, 11, 49, 55, 16, 139, 119, 66, 158, 62, 109, 190, 103, 66, 195, 134, 38, 222, 67, 251, 116, + 127, 170, 125, 135, 151, 198, 252, 57, 78, 209, 124, 223, 214, 93, 175, 121, 87, 44, 16, 27, 133, 191, 234, + 125, 225, 154, 15, 170, 13, 192, 190, 97, 231, 237, 56, 79, 127, 159, 99, 246, 2, 174, 207, 58, 89, 253, + 86, 155, 15, 116, 142, 193, 104, 95, 157, 58, 230, 29, 186, 57, 172, 27, 198, 39, 61, 224, 94, 145, 197, + 254, 11, 172, 106, 212, 200, 151, 147, 165, 200, 24, 168, 31, 196, 88, 126, 0, 45, 52, 26, 199, 26, 248, + 241, 251, 239, 83, 228, 51, 207, 248, 238, 235, 213, 121, 77, 221, 167, 164, 247, 120, 204, 176, 236, 31, + 220, 135, 162, 238, 43, 160, 75, 240, 3, 205, 137, 245, 61, 65, 106, 3, 186, 150, 218, 83, 236, 160, 43, + 215, 215, 125, 217, 151, 245, 61, 68, 118, 191, 53, 215, 209, 60, 223, 112, 207, 227, 182, 147, 99, 7, 252, + 222, 75, 222, 109, 28, 224, 156, 243, 0, 219, 192, 74, 203, 6, 146, 93, 99, 0, 63, 64, 60, 243, 173, 39, + 179, 237, 247, 230, 90, 66, 231, 179, 245, 125, 139, 246, 30, 53, 123, 12, 66, 57, 230, 219, 120, 95, 108, + 32, 69, 250, 175, 247, 72, 170, 13, 232, 156, 249, 0, 233, 111, 184, 227, 127, 247, 152, 114, 31, 232, 252, + 98, 146, 112, 255, 183, 101, 203, 40, 139, 243, 251, 207, 247, 237, 11, 41, 236, 231, 28, 4, 88, 246, 210, + 75, 62, 157, 214, 53, 132, 64, 99, 240, 158, 213, 127, 125, 151, 178, 174, 101, 232, 30, 53, 123, 110, 63, + 16, 247, 161, 200, 127, 186, 180, 81, 117, 192, 142, 5, 58, 63, 2, 125, 71, 60, 212, 119, 70, 235, 187, 69, + 109, 238, 237, 179, 203, 102, 79, 11, 215, 119, 59, 210, 210, 66, 146, 123, 5, 52, 96, 239, 167, 159, 82, + 218, 47, 127, 89, 68, 179, 96, 3, 154, 15, 66, 7, 198, 8, 207, 195, 165, 255, 195, 196, 246, 237, 249, 173, + 96, 126, 111, 143, 245, 146, 16, 132, 218, 128, 91, 7, 236, 249, 145, 9, 142, 255, 110, 129, 209, 78, 209, + 251, 36, 116, 173, 94, 231, 241, 13, 106, 212, 160, 237, 137, 137, 33, 205, 189, 34, 139, 115, 66, 216, + 233, 60, 110, 179, 125, 199, 142, 123, 158, 112, 188, 216, 193, 104, 199, 255, 78, 93, 251, 174, 222, 96, + 154, 31, 202, 220, 43, 255, 193, 108, 64, 247, 85, 232, 26, 90, 140, 227, 127, 151, 172, 125, 55, 185, 125, + 238, 12, 127, 223, 52, 106, 20, 101, 115, 174, 231, 53, 183, 165, 5, 114, 147, 53, 157, 58, 249, 180, 59, + 216, 61, 11, 83, 172, 254, 219, 239, 47, 45, 137, 251, 80, 230, 63, 152, 13, 104, 109, 108, 175, 169, 235, + 254, 107, 61, 87, 110, 223, 37, 161, 62, 179, 186, 85, 171, 66, 191, 231, 60, 203, 107, 94, 75, 139, 253, + 92, 143, 238, 221, 177, 131, 22, 212, 173, 91, 228, 238, 61, 181, 3, 251, 172, 189, 246, 223, 189, 87, 161, + 42, 105, 190, 141, 165, 1, 108, 97, 145, 244, 197, 189, 199, 198, 190, 139, 56, 208, 253, 116, 24, 167, + 205, 49, 49, 85, 66, 247, 139, 64, 106, 130, 180, 199, 31, 247, 205, 213, 186, 207, 90, 6, 235, 191, 189, + 158, 147, 30, 96, 108, 171, 10, 2, 217, 128, 106, 129, 189, 231, 206, 125, 214, 68, 199, 8, 99, 2, 223, 88, + 222, 188, 185, 89, 203, 241, 156, 211, 171, 244, 255, 221, 219, 182, 209, 236, 187, 238, 242, 173, 211, + 217, 123, 114, 3, 245, 223, 222, 183, 163, 220, 219, 254, 238, 53, 159, 229, 97, 3, 90, 27, 168, 45, 184, + 247, 142, 168, 109, 104, 237, 140, 124, 96, 238, 131, 15, 210, 231, 123, 247, 154, 121, 30, 175, 121, 45, + 45, 178, 14, 31, 166, 173, 201, 201, 190, 61, 26, 246, 121, 156, 180, 32, 125, 215, 53, 60, 55, 239, 85, + 149, 251, 64, 54, 224, 206, 13, 108, 216, 49, 2, 252, 67, 55, 245, 93, 163, 91, 22, 44, 48, 99, 234, 53, + 175, 165, 69, 14, 231, 127, 75, 187, 116, 49, 57, 190, 206, 221, 217, 107, 181, 193, 214, 206, 2, 197, 119, + 175, 249, 187, 90, 124, 224, 130, 109, 7, 37, 217, 133, 206, 27, 128, 127, 189, 143, 20, 245, 209, 130, + 102, 205, 204, 154, 174, 215, 188, 150, 74, 251, 161, 83, 28, 255, 167, 61, 252, 176, 225, 63, 206, 241, + 239, 211, 73, 43, 37, 207, 246, 191, 221, 227, 25, 234, 88, 86, 10, 4, 250, 220, 82, 25, 155, 52, 25, 43, + 240, 143, 154, 208, 236, 177, 188, 245, 86, 218, 177, 126, 189, 89, 219, 247, 154, 223, 146, 128, 181, 225, + 141, 115, 231, 154, 185, 157, 137, 194, 63, 252, 31, 250, 255, 190, 112, 127, 173, 227, 119, 189, 65, 249, + 95, 44, 252, 171, 255, 163, 38, 198, 188, 8, 214, 205, 230, 134, 133, 209, 193, 80, 215, 0, 172, 9, 114, + 156, 154, 254, 242, 203, 102, 62, 27, 243, 92, 208, 176, 217, 22, 255, 75, 126, 192, 60, 151, 164, 7, 110, + 255, 7, 255, 240, 127, 204, 139, 135, 223, 124, 51, 109, 74, 79, 55, 251, 248, 60, 231, 57, 8, 176, 111, + 112, 125, 82, 146, 89, 203, 26, 113, 131, 255, 171, 230, 95, 215, 143, 108, 253, 71, 12, 133, 150, 246, + 102, 68, 62, 241, 68, 225, 122, 27, 215, 87, 94, 115, 237, 6, 246, 132, 224, 207, 200, 71, 31, 245, 221, + 195, 62, 201, 145, 26, 198, 41, 172, 247, 22, 253, 0, 248, 95, 94, 6, 232, 103, 151, 200, 24, 45, 112, 252, + 245, 223, 36, 25, 75, 196, 0, 172, 149, 198, 181, 104, 65, 7, 243, 242, 66, 171, 30, 100, 155, 60, 196, 57, + 127, 98, 199, 142, 102, 15, 11, 214, 55, 177, 150, 19, 227, 20, 206, 237, 161, 254, 67, 93, 147, 110, 113, + 95, 150, 113, 186, 158, 129, 49, 209, 28, 16, 53, 192, 60, 199, 255, 62, 10, 212, 0, 136, 167, 216, 55, + 128, 61, 50, 201, 239, 190, 107, 246, 140, 133, 138, 13, 160, 45, 75, 199, 143, 55, 246, 169, 247, 241, 32, + 110, 33, 126, 97, 254, 7, 249, 12, 226, 154, 230, 126, 55, 248, 15, 204, 191, 198, 0, 119, 13, 128, 24, + 128, 120, 138, 125, 2, 221, 157, 194, 253, 83, 201, 17, 17, 116, 72, 246, 249, 122, 233, 247, 224, 126, + 249, 180, 105, 212, 169, 70, 13, 211, 54, 61, 155, 25, 40, 247, 183, 181, 223, 235, 241, 174, 40, 14, 175, + 229, 179, 26, 3, 48, 86, 208, 75, 157, 3, 134, 142, 66, 79, 245, 108, 153, 238, 33, 196, 62, 90, 228, 2, + 57, 30, 204, 13, 225, 185, 135, 89, 243, 211, 199, 142, 165, 246, 53, 107, 26, 223, 215, 115, 217, 88, 207, + 157, 226, 248, 231, 254, 208, 23, 196, 181, 165, 206, 181, 197, 201, 80, 71, 121, 240, 239, 158, 7, 64, + 238, 140, 28, 26, 185, 52, 252, 74, 207, 150, 97, 188, 113, 78, 100, 208, 83, 79, 209, 95, 51, 50, 140, 31, + 102, 85, 66, 94, 136, 252, 19, 251, 117, 247, 237, 217, 67, 211, 219, 180, 161, 150, 213, 170, 153, 115, + 26, 125, 156, 162, 119, 240, 6, 171, 251, 175, 87, 254, 181, 95, 43, 202, 8, 251, 123, 220, 121, 128, 190, + 151, 12, 115, 1, 129, 246, 147, 183, 169, 85, 139, 226, 187, 116, 161, 204, 79, 62, 49, 62, 137, 61, 213, + 229, 189, 94, 188, 159, 227, 204, 33, 236, 253, 63, 116, 136, 86, 36, 36, 80, 223, 95, 253, 202, 236, 217, + 237, 36, 109, 177, 207, 232, 216, 113, 127, 161, 244, 101, 169, 213, 199, 178, 142, 81, 168, 194, 182, 131, + 242, 248, 30, 248, 137, 198, 1, 173, 5, 116, 47, 181, 189, 143, 22, 227, 142, 88, 128, 115, 53, 56, 47, + 218, 233, 238, 187, 41, 14, 103, 123, 87, 175, 166, 28, 220, 255, 138, 51, 96, 252, 167, 201, 17, 174, 210, + 30, 204, 222, 94, 220, 187, 147, 155, 107, 108, 10, 254, 190, 44, 62, 158, 6, 61, 253, 180, 217, 167, 31, + 38, 246, 103, 159, 85, 65, 219, 98, 164, 173, 73, 78, 209, 154, 207, 246, 121, 175, 249, 170, 40, 254, 63, + 40, 71, 59, 210, 249, 64, 157, 15, 64, 28, 136, 119, 174, 220, 75, 13, 221, 213, 187, 185, 192, 9, 238, + 222, 8, 227, 120, 252, 222, 51, 207, 208, 28, 156, 235, 94, 188, 152, 118, 237, 220, 233, 59, 103, 1, 155, + 0, 224, 203, 224, 86, 129, 127, 251, 254, 15, 231, 128, 57, 150, 236, 220, 188, 153, 50, 18, 19, 105, 10, + 235, 124, 143, 251, 239, 55, 103, 56, 193, 125, 91, 231, 202, 179, 169, 122, 78, 41, 152, 238, 95, 239, + 220, 171, 110, 151, 247, 247, 105, 28, 80, 27, 112, 159, 43, 65, 190, 221, 215, 185, 242, 14, 22, 112, 133, + 251, 3, 222, 170, 94, 157, 58, 254, 252, 231, 20, 193, 126, 59, 182, 105, 83, 74, 232, 221, 155, 82, 70, + 140, 160, 244, 73, 147, 104, 9, 231, 237, 75, 166, 78, 165, 165, 252, 231, 162, 137, 19, 105, 222, 208, + 161, 20, 219, 181, 43, 69, 53, 104, 64, 253, 30, 123, 140, 218, 214, 169, 99, 116, 5, 247, 10, 66, 235, + 245, 174, 169, 110, 142, 255, 30, 105, 61, 155, 138, 121, 10, 61, 159, 229, 214, 253, 235, 213, 247, 221, + 92, 45, 46, 199, 239, 180, 227, 128, 189, 46, 168, 54, 0, 29, 64, 141, 141, 125, 179, 238, 59, 88, 16, 147, + 219, 11, 95, 45, 133, 187, 55, 197, 30, 26, 57, 133, 247, 131, 190, 33, 188, 42, 222, 144, 159, 55, 150, + 127, 195, 126, 144, 95, 226, 236, 178, 222, 53, 5, 159, 239, 233, 56, 190, 179, 10, 246, 189, 130, 246, + 217, 60, 205, 247, 181, 222, 187, 158, 185, 183, 121, 66, 206, 190, 178, 28, 144, 33, 192, 115, 108, 219, + 194, 247, 235, 217, 18, 221, 79, 141, 186, 192, 62, 87, 160, 247, 248, 67, 15, 16, 23, 96, 11, 250, 142, + 31, 240, 8, 155, 104, 45, 188, 218, 208, 119, 65, 225, 255, 219, 201, 239, 43, 231, 176, 41, 189, 107, 74, + 239, 142, 215, 123, 40, 144, 147, 216, 119, 49, 184, 253, 126, 133, 213, 159, 242, 24, 155, 80, 64, 134, 5, + 229, 63, 93, 184, 169, 200, 103, 104, 62, 96, 159, 49, 83, 45, 112, 223, 201, 20, 33, 124, 193, 22, 224, + 179, 221, 133, 199, 174, 194, 105, 231, 0, 232, 226, 248, 223, 9, 212, 67, 56, 71, 108, 193, 25, 13, 251, + 142, 49, 251, 78, 65, 189, 131, 5, 125, 215, 245, 125, 173, 243, 236, 62, 120, 205, 89, 69, 240, 175, 254, + 9, 223, 135, 230, 173, 120, 225, 133, 10, 123, 142, 219, 6, 116, 159, 144, 158, 173, 0, 23, 186, 175, 30, + 122, 128, 184, 128, 216, 60, 72, 184, 211, 243, 70, 253, 132, 83, 160, 143, 5, 253, 89, 127, 199, 127, 38, + 9, 26, 143, 57, 39, 216, 20, 252, 29, 57, 7, 106, 251, 169, 206, 149, 103, 115, 52, 215, 211, 58, 239, 122, + 244, 251, 64, 126, 137, 254, 26, 187, 191, 231, 30, 218, 179, 101, 75, 133, 63, 79, 99, 141, 230, 133, 122, + 198, 200, 62, 91, 0, 77, 134, 127, 234, 189, 141, 224, 78, 223, 243, 49, 84, 56, 181, 223, 253, 162, 127, + 119, 191, 227, 54, 74, 56, 71, 140, 153, 108, 241, 174, 103, 147, 244, 44, 174, 238, 209, 214, 88, 255, 67, + 226, 30, 125, 79, 189, 249, 102, 250, 116, 222, 60, 202, 226, 186, 105, 53, 255, 187, 60, 177, 202, 130, + 182, 193, 206, 11, 116, 174, 16, 62, 104, 159, 185, 212, 59, 251, 244, 156, 5, 236, 1, 190, 11, 125, 128, + 93, 140, 117, 97, 156, 96, 188, 19, 248, 93, 151, 246, 254, 124, 141, 243, 238, 28, 79, 249, 182, 219, 92, + 222, 227, 225, 21, 236, 62, 41, 255, 75, 100, 28, 54, 13, 28, 72, 89, 71, 143, 154, 121, 147, 202, 120, + 254, 74, 171, 13, 182, 29, 104, 92, 208, 179, 38, 246, 187, 45, 19, 132, 199, 56, 231, 202, 247, 27, 2, + 177, 214, 255, 217, 239, 188, 179, 239, 147, 179, 207, 100, 252, 80, 120, 119, 143, 63, 250, 185, 66, 250, + 142, 177, 248, 176, 97, 67, 58, 128, 245, 23, 89, 139, 173, 44, 27, 12, 102, 7, 238, 243, 38, 122, 55, 139, + 251, 204, 5, 120, 157, 109, 97, 142, 245, 127, 246, 59, 175, 2, 157, 199, 208, 252, 78, 117, 222, 221, 46, + 175, 185, 170, 200, 113, 87, 237, 197, 120, 44, 251, 237, 111, 105, 223, 174, 93, 230, 220, 179, 206, 155, + 86, 118, 123, 220, 113, 65, 115, 4, 181, 5, 221, 91, 174, 123, 238, 245, 140, 129, 218, 134, 194, 190, 47, + 221, 189, 31, 95, 247, 227, 234, 60, 142, 242, 238, 246, 249, 235, 157, 251, 12, 25, 3, 179, 95, 253, 206, + 59, 41, 115, 205, 154, 66, 223, 183, 230, 205, 189, 106, 155, 109, 7, 182, 45, 232, 190, 2, 123, 207, 121, + 113, 231, 215, 221, 123, 175, 75, 195, 249, 245, 200, 123, 32, 238, 53, 230, 167, 221, 116, 19, 109, 143, + 143, 15, 120, 46, 111, 77, 53, 167, 82, 177, 58, 0, 86, 89, 88, 41, 200, 96, 172, 112, 97, 185, 5, 251, + 231, 25, 2, 253, 172, 126, 87, 160, 103, 85, 118, 127, 189, 24, 215, 85, 50, 46, 26, 243, 63, 238, 215, + 207, 151, 239, 93, 193, 127, 117, 199, 115, 172, 46, 6, 171, 74, 129, 226, 62, 239, 117, 223, 42, 123, 12, + 49, 30, 25, 140, 101, 213, 11, 99, 226, 218, 198, 141, 138, 228, 123, 161, 200, 255, 13, 148, 47, 247, 203, + 171, 23, 230, 66, 43, 158, 252, 29, 237, 219, 179, 151, 246, 103, 101, 7, 91, 55, 255, 127, 164, 3, 204, + 79, 69, 244, 185, 170, 0, 0, 20, 197, 109, 107, 66, 84, 250, 206, 202, 254, 0, 127, 67, 165, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 157, 125, + 84, 85, 85, 250, 199, 239, 13, 146, 171, 8, 26, 164, 65, 132, 233, 224, 164, 49, 152, 111, 121, 125, 1, + 132, 52, 11, 95, 162, 145, 108, 66, 29, 197, 52, 52, 75, 194, 84, 80, 52, 72, 32, 240, 61, 231, 71, 43, + 151, 147, 105, 57, 214, 207, 65, 166, 86, 90, 218, 76, 56, 171, 161, 44, 38, 109, 108, 230, 167, 137, 149, + 138, 74, 190, 100, 42, 134, 32, 47, 42, 251, 183, 159, 205, 126, 96, 115, 60, 247, 114, 245, 156, 59, 231, + 156, 123, 239, 94, 235, 251, 207, 69, 93, 120, 62, 231, 217, 251, 121, 190, 251, 217, 251, 154, 8, 33, 38, + 173, 117, 234, 212, 41, 147, 175, 175, 175, 9, 134, 217, 108, 118, 72, 58, 27, 102, 97, 220, 70, 229, 37, + 252, 142, 3, 99, 98, 98, 254, 82, 90, 90, 122, 157, 232, 111, 104, 206, 158, 24, 155, 191, 28, 119, 252, + 229, 194, 163, 162, 162, 222, 254, 228, 147, 79, 234, 157, 78, 241, 214, 135, 230, 236, 137, 49, 249, 219, + 227, 222, 195, 106, 181, 190, 182, 125, 251, 246, 234, 198, 198, 70, 167, 3, 84, 50, 202, 203, 202, 52, + 103, 79, 140, 197, 223, 30, 247, 224, 158, 61, 123, 230, 111, 216, 176, 161, 242, 218, 181, 107, 78, 103, + 167, 100, 156, 42, 47, 39, 43, 158, 125, 150, 12, 243, 241, 209, 156, 61, 49, 14, 127, 41, 247, 219, 248, + 231, 129, 247, 222, 123, 239, 226, 117, 235, 214, 157, 173, 169, 169, 113, 58, 59, 37, 227, 194, 217, 179, + 164, 96, 193, 2, 18, 235, 239, 79, 250, 152, 76, 100, 40, 253, 229, 137, 135, 191, 35, 204, 229, 184, 251, + 5, 7, 7, 167, 172, 89, 179, 230, 120, 85, 85, 149, 211, 217, 41, 25, 191, 92, 188, 72, 54, 230, 228, 144, + 81, 129, 129, 36, 130, 34, 31, 66, 53, 156, 42, 214, 195, 223, 17, 246, 82, 238, 150, 78, 157, 58, 77, 91, + 176, 96, 65, 217, 153, 51, 103, 156, 206, 78, 201, 168, 165, 243, 209, 214, 181, 107, 201, 184, 187, 239, + 102, 220, 173, 84, 209, 77, 220, 201, 8, 170, 81, 30, 254, 142, 112, 247, 226, 159, 223, 222, 177, 99, 199, + 9, 169, 169, 169, 251, 43, 42, 42, 156, 206, 78, 201, 168, 175, 171, 35, 59, 54, 110, 36, 9, 97, 97, 108, + 158, 31, 196, 185, 199, 180, 112, 39, 113, 84, 99, 61, 252, 111, 128, 206, 135, 200, 253, 54, 47, 47, 175, + 209, 201, 201, 201, 159, 29, 61, 122, 212, 233, 236, 148, 140, 235, 215, 175, 147, 226, 194, 66, 50, 41, + 34, 130, 113, 127, 144, 42, 74, 194, 253, 209, 38, 238, 36, 158, 106, 188, 135, 191, 20, 189, 200, 221, 68, + 185, 71, 143, 31, 63, 254, 175, 251, 246, 237, 211, 119, 33, 71, 199, 23, 59, 119, 146, 233, 131, 7, 147, + 190, 20, 233, 64, 25, 238, 113, 2, 247, 4, 170, 39, 169, 18, 221, 155, 255, 13, 185, 157, 240, 179, 129, + 163, 71, 143, 214, 171, 103, 215, 106, 236, 47, 41, 33, 115, 70, 140, 32, 3, 40, 202, 1, 194, 250, 62, 146, + 234, 17, 206, 125, 28, 213, 227, 2, 247, 137, 84, 191, 167, 74, 114, 79, 254, 114, 57, 61, 254, 44, 124, + 200, 144, 33, 111, 151, 148, 148, 212, 57, 29, 156, 194, 81, 246, 245, 215, 36, 237, 177, 199, 200, 131, + 102, 51, 233, 239, 96, 188, 35, 247, 169, 84, 79, 83, 61, 227, 102, 252, 101, 226, 29, 255, 161, 95, 245, + 235, 215, 239, 181, 162, 162, 162, 26, 189, 123, 55, 229, 101, 101, 36, 107, 226, 68, 50, 196, 219, 155, + 205, 245, 145, 173, 243, 249, 86, 235, 187, 48, 207, 147, 201, 77, 241, 142, 220, 201, 76, 170, 103, 221, + 131, 191, 92, 188, 55, 123, 118, 225, 225, 225, 249, 239, 188, 243, 78, 101, 67, 67, 131, 211, 217, 41, 25, + 167, 142, 29, 35, 43, 102, 205, 34, 81, 22, 11, 227, 62, 140, 199, 251, 67, 242, 121, 29, 153, 32, 112, + 199, 120, 159, 209, 194, 157, 204, 166, 122, 222, 181, 249, 203, 113, 199, 26, 62, 32, 40, 40, 40, 3, 60, + 187, 250, 122, 61, 111, 207, 8, 158, 157, 159, 31, 121, 64, 194, 253, 97, 129, 251, 99, 14, 114, 127, 142, + 106, 14, 85, 10, 213, 11, 174, 203, 223, 22, 247, 142, 93, 187, 118, 157, 147, 159, 159, 95, 126, 241, 226, + 69, 167, 179, 83, 50, 170, 184, 103, 247, 72, 64, 0, 122, 181, 55, 112, 31, 35, 225, 254, 20, 213, 36, 9, + 247, 228, 214, 241, 206, 184, 115, 246, 36, 213, 181, 248, 219, 139, 247, 246, 129, 129, 129, 73, 89, 89, + 89, 101, 231, 207, 159, 119, 58, 59, 37, 163, 182, 186, 154, 108, 125, 245, 85, 242, 88, 72, 8, 227, 142, + 94, 173, 200, 125, 52, 231, 254, 91, 170, 39, 4, 238, 83, 168, 166, 81, 77, 231, 220, 103, 73, 184, 115, + 230, 76, 115, 155, 164, 57, 123, 162, 14, 127, 91, 220, 189, 125, 124, 124, 38, 204, 156, 57, 115, 191, + 222, 189, 90, 244, 236, 158, 8, 11, 99, 243, 188, 85, 224, 142, 181, 28, 114, 127, 252, 38, 184, 207, 145, + 176, 7, 238, 47, 182, 72, 115, 246, 68, 25, 127, 145, 187, 88, 195, 155, 41, 247, 184, 105, 211, 166, 125, + 246, 221, 119, 223, 57, 157, 157, 146, 1, 158, 221, 238, 194, 66, 50, 57, 34, 130, 113, 31, 100, 106, 222, + 155, 105, 197, 125, 156, 132, 251, 68, 206, 61, 233, 38, 184, 75, 216, 27, 153, 255, 13, 220, 241, 157, + 240, 246, 246, 142, 78, 76, 76, 252, 248, 192, 129, 3, 78, 103, 167, 116, 128, 103, 55, 195, 106, 37, 253, + 76, 77, 158, 157, 212, 187, 145, 114, 255, 157, 169, 149, 119, 195, 184, 11, 181, 156, 52, 183, 179, 199, + 221, 168, 252, 109, 197, 59, 140, 129, 177, 177, 177, 69, 159, 127, 254, 185, 238, 61, 187, 111, 74, 74, + 72, 202, 136, 17, 140, 57, 114, 151, 155, 231, 127, 43, 112, 23, 231, 121, 49, 175, 19, 153, 75, 231, 247, + 121, 92, 243, 109, 75, 115, 246, 196, 49, 254, 114, 185, 29, 114, 191, 63, 58, 58, 250, 237, 226, 226, 98, + 221, 123, 118, 135, 255, 245, 47, 146, 30, 31, 79, 172, 102, 115, 179, 87, 139, 220, 229, 242, 58, 57, 238, + 114, 177, 46, 114, 119, 128, 185, 145, 248, 203, 113, 111, 246, 236, 172, 86, 107, 193, 142, 29, 59, 244, + 221, 116, 67, 154, 60, 187, 165, 147, 39, 147, 161, 94, 94, 204, 171, 149, 139, 119, 233, 60, 223, 86, 188, + 75, 243, 185, 155, 228, 174, 119, 254, 246, 184, 99, 159, 221, 69, 189, 123, 118, 167, 143, 31, 39, 43, + 103, 205, 34, 209, 22, 11, 91, 227, 209, 171, 149, 219, 155, 145, 174, 239, 98, 62, 175, 98, 188, 27, 129, + 191, 148, 187, 55, 71, 31, 208, 189, 123, 119, 230, 217, 213, 214, 214, 58, 157, 157, 146, 113, 158, 214, + 154, 175, 167, 167, 147, 145, 126, 126, 205, 220, 177, 126, 151, 174, 239, 232, 219, 76, 230, 241, 142, + 190, 141, 180, 118, 151, 50, 7, 126, 11, 184, 210, 110, 93, 154, 179, 39, 173, 249, 75, 217, 67, 126, 215, + 222, 98, 177, 60, 191, 122, 245, 106, 221, 247, 217, 85, 85, 86, 146, 77, 57, 57, 36, 46, 48, 176, 21, 119, + 185, 188, 78, 206, 175, 123, 70, 224, 46, 55, 199, 171, 196, 92, 175, 252, 205, 156, 63, 178, 191, 221, + 220, 228, 227, 252, 58, 44, 44, 236, 178, 158, 231, 122, 240, 236, 10, 215, 174, 37, 241, 33, 33, 205, 123, + 51, 55, 187, 190, 207, 180, 19, 239, 56, 95, 171, 204, 94, 175, 252, 145, 189, 133, 202, 135, 126, 22, 218, + 163, 71, 143, 31, 235, 234, 244, 151, 222, 55, 212, 215, 147, 15, 55, 109, 34, 79, 134, 133, 177, 120, 7, + 175, 182, 173, 245, 221, 86, 62, 47, 122, 180, 78, 152, 231, 141, 194, 255, 54, 190, 222, 251, 80, 249, 82, + 249, 209, 207, 186, 250, 251, 251, 31, 58, 113, 226, 132, 211, 121, 58, 58, 26, 175, 95, 39, 127, 223, 182, + 141, 76, 233, 211, 135, 113, 31, 44, 112, 199, 222, 11, 185, 188, 206, 30, 119, 39, 173, 239, 70, 228, 15, + 177, 223, 158, 202, 159, 42, 16, 248, 83, 125, 249, 213, 87, 95, 57, 157, 171, 35, 163, 116, 215, 46, 146, + 108, 181, 178, 250, 221, 42, 225, 14, 243, 252, 88, 7, 226, 93, 110, 158, 23, 153, 35, 159, 116, 231, 75, + 115, 246, 164, 53, 127, 47, 30, 251, 29, 169, 2, 168, 130, 233, 103, 119, 83, 237, 44, 41, 41, 113, 58, 91, + 123, 3, 60, 187, 212, 145, 35, 89, 79, 45, 120, 244, 49, 54, 184, 39, 24, 131, 187, 30, 249, 67, 174, 231, + 205, 215, 125, 136, 253, 46, 84, 221, 168, 66, 233, 231, 239, 208, 122, 223, 233, 140, 229, 6, 120, 118, + 11, 227, 227, 201, 96, 179, 153, 121, 181, 114, 61, 118, 114, 189, 149, 88, 191, 219, 154, 231, 53, 230, + 174, 87, 254, 48, 247, 119, 160, 234, 76, 21, 68, 245, 43, 16, 253, 252, 245, 220, 220, 92, 167, 179, 22, + 71, 249, 161, 67, 36, 123, 242, 100, 50, 204, 219, 155, 113, 31, 46, 195, 29, 123, 173, 176, 199, 78, 220, + 151, 65, 223, 198, 17, 238, 26, 177, 215, 51, 255, 59, 168, 238, 166, 250, 53, 85, 111, 250, 121, 126, 90, + 90, 154, 211, 153, 195, 56, 195, 61, 187, 24, 139, 133, 173, 241, 114, 220, 109, 244, 82, 219, 204, 235, + 164, 57, 157, 200, 123, 161, 182, 210, 156, 61, 185, 145, 191, 47, 95, 251, 67, 168, 122, 81, 69, 208, 207, + 23, 38, 36, 36, 56, 149, 251, 5, 240, 236, 232, 59, 6, 158, 29, 122, 244, 142, 198, 187, 61, 238, 114, 115, + 188, 198, 204, 245, 204, 191, 157, 192, 255, 30, 136, 125, 42, 90, 98, 153, 102, 71, 69, 69, 57, 133, 251, + 229, 202, 74, 242, 86, 78, 14, 25, 205, 61, 187, 40, 206, 93, 236, 177, 187, 217, 121, 94, 140, 119, 233, + 220, 174, 3, 230, 122, 230, 143, 241, 31, 8, 121, 31, 213, 253, 84, 116, 26, 54, 77, 233, 219, 183, 111, + 173, 154, 189, 249, 112, 54, 22, 60, 187, 199, 67, 66, 24, 247, 97, 50, 220, 177, 183, 82, 228, 62, 213, 6, + 247, 23, 76, 182, 231, 121, 29, 112, 54, 26, 255, 0, 129, 63, 45, 185, 76, 227, 3, 2, 2, 42, 207, 157, 59, + 167, 26, 255, 143, 54, 109, 34, 52, 177, 96, 158, 157, 173, 61, 120, 113, 111, 6, 185, 63, 99, 106, 217, + 143, 179, 151, 215, 233, 52, 222, 141, 192, 191, 131, 100, 254, 7, 254, 113, 237, 219, 183, 63, 81, 94, 94, + 174, 26, 255, 61, 219, 183, 51, 223, 14, 98, 94, 110, 111, 70, 60, 51, 99, 111, 158, 183, 23, 235, 139, + 244, 47, 205, 217, 11, 252, 205, 188, 254, 199, 252, 31, 243, 63, 224, 31, 75, 245, 159, 189, 123, 247, + 170, 198, 255, 240, 215, 95, 55, 251, 244, 162, 103, 39, 141, 119, 113, 255, 221, 17, 238, 58, 96, 106, + 116, 254, 237, 121, 253, 143, 245, 223, 64, 42, 186, 60, 155, 74, 138, 138, 138, 84, 227, 127, 238, 228, + 73, 18, 223, 161, 3, 139, 123, 136, 121, 172, 229, 112, 15, 222, 22, 247, 121, 174, 193, 93, 207, 252, 45, + 156, 127, 48, 85, 79, 170, 254, 84, 67, 232, 207, 222, 223, 184, 113, 163, 106, 252, 171, 47, 93, 34, 73, + 247, 220, 195, 246, 105, 126, 103, 106, 153, 235, 177, 247, 194, 197, 185, 235, 149, 191, 23, 231, 223, + 137, 251, 127, 97, 80, 255, 81, 13, 162, 63, 251, 99, 70, 70, 134, 106, 252, 97, 204, 237, 223, 159, 213, + 118, 224, 213, 131, 95, 139, 185, 29, 246, 94, 136, 121, 157, 65, 215, 119, 35, 242, 247, 225, 254, 255, + 93, 220, 255, 125, 128, 231, 0, 249, 83, 167, 78, 85, 149, 127, 238, 163, 143, 178, 250, 46, 137, 179, 199, + 152, 159, 107, 106, 89, 223, 165, 177, 158, 225, 90, 210, 156, 189, 13, 254, 126, 84, 93, 169, 186, 83, + 245, 225, 241, 191, 96, 220, 184, 113, 170, 242, 127, 35, 57, 153, 229, 250, 192, 126, 54, 143, 249, 121, + 2, 115, 120, 70, 139, 185, 150, 184, 160, 22, 235, 139, 191, 137, 239, 255, 183, 227, 251, 191, 176, 255, + 119, 47, 213, 111, 56, 255, 233, 189, 123, 247, 190, 170, 166, 7, 244, 126, 118, 54, 91, 251, 193, 187, + 133, 57, 255, 69, 30, 243, 238, 192, 222, 0, 252, 239, 228, 251, 191, 225, 156, 255, 147, 161, 161, 161, + 149, 106, 246, 128, 150, 108, 218, 196, 114, 126, 88, 243, 83, 132, 216, 95, 228, 226, 220, 117, 206, 95, + 234, 1, 247, 230, 252, 227, 44, 22, 203, 137, 239, 191, 255, 94, 53, 254, 7, 119, 239, 102, 245, 30, 240, + 135, 185, 127, 62, 231, 159, 161, 3, 54, 255, 13, 233, 108, 253, 71, 254, 232, 1, 137, 123, 128, 131, 184, + 7, 244, 239, 210, 210, 82, 213, 248, 87, 28, 56, 64, 158, 241, 246, 102, 245, 158, 135, 191, 46, 248, 155, + 57, 255, 246, 66, 15, 192, 125, 224, 1, 209, 159, 69, 82, 21, 191, 247, 222, 123, 170, 241, 175, 250, 249, + 103, 146, 114, 231, 157, 204, 235, 17, 115, 63, 119, 224, 191, 88, 255, 252, 209, 3, 2, 15, 112, 0, 213, + 96, 250, 243, 173, 203, 150, 45, 83, 141, 255, 181, 171, 87, 73, 70, 175, 94, 204, 231, 21, 215, 127, 15, + 127, 77, 249, 219, 242, 128, 172, 244, 231, 127, 152, 63, 127, 190, 106, 252, 97, 172, 124, 248, 97, 86, + 255, 35, 127, 240, 121, 220, 33, 255, 51, 0, 127, 209, 3, 234, 203, 249, 47, 25, 51, 102, 140, 170, 252, + 55, 36, 37, 177, 28, 16, 235, 63, 15, 127, 205, 249, 99, 13, 40, 245, 128, 128, 255, 236, 161, 67, 135, + 170, 122, 191, 195, 7, 217, 217, 55, 240, 199, 249, 255, 37, 23, 22, 127, 7, 52, 103, 47, 225, 111, 18, + 248, 163, 7, 128, 30, 16, 172, 255, 137, 33, 33, 33, 151, 47, 93, 186, 164, 26, 255, 47, 54, 111, 102, 125, + 61, 207, 187, 25, 255, 151, 244, 207, 95, 218, 7, 6, 241, 63, 150, 254, 185, 10, 53, 207, 130, 29, 250, + 244, 83, 182, 223, 11, 222, 63, 248, 254, 224, 255, 225, 252, 175, 53, 31, 55, 230, 47, 122, 64, 216, 7, 4, + 252, 31, 2, 15, 96, 207, 158, 61, 170, 241, 63, 251, 195, 15, 100, 86, 187, 118, 204, 3, 242, 240, 215, 5, + 127, 51, 231, 47, 122, 64, 224, 1, 60, 72, 21, 73, 255, 200, 238, 194, 194, 66, 213, 248, 215, 84, 86, 146, + 121, 33, 33, 204, 3, 128, 189, 126, 240, 128, 22, 122, 248, 107, 205, 223, 150, 7, 0, 125, 32, 127, 90, + 190, 124, 185, 106, 252, 97, 228, 14, 28, 200, 248, 67, 252, 227, 250, 15, 207, 39, 203, 197, 149, 169, 95, + 254, 182, 60, 0, 200, 1, 87, 207, 152, 49, 67, 85, 254, 235, 18, 18, 152, 7, 4, 249, 95, 58, 143, 253, 76, + 254, 140, 94, 118, 97, 101, 233, 155, 191, 180, 15, 164, 47, 231, 159, 166, 182, 7, 80, 148, 158, 206, 60, + 160, 84, 153, 248, 215, 154, 145, 155, 243, 7, 15, 160, 139, 224, 1, 0, 255, 233, 247, 221, 119, 95, 253, + 213, 171, 87, 85, 227, 255, 143, 245, 235, 201, 52, 206, 127, 129, 27, 241, 127, 89, 191, 252, 237, 121, 0, + 9, 93, 186, 116, 249, 137, 14, 213, 248, 31, 218, 189, 155, 245, 125, 190, 32, 137, 127, 120, 70, 75, 93, + 91, 154, 179, 151, 225, 47, 173, 1, 239, 228, 30, 64, 56, 231, 255, 8, 213, 119, 251, 247, 239, 87, 141, + 255, 233, 178, 50, 242, 28, 173, 1, 231, 72, 226, 223, 195, 95, 115, 254, 226, 89, 32, 236, 3, 24, 78, 85, + 242, 209, 71, 31, 169, 198, 255, 202, 47, 191, 144, 180, 224, 96, 214, 3, 8, 245, 31, 212, 255, 224, 255, + 101, 105, 207, 199, 93, 249, 99, 13, 40, 222, 5, 128, 30, 0, 124, 109, 241, 182, 85, 171, 86, 169, 198, 31, + 70, 190, 213, 202, 250, 0, 177, 254, 247, 240, 215, 5, 127, 209, 3, 232, 41, 120, 0, 107, 83, 82, 82, 84, + 229, 255, 198, 83, 79, 177, 28, 224, 69, 83, 139, 255, 3, 53, 160, 139, 175, 1, 154, 179, 183, 195, 95, + 206, 3, 232, 203, 249, 47, 28, 57, 114, 164, 170, 252, 63, 200, 204, 100, 30, 192, 60, 153, 248, 207, 118, + 93, 105, 206, 190, 13, 254, 88, 3, 130, 7, 208, 131, 215, 128, 48, 255, 79, 143, 136, 136, 168, 83, 179, 6, + 44, 221, 178, 165, 85, 252, 75, 249, 231, 184, 160, 116, 206, 95, 236, 3, 192, 179, 0, 17, 60, 254, 199, + 251, 251, 251, 255, 116, 250, 244, 105, 213, 248, 31, 249, 242, 75, 182, 7, 4, 30, 0, 122, 128, 30, 254, + 154, 241, 151, 238, 3, 139, 103, 1, 128, 63, 124, 117, 253, 65, 53, 239, 132, 188, 248, 227, 143, 100, 174, + 159, 31, 235, 3, 75, 115, 3, 254, 58, 159, 255, 237, 238, 3, 83, 69, 211, 63, 186, 123, 219, 182, 109, 170, + 241, 191, 214, 208, 64, 94, 190, 255, 126, 86, 3, 162, 7, 144, 233, 225, 175, 37, 127, 105, 13, 40, 238, 3, + 195, 125, 0, 155, 179, 179, 179, 85, 227, 15, 163, 32, 46, 142, 157, 5, 144, 242, 135, 231, 149, 235, 98, + 226, 239, 129, 230, 236, 29, 224, 47, 87, 3, 66, 14, 184, 44, 41, 41, 73, 85, 254, 133, 169, 169, 236, 44, + 168, 187, 240, 55, 64, 252, 219, 218, 7, 6, 254, 41, 86, 171, 85, 85, 254, 255, 88, 183, 142, 241, 71, 15, + 16, 61, 96, 156, 51, 181, 102, 230, 166, 252, 197, 243, 224, 98, 13, 56, 169, 91, 183, 110, 151, 212, 60, + 15, 122, 248, 211, 79, 217, 252, 143, 53, 32, 242, 199, 245, 95, 107, 102, 106, 243, 215, 177, 255, 35, + 183, 15, 40, 158, 7, 7, 254, 99, 188, 188, 188, 142, 125, 251, 237, 183, 170, 241, 255, 185, 188, 156, 204, + 245, 245, 101, 53, 160, 232, 1, 184, 26, 127, 156, 207, 12, 196, 95, 236, 5, 198, 26, 16, 122, 65, 247, + 236, 218, 181, 75, 53, 254, 13, 117, 117, 36, 43, 44, 140, 237, 3, 138, 30, 128, 43, 242, 135, 255, 147, + 78, 247, 255, 229, 106, 64, 233, 157, 128, 131, 204, 77, 189, 160, 219, 214, 172, 89, 163, 26, 127, 24, + 175, 241, 26, 0, 61, 128, 76, 15, 127, 45, 249, 75, 107, 128, 230, 243, 192, 188, 6, 92, 157, 156, 156, + 172, 42, 255, 194, 185, 115, 89, 47, 168, 43, 215, 0, 200, 95, 167, 253, 95, 109, 213, 0, 120, 39, 28, 240, + 159, 23, 27, 27, 171, 42, 255, 61, 111, 190, 121, 67, 13, 32, 122, 64, 90, 179, 115, 83, 254, 114, 189, + 160, 192, 255, 247, 161, 161, 161, 213, 106, 214, 0, 63, 236, 217, 195, 60, 192, 121, 156, 191, 52, 254, + 95, 113, 1, 225, 59, 96, 16, 254, 210, 125, 32, 232, 5, 141, 224, 252, 199, 250, 248, 248, 28, 61, 124, + 248, 176, 106, 252, 43, 79, 157, 34, 105, 157, 58, 177, 26, 16, 243, 191, 28, 254, 220, 242, 168, 242, 93, + 64, 121, 252, 29, 208, 121, 254, 47, 221, 7, 146, 222, 9, 53, 132, 10, 106, 128, 47, 118, 236, 216, 161, + 26, 127, 248, 110, 183, 188, 136, 8, 182, 15, 148, 97, 106, 201, 255, 61, 252, 53, 229, 47, 222, 11, 47, + 238, 3, 69, 209, 191, 178, 85, 237, 94, 176, 13, 19, 38, 176, 243, 160, 224, 1, 96, 254, 159, 235, 34, 252, + 243, 76, 45, 107, 128, 1, 242, 255, 182, 122, 1, 97, 13, 88, 241, 244, 211, 79, 171, 202, 127, 231, 210, + 165, 172, 6, 68, 15, 112, 169, 11, 242, 207, 49, 30, 127, 185, 26, 0, 60, 128, 23, 6, 13, 26, 164, 42, 255, + 111, 222, 127, 159, 245, 130, 128, 7, 176, 164, 233, 57, 53, 243, 55, 250, 59, 32, 242, 55, 64, 254, 215, + 86, 13, 0, 252, 19, 131, 131, 131, 47, 92, 56, 127, 190, 9, 94, 99, 163, 50, 209, 113, 234, 224, 65, 146, + 122, 251, 237, 172, 6, 92, 108, 106, 217, 3, 114, 133, 28, 192, 224, 252, 229, 106, 128, 209, 84, 101, 120, + 30, 164, 145, 50, 84, 34, 24, 181, 151, 47, 147, 204, 208, 80, 118, 30, 216, 213, 114, 64, 228, 15, 255, + 31, 157, 158, 255, 181, 87, 3, 202, 213, 0, 177, 208, 11, 180, 101, 203, 22, 213, 248, 195, 40, 24, 49, + 130, 221, 9, 131, 30, 128, 43, 241, 207, 53, 22, 127, 71, 106, 128, 55, 22, 47, 94, 220, 196, 159, 214, + 111, 74, 5, 163, 40, 53, 149, 229, 0, 88, 3, 184, 74, 14, 40, 212, 126, 144, 219, 106, 206, 222, 65, 254, + 152, 3, 138, 247, 130, 226, 119, 195, 64, 14, 240, 18, 158, 9, 135, 24, 190, 78, 25, 42, 17, 140, 210, 183, + 222, 98, 62, 32, 198, 127, 14, 127, 118, 203, 184, 150, 27, 80, 248, 187, 231, 241, 255, 143, 129, 226, 31, + 115, 0, 105, 47, 80, 127, 30, 255, 211, 123, 246, 236, 89, 91, 83, 83, 195, 216, 169, 193, 255, 248, 190, + 125, 205, 189, 224, 226, 252, 111, 116, 254, 249, 166, 150, 245, 223, 96, 241, 47, 214, 0, 216, 11, 244, 0, + 143, 255, 199, 59, 116, 232, 112, 226, 200, 145, 35, 170, 241, 175, 58, 119, 142, 44, 185, 235, 46, 182, + 15, 176, 132, 207, 151, 175, 240, 231, 231, 10, 252, 13, 56, 255, 219, 234, 5, 130, 26, 96, 36, 85, 41, + 158, 9, 134, 239, 136, 80, 34, 124, 7, 214, 70, 70, 178, 59, 1, 176, 6, 204, 117, 17, 254, 220, 251, 211, + 235, 253, 79, 142, 228, 128, 226, 189, 128, 131, 205, 77, 231, 1, 182, 226, 189, 80, 74, 249, 227, 119, + 140, 20, 206, 158, 205, 106, 128, 12, 83, 107, 15, 200, 195, 95, 83, 254, 55, 124, 55, 0, 231, 159, 55, + 105, 210, 164, 230, 249, 95, 13, 254, 95, 108, 216, 192, 122, 193, 48, 254, 113, 253, 95, 193, 181, 210, + 64, 194, 223, 121, 153, 169, 101, 254, 55, 24, 127, 177, 6, 144, 222, 11, 7, 57, 224, 236, 62, 125, 250, + 92, 109, 104, 104, 96, 252, 225, 108, 168, 18, 193, 56, 90, 90, 202, 60, 160, 69, 166, 214, 243, 255, 114, + 131, 243, 199, 248, 215, 225, 253, 207, 109, 241, 183, 117, 55, 56, 240, 127, 194, 223, 223, 255, 236, 241, + 227, 199, 25, 59, 165, 252, 193, 9, 130, 239, 135, 200, 12, 10, 98, 189, 96, 216, 7, 96, 100, 254, 203, 77, + 45, 243, 63, 252, 127, 210, 141, 201, 95, 238, 251, 225, 160, 6, 128, 51, 161, 123, 139, 139, 139, 85, 225, + 15, 107, 0, 188, 3, 5, 195, 135, 179, 57, 0, 246, 1, 161, 102, 202, 115, 1, 254, 220, 251, 135, 253, 13, + 205, 217, 223, 36, 127, 123, 62, 112, 12, 253, 235, 133, 43, 87, 174, 100, 252, 97, 29, 80, 42, 24, 127, + 73, 77, 101, 189, 32, 34, 127, 100, 191, 202, 64, 194, 119, 0, 231, 127, 224, 255, 162, 177, 248, 219, 242, + 129, 197, 28, 112, 121, 98, 98, 162, 170, 252, 255, 185, 121, 51, 227, 143, 30, 0, 198, 63, 198, 149, 214, + 92, 111, 150, 191, 56, 255, 235, 236, 251, 95, 29, 225, 47, 205, 1, 69, 31, 24, 238, 5, 123, 174, 95, 191, + 126, 87, 235, 235, 235, 217, 252, 173, 6, 255, 147, 223, 124, 67, 230, 155, 205, 205, 57, 32, 214, 0, 70, + 230, 207, 123, 63, 224, 157, 214, 156, 253, 45, 240, 183, 117, 38, 20, 226, 127, 2, 205, 1, 79, 99, 14, + 216, 64, 223, 3, 37, 186, 70, 235, 8, 248, 158, 240, 156, 238, 221, 89, 47, 72, 22, 143, 29, 172, 1, 141, + 202, 223, 128, 251, 63, 246, 114, 192, 30, 60, 7, 140, 194, 28, 16, 207, 132, 193, 60, 160, 68, 48, 7, 64, + 14, 184, 126, 236, 88, 150, 3, 226, 62, 80, 190, 129, 249, 99, 253, 111, 176, 253, 95, 71, 114, 192, 161, + 60, 7, 220, 154, 159, 159, 175, 10, 127, 16, 140, 157, 89, 89, 204, 7, 126, 73, 194, 31, 158, 235, 106, 3, + 72, 124, 7, 32, 119, 17, 122, 0, 52, 103, 127, 147, 252, 219, 234, 5, 128, 28, 224, 149, 39, 39, 76, 104, + 158, 255, 235, 235, 234, 20, 9, 198, 255, 109, 223, 206, 246, 2, 151, 240, 184, 17, 249, 27, 233, 29, 16, + 231, 0, 254, 14, 104, 206, 254, 22, 248, 139, 57, 160, 180, 23, 0, 248, 207, 236, 213, 171, 87, 93, 117, + 117, 53, 171, 227, 235, 40, 67, 37, 186, 214, 216, 72, 126, 58, 114, 132, 100, 248, 250, 178, 28, 80, 90, + 3, 24, 145, 63, 238, 5, 228, 25, 151, 191, 173, 28, 16, 248, 143, 111, 215, 174, 221, 137, 131, 7, 15, 178, + 216, 85, 202, 191, 158, 230, 0, 176, 14, 172, 30, 48, 128, 249, 128, 210, 26, 192, 8, 252, 229, 242, 0, + 254, 14, 104, 206, 94, 1, 127, 57, 31, 16, 114, 192, 135, 169, 62, 195, 187, 193, 234, 106, 107, 21, 11, + 198, 255, 78, 159, 206, 214, 0, 177, 6, 48, 10, 127, 241, 29, 144, 236, 7, 104, 206, 254, 22, 249, 183, + 149, 3, 190, 153, 158, 158, 206, 184, 213, 82, 126, 74, 5, 227, 243, 245, 235, 25, 255, 76, 9, 127, 124, + 190, 107, 116, 46, 27, 239, 131, 230, 236, 21, 240, 183, 117, 47, 4, 240, 207, 192, 251, 129, 97, 14, 87, + 202, 31, 118, 131, 143, 237, 221, 75, 210, 205, 102, 86, 3, 32, 255, 85, 194, 243, 125, 85, 231, 178, 241, + 94, 104, 206, 254, 22, 248, 99, 13, 32, 230, 128, 226, 94, 48, 240, 159, 18, 20, 20, 244, 203, 79, 103, + 207, 178, 28, 80, 41, 255, 122, 250, 111, 84, 93, 184, 64, 242, 186, 117, 99, 57, 32, 214, 128, 24, 255, + 70, 224, 111, 227, 61, 208, 156, 253, 45, 242, 23, 115, 64, 233, 94, 48, 228, 128, 99, 168, 190, 253, 172, + 164, 132, 205, 1, 87, 174, 92, 81, 38, 250, 14, 64, 71, 192, 155, 241, 241, 236, 76, 16, 214, 0, 43, 12, + 200, 95, 242, 46, 104, 206, 94, 33, 127, 185, 51, 65, 145, 230, 166, 115, 225, 219, 11, 10, 10, 212, 225, + 79, 5, 62, 224, 223, 242, 242, 216, 189, 0, 47, 75, 248, 195, 179, 92, 107, 76, 105, 206, 94, 1, 127, 233, + 221, 96, 144, 3, 66, 63, 32, 238, 5, 175, 156, 50, 101, 138, 106, 252, 33, 7, 56, 84, 92, 220, 220, 11, + 242, 138, 132, 191, 65, 223, 1, 205, 217, 223, 34, 127, 209, 7, 148, 246, 3, 62, 200, 249, 63, 23, 30, 30, + 94, 95, 125, 249, 50, 171, 225, 174, 212, 212, 40, 18, 248, 0, 231, 43, 42, 200, 210, 46, 93, 88, 63, 32, + 228, 128, 80, 67, 99, 14, 232, 225, 255, 95, 231, 111, 54, 203, 223, 15, 220, 159, 243, 127, 194, 98, 177, + 84, 128, 15, 4, 123, 193, 112, 54, 68, 137, 96, 14, 168, 167, 255, 206, 186, 152, 24, 118, 38, 4, 114, 64, + 177, 6, 240, 240, 215, 132, 191, 52, 7, 236, 97, 110, 58, 19, 18, 205, 247, 2, 75, 222, 125, 247, 93, 182, + 6, 40, 229, 15, 130, 83, 1, 31, 46, 90, 196, 206, 132, 64, 14, 136, 53, 128, 152, 255, 233, 128, 169, 187, + 241, 135, 28, 80, 244, 129, 216, 153, 16, 115, 211, 185, 224, 63, 166, 166, 166, 54, 241, 175, 174, 86, 44, + 168, 1, 254, 253, 193, 7, 205, 62, 112, 158, 192, 31, 159, 233, 31, 140, 37, 205, 217, 43, 228, 111, 111, + 47, 16, 248, 167, 69, 70, 70, 50, 255, 30, 226, 23, 246, 132, 148, 168, 150, 230, 0, 103, 143, 29, 35, 75, + 239, 184, 131, 249, 128, 34, 127, 124, 166, 255, 99, 44, 105, 206, 94, 1, 127, 209, 7, 18, 239, 6, 194, + 189, 64, 224, 63, 177, 115, 231, 206, 231, 142, 81, 102, 240, 14, 40, 229, 15, 239, 16, 188, 3, 175, 71, + 71, 51, 31, 72, 172, 1, 48, 246, 117, 192, 212, 157, 248, 139, 57, 64, 39, 158, 3, 224, 247, 196, 129, 15, + 20, 71, 181, 15, 239, 135, 131, 90, 64, 169, 160, 14, 220, 145, 150, 198, 214, 0, 200, 1, 151, 123, 248, + 235, 129, 191, 116, 47, 80, 244, 129, 254, 148, 145, 145, 193, 248, 95, 166, 252, 148, 10, 58, 130, 224, + 126, 40, 168, 1, 160, 23, 4, 107, 128, 87, 77, 134, 92, 3, 52, 103, 175, 2, 127, 185, 59, 226, 241, 92, 40, + 172, 1, 153, 163, 70, 141, 98, 251, 0, 48, 135, 43, 229, 127, 133, 174, 35, 103, 142, 30, 37, 75, 59, 119, + 102, 62, 16, 214, 0, 30, 254, 154, 240, 183, 229, 3, 225, 253, 128, 15, 241, 189, 160, 202, 138, 147, 39, + 153, 15, 116, 185, 170, 74, 145, 96, 13, 184, 82, 87, 71, 94, 31, 54, 140, 157, 11, 198, 28, 16, 249, 195, + 115, 45, 48, 142, 52, 103, 175, 2, 127, 179, 185, 181, 15, 36, 246, 3, 197, 240, 189, 160, 253, 31, 127, + 252, 49, 59, 23, 10, 119, 69, 43, 21, 156, 12, 248, 144, 230, 0, 208, 19, 14, 62, 32, 228, 128, 88, 3, 120, + 248, 107, 194, 223, 102, 79, 56, 21, 220, 13, 241, 231, 156, 156, 28, 2, 67, 13, 254, 117, 244, 61, 250, + 15, 205, 41, 225, 110, 40, 200, 1, 196, 28, 16, 231, 86, 29, 176, 117, 68, 255, 15, 182, 249, 153, 94, 18, + 228, 200, 106, 0, 0, 10, 181, 109, 107, 66, 84, 250, 206, 202, 254, 0, 127, 87, 186, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 157, 141, 145, + 219, 56, 12, 70, 83, 72, 26, 73, 33, 41, 36, 141, 164, 144, 20, 146, 70, 82, 72, 110, 144, 155, 119, 243, + 238, 11, 72, 201, 89, 175, 29, 219, 120, 51, 158, 213, 234, 135, 164, 8, 18, 162, 0, 144, 250, 249, 115, + 24, 134, 97, 24, 134, 97, 24, 134, 97, 24, 134, 97, 120, 73, 190, 127, 255, 254, 219, 239, 199, 143, 31, + 255, 29, 187, 39, 85, 142, 123, 151, 225, 217, 249, 240, 225, 195, 111, 191, 175, 95, 191, 254, 170, 247, + 218, 190, 103, 253, 87, 57, 170, 12, 195, 251, 129, 188, 207, 226, 246, 240, 150, 254, 185, 187, 182, 142, + 213, 111, 39, 127, 174, 71, 87, 13, 123, 62, 126, 252, 216, 214, 213, 74, 254, 238, 255, 108, 127, 250, + 244, 233, 215, 223, 111, 223, 190, 253, 252, 242, 229, 203, 127, 250, 162, 246, 23, 181, 175, 242, 41, 42, + 47, 206, 229, 24, 231, 145, 78, 253, 92, 174, 218, 207, 177, 218, 111, 249, 147, 118, 157, 91, 105, 90, 95, + 213, 177, 97, 207, 74, 206, 157, 254, 47, 58, 249, 127, 254, 252, 249, 215, 54, 245, 79, 255, 45, 185, 148, + 12, 144, 57, 50, 98, 63, 231, 84, 254, 200, 20, 153, 215, 254, 108, 23, 244, 107, 206, 37, 63, 183, 19, + 218, 2, 229, 27, 246, 236, 228, 95, 50, 242, 248, 175, 232, 228, 207, 49, 228, 66, 127, 181, 12, 145, 115, + 181, 21, 247, 89, 228, 199, 53, 224, 62, 190, 58, 134, 62, 0, 202, 99, 61, 49, 236, 217, 201, 255, 172, + 254, 79, 249, 119, 239, 12, 232, 121, 228, 94, 127, 171, 45, 32, 215, 218, 182, 44, 253, 204, 88, 201, 223, + 122, 0, 232, 251, 149, 158, 117, 195, 208, 115, 77, 249, 35, 215, 146, 85, 93, 235, 62, 72, 95, 247, 152, + 192, 121, 248, 89, 146, 199, 118, 186, 33, 219, 137, 245, 140, 229, 95, 109, 196, 105, 12, 255, 82, 117, + 226, 254, 115, 180, 31, 93, 205, 88, 156, 109, 31, 167, 95, 103, 251, 41, 89, 89, 222, 41, 15, 250, 109, + 230, 93, 215, 121, 44, 151, 178, 172, 109, 218, 32, 122, 134, 49, 201, 234, 154, 97, 24, 134, 97, 24, 134, + 97, 120, 69, 24, 199, 223, 147, 71, 176, 215, 167, 255, 243, 111, 47, 239, 89, 242, 221, 250, 30, 92, 234, + 107, 186, 54, 245, 174, 120, 132, 203, 232, 237, 106, 7, 207, 230, 103, 72, 157, 240, 150, 246, 190, 187, + 150, 247, 243, 157, 252, 207, 216, 241, 143, 124, 134, 121, 158, 247, 117, 190, 196, 46, 189, 149, 252, + 255, 134, 254, 243, 22, 92, 254, 244, 179, 97, 207, 195, 166, 142, 77, 38, 253, 119, 233, 219, 195, 23, + 228, 107, 233, 35, 157, 207, 144, 250, 36, 63, 206, 93, 249, 3, 77, 231, 111, 164, 140, 92, 143, 253, 200, + 190, 44, 219, 47, 237, 223, 218, 165, 151, 242, 183, 31, 226, 81, 219, 64, 202, 223, 126, 54, 31, 115, 63, + 41, 125, 137, 206, 44, 185, 32, 27, 108, 190, 236, 231, 156, 244, 11, 216, 103, 88, 32, 35, 236, 118, 5, + 231, 81, 231, 180, 15, 147, 246, 103, 183, 29, 218, 12, 247, 66, 158, 153, 22, 242, 238, 236, 217, 153, 94, + 202, 223, 117, 244, 168, 227, 129, 174, 255, 3, 117, 104, 189, 224, 190, 109, 63, 142, 125, 123, 93, 140, + 208, 46, 126, 200, 125, 208, 118, 95, 247, 255, 74, 59, 235, 120, 231, 111, 204, 103, 74, 246, 235, 244, + 89, 93, 146, 222, 179, 235, 127, 64, 182, 233, 3, 46, 236, 171, 41, 153, 225, 111, 113, 127, 67, 150, 252, + 191, 147, 63, 125, 223, 62, 64, 199, 251, 88, 159, 192, 206, 223, 152, 242, 39, 45, 252, 0, 228, 211, 201, + 255, 40, 189, 87, 145, 63, 207, 246, 250, 155, 178, 177, 188, 139, 244, 197, 219, 23, 231, 250, 222, 233, + 6, 244, 137, 219, 9, 186, 197, 186, 24, 118, 254, 198, 148, 191, 207, 235, 228, 79, 156, 202, 153, 244, 82, + 254, 156, 215, 249, 195, 254, 118, 236, 91, 75, 63, 91, 65, 125, 165, 63, 45, 253, 119, 246, 237, 229, 181, + 212, 109, 209, 213, 145, 253, 125, 60, 71, 200, 99, 229, 75, 132, 149, 191, 49, 125, 136, 188, 167, 117, + 229, 241, 120, 230, 76, 122, 222, 166, 30, 30, 85, 254, 195, 48, 12, 195, 48, 12, 195, 80, 99, 91, 236, + 155, 252, 60, 62, 191, 103, 92, 61, 246, 128, 25, 99, 191, 31, 182, 125, 241, 179, 77, 190, 139, 11, 189, + 21, 127, 195, 252, 195, 103, 103, 103, 211, 234, 252, 224, 214, 9, 232, 14, 199, 132, 231, 220, 192, 244, + 45, 66, 94, 235, 243, 107, 95, 103, 63, 204, 242, 160, 175, 70, 63, 156, 163, 179, 171, 32, 255, 149, 221, + 215, 118, 48, 124, 124, 216, 142, 208, 27, 216, 127, 61, 199, 167, 72, 191, 80, 198, 238, 219, 103, 231, + 115, 236, 183, 227, 47, 199, 104, 31, 216, 145, 241, 73, 13, 199, 116, 253, 220, 126, 23, 215, 123, 145, + 242, 231, 250, 110, 94, 167, 125, 129, 182, 239, 90, 230, 248, 15, 186, 121, 68, 158, 235, 151, 243, 207, + 236, 183, 243, 53, 232, 136, 233, 255, 231, 88, 201, 127, 165, 255, 87, 118, 240, 244, 165, 167, 79, 29, + 27, 41, 237, 34, 251, 177, 99, 48, 206, 28, 203, 118, 89, 224, 147, 216, 197, 11, 12, 255, 231, 90, 242, + 239, 124, 126, 224, 185, 95, 37, 47, 207, 5, 44, 206, 244, 127, 112, 92, 128, 203, 201, 185, 121, 206, 176, + 231, 90, 242, 47, 208, 201, 233, 59, 47, 120, 134, 23, 214, 225, 206, 115, 245, 252, 95, 233, 6, 183, 57, + 63, 255, 29, 171, 80, 204, 220, 175, 53, 221, 187, 92, 237, 91, 189, 227, 121, 124, 222, 217, 2, 24, 195, + 231, 245, 196, 141, 56, 157, 212, 207, 221, 248, 159, 103, 0, 228, 251, 191, 203, 202, 177, 76, 123, 228, + 63, 12, 195, 48, 12, 195, 48, 12, 231, 24, 95, 224, 107, 51, 190, 192, 231, 134, 62, 180, 146, 227, 248, 2, + 159, 27, 219, 220, 198, 23, 248, 122, 228, 26, 171, 201, 248, 2, 95, 131, 157, 252, 199, 23, 248, 252, 92, + 83, 254, 227, 11, 124, 60, 174, 41, 255, 98, 124, 129, 143, 197, 202, 231, 55, 190, 192, 97, 24, 134, 97, + 24, 134, 97, 120, 110, 46, 181, 149, 116, 235, 134, 28, 97, 127, 18, 63, 108, 196, 247, 94, 67, 227, 149, + 223, 17, 118, 107, 173, 172, 216, 189, 35, 174, 224, 253, 220, 126, 101, 251, 144, 238, 41, 255, 180, 51, + 60, 51, 94, 215, 7, 219, 27, 182, 185, 194, 107, 240, 172, 100, 108, 249, 99, 127, 193, 38, 183, 106, 75, + 43, 155, 156, 229, 111, 127, 34, 101, 242, 250, 60, 46, 227, 202, 158, 96, 155, 193, 234, 94, 40, 51, 122, + 204, 242, 207, 246, 232, 117, 10, 159, 193, 166, 108, 219, 43, 54, 187, 250, 223, 118, 180, 238, 155, 60, + 153, 134, 215, 16, 195, 175, 135, 13, 190, 107, 55, 93, 255, 47, 108, 211, 99, 27, 91, 96, 253, 79, 218, + 246, 249, 208, 110, 125, 189, 215, 231, 242, 154, 132, 171, 239, 11, 145, 71, 202, 223, 235, 142, 177, 6, + 154, 215, 196, 122, 116, 144, 17, 184, 94, 118, 223, 228, 50, 41, 127, 63, 59, 87, 109, 198, 114, 245, 53, + 157, 252, 29, 111, 228, 99, 246, 31, 179, 159, 254, 73, 122, 236, 63, 250, 190, 152, 143, 145, 79, 238, + 247, 122, 120, 247, 140, 123, 185, 38, 216, 199, 33, 251, 133, 101, 185, 122, 46, 254, 169, 252, 187, 253, + 157, 252, 211, 23, 212, 197, 34, 209, 175, 209, 237, 164, 127, 244, 13, 185, 221, 49, 252, 20, 214, 243, + 228, 193, 241, 71, 103, 215, 255, 237, 123, 43, 210, 143, 3, 183, 146, 127, 215, 30, 108, 251, 119, 60, 1, + 253, 61, 125, 71, 221, 189, 236, 218, 70, 198, 168, 144, 94, 250, 41, 31, 245, 157, 129, 182, 236, 122, 73, + 29, 112, 228, 71, 191, 149, 252, 11, 175, 227, 75, 236, 0, 172, 214, 156, 206, 123, 205, 123, 217, 201, + 223, 101, 200, 239, 11, 251, 154, 71, 149, 127, 145, 49, 50, 233, 199, 219, 173, 175, 207, 113, 175, 167, + 153, 105, 117, 109, 102, 23, 151, 147, 62, 191, 46, 191, 213, 254, 221, 125, 172, 174, 205, 235, 242, 156, + 174, 126, 158, 97, 236, 63, 12, 195, 48, 12, 195, 48, 12, 176, 154, 91, 117, 180, 191, 155, 43, 240, 55, + 248, 83, 118, 113, 172, 195, 239, 236, 230, 214, 173, 246, 121, 206, 133, 231, 10, 29, 189, 63, 222, 130, + 145, 127, 143, 125, 24, 182, 161, 229, 156, 26, 88, 249, 231, 119, 237, 197, 182, 145, 218, 118, 204, 63, + 223, 229, 176, 223, 169, 240, 247, 68, 240, 255, 129, 143, 249, 90, 219, 147, 240, 45, 113, 47, 150, 63, + 223, 179, 241, 61, 191, 234, 60, 17, 203, 204, 126, 182, 140, 155, 135, 35, 253, 223, 217, 230, 173, 255, + 217, 230, 187, 62, 182, 211, 217, 70, 107, 255, 140, 219, 34, 113, 254, 248, 122, 176, 1, 114, 173, 191, + 81, 232, 111, 9, 57, 198, 196, 114, 166, 44, 248, 136, 238, 173, 167, 110, 205, 89, 91, 59, 28, 237, 167, + 111, 230, 58, 1, 41, 127, 64, 15, 184, 45, 96, 215, 167, 45, 216, 55, 139, 252, 40, 123, 206, 27, 177, 223, + 175, 155, 83, 210, 237, 167, 221, 250, 187, 64, 175, 194, 181, 229, 223, 245, 159, 75, 228, 239, 57, 31, + 232, 238, 252, 214, 160, 191, 201, 184, 147, 127, 62, 15, 58, 159, 110, 193, 51, 233, 21, 231, 10, 95, 91, + 255, 95, 42, 127, 235, 109, 116, 176, 99, 109, 236, 195, 67, 62, 228, 113, 164, 255, 83, 254, 180, 141, 76, + 147, 248, 16, 199, 8, 60, 178, 63, 231, 18, 60, 110, 162, 143, 209, 175, 110, 33, 255, 194, 62, 61, 247, + 231, 221, 60, 242, 188, 54, 199, 127, 59, 249, 227, 199, 171, 244, 115, 252, 247, 232, 254, 220, 97, 24, + 134, 97, 24, 134, 97, 24, 134, 123, 224, 120, 203, 140, 153, 92, 197, 127, 222, 138, 221, 251, 234, 112, + 29, 120, 231, 182, 63, 48, 215, 139, 188, 23, 35, 255, 53, 158, 223, 224, 248, 122, 230, 199, 209, 143, + 153, 131, 99, 191, 93, 166, 179, 178, 161, 120, 14, 94, 250, 234, 108, 135, 242, 188, 160, 149, 15, 208, + 199, 40, 19, 215, 102, 249, 177, 255, 58, 126, 31, 159, 166, 203, 211, 217, 163, 94, 1, 108, 160, 105, 15, + 197, 110, 231, 53, 26, 57, 175, 179, 169, 23, 158, 87, 199, 207, 126, 183, 92, 59, 20, 219, 63, 118, 254, + 110, 142, 151, 237, 187, 246, 231, 146, 54, 101, 204, 114, 165, 223, 209, 253, 191, 243, 85, 98, 83, 126, + 118, 249, 167, 254, 163, 94, 185, 247, 85, 12, 79, 55, 79, 40, 233, 124, 59, 43, 249, 83, 207, 233, 71, + 244, 252, 52, 124, 63, 216, 102, 237, 31, 180, 255, 208, 247, 182, 42, 63, 199, 114, 142, 151, 247, 87, + 126, 207, 50, 207, 111, 197, 78, 254, 150, 217, 159, 202, 127, 165, 255, 83, 254, 57, 255, 215, 126, 100, + 142, 97, 171, 231, 152, 231, 242, 238, 214, 135, 220, 201, 223, 109, 20, 72, 139, 54, 246, 236, 109, 192, + 88, 255, 91, 255, 221, 74, 254, 133, 253, 144, 126, 206, 115, 46, 227, 18, 218, 3, 121, 156, 209, 255, 144, + 109, 131, 52, 217, 182, 79, 220, 237, 239, 21, 124, 66, 30, 255, 173, 100, 252, 158, 242, 247, 248, 47, + 231, 248, 217, 7, 152, 254, 193, 98, 53, 254, 219, 201, 191, 200, 121, 254, 221, 248, 239, 85, 228, 63, 12, + 195, 48, 12, 195, 48, 12, 195, 48, 12, 195, 48, 12, 195, 48, 12, 195, 48, 12, 195, 48, 188, 46, 196, 80, + 22, 151, 126, 15, 4, 31, 254, 42, 214, 206, 49, 64, 71, 92, 226, 159, 191, 228, 220, 75, 202, 240, 222, 16, + 223, 114, 75, 88, 255, 152, 181, 115, 50, 127, 226, 177, 40, 223, 165, 242, 231, 186, 142, 74, 235, 236, + 183, 22, 186, 56, 148, 142, 140, 39, 62, 226, 146, 88, 64, 226, 150, 188, 14, 206, 81, 172, 251, 81, 253, + 26, 98, 163, 224, 218, 113, 244, 142, 157, 242, 119, 120, 137, 11, 236, 98, 247, 41, 147, 191, 235, 238, + 184, 95, 202, 75, 124, 149, 143, 145, 118, 206, 23, 32, 222, 220, 49, 231, 142, 213, 77, 188, 54, 16, 107, + 8, 101, 159, 101, 45, 50, 199, 155, 239, 250, 53, 249, 159, 57, 151, 243, 29, 63, 75, 94, 142, 69, 186, + 164, 126, 137, 57, 242, 207, 177, 81, 239, 177, 174, 89, 174, 215, 70, 185, 56, 150, 235, 127, 17, 15, 78, + 63, 229, 126, 59, 58, 61, 74, 60, 151, 239, 219, 223, 254, 161, 45, 236, 116, 0, 241, 186, 196, 146, 121, + 78, 65, 222, 27, 199, 233, 103, 187, 254, 67, 254, 142, 9, 92, 225, 251, 78, 253, 226, 88, 202, 75, 234, + 151, 115, 41, 39, 233, 94, 75, 255, 103, 92, 126, 226, 231, 50, 125, 155, 54, 237, 125, 212, 179, 191, 183, + 225, 239, 41, 185, 30, 220, 110, 93, 79, 187, 251, 114, 222, 29, 94, 27, 204, 247, 179, 106, 135, 126, 134, + 34, 183, 238, 123, 31, 112, 230, 185, 226, 249, 50, 57, 119, 128, 54, 148, 28, 213, 47, 208, 46, 28, 159, + 122, 45, 118, 237, 58, 251, 43, 253, 199, 255, 163, 243, 178, 77, 123, 222, 87, 151, 30, 253, 143, 251, 74, + 89, 185, 175, 90, 247, 173, 202, 234, 181, 162, 96, 37, 183, 140, 13, 237, 210, 164, 108, 57, 143, 133, + 188, 18, 231, 149, 237, 158, 182, 153, 28, 213, 175, 207, 35, 79, 207, 85, 122, 43, 232, 193, 85, 255, 63, + 59, 238, 253, 19, 249, 115, 142, 231, 220, 100, 154, 126, 30, 118, 241, 224, 78, 183, 155, 135, 68, 157, + 231, 55, 42, 46, 89, 231, 171, 27, 43, 118, 58, 211, 121, 101, 59, 244, 248, 56, 203, 125, 166, 126, 233, + 255, 221, 124, 133, 183, 178, 43, 195, 145, 222, 133, 78, 254, 57, 127, 163, 224, 221, 192, 125, 149, 123, + 66, 198, 158, 35, 116, 6, 175, 233, 152, 215, 120, 238, 144, 227, 213, 173, 115, 143, 88, 201, 191, 107, + 175, 140, 83, 172, 31, 86, 237, 155, 252, 47, 213, 231, 187, 117, 74, 61, 111, 234, 12, 71, 253, 191, 240, + 60, 139, 213, 187, 76, 39, 255, 163, 178, 243, 76, 172, 242, 58, 15, 228, 68, 93, 178, 54, 220, 106, 172, + 102, 157, 153, 242, 103, 76, 152, 235, 4, 122, 157, 47, 175, 43, 216, 189, 91, 123, 142, 153, 223, 29, 186, + 114, 240, 221, 67, 244, 77, 174, 89, 215, 113, 166, 126, 225, 232, 91, 187, 28, 123, 143, 121, 139, 188, + 163, 174, 242, 205, 121, 26, 9, 99, 5, 200, 122, 65, 191, 167, 222, 244, 187, 244, 145, 222, 59, 211, 238, + 119, 239, 132, 171, 177, 128, 199, 57, 151, 172, 19, 122, 201, 115, 122, 87, 191, 148, 251, 72, 174, 156, + 243, 236, 243, 86, 135, 97, 120, 51, 255, 0, 160, 130, 250, 32, 224, 191, 37, 163, 0, 0, 1, 129, 109, 107, + 66, 84, 250, 206, 202, 254, 0, 127, 102, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 209, 193, 9, 132, 80, 16, 68, 193, 241, 170, 25, 8, 94, + 205, 63, 169, 15, 70, 224, 81, 23, 147, 248, 189, 48, 213, 80, 9, 244, 171, 247, 125, 43, 109, 140, 81, + 219, 182, 213, 183, 101, 89, 152, 40, 221, 94, 127, 253, 245, 215, 95, 127, 253, 245, 215, 63, 253, 71, 55, + 233, 246, 250, 235, 175, 191, 254, 250, 235, 175, 191, 254, 233, 63, 186, 73, 183, 215, 95, 127, 253, 245, + 215, 95, 127, 253, 245, 79, 255, 209, 77, 186, 189, 254, 250, 235, 175, 191, 254, 250, 235, 175, 127, 250, + 143, 110, 210, 237, 245, 215, 95, 127, 253, 245, 215, 95, 127, 253, 211, 127, 116, 147, 110, 175, 191, 254, + 250, 235, 175, 191, 254, 250, 235, 159, 254, 163, 155, 116, 123, 253, 245, 215, 95, 127, 253, 245, 215, 95, + 255, 244, 31, 221, 164, 219, 235, 175, 191, 254, 250, 235, 175, 191, 254, 250, 167, 255, 232, 38, 221, 94, + 127, 253, 245, 215, 95, 127, 253, 245, 215, 63, 253, 71, 55, 233, 246, 250, 235, 175, 191, 254, 250, 235, + 175, 191, 254, 233, 63, 186, 73, 183, 215, 95, 127, 253, 245, 215, 95, 127, 253, 245, 79, 255, 209, 77, + 186, 189, 254, 250, 235, 175, 191, 254, 250, 235, 175, 127, 250, 143, 110, 210, 237, 245, 215, 95, 127, + 253, 245, 239, 221, 127, 93, 215, 178, 249, 75, 183, 255, 92, 215, 85, 231, 121, 214, 190, 239, 117, 28, 7, + 19, 165, 219, 127, 158, 231, 169, 251, 190, 9, 72, 183, 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, 248, 51, 63, 77, 240, 43, 16, 101, 34, 111, 240, 0, 0, 13, 72, 109, + 107, 66, 84, 250, 206, 202, 254, 0, 127, 122, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 157, 123, 76, 84, 217, 29, 199, 239, 192, 0, 67, 4, + 147, 117, 212, 132, 193, 7, 143, 182, 10, 14, 248, 0, 28, 65, 165, 128, 46, 162, 235, 184, 187, 22, 89, 23, + 193, 213, 173, 138, 93, 37, 86, 148, 68, 23, 19, 149, 88, 109, 162, 6, 44, 254, 209, 42, 70, 124, 45, 184, + 117, 91, 53, 65, 221, 54, 81, 87, 209, 196, 240, 72, 52, 42, 54, 209, 202, 154, 172, 16, 31, 248, 194, 42, + 130, 158, 222, 115, 156, 59, 30, 238, 156, 123, 153, 225, 117, 206, 189, 156, 111, 242, 253, 107, 254, 80, + 127, 31, 127, 231, 241, 189, 191, 59, 35, 0, 0, 4, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 125, 249, 240, 225, 195, 220, 253, 216, 92, + 253, 91, 6, 131, 129, 155, 155, 187, 27, 214, 178, 104, 215, 78, 15, 214, 178, 104, 215, 78, 15, 214, 178, + 104, 215, 78, 15, 214, 178, 104, 215, 78, 15, 214, 178, 104, 215, 78, 15, 214, 178, 104, 215, 78, 15, 214, + 178, 104, 215, 78, 15, 214, 178, 104, 215, 78, 15, 214, 178, 104, 215, 78, 15, 214, 178, 104, 215, 78, 15, + 214, 178, 104, 215, 78, 15, 214, 178, 104, 215, 78, 15, 214, 178, 104, 215, 78, 15, 214, 178, 104, 215, 78, + 15, 214, 178, 104, 215, 78, 15, 214, 178, 104, 215, 78, 15, 214, 178, 104, 215, 78, 15, 214, 178, 104, 215, + 78, 15, 214, 178, 104, 215, 78, 15, 214, 178, 104, 215, 78, 15, 214, 178, 104, 215, 78, 15, 214, 178, 104, + 215, 78, 15, 214, 168, 12, 180, 235, 166, 23, 107, 76, 6, 76, 212, 107, 167, 7, 107, 68, 56, 119, 47, 209, + 222, 180, 235, 166, 23, 51, 46, 18, 119, 3, 246, 33, 183, 62, 249, 171, 113, 15, 26, 61, 122, 244, 182, 3, + 7, 14, 80, 175, 157, 30, 204, 152, 72, 220, 189, 28, 159, 153, 67, 67, 67, 191, 221, 179, 103, 79, 211, + 171, 87, 175, 0, 124, 255, 155, 118, 237, 244, 96, 70, 164, 198, 61, 208, 108, 54, 231, 110, 220, 184, 241, + 231, 167, 79, 159, 2, 76, 212, 107, 167, 7, 211, 150, 10, 119, 211, 71, 31, 125, 180, 184, 160, 160, 160, + 254, 193, 131, 7, 128, 32, 234, 181, 211, 131, 25, 64, 47, 231, 238, 99, 50, 153, 210, 243, 242, 242, 234, + 238, 223, 191, 79, 226, 206, 249, 107, 151, 191, 1, 147, 151, 196, 94, 250, 204, 215, 215, 119, 102, 102, + 102, 230, 197, 235, 215, 175, 171, 113, 231, 252, 181, 201, 95, 206, 222, 91, 250, 243, 189, 189, 189, 167, + 102, 100, 100, 252, 120, 245, 234, 85, 119, 184, 115, 254, 218, 226, 239, 194, 29, 251, 44, 54, 53, 53, + 245, 88, 117, 117, 245, 91, 79, 192, 115, 254, 154, 224, 239, 194, 29, 251, 243, 34, 226, 227, 227, 203, + 42, 43, 43, 91, 223, 190, 237, 10, 122, 206, 159, 97, 254, 36, 238, 210, 31, 20, 22, 27, 27, 91, 114, 226, + 196, 137, 151, 93, 133, 206, 249, 51, 203, 95, 141, 123, 208, 200, 145, 35, 183, 30, 57, 114, 228, 73, 91, + 91, 91, 15, 160, 231, 252, 25, 226, 79, 226, 238, 204, 236, 70, 140, 24, 177, 110, 215, 174, 93, 77, 45, + 45, 45, 61, 197, 157, 243, 103, 135, 191, 18, 247, 192, 160, 160, 160, 220, 237, 219, 183, 55, 200, 50, 59, + 206, 159, 49, 247, 112, 191, 155, 2, 2, 2, 22, 229, 231, 231, 215, 63, 121, 242, 164, 183, 184, 115, 254, + 244, 248, 43, 113, 55, 250, 251, 251, 167, 175, 92, 185, 178, 182, 161, 161, 161, 183, 185, 115, 254, 125, + 207, 95, 206, 93, 186, 195, 123, 153, 76, 166, 180, 37, 75, 150, 92, 188, 125, 251, 118, 95, 113, 231, 252, + 251, 142, 191, 1, 19, 206, 29, 126, 48, 117, 214, 172, 89, 103, 60, 204, 236, 56, 127, 198, 236, 6, 119, + 121, 118, 19, 51, 99, 198, 140, 191, 87, 85, 85, 117, 57, 184, 225, 252, 217, 113, 103, 220, 177, 207, 34, + 146, 146, 146, 246, 159, 59, 119, 174, 149, 50, 119, 73, 212, 107, 167, 7, 171, 244, 187, 244, 97, 168, + 213, 106, 253, 75, 121, 121, 121, 143, 95, 224, 187, 41, 234, 181, 211, 137, 149, 184, 7, 141, 26, 53, 106, + 235, 193, 131, 7, 155, 91, 91, 89, 105, 249, 14, 162, 93, 55, 45, 27, 151, 75, 102, 23, 18, 18, 178, 30, + 206, 217, 189, 126, 253, 154, 54, 99, 53, 209, 174, 161, 86, 173, 196, 61, 96, 200, 144, 33, 185, 155, 54, + 109, 106, 120, 252, 248, 49, 109, 182, 170, 122, 214, 220, 12, 254, 90, 88, 72, 187, 142, 90, 179, 156, + 187, 116, 182, 243, 31, 52, 104, 208, 162, 130, 130, 130, 91, 10, 115, 118, 204, 232, 127, 45, 45, 224, 96, + 81, 17, 72, 177, 88, 64, 168, 192, 231, 255, 187, 201, 221, 199, 207, 207, 47, 125, 245, 234, 213, 181, + 157, 204, 217, 81, 87, 171, 184, 15, 253, 80, 90, 10, 102, 134, 133, 129, 48, 65, 0, 145, 162, 39, 244, 32, + 127, 157, 74, 137, 187, 151, 175, 175, 111, 90, 86, 86, 150, 187, 115, 118, 212, 4, 103, 67, 78, 87, 84, + 128, 185, 81, 81, 136, 123, 196, 123, 238, 32, 86, 244, 68, 129, 243, 87, 16, 206, 189, 195, 29, 222, 104, + 52, 194, 57, 59, 154, 153, 157, 219, 186, 80, 89, 9, 22, 76, 156, 8, 126, 45, 178, 30, 237, 224, 30, 247, + 158, 59, 152, 36, 122, 178, 192, 249, 203, 228, 194, 29, 251, 183, 197, 76, 155, 54, 237, 88, 77, 77, 77, + 59, 109, 174, 157, 169, 250, 252, 121, 176, 36, 57, 25, 252, 70, 100, 60, 74, 244, 248, 15, 253, 14, 226, + 223, 115, 7, 83, 69, 39, 9, 156, 191, 67, 216, 22, 239, 154, 217, 37, 36, 36, 236, 63, 117, 234, 20, 147, + 23, 120, 92, 55, 106, 106, 64, 174, 221, 14, 34, 13, 6, 212, 243, 56, 247, 73, 29, 185, 131, 20, 209, 31, + 11, 253, 158, 191, 11, 119, 195, 135, 127, 76, 104, 92, 92, 92, 201, 241, 227, 199, 95, 118, 99, 190, 178, + 79, 116, 251, 198, 13, 176, 46, 51, 19, 68, 121, 123, 131, 95, 137, 92, 199, 201, 184, 39, 96, 220, 167, + 189, 231, 14, 210, 68, 127, 34, 244, 91, 254, 106, 220, 131, 66, 66, 66, 182, 30, 58, 116, 168, 153, 117, + 238, 191, 220, 189, 11, 10, 151, 45, 3, 227, 77, 38, 34, 247, 201, 202, 220, 193, 28, 209, 159, 9, 253, + 142, 63, 137, 187, 51, 179, 27, 62, 124, 248, 186, 146, 146, 146, 166, 23, 47, 94, 208, 70, 171, 170, 135, + 141, 141, 96, 231, 218, 181, 192, 22, 24, 8, 194, 69, 142, 99, 221, 239, 119, 96, 23, 253, 169, 232, 185, + 162, 127, 39, 244, 27, 254, 106, 220, 209, 156, 221, 142, 29, 59, 26, 158, 61, 123, 70, 27, 173, 170, 80, + 102, 183, 121, 51, 152, 98, 54, 163, 187, 92, 180, 131, 123, 28, 129, 123, 10, 198, 125, 150, 43, 119, 48, + 79, 244, 23, 66, 191, 224, 175, 196, 221, 31, 206, 217, 173, 89, 179, 230, 86, 179, 88, 87, 150, 5, 51, + 187, 67, 69, 69, 96, 154, 197, 130, 184, 71, 137, 142, 113, 112, 183, 97, 220, 127, 139, 113, 159, 225, + 224, 62, 219, 193, 253, 115, 140, 123, 134, 232, 249, 162, 191, 20, 116, 205, 95, 137, 187, 113, 192, 128, + 1, 104, 206, 238, 222, 189, 123, 180, 209, 170, 10, 102, 118, 255, 40, 45, 5, 179, 194, 194, 208, 58, 111, + 117, 131, 123, 154, 10, 247, 47, 62, 112, 7, 153, 162, 23, 8, 186, 228, 143, 115, 199, 239, 240, 104, 206, + 110, 233, 210, 165, 23, 239, 220, 185, 67, 27, 173, 170, 224, 185, 243, 76, 69, 5, 72, 183, 90, 209, 61, + 110, 12, 225, 92, 151, 136, 237, 239, 169, 162, 103, 170, 48, 199, 120, 131, 108, 209, 11, 29, 254, 74, + 208, 21, 127, 121, 191, 59, 239, 240, 94, 94, 94, 137, 179, 103, 207, 62, 83, 87, 87, 71, 27, 173, 170, + 222, 189, 123, 7, 46, 86, 86, 130, 172, 137, 19, 81, 110, 19, 233, 1, 247, 57, 14, 238, 233, 50, 238, 144, + 121, 150, 43, 119, 228, 69, 130, 46, 248, 27, 48, 201, 179, 27, 56, 103, 119, 236, 210, 165, 75, 204, 103, + 118, 53, 231, 207, 131, 165, 201, 201, 40, 167, 141, 112, 172, 243, 132, 188, 174, 3, 119, 236, 30, 231, + 178, 198, 227, 253, 158, 237, 202, 93, 178, 150, 249, 43, 173, 243, 80, 145, 73, 73, 73, 101, 12, 205, 217, + 41, 234, 102, 109, 45, 88, 101, 183, 3, 171, 193, 128, 216, 75, 220, 73, 247, 247, 84, 161, 227, 253, 189, + 179, 117, 94, 133, 187, 150, 249, 187, 244, 187, 225, 195, 95, 32, 52, 42, 42, 170, 164, 188, 188, 156, + 249, 204, 238, 206, 205, 155, 224, 219, 204, 76, 48, 214, 219, 27, 173, 245, 19, 4, 242, 253, 29, 63, 215, + 73, 247, 119, 169, 223, 211, 61, 239, 119, 45, 243, 87, 227, 30, 20, 17, 17, 177, 13, 206, 217, 245, 224, + 187, 177, 189, 162, 95, 26, 26, 192, 150, 156, 28, 16, 99, 50, 57, 51, 122, 79, 184, 207, 85, 88, 231, 179, + 8, 220, 59, 97, 175, 21, 254, 106, 220, 205, 195, 134, 13, 91, 191, 119, 239, 94, 233, 251, 236, 152, 213, + 163, 166, 38, 80, 148, 159, 15, 38, 5, 4, 56, 185, 43, 221, 227, 166, 11, 31, 238, 239, 56, 119, 216, 239, + 25, 110, 112, 239, 132, 185, 86, 248, 147, 184, 59, 51, 187, 161, 67, 135, 230, 22, 22, 22, 106, 98, 206, + 238, 111, 133, 133, 32, 209, 108, 118, 102, 244, 56, 247, 41, 42, 220, 165, 188, 14, 231, 238, 198, 153, + 94, 15, 252, 149, 184, 163, 57, 187, 13, 27, 54, 252, 231, 225, 195, 135, 180, 209, 170, 234, 229, 139, 23, + 224, 112, 113, 49, 152, 110, 177, 32, 238, 209, 24, 247, 120, 55, 184, 75, 119, 57, 53, 238, 30, 172, 243, + 90, 224, 175, 214, 239, 70, 95, 95, 223, 121, 171, 86, 173, 170, 109, 108, 108, 164, 141, 86, 85, 111, 90, + 91, 193, 63, 247, 237, 3, 246, 240, 112, 180, 206, 67, 238, 242, 253, 93, 158, 215, 201, 207, 117, 242, + 251, 59, 206, 91, 98, 183, 216, 225, 175, 187, 103, 86, 248, 227, 236, 93, 230, 236, 178, 179, 179, 171, + 110, 138, 231, 101, 150, 5, 239, 27, 63, 30, 61, 138, 50, 59, 56, 119, 19, 37, 116, 124, 46, 131, 247, 59, + 225, 57, 44, 145, 123, 86, 239, 113, 103, 133, 191, 188, 223, 157, 119, 120, 163, 209, 152, 56, 127, 254, + 124, 77, 204, 217, 193, 204, 46, 219, 102, 67, 247, 247, 49, 157, 112, 39, 157, 235, 40, 112, 167, 205, + 223, 101, 173, 199, 62, 139, 73, 74, 74, 250, 161, 186, 186, 154, 249, 204, 174, 246, 167, 159, 192, 178, + 148, 20, 148, 215, 69, 10, 228, 253, 61, 153, 77, 238, 180, 248, 147, 246, 120, 233, 179, 200, 201, 147, + 39, 151, 157, 62, 125, 154, 249, 204, 14, 206, 217, 253, 209, 110, 7, 81, 142, 204, 46, 86, 198, 61, 209, + 193, 93, 233, 60, 47, 61, 131, 149, 242, 58, 233, 76, 215, 135, 220, 251, 154, 63, 137, 123, 135, 57, 187, + 147, 39, 79, 50, 159, 217, 253, 87, 60, 131, 20, 44, 88, 0, 198, 121, 123, 59, 185, 203, 215, 121, 119, + 250, 93, 254, 44, 142, 196, 251, 247, 125, 227, 222, 230, 175, 198, 221, 18, 26, 26, 186, 173, 172, 172, + 236, 9, 124, 238, 197, 178, 96, 102, 247, 167, 156, 28, 16, 103, 50, 161, 172, 22, 231, 174, 116, 158, 199, + 243, 121, 60, 179, 193, 215, 120, 18, 239, 37, 125, 235, 222, 226, 175, 198, 29, 126, 159, 221, 250, 221, + 187, 119, 55, 189, 124, 217, 19, 95, 97, 217, 123, 122, 36, 222, 53, 139, 243, 243, 65, 66, 64, 0, 226, 30, + 67, 232, 119, 233, 254, 174, 118, 143, 147, 115, 151, 250, 93, 222, 231, 125, 204, 190, 55, 248, 147, 184, + 59, 51, 59, 139, 197, 146, 187, 115, 231, 206, 134, 231, 207, 159, 211, 70, 171, 170, 231, 205, 205, 96, + 207, 230, 205, 32, 105, 240, 96, 116, 151, 131, 207, 102, 72, 231, 58, 105, 127, 87, 202, 231, 241, 117, + 94, 206, 157, 98, 207, 247, 6, 127, 53, 238, 254, 3, 7, 14, 92, 148, 151, 151, 119, 235, 209, 163, 71, 180, + 209, 170, 10, 102, 118, 71, 138, 139, 65, 170, 197, 130, 184, 143, 195, 184, 75, 179, 23, 164, 115, 29, + 137, 187, 82, 191, 51, 194, 189, 39, 249, 203, 185, 75, 103, 122, 56, 103, 55, 47, 55, 55, 151, 249, 57, + 187, 54, 152, 217, 149, 150, 2, 123, 88, 24, 90, 231, 199, 10, 158, 159, 231, 73, 121, 29, 67, 235, 124, + 79, 243, 151, 247, 187, 23, 214, 239, 94, 126, 126, 126, 104, 206, 142, 194, 247, 217, 121, 164, 183, 237, + 237, 224, 95, 71, 143, 130, 121, 86, 43, 226, 30, 77, 232, 247, 36, 225, 253, 236, 5, 228, 142, 207, 216, + 73, 207, 101, 228, 220, 25, 239, 247, 158, 224, 79, 90, 235, 165, 205, 127, 170, 221, 110, 63, 93, 35, 222, + 143, 89, 23, 204, 236, 22, 218, 108, 40, 187, 129, 89, 45, 62, 107, 165, 54, 91, 169, 196, 93, 222, 239, + 140, 115, 239, 10, 127, 53, 238, 19, 210, 210, 210, 142, 93, 190, 124, 153, 253, 204, 238, 194, 5, 144, + 147, 156, 140, 114, 218, 49, 2, 121, 198, 46, 69, 112, 157, 177, 195, 159, 199, 41, 61, 151, 209, 16, 119, + 79, 248, 147, 184, 75, 7, 254, 200, 196, 196, 196, 253, 103, 207, 158, 101, 62, 179, 187, 41, 174, 73, 171, + 237, 118, 16, 109, 48, 160, 172, 214, 147, 126, 39, 237, 239, 164, 123, 156, 84, 215, 165, 218, 113, 87, + 185, 135, 68, 71, 71, 151, 84, 84, 84, 180, 180, 183, 179, 221, 242, 40, 179, 203, 204, 4, 19, 140, 70, 39, + 247, 4, 161, 227, 121, 94, 218, 223, 241, 243, 188, 116, 127, 151, 231, 54, 56, 115, 57, 239, 101, 218, + 179, 167, 153, 29, 252, 221, 88, 248, 110, 236, 147, 55, 111, 222, 208, 70, 171, 42, 248, 110, 44, 204, + 236, 38, 154, 76, 40, 171, 133, 207, 102, 60, 237, 119, 121, 54, 47, 239, 117, 13, 115, 39, 241, 39, 113, + 151, 206, 244, 131, 130, 131, 131, 225, 247, 217, 53, 50, 63, 103, 231, 200, 236, 38, 7, 4, 56, 51, 122, + 181, 25, 250, 126, 202, 93, 206, 95, 137, 59, 156, 179, 91, 185, 101, 203, 150, 159, 181, 48, 103, 7, 51, + 187, 228, 193, 131, 157, 89, 45, 228, 46, 127, 23, 154, 196, 93, 233, 30, 167, 99, 238, 146, 149, 184, 195, + 223, 141, 133, 115, 118, 245, 90, 152, 179, 251, 174, 168, 8, 204, 176, 88, 156, 223, 113, 164, 212, 239, + 105, 130, 235, 187, 82, 106, 220, 117, 176, 191, 119, 102, 151, 57, 59, 31, 31, 159, 244, 21, 43, 86, 212, + 105, 97, 206, 238, 120, 105, 41, 248, 52, 44, 12, 113, 31, 175, 194, 93, 237, 60, 143, 159, 235, 228, 189, + 142, 215, 42, 71, 159, 198, 127, 55, 54, 109, 225, 194, 133, 23, 235, 235, 235, 105, 163, 85, 85, 123, 91, + 27, 202, 236, 50, 172, 86, 148, 221, 140, 35, 112, 151, 158, 197, 170, 173, 243, 242, 243, 188, 210, 26, + 207, 0, 163, 222, 180, 244, 187, 177, 103, 174, 93, 187, 70, 27, 109, 167, 130, 153, 221, 87, 54, 27, 186, + 199, 193, 172, 182, 179, 119, 102, 220, 89, 231, 229, 247, 246, 126, 194, 93, 242, 177, 43, 87, 174, 176, + 125, 129, 23, 85, 119, 225, 2, 88, 158, 156, 140, 190, 255, 32, 74, 112, 127, 246, 130, 196, 93, 173, 223, + 25, 224, 209, 231, 102, 89, 48, 179, 203, 179, 219, 209, 243, 56, 200, 30, 62, 155, 145, 214, 121, 37, 238, + 248, 58, 47, 207, 109, 164, 253, 157, 212, 231, 203, 251, 169, 89, 20, 204, 236, 54, 100, 102, 130, 24, + 163, 17, 101, 244, 238, 112, 151, 247, 187, 218, 254, 206, 185, 179, 201, 31, 102, 118, 91, 115, 114, 128, + 205, 207, 175, 67, 86, 171, 246, 238, 132, 252, 185, 76, 103, 231, 121, 206, 157, 61, 254, 40, 179, 91, + 187, 22, 76, 9, 12, 68, 103, 250, 56, 140, 123, 162, 208, 113, 198, 14, 207, 232, 73, 207, 227, 228, 231, + 58, 210, 222, 78, 187, 230, 44, 153, 166, 164, 204, 46, 197, 108, 118, 102, 181, 56, 119, 165, 89, 43, 105, + 166, 86, 226, 142, 207, 211, 242, 126, 103, 159, 255, 171, 150, 22, 240, 93, 113, 49, 152, 25, 28, 236, + 252, 174, 27, 79, 246, 119, 233, 92, 71, 98, 142, 179, 254, 131, 195, 223, 112, 43, 186, 47, 5, 51, 187, + 19, 251, 246, 129, 207, 194, 195, 165, 223, 159, 240, 232, 30, 7, 185, 147, 214, 120, 169, 207, 113, 230, + 156, 59, 59, 252, 225, 156, 221, 191, 191, 255, 30, 204, 183, 90, 209, 121, 126, 188, 160, 62, 67, 175, + 116, 158, 199, 231, 108, 228, 220, 121, 191, 179, 201, 191, 234, 212, 41, 176, 216, 102, 67, 247, 119, 41, + 171, 237, 108, 127, 39, 157, 231, 249, 58, 175, 45, 254, 48, 179, 251, 38, 37, 5, 229, 180, 209, 110, 114, + 39, 157, 235, 240, 126, 199, 207, 116, 156, 59, 155, 252, 235, 107, 107, 193, 154, 57, 115, 208, 26, 143, + 115, 151, 191, 51, 131, 115, 39, 173, 243, 82, 191, 147, 152, 227, 127, 255, 21, 220, 221, 114, 79, 233, + 110, 125, 61, 202, 236, 226, 124, 124, 208, 90, 63, 73, 232, 218, 58, 191, 72, 80, 62, 215, 113, 230, 236, + 241, 135, 153, 221, 159, 151, 47, 7, 241, 126, 126, 110, 115, 199, 215, 121, 210, 254, 206, 185, 179, 207, + 255, 113, 83, 19, 216, 181, 118, 45, 72, 12, 12, 116, 206, 209, 227, 220, 229, 179, 23, 238, 236, 239, 74, + 123, 59, 237, 26, 233, 217, 158, 10, 190, 27, 91, 90, 88, 8, 166, 155, 205, 68, 238, 242, 126, 87, 187, + 191, 227, 103, 121, 121, 159, 175, 116, 56, 151, 187, 87, 237, 174, 224, 111, 80, 192, 57, 187, 79, 130, + 131, 157, 223, 113, 164, 118, 174, 243, 148, 187, 244, 255, 145, 51, 103, 139, 191, 148, 217, 125, 30, 30, + 238, 252, 29, 2, 119, 246, 119, 165, 243, 60, 190, 198, 243, 126, 167, 111, 37, 193, 239, 226, 129, 153, + 221, 151, 86, 43, 58, 215, 193, 172, 150, 244, 238, 132, 187, 220, 249, 58, 207, 166, 73, 170, 170, 172, 4, + 95, 219, 108, 104, 214, 106, 188, 2, 119, 165, 115, 157, 252, 60, 143, 103, 117, 248, 90, 207, 185, 51, + 225, 255, 3, 231, 30, 81, 182, 237, 137, 92, 77, 0, 0, 23, 73, 109, 107, 66, 84, 250, 206, 202, 254, 0, + 127, 126, 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, 120, 156, 237, 157, 123, 84, 84, 247, 181, 199, 231, 128, 15, 192, 32, 190, 176, 70, 163, 98, 123, 111, + 125, 196, 7, 246, 198, 155, 168, 181, 106, 20, 177, 38, 215, 198, 154, 54, 209, 84, 5, 81, 240, 5, 62, 64, + 211, 198, 39, 196, 136, 143, 52, 213, 198, 16, 81, 155, 164, 85, 241, 17, 121, 41, 32, 62, 241, 1, 68, 124, + 241, 82, 6, 230, 193, 204, 224, 93, 55, 171, 171, 247, 246, 222, 172, 174, 222, 54, 189, 77, 127, 119, 239, + 57, 231, 7, 63, 14, 103, 6, 6, 206, 143, 57, 51, 204, 89, 107, 175, 252, 145, 72, 152, 243, 113, 239, 223, + 222, 223, 189, 247, 111, 200, 147, 199, 143, 73, 71, 205, 88, 95, 79, 110, 102, 101, 145, 181, 65, 129, 36, + 65, 167, 35, 191, 16, 116, 36, 5, 236, 125, 63, 29, 249, 8, 236, 19, 176, 83, 96, 159, 131, 229, 128, 229, + 129, 21, 128, 21, 74, 118, 217, 195, 140, 254, 222, 151, 164, 207, 130, 159, 233, 12, 124, 238, 139, 51, + 166, 147, 26, 163, 145, 60, 121, 242, 164, 195, 239, 148, 53, 171, 197, 82, 113, 252, 216, 177, 40, 157, + 78, 247, 6, 216, 60, 65, 16, 190, 15, 54, 30, 236, 219, 96, 131, 192, 66, 192, 2, 193, 186, 131, 249, 9, + 77, 143, 174, 149, 167, 195, 191, 91, 109, 93, 29, 169, 122, 248, 144, 188, 51, 106, 36, 89, 13, 63, 239, + 109, 224, 190, 11, 108, 31, 216, 135, 240, 94, 142, 129, 157, 0, 59, 7, 150, 13, 118, 1, 44, 95, 122, 119, + 158, 200, 159, 101, 159, 47, 125, 158, 243, 240, 185, 207, 4, 244, 36, 15, 115, 115, 137, 222, 108, 86, + 149, 125, 173, 94, 255, 127, 53, 79, 158, 188, 59, 97, 252, 248, 69, 192, 107, 1, 48, 125, 25, 236, 5, 176, + 81, 96, 207, 129, 245, 7, 123, 6, 172, 39, 152, 63, 195, 191, 53, 246, 29, 230, 15, 191, 23, 49, 128, 239, + 31, 252, 241, 2, 178, 18, 126, 214, 102, 96, 190, 29, 44, 21, 236, 32, 188, 151, 163, 96, 191, 5, 59, 11, + 150, 37, 99, 207, 190, 211, 43, 30, 98, 236, 239, 92, 192, 248, 254, 105, 248, 236, 215, 226, 98, 73, 173, + 205, 166, 42, 123, 180, 6, 155, 237, 70, 74, 74, 202, 91, 146, 239, 255, 16, 184, 78, 5, 27, 7, 54, 2, 236, + 91, 14, 124, 191, 45, 236, 59, 204, 223, 212, 208, 64, 206, 236, 216, 110, 103, 159, 168, 19, 217, 239, 1, + 251, 21, 188, 147, 116, 137, 253, 25, 137, 253, 69, 233, 157, 177, 188, 175, 122, 152, 177, 127, 15, 46, + 73, 159, 9, 125, 63, 107, 68, 24, 169, 126, 240, 128, 212, 212, 214, 170, 202, 222, 80, 87, 247, 85, 217, + 221, 187, 155, 7, 15, 30, 140, 190, 255, 35, 224, 58, 19, 236, 95, 192, 190, 11, 54, 4, 172, 159, 204, 247, + 219, 26, 247, 59, 204, 223, 104, 181, 146, 235, 167, 51, 200, 26, 136, 123, 235, 225, 231, 188, 3, 220, + 223, 149, 206, 252, 52, 176, 79, 193, 50, 240, 253, 128, 229, 74, 126, 95, 40, 243, 39, 119, 243, 108, 15, + 251, 43, 126, 204, 185, 47, 136, 231, 126, 233, 175, 15, 145, 90, 120, 31, 28, 124, 255, 236, 202, 149, 43, + 23, 3, 167, 159, 0, 211, 72, 176, 201, 96, 99, 193, 194, 192, 6, 50, 190, 223, 173, 29, 190, 223, 110, 254, + 117, 144, 227, 60, 250, 162, 148, 108, 129, 191, 247, 107, 224, 103, 252, 28, 222, 67, 50, 216, 126, 176, + 195, 240, 94, 142, 131, 157, 244, 107, 202, 247, 216, 152, 239, 137, 236, 89, 254, 248, 119, 24, 227, 24, + 158, 101, 231, 224, 179, 23, 68, 206, 33, 122, 147, 73, 245, 156, 207, 108, 50, 217, 46, 94, 184, 176, 58, + 48, 32, 0, 125, 255, 223, 128, 235, 12, 176, 239, 129, 253, 51, 216, 96, 201, 247, 123, 129, 245, 104, 167, + 239, 183, 139, 191, 94, 175, 39, 122, 200, 249, 246, 190, 60, 147, 196, 194, 159, 223, 2, 204, 119, 128, + 237, 5, 59, 228, 39, 158, 249, 191, 243, 19, 207, 252, 108, 63, 239, 138, 251, 172, 239, 103, 193, 103, + 255, 60, 248, 25, 82, 94, 88, 40, 242, 87, 145, 61, 230, 85, 245, 102, 243, 225, 136, 136, 8, 100, 191, 16, + 152, 70, 128, 189, 4, 246, 60, 216, 112, 176, 80, 176, 96, 176, 128, 14, 248, 126, 187, 248, 155, 32, 199, + 57, 190, 122, 21, 89, 33, 157, 249, 219, 152, 51, 255, 8, 216, 103, 96, 167, 253, 154, 159, 249, 222, 18, + 247, 241, 115, 96, 44, 195, 243, 12, 227, 254, 205, 205, 73, 164, 22, 114, 32, 181, 227, 190, 205, 106, + 125, 240, 113, 90, 90, 20, 240, 65, 254, 175, 0, 215, 105, 96, 225, 96, 255, 4, 246, 44, 88, 95, 176, 160, + 14, 250, 190, 203, 252, 49, 223, 203, 61, 120, 208, 238, 247, 27, 152, 51, 255, 151, 130, 120, 230, 99, + 157, 239, 77, 103, 62, 203, 159, 230, 252, 52, 231, 203, 29, 63, 142, 60, 169, 174, 38, 53, 16, 15, 213, + 100, 15, 245, 222, 95, 170, 42, 43, 119, 142, 26, 53, 10, 207, 125, 172, 247, 102, 129, 253, 43, 216, 104, + 176, 97, 96, 3, 84, 242, 125, 151, 248, 99, 157, 119, 27, 234, 219, 248, 144, 16, 178, 142, 57, 243, 15, + 72, 103, 254, 111, 252, 154, 159, 249, 121, 126, 222, 115, 230, 179, 190, 159, 13, 159, 253, 172, 191, 31, + 185, 119, 242, 36, 209, 91, 44, 170, 251, 62, 228, 124, 121, 155, 147, 146, 236, 245, 30, 48, 165, 245, 30, + 171, 245, 244, 145, 124, 223, 85, 173, 167, 221, 252, 107, 13, 6, 82, 113, 255, 62, 249, 197, 200, 145, + 100, 149, 164, 241, 236, 148, 206, 252, 95, 251, 53, 105, 60, 222, 116, 230, 179, 252, 41, 123, 204, 249, + 206, 194, 231, 191, 186, 100, 9, 151, 124, 223, 100, 52, 126, 121, 245, 234, 213, 132, 144, 144, 16, 228, + 79, 235, 61, 212, 122, 70, 10, 29, 215, 122, 218, 197, 31, 243, 61, 212, 248, 246, 69, 68, 52, 211, 120, + 246, 72, 26, 143, 188, 206, 191, 224, 231, 249, 103, 62, 203, 158, 173, 245, 51, 177, 214, 31, 54, 148, 84, + 151, 149, 145, 26, 120, 39, 106, 178, 199, 156, 207, 106, 177, 28, 253, 209, 252, 249, 142, 234, 61, 185, + 214, 211, 145, 115, 191, 77, 252, 241, 119, 194, 124, 239, 88, 92, 28, 137, 129, 255, 118, 19, 216, 86, + 224, 190, 27, 236, 3, 120, 31, 31, 251, 137, 117, 62, 230, 123, 222, 120, 230, 55, 203, 249, 4, 209, 247, + 191, 248, 240, 67, 46, 190, 111, 179, 88, 42, 143, 29, 61, 186, 28, 152, 32, 127, 172, 247, 166, 115, 168, + 247, 92, 226, 143, 249, 94, 230, 222, 189, 246, 92, 127, 61, 219, 215, 17, 90, 246, 117, 144, 189, 55, 156, + 249, 114, 223, 167, 57, 31, 214, 250, 133, 243, 231, 19, 61, 228, 65, 106, 215, 250, 144, 243, 125, 93, 93, + 85, 149, 60, 122, 244, 104, 140, 251, 63, 150, 234, 189, 23, 193, 198, 48, 245, 94, 111, 149, 114, 190, 54, + 241, 55, 217, 245, 189, 211, 100, 77, 96, 32, 137, 151, 105, 60, 216, 215, 65, 141, 135, 237, 235, 208, + 158, 158, 55, 177, 103, 107, 253, 204, 129, 3, 73, 229, 173, 91, 164, 6, 114, 33, 181, 125, 255, 105, 67, + 67, 222, 166, 141, 27, 151, 0, 143, 55, 129, 233, 60, 169, 222, 155, 0, 246, 29, 149, 235, 189, 54, 241, + 55, 152, 205, 228, 94, 209, 13, 178, 105, 200, 16, 123, 79, 111, 11, 147, 239, 177, 26, 143, 51, 109, 223, + 211, 249, 203, 227, 126, 113, 106, 42, 169, 181, 169, 95, 235, 155, 77, 166, 255, 184, 92, 88, 24, 31, 28, + 28, 140, 190, 255, 154, 32, 246, 247, 38, 9, 98, 127, 111, 168, 202, 245, 94, 171, 252, 49, 215, 175, 174, + 168, 32, 59, 38, 78, 180, 215, 249, 242, 124, 143, 213, 120, 50, 253, 154, 122, 122, 158, 126, 230, 203, + 125, 159, 198, 253, 207, 81, 227, 157, 19, 193, 69, 227, 197, 252, 10, 248, 167, 69, 70, 70, 34, 251, 159, + 2, 211, 185, 96, 83, 132, 166, 254, 94, 71, 122, 251, 46, 243, 199, 92, 31, 181, 253, 3, 175, 204, 179, + 231, 123, 137, 130, 114, 190, 231, 109, 26, 15, 203, 94, 174, 241, 158, 239, 219, 151, 84, 92, 189, 170, + 186, 198, 139, 6, 181, 126, 217, 161, 131, 7, 163, 117, 45, 115, 62, 121, 127, 79, 237, 184, 223, 130, 191, + 61, 215, 135, 51, 255, 104, 108, 44, 129, 36, 148, 108, 100, 123, 122, 82, 190, 135, 26, 143, 124, 142, + 199, 155, 242, 61, 182, 191, 67, 227, 254, 157, 148, 20, 46, 26, 175, 161, 174, 238, 79, 247, 239, 221, + 123, 103, 248, 240, 225, 63, 211, 41, 107, 252, 3, 29, 228, 124, 92, 248, 155, 177, 151, 159, 156, 108, + 247, 251, 245, 93, 40, 223, 99, 249, 183, 136, 251, 179, 94, 182, 207, 115, 213, 212, 212, 168, 206, 223, + 102, 181, 158, 137, 90, 182, 12, 217, 179, 57, 95, 184, 148, 243, 13, 150, 114, 62, 181, 235, 61, 69, 254, + 88, 227, 231, 167, 167, 147, 184, 238, 221, 237, 218, 46, 59, 195, 133, 250, 30, 219, 211, 243, 150, 190, + 142, 146, 239, 211, 184, 143, 26, 111, 102, 223, 62, 164, 156, 83, 220, 183, 212, 215, 215, 101, 100, 100, + 196, 249, 249, 251, 35, 127, 154, 243, 209, 153, 46, 222, 57, 95, 51, 254, 70, 171, 133, 220, 202, 206, 34, + 235, 250, 132, 216, 123, 249, 180, 159, 155, 170, 160, 239, 121, 91, 190, 199, 242, 111, 145, 239, 239, + 222, 205, 101, 158, 11, 106, 253, 191, 193, 63, 247, 132, 135, 135, 35, 251, 159, 40, 228, 124, 142, 102, + 186, 236, 252, 85, 54, 168, 243, 138, 72, 226, 208, 161, 36, 78, 150, 235, 179, 253, 220, 12, 137, 61, 205, + 247, 46, 121, 25, 123, 121, 111, 239, 18, 157, 233, 224, 16, 247, 159, 218, 108, 5, 155, 147, 146, 150, 2, + 251, 197, 240, 254, 29, 229, 124, 24, 247, 91, 104, 252, 60, 248, 111, 29, 55, 78, 156, 223, 147, 229, 250, + 180, 159, 139, 249, 30, 205, 245, 189, 37, 223, 99, 217, 211, 184, 79, 123, 123, 89, 161, 3, 72, 37, 248, + 132, 125, 142, 91, 101, 246, 245, 102, 243, 191, 231, 231, 229, 197, 247, 234, 213, 11, 181, 30, 151, 116, + 62, 94, 252, 237, 186, 190, 208, 124, 126, 143, 230, 250, 222, 214, 207, 85, 98, 207, 198, 125, 212, 120, + 75, 127, 249, 62, 151, 184, 175, 135, 88, 98, 52, 24, 14, 77, 155, 54, 13, 217, 99, 111, 151, 206, 241, + 179, 58, 31, 237, 237, 182, 200, 249, 120, 241, 223, 40, 136, 186, 62, 219, 203, 151, 231, 250, 222, 148, + 239, 177, 252, 229, 249, 254, 229, 5, 11, 184, 232, 251, 246, 184, 223, 208, 80, 148, 156, 156, 28, 5, 236, + 241, 220, 159, 47, 52, 205, 242, 42, 245, 118, 59, 195, 247, 237, 252, 217, 58, 207, 89, 47, 223, 27, 217, + 179, 58, 79, 246, 240, 97, 164, 234, 238, 93, 82, 83, 167, 190, 190, 111, 50, 26, 127, 127, 253, 218, 181, + 196, 254, 253, 251, 163, 239, 191, 14, 239, 125, 142, 208, 84, 235, 43, 245, 118, 121, 230, 124, 205, 248, + 179, 115, 28, 88, 231, 201, 123, 249, 222, 152, 235, 55, 139, 251, 56, 199, 9, 239, 161, 236, 248, 49, 46, + 125, 93, 251, 44, 167, 201, 148, 54, 39, 34, 2, 217, 47, 130, 119, 46, 159, 231, 115, 218, 219, 229, 205, + 159, 214, 121, 71, 36, 246, 74, 186, 190, 55, 156, 249, 44, 127, 170, 241, 209, 184, 127, 61, 102, 57, 209, + 219, 207, 124, 245, 227, 126, 131, 205, 86, 178, 111, 239, 94, 236, 235, 47, 209, 181, 236, 239, 56, 155, + 231, 235, 20, 254, 180, 206, 163, 186, 190, 188, 206, 243, 54, 246, 108, 220, 199, 121, 158, 139, 227, 199, + 139, 115, 156, 42, 239, 238, 72, 113, 255, 15, 55, 139, 138, 146, 66, 67, 67, 151, 234, 154, 207, 244, 200, + 107, 253, 206, 204, 249, 154, 241, 87, 218, 213, 241, 166, 92, 159, 101, 207, 198, 253, 28, 236, 237, 244, + 10, 34, 15, 179, 179, 197, 156, 143, 71, 220, 55, 155, 211, 231, 206, 157, 187, 84, 138, 251, 175, 130, + 253, 0, 108, 162, 32, 206, 244, 40, 237, 111, 117, 70, 206, 215, 140, 191, 210, 110, 182, 156, 189, 183, + 240, 111, 220, 221, 145, 106, 189, 219, 219, 183, 113, 233, 237, 72, 249, 62, 27, 247, 149, 230, 184, 217, + 29, 142, 206, 204, 249, 154, 241, 199, 26, 255, 156, 196, 222, 219, 114, 125, 150, 61, 27, 247, 81, 227, + 43, 156, 27, 73, 106, 140, 124, 52, 62, 140, 251, 69, 55, 110, 108, 14, 29, 48, 96, 169, 130, 198, 43, 159, + 227, 118, 71, 220, 111, 228, 239, 173, 117, 158, 35, 246, 168, 241, 101, 15, 25, 66, 170, 138, 139, 137, + 222, 160, 190, 198, 135, 58, 15, 206, 116, 68, 204, 158, 45, 215, 120, 49, 238, 163, 198, 139, 181, 190, + 187, 227, 126, 35, 127, 111, 103, 223, 172, 167, 143, 103, 190, 159, 159, 189, 214, 211, 115, 168, 245, + 164, 184, 127, 43, 37, 57, 25, 227, 254, 82, 89, 220, 71, 141, 151, 198, 125, 170, 241, 186, 43, 238, 55, + 242, 247, 118, 246, 114, 141, 175, 104, 245, 106, 46, 115, 124, 104, 224, 247, 95, 94, 46, 44, 220, 20, 18, + 18, 178, 76, 22, 247, 149, 246, 119, 220, 25, 247, 27, 249, 123, 91, 157, 199, 242, 151, 215, 122, 249, + 147, 39, 147, 39, 122, 189, 234, 59, 123, 82, 220, 255, 166, 174, 182, 246, 208, 212, 169, 83, 157, 245, + 246, 80, 227, 197, 156, 79, 174, 241, 186, 141, 191, 55, 233, 59, 114, 223, 103, 251, 122, 217, 161, 161, + 164, 226, 218, 53, 46, 243, 28, 82, 220, 191, 188, 121, 243, 230, 104, 39, 113, 159, 157, 231, 114, 119, + 220, 111, 228, 239, 173, 236, 27, 107, 61, 157, 24, 247, 239, 126, 116, 152, 75, 95, 15, 205, 82, 95, 95, + 159, 121, 254, 124, 124, 64, 64, 64, 84, 43, 113, 223, 29, 26, 175, 83, 254, 222, 194, 158, 229, 47, 63, + 243, 111, 196, 74, 119, 51, 113, 232, 235, 65, 204, 255, 107, 85, 101, 101, 234, 216, 177, 99, 163, 24, + 157, 71, 41, 238, 43, 245, 246, 124, 252, 57, 176, 103, 207, 252, 130, 201, 47, 217, 107, 124, 30, 103, 62, + 106, 124, 54, 171, 245, 243, 232, 168, 40, 140, 251, 75, 224, 125, 82, 125, 95, 174, 243, 96, 220, 87, 220, + 219, 212, 2, 127, 119, 179, 83, 139, 61, 123, 230, 231, 216, 207, 252, 1, 164, 226, 58, 191, 51, 31, 216, + 87, 166, 167, 167, 175, 2, 246, 81, 140, 190, 175, 69, 157, 199, 33, 127, 119, 179, 83, 147, 61, 123, 230, + 159, 247, 19, 72, 217, 145, 35, 82, 95, 79, 125, 246, 38, 163, 241, 143, 197, 119, 238, 108, 29, 252, 236, + 179, 200, 30, 103, 184, 177, 175, 235, 76, 223, 215, 82, 220, 247, 10, 254, 138, 117, 190, 32, 234, 187, + 55, 19, 226, 185, 229, 123, 168, 241, 1, 255, 244, 200, 200, 72, 251, 60, 15, 188, 71, 188, 171, 65, 190, + 183, 167, 37, 157, 199, 171, 249, 203, 207, 252, 66, 220, 219, 48, 212, 113, 57, 243, 209, 160, 214, 187, + 190, 109, 235, 214, 24, 96, 143, 58, 15, 238, 238, 224, 60, 15, 189, 171, 97, 132, 32, 246, 117, 181, 28, + 247, 61, 158, 191, 156, 61, 173, 243, 115, 195, 134, 147, 170, 146, 82, 46, 243, 187, 104, 82, 173, 183, + 62, 48, 48, 48, 154, 153, 227, 164, 243, 60, 236, 93, 13, 74, 250, 190, 143, 191, 138, 236, 229, 115, 92, + 153, 129, 129, 228, 193, 217, 51, 68, 111, 225, 163, 237, 27, 234, 234, 254, 183, 162, 188, 252, 189, 49, + 99, 198, 32, 251, 183, 4, 81, 227, 155, 33, 56, 222, 221, 81, 220, 217, 213, 0, 119, 143, 229, 175, 152, + 239, 73, 103, 126, 241, 187, 124, 118, 53, 209, 164, 251, 121, 50, 222, 124, 227, 13, 187, 198, 7, 239, 14, + 53, 190, 217, 130, 56, 191, 47, 159, 227, 164, 247, 115, 41, 238, 237, 105, 128, 187, 199, 243, 151, 247, + 243, 175, 255, 236, 45, 241, 62, 54, 14, 26, 143, 116, 230, 127, 177, 111, 223, 190, 88, 192, 23, 205, 104, + 124, 244, 110, 54, 246, 158, 14, 186, 187, 227, 112, 111, 79, 3, 220, 61, 146, 191, 163, 217, 237, 130, + 201, 47, 218, 185, 243, 152, 225, 147, 206, 124, 220, 219, 73, 234, 221, 187, 247, 114, 217, 44, 23, 213, + 248, 232, 252, 190, 195, 57, 78, 31, 127, 117, 227, 62, 213, 120, 114, 135, 12, 33, 149, 183, 110, 146, 26, + 78, 26, 143, 164, 239, 238, 159, 48, 97, 66, 180, 66, 173, 215, 38, 141, 79, 254, 104, 128, 187, 71, 241, + 119, 148, 239, 101, 5, 6, 144, 251, 167, 78, 113, 155, 229, 176, 235, 187, 22, 203, 153, 183, 22, 47, 70, + 191, 143, 130, 247, 165, 84, 235, 41, 105, 124, 78, 247, 181, 53, 192, 221, 99, 248, 43, 229, 123, 23, 117, + 98, 157, 95, 242, 222, 110, 110, 249, 158, 116, 230, 223, 61, 176, 127, 127, 28, 32, 67, 254, 120, 63, 15, + 222, 199, 138, 59, 123, 242, 221, 13, 197, 189, 45, 71, 143, 6, 184, 123, 28, 127, 185, 198, 115, 99, 249, + 114, 209, 239, 57, 229, 123, 112, 230, 63, 189, 120, 225, 66, 98, 239, 224, 224, 24, 233, 204, 167, 181, + 30, 221, 217, 83, 170, 245, 218, 116, 79, 135, 6, 184, 123, 4, 127, 121, 95, 135, 230, 123, 133, 179, 102, + 218, 115, 61, 94, 250, 158, 84, 231, 239, 29, 251, 252, 243, 246, 249, 109, 65, 236, 235, 177, 243, 28, 97, + 66, 243, 239, 223, 112, 233, 142, 22, 13, 112, 215, 60, 127, 214, 239, 217, 187, 183, 47, 142, 252, 174, + 120, 255, 46, 39, 125, 15, 181, 125, 240, 253, 19, 175, 47, 92, 168, 116, 230, 211, 190, 30, 91, 235, 33, + 123, 151, 238, 104, 209, 0, 119, 77, 243, 119, 148, 239, 229, 244, 235, 71, 202, 243, 243, 185, 236, 235, + 48, 103, 254, 205, 237, 219, 182, 197, 74, 103, 62, 187, 167, 79, 245, 221, 86, 231, 57, 124, 252, 213, 99, + 79, 251, 185, 89, 221, 187, 145, 123, 199, 142, 114, 235, 231, 162, 217, 172, 86, 99, 198, 169, 83, 235, + 123, 246, 236, 137, 103, 62, 157, 225, 156, 33, 136, 103, 62, 171, 239, 178, 181, 158, 203, 247, 178, 105, + 128, 187, 230, 249, 55, 222, 187, 46, 229, 250, 197, 59, 119, 18, 61, 199, 92, 223, 100, 52, 254, 119, 73, + 113, 241, 174, 97, 195, 134, 33, 123, 71, 103, 190, 42, 119, 176, 107, 128, 187, 38, 249, 183, 200, 245, 5, + 145, 125, 81, 12, 223, 92, 191, 86, 175, 255, 123, 93, 109, 237, 71, 63, 152, 54, 13, 217, 71, 9, 202, 103, + 62, 214, 249, 142, 244, 93, 31, 127, 181, 217, 251, 137, 185, 254, 21, 220, 211, 51, 24, 184, 229, 250, + 210, 12, 95, 246, 138, 152, 152, 21, 128, 102, 57, 188, 19, 121, 157, 175, 202, 153, 239, 227, 223, 58, + 123, 54, 223, 195, 92, 191, 96, 98, 56, 121, 92, 94, 206, 229, 206, 117, 38, 223, 43, 59, 176, 127, 255, + 106, 192, 66, 235, 124, 118, 126, 87, 94, 231, 171, 242, 221, 27, 26, 224, 174, 25, 254, 142, 116, 253, + 139, 195, 135, 145, 202, 155, 55, 85, 255, 62, 101, 214, 172, 22, 139, 53, 243, 252, 249, 196, 160, 160, + 32, 244, 125, 86, 219, 167, 243, 187, 244, 30, 94, 121, 157, 223, 161, 251, 56, 53, 192, 93, 19, 252, 29, + 237, 104, 230, 244, 9, 33, 143, 240, 94, 6, 14, 223, 175, 197, 228, 123, 255, 83, 90, 82, 146, 18, 22, 22, + 134, 236, 177, 159, 79, 239, 227, 195, 123, 153, 228, 218, 126, 187, 234, 124, 31, 127, 215, 216, 99, 157, + 151, 221, 163, 59, 185, 135, 251, 185, 156, 118, 52, 209, 32, 215, 251, 59, 228, 124, 105, 211, 167, 79, + 71, 246, 209, 240, 30, 240, 78, 46, 218, 207, 167, 247, 241, 57, 211, 246, 125, 252, 85, 98, 223, 56, 183, + 171, 19, 243, 189, 210, 212, 61, 92, 235, 60, 41, 223, 59, 31, 21, 21, 181, 18, 80, 196, 192, 59, 96, 103, + 248, 216, 29, 125, 249, 153, 175, 218, 253, 235, 26, 224, 238, 54, 254, 114, 246, 246, 26, 95, 170, 243, + 110, 111, 220, 32, 234, 59, 156, 234, 60, 41, 223, 187, 179, 115, 231, 78, 220, 217, 64, 223, 103, 251, 58, + 116, 134, 207, 229, 126, 190, 143, 191, 235, 252, 217, 26, 31, 253, 254, 198, 210, 37, 68, 95, 111, 225, + 114, 31, 11, 181, 6, 155, 77, 255, 219, 207, 62, 219, 208, 179, 103, 79, 244, 125, 154, 239, 41, 105, 60, + 142, 250, 249, 62, 254, 42, 250, 61, 230, 250, 200, 254, 234, 43, 243, 164, 26, 159, 207, 252, 22, 154, + 165, 190, 254, 247, 87, 175, 92, 217, 246, 173, 129, 3, 145, 61, 155, 239, 57, 234, 235, 40, 222, 195, 170, + 198, 163, 1, 238, 110, 227, 47, 159, 215, 47, 252, 254, 20, 241, 254, 61, 149, 191, 79, 147, 53, 163, 193, + 240, 231, 135, 15, 30, 28, 24, 59, 118, 44, 178, 143, 22, 90, 230, 123, 242, 89, 14, 158, 223, 185, 226, + 110, 230, 157, 206, 95, 41, 215, 199, 26, 191, 96, 252, 56, 82, 125, 255, 62, 209, 115, 234, 229, 162, 65, + 158, 255, 13, 240, 63, 30, 49, 123, 54, 178, 71, 125, 175, 173, 249, 30, 175, 239, 92, 113, 55, 243, 78, + 229, 239, 168, 198, 207, 251, 246, 8, 82, 117, 251, 22, 87, 125, 135, 106, 187, 144, 235, 99, 63, 119, 5, + 124, 94, 170, 239, 205, 16, 154, 231, 123, 244, 110, 14, 165, 89, 14, 31, 127, 149, 217, 95, 120, 118, 16, + 41, 47, 188, 196, 85, 223, 65, 195, 187, 184, 118, 236, 216, 129, 218, 46, 250, 62, 238, 235, 176, 250, + 158, 188, 167, 71, 243, 61, 158, 223, 183, 211, 101, 248, 59, 98, 159, 219, 183, 15, 121, 152, 153, 201, + 109, 102, 151, 26, 228, 250, 85, 31, 167, 165, 173, 247, 247, 247, 71, 223, 199, 126, 46, 221, 215, 145, + 235, 123, 170, 244, 244, 124, 252, 29, 179, 199, 124, 15, 181, 189, 156, 103, 122, 145, 7, 39, 126, 199, + 109, 47, 155, 154, 213, 98, 177, 101, 103, 101, 189, 29, 210, 187, 55, 178, 95, 38, 52, 245, 115, 233, 157, + 60, 92, 245, 189, 174, 204, 95, 169, 206, 179, 179, 15, 8, 32, 247, 142, 28, 225, 58, 175, 141, 86, 111, + 54, 255, 231, 205, 162, 162, 148, 231, 158, 123, 206, 190, 171, 37, 52, 229, 250, 74, 253, 92, 151, 103, + 119, 125, 252, 93, 243, 123, 212, 117, 179, 253, 253, 201, 221, 15, 62, 32, 181, 79, 159, 114, 101, 143, + 117, 94, 249, 163, 71, 31, 132, 135, 135, 35, 123, 86, 219, 165, 187, 90, 180, 159, 203, 85, 223, 235, 138, + 252, 21, 117, 93, 157, 88, 227, 151, 238, 77, 229, 238, 247, 216, 211, 1, 59, 54, 107, 214, 44, 154, 235, + 227, 157, 44, 108, 174, 207, 173, 159, 219, 213, 249, 43, 177, 207, 147, 216, 151, 236, 218, 201, 237, 238, + 53, 106, 210, 204, 246, 185, 197, 139, 22, 225, 174, 206, 74, 248, 92, 56, 187, 137, 223, 177, 68, 247, + 244, 228, 218, 174, 210, 247, 235, 249, 248, 119, 144, 191, 156, 125, 241, 219, 91, 196, 94, 30, 71, 246, + 88, 227, 67, 174, 127, 41, 33, 62, 30, 235, 60, 244, 125, 86, 215, 199, 221, 124, 154, 235, 59, 211, 118, + 59, 141, 189, 55, 241, 119, 230, 247, 119, 146, 18, 185, 206, 108, 82, 131, 26, 191, 56, 37, 57, 121, 29, + 188, 86, 244, 125, 122, 47, 3, 171, 235, 203, 115, 253, 78, 207, 247, 188, 157, 191, 188, 151, 119, 135, + 246, 113, 57, 246, 242, 36, 246, 21, 135, 15, 31, 222, 208, 173, 91, 55, 100, 79, 235, 60, 188, 131, 143, + 213, 245, 149, 114, 125, 183, 248, 189, 183, 240, 119, 230, 247, 183, 86, 197, 138, 186, 30, 103, 246, 16, + 243, 141, 39, 79, 156, 216, 28, 20, 20, 100, 191, 127, 81, 104, 89, 231, 57, 211, 245, 59, 53, 223, 243, + 86, 254, 172, 223, 219, 217, 199, 137, 236, 121, 205, 106, 83, 179, 89, 173, 79, 115, 115, 114, 182, 246, + 235, 215, 207, 190, 155, 45, 136, 51, 219, 108, 157, 135, 236, 229, 117, 158, 91, 114, 125, 111, 226, 175, + 232, 247, 50, 246, 79, 56, 179, 135, 60, 255, 15, 215, 175, 93, 75, 25, 58, 116, 40, 178, 167, 53, 62, 222, + 189, 137, 51, 219, 116, 79, 139, 246, 116, 28, 233, 250, 62, 254, 46, 242, 111, 149, 125, 125, 61, 119, + 191, 55, 155, 76, 95, 149, 150, 150, 238, 27, 57, 114, 164, 125, 126, 75, 16, 107, 124, 118, 126, 139, 214, + 248, 242, 58, 79, 51, 236, 61, 145, 191, 115, 246, 113, 157, 18, 243, 77, 70, 227, 159, 31, 61, 124, 120, + 112, 98, 120, 184, 82, 141, 143, 253, 60, 122, 7, 155, 91, 122, 58, 93, 129, 63, 155, 235, 225, 252, 198, + 237, 248, 117, 157, 226, 247, 70, 131, 225, 235, 199, 213, 213, 71, 166, 78, 153, 130, 126, 31, 11, 191, + 55, 237, 229, 202, 107, 124, 202, 190, 211, 123, 58, 174, 60, 26, 224, 222, 38, 254, 78, 235, 251, 196, + 196, 78, 169, 241, 164, 89, 253, 79, 231, 204, 153, 131, 236, 227, 224, 119, 70, 125, 7, 119, 115, 105, 47, + 151, 206, 238, 105, 170, 198, 119, 246, 104, 128, 123, 171, 252, 29, 177, 207, 97, 181, 29, 254, 236, 255, + 1, 190, 127, 106, 193, 107, 175, 161, 182, 135, 252, 105, 31, 159, 234, 59, 216, 203, 165, 179, 123, 110, + 235, 231, 185, 250, 104, 128, 187, 83, 254, 206, 216, 151, 236, 216, 222, 41, 126, 15, 62, 143, 249, 222, + 249, 197, 139, 22, 173, 209, 137, 236, 233, 204, 46, 237, 227, 59, 211, 119, 184, 206, 111, 117, 244, 209, + 0, 119, 135, 252, 29, 245, 241, 114, 252, 253, 73, 105, 74, 50, 247, 253, 12, 202, 222, 106, 177, 228, 68, + 45, 91, 134, 236, 209, 247, 145, 61, 171, 237, 209, 62, 62, 213, 119, 228, 189, 92, 183, 215, 248, 206, 30, + 13, 112, 87, 228, 239, 144, 125, 247, 110, 228, 238, 251, 239, 139, 253, 123, 206, 236, 165, 94, 94, 126, + 92, 108, 236, 90, 157, 200, 30, 117, 93, 86, 219, 163, 51, 187, 172, 190, 195, 109, 87, 131, 199, 163, 1, + 238, 45, 248, 59, 154, 221, 200, 13, 12, 32, 247, 210, 62, 226, 222, 191, 167, 236, 27, 108, 182, 203, 9, + 9, 9, 44, 123, 122, 215, 50, 157, 215, 102, 103, 56, 88, 125, 199, 35, 216, 227, 163, 1, 238, 205, 248, 59, + 242, 251, 11, 33, 189, 201, 131, 207, 62, 229, 246, 125, 169, 10, 236, 175, 39, 37, 38, 38, 232, 68, 246, + 209, 18, 123, 249, 252, 142, 166, 181, 189, 182, 60, 26, 224, 222, 200, 223, 209, 30, 118, 94, 232, 0, 242, + 240, 220, 89, 174, 247, 109, 177, 236, 109, 86, 235, 245, 164, 164, 164, 120, 120, 61, 120, 230, 35, 123, + 86, 211, 151, 235, 186, 236, 126, 158, 71, 177, 199, 71, 3, 220, 91, 240, 103, 231, 116, 243, 135, 15, 19, + 239, 217, 227, 60, 163, 141, 38, 237, 104, 220, 0, 246, 232, 247, 44, 123, 86, 211, 247, 8, 93, 183, 173, + 143, 6, 184, 55, 227, 207, 206, 231, 95, 26, 51, 154, 84, 22, 21, 113, 223, 205, 160, 236, 113, 31, 123, + 199, 246, 237, 200, 30, 207, 124, 186, 159, 69, 217, 83, 77, 63, 172, 45, 236, 125, 230, 58, 127, 150, 253, + 229, 23, 39, 217, 239, 86, 229, 185, 147, 197, 198, 124, 96, 95, 146, 188, 107, 215, 6, 157, 232, 247, 44, + 251, 25, 10, 236, 157, 106, 250, 62, 107, 31, 255, 2, 65, 212, 117, 174, 69, 206, 33, 143, 43, 43, 185, + 221, 171, 171, 112, 222, 23, 109, 217, 178, 101, 189, 196, 158, 246, 113, 217, 121, 93, 58, 179, 201, 246, + 115, 232, 94, 174, 86, 191, 79, 205, 211, 204, 206, 190, 232, 205, 159, 146, 154, 186, 90, 174, 247, 172, + 177, 236, 33, 207, 191, 33, 229, 249, 148, 61, 59, 171, 77, 231, 117, 71, 8, 77, 51, 155, 90, 254, 14, 77, + 79, 54, 114, 103, 221, 90, 123, 188, 231, 245, 221, 57, 10, 126, 79, 107, 188, 181, 50, 246, 51, 37, 246, + 207, 75, 236, 209, 239, 229, 251, 248, 62, 191, 87, 153, 127, 103, 104, 249, 104, 168, 233, 34, 251, 68, + 231, 236, 89, 191, 151, 247, 242, 124, 126, 207, 129, 63, 111, 61, 151, 178, 183, 90, 44, 5, 113, 177, 177, + 241, 109, 240, 123, 37, 246, 205, 52, 125, 159, 169, 200, 159, 51, 251, 58, 56, 87, 234, 205, 230, 252, + 149, 43, 86, 116, 132, 61, 125, 220, 253, 190, 188, 205, 184, 179, 55, 155, 76, 89, 139, 23, 47, 94, 199, + 212, 247, 174, 196, 124, 45, 127, 119, 174, 55, 24, 55, 246, 134, 186, 186, 111, 192, 206, 190, 190, 112, + 97, 188, 76, 219, 105, 143, 223, 251, 216, 123, 16, 127, 147, 209, 248, 55, 248, 231, 137, 87, 230, 205, + 91, 167, 192, 126, 134, 224, 243, 123, 173, 152, 234, 236, 33, 222, 255, 165, 162, 188, 252, 55, 51, 166, + 79, 71, 238, 107, 225, 255, 209, 30, 246, 236, 227, 238, 119, 228, 205, 166, 42, 123, 200, 243, 254, 84, + 86, 86, 150, 246, 194, 11, 47, 80, 246, 209, 66, 243, 94, 14, 213, 245, 124, 236, 181, 97, 170, 177, 135, + 250, 238, 143, 183, 111, 221, 250, 213, 152, 49, 99, 144, 253, 26, 248, 217, 81, 66, 83, 15, 23, 217, 179, + 126, 207, 206, 105, 251, 98, 190, 135, 243, 183, 89, 173, 95, 22, 228, 231, 239, 13, 11, 11, 91, 39, 177, + 167, 115, 59, 148, 61, 219, 203, 113, 196, 158, 125, 220, 253, 94, 186, 138, 117, 152, 253, 211, 134, 6, + 235, 153, 211, 167, 147, 67, 67, 67, 89, 246, 56, 175, 135, 223, 161, 67, 103, 55, 90, 99, 239, 243, 123, + 15, 227, 47, 245, 238, 107, 142, 166, 167, 111, 13, 14, 14, 70, 246, 171, 224, 231, 45, 149, 177, 255, 158, + 208, 124, 118, 195, 231, 247, 218, 178, 118, 177, 151, 122, 120, 247, 83, 83, 83, 183, 244, 232, 209, 131, + 178, 199, 221, 12, 156, 209, 166, 115, 186, 116, 94, 143, 101, 79, 251, 247, 84, 207, 247, 105, 186, 30, + 198, 95, 210, 242, 139, 18, 19, 19, 55, 1, 119, 212, 118, 226, 36, 246, 184, 155, 17, 41, 52, 205, 104, + 211, 89, 77, 118, 110, 71, 177, 143, 167, 177, 153, 168, 174, 100, 46, 177, 55, 26, 12, 120, 151, 118, 238, + 178, 101, 203, 54, 72, 236, 113, 23, 19, 247, 241, 112, 39, 11, 247, 114, 232, 110, 6, 59, 167, 219, 166, + 121, 61, 13, 188, 139, 174, 104, 109, 102, 111, 54, 153, 190, 174, 174, 170, 58, 249, 195, 185, 115, 227, + 37, 246, 184, 131, 141, 123, 184, 184, 139, 137, 251, 120, 83, 132, 166, 123, 87, 134, 58, 96, 239, 112, + 39, 79, 3, 239, 162, 43, 90, 155, 216, 91, 234, 235, 191, 42, 41, 46, 254, 120, 210, 164, 73, 118, 246, + 240, 231, 232, 93, 234, 184, 131, 141, 123, 184, 116, 23, 147, 238, 100, 177, 187, 25, 109, 154, 211, 213, + 192, 187, 232, 138, 214, 42, 123, 200, 243, 190, 204, 207, 203, 219, 63, 98, 196, 8, 100, 191, 14, 254, 12, + 237, 223, 226, 189, 27, 184, 127, 255, 146, 208, 180, 135, 43, 103, 223, 230, 249, 124, 13, 188, 139, 174, + 104, 173, 213, 119, 134, 79, 63, 249, 100, 87, 255, 254, 253, 227, 25, 61, 151, 237, 225, 209, 187, 23, + 240, 142, 61, 220, 195, 165, 187, 152, 46, 239, 102, 104, 224, 93, 116, 69, 115, 152, 227, 131, 223, 151, + 189, 183, 123, 247, 207, 161, 190, 139, 151, 233, 185, 116, 62, 155, 246, 111, 233, 221, 11, 116, 7, 187, + 93, 123, 57, 26, 120, 23, 93, 209, 90, 176, 55, 212, 213, 253, 3, 114, 189, 194, 85, 113, 113, 88, 223, 37, + 56, 208, 117, 228, 125, 28, 202, 94, 233, 158, 53, 65, 3, 159, 211, 103, 109, 224, 95, 111, 54, 255, 181, + 178, 162, 34, 227, 213, 87, 95, 93, 47, 177, 103, 107, 123, 186, 131, 43, 215, 115, 251, 9, 142, 239, 87, + 244, 177, 215, 182, 177, 61, 156, 255, 42, 42, 42, 58, 28, 30, 30, 142, 241, 62, 1, 254, 29, 173, 239, 216, + 218, 30, 117, 29, 220, 195, 116, 166, 231, 250, 216, 123, 142, 209, 60, 207, 114, 58, 35, 227, 189, 65, + 131, 6, 37, 48, 57, 62, 222, 175, 134, 245, 157, 188, 182, 87, 210, 244, 124, 236, 61, 211, 72, 131, 213, + 250, 32, 117, 207, 158, 119, 130, 130, 130, 18, 152, 121, 29, 172, 239, 240, 110, 61, 182, 190, 195, 218, + 94, 73, 215, 241, 245, 113, 60, 215, 10, 86, 196, 196, 36, 2, 247, 245, 10, 57, 254, 76, 65, 188, 87, 17, + 239, 87, 83, 170, 237, 125, 251, 88, 158, 111, 255, 15, 143, 115, 206, 4, 131, 53, 15, 6, 0, 0, 4, 23, 109, + 107, 66, 84, 250, 206, 202, 254, 0, 127, 135, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 153, 81, 109, 43, 49, 16, 69, 11, 33, 16, 2, 33, 16, + 2, 161, 16, 2, 33, 16, 2, 161, 16, 10, 161, 16, 10, 96, 63, 2, 161, 16, 202, 32, 175, 150, 98, 201, 239, + 246, 142, 61, 222, 172, 170, 234, 189, 115, 165, 243, 211, 204, 206, 204, 122, 236, 177, 215, 125, 122, 66, + 8, 33, 132, 16, 66, 8, 33, 132, 208, 191, 174, 247, 101, 89, 90, 50, 54, 51, 28, 196, 231, 62, 176, 115, + 113, 95, 196, 230, 53, 176, 43, 122, 53, 62, 119, 129, 253, 69, 236, 94, 140, 221, 76, 158, 173, 14, 147, + 227, 83, 114, 121, 78, 248, 45, 239, 114, 254, 226, 45, 225, 115, 228, 171, 213, 237, 203, 190, 229, 100, + 158, 87, 155, 25, 142, 226, 239, 18, 216, 185, 184, 103, 99, 183, 15, 106, 229, 124, 70, 227, 250, 41, 118, + 110, 94, 205, 228, 217, 234, 184, 114, 156, 174, 157, 249, 90, 222, 67, 115, 238, 209, 203, 79, 165, 207, + 186, 249, 179, 101, 253, 163, 247, 112, 113, 93, 93, 221, 248, 159, 2, 159, 110, 93, 31, 146, 243, 100, 38, + 207, 86, 107, 235, 95, 231, 128, 250, 123, 94, 225, 167, 151, 159, 202, 61, 175, 107, 204, 245, 152, 15, + 121, 230, 211, 216, 104, 255, 143, 234, 212, 91, 219, 87, 177, 121, 51, 54, 175, 129, 191, 15, 99, 251, 98, + 242, 86, 155, 53, 121, 86, 185, 250, 103, 198, 207, 205, 197, 221, 18, 175, 251, 107, 224, 247, 209, 254, + 95, 232, 237, 179, 85, 218, 31, 51, 113, 223, 7, 227, 234, 226, 186, 61, 64, 109, 122, 189, 81, 107, 165, + 243, 201, 197, 92, 147, 103, 149, 171, 127, 100, 251, 102, 108, 47, 141, 189, 219, 131, 174, 131, 249, 55, + 43, 247, 126, 101, 60, 163, 189, 40, 202, 109, 84, 255, 104, 143, 30, 197, 117, 207, 181, 107, 196, 245, + 243, 150, 115, 99, 59, 242, 245, 72, 158, 85, 51, 245, 119, 182, 109, 253, 93, 143, 24, 213, 101, 86, 117, + 140, 52, 206, 232, 156, 51, 91, 127, 215, 163, 179, 113, 123, 107, 54, 58, 167, 85, 218, 253, 194, 245, + 117, 29, 207, 71, 242, 44, 154, 169, 191, 203, 167, 214, 127, 103, 126, 155, 237, 237, 25, 85, 159, 58, + 215, 220, 89, 164, 213, 76, 253, 221, 62, 54, 19, 87, 99, 181, 251, 186, 246, 234, 222, 254, 174, 253, 86, + 207, 18, 143, 230, 89, 228, 234, 127, 52, 156, 76, 172, 66, 61, 47, 57, 63, 209, 25, 235, 145, 253, 191, + 246, 63, 183, 142, 244, 236, 222, 171, 73, 47, 174, 155, 231, 51, 113, 93, 143, 47, 127, 115, 107, 100, + 191, 124, 63, 91, 85, 127, 163, 53, 252, 104, 158, 81, 221, 178, 180, 99, 248, 136, 159, 92, 229, 255, 150, + 219, 247, 122, 231, 156, 153, 250, 107, 255, 110, 215, 111, 54, 174, 214, 244, 114, 175, 141, 91, 147, 218, + 195, 157, 237, 109, 249, 222, 251, 183, 200, 115, 109, 221, 244, 251, 255, 167, 234, 223, 246, 13, 215, + 143, 122, 119, 104, 153, 250, 103, 250, 88, 38, 174, 246, 245, 235, 125, 252, 219, 191, 213, 239, 125, 55, + 47, 212, 86, 123, 255, 86, 121, 174, 173, 155, 222, 85, 252, 84, 255, 31, 229, 117, 14, 252, 101, 235, 239, + 206, 83, 25, 52, 174, 219, 3, 162, 62, 239, 246, 5, 181, 213, 222, 191, 85, 158, 163, 253, 255, 121, 249, + 126, 70, 169, 92, 196, 151, 123, 135, 153, 218, 102, 52, 122, 191, 40, 102, 166, 254, 174, 14, 89, 92, 92, + 247, 61, 212, 174, 141, 214, 86, 207, 133, 189, 117, 187, 101, 158, 217, 243, 191, 155, 207, 250, 14, 186, + 31, 181, 115, 124, 43, 105, 239, 112, 61, 206, 221, 143, 102, 234, 239, 190, 155, 62, 22, 223, 179, 50, + 113, 163, 117, 83, 208, 126, 238, 98, 71, 185, 110, 153, 103, 182, 254, 69, 238, 254, 167, 173, 175, 203, + 171, 196, 47, 99, 175, 255, 87, 219, 74, 238, 156, 235, 238, 92, 51, 245, 119, 235, 53, 250, 159, 76, 38, + 110, 239, 174, 71, 251, 121, 207, 86, 123, 246, 150, 121, 206, 212, 127, 244, 77, 177, 91, 226, 123, 226, + 30, 81, 188, 140, 162, 94, 184, 23, 191, 163, 250, 187, 243, 118, 111, 255, 202, 198, 141, 238, 122, 213, + 174, 40, 26, 187, 214, 118, 235, 60, 103, 234, 239, 98, 187, 115, 79, 239, 126, 123, 235, 250, 23, 185, + 179, 144, 158, 77, 70, 245, 119, 189, 45, 58, 75, 206, 196, 117, 54, 209, 93, 76, 198, 118, 235, 60, 103, + 234, 239, 108, 245, 59, 160, 104, 127, 31, 223, 159, 170, 255, 254, 254, 62, 45, 218, 95, 143, 131, 223, + 79, 198, 199, 232, 238, 58, 19, 247, 96, 108, 162, 51, 81, 198, 118, 235, 60, 221, 111, 61, 95, 163, 247, + 213, 184, 58, 238, 142, 94, 60, 132, 16, 66, 8, 33, 132, 16, 66, 8, 33, 132, 208, 127, 164, 219, 237, 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, 240, 219, 248, 3, 137, 186, 94, 16, 41, 87, 148, 10, 0, + 0, 24, 237, 109, 107, 66, 84, 250, 206, 202, 254, 0, 127, 137, 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, 120, 156, 237, 157, 11, 120, 140, 215, 186, 199, + 103, 154, 184, 228, 144, 244, 168, 75, 181, 72, 67, 57, 167, 45, 91, 123, 78, 181, 61, 231, 164, 216, 85, + 234, 210, 170, 77, 107, 23, 69, 17, 151, 168, 150, 237, 114, 74, 247, 57, 117, 217, 46, 27, 213, 10, 33, + 34, 9, 137, 72, 144, 68, 92, 82, 74, 176, 85, 244, 130, 77, 80, 33, 9, 114, 35, 145, 43, 185, 186, 235, 62, + 235, 188, 239, 154, 181, 146, 229, 51, 51, 194, 183, 102, 86, 38, 153, 121, 158, 255, 227, 121, 246, 147, + 61, 243, 117, 126, 239, 247, 127, 47, 107, 125, 107, 12, 132, 16, 131, 106, 93, 185, 114, 197, 208, 168, + 81, 35, 3, 190, 140, 70, 227, 163, 10, 95, 79, 128, 234, 131, 26, 131, 154, 129, 60, 65, 47, 129, 254, 3, + 244, 22, 188, 237, 220, 222, 189, 123, 147, 123, 247, 238, 145, 138, 138, 10, 82, 94, 94, 174, 75, 55, 110, + 221, 34, 249, 89, 89, 100, 126, 179, 102, 100, 182, 193, 64, 254, 10, 250, 26, 244, 45, 104, 5, 211, 74, + 199, 144, 114, 246, 18, 249, 215, 3, 253, 19, 232, 41, 80, 43, 208, 191, 130, 94, 3, 245, 128, 183, 29, + 213, 178, 101, 203, 210, 236, 236, 108, 114, 227, 198, 13, 82, 86, 86, 166, 75, 52, 6, 238, 220, 33, 65, + 61, 123, 146, 63, 51, 254, 203, 64, 126, 236, 123, 245, 7, 173, 114, 12, 41, 103, 47, 129, 191, 129, 241, + 119, 5, 185, 129, 254, 25, 244, 12, 168, 61, 232, 223, 64, 191, 135, 183, 125, 15, 244, 107, 124, 124, 60, + 245, 0, 189, 252, 81, 183, 225, 194, 247, 206, 155, 71, 102, 194, 87, 184, 144, 221, 255, 203, 157, 252, + 85, 241, 199, 151, 11, 168, 33, 200, 3, 244, 52, 168, 45, 168, 51, 168, 43, 232, 109, 120, 235, 77, 179, + 103, 207, 38, 248, 42, 43, 45, 213, 173, 155, 119, 239, 146, 115, 251, 247, 211, 251, 127, 62, 104, 137, + 161, 202, 255, 253, 29, 39, 6, 148, 179, 151, 200, 223, 82, 13, 240, 159, 44, 7, 204, 238, 9, 126, 125, + 231, 246, 109, 82, 142, 247, 176, 78, 254, 21, 215, 175, 147, 171, 185, 185, 100, 137, 167, 39, 153, 3, 95, + 227, 98, 208, 55, 78, 254, 170, 248, 243, 28, 128, 53, 64, 35, 86, 3, 180, 214, 212, 0, 35, 159, 126, 250, + 233, 146, 44, 168, 219, 176, 6, 40, 5, 134, 122, 117, 3, 114, 201, 134, 65, 131, 42, 107, 0, 204, 1, 14, + 86, 3, 40, 103, 47, 241, 254, 55, 90, 169, 1, 176, 7, 232, 7, 74, 220, 185, 115, 39, 185, 7, 222, 93, 90, + 82, 162, 91, 183, 254, 241, 15, 114, 104, 197, 10, 50, 203, 80, 85, 3, 248, 105, 216, 175, 174, 217, 82, + 206, 94, 214, 253, 111, 250, 191, 62, 180, 6, 8, 159, 249, 197, 23, 132, 0, 55, 25, 252, 175, 67, 31, 152, + 126, 236, 24, 153, 83, 175, 30, 173, 1, 150, 26, 170, 106, 64, 39, 127, 37, 252, 121, 13, 224, 46, 212, 0, + 29, 89, 13, 128, 252, 103, 117, 237, 218, 181, 210, 255, 75, 128, 161, 30, 149, 66, 29, 129, 255, 174, 232, + 220, 153, 206, 1, 180, 53, 160, 147, 191, 18, 254, 214, 230, 0, 67, 159, 124, 242, 201, 252, 212, 212, 84, + 26, 3, 122, 249, 163, 110, 130, 151, 196, 250, 250, 62, 48, 7, 112, 242, 183, 59, 127, 124, 89, 154, 3, + 252, 59, 214, 0, 160, 190, 240, 55, 63, 70, 70, 68, 208, 26, 160, 164, 184, 88, 183, 110, 192, 251, 156, + 216, 178, 133, 242, 215, 206, 1, 28, 32, 7, 40, 103, 47, 153, 191, 182, 6, 104, 97, 166, 6, 88, 51, 126, + 252, 120, 242, 219, 111, 191, 145, 98, 224, 167, 87, 101, 21, 21, 36, 231, 226, 69, 178, 176, 105, 83, 242, + 23, 195, 131, 53, 0, 126, 207, 1, 53, 87, 202, 217, 219, 128, 191, 181, 181, 0, 228, 63, 185, 99, 199, 142, + 119, 175, 93, 187, 70, 107, 0, 221, 49, 0, 57, 160, 252, 230, 77, 18, 210, 171, 23, 249, 202, 80, 85, 3, + 56, 249, 43, 225, 47, 206, 1, 204, 213, 0, 200, 255, 195, 122, 245, 234, 101, 28, 59, 122, 148, 220, 132, + 26, 160, 24, 226, 64, 175, 112, 14, 176, 127, 209, 162, 202, 26, 128, 207, 129, 68, 239, 175, 1, 172, 235, + 2, 127, 35, 123, 137, 53, 64, 75, 163, 176, 22, 0, 122, 7, 254, 110, 183, 159, 159, 31, 93, 11, 64, 31, + 208, 171, 50, 136, 163, 243, 63, 253, 68, 230, 184, 184, 60, 48, 7, 112, 242, 183, 239, 253, 47, 212, 0, + 13, 140, 166, 62, 16, 107, 0, 47, 208, 239, 64, 111, 130, 122, 194, 223, 44, 30, 48, 96, 0, 185, 125, 251, + 182, 20, 254, 152, 3, 174, 22, 21, 17, 191, 151, 94, 34, 115, 13, 85, 53, 0, 231, 143, 223, 245, 154, 154, + 41, 229, 236, 109, 196, 223, 90, 13, 128, 252, 125, 90, 183, 110, 93, 126, 249, 210, 37, 58, 203, 191, 118, + 245, 170, 110, 93, 135, 62, 0, 251, 192, 255, 53, 220, 95, 3, 212, 24, 254, 224, 77, 171, 141, 70, 237, + 181, 40, 103, 111, 67, 254, 188, 6, 104, 2, 122, 22, 244, 47, 160, 46, 70, 211, 28, 160, 63, 232, 84, 92, + 92, 28, 185, 125, 235, 150, 20, 254, 21, 240, 62, 137, 209, 209, 180, 6, 212, 214, 0, 220, 111, 237, 197, + 90, 235, 243, 120, 13, 81, 93, 186, 144, 77, 175, 188, 66, 99, 178, 150, 251, 63, 143, 1, 94, 3, 60, 201, + 106, 128, 231, 65, 175, 128, 186, 131, 122, 193, 223, 132, 207, 152, 49, 131, 220, 133, 251, 246, 42, 240, + 211, 171, 98, 240, 145, 43, 25, 25, 100, 73, 203, 150, 116, 22, 44, 206, 129, 106, 2, 255, 240, 118, 237, + 72, 218, 15, 63, 144, 13, 237, 219, 139, 49, 160, 156, 189, 13, 249, 139, 53, 64, 115, 208, 115, 160, 78, + 160, 255, 98, 252, 191, 120, 237, 181, 215, 254, 15, 103, 120, 120, 255, 98, 254, 214, 171, 50, 232, 3, 55, + 64, 93, 129, 179, 96, 85, 53, 128, 185, 58, 111, 53, 139, 129, 204, 35, 71, 200, 229, 196, 68, 18, 210, + 162, 5, 143, 1, 229, 236, 109, 200, 95, 92, 15, 110, 106, 52, 173, 7, 191, 8, 122, 157, 213, 0, 31, 185, + 185, 185, 101, 39, 194, 247, 81, 81, 94, 46, 133, 127, 57, 212, 147, 9, 254, 254, 102, 107, 0, 206, 39, + 208, 198, 210, 198, 1, 103, 143, 94, 148, 24, 24, 72, 110, 194, 23, 126, 241, 224, 65, 18, 216, 164, 73, + 109, 217, 255, 103, 142, 63, 159, 3, 184, 10, 53, 0, 206, 130, 59, 24, 171, 102, 193, 125, 224, 207, 226, + 253, 129, 215, 157, 59, 119, 72, 17, 240, 211, 171, 98, 136, 163, 244, 83, 167, 200, 130, 70, 141, 200, 34, + 131, 169, 6, 80, 205, 159, 207, 160, 241, 90, 14, 207, 153, 67, 74, 225, 191, 21, 149, 178, 107, 23, 89, + 221, 184, 177, 114, 246, 182, 226, 47, 212, 0, 218, 245, 224, 151, 141, 166, 89, 48, 230, 128, 165, 131, 6, + 14, 164, 115, 160, 162, 194, 66, 221, 66, 15, 192, 58, 96, 173, 183, 55, 153, 103, 48, 213, 0, 188, 6, 84, + 193, 31, 63, 215, 159, 197, 32, 206, 36, 226, 39, 77, 34, 165, 80, 167, 226, 181, 150, 65, 12, 36, 69, 69, + 41, 103, 111, 99, 254, 214, 246, 132, 33, 127, 159, 103, 158, 121, 166, 44, 19, 234, 54, 92, 203, 145, 17, + 3, 229, 240, 189, 238, 133, 251, 12, 251, 128, 165, 134, 251, 107, 64, 123, 241, 231, 190, 239, 207, 226, + 15, 175, 1, 243, 209, 174, 49, 99, 42, 249, 211, 24, 184, 123, 87, 57, 123, 59, 240, 23, 247, 132, 105, + 103, 193, 216, 7, 158, 136, 141, 141, 165, 235, 193, 133, 240, 157, 232, 85, 113, 69, 5, 73, 62, 116, 136, + 204, 131, 94, 27, 251, 64, 123, 215, 0, 226, 189, 191, 146, 177, 71, 239, 199, 185, 100, 156, 143, 15, 41, + 1, 254, 194, 245, 42, 103, 111, 67, 254, 248, 210, 174, 7, 107, 251, 64, 156, 5, 175, 155, 244, 233, 167, + 116, 22, 40, 131, 127, 17, 244, 18, 248, 239, 170, 78, 157, 104, 31, 40, 214, 0, 156, 209, 90, 27, 138, + 199, 192, 106, 246, 185, 216, 131, 96, 30, 194, 107, 217, 1, 247, 127, 29, 227, 143, 30, 160, 237, 3, 189, + 140, 166, 62, 208, 155, 241, 159, 218, 177, 99, 199, 123, 133, 5, 5, 52, 127, 227, 191, 122, 133, 30, 27, + 55, 101, 10, 157, 5, 127, 203, 124, 120, 13, 227, 19, 4, 10, 182, 161, 130, 216, 231, 4, 176, 207, 245, 99, + 252, 113, 109, 58, 206, 215, 151, 148, 66, 143, 42, 92, 171, 114, 246, 118, 224, 207, 107, 0, 222, 7, 182, + 1, 189, 96, 52, 245, 129, 88, 3, 124, 232, 226, 226, 146, 150, 144, 144, 64, 159, 235, 40, 128, 239, 69, + 175, 48, 7, 252, 10, 245, 53, 126, 231, 95, 179, 28, 204, 239, 255, 32, 27, 199, 64, 16, 251, 28, 126, 255, + 99, 252, 97, 238, 199, 153, 196, 158, 47, 191, 164, 247, 191, 112, 173, 202, 217, 219, 137, 127, 61, 33, 7, + 224, 44, 88, 236, 3, 123, 195, 223, 197, 206, 155, 55, 143, 220, 186, 255, 187, 121, 108, 21, 66, 14, 200, + 205, 201, 33, 43, 218, 183, 167, 125, 224, 114, 67, 85, 15, 96, 79, 254, 24, 119, 152, 127, 176, 14, 193, + 153, 196, 193, 175, 191, 166, 222, 84, 135, 248, 139, 57, 0, 251, 64, 156, 5, 107, 247, 5, 99, 14, 152, + 221, 189, 91, 55, 186, 167, 23, 125, 177, 32, 63, 95, 183, 74, 160, 158, 140, 29, 55, 142, 246, 129, 246, + 204, 1, 90, 254, 232, 253, 139, 24, 255, 163, 225, 225, 212, 155, 132, 235, 84, 206, 222, 142, 252, 45, + 173, 7, 34, 255, 143, 221, 221, 221, 243, 78, 158, 60, 73, 247, 244, 228, 195, 119, 163, 87, 215, 224, 123, + 62, 177, 117, 43, 205, 1, 188, 6, 228, 247, 63, 103, 21, 98, 3, 5, 27, 170, 242, 63, 242, 199, 252, 179, + 144, 249, 127, 210, 129, 3, 228, 42, 228, 56, 225, 58, 149, 179, 183, 19, 127, 237, 122, 32, 246, 129, 124, + 61, 240, 109, 16, 62, 27, 178, 31, 103, 129, 216, 7, 202, 224, 143, 57, 32, 59, 35, 131, 44, 111, 211, 134, + 62, 27, 198, 107, 128, 181, 118, 226, 207, 239, 127, 228, 143, 49, 184, 160, 73, 19, 146, 145, 148, 68, + 138, 174, 93, 171, 107, 252, 121, 12, 240, 89, 32, 95, 15, 108, 103, 172, 234, 3, 177, 6, 88, 242, 254, + 251, 239, 147, 10, 188, 63, 242, 242, 164, 168, 248, 250, 117, 18, 51, 98, 4, 253, 254, 121, 13, 16, 104, + 71, 254, 248, 153, 56, 131, 194, 231, 19, 151, 191, 248, 34, 201, 207, 205, 165, 121, 95, 184, 70, 229, + 236, 237, 200, 223, 218, 122, 32, 242, 31, 221, 162, 69, 139, 226, 212, 148, 20, 186, 30, 40, 131, 255, + 181, 242, 114, 114, 124, 243, 102, 187, 230, 128, 96, 67, 85, 254, 231, 252, 49, 247, 135, 14, 24, 64, 175, + 135, 222, 247, 117, 147, 191, 181, 89, 32, 246, 129, 56, 11, 252, 57, 44, 44, 140, 158, 17, 146, 7, 223, + 143, 94, 21, 20, 22, 210, 28, 224, 39, 228, 128, 0, 27, 231, 0, 206, 127, 21, 227, 143, 189, 31, 238, 75, + 221, 245, 213, 87, 164, 24, 114, 155, 230, 26, 149, 179, 183, 51, 127, 139, 103, 68, 48, 15, 88, 49, 116, + 232, 80, 114, 29, 238, 147, 60, 240, 74, 25, 194, 58, 112, 235, 200, 145, 100, 129, 134, 63, 178, 90, 7, + 90, 47, 81, 235, 216, 251, 114, 255, 231, 115, 127, 172, 253, 142, 67, 45, 122, 181, 180, 84, 123, 125, + 202, 217, 219, 137, 191, 54, 7, 240, 103, 67, 188, 140, 166, 125, 161, 222, 140, 255, 132, 86, 173, 90, 85, + 164, 93, 188, 72, 215, 71, 100, 240, 199, 122, 27, 115, 192, 2, 118, 63, 242, 57, 16, 231, 47, 51, 6, 180, + 252, 241, 243, 176, 247, 95, 204, 106, 191, 130, 162, 162, 186, 206, 223, 220, 44, 144, 239, 9, 193, 62, + 112, 0, 8, 112, 109, 166, 179, 192, 92, 248, 142, 244, 42, 31, 226, 232, 114, 122, 58, 89, 1, 57, 0, 107, + 113, 62, 7, 8, 182, 49, 127, 244, 127, 156, 59, 224, 220, 63, 200, 219, 155, 20, 64, 77, 131, 158, 175, + 185, 62, 229, 236, 21, 240, 231, 125, 32, 207, 1, 218, 61, 33, 107, 71, 143, 26, 69, 107, 0, 25, 252, 81, + 87, 49, 7, 12, 31, 78, 251, 112, 158, 3, 130, 108, 196, 159, 231, 127, 140, 51, 172, 57, 177, 246, 255, + 110, 250, 116, 114, 21, 122, 17, 51, 215, 166, 156, 189, 29, 249, 139, 57, 64, 251, 124, 32, 127, 54, 0, + 249, 127, 234, 229, 229, 117, 35, 3, 238, 89, 156, 145, 229, 94, 185, 162, 91, 69, 144, 119, 143, 111, 217, + 66, 231, 112, 126, 26, 254, 200, 45, 84, 130, 120, 12, 132, 8, 252, 249, 186, 207, 201, 29, 59, 72, 97, 73, + 137, 185, 107, 83, 206, 94, 17, 127, 113, 22, 200, 115, 192, 27, 44, 7, 252, 1, 116, 10, 247, 4, 224, 222, + 80, 184, 54, 221, 202, 133, 56, 186, 156, 153, 73, 252, 219, 182, 165, 57, 96, 149, 161, 170, 6, 92, 47, + 41, 6, 248, 251, 4, 179, 252, 130, 189, 38, 246, 28, 126, 158, 158, 228, 18, 196, 50, 94, 131, 153, 107, + 83, 206, 94, 1, 127, 75, 207, 6, 188, 10, 234, 193, 60, 32, 4, 159, 17, 198, 115, 254, 100, 240, 71, 21, + 193, 123, 109, 27, 55, 142, 230, 0, 62, 7, 224, 53, 128, 44, 254, 235, 152, 175, 4, 48, 159, 193, 220, 31, + 53, 108, 24, 41, 180, 252, 223, 161, 156, 189, 157, 249, 243, 24, 48, 183, 47, 144, 175, 7, 33, 255, 207, + 219, 183, 111, 127, 43, 11, 238, 89, 156, 147, 92, 201, 201, 209, 173, 130, 226, 98, 114, 114, 251, 118, + 90, 143, 35, 27, 62, 11, 22, 243, 191, 12, 239, 231, 181, 223, 114, 198, 255, 72, 88, 24, 41, 196, 103, 19, + 204, 95, 151, 114, 246, 138, 248, 91, 91, 15, 194, 62, 112, 32, 232, 52, 230, 0, 92, 15, 202, 129, 239, 74, + 175, 174, 64, 189, 149, 125, 249, 50, 9, 120, 225, 133, 202, 28, 192, 251, 64, 153, 252, 121, 238, 167, + 231, 80, 60, 251, 44, 201, 76, 77, 165, 222, 111, 225, 186, 148, 179, 87, 196, 223, 234, 243, 97, 70, 211, + 57, 33, 33, 99, 199, 142, 165, 57, 64, 6, 127, 20, 250, 240, 174, 169, 83, 105, 29, 232, 175, 225, 143, 28, + 195, 30, 83, 60, 6, 120, 237, 143, 249, 5, 63, 35, 122, 232, 80, 82, 0, 247, 190, 149, 107, 82, 206, 94, 1, + 127, 124, 61, 97, 124, 112, 79, 64, 59, 33, 7, 32, 255, 207, 176, 15, 72, 79, 75, 163, 179, 146, 156, 236, + 108, 221, 202, 47, 42, 34, 73, 251, 246, 145, 165, 46, 46, 149, 125, 64, 176, 230, 222, 127, 28, 246, 34, + 127, 190, 238, 139, 252, 113, 238, 132, 121, 199, 202, 53, 41, 103, 175, 136, 63, 207, 1, 13, 30, 146, 3, + 18, 183, 64, 223, 86, 98, 253, 59, 172, 182, 104, 206, 133, 122, 34, 228, 213, 87, 233, 186, 12, 239, 3, + 214, 73, 224, 207, 107, 191, 213, 204, 251, 87, 119, 232, 64, 123, 142, 43, 214, 99, 87, 57, 123, 133, 252, + 45, 237, 9, 224, 125, 0, 122, 64, 224, 200, 79, 62, 161, 231, 196, 224, 217, 225, 50, 84, 80, 86, 70, 246, + 205, 157, 75, 239, 207, 149, 18, 114, 0, 191, 247, 197, 220, 143, 239, 189, 107, 218, 52, 250, 89, 15, 185, + 30, 229, 236, 101, 241, 127, 68, 241, 151, 184, 39, 128, 231, 0, 124, 62, 168, 155, 209, 180, 39, 100, 98, + 235, 214, 173, 43, 206, 67, 13, 149, 199, 234, 55, 189, 202, 45, 40, 32, 41, 191, 252, 66, 150, 53, 106, + 68, 107, 116, 113, 22, 244, 168, 30, 32, 122, 63, 239, 251, 232, 126, 239, 6, 13, 200, 185, 132, 4, 250, + 89, 15, 185, 30, 229, 236, 21, 241, 231, 49, 240, 176, 28, 128, 179, 160, 99, 97, 161, 161, 52, 7, 200, + 224, 143, 247, 93, 46, 212, 1, 27, 123, 245, 162, 57, 96, 53, 99, 183, 94, 224, 186, 161, 154, 226, 127, + 47, 242, 199, 247, 140, 236, 211, 135, 228, 225, 254, 35, 188, 199, 157, 252, 173, 241, 183, 182, 47, 172, + 7, 243, 128, 21, 131, 7, 15, 166, 125, 224, 101, 248, 206, 100, 40, 175, 164, 132, 252, 184, 106, 21, 157, + 207, 137, 53, 0, 103, 31, 94, 77, 109, 208, 240, 199, 88, 194, 153, 127, 226, 214, 173, 228, 218, 221, 187, + 36, 31, 174, 185, 128, 9, 103, 0, 56, 135, 46, 194, 61, 174, 248, 191, 225, 30, 151, 162, 34, 229, 236, + 107, 0, 127, 75, 57, 160, 43, 227, 63, 182, 69, 243, 230, 197, 73, 103, 206, 208, 153, 57, 158, 25, 163, + 87, 57, 240, 62, 105, 73, 73, 196, 191, 101, 75, 218, 7, 240, 26, 32, 84, 184, 183, 171, 195, 158, 243, 95, + 199, 98, 136, 62, 239, 231, 230, 70, 247, 27, 68, 67, 239, 26, 49, 102, 12, 9, 5, 5, 141, 30, 77, 66, 62, + 251, 140, 132, 206, 152, 65, 34, 160, 246, 136, 89, 182, 140, 236, 94, 183, 142, 36, 108, 219, 166, 156, + 189, 66, 254, 213, 201, 1, 125, 64, 239, 195, 101, 253, 176, 26, 238, 87, 60, 235, 77, 6, 127, 84, 30, 220, + 131, 177, 195, 135, 83, 191, 22, 251, 192, 234, 122, 0, 231, 31, 42, 240, 231, 207, 121, 227, 158, 243, + 153, 160, 201, 160, 113, 160, 17, 160, 143, 64, 208, 208, 16, 248, 143, 33, 239, 129, 222, 53, 253, 171, + 156, 125, 13, 224, 255, 176, 245, 0, 244, 128, 37, 189, 223, 121, 135, 238, 9, 65, 255, 190, 4, 252, 244, + 234, 10, 212, 0, 199, 163, 163, 233, 26, 157, 88, 3, 32, 211, 141, 76, 17, 86, 196, 255, 102, 131, 198, + 255, 249, 158, 143, 57, 44, 6, 166, 128, 124, 65, 62, 160, 145, 160, 143, 65, 67, 88, 60, 12, 118, 242, + 231, 47, 107, 231, 4, 32, 255, 79, 220, 221, 221, 243, 143, 29, 57, 66, 251, 128, 75, 89, 89, 186, 133, + 113, 132, 235, 11, 193, 29, 59, 210, 28, 176, 86, 2, 127, 190, 238, 179, 132, 121, 0, 238, 251, 155, 14, + 250, 156, 197, 192, 88, 208, 104, 208, 39, 44, 22, 70, 56, 249, 91, 202, 1, 109, 132, 28, 208, 27, 132, + 123, 67, 119, 45, 88, 176, 128, 246, 1, 50, 248, 163, 114, 225, 189, 246, 206, 154, 69, 231, 53, 107, 88, + 13, 16, 198, 252, 253, 81, 248, 135, 26, 170, 214, 125, 181, 207, 124, 204, 98, 49, 128, 62, 48, 9, 52, 17, + 52, 1, 52, 222, 148, 27, 148, 179, 175, 33, 252, 205, 229, 128, 14, 44, 7, 188, 5, 130, 116, 105, 248, 234, + 245, 215, 95, 167, 235, 166, 232, 223, 248, 59, 50, 122, 149, 157, 151, 71, 206, 30, 62, 76, 252, 26, 54, + 164, 181, 91, 144, 161, 170, 6, 124, 152, 7, 104, 249, 107, 247, 125, 161, 7, 44, 96, 121, 224, 207, 44, + 23, 204, 0, 77, 3, 253, 137, 105, 178, 147, 191, 24, 3, 150, 214, 132, 223, 100, 57, 96, 168, 139, 139, 75, + 122, 252, 222, 189, 116, 77, 24, 189, 91, 183, 32, 6, 114, 242, 243, 73, 36, 212, 22, 200, 12, 251, 0, 222, + 7, 86, 151, 127, 184, 161, 170, 7, 224, 30, 224, 207, 98, 0, 107, 75, 156, 5, 226, 58, 240, 92, 230, 7, + 120, 46, 201, 255, 176, 152, 248, 210, 201, 95, 155, 3, 248, 154, 176, 184, 55, 148, 238, 11, 2, 97, 185, + 28, 249, 167, 41, 83, 104, 31, 32, 133, 63, 206, 231, 161, 14, 252, 41, 48, 144, 214, 129, 1, 143, 144, 3, + 54, 26, 30, 244, 0, 190, 6, 176, 198, 80, 117, 230, 215, 183, 44, 31, 160, 31, 252, 149, 197, 195, 66, 230, + 13, 11, 156, 252, 181, 57, 128, 159, 23, 166, 253, 237, 136, 223, 179, 28, 48, 181, 67, 251, 246, 183, 113, + 127, 120, 54, 171, 223, 244, 234, 18, 188, 79, 90, 74, 10, 9, 244, 244, 164, 235, 1, 193, 140, 101, 184, + 192, 58, 210, 140, 196, 88, 16, 103, 65, 220, 7, 248, 51, 160, 252, 12, 40, 126, 14, 208, 114, 22, 19, 223, + 152, 164, 156, 125, 13, 227, 175, 221, 27, 234, 101, 172, 122, 62, 0, 115, 192, 7, 160, 83, 248, 251, 33, + 248, 156, 56, 158, 27, 37, 67, 57, 224, 1, 120, 54, 199, 55, 134, 170, 89, 32, 175, 1, 44, 241, 183, 22, 3, + 226, 94, 96, 126, 30, 72, 160, 225, 193, 51, 1, 107, 209, 239, 191, 201, 140, 1, 241, 249, 0, 60, 51, 178, + 242, 172, 16, 150, 3, 86, 253, 113, 240, 96, 58, 11, 144, 197, 255, 50, 244, 148, 191, 238, 217, 67, 150, + 227, 25, 205, 66, 14, 16, 253, 255, 97, 252, 197, 122, 128, 199, 129, 118, 111, 144, 248, 140, 24, 139, 13, + 229, 236, 107, 32, 127, 237, 51, 98, 120, 94, 20, 62, 35, 214, 157, 241, 31, 215, 180, 105, 211, 107, 137, + 39, 78, 208, 53, 116, 41, 49, 0, 121, 224, 50, 244, 21, 27, 187, 119, 167, 254, 44, 246, 1, 213, 229, 111, + 41, 14, 180, 107, 69, 226, 186, 97, 168, 147, 191, 185, 24, 176, 246, 156, 112, 95, 16, 62, 35, 180, 127, + 241, 226, 197, 244, 204, 207, 12, 224, 39, 67, 217, 224, 39, 9, 43, 87, 210, 28, 160, 237, 3, 172, 229, 0, + 107, 177, 96, 173, 102, 100, 82, 206, 190, 6, 242, 183, 244, 251, 49, 252, 172, 8, 244, 128, 121, 222, 222, + 222, 149, 247, 63, 62, 43, 162, 87, 89, 151, 46, 145, 11, 73, 73, 36, 176, 85, 43, 154, 155, 197, 28, 192, + 25, 111, 146, 32, 77, 220, 40, 103, 95, 3, 249, 227, 203, 218, 190, 16, 228, 63, 204, 213, 213, 53, 109, + 207, 247, 223, 211, 53, 65, 25, 252, 81, 232, 1, 113, 19, 38, 208, 250, 156, 231, 0, 222, 7, 200, 226, 175, + 145, 114, 246, 53, 140, 191, 54, 7, 152, 221, 23, 98, 52, 205, 131, 55, 78, 156, 56, 145, 230, 128, 116, + 96, 39, 67, 89, 16, 75, 167, 247, 238, 37, 43, 92, 93, 105, 15, 207, 251, 0, 209, 255, 157, 252, 237, 158, + 3, 204, 205, 131, 145, 255, 100, 79, 79, 207, 235, 201, 231, 206, 209, 62, 30, 247, 9, 235, 22, 198, 64, + 78, 14, 137, 124, 235, 45, 218, 175, 7, 219, 40, 7, 56, 249, 87, 139, 191, 185, 121, 48, 159, 5, 224, 44, + 104, 16, 232, 231, 128, 128, 0, 250, 156, 168, 20, 254, 160, 75, 240, 94, 63, 193, 123, 98, 31, 176, 86, + 200, 1, 34, 251, 205, 242, 164, 156, 125, 13, 228, 47, 230, 0, 139, 231, 134, 50, 15, 88, 218, 171, 87, 47, + 186, 38, 132, 247, 110, 26, 240, 211, 171, 116, 240, 146, 11, 41, 41, 36, 248, 249, 231, 105, 29, 40, 230, + 0, 39, 127, 37, 57, 192, 220, 121, 49, 221, 25, 255, 145, 110, 110, 110, 151, 255, 118, 224, 0, 157, 7, + 227, 92, 88, 134, 46, 21, 20, 144, 61, 211, 167, 83, 15, 208, 230, 0, 39, 127, 187, 241, 231, 30, 160, 157, + 5, 240, 223, 147, 199, 89, 0, 238, 13, 139, 154, 50, 121, 50, 157, 7, 203, 226, 159, 1, 189, 224, 153, 195, + 135, 201, 170, 198, 141, 105, 29, 184, 222, 80, 213, 7, 72, 246, 0, 229, 236, 107, 40, 127, 173, 7, 136, + 103, 134, 137, 231, 70, 34, 255, 169, 237, 218, 181, 187, 153, 156, 156, 76, 231, 56, 23, 129, 159, 12, + 101, 230, 230, 146, 152, 65, 131, 104, 29, 40, 206, 2, 156, 252, 237, 206, 95, 59, 11, 104, 107, 172, 122, + 78, 240, 61, 182, 38, 116, 100, 109, 96, 32, 221, 27, 118, 241, 194, 5, 41, 202, 128, 62, 224, 216, 230, + 205, 149, 107, 130, 97, 194, 253, 191, 133, 41, 74, 191, 148, 179, 175, 225, 252, 241, 101, 245, 188, 16, + 230, 1, 75, 122, 244, 232, 81, 89, 3, 200, 224, 79, 235, 65, 240, 147, 141, 93, 186, 208, 53, 161, 245, + 194, 253, 239, 228, 175, 36, 7, 136, 191, 35, 38, 158, 27, 136, 252, 71, 212, 175, 95, 63, 43, 62, 62, 158, + 238, 235, 148, 229, 1, 153, 121, 121, 228, 208, 178, 101, 212, 3, 48, 7, 108, 96, 53, 224, 102, 39, 127, + 123, 243, 55, 183, 47, 64, 187, 38, 20, 233, 235, 235, 75, 247, 134, 93, 56, 127, 94, 138, 46, 130, 7, 164, + 156, 57, 67, 66, 218, 180, 161, 107, 66, 161, 242, 61, 64, 57, 251, 26, 206, 95, 140, 1, 62, 11, 192, 58, + 16, 247, 5, 136, 107, 66, 200, 255, 115, 60, 59, 242, 244, 169, 83, 116, 150, 47, 43, 6, 176, 14, 252, 126, + 234, 84, 234, 1, 56, 11, 224, 179, 32, 73, 30, 160, 156, 189, 3, 241, 215, 254, 158, 176, 248, 156, 216, + 123, 32, 156, 7, 130, 93, 47, 163, 103, 235, 201, 226, 159, 150, 153, 73, 126, 77, 72, 32, 107, 220, 221, + 233, 154, 80, 152, 192, 159, 115, 140, 126, 124, 41, 103, 239, 0, 252, 121, 12, 88, 90, 19, 226, 117, 32, + 122, 192, 60, 220, 35, 206, 239, 127, 124, 110, 92, 134, 210, 161, 23, 216, 54, 100, 8, 157, 7, 242, 28, + 224, 228, 111, 63, 25, 44, 159, 29, 170, 173, 3, 135, 129, 82, 162, 163, 162, 232, 51, 126, 178, 248, 167, + 193, 123, 29, 223, 190, 157, 172, 126, 226, 9, 218, 11, 242, 58, 112, 139, 254, 24, 80, 206, 222, 193, 248, + 87, 167, 14, 92, 131, 251, 3, 241, 172, 23, 89, 252, 207, 99, 45, 152, 149, 69, 54, 67, 143, 25, 192, 60, + 32, 66, 142, 7, 40, 103, 239, 32, 252, 197, 24, 16, 235, 64, 237, 222, 32, 228, 63, 206, 195, 195, 163, + 240, 240, 225, 195, 116, 30, 152, 10, 252, 100, 40, 45, 59, 155, 252, 28, 28, 124, 31, 255, 45, 140, 99, + 12, 104, 235, 227, 73, 57, 123, 7, 228, 47, 214, 129, 226, 185, 97, 248, 156, 208, 187, 32, 60, 55, 106, + 219, 140, 25, 51, 168, 7, 224, 239, 137, 200, 16, 122, 0, 42, 162, 115, 103, 90, 7, 110, 20, 248, 115, 158, + 177, 143, 46, 229, 236, 29, 140, 63, 190, 172, 61, 39, 132, 235, 194, 120, 102, 204, 244, 182, 109, 219, + 222, 58, 3, 189, 59, 206, 113, 100, 197, 64, 26, 196, 211, 15, 75, 150, 80, 15, 224, 125, 64, 148, 147, + 191, 189, 248, 107, 235, 64, 75, 235, 194, 88, 7, 126, 8, 250, 113, 249, 242, 229, 244, 12, 158, 20, 96, + 39, 67, 169, 16, 75, 231, 78, 159, 38, 97, 94, 94, 116, 30, 40, 230, 128, 199, 140, 1, 229, 236, 29, 144, + 63, 247, 0, 75, 235, 194, 125, 152, 7, 204, 127, 227, 141, 55, 232, 122, 0, 222, 187, 41, 201, 201, 82, + 116, 17, 226, 41, 126, 230, 76, 234, 1, 216, 7, 108, 98, 30, 16, 243, 120, 49, 160, 156, 189, 131, 241, 55, + 215, 11, 138, 235, 194, 124, 127, 224, 0, 214, 11, 158, 219, 20, 25, 73, 159, 245, 151, 197, 255, 60, 196, + 211, 153, 35, 71, 200, 186, 22, 45, 232, 60, 144, 123, 64, 140, 192, 117, 91, 245, 165, 156, 189, 3, 243, + 23, 247, 7, 138, 191, 35, 65, 159, 21, 100, 30, 224, 223, 191, 127, 127, 122, 94, 0, 238, 15, 144, 165, 11, + 224, 1, 187, 125, 125, 233, 154, 192, 70, 39, 127, 21, 252, 241, 165, 221, 31, 200, 215, 4, 240, 247, 228, + 176, 23, 196, 62, 96, 180, 155, 155, 91, 206, 222, 61, 123, 232, 222, 78, 220, 43, 44, 67, 169, 224, 1, + 167, 14, 30, 36, 33, 30, 30, 180, 23, 20, 235, 192, 71, 140, 1, 229, 236, 29, 144, 255, 195, 122, 65, 113, + 77, 0, 99, 32, 194, 199, 199, 135, 238, 13, 144, 197, 31, 117, 1, 60, 101, 231, 240, 225, 116, 143, 48, + 159, 7, 63, 134, 7, 40, 103, 239, 192, 252, 185, 7, 104, 207, 13, 18, 123, 65, 228, 63, 169, 121, 243, 230, + 37, 71, 126, 249, 133, 246, 130, 210, 60, 0, 252, 228, 196, 238, 221, 36, 184, 65, 3, 234, 1, 155, 30, 207, + 3, 148, 179, 119, 80, 254, 218, 58, 208, 98, 47, 8, 194, 253, 97, 223, 205, 154, 53, 139, 174, 9, 156, 59, + 123, 86, 154, 82, 51, 51, 201, 182, 129, 3, 233, 60, 232, 49, 235, 64, 229, 236, 29, 156, 191, 232, 1, 218, + 94, 144, 63, 43, 134, 235, 194, 255, 221, 174, 93, 187, 91, 184, 55, 0, 123, 65, 105, 252, 211, 211, 201, + 223, 183, 109, 35, 193, 174, 174, 180, 23, 196, 28, 16, 173, 97, 191, 221, 186, 148, 179, 119, 96, 254, 90, + 15, 208, 62, 43, 198, 207, 141, 25, 0, 194, 163, 22, 19, 150, 46, 93, 74, 123, 65, 105, 30, 128, 121, 0, + 98, 32, 182, 95, 63, 186, 46, 24, 33, 228, 0, 39, 127, 187, 242, 215, 246, 130, 94, 198, 251, 215, 5, 209, + 3, 230, 188, 252, 242, 203, 191, 241, 89, 144, 76, 15, 56, 26, 29, 77, 130, 140, 198, 74, 15, 136, 169, + 190, 7, 40, 103, 239, 224, 252, 121, 12, 136, 189, 160, 118, 93, 16, 207, 144, 197, 58, 112, 40, 40, 49, + 104, 237, 90, 250, 188, 168, 76, 15, 72, 129, 90, 48, 166, 103, 79, 58, 19, 142, 124, 52, 15, 80, 206, 190, + 150, 240, 55, 215, 11, 182, 53, 154, 214, 5, 249, 60, 8, 61, 96, 73, 183, 174, 93, 233, 76, 24, 107, 120, + 105, 30, 144, 145, 65, 142, 68, 70, 210, 28, 192, 231, 65, 91, 53, 236, 119, 152, 151, 114, 246, 181, 132, + 191, 232, 1, 124, 93, 144, 159, 29, 197, 231, 65, 200, 127, 56, 232, 92, 36, 176, 194, 61, 98, 82, 61, 0, + 222, 111, 235, 219, 111, 211, 153, 240, 38, 161, 14, 116, 242, 183, 57, 127, 115, 30, 128, 189, 160, 118, + 143, 232, 187, 44, 6, 86, 246, 237, 219, 151, 158, 27, 35, 219, 3, 142, 66, 92, 133, 60, 154, 7, 40, 103, + 95, 139, 248, 115, 15, 48, 55, 15, 226, 207, 140, 35, 255, 81, 174, 174, 174, 233, 219, 161, 111, 195, 153, + 176, 116, 15, 128, 58, 224, 17, 60, 64, 57, 251, 90, 194, 95, 244, 0, 237, 30, 81, 60, 63, 238, 21, 163, + 233, 236, 160, 254, 70, 211, 60, 104, 237, 160, 65, 131, 228, 214, 129, 66, 29, 192, 61, 128, 215, 129, 34, + 251, 157, 247, 75, 57, 251, 90, 198, 95, 244, 0, 119, 163, 249, 125, 226, 200, 223, 167, 97, 195, 134, 217, + 120, 126, 20, 214, 130, 178, 61, 32, 22, 234, 128, 80, 33, 7, 108, 23, 152, 199, 221, 47, 229, 236, 107, + 17, 127, 107, 30, 96, 110, 38, 188, 126, 216, 176, 97, 114, 231, 65, 66, 29, 176, 142, 245, 130, 209, 172, + 6, 216, 225, 228, 111, 79, 254, 124, 30, 100, 105, 38, 140, 251, 195, 198, 55, 110, 212, 40, 247, 192, 254, + 253, 210, 61, 0, 99, 96, 123, 191, 126, 213, 241, 0, 229, 236, 107, 25, 127, 30, 3, 188, 23, 180, 54, 19, + 198, 24, 136, 24, 61, 122, 180, 244, 117, 33, 204, 1, 199, 98, 98, 72, 168, 139, 11, 245, 128, 24, 230, 1, + 78, 254, 118, 227, 111, 110, 38, 172, 221, 35, 136, 252, 125, 61, 60, 60, 242, 241, 252, 32, 92, 27, 150, + 237, 1, 59, 7, 12, 160, 30, 16, 197, 250, 128, 29, 2, 251, 239, 76, 82, 206, 190, 22, 242, 215, 122, 128, + 246, 236, 24, 190, 71, 240, 15, 70, 211, 186, 80, 164, 207, 152, 49, 242, 61, 0, 122, 203, 227, 113, 113, + 36, 172, 126, 253, 74, 15, 216, 174, 185, 255, 157, 252, 109, 202, 191, 58, 235, 66, 232, 1, 147, 154, 52, + 105, 82, 148, 112, 232, 144, 92, 15, 192, 90, 16, 106, 203, 93, 67, 134, 88, 243, 0, 229, 236, 107, 41, + 255, 234, 120, 64, 15, 193, 3, 162, 125, 39, 76, 144, 239, 1, 80, 87, 158, 140, 143, 39, 225, 141, 27, 63, + 80, 7, 56, 243, 191, 93, 248, 139, 51, 97, 115, 251, 132, 69, 15, 184, 106, 19, 15, 128, 152, 218, 227, + 227, 99, 201, 3, 148, 179, 175, 229, 252, 173, 121, 64, 229, 218, 48, 243, 128, 200, 49, 54, 232, 5, 146, + 33, 158, 78, 31, 62, 76, 34, 154, 53, 163, 30, 192, 123, 65, 167, 255, 219, 156, 191, 214, 3, 180, 103, + 200, 137, 30, 240, 71, 248, 219, 137, 238, 238, 238, 121, 210, 123, 1, 208, 121, 136, 169, 253, 211, 166, + 209, 103, 6, 163, 132, 28, 224, 228, 111, 23, 254, 230, 60, 64, 60, 63, 136, 123, 0, 198, 128, 77, 230, 1, + 201, 169, 169, 36, 233, 248, 113, 178, 217, 211, 147, 238, 17, 19, 60, 64, 57, 251, 90, 206, 159, 199, 128, + 165, 253, 33, 90, 15, 240, 5, 15, 200, 221, 191, 111, 159, 220, 153, 32, 171, 3, 14, 205, 159, 127, 159, 7, + 56, 215, 255, 236, 198, 159, 123, 64, 3, 163, 149, 61, 98, 70, 83, 29, 16, 54, 108, 232, 80, 249, 30, 128, + 251, 142, 147, 146, 72, 116, 167, 78, 116, 109, 144, 205, 3, 148, 179, 175, 3, 252, 121, 12, 136, 207, 10, + 88, 242, 0, 228, 63, 30, 207, 20, 223, 189, 107, 151, 220, 253, 1, 103, 77, 243, 128, 159, 3, 2, 232, 62, + 81, 182, 46, 164, 156, 125, 29, 226, 207, 61, 192, 92, 29, 32, 206, 4, 49, 15, 4, 13, 26, 56, 80, 250, 218, + 32, 93, 31, 134, 188, 178, 163, 91, 55, 90, 7, 56, 159, 255, 182, 27, 127, 30, 3, 214, 234, 0, 62, 19, 68, + 254, 62, 248, 251, 82, 177, 91, 183, 202, 221, 39, 120, 214, 180, 54, 244, 247, 168, 40, 178, 209, 197, + 197, 121, 254, 147, 253, 249, 115, 15, 48, 87, 7, 104, 61, 192, 191, 79, 239, 222, 36, 19, 120, 201, 220, + 39, 200, 243, 192, 238, 15, 62, 112, 254, 254, 159, 125, 249, 243, 24, 176, 86, 7, 160, 7, 224, 218, 32, + 214, 1, 163, 64, 231, 54, 134, 135, 211, 189, 162, 82, 61, 0, 159, 31, 63, 112, 128, 108, 246, 240, 80, + 206, 222, 17, 248, 75, 148, 232, 1, 214, 214, 6, 113, 127, 192, 71, 240, 117, 44, 125, 211, 219, 187, 242, + 185, 97, 169, 30, 0, 253, 197, 129, 201, 147, 149, 179, 175, 99, 252, 121, 12, 152, 91, 23, 240, 50, 154, + 214, 6, 249, 254, 0, 244, 128, 17, 160, 19, 248, 27, 99, 178, 107, 65, 58, 19, 74, 76, 84, 206, 190, 142, + 242, 199, 151, 57, 15, 16, 247, 8, 225, 62, 65, 244, 128, 191, 116, 238, 220, 249, 30, 222, 255, 50, 159, + 27, 100, 30, 160, 156, 125, 29, 228, 47, 122, 0, 214, 1, 218, 253, 1, 124, 143, 16, 238, 19, 68, 15, 248, + 24, 116, 104, 209, 194, 133, 242, 103, 66, 201, 201, 202, 217, 215, 97, 254, 248, 18, 61, 64, 187, 79, 144, + 254, 198, 28, 104, 8, 124, 45, 179, 158, 123, 238, 185, 27, 248, 155, 243, 120, 30, 176, 196, 24, 80, 206, + 190, 142, 242, 23, 61, 64, 220, 35, 164, 221, 43, 140, 207, 11, 12, 6, 225, 179, 195, 113, 211, 166, 78, + 165, 231, 8, 57, 249, 215, 10, 241, 151, 165, 189, 194, 248, 188, 0, 127, 102, 8, 61, 96, 202, 83, 79, 61, + 37, 123, 159, 216, 255, 3, 92, 244, 33, 124, 174, 141, 245, 168, 0, 0, 12, 246, 109, 107, 66, 84, 250, 206, + 202, 254, 0, 127, 139, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 120, 156, 237, 157, 121, 80, 85, 215, 29, 199, 239, 123, 44, 162, 226, 174, 169, 85, 169, + 141, 162, 113, 71, 130, 130, 40, 136, 24, 21, 17, 171, 141, 90, 12, 209, 184, 32, 110, 169, 26, 212, 113, + 11, 46, 35, 118, 104, 106, 236, 168, 213, 208, 73, 167, 85, 18, 116, 154, 70, 52, 81, 99, 83, 199, 26, 180, + 65, 180, 128, 40, 46, 80, 59, 238, 21, 245, 53, 104, 159, 236, 16, 224, 244, 156, 231, 61, 237, 245, 114, + 207, 123, 44, 23, 126, 199, 119, 238, 119, 230, 251, 191, 243, 251, 124, 61, 231, 247, 251, 221, 3, 72, 8, + 33, 201, 176, 97, 195, 134, 13, 27, 54, 108, 216, 176, 97, 195, 134, 13, 27, 54, 108, 216, 176, 97, 195, + 134, 13, 27, 54, 236, 92, 62, 112, 224, 128, 97, 129, 109, 72, 108, 153, 76, 38, 195, 134, 13, 27, 54, 108, + 216, 176, 97, 195, 134, 13, 11, 98, 94, 4, 93, 7, 81, 205, 139, 160, 235, 32, 170, 121, 17, 116, 29, 68, + 53, 47, 130, 174, 131, 168, 230, 69, 208, 117, 16, 213, 188, 8, 186, 14, 162, 154, 23, 65, 215, 65, 84, + 243, 34, 232, 58, 136, 106, 94, 4, 93, 7, 81, 205, 139, 160, 235, 32, 170, 121, 17, 116, 29, 68, 53, 47, + 130, 174, 131, 168, 230, 69, 208, 117, 16, 213, 188, 8, 186, 14, 162, 154, 23, 65, 215, 65, 84, 243, 34, + 232, 58, 136, 106, 94, 4, 93, 7, 81, 205, 139, 160, 235, 32, 170, 121, 17, 116, 29, 68, 53, 47, 130, 174, + 131, 168, 230, 69, 208, 117, 16, 213, 188, 8, 186, 14, 162, 154, 23, 65, 215, 65, 84, 243, 34, 232, 58, + 136, 106, 94, 4, 93, 7, 81, 205, 139, 160, 235, 32, 170, 121, 17, 116, 29, 68, 53, 47, 130, 174, 131, 168, + 230, 69, 208, 117, 16, 213, 188, 8, 186, 14, 162, 154, 23, 65, 215, 65, 84, 243, 34, 232, 58, 136, 106, 94, + 4, 93, 7, 81, 205, 139, 160, 235, 32, 168, 77, 188, 100, 128, 131, 90, 136, 104, 165, 12, 254, 226, 217, 5, + 219, 204, 67, 14, 56, 168, 133, 144, 198, 50, 99, 171, 115, 96, 240, 23, 195, 75, 227, 227, 227, 91, 181, + 111, 223, 158, 32, 112, 129, 204, 1, 7, 181, 16, 209, 8, 235, 114, 126, 126, 254, 155, 203, 151, 47, 119, + 113, 117, 117, 5, 203, 1, 7, 181, 16, 209, 72, 161, 83, 151, 47, 95, 14, 154, 54, 109, 154, 100, 54, 155, + 37, 57, 3, 205, 150, 3, 14, 106, 33, 162, 145, 74, 85, 216, 7, 211, 210, 210, 6, 140, 24, 49, 194, 134, 69, + 170, 125, 22, 52, 73, 14, 56, 168, 133, 136, 86, 243, 167, 42, 174, 174, 174, 254, 117, 74, 74, 74, 247, 1, + 3, 6, 16, 60, 90, 61, 162, 174, 57, 224, 160, 22, 34, 154, 197, 159, 202, 82, 92, 92, 188, 102, 199, 142, + 29, 237, 186, 118, 237, 202, 202, 129, 164, 71, 14, 56, 168, 133, 136, 118, 196, 159, 234, 198, 211, 167, + 79, 231, 196, 197, 197, 185, 183, 108, 217, 82, 146, 154, 160, 55, 224, 160, 22, 34, 186, 174, 252, 169, + 206, 223, 186, 117, 43, 44, 58, 58, 218, 228, 230, 230, 102, 203, 1, 57, 19, 76, 47, 74, 106, 72, 22, 56, + 168, 133, 136, 174, 47, 127, 162, 26, 236, 99, 233, 233, 233, 126, 227, 198, 141, 163, 248, 26, 221, 27, + 112, 80, 11, 17, 221, 16, 254, 84, 21, 216, 191, 59, 121, 242, 100, 47, 63, 63, 63, 27, 194, 198, 228, 128, + 131, 90, 136, 232, 198, 240, 167, 122, 90, 94, 94, 30, 191, 111, 223, 190, 206, 189, 123, 247, 38, 40, 27, + 52, 43, 112, 80, 11, 17, 173, 7, 127, 170, 251, 133, 133, 133, 239, 110, 222, 188, 185, 85, 135, 14, 29, + 108, 119, 66, 125, 114, 192, 65, 45, 68, 180, 158, 252, 169, 114, 242, 243, 243, 167, 197, 198, 198, 186, + 180, 104, 209, 130, 230, 192, 108, 114, 48, 43, 112, 80, 11, 17, 221, 20, 252, 169, 78, 95, 185, 114, 101, + 244, 140, 25, 51, 254, 183, 79, 150, 52, 102, 5, 131, 191, 211, 242, 39, 170, 198, 254, 99, 106, 106, 234, + 64, 127, 127, 127, 187, 61, 162, 97, 167, 228, 79, 85, 92, 83, 83, 179, 243, 240, 225, 195, 61, 124, 124, + 124, 236, 246, 136, 134, 157, 146, 63, 149, 165, 172, 172, 108, 221, 206, 157, 59, 219, 117, 235, 214, 141, + 149, 3, 232, 154, 136, 228, 230, 230, 79, 245, 79, 171, 213, 58, 119, 245, 234, 213, 238, 173, 90, 181, 98, + 205, 10, 208, 181, 17, 193, 80, 252, 169, 46, 220, 188, 121, 51, 60, 38, 38, 198, 68, 103, 5, 147, 198, + 119, 5, 195, 78, 203, 159, 234, 120, 70, 70, 198, 240, 9, 19, 38, 208, 113, 128, 230, 64, 41, 251, 11, 196, + 102, 16, 7, 188, 156, 149, 63, 17, 217, 39, 255, 254, 212, 169, 83, 222, 1, 1, 1, 182, 114, 75, 205, 244, + 246, 196, 224, 207, 149, 254, 83, 89, 89, 249, 139, 253, 251, 247, 191, 210, 167, 79, 31, 82, 246, 38, 127, + 123, 34, 50, 255, 27, 57, 57, 208, 188, 89, 250, 87, 73, 73, 201, 178, 173, 91, 183, 182, 150, 247, 201, + 224, 239, 212, 57, 224, 165, 59, 127, 95, 119, 119, 180, 109, 209, 34, 244, 232, 254, 125, 104, 222, 44, + 93, 121, 252, 248, 241, 140, 85, 171, 86, 185, 182, 110, 221, 154, 96, 168, 215, 119, 5, 131, 191, 3, 254, + 146, 132, 188, 177, 71, 182, 107, 135, 126, 187, 101, 11, 42, 180, 90, 161, 121, 179, 244, 205, 181, 107, + 215, 66, 34, 35, 35, 37, 23, 23, 23, 154, 131, 102, 205, 0, 7, 188, 116, 231, 143, 59, 45, 228, 143, 237, + 35, 231, 96, 130, 151, 23, 58, 244, 241, 199, 168, 178, 188, 28, 154, 183, 150, 200, 251, 228, 207, 206, + 157, 59, 55, 56, 48, 48, 208, 134, 68, 106, 198, 179, 128, 3, 94, 186, 243, 15, 34, 255, 247, 177, 73, 14, + 134, 99, 15, 194, 198, 93, 23, 250, 217, 144, 33, 40, 245, 203, 47, 161, 121, 179, 84, 82, 93, 93, 189, + 251, 200, 145, 35, 94, 142, 246, 201, 6, 127, 251, 252, 199, 98, 214, 33, 216, 193, 114, 14, 70, 200, 57, + 24, 136, 221, 31, 123, 81, 104, 40, 202, 73, 79, 135, 230, 205, 210, 191, 43, 42, 42, 214, 239, 218, 181, + 171, 125, 143, 30, 61, 154, 60, 7, 28, 240, 210, 157, 255, 68, 204, 120, 60, 54, 205, 129, 242, 60, 24, 38, + 103, 96, 136, 217, 140, 54, 68, 69, 161, 187, 55, 110, 64, 243, 102, 233, 166, 213, 106, 157, 191, 97, 195, + 134, 22, 170, 125, 242, 11, 25, 104, 108, 14, 56, 224, 165, 59, 255, 159, 96, 190, 147, 176, 195, 176, 199, + 169, 114, 16, 40, 231, 192, 15, 251, 53, 210, 39, 180, 108, 137, 118, 172, 92, 137, 158, 88, 44, 208, 188, + 89, 250, 251, 237, 219, 183, 39, 145, 125, 178, 135, 135, 135, 36, 253, 255, 44, 208, 101, 102, 228, 128, + 151, 238, 252, 167, 97, 174, 83, 177, 213, 57, 8, 197, 30, 141, 61, 74, 145, 3, 95, 185, 55, 8, 237, 210, + 5, 125, 178, 125, 59, 42, 43, 41, 129, 230, 205, 210, 87, 217, 217, 217, 254, 97, 97, 97, 20, 157, 46, 119, + 2, 7, 188, 116, 231, 31, 137, 121, 206, 192, 166, 57, 152, 140, 29, 78, 230, 0, 236, 55, 176, 199, 200, + 189, 193, 40, 185, 55, 8, 144, 103, 5, 146, 131, 41, 222, 222, 232, 196, 129, 3, 168, 186, 170, 10, 154, + 183, 150, 42, 177, 255, 112, 250, 244, 105, 111, 95, 95, 95, 27, 190, 198, 230, 128, 3, 94, 186, 243, 159, + 133, 57, 70, 97, 207, 36, 61, 191, 156, 131, 159, 106, 156, 7, 99, 84, 231, 1, 153, 25, 7, 99, 247, 195, + 158, 19, 16, 128, 46, 156, 58, 5, 205, 155, 37, 107, 101, 101, 101, 66, 82, 82, 210, 43, 222, 222, 222, 4, + 99, 131, 127, 134, 141, 3, 94, 186, 243, 159, 75, 248, 97, 207, 198, 126, 27, 251, 45, 57, 7, 211, 25, 57, + 80, 223, 11, 254, 242, 172, 64, 230, 198, 216, 201, 147, 209, 63, 46, 93, 130, 230, 205, 210, 131, 178, + 178, 178, 229, 9, 9, 9, 158, 157, 58, 117, 178, 221, 9, 90, 57, 16, 141, 255, 124, 204, 109, 30, 54, 201, + 193, 59, 138, 28, 40, 207, 3, 71, 247, 66, 160, 60, 51, 146, 89, 225, 117, 55, 55, 20, 31, 19, 131, 30, + 222, 189, 11, 205, 155, 165, 107, 22, 139, 37, 114, 229, 202, 149, 174, 238, 238, 238, 172, 28, 104, 102, + 129, 3, 94, 186, 243, 143, 198, 204, 136, 213, 57, 80, 222, 11, 90, 253, 193, 120, 85, 14, 232, 238, 128, + 206, 10, 163, 218, 182, 69, 137, 155, 54, 161, 103, 79, 159, 66, 243, 102, 41, 245, 234, 213, 171, 161, + 100, 159, 172, 248, 125, 23, 118, 51, 192, 1, 47, 221, 249, 47, 192, 172, 22, 200, 25, 80, 230, 96, 142, + 42, 7, 180, 79, 124, 147, 244, 125, 216, 17, 216, 172, 221, 193, 8, 121, 86, 232, 75, 238, 141, 238, 221, + 209, 231, 137, 137, 188, 238, 147, 201, 251, 228, 207, 47, 92, 184, 48, 56, 40, 40, 200, 134, 88, 178, 51, + 51, 114, 192, 75, 119, 254, 49, 152, 81, 140, 156, 129, 5, 138, 12, 204, 151, 207, 2, 117, 111, 16, 41, + 247, 6, 234, 28, 208, 221, 193, 104, 233, 197, 221, 129, 143, 124, 30, 68, 14, 26, 132, 190, 249, 226, 11, + 132, 106, 106, 160, 153, 107, 169, 164, 166, 166, 230, 55, 71, 143, 30, 245, 26, 52, 104, 144, 58, 7, 74, + 65, 243, 106, 50, 254, 172, 28, 204, 115, 144, 3, 123, 61, 162, 50, 7, 164, 63, 28, 32, 61, 223, 39, 95, + 78, 75, 131, 230, 205, 82, 65, 73, 73, 73, 220, 238, 221, 187, 59, 56, 218, 39, 59, 137, 107, 241, 87, 230, + 160, 46, 189, 1, 157, 21, 212, 59, 164, 55, 164, 218, 179, 194, 112, 57, 3, 62, 100, 159, 60, 115, 38, 186, + 147, 151, 7, 205, 155, 165, 91, 207, 158, 61, 139, 222, 178, 101, 139, 7, 221, 39, 155, 156, 243, 93, 42, + 147, 191, 250, 44, 104, 72, 143, 168, 158, 21, 104, 111, 64, 190, 43, 144, 189, 129, 109, 159, 28, 27, 139, + 190, 123, 244, 8, 154, 55, 75, 153, 247, 238, 221, 139, 88, 188, 120, 177, 89, 49, 43, 212, 234, 13, 94, + 98, 163, 133, 152, 131, 35, 179, 238, 134, 198, 206, 140, 116, 86, 8, 237, 220, 25, 37, 125, 240, 1, 42, + 45, 46, 134, 230, 205, 210, 159, 51, 50, 50, 2, 194, 195, 195, 233, 40, 224, 44, 119, 2, 90, 68, 238, 228, + 122, 88, 157, 7, 229, 188, 160, 222, 33, 41, 191, 45, 216, 203, 129, 175, 124, 30, 76, 233, 213, 11, 125, + 245, 233, 167, 168, 234, 251, 239, 161, 121, 107, 137, 236, 147, 247, 159, 57, 115, 166, 143, 19, 253, 44, + 99, 189, 249, 211, 12, 208, 28, 208, 51, 65, 43, 7, 172, 243, 128, 206, 140, 234, 123, 129, 204, 10, 100, + 135, 52, 103, 248, 112, 116, 254, 228, 73, 104, 222, 44, 61, 171, 168, 168, 248, 101, 114, 114, 242, 15, + 250, 246, 237, 107, 183, 71, 124, 9, 212, 32, 254, 90, 57, 136, 145, 94, 236, 17, 232, 189, 160, 236, 15, + 234, 178, 59, 160, 179, 2, 249, 182, 240, 94, 68, 4, 202, 203, 206, 134, 230, 205, 210, 131, 226, 226, 226, + 21, 241, 241, 241, 158, 93, 186, 116, 33, 181, 124, 25, 115, 208, 40, 254, 172, 59, 65, 221, 31, 168, 251, + 68, 173, 221, 65, 168, 244, 226, 187, 3, 242, 93, 129, 204, 10, 126, 100, 159, 28, 29, 205, 243, 62, 249, + 186, 197, 98, 121, 107, 237, 218, 181, 110, 245, 249, 125, 23, 156, 72, 23, 254, 172, 123, 129, 149, 3, + 229, 238, 128, 228, 128, 181, 59, 32, 231, 1, 153, 25, 73, 111, 16, 212, 182, 45, 250, 40, 46, 14, 61, 123, + 242, 4, 154, 55, 75, 103, 175, 95, 191, 62, 54, 42, 42, 74, 162, 191, 71, 219, 212, 140, 191, 63, 185, 129, + 66, 139, 117, 54, 43, 11, 202, 254, 64, 43, 7, 246, 118, 72, 36, 7, 126, 114, 14, 194, 186, 117, 67, 127, + 218, 187, 23, 85, 148, 149, 65, 243, 214, 18, 217, 39, 167, 100, 102, 102, 250, 140, 25, 51, 134, 214, 152, + 231, 59, 65, 119, 254, 172, 28, 40, 251, 68, 229, 121, 96, 111, 151, 168, 181, 67, 162, 179, 66, 228, 192, + 129, 232, 116, 74, 10, 52, 111, 150, 74, 177, 247, 30, 63, 126, 252, 71, 242, 219, 19, 94, 123, 131, 38, + 227, 175, 149, 3, 229, 189, 48, 79, 145, 3, 173, 153, 81, 107, 119, 64, 115, 64, 102, 133, 33, 210, 243, + 119, 7, 139, 66, 66, 208, 165, 111, 191, 133, 230, 205, 82, 65, 89, 89, 89, 220, 158, 61, 123, 58, 122, + 121, 121, 145, 122, 131, 255, 12, 91, 115, 243, 87, 103, 65, 121, 47, 208, 254, 192, 222, 238, 192, 209, + 123, 52, 50, 43, 12, 53, 155, 209, 250, 200, 72, 116, 39, 55, 23, 154, 55, 75, 183, 172, 86, 235, 194, 109, + 219, 182, 121, 180, 105, 211, 134, 212, 29, 244, 111, 173, 40, 249, 47, 105, 102, 171, 179, 160, 236, 15, + 212, 247, 66, 93, 115, 64, 103, 133, 0, 15, 15, 180, 99, 197, 10, 244, 221, 195, 135, 208, 188, 89, 202, + 186, 123, 247, 238, 148, 165, 75, 151, 154, 233, 251, 100, 73, 227, 157, 186, 51, 243, 87, 103, 64, 153, 3, + 122, 47, 208, 183, 7, 234, 29, 146, 163, 221, 1, 157, 21, 198, 202, 251, 228, 146, 162, 34, 104, 222, 44, + 253, 229, 226, 197, 139, 129, 17, 17, 17, 146, 204, 27, 170, 55, 0, 225, 111, 47, 7, 202, 254, 64, 189, 75, + 84, 239, 14, 194, 228, 28, 40, 119, 7, 36, 7, 175, 75, 207, 247, 136, 100, 159, 124, 60, 41, 137, 215, 125, + 50, 249, 71, 125, 146, 154, 154, 250, 218, 200, 145, 35, 9, 11, 136, 223, 119, 1, 202, 159, 117, 39, 208, + 28, 168, 119, 202, 202, 153, 145, 228, 192, 209, 187, 131, 161, 210, 243, 123, 225, 157, 97, 195, 80, 250, + 215, 95, 67, 243, 102, 169, 176, 178, 178, 242, 87, 201, 201, 201, 93, 251, 245, 235, 71, 152, 52, 231, + 172, 0, 206, 190, 46, 231, 129, 189, 28, 40, 103, 198, 9, 82, 237, 183, 234, 116, 86, 176, 237, 147, 195, + 195, 81, 94, 86, 22, 52, 111, 150, 30, 150, 150, 150, 174, 76, 72, 72, 104, 211, 185, 115, 103, 86, 14, 36, + 157, 115, 128, 222, 229, 204, 75, 21, 166, 153, 80, 103, 97, 174, 164, 125, 47, 144, 28, 208, 123, 65, 125, + 30, 208, 89, 97, 24, 217, 39, 207, 155, 135, 242, 239, 220, 129, 230, 205, 82, 174, 197, 98, 137, 90, 183, + 110, 157, 155, 157, 223, 119, 225, 180, 252, 181, 178, 160, 204, 129, 122, 94, 80, 126, 99, 114, 180, 67, + 34, 57, 32, 223, 151, 200, 157, 16, 236, 233, 137, 62, 122, 255, 125, 100, 229, 119, 159, 252, 183, 220, + 220, 220, 113, 179, 102, 205, 146, 20, 127, 151, 81, 239, 239, 10, 224, 140, 235, 147, 1, 117, 14, 212, + 125, 162, 214, 189, 192, 154, 25, 233, 207, 43, 76, 36, 251, 228, 61, 123, 120, 221, 39, 147, 199, 178, 71, + 206, 159, 63, 63, 52, 56, 56, 152, 240, 210, 187, 71, 4, 231, 219, 152, 28, 104, 205, 141, 172, 221, 193, + 68, 70, 14, 200, 119, 5, 114, 30, 68, 246, 239, 143, 254, 122, 232, 16, 170, 225, 243, 125, 50, 9, 103, + 226, 177, 99, 199, 126, 172, 199, 223, 90, 121, 25, 249, 107, 229, 64, 171, 55, 32, 57, 208, 218, 33, 177, + 118, 7, 244, 253, 9, 153, 21, 72, 127, 176, 48, 56, 24, 101, 159, 61, 11, 205, 155, 165, 39, 120, 86, 216, + 148, 152, 152, 216, 169, 103, 207, 158, 132, 95, 99, 103, 5, 244, 243, 151, 208, 172, 44, 168, 207, 131, + 250, 230, 128, 204, 140, 100, 86, 240, 53, 153, 208, 250, 233, 211, 209, 237, 235, 215, 161, 121, 179, 116, + 167, 168, 168, 104, 209, 198, 141, 27, 237, 237, 147, 235, 146, 3, 112, 150, 122, 100, 161, 46, 57, 80, + 126, 91, 112, 180, 67, 162, 179, 66, 160, 135, 7, 250, 112, 217, 50, 158, 247, 201, 23, 239, 221, 187, 55, + 117, 201, 146, 37, 102, 197, 223, 101, 172, 79, 143, 8, 206, 175, 41, 206, 3, 186, 71, 80, 230, 64, 249, + 173, 81, 61, 51, 78, 146, 180, 103, 70, 250, 179, 205, 99, 59, 118, 68, 251, 19, 18, 80, 73, 97, 33, 52, + 111, 150, 78, 230, 228, 228, 140, 154, 60, 121, 114, 157, 127, 150, 209, 153, 248, 219, 203, 1, 107, 119, + 192, 154, 25, 181, 118, 72, 228, 231, 21, 72, 143, 56, 245, 213, 87, 209, 177, 125, 251, 120, 222, 39, 39, + 159, 57, 115, 166, 95, 61, 122, 68, 180, 220, 9, 189, 76, 182, 242, 126, 80, 102, 65, 125, 47, 212, 245, + 60, 32, 179, 2, 185, 23, 230, 250, 249, 161, 115, 39, 78, 64, 243, 102, 169, 168, 170, 170, 234, 195, 131, + 7, 15, 254, 176, 14, 127, 187, 27, 156, 85, 115, 231, 96, 137, 84, 123, 127, 96, 47, 7, 90, 231, 1, 153, + 21, 200, 91, 245, 247, 194, 194, 80, 110, 102, 38, 52, 111, 150, 30, 149, 151, 151, 175, 218, 190, 125, + 123, 91, 59, 239, 147, 193, 25, 65, 159, 7, 234, 254, 192, 222, 183, 5, 229, 59, 36, 50, 51, 146, 89, 193, + 223, 213, 21, 109, 157, 59, 23, 61, 184, 125, 27, 154, 55, 75, 121, 5, 5, 5, 111, 175, 89, 179, 70, 249, + 62, 153, 230, 0, 156, 77, 115, 231, 64, 217, 43, 40, 231, 5, 173, 254, 64, 153, 3, 214, 251, 19, 58, 43, + 140, 246, 244, 68, 123, 215, 175, 71, 214, 130, 2, 104, 222, 44, 165, 229, 229, 229, 141, 159, 61, 123, + 182, 242, 125, 50, 56, 19, 30, 206, 2, 173, 28, 176, 118, 137, 100, 102, 212, 218, 29, 144, 239, 10, 100, + 86, 8, 239, 218, 21, 125, 182, 123, 55, 42, 47, 45, 133, 230, 173, 37, 219, 62, 57, 43, 43, 203, 55, 36, + 36, 132, 100, 224, 191, 212, 145, 41, 24, 54, 107, 105, 49, 0, 0, 4, 92, 109, 107, 66, 84, 250, 206, 202, + 254, 0, 127, 144, 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 120, 156, 237, 154, 127, 109, 195, 48, 16, 70, 7, 97, 16, 6, 97, 16, 10, 97, 16, 10, 161, 16, + 6, 161, 16, 6, 97, 16, 10, 97, 16, 10, 161, 12, 186, 158, 180, 72, 81, 228, 239, 179, 221, 158, 155, 72, + 123, 79, 122, 255, 181, 190, 56, 231, 156, 127, 36, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 158, + 207, 235, 227, 156, 110, 126, 223, 140, 182, 222, 111, 142, 142, 251, 243, 23, 243, 120, 243, 163, 33, 222, + 183, 105, 167, 245, 62, 237, 205, 245, 124, 119, 180, 115, 48, 237, 180, 182, 145, 73, 70, 254, 151, 68, + 110, 222, 42, 253, 201, 140, 123, 190, 185, 55, 241, 92, 238, 94, 43, 215, 57, 241, 85, 185, 134, 214, 251, + 125, 18, 255, 239, 25, 67, 153, 140, 200, 127, 112, 185, 250, 90, 48, 106, 220, 149, 242, 249, 106, 254, + 227, 198, 205, 156, 75, 37, 246, 174, 161, 157, 140, 235, 200, 102, 84, 254, 3, 87, 95, 71, 197, 141, 152, + 165, 49, 160, 230, 128, 47, 115, 141, 19, 239, 13, 113, 143, 13, 237, 100, 212, 161, 108, 70, 230, 63, 80, + 227, 122, 100, 220, 82, 46, 212, 189, 191, 136, 235, 235, 189, 214, 150, 181, 132, 154, 67, 214, 170, 253, + 129, 234, 91, 244, 103, 215, 224, 241, 239, 30, 42, 78, 162, 111, 247, 196, 141, 181, 94, 252, 239, 108, + 226, 77, 44, 231, 158, 55, 243, 219, 90, 237, 86, 115, 246, 146, 218, 154, 71, 221, 167, 181, 106, 127, + 160, 242, 160, 242, 86, 98, 87, 185, 47, 35, 226, 186, 117, 116, 80, 170, 235, 63, 226, 183, 174, 118, 187, + 57, 123, 137, 203, 163, 187, 71, 107, 213, 254, 32, 35, 255, 129, 123, 38, 71, 197, 117, 117, 185, 84, 215, + 213, 152, 57, 155, 152, 31, 38, 198, 18, 183, 150, 56, 138, 255, 172, 89, 251, 131, 172, 252, 187, 26, 57, + 42, 110, 60, 55, 110, 238, 233, 153, 3, 84, 237, 174, 237, 251, 230, 184, 181, 132, 122, 62, 14, 29, 253, + 29, 193, 232, 231, 95, 221, 147, 172, 184, 46, 63, 165, 123, 171, 230, 0, 149, 135, 82, 191, 162, 79, 42, + 110, 105, 207, 123, 207, 184, 123, 22, 25, 121, 112, 53, 82, 213, 183, 172, 252, 187, 61, 213, 103, 161, + 45, 53, 7, 148, 226, 170, 188, 69, 159, 84, 220, 210, 56, 82, 49, 123, 206, 31, 71, 241, 200, 250, 63, 242, + 174, 230, 181, 137, 222, 253, 95, 111, 254, 221, 222, 188, 39, 167, 193, 114, 29, 166, 242, 182, 255, 251, + 109, 107, 76, 117, 246, 176, 118, 237, 15, 70, 238, 195, 163, 78, 170, 181, 109, 86, 254, 3, 21, 95, 181, + 165, 230, 128, 229, 88, 85, 121, 155, 250, 164, 218, 153, 247, 217, 237, 31, 214, 174, 253, 193, 200, 252, + 187, 119, 51, 107, 230, 95, 213, 172, 229, 250, 189, 244, 155, 121, 205, 86, 125, 152, 247, 91, 205, 141, + 91, 168, 253, 193, 136, 252, 199, 115, 95, 59, 83, 89, 51, 255, 106, 206, 152, 175, 85, 213, 126, 125, 190, + 166, 80, 237, 204, 207, 19, 212, 58, 113, 11, 181, 63, 200, 206, 127, 237, 189, 79, 45, 110, 111, 254, 221, + 124, 238, 218, 82, 251, 149, 105, 220, 170, 26, 177, 236, 91, 105, 255, 57, 63, 79, 80, 251, 211, 45, 212, + 254, 96, 84, 253, 175, 157, 105, 102, 229, 223, 237, 61, 220, 185, 158, 202, 239, 244, 159, 210, 220, 94, + 218, 203, 170, 231, 59, 242, 171, 234, 131, 59, 111, 122, 54, 247, 228, 33, 158, 145, 195, 181, 126, 14, + 255, 140, 249, 223, 237, 63, 74, 251, 191, 9, 151, 27, 85, 83, 74, 231, 123, 110, 31, 88, 27, 99, 91, 224, + 145, 60, 188, 94, 245, 57, 200, 116, 47, 71, 196, 157, 227, 198, 96, 109, 13, 162, 254, 171, 174, 173, 84, + 211, 212, 250, 62, 246, 14, 106, 127, 208, 250, 141, 212, 51, 120, 52, 15, 209, 127, 151, 3, 85, 3, 50, + 242, 239, 206, 126, 130, 218, 123, 21, 245, 124, 170, 57, 91, 181, 167, 230, 138, 18, 91, 170, 253, 65, 70, + 30, 92, 13, 86, 181, 238, 209, 184, 239, 230, 30, 7, 45, 251, 171, 150, 239, 58, 90, 218, 235, 89, 67, 109, + 169, 246, 7, 25, 249, 87, 123, 37, 215, 206, 61, 113, 227, 249, 219, 93, 235, 223, 28, 4, 173, 251, 171, + 90, 59, 19, 247, 172, 37, 74, 108, 169, 246, 7, 89, 239, 225, 20, 189, 249, 207, 192, 157, 59, 46, 105, + 125, 191, 87, 203, 91, 203, 56, 218, 90, 237, 15, 178, 214, 97, 46, 23, 61, 113, 51, 112, 251, 142, 37, 45, + 239, 247, 91, 190, 17, 107, 25, 71, 91, 171, 253, 65, 86, 254, 213, 90, 247, 42, 218, 25, 149, 255, 210, + 30, 173, 70, 237, 217, 109, 105, 179, 182, 22, 13, 122, 198, 229, 179, 200, 202, 255, 201, 244, 187, 84, + 59, 71, 156, 59, 214, 206, 156, 20, 181, 103, 183, 165, 221, 218, 119, 98, 45, 53, 100, 13, 178, 242, 239, + 242, 89, 186, 127, 89, 249, 143, 235, 140, 181, 222, 35, 223, 208, 213, 230, 128, 214, 182, 221, 51, 112, + 79, 93, 122, 6, 113, 214, 85, 122, 183, 223, 187, 78, 85, 237, 132, 165, 179, 110, 247, 251, 22, 179, 191, + 153, 116, 177, 70, 221, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 135, 196, 55, 4, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 255, 192, 95, 14, 131, 13, 118, 199, 43, 101, 211, 0, 0, 3, 197, 109, 107, 66, 84, + 250, 206, 202, 254, 0, 127, 145, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 216, 49, 72, 162, 97, 28, 199, 241, 247, 205, 164, 40, 18, 186, + 37, 106, 9, 199, 90, 26, 162, 73, 163, 217, 165, 41, 154, 189, 33, 112, 8, 151, 166, 187, 193, 173, 166, + 182, 104, 112, 144, 6, 29, 34, 110, 105, 171, 45, 104, 104, 8, 90, 26, 156, 26, 34, 226, 36, 7, 33, 50, + 138, 206, 222, 211, 67, 195, 202, 222, 234, 242, 245, 167, 62, 223, 63, 124, 23, 95, 120, 145, 255, 199, + 103, 240, 177, 28, 199, 177, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 154, 221, 237, + 237, 173, 181, 189, 189, 109, 165, 211, 105, 43, 147, 201, 80, 11, 83, 219, 87, 186, 188, 188, 180, 6, 6, + 6, 44, 166, 245, 163, 182, 175, 249, 15, 14, 14, 254, 251, 62, 182, 109, 83, 11, 83, 219, 227, 143, 63, + 254, 248, 227, 143, 63, 254, 248, 171, 247, 97, 90, 106, 123, 252, 241, 199, 31, 127, 252, 241, 199, 31, + 127, 245, 62, 76, 75, 109, 143, 63, 254, 248, 227, 143, 63, 254, 248, 227, 175, 222, 135, 105, 169, 237, + 241, 199, 31, 127, 252, 241, 199, 31, 127, 252, 213, 251, 48, 45, 181, 61, 254, 248, 227, 143, 63, 254, + 248, 227, 143, 191, 122, 31, 166, 165, 182, 199, 31, 127, 252, 241, 199, 31, 127, 252, 241, 87, 239, 195, + 180, 212, 246, 248, 227, 143, 63, 254, 248, 227, 143, 63, 254, 234, 125, 152, 150, 218, 30, 127, 252, 241, + 199, 31, 127, 252, 241, 199, 95, 189, 15, 211, 82, 219, 227, 143, 63, 254, 248, 227, 143, 63, 254, 248, + 171, 247, 97, 90, 106, 123, 252, 241, 199, 31, 127, 252, 241, 199, 31, 127, 245, 62, 76, 75, 109, 143, 63, + 254, 248, 227, 143, 63, 254, 248, 227, 175, 222, 135, 105, 169, 237, 241, 199, 31, 127, 252, 241, 199, 31, + 127, 252, 213, 251, 48, 45, 181, 61, 254, 248, 227, 143, 63, 254, 248, 227, 143, 191, 122, 31, 166, 165, + 182, 199, 31, 127, 252, 241, 199, 31, 127, 252, 241, 87, 239, 195, 180, 212, 246, 248, 227, 143, 63, 254, + 248, 227, 143, 63, 254, 234, 125, 152, 150, 218, 30, 127, 252, 241, 199, 31, 127, 252, 241, 199, 95, 189, + 15, 211, 82, 219, 227, 143, 63, 254, 248, 227, 143, 63, 254, 248, 171, 247, 97, 90, 106, 123, 252, 241, + 199, 223, 61, 47, 71, 109, 143, 63, 254, 248, 227, 143, 127, 203, 253, 237, 202, 187, 213, 246, 248, 75, + 252, 237, 234, 200, 237, 241, 111, 169, 127, 205, 189, 167, 156, 15, 255, 206, 168, 137, 238, 79, 246, 181, + 7, 106, 123, 252, 61, 245, 127, 229, 94, 247, 190, 233, 185, 185, 57, 185, 61, 254, 158, 248, 187, 185, 79, + 134, 66, 161, 173, 253, 253, 253, 251, 199, 199, 71, 185, 61, 254, 77, 245, 111, 228, 94, 123, 65, 112, + 102, 102, 102, 99, 119, 119, 247, 166, 236, 238, 84, 71, 110, 143, 127, 83, 252, 221, 220, 71, 131, 193, + 224, 90, 42, 149, 42, 148, 74, 37, 231, 197, 200, 237, 241, 255, 146, 127, 35, 247, 158, 234, 179, 111, + 227, 227, 227, 63, 54, 55, 55, 127, 23, 139, 197, 151, 238, 248, 119, 80, 239, 192, 191, 116, 31, 26, 27, + 27, 91, 94, 95, 95, 63, 191, 190, 190, 126, 203, 29, 255, 14, 234, 131, 231, 189, 63, 16, 8, 68, 87, 86, + 86, 178, 87, 87, 87, 239, 185, 227, 223, 65, 53, 56, 239, 245, 255, 225, 253, 229, 221, 45, 196, 227, 241, + 147, 139, 139, 139, 143, 186, 227, 223, 57, 189, 114, 175, 254, 38, 236, 222, 222, 222, 200, 210, 210, 210, + 225, 217, 217, 217, 103, 221, 241, 111, 255, 234, 231, 217, 157, 157, 207, 231, 155, 157, 159, 159, 223, + 59, 62, 62, 254, 95, 119, 252, 219, 183, 87, 238, 149, 207, 171, 51, 29, 137, 68, 126, 29, 29, 29, 253, + 249, 42, 60, 254, 109, 151, 155, 251, 100, 56, 28, 222, 58, 56, 56, 184, 111, 146, 59, 254, 237, 83, 35, + 247, 167, 59, 187, 169, 169, 169, 141, 157, 157, 157, 155, 135, 135, 135, 38, 211, 119, 182, 127, 23, 140, + 155, 251, 232, 196, 196, 196, 90, 38, 147, 41, 120, 228, 142, 191, 110, 26, 185, 63, 221, 217, 141, 140, + 140, 252, 76, 38, 147, 185, 187, 187, 59, 47, 221, 107, 35, 183, 119, 204, 241, 119, 115, 31, 42, 187, 47, + 175, 174, 174, 158, 23, 10, 5, 207, 209, 235, 70, 110, 239, 152, 225, 255, 150, 123, 255, 240, 240, 240, + 247, 68, 34, 145, 205, 231, 243, 158, 99, 55, 24, 185, 189, 211, 189, 254, 110, 231, 221, 223, 215, 215, + 183, 16, 139, 197, 78, 114, 185, 156, 231, 200, 46, 35, 183, 119, 186, 211, 191, 222, 190, 226, 94, 187, + 187, 177, 253, 126, 127, 36, 26, 141, 30, 102, 179, 89, 207, 113, 63, 48, 114, 123, 167, 187, 252, 235, + 207, 251, 179, 59, 187, 178, 251, 236, 226, 226, 226, 222, 233, 233, 169, 231, 168, 159, 152, 191, 111, + 120, 172, 247, 36, 144, 207, 245, 0, 0, 6, 50, 109, 107, 66, 84, 250, 206, 202, 254, 0, 127, 146, 53, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, + 155, 75, 76, 92, 101, 20, 199, 231, 171, 189, 160, 224, 27, 21, 159, 204, 248, 162, 85, 240, 45, 90, 95, + 168, 45, 141, 90, 81, 227, 179, 15, 64, 140, 33, 117, 192, 157, 238, 52, 144, 116, 225, 198, 13, 73, 235, + 162, 186, 169, 137, 17, 19, 43, 132, 69, 93, 105, 88, 213, 196, 162, 109, 173, 229, 89, 152, 1, 106, 216, + 184, 112, 161, 49, 26, 19, 115, 61, 135, 185, 159, 115, 185, 157, 39, 51, 204, 201, 204, 249, 159, 228, 23, + 86, 108, 238, 239, 228, 156, 243, 157, 239, 155, 144, 235, 186, 33, 105, 150, 151, 151, 67, 181, 181, 181, + 33, 14, 99, 140, 38, 56, 54, 16, 27, 137, 243, 137, 139, 136, 43, 137, 6, 226, 118, 226, 65, 98, 59, 241, + 10, 177, 139, 62, 207, 103, 157, 29, 29, 238, 217, 165, 37, 119, 114, 98, 162, 24, 136, 187, 135, 255, 255, + 115, 160, 138, 168, 33, 46, 35, 174, 33, 110, 33, 238, 38, 30, 35, 218, 61, 255, 123, 171, 171, 171, 227, + 163, 163, 163, 110, 108, 126, 30, 254, 43, 3, 235, 255, 60, 147, 172, 1, 87, 152, 68, 13, 184, 141, 120, + 128, 104, 35, 94, 242, 114, 96, 255, 246, 182, 182, 21, 255, 83, 147, 147, 240, 95, 254, 216, 224, 28, 112, + 76, 162, 6, 92, 66, 92, 77, 220, 68, 220, 69, 60, 74, 60, 75, 236, 164, 79, 244, 6, 113, 226, 227, 131, 7, + 221, 197, 133, 5, 248, 175, 12, 172, 127, 158, 3, 170, 137, 11, 77, 162, 6, 92, 79, 108, 38, 90, 136, 109, + 196, 139, 196, 110, 250, 76, 251, 154, 155, 155, 255, 153, 56, 125, 218, 157, 153, 158, 134, 255, 242, 199, + 134, 173, 1, 23, 152, 68, 13, 168, 39, 110, 36, 238, 32, 30, 33, 158, 33, 118, 18, 29, 244, 169, 190, 233, + 239, 239, 119, 127, 41, 108, 22, 20, 119, 15, 255, 231, 228, 0, 207, 1, 182, 6, 212, 153, 68, 13, 216, 68, + 220, 71, 60, 73, 188, 64, 236, 161, 79, 245, 110, 125, 125, 253, 111, 223, 29, 61, 234, 206, 205, 206, 194, + 127, 101, 192, 17, 172, 1, 87, 17, 17, 162, 153, 120, 136, 120, 138, 120, 213, 203, 129, 207, 187, 187, + 187, 11, 57, 15, 138, 187, 135, 255, 180, 53, 128, 207, 131, 181, 196, 229, 196, 181, 196, 173, 196, 189, + 196, 227, 196, 115, 158, 255, 183, 170, 170, 170, 226, 35, 195, 195, 110, 60, 22, 131, 255, 202, 128, 195, + 191, 19, 186, 216, 36, 118, 66, 97, 179, 122, 39, 244, 178, 151, 3, 131, 173, 173, 173, 238, 252, 220, 220, + 90, 206, 131, 226, 238, 225, 63, 107, 13, 72, 183, 19, 226, 243, 32, 239, 3, 186, 137, 239, 7, 7, 7, 215, + 210, 7, 196, 221, 195, 127, 218, 28, 240, 159, 7, 253, 59, 161, 224, 121, 144, 107, 192, 251, 145, 72, 228, + 207, 19, 199, 143, 187, 179, 51, 51, 240, 95, 254, 216, 224, 26, 96, 103, 193, 75, 77, 114, 39, 116, 167, + 57, 247, 60, 56, 242, 118, 95, 95, 190, 231, 65, 113, 247, 240, 159, 83, 14, 228, 114, 30, 236, 171, 169, + 169, 57, 251, 245, 145, 35, 249, 220, 13, 136, 187, 135, 255, 172, 57, 144, 207, 121, 112, 255, 182, 173, + 91, 221, 88, 238, 179, 160, 184, 123, 248, 207, 234, 159, 35, 221, 121, 240, 30, 162, 213, 36, 238, 7, 247, + 120, 119, 3, 249, 204, 130, 226, 238, 225, 63, 167, 28, 200, 244, 70, 192, 127, 63, 200, 115, 192, 123, + 225, 134, 134, 63, 126, 24, 31, 119, 207, 100, 223, 11, 138, 187, 135, 255, 156, 252, 115, 164, 58, 15, + 222, 108, 146, 247, 131, 59, 136, 93, 68, 39, 125, 198, 47, 123, 122, 122, 114, 169, 1, 226, 238, 225, 63, + 59, 137, 207, 146, 246, 126, 144, 103, 193, 251, 77, 114, 22, 228, 26, 16, 117, 28, 39, 246, 213, 225, 195, + 238, 66, 60, 14, 255, 101, 142, 231, 223, 230, 64, 170, 251, 193, 224, 44, 200, 57, 240, 97, 75, 75, 203, + 191, 124, 63, 60, 61, 53, 5, 255, 101, 140, 23, 214, 191, 61, 15, 218, 89, 240, 58, 147, 156, 5, 249, 110, + 192, 206, 130, 175, 19, 223, 14, 12, 12, 100, 234, 3, 226, 238, 225, 63, 47, 108, 14, 100, 186, 27, 176, + 179, 32, 207, 1, 239, 212, 213, 213, 253, 58, 54, 54, 182, 114, 63, 0, 255, 101, 143, 13, 255, 44, 200, + 123, 193, 76, 179, 224, 39, 237, 237, 237, 43, 115, 64, 138, 157, 128, 184, 123, 248, 95, 83, 14, 4, 103, + 65, 255, 94, 208, 63, 11, 178, 255, 55, 137, 31, 63, 58, 112, 32, 85, 31, 16, 119, 15, 255, 107, 242, 111, + 115, 32, 56, 11, 70, 204, 234, 89, 144, 127, 55, 208, 197, 247, 67, 225, 112, 248, 247, 241, 99, 199, 130, + 59, 1, 113, 247, 240, 95, 80, 14, 228, 178, 23, 220, 237, 229, 192, 80, 87, 87, 151, 187, 180, 184, 8, 255, + 149, 1, 71, 186, 189, 32, 255, 110, 192, 127, 71, 204, 254, 247, 210, 223, 201, 79, 15, 29, 242, 191, 27, + 23, 119, 15, 255, 5, 249, 231, 8, 206, 130, 246, 142, 152, 223, 12, 63, 76, 60, 77, 188, 230, 229, 192, + 190, 77, 141, 141, 127, 253, 116, 242, 164, 125, 39, 32, 238, 30, 254, 11, 206, 129, 224, 44, 104, 119, 2, + 141, 102, 245, 123, 193, 14, 130, 119, 2, 195, 209, 104, 212, 206, 130, 226, 238, 225, 191, 96, 255, 254, + 28, 200, 182, 19, 224, 26, 208, 235, 56, 206, 153, 47, 134, 134, 184, 15, 136, 187, 135, 255, 162, 228, + 128, 221, 11, 102, 186, 31, 178, 111, 133, 184, 6, 124, 208, 212, 212, 244, 247, 207, 167, 78, 137, 187, + 135, 255, 162, 230, 64, 186, 157, 0, 191, 21, 122, 130, 120, 222, 36, 250, 0, 191, 25, 29, 233, 141, 70, + 197, 221, 195, 127, 209, 252, 115, 248, 223, 11, 250, 223, 10, 53, 17, 91, 76, 242, 221, 56, 215, 128, 222, + 141, 142, 35, 238, 30, 254, 139, 154, 3, 254, 62, 192, 59, 129, 76, 239, 4, 56, 7, 196, 221, 195, 255, 186, + 228, 128, 127, 39, 192, 239, 4, 110, 48, 171, 119, 195, 220, 7, 58, 249, 127, 164, 221, 195, 127, 209, 253, + 115, 216, 26, 16, 220, 13, 7, 251, 128, 184, 123, 248, 95, 151, 28, 72, 213, 7, 120, 55, 236, 255, 253, + 208, 14, 248, 175, 88, 108, 14, 100, 235, 3, 226, 238, 225, 127, 221, 252, 115, 164, 235, 3, 124, 71, 184, + 5, 254, 43, 26, 142, 96, 31, 176, 119, 132, 182, 15, 136, 187, 135, 255, 117, 245, 111, 115, 32, 85, 31, + 216, 12, 255, 21, 143, 13, 255, 110, 216, 223, 7, 196, 221, 195, 127, 73, 114, 32, 221, 94, 72, 220, 61, + 252, 151, 196, 191, 205, 129, 96, 31, 16, 119, 15, 255, 37, 205, 129, 224, 253, 128, 184, 123, 248, 47, + 105, 14, 4, 251, 128, 184, 123, 248, 47, 169, 127, 155, 3, 182, 15, 136, 187, 135, 255, 210, 225, 251, 29, + 161, 237, 3, 226, 238, 225, 191, 164, 254, 131, 57, 32, 238, 30, 254, 197, 252, 111, 128, 127, 93, 248, + 194, 230, 128, 184, 123, 248, 23, 241, 111, 115, 64, 220, 61, 252, 139, 249, 15, 225, 253, 151, 46, 224, + 95, 55, 240, 175, 27, 248, 215, 13, 252, 235, 6, 254, 117, 3, 255, 186, 129, 127, 221, 192, 191, 110, 224, + 95, 55, 240, 175, 27, 248, 215, 13, 252, 235, 6, 254, 117, 3, 255, 186, 129, 127, 221, 192, 191, 110, 224, + 95, 55, 240, 175, 27, 248, 215, 13, 252, 235, 6, 254, 117, 3, 255, 186, 129, 127, 221, 192, 191, 110, 224, + 95, 55, 240, 175, 27, 248, 215, 13, 252, 235, 6, 254, 117, 3, 255, 186, 129, 127, 221, 192, 191, 110, 224, + 95, 55, 240, 175, 27, 248, 215, 13, 252, 235, 6, 254, 117, 3, 255, 186, 129, 127, 221, 192, 191, 110, 224, + 95, 55, 240, 175, 27, 248, 215, 13, 252, 235, 6, 254, 117, 3, 255, 186, 129, 127, 221, 192, 191, 110, 224, + 95, 55, 240, 175, 27, 248, 215, 13, 252, 235, 6, 254, 117, 3, 255, 186, 129, 127, 221, 192, 191, 110, 224, + 95, 55, 240, 175, 27, 248, 215, 13, 252, 235, 6, 254, 117, 3, 255, 186, 129, 127, 221, 192, 191, 110, 224, + 95, 55, 240, 175, 27, 248, 215, 13, 252, 235, 6, 254, 65, 16, 105, 247, 240, 15, 255, 240, 15, 255, 240, + 15, 255, 240, 15, 255, 210, 223, 67, 25, 255, 1, 5, 102, 254, 184, 119, 167, 3, 104, 0, 0, 14, 215, 109, + 107, 66, 84, 250, 206, 202, 254, 0, 127, 146, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 157, 141, 145, 28, 41, 12, 133, 29, 136, 19, 113, 32, + 14, 196, 137, 56, 16, 7, 226, 68, 28, 200, 94, 233, 234, 62, 215, 187, 103, 73, 64, 207, 207, 254, 88, 175, + 106, 106, 103, 187, 105, 16, 18, 8, 208, 131, 158, 151, 151, 193, 96, 48, 24, 12, 6, 131, 193, 96, 48, 24, + 12, 6, 131, 193, 224, 63, 252, 250, 245, 235, 229, 231, 207, 159, 127, 124, 226, 58, 247, 170, 231, 226, + 115, 165, 172, 0, 101, 248, 247, 193, 255, 81, 233, 249, 138, 254, 51, 124, 255, 254, 253, 229, 211, 167, + 79, 127, 124, 226, 58, 247, 50, 124, 249, 242, 229, 223, 207, 46, 190, 125, 251, 246, 59, 239, 176, 55, + 101, 4, 244, 251, 71, 70, 212, 251, 180, 158, 149, 158, 79, 245, 191, 2, 54, 209, 254, 174, 246, 95, 245, + 81, 250, 118, 149, 166, 147, 215, 237, 223, 249, 157, 93, 84, 242, 172, 228, 4, 93, 26, 189, 94, 165, 203, + 174, 103, 237, 188, 123, 62, 112, 106, 231, 171, 122, 235, 236, 31, 229, 107, 223, 117, 185, 180, 111, 123, + 30, 154, 15, 121, 5, 170, 254, 175, 121, 101, 245, 142, 251, 159, 63, 127, 254, 247, 123, 232, 45, 210, + 253, 248, 241, 227, 247, 189, 120, 134, 186, 168, 47, 11, 68, 58, 189, 30, 233, 51, 68, 254, 158, 38, 242, + 136, 188, 185, 23, 101, 171, 94, 72, 23, 215, 245, 121, 234, 160, 105, 35, 47, 79, 71, 29, 244, 122, 252, + 141, 207, 170, 255, 199, 223, 175, 95, 191, 254, 126, 238, 10, 58, 251, 115, 77, 101, 209, 242, 35, 77, + 148, 207, 51, 89, 159, 35, 61, 247, 50, 251, 187, 12, 81, 158, 219, 8, 155, 199, 223, 208, 153, 166, 137, + 239, 140, 91, 92, 115, 61, 69, 26, 157, 243, 56, 180, 125, 69, 62, 164, 71, 23, 200, 169, 233, 84, 238, + 248, 160, 11, 218, 178, 202, 29, 215, 84, 31, 170, 103, 45, 159, 241, 125, 215, 254, 250, 204, 21, 172, + 252, 127, 86, 102, 214, 255, 233, 127, 157, 188, 129, 204, 254, 234, 111, 168, 83, 86, 119, 236, 28, 122, + 86, 125, 209, 46, 226, 131, 47, 208, 62, 168, 126, 129, 60, 86, 114, 118, 186, 64, 62, 202, 33, 63, 247, + 21, 85, 157, 253, 249, 144, 207, 203, 223, 25, 255, 239, 49, 23, 184, 197, 254, 232, 60, 250, 35, 245, 238, + 228, 165, 254, 149, 253, 125, 29, 226, 192, 182, 216, 61, 254, 70, 91, 32, 127, 254, 247, 126, 134, 172, + 244, 81, 218, 139, 66, 243, 161, 78, 153, 46, 240, 183, 46, 43, 237, 145, 185, 94, 101, 127, 100, 212, 231, + 189, 252, 76, 111, 43, 91, 92, 197, 45, 246, 167, 29, 107, 187, 239, 228, 13, 100, 246, 87, 127, 135, 239, + 205, 250, 40, 125, 221, 253, 143, 234, 54, 238, 113, 221, 253, 36, 190, 35, 179, 63, 122, 208, 54, 150, + 233, 66, 211, 169, 205, 105, 23, 200, 239, 246, 199, 63, 242, 76, 252, 229, 25, 205, 55, 174, 33, 227, 51, + 236, 79, 95, 81, 125, 208, 159, 1, 117, 245, 239, 234, 111, 25, 223, 28, 154, 30, 153, 233, 91, 250, 61, + 158, 165, 15, 116, 107, 165, 200, 139, 251, 248, 77, 192, 255, 145, 198, 239, 33, 39, 125, 47, 3, 245, 198, + 135, 100, 186, 208, 114, 50, 249, 201, 95, 199, 67, 250, 135, 255, 239, 178, 168, 252, 58, 151, 169, 244, + 233, 186, 29, 12, 6, 131, 193, 96, 48, 24, 12, 58, 56, 247, 151, 221, 127, 205, 242, 111, 193, 61, 184, + 132, 43, 56, 45, 243, 52, 125, 197, 219, 158, 194, 99, 229, 196, 165, 88, 207, 100, 113, 129, 123, 98, 85, + 254, 234, 217, 21, 159, 214, 113, 152, 143, 194, 169, 206, 174, 232, 184, 226, 109, 239, 33, 171, 198, 182, + 171, 103, 42, 206, 170, 242, 31, 85, 92, 122, 183, 252, 91, 249, 180, 71, 65, 229, 214, 61, 19, 94, 167, + 43, 114, 117, 241, 252, 123, 181, 235, 76, 86, 229, 213, 252, 254, 9, 231, 85, 165, 63, 41, 255, 86, 62, + 173, 210, 147, 243, 134, 206, 41, 250, 30, 5, 231, 120, 144, 133, 124, 156, 3, 89, 233, 172, 210, 129, 198, + 21, 187, 103, 30, 105, 127, 244, 227, 156, 92, 197, 121, 105, 220, 94, 99, 230, 85, 250, 211, 242, 111, + 225, 211, 42, 61, 17, 163, 11, 192, 179, 194, 243, 33, 243, 202, 254, 196, 237, 84, 22, 149, 179, 211, 89, + 165, 3, 181, 63, 114, 102, 242, 103, 254, 255, 202, 30, 154, 19, 251, 87, 156, 151, 115, 214, 202, 189, 86, + 28, 217, 110, 249, 212, 245, 42, 159, 86, 217, 31, 238, 88, 249, 35, 229, 20, 61, 255, 204, 70, 200, 220, + 253, 127, 170, 3, 207, 171, 146, 127, 151, 43, 91, 161, 26, 171, 224, 70, 244, 126, 197, 121, 5, 72, 171, + 92, 76, 151, 126, 183, 252, 91, 249, 180, 206, 79, 210, 135, 163, 140, 104, 15, 244, 53, 158, 221, 181, + 191, 142, 25, 158, 246, 84, 7, 167, 246, 191, 21, 234, 111, 224, 26, 148, 119, 175, 124, 83, 102, 23, 174, + 251, 220, 193, 211, 159, 148, 127, 43, 159, 214, 233, 41, 179, 183, 206, 59, 25, 23, 180, 236, 204, 70, 1, + 229, 22, 179, 180, 59, 58, 120, 13, 251, 235, 216, 201, 199, 247, 226, 41, 47, 136, 79, 83, 206, 11, 121, + 178, 235, 85, 250, 147, 242, 111, 225, 211, 50, 222, 206, 101, 3, 202, 41, 86, 101, 51, 39, 119, 174, 148, + 231, 145, 103, 71, 103, 153, 142, 61, 239, 74, 254, 174, 94, 131, 193, 96, 48, 24, 12, 6, 131, 193, 10, + 196, 190, 136, 249, 156, 130, 117, 32, 107, 152, 85, 44, 170, 75, 19, 115, 219, 29, 254, 231, 30, 216, 145, + 53, 128, 110, 30, 89, 230, 174, 44, 247, 6, 231, 98, 88, 119, 123, 12, 127, 5, 226, 31, 172, 191, 119, 214, + 38, 221, 250, 245, 153, 251, 25, 51, 174, 81, 215, 148, 129, 248, 78, 172, 240, 81, 101, 118, 215, 31, 9, + 143, 93, 7, 168, 175, 198, 183, 186, 246, 175, 103, 99, 72, 175, 250, 203, 158, 231, 25, 238, 105, 189, + 157, 247, 138, 123, 238, 151, 244, 204, 65, 166, 51, 158, 233, 244, 73, 127, 243, 56, 134, 199, 104, 179, + 242, 119, 242, 202, 100, 204, 210, 117, 215, 119, 203, 200, 244, 184, 131, 85, 28, 73, 247, 228, 87, 231, + 113, 148, 131, 240, 56, 173, 238, 213, 215, 231, 73, 163, 62, 7, 157, 43, 151, 163, 241, 64, 229, 236, 148, + 15, 112, 153, 244, 28, 81, 197, 159, 225, 243, 200, 71, 99, 254, 90, 151, 170, 252, 157, 242, 92, 198, 170, + 204, 234, 250, 142, 188, 196, 27, 85, 198, 19, 172, 236, 223, 157, 183, 4, 93, 204, 210, 249, 47, 248, 58, + 237, 255, 232, 202, 207, 51, 100, 231, 59, 201, 171, 58, 103, 66, 57, 200, 82, 157, 141, 200, 244, 239, + 124, 71, 87, 126, 149, 151, 238, 215, 119, 25, 171, 50, 171, 235, 59, 242, 102, 122, 60, 65, 199, 143, 145, + 223, 138, 103, 236, 236, 95, 233, 127, 231, 108, 17, 249, 250, 167, 203, 23, 121, 208, 253, 142, 207, 210, + 254, 158, 197, 226, 179, 242, 61, 175, 157, 179, 132, 85, 153, 213, 245, 29, 121, 51, 61, 158, 32, 27, 255, + 149, 91, 244, 54, 95, 237, 251, 185, 218, 255, 51, 93, 85, 253, 95, 203, 238, 236, 239, 28, 244, 170, 255, + 107, 222, 93, 255, 175, 230, 127, 93, 255, 215, 178, 171, 50, 171, 235, 59, 242, 222, 106, 255, 128, 142, + 45, 62, 134, 225, 159, 116, 124, 233, 248, 43, 151, 105, 53, 254, 171, 220, 110, 255, 128, 158, 225, 171, + 206, 159, 103, 186, 90, 205, 89, 124, 60, 245, 49, 78, 121, 197, 172, 124, 69, 55, 254, 107, 250, 170, 204, + 234, 250, 142, 188, 247, 176, 63, 245, 174, 214, 255, 122, 47, 107, 155, 220, 215, 62, 228, 60, 154, 207, + 255, 61, 141, 206, 145, 125, 78, 159, 205, 229, 187, 24, 129, 206, 133, 249, 158, 1, 25, 252, 62, 229, 117, + 229, 87, 121, 173, 100, 172, 202, 172, 174, 175, 210, 100, 122, 28, 12, 6, 131, 193, 96, 48, 24, 12, 42, + 232, 220, 92, 63, 87, 56, 192, 71, 163, 146, 203, 215, 31, 31, 1, 207, 226, 2, 89, 187, 251, 30, 204, 213, + 58, 130, 253, 210, 207, 68, 21, 103, 171, 246, 99, 190, 103, 60, 139, 11, 204, 246, 50, 43, 178, 184, 128, + 238, 217, 213, 253, 255, 39, 235, 87, 181, 21, 177, 54, 189, 158, 113, 110, 216, 159, 123, 158, 7, 114, + 232, 117, 231, 34, 119, 184, 60, 210, 84, 107, 244, 206, 46, 153, 30, 244, 92, 160, 114, 164, 149, 190, + 110, 229, 27, 79, 224, 251, 239, 213, 62, 85, 236, 143, 152, 19, 126, 99, 135, 35, 84, 63, 163, 241, 43, + 174, 235, 158, 121, 246, 239, 123, 188, 81, 249, 194, 44, 143, 44, 94, 157, 113, 70, 29, 47, 88, 197, 251, + 118, 56, 186, 46, 214, 169, 103, 19, 225, 215, 51, 125, 237, 200, 184, 226, 2, 79, 80, 249, 127, 236, 143, + 12, 126, 110, 37, 227, 104, 85, 7, 222, 71, 52, 14, 167, 231, 248, 40, 95, 251, 133, 115, 110, 124, 87, + 125, 84, 103, 38, 120, 94, 99, 235, 244, 147, 44, 70, 237, 253, 133, 182, 199, 249, 21, 176, 195, 209, 173, + 184, 14, 242, 171, 244, 181, 43, 227, 138, 11, 60, 193, 202, 255, 35, 43, 125, 47, 227, 85, 119, 56, 66, + 206, 82, 104, 95, 207, 202, 239, 228, 209, 124, 187, 51, 51, 33, 15, 109, 150, 114, 92, 55, 85, 57, 140, + 109, 234, 223, 40, 123, 197, 209, 157, 112, 157, 153, 190, 118, 101, 220, 229, 2, 119, 208, 233, 91, 251, + 172, 250, 120, 175, 235, 14, 71, 168, 239, 181, 204, 250, 191, 142, 223, 93, 255, 223, 177, 63, 103, 59, + 245, 44, 231, 110, 223, 210, 189, 3, 218, 111, 119, 56, 186, 93, 174, 179, 210, 215, 149, 254, 175, 207, + 223, 98, 127, 247, 255, 200, 238, 227, 63, 250, 199, 79, 86, 233, 188, 61, 249, 184, 90, 217, 95, 243, 206, + 198, 255, 29, 251, 163, 35, 191, 118, 101, 252, 63, 225, 232, 118, 185, 206, 78, 95, 87, 198, 255, 157, + 179, 142, 21, 170, 245, 191, 114, 222, 89, 76, 128, 235, 218, 111, 59, 142, 16, 249, 176, 159, 206, 49, + 179, 103, 178, 57, 112, 86, 94, 149, 71, 181, 126, 62, 153, 91, 95, 225, 232, 118, 184, 78, 79, 183, 83, + 247, 29, 25, 159, 21, 51, 24, 12, 6, 131, 193, 96, 48, 24, 188, 127, 192, 231, 232, 218, 239, 81, 184, 146, + 183, 190, 91, 227, 30, 239, 190, 215, 216, 192, 9, 118, 101, 127, 79, 92, 20, 107, 94, 56, 0, 214, 148, + 143, 168, 3, 118, 60, 1, 235, 90, 98, 122, 186, 175, 178, 219, 7, 92, 1, 142, 225, 20, 26, 79, 236, 112, + 165, 142, 175, 5, 98, 22, 190, 110, 36, 126, 22, 240, 125, 172, 190, 14, 199, 111, 232, 122, 149, 51, 24, + 241, 209, 152, 13, 109, 75, 227, 11, 232, 171, 227, 118, 85, 198, 206, 254, 93, 94, 187, 105, 180, 78, 186, + 15, 222, 229, 184, 87, 29, 65, 246, 187, 35, 180, 247, 120, 142, 235, 148, 171, 233, 2, 145, 230, 106, 223, + 202, 116, 196, 245, 236, 28, 11, 113, 11, 141, 179, 58, 7, 163, 191, 207, 69, 61, 208, 13, 122, 37, 214, + 133, 223, 113, 249, 41, 67, 99, 241, 213, 89, 1, 181, 69, 197, 209, 237, 164, 113, 153, 180, 174, 202, 121, + 82, 71, 253, 45, 161, 43, 117, 12, 40, 15, 75, 92, 15, 251, 104, 172, 80, 211, 17, 39, 165, 220, 42, 94, + 216, 161, 178, 191, 94, 175, 236, 175, 241, 113, 218, 61, 109, 18, 61, 121, 124, 75, 243, 242, 248, 118, + 197, 171, 101, 252, 137, 219, 92, 253, 152, 114, 200, 138, 157, 52, 1, 181, 159, 199, 31, 61, 142, 155, + 241, 123, 87, 234, 184, 250, 221, 49, 210, 251, 251, 4, 157, 59, 61, 221, 183, 229, 242, 120, 28, 218, 235, + 19, 112, 251, 59, 111, 64, 62, 250, 155, 148, 200, 152, 233, 6, 84, 92, 212, 142, 253, 43, 30, 67, 177, + 147, 6, 61, 42, 239, 153, 201, 171, 124, 152, 191, 71, 240, 74, 29, 79, 184, 67, 202, 229, 3, 87, 93, 249, + 150, 21, 120, 142, 49, 46, 179, 153, 239, 181, 160, 15, 57, 95, 69, 159, 208, 177, 169, 226, 13, 189, 253, + 86, 253, 113, 199, 254, 1, 245, 127, 202, 227, 41, 118, 210, 40, 231, 168, 227, 160, 202, 145, 125, 207, + 236, 191, 91, 71, 229, 4, 241, 249, 29, 119, 168, 156, 159, 238, 199, 186, 2, 29, 219, 244, 227, 123, 45, + 226, 131, 111, 244, 189, 28, 220, 83, 29, 100, 215, 149, 95, 203, 158, 239, 206, 215, 131, 202, 254, 248, + 50, 229, 212, 29, 59, 105, 84, 38, 159, 119, 42, 223, 206, 119, 250, 135, 183, 153, 147, 58, 6, 212, 6, + 186, 167, 199, 199, 103, 215, 173, 182, 147, 83, 254, 79, 161, 227, 7, 115, 204, 236, 222, 106, 143, 221, + 234, 186, 239, 37, 90, 141, 91, 126, 95, 203, 175, 100, 233, 214, 174, 183, 164, 241, 178, 43, 157, 156, + 214, 241, 244, 185, 204, 119, 93, 217, 255, 55, 24, 12, 6, 131, 193, 96, 48, 248, 187, 160, 235, 24, 93, + 207, 220, 107, 30, 217, 237, 73, 140, 117, 144, 190, 43, 101, 167, 76, 93, 171, 18, 239, 206, 214, 130, + 239, 1, 111, 65, 94, 143, 231, 176, 238, 59, 61, 71, 82, 161, 179, 63, 156, 0, 233, 118, 236, 175, 177, 22, + 214, 59, 60, 247, 22, 244, 121, 130, 183, 32, 111, 22, 143, 36, 78, 238, 49, 27, 231, 180, 136, 61, 58, + 223, 165, 80, 238, 86, 227, 21, 1, 158, 117, 159, 163, 60, 180, 199, 32, 60, 38, 171, 252, 191, 234, 51, + 75, 171, 121, 19, 67, 169, 184, 24, 47, 23, 249, 52, 150, 163, 28, 114, 199, 41, 105, 61, 181, 254, 42, 47, + 124, 206, 142, 94, 144, 93, 203, 81, 185, 78, 208, 157, 49, 113, 142, 71, 185, 8, 141, 165, 119, 62, 195, + 185, 123, 229, 149, 225, 11, 60, 70, 170, 245, 243, 243, 141, 206, 193, 86, 254, 159, 114, 178, 50, 189, + 110, 217, 222, 108, 111, 255, 216, 141, 216, 167, 199, 124, 177, 109, 182, 111, 155, 182, 2, 39, 226, 113, + 98, 236, 173, 237, 162, 211, 139, 203, 238, 114, 157, 96, 101, 127, 236, 234, 101, 102, 177, 255, 21, 143, + 232, 54, 10, 48, 7, 168, 108, 122, 146, 159, 115, 65, 222, 95, 178, 188, 171, 24, 176, 238, 15, 210, 120, + 55, 177, 214, 236, 183, 163, 42, 238, 85, 125, 141, 238, 173, 82, 174, 37, 243, 25, 43, 189, 184, 191, 67, + 174, 19, 172, 252, 191, 219, 95, 231, 9, 183, 218, 159, 126, 73, 92, 253, 81, 246, 215, 126, 177, 107, 127, + 252, 6, 121, 169, 207, 35, 95, 183, 255, 106, 111, 7, 126, 68, 121, 85, 229, 15, 192, 174, 94, 170, 250, + 158, 96, 53, 255, 163, 158, 112, 140, 186, 7, 229, 22, 251, 107, 185, 238, 135, 111, 181, 63, 58, 164, 28, + 213, 203, 174, 253, 201, 67, 199, 14, 181, 185, 238, 119, 217, 201, 7, 127, 174, 252, 159, 203, 235, 62, + 63, 211, 75, 118, 207, 229, 58, 65, 182, 254, 243, 125, 69, 58, 183, 200, 206, 95, 171, 110, 28, 43, 123, + 209, 254, 117, 255, 195, 61, 236, 175, 243, 191, 234, 220, 114, 160, 179, 155, 247, 113, 205, 147, 190, + 204, 179, 93, 62, 62, 255, 203, 100, 209, 125, 24, 43, 189, 248, 252, 207, 229, 26, 124, 76, 188, 133, 245, + 226, 224, 245, 48, 246, 255, 187, 49, 252, 254, 96, 48, 24, 12, 238, 133, 108, 253, 183, 138, 101, 128, + 183, 244, 174, 249, 142, 103, 58, 133, 174, 215, 186, 241, 182, 138, 157, 158, 96, 87, 215, 247, 44, 51, + 203, 79, 227, 63, 171, 189, 145, 1, 93, 151, 190, 5, 92, 57, 251, 80, 129, 248, 215, 238, 126, 205, 91, + 176, 163, 107, 79, 255, 8, 251, 87, 249, 105, 236, 71, 99, 21, 126, 198, 41, 227, 8, 29, 196, 45, 60, 158, + 14, 119, 166, 188, 46, 253, 143, 51, 113, 204, 125, 149, 15, 227, 158, 127, 39, 118, 170, 117, 240, 119, + 36, 86, 177, 146, 172, 110, 26, 147, 209, 118, 225, 242, 40, 178, 114, 178, 186, 194, 255, 184, 174, 53, + 142, 239, 50, 169, 189, 136, 83, 59, 87, 184, 139, 202, 255, 107, 140, 95, 207, 75, 209, 207, 148, 243, + 173, 56, 66, 47, 7, 221, 193, 157, 104, 249, 232, 69, 207, 213, 160, 31, 151, 39, 139, 57, 234, 119, 63, + 127, 75, 59, 210, 120, 58, 242, 120, 27, 240, 186, 5, 60, 150, 236, 124, 64, 182, 15, 219, 99, 179, 196, + 207, 189, 174, 21, 135, 167, 249, 86, 250, 224, 121, 226, 198, 21, 7, 187, 99, 127, 247, 255, 64, 219, 150, + 142, 83, 30, 119, 205, 56, 66, 7, 28, 149, 242, 113, 174, 195, 238, 255, 93, 251, 163, 23, 61, 143, 233, + 50, 7, 244, 108, 143, 66, 211, 101, 54, 86, 125, 101, 246, 247, 185, 136, 158, 173, 171, 242, 82, 253, 40, + 183, 216, 233, 195, 203, 225, 222, 9, 86, 254, 223, 101, 202, 246, 90, 84, 28, 161, 235, 132, 52, 221, 251, + 31, 239, 97, 127, 100, 162, 173, 101, 50, 7, 222, 146, 253, 43, 110, 241, 89, 246, 207, 230, 127, 248, 66, + 245, 151, 186, 143, 2, 159, 84, 113, 132, 174, 83, 252, 127, 215, 255, 3, 187, 254, 14, 223, 148, 233, 60, + 155, 195, 239, 248, 127, 173, 91, 38, 207, 61, 252, 127, 102, 255, 142, 91, 124, 134, 255, 247, 15, 245, + 247, 115, 176, 122, 238, 80, 231, 41, 25, 71, 232, 229, 232, 217, 193, 170, 125, 123, 90, 215, 133, 206, + 51, 171, 179, 153, 110, 55, 197, 106, 254, 23, 112, 251, 87, 243, 191, 206, 119, 102, 229, 116, 246, 239, + 184, 69, 191, 119, 207, 249, 223, 91, 199, 189, 215, 59, 131, 247, 133, 177, 255, 96, 108, 63, 24, 12, 6, + 131, 193, 96, 48, 24, 12, 6, 131, 193, 96, 48, 24, 12, 6, 131, 193, 96, 240, 247, 225, 17, 123, 209, 217, + 251, 244, 145, 193, 126, 19, 255, 172, 246, 189, 179, 199, 210, 223, 105, 17, 96, 111, 76, 246, 121, 132, + 62, 117, 111, 169, 195, 223, 105, 92, 113, 137, 236, 75, 243, 124, 125, 255, 8, 239, 0, 210, 15, 251, 55, + 158, 201, 83, 118, 117, 57, 205, 71, 247, 237, 241, 169, 236, 175, 191, 99, 194, 190, 35, 246, 217, 233, + 62, 183, 44, 207, 106, 111, 240, 173, 242, 119, 123, 245, 213, 134, 250, 30, 16, 135, 214, 27, 221, 178, + 135, 76, 251, 4, 249, 61, 171, 109, 87, 232, 234, 242, 200, 50, 117, 95, 164, 246, 141, 172, 255, 56, 216, + 175, 150, 229, 233, 159, 106, 111, 158, 63, 187, 218, 27, 178, 107, 127, 222, 203, 68, 250, 248, 223, 223, + 177, 161, 246, 127, 109, 188, 134, 253, 253, 119, 7, 212, 62, 244, 195, 14, 236, 35, 174, 160, 125, 169, + 219, 203, 22, 215, 245, 183, 69, 58, 172, 236, 79, 219, 161, 79, 59, 60, 255, 172, 255, 115, 157, 252, 121, + 151, 155, 238, 161, 212, 125, 155, 1, 218, 155, 190, 107, 137, 125, 126, 250, 140, 238, 177, 213, 124, 181, + 77, 146, 134, 239, 39, 56, 25, 67, 84, 23, 254, 174, 161, 172, 111, 43, 168, 91, 87, 158, 250, 130, 204, + 246, 140, 189, 248, 134, 85, 153, 228, 169, 239, 239, 81, 153, 245, 253, 114, 39, 246, 247, 189, 238, 92, + 231, 127, 173, 39, 231, 146, 116, 156, 84, 89, 184, 207, 119, 244, 138, 204, 122, 46, 68, 243, 165, 61, + 168, 220, 87, 124, 211, 201, 126, 113, 61, 95, 161, 190, 0, 121, 170, 190, 77, 187, 220, 241, 231, 217, + 217, 1, 205, 199, 247, 150, 175, 228, 199, 143, 107, 254, 1, 116, 167, 239, 98, 83, 61, 50, 230, 251, 124, + 165, 210, 177, 207, 121, 180, 78, 218, 95, 125, 79, 175, 238, 101, 215, 249, 148, 230, 145, 189, 219, 143, + 246, 224, 253, 240, 116, 76, 224, 156, 83, 54, 159, 113, 96, 67, 255, 237, 204, 106, 28, 102, 253, 180, 51, + 150, 35, 203, 233, 220, 176, 179, 63, 122, 213, 49, 11, 255, 233, 237, 72, 237, 175, 254, 93, 247, 154, + 147, 231, 137, 253, 245, 92, 34, 237, 87, 203, 204, 222, 93, 229, 243, 172, 202, 254, 252, 79, 59, 190, 50, + 39, 64, 190, 236, 227, 64, 126, 116, 71, 27, 206, 252, 58, 186, 171, 252, 170, 231, 123, 229, 221, 117, + 129, 202, 254, 234, 55, 1, 109, 49, 139, 21, 232, 153, 81, 93, 223, 80, 87, 157, 31, 86, 231, 27, 50, 251, + 83, 174, 142, 229, 122, 93, 207, 165, 122, 159, 210, 115, 31, 157, 253, 145, 201, 219, 215, 51, 208, 197, + 93, 118, 231, 22, 145, 238, 170, 220, 221, 120, 119, 210, 158, 244, 221, 58, 218, 151, 62, 218, 121, 138, + 193, 96, 240, 161, 241, 15, 136, 36, 106, 162, 235, 119, 189, 22, 0, 0, 18, 36, 109, 107, 66, 84, 250, 206, + 202, 254, 0, 127, 152, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 120, 156, 237, 157, 107, 88, 85, 85, 26, 199, 15, 183, 99, 66, 152, 78, 74, 13, 100, 163, + 49, 102, 20, 163, 121, 87, 84, 66, 188, 12, 198, 32, 101, 78, 153, 38, 98, 150, 89, 222, 26, 21, 5, 36, 68, + 176, 80, 76, 157, 156, 74, 209, 201, 102, 154, 24, 165, 68, 51, 63, 88, 163, 101, 165, 146, 58, 227, 5, 26, + 42, 149, 81, 71, 37, 209, 49, 4, 143, 192, 185, 0, 107, 222, 247, 204, 90, 211, 106, 179, 15, 156, 179, + 246, 62, 231, 96, 207, 250, 63, 207, 255, 241, 241, 67, 125, 240, 247, 238, 181, 254, 239, 187, 214, 222, + 167, 251, 128, 1, 3, 12, 32, 31, 176, 159, 143, 143, 143, 175, 207, 143, 101, 224, 133, 127, 191, 25, 140, + 122, 239, 189, 247, 12, 132, 16, 233, 150, 93, 213, 208, 208, 176, 116, 195, 134, 13, 157, 187, 117, 235, + 134, 255, 108, 190, 45, 213, 129, 183, 185, 74, 254, 186, 155, 233, 156, 201, 100, 154, 153, 147, 147, 211, + 254, 214, 91, 111, 117, 84, 7, 94, 231, 42, 249, 187, 141, 63, 211, 241, 11, 23, 46, 60, 50, 107, 214, 44, + 191, 192, 192, 64, 252, 103, 244, 187, 25, 235, 64, 242, 23, 230, 207, 180, 167, 172, 172, 108, 104, 66, + 66, 2, 251, 247, 196, 58, 104, 182, 39, 180, 85, 75, 254, 154, 249, 163, 26, 192, 127, 57, 112, 224, 64, + 196, 224, 193, 131, 91, 204, 136, 109, 205, 146, 191, 46, 252, 153, 76, 54, 155, 237, 213, 173, 91, 183, + 134, 69, 68, 68, 180, 90, 7, 109, 161, 87, 144, 252, 117, 229, 207, 84, 105, 177, 88, 22, 174, 93, 187, + 182, 67, 72, 72, 136, 163, 108, 224, 195, 215, 128, 222, 146, 252, 189, 202, 159, 233, 228, 213, 171, 87, + 167, 164, 167, 167, 27, 219, 183, 111, 223, 98, 70, 148, 252, 219, 188, 181, 232, 224, 201, 147, 39, 199, + 36, 37, 37, 249, 4, 4, 4, 24, 104, 13, 52, 171, 3, 201, 191, 77, 91, 15, 125, 112, 252, 248, 241, 190, 35, + 71, 142, 100, 152, 220, 182, 39, 72, 254, 109, 146, 63, 202, 12, 206, 223, 189, 123, 119, 247, 126, 253, + 250, 217, 81, 185, 163, 14, 36, 255, 54, 203, 159, 169, 202, 108, 54, 47, 203, 207, 207, 239, 210, 205, + 241, 60, 89, 56, 27, 72, 254, 109, 158, 63, 211, 191, 77, 38, 211, 11, 185, 185, 185, 129, 29, 58, 116, 48, + 24, 116, 202, 6, 146, 255, 77, 195, 159, 169, 228, 226, 197, 139, 227, 231, 206, 157, 235, 199, 245, 10, + 190, 162, 251, 130, 228, 127, 211, 241, 103, 218, 123, 226, 196, 137, 225, 137, 137, 137, 140, 143, 80, 54, + 144, 252, 111, 90, 254, 40, 156, 39, 23, 28, 56, 112, 224, 129, 225, 195, 135, 219, 113, 186, 90, 7, 146, + 255, 77, 205, 159, 233, 134, 205, 102, 91, 83, 88, 88, 24, 26, 25, 25, 137, 168, 90, 188, 115, 32, 249, + 255, 228, 248, 51, 85, 214, 215, 215, 167, 228, 229, 229, 117, 184, 227, 142, 59, 156, 170, 3, 201, 255, + 39, 197, 159, 233, 212, 213, 171, 87, 147, 50, 51, 51, 141, 65, 65, 65, 246, 108, 160, 82, 7, 78, 179, 151, + 252, 111, 58, 254, 76, 95, 158, 58, 117, 42, 46, 57, 57, 217, 199, 104, 52, 178, 58, 80, 246, 10, 146, 255, + 79, 151, 63, 211, 135, 71, 142, 28, 233, 63, 98, 196, 8, 182, 236, 187, 124, 231, 64, 242, 119, 158, 127, + 99, 99, 163, 40, 39, 119, 202, 2, 222, 244, 209, 71, 31, 133, 139, 220, 61, 145, 252, 157, 231, 255, 236, + 144, 33, 228, 31, 159, 124, 34, 136, 201, 237, 186, 102, 181, 90, 115, 54, 110, 220, 216, 229, 158, 123, + 238, 105, 49, 35, 74, 254, 98, 252, 251, 27, 12, 100, 32, 56, 53, 49, 145, 156, 46, 41, 17, 229, 228, 110, + 157, 175, 173, 173, 125, 33, 43, 43, 43, 176, 99, 199, 142, 108, 79, 112, 152, 17, 37, 127, 231, 249, 199, + 2, 251, 104, 112, 95, 240, 176, 118, 237, 72, 222, 204, 153, 228, 242, 133, 11, 162, 156, 220, 173, 210, + 138, 138, 138, 199, 230, 205, 155, 103, 244, 243, 243, 243, 119, 212, 39, 72, 254, 206, 243, 255, 53, 112, + 31, 5, 30, 129, 252, 193, 15, 130, 71, 119, 236, 72, 222, 202, 202, 34, 166, 234, 106, 81, 78, 238, 148, 9, + 246, 132, 123, 195, 195, 195, 17, 116, 128, 218, 58, 32, 249, 59, 207, 63, 1, 120, 143, 5, 243, 117, 16, 5, + 238, 13, 126, 164, 107, 87, 178, 115, 227, 70, 98, 181, 88, 68, 89, 185, 67, 151, 44, 22, 75, 55, 200, 3, + 216, 36, 222, 2, 188, 89, 13, 72, 254, 2, 252, 39, 32, 103, 240, 111, 192, 15, 131, 199, 128, 71, 210, 58, + 128, 228, 77, 250, 128, 147, 122, 245, 34, 95, 236, 220, 41, 202, 75, 111, 125, 91, 89, 89, 121, 103, 231, + 206, 157, 131, 1, 115, 16, 240, 54, 130, 253, 185, 53, 64, 242, 119, 129, 255, 100, 224, 251, 4, 152, 175, + 131, 177, 92, 29, 196, 208, 124, 216, 15, 60, 55, 54, 150, 124, 245, 229, 151, 162, 220, 244, 210, 17, 16, + 14, 140, 111, 7, 119, 0, 222, 237, 233, 26, 32, 249, 11, 240, 159, 134, 207, 55, 120, 18, 248, 113, 240, + 99, 224, 68, 149, 58, 120, 136, 214, 192, 16, 63, 63, 146, 53, 105, 18, 57, 127, 234, 148, 40, 63, 173, + 250, 104, 255, 254, 253, 161, 128, 248, 78, 112, 39, 224, 141, 107, 64, 59, 110, 15, 144, 252, 93, 224, + 255, 28, 48, 125, 6, 156, 12, 158, 194, 213, 193, 120, 90, 7, 241, 224, 56, 204, 132, 96, 214, 43, 224, + 158, 16, 19, 24, 72, 254, 176, 96, 1, 169, 186, 114, 69, 148, 163, 168, 182, 20, 20, 20, 116, 5, 196, 232, + 46, 192, 27, 215, 128, 91, 184, 61, 64, 242, 119, 129, 255, 44, 96, 249, 60, 120, 6, 120, 58, 173, 131, + 167, 192, 79, 130, 127, 75, 235, 96, 28, 173, 3, 150, 17, 99, 185, 94, 33, 62, 36, 132, 108, 121, 245, 85, + 82, 95, 91, 43, 202, 211, 85, 109, 88, 190, 124, 57, 14, 131, 186, 3, 235, 59, 193, 29, 193, 129, 220, 30, + 32, 249, 187, 192, 255, 69, 220, 215, 193, 174, 214, 1, 91, 15, 162, 232, 122, 240, 68, 143, 30, 228, 111, + 5, 5, 158, 152, 39, 175, 76, 79, 79, 191, 15, 16, 247, 0, 214, 161, 224, 78, 146, 191, 56, 255, 5, 192, + 110, 62, 120, 30, 173, 131, 217, 14, 234, 96, 34, 173, 131, 71, 105, 29, 60, 172, 88, 15, 6, 211, 25, 210, + 140, 65, 131, 200, 223, 247, 236, 17, 101, 235, 140, 210, 38, 78, 156, 136, 23, 71, 122, 2, 235, 48, 240, + 207, 104, 6, 144, 252, 5, 248, 167, 0, 179, 133, 180, 6, 126, 71, 235, 96, 14, 93, 15, 102, 130, 159, 5, + 63, 13, 158, 10, 158, 76, 235, 96, 2, 173, 131, 4, 174, 103, 28, 69, 123, 133, 1, 180, 95, 88, 148, 144, + 64, 78, 159, 56, 33, 202, 184, 37, 205, 142, 142, 142, 238, 13, 136, 239, 3, 214, 119, 113, 252, 141, 146, + 191, 235, 252, 23, 33, 43, 90, 3, 106, 117, 240, 2, 87, 7, 172, 87, 96, 61, 227, 99, 14, 122, 70, 214, 43, + 12, 11, 8, 32, 43, 159, 125, 150, 92, 189, 116, 73, 148, 181, 82, 150, 166, 166, 166, 169, 125, 65, 128, + 56, 2, 88, 119, 5, 223, 46, 249, 139, 243, 95, 12, 156, 22, 211, 26, 64, 227, 122, 192, 246, 132, 23, 105, + 29, 204, 166, 117, 192, 122, 5, 101, 207, 232, 168, 87, 192, 140, 216, 19, 92, 180, 97, 131, 40, 111, 165, + 106, 190, 255, 254, 251, 241, 33, 33, 33, 253, 57, 254, 114, 253, 215, 192, 63, 21, 248, 164, 210, 26, 224, + 107, 193, 209, 190, 208, 90, 29, 240, 217, 96, 36, 205, 5, 95, 236, 216, 33, 202, 91, 169, 11, 231, 206, + 157, 27, 27, 24, 24, 216, 95, 101, 253, 151, 252, 53, 240, 231, 173, 86, 7, 11, 184, 58, 80, 91, 15, 112, + 118, 192, 122, 133, 71, 233, 158, 192, 106, 224, 235, 67, 135, 68, 121, 43, 245, 213, 177, 99, 199, 98, + 125, 125, 125, 251, 115, 249, 143, 229, 127, 127, 57, 255, 209, 135, 191, 163, 58, 224, 247, 5, 181, 94, + 129, 101, 68, 182, 22, 224, 126, 144, 208, 174, 29, 185, 116, 246, 172, 32, 238, 102, 218, 95, 84, 84, 4, + 45, 167, 161, 31, 112, 230, 251, 191, 246, 146, 191, 254, 252, 157, 173, 3, 54, 59, 192, 140, 200, 250, 69, + 204, 135, 216, 31, 36, 133, 134, 18, 83, 85, 149, 40, 111, 165, 62, 120, 251, 237, 183, 241, 66, 88, 31, + 224, 252, 75, 240, 207, 233, 252, 71, 242, 119, 35, 127, 103, 246, 132, 57, 220, 90, 48, 141, 174, 3, 152, + 9, 95, 236, 221, 155, 64, 102, 23, 229, 173, 212, 166, 204, 204, 76, 104, 47, 13, 15, 2, 231, 112, 58, 255, + 187, 141, 206, 127, 229, 252, 95, 128, 127, 26, 48, 114, 197, 124, 61, 40, 215, 131, 185, 52, 23, 176, 117, + 0, 247, 128, 236, 209, 163, 69, 89, 171, 105, 69, 114, 114, 50, 238, 253, 189, 129, 243, 61, 224, 59, 232, + 252, 95, 158, 255, 8, 242, 95, 2, 140, 68, 156, 78, 205, 106, 98, 17, 173, 131, 121, 92, 13, 96, 14, 200, + 159, 62, 93, 148, 181, 154, 82, 198, 141, 27, 135, 31, 44, 254, 21, 112, 198, 249, 127, 8, 56, 88, 242, + 247, 60, 127, 190, 14, 88, 13, 164, 208, 253, 0, 247, 130, 231, 40, 255, 162, 165, 75, 5, 81, 55, 83, 3, + 232, 153, 136, 136, 8, 228, 31, 9, 156, 127, 1, 198, 243, 191, 91, 249, 217, 143, 228, 239, 89, 254, 204, + 105, 220, 26, 128, 251, 0, 206, 12, 177, 31, 252, 236, 143, 127, 20, 229, 173, 84, 181, 201, 100, 122, 252, + 238, 187, 239, 70, 254, 247, 3, 231, 187, 193, 157, 37, 255, 182, 201, 31, 179, 32, 246, 1, 255, 220, 187, + 87, 148, 183, 82, 231, 203, 203, 203, 113, 246, 51, 80, 101, 246, 27, 32, 249, 183, 45, 254, 248, 252, 79, + 247, 245, 37, 231, 75, 75, 69, 121, 43, 85, 122, 232, 208, 33, 124, 41, 108, 128, 98, 246, 23, 40, 249, + 183, 29, 254, 172, 15, 192, 252, 55, 251, 246, 219, 73, 205, 229, 203, 162, 188, 149, 218, 187, 99, 199, + 142, 161, 56, 251, 1, 223, 235, 104, 246, 35, 249, 123, 159, 63, 230, 63, 60, 51, 78, 187, 247, 94, 210, + 96, 181, 138, 242, 86, 170, 112, 229, 202, 149, 131, 0, 109, 95, 58, 251, 83, 157, 253, 72, 254, 158, 231, + 143, 61, 0, 203, 255, 140, 63, 246, 255, 121, 163, 70, 137, 178, 86, 211, 186, 148, 148, 148, 86, 103, 63, + 146, 191, 119, 249, 99, 255, 135, 231, 2, 120, 30, 180, 105, 234, 84, 65, 212, 170, 122, 41, 62, 62, 126, + 160, 202, 236, 71, 242, 215, 192, 63, 3, 56, 105, 53, 91, 255, 149, 252, 119, 46, 91, 38, 202, 90, 41, 188, + 84, 248, 66, 84, 84, 212, 64, 58, 251, 233, 230, 104, 246, 35, 249, 123, 159, 63, 158, 7, 97, 239, 119, + 240, 157, 119, 4, 113, 55, 147, 169, 166, 166, 102, 98, 88, 88, 24, 238, 255, 15, 180, 52, 251, 145, 252, + 61, 207, 159, 173, 255, 120, 38, 132, 103, 130, 56, 255, 197, 51, 160, 111, 62, 251, 76, 148, 183, 82, 23, + 206, 159, 63, 31, 31, 20, 20, 52, 80, 49, 251, 9, 146, 252, 219, 30, 127, 236, 253, 159, 51, 26, 201, 229, + 242, 114, 81, 222, 74, 157, 56, 120, 240, 96, 44, 96, 29, 200, 245, 254, 170, 179, 31, 201, 223, 59, 252, + 241, 60, 144, 157, 255, 96, 239, 191, 224, 174, 187, 72, 173, 126, 239, 143, 239, 45, 44, 44, 196, 222, + 191, 63, 240, 197, 222, 159, 221, 251, 102, 179, 31, 31, 201, 95, 140, 127, 38, 176, 210, 234, 12, 110, + 255, 127, 145, 242, 95, 222, 191, 191, 40, 107, 53, 189, 179, 98, 197, 138, 193, 92, 239, 31, 234, 168, + 247, 151, 252, 93, 227, 191, 20, 88, 105, 49, 242, 127, 137, 174, 1, 139, 104, 254, 195, 217, 207, 250, 9, + 19, 68, 89, 171, 105, 213, 244, 233, 211, 7, 57, 211, 251, 75, 254, 158, 231, 207, 63, 255, 184, 254, 227, + 61, 192, 247, 23, 45, 18, 101, 173, 166, 133, 113, 113, 113, 131, 90, 187, 247, 33, 249, 123, 151, 255, 66, + 202, 31, 103, 127, 159, 231, 231, 139, 178, 86, 202, 98, 179, 217, 158, 238, 209, 163, 199, 32, 103, 122, + 127, 201, 223, 53, 254, 89, 192, 74, 139, 151, 42, 158, 127, 60, 251, 193, 187, 192, 223, 124, 250, 169, + 40, 111, 165, 46, 87, 86, 86, 62, 218, 185, 115, 103, 190, 247, 87, 158, 251, 75, 254, 109, 128, 63, 62, + 255, 56, 251, 155, 117, 203, 45, 228, 210, 201, 147, 162, 188, 149, 250, 246, 232, 209, 163, 163, 1, 233, + 32, 218, 251, 119, 229, 122, 255, 102, 189, 159, 228, 239, 89, 254, 184, 254, 227, 252, 15, 251, 127, 236, + 255, 240, 222, 199, 226, 176, 48, 98, 54, 153, 68, 121, 43, 181, 111, 231, 206, 157, 209, 244, 220, 191, + 167, 79, 11, 231, 254, 146, 191, 247, 248, 99, 255, 143, 103, 127, 120, 255, 123, 69, 84, 148, 40, 107, 53, + 109, 205, 203, 203, 27, 194, 245, 254, 252, 59, 255, 205, 122, 63, 201, 223, 115, 252, 113, 237, 103, 189, + 31, 242, 255, 29, 221, 251, 55, 77, 154, 36, 202, 90, 77, 171, 159, 127, 254, 249, 86, 223, 249, 144, 252, + 197, 248, 47, 3, 94, 162, 86, 123, 254, 177, 247, 223, 165, 223, 185, 31, 42, 37, 54, 54, 118, 48, 237, + 253, 90, 237, 253, 37, 127, 215, 248, 103, 3, 47, 17, 171, 241, 103, 207, 255, 145, 191, 254, 85, 148, 181, + 82, 245, 102, 179, 57, 185, 103, 207, 158, 184, 254, 247, 242, 249, 225, 206, 191, 195, 222, 95, 242, 247, + 60, 127, 54, 251, 195, 222, 31, 207, 126, 206, 30, 57, 34, 202, 91, 169, 75, 21, 21, 21, 143, 4, 7, 7, 227, + 243, 207, 223, 249, 15, 118, 212, 251, 73, 254, 222, 225, 143, 189, 63, 222, 251, 154, 223, 177, 35, 169, + 254, 238, 59, 81, 222, 74, 149, 22, 23, 23, 143, 2, 156, 131, 13, 63, 156, 251, 54, 251, 222, 135, 228, + 239, 61, 254, 152, 255, 88, 239, 143, 189, 95, 118, 100, 164, 158, 223, 0, 251, 120, 235, 214, 173, 248, + 99, 113, 3, 129, 107, 171, 231, 190, 146, 191, 235, 252, 115, 128, 153, 136, 179, 85, 248, 227, 59, 95, + 111, 140, 27, 39, 202, 90, 77, 111, 165, 167, 167, 71, 185, 210, 251, 73, 254, 222, 227, 143, 223, 2, 217, + 190, 120, 177, 40, 107, 53, 229, 76, 158, 60, 121, 136, 162, 247, 187, 173, 165, 222, 79, 242, 119, 63, + 127, 182, 7, 176, 217, 47, 155, 253, 33, 255, 3, 155, 55, 139, 178, 86, 10, 63, 26, 48, 171, 111, 223, 190, + 67, 12, 63, 62, 247, 107, 177, 247, 147, 252, 61, 195, 127, 25, 199, 159, 245, 126, 152, 253, 203, 15, 30, + 20, 196, 221, 76, 85, 215, 174, 93, 123, 34, 44, 44, 12, 249, 183, 248, 190, 183, 228, 239, 29, 254, 124, + 239, 143, 231, 126, 11, 32, 251, 95, 211, 47, 251, 159, 46, 41, 41, 137, 3, 158, 200, 223, 169, 115, 63, + 201, 223, 243, 252, 89, 239, 143, 119, 190, 179, 239, 191, 159, 52, 216, 108, 162, 188, 149, 218, 183, 125, + 251, 246, 24, 122, 238, 231, 240, 91, 143, 146, 191, 119, 248, 179, 236, 199, 122, 127, 204, 254, 235, 19, + 19, 69, 89, 171, 233, 221, 220, 220, 92, 188, 243, 57, 0, 152, 242, 223, 250, 101, 217, 95, 242, 247, 2, + 255, 108, 131, 227, 236, 191, 35, 61, 93, 148, 181, 154, 114, 39, 77, 154, 164, 252, 214, 91, 139, 231, 62, + 146, 191, 103, 248, 179, 217, 143, 50, 251, 31, 46, 40, 16, 101, 173, 20, 14, 144, 230, 68, 129, 104, 239, + 231, 212, 185, 143, 228, 239, 58, 255, 229, 192, 205, 21, 243, 235, 63, 227, 207, 222, 249, 250, 247, 209, + 163, 130, 184, 155, 169, 186, 170, 170, 106, 98, 72, 72, 72, 148, 43, 231, 62, 146, 191, 235, 252, 95, 1, + 110, 174, 248, 101, 90, 7, 217, 52, 255, 165, 81, 254, 169, 93, 186, 144, 235, 250, 253, 22, 204, 201, 210, + 210, 210, 177, 254, 254, 254, 81, 174, 156, 251, 72, 254, 158, 227, 191, 140, 238, 255, 248, 252, 227, 185, + 79, 222, 128, 1, 162, 172, 213, 180, 111, 219, 182, 109, 152, 253, 7, 3, 79, 118, 231, 207, 169, 236, 47, + 249, 187, 159, 127, 14, 229, 207, 102, 63, 120, 238, 243, 231, 228, 100, 81, 214, 106, 250, 83, 102, 102, + 230, 48, 238, 220, 71, 249, 190, 151, 228, 239, 101, 254, 108, 255, 199, 222, 31, 123, 191, 61, 171, 86, + 137, 178, 86, 83, 206, 147, 79, 62, 57, 84, 36, 251, 75, 254, 238, 227, 255, 50, 53, 155, 253, 227, 236, + 15, 123, 127, 124, 223, 251, 235, 143, 63, 22, 101, 173, 148, 173, 169, 169, 105, 102, 100, 100, 228, 80, + 7, 217, 95, 242, 247, 34, 255, 229, 28, 127, 156, 253, 224, 157, 191, 249, 65, 65, 228, 63, 103, 206, 252, + 143, 30, 126, 235, 89, 139, 9, 185, 92, 113, 241, 226, 99, 157, 58, 117, 26, 202, 101, 255, 22, 223, 247, + 146, 252, 61, 203, 159, 205, 126, 49, 251, 227, 157, 175, 236, 158, 61, 137, 205, 108, 166, 248, 155, 52, + 25, 116, 162, 184, 184, 120, 12, 32, 20, 202, 254, 146, 191, 251, 249, 179, 217, 95, 42, 93, 251, 243, 233, + 220, 183, 73, 31, 254, 187, 222, 124, 243, 205, 104, 154, 253, 29, 205, 253, 37, 127, 47, 241, 231, 179, + 31, 102, 127, 60, 243, 221, 69, 191, 241, 220, 212, 216, 168, 217, 160, 117, 115, 230, 204, 25, 198, 205, + 253, 91, 125, 223, 71, 242, 23, 231, 191, 2, 248, 57, 227, 92, 174, 6, 88, 239, 191, 152, 62, 255, 199, + 182, 109, 179, 243, 199, 123, 127, 90, 76, 159, 255, 148, 17, 35, 70, 40, 179, 191, 234, 119, 62, 37, 127, + 207, 242, 207, 229, 246, 255, 12, 154, 253, 231, 7, 4, 144, 75, 223, 124, 163, 11, 127, 144, 169, 186, 186, + 250, 169, 176, 176, 48, 124, 254, 157, 250, 214, 131, 228, 239, 57, 254, 175, 112, 251, 63, 246, 126, 56, + 247, 93, 22, 30, 78, 204, 244, 183, 159, 117, 224, 127, 170, 164, 164, 36, 222, 223, 223, 159, 207, 254, + 78, 207, 253, 37, 127, 247, 243, 207, 225, 122, 63, 156, 251, 174, 143, 143, 255, 63, 251, 134, 134, 6, 77, + 6, 125, 82, 88, 88, 136, 223, 248, 30, 2, 28, 93, 186, 243, 35, 249, 187, 159, 255, 203, 28, 255, 52, 186, + 247, 239, 90, 178, 196, 206, 95, 43, 123, 202, 255, 173, 212, 212, 84, 188, 239, 63, 200, 199, 133, 251, + 254, 146, 191, 56, 255, 60, 96, 216, 154, 87, 82, 231, 42, 248, 227, 183, 30, 142, 191, 255, 190, 46, 252, + 233, 250, 159, 17, 31, 31, 63, 204, 193, 125, 255, 102, 223, 121, 147, 252, 61, 199, 127, 5, 183, 254, 103, + 210, 236, 191, 208, 104, 36, 21, 101, 101, 118, 254, 54, 155, 77, 147, 33, 251, 223, 48, 153, 76, 211, 194, + 195, 195, 135, 187, 122, 223, 95, 242, 247, 28, 255, 108, 218, 251, 225, 157, 159, 229, 61, 122, 144, 122, + 200, 126, 141, 208, 183, 105, 229, 15, 58, 87, 86, 86, 54, 46, 32, 32, 96, 152, 193, 201, 239, 124, 73, + 254, 158, 229, 207, 122, 127, 236, 253, 112, 238, 187, 145, 190, 235, 101, 131, 245, 91, 7, 254, 95, 20, + 21, 21, 141, 116, 48, 247, 109, 231, 108, 246, 147, 252, 93, 227, 191, 10, 56, 182, 100, 86, 3, 74, 254, + 152, 253, 119, 103, 103, 219, 249, 91, 173, 86, 205, 6, 109, 206, 200, 200, 208, 52, 247, 149, 252, 221, + 195, 159, 61, 255, 172, 247, 199, 222, 15, 223, 247, 40, 221, 181, 75, 23, 254, 244, 249, 127, 41, 46, 46, + 110, 184, 65, 253, 27, 191, 45, 222, 247, 150, 252, 221, 203, 63, 207, 240, 195, 236, 111, 41, 205, 126, + 105, 193, 193, 228, 202, 153, 51, 246, 51, 31, 173, 252, 33, 251, 215, 93, 175, 169, 153, 214, 189, 123, + 119, 124, 254, 251, 250, 56, 249, 157, 31, 201, 223, 51, 252, 249, 222, 47, 147, 102, 191, 188, 94, 189, + 136, 213, 98, 177, 63, 187, 248, 167, 22, 131, 254, 85, 90, 82, 146, 96, 52, 26, 135, 171, 100, 63, 167, + 231, 190, 146, 191, 251, 248, 243, 217, 31, 179, 223, 187, 73, 73, 248, 159, 19, 11, 240, 211, 106, 208, + 39, 91, 182, 108, 193, 236, 55, 20, 248, 97, 246, 235, 166, 200, 126, 146, 191, 155, 248, 191, 10, 44, 29, + 153, 213, 0, 207, 159, 101, 191, 207, 223, 120, 67, 79, 254, 27, 231, 207, 159, 207, 103, 63, 167, 190, + 243, 34, 249, 123, 142, 63, 203, 254, 75, 232, 250, 143, 239, 121, 227, 222, 111, 49, 155, 53, 153, 174, + 255, 169, 49, 49, 49, 209, 14, 222, 245, 115, 122, 238, 43, 249, 235, 207, 159, 245, 126, 44, 251, 227, + 125, 223, 172, 208, 80, 82, 125, 229, 10, 177, 66, 223, 111, 6, 134, 90, 220, 208, 208, 0, 255, 171, 43, + 120, 230, 171, 75, 246, 147, 252, 245, 231, 207, 103, 127, 188, 239, 249, 230, 168, 81, 4, 79, 107, 112, + 237, 214, 202, 31, 84, 86, 92, 92, 28, 15, 200, 116, 201, 126, 146, 191, 62, 252, 87, 41, 248, 231, 208, + 236, 135, 125, 255, 46, 250, 158, 175, 185, 190, 94, 179, 65, 31, 190, 254, 250, 235, 120, 230, 27, 69, + 179, 159, 114, 238, 39, 249, 187, 145, 255, 106, 224, 169, 102, 86, 7, 140, 63, 203, 254, 120, 231, 227, + 248, 142, 29, 246, 189, 191, 30, 248, 105, 53, 104, 205, 212, 169, 83, 31, 162, 103, 190, 142, 126, 215, + 93, 242, 119, 19, 255, 53, 192, 83, 205, 172, 14, 120, 254, 56, 247, 91, 18, 28, 76, 42, 203, 203, 137, + 173, 177, 81, 51, 123, 216, 63, 26, 224, 207, 217, 125, 250, 244, 121, 136, 206, 253, 52, 103, 63, 201, 95, + 63, 254, 236, 249, 127, 133, 102, 127, 204, 126, 107, 250, 245, 35, 102, 220, 247, 193, 90, 249, 55, 54, + 54, 86, 156, 62, 125, 122, 66, 112, 112, 112, 180, 161, 249, 247, 189, 157, 122, 215, 71, 242, 119, 47, + 127, 214, 251, 101, 209, 236, 87, 56, 99, 134, 125, 237, 175, 171, 171, 211, 108, 208, 193, 237, 219, 183, + 227, 187, 30, 195, 129, 155, 242, 93, 31, 161, 236, 39, 249, 187, 198, 127, 45, 48, 85, 154, 213, 0, 227, + 207, 178, 63, 238, 253, 95, 110, 222, 108, 255, 56, 135, 78, 252, 255, 148, 150, 150, 22, 67, 179, 159, + 163, 223, 245, 149, 252, 189, 200, 159, 245, 254, 246, 223, 248, 9, 8, 32, 231, 75, 74, 136, 181, 169, 73, + 51, 123, 92, 255, 155, 154, 154, 50, 198, 140, 30, 141, 123, 191, 75, 223, 247, 149, 252, 221, 207, 127, + 53, 237, 255, 88, 246, 195, 119, 189, 242, 34, 34, 200, 141, 235, 215, 241, 163, 252, 164, 174, 182, 86, + 147, 173, 22, 75, 245, 165, 239, 190, 75, 10, 13, 13, 125, 72, 203, 187, 30, 146, 191, 251, 248, 243, 217, + 15, 103, 190, 239, 62, 245, 148, 125, 238, 83, 11, 252, 180, 26, 84, 186, 111, 223, 62, 156, 251, 68, 59, + 120, 215, 67, 242, 247, 2, 127, 229, 222, 207, 103, 191, 253, 235, 215, 219, 247, 126, 157, 248, 23, 229, + 229, 229, 197, 210, 51, 63, 167, 126, 215, 81, 242, 215, 159, 255, 239, 129, 43, 111, 86, 7, 60, 127, 60, + 243, 79, 245, 245, 37, 103, 14, 31, 38, 86, 232, 251, 107, 111, 220, 208, 108, 208, 43, 227, 199, 143, 143, + 49, 252, 240, 141, 31, 60, 243, 115, 249, 93, 15, 201, 95, 27, 255, 215, 128, 45, 111, 86, 7, 171, 57, 254, + 120, 230, 183, 50, 60, 28, 63, 202, 70, 234, 32, 183, 221, 0, 126, 90, 12, 217, 175, 190, 170, 170, 106, + 70, 120, 120, 120, 140, 94, 103, 126, 146, 191, 126, 252, 217, 243, 143, 217, 63, 135, 206, 125, 254, 242, + 248, 227, 4, 111, 105, 106, 101, 143, 110, 108, 108, 44, 63, 124, 248, 112, 162, 159, 159, 95, 140, 202, + 220, 135, 101, 63, 201, 223, 75, 252, 215, 40, 178, 63, 126, 223, 245, 243, 117, 235, 8, 222, 210, 188, 97, + 50, 105, 54, 104, 119, 254, 134, 13, 163, 20, 115, 31, 151, 223, 243, 148, 252, 245, 229, 207, 175, 253, + 44, 251, 219, 223, 245, 132, 189, 31, 30, 88, 98, 110, 104, 32, 38, 224, 167, 213, 160, 213, 83, 166, 76, + 97, 103, 126, 194, 239, 121, 74, 254, 250, 243, 95, 203, 241, 103, 123, 255, 170, 251, 238, 35, 53, 215, + 174, 145, 27, 117, 117, 154, 217, 67, 246, 183, 212, 212, 212, 204, 138, 136, 136, 24, 161, 152, 251, 224, + 222, 175, 105, 238, 35, 249, 187, 206, 127, 29, 240, 101, 126, 205, 240, 227, 236, 135, 115, 63, 188, 235, + 93, 0, 125, 63, 222, 210, 50, 93, 191, 174, 217, 54, 171, 245, 236, 241, 99, 199, 198, 27, 141, 198, 24, + 189, 231, 62, 146, 191, 56, 127, 126, 13, 224, 179, 31, 126, 227, 227, 64, 126, 190, 157, 255, 117, 224, + 167, 213, 160, 61, 155, 54, 109, 194, 223, 115, 143, 6, 86, 106, 191, 235, 35, 249, 123, 145, 255, 90, 46, + 251, 225, 220, 39, 195, 104, 36, 103, 143, 29, 35, 117, 86, 171, 94, 252, 95, 155, 54, 109, 154, 174, 247, + 125, 36, 127, 97, 255, 23, 82, 102, 74, 15, 63, 177, 45, 47, 0, 0, 37, 139, 109, 107, 66, 84, 250, 206, + 202, 254, 0, 127, 158, 188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 120, 156, 237, 93, 7, 124, 85, 85, 242, 190, 18, 9, 216, 16, 118, 93, 11, 174, 29, 5, 93, + 87, 215, 130, 238, 186, 42, 248, 87, 88, 68, 1, 41, 22, 16, 150, 162, 34, 69, 16, 68, 80, 68, 65, 80, 144, + 26, 90, 168, 9, 16, 233, 29, 18, 90, 144, 38, 130, 133, 34, 132, 150, 94, 94, 66, 239, 213, 182, 234, 206, + 127, 190, 243, 206, 36, 39, 151, 247, 146, 151, 228, 222, 36, 143, 197, 223, 239, 251, 97, 32, 185, 119, + 238, 124, 103, 102, 190, 153, 115, 238, 11, 157, 57, 115, 134, 74, 29, 206, 158, 165, 159, 126, 251, 141, + 38, 213, 175, 79, 61, 44, 139, 62, 97, 12, 98, 12, 101, 12, 103, 140, 100, 140, 186, 8, 71, 112, 250, 244, + 233, 82, 137, 159, 137, 104, 237, 240, 225, 212, 157, 109, 252, 84, 243, 31, 166, 185, 31, 205, 8, 191, 8, + 71, 80, 210, 60, 251, 195, 15, 191, 252, 66, 233, 219, 182, 209, 71, 161, 161, 212, 151, 237, 28, 200, 24, + 198, 24, 161, 249, 191, 184, 6, 28, 226, 255, 212, 169, 82, 137, 51, 188, 6, 206, 158, 59, 71, 99, 30, 125, + 148, 122, 177, 157, 159, 89, 222, 252, 15, 254, 71, 93, 228, 255, 130, 231, 31, 248, 249, 191, 255, 165, + 85, 253, 251, 211, 251, 108, 231, 0, 198, 16, 203, 91, 255, 47, 242, 239, 28, 78, 177, 159, 75, 43, 206, + 253, 244, 19, 121, 226, 226, 168, 239, 229, 151, 43, 13, 56, 216, 202, 173, 1, 46, 174, 1, 7, 248, 63, 121, + 178, 244, 130, 215, 0, 116, 192, 148, 186, 117, 233, 35, 43, 183, 6, 20, 251, 199, 92, 68, 145, 80, 226, + 28, 231, 131, 31, 127, 253, 149, 182, 206, 156, 73, 31, 90, 94, 13, 96, 106, 192, 139, 252, 23, 29, 39, + 217, 199, 165, 25, 167, 206, 156, 161, 227, 71, 143, 210, 200, 106, 213, 84, 31, 96, 106, 128, 139, 57, + 224, 194, 231, 31, 248, 145, 117, 224, 218, 129, 3, 85, 14, 144, 26, 112, 145, 127, 135, 248, 63, 113, 162, + 212, 227, 244, 217, 179, 116, 40, 35, 131, 134, 84, 174, 172, 102, 65, 210, 7, 154, 250, 175, 164, 253, 24, + 140, 128, 223, 78, 176, 127, 131, 1, 63, 252, 254, 59, 197, 246, 234, 69, 189, 173, 243, 107, 0, 158, 101, + 236, 69, 20, 24, 99, 130, 136, 127, 228, 128, 3, 105, 105, 52, 244, 250, 235, 213, 44, 192, 236, 3, 100, + 61, 151, 180, 63, 131, 13, 138, 255, 227, 199, 131, 6, 63, 252, 246, 27, 173, 238, 215, 143, 62, 182, 114, + 215, 128, 139, 252, 23, 142, 123, 224, 56, 251, 53, 88, 112, 242, 244, 105, 58, 114, 224, 0, 141, 190, 243, + 206, 139, 57, 224, 127, 144, 127, 224, 236, 175, 191, 210, 183, 19, 39, 82, 63, 203, 155, 3, 100, 22, 104, + 114, 63, 238, 34, 242, 133, 172, 129, 227, 199, 142, 5, 21, 160, 5, 48, 19, 136, 170, 89, 147, 250, 91, + 185, 107, 64, 48, 240, 175, 252, 30, 18, 66, 227, 202, 148, 41, 113, 59, 194, 131, 144, 127, 224, 204, 143, + 63, 82, 210, 151, 95, 210, 192, 208, 80, 213, 11, 72, 13, 48, 243, 91, 73, 243, 44, 62, 182, 3, 107, 117, + 73, 131, 6, 52, 241, 202, 43, 207, 171, 87, 197, 109, 23, 124, 118, 140, 253, 25, 140, 64, 29, 88, 209, + 173, 155, 154, 7, 72, 47, 88, 154, 114, 128, 47, 238, 177, 78, 191, 236, 222, 157, 190, 31, 55, 78, 217, + 235, 235, 123, 138, 203, 182, 49, 122, 45, 30, 59, 122, 52, 40, 113, 226, 228, 73, 165, 5, 199, 223, 123, + 175, 58, 27, 82, 90, 116, 128, 63, 173, 133, 58, 181, 188, 89, 51, 58, 71, 68, 177, 45, 91, 170, 175, 125, + 233, 213, 226, 178, 15, 247, 30, 21, 196, 252, 3, 167, 127, 250, 137, 118, 47, 93, 74, 131, 184, 158, 14, + 179, 114, 230, 65, 166, 31, 199, 23, 35, 252, 249, 25, 249, 41, 250, 133, 23, 232, 36, 235, 150, 147, 63, + 252, 64, 115, 254, 241, 143, 243, 248, 55, 127, 182, 56, 108, 20, 254, 143, 178, 31, 129, 236, 220, 202, + 26, 91, 65, 127, 45, 255, 94, 90, 113, 250, 63, 255, 161, 149, 239, 190, 171, 250, 65, 83, 7, 148, 6, 254, + 225, 99, 172, 203, 133, 117, 234, 40, 91, 79, 156, 61, 75, 135, 15, 30, 164, 41, 183, 223, 174, 248, 55, + 103, 151, 197, 205, 127, 184, 246, 215, 185, 159, 127, 166, 31, 24, 103, 89, 83, 157, 60, 117, 74, 245, 88, + 224, 29, 255, 143, 191, 195, 254, 251, 57, 254, 19, 127, 127, 244, 200, 145, 82, 135, 227, 220, 15, 224, + 207, 40, 142, 169, 65, 86, 201, 229, 0, 59, 239, 225, 154, 251, 57, 53, 106, 168, 58, 117, 226, 244, 105, + 101, 235, 254, 228, 100, 26, 127, 221, 117, 62, 231, 215, 197, 197, 191, 232, 80, 172, 193, 5, 35, 70, 208, + 232, 142, 29, 233, 99, 206, 79, 239, 114, 79, 213, 169, 122, 117, 234, 248, 224, 131, 212, 237, 201, 39, + 169, 15, 235, 212, 177, 93, 187, 82, 52, 235, 149, 140, 196, 196, 82, 187, 6, 78, 158, 59, 71, 233, 155, + 55, 211, 136, 63, 252, 65, 249, 92, 116, 64, 113, 199, 148, 248, 22, 156, 98, 54, 53, 237, 161, 135, 232, + 160, 199, 163, 226, 94, 173, 85, 214, 44, 89, 187, 119, 83, 120, 165, 74, 217, 231, 24, 138, 115, 189, 154, + 54, 142, 210, 54, 254, 159, 198, 211, 140, 90, 140, 218, 250, 207, 103, 24, 53, 25, 213, 25, 237, 31, 120, + 128, 18, 227, 226, 188, 154, 139, 159, 163, 52, 226, 20, 231, 169, 205, 147, 38, 169, 28, 48, 188, 24, 215, + 128, 47, 238, 193, 235, 240, 75, 47, 165, 148, 13, 27, 232, 36, 107, 20, 177, 241, 24, 251, 47, 115, 207, + 30, 26, 201, 235, 84, 206, 178, 217, 231, 23, 197, 193, 191, 228, 126, 172, 193, 134, 26, 141, 12, 224, + 235, 122, 140, 127, 225, 251, 222, 124, 83, 213, 46, 53, 123, 45, 5, 60, 251, 5, 219, 120, 138, 125, 189, + 162, 83, 39, 213, 15, 152, 252, 155, 62, 152, 224, 48, 76, 223, 74, 79, 133, 153, 196, 156, 218, 181, 85, + 220, 195, 174, 92, 252, 115, 252, 135, 49, 255, 246, 243, 236, 166, 173, 78, 219, 104, 218, 42, 118, 130, + 127, 204, 79, 95, 97, 52, 53, 128, 175, 27, 51, 154, 240, 250, 93, 56, 116, 40, 157, 101, 159, 34, 239, 31, + 57, 124, 184, 212, 227, 40, 234, 19, 107, 151, 57, 181, 106, 169, 103, 27, 171, 159, 121, 162, 129, 8, 135, + 33, 215, 29, 111, 229, 212, 85, 220, 59, 110, 246, 108, 165, 245, 77, 251, 142, 113, 253, 207, 226, 58, 58, + 252, 79, 127, 82, 103, 217, 204, 253, 139, 113, 154, 35, 55, 108, 52, 237, 156, 96, 229, 228, 127, 216, + 217, 146, 209, 202, 0, 214, 64, 171, 43, 174, 160, 117, 211, 167, 211, 89, 206, 169, 88, 183, 135, 217, + 246, 96, 193, 49, 214, 173, 251, 82, 82, 40, 178, 106, 85, 229, 95, 89, 3, 19, 44, 231, 215, 128, 233, 83, + 201, 171, 136, 253, 168, 71, 30, 161, 35, 188, 14, 17, 251, 166, 109, 248, 187, 3, 89, 89, 52, 226, 214, + 91, 213, 121, 102, 124, 175, 244, 1, 197, 197, 63, 124, 33, 243, 8, 228, 160, 118, 6, 218, 48, 58, 92, 125, + 53, 109, 138, 142, 166, 51, 220, 19, 148, 52, 151, 133, 197, 9, 142, 187, 228, 141, 27, 41, 156, 243, 236, + 8, 203, 157, 60, 96, 94, 75, 124, 138, 88, 134, 254, 216, 50, 117, 170, 178, 193, 110, 151, 170, 5, 140, + 240, 123, 239, 85, 123, 216, 208, 0, 162, 85, 198, 22, 3, 255, 178, 78, 113, 63, 196, 6, 246, 208, 186, + 106, 188, 197, 232, 86, 161, 2, 109, 141, 137, 81, 115, 149, 195, 135, 14, 5, 53, 78, 114, 207, 186, 99, + 238, 92, 26, 25, 26, 170, 114, 157, 25, 95, 78, 242, 47, 249, 116, 180, 230, 115, 42, 247, 77, 200, 243, + 42, 111, 218, 108, 82, 53, 128, 53, 64, 228, 51, 207, 228, 58, 207, 94, 156, 252, 75, 238, 135, 246, 192, + 26, 236, 201, 232, 193, 120, 255, 178, 203, 104, 203, 130, 5, 74, 67, 29, 98, 91, 47, 4, 156, 224, 28, 182, + 105, 204, 24, 21, 99, 225, 86, 78, 14, 48, 253, 18, 89, 8, 152, 63, 47, 117, 31, 177, 63, 164, 76, 25, 218, + 185, 116, 41, 29, 199, 121, 69, 127, 54, 241, 186, 156, 221, 178, 165, 122, 167, 109, 160, 193, 255, 56, + 195, 182, 194, 216, 20, 136, 189, 19, 12, 91, 177, 246, 134, 252, 241, 143, 234, 60, 221, 135, 108, 247, + 55, 147, 39, 171, 94, 165, 164, 57, 115, 20, 168, 5, 236, 239, 245, 125, 251, 42, 63, 143, 241, 19, 99, 69, + 241, 167, 228, 83, 112, 185, 152, 121, 61, 126, 238, 92, 158, 54, 33, 47, 173, 96, 123, 16, 119, 162, 1, + 139, 139, 255, 241, 86, 78, 127, 10, 253, 49, 189, 65, 3, 234, 195, 127, 174, 25, 48, 192, 203, 253, 193, + 131, 23, 28, 80, 119, 193, 201, 170, 174, 93, 179, 245, 160, 125, 13, 20, 198, 151, 102, 221, 71, 46, 13, + 191, 241, 70, 202, 140, 143, 87, 61, 72, 94, 246, 156, 56, 115, 134, 190, 99, 109, 253, 129, 229, 125, 167, + 17, 26, 92, 234, 147, 27, 252, 155, 246, 218, 107, 255, 198, 113, 227, 40, 186, 93, 59, 229, 31, 248, 169, + 164, 185, 114, 109, 13, 160, 247, 102, 191, 199, 182, 111, 239, 119, 13, 4, 226, 119, 243, 123, 37, 246, + 193, 29, 234, 254, 230, 41, 83, 232, 56, 107, 190, 252, 108, 57, 202, 218, 32, 241, 187, 239, 232, 227, + 114, 229, 178, 207, 178, 203, 94, 176, 155, 252, 155, 185, 31, 246, 14, 97, 109, 156, 177, 123, 55, 29, 70, + 143, 194, 56, 200, 182, 93, 200, 56, 4, 237, 205, 218, 107, 105, 171, 86, 74, 15, 200, 26, 40, 12, 255, + 102, 236, 195, 151, 203, 56, 134, 142, 113, 12, 29, 228, 252, 158, 175, 29, 188, 22, 247, 113, 15, 56, 180, + 74, 21, 245, 62, 83, 113, 241, 111, 246, 125, 88, 119, 211, 235, 215, 87, 49, 113, 132, 215, 227, 193, 3, + 7, 254, 39, 128, 60, 128, 231, 93, 166, 247, 223, 199, 27, 254, 158, 100, 96, 178, 13, 230, 191, 69, 26, + 185, 20, 185, 100, 102, 205, 154, 138, 87, 92, 59, 80, 59, 142, 157, 62, 77, 81, 245, 234, 169, 218, 43, + 251, 214, 227, 180, 45, 190, 238, 95, 88, 152, 54, 79, 176, 114, 246, 162, 81, 251, 55, 142, 31, 175, 116, + 170, 83, 190, 197, 220, 13, 251, 27, 37, 205, 113, 160, 107, 96, 57, 231, 129, 145, 126, 214, 64, 94, 252, + 75, 46, 197, 250, 249, 252, 190, 251, 40, 43, 41, 169, 192, 49, 132, 122, 187, 178, 95, 63, 165, 189, 205, + 250, 31, 145, 135, 13, 69, 225, 95, 226, 95, 102, 211, 195, 88, 247, 75, 238, 63, 192, 246, 20, 5, 152, + 105, 157, 226, 186, 183, 251, 251, 239, 41, 118, 218, 52, 21, 11, 7, 128, 34, 94, 215, 77, 28, 196, 26, + 224, 24, 252, 226, 173, 183, 212, 26, 16, 223, 219, 243, 128, 29, 38, 247, 83, 153, 123, 207, 158, 61, 170, + 166, 20, 216, 103, 252, 51, 113, 203, 151, 171, 252, 143, 250, 1, 27, 36, 255, 59, 205, 191, 228, 43, 169, + 253, 208, 156, 179, 26, 54, 164, 163, 252, 252, 69, 226, 29, 251, 45, 188, 142, 19, 226, 226, 40, 188, 83, + 39, 122, 158, 245, 76, 79, 238, 39, 78, 156, 58, 85, 234, 249, 87, 107, 0, 243, 56, 230, 225, 171, 62, 125, + 104, 76, 217, 178, 170, 47, 154, 232, 103, 13, 72, 29, 29, 167, 125, 184, 160, 78, 29, 202, 74, 73, 81, + 113, 95, 152, 123, 163, 47, 205, 74, 75, 163, 176, 155, 110, 82, 124, 200, 89, 160, 9, 198, 253, 221, 200, + 253, 82, 251, 191, 137, 140, 164, 163, 92, 251, 149, 61, 251, 247, 23, 8, 176, 253, 36, 215, 141, 20, 206, + 31, 19, 186, 117, 163, 23, 43, 86, 164, 167, 248, 154, 79, 98, 141, 189, 253, 54, 157, 194, 123, 90, 5, + 188, 102, 73, 1, 185, 234, 40, 219, 139, 51, 100, 179, 31, 122, 40, 123, 15, 86, 214, 129, 196, 142, 244, + 205, 145, 156, 55, 55, 114, 175, 124, 136, 115, 30, 244, 100, 81, 238, 141, 248, 155, 209, 168, 145, 234, + 195, 132, 127, 137, 127, 240, 55, 165, 136, 144, 117, 32, 252, 195, 126, 245, 206, 212, 245, 215, 83, 70, + 66, 130, 226, 17, 118, 236, 15, 16, 208, 182, 56, 103, 145, 145, 154, 74, 83, 122, 245, 162, 102, 215, 92, + 163, 206, 8, 60, 199, 168, 111, 121, 247, 138, 99, 160, 41, 248, 185, 2, 189, 102, 105, 193, 97, 157, 179, + 190, 159, 60, 153, 162, 159, 125, 150, 162, 216, 71, 17, 161, 161, 52, 49, 36, 132, 38, 85, 168, 64, 115, + 30, 124, 144, 214, 243, 51, 103, 236, 220, 73, 71, 176, 190, 249, 123, 139, 122, 79, 196, 223, 250, 240, + 112, 85, 3, 194, 52, 63, 18, 255, 194, 93, 81, 249, 151, 154, 37, 125, 42, 114, 205, 220, 166, 77, 233, 8, + 223, 59, 80, 59, 145, 35, 48, 179, 216, 191, 111, 31, 205, 25, 60, 152, 90, 255, 249, 207, 138, 107, 112, + 110, 158, 23, 104, 194, 57, 116, 219, 87, 95, 41, 61, 80, 210, 124, 22, 6, 224, 244, 8, 175, 131, 195, 216, + 163, 77, 78, 166, 164, 13, 27, 40, 97, 205, 26, 74, 223, 177, 131, 14, 96, 118, 207, 62, 128, 110, 112, + 234, 126, 200, 31, 201, 172, 153, 6, 93, 117, 149, 210, 100, 163, 173, 28, 45, 90, 84, 254, 205, 26, 32, + 181, 127, 132, 230, 127, 243, 204, 153, 234, 57, 179, 109, 97, 94, 253, 1, 179, 10, 240, 25, 251, 249, 231, + 244, 214, 95, 254, 66, 207, 242, 207, 55, 96, 188, 200, 120, 217, 242, 158, 21, 144, 243, 2, 111, 221, 121, + 39, 101, 121, 60, 74, 223, 230, 117, 205, 194, 0, 154, 29, 179, 83, 167, 175, 235, 15, 88, 11, 7, 153, 31, + 228, 121, 232, 132, 3, 46, 60, 147, 90, 3, 124, 253, 41, 79, 63, 157, 125, 118, 213, 222, 3, 58, 145, 251, + 165, 118, 33, 247, 135, 223, 114, 11, 101, 113, 254, 86, 249, 75, 219, 177, 207, 7, 48, 163, 56, 142, 57, + 229, 23, 95, 208, 7, 79, 61, 165, 114, 124, 61, 205, 121, 51, 70, 115, 70, 11, 198, 191, 53, 176, 30, 134, + 115, 94, 81, 123, 239, 126, 174, 89, 80, 192, 63, 71, 240, 206, 31, 215, 19, 244, 22, 137, 187, 118, 41, + 187, 157, 186, 126, 105, 0, 122, 144, 181, 67, 135, 170, 126, 220, 151, 6, 40, 236, 26, 144, 159, 181, 231, + 254, 69, 111, 188, 161, 242, 152, 95, 159, 243, 58, 7, 239, 73, 236, 235, 17, 109, 218, 80, 35, 174, 129, + 207, 243, 207, 189, 196, 120, 85, 115, 221, 154, 241, 58, 227, 13, 70, 91, 253, 39, 214, 194, 242, 177, 99, + 233, 168, 3, 252, 195, 6, 172, 35, 244, 166, 223, 172, 88, 65, 131, 90, 180, 160, 122, 108, 199, 64, 254, + 243, 40, 235, 245, 146, 230, 204, 73, 160, 158, 36, 109, 221, 74, 67, 185, 6, 12, 179, 241, 47, 92, 70, 21, + 16, 230, 26, 48, 123, 22, 236, 79, 109, 139, 142, 166, 67, 156, 211, 115, 217, 177, 119, 175, 2, 246, 45, + 160, 241, 230, 113, 141, 111, 121, 237, 181, 84, 151, 191, 191, 137, 142, 119, 240, 222, 70, 243, 221, 158, + 209, 145, 209, 73, 163, 3, 227, 109, 214, 72, 9, 91, 182, 168, 92, 41, 215, 43, 40, 160, 69, 143, 235, 186, + 180, 34, 42, 138, 122, 60, 241, 4, 61, 199, 250, 11, 231, 82, 113, 14, 181, 47, 107, 101, 204, 152, 76, + 155, 131, 30, 252, 44, 135, 216, 239, 211, 235, 214, 85, 252, 200, 30, 117, 164, 3, 252, 75, 237, 199, 154, + 130, 190, 24, 207, 245, 27, 247, 132, 127, 115, 249, 157, 57, 71, 142, 253, 150, 99, 173, 251, 163, 143, + 170, 92, 15, 77, 215, 84, 199, 117, 107, 29, 227, 224, 185, 179, 229, 61, 43, 210, 141, 241, 174, 6, 206, + 141, 132, 213, 172, 169, 106, 198, 254, 66, 112, 3, 123, 16, 239, 123, 249, 255, 23, 177, 30, 238, 116, + 255, 253, 84, 199, 178, 178, 53, 102, 125, 93, 123, 54, 196, 196, 40, 45, 82, 226, 156, 57, 140, 195, 156, + 211, 190, 142, 136, 56, 79, 3, 152, 185, 191, 160, 252, 155, 181, 127, 180, 206, 253, 203, 187, 119, 87, + 245, 198, 126, 255, 140, 180, 52, 26, 219, 161, 3, 53, 102, 253, 14, 95, 67, 207, 161, 190, 183, 210, 121, + 190, 189, 230, 29, 156, 191, 199, 192, 190, 101, 47, 13, 252, 127, 23, 198, 210, 254, 253, 213, 181, 193, + 97, 192, 224, 181, 130, 124, 142, 124, 143, 247, 11, 58, 220, 125, 183, 210, 151, 178, 254, 154, 104, 160, + 254, 244, 98, 141, 132, 122, 128, 120, 41, 208, 61, 130, 0, 251, 89, 211, 100, 36, 37, 209, 232, 155, 110, + 82, 26, 173, 40, 53, 192, 204, 253, 166, 238, 31, 204, 220, 238, 94, 183, 142, 14, 176, 15, 237, 247, 239, + 88, 165, 74, 174, 26, 143, 243, 160, 175, 89, 222, 243, 128, 136, 237, 119, 44, 239, 249, 32, 240, 141, + 253, 10, 244, 171, 253, 244, 159, 56, 195, 244, 81, 249, 242, 180, 103, 227, 70, 58, 192, 185, 127, 111, + 86, 86, 64, 80, 123, 142, 28, 203, 171, 102, 204, 160, 46, 220, 91, 215, 213, 49, 14, 27, 164, 175, 48, + 207, 34, 175, 158, 62, 93, 105, 193, 64, 175, 31, 108, 192, 252, 33, 154, 99, 240, 51, 43, 167, 15, 148, + 57, 64, 97, 248, 199, 218, 145, 153, 15, 230, 203, 83, 184, 150, 238, 231, 60, 143, 120, 183, 223, 187, + 177, 149, 163, 237, 80, 227, 223, 212, 188, 119, 213, 188, 127, 104, 121, 207, 137, 97, 110, 8, 251, 6, + 106, 224, 255, 177, 127, 49, 158, 175, 173, 184, 247, 113, 109, 59, 48, 111, 67, 174, 223, 188, 122, 53, + 245, 174, 85, 75, 113, 110, 246, 21, 210, 83, 200, 153, 100, 172, 129, 15, 31, 121, 68, 229, 8, 21, 251, + 165, 128, 171, 128, 161, 227, 75, 234, 124, 182, 190, 213, 125, 183, 124, 141, 239, 65, 92, 238, 94, 179, + 134, 134, 114, 156, 142, 178, 114, 107, 0, 225, 246, 243, 0, 32, 107, 64, 102, 126, 114, 46, 105, 221, 144, + 33, 116, 136, 115, 173, 47, 59, 77, 109, 215, 81, 231, 243, 238, 58, 222, 133, 119, 243, 119, 111, 0, 208, + 170, 67, 244, 191, 175, 26, 56, 80, 93, 59, 139, 175, 229, 15, 120, 70, 228, 250, 228, 61, 123, 104, 84, + 219, 182, 212, 164, 92, 57, 149, 115, 94, 54, 114, 14, 108, 120, 93, 219, 241, 166, 6, 214, 192, 202, 241, + 227, 85, 141, 204, 235, 250, 37, 5, 197, 47, 102, 71, 56, 223, 139, 243, 222, 172, 173, 177, 190, 241, 39, + 190, 134, 38, 130, 190, 202, 202, 204, 164, 76, 143, 135, 60, 233, 233, 148, 154, 152, 72, 30, 174, 185, + 248, 58, 147, 255, 30, 113, 121, 0, 251, 81, 120, 47, 248, 249, 231, 149, 111, 77, 254, 133, 219, 169, 249, + 64, 190, 79, 248, 199, 53, 144, 251, 241, 174, 81, 242, 246, 237, 180, 143, 99, 207, 215, 51, 64, 219, 153, + 53, 190, 167, 142, 235, 79, 244, 218, 17, 222, 229, 51, 215, 229, 189, 65, 117, 134, 228, 234, 171, 41, + 145, 117, 63, 106, 24, 158, 209, 23, 208, 19, 0, 139, 89, 219, 181, 185, 241, 70, 149, 235, 95, 180, 241, + 14, 206, 59, 232, 188, 211, 89, 3, 54, 245, 251, 235, 95, 213, 53, 224, 103, 127, 215, 47, 78, 168, 158, + 13, 251, 70, 152, 139, 233, 189, 159, 148, 132, 4, 250, 126, 253, 122, 90, 51, 123, 54, 205, 27, 54, 140, + 34, 88, 103, 133, 181, 110, 77, 125, 235, 215, 167, 247, 158, 124, 146, 186, 60, 244, 16, 117, 188, 231, + 30, 234, 200, 250, 166, 227, 93, 119, 81, 59, 174, 243, 93, 239, 188, 147, 122, 242, 215, 125, 248, 239, 7, + 243, 191, 143, 229, 239, 155, 245, 242, 203, 244, 249, 99, 143, 41, 95, 139, 6, 44, 12, 255, 210, 247, 141, + 213, 49, 58, 167, 113, 99, 58, 200, 107, 209, 223, 51, 73, 174, 135, 182, 67, 174, 71, 93, 183, 127, 214, + 190, 188, 155, 100, 126, 110, 0, 242, 255, 12, 94, 175, 200, 93, 106, 45, 217, 174, 171, 98, 158, 99, 33, + 142, 181, 65, 239, 103, 158, 81, 241, 142, 57, 177, 189, 159, 84, 253, 163, 229, 213, 25, 232, 39, 122, + 232, 252, 131, 53, 16, 27, 22, 230, 157, 199, 150, 32, 231, 168, 61, 208, 30, 224, 27, 90, 121, 211, 170, + 85, 52, 127, 248, 112, 26, 214, 170, 21, 189, 251, 247, 191, 83, 171, 27, 110, 200, 206, 103, 208, 175, + 117, 244, 159, 88, 231, 208, 178, 248, 123, 232, 234, 6, 250, 249, 177, 246, 155, 106, 31, 188, 161, 215, + 252, 187, 218, 247, 240, 169, 236, 5, 75, 15, 32, 185, 63, 16, 238, 241, 189, 246, 218, 191, 137, 181, 211, + 129, 60, 248, 23, 109, 103, 231, 221, 60, 147, 110, 63, 247, 132, 127, 67, 77, 248, 58, 50, 146, 14, 176, + 111, 144, 199, 76, 32, 31, 34, 223, 204, 236, 215, 143, 94, 173, 80, 65, 61, 191, 60, 179, 189, 214, 224, + 217, 223, 215, 54, 64, 79, 34, 247, 32, 7, 13, 226, 24, 65, 158, 204, 226, 152, 179, 95, 223, 109, 32, 206, + 15, 227, 28, 39, 251, 109, 207, 182, 109, 180, 120, 204, 24, 26, 248, 210, 75, 212, 246, 182, 219, 168, 81, + 72, 136, 226, 86, 52, 235, 11, 150, 87, 163, 202, 76, 220, 212, 175, 77, 245, 122, 7, 144, 239, 160, 111, + 68, 95, 163, 190, 117, 50, 184, 255, 84, 251, 222, 172, 255, 81, 154, 223, 105, 140, 233, 121, 96, 154, + 134, 201, 63, 114, 244, 4, 246, 97, 70, 62, 62, 236, 99, 229, 254, 253, 74, 114, 22, 205, 215, 94, 180, + 156, 35, 81, 239, 212, 220, 124, 51, 165, 113, 45, 203, 226, 56, 87, 181, 140, 129, 245, 132, 120, 69, 204, + 127, 244, 248, 227, 106, 205, 191, 100, 157, 63, 71, 120, 91, 63, 119, 79, 205, 57, 214, 222, 39, 218, 142, + 79, 245, 90, 88, 249, 217, 103, 116, 144, 175, 37, 215, 46, 14, 168, 88, 231, 123, 162, 70, 199, 112, 79, + 218, 231, 217, 103, 233, 213, 138, 21, 85, 28, 63, 167, 185, 110, 162, 57, 22, 110, 193, 171, 57, 15, 55, + 223, 167, 107, 173, 209, 198, 202, 173, 111, 218, 107, 238, 223, 209, 107, 191, 143, 142, 61, 121, 119, + 189, 48, 252, 79, 213, 223, 143, 159, 27, 167, 215, 210, 178, 174, 93, 189, 241, 153, 199, 51, 155, 191, + 87, 71, 230, 79, 178, 7, 97, 234, 79, 115, 158, 136, 107, 199, 188, 249, 38, 29, 48, 248, 217, 175, 207, + 213, 44, 30, 58, 148, 94, 99, 93, 208, 216, 202, 61, 71, 104, 167, 159, 185, 155, 126, 102, 225, 29, 159, + 225, 6, 157, 49, 88, 3, 95, 143, 188, 227, 14, 202, 72, 78, 86, 53, 164, 88, 120, 199, 222, 31, 63, 203, + 142, 239, 190, 163, 113, 157, 59, 211, 107, 172, 83, 132, 243, 198, 6, 223, 18, 195, 255, 54, 248, 125, + 205, 224, 85, 180, 107, 59, 205, 113, 123, 189, 222, 59, 90, 57, 51, 83, 153, 161, 73, 222, 131, 31, 208, + 79, 203, 123, 235, 178, 15, 60, 41, 64, 254, 37, 246, 69, 251, 69, 232, 107, 12, 231, 94, 98, 23, 247, 20, + 251, 88, 95, 230, 245, 236, 18, 243, 242, 126, 148, 244, 157, 246, 158, 67, 102, 10, 234, 12, 33, 231, 192, + 29, 177, 177, 180, 151, 175, 237, 193, 158, 31, 231, 73, 104, 251, 17, 13, 26, 100, 239, 15, 181, 178, 114, + 242, 156, 189, 159, 148, 90, 51, 88, 175, 121, 179, 175, 64, 252, 175, 238, 223, 95, 173, 45, 92, 219, 77, + 96, 125, 41, 222, 55, 109, 82, 251, 29, 175, 92, 121, 165, 202, 235, 13, 173, 220, 123, 93, 194, 183, 25, + 195, 237, 172, 28, 205, 42, 188, 118, 209, 207, 249, 142, 149, 123, 70, 218, 93, 63, 59, 32, 51, 52, 248, + 1, 113, 47, 58, 91, 206, 129, 202, 249, 19, 225, 32, 80, 254, 205, 220, 175, 62, 123, 162, 102, 77, 47, 63, + 156, 147, 243, 242, 1, 248, 52, 247, 157, 69, 115, 154, 250, 66, 226, 127, 130, 230, 105, 218, 63, 255, 73, + 89, 220, 247, 100, 162, 167, 103, 255, 125, 187, 112, 33, 125, 112, 235, 173, 202, 79, 224, 92, 246, 134, + 204, 92, 255, 129, 126, 94, 169, 53, 230, 231, 95, 140, 182, 114, 222, 73, 27, 115, 203, 45, 148, 202, 107, + 9, 117, 197, 147, 145, 225, 26, 144, 171, 50, 184, 31, 155, 252, 254, 251, 212, 140, 243, 21, 120, 71, 172, + 75, 156, 155, 123, 93, 246, 125, 143, 46, 86, 110, 189, 138, 56, 70, 45, 147, 185, 168, 232, 152, 222, 250, + 153, 129, 143, 53, 164, 214, 33, 207, 125, 102, 229, 254, 157, 70, 102, 221, 21, 30, 132, 223, 188, 184, + 159, 106, 229, 244, 125, 162, 251, 191, 26, 53, 138, 246, 179, 54, 207, 207, 15, 230, 172, 81, 120, 55, + 239, 41, 252, 79, 210, 235, 4, 28, 125, 197, 250, 247, 32, 102, 201, 188, 190, 162, 123, 247, 166, 46, 161, + 161, 42, 206, 59, 24, 126, 146, 126, 82, 114, 156, 217, 79, 218, 63, 167, 73, 62, 55, 3, 118, 175, 234, + 211, 135, 246, 115, 205, 114, 139, 119, 165, 81, 248, 250, 235, 23, 45, 162, 78, 220, 127, 73, 142, 151, + 249, 147, 153, 183, 58, 24, 124, 227, 89, 186, 91, 185, 181, 170, 57, 15, 253, 84, 115, 58, 192, 202, 61, + 39, 27, 100, 64, 106, 220, 80, 43, 39, 239, 201, 231, 214, 153, 220, 219, 99, 63, 63, 254, 37, 247, 131, + 75, 149, 67, 184, 39, 73, 221, 189, 59, 160, 24, 154, 98, 229, 157, 103, 76, 93, 161, 206, 40, 86, 174, + 172, 230, 24, 233, 41, 41, 20, 197, 61, 174, 188, 63, 12, 31, 189, 109, 229, 196, 198, 123, 214, 249, 125, + 133, 253, 93, 119, 179, 167, 128, 221, 19, 89, 95, 167, 197, 199, 83, 166, 75, 177, 143, 61, 7, 204, 91, + 162, 62, 248, 128, 154, 240, 154, 125, 193, 224, 93, 244, 41, 214, 239, 91, 6, 231, 146, 175, 193, 247, + 199, 86, 238, 216, 21, 78, 133, 207, 48, 43, 167, 150, 141, 176, 124, 255, 158, 90, 243, 247, 150, 153, + 159, 249, 97, 198, 161, 47, 62, 102, 248, 128, 172, 1, 169, 207, 19, 180, 29, 209, 111, 188, 65, 251, 185, + 38, 7, 226, 19, 137, 121, 127, 245, 69, 114, 75, 132, 182, 127, 85, 143, 30, 148, 176, 121, 51, 133, 87, + 171, 150, 157, 247, 164, 103, 239, 110, 248, 43, 144, 190, 194, 60, 155, 142, 239, 89, 59, 96, 0, 237, 99, + 187, 145, 151, 157, 6, 106, 85, 26, 107, 202, 1, 13, 27, 102, 239, 53, 216, 121, 239, 108, 229, 236, 119, + 8, 231, 125, 173, 156, 217, 247, 32, 189, 142, 37, 118, 237, 191, 139, 210, 254, 121, 126, 246, 207, 223, + 49, 63, 139, 101, 162, 149, 251, 188, 177, 189, 246, 218, 99, 209, 23, 247, 246, 248, 196, 125, 135, 151, + 41, 67, 219, 151, 45, 163, 44, 214, 227, 129, 248, 197, 215, 125, 204, 252, 98, 230, 150, 137, 87, 93, 69, + 171, 57, 118, 70, 93, 127, 189, 242, 11, 226, 1, 58, 70, 246, 2, 101, 143, 168, 159, 246, 151, 196, 188, + 169, 49, 204, 125, 45, 233, 41, 212, 217, 218, 42, 85, 84, 63, 9, 189, 226, 6, 255, 152, 73, 12, 105, 214, + 76, 229, 123, 196, 60, 250, 52, 179, 47, 49, 115, 150, 232, 50, 169, 207, 230, 239, 157, 22, 174, 133, 99, + 147, 79, 251, 187, 91, 121, 157, 229, 247, 181, 183, 231, 143, 251, 252, 248, 23, 126, 212, 123, 9, 172, + 205, 50, 57, 207, 101, 112, 108, 7, 226, 23, 95, 247, 176, 243, 47, 218, 127, 66, 249, 242, 52, 234, 242, + 203, 149, 79, 224, 27, 196, 133, 172, 3, 209, 53, 162, 235, 205, 152, 183, 231, 54, 179, 167, 20, 187, 215, + 13, 28, 232, 90, 236, 239, 227, 88, 192, 89, 182, 87, 56, 231, 131, 123, 196, 60, 52, 157, 217, 151, 152, + 251, 29, 246, 185, 183, 240, 109, 126, 142, 140, 125, 54, 226, 143, 207, 188, 32, 250, 122, 154, 149, 119, + 157, 247, 199, 189, 169, 251, 69, 155, 173, 103, 109, 182, 143, 117, 95, 160, 190, 201, 239, 250, 230, 76, + 89, 206, 146, 133, 105, 142, 7, 106, 190, 7, 88, 57, 61, 60, 108, 64, 156, 152, 239, 51, 216, 231, 152, + 230, 172, 18, 223, 55, 249, 238, 187, 41, 141, 245, 68, 6, 199, 126, 58, 180, 133, 195, 192, 254, 202, 240, + 230, 205, 213, 140, 14, 218, 78, 114, 125, 94, 125, 137, 201, 185, 175, 60, 109, 242, 107, 231, 48, 191, + 121, 77, 32, 240, 85, 239, 243, 202, 253, 74, 87, 177, 238, 75, 218, 185, 147, 60, 92, 235, 2, 245, 205, + 76, 254, 57, 59, 204, 251, 152, 189, 133, 188, 71, 130, 53, 32, 253, 186, 93, 203, 138, 190, 51, 231, 215, + 102, 78, 51, 251, 149, 8, 253, 51, 27, 120, 205, 238, 101, 142, 210, 211, 210, 28, 7, 52, 223, 150, 181, + 107, 169, 21, 231, 45, 196, 61, 52, 61, 180, 29, 114, 189, 244, 37, 194, 187, 172, 91, 147, 115, 251, 218, + 181, 243, 235, 143, 35, 95, 126, 117, 10, 118, 110, 96, 43, 98, 50, 250, 245, 215, 11, 236, 199, 64, 248, + 151, 88, 149, 28, 32, 159, 115, 103, 106, 90, 83, 215, 219, 251, 87, 123, 207, 34, 57, 5, 215, 153, 122, + 255, 253, 106, 29, 162, 94, 185, 193, 255, 126, 246, 199, 200, 87, 95, 85, 121, 31, 220, 35, 223, 203, 204, + 21, 58, 94, 126, 127, 128, 47, 141, 98, 175, 199, 37, 193, 117, 94, 220, 124, 174, 109, 85, 103, 60, 67, + 66, 104, 251, 242, 229, 148, 185, 127, 191, 227, 252, 139, 6, 148, 51, 133, 246, 207, 189, 148, 186, 232, + 47, 230, 125, 173, 39, 233, 39, 190, 153, 56, 145, 50, 89, 155, 165, 177, 45, 78, 3, 58, 8, 123, 179, 111, + 92, 113, 133, 170, 247, 93, 172, 243, 231, 237, 190, 52, 74, 126, 188, 23, 39, 223, 254, 184, 153, 102, + 229, 206, 161, 211, 107, 212, 32, 15, 63, 111, 26, 199, 82, 65, 124, 148, 215, 61, 228, 62, 246, 53, 96, + 126, 174, 128, 175, 254, 197, 159, 223, 100, 205, 74, 236, 207, 100, 173, 42, 53, 63, 45, 53, 213, 113, + 236, 231, 117, 53, 158, 115, 34, 180, 62, 102, 19, 239, 105, 238, 229, 247, 8, 155, 123, 45, 38, 239, 118, + 219, 75, 146, 239, 188, 114, 191, 244, 252, 200, 253, 27, 194, 195, 41, 243, 208, 161, 2, 251, 104, 22, + 255, 172, 29, 190, 238, 39, 121, 219, 126, 214, 204, 212, 65, 38, 239, 190, 236, 22, 189, 42, 61, 223, 150, + 217, 179, 41, 243, 224, 65, 87, 184, 199, 12, 9, 239, 163, 181, 231, 158, 21, 121, 31, 179, 9, 204, 99, 37, + 238, 101, 159, 101, 114, 62, 182, 251, 242, 79, 73, 65, 108, 50, 115, 63, 226, 40, 226, 182, 219, 40, 37, + 62, 158, 210, 185, 134, 58, 205, 191, 220, 207, 212, 110, 118, 152, 53, 222, 223, 186, 53, 215, 44, 124, + 63, 175, 110, 93, 242, 112, 173, 74, 229, 28, 148, 202, 118, 56, 141, 189, 28, 251, 99, 90, 180, 80, 154, + 15, 189, 61, 116, 190, 124, 230, 166, 236, 177, 79, 50, 184, 47, 205, 188, 155, 188, 216, 115, 63, 116, + 247, 138, 119, 222, 81, 53, 180, 48, 126, 202, 111, 173, 249, 210, 4, 190, 250, 148, 252, 114, 150, 25, + 251, 99, 185, 15, 199, 140, 42, 131, 235, 85, 42, 247, 125, 78, 3, 253, 15, 206, 152, 182, 187, 236, 50, + 213, 227, 35, 239, 163, 183, 71, 143, 138, 222, 14, 154, 69, 246, 215, 131, 137, 123, 51, 246, 39, 235, + 231, 8, 191, 242, 74, 218, 197, 26, 39, 157, 235, 104, 97, 124, 21, 40, 255, 190, 180, 129, 191, 239, 177, + 255, 188, 105, 51, 98, 63, 154, 123, 113, 15, 231, 125, 55, 184, 7, 176, 239, 25, 206, 247, 192, 126, 45, + 102, 248, 152, 81, 66, 235, 75, 222, 159, 168, 227, 103, 170, 237, 57, 74, 154, 227, 64, 248, 151, 56, 194, + 250, 133, 238, 155, 223, 176, 97, 145, 124, 25, 200, 61, 3, 133, 175, 159, 53, 99, 95, 205, 16, 43, 85, + 162, 93, 27, 55, 82, 26, 199, 104, 10, 223, 223, 105, 120, 184, 238, 111, 250, 226, 139, 236, 216, 135, + 222, 55, 63, 103, 197, 204, 251, 211, 253, 216, 94, 218, 96, 247, 37, 214, 238, 4, 253, 60, 155, 231, 206, + 165, 12, 174, 163, 133, 245, 215, 28, 190, 70, 94, 152, 29, 32, 252, 253, 204, 76, 195, 102, 104, 149, 149, + 92, 171, 60, 28, 159, 41, 201, 201, 174, 0, 251, 30, 35, 154, 52, 81, 115, 62, 204, 247, 160, 249, 62, 179, + 172, 236, 115, 181, 194, 253, 12, 237, 91, 95, 246, 151, 54, 136, 141, 194, 191, 244, 79, 211, 170, 87, + 167, 52, 214, 124, 136, 227, 194, 250, 203, 77, 123, 225, 95, 201, 253, 136, 253, 168, 91, 111, 165, 196, + 29, 59, 40, 149, 251, 61, 55, 184, 71, 236, 127, 29, 19, 67, 111, 94, 122, 169, 154, 239, 98, 111, 18, 123, + 81, 208, 124, 102, 222, 159, 166, 215, 101, 48, 112, 47, 254, 156, 165, 249, 135, 47, 145, 251, 161, 97, + 215, 135, 133, 81, 6, 231, 254, 162, 248, 204, 77, 238, 37, 246, 177, 94, 49, 99, 89, 63, 120, 112, 145, + 237, 245, 11, 228, 126, 214, 147, 67, 158, 123, 78, 237, 235, 73, 191, 103, 143, 125, 169, 249, 193, 22, + 251, 102, 30, 85, 250, 245, 230, 155, 213, 103, 34, 160, 127, 42, 173, 252, 75, 236, 163, 230, 206, 124, + 248, 97, 74, 225, 126, 3, 60, 37, 39, 37, 57, 14, 196, 254, 186, 57, 115, 20, 247, 152, 245, 152, 177, 143, + 57, 143, 196, 190, 212, 252, 96, 224, 222, 30, 251, 88, 187, 88, 195, 136, 253, 229, 92, 71, 17, 75, 69, + 245, 155, 91, 220, 139, 189, 210, 167, 224, 61, 132, 116, 142, 79, 55, 184, 199, 58, 78, 247, 120, 232, + 211, 26, 53, 212, 89, 14, 51, 246, 165, 223, 11, 230, 186, 47, 177, 4, 13, 173, 126, 143, 79, 133, 10, 180, + 115, 195, 6, 74, 229, 218, 95, 84, 223, 205, 229, 235, 57, 5, 177, 219, 172, 85, 136, 253, 69, 220, 163, + 164, 113, 124, 38, 51, 79, 174, 196, 62, 235, 223, 216, 200, 72, 165, 249, 48, 227, 199, 172, 7, 251, 185, + 234, 51, 111, 44, 239, 204, 33, 74, 251, 112, 150, 97, 167, 147, 207, 238, 6, 100, 13, 152, 117, 20, 207, + 179, 232, 213, 87, 41, 157, 159, 217, 9, 223, 57, 205, 189, 105, 175, 218, 51, 228, 181, 186, 99, 205, 26, + 74, 225, 248, 76, 74, 76, 116, 28, 106, 77, 49, 62, 122, 240, 65, 117, 102, 19, 103, 57, 48, 227, 31, 100, + 229, 244, 123, 147, 173, 220, 154, 47, 24, 248, 55, 253, 41, 177, 164, 102, 103, 33, 33, 234, 119, 180, + 164, 58, 228, 79, 55, 99, 31, 121, 119, 101, 215, 174, 148, 198, 61, 153, 27, 220, 3, 136, 253, 69, 67, + 135, 170, 89, 15, 246, 118, 113, 142, 7, 177, 47, 159, 167, 19, 97, 229, 206, 251, 193, 192, 189, 221, 159, + 200, 91, 210, 63, 207, 126, 230, 25, 47, 247, 28, 187, 165, 133, 127, 123, 236, 79, 213, 126, 159, 90, 165, + 10, 37, 236, 220, 73, 201, 172, 251, 220, 224, 30, 122, 114, 15, 95, 191, 199, 29, 119, 168, 51, 61, 136, + 125, 204, 121, 47, 164, 216, 23, 127, 34, 151, 34, 247, 127, 51, 101, 138, 170, 165, 78, 249, 112, 62, 95, + 179, 168, 152, 167, 49, 199, 176, 23, 122, 123, 99, 120, 56, 165, 178, 230, 75, 228, 251, 184, 129, 12, + 206, 43, 211, 223, 127, 95, 213, 125, 204, 121, 113, 158, 7, 251, 123, 210, 239, 9, 247, 179, 180, 95, 197, + 78, 39, 158, 217, 77, 152, 254, 156, 165, 253, 9, 221, 55, 253, 129, 7, 40, 137, 251, 167, 36, 174, 119, + 78, 249, 112, 1, 95, 183, 40, 48, 109, 134, 189, 200, 179, 152, 79, 204, 127, 250, 105, 74, 102, 125, 170, + 238, 147, 144, 224, 56, 16, 251, 219, 190, 254, 154, 186, 92, 115, 141, 58, 191, 139, 126, 15, 251, 123, + 166, 230, 155, 170, 215, 227, 28, 195, 206, 162, 62, 111, 113, 64, 108, 21, 127, 66, 187, 170, 249, 201, + 176, 97, 148, 202, 177, 239, 152, 15, 121, 29, 57, 201, 61, 124, 173, 246, 165, 203, 151, 167, 109, 75, + 151, 42, 205, 231, 6, 247, 0, 102, 222, 227, 91, 183, 206, 53, 235, 193, 254, 158, 228, 125, 233, 245, 145, + 67, 231, 6, 17, 255, 98, 39, 108, 70, 236, 35, 127, 41, 13, 131, 90, 186, 123, 183, 55, 246, 29, 242, 33, + 62, 155, 198, 41, 91, 103, 107, 127, 195, 214, 216, 142, 29, 41, 133, 243, 126, 2, 223, 195, 13, 164, 112, + 94, 217, 184, 108, 25, 181, 47, 87, 46, 123, 206, 43, 177, 47, 154, 207, 140, 125, 51, 231, 151, 52, 191, + 133, 137, 39, 212, 178, 85, 31, 125, 228, 168, 79, 89, 63, 254, 158, 92, 132, 248, 247, 149, 247, 85, 204, + 241, 58, 221, 19, 23, 71, 137, 124, 237, 132, 248, 120, 231, 193, 182, 99, 238, 49, 184, 78, 29, 117, 166, + 207, 30, 251, 19, 180, 29, 51, 244, 154, 12, 22, 238, 253, 197, 147, 58, 131, 92, 185, 50, 237, 218, 178, + 197, 81, 159, 102, 122, 60, 59, 62, 143, 138, 162, 133, 124, 253, 130, 194, 180, 215, 110, 235, 215, 227, + 198, 81, 10, 231, 21, 87, 184, 103, 164, 101, 102, 210, 202, 201, 147, 213, 156, 79, 250, 61, 236, 237, + 203, 239, 245, 130, 78, 54, 53, 159, 233, 223, 194, 60, 107, 113, 194, 244, 169, 232, 62, 212, 178, 21, + 157, 59, 123, 99, 223, 33, 31, 34, 247, 123, 50, 50, 194, 254, 85, 187, 118, 145, 249, 151, 60, 5, 191, 47, + 126, 238, 57, 74, 226, 216, 140, 231, 235, 199, 243, 125, 156, 70, 2, 247, 188, 136, 255, 143, 238, 187, + 79, 189, 183, 37, 231, 122, 6, 91, 250, 253, 81, 203, 155, 47, 77, 205, 23, 76, 220, 155, 62, 69, 254, 82, + 159, 225, 94, 169, 18, 197, 109, 216, 64, 137, 172, 251, 157, 242, 99, 122, 122, 186, 103, 201, 146, 37, + 45, 203, 150, 45, 91, 228, 216, 151, 117, 26, 85, 177, 34, 109, 95, 179, 134, 18, 89, 151, 199, 239, 217, + 227, 10, 112, 102, 100, 246, 199, 31, 103, 247, 123, 56, 215, 99, 239, 247, 68, 243, 205, 179, 130, 47, + 246, 23, 88, 185, 117, 31, 106, 217, 146, 54, 109, 40, 153, 159, 219, 73, 63, 238, 205, 202, 154, 210, 162, + 69, 139, 134, 86, 17, 236, 180, 247, 123, 107, 122, 245, 162, 100, 206, 251, 110, 113, 15, 221, 187, 237, + 155, 111, 168, 235, 117, 215, 101, 159, 235, 49, 247, 246, 101, 206, 23, 236, 177, 63, 87, 63, 131, 122, + 231, 234, 202, 43, 105, 219, 170, 85, 222, 216, 119, 200, 143, 169, 201, 201, 71, 191, 90, 191, 190, 93, + 165, 138, 21, 11, 204, 191, 175, 216, 135, 157, 115, 31, 126, 152, 226, 185, 207, 71, 110, 118, 139, 255, + 84, 142, 129, 177, 45, 91, 102, 159, 235, 193, 172, 71, 246, 246, 101, 206, 231, 43, 246, 75, 154, 219, + 130, 198, 20, 236, 151, 216, 95, 252, 202, 43, 148, 196, 122, 199, 225, 216, 95, 208, 165, 75, 151, 70, + 204, 125, 189, 75, 46, 185, 164, 200, 118, 78, 9, 13, 165, 77, 243, 230, 81, 98, 122, 58, 237, 225, 254, + 212, 13, 36, 167, 165, 209, 151, 11, 23, 82, 59, 174, 87, 157, 173, 243, 251, 61, 228, 159, 169, 86, 142, + 230, 11, 166, 216, 23, 191, 154, 177, 175, 206, 73, 151, 47, 79, 91, 185, 199, 77, 224, 216, 119, 202, 143, + 73, 137, 137, 103, 183, 110, 217, 210, 229, 198, 27, 111, 4, 255, 181, 193, 255, 34, 190, 87, 32, 48, 109, + 21, 59, 161, 249, 98, 219, 181, 83, 107, 212, 45, 238, 177, 102, 209, 247, 124, 250, 196, 19, 231, 237, + 239, 137, 230, 131, 191, 80, 135, 36, 239, 139, 173, 129, 62, 91, 73, 66, 108, 21, 221, 39, 51, 20, 236, + 153, 39, 178, 150, 118, 210, 151, 89, 153, 153, 171, 250, 245, 237, 251, 34, 115, 223, 128, 185, 175, 25, + 40, 255, 38, 247, 18, 251, 168, 181, 179, 170, 86, 165, 221, 219, 183, 171, 220, 239, 22, 255, 169, 188, + 182, 22, 14, 27, 166, 230, 124, 246, 126, 207, 156, 241, 155, 121, 63, 88, 248, 183, 251, 117, 150, 246, + 107, 4, 231, 185, 205, 139, 23, 83, 2, 246, 183, 28, 242, 35, 247, 125, 191, 236, 218, 181, 171, 103, 213, + 170, 85, 17, 251, 117, 152, 251, 127, 4, 194, 191, 153, 167, 204, 53, 58, 153, 127, 246, 219, 168, 40, 199, + 215, 104, 46, 155, 185, 223, 139, 219, 178, 133, 222, 189, 229, 22, 245, 14, 23, 250, 61, 57, 203, 61, 218, + 202, 173, 249, 164, 215, 15, 22, 238, 125, 197, 254, 12, 203, 189, 216, 207, 244, 120, 190, 30, 30, 22, + 246, 50, 115, 255, 2, 227, 41, 230, 254, 161, 130, 240, 111, 174, 81, 196, 220, 178, 22, 45, 40, 209, 227, + 113, 141, 123, 137, 125, 188, 191, 105, 238, 239, 201, 153, 46, 115, 198, 31, 140, 121, 95, 124, 107, 250, + 85, 237, 155, 135, 132, 208, 166, 249, 243, 41, 145, 53, 143, 131, 177, 255, 95, 174, 253, 253, 30, 126, + 248, 97, 196, 254, 179, 204, 251, 63, 25, 127, 5, 255, 139, 249, 158, 254, 96, 218, 41, 107, 84, 205, 214, + 110, 191, 157, 118, 109, 221, 74, 241, 28, 159, 110, 113, 15, 205, 183, 30, 154, 143, 245, 229, 219, 86, + 206, 251, 123, 195, 44, 175, 230, 147, 57, 159, 228, 125, 147, 247, 188, 158, 169, 180, 64, 108, 53, 245, + 20, 116, 236, 130, 103, 159, 245, 106, 105, 214, 61, 78, 249, 210, 147, 145, 177, 45, 50, 34, 162, 41, 115, + 143, 158, 239, 105, 230, 189, 58, 163, 106, 94, 252, 47, 178, 217, 56, 207, 202, 233, 75, 241, 206, 190, + 155, 177, 143, 25, 85, 34, 175, 173, 126, 143, 61, 230, 87, 243, 217, 243, 126, 48, 114, 47, 113, 133, 53, + 140, 216, 143, 44, 83, 134, 54, 205, 157, 235, 104, 236, 171, 222, 57, 37, 101, 240, 19, 79, 60, 209, 152, + 185, 127, 142, 57, 127, 156, 113, 31, 227, 246, 64, 248, 95, 104, 229, 104, 62, 112, 191, 172, 89, 51, 111, + 109, 114, 112, 125, 250, 202, 251, 115, 251, 247, 87, 121, 31, 239, 238, 218, 103, 252, 102, 175, 47, 121, + 63, 24, 249, 183, 247, 82, 11, 235, 214, 117, 60, 246, 51, 210, 211, 227, 103, 76, 159, 222, 156, 185, 71, + 238, 127, 134, 57, 127, 132, 113, 55, 227, 38, 127, 252, 251, 203, 251, 179, 139, 33, 239, 163, 215, 219, + 186, 113, 35, 117, 185, 246, 90, 245, 57, 162, 190, 52, 159, 217, 235, 7, 115, 236, 75, 92, 169, 243, 93, + 208, 252, 11, 22, 56, 30, 251, 233, 105, 105, 35, 106, 215, 174, 141, 216, 127, 158, 249, 126, 130, 113, + 63, 227, 14, 198, 245, 224, 63, 154, 239, 109, 194, 180, 211, 204, 251, 232, 177, 191, 157, 52, 201, 93, + 205, 199, 246, 98, 111, 127, 228, 75, 47, 169, 126, 207, 124, 127, 111, 132, 229, 213, 124, 210, 235, 155, + 220, 139, 205, 246, 103, 41, 109, 48, 215, 193, 66, 43, 119, 236, 47, 134, 230, 119, 216, 183, 204, 125, + 202, 130, 249, 243, 91, 133, 132, 132, 128, 255, 90, 204, 247, 163, 58, 246, 111, 102, 92, 3, 254, 99, 248, + 222, 38, 76, 91, 37, 63, 161, 214, 198, 182, 110, 77, 137, 46, 206, 121, 0, 156, 23, 138, 229, 53, 134, + 154, 111, 158, 229, 149, 188, 47, 251, 250, 194, 189, 201, 185, 253, 57, 74, 35, 76, 223, 10, 255, 170, + 151, 230, 216, 223, 226, 112, 191, 143, 216, 231, 220, 63, 166, 222, 243, 207, 55, 209, 179, 222, 39, 25, + 127, 211, 177, 127, 3, 163, 162, 157, 127, 187, 125, 243, 180, 125, 243, 238, 190, 155, 118, 185, 60, 231, + 73, 224, 107, 239, 138, 139, 163, 158, 213, 170, 169, 179, 188, 102, 222, 87, 159, 15, 106, 121, 243, 164, + 232, 253, 69, 182, 216, 42, 105, 110, 11, 194, 63, 108, 23, 221, 7, 45, 19, 211, 184, 177, 227, 253, 126, + 90, 106, 106, 198, 146, 152, 152, 54, 161, 161, 161, 141, 245, 172, 23, 177, 127, 143, 17, 251, 87, 153, + 252, 71, 251, 176, 79, 237, 67, 162, 46, 205, 154, 229, 234, 156, 7, 192, 254, 78, 100, 135, 14, 185, 246, + 119, 176, 183, 107, 230, 125, 83, 239, 7, 115, 236, 75, 94, 85, 239, 116, 93, 118, 25, 125, 191, 124, 185, + 163, 115, 126, 32, 211, 227, 153, 216, 184, 113, 99, 196, 126, 125, 230, 185, 6, 227, 1, 198, 157, 140, + 202, 140, 74, 140, 203, 125, 241, 111, 218, 135, 120, 91, 221, 185, 51, 37, 50, 55, 110, 114, 159, 204, + 154, 247, 75, 214, 62, 56, 207, 135, 94, 95, 246, 119, 204, 94, 223, 156, 243, 152, 177, 95, 210, 188, 22, + 53, 246, 151, 54, 111, 238, 120, 221, 231, 216, 199, 249, 142, 215, 202, 149, 43, 7, 254, 255, 197, 60, + 255, 93, 199, 254, 45, 140, 63, 233, 216, 47, 15, 254, 151, 216, 108, 20, 251, 80, 103, 23, 61, 250, 168, + 247, 204, 72, 66, 130, 107, 220, 203, 89, 161, 143, 171, 87, 63, 239, 76, 143, 169, 247, 165, 215, 19, 238, + 197, 230, 37, 65, 0, 187, 127, 231, 105, 255, 78, 173, 80, 129, 182, 173, 94, 237, 120, 236, 123, 50, 50, + 34, 154, 240, 127, 198, 62, 143, 61, 246, 175, 96, 148, 181, 215, 127, 209, 252, 234, 189, 19, 216, 182, + 98, 5, 37, 56, 216, 143, 248, 203, 251, 211, 222, 123, 207, 231, 59, 28, 246, 188, 191, 48, 8, 185, 55, + 249, 151, 220, 138, 60, 6, 45, 187, 162, 109, 91, 199, 247, 78, 85, 236, 199, 196, 188, 174, 99, 95, 246, + 121, 238, 213, 177, 127, 173, 17, 251, 151, 154, 252, 155, 154, 20, 189, 254, 87, 253, 251, 187, 159, 247, + 121, 109, 109, 88, 186, 148, 58, 94, 113, 69, 246, 59, 28, 56, 211, 35, 251, 250, 50, 227, 157, 99, 229, + 212, 124, 115, 189, 150, 52, 175, 5, 141, 125, 83, 83, 79, 187, 230, 26, 117, 174, 47, 193, 225, 89, 138, + 174, 251, 230, 30, 239, 131, 62, 234, 126, 40, 35, 68, 248, 23, 219, 230, 107, 219, 150, 53, 104, 64, 9, + 14, 207, 161, 206, 203, 251, 152, 241, 38, 39, 211, 39, 143, 63, 174, 206, 113, 251, 155, 241, 206, 178, + 114, 102, 124, 193, 30, 251, 82, 247, 17, 251, 171, 186, 118, 117, 188, 159, 54, 98, 255, 69, 29, 251, 143, + 233, 216, 191, 85, 199, 126, 5, 35, 246, 203, 200, 252, 71, 242, 190, 154, 169, 221, 118, 27, 237, 220, + 180, 137, 18, 152, 27, 183, 243, 254, 204, 222, 189, 179, 103, 188, 242, 25, 109, 200, 251, 227, 172, 220, + 189, 126, 176, 115, 47, 241, 37, 154, 127, 230, 77, 55, 209, 206, 45, 91, 28, 239, 167, 51, 189, 117, 95, + 98, 95, 246, 120, 239, 210, 177, 255, 7, 93, 247, 37, 246, 47, 17, 254, 197, 182, 25, 151, 94, 74, 155, + 166, 77, 115, 125, 95, 23, 239, 3, 127, 19, 27, 75, 111, 177, 198, 240, 151, 247, 69, 239, 75, 222, 55, + 253, 186, 52, 72, 32, 246, 218, 235, 254, 186, 190, 125, 29, 175, 173, 62, 234, 126, 126, 177, 127, 137, + 236, 255, 75, 222, 95, 139, 156, 228, 114, 205, 151, 115, 252, 56, 207, 229, 47, 239, 219, 245, 190, 25, + 243, 37, 205, 105, 65, 185, 23, 93, 45, 117, 127, 206, 61, 247, 208, 238, 93, 187, 28, 239, 169, 50, 210, + 211, 199, 213, 171, 87, 207, 87, 236, 223, 232, 39, 246, 21, 255, 88, 151, 208, 215, 49, 53, 107, 170, 125, + 29, 55, 123, 61, 201, 251, 211, 123, 246, 244, 153, 247, 229, 76, 199, 12, 43, 103, 79, 63, 250, 2, 137, + 125, 172, 103, 244, 50, 27, 71, 141, 114, 99, 206, 159, 186, 96, 254, 252, 54, 33, 33, 33, 129, 214, 125, + 252, 103, 89, 218, 174, 185, 55, 220, 64, 113, 235, 215, 59, 222, 135, 158, 151, 247, 161, 247, 99, 98, + 148, 222, 151, 115, 188, 146, 247, 195, 45, 239, 140, 215, 151, 222, 15, 86, 238, 205, 126, 31, 57, 109, + 193, 99, 143, 81, 60, 116, 149, 131, 186, 90, 239, 241, 141, 174, 83, 167, 142, 93, 243, 231, 85, 247, 179, + 249, 159, 81, 166, 12, 125, 23, 17, 225, 122, 205, 79, 48, 230, 60, 230, 153, 14, 121, 111, 211, 174, 247, + 47, 132, 188, 47, 177, 175, 206, 117, 114, 174, 221, 52, 99, 134, 227, 231, 228, 57, 239, 39, 204, 154, 57, + 179, 21, 243, 249, 162, 173, 223, 207, 47, 246, 21, 255, 107, 48, 223, 117, 121, 95, 79, 242, 254, 148, + 183, 223, 86, 251, 186, 221, 44, 223, 243, 125, 225, 94, 226, 30, 254, 92, 166, 177, 60, 8, 176, 204, 192, + 18, 43, 103, 150, 138, 156, 182, 132, 123, 106, 167, 207, 205, 232, 179, 61, 195, 106, 60, 249, 228, 75, + 62, 98, 63, 175, 186, 159, 205, 127, 113, 212, 124, 236, 233, 175, 153, 53, 139, 218, 151, 45, 155, 125, + 150, 79, 62, 163, 73, 206, 243, 72, 205, 151, 184, 15, 54, 238, 77, 254, 151, 234, 103, 128, 126, 81, 231, + 122, 185, 222, 109, 115, 97, 143, 199, 147, 145, 17, 23, 25, 25, 249, 111, 230, 241, 69, 61, 231, 47, 72, + 236, 43, 254, 221, 174, 249, 216, 215, 221, 185, 125, 123, 174, 125, 93, 251, 124, 95, 106, 190, 169, 247, + 130, 141, 123, 147, 127, 209, 125, 18, 251, 43, 219, 182, 117, 60, 199, 38, 196, 199, 255, 158, 148, 152, + 56, 160, 122, 245, 234, 47, 233, 61, 190, 130, 198, 190, 226, 223, 213, 188, 143, 243, 60, 248, 29, 227, + 205, 155, 103, 159, 231, 49, 207, 112, 227, 29, 55, 179, 230, 75, 159, 111, 230, 209, 146, 230, 180, 48, + 177, 47, 51, 21, 245, 57, 163, 149, 43, 211, 206, 111, 191, 117, 252, 204, 92, 166, 199, 243, 237, 200, 17, + 35, 154, 7, 16, 251, 101, 253, 196, 190, 235, 252, 227, 28, 231, 146, 240, 112, 213, 231, 155, 239, 238, + 152, 51, 190, 153, 6, 247, 146, 243, 87, 104, 196, 6, 9, 196, 222, 229, 6, 255, 208, 125, 232, 247, 215, + 247, 235, 231, 120, 236, 39, 38, 36, 252, 178, 107, 231, 206, 222, 119, 87, 171, 246, 178, 177, 191, 111, + 159, 243, 231, 23, 251, 174, 242, 143, 207, 41, 219, 194, 61, 229, 59, 250, 125, 109, 251, 140, 207, 172, + 249, 18, 247, 203, 131, 144, 123, 59, 255, 146, 251, 209, 87, 47, 252, 219, 223, 84, 14, 68, 223, 227, 164, + 111, 179, 50, 51, 87, 247, 237, 219, 183, 25, 243, 215, 132, 57, 197, 217, 30, 236, 239, 255, 229, 146, + 156, 61, 190, 252, 234, 190, 171, 252, 171, 189, 29, 230, 127, 224, 211, 79, 251, 60, 191, 111, 175, 249, + 49, 182, 184, 15, 38, 254, 77, 155, 37, 246, 229, 252, 196, 119, 56, 47, 235, 240, 185, 41, 253, 14, 111, + 143, 155, 111, 190, 249, 101, 125, 174, 79, 206, 246, 84, 185, 196, 247, 30, 159, 191, 216, 119, 141, 127, + 53, 227, 235, 209, 35, 223, 94, 111, 129, 246, 215, 210, 11, 32, 246, 205, 158, 15, 53, 109, 105, 221, 186, + 222, 179, 19, 14, 239, 161, 238, 205, 202, 90, 220, 165, 75, 151, 166, 58, 246, 229, 76, 175, 175, 179, 61, + 249, 197, 190, 43, 252, 163, 215, 91, 59, 123, 182, 207, 179, 92, 99, 173, 156, 188, 111, 215, 123, 193, + 204, 189, 89, 247, 213, 187, 124, 232, 247, 112, 118, 198, 193, 243, 188, 202, 183, 201, 201, 71, 190, 92, + 183, 174, 83, 165, 74, 149, 94, 177, 188, 231, 249, 229, 76, 47, 98, 255, 6, 35, 246, 203, 6, 16, 251, 142, + 243, 143, 119, 182, 118, 108, 221, 74, 61, 239, 186, 83, 189, 175, 251, 254, 37, 22, 245, 101, 12, 102, + 140, 102, 68, 50, 166, 51, 230, 50, 22, 49, 150, 48, 150, 51, 86, 48, 98, 53, 86, 6, 9, 98, 13, 44, 211, + 207, 130, 103, 66, 236, 175, 238, 216, 145, 18, 179, 156, 159, 169, 177, 230, 255, 188, 121, 243, 230, 224, + 190, 49, 115, 42, 239, 242, 200, 153, 222, 130, 198, 190, 163, 252, 99, 22, 133, 115, 156, 35, 26, 53, 242, + 254, 14, 6, 246, 69, 111, 198, 64, 198, 200, 50, 22, 77, 100, 76, 101, 204, 97, 44, 100, 196, 48, 150, 49, + 86, 48, 98, 53, 86, 6, 17, 196, 230, 21, 250, 57, 162, 203, 232, 207, 30, 185, 253, 54, 218, 245, 253, 86, + 199, 247, 246, 211, 211, 210, 50, 22, 45, 92, 216, 54, 52, 52, 20, 252, 227, 61, 62, 243, 93, 30, 57, 207, + 47, 117, 63, 16, 238, 29, 229, 31, 53, 127, 14, 247, 58, 224, 30, 251, 122, 189, 152, 247, 254, 140, 225, + 236, 151, 241, 140, 40, 198, 44, 198, 2, 237, 171, 165, 23, 0, 247, 192, 114, 198, 18, 172, 105, 29, 251, + 95, 135, 133, 57, 222, 239, 201, 30, 79, 173, 90, 181, 192, 125, 35, 230, 85, 222, 225, 149, 247, 248, 228, + 60, 127, 185, 2, 196, 62, 254, 251, 127, 52, 236, 82, 212, 99, 101, 187, 34, 0, 0, 7, 176, 109, 107, 66, + 84, 250, 206, 202, 254, 0, 127, 161, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 218, 105, 108, 84, 85, 20, 7, 240, 185, 116, 92, 106, 91, 11, + 181, 213, 130, 150, 130, 214, 149, 182, 106, 221, 215, 22, 171, 2, 182, 84, 173, 27, 84, 65, 220, 45, 174, + 45, 160, 209, 40, 181, 36, 84, 12, 40, 70, 155, 0, 31, 209, 136, 242, 65, 144, 189, 18, 36, 128, 169, 128, + 213, 176, 164, 237, 84, 218, 210, 69, 99, 92, 190, 184, 98, 140, 38, 207, 115, 230, 205, 245, 221, 62, 222, + 144, 182, 148, 185, 243, 46, 255, 147, 252, 190, 206, 36, 231, 157, 156, 123, 238, 18, 16, 66, 4, 224, 127, + 50, 18, 72, 144, 156, 68, 78, 33, 169, 36, 131, 156, 73, 206, 33, 185, 228, 74, 82, 68, 74, 200, 61, 228, + 65, 242, 36, 121, 46, 16, 8, 60, 79, 62, 44, 43, 43, 251, 107, 239, 158, 61, 214, 193, 206, 78, 171, 165, + 185, 57, 166, 66, 93, 93, 86, 243, 190, 125, 214, 246, 233, 211, 172, 117, 34, 96, 109, 8, 4, 172, 134, 97, + 1, 235, 83, 178, 217, 161, 59, 223, 241, 72, 198, 176, 72, 13, 156, 24, 169, 129, 83, 73, 58, 25, 69, 206, + 38, 23, 145, 203, 201, 141, 100, 18, 185, 139, 76, 35, 143, 147, 103, 25, 213, 192, 59, 185, 227, 198, 253, + 180, 185, 161, 193, 234, 237, 233, 137, 121, 13, 180, 182, 181, 89, 33, 250, 223, 166, 165, 75, 172, 77, + 163, 70, 90, 235, 168, 6, 54, 137, 62, 53, 160, 59, 215, 241, 74, 173, 129, 132, 72, 13, 36, 146, 20, 146, + 70, 70, 146, 49, 228, 2, 82, 64, 174, 39, 19, 200, 157, 228, 126, 242, 24, 121, 70, 216, 189, 160, 54, 45, + 45, 45, 180, 108, 217, 50, 235, 219, 222, 94, 43, 212, 218, 26, 219, 58, 104, 105, 9, 215, 192, 254, 198, + 70, 107, 107, 201, 36, 107, 109, 192, 233, 5, 248, 254, 3, 170, 129, 19, 200, 201, 36, 153, 140, 32, 103, + 144, 108, 114, 62, 185, 132, 92, 75, 110, 38, 183, 147, 169, 228, 97, 242, 84, 164, 6, 94, 76, 72, 72, 216, + 90, 93, 85, 101, 117, 118, 116, 88, 237, 7, 14, 196, 190, 23, 208, 127, 134, 104, 29, 218, 181, 224, 117, + 107, 195, 136, 225, 214, 122, 174, 1, 129, 239, 63, 200, 26, 72, 34, 195, 201, 233, 36, 139, 156, 75, 242, + 201, 213, 228, 38, 82, 74, 238, 35, 51, 72, 165, 112, 102, 130, 15, 38, 78, 152, 240, 231, 87, 77, 77, 86, + 55, 173, 207, 177, 174, 1, 238, 5, 109, 61, 189, 214, 190, 45, 91, 172, 207, 138, 10, 185, 23, 232, 206, + 175, 31, 168, 209, 223, 185, 176, 144, 220, 70, 238, 38, 211, 201, 19, 92, 3, 145, 58, 120, 43, 39, 39, + 231, 187, 213, 171, 86, 133, 215, 131, 86, 250, 38, 49, 239, 5, 237, 29, 212, 15, 218, 173, 157, 115, 95, + 213, 157, 91, 191, 80, 67, 206, 133, 178, 6, 120, 46, 60, 77, 216, 115, 225, 88, 97, 207, 133, 151, 145, + 27, 132, 61, 19, 148, 11, 123, 38, 120, 84, 56, 51, 193, 43, 137, 137, 137, 77, 117, 243, 231, 91, 61, 221, + 221, 214, 55, 52, 167, 197, 188, 23, 208, 28, 18, 234, 237, 213, 157, 87, 191, 81, 107, 192, 107, 46, 204, + 20, 246, 76, 192, 115, 225, 165, 228, 58, 114, 139, 112, 102, 130, 71, 132, 61, 19, 240, 90, 48, 139, 172, + 158, 58, 101, 202, 223, 251, 105, 159, 214, 117, 240, 96, 236, 107, 160, 185, 89, 119, 62, 253, 200, 93, 3, + 94, 115, 225, 104, 114, 30, 185, 88, 244, 157, 9, 238, 21, 206, 76, 192, 53, 192, 189, 160, 62, 47, 47, + 239, 199, 77, 27, 55, 234, 88, 15, 116, 231, 210, 175, 188, 106, 128, 215, 3, 57, 23, 242, 76, 112, 150, + 136, 62, 19, 200, 115, 2, 57, 19, 188, 150, 154, 154, 186, 103, 209, 194, 133, 177, 94, 15, 116, 231, 209, + 207, 212, 112, 207, 133, 234, 89, 209, 88, 113, 248, 76, 192, 231, 4, 21, 194, 94, 15, 158, 22, 118, 47, + 152, 77, 62, 169, 168, 168, 136, 229, 122, 160, 59, 135, 38, 144, 161, 158, 23, 122, 205, 4, 238, 115, 130, + 50, 50, 133, 60, 68, 102, 114, 13, 68, 234, 224, 221, 188, 220, 220, 239, 215, 174, 89, 19, 139, 245, 64, + 119, 238, 76, 161, 214, 128, 58, 23, 202, 153, 192, 125, 78, 112, 21, 25, 47, 236, 187, 3, 247, 30, 145, + 107, 96, 110, 82, 82, 210, 238, 121, 181, 181, 86, 87, 103, 231, 177, 60, 47, 210, 157, 55, 35, 68, 194, + 93, 3, 234, 76, 224, 62, 39, 24, 39, 156, 187, 131, 137, 194, 57, 55, 230, 61, 34, 175, 7, 85, 145, 253, + 193, 71, 165, 165, 165, 127, 124, 185, 123, 119, 120, 46, 192, 247, 143, 79, 74, 8, 37, 188, 102, 2, 62, + 39, 224, 187, 131, 177, 162, 239, 30, 209, 189, 30, 240, 254, 160, 74, 216, 189, 96, 97, 118, 118, 118, + 231, 123, 203, 151, 135, 215, 131, 182, 80, 8, 223, 63, 206, 184, 66, 173, 1, 247, 76, 192, 235, 1, 207, 4, + 234, 30, 209, 189, 30, 240, 93, 50, 175, 7, 242, 30, 145, 123, 193, 75, 193, 96, 112, 115, 101, 101, 229, + 63, 124, 127, 52, 132, 247, 201, 218, 115, 103, 130, 40, 161, 214, 128, 215, 221, 129, 186, 71, 84, 215, 3, + 245, 30, 81, 238, 15, 170, 233, 247, 184, 14, 150, 22, 20, 20, 252, 176, 97, 253, 250, 161, 186, 75, 212, + 158, 59, 19, 28, 33, 220, 53, 224, 181, 71, 116, 175, 7, 234, 254, 64, 222, 33, 241, 187, 18, 222, 31, 112, + 13, 212, 36, 39, 39, 239, 170, 169, 169, 9, 223, 37, 118, 180, 183, 227, 251, 199, 239, 247, 247, 90, 15, + 188, 206, 141, 163, 173, 7, 124, 94, 36, 223, 149, 200, 55, 5, 213, 145, 217, 240, 253, 226, 226, 226, 95, + 182, 111, 219, 22, 126, 91, 50, 200, 125, 162, 246, 220, 153, 160, 159, 225, 174, 1, 175, 187, 100, 117, + 61, 144, 231, 69, 183, 146, 59, 132, 243, 166, 128, 207, 10, 170, 34, 235, 193, 252, 140, 140, 140, 189, + 111, 46, 90, 20, 190, 79, 30, 196, 62, 81, 123, 238, 76, 48, 128, 112, 215, 64, 180, 253, 193, 24, 97, 175, + 7, 124, 94, 116, 141, 232, 123, 127, 160, 158, 21, 112, 47, 152, 67, 86, 78, 46, 45, 253, 237, 139, 198, + 198, 129, 246, 2, 237, 185, 51, 193, 0, 67, 173, 1, 175, 253, 129, 122, 135, 196, 231, 69, 121, 228, 10, + 97, 223, 31, 168, 103, 5, 242, 46, 177, 90, 216, 253, 96, 65, 102, 102, 102, 75, 125, 125, 253, 64, 122, + 129, 246, 220, 153, 96, 144, 161, 214, 129, 123, 61, 224, 243, 34, 158, 13, 249, 188, 72, 190, 53, 229, + 119, 134, 234, 89, 1, 207, 134, 252, 230, 152, 123, 1, 207, 134, 220, 11, 94, 32, 31, 151, 151, 151, 255, + 190, 107, 231, 206, 254, 244, 2, 237, 185, 51, 193, 81, 132, 187, 6, 228, 122, 192, 189, 64, 174, 7, 242, + 254, 64, 157, 13, 139, 132, 253, 230, 88, 125, 91, 162, 238, 19, 223, 160, 94, 176, 255, 237, 197, 139, + 195, 247, 72, 71, 232, 5, 218, 115, 103, 130, 163, 12, 161, 132, 186, 63, 80, 223, 20, 120, 205, 134, 252, + 230, 152, 223, 150, 200, 115, 195, 25, 194, 217, 39, 202, 94, 176, 178, 180, 164, 228, 215, 207, 119, 236, + 136, 214, 11, 180, 231, 206, 4, 67, 20, 238, 26, 144, 247, 7, 242, 157, 161, 58, 27, 242, 93, 162, 124, 91, + 50, 94, 56, 251, 196, 7, 132, 189, 79, 228, 94, 48, 43, 82, 7, 117, 233, 233, 233, 95, 215, 213, 213, 133, + 207, 10, 248, 204, 0, 223, 63, 46, 191, 191, 90, 3, 178, 14, 220, 247, 201, 234, 93, 98, 142, 112, 206, 13, + 229, 62, 145, 223, 153, 185, 123, 1, 159, 21, 240, 30, 97, 121, 97, 97, 225, 207, 13, 13, 13, 234, 61, 130, + 246, 220, 153, 96, 136, 195, 93, 3, 209, 102, 67, 126, 91, 50, 70, 244, 221, 39, 142, 23, 206, 27, 35, 238, + 5, 234, 92, 192, 106, 83, 82, 82, 118, 204, 153, 61, 251, 95, 94, 11, 104, 159, 160, 61, 119, 38, 56, 70, + 161, 214, 64, 180, 183, 37, 188, 79, 148, 189, 128, 223, 153, 29, 169, 23, 240, 121, 1, 247, 2, 182, 36, + 63, 63, 191, 123, 197, 138, 21, 218, 115, 103, 130, 99, 24, 66, 137, 254, 244, 2, 249, 198, 200, 61, 23, + 200, 61, 130, 60, 47, 224, 94, 240, 114, 48, 24, 212, 158, 59, 19, 196, 32, 220, 53, 224, 53, 23, 68, 235, + 5, 114, 143, 160, 158, 23, 240, 189, 242, 172, 200, 15, 67, 252, 127, 127, 181, 6, 100, 29, 200, 26, 144, + 251, 196, 104, 115, 1, 247, 130, 34, 225, 156, 23, 200, 119, 167, 51, 117, 231, 205, 20, 49, 14, 181, 6, + 188, 238, 16, 220, 115, 129, 251, 188, 96, 178, 112, 222, 152, 104, 207, 157, 9, 52, 132, 80, 194, 221, 11, + 212, 185, 192, 125, 94, 192, 103, 135, 234, 61, 130, 246, 220, 153, 64, 99, 168, 53, 160, 206, 5, 220, 11, + 212, 243, 2, 121, 118, 40, 239, 17, 248, 141, 73, 177, 238, 188, 153, 66, 115, 8, 37, 162, 237, 17, 228, + 217, 161, 188, 71, 144, 119, 138, 218, 115, 103, 130, 56, 9, 181, 6, 188, 206, 11, 228, 27, 19, 121, 167, + 120, 161, 238, 188, 153, 34, 142, 66, 40, 225, 238, 5, 234, 27, 19, 190, 83, 28, 173, 59, 111, 166, 136, + 195, 80, 107, 192, 107, 175, 40, 223, 31, 107, 207, 157, 9, 226, 53, 132, 19, 94, 123, 197, 20, 221, 121, + 51, 69, 156, 135, 82, 6, 135, 189, 47, 208, 158, 59, 19, 248, 33, 60, 106, 32, 168, 59, 111, 166, 240, 81, + 40, 101, 16, 174, 3, 237, 185, 51, 129, 15, 67, 214, 128, 246, 220, 153, 192, 207, 161, 59, 119, 38, 240, + 115, 232, 206, 157, 9, 252, 28, 186, 115, 103, 2, 63, 135, 238, 220, 153, 192, 207, 161, 59, 119, 38, 240, + 115, 232, 206, 157, 9, 252, 28, 186, 115, 103, 2, 63, 135, 238, 220, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, + 208, 67, 28, 223, 145, 149, 149, 5, 199, 177, 67, 135, 14, 193, 113, 204, 178, 44, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 252, 7, 226, 175, 242, 23, 9, 254, 53, 10, 0, 0, 4, + 121, 109, 107, 66, 84, 250, 206, 202, 254, 0, 127, 162, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 154, 137, 109, 235, 48, 16, 5, 93, 72, 26, + 73, 33, 41, 36, 141, 164, 144, 20, 146, 70, 82, 136, 63, 54, 248, 99, 60, 108, 72, 217, 177, 100, 248, 154, + 7, 12, 116, 144, 226, 177, 203, 67, 34, 181, 223, 43, 165, 148, 82, 74, 41, 165, 148, 82, 74, 253, 215, + 247, 247, 247, 254, 235, 235, 107, 74, 133, 223, 131, 178, 30, 151, 76, 251, 18, 233, 95, 83, 85, 159, 221, + 110, 55, 229, 243, 243, 115, 255, 250, 250, 250, 115, 126, 203, 117, 167, 30, 85, 214, 45, 85, 190, 127, + 121, 121, 57, 216, 99, 235, 244, 175, 173, 244, 255, 251, 251, 251, 47, 74, 117, 172, 122, 63, 163, 255, + 105, 251, 207, 224, 255, 153, 62, 62, 62, 126, 218, 0, 115, 1, 109, 163, 174, 43, 140, 118, 193, 117, 133, + 213, 145, 248, 21, 206, 189, 89, 154, 117, 204, 56, 179, 180, 250, 179, 117, 78, 25, 210, 63, 164, 87, 80, + 62, 202, 49, 74, 115, 164, 138, 87, 105, 86, 255, 231, 252, 145, 253, 95, 117, 75, 240, 69, 31, 255, 137, + 207, 184, 136, 47, 114, 156, 204, 249, 163, 194, 136, 95, 226, 154, 103, 75, 149, 87, 93, 215, 177, 158, + 153, 205, 69, 89, 30, 242, 99, 108, 202, 243, 44, 91, 166, 159, 84, 156, 89, 27, 72, 187, 84, 190, 207, + 224, 255, 14, 182, 155, 249, 255, 237, 237, 237, 240, 142, 136, 125, 120, 166, 247, 199, 76, 35, 125, 65, + 155, 32, 188, 210, 226, 156, 246, 71, 252, 158, 86, 29, 203, 55, 188, 151, 145, 94, 247, 125, 62, 147, 105, + 210, 158, 186, 178, 45, 231, 28, 248, 232, 254, 159, 105, 230, 255, 236, 59, 125, 158, 76, 74, 248, 176, + 236, 88, 237, 38, 199, 84, 202, 80, 247, 51, 253, 84, 222, 35, 175, 244, 223, 168, 29, 103, 255, 174, 240, + 74, 31, 31, 214, 249, 108, 14, 32, 30, 101, 228, 253, 39, 239, 61, 138, 214, 248, 63, 133, 205, 152, 111, + 233, 231, 249, 110, 128, 237, 177, 97, 246, 235, 236, 155, 244, 189, 124, 55, 24, 141, 21, 249, 62, 154, + 253, 63, 199, 144, 244, 85, 150, 37, 203, 59, 171, 239, 18, 143, 162, 173, 252, 143, 47, 241, 109, 246, + 181, 158, 78, 127, 47, 232, 227, 73, 142, 181, 217, 247, 102, 243, 81, 214, 131, 252, 122, 123, 200, 241, + 60, 211, 100, 204, 233, 54, 233, 100, 153, 110, 249, 59, 232, 175, 218, 202, 255, 165, 178, 81, 190, 3, + 150, 109, 251, 123, 123, 247, 53, 237, 36, 253, 192, 251, 4, 105, 209, 166, 120, 230, 20, 255, 103, 60, + 198, 36, 242, 34, 205, 94, 190, 37, 61, 234, 252, 175, 148, 82, 74, 41, 165, 158, 83, 151, 218, 231, 205, + 116, 239, 101, 47, 249, 214, 148, 235, 32, 151, 176, 97, 125, 27, 205, 190, 107, 250, 247, 212, 95, 181, + 246, 121, 181, 63, 172, 57, 212, 154, 201, 108, 205, 122, 141, 210, 255, 125, 109, 35, 191, 243, 71, 223, + 252, 75, 107, 33, 172, 155, 244, 243, 107, 40, 203, 57, 234, 71, 252, 227, 49, 187, 191, 148, 222, 232, + 122, 150, 215, 44, 173, 81, 191, 38, 238, 108, 205, 105, 86, 230, 191, 138, 253, 178, 220, 251, 35, 95, + 214, 60, 242, 156, 246, 194, 51, 185, 206, 158, 109, 36, 247, 94, 57, 103, 13, 151, 123, 57, 38, 176, 119, + 179, 38, 188, 219, 58, 203, 153, 235, 137, 117, 143, 245, 102, 214, 154, 250, 186, 82, 133, 247, 58, 214, + 189, 76, 43, 109, 87, 199, 244, 25, 144, 87, 94, 163, 30, 167, 196, 122, 37, 247, 73, 151, 189, 238, 165, + 50, 159, 163, 238, 151, 108, 111, 163, 254, 207, 90, 27, 182, 102, 63, 190, 107, 52, 246, 87, 188, 220, + 199, 45, 232, 35, 172, 243, 173, 9, 63, 86, 47, 236, 151, 99, 94, 255, 183, 33, 247, 33, 16, 123, 25, 117, + 204, 181, 202, 180, 85, 166, 217, 243, 26, 217, 183, 255, 19, 65, 156, 209, 253, 145, 255, 71, 101, 62, 71, + 125, 254, 63, 197, 255, 25, 127, 246, 254, 144, 118, 226, 156, 189, 25, 142, 248, 51, 255, 201, 88, 19, + 126, 106, 189, 250, 156, 151, 123, 2, 248, 122, 84, 167, 244, 65, 183, 79, 94, 207, 242, 202, 176, 209, 62, + 19, 247, 179, 63, 115, 157, 121, 143, 202, 124, 174, 182, 240, 127, 223, 71, 41, 159, 80, 166, 60, 47, 49, + 214, 49, 126, 50, 150, 209, 158, 215, 134, 159, 82, 47, 194, 24, 55, 248, 143, 0, 27, 211, 190, 16, 115, + 109, 247, 127, 31, 115, 114, 143, 242, 152, 255, 249, 127, 34, 243, 40, 245, 251, 221, 255, 179, 50, 159, + 171, 99, 254, 207, 185, 29, 59, 244, 126, 146, 117, 45, 245, 241, 41, 125, 131, 191, 136, 203, 60, 182, 85, + 248, 49, 187, 103, 24, 182, 228, 253, 58, 231, 97, 198, 112, 226, 98, 231, 180, 53, 123, 157, 248, 51, 247, + 40, 143, 149, 131, 127, 107, 241, 33, 109, 39, 109, 202, 158, 217, 200, 255, 163, 50, 159, 243, 46, 200, + 126, 91, 214, 41, 125, 71, 223, 206, 186, 98, 143, 209, 88, 69, 220, 76, 175, 231, 215, 253, 217, 251, 193, + 154, 112, 194, 150, 234, 149, 97, 212, 131, 185, 164, 251, 55, 231, 242, 209, 55, 24, 207, 247, 231, 70, + 121, 245, 48, 218, 64, 223, 139, 76, 27, 19, 63, 243, 158, 149, 185, 247, 181, 75, 104, 105, 189, 64, 61, + 190, 244, 191, 82, 74, 41, 165, 148, 82, 74, 41, 165, 148, 82, 74, 93, 77, 59, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 145, 59, 228, 31, 135, + 151, 142, 106, 217, 59, 142, 156, 0, 0, 1, 83, 109, 107, 66, 84, 250, 206, 202, 254, 0, 127, 165, 133, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, + 214, 225, 105, 131, 96, 20, 134, 81, 7, 113, 17, 7, 113, 16, 23, 113, 16, 7, 113, 17, 7, 177, 188, 129, 11, + 183, 166, 33, 255, 138, 9, 231, 129, 67, 155, 79, 251, 235, 77, 108, 206, 83, 146, 36, 73, 146, 36, 73, + 146, 36, 73, 146, 36, 73, 146, 36, 73, 146, 36, 73, 31, 209, 113, 28, 231, 190, 239, 79, 231, 57, 203, 181, + 119, 247, 191, 186, 79, 247, 111, 93, 215, 115, 28, 199, 115, 154, 166, 199, 207, 236, 24, 253, 44, 247, + 212, 189, 117, 22, 203, 178, 60, 94, 199, 48, 12, 127, 190, 135, 116, 239, 178, 99, 149, 125, 179, 97, 118, + 173, 205, 251, 61, 181, 127, 213, 55, 191, 254, 141, 238, 95, 182, 235, 123, 86, 57, 235, 159, 229, 122, + 157, 125, 251, 198, 217, 191, 186, 94, 211, 253, 203, 115, 190, 239, 95, 255, 215, 231, 121, 126, 218, 63, + 215, 236, 255, 125, 101, 219, 122, 238, 215, 239, 219, 182, 253, 250, 204, 247, 231, 191, 253, 191, 175, + 250, 30, 215, 247, 171, 247, 64, 174, 213, 119, 251, 156, 69, 213, 159, 29, 215, 107, 146, 36, 73, 146, 36, + 73, 146, 36, 73, 250, 247, 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, 248, 64, 63, 10, 249, 172, 184, 82, 218, 42, 102, 0, 0, 34, + 191, 109, 107, 66, 84, 250, 206, 202, 254, 0, 127, 171, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 93, 119, 116, 85, 85, 246, 190, 32, 118, 68, + 176, 97, 25, 203, 82, 89, 203, 138, 5, 103, 141, 203, 209, 177, 252, 4, 29, 17, 69, 1, 145, 177, 49, 136, + 40, 210, 12, 93, 165, 9, 72, 47, 9, 129, 64, 66, 79, 66, 49, 16, 72, 64, 66, 104, 10, 50, 72, 17, 136, 64, + 2, 164, 146, 132, 222, 155, 58, 206, 56, 51, 251, 183, 191, 243, 206, 206, 59, 185, 222, 151, 198, 187, + 121, 239, 101, 229, 143, 111, 69, 16, 238, 219, 119, 239, 125, 190, 253, 237, 125, 206, 121, 208, 4, 203, + 162, 80, 64, 132, 198, 56, 198, 104, 198, 48, 198, 32, 70, 47, 198, 143, 201, 201, 244, 235, 127, 255, 75, + 231, 206, 157, 171, 70, 57, 49, 145, 253, 23, 10, 136, 212, 8, 103, 140, 97, 12, 103, 12, 96, 12, 173, 95, + 159, 142, 22, 20, 208, 249, 95, 126, 161, 179, 103, 207, 86, 163, 156, 8, 116, 92, 203, 19, 127, 240, 192, + 120, 99, 253, 127, 202, 152, 245, 234, 171, 244, 203, 127, 254, 67, 103, 57, 151, 3, 237, 203, 80, 68, 160, + 227, 90, 222, 248, 131, 255, 71, 49, 190, 100, 244, 97, 108, 136, 142, 166, 95, 255, 247, 63, 58, 123, 230, + 76, 53, 42, 128, 64, 199, 181, 60, 220, 47, 245, 127, 36, 227, 11, 198, 144, 107, 174, 161, 67, 217, 217, + 244, 211, 207, 63, 7, 220, 143, 161, 138, 64, 199, 182, 60, 107, 31, 181, 127, 172, 229, 169, 253, 159, 51, + 226, 90, 181, 82, 220, 127, 134, 223, 163, 26, 21, 195, 36, 246, 99, 48, 195, 204, 1, 209, 126, 168, 253, + 253, 24, 105, 11, 22, 208, 47, 191, 253, 70, 103, 78, 159, 174, 70, 5, 17, 232, 248, 150, 53, 254, 166, + 246, 3, 247, 71, 220, 119, 31, 157, 58, 113, 66, 233, 190, 64, 251, 48, 148, 17, 232, 248, 150, 37, 254, + 82, 251, 193, 253, 168, 253, 224, 254, 213, 67, 134, 208, 47, 172, 251, 78, 243, 59, 84, 163, 226, 8, 116, + 124, 203, 203, 253, 67, 25, 35, 174, 191, 158, 14, 229, 228, 208, 185, 159, 126, 10, 184, 255, 66, 29, 129, + 142, 113, 89, 185, 95, 250, 190, 254, 140, 37, 93, 187, 42, 221, 119, 250, 212, 169, 106, 92, 32, 162, 216, + 159, 193, 8, 51, 7, 164, 239, 131, 238, 31, 81, 167, 14, 21, 236, 220, 73, 103, 185, 231, 59, 197, 246, 87, + 227, 194, 16, 232, 56, 151, 22, 127, 147, 251, 7, 98, 237, 119, 238, 76, 63, 243, 218, 15, 180, 223, 170, + 10, 2, 29, 231, 210, 214, 190, 232, 126, 172, 253, 209, 215, 94, 75, 251, 119, 239, 166, 179, 92, 247, 79, + 157, 60, 89, 13, 63, 32, 208, 177, 46, 235, 218, 199, 94, 223, 202, 1, 3, 232, 39, 94, 251, 39, 217, 238, + 106, 248, 7, 147, 217, 175, 193, 4, 51, 7, 204, 181, 31, 121, 247, 221, 116, 244, 192, 1, 58, 125, 246, + 108, 192, 125, 86, 149, 16, 232, 120, 251, 138, 191, 112, 63, 122, 254, 33, 140, 45, 211, 167, 211, 249, + 127, 255, 155, 78, 158, 56, 81, 13, 63, 66, 252, 29, 232, 184, 59, 173, 125, 112, 63, 246, 249, 226, 95, + 124, 145, 206, 160, 230, 179, 94, 9, 180, 191, 170, 26, 204, 186, 27, 12, 177, 151, 181, 143, 158, 15, 179, + 222, 209, 220, 239, 229, 110, 217, 66, 103, 184, 223, 59, 193, 246, 86, 195, 191, 176, 107, 175, 64, 199, + 223, 172, 251, 152, 245, 125, 51, 100, 136, 226, 253, 19, 199, 143, 87, 195, 5, 76, 114, 136, 251, 148, 74, + 132, 61, 7, 100, 214, 15, 205, 55, 251, 47, 127, 161, 147, 224, 124, 70, 160, 253, 84, 85, 17, 225, 99, + 237, 7, 34, 254, 178, 246, 209, 239, 141, 171, 91, 151, 114, 55, 111, 166, 211, 204, 251, 199, 217, 206, + 96, 70, 17, 159, 178, 158, 86, 224, 255, 62, 14, 4, 129, 109, 165, 33, 242, 178, 203, 84, 14, 4, 138, 7, + 236, 107, 63, 92, 175, 253, 239, 35, 34, 232, 220, 191, 254, 69, 199, 143, 29, 11, 74, 160, 119, 58, 255, + 207, 127, 210, 207, 108, 227, 121, 204, 162, 207, 156, 41, 202, 129, 211, 252, 223, 56, 143, 250, 243, 175, + 191, 210, 79, 252, 103, 176, 79, 117, 234, 244, 105, 143, 207, 131, 192, 118, 19, 219, 102, 204, 160, 136, + 139, 46, 82, 57, 48, 177, 146, 115, 192, 140, 189, 244, 123, 136, 253, 162, 54, 109, 232, 52, 251, 236, 68, + 16, 250, 75, 98, 159, 155, 145, 65, 73, 81, 81, 52, 177, 75, 23, 234, 223, 172, 25, 245, 120, 234, 41, 250, + 248, 225, 135, 169, 243, 99, 143, 81, 207, 167, 159, 166, 65, 205, 155, 83, 100, 167, 78, 180, 136, 243, + 120, 211, 242, 229, 84, 144, 147, 163, 230, 150, 200, 9, 156, 89, 80, 28, 17, 4, 239, 114, 238, 63, 255, + 161, 101, 29, 58, 168, 189, 181, 9, 14, 60, 80, 153, 177, 135, 13, 83, 31, 124, 144, 14, 23, 22, 210, 73, + 94, 67, 199, 216, 190, 96, 4, 214, 250, 238, 173, 91, 233, 131, 134, 13, 233, 143, 108, 243, 51, 140, 231, + 25, 141, 25, 77, 244, 207, 255, 99, 60, 167, 241, 34, 163, 205, 245, 215, 83, 223, 231, 159, 167, 56, 214, + 179, 105, 235, 215, 211, 9, 214, 52, 63, 49, 119, 224, 89, 199, 3, 249, 46, 231, 207, 83, 214, 218, 181, + 52, 158, 57, 32, 220, 224, 0, 51, 86, 209, 126, 134, 249, 108, 137, 63, 246, 247, 194, 185, 215, 203, 250, + 238, 59, 85, 243, 3, 29, 227, 210, 128, 57, 228, 177, 163, 71, 105, 124, 187, 118, 244, 2, 219, 222, 140, + 241, 26, 227, 117, 27, 240, 123, 175, 50, 154, 234, 220, 64, 94, 52, 171, 85, 139, 186, 54, 106, 68, 241, + 67, 135, 82, 230, 142, 29, 158, 187, 11, 204, 13, 168, 15, 1, 201, 1, 230, 163, 132, 151, 94, 82, 186, 107, + 146, 94, 151, 136, 83, 140, 198, 84, 63, 34, 198, 64, 180, 254, 44, 212, 125, 204, 249, 126, 152, 58, 149, + 206, 48, 63, 194, 175, 161, 0, 244, 37, 136, 93, 194, 176, 97, 212, 130, 215, 79, 11, 126, 135, 55, 177, + 214, 13, 224, 215, 173, 25, 111, 48, 90, 49, 240, 103, 154, 51, 254, 170, 57, 163, 101, 237, 218, 52, 188, + 117, 107, 85, 35, 206, 112, 78, 65, 43, 40, 62, 168, 164, 119, 56, 202, 56, 197, 159, 185, 51, 57, 89, 241, + 175, 104, 193, 41, 182, 88, 185, 21, 123, 172, 125, 204, 121, 86, 247, 233, 67, 167, 89, 43, 29, 229, 119, + 63, 170, 237, 10, 5, 28, 227, 53, 123, 158, 121, 124, 245, 204, 153, 244, 238, 229, 151, 211, 223, 248, 93, + 218, 26, 120, 79, 227, 29, 198, 91, 58, 39, 36, 31, 90, 104, 110, 0, 47, 52, 173, 89, 147, 250, 62, 243, + 12, 173, 75, 76, 164, 83, 156, 7, 152, 119, 86, 218, 59, 176, 207, 79, 112, 29, 154, 211, 184, 177, 202, + 129, 72, 205, 203, 254, 228, 0, 123, 236, 167, 232, 60, 3, 231, 44, 126, 227, 13, 58, 193, 28, 116, 140, + 53, 81, 160, 227, 89, 81, 156, 103, 222, 218, 144, 144, 64, 31, 95, 117, 21, 189, 207, 239, 244, 145, 129, + 15, 25, 31, 48, 240, 251, 127, 215, 249, 240, 54, 227, 111, 58, 23, 192, 11, 168, 19, 47, 106, 94, 232, + 251, 236, 179, 180, 49, 53, 213, 115, 198, 133, 227, 226, 170, 237, 71, 142, 40, 64, 7, 164, 167, 164, 208, + 40, 206, 195, 112, 203, 91, 7, 220, 136, 191, 212, 125, 112, 254, 220, 39, 159, 164, 163, 135, 15, 211, + 113, 214, 212, 98, 75, 168, 226, 28, 231, 192, 15, 73, 73, 20, 198, 156, 222, 153, 223, 45, 76, 227, 19, + 70, 55, 70, 23, 198, 199, 58, 39, 144, 15, 237, 140, 92, 104, 99, 112, 2, 242, 224, 101, 174, 39, 195, 121, + 93, 236, 217, 190, 93, 245, 153, 208, 6, 110, 216, 124, 68, 192, 185, 112, 146, 57, 39, 145, 123, 175, 145, + 154, 151, 37, 254, 18, 195, 105, 21, 132, 153, 7, 194, 251, 152, 239, 206, 188, 247, 94, 218, 159, 149, 69, + 199, 57, 199, 143, 152, 182, 132, 48, 206, 112, 172, 54, 206, 153, 67, 125, 46, 189, 148, 122, 91, 158, 59, + 138, 64, 95, 6, 126, 221, 147, 209, 157, 209, 149, 209, 73, 231, 66, 123, 205, 11, 239, 24, 156, 0, 237, 8, + 93, 217, 250, 234, 171, 41, 118, 224, 64, 207, 179, 121, 141, 186, 105, 251, 241, 211, 167, 41, 47, 45, + 141, 34, 174, 189, 86, 233, 113, 83, 7, 84, 52, 7, 236, 28, 128, 231, 65, 99, 196, 220, 118, 27, 229, 109, + 219, 166, 120, 63, 208, 49, 243, 123, 14, 48, 15, 124, 55, 121, 178, 58, 167, 142, 59, 202, 131, 52, 112, + 126, 13, 231, 87, 63, 211, 249, 208, 83, 243, 3, 120, 161, 163, 193, 9, 146, 7, 224, 131, 230, 58, 15, 186, + 62, 252, 176, 210, 136, 231, 192, 5, 92, 39, 253, 102, 47, 115, 175, 137, 83, 92, 115, 214, 141, 28, 73, + 35, 44, 143, 14, 144, 94, 160, 34, 241, 119, 138, 61, 250, 252, 41, 220, 11, 103, 173, 91, 167, 248, 198, + 254, 249, 85, 2, 236, 87, 104, 217, 149, 131, 6, 169, 248, 99, 15, 123, 152, 6, 246, 180, 6, 235, 124, 144, + 92, 232, 109, 112, 2, 234, 67, 7, 27, 31, 32, 15, 208, 63, 190, 122, 241, 197, 20, 19, 22, 70, 135, 15, 29, + 162, 211, 88, 55, 46, 216, 174, 244, 32, 215, 226, 185, 47, 188, 160, 180, 96, 69, 57, 192, 87, 236, 163, + 152, 207, 246, 172, 88, 81, 117, 99, 111, 248, 241, 36, 243, 245, 226, 118, 237, 84, 188, 225, 203, 209, + 26, 168, 175, 195, 117, 94, 12, 214, 188, 0, 174, 232, 195, 232, 161, 243, 64, 248, 0, 61, 132, 232, 3, + 169, 9, 221, 30, 121, 132, 182, 175, 93, 171, 122, 132, 11, 181, 243, 176, 3, 142, 113, 29, 216, 183, 115, + 39, 69, 221, 114, 139, 170, 3, 210, 11, 152, 49, 45, 111, 236, 193, 37, 147, 234, 212, 161, 157, 139, 23, + 211, 9, 230, 24, 167, 207, 173, 106, 56, 202, 154, 13, 186, 42, 246, 233, 167, 85, 188, 225, 203, 241, 26, + 208, 190, 99, 116, 94, 224, 255, 13, 177, 229, 129, 240, 1, 242, 0, 250, 0, 58, 17, 253, 99, 107, 205, 5, + 45, 174, 184, 130, 86, 198, 197, 209, 153, 95, 126, 185, 48, 59, 153, 75, 156, 112, 130, 115, 23, 177, 138, + 96, 29, 19, 105, 196, 127, 186, 129, 25, 14, 48, 255, 255, 52, 29, 127, 165, 37, 185, 47, 218, 181, 104, + 145, 39, 246, 62, 62, 179, 42, 226, 248, 169, 83, 148, 159, 158, 78, 209, 172, 119, 198, 233, 117, 96, 222, + 105, 150, 187, 13, 200, 133, 17, 154, 19, 112, 191, 17, 247, 91, 251, 106, 62, 128, 62, 128, 78, 68, 255, + 248, 174, 174, 9, 208, 5, 173, 184, 207, 216, 184, 108, 25, 157, 230, 88, 185, 97, 59, 98, 181, 41, 42, + 138, 194, 185, 39, 156, 164, 99, 57, 173, 132, 28, 240, 21, 251, 41, 188, 238, 17, 251, 147, 33, 18, 123, + 53, 147, 103, 141, 229, 55, 63, 98, 45, 241, 251, 71, 212, 170, 229, 169, 129, 150, 243, 254, 199, 120, + 157, 7, 35, 117, 30, 12, 210, 124, 0, 125, 128, 30, 178, 147, 81, 19, 192, 5, 152, 25, 252, 157, 57, 26, + 123, 17, 216, 47, 169, 136, 109, 135, 74, 2, 243, 3, 114, 96, 227, 132, 9, 52, 129, 251, 81, 95, 57, 96, + 135, 196, 30, 57, 30, 195, 90, 111, 119, 106, 42, 29, 231, 90, 85, 226, 103, 5, 3, 248, 125, 241, 51, 101, + 230, 76, 202, 224, 190, 27, 103, 206, 48, 147, 242, 199, 179, 79, 48, 79, 127, 203, 125, 156, 212, 83, 251, + 126, 152, 61, 15, 70, 107, 62, 64, 93, 128, 134, 252, 212, 242, 106, 3, 112, 129, 244, 9, 152, 31, 126, + 194, 122, 160, 32, 47, 207, 111, 182, 218, 125, 114, 156, 243, 55, 141, 123, 218, 169, 215, 93, 167, 236, + 139, 46, 33, 7, 166, 233, 255, 15, 94, 139, 227, 254, 62, 147, 117, 254, 113, 214, 170, 1, 143, 109, 25, + 129, 217, 107, 143, 231, 158, 163, 102, 151, 93, 70, 209, 189, 122, 81, 118, 70, 134, 103, 22, 203, 181, + 252, 66, 158, 123, 24, 189, 22, 199, 39, 161, 73, 19, 21, 95, 251, 30, 139, 232, 36, 153, 137, 219, 191, + 235, 236, 11, 205, 5, 189, 44, 207, 44, 169, 163, 81, 15, 94, 97, 12, 125, 229, 21, 21, 127, 232, 141, 114, + 217, 118, 240, 96, 153, 128, 24, 230, 114, 191, 158, 212, 180, 105, 209, 57, 61, 209, 4, 162, 249, 166, + 104, 219, 163, 217, 119, 43, 63, 250, 136, 14, 236, 219, 167, 180, 100, 89, 63, 35, 24, 128, 190, 42, 162, + 99, 71, 250, 11, 191, 199, 179, 140, 55, 57, 231, 99, 122, 246, 164, 156, 61, 123, 60, 122, 27, 254, 173, + 224, 179, 143, 114, 95, 133, 249, 74, 244, 77, 55, 121, 252, 100, 253, 94, 75, 219, 247, 70, 204, 123, 239, + 67, 53, 23, 64, 23, 132, 233, 122, 208, 94, 231, 0, 120, 96, 122, 247, 238, 74, 11, 148, 39, 174, 7, 203, + 1, 228, 239, 17, 214, 51, 187, 88, 23, 46, 107, 221, 154, 98, 89, 211, 76, 99, 125, 24, 195, 250, 96, 218, + 149, 87, 210, 220, 123, 238, 161, 213, 157, 58, 81, 230, 63, 254, 65, 199, 216, 143, 135, 217, 87, 229, + 121, 126, 48, 0, 123, 161, 137, 17, 17, 106, 79, 6, 235, 10, 90, 27, 251, 116, 111, 223, 120, 35, 205, 102, + 254, 206, 103, 158, 197, 172, 28, 235, 185, 34, 207, 63, 198, 127, 119, 115, 76, 140, 154, 177, 203, 124, + 213, 206, 165, 146, 7, 82, 23, 34, 117, 77, 144, 239, 189, 26, 164, 235, 1, 122, 132, 206, 90, 19, 160, 71, + 108, 201, 72, 153, 58, 85, 237, 231, 185, 229, 31, 228, 214, 17, 94, 211, 71, 153, 39, 247, 179, 47, 178, + 55, 110, 164, 61, 171, 87, 83, 46, 107, 144, 131, 7, 14, 168, 184, 35, 79, 2, 29, 199, 138, 2, 179, 143, + 205, 43, 87, 210, 235, 53, 106, 20, 219, 207, 199, 254, 62, 122, 239, 247, 111, 191, 157, 22, 142, 27, 167, + 252, 112, 146, 125, 128, 159, 229, 250, 12, 254, 243, 71, 89, 171, 37, 183, 105, 163, 98, 106, 239, 171, + 76, 45, 109, 206, 203, 193, 5, 230, 247, 223, 32, 7, 62, 211, 57, 32, 60, 128, 25, 193, 187, 117, 235, 82, + 218, 119, 223, 209, 9, 142, 81, 153, 236, 225, 152, 85, 20, 208, 6, 135, 209, 227, 66, 43, 31, 59, 230, + 241, 197, 5, 60, 47, 24, 128, 158, 184, 32, 55, 151, 58, 50, 183, 201, 126, 190, 236, 225, 183, 210, 60, + 139, 61, 186, 174, 13, 27, 210, 42, 214, 68, 216, 183, 2, 202, 245, 25, 236, 171, 125, 187, 119, 83, 204, + 173, 183, 22, 245, 214, 211, 44, 231, 126, 202, 228, 130, 73, 186, 30, 152, 57, 32, 60, 240, 177, 214, 3, + 152, 21, 118, 127, 232, 33, 42, 228, 218, 139, 90, 85, 154, 45, 7, 66, 28, 106, 61, 105, 190, 241, 215, 51, + 177, 15, 50, 186, 121, 115, 229, 203, 119, 53, 222, 177, 138, 239, 217, 54, 211, 181, 161, 95, 227, 198, + 244, 195, 154, 53, 116, 82, 215, 187, 178, 126, 198, 81, 254, 243, 155, 184, 14, 136, 22, 148, 58, 224, + 107, 166, 34, 92, 16, 229, 35, 7, 194, 116, 14, 180, 211, 124, 21, 254, 206, 59, 234, 61, 252, 233, 151, + 96, 3, 248, 103, 239, 206, 157, 180, 33, 37, 69, 241, 182, 226, 60, 206, 135, 11, 125, 238, 9, 230, 245, + 37, 99, 199, 170, 120, 163, 182, 118, 208, 63, 101, 159, 78, 102, 48, 50, 151, 111, 129, 25, 89, 135, 14, + 148, 205, 26, 17, 121, 80, 22, 27, 16, 151, 195, 108, 243, 66, 214, 237, 225, 6, 7, 32, 222, 51, 29, 48, + 195, 224, 2, 228, 128, 220, 141, 28, 174, 115, 0, 154, 16, 51, 130, 142, 218, 70, 104, 129, 228, 200, 72, + 101, 79, 137, 182, 236, 223, 31, 178, 64, 189, 65, 223, 251, 49, 247, 191, 97, 79, 60, 65, 171, 230, 206, + 85, 186, 12, 103, 89, 160, 109, 43, 250, 92, 240, 102, 250, 247, 223, 83, 23, 238, 99, 176, 166, 186, 104, + 116, 210, 254, 237, 160, 215, 153, 228, 65, 75, 93, 19, 218, 178, 174, 79, 100, 109, 128, 191, 143, 154, + 80, 218, 231, 160, 118, 102, 109, 222, 76, 81, 245, 234, 21, 205, 86, 164, 6, 148, 150, 3, 147, 45, 239, + 93, 9, 240, 0, 102, 199, 152, 27, 163, 55, 252, 80, 115, 85, 91, 126, 238, 14, 104, 113, 230, 199, 64, 199, + 202, 45, 96, 238, 181, 32, 60, 156, 254, 108, 121, 206, 81, 225, 92, 229, 215, 211, 166, 121, 102, 46, 252, + 255, 14, 86, 32, 15, 84, 141, 230, 60, 26, 253, 248, 227, 74, 95, 247, 212, 232, 97, 21, 223, 167, 147, 89, + 28, 106, 3, 180, 215, 107, 154, 15, 62, 125, 242, 73, 218, 178, 106, 149, 71, 31, 50, 71, 149, 244, 89, + 168, 3, 223, 14, 30, 172, 122, 253, 41, 154, 231, 125, 197, 223, 204, 1, 179, 22, 96, 70, 128, 190, 0, 251, + 137, 189, 116, 174, 118, 208, 252, 212, 143, 109, 81, 239, 228, 195, 15, 251, 67, 28, 224, 218, 125, 172, + 215, 218, 221, 121, 167, 58, 55, 243, 130, 70, 151, 135, 31, 166, 101, 211, 167, 171, 154, 140, 25, 60, + 184, 174, 60, 207, 61, 198, 177, 75, 30, 48, 64, 173, 39, 232, 236, 207, 53, 62, 179, 156, 247, 103, 100, + 159, 14, 90, 17, 218, 160, 21, 215, 132, 232, 110, 221, 168, 128, 117, 24, 234, 176, 175, 207, 57, 192, + 246, 227, 231, 236, 71, 31, 245, 156, 139, 40, 165, 14, 72, 14, 136, 30, 0, 111, 160, 126, 160, 55, 28, + 162, 109, 236, 161, 185, 10, 122, 16, 26, 118, 225, 232, 209, 106, 14, 227, 104, 67, 97, 97, 200, 3, 235, + 60, 118, 208, 32, 21, 255, 215, 52, 94, 210, 156, 220, 227, 79, 127, 162, 111, 18, 18, 148, 62, 192, 217, + 210, 178, 62, 19, 121, 179, 107, 237, 90, 234, 199, 113, 196, 186, 194, 252, 109, 176, 254, 41, 251, 116, + 152, 203, 67, 119, 117, 214, 156, 43, 243, 56, 204, 230, 209, 43, 188, 140, 28, 185, 231, 30, 90, 203, 159, + 175, 106, 18, 115, 129, 211, 103, 97, 166, 178, 237, 171, 175, 148, 22, 140, 50, 234, 128, 25, 243, 89, + 182, 248, 139, 38, 148, 153, 27, 248, 99, 132, 182, 15, 122, 80, 180, 0, 120, 41, 254, 243, 207, 61, 57, + 24, 4, 177, 114, 3, 240, 107, 214, 174, 93, 212, 238, 198, 27, 85, 190, 191, 161, 209, 82, 199, 224, 21, + 238, 229, 191, 104, 218, 148, 182, 114, 60, 75, 138, 131, 9, 197, 153, 252, 231, 162, 184, 6, 96, 230, 54, + 92, 251, 87, 246, 238, 49, 139, 51, 247, 103, 204, 60, 16, 109, 128, 60, 128, 22, 111, 85, 179, 38, 69, + 181, 111, 79, 249, 57, 57, 116, 140, 99, 253, 187, 207, 227, 207, 130, 22, 76, 124, 253, 245, 98, 90, 80, + 226, 14, 204, 214, 152, 101, 64, 106, 129, 153, 3, 195, 173, 226, 90, 0, 251, 198, 73, 35, 71, 122, 214, + 191, 143, 60, 87, 122, 149, 235, 3, 236, 40, 228, 223, 11, 69, 224, 12, 225, 116, 230, 91, 196, 92, 122, + 53, 57, 111, 141, 181, 136, 186, 220, 234, 138, 43, 40, 170, 115, 103, 202, 205, 204, 44, 226, 228, 146, + 158, 121, 132, 159, 153, 202, 188, 130, 56, 143, 182, 188, 251, 247, 178, 95, 43, 51, 89, 147, 15, 100, + 159, 78, 206, 240, 136, 70, 68, 30, 132, 53, 104, 64, 255, 88, 180, 136, 142, 241, 115, 225, 111, 243, 179, + 14, 50, 55, 237, 89, 191, 158, 38, 213, 174, 173, 56, 64, 226, 63, 219, 64, 172, 134, 153, 11, 51, 141, 28, + 144, 123, 20, 162, 5, 160, 89, 160, 81, 150, 69, 68, 208, 81, 206, 59, 167, 119, 220, 194, 189, 107, 198, + 182, 109, 180, 143, 115, 83, 230, 95, 168, 151, 248, 41, 243, 91, 228, 73, 97, 65, 65, 80, 3, 107, 58, 99, + 203, 22, 234, 88, 183, 174, 170, 197, 237, 52, 68, 159, 137, 78, 71, 93, 248, 224, 246, 219, 233, 235, 232, + 104, 58, 194, 250, 27, 239, 232, 235, 153, 7, 89, 3, 238, 222, 176, 129, 70, 94, 126, 185, 138, 127, 184, + 229, 253, 46, 122, 249, 126, 18, 249, 183, 72, 156, 246, 233, 228, 12, 143, 156, 249, 134, 54, 120, 167, + 86, 45, 138, 13, 11, 83, 122, 4, 115, 32, 243, 243, 14, 115, 78, 46, 239, 210, 69, 229, 152, 89, 3, 236, + 241, 183, 231, 128, 232, 1, 209, 131, 208, 2, 131, 181, 45, 208, 169, 203, 89, 31, 31, 225, 120, 58, 189, + 227, 235, 108, 79, 155, 171, 175, 166, 246, 119, 220, 65, 61, 152, 235, 190, 108, 209, 66, 237, 119, 36, + 71, 69, 209, 198, 21, 43, 40, 51, 61, 221, 179, 7, 40, 57, 1, 238, 196, 186, 9, 130, 152, 219, 1, 110, 157, + 254, 254, 251, 202, 223, 29, 53, 192, 199, 246, 243, 181, 208, 7, 208, 104, 95, 252, 245, 175, 180, 115, + 211, 38, 47, 23, 216, 159, 137, 218, 194, 49, 138, 109, 220, 88, 113, 191, 253, 126, 164, 249, 93, 21, 230, + 62, 93, 63, 205, 191, 82, 19, 228, 140, 175, 156, 247, 6, 39, 13, 97, 95, 239, 226, 30, 19, 188, 92, 168, + 215, 23, 180, 96, 14, 215, 177, 232, 155, 111, 86, 207, 150, 94, 192, 228, 127, 123, 252, 103, 235, 28, 65, + 174, 160, 110, 76, 212, 28, 48, 76, 115, 0, 122, 129, 175, 71, 141, 242, 25, 255, 150, 154, 155, 154, 107, + 159, 136, 110, 194, 207, 215, 184, 110, 189, 123, 195, 13, 212, 147, 109, 141, 248, 224, 3, 74, 158, 60, + 153, 210, 184, 159, 44, 132, 62, 102, 95, 99, 238, 171, 120, 140, 159, 83, 16, 4, 56, 200, 107, 121, 199, + 186, 117, 212, 157, 251, 246, 110, 150, 247, 236, 189, 156, 187, 151, 190, 93, 250, 53, 236, 239, 188, 205, + 124, 145, 48, 98, 4, 29, 226, 181, 126, 136, 255, 190, 253, 153, 135, 248, 61, 215, 79, 154, 84, 116, 30, + 214, 126, 22, 82, 250, 48, 217, 163, 177, 239, 215, 154, 218, 224, 35, 203, 59, 75, 66, 30, 132, 93, 115, + 13, 173, 137, 137, 81, 250, 111, 63, 243, 65, 65, 126, 62, 29, 226, 124, 64, 63, 40, 189, 128, 196, 31, 49, + 143, 211, 136, 215, 144, 95, 199, 234, 63, 51, 77, 231, 165, 201, 1, 248, 236, 36, 238, 99, 14, 243, 103, + 56, 249, 12, 117, 82, 106, 229, 223, 172, 226, 119, 214, 90, 89, 222, 189, 15, 201, 137, 55, 216, 183, 93, + 30, 124, 144, 194, 89, 207, 172, 136, 139, 163, 204, 140, 12, 53, 127, 197, 254, 56, 214, 16, 222, 33, 144, + 56, 204, 182, 204, 122, 235, 45, 245, 222, 125, 245, 58, 68, 12, 132, 147, 237, 125, 123, 43, 157, 251, + 131, 158, 123, 142, 118, 110, 220, 232, 169, 147, 240, 141, 126, 30, 226, 146, 195, 28, 56, 145, 181, 101, + 184, 142, 191, 57, 167, 181, 207, 102, 101, 46, 103, 106, 3, 240, 112, 79, 157, 139, 157, 181, 13, 194, 77, + 248, 239, 185, 29, 59, 210, 126, 244, 231, 204, 173, 88, 91, 251, 178, 179, 105, 38, 107, 133, 73, 250, + 249, 190, 226, 111, 207, 129, 153, 150, 247, 204, 149, 232, 0, 124, 238, 130, 238, 221, 85, 142, 57, 249, + 11, 188, 244, 190, 229, 189, 155, 36, 181, 74, 102, 222, 102, 94, 32, 39, 192, 23, 175, 234, 92, 64, 94, + 188, 87, 191, 62, 13, 227, 154, 177, 124, 214, 44, 202, 205, 202, 82, 188, 128, 181, 84, 96, 248, 176, 50, + 129, 154, 253, 227, 202, 149, 212, 239, 146, 75, 20, 255, 161, 38, 247, 183, 138, 159, 171, 52, 207, 211, + 201, 253, 27, 244, 13, 237, 121, 61, 46, 101, 173, 132, 185, 28, 184, 88, 158, 121, 136, 185, 51, 169, 93, + 59, 181, 182, 39, 91, 197, 121, 89, 52, 216, 116, 203, 59, 151, 51, 247, 234, 160, 13, 204, 154, 208, 67, + 231, 65, 87, 171, 248, 92, 113, 210, 179, 207, 82, 54, 115, 255, 33, 156, 51, 1, 231, 140, 25, 163, 114, + 41, 198, 242, 106, 0, 167, 248, 75, 14, 72, 252, 97, 27, 242, 70, 190, 55, 17, 185, 31, 215, 182, 173, 207, + 248, 139, 29, 102, 94, 154, 60, 37, 121, 209, 86, 231, 132, 169, 171, 209, 99, 201, 204, 11, 125, 86, 251, + 219, 110, 163, 73, 172, 175, 127, 224, 62, 11, 62, 132, 190, 65, 30, 228, 243, 231, 84, 38, 14, 49, 7, 196, + 181, 108, 169, 124, 62, 212, 242, 158, 185, 47, 169, 111, 151, 249, 13, 114, 61, 178, 85, 43, 117, 222, 3, + 177, 192, 243, 14, 112, 93, 216, 158, 156, 172, 214, 148, 204, 105, 237, 117, 217, 236, 199, 76, 46, 144, + 127, 175, 72, 184, 64, 206, 251, 203, 44, 177, 187, 145, 19, 163, 238, 186, 139, 118, 172, 90, 69, 135, + 185, 63, 192, 231, 198, 62, 240, 128, 122, 78, 89, 56, 192, 94, 3, 144, 127, 168, 89, 224, 192, 152, 102, + 205, 84, 127, 145, 239, 16, 11, 147, 35, 123, 25, 118, 73, 142, 74, 94, 72, 78, 136, 142, 17, 254, 52, 247, + 196, 144, 11, 168, 19, 45, 47, 189, 148, 6, 191, 252, 50, 173, 229, 94, 71, 234, 106, 254, 190, 125, 149, + 134, 3, 252, 153, 105, 169, 169, 244, 37, 107, 91, 172, 129, 81, 150, 183, 111, 55, 117, 122, 79, 171, 248, + 157, 11, 225, 66, 228, 121, 191, 187, 239, 166, 205, 28, 115, 244, 229, 5, 172, 207, 10, 152, 151, 103, + 253, 241, 143, 69, 253, 185, 89, 151, 77, 77, 102, 234, 113, 233, 203, 241, 119, 70, 235, 207, 71, 30, 202, + 189, 143, 62, 218, 231, 189, 45, 111, 173, 26, 198, 122, 100, 19, 215, 213, 99, 191, 253, 70, 27, 34, 35, + 149, 174, 192, 179, 202, 194, 1, 118, 13, 32, 255, 86, 198, 184, 70, 141, 84, 93, 193, 122, 183, 251, 106, + 136, 85, 124, 174, 5, 223, 244, 211, 127, 239, 83, 195, 70, 51, 39, 204, 125, 16, 115, 79, 76, 238, 41, + 200, 236, 171, 57, 235, 199, 254, 207, 63, 79, 27, 150, 45, 43, 210, 138, 149, 146, 3, 122, 205, 206, 121, + 229, 21, 165, 197, 198, 105, 140, 117, 136, 131, 57, 203, 149, 247, 146, 124, 128, 142, 252, 154, 181, 24, + 116, 229, 97, 204, 233, 71, 142, 84, 207, 64, 92, 205, 53, 233, 164, 197, 204, 154, 32, 250, 208, 252, 183, + 235, 190, 176, 188, 117, 73, 230, 203, 3, 52, 134, 113, 237, 250, 110, 194, 4, 58, 200, 62, 139, 111, 216, + 80, 197, 83, 242, 45, 206, 242, 205, 1, 179, 245, 159, 147, 187, 54, 163, 244, 243, 134, 222, 122, 171, + 226, 51, 244, 25, 118, 95, 141, 209, 62, 145, 53, 2, 206, 24, 166, 109, 28, 98, 228, 133, 216, 218, 215, + 242, 242, 132, 93, 91, 155, 125, 150, 220, 85, 128, 70, 104, 193, 235, 112, 204, 219, 111, 211, 238, 180, + 52, 213, 135, 56, 229, 161, 223, 57, 0, 156, 189, 116, 41, 141, 185, 232, 34, 85, 11, 205, 190, 221, 73, + 167, 75, 30, 200, 93, 93, 252, 12, 211, 191, 23, 203, 250, 6, 207, 204, 99, 125, 51, 133, 251, 33, 153, + 207, 152, 241, 247, 197, 199, 50, 159, 145, 89, 189, 156, 231, 131, 159, 205, 187, 96, 3, 181, 45, 67, 180, + 239, 17, 139, 245, 220, 183, 111, 153, 54, 173, 88, 13, 48, 227, 62, 199, 64, 188, 229, 213, 0, 209, 250, + 93, 229, 223, 74, 250, 156, 249, 24, 125, 209, 126, 214, 52, 118, 63, 217, 239, 34, 132, 91, 197, 239, 167, + 152, 247, 149, 156, 238, 174, 153, 154, 198, 126, 143, 81, 102, 160, 208, 9, 224, 131, 182, 172, 21, 23, + 113, 94, 163, 30, 40, 157, 155, 151, 231, 30, 248, 221, 246, 115, 29, 152, 207, 117, 72, 190, 215, 196, + 254, 29, 147, 162, 211, 229, 238, 141, 201, 201, 194, 203, 114, 119, 55, 138, 123, 158, 204, 109, 219, 40, + 181, 91, 55, 229, 39, 225, 100, 167, 248, 155, 57, 96, 246, 231, 162, 15, 205, 94, 81, 214, 155, 232, 148, + 47, 245, 239, 225, 255, 141, 103, 254, 252, 166, 127, 127, 154, 255, 208, 67, 234, 239, 58, 229, 155, 61, + 254, 51, 44, 239, 217, 251, 49, 58, 94, 168, 115, 107, 89, 159, 99, 77, 216, 253, 36, 231, 77, 229, 156, + 153, 204, 53, 228, 251, 215, 37, 47, 36, 39, 36, 31, 196, 102, 201, 133, 79, 45, 231, 123, 140, 102, 30, + 64, 99, 163, 231, 30, 193, 250, 42, 123, 239, 94, 165, 213, 221, 204, 129, 66, 238, 167, 210, 152, 3, 194, + 153, 3, 212, 61, 20, 219, 187, 154, 181, 121, 152, 246, 149, 212, 63, 225, 228, 254, 250, 29, 177, 142, 38, + 222, 114, 11, 173, 238, 219, 151, 162, 175, 184, 162, 152, 46, 119, 138, 133, 19, 23, 152, 186, 64, 184, + 64, 206, 120, 11, 247, 226, 231, 40, 237, 107, 117, 70, 180, 118, 109, 138, 103, 45, 98, 215, 0, 190, 226, + 47, 61, 224, 36, 253, 12, 196, 8, 235, 115, 65, 175, 94, 74, 23, 219, 125, 228, 116, 222, 204, 188, 187, + 39, 190, 146, 251, 9, 242, 253, 156, 114, 87, 197, 188, 191, 54, 200, 242, 222, 91, 66, 206, 129, 71, 101, + 22, 46, 121, 0, 125, 128, 154, 208, 229, 190, 251, 212, 126, 140, 58, 11, 231, 98, 14, 236, 231, 231, 47, + 228, 124, 27, 111, 121, 247, 215, 229, 29, 237, 58, 125, 148, 145, 7, 114, 103, 91, 56, 89, 116, 100, 36, + 199, 62, 26, 103, 158, 181, 207, 204, 120, 216, 249, 184, 52, 46, 48, 191, 239, 84, 244, 201, 88, 203, 187, + 207, 16, 105, 121, 239, 223, 154, 251, 1, 165, 197, 95, 122, 64, 153, 1, 128, 203, 34, 155, 52, 81, 186, + 216, 238, 31, 95, 51, 101, 169, 93, 246, 188, 144, 239, 110, 41, 233, 222, 146, 104, 43, 51, 15, 204, 123, + 205, 208, 137, 232, 21, 222, 187, 254, 122, 90, 151, 148, 164, 250, 172, 60, 182, 197, 13, 20, 48, 7, 252, + 184, 98, 5, 77, 96, 77, 101, 246, 238, 78, 123, 168, 82, 155, 17, 231, 17, 58, 230, 195, 44, 47, 31, 143, + 211, 239, 107, 62, 199, 87, 252, 203, 202, 5, 146, 131, 226, 75, 249, 119, 238, 37, 246, 114, 54, 208, 220, + 11, 240, 21, 127, 233, 1, 100, 47, 96, 188, 229, 253, 119, 178, 7, 50, 119, 97, 86, 135, 30, 208, 244, 143, + 47, 123, 77, 61, 107, 246, 54, 102, 78, 152, 252, 32, 53, 85, 248, 76, 52, 182, 189, 215, 50, 239, 179, + 162, 79, 120, 235, 170, 171, 104, 205, 252, 249, 106, 206, 158, 151, 155, 235, 10, 10, 185, 238, 45, 110, + 221, 90, 217, 103, 238, 171, 202, 59, 217, 103, 55, 102, 189, 27, 163, 127, 142, 215, 239, 39, 119, 161, + 237, 250, 95, 252, 55, 215, 1, 118, 255, 138, 86, 23, 46, 48, 207, 121, 155, 223, 197, 45, 179, 102, 115, + 237, 251, 250, 60, 121, 246, 108, 253, 76, 249, 158, 141, 17, 58, 6, 168, 203, 27, 18, 19, 149, 6, 52, 125, + 227, 203, 206, 210, 114, 66, 236, 55, 207, 164, 73, 93, 51, 245, 141, 228, 129, 185, 39, 34, 53, 1, 51, 4, + 117, 198, 182, 94, 61, 213, 35, 30, 176, 217, 230, 47, 20, 112, 223, 185, 115, 205, 26, 154, 116, 249, 229, + 202, 70, 89, 183, 246, 61, 20, 209, 233, 147, 173, 226, 250, 103, 130, 85, 124, 61, 154, 243, 191, 178, + 196, 223, 201, 183, 78, 189, 162, 253, 123, 146, 164, 86, 153, 179, 166, 146, 226, 63, 199, 242, 106, 192, + 104, 203, 219, 3, 162, 142, 97, 237, 205, 237, 222, 157, 14, 130, 107, 125, 196, 191, 172, 182, 251, 234, + 115, 236, 156, 102, 191, 183, 34, 26, 91, 238, 52, 203, 89, 9, 204, 148, 63, 121, 224, 1, 202, 201, 206, + 166, 125, 220, 27, 230, 178, 93, 254, 70, 33, 243, 203, 146, 119, 223, 45, 226, 0, 115, 158, 22, 107, 188, + 135, 121, 135, 209, 252, 158, 82, 249, 46, 84, 59, 23, 151, 53, 254, 190, 184, 192, 23, 183, 154, 247, 65, + 204, 207, 178, 215, 26, 251, 179, 77, 13, 40, 61, 224, 96, 237, 243, 47, 31, 121, 132, 242, 208, 199, 50, + 196, 47, 101, 137, 127, 89, 242, 193, 94, 219, 236, 115, 80, 233, 121, 133, 11, 208, 43, 64, 23, 200, 93, + 86, 212, 130, 196, 177, 99, 213, 172, 37, 55, 39, 199, 239, 216, 199, 253, 102, 250, 250, 245, 52, 185, 78, + 29, 21, 71, 167, 90, 234, 196, 107, 246, 239, 188, 176, 199, 62, 206, 230, 139, 242, 250, 207, 174, 15, + 237, 103, 124, 102, 91, 190, 99, 239, 20, 127, 83, 3, 152, 61, 128, 58, 19, 198, 125, 208, 166, 148, 20, + 42, 56, 112, 160, 200, 47, 243, 248, 247, 43, 10, 167, 247, 178, 215, 55, 115, 246, 33, 189, 22, 184, 0, + 53, 9, 245, 64, 206, 169, 97, 102, 212, 131, 123, 130, 156, 172, 44, 213, 187, 187, 145, 3, 224, 128, 148, + 78, 157, 84, 62, 78, 55, 226, 95, 82, 60, 204, 115, 119, 162, 27, 236, 177, 144, 247, 247, 151, 239, 156, + 96, 255, 44, 167, 207, 148, 231, 136, 6, 144, 125, 128, 225, 218, 223, 152, 229, 199, 119, 235, 70, 7, 216, + 15, 254, 136, 127, 73, 239, 98, 231, 131, 146, 206, 172, 35, 7, 192, 3, 216, 71, 88, 196, 28, 128, 57, 69, + 14, 219, 230, 111, 228, 177, 246, 221, 179, 117, 43, 197, 212, 175, 175, 114, 114, 166, 225, 91, 123, 28, + 204, 60, 176, 195, 23, 7, 251, 195, 111, 246, 158, 161, 180, 218, 226, 20, 127, 187, 6, 64, 95, 6, 13, 0, + 13, 216, 191, 65, 3, 202, 202, 204, 164, 92, 94, 99, 57, 126, 138, 127, 105, 121, 96, 114, 129, 121, 78, + 13, 57, 32, 60, 128, 90, 128, 58, 208, 251, 222, 123, 41, 155, 237, 67, 111, 2, 61, 224, 111, 20, 112, 110, + 173, 250, 236, 51, 101, 131, 112, 64, 188, 131, 237, 21, 137, 135, 191, 252, 86, 86, 248, 122, 78, 156, 85, + 252, 44, 0, 214, 27, 102, 24, 232, 199, 193, 181, 43, 166, 78, 85, 179, 49, 248, 195, 159, 241, 119, 122, + 31, 83, 231, 200, 254, 148, 211, 89, 69, 185, 183, 128, 25, 209, 162, 49, 99, 212, 172, 194, 141, 248, 35, + 239, 179, 210, 211, 105, 198, 93, 119, 21, 233, 128, 88, 31, 241, 244, 85, 179, 203, 26, 15, 183, 115, 192, + 215, 51, 164, 15, 132, 175, 161, 191, 198, 105, 63, 67, 119, 161, 6, 140, 122, 230, 25, 202, 103, 61, 228, + 47, 254, 47, 203, 59, 153, 243, 9, 233, 79, 193, 77, 208, 3, 208, 39, 152, 181, 130, 159, 176, 119, 208, + 135, 57, 64, 113, 20, 238, 151, 115, 204, 252, 141, 125, 156, 91, 107, 71, 143, 46, 198, 1, 162, 3, 252, + 181, 22, 221, 202, 133, 178, 252, 93, 115, 47, 192, 156, 3, 160, 222, 98, 14, 243, 113, 141, 26, 180, 126, + 209, 34, 202, 103, 29, 248, 21, 255, 218, 45, 204, 183, 193, 110, 155, 217, 163, 162, 47, 64, 111, 8, 45, + 128, 25, 225, 130, 97, 195, 20, 71, 101, 179, 30, 244, 55, 80, 247, 178, 25, 241, 143, 62, 170, 252, 51, + 75, 219, 53, 207, 193, 230, 178, 192, 77, 31, 86, 196, 231, 243, 44, 47, 7, 216, 251, 0, 248, 24, 53, 96, + 220, 75, 47, 169, 62, 160, 178, 108, 50, 115, 192, 73, 163, 74, 126, 246, 214, 246, 245, 190, 251, 110, + 218, 155, 145, 161, 122, 84, 55, 114, 96, 223, 161, 67, 180, 105, 230, 76, 197, 143, 200, 69, 89, 255, 193, + 26, 215, 242, 250, 218, 212, 129, 83, 172, 226, 125, 0, 102, 1, 29, 193, 1, 137, 137, 149, 110, 151, 228, + 128, 217, 167, 202, 121, 69, 179, 14, 128, 3, 230, 15, 28, 72, 133, 204, 213, 110, 196, 31, 117, 32, 151, + 107, 224, 130, 38, 77, 84, 14, 10, 7, 204, 173, 34, 241, 23, 174, 181, 207, 130, 176, 159, 5, 29, 248, 33, + 242, 225, 217, 103, 3, 98, 155, 61, 63, 229, 251, 194, 70, 90, 158, 62, 5, 253, 0, 246, 139, 122, 252, 225, + 15, 148, 158, 150, 70, 57, 204, 1, 208, 3, 254, 70, 110, 97, 33, 109, 91, 178, 132, 166, 92, 114, 137, 226, + 34, 209, 129, 102, 29, 8, 116, 60, 43, 234, 231, 121, 150, 151, 103, 69, 7, 98, 22, 43, 58, 16, 107, 172, + 125, 128, 108, 51, 107, 148, 57, 171, 50, 117, 42, 236, 67, 63, 24, 219, 171, 151, 210, 1, 110, 196, 31, + 200, 227, 58, 176, 244, 189, 247, 148, 127, 170, 34, 7, 128, 103, 157, 102, 1, 88, 99, 152, 185, 36, 84, + 50, 76, 27, 205, 94, 213, 212, 130, 194, 81, 216, 39, 234, 118, 195, 13, 180, 99, 211, 38, 213, 11, 184, + 17, 255, 28, 238, 7, 241, 93, 15, 211, 175, 187, 78, 173, 147, 56, 35, 254, 98, 107, 101, 251, 200, 95, 62, + 22, 14, 0, 175, 57, 245, 130, 221, 3, 108, 159, 212, 1, 209, 130, 194, 81, 208, 41, 152, 9, 64, 167, 128, + 3, 166, 126, 244, 17, 21, 240, 58, 205, 220, 187, 215, 21, 228, 242, 179, 87, 247, 235, 87, 140, 3, 230, + 133, 112, 252, 237, 57, 224, 107, 141, 245, 9, 18, 251, 156, 116, 10, 250, 65, 112, 0, 230, 21, 157, 234, + 212, 161, 45, 223, 124, 163, 102, 55, 110, 196, 63, 139, 181, 32, 122, 141, 184, 251, 238, 83, 54, 96, 189, + 84, 53, 14, 176, 207, 131, 48, 123, 237, 23, 4, 246, 153, 90, 208, 137, 3, 48, 175, 192, 153, 252, 9, 109, + 218, 168, 121, 133, 107, 28, 192, 207, 254, 62, 38, 70, 245, 2, 51, 45, 175, 14, 48, 235, 106, 160, 99, 90, + 17, 31, 59, 213, 89, 179, 23, 88, 24, 64, 44, 208, 248, 74, 219, 40, 117, 202, 62, 175, 80, 223, 119, 91, + 171, 22, 173, 79, 74, 162, 220, 130, 2, 218, 203, 241, 242, 59, 88, 11, 100, 231, 231, 83, 226, 11, 47, 40, + 61, 42, 53, 32, 193, 176, 51, 144, 190, 186, 16, 255, 38, 88, 197, 121, 86, 250, 45, 204, 92, 18, 3, 8, + 211, 78, 228, 0, 120, 0, 245, 23, 28, 108, 106, 85, 204, 132, 58, 224, 215, 220, 171, 231, 114, 140, 176, + 94, 247, 238, 217, 227, 119, 100, 113, 125, 193, 189, 161, 233, 87, 94, 169, 248, 82, 52, 128, 25, 251, 64, + 250, 235, 66, 124, 44, 57, 96, 242, 236, 184, 32, 180, 47, 206, 102, 31, 180, 42, 102, 66, 56, 55, 134, + 189, 129, 21, 51, 102, 80, 30, 247, 237, 110, 196, 31, 200, 225, 58, 144, 218, 169, 147, 202, 65, 172, 151, + 249, 218, 182, 80, 143, 255, 2, 203, 91, 107, 101, 141, 69, 6, 153, 125, 118, 14, 128, 125, 163, 172, 226, + 253, 234, 192, 71, 31, 85, 92, 13, 236, 225, 120, 249, 27, 123, 89, 11, 102, 164, 165, 81, 252, 157, 119, + 42, 174, 20, 13, 80, 149, 56, 64, 102, 2, 83, 130, 192, 182, 146, 236, 131, 22, 179, 247, 171, 152, 89, 37, + 142, 24, 65, 121, 251, 247, 211, 158, 221, 187, 93, 65, 54, 243, 203, 250, 9, 19, 148, 14, 136, 179, 188, + 58, 192, 172, 173, 129, 246, 217, 133, 172, 49, 83, 107, 45, 10, 2, 152, 118, 138, 125, 178, 119, 37, 255, + 62, 176, 244, 131, 152, 9, 245, 186, 253, 118, 218, 185, 125, 59, 101, 102, 101, 185, 147, 3, 204, 3, 153, + 172, 5, 22, 53, 110, 172, 106, 145, 201, 1, 98, 107, 160, 125, 86, 17, 255, 38, 90, 197, 121, 118, 118, 16, + 216, 102, 183, 209, 172, 83, 224, 95, 251, 222, 149, 244, 131, 51, 187, 118, 165, 60, 174, 213, 187, 57, + 94, 110, 32, 51, 47, 143, 182, 179, 22, 156, 89, 187, 182, 90, 43, 38, 7, 84, 133, 28, 128, 143, 227, 131, + 192, 46, 187, 125, 118, 173, 42, 253, 160, 156, 97, 194, 57, 214, 174, 140, 206, 117, 234, 208, 166, 213, + 171, 41, 43, 39, 135, 118, 103, 100, 184, 130, 44, 174, 49, 43, 187, 119, 87, 54, 32, 31, 67, 153, 3, 124, + 249, 56, 208, 54, 57, 217, 103, 231, 0, 179, 95, 5, 7, 224, 172, 24, 122, 129, 241, 175, 189, 70, 57, 5, 5, + 174, 197, 127, 15, 247, 153, 25, 187, 118, 209, 188, 251, 239, 87, 118, 84, 53, 14, 72, 8, 2, 155, 74, 203, + 79, 95, 51, 33, 156, 19, 234, 80, 163, 6, 173, 138, 143, 167, 108, 174, 213, 110, 229, 64, 102, 126, 62, + 109, 156, 61, 155, 166, 243, 103, 197, 233, 188, 52, 57, 32, 212, 115, 32, 208, 246, 148, 148, 3, 162, 5, + 157, 102, 66, 69, 253, 224, 99, 143, 41, 189, 134, 154, 157, 145, 158, 238, 10, 246, 114, 14, 44, 109, 221, + 186, 152, 22, 12, 85, 14, 176, 231, 192, 226, 32, 131, 105, 167, 169, 83, 164, 31, 148, 59, 173, 232, 7, + 177, 63, 136, 126, 48, 97, 232, 80, 85, 7, 220, 138, 255, 158, 204, 76, 218, 241, 253, 247, 20, 127, 243, + 205, 138, 143, 76, 14, 16, 91, 3, 237, 183, 138, 250, 57, 208, 118, 148, 100, 27, 252, 139, 58, 96, 246, + 171, 78, 253, 96, 247, 155, 110, 162, 237, 27, 55, 170, 153, 144, 107, 28, 192, 249, 245, 221, 216, 177, + 138, 3, 68, 11, 46, 180, 229, 107, 160, 253, 86, 85, 226, 111, 218, 39, 117, 160, 180, 126, 48, 234, 189, + 247, 92, 229, 128, 12, 232, 193, 220, 92, 90, 252, 226, 139, 69, 90, 176, 42, 112, 64, 160, 109, 40, 45, + 254, 162, 83, 204, 189, 11, 167, 253, 193, 143, 46, 185, 132, 214, 38, 38, 82, 22, 199, 200, 181, 58, 144, + 157, 77, 105, 107, 214, 80, 108, 189, 122, 74, 11, 218, 57, 32, 208, 62, 171, 8, 146, 130, 24, 98, 163, 89, + 7, 48, 179, 18, 45, 104, 238, 13, 224, 60, 235, 144, 63, 255, 153, 246, 102, 101, 185, 170, 5, 51, 153, 99, + 190, 29, 50, 164, 104, 111, 64, 56, 32, 84, 124, 26, 74, 48, 185, 64, 234, 128, 93, 11, 154, 123, 3, 168, + 3, 11, 134, 15, 119, 183, 14, 96, 62, 204, 57, 182, 232, 233, 167, 85, 95, 50, 223, 242, 114, 64, 117, 252, + 221, 203, 1, 225, 0, 115, 38, 96, 63, 43, 166, 180, 32, 107, 244, 109, 172, 213, 193, 3, 174, 213, 129, + 156, 28, 218, 150, 154, 74, 177, 87, 93, 165, 242, 81, 102, 66, 213, 28, 224, 94, 252, 203, 170, 5, 209, + 15, 70, 190, 245, 22, 229, 112, 207, 238, 26, 7, 160, 14, 20, 22, 210, 183, 3, 6, 252, 78, 11, 134, 90, 14, + 36, 7, 57, 76, 91, 37, 7, 192, 185, 114, 78, 196, 73, 11, 126, 88, 179, 166, 103, 46, 152, 151, 231, 90, + 252, 213, 62, 17, 247, 155, 168, 3, 179, 173, 226, 90, 48, 148, 252, 187, 36, 68, 32, 246, 98, 93, 201, 92, + 200, 172, 3, 208, 130, 114, 111, 160, 35, 163, 127, 195, 134, 30, 174, 222, 179, 199, 213, 58, 176, 125, + 197, 10, 154, 83, 183, 174, 210, 130, 18, 255, 80, 244, 111, 176, 195, 228, 3, 179, 31, 128, 6, 51, 235, + 128, 156, 25, 70, 29, 136, 237, 221, 155, 114, 152, 167, 221, 174, 3, 235, 184, 31, 16, 14, 144, 26, 80, + 157, 3, 238, 229, 0, 252, 43, 90, 192, 172, 3, 78, 123, 196, 223, 47, 95, 78, 153, 188, 78, 93, 203, 1, + 244, 3, 252, 252, 37, 77, 154, 40, 91, 100, 79, 205, 228, 254, 64, 251, 173, 42, 65, 124, 42, 251, 3, 208, + 94, 230, 76, 0, 251, 67, 114, 143, 28, 103, 134, 135, 63, 247, 28, 101, 102, 103, 187, 58, 19, 192, 92, + 232, 199, 117, 235, 104, 94, 253, 250, 69, 117, 32, 84, 56, 96, 105, 136, 193, 204, 3, 201, 1, 179, 14, 96, + 38, 32, 251, 67, 221, 45, 79, 29, 88, 56, 98, 132, 187, 51, 129, 116, 207, 254, 192, 134, 136, 136, 162, + 185, 32, 234, 64, 82, 136, 251, 58, 24, 97, 250, 83, 180, 128, 212, 1, 243, 172, 144, 252, 251, 119, 184, + 63, 22, 198, 235, 114, 235, 250, 245, 174, 206, 4, 176, 63, 176, 119, 223, 62, 90, 222, 186, 181, 178, 5, + 121, 41, 28, 80, 29, 127, 119, 114, 192, 236, 7, 164, 14, 152, 103, 133, 80, 7, 228, 172, 208, 184, 230, + 205, 41, 139, 251, 65, 156, 233, 112, 43, 7, 208, 15, 238, 218, 186, 149, 22, 52, 104, 240, 187, 58, 80, + 157, 3, 238, 228, 128, 217, 15, 96, 46, 100, 63, 55, 110, 222, 29, 89, 18, 25, 233, 126, 29, 96, 14, 216, + 50, 119, 46, 197, 95, 124, 113, 117, 29, 168, 132, 248, 3, 210, 15, 200, 92, 72, 206, 141, 155, 51, 1, 204, + 134, 123, 220, 114, 11, 165, 109, 218, 228, 234, 57, 1, 149, 3, 220, 19, 174, 9, 11, 43, 170, 3, 50, 19, 8, + 214, 248, 127, 29, 162, 48, 115, 65, 114, 192, 169, 14, 152, 103, 70, 39, 188, 249, 166, 58, 47, 152, 225, + 102, 29, 192, 121, 180, 189, 123, 41, 249, 169, 167, 84, 29, 48, 57, 32, 216, 124, 30, 76, 182, 92, 72, 14, + 72, 63, 224, 84, 7, 228, 123, 165, 62, 209, 57, 176, 108, 202, 20, 215, 247, 7, 48, 19, 192, 89, 129, 249, + 215, 93, 167, 234, 128, 204, 4, 130, 45, 7, 130, 201, 150, 11, 177, 223, 87, 63, 48, 209, 42, 94, 7, 62, + 102, 244, 186, 237, 54, 74, 219, 188, 217, 221, 126, 32, 93, 247, 132, 19, 38, 168, 124, 52, 251, 129, 96, + 226, 222, 96, 177, 195, 95, 57, 96, 246, 3, 152, 9, 160, 14, 56, 237, 17, 134, 183, 108, 233, 122, 29, 80, + 61, 33, 231, 192, 202, 182, 109, 213, 62, 177, 244, 3, 193, 196, 1, 102, 62, 6, 218, 22, 127, 196, 223, + 172, 3, 114, 86, 4, 119, 201, 237, 119, 7, 144, 3, 149, 209, 15, 236, 214, 119, 72, 22, 55, 106, 164, 114, + 50, 216, 180, 192, 18, 253, 115, 153, 70, 74, 8, 98, 153, 1, 187, 22, 64, 14, 96, 127, 96, 162, 229, 112, + 86, 228, 198, 27, 221, 159, 11, 65, 11, 228, 230, 170, 187, 132, 9, 245, 234, 21, 213, 129, 96, 241, 123, + 146, 246, 89, 160, 237, 240, 103, 30, 72, 14, 96, 173, 201, 62, 49, 122, 66, 236, 15, 152, 223, 51, 11, 45, + 56, 166, 105, 83, 117, 102, 212, 205, 185, 80, 145, 22, 24, 55, 174, 136, 3, 146, 131, 36, 254, 88, 39, + 193, 146, 139, 254, 138, 191, 212, 4, 233, 9, 209, 131, 201, 121, 33, 251, 153, 65, 181, 63, 48, 108, 152, + 235, 251, 196, 162, 5, 86, 181, 107, 87, 116, 239, 50, 24, 252, 14, 255, 84, 69, 14, 16, 109, 99, 175, 3, + 230, 254, 0, 234, 64, 23, 70, 87, 230, 229, 141, 43, 86, 184, 187, 79, 44, 90, 128, 243, 96, 201, 227, 143, + 43, 94, 10, 134, 58, 144, 96, 139, 255, 114, 141, 212, 16, 197, 114, 3, 203, 180, 127, 37, 7, 164, 39, 140, + 180, 126, 255, 189, 50, 67, 159, 120, 66, 221, 247, 117, 243, 188, 144, 210, 2, 156, 99, 63, 126, 243, 13, + 37, 214, 175, 175, 214, 158, 212, 129, 148, 0, 249, 94, 190, 3, 96, 73, 21, 137, 191, 61, 7, 76, 30, 192, + 154, 147, 217, 160, 253, 188, 16, 180, 192, 236, 176, 48, 215, 251, 1, 165, 5, 242, 243, 105, 243, 212, + 169, 148, 80, 179, 166, 226, 0, 251, 218, 171, 76, 255, 47, 184, 227, 14, 53, 47, 17, 14, 8, 84, 30, 186, + 149, 3, 41, 58, 7, 240, 126, 166, 22, 112, 154, 13, 118, 188, 248, 98, 90, 51, 103, 142, 103, 46, 224, 118, + 14, 176, 222, 88, 219, 179, 103, 192, 125, 191, 126, 212, 40, 197, 1, 166, 38, 13, 68, 30, 186, 153, 3, + 210, 19, 96, 173, 137, 22, 48, 239, 146, 154, 179, 193, 79, 27, 52, 160, 29, 91, 183, 186, 190, 71, 132, + 115, 99, 187, 185, 22, 164, 190, 252, 178, 178, 41, 80, 117, 0, 123, 214, 73, 172, 71, 230, 105, 255, 84, + 85, 14, 48, 181, 128, 244, 132, 56, 51, 230, 180, 71, 20, 161, 103, 131, 110, 247, 132, 187, 179, 178, 40, + 125, 251, 118, 90, 114, 255, 253, 138, 155, 68, 11, 86, 166, 255, 247, 230, 229, 209, 150, 121, 243, 104, + 238, 69, 53, 61, 54, 212, 96, 95, 49, 150, 51, 82, 53, 86, 132, 48, 228, 29, 240, 62, 95, 51, 146, 25, 137, + 140, 121, 140, 89, 140, 41, 140, 241, 140, 47, 25, 253, 106, 120, 122, 66, 156, 27, 76, 28, 57, 210, 253, + 158, 48, 221, 51, 27, 74, 75, 73, 161, 196, 107, 234, 169, 220, 92, 202, 54, 164, 84, 162, 255, 69, 143, + 164, 182, 110, 173, 56, 32, 169, 38, 251, 137, 145, 194, 72, 213, 88, 17, 226, 144, 247, 72, 209, 239, 134, + 119, 92, 200, 152, 195, 152, 193, 136, 98, 140, 97, 12, 97, 127, 124, 86, 67, 247, 132, 87, 215, 161, 13, + 41, 203, 92, 189, 79, 92, 164, 5, 88, 115, 110, 154, 28, 69, 11, 106, 214, 80, 90, 192, 238, 127, 55, 99, + 32, 60, 132, 243, 171, 9, 215, 93, 171, 230, 147, 201, 252, 251, 203, 24, 203, 171, 72, 14, 152, 126, 196, + 123, 45, 101, 44, 102, 36, 48, 226, 24, 83, 25, 145, 140, 145, 28, 251, 65, 140, 62, 53, 60, 61, 225, 160, + 70, 141, 60, 107, 20, 125, 123, 37, 232, 193, 117, 189, 122, 122, 252, 95, 163, 210, 252, 255, 255, 34, + 211, 204, 69, 71, 100, 37, 3, 0, 0, 21, 221, 109, 107, 66, 84, 250, 206, 202, 254, 0, 127, 173, 80, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, + 93, 249, 119, 84, 85, 182, 78, 21, 131, 32, 2, 138, 32, 34, 121, 15, 5, 68, 197, 161, 237, 182, 237, 231, + 19, 17, 88, 202, 66, 109, 91, 27, 177, 87, 59, 32, 162, 204, 9, 67, 72, 0, 5, 4, 2, 4, 17, 72, 26, 4, 148, + 134, 68, 160, 177, 73, 24, 147, 80, 153, 10, 18, 66, 2, 9, 9, 100, 38, 73, 165, 50, 32, 226, 255, 209, 107, + 247, 217, 231, 158, 83, 117, 114, 185, 183, 82, 149, 84, 221, 83, 149, 156, 31, 190, 95, 92, 184, 114, 110, + 125, 123, 252, 246, 62, 247, 194, 69, 123, 20, 40, 68, 46, 156, 2, 242, 9, 114, 8, 50, 163, 162, 32, 59, + 122, 44, 52, 148, 92, 129, 150, 142, 14, 104, 110, 106, 50, 133, 236, 243, 43, 4, 143, 251, 92, 130, 44, + 194, 253, 249, 251, 7, 67, 245, 169, 83, 208, 114, 231, 87, 159, 220, 35, 46, 145, 255, 71, 33, 242, 32, + 218, 64, 1, 65, 30, 193, 5, 194, 253, 57, 130, 235, 201, 201, 224, 254, 237, 183, 46, 185, 71, 20, 146, + 255, 79, 33, 242, 32, 218, 1, 141, 251, 54, 226, 247, 132, 251, 210, 184, 56, 112, 223, 189, 11, 205, 205, + 205, 138, 255, 94, 10, 145, 123, 238, 251, 152, 243, 139, 254, 246, 33, 180, 220, 190, 13, 46, 151, 203, + 47, 238, 21, 255, 145, 7, 35, 238, 49, 231, 59, 167, 190, 70, 125, 222, 229, 118, 251, 205, 189, 226, 63, + 178, 32, 230, 127, 39, 227, 62, 155, 112, 159, 251, 212, 36, 104, 188, 81, 9, 174, 246, 246, 128, 184, 87, + 252, 71, 14, 244, 220, 99, 206, 199, 122, 239, 194, 163, 163, 161, 254, 226, 69, 104, 249, 229, 151, 128, + 185, 87, 252, 71, 6, 140, 184, 119, 96, 143, 255, 192, 16, 168, 206, 72, 135, 150, 95, 187, 238, 243, 20, + 255, 145, 9, 125, 207, 135, 57, 63, 135, 112, 159, 217, 175, 31, 84, 30, 216, 239, 119, 159, 167, 248, 143, + 60, 232, 253, 222, 195, 61, 65, 121, 226, 22, 104, 233, 33, 247, 138, 255, 240, 133, 145, 223, 231, 218, + 52, 238, 75, 87, 44, 215, 98, 190, 159, 61, 190, 226, 63, 178, 224, 139, 251, 226, 79, 63, 209, 106, 189, + 0, 122, 124, 197, 127, 100, 193, 76, 223, 41, 252, 243, 59, 224, 106, 107, 11, 184, 199, 87, 252, 71, 14, + 68, 238, 121, 143, 143, 250, 206, 197, 215, 167, 66, 115, 99, 19, 184, 90, 91, 131, 198, 189, 226, 63, 188, + 96, 212, 231, 161, 190, 83, 240, 210, 31, 160, 169, 182, 22, 90, 218, 2, 215, 119, 20, 255, 145, 1, 189, + 223, 115, 238, 243, 158, 126, 10, 110, 85, 84, 128, 171, 139, 57, 190, 226, 63, 114, 97, 166, 237, 229, 62, + 241, 56, 52, 148, 148, 64, 203, 237, 238, 105, 123, 138, 255, 240, 135, 25, 247, 57, 209, 209, 80, 239, + 116, 118, 91, 215, 85, 252, 135, 63, 204, 184, 119, 140, 26, 5, 181, 23, 46, 244, 72, 215, 85, 252, 135, + 55, 76, 185, 31, 249, 48, 212, 102, 101, 90, 194, 189, 226, 63, 124, 184, 199, 121, 206, 133, 225, 195, + 160, 58, 253, 164, 182, 191, 99, 1, 247, 138, 255, 48, 227, 254, 228, 191, 161, 197, 66, 238, 219, 110, + 223, 150, 254, 123, 244, 37, 232, 117, 93, 47, 247, 195, 41, 247, 61, 157, 229, 5, 130, 214, 246, 118, 104, + 168, 174, 166, 103, 145, 253, 187, 244, 5, 152, 249, 189, 131, 248, 125, 13, 245, 123, 235, 184, 119, 187, + 221, 116, 71, 112, 199, 244, 105, 158, 51, 201, 254, 125, 122, 51, 204, 252, 222, 193, 98, 190, 149, 126, + 223, 210, 210, 2, 173, 29, 29, 176, 119, 246, 108, 248, 50, 170, 243, 217, 100, 255, 78, 189, 17, 230, 126, + 63, 220, 242, 124, 143, 62, 223, 126, 231, 14, 28, 94, 184, 0, 190, 32, 103, 88, 21, 165, 157, 73, 217, 64, + 232, 185, 239, 156, 239, 153, 223, 91, 201, 125, 115, 51, 116, 144, 191, 119, 98, 237, 26, 234, 247, 43, 9, + 190, 178, 105, 103, 114, 178, 243, 41, 27, 8, 13, 247, 162, 223, 231, 140, 26, 9, 53, 167, 50, 44, 245, + 123, 68, 7, 201, 49, 103, 118, 236, 128, 5, 228, 12, 203, 9, 214, 17, 238, 183, 216, 180, 25, 3, 183, 1, + 21, 7, 130, 207, 189, 232, 247, 57, 143, 140, 130, 218, 172, 44, 75, 253, 158, 115, 239, 216, 191, 31, 22, + 245, 239, 7, 177, 228, 28, 107, 9, 239, 155, 8, 190, 37, 184, 244, 250, 212, 78, 54, 160, 226, 64, 240, + 184, 239, 52, 203, 249, 159, 104, 168, 203, 201, 241, 235, 78, 102, 80, 185, 39, 182, 230, 60, 118, 12, + 150, 12, 30, 4, 203, 200, 57, 214, 16, 206, 191, 33, 216, 65, 240, 15, 114, 54, 252, 55, 133, 51, 223, 212, + 108, 192, 166, 226, 64, 176, 184, 231, 126, 143, 220, 231, 141, 127, 66, 219, 209, 183, 72, 211, 245, 112, + 79, 254, 94, 241, 153, 211, 16, 51, 108, 24, 44, 37, 231, 72, 96, 220, 39, 17, 164, 144, 179, 253, 72, 224, + 106, 109, 131, 102, 210, 19, 92, 254, 235, 123, 218, 188, 217, 166, 226, 64, 79, 185, 23, 253, 190, 224, + 217, 201, 208, 80, 90, 74, 252, 254, 142, 229, 220, 95, 117, 56, 96, 197, 200, 145, 176, 132, 113, 191, + 145, 96, 59, 65, 50, 193, 15, 228, 124, 63, 217, 53, 255, 199, 125, 50, 188, 59, 116, 101, 238, 167, 154, + 13, 24, 244, 5, 202, 14, 2, 227, 30, 127, 71, 231, 203, 127, 132, 198, 202, 74, 122, 39, 211, 74, 238, 177, + 199, 187, 238, 116, 194, 234, 232, 177, 176, 136, 156, 35, 158, 240, 189, 129, 113, 191, 135, 224, 32, 57, + 95, 26, 193, 191, 25, 255, 212, 6, 72, 12, 192, 89, 243, 213, 152, 101, 157, 108, 224, 162, 93, 217, 128, + 63, 188, 123, 184, 183, 105, 126, 95, 56, 125, 26, 52, 213, 213, 133, 108, 111, 199, 12, 109, 132, 195, + 155, 87, 174, 192, 26, 146, 115, 22, 10, 220, 111, 99, 220, 31, 96, 220, 255, 76, 112, 90, 224, 159, 218, + 128, 203, 69, 115, 84, 249, 250, 175, 33, 155, 252, 219, 220, 40, 109, 255, 84, 217, 128, 127, 220, 231, + 177, 126, 234, 242, 251, 239, 209, 253, 108, 220, 213, 181, 154, 251, 170, 171, 87, 97, 237, 196, 137, 148, + 251, 213, 228, 60, 235, 9, 182, 18, 236, 102, 220, 167, 18, 156, 32, 56, 69, 144, 169, 227, 159, 162, 185, + 153, 222, 43, 169, 216, 189, 11, 46, 220, 55, 80, 217, 64, 23, 220, 123, 246, 116, 163, 52, 238, 75, 62, + 255, 156, 230, 210, 96, 239, 233, 118, 201, 61, 201, 49, 181, 21, 21, 176, 225, 185, 103, 105, 143, 47, + 114, 191, 139, 96, 191, 142, 251, 243, 4, 14, 35, 254, 5, 27, 168, 74, 61, 2, 57, 195, 135, 209, 222, 85, + 217, 128, 49, 247, 244, 110, 70, 148, 22, 243, 175, 197, 175, 166, 57, 20, 115, 169, 213, 220, 215, 84, 92, + 135, 13, 207, 63, 239, 225, 254, 107, 130, 68, 129, 251, 35, 4, 255, 210, 113, 159, 103, 198, 63, 3, 106, + 84, 53, 103, 207, 66, 238, 152, 71, 61, 54, 208, 151, 251, 67, 35, 191, 167, 220, 15, 28, 0, 21, 223, 238, + 208, 116, 157, 32, 221, 203, 241, 23, 56, 203, 169, 65, 191, 127, 254, 57, 170, 235, 198, 233, 184, 255, + 158, 156, 241, 48, 227, 62, 67, 199, 125, 65, 23, 252, 83, 27, 32, 245, 64, 67, 81, 17, 20, 76, 126, 154, + 218, 120, 95, 213, 10, 141, 252, 30, 239, 98, 230, 12, 27, 10, 85, 135, 15, 107, 51, 188, 32, 220, 199, 11, + 200, 239, 9, 247, 13, 53, 53, 176, 241, 197, 23, 233, 60, 7, 185, 255, 138, 113, 255, 29, 193, 62, 198, + 253, 113, 198, 253, 57, 130, 11, 118, 237, 61, 97, 60, 158, 251, 243, 119, 48, 166, 53, 86, 221, 132, 75, + 175, 77, 209, 108, 160, 143, 233, 68, 70, 220, 99, 60, 204, 139, 142, 134, 218, 204, 243, 150, 107, 249, + 220, 239, 113, 127, 99, 203, 255, 253, 73, 155, 229, 49, 238, 183, 48, 238, 185, 223, 35, 247, 233, 38, + 220, 95, 242, 147, 127, 4, 125, 183, 8, 177, 239, 226, 15, 63, 208, 52, 173, 62, 208, 31, 26, 246, 119, + 118, 45, 215, 59, 95, 120, 30, 26, 72, 159, 101, 181, 158, 75, 253, 30, 243, 253, 245, 235, 176, 241, 133, + 23, 60, 220, 243, 121, 206, 78, 230, 247, 255, 212, 113, 159, 109, 192, 125, 32, 252, 83, 27, 112, 183, + 130, 139, 252, 237, 107, 43, 87, 104, 154, 118, 47, 175, 11, 205, 122, 251, 162, 55, 223, 208, 238, 99, 89, + 172, 235, 112, 238, 107, 89, 190, 23, 253, 126, 179, 142, 251, 99, 118, 223, 126, 223, 29, 254, 41, 80, 35, + 32, 241, 174, 146, 244, 135, 142, 193, 131, 104, 14, 236, 109, 54, 96, 20, 239, 243, 88, 141, 95, 58, 255, + 115, 218, 219, 89, 221, 219, 55, 55, 53, 18, 238, 127, 161, 220, 175, 23, 184, 95, 215, 5, 247, 102, 126, + 207, 57, 234, 214, 89, 72, 30, 192, 122, 167, 38, 61, 29, 242, 72, 111, 208, 155, 108, 192, 172, 191, 115, + 12, 232, 15, 215, 55, 111, 162, 245, 176, 213, 253, 29, 245, 123, 212, 118, 74, 75, 97, 253, 179, 147, 105, + 157, 47, 114, 143, 115, 220, 189, 228, 156, 135, 12, 184, 199, 247, 1, 231, 251, 224, 166, 39, 103, 162, + 189, 65, 113, 49, 92, 124, 241, 5, 109, 214, 97, 143, 236, 186, 208, 172, 198, 207, 125, 120, 4, 213, 66, + 2, 121, 175, 102, 48, 129, 122, 254, 13, 212, 116, 39, 78, 48, 140, 249, 156, 251, 163, 4, 39, 9, 206, 218, + 189, 126, 223, 85, 191, 214, 211, 179, 209, 28, 88, 95, 15, 197, 127, 121, 183, 83, 93, 24, 105, 179, 35, + 179, 157, 13, 231, 83, 147, 160, 62, 63, 95, 74, 141, 143, 192, 57, 94, 121, 65, 1, 196, 143, 27, 119, 143, + 223, 251, 195, 125, 87, 49, 57, 24, 103, 196, 124, 216, 210, 113, 27, 202, 226, 86, 129, 195, 110, 163, + 241, 50, 82, 122, 3, 95, 51, 156, 162, 153, 111, 66, 35, 233, 177, 66, 125, 7, 211, 148, 123, 98, 115, 165, + 217, 217, 176, 234, 177, 49, 221, 226, 222, 159, 88, 28, 180, 243, 98, 93, 72, 106, 130, 155, 7, 15, 64, + 238, 131, 195, 35, 162, 38, 48, 213, 243, 8, 174, 46, 93, 162, 189, 107, 197, 242, 58, 79, 195, 109, 242, + 91, 22, 101, 100, 64, 236, 200, 135, 169, 166, 43, 246, 247, 190, 184, 239, 42, 223, 135, 140, 127, 6, 140, + 147, 117, 185, 185, 224, 124, 230, 105, 77, 51, 54, 208, 138, 194, 193, 14, 204, 234, 188, 156, 161, 15, + 192, 141, 148, 20, 250, 28, 50, 234, 60, 206, 125, 65, 90, 26, 44, 29, 54, 148, 206, 239, 227, 116, 220, + 139, 117, 126, 119, 253, 62, 84, 252, 83, 27, 32, 241, 18, 251, 227, 203, 127, 126, 71, 211, 11, 195, 108, + 207, 92, 31, 239, 209, 70, 169, 173, 78, 122, 18, 234, 240, 222, 245, 93, 235, 181, 92, 4, 238, 104, 35, + 247, 89, 123, 247, 194, 194, 65, 131, 96, 177, 31, 220, 139, 61, 94, 119, 180, 249, 144, 61, 11, 198, 78, + 82, 19, 148, 175, 93, 67, 122, 167, 1, 97, 81, 19, 24, 197, 251, 124, 22, 239, 47, 191, 53, 11, 154, 36, + 230, 122, 220, 189, 192, 124, 159, 145, 152, 8, 95, 218, 237, 30, 238, 249, 44, 231, 59, 155, 239, 254, + 190, 187, 115, 153, 144, 62, 23, 213, 138, 126, 131, 234, 99, 71, 33, 255, 49, 185, 58, 129, 89, 174, 119, + 244, 239, 7, 101, 9, 241, 224, 106, 239, 144, 150, 235, 241, 78, 22, 246, 120, 71, 87, 173, 130, 249, 228, + 76, 75, 117, 51, 92, 35, 238, 123, 18, 243, 45, 227, 159, 63, 31, 233, 97, 110, 93, 189, 10, 133, 175, 189, + 74, 227, 172, 209, 252, 40, 148, 118, 96, 214, 215, 231, 143, 25, 13, 213, 71, 127, 210, 222, 163, 106, + 241, 220, 150, 195, 77, 122, 39, 55, 177, 187, 131, 243, 230, 193, 60, 114, 166, 101, 194, 238, 134, 126, + 134, 107, 164, 231, 247, 116, 30, 107, 213, 115, 82, 255, 114, 187, 225, 90, 204, 50, 112, 244, 179, 123, + 242, 65, 168, 109, 192, 168, 183, 67, 27, 44, 156, 242, 42, 220, 194, 189, 92, 139, 119, 178, 69, 224, 29, + 236, 166, 198, 70, 216, 245, 206, 59, 148, 251, 24, 97, 95, 111, 171, 15, 238, 185, 158, 31, 140, 89, 188, + 149, 207, 139, 245, 180, 155, 228, 131, 170, 35, 135, 33, 111, 244, 35, 33, 205, 7, 166, 241, 158, 216, 30, + 218, 160, 171, 197, 77, 109, 82, 22, 247, 168, 231, 214, 86, 86, 194, 150, 87, 94, 161, 220, 199, 218, 180, + 29, 109, 190, 171, 185, 91, 216, 219, 49, 154, 223, 7, 107, 15, 67, 198, 179, 211, 124, 64, 124, 175, 104, + 218, 84, 45, 31, 4, 185, 63, 48, 143, 247, 143, 66, 85, 90, 42, 213, 113, 101, 245, 118, 8, 212, 244, 174, + 95, 186, 8, 107, 39, 77, 162, 249, 126, 133, 205, 187, 159, 47, 238, 233, 34, 247, 124, 111, 71, 63, 199, + 11, 214, 239, 37, 235, 55, 192, 189, 104, 172, 183, 202, 86, 199, 65, 206, 192, 1, 65, 153, 37, 27, 106, + 121, 81, 90, 188, 47, 154, 49, 29, 110, 93, 187, 38, 77, 199, 165, 96, 253, 29, 234, 58, 203, 71, 143, 166, + 90, 62, 114, 207, 239, 100, 109, 23, 184, 79, 181, 119, 222, 213, 244, 53, 195, 237, 137, 175, 184, 45, + 222, 83, 237, 4, 54, 75, 174, 73, 63, 9, 206, 9, 227, 61, 122, 81, 119, 158, 207, 44, 222, 231, 12, 26, 72, + 123, 80, 218, 143, 118, 227, 251, 56, 65, 179, 119, 242, 172, 188, 183, 95, 52, 228, 126, 170, 233, 173, + 180, 121, 239, 98, 238, 96, 247, 114, 248, 221, 12, 253, 158, 110, 40, 184, 71, 52, 54, 52, 208, 157, 2, + 105, 54, 64, 128, 119, 163, 80, 103, 47, 249, 112, 142, 182, 87, 21, 64, 109, 168, 255, 55, 52, 222, 219, + 248, 236, 230, 73, 168, 61, 115, 90, 106, 125, 79, 159, 143, 212, 189, 237, 36, 223, 31, 95, 179, 6, 230, + 219, 109, 84, 211, 227, 90, 62, 231, 30, 239, 227, 253, 96, 247, 222, 205, 208, 239, 233, 134, 170, 78, + 218, 248, 135, 223, 195, 77, 146, 139, 59, 36, 214, 193, 212, 63, 112, 134, 132, 115, 206, 148, 100, 200, + 31, 57, 194, 180, 54, 20, 159, 219, 40, 222, 231, 177, 120, 95, 242, 241, 71, 208, 84, 87, 43, 77, 207, + 225, 192, 26, 31, 125, 127, 223, 71, 127, 135, 207, 88, 111, 207, 53, 61, 62, 187, 199, 123, 184, 120, 23, + 19, 239, 227, 225, 157, 44, 188, 151, 147, 105, 1, 247, 136, 207, 209, 22, 163, 199, 66, 241, 153, 51, 52, + 62, 201, 208, 61, 61, 192, 123, 7, 36, 31, 224, 78, 193, 229, 25, 211, 76, 107, 67, 51, 159, 167, 53, 30, + 233, 43, 110, 30, 216, 175, 237, 105, 200, 204, 109, 4, 237, 191, 220, 129, 218, 27, 55, 96, 235, 148, 41, + 148, 123, 222, 219, 127, 109, 50, 199, 65, 238, 207, 232, 184, 15, 181, 102, 138, 245, 7, 206, 22, 49, 39, + 101, 18, 223, 235, 248, 237, 46, 180, 184, 228, 213, 198, 52, 22, 160, 207, 16, 84, 108, 250, 6, 242, 134, + 14, 209, 180, 2, 131, 186, 64, 212, 112, 209, 86, 138, 103, 205, 244, 214, 120, 146, 237, 248, 54, 233, + 115, 241, 254, 109, 194, 196, 9, 158, 254, 46, 94, 208, 117, 244, 154, 222, 73, 198, 125, 150, 221, 59, + 195, 179, 66, 47, 199, 250, 3, 235, 16, 204, 73, 24, 11, 82, 99, 99, 160, 181, 163, 93, 110, 93, 136, 96, + 243, 100, 220, 189, 40, 122, 245, 149, 78, 177, 128, 131, 251, 124, 222, 131, 195, 161, 50, 41, 73, 251, + 246, 169, 196, 26, 143, 218, 46, 171, 243, 28, 63, 254, 0, 75, 201, 185, 120, 141, 175, 239, 237, 245, 186, + 206, 89, 3, 238, 173, 208, 70, 55, 179, 58, 4, 235, 17, 204, 77, 24, 167, 190, 123, 251, 109, 122, 175, + 160, 93, 114, 238, 68, 224, 94, 9, 198, 241, 242, 175, 214, 65, 238, 3, 67, 180, 250, 208, 230, 157, 211, + 23, 77, 159, 6, 13, 69, 133, 242, 125, 190, 73, 211, 114, 219, 104, 157, 151, 64, 234, 60, 59, 189, 131, + 185, 146, 245, 119, 252, 238, 189, 216, 219, 139, 186, 142, 56, 187, 183, 114, 86, 250, 45, 203, 69, 88, + 143, 96, 110, 138, 177, 105, 54, 176, 110, 242, 51, 80, 238, 116, 146, 56, 38, 177, 95, 246, 248, 84, 11, + 221, 55, 197, 88, 112, 137, 196, 2, 252, 198, 57, 190, 67, 171, 98, 219, 86, 77, 87, 182, 248, 142, 181, + 17, 176, 135, 194, 94, 106, 207, 251, 239, 209, 223, 111, 137, 174, 198, 79, 18, 250, 187, 84, 187, 214, + 223, 241, 251, 88, 193, 210, 242, 187, 3, 204, 65, 223, 177, 156, 180, 158, 229, 168, 229, 4, 168, 75, 45, + 27, 241, 16, 141, 99, 24, 207, 90, 36, 234, 101, 222, 88, 208, 65, 243, 66, 249, 142, 36, 250, 46, 29, 212, + 146, 93, 205, 242, 250, 58, 14, 156, 219, 86, 20, 94, 130, 245, 47, 254, 142, 114, 143, 62, 164, 175, 241, + 197, 254, 206, 10, 93, 199, 95, 96, 253, 129, 185, 104, 23, 203, 77, 27, 89, 174, 194, 156, 133, 26, 5, + 198, 177, 180, 149, 43, 105, 31, 211, 42, 105, 62, 218, 9, 88, 23, 144, 62, 81, 214, 172, 86, 4, 207, 245, + 121, 71, 142, 192, 178, 135, 71, 208, 250, 137, 215, 121, 124, 118, 203, 107, 124, 89, 253, 93, 87, 192, + 28, 132, 185, 8, 103, 13, 123, 88, 142, 250, 198, 230, 173, 11, 49, 142, 205, 37, 248, 118, 230, 76, 168, + 187, 121, 147, 206, 169, 101, 255, 238, 225, 0, 156, 217, 226, 29, 188, 163, 171, 87, 195, 252, 254, 253, + 168, 175, 136, 117, 158, 56, 191, 67, 31, 227, 123, 122, 250, 254, 78, 246, 142, 36, 230, 32, 156, 49, 96, + 78, 194, 220, 148, 194, 244, 168, 205, 44, 126, 97, 28, 91, 198, 106, 130, 248, 241, 227, 225, 202, 185, + 115, 212, 230, 93, 146, 107, 45, 153, 64, 31, 168, 175, 170, 130, 157, 179, 102, 81, 223, 88, 44, 104, 185, + 92, 199, 231, 243, 187, 174, 106, 124, 217, 251, 177, 152, 131, 48, 23, 161, 230, 136, 185, 9, 115, 20, + 234, 81, 59, 89, 93, 248, 53, 139, 103, 24, 215, 176, 151, 89, 120, 255, 96, 200, 32, 117, 23, 254, 6, 210, + 123, 68, 139, 193, 247, 243, 138, 137, 15, 196, 79, 152, 112, 79, 174, 215, 235, 248, 250, 249, 157, 175, + 26, 95, 6, 247, 133, 44, 14, 97, 60, 194, 156, 132, 185, 9, 227, 20, 234, 81, 88, 23, 238, 98, 113, 108, + 131, 80, 19, 44, 98, 249, 32, 101, 206, 7, 112, 171, 174, 174, 207, 228, 3, 180, 117, 124, 86, 180, 125, + 244, 1, 172, 143, 151, 219, 58, 235, 121, 92, 203, 245, 85, 231, 133, 219, 251, 19, 242, 152, 77, 98, 92, + 194, 220, 132, 57, 10, 227, 21, 198, 45, 163, 154, 128, 235, 4, 104, 3, 107, 159, 126, 10, 74, 178, 178, + 122, 125, 62, 64, 29, 23, 109, 61, 101, 206, 28, 234, 243, 139, 12, 114, 61, 215, 243, 68, 45, 151, 215, + 121, 161, 152, 219, 7, 11, 252, 78, 59, 218, 0, 198, 39, 140, 83, 247, 212, 4, 246, 206, 53, 1, 215, 9, + 208, 7, 22, 14, 185, 31, 78, 109, 223, 78, 181, 34, 119, 24, 212, 228, 193, 4, 175, 239, 75, 178, 179, 168, + 173, 207, 101, 243, 155, 85, 62, 114, 189, 145, 150, 27, 14, 117, 158, 25, 196, 239, 77, 230, 50, 27, 224, + 53, 1, 198, 47, 140, 99, 216, 187, 96, 15, 163, 215, 9, 208, 7, 22, 178, 88, 176, 231, 253, 247, 161, 190, + 186, 186, 215, 228, 3, 180, 101, 188, 111, 157, 158, 152, 232, 137, 247, 177, 186, 190, 222, 40, 215, 139, + 187, 185, 225, 206, 125, 161, 112, 30, 167, 221, 251, 173, 105, 163, 154, 128, 235, 4, 187, 5, 157, 96, 13, + 235, 17, 151, 218, 52, 27, 192, 254, 160, 48, 35, 93, 211, 139, 36, 206, 219, 123, 10, 156, 133, 99, 175, + 187, 235, 221, 119, 233, 115, 45, 100, 185, 62, 193, 230, 157, 223, 136, 125, 189, 62, 215, 251, 210, 243, + 194, 137, 123, 145, 127, 113, 87, 142, 219, 64, 22, 179, 101, 94, 19, 160, 141, 163, 118, 157, 204, 244, + 204, 77, 66, 143, 24, 203, 242, 193, 23, 3, 7, 194, 209, 248, 120, 77, 11, 15, 3, 93, 54, 16, 160, 198, + 137, 182, 123, 241, 196, 9, 136, 123, 124, 156, 22, 239, 109, 222, 222, 142, 239, 231, 233, 251, 122, 127, + 115, 125, 184, 113, 111, 102, 3, 190, 106, 2, 125, 143, 168, 215, 141, 177, 54, 250, 148, 96, 203, 148, 41, + 80, 81, 84, 20, 49, 181, 33, 234, 247, 200, 127, 234, 138, 21, 48, 127, 192, 0, 159, 241, 94, 156, 223, + 240, 251, 119, 89, 246, 240, 209, 116, 130, 105, 3, 185, 204, 166, 207, 51, 27, 255, 217, 126, 111, 143, + 200, 243, 1, 239, 15, 184, 94, 180, 244, 161, 135, 224, 220, 238, 221, 97, 93, 27, 242, 158, 30, 239, 216, + 127, 243, 167, 151, 169, 237, 242, 250, 94, 156, 215, 239, 212, 245, 118, 70, 125, 189, 21, 251, 26, 50, + 243, 1, 198, 55, 125, 143, 200, 243, 129, 190, 63, 64, 223, 249, 146, 213, 134, 187, 223, 251, 11, 221, + 117, 239, 8, 131, 25, 173, 8, 156, 105, 160, 223, 159, 74, 218, 14, 139, 135, 13, 211, 238, 223, 216, 188, + 245, 189, 24, 239, 197, 222, 142, 191, 59, 185, 171, 190, 62, 210, 184, 247, 21, 11, 184, 78, 96, 212, 35, + 26, 229, 3, 174, 23, 45, 97, 181, 225, 138, 177, 99, 33, 231, 159, 135, 72, 109, 117, 87, 186, 110, 200, + 191, 133, 84, 93, 118, 13, 118, 190, 53, 139, 250, 252, 2, 22, 239, 87, 155, 196, 123, 163, 222, 46, 148, + 123, 185, 178, 97, 180, 91, 169, 239, 17, 205, 250, 3, 81, 47, 138, 99, 90, 1, 106, 199, 243, 108, 54, 216, + 247, 209, 71, 84, 59, 151, 181, 111, 138, 121, 168, 227, 206, 175, 144, 253, 253, 247, 16, 59, 250, 17, 79, + 141, 39, 234, 57, 124, 63, 107, 175, 189, 179, 150, 135, 54, 175, 239, 237, 34, 61, 222, 7, 98, 3, 158, + 247, 36, 216, 59, 231, 3, 236, 121, 197, 254, 128, 207, 144, 196, 249, 1, 214, 134, 139, 89, 109, 24, 247, + 196, 227, 80, 112, 236, 40, 245, 65, 203, 98, 1, 250, 60, 177, 57, 124, 127, 90, 242, 236, 191, 210, 250, + 228, 11, 65, 191, 231, 123, 26, 124, 71, 71, 95, 223, 139, 58, 110, 184, 105, 248, 86, 218, 129, 175, 254, + 64, 175, 23, 153, 213, 134, 88, 91, 207, 179, 219, 97, 223, 39, 31, 67, 29, 139, 5, 161, 236, 17, 208, 231, + 81, 151, 202, 62, 120, 0, 150, 63, 54, 134, 218, 224, 98, 214, 211, 243, 26, 143, 235, 247, 168, 117, 114, + 61, 135, 215, 247, 98, 188, 143, 212, 250, 62, 216, 177, 192, 172, 63, 64, 95, 193, 60, 41, 206, 15, 146, + 88, 62, 53, 138, 5, 171, 198, 253, 47, 228, 28, 62, 172, 205, 19, 131, 221, 35, 176, 60, 207, 125, 126, + 174, 224, 243, 162, 134, 171, 175, 241, 126, 178, 123, 227, 125, 111, 171, 239, 131, 105, 7, 122, 205, 144, + 235, 69, 152, 15, 244, 181, 33, 230, 83, 62, 75, 92, 163, 139, 5, 24, 139, 147, 231, 124, 0, 53, 229, 229, + 116, 223, 48, 24, 177, 128, 214, 246, 164, 239, 204, 220, 183, 207, 208, 231, 249, 204, 142, 214, 120, 246, + 206, 250, 189, 145, 158, 211, 151, 226, 125, 32, 54, 192, 107, 2, 125, 62, 224, 59, 5, 98, 109, 200, 99, 1, + 215, 13, 87, 235, 98, 1, 214, 99, 103, 119, 239, 34, 61, 89, 71, 183, 181, 67, 62, 179, 185, 81, 114, 5, + 118, 190, 253, 150, 161, 207, 111, 180, 121, 103, 118, 98, 141, 39, 234, 247, 125, 61, 222, 7, 98, 3, 250, + 124, 96, 86, 27, 98, 94, 229, 125, 162, 81, 44, 248, 130, 217, 193, 182, 25, 211, 161, 172, 160, 32, 224, + 189, 83, 236, 229, 49, 135, 100, 108, 219, 6, 75, 70, 140, 208, 124, 222, 214, 217, 231, 55, 51, 27, 68, + 91, 220, 111, 191, 87, 195, 53, 170, 241, 20, 247, 254, 217, 129, 62, 22, 160, 15, 137, 177, 0, 243, 42, + 230, 87, 222, 39, 138, 117, 1, 143, 5, 124, 223, 112, 193, 144, 33, 112, 52, 33, 158, 242, 74, 103, 138, + 62, 114, 2, 222, 175, 68, 91, 41, 117, 92, 128, 205, 175, 254, 63, 124, 18, 165, 105, 79, 70, 62, 47, 234, + 120, 169, 118, 175, 207, 27, 237, 229, 169, 120, 223, 61, 27, 48, 139, 5, 226, 28, 73, 31, 11, 196, 30, 33, + 134, 105, 135, 200, 227, 218, 201, 207, 64, 193, 241, 227, 180, 71, 208, 215, 135, 46, 214, 211, 53, 214, + 215, 195, 225, 216, 24, 248, 114, 240, 32, 106, 59, 75, 108, 94, 253, 214, 151, 207, 243, 123, 182, 250, + 26, 79, 197, 251, 224, 216, 1, 175, 13, 205, 234, 2, 30, 11, 140, 122, 4, 228, 15, 117, 25, 212, 100, 63, + 35, 189, 98, 202, 223, 62, 132, 234, 178, 50, 90, 207, 35, 239, 84, 199, 33, 220, 231, 165, 165, 65, 194, + 147, 19, 169, 173, 44, 240, 145, 231, 69, 159, 23, 251, 58, 94, 227, 229, 217, 85, 141, 23, 10, 27, 208, + 247, 137, 250, 88, 128, 124, 96, 44, 224, 251, 37, 219, 88, 79, 182, 206, 230, 157, 43, 243, 157, 195, 216, + 81, 35, 225, 116, 82, 18, 221, 187, 70, 91, 72, 153, 61, 155, 106, 138, 243, 153, 110, 47, 250, 60, 175, + 237, 245, 90, 78, 32, 62, 175, 184, 239, 185, 13, 24, 197, 2, 163, 186, 0, 249, 225, 122, 1, 215, 14, 215, + 219, 188, 59, 38, 232, 215, 184, 135, 129, 92, 39, 254, 241, 37, 72, 136, 30, 75, 239, 91, 44, 21, 246, 48, + 215, 217, 188, 51, 27, 177, 182, 79, 181, 123, 119, 176, 69, 159, 23, 251, 58, 21, 239, 67, 107, 7, 190, + 98, 129, 94, 47, 224, 218, 225, 118, 161, 87, 76, 96, 241, 128, 230, 5, 118, 151, 126, 37, 227, 125, 173, + 205, 171, 219, 163, 134, 151, 236, 35, 207, 235, 119, 242, 84, 188, 183, 206, 6, 244, 154, 145, 89, 93, + 192, 231, 202, 41, 54, 111, 125, 184, 137, 197, 131, 175, 24, 223, 235, 88, 156, 223, 192, 98, 69, 146, + 160, 225, 253, 104, 55, 174, 237, 149, 207, 135, 135, 29, 152, 197, 2, 81, 59, 68, 61, 134, 215, 135, 201, + 204, 14, 146, 152, 45, 36, 50, 108, 99, 185, 98, 23, 171, 239, 14, 50, 219, 17, 103, 54, 42, 207, 135, 15, + 186, 170, 11, 244, 115, 101, 94, 31, 162, 63, 99, 60, 223, 203, 108, 97, 15, 67, 10, 243, 119, 228, 29, 99, + 61, 215, 237, 69, 13, 79, 233, 183, 190, 249, 144, 109, 7, 70, 122, 1, 175, 15, 113, 254, 242, 51, 179, 3, + 140, 7, 232, 219, 135, 152, 61, 28, 98, 156, 31, 97, 188, 99, 204, 192, 158, 130, 107, 120, 202, 231, 253, + 227, 32, 28, 206, 160, 215, 14, 245, 245, 33, 198, 113, 140, 7, 232, 219, 199, 5, 32, 231, 104, 31, 233, + 140, 119, 94, 223, 41, 13, 207, 255, 223, 61, 156, 206, 194, 99, 129, 62, 39, 100, 50, 110, 185, 45, 112, + 32, 231, 24, 231, 207, 219, 141, 99, 189, 242, 121, 243, 223, 154, 215, 226, 178, 207, 228, 203, 14, 144, + 71, 110, 7, 200, 109, 54, 227, 57, 147, 33, 155, 253, 119, 190, 135, 167, 98, 189, 127, 191, 177, 103, 167, + 211, 38, 255, 76, 102, 54, 160, 143, 7, 220, 22, 114, 117, 224, 186, 45, 143, 245, 138, 123, 223, 191, 171, + 248, 173, 35, 124, 127, 150, 236, 179, 249, 107, 7, 220, 22, 140, 96, 196, 185, 226, 189, 11, 238, 251, + 247, 135, 235, 91, 19, 165, 159, 207, 95, 27, 8, 4, 178, 207, 30, 46, 48, 226, 30, 223, 151, 152, 51, 116, + 40, 220, 60, 244, 35, 125, 191, 162, 236, 51, 6, 195, 38, 100, 159, 43, 28, 97, 196, 61, 125, 119, 226, 99, + 99, 160, 246, 236, 89, 207, 123, 240, 101, 159, 83, 33, 180, 220, 139, 223, 51, 117, 62, 247, 44, 125, 183, + 178, 248, 205, 27, 217, 103, 85, 176, 134, 251, 162, 55, 102, 64, 83, 77, 141, 246, 189, 102, 97, 135, 70, + 246, 121, 21, 130, 207, 187, 167, 191, 99, 53, 126, 201, 103, 115, 233, 183, 183, 140, 222, 153, 40, 251, + 220, 10, 193, 231, 158, 215, 248, 248, 173, 171, 242, 13, 235, 181, 247, 101, 154, 236, 209, 202, 62, 187, + 66, 240, 185, 199, 26, 63, 247, 193, 97, 180, 198, 119, 119, 241, 237, 19, 217, 231, 87, 8, 46, 247, 244, + 27, 74, 19, 198, 67, 157, 195, 161, 125, 199, 184, 139, 157, 121, 217, 207, 160, 208, 115, 238, 197, 58, + 175, 240, 245, 215, 160, 177, 178, 130, 198, 124, 127, 238, 76, 200, 126, 14, 133, 238, 243, 174, 175, 243, + 74, 73, 157, 215, 76, 242, 124, 32, 223, 192, 144, 253, 60, 10, 61, 227, 158, 214, 121, 247, 13, 132, 138, + 173, 137, 164, 175, 191, 67, 235, 252, 64, 238, 203, 201, 126, 38, 133, 238, 113, 239, 209, 243, 198, 60, + 10, 213, 63, 159, 208, 234, 188, 110, 220, 155, 149, 253, 92, 10, 254, 243, 174, 207, 245, 151, 94, 126, 9, + 110, 149, 148, 244, 232, 27, 214, 178, 159, 79, 193, 63, 238, 239, 209, 116, 62, 249, 88, 251, 94, 94, 15, + 223, 177, 40, 251, 25, 21, 252, 227, 222, 51, 187, 27, 60, 8, 42, 182, 111, 211, 52, 157, 0, 115, 189, 226, + 63, 252, 97, 180, 251, 224, 233, 235, 31, 31, 7, 53, 167, 79, 105, 223, 179, 13, 210, 251, 114, 100, 63, + 175, 130, 57, 247, 60, 215, 35, 247, 151, 223, 124, 131, 244, 245, 149, 126, 247, 245, 138, 255, 200, 130, + 89, 174, 119, 244, 239, 7, 101, 113, 171, 72, 79, 223, 22, 146, 111, 94, 201, 126, 110, 5, 243, 92, 159, + 63, 102, 52, 84, 253, 148, 70, 227, 189, 43, 68, 239, 83, 151, 253, 236, 125, 25, 190, 226, 125, 209, 212, + 41, 112, 171, 180, 180, 71, 189, 157, 226, 63, 124, 97, 170, 229, 245, 179, 67, 217, 242, 24, 250, 205, 91, + 252, 182, 105, 40, 185, 87, 252, 135, 7, 247, 158, 111, 215, 143, 29, 3, 85, 105, 169, 90, 188, 183, 232, + 123, 171, 178, 127, 139, 190, 4, 195, 120, 31, 197, 234, 251, 55, 102, 192, 173, 178, 178, 144, 199, 123, + 197, 191, 124, 238, 197, 120, 159, 51, 232, 62, 250, 109, 115, 156, 217, 89, 253, 237, 122, 55, 137, 49, + 178, 127, 151, 190, 0, 163, 120, 143, 62, 239, 124, 114, 34, 212, 158, 57, 29, 210, 250, 222, 12, 237, 109, + 109, 255, 105, 107, 109, 253, 47, 184, 74, 135, 48, 27, 51, 243, 87, 0, 0, 14, 126, 109, 107, 66, 84, 250, + 206, 202, 254, 0, 127, 182, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 157, 11, 80, 85, 213, 26, 199, 55, 79, 41, 132, 124, 229, 149, 154, + 200, 163, 102, 160, 132, 8, 98, 40, 34, 15, 21, 37, 228, 128, 102, 165, 34, 105, 101, 192, 96, 93, 122, 24, + 166, 94, 199, 107, 47, 111, 102, 230, 84, 119, 148, 201, 110, 78, 15, 74, 47, 118, 109, 20, 211, 59, 154, + 161, 222, 169, 68, 153, 49, 31, 81, 97, 166, 165, 81, 196, 201, 7, 130, 10, 186, 238, 90, 167, 181, 112, + 177, 88, 123, 159, 135, 231, 156, 189, 241, 124, 223, 204, 79, 155, 3, 158, 179, 247, 250, 255, 247, 90, + 223, 247, 173, 5, 41, 8, 33, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 235, 139, 247, 223, + 127, 31, 240, 98, 32, 188, 59, 124, 124, 124, 58, 11, 29, 66, 126, 59, 237, 191, 5, 208, 198, 232, 33, 232, + 233, 203, 233, 238, 23, 28, 28, 60, 165, 184, 184, 120, 227, 254, 253, 251, 51, 241, 223, 138, 175, 175, + 47, 121, 157, 252, 225, 11, 62, 232, 244, 250, 243, 154, 51, 172, 175, 7, 5, 5, 165, 231, 231, 231, 239, + 58, 122, 244, 40, 226, 98, 115, 85, 85, 85, 188, 217, 108, 102, 247, 229, 199, 252, 2, 62, 232, 60, 250, + 115, 90, 49, 205, 253, 184, 47, 39, 77, 156, 56, 113, 235, 145, 35, 71, 144, 74, 92, 194, 252, 107, 231, + 206, 157, 3, 98, 99, 99, 173, 111, 167, 116, 244, 129, 238, 99, 110, 36, 12, 20, 156, 68, 127, 234, 206, + 93, 95, 92, 122, 122, 122, 249, 174, 93, 187, 90, 213, 132, 23, 226, 116, 75, 75, 203, 75, 101, 101, 101, + 127, 233, 223, 191, 63, 249, 247, 100, 77, 128, 249, 192, 152, 250, 107, 233, 30, 153, 156, 156, 252, 206, + 142, 29, 59, 46, 218, 169, 187, 24, 39, 79, 159, 62, 253, 215, 23, 95, 124, 177, 235, 205, 55, 223, 76, + 222, 15, 124, 96, 28, 253, 101, 186, 179, 11, 50, 69, 68, 68, 188, 89, 94, 94, 222, 232, 164, 238, 98, 28, + 174, 175, 175, 127, 224, 169, 167, 158, 242, 15, 12, 12, 36, 239, 239, 71, 63, 175, 221, 186, 0, 225, 145, + 208, 210, 61, 12, 235, 254, 210, 218, 181, 107, 255, 184, 120, 209, 217, 71, 94, 51, 42, 107, 106, 106, 82, + 115, 115, 115, 21, 63, 63, 107, 90, 65, 254, 240, 5, 31, 120, 36, 100, 186, 251, 210, 175, 245, 48, 153, + 76, 243, 75, 75, 75, 235, 154, 154, 154, 220, 161, 59, 31, 151, 49, 255, 198, 57, 226, 144, 209, 163, 71, + 91, 175, 75, 81, 89, 19, 32, 92, 18, 90, 186, 135, 244, 234, 213, 235, 177, 197, 139, 23, 31, 63, 123, 246, + 172, 187, 117, 23, 131, 24, 237, 141, 205, 155, 55, 135, 71, 69, 69, 89, 175, 83, 1, 31, 184, 58, 58, 232, + 78, 199, 51, 168, 91, 183, 110, 179, 22, 46, 92, 248, 77, 93, 93, 157, 167, 117, 23, 163, 30, 207, 57, 11, + 87, 173, 90, 213, 61, 60, 60, 156, 92, 155, 106, 142, 8, 97, 87, 136, 207, 187, 47, 247, 188, 7, 116, 237, + 218, 245, 94, 156, 135, 85, 159, 58, 117, 74, 111, 221, 197, 56, 106, 177, 88, 30, 46, 41, 41, 233, 18, 26, + 26, 74, 174, 21, 124, 224, 120, 200, 230, 122, 235, 235, 56, 223, 202, 152, 58, 117, 234, 238, 195, 135, + 15, 235, 173, 179, 173, 168, 58, 126, 252, 120, 86, 81, 81, 145, 47, 203, 17, 57, 31, 131, 7, 228, 161, + 166, 187, 226, 239, 239, 159, 52, 101, 202, 148, 173, 7, 14, 28, 184, 162, 183, 176, 14, 198, 167, 251, + 246, 237, 75, 16, 250, 201, 126, 48, 23, 180, 11, 85, 221, 113, 196, 101, 100, 100, 148, 239, 221, 187, + 247, 178, 222, 66, 94, 67, 144, 126, 242, 218, 202, 202, 202, 129, 241, 241, 241, 214, 251, 85, 96, 77, 32, + 161, 165, 123, 100, 66, 66, 194, 218, 77, 155, 54, 185, 165, 128, 215, 41, 206, 182, 182, 182, 254, 227, + 195, 15, 63, 236, 19, 17, 17, 65, 238, 209, 91, 115, 3, 153, 238, 109, 61, 187, 184, 184, 184, 55, 54, 110, + 220, 216, 120, 249, 114, 103, 126, 228, 53, 227, 212, 185, 115, 231, 158, 88, 186, 116, 105, 72, 239, 222, + 189, 201, 61, 203, 124, 160, 159, 58, 238, 11, 45, 221, 195, 250, 245, 235, 247, 18, 126, 54, 254, 192, + 207, 136, 222, 250, 120, 42, 72, 63, 121, 218, 188, 121, 243, 252, 131, 130, 130, 200, 24, 92, 175, 253, + 100, 153, 238, 172, 150, 235, 121, 219, 109, 183, 45, 88, 185, 114, 101, 157, 14, 189, 27, 163, 196, 174, + 154, 154, 154, 177, 121, 121, 121, 36, 207, 37, 99, 114, 189, 172, 9, 90, 186, 135, 132, 133, 133, 61, 190, + 108, 217, 50, 61, 122, 118, 70, 12, 178, 216, 109, 216, 189, 123, 119, 76, 74, 74, 138, 117, 236, 148, 206, + 237, 3, 53, 221, 131, 110, 188, 241, 198, 135, 230, 207, 159, 255, 141, 197, 98, 209, 123, 204, 141, 24, + 205, 152, 127, 86, 84, 84, 220, 30, 19, 19, 99, 29, 71, 165, 115, 249, 64, 77, 247, 128, 224, 224, 224, + 123, 139, 138, 138, 170, 143, 29, 59, 166, 247, 24, 119, 134, 104, 104, 110, 110, 94, 180, 122, 245, 234, + 30, 125, 251, 246, 37, 227, 103, 244, 90, 129, 191, 38, 107, 30, 195, 94, 15, 12, 12, 204, 152, 61, 123, + 246, 238, 218, 218, 90, 189, 199, 180, 51, 198, 15, 103, 206, 156, 121, 116, 193, 130, 5, 55, 104, 244, + 147, 245, 83, 253, 207, 96, 207, 123, 187, 26, 30, 255, 157, 148, 153, 153, 185, 237, 224, 193, 131, 134, + 239, 217, 109, 219, 176, 1, 45, 155, 59, 23, 253, 242, 211, 79, 122, 95, 138, 90, 236, 63, 113, 226, 132, + 121, 206, 156, 57, 190, 93, 186, 116, 33, 195, 107, 164, 51, 7, 29, 122, 118, 227, 199, 143, 47, 223, 179, + 103, 143, 225, 11, 248, 170, 202, 74, 244, 80, 74, 10, 234, 167, 40, 232, 22, 76, 66, 143, 30, 232, 173, + 165, 75, 81, 163, 113, 115, 210, 173, 213, 213, 213, 35, 178, 179, 179, 219, 250, 201, 138, 228, 156, 186, + 135, 131, 125, 96, 36, 206, 93, 215, 126, 246, 217, 103, 134, 239, 217, 29, 170, 170, 66, 143, 153, 205, + 104, 160, 143, 15, 50, 97, 221, 7, 99, 238, 194, 220, 137, 9, 199, 164, 155, 76, 232, 63, 239, 188, 131, + 90, 90, 90, 244, 190, 84, 89, 144, 126, 242, 187, 219, 183, 111, 143, 136, 139, 139, 99, 227, 175, 103, + 110, 96, 26, 52, 104, 208, 155, 235, 215, 175, 63, 175, 247, 192, 216, 138, 163, 71, 142, 160, 146, 105, + 211, 208, 96, 127, 127, 235, 51, 31, 133, 25, 34, 129, 248, 128, 248, 226, 254, 216, 88, 180, 123, 203, 22, + 189, 47, 91, 45, 72, 63, 121, 89, 89, 89, 89, 24, 30, 127, 162, 131, 94, 57, 162, 229, 194, 133, 11, 122, + 143, 133, 102, 252, 252, 195, 15, 104, 73, 126, 62, 26, 210, 165, 139, 85, 87, 242, 172, 15, 197, 196, 82, + 226, 56, 98, 233, 215, 136, 15, 238, 160, 20, 78, 152, 96, 157, 51, 12, 26, 167, 154, 154, 154, 158, 124, + 249, 229, 151, 67, 251, 244, 233, 67, 244, 240, 243, 176, 15, 244, 190, 127, 213, 168, 255, 229, 23, 244, + 202, 211, 79, 163, 248, 144, 144, 54, 221, 153, 222, 195, 48, 195, 49, 119, 11, 144, 215, 226, 233, 215, + 99, 169, 15, 250, 147, 53, 2, 207, 25, 127, 155, 53, 11, 253, 132, 189, 100, 208, 56, 210, 208, 208, 48, + 189, 184, 184, 56, 128, 245, 147, 37, 62, 240, 10, 253, 79, 55, 52, 160, 85, 75, 150, 160, 145, 56, 159, + 235, 75, 231, 121, 166, 123, 60, 213, 121, 4, 102, 36, 102, 20, 37, 137, 254, 157, 72, 191, 150, 64, 189, + 192, 124, 16, 77, 215, 132, 97, 93, 187, 162, 149, 207, 62, 139, 254, 248, 253, 119, 189, 111, 83, 45, 246, + 124, 251, 237, 183, 214, 126, 114, 64, 64, 128, 162, 184, 255, 236, 137, 222, 247, 219, 22, 77, 231, 207, + 163, 119, 95, 123, 13, 165, 134, 133, 89, 117, 31, 68, 231, 242, 97, 156, 238, 76, 243, 209, 152, 20, 76, + 42, 38, 141, 146, 74, 95, 27, 77, 253, 144, 40, 241, 1, 241, 18, 121, 239, 20, 252, 25, 31, 188, 254, 58, + 186, 208, 220, 172, 247, 109, 203, 130, 212, 220, 31, 127, 241, 197, 23, 49, 169, 169, 169, 76, 39, 119, + 173, 9, 122, 223, 43, 186, 136, 243, 143, 13, 107, 214, 160, 140, 126, 253, 172, 207, 104, 36, 213, 61, 78, + 162, 123, 50, 213, 121, 12, 102, 28, 102, 188, 64, 58, 102, 44, 245, 67, 50, 245, 193, 72, 234, 131, 120, + 250, 158, 67, 233, 103, 144, 207, 50, 71, 70, 162, 109, 235, 215, 163, 43, 87, 12, 217, 230, 32, 230, 92, + 85, 81, 81, 209, 151, 230, 136, 238, 168, 21, 116, 187, 57, 114, 70, 224, 211, 117, 235, 208, 164, 168, 40, + 171, 22, 17, 18, 221, 71, 8, 186, 143, 165, 26, 79, 192, 220, 131, 201, 196, 76, 164, 100, 210, 215, 50, + 168, 23, 100, 62, 184, 91, 240, 193, 157, 52, 63, 152, 153, 148, 132, 170, 62, 255, 92, 183, 177, 176, 17, + 13, 56, 71, 95, 92, 90, 90, 218, 211, 100, 50, 17, 205, 92, 89, 43, 232, 114, 67, 164, 46, 155, 54, 124, + 184, 117, 236, 7, 98, 98, 232, 252, 60, 76, 208, 125, 180, 160, 123, 6, 167, 185, 25, 147, 141, 201, 161, + 100, 211, 215, 178, 232, 247, 200, 124, 48, 138, 243, 1, 91, 19, 200, 103, 15, 32, 254, 243, 241, 65, 79, + 78, 158, 140, 106, 15, 29, 210, 101, 76, 236, 136, 31, 27, 27, 27, 11, 22, 45, 90, 116, 195, 77, 55, 221, + 164, 40, 174, 57, 115, 224, 209, 27, 32, 61, 187, 71, 82, 83, 219, 106, 179, 24, 229, 106, 62, 207, 116, + 79, 228, 116, 31, 35, 232, 158, 197, 105, 62, 9, 115, 175, 192, 100, 250, 122, 182, 224, 3, 182, 46, 164, + 210, 247, 30, 69, 63, 139, 249, 128, 92, 3, 169, 21, 72, 95, 33, 38, 40, 8, 189, 48, 103, 14, 250, 245, + 228, 73, 143, 142, 141, 3, 65, 206, 206, 231, 20, 22, 22, 250, 177, 51, 7, 74, 199, 126, 178, 189, 94, 240, + 200, 5, 31, 218, 183, 15, 61, 110, 54, 91, 159, 177, 1, 116, 172, 217, 243, 62, 92, 67, 119, 54, 207, 243, + 186, 79, 166, 90, 79, 193, 220, 71, 185, 159, 251, 111, 230, 5, 209, 7, 19, 232, 123, 146, 247, 78, 161, + 159, 197, 234, 5, 62, 71, 36, 117, 38, 89, 143, 70, 224, 250, 163, 244, 133, 23, 80, 227, 153, 51, 30, 25, + 35, 39, 226, 191, 213, 213, 213, 137, 57, 57, 57, 236, 247, 158, 56, 179, 38, 184, 245, 2, 73, 207, 110, + 222, 244, 233, 40, 10, 215, 223, 253, 37, 186, 39, 80, 13, 146, 168, 38, 44, 175, 155, 32, 204, 243, 188, + 238, 76, 239, 7, 84, 96, 94, 152, 162, 225, 131, 113, 156, 15, 212, 106, 5, 210, 87, 238, 75, 60, 115, 251, + 237, 232, 227, 183, 223, 70, 45, 151, 46, 185, 117, 172, 156, 12, 210, 228, 126, 175, 178, 178, 50, 194, + 201, 243, 201, 110, 185, 168, 147, 199, 142, 161, 37, 5, 5, 109, 61, 187, 104, 229, 106, 13, 47, 211, 61, + 77, 185, 154, 207, 223, 99, 135, 238, 83, 109, 192, 251, 128, 173, 11, 57, 244, 61, 39, 210, 207, 24, 79, + 63, 51, 141, 243, 129, 44, 71, 140, 80, 174, 246, 147, 43, 43, 42, 220, 50, 94, 46, 136, 115, 173, 173, + 173, 175, 172, 91, 183, 238, 150, 193, 131, 7, 19, 93, 237, 205, 17, 93, 122, 17, 245, 117, 117, 104, 249, + 220, 185, 40, 62, 52, 212, 250, 236, 176, 158, 29, 171, 225, 19, 232, 24, 187, 74, 247, 105, 18, 120, 15, + 56, 234, 3, 49, 71, 228, 125, 64, 242, 21, 146, 171, 22, 164, 167, 163, 131, 123, 247, 186, 116, 220, 92, + 24, 117, 184, 86, 120, 122, 249, 242, 229, 161, 97, 97, 97, 246, 248, 192, 37, 31, 122, 198, 98, 65, 171, + 158, 123, 14, 37, 246, 236, 217, 214, 179, 227, 107, 57, 94, 247, 100, 137, 238, 153, 18, 221, 217, 250, + 206, 116, 180, 165, 187, 61, 62, 96, 107, 2, 243, 65, 22, 245, 1, 95, 43, 168, 229, 136, 237, 250, 201, + 126, 126, 104, 126, 94, 30, 58, 97, 220, 115, 49, 53, 22, 139, 101, 70, 73, 73, 73, 0, 119, 230, 64, 246, + 179, 75, 215, 244, 33, 172, 103, 151, 118, 235, 173, 86, 221, 7, 43, 237, 123, 181, 50, 221, 199, 218, 120, + 222, 175, 85, 119, 153, 7, 120, 31, 104, 229, 6, 172, 86, 24, 195, 249, 64, 150, 27, 144, 245, 140, 212, + 10, 164, 159, 188, 162, 164, 4, 89, 234, 235, 93, 36, 155, 203, 227, 127, 181, 181, 181, 233, 51, 103, 206, + 84, 216, 239, 61, 81, 218, 159, 57, 112, 234, 77, 89, 207, 110, 130, 157, 61, 59, 94, 119, 86, 203, 177, + 250, 157, 213, 113, 76, 119, 217, 92, 239, 168, 238, 182, 124, 192, 231, 136, 178, 154, 81, 173, 86, 96, + 62, 96, 123, 141, 44, 71, 76, 238, 211, 7, 189, 183, 114, 37, 106, 118, 255, 239, 174, 112, 38, 72, 115, + 115, 99, 85, 85, 85, 108, 90, 90, 26, 155, 247, 153, 15, 28, 122, 163, 203, 173, 173, 104, 235, 71, 31, + 161, 201, 119, 221, 101, 245, 191, 168, 187, 51, 207, 59, 171, 219, 120, 205, 121, 237, 166, 187, 8, 153, + 31, 236, 169, 21, 120, 31, 136, 181, 2, 243, 1, 217, 171, 32, 207, 65, 86, 68, 4, 250, 20, 143, 207, 21, + 99, 254, 252, 19, 217, 232, 95, 189, 109, 219, 54, 83, 116, 116, 52, 203, 13, 236, 254, 199, 187, 182, 108, + 65, 211, 105, 207, 142, 244, 77, 89, 239, 198, 158, 231, 125, 162, 210, 177, 126, 23, 159, 117, 119, 104, + 110, 175, 23, 196, 252, 192, 209, 154, 81, 236, 39, 63, 152, 152, 136, 246, 238, 220, 233, 54, 33, 175, 49, + 44, 205, 205, 205, 127, 95, 179, 102, 77, 47, 147, 201, 100, 243, 155, 89, 207, 142, 228, 190, 172, 87, + 171, 181, 55, 35, 234, 206, 158, 119, 54, 207, 235, 169, 187, 45, 31, 104, 205, 7, 247, 112, 62, 208, 218, + 87, 32, 227, 67, 106, 5, 82, 55, 62, 57, 105, 18, 250, 222, 192, 253, 228, 243, 231, 213, 143, 125, 89, + 123, 118, 89, 89, 109, 61, 59, 89, 175, 86, 182, 55, 195, 247, 106, 141, 242, 188, 59, 226, 3, 173, 252, + 128, 175, 25, 213, 246, 21, 152, 15, 88, 173, 64, 122, 32, 207, 23, 22, 162, 186, 159, 127, 246, 160, 180, + 206, 7, 235, 217, 145, 26, 135, 245, 236, 100, 186, 171, 237, 205, 176, 94, 45, 159, 215, 25, 85, 119, 123, + 214, 4, 181, 222, 129, 88, 51, 50, 31, 136, 251, 10, 109, 253, 228, 110, 221, 208, 106, 92, 35, 159, 51, + 104, 63, 153, 244, 236, 158, 43, 40, 64, 49, 216, 175, 36, 183, 139, 86, 228, 123, 177, 106, 186, 219, 59, + 207, 243, 99, 158, 107, 48, 236, 89, 23, 108, 249, 64, 173, 119, 16, 69, 125, 144, 30, 30, 142, 54, 188, + 245, 150, 97, 250, 201, 228, 156, 29, 233, 217, 13, 15, 9, 105, 167, 187, 61, 207, 187, 152, 207, 243, 53, + 28, 211, 220, 200, 122, 219, 227, 5, 230, 7, 49, 79, 148, 249, 192, 214, 62, 35, 171, 21, 200, 56, 223, 55, + 116, 40, 250, 124, 211, 38, 189, 229, 183, 246, 236, 76, 212, 159, 90, 123, 177, 90, 235, 187, 172, 118, + 239, 172, 186, 219, 227, 3, 181, 249, 64, 171, 135, 196, 239, 51, 178, 90, 129, 228, 211, 249, 227, 198, + 161, 131, 95, 125, 165, 155, 254, 236, 124, 165, 76, 119, 182, 39, 199, 246, 98, 121, 221, 181, 230, 249, + 235, 69, 123, 153, 7, 100, 62, 96, 249, 129, 173, 222, 1, 201, 17, 249, 94, 34, 59, 123, 18, 133, 115, 173, + 5, 51, 102, 160, 227, 223, 127, 239, 113, 253, 101, 123, 240, 106, 186, 243, 121, 157, 55, 232, 110, 207, + 92, 32, 203, 19, 237, 169, 25, 217, 153, 68, 50, 254, 236, 236, 201, 176, 224, 96, 180, 226, 153, 103, 144, + 229, 183, 223, 60, 166, 63, 219, 139, 117, 86, 247, 235, 93, 115, 91, 94, 80, 243, 129, 172, 102, 180, 181, + 207, 200, 106, 133, 228, 222, 189, 209, 187, 43, 86, 160, 102, 141, 250, 220, 85, 97, 107, 158, 231, 215, + 119, 241, 89, 231, 199, 99, 134, 23, 34, 250, 65, 182, 46, 136, 61, 36, 123, 124, 64, 246, 21, 200, 124, + 144, 53, 112, 32, 218, 82, 86, 134, 220, 249, 251, 180, 180, 158, 119, 208, 221, 49, 31, 176, 57, 129, 223, + 95, 16, 123, 137, 90, 61, 36, 241, 44, 26, 217, 95, 33, 249, 65, 222, 136, 17, 232, 171, 29, 59, 220, 162, + 191, 120, 198, 78, 171, 142, 3, 221, 29, 243, 1, 223, 79, 228, 125, 160, 213, 59, 72, 84, 58, 214, 10, 164, + 78, 136, 244, 241, 65, 79, 100, 103, 163, 239, 190, 254, 218, 165, 250, 203, 116, 87, 123, 222, 249, 123, + 205, 51, 192, 120, 27, 9, 113, 60, 196, 117, 193, 150, 15, 180, 106, 70, 178, 46, 176, 90, 33, 38, 48, 240, + 207, 126, 178, 139, 126, 223, 5, 211, 157, 229, 116, 124, 30, 47, 222, 31, 224, 24, 188, 23, 196, 92, 145, + 207, 15, 100, 62, 80, 59, 163, 204, 246, 21, 70, 118, 239, 142, 86, 47, 89, 114, 205, 253, 100, 181, 231, + 29, 180, 119, 173, 7, 100, 62, 224, 231, 3, 181, 30, 146, 218, 25, 101, 82, 43, 144, 28, 145, 244, 147, + 203, 75, 75, 209, 37, 39, 255, 127, 57, 160, 187, 113, 124, 192, 159, 75, 228, 207, 29, 104, 245, 14, 72, + 173, 64, 230, 131, 251, 134, 12, 65, 59, 63, 249, 196, 97, 253, 65, 119, 253, 124, 32, 91, 19, 136, 15, + 156, 169, 25, 201, 121, 3, 210, 83, 206, 31, 51, 6, 29, 248, 242, 75, 187, 245, 7, 205, 245, 245, 1, 63, + 23, 176, 60, 209, 145, 222, 1, 219, 95, 34, 62, 32, 53, 35, 169, 21, 162, 124, 125, 209, 252, 220, 92, 244, + 227, 119, 223, 217, 212, 127, 38, 254, 254, 89, 128, 46, 204, 164, 60, 72, 97, 190, 200, 213, 240, 130, 44, + 79, 76, 82, 218, 231, 7, 236, 231, 21, 226, 73, 63, 121, 238, 92, 212, 240, 235, 175, 170, 250, 235, 61, 6, + 128, 186, 15, 248, 218, 145, 249, 128, 223, 115, 102, 123, 76, 178, 252, 128, 248, 128, 213, 140, 169, 164, + 159, 252, 234, 171, 210, 126, 178, 222, 247, 14, 200, 125, 192, 175, 19, 90, 62, 144, 229, 137, 163, 148, + 246, 235, 66, 52, 245, 129, 249, 142, 59, 80, 197, 7, 31, 88, 207, 113, 131, 254, 198, 69, 230, 3, 150, 39, + 240, 185, 162, 88, 47, 176, 252, 64, 118, 30, 141, 248, 128, 212, 10, 36, 63, 200, 75, 72, 64, 95, 110, + 223, 14, 250, 27, 28, 209, 7, 51, 4, 31, 240, 117, 163, 108, 111, 65, 236, 37, 178, 115, 72, 100, 95, 129, + 156, 67, 42, 54, 155, 117, 191, 71, 192, 62, 15, 200, 124, 32, 246, 15, 28, 201, 17, 73, 205, 56, 208, 0, + 247, 7, 56, 238, 5, 53, 31, 136, 181, 2, 235, 37, 138, 63, 187, 194, 231, 136, 122, 223, 19, 224, 188, 7, + 236, 173, 21, 180, 122, 137, 122, 223, 15, 224, 58, 31, 136, 251, 141, 178, 28, 81, 244, 193, 195, 64, 167, + 229, 33, 10, 239, 9, 113, 78, 96, 249, 1, 191, 215, 200, 251, 64, 239, 123, 0, 220, 227, 5, 123, 125, 160, + 247, 117, 3, 174, 247, 0, 243, 1, 63, 31, 200, 122, 202, 57, 6, 184, 102, 192, 115, 62, 32, 115, 129, 232, + 3, 189, 175, 21, 112, 191, 15, 196, 252, 128, 249, 128, 172, 9, 143, 0, 215, 61, 162, 31, 248, 117, 97, 54, + 224, 53, 136, 126, 152, 101, 128, 107, 2, 244, 245, 129, 222, 215, 2, 232, 235, 1, 189, 175, 3, 0, 0, 0, 0, + 0, 0, 240, 44, 143, 2, 94, 77, 62, 0, 0, 0, 0, 0, 0, 224, 85, 20, 0, 0, 0, 0, 0, 224, 117, 20, 2, 0, 0, 0, + 0, 0, 0, 94, 69, 17, 0, 0, 0, 0, 0, 0, 224, 85, 204, 1, 0, 0, 0, 0, 192, 235, 120, 28, 0, 0, 0, 0, 0, 0, + 240, 38, 254, 15, 6, 45, 191, 15, 128, 0, 108, 150, 0, 0, 1, 192, 109, 107, 66, 84, 250, 206, 202, 254, 0, + 127, 193, 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, 120, 156, 237, 210, 177, 13, 195, 48, 12, 69, 65, 43, 217, 127, 6, 53, 106, 172, 173, 60, 137, 227, 116, + 73, 151, 0, 6, 8, 138, 71, 224, 45, 240, 143, 219, 121, 158, 155, 36, 73, 146, 36, 73, 146, 36, 73, 90, + 171, 49, 198, 114, 245, 222, 183, 227, 56, 194, 183, 205, 208, 170, 183, 239, 123, 248, 182, 25, 106, 173, + 45, 215, 251, 230, 156, 225, 219, 102, 40, 218, 138, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, + 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, + 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 143, 222, 54, 67, + 209, 86, 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, + 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, + 63, 127, 254, 252, 249, 243, 231, 207, 159, 127, 244, 182, 25, 138, 182, 226, 207, 159, 63, 127, 254, 252, + 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, + 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, + 252, 163, 183, 205, 80, 180, 21, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, + 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 239, 235, 159, 139, 118, 229, 207, + 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, + 252, 249, 243, 143, 222, 54, 67, 252, 107, 199, 191, 118, 252, 107, 199, 191, 118, 252, 107, 199, 191, 118, + 252, 107, 199, 191, 118, 252, 107, 199, 191, 118, 252, 75, 215, 62, 142, 127, 189, 30, 237, 251, 248, 23, + 235, 186, 231, 181, 217, 79, 127, 16, 237, 202, 255, 246, 94, 71, 104, 96, 169, 121, 252, 177, 241, 0, 0, + 1, 51, 109, 107, 66, 84, 250, 206, 202, 254, 0, 127, 204, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 208, 1, 13, 192, 64, 16, 195, 176, 231, + 79, 250, 198, 98, 173, 84, 71, 50, 129, 188, 87, 214, 221, 241, 163, 182, 210, 63, 214, 180, 149, 254, 177, + 166, 173, 244, 143, 53, 109, 165, 127, 172, 105, 43, 253, 99, 77, 91, 233, 31, 107, 218, 74, 255, 88, 211, + 86, 250, 199, 154, 182, 210, 63, 214, 180, 149, 254, 177, 166, 173, 244, 143, 53, 109, 165, 127, 172, 105, + 43, 253, 99, 77, 91, 233, 31, 107, 218, 74, 255, 88, 211, 86, 250, 199, 154, 182, 210, 63, 214, 180, 149, + 254, 177, 166, 173, 244, 143, 53, 109, 165, 127, 172, 105, 43, 253, 99, 77, 91, 233, 31, 107, 218, 74, 255, + 88, 211, 86, 250, 199, 154, 182, 210, 63, 214, 180, 149, 254, 177, 166, 173, 244, 143, 53, 109, 165, 127, + 172, 105, 43, 253, 99, 77, 91, 233, 31, 107, 218, 74, 255, 88, 211, 86, 250, 199, 154, 182, 210, 63, 214, + 180, 149, 254, 177, 166, 173, 244, 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, 32, 238, 3, 173, 11, 41, 129, 134, 127, + 239, 241, 0, 0, 20, 182, 109, 107, 66, 84, 250, 206, 202, 254, 0, 127, 205, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 93, 7, 120, 149, 229, + 21, 254, 163, 128, 213, 106, 109, 43, 109, 181, 162, 240, 168, 29, 86, 75, 165, 69, 91, 68, 72, 48, 17, 51, + 48, 128, 33, 6, 194, 16, 40, 4, 194, 18, 8, 217, 36, 64, 2, 4, 18, 150, 66, 17, 180, 66, 144, 85, 212, 178, + 65, 130, 140, 166, 160, 136, 32, 72, 217, 67, 68, 54, 97, 8, 100, 15, 56, 61, 231, 207, 57, 201, 151, 203, + 205, 186, 36, 249, 185, 201, 119, 158, 231, 125, 8, 247, 249, 147, 251, 253, 223, 123, 230, 55, 1, 20, 217, + 149, 154, 10, 3, 218, 180, 129, 231, 12, 195, 68, 75, 68, 107, 132, 27, 194, 29, 209, 22, 225, 141, 104, + 135, 232, 128, 240, 67, 188, 129, 232, 130, 232, 134, 120, 19, 209, 27, 209, 7, 17, 132, 232, 135, 8, 70, + 12, 64, 12, 68, 12, 66, 12, 102, 12, 209, 184, 35, 64, 114, 112, 231, 78, 8, 245, 245, 133, 191, 184, 184, + 20, 241, 238, 138, 104, 131, 240, 64, 188, 202, 188, 191, 134, 232, 136, 232, 132, 8, 64, 4, 34, 186, 35, + 122, 50, 239, 125, 153, 243, 254, 118, 56, 151, 239, 123, 75, 227, 142, 66, 76, 96, 32, 252, 181, 94, 61, + 248, 19, 254, 252, 162, 81, 104, 239, 194, 59, 217, 187, 23, 243, 46, 246, 46, 188, 219, 218, 187, 230, + 221, 57, 209, 20, 209, 194, 184, 213, 207, 19, 239, 228, 231, 219, 27, 37, 253, 124, 119, 227, 86, 63, 175, + 121, 119, 94, 148, 198, 187, 216, 187, 191, 81, 50, 190, 247, 66, 252, 93, 243, 94, 107, 32, 188, 123, 26, + 197, 246, 254, 186, 13, 239, 61, 152, 119, 219, 188, 206, 30, 239, 154, 123, 231, 2, 241, 238, 131, 240, + 85, 120, 239, 140, 232, 170, 240, 46, 246, 110, 143, 119, 225, 222, 234, 247, 208, 112, 12, 229, 241, 46, + 57, 189, 212, 113, 246, 106, 56, 171, 223, 65, 195, 113, 116, 178, 225, 189, 103, 41, 188, 235, 24, 95, 59, + 97, 207, 207, 247, 55, 74, 143, 239, 242, 123, 67, 53, 106, 5, 212, 250, 221, 214, 199, 11, 223, 242, 236, + 48, 141, 90, 7, 181, 142, 211, 188, 215, 61, 104, 222, 235, 54, 52, 239, 117, 27, 154, 247, 186, 13, 205, + 187, 134, 134, 134, 134, 134, 134, 134, 70, 221, 66, 136, 134, 134, 134, 134, 134, 134, 70, 157, 67, 168, + 134, 134, 134, 134, 134, 134, 134, 134, 70, 157, 66, 152, 134, 134, 134, 134, 134, 134, 70, 157, 67, 184, + 134, 134, 134, 134, 134, 134, 134, 134, 70, 157, 66, 132, 134, 134, 134, 134, 130, 210, 106, 67, 171, 219, + 165, 81, 189, 32, 142, 35, 239, 190, 27, 70, 222, 119, 31, 68, 223, 123, 47, 68, 214, 175, 15, 225, 119, + 221, 5, 161, 46, 46, 230, 90, 17, 90, 47, 74, 251, 133, 228, 12, 0, 245, 76, 0, 217, 71, 52, 28, 49, 194, + 40, 156, 91, 208, 186, 227, 28, 16, 142, 136, 187, 164, 223, 255, 30, 46, 29, 59, 6, 87, 78, 156, 128, 243, + 251, 246, 193, 153, 221, 187, 225, 228, 246, 237, 240, 237, 127, 254, 3, 135, 214, 173, 131, 189, 75, 151, + 194, 142, 228, 100, 216, 58, 125, 58, 108, 136, 139, 131, 85, 195, 135, 195, 71, 189, 122, 193, 188, 142, + 29, 225, 93, 87, 87, 152, 252, 236, 179, 48, 254, 241, 199, 33, 246, 193, 7, 77, 221, 9, 97, 221, 176, 213, + 19, 210, 17, 241, 49, 86, 191, 191, 70, 33, 15, 196, 213, 232, 134, 13, 33, 61, 45, 13, 110, 71, 114, 211, + 211, 225, 218, 233, 211, 112, 225, 192, 1, 248, 118, 243, 102, 216, 189, 120, 49, 164, 78, 158, 12, 43, + 134, 12, 49, 245, 100, 250, 11, 47, 192, 184, 70, 141, 32, 250, 71, 63, 50, 245, 64, 124, 202, 80, 163, + 120, 77, 154, 232, 69, 164, 70, 181, 34, 138, 255, 165, 190, 54, 227, 62, 250, 250, 179, 255, 251, 223, + 109, 241, 95, 174, 220, 188, 9, 185, 25, 25, 112, 249, 248, 113, 248, 110, 203, 22, 248, 122, 222, 60, 72, + 137, 142, 134, 133, 254, 254, 240, 78, 179, 102, 16, 143, 58, 24, 161, 196, 156, 16, 110, 27, 181, 51, 90, + 163, 74, 17, 101, 20, 219, 63, 217, 34, 249, 233, 3, 159, 126, 90, 189, 252, 151, 163, 27, 25, 23, 47, 194, + 153, 175, 191, 134, 221, 11, 23, 194, 186, 136, 8, 72, 246, 241, 129, 196, 39, 159, 132, 232, 6, 13, 74, + 232, 68, 56, 183, 223, 234, 62, 116, 102, 68, 114, 63, 146, 207, 165, 248, 79, 231, 0, 109, 199, 248, 126, + 167, 73, 126, 78, 14, 92, 60, 124, 24, 246, 45, 91, 6, 235, 71, 142, 132, 185, 94, 94, 144, 240, 232, 163, + 166, 159, 24, 206, 109, 23, 31, 81, 215, 116, 130, 222, 91, 242, 169, 202, 190, 187, 248, 125, 201, 211, + 232, 44, 168, 245, 137, 137, 86, 211, 93, 33, 161, 60, 227, 52, 250, 137, 237, 179, 102, 193, 146, 238, + 221, 97, 50, 230, 174, 81, 245, 234, 221, 162, 15, 86, 243, 83, 213, 16, 159, 77, 239, 72, 118, 251, 78, + 211, 166, 176, 227, 253, 247, 97, 75, 82, 146, 25, 191, 197, 47, 86, 68, 23, 84, 219, 39, 223, 79, 231, + 255, 253, 59, 60, 220, 106, 106, 29, 146, 27, 121, 121, 112, 97, 255, 126, 216, 49, 103, 14, 124, 212, 163, + 7, 36, 61, 245, 20, 68, 96, 13, 82, 27, 226, 133, 240, 73, 92, 145, 157, 198, 252, 248, 199, 176, 40, 32, + 0, 142, 110, 216, 0, 55, 242, 243, 139, 250, 96, 231, 7, 31, 64, 24, 214, 240, 97, 202, 239, 148, 245, 206, + 18, 247, 233, 111, 210, 57, 80, 116, 22, 224, 188, 160, 32, 11, 89, 172, 58, 41, 192, 152, 113, 102, 215, + 46, 216, 130, 181, 199, 28, 140, 23, 113, 63, 255, 121, 81, 254, 224, 44, 190, 65, 181, 117, 179, 62, 71, + 157, 222, 24, 31, 111, 214, 231, 165, 201, 78, 140, 223, 161, 168, 3, 35, 140, 226, 120, 88, 154, 14, 136, + 239, 167, 250, 139, 206, 2, 163, 243, 158, 103, 162, 94, 213, 70, 161, 188, 114, 255, 242, 229, 240, 239, + 190, 125, 33, 241, 137, 39, 76, 91, 26, 198, 54, 117, 39, 229, 13, 194, 87, 24, 219, 101, 36, 230, 189, + 115, 189, 189, 205, 182, 83, 30, 84, 17, 217, 251, 201, 39, 16, 118, 207, 61, 229, 234, 64, 152, 81, 236, + 251, 233, 252, 71, 186, 219, 97, 90, 135, 14, 213, 204, 132, 245, 146, 159, 157, 109, 214, 158, 159, 98, + 125, 49, 245, 153, 103, 204, 177, 42, 43, 117, 65, 248, 137, 100, 123, 164, 182, 140, 199, 252, 118, 109, + 88, 24, 164, 29, 60, 232, 208, 59, 210, 88, 93, 40, 234, 64, 72, 25, 58, 160, 242, 223, 159, 249, 159, 216, + 182, 109, 153, 127, 247, 218, 165, 75, 144, 50, 127, 62, 132, 122, 122, 66, 172, 159, 31, 108, 193, 156, + 60, 243, 218, 53, 135, 218, 120, 39, 8, 197, 79, 170, 55, 215, 199, 198, 154, 186, 64, 57, 148, 196, 136, + 154, 208, 3, 250, 142, 112, 230, 60, 28, 253, 246, 236, 214, 173, 97, 23, 246, 111, 206, 245, 235, 183, + 253, 110, 187, 255, 245, 47, 24, 134, 186, 173, 250, 1, 245, 187, 101, 220, 79, 181, 255, 68, 228, 213, 86, + 114, 50, 51, 97, 251, 218, 181, 48, 14, 243, 108, 223, 134, 13, 225, 121, 124, 238, 5, 198, 223, 16, 157, + 126, 253, 107, 72, 234, 211, 7, 118, 126, 246, 25, 228, 162, 109, 57, 171, 144, 46, 156, 252, 242, 75, 88, + 19, 18, 2, 73, 24, 35, 70, 176, 125, 68, 112, 127, 141, 172, 66, 72, 62, 71, 188, 211, 152, 215, 242, 1, 3, + 224, 244, 206, 157, 85, 254, 78, 52, 94, 31, 66, 243, 56, 70, 201, 156, 103, 164, 29, 254, 41, 254, 143, + 115, 115, 51, 127, 239, 230, 205, 155, 112, 8, 251, 98, 214, 176, 97, 208, 181, 73, 19, 243, 126, 32, 226, + 253, 37, 163, 240, 142, 32, 129, 27, 127, 246, 60, 235, 66, 151, 39, 159, 132, 73, 253, 251, 195, 254, 109, + 219, 170, 252, 93, 106, 82, 242, 80, 143, 143, 164, 164, 152, 181, 4, 229, 142, 50, 183, 21, 101, 56, 174, + 11, 209, 70, 201, 218, 109, 70, 243, 230, 176, 109, 230, 76, 200, 68, 159, 90, 157, 242, 37, 214, 135, 67, + 237, 248, 52, 201, 255, 37, 255, 163, 250, 47, 226, 233, 167, 97, 249, 132, 9, 16, 210, 172, 25, 120, 161, + 47, 108, 197, 28, 123, 216, 224, 21, 134, 252, 255, 101, 126, 142, 238, 20, 242, 252, 197, 47, 96, 199, + 250, 245, 213, 250, 78, 53, 41, 148, 59, 238, 192, 218, 106, 182, 171, 43, 68, 242, 24, 67, 184, 141, 45, + 149, 197, 185, 228, 115, 100, 235, 163, 126, 242, 19, 88, 210, 173, 27, 28, 79, 77, 133, 155, 55, 110, 212, + 216, 59, 164, 78, 157, 106, 218, 185, 170, 3, 17, 70, 113, 253, 71, 231, 189, 211, 121, 208, 84, 3, 182, + 55, 10, 239, 253, 162, 251, 33, 232, 94, 24, 186, 255, 205, 75, 129, 183, 205, 103, 116, 143, 136, 59, 219, + 127, 244, 107, 175, 193, 149, 243, 231, 107, 236, 189, 106, 90, 206, 237, 217, 3, 107, 70, 140, 128, 132, + 70, 141, 76, 223, 41, 177, 213, 94, 108, 151, 124, 142, 48, 5, 237, 42, 53, 49, 209, 156, 27, 179, 74, 82, + 70, 141, 50, 207, 252, 149, 177, 144, 8, 37, 6, 209, 231, 148, 3, 246, 230, 56, 208, 217, 40, 188, 31, 130, + 238, 7, 233, 192, 58, 209, 158, 127, 38, 116, 84, 62, 55, 239, 16, 170, 95, 31, 150, 36, 36, 88, 246, 110, + 53, 45, 148, 159, 125, 179, 104, 17, 252, 211, 195, 195, 92, 43, 161, 142, 43, 136, 173, 211, 58, 138, 15, + 177, 158, 58, 180, 102, 13, 20, 228, 230, 90, 221, 100, 83, 150, 14, 30, 92, 164, 3, 209, 54, 58, 64, 99, + 64, 253, 88, 7, 200, 15, 116, 53, 10, 239, 129, 234, 194, 250, 208, 153, 127, 14, 100, 116, 102, 255, 16, + 212, 184, 49, 236, 221, 188, 217, 234, 87, 179, 76, 206, 237, 221, 11, 171, 49, 79, 26, 255, 240, 195, 166, + 173, 79, 196, 124, 137, 230, 41, 46, 29, 61, 106, 117, 211, 110, 21, 204, 235, 230, 7, 4, 152, 49, 95, 242, + 80, 117, 28, 112, 32, 251, 129, 62, 172, 7, 61, 237, 160, 23, 235, 135, 63, 98, 146, 183, 55, 92, 61, 119, + 206, 234, 183, 186, 35, 132, 242, 132, 163, 88, 3, 101, 95, 189, 106, 117, 83, 202, 148, 60, 172, 231, 102, + 181, 105, 3, 49, 74, 156, 82, 231, 129, 200, 15, 12, 96, 61, 232, 199, 121, 129, 10, 243, 190, 24, 172, 85, + 87, 199, 199, 155, 117, 130, 22, 231, 147, 116, 204, 209, 98, 21, 31, 160, 206, 5, 82, 44, 144, 53, 126, + 114, 223, 215, 32, 246, 13, 116, 79, 80, 228, 99, 143, 193, 161, 13, 27, 172, 126, 5, 45, 183, 41, 163, + 144, 75, 209, 1, 241, 3, 225, 70, 241, 156, 50, 233, 130, 204, 61, 188, 197, 190, 96, 150, 151, 23, 92, 59, + 123, 214, 234, 166, 107, 169, 2, 33, 254, 9, 49, 70, 201, 90, 85, 213, 3, 153, 135, 24, 134, 117, 239, 103, + 218, 223, 215, 42, 25, 205, 252, 139, 31, 176, 213, 131, 8, 182, 251, 120, 244, 247, 148, 215, 104, 169, + 93, 162, 242, 111, 171, 3, 145, 108, 247, 115, 48, 191, 191, 174, 253, 125, 173, 20, 226, 223, 158, 15, 48, + 215, 95, 99, 126, 191, 73, 251, 251, 90, 45, 99, 144, 231, 49, 172, 3, 162, 7, 20, 239, 105, 109, 229, 49, + 237, 239, 107, 189, 168, 252, 143, 226, 152, 63, 199, 221, 29, 174, 157, 57, 99, 117, 211, 180, 212, 128, + 168, 220, 203, 56, 192, 73, 39, 159, 183, 213, 82, 113, 17, 191, 31, 203, 220, 71, 97, 204, 79, 59, 124, + 216, 234, 102, 105, 169, 33, 17, 238, 101, 45, 72, 204, 3, 15, 192, 85, 11, 231, 39, 181, 212, 172, 8, 255, + 209, 60, 222, 23, 135, 121, 95, 214, 15, 63, 88, 221, 44, 167, 151, 156, 172, 44, 184, 236, 4, 115, 98, 50, + 246, 23, 197, 99, 254, 9, 79, 63, 13, 5, 202, 126, 2, 45, 142, 201, 156, 49, 99, 160, 45, 250, 210, 149, + 239, 189, 87, 163, 107, 124, 42, 43, 163, 140, 226, 53, 0, 52, 199, 51, 229, 197, 23, 173, 110, 146, 211, + 203, 87, 41, 41, 208, 170, 94, 61, 115, 109, 236, 95, 104, 252, 212, 205, 13, 142, 238, 222, 109, 117, 179, + 236, 138, 228, 125, 84, 243, 211, 250, 207, 217, 117, 96, 237, 127, 117, 202, 197, 83, 167, 192, 175, 113, + 99, 115, 173, 44, 173, 135, 164, 245, 177, 127, 165, 127, 27, 52, 128, 217, 225, 225, 144, 89, 5, 107, 186, + 171, 82, 98, 120, 156, 151, 98, 127, 95, 196, 162, 1, 3, 172, 110, 146, 211, 10, 249, 249, 112, 111, 111, + 115, 13, 228, 43, 54, 32, 61, 32, 127, 208, 237, 169, 167, 96, 235, 138, 21, 86, 55, 181, 72, 70, 178, 239, + 15, 225, 121, 253, 213, 24, 183, 180, 56, 38, 243, 176, 239, 90, 96, 31, 190, 106, 148, 92, 35, 75, 240, + 228, 207, 91, 27, 133, 107, 229, 71, 251, 249, 193, 185, 239, 190, 179, 186, 201, 69, 117, 223, 112, 230, + 127, 235, 220, 185, 86, 55, 201, 41, 101, 199, 186, 117, 224, 113, 247, 221, 38, 199, 180, 110, 90, 214, + 201, 170, 107, 100, 95, 99, 93, 160, 103, 40, 62, 180, 251, 233, 79, 225, 227, 201, 147, 33, 223, 194, 117, + 161, 178, 7, 76, 246, 254, 31, 208, 107, 122, 42, 45, 105, 39, 79, 66, 151, 199, 31, 55, 253, 60, 241, 236, + 103, 20, 174, 139, 12, 48, 10, 215, 199, 210, 191, 111, 240, 231, 29, 21, 61, 144, 245, 242, 193, 205, 155, + 195, 222, 173, 91, 45, 105, 187, 228, 126, 180, 206, 107, 32, 230, 172, 167, 247, 238, 181, 164, 29, 206, + 42, 52, 55, 26, 237, 227, 99, 198, 247, 142, 204, 59, 173, 143, 166, 245, 243, 180, 62, 246, 77, 254, 183, + 187, 81, 184, 94, 58, 128, 245, 128, 124, 66, 59, 142, 19, 230, 254, 26, 244, 29, 211, 130, 131, 205, 189, + 149, 53, 41, 100, 255, 180, 246, 155, 214, 246, 133, 60, 244, 16, 164, 215, 240, 247, 59, 187, 124, 24, 27, + 107, 238, 121, 234, 192, 54, 78, 235, 229, 123, 114, 44, 165, 124, 90, 214, 203, 202, 90, 234, 55, 249, 25, + 210, 131, 215, 217, 95, 144, 30, 208, 254, 9, 202, 29, 252, 31, 125, 20, 62, 155, 63, 191, 198, 218, 47, + 241, 159, 248, 143, 163, 177, 159, 188, 188, 26, 251, 110, 103, 151, 237, 171, 86, 129, 167, 139, 139, 201, + 97, 0, 219, 56, 241, 222, 159, 251, 83, 206, 60, 124, 139, 199, 86, 212, 117, 245, 165, 233, 193, 203, 156, + 31, 70, 188, 250, 42, 156, 216, 191, 191, 218, 223, 97, 36, 251, 127, 106, 215, 116, 47, 175, 106, 255, + 190, 218, 34, 23, 78, 156, 128, 174, 141, 26, 153, 113, 252, 13, 133, 251, 96, 230, 93, 61, 7, 53, 148, + 127, 150, 125, 246, 180, 174, 94, 246, 216, 116, 231, 120, 225, 207, 241, 195, 151, 99, 2, 233, 128, 215, + 125, 247, 193, 188, 81, 163, 32, 59, 51, 179, 218, 222, 67, 242, 63, 242, 81, 139, 250, 247, 175, 182, 239, + 169, 77, 66, 117, 126, 180, 167, 167, 185, 231, 213, 159, 237, 184, 55, 219, 16, 241, 43, 103, 13, 169, + 123, 2, 213, 115, 214, 100, 175, 93, 48, 199, 136, 158, 70, 241, 126, 59, 63, 197, 23, 188, 194, 49, 161, + 215, 31, 254, 0, 59, 82, 82, 170, 229, 93, 100, 15, 58, 181, 99, 227, 180, 105, 213, 242, 29, 181, 69, 242, + 49, 54, 110, 91, 185, 18, 194, 220, 220, 204, 26, 206, 143, 57, 11, 100, 254, 7, 43, 220, 19, 231, 52, 182, + 106, 187, 174, 206, 118, 175, 149, 236, 183, 35, 223, 209, 131, 255, 214, 27, 28, 19, 200, 23, 248, 24, + 133, 123, 170, 93, 17, 9, 221, 186, 193, 197, 42, 158, 155, 141, 226, 182, 144, 238, 238, 193, 120, 166, + 229, 86, 185, 126, 249, 50, 44, 155, 62, 29, 250, 62, 243, 140, 201, 131, 43, 251, 104, 178, 211, 158, 13, + 26, 192, 88, 172, 223, 198, 62, 251, 172, 25, 223, 41, 214, 71, 48, 223, 52, 183, 58, 70, 129, 58, 215, 46, + 251, 173, 212, 152, 16, 100, 19, 19, 104, 239, 45, 229, 149, 84, 47, 210, 248, 81, 75, 138, 17, 13, 27, + 194, 138, 153, 51, 225, 70, 65, 65, 149, 188, 91, 164, 180, 1, 235, 143, 179, 146, 111, 208, 122, 207, 186, + 12, 150, 227, 88, 11, 207, 28, 54, 12, 58, 96, 159, 55, 51, 10, 199, 111, 201, 238, 255, 142, 57, 250, 100, + 127, 127, 216, 56, 123, 54, 156, 61, 112, 192, 252, 29, 218, 219, 123, 96, 237, 90, 115, 175, 239, 168, + 123, 239, 45, 92, 75, 129, 136, 67, 196, 51, 226, 20, 61, 144, 125, 119, 178, 255, 94, 141, 9, 182, 249, + 161, 26, 19, 220, 89, 15, 222, 106, 217, 18, 14, 239, 216, 81, 76, 164, 131, 239, 42, 235, 251, 163, 48, + 151, 201, 228, 121, 127, 170, 105, 111, 7, 165, 201, 237, 254, 221, 154, 128, 200, 166, 37, 75, 224, 77, + 172, 135, 40, 254, 122, 34, 159, 195, 95, 122, 9, 22, 140, 30, 13, 251, 82, 83, 33, 187, 156, 57, 28, 58, + 63, 125, 19, 62, 251, 246, 19, 79, 20, 157, 1, 17, 167, 232, 64, 156, 141, 47, 144, 152, 32, 231, 176, 13, + 52, 74, 238, 193, 182, 205, 15, 41, 231, 164, 49, 3, 143, 250, 245, 225, 93, 212, 207, 235, 87, 174, 56, + 220, 199, 225, 252, 125, 147, 148, 121, 223, 170, 226, 250, 6, 230, 73, 130, 242, 196, 106, 222, 109, 65, + 107, 32, 178, 210, 211, 225, 251, 131, 7, 225, 194, 247, 223, 223, 218, 222, 210, 218, 172, 60, 147, 151, + 149, 5, 7, 151, 45, 131, 133, 88, 87, 141, 197, 56, 17, 205, 185, 128, 232, 128, 26, 19, 108, 247, 225, + 151, 149, 31, 74, 76, 32, 95, 68, 250, 25, 216, 164, 9, 164, 126, 252, 177, 67, 125, 25, 206, 177, 127, 65, + 159, 62, 133, 191, 139, 92, 149, 7, 85, 168, 54, 57, 246, 205, 55, 176, 254, 195, 15, 225, 253, 200, 72, + 24, 27, 24, 8, 33, 30, 30, 16, 252, 252, 243, 16, 212, 172, 25, 4, 253, 249, 207, 38, 6, 163, 191, 138, + 240, 246, 134, 196, 222, 189, 205, 121, 146, 245, 243, 231, 195, 193, 237, 219, 225, 106, 41, 103, 205, 87, + 164, 29, 213, 9, 176, 163, 219, 149, 254, 27, 138, 164, 97, 156, 216, 16, 17, 1, 211, 30, 123, 172, 132, + 79, 16, 95, 32, 235, 112, 212, 51, 121, 134, 26, 197, 103, 114, 168, 49, 65, 242, 67, 138, 9, 148, 31, 182, + 97, 127, 16, 235, 235, 11, 167, 143, 28, 169, 84, 123, 35, 88, 207, 54, 113, 238, 175, 218, 172, 45, 68, + 104, 14, 251, 191, 75, 151, 66, 66, 247, 238, 166, 238, 185, 223, 117, 151, 57, 159, 65, 99, 217, 244, 239, + 75, 220, 158, 214, 10, 90, 113, 220, 82, 159, 107, 195, 249, 204, 160, 22, 45, 96, 198, 144, 33, 176, 249, + 163, 143, 224, 194, 201, 147, 183, 216, 89, 89, 109, 114, 6, 168, 126, 146, 206, 12, 217, 183, 120, 49, 44, + 112, 119, 135, 248, 122, 245, 76, 61, 24, 93, 74, 110, 80, 153, 58, 193, 155, 251, 189, 221, 3, 15, 192, + 226, 132, 132, 162, 51, 216, 202, 107, 91, 24, 251, 255, 67, 27, 55, 150, 250, 188, 180, 62, 237, 212, 41, + 152, 51, 114, 36, 116, 70, 29, 110, 201, 190, 135, 106, 19, 170, 83, 41, 63, 181, 61, 27, 200, 30, 212, + 243, 130, 104, 204, 211, 157, 245, 163, 5, 235, 71, 187, 251, 239, 135, 161, 173, 90, 193, 130, 113, 227, + 224, 200, 174, 93, 80, 160, 228, 185, 182, 49, 197, 25, 161, 202, 249, 61, 123, 32, 5, 227, 247, 212, 71, + 30, 49, 245, 32, 198, 176, 95, 39, 200, 153, 191, 164, 3, 114, 246, 66, 87, 206, 9, 218, 115, 191, 82, 95, + 190, 204, 253, 248, 39, 210, 145, 223, 254, 214, 60, 175, 175, 188, 126, 51, 239, 219, 64, 157, 185, 204, + 118, 103, 175, 189, 217, 25, 25, 176, 96, 236, 88, 240, 253, 217, 207, 76, 219, 109, 195, 177, 199, 155, + 253, 79, 59, 163, 248, 172, 40, 245, 124, 32, 117, 254, 83, 32, 103, 8, 249, 242, 239, 180, 227, 191, 33, + 115, 228, 30, 236, 43, 232, 61, 220, 177, 38, 233, 143, 177, 99, 225, 248, 241, 112, 82, 89, 147, 110, 53, + 135, 85, 237, 19, 178, 48, 127, 251, 38, 57, 25, 146, 49, 199, 28, 141, 190, 84, 238, 230, 144, 49, 164, + 72, 23, 23, 136, 188, 231, 30, 136, 68, 158, 162, 126, 249, 75, 136, 197, 188, 114, 76, 211, 166, 48, 22, + 115, 182, 9, 109, 219, 194, 84, 172, 69, 222, 13, 10, 130, 228, 176, 48, 88, 130, 118, 179, 114, 198, 12, + 88, 53, 107, 22, 124, 177, 114, 37, 228, 229, 228, 148, 233, 67, 41, 223, 76, 192, 191, 69, 99, 27, 55, 40, + 239, 65, 123, 35, 8, 247, 251, 191, 248, 2, 130, 254, 248, 199, 66, 62, 216, 118, 125, 140, 226, 57, 238, + 142, 236, 131, 58, 177, 62, 146, 79, 146, 121, 79, 91, 200, 60, 168, 63, 63, 239, 199, 191, 43, 58, 34, + 103, 141, 249, 240, 247, 180, 101, 223, 96, 174, 167, 193, 92, 55, 9, 115, 7, 202, 201, 72, 164, 157, 78, + 15, 197, 191, 82, 255, 127, 143, 253, 189, 237, 237, 183, 97, 247, 188, 121, 112, 16, 249, 251, 118, 211, + 38, 56, 245, 213, 87, 112, 30, 243, 208, 31, 208, 255, 102, 94, 190, 12, 217, 216, 7, 249, 21, 156, 167, + 33, 30, 203, 250, 126, 242, 253, 243, 186, 118, 45, 209, 167, 55, 88, 55, 215, 160, 14, 121, 161, 222, 185, + 41, 118, 46, 156, 119, 98, 62, 229, 44, 40, 202, 79, 105, 220, 130, 114, 20, 123, 231, 5, 9, 100, 62, 180, + 27, 251, 48, 57, 67, 42, 128, 245, 66, 230, 200, 101, 189, 132, 232, 2, 249, 5, 170, 191, 99, 176, 190, + 166, 177, 143, 155, 181, 73, 7, 108, 250, 189, 60, 185, 201, 80, 237, 213, 81, 16, 255, 155, 166, 76, 41, + 226, 95, 236, 254, 99, 244, 185, 175, 112, 223, 251, 218, 112, 30, 168, 112, 77, 53, 106, 31, 142, 75, 148, + 159, 80, 174, 58, 128, 49, 80, 129, 124, 22, 204, 207, 208, 243, 125, 141, 146, 103, 76, 137, 94, 116, 225, + 239, 145, 179, 231, 68, 23, 168, 45, 148, 55, 206, 197, 28, 164, 86, 249, 0, 11, 65, 121, 197, 145, 212, + 212, 162, 254, 36, 89, 49, 105, 146, 25, 143, 219, 43, 190, 61, 128, 237, 85, 56, 239, 203, 60, 18, 183, + 50, 215, 169, 222, 1, 72, 8, 81, 32, 159, 169, 119, 8, 14, 49, 138, 207, 153, 10, 54, 110, 157, 39, 23, 93, + 144, 181, 51, 237, 89, 7, 60, 177, 150, 222, 199, 235, 101, 242, 177, 78, 215, 112, 28, 49, 152, 79, 92, + 85, 206, 234, 252, 122, 245, 106, 232, 132, 57, 200, 235, 220, 239, 50, 191, 33, 188, 247, 99, 190, 6, 51, + 143, 50, 207, 169, 222, 229, 87, 214, 125, 99, 114, 215, 20, 61, 47, 243, 162, 234, 121, 83, 162, 15, 253, + 88, 23, 122, 25, 183, 206, 145, 82, 44, 8, 113, 115, 43, 202, 97, 172, 238, 67, 103, 198, 12, 87, 215, 66, + 219, 199, 159, 63, 69, 187, 239, 133, 245, 151, 248, 120, 89, 195, 212, 155, 109, 115, 0, 219, 172, 220, + 223, 40, 249, 41, 141, 95, 74, 253, 18, 107, 148, 156, 247, 178, 133, 204, 131, 73, 141, 107, 123, 255, + 156, 204, 147, 203, 216, 135, 140, 129, 245, 226, 246, 200, 122, 9, 202, 13, 183, 126, 242, 137, 246, 1, + 183, 137, 245, 113, 113, 144, 118, 252, 56, 36, 98, 45, 17, 200, 124, 75, 174, 38, 126, 94, 93, 211, 160, + 222, 155, 18, 195, 156, 202, 248, 133, 204, 115, 140, 45, 3, 246, 230, 66, 84, 189, 80, 231, 202, 213, 121, + 17, 138, 53, 50, 246, 65, 62, 137, 242, 194, 112, 212, 93, 202, 131, 242, 49, 110, 229, 97, 62, 172, 81, + 121, 208, 25, 144, 225, 15, 61, 100, 246, 109, 63, 230, 91, 214, 173, 5, 179, 63, 30, 202, 92, 68, 176, + 157, 199, 50, 119, 113, 204, 233, 56, 196, 120, 68, 2, 99, 66, 25, 144, 103, 198, 51, 198, 41, 122, 33, 58, + 161, 142, 133, 202, 252, 152, 156, 79, 222, 135, 117, 128, 252, 0, 229, 165, 123, 248, 204, 89, 171, 251, + 209, 89, 33, 231, 250, 201, 250, 52, 201, 211, 7, 241, 231, 114, 247, 102, 148, 194, 123, 188, 13, 231, + 196, 235, 68, 5, 137, 229, 64, 158, 179, 213, 11, 85, 31, 100, 92, 92, 214, 76, 200, 24, 152, 232, 0, 229, + 4, 84, 143, 78, 231, 121, 11, 171, 251, 209, 89, 161, 206, 63, 203, 90, 69, 201, 235, 66, 21, 155, 151, + 121, 171, 177, 204, 147, 202, 121, 105, 60, 39, 41, 168, 140, 78, 136, 46, 136, 30, 200, 30, 197, 80, 110, + 31, 249, 37, 138, 77, 148, 159, 246, 121, 228, 17, 248, 33, 45, 205, 172, 133, 243, 114, 115, 53, 42, 9, + 117, 61, 146, 64, 120, 143, 98, 251, 27, 173, 240, 158, 80, 10, 231, 73, 14, 162, 52, 93, 80, 245, 32, 222, + 40, 62, 155, 72, 238, 168, 149, 123, 10, 168, 30, 248, 146, 247, 211, 229, 226, 251, 104, 84, 14, 50, 247, + 44, 121, 184, 220, 11, 33, 185, 157, 216, 188, 202, 187, 45, 135, 147, 170, 0, 165, 233, 197, 68, 69, 7, + 98, 141, 226, 251, 20, 40, 86, 81, 28, 160, 90, 224, 189, 65, 131, 52, 255, 14, 66, 242, 45, 181, 110, 147, + 124, 222, 158, 205, 87, 53, 239, 229, 233, 131, 170, 3, 113, 70, 241, 217, 132, 20, 163, 228, 190, 178, + 176, 102, 205, 204, 119, 161, 120, 150, 155, 147, 163, 81, 9, 72, 140, 85, 161, 230, 244, 18, 231, 171, + 195, 230, 43, 163, 3, 19, 184, 93, 18, 7, 196, 7, 208, 184, 64, 239, 251, 239, 135, 51, 199, 142, 65, 1, + 230, 0, 57, 248, 78, 26, 21, 135, 228, 220, 2, 219, 156, 222, 54, 190, 215, 4, 239, 246, 116, 96, 34, 183, + 143, 244, 83, 246, 172, 80, 46, 72, 121, 0, 141, 7, 236, 92, 179, 198, 140, 1, 86, 247, 167, 179, 193, 94, + 141, 110, 155, 215, 215, 180, 221, 151, 230, 3, 72, 47, 37, 15, 160, 252, 148, 106, 22, 170, 5, 104, 44, + 96, 85, 82, 82, 33, 255, 217, 217, 26, 149, 128, 154, 107, 149, 197, 243, 100, 11, 33, 122, 32, 121, 192, + 24, 246, 1, 84, 167, 208, 184, 5, 205, 75, 125, 192, 119, 86, 103, 227, 59, 105, 84, 28, 21, 233, 255, 41, + 22, 67, 218, 65, 58, 32, 121, 128, 248, 0, 202, 3, 105, 172, 122, 178, 143, 15, 20, 176, 255, 183, 186, 79, + 157, 9, 119, 58, 247, 170, 14, 76, 50, 138, 243, 0, 170, 81, 100, 239, 10, 213, 129, 99, 154, 55, 135, 220, + 252, 124, 205, 191, 131, 252, 91, 205, 111, 101, 248, 151, 24, 32, 103, 86, 82, 14, 24, 245, 187, 223, 65, + 70, 122, 58, 228, 96, 29, 152, 149, 149, 165, 81, 65, 76, 197, 190, 115, 6, 136, 14, 80, 12, 144, 60, 144, + 198, 2, 228, 220, 186, 136, 38, 77, 224, 234, 165, 75, 144, 147, 151, 103, 121, 159, 58, 19, 172, 230, 181, + 50, 252, 79, 97, 31, 96, 155, 3, 12, 66, 132, 62, 252, 48, 92, 60, 115, 198, 140, 1, 86, 247, 169, 51, 193, + 106, 94, 43, 171, 3, 18, 3, 100, 44, 72, 206, 45, 13, 253, 213, 175, 204, 179, 23, 115, 201, 254, 51, 51, + 53, 42, 8, 171, 57, 117, 36, 6, 216, 230, 128, 52, 31, 20, 221, 184, 49, 92, 73, 75, 131, 108, 140, 255, + 153, 248, 94, 26, 21, 131, 213, 156, 58, 194, 63, 141, 85, 140, 103, 254, 163, 216, 254, 99, 127, 243, 27, + 184, 126, 245, 42, 100, 99, 254, 111, 117, 159, 58, 19, 166, 97, 223, 57, 11, 68, 7, 36, 7, 148, 26, 128, + 236, 127, 252, 115, 207, 65, 22, 214, 51, 20, 211, 50, 51, 50, 52, 42, 136, 183, 177, 239, 156, 5, 162, 3, + 146, 3, 202, 92, 0, 241, 255, 142, 135, 7, 228, 96, 238, 71, 58, 157, 129, 239, 165, 81, 49, 88, 205, 233, + 237, 240, 31, 207, 252, 83, 254, 159, 220, 163, 7, 208, 173, 5, 25, 154, 255, 58, 195, 191, 216, 63, 241, + 191, 34, 58, 218, 28, 255, 165, 49, 32, 141, 138, 195, 106, 78, 171, 130, 127, 202, 255, 62, 79, 78, 6, + 218, 17, 153, 142, 239, 164, 81, 113, 88, 205, 169, 35, 252, 75, 254, 71, 252, 155, 99, 192, 46, 46, 112, + 248, 243, 207, 33, 167, 160, 192, 242, 254, 116, 54, 188, 131, 253, 231, 44, 16, 29, 80, 237, 159, 234, + 255, 209, 52, 246, 119, 250, 52, 100, 98, 238, 159, 126, 253, 186, 70, 37, 96, 53, 167, 149, 229, 95, 252, + 191, 216, 63, 173, 1, 248, 135, 171, 43, 100, 230, 230, 154, 250, 124, 29, 223, 73, 163, 226, 176, 154, 83, + 71, 248, 39, 255, 47, 235, 65, 135, 35, 150, 135, 134, 154, 177, 223, 234, 190, 116, 66, 252, 31, 149, 129, + 56, 82, 187, 193, 120, 19, 0, 0, 12, 14, 109, 107, 66, 84, 250, 206, 202, 254, 0, 127, 207, 75, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 157, + 123, 112, 84, 103, 21, 192, 119, 41, 65, 48, 69, 5, 193, 40, 144, 2, 198, 18, 77, 140, 10, 42, 42, 18, 133, + 96, 193, 210, 144, 7, 224, 31, 34, 41, 78, 149, 167, 37, 65, 42, 83, 29, 129, 198, 182, 90, 30, 9, 149, 0, + 67, 152, 226, 56, 20, 104, 128, 254, 65, 74, 109, 121, 204, 4, 198, 177, 105, 29, 59, 101, 113, 42, 132, + 37, 176, 73, 118, 179, 217, 236, 35, 251, 222, 100, 55, 129, 124, 158, 67, 238, 45, 55, 203, 238, 178, 187, + 247, 114, 239, 62, 206, 157, 249, 77, 254, 201, 228, 143, 251, 203, 119, 206, 119, 206, 247, 184, 172, 78, + 165, 98, 200, 94, 142, 61, 192, 110, 224, 47, 192, 31, 129, 87, 11, 10, 152, 219, 237, 102, 30, 175, 247, + 238, 79, 49, 120, 189, 222, 1, 151, 203, 245, 108, 65, 65, 65, 145, 74, 165, 250, 158, 90, 173, 254, 26, + 48, 5, 248, 60, 144, 9, 140, 2, 70, 168, 135, 30, 85, 188, 224, 115, 234, 212, 41, 21, 99, 140, 136, 12, + 219, 15, 142, 145, 125, 220, 255, 193, 171, 2, 255, 191, 7, 222, 92, 179, 134, 249, 225, 247, 192, 155, + 104, 252, 126, 127, 135, 70, 163, 89, 54, 122, 244, 232, 249, 160, 232, 219, 224, 106, 6, 48, 9, 24, 7, + 124, 26, 24, 201, 249, 143, 219, 61, 249, 143, 221, 255, 62, 14, 126, 252, 239, 2, 94, 230, 252, 255, 231, + 216, 49, 214, 55, 56, 40, 137, 255, 193, 193, 193, 243, 245, 245, 245, 79, 128, 158, 31, 129, 167, 111, 2, + 95, 6, 178, 128, 207, 2, 163, 129, 71, 196, 142, 125, 242, 47, 206, 127, 45, 176, 19, 248, 19, 50, 118, 44, + 235, 108, 105, 97, 222, 222, 94, 230, 114, 58, 69, 51, 120, 231, 206, 158, 138, 149, 43, 49, 246, 255, 16, + 60, 125, 29, 152, 10, 76, 4, 198, 2, 159, 146, 34, 246, 147, 255, 248, 252, 99, 236, 255, 43, 80, 3, 188, + 2, 108, 5, 14, 206, 153, 195, 60, 62, 31, 115, 227, 248, 21, 233, 222, 235, 241, 248, 123, 108, 182, 13, + 51, 102, 204, 16, 230, 254, 108, 65, 238, 207, 32, 255, 202, 250, 15, 206, 253, 255, 120, 254, 121, 214, 7, + 191, 227, 4, 127, 98, 9, 4, 2, 173, 205, 205, 205, 101, 224, 135, 207, 253, 143, 135, 200, 253, 162, 221, + 147, 255, 216, 253, 239, 15, 242, 255, 50, 55, 247, 255, 248, 157, 119, 152, 175, 191, 159, 57, 29, 14, + 209, 64, 236, 63, 83, 91, 91, 43, 204, 253, 57, 192, 23, 5, 185, 255, 19, 255, 248, 144, 127, 121, 253, + 243, 115, 63, 204, 253, 213, 248, 115, 210, 36, 102, 49, 24, 152, 219, 227, 145, 196, 255, 64, 127, 255, + 43, 229, 101, 101, 11, 64, 205, 28, 46, 247, 79, 11, 202, 253, 143, 144, 127, 101, 252, 239, 227, 114, 63, + 206, 253, 118, 112, 99, 255, 245, 178, 50, 230, 133, 177, 239, 128, 216, 237, 0, 127, 98, 240, 192, 99, 52, + 26, 127, 157, 157, 157, 189, 32, 76, 238, 31, 86, 247, 147, 127, 101, 252, 243, 185, 255, 15, 192, 63, 247, + 238, 101, 189, 119, 238, 136, 118, 143, 64, 238, 255, 248, 194, 133, 11, 37, 160, 165, 40, 66, 238, 31, + 193, 187, 35, 255, 242, 250, 175, 19, 212, 253, 47, 97, 252, 207, 200, 96, 186, 15, 63, 100, 30, 168, 251, + 28, 118, 187, 104, 238, 220, 190, 221, 176, 109, 219, 182, 159, 4, 213, 253, 194, 220, 63, 44, 246, 147, + 127, 101, 252, 99, 238, 223, 142, 241, 96, 230, 204, 161, 184, 15, 216, 193, 159, 24, 112, 252, 251, 124, + 190, 173, 243, 230, 205, 19, 230, 254, 176, 117, 63, 249, 151, 223, 255, 222, 160, 220, 223, 88, 85, 197, + 124, 183, 111, 139, 118, 143, 64, 234, 183, 106, 181, 218, 149, 227, 199, 143, 71, 255, 179, 193, 207, 87, + 213, 195, 123, 254, 25, 228, 95, 57, 255, 124, 238, 175, 225, 114, 63, 246, 125, 174, 52, 54, 50, 143, 223, + 207, 236, 61, 61, 162, 233, 15, 4, 154, 223, 56, 126, 252, 73, 80, 130, 117, 255, 44, 65, 238, 255, 28, 48, + 70, 29, 212, 243, 39, 255, 242, 250, 231, 235, 126, 204, 253, 47, 114, 117, 159, 169, 163, 131, 57, 92, 46, + 214, 3, 254, 196, 50, 48, 48, 80, 191, 118, 237, 218, 224, 220, 143, 61, 255, 207, 132, 203, 253, 228, 95, + 25, 255, 219, 128, 163, 75, 151, 50, 119, 32, 32, 137, 123, 200, 253, 3, 86, 171, 181, 42, 63, 63, 31, 253, + 255, 0, 220, 228, 115, 185, 127, 2, 240, 168, 58, 68, 221, 71, 254, 229, 247, 207, 231, 126, 140, 253, 255, + 58, 112, 128, 121, 208, 191, 205, 38, 26, 159, 215, 123, 171, 249, 189, 247, 150, 141, 28, 57, 18, 253, + 127, 23, 220, 228, 114, 185, 127, 124, 164, 220, 79, 254, 229, 243, 191, 151, 203, 253, 127, 198, 218, 47, + 51, 147, 181, 93, 185, 194, 156, 110, 183, 36, 254, 7, 250, 251, 223, 174, 169, 169, 89, 4, 58, 230, 129, + 151, 153, 192, 87, 128, 47, 133, 202, 253, 193, 15, 249, 151, 199, 63, 223, 243, 175, 6, 14, 205, 157, 203, + 28, 232, 30, 98, 183, 13, 252, 137, 1, 255, 70, 111, 111, 239, 203, 79, 45, 94, 140, 61, 255, 185, 224, + 229, 27, 192, 116, 224, 11, 92, 238, 191, 175, 231, 75, 254, 229, 247, 207, 215, 253, 88, 247, 157, 219, + 190, 253, 110, 236, 183, 89, 173, 162, 113, 57, 157, 246, 27, 90, 237, 170, 137, 19, 38, 160, 127, 236, + 249, 230, 169, 239, 245, 124, 35, 230, 126, 242, 47, 159, 255, 90, 110, 189, 191, 122, 196, 8, 214, 114, + 233, 18, 115, 122, 189, 146, 248, 247, 247, 245, 253, 251, 68, 67, 195, 83, 160, 2, 235, 254, 239, 168, + 135, 246, 122, 77, 86, 223, 235, 249, 134, 205, 253, 228, 95, 62, 255, 53, 92, 221, 87, 151, 159, 207, 44, + 22, 11, 179, 65, 220, 134, 57, 187, 104, 2, 129, 64, 253, 234, 213, 171, 249, 245, 222, 111, 169, 239, 223, + 235, 53, 50, 156, 123, 242, 47, 159, 255, 221, 92, 221, 215, 184, 113, 35, 115, 251, 253, 204, 10, 255, 3, + 98, 129, 185, 95, 192, 220, 221, 189, 49, 47, 47, 15, 253, 71, 181, 222, 75, 254, 149, 241, 143, 185, 255, + 5, 64, 211, 216, 200, 156, 62, 159, 36, 254, 189, 30, 143, 246, 98, 83, 211, 82, 112, 129, 117, 159, 176, + 231, 251, 192, 186, 143, 252, 203, 235, 31, 247, 250, 212, 78, 157, 202, 186, 244, 250, 187, 177, 31, 115, + 128, 88, 252, 126, 255, 155, 213, 213, 213, 88, 247, 205, 7, 31, 216, 243, 13, 87, 247, 145, 127, 133, 253, + 227, 216, 63, 89, 81, 193, 156, 125, 125, 146, 184, 199, 220, 239, 116, 58, 183, 22, 22, 22, 46, 84, 13, + 213, 125, 5, 234, 225, 117, 95, 216, 158, 47, 249, 151, 223, 127, 53, 238, 241, 63, 122, 148, 57, 32, 246, + 91, 204, 102, 209, 56, 29, 14, 227, 229, 143, 62, 90, 145, 153, 153, 137, 185, 255, 251, 234, 161, 186, + 239, 49, 117, 20, 61, 95, 242, 47, 191, 255, 154, 172, 44, 166, 111, 109, 101, 86, 136, 253, 102, 240, 39, + 150, 222, 222, 222, 243, 117, 117, 117, 184, 222, 183, 0, 92, 132, 58, 227, 243, 192, 220, 79, 254, 229, + 243, 255, 198, 242, 229, 204, 14, 53, 191, 20, 238, 17, 175, 215, 187, 179, 180, 180, 20, 99, 127, 184, 51, + 62, 17, 235, 62, 242, 47, 175, 255, 247, 95, 123, 237, 110, 236, 135, 122, 77, 52, 118, 155, 205, 113, 67, + 171, 125, 102, 226, 196, 137, 56, 247, 19, 174, 247, 69, 93, 247, 145, 127, 121, 253, 183, 95, 189, 202, + 44, 16, 251, 187, 193, 159, 88, 96, 236, 191, 255, 250, 145, 35, 197, 240, 250, 99, 94, 239, 35, 255, 202, + 248, 239, 241, 120, 36, 113, 143, 248, 124, 190, 3, 21, 21, 21, 113, 173, 247, 145, 127, 101, 252, 99, 238, + 239, 54, 153, 68, 99, 181, 88, 124, 29, 237, 237, 235, 167, 79, 159, 142, 254, 241, 124, 39, 214, 125, 211, + 212, 67, 117, 95, 76, 177, 159, 252, 203, 231, 223, 98, 179, 73, 226, 223, 237, 114, 105, 78, 159, 62, 93, + 6, 175, 30, 231, 126, 124, 207, 47, 226, 25, 15, 242, 175, 56, 204, 4, 238, 164, 0, 98, 255, 225, 117, 235, + 214, 253, 84, 117, 175, 231, 247, 120, 80, 236, 143, 58, 247, 147, 127, 25, 253, 119, 117, 137, 198, 98, + 54, 7, 58, 13, 134, 170, 220, 220, 92, 140, 253, 194, 189, 30, 252, 62, 207, 152, 98, 63, 249, 79, 46, 255, + 46, 167, 243, 127, 111, 159, 57, 179, 148, 139, 253, 216, 243, 227, 207, 247, 197, 212, 243, 35, 255, 242, + 251, 239, 2, 127, 98, 129, 186, 239, 72, 101, 101, 37, 246, 252, 138, 212, 34, 122, 126, 228, 63, 249, 252, + 67, 221, 55, 0, 63, 159, 203, 207, 207, 199, 220, 95, 200, 197, 254, 176, 247, 250, 68, 251, 144, 127, 153, + 252, 27, 141, 162, 112, 216, 237, 215, 207, 157, 61, 187, 28, 94, 249, 34, 46, 246, 135, 218, 227, 79, 254, + 19, 19, 102, 4, 135, 98, 240, 120, 60, 199, 54, 111, 222, 204, 175, 247, 240, 251, 252, 68, 197, 126, 242, + 159, 28, 254, 161, 238, 235, 239, 236, 236, 124, 174, 160, 160, 0, 99, 127, 184, 179, 221, 252, 122, 15, + 249, 79, 60, 152, 177, 179, 51, 110, 236, 61, 61, 45, 103, 223, 125, 247, 103, 240, 206, 209, 63, 174, 247, + 8, 215, 250, 99, 238, 249, 145, 127, 249, 253, 195, 248, 141, 27, 183, 219, 125, 108, 211, 166, 77, 194, + 216, 143, 235, 61, 81, 239, 241, 38, 255, 138, 19, 183, 123, 152, 243, 247, 235, 245, 250, 205, 185, 185, + 185, 232, 63, 82, 236, 143, 106, 189, 135, 252, 43, 228, 223, 96, 136, 11, 136, 253, 87, 207, 188, 245, + 214, 50, 120, 213, 124, 236, 143, 123, 173, 159, 252, 39, 159, 127, 151, 211, 249, 247, 13, 235, 215, 47, + 86, 221, 31, 251, 199, 139, 141, 253, 228, 95, 62, 255, 6, 112, 25, 43, 16, 251, 251, 116, 58, 93, 101, 78, + 78, 14, 31, 251, 241, 124, 79, 184, 251, 28, 201, 127, 226, 194, 12, 122, 125, 204, 64, 236, 215, 156, 60, + 113, 2, 251, 253, 81, 197, 126, 185, 33, 255, 15, 215, 191, 211, 225, 56, 244, 203, 85, 171, 194, 197, 126, + 73, 239, 114, 38, 255, 15, 215, 63, 204, 225, 99, 2, 98, 191, 187, 165, 165, 101, 253, 148, 41, 83, 22, + 171, 34, 223, 229, 75, 254, 19, 31, 166, 239, 232, 136, 9, 136, 253, 205, 127, 59, 124, 184, 44, 40, 246, + 63, 198, 197, 254, 71, 149, 142, 253, 228, 255, 225, 249, 55, 0, 61, 54, 219, 158, 210, 146, 18, 97, 236, + 143, 120, 174, 159, 252, 39, 52, 172, 3, 156, 70, 11, 196, 126, 235, 229, 203, 151, 159, 25, 55, 110, 28, + 222, 235, 80, 168, 142, 124, 190, 131, 252, 39, 62, 172, 163, 189, 61, 106, 32, 246, 95, 168, 173, 169, + 193, 123, 156, 23, 193, 123, 14, 117, 182, 79, 241, 216, 79, 254, 31, 142, 127, 140, 255, 221, 38, 211, + 139, 133, 133, 133, 56, 246, 163, 218, 231, 67, 254, 19, 30, 214, 14, 110, 163, 193, 100, 50, 117, 92, 108, + 106, 90, 145, 145, 145, 129, 254, 67, 237, 241, 28, 214, 239, 39, 255, 73, 1, 107, 111, 107, 139, 10, 136, + 253, 167, 182, 108, 217, 82, 204, 197, 126, 225, 125, 94, 33, 247, 249, 144, 255, 164, 32, 42, 247, 16, + 251, 251, 219, 116, 186, 223, 229, 229, 229, 161, 255, 249, 234, 123, 251, 251, 19, 46, 246, 147, 127, 233, + 253, 91, 204, 230, 255, 158, 60, 113, 2, 247, 248, 97, 221, 199, 159, 237, 194, 216, 31, 124, 167, 7, 249, + 79, 46, 24, 140, 235, 7, 98, 179, 90, 15, 174, 88, 177, 2, 199, 254, 19, 240, 126, 195, 157, 237, 74, 136, + 216, 79, 254, 165, 245, 111, 208, 235, 237, 87, 52, 154, 181, 89, 89, 89, 232, 127, 158, 58, 242, 185, 94, + 242, 159, 92, 68, 51, 246, 155, 106, 107, 107, 75, 225, 149, 62, 9, 239, 86, 120, 151, 159, 240, 92, 175, + 100, 223, 110, 36, 255, 242, 250, 215, 129, 227, 112, 180, 65, 238, 55, 118, 118, 190, 4, 53, 127, 49, 215, + 239, 229, 239, 116, 16, 174, 245, 73, 242, 205, 118, 242, 175, 144, 255, 91, 183, 194, 210, 101, 52, 234, + 206, 159, 63, 255, 11, 168, 249, 139, 195, 172, 245, 37, 92, 236, 39, 255, 210, 249, 135, 216, 127, 252, + 55, 27, 54, 44, 73, 244, 126, 47, 249, 143, 223, 255, 45, 240, 28, 138, 246, 246, 118, 223, 181, 107, 215, + 170, 166, 77, 155, 182, 132, 171, 249, 249, 126, 111, 66, 173, 245, 145, 127, 145, 254, 111, 222, 12, 137, + 185, 187, 251, 131, 67, 245, 245, 184, 199, 235, 65, 253, 94, 254, 81, 220, 59, 249, 151, 198, 63, 151, + 251, 119, 47, 92, 184, 112, 137, 160, 230, 23, 126, 179, 55, 161, 250, 189, 228, 63, 126, 255, 55, 193, + 119, 48, 6, 131, 65, 223, 212, 212, 244, 244, 152, 49, 99, 208, 255, 143, 213, 161, 107, 254, 132, 140, + 253, 228, 63, 70, 255, 173, 173, 247, 97, 49, 155, 79, 86, 85, 85, 149, 112, 53, 63, 238, 241, 10, 85, 243, + 39, 76, 191, 151, 252, 75, 231, 191, 77, 167, 235, 109, 185, 118, 237, 183, 57, 57, 57, 37, 17, 246, 247, + 38, 92, 205, 79, 254, 227, 243, 223, 10, 206, 133, 152, 76, 166, 15, 14, 30, 60, 136, 231, 186, 138, 85, + 161, 239, 243, 72, 200, 154, 159, 252, 199, 233, 255, 198, 141, 79, 192, 241, 111, 208, 235, 119, 22, 21, + 21, 225, 216, 95, 168, 30, 90, 231, 15, 190, 203, 73, 88, 243, 147, 255, 228, 102, 152, 127, 112, 223, 118, + 238, 220, 185, 167, 71, 141, 26, 85, 34, 88, 235, 73, 216, 117, 126, 242, 47, 173, 255, 110, 147, 233, 216, + 154, 53, 107, 34, 173, 245, 40, 126, 182, 131, 252, 75, 235, 255, 134, 86, 123, 23, 168, 249, 221, 26, 141, + 230, 217, 201, 147, 39, 151, 6, 205, 251, 132, 247, 119, 39, 244, 188, 143, 252, 199, 239, 223, 212, 213, + 117, 113, 231, 142, 29, 216, 239, 43, 134, 119, 40, 220, 219, 159, 208, 107, 61, 228, 95, 188, 127, 136, + 253, 131, 48, 254, 171, 103, 207, 158, 93, 42, 152, 247, 69, 218, 223, 73, 254, 83, 3, 166, 189, 126, 29, + 231, 125, 87, 27, 26, 26, 126, 14, 175, 77, 56, 239, 227, 251, 125, 73, 51, 239, 35, 255, 241, 249, 239, + 52, 24, 246, 47, 45, 47, 15, 53, 239, 227, 207, 243, 39, 212, 254, 78, 242, 47, 157, 255, 54, 157, 174, + 235, 210, 197, 139, 191, 202, 204, 204, 44, 227, 206, 245, 36, 93, 191, 143, 252, 199, 239, 223, 104, 52, + 158, 170, 172, 172, 44, 199, 117, 94, 120, 119, 252, 58, 47, 223, 239, 195, 117, 222, 164, 153, 247, 145, + 255, 152, 241, 93, 209, 104, 54, 101, 103, 103, 151, 69, 185, 206, 75, 254, 83, 139, 75, 187, 119, 237, 90, + 206, 205, 251, 66, 173, 243, 38, 213, 188, 143, 252, 199, 204, 11, 179, 102, 205, 42, 227, 246, 247, 69, + 186, 199, 137, 252, 167, 38, 88, 243, 149, 10, 246, 247, 37, 93, 175, 159, 252, 139, 162, 156, 171, 249, + 130, 191, 215, 22, 124, 158, 155, 252, 167, 38, 229, 65, 231, 58, 130, 123, 253, 195, 238, 111, 85, 218, + 43, 249, 151, 28, 172, 249, 162, 234, 245, 147, 255, 148, 36, 92, 205, 23, 242, 238, 102, 165, 189, 146, + 127, 201, 9, 190, 187, 55, 226, 183, 26, 149, 246, 74, 254, 37, 71, 120, 166, 43, 212, 221, 189, 228, 63, + 181, 9, 119, 143, 75, 200, 123, 251, 149, 246, 74, 254, 37, 71, 184, 191, 43, 100, 205, 71, 254, 83, 26, + 254, 60, 103, 216, 154, 143, 252, 167, 52, 211, 213, 161, 239, 239, 35, 255, 233, 1, 246, 123, 66, 221, + 225, 68, 254, 211, 131, 136, 253, 30, 242, 159, 242, 132, 93, 227, 39, 255, 105, 65, 196, 126, 15, 249, 79, + 121, 66, 158, 231, 35, 255, 105, 67, 76, 223, 233, 83, 218, 43, 249, 151, 156, 251, 246, 247, 144, 255, + 180, 34, 166, 111, 116, 42, 237, 149, 252, 75, 78, 76, 223, 232, 84, 218, 43, 249, 151, 156, 152, 190, 207, + 172, 180, 87, 242, 47, 57, 49, 125, 159, 89, 105, 175, 228, 95, 114, 162, 118, 79, 254, 83, 18, 242, 159, + 222, 144, 255, 52, 39, 150, 71, 105, 175, 228, 159, 252, 147, 127, 242, 79, 254, 201, 63, 249, 39, 255, + 228, 159, 252, 147, 127, 242, 79, 254, 201, 63, 249, 39, 255, 228, 159, 252, 147, 127, 242, 79, 254, 201, + 63, 249, 39, 255, 74, 191, 219, 100, 128, 252, 167, 55, 228, 63, 189, 33, 255, 233, 13, 249, 79, 107, 254, + 15, 204, 214, 142, 153, 112, 48, 251, 159, 0, 0, 1, 11, 109, 107, 66, 84, 250, 206, 202, 254, 0, 127, 207, + 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, + 156, 237, 209, 49, 13, 0, 0, 8, 192, 48, 252, 155, 6, 25, 28, 235, 146, 42, 216, 204, 99, 187, 203, 51, + 255, 219, 252, 111, 243, 191, 205, 255, 54, 255, 219, 252, 111, 243, 191, 205, 255, 54, 255, 219, 252, 111, + 243, 191, 205, 255, 54, 255, 219, 252, 111, 243, 191, 205, 255, 54, 255, 219, 252, 111, 243, 191, 205, 255, + 54, 255, 219, 252, 111, 243, 191, 205, 255, 54, 255, 219, 252, 111, 243, 191, 205, 255, 54, 255, 219, 252, + 111, 243, 191, 205, 255, 54, 255, 219, 252, 111, 243, 191, 205, 255, 54, 255, 219, 252, 111, 243, 191, 205, + 255, 54, 255, 219, 252, 111, 243, 191, 205, 255, 54, 255, 219, 252, 111, 243, 191, 205, 255, 54, 255, 219, + 252, 111, 243, 191, 205, 255, 54, 255, 219, 252, 111, 243, 191, 205, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 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, 14, 116, 156, 169, 172, 112, + 158, 41, 45, 0, 0, 19, 206, 109, 107, 66, 84, 250, 206, 202, 254, 0, 127, 208, 39, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 93, 9, 112, 148, 69, + 22, 254, 49, 165, 224, 13, 110, 41, 86, 89, 178, 236, 22, 202, 162, 139, 138, 34, 200, 145, 8, 68, 64, 8, + 8, 49, 114, 31, 9, 87, 36, 225, 38, 36, 132, 4, 19, 66, 2, 43, 4, 228, 218, 149, 99, 85, 60, 74, 142, 85, + 68, 40, 60, 23, 141, 33, 138, 2, 10, 168, 137, 200, 130, 202, 114, 19, 86, 17, 8, 9, 9, 9, 111, 251, 245, + 244, 203, 116, 126, 254, 153, 12, 195, 64, 247, 132, 126, 85, 95, 133, 144, 201, 164, 167, 191, 175, 95, + 191, 247, 250, 248, 97, 172, 101, 193, 213, 136, 49, 2, 163, 25, 70, 49, 196, 51, 196, 49, 60, 203, 16, + 203, 48, 140, 97, 8, 195, 96, 134, 129, 12, 125, 25, 122, 49, 60, 205, 208, 131, 33, 130, 225, 73, 134, + 142, 12, 29, 24, 30, 103, 8, 101, 120, 148, 225, 175, 12, 125, 154, 52, 129, 127, 175, 94, 13, 231, 207, + 159, 7, 13, 173, 132, 97, 201, 134, 13, 27, 96, 28, 107, 235, 213, 14, 210, 131, 172, 133, 145, 66, 7, 195, + 25, 134, 50, 68, 11, 29, 244, 99, 232, 45, 233, 160, 27, 67, 23, 73, 7, 237, 132, 14, 30, 97, 120, 16, 245, + 212, 182, 45, 108, 207, 205, 85, 205, 183, 71, 83, 221, 247, 186, 192, 147, 79, 32, 29, 120, 243, 7, 79, + 89, 46, 127, 208, 89, 232, 160, 189, 229, 242, 7, 109, 24, 154, 49, 52, 103, 152, 252, 244, 211, 240, 83, + 126, 190, 106, 186, 47, 48, 213, 253, 174, 19, 228, 249, 97, 180, 128, 60, 47, 140, 16, 58, 136, 17, 58, + 24, 32, 116, 240, 12, 67, 36, 67, 119, 134, 174, 66, 7, 79, 72, 58, 104, 205, 240, 0, 126, 173, 93, 27, + 178, 227, 227, 161, 240, 208, 33, 213, 180, 87, 154, 234, 62, 215, 21, 78, 254, 192, 147, 14, 250, 51, 244, + 17, 58, 232, 41, 233, 160, 19, 67, 184, 208, 65, 24, 67, 43, 134, 166, 248, 127, 245, 234, 193, 43, 153, + 153, 80, 116, 242, 164, 106, 250, 149, 247, 179, 206, 144, 99, 69, 217, 31, 140, 148, 116, 48, 84, 232, 96, + 144, 229, 138, 13, 80, 7, 81, 66, 7, 20, 27, 144, 14, 218, 9, 29, 180, 180, 92, 49, 98, 143, 134, 13, 97, + 221, 75, 47, 193, 185, 178, 50, 195, 191, 198, 176, 235, 64, 142, 13, 80, 7, 158, 98, 68, 212, 65, 15, 203, + 115, 140, 136, 113, 1, 206, 11, 131, 155, 53, 131, 207, 89, 44, 110, 248, 215, 27, 78, 58, 136, 179, 170, + 230, 10, 67, 36, 29, 248, 146, 51, 182, 101, 120, 216, 114, 197, 137, 99, 59, 117, 130, 130, 173, 91, 13, + 255, 26, 195, 83, 253, 192, 30, 27, 80, 174, 64, 49, 34, 234, 0, 99, 68, 204, 21, 156, 98, 68, 204, 21, 30, + 100, 104, 17, 18, 2, 25, 131, 6, 193, 129, 189, 123, 175, 8, 255, 227, 217, 223, 52, 184, 120, 200, 122, + 240, 86, 59, 240, 166, 3, 242, 7, 78, 185, 66, 216, 141, 55, 194, 223, 147, 146, 224, 196, 241, 227, 151, + 149, 255, 9, 236, 111, 25, 248, 15, 187, 30, 156, 124, 130, 61, 62, 112, 170, 29, 144, 14, 104, 94, 160, + 92, 161, 107, 253, 250, 176, 106, 222, 60, 56, 91, 92, 108, 248, 215, 24, 178, 14, 100, 159, 112, 49, 254, + 192, 105, 94, 104, 41, 116, 208, 167, 113, 99, 248, 120, 229, 74, 56, 95, 81, 97, 248, 215, 24, 190, 232, + 192, 30, 31, 248, 82, 59, 192, 92, 225, 33, 252, 253, 214, 173, 225, 155, 156, 28, 195, 191, 230, 112, 210, + 129, 28, 31, 200, 53, 36, 172, 29, 56, 213, 144, 40, 103, 164, 218, 1, 230, 140, 205, 80, 11, 181, 106, 65, + 114, 100, 36, 236, 253, 254, 123, 195, 191, 198, 176, 199, 139, 84, 87, 38, 29, 216, 107, 137, 3, 133, 14, + 228, 218, 129, 61, 103, 68, 29, 96, 206, 136, 190, 160, 77, 237, 218, 48, 59, 46, 14, 142, 29, 56, 96, 248, + 215, 28, 158, 230, 4, 79, 49, 34, 214, 144, 156, 106, 7, 114, 140, 72, 185, 66, 120, 221, 186, 240, 114, + 70, 6, 20, 253, 254, 187, 225, 95, 99, 120, 139, 13, 80, 7, 78, 53, 36, 210, 65, 164, 229, 57, 70, 124, 76, + 232, 160, 103, 131, 6, 240, 238, 178, 101, 80, 86, 90, 106, 248, 215, 24, 254, 228, 10, 78, 49, 162, 172, + 3, 140, 17, 31, 21, 58, 24, 252, 208, 67, 144, 183, 126, 189, 225, 95, 115, 248, 154, 43, 84, 23, 35, 218, + 215, 151, 112, 239, 73, 51, 124, 207, 142, 29, 33, 255, 171, 175, 12, 255, 154, 131, 116, 32, 239, 61, 240, + 180, 222, 76, 58, 112, 90, 95, 66, 29, 216, 99, 196, 150, 33, 33, 48, 109, 224, 64, 216, 191, 103, 143, 35, + 255, 9, 236, 53, 6, 234, 49, 81, 128, 244, 96, 207, 23, 40, 62, 144, 107, 7, 190, 248, 3, 210, 65, 59, 172, + 39, 39, 38, 194, 137, 194, 66, 195, 191, 230, 144, 181, 96, 215, 129, 61, 62, 176, 251, 3, 79, 251, 14, 40, + 87, 192, 122, 242, 138, 185, 115, 161, 228, 204, 25, 195, 191, 198, 240, 230, 15, 188, 197, 7, 246, 121, + 193, 94, 59, 160, 92, 161, 207, 189, 247, 194, 71, 43, 86, 40, 255, 156, 6, 23, 175, 3, 123, 156, 40, 239, + 67, 178, 215, 14, 228, 245, 37, 121, 223, 1, 230, 10, 56, 47, 36, 26, 104, 143, 73, 2, 164, 9, 187, 22, + 236, 241, 129, 175, 254, 224, 113, 13, 62, 155, 129, 255, 90, 240, 85, 7, 242, 153, 5, 187, 63, 80, 253, + 121, 12, 46, 77, 3, 158, 116, 64, 241, 129, 167, 154, 50, 213, 18, 85, 127, 22, 131, 192, 232, 64, 142, 17, + 168, 150, 100, 143, 15, 80, 7, 246, 51, 11, 170, 63, 131, 193, 229, 209, 129, 61, 95, 160, 53, 38, 251, + 254, 147, 36, 131, 26, 3, 89, 15, 118, 127, 32, 235, 0, 253, 1, 233, 64, 117, 155, 13, 46, 175, 14, 228, + 248, 192, 201, 31, 168, 110, 171, 193, 149, 209, 129, 147, 63, 136, 211, 160, 141, 6, 87, 78, 3, 246, 248, + 0, 99, 196, 201, 6, 87, 5, 100, 61, 200, 90, 80, 221, 46, 3, 181, 58, 80, 221, 30, 3, 181, 58, 80, 221, 14, + 3, 3, 3, 117, 72, 54, 48, 48, 48, 48, 240, 25, 118, 31, 42, 199, 82, 170, 219, 102, 112, 241, 60, 82, 62, + 68, 57, 177, 188, 223, 106, 172, 85, 245, 254, 135, 241, 226, 53, 248, 218, 201, 215, 92, 195, 145, 82, + 167, 14, 164, 222, 112, 3, 164, 178, 175, 70, 3, 250, 192, 206, 173, 188, 46, 54, 86, 124, 143, 57, 112, + 74, 237, 218, 144, 113, 199, 29, 48, 171, 81, 35, 88, 208, 188, 57, 188, 212, 185, 51, 188, 217, 175, 31, + 172, 25, 57, 18, 62, 152, 50, 5, 114, 102, 205, 130, 175, 150, 46, 133, 29, 43, 86, 64, 193, 250, 245, 176, + 231, 147, 79, 224, 231, 77, 155, 224, 224, 246, 237, 112, 104, 199, 14, 56, 254, 159, 255, 192, 169, 163, + 71, 225, 235, 215, 94, 227, 218, 144, 243, 42, 213, 125, 80, 29, 166, 212, 0, 16, 215, 84, 231, 166, 241, + 139, 252, 226, 248, 76, 187, 245, 86, 200, 110, 220, 24, 150, 180, 111, 15, 171, 6, 13, 130, 15, 83, 83, + 225, 75, 198, 103, 193, 186, 117, 176, 127, 235, 86, 248, 223, 222, 189, 80, 84, 88, 8, 229, 151, 120, 15, + 215, 182, 229, 203, 249, 223, 181, 207, 5, 170, 251, 199, 27, 82, 131, 12, 41, 162, 79, 19, 45, 119, 45, + 27, 255, 61, 149, 141, 225, 89, 127, 252, 35, 44, 99, 28, 191, 19, 27, 11, 155, 178, 179, 225, 7, 198, 239, + 97, 54, 62, 79, 179, 177, 89, 126, 17, 103, 226, 252, 181, 141, 153, 153, 149, 53, 245, 100, 209, 214, 20, + 13, 250, 44, 88, 129, 125, 55, 197, 198, 53, 142, 173, 140, 186, 117, 97, 209, 35, 143, 192, 191, 6, 15, + 134, 77, 115, 231, 194, 238, 15, 62, 224, 99, 184, 236, 50, 221, 145, 226, 171, 173, 29, 63, 158, 175, 173, + 38, 26, 13, 248, 205, 55, 246, 217, 36, 193, 53, 206, 217, 105, 215, 95, 15, 243, 155, 54, 133, 127, 69, + 71, 195, 23, 139, 22, 193, 47, 108, 222, 61, 125, 236, 152, 150, 247, 106, 191, 193, 230, 150, 56, 209, + 238, 36, 203, 237, 251, 13, 255, 190, 241, 141, 95, 113, 108, 47, 13, 11, 131, 247, 147, 146, 248, 252, + 252, 219, 190, 125, 112, 190, 188, 92, 53, 181, 62, 217, 146, 30, 61, 248, 158, 75, 250, 44, 178, 15, 80, + 221, 215, 58, 128, 252, 121, 146, 229, 30, 223, 233, 55, 221, 4, 139, 219, 180, 129, 143, 82, 82, 184, 31, + 199, 177, 29, 172, 54, 47, 60, 156, 239, 169, 193, 24, 144, 242, 0, 195, 191, 171, 15, 144, 107, 140, 203, + 147, 89, 60, 62, 231, 222, 123, 121, 140, 246, 221, 91, 111, 193, 201, 131, 7, 85, 211, 22, 48, 203, 106, + 209, 130, 239, 179, 29, 99, 185, 227, 210, 201, 87, 33, 255, 41, 226, 115, 83, 206, 61, 149, 205, 225, 75, + 66, 67, 33, 103, 230, 76, 56, 248, 205, 55, 87, 36, 22, 87, 97, 211, 88, 76, 138, 103, 46, 70, 11, 173, + 211, 28, 80, 211, 249, 167, 24, 151, 198, 57, 250, 190, 244, 91, 110, 129, 229, 93, 187, 194, 150, 101, + 203, 224, 183, 159, 127, 86, 77, 141, 223, 118, 246, 204, 25, 56, 246, 223, 255, 86, 27, 111, 98, 237, 32, + 185, 73, 19, 190, 199, 30, 207, 95, 140, 147, 248, 15, 198, 60, 219, 87, 16, 231, 56, 206, 211, 216, 92, + 254, 106, 183, 110, 176, 253, 141, 55, 224, 212, 225, 195, 87, 136, 161, 192, 27, 222, 199, 158, 255, 197, + 23, 176, 120, 210, 36, 24, 196, 230, 170, 78, 181, 107, 67, 194, 19, 79, 192, 71, 175, 189, 6, 39, 127, + 253, 213, 227, 239, 76, 254, 203, 95, 248, 158, 234, 248, 32, 226, 127, 170, 31, 192, 177, 78, 49, 92, 42, + 235, 155, 151, 58, 116, 128, 45, 75, 151, 6, 245, 92, 126, 142, 205, 73, 156, 243, 196, 68, 136, 102, 60, + 134, 214, 170, 197, 207, 200, 182, 177, 220, 119, 246, 183, 96, 232, 121, 199, 29, 144, 61, 108, 24, 236, + 204, 201, 169, 114, 111, 63, 241, 79, 227, 159, 252, 63, 197, 127, 254, 244, 179, 46, 32, 173, 160, 150, + 41, 174, 93, 240, 192, 3, 124, 62, 199, 218, 119, 176, 219, 215, 27, 55, 66, 212, 93, 119, 241, 59, 119, + 155, 11, 206, 241, 78, 37, 60, 35, 27, 46, 208, 193, 114, 223, 179, 132, 90, 192, 179, 179, 177, 247, 221, + 7, 43, 167, 79, 135, 195, 123, 246, 64, 69, 69, 5, 36, 179, 239, 101, 254, 19, 131, 156, 127, 154, 219, + 169, 174, 158, 197, 180, 143, 113, 251, 47, 121, 121, 80, 113, 238, 156, 106, 218, 2, 102, 165, 103, 207, + 194, 210, 228, 100, 206, 63, 222, 151, 130, 119, 106, 225, 217, 216, 78, 94, 64, 119, 111, 161, 46, 250, + 212, 169, 3, 51, 88, 238, 55, 234, 15, 127, 224, 249, 31, 242, 79, 241, 127, 178, 229, 191, 159, 189, 146, + 99, 219, 14, 26, 235, 201, 33, 33, 188, 30, 243, 245, 242, 229, 80, 236, 97, 238, 171, 41, 150, 183, 102, + 13, 116, 175, 87, 143, 143, 113, 188, 63, 5, 207, 199, 226, 89, 233, 110, 2, 17, 18, 240, 123, 60, 83, 143, + 103, 105, 159, 17, 192, 216, 31, 207, 91, 202, 249, 159, 238, 252, 211, 216, 166, 90, 37, 213, 226, 102, + 220, 121, 39, 172, 31, 51, 134, 231, 107, 87, 147, 237, 251, 254, 123, 136, 107, 218, 148, 251, 252, 158, + 130, 223, 40, 129, 167, 37, 68, 9, 206, 251, 88, 174, 123, 22, 48, 238, 195, 177, 143, 245, 223, 177, 150, + 123, 158, 164, 216, 79, 53, 207, 158, 128, 53, 183, 55, 34, 35, 121, 28, 135, 237, 93, 210, 170, 21, 108, + 123, 229, 21, 40, 57, 113, 66, 53, 21, 202, 12, 239, 81, 157, 19, 21, 197, 207, 200, 247, 181, 92, 103, + 231, 17, 3, 108, 24, 40, 120, 143, 169, 134, 251, 231, 24, 210, 52, 5, 217, 209, 130, 2, 216, 183, 121, + 115, 192, 239, 151, 15, 102, 91, 59, 109, 26, 12, 100, 121, 0, 114, 140, 247, 105, 12, 181, 97, 152, 224, + 29, 107, 254, 152, 243, 57, 249, 125, 226, 62, 93, 83, 24, 243, 110, 219, 89, 76, 48, 166, 110, 93, 126, + 94, 122, 164, 132, 56, 1, 228, 125, 180, 52, 238, 237, 57, 191, 225, 63, 248, 237, 112, 126, 62, 204, 96, + 249, 238, 48, 49, 198, 237, 251, 2, 39, 8, 238, 169, 222, 31, 44, 220, 27, 254, 125, 183, 146, 147, 39, + 225, 213, 222, 189, 249, 216, 199, 220, 62, 65, 140, 117, 228, 92, 222, 239, 69, 185, 190, 204, 253, 52, + 141, 97, 236, 226, 108, 99, 86, 22, 140, 103, 49, 193, 4, 203, 189, 199, 83, 222, 227, 97, 231, 222, 240, + 95, 243, 172, 224, 221, 119, 33, 237, 182, 219, 184, 6, 228, 181, 189, 231, 130, 140, 123, 195, 191, 255, + 86, 184, 107, 23, 204, 127, 240, 65, 215, 26, 72, 16, 142, 123, 195, 255, 165, 219, 89, 22, 19, 172, 96, + 49, 193, 68, 225, 7, 12, 255, 87, 167, 229, 176, 152, 32, 153, 197, 4, 41, 54, 222, 51, 130, 0, 198, 2, 99, + 63, 176, 152, 32, 243, 150, 91, 248, 60, 96, 231, 126, 186, 198, 48, 22, 56, 123, 59, 38, 134, 231, 131, + 105, 65, 164, 1, 99, 129, 179, 13, 9, 9, 174, 253, 142, 14, 26, 80, 205, 179, 225, 255, 242, 27, 214, 6, + 176, 30, 72, 177, 96, 122, 16, 248, 0, 220, 183, 116, 252, 208, 33, 213, 93, 87, 35, 108, 243, 210, 165, + 188, 62, 60, 69, 248, 0, 226, 159, 250, 58, 83, 67, 76, 141, 138, 130, 238, 245, 235, 195, 254, 221, 187, + 85, 119, 95, 208, 219, 183, 107, 215, 242, 181, 32, 172, 9, 98, 77, 128, 230, 0, 157, 249, 127, 68, 96, 76, + 251, 246, 124, 15, 164, 49, 255, 109, 111, 94, 30, 223, 251, 53, 73, 248, 0, 121, 14, 208, 149, 255, 246, + 2, 184, 239, 241, 31, 44, 126, 49, 230, 191, 225, 58, 225, 184, 107, 175, 229, 49, 32, 174, 5, 217, 231, 0, + 213, 92, 59, 161, 163, 229, 126, 30, 12, 238, 125, 204, 89, 181, 74, 117, 55, 6, 173, 157, 60, 122, 20, 38, + 213, 171, 199, 215, 134, 229, 57, 64, 103, 254, 187, 10, 116, 17, 126, 160, 231, 237, 183, 195, 129, 31, + 127, 84, 221, 149, 65, 105, 165, 197, 197, 144, 218, 176, 33, 159, 3, 176, 14, 64, 121, 0, 197, 0, 170, + 185, 118, 2, 62, 3, 4, 247, 57, 226, 94, 55, 220, 211, 138, 123, 95, 199, 135, 133, 65, 217, 217, 179, 170, + 187, 51, 40, 109, 86, 171, 86, 124, 143, 128, 28, 3, 232, 204, 63, 238, 111, 236, 109, 185, 159, 7, 131, + 58, 8, 101, 88, 60, 97, 130, 234, 174, 12, 74, 91, 28, 25, 201, 159, 175, 145, 96, 185, 243, 64, 157, 115, + 128, 104, 203, 245, 140, 176, 1, 150, 107, 47, 51, 238, 107, 198, 231, 200, 134, 51, 228, 174, 94, 173, + 186, 59, 131, 206, 86, 141, 27, 199, 247, 137, 209, 158, 122, 221, 99, 64, 122, 150, 236, 80, 203, 181, + 151, 185, 159, 240, 5, 24, 15, 244, 194, 88, 96, 215, 46, 213, 93, 26, 84, 182, 113, 193, 2, 222, 151, 50, + 255, 178, 255, 207, 210, 12, 244, 28, 136, 120, 161, 133, 24, 225, 11, 122, 89, 174, 115, 78, 227, 217, + 124, 86, 170, 248, 94, 165, 96, 178, 29, 239, 188, 195, 251, 145, 252, 127, 154, 224, 30, 251, 122, 6, 195, + 76, 205, 64, 119, 35, 226, 158, 70, 140, 91, 159, 21, 26, 232, 47, 252, 0, 230, 133, 139, 199, 142, 85, + 221, 173, 65, 99, 251, 119, 236, 224, 253, 56, 49, 72, 248, 167, 123, 27, 232, 60, 247, 40, 225, 7, 48, 46, + 192, 185, 0, 99, 66, 172, 15, 228, 172, 92, 169, 186, 107, 131, 194, 126, 63, 114, 132, 215, 0, 198, 137, + 126, 197, 248, 63, 67, 99, 254, 211, 68, 27, 233, 76, 63, 250, 1, 204, 95, 232, 185, 177, 24, 19, 98, 60, + 24, 121, 243, 205, 240, 207, 137, 19, 225, 128, 89, 39, 240, 106, 21, 229, 229, 144, 121, 255, 253, 149, + 235, 0, 196, 127, 166, 166, 252, 99, 219, 48, 62, 165, 179, 160, 56, 254, 19, 110, 188, 17, 230, 132, 133, + 193, 164, 6, 13, 56, 255, 17, 194, 7, 96, 125, 176, 107, 157, 58, 48, 189, 87, 47, 248, 54, 55, 87, 203, + 59, 248, 116, 176, 127, 68, 68, 240, 179, 65, 147, 45, 119, 252, 167, 43, 255, 211, 44, 247, 28, 48, 187, + 97, 67, 126, 55, 110, 161, 184, 211, 1, 207, 60, 252, 240, 233, 167, 176, 122, 234, 84, 72, 105, 221, 26, + 122, 221, 112, 3, 175, 15, 53, 99, 192, 179, 242, 163, 90, 180, 128, 15, 95, 125, 21, 78, 253, 246, 155, + 235, 131, 163, 30, 174, 118, 48, 123, 123, 194, 4, 62, 135, 162, 63, 77, 213, 156, 255, 233, 215, 93, 7, + 175, 119, 236, 8, 249, 111, 189, 5, 165, 69, 69, 94, 117, 93, 184, 111, 31, 228, 174, 88, 1, 47, 12, 29, + 10, 209, 127, 254, 51, 191, 39, 35, 252, 218, 107, 97, 122, 223, 190, 112, 132, 253, 204, 37, 129, 243, + 218, 195, 147, 5, 234, 189, 243, 150, 45, 227, 252, 39, 10, 254, 209, 191, 78, 23, 252, 235, 166, 129, 99, + 5, 5, 62, 245, 129, 221, 48, 39, 252, 37, 63, 31, 142, 31, 60, 8, 101, 165, 165, 252, 254, 19, 213, 188, + 250, 194, 177, 252, 57, 177, 205, 132, 234, 94, 123, 49, 127, 119, 79, 94, 30, 207, 167, 19, 132, 111, 37, + 254, 117, 140, 1, 43, 63, 31, 242, 231, 43, 28, 250, 247, 162, 223, 35, 208, 112, 104, 19, 238, 103, 56, + 252, 211, 79, 176, 237, 195, 15, 97, 237, 162, 69, 176, 56, 33, 1, 50, 122, 247, 134, 132, 240, 112, 136, + 99, 115, 87, 108, 179, 102, 16, 251, 240, 195, 28, 99, 218, 180, 129, 41, 221, 186, 193, 220, 216, 88, 88, + 53, 123, 54, 108, 121, 255, 125, 56, 182, 127, 127, 213, 243, 240, 62, 124, 70, 180, 19, 108, 76, 76, 186, + 245, 86, 158, 79, 233, 158, 3, 202, 99, 32, 232, 96, 227, 28, 239, 241, 249, 113, 219, 54, 120, 123, 254, + 124, 206, 115, 116, 227, 198, 208, 229, 250, 235, 121, 204, 242, 152, 229, 138, 89, 112, 206, 194, 56, 22, + 215, 56, 194, 36, 132, 138, 159, 181, 18, 175, 197, 239, 35, 88, 28, 60, 170, 101, 75, 88, 158, 158, 14, + 123, 118, 238, 172, 212, 152, 221, 119, 200, 192, 87, 224, 158, 186, 153, 77, 155, 86, 238, 5, 196, 241, + 159, 41, 250, 251, 111, 12, 207, 107, 4, 229, 28, 250, 1, 217, 48, 246, 252, 124, 221, 58, 152, 51, 124, + 56, 12, 110, 212, 8, 58, 92, 115, 77, 37, 207, 237, 44, 215, 29, 77, 120, 87, 83, 23, 203, 125, 167, 143, + 55, 208, 235, 232, 126, 167, 80, 161, 135, 240, 144, 16, 152, 216, 174, 29, 108, 90, 179, 6, 202, 197, 221, + 87, 158, 116, 128, 246, 50, 203, 145, 70, 217, 198, 255, 12, 195, 127, 64, 184, 47, 45, 41, 129, 173, 204, + 167, 207, 138, 137, 129, 103, 234, 215, 231, 227, 185, 181, 229, 218, 191, 208, 201, 186, 240, 238, 38, + 172, 95, 224, 186, 38, 222, 215, 212, 83, 66, 164, 229, 94, 255, 38, 244, 16, 175, 237, 46, 126, 151, 52, + 209, 201, 114, 251, 136, 209, 143, 61, 198, 239, 255, 35, 115, 106, 227, 7, 89, 89, 188, 142, 146, 236, + 192, 191, 78, 26, 40, 47, 47, 15, 26, 160, 237, 252, 236, 51, 24, 210, 164, 73, 37, 231, 88, 159, 126, 82, + 240, 68, 92, 19, 207, 200, 45, 221, 207, 133, 235, 25, 189, 5, 176, 166, 209, 215, 1, 244, 115, 124, 61, + 221, 247, 68, 154, 160, 251, 191, 158, 20, 58, 104, 87, 171, 22, 44, 138, 143, 135, 226, 211, 167, 121, + 187, 236, 237, 252, 118, 253, 122, 62, 254, 229, 26, 16, 205, 253, 134, 127, 255, 184, 47, 248, 242, 75, + 232, 114, 243, 205, 156, 251, 206, 18, 231, 79, 89, 238, 187, 186, 136, 107, 228, 19, 235, 151, 184, 142, + 129, 247, 52, 97, 61, 19, 215, 55, 177, 174, 29, 227, 1, 209, 226, 53, 180, 30, 222, 95, 210, 69, 148, 85, + 117, 159, 12, 234, 0, 125, 193, 152, 230, 205, 225, 240, 222, 189, 85, 52, 128, 86, 200, 226, 206, 68, 22, + 63, 240, 103, 211, 88, 238, 26, 176, 25, 255, 254, 113, 127, 226, 216, 49, 24, 124, 207, 61, 124, 78, 143, + 16, 60, 68, 10, 94, 122, 11, 158, 250, 11, 238, 144, 71, 188, 175, 7, 215, 97, 233, 126, 38, 92, 215, 66, + 127, 76, 119, 246, 32, 70, 73, 136, 23, 63, 27, 41, 94, 139, 123, 56, 134, 137, 247, 137, 22, 26, 234, 39, + 180, 133, 58, 163, 121, 2, 247, 73, 12, 105, 216, 16, 246, 139, 60, 26, 219, 91, 33, 98, 192, 231, 239, + 191, 159, 175, 3, 225, 248, 39, 255, 143, 125, 62, 139, 97, 182, 38, 56, 199, 98, 25, 157, 65, 252, 191, + 48, 98, 4, 143, 211, 137, 119, 251, 221, 123, 49, 130, 175, 17, 130, 63, 226, 151, 238, 235, 193, 117, 13, + 186, 167, 135, 144, 32, 129, 254, 143, 158, 29, 134, 191, 55, 90, 188, 207, 179, 66, 71, 67, 44, 247, 186, + 8, 249, 4, 212, 2, 198, 7, 177, 127, 250, 19, 28, 101, 99, 158, 231, 157, 34, 62, 124, 125, 192, 0, 254, + 183, 105, 252, 211, 252, 111, 248, 247, 29, 124, 46, 101, 115, 126, 103, 54, 223, 118, 23, 125, 142, 188, + 163, 127, 198, 113, 137, 99, 28, 199, 119, 156, 224, 155, 184, 38, 126, 229, 251, 121, 232, 142, 158, 234, + 158, 35, 55, 217, 186, 240, 153, 129, 163, 197, 223, 24, 97, 211, 65, 31, 161, 5, 156, 19, 166, 182, 109, + 203, 239, 139, 39, 203, 97, 121, 40, 234, 136, 106, 192, 228, 255, 13, 255, 62, 142, 125, 17, 75, 63, 215, + 165, 11, 143, 191, 123, 137, 62, 167, 251, 248, 104, 156, 211, 179, 28, 137, 111, 251, 115, 119, 232, 110, + 142, 234, 238, 227, 74, 147, 94, 151, 106, 85, 93, 27, 167, 61, 18, 168, 3, 156, 35, 208, 31, 196, 88, 85, + 99, 5, 244, 73, 233, 45, 90, 192, 79, 91, 182, 240, 118, 255, 188, 121, 115, 101, 13, 208, 206, 191, 46, + 26, 40, 99, 243, 148, 174, 64, 251, 46, 55, 151, 143, 173, 103, 68, 63, 99, 159, 199, 90, 238, 59, 246, + 229, 103, 109, 201, 119, 111, 209, 61, 12, 246, 125, 119, 213, 237, 135, 202, 20, 175, 207, 16, 191, 159, + 38, 222, 83, 126, 86, 21, 233, 64, 158, 23, 40, 134, 68, 29, 140, 184, 238, 58, 216, 144, 158, 14, 167, 10, + 11, 225, 121, 54, 47, 36, 75, 252, 203, 243, 127, 182, 6, 80, 205, 177, 71, 8, 223, 159, 221, 191, 63, 143, + 243, 7, 136, 126, 126, 86, 244, 61, 221, 179, 73, 123, 108, 229, 243, 214, 114, 173, 85, 206, 185, 170, + 139, 189, 233, 231, 51, 165, 223, 37, 61, 76, 179, 220, 251, 36, 232, 110, 108, 244, 59, 56, 231, 140, 20, + 154, 28, 33, 190, 198, 10, 93, 204, 99, 190, 96, 118, 163, 70, 188, 141, 78, 254, 95, 53, 247, 58, 243, + 143, 117, 212, 163, 251, 246, 193, 128, 122, 245, 248, 252, 74, 227, 126, 180, 232, 123, 251, 249, 26, 26, + 219, 84, 215, 150, 121, 158, 101, 249, 238, 115, 233, 117, 178, 38, 102, 138, 247, 70, 29, 208, 94, 9, 249, + 185, 117, 164, 131, 120, 203, 29, 119, 210, 115, 134, 147, 44, 247, 25, 0, 45, 249, 47, 45, 213, 18, 104, + 239, 191, 248, 34, 143, 249, 112, 190, 31, 33, 113, 47, 239, 171, 165, 117, 117, 39, 190, 189, 241, 108, + 239, 7, 111, 122, 144, 117, 144, 41, 244, 134, 186, 35, 95, 64, 58, 144, 159, 19, 46, 223, 1, 45, 215, 127, + 116, 227, 191, 148, 245, 181, 110, 160, 185, 63, 43, 34, 130, 231, 87, 24, 227, 199, 139, 62, 150, 247, + 212, 208, 120, 247, 150, 83, 251, 219, 47, 222, 116, 128, 60, 202, 190, 96, 138, 164, 3, 2, 205, 77, 246, + 245, 127, 195, 127, 245, 192, 117, 61, 188, 147, 98, 216, 237, 183, 243, 186, 11, 206, 249, 227, 44, 247, + 126, 10, 95, 198, 210, 156, 0, 193, 174, 9, 210, 129, 221, 23, 208, 179, 52, 40, 151, 164, 88, 84, 94, 251, + 183, 183, 55, 80, 109, 188, 20, 224, 154, 169, 110, 64, 251, 250, 189, 247, 120, 190, 135, 121, 30, 206, + 167, 180, 159, 62, 93, 234, 75, 59, 239, 151, 179, 159, 156, 116, 64, 190, 128, 116, 64, 57, 36, 129, 206, + 125, 56, 249, 41, 93, 248, 63, 203, 250, 91, 55, 160, 173, 102, 249, 19, 230, 124, 52, 246, 113, 46, 165, + 58, 218, 76, 235, 194, 113, 127, 37, 250, 202, 147, 6, 40, 62, 164, 92, 65, 62, 235, 71, 220, 59, 249, 42, + 213, 220, 235, 204, 255, 156, 167, 158, 226, 181, 30, 156, 247, 233, 44, 5, 237, 163, 176, 143, 253, 43, + 217, 95, 158, 230, 3, 123, 222, 104, 95, 235, 147, 227, 19, 173, 248, 47, 41, 209, 10, 24, 251, 21, 23, 21, + 65, 146, 120, 150, 26, 214, 79, 49, 158, 146, 231, 253, 231, 21, 247, 163, 83, 156, 40, 231, 140, 118, 56, + 113, 175, 11, 255, 37, 172, 207, 117, 66, 89, 121, 57, 223, 119, 23, 87, 183, 46, 207, 249, 248, 51, 163, + 45, 215, 124, 74, 245, 179, 217, 82, 251, 231, 42, 130, 55, 77, 144, 46, 170, 139, 73, 85, 181, 93, 134, + 106, 190, 237, 192, 213, 190, 61, 219, 182, 193, 240, 144, 144, 202, 61, 180, 52, 246, 103, 74, 220, 83, + 251, 95, 80, 12, 127, 251, 93, 117, 187, 9, 170, 249, 182, 3, 235, 126, 223, 126, 252, 49, 175, 247, 161, + 239, 167, 253, 19, 24, 79, 209, 188, 79, 252, 171, 238, 59, 127, 53, 160, 186, 189, 50, 138, 139, 139, 181, + 2, 242, 191, 121, 245, 106, 62, 247, 99, 220, 143, 117, 21, 244, 253, 20, 247, 101, 107, 218, 143, 222, 52, + 161, 186, 45, 193, 198, 127, 238, 242, 229, 124, 173, 135, 246, 207, 99, 220, 143, 113, 31, 198, 81, 115, + 164, 182, 207, 51, 184, 100, 168, 230, 219, 137, 255, 143, 23, 46, 228, 53, 95, 167, 185, 159, 198, 147, + 234, 126, 171, 41, 40, 62, 115, 70, 43, 112, 254, 231, 207, 231, 235, 167, 148, 247, 77, 23, 252, 147, 239, + 55, 252, 7, 14, 103, 88, 159, 235, 4, 220, 241, 147, 251, 242, 203, 149, 231, 39, 229, 216, 47, 219, 50, + 190, 191, 166, 243, 143, 249, 223, 230, 55, 223, 172, 228, 31, 215, 78, 229, 216, 207, 240, 31, 96, 254, + 139, 138, 180, 2, 242, 191, 115, 195, 6, 190, 215, 18, 107, 254, 114, 221, 103, 142, 212, 238, 249, 6, 1, + 65, 17, 235, 115, 157, 80, 90, 81, 1, 187, 63, 255, 188, 50, 247, 163, 216, 159, 98, 63, 108, 243, 2, 131, + 128, 65, 53, 223, 118, 148, 148, 149, 193, 193, 221, 187, 33, 241, 166, 155, 248, 248, 55, 252, 95, 102, + 254, 79, 159, 214, 10, 152, 3, 158, 40, 44, 132, 105, 13, 26, 240, 248, 223, 240, 127, 121, 113, 154, 245, + 185, 78, 64, 31, 80, 92, 90, 10, 243, 67, 67, 249, 186, 175, 225, 255, 234, 226, 31, 129, 187, 255, 222, + 28, 62, 156, 175, 253, 201, 181, 63, 226, 223, 104, 32, 128, 252, 159, 58, 165, 29, 112, 231, 127, 206, + 194, 133, 85, 248, 199, 241, 255, 130, 212, 238, 133, 6, 1, 193, 41, 214, 223, 186, 161, 164, 188, 28, 118, + 125, 246, 89, 229, 179, 20, 179, 172, 11, 253, 191, 234, 126, 171, 41, 80, 205, 181, 19, 138, 88, 12, 248, + 191, 35, 71, 32, 235, 238, 187, 249, 62, 90, 228, 95, 246, 255, 134, 255, 128, 225, 255, 179, 102, 232, + 201, 45, 175, 224, 26, 0, 0, 42, 23, 109, 107, 66, 84, 250, 206, 202, 254, 0, 127, 212, 240, 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, 120, 156, 237, 125, 43, + 184, 236, 40, 214, 246, 146, 72, 44, 18, 137, 196, 34, 145, 72, 36, 22, 25, 137, 196, 34, 35, 145, 88, 36, + 18, 25, 137, 141, 140, 140, 140, 141, 44, 153, 127, 81, 251, 156, 238, 158, 158, 233, 249, 212, 255, 212, + 136, 90, 115, 233, 62, 85, 123, 215, 9, 176, 46, 239, 187, 46, 84, 230, 231, 125, 54, 158, 0, 218, 179, + 145, 45, 198, 215, 70, 96, 135, 163, 195, 2, 112, 93, 197, 5, 107, 0, 223, 133, 126, 195, 243, 98, 29, 224, + 129, 10, 16, 1, 182, 10, 27, 208, 158, 36, 193, 119, 221, 147, 217, 177, 132, 193, 241, 205, 124, 115, 252, + 241, 67, 111, 0, 149, 155, 221, 65, 43, 213, 113, 51, 182, 190, 108, 79, 21, 20, 224, 120, 157, 64, 225, + 40, 233, 48, 240, 97, 185, 175, 43, 63, 247, 9, 18, 160, 220, 84, 44, 164, 95, 141, 3, 175, 55, 129, 184, + 115, 92, 157, 219, 222, 207, 152, 94, 66, 108, 49, 41, 252, 67, 17, 243, 149, 210, 15, 15, 43, 212, 107, + 219, 40, 238, 70, 121, 78, 34, 56, 245, 150, 100, 80, 67, 204, 95, 57, 22, 200, 210, 62, 79, 6, 48, 38, + 108, 171, 52, 184, 143, 73, 109, 43, 254, 238, 235, 110, 144, 119, 238, 219, 71, 23, 143, 114, 197, 176, + 248, 141, 153, 224, 1, 60, 81, 170, 131, 113, 9, 15, 209, 20, 9, 43, 175, 151, 178, 133, 72, 147, 125, 12, + 250, 161, 174, 193, 101, 161, 183, 29, 127, 113, 143, 185, 174, 126, 126, 130, 91, 41, 46, 163, 53, 99, + 131, 137, 54, 44, 214, 250, 184, 197, 192, 193, 130, 109, 14, 158, 29, 4, 117, 79, 160, 248, 239, 168, 57, + 112, 92, 248, 211, 253, 60, 47, 27, 15, 47, 63, 188, 252, 183, 184, 78, 196, 58, 18, 158, 147, 77, 194, + 155, 5, 112, 41, 182, 21, 32, 21, 246, 196, 156, 45, 28, 213, 30, 50, 112, 192, 39, 15, 135, 117, 75, 113, + 96, 2, 190, 180, 205, 95, 183, 224, 218, 230, 192, 31, 213, 47, 184, 153, 251, 54, 252, 52, 29, 60, 126, 0, + 133, 11, 180, 30, 55, 55, 83, 234, 27, 129, 199, 225, 78, 221, 213, 66, 81, 215, 225, 214, 237, 243, 235, + 167, 168, 148, 117, 77, 224, 247, 123, 143, 142, 251, 53, 200, 37, 46, 66, 166, 78, 201, 138, 11, 24, 107, + 58, 24, 9, 107, 155, 78, 192, 188, 109, 129, 57, 216, 15, 252, 231, 2, 42, 167, 117, 129, 85, 197, 124, 50, + 168, 134, 217, 37, 59, 209, 239, 17, 129, 155, 171, 29, 184, 93, 70, 225, 97, 215, 146, 41, 207, 11, 170, + 82, 69, 37, 72, 87, 99, 48, 77, 103, 3, 198, 62, 187, 248, 41, 47, 116, 105, 104, 147, 102, 152, 245, 213, + 9, 209, 184, 88, 134, 62, 202, 202, 28, 168, 18, 203, 69, 203, 197, 242, 227, 41, 21, 150, 212, 60, 15, 44, + 233, 54, 246, 115, 52, 197, 225, 192, 127, 214, 53, 155, 122, 224, 98, 240, 63, 164, 162, 74, 31, 240, 224, + 246, 92, 27, 60, 25, 79, 28, 77, 37, 79, 35, 40, 55, 228, 54, 224, 58, 167, 22, 61, 9, 157, 170, 234, 253, + 211, 139, 7, 89, 65, 163, 247, 194, 131, 72, 13, 182, 171, 8, 144, 76, 160, 115, 54, 155, 206, 3, 77, 131, + 88, 234, 200, 249, 66, 99, 88, 157, 38, 199, 152, 74, 189, 19, 116, 4, 101, 187, 46, 202, 246, 18, 252, + 168, 207, 9, 51, 46, 24, 106, 101, 40, 148, 207, 63, 212, 60, 63, 157, 45, 49, 233, 36, 112, 157, 79, 1, + 61, 0, 253, 127, 120, 20, 26, 18, 140, 11, 255, 218, 253, 9, 31, 93, 60, 74, 116, 194, 161, 183, 86, 103, + 155, 154, 96, 124, 73, 44, 60, 228, 184, 149, 125, 224, 70, 243, 14, 81, 106, 93, 208, 111, 37, 91, 80, 97, + 209, 253, 1, 136, 54, 253, 24, 88, 18, 89, 191, 205, 60, 225, 23, 170, 63, 16, 168, 89, 111, 104, 0, 128, + 70, 158, 23, 252, 48, 54, 55, 225, 129, 173, 31, 54, 74, 70, 241, 151, 71, 91, 240, 133, 5, 119, 118, 41, + 154, 207, 55, 63, 44, 28, 228, 64, 119, 142, 10, 141, 6, 110, 77, 224, 199, 166, 221, 19, 109, 204, 5, 202, + 107, 62, 63, 245, 232, 201, 76, 218, 106, 239, 15, 179, 21, 61, 128, 221, 15, 218, 37, 119, 131, 90, 136, + 105, 122, 70, 84, 120, 6, 129, 16, 244, 132, 36, 17, 129, 175, 107, 80, 246, 56, 155, 69, 183, 144, 109, + 242, 248, 9, 106, 65, 79, 153, 241, 212, 215, 250, 222, 128, 171, 158, 28, 62, 126, 254, 146, 134, 229, + 220, 224, 216, 134, 145, 186, 6, 233, 66, 57, 250, 181, 226, 9, 134, 11, 214, 164, 2, 56, 85, 173, 171, 75, + 28, 14, 67, 195, 118, 180, 106, 98, 235, 15, 76, 11, 232, 229, 231, 67, 188, 2, 239, 128, 121, 175, 5, 161, + 11, 231, 30, 141, 59, 164, 109, 23, 106, 11, 80, 46, 212, 5, 32, 151, 248, 227, 239, 68, 107, 241, 21, 194, + 234, 119, 254, 161, 85, 255, 69, 194, 194, 128, 51, 244, 220, 168, 193, 148, 145, 149, 146, 56, 120, 235, + 85, 192, 133, 74, 202, 252, 185, 115, 18, 143, 163, 18, 137, 158, 92, 132, 179, 8, 14, 232, 201, 159, 142, + 43, 59, 6, 125, 7, 4, 115, 173, 24, 70, 16, 227, 29, 81, 40, 30, 75, 73, 173, 238, 247, 166, 88, 221, 155, + 132, 198, 168, 10, 185, 49, 11, 203, 250, 254, 43, 75, 143, 250, 168, 232, 100, 88, 140, 31, 93, 59, 74, + 196, 163, 142, 239, 99, 8, 136, 120, 36, 157, 167, 68, 209, 215, 183, 222, 15, 16, 158, 162, 19, 88, 96, + 105, 215, 30, 32, 236, 168, 235, 209, 16, 64, 108, 204, 143, 251, 114, 110, 176, 109, 36, 129, 168, 198, + 94, 215, 57, 206, 132, 239, 122, 66, 71, 207, 158, 160, 81, 61, 21, 198, 110, 102, 16, 228, 107, 132, 68, + 234, 246, 172, 101, 59, 10, 60, 168, 253, 248, 22, 97, 211, 252, 62, 44, 181, 226, 162, 158, 155, 106, 198, + 239, 107, 135, 48, 66, 159, 91, 112, 40, 245, 226, 36, 191, 29, 0, 186, 135, 199, 160, 145, 219, 246, 204, + 112, 253, 52, 12, 110, 203, 25, 203, 113, 96, 148, 88, 198, 147, 249, 9, 250, 118, 207, 181, 246, 232, 24, + 217, 46, 120, 245, 72, 110, 140, 251, 141, 111, 114, 159, 74, 190, 128, 207, 53, 172, 241, 193, 224, 255, + 72, 224, 28, 117, 169, 137, 241, 234, 235, 135, 151, 143, 11, 102, 224, 167, 22, 12, 237, 215, 215, 97, + 236, 24, 149, 134, 137, 91, 90, 23, 25, 58, 62, 60, 199, 77, 64, 74, 163, 57, 243, 2, 253, 2, 172, 226, 36, + 211, 113, 93, 21, 1, 161, 0, 125, 61, 72, 133, 22, 12, 107, 4, 208, 254, 51, 198, 202, 24, 186, 227, 175, + 249, 233, 178, 186, 116, 191, 81, 147, 61, 127, 130, 1, 44, 9, 55, 198, 199, 6, 181, 223, 187, 253, 236, + 234, 231, 115, 13, 196, 62, 144, 227, 162, 51, 248, 182, 239, 222, 220, 54, 91, 166, 209, 103, 149, 168, + 151, 12, 82, 76, 141, 216, 141, 170, 168, 249, 17, 173, 63, 23, 183, 40, 12, 141, 38, 119, 221, 46, 55, 67, + 35, 126, 66, 123, 8, 130, 93, 175, 211, 10, 215, 226, 151, 85, 212, 87, 2, 178, 12, 55, 153, 210, 49, 127, + 106, 107, 126, 130, 101, 148, 99, 71, 187, 191, 114, 22, 203, 199, 249, 31, 208, 227, 68, 216, 46, 27, 18, + 61, 244, 203, 75, 180, 220, 238, 235, 8, 197, 64, 221, 87, 221, 199, 177, 77, 18, 3, 251, 48, 229, 128, + 144, 3, 227, 251, 237, 232, 228, 188, 48, 206, 92, 6, 218, 242, 120, 127, 144, 243, 174, 118, 207, 113, + 223, 78, 90, 162, 11, 62, 35, 4, 198, 13, 131, 132, 140, 224, 66, 69, 151, 9, 153, 165, 41, 149, 130, 186, + 38, 121, 216, 65, 125, 116, 229, 63, 66, 251, 234, 11, 89, 236, 109, 40, 194, 87, 73, 112, 225, 129, 201, + 177, 242, 128, 241, 11, 184, 124, 189, 50, 151, 43, 232, 253, 224, 92, 50, 183, 246, 32, 237, 222, 41, 144, + 108, 220, 56, 183, 214, 116, 108, 24, 5, 28, 193, 64, 90, 46, 66, 189, 128, 163, 239, 24, 4, 149, 101, 241, + 133, 139, 141, 131, 82, 83, 223, 244, 129, 198, 131, 109, 62, 100, 152, 73, 129, 233, 254, 108, 254, 244, + 242, 39, 78, 13, 97, 134, 100, 196, 162, 71, 51, 185, 37, 141, 134, 188, 35, 171, 41, 63, 232, 188, 207, + 36, 5, 1, 115, 31, 28, 223, 9, 3, 95, 53, 61, 19, 178, 237, 89, 28, 199, 66, 82, 35, 45, 107, 34, 113, 71, + 80, 45, 208, 101, 18, 254, 34, 231, 102, 173, 193, 8, 194, 225, 37, 214, 169, 45, 207, 147, 51, 30, 55, + 234, 208, 228, 204, 200, 56, 212, 77, 57, 153, 25, 129, 207, 138, 25, 138, 44, 27, 172, 232, 228, 95, 42, + 110, 59, 72, 130, 193, 250, 198, 69, 22, 66, 198, 177, 134, 29, 214, 99, 108, 191, 126, 248, 206, 238, 177, + 231, 13, 203, 157, 91, 131, 142, 47, 115, 97, 159, 103, 184, 73, 21, 23, 69, 8, 50, 229, 44, 122, 3, 210, + 49, 218, 23, 116, 129, 27, 58, 146, 107, 76, 198, 211, 231, 206, 193, 6, 161, 205, 237, 28, 200, 153, 8, + 15, 229, 163, 139, 71, 41, 230, 28, 212, 123, 18, 55, 202, 111, 240, 203, 197, 110, 100, 168, 248, 164, + 232, 183, 240, 225, 149, 123, 64, 114, 245, 80, 152, 62, 16, 198, 107, 194, 119, 140, 107, 215, 189, 190, + 161, 11, 35, 184, 15, 107, 88, 23, 102, 121, 145, 18, 214, 69, 199, 247, 154, 200, 65, 169, 205, 66, 194, + 57, 194, 117, 77, 16, 176, 219, 222, 52, 80, 61, 185, 95, 4, 211, 108, 146, 144, 198, 103, 87, 143, 174, + 216, 135, 221, 78, 149, 20, 213, 35, 150, 95, 110, 153, 135, 71, 239, 164, 112, 3, 112, 11, 44, 90, 133, + 30, 18, 255, 85, 117, 155, 54, 200, 147, 247, 195, 86, 166, 155, 211, 176, 184, 229, 48, 69, 75, 145, 55, + 42, 124, 183, 253, 24, 93, 175, 123, 157, 252, 55, 53, 70, 92, 233, 212, 182, 187, 250, 122, 81, 216, 21, + 160, 122, 33, 225, 130, 199, 7, 9, 117, 21, 72, 128, 62, 238, 255, 243, 166, 117, 112, 154, 178, 218, 246, + 245, 84, 217, 163, 187, 111, 51, 80, 41, 136, 248, 180, 91, 224, 94, 213, 54, 227, 214, 218, 243, 227, 96, + 32, 45, 154, 100, 38, 18, 225, 42, 61, 182, 37, 196, 192, 202, 102, 89, 146, 60, 191, 94, 146, 131, 216, + 183, 96, 95, 54, 157, 168, 223, 200, 124, 104, 29, 184, 204, 235, 5, 51, 216, 161, 62, 128, 132, 50, 32, + 25, 80, 186, 16, 250, 113, 255, 215, 55, 7, 21, 207, 142, 179, 11, 253, 213, 14, 252, 44, 78, 115, 190, + 106, 187, 70, 153, 61, 66, 181, 138, 252, 96, 11, 168, 237, 129, 179, 149, 67, 167, 242, 246, 4, 105, 142, + 85, 146, 41, 1, 82, 233, 144, 143, 64, 76, 197, 223, 6, 210, 174, 132, 139, 255, 137, 29, 2, 183, 199, 167, + 109, 98, 60, 50, 19, 70, 72, 147, 82, 113, 176, 178, 28, 195, 185, 70, 189, 30, 229, 227, 248, 247, 88, 28, + 186, 105, 141, 228, 142, 178, 245, 79, 109, 172, 71, 65, 253, 221, 16, 183, 244, 210, 125, 58, 182, 42, 26, + 190, 203, 19, 117, 12, 196, 102, 5, 216, 58, 29, 64, 202, 171, 82, 72, 153, 46, 3, 242, 217, 239, 138, 176, + 54, 194, 241, 188, 177, 195, 54, 142, 106, 144, 229, 1, 167, 99, 230, 71, 79, 112, 79, 45, 13, 16, 250, + 173, 54, 29, 72, 23, 210, 253, 250, 220, 202, 127, 75, 157, 201, 74, 230, 219, 85, 192, 206, 236, 22, 58, + 186, 74, 199, 131, 190, 157, 138, 253, 201, 118, 60, 103, 122, 142, 227, 140, 232, 4, 241, 32, 241, 255, 8, + 49, 70, 42, 113, 109, 153, 45, 59, 147, 13, 73, 242, 141, 20, 0, 55, 13, 63, 3, 222, 30, 226, 79, 236, 40, + 89, 114, 13, 217, 100, 101, 199, 10, 207, 201, 70, 6, 202, 23, 13, 229, 153, 9, 210, 250, 209, 165, 255, + 150, 114, 197, 216, 72, 150, 16, 31, 203, 193, 97, 236, 199, 199, 219, 161, 232, 165, 62, 24, 198, 16, 0, + 44, 161, 149, 184, 175, 51, 255, 139, 27, 68, 236, 90, 8, 139, 185, 69, 241, 202, 198, 174, 1, 210, 113, + 113, 240, 236, 216, 55, 112, 27, 129, 63, 184, 131, 200, 140, 222, 75, 172, 6, 144, 247, 197, 37, 14, 200, + 167, 36, 129, 59, 15, 226, 188, 63, 30, 253, 81, 172, 114, 24, 141, 54, 179, 112, 80, 3, 55, 96, 188, 97, + 153, 134, 184, 233, 94, 61, 132, 7, 132, 253, 201, 82, 231, 182, 95, 23, 134, 245, 153, 179, 41, 109, 163, + 132, 199, 62, 192, 68, 51, 35, 30, 194, 163, 12, 188, 95, 39, 13, 231, 73, 254, 194, 29, 201, 173, 117, 15, + 205, 139, 67, 193, 202, 45, 82, 141, 110, 16, 101, 227, 175, 132, 179, 178, 207, 243, 31, 115, 115, 149, + 192, 238, 76, 207, 204, 60, 200, 173, 47, 19, 181, 224, 27, 82, 41, 124, 76, 116, 95, 49, 187, 233, 242, + 193, 60, 117, 245, 125, 69, 10, 68, 200, 122, 108, 194, 241, 36, 20, 72, 211, 17, 14, 43, 239, 78, 8, 29, + 95, 21, 50, 236, 191, 115, 7, 99, 1, 219, 175, 45, 242, 114, 72, 145, 86, 46, 160, 25, 179, 165, 136, 244, + 26, 255, 206, 212, 214, 143, 39, 128, 145, 239, 140, 153, 133, 40, 125, 11, 224, 111, 9, 178, 237, 58, 93, + 232, 172, 167, 219, 54, 167, 70, 104, 108, 119, 177, 134, 188, 64, 140, 210, 122, 198, 123, 54, 186, 80, + 95, 153, 63, 12, 1, 182, 13, 69, 235, 27, 210, 221, 24, 208, 104, 179, 162, 246, 223, 185, 163, 131, 195, + 118, 162, 230, 75, 171, 12, 47, 251, 66, 233, 34, 77, 210, 254, 178, 104, 59, 192, 215, 241, 241, 250, 23, + 231, 4, 208, 177, 161, 111, 191, 235, 41, 103, 82, 2, 109, 32, 195, 36, 172, 53, 191, 44, 32, 148, 69, 131, + 120, 252, 40, 63, 170, 58, 19, 182, 103, 192, 85, 235, 181, 133, 23, 70, 188, 52, 158, 153, 234, 192, 32, + 9, 232, 224, 22, 8, 243, 181, 223, 185, 195, 69, 52, 140, 129, 6, 33, 150, 179, 113, 63, 16, 108, 228, 152, + 7, 144, 245, 65, 174, 245, 14, 136, 159, 22, 89, 118, 180, 238, 115, 58, 109, 82, 30, 170, 40, 71, 7, 255, + 176, 90, 223, 121, 218, 71, 113, 132, 43, 119, 48, 17, 41, 78, 122, 251, 246, 231, 225, 117, 136, 89, 244, + 45, 197, 38, 149, 167, 143, 232, 192, 34, 162, 89, 16, 9, 61, 39, 73, 134, 253, 206, 29, 131, 56, 240, 183, + 232, 24, 123, 187, 153, 109, 136, 27, 76, 47, 126, 132, 185, 143, 25, 131, 194, 33, 254, 143, 199, 251, + 255, 46, 227, 66, 239, 174, 224, 216, 209, 204, 65, 61, 168, 158, 248, 231, 188, 177, 89, 153, 203, 12, + 124, 122, 4, 244, 240, 58, 102, 137, 27, 35, 194, 172, 127, 111, 104, 185, 50, 88, 106, 129, 248, 199, 188, + 73, 124, 49, 214, 216, 105, 51, 19, 65, 40, 124, 249, 167, 118, 16, 102, 49, 197, 3, 19, 165, 214, 13, 78, + 75, 128, 136, 154, 76, 192, 205, 171, 26, 218, 46, 159, 235, 211, 235, 63, 210, 114, 217, 93, 195, 113, 66, + 83, 160, 94, 35, 111, 22, 242, 254, 46, 108, 128, 37, 4, 122, 2, 226, 226, 129, 139, 13, 175, 196, 247, 89, + 210, 227, 126, 105, 136, 228, 148, 131, 80, 174, 0, 136, 113, 16, 30, 235, 117, 38, 55, 40, 132, 5, 28, + 249, 85, 59, 66, 2, 161, 146, 108, 32, 122, 70, 235, 120, 215, 142, 6, 179, 129, 162, 139, 77, 155, 247, + 203, 242, 11, 44, 124, 80, 102, 12, 86, 245, 214, 160, 246, 107, 130, 145, 39, 155, 78, 186, 244, 98, 204, + 148, 47, 161, 36, 69, 78, 149, 185, 170, 10, 72, 3, 65, 215, 105, 222, 251, 81, 11, 61, 130, 117, 45, 31, + 47, 84, 230, 81, 65, 68, 57, 147, 163, 168, 210, 103, 213, 236, 87, 237, 240, 224, 37, 89, 90, 239, 174, + 92, 128, 159, 218, 97, 212, 165, 164, 227, 53, 144, 79, 173, 106, 114, 168, 15, 203, 209, 241, 169, 248, + 117, 34, 57, 227, 214, 66, 216, 122, 112, 131, 204, 172, 214, 118, 108, 165, 173, 108, 61, 11, 131, 16, + 143, 30, 21, 201, 184, 89, 236, 232, 199, 121, 159, 21, 220, 190, 53, 116, 3, 253, 133, 166, 210, 17, 11, + 215, 109, 69, 131, 129, 122, 158, 43, 252, 170, 29, 239, 77, 27, 177, 190, 139, 62, 168, 76, 191, 107, 199, + 61, 139, 114, 114, 12, 52, 141, 3, 249, 236, 234, 167, 252, 20, 47, 103, 253, 15, 154, 69, 192, 114, 18, + 254, 192, 126, 80, 134, 24, 166, 110, 66, 223, 91, 160, 174, 92, 103, 91, 21, 123, 161, 171, 135, 146, 103, + 26, 163, 227, 89, 219, 3, 118, 82, 159, 87, 39, 27, 134, 135, 10, 123, 70, 101, 176, 109, 49, 239, 222, 1, + 140, 123, 11, 2, 221, 119, 190, 7, 3, 76, 255, 213, 59, 144, 29, 55, 168, 38, 36, 145, 231, 254, 120, 250, + 99, 218, 248, 195, 208, 48, 159, 11, 129, 142, 158, 110, 221, 246, 137, 243, 237, 38, 17, 250, 218, 117, + 197, 64, 53, 115, 67, 232, 20, 67, 213, 177, 109, 156, 241, 31, 56, 72, 24, 131, 227, 101, 102, 241, 239, + 185, 198, 116, 12, 146, 206, 60, 80, 74, 90, 255, 244, 142, 176, 64, 131, 143, 239, 144, 249, 200, 220, + 255, 232, 29, 161, 187, 22, 52, 157, 75, 124, 174, 143, 35, 96, 14, 23, 125, 23, 97, 159, 107, 17, 82, 78, + 226, 255, 160, 39, 151, 126, 73, 85, 33, 194, 107, 242, 87, 1, 128, 129, 76, 140, 155, 90, 215, 245, 68, + 152, 4, 78, 75, 149, 193, 165, 5, 247, 204, 161, 85, 227, 6, 12, 163, 156, 207, 196, 247, 253, 221, 59, + 180, 154, 103, 204, 18, 239, 76, 126, 97, 40, 93, 229, 175, 222, 33, 66, 106, 118, 232, 40, 209, 102, 242, + 199, 245, 31, 163, 191, 185, 244, 92, 183, 243, 66, 229, 5, 125, 146, 65, 117, 72, 247, 82, 161, 164, 160, + 17, 6, 206, 2, 0, 213, 103, 235, 247, 152, 238, 26, 77, 31, 238, 11, 168, 60, 55, 135, 12, 79, 139, 183, + 58, 200, 237, 202, 91, 247, 109, 54, 117, 237, 118, 246, 142, 221, 199, 59, 51, 142, 230, 181, 61, 200, + 252, 238, 119, 29, 233, 167, 119, 140, 110, 30, 232, 251, 175, 255, 248, 250, 143, 151, 4, 164, 164, 51, + 112, 75, 254, 206, 77, 162, 164, 182, 165, 131, 168, 171, 123, 243, 46, 0, 116, 11, 174, 34, 161, 3, 243, + 110, 116, 154, 26, 63, 19, 224, 235, 141, 100, 105, 241, 176, 98, 204, 67, 54, 179, 243, 61, 176, 202, 69, + 9, 179, 25, 160, 30, 173, 30, 213, 14, 133, 44, 128, 165, 27, 209, 174, 79, 200, 10, 178, 156, 245, 48, + 185, 104, 254, 118, 135, 203, 71, 23, 143, 146, 59, 30, 61, 186, 239, 245, 77, 86, 37, 165, 19, 246, 247, + 155, 202, 170, 136, 114, 252, 167, 0, 192, 228, 194, 52, 157, 72, 24, 13, 29, 56, 114, 228, 217, 212, 6, + 75, 236, 141, 128, 201, 120, 186, 237, 65, 28, 244, 58, 202, 50, 13, 218, 17, 101, 192, 46, 169, 172, 1, + 215, 221, 159, 48, 78, 60, 103, 157, 235, 228, 131, 248, 153, 39, 136, 166, 202, 238, 205, 54, 163, 233, + 135, 37, 193, 195, 71, 204, 49, 214, 214, 183, 109, 125, 238, 161, 94, 106, 174, 110, 237, 210, 189, 211, + 83, 253, 48, 12, 67, 122, 1, 139, 199, 237, 76, 88, 134, 51, 253, 156, 200, 85, 131, 246, 132, 77, 59, 94, + 5, 226, 254, 94, 21, 126, 88, 99, 176, 189, 142, 128, 1, 97, 1, 26, 232, 118, 3, 71, 72, 5, 117, 34, 225, + 231, 13, 49, 138, 243, 107, 78, 215, 75, 253, 84, 130, 63, 44, 136, 217, 231, 114, 131, 61, 238, 220, 142, + 134, 88, 125, 54, 67, 66, 16, 87, 54, 219, 187, 0, 144, 70, 223, 23, 168, 92, 238, 51, 150, 109, 123, 52, + 33, 93, 57, 255, 225, 187, 173, 215, 220, 74, 52, 110, 233, 20, 216, 19, 53, 74, 211, 115, 132, 119, 130, + 220, 94, 12, 170, 68, 159, 247, 104, 168, 15, 130, 141, 244, 140, 122, 246, 130, 187, 182, 163, 223, 253, + 56, 255, 149, 224, 28, 80, 235, 148, 93, 151, 122, 157, 23, 240, 243, 186, 49, 182, 27, 120, 165, 226, 126, + 23, 0, 252, 181, 74, 56, 35, 99, 190, 37, 129, 207, 190, 19, 174, 183, 99, 70, 123, 100, 243, 151, 27, 221, + 223, 3, 29, 186, 189, 111, 29, 247, 136, 64, 119, 197, 48, 137, 81, 115, 80, 175, 227, 185, 18, 154, 95, + 21, 204, 129, 206, 32, 63, 8, 51, 121, 66, 50, 196, 144, 123, 124, 190, 255, 5, 53, 179, 167, 184, 135, + 125, 203, 62, 120, 123, 113, 40, 97, 191, 178, 219, 209, 130, 97, 161, 63, 5, 128, 142, 208, 254, 81, 147, + 37, 242, 167, 204, 108, 193, 172, 246, 52, 244, 130, 164, 207, 130, 120, 109, 87, 73, 215, 134, 128, 71, + 237, 175, 166, 67, 232, 26, 210, 244, 236, 49, 18, 234, 18, 146, 8, 219, 18, 107, 215, 81, 214, 253, 140, + 51, 105, 74, 104, 27, 220, 44, 199, 255, 128, 250, 227, 250, 137, 26, 75, 186, 154, 82, 136, 247, 197, 196, + 240, 162, 21, 196, 194, 200, 246, 200, 79, 1, 96, 250, 200, 231, 133, 202, 178, 187, 134, 143, 60, 33, 243, + 141, 91, 16, 158, 184, 78, 119, 217, 244, 182, 97, 196, 220, 248, 182, 162, 90, 128, 142, 192, 120, 137, + 92, 82, 116, 118, 154, 1, 210, 94, 90, 74, 237, 221, 97, 92, 40, 1, 202, 30, 200, 90, 153, 80, 69, 150, + 143, 235, 255, 238, 32, 49, 138, 154, 222, 163, 5, 161, 104, 142, 224, 247, 157, 236, 121, 6, 48, 247, 83, + 0, 144, 76, 33, 200, 121, 14, 205, 81, 3, 80, 15, 204, 158, 16, 237, 35, 82, 64, 211, 177, 38, 52, 175, 97, + 159, 57, 16, 2, 39, 50, 201, 1, 158, 196, 139, 224, 182, 73, 21, 172, 69, 199, 56, 88, 201, 248, 73, 114, + 213, 196, 10, 52, 168, 19, 150, 42, 121, 158, 253, 98, 31, 207, 127, 139, 203, 188, 211, 26, 47, 35, 137, + 13, 120, 176, 221, 209, 220, 59, 198, 50, 82, 126, 23, 0, 170, 139, 1, 245, 226, 25, 214, 225, 79, 55, 207, + 237, 162, 104, 239, 147, 213, 152, 85, 142, 243, 94, 8, 167, 107, 4, 244, 13, 187, 154, 165, 227, 167, 40, + 228, 190, 160, 44, 165, 136, 159, 50, 24, 135, 252, 215, 41, 207, 67, 7, 247, 58, 40, 217, 144, 59, 151, + 28, 81, 51, 62, 189, 254, 52, 225, 41, 250, 37, 136, 249, 212, 98, 54, 238, 23, 66, 56, 1, 253, 92, 160, + 20, 31, 179, 0, 112, 181, 245, 154, 201, 236, 171, 101, 60, 234, 186, 237, 83, 233, 185, 16, 144, 130, 216, + 236, 218, 43, 211, 106, 115, 240, 196, 112, 140, 132, 184, 8, 223, 37, 60, 38, 25, 116, 123, 51, 63, 140, + 163, 8, 172, 124, 78, 6, 41, 112, 55, 17, 98, 153, 212, 2, 127, 238, 227, 233, 63, 212, 97, 164, 105, 228, + 68, 19, 181, 87, 108, 8, 127, 146, 22, 1, 161, 189, 240, 136, 88, 151, 159, 2, 192, 90, 218, 62, 59, 117, + 248, 157, 41, 164, 107, 111, 3, 41, 35, 87, 225, 200, 205, 83, 154, 110, 174, 99, 82, 189, 120, 244, 148, + 123, 91, 192, 115, 88, 118, 49, 164, 172, 57, 53, 137, 17, 95, 172, 26, 172, 48, 75, 233, 24, 245, 193, 24, + 138, 17, 182, 213, 153, 55, 218, 62, 158, 0, 84, 112, 161, 53, 135, 139, 184, 217, 180, 164, 108, 26, 51, + 165, 83, 252, 34, 216, 157, 234, 76, 238, 189, 136, 88, 144, 234, 133, 231, 157, 171, 91, 225, 53, 109, + 246, 161, 248, 14, 12, 186, 191, 81, 0, 61, 34, 117, 125, 246, 145, 198, 112, 207, 152, 42, 120, 141, 98, + 246, 213, 137, 186, 238, 227, 151, 227, 35, 105, 77, 43, 179, 249, 64, 187, 90, 33, 144, 9, 254, 183, 207, + 174, 126, 106, 224, 210, 89, 148, 221, 172, 21, 24, 145, 161, 180, 210, 36, 30, 63, 53, 138, 149, 160, 109, + 6, 116, 234, 117, 136, 93, 32, 135, 37, 142, 64, 142, 247, 221, 133, 58, 14, 52, 104, 56, 219, 131, 184, + 152, 161, 187, 116, 117, 236, 23, 51, 192, 59, 250, 10, 206, 145, 79, 164, 49, 65, 47, 114, 139, 191, 4, + 190, 153, 5, 10, 27, 198, 17, 207, 82, 42, 53, 192, 199, 251, 255, 203, 236, 105, 220, 38, 106, 35, 4, 89, + 30, 50, 58, 186, 36, 90, 8, 40, 97, 173, 100, 230, 64, 223, 62, 39, 122, 10, 158, 20, 6, 132, 215, 76, 16, + 172, 175, 179, 172, 219, 2, 23, 235, 135, 182, 169, 189, 54, 90, 144, 209, 192, 56, 124, 96, 27, 198, 54, + 221, 34, 2, 229, 140, 88, 1, 49, 223, 95, 128, 15, 122, 5, 39, 16, 13, 238, 70, 45, 169, 247, 187, 209, + 143, 251, 63, 176, 250, 88, 94, 2, 242, 11, 65, 58, 63, 49, 8, 162, 7, 59, 216, 204, 104, 47, 75, 24, 158, + 86, 66, 39, 245, 7, 12, 252, 118, 79, 110, 18, 31, 25, 207, 4, 70, 83, 242, 130, 188, 201, 12, 245, 6, 198, + 164, 234, 176, 239, 204, 222, 81, 123, 61, 107, 104, 55, 153, 192, 23, 77, 229, 175, 192, 119, 88, 81, 249, + 112, 252, 92, 118, 239, 205, 147, 206, 79, 47, 255, 182, 46, 197, 246, 218, 241, 185, 10, 244, 141, 78, 51, + 183, 205, 72, 75, 82, 240, 201, 108, 138, 75, 150, 34, 155, 113, 29, 15, 242, 148, 30, 137, 94, 87, 220, 4, + 179, 104, 129, 188, 49, 119, 116, 249, 30, 227, 160, 11, 104, 64, 7, 2, 167, 172, 209, 51, 240, 101, 18, + 31, 54, 254, 78, 124, 150, 146, 23, 182, 193, 169, 139, 73, 59, 121, 238, 143, 243, 63, 31, 3, 56, 116, 91, + 6, 131, 91, 233, 33, 145, 11, 250, 165, 181, 36, 44, 31, 206, 174, 76, 173, 183, 101, 150, 34, 143, 5, 122, + 166, 229, 37, 73, 222, 134, 65, 234, 107, 220, 204, 23, 17, 82, 228, 108, 33, 51, 117, 250, 56, 224, 218, + 129, 121, 19, 223, 235, 63, 19, 95, 158, 87, 197, 233, 189, 41, 131, 65, 98, 67, 210, 245, 233, 245, 79, + 249, 33, 114, 122, 191, 132, 97, 162, 164, 53, 83, 177, 205, 110, 214, 151, 163, 179, 136, 17, 35, 194, 20, + 60, 253, 52, 51, 121, 143, 220, 54, 34, 170, 21, 160, 210, 82, 253, 234, 209, 244, 223, 131, 67, 129, 130, + 81, 4, 229, 191, 38, 62, 184, 91, 143, 188, 35, 10, 66, 0, 72, 205, 199, 189, 223, 123, 118, 161, 101, 224, + 5, 215, 107, 79, 195, 215, 84, 201, 108, 113, 40, 143, 85, 72, 3, 240, 205, 181, 104, 143, 15, 12, 187, + 221, 148, 56, 16, 186, 44, 64, 116, 176, 181, 246, 200, 195, 213, 130, 76, 219, 123, 112, 8, 180, 25, 149, + 252, 31, 137, 47, 216, 42, 203, 76, 34, 141, 20, 100, 95, 121, 12, 31, 239, 127, 159, 107, 44, 52, 238, 11, + 71, 204, 150, 253, 209, 98, 68, 62, 44, 193, 207, 46, 111, 107, 18, 34, 253, 68, 59, 134, 124, 55, 150, 91, + 46, 21, 28, 181, 68, 214, 67, 237, 23, 65, 156, 159, 17, 228, 35, 137, 105, 199, 230, 233, 108, 255, 252, + 175, 137, 207, 159, 161, 73, 214, 172, 208, 22, 242, 8, 226, 243, 222, 31, 68, 191, 113, 189, 93, 43, 222, + 24, 101, 69, 9, 149, 242, 150, 95, 171, 45, 45, 160, 153, 131, 166, 11, 218, 176, 99, 169, 28, 155, 179, + 232, 231, 128, 94, 248, 191, 165, 76, 244, 18, 152, 113, 177, 49, 126, 17, 235, 16, 67, 144, 223, 67, 147, + 255, 148, 248, 158, 67, 147, 57, 161, 142, 8, 103, 78, 141, 17, 228, 243, 253, 255, 251, 26, 147, 245, 72, + 200, 4, 56, 66, 22, 107, 104, 234, 231, 171, 74, 193, 142, 35, 90, 164, 45, 96, 250, 86, 129, 111, 167, + 153, 77, 203, 97, 32, 57, 114, 24, 17, 23, 36, 0, 19, 238, 213, 186, 20, 3, 90, 45, 188, 104, 243, 107, + 104, 242, 31, 10, 31, 63, 67, 147, 36, 183, 9, 251, 94, 150, 241, 116, 196, 143, 247, 191, 57, 100, 40, + 145, 56, 22, 80, 221, 133, 93, 218, 182, 154, 163, 215, 119, 91, 18, 162, 1, 119, 108, 24, 233, 207, 59, + 181, 140, 100, 149, 212, 110, 151, 215, 134, 244, 111, 206, 75, 171, 232, 141, 100, 249, 12, 72, 26, 166, + 222, 132, 40, 68, 250, 175, 133, 175, 159, 161, 73, 110, 252, 73, 204, 32, 77, 239, 227, 252, 95, 40, 0, + 249, 129, 188, 14, 25, 240, 26, 156, 146, 24, 238, 240, 53, 41, 54, 18, 72, 47, 246, 245, 204, 89, 205, 49, + 135, 184, 32, 177, 81, 82, 230, 140, 107, 31, 44, 110, 203, 214, 251, 88, 72, 189, 173, 6, 202, 137, 240, + 14, 145, 131, 202, 203, 63, 20, 62, 255, 24, 154, 100, 102, 147, 4, 1, 231, 38, 54, 179, 127, 252, 252, + 189, 94, 69, 127, 21, 74, 150, 109, 139, 18, 20, 170, 233, 116, 222, 200, 123, 165, 67, 151, 181, 155, 189, + 204, 67, 172, 2, 99, 96, 189, 238, 217, 48, 202, 133, 118, 30, 53, 29, 195, 194, 120, 60, 228, 131, 243, + 92, 57, 89, 2, 183, 221, 255, 99, 225, 251, 215, 208, 228, 125, 49, 218, 48, 54, 34, 215, 180, 33, 214, + 143, 243, 159, 235, 57, 234, 100, 108, 58, 39, 150, 12, 251, 49, 72, 34, 193, 60, 72, 78, 182, 2, 38, 93, + 11, 196, 53, 207, 246, 143, 54, 182, 57, 199, 33, 22, 73, 237, 49, 59, 34, 144, 201, 30, 248, 238, 89, 120, + 65, 207, 215, 75, 45, 151, 121, 245, 127, 109, 124, 104, 127, 31, 154, 12, 100, 28, 13, 162, 34, 93, 240, + 207, 215, 255, 219, 235, 185, 8, 85, 185, 46, 97, 107, 171, 103, 98, 98, 119, 50, 52, 172, 141, 166, 253, + 152, 131, 192, 106, 45, 185, 32, 81, 14, 170, 204, 194, 0, 79, 100, 150, 45, 214, 4, 214, 193, 58, 78, 138, + 20, 9, 100, 71, 167, 151, 203, 165, 77, 217, 254, 165, 241, 229, 248, 247, 161, 73, 9, 86, 248, 71, 61, + 179, 87, 248, 127, 33, 1, 114, 54, 233, 155, 119, 209, 72, 51, 243, 177, 24, 187, 22, 251, 210, 112, 34, + 241, 29, 215, 219, 139, 23, 12, 1, 185, 161, 130, 163, 35, 103, 54, 42, 120, 165, 57, 31, 240, 174, 132, + 239, 107, 123, 72, 144, 174, 60, 87, 144, 168, 246, 8, 237, 220, 66, 22, 81, 223, 141, 79, 231, 191, 15, + 77, 86, 4, 17, 249, 133, 123, 75, 104, 245, 159, 94, 60, 204, 70, 127, 21, 137, 87, 13, 29, 60, 228, 181, + 76, 192, 134, 199, 253, 58, 119, 36, 124, 176, 111, 89, 128, 156, 45, 81, 93, 60, 19, 202, 171, 205, 218, + 33, 225, 33, 229, 158, 185, 251, 240, 70, 207, 30, 113, 64, 16, 125, 51, 102, 161, 82, 248, 37, 29, 187, + 152, 141, 111, 21, 196, 191, 15, 77, 142, 163, 208, 6, 114, 175, 68, 245, 242, 241, 254, 15, 43, 203, 78, + 124, 236, 89, 205, 89, 252, 153, 142, 54, 253, 106, 27, 151, 114, 3, 49, 209, 49, 21, 107, 52, 248, 250, + 105, 39, 88, 201, 25, 252, 102, 131, 92, 58, 220, 101, 174, 222, 188, 247, 32, 220, 126, 185, 80, 57, 154, + 229, 210, 49, 237, 223, 141, 143, 179, 10, 246, 31, 134, 38, 55, 142, 56, 81, 161, 97, 112, 101, 245, 199, + 241, 239, 134, 232, 246, 136, 53, 32, 57, 111, 115, 166, 77, 218, 121, 151, 9, 245, 75, 4, 45, 209, 219, + 117, 138, 164, 117, 22, 57, 230, 220, 7, 66, 100, 120, 55, 72, 135, 86, 153, 190, 214, 216, 38, 166, 95, + 15, 168, 175, 157, 33, 67, 242, 163, 108, 1, 24, 103, 76, 14, 32, 255, 48, 52, 137, 177, 127, 183, 121, 83, + 247, 2, 165, 125, 124, 254, 113, 217, 179, 222, 107, 208, 240, 236, 1, 217, 250, 204, 98, 174, 115, 58, 1, + 102, 186, 39, 47, 208, 252, 130, 192, 14, 29, 227, 188, 179, 64, 33, 254, 93, 37, 185, 131, 220, 122, 35, + 215, 61, 196, 74, 164, 115, 199, 96, 51, 151, 127, 87, 32, 101, 122, 60, 141, 80, 73, 71, 242, 15, 67, 147, + 130, 174, 251, 48, 168, 64, 232, 52, 237, 199, 251, 191, 11, 3, 213, 222, 30, 251, 53, 184, 2, 53, 103, + 181, 149, 120, 255, 99, 142, 237, 84, 191, 71, 244, 220, 251, 85, 25, 244, 35, 175, 82, 212, 27, 67, 67, + 198, 63, 116, 100, 120, 199, 28, 244, 134, 248, 76, 96, 140, 198, 129, 56, 167, 245, 235, 233, 100, 103, + 115, 84, 226, 63, 15, 77, 54, 125, 44, 12, 2, 95, 157, 154, 147, 32, 31, 150, 92, 130, 107, 217, 172, 4, + 222, 248, 158, 108, 116, 206, 132, 108, 175, 115, 160, 139, 58, 109, 34, 50, 215, 227, 53, 183, 98, 1, 101, + 92, 93, 8, 92, 242, 12, 203, 155, 220, 228, 123, 120, 97, 223, 76, 111, 185, 139, 81, 211, 127, 108, 80, + 119, 75, 55, 141, 236, 233, 63, 15, 77, 238, 165, 137, 0, 94, 97, 44, 213, 31, 95, 254, 108, 98, 40, 212, + 192, 49, 135, 63, 241, 191, 235, 131, 6, 237, 243, 14, 207, 51, 147, 29, 132, 221, 140, 94, 55, 162, 219, + 246, 58, 240, 16, 133, 203, 222, 131, 195, 195, 94, 186, 117, 115, 172, 207, 154, 113, 66, 185, 56, 42, + 193, 141, 232, 104, 128, 71, 120, 140, 31, 176, 89, 254, 15, 67, 147, 109, 53, 2, 131, 77, 126, 237, 123, + 83, 31, 103, 192, 57, 110, 232, 145, 82, 88, 150, 29, 67, 125, 91, 249, 171, 139, 23, 159, 104, 7, 79, 206, + 116, 67, 155, 151, 49, 35, 87, 51, 232, 7, 42, 154, 251, 58, 59, 189, 38, 95, 24, 135, 71, 20, 219, 219, + 130, 180, 38, 156, 72, 124, 137, 221, 208, 224, 193, 232, 53, 130, 76, 145, 137, 255, 60, 52, 201, 131, + 239, 242, 92, 98, 5, 166, 251, 199, 251, 191, 134, 17, 151, 68, 63, 93, 102, 77, 123, 86, 54, 42, 130, 83, + 228, 60, 135, 155, 217, 219, 101, 153, 141, 48, 44, 160, 33, 171, 216, 13, 65, 180, 203, 216, 190, 188, + 231, 246, 133, 228, 161, 246, 140, 75, 184, 8, 159, 109, 164, 156, 109, 157, 193, 198, 223, 141, 195, 114, + 139, 157, 189, 79, 247, 111, 67, 147, 173, 164, 154, 252, 188, 50, 137, 10, 8, 31, 247, 127, 214, 225, 35, + 131, 195, 112, 39, 36, 180, 70, 144, 203, 191, 64, 33, 210, 123, 48, 158, 23, 86, 132, 17, 166, 89, 87, + 169, 216, 194, 111, 101, 173, 44, 169, 138, 39, 170, 139, 72, 39, 186, 191, 247, 96, 231, 114, 253, 49, + 206, 226, 218, 232, 21, 131, 35, 154, 205, 191, 15, 77, 82, 83, 150, 26, 221, 16, 19, 89, 186, 143, 223, + 127, 146, 90, 66, 29, 208, 104, 196, 124, 150, 120, 178, 183, 72, 243, 64, 13, 54, 219, 89, 122, 105, 87, + 31, 108, 132, 119, 81, 19, 193, 12, 17, 28, 225, 125, 130, 121, 113, 15, 23, 115, 224, 173, 236, 179, 33, + 96, 171, 179, 31, 126, 121, 35, 162, 45, 79, 24, 221, 11, 213, 145, 170, 246, 183, 161, 73, 162, 88, 149, + 247, 144, 109, 214, 203, 17, 20, 127, 188, 254, 7, 241, 168, 204, 121, 207, 241, 129, 209, 245, 159, 124, + 239, 252, 42, 48, 111, 64, 162, 129, 27, 93, 219, 147, 137, 94, 40, 96, 80, 15, 17, 202, 113, 237, 171, + 194, 131, 118, 182, 173, 101, 102, 183, 1, 233, 207, 118, 238, 39, 154, 79, 65, 61, 66, 128, 251, 30, 140, + 131, 221, 130, 112, 228, 239, 67, 147, 74, 35, 10, 188, 168, 16, 12, 214, 158, 158, 143, 167, 255, 113, + 149, 230, 53, 177, 13, 82, 209, 195, 238, 23, 186, 128, 235, 129, 119, 86, 38, 237, 133, 41, 12, 212, 169, + 131, 217, 110, 64, 112, 111, 239, 141, 231, 178, 93, 221, 204, 123, 51, 172, 118, 182, 58, 11, 250, 14, 24, + 199, 250, 181, 134, 222, 195, 89, 145, 232, 205, 102, 42, 97, 87, 239, 210, 95, 135, 38, 39, 10, 74, 107, + 48, 110, 165, 137, 162, 175, 68, 184, 120, 232, 143, 251, 127, 11, 148, 92, 47, 72, 147, 220, 204, 201, 68, + 12, 225, 117, 3, 206, 113, 15, 90, 150, 92, 218, 140, 71, 43, 229, 149, 181, 88, 11, 127, 236, 90, 165, 84, + 62, 122, 39, 17, 55, 249, 81, 135, 129, 113, 17, 155, 132, 185, 142, 190, 185, 201, 140, 237, 2, 35, 75, + 226, 82, 46, 242, 47, 67, 147, 187, 7, 86, 214, 220, 103, 199, 81, 215, 200, 172, 168, 229, 233, 227, 243, + 31, 92, 11, 226, 16, 236, 96, 184, 183, 63, 100, 220, 219, 23, 49, 121, 179, 148, 229, 117, 77, 219, 54, + 198, 181, 56, 90, 88, 93, 56, 195, 248, 94, 112, 133, 170, 119, 81, 235, 22, 69, 190, 231, 13, 38, 8, 239, + 140, 135, 173, 49, 22, 102, 114, 19, 82, 154, 3, 193, 75, 105, 251, 241, 231, 208, 36, 16, 71, 164, 22, + 206, 19, 211, 240, 212, 221, 156, 157, 143, 219, 199, 1, 208, 149, 24, 30, 140, 175, 240, 104, 51, 39, 129, + 192, 174, 194, 248, 148, 183, 147, 6, 199, 123, 188, 28, 20, 1, 177, 154, 30, 30, 59, 59, 214, 126, 70, + 160, 246, 75, 238, 51, 55, 208, 107, 154, 20, 150, 204, 117, 60, 8, 112, 246, 181, 100, 202, 142, 229, 232, + 136, 43, 67, 168, 127, 25, 154, 164, 8, 153, 12, 141, 82, 225, 15, 145, 247, 77, 122, 185, 198, 143, 231, + 191, 55, 27, 41, 110, 0, 210, 128, 8, 169, 230, 4, 246, 212, 32, 108, 69, 3, 14, 71, 29, 27, 121, 205, 108, + 189, 135, 58, 18, 204, 145, 255, 73, 141, 222, 237, 146, 111, 31, 177, 66, 236, 60, 65, 92, 142, 140, 154, + 92, 54, 143, 100, 240, 232, 253, 70, 166, 224, 113, 31, 224, 207, 161, 201, 133, 81, 137, 91, 226, 181, 49, + 60, 107, 168, 238, 221, 78, 195, 62, 222, 255, 151, 83, 37, 124, 235, 130, 206, 208, 149, 239, 115, 1, 84, + 117, 198, 108, 101, 193, 245, 146, 98, 154, 65, 125, 65, 184, 235, 230, 237, 22, 158, 205, 180, 254, 49, + 227, 253, 27, 48, 192, 65, 123, 31, 201, 75, 249, 147, 202, 152, 27, 20, 211, 186, 188, 116, 106, 209, 7, + 242, 199, 208, 100, 22, 76, 73, 61, 114, 158, 9, 17, 15, 162, 80, 82, 103, 243, 251, 199, 243, 95, 76, 98, + 184, 82, 179, 163, 233, 13, 197, 158, 235, 16, 108, 63, 171, 226, 144, 148, 158, 41, 33, 176, 214, 91, 171, + 137, 70, 194, 230, 8, 111, 214, 231, 11, 119, 105, 38, 2, 107, 94, 148, 67, 86, 40, 116, 64, 112, 252, 87, + 50, 211, 247, 178, 14, 243, 123, 104, 210, 120, 129, 72, 151, 71, 82, 110, 178, 4, 205, 137, 140, 101, 17, + 4, 67, 98, 250, 120, 5, 212, 137, 176, 129, 170, 233, 54, 71, 193, 179, 169, 247, 29, 145, 172, 141, 81, + 133, 214, 100, 50, 55, 92, 204, 216, 171, 100, 156, 83, 145, 27, 201, 61, 92, 187, 70, 2, 167, 102, 42, + 188, 48, 233, 145, 29, 3, 219, 163, 0, 220, 14, 79, 80, 3, 144, 250, 199, 53, 40, 114, 132, 90, 223, 153, + 19, 120, 81, 145, 16, 90, 22, 62, 8, 165, 126, 71, 160, 65, 101, 30, 78, 45, 245, 227, 249, 255, 106, 89, + 244, 220, 55, 151, 210, 190, 110, 59, 250, 110, 63, 211, 185, 34, 80, 183, 175, 120, 210, 125, 22, 135, + 183, 149, 26, 22, 16, 29, 47, 224, 78, 228, 246, 24, 0, 222, 87, 58, 221, 138, 38, 180, 151, 215, 190, 134, + 217, 58, 120, 34, 12, 234, 173, 165, 209, 131, 16, 59, 134, 196, 82, 231, 20, 237, 142, 148, 185, 23, 12, + 129, 174, 99, 228, 155, 133, 209, 153, 245, 177, 241, 220, 21, 253, 252, 253, 23, 69, 108, 109, 71, 194, + 167, 97, 61, 143, 11, 23, 104, 8, 242, 22, 194, 168, 66, 71, 95, 230, 117, 133, 179, 215, 89, 110, 90, 236, + 171, 173, 70, 89, 115, 32, 244, 85, 233, 181, 34, 21, 122, 77, 27, 38, 203, 58, 203, 221, 71, 110, 184, 1, + 207, 117, 237, 46, 245, 68, 88, 137, 26, 131, 201, 53, 88, 110, 20, 28, 154, 193, 161, 246, 2, 155, 59, + 222, 125, 182, 212, 171, 37, 88, 79, 63, 189, 126, 50, 38, 249, 221, 216, 28, 238, 184, 7, 70, 114, 106, + 106, 162, 17, 24, 162, 29, 133, 56, 136, 155, 11, 121, 65, 202, 198, 228, 23, 42, 177, 87, 16, 9, 17, 161, + 179, 19, 137, 128, 169, 210, 16, 73, 144, 210, 17, 152, 247, 4, 147, 57, 47, 185, 167, 117, 130, 98, 41, + 245, 129, 90, 179, 108, 24, 58, 235, 12, 115, 225, 188, 14, 185, 32, 56, 178, 8, 53, 192, 192, 74, 245, + 154, 62, 126, 255, 105, 180, 129, 156, 129, 144, 208, 243, 152, 73, 60, 144, 107, 157, 237, 14, 194, 182, + 13, 136, 217, 164, 227, 94, 162, 83, 215, 120, 154, 91, 139, 232, 7, 178, 214, 115, 14, 128, 173, 71, 68, + 23, 184, 225, 22, 192, 227, 40, 134, 0, 43, 137, 151, 34, 69, 163, 185, 179, 72, 110, 214, 134, 65, 95, + 155, 225, 92, 70, 176, 11, 90, 249, 189, 217, 25, 37, 210, 204, 27, 139, 146, 196, 210, 63, 222, 255, 52, + 96, 181, 4, 172, 172, 119, 157, 215, 30, 95, 123, 217, 55, 161, 28, 28, 18, 185, 16, 34, 244, 221, 48, 171, + 89, 237, 6, 241, 174, 64, 147, 102, 125, 152, 165, 182, 201, 255, 231, 197, 80, 69, 106, 175, 109, 200, + 218, 118, 58, 239, 81, 200, 30, 29, 136, 191, 4, 239, 210, 222, 114, 78, 190, 175, 91, 119, 204, 244, 157, + 122, 224, 42, 246, 177, 138, 53, 28, 8, 139, 99, 63, 162, 106, 31, 159, 255, 229, 24, 148, 172, 148, 102, + 157, 55, 181, 181, 151, 63, 75, 95, 209, 26, 80, 157, 209, 39, 44, 32, 115, 90, 40, 111, 84, 13, 124, 145, + 234, 195, 147, 92, 45, 37, 234, 232, 148, 146, 251, 104, 132, 146, 236, 121, 131, 193, 248, 197, 243, 202, + 92, 9, 99, 75, 47, 23, 9, 203, 167, 89, 71, 212, 187, 218, 144, 254, 134, 141, 18, 209, 122, 38, 99, 34, + 12, 42, 199, 40, 44, 223, 209, 127, 220, 255, 183, 121, 237, 69, 159, 113, 40, 154, 121, 7, 152, 91, 245, + 188, 178, 28, 113, 96, 229, 97, 160, 55, 88, 196, 188, 221, 224, 126, 16, 255, 193, 254, 164, 190, 82, 174, + 165, 208, 47, 230, 201, 123, 104, 146, 104, 133, 241, 204, 34, 166, 103, 248, 195, 26, 17, 61, 119, 8, 152, + 142, 247, 221, 160, 251, 213, 151, 136, 138, 132, 63, 250, 211, 233, 255, 204, 182, 145, 117, 18, 78, 29, + 104, 123, 220, 103, 23, 15, 243, 250, 63, 116, 113, 170, 158, 136, 109, 237, 44, 229, 162, 117, 162, 91, + 247, 89, 194, 243, 218, 111, 116, 255, 6, 161, 43, 244, 128, 20, 33, 171, 104, 102, 218, 231, 46, 50, 93, + 236, 221, 185, 63, 135, 38, 149, 156, 119, 65, 225, 82, 136, 180, 190, 70, 195, 196, 190, 235, 182, 190, + 17, 85, 101, 173, 130, 171, 7, 37, 253, 157, 100, 207, 203, 108, 2, 27, 179, 105, 248, 129, 139, 218, 254, + 113, 254, 151, 77, 115, 38, 231, 54, 153, 88, 155, 119, 22, 45, 38, 206, 30, 22, 89, 237, 190, 133, 51, 40, + 165, 173, 153, 71, 57, 145, 172, 123, 99, 215, 129, 204, 214, 172, 199, 191, 15, 77, 230, 221, 59, 163, + 162, 173, 233, 28, 118, 222, 240, 250, 128, 110, 129, 34, 151, 206, 8, 1, 237, 98, 181, 29, 185, 41, 4, + 189, 60, 131, 215, 190, 205, 220, 241, 135, 101, 95, 240, 49, 182, 21, 29, 252, 156, 112, 232, 232, 247, + 231, 125, 247, 171, 49, 49, 244, 221, 70, 35, 145, 223, 89, 88, 131, 129, 112, 21, 164, 113, 20, 26, 93, + 151, 220, 115, 142, 127, 31, 154, 44, 91, 194, 37, 42, 38, 28, 161, 6, 177, 64, 131, 29, 68, 188, 102, 243, + 195, 210, 185, 65, 135, 217, 153, 102, 115, 148, 12, 189, 203, 44, 168, 131, 222, 62, 191, 254, 51, 89, + 207, 28, 212, 149, 23, 8, 59, 231, 58, 35, 104, 69, 76, 172, 215, 157, 91, 1, 82, 79, 100, 139, 202, 17, + 94, 71, 233, 154, 65, 141, 203, 169, 102, 223, 126, 89, 33, 253, 203, 208, 228, 69, 229, 234, 24, 241, 8, + 110, 23, 183, 14, 244, 252, 48, 175, 126, 197, 224, 47, 171, 65, 14, 221, 242, 129, 10, 150, 75, 229, 109, + 247, 130, 1, 177, 16, 62, 94, 255, 221, 87, 89, 162, 113, 134, 34, 181, 1, 18, 19, 165, 226, 60, 24, 8, + 209, 134, 70, 138, 178, 206, 235, 42, 99, 7, 185, 189, 58, 26, 120, 219, 119, 132, 124, 164, 205, 158, 119, + 173, 151, 37, 253, 101, 104, 82, 103, 176, 229, 216, 250, 1, 230, 220, 230, 100, 191, 57, 231, 180, 252, + 204, 149, 170, 203, 195, 118, 158, 51, 192, 118, 13, 68, 103, 153, 141, 104, 231, 62, 62, 63, 255, 242, 51, + 233, 137, 104, 159, 89, 68, 107, 144, 103, 67, 227, 40, 3, 202, 185, 16, 194, 131, 170, 212, 149, 141, 244, + 215, 83, 201, 1, 183, 134, 172, 212, 156, 124, 232, 13, 17, 50, 81, 193, 252, 57, 52, 169, 40, 241, 189, + 63, 79, 71, 20, 149, 81, 51, 52, 133, 13, 102, 235, 99, 99, 179, 182, 80, 111, 112, 3, 84, 128, 89, 97, + 131, 150, 87, 40, 163, 62, 31, 199, 255, 64, 173, 116, 227, 88, 52, 136, 96, 240, 76, 71, 166, 217, 158, + 112, 149, 8, 139, 201, 132, 227, 97, 239, 227, 154, 197, 176, 108, 30, 92, 164, 91, 57, 130, 99, 251, 50, + 54, 243, 226, 85, 14, 127, 12, 77, 54, 102, 44, 186, 138, 242, 188, 203, 0, 39, 155, 23, 164, 17, 133, 6, + 158, 67, 208, 214, 241, 52, 248, 105, 60, 68, 247, 110, 4, 178, 239, 161, 35, 248, 120, 252, 151, 208, 179, + 13, 72, 122, 53, 231, 190, 15, 91, 170, 10, 178, 95, 169, 207, 193, 183, 232, 27, 180, 81, 116, 156, 193, + 109, 137, 118, 78, 203, 67, 95, 204, 241, 96, 160, 135, 120, 232, 209, 252, 226, 126, 13, 77, 98, 8, 13, + 115, 0, 22, 215, 20, 80, 69, 120, 187, 134, 199, 216, 135, 59, 226, 192, 247, 99, 87, 193, 23, 140, 42, + 110, 92, 2, 152, 214, 63, 153, 255, 143, 215, 191, 118, 131, 58, 79, 8, 245, 177, 51, 64, 102, 190, 31, + 131, 194, 210, 82, 207, 38, 198, 101, 219, 242, 245, 243, 29, 21, 239, 199, 109, 5, 150, 91, 109, 217, 156, + 67, 7, 132, 135, 234, 53, 102, 23, 40, 252, 12, 77, 214, 228, 214, 217, 78, 105, 3, 191, 142, 89, 88, 208, + 120, 208, 168, 19, 165, 230, 213, 61, 167, 52, 10, 121, 196, 72, 24, 79, 145, 60, 228, 158, 48, 124, 154, + 143, 231, 127, 28, 19, 51, 244, 165, 204, 16, 8, 204, 91, 255, 246, 66, 9, 58, 127, 100, 49, 145, 34, 90, + 217, 79, 36, 43, 75, 120, 247, 105, 204, 146, 61, 239, 115, 152, 229, 74, 184, 254, 128, 212, 103, 166, + 136, 200, 12, 5, 126, 223, 105, 91, 82, 122, 39, 134, 24, 188, 154, 7, 198, 71, 21, 158, 35, 175, 118, 145, + 151, 125, 218, 62, 165, 63, 87, 126, 112, 31, 175, 115, 207, 160, 63, 158, 255, 107, 179, 222, 65, 247, + 215, 75, 195, 114, 197, 181, 196, 197, 206, 107, 64, 150, 73, 240, 124, 62, 94, 120, 240, 115, 184, 63, + 253, 92, 213, 240, 96, 44, 68, 27, 232, 228, 245, 204, 146, 1, 169, 140, 176, 142, 251, 53, 175, 7, 233, + 157, 87, 3, 23, 143, 219, 252, 201, 94, 163, 19, 232, 248, 231, 119, 11, 128, 68, 211, 25, 181, 77, 7, 136, + 225, 22, 248, 88, 102, 95, 56, 60, 37, 124, 30, 0, 19, 56, 95, 236, 153, 137, 112, 18, 80, 243, 49, 134, + 133, 227, 238, 132, 87, 254, 192, 108, 109, 223, 131, 152, 147, 138, 102, 63, 52, 158, 253, 188, 187, 58, + 189, 242, 204, 129, 15, 147, 95, 163, 212, 148, 118, 32, 251, 143, 29, 251, 77, 224, 59, 107, 158, 58, 112, + 205, 214, 127, 178, 31, 14, 226, 28, 141, 95, 214, 249, 225, 115, 106, 216, 142, 113, 119, 93, 36, 70, 135, + 163, 125, 28, 255, 162, 21, 187, 121, 171, 13, 215, 215, 251, 44, 98, 24, 39, 213, 232, 176, 78, 135, 206, + 254, 61, 212, 111, 185, 246, 214, 244, 212, 48, 44, 10, 245, 168, 199, 255, 186, 187, 226, 126, 150, 198, + 77, 139, 30, 131, 196, 251, 10, 89, 149, 82, 180, 137, 165, 52, 226, 54, 43, 33, 143, 148, 125, 64, 126, + 117, 135, 106, 176, 99, 116, 157, 67, 212, 250, 224, 245, 80, 46, 197, 89, 40, 253, 120, 255, 215, 142, + 143, 160, 189, 215, 122, 181, 63, 55, 18, 48, 198, 87, 88, 70, 220, 163, 190, 111, 27, 3, 140, 27, 189, + 183, 175, 139, 51, 122, 14, 139, 129, 138, 128, 48, 8, 127, 176, 22, 174, 16, 193, 99, 56, 168, 82, 163, + 234, 71, 177, 162, 103, 31, 155, 48, 224, 246, 19, 12, 2, 166, 84, 151, 85, 235, 26, 248, 242, 132, 189, + 187, 4, 139, 157, 119, 173, 34, 47, 52, 179, 222, 214, 143, 143, 247, 191, 190, 238, 67, 190, 81, 96, 91, + 5, 123, 79, 179, 147, 4, 186, 99, 200, 110, 175, 93, 149, 3, 182, 43, 149, 123, 219, 123, 173, 231, 188, + 222, 213, 206, 11, 78, 17, 33, 129, 51, 149, 129, 60, 174, 222, 199, 86, 237, 130, 236, 121, 120, 233, 44, + 33, 67, 10, 230, 153, 98, 178, 46, 160, 234, 8, 108, 102, 214, 215, 229, 193, 248, 39, 14, 132, 210, 193, + 92, 32, 215, 159, 206, 207, 237, 227, 235, 103, 117, 44, 16, 206, 188, 183, 184, 154, 119, 45, 47, 22, 244, + 223, 51, 219, 165, 249, 186, 241, 237, 78, 176, 237, 226, 88, 40, 155, 99, 13, 131, 142, 211, 226, 111, + 245, 77, 17, 68, 240, 145, 115, 202, 25, 162, 97, 183, 35, 252, 35, 48, 123, 99, 13, 193, 200, 192, 240, + 37, 181, 117, 68, 87, 67, 66, 1, 19, 165, 90, 128, 65, 233, 205, 90, 54, 187, 44, 216, 143, 231, 251, 120, + 253, 11, 40, 90, 37, 135, 177, 181, 216, 231, 119, 128, 209, 192, 225, 138, 72, 98, 6, 104, 84, 98, 50, + 249, 254, 60, 36, 247, 198, 42, 99, 192, 188, 230, 8, 110, 107, 247, 179, 148, 95, 247, 215, 144, 149, 240, + 171, 208, 247, 191, 35, 123, 68, 43, 66, 16, 60, 153, 33, 226, 199, 252, 83, 47, 188, 103, 255, 3, 195, + 143, 96, 248, 57, 148, 173, 46, 94, 7, 93, 159, 143, 195, 159, 153, 198, 67, 237, 204, 43, 62, 153, 236, + 51, 239, 131, 43, 149, 5, 253, 53, 198, 235, 93, 164, 6, 113, 157, 135, 132, 196, 112, 166, 106, 39, 10, + 114, 175, 57, 181, 188, 70, 68, 200, 172, 41, 126, 58, 12, 227, 232, 19, 186, 159, 151, 57, 71, 109, 220, + 236, 147, 120, 50, 146, 165, 249, 45, 63, 115, 6, 150, 114, 97, 71, 34, 121, 118, 85, 179, 129, 112, 97, + 59, 82, 15, 15, 2, 171, 231, 227, 248, 247, 196, 131, 156, 23, 32, 204, 65, 159, 92, 38, 23, 250, 185, 147, + 10, 255, 63, 141, 35, 196, 7, 236, 110, 9, 219, 237, 48, 218, 101, 101, 141, 189, 180, 147, 100, 126, 111, + 146, 113, 229, 182, 173, 175, 33, 0, 33, 199, 178, 80, 94, 72, 41, 62, 190, 111, 181, 235, 200, 145, 46, + 174, 196, 188, 8, 145, 212, 182, 61, 72, 121, 187, 25, 55, 180, 83, 180, 45, 77, 2, 189, 10, 225, 63, 222, + 255, 244, 56, 121, 163, 99, 182, 206, 17, 153, 223, 167, 113, 19, 132, 124, 220, 35, 8, 222, 53, 34, 249, + 50, 208, 145, 11, 135, 108, 181, 109, 35, 151, 253, 85, 137, 209, 202, 14, 187, 236, 253, 101, 252, 206, + 164, 206, 86, 134, 206, 200, 98, 23, 77, 144, 20, 131, 164, 205, 152, 5, 247, 106, 65, 204, 99, 55, 6, 190, + 90, 31, 10, 228, 93, 62, 11, 52, 189, 103, 98, 246, 10, 196, 21, 253, 241, 245, 115, 9, 50, 87, 82, 115, + 21, 75, 103, 3, 237, 54, 222, 8, 230, 231, 13, 39, 115, 56, 113, 31, 27, 122, 241, 84, 84, 91, 148, 82, + 155, 91, 119, 196, 0, 205, 41, 73, 139, 151, 57, 248, 53, 120, 165, 142, 220, 87, 106, 253, 218, 13, 35, + 148, 33, 110, 78, 43, 122, 80, 146, 196, 218, 148, 19, 226, 9, 193, 75, 16, 103, 226, 178, 193, 222, 84, + 69, 140, 44, 7, 194, 1, 193, 249, 199, 235, 63, 179, 165, 123, 233, 94, 82, 127, 168, 68, 221, 165, 61, + 180, 4, 82, 165, 117, 94, 122, 195, 174, 99, 175, 146, 167, 179, 204, 7, 165, 38, 68, 14, 188, 4, 137, 39, + 105, 55, 52, 248, 83, 21, 203, 74, 189, 28, 223, 148, 143, 237, 38, 72, 165, 230, 85, 169, 27, 71, 224, + 187, 28, 91, 17, 251, 130, 225, 99, 114, 8, 195, 205, 166, 129, 138, 60, 250, 146, 139, 161, 30, 215, 191, + 126, 30, 254, 137, 52, 125, 218, 133, 24, 158, 237, 104, 162, 176, 206, 59, 175, 252, 242, 108, 112, 65, + 90, 240, 180, 37, 146, 88, 212, 90, 22, 59, 116, 174, 81, 63, 132, 19, 177, 247, 247, 29, 14, 158, 243, + 121, 153, 239, 107, 49, 43, 198, 179, 117, 54, 194, 29, 91, 171, 169, 204, 214, 232, 134, 12, 225, 68, 245, + 153, 99, 52, 191, 198, 156, 218, 243, 208, 221, 42, 100, 132, 149, 66, 35, 33, 125, 222, 255, 101, 62, 199, + 115, 97, 109, 104, 161, 185, 255, 234, 71, 51, 99, 94, 231, 30, 230, 151, 56, 117, 57, 243, 188, 181, 149, + 27, 226, 184, 136, 223, 130, 207, 85, 233, 121, 135, 135, 66, 59, 102, 11, 34, 89, 144, 105, 61, 214, 68, + 167, 11, 61, 202, 226, 28, 130, 193, 52, 145, 237, 138, 38, 161, 142, 146, 222, 215, 124, 190, 67, 253, + 147, 210, 51, 187, 196, 247, 154, 103, 93, 216, 126, 252, 254, 155, 87, 103, 106, 6, 104, 83, 73, 88, 85, + 14, 147, 145, 34, 49, 65, 53, 70, 30, 127, 114, 52, 6, 215, 18, 123, 252, 225, 220, 235, 65, 228, 151, 233, + 108, 106, 159, 119, 184, 84, 240, 206, 225, 150, 221, 116, 54, 60, 29, 239, 47, 78, 193, 160, 32, 141, 92, + 251, 164, 245, 243, 171, 82, 165, 116, 199, 251, 14, 152, 97, 124, 12, 198, 105, 168, 204, 205, 62, 137, + 84, 46, 154, 87, 111, 62, 62, 255, 120, 140, 149, 207, 175, 188, 89, 188, 230, 200, 123, 231, 183, 183, 0, + 109, 44, 7, 74, 178, 123, 103, 103, 125, 201, 118, 126, 41, 234, 93, 15, 23, 209, 230, 115, 33, 63, 119, + 248, 232, 247, 88, 155, 137, 129, 230, 232, 152, 30, 71, 151, 70, 176, 165, 108, 33, 55, 142, 134, 85, 156, + 214, 124, 67, 110, 225, 22, 102, 239, 179, 133, 58, 46, 64, 109, 113, 37, 174, 193, 232, 135, 148, 177, + 127, 220, 255, 211, 82, 6, 23, 117, 63, 7, 46, 150, 143, 58, 175, 232, 97, 66, 235, 188, 214, 186, 204, + 204, 15, 69, 35, 71, 28, 131, 103, 39, 121, 88, 171, 68, 229, 255, 117, 135, 83, 87, 186, 228, 153, 199, + 138, 68, 41, 140, 152, 50, 49, 215, 209, 181, 25, 137, 86, 181, 136, 97, 103, 87, 172, 224, 80, 142, 179, + 178, 113, 141, 189, 231, 171, 207, 200, 146, 207, 11, 3, 205, 22, 115, 148, 31, 63, 127, 194, 182, 149, 64, + 229, 103, 34, 41, 170, 237, 170, 231, 169, 115, 92, 214, 84, 242, 226, 244, 123, 222, 1, 234, 171, 102, 51, + 103, 247, 137, 111, 2, 209, 254, 207, 29, 94, 16, 119, 58, 94, 235, 188, 34, 0, 149, 221, 123, 185, 24, + 170, 100, 35, 179, 21, 24, 33, 207, 134, 116, 224, 125, 169, 44, 110, 198, 121, 87, 70, 75, 118, 8, 143, + 194, 132, 88, 148, 18, 52, 150, 131, 124, 60, 251, 141, 66, 43, 4, 160, 232, 174, 194, 56, 136, 105, 61, + 143, 45, 59, 180, 8, 179, 88, 9, 53, 28, 108, 61, 47, 120, 108, 234, 243, 142, 119, 149, 150, 229, 247, 29, + 110, 179, 93, 236, 32, 10, 25, 224, 43, 83, 219, 211, 188, 44, 123, 213, 158, 0, 175, 47, 208, 148, 226, + 86, 0, 161, 251, 187, 43, 60, 60, 13, 216, 204, 8, 164, 174, 192, 111, 32, 30, 159, 226, 222, 231, 232, + 212, 135, 101, 78, 112, 249, 94, 79, 255, 254, 22, 188, 217, 249, 142, 79, 118, 11, 113, 82, 182, 32, 163, + 19, 119, 72, 1, 70, 51, 251, 221, 129, 223, 61, 111, 253, 143, 59, 252, 96, 126, 107, 146, 82, 207, 3, 119, + 67, 223, 207, 237, 178, 148, 117, 194, 166, 227, 25, 107, 161, 106, 69, 152, 19, 124, 251, 137, 113, 207, + 169, 142, 212, 20, 4, 130, 75, 86, 44, 207, 11, 224, 207, 42, 63, 222, 255, 254, 120, 107, 225, 220, 125, + 81, 144, 120, 193, 85, 185, 233, 19, 6, 156, 47, 77, 219, 252, 222, 3, 196, 194, 225, 129, 61, 157, 11, + 164, 213, 176, 112, 253, 190, 202, 230, 61, 231, 138, 144, 8, 30, 206, 94, 120, 250, 66, 22, 203, 143, 247, + 23, 222, 218, 75, 120, 171, 167, 211, 64, 240, 91, 144, 242, 206, 73, 153, 190, 212, 89, 66, 93, 22, 84, + 170, 166, 226, 158, 144, 7, 153, 143, 231, 255, 250, 209, 75, 113, 5, 201, 46, 2, 225, 189, 128, 80, 214, + 219, 119, 27, 255, 188, 195, 211, 65, 71, 92, 244, 154, 87, 194, 207, 139, 129, 216, 226, 57, 249, 227, 14, + 207, 50, 83, 30, 179, 151, 229, 65, 92, 232, 147, 89, 92, 156, 223, 121, 61, 199, 168, 240, 71, 106, 247, + 190, 204, 233, 199, 245, 213, 162, 194, 77, 238, 64, 26, 226, 140, 116, 212, 130, 182, 132, 118, 3, 68, + 127, 190, 252, 131, 14, 122, 206, 43, 178, 217, 204, 66, 14, 196, 186, 92, 183, 159, 172, 252, 188, 195, + 213, 172, 133, 247, 217, 235, 54, 203, 219, 107, 153, 54, 76, 254, 184, 202, 166, 218, 82, 223, 95, 114, + 253, 110, 157, 108, 124, 85, 65, 207, 175, 16, 60, 17, 10, 162, 185, 203, 124, 166, 178, 33, 130, 184, 59, + 186, 18, 193, 56, 153, 95, 49, 220, 103, 233, 115, 222, 141, 249, 198, 67, 159, 135, 255, 191, 228, 32, 11, + 62, 234, 86, 66, 137, 126, 230, 44, 182, 185, 174, 25, 160, 203, 152, 95, 255, 38, 102, 153, 228, 213, 106, + 112, 241, 47, 87, 217, 212, 141, 202, 119, 97, 0, 249, 79, 32, 188, 154, 176, 72, 12, 18, 51, 201, 219, + 251, 254, 190, 1, 73, 96, 152, 200, 242, 117, 216, 249, 21, 187, 245, 184, 49, 234, 205, 164, 201, 251, + 183, 8, 200, 207, 247, 255, 127, 229, 43, 95, 249, 202, 87, 190, 242, 149, 175, 124, 229, 43, 95, 249, 202, + 87, 190, 242, 149, 175, 124, 229, 43, 95, 249, 202, 87, 190, 242, 149, 175, 124, 229, 43, 95, 249, 202, 87, + 190, 242, 149, 175, 124, 229, 43, 95, 249, 202, 87, 190, 242, 149, 175, 124, 229, 43, 95, 249, 202, 87, + 190, 242, 149, 175, 124, 229, 43, 95, 249, 202, 87, 190, 242, 149, 175, 124, 229, 43, 95, 249, 202, 87, + 190, 242, 149, 175, 124, 229, 43, 95, 249, 202, 87, 190, 242, 149, 175, 124, 229, 43, 95, 249, 202, 87, + 190, 242, 149, 175, 124, 229, 43, 95, 249, 202, 87, 190, 242, 149, 175, 124, 229, 43, 95, 249, 202, 87, + 190, 242, 149, 175, 124, 229, 43, 95, 249, 202, 87, 190, 242, 149, 175, 124, 229, 43, 95, 249, 202, 87, + 190, 242, 149, 175, 124, 229, 43, 95, 249, 202, 87, 190, 242, 149, 175, 124, 229, 43, 95, 249, 202, 87, + 190, 242, 21, 128, 255, 7, 221, 154, 25, 153, 119, 41, 166, 247, 0, 0, 1, 169, 109, 107, 66, 84, 250, 206, + 202, 254, 0, 127, 216, 221, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 120, 156, 237, 209, 193, 9, 3, 49, 16, 4, 65, 41, 255, 76, 46, 73, 25, 71, 96, 238, 97, + 22, 209, 53, 208, 9, 76, 173, 245, 98, 123, 239, 43, 250, 238, 121, 158, 117, 206, 209, 143, 248, 183, 227, + 223, 142, 127, 59, 254, 237, 248, 183, 227, 223, 142, 127, 59, 254, 237, 248, 183, 227, 223, 142, 127, 59, + 254, 237, 248, 183, 227, 223, 142, 127, 59, 254, 237, 248, 183, 227, 223, 142, 127, 59, 254, 237, 166, 173, + 248, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, + 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, + 252, 249, 243, 231, 207, 159, 63, 255, 233, 111, 111, 104, 218, 138, 63, 127, 254, 252, 249, 243, 231, 207, + 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, + 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 159, + 254, 246, 134, 166, 173, 248, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, + 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, + 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 255, 233, 111, 111, 104, 218, 138, 63, 127, 254, + 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, + 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 63, 127, + 254, 252, 249, 243, 159, 254, 246, 134, 166, 173, 248, 243, 231, 207, 159, 63, 127, 254, 252, 249, 243, + 231, 207, 159, 63, 127, 254, 252, 249, 243, 231, 207, 159, 255, 95, 250, 0, 3, 252, 100, 190, 230, 58, 5, + 209, 0, 0, 1, 92, 109, 107, 66, 84, 250, 206, 202, 254, 0, 127, 225, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 209, 193, 9, 3, 32, 16, 68, + 81, 45, 193, 2, 236, 31, 189, 218, 155, 39, 193, 144, 10, 114, 9, 44, 43, 111, 224, 53, 48, 191, 212, 90, + 203, 107, 190, 155, 115, 150, 123, 47, 63, 68, 183, 210, 95, 127, 253, 245, 215, 95, 127, 253, 245, 215, + 95, 127, 253, 245, 215, 95, 127, 253, 245, 215, 95, 127, 253, 245, 215, 95, 127, 253, 245, 215, 95, 127, + 253, 245, 215, 95, 127, 253, 245, 215, 95, 127, 253, 245, 215, 95, 127, 253, 245, 215, 95, 127, 253, 245, + 215, 95, 255, 232, 111, 51, 136, 110, 165, 191, 254, 250, 235, 175, 191, 254, 250, 235, 175, 191, 254, 250, + 235, 175, 191, 254, 250, 235, 175, 191, 254, 250, 235, 175, 191, 254, 250, 235, 175, 191, 254, 250, 235, + 175, 191, 254, 250, 235, 175, 191, 254, 250, 235, 175, 191, 254, 250, 235, 175, 191, 254, 250, 235, 175, + 191, 254, 209, 223, 102, 16, 221, 74, 127, 253, 245, 215, 95, 127, 253, 245, 215, 95, 127, 253, 245, 215, + 95, 127, 253, 245, 215, 95, 127, 253, 245, 215, 95, 127, 253, 245, 215, 95, 127, 253, 245, 215, 95, 255, + 255, 120, 117, 99, 140, 240, 111, 51, 232, 189, 63, 167, 181, 86, 214, 90, 225, 223, 102, 176, 247, 126, + 210, 57, 39, 252, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 210, 249, 0, 160, 81, 161, 21, 73, 101, 14, 2, 0, 0, 2, 46, 109, 107, 66, 84, 250, 206, 202, 254, 0, + 127, 241, 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, 120, 156, 237, 219, 203, 106, 83, 97, 20, 134, 225, 189, 227, 217, 120, 214, 104, 36, 70, 241, 128, 34, + 34, 34, 34, 34, 34, 34, 40, 130, 136, 136, 56, 16, 17, 71, 34, 142, 236, 253, 117, 88, 232, 101, 116, 90, + 232, 5, 180, 211, 250, 149, 82, 236, 121, 32, 13, 105, 179, 158, 5, 207, 252, 223, 188, 100, 255, 139, 144, + 76, 53, 77, 51, 21, 191, 219, 182, 253, 17, 95, 226, 125, 188, 138, 167, 241, 32, 110, 197, 32, 46, 197, + 153, 56, 25, 71, 227, 112, 116, 218, 141, 211, 112, 160, 252, 137, 95, 241, 61, 62, 199, 187, 120, 25, 79, + 226, 126, 220, 140, 171, 113, 49, 78, 199, 137, 118, 181, 253, 161, 118, 99, 251, 113, 63, 7, 255, 231, + 103, 124, 139, 79, 241, 54, 94, 196, 227, 184, 23, 55, 162, 31, 23, 90, 237, 39, 213, 215, 248, 24, 111, + 226, 121, 60, 138, 187, 113, 61, 174, 196, 185, 56, 21, 199, 227, 72, 171, 253, 164, 249, 16, 175, 227, 89, + 60, 140, 59, 113, 45, 122, 237, 106, 251, 110, 28, 107, 181, 159, 84, 235, 247, 188, 219, 237, 191, 61, + 239, 108, 107, 207, 171, 96, 183, 61, 111, 229, 115, 191, 185, 253, 184, 207, 203, 222, 90, 191, 231, 157, + 111, 237, 121, 213, 12, 227, 114, 187, 218, 222, 158, 87, 207, 202, 158, 183, 114, 215, 219, 243, 106, 90, + 251, 62, 111, 187, 187, 190, 221, 7, 231, 99, 180, 220, 245, 181, 109, 251, 190, 95, 155, 125, 112, 62, 70, + 107, 199, 246, 250, 151, 176, 126, 154, 205, 179, 15, 206, 199, 232, 251, 111, 233, 174, 127, 29, 187, 205, + 184, 207, 134, 254, 232, 143, 254, 232, 143, 254, 236, 173, 110, 183, 187, 163, 78, 167, 51, 246, 243, 49, + 90, 243, 243, 243, 91, 44, 44, 44, 52, 115, 115, 115, 77, 191, 223, 247, 30, 152, 112, 203, 203, 203, 219, + 90, 92, 92, 108, 6, 131, 129, 254, 19, 78, 255, 218, 244, 175, 77, 255, 218, 244, 175, 77, 255, 218, 244, + 175, 77, 255, 218, 244, 175, 77, 255, 218, 244, 175, 77, 255, 218, 244, 175, 77, 255, 218, 244, 175, 77, + 255, 218, 244, 175, 77, 255, 218, 244, 175, 77, 255, 218, 244, 175, 109, 102, 102, 102, 139, 217, 217, 217, + 102, 122, 122, 186, 233, 245, 122, 250, 79, 56, 255, 255, 168, 77, 127, 0, 0, 0, 0, 0, 0, 0, 128, 131, 205, + 212, 158, 225, 112, 72, 97, 75, 75, 75, 20, 182, 211, 239, 191, 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, 138, 250, 11, 7, 171, 18, 5, 96, 120, 103, 83, 0, 0, 14, + 19, 109, 107, 66, 84, 250, 206, 202, 254, 0, 127, 242, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 156, 237, 157, 11, 112, 84, 213, 25, 199, 47, 143, 0, + 130, 209, 65, 112, 208, 145, 1, 7, 68, 7, 71, 112, 124, 205, 96, 105, 121, 20, 176, 128, 130, 173, 84, 17, + 171, 2, 210, 74, 11, 213, 148, 71, 200, 147, 4, 18, 242, 14, 137, 50, 17, 180, 16, 53, 173, 177, 82, 196, + 33, 34, 15, 153, 10, 98, 1, 33, 16, 10, 8, 5, 202, 51, 32, 132, 151, 1, 18, 242, 216, 36, 155, 175, 231, + 59, 123, 207, 230, 228, 186, 145, 36, 123, 239, 158, 187, 187, 223, 55, 243, 27, 29, 49, 236, 61, 231, 255, + 61, 207, 189, 123, 3, 111, 106, 26, 16, 193, 75, 24, 65, 16, 4, 65, 16, 4, 65, 16, 4, 65, 16, 1, 207, 95, + 136, 160, 102, 22, 65, 16, 4, 65, 16, 4, 65, 16, 4, 65, 16, 4, 65, 16, 1, 203, 28, 130, 32, 8, 130, 32, + 130, 142, 112, 130, 32, 8, 130, 32, 8, 34, 168, 152, 71, 16, 4, 65, 16, 68, 208, 17, 65, 16, 4, 65, 16, 4, + 65, 4, 21, 145, 4, 65, 16, 4, 65, 16, 68, 80, 17, 69, 4, 53, 49, 4, 65, 16, 132, 45, 192, 51, 25, 188, 47, + 135, 207, 102, 71, 218, 224, 122, 8, 235, 137, 214, 153, 205, 200, 30, 48, 0, 142, 174, 91, 7, 5, 51, 102, + 64, 66, 215, 174, 252, 59, 122, 115, 53, 87, 173, 142, 182, 193, 181, 18, 230, 235, 142, 160, 206, 111, 63, + 250, 40, 92, 59, 115, 6, 132, 221, 184, 120, 17, 182, 47, 89, 2, 111, 63, 252, 48, 247, 1, 252, 127, 34, + 165, 159, 81, 125, 253, 132, 247, 218, 99, 92, 227, 123, 24, 223, 98, 218, 151, 157, 63, 15, 158, 204, 89, + 91, 11, 199, 191, 250, 10, 62, 158, 56, 17, 98, 187, 116, 225, 239, 237, 11, 39, 31, 240, 91, 132, 238, 24, + 203, 248, 59, 56, 114, 6, 15, 134, 114, 22, 235, 205, 177, 171, 197, 197, 176, 57, 41, 9, 50, 251, 245, + 227, 245, 98, 182, 214, 144, 19, 84, 175, 139, 104, 153, 246, 111, 160, 246, 67, 134, 64, 101, 105, 105, + 179, 180, 151, 173, 182, 170, 10, 14, 21, 20, 192, 7, 207, 60, 3, 81, 29, 58, 52, 202, 9, 228, 11, 246, + 196, 24, 247, 89, 143, 61, 6, 55, 46, 93, 106, 177, 246, 70, 187, 116, 228, 8, 108, 136, 136, 128, 228, + 158, 61, 221, 239, 116, 104, 238, 217, 78, 44, 225, 19, 100, 253, 177, 222, 103, 97, 189, 47, 41, 241, 90, + 123, 217, 170, 203, 203, 225, 63, 249, 249, 240, 215, 161, 67, 33, 178, 93, 59, 119, 191, 72, 58, 219, 75, + 251, 180, 7, 31, 132, 235, 231, 206, 153, 170, 189, 209, 206, 21, 21, 193, 26, 54, 67, 38, 118, 239, 238, + 158, 33, 69, 93, 48, 94, 155, 234, 253, 9, 100, 100, 237, 177, 70, 47, 234, 211, 7, 174, 156, 56, 97, 169, + 246, 178, 85, 92, 185, 2, 59, 151, 46, 133, 156, 199, 31, 135, 121, 109, 218, 184, 251, 69, 170, 3, 190, + 209, 62, 70, 215, 30, 99, 48, 254, 174, 187, 160, 228, 192, 1, 159, 105, 47, 91, 189, 211, 9, 39, 191, 249, + 6, 86, 190, 242, 10, 196, 223, 118, 27, 191, 158, 121, 90, 227, 62, 65, 245, 126, 5, 18, 114, 220, 243, + 126, 44, 52, 20, 78, 109, 219, 166, 68, 123, 163, 97, 237, 217, 154, 158, 14, 89, 253, 251, 243, 107, 196, + 235, 157, 207, 136, 35, 76, 97, 190, 14, 250, 0, 158, 231, 135, 135, 132, 240, 89, 205, 110, 86, 87, 83, + 195, 243, 128, 172, 127, 60, 225, 21, 178, 15, 136, 216, 223, 181, 124, 185, 106, 169, 155, 180, 204, 135, + 30, 226, 61, 1, 249, 128, 121, 218, 227, 94, 98, 94, 197, 126, 111, 83, 124, 188, 106, 137, 127, 210, 46, + 28, 60, 8, 11, 88, 95, 18, 78, 62, 96, 138, 254, 34, 239, 163, 246, 43, 167, 78, 85, 45, 111, 179, 236, + 127, 155, 54, 65, 100, 135, 14, 124, 46, 152, 47, 173, 103, 1, 209, 44, 100, 253, 49, 134, 176, 166, 190, + 55, 98, 4, 63, 163, 245, 23, 219, 249, 238, 187, 188, 14, 68, 107, 141, 115, 128, 234, 189, 245, 7, 228, + 216, 199, 115, 150, 180, 7, 30, 128, 50, 139, 207, 119, 172, 176, 181, 179, 102, 241, 188, 21, 163, 81, 30, + 104, 141, 246, 216, 235, 199, 178, 217, 250, 108, 97, 161, 106, 41, 91, 101, 245, 117, 117, 144, 59, 118, + 172, 123, 38, 160, 28, 112, 115, 237, 227, 181, 198, 189, 254, 222, 252, 124, 213, 50, 122, 101, 229, 23, + 46, 64, 106, 191, 126, 60, 143, 201, 62, 64, 126, 240, 99, 237, 141, 253, 222, 250, 232, 104, 213, 242, + 153, 98, 167, 183, 111, 135, 232, 206, 157, 185, 79, 199, 73, 107, 94, 72, 184, 17, 62, 128, 250, 99, 223, + 244, 254, 184, 113, 80, 95, 95, 175, 90, 58, 211, 12, 251, 193, 57, 186, 111, 139, 216, 23, 107, 79, 8, 82, + 140, 250, 99, 108, 224, 25, 122, 234, 125, 247, 53, 249, 236, 150, 63, 219, 170, 105, 211, 120, 47, 32, + 122, 193, 96, 246, 1, 79, 218, 243, 243, 125, 54, 55, 159, 248, 250, 107, 213, 82, 89, 98, 213, 215, 175, + 67, 246, 35, 143, 240, 94, 64, 248, 128, 188, 15, 170, 53, 81, 169, 189, 152, 243, 183, 102, 102, 170, 150, + 201, 82, 251, 126, 207, 30, 136, 13, 13, 229, 103, 67, 162, 23, 8, 54, 31, 240, 84, 243, 81, 251, 191, 77, + 152, 160, 90, 30, 159, 216, 183, 203, 150, 185, 239, 17, 136, 28, 32, 239, 79, 98, 0, 35, 251, 128, 92, + 243, 83, 250, 244, 49, 253, 249, 45, 59, 219, 199, 147, 38, 113, 31, 144, 115, 64, 160, 235, 111, 204, 1, + 232, 251, 216, 15, 71, 180, 109, 11, 71, 55, 110, 84, 45, 137, 215, 118, 81, 250, 174, 201, 205, 140, 159, + 11, 244, 237, 203, 207, 184, 130, 197, 7, 140, 177, 47, 242, 254, 250, 168, 40, 11, 85, 177, 222, 156, 117, + 117, 240, 89, 78, 14, 140, 237, 214, 173, 69, 63, 119, 100, 221, 58, 158, 251, 196, 76, 24, 200, 117, 192, + 83, 222, 199, 62, 56, 103, 208, 32, 168, 173, 174, 182, 72, 25, 235, 237, 240, 174, 93, 48, 131, 173, 225, + 9, 182, 150, 159, 51, 90, 106, 159, 207, 158, 237, 158, 9, 3, 53, 7, 120, 202, 251, 252, 217, 217, 91, 111, + 133, 239, 139, 138, 44, 80, 197, 122, 43, 43, 45, 133, 119, 194, 194, 96, 120, 72, 8, 252, 140, 173, 101, + 36, 99, 84, 43, 244, 175, 46, 43, 131, 197, 3, 7, 242, 231, 5, 2, 181, 14, 24, 181, 23, 121, 127, 75, 122, + 186, 5, 202, 88, 111, 91, 86, 174, 132, 23, 123, 247, 134, 65, 186, 238, 163, 25, 99, 24, 99, 91, 161, 63, + 218, 201, 173, 91, 33, 178, 125, 123, 30, 19, 194, 7, 2, 165, 14, 52, 149, 247, 151, 13, 27, 198, 159, 161, + 245, 39, 59, 123, 244, 40, 196, 140, 27, 7, 131, 217, 245, 15, 211, 53, 127, 154, 49, 158, 241, 44, 227, + 55, 173, 212, 31, 237, 139, 240, 240, 70, 103, 131, 129, 144, 3, 100, 31, 22, 179, 62, 127, 62, 154, 229, + 253, 243, 251, 246, 153, 168, 140, 181, 230, 168, 170, 130, 252, 228, 100, 24, 19, 26, 202, 115, 253, 175, + 116, 221, 81, 243, 231, 24, 191, 101, 188, 192, 120, 209, 11, 253, 121, 29, 24, 48, 32, 160, 234, 128, 49, + 239, 139, 51, 190, 45, 105, 105, 38, 170, 99, 173, 237, 221, 188, 25, 166, 177, 250, 140, 185, 126, 132, + 214, 16, 239, 24, 235, 207, 235, 154, 255, 142, 241, 10, 99, 178, 23, 250, 163, 29, 253, 242, 75, 62, 15, + 24, 207, 133, 196, 126, 46, 242, 19, 140, 62, 32, 244, 231, 253, 254, 224, 193, 252, 251, 247, 118, 183, + 82, 54, 159, 103, 188, 246, 26, 12, 109, 211, 6, 134, 104, 174, 92, 63, 142, 241, 107, 205, 21, 239, 47, + 234, 154, 79, 97, 76, 99, 252, 129, 241, 186, 151, 250, 163, 125, 54, 125, 58, 223, 39, 209, 3, 224, 126, + 38, 233, 36, 251, 9, 73, 18, 139, 116, 253, 249, 125, 253, 14, 29, 224, 244, 142, 29, 38, 168, 99, 157, 97, + 79, 178, 33, 55, 23, 38, 244, 232, 193, 115, 253, 232, 38, 116, 159, 170, 107, 254, 39, 198, 159, 53, 215, + 247, 143, 195, 76, 208, 191, 188, 164, 4, 82, 122, 245, 226, 189, 224, 66, 173, 33, 238, 253, 201, 7, 100, + 237, 69, 237, 71, 159, 94, 55, 119, 174, 9, 10, 89, 103, 199, 89, 79, 50, 135, 245, 165, 216, 223, 97, 174, + 127, 70, 115, 213, 248, 9, 140, 137, 154, 43, 207, 99, 142, 255, 61, 227, 143, 186, 238, 248, 156, 138, + 252, 123, 127, 205, 176, 162, 188, 60, 254, 119, 197, 107, 254, 151, 3, 100, 237, 19, 117, 31, 198, 158, + 47, 227, 254, 251, 91, 245, 94, 6, 95, 88, 101, 121, 57, 172, 136, 140, 132, 167, 58, 117, 130, 95, 104, + 174, 57, 14, 99, 94, 212, 248, 151, 52, 87, 204, 191, 166, 185, 114, 252, 76, 205, 21, 235, 168, 59, 214, + 107, 249, 125, 33, 102, 89, 238, 232, 209, 220, 7, 22, 104, 254, 149, 3, 140, 177, 31, 167, 199, 197, 129, + 85, 171, 76, 219, 27, 51, 109, 199, 231, 159, 195, 171, 253, 250, 241, 92, 255, 148, 230, 138, 121, 204, + 245, 24, 243, 152, 235, 95, 214, 92, 53, 94, 228, 122, 124, 199, 200, 108, 125, 77, 226, 123, 191, 242, + 179, 189, 102, 25, 158, 139, 197, 116, 236, 200, 123, 65, 127, 169, 3, 158, 242, 62, 238, 83, 222, 248, + 241, 166, 237, 139, 89, 118, 225, 212, 41, 72, 120, 254, 121, 222, 219, 13, 215, 26, 250, 122, 156, 231, + 112, 150, 195, 152, 199, 92, 143, 189, 157, 156, 235, 177, 142, 225, 61, 27, 241, 92, 191, 241, 57, 30, + 192, 103, 214, 188, 69, 183, 47, 230, 204, 225, 57, 198, 31, 234, 128, 167, 188, 207, 191, 187, 123, 203, + 45, 112, 126, 255, 126, 215, 130, 204, 216, 27, 47, 247, 180, 142, 205, 30, 171, 179, 179, 97, 124, 215, + 174, 188, 206, 203, 253, 29, 230, 250, 73, 90, 67, 127, 135, 185, 126, 134, 230, 202, 245, 24, 243, 226, + 251, 221, 226, 57, 94, 121, 70, 23, 243, 14, 62, 179, 104, 6, 104, 248, 46, 27, 236, 5, 163, 52, 251, 215, + 1, 99, 236, 163, 207, 162, 239, 174, 11, 15, 119, 73, 207, 229, 55, 103, 111, 90, 179, 151, 104, 7, 183, + 111, 135, 153, 79, 60, 225, 62, 175, 247, 212, 223, 97, 174, 23, 253, 29, 230, 122, 60, 175, 240, 148, 235, + 141, 186, 163, 62, 209, 38, 234, 47, 174, 91, 60, 55, 26, 167, 53, 212, 1, 121, 190, 82, 173, 187, 167, + 216, 95, 160, 199, 73, 74, 239, 222, 112, 227, 242, 101, 61, 244, 213, 233, 126, 237, 202, 21, 88, 50, 99, + 6, 252, 178, 93, 59, 158, 239, 177, 191, 19, 185, 94, 244, 119, 175, 106, 174, 254, 110, 186, 246, 227, + 254, 206, 83, 174, 23, 231, 26, 248, 223, 49, 31, 100, 223, 115, 15, 108, 98, 243, 13, 206, 143, 102, 193, + 243, 85, 77, 13, 191, 71, 26, 161, 217, 55, 7, 52, 21, 251, 223, 50, 223, 229, 218, 155, 184, 39, 205, 66, + 210, 254, 95, 249, 249, 48, 177, 103, 79, 247, 185, 173, 232, 235, 141, 179, 188, 200, 245, 56, 199, 223, + 44, 215, 227, 191, 99, 46, 88, 200, 252, 41, 143, 205, 139, 7, 62, 250, 8, 170, 174, 95, 231, 159, 231, + 100, 159, 111, 38, 104, 71, 214, 175, 231, 250, 199, 107, 13, 241, 159, 34, 145, 170, 16, 113, 13, 201, + 146, 254, 152, 43, 115, 88, 158, 69, 223, 181, 98, 79, 126, 10, 161, 253, 169, 67, 135, 32, 138, 205, 80, + 56, 207, 25, 103, 121, 209, 215, 203, 103, 56, 66, 247, 112, 15, 186, 139, 115, 108, 241, 156, 106, 86, + 143, 30, 176, 241, 141, 55, 224, 252, 222, 189, 141, 122, 74, 43, 215, 147, 247, 236, 179, 220, 39, 69, 31, + 152, 108, 51, 253, 147, 116, 223, 140, 215, 99, 231, 191, 107, 215, 250, 92, 123, 180, 26, 135, 3, 114, + 163, 163, 97, 72, 251, 246, 240, 8, 187, 142, 33, 186, 254, 163, 117, 31, 120, 78, 215, 31, 243, 253, 52, + 131, 246, 198, 92, 47, 238, 89, 242, 88, 111, 219, 22, 222, 127, 242, 73, 216, 155, 155, 11, 21, 63, 252, + 224, 214, 28, 245, 241, 197, 186, 206, 238, 222, 13, 49, 33, 33, 220, 7, 69, 14, 80, 237, 3, 158, 98, 31, + 247, 240, 131, 167, 159, 118, 247, 124, 62, 141, 125, 246, 121, 213, 149, 149, 176, 117, 213, 42, 88, 187, + 116, 41, 124, 150, 149, 5, 249, 113, 113, 176, 34, 44, 12, 114, 38, 79, 134, 12, 54, 135, 166, 12, 31, 14, + 137, 44, 55, 197, 247, 239, 15, 177, 172, 46, 68, 179, 57, 32, 170, 115, 103, 136, 102, 254, 34, 222, 37, + 41, 191, 19, 58, 253, 142, 59, 224, 139, 215, 95, 135, 179, 59, 119, 54, 186, 95, 221, 212, 53, 212, 213, + 213, 153, 143, 254, 185, 248, 253, 145, 185, 186, 95, 170, 206, 1, 178, 246, 34, 246, 209, 55, 163, 88, + 156, 156, 98, 125, 54, 239, 93, 172, 216, 139, 155, 224, 116, 222, 252, 153, 2, 212, 17, 239, 233, 86, 178, + 154, 93, 206, 102, 172, 43, 39, 79, 242, 25, 21, 191, 167, 119, 108, 211, 38, 248, 142, 249, 79, 225, 178, + 101, 80, 196, 98, 253, 186, 244, 61, 36, 39, 139, 117, 21, 107, 66, 208, 46, 30, 57, 2, 113, 161, 161, 60, + 63, 169, 206, 1, 198, 216, 71, 159, 196, 218, 249, 241, 75, 47, 185, 180, 183, 42, 22, 76, 240, 15, 212, + 177, 94, 207, 79, 205, 49, 213, 215, 44, 251, 0, 190, 83, 32, 92, 207, 181, 162, 15, 76, 211, 73, 247, 17, + 226, 243, 82, 37, 253, 249, 115, 93, 157, 58, 193, 57, 253, 185, 14, 213, 123, 165, 138, 218, 218, 90, 203, + 64, 187, 124, 252, 56, 44, 188, 253, 118, 158, 107, 23, 25, 244, 247, 149, 15, 24, 245, 199, 92, 132, 117, + 255, 159, 83, 166, 240, 107, 172, 181, 120, 31, 130, 25, 52, 60, 83, 19, 179, 64, 146, 174, 131, 175, 244, + 151, 125, 45, 69, 142, 253, 142, 29, 221, 177, 175, 122, 143, 2, 25, 180, 210, 226, 98, 72, 236, 214, 141, + 247, 1, 34, 7, 248, 202, 7, 140, 177, 47, 122, 254, 85, 250, 187, 185, 130, 61, 246, 107, 106, 106, 44, 71, + 244, 1, 243, 244, 220, 155, 108, 208, 61, 195, 34, 100, 31, 72, 213, 115, 143, 177, 238, 251, 98, 253, 193, + 14, 246, 173, 151, 142, 29, 115, 247, 1, 114, 31, 104, 165, 15, 200, 250, 167, 232, 190, 135, 231, 146, + 162, 238, 215, 248, 200, 255, 9, 87, 14, 88, 51, 115, 102, 163, 28, 144, 106, 161, 254, 77, 197, 126, 108, + 251, 246, 112, 102, 247, 110, 138, 125, 129, 195, 225, 19, 48, 7, 148, 28, 58, 4, 113, 157, 59, 115, 29, + 172, 206, 1, 178, 254, 162, 231, 199, 216, 255, 232, 133, 23, 26, 180, 247, 209, 218, 237, 140, 195, 87, + 232, 57, 224, 147, 151, 95, 182, 188, 15, 240, 20, 251, 226, 30, 239, 177, 205, 155, 249, 117, 248, 108, + 221, 132, 27, 204, 1, 167, 118, 236, 128, 152, 182, 109, 185, 30, 98, 22, 148, 181, 207, 52, 1, 241, 119, + 201, 51, 31, 106, 191, 124, 228, 72, 112, 234, 177, 175, 122, 47, 108, 67, 117, 181, 207, 192, 124, 131, + 251, 255, 254, 152, 49, 92, 15, 49, 11, 154, 169, 127, 134, 65, 127, 49, 243, 97, 238, 223, 255, 233, 167, + 174, 216, 247, 225, 154, 237, 78, 181, 143, 65, 251, 110, 205, 26, 126, 207, 42, 193, 80, 3, 204, 240, 1, + 185, 6, 136, 216, 199, 251, 161, 111, 13, 28, 8, 85, 21, 21, 224, 96, 61, 191, 175, 215, 76, 52, 128, 125, + 0, 254, 19, 127, 215, 109, 140, 174, 143, 153, 53, 192, 83, 236, 227, 253, 135, 127, 47, 89, 194, 125, 79, + 245, 250, 109, 71, 85, 149, 207, 65, 219, 198, 244, 16, 247, 133, 68, 14, 200, 240, 210, 7, 228, 216, 23, + 125, 31, 158, 57, 38, 223, 125, 55, 92, 43, 41, 225, 103, 125, 42, 214, 107, 103, 170, 20, 80, 195, 116, + 40, 101, 122, 160, 46, 226, 60, 40, 205, 160, 251, 226, 86, 32, 126, 86, 206, 253, 56, 107, 20, 132, 133, + 113, 159, 83, 177, 86, 194, 51, 104, 5, 111, 190, 201, 251, 0, 49, 7, 100, 72, 90, 102, 181, 16, 217, 7, + 132, 254, 120, 143, 63, 46, 36, 4, 206, 20, 21, 65, 29, 233, 111, 43, 80, 143, 211, 133, 133, 16, 219, 174, + 29, 215, 73, 204, 1, 153, 173, 244, 1, 241, 51, 162, 246, 163, 79, 225, 243, 80, 56, 107, 112, 237, 89, + 173, 83, 189, 102, 59, 82, 89, 89, 169, 4, 252, 236, 26, 167, 19, 86, 140, 26, 197, 117, 242, 38, 7, 120, + 138, 125, 113, 222, 183, 247, 147, 79, 248, 204, 169, 106, 157, 68, 211, 160, 46, 133, 121, 121, 188, 6, + 36, 26, 244, 23, 218, 102, 55, 3, 217, 15, 80, 255, 100, 189, 239, 203, 236, 219, 23, 202, 174, 94, 133, + 106, 54, 115, 168, 94, 43, 241, 99, 80, 151, 107, 151, 46, 65, 90, 175, 94, 252, 158, 64, 138, 151, 250, + 103, 74, 185, 31, 99, 127, 125, 68, 4, 63, 115, 84, 189, 78, 91, 83, 81, 161, 20, 204, 1, 107, 164, 62, 48, + 77, 215, 177, 185, 250, 203, 177, 159, 161, 251, 80, 130, 222, 247, 21, 239, 217, 3, 53, 245, 245, 202, + 215, 104, 103, 42, 20, 131, 119, 133, 142, 111, 219, 198, 191, 167, 146, 208, 138, 28, 96, 140, 125, 204, + 253, 120, 174, 180, 124, 248, 112, 112, 176, 57, 19, 125, 92, 245, 26, 137, 166, 169, 196, 62, 148, 245, + 230, 75, 7, 13, 226, 186, 181, 36, 7, 24, 99, 63, 85, 234, 251, 118, 188, 247, 30, 239, 251, 85, 175, 207, + 246, 220, 184, 161, 28, 212, 105, 75, 102, 38, 175, 1, 139, 12, 250, 11, 173, 223, 242, 128, 248, 51, 57, + 247, 243, 251, 138, 119, 222, 9, 151, 139, 139, 161, 218, 225, 80, 190, 54, 187, 115, 195, 6, 84, 213, 214, + 194, 185, 195, 135, 33, 161, 75, 23, 94, 3, 132, 254, 178, 238, 111, 123, 64, 252, 89, 150, 164, 63, 206, + 146, 255, 152, 52, 137, 215, 21, 213, 235, 34, 154, 9, 203, 67, 14, 167, 19, 62, 24, 59, 150, 215, 0, 209, + 3, 100, 253, 132, 254, 114, 14, 88, 172, 251, 140, 184, 207, 191, 111, 245, 106, 210, 191, 185, 148, 151, + 219, 2, 124, 82, 252, 219, 21, 43, 220, 115, 64, 186, 174, 107, 83, 57, 192, 24, 251, 88, 251, 113, 134, + 204, 184, 247, 94, 184, 202, 102, 74, 236, 43, 84, 175, 201, 31, 40, 183, 9, 149, 172, 7, 196, 119, 28, 45, + 234, 222, 157, 159, 7, 167, 74, 61, 64, 83, 250, 139, 216, 23, 103, 62, 24, 251, 171, 167, 79, 231, 177, + 175, 122, 61, 68, 203, 113, 48, 221, 254, 62, 97, 2, 175, 225, 201, 186, 174, 158, 244, 151, 115, 191, 152, + 251, 18, 245, 218, 127, 112, 195, 6, 112, 176, 153, 95, 245, 90, 252, 134, 178, 50, 219, 128, 113, 91, 248, + 225, 135, 60, 142, 147, 12, 250, 163, 238, 75, 116, 132, 31, 8, 253, 69, 238, 95, 220, 183, 47, 127, 119, + 14, 206, 53, 170, 215, 226, 47, 148, 217, 136, 10, 86, 179, 177, 6, 36, 117, 235, 214, 168, 6, 100, 55, + 209, 255, 137, 218, 47, 231, 126, 204, 33, 170, 215, 65, 180, 18, 150, 143, 170, 234, 234, 224, 195, 241, + 227, 61, 206, 1, 70, 253, 229, 190, 31, 115, 255, 254, 130, 2, 168, 102, 185, 95, 249, 58, 252, 135, 255, + 3, 222, 105, 177, 195, 34, 229, 8, 239, 0, 0, 3, 101, 109, 107, 66, 84, 250, 206, 202, 254, 0, 132, 111, + 199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, + 156, 237, 217, 225, 77, 235, 48, 16, 0, 96, 70, 232, 8, 29, 161, 35, 116, 4, 70, 232, 8, 140, 192, 8, 29, + 129, 17, 24, 129, 1, 242, 131, 17, 58, 2, 27, 244, 97, 169, 150, 204, 189, 115, 146, 130, 41, 32, 125, 39, + 125, 63, 72, 29, 251, 226, 75, 28, 151, 222, 221, 9, 33, 132, 16, 66, 8, 33, 196, 247, 196, 110, 154, 166, + 125, 71, 214, 126, 27, 218, 108, 58, 237, 178, 190, 119, 51, 109, 99, 191, 237, 248, 115, 57, 174, 201, 99, + 68, 238, 89, 219, 182, 191, 109, 167, 175, 205, 76, 206, 187, 228, 26, 151, 174, 97, 68, 148, 156, 142, + 239, 222, 222, 157, 103, 180, 231, 60, 190, 255, 125, 234, 180, 43, 199, 15, 73, 238, 47, 73, 219, 222, + 156, 191, 206, 140, 159, 245, 147, 121, 233, 244, 63, 34, 247, 231, 78, 191, 245, 243, 199, 240, 121, 201, + 227, 105, 69, 190, 113, 188, 94, 205, 70, 70, 54, 215, 115, 245, 95, 219, 254, 41, 228, 159, 213, 45, 155, + 235, 237, 194, 248, 107, 235, 31, 231, 116, 116, 238, 241, 249, 236, 213, 191, 212, 126, 205, 184, 63, 81, + 255, 199, 36, 143, 231, 75, 254, 81, 214, 190, 172, 25, 15, 151, 185, 120, 152, 254, 95, 67, 14, 201, 53, + 93, 243, 28, 45, 213, 255, 37, 201, 51, 230, 80, 215, 213, 209, 185, 159, 86, 214, 63, 62, 247, 229, 188, + 99, 146, 119, 54, 222, 168, 58, 247, 34, 174, 131, 115, 239, 228, 53, 237, 119, 225, 243, 215, 133, 57, 44, + 226, 26, 221, 91, 155, 179, 126, 226, 58, 91, 226, 16, 206, 171, 109, 190, 35, 247, 135, 166, 77, 86, 255, + 77, 210, 231, 154, 189, 201, 45, 234, 31, 115, 203, 158, 197, 185, 246, 113, 109, 173, 17, 231, 170, 94, + 111, 111, 14, 219, 251, 62, 214, 224, 51, 245, 223, 39, 245, 31, 153, 123, 123, 31, 189, 53, 109, 178, 250, + 223, 207, 92, 235, 92, 220, 162, 254, 217, 60, 141, 104, 31, 215, 217, 250, 158, 108, 231, 240, 185, 115, + 223, 29, 155, 227, 113, 221, 172, 109, 230, 234, 191, 9, 125, 215, 57, 31, 153, 251, 253, 244, 241, 93, 81, + 247, 10, 89, 253, 99, 127, 175, 151, 123, 47, 115, 76, 174, 113, 169, 134, 95, 137, 159, 172, 127, 92, 163, + 235, 51, 212, 206, 107, 124, 118, 106, 255, 215, 236, 255, 234, 243, 57, 50, 247, 186, 95, 104, 219, 237, + 46, 125, 46, 213, 127, 206, 173, 247, 127, 113, 78, 142, 11, 227, 141, 158, 195, 118, 79, 124, 8, 245, 126, + 187, 156, 243, 213, 250, 215, 245, 118, 116, 238, 229, 88, 155, 127, 221, 135, 254, 165, 250, 111, 195, + 248, 175, 11, 227, 125, 246, 29, 186, 93, 241, 12, 149, 177, 219, 245, 190, 222, 139, 75, 245, 63, 77, 249, + 90, 250, 52, 125, 252, 126, 54, 58, 247, 114, 44, 222, 83, 237, 190, 224, 47, 188, 255, 75, 196, 61, 241, + 126, 97, 204, 107, 247, 208, 167, 78, 221, 202, 56, 177, 38, 111, 73, 191, 75, 245, 95, 122, 103, 125, 87, + 238, 245, 120, 220, 163, 196, 188, 126, 243, 254, 191, 68, 182, 62, 205, 125, 255, 143, 239, 237, 165, 239, + 208, 109, 125, 178, 57, 140, 123, 181, 184, 14, 141, 172, 255, 232, 220, 75, 108, 146, 243, 226, 185, 241, + 30, 41, 237, 159, 146, 249, 61, 36, 227, 93, 87, 205, 235, 99, 237, 255, 166, 206, 51, 215, 211, 19, 215, + 216, 108, 14, 99, 77, 206, 211, 199, 239, 212, 35, 235, 63, 58, 247, 26, 113, 47, 24, 243, 42, 115, 28, + 215, 158, 165, 49, 111, 85, 255, 154, 223, 154, 121, 105, 207, 57, 204, 220, 55, 167, 78, 93, 178, 57, 140, + 235, 99, 177, 157, 190, 175, 254, 35, 115, 111, 35, 246, 23, 251, 248, 205, 255, 255, 111, 99, 63, 93, 247, + 251, 95, 252, 61, 107, 59, 147, 115, 251, 27, 90, 251, 14, 108, 143, 199, 119, 114, 54, 254, 110, 229, 120, + 75, 49, 34, 247, 26, 219, 79, 246, 181, 239, 92, 251, 45, 127, 255, 19, 66, 8, 33, 132, 16, 66, 8, 33, 196, + 15, 199, 249, 124, 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, 248, 9, 255, 0, 194, 154, 247, 53, 92, 205, 41, + 89, 0, 0, 50, 16, 105, 84, 88, 116, 88, 77, 76, 58, 99, 111, 109, 46, 97, 100, 111, 98, 101, 46, 120, 109, + 112, 0, 0, 0, 0, 0, 60, 63, 120, 112, 97, 99, 107, 101, 116, 32, 98, 101, 103, 105, 110, 61, 34, 239, 187, + 191, 34, 32, 105, 100, 61, 34, 87, 53, 77, 48, 77, 112, 67, 101, 104, 105, 72, 122, 114, 101, 83, 122, 78, + 84, 99, 122, 107, 99, 57, 100, 34, 63, 62, 10, 60, 120, 58, 120, 109, 112, 109, 101, 116, 97, 32, 120, 109, + 108, 110, 115, 58, 120, 61, 34, 97, 100, 111, 98, 101, 58, 110, 115, 58, 109, 101, 116, 97, 47, 34, 32, + 120, 58, 120, 109, 112, 116, 107, 61, 34, 65, 100, 111, 98, 101, 32, 88, 77, 80, 32, 67, 111, 114, 101, 32, + 52, 46, 50, 46, 50, 45, 99, 48, 54, 51, 32, 53, 51, 46, 51, 53, 49, 55, 51, 53, 44, 32, 50, 48, 48, 56, 47, + 48, 55, 47, 50, 50, 45, 49, 56, 58, 49, 49, 58, 49, 50, 32, 32, 32, 32, 32, 32, 32, 32, 34, 62, 10, 32, 32, + 32, 60, 114, 100, 102, 58, 82, 68, 70, 32, 120, 109, 108, 110, 115, 58, 114, 100, 102, 61, 34, 104, 116, + 116, 112, 58, 47, 47, 119, 119, 119, 46, 119, 51, 46, 111, 114, 103, 47, 49, 57, 57, 57, 47, 48, 50, 47, + 50, 50, 45, 114, 100, 102, 45, 115, 121, 110, 116, 97, 120, 45, 110, 115, 35, 34, 62, 10, 32, 32, 32, 32, + 32, 32, 60, 114, 100, 102, 58, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 32, 114, 100, 102, 58, + 97, 98, 111, 117, 116, 61, 34, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 120, 109, 108, 110, + 115, 58, 120, 109, 112, 61, 34, 104, 116, 116, 112, 58, 47, 47, 110, 115, 46, 97, 100, 111, 98, 101, 46, + 99, 111, 109, 47, 120, 97, 112, 47, 49, 46, 48, 47, 34, 62, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 60, + 120, 109, 112, 58, 67, 114, 101, 97, 116, 111, 114, 84, 111, 111, 108, 62, 65, 100, 111, 98, 101, 32, 70, + 105, 114, 101, 119, 111, 114, 107, 115, 32, 67, 83, 52, 60, 47, 120, 109, 112, 58, 67, 114, 101, 97, 116, + 111, 114, 84, 111, 111, 108, 62, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 60, 120, 109, 112, 58, 67, 114, + 101, 97, 116, 101, 68, 97, 116, 101, 62, 50, 48, 50, 50, 45, 48, 53, 45, 48, 57, 84, 50, 48, 58, 52, 53, + 58, 50, 50, 90, 60, 47, 120, 109, 112, 58, 67, 114, 101, 97, 116, 101, 68, 97, 116, 101, 62, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 60, 120, 109, 112, 58, 77, 111, 100, 105, 102, 121, 68, 97, 116, 101, 62, 50, + 48, 50, 50, 45, 48, 53, 45, 50, 52, 84, 49, 55, 58, 50, 49, 58, 49, 52, 90, 60, 47, 120, 109, 112, 58, 77, + 111, 100, 105, 102, 121, 68, 97, 116, 101, 62, 10, 32, 32, 32, 32, 32, 32, 60, 47, 114, 100, 102, 58, 68, + 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 62, 10, 32, 32, 32, 32, 32, 32, 60, 114, 100, 102, 58, 68, + 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 32, 114, 100, 102, 58, 97, 98, 111, 117, 116, 61, 34, 34, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 120, 109, 108, 110, 115, 58, 100, 99, 61, 34, 104, 116, + 116, 112, 58, 47, 47, 112, 117, 114, 108, 46, 111, 114, 103, 47, 100, 99, 47, 101, 108, 101, 109, 101, 110, + 116, 115, 47, 49, 46, 49, 47, 34, 62, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 60, 100, 99, 58, 102, 111, + 114, 109, 97, 116, 62, 105, 109, 97, 103, 101, 47, 112, 110, 103, 60, 47, 100, 99, 58, 102, 111, 114, 109, + 97, 116, 62, 10, 32, 32, 32, 32, 32, 32, 60, 47, 114, 100, 102, 58, 68, 101, 115, 99, 114, 105, 112, 116, + 105, 111, 110, 62, 10, 32, 32, 32, 60, 47, 114, 100, 102, 58, 82, 68, 70, 62, 10, 60, 47, 120, 58, 120, + 109, 112, 109, 101, 116, 97, 62, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 60, 63, 120, 112, 97, 99, 107, 101, 116, + 32, 101, 110, 100, 61, 34, 119, 34, 63, 62, 143, 70, 183, 103, 0, 0, 32, 0, 73, 68, 65, 84, 120, 156, 236, + 157, 119, 88, 20, 103, 215, 198, 239, 165, 75, 17, 208, 88, 48, 118, 243, 98, 5, 68, 208, 216, 89, 141, + 209, 24, 123, 9, 98, 199, 6, 154, 216, 123, 73, 20, 177, 196, 2, 118, 99, 196, 36, 106, 140, 250, 90, 163, + 98, 44, 137, 74, 179, 161, 44, 69, 193, 194, 251, 153, 152, 168, 88, 98, 65, 5, 11, 186, 59, 223, 31, 187, + 131, 179, 195, 204, 176, 139, 176, 59, 192, 249, 93, 215, 92, 192, 50, 236, 60, 207, 236, 236, 206, 205, + 57, 231, 185, 143, 130, 97, 24, 16, 4, 65, 16, 4, 65, 16, 133, 135, 133, 185, 7, 64, 16, 4, 65, 16, 4, 81, + 210, 32, 129, 69, 16, 4, 65, 16, 4, 81, 200, 144, 192, 34, 8, 130, 32, 8, 130, 40, 100, 72, 96, 17, 4, 65, + 16, 4, 65, 20, 50, 36, 176, 8, 130, 32, 8, 130, 32, 10, 25, 18, 88, 4, 65, 16, 4, 65, 16, 133, 12, 9, 44, + 130, 32, 8, 130, 32, 136, 66, 134, 4, 22, 65, 16, 4, 65, 16, 68, 33, 67, 2, 139, 32, 8, 130, 32, 8, 162, + 144, 33, 129, 69, 16, 4, 65, 16, 4, 81, 200, 144, 192, 34, 8, 130, 32, 8, 130, 40, 100, 172, 204, 61, 0, 0, + 120, 249, 242, 37, 14, 29, 58, 132, 55, 111, 222, 64, 161, 80, 152, 123, 56, 4, 65, 16, 4, 65, 20, 67, 222, + 188, 121, 131, 246, 237, 219, 163, 122, 245, 234, 230, 30, 10, 192, 48, 140, 217, 183, 59, 119, 238, 192, + 222, 222, 222, 220, 167, 130, 32, 8, 130, 32, 136, 98, 206, 174, 93, 187, 204, 174, 107, 24, 134, 145, 71, + 4, 11, 64, 110, 228, 138, 34, 88, 4, 65, 136, 160, 247, 225, 192, 48, 12, 0, 48, 122, 59, 228, 253, 0, 97, + 64, 16, 68, 169, 129, 97, 24, 217, 232, 8, 170, 193, 34, 136, 247, 196, 220, 255, 37, 149, 228, 77, 135, 2, + 239, 196, 149, 66, 247, 59, 198, 193, 193, 193, 98, 194, 132, 9, 125, 85, 42, 213, 129, 9, 19, 38, 116, + 177, 176, 176, 0, 163, 69, 111, 127, 240, 132, 25, 65, 16, 132, 41, 32, 129, 69, 16, 132, 44, 209, 69, 163, + 244, 54, 134, 97, 52, 118, 118, 118, 8, 10, 10, 234, 120, 233, 210, 165, 168, 85, 171, 86, 237, 105, 210, + 164, 73, 143, 85, 171, 86, 29, 142, 143, 143, 63, 220, 189, 123, 247, 166, 10, 133, 66, 195, 48, 140, 6, + 218, 207, 55, 18, 90, 4, 65, 152, 5, 18, 88, 4, 65, 200, 6, 133, 66, 1, 133, 14, 188, 19, 85, 10, 134, 97, + 52, 12, 195, 104, 186, 118, 237, 218, 38, 49, 49, 241, 232, 198, 141, 27, 143, 215, 174, 93, 187, 13, 247, + 111, 125, 125, 125, 187, 28, 60, 120, 240, 204, 169, 83, 167, 126, 106, 210, 164, 201, 71, 12, 195, 168, + 25, 109, 24, 140, 47, 180, 8, 130, 32, 138, 28, 18, 88, 4, 65, 200, 2, 142, 168, 2, 56, 17, 43, 0, 234, + 142, 29, 59, 250, 196, 198, 198, 238, 141, 140, 140, 140, 170, 95, 191, 126, 39, 137, 167, 177, 86, 42, + 149, 195, 226, 227, 227, 19, 118, 236, 216, 177, 184, 78, 157, 58, 21, 117, 66, 11, 120, 39, 180, 184, 27, + 65, 16, 68, 145, 64, 2, 139, 32, 8, 179, 194, 137, 88, 1, 90, 209, 99, 161, 139, 88, 169, 253, 252, 252, + 234, 159, 60, 121, 114, 243, 241, 227, 199, 207, 182, 105, 211, 166, 15, 0, 75, 67, 158, 211, 202, 202, + 202, 185, 127, 255, 254, 179, 84, 42, 85, 226, 162, 69, 139, 198, 87, 168, 80, 193, 94, 64, 104, 177, 199, + 35, 161, 69, 16, 68, 161, 67, 2, 139, 32, 8, 179, 32, 34, 172, 24, 134, 97, 212, 245, 234, 213, 171, 181, + 119, 239, 222, 117, 209, 209, 209, 23, 219, 183, 111, 31, 8, 192, 166, 32, 199, 112, 118, 118, 174, 50, + 123, 246, 236, 213, 87, 174, 92, 137, 159, 60, 121, 114, 63, 27, 27, 27, 11, 134, 97, 212, 236, 241, 144, + 183, 120, 158, 54, 243, 45, 102, 32, 136, 18, 5, 9, 44, 130, 32, 76, 74, 62, 194, 170, 242, 150, 45, 91, + 22, 167, 164, 164, 36, 246, 233, 211, 231, 43, 0, 14, 133, 113, 204, 15, 62, 248, 160, 65, 120, 120, 248, + 127, 47, 93, 186, 116, 114, 224, 192, 129, 237, 44, 44, 44, 212, 186, 136, 86, 110, 186, 144, 55, 46, 130, + 32, 136, 247, 130, 4, 22, 65, 16, 38, 65, 68, 88, 129, 97, 24, 117, 173, 90, 181, 92, 55, 110, 220, 56, 43, + 49, 49, 49, 105, 232, 208, 161, 179, 108, 108, 108, 92, 138, 98, 12, 117, 235, 214, 109, 251, 203, 47, 191, + 156, 56, 113, 226, 196, 158, 182, 109, 219, 122, 1, 96, 11, 225, 115, 83, 133, 36, 180, 8, 130, 40, 12, 72, + 96, 17, 4, 81, 164, 72, 9, 171, 15, 62, 248, 192, 97, 222, 188, 121, 99, 83, 82, 82, 146, 130, 130, 130, + 22, 151, 41, 83, 166, 146, 9, 134, 100, 161, 84, 42, 251, 198, 196, 196, 156, 59, 124, 248, 240, 218, 70, + 141, 26, 85, 19, 90, 113, 72, 66, 139, 32, 136, 247, 129, 4, 22, 65, 16, 69, 6, 95, 88, 1, 0, 195, 48, 106, + 23, 23, 23, 155, 57, 115, 230, 4, 166, 166, 166, 94, 8, 9, 9, 89, 235, 228, 228, 100, 142, 198, 97, 101, + 186, 116, 233, 50, 246, 194, 133, 11, 170, 13, 27, 54, 204, 169, 94, 189, 186, 139, 80, 33, 60, 9, 45, 130, + 32, 10, 2, 9, 44, 130, 32, 10, 21, 5, 7, 188, 179, 91, 0, 195, 48, 106, 7, 7, 7, 203, 201, 147, 39, 247, + 185, 114, 229, 202, 217, 133, 11, 23, 110, 174, 84, 169, 82, 61, 115, 143, 183, 76, 153, 50, 31, 140, 30, + 61, 122, 97, 114, 114, 114, 194, 244, 233, 211, 135, 151, 45, 91, 214, 154, 132, 22, 65, 16, 239, 11, 9, + 44, 130, 32, 10, 13, 158, 0, 201, 245, 178, 178, 180, 180, 100, 2, 2, 2, 58, 199, 199, 199, 159, 10, 15, + 15, 223, 235, 230, 230, 230, 109, 174, 49, 138, 225, 234, 234, 90, 123, 233, 210, 165, 63, 94, 190, 124, + 249, 244, 151, 95, 126, 217, 205, 210, 210, 18, 156, 21, 135, 122, 53, 90, 102, 29, 40, 65, 16, 197, 2, 18, + 88, 4, 65, 188, 55, 98, 94, 86, 150, 150, 150, 234, 190, 125, 251, 182, 73, 76, 76, 60, 186, 115, 231, 206, + 223, 26, 52, 104, 208, 218, 156, 227, 52, 132, 234, 213, 171, 251, 174, 95, 191, 254, 80, 124, 124, 252, + 111, 221, 187, 119, 111, 14, 109, 33, 188, 6, 156, 52, 39, 69, 179, 8, 130, 200, 15, 18, 88, 4, 65, 20, 24, + 41, 147, 208, 206, 157, 59, 251, 156, 61, 123, 118, 239, 158, 61, 123, 162, 61, 61, 61, 59, 161, 152, 25, + 122, 250, 248, 248, 124, 118, 240, 224, 193, 216, 232, 232, 232, 45, 77, 155, 54, 117, 215, 165, 13, 245, + 122, 28, 146, 208, 34, 8, 66, 12, 18, 88, 4, 65, 24, 141, 148, 176, 106, 222, 188, 121, 253, 200, 200, 200, + 45, 71, 142, 28, 57, 219, 180, 105, 211, 62, 40, 222, 159, 51, 214, 109, 219, 182, 29, 122, 238, 220, 185, + 132, 157, 59, 119, 46, 169, 87, 175, 94, 37, 170, 207, 34, 8, 194, 16, 138, 243, 7, 31, 65, 16, 38, 70, + 202, 36, 212, 199, 199, 167, 214, 129, 3, 7, 214, 158, 57, 115, 230, 98, 215, 174, 93, 135, 162, 128, 238, + 235, 114, 196, 210, 210, 210, 41, 32, 32, 96, 198, 197, 139, 23, 19, 191, 253, 246, 219, 137, 21, 43, 86, + 116, 16, 19, 90, 102, 29, 40, 65, 16, 178, 129, 4, 22, 65, 16, 249, 34, 37, 172, 106, 215, 174, 93, 121, + 231, 206, 157, 139, 227, 227, 227, 19, 123, 244, 232, 49, 214, 194, 194, 162, 80, 220, 215, 229, 136, 163, + 163, 163, 219, 204, 153, 51, 87, 166, 165, 165, 157, 159, 49, 99, 70, 127, 59, 59, 187, 60, 173, 119, 40, + 154, 69, 16, 4, 64, 2, 139, 32, 8, 9, 164, 76, 66, 171, 85, 171, 86, 110, 213, 170, 85, 179, 147, 147, 147, + 147, 2, 2, 2, 102, 89, 90, 90, 22, 137, 251, 186, 28, 249, 224, 131, 15, 26, 44, 89, 178, 100, 71, 114, + 114, 242, 169, 193, 131, 7, 119, 176, 180, 180, 84, 243, 86, 28, 82, 218, 144, 32, 74, 57, 36, 176, 8, 130, + 200, 131, 148, 176, 114, 115, 115, 115, 88, 182, 108, 217, 184, 180, 180, 180, 196, 9, 19, 38, 44, 114, + 114, 114, 50, 133, 251, 186, 44, 169, 91, 183, 110, 155, 159, 127, 254, 249, 120, 84, 84, 212, 62, 165, 82, + 217, 152, 28, 225, 9, 130, 96, 33, 129, 69, 16, 132, 30, 98, 194, 202, 222, 222, 222, 102, 214, 172, 89, + 195, 210, 210, 210, 46, 76, 155, 54, 109, 141, 153, 220, 215, 229, 136, 69, 235, 214, 173, 123, 71, 69, 69, + 157, 251, 237, 183, 223, 214, 55, 110, 220, 184, 58, 9, 45, 130, 32, 72, 96, 17, 4, 1, 64, 79, 0, 232, 9, + 43, 7, 7, 7, 203, 47, 191, 252, 178, 79, 90, 90, 218, 217, 197, 139, 23, 255, 228, 234, 234, 106, 118, 247, + 117, 153, 98, 247, 249, 231, 159, 127, 121, 238, 220, 185, 196, 239, 191, 255, 254, 155, 154, 53, 107, 186, + 210, 138, 67, 130, 40, 189, 144, 192, 34, 136, 82, 14, 239, 134, 111, 193, 48, 140, 130, 97, 24, 181, 141, + 141, 13, 51, 114, 228, 200, 206, 41, 41, 41, 167, 214, 175, 95, 191, 183, 102, 205, 154, 178, 115, 95, 151, + 35, 118, 118, 118, 229, 130, 131, 131, 67, 83, 82, 82, 18, 102, 207, 158, 61, 170, 108, 217, 178, 182, 180, + 226, 144, 32, 74, 31, 36, 176, 8, 162, 148, 194, 239, 23, 8, 173, 184, 82, 43, 20, 10, 117, 151, 46, 93, + 218, 168, 84, 170, 99, 155, 54, 109, 250, 173, 78, 157, 58, 178, 117, 95, 255, 125, 255, 126, 44, 159, 54, + 13, 247, 110, 223, 54, 247, 80, 242, 80, 182, 108, 217, 90, 139, 22, 45, 138, 72, 77, 77, 61, 253, 213, 87, + 95, 117, 183, 181, 181, 133, 78, 104, 229, 158, 115, 138, 102, 17, 68, 201, 133, 4, 22, 65, 148, 50, 4, 10, + 216, 21, 172, 73, 104, 167, 78, 157, 124, 226, 226, 226, 246, 30, 62, 124, 56, 186, 81, 163, 70, 29, 33, + 83, 247, 245, 132, 216, 88, 12, 111, 215, 14, 99, 250, 244, 193, 170, 176, 48, 244, 242, 242, 194, 15, 75, + 150, 32, 251, 249, 115, 115, 15, 45, 15, 213, 170, 85, 107, 178, 110, 221, 186, 131, 231, 206, 157, 59, + 210, 163, 71, 143, 22, 10, 133, 66, 173, 59, 223, 180, 226, 144, 32, 74, 48, 36, 176, 8, 162, 148, 32, 229, + 101, 165, 84, 42, 235, 159, 58, 117, 106, 203, 177, 99, 199, 206, 182, 106, 213, 74, 182, 238, 235, 105, 9, + 9, 24, 215, 163, 7, 6, 42, 149, 136, 142, 142, 70, 25, 0, 229, 1, 60, 121, 252, 24, 11, 102, 205, 66, 111, + 47, 47, 28, 216, 178, 5, 111, 223, 190, 53, 247, 80, 243, 224, 237, 237, 221, 233, 192, 129, 3, 49, 127, + 252, 241, 199, 207, 62, 62, 62, 245, 160, 237, 113, 72, 133, 240, 4, 81, 66, 145, 229, 135, 40, 65, 16, + 133, 135, 148, 176, 106, 208, 160, 65, 205, 221, 187, 119, 175, 139, 138, 138, 74, 104, 215, 174, 157, 108, + 221, 215, 255, 188, 122, 21, 51, 6, 12, 64, 191, 22, 45, 112, 228, 208, 33, 216, 48, 12, 202, 2, 176, 130, + 246, 67, 204, 14, 128, 43, 128, 191, 255, 250, 11, 147, 135, 13, 195, 192, 143, 63, 198, 233, 163, 71, 205, + 58, 102, 17, 172, 63, 249, 228, 147, 193, 241, 241, 241, 23, 118, 236, 216, 177, 172, 65, 131, 6, 149, 169, + 16, 158, 32, 74, 38, 36, 176, 8, 162, 132, 34, 37, 172, 234, 213, 171, 87, 121, 235, 214, 173, 223, 38, 38, + 38, 170, 190, 248, 226, 139, 175, 0, 216, 155, 113, 168, 162, 220, 249, 235, 47, 132, 6, 7, 163, 183, 183, + 55, 246, 236, 220, 9, 139, 183, 111, 225, 12, 173, 10, 180, 132, 86, 96, 177, 155, 37, 180, 147, 40, 11, + 32, 41, 49, 17, 195, 63, 255, 28, 99, 58, 119, 70, 90, 66, 130, 217, 198, 47, 134, 165, 165, 165, 83, 255, + 254, 253, 167, 37, 36, 36, 168, 150, 46, 93, 58, 169, 114, 229, 202, 142, 156, 250, 44, 18, 90, 4, 81, 2, + 32, 129, 69, 16, 37, 12, 41, 147, 208, 90, 181, 106, 149, 139, 136, 136, 152, 157, 148, 148, 148, 52, 100, + 200, 144, 153, 182, 182, 182, 174, 230, 28, 171, 24, 15, 239, 221, 67, 216, 212, 169, 232, 229, 229, 133, + 45, 17, 17, 208, 188, 126, 13, 87, 232, 11, 43, 107, 232, 11, 44, 43, 206, 227, 78, 208, 138, 173, 63, 142, + 29, 67, 191, 22, 45, 240, 205, 176, 97, 184, 253, 215, 95, 102, 153, 139, 20, 101, 202, 148, 113, 155, 62, + 125, 250, 138, 180, 180, 180, 243, 19, 38, 76, 24, 192, 182, 222, 17, 18, 90, 230, 29, 41, 65, 16, 198, 66, + 2, 139, 32, 74, 8, 82, 194, 170, 124, 249, 242, 14, 243, 230, 205, 27, 151, 148, 148, 148, 56, 106, 212, + 168, 69, 118, 118, 118, 178, 116, 95, 127, 250, 248, 49, 190, 15, 13, 69, 143, 134, 13, 177, 62, 60, 28, + 47, 159, 63, 23, 21, 86, 214, 186, 205, 134, 243, 61, 95, 104, 57, 3, 176, 124, 251, 22, 219, 183, 108, 65, + 47, 79, 79, 172, 158, 53, 11, 153, 143, 30, 153, 126, 98, 249, 80, 174, 92, 185, 250, 171, 86, 173, 218, + 158, 146, 146, 18, 53, 120, 240, 224, 14, 214, 214, 214, 252, 214, 59, 180, 226, 144, 32, 138, 25, 36, 176, + 8, 162, 152, 163, 80, 40, 68, 221, 215, 93, 93, 93, 109, 230, 204, 153, 51, 236, 234, 213, 171, 23, 66, 66, + 66, 214, 56, 59, 59, 203, 210, 125, 253, 229, 139, 23, 216, 182, 106, 21, 122, 53, 106, 132, 165, 243, 230, + 33, 243, 241, 99, 184, 66, 91, 91, 197, 21, 86, 124, 81, 101, 195, 123, 156, 187, 177, 66, 203, 6, 218, + 250, 172, 87, 89, 89, 88, 181, 100, 9, 122, 121, 120, 96, 199, 218, 181, 120, 253, 234, 149, 105, 39, 105, + 0, 238, 238, 238, 173, 126, 254, 249, 231, 223, 99, 99, 99, 247, 183, 107, 215, 142, 109, 189, 163, 1, 245, + 56, 36, 136, 98, 7, 9, 44, 130, 40, 198, 8, 248, 88, 129, 97, 24, 181, 157, 157, 157, 229, 228, 201, 147, + 251, 166, 165, 165, 157, 93, 184, 112, 225, 79, 21, 42, 84, 144, 165, 251, 122, 206, 235, 215, 216, 255, + 227, 143, 232, 227, 225, 129, 121, 147, 38, 225, 222, 221, 187, 112, 5, 80, 6, 239, 234, 170, 196, 4, 148, + 13, 239, 123, 27, 206, 99, 252, 20, 162, 37, 0, 91, 104, 133, 214, 253, 187, 119, 241, 245, 248, 241, 240, + 111, 210, 4, 191, 239, 217, 3, 93, 129, 185, 156, 80, 52, 111, 222, 188, 215, 169, 83, 167, 206, 253, 246, + 219, 111, 27, 26, 52, 104, 80, 147, 90, 239, 16, 68, 241, 131, 4, 22, 65, 20, 51, 20, 28, 240, 206, 199, + 42, 215, 125, 125, 192, 128, 1, 157, 19, 18, 18, 78, 133, 135, 135, 239, 113, 115, 115, 147, 165, 251, 186, + 70, 163, 193, 177, 221, 187, 17, 224, 235, 139, 169, 35, 71, 226, 175, 63, 255, 132, 11, 180, 117, 83, 252, + 52, 159, 84, 132, 138, 31, 173, 202, 111, 127, 43, 221, 49, 92, 0, 92, 191, 122, 21, 95, 250, 251, 99, 152, + 159, 31, 18, 98, 98, 76, 51, 113, 227, 176, 251, 252, 243, 207, 71, 39, 38, 38, 170, 54, 110, 220, 56, 175, + 86, 173, 90, 229, 104, 197, 33, 65, 20, 31, 72, 96, 17, 68, 49, 130, 119, 35, 205, 53, 9, 181, 180, 180, + 84, 251, 251, 251, 183, 185, 120, 241, 226, 177, 237, 219, 183, 31, 105, 216, 176, 161, 108, 221, 215, 79, + 31, 61, 138, 65, 45, 90, 96, 108, 191, 126, 72, 75, 77, 133, 51, 180, 162, 135, 187, 42, 208, 16, 161, 36, + 181, 229, 247, 247, 150, 0, 28, 160, 45, 134, 63, 19, 23, 135, 193, 237, 218, 97, 114, 159, 62, 184, 145, + 150, 86, 244, 39, 192, 72, 108, 109, 109, 203, 5, 5, 5, 133, 92, 190, 124, 89, 245, 205, 55, 223, 4, 59, + 59, 59, 219, 114, 234, 179, 168, 16, 158, 32, 100, 10, 9, 44, 130, 40, 6, 240, 11, 216, 25, 134, 177, 96, + 221, 215, 59, 118, 236, 232, 123, 254, 252, 249, 189, 187, 118, 237, 138, 246, 244, 244, 236, 104, 214, + 129, 74, 144, 16, 27, 139, 145, 237, 219, 99, 248, 231, 159, 35, 225, 194, 5, 56, 65, 43, 112, 248, 145, + 40, 67, 132, 149, 37, 231, 43, 223, 174, 129, 47, 180, 164, 158, 223, 10, 218, 66, 120, 91, 134, 193, 193, + 253, 251, 209, 215, 215, 23, 139, 198, 142, 197, 131, 140, 140, 34, 62, 27, 198, 227, 224, 224, 80, 35, 52, + 52, 244, 251, 171, 87, 175, 158, 25, 61, 122, 116, 79, 75, 75, 75, 209, 214, 59, 36, 182, 8, 194, 252, 144, + 192, 34, 8, 25, 35, 178, 50, 80, 3, 64, 221, 162, 69, 139, 250, 191, 253, 246, 219, 150, 163, 71, 143, 158, + 241, 245, 245, 149, 175, 251, 186, 74, 133, 241, 61, 122, 96, 176, 82, 137, 152, 168, 40, 216, 227, 157, + 176, 98, 107, 172, 88, 225, 195, 47, 90, 231, 139, 42, 238, 102, 161, 219, 44, 121, 95, 13, 21, 89, 236, + 87, 118, 12, 46, 0, 212, 175, 94, 225, 199, 245, 235, 209, 211, 195, 3, 17, 139, 22, 33, 251, 217, 179, 34, + 60, 51, 5, 195, 205, 205, 205, 123, 195, 134, 13, 191, 94, 184, 112, 225, 104, 207, 158, 61, 91, 89, 88, + 88, 228, 41, 132, 7, 40, 162, 69, 16, 230, 70, 150, 31, 200, 4, 81, 218, 145, 50, 9, 245, 245, 245, 173, + 125, 240, 224, 193, 181, 103, 207, 158, 77, 248, 252, 243, 207, 135, 90, 88, 88, 200, 214, 125, 125, 230, + 192, 129, 8, 104, 222, 28, 71, 14, 29, 130, 173, 206, 125, 157, 95, 51, 37, 22, 97, 18, 19, 86, 124, 129, + 165, 128, 176, 216, 50, 36, 101, 200, 47, 134, 103, 11, 225, 159, 61, 126, 140, 111, 191, 254, 26, 189, 61, + 61, 241, 235, 79, 63, 225, 237, 155, 55, 69, 117, 154, 10, 140, 183, 183, 247, 167, 191, 254, 250, 107, + 116, 84, 84, 212, 182, 166, 77, 155, 214, 163, 66, 120, 130, 144, 23, 36, 176, 8, 66, 70, 72, 9, 171, 26, + 53, 106, 84, 222, 190, 125, 251, 226, 115, 231, 206, 169, 186, 119, 239, 62, 22, 50, 117, 95, 207, 184, + 121, 19, 161, 163, 71, 163, 183, 183, 55, 118, 239, 216, 145, 235, 190, 158, 159, 224, 225, 138, 29, 174, + 64, 18, 19, 85, 66, 155, 133, 192, 198, 253, 123, 33, 81, 199, 175, 205, 178, 196, 187, 214, 59, 255, 252, + 253, 55, 166, 140, 24, 129, 129, 205, 155, 35, 246, 200, 145, 162, 56, 93, 239, 139, 85, 219, 182, 109, 7, + 157, 59, 119, 238, 226, 174, 93, 187, 150, 55, 108, 216, 208, 141, 10, 225, 9, 66, 30, 144, 192, 34, 8, 25, + 32, 101, 18, 90, 189, 122, 245, 114, 171, 87, 175, 158, 153, 150, 150, 150, 52, 96, 192, 128, 89, 86, 86, + 86, 46, 230, 28, 171, 24, 15, 239, 223, 71, 248, 180, 105, 232, 233, 229, 133, 205, 27, 55, 230, 113, 95, + 207, 175, 198, 74, 42, 37, 200, 21, 86, 44, 66, 2, 139, 251, 184, 144, 184, 50, 164, 8, 158, 59, 14, 7, + 104, 83, 135, 73, 137, 137, 24, 213, 165, 11, 70, 119, 234, 132, 212, 139, 23, 11, 233, 140, 21, 30, 150, + 150, 150, 142, 254, 254, 254, 83, 85, 42, 85, 98, 88, 88, 216, 20, 55, 55, 55, 71, 18, 90, 4, 97, 94, 72, + 96, 17, 132, 153, 17, 19, 86, 110, 110, 110, 14, 203, 151, 47, 31, 119, 233, 210, 37, 213, 248, 241, 227, + 191, 117, 112, 112, 144, 165, 251, 250, 179, 39, 79, 240, 253, 130, 5, 232, 217, 176, 33, 214, 133, 133, + 225, 229, 179, 103, 130, 238, 235, 134, 174, 10, 228, 10, 42, 110, 180, 138, 133, 255, 51, 4, 126, 199, + 143, 106, 9, 165, 14, 197, 68, 159, 144, 135, 150, 19, 180, 222, 92, 39, 126, 255, 29, 1, 45, 90, 96, 246, + 144, 33, 184, 117, 227, 70, 1, 207, 88, 209, 97, 107, 107, 91, 105, 202, 148, 41, 97, 105, 105, 105, 23, + 166, 79, 159, 62, 200, 214, 214, 214, 146, 215, 122, 7, 0, 213, 103, 17, 132, 41, 32, 129, 69, 16, 102, 64, + 192, 203, 42, 87, 88, 57, 58, 58, 218, 76, 155, 54, 45, 240, 202, 149, 43, 23, 166, 78, 157, 186, 198, 217, + 217, 185, 134, 185, 199, 43, 68, 174, 251, 186, 135, 7, 150, 206, 157, 139, 204, 71, 143, 80, 14, 218, 58, + 38, 67, 162, 68, 66, 105, 65, 126, 45, 149, 80, 100, 202, 16, 248, 127, 163, 16, 120, 126, 126, 42, 50, 63, + 241, 103, 13, 93, 235, 29, 181, 26, 187, 182, 109, 67, 239, 198, 141, 177, 114, 198, 12, 60, 121, 248, 208, + 208, 83, 102, 50, 92, 93, 93, 235, 46, 93, 186, 116, 91, 90, 90, 90, 244, 208, 161, 67, 59, 218, 216, 216, + 168, 117, 66, 139, 162, 89, 4, 97, 34, 72, 96, 17, 132, 137, 17, 139, 88, 149, 41, 83, 198, 98, 236, 216, + 177, 125, 83, 83, 83, 207, 44, 91, 182, 108, 179, 139, 139, 139, 172, 221, 215, 123, 235, 220, 215, 239, + 222, 185, 35, 216, 214, 38, 63, 209, 34, 148, 2, 20, 138, 90, 25, 35, 172, 184, 136, 165, 13, 249, 181, 89, + 249, 165, 14, 185, 238, 240, 236, 62, 46, 0, 94, 102, 101, 97, 205, 178, 101, 232, 229, 225, 129, 95, 86, + 175, 198, 171, 151, 47, 11, 48, 202, 162, 165, 78, 157, 58, 45, 183, 108, 217, 114, 236, 204, 153, 51, 7, + 218, 183, 111, 223, 4, 128, 90, 103, 239, 65, 66, 139, 32, 138, 24, 18, 88, 4, 97, 34, 4, 34, 86, 10, 93, + 91, 27, 140, 28, 57, 242, 179, 203, 151, 47, 71, 173, 93, 187, 118, 79, 141, 26, 53, 154, 152, 123, 172, + 66, 104, 212, 106, 28, 223, 181, 11, 253, 155, 54, 197, 180, 145, 35, 241, 55, 207, 125, 157, 47, 72, 248, + 173, 108, 196, 34, 67, 92, 177, 195, 23, 88, 82, 5, 237, 134, 110, 252, 231, 227, 167, 12, 165, 68, 150, + 88, 175, 67, 43, 104, 5, 101, 57, 0, 255, 222, 187, 135, 185, 19, 39, 194, 191, 73, 19, 28, 219, 181, 11, + 140, 70, 243, 222, 231, 186, 144, 81, 248, 250, 250, 246, 56, 121, 242, 228, 217, 227, 199, 143, 127, 239, + 233, 233, 89, 11, 90, 161, 5, 80, 125, 22, 65, 20, 25, 36, 176, 8, 162, 136, 225, 221, 184, 114, 133, 149, + 66, 161, 80, 127, 254, 249, 231, 109, 226, 227, 227, 143, 108, 218, 180, 233, 104, 157, 58, 117, 100, 235, + 190, 30, 119, 244, 40, 6, 183, 108, 137, 175, 2, 2, 144, 118, 249, 50, 202, 66, 191, 173, 141, 49, 5, 236, + 252, 200, 21, 63, 29, 200, 47, 90, 47, 12, 132, 158, 91, 200, 250, 65, 42, 154, 37, 36, 182, 172, 160, 173, + 205, 114, 1, 144, 126, 237, 26, 198, 6, 4, 32, 176, 109, 91, 92, 140, 142, 46, 196, 209, 23, 26, 182, 29, + 59, 118, 12, 142, 143, 143, 87, 253, 240, 195, 15, 33, 82, 173, 119, 204, 58, 74, 130, 40, 33, 144, 192, + 34, 136, 34, 66, 100, 101, 160, 26, 128, 186, 83, 167, 78, 62, 113, 113, 113, 123, 126, 251, 237, 183, 104, + 79, 79, 207, 78, 102, 28, 166, 36, 172, 251, 250, 72, 142, 251, 186, 35, 12, 19, 84, 92, 17, 194, 95, 209, + 199, 79, 7, 2, 133, 47, 170, 196, 224, 167, 14, 133, 108, 29, 140, 177, 148, 96, 55, 71, 104, 139, 225, + 207, 157, 57, 131, 33, 237, 218, 97, 114, 239, 222, 248, 63, 25, 182, 222, 177, 179, 179, 115, 29, 49, 98, + 196, 188, 212, 212, 212, 132, 208, 208, 208, 49, 46, 46, 46, 118, 188, 66, 120, 114, 131, 39, 136, 66, 128, + 4, 22, 65, 20, 50, 82, 109, 109, 148, 74, 101, 253, 168, 168, 168, 205, 199, 142, 29, 59, 219, 170, 85, + 171, 190, 144, 233, 123, 48, 77, 165, 194, 248, 238, 221, 5, 221, 215, 13, 49, 239, 20, 107, 107, 99, 78, + 97, 197, 135, 47, 180, 248, 227, 51, 196, 59, 75, 72, 116, 149, 133, 182, 208, 255, 208, 175, 191, 162, + 175, 143, 15, 22, 142, 25, 131, 251, 119, 238, 152, 104, 86, 134, 99, 111, 111, 95, 227, 155, 111, 190, + 249, 46, 45, 45, 237, 236, 184, 113, 227, 122, 89, 89, 89, 129, 132, 22, 65, 20, 30, 178, 252, 112, 39, + 136, 226, 136, 152, 73, 40, 0, 117, 163, 70, 141, 106, 237, 220, 185, 115, 77, 84, 84, 212, 69, 165, 82, + 25, 8, 109, 198, 73, 118, 176, 238, 235, 253, 62, 254, 24, 71, 34, 35, 97, 203, 48, 122, 38, 161, 134, 250, + 71, 113, 5, 149, 220, 132, 21, 31, 238, 24, 132, 162, 89, 252, 168, 150, 33, 243, 103, 11, 225, 53, 175, + 95, 227, 167, 239, 191, 71, 175, 70, 141, 176, 113, 193, 2, 100, 201, 176, 245, 78, 149, 42, 85, 188, 214, + 172, 89, 179, 63, 33, 33, 225, 88, 239, 222, 189, 91, 235, 90, 239, 232, 53, 147, 38, 161, 69, 16, 198, 67, + 2, 139, 32, 222, 19, 133, 66, 33, 180, 50, 144, 97, 24, 70, 93, 183, 110, 221, 202, 63, 255, 252, 243, 98, + 149, 74, 165, 10, 8, 8, 24, 7, 173, 119, 165, 236, 200, 184, 121, 19, 11, 70, 143, 70, 31, 111, 111, 236, + 217, 177, 3, 150, 106, 53, 92, 160, 85, 129, 134, 214, 35, 9, 9, 44, 67, 220, 215, 229, 176, 241, 199, 199, + 79, 105, 22, 180, 16, 158, 109, 189, 243, 60, 51, 19, 75, 231, 206, 69, 31, 15, 15, 236, 255, 225, 7, 89, + 182, 222, 241, 242, 242, 234, 176, 111, 223, 190, 232, 216, 216, 216, 237, 205, 155, 55, 111, 160, 139, + 102, 233, 245, 56, 36, 161, 69, 16, 134, 67, 2, 139, 32, 10, 78, 158, 251, 52, 107, 185, 80, 179, 102, 205, + 114, 17, 17, 17, 179, 82, 82, 82, 146, 6, 15, 30, 60, 203, 198, 198, 198, 213, 188, 67, 21, 230, 225, 189, + 123, 8, 159, 54, 13, 189, 60, 61, 177, 133, 231, 190, 158, 159, 152, 224, 126, 159, 95, 83, 102, 33, 17, + 35, 55, 196, 86, 29, 138, 137, 44, 99, 132, 39, 219, 122, 231, 246, 63, 255, 96, 218, 168, 81, 24, 240, + 241, 199, 136, 57, 124, 216, 100, 115, 51, 2, 203, 86, 173, 90, 13, 56, 115, 230, 204, 133, 189, 123, 247, + 134, 55, 104, 208, 160, 10, 57, 194, 19, 68, 193, 32, 129, 69, 16, 5, 131, 31, 177, 2, 195, 48, 234, 10, + 21, 42, 216, 135, 132, 132, 140, 83, 169, 84, 170, 81, 163, 70, 45, 182, 181, 181, 149, 173, 251, 250, 198, + 5, 11, 208, 179, 81, 35, 172, 15, 11, 195, 139, 231, 207, 245, 132, 21, 191, 230, 72, 202, 102, 65, 168, + 190, 74, 142, 169, 64, 99, 40, 140, 66, 120, 161, 130, 120, 123, 104, 205, 74, 47, 37, 37, 33, 168, 91, 55, + 4, 119, 236, 136, 212, 11, 23, 76, 52, 43, 195, 177, 176, 176, 112, 232, 211, 167, 207, 228, 11, 23, 46, + 36, 134, 133, 133, 77, 171, 92, 185, 178, 147, 132, 208, 50, 235, 88, 9, 66, 174, 40, 116, 111, 24, 179, + 146, 145, 145, 1, 119, 119, 119, 100, 103, 103, 131, 222, 172, 132, 204, 209, 211, 13, 186, 247, 143, 186, + 92, 185, 114, 101, 198, 140, 25, 211, 111, 194, 132, 9, 51, 43, 84, 168, 80, 215, 124, 195, 147, 230, 101, + 118, 54, 246, 110, 218, 132, 45, 203, 151, 227, 175, 140, 12, 56, 64, 43, 158, 248, 181, 82, 124, 159, 40, + 254, 99, 92, 209, 33, 101, 175, 80, 18, 222, 205, 252, 79, 72, 70, 183, 105, 120, 95, 213, 186, 239, 53, + 156, 239, 213, 188, 77, 195, 217, 222, 2, 200, 2, 96, 103, 105, 137, 238, 253, 251, 35, 120, 222, 60, 84, + 255, 232, 163, 34, 159, 79, 65, 120, 242, 228, 73, 122, 120, 120, 248, 162, 21, 43, 86, 252, 247, 229, 203, + 151, 57, 10, 133, 194, 82, 247, 43, 246, 116, 128, 121, 143, 155, 9, 125, 238, 19, 133, 5, 195, 48, 216, + 189, 123, 55, 190, 248, 226, 11, 115, 15, 133, 34, 88, 4, 97, 32, 252, 84, 160, 130, 97, 24, 181, 173, 173, + 173, 197, 164, 73, 147, 250, 166, 166, 166, 158, 94, 184, 112, 225, 102, 185, 138, 43, 214, 125, 189, 143, + 167, 39, 66, 38, 77, 194, 189, 140, 140, 92, 247, 117, 177, 85, 114, 98, 81, 43, 177, 85, 129, 197, 61, + 106, 37, 134, 144, 104, 228, 10, 76, 177, 213, 134, 249, 57, 217, 179, 133, 240, 150, 106, 53, 254, 251, + 203, 47, 232, 211, 184, 49, 86, 78, 159, 142, 39, 255, 254, 107, 138, 105, 25, 133, 171, 171, 171, 251, + 194, 133, 11, 183, 166, 166, 166, 198, 12, 31, 62, 188, 147, 149, 149, 149, 134, 179, 226, 80, 47, 109, 72, + 98, 137, 32, 180, 144, 192, 34, 10, 5, 93, 138, 172, 196, 109, 16, 17, 86, 54, 54, 54, 204, 160, 65, 131, + 62, 83, 169, 84, 167, 86, 172, 88, 177, 199, 205, 205, 77, 158, 238, 235, 26, 13, 142, 113, 220, 215, 111, + 242, 220, 215, 13, 169, 35, 146, 74, 7, 138, 153, 132, 150, 68, 132, 10, 227, 165, 90, 239, 72, 165, 89, + 217, 199, 45, 117, 143, 187, 2, 120, 157, 157, 141, 181, 203, 151, 163, 87, 163, 70, 216, 182, 114, 37, 94, + 189, 120, 97, 186, 201, 25, 72, 237, 218, 181, 155, 255, 248, 227, 143, 71, 99, 98, 98, 14, 118, 232, 208, + 193, 7, 186, 214, 59, 224, 233, 107, 82, 89, 4, 65, 2, 139, 32, 4, 225, 181, 181, 81, 176, 194, 202, 202, + 202, 74, 237, 239, 239, 223, 230, 226, 197, 139, 71, 182, 109, 219, 118, 180, 97, 195, 134, 242, 117, 95, + 63, 114, 4, 67, 90, 180, 192, 248, 128, 0, 92, 185, 124, 25, 46, 208, 154, 97, 114, 5, 128, 84, 59, 27, + 177, 232, 21, 119, 19, 91, 133, 87, 210, 55, 110, 225, 190, 148, 35, 188, 216, 226, 0, 33, 17, 203, 182, + 222, 121, 248, 224, 1, 66, 38, 79, 134, 191, 183, 55, 142, 238, 220, 9, 141, 12, 91, 239, 180, 104, 209, + 162, 219, 31, 127, 252, 113, 246, 248, 241, 227, 17, 62, 62, 62, 181, 117, 209, 44, 6, 84, 8, 79, 16, 185, + 144, 192, 34, 8, 14, 124, 97, 5, 173, 184, 210, 0, 80, 127, 242, 201, 39, 62, 231, 207, 159, 223, 187, 107, + 215, 174, 40, 89, 187, 175, 199, 196, 96, 84, 251, 246, 24, 217, 165, 11, 18, 46, 92, 128, 35, 242, 10, 43, + 67, 35, 86, 114, 113, 95, 151, 35, 252, 66, 120, 161, 180, 97, 126, 254, 89, 252, 168, 150, 37, 222, 181, + 222, 249, 191, 244, 116, 140, 31, 48, 0, 129, 173, 91, 227, 194, 169, 83, 38, 154, 149, 81, 216, 116, 236, + 216, 113, 212, 153, 51, 103, 18, 126, 250, 233, 167, 208, 58, 117, 234, 148, 167, 21, 135, 4, 241, 14, 18, + 88, 4, 129, 60, 55, 1, 54, 98, 165, 97, 24, 70, 221, 178, 101, 203, 250, 71, 142, 28, 217, 124, 226, 196, + 137, 179, 62, 62, 62, 125, 160, 189, 15, 202, 142, 43, 58, 247, 245, 161, 237, 218, 33, 38, 42, 10, 14, + 208, 186, 175, 231, 87, 23, 36, 244, 59, 110, 123, 27, 18, 86, 210, 136, 165, 14, 133, 162, 90, 82, 181, + 89, 252, 215, 132, 125, 253, 226, 207, 157, 67, 96, 135, 14, 152, 212, 179, 39, 254, 119, 249, 178, 233, + 38, 102, 32, 182, 182, 182, 174, 195, 134, 13, 251, 38, 41, 41, 41, 113, 238, 220, 185, 95, 186, 186, 186, + 230, 105, 189, 3, 144, 208, 34, 74, 31, 36, 176, 136, 82, 141, 148, 251, 122, 211, 166, 77, 107, 29, 56, + 112, 96, 109, 92, 92, 92, 66, 231, 206, 157, 3, 33, 83, 247, 245, 27, 87, 174, 96, 214, 192, 129, 8, 248, + 248, 99, 28, 141, 140, 132, 141, 206, 125, 157, 95, 80, 205, 141, 152, 8, 165, 169, 216, 154, 32, 161, 168, + 149, 212, 74, 65, 194, 184, 244, 161, 148, 176, 18, 122, 77, 156, 1, 216, 50, 12, 14, 31, 60, 8, 127, 95, + 95, 109, 235, 157, 219, 183, 77, 55, 57, 3, 113, 114, 114, 170, 54, 127, 254, 252, 245, 169, 169, 169, 231, + 38, 78, 156, 216, 219, 214, 214, 150, 219, 122, 71, 175, 24, 222, 188, 35, 37, 8, 211, 64, 2, 139, 40, 149, + 136, 9, 43, 157, 73, 104, 229, 109, 219, 182, 45, 62, 127, 254, 188, 170, 71, 143, 30, 99, 45, 44, 44, 236, + 205, 57, 86, 49, 50, 110, 222, 196, 130, 224, 96, 124, 225, 227, 131, 189, 18, 238, 235, 124, 49, 37, 86, + 3, 196, 95, 29, 152, 159, 73, 168, 185, 235, 160, 228, 180, 241, 207, 7, 247, 188, 9, 21, 192, 11, 173, + 216, 148, 114, 132, 183, 129, 54, 109, 200, 228, 228, 96, 203, 247, 223, 163, 183, 167, 39, 54, 134, 134, + 202, 181, 245, 142, 231, 202, 149, 43, 247, 93, 188, 120, 241, 247, 190, 125, 251, 182, 213, 181, 222, 209, + 8, 173, 56, 52, 243, 80, 9, 162, 72, 33, 129, 69, 148, 42, 68, 132, 21, 24, 134, 81, 87, 171, 86, 173, 220, + 218, 181, 107, 103, 94, 190, 124, 57, 105, 208, 160, 65, 179, 44, 44, 44, 100, 235, 190, 190, 98, 218, 52, + 244, 246, 244, 196, 214, 136, 8, 104, 94, 189, 210, 19, 86, 82, 197, 213, 98, 5, 235, 252, 72, 21, 247, + 131, 129, 238, 130, 5, 67, 239, 34, 227, 109, 252, 136, 150, 148, 32, 230, 166, 22, 115, 91, 239, 60, 121, + 130, 101, 243, 230, 161, 143, 135, 7, 246, 69, 68, 224, 77, 78, 142, 169, 166, 101, 48, 30, 30, 30, 237, + 247, 236, 217, 19, 117, 242, 228, 201, 157, 205, 154, 53, 107, 8, 237, 138, 67, 42, 132, 39, 74, 13, 36, + 176, 136, 82, 129, 148, 176, 114, 115, 115, 115, 8, 11, 11, 27, 151, 154, 154, 170, 26, 59, 118, 236, 183, + 142, 142, 142, 242, 117, 95, 15, 13, 69, 47, 157, 251, 250, 75, 158, 251, 186, 208, 202, 64, 177, 90, 171, + 210, 230, 101, 101, 46, 248, 17, 46, 33, 55, 120, 41, 107, 7, 161, 215, 142, 187, 226, 240, 206, 63, 255, + 96, 70, 112, 48, 6, 54, 107, 134, 232, 67, 135, 76, 52, 43, 163, 176, 80, 42, 149, 1, 231, 207, 159, 143, + 223, 183, 111, 223, 74, 47, 47, 175, 15, 133, 10, 225, 65, 151, 27, 81, 2, 33, 129, 69, 148, 120, 196, 132, + 149, 163, 163, 163, 237, 148, 41, 83, 2, 211, 210, 210, 46, 78, 153, 50, 101, 77, 217, 178, 101, 107, 152, + 115, 156, 98, 188, 204, 206, 198, 47, 171, 86, 161, 119, 163, 70, 88, 54, 111, 30, 158, 62, 122, 4, 87, + 104, 163, 25, 249, 213, 244, 240, 111, 204, 98, 171, 2, 233, 78, 87, 180, 8, 9, 45, 110, 180, 208, 152, + 134, 210, 92, 15, 45, 123, 104, 83, 135, 151, 83, 82, 48, 186, 71, 15, 4, 119, 232, 128, 75, 241, 241, 38, + 154, 149, 225, 40, 20, 10, 135, 222, 189, 123, 79, 60, 127, 254, 188, 106, 229, 202, 149, 51, 170, 84, 169, + 34, 216, 122, 7, 116, 233, 17, 37, 8, 18, 88, 68, 137, 133, 103, 185, 144, 43, 172, 28, 28, 28, 44, 198, + 142, 29, 219, 247, 202, 149, 43, 167, 195, 194, 194, 54, 187, 186, 186, 202, 214, 125, 253, 215, 31, 127, + 68, 95, 157, 251, 250, 125, 1, 247, 245, 252, 106, 171, 196, 108, 23, 248, 194, 138, 138, 215, 77, 3, 247, + 28, 243, 5, 46, 63, 154, 101, 200, 107, 204, 238, 231, 4, 237, 170, 195, 232, 147, 39, 49, 176, 101, 75, + 204, 30, 52, 8, 127, 255, 239, 127, 38, 154, 149, 225, 216, 217, 217, 85, 156, 56, 113, 226, 146, 43, 87, + 174, 92, 156, 50, 101, 202, 80, 123, 123, 123, 43, 129, 21, 135, 116, 41, 18, 37, 2, 234, 69, 72, 20, 10, + 114, 184, 142, 88, 120, 17, 43, 64, 123, 157, 171, 237, 236, 236, 44, 6, 15, 30, 220, 113, 230, 204, 153, + 115, 106, 215, 174, 45, 91, 131, 80, 141, 70, 131, 63, 246, 236, 193, 15, 11, 23, 34, 37, 53, 21, 54, 208, + 122, 35, 241, 235, 119, 196, 86, 169, 241, 111, 220, 252, 104, 73, 158, 147, 99, 138, 73, 17, 121, 96, 4, + 190, 114, 251, 28, 10, 109, 252, 222, 134, 220, 30, 135, 236, 215, 55, 208, 246, 56, 116, 113, 112, 64, + 255, 49, 99, 48, 116, 218, 52, 148, 171, 88, 209, 20, 83, 50, 154, 27, 55, 110, 196, 47, 89, 178, 100, 254, + 182, 109, 219, 142, 189, 126, 253, 154, 17, 234, 113, 136, 188, 237, 32, 9, 66, 20, 234, 69, 72, 16, 69, + 128, 64, 196, 74, 193, 48, 140, 70, 161, 80, 168, 187, 118, 237, 218, 246, 236, 217, 179, 71, 34, 34, 34, + 142, 202, 85, 92, 49, 12, 131, 211, 71, 142, 96, 104, 139, 22, 152, 16, 16, 128, 43, 169, 169, 112, 134, + 54, 50, 33, 21, 205, 48, 164, 181, 13, 223, 121, 157, 194, 4, 230, 71, 232, 181, 144, 90, 117, 40, 20, 213, + 226, 46, 92, 224, 23, 194, 191, 201, 206, 198, 119, 97, 97, 232, 235, 225, 129, 109, 43, 86, 200, 178, 245, + 78, 157, 58, 117, 62, 222, 180, 105, 211, 145, 184, 184, 184, 67, 29, 59, 118, 108, 170, 139, 102, 169, + 161, 191, 214, 66, 1, 93, 48, 192, 204, 109, 179, 8, 194, 40, 72, 96, 17, 197, 30, 17, 147, 80, 53, 0, 117, + 167, 78, 157, 124, 226, 226, 226, 246, 70, 70, 70, 158, 242, 246, 246, 150, 173, 251, 186, 42, 38, 6, 193, + 159, 124, 130, 81, 93, 186, 64, 197, 113, 95, 23, 243, 74, 18, 91, 101, 102, 168, 135, 21, 9, 43, 249, 32, + 246, 250, 72, 185, 193, 179, 214, 13, 98, 215, 131, 37, 222, 9, 173, 71, 15, 30, 32, 116, 202, 20, 244, + 107, 220, 24, 71, 118, 236, 128, 70, 173, 54, 221, 228, 12, 164, 105, 211, 166, 93, 143, 31, 63, 126, 250, + 143, 63, 254, 248, 225, 227, 143, 63, 254, 72, 39, 180, 244, 122, 28, 210, 138, 67, 162, 184, 65, 2, 139, + 40, 182, 8, 180, 181, 177, 96, 219, 218, 40, 149, 202, 6, 81, 81, 81, 91, 142, 29, 59, 118, 182, 101, 203, + 150, 178, 117, 95, 191, 154, 152, 136, 137, 221, 187, 35, 176, 93, 59, 196, 241, 220, 215, 185, 226, 73, + 40, 82, 37, 84, 139, 195, 23, 88, 84, 216, 82, 124, 16, 242, 209, 98, 133, 22, 63, 170, 37, 100, 237, 32, + 22, 217, 42, 3, 173, 208, 186, 241, 191, 255, 97, 210, 192, 129, 8, 108, 221, 26, 241, 39, 79, 154, 110, + 98, 134, 99, 211, 161, 67, 135, 17, 113, 113, 113, 23, 55, 111, 222, 188, 240, 63, 255, 249, 79, 5, 106, + 189, 67, 20, 103, 72, 96, 17, 197, 14, 1, 203, 5, 5, 107, 18, 234, 225, 225, 81, 107, 231, 206, 157, 107, + 79, 158, 60, 121, 81, 169, 84, 14, 133, 76, 221, 215, 255, 188, 122, 21, 115, 6, 14, 68, 255, 102, 205, + 112, 76, 231, 190, 94, 22, 226, 203, 244, 133, 54, 238, 50, 127, 67, 205, 65, 9, 249, 99, 136, 97, 169, + 148, 181, 131, 88, 202, 216, 17, 64, 89, 0, 9, 231, 207, 99, 120, 135, 14, 152, 216, 163, 7, 210, 47, 93, + 50, 221, 196, 12, 196, 218, 218, 218, 37, 48, 48, 112, 78, 114, 114, 178, 106, 254, 252, 249, 99, 93, 93, + 93, 203, 136, 9, 45, 179, 14, 148, 32, 242, 129, 4, 22, 81, 108, 144, 114, 95, 175, 95, 191, 126, 229, 159, + 127, 254, 249, 219, 196, 196, 68, 85, 64, 64, 128, 124, 221, 215, 255, 254, 27, 139, 70, 143, 134, 127, + 147, 38, 216, 179, 99, 7, 44, 212, 106, 56, 67, 223, 125, 221, 152, 149, 129, 66, 233, 64, 90, 243, 94, 50, + 48, 196, 168, 84, 170, 145, 180, 88, 93, 158, 19, 180, 81, 173, 163, 135, 14, 33, 160, 105, 83, 44, 12, 14, + 198, 189, 91, 183, 76, 52, 43, 195, 177, 183, 183, 175, 58, 119, 238, 220, 181, 87, 175, 94, 61, 55, 121, + 242, 228, 190, 14, 14, 14, 22, 252, 21, 135, 92, 204, 61, 94, 130, 224, 67, 2, 139, 144, 61, 82, 194, 170, + 106, 213, 170, 229, 54, 109, 218, 52, 43, 49, 49, 49, 105, 240, 224, 193, 51, 173, 172, 172, 100, 233, 190, + 254, 232, 254, 125, 172, 154, 62, 29, 125, 26, 53, 194, 214, 141, 27, 243, 184, 175, 11, 121, 87, 229, 39, + 170, 196, 188, 172, 40, 106, 85, 114, 16, 43, 130, 23, 139, 102, 137, 21, 193, 11, 213, 236, 185, 0, 64, + 78, 14, 182, 70, 68, 160, 143, 135, 7, 190, 15, 9, 193, 243, 167, 79, 77, 54, 55, 67, 169, 84, 169, 146, + 71, 120, 120, 248, 158, 248, 248, 248, 223, 253, 253, 253, 253, 44, 45, 45, 213, 188, 30, 135, 0, 40, 162, + 69, 200, 15, 18, 88, 132, 108, 145, 114, 95, 175, 88, 177, 162, 99, 104, 104, 232, 184, 148, 148, 20, 213, + 200, 145, 35, 23, 219, 217, 217, 201, 214, 125, 61, 98, 193, 2, 244, 110, 216, 16, 235, 151, 47, 199, 171, + 172, 172, 92, 97, 37, 22, 109, 16, 243, 58, 202, 207, 199, 10, 32, 81, 85, 146, 225, 27, 193, 114, 133, 22, + 235, 163, 37, 100, 84, 154, 95, 143, 195, 114, 0, 178, 159, 62, 69, 248, 252, 249, 232, 235, 225, 129, 189, + 17, 17, 120, 243, 250, 181, 169, 166, 101, 48, 13, 27, 54, 108, 183, 107, 215, 174, 147, 177, 177, 177, + 255, 109, 209, 162, 133, 7, 168, 245, 14, 33, 115, 72, 96, 17, 178, 68, 76, 88, 149, 43, 87, 206, 246, 235, + 175, 191, 14, 76, 75, 75, 75, 248, 230, 155, 111, 214, 148, 43, 87, 78, 150, 238, 235, 47, 178, 178, 176, + 125, 245, 106, 244, 105, 212, 8, 203, 231, 206, 69, 38, 199, 125, 93, 170, 87, 160, 208, 178, 123, 169, + 168, 21, 69, 172, 74, 23, 98, 214, 14, 220, 26, 60, 169, 218, 44, 49, 91, 15, 59, 104, 11, 225, 51, 110, + 221, 194, 108, 182, 245, 206, 193, 131, 166, 155, 152, 225, 88, 182, 108, 217, 178, 223, 233, 211, 167, + 207, 239, 223, 191, 127, 181, 151, 151, 87, 85, 42, 132, 39, 228, 10, 25, 141, 18, 133, 66, 97, 92, 71, + 188, 15, 196, 220, 226, 117, 0, 26, 27, 27, 27, 171, 49, 99, 198, 244, 154, 57, 115, 230, 204, 202, 149, + 43, 55, 121, 239, 131, 21, 17, 111, 114, 114, 240, 219, 47, 191, 224, 167, 197, 139, 113, 237, 198, 13, + 148, 129, 246, 230, 197, 143, 54, 8, 153, 131, 26, 98, 20, 74, 38, 161, 4, 139, 148, 81, 41, 223, 172, 148, + 107, 70, 154, 159, 81, 169, 26, 192, 11, 221, 247, 109, 218, 181, 195, 87, 139, 22, 193, 179, 69, 11, 19, + 204, 200, 120, 114, 114, 114, 254, 221, 176, 97, 195, 138, 176, 176, 176, 239, 111, 223, 190, 157, 9, 192, + 66, 247, 57, 194, 53, 42, 5, 83, 8, 31, 80, 116, 111, 42, 30, 200, 201, 104, 148, 4, 22, 81, 40, 188, 239, + 117, 196, 19, 87, 22, 186, 231, 83, 219, 216, 216, 88, 244, 235, 215, 175, 227, 172, 89, 179, 190, 174, 95, + 191, 126, 171, 247, 58, 72, 17, 162, 209, 104, 112, 98, 239, 94, 108, 90, 176, 0, 151, 82, 83, 97, 11, 173, + 176, 226, 10, 38, 33, 215, 117, 254, 234, 63, 190, 168, 18, 75, 1, 230, 247, 46, 233, 17, 18, 130, 238, + 243, 230, 189, 215, 156, 174, 199, 196, 224, 69, 102, 38, 110, 37, 39, 35, 233, 192, 1, 252, 147, 156, 156, + 239, 223, 188, 207, 113, 111, 165, 164, 228, 30, 239, 90, 116, 52, 146, 14, 28, 144, 220, 127, 236, 129, 3, + 240, 238, 209, 67, 240, 121, 66, 26, 55, 54, 232, 152, 173, 2, 3, 49, 124, 243, 102, 193, 223, 37, 29, 60, + 136, 117, 61, 123, 26, 244, 60, 159, 78, 156, 136, 128, 149, 43, 5, 127, 55, 194, 4, 159, 105, 124, 177, + 165, 65, 193, 132, 22, 255, 247, 217, 0, 172, 45, 44, 208, 165, 95, 63, 4, 135, 132, 160, 134, 187, 123, + 145, 207, 165, 32, 60, 125, 250, 244, 198, 210, 165, 75, 23, 173, 94, 189, 122, 199, 139, 23, 47, 94, 3, + 176, 212, 125, 164, 104, 56, 187, 189, 151, 206, 162, 123, 83, 241, 64, 78, 2, 139, 82, 132, 132, 89, 225, + 187, 175, 67, 43, 174, 212, 86, 86, 86, 234, 128, 128, 128, 182, 23, 47, 94, 60, 242, 243, 207, 63, 31, + 149, 179, 184, 58, 125, 228, 8, 2, 91, 182, 196, 132, 126, 253, 112, 149, 227, 190, 158, 159, 143, 149, 80, + 42, 80, 204, 203, 202, 28, 169, 192, 186, 126, 126, 240, 238, 209, 3, 221, 231, 205, 195, 188, 164, 36, 76, + 143, 142, 198, 7, 53, 107, 22, 217, 241, 170, 121, 121, 161, 174, 159, 31, 58, 76, 152, 128, 177, 191, 254, + 138, 101, 55, 111, 162, 85, 96, 160, 232, 254, 98, 2, 172, 154, 151, 23, 236, 93, 92, 12, 58, 102, 61, 165, + 82, 244, 119, 66, 226, 77, 116, 95, 17, 33, 150, 100, 162, 52, 155, 88, 125, 150, 148, 181, 131, 88, 253, + 31, 247, 231, 178, 0, 172, 53, 26, 236, 223, 185, 19, 254, 141, 27, 35, 124, 242, 100, 60, 126, 240, 192, + 36, 115, 50, 6, 103, 103, 231, 58, 139, 23, 47, 254, 41, 53, 53, 53, 118, 228, 200, 145, 159, 219, 217, + 217, 105, 116, 102, 195, 122, 111, 33, 74, 27, 18, 166, 132, 4, 22, 97, 22, 196, 220, 215, 25, 134, 81, 43, + 149, 74, 159, 115, 231, 206, 237, 219, 229, 45, 146, 167, 0, 0, 32, 0, 73, 68, 65, 84, 185, 115, 231, 41, + 79, 79, 79, 217, 186, 175, 39, 198, 198, 34, 248, 147, 79, 16, 212, 165, 11, 84, 241, 241, 112, 130, 214, + 107, 72, 170, 200, 88, 170, 181, 141, 92, 132, 149, 24, 117, 253, 252, 16, 146, 156, 140, 234, 6, 70, 135, + 222, 151, 242, 53, 106, 96, 248, 230, 205, 152, 30, 29, 45, 40, 152, 164, 34, 92, 98, 130, 199, 216, 253, + 234, 74, 8, 48, 22, 123, 23, 23, 212, 245, 243, 19, 252, 93, 126, 81, 184, 194, 132, 31, 233, 148, 178, + 117, 224, 139, 44, 169, 127, 0, 108, 160, 93, 113, 248, 230, 229, 75, 108, 92, 185, 18, 125, 27, 53, 194, + 207, 203, 151, 203, 178, 245, 78, 173, 90, 181, 154, 109, 218, 180, 233, 183, 179, 103, 207, 70, 118, 234, + 212, 169, 25, 199, 17, 62, 247, 244, 80, 125, 22, 97, 42, 72, 96, 17, 38, 69, 100, 101, 160, 6, 128, 186, + 85, 171, 86, 13, 142, 30, 61, 186, 37, 42, 42, 234, 172, 175, 175, 111, 111, 200, 212, 125, 253, 138, 74, + 133, 73, 221, 187, 35, 80, 169, 68, 236, 169, 83, 185, 238, 235, 66, 145, 1, 161, 101, 242, 98, 62, 86, + 114, 21, 86, 92, 202, 56, 59, 99, 248, 150, 45, 38, 61, 102, 93, 63, 63, 65, 145, 245, 34, 51, 83, 52, 66, + 36, 21, 153, 98, 169, 222, 184, 49, 202, 56, 59, 75, 238, 211, 196, 0, 161, 38, 37, 210, 76, 41, 176, 88, + 248, 66, 139, 91, 8, 207, 21, 90, 92, 87, 120, 67, 60, 180, 108, 161, 93, 113, 248, 248, 223, 127, 177, + 112, 250, 116, 244, 243, 242, 194, 145, 237, 219, 101, 217, 122, 199, 219, 219, 187, 203, 177, 99, 199, 78, + 159, 60, 121, 242, 71, 111, 111, 111, 182, 245, 14, 173, 56, 36, 76, 10, 9, 44, 194, 36, 72, 121, 89, 53, + 109, 218, 180, 214, 161, 67, 135, 214, 198, 198, 198, 94, 252, 236, 179, 207, 100, 235, 190, 254, 215, 213, + 171, 248, 122, 208, 32, 12, 252, 248, 99, 28, 139, 140, 132, 45, 195, 232, 89, 46, 176, 95, 109, 161, 191, + 98, 43, 63, 145, 197, 110, 249, 21, 183, 27, 179, 21, 37, 213, 188, 188, 208, 58, 48, 208, 164, 199, 173, + 230, 229, 133, 30, 33, 33, 121, 142, 151, 44, 34, 96, 188, 123, 246, 204, 247, 28, 25, 18, 229, 170, 171, + 84, 230, 251, 60, 98, 98, 46, 249, 224, 65, 188, 204, 204, 44, 240, 107, 248, 190, 155, 208, 245, 196, 21, + 89, 98, 246, 32, 182, 2, 27, 251, 123, 43, 0, 246, 208, 174, 56, 252, 235, 255, 254, 15, 83, 6, 13, 194, + 176, 86, 173, 16, 127, 226, 68, 190, 231, 210, 12, 88, 183, 111, 223, 126, 120, 124, 124, 124, 194, 150, + 45, 91, 22, 127, 244, 209, 71, 82, 173, 119, 204, 58, 80, 162, 100, 98, 101, 238, 1, 16, 37, 27, 145, 149, + 129, 26, 0, 154, 90, 181, 106, 85, 153, 55, 111, 222, 184, 33, 67, 134, 140, 86, 40, 20, 134, 21, 205, 152, + 129, 140, 191, 255, 198, 150, 111, 191, 197, 129, 173, 91, 241, 236, 213, 43, 56, 65, 155, 50, 145, 90, 21, + 104, 76, 1, 59, 4, 190, 190, 47, 98, 207, 115, 43, 37, 5, 187, 38, 78, 204, 247, 239, 189, 123, 246, 68, + 203, 192, 64, 209, 8, 79, 171, 192, 64, 156, 21, 136, 100, 21, 228, 184, 246, 46, 46, 168, 214, 184, 49, + 90, 6, 6, 162, 124, 13, 113, 215, 141, 14, 19, 38, 224, 236, 150, 45, 184, 197, 41, 182, 191, 30, 29, 45, + 184, 111, 25, 103, 103, 212, 83, 42, 69, 127, 15, 24, 22, 229, 170, 230, 229, 133, 15, 106, 214, 196, 163, + 155, 55, 69, 247, 17, 173, 191, 58, 112, 64, 22, 209, 71, 118, 12, 12, 239, 103, 182, 147, 50, 183, 16, + 222, 18, 218, 226, 118, 246, 171, 90, 228, 103, 11, 206, 99, 170, 248, 120, 140, 252, 244, 83, 116, 232, + 218, 21, 163, 23, 44, 64, 93, 19, 165, 144, 13, 197, 218, 218, 218, 121, 232, 208, 161, 179, 250, 245, 235, + 55, 100, 229, 202, 149, 75, 195, 195, 195, 55, 63, 122, 244, 40, 11, 218, 66, 120, 5, 116, 167, 70, 161, + 80, 20, 202, 106, 67, 130, 96, 33, 129, 69, 20, 9, 82, 194, 170, 122, 245, 234, 229, 167, 79, 159, 30, 52, + 108, 216, 176, 9, 246, 246, 246, 178, 52, 8, 5, 128, 71, 247, 238, 225, 151, 21, 43, 176, 123, 195, 6, 60, + 202, 202, 130, 35, 180, 255, 185, 243, 163, 1, 172, 201, 163, 152, 221, 2, 191, 149, 141, 88, 212, 199, 20, + 55, 227, 151, 153, 153, 146, 162, 131, 229, 186, 110, 21, 223, 212, 168, 40, 193, 223, 187, 139, 212, 28, + 21, 244, 184, 73, 7, 14, 224, 80, 72, 8, 58, 76, 156, 136, 126, 34, 171, 241, 0, 160, 195, 196, 137, 216, + 204, 41, 124, 127, 116, 243, 38, 110, 165, 164, 160, 154, 151, 87, 158, 125, 189, 123, 246, 20, 61, 166, + 189, 139, 139, 193, 115, 168, 171, 84, 10, 138, 73, 246, 119, 98, 34, 84, 44, 186, 102, 46, 248, 215, 23, + 43, 174, 24, 228, 141, 122, 169, 33, 28, 1, 179, 16, 216, 167, 44, 128, 183, 0, 142, 31, 62, 140, 216, 227, + 199, 209, 115, 232, 80, 140, 252, 250, 107, 184, 73, 136, 101, 115, 96, 103, 103, 247, 225, 172, 89, 179, + 214, 140, 24, 49, 34, 120, 201, 146, 37, 161, 235, 215, 175, 223, 159, 147, 147, 243, 22, 28, 161, 197, + 253, 216, 34, 177, 69, 188, 47, 148, 34, 36, 10, 21, 41, 247, 245, 42, 85, 170, 56, 134, 135, 135, 143, 75, + 77, 77, 85, 125, 245, 213, 87, 139, 229, 42, 174, 158, 63, 121, 130, 77, 161, 161, 232, 235, 225, 129, 239, + 120, 238, 235, 66, 53, 43, 182, 2, 143, 113, 87, 7, 26, 226, 190, 46, 135, 72, 7, 159, 235, 209, 209, 120, + 244, 247, 223, 38, 61, 230, 137, 85, 171, 16, 57, 127, 190, 232, 239, 133, 162, 69, 98, 226, 167, 177, 68, + 10, 208, 144, 226, 117, 67, 246, 21, 139, 94, 37, 31, 60, 136, 23, 153, 153, 6, 31, 195, 148, 8, 213, 103, + 229, 183, 218, 80, 42, 229, 205, 238, 231, 12, 64, 241, 230, 13, 182, 255, 240, 3, 190, 240, 244, 196, 134, + 185, 115, 241, 236, 201, 19, 83, 77, 203, 96, 42, 86, 172, 216, 112, 197, 138, 21, 187, 84, 42, 213, 31, + 254, 254, 254, 237, 44, 44, 44, 212, 186, 21, 135, 122, 111, 69, 202, 27, 18, 239, 11, 9, 44, 162, 80, 144, + 18, 86, 101, 203, 150, 181, 157, 60, 121, 114, 224, 165, 75, 151, 46, 78, 158, 60, 121, 141, 147, 147, 147, + 188, 254, 181, 213, 241, 34, 43, 11, 59, 86, 175, 70, 223, 70, 141, 16, 54, 111, 30, 50, 31, 62, 20, 116, + 95, 151, 114, 197, 22, 43, 100, 55, 36, 130, 37, 71, 164, 82, 99, 69, 197, 137, 85, 171, 240, 82, 164, 39, + 94, 25, 103, 103, 84, 227, 165, 160, 196, 10, 201, 203, 215, 168, 129, 242, 53, 107, 10, 254, 78, 74, 124, + 241, 145, 170, 213, 18, 123, 30, 67, 162, 132, 230, 68, 170, 102, 75, 72, 100, 9, 93, 255, 66, 215, 187, + 45, 180, 81, 222, 23, 207, 158, 97, 213, 130, 5, 240, 247, 240, 192, 158, 13, 27, 100, 217, 122, 167, 81, + 163, 70, 202, 93, 187, 118, 157, 56, 123, 246, 236, 238, 214, 173, 91, 123, 8, 20, 194, 83, 35, 105, 226, + 189, 32, 129, 69, 20, 6, 122, 194, 10, 218, 116, 160, 218, 193, 193, 193, 98, 220, 184, 113, 95, 164, 166, + 166, 158, 14, 15, 15, 223, 92, 190, 124, 249, 186, 102, 28, 163, 40, 111, 115, 114, 112, 224, 199, 31, 17, + 224, 229, 133, 208, 137, 19, 113, 63, 35, 3, 174, 0, 202, 64, 252, 63, 120, 177, 27, 12, 95, 80, 21, 247, + 182, 54, 98, 2, 69, 76, 0, 21, 6, 47, 50, 51, 37, 87, 223, 241, 35, 74, 108, 154, 80, 8, 49, 113, 36, 20, + 149, 122, 249, 244, 41, 206, 110, 221, 154, 231, 113, 33, 81, 7, 104, 207, 141, 88, 205, 152, 57, 86, 15, + 22, 4, 177, 2, 121, 126, 186, 219, 208, 136, 22, 187, 31, 219, 122, 231, 222, 157, 59, 248, 230, 203, 47, + 49, 200, 215, 23, 81, 7, 14, 0, 242, 203, 186, 89, 124, 252, 241, 199, 95, 196, 198, 198, 158, 63, 120, + 240, 224, 154, 70, 141, 26, 85, 229, 8, 173, 220, 183, 42, 199, 171, 143, 32, 12, 134, 4, 22, 81, 80, 242, + 124, 46, 179, 17, 43, 27, 27, 27, 102, 212, 168, 81, 159, 165, 164, 164, 68, 173, 89, 179, 102, 119, 181, + 106, 213, 100, 217, 218, 70, 163, 86, 227, 143, 221, 187, 49, 192, 199, 7, 51, 71, 142, 196, 223, 127, 254, + 9, 23, 104, 87, 73, 241, 255, 115, 55, 36, 82, 37, 100, 189, 80, 28, 82, 129, 98, 120, 247, 236, 41, 42, + 32, 138, 58, 66, 35, 245, 252, 66, 158, 88, 98, 105, 66, 33, 129, 37, 38, 140, 174, 71, 71, 139, 30, 87, + 72, 144, 137, 137, 183, 91, 41, 41, 102, 137, 252, 189, 15, 252, 72, 22, 63, 162, 37, 230, 159, 149, 159, + 29, 137, 61, 180, 11, 66, 174, 164, 166, 98, 108, 175, 94, 8, 254, 228, 19, 164, 156, 57, 99, 186, 137, 25, + 136, 66, 161, 176, 239, 222, 189, 251, 184, 248, 248, 248, 164, 213, 171, 87, 207, 169, 90, 181, 170, 139, + 208, 138, 67, 20, 191, 183, 49, 97, 70, 72, 96, 17, 5, 65, 176, 128, 93, 161, 80, 104, 186, 117, 235, 214, + 230, 204, 153, 51, 191, 69, 68, 68, 28, 173, 83, 167, 78, 107, 115, 13, 48, 63, 78, 31, 57, 130, 97, 173, + 90, 97, 66, 191, 126, 184, 198, 113, 95, 151, 50, 96, 52, 196, 36, 84, 238, 169, 192, 50, 46, 46, 168, 171, + 84, 74, 110, 222, 61, 123, 34, 96, 213, 42, 124, 249, 235, 175, 162, 207, 83, 212, 17, 154, 91, 18, 109, + 121, 132, 196, 142, 216, 120, 220, 253, 252, 242, 8, 50, 169, 85, 127, 82, 182, 15, 134, 140, 3, 16, 23, + 123, 197, 1, 41, 171, 7, 254, 10, 89, 254, 63, 31, 82, 205, 164, 157, 160, 125, 127, 157, 142, 138, 194, + 208, 182, 109, 49, 59, 32, 0, 55, 175, 93, 51, 221, 196, 12, 196, 222, 222, 190, 252, 248, 241, 227, 23, + 166, 165, 165, 37, 204, 155, 55, 111, 184, 189, 189, 189, 13, 167, 62, 75, 104, 225, 47, 65, 136, 66, 171, + 8, 9, 99, 16, 18, 86, 106, 133, 66, 129, 207, 62, 251, 172, 201, 220, 185, 115, 103, 183, 104, 209, 162, + 39, 100, 106, 16, 10, 0, 137, 113, 113, 136, 152, 55, 15, 167, 117, 171, 227, 156, 32, 188, 226, 79, 104, + 85, 160, 144, 237, 2, 255, 102, 4, 200, 251, 19, 184, 154, 151, 151, 232, 202, 64, 67, 121, 249, 244, 105, + 145, 175, 144, 147, 18, 88, 66, 72, 173, 38, 108, 220, 179, 167, 158, 232, 17, 19, 70, 201, 7, 14, 104, + 123, 33, 10, 60, 15, 43, 212, 216, 194, 117, 123, 23, 23, 52, 22, 105, 165, 83, 92, 210, 131, 82, 240, 175, + 93, 214, 203, 128, 189, 206, 53, 188, 77, 129, 119, 182, 15, 66, 43, 17, 89, 133, 82, 22, 192, 91, 141, 6, + 191, 238, 218, 133, 147, 135, 14, 193, 63, 56, 24, 67, 103, 204, 192, 7, 149, 43, 23, 253, 164, 140, 160, + 108, 217, 178, 181, 67, 66, 66, 126, 28, 62, 124, 248, 152, 197, 139, 23, 135, 108, 222, 188, 249, 104, 78, + 78, 142, 6, 239, 122, 28, 114, 145, 93, 222, 147, 144, 7, 20, 193, 34, 12, 129, 159, 233, 202, 53, 9, 109, + 219, 182, 109, 131, 147, 39, 79, 110, 62, 122, 244, 232, 185, 22, 45, 90, 244, 129, 76, 197, 213, 85, 149, + 10, 147, 187, 119, 199, 48, 63, 63, 196, 69, 69, 193, 1, 186, 62, 107, 200, 27, 173, 178, 229, 125, 207, + 254, 44, 213, 218, 70, 204, 235, 202, 92, 91, 81, 178, 57, 48, 80, 212, 64, 83, 138, 194, 156, 131, 208, + 254, 233, 34, 233, 189, 122, 60, 179, 80, 33, 97, 116, 59, 37, 37, 119, 78, 98, 226, 145, 107, 58, 42, 38, + 210, 110, 167, 164, 224, 241, 205, 155, 102, 125, 237, 11, 107, 147, 50, 42, 229, 167, 12, 133, 162, 88, + 98, 117, 139, 108, 33, 188, 250, 229, 75, 108, 90, 181, 10, 254, 30, 30, 216, 186, 116, 41, 94, 102, 103, + 11, 158, 83, 115, 82, 189, 122, 117, 223, 239, 191, 255, 254, 240, 233, 211, 167, 15, 119, 238, 220, 249, + 99, 0, 121, 90, 239, 240, 190, 39, 136, 92, 72, 96, 17, 82, 136, 10, 43, 79, 79, 207, 26, 255, 253, 239, + 127, 215, 158, 58, 117, 234, 66, 187, 118, 237, 2, 33, 103, 247, 245, 129, 3, 49, 168, 121, 115, 28, 143, + 140, 132, 157, 206, 125, 157, 95, 59, 34, 228, 94, 45, 85, 204, 206, 109, 55, 34, 102, 193, 96, 238, 173, + 176, 121, 249, 244, 41, 194, 219, 181, 67, 138, 206, 64, 211, 216, 227, 22, 181, 192, 58, 39, 97, 215, 144, + 159, 48, 74, 230, 204, 41, 197, 0, 129, 37, 150, 102, 60, 187, 101, 139, 217, 95, 247, 162, 18, 90, 252, + 72, 47, 191, 246, 80, 172, 0, 158, 223, 217, 128, 125, 15, 217, 65, 219, 122, 39, 243, 225, 67, 44, 153, + 57, 19, 1, 158, 158, 248, 109, 219, 54, 168, 223, 190, 21, 60, 183, 230, 164, 105, 211, 166, 157, 143, 28, + 57, 18, 23, 29, 29, 189, 185, 89, 179, 102, 255, 17, 106, 189, 3, 18, 90, 4, 15, 18, 88, 197, 0, 93, 241, + 184, 201, 54, 72, 8, 171, 122, 245, 234, 85, 222, 182, 109, 219, 226, 132, 132, 132, 164, 126, 253, 250, + 141, 181, 180, 180, 116, 48, 219, 137, 145, 32, 227, 230, 77, 44, 30, 61, 26, 1, 77, 154, 96, 223, 142, 29, + 176, 124, 251, 22, 206, 48, 110, 201, 57, 223, 199, 42, 63, 33, 85, 146, 121, 249, 244, 41, 194, 149, 74, + 209, 40, 81, 97, 35, 182, 122, 81, 138, 91, 201, 201, 130, 190, 93, 101, 156, 157, 225, 174, 19, 86, 98, + 182, 10, 220, 168, 213, 173, 228, 100, 193, 85, 146, 220, 191, 53, 228, 121, 74, 34, 66, 226, 75, 170, 145, + 180, 33, 245, 89, 101, 160, 45, 132, 255, 251, 207, 63, 49, 109, 200, 16, 12, 111, 217, 18, 231, 127, 255, + 221, 132, 179, 50, 24, 107, 63, 63, 191, 192, 184, 184, 184, 132, 109, 219, 182, 125, 235, 238, 238, 94, + 81, 170, 16, 222, 212, 159, 219, 38, 184, 47, 16, 70, 66, 2, 139, 200, 69, 202, 203, 234, 195, 15, 63, 116, + 141, 136, 136, 152, 149, 148, 148, 148, 56, 104, 208, 160, 89, 214, 214, 214, 178, 108, 109, 243, 232, 222, + 61, 172, 158, 62, 29, 254, 30, 30, 216, 182, 113, 35, 52, 175, 94, 193, 21, 121, 77, 66, 165, 82, 24, 236, + 198, 111, 140, 43, 38, 174, 74, 3, 101, 156, 157, 241, 117, 82, 18, 90, 114, 92, 212, 139, 18, 33, 91, 4, + 22, 169, 250, 44, 49, 129, 195, 10, 34, 49, 123, 6, 254, 115, 10, 61, 15, 235, 171, 85, 77, 164, 73, 244, + 163, 191, 255, 46, 118, 171, 7, 11, 2, 95, 96, 41, 160, 95, 159, 200, 190, 95, 132, 254, 153, 145, 90, 44, + 194, 166, 237, 19, 47, 94, 68, 80, 167, 78, 152, 216, 181, 43, 174, 37, 37, 153, 110, 98, 6, 98, 99, 99, + 83, 118, 208, 160, 65, 51, 19, 19, 19, 85, 161, 161, 161, 227, 43, 84, 168, 96, 47, 36, 180, 200, 67, 139, + 32, 129, 69, 0, 0, 196, 132, 85, 197, 138, 21, 29, 22, 46, 92, 56, 246, 210, 165, 75, 73, 163, 70, 141, 90, + 108, 103, 103, 39, 175, 106, 84, 29, 207, 116, 238, 235, 95, 120, 120, 96, 131, 206, 125, 157, 47, 172, + 242, 19, 85, 252, 218, 170, 146, 40, 172, 210, 99, 98, 16, 172, 80, 8, 110, 225, 237, 218, 97, 247, 164, + 73, 146, 238, 237, 67, 55, 111, 54, 202, 164, 179, 160, 184, 139, 164, 242, 0, 109, 219, 29, 49, 164, 210, + 132, 229, 107, 214, 68, 85, 129, 34, 120, 33, 49, 37, 22, 169, 107, 220, 179, 39, 90, 136, 136, 204, 146, + 30, 189, 226, 195, 127, 47, 112, 223, 39, 220, 52, 186, 161, 239, 63, 118, 115, 130, 54, 170, 245, 199, + 111, 191, 97, 208, 199, 31, 99, 193, 136, 17, 184, 107, 226, 142, 2, 134, 224, 224, 224, 240, 225, 55, 223, + 124, 179, 58, 53, 53, 53, 126, 250, 244, 233, 1, 182, 182, 182, 150, 58, 161, 165, 119, 106, 72, 100, 149, + 94, 72, 96, 149, 98, 20, 28, 192, 19, 86, 174, 174, 174, 54, 95, 127, 253, 117, 96, 90, 90, 218, 133, 57, + 115, 230, 172, 45, 87, 174, 92, 117, 115, 143, 87, 136, 23, 89, 89, 216, 185, 106, 21, 252, 27, 53, 194, + 138, 121, 243, 240, 244, 225, 67, 148, 131, 182, 190, 195, 10, 226, 237, 61, 140, 241, 178, 42, 9, 194, + 202, 16, 210, 163, 163, 113, 114, 213, 42, 44, 108, 220, 24, 231, 4, 12, 55, 89, 252, 87, 173, 42, 242, + 177, 72, 137, 56, 41, 143, 44, 177, 52, 97, 249, 26, 53, 68, 163, 111, 66, 98, 74, 170, 208, 93, 172, 142, + 75, 76, 220, 149, 116, 184, 145, 44, 126, 65, 188, 88, 157, 86, 126, 29, 17, 108, 160, 107, 168, 254, 230, + 13, 118, 252, 244, 19, 252, 61, 61, 241, 221, 215, 95, 227, 217, 227, 199, 38, 156, 153, 97, 84, 172, 88, + 177, 193, 210, 165, 75, 119, 38, 38, 38, 158, 232, 223, 191, 127, 123, 43, 43, 43, 110, 33, 188, 5, 64, + 142, 240, 165, 21, 18, 88, 165, 20, 177, 136, 149, 181, 181, 181, 197, 87, 95, 125, 213, 247, 202, 149, 43, + 103, 23, 44, 88, 176, 249, 131, 15, 62, 168, 103, 206, 113, 138, 241, 38, 39, 7, 7, 127, 252, 17, 3, 188, + 188, 16, 58, 105, 18, 30, 112, 220, 215, 197, 254, 99, 182, 229, 125, 21, 19, 90, 66, 226, 74, 78, 197, + 235, 134, 108, 82, 228, 247, 183, 47, 51, 51, 177, 103, 226, 68, 60, 22, 137, 26, 148, 175, 81, 3, 222, + 156, 194, 241, 194, 58, 46, 187, 181, 12, 12, 20, 53, 56, 5, 128, 59, 201, 201, 146, 127, 47, 86, 164, 254, + 201, 196, 137, 130, 143, 11, 21, 237, 191, 204, 204, 196, 109, 1, 119, 120, 119, 165, 82, 48, 10, 246, 248, + 239, 191, 113, 59, 159, 113, 149, 244, 77, 200, 160, 84, 200, 5, 94, 204, 95, 78, 168, 16, 222, 22, 218, + 66, 248, 151, 207, 158, 97, 237, 162, 69, 240, 247, 240, 192, 238, 245, 235, 145, 243, 234, 85, 158, 215, + 192, 220, 52, 104, 208, 160, 237, 142, 29, 59, 254, 56, 119, 238, 220, 94, 165, 82, 233, 165, 139, 102, + 233, 245, 56, 36, 161, 85, 186, 32, 129, 85, 202, 16, 136, 88, 41, 88, 247, 245, 33, 67, 134, 124, 118, + 233, 210, 165, 168, 117, 235, 214, 237, 169, 92, 185, 178, 183, 185, 199, 42, 132, 250, 237, 91, 252, 177, + 123, 55, 6, 249, 248, 96, 150, 206, 125, 221, 21, 250, 238, 235, 82, 237, 60, 248, 117, 33, 82, 209, 42, + 240, 190, 47, 77, 188, 200, 204, 148, 76, 121, 73, 165, 240, 222, 135, 106, 141, 27, 75, 70, 200, 110, 167, + 164, 228, 219, 68, 89, 44, 146, 36, 84, 55, 37, 245, 124, 66, 243, 23, 122, 14, 177, 125, 75, 35, 98, 194, + 203, 152, 182, 59, 66, 239, 87, 182, 245, 206, 131, 140, 12, 204, 27, 59, 22, 131, 125, 125, 113, 106, 223, + 62, 211, 77, 204, 112, 44, 124, 125, 125, 251, 68, 69, 69, 157, 139, 140, 140, 92, 231, 237, 237, 93, 157, + 234, 179, 74, 47, 36, 176, 74, 9, 252, 2, 118, 86, 88, 89, 90, 90, 170, 253, 253, 253, 219, 36, 36, 36, 28, + 221, 186, 117, 235, 209, 122, 245, 234, 201, 218, 125, 125, 68, 235, 214, 152, 200, 113, 95, 151, 18, 86, + 82, 169, 64, 190, 135, 85, 65, 34, 65, 37, 29, 41, 209, 80, 85, 162, 8, 221, 88, 236, 93, 92, 224, 174, 84, + 194, 127, 213, 42, 76, 142, 142, 22, 21, 49, 128, 97, 105, 56, 177, 85, 128, 66, 72, 205, 81, 44, 18, 38, + 68, 105, 77, 15, 138, 33, 21, 221, 226, 59, 193, 231, 215, 126, 135, 187, 177, 173, 119, 174, 165, 165, 97, + 124, 223, 190, 8, 86, 42, 145, 124, 250, 180, 233, 38, 102, 56, 101, 186, 118, 237, 250, 213, 217, 179, + 103, 19, 215, 174, 93, 59, 167, 90, 181, 106, 130, 173, 119, 72, 100, 149, 108, 200, 201, 189, 132, 195, + 123, 3, 43, 160, 21, 87, 106, 0, 240, 243, 243, 243, 89, 182, 108, 217, 172, 102, 205, 154, 201, 218, 125, + 61, 137, 227, 190, 174, 128, 118, 165, 17, 215, 151, 135, 47, 150, 164, 12, 64, 89, 49, 69, 145, 170, 252, + 185, 109, 164, 155, 186, 20, 238, 126, 126, 248, 254, 61, 151, 122, 191, 124, 250, 212, 96, 33, 147, 124, + 224, 0, 90, 12, 29, 154, 239, 126, 82, 34, 138, 21, 106, 82, 130, 15, 208, 166, 7, 141, 117, 158, 47, 45, + 112, 223, 95, 12, 222, 89, 158, 179, 110, 240, 236, 251, 144, 253, 222, 18, 90, 215, 119, 177, 141, 125, + 31, 59, 233, 126, 62, 27, 19, 131, 11, 126, 126, 248, 172, 111, 95, 4, 135, 132, 160, 102, 253, 250, 166, + 152, 150, 193, 216, 217, 217, 149, 31, 59, 118, 236, 194, 193, 131, 7, 15, 95, 187, 118, 237, 146, 101, + 203, 150, 109, 123, 254, 252, 249, 43, 104, 29, 225, 21, 0, 24, 246, 35, 154, 33, 47, 132, 18, 7, 69, 176, + 74, 40, 34, 150, 11, 26, 134, 97, 212, 173, 90, 181, 106, 112, 252, 248, 241, 205, 81, 81, 81, 103, 155, + 53, 107, 38, 107, 247, 245, 41, 221, 187, 99, 88, 219, 182, 56, 157, 143, 251, 186, 148, 169, 33, 223, 122, + 65, 104, 117, 96, 113, 171, 177, 50, 100, 19, 194, 152, 191, 151, 90, 173, 87, 173, 113, 99, 147, 71, 253, + 182, 74, 56, 200, 243, 55, 67, 162, 79, 47, 159, 62, 205, 183, 110, 202, 144, 231, 73, 206, 199, 120, 149, + 54, 237, 38, 230, 10, 47, 85, 248, 158, 95, 250, 208, 25, 128, 141, 70, 131, 67, 187, 119, 35, 160, 73, 19, + 132, 79, 152, 128, 135, 119, 239, 230, 251, 154, 153, 26, 103, 103, 231, 218, 95, 127, 253, 117, 196, 229, + 203, 151, 79, 143, 25, 51, 166, 187, 157, 157, 29, 195, 89, 113, 104, 1, 128, 210, 134, 37, 16, 18, 88, 37, + 12, 17, 97, 197, 48, 12, 163, 110, 218, 180, 105, 173, 131, 7, 15, 174, 141, 139, 139, 187, 208, 177, 99, + 199, 64, 133, 66, 33, 91, 247, 245, 111, 6, 14, 196, 96, 214, 125, 29, 186, 15, 82, 24, 183, 228, 187, 184, + 53, 98, 150, 35, 66, 133, 222, 128, 120, 45, 82, 81, 113, 126, 235, 86, 163, 82, 118, 41, 7, 14, 228, 155, + 38, 52, 228, 249, 12, 49, 86, 53, 149, 249, 106, 73, 128, 251, 193, 196, 21, 93, 252, 168, 179, 49, 41, + 127, 118, 197, 161, 230, 213, 43, 252, 176, 102, 13, 250, 121, 122, 98, 235, 210, 165, 120, 145, 149, 101, + 170, 105, 25, 76, 141, 26, 53, 124, 190, 251, 238, 187, 131, 103, 206, 156, 57, 210, 165, 75, 151, 22, 10, + 133, 130, 45, 132, 167, 250, 172, 18, 8, 9, 172, 18, 130, 148, 176, 170, 85, 171, 86, 229, 31, 127, 252, + 113, 241, 249, 243, 231, 19, 187, 119, 239, 62, 86, 161, 80, 200, 214, 125, 253, 219, 209, 163, 209, 223, + 219, 27, 251, 69, 220, 215, 13, 245, 210, 17, 19, 87, 165, 197, 114, 161, 176, 144, 138, 98, 21, 102, 29, + 150, 232, 241, 159, 62, 197, 207, 195, 134, 97, 107, 1, 12, 78, 243, 19, 80, 134, 8, 163, 252, 138, 215, + 95, 62, 125, 106, 148, 240, 35, 196, 163, 91, 124, 255, 57, 67, 22, 173, 112, 223, 251, 236, 138, 195, 204, + 135, 15, 177, 116, 230, 76, 244, 247, 242, 194, 225, 173, 91, 101, 217, 122, 167, 73, 147, 38, 157, 14, 31, + 62, 28, 123, 234, 212, 169, 173, 45, 91, 182, 172, 203, 8, 180, 222, 33, 161, 85, 252, 33, 129, 85, 204, + 145, 114, 95, 175, 81, 163, 134, 235, 250, 245, 235, 103, 165, 166, 166, 38, 14, 31, 62, 124, 150, 133, + 133, 133, 124, 221, 215, 167, 77, 67, 63, 79, 79, 173, 251, 250, 235, 215, 112, 193, 187, 136, 149, 152, + 135, 149, 80, 196, 42, 191, 230, 203, 0, 9, 43, 99, 144, 18, 33, 82, 110, 235, 239, 203, 255, 98, 98, 176, + 103, 210, 36, 204, 169, 89, 179, 192, 5, 228, 249, 137, 35, 67, 86, 254, 189, 204, 204, 196, 255, 98, 98, + 68, 127, 79, 226, 170, 224, 228, 39, 180, 196, 44, 30, 132, 108, 30, 184, 159, 1, 108, 33, 252, 63, 127, + 254, 137, 25, 129, 129, 24, 214, 162, 5, 206, 29, 59, 102, 186, 137, 25, 142, 149, 82, 169, 28, 18, 29, 29, + 125, 113, 219, 182, 109, 75, 235, 213, 171, 87, 137, 86, 28, 150, 44, 20, 114, 168, 171, 203, 200, 200, + 128, 187, 187, 59, 178, 179, 179, 65, 215, 81, 94, 132, 94, 35, 221, 121, 210, 139, 184, 235, 254, 3, 210, + 84, 169, 82, 197, 105, 242, 228, 201, 67, 131, 130, 130, 166, 57, 57, 57, 201, 210, 32, 20, 208, 186, 175, + 239, 90, 187, 22, 255, 93, 179, 6, 25, 143, 30, 193, 17, 218, 15, 75, 177, 180, 129, 88, 1, 59, 183, 112, + 93, 172, 71, 96, 105, 187, 170, 202, 215, 172, 41, 216, 207, 239, 69, 102, 166, 81, 197, 235, 98, 207, 3, + 0, 143, 110, 222, 204, 211, 26, 70, 106, 127, 67, 184, 149, 156, 44, 25, 53, 51, 22, 41, 59, 9, 67, 83, + 123, 198, 158, 3, 162, 96, 48, 2, 95, 53, 186, 141, 251, 189, 88, 1, 252, 91, 221, 239, 223, 242, 246, 123, + 161, 251, 251, 246, 157, 59, 99, 244, 130, 5, 168, 231, 227, 99, 138, 233, 24, 205, 203, 151, 47, 239, 174, + 90, 181, 106, 249, 138, 21, 43, 126, 120, 248, 240, 225, 115, 0, 22, 108, 33, 60, 56, 167, 197, 92, 247, + 236, 226, 114, 111, 102, 24, 6, 187, 119, 239, 198, 23, 95, 124, 97, 238, 161, 144, 192, 42, 14, 112, 95, + 35, 145, 85, 129, 12, 0, 77, 217, 178, 101, 237, 70, 141, 26, 21, 48, 99, 198, 140, 25, 21, 42, 84, 144, + 165, 65, 40, 0, 188, 202, 206, 198, 175, 63, 252, 128, 109, 203, 151, 227, 230, 157, 59, 176, 135, 214, + 231, 166, 32, 194, 138, 47, 170, 132, 34, 85, 116, 69, 17, 68, 241, 128, 225, 125, 207, 221, 52, 208, 23, + 89, 124, 177, 197, 21, 88, 220, 199, 217, 199, 178, 0, 216, 89, 91, 163, 251, 192, 129, 24, 49, 111, 30, + 170, 188, 199, 63, 2, 69, 201, 131, 7, 15, 174, 174, 88, 177, 98, 193, 186, 117, 235, 246, 102, 103, 103, + 191, 129, 118, 197, 33, 192, 17, 90, 230, 80, 89, 197, 229, 222, 44, 39, 129, 69, 41, 194, 98, 130, 66, + 161, 224, 187, 175, 231, 122, 89, 57, 56, 56, 88, 142, 31, 63, 190, 111, 90, 90, 218, 217, 176, 176, 176, + 205, 114, 21, 87, 111, 114, 114, 112, 232, 167, 159, 208, 223, 203, 11, 11, 39, 78, 196, 253, 59, 119, 242, + 152, 132, 26, 179, 130, 72, 200, 207, 74, 44, 130, 69, 16, 132, 252, 145, 90, 121, 200, 247, 207, 50, 196, + 25, 158, 223, 122, 199, 242, 205, 27, 252, 119, 203, 22, 4, 120, 120, 224, 187, 57, 115, 240, 84, 158, 173, + 119, 234, 47, 89, 178, 100, 199, 197, 139, 23, 79, 14, 28, 56, 176, 131, 174, 245, 142, 94, 143, 67, 74, + 27, 22, 15, 72, 96, 21, 3, 56, 206, 235, 185, 27, 195, 48, 26, 43, 43, 43, 205, 168, 81, 163, 58, 95, 186, + 116, 233, 212, 234, 213, 171, 247, 84, 173, 90, 85, 150, 238, 235, 26, 181, 26, 39, 246, 236, 193, 16, 31, + 31, 204, 30, 49, 2, 127, 223, 184, 1, 23, 104, 133, 149, 33, 203, 179, 249, 54, 11, 82, 162, 10, 32, 97, + 69, 16, 37, 1, 161, 21, 135, 252, 247, 190, 177, 142, 240, 54, 208, 58, 194, 191, 202, 202, 194, 186, 197, + 139, 17, 224, 225, 129, 221, 235, 214, 201, 178, 245, 78, 253, 250, 245, 219, 252, 242, 203, 47, 191, 199, + 197, 197, 237, 111, 211, 166, 77, 99, 0, 108, 33, 124, 238, 71, 28, 9, 45, 121, 67, 2, 75, 222, 232, 233, + 6, 93, 196, 74, 99, 97, 97, 161, 238, 222, 189, 123, 155, 115, 231, 206, 29, 141, 136, 136, 56, 82, 187, + 118, 109, 217, 186, 175, 159, 57, 122, 20, 35, 91, 181, 194, 36, 127, 127, 92, 75, 77, 69, 89, 0, 14, 16, + 94, 33, 36, 229, 224, 44, 182, 50, 144, 44, 23, 8, 162, 228, 98, 200, 138, 67, 177, 66, 120, 177, 200, 150, + 53, 180, 37, 9, 229, 0, 252, 155, 145, 129, 249, 227, 198, 97, 112, 147, 38, 56, 185, 119, 175, 96, 189, + 171, 153, 81, 52, 111, 222, 188, 87, 108, 108, 236, 185, 67, 135, 14, 125, 231, 227, 227, 83, 131, 86, 28, + 22, 31, 72, 96, 201, 19, 126, 64, 198, 66, 215, 157, 93, 221, 185, 115, 103, 159, 211, 167, 79, 239, 61, + 120, 240, 96, 148, 175, 175, 111, 39, 243, 13, 81, 154, 164, 184, 56, 124, 245, 201, 39, 248, 242, 243, + 207, 161, 138, 143, 135, 19, 0, 71, 24, 102, 38, 40, 38, 170, 242, 51, 5, 37, 8, 162, 100, 34, 101, 92, 42, + 228, 159, 101, 168, 149, 11, 187, 226, 48, 253, 234, 85, 76, 252, 226, 11, 4, 251, 249, 33, 41, 54, 214, + 116, 19, 51, 28, 187, 110, 221, 186, 141, 57, 119, 238, 156, 234, 187, 239, 190, 251, 166, 70, 141, 26, + 229, 104, 197, 161, 252, 161, 34, 119, 121, 33, 84, 192, 174, 6, 128, 214, 173, 91, 55, 88, 184, 112, 225, + 52, 63, 63, 191, 1, 208, 126, 94, 200, 146, 107, 137, 137, 248, 97, 254, 124, 156, 58, 116, 8, 106, 104, + 163, 85, 252, 194, 116, 161, 48, 63, 255, 247, 134, 138, 169, 82, 125, 181, 16, 68, 41, 68, 104, 181, 33, + 91, 4, 207, 95, 109, 40, 84, 8, 47, 180, 2, 145, 45, 132, 207, 6, 96, 169, 80, 160, 83, 239, 222, 8, 10, + 13, 69, 173, 6, 13, 76, 49, 37, 163, 201, 202, 202, 186, 185, 116, 233, 210, 111, 87, 175, 94, 253, 51, + 167, 245, 14, 160, 191, 226, 176, 80, 139, 225, 139, 203, 189, 153, 138, 220, 9, 62, 66, 17, 43, 134, 97, + 24, 181, 151, 151, 87, 173, 221, 187, 119, 175, 141, 138, 138, 186, 224, 231, 231, 23, 8, 153, 138, 171, + 155, 215, 174, 225, 155, 129, 3, 49, 164, 121, 115, 28, 63, 116, 8, 182, 48, 188, 173, 141, 161, 6, 161, + 84, 192, 78, 16, 4, 127, 197, 176, 152, 127, 150, 80, 186, 80, 168, 149, 22, 215, 111, 175, 44, 0, 91, 134, + 193, 225, 125, 251, 48, 208, 199, 7, 97, 227, 198, 201, 178, 245, 142, 163, 163, 99, 205, 5, 11, 22, 108, + 76, 77, 77, 61, 51, 122, 244, 232, 30, 101, 202, 148, 97, 116, 255, 140, 235, 125, 60, 82, 52, 203, 188, + 20, 219, 8, 150, 28, 198, 253, 190, 136, 88, 46, 104, 0, 48, 245, 235, 215, 119, 155, 51, 103, 206, 184, + 126, 253, 250, 141, 177, 178, 178, 146, 165, 65, 40, 160, 117, 95, 223, 182, 116, 41, 14, 110, 222, 140, + 231, 175, 95, 195, 17, 218, 15, 43, 67, 237, 22, 248, 150, 11, 252, 15, 206, 210, 236, 101, 69, 16, 68, + 254, 240, 35, 90, 26, 206, 87, 54, 162, 37, 20, 205, 202, 47, 162, 149, 3, 109, 68, 171, 82, 185, 114, 24, + 60, 117, 42, 252, 199, 142, 133, 189, 147, 83, 145, 207, 167, 32, 92, 186, 116, 233, 247, 57, 115, 230, + 132, 30, 57, 114, 228, 140, 70, 163, 129, 66, 161, 176, 68, 33, 71, 179, 138, 139, 86, 163, 8, 86, 41, 71, + 202, 125, 189, 82, 165, 74, 174, 27, 55, 110, 156, 157, 148, 148, 148, 52, 112, 224, 192, 89, 114, 21, 87, + 143, 239, 223, 199, 154, 105, 211, 208, 223, 211, 19, 219, 190, 255, 30, 106, 142, 251, 186, 84, 177, 169, + 208, 202, 30, 49, 7, 118, 138, 86, 17, 4, 145, 31, 82, 214, 14, 236, 63, 111, 66, 133, 240, 98, 117, 90, + 108, 68, 203, 14, 218, 250, 172, 103, 143, 31, 99, 249, 236, 217, 24, 224, 229, 133, 200, 205, 155, 101, + 217, 122, 199, 211, 211, 179, 99, 100, 100, 100, 244, 169, 83, 167, 182, 249, 248, 248, 212, 163, 66, 120, + 121, 64, 17, 44, 19, 34, 101, 18, 90, 169, 82, 37, 167, 241, 227, 199, 15, 253, 242, 203, 47, 167, 185, + 184, 184, 200, 214, 125, 253, 249, 147, 39, 216, 189, 110, 29, 254, 187, 122, 53, 238, 62, 122, 4, 7, 188, + 115, 95, 151, 170, 175, 18, 18, 80, 66, 14, 236, 0, 69, 173, 8, 130, 40, 56, 252, 218, 44, 110, 125, 22, 3, + 241, 104, 86, 126, 17, 173, 151, 0, 94, 3, 240, 241, 241, 65, 80, 104, 40, 90, 126, 254, 185, 137, 102, + 100, 28, 106, 181, 58, 107, 215, 174, 93, 223, 47, 90, 180, 104, 197, 149, 43, 87, 238, 66, 216, 17, 222, + 232, 136, 86, 113, 209, 102, 114, 138, 96, 145, 192, 50, 17, 2, 38, 161, 12, 0, 141, 171, 171, 171, 221, + 184, 113, 227, 250, 143, 27, 55, 110, 250, 7, 31, 124, 32, 75, 131, 80, 0, 120, 153, 157, 141, 3, 155, 54, + 97, 123, 88, 88, 174, 251, 186, 45, 196, 139, 215, 141, 21, 86, 228, 97, 69, 16, 68, 97, 34, 36, 180, 248, + 142, 240, 249, 9, 45, 161, 246, 59, 217, 186, 231, 81, 118, 234, 132, 224, 133, 11, 81, 223, 215, 215, 68, + 51, 50, 142, 215, 175, 95, 223, 91, 179, 102, 205, 242, 229, 203, 151, 255, 240, 239, 191, 255, 62, 131, + 128, 208, 50, 70, 100, 145, 192, 50, 30, 74, 17, 22, 33, 10, 14, 224, 165, 2, 109, 109, 109, 45, 71, 143, + 30, 221, 247, 234, 213, 171, 103, 231, 207, 159, 255, 147, 92, 197, 21, 235, 190, 62, 208, 203, 11, 139, + 38, 77, 202, 117, 95, 47, 3, 227, 12, 66, 185, 33, 122, 174, 232, 34, 187, 5, 130, 32, 138, 2, 67, 28, 225, + 249, 70, 165, 252, 207, 52, 110, 81, 60, 251, 59, 214, 203, 47, 234, 248, 113, 4, 182, 104, 129, 208, 192, + 64, 220, 249, 235, 47, 211, 77, 204, 64, 108, 109, 109, 43, 79, 155, 54, 45, 252, 234, 213, 171, 241, 211, + 166, 77, 27, 96, 107, 107, 107, 201, 113, 132, 183, 128, 254, 45, 138, 62, 122, 139, 0, 18, 88, 69, 4, 239, + 130, 181, 96, 219, 218, 88, 91, 91, 51, 129, 129, 129, 157, 147, 147, 147, 79, 109, 216, 176, 97, 79, 165, + 74, 149, 228, 233, 190, 174, 209, 224, 196, 158, 61, 24, 234, 227, 131, 57, 60, 247, 117, 41, 247, 100, + 238, 202, 64, 246, 43, 215, 12, 144, 111, 18, 202, 175, 181, 34, 8, 130, 40, 76, 196, 140, 74, 133, 196, + 150, 161, 173, 186, 108, 0, 56, 3, 176, 120, 251, 22, 123, 182, 110, 197, 0, 79, 79, 172, 159, 53, 11, 79, + 31, 61, 50, 225, 204, 12, 163, 124, 249, 242, 245, 150, 45, 91, 182, 61, 57, 57, 57, 106, 208, 160, 65, + 159, 178, 173, 119, 192, 251, 216, 37, 145, 85, 248, 144, 192, 42, 100, 120, 17, 43, 5, 195, 48, 22, 58, + 97, 165, 246, 247, 247, 111, 147, 152, 152, 120, 116, 243, 230, 205, 71, 234, 213, 171, 39, 95, 247, 245, + 35, 71, 48, 170, 101, 75, 76, 214, 185, 175, 59, 227, 253, 76, 66, 185, 62, 87, 66, 75, 172, 233, 93, 77, + 16, 68, 81, 35, 101, 84, 106, 140, 35, 60, 119, 179, 133, 182, 245, 206, 235, 172, 44, 108, 88, 178, 4, + 253, 27, 53, 194, 174, 53, 107, 240, 250, 229, 75, 19, 206, 204, 48, 234, 213, 171, 215, 106, 219, 182, + 109, 199, 207, 159, 63, 191, 223, 207, 207, 207, 91, 23, 205, 210, 128, 10, 225, 139, 12, 18, 88, 133, 132, + 192, 202, 64, 214, 114, 65, 237, 231, 231, 231, 19, 27, 27, 187, 119, 215, 174, 93, 209, 141, 26, 53, 146, + 175, 251, 122, 108, 44, 190, 106, 223, 30, 99, 187, 116, 65, 98, 124, 60, 202, 2, 112, 130, 176, 143, 140, + 45, 242, 122, 202, 240, 133, 150, 208, 10, 65, 67, 76, 68, 105, 163, 141, 54, 218, 138, 98, 19, 74, 21, 74, + 165, 12, 249, 105, 66, 161, 207, 61, 110, 235, 157, 135, 247, 238, 97, 225, 132, 9, 24, 234, 227, 131, 19, + 187, 119, 203, 177, 86, 88, 225, 227, 227, 211, 43, 58, 58, 250, 236, 225, 195, 135, 191, 111, 218, 180, + 105, 45, 90, 113, 88, 116, 80, 145, 251, 123, 34, 229, 101, 213, 186, 117, 235, 6, 115, 231, 206, 157, 254, + 233, 167, 159, 246, 135, 76, 13, 66, 1, 224, 154, 74, 133, 159, 66, 67, 113, 42, 50, 18, 106, 134, 201, + 237, 21, 104, 104, 241, 58, 121, 89, 17, 4, 81, 92, 225, 23, 193, 27, 82, 8, 207, 95, 109, 200, 254, 204, + 238, 251, 66, 247, 88, 243, 214, 173, 17, 188, 104, 17, 188, 219, 182, 53, 225, 140, 12, 71, 173, 86, 63, + 249, 225, 135, 31, 86, 47, 89, 178, 100, 253, 205, 155, 55, 31, 66, 98, 197, 97, 113, 209, 91, 84, 228, 94, + 2, 16, 241, 178, 98, 24, 134, 81, 55, 107, 214, 172, 230, 193, 131, 7, 215, 198, 198, 198, 94, 248, 244, + 211, 79, 135, 66, 166, 226, 234, 230, 181, 107, 152, 59, 112, 32, 2, 155, 55, 199, 239, 135, 14, 193, 150, + 97, 80, 22, 121, 67, 225, 134, 164, 2, 249, 197, 235, 98, 81, 42, 130, 32, 8, 57, 33, 20, 225, 226, 167, + 13, 165, 234, 78, 249, 5, 242, 86, 208, 150, 84, 56, 2, 184, 112, 250, 52, 130, 252, 252, 48, 179, 79, 31, + 252, 153, 150, 102, 194, 89, 25, 134, 165, 165, 165, 107, 112, 112, 112, 200, 229, 203, 151, 19, 22, 44, + 88, 48, 218, 209, 209, 209, 86, 172, 199, 161, 89, 7, 90, 76, 161, 8, 150, 145, 72, 69, 172, 62, 250, 232, + 35, 183, 25, 51, 102, 140, 27, 54, 108, 216, 24, 75, 75, 75, 89, 26, 132, 2, 90, 247, 245, 95, 116, 238, + 235, 89, 175, 95, 195, 1, 218, 15, 6, 67, 188, 172, 184, 145, 45, 67, 218, 216, 20, 167, 119, 101, 57, 119, + 119, 248, 78, 157, 106, 240, 254, 247, 19, 18, 240, 56, 61, 29, 183, 162, 163, 37, 247, 179, 113, 114, 66, + 157, 110, 221, 80, 201, 199, 7, 54, 249, 56, 65, 255, 30, 20, 164, 247, 115, 37, 31, 31, 84, 87, 42, 225, + 90, 183, 174, 193, 227, 74, 8, 11, 195, 227, 244, 116, 116, 140, 136, 48, 248, 111, 132, 158, 3, 128, 65, + 231, 35, 231, 249, 115, 60, 185, 126, 221, 160, 115, 193, 226, 88, 165, 10, 90, 134, 132, 228, 121, 156, + 63, 127, 0, 239, 61, 143, 199, 233, 233, 5, 58, 110, 211, 41, 83, 244, 206, 123, 86, 70, 6, 206, 10, 252, + 45, 0, 180, 12, 9, 129, 99, 149, 42, 122, 143, 69, 79, 153, 130, 156, 231, 207, 243, 236, 235, 21, 20, 132, + 74, 156, 165, 253, 79, 174, 95, 199, 197, 240, 112, 189, 125, 140, 25, 39, 23, 57, 94, 195, 197, 5, 238, + 29, 69, 200, 13, 94, 172, 199, 225, 91, 136, 123, 104, 105, 0, 188, 1, 144, 5, 192, 209, 214, 22, 189, 70, + 140, 192, 208, 57, 115, 80, 129, 119, 173, 200, 133, 219, 183, 111, 39, 47, 89, 178, 100, 254, 230, 205, + 155, 35, 95, 188, 120, 161, 134, 112, 143, 67, 243, 139, 6, 9, 228, 20, 193, 178, 50, 247, 0, 138, 19, 34, + 94, 86, 234, 26, 53, 106, 148, 159, 49, 99, 70, 240, 208, 161, 67, 199, 219, 219, 219, 87, 50, 227, 16, 37, + 121, 124, 255, 62, 182, 135, 133, 97, 127, 68, 4, 30, 61, 123, 6, 71, 104, 157, 138, 165, 82, 129, 22, 200, + 187, 250, 143, 47, 176, 138, 187, 176, 98, 177, 118, 114, 66, 165, 38, 77, 12, 222, 159, 221, 247, 73, 122, + 58, 126, 15, 14, 22, 188, 153, 86, 83, 42, 209, 42, 36, 4, 214, 142, 142, 70, 143, 167, 101, 72, 8, 234, + 116, 237, 106, 244, 223, 89, 235, 110, 128, 198, 204, 229, 125, 159, 163, 154, 159, 31, 0, 32, 251, 238, + 93, 156, 9, 9, 193, 125, 149, 74, 114, 255, 58, 93, 187, 10, 62, 119, 157, 110, 221, 112, 35, 50, 82, 239, + 177, 194, 152, 71, 65, 142, 155, 117, 247, 46, 234, 245, 239, 175, 55, 142, 75, 17, 17, 200, 202, 200, 208, + 219, 207, 177, 74, 21, 193, 215, 169, 146, 143, 143, 160, 112, 169, 63, 96, 128, 222, 245, 192, 127, 62, + 99, 199, 201, 69, 110, 215, 112, 113, 130, 251, 153, 101, 1, 173, 138, 96, 251, 205, 88, 224, 157, 192, + 178, 224, 124, 101, 63, 7, 213, 186, 239, 185, 34, 139, 253, 158, 253, 12, 125, 243, 250, 53, 126, 254, + 238, 59, 28, 219, 185, 19, 3, 39, 79, 134, 255, 248, 241, 112, 40, 91, 214, 20, 83, 51, 152, 170, 85, 171, + 54, 94, 183, 110, 221, 175, 95, 126, 249, 229, 137, 153, 51, 103, 134, 28, 62, 124, 248, 140, 46, 152, 193, + 21, 90, 236, 169, 146, 181, 208, 146, 3, 148, 34, 204, 7, 41, 47, 43, 55, 55, 55, 135, 240, 240, 240, 113, + 151, 47, 95, 86, 141, 25, 51, 102, 145, 92, 197, 213, 179, 39, 79, 240, 211, 130, 5, 8, 104, 216, 16, 17, + 97, 97, 120, 245, 236, 25, 92, 161, 45, 214, 228, 134, 183, 133, 194, 222, 236, 62, 252, 148, 160, 88, 42, + 16, 40, 158, 226, 234, 125, 112, 117, 119, 71, 199, 141, 27, 243, 60, 94, 77, 169, 132, 50, 44, 172, 64, + 55, 166, 106, 74, 101, 129, 196, 149, 185, 113, 112, 115, 67, 199, 141, 27, 81, 201, 199, 71, 114, 191, + 250, 3, 6, 8, 62, 94, 167, 91, 183, 162, 24, 86, 129, 142, 43, 36, 142, 132, 230, 37, 54, 215, 202, 2, 143, + 151, 115, 119, 207, 115, 61, 136, 137, 48, 67, 199, 89, 24, 20, 197, 53, 92, 156, 17, 42, 144, 23, 106, 38, + 205, 181, 118, 96, 87, 21, 138, 149, 83, 176, 43, 14, 179, 158, 60, 193, 138, 111, 190, 193, 64, 47, 47, + 28, 250, 241, 71, 188, 125, 243, 198, 132, 51, 51, 140, 6, 13, 26, 116, 56, 116, 232, 80, 76, 92, 92, 220, + 182, 230, 205, 155, 215, 7, 144, 167, 16, 30, 84, 249, 145, 47, 20, 193, 146, 64, 44, 98, 229, 236, 236, + 108, 55, 106, 212, 168, 128, 41, 83, 166, 204, 168, 92, 185, 178, 44, 13, 66, 1, 224, 213, 139, 23, 56, 16, + 17, 129, 237, 203, 151, 227, 102, 70, 6, 236, 161, 125, 131, 27, 227, 190, 206, 221, 151, 91, 163, 192, + 143, 86, 149, 212, 119, 217, 253, 196, 196, 60, 143, 57, 186, 185, 193, 193, 205, 77, 239, 49, 87, 119, + 119, 84, 83, 42, 115, 111, 150, 54, 78, 78, 104, 37, 146, 78, 122, 146, 158, 142, 156, 172, 44, 201, 227, + 138, 221, 72, 133, 198, 195, 231, 141, 46, 10, 97, 200, 216, 223, 100, 101, 233, 165, 208, 184, 207, 193, + 143, 254, 8, 61, 167, 144, 96, 0, 128, 86, 33, 33, 216, 47, 50, 135, 58, 221, 186, 137, 222, 176, 43, 53, + 105, 2, 199, 42, 85, 244, 162, 58, 239, 59, 143, 130, 30, 55, 43, 35, 3, 79, 210, 211, 225, 234, 238, 158, + 251, 88, 53, 165, 50, 111, 132, 77, 68, 96, 85, 83, 42, 243, 164, 254, 248, 175, 235, 155, 172, 172, 60, 2, + 203, 216, 113, 230, 135, 185, 174, 225, 226, 14, 191, 22, 132, 171, 46, 216, 48, 14, 27, 189, 178, 224, + 125, 159, 95, 68, 203, 6, 192, 157, 155, 55, 241, 205, 200, 145, 216, 183, 126, 61, 130, 22, 44, 64, 171, + 46, 93, 76, 49, 45, 99, 176, 108, 213, 170, 213, 160, 184, 184, 184, 158, 251, 246, 237, 219, 56, 127, 254, + 252, 149, 87, 175, 94, 189, 3, 237, 173, 145, 13, 242, 233, 69, 180, 216, 210, 29, 42, 217, 210, 66, 2, 75, + 0, 1, 97, 5, 0, 106, 71, 71, 71, 235, 17, 35, 70, 244, 158, 58, 117, 234, 236, 170, 85, 171, 202, 210, 32, + 20, 0, 114, 94, 191, 198, 241, 237, 219, 177, 101, 241, 98, 252, 239, 198, 13, 216, 65, 43, 172, 140, 233, + 23, 40, 86, 99, 37, 20, 169, 42, 201, 111, 37, 177, 122, 18, 101, 120, 120, 110, 90, 140, 165, 156, 187, + 123, 238, 205, 169, 126, 255, 254, 121, 110, 146, 79, 210, 211, 17, 61, 117, 170, 65, 55, 71, 254, 115, + 191, 201, 202, 194, 254, 110, 221, 4, 83, 56, 198, 140, 221, 43, 40, 8, 158, 156, 199, 31, 167, 167, 139, + 206, 81, 72, 56, 8, 237, 91, 127, 192, 0, 248, 78, 158, 172, 247, 152, 131, 155, 155, 104, 58, 43, 191, 40, + 140, 103, 80, 144, 94, 173, 211, 251, 206, 163, 160, 199, 5, 128, 27, 135, 15, 235, 205, 141, 255, 186, 0, + 64, 117, 165, 82, 240, 249, 28, 220, 220, 242, 136, 33, 254, 57, 253, 71, 32, 122, 85, 144, 113, 74, 97, + 174, 107, 184, 164, 32, 36, 180, 88, 85, 161, 225, 124, 229, 150, 79, 176, 130, 138, 21, 91, 106, 129, 239, + 45, 160, 181, 119, 72, 77, 74, 194, 184, 174, 93, 209, 166, 99, 71, 4, 47, 92, 136, 6, 77, 155, 154, 98, + 90, 6, 99, 101, 101, 229, 216, 175, 95, 191, 41, 189, 122, 245, 26, 244, 221, 119, 223, 133, 125, 251, 237, + 183, 17, 15, 30, 60, 120, 6, 109, 218, 80, 239, 148, 40, 20, 10, 232, 22, 123, 21, 250, 56, 138, 163, 104, + 163, 20, 161, 14, 133, 66, 193, 95, 25, 152, 235, 190, 110, 105, 105, 201, 140, 26, 53, 170, 115, 74, 74, + 202, 201, 85, 116, 11, 34, 248, 0, 0, 32, 0, 73, 68, 65, 84, 171, 86, 237, 145, 171, 184, 210, 104, 52, 56, + 177, 123, 55, 134, 249, 250, 98, 206, 136, 17, 248, 231, 198, 13, 56, 67, 235, 190, 46, 150, 10, 20, 11, + 103, 11, 153, 132, 138, 249, 86, 149, 70, 174, 238, 216, 33, 249, 123, 161, 155, 228, 239, 193, 193, 5, + 190, 49, 61, 78, 79, 55, 74, 92, 153, 146, 171, 59, 118, 224, 146, 64, 33, 186, 144, 64, 115, 172, 82, 37, + 223, 26, 161, 234, 74, 101, 190, 133, 212, 198, 82, 208, 227, 10, 165, 239, 170, 113, 4, 149, 88, 4, 79, + 104, 95, 199, 42, 85, 244, 162, 97, 66, 207, 111, 202, 243, 99, 234, 107, 184, 184, 195, 143, 216, 231, + 231, 165, 101, 136, 25, 179, 53, 180, 94, 131, 246, 0, 98, 126, 255, 29, 195, 90, 180, 64, 232, 144, 33, + 184, 125, 227, 134, 137, 102, 101, 56, 54, 54, 54, 149, 38, 78, 156, 184, 252, 202, 149, 43, 23, 103, 207, + 158, 61, 184, 76, 153, 50, 121, 90, 239, 0, 185, 101, 53, 230, 29, 172, 76, 32, 129, 133, 220, 136, 21, 87, + 88, 89, 232, 132, 149, 186, 87, 175, 94, 109, 206, 159, 63, 127, 36, 34, 34, 226, 183, 218, 181, 107, 183, + 49, 231, 56, 165, 56, 171, 115, 95, 159, 218, 175, 31, 174, 235, 220, 215, 29, 32, 220, 202, 134, 191, 9, + 45, 55, 22, 50, 9, 21, 138, 100, 149, 180, 141, 143, 216, 126, 78, 34, 171, 128, 20, 0, 108, 157, 156, 242, + 164, 95, 238, 39, 38, 226, 205, 243, 231, 5, 30, 71, 165, 38, 77, 80, 127, 192, 128, 66, 159, 159, 212, 28, + 141, 57, 31, 127, 30, 62, 156, 103, 223, 114, 238, 238, 121, 246, 243, 18, 136, 166, 36, 172, 88, 161, 247, + 179, 181, 163, 35, 170, 43, 149, 133, 58, 143, 130, 30, 55, 91, 151, 38, 228, 194, 221, 167, 154, 72, 244, + 138, 165, 146, 143, 79, 238, 190, 66, 53, 89, 15, 84, 170, 66, 63, 63, 124, 204, 117, 13, 151, 196, 141, + 31, 213, 231, 219, 58, 72, 217, 219, 8, 125, 246, 114, 235, 96, 93, 0, 88, 169, 213, 216, 183, 109, 27, 6, + 122, 121, 97, 253, 140, 25, 200, 124, 248, 80, 240, 53, 50, 39, 229, 203, 151, 119, 95, 180, 104, 209, 207, + 201, 201, 201, 81, 67, 134, 12, 233, 104, 109, 109, 173, 225, 180, 222, 201, 189, 53, 144, 202, 42, 229, + 41, 66, 190, 229, 130, 78, 137, 171, 1, 160, 115, 231, 206, 62, 115, 231, 206, 157, 213, 188, 121, 243, 94, + 144, 177, 16, 77, 138, 141, 197, 79, 243, 231, 227, 236, 169, 83, 0, 180, 141, 72, 249, 162, 136, 47, 148, + 132, 132, 19, 153, 132, 10, 207, 79, 232, 166, 232, 80, 165, 10, 124, 167, 76, 201, 243, 248, 237, 232, + 104, 40, 160, 21, 22, 124, 202, 185, 187, 27, 100, 55, 240, 135, 238, 6, 123, 59, 38, 6, 85, 121, 233, 27, + 223, 201, 147, 243, 164, 226, 88, 158, 164, 167, 227, 190, 74, 133, 203, 17, 17, 146, 145, 46, 254, 28, + 243, 19, 44, 134, 60, 6, 104, 133, 72, 246, 221, 187, 122, 55, 101, 87, 157, 192, 98, 177, 113, 114, 202, + 35, 72, 30, 36, 38, 226, 250, 142, 29, 168, 223, 191, 191, 222, 223, 214, 235, 223, 31, 127, 74, 172, 150, + 51, 102, 30, 239, 123, 220, 219, 209, 209, 122, 145, 39, 86, 52, 1, 64, 101, 142, 221, 2, 0, 92, 219, 185, + 83, 111, 229, 97, 101, 206, 190, 252, 49, 220, 142, 137, 201, 21, 44, 133, 49, 78, 64, 94, 215, 112, 73, + 134, 61, 207, 124, 223, 2, 54, 85, 200, 90, 59, 176, 233, 66, 174, 173, 131, 37, 244, 235, 178, 44, 121, + 223, 91, 3, 200, 201, 206, 198, 198, 101, 203, 112, 100, 235, 86, 12, 153, 57, 19, 61, 131, 131, 97, 91, + 166, 76, 145, 207, 203, 24, 220, 221, 221, 91, 110, 221, 186, 245, 248, 164, 73, 147, 14, 78, 157, 58, 53, + 244, 228, 201, 147, 137, 0, 160, 80, 40, 44, 117, 187, 48, 236, 61, 182, 72, 114, 134, 197, 128, 82, 41, + 176, 68, 188, 172, 212, 0, 208, 188, 121, 243, 6, 75, 151, 46, 157, 222, 182, 109, 219, 0, 104, 255, 193, + 144, 37, 215, 84, 42, 252, 52, 127, 62, 162, 14, 31, 206, 117, 95, 23, 170, 163, 226, 10, 42, 110, 186, 79, + 170, 206, 170, 180, 9, 43, 41, 58, 8, 172, 172, 18, 226, 65, 98, 98, 158, 72, 7, 23, 107, 71, 71, 84, 52, + 98, 249, 252, 181, 29, 59, 242, 8, 44, 41, 92, 221, 221, 225, 234, 238, 142, 58, 221, 186, 225, 143, 160, + 32, 201, 177, 20, 21, 124, 129, 197, 167, 170, 82, 153, 39, 157, 118, 77, 151, 166, 250, 51, 50, 18, 30, + 156, 27, 179, 171, 187, 59, 42, 249, 248, 228, 107, 247, 96, 8, 239, 123, 220, 91, 209, 209, 122, 251, 56, + 184, 185, 193, 213, 221, 29, 217, 119, 239, 230, 121, 77, 175, 237, 220, 137, 106, 74, 101, 238, 121, 176, + 118, 116, 204, 125, 62, 254, 235, 201, 79, 15, 22, 213, 249, 49, 215, 53, 92, 26, 224, 127, 54, 242, 43, + 191, 217, 141, 91, 163, 197, 173, 197, 226, 22, 194, 243, 11, 230, 109, 0, 60, 186, 127, 31, 139, 38, 77, + 194, 175, 223, 127, 143, 17, 33, 33, 232, 224, 239, 15, 133, 133, 188, 254, 223, 111, 220, 184, 113, 143, + 19, 39, 78, 124, 118, 236, 216, 177, 173, 95, 127, 253, 245, 18, 149, 74, 245, 23, 160, 95, 8, 95, 90, 133, + 150, 188, 94, 169, 34, 134, 173, 179, 98, 127, 212, 165, 2, 25, 134, 97, 212, 141, 27, 55, 174, 189, 103, + 207, 158, 181, 167, 79, 159, 190, 216, 182, 109, 219, 161, 144, 169, 184, 186, 121, 237, 26, 230, 13, 24, + 128, 97, 205, 155, 227, 247, 200, 72, 216, 50, 12, 156, 145, 55, 205, 39, 213, 55, 139, 159, 6, 228, 215, + 89, 145, 251, 186, 113, 60, 73, 79, 71, 140, 64, 52, 224, 125, 184, 175, 82, 225, 220, 252, 249, 120, 99, + 228, 74, 45, 107, 71, 71, 163, 140, 38, 77, 9, 55, 178, 3, 104, 5, 25, 43, 50, 110, 8, 164, 24, 107, 23, + 146, 37, 193, 251, 30, 247, 73, 122, 58, 178, 239, 222, 213, 123, 172, 154, 82, 153, 167, 198, 236, 73, + 122, 58, 178, 51, 50, 242, 136, 158, 74, 62, 62, 130, 169, 196, 219, 60, 129, 101, 174, 243, 3, 20, 205, + 53, 92, 154, 16, 75, 35, 138, 53, 146, 150, 170, 131, 229, 126, 62, 179, 43, 191, 111, 92, 191, 142, 233, + 253, 251, 99, 116, 155, 54, 72, 52, 208, 204, 215, 196, 216, 126, 246, 217, 103, 65, 103, 206, 156, 81, + 109, 220, 184, 113, 126, 205, 154, 53, 63, 16, 115, 132, 47, 77, 153, 195, 82, 17, 193, 146, 112, 95, 215, + 52, 104, 208, 192, 109, 246, 236, 217, 227, 252, 253, 253, 199, 88, 91, 91, 203, 215, 125, 253, 175, 191, + 240, 203, 210, 165, 136, 220, 186, 21, 207, 95, 189, 130, 3, 222, 153, 132, 90, 161, 224, 169, 64, 33, 49, + 85, 122, 46, 255, 194, 225, 190, 74, 149, 111, 1, 250, 155, 172, 44, 163, 163, 74, 127, 70, 70, 230, 166, + 167, 196, 172, 0, 106, 119, 235, 150, 39, 106, 84, 177, 73, 19, 216, 56, 57, 153, 188, 40, 158, 95, 192, + 205, 165, 146, 143, 79, 158, 223, 219, 56, 57, 225, 83, 78, 202, 233, 77, 86, 150, 94, 4, 167, 118, 215, + 174, 80, 133, 135, 191, 215, 60, 10, 235, 184, 183, 162, 163, 245, 4, 80, 85, 165, 18, 14, 188, 26, 38, 86, + 88, 221, 142, 142, 70, 109, 142, 135, 153, 208, 190, 183, 99, 98, 244, 158, 223, 92, 231, 135, 59, 246, + 162, 184, 134, 75, 27, 252, 27, 13, 63, 154, 197, 183, 115, 224, 254, 204, 79, 21, 190, 197, 187, 149, 136, + 142, 186, 223, 93, 60, 123, 22, 137, 237, 219, 163, 67, 207, 158, 24, 25, 26, 138, 58, 141, 26, 153, 98, + 90, 6, 99, 107, 107, 235, 26, 20, 20, 52, 119, 192, 128, 1, 129, 235, 214, 173, 91, 250, 237, 183, 223, + 110, 121, 246, 236, 217, 11, 93, 218, 144, 61, 37, 96, 87, 27, 154, 119, 180, 69, 79, 137, 22, 88, 34, 194, + 138, 1, 160, 174, 92, 185, 114, 185, 185, 115, 231, 6, 143, 24, 49, 98, 130, 141, 141, 141, 44, 13, 66, 1, + 142, 251, 250, 198, 141, 120, 252, 252, 185, 160, 251, 58, 95, 96, 73, 9, 43, 74, 5, 26, 199, 137, 224, + 224, 220, 239, 109, 156, 156, 80, 209, 199, 39, 79, 164, 161, 94, 255, 254, 120, 243, 252, 121, 238, 74, + 58, 161, 180, 77, 206, 243, 231, 5, 170, 77, 201, 121, 254, 28, 247, 85, 42, 209, 84, 208, 165, 136, 8, + 124, 26, 17, 145, 39, 117, 227, 234, 238, 94, 40, 233, 53, 67, 113, 21, 88, 77, 247, 128, 227, 191, 36, 20, + 109, 49, 36, 229, 84, 187, 91, 183, 220, 52, 89, 65, 40, 172, 227, 254, 25, 25, 169, 247, 186, 187, 186, + 187, 231, 89, 201, 199, 70, 164, 248, 231, 93, 104, 95, 126, 122, 176, 40, 207, 143, 185, 175, 225, 210, 8, + 171, 36, 20, 188, 239, 89, 91, 7, 174, 200, 226, 11, 43, 49, 111, 45, 11, 0, 206, 0, 222, 50, 12, 142, 253, + 250, 43, 226, 142, 28, 65, 143, 225, 195, 49, 116, 246, 108, 84, 172, 90, 213, 132, 179, 203, 31, 71, 71, + 199, 234, 51, 103, 206, 92, 63, 120, 240, 224, 224, 101, 203, 150, 205, 223, 180, 105, 211, 193, 151, 47, + 95, 114, 91, 239, 232, 217, 46, 148, 84, 177, 85, 98, 83, 132, 2, 141, 152, 193, 48, 140, 186, 98, 197, + 138, 246, 139, 23, 47, 30, 123, 229, 202, 21, 213, 152, 49, 99, 22, 203, 85, 92, 61, 215, 185, 175, 247, + 111, 208, 0, 155, 194, 194, 240, 250, 249, 243, 60, 238, 235, 252, 21, 42, 98, 97, 102, 126, 35, 102, 177, + 21, 50, 68, 94, 88, 113, 115, 95, 165, 194, 173, 232, 104, 168, 194, 195, 113, 68, 192, 101, 187, 30, 239, + 49, 254, 127, 250, 14, 110, 110, 249, 186, 155, 23, 148, 199, 215, 175, 23, 201, 243, 26, 131, 39, 231, 38, + 206, 194, 46, 231, 183, 113, 114, 210, 139, 232, 24, 3, 95, 8, 24, 67, 97, 30, 87, 40, 77, 200, 55, 58, + 101, 69, 73, 206, 243, 231, 122, 226, 146, 191, 47, 160, 159, 30, 44, 234, 243, 83, 28, 174, 225, 146, 72, + 126, 171, 16, 249, 233, 67, 33, 27, 29, 126, 153, 7, 187, 159, 51, 0, 230, 245, 107, 252, 178, 97, 3, 6, + 120, 120, 224, 167, 208, 80, 100, 63, 125, 106, 186, 201, 25, 200, 135, 31, 126, 232, 185, 122, 245, 234, + 125, 231, 206, 157, 59, 222, 163, 71, 143, 54, 10, 133, 66, 173, 203, 30, 233, 221, 118, 74, 106, 222, 176, + 68, 9, 44, 169, 182, 54, 229, 203, 151, 183, 157, 59, 119, 238, 208, 43, 87, 174, 92, 156, 53, 107, 214, + 90, 87, 87, 215, 154, 102, 30, 174, 32, 175, 178, 179, 241, 223, 149, 43, 49, 208, 195, 3, 171, 230, 206, + 197, 179, 199, 143, 225, 10, 173, 33, 157, 161, 94, 86, 252, 46, 240, 252, 2, 119, 33, 55, 118, 194, 112, + 158, 164, 167, 227, 118, 76, 140, 222, 99, 108, 49, 51, 139, 144, 109, 129, 95, 120, 56, 60, 131, 130, 36, + 83, 105, 198, 82, 77, 169, 20, 244, 43, 50, 85, 122, 208, 213, 221, 29, 126, 225, 225, 130, 5, 249, 172, + 136, 16, 138, 206, 100, 223, 189, 139, 7, 137, 137, 121, 54, 126, 205, 153, 131, 155, 91, 190, 86, 8, 98, + 20, 246, 113, 165, 26, 34, 243, 35, 62, 82, 251, 62, 72, 76, 212, 123, 125, 204, 113, 126, 228, 116, 13, + 151, 6, 196, 4, 22, 187, 113, 255, 25, 230, 182, 41, 51, 164, 245, 78, 118, 102, 38, 86, 207, 155, 135, 65, + 158, 158, 56, 184, 105, 19, 222, 228, 228, 152, 112, 102, 134, 225, 229, 229, 245, 201, 129, 3, 7, 162, + 226, 226, 226, 182, 183, 105, 211, 166, 161, 174, 62, 75, 175, 245, 142, 162, 4, 22, 104, 149, 152, 20, + 161, 88, 91, 27, 91, 91, 91, 171, 161, 67, 135, 246, 158, 63, 127, 254, 236, 202, 149, 43, 203, 210, 32, + 20, 120, 231, 190, 190, 149, 231, 190, 206, 95, 245, 199, 77, 7, 22, 36, 21, 72, 162, 170, 112, 120, 114, + 253, 186, 228, 42, 63, 54, 165, 196, 141, 92, 88, 59, 58, 194, 35, 40, 72, 111, 53, 24, 159, 237, 186, 101, + 255, 149, 124, 124, 12, 94, 253, 197, 167, 40, 107, 101, 6, 38, 36, 24, 180, 31, 183, 64, 91, 40, 202, 162, + 10, 15, 23, 20, 33, 158, 2, 231, 167, 118, 183, 110, 146, 130, 69, 140, 194, 62, 46, 63, 77, 200, 133, 255, + 156, 247, 37, 206, 19, 127, 95, 115, 157, 159, 162, 190, 134, 9, 125, 164, 234, 179, 184, 41, 68, 11, 228, + 93, 117, 200, 77, 21, 170, 121, 27, 187, 226, 240, 206, 63, 255, 96, 110, 80, 16, 246, 127, 247, 29, 70, + 133, 134, 162, 117, 17, 247, 245, 44, 0, 150, 173, 90, 181, 26, 112, 234, 212, 169, 30, 251, 247, 239, 143, + 88, 176, 96, 65, 88, 106, 106, 106, 6, 0, 139, 146, 186, 226, 176, 216, 71, 176, 120, 17, 43, 5, 235, 190, + 110, 107, 107, 203, 4, 6, 6, 126, 118, 233, 210, 165, 83, 27, 55, 110, 220, 35, 87, 113, 165, 209, 104, + 112, 114, 247, 110, 12, 247, 245, 197, 215, 58, 247, 117, 23, 188, 115, 95, 23, 138, 86, 217, 33, 239, 127, + 51, 124, 7, 118, 41, 11, 6, 226, 253, 17, 18, 48, 174, 117, 235, 230, 126, 159, 243, 252, 57, 98, 166, 76, + 49, 122, 21, 96, 97, 32, 228, 170, 110, 106, 206, 233, 90, 185, 112, 45, 11, 88, 184, 226, 139, 207, 181, + 157, 59, 243, 60, 86, 213, 207, 47, 79, 145, 120, 126, 20, 197, 113, 159, 164, 167, 139, 190, 158, 252, 8, + 150, 80, 74, 145, 133, 59, 6, 115, 157, 31, 118, 140, 124, 228, 114, 13, 151, 100, 140, 93, 113, 40, 181, + 50, 156, 187, 15, 187, 240, 41, 45, 57, 25, 227, 187, 119, 199, 132, 142, 29, 145, 22, 31, 111, 186, 137, + 25, 136, 149, 149, 149, 131, 191, 191, 255, 164, 139, 23, 47, 38, 46, 91, 182, 108, 90, 165, 74, 149, 28, + 37, 86, 28, 22, 235, 91, 86, 177, 21, 88, 124, 97, 5, 221, 202, 64, 43, 43, 43, 117, 64, 64, 64, 155, 132, + 132, 132, 35, 155, 55, 111, 62, 234, 238, 238, 46, 107, 247, 245, 160, 22, 45, 48, 181, 95, 63, 92, 227, + 184, 175, 75, 185, 0, 243, 173, 22, 88, 81, 149, 95, 15, 65, 18, 87, 133, 139, 80, 10, 142, 127, 163, 124, + 146, 158, 142, 223, 6, 12, 200, 83, 143, 83, 148, 92, 219, 185, 243, 189, 138, 194, 223, 151, 236, 187, + 119, 113, 34, 56, 56, 87, 112, 8, 165, 191, 132, 68, 2, 75, 206, 243, 231, 130, 169, 169, 58, 70, 214, 40, + 21, 213, 113, 133, 132, 15, 107, 207, 192, 71, 168, 80, 156, 191, 175, 185, 206, 15, 251, 92, 124, 228, + 112, 13, 151, 22, 248, 66, 139, 43, 184, 184, 25, 11, 67, 108, 29, 184, 229, 33, 78, 208, 222, 71, 98, 255, + 248, 3, 35, 90, 181, 194, 252, 193, 131, 113, 235, 255, 254, 207, 116, 19, 51, 16, 59, 59, 187, 74, 211, + 166, 77, 91, 150, 150, 150, 150, 48, 119, 238, 220, 33, 14, 14, 14, 86, 37, 173, 245, 78, 113, 76, 17, 234, + 45, 122, 227, 186, 175, 43, 149, 74, 159, 5, 11, 22, 204, 108, 221, 186, 117, 111, 200, 88, 60, 38, 243, + 220, 215, 157, 240, 46, 245, 39, 102, 177, 144, 95, 58, 144, 123, 69, 242, 87, 5, 22, 207, 75, 211, 244, + 188, 184, 123, 23, 169, 188, 232, 143, 216, 69, 244, 175, 74, 149, 103, 223, 236, 187, 119, 243, 236, 255, + 50, 35, 3, 39, 131, 130, 224, 80, 165, 138, 65, 69, 194, 236, 223, 11, 141, 69, 138, 236, 187, 119, 113, + 95, 165, 66, 118, 70, 134, 228, 133, 255, 128, 55, 110, 161, 49, 179, 24, 51, 134, 236, 187, 119, 241, 228, + 250, 245, 220, 168, 8, 251, 156, 119, 162, 163, 145, 201, 43, 194, 191, 25, 25, 41, 57, 198, 212, 136, 8, + 188, 224, 9, 150, 23, 188, 113, 230, 55, 143, 162, 58, 110, 250, 142, 29, 121, 246, 185, 175, 82, 9, 62, + 175, 33, 251, 22, 246, 56, 229, 116, 13, 19, 134, 195, 22, 35, 113, 191, 178, 110, 240, 236, 87, 54, 37, + 168, 129, 246, 126, 240, 86, 247, 149, 93, 129, 200, 181, 122, 96, 239, 25, 111, 213, 106, 28, 248, 229, + 23, 68, 255, 250, 43, 250, 126, 249, 37, 6, 78, 155, 6, 151, 10, 21, 76, 57, 181, 124, 41, 95, 190, 252, + 127, 230, 207, 159, 191, 117, 208, 160, 65, 99, 22, 47, 94, 60, 127, 199, 142, 29, 199, 115, 114, 114, 24, + 112, 86, 28, 114, 40, 86, 105, 67, 133, 28, 210, 156, 25, 25, 25, 112, 119, 119, 71, 118, 118, 182, 84, + 199, 108, 81, 247, 245, 54, 109, 218, 212, 159, 59, 119, 238, 140, 14, 29, 58, 200, 218, 125, 253, 122, 98, + 34, 126, 154, 63, 31, 209, 145, 145, 120, 171, 115, 95, 231, 214, 84, 25, 226, 101, 37, 84, 99, 69, 94, 86, + 4, 65, 16, 37, 3, 110, 251, 29, 13, 239, 43, 43, 176, 88, 193, 245, 150, 247, 149, 255, 61, 187, 229, 0, + 200, 2, 80, 181, 82, 37, 12, 154, 62, 29, 189, 70, 143, 134, 157, 189, 189, 169, 166, 100, 20, 23, 47, 94, + 140, 156, 49, 99, 70, 104, 84, 84, 84, 2, 144, 219, 122, 135, 213, 156, 44, 162, 194, 133, 97, 24, 236, + 222, 189, 27, 95, 124, 241, 69, 17, 143, 52, 127, 138, 195, 63, 27, 124, 221, 144, 235, 190, 222, 172, 89, + 179, 218, 135, 14, 29, 90, 19, 27, 27, 155, 208, 161, 67, 7, 89, 187, 175, 207, 31, 52, 8, 195, 154, 53, + 195, 31, 135, 14, 233, 185, 175, 139, 173, 12, 20, 203, 181, 243, 87, 7, 242, 163, 88, 148, 10, 36, 8, 130, + 40, 190, 232, 221, 236, 144, 55, 179, 193, 173, 209, 18, 186, 95, 8, 221, 55, 236, 0, 148, 131, 214, 87, + 113, 201, 148, 41, 8, 244, 246, 198, 239, 59, 119, 66, 163, 209, 152, 106, 90, 6, 211, 180, 105, 211, 110, + 167, 78, 157, 58, 115, 236, 216, 177, 77, 205, 155, 55, 175, 35, 180, 226, 16, 197, 228, 86, 39, 103, 129, + 37, 42, 172, 62, 250, 232, 163, 202, 155, 54, 109, 90, 124, 250, 244, 233, 132, 110, 221, 186, 141, 131, + 182, 38, 92, 118, 220, 253, 251, 111, 44, 31, 61, 26, 67, 188, 189, 113, 96, 251, 118, 88, 168, 213, 122, + 194, 202, 144, 182, 54, 252, 2, 118, 177, 40, 86, 177, 184, 218, 8, 130, 32, 136, 124, 145, 42, 132, 231, + 10, 45, 161, 66, 120, 177, 205, 26, 239, 90, 239, 252, 153, 158, 142, 25, 3, 6, 96, 116, 235, 214, 80, 233, + 74, 85, 100, 134, 77, 167, 78, 157, 70, 198, 198, 198, 38, 68, 68, 68, 44, 168, 93, 187, 182, 96, 235, 29, + 200, 252, 214, 39, 215, 20, 33, 255, 228, 41, 24, 134, 121, 91, 179, 102, 205, 114, 211, 167, 79, 15, 30, + 54, 108, 216, 4, 59, 59, 59, 89, 26, 132, 2, 192, 163, 123, 247, 176, 107, 229, 74, 236, 223, 176, 1, 143, + 158, 63, 135, 3, 180, 23, 56, 183, 118, 138, 239, 79, 37, 148, 42, 148, 42, 86, 167, 116, 32, 65, 16, 68, + 201, 135, 225, 125, 101, 211, 133, 108, 234, 144, 155, 50, 228, 111, 252, 20, 34, 63, 125, 152, 13, 237, + 189, 165, 125, 143, 30, 24, 17, 26, 138, 143, 60, 61, 77, 48, 35, 227, 121, 241, 226, 197, 173, 229, 203, + 151, 47, 89, 181, 106, 213, 150, 204, 204, 76, 182, 245, 14, 160, 159, 58, 100, 0, 121, 165, 8, 229, 40, + 176, 248, 126, 86, 176, 179, 179, 179, 89, 184, 112, 225, 240, 160, 160, 160, 105, 78, 78, 78, 53, 204, 57, + 86, 41, 158, 103, 102, 98, 239, 218, 181, 216, 189, 122, 53, 238, 61, 122, 148, 43, 172, 132, 138, 215, + 173, 4, 30, 19, 235, 25, 200, 95, 105, 2, 144, 168, 34, 8, 130, 40, 109, 8, 213, 103, 229, 39, 180, 184, + 226, 74, 168, 62, 235, 45, 180, 245, 89, 246, 182, 182, 232, 62, 108, 24, 134, 206, 153, 35, 187, 214, 59, + 44, 25, 25, 25, 151, 151, 45, 91, 54, 127, 221, 186, 117, 145, 106, 181, 90, 163, 80, 40, 216, 83, 144, + 123, 106, 72, 96, 241, 224, 8, 44, 5, 39, 130, 197, 166, 5, 213, 117, 234, 212, 169, 115, 245, 234, 213, + 68, 107, 107, 107, 71, 233, 103, 50, 15, 175, 178, 179, 113, 104, 211, 38, 108, 15, 11, 195, 223, 119, 238, + 192, 1, 218, 116, 31, 223, 173, 87, 76, 96, 73, 21, 176, 179, 194, 10, 32, 113, 69, 16, 4, 81, 218, 49, 36, + 162, 197, 22, 195, 243, 5, 149, 148, 216, 122, 3, 173, 208, 170, 224, 226, 130, 128, 137, 19, 225, 63, 113, + 34, 28, 157, 157, 77, 49, 37, 163, 120, 243, 230, 77, 86, 253, 250, 245, 125, 110, 220, 184, 241, 63, 133, + 66, 97, 5, 253, 83, 0, 134, 97, 24, 185, 8, 44, 185, 214, 96, 177, 186, 194, 18, 128, 181, 70, 163, 121, + 165, 209, 104, 100, 215, 104, 233, 77, 78, 14, 14, 111, 222, 140, 33, 94, 94, 248, 118, 210, 36, 60, 184, + 115, 7, 174, 0, 202, 64, 188, 198, 74, 170, 214, 202, 144, 26, 43, 18, 87, 4, 65, 16, 165, 151, 252, 250, + 27, 114, 91, 239, 72, 213, 100, 241, 125, 21, 217, 238, 33, 217, 153, 153, 88, 19, 18, 130, 193, 30, 30, + 56, 36, 195, 214, 59, 12, 195, 100, 49, 12, 147, 131, 119, 109, 118, 185, 201, 29, 89, 33, 71, 31, 44, 238, + 117, 99, 9, 192, 226, 209, 163, 71, 175, 239, 223, 191, 255, 172, 122, 245, 234, 31, 154, 119, 104, 90, 24, + 141, 6, 81, 251, 246, 97, 203, 130, 5, 184, 124, 249, 50, 108, 161, 117, 208, 149, 170, 177, 50, 212, 203, + 138, 106, 172, 8, 33, 92, 220, 221, 97, 227, 228, 36, 248, 187, 7, 2, 134, 150, 172, 103, 17, 203, 147, + 244, 116, 188, 17, 233, 79, 200, 127, 238, 156, 231, 207, 145, 41, 210, 106, 135, 255, 188, 220, 227, 75, + 141, 209, 144, 113, 20, 198, 216, 133, 246, 229, 62, 95, 246, 221, 187, 130, 166, 160, 214, 78, 78, 162, + 253, 245, 184, 231, 163, 160, 199, 171, 104, 100, 147, 100, 238, 107, 42, 116, 206, 243, 251, 27, 162, 228, + 35, 213, 122, 71, 195, 249, 42, 212, 114, 135, 235, 151, 101, 9, 109, 52, 139, 253, 106, 1, 173, 248, 186, + 119, 235, 22, 66, 130, 130, 176, 111, 221, 58, 140, 92, 176, 0, 109, 186, 119, 55, 197, 180, 242, 229, 201, + 147, 39, 79, 159, 61, 123, 246, 10, 218, 97, 178, 65, 59, 246, 150, 105, 254, 148, 28, 7, 57, 10, 44, 128, + 23, 193, 122, 246, 236, 25, 238, 221, 187, 151, 89, 189, 122, 117, 51, 15, 11, 56, 127, 244, 40, 126, 10, + 9, 129, 234, 194, 5, 88, 65, 95, 88, 9, 245, 9, 52, 52, 21, 72, 94, 86, 4, 31, 107, 39, 39, 52, 10, 10, 66, + 205, 110, 221, 96, 237, 40, 158, 29, 223, 205, 233, 253, 214, 48, 40, 8, 181, 186, 117, 131, 189, 192, 13, + 153, 53, 161, 188, 25, 25, 169, 247, 120, 147, 169, 83, 81, 161, 73, 19, 189, 199, 126, 109, 215, 78, 80, + 212, 180, 14, 11, 131, 11, 79, 136, 176, 199, 23, 122, 30, 33, 254, 77, 76, 196, 233, 41, 83, 242, 60, 127, + 97, 140, 253, 78, 76, 12, 206, 76, 153, 162, 183, 79, 173, 174, 93, 209, 80, 215, 59, 47, 45, 34, 2, 105, + 28, 115, 77, 107, 39, 39, 120, 79, 153, 130, 154, 18, 78, 232, 255, 38, 38, 34, 74, 247, 247, 5, 61, 94, + 59, 35, 251, 74, 238, 246, 245, 133, 139, 187, 59, 188, 13, 60, 167, 236, 223, 16, 165, 15, 246, 62, 193, + 77, 29, 178, 74, 131, 219, 215, 144, 21, 85, 220, 212, 33, 247, 159, 127, 86, 92, 113, 123, 28, 218, 1, + 184, 118, 233, 18, 38, 245, 232, 129, 86, 237, 219, 99, 212, 162, 69, 104, 212, 188, 185, 41, 166, 37, 202, + 63, 255, 252, 243, 236, 225, 195, 135, 12, 180, 129, 183, 55, 120, 151, 34, 148, 29, 114, 76, 17, 114, 197, + 21, 27, 229, 180, 122, 245, 234, 213, 19, 115, 14, 42, 57, 54, 22, 19, 59, 116, 192, 184, 207, 63, 71, 242, + 133, 11, 112, 130, 214, 129, 93, 204, 191, 74, 170, 19, 186, 88, 163, 102, 178, 92, 32, 184, 180, 219, 184, + 17, 255, 233, 223, 95, 82, 92, 113, 233, 184, 99, 7, 26, 6, 5, 9, 10, 20, 0, 176, 119, 115, 67, 179, 121, + 243, 208, 76, 215, 39, 80, 138, 15, 149, 202, 60, 143, 57, 84, 169, 146, 71, 92, 21, 132, 10, 77, 154, 160, + 117, 120, 184, 222, 99, 133, 53, 246, 15, 253, 252, 12, 142, 22, 89, 59, 57, 161, 221, 198, 141, 146, 226, + 42, 63, 140, 57, 158, 177, 180, 14, 15, 55, 88, 92, 17, 4, 247, 222, 33, 84, 251, 203, 181, 117, 16, 74, + 21, 242, 191, 103, 55, 39, 0, 142, 0, 206, 156, 58, 133, 160, 214, 173, 49, 127, 224, 64, 220, 250, 223, + 255, 76, 55, 49, 30, 175, 95, 191, 126, 140, 119, 153, 80, 254, 237, 83, 86, 200, 45, 130, 197, 79, 45, 91, + 42, 20, 10, 107, 134, 97, 152, 244, 244, 244, 39, 109, 219, 182, 53, 249, 128, 174, 39, 38, 98, 51, 199, + 125, 221, 17, 226, 133, 235, 82, 182, 11, 82, 109, 109, 40, 98, 69, 240, 105, 24, 20, 148, 71, 204, 220, + 137, 137, 201, 211, 86, 69, 108, 255, 55, 89, 89, 72, 139, 136, 64, 230, 245, 235, 112, 169, 91, 23, 13, + 131, 130, 114, 133, 90, 205, 174, 93, 241, 64, 165, 202, 19, 13, 226, 242, 161, 82, 153, 231, 247, 198, 8, + 145, 127, 19, 19, 241, 32, 33, 65, 239, 49, 247, 1, 3, 114, 199, 80, 161, 73, 19, 184, 184, 187, 35, 51, + 61, 189, 208, 199, 222, 44, 36, 4, 135, 5, 122, 252, 241, 241, 158, 50, 69, 239, 184, 47, 238, 222, 197, + 157, 232, 232, 60, 61, 250, 196, 154, 54, 27, 115, 188, 52, 94, 75, 26, 110, 164, 78, 232, 92, 125, 168, + 84, 234, 137, 205, 23, 119, 239, 226, 47, 137, 57, 19, 4, 75, 158, 150, 39, 120, 151, 67, 227, 70, 180, + 184, 81, 45, 238, 247, 108, 170, 144, 45, 134, 103, 247, 117, 134, 182, 245, 206, 193, 29, 59, 16, 125, + 224, 0, 250, 140, 25, 131, 129, 51, 102, 192, 213, 196, 173, 119, 254, 249, 231, 159, 39, 120, 119, 203, + 229, 214, 233, 203, 46, 77, 40, 55, 129, 5, 228, 53, 176, 181, 2, 128, 123, 247, 238, 153, 180, 200, 253, + 230, 213, 171, 248, 121, 209, 34, 28, 223, 181, 11, 175, 223, 190, 133, 3, 180, 13, 52, 133, 210, 125, 134, + 166, 3, 197, 132, 21, 64, 226, 138, 208, 167, 22, 239, 134, 253, 251, 128, 1, 162, 117, 81, 66, 251, 71, 5, + 5, 229, 238, 255, 64, 165, 194, 131, 132, 4, 116, 228, 52, 129, 118, 239, 223, 95, 90, 96, 249, 249, 193, + 218, 201, 73, 47, 141, 199, 63, 134, 20, 15, 18, 18, 242, 136, 138, 236, 187, 119, 209, 108, 222, 188, 119, + 199, 80, 42, 145, 153, 158, 94, 232, 99, 183, 119, 115, 131, 251, 128, 1, 72, 151, 104, 122, 109, 237, 228, + 164, 39, 24, 51, 211, 211, 17, 21, 28, 156, 111, 125, 88, 65, 143, 199, 63, 23, 21, 125, 125, 115, 5, 148, + 208, 185, 98, 83, 140, 44, 73, 225, 225, 184, 35, 208, 104, 154, 32, 196, 96, 149, 6, 123, 223, 225, 214, + 104, 113, 133, 23, 183, 54, 139, 43, 182, 184, 117, 89, 92, 177, 229, 10, 32, 231, 197, 11, 252, 24, 30, + 142, 99, 219, 182, 97, 208, 244, 233, 232, 57, 102, 140, 201, 90, 239, 252, 245, 215, 95, 79, 1, 88, 235, + 44, 26, 100, 29, 193, 146, 99, 138, 144, 133, 155, 42, 180, 121, 246, 236, 153, 73, 4, 214, 61, 157, 251, + 122, 96, 147, 38, 56, 184, 125, 59, 172, 222, 190, 133, 51, 242, 134, 81, 217, 205, 14, 226, 105, 65, 161, + 116, 160, 80, 237, 149, 88, 129, 59, 109, 165, 115, 179, 113, 114, 210, 139, 94, 100, 196, 196, 224, 105, + 122, 186, 193, 251, 255, 155, 152, 152, 103, 255, 167, 233, 233, 248, 55, 49, 49, 119, 31, 182, 88, 91, 1, + 113, 170, 42, 149, 185, 127, 239, 234, 238, 46, 154, 190, 99, 247, 17, 122, 140, 187, 241, 27, 20, 23, 246, + 216, 95, 112, 34, 77, 13, 131, 130, 114, 247, 225, 238, 199, 254, 204, 111, 88, 252, 191, 157, 59, 241, + 246, 249, 243, 124, 95, 155, 130, 30, 79, 234, 121, 12, 217, 231, 67, 165, 82, 239, 249, 105, 163, 205, + 144, 77, 104, 133, 33, 27, 12, 224, 119, 10, 17, 43, 115, 225, 111, 214, 208, 174, 148, 47, 7, 224, 201, + 131, 7, 88, 54, 117, 42, 2, 27, 55, 198, 31, 59, 118, 152, 164, 245, 206, 139, 23, 47, 158, 234, 134, 202, + 38, 136, 20, 69, 126, 208, 2, 34, 87, 129, 197, 191, 70, 172, 110, 220, 184, 81, 164, 2, 235, 241, 189, + 123, 248, 110, 250, 116, 12, 242, 240, 192, 206, 141, 27, 161, 121, 245, 10, 46, 16, 206, 73, 243, 243, + 213, 220, 11, 207, 144, 158, 129, 92, 65, 69, 16, 124, 248, 169, 65, 177, 180, 160, 216, 254, 255, 242, + 210, 77, 98, 143, 11, 213, 83, 101, 196, 196, 228, 126, 207, 173, 195, 170, 201, 137, 50, 221, 60, 124, 88, + 114, 60, 66, 88, 59, 57, 193, 125, 192, 0, 189, 199, 178, 239, 222, 45, 212, 177, 39, 135, 135, 227, 77, + 86, 150, 246, 120, 142, 142, 104, 204, 43, 62, 151, 250, 251, 255, 103, 239, 204, 227, 163, 42, 239, 253, + 255, 62, 179, 101, 223, 87, 18, 178, 177, 4, 8, 16, 32, 128, 160, 128, 128, 224, 174, 104, 173, 90, 177, + 42, 117, 195, 165, 246, 222, 106, 111, 23, 189, 214, 253, 182, 182, 94, 109, 181, 189, 237, 175, 238, 181, + 181, 238, 87, 43, 88, 171, 87, 43, 46, 160, 178, 67, 36, 44, 97, 73, 66, 18, 8, 73, 200, 50, 89, 38, 179, + 157, 223, 31, 51, 103, 114, 230, 204, 153, 16, 200, 73, 102, 206, 100, 62, 175, 215, 243, 58, 179, 158, + 231, 57, 207, 242, 125, 62, 207, 247, 251, 125, 190, 207, 196, 149, 43, 89, 242, 244, 211, 170, 41, 216, + 125, 78, 38, 191, 147, 133, 82, 91, 85, 124, 209, 69, 92, 250, 201, 39, 92, 177, 121, 179, 95, 186, 116, + 221, 58, 230, 62, 240, 0, 9, 121, 121, 154, 229, 29, 69, 228, 97, 32, 210, 165, 118, 182, 161, 146, 104, + 41, 231, 59, 105, 158, 147, 142, 222, 169, 173, 174, 230, 103, 223, 253, 46, 183, 157, 113, 6, 155, 63, + 250, 104, 88, 159, 229, 224, 193, 131, 237, 248, 147, 171, 176, 157, 78, 195, 145, 96, 9, 138, 215, 2, 96, + 58, 118, 236, 88, 231, 112, 100, 214, 213, 222, 206, 139, 15, 63, 204, 53, 211, 166, 241, 204, 99, 143, + 209, 103, 181, 146, 134, 127, 39, 58, 145, 3, 187, 26, 177, 138, 158, 23, 24, 133, 30, 33, 159, 216, 243, + 188, 102, 66, 240, 39, 88, 141, 131, 48, 85, 149, 173, 94, 237, 79, 4, 62, 249, 132, 188, 197, 139, 125, + 223, 59, 186, 186, 52, 55, 121, 217, 173, 86, 63, 83, 91, 241, 69, 23, 13, 218, 41, 63, 181, 180, 148, 172, + 138, 10, 213, 148, 58, 105, 146, 230, 249, 157, 8, 237, 251, 246, 81, 253, 202, 43, 39, 252, 157, 57, 49, + 145, 226, 139, 46, 226, 236, 191, 253, 45, 74, 178, 162, 56, 33, 78, 69, 187, 165, 36, 87, 74, 103, 120, + 19, 30, 39, 248, 100, 96, 219, 215, 95, 243, 253, 179, 207, 230, 167, 43, 86, 176, 127, 199, 142, 97, 121, + 134, 198, 198, 70, 171, 183, 168, 202, 41, 53, 236, 166, 215, 112, 36, 88, 146, 131, 154, 95, 95, 176, 90, + 173, 93, 46, 151, 203, 166, 85, 38, 182, 158, 30, 94, 255, 237, 111, 185, 102, 218, 52, 158, 188, 239, 62, + 58, 90, 91, 73, 199, 99, 242, 27, 108, 128, 80, 57, 193, 146, 251, 96, 69, 131, 132, 70, 161, 37, 204, 39, + 136, 45, 165, 37, 186, 27, 27, 253, 124, 189, 242, 151, 44, 33, 127, 201, 18, 159, 147, 185, 86, 196, 104, + 251, 227, 143, 159, 146, 191, 211, 137, 80, 253, 183, 191, 249, 149, 127, 230, 127, 252, 135, 230, 121, + 140, 84, 126, 219, 31, 127, 156, 117, 183, 220, 66, 205, 218, 181, 52, 111, 221, 26, 144, 228, 144, 136, + 86, 20, 81, 12, 6, 106, 68, 107, 48, 59, 14, 131, 237, 52, 148, 126, 151, 140, 199, 124, 248, 241, 154, 53, + 92, 63, 119, 46, 191, 94, 189, 154, 214, 163, 71, 53, 43, 183, 40, 138, 246, 174, 174, 46, 37, 193, 10, + 219, 169, 53, 28, 157, 220, 37, 200, 119, 2, 24, 14, 31, 62, 220, 117, 252, 248, 113, 91, 86, 86, 86, 172, + 22, 55, 255, 248, 181, 215, 184, 255, 206, 59, 73, 197, 163, 226, 84, 198, 177, 26, 204, 129, 204, 242, 16, + 178, 193, 200, 84, 216, 182, 124, 20, 97, 11, 185, 111, 15, 64, 214, 9, 194, 0, 40, 157, 223, 179, 230, + 204, 1, 133, 211, 180, 239, 243, 1, 242, 145, 80, 179, 118, 45, 51, 239, 186, 11, 240, 152, 206, 228, 247, + 31, 200, 185, 92, 121, 111, 181, 221, 119, 221, 141, 141, 212, 172, 89, 67, 179, 55, 40, 166, 214, 101, 7, + 15, 49, 89, 226, 141, 59, 149, 85, 81, 161, 26, 164, 83, 153, 239, 166, 7, 31, 28, 244, 179, 157, 74, 126, + 167, 138, 230, 45, 91, 124, 117, 165, 68, 214, 236, 217, 190, 124, 33, 120, 221, 69, 17, 69, 48, 72, 243, + 147, 252, 56, 54, 121, 212, 78, 201, 249, 93, 233, 8, 47, 15, 80, 42, 125, 174, 220, 113, 104, 119, 56, + 120, 254, 153, 103, 152, 48, 123, 54, 151, 221, 114, 139, 38, 229, 109, 107, 107, 179, 213, 215, 215, 91, + 241, 87, 14, 41, 79, 15, 10, 27, 132, 43, 193, 146, 87, 152, 8, 208, 219, 219, 219, 219, 221, 221, 221, + 153, 149, 149, 149, 170, 69, 6, 169, 25, 25, 164, 224, 177, 33, 171, 17, 169, 129, 118, 6, 42, 35, 227, 6, + 211, 82, 69, 201, 85, 20, 167, 130, 158, 198, 70, 122, 142, 28, 241, 57, 127, 167, 150, 150, 146, 61, 123, + 118, 208, 137, 214, 105, 181, 250, 253, 62, 171, 162, 130, 52, 111, 8, 4, 9, 146, 9, 204, 151, 199, 145, + 35, 244, 52, 54, 6, 244, 81, 1, 168, 93, 179, 198, 71, 176, 82, 75, 75, 253, 76, 79, 181, 107, 214, 168, + 254, 71, 137, 154, 53, 107, 168, 26, 96, 178, 151, 254, 163, 117, 217, 5, 160, 101, 203, 22, 106, 215, 174, + 165, 200, 171, 209, 81, 58, 231, 11, 16, 80, 151, 165, 43, 87, 210, 184, 110, 221, 73, 105, 213, 78, 38, + 191, 193, 220, 235, 100, 209, 161, 178, 171, 52, 42, 115, 162, 24, 10, 164, 62, 173, 12, 82, 234, 38, 48, + 38, 130, 60, 64, 169, 124, 199, 161, 68, 180, 4, 60, 202, 139, 172, 156, 28, 205, 202, 103, 181, 90, 59, + 187, 186, 186, 122, 189, 111, 229, 135, 60, 135, 37, 194, 141, 96, 249, 157, 138, 141, 63, 193, 178, 53, + 55, 55, 183, 23, 23, 23, 107, 18, 206, 61, 51, 63, 223, 23, 211, 74, 233, 148, 174, 70, 174, 148, 177, 172, + 162, 26, 171, 40, 134, 19, 53, 107, 214, 80, 38, 219, 170, 191, 248, 79, 127, 162, 49, 72, 28, 172, 170, + 167, 159, 166, 234, 233, 167, 153, 35, 11, 129, 176, 216, 251, 153, 20, 75, 170, 76, 177, 237, 127, 32, + 109, 141, 195, 106, 165, 241, 211, 79, 125, 62, 83, 146, 121, 176, 99, 223, 190, 1, 67, 69, 156, 42, 180, + 44, 187, 132, 237, 143, 63, 78, 158, 204, 180, 169, 132, 195, 106, 245, 35, 69, 41, 165, 165, 92, 176, 102, + 13, 141, 235, 214, 5, 28, 165, 211, 115, 228, 200, 9, 243, 60, 81, 126, 167, 130, 226, 32, 81, 237, 229, + 223, 203, 161, 220, 165, 25, 69, 20, 131, 133, 218, 98, 37, 88, 68, 120, 121, 204, 44, 185, 54, 75, 158, + 28, 222, 251, 36, 0, 153, 26, 106, 116, 143, 31, 63, 222, 110, 179, 217, 250, 188, 111, 197, 32, 41, 108, + 16, 110, 4, 75, 130, 188, 178, 220, 130, 32, 136, 162, 40, 218, 107, 107, 107, 219, 231, 206, 157, 171, 73, + 6, 233, 217, 217, 36, 196, 199, 227, 232, 233, 81, 221, 249, 39, 247, 167, 26, 109, 65, 66, 165, 141, 182, + 131, 209, 84, 68, 49, 60, 168, 126, 229, 21, 242, 151, 44, 33, 69, 230, 52, 157, 183, 120, 177, 159, 163, + 184, 132, 42, 239, 17, 50, 89, 179, 103, 251, 8, 131, 57, 49, 145, 25, 94, 45, 148, 18, 205, 91, 183, 14, + 168, 93, 2, 143, 35, 187, 50, 175, 83, 217, 61, 56, 24, 104, 93, 118, 240, 16, 168, 170, 167, 159, 14, 122, + 31, 240, 144, 162, 172, 217, 179, 125, 36, 198, 156, 152, 232, 43, 131, 50, 207, 19, 17, 172, 193, 228, + 119, 178, 40, 186, 248, 226, 147, 138, 228, 62, 152, 122, 137, 98, 232, 80, 206, 224, 74, 167, 97, 189, 67, + 105, 133, 145, 179, 22, 233, 25, 213, 206, 56, 84, 42, 30, 68, 192, 18, 19, 67, 154, 134, 26, 172, 67, 135, + 14, 181, 187, 221, 110, 155, 55, 6, 150, 252, 136, 156, 176, 34, 86, 18, 194, 209, 201, 29, 2, 181, 88, + 110, 192, 221, 217, 217, 217, 170, 85, 6, 241, 201, 201, 164, 165, 167, 123, 130, 108, 169, 36, 229, 206, + 192, 209, 112, 172, 141, 8, 8, 70, 35, 150, 248, 120, 204, 113, 113, 24, 204, 102, 48, 24, 112, 11, 2, 78, + 160, 15, 176, 1, 189, 222, 212, 227, 77, 189, 222, 207, 251, 0, 59, 253, 129, 233, 194, 114, 73, 161, 19, + 56, 172, 86, 214, 221, 114, 11, 181, 39, 65, 106, 54, 61, 240, 0, 155, 31, 124, 80, 213, 116, 4, 30, 77, + 76, 213, 211, 79, 243, 169, 66, 35, 164, 6, 53, 71, 246, 193, 236, 30, 60, 85, 104, 89, 118, 9, 213, 127, + 251, 91, 208, 251, 129, 167, 142, 255, 239, 234, 171, 79, 170, 142, 135, 146, 223, 112, 193, 209, 213, 197, + 230, 7, 31, 84, 61, 196, 58, 138, 224, 144, 79, 46, 46, 60, 90, 23, 59, 253, 50, 78, 46, 223, 164, 100, + 243, 254, 206, 9, 96, 48, 128, 193, 128, 41, 54, 22, 115, 124, 60, 166, 216, 216, 136, 146, 117, 74, 71, + 248, 193, 28, 189, 99, 150, 93, 13, 64, 90, 70, 6, 137, 41, 41, 154, 149, 201, 203, 1, 164, 3, 158, 195, + 126, 138, 17, 68, 49, 244, 101, 107, 108, 108, 164, 180, 180, 148, 238, 238, 110, 65, 16, 4, 3, 158, 246, + 137, 193, 179, 33, 33, 1, 72, 18, 69, 209, 124, 247, 221, 119, 223, 244, 139, 95, 252, 98, 240, 18, 246, 4, + 184, 179, 162, 130, 131, 219, 182, 145, 72, 255, 118, 83, 41, 13, 116, 24, 179, 132, 72, 34, 86, 224, 17, + 28, 99, 38, 79, 230, 250, 181, 107, 49, 152, 76, 216, 187, 186, 112, 57, 28, 184, 236, 118, 28, 189, 189, + 56, 108, 54, 28, 61, 61, 216, 58, 59, 233, 179, 90, 177, 181, 181, 209, 219, 222, 78, 175, 247, 218, 115, + 252, 56, 61, 173, 173, 244, 117, 118, 98, 235, 232, 160, 207, 106, 197, 233, 118, 251, 14, 24, 149, 15, 88, + 249, 6, 129, 72, 169, 199, 225, 196, 64, 142, 238, 106, 190, 89, 230, 164, 164, 128, 99, 96, 130, 77, 192, + 169, 165, 165, 190, 157, 138, 237, 251, 246, 249, 252, 144, 228, 159, 59, 172, 86, 63, 243, 160, 188, 60, + 82, 254, 242, 223, 15, 148, 223, 137, 160, 69, 217, 37, 36, 228, 229, 5, 28, 57, 51, 152, 123, 201, 33, + 127, 118, 173, 242, 27, 76, 93, 5, 43, 79, 176, 178, 69, 225, 15, 63, 51, 8, 254, 179, 50, 244, 147, 5, 75, + 76, 12, 49, 41, 41, 196, 38, 39, 19, 155, 154, 74, 66, 70, 6, 113, 233, 233, 196, 166, 164, 16, 159, 150, + 70, 108, 106, 42, 113, 169, 169, 196, 36, 37, 97, 73, 76, 196, 146, 144, 128, 209, 108, 198, 146, 152, 136, + 32, 8, 88, 18, 18, 136, 73, 78, 102, 223, 7, 31, 240, 183, 85, 171, 48, 17, 121, 150, 13, 53, 191, 29, 101, + 189, 74, 11, 107, 137, 168, 118, 1, 37, 51, 102, 240, 196, 182, 109, 8, 130, 54, 53, 113, 255, 253, 247, + 63, 251, 208, 67, 15, 61, 35, 8, 130, 29, 176, 2, 221, 120, 184, 111, 159, 55, 107, 183, 40, 138, 226, 235, + 175, 191, 206, 21, 87, 92, 161, 73, 158, 67, 129, 30, 76, 132, 62, 85, 96, 67, 67, 131, 102, 26, 44, 128, + 140, 236, 108, 106, 233, 215, 82, 89, 240, 103, 233, 114, 98, 5, 145, 73, 6, 228, 118, 118, 1, 232, 110, + 105, 33, 38, 57, 153, 196, 33, 156, 47, 101, 239, 234, 194, 214, 209, 129, 173, 179, 147, 174, 166, 38, 58, + 143, 30, 165, 179, 177, 145, 246, 218, 90, 218, 15, 31, 166, 179, 161, 129, 206, 198, 70, 122, 90, 90, 232, + 179, 217, 112, 202, 242, 87, 211, 16, 70, 225, 113, 164, 14, 6, 181, 58, 114, 90, 173, 1, 255, 9, 86, 151, + 74, 173, 139, 112, 130, 207, 149, 229, 25, 204, 239, 79, 6, 90, 148, 93, 66, 79, 99, 163, 106, 4, 249, 193, + 220, 75, 237, 63, 90, 229, 55, 152, 186, 26, 172, 54, 108, 180, 143, 17, 105, 146, 144, 22, 114, 18, 137, + 50, 0, 22, 131, 129, 216, 164, 36, 146, 114, 115, 73, 202, 203, 35, 117, 236, 88, 82, 11, 11, 73, 41, 44, + 36, 57, 55, 151, 164, 49, 99, 136, 79, 79, 247, 145, 43, 163, 217, 124, 234, 229, 240, 46, 38, 165, 73, 53, + 146, 72, 150, 244, 12, 74, 162, 37, 249, 102, 201, 143, 224, 145, 190, 51, 226, 113, 197, 209, 138, 92, 1, + 212, 213, 213, 73, 26, 172, 176, 246, 189, 146, 16, 174, 4, 11, 20, 228, 10, 16, 142, 31, 63, 126, 92, 203, + 12, 114, 10, 11, 125, 78, 238, 74, 31, 44, 53, 114, 21, 105, 144, 147, 43, 240, 12, 136, 158, 214, 86, 172, + 71, 143, 14, 137, 96, 89, 18, 19, 177, 36, 38, 146, 156, 159, 79, 246, 148, 41, 42, 25, 139, 216, 123, 122, + 232, 58, 118, 140, 206, 134, 6, 142, 31, 60, 72, 203, 190, 125, 180, 236, 219, 71, 235, 254, 253, 116, 28, + 62, 76, 119, 107, 43, 14, 81, 244, 217, 250, 229, 230, 217, 40, 162, 136, 98, 116, 66, 110, 210, 147, 220, + 16, 76, 64, 76, 76, 12, 233, 185, 185, 164, 141, 27, 71, 230, 196, 137, 158, 84, 90, 74, 106, 97, 33, 73, + 99, 198, 16, 151, 150, 134, 209, 98, 25, 214, 178, 117, 212, 215, 7, 132, 56, 128, 200, 157, 59, 164, 171, + 212, 38, 202, 5, 177, 9, 207, 28, 171, 37, 142, 31, 63, 222, 74, 191, 27, 88, 88, 147, 43, 8, 63, 130, 21, + 108, 87, 128, 27, 96, 255, 254, 253, 199, 93, 46, 151, 211, 104, 52, 106, 82, 238, 204, 177, 99, 3, 130, + 172, 41, 77, 130, 16, 153, 3, 68, 14, 121, 37, 219, 69, 145, 246, 134, 6, 198, 76, 159, 62, 124, 25, 122, + 213, 234, 233, 37, 37, 164, 151, 148, 80, 188, 112, 161, 172, 48, 34, 221, 173, 173, 116, 212, 213, 113, + 108, 207, 30, 154, 42, 43, 57, 90, 89, 201, 177, 61, 123, 232, 56, 124, 24, 155, 221, 238, 35, 93, 146, + 111, 92, 164, 183, 79, 20, 81, 140, 70, 72, 114, 73, 238, 211, 105, 6, 18, 82, 83, 73, 31, 63, 158, 156, + 169, 83, 201, 157, 49, 131, 156, 178, 50, 50, 38, 78, 36, 57, 47, 15, 115, 92, 92, 200, 202, 107, 109, 109, + 245, 105, 209, 228, 187, 238, 164, 133, 108, 36, 65, 249, 60, 210, 115, 202, 119, 24, 130, 103, 142, 213, + 10, 46, 151, 203, 85, 93, 93, 221, 230, 125, 43, 87, 190, 132, 173, 38, 43, 220, 8, 150, 18, 126, 149, 214, + 221, 221, 109, 237, 233, 233, 233, 74, 74, 74, 210, 36, 22, 86, 70, 65, 65, 128, 47, 80, 36, 58, 175, 15, + 4, 165, 45, 189, 15, 176, 54, 53, 133, 174, 64, 130, 64, 66, 102, 38, 9, 153, 153, 228, 201, 118, 80, 57, + 251, 250, 104, 175, 173, 165, 169, 170, 138, 198, 45, 91, 104, 216, 178, 133, 163, 59, 119, 210, 209, 216, + 136, 221, 235, 71, 40, 39, 92, 163, 161, 237, 36, 56, 192, 143, 116, 142, 166, 103, 143, 52, 72, 230, 114, + 23, 253, 39, 68, 140, 22, 72, 114, 72, 34, 84, 6, 32, 33, 46, 142, 156, 9, 19, 200, 171, 168, 32, 127, 206, + 28, 242, 102, 204, 32, 115, 210, 36, 18, 178, 178, 52, 53, 61, 105, 129, 174, 214, 214, 0, 109, 78, 36, + 146, 43, 57, 228, 187, 10, 149, 243, 167, 17, 207, 28, 171, 21, 122, 123, 123, 187, 186, 187, 187, 165, 35, + 243, 228, 228, 42, 108, 17, 174, 4, 75, 85, 131, 213, 220, 220, 108, 61, 122, 244, 104, 167, 102, 4, 171, + 176, 208, 207, 94, 30, 201, 190, 86, 106, 80, 115, 86, 116, 1, 29, 199, 142, 133, 178, 88, 170, 48, 197, + 196, 144, 89, 90, 74, 102, 105, 41, 83, 47, 189, 20, 240, 248, 122, 53, 239, 219, 71, 195, 166, 77, 212, + 172, 95, 79, 253, 166, 77, 180, 238, 223, 143, 205, 233, 244, 252, 135, 200, 52, 43, 250, 180, 141, 120, + 158, 175, 160, 188, 156, 211, 127, 240, 3, 108, 237, 237, 172, 249, 201, 79, 16, 68, 209, 55, 49, 143, 134, + 126, 172, 119, 72, 51, 132, 200, 167, 169, 148, 0, 0, 32, 0, 73, 68, 65, 84, 13, 40, 152, 62, 157, 11, 30, + 125, 148, 61, 239, 189, 199, 142, 87, 94, 161, 173, 173, 205, 231, 198, 16, 105, 114, 73, 73, 168, 140, 64, + 82, 106, 42, 185, 229, 229, 20, 204, 159, 79, 209, 130, 5, 140, 153, 49, 131, 212, 177, 99, 17, 140, 225, + 79, 53, 187, 59, 59, 3, 54, 244, 64, 100, 181, 217, 96, 33, 17, 172, 204, 226, 98, 205, 238, 217, 212, 212, + 212, 217, 210, 210, 98, 197, 223, 213, 43, 44, 53, 87, 18, 244, 64, 176, 124, 27, 63, 108, 54, 155, 173, + 181, 181, 181, 109, 226, 196, 137, 154, 24, 118, 83, 114, 114, 136, 49, 153, 16, 189, 19, 242, 104, 132, + 178, 162, 157, 120, 84, 221, 122, 128, 37, 49, 145, 252, 138, 10, 242, 43, 42, 56, 237, 150, 91, 112, 59, + 28, 180, 84, 87, 83, 247, 245, 215, 28, 90, 183, 142, 218, 13, 27, 104, 61, 120, 144, 30, 183, 91, 247, 38, + 69, 249, 78, 79, 7, 144, 148, 144, 64, 249, 69, 23, 49, 247, 230, 155, 25, 183, 120, 49, 6, 147, 103, 40, + 199, 165, 167, 243, 250, 234, 213, 56, 93, 46, 76, 178, 255, 233, 241, 153, 35, 29, 242, 25, 161, 23, 40, + 174, 168, 96, 213, 59, 239, 144, 82, 80, 64, 233, 5, 23, 176, 236, 254, 251, 217, 241, 218, 107, 108, 126, + 238, 57, 14, 239, 216, 129, 11, 207, 214, 106, 189, 250, 246, 200, 157, 209, 29, 120, 158, 35, 49, 49, 145, + 162, 25, 51, 24, 183, 120, 49, 197, 139, 22, 145, 87, 81, 65, 98, 118, 118, 72, 203, 121, 170, 232, 237, + 234, 242, 45, 84, 149, 110, 38, 163, 13, 34, 16, 99, 48, 144, 172, 97, 91, 182, 180, 180, 180, 247, 244, + 244, 216, 208, 9, 185, 130, 240, 36, 88, 3, 237, 8, 117, 52, 54, 54, 54, 107, 149, 81, 74, 110, 46, 113, + 169, 169, 216, 90, 90, 252, 50, 30, 13, 16, 21, 175, 229, 219, 109, 187, 218, 218, 84, 255, 19, 238, 48, + 152, 205, 100, 151, 149, 145, 93, 86, 198, 156, 235, 175, 199, 213, 215, 71, 83, 85, 21, 7, 63, 249, 132, + 234, 143, 62, 162, 254, 235, 175, 233, 56, 126, 28, 55, 253, 230, 151, 112, 215, 110, 201, 181, 85, 0, 99, + 38, 76, 160, 98, 213, 42, 102, 93, 123, 45, 105, 69, 69, 1, 191, 159, 125, 195, 13, 96, 52, 242, 218, 141, + 55, 98, 119, 185, 124, 154, 143, 72, 55, 85, 232, 13, 114, 33, 215, 3, 148, 84, 84, 112, 253, 218, 181, 36, + 201, 66, 60, 36, 100, 103, 115, 198, 15, 126, 192, 252, 219, 110, 227, 208, 103, 159, 177, 241, 233, 167, + 169, 90, 187, 150, 174, 238, 110, 223, 198, 28, 61, 180, 169, 68, 168, 92, 64, 172, 193, 64, 246, 132, 9, + 140, 91, 178, 132, 9, 103, 159, 77, 209, 233, 167, 147, 156, 159, 31, 226, 18, 106, 131, 110, 171, 213, 39, + 67, 37, 159, 164, 209, 52, 167, 64, 255, 243, 186, 128, 184, 180, 52, 82, 52, 12, 50, 122, 228, 200, 145, + 99, 120, 68, 161, 50, 234, 70, 216, 18, 173, 112, 36, 88, 114, 248, 42, 206, 27, 205, 221, 185, 111, 223, + 190, 22, 173, 110, 30, 159, 154, 74, 98, 70, 6, 221, 45, 45, 225, 215, 50, 35, 4, 53, 51, 97, 119, 71, 71, + 72, 203, 164, 21, 140, 49, 49, 228, 205, 154, 69, 222, 172, 89, 44, 188, 235, 46, 186, 91, 90, 168, 93, + 191, 158, 61, 239, 189, 199, 129, 143, 63, 166, 249, 224, 65, 156, 248, 239, 28, 13, 135, 9, 75, 234, 139, + 78, 60, 210, 36, 206, 98, 97, 250, 242, 229, 156, 182, 122, 53, 165, 231, 157, 135, 41, 38, 102, 192, 255, + 207, 94, 181, 138, 152, 196, 68, 254, 242, 221, 239, 226, 232, 235, 139, 146, 172, 48, 131, 124, 204, 245, + 0, 165, 11, 22, 176, 234, 127, 255, 55, 168, 230, 198, 96, 50, 49, 254, 172, 179, 24, 127, 214, 89, 180, + 215, 213, 177, 237, 175, 127, 101, 235, 139, 47, 210, 88, 93, 13, 120, 194, 203, 132, 147, 182, 68, 210, + 82, 57, 241, 200, 147, 132, 184, 56, 138, 231, 204, 97, 210, 249, 231, 51, 241, 220, 115, 201, 157, 54, + 109, 216, 119, 244, 133, 2, 78, 151, 75, 31, 91, 219, 134, 25, 82, 251, 39, 101, 100, 144, 144, 150, 166, + 217, 125, 247, 237, 219, 215, 10, 56, 189, 81, 220, 117, 81, 205, 225, 74, 176, 212, 180, 87, 110, 64, 108, + 105, 105, 209, 204, 3, 219, 104, 50, 145, 86, 80, 64, 163, 236, 124, 55, 121, 166, 225, 34, 176, 134, 27, + 202, 138, 182, 247, 245, 13, 252, 7, 157, 34, 33, 51, 147, 178, 75, 46, 161, 236, 146, 75, 112, 218, 108, + 212, 111, 222, 204, 158, 247, 222, 99, 207, 154, 53, 28, 221, 189, 27, 187, 219, 29, 50, 178, 37, 215, 104, + 72, 75, 180, 172, 252, 124, 102, 126, 247, 187, 204, 185, 254, 122, 178, 38, 79, 62, 169, 251, 77, 251, + 246, 183, 185, 214, 96, 224, 165, 149, 43, 177, 247, 245, 97, 33, 74, 178, 194, 1, 242, 177, 214, 13, 76, + 58, 243, 76, 110, 120, 231, 29, 226, 6, 57, 17, 165, 22, 22, 178, 244, 158, 123, 88, 116, 215, 93, 236, + 251, 240, 67, 54, 62, 243, 12, 251, 62, 252, 144, 30, 187, 221, 167, 213, 130, 208, 244, 93, 55, 30, 77, + 149, 8, 36, 37, 39, 83, 188, 112, 33, 101, 151, 94, 202, 196, 229, 203, 73, 43, 41, 25, 193, 18, 105, 135, + 190, 158, 30, 58, 90, 90, 200, 42, 40, 24, 208, 169, 222, 229, 112, 96, 235, 233, 81, 157, 245, 35, 125, + 204, 169, 61, 179, 27, 72, 43, 44, 28, 82, 92, 49, 37, 188, 115, 191, 31, 31, 8, 146, 125, 216, 32, 92, 9, + 150, 132, 128, 10, 220, 189, 123, 183, 102, 38, 66, 128, 180, 252, 124, 125, 108, 71, 24, 1, 72, 207, 223, + 215, 211, 51, 224, 239, 58, 91, 91, 249, 234, 253, 247, 249, 232, 229, 151, 137, 75, 72, 224, 236, 107, + 174, 161, 226, 172, 179, 136, 79, 78, 30, 254, 66, 106, 4, 83, 108, 44, 197, 11, 23, 82, 188, 112, 33, 231, + 60, 252, 48, 71, 119, 238, 100, 215, 223, 255, 206, 174, 183, 222, 226, 72, 85, 21, 14, 81, 244, 197, 70, + 27, 110, 225, 40, 173, 248, 236, 128, 197, 104, 164, 116, 193, 2, 230, 222, 124, 51, 101, 151, 92, 66, 204, + 9, 34, 121, 15, 132, 105, 223, 250, 22, 87, 255, 249, 207, 188, 116, 245, 213, 56, 220, 110, 221, 152, 148, + 34, 21, 74, 205, 85, 201, 236, 217, 124, 239, 205, 55, 7, 77, 174, 228, 48, 197, 198, 82, 182, 98, 5, 101, + 43, 86, 208, 188, 119, 47, 91, 94, 120, 129, 109, 47, 191, 76, 115, 125, 189, 39, 192, 38, 35, 99, 254, + 150, 204, 127, 110, 32, 41, 49, 145, 201, 75, 150, 80, 254, 157, 239, 48, 97, 217, 50, 63, 115, 167, 158, + 224, 116, 56, 216, 187, 105, 19, 159, 191, 253, 54, 27, 222, 125, 151, 166, 218, 90, 166, 47, 90, 196, 57, + 215, 94, 203, 252, 139, 46, 34, 57, 61, 61, 224, 63, 34, 32, 138, 226, 168, 159, 71, 228, 126, 118, 105, + 26, 155, 126, 171, 170, 170, 164, 185, 63, 236, 137, 149, 132, 112, 37, 88, 114, 231, 118, 57, 99, 165, + 173, 173, 237, 56, 253, 102, 238, 33, 35, 107, 220, 184, 128, 207, 70, 83, 152, 6, 181, 221, 46, 130, 33, + 176, 106, 251, 122, 122, 216, 241, 233, 167, 124, 244, 202, 43, 124, 253, 254, 251, 28, 105, 105, 241, 253, + 254, 195, 183, 222, 98, 108, 94, 30, 243, 46, 184, 128, 165, 223, 249, 14, 211, 23, 46, 196, 18, 27, 59, 2, + 165, 215, 6, 6, 147, 137, 188, 138, 10, 242, 42, 42, 88, 246, 243, 159, 211, 176, 101, 11, 149, 111, 188, + 65, 213, 219, 111, 211, 116, 240, 32, 110, 250, 163, 252, 107, 217, 39, 164, 21, 191, 19, 72, 207, 204, + 100, 250, 149, 87, 50, 231, 134, 27, 200, 31, 224, 88, 156, 147, 197, 204, 239, 124, 7, 167, 205, 198, 171, + 55, 220, 128, 211, 171, 161, 27, 205, 187, 155, 66, 5, 53, 135, 246, 155, 214, 174, 37, 97, 8, 1, 125, 37, + 100, 77, 154, 196, 121, 143, 62, 202, 210, 123, 239, 101, 247, 187, 239, 178, 233, 233, 167, 57, 248, 197, + 23, 244, 184, 92, 196, 48, 60, 253, 214, 137, 167, 239, 198, 199, 196, 48, 97, 193, 2, 166, 127, 231, 59, + 76, 190, 240, 66, 221, 250, 83, 57, 237, 118, 246, 110, 222, 204, 231, 239, 188, 195, 87, 107, 214, 112, + 112, 239, 94, 108, 162, 232, 27, 247, 95, 124, 244, 17, 159, 127, 244, 17, 121, 217, 217, 44, 184, 248, 98, + 206, 190, 230, 26, 166, 46, 88, 128, 73, 161, 161, 81, 206, 29, 163, 101, 46, 81, 123, 190, 108, 149, 185, + 117, 8, 112, 183, 181, 181, 73, 187, 175, 116, 115, 22, 97, 56, 18, 44, 185, 70, 85, 78, 180, 220, 128, 80, + 87, 87, 215, 214, 209, 209, 209, 147, 146, 146, 146, 168, 69, 102, 89, 197, 197, 225, 221, 66, 195, 4, 121, + 4, 119, 57, 12, 128, 195, 102, 3, 60, 43, 178, 125, 27, 55, 178, 238, 181, 215, 248, 252, 237, 183, 57, 84, + 83, 131, 3, 207, 78, 38, 121, 229, 139, 192, 209, 198, 70, 94, 127, 246, 89, 222, 122, 246, 89, 74, 198, + 143, 103, 246, 217, 103, 115, 254, 170, 85, 148, 205, 159, 63, 220, 143, 162, 41, 12, 38, 19, 5, 243, 230, + 81, 48, 111, 30, 103, 63, 242, 8, 53, 159, 125, 198, 246, 151, 95, 102, 207, 218, 181, 180, 31, 63, 238, + 211, 14, 156, 170, 208, 148, 107, 171, 140, 64, 209, 156, 57, 204, 190, 225, 6, 202, 175, 188, 146, 248, + 140, 12, 237, 30, 68, 134, 57, 171, 86, 225, 114, 56, 120, 245, 230, 155, 253, 4, 126, 164, 155, 46, 194, + 5, 74, 205, 85, 94, 89, 25, 55, 174, 89, 67, 82, 110, 174, 166, 249, 196, 36, 38, 50, 243, 234, 171, 153, + 121, 245, 213, 52, 110, 221, 202, 166, 231, 158, 163, 242, 245, 215, 57, 222, 210, 226, 59, 212, 254, 84, + 250, 173, 220, 39, 208, 129, 103, 210, 200, 47, 47, 167, 252, 170, 171, 152, 118, 249, 229, 100, 78, 156, + 168, 221, 67, 132, 0, 91, 62, 254, 152, 95, 174, 90, 69, 99, 67, 131, 79, 190, 89, 128, 36, 250, 235, 74, + 218, 145, 123, 252, 216, 49, 222, 124, 238, 57, 214, 62, 247, 28, 147, 202, 202, 88, 122, 213, 85, 44, 94, + 185, 146, 156, 113, 227, 2, 22, 166, 163, 117, 108, 73, 125, 61, 83, 67, 179, 112, 103, 103, 103, 79, 109, + 109, 237, 113, 212, 163, 184, 135, 45, 209, 10, 71, 130, 37, 71, 128, 15, 86, 123, 123, 187, 181, 163, 163, + 163, 93, 43, 130, 149, 86, 88, 136, 25, 245, 150, 26, 45, 3, 68, 62, 233, 154, 240, 4, 26, 253, 251, 175, + 126, 197, 231, 175, 189, 70, 213, 246, 237, 116, 121, 227, 42, 197, 171, 252, 15, 60, 117, 37, 157, 229, + 232, 6, 118, 29, 56, 64, 91, 103, 39, 139, 47, 187, 108, 132, 158, 96, 120, 96, 142, 141, 101, 226, 57, + 231, 48, 241, 156, 115, 232, 110, 105, 97, 247, 187, 239, 178, 245, 165, 151, 168, 89, 191, 30, 155, 211, + 233, 51, 33, 194, 192, 125, 69, 234, 79, 210, 4, 149, 156, 156, 204, 172, 21, 43, 152, 123, 243, 205, 20, + 47, 92, 168, 170, 49, 212, 26, 243, 110, 186, 137, 190, 174, 46, 222, 186, 243, 78, 98, 233, 55, 125, 142, + 166, 126, 30, 10, 200, 229, 73, 47, 30, 141, 249, 141, 107, 214, 144, 156, 151, 55, 172, 249, 230, 85, 84, + 112, 73, 69, 5, 103, 63, 244, 16, 149, 175, 191, 206, 230, 231, 159, 167, 110, 203, 22, 156, 50, 173, 12, + 12, 174, 223, 74, 62, 129, 233, 217, 217, 148, 93, 122, 41, 179, 174, 189, 150, 194, 249, 243, 125, 161, + 65, 244, 142, 233, 11, 23, 114, 206, 181, 215, 242, 226, 163, 143, 18, 11, 196, 18, 156, 136, 154, 101, + 223, 31, 172, 170, 98, 255, 125, 247, 241, 206, 47, 126, 65, 249, 130, 5, 88, 155, 154, 84, 125, 224, 34, + 125, 124, 169, 205, 157, 102, 32, 93, 195, 99, 114, 58, 58, 58, 218, 219, 219, 219, 173, 65, 178, 11, 91, + 8, 162, 24, 250, 242, 53, 54, 54, 82, 90, 90, 74, 119, 119, 183, 228, 72, 40, 69, 220, 183, 224, 233, 207, + 113, 64, 162, 40, 138, 201, 64, 194, 23, 95, 124, 241, 155, 5, 11, 22, 204, 208, 34, 239, 166, 253, 251, + 185, 127, 234, 84, 4, 187, 221, 55, 241, 152, 232, 63, 112, 56, 146, 33, 63, 5, 93, 154, 252, 29, 120, 2, + 30, 118, 208, 31, 207, 69, 121, 10, 61, 168, 31, 254, 233, 192, 227, 184, 187, 236, 226, 139, 249, 209, 51, + 207, 144, 166, 225, 22, 221, 112, 194, 209, 157, 59, 217, 250, 151, 191, 176, 243, 213, 87, 105, 169, 175, + 71, 192, 35, 80, 212, 250, 139, 60, 196, 66, 254, 148, 41, 204, 190, 254, 122, 102, 94, 125, 117, 200, 76, + 41, 31, 62, 240, 0, 107, 31, 124, 144, 120, 252, 77, 71, 145, 62, 9, 132, 2, 114, 231, 111, 27, 144, 156, + 155, 203, 173, 31, 126, 72, 238, 112, 30, 67, 21, 172, 44, 110, 55, 53, 235, 215, 179, 233, 153, 103, 168, + 250, 251, 223, 233, 236, 236, 244, 115, 138, 87, 66, 146, 7, 22, 163, 145, 146, 5, 11, 152, 125, 253, 245, + 148, 173, 88, 65, 156, 138, 255, 81, 164, 224, 139, 255, 253, 95, 126, 125, 211, 77, 116, 180, 181, 145, + 64, 160, 121, 79, 41, 255, 148, 231, 163, 38, 226, 153, 172, 228, 231, 218, 74, 191, 137, 228, 241, 165, + 156, 71, 108, 128, 104, 177, 240, 80, 85, 21, 217, 227, 199, 107, 146, 199, 134, 13, 27, 118, 44, 88, 176, + 224, 46, 160, 75, 16, 132, 78, 160, 11, 207, 154, 197, 134, 71, 196, 74, 49, 94, 17, 69, 145, 215, 95, 127, + 157, 43, 174, 184, 66, 147, 188, 135, 130, 112, 93, 130, 200, 231, 109, 159, 22, 75, 16, 4, 183, 40, 138, + 246, 134, 134, 6, 205, 66, 53, 36, 101, 102, 146, 144, 149, 133, 181, 161, 65, 31, 148, 120, 24, 32, 63, + 38, 72, 10, 200, 153, 68, 255, 128, 81, 18, 44, 249, 164, 44, 95, 157, 155, 205, 102, 238, 124, 232, 33, + 174, 252, 217, 207, 70, 174, 240, 33, 64, 110, 121, 57, 23, 60, 246, 24, 203, 238, 187, 143, 61, 107, 215, + 178, 249, 249, 231, 57, 240, 233, 167, 244, 56, 28, 190, 248, 90, 146, 243, 111, 124, 92, 28, 51, 206, 61, + 151, 211, 110, 190, 153, 9, 203, 151, 135, 124, 123, 250, 57, 15, 60, 64, 247, 241, 227, 124, 242, 187, + 223, 17, 79, 127, 155, 71, 53, 89, 218, 66, 46, 75, 236, 64, 108, 82, 18, 223, 123, 243, 205, 144, 144, 43, + 240, 248, 85, 150, 44, 90, 68, 201, 162, 69, 116, 54, 54, 178, 253, 229, 151, 217, 242, 194, 11, 52, 238, + 222, 237, 243, 49, 20, 232, 143, 87, 149, 153, 155, 203, 244, 43, 174, 160, 226, 123, 223, 35, 95, 118, + 100, 85, 36, 99, 225, 101, 151, 81, 80, 90, 202, 175, 174, 190, 154, 125, 149, 149, 36, 225, 31, 254, 66, + 73, 176, 228, 36, 75, 185, 251, 120, 180, 248, 94, 73, 144, 247, 119, 23, 144, 156, 157, 77, 98, 102, 166, + 102, 247, 175, 175, 175, 111, 1, 250, 4, 65, 8, 230, 127, 21, 150, 211, 118, 184, 18, 44, 80, 49, 15, 122, + 175, 174, 67, 135, 14, 53, 106, 149, 73, 124, 106, 42, 105, 185, 185, 88, 27, 26, 252, 72, 198, 104, 208, + 96, 169, 9, 0, 121, 143, 149, 212, 136, 110, 217, 119, 202, 255, 185, 241, 44, 37, 138, 139, 138, 248, 193, + 139, 47, 50, 109, 201, 146, 97, 43, 111, 184, 33, 38, 41, 137, 25, 43, 87, 50, 99, 229, 74, 142, 126, 243, + 13, 91, 158, 127, 158, 157, 175, 188, 66, 235, 209, 163, 100, 23, 23, 51, 235, 154, 107, 168, 88, 181, 138, + 140, 9, 19, 66, 93, 84, 63, 124, 235, 201, 39, 233, 62, 118, 140, 205, 175, 189, 166, 186, 82, 143, 98, + 104, 144, 200, 170, 116, 244, 148, 193, 108, 230, 154, 191, 254, 149, 226, 5, 11, 66, 91, 48, 47, 146, 243, + 242, 56, 243, 199, 63, 102, 193, 15, 127, 200, 129, 143, 63, 102, 227, 211, 79, 179, 231, 31, 255, 192, + 209, 215, 199, 132, 211, 79, 103, 246, 205, 55, 51, 237, 91, 223, 34, 54, 85, 147, 19, 201, 116, 133, 162, + 105, 211, 120, 236, 243, 207, 249, 127, 55, 222, 200, 103, 111, 189, 229, 179, 106, 64, 224, 12, 174, 92, + 148, 74, 26, 65, 185, 246, 74, 250, 62, 210, 199, 150, 136, 255, 115, 166, 229, 230, 18, 159, 146, 162, + 217, 253, 189, 115, 190, 164, 165, 146, 115, 131, 176, 214, 137, 232, 129, 96, 5, 16, 173, 234, 234, 106, + 77, 15, 203, 203, 40, 42, 226, 208, 150, 45, 170, 43, 143, 72, 31, 24, 146, 144, 16, 241, 8, 4, 185, 255, + 153, 116, 34, 188, 59, 200, 255, 92, 120, 52, 87, 75, 46, 184, 128, 155, 158, 123, 142, 20, 141, 157, 118, + 245, 132, 220, 105, 211, 184, 240, 137, 39, 88, 114, 207, 61, 28, 217, 190, 157, 177, 115, 231, 18, 171, + 161, 128, 209, 20, 130, 192, 119, 158, 127, 158, 238, 99, 199, 216, 251, 201, 39, 36, 200, 191, 10, 89, + 161, 34, 3, 210, 216, 145, 4, 150, 19, 184, 242, 15, 127, 160, 108, 197, 138, 144, 150, 75, 13, 70, 179, + 153, 210, 243, 206, 163, 244, 188, 243, 104, 170, 170, 194, 214, 209, 65, 225, 188, 121, 35, 226, 19, 24, + 206, 72, 72, 73, 225, 71, 111, 190, 201, 248, 7, 31, 228, 173, 7, 31, 196, 224, 13, 217, 162, 70, 176, 36, + 57, 41, 55, 7, 202, 137, 149, 252, 240, 227, 72, 132, 212, 223, 229, 201, 5, 100, 20, 23, 107, 154, 79, + 117, 117, 181, 50, 6, 150, 46, 118, 17, 134, 251, 72, 82, 117, 104, 59, 114, 228, 136, 102, 193, 70, 1, + 178, 38, 76, 8, 160, 198, 97, 219, 98, 26, 67, 105, 30, 148, 14, 150, 149, 156, 214, 45, 244, 239, 170, + 145, 39, 0, 179, 209, 200, 170, 135, 31, 230, 174, 181, 107, 71, 53, 185, 146, 35, 33, 51, 147, 9, 203, + 151, 135, 47, 185, 242, 194, 28, 31, 207, 119, 95, 121, 133, 252, 105, 211, 232, 97, 244, 245, 251, 225, + 128, 220, 231, 74, 90, 124, 156, 123, 255, 253, 156, 118, 211, 77, 161, 43, 212, 32, 145, 83, 86, 70, 209, + 233, 167, 143, 122, 114, 37, 199, 165, 247, 223, 207, 93, 111, 190, 73, 74, 106, 170, 207, 140, 26, 76, 38, + 74, 26, 44, 137, 92, 69, 42, 161, 82, 131, 82, 11, 226, 2, 50, 181, 13, 209, 64, 67, 67, 131, 52, 231, 235, + 202, 201, 93, 15, 163, 73, 201, 90, 217, 191, 127, 127, 171, 211, 233, 180, 15, 248, 175, 147, 64, 214, + 184, 113, 170, 118, 246, 72, 135, 114, 229, 33, 17, 44, 137, 100, 153, 9, 20, 40, 102, 60, 3, 40, 183, 160, + 128, 31, 127, 240, 1, 23, 222, 123, 239, 128, 17, 142, 163, 8, 95, 36, 230, 228, 112, 205, 171, 175, 146, + 156, 155, 75, 31, 58, 145, 88, 97, 14, 121, 56, 134, 211, 175, 191, 158, 179, 31, 120, 32, 180, 5, 138, 98, + 72, 152, 117, 217, 101, 220, 253, 197, 23, 76, 40, 47, 199, 65, 191, 76, 148, 95, 165, 5, 233, 104, 211, + 94, 41, 33, 119, 33, 209, 202, 185, 29, 192, 233, 116, 218, 15, 28, 56, 112, 220, 251, 86, 169, 189, 10, + 107, 132, 51, 193, 82, 99, 170, 82, 176, 209, 246, 227, 199, 143, 183, 107, 149, 81, 246, 132, 9, 62, 243, + 152, 114, 123, 237, 104, 72, 114, 237, 149, 228, 176, 105, 86, 73, 70, 60, 38, 143, 185, 231, 159, 207, + 207, 190, 254, 154, 73, 203, 150, 157, 116, 93, 71, 17, 94, 200, 153, 58, 149, 171, 95, 122, 9, 163, 197, + 130, 211, 251, 153, 220, 60, 30, 77, 39, 78, 114, 72, 228, 106, 202, 178, 101, 92, 246, 135, 63, 156, 168, + 250, 163, 208, 1, 198, 76, 157, 202, 93, 159, 127, 206, 162, 43, 175, 196, 129, 71, 86, 202, 23, 160, 114, + 249, 40, 39, 89, 161, 238, 151, 35, 221, 255, 5, 250, 93, 77, 178, 53, 140, 141, 214, 218, 218, 218, 222, + 214, 214, 214, 230, 125, 43, 247, 199, 14, 251, 53, 97, 184, 18, 44, 229, 46, 66, 144, 109, 100, 107, 110, + 110, 238, 106, 104, 104, 208, 140, 96, 165, 230, 231, 19, 99, 177, 4, 132, 34, 24, 45, 144, 15, 22, 57, + 209, 146, 19, 46, 55, 158, 32, 156, 151, 63, 252, 48, 171, 223, 123, 143, 100, 157, 30, 131, 17, 69, 32, + 38, 158, 125, 54, 151, 62, 245, 148, 223, 94, 231, 176, 150, 90, 97, 8, 169, 190, 108, 64, 238, 164, 73, + 172, 124, 233, 37, 76, 58, 58, 205, 32, 138, 129, 17, 155, 156, 204, 170, 215, 94, 227, 242, 71, 30, 1, 65, + 192, 77, 63, 145, 26, 136, 88, 141, 38, 72, 172, 39, 54, 54, 150, 84, 13, 195, 208, 52, 52, 52, 180, 181, + 180, 180, 116, 41, 178, 145, 94, 135, 245, 46, 194, 112, 37, 88, 114, 200, 217, 170, 36, 255, 109, 141, + 141, 141, 71, 181, 202, 32, 53, 47, 143, 132, 140, 12, 92, 232, 200, 184, 171, 17, 36, 33, 160, 220, 61, + 41, 9, 14, 3, 208, 7, 100, 20, 20, 112, 251, 251, 239, 179, 60, 106, 18, 140, 72, 204, 187, 229, 22, 150, + 222, 121, 39, 61, 248, 135, 228, 24, 13, 99, 96, 40, 8, 8, 199, 144, 156, 204, 213, 127, 249, 11, 73, 195, + 28, 72, 52, 138, 208, 96, 217, 127, 254, 39, 55, 191, 253, 54, 73, 233, 233, 190, 211, 24, 36, 82, 165, 70, + 174, 34, 93, 82, 42, 231, 75, 23, 144, 152, 145, 65, 154, 134, 253, 191, 190, 190, 254, 8, 158, 105, 72, + 114, 241, 146, 115, 130, 176, 70, 56, 19, 44, 37, 59, 117, 3, 162, 32, 8, 34, 224, 216, 189, 123, 183, 102, + 142, 238, 113, 201, 201, 164, 21, 20, 224, 146, 101, 54, 26, 161, 84, 253, 74, 43, 242, 25, 23, 92, 192, + 191, 127, 253, 53, 19, 150, 47, 15, 101, 241, 162, 24, 102, 92, 248, 216, 99, 76, 191, 224, 2, 63, 167, + 247, 40, 130, 67, 46, 156, 164, 152, 113, 151, 253, 241, 143, 140, 157, 59, 55, 116, 133, 138, 98, 216, 81, + 118, 201, 37, 220, 177, 126, 61, 69, 51, 102, 208, 235, 253, 76, 78, 168, 70, 11, 185, 146, 67, 78, 176, + 210, 138, 138, 136, 73, 212, 228, 160, 21, 0, 246, 238, 221, 219, 4, 56, 188, 115, 191, 146, 92, 133, 181, + 168, 10, 103, 130, 37, 65, 53, 84, 67, 93, 93, 93, 131, 150, 153, 100, 150, 148, 244, 135, 130, 85, 100, + 26, 233, 80, 19, 4, 14, 64, 52, 26, 89, 241, 240, 195, 124, 111, 237, 90, 146, 162, 38, 193, 136, 135, 96, + 52, 114, 229, 243, 207, 147, 51, 113, 34, 54, 116, 226, 228, 16, 34, 40, 5, 82, 47, 176, 236, 158, 123, + 152, 117, 245, 213, 33, 45, 87, 20, 35, 131, 172, 201, 147, 185, 245, 179, 207, 152, 123, 229, 149, 244, + 162, 30, 202, 38, 210, 161, 148, 13, 18, 193, 210, 58, 68, 195, 161, 67, 135, 26, 100, 183, 215, 149, 88, + 10, 119, 130, 165, 230, 232, 238, 2, 168, 170, 170, 210, 204, 68, 8, 144, 93, 90, 234, 231, 228, 30, 106, + 199, 193, 80, 166, 62, 60, 126, 105, 55, 253, 243, 159, 44, 141, 154, 4, 71, 21, 18, 115, 114, 184, 234, + 197, 23, 177, 196, 199, 251, 52, 186, 161, 238, 143, 225, 156, 192, 67, 174, 202, 47, 190, 152, 243, 30, + 121, 228, 164, 235, 59, 10, 253, 34, 38, 57, 153, 149, 175, 189, 198, 197, 143, 60, 130, 91, 16, 112, 17, + 250, 254, 24, 202, 113, 32, 224, 153, 160, 115, 39, 77, 26, 82, 189, 42, 177, 119, 239, 94, 105, 174, 15, + 118, 200, 115, 216, 34, 220, 9, 22, 248, 171, 4, 165, 5, 163, 208, 212, 212, 212, 236, 116, 58, 251, 180, + 202, 36, 167, 180, 212, 215, 65, 212, 16, 234, 14, 60, 92, 131, 66, 14, 17, 143, 230, 106, 242, 178, 101, + 220, 190, 113, 35, 227, 163, 38, 193, 81, 137, 162, 51, 206, 96, 197, 19, 79, 248, 156, 222, 149, 99, 34, + 212, 253, 54, 156, 198, 75, 31, 158, 93, 200, 151, 255, 233, 79, 209, 133, 200, 40, 197, 146, 255, 252, 79, + 174, 123, 251, 109, 226, 146, 147, 253, 22, 37, 200, 94, 71, 90, 82, 131, 164, 160, 200, 209, 112, 7, 97, + 95, 95, 159, 173, 161, 161, 161, 217, 123, 107, 63, 43, 22, 97, 78, 174, 32, 252, 9, 150, 114, 23, 161, + 175, 98, 235, 234, 234, 218, 154, 155, 155, 59, 180, 202, 40, 107, 252, 120, 204, 232, 168, 229, 52, 132, + 159, 106, 16, 88, 254, 200, 35, 36, 71, 157, 116, 71, 53, 230, 221, 114, 11, 243, 111, 188, 209, 207, 233, + 125, 52, 59, 190, 139, 138, 215, 82, 148, 118, 163, 197, 194, 21, 207, 62, 27, 53, 161, 143, 114, 76, 185, + 228, 18, 166, 92, 118, 153, 207, 19, 91, 217, 95, 34, 25, 114, 115, 185, 25, 79, 224, 110, 173, 208, 218, + 218, 218, 222, 216, 216, 216, 142, 58, 185, 10, 251, 169, 58, 156, 9, 150, 188, 226, 148, 231, 15, 209, + 217, 217, 217, 117, 248, 240, 225, 102, 173, 50, 75, 47, 44, 36, 54, 41, 73, 31, 91, 19, 52, 128, 114, 178, + 244, 85, 172, 209, 72, 108, 122, 122, 72, 202, 20, 69, 120, 225, 226, 39, 158, 160, 112, 214, 44, 159, 143, + 201, 104, 154, 52, 228, 80, 35, 87, 146, 223, 213, 121, 191, 248, 5, 227, 22, 47, 14, 73, 185, 162, 8, 47, + 196, 102, 100, 224, 196, 159, 5, 140, 22, 72, 227, 34, 62, 53, 149, 180, 177, 99, 53, 187, 111, 109, 109, + 109, 179, 213, 106, 149, 66, 52, 40, 45, 89, 242, 236, 195, 18, 225, 76, 176, 36, 40, 57, 128, 219, 123, + 162, 182, 173, 182, 182, 86, 51, 63, 172, 228, 236, 108, 82, 198, 142, 197, 137, 78, 168, 177, 134, 144, + 122, 171, 11, 48, 198, 199, 99, 73, 72, 56, 193, 63, 162, 24, 13, 136, 73, 78, 230, 138, 103, 158, 33, 54, + 41, 201, 179, 233, 129, 209, 75, 178, 192, 95, 46, 116, 3, 179, 190, 253, 109, 206, 252, 209, 143, 66, 91, + 168, 40, 194, 6, 177, 105, 105, 65, 237, 87, 145, 58, 86, 228, 99, 194, 9, 164, 142, 29, 75, 82, 78, 142, + 102, 247, 175, 171, 171, 59, 2, 244, 121, 231, 124, 221, 16, 43, 9, 225, 78, 176, 148, 59, 8, 229, 236, + 213, 181, 123, 247, 110, 205, 118, 18, 26, 205, 102, 50, 138, 138, 130, 30, 108, 28, 169, 73, 130, 100, 34, + 52, 39, 39, 71, 9, 150, 6, 232, 235, 237, 229, 248, 81, 77, 247, 97, 132, 4, 249, 179, 103, 115, 225, 175, + 127, 141, 29, 255, 85, 185, 188, 255, 132, 186, 15, 15, 247, 248, 80, 142, 147, 62, 32, 123, 220, 56, 46, + 253, 253, 239, 79, 178, 54, 195, 15, 78, 135, 131, 150, 198, 198, 80, 23, 35, 34, 16, 159, 149, 165, 74, + 174, 66, 221, 135, 135, 123, 238, 144, 224, 6, 50, 198, 141, 195, 160, 225, 121, 150, 59, 119, 238, 172, + 167, 127, 247, 160, 174, 14, 122, 134, 240, 39, 88, 18, 148, 187, 162, 221, 128, 120, 240, 224, 65, 77, 37, + 67, 206, 164, 73, 62, 63, 164, 209, 0, 181, 237, 153, 230, 228, 100, 44, 26, 198, 48, 25, 173, 248, 219, + 99, 143, 177, 178, 180, 148, 53, 207, 60, 131, 232, 214, 247, 38, 238, 249, 183, 222, 202, 156, 149, 43, + 71, 221, 161, 208, 202, 103, 148, 198, 136, 96, 48, 112, 217, 31, 254, 64, 146, 206, 15, 56, 63, 118, 248, + 48, 15, 174, 92, 201, 13, 21, 21, 28, 222, 183, 47, 212, 197, 209, 61, 18, 178, 179, 253, 52, 1, 163, 101, + 156, 72, 112, 1, 99, 166, 76, 209, 244, 158, 181, 181, 181, 141, 4, 134, 104, 208, 141, 5, 86, 15, 4, 75, + 109, 91, 166, 27, 96, 247, 238, 221, 154, 19, 44, 181, 12, 65, 39, 173, 121, 138, 144, 24, 171, 19, 136, + 73, 75, 195, 104, 50, 133, 184, 68, 250, 198, 166, 15, 63, 228, 133, 135, 31, 166, 221, 106, 229, 193, 213, + 171, 185, 115, 217, 50, 246, 111, 223, 30, 234, 98, 13, 9, 23, 255, 230, 55, 100, 143, 31, 239, 231, 196, + 59, 26, 198, 6, 248, 11, 157, 30, 96, 241, 79, 127, 74, 233, 185, 231, 134, 182, 80, 67, 128, 219, 229, + 226, 237, 255, 249, 31, 174, 159, 53, 139, 247, 223, 122, 139, 198, 166, 38, 30, 187, 245, 86, 156, 118, + 123, 168, 139, 166, 107, 36, 100, 102, 234, 51, 88, 211, 73, 66, 62, 238, 149, 207, 152, 173, 109, 136, 6, + 113, 247, 238, 221, 242, 16, 13, 114, 19, 161, 46, 170, 86, 15, 4, 11, 2, 181, 87, 46, 128, 163, 71, 143, + 182, 90, 173, 86, 205, 118, 18, 230, 78, 153, 130, 145, 209, 227, 208, 171, 100, 172, 78, 60, 171, 176, 40, + 78, 29, 45, 245, 245, 252, 106, 245, 106, 92, 78, 39, 137, 64, 50, 240, 213, 186, 117, 172, 158, 55, 143, + 167, 127, 246, 51, 122, 172, 214, 80, 23, 241, 148, 144, 152, 147, 195, 165, 79, 61, 229, 155, 64, 212, + 180, 59, 145, 4, 229, 36, 34, 57, 181, 143, 159, 63, 159, 179, 239, 191, 63, 100, 229, 26, 42, 246, 108, + 220, 200, 15, 22, 46, 228, 151, 119, 220, 65, 103, 107, 43, 201, 120, 250, 232, 151, 159, 124, 194, 211, + 247, 220, 19, 234, 226, 233, 26, 241, 105, 105, 152, 204, 102, 191, 35, 215, 34, 21, 106, 27, 63, 76, 104, + 27, 3, 171, 189, 189, 189, 189, 169, 169, 169, 197, 251, 86, 185, 209, 77, 23, 213, 171, 7, 130, 165, 166, + 189, 114, 3, 52, 52, 52, 180, 31, 62, 124, 248, 184, 86, 25, 101, 20, 23, 19, 151, 144, 160, 47, 138, 124, + 10, 80, 14, 14, 57, 193, 138, 158, 161, 118, 234, 16, 221, 110, 254, 251, 150, 91, 104, 168, 173, 37, 129, + 254, 131, 178, 147, 1, 236, 118, 158, 251, 213, 175, 184, 165, 162, 130, 245, 239, 190, 27, 210, 114, 158, + 42, 38, 93, 112, 1, 11, 239, 186, 75, 53, 116, 67, 36, 65, 141, 60, 58, 129, 152, 196, 68, 46, 253, 159, + 255, 193, 20, 19, 19, 130, 82, 13, 13, 214, 182, 54, 254, 240, 195, 31, 114, 251, 194, 133, 108, 255, 234, + 43, 82, 128, 56, 60, 253, 83, 234, 163, 175, 60, 254, 56, 235, 94, 123, 45, 164, 229, 212, 51, 18, 50, 51, + 49, 39, 38, 6, 156, 105, 27, 169, 144, 63, 159, 11, 72, 72, 77, 37, 163, 164, 68, 179, 251, 215, 213, 213, + 181, 54, 54, 54, 74, 10, 20, 221, 249, 95, 129, 62, 8, 150, 4, 57, 185, 18, 1, 209, 229, 114, 245, 122, + 109, 180, 154, 32, 101, 204, 24, 146, 115, 115, 71, 205, 10, 68, 141, 185, 38, 107, 184, 3, 100, 180, 225, + 47, 143, 60, 194, 103, 255, 248, 7, 41, 120, 38, 45, 179, 44, 197, 0, 105, 64, 221, 254, 253, 252, 236, + 146, 75, 120, 240, 242, 203, 57, 90, 83, 19, 186, 194, 158, 34, 206, 121, 224, 1, 198, 150, 151, 7, 28, + 165, 3, 145, 55, 94, 228, 2, 167, 23, 88, 126, 223, 125, 228, 87, 84, 132, 182, 80, 167, 128, 117, 175, + 191, 206, 234, 89, 179, 248, 203, 147, 79, 98, 116, 56, 72, 198, 191, 111, 74, 253, 211, 12, 60, 249, 131, + 31, 80, 191, 119, 111, 8, 75, 171, 95, 196, 38, 39, 19, 147, 146, 18, 241, 38, 66, 57, 228, 254, 187, 41, + 121, 121, 36, 101, 101, 105, 118, 239, 3, 7, 14, 212, 139, 162, 40, 137, 26, 93, 110, 208, 12, 119, 130, + 21, 204, 220, 235, 22, 4, 193, 5, 216, 181, 244, 195, 50, 199, 196, 144, 53, 113, 162, 111, 75, 186, 188, + 0, 145, 12, 121, 143, 77, 45, 44, 12, 101, 81, 116, 139, 205, 31, 124, 192, 95, 30, 122, 136, 100, 192, 34, + 75, 49, 138, 107, 34, 144, 0, 124, 248, 214, 91, 220, 60, 107, 22, 111, 62, 241, 132, 174, 124, 95, 98, + 146, 146, 248, 214, 239, 126, 135, 209, 100, 242, 197, 252, 209, 141, 180, 27, 4, 212, 4, 78, 47, 80, 186, + 100, 9, 139, 117, 22, 146, 161, 126, 223, 62, 238, 93, 177, 130, 123, 191, 243, 29, 142, 214, 214, 146, 70, + 127, 63, 148, 250, 164, 244, 222, 140, 167, 95, 30, 111, 110, 230, 241, 213, 171, 113, 244, 105, 118, 72, + 198, 168, 129, 37, 46, 142, 228, 49, 99, 70, 213, 2, 93, 122, 237, 4, 178, 38, 78, 212, 212, 127, 119, 239, + 222, 189, 13, 120, 14, 121, 86, 35, 88, 186, 216, 57, 20, 238, 4, 11, 212, 205, 131, 190, 202, 222, 179, + 103, 79, 157, 150, 153, 101, 79, 158, 28, 241, 43, 115, 9, 202, 138, 21, 128, 244, 130, 130, 144, 150, 73, + 143, 104, 62, 124, 152, 39, 86, 175, 70, 112, 185, 136, 37, 112, 2, 147, 79, 100, 210, 53, 21, 232, 109, + 111, 231, 241, 31, 253, 136, 127, 91, 176, 128, 111, 214, 175, 15, 81, 233, 79, 30, 37, 103, 158, 201, 194, + 59, 239, 164, 151, 200, 90, 165, 171, 153, 206, 29, 120, 76, 131, 151, 252, 246, 183, 8, 26, 110, 63, 31, + 78, 216, 109, 54, 254, 246, 203, 95, 178, 122, 206, 28, 62, 89, 179, 198, 71, 234, 149, 132, 95, 222, 47, + 37, 146, 149, 10, 108, 249, 236, 51, 158, 187, 251, 238, 208, 20, 94, 231, 144, 91, 64, 32, 178, 22, 31, + 160, 110, 62, 151, 52, 88, 185, 83, 167, 106, 154, 87, 101, 101, 229, 97, 2, 45, 87, 242, 53, 93, 216, 87, + 169, 62, 36, 70, 112, 146, 69, 117, 117, 181, 166, 59, 9, 243, 167, 77, 83, 221, 29, 17, 41, 147, 136, 18, + 210, 51, 185, 129, 24, 147, 41, 106, 34, 60, 73, 136, 162, 200, 147, 183, 221, 198, 209, 186, 58, 18, 9, + 78, 174, 148, 147, 153, 5, 143, 15, 76, 26, 240, 205, 230, 205, 252, 96, 241, 98, 158, 188, 253, 118, 58, + 91, 91, 67, 241, 24, 39, 141, 229, 63, 255, 57, 99, 167, 79, 199, 134, 250, 88, 209, 51, 228, 147, 134, 13, + 207, 179, 142, 153, 49, 35, 180, 133, 26, 36, 182, 125, 242, 9, 183, 207, 155, 199, 239, 238, 185, 7, 187, + 213, 26, 160, 181, 58, 81, 223, 148, 72, 214, 155, 191, 249, 13, 159, 189, 254, 122, 40, 30, 65, 215, 72, + 43, 44, 84, 93, 160, 235, 125, 76, 200, 161, 166, 229, 5, 200, 211, 150, 96, 185, 107, 106, 106, 164, 185, + 93, 151, 254, 87, 160, 31, 130, 5, 65, 28, 221, 15, 28, 56, 112, 204, 106, 181, 118, 107, 149, 73, 206, + 228, 201, 152, 233, 111, 189, 72, 14, 166, 40, 61, 151, 84, 161, 177, 41, 41, 164, 68, 207, 84, 59, 41, + 252, 245, 129, 7, 88, 255, 222, 123, 164, 224, 153, 156, 212, 38, 176, 88, 217, 53, 86, 246, 94, 154, 240, + 82, 0, 139, 203, 197, 107, 127, 252, 35, 55, 205, 152, 193, 71, 127, 253, 235, 200, 63, 200, 73, 34, 38, + 41, 137, 139, 254, 251, 191, 17, 8, 52, 19, 234, 109, 204, 40, 203, 45, 193, 6, 140, 95, 176, 128, 51, 239, + 186, 235, 228, 43, 104, 132, 209, 214, 212, 196, 127, 223, 120, 35, 119, 46, 91, 70, 245, 206, 157, 164, 1, + 241, 248, 247, 201, 88, 2, 251, 224, 64, 90, 214, 223, 223, 113, 7, 245, 123, 246, 140, 248, 179, 232, 25, + 153, 227, 198, 5, 204, 252, 161, 238, 223, 195, 57, 102, 192, 187, 56, 7, 114, 39, 79, 62, 249, 10, 11, + 130, 182, 182, 54, 235, 254, 253, 251, 165, 163, 240, 228, 129, 70, 117, 67, 174, 64, 63, 4, 75, 141, 92, + 185, 0, 142, 29, 59, 214, 214, 216, 216, 216, 164, 85, 70, 153, 37, 37, 36, 166, 164, 32, 226, 169, 28, + 193, 123, 141, 180, 36, 40, 174, 0, 41, 217, 217, 196, 37, 39, 15, 189, 18, 71, 9, 54, 174, 93, 203, 223, + 30, 126, 152, 20, 252, 201, 84, 44, 30, 237, 212, 64, 41, 86, 118, 149, 180, 89, 25, 64, 107, 67, 3, 15, + 94, 123, 45, 119, 159, 119, 30, 181, 85, 85, 35, 252, 68, 39, 135, 210, 115, 206, 97, 254, 45, 183, 96, + 163, 95, 240, 134, 186, 95, 107, 145, 192, 59, 105, 88, 44, 92, 244, 216, 99, 24, 194, 56, 46, 156, 232, + 118, 243, 207, 231, 159, 231, 230, 25, 51, 120, 251, 249, 231, 137, 19, 197, 128, 254, 168, 236, 115, 193, + 250, 163, 156, 116, 37, 2, 29, 205, 205, 60, 126, 195, 13, 216, 123, 123, 71, 250, 177, 116, 139, 140, 130, + 2, 76, 68, 214, 120, 56, 209, 60, 2, 144, 148, 149, 69, 154, 134, 238, 37, 245, 245, 245, 77, 199, 143, 31, + 87, 238, 32, 84, 51, 46, 133, 53, 12, 39, 254, 73, 200, 17, 44, 170, 128, 91, 16, 4, 119, 95, 95, 95, 207, + 190, 125, 251, 52, 59, 147, 36, 37, 55, 151, 212, 130, 2, 223, 153, 132, 202, 2, 68, 34, 36, 39, 197, 180, + 226, 98, 140, 102, 115, 168, 139, 163, 11, 28, 171, 173, 229, 169, 219, 110, 195, 32, 138, 1, 38, 24, 181, + 164, 52, 17, 202, 181, 88, 114, 243, 76, 34, 144, 4, 124, 241, 193, 7, 220, 54, 119, 46, 47, 61, 240, 0, + 182, 158, 158, 17, 125, 182, 147, 193, 217, 15, 60, 64, 70, 97, 33, 118, 244, 111, 42, 148, 59, 120, 244, + 2, 103, 252, 219, 191, 81, 116, 250, 233, 161, 45, 212, 0, 56, 176, 99, 7, 63, 94, 182, 140, 71, 110, 188, + 145, 246, 166, 38, 210, 81, 247, 177, 26, 140, 185, 90, 234, 127, 210, 110, 66, 51, 158, 208, 13, 59, 191, + 252, 146, 231, 127, 246, 179, 17, 125, 46, 61, 35, 163, 164, 196, 207, 2, 18, 169, 144, 143, 117, 39, 144, + 94, 92, 172, 233, 14, 194, 125, 251, 246, 53, 58, 157, 206, 94, 133, 131, 123, 244, 44, 194, 97, 68, 48, + 71, 119, 199, 222, 189, 123, 235, 180, 202, 68, 48, 24, 200, 158, 60, 217, 111, 171, 45, 232, 160, 37, 7, + 137, 96, 190, 1, 110, 32, 163, 168, 40, 36, 101, 210, 27, 68, 183, 155, 167, 110, 189, 149, 166, 250, 122, + 18, 8, 220, 242, 46, 79, 242, 201, 75, 154, 192, 228, 147, 160, 210, 84, 35, 253, 39, 21, 112, 246, 244, + 240, 255, 30, 124, 144, 219, 231, 206, 101, 243, 135, 31, 142, 224, 19, 14, 30, 137, 185, 185, 156, 243, + 240, 195, 56, 208, 81, 244, 63, 25, 212, 252, 73, 250, 128, 156, 210, 82, 150, 134, 105, 224, 205, 222, + 174, 46, 158, 187, 251, 110, 110, 159, 63, 159, 141, 235, 214, 145, 66, 160, 57, 48, 24, 201, 146, 247, 69, + 229, 107, 11, 158, 240, 34, 242, 207, 83, 128, 255, 125, 234, 41, 214, 189, 250, 234, 200, 61, 160, 142, + 145, 156, 155, 75, 92, 90, 90, 68, 199, 194, 82, 142, 25, 39, 144, 163, 177, 131, 251, 206, 157, 59, 107, + 189, 183, 214, 173, 255, 21, 232, 135, 96, 41, 85, 131, 126, 36, 171, 170, 170, 74, 51, 130, 5, 144, 55, + 109, 154, 239, 76, 66, 93, 181, 230, 73, 64, 109, 98, 201, 209, 208, 134, 30, 137, 112, 58, 28, 124, 181, + 102, 13, 63, 91, 182, 140, 205, 255, 252, 39, 41, 120, 130, 137, 74, 117, 41, 77, 74, 82, 240, 70, 229, + 107, 11, 193, 253, 180, 148, 147, 162, 100, 54, 76, 7, 14, 85, 85, 241, 31, 231, 158, 203, 163, 215, 94, + 75, 75, 131, 102, 231, 155, 107, 134, 138, 235, 174, 99, 242, 121, 231, 169, 6, 32, 213, 211, 216, 145, 28, + 219, 157, 192, 185, 255, 245, 95, 196, 165, 165, 133, 184, 68, 129, 248, 114, 205, 26, 110, 173, 168, 224, + 249, 71, 31, 5, 155, 205, 227, 191, 71, 96, 223, 81, 18, 119, 57, 105, 10, 214, 79, 165, 207, 13, 244, 171, + 9, 164, 123, 61, 181, 122, 53, 207, 254, 232, 71, 212, 71, 207, 44, 28, 16, 73, 89, 89, 164, 228, 229, 5, + 156, 118, 160, 167, 113, 48, 24, 200, 199, 183, 27, 205, 29, 220, 169, 174, 174, 150, 118, 16, 186, 232, + 63, 60, 66, 119, 36, 75, 47, 4, 75, 130, 82, 123, 229, 2, 132, 111, 190, 249, 70, 211, 89, 39, 175, 188, + 220, 207, 121, 55, 82, 7, 138, 124, 144, 24, 129, 204, 241, 227, 67, 88, 154, 240, 133, 245, 248, 113, 222, + 249, 253, 239, 185, 125, 214, 44, 126, 182, 98, 5, 95, 175, 91, 135, 1, 207, 68, 28, 107, 177, 80, 54, 103, + 14, 227, 166, 77, 243, 69, 195, 23, 240, 212, 167, 220, 87, 193, 72, 127, 100, 119, 165, 214, 64, 233, 191, + 165, 156, 20, 147, 240, 144, 173, 181, 127, 253, 43, 171, 103, 206, 228, 221, 63, 254, 17, 183, 43, 188, + 142, 37, 63, 247, 191, 254, 11, 75, 76, 140, 95, 108, 172, 112, 39, 89, 202, 73, 66, 10, 40, 58, 109, 197, + 10, 166, 95, 126, 121, 200, 202, 165, 134, 166, 154, 26, 30, 190, 242, 74, 126, 182, 98, 5, 135, 171, 171, + 73, 131, 160, 33, 65, 212, 180, 162, 114, 82, 37, 239, 155, 242, 215, 110, 60, 97, 41, 18, 18, 18, 152, + 113, 230, 153, 228, 123, 99, 226, 185, 129, 46, 171, 149, 63, 63, 241, 4, 183, 204, 152, 193, 195, 87, 94, + 201, 206, 207, 62, 67, 20, 195, 181, 101, 67, 7, 131, 209, 72, 122, 113, 113, 68, 46, 208, 213, 22, 229, + 210, 220, 145, 95, 94, 174, 93, 62, 162, 232, 172, 172, 172, 148, 230, 244, 129, 130, 140, 134, 61, 194, + 215, 123, 51, 16, 193, 180, 88, 212, 215, 215, 31, 59, 222, 218, 122, 60, 61, 35, 35, 157, 161, 14, 122, + 65, 32, 187, 180, 148, 24, 179, 25, 183, 195, 17, 208, 169, 148, 59, 40, 244, 14, 169, 34, 45, 70, 35, 89, + 227, 198, 121, 63, 212, 85, 31, 214, 30, 130, 167, 149, 15, 125, 243, 13, 255, 124, 254, 121, 62, 252, 203, + 95, 168, 109, 105, 193, 140, 39, 172, 194, 216, 252, 124, 202, 206, 56, 131, 153, 203, 151, 51, 101, 209, + 34, 198, 76, 158, 140, 203, 225, 96, 223, 199, 31, 179, 249, 233, 167, 57, 240, 193, 7, 216, 122, 123, 125, + 4, 73, 234, 51, 82, 255, 145, 111, 46, 80, 18, 48, 53, 98, 230, 244, 190, 54, 1, 157, 45, 45, 252, 250, + 246, 219, 249, 215, 203, 47, 115, 251, 111, 127, 75, 233, 156, 57, 222, 155, 135, 176, 205, 4, 129, 252, + 138, 10, 78, 191, 227, 14, 62, 121, 252, 113, 140, 168, 239, 54, 10, 39, 168, 77, 22, 78, 32, 38, 46, 142, + 179, 31, 126, 216, 251, 101, 104, 235, 20, 192, 229, 116, 242, 247, 223, 255, 158, 63, 63, 244, 16, 173, + 109, 109, 36, 225, 233, 83, 70, 252, 181, 80, 74, 77, 148, 68, 230, 149, 125, 74, 185, 19, 204, 5, 62, 243, + 110, 118, 113, 49, 229, 223, 253, 46, 21, 171, 86, 145, 53, 113, 34, 182, 206, 78, 14, 109, 217, 66, 229, + 191, 254, 197, 142, 127, 253, 139, 234, 237, 219, 105, 234, 233, 225, 237, 55, 222, 224, 253, 55, 222, 160, + 226, 180, 211, 184, 248, 246, 219, 57, 99, 197, 10, 146, 210, 210, 162, 114, 3, 64, 16, 200, 41, 45, 101, + 199, 123, 239, 233, 143, 13, 12, 2, 74, 101, 131, 11, 136, 77, 72, 32, 107, 226, 68, 239, 135, 67, 159, + 127, 143, 52, 54, 30, 111, 104, 104, 80, 238, 32, 212, 157, 131, 59, 232, 139, 96, 73, 80, 238, 36, 20, + 143, 28, 57, 210, 81, 91, 87, 119, 44, 61, 35, 35, 125, 168, 53, 47, 0, 233, 69, 69, 36, 231, 230, 98, 61, + 124, 88, 127, 45, 58, 72, 200, 159, 203, 5, 36, 142, 25, 67, 138, 247, 28, 194, 33, 215, 161, 160, 62, 181, + 234, 97, 197, 43, 149, 253, 147, 215, 95, 231, 207, 15, 60, 192, 190, 221, 187, 73, 137, 139, 99, 233, 194, + 133, 84, 44, 95, 206, 204, 165, 75, 25, 63, 107, 22, 177, 73, 73, 126, 255, 51, 90, 44, 76, 57, 255, 124, + 166, 156, 127, 62, 173, 7, 14, 176, 243, 175, 127, 165, 242, 165, 151, 104, 62, 120, 16, 240, 104, 25, 228, + 225, 11, 164, 171, 68, 180, 92, 4, 18, 43, 7, 254, 147, 163, 68, 180, 98, 128, 173, 235, 215, 243, 253, 51, + 206, 224, 219, 119, 220, 193, 119, 127, 254, 115, 207, 4, 71, 136, 234, 88, 20, 17, 4, 129, 37, 63, 253, + 41, 149, 111, 188, 65, 103, 93, 29, 49, 248, 63, 103, 56, 47, 78, 36, 129, 210, 11, 156, 117, 199, 29, 140, + 41, 47, 15, 233, 120, 151, 250, 224, 174, 13, 27, 248, 227, 15, 127, 200, 182, 77, 155, 136, 199, 67, 238, + 37, 226, 20, 204, 12, 45, 189, 86, 35, 235, 74, 98, 101, 199, 163, 129, 157, 188, 120, 49, 21, 171, 87, 51, + 241, 252, 243, 177, 36, 36, 248, 202, 17, 155, 156, 204, 148, 165, 75, 153, 178, 116, 41, 87, 62, 252, 48, + 205, 181, 181, 236, 222, 176, 129, 45, 31, 125, 196, 142, 117, 235, 216, 190, 113, 35, 123, 182, 109, 99, + 241, 63, 255, 201, 205, 143, 62, 74, 110, 81, 145, 174, 198, 184, 18, 90, 148, 93, 0, 114, 166, 76, 241, + 220, 79, 186, 175, 226, 117, 184, 142, 131, 193, 66, 57, 119, 100, 140, 29, 75, 170, 86, 115, 7, 80, 91, + 87, 119, 164, 173, 173, 205, 74, 160, 59, 144, 238, 166, 99, 61, 17, 44, 85, 13, 150, 32, 8, 110, 81, 20, + 123, 119, 237, 218, 213, 48, 107, 214, 44, 77, 156, 136, 98, 19, 19, 201, 154, 56, 145, 227, 135, 15, 19, + 139, 142, 90, 115, 144, 80, 174, 66, 156, 64, 122, 97, 33, 241, 169, 169, 39, 125, 55, 25, 209, 113, 0, 0, + 32, 0, 73, 68, 65, 84, 175, 129, 132, 149, 92, 96, 25, 12, 134, 160, 191, 149, 126, 31, 14, 144, 202, 113, + 230, 101, 151, 49, 255, 130, 11, 104, 174, 175, 39, 54, 62, 158, 108, 197, 17, 66, 162, 231, 199, 129, 55, + 16, 4, 50, 198, 143, 103, 233, 253, 247, 179, 240, 39, 63, 225, 192, 7, 31, 176, 245, 233, 167, 57, 244, + 241, 199, 244, 218, 237, 126, 38, 26, 137, 92, 73, 81, 244, 213, 182, 117, 27, 241, 215, 112, 57, 188, 239, + 83, 1, 187, 195, 193, 75, 191, 249, 13, 159, 191, 253, 54, 183, 60, 246, 24, 103, 94, 126, 57, 130, 32, + 132, 164, 46, 69, 81, 36, 33, 43, 139, 165, 247, 220, 195, 27, 183, 222, 234, 211, 220, 201, 183, 114, 135, + 203, 228, 162, 156, 248, 220, 120, 200, 70, 102, 81, 17, 139, 127, 242, 19, 239, 151, 35, 95, 135, 210, + 248, 232, 104, 109, 229, 165, 251, 238, 227, 157, 63, 253, 9, 167, 203, 69, 42, 254, 196, 41, 24, 169, 146, + 190, 87, 246, 49, 41, 137, 224, 59, 6, 44, 35, 63, 159, 169, 43, 87, 50, 227, 250, 235, 201, 46, 43, 243, + 149, 33, 88, 223, 17, 4, 129, 172, 162, 34, 178, 138, 138, 56, 115, 229, 74, 236, 189, 189, 52, 30, 60, 72, + 98, 106, 42, 41, 89, 89, 24, 77, 166, 176, 25, 195, 16, 92, 46, 73, 56, 25, 249, 116, 178, 207, 149, 59, + 101, 10, 38, 212, 143, 145, 10, 135, 254, 63, 84, 200, 39, 97, 7, 30, 223, 93, 83, 76, 140, 102, 243, 228, + 246, 237, 219, 15, 3, 54, 239, 14, 66, 121, 12, 44, 93, 28, 143, 35, 135, 94, 8, 150, 212, 55, 85, 157, + 220, 1, 231, 238, 221, 187, 15, 2, 203, 134, 42, 24, 69, 81, 68, 48, 24, 24, 51, 125, 58, 85, 255, 250, 87, + 196, 154, 8, 229, 203, 0, 23, 144, 235, 21, 178, 162, 251, 196, 125, 88, 126, 100, 136, 173, 167, 135, 134, + 234, 106, 14, 238, 220, 73, 237, 238, 221, 52, 213, 214, 210, 118, 236, 24, 61, 29, 29, 184, 156, 78, 159, + 169, 35, 38, 46, 142, 132, 148, 20, 210, 115, 115, 201, 41, 42, 98, 204, 184, 113, 20, 148, 150, 50, 166, + 164, 132, 148, 172, 172, 0, 225, 54, 152, 114, 12, 39, 140, 70, 35, 113, 137, 137, 20, 202, 28, 255, 7, 85, + 38, 81, 236, 119, 122, 143, 139, 99, 242, 165, 151, 50, 249, 210, 75, 105, 222, 189, 155, 157, 47, 189, + 196, 55, 47, 191, 76, 203, 225, 195, 64, 160, 86, 75, 141, 80, 73, 147, 165, 147, 126, 141, 150, 3, 127, + 179, 225, 145, 154, 26, 238, 189, 226, 10, 150, 174, 88, 193, 234, 255, 254, 111, 242, 189, 234, 250, 17, + 175, 67, 65, 96, 206, 13, 55, 176, 249, 197, 23, 57, 252, 213, 87, 196, 121, 63, 14, 231, 113, 35, 141, 3, + 59, 176, 228, 238, 187, 73, 200, 204, 12, 73, 189, 73, 253, 255, 227, 191, 253, 141, 103, 126, 250, 83, 14, + 215, 215, 147, 132, 231, 136, 27, 57, 113, 50, 163, 78, 172, 6, 50, 7, 74, 4, 210, 98, 52, 50, 97, 209, 34, + 102, 221, 116, 19, 19, 47, 190, 152, 88, 111, 204, 59, 81, 20, 79, 72, 40, 253, 72, 134, 32, 96, 137, 139, + 163, 88, 230, 216, 60, 152, 123, 12, 43, 100, 117, 40, 193, 105, 183, 211, 92, 95, 79, 67, 117, 53, 245, + 213, 213, 28, 173, 169, 225, 216, 225, 195, 116, 182, 182, 210, 99, 181, 226, 114, 56, 252, 228, 83, 98, + 90, 26, 153, 121, 121, 228, 79, 152, 64, 201, 180, 105, 20, 79, 155, 70, 86, 126, 126, 191, 188, 83, 144, + 178, 96, 229, 200, 44, 41, 33, 62, 37, 5, 87, 71, 135, 190, 212, 45, 131, 128, 218, 226, 36, 111, 230, 76, + 207, 135, 90, 140, 27, 65, 96, 247, 238, 221, 135, 232, 183, 80, 5, 51, 15, 234, 162, 90, 245, 66, 176, + 192, 191, 77, 165, 171, 111, 135, 193, 246, 237, 219, 61, 59, 9, 53, 88, 193, 11, 192, 216, 153, 51, 253, + 84, 234, 202, 64, 132, 225, 58, 97, 12, 4, 249, 68, 39, 189, 150, 82, 222, 180, 105, 190, 207, 131, 193, + 224, 21, 52, 61, 86, 43, 91, 62, 250, 136, 245, 111, 191, 77, 229, 231, 159, 211, 84, 87, 71, 175, 219, + 141, 27, 117, 115, 132, 116, 95, 121, 195, 73, 166, 174, 212, 204, 76, 242, 39, 78, 100, 242, 220, 185, 76, + 93, 184, 144, 178, 249, 243, 201, 46, 40, 240, 9, 53, 145, 208, 144, 45, 45, 38, 12, 169, 220, 130, 32, + 144, 53, 101, 10, 203, 126, 249, 75, 22, 222, 115, 15, 251, 223, 123, 143, 237, 207, 62, 203, 161, 79, 63, + 165, 207, 233, 244, 211, 56, 136, 244, 107, 181, 140, 120, 58, 183, 68, 176, 148, 87, 233, 181, 244, 254, + 95, 239, 190, 203, 214, 79, 62, 225, 187, 247, 220, 195, 101, 63, 252, 33, 150, 216, 88, 220, 35, 88, 119, + 162, 219, 141, 209, 108, 102, 249, 125, 247, 241, 194, 5, 23, 248, 250, 146, 60, 152, 173, 244, 62, 84, 80, + 174, 212, 192, 19, 150, 161, 100, 238, 92, 230, 222, 112, 131, 239, 55, 35, 5, 193, 75, 12, 106, 170, 170, + 120, 250, 71, 63, 226, 139, 127, 254, 19, 11, 158, 221, 163, 3, 145, 42, 185, 195, 186, 210, 113, 93, 170, + 107, 105, 195, 65, 122, 78, 14, 101, 87, 94, 73, 249, 245, 215, 51, 102, 214, 44, 95, 222, 167, 220, 55, 6, + 67, 52, 70, 2, 130, 128, 65, 70, 170, 236, 125, 125, 28, 170, 172, 228, 155, 245, 235, 217, 181, 97, 3, 7, + 119, 236, 224, 88, 93, 29, 221, 189, 189, 216, 241, 215, 168, 6, 147, 79, 146, 140, 50, 3, 201, 9, 9, 20, + 79, 155, 198, 156, 243, 206, 99, 225, 183, 190, 197, 248, 242, 114, 4, 131, 33, 64, 251, 165, 68, 98, 118, + 54, 233, 133, 133, 52, 85, 86, 250, 229, 165, 38, 23, 245, 2, 233, 105, 229, 26, 119, 233, 125, 254, 244, + 233, 126, 191, 57, 85, 72, 4, 249, 155, 111, 190, 81, 158, 65, 24, 245, 193, 26, 33, 4, 211, 96, 9, 251, + 246, 237, 107, 236, 233, 233, 177, 197, 199, 199, 199, 106, 49, 248, 199, 76, 155, 134, 133, 126, 157, 164, + 174, 90, 117, 0, 168, 217, 89, 13, 64, 158, 119, 144, 168, 65, 48, 24, 16, 128, 230, 250, 122, 214, 254, + 233, 79, 124, 248, 231, 63, 115, 248, 240, 97, 223, 17, 9, 82, 80, 66, 165, 143, 81, 176, 252, 165, 171, + 27, 143, 211, 118, 107, 75, 11, 91, 190, 252, 18, 195, 83, 79, 145, 150, 152, 200, 132, 89, 179, 152, 115, + 222, 121, 156, 118, 254, 249, 140, 43, 47, 199, 104, 52, 122, 254, 19, 46, 130, 253, 36, 33, 47, 119, 76, + 82, 18, 83, 175, 186, 138, 169, 87, 93, 69, 211, 206, 157, 236, 120, 241, 69, 170, 94, 125, 149, 214, 35, + 71, 16, 232, 159, 44, 149, 66, 217, 119, 47, 100, 206, 135, 244, 135, 21, 112, 226, 209, 136, 181, 90, 173, + 60, 122, 247, 221, 188, 255, 194, 11, 124, 255, 183, 191, 229, 180, 243, 207, 31, 209, 122, 19, 69, 145, + 73, 231, 159, 79, 217, 37, 151, 176, 235, 239, 127, 39, 145, 240, 212, 254, 202, 125, 72, 220, 192, 89, + 247, 221, 135, 209, 108, 30, 81, 66, 106, 48, 24, 112, 216, 237, 252, 229, 193, 7, 249, 243, 175, 127, 141, + 213, 233, 68, 242, 236, 115, 122, 175, 70, 233, 183, 244, 107, 44, 213, 204, 130, 210, 247, 34, 30, 194, + 104, 49, 24, 40, 158, 55, 143, 153, 55, 221, 196, 164, 75, 47, 37, 62, 61, 29, 208, 239, 24, 146, 195, 32, + 211, 160, 91, 219, 218, 216, 249, 249, 231, 124, 181, 102, 13, 59, 215, 173, 163, 254, 224, 65, 122, 221, + 110, 12, 244, 215, 83, 28, 30, 77, 32, 156, 184, 15, 74, 53, 227, 6, 250, 186, 187, 217, 249, 245, 215, + 108, 249, 250, 107, 254, 250, 200, 35, 204, 88, 180, 136, 75, 127, 240, 3, 206, 88, 177, 194, 103, 18, 85, + 214, 165, 232, 118, 99, 50, 155, 201, 153, 60, 153, 134, 202, 202, 0, 121, 27, 78, 99, 224, 100, 33, 105, + 67, 161, 95, 14, 197, 154, 205, 140, 209, 40, 68, 131, 32, 8, 116, 116, 116, 116, 237, 219, 183, 239, 136, + 55, 59, 165, 121, 80, 119, 211, 176, 222, 8, 22, 4, 146, 44, 23, 32, 54, 54, 54, 182, 30, 57, 114, 228, + 216, 248, 241, 227, 11, 7, 252, 247, 32, 145, 94, 84, 68, 98, 78, 14, 189, 77, 77, 126, 145, 121, 245, 62, + 72, 36, 200, 205, 131, 241, 73, 73, 253, 187, 64, 20, 48, 24, 12, 216, 186, 187, 121, 235, 183, 191, 229, + 245, 199, 31, 231, 88, 91, 27, 113, 120, 34, 142, 203, 137, 64, 176, 179, 170, 36, 109, 129, 50, 95, 185, + 208, 145, 252, 220, 220, 128, 173, 171, 139, 45, 159, 127, 206, 215, 159, 127, 206, 11, 247, 221, 199, 196, + 25, 51, 88, 116, 249, 229, 44, 250, 246, 183, 41, 40, 45, 69, 16, 132, 17, 157, 4, 181, 134, 91, 166, 213, + 202, 41, 47, 231, 156, 39, 158, 96, 209, 207, 127, 206, 190, 119, 223, 101, 251, 179, 207, 82, 179, 97, 3, + 125, 222, 223, 72, 228, 215, 36, 8, 152, 44, 22, 176, 88, 16, 226, 226, 48, 37, 38, 98, 244, 38, 83, 98, + 34, 49, 41, 41, 196, 166, 165, 17, 151, 154, 74, 92, 74, 10, 113, 41, 41, 8, 38, 19, 46, 167, 19, 71, 95, + 31, 166, 152, 152, 17, 51, 223, 136, 94, 135, 247, 179, 238, 189, 151, 125, 255, 248, 7, 78, 135, 35, 224, + 108, 207, 80, 141, 33, 181, 190, 215, 11, 76, 185, 240, 66, 166, 92, 116, 209, 136, 75, 110, 17, 112, 187, + 92, 76, 152, 53, 139, 31, 63, 245, 20, 14, 155, 141, 222, 246, 118, 122, 59, 58, 176, 181, 183, 211, 219, + 214, 134, 211, 106, 197, 217, 213, 133, 179, 171, 11, 151, 213, 138, 187, 187, 27, 177, 175, 15, 193, 110, + 71, 116, 58, 125, 66, 80, 162, 28, 169, 233, 233, 148, 93, 126, 57, 51, 110, 184, 129, 252, 185, 115, 125, + 154, 96, 61, 143, 25, 57, 12, 6, 3, 118, 155, 141, 29, 159, 126, 202, 39, 175, 190, 202, 166, 247, 223, + 231, 104, 83, 147, 223, 98, 47, 149, 224, 114, 73, 41, 155, 32, 80, 62, 201, 147, 197, 123, 117, 185, 92, + 108, 90, 183, 142, 175, 215, 173, 99, 214, 252, 249, 220, 244, 203, 95, 50, 99, 201, 146, 160, 242, 40, + 111, 198, 12, 54, 189, 241, 134, 106, 159, 210, 235, 28, 162, 28, 63, 78, 32, 181, 176, 144, 180, 66, 77, + 166, 92, 0, 106, 107, 107, 143, 52, 53, 53, 181, 17, 92, 131, 165, 43, 232, 141, 96, 5, 51, 19, 138, 61, + 61, 61, 93, 123, 246, 236, 105, 28, 63, 126, 124, 225, 80, 87, 104, 110, 183, 155, 164, 172, 44, 50, 39, + 76, 224, 80, 83, 147, 254, 244, 146, 39, 128, 188, 18, 157, 64, 110, 73, 9, 201, 185, 185, 184, 101, 43, + 50, 65, 16, 48, 24, 12, 84, 125, 249, 37, 79, 222, 114, 11, 149, 149, 149, 190, 157, 76, 106, 231, 81, 41, + 85, 239, 106, 2, 68, 41, 188, 212, 180, 105, 38, 60, 130, 210, 141, 71, 168, 85, 109, 221, 202, 246, 173, + 91, 121, 241, 254, 251, 57, 231, 218, 107, 249, 254, 147, 79, 18, 151, 152, 136, 43, 204, 226, 64, 157, 44, + 124, 125, 84, 16, 136, 77, 75, 99, 198, 170, 85, 76, 191, 238, 58, 234, 191, 250, 138, 198, 77, 155, 136, + 77, 77, 37, 54, 45, 13, 75, 98, 34, 150, 196, 68, 204, 73, 73, 196, 36, 38, 98, 137, 143, 199, 96, 177, 96, + 138, 137, 193, 52, 136, 99, 141, 220, 110, 247, 136, 199, 204, 114, 185, 221, 140, 157, 51, 135, 153, 215, + 93, 199, 215, 207, 61, 71, 18, 161, 55, 141, 168, 145, 43, 39, 96, 52, 24, 88, 226, 141, 216, 62, 210, 245, + 36, 186, 92, 152, 99, 98, 56, 243, 4, 49, 183, 68, 183, 27, 135, 221, 142, 203, 110, 199, 213, 215, 71, 95, + 87, 23, 118, 171, 21, 123, 87, 23, 142, 238, 110, 108, 29, 29, 244, 182, 180, 96, 180, 88, 152, 112, 254, + 249, 36, 123, 15, 108, 119, 139, 98, 216, 197, 75, 27, 10, 140, 70, 35, 59, 62, 253, 148, 39, 111, 187, + 141, 234, 221, 187, 61, 26, 20, 60, 139, 189, 129, 100, 145, 210, 52, 23, 172, 47, 186, 101, 87, 229, 68, + 227, 194, 67, 222, 92, 192, 142, 175, 190, 226, 135, 103, 157, 197, 183, 111, 187, 141, 27, 127, 245, 43, + 85, 121, 148, 87, 94, 238, 11, 66, 172, 116, 28, 210, 35, 185, 146, 160, 28, 63, 217, 147, 39, 19, 19, 31, + 143, 219, 237, 214, 68, 51, 186, 103, 207, 158, 195, 78, 167, 179, 39, 136, 131, 187, 238, 166, 97, 61, 17, + 44, 165, 251, 132, 175, 226, 5, 65, 112, 137, 162, 104, 255, 230, 155, 111, 106, 46, 188, 240, 194, 249, + 67, 206, 200, 219, 81, 242, 202, 203, 217, 191, 126, 125, 192, 10, 71, 207, 3, 68, 9, 39, 30, 243, 160, + 201, 108, 246, 9, 9, 193, 96, 192, 32, 8, 252, 227, 79, 127, 226, 247, 255, 254, 239, 244, 246, 245, 145, + 14, 126, 1, 52, 229, 14, 181, 202, 216, 78, 39, 50, 17, 202, 5, 151, 146, 45, 43, 147, 217, 123, 117, 56, + 28, 188, 241, 252, 243, 116, 30, 63, 206, 3, 111, 190, 137, 193, 104, 140, 140, 201, 67, 54, 9, 10, 6, 3, + 133, 167, 159, 78, 225, 9, 206, 191, 243, 153, 49, 68, 49, 228, 155, 1, 84, 33, 237, 196, 252, 241, 143, + 169, 124, 253, 117, 156, 86, 171, 207, 124, 5, 161, 15, 219, 32, 245, 181, 94, 96, 214, 85, 87, 81, 124, + 198, 25, 184, 66, 84, 143, 162, 40, 14, 184, 88, 16, 4, 1, 4, 1, 115, 108, 44, 230, 216, 88, 4, 32, 241, 4, + 103, 190, 233, 125, 241, 161, 6, 163, 209, 72, 213, 87, 95, 113, 247, 197, 23, 99, 181, 90, 73, 32, 208, + 239, 76, 78, 178, 212, 204, 236, 3, 45, 254, 32, 112, 177, 167, 52, 147, 72, 254, 144, 38, 192, 41, 138, + 188, 250, 135, 63, 176, 111, 227, 70, 238, 126, 245, 85, 198, 140, 31, 239, 87, 239, 99, 166, 78, 37, 62, + 33, 193, 163, 113, 148, 221, 95, 111, 145, 189, 229, 80, 206, 131, 46, 60, 190, 202, 128, 102, 102, 231, + 109, 219, 182, 213, 208, 239, 62, 40, 143, 226, 174, 228, 169, 186, 128, 94, 219, 59, 128, 100, 1, 236, + 220, 185, 243, 32, 156, 120, 139, 238, 96, 49, 182, 162, 34, 96, 229, 163, 92, 41, 233, 37, 13, 228, 224, + 89, 48, 123, 182, 239, 181, 224, 117, 28, 125, 243, 151, 191, 228, 183, 183, 222, 10, 125, 125, 36, 211, + 127, 100, 70, 44, 30, 159, 134, 56, 217, 235, 120, 89, 146, 191, 79, 144, 165, 248, 19, 164, 56, 197, 125, + 149, 17, 205, 227, 128, 12, 224, 227, 119, 222, 225, 165, 7, 30, 136, 40, 146, 43, 65, 116, 187, 113, 185, + 92, 39, 76, 110, 111, 10, 75, 114, 229, 133, 203, 229, 34, 123, 210, 36, 230, 222, 116, 19, 54, 252, 201, + 85, 40, 251, 190, 4, 55, 16, 27, 27, 27, 210, 176, 12, 131, 129, 232, 37, 209, 82, 155, 15, 166, 127, 68, + 26, 140, 70, 35, 237, 199, 142, 241, 171, 235, 174, 163, 215, 106, 37, 133, 192, 200, 245, 114, 217, 36, + 151, 39, 3, 201, 156, 19, 201, 167, 56, 149, 36, 63, 210, 42, 3, 168, 218, 188, 153, 255, 92, 190, 156, + 195, 85, 85, 62, 95, 81, 55, 144, 86, 80, 64, 70, 177, 39, 162, 187, 146, 220, 133, 122, 46, 56, 213, 241, + 163, 36, 11, 6, 250, 9, 214, 80, 33, 205, 217, 149, 149, 149, 135, 240, 119, 143, 148, 107, 175, 64, 71, + 228, 10, 244, 165, 193, 130, 192, 69, 134, 159, 31, 86, 101, 101, 101, 189, 195, 225, 112, 26, 141, 70, + 147, 22, 140, 58, 119, 218, 52, 95, 60, 19, 101, 230, 122, 158, 224, 229, 207, 97, 6, 198, 202, 8, 150, + 193, 96, 224, 221, 199, 31, 231, 133, 123, 238, 33, 30, 127, 141, 149, 114, 59, 184, 148, 148, 196, 83, + 205, 217, 93, 205, 68, 35, 111, 68, 229, 136, 114, 169, 36, 3, 158, 195, 103, 95, 251, 245, 175, 153, 123, + 222, 121, 76, 93, 176, 0, 167, 211, 73, 20, 225, 139, 249, 223, 255, 62, 91, 159, 127, 30, 103, 71, 71, + 128, 128, 14, 165, 47, 86, 47, 48, 231, 170, 171, 200, 155, 49, 3, 167, 203, 21, 182, 4, 107, 180, 67, 154, + 120, 95, 184, 247, 94, 106, 170, 171, 73, 37, 80, 254, 152, 232, 151, 81, 6, 217, 107, 53, 205, 186, 154, + 15, 22, 200, 180, 194, 168, 251, 160, 72, 73, 218, 80, 34, 189, 79, 1, 142, 214, 212, 240, 200, 69, 23, + 241, 208, 71, 31, 145, 51, 110, 28, 78, 167, 19, 147, 217, 76, 222, 204, 153, 52, 238, 218, 21, 17, 38, 66, + 229, 51, 184, 241, 4, 169, 149, 98, 168, 13, 117, 190, 53, 24, 12, 116, 117, 117, 117, 239, 217, 179, 167, + 1, 127, 7, 119, 165, 193, 67, 87, 80, 202, 60, 61, 64, 57, 55, 75, 125, 157, 218, 218, 218, 99, 141, 141, + 141, 173, 242, 93, 38, 67, 201, 36, 107, 194, 4, 146, 114, 115, 113, 162, 211, 214, 85, 64, 57, 72, 92, 64, + 82, 118, 54, 217, 147, 38, 1, 158, 149, 226, 214, 247, 222, 227, 47, 63, 249, 137, 79, 131, 36, 157, 117, + 38, 189, 143, 85, 36, 181, 51, 244, 98, 20, 255, 13, 118, 184, 177, 244, 223, 56, 197, 85, 45, 15, 121, 57, + 156, 118, 59, 47, 220, 123, 47, 110, 183, 27, 45, 218, 58, 138, 225, 129, 211, 233, 36, 115, 252, 120, 230, + 172, 94, 141, 141, 192, 165, 232, 72, 64, 105, 214, 144, 252, 14, 99, 98, 98, 88, 240, 195, 31, 122, 191, + 208, 251, 200, 142, 92, 24, 141, 70, 118, 126, 250, 41, 31, 60, 251, 44, 41, 248, 31, 150, 174, 212, 92, + 41, 181, 235, 193, 100, 72, 48, 249, 164, 188, 175, 154, 134, 76, 121, 63, 233, 172, 208, 198, 67, 135, + 248, 253, 170, 85, 244, 245, 244, 96, 50, 121, 244, 22, 5, 115, 231, 6, 44, 40, 245, 14, 63, 7, 247, 162, + 34, 210, 139, 139, 113, 107, 17, 1, 95, 16, 168, 171, 171, 107, 169, 171, 171, 107, 69, 221, 193, 125, 164, + 69, 135, 38, 208, 235, 236, 164, 170, 4, 233, 236, 236, 236, 172, 174, 174, 174, 211, 34, 3, 183, 203, 69, + 98, 102, 38, 89, 165, 165, 170, 7, 216, 234, 25, 210, 51, 184, 240, 28, 235, 144, 146, 147, 131, 203, 233, + 228, 159, 143, 63, 206, 239, 175, 186, 10, 163, 219, 237, 119, 144, 172, 156, 72, 169, 145, 36, 139, 34, + 153, 85, 62, 83, 166, 96, 4, 76, 205, 12, 169, 20, 106, 201, 64, 229, 186, 117, 124, 249, 246, 219, 81, + 130, 165, 3, 156, 126, 199, 29, 36, 101, 100, 248, 162, 136, 135, 194, 153, 66, 46, 44, 122, 129, 242, 171, + 175, 238, 215, 94, 69, 17, 150, 144, 118, 64, 190, 249, 171, 95, 33, 138, 162, 79, 38, 5, 35, 61, 74, 183, + 2, 53, 217, 116, 50, 41, 216, 162, 80, 41, 251, 164, 48, 53, 123, 190, 248, 130, 95, 46, 93, 202, 193, 141, + 27, 1, 40, 58, 237, 52, 223, 46, 68, 37, 244, 56, 143, 4, 56, 184, 79, 153, 66, 172, 215, 193, 93, 11, 236, + 217, 179, 167, 206, 225, 112, 116, 227, 175, 56, 209, 173, 121, 16, 244, 103, 34, 4, 117, 114, 229, 146, + 28, 221, 183, 109, 219, 118, 104, 249, 242, 229, 115, 135, 170, 178, 20, 69, 17, 163, 209, 72, 222, 172, + 89, 84, 127, 246, 153, 223, 119, 39, 114, 150, 12, 103, 200, 203, 237, 6, 74, 151, 45, 163, 249, 208, 33, + 94, 188, 230, 26, 182, 111, 216, 224, 139, 27, 3, 254, 166, 65, 229, 57, 103, 3, 249, 184, 12, 54, 14, 150, + 90, 82, 218, 125, 77, 244, 71, 49, 151, 231, 103, 6, 214, 252, 238, 119, 156, 241, 237, 111, 131, 32, 132, + 181, 63, 210, 104, 134, 195, 225, 32, 173, 176, 144, 153, 215, 93, 199, 231, 191, 249, 141, 111, 194, 25, + 108, 127, 25, 10, 228, 187, 98, 164, 247, 46, 32, 38, 54, 150, 51, 254, 253, 223, 61, 159, 69, 251, 77, + 216, 194, 100, 48, 80, 249, 217, 103, 108, 123, 255, 125, 159, 31, 168, 180, 120, 83, 6, 91, 61, 145, 191, + 233, 96, 251, 218, 64, 242, 72, 210, 126, 74, 201, 129, 191, 23, 182, 5, 168, 222, 184, 145, 71, 23, 45, + 226, 146, 187, 239, 230, 204, 239, 127, 159, 172, 146, 18, 218, 15, 29, 242, 221, 255, 68, 59, 25, 195, 13, + 202, 49, 36, 193, 13, 20, 120, 15, 154, 215, 106, 12, 109, 219, 182, 109, 63, 224, 24, 96, 7, 161, 238, + 160, 183, 229, 191, 114, 126, 86, 154, 9, 221, 91, 183, 110, 61, 20, 228, 191, 167, 132, 177, 21, 21, 126, + 25, 42, 11, 161, 55, 200, 203, 28, 3, 28, 252, 228, 19, 30, 159, 59, 151, 189, 27, 54, 144, 68, 127, 44, + 25, 229, 10, 78, 77, 67, 101, 150, 37, 229, 177, 29, 131, 73, 102, 149, 116, 162, 21, 164, 244, 93, 34, + 176, 251, 211, 79, 169, 92, 183, 14, 147, 81, 10, 199, 24, 69, 56, 66, 4, 230, 221, 126, 59, 9, 41, 41, 62, + 45, 214, 72, 47, 75, 165, 60, 109, 192, 116, 175, 239, 149, 35, 234, 191, 23, 190, 240, 250, 94, 125, 240, + 167, 63, 249, 98, 92, 41, 77, 121, 106, 90, 39, 165, 60, 81, 59, 78, 40, 152, 60, 82, 59, 72, 219, 76, 160, + 220, 147, 151, 65, 169, 201, 74, 4, 4, 187, 157, 119, 30, 124, 144, 231, 46, 186, 8, 131, 209, 168, 234, + 235, 165, 39, 168, 77, 186, 2, 144, 47, 59, 21, 96, 40, 144, 252, 236, 54, 111, 222, 44, 57, 184, 75, 110, + 110, 202, 205, 230, 242, 226, 232, 2, 122, 35, 88, 16, 124, 113, 225, 6, 132, 61, 123, 246, 212, 217, 237, + 118, 167, 86, 166, 163, 188, 242, 114, 44, 130, 160, 186, 87, 84, 175, 144, 86, 37, 70, 96, 223, 39, 159, + 96, 107, 109, 37, 30, 117, 161, 162, 70, 174, 148, 218, 44, 229, 25, 104, 3, 37, 163, 202, 245, 68, 196, + 43, 152, 10, 223, 13, 124, 246, 242, 203, 154, 215, 79, 20, 218, 194, 233, 112, 144, 53, 97, 2, 51, 174, + 185, 198, 231, 139, 53, 220, 227, 72, 109, 82, 112, 2, 102, 147, 137, 249, 223, 255, 190, 247, 75, 189, + 143, 228, 200, 133, 201, 100, 162, 169, 182, 150, 237, 239, 191, 79, 34, 193, 229, 129, 146, 76, 201, 181, + 90, 106, 178, 105, 32, 57, 165, 12, 65, 19, 140, 112, 169, 201, 36, 101, 25, 18, 128, 67, 27, 55, 210, 178, + 127, 191, 46, 205, 68, 114, 168, 105, 129, 19, 146, 146, 200, 157, 58, 85, 147, 49, 108, 48, 24, 176, 118, + 118, 246, 238, 221, 187, 183, 158, 254, 128, 241, 186, 223, 65, 8, 250, 52, 17, 66, 16, 51, 33, 32, 30, 60, + 120, 240, 216, 145, 35, 71, 154, 139, 138, 138, 198, 12, 53, 78, 146, 203, 237, 38, 189, 164, 132, 148, + 162, 34, 172, 53, 53, 17, 177, 27, 4, 252, 213, 230, 22, 252, 151, 11, 210, 247, 114, 65, 163, 118, 144, + 236, 96, 76, 60, 193, 86, 110, 131, 217, 101, 104, 160, 63, 66, 181, 242, 119, 82, 163, 199, 3, 59, 222, + 123, 143, 246, 230, 102, 146, 51, 51, 61, 135, 183, 70, 17, 150, 144, 180, 88, 91, 95, 120, 1, 103, 79, 15, + 6, 250, 219, 114, 184, 227, 98, 73, 2, 194, 6, 76, 191, 236, 50, 10, 230, 204, 193, 225, 112, 68, 9, 86, + 24, 67, 0, 182, 254, 227, 31, 116, 182, 181, 145, 70, 32, 169, 81, 115, 87, 80, 202, 149, 129, 250, 147, + 242, 59, 81, 241, 185, 60, 202, 187, 212, 55, 149, 33, 11, 12, 248, 239, 48, 148, 27, 202, 228, 114, 83, + 186, 159, 94, 231, 11, 165, 108, 118, 2, 57, 37, 37, 164, 230, 231, 227, 114, 58, 135, 60, 142, 12, 6, 3, + 53, 53, 53, 71, 26, 26, 26, 90, 232, 231, 112, 186, 14, 48, 42, 65, 143, 26, 44, 9, 106, 46, 59, 98, 103, + 103, 103, 71, 85, 85, 85, 189, 244, 131, 161, 36, 183, 203, 69, 124, 74, 10, 217, 83, 167, 170, 58, 232, + 234, 17, 106, 49, 89, 36, 242, 164, 92, 161, 13, 180, 50, 84, 11, 201, 48, 80, 48, 63, 181, 239, 149, 91, + 166, 149, 194, 75, 238, 255, 165, 166, 250, 143, 5, 90, 143, 28, 97, 239, 151, 95, 98, 16, 132, 33, 183, + 119, 52, 13, 95, 114, 56, 28, 228, 150, 149, 81, 118, 217, 101, 244, 50, 188, 78, 21, 162, 236, 42, 37, 41, + 204, 199, 188, 91, 111, 245, 124, 39, 138, 33, 175, 147, 104, 82, 79, 146, 121, 112, 235, 123, 239, 249, + 201, 31, 53, 179, 95, 176, 133, 223, 64, 114, 73, 141, 232, 12, 36, 151, 228, 247, 30, 72, 163, 37, 127, + 175, 44, 151, 94, 201, 149, 4, 121, 251, 56, 129, 188, 153, 51, 49, 91, 44, 158, 8, 238, 12, 177, 189, 129, + 93, 85, 85, 53, 118, 187, 93, 45, 130, 187, 252, 103, 186, 131, 94, 9, 150, 188, 125, 124, 62, 88, 130, 32, + 184, 0, 251, 246, 237, 219, 15, 104, 146, 137, 40, 34, 224, 9, 196, 169, 54, 33, 4, 27, 188, 225, 150, 212, + 202, 170, 20, 22, 202, 221, 127, 74, 129, 166, 84, 183, 43, 239, 117, 170, 101, 83, 10, 69, 249, 103, 106, + 170, 122, 165, 80, 19, 128, 157, 255, 247, 127, 68, 17, 230, 240, 18, 154, 121, 183, 223, 142, 217, 96, + 240, 51, 185, 195, 137, 39, 196, 83, 237, 247, 82, 30, 125, 192, 184, 229, 203, 25, 183, 116, 169, 71, 123, + 21, 69, 216, 194, 104, 50, 209, 210, 216, 200, 161, 141, 27, 137, 39, 144, 88, 13, 68, 98, 6, 146, 43, 67, + 145, 75, 106, 11, 63, 165, 60, 138, 33, 144, 100, 5, 115, 194, 215, 67, 66, 118, 149, 32, 77, 184, 5, 243, + 230, 41, 155, 109, 72, 216, 180, 105, 211, 1, 252, 247, 13, 168, 105, 176, 116, 71, 180, 244, 104, 34, 20, + 241, 180, 187, 156, 96, 249, 105, 177, 182, 109, 221, 122, 0, 233, 71, 26, 152, 1, 10, 102, 207, 246, 203, + 80, 173, 48, 225, 12, 169, 236, 210, 107, 37, 171, 86, 126, 175, 20, 40, 74, 18, 37, 255, 159, 150, 101, + 12, 6, 73, 205, 46, 111, 112, 233, 92, 176, 88, 96, 255, 250, 245, 216, 237, 118, 132, 232, 110, 194, 176, + 134, 211, 110, 167, 240, 244, 211, 25, 127, 238, 185, 84, 191, 255, 62, 38, 180, 151, 152, 106, 227, 83, + 18, 14, 167, 221, 122, 43, 6, 192, 25, 237, 35, 97, 13, 131, 32, 80, 187, 125, 59, 157, 205, 205, 36, 163, + 238, 140, 46, 15, 38, 42, 97, 56, 228, 176, 156, 168, 75, 242, 79, 254, 90, 114, 99, 80, 219, 234, 166, 22, + 17, 93, 175, 144, 51, 28, 11, 144, 63, 115, 166, 231, 89, 135, 56, 191, 74, 14, 238, 91, 183, 110, 61, 232, + 253, 72, 34, 87, 17, 225, 246, 172, 119, 13, 150, 90, 192, 93, 118, 86, 86, 214, 117, 119, 119, 247, 9, 6, + 195, 144, 213, 151, 46, 81, 36, 199, 123, 174, 148, 178, 197, 245, 218, 234, 106, 90, 34, 229, 78, 26, 53, + 103, 208, 225, 22, 102, 202, 50, 74, 87, 181, 21, 164, 148, 98, 128, 150, 234, 106, 90, 14, 31, 198, 96, + 50, 133, 220, 188, 17, 77, 193, 147, 91, 20, 49, 0, 115, 111, 185, 197, 111, 240, 202, 199, 146, 86, 99, + 74, 186, 191, 27, 143, 246, 106, 76, 121, 57, 165, 231, 159, 143, 221, 233, 12, 121, 61, 68, 211, 192, 9, + 224, 192, 198, 141, 136, 12, 108, 10, 148, 99, 164, 228, 145, 244, 122, 32, 25, 26, 204, 63, 76, 169, 29, + 210, 3, 148, 109, 227, 0, 146, 242, 242, 200, 156, 56, 17, 167, 203, 53, 228, 182, 54, 24, 141, 52, 55, 55, + 119, 84, 87, 87, 215, 123, 179, 84, 106, 176, 148, 93, 67, 87, 208, 43, 193, 130, 254, 74, 87, 106, 176, + 56, 116, 232, 80, 115, 77, 77, 77, 147, 20, 81, 119, 40, 112, 57, 157, 164, 22, 20, 144, 49, 105, 146, 95, + 68, 119, 61, 181, 182, 84, 214, 96, 106, 112, 165, 41, 78, 205, 28, 136, 226, 30, 35, 1, 53, 179, 145, 114, + 247, 161, 25, 232, 233, 234, 226, 200, 222, 189, 24, 53, 58, 131, 50, 138, 225, 131, 221, 225, 96, 226, + 121, 231, 49, 166, 162, 130, 62, 134, 207, 23, 75, 46, 28, 236, 192, 236, 155, 110, 34, 54, 62, 30, 49, 26, + 88, 84, 23, 56, 188, 109, 155, 159, 25, 48, 152, 123, 2, 140, 188, 60, 146, 94, 7, 147, 161, 193, 118, 48, + 234, 85, 58, 137, 178, 171, 19, 200, 46, 43, 35, 49, 43, 75, 147, 177, 100, 52, 26, 217, 191, 127, 127, 67, + 67, 67, 67, 155, 55, 139, 136, 113, 112, 7, 125, 19, 44, 240, 39, 88, 62, 230, 107, 183, 219, 173, 85, 85, + 85, 181, 158, 95, 136, 67, 74, 162, 203, 133, 197, 98, 33, 111, 230, 76, 63, 71, 119, 61, 65, 57, 176, 7, + 18, 14, 193, 28, 69, 67, 13, 185, 153, 82, 169, 205, 18, 129, 35, 85, 85, 158, 31, 14, 177, 189, 163, 105, + 120, 147, 232, 114, 17, 19, 19, 195, 236, 239, 125, 15, 59, 234, 166, 149, 83, 29, 95, 162, 236, 42, 37, 7, + 144, 54, 102, 12, 211, 175, 184, 162, 255, 204, 193, 104, 10, 219, 100, 48, 24, 232, 237, 238, 230, 216, + 254, 253, 88, 56, 177, 38, 125, 164, 49, 16, 201, 82, 147, 165, 161, 34, 131, 67, 133, 114, 12, 138, 244, + 135, 58, 41, 56, 237, 52, 143, 220, 117, 187, 135, 222, 230, 192, 86, 143, 75, 79, 143, 215, 135, 90, 25, + 193, 253, 84, 197, 65, 88, 64, 207, 4, 75, 46, 71, 253, 34, 186, 3, 142, 205, 155, 55, 239, 83, 254, 232, + 84, 19, 120, 58, 21, 4, 182, 182, 154, 150, 37, 156, 83, 176, 216, 47, 114, 225, 160, 252, 92, 32, 144, + 120, 141, 100, 121, 229, 175, 131, 169, 227, 143, 85, 87, 251, 218, 39, 154, 194, 59, 57, 92, 46, 202, 174, + 184, 130, 180, 49, 99, 124, 90, 97, 9, 90, 244, 25, 100, 121, 245, 1, 83, 175, 188, 146, 148, 220, 92, 156, + 14, 71, 200, 159, 61, 154, 6, 78, 24, 12, 88, 143, 31, 199, 218, 216, 232, 35, 88, 193, 226, 237, 41, 229, + 67, 168, 100, 82, 48, 114, 165, 36, 90, 122, 114, 112, 151, 143, 37, 164, 182, 241, 62, 207, 88, 149, 51, + 22, 79, 185, 189, 129, 77, 155, 54, 237, 39, 240, 120, 28, 221, 71, 113, 7, 125, 19, 44, 240, 84, 188, 218, + 105, 6, 108, 217, 178, 197, 227, 232, 174, 129, 217, 200, 5, 228, 87, 84, 16, 227, 13, 5, 32, 33, 212, 157, + 127, 168, 66, 66, 141, 88, 5, 219, 145, 19, 110, 229, 85, 134, 151, 104, 111, 104, 192, 133, 54, 237, 29, + 197, 240, 194, 229, 112, 144, 150, 155, 203, 212, 43, 174, 192, 238, 253, 76, 26, 87, 67, 153, 8, 148, 45, + 239, 2, 98, 205, 102, 102, 93, 119, 29, 81, 195, 160, 62, 96, 48, 26, 233, 108, 106, 194, 97, 181, 6, 152, + 8, 195, 105, 39, 222, 64, 187, 12, 149, 11, 212, 112, 149, 169, 131, 29, 87, 18, 92, 64, 124, 82, 18, 99, + 166, 79, 199, 165, 193, 70, 17, 131, 193, 128, 205, 102, 115, 237, 220, 185, 83, 233, 224, 174, 166, 189, + 210, 37, 201, 210, 43, 193, 18, 101, 87, 41, 201, 213, 139, 236, 218, 181, 171, 254, 88, 83, 83, 167, 81, + 131, 99, 84, 92, 78, 39, 153, 227, 199, 147, 82, 80, 16, 224, 135, 165, 151, 86, 87, 27, 48, 131, 253, 95, + 168, 33, 159, 64, 149, 2, 74, 10, 55, 209, 213, 212, 228, 9, 122, 23, 133, 46, 224, 2, 102, 92, 115, 13, + 38, 163, 81, 213, 183, 241, 84, 199, 149, 116, 15, 201, 185, 189, 120, 249, 114, 242, 42, 42, 112, 244, + 245, 13, 181, 200, 81, 140, 0, 12, 64, 79, 91, 27, 78, 151, 43, 168, 153, 77, 66, 56, 201, 166, 225, 254, + 79, 40, 160, 156, 100, 157, 64, 70, 105, 41, 169, 5, 5, 154, 200, 90, 147, 201, 68, 125, 125, 125, 211, + 254, 253, 251, 143, 226, 63, 135, 71, 140, 15, 150, 30, 195, 52, 72, 80, 146, 43, 185, 138, 81, 60, 122, + 244, 104, 235, 222, 189, 123, 235, 23, 157, 121, 102, 217, 80, 227, 222, 184, 156, 78, 226, 210, 211, 201, + 153, 57, 147, 227, 117, 117, 186, 110, 117, 249, 224, 86, 106, 227, 244, 2, 181, 85, 99, 159, 213, 138, + 195, 102, 195, 100, 177, 68, 67, 53, 232, 0, 14, 155, 141, 188, 217, 179, 41, 62, 235, 44, 14, 254, 223, + 255, 97, 34, 248, 68, 122, 34, 40, 39, 2, 185, 83, 230, 204, 85, 171, 16, 32, 218, 39, 116, 132, 238, 182, + 54, 68, 212, 253, 174, 78, 117, 161, 56, 156, 80, 43, 143, 94, 101, 171, 18, 242, 73, 214, 9, 228, 207, + 158, 141, 197, 98, 193, 214, 219, 59, 228, 123, 27, 12, 6, 42, 43, 43, 107, 172, 86, 107, 167, 32, 8, 106, + 4, 75, 42, 130, 110, 161, 87, 13, 150, 28, 1, 114, 213, 235, 135, 213, 187, 125, 199, 142, 253, 218, 228, + 32, 98, 196, 19, 92, 77, 207, 1, 71, 131, 169, 185, 245, 162, 174, 86, 106, 174, 228, 234, 120, 119, 95, + 31, 206, 190, 62, 136, 154, 8, 117, 1, 81, 20, 49, 26, 12, 148, 95, 115, 141, 159, 52, 149, 160, 166, 181, + 28, 76, 2, 207, 248, 180, 3, 89, 227, 199, 51, 225, 220, 115, 163, 129, 69, 117, 6, 135, 247, 40, 165, 112, + 240, 1, 29, 77, 178, 85, 62, 134, 228, 82, 84, 78, 178, 10, 231, 207, 215, 148, 241, 108, 218, 180, 169, + 26, 207, 112, 141, 56, 255, 43, 208, 63, 193, 82, 146, 43, 63, 71, 185, 77, 155, 54, 237, 213, 42, 35, 55, + 178, 221, 19, 4, 182, 186, 174, 123, 129, 78, 16, 76, 144, 25, 1, 151, 205, 134, 163, 175, 47, 234, 131, + 165, 35, 56, 28, 14, 74, 207, 63, 159, 180, 194, 194, 0, 103, 247, 83, 129, 124, 34, 176, 3, 101, 151, 95, + 78, 98, 106, 42, 238, 168, 233, 88, 87, 232, 179, 90, 7, 36, 41, 224, 79, 0, 162, 24, 62, 72, 99, 82, 242, + 103, 204, 159, 61, 27, 151, 56, 244, 217, 78, 16, 4, 68, 81, 100, 203, 230, 205, 251, 233, 87, 144, 5, 219, + 65, 168, 219, 233, 85, 239, 38, 66, 1, 117, 83, 161, 19, 136, 217, 178, 101, 75, 77, 119, 87, 151, 221, + 100, 50, 89, 220, 67, 52, 17, 184, 28, 14, 178, 39, 79, 38, 49, 43, 11, 123, 115, 51, 102, 69, 198, 209, 1, + 63, 188, 144, 26, 90, 122, 29, 112, 21, 69, 144, 111, 27, 142, 34, 236, 225, 118, 56, 72, 202, 202, 98, + 210, 165, 151, 242, 213, 83, 79, 97, 193, 51, 120, 229, 19, 233, 137, 160, 102, 30, 116, 1, 49, 102, 51, + 83, 175, 184, 2, 103, 180, 63, 232, 15, 110, 119, 128, 89, 80, 126, 141, 98, 248, 33, 159, 219, 164, 9, 53, + 125, 194, 4, 210, 75, 74, 112, 217, 237, 67, 30, 83, 70, 163, 145, 166, 163, 71, 59, 190, 217, 181, 171, + 206, 251, 81, 196, 249, 95, 65, 228, 104, 176, 148, 174, 23, 46, 128, 131, 7, 15, 54, 213, 212, 214, 30, + 51, 153, 205, 67, 222, 78, 234, 114, 58, 73, 26, 51, 134, 236, 178, 50, 63, 167, 220, 40, 70, 22, 193, 76, + 71, 150, 216, 88, 140, 49, 49, 184, 197, 232, 33, 190, 122, 74, 46, 96, 218, 149, 87, 98, 98, 104, 75, 87, + 81, 246, 223, 62, 160, 96, 225, 66, 114, 103, 206, 196, 105, 179, 133, 252, 25, 163, 233, 228, 82, 76, 82, + 82, 208, 88, 124, 81, 146, 53, 114, 144, 183, 137, 3, 200, 155, 61, 155, 216, 164, 36, 220, 26, 68, 112, + 55, 91, 44, 236, 217, 187, 183, 174, 177, 177, 177, 213, 251, 145, 26, 185, 210, 61, 244, 78, 176, 160, + 191, 205, 2, 76, 132, 54, 155, 173, 115, 199, 142, 29, 7, 181, 216, 73, 40, 138, 34, 38, 163, 145, 130, + 211, 79, 199, 73, 4, 237, 35, 213, 33, 148, 130, 87, 4, 140, 22, 11, 38, 139, 133, 168, 182, 66, 95, 112, + 218, 108, 228, 207, 153, 67, 222, 252, 249, 190, 200, 238, 131, 149, 174, 162, 236, 42, 37, 23, 158, 213, + 246, 212, 171, 174, 194, 104, 52, 162, 197, 89, 164, 81, 140, 28, 68, 192, 28, 27, 235, 123, 127, 50, 218, + 204, 40, 134, 14, 181, 49, 37, 165, 162, 5, 11, 52, 109, 11, 175, 255, 85, 175, 74, 128, 209, 136, 208, 94, + 129, 190, 77, 132, 114, 72, 4, 203, 215, 80, 130, 32, 184, 68, 81, 116, 108, 220, 184, 113, 207, 213, 87, + 95, 125, 166, 22, 19, 175, 27, 40, 152, 63, 31, 3, 129, 173, 31, 93, 97, 141, 28, 212, 124, 177, 98, 19, + 18, 48, 197, 196, 244, 71, 23, 142, 66, 23, 16, 93, 46, 44, 9, 9, 76, 185, 252, 114, 234, 190, 250, 42, 64, + 162, 14, 102, 92, 201, 39, 5, 23, 144, 156, 149, 197, 196, 243, 206, 195, 169, 129, 41, 35, 138, 145, 71, + 124, 74, 138, 239, 32, 231, 193, 56, 97, 71, 49, 188, 112, 3, 22, 131, 129, 252, 138, 10, 79, 252, 43, 141, + 198, 212, 87, 95, 125, 181, 23, 245, 0, 163, 114, 94, 167, 107, 68, 2, 193, 146, 200, 149, 82, 139, 229, 4, + 44, 155, 55, 111, 222, 111, 183, 219, 193, 235, 84, 55, 20, 56, 29, 14, 114, 203, 203, 73, 76, 75, 195, + 213, 214, 230, 247, 93, 116, 224, 143, 28, 212, 4, 110, 98, 102, 38, 6, 147, 9, 151, 221, 174, 255, 81, 57, + 202, 224, 112, 58, 41, 189, 240, 66, 62, 191, 255, 126, 220, 221, 221, 190, 207, 7, 59, 161, 202, 191, 179, + 3, 147, 150, 47, 39, 165, 176, 16, 187, 236, 94, 81, 232, 3, 46, 183, 155, 184, 212, 84, 44, 4, 110, 102, + 81, 142, 249, 40, 134, 15, 242, 58, 118, 1, 105, 37, 37, 164, 79, 156, 136, 83, 3, 249, 106, 52, 26, 105, + 107, 107, 179, 237, 216, 177, 163, 70, 150, 133, 26, 201, 2, 157, 147, 44, 189, 155, 8, 213, 52, 154, 126, + 126, 88, 187, 118, 237, 170, 111, 104, 104, 104, 214, 226, 224, 103, 183, 195, 65, 202, 216, 177, 100, 77, + 155, 230, 119, 46, 97, 68, 80, 109, 29, 66, 18, 2, 110, 32, 57, 47, 15, 163, 201, 20, 109, 7, 29, 194, 101, + 183, 147, 89, 90, 74, 193, 226, 197, 126, 7, 64, 15, 212, 150, 202, 129, 47, 13, 122, 17, 152, 114, 249, + 229, 195, 89, 220, 40, 134, 17, 110, 151, 139, 132, 172, 44, 44, 137, 137, 209, 177, 28, 34, 40, 39, 83, + 201, 255, 42, 62, 45, 13, 183, 6, 7, 60, 91, 44, 22, 170, 171, 171, 27, 106, 106, 106, 154, 188, 31, 73, + 59, 8, 35, 202, 60, 8, 145, 163, 193, 82, 106, 175, 164, 141, 15, 238, 246, 246, 246, 182, 111, 190, 249, + 166, 182, 164, 164, 36, 203, 97, 183, 15, 112, 155, 65, 100, 36, 138, 152, 205, 102, 10, 230, 207, 231, + 208, 231, 159, 71, 142, 39, 158, 78, 33, 175, 251, 180, 130, 2, 15, 225, 138, 6, 148, 212, 31, 188, 135, + 252, 78, 190, 236, 50, 246, 254, 227, 31, 1, 54, 2, 65, 118, 13, 248, 43, 253, 18, 217, 1, 164, 23, 23, 83, + 180, 104, 17, 78, 155, 45, 106, 30, 212, 33, 68, 167, 147, 132, 180, 52, 18, 210, 211, 233, 234, 234, 10, + 117, 113, 70, 37, 148, 138, 3, 55, 80, 184, 112, 97, 255, 110, 237, 33, 194, 96, 48, 176, 125, 219, 182, + 106, 151, 203, 213, 173, 240, 191, 138, 56, 146, 165, 119, 13, 150, 28, 114, 89, 235, 243, 195, 2, 250, + 190, 252, 242, 203, 221, 210, 15, 134, 154, 92, 64, 193, 233, 167, 251, 249, 97, 201, 123, 130, 238, 123, + 132, 14, 33, 0, 153, 19, 39, 6, 76, 204, 209, 164, 159, 228, 232, 235, 163, 100, 217, 50, 18, 51, 51, 131, + 110, 34, 81, 66, 254, 127, 55, 30, 243, 224, 184, 115, 207, 37, 33, 43, 11, 151, 211, 25, 242, 103, 138, + 166, 147, 79, 110, 183, 155, 152, 148, 20, 82, 139, 138, 2, 130, 207, 70, 49, 188, 16, 101, 87, 41, 185, + 240, 250, 95, 205, 155, 135, 75, 131, 221, 131, 82, 30, 95, 172, 95, 95, 133, 58, 177, 138, 24, 114, 5, + 145, 67, 176, 124, 227, 19, 255, 70, 115, 2, 226, 230, 205, 155, 171, 157, 78, 167, 54, 7, 63, 219, 237, + 228, 206, 152, 65, 124, 106, 170, 207, 36, 17, 17, 61, 65, 71, 144, 215, 185, 8, 196, 8, 130, 135, 96, 105, + 160, 190, 142, 34, 52, 112, 57, 28, 164, 21, 23, 83, 36, 51, 19, 6, 155, 96, 69, 197, 107, 105, 34, 16, + 128, 73, 151, 94, 26, 221, 57, 168, 99, 136, 162, 136, 201, 98, 33, 107, 210, 36, 191, 246, 87, 182, 121, + 20, 195, 3, 101, 61, 59, 129, 180, 210, 82, 178, 74, 75, 61, 155, 70, 134, 8, 131, 193, 64, 103, 103, 167, + 125, 243, 230, 205, 210, 1, 207, 17, 25, 96, 84, 66, 164, 152, 8, 149, 1, 71, 229, 68, 75, 168, 172, 172, + 172, 57, 122, 228, 72, 123, 86, 86, 86, 234, 80, 143, 205, 112, 219, 237, 164, 228, 231, 147, 85, 86, 70, + 253, 134, 13, 196, 40, 190, 143, 58, 97, 14, 63, 228, 117, 236, 6, 18, 115, 114, 72, 47, 42, 210, 36, 0, + 94, 20, 161, 131, 0, 76, 186, 248, 98, 170, 222, 122, 43, 64, 178, 170, 141, 43, 185, 20, 118, 2, 25, 227, + 199, 51, 118, 238, 92, 156, 189, 189, 209, 126, 160, 99, 8, 64, 94, 121, 121, 192, 103, 209, 93, 132, 35, + 7, 105, 34, 117, 2, 121, 115, 230, 16, 155, 154, 138, 221, 106, 29, 242, 125, 45, 102, 51, 251, 246, 238, + 109, 60, 112, 224, 192, 17, 250, 215, 70, 114, 114, 21, 213, 96, 133, 33, 130, 145, 43, 39, 224, 62, 122, + 244, 104, 235, 55, 187, 118, 29, 50, 91, 44, 67, 87, 97, 139, 34, 166, 152, 24, 10, 23, 44, 24, 180, 41, + 35, 10, 237, 160, 92, 218, 56, 129, 172, 73, 147, 136, 207, 202, 210, 36, 0, 94, 52, 133, 46, 57, 108, 54, + 10, 23, 47, 38, 49, 35, 195, 55, 182, 148, 219, 137, 148, 175, 69, 250, 205, 131, 197, 203, 151, 19, 151, + 145, 161, 153, 41, 35, 154, 66, 147, 156, 46, 23, 185, 229, 229, 126, 167, 101, 160, 120, 29, 133, 182, 16, + 21, 175, 229, 99, 171, 104, 209, 162, 128, 207, 79, 53, 153, 204, 102, 54, 111, 217, 178, 223, 110, 183, + 91, 5, 65, 144, 124, 165, 149, 36, 43, 98, 16, 41, 4, 11, 250, 251, 131, 220, 158, 235, 243, 195, 218, 180, + 105, 211, 62, 131, 65, 155, 199, 117, 187, 221, 20, 46, 90, 132, 1, 245, 160, 29, 17, 213, 67, 194, 16, + 242, 186, 118, 1, 249, 167, 157, 134, 217, 98, 137, 154, 134, 116, 14, 151, 211, 73, 74, 65, 1, 249, 11, + 22, 96, 39, 80, 56, 43, 33, 13, 120, 233, 120, 157, 9, 23, 92, 16, 237, 3, 17, 0, 151, 221, 78, 214, 164, + 73, 164, 20, 20, 32, 157, 34, 25, 109, 213, 145, 129, 124, 188, 185, 128, 24, 139, 133, 252, 185, 115, 113, + 105, 120, 96, 250, 134, 13, 27, 170, 240, 16, 43, 37, 185, 138, 56, 125, 69, 164, 17, 44, 57, 241, 246, + 211, 98, 173, 95, 191, 126, 143, 150, 126, 88, 57, 229, 229, 36, 102, 102, 250, 249, 97, 69, 76, 175, 8, + 67, 168, 145, 87, 55, 158, 131, 158, 139, 23, 46, 100, 168, 103, 77, 70, 17, 6, 16, 69, 12, 70, 35, 19, 47, + 186, 232, 132, 203, 89, 249, 152, 115, 0, 41, 5, 5, 140, 157, 55, 207, 179, 123, 48, 10, 93, 67, 10, 213, + 48, 102, 214, 44, 191, 67, 192, 163, 50, 118, 248, 33, 175, 107, 7, 144, 49, 105, 18, 25, 19, 38, 120, 220, + 47, 134, 8, 175, 255, 149, 115, 243, 230, 205, 213, 120, 214, 68, 17, 187, 123, 80, 66, 36, 248, 96, 201, + 33, 95, 212, 202, 27, 79, 216, 177, 99, 71, 205, 209, 163, 71, 59, 210, 211, 211, 83, 156, 78, 231, 64, + 247, 56, 33, 92, 14, 7, 73, 99, 198, 144, 51, 115, 38, 53, 31, 125, 4, 68, 131, 225, 13, 55, 228, 3, 95, + 210, 88, 184, 129, 148, 156, 28, 198, 204, 156, 137, 163, 175, 47, 170, 189, 136, 0, 56, 108, 54, 10, 23, + 46, 36, 33, 41, 9, 183, 204, 231, 67, 126, 248, 175, 136, 255, 24, 115, 2, 69, 139, 23, 19, 159, 157, 173, + 137, 159, 72, 20, 33, 134, 40, 34, 24, 141, 148, 44, 93, 202, 158, 119, 223, 245, 181, 179, 65, 150, 162, + 242, 85, 91, 72, 172, 70, 25, 96, 116, 236, 233, 167, 99, 73, 74, 162, 175, 179, 115, 200, 121, 152, 76, + 38, 170, 171, 171, 27, 171, 171, 171, 37, 255, 43, 181, 248, 87, 210, 74, 57, 34, 132, 121, 164, 104, 176, + 148, 139, 28, 101, 68, 119, 247, 209, 163, 71, 91, 170, 170, 170, 106, 45, 22, 203, 208, 51, 19, 69, 140, + 22, 11, 133, 139, 22, 169, 110, 125, 136, 98, 120, 160, 52, 25, 57, 128, 177, 243, 231, 147, 148, 159, 143, + 123, 136, 164, 57, 138, 240, 128, 219, 225, 32, 109, 220, 56, 114, 231, 204, 193, 78, 240, 115, 51, 228, + 131, 92, 4, 74, 206, 57, 103, 196, 203, 26, 197, 240, 193, 101, 183, 83, 188, 120, 49, 177, 22, 139, 170, + 149, 32, 42, 107, 181, 131, 114, 242, 148, 179, 156, 162, 51, 207, 212, 108, 225, 106, 177, 88, 248, 250, + 235, 175, 247, 216, 108, 182, 78, 175, 217, 40, 76, 12, 0, 0, 32, 0, 73, 68, 65, 84, 235, 142, 220, 76, 24, + 145, 26, 172, 72, 33, 88, 16, 216, 63, 124, 90, 44, 111, 99, 246, 174, 95, 191, 126, 151, 201, 100, 2, 81, + 28, 114, 114, 59, 28, 20, 156, 113, 6, 70, 212, 123, 70, 196, 244, 144, 48, 131, 178, 145, 39, 94, 112, 1, + 6, 131, 193, 19, 96, 84, 131, 118, 141, 166, 208, 38, 209, 237, 198, 20, 19, 67, 201, 242, 229, 62, 243, + 144, 212, 214, 202, 246, 23, 241, 72, 231, 248, 180, 52, 10, 230, 207, 199, 37, 5, 23, 141, 38, 221, 39, + 151, 205, 70, 86, 105, 41, 185, 179, 102, 249, 249, 227, 33, 187, 70, 161, 61, 164, 122, 118, 1, 113, 73, + 73, 228, 205, 158, 173, 233, 184, 90, 255, 197, 23, 187, 240, 183, 46, 69, 44, 185, 130, 200, 34, 88, 128, + 170, 137, 80, 98, 201, 226, 134, 13, 27, 246, 216, 251, 250, 180, 243, 195, 154, 58, 149, 148, 194, 66, + 191, 137, 32, 10, 237, 161, 20, 172, 34, 158, 6, 77, 76, 79, 167, 228, 172, 179, 60, 219, 242, 163, 136, + 24, 184, 236, 118, 138, 22, 47, 198, 108, 48, 4, 104, 136, 229, 73, 58, 198, 99, 204, 220, 185, 164, 20, + 21, 225, 214, 208, 17, 55, 138, 208, 66, 20, 69, 204, 241, 241, 148, 174, 88, 17, 245, 115, 29, 1, 168, + 141, 171, 236, 233, 211, 73, 41, 44, 212, 100, 92, 121, 207, 31, 236, 251, 122, 227, 198, 253, 222, 143, + 148, 154, 171, 129, 66, 223, 233, 22, 145, 68, 176, 228, 243, 175, 146, 104, 57, 1, 42, 43, 43, 107, 142, + 28, 61, 218, 46, 157, 89, 55, 148, 228, 114, 58, 137, 203, 202, 34, 119, 206, 28, 223, 185, 132, 17, 73, + 193, 195, 4, 74, 1, 96, 7, 138, 151, 45, 35, 181, 164, 4, 167, 195, 49, 228, 246, 140, 166, 240, 73, 206, + 190, 62, 50, 203, 202, 72, 159, 60, 57, 224, 204, 79, 169, 47, 72, 131, 219, 9, 20, 46, 93, 138, 193, 108, + 198, 45, 138, 33, 47, 123, 52, 105, 219, 15, 38, 94, 120, 33, 113, 241, 241, 81, 51, 225, 8, 192, 175, 238, + 129, 130, 69, 139, 48, 197, 199, 107, 50, 174, 204, 22, 11, 123, 246, 238, 61, 92, 93, 93, 221, 40, 203, + 66, 78, 178, 148, 127, 137, 8, 68, 18, 193, 146, 7, 27, 85, 211, 98, 137, 77, 77, 77, 45, 59, 118, 236, 56, + 104, 49, 155, 209, 66, 221, 105, 48, 24, 40, 90, 188, 56, 128, 122, 43, 3, 226, 69, 211, 169, 39, 101, 125, + 74, 13, 44, 0, 211, 174, 188, 82, 147, 118, 140, 166, 240, 74, 162, 203, 69, 108, 74, 10, 99, 23, 46, 244, + 17, 44, 100, 237, 47, 193, 13, 152, 13, 6, 138, 22, 45, 234, 15, 50, 27, 77, 17, 147, 156, 125, 125, 100, + 77, 153, 66, 225, 146, 37, 62, 51, 161, 132, 80, 203, 165, 72, 73, 200, 174, 242, 113, 101, 196, 227, 127, + 229, 118, 56, 52, 105, 75, 179, 201, 196, 87, 95, 125, 181, 91, 20, 197, 110, 153, 255, 149, 170, 246, 42, + 146, 54, 43, 69, 12, 193, 18, 251, 91, 69, 244, 38, 165, 31, 150, 19, 232, 219, 176, 126, 253, 46, 147, + 209, 168, 73, 158, 46, 187, 157, 130, 249, 243, 137, 49, 155, 131, 58, 227, 70, 161, 13, 228, 117, 235, 0, + 178, 202, 202, 40, 90, 186, 20, 71, 212, 60, 24, 145, 16, 221, 110, 138, 22, 47, 6, 2, 15, 41, 147, 107, + 175, 210, 38, 78, 36, 115, 242, 100, 77, 182, 145, 71, 17, 102, 16, 69, 4, 131, 129, 233, 215, 92, 227, + 107, 247, 168, 140, 29, 30, 200, 39, 77, 39, 144, 156, 151, 71, 78, 121, 57, 174, 190, 62, 77, 238, 239, + 114, 185, 248, 226, 243, 207, 119, 201, 178, 80, 250, 96, 69, 100, 179, 70, 12, 193, 146, 65, 62, 22, 149, + 231, 18, 178, 225, 203, 47, 171, 122, 108, 54, 16, 132, 161, 171, 176, 237, 118, 210, 75, 75, 73, 159, 50, + 37, 192, 148, 17, 113, 61, 37, 132, 80, 50, 102, 59, 48, 117, 229, 74, 98, 211, 211, 163, 209, 219, 35, 52, + 57, 237, 118, 114, 103, 207, 38, 62, 53, 85, 117, 169, 43, 245, 131, 188, 51, 206, 32, 54, 53, 53, 218, 15, + 34, 52, 217, 123, 123, 41, 57, 251, 108, 178, 38, 79, 14, 216, 85, 138, 236, 26, 197, 169, 67, 89, 231, 14, + 96, 204, 105, 167, 17, 159, 147, 163, 201, 169, 8, 70, 147, 137, 99, 205, 205, 93, 155, 183, 108, 57, 224, + 205, 114, 84, 56, 184, 67, 100, 18, 44, 240, 52, 148, 212, 120, 126, 142, 238, 59, 119, 238, 172, 61, 124, + 248, 112, 147, 217, 108, 30, 122, 38, 110, 55, 49, 201, 201, 252, 127, 246, 206, 59, 62, 138, 58, 255, 255, + 207, 153, 237, 155, 205, 38, 33, 148, 64, 32, 1, 164, 136, 72, 17, 69, 1, 233, 40, 210, 65, 176, 113, 69, + 209, 179, 159, 122, 222, 89, 142, 251, 121, 231, 233, 221, 217, 207, 198, 233, 89, 238, 244, 171, 162, 119, + 214, 83, 241, 16, 145, 206, 209, 68, 90, 144, 42, 77, 154, 64, 104, 233, 219, 166, 252, 254, 152, 157, 205, + 236, 100, 54, 5, 54, 36, 33, 121, 63, 30, 239, 199, 110, 54, 201, 206, 103, 230, 243, 254, 188, 63, 175, + 207, 187, 182, 29, 48, 192, 178, 181, 71, 19, 157, 30, 169, 166, 247, 250, 226, 79, 109, 209, 130, 243, + 166, 78, 69, 42, 43, 171, 155, 129, 53, 81, 173, 147, 18, 137, 144, 214, 174, 29, 205, 123, 244, 136, 59, + 188, 152, 27, 150, 229, 68, 219, 120, 52, 209, 217, 73, 170, 44, 227, 201, 204, 164, 199, 180, 105, 68, + 104, 210, 175, 181, 73, 198, 195, 75, 238, 176, 97, 136, 54, 27, 36, 193, 93, 231, 116, 58, 217, 188, 121, + 243, 15, 251, 247, 239, 207, 71, 155, 62, 171, 248, 43, 5, 48, 122, 162, 206, 10, 58, 171, 0, 86, 53, 220, + 132, 106, 97, 97, 97, 193, 218, 53, 107, 118, 36, 43, 14, 75, 149, 101, 114, 135, 14, 5, 154, 218, 230, + 212, 22, 25, 39, 50, 4, 156, 55, 117, 42, 233, 237, 219, 55, 197, 221, 156, 197, 172, 151, 107, 48, 31, 94, + 140, 11, 218, 237, 245, 210, 250, 194, 11, 145, 66, 161, 58, 31, 111, 19, 215, 30, 71, 74, 75, 57, 239, + 218, 107, 73, 107, 211, 38, 6, 178, 204, 61, 42, 155, 168, 230, 100, 124, 126, 70, 151, 143, 203, 225, 160, + 221, 128, 1, 154, 123, 48, 9, 243, 103, 183, 217, 248, 223, 255, 254, 183, 9, 40, 139, 134, 234, 88, 101, + 16, 170, 156, 133, 83, 121, 86, 1, 172, 40, 169, 6, 182, 42, 215, 16, 94, 178, 116, 233, 38, 65, 20, 147, + 98, 194, 150, 66, 33, 178, 46, 188, 144, 148, 204, 204, 88, 166, 139, 145, 234, 58, 136, 177, 161, 50, 134, + 87, 253, 153, 202, 64, 138, 223, 79, 175, 155, 111, 214, 42, 183, 39, 97, 254, 154, 184, 254, 178, 44, 203, + 100, 247, 235, 135, 64, 197, 163, 110, 4, 104, 214, 181, 43, 105, 185, 185, 200, 77, 89, 164, 103, 53, 203, + 145, 8, 169, 57, 57, 244, 184, 241, 198, 10, 61, 42, 161, 238, 117, 85, 67, 102, 35, 169, 68, 219, 227, + 156, 127, 62, 25, 157, 59, 35, 133, 195, 167, 61, 119, 8, 2, 193, 80, 136, 255, 105, 241, 87, 42, 141, 40, + 254, 10, 206, 78, 128, 5, 218, 100, 153, 15, 188, 18, 154, 252, 176, 124, 249, 242, 173, 133, 133, 133, + 145, 100, 52, 127, 150, 37, 9, 127, 118, 54, 173, 250, 244, 137, 115, 101, 52, 81, 114, 72, 127, 158, 10, + 16, 4, 206, 187, 254, 122, 154, 159, 119, 94, 210, 130, 47, 155, 168, 254, 146, 28, 14, 211, 226, 252, 243, + 73, 105, 214, 172, 194, 113, 87, 66, 139, 19, 113, 250, 124, 168, 77, 125, 40, 207, 122, 146, 202, 202, + 232, 121, 211, 77, 248, 179, 178, 44, 245, 108, 147, 206, 61, 117, 138, 3, 179, 64, 187, 193, 131, 147, + 182, 174, 236, 118, 59, 7, 14, 28, 56, 182, 113, 227, 198, 31, 162, 31, 37, 178, 96, 157, 149, 116, 54, 2, + 44, 213, 240, 106, 213, 151, 144, 239, 191, 255, 254, 199, 157, 59, 118, 28, 72, 138, 155, 80, 81, 176, 57, + 28, 228, 14, 27, 150, 16, 142, 55, 45, 254, 154, 145, 113, 2, 117, 142, 0, 190, 204, 76, 46, 184, 243, 78, + 173, 161, 111, 61, 112, 93, 52, 113, 237, 178, 26, 237, 249, 217, 252, 252, 243, 99, 1, 206, 198, 53, 214, + 182, 95, 63, 109, 19, 168, 7, 99, 109, 226, 218, 101, 57, 28, 38, 45, 55, 151, 222, 119, 222, 105, 25, 236, + 222, 68, 53, 35, 213, 240, 170, 179, 222, 227, 181, 253, 176, 97, 90, 235, 177, 36, 204, 155, 203, 233, + 100, 237, 154, 53, 223, 159, 56, 113, 226, 56, 241, 25, 132, 230, 229, 108, 28, 214, 89, 67, 103, 35, 192, + 18, 168, 40, 55, 49, 55, 161, 32, 8, 114, 36, 18, 41, 90, 185, 106, 213, 86, 135, 211, 153, 20, 19, 182, + 20, 14, 147, 51, 120, 48, 14, 155, 237, 236, 118, 40, 159, 97, 50, 78, 94, 8, 232, 245, 203, 95, 146, 209, + 165, 11, 82, 147, 123, 176, 81, 176, 162, 170, 216, 92, 46, 90, 95, 114, 73, 156, 86, 142, 0, 46, 143, 135, + 150, 189, 123, 39, 197, 141, 209, 196, 13, 131, 195, 165, 165, 244, 188, 249, 102, 50, 59, 119, 142, 129, + 172, 179, 122, 119, 62, 3, 20, 91, 107, 104, 200, 39, 181, 77, 27, 90, 93, 112, 65, 210, 116, 172, 32, 138, + 44, 89, 186, 244, 59, 32, 18, 173, 127, 149, 200, 61, 120, 182, 197, 183, 3, 103, 33, 192, 50, 5, 186, 27, + 81, 178, 100, 96, 101, 209, 162, 69, 223, 201, 178, 156, 148, 107, 202, 225, 48, 153, 93, 187, 146, 209, + 181, 171, 165, 249, 186, 174, 253, 236, 13, 137, 49, 188, 234, 207, 49, 2, 100, 118, 234, 68, 175, 91, 111, + 37, 82, 90, 90, 213, 116, 52, 209, 89, 68, 170, 162, 208, 186, 111, 95, 32, 222, 61, 152, 214, 169, 19, + 105, 237, 218, 53, 181, 199, 105, 68, 164, 68, 187, 103, 92, 244, 192, 3, 177, 196, 7, 40, 215, 181, 70, + 253, 209, 196, 213, 211, 181, 70, 138, 0, 109, 250, 245, 35, 37, 43, 75, 179, 96, 157, 38, 137, 162, 72, + 65, 65, 129, 180, 108, 217, 178, 173, 134, 75, 24, 99, 176, 206, 250, 196, 123, 123, 93, 15, 160, 22, 201, + 8, 164, 43, 180, 205, 89, 187, 118, 237, 142, 252, 35, 71, 138, 211, 210, 210, 82, 165, 211, 20, 38, 189, + 242, 116, 187, 193, 131, 57, 182, 101, 75, 220, 133, 235, 13, 217, 108, 40, 138, 130, 160, 170, 150, 139, + 171, 190, 145, 254, 236, 244, 13, 245, 146, 223, 253, 14, 111, 203, 150, 132, 139, 138, 234, 112, 84, 77, + 116, 166, 73, 142, 86, 243, 246, 164, 166, 18, 41, 46, 198, 134, 166, 165, 91, 245, 238, 141, 51, 53, 149, + 112, 113, 113, 93, 15, 177, 137, 206, 32, 69, 138, 139, 233, 118, 221, 117, 108, 255, 215, 191, 56, 184, + 120, 113, 131, 219, 192, 84, 64, 181, 217, 16, 85, 85, 107, 80, 95, 199, 99, 129, 120, 148, 211, 126, 196, + 8, 109, 127, 72, 130, 53, 201, 233, 112, 176, 101, 243, 230, 125, 219, 183, 111, 63, 16, 253, 40, 81, 123, + 156, 179, 150, 206, 58, 11, 150, 137, 140, 86, 172, 56, 11, 214, 129, 3, 7, 242, 55, 228, 229, 237, 114, + 185, 92, 201, 185, 144, 44, 211, 126, 248, 112, 4, 234, 190, 92, 131, 217, 76, 43, 3, 205, 46, 184, 128, + 140, 94, 189, 226, 26, 83, 215, 55, 32, 104, 54, 61, 234, 129, 237, 29, 70, 141, 162, 203, 181, 215, 18, + 41, 41, 169, 179, 177, 53, 81, 146, 73, 16, 16, 4, 1, 193, 102, 195, 230, 112, 224, 112, 185, 112, 122, 60, + 184, 82, 82, 112, 251, 124, 184, 253, 126, 60, 105, 105, 56, 188, 94, 90, 116, 235, 70, 102, 180, 152, 175, + 46, 23, 237, 46, 189, 20, 151, 211, 137, 203, 231, 195, 229, 243, 225, 78, 77, 197, 227, 247, 227, 77, 75, + 195, 235, 247, 227, 73, 77, 197, 157, 146, 130, 211, 227, 193, 225, 114, 97, 115, 56, 16, 68, 81, 107, 244, + 158, 132, 102, 239, 77, 84, 55, 164, 42, 10, 162, 221, 78, 255, 71, 30, 193, 230, 116, 90, 214, 198, 170, + 79, 250, 204, 74, 23, 231, 140, 27, 135, 205, 235, 173, 179, 202, 244, 230, 103, 165, 143, 203, 149, 146, + 66, 219, 75, 47, 77, 90, 2, 145, 211, 233, 100, 229, 170, 85, 91, 36, 73, 42, 49, 149, 103, 168, 96, 189, + 58, 43, 253, 131, 156, 165, 22, 44, 85, 85, 85, 65, 83, 162, 150, 22, 44, 65, 16, 100, 85, 85, 131, 75, + 151, 46, 253, 110, 212, 168, 81, 189, 147, 49, 179, 145, 80, 136, 172, 139, 46, 194, 151, 149, 69, 248, + 240, 97, 28, 212, 47, 240, 18, 58, 113, 130, 1, 111, 188, 193, 242, 91, 110, 161, 112, 231, 206, 10, 19, + 175, 98, 109, 54, 62, 83, 100, 181, 232, 35, 128, 211, 239, 167, 255, 159, 254, 4, 130, 128, 210, 148, 45, + 214, 224, 72, 16, 4, 68, 155, 13, 209, 102, 195, 102, 183, 107, 32, 71, 20, 81, 100, 153, 72, 48, 72, 36, + 20, 162, 172, 168, 136, 178, 194, 66, 237, 245, 228, 73, 2, 5, 5, 132, 10, 11, 137, 20, 23, 35, 151, 148, + 32, 72, 18, 165, 199, 142, 33, 160, 201, 133, 3, 200, 123, 247, 93, 118, 44, 94, 140, 224, 245, 18, 81, 85, + 112, 58, 177, 167, 164, 224, 136, 2, 46, 111, 90, 26, 222, 244, 116, 252, 153, 153, 218, 251, 180, 52, 82, + 210, 210, 112, 186, 221, 56, 220, 110, 4, 65, 64, 85, 85, 100, 73, 66, 145, 36, 173, 98, 117, 147, 124, 53, + 8, 10, 151, 149, 209, 230, 210, 75, 233, 117, 247, 221, 172, 125, 246, 89, 236, 84, 238, 250, 170, 11, 178, + 210, 251, 17, 160, 215, 3, 15, 144, 218, 177, 35, 123, 62, 255, 188, 78, 117, 176, 113, 99, 212, 117, 109, + 235, 11, 46, 32, 189, 99, 199, 88, 217, 147, 211, 33, 65, 16, 136, 72, 18, 139, 22, 46, 204, 35, 113, 123, + 156, 179, 222, 138, 117, 86, 2, 44, 3, 89, 185, 7, 245, 114, 13, 206, 37, 75, 150, 108, 42, 45, 45, 85, 5, + 16, 78, 23, 64, 43, 145, 8, 190, 172, 44, 178, 46, 185, 132, 93, 159, 127, 142, 139, 120, 139, 204, 153, + 92, 56, 102, 18, 128, 162, 221, 187, 177, 185, 221, 12, 251, 224, 3, 190, 30, 61, 154, 178, 252, 252, 122, + 7, 178, 244, 49, 24, 139, 138, 14, 120, 224, 1, 90, 246, 238, 77, 168, 176, 176, 110, 7, 214, 68, 85, 146, + 32, 138, 216, 236, 118, 108, 14, 7, 54, 155, 13, 85, 85, 137, 132, 66, 148, 22, 20, 80, 144, 159, 207, 177, + 253, 251, 57, 186, 119, 175, 198, 251, 247, 115, 242, 208, 33, 10, 243, 243, 9, 20, 22, 18, 44, 46, 70, 10, + 6, 17, 208, 26, 205, 218, 209, 128, 148, 27, 112, 1, 41, 209, 159, 65, 147, 209, 93, 203, 150, 17, 64, 147, + 17, 157, 195, 16, 179, 104, 232, 127, 39, 2, 46, 151, 11, 79, 106, 42, 41, 25, 25, 164, 103, 101, 209, 188, + 109, 91, 90, 182, 111, 79, 171, 142, 29, 105, 213, 161, 3, 205, 219, 181, 195, 223, 188, 57, 110, 159, 15, + 81, 20, 145, 37, 9, 57, 28, 70, 150, 36, 206, 210, 131, 117, 131, 167, 72, 73, 9, 23, 222, 119, 31, 123, + 231, 206, 165, 96, 211, 38, 60, 104, 243, 46, 66, 12, 136, 215, 133, 46, 179, 146, 22, 29, 192, 116, 249, + 201, 79, 184, 232, 233, 167, 89, 54, 109, 90, 12, 89, 156, 233, 49, 90, 29, 100, 245, 196, 145, 220, 225, + 195, 177, 187, 92, 132, 146, 96, 193, 178, 219, 237, 28, 216, 191, 255, 228, 234, 213, 171, 119, 68, 63, + 210, 227, 175, 26, 149, 139, 176, 49, 1, 44, 115, 209, 81, 117, 211, 166, 77, 123, 119, 239, 222, 125, 176, + 75, 231, 206, 109, 147, 33, 84, 130, 40, 210, 254, 178, 203, 216, 241, 249, 231, 21, 76, 191, 230, 0, 238, + 218, 38, 35, 184, 83, 209, 110, 248, 68, 94, 30, 221, 110, 187, 141, 33, 239, 191, 207, 130, 41, 83, 8, + 159, 60, 137, 141, 138, 39, 191, 51, 185, 232, 141, 207, 199, 120, 162, 10, 162, 213, 99, 233, 245, 203, + 95, 18, 110, 114, 13, 214, 75, 18, 109, 54, 236, 78, 39, 182, 104, 185, 147, 96, 105, 41, 199, 246, 239, + 231, 240, 238, 221, 236, 223, 178, 133, 3, 91, 183, 242, 227, 247, 223, 115, 108, 223, 62, 138, 142, 30, + 37, 16, 14, 163, 167, 149, 232, 64, 74, 140, 178, 13, 13, 64, 217, 163, 236, 52, 177, 46, 167, 250, 255, + 234, 96, 203, 8, 198, 172, 10, 236, 0, 40, 161, 16, 197, 161, 16, 133, 199, 142, 177, 127, 199, 14, 140, + 169, 45, 46, 65, 192, 151, 150, 70, 243, 220, 92, 178, 187, 118, 37, 183, 103, 79, 58, 244, 234, 69, 155, + 206, 157, 201, 104, 221, 26, 167, 219, 141, 34, 203, 72, 225, 48, 146, 158, 186, 222, 68, 117, 78, 138, 36, + 225, 202, 200, 96, 224, 147, 79, 50, 123, 226, 68, 36, 89, 142, 121, 13, 172, 18, 102, 206, 4, 25, 1, 147, + 81, 255, 134, 129, 142, 147, 38, 209, 255, 213, 87, 137, 148, 149, 81, 248, 253, 247, 21, 254, 247, 76, + 235, 95, 115, 56, 134, 67, 20, 181, 82, 67, 73, 74, 26, 113, 185, 92, 172, 91, 183, 238, 251, 163, 199, + 142, 29, 35, 222, 192, 97, 174, 222, 126, 86, 211, 217, 12, 176, 116, 121, 55, 2, 245, 152, 21, 75, 16, 4, + 57, 16, 8, 20, 174, 88, 177, 98, 203, 249, 231, 159, 223, 54, 152, 4, 128, 37, 133, 195, 180, 29, 56, 16, + 119, 74, 10, 114, 105, 105, 189, 120, 184, 186, 4, 203, 64, 233, 161, 67, 132, 195, 97, 90, 92, 122, 41, + 67, 102, 206, 100, 225, 117, 215, 33, 149, 148, 196, 41, 38, 168, 155, 147, 149, 126, 93, 253, 180, 231, + 74, 79, 103, 224, 51, 207, 32, 186, 92, 245, 190, 231, 160, 160, 199, 244, 232, 175, 170, 170, 7, 22, 212, + 213, 144, 106, 135, 4, 1, 167, 219, 141, 221, 225, 64, 150, 101, 138, 143, 31, 231, 112, 94, 30, 123, 242, + 242, 216, 249, 237, 183, 236, 219, 180, 137, 252, 61, 123, 40, 46, 42, 66, 130, 56, 107, 148, 13, 240, 98, + 157, 49, 42, 24, 254, 86, 255, 123, 187, 225, 255, 140, 64, 12, 52, 25, 177, 161, 45, 104, 59, 229, 114, + 163, 255, 141, 108, 248, 204, 124, 208, 48, 127, 166, 168, 42, 101, 5, 5, 236, 46, 40, 224, 251, 188, 60, + 212, 15, 63, 196, 1, 248, 51, 50, 200, 238, 214, 141, 78, 23, 93, 196, 185, 3, 6, 208, 225, 130, 11, 200, + 204, 206, 198, 238, 112, 16, 10, 4, 146, 182, 17, 213, 23, 178, 146, 97, 237, 165, 254, 202, 112, 184, 164, + 132, 118, 35, 71, 210, 251, 215, 191, 102, 237, 95, 255, 90, 47, 244, 173, 145, 244, 131, 98, 135, 81, 163, + 24, 240, 143, 127, 160, 10, 2, 145, 162, 34, 202, 142, 28, 137, 253, 30, 234, 86, 215, 234, 250, 182, 89, + 183, 110, 100, 118, 239, 30, 43, 207, 112, 186, 36, 136, 34, 11, 22, 46, 220, 0, 132, 5, 65, 48, 90, 175, + 204, 109, 123, 213, 179, 53, 254, 10, 206, 98, 128, 165, 170, 42, 130, 32, 24, 19, 37, 140, 229, 26, 116, + 160, 101, 95, 180, 112, 97, 222, 47, 110, 186, 105, 100, 50, 54, 67, 37, 20, 34, 163, 67, 7, 90, 244, 238, + 205, 225, 229, 203, 113, 82, 183, 54, 80, 163, 13, 86, 1, 2, 199, 142, 129, 162, 16, 41, 46, 166, 205, 229, + 151, 51, 248, 141, 55, 88, 124, 195, 13, 68, 130, 193, 152, 32, 212, 21, 200, 50, 154, 26, 35, 192, 144, + 71, 31, 165, 69, 61, 118, 13, 138, 54, 27, 78, 175, 23, 81, 20, 81, 36, 137, 72, 36, 162, 165, 54, 11, 2, + 54, 187, 29, 187, 211, 137, 40, 138, 168, 170, 170, 89, 64, 34, 17, 228, 6, 108, 1, 209, 93, 127, 187, 215, + 173, 99, 219, 242, 229, 108, 93, 177, 130, 31, 214, 175, 231, 248, 143, 63, 18, 84, 20, 4, 202, 65, 145, + 135, 114, 208, 36, 18, 15, 162, 42, 3, 88, 34, 229, 160, 74, 183, 74, 153, 65, 22, 84, 4, 77, 250, 247, 72, + 148, 3, 47, 179, 255, 193, 42, 224, 216, 138, 245, 255, 43, 59, 121, 146, 45, 43, 86, 176, 113, 197, 10, + 196, 25, 51, 200, 72, 79, 167, 67, 159, 62, 156, 63, 116, 40, 131, 166, 78, 37, 51, 59, 155, 96, 67, 181, + 172, 234, 50, 234, 112, 32, 218, 237, 90, 98, 142, 162, 32, 133, 195, 40, 178, 140, 170, 170, 229, 50, 108, + 179, 161, 202, 50, 161, 64, 0, 37, 73, 101, 109, 146, 73, 82, 73, 9, 125, 30, 124, 144, 67, 203, 151, 115, + 100, 229, 74, 60, 209, 207, 207, 180, 171, 208, 74, 206, 66, 64, 219, 33, 67, 24, 248, 230, 155, 216, 156, + 78, 212, 72, 4, 169, 184, 152, 80, 105, 105, 76, 214, 140, 89, 102, 103, 58, 254, 202, 8, 176, 114, 134, + 15, 199, 237, 247, 19, 74, 66, 150, 182, 40, 138, 20, 156, 60, 25, 94, 190, 124, 249, 230, 232, 71, 102, + 96, 213, 40, 220, 131, 112, 22, 3, 44, 3, 89, 185, 8, 117, 68, 205, 202, 85, 171, 182, 31, 57, 114, 164, + 40, 61, 61, 221, 127, 218, 229, 26, 84, 21, 187, 199, 67, 238, 101, 151, 113, 96, 249, 242, 10, 89, 34, + 117, 177, 128, 226, 250, 183, 5, 2, 177, 191, 9, 23, 22, 146, 115, 229, 149, 12, 40, 45, 101, 217, 45, 183, + 32, 201, 114, 108, 19, 59, 83, 32, 203, 108, 166, 86, 129, 0, 208, 117, 234, 84, 186, 253, 226, 23, 245, + 182, 36, 131, 104, 179, 81, 112, 248, 48, 223, 45, 89, 194, 129, 173, 91, 57, 242, 195, 15, 148, 21, 20, + 16, 40, 46, 70, 180, 219, 113, 167, 164, 224, 203, 200, 32, 51, 59, 155, 236, 46, 93, 104, 211, 165, 11, + 173, 59, 119, 38, 61, 43, 11, 187, 221, 142, 20, 14, 19, 9, 135, 27, 76, 80, 181, 203, 235, 37, 28, 12, 50, + 243, 129, 7, 152, 243, 234, 171, 132, 209, 228, 196, 137, 6, 130, 252, 148, 203, 141, 25, 80, 37, 2, 88, + 198, 207, 161, 220, 250, 164, 187, 11, 205, 86, 44, 59, 241, 0, 75, 49, 252, 191, 209, 242, 37, 19, 47, 79, + 198, 19, 22, 22, 191, 51, 175, 17, 253, 51, 7, 196, 226, 40, 21, 160, 172, 160, 128, 117, 11, 23, 178, 106, + 225, 66, 22, 207, 156, 201, 157, 175, 191, 206, 185, 3, 6, 16, 40, 46, 110, 16, 243, 40, 8, 2, 14, 151, 11, + 187, 211, 137, 20, 137, 80, 112, 228, 8, 135, 118, 236, 224, 224, 246, 237, 252, 184, 99, 7, 199, 15, 30, + 164, 164, 160, 128, 80, 105, 41, 138, 44, 227, 246, 249, 240, 101, 100, 208, 170, 99, 71, 178, 187, 116, + 161, 231, 176, 97, 248, 91, 180, 168, 119, 32, 75, 145, 36, 236, 94, 47, 131, 95, 124, 145, 89, 163, 70, + 17, 57, 113, 34, 118, 176, 61, 211, 122, 204, 248, 115, 24, 104, 121, 225, 133, 12, 126, 251, 109, 236, + 169, 169, 200, 129, 0, 162, 195, 129, 28, 14, 107, 64, 150, 120, 217, 63, 147, 32, 80, 127, 175, 111, 138, + 34, 144, 59, 98, 68, 210, 230, 214, 229, 114, 145, 151, 151, 247, 195, 214, 173, 91, 15, 82, 30, 161, 98, + 229, 193, 111, 2, 88, 103, 9, 153, 221, 132, 49, 127, 240, 161, 67, 135, 242, 215, 173, 95, 191, 99, 212, + 168, 81, 23, 70, 146, 80, 92, 77, 10, 135, 201, 25, 54, 140, 111, 254, 244, 39, 100, 85, 141, 9, 176, 209, + 95, 121, 166, 22, 147, 206, 177, 155, 21, 132, 184, 77, 39, 84, 80, 64, 231, 235, 175, 231, 240, 170, 85, + 108, 126, 253, 117, 220, 196, 91, 22, 106, 123, 124, 250, 171, 177, 36, 67, 243, 30, 61, 232, 255, 212, 83, + 40, 146, 132, 82, 79, 173, 61, 130, 205, 70, 40, 16, 96, 246, 171, 175, 178, 97, 227, 70, 82, 32, 46, 147, + 201, 184, 89, 131, 6, 68, 50, 90, 180, 32, 183, 87, 47, 186, 15, 25, 194, 249, 67, 135, 210, 174, 123, 119, + 60, 169, 169, 132, 3, 1, 228, 104, 53, 242, 250, 72, 158, 212, 84, 246, 109, 218, 196, 63, 239, 190, 155, + 188, 85, 171, 72, 161, 220, 66, 101, 4, 69, 130, 197, 123, 193, 226, 243, 170, 64, 151, 206, 70, 203, 149, + 217, 69, 8, 229, 27, 131, 13, 77, 190, 19, 129, 171, 68, 22, 42, 43, 112, 85, 217, 123, 61, 46, 76, 5, 246, + 239, 216, 193, 159, 199, 141, 227, 39, 143, 60, 194, 229, 183, 221, 166, 101, 33, 38, 65, 119, 212, 6, 217, + 157, 78, 156, 30, 15, 193, 146, 18, 118, 109, 216, 192, 166, 69, 139, 216, 188, 116, 41, 251, 190, 251, + 142, 147, 249, 249, 132, 163, 127, 103, 156, 23, 253, 217, 72, 64, 41, 112, 209, 5, 23, 208, 181, 127, 127, + 4, 81, 68, 173, 103, 0, 11, 32, 82, 86, 70, 179, 94, 189, 24, 240, 204, 51, 44, 250, 197, 47, 98, 242, 3, + 241, 160, 188, 54, 116, 154, 21, 104, 145, 0, 193, 110, 167, 223, 11, 47, 224, 110, 213, 138, 72, 180, 86, + 155, 10, 168, 130, 128, 44, 8, 200, 196, 235, 218, 51, 233, 46, 52, 174, 129, 8, 224, 207, 205, 165, 85, + 159, 62, 72, 193, 96, 82, 244, 144, 221, 225, 96, 233, 255, 254, 183, 81, 85, 213, 210, 104, 245, 246, 70, + 9, 174, 224, 44, 7, 88, 209, 114, 13, 198, 61, 207, 24, 135, 21, 17, 4, 65, 82, 85, 53, 180, 112, 193, 130, + 188, 177, 99, 199, 94, 152, 140, 107, 202, 161, 16, 205, 207, 59, 143, 204, 238, 221, 57, 185, 105, 19, 78, + 195, 239, 206, 100, 224, 165, 241, 244, 22, 187, 121, 11, 192, 34, 5, 2, 116, 254, 201, 79, 248, 254, 141, + 55, 80, 100, 185, 130, 101, 1, 146, 63, 94, 243, 233, 18, 180, 9, 113, 250, 253, 12, 121, 249, 101, 220, + 153, 153, 245, 186, 98, 187, 20, 14, 211, 186, 115, 103, 30, 155, 55, 143, 247, 126, 247, 59, 190, 122, + 243, 77, 156, 148, 131, 44, 35, 233, 207, 190, 232, 232, 81, 214, 205, 159, 207, 183, 243, 231, 227, 181, + 219, 233, 208, 171, 23, 23, 95, 121, 37, 125, 199, 143, 167, 77, 231, 206, 40, 138, 66, 56, 16, 168, 87, + 49, 47, 14, 151, 139, 249, 175, 191, 206, 63, 31, 120, 128, 112, 56, 76, 58, 229, 160, 198, 248, 106, 197, + 137, 0, 88, 77, 64, 150, 104, 186, 142, 241, 217, 154, 23, 180, 149, 21, 202, 200, 88, 252, 222, 12, 162, + 244, 159, 101, 195, 171, 217, 244, 45, 163, 89, 236, 66, 165, 165, 252, 253, 129, 7, 200, 155, 55, 143, + 219, 95, 123, 13, 143, 223, 95, 111, 172, 59, 130, 32, 224, 244, 120, 16, 68, 145, 67, 223, 127, 207, 183, + 95, 124, 193, 55, 159, 126, 202, 158, 188, 60, 202, 100, 57, 230, 126, 117, 65, 204, 165, 102, 126, 182, + 18, 154, 21, 230, 202, 219, 110, 227, 39, 127, 249, 11, 118, 167, 147, 72, 61, 110, 176, 30, 46, 42, 162, + 203, 79, 126, 194, 241, 13, 27, 200, 251, 219, 223, 226, 54, 182, 51, 17, 64, 110, 229, 114, 203, 236, 221, + 187, 98, 237, 62, 85, 173, 208, 128, 207, 56, 54, 179, 238, 173, 141, 113, 26, 117, 111, 4, 232, 60, 120, + 48, 222, 22, 45, 146, 82, 180, 87, 16, 4, 130, 193, 32, 11, 22, 44, 200, 51, 92, 34, 66, 226, 246, 56, 245, + 71, 225, 213, 2, 157, 213, 0, 43, 74, 86, 214, 43, 35, 170, 118, 45, 94, 178, 100, 83, 81, 97, 161, 36, + 138, 162, 253, 116, 107, 45, 169, 178, 140, 211, 239, 39, 103, 196, 8, 142, 109, 218, 148, 112, 67, 169, + 45, 50, 187, 36, 141, 139, 73, 116, 58, 17, 244, 70, 156, 81, 146, 2, 1, 154, 247, 233, 67, 246, 21, 87, + 176, 239, 203, 47, 113, 88, 140, 51, 153, 227, 181, 50, 221, 235, 227, 189, 244, 217, 103, 105, 121, 241, + 197, 132, 235, 105, 220, 149, 145, 34, 193, 32, 54, 135, 131, 155, 95, 122, 137, 236, 78, 157, 248, 224, + 15, 127, 128, 104, 38, 147, 121, 179, 50, 91, 76, 100, 73, 98, 199, 218, 181, 108, 89, 187, 150, 207, 158, + 124, 146, 11, 199, 142, 101, 216, 180, 105, 156, 59, 96, 0, 162, 205, 70, 168, 172, 172, 94, 0, 45, 69, + 146, 104, 219, 189, 59, 23, 143, 24, 193, 134, 185, 115, 81, 21, 5, 23, 214, 214, 37, 43, 176, 85, 19, 235, + 85, 101, 64, 203, 248, 127, 58, 197, 29, 28, 12, 239, 173, 64, 21, 84, 156, 7, 43, 215, 160, 57, 150, 192, + 74, 97, 232, 125, 49, 5, 224, 188, 206, 157, 185, 100, 210, 36, 28, 46, 87, 121, 211, 233, 58, 36, 65, 16, + 112, 121, 189, 200, 178, 204, 150, 165, 75, 89, 248, 230, 155, 172, 159, 51, 135, 130, 210, 210, 24, 160, + 202, 192, 122, 14, 116, 210, 119, 68, 151, 221, 206, 141, 79, 62, 201, 229, 191, 252, 37, 225, 178, 50, 34, + 193, 224, 153, 190, 157, 154, 145, 170, 18, 41, 43, 227, 162, 63, 254, 145, 162, 109, 219, 216, 63, 111, + 94, 44, 169, 162, 54, 227, 156, 140, 46, 104, 163, 190, 236, 122, 211, 77, 8, 162, 72, 92, 181, 118, 85, + 69, 176, 219, 17, 108, 182, 56, 253, 108, 181, 78, 146, 77, 102, 93, 107, 28, 107, 135, 145, 35, 147, 38, + 191, 14, 135, 131, 221, 187, 118, 253, 184, 110, 221, 186, 221, 148, 99, 117, 115, 237, 171, 38, 11, 214, + 89, 70, 102, 125, 28, 179, 98, 1, 234, 182, 109, 219, 246, 111, 221, 182, 109, 111, 239, 222, 189, 207, 9, + 38, 65, 145, 40, 146, 68, 238, 229, 151, 179, 225, 197, 23, 145, 41, 15, 188, 53, 186, 144, 206, 20, 200, + 50, 222, 172, 35, 35, 3, 53, 234, 38, 44, 255, 99, 21, 68, 145, 115, 111, 187, 141, 31, 190, 252, 82, 139, + 252, 39, 126, 161, 39, 107, 188, 86, 230, 116, 25, 205, 53, 120, 193, 111, 127, 75, 167, 159, 253, 44, 41, + 65, 150, 103, 138, 164, 72, 4, 89, 150, 25, 125, 223, 125, 52, 107, 221, 154, 119, 238, 188, 19, 41, 16, + 136, 179, 90, 26, 21, 176, 145, 157, 68, 131, 1, 75, 74, 88, 244, 193, 7, 44, 251, 232, 35, 122, 12, 30, + 204, 232, 187, 239, 166, 199, 101, 151, 105, 64, 171, 142, 173, 120, 146, 36, 113, 206, 197, 23, 115, 239, + 199, 31, 179, 233, 235, 175, 249, 234, 241, 199, 217, 253, 237, 183, 90, 109, 41, 226, 99, 164, 42, 179, + 98, 37, 2, 86, 88, 252, 92, 21, 0, 211, 73, 151, 111, 17, 44, 65, 85, 117, 0, 150, 121, 157, 152, 129, 150, + 25, 92, 133, 209, 92, 102, 205, 154, 53, 99, 200, 61, 247, 48, 228, 150, 91, 72, 201, 200, 32, 88, 82, 82, + 167, 69, 112, 5, 65, 192, 233, 245, 162, 72, 18, 235, 230, 206, 101, 206, 140, 25, 108, 90, 186, 148, 136, + 170, 226, 6, 210, 168, 104, 9, 52, 186, 92, 141, 207, 53, 4, 164, 166, 164, 112, 195, 107, 175, 113, 209, + 213, 87, 19, 40, 44, 172, 23, 96, 191, 58, 164, 74, 18, 54, 151, 139, 75, 255, 254, 119, 190, 26, 55, 142, + 162, 237, 219, 113, 71, 127, 87, 27, 186, 215, 44, 91, 122, 152, 67, 139, 139, 47, 166, 205, 101, 151, 17, + 41, 43, 139, 211, 121, 138, 162, 96, 247, 122, 17, 82, 82, 144, 142, 30, 141, 139, 43, 60, 83, 100, 28, + 171, 4, 248, 90, 181, 34, 171, 95, 191, 164, 185, 7, 157, 46, 23, 203, 150, 47, 223, 84, 90, 90, 122, 82, + 16, 4, 61, 103, 201, 170, 254, 85, 163, 160, 179, 189, 85, 142, 145, 44, 173, 88, 130, 32, 72, 178, 44, 23, + 47, 94, 188, 56, 207, 233, 116, 86, 250, 5, 213, 37, 41, 20, 162, 69, 239, 222, 164, 117, 234, 20, 215, + 202, 225, 76, 75, 149, 121, 243, 112, 53, 107, 102, 169, 92, 164, 178, 50, 218, 12, 25, 66, 246, 229, 151, + 19, 162, 118, 142, 24, 102, 112, 101, 84, 72, 157, 174, 185, 134, 222, 15, 61, 164, 185, 5, 27, 136, 50, + 215, 73, 85, 20, 202, 10, 10, 184, 100, 234, 84, 110, 123, 251, 109, 210, 83, 83, 177, 161, 21, 200, 116, + 163, 185, 96, 220, 22, 236, 68, 3, 41, 250, 6, 232, 84, 20, 54, 44, 94, 204, 147, 83, 166, 240, 244, 164, + 73, 108, 93, 182, 12, 183, 207, 135, 35, 73, 173, 156, 78, 149, 34, 129, 0, 161, 210, 82, 186, 143, 28, + 201, 175, 190, 250, 138, 105, 175, 188, 66, 219, 14, 29, 128, 242, 66, 160, 149, 221, 171, 43, 202, 78, + 195, 171, 51, 193, 207, 122, 208, 188, 221, 130, 205, 32, 206, 24, 8, 239, 176, 96, 167, 225, 213, 124, + 205, 68, 236, 54, 189, 55, 222, 131, 8, 120, 28, 14, 134, 223, 112, 3, 247, 47, 89, 194, 152, 233, 211, + 113, 184, 92, 90, 144, 123, 29, 202, 172, 211, 237, 198, 149, 146, 194, 230, 37, 75, 120, 106, 226, 68, + 158, 154, 50, 133, 188, 37, 75, 112, 170, 42, 105, 104, 115, 98, 117, 159, 86, 115, 38, 2, 25, 105, 105, + 220, 241, 175, 127, 113, 225, 85, 87, 81, 86, 80, 208, 96, 192, 149, 78, 114, 40, 132, 183, 77, 27, 6, 191, + 241, 6, 206, 102, 205, 8, 83, 81, 151, 37, 227, 142, 18, 29, 22, 21, 160, 251, 93, 119, 97, 247, 120, 42, + 38, 63, 68, 147, 160, 236, 62, 95, 133, 82, 34, 103, 226, 41, 155, 247, 131, 48, 208, 102, 208, 32, 124, + 173, 91, 39, 165, 185, 51, 104, 32, 114, 193, 130, 5, 27, 136, 79, 38, 179, 138, 191, 58, 235, 221, 131, + 208, 8, 0, 86, 116, 18, 205, 30, 4, 115, 111, 66, 117, 225, 130, 5, 121, 161, 104, 37, 105, 116, 55, 218, + 41, 178, 42, 73, 120, 50, 50, 104, 59, 108, 152, 102, 34, 163, 226, 137, 250, 140, 221, 191, 225, 154, 222, + 86, 173, 180, 133, 100, 30, 175, 162, 32, 218, 108, 244, 250, 245, 175, 65, 20, 227, 130, 133, 107, 107, + 76, 58, 184, 106, 51, 112, 32, 3, 94, 124, 17, 53, 18, 65, 181, 24, 91, 67, 225, 178, 130, 2, 122, 76, 152, + 192, 141, 51, 103, 226, 247, 249, 98, 229, 10, 116, 246, 70, 217, 248, 153, 113, 3, 119, 163, 197, 246, + 120, 129, 13, 139, 22, 241, 216, 216, 177, 252, 253, 198, 27, 57, 178, 123, 55, 94, 191, 31, 81, 20, 235, + 236, 222, 84, 69, 33, 84, 92, 140, 34, 203, 92, 124, 195, 13, 220, 177, 120, 49, 99, 30, 122, 136, 244, + 140, 12, 64, 3, 46, 198, 251, 72, 4, 96, 204, 64, 202, 138, 141, 229, 25, 204, 174, 200, 202, 216, 8, 198, + 140, 223, 147, 136, 171, 2, 94, 250, 103, 250, 247, 159, 55, 116, 40, 55, 125, 249, 37, 83, 94, 121, 133, + 244, 182, 109, 9, 20, 20, 148, 151, 221, 168, 3, 22, 69, 17, 175, 223, 207, 143, 223, 127, 207, 75, 215, + 95, 207, 19, 227, 199, 147, 183, 100, 9, 158, 168, 28, 25, 231, 67, 7, 82, 149, 201, 162, 29, 200, 240, + 251, 185, 105, 230, 76, 206, 29, 57, 146, 64, 65, 65, 157, 175, 169, 83, 229, 72, 113, 49, 45, 250, 244, + 97, 208, 171, 175, 34, 56, 157, 113, 253, 87, 147, 77, 42, 229, 168, 33, 4, 180, 30, 60, 152, 14, 227, 198, + 33, 233, 135, 69, 35, 71, 251, 40, 186, 179, 178, 226, 0, 214, 153, 36, 213, 192, 10, 208, 254, 138, 43, + 180, 26, 104, 73, 120, 238, 14, 155, 141, 31, 15, 30, 44, 88, 177, 98, 197, 118, 52, 67, 161, 14, 176, 26, + 77, 107, 28, 51, 157, 245, 0, 203, 68, 86, 150, 255, 8, 192, 186, 245, 235, 119, 237, 222, 179, 231, 176, + 221, 225, 168, 210, 157, 80, 29, 86, 20, 133, 220, 43, 174, 136, 243, 123, 67, 98, 247, 72, 109, 48, 134, + 107, 139, 64, 74, 155, 54, 40, 138, 98, 57, 222, 112, 89, 25, 173, 7, 15, 230, 156, 107, 175, 37, 68, 252, + 10, 56, 221, 241, 26, 255, 87, 191, 94, 8, 173, 184, 221, 160, 55, 223, 68, 244, 120, 98, 253, 175, 26, 50, + 151, 21, 20, 208, 249, 138, 43, 184, 230, 181, 215, 72, 113, 185, 98, 22, 158, 154, 0, 45, 23, 81, 139, + 150, 44, 179, 248, 195, 15, 121, 100, 216, 48, 62, 125, 242, 73, 100, 89, 198, 149, 146, 82, 167, 247, 167, + 40, 10, 129, 162, 34, 236, 41, 41, 12, 250, 253, 239, 249, 217, 146, 37, 244, 189, 241, 70, 156, 78, 39, + 42, 21, 173, 71, 230, 247, 149, 129, 41, 35, 72, 50, 131, 167, 68, 129, 244, 34, 21, 65, 86, 162, 98, 165, + 102, 224, 85, 153, 229, 75, 175, 28, 175, 2, 173, 207, 61, 151, 9, 111, 191, 205, 148, 207, 62, 35, 251, + 146, 75, 8, 22, 23, 19, 137, 22, 99, 172, 43, 118, 249, 124, 72, 145, 8, 159, 252, 229, 47, 60, 50, 124, + 56, 75, 63, 249, 4, 167, 162, 144, 70, 245, 128, 149, 81, 254, 220, 209, 251, 246, 121, 60, 92, 247, 127, + 255, 71, 167, 203, 47, 215, 220, 130, 117, 120, 127, 201, 224, 80, 81, 17, 237, 38, 76, 160, 223, 243, 207, + 199, 148, 189, 138, 70, 230, 160, 247, 211, 213, 103, 16, 13, 1, 17, 69, 122, 63, 248, 32, 130, 195, 97, + 169, 103, 21, 85, 69, 116, 185, 240, 101, 103, 87, 176, 170, 213, 246, 62, 96, 118, 175, 75, 64, 74, 102, + 38, 109, 6, 12, 32, 18, 117, 15, 158, 46, 59, 221, 110, 86, 173, 90, 181, 245, 232, 209, 163, 249, 196, 27, + 49, 44, 27, 60, 55, 6, 106, 76, 0, 43, 38, 231, 152, 2, 221, 5, 65, 144, 139, 139, 139, 79, 46, 95, 190, + 124, 147, 43, 73, 46, 25, 57, 20, 162, 85, 159, 62, 164, 182, 107, 23, 179, 98, 157, 73, 201, 50, 94, 71, + 6, 156, 25, 25, 164, 180, 106, 165, 89, 137, 44, 255, 65, 69, 137, 68, 184, 224, 193, 7, 113, 103, 102, + 198, 76, 235, 198, 49, 159, 202, 216, 85, 211, 123, 21, 205, 52, 157, 146, 147, 195, 144, 119, 223, 197, + 147, 149, 133, 92, 223, 3, 104, 107, 64, 193, 194, 66, 186, 77, 153, 194, 216, 23, 94, 136, 109, 218, 250, + 134, 103, 220, 212, 18, 129, 44, 221, 125, 168, 187, 14, 67, 133, 133, 188, 247, 232, 163, 60, 62, 106, 20, + 219, 150, 45, 195, 155, 150, 134, 205, 94, 183, 161, 147, 138, 36, 17, 44, 44, 36, 181, 109, 91, 134, 190, + 252, 50, 19, 231, 206, 165, 211, 21, 87, 0, 218, 252, 154, 1, 79, 162, 146, 11, 102, 240, 84, 85, 220, 85, + 85, 155, 93, 162, 88, 47, 171, 140, 196, 68, 150, 48, 1, 109, 189, 164, 100, 102, 50, 224, 209, 71, 153, + 184, 96, 1, 157, 175, 186, 10, 57, 20, 210, 98, 106, 212, 186, 219, 27, 108, 118, 59, 30, 191, 159, 205, + 139, 23, 243, 216, 21, 87, 240, 175, 199, 30, 35, 82, 92, 76, 58, 214, 238, 77, 51, 184, 50, 187, 4, 93, + 68, 65, 165, 40, 50, 225, 229, 151, 233, 52, 102, 12, 193, 6, 144, 96, 82, 93, 10, 23, 22, 210, 249, 198, + 27, 233, 243, 232, 163, 132, 193, 210, 106, 116, 58, 179, 105, 204, 58, 13, 0, 157, 127, 254, 115, 178, + 135, 14, 173, 52, 3, 90, 0, 210, 58, 118, 172, 19, 148, 97, 220, 131, 194, 64, 235, 129, 3, 73, 205, 201, + 65, 73, 82, 87, 2, 65, 16, 152, 55, 127, 254, 122, 162, 25, 250, 84, 2, 174, 26, 131, 123, 16, 26, 9, 192, + 50, 184, 9, 117, 25, 51, 198, 126, 199, 4, 97, 222, 188, 121, 235, 172, 92, 104, 167, 194, 74, 36, 66, 74, + 203, 150, 180, 29, 58, 52, 46, 14, 224, 76, 74, 149, 81, 1, 164, 100, 101, 225, 205, 204, 180, 116, 17, + 234, 44, 7, 131, 164, 119, 233, 66, 239, 7, 31, 76, 202, 152, 205, 138, 76, 247, 251, 187, 90, 180, 96, + 232, 204, 153, 164, 117, 237, 106, 109, 74, 111, 224, 28, 44, 40, 160, 199, 180, 105, 12, 121, 228, 17, + 160, 220, 50, 82, 217, 6, 104, 4, 90, 198, 184, 25, 47, 26, 208, 218, 181, 97, 3, 79, 76, 152, 192, 251, + 255, 239, 255, 33, 133, 195, 184, 188, 222, 58, 191, 79, 57, 20, 34, 92, 88, 72, 139, 62, 125, 24, 241, + 225, 135, 140, 120, 255, 125, 90, 246, 234, 21, 115, 201, 84, 5, 124, 170, 115, 242, 198, 226, 103, 76, + 191, 179, 250, 172, 58, 214, 7, 51, 75, 128, 232, 112, 112, 222, 180, 105, 140, 93, 188, 152, 94, 15, 60, + 128, 205, 225, 32, 92, 84, 84, 158, 101, 85, 71, 236, 242, 122, 145, 66, 33, 254, 245, 224, 131, 60, 53, + 105, 18, 123, 190, 251, 142, 244, 168, 172, 24, 227, 249, 172, 100, 202, 40, 87, 58, 128, 55, 150, 21, 25, + 246, 151, 191, 208, 109, 234, 84, 66, 13, 216, 45, 104, 201, 209, 174, 21, 231, 223, 119, 31, 61, 126, 253, + 107, 66, 88, 131, 172, 154, 144, 106, 120, 85, 41, 215, 105, 190, 236, 108, 46, 248, 237, 111, 81, 66, 161, + 74, 199, 164, 74, 18, 25, 231, 156, 19, 179, 126, 213, 54, 208, 50, 143, 215, 120, 205, 246, 163, 70, 37, + 205, 61, 104, 19, 69, 142, 29, 61, 90, 182, 108, 217, 178, 77, 209, 75, 154, 227, 175, 26, 77, 131, 103, + 35, 53, 10, 128, 101, 32, 163, 140, 85, 112, 19, 174, 90, 181, 106, 219, 193, 31, 127, 60, 233, 112, 56, + 18, 127, 67, 77, 46, 166, 40, 180, 31, 51, 6, 176, 118, 64, 215, 150, 148, 153, 191, 87, 6, 210, 187, 116, + 193, 225, 243, 81, 213, 193, 33, 82, 82, 66, 183, 155, 111, 38, 231, 138, 43, 8, 112, 234, 99, 86, 77, 239, + 117, 69, 100, 79, 75, 99, 200, 187, 239, 146, 121, 225, 133, 177, 2, 124, 103, 29, 169, 42, 225, 162, 34, + 46, 188, 239, 62, 46, 184, 233, 166, 88, 33, 76, 221, 154, 85, 21, 208, 50, 91, 179, 156, 104, 113, 53, + 182, 72, 132, 79, 158, 127, 158, 39, 199, 142, 101, 207, 186, 117, 184, 83, 83, 207, 244, 157, 89, 146, 84, + 86, 134, 20, 8, 208, 118, 236, 88, 46, 251, 250, 107, 250, 61, 255, 60, 41, 109, 219, 198, 64, 186, 21, 37, + 2, 76, 117, 65, 250, 46, 144, 61, 98, 4, 35, 230, 204, 225, 226, 151, 95, 198, 147, 157, 77, 184, 176, 176, + 206, 107, 91, 9, 162, 136, 55, 45, 141, 221, 107, 214, 240, 248, 232, 209, 124, 246, 210, 75, 56, 36, 137, + 84, 202, 45, 157, 85, 1, 43, 221, 90, 101, 140, 57, 179, 163, 205, 77, 159, 219, 111, 167, 247, 61, 247, + 212, 219, 174, 9, 167, 75, 170, 162, 32, 149, 149, 113, 193, 163, 143, 114, 222, 29, 119, 16, 164, 34, 200, + 170, 238, 142, 111, 214, 105, 42, 229, 155, 200, 197, 127, 249, 11, 190, 220, 92, 228, 112, 216, 242, 127, + 117, 146, 37, 137, 244, 78, 157, 112, 186, 92, 113, 107, 163, 182, 17, 135, 113, 227, 147, 0, 79, 179, 102, + 100, 15, 26, 132, 148, 36, 239, 129, 203, 229, 98, 221, 250, 245, 223, 239, 217, 179, 231, 80, 244, 82, + 149, 213, 191, 106, 52, 212, 24, 1, 150, 85, 169, 134, 8, 160, 228, 231, 231, 31, 91, 245, 205, 55, 91, + 157, 46, 87, 82, 124, 210, 82, 48, 72, 214, 37, 151, 224, 55, 184, 9, 207, 148, 132, 25, 149, 135, 2, 180, + 232, 217, 83, 171, 191, 162, 170, 149, 142, 89, 81, 20, 16, 69, 250, 63, 243, 12, 190, 236, 236, 88, 86, + 161, 89, 185, 84, 231, 218, 198, 235, 71, 0, 155, 223, 207, 192, 183, 222, 162, 197, 192, 129, 132, 139, + 139, 147, 242, 140, 235, 43, 43, 138, 130, 20, 12, 210, 255, 137, 39, 104, 63, 100, 72, 172, 92, 135, 94, + 17, 220, 104, 117, 48, 179, 213, 38, 233, 140, 190, 79, 7, 118, 174, 95, 207, 99, 99, 198, 176, 250, 211, + 79, 113, 167, 165, 213, 249, 189, 170, 128, 170, 170, 90, 81, 69, 65, 160, 211, 109, 183, 113, 217, 146, + 37, 244, 184, 255, 126, 108, 169, 169, 49, 25, 50, 210, 153, 214, 178, 230, 117, 167, 162, 45, 254, 16, + 144, 222, 173, 27, 151, 190, 243, 14, 131, 62, 249, 132, 204, 190, 125, 9, 23, 21, 33, 215, 113, 156, 149, + 10, 8, 54, 27, 54, 167, 147, 47, 103, 204, 224, 241, 113, 227, 216, 179, 113, 99, 156, 59, 48, 81, 246, + 166, 249, 103, 29, 208, 27, 147, 7, 100, 224, 156, 203, 47, 167, 223, 159, 255, 140, 20, 8, 36, 140, 205, + 60, 27, 88, 145, 101, 164, 80, 136, 62, 143, 63, 78, 151, 105, 211, 226, 44, 89, 167, 66, 177, 239, 69, 75, + 212, 233, 126, 251, 237, 116, 188, 250, 234, 106, 233, 52, 89, 146, 240, 181, 105, 131, 175, 93, 59, 206, + 36, 116, 55, 142, 193, 232, 30, 76, 86, 236, 171, 205, 110, 103, 238, 220, 185, 107, 129, 160, 161, 185, + 179, 177, 124, 92, 163, 138, 189, 210, 169, 177, 1, 44, 40, 95, 27, 113, 64, 43, 42, 20, 225, 185, 115, + 231, 174, 17, 146, 96, 50, 69, 85, 81, 36, 9, 111, 139, 22, 180, 29, 54, 12, 115, 228, 147, 57, 54, 36, 25, + 156, 200, 37, 98, 7, 90, 245, 234, 165, 249, 218, 171, 49, 110, 57, 16, 32, 181, 67, 7, 6, 190, 244, 18, + 54, 151, 43, 78, 17, 36, 170, 212, 157, 168, 184, 36, 68, 187, 106, 167, 166, 50, 248, 173, 183, 104, 51, + 114, 36, 145, 194, 194, 164, 60, 223, 250, 206, 74, 36, 130, 205, 225, 96, 240, 203, 47, 211, 125, 66, 244, + 47, 0, 0, 32, 0, 73, 68, 65, 84, 44, 39, 39, 54, 23, 198, 96, 106, 125, 243, 179, 10, 68, 182, 10, 72, 214, + 131, 224, 229, 178, 50, 254, 113, 199, 29, 108, 93, 180, 8, 183, 207, 87, 231, 247, 170, 179, 42, 73, 68, + 10, 10, 112, 250, 253, 244, 124, 244, 81, 46, 91, 184, 144, 115, 166, 78, 69, 181, 219, 209, 35, 61, 172, + 228, 53, 217, 107, 193, 170, 192, 169, 254, 179, 138, 6, 248, 221, 205, 155, 211, 231, 207, 127, 102, 216, + 188, 121, 180, 187, 242, 74, 148, 96, 176, 222, 184, 172, 245, 222, 129, 255, 158, 62, 157, 183, 166, 79, + 71, 45, 43, 195, 79, 188, 43, 208, 74, 78, 172, 228, 197, 88, 178, 66, 183, 92, 101, 118, 236, 200, 160, + 25, 51, 16, 108, 182, 106, 235, 133, 134, 204, 106, 36, 130, 26, 137, 112, 241, 115, 207, 209, 229, 134, + 27, 8, 71, 229, 0, 131, 124, 36, 146, 69, 179, 155, 155, 232, 255, 134, 128, 182, 67, 135, 210, 231, 143, + 127, 68, 46, 43, 211, 138, 138, 86, 99, 125, 184, 211, 210, 104, 222, 173, 91, 133, 226, 164, 201, 94, 7, + 230, 251, 210, 199, 173, 2, 237, 199, 140, 73, 170, 123, 240, 228, 137, 19, 225, 69, 139, 22, 125, 103, 88, + 94, 86, 13, 158, 21, 160, 81, 148, 103, 208, 169, 209, 0, 172, 106, 196, 97, 69, 0, 150, 46, 93, 186, 229, + 240, 145, 35, 37, 246, 36, 5, 18, 171, 138, 66, 238, 232, 209, 128, 181, 141, 180, 54, 37, 77, 191, 81, + 111, 70, 6, 153, 93, 187, 34, 215, 32, 152, 49, 82, 92, 76, 155, 145, 35, 185, 228, 249, 231, 145, 69, 209, + 50, 213, 217, 60, 118, 243, 239, 98, 110, 65, 191, 159, 129, 111, 191, 77, 155, 43, 174, 208, 192, 85, 61, + 39, 151, 215, 139, 61, 89, 53, 209, 130, 65, 124, 185, 185, 244, 127, 225, 5, 108, 118, 59, 42, 218, 162, + 51, 102, 177, 153, 193, 150, 217, 10, 97, 229, 234, 73, 1, 164, 146, 18, 94, 191, 245, 86, 14, 109, 223, + 142, 211, 235, 77, 202, 120, 147, 69, 74, 36, 66, 184, 176, 144, 148, 142, 29, 233, 251, 250, 235, 12, 249, + 226, 11, 178, 134, 14, 37, 2, 113, 155, 155, 78, 181, 177, 14, 204, 223, 169, 203, 163, 234, 116, 210, 233, + 23, 191, 96, 216, 162, 69, 116, 253, 205, 111, 16, 29, 14, 34, 245, 172, 105, 179, 59, 53, 149, 217, 207, + 61, 199, 87, 175, 189, 22, 43, 223, 97, 149, 44, 97, 182, 122, 26, 93, 129, 230, 140, 77, 189, 40, 171, + 195, 237, 102, 192, 75, 47, 225, 109, 219, 54, 105, 9, 38, 122, 207, 195, 250, 76, 138, 36, 161, 74, 18, + 125, 159, 127, 190, 130, 37, 171, 186, 242, 167, 255, 109, 8, 200, 236, 217, 147, 129, 175, 189, 134, 205, + 229, 170, 81, 29, 41, 193, 102, 163, 117, 223, 190, 9, 175, 155, 236, 181, 96, 220, 244, 36, 192, 155, 153, + 73, 246, 192, 129, 73, 117, 15, 174, 95, 191, 126, 199, 246, 237, 219, 247, 71, 47, 165, 239, 167, 102, + 235, 85, 163, 1, 86, 58, 53, 26, 128, 101, 32, 125, 162, 173, 202, 53, 168, 7, 15, 30, 60, 252, 237, 154, + 53, 219, 146, 230, 38, 12, 133, 104, 117, 241, 197, 164, 182, 107, 23, 131, 243, 103, 66, 210, 98, 215, 7, + 154, 157, 119, 30, 41, 209, 98, 114, 53, 25, 123, 184, 168, 136, 78, 55, 220, 192, 37, 47, 188, 128, 108, + 179, 197, 21, 77, 53, 95, 199, 10, 92, 133, 0, 103, 139, 22, 12, 254, 240, 67, 178, 70, 142, 36, 84, 223, + 211, 191, 163, 85, 238, 87, 125, 250, 41, 249, 251, 246, 225, 73, 75, 195, 22, 45, 65, 112, 58, 28, 46, 46, + 166, 205, 168, 81, 244, 124, 232, 161, 152, 37, 211, 120, 98, 53, 214, 111, 50, 198, 201, 88, 185, 125, + 140, 150, 9, 31, 112, 226, 224, 65, 94, 191, 229, 22, 74, 78, 156, 72, 202, 88, 147, 205, 114, 40, 68, 164, + 184, 152, 204, 254, 253, 185, 244, 63, 255, 161, 223, 219, 111, 147, 118, 222, 121, 132, 32, 230, 54, 215, + 41, 89, 235, 194, 74, 30, 195, 209, 235, 181, 25, 57, 146, 33, 115, 230, 208, 231, 197, 23, 113, 183, 110, + 29, 139, 179, 170, 235, 231, 100, 100, 183, 223, 207, 170, 15, 62, 224, 63, 127, 250, 19, 41, 84, 44, 76, + 155, 168, 112, 173, 85, 177, 86, 61, 107, 82, 127, 14, 18, 208, 235, 15, 127, 32, 107, 232, 208, 164, 184, + 233, 109, 78, 39, 158, 180, 52, 142, 236, 221, 203, 183, 255, 253, 47, 8, 66, 108, 29, 213, 71, 150, 163, + 141, 185, 47, 122, 241, 69, 186, 221, 117, 23, 161, 232, 51, 49, 202, 140, 249, 127, 116, 210, 79, 229, 1, + 160, 89, 207, 158, 12, 249, 247, 191, 113, 183, 108, 25, 171, 130, 94, 237, 49, 68, 34, 180, 186, 232, 162, + 88, 135, 15, 171, 107, 37, 139, 244, 239, 213, 199, 30, 1, 218, 12, 30, 172, 185, 40, 147, 232, 30, 156, + 55, 127, 254, 90, 32, 16, 205, 30, 52, 198, 94, 53, 90, 247, 32, 52, 78, 128, 5, 6, 89, 199, 144, 73, 24, + 117, 19, 134, 190, 158, 59, 119, 157, 40, 38, 231, 209, 40, 146, 132, 183, 101, 75, 178, 135, 12, 57, 35, + 217, 132, 102, 225, 151, 128, 214, 253, 250, 97, 115, 187, 169, 177, 101, 86, 213, 130, 181, 59, 221, 120, + 35, 131, 222, 121, 7, 103, 243, 230, 113, 65, 162, 137, 174, 175, 167, 45, 167, 119, 235, 198, 144, 143, + 63, 166, 197, 128, 1, 68, 26, 66, 16, 173, 170, 226, 78, 73, 97, 193, 204, 153, 76, 31, 48, 128, 15, 30, + 121, 132, 194, 35, 71, 240, 250, 253, 216, 78, 51, 241, 33, 82, 84, 68, 183, 187, 239, 166, 237, 200, 145, + 177, 58, 99, 70, 151, 128, 185, 42, 185, 21, 200, 50, 23, 241, 116, 162, 185, 11, 119, 175, 95, 207, 204, + 123, 239, 5, 64, 180, 217, 78, 107, 156, 181, 69, 82, 89, 25, 114, 40, 68, 187, 201, 147, 25, 250, 245, + 215, 244, 126, 236, 49, 220, 173, 90, 89, 198, 195, 156, 234, 218, 48, 175, 43, 93, 254, 67, 64, 250, 121, + 231, 209, 127, 230, 76, 250, 127, 240, 1, 205, 250, 244, 33, 82, 84, 132, 82, 69, 64, 114, 93, 144, 219, + 231, 99, 215, 170, 85, 188, 115, 239, 189, 216, 85, 53, 150, 37, 152, 8, 88, 153, 45, 86, 198, 250, 95, 70, + 151, 22, 104, 32, 51, 119, 252, 120, 186, 221, 113, 199, 105, 175, 71, 187, 195, 129, 215, 239, 231, 248, + 129, 3, 188, 59, 125, 58, 211, 7, 12, 96, 201, 199, 31, 227, 170, 231, 86, 44, 0, 85, 146, 144, 131, 65, + 122, 255, 249, 207, 92, 240, 199, 63, 162, 56, 28, 150, 177, 166, 177, 191, 167, 220, 250, 19, 4, 218, 141, + 26, 197, 208, 79, 62, 193, 219, 186, 53, 82, 32, 80, 227, 235, 43, 225, 48, 205, 186, 118, 141, 29, 186, + 19, 1, 186, 211, 33, 243, 58, 48, 2, 173, 220, 177, 99, 65, 72, 78, 154, 137, 40, 138, 20, 21, 21, 73, 11, + 22, 44, 216, 24, 189, 132, 30, 211, 108, 46, 48, 218, 232, 220, 131, 208, 200, 0, 150, 169, 170, 123, 162, + 96, 119, 22, 45, 94, 156, 119, 52, 63, 191, 204, 150, 164, 234, 217, 170, 44, 147, 59, 110, 92, 92, 97, 58, + 157, 146, 93, 76, 206, 92, 80, 206, 6, 100, 15, 26, 116, 234, 113, 22, 138, 66, 164, 168, 136, 182, 227, + 199, 51, 124, 238, 92, 114, 198, 142, 141, 53, 188, 53, 90, 228, 244, 211, 81, 16, 192, 237, 166, 219, 237, + 183, 51, 236, 203, 47, 201, 232, 217, 83, 203, 22, 172, 7, 113, 24, 213, 97, 65, 16, 200, 233, 218, 149, + 194, 96, 144, 247, 159, 121, 134, 63, 12, 25, 194, 135, 143, 60, 66, 241, 177, 99, 90, 69, 117, 155, 237, + 148, 101, 64, 16, 4, 46, 122, 234, 41, 188, 173, 91, 199, 226, 218, 204, 32, 203, 70, 69, 75, 150, 85, 10, + 190, 209, 114, 145, 14, 124, 59, 107, 22, 95, 60, 254, 184, 86, 190, 65, 19, 246, 250, 199, 81, 89, 18, + 236, 118, 186, 252, 234, 87, 12, 91, 188, 152, 115, 239, 186, 11, 49, 37, 165, 66, 76, 76, 77, 214, 135, + 249, 111, 33, 190, 36, 72, 239, 199, 30, 99, 240, 188, 121, 100, 79, 156, 136, 28, 8, 32, 149, 149, 213, + 253, 179, 176, 96, 135, 211, 201, 137, 3, 7, 120, 243, 246, 219, 9, 21, 21, 145, 82, 197, 220, 155, 43, + 228, 27, 1, 150, 85, 28, 164, 175, 109, 91, 46, 124, 226, 9, 84, 69, 65, 149, 229, 83, 26, 163, 104, 179, + 225, 73, 77, 165, 240, 200, 17, 62, 248, 227, 31, 121, 120, 232, 80, 62, 249, 219, 223, 40, 10, 133, 104, + 215, 190, 189, 182, 62, 234, 184, 164, 69, 181, 214, 99, 20, 100, 117, 187, 255, 126, 134, 124, 250, 41, + 205, 47, 188, 48, 230, 190, 54, 186, 13, 245, 205, 33, 4, 56, 50, 51, 185, 240, 241, 199, 185, 244, 221, + 119, 113, 166, 167, 107, 224, 234, 20, 174, 173, 72, 18, 158, 230, 205, 105, 213, 183, 111, 92, 108, 110, + 178, 246, 2, 171, 181, 161, 234, 50, 144, 149, 69, 235, 75, 47, 69, 62, 197, 177, 155, 217, 229, 116, 178, + 49, 47, 111, 215, 230, 205, 155, 247, 70, 47, 99, 182, 94, 233, 32, 171, 81, 82, 163, 2, 88, 38, 50, 130, + 44, 99, 28, 150, 242, 195, 15, 63, 252, 184, 126, 195, 134, 239, 147, 229, 38, 140, 4, 131, 180, 186, 228, + 18, 82, 59, 116, 176, 236, 77, 168, 191, 38, 131, 140, 215, 149, 0, 127, 78, 14, 153, 61, 122, 32, 157, + 102, 86, 84, 184, 184, 152, 148, 220, 92, 250, 205, 156, 201, 160, 79, 63, 165, 253, 181, 215, 226, 201, + 201, 65, 112, 185, 80, 68, 17, 33, 37, 5, 255, 185, 231, 114, 238, 47, 127, 201, 208, 249, 243, 233, 253, + 244, 211, 216, 188, 222, 88, 195, 211, 134, 196, 109, 207, 61, 23, 55, 144, 10, 20, 31, 59, 198, 135, 127, + 253, 43, 143, 12, 27, 198, 231, 207, 60, 67, 176, 180, 20, 183, 223, 175, 101, 100, 214, 240, 123, 165, 96, + 16, 95, 167, 78, 244, 126, 244, 209, 56, 112, 10, 229, 10, 209, 92, 153, 60, 17, 216, 50, 183, 166, 73, 5, + 230, 60, 247, 28, 43, 223, 127, 31, 183, 223, 95, 231, 207, 176, 50, 86, 100, 153, 112, 97, 33, 206, 204, + 76, 122, 60, 249, 36, 67, 230, 205, 35, 103, 242, 100, 100, 81, 172, 145, 219, 208, 234, 119, 177, 56, 43, + 151, 139, 78, 55, 223, 204, 208, 69, 139, 232, 252, 171, 95, 33, 216, 108, 90, 156, 149, 90, 121, 22, 109, + 93, 177, 96, 183, 35, 201, 50, 51, 239, 185, 135, 67, 59, 119, 146, 74, 226, 190, 136, 86, 113, 86, 230, + 98, 169, 198, 160, 102, 253, 20, 121, 193, 227, 143, 227, 205, 205, 61, 37, 93, 32, 216, 108, 120, 210, + 210, 8, 20, 23, 243, 217, 147, 79, 242, 199, 161, 67, 249, 232, 217, 103, 41, 43, 40, 32, 21, 13, 248, 181, + 237, 214, 13, 185, 1, 101, 35, 42, 138, 66, 184, 168, 136, 22, 3, 7, 50, 248, 191, 255, 165, 223, 155, 111, + 146, 61, 122, 52, 206, 172, 44, 84, 167, 19, 197, 102, 195, 230, 247, 147, 209, 167, 15, 61, 30, 122, 136, + 17, 139, 22, 209, 229, 238, 187, 81, 34, 17, 228, 112, 248, 180, 174, 141, 32, 208, 118, 248, 240, 216, + 252, 196, 253, 206, 240, 122, 58, 20, 187, 79, 12, 189, 7, 135, 13, 35, 37, 59, 27, 185, 134, 225, 34, 137, + 216, 238, 112, 240, 245, 188, 121, 107, 128, 82, 67, 113, 81, 99, 137, 134, 70, 27, 127, 5, 154, 14, 111, + 140, 100, 148, 189, 10, 205, 159, 85, 85, 13, 206, 157, 59, 119, 237, 229, 151, 95, 222, 59, 41, 23, 147, + 101, 60, 153, 153, 100, 95, 118, 25, 91, 255, 241, 15, 92, 209, 11, 235, 65, 167, 201, 170, 9, 20, 167, 60, + 208, 36, 188, 195, 192, 129, 120, 90, 180, 72, 74, 205, 41, 57, 20, 66, 16, 4, 90, 12, 29, 74, 203, 225, + 195, 9, 31, 63, 78, 240, 200, 17, 164, 210, 82, 156, 233, 233, 184, 179, 178, 112, 248, 253, 40, 225, 112, + 131, 173, 113, 37, 69, 34, 180, 237, 214, 13, 159, 32, 160, 170, 42, 118, 180, 13, 173, 240, 240, 97, 254, + 245, 232, 163, 44, 125, 235, 45, 70, 255, 234, 87, 12, 184, 238, 58, 220, 62, 31, 161, 210, 82, 106, 98, + 245, 142, 20, 23, 211, 254, 154, 107, 56, 188, 104, 17, 187, 255, 253, 111, 188, 196, 203, 64, 85, 39, 82, + 209, 244, 183, 80, 62, 231, 50, 240, 254, 3, 15, 208, 186, 107, 87, 218, 245, 232, 65, 168, 172, 236, 116, + 30, 69, 173, 147, 18, 137, 160, 20, 22, 146, 218, 181, 43, 125, 255, 239, 255, 200, 189, 254, 122, 182, 63, + 245, 20, 71, 87, 174, 140, 89, 244, 140, 247, 136, 197, 207, 24, 126, 214, 83, 56, 90, 143, 28, 201, 185, + 211, 167, 211, 172, 111, 95, 228, 64, 160, 254, 39, 86, 8, 2, 46, 175, 151, 143, 31, 122, 136, 188, 249, + 243, 73, 199, 186, 47, 162, 49, 19, 208, 170, 141, 16, 148, 103, 73, 66, 185, 30, 8, 2, 157, 166, 77, 35, + 103, 210, 164, 26, 175, 75, 65, 16, 112, 251, 124, 4, 138, 138, 248, 250, 239, 127, 231, 171, 25, 51, 248, + 241, 192, 1, 92, 104, 181, 217, 244, 235, 164, 58, 28, 180, 61, 239, 188, 26, 37, 210, 212, 23, 146, 74, + 75, 17, 68, 145, 118, 147, 39, 211, 118, 210, 36, 66, 199, 142, 17, 56, 114, 4, 37, 28, 198, 213, 188, 57, + 238, 86, 173, 176, 123, 189, 200, 193, 96, 210, 66, 29, 228, 80, 136, 214, 253, 251, 227, 78, 77, 69, 54, + 197, 194, 157, 46, 169, 166, 247, 186, 28, 0, 180, 31, 63, 94, 179, 48, 38, 129, 68, 81, 164, 176, 176, 48, + 50, 111, 222, 188, 245, 148, 47, 65, 221, 61, 24, 231, 26, 164, 9, 96, 53, 14, 82, 85, 85, 21, 52, 255, + 179, 25, 96, 69, 12, 236, 92, 184, 112, 97, 222, 137, 227, 199, 131, 110, 183, 219, 45, 39, 161, 216, 160, + 34, 73, 180, 31, 51, 134, 237, 255, 248, 71, 156, 228, 25, 3, 80, 79, 21, 104, 25, 21, 170, 241, 68, 4, + 144, 51, 114, 100, 185, 201, 62, 9, 164, 170, 42, 114, 180, 21, 132, 205, 227, 193, 215, 169, 19, 130, 32, + 104, 110, 7, 73, 106, 24, 177, 86, 149, 144, 28, 14, 147, 117, 206, 57, 180, 106, 215, 142, 252, 125, 251, + 208, 35, 175, 244, 190, 130, 199, 246, 238, 229, 141, 223, 252, 134, 165, 111, 189, 197, 248, 223, 254, + 150, 222, 163, 70, 1, 16, 174, 110, 44, 134, 170, 162, 132, 195, 244, 252, 195, 31, 56, 178, 108, 25, 161, + 253, 251, 113, 98, 237, 238, 170, 172, 244, 70, 236, 235, 12, 175, 42, 80, 92, 80, 192, 204, 187, 239, 230, + 222, 207, 62, 195, 233, 245, 54, 136, 13, 79, 142, 62, 187, 150, 67, 134, 208, 124, 192, 0, 14, 126, 250, + 41, 219, 159, 121, 134, 194, 157, 59, 99, 96, 162, 50, 96, 165, 187, 113, 154, 157, 127, 62, 93, 167, 79, + 167, 245, 152, 49, 160, 170, 245, 31, 88, 69, 201, 147, 154, 202, 234, 15, 63, 228, 235, 25, 51, 240, 99, + 221, 128, 218, 42, 35, 208, 104, 173, 178, 146, 11, 221, 106, 145, 218, 177, 35, 61, 127, 247, 59, 237, 57, + 215, 96, 115, 117, 122, 189, 168, 138, 194, 234, 79, 63, 229, 191, 79, 63, 205, 174, 205, 155, 99, 69, 111, + 141, 64, 63, 2, 100, 181, 111, 79, 243, 156, 28, 173, 208, 102, 146, 116, 141, 78, 118, 167, 19, 85, 81, + 180, 230, 218, 181, 68, 170, 44, 107, 117, 220, 208, 74, 202, 248, 51, 50, 52, 189, 38, 203, 218, 239, 146, + 172, 215, 228, 112, 24, 127, 110, 46, 45, 47, 190, 152, 67, 11, 22, 224, 36, 126, 45, 39, 227, 208, 109, + 180, 94, 73, 128, 63, 55, 151, 172, 139, 47, 46, 119, 109, 158, 38, 185, 156, 78, 190, 249, 230, 155, 93, + 155, 54, 109, 218, 23, 253, 200, 8, 176, 42, 228, 116, 53, 182, 248, 43, 104, 220, 46, 66, 163, 252, 85, + 200, 38, 220, 185, 115, 231, 129, 181, 235, 214, 109, 79, 102, 209, 209, 22, 23, 94, 72, 218, 185, 231, + 214, 106, 209, 209, 216, 245, 0, 95, 155, 54, 100, 245, 235, 87, 227, 44, 151, 234, 178, 34, 203, 200, 161, + 16, 82, 48, 136, 28, 14, 215, 73, 177, 66, 68, 17, 187, 219, 173, 101, 47, 37, 225, 251, 100, 89, 198, 219, + 172, 25, 29, 251, 244, 193, 70, 69, 247, 92, 10, 218, 6, 179, 103, 227, 70, 94, 248, 233, 79, 121, 241, + 186, 235, 248, 97, 195, 6, 220, 126, 63, 98, 53, 27, 133, 203, 225, 48, 222, 182, 109, 233, 249, 135, 63, + 196, 29, 245, 204, 178, 160, 131, 44, 179, 203, 208, 170, 180, 131, 206, 62, 224, 135, 188, 60, 254, 243, + 240, 195, 216, 156, 206, 164, 61, 151, 51, 193, 145, 210, 82, 20, 73, 162, 221, 212, 169, 12, 158, 63, 159, + 243, 31, 126, 24, 71, 102, 102, 133, 116, 250, 216, 115, 36, 154, 169, 218, 178, 37, 189, 30, 127, 156, + 129, 115, 231, 210, 122, 252, 120, 45, 206, 42, 16, 168, 243, 251, 169, 14, 59, 60, 30, 14, 108, 222, 204, + 7, 15, 62, 24, 155, 79, 243, 188, 154, 43, 176, 155, 173, 87, 137, 192, 149, 206, 189, 30, 121, 4, 119, + 235, 214, 213, 206, 26, 179, 57, 157, 184, 253, 126, 118, 173, 89, 195, 11, 87, 95, 205, 223, 110, 184, + 129, 189, 155, 55, 227, 135, 88, 92, 152, 113, 76, 34, 112, 206, 69, 23, 225, 77, 79, 79, 154, 139, 16, 65, + 192, 225, 241, 224, 78, 77, 229, 232, 254, 253, 20, 28, 61, 122, 74, 110, 249, 83, 225, 56, 189, 22, 137, + 212, 142, 94, 83, 85, 68, 135, 131, 220, 209, 163, 99, 178, 93, 211, 130, 206, 85, 81, 236, 126, 208, 128, + 118, 246, 200, 145, 184, 91, 182, 76, 90, 214, 172, 221, 225, 96, 238, 215, 95, 175, 85, 85, 181, 36, 154, + 32, 150, 40, 254, 234, 116, 111, 165, 193, 82, 99, 7, 88, 186, 252, 89, 101, 19, 6, 231, 204, 153, 179, 38, + 153, 245, 176, 92, 233, 233, 228, 140, 30, 93, 33, 206, 4, 146, 19, 204, 168, 26, 94, 35, 64, 246, 144, 33, + 120, 179, 178, 106, 84, 163, 165, 33, 145, 104, 179, 81, 124, 236, 24, 59, 87, 175, 198, 225, 118, 227, 78, + 73, 65, 72, 66, 246, 167, 32, 138, 116, 29, 52, 200, 50, 53, 94, 223, 244, 82, 209, 54, 155, 245, 243, 230, + 241, 228, 152, 49, 252, 235, 254, 251, 41, 57, 113, 2, 143, 223, 95, 173, 49, 72, 197, 197, 228, 78, 153, + 66, 187, 9, 19, 98, 89, 133, 177, 235, 155, 216, 10, 100, 89, 129, 43, 253, 179, 52, 96, 217, 204, 153, + 172, 120, 247, 221, 122, 211, 78, 167, 186, 164, 70, 3, 225, 69, 151, 139, 174, 15, 60, 192, 144, 69, 139, + 232, 116, 243, 205, 224, 114, 197, 53, 32, 15, 3, 184, 221, 116, 190, 245, 86, 134, 44, 92, 72, 167, 187, + 238, 66, 16, 4, 164, 104, 156, 85, 67, 32, 209, 102, 35, 18, 12, 242, 254, 125, 247, 81, 122, 252, 120, 12, + 188, 88, 205, 171, 49, 222, 202, 88, 126, 161, 178, 160, 230, 16, 144, 123, 205, 53, 180, 27, 63, 190, 90, + 174, 65, 65, 20, 241, 248, 253, 20, 30, 57, 194, 204, 123, 239, 229, 233, 113, 227, 216, 184, 104, 81, 236, + 80, 145, 40, 38, 204, 13, 116, 29, 52, 40, 41, 187, 168, 32, 138, 184, 125, 62, 236, 78, 39, 59, 87, 175, + 230, 159, 119, 221, 197, 239, 250, 247, 231, 179, 167, 159, 198, 225, 118, 39, 225, 10, 245, 135, 228, 80, + 136, 236, 161, 67, 241, 164, 166, 86, 168, 234, 126, 186, 201, 78, 70, 82, 209, 100, 37, 119, 220, 184, + 164, 237, 5, 162, 40, 82, 80, 80, 16, 153, 51, 103, 206, 186, 232, 71, 70, 15, 80, 163, 109, 238, 108, 166, + 70, 9, 176, 12, 147, 109, 149, 77, 168, 151, 204, 97, 254, 252, 249, 27, 146, 153, 77, 168, 132, 66, 228, + 142, 30, 141, 221, 102, 179, 132, 246, 167, 34, 129, 230, 255, 49, 126, 103, 135, 9, 19, 26, 68, 70, 207, + 233, 176, 199, 231, 227, 189, 135, 30, 226, 137, 241, 227, 89, 63, 103, 14, 98, 84, 65, 139, 167, 81, 165, + 88, 10, 6, 233, 216, 191, 63, 25, 110, 119, 172, 127, 160, 185, 61, 137, 206, 105, 128, 16, 10, 241, 229, + 235, 175, 243, 216, 240, 225, 44, 254, 231, 63, 177, 217, 108, 90, 186, 122, 37, 215, 80, 21, 5, 20, 133, + 158, 15, 61, 132, 51, 35, 163, 202, 26, 105, 230, 108, 67, 163, 203, 200, 8, 182, 140, 229, 29, 62, 125, + 248, 97, 14, 108, 220, 136, 211, 237, 174, 243, 121, 170, 41, 235, 21, 225, 221, 173, 90, 209, 243, 217, + 103, 25, 244, 213, 87, 180, 25, 59, 150, 112, 116, 129, 182, 25, 61, 154, 65, 115, 230, 208, 243, 153, 103, + 112, 181, 104, 65, 164, 176, 240, 148, 51, 227, 234, 138, 93, 94, 47, 115, 158, 121, 134, 237, 43, 86, 196, + 122, 11, 26, 231, 210, 202, 45, 104, 174, 204, 109, 165, 15, 244, 248, 75, 119, 139, 22, 244, 252, 221, + 239, 80, 35, 145, 42, 245, 128, 203, 227, 65, 20, 69, 22, 190, 250, 42, 143, 143, 24, 193, 215, 111, 190, + 137, 24, 14, 227, 183, 144, 125, 227, 122, 112, 0, 205, 252, 126, 58, 244, 237, 139, 84, 69, 163, 227, 202, + 88, 20, 4, 60, 209, 142, 4, 223, 126, 246, 25, 207, 78, 158, 204, 99, 227, 198, 241, 245, 204, 153, 20, + 135, 195, 132, 74, 75, 65, 15, 213, 168, 7, 115, 151, 12, 150, 195, 97, 210, 58, 116, 32, 107, 208, 160, + 216, 161, 59, 89, 230, 30, 213, 240, 125, 97, 32, 189, 123, 119, 90, 246, 233, 147, 180, 236, 65, 183, 203, + 197, 6, 173, 184, 168, 49, 123, 48, 81, 99, 231, 100, 220, 82, 131, 164, 70, 9, 176, 162, 164, 26, 94, 141, + 46, 66, 99, 54, 225, 193, 111, 215, 172, 217, 230, 78, 210, 201, 73, 14, 133, 104, 214, 163, 7, 205, 122, + 247, 142, 59, 141, 39, 115, 65, 169, 104, 11, 42, 173, 115, 103, 90, 69, 221, 131, 103, 43, 41, 178, 140, + 175, 89, 51, 134, 221, 112, 3, 171, 87, 172, 224, 153, 159, 252, 132, 39, 198, 142, 101, 213, 199, 31, 131, + 32, 224, 78, 77, 61, 37, 139, 150, 28, 137, 144, 217, 177, 35, 57, 189, 123, 35, 146, 184, 194, 186, 14, + 104, 244, 30, 129, 133, 135, 14, 241, 230, 111, 126, 195, 139, 83, 166, 176, 103, 221, 58, 60, 126, 63, 98, + 37, 22, 80, 57, 24, 36, 173, 91, 55, 186, 253, 250, 215, 177, 58, 60, 149, 69, 200, 24, 65, 86, 162, 106, + 240, 58, 123, 129, 178, 147, 39, 249, 104, 250, 116, 194, 129, 64, 82, 44, 123, 117, 65, 74, 56, 140, 84, + 84, 132, 191, 71, 15, 46, 126, 231, 29, 250, 205, 156, 201, 37, 111, 191, 205, 197, 51, 103, 226, 239, 209, + 163, 222, 214, 179, 170, 138, 156, 94, 47, 223, 205, 157, 203, 130, 25, 51, 240, 17, 15, 174, 172, 92, 130, + 34, 241, 86, 43, 43, 210, 55, 84, 125, 83, 237, 118, 223, 125, 248, 58, 118, 68, 14, 133, 18, 142, 67, 116, + 56, 240, 248, 253, 236, 92, 189, 154, 231, 38, 78, 228, 173, 7, 31, 164, 56, 63, 159, 52, 202, 43, 195, 91, + 29, 44, 244, 207, 69, 32, 183, 79, 31, 50, 114, 115, 181, 82, 48, 53, 36, 65, 20, 181, 64, 111, 69, 97, + 233, 187, 239, 242, 228, 152, 49, 188, 56, 109, 26, 121, 255, 251, 31, 54, 89, 38, 5, 205, 90, 60, 124, + 218, 52, 221, 20, 82, 227, 107, 212, 91, 82, 85, 4, 81, 164, 195, 149, 87, 198, 78, 248, 102, 68, 114, 42, + 119, 107, 4, 87, 58, 216, 206, 25, 51, 6, 167, 223, 159, 180, 110, 5, 54, 155, 141, 175, 190, 250, 106, 53, + 90, 113, 81, 115, 236, 85, 147, 123, 48, 74, 13, 83, 235, 38, 143, 140, 114, 24, 23, 135, 165, 187, 9, 191, + 156, 51, 231, 91, 65, 20, 147, 227, 219, 87, 85, 236, 94, 47, 57, 227, 199, 87, 176, 88, 156, 142, 20, 90, + 45, 168, 220, 241, 227, 113, 53, 107, 86, 239, 170, 84, 39, 155, 131, 101, 101, 92, 52, 126, 60, 93, 59, + 118, 68, 4, 182, 175, 93, 203, 223, 110, 190, 153, 39, 198, 140, 225, 155, 79, 62, 65, 180, 219, 113, 165, + 164, 212, 40, 22, 73, 81, 85, 108, 30, 15, 93, 70, 142, 140, 197, 97, 89, 53, 215, 53, 182, 39, 209, 227, + 179, 82, 129, 77, 203, 150, 241, 204, 184, 113, 124, 252, 240, 195, 68, 130, 65, 92, 62, 95, 194, 107, 69, + 74, 74, 232, 116, 227, 141, 100, 246, 233, 19, 115, 21, 86, 166, 149, 140, 32, 43, 81, 92, 150, 238, 78, + 74, 5, 182, 46, 91, 198, 170, 247, 223, 199, 225, 245, 214, 249, 92, 157, 14, 235, 113, 85, 109, 198, 140, + 33, 123, 220, 56, 45, 62, 166, 129, 196, 89, 153, 25, 81, 36, 88, 82, 194, 23, 143, 61, 6, 138, 130, 59, + 193, 252, 153, 171, 177, 155, 129, 149, 217, 37, 168, 175, 255, 16, 208, 226, 146, 75, 56, 231, 231, 63, + 39, 82, 82, 146, 112, 28, 174, 212, 84, 66, 165, 165, 124, 240, 187, 223, 241, 215, 9, 19, 216, 254, 205, + 55, 164, 82, 222, 150, 199, 170, 6, 151, 185, 199, 161, 29, 232, 114, 249, 229, 136, 46, 23, 138, 90, 131, + 18, 24, 130, 128, 203, 231, 3, 65, 96, 249, 191, 255, 205, 19, 35, 71, 242, 250, 93, 119, 177, 59, 47, 15, + 47, 196, 44, 122, 10, 208, 115, 196, 8, 186, 244, 239, 79, 184, 150, 98, 73, 235, 146, 165, 96, 144, 54, + 131, 7, 147, 218, 174, 157, 101, 9, 159, 154, 144, 241, 127, 140, 155, 154, 221, 225, 32, 103, 204, 24, + 164, 211, 44, 45, 161, 179, 104, 179, 113, 252, 196, 137, 224, 220, 175, 191, 54, 102, 15, 38, 2, 87, 167, + 114, 43, 103, 13, 157, 53, 0, 75, 16, 132, 26, 113, 148, 116, 1, 48, 215, 195, 210, 89, 88, 184, 96, 65, + 222, 145, 195, 135, 75, 236, 167, 88, 96, 178, 130, 89, 56, 24, 164, 221, 200, 145, 56, 83, 82, 42, 58, + 170, 169, 153, 52, 90, 45, 40, 9, 112, 186, 92, 116, 152, 56, 81, 235, 51, 86, 15, 76, 225, 181, 201, 138, + 36, 145, 154, 153, 201, 208, 235, 175, 7, 202, 27, 223, 238, 218, 176, 129, 151, 126, 241, 11, 254, 58, 97, + 2, 223, 205, 159, 143, 211, 227, 193, 233, 114, 213, 104, 158, 58, 14, 31, 78, 170, 203, 21, 7, 178, 172, + 44, 89, 230, 250, 68, 126, 128, 80, 136, 47, 94, 124, 145, 103, 71, 143, 102, 243, 188, 121, 120, 82, 83, + 177, 217, 237, 21, 174, 163, 74, 18, 142, 148, 20, 206, 255, 237, 111, 99, 243, 151, 40, 224, 221, 72, 102, + 144, 101, 174, 153, 101, 124, 31, 44, 40, 208, 254, 191, 30, 204, 215, 105, 177, 162, 32, 149, 150, 106, + 13, 153, 27, 176, 235, 91, 64, 107, 161, 21, 57, 121, 178, 2, 184, 50, 186, 4, 141, 110, 65, 51, 192, 50, + 150, 99, 208, 117, 65, 204, 10, 34, 8, 244, 152, 62, 93, 235, 222, 96, 225, 54, 181, 217, 237, 184, 125, + 62, 54, 206, 158, 205, 95, 175, 184, 130, 47, 255, 254, 119, 108, 145, 136, 101, 237, 173, 202, 228, 220, + 6, 164, 186, 221, 116, 24, 50, 68, 179, 148, 87, 243, 254, 157, 110, 55, 78, 183, 155, 13, 95, 126, 201, + 51, 227, 198, 241, 218, 29, 119, 176, 127, 235, 86, 82, 33, 102, 205, 211, 159, 129, 11, 24, 118, 227, 141, + 8, 162, 168, 89, 95, 234, 193, 252, 37, 147, 149, 72, 4, 111, 171, 86, 228, 140, 31, 31, 3, 88, 167, 139, + 76, 244, 255, 213, 45, 153, 45, 250, 245, 35, 163, 91, 55, 148, 36, 237, 7, 110, 151, 139, 111, 87, 175, + 222, 182, 107, 215, 174, 3, 209, 75, 89, 85, 111, 55, 222, 130, 122, 138, 251, 115, 131, 167, 179, 6, 96, + 157, 2, 169, 134, 87, 149, 138, 153, 132, 97, 64, 62, 112, 224, 192, 161, 149, 43, 87, 110, 73, 154, 155, + 48, 28, 214, 220, 119, 3, 6, 196, 5, 187, 39, 163, 90, 47, 209, 129, 183, 30, 54, 140, 102, 221, 187, 107, + 41, 211, 141, 128, 194, 129, 0, 253, 166, 76, 161, 77, 86, 22, 34, 154, 114, 246, 161, 89, 148, 182, 127, + 243, 13, 47, 92, 123, 45, 175, 92, 127, 61, 251, 183, 108, 193, 83, 205, 182, 55, 114, 180, 157, 69, 155, + 11, 46, 64, 160, 98, 235, 26, 15, 229, 96, 78, 103, 163, 69, 203, 131, 22, 159, 117, 96, 219, 54, 94, 190, + 238, 58, 62, 188, 255, 126, 194, 165, 165, 218, 169, 221, 68, 145, 210, 82, 218, 92, 118, 25, 57, 147, 39, + 199, 42, 154, 91, 201, 133, 104, 120, 53, 6, 189, 219, 169, 232, 34, 52, 186, 154, 124, 209, 194, 163, 77, + 84, 63, 72, 85, 85, 236, 46, 23, 169, 169, 169, 177, 185, 75, 20, 204, 110, 21, 208, 110, 14, 110, 135, + 114, 153, 9, 1, 237, 167, 78, 37, 107, 200, 16, 13, 136, 154, 200, 21, 173, 105, 245, 254, 189, 247, 242, + 202, 207, 126, 198, 225, 157, 59, 73, 35, 62, 182, 74, 151, 99, 179, 108, 155, 91, 243, 8, 64, 118, 223, + 190, 100, 116, 238, 92, 45, 93, 99, 143, 186, 35, 247, 230, 229, 241, 242, 212, 169, 204, 248, 233, 79, + 217, 181, 110, 29, 169, 16, 7, 238, 116, 22, 128, 110, 23, 95, 76, 183, 225, 195, 171, 95, 6, 165, 190, + 144, 32, 128, 14, 24, 68, 49, 198, 162, 205, 134, 104, 179, 197, 126, 70, 16, 144, 35, 17, 206, 153, 50, 5, + 71, 52, 11, 57, 246, 21, 84, 191, 62, 94, 162, 100, 39, 5, 104, 63, 97, 2, 54, 151, 139, 100, 197, 153, + 139, 162, 200, 156, 57, 115, 86, 3, 193, 4, 238, 193, 100, 70, 191, 52, 104, 106, 204, 0, 75, 39, 93, 14, + 205, 110, 66, 61, 155, 48, 60, 251, 203, 47, 87, 233, 10, 236, 180, 89, 85, 17, 236, 118, 218, 79, 156, + 104, 233, 34, 60, 29, 112, 165, 162, 41, 227, 115, 111, 190, 25, 167, 223, 143, 35, 37, 5, 167, 207, 135, + 211, 231, 195, 229, 247, 227, 246, 251, 113, 167, 166, 226, 242, 249, 112, 122, 189, 56, 60, 30, 236, 46, + 23, 162, 221, 142, 96, 179, 53, 168, 148, 126, 35, 75, 145, 8, 25, 237, 218, 113, 233, 181, 215, 34, 16, + 159, 81, 151, 10, 184, 84, 149, 213, 179, 103, 243, 212, 152, 49, 124, 248, 251, 223, 19, 40, 42, 210, 178, + 235, 42, 185, 95, 221, 77, 216, 113, 212, 168, 88, 188, 83, 101, 173, 107, 204, 32, 75, 111, 99, 227, 3, + 28, 138, 194, 252, 127, 254, 147, 23, 71, 143, 230, 251, 197, 139, 113, 153, 43, 193, 171, 42, 138, 44, + 115, 222, 175, 127, 141, 195, 231, 139, 203, 40, 50, 43, 89, 243, 70, 155, 200, 130, 101, 180, 98, 57, 162, + 125, 40, 235, 122, 158, 154, 184, 124, 190, 69, 187, 29, 143, 199, 83, 1, 24, 27, 173, 55, 230, 82, 12, + 198, 249, 135, 138, 27, 170, 12, 184, 211, 211, 233, 118, 207, 61, 21, 74, 50, 8, 54, 27, 46, 191, 159, + 173, 243, 231, 51, 99, 212, 40, 22, 189, 253, 54, 78, 85, 77, 216, 142, 71, 151, 103, 171, 184, 67, 99, + 208, 253, 57, 99, 199, 34, 58, 157, 149, 202, 151, 30, 15, 89, 124, 226, 4, 255, 122, 240, 65, 158, 30, 59, + 150, 117, 243, 230, 225, 133, 88, 16, 189, 85, 32, 189, 11, 24, 116, 211, 77, 216, 61, 158, 58, 41, 1, 83, + 21, 35, 8, 8, 54, 27, 54, 151, 11, 167, 215, 139, 203, 231, 195, 227, 247, 107, 250, 213, 227, 193, 225, + 114, 33, 58, 28, 90, 217, 7, 73, 66, 10, 135, 9, 20, 23, 19, 9, 6, 181, 166, 211, 178, 140, 232, 112, 128, + 170, 210, 178, 95, 63, 218, 93, 113, 5, 230, 40, 182, 83, 205, 30, 84, 163, 242, 224, 105, 214, 140, 236, + 203, 46, 75, 90, 169, 30, 155, 221, 206, 161, 195, 135, 139, 231, 47, 88, 176, 33, 122, 41, 179, 245, 74, + 103, 93, 44, 27, 53, 53, 186, 66, 163, 9, 72, 197, 186, 109, 78, 4, 112, 47, 89, 188, 248, 187, 131, 7, 14, + 156, 204, 204, 204, 204, 144, 146, 144, 230, 42, 151, 149, 209, 122, 200, 16, 82, 178, 178, 144, 14, 31, + 198, 142, 65, 17, 26, 94, 171, 26, 176, 241, 189, 126, 3, 118, 143, 135, 61, 179, 102, 177, 235, 171, 175, + 8, 43, 138, 118, 19, 170, 138, 152, 146, 130, 205, 237, 198, 225, 243, 225, 242, 249, 240, 102, 100, 224, + 203, 200, 192, 147, 150, 70, 74, 122, 58, 222, 180, 52, 77, 41, 184, 221, 90, 129, 61, 85, 69, 150, 36, 20, + 73, 210, 226, 184, 146, 116, 250, 169, 45, 138, 4, 2, 244, 251, 233, 79, 89, 243, 246, 219, 4, 10, 10, 98, + 39, 7, 133, 114, 240, 17, 46, 43, 227, 191, 47, 189, 196, 250, 47, 190, 96, 226, 255, 251, 127, 92, 52, + 121, 178, 86, 22, 32, 65, 34, 128, 28, 12, 146, 115, 249, 229, 228, 61, 245, 20, 4, 2, 49, 64, 3, 229, 207, + 91, 183, 36, 73, 134, 247, 54, 139, 207, 29, 192, 161, 29, 59, 120, 237, 154, 107, 184, 252, 238, 187, 25, + 126, 223, 125, 56, 220, 110, 34, 209, 147, 185, 28, 8, 144, 126, 254, 249, 116, 188, 241, 70, 182, 253, + 237, 111, 113, 85, 204, 205, 167, 32, 179, 140, 232, 227, 50, 222, 171, 126, 74, 112, 0, 162, 170, 106, + 243, 87, 207, 231, 176, 58, 164, 203, 230, 217, 64, 198, 24, 58, 163, 181, 42, 81, 141, 43, 43, 157, 160, + 175, 125, 189, 38, 88, 247, 91, 110, 193, 223, 181, 107, 92, 97, 76, 135, 215, 75, 36, 16, 96, 246, 67, 15, + 177, 224, 149, 87, 144, 20, 5, 31, 21, 193, 121, 12, 144, 19, 111, 69, 51, 182, 224, 129, 242, 29, 52, 37, + 45, 141, 118, 35, 70, 148, 135, 34, 88, 144, 94, 90, 97, 249, 123, 239, 49, 235, 137, 39, 56, 124, 240, 32, + 41, 104, 214, 93, 253, 187, 205, 238, 80, 208, 20, 111, 199, 30, 61, 232, 54, 122, 52, 225, 146, 146, 122, + 33, 187, 162, 205, 134, 205, 225, 136, 89, 192, 165, 96, 144, 210, 194, 66, 138, 242, 243, 41, 56, 116, + 136, 19, 7, 15, 82, 112, 248, 48, 197, 199, 142, 81, 124, 252, 56, 101, 5, 5, 132, 74, 75, 181, 53, 174, + 170, 32, 203, 200, 129, 0, 30, 183, 27, 183, 221, 142, 83, 16, 72, 241, 120, 240, 165, 164, 144, 209, 186, + 53, 225, 19, 39, 98, 221, 61, 78, 245, 110, 141, 123, 65, 4, 200, 25, 54, 76, 139, 239, 178, 176, 102, 158, + 10, 185, 93, 46, 230, 44, 95, 254, 221, 129, 3, 7, 14, 25, 46, 163, 239, 151, 70, 112, 21, 135, 69, 27, 43, + 53, 118, 128, 165, 26, 94, 117, 61, 21, 215, 252, 89, 16, 4, 37, 255, 232, 209, 252, 165, 75, 151, 230, 77, + 157, 58, 117, 104, 73, 180, 218, 239, 233, 144, 34, 73, 164, 100, 103, 211, 230, 178, 203, 216, 245, 238, + 187, 177, 42, 190, 70, 144, 85, 211, 27, 32, 250, 127, 82, 32, 192, 230, 119, 222, 161, 12, 8, 68, 57, 8, + 177, 244, 118, 163, 131, 92, 0, 156, 209, 32, 240, 148, 140, 12, 210, 178, 178, 104, 150, 157, 77, 139, 14, + 29, 104, 213, 177, 35, 45, 207, 57, 135, 102, 217, 217, 164, 102, 102, 226, 136, 154, 152, 229, 112, 24, + 73, 146, 146, 150, 141, 146, 44, 146, 194, 97, 90, 116, 234, 196, 69, 83, 166, 176, 236, 141, 55, 112, 69, + 63, 55, 154, 37, 245, 88, 170, 99, 123, 247, 242, 218, 109, 183, 177, 246, 179, 207, 184, 242, 143, 127, + 164, 117, 215, 174, 4, 75, 74, 42, 220, 147, 28, 14, 147, 222, 185, 51, 173, 7, 14, 228, 199, 121, 243, 98, + 89, 83, 250, 169, 81, 175, 196, 111, 5, 176, 244, 205, 35, 98, 250, 189, 44, 73, 204, 121, 254, 121, 246, + 174, 92, 201, 164, 231, 158, 163, 85, 183, 110, 4, 163, 205, 176, 229, 64, 128, 206, 183, 222, 202, 190, + 79, 62, 33, 242, 227, 143, 177, 235, 84, 6, 188, 205, 214, 44, 133, 248, 77, 203, 22, 189, 143, 179, 133, + 20, 73, 66, 208, 99, 217, 26, 42, 9, 2, 138, 44, 67, 36, 18, 155, 39, 35, 144, 49, 187, 4, 161, 162, 117, + 66, 127, 53, 110, 166, 190, 220, 92, 58, 221, 116, 19, 178, 222, 34, 41, 106, 57, 58, 180, 113, 35, 159, + 221, 119, 31, 219, 214, 172, 137, 43, 14, 106, 182, 124, 58, 72, 12, 174, 140, 27, 191, 174, 40, 115, 6, + 13, 194, 223, 190, 189, 86, 25, 220, 124, 139, 209, 236, 192, 131, 155, 54, 241, 159, 71, 30, 97, 221, 252, + 249, 56, 208, 178, 109, 237, 38, 118, 16, 15, 42, 245, 251, 187, 248, 198, 27, 181, 64, 252, 58, 108, 187, + 101, 115, 56, 112, 184, 92, 32, 8, 148, 158, 60, 201, 193, 173, 91, 217, 191, 105, 19, 123, 243, 242, 56, + 180, 109, 27, 199, 246, 238, 165, 228, 196, 9, 130, 161, 80, 12, 89, 152, 173, 75, 70, 215, 190, 241, 158, + 205, 241, 110, 41, 16, 107, 157, 5, 213, 223, 15, 172, 228, 65, 215, 241, 237, 175, 188, 50, 105, 8, 71, + 64, 179, 190, 206, 154, 53, 235, 27, 32, 108, 112, 15, 234, 224, 170, 178, 186, 201, 141, 146, 26, 59, 192, + 210, 201, 40, 151, 230, 114, 13, 97, 64, 156, 53, 107, 214, 234, 107, 174, 185, 102, 40, 73, 58, 65, 43, + 178, 76, 206, 132, 9, 236, 121, 247, 221, 56, 152, 175, 47, 68, 253, 125, 101, 3, 54, 190, 55, 46, 102, 61, + 251, 70, 255, 14, 29, 88, 152, 143, 24, 10, 160, 74, 18, 161, 194, 66, 2, 133, 133, 28, 249, 225, 135, 56, + 37, 225, 18, 69, 82, 155, 55, 167, 101, 199, 142, 180, 235, 209, 131, 246, 125, 250, 144, 211, 163, 7, 153, + 185, 185, 184, 83, 83, 81, 20, 5, 41, 20, 66, 137, 54, 14, 173, 107, 138, 68, 34, 92, 116, 253, 245, 108, + 126, 239, 61, 228, 96, 48, 166, 172, 205, 53, 56, 116, 192, 179, 118, 206, 28, 118, 172, 92, 201, 132, 233, + 211, 25, 56, 109, 26, 8, 66, 188, 53, 75, 85, 193, 110, 167, 195, 164, 73, 252, 56, 111, 94, 236, 89, 26, + 45, 11, 177, 76, 29, 202, 21, 167, 174, 113, 236, 134, 247, 198, 6, 93, 78, 96, 231, 170, 85, 188, 57, 110, + 28, 227, 158, 124, 146, 238, 87, 93, 69, 164, 172, 44, 86, 225, 189, 203, 237, 183, 179, 241, 225, 135, 49, + 70, 138, 89, 109, 182, 170, 233, 119, 49, 43, 102, 116, 76, 250, 38, 41, 149, 148, 160, 70, 221, 161, 13, + 149, 4, 81, 36, 80, 80, 192, 225, 173, 91, 57, 103, 208, 160, 6, 15, 26, 229, 72, 4, 53, 24, 140, 101, 226, + 89, 1, 45, 163, 229, 210, 56, 231, 86, 1, 238, 18, 208, 243, 206, 59, 113, 103, 101, 17, 41, 44, 68, 116, + 56, 112, 120, 60, 108, 120, 239, 61, 102, 63, 244, 16, 5, 133, 133, 248, 40, 215, 7, 186, 85, 213, 202, + 114, 149, 104, 28, 70, 37, 41, 2, 237, 39, 77, 2, 81, 172, 160, 15, 29, 110, 55, 138, 162, 48, 111, 198, + 12, 102, 255, 245, 175, 20, 23, 21, 145, 106, 250, 238, 202, 226, 204, 34, 64, 243, 206, 157, 57, 119, 226, + 68, 66, 209, 102, 241, 103, 146, 108, 54, 27, 14, 143, 7, 85, 85, 57, 190, 111, 31, 59, 86, 174, 100, 219, + 146, 37, 236, 254, 246, 91, 142, 237, 219, 71, 48, 90, 143, 203, 8, 136, 61, 196, 235, 109, 243, 90, 213, + 117, 179, 17, 100, 153, 179, 147, 237, 84, 4, 100, 85, 213, 61, 131, 114, 89, 48, 134, 22, 72, 104, 165, + 122, 90, 246, 239, 31, 115, 15, 158, 46, 217, 29, 14, 246, 238, 219, 119, 108, 233, 255, 254, 183, 41, 58, + 36, 189, 102, 164, 177, 53, 78, 83, 246, 160, 129, 154, 0, 150, 70, 70, 240, 111, 236, 77, 168, 131, 44, + 247, 138, 149, 43, 183, 236, 222, 181, 235, 72, 78, 110, 110, 171, 112, 18, 148, 187, 28, 8, 208, 162, 111, + 95, 210, 186, 119, 167, 116, 243, 230, 164, 76, 132, 17, 100, 25, 227, 115, 140, 96, 43, 81, 5, 56, 43, + 127, 187, 162, 40, 148, 228, 231, 115, 50, 63, 159, 205, 171, 86, 33, 0, 62, 183, 155, 86, 157, 59, 115, + 206, 37, 151, 208, 109, 200, 16, 218, 247, 233, 67, 122, 171, 86, 160, 170, 132, 131, 65, 237, 100, 94, 71, + 36, 5, 2, 180, 236, 222, 157, 158, 83, 166, 144, 247, 222, 123, 184, 12, 247, 98, 156, 80, 221, 178, 100, + 71, 203, 176, 251, 215, 244, 233, 108, 249, 250, 107, 38, 63, 246, 24, 173, 186, 118, 37, 100, 168, 6, 174, + 187, 115, 125, 81, 119, 174, 131, 120, 87, 134, 241, 89, 27, 55, 36, 179, 37, 75, 7, 117, 186, 22, 178, 3, + 101, 39, 78, 240, 201, 173, 183, 114, 100, 253, 122, 6, 253, 254, 247, 216, 92, 46, 164, 146, 18, 218, 79, + 157, 202, 15, 51, 103, 82, 182, 99, 71, 204, 37, 105, 69, 70, 171, 150, 217, 130, 101, 228, 72, 73, 137, + 166, 160, 27, 176, 213, 71, 20, 69, 138, 142, 30, 101, 203, 226, 197, 116, 25, 50, 4, 185, 1, 223, 139, 0, + 90, 163, 235, 178, 178, 10, 115, 85, 93, 215, 32, 148, 203, 118, 4, 200, 56, 239, 60, 114, 174, 190, 26, + 169, 184, 24, 187, 219, 141, 28, 14, 51, 239, 129, 7, 88, 241, 198, 27, 40, 104, 150, 17, 179, 21, 37, 145, + 213, 202, 236, 22, 52, 186, 6, 245, 215, 212, 156, 28, 178, 6, 14, 68, 42, 43, 139, 201, 149, 32, 8, 184, + 82, 83, 57, 180, 101, 11, 159, 76, 159, 206, 198, 101, 203, 98, 157, 5, 204, 192, 202, 42, 91, 210, 120, + 157, 222, 55, 221, 132, 43, 35, 131, 240, 25, 236, 109, 106, 119, 58, 113, 184, 221, 20, 229, 231, 179, + 238, 139, 47, 88, 59, 107, 22, 59, 87, 174, 164, 160, 160, 0, 12, 227, 77, 37, 30, 248, 84, 21, 19, 101, + 116, 229, 155, 203, 171, 88, 197, 218, 157, 10, 25, 245, 184, 110, 209, 236, 60, 110, 28, 174, 244, 244, + 26, 55, 248, 78, 68, 110, 151, 139, 69, 11, 23, 174, 63, 121, 242, 228, 49, 65, 16, 140, 97, 52, 198, 248, + 43, 243, 182, 210, 168, 169, 41, 200, 221, 218, 194, 106, 118, 19, 202, 197, 197, 197, 39, 230, 45, 88, + 176, 38, 89, 217, 132, 170, 162, 224, 76, 75, 211, 218, 88, 112, 122, 208, 223, 202, 36, 109, 54, 255, 39, + 42, 24, 104, 174, 204, 236, 54, 253, 173, 7, 77, 161, 164, 71, 95, 149, 96, 144, 125, 223, 125, 199, 215, + 255, 252, 39, 47, 253, 252, 231, 60, 62, 124, 56, 111, 220, 118, 27, 235, 102, 207, 38, 28, 8, 224, 241, + 251, 181, 184, 139, 58, 74, 181, 85, 36, 137, 222, 55, 220, 64, 138, 211, 89, 193, 12, 111, 78, 57, 215, + 11, 114, 250, 128, 239, 22, 46, 100, 198, 216, 177, 172, 158, 57, 19, 135, 215, 171, 245, 241, 139, 126, + 159, 183, 117, 107, 218, 142, 25, 19, 215, 67, 18, 42, 6, 153, 39, 50, 253, 91, 165, 184, 235, 243, 98, 3, + 150, 191, 242, 10, 179, 126, 246, 51, 2, 199, 142, 97, 119, 187, 113, 101, 102, 210, 233, 182, 219, 44, 53, + 150, 153, 42, 115, 25, 234, 28, 60, 113, 162, 198, 207, 177, 190, 145, 205, 225, 224, 196, 129, 3, 108, 91, + 177, 2, 41, 28, 110, 216, 169, 220, 130, 128, 20, 12, 18, 41, 46, 182, 12, 100, 79, 228, 26, 52, 146, 57, + 166, 161, 243, 157, 119, 226, 72, 75, 195, 238, 245, 82, 122, 232, 16, 159, 77, 157, 202, 170, 55, 222, + 136, 179, 78, 85, 166, 7, 204, 89, 140, 137, 44, 105, 58, 160, 107, 59, 122, 52, 158, 150, 45, 181, 50, 16, + 68, 193, 137, 199, 195, 202, 55, 223, 228, 111, 99, 199, 178, 101, 217, 178, 42, 107, 106, 89, 173, 11, 1, + 104, 121, 206, 57, 116, 153, 50, 197, 50, 11, 178, 54, 200, 238, 114, 225, 241, 251, 57, 182, 111, 31, 159, + 60, 242, 8, 79, 140, 24, 193, 107, 119, 220, 193, 154, 57, 115, 8, 22, 20, 224, 131, 88, 31, 70, 99, 221, + 187, 202, 202, 89, 152, 107, 229, 89, 221, 179, 254, 172, 173, 220, 194, 213, 149, 110, 171, 3, 114, 172, + 246, 213, 184, 113, 167, 84, 252, 213, 138, 4, 65, 32, 28, 14, 243, 217, 231, 159, 175, 162, 252, 188, 218, + 148, 61, 88, 5, 53, 1, 172, 114, 50, 187, 9, 141, 66, 20, 6, 148, 89, 179, 102, 125, 83, 22, 8, 36, 45, + 219, 78, 14, 133, 104, 59, 102, 12, 14, 183, 219, 178, 85, 74, 77, 164, 212, 104, 197, 208, 55, 125, 171, + 218, 77, 198, 44, 161, 68, 217, 111, 137, 106, 223, 232, 223, 227, 131, 88, 165, 231, 162, 35, 71, 88, 254, + 201, 39, 188, 60, 109, 26, 79, 92, 118, 25, 31, 61, 252, 48, 7, 183, 109, 195, 233, 245, 226, 244, 122, + 147, 246, 172, 170, 203, 145, 96, 144, 150, 125, 250, 208, 117, 194, 4, 212, 42, 158, 129, 49, 245, 60, 21, + 13, 136, 252, 251, 87, 191, 226, 227, 59, 239, 36, 88, 88, 136, 35, 37, 69, 19, 10, 73, 34, 103, 226, 68, + 68, 42, 106, 15, 115, 54, 159, 85, 51, 102, 171, 141, 204, 120, 138, 119, 3, 59, 22, 45, 226, 211, 73, 147, + 82, 109, 184, 112, 0, 0, 32, 0, 73, 68, 65, 84, 56, 186, 97, 3, 130, 40, 210, 238, 170, 171, 72, 63, 255, + 252, 26, 201, 133, 57, 230, 67, 127, 31, 56, 126, 28, 89, 146, 98, 110, 194, 134, 200, 162, 221, 206, 193, + 109, 219, 216, 183, 105, 19, 69, 71, 143, 34, 216, 237, 117, 62, 166, 83, 101, 108, 54, 2, 5, 5, 200, 209, + 196, 137, 68, 27, 171, 121, 147, 53, 206, 191, 74, 185, 165, 162, 217, 133, 23, 146, 61, 97, 2, 162, 205, + 198, 145, 213, 171, 249, 207, 164, 73, 236, 89, 190, 60, 230, 118, 50, 183, 84, 210, 215, 129, 185, 135, + 165, 21, 176, 50, 142, 73, 191, 166, 221, 102, 35, 247, 202, 43, 145, 163, 133, 43, 157, 62, 31, 165, 39, + 79, 242, 193, 45, 183, 240, 225, 253, 247, 19, 42, 44, 172, 80, 83, 203, 188, 238, 204, 235, 79, 7, 26, 42, + 208, 253, 166, 155, 112, 53, 111, 142, 92, 203, 69, 146, 69, 155, 45, 6, 172, 254, 117, 255, 253, 60, 113, + 217, 101, 124, 49, 99, 6, 39, 14, 30, 140, 211, 113, 230, 242, 17, 70, 16, 101, 188, 15, 115, 217, 150, 20, + 211, 251, 68, 197, 90, 205, 21, 251, 107, 2, 176, 116, 210, 231, 70, 175, 125, 213, 252, 210, 75, 73, 239, + 222, 29, 41, 20, 74, 202, 179, 114, 56, 157, 108, 217, 178, 101, 223, 170, 85, 171, 182, 69, 47, 169, 187, + 7, 141, 145, 39, 167, 90, 210, 241, 172, 165, 38, 128, 165, 145, 81, 150, 42, 84, 117, 143, 178, 186, 118, + 237, 218, 157, 155, 190, 251, 110, 183, 203, 233, 36, 25, 5, 219, 228, 80, 136, 244, 46, 93, 104, 49, 120, + 112, 5, 43, 86, 117, 201, 108, 185, 50, 198, 86, 232, 138, 211, 8, 170, 82, 40, 95, 248, 70, 5, 96, 245, + 179, 213, 201, 203, 12, 184, 244, 140, 160, 20, 224, 248, 190, 125, 252, 247, 165, 151, 120, 234, 138, 43, + 248, 199, 141, 55, 178, 125, 217, 50, 28, 46, 23, 206, 42, 250, 242, 37, 189, 120, 159, 36, 113, 254, 205, + 55, 227, 177, 219, 45, 43, 177, 39, 178, 42, 233, 74, 243, 219, 143, 62, 226, 173, 241, 227, 217, 191, 98, + 5, 174, 212, 84, 228, 80, 136, 204, 62, 125, 200, 236, 219, 183, 66, 163, 110, 243, 179, 79, 4, 178, 172, + 82, 208, 141, 167, 87, 55, 112, 124, 215, 46, 102, 95, 125, 53, 123, 191, 248, 2, 111, 118, 54, 231, 68, + 173, 88, 85, 89, 54, 173, 20, 178, 254, 153, 13, 40, 249, 241, 71, 228, 80, 8, 161, 30, 20, 86, 60, 229, + 57, 141, 68, 216, 179, 110, 29, 69, 146, 196, 143, 219, 183, 99, 183, 40, 218, 218, 80, 88, 20, 69, 202, + 242, 243, 137, 132, 66, 21, 220, 112, 88, 204, 37, 134, 185, 87, 13, 172, 235, 139, 78, 119, 220, 129, 39, + 43, 139, 221, 31, 127, 204, 236, 107, 175, 229, 228, 222, 189, 184, 76, 242, 104, 37, 131, 230, 138, 236, + 137, 172, 41, 198, 107, 135, 129, 230, 253, 250, 145, 209, 163, 7, 74, 56, 140, 203, 239, 231, 135, 165, + 75, 121, 107, 236, 88, 214, 125, 254, 121, 76, 95, 88, 117, 63, 72, 100, 193, 209, 193, 5, 64, 70, 110, 46, + 237, 39, 77, 210, 172, 87, 181, 56, 7, 46, 175, 23, 41, 18, 225, 191, 79, 63, 205, 83, 35, 71, 242, 245, + 155, 111, 18, 41, 41, 33, 141, 138, 86, 183, 68, 37, 44, 140, 122, 211, 172, 87, 19, 233, 88, 243, 97, 214, + 248, 252, 19, 53, 241, 78, 68, 86, 50, 161, 111, 92, 185, 147, 39, 35, 218, 108, 73, 43, 200, 235, 114, 58, + 153, 243, 213, 87, 223, 68, 34, 145, 34, 131, 123, 48, 145, 245, 74, 53, 143, 181, 177, 82, 19, 192, 138, + 39, 163, 222, 138, 43, 215, 32, 8, 130, 36, 203, 114, 241, 156, 57, 115, 86, 57, 163, 238, 163, 211, 191, + 154, 138, 96, 179, 145, 59, 121, 242, 41, 87, 116, 79, 20, 119, 101, 85, 24, 211, 172, 32, 82, 176, 86, 14, + 137, 126, 151, 8, 120, 25, 193, 86, 58, 32, 132, 66, 172, 254, 239, 127, 121, 225, 170, 171, 120, 229, 103, + 63, 99, 207, 154, 53, 184, 83, 83, 177, 39, 235, 185, 85, 65, 82, 48, 72, 139, 11, 46, 160, 253, 152, 49, + 168, 196, 187, 74, 171, 99, 182, 247, 1, 249, 59, 119, 242, 193, 181, 215, 178, 246, 229, 151, 177, 187, + 92, 56, 211, 210, 200, 189, 234, 42, 75, 151, 157, 57, 40, 85, 52, 93, 211, 73, 252, 166, 150, 232, 244, + 234, 66, 139, 9, 91, 248, 139, 95, 176, 237, 149, 87, 104, 63, 117, 42, 25, 61, 123, 34, 89, 92, 211, 74, + 62, 204, 214, 43, 29, 96, 149, 229, 231, 19, 46, 41, 105, 176, 253, 8, 69, 155, 141, 146, 19, 39, 56, 176, + 105, 19, 0, 187, 86, 175, 174, 180, 199, 99, 125, 39, 65, 20, 41, 62, 120, 16, 5, 235, 108, 51, 168, 218, + 130, 161, 162, 41, 167, 230, 23, 93, 68, 206, 85, 87, 177, 229, 133, 23, 88, 124, 251, 237, 132, 139, 139, + 171, 4, 87, 86, 150, 84, 43, 203, 149, 217, 53, 168, 43, 199, 220, 171, 174, 194, 225, 243, 97, 115, 58, + 89, 253, 194, 11, 124, 112, 221, 117, 28, 255, 225, 135, 184, 158, 138, 137, 172, 86, 137, 92, 100, 186, + 117, 184, 203, 180, 105, 120, 178, 178, 80, 146, 80, 14, 199, 138, 68, 81, 196, 227, 247, 243, 253, 242, + 229, 60, 55, 110, 28, 159, 60, 249, 36, 161, 194, 66, 210, 41, 7, 86, 149, 1, 42, 179, 94, 180, 210, 155, + 102, 64, 101, 244, 22, 88, 61, 7, 125, 14, 18, 89, 14, 171, 34, 93, 23, 232, 155, 86, 74, 235, 214, 180, + 25, 62, 92, 43, 159, 145, 4, 18, 69, 145, 194, 194, 194, 200, 236, 217, 179, 87, 71, 63, 170, 204, 122, + 213, 4, 174, 12, 212, 48, 53, 110, 237, 145, 17, 96, 153, 45, 88, 97, 64, 157, 61, 123, 246, 154, 19, 39, + 78, 132, 108, 182, 202, 194, 143, 171, 79, 82, 32, 64, 214, 144, 33, 248, 114, 114, 42, 108, 164, 70, 101, + 91, 21, 155, 221, 131, 230, 205, 189, 50, 51, 125, 162, 147, 153, 149, 98, 169, 236, 52, 102, 228, 52, 192, + 165, 40, 108, 152, 63, 159, 231, 38, 78, 228, 221, 123, 239, 165, 40, 63, 31, 183, 223, 95, 251, 241, 51, + 170, 246, 4, 187, 221, 114, 11, 78, 155, 13, 1, 107, 23, 137, 89, 233, 25, 45, 75, 94, 64, 13, 6, 89, 248, + 240, 195, 44, 184, 243, 78, 66, 199, 143, 147, 123, 229, 149, 164, 180, 108, 153, 176, 149, 141, 121, 30, + 116, 107, 162, 149, 37, 203, 104, 5, 52, 130, 44, 7, 160, 134, 195, 172, 188, 231, 30, 118, 191, 251, 46, + 93, 238, 185, 167, 130, 214, 170, 142, 60, 24, 1, 86, 32, 63, 159, 210, 252, 124, 173, 188, 65, 3, 36, 187, + 211, 201, 193, 45, 91, 56, 113, 224, 128, 230, 78, 93, 177, 66, 107, 96, 221, 64, 227, 176, 4, 81, 228, + 228, 206, 157, 213, 10, 146, 182, 250, 220, 104, 177, 232, 116, 215, 93, 236, 120, 245, 85, 86, 61, 248, + 32, 72, 82, 108, 163, 54, 135, 8, 152, 45, 86, 70, 112, 101, 21, 96, 111, 229, 158, 148, 1, 95, 155, 54, + 228, 76, 156, 72, 32, 63, 159, 249, 183, 222, 202, 226, 63, 253, 9, 33, 28, 198, 67, 60, 152, 51, 199, 32, + 153, 99, 31, 141, 215, 214, 193, 85, 90, 135, 14, 116, 188, 246, 90, 45, 112, 190, 22, 200, 230, 112, 96, + 115, 185, 152, 243, 236, 179, 252, 237, 218, 107, 217, 191, 101, 75, 156, 197, 202, 74, 71, 86, 165, 3, + 205, 58, 196, 120, 175, 86, 224, 210, 236, 154, 77, 212, 119, 178, 170, 32, 122, 243, 28, 233, 242, 16, 1, + 178, 199, 141, 75, 42, 72, 117, 187, 221, 172, 94, 189, 122, 235, 150, 45, 91, 126, 160, 220, 11, 153, 200, + 130, 213, 68, 6, 106, 2, 88, 21, 169, 50, 144, 165, 238, 216, 185, 115, 223, 55, 223, 124, 179, 213, 21, + 173, 11, 117, 186, 172, 72, 18, 238, 230, 205, 105, 19, 13, 162, 174, 174, 157, 213, 184, 184, 140, 139, + 49, 17, 200, 50, 198, 90, 88, 197, 19, 36, 10, 208, 180, 82, 38, 149, 41, 25, 179, 27, 204, 15, 216, 36, + 137, 197, 239, 190, 203, 211, 163, 70, 177, 226, 189, 247, 112, 120, 60, 136, 118, 123, 82, 158, 95, 34, + 142, 148, 149, 209, 162, 111, 95, 218, 142, 30, 141, 76, 69, 235, 94, 85, 193, 190, 250, 6, 224, 2, 182, + 124, 242, 9, 95, 78, 152, 64, 164, 184, 152, 246, 83, 167, 86, 8, 118, 183, 154, 27, 43, 171, 162, 21, 216, + 50, 42, 89, 99, 6, 162, 8, 172, 249, 205, 111, 40, 217, 187, 151, 102, 189, 122, 197, 50, 184, 170, 178, + 98, 169, 84, 220, 160, 67, 161, 16, 39, 247, 236, 209, 170, 199, 215, 226, 51, 175, 45, 22, 237, 118, 182, + 46, 94, 172, 85, 42, 7, 14, 110, 220, 200, 145, 93, 187, 16, 29, 142, 58, 31, 91, 141, 25, 173, 102, 219, + 177, 239, 191, 175, 212, 74, 81, 21, 116, 148, 209, 172, 87, 133, 155, 54, 177, 102, 250, 244, 10, 25, 172, + 230, 170, 254, 137, 130, 216, 19, 245, 58, 52, 203, 148, 14, 176, 58, 70, 147, 49, 190, 28, 63, 158, 109, + 179, 102, 225, 198, 58, 198, 203, 28, 203, 105, 101, 49, 51, 94, 83, 2, 58, 221, 114, 11, 174, 150, 45, 81, + 34, 145, 164, 63, 119, 193, 102, 35, 92, 86, 198, 219, 119, 220, 193, 39, 143, 63, 142, 24, 14, 199, 226, + 196, 204, 128, 40, 209, 33, 211, 42, 84, 194, 124, 88, 50, 115, 162, 57, 176, 42, 232, 106, 158, 139, 154, + 184, 7, 245, 205, 74, 20, 69, 114, 38, 77, 210, 226, 227, 146, 181, 254, 68, 145, 207, 103, 205, 90, 65, + 124, 107, 28, 115, 246, 160, 98, 26, 82, 19, 209, 4, 176, 140, 100, 14, 111, 176, 42, 58, 26, 1, 66, 159, + 127, 254, 249, 242, 100, 158, 158, 149, 72, 132, 220, 137, 19, 17, 109, 182, 106, 187, 131, 204, 100, 222, + 208, 205, 85, 154, 205, 253, 234, 18, 45, 126, 99, 60, 82, 101, 113, 8, 230, 64, 249, 202, 92, 1, 186, 69, + 171, 248, 200, 17, 222, 186, 231, 30, 222, 185, 235, 46, 66, 165, 165, 90, 16, 124, 109, 81, 84, 57, 116, + 189, 237, 54, 236, 209, 182, 52, 102, 176, 99, 62, 217, 155, 227, 163, 244, 231, 230, 6, 142, 126, 247, 29, + 243, 38, 76, 192, 238, 241, 224, 246, 122, 45, 93, 185, 102, 235, 67, 101, 243, 97, 165, 104, 205, 21, 173, + 5, 69, 97, 251, 243, 207, 35, 149, 150, 198, 98, 97, 170, 11, 188, 141, 110, 30, 21, 56, 186, 121, 179, 22, + 147, 209, 192, 72, 16, 69, 2, 133, 133, 108, 155, 63, 63, 102, 253, 8, 6, 2, 108, 95, 188, 88, 43, 0, 217, + 192, 72, 16, 69, 66, 133, 133, 156, 252, 254, 251, 88, 221, 163, 170, 226, 109, 172, 98, 109, 4, 32, 116, + 236, 24, 219, 95, 126, 57, 14, 88, 89, 85, 102, 79, 100, 41, 49, 2, 172, 216, 248, 76, 215, 53, 94, 219, + 157, 154, 138, 96, 183, 51, 111, 194, 4, 142, 111, 219, 134, 155, 138, 49, 159, 137, 98, 53, 173, 128, 157, + 17, 92, 249, 59, 117, 34, 119, 242, 228, 90, 203, 28, 116, 184, 92, 252, 231, 145, 71, 88, 254, 233, 167, + 164, 18, 111, 73, 74, 100, 221, 183, 2, 85, 86, 128, 42, 81, 187, 35, 243, 28, 152, 75, 84, 84, 214, 18, + 169, 38, 187, 139, 190, 97, 133, 129, 204, 254, 253, 181, 3, 89, 40, 84, 163, 231, 147, 136, 236, 118, 59, + 7, 14, 28, 56, 185, 192, 186, 53, 78, 83, 246, 96, 21, 212, 4, 176, 172, 169, 178, 108, 66, 22, 44, 92, + 152, 183, 111, 223, 190, 19, 142, 106, 52, 13, 174, 14, 201, 161, 16, 25, 61, 123, 210, 124, 224, 64, 45, + 93, 145, 242, 69, 83, 93, 50, 187, 11, 19, 109, 238, 230, 146, 2, 86, 109, 50, 172, 172, 44, 137, 210, 146, + 43, 115, 43, 154, 227, 180, 116, 19, 251, 242, 143, 62, 98, 198, 228, 201, 28, 218, 182, 13, 183, 69, 243, + 227, 100, 145, 28, 8, 208, 252, 146, 75, 104, 59, 121, 114, 172, 199, 151, 149, 69, 201, 108, 201, 178, 58, + 233, 59, 129, 178, 131, 7, 217, 58, 99, 6, 68, 83, 211, 19, 197, 203, 153, 3, 150, 19, 5, 193, 87, 86, 228, + 49, 86, 215, 170, 164, 132, 146, 168, 59, 169, 186, 100, 190, 190, 8, 28, 206, 203, 171, 181, 184, 150, + 218, 36, 135, 199, 195, 238, 111, 190, 225, 240, 214, 173, 177, 172, 56, 39, 144, 247, 217, 103, 132, 74, + 75, 27, 92, 92, 153, 205, 110, 167, 96, 255, 126, 138, 15, 30, 172, 118, 128, 187, 21, 9, 64, 233, 15, 63, + 196, 90, 56, 37, 138, 253, 51, 202, 149, 21, 192, 169, 206, 181, 99, 114, 30, 137, 176, 229, 133, 23, 8, + 30, 62, 28, 23, 24, 175, 31, 86, 172, 14, 42, 86, 113, 94, 102, 119, 167, 4, 156, 115, 243, 205, 184, 154, + 55, 143, 149, 125, 72, 38, 57, 220, 110, 246, 229, 229, 177, 246, 227, 143, 181, 208, 5, 42, 7, 86, 149, + 37, 246, 84, 6, 164, 172, 116, 172, 185, 66, 191, 217, 210, 40, 82, 17, 236, 90, 37, 172, 24, 201, 168, + 119, 20, 226, 55, 171, 220, 171, 174, 194, 230, 114, 197, 194, 36, 78, 151, 60, 30, 15, 11, 22, 46, 92, + 127, 228, 200, 145, 195, 130, 32, 200, 196, 187, 7, 155, 172, 87, 85, 80, 195, 210, 78, 181, 79, 86, 86, + 44, 115, 176, 187, 124, 252, 248, 241, 252, 121, 243, 231, 175, 115, 185, 221, 73, 73, 129, 85, 85, 21, + 193, 225, 32, 103, 202, 148, 184, 5, 83, 29, 107, 133, 149, 146, 180, 138, 5, 178, 83, 57, 216, 74, 84, 8, + 176, 50, 55, 163, 217, 173, 104, 21, 215, 100, 165, 172, 210, 128, 3, 91, 182, 240, 183, 171, 175, 230, + 251, 104, 166, 94, 82, 158, 163, 5, 43, 178, 76, 167, 155, 111, 198, 230, 116, 198, 158, 101, 85, 110, 59, + 171, 0, 84, 253, 249, 168, 101, 101, 40, 161, 80, 149, 27, 97, 117, 172, 89, 102, 80, 107, 220, 132, 172, + 92, 6, 85, 145, 213, 53, 133, 232, 119, 29, 219, 188, 153, 210, 227, 199, 227, 155, 76, 55, 0, 6, 88, 251, + 209, 71, 96, 120, 70, 94, 224, 224, 250, 245, 236, 249, 246, 91, 236, 201, 90, 131, 103, 136, 5, 167, 147, + 35, 121, 121, 132, 37, 41, 14, 108, 152, 231, 174, 42, 178, 114, 65, 87, 182, 134, 19, 197, 90, 233, 223, + 85, 29, 121, 86, 130, 65, 40, 43, 139, 147, 81, 115, 125, 45, 43, 235, 78, 162, 98, 154, 42, 154, 82, 245, + 119, 235, 70, 206, 148, 41, 68, 74, 75, 107, 229, 153, 139, 118, 59, 43, 223, 121, 7, 57, 26, 43, 150, 72, + 111, 37, 10, 196, 175, 12, 76, 153, 159, 189, 149, 190, 77, 196, 85, 149, 232, 168, 137, 155, 80, 2, 188, + 173, 91, 147, 53, 98, 4, 82, 32, 144, 156, 181, 39, 8, 132, 66, 33, 62, 251, 236, 179, 21, 104, 123, 161, + 49, 184, 221, 216, 156, 66, 165, 41, 254, 202, 146, 154, 0, 150, 53, 233, 2, 99, 118, 19, 198, 90, 250, + 125, 241, 197, 23, 43, 66, 193, 160, 182, 0, 84, 245, 180, 89, 14, 4, 104, 61, 108, 24, 41, 217, 217, 49, + 55, 161, 78, 149, 5, 189, 90, 89, 173, 18, 177, 57, 230, 34, 17, 8, 51, 43, 142, 170, 192, 86, 85, 193, + 161, 58, 27, 21, 155, 31, 40, 59, 122, 148, 215, 127, 254, 115, 182, 46, 88, 160, 89, 178, 146, 240, 28, + 43, 60, 215, 178, 50, 154, 245, 238, 77, 187, 43, 175, 36, 98, 122, 94, 149, 149, 84, 72, 20, 132, 154, 40, + 86, 34, 209, 28, 153, 107, 82, 37, 114, 25, 38, 218, 12, 173, 226, 100, 170, 98, 243, 28, 59, 128, 226, + 131, 7, 57, 182, 109, 155, 214, 168, 182, 22, 158, 115, 109, 176, 221, 229, 226, 208, 230, 205, 108, 159, + 51, 135, 20, 211, 92, 1, 172, 126, 251, 109, 98, 84, 15, 198, 91, 45, 86, 20, 246, 175, 92, 105, 185, 62, + 205, 242, 82, 217, 252, 90, 29, 162, 172, 44, 162, 137, 228, 201, 74, 62, 171, 115, 93, 171, 82, 36, 137, + 92, 102, 86, 46, 73, 253, 187, 116, 5, 43, 1, 157, 111, 189, 21, 103, 90, 26, 170, 36, 37, 253, 121, 59, + 156, 78, 14, 110, 218, 68, 222, 127, 254, 131, 207, 48, 198, 170, 92, 129, 213, 177, 84, 25, 117, 101, 117, + 244, 111, 77, 184, 170, 185, 136, 137, 61, 229, 238, 193, 54, 99, 199, 226, 205, 202, 210, 138, 139, 38, + 225, 217, 185, 156, 78, 54, 109, 222, 188, 199, 80, 251, 74, 223, 3, 205, 214, 171, 38, 112, 149, 128, 154, + 0, 150, 53, 169, 16, 7, 178, 140, 129, 238, 17, 128, 111, 190, 249, 102, 251, 119, 223, 125, 183, 203, 149, + 164, 56, 16, 69, 146, 240, 180, 106, 69, 155, 113, 227, 226, 220, 132, 58, 39, 139, 170, 90, 180, 86, 96, + 32, 145, 171, 209, 202, 210, 149, 40, 102, 203, 232, 86, 52, 150, 117, 136, 20, 23, 243, 246, 29, 119, 176, + 231, 219, 111, 181, 122, 89, 181, 64, 170, 36, 113, 206, 173, 183, 98, 243, 120, 98, 224, 213, 120, 191, + 137, 64, 164, 149, 171, 208, 184, 41, 85, 151, 172, 92, 118, 85, 185, 111, 19, 157, 250, 171, 186, 78, 34, + 176, 37, 1, 123, 151, 47, 71, 76, 146, 91, 251, 76, 144, 221, 225, 96, 229, 155, 111, 18, 14, 6, 99, 214, + 68, 125, 62, 82, 128, 109, 115, 230, 176, 183, 22, 229, 38, 217, 36, 218, 108, 148, 29, 63, 206, 143, 223, + 126, 139, 3, 235, 141, 180, 42, 210, 255, 198, 124, 72, 170, 142, 12, 153, 99, 173, 170, 43, 195, 86, 58, + 193, 202, 21, 89, 85, 217, 7, 157, 116, 157, 22, 6, 50, 122, 245, 34, 123, 226, 196, 90, 139, 189, 18, 157, + 78, 86, 188, 241, 6, 225, 178, 178, 88, 220, 149, 85, 98, 143, 85, 32, 190, 249, 62, 18, 101, 90, 86, 6, + 128, 146, 77, 170, 233, 189, 190, 65, 217, 108, 54, 114, 38, 79, 78, 90, 229, 118, 0, 167, 211, 201, 172, + 207, 63, 95, 25, 173, 125, 165, 131, 43, 115, 128, 123, 109, 109, 85, 103, 5, 53, 1, 172, 138, 164, 26, 94, + 85, 44, 172, 88, 130, 32, 68, 36, 73, 42, 158, 245, 197, 23, 43, 29, 81, 215, 83, 50, 88, 142, 68, 200, + 185, 242, 74, 108, 118, 123, 133, 178, 184, 80, 251, 210, 91, 19, 203, 136, 21, 216, 50, 7, 205, 39, 202, + 76, 52, 130, 44, 31, 80, 118, 242, 36, 31, 253, 246, 183, 4, 75, 75, 107, 197, 133, 37, 5, 131, 164, 247, + 232, 65, 187, 171, 175, 142, 3, 175, 70, 176, 100, 149, 20, 144, 72, 209, 90, 197, 175, 84, 247, 217, 234, + 100, 101, 73, 76, 20, 128, 92, 29, 229, 157, 200, 189, 160, 223, 163, 3, 216, 179, 104, 17, 161, 146, 18, + 16, 197, 51, 226, 14, 59, 29, 118, 120, 189, 236, 89, 181, 138, 188, 15, 62, 136, 179, 94, 25, 65, 176, 42, + 73, 44, 122, 238, 57, 100, 89, 110, 16, 247, 36, 186, 92, 28, 92, 191, 158, 130, 125, 251, 112, 16, 47, + 127, 167, 3, 120, 204, 96, 221, 202, 242, 105, 6, 87, 53, 161, 68, 135, 2, 171, 128, 237, 68, 113, 94, 250, + 53, 205, 74, 181, 211, 47, 127, 137, 45, 37, 5, 69, 81, 146, 254, 188, 109, 46, 23, 135, 183, 110, 101, + 211, 103, 159, 197, 106, 116, 89, 149, 173, 72, 100, 157, 74, 228, 162, 63, 83, 96, 170, 50, 82, 137, 175, + 220, 158, 57, 112, 160, 86, 51, 47, 73, 149, 219, 69, 155, 141, 252, 163, 71, 203, 102, 127, 249, 165, 185, + 246, 149, 149, 245, 74, 173, 245, 27, 110, 160, 212, 4, 176, 18, 147, 81, 134, 173, 106, 98, 49, 123, 246, + 236, 111, 143, 230, 231, 151, 218, 68, 145, 100, 152, 100, 229, 96, 144, 244, 243, 207, 167, 249, 160, 65, + 21, 172, 88, 117, 73, 213, 113, 25, 36, 202, 94, 178, 10, 140, 55, 90, 181, 156, 104, 238, 194, 131, 155, + 54, 145, 55, 107, 86, 173, 85, 125, 151, 67, 33, 58, 222, 114, 11, 14, 191, 191, 66, 166, 166, 81, 145, + 234, 202, 53, 81, 208, 234, 233, 102, 252, 36, 178, 102, 89, 185, 108, 173, 0, 93, 85, 215, 75, 4, 136, + 157, 192, 209, 141, 27, 201, 223, 186, 181, 222, 187, 9, 69, 81, 68, 10, 6, 249, 250, 177, 255, 207, 222, + 121, 135, 75, 81, 158, 239, 255, 51, 219, 235, 57, 116, 56, 133, 102, 137, 45, 209, 104, 76, 52, 249, 105, + 52, 69, 205, 87, 141, 37, 177, 4, 141, 81, 52, 198, 110, 4, 98, 143, 198, 134, 65, 177, 11, 74, 141, 160, + 128, 74, 17, 5, 20, 105, 210, 145, 46, 77, 64, 233, 72, 145, 14, 167, 237, 158, 221, 157, 153, 223, 31, + 187, 179, 188, 59, 103, 102, 57, 192, 236, 225, 204, 186, 247, 117, 189, 215, 46, 235, 241, 236, 156, 119, + 102, 222, 247, 158, 231, 185, 159, 251, 233, 142, 26, 143, 155, 86, 106, 5, 129, 181, 83, 167, 178, 248, + 131, 15, 240, 230, 40, 197, 108, 245, 223, 181, 110, 226, 196, 228, 230, 79, 221, 13, 252, 112, 206, 173, + 54, 14, 165, 241, 209, 162, 174, 70, 215, 223, 161, 96, 116, 45, 101, 139, 98, 155, 61, 28, 136, 208, 22, + 85, 173, 157, 75, 201, 37, 151, 32, 231, 200, 181, 221, 229, 118, 179, 224, 189, 247, 136, 85, 87, 215, + 169, 26, 52, 210, 87, 25, 69, 171, 26, 50, 58, 85, 95, 168, 194, 72, 139, 219, 175, 189, 54, 233, 115, 103, + 145, 115, 187, 223, 231, 99, 230, 140, 25, 203, 54, 110, 220, 248, 29, 7, 187, 50, 101, 139, 94, 21, 96, + 128, 2, 193, 202, 14, 241, 26, 214, 72, 150, 166, 195, 82, 54, 111, 222, 188, 101, 218, 244, 233, 75, 253, + 86, 165, 40, 84, 21, 201, 229, 162, 253, 181, 215, 26, 10, 221, 179, 133, 164, 27, 114, 232, 55, 5, 179, + 39, 91, 51, 146, 101, 230, 39, 51, 103, 224, 64, 34, 7, 14, 228, 196, 78, 64, 169, 173, 165, 232, 164, 147, + 104, 127, 211, 77, 105, 242, 170, 65, 191, 89, 233, 55, 15, 163, 106, 32, 163, 205, 241, 112, 52, 82, 70, + 115, 167, 79, 199, 154, 105, 59, 234, 243, 187, 245, 132, 205, 13, 36, 100, 153, 181, 19, 38, 164, 27, 89, + 55, 70, 72, 146, 132, 39, 20, 98, 234, 43, 175, 176, 113, 222, 60, 130, 152, 91, 137, 104, 215, 205, 164, + 238, 221, 217, 182, 116, 41, 158, 28, 86, 164, 30, 45, 28, 78, 39, 85, 187, 118, 177, 97, 202, 148, 180, + 189, 129, 209, 117, 84, 159, 243, 155, 141, 148, 235, 63, 55, 187, 238, 14, 247, 94, 63, 84, 58, 210, 72, + 143, 148, 45, 122, 165, 2, 39, 222, 119, 31, 14, 143, 7, 85, 177, 94, 194, 227, 242, 122, 217, 241, 205, + 55, 233, 8, 168, 81, 85, 180, 25, 185, 58, 146, 123, 186, 33, 6, 194, 171, 54, 151, 9, 32, 220, 177, 35, + 109, 126, 251, 91, 228, 72, 196, 138, 169, 67, 146, 36, 100, 89, 102, 212, 71, 31, 205, 34, 89, 216, 165, + 237, 121, 162, 61, 195, 145, 54, 31, 249, 65, 161, 64, 176, 140, 97, 244, 144, 160, 175, 38, 140, 1, 241, + 209, 163, 71, 207, 78, 200, 50, 86, 53, 53, 78, 68, 34, 180, 250, 205, 111, 8, 29, 127, 124, 218, 120, 180, + 177, 62, 34, 232, 159, 232, 244, 11, 178, 158, 112, 25, 25, 156, 138, 122, 172, 237, 43, 87, 178, 108, 236, + 88, 220, 41, 159, 41, 171, 71, 34, 18, 161, 99, 231, 206, 248, 90, 183, 78, 175, 16, 164, 254, 91, 182, + 141, 37, 219, 83, 237, 209, 204, 157, 254, 223, 102, 11, 250, 225, 166, 36, 205, 54, 71, 15, 240, 205, 103, + 159, 81, 179, 111, 31, 52, 194, 106, 66, 36, 9, 95, 113, 49, 243, 6, 13, 98, 198, 155, 111, 214, 17, 182, + 27, 189, 250, 128, 232, 190, 125, 140, 184, 239, 62, 42, 182, 109, 203, 217, 181, 115, 180, 195, 229, 247, + 179, 97, 230, 76, 246, 109, 217, 146, 214, 95, 29, 105, 36, 212, 236, 90, 49, 75, 105, 97, 240, 239, 250, + 66, 220, 216, 141, 238, 9, 61, 153, 51, 250, 110, 200, 92, 76, 107, 129, 214, 151, 94, 74, 203, 243, 207, + 39, 94, 83, 147, 147, 249, 118, 120, 60, 124, 217, 191, 63, 209, 202, 202, 12, 51, 212, 250, 166, 2, 143, + 246, 254, 206, 21, 196, 121, 212, 34, 129, 229, 87, 95, 141, 167, 121, 115, 20, 139, 154, 99, 187, 61, 30, + 86, 173, 94, 253, 221, 204, 153, 51, 151, 167, 190, 214, 72, 123, 101, 212, 53, 172, 0, 29, 10, 4, 43, 59, + 196, 235, 89, 79, 178, 98, 0, 179, 102, 205, 90, 177, 122, 213, 170, 239, 60, 22, 165, 93, 212, 68, 2, 111, + 179, 102, 148, 95, 117, 85, 29, 130, 213, 88, 175, 100, 35, 162, 165, 79, 87, 100, 171, 58, 18, 73, 215, + 220, 1, 3, 136, 236, 223, 143, 195, 162, 180, 171, 56, 148, 88, 140, 64, 219, 182, 116, 188, 237, 182, 116, + 20, 75, 255, 236, 108, 180, 145, 28, 42, 138, 100, 229, 188, 25, 17, 35, 179, 239, 49, 251, 76, 191, 233, + 106, 231, 192, 3, 236, 94, 179, 134, 13, 51, 102, 224, 246, 249, 44, 159, 223, 35, 30, 128, 203, 227, 193, + 27, 10, 49, 103, 224, 64, 62, 121, 244, 81, 67, 51, 92, 179, 170, 174, 32, 240, 253, 170, 85, 188, 123, + 243, 205, 236, 221, 184, 17, 127, 81, 81, 78, 174, 159, 163, 249, 251, 228, 120, 156, 229, 195, 135, 31, + 82, 48, 109, 116, 94, 179, 157, 231, 67, 93, 39, 71, 114, 141, 234, 127, 94, 31, 21, 205, 118, 127, 24, 65, + 191, 136, 58, 60, 30, 78, 184, 231, 30, 84, 85, 181, 44, 165, 37, 14, 151, 199, 195, 246, 229, 203, 89, 62, + 114, 100, 154, 164, 155, 137, 215, 205, 52, 86, 141, 13, 170, 240, 170, 237, 9, 9, 192, 29, 10, 81, 126, + 229, 149, 201, 190, 131, 22, 205, 159, 215, 227, 97, 204, 152, 49, 95, 70, 34, 145, 253, 169, 198, 206, + 217, 244, 87, 5, 100, 65, 129, 96, 101, 135, 118, 61, 235, 117, 88, 49, 146, 98, 247, 68, 36, 18, 217, 63, + 102, 204, 152, 47, 173, 170, 38, 4, 144, 163, 81, 202, 174, 188, 18, 119, 40, 148, 97, 52, 34, 222, 100, + 141, 17, 102, 17, 45, 163, 212, 155, 62, 100, 175, 105, 106, 190, 95, 181, 138, 229, 99, 199, 230, 204, + 229, 61, 81, 83, 67, 251, 27, 110, 32, 40, 68, 8, 205, 84, 154, 135, 74, 19, 88, 5, 171, 23, 116, 179, 205, + 80, 219, 84, 150, 14, 29, 138, 146, 72, 28, 243, 94, 126, 78, 151, 11, 95, 56, 140, 219, 235, 101, 223, + 214, 173, 140, 126, 248, 97, 62, 122, 248, 97, 92, 137, 132, 97, 212, 33, 91, 165, 103, 24, 216, 186, 124, + 57, 253, 174, 185, 134, 175, 62, 250, 136, 68, 109, 45, 190, 112, 24, 143, 223, 127, 204, 205, 72, 221, 62, + 31, 219, 190, 250, 138, 205, 211, 167, 167, 211, 131, 70, 81, 159, 92, 92, 7, 86, 254, 174, 250, 70, 86, + 245, 255, 22, 23, 209, 90, 160, 236, 186, 235, 104, 122, 214, 89, 150, 165, 180, 244, 112, 122, 60, 204, + 31, 52, 136, 88, 36, 98, 40, 98, 55, 211, 137, 53, 214, 168, 149, 8, 145, 172, 198, 128, 54, 23, 93, 68, + 248, 71, 63, 66, 137, 197, 44, 249, 253, 78, 167, 147, 61, 123, 246, 68, 198, 141, 27, 55, 55, 245, 81, 54, + 239, 43, 113, 20, 96, 128, 2, 193, 50, 135, 254, 161, 193, 84, 236, 62, 118, 220, 184, 185, 187, 247, 236, + 137, 56, 44, 74, 187, 200, 177, 24, 225, 19, 78, 160, 245, 197, 23, 103, 68, 90, 236, 114, 21, 235, 53, 3, + 102, 41, 67, 145, 104, 105, 79, 152, 94, 96, 222, 192, 129, 212, 28, 56, 144, 147, 138, 66, 37, 145, 192, + 221, 162, 5, 199, 221, 121, 103, 70, 132, 240, 80, 243, 123, 40, 98, 117, 180, 11, 115, 125, 137, 91, 182, + 159, 51, 75, 215, 138, 81, 19, 31, 176, 113, 250, 116, 190, 91, 176, 0, 231, 49, 50, 233, 116, 121, 189, + 120, 195, 97, 42, 118, 239, 102, 214, 160, 65, 244, 187, 225, 6, 94, 251, 253, 239, 153, 53, 104, 80, 218, + 147, 40, 91, 196, 202, 136, 104, 185, 73, 146, 172, 170, 109, 219, 120, 239, 206, 59, 121, 245, 162, 139, + 248, 240, 95, 255, 226, 155, 217, 179, 1, 240, 134, 195, 199, 204, 100, 85, 114, 58, 89, 60, 116, 40, 9, + 69, 169, 179, 193, 139, 58, 169, 108, 168, 207, 245, 97, 229, 3, 64, 182, 235, 60, 219, 245, 103, 68, 174, + 180, 145, 0, 220, 77, 155, 114, 220, 157, 119, 34, 199, 227, 185, 185, 182, 124, 62, 182, 45, 91, 198, 138, + 81, 163, 8, 112, 232, 180, 160, 184, 78, 53, 86, 168, 6, 175, 154, 223, 125, 187, 78, 157, 80, 45, 172, + 192, 244, 249, 253, 76, 155, 62, 125, 233, 186, 117, 235, 54, 115, 144, 199, 233, 35, 88, 133, 232, 85, 61, + 225, 58, 214, 7, 96, 19, 104, 215, 180, 145, 233, 168, 127, 253, 250, 245, 155, 103, 206, 152, 177, 244, + 138, 43, 174, 56, 183, 170, 170, 202, 154, 47, 84, 20, 218, 93, 123, 45, 219, 63, 250, 40, 125, 99, 105, + 139, 128, 67, 247, 239, 198, 10, 145, 176, 56, 72, 222, 145, 70, 79, 190, 34, 193, 81, 128, 157, 171, 86, + 177, 116, 212, 40, 206, 233, 220, 153, 218, 202, 74, 203, 143, 75, 174, 170, 162, 236, 234, 171, 217, 242, + 254, 251, 84, 45, 94, 124, 196, 254, 86, 26, 26, 211, 121, 80, 57, 120, 60, 250, 194, 131, 4, 73, 50, 82, + 173, 170, 44, 24, 48, 128, 118, 191, 248, 69, 234, 127, 202, 70, 45, 173, 131, 219, 235, 197, 225, 118, + 179, 117, 197, 10, 190, 28, 58, 148, 165, 99, 199, 178, 127, 239, 94, 220, 36, 205, 30, 139, 201, 236, 103, + 39, 166, 143, 53, 179, 76, 72, 254, 141, 98, 117, 156, 182, 57, 104, 112, 1, 7, 182, 108, 97, 214, 144, 33, + 204, 25, 50, 132, 182, 63, 249, 9, 231, 254, 245, 175, 156, 113, 217, 101, 132, 154, 55, 39, 86, 93, 141, + 146, 3, 97, 181, 17, 92, 62, 31, 219, 151, 47, 231, 155, 79, 62, 201, 216, 240, 205, 10, 39, 160, 241, 93, + 79, 245, 129, 120, 204, 226, 53, 40, 234, 28, 227, 192, 9, 157, 59, 19, 62, 225, 4, 226, 21, 21, 22, 29, + 97, 38, 28, 78, 39, 95, 246, 235, 71, 60, 18, 73, 91, 51, 24, 117, 75, 208, 12, 131, 237, 68, 176, 196, + 134, 239, 9, 160, 217, 207, 127, 78, 243, 159, 255, 28, 185, 166, 198, 146, 123, 88, 146, 36, 18, 241, 56, + 35, 70, 140, 152, 65, 93, 113, 123, 156, 204, 244, 160, 254, 182, 43, 192, 0, 133, 8, 214, 161, 145, 14, + 126, 96, 236, 137, 21, 3, 226, 31, 14, 31, 62, 35, 97, 97, 218, 69, 137, 70, 105, 126, 206, 57, 52, 61, + 251, 236, 12, 203, 6, 59, 65, 255, 68, 171, 143, 168, 152, 153, 21, 250, 128, 5, 255, 251, 31, 53, 123, + 247, 230, 164, 162, 80, 85, 20, 92, 129, 0, 39, 220, 119, 95, 70, 116, 208, 72, 143, 85, 159, 209, 216, 32, + 30, 155, 94, 11, 231, 34, 73, 102, 214, 140, 31, 207, 230, 121, 243, 112, 55, 128, 73, 167, 195, 233, 196, + 95, 84, 196, 238, 141, 27, 121, 255, 129, 7, 120, 245, 242, 203, 153, 54, 120, 48, 145, 189, 123, 41, 34, + 105, 211, 33, 150, 209, 235, 43, 189, 204, 44, 51, 244, 169, 102, 177, 50, 85, 35, 108, 62, 96, 243, 242, + 229, 12, 123, 248, 97, 94, 187, 244, 82, 102, 167, 220, 223, 189, 185, 108, 52, 46, 192, 233, 114, 177, 96, + 192, 0, 98, 209, 104, 70, 219, 24, 51, 79, 181, 198, 118, 61, 29, 205, 61, 160, 221, 83, 90, 141, 127, 176, + 67, 7, 218, 223, 124, 51, 137, 154, 154, 156, 28, 171, 219, 239, 231, 187, 133, 11, 89, 245, 241, 199, 105, + 237, 149, 120, 173, 100, 51, 10, 109, 236, 208, 214, 126, 49, 149, 210, 174, 83, 39, 28, 62, 95, 82, 203, + 102, 1, 188, 94, 47, 95, 175, 92, 185, 113, 214, 172, 89, 95, 167, 62, 210, 8, 86, 54, 239, 43, 187, 109, + 75, 13, 138, 2, 193, 202, 14, 241, 34, 18, 73, 150, 62, 138, 197, 172, 89, 179, 86, 172, 92, 181, 106, 147, + 199, 34, 45, 150, 170, 40, 56, 253, 126, 218, 254, 229, 47, 117, 174, 106, 187, 93, 209, 122, 146, 37, 106, + 179, 140, 252, 116, 252, 192, 174, 181, 107, 89, 50, 124, 56, 238, 96, 48, 39, 199, 148, 168, 174, 166, + 229, 239, 127, 79, 203, 139, 47, 166, 150, 131, 37, 49, 249, 18, 247, 22, 35, 114, 226, 92, 107, 5, 7, 138, + 170, 50, 171, 87, 47, 84, 69, 201, 169, 22, 203, 19, 8, 32, 39, 18, 140, 127, 233, 37, 94, 189, 252, 114, + 102, 15, 31, 142, 35, 22, 163, 152, 36, 9, 210, 123, 19, 25, 53, 10, 54, 138, 246, 100, 107, 215, 162, 143, + 128, 133, 83, 99, 247, 230, 205, 12, 123, 228, 17, 122, 93, 115, 13, 223, 206, 158, 141, 47, 28, 198, 225, + 202, 93, 16, 223, 29, 8, 176, 121, 254, 124, 86, 124, 244, 17, 1, 225, 111, 208, 119, 5, 200, 167, 69, 88, + 191, 96, 106, 161, 255, 4, 208, 241, 238, 187, 241, 182, 106, 149, 108, 137, 99, 53, 36, 9, 36, 137, 57, + 125, 251, 34, 39, 18, 117, 250, 136, 26, 145, 90, 59, 64, 156, 79, 145, 172, 6, 218, 181, 163, 245, 69, 23, + 37, 163, 87, 22, 193, 237, 118, 243, 209, 71, 31, 205, 142, 197, 98, 7, 76, 156, 219, 69, 253, 85, 1, 245, + 64, 62, 221, 219, 185, 134, 248, 240, 80, 199, 217, 61, 22, 139, 85, 140, 30, 61, 122, 182, 199, 237, 70, + 85, 85, 75, 70, 162, 186, 154, 214, 23, 95, 76, 160, 109, 91, 219, 27, 143, 24, 69, 178, 180, 141, 223, + 200, 57, 221, 15, 44, 24, 56, 144, 138, 237, 219, 147, 218, 25, 139, 230, 52, 61, 82, 213, 75, 199, 221, + 123, 47, 146, 199, 99, 24, 247, 182, 211, 252, 106, 208, 11, 118, 205, 252, 139, 130, 192, 186, 169, 83, + 89, 57, 110, 28, 238, 96, 208, 242, 249, 5, 240, 133, 195, 108, 92, 180, 136, 183, 174, 185, 134, 49, 47, + 189, 68, 162, 178, 50, 29, 85, 202, 230, 246, 175, 111, 91, 98, 230, 17, 230, 162, 174, 215, 154, 222, 99, + 77, 252, 174, 16, 73, 162, 181, 105, 201, 18, 250, 220, 112, 3, 163, 159, 120, 130, 68, 44, 150, 108, 24, + 109, 245, 223, 47, 73, 40, 137, 4, 51, 94, 123, 45, 169, 251, 195, 152, 40, 54, 230, 72, 232, 209, 66, 180, + 18, 104, 114, 246, 217, 148, 254, 233, 79, 36, 170, 170, 172, 191, 151, 85, 21, 183, 207, 199, 134, 217, + 179, 249, 230, 211, 79, 9, 82, 63, 131, 96, 176, 199, 188, 139, 100, 85, 35, 88, 165, 215, 92, 131, 183, + 69, 11, 148, 68, 194, 146, 249, 115, 58, 157, 108, 255, 254, 251, 202, 79, 63, 253, 84, 20, 183, 155, 121, + 95, 217, 245, 89, 191, 193, 81, 32, 88, 135, 134, 254, 250, 54, 178, 107, 72, 138, 221, 199, 142, 157, 251, + 253, 247, 223, 87, 185, 44, 122, 42, 86, 101, 25, 95, 139, 22, 148, 94, 115, 77, 78, 251, 19, 54, 20, 204, + 72, 150, 86, 225, 38, 18, 44, 31, 176, 111, 203, 22, 22, 15, 27, 150, 179, 138, 66, 57, 18, 161, 233, 217, + 103, 83, 214, 169, 19, 181, 228, 215, 170, 97, 68, 176, 244, 17, 67, 23, 48, 253, 229, 151, 169, 222, 189, + 219, 210, 72, 142, 195, 229, 194, 19, 8, 48, 163, 127, 127, 222, 254, 203, 95, 216, 188, 124, 57, 197, 28, + 20, 175, 107, 68, 72, 108, 4, 174, 119, 247, 215, 210, 105, 162, 94, 198, 200, 99, 77, 35, 89, 98, 244, 74, + 108, 224, 43, 54, 26, 23, 35, 90, 110, 89, 102, 242, 128, 1, 244, 249, 203, 95, 216, 185, 102, 13, 190, + 112, 216, 178, 191, 31, 192, 19, 12, 178, 124, 244, 104, 214, 78, 155, 86, 39, 93, 101, 230, 167, 102, 135, + 205, 62, 27, 140, 162, 45, 90, 100, 248, 248, 7, 30, 72, 22, 85, 228, 64, 251, 38, 73, 18, 138, 44, 51, + 251, 173, 183, 144, 200, 110, 201, 96, 39, 50, 171, 234, 222, 107, 205, 177, 61, 69, 69, 148, 95, 125, 117, + 210, 154, 193, 34, 248, 253, 126, 38, 78, 152, 176, 112, 235, 214, 173, 219, 36, 73, 146, 49, 239, 59, 152, + 47, 65, 254, 6, 65, 129, 96, 29, 30, 76, 171, 9, 37, 73, 146, 183, 110, 221, 186, 117, 242, 148, 41, 139, + 124, 22, 234, 90, 228, 218, 90, 202, 174, 186, 10, 119, 56, 156, 190, 194, 53, 232, 163, 21, 118, 27, 70, + 145, 21, 49, 237, 227, 7, 22, 13, 30, 204, 190, 77, 155, 146, 237, 93, 114, 0, 165, 182, 150, 142, 119, + 220, 129, 183, 69, 139, 116, 11, 29, 13, 118, 159, 95, 109, 142, 197, 212, 148, 184, 241, 4, 128, 93, 235, + 214, 49, 171, 87, 47, 203, 72, 172, 230, 18, 63, 234, 145, 71, 24, 249, 228, 147, 16, 137, 80, 68, 166, 54, + 74, 79, 174, 68, 146, 37, 70, 157, 178, 53, 219, 53, 210, 241, 137, 145, 176, 0, 201, 40, 157, 17, 137, + 243, 166, 94, 155, 144, 140, 102, 189, 125, 221, 117, 172, 156, 60, 25, 95, 81, 81, 50, 213, 100, 193, 28, + 28, 216, 178, 133, 105, 61, 123, 154, 246, 186, 51, 35, 90, 249, 48, 52, 168, 164, 172, 4, 174, 190, 154, + 22, 23, 92, 144, 59, 237, 85, 48, 200, 183, 147, 39, 179, 97, 250, 244, 58, 190, 87, 217, 250, 123, 218, + 97, 238, 161, 110, 244, 170, 245, 31, 255, 72, 232, 184, 227, 44, 179, 102, 144, 36, 137, 72, 36, 162, 142, + 250, 232, 163, 25, 36, 247, 54, 189, 184, 189, 96, 46, 122, 132, 40, 16, 172, 250, 161, 190, 81, 44, 121, + 248, 240, 225, 211, 163, 41, 127, 23, 43, 66, 183, 114, 109, 45, 161, 227, 143, 167, 245, 101, 151, 17, 19, + 14, 192, 174, 144, 132, 87, 125, 4, 75, 220, 44, 181, 40, 86, 229, 206, 157, 204, 31, 52, 40, 39, 105, 28, + 109, 126, 253, 29, 58, 208, 254, 206, 59, 147, 39, 16, 251, 139, 12, 180, 57, 22, 55, 19, 35, 237, 146, + 102, 210, 57, 127, 224, 64, 190, 157, 58, 245, 168, 83, 133, 78, 143, 135, 88, 36, 194, 208, 187, 239, 102, + 198, 144, 33, 132, 56, 168, 179, 18, 219, 36, 153, 69, 174, 196, 138, 65, 125, 228, 74, 79, 26, 141, 172, + 63, 204, 218, 50, 101, 251, 190, 34, 32, 178, 103, 15, 131, 110, 191, 157, 5, 169, 158, 134, 42, 71, 126, + 239, 66, 50, 130, 55, 249, 133, 23, 216, 191, 109, 27, 126, 234, 146, 43, 51, 247, 112, 59, 195, 72, 172, + 154, 0, 156, 69, 69, 28, 119, 239, 189, 73, 151, 113, 69, 201, 73, 42, 54, 86, 93, 205, 236, 183, 222, 74, + 71, 51, 179, 249, 94, 217, 101, 174, 141, 162, 87, 50, 201, 130, 145, 182, 215, 95, 143, 18, 143, 91, 54, + 135, 62, 159, 143, 121, 243, 231, 175, 154, 63, 127, 254, 55, 28, 228, 197, 122, 129, 123, 62, 40, 40, 26, + 28, 5, 130, 85, 15, 104, 11, 39, 153, 209, 111, 61, 185, 138, 1, 234, 252, 249, 243, 191, 89, 184, 112, + 225, 106, 159, 207, 103, 221, 247, 203, 50, 109, 175, 191, 30, 201, 225, 176, 189, 22, 11, 234, 146, 44, + 109, 241, 51, 138, 100, 5, 128, 37, 195, 134, 177, 99, 245, 106, 92, 22, 154, 185, 138, 144, 171, 171, 41, + 239, 212, 137, 240, 169, 167, 26, 54, 217, 182, 219, 252, 234, 97, 148, 86, 19, 219, 23, 73, 178, 204, 231, + 79, 60, 65, 245, 206, 157, 71, 220, 167, 208, 233, 241, 16, 143, 68, 24, 114, 199, 29, 44, 157, 48, 129, + 98, 140, 201, 142, 152, 190, 19, 35, 74, 162, 230, 74, 219, 24, 235, 227, 80, 94, 159, 116, 161, 209, 16, + 181, 94, 33, 192, 81, 91, 203, 7, 93, 187, 50, 239, 189, 247, 142, 42, 93, 232, 13, 135, 249, 234, 131, 15, + 88, 54, 106, 20, 33, 140, 35, 87, 118, 113, 15, 63, 18, 136, 4, 43, 6, 180, 187, 237, 54, 66, 167, 156, + 130, 98, 97, 58, 75, 132, 39, 24, 228, 235, 49, 99, 216, 186, 120, 113, 86, 27, 12, 59, 106, 175, 160, 238, + 124, 54, 251, 205, 111, 104, 114, 250, 233, 200, 181, 181, 150, 125, 135, 36, 73, 140, 24, 62, 124, 42, 80, + 163, 19, 183, 39, 168, 171, 191, 42, 224, 48, 80, 32, 88, 135, 15, 81, 232, 87, 71, 236, 14, 84, 143, 28, + 57, 114, 154, 211, 66, 123, 1, 57, 26, 165, 201, 153, 103, 210, 236, 194, 11, 27, 125, 127, 194, 195, 133, + 182, 232, 153, 85, 136, 249, 128, 104, 69, 5, 115, 251, 247, 207, 89, 154, 80, 149, 101, 220, 197, 197, 28, + 255, 192, 3, 166, 125, 32, 236, 54, 215, 226, 70, 34, 18, 17, 177, 109, 145, 72, 98, 119, 174, 91, 199, + 231, 207, 60, 131, 195, 233, 60, 108, 231, 115, 135, 203, 133, 170, 40, 140, 232, 214, 141, 213, 51, 103, + 154, 146, 43, 81, 15, 101, 228, 115, 165, 79, 155, 137, 21, 104, 9, 221, 123, 125, 57, 147, 158, 160, 155, + 53, 26, 215, 71, 177, 180, 116, 100, 0, 240, 170, 42, 31, 61, 254, 56, 203, 62, 249, 36, 153, 46, 60, 76, + 120, 2, 1, 182, 45, 91, 198, 196, 231, 158, 171, 67, 24, 181, 97, 182, 225, 219, 25, 250, 232, 149, 150, + 99, 10, 158, 112, 2, 237, 58, 119, 182, 180, 210, 77, 132, 195, 229, 162, 122, 207, 30, 190, 124, 251, 237, + 67, 58, 182, 219, 105, 174, 141, 162, 129, 218, 181, 222, 238, 198, 27, 145, 156, 78, 203, 188, 235, 60, + 30, 15, 107, 214, 172, 217, 62, 97, 226, 196, 175, 72, 78, 81, 45, 117, 189, 175, 244, 194, 118, 187, 45, + 135, 199, 12, 5, 163, 209, 122, 66, 85, 85, 85, 40, 103, 55, 115, 117, 143, 1, 158, 207, 39, 76, 88, 124, + 239, 250, 245, 187, 202, 203, 203, 91, 198, 172, 200, 147, 171, 42, 146, 211, 73, 187, 78, 157, 216, 247, + 197, 23, 233, 143, 205, 180, 15, 118, 129, 104, 160, 106, 164, 55, 208, 200, 78, 8, 88, 53, 98, 4, 103, 94, + 127, 61, 165, 103, 158, 73, 60, 7, 45, 54, 226, 213, 213, 180, 188, 248, 98, 90, 93, 114, 9, 123, 39, 76, + 192, 77, 221, 185, 181, 219, 28, 139, 228, 67, 127, 141, 104, 243, 171, 173, 156, 197, 192, 178, 143, 63, + 166, 213, 201, 39, 243, 235, 251, 239, 39, 90, 79, 35, 72, 73, 146, 112, 122, 189, 140, 251, 247, 191, 89, + 54, 126, 60, 77, 200, 244, 176, 18, 91, 33, 213, 39, 85, 166, 29, 179, 211, 229, 194, 215, 161, 3, 190, + 147, 78, 194, 215, 161, 3, 174, 22, 45, 112, 248, 253, 168, 137, 4, 74, 77, 13, 241, 239, 191, 39, 186, 97, + 3, 209, 181, 107, 137, 109, 219, 134, 44, 203, 25, 68, 93, 219, 13, 180, 191, 81, 51, 90, 77, 80, 151, 244, + 184, 72, 222, 184, 78, 160, 38, 145, 96, 228, 191, 254, 69, 184, 117, 107, 218, 253, 252, 231, 196, 170, + 171, 235, 53, 15, 46, 143, 135, 234, 125, 251, 248, 184, 91, 55, 98, 7, 14, 164, 73, 166, 190, 29, 148, + 126, 243, 79, 207, 99, 189, 190, 165, 113, 66, 244, 104, 18, 63, 59, 238, 129, 7, 112, 55, 107, 70, 194, + 34, 243, 101, 61, 92, 129, 0, 243, 6, 12, 96, 207, 186, 117, 52, 193, 184, 119, 165, 56, 223, 118, 185, + 143, 197, 249, 212, 142, 53, 1, 52, 57, 243, 76, 154, 159, 119, 30, 137, 72, 196, 50, 134, 227, 241, 122, + 25, 253, 241, 199, 179, 170, 171, 171, 247, 10, 209, 43, 179, 234, 193, 2, 14, 19, 5, 130, 117, 100, 48, + 235, 79, 88, 43, 73, 146, 175, 162, 162, 98, 247, 152, 49, 99, 102, 117, 121, 224, 129, 171, 99, 22, 133, + 114, 229, 154, 26, 90, 252, 250, 215, 20, 157, 126, 58, 53, 203, 150, 101, 156, 56, 187, 44, 28, 102, 208, + 226, 37, 42, 201, 11, 82, 156, 88, 79, 234, 53, 146, 72, 48, 231, 173, 183, 184, 166, 95, 191, 228, 70, + 108, 209, 19, 92, 26, 41, 61, 194, 113, 93, 186, 176, 127, 214, 44, 228, 234, 106, 156, 28, 116, 165, 182, + 227, 28, 107, 132, 69, 79, 172, 180, 8, 161, 70, 62, 52, 34, 27, 4, 166, 246, 236, 73, 243, 142, 29, 57, + 237, 242, 203, 235, 69, 178, 188, 225, 48, 243, 6, 15, 102, 206, 224, 193, 105, 49, 187, 72, 174, 140, 34, + 57, 122, 193, 49, 169, 227, 68, 146, 8, 255, 248, 199, 52, 189, 236, 50, 138, 206, 63, 31, 95, 199, 142, + 56, 67, 33, 112, 56, 64, 146, 146, 141, 129, 83, 126, 71, 40, 10, 170, 44, 35, 31, 56, 64, 116, 195, 6, 42, + 191, 252, 146, 253, 147, 38, 81, 181, 116, 41, 178, 44, 167, 201, 139, 214, 65, 64, 139, 140, 38, 200, 140, + 150, 26, 145, 188, 170, 234, 106, 70, 117, 235, 198, 223, 63, 252, 144, 96, 243, 230, 36, 14, 241, 144, + 228, 72, 69, 20, 198, 61, 242, 8, 223, 127, 253, 117, 218, 145, 94, 191, 209, 139, 30, 88, 118, 218, 240, + 179, 65, 187, 190, 196, 168, 75, 12, 104, 246, 187, 223, 209, 234, 178, 203, 146, 228, 202, 234, 123, 21, + 112, 186, 221, 236, 219, 176, 129, 133, 3, 6, 16, 192, 152, 84, 233, 73, 60, 67, 129, 202, 101, 0, 0, 32, + 0, 73, 68, 65, 84, 216, 111, 174, 197, 141, 166, 237, 95, 255, 138, 211, 231, 179, 140, 176, 58, 157, 78, + 118, 237, 220, 89, 51, 122, 244, 232, 57, 100, 106, 175, 244, 125, 7, 11, 226, 246, 35, 68, 33, 69, 120, + 248, 16, 35, 225, 250, 40, 150, 70, 180, 212, 81, 163, 70, 205, 222, 179, 119, 111, 212, 170, 84, 161, 170, + 40, 56, 131, 65, 202, 110, 188, 177, 78, 73, 135, 93, 145, 45, 141, 101, 36, 198, 94, 59, 113, 34, 107, + 191, 248, 2, 119, 142, 108, 27, 148, 104, 148, 240, 143, 127, 76, 217, 45, 183, 100, 152, 143, 218, 121, + 142, 53, 232, 83, 177, 250, 138, 77, 173, 10, 207, 37, 203, 124, 242, 208, 67, 108, 156, 55, 15, 111, 40, + 148, 245, 119, 186, 253, 126, 182, 46, 89, 194, 132, 231, 159, 175, 35, 84, 23, 61, 169, 244, 169, 64, 49, + 170, 160, 2, 56, 28, 52, 251, 237, 111, 57, 233, 189, 247, 56, 121, 212, 40, 74, 238, 189, 151, 192, 41, + 167, 32, 57, 157, 200, 213, 213, 200, 149, 149, 200, 21, 21, 200, 85, 85, 25, 239, 149, 104, 20, 135, 223, + 79, 240, 140, 51, 40, 185, 239, 62, 78, 26, 62, 156, 83, 70, 140, 160, 228, 198, 27, 113, 166, 170, 110, + 37, 14, 237, 252, 174, 63, 206, 16, 176, 123, 195, 6, 62, 123, 250, 105, 36, 167, 51, 171, 17, 171, 228, + 112, 224, 242, 249, 152, 208, 189, 59, 43, 198, 143, 207, 104, 207, 98, 180, 225, 219, 73, 104, 125, 40, + 232, 109, 25, 180, 197, 80, 242, 249, 56, 174, 75, 151, 228, 188, 229, 128, 92, 1, 184, 252, 126, 230, 15, + 24, 64, 213, 238, 221, 117, 26, 131, 103, 211, 186, 53, 118, 232, 29, 219, 211, 46, 248, 39, 156, 64, 171, + 75, 46, 177, 180, 65, 182, 223, 239, 103, 210, 164, 73, 243, 191, 251, 238, 187, 45, 28, 148, 121, 25, 89, + 51, 228, 147, 36, 181, 65, 81, 32, 88, 135, 1, 245, 96, 216, 196, 140, 100, 105, 79, 0, 202, 134, 13, 27, + 54, 77, 153, 50, 101, 161, 207, 239, 207, 72, 92, 31, 205, 72, 212, 212, 208, 234, 146, 75, 8, 116, 232, + 144, 182, 20, 16, 171, 10, 237, 124, 229, 139, 213, 97, 102, 77, 161, 157, 192, 156, 94, 189, 136, 69, 34, + 224, 112, 88, 54, 175, 25, 115, 28, 137, 208, 246, 239, 127, 39, 112, 220, 113, 134, 122, 55, 187, 205, + 177, 81, 213, 166, 81, 155, 34, 45, 210, 228, 7, 226, 7, 14, 48, 226, 158, 123, 248, 126, 213, 42, 60, 193, + 160, 225, 60, 225, 112, 144, 136, 197, 24, 255, 236, 179, 196, 171, 170, 234, 184, 178, 235, 137, 149, 168, + 179, 210, 22, 29, 25, 40, 58, 251, 108, 78, 122, 239, 61, 142, 127, 231, 29, 138, 206, 63, 31, 85, 81, 72, + 84, 86, 34, 215, 214, 162, 28, 170, 137, 173, 170, 162, 200, 50, 114, 52, 74, 162, 178, 18, 53, 145, 32, + 112, 230, 153, 180, 123, 225, 5, 78, 25, 51, 134, 146, 191, 253, 13, 135, 223, 159, 172, 190, 18, 254, 110, + 61, 201, 210, 31, 179, 135, 100, 117, 225, 138, 79, 63, 229, 171, 17, 35, 112, 107, 149, 133, 250, 57, 144, + 36, 60, 193, 32, 211, 95, 127, 157, 47, 255, 247, 191, 122, 145, 43, 59, 53, 25, 174, 47, 244, 66, 236, + 178, 219, 110, 35, 252, 211, 159, 166, 83, 89, 86, 15, 167, 207, 199, 214, 37, 75, 88, 58, 108, 88, 218, + 33, 191, 62, 194, 246, 198, 14, 253, 230, 162, 205, 105, 2, 40, 237, 212, 9, 87, 147, 38, 201, 106, 76, + 142, 126, 14, 37, 135, 131, 154, 72, 68, 121, 255, 131, 15, 166, 1, 9, 73, 146, 52, 237, 149, 190, 177, + 179, 222, 29, 168, 128, 195, 64, 129, 96, 29, 25, 180, 107, 223, 176, 117, 78, 170, 63, 97, 226, 131, 15, + 62, 152, 86, 27, 141, 38, 111, 112, 85, 61, 234, 161, 38, 18, 120, 154, 55, 167, 228, 250, 235, 235, 88, + 10, 228, 3, 1, 48, 170, 10, 211, 87, 20, 110, 93, 188, 152, 175, 71, 143, 78, 250, 54, 89, 48, 167, 117, + 230, 56, 30, 199, 211, 188, 57, 237, 31, 120, 160, 206, 35, 156, 6, 187, 205, 177, 6, 163, 249, 21, 109, + 49, 52, 82, 16, 4, 170, 182, 111, 103, 232, 173, 183, 178, 99, 245, 106, 188, 193, 96, 157, 121, 242, 4, 2, + 44, 26, 54, 140, 13, 115, 231, 18, 198, 184, 31, 160, 190, 221, 141, 182, 233, 41, 128, 179, 73, 19, 58, + 60, 253, 52, 63, 26, 54, 140, 162, 243, 206, 67, 169, 169, 65, 174, 174, 78, 59, 236, 31, 209, 185, 83, 20, + 148, 72, 4, 185, 162, 2, 111, 219, 182, 180, 123, 254, 121, 78, 25, 57, 146, 166, 23, 92, 144, 110, 148, + 155, 205, 5, 94, 79, 182, 124, 192, 180, 87, 94, 97, 255, 119, 223, 225, 116, 185, 50, 190, 75, 74, 145, + 171, 105, 175, 191, 206, 228, 151, 95, 206, 32, 152, 70, 154, 51, 59, 87, 178, 25, 65, 79, 6, 100, 146, 11, + 160, 255, 132, 19, 104, 123, 251, 237, 7, 27, 16, 91, 61, 72, 206, 219, 156, 55, 223, 68, 174, 173, 53, + 245, 25, 211, 123, 94, 129, 125, 230, 91, 36, 87, 113, 192, 91, 90, 74, 155, 43, 174, 176, 116, 78, 125, + 94, 47, 95, 206, 153, 179, 98, 241, 226, 197, 223, 166, 190, 78, 172, 134, 55, 139, 96, 217, 117, 233, 59, + 102, 40, 16, 172, 195, 132, 46, 138, 101, 216, 58, 135, 100, 37, 134, 58, 111, 222, 188, 85, 243, 231, 207, + 95, 233, 183, 208, 120, 84, 137, 70, 41, 185, 234, 42, 188, 173, 90, 213, 169, 164, 58, 86, 102, 120, 86, + 13, 35, 19, 73, 125, 68, 192, 11, 204, 125, 251, 109, 170, 118, 237, 202, 89, 31, 185, 68, 117, 53, 173, + 254, 248, 71, 154, 95, 116, 81, 218, 123, 44, 253, 228, 103, 227, 161, 159, 95, 49, 58, 168, 143, 56, 133, + 128, 138, 45, 91, 24, 118, 219, 109, 236, 88, 181, 42, 35, 93, 232, 116, 187, 217, 191, 101, 11, 95, 190, + 253, 54, 65, 204, 201, 149, 190, 221, 141, 68, 242, 70, 41, 62, 231, 28, 78, 25, 57, 146, 54, 127, 255, 59, + 40, 10, 114, 117, 117, 122, 243, 180, 10, 74, 44, 134, 92, 81, 129, 255, 212, 83, 57, 241, 157, 119, 232, + 248, 220, 115, 56, 139, 138, 50, 244, 88, 70, 41, 67, 205, 54, 66, 35, 154, 21, 219, 183, 51, 183, 127, + 127, 92, 130, 237, 138, 195, 233, 196, 19, 12, 50, 227, 141, 55, 152, 220, 179, 103, 29, 167, 120, 51, 114, + 153, 47, 198, 162, 8, 175, 226, 189, 33, 3, 29, 187, 117, 195, 211, 188, 121, 110, 250, 13, 146, 172, 212, + 92, 55, 117, 42, 107, 62, 255, 156, 32, 230, 77, 193, 245, 209, 66, 187, 12, 13, 218, 230, 146, 0, 74, 174, + 185, 6, 95, 73, 137, 101, 115, 42, 73, 18, 170, 170, 50, 108, 216, 176, 41, 64, 52, 21, 16, 200, 70, 174, + 10, 56, 66, 20, 8, 214, 209, 65, 188, 15, 50, 170, 9, 83, 21, 25, 53, 239, 127, 240, 193, 23, 72, 146, 101, + 225, 113, 57, 30, 199, 87, 94, 78, 155, 63, 253, 137, 56, 249, 113, 245, 139, 139, 182, 222, 120, 212, 200, + 221, 125, 239, 166, 77, 44, 26, 52, 8, 119, 32, 144, 147, 20, 132, 154, 122, 202, 235, 208, 173, 27, 142, + 80, 40, 131, 200, 138, 236, 218, 46, 16, 23, 238, 108, 36, 86, 223, 108, 57, 4, 28, 248, 238, 59, 222, 251, + 219, 223, 216, 180, 96, 1, 222, 162, 162, 116, 138, 102, 241, 144, 33, 84, 238, 216, 145, 22, 24, 235, 163, + 86, 90, 171, 27, 141, 84, 104, 55, 74, 201, 237, 183, 115, 226, 187, 239, 226, 61, 238, 56, 226, 7, 14, 28, + 58, 13, 120, 148, 67, 142, 68, 80, 106, 107, 105, 117, 203, 45, 156, 244, 225, 135, 4, 78, 59, 45, 169, 19, + 34, 147, 104, 137, 228, 82, 36, 89, 33, 96, 249, 240, 225, 236, 92, 189, 26, 135, 199, 131, 195, 237, 198, + 233, 245, 50, 169, 123, 119, 38, 233, 200, 149, 254, 239, 207, 215, 232, 149, 8, 237, 188, 214, 2, 45, 46, + 187, 140, 22, 127, 248, 3, 241, 170, 170, 156, 156, 75, 156, 78, 98, 53, 53, 204, 122, 237, 53, 156, 24, + 87, 166, 26, 9, 219, 161, 241, 207, 183, 170, 123, 175, 109, 42, 238, 166, 77, 41, 185, 246, 90, 100, 11, + 211, 173, 30, 175, 151, 229, 43, 86, 108, 250, 98, 234, 212, 165, 169, 175, 212, 27, 139, 214, 137, 94, + 169, 150, 87, 21, 253, 48, 80, 32, 88, 71, 14, 237, 122, 21, 163, 88, 162, 14, 171, 22, 144, 38, 79, 158, + 188, 120, 213, 202, 149, 91, 189, 30, 15, 86, 133, 119, 149, 104, 148, 210, 235, 174, 195, 85, 84, 100, + 248, 168, 97, 231, 59, 65, 31, 105, 209, 107, 177, 52, 193, 251, 162, 65, 131, 216, 185, 122, 53, 46, 11, + 231, 85, 28, 114, 36, 66, 232, 180, 211, 40, 251, 199, 63, 12, 205, 71, 237, 6, 73, 247, 222, 44, 85, 168, + 215, 37, 133, 129, 154, 29, 59, 248, 160, 115, 103, 86, 142, 25, 67, 160, 89, 51, 14, 108, 217, 194, 138, + 225, 195, 9, 9, 63, 103, 84, 49, 39, 166, 4, 241, 249, 232, 208, 163, 7, 109, 159, 120, 34, 121, 13, 71, + 34, 57, 57, 111, 102, 169, 195, 196, 129, 3, 4, 78, 62, 153, 147, 134, 12, 161, 217, 197, 23, 163, 197, 2, + 204, 186, 8, 136, 100, 43, 94, 85, 197, 87, 67, 135, 226, 11, 135, 145, 99, 49, 198, 116, 237, 202, 204, + 62, 125, 8, 82, 215, 180, 212, 44, 45, 170, 223, 240, 237, 10, 113, 141, 17, 29, 151, 157, 77, 154, 208, + 190, 107, 87, 84, 89, 78, 86, 123, 230, 224, 60, 122, 252, 126, 150, 126, 248, 33, 219, 150, 45, 171, 211, + 18, 199, 104, 190, 27, 59, 169, 50, 130, 94, 220, 222, 234, 234, 171, 9, 180, 111, 159, 108, 139, 99, 209, + 60, 186, 93, 46, 134, 15, 31, 62, 53, 30, 143, 87, 28, 34, 122, 85, 136, 96, 29, 37, 242, 225, 158, 111, + 112, 24, 164, 9, 77, 163, 88, 145, 72, 100, 255, 136, 145, 35, 167, 121, 142, 208, 33, 219, 8, 74, 44, 70, + 240, 248, 227, 105, 121, 197, 21, 233, 205, 223, 238, 119, 130, 248, 100, 175, 13, 179, 138, 66, 47, 80, + 91, 81, 193, 151, 189, 123, 227, 200, 145, 249, 40, 36, 29, 222, 203, 58, 119, 38, 120, 218, 105, 121, 229, + 240, 46, 206, 175, 158, 92, 136, 209, 44, 177, 57, 178, 82, 81, 193, 39, 247, 222, 203, 130, 190, 125, 249, + 230, 147, 79, 168, 221, 181, 43, 221, 188, 217, 140, 88, 104, 41, 65, 103, 211, 166, 156, 208, 183, 47, + 173, 110, 188, 17, 185, 170, 42, 185, 9, 31, 3, 200, 53, 53, 56, 67, 33, 142, 239, 221, 155, 150, 127, 254, + 51, 241, 212, 231, 122, 50, 175, 23, 231, 135, 128, 141, 227, 199, 179, 113, 198, 12, 70, 223, 126, 59, 75, + 63, 250, 136, 48, 153, 46, 244, 217, 252, 174, 242, 209, 181, 93, 124, 186, 140, 1, 109, 239, 185, 135, + 224, 143, 126, 132, 98, 161, 195, 184, 8, 167, 219, 205, 129, 45, 91, 152, 247, 246, 219, 233, 246, 67, + 245, 209, 185, 65, 227, 159, 111, 253, 122, 162, 146, 34, 173, 161, 16, 101, 157, 58, 89, 58, 167, 30, 183, + 155, 13, 27, 54, 236, 30, 55, 118, 236, 188, 212, 71, 90, 48, 192, 200, 92, 180, 16, 189, 58, 74, 20, 8, + 214, 209, 161, 62, 81, 44, 198, 140, 25, 243, 229, 150, 45, 91, 246, 187, 45, 36, 3, 74, 60, 78, 89, 167, + 78, 56, 188, 222, 116, 69, 97, 190, 70, 177, 244, 154, 25, 45, 138, 181, 234, 227, 143, 217, 48, 115, 102, + 206, 108, 27, 84, 89, 198, 21, 14, 211, 225, 161, 135, 80, 36, 169, 142, 230, 13, 236, 53, 207, 250, 84, + 161, 54, 207, 102, 109, 102, 196, 215, 32, 224, 83, 20, 166, 63, 243, 12, 139, 94, 123, 45, 67, 216, 110, + 102, 69, 160, 0, 174, 214, 173, 57, 113, 192, 0, 154, 252, 230, 55, 36, 42, 42, 176, 90, 107, 117, 184, 80, + 98, 49, 84, 85, 165, 67, 143, 30, 180, 252, 243, 159, 51, 34, 89, 122, 93, 154, 246, 247, 5, 0, 121, 215, + 46, 62, 249, 219, 223, 216, 58, 103, 14, 77, 200, 180, 118, 48, 211, 156, 217, 89, 104, 109, 4, 113, 109, + 17, 201, 85, 209, 217, 103, 83, 114, 211, 77, 200, 57, 50, 20, 133, 100, 90, 122, 110, 223, 190, 84, 236, + 216, 145, 97, 203, 144, 173, 153, 51, 216, 107, 190, 197, 141, 36, 6, 180, 184, 252, 242, 36, 105, 181, + 168, 169, 51, 128, 215, 231, 227, 163, 209, 163, 103, 236, 219, 191, 127, 167, 36, 73, 9, 14, 146, 43, 141, + 96, 137, 149, 131, 118, 90, 222, 26, 37, 10, 4, 235, 8, 97, 34, 118, 175, 211, 0, 90, 146, 36, 121, 215, + 174, 93, 223, 127, 50, 102, 204, 44, 175, 215, 139, 101, 77, 138, 163, 81, 66, 167, 158, 74, 243, 75, 47, + 205, 155, 246, 57, 217, 180, 88, 122, 203, 6, 47, 224, 80, 85, 102, 189, 246, 26, 137, 104, 20, 82, 194, + 77, 171, 71, 162, 170, 138, 166, 23, 92, 64, 171, 235, 174, 203, 139, 104, 161, 153, 30, 75, 156, 103, 35, + 159, 40, 173, 205, 76, 80, 150, 113, 71, 163, 25, 130, 118, 49, 146, 160, 253, 78, 141, 92, 253, 168, 127, + 127, 66, 103, 159, 77, 162, 162, 34, 39, 231, 231, 72, 134, 18, 139, 161, 42, 10, 29, 158, 127, 158, 166, + 191, 251, 29, 113, 50, 211, 166, 122, 251, 10, 31, 73, 114, 233, 142, 68, 210, 145, 43, 113, 110, 204, 136, + 166, 221, 26, 12, 215, 23, 218, 130, 151, 0, 240, 120, 104, 255, 240, 195, 56, 60, 158, 164, 133, 64, 14, + 206, 151, 203, 231, 99, 203, 194, 133, 44, 27, 54, 172, 78, 106, 80, 211, 250, 217, 125, 190, 245, 79, 234, + 14, 159, 143, 242, 155, 110, 74, 63, 16, 88, 49, 156, 78, 39, 59, 118, 236, 168, 26, 49, 98, 196, 204, 212, + 215, 102, 35, 87, 118, 94, 230, 26, 13, 10, 4, 235, 232, 33, 166, 9, 141, 170, 9, 107, 1, 117, 248, 240, + 225, 51, 246, 90, 104, 60, 10, 128, 162, 80, 126, 211, 77, 72, 46, 87, 29, 83, 76, 163, 148, 155, 157, 134, + 168, 91, 49, 74, 99, 105, 81, 172, 173, 11, 23, 178, 124, 212, 40, 60, 193, 224, 209, 205, 101, 22, 168, + 181, 181, 180, 251, 231, 63, 241, 150, 150, 102, 248, 143, 129, 61, 231, 217, 161, 123, 111, 84, 85, 151, + 173, 65, 179, 246, 94, 212, 94, 105, 81, 27, 209, 134, 225, 132, 55, 223, 36, 120, 198, 25, 200, 149, 149, + 135, 63, 233, 57, 134, 26, 143, 35, 57, 28, 116, 252, 239, 127, 9, 156, 120, 98, 218, 148, 84, 63, 23, 34, + 145, 210, 52, 87, 70, 61, 13, 179, 105, 175, 140, 230, 221, 110, 3, 225, 85, 140, 94, 149, 220, 122, 43, + 77, 126, 241, 139, 156, 245, 27, 148, 36, 9, 69, 150, 153, 245, 234, 171, 168, 241, 184, 161, 222, 207, + 172, 237, 146, 29, 230, 27, 225, 85, 155, 215, 56, 208, 226, 255, 254, 143, 208, 169, 167, 90, 154, 30, + 244, 251, 253, 124, 246, 217, 103, 115, 183, 110, 221, 186, 85, 146, 36, 45, 80, 166, 111, 139, 147, 225, + 123, 85, 72, 15, 30, 29, 10, 4, 235, 40, 144, 37, 138, 149, 145, 38, 148, 36, 73, 94, 191, 126, 253, 198, + 137, 147, 38, 205, 183, 210, 178, 65, 142, 70, 41, 58, 227, 12, 154, 93, 124, 113, 218, 23, 43, 95, 162, + 88, 80, 151, 100, 233, 163, 88, 90, 180, 101, 110, 239, 222, 84, 108, 219, 150, 179, 102, 208, 74, 60, 142, + 183, 172, 140, 118, 221, 186, 213, 17, 40, 104, 176, 235, 156, 235, 137, 150, 222, 140, 83, 140, 84, 233, + 155, 36, 107, 164, 66, 212, 92, 169, 0, 94, 47, 199, 191, 242, 10, 225, 115, 206, 105, 148, 228, 74, 131, + 82, 91, 139, 187, 101, 75, 58, 118, 239, 142, 228, 245, 166, 207, 161, 118, 189, 153, 53, 140, 54, 19, 182, + 103, 139, 164, 136, 239, 237, 6, 35, 193, 105, 28, 8, 156, 116, 18, 229, 119, 220, 97, 169, 187, 184, 30, + 158, 80, 136, 149, 99, 199, 178, 113, 230, 76, 2, 152, 107, 175, 236, 24, 189, 50, 74, 185, 202, 0, 110, + 55, 101, 55, 223, 108, 169, 86, 209, 225, 112, 112, 160, 162, 34, 54, 116, 216, 176, 47, 82, 95, 163, 61, + 252, 103, 243, 189, 42, 224, 40, 81, 32, 88, 214, 33, 27, 201, 138, 1, 242, 208, 161, 67, 191, 136, 68, 34, + 178, 195, 97, 209, 180, 167, 248, 93, 217, 45, 183, 160, 74, 82, 94, 24, 143, 66, 230, 147, 157, 184, 241, + 27, 181, 120, 241, 3, 7, 182, 111, 103, 110, 159, 62, 25, 94, 69, 86, 67, 174, 170, 162, 229, 85, 87, 209, + 236, 15, 127, 200, 219, 170, 66, 189, 61, 134, 70, 46, 252, 186, 161, 39, 87, 46, 225, 247, 41, 64, 135, + 255, 252, 135, 166, 23, 93, 212, 168, 201, 149, 6, 185, 186, 154, 162, 115, 207, 165, 213, 173, 183, 166, + 69, 239, 218, 124, 232, 137, 166, 217, 60, 152, 165, 5, 237, 180, 217, 155, 65, 255, 16, 161, 165, 6, 101, + 73, 162, 195, 163, 143, 226, 106, 210, 36, 103, 158, 87, 14, 183, 155, 170, 157, 59, 153, 243, 198, 27, + 117, 162, 86, 70, 228, 202, 238, 218, 43, 45, 42, 216, 226, 242, 203, 41, 58, 227, 12, 148, 104, 212, 178, + 239, 8, 4, 2, 76, 158, 52, 105, 225, 55, 223, 124, 179, 158, 131, 206, 26, 89, 141, 69, 11, 209, 171, 163, + 71, 129, 96, 29, 37, 82, 23, 161, 254, 33, 68, 95, 81, 88, 11, 168, 75, 151, 46, 253, 118, 198, 140, 25, + 75, 173, 142, 98, 21, 159, 117, 86, 90, 75, 146, 111, 201, 115, 113, 243, 215, 139, 144, 181, 17, 2, 150, + 189, 255, 62, 91, 22, 46, 196, 109, 225, 220, 102, 64, 85, 65, 81, 232, 240, 224, 131, 56, 155, 54, 53, 20, + 188, 219, 13, 250, 52, 133, 81, 180, 208, 168, 119, 159, 62, 37, 166, 109, 108, 50, 208, 166, 115, 103, 90, + 221, 120, 99, 82, 208, 110, 19, 200, 53, 53, 148, 222, 122, 43, 254, 242, 242, 116, 110, 36, 155, 25, 105, + 125, 44, 25, 196, 121, 181, 211, 102, 111, 6, 189, 176, 189, 245, 95, 255, 74, 211, 11, 47, 76, 154, 196, + 230, 8, 238, 148, 176, 125, 223, 166, 77, 233, 138, 85, 163, 212, 160, 62, 122, 101, 167, 249, 174, 19, + 189, 114, 58, 41, 189, 241, 198, 164, 213, 133, 69, 112, 56, 28, 68, 163, 81, 117, 104, 210, 88, 52, 110, + 210, 22, 167, 96, 46, 154, 3, 20, 8, 150, 117, 48, 210, 98, 137, 105, 194, 90, 160, 118, 200, 144, 33, 147, + 19, 137, 68, 214, 6, 178, 135, 247, 173, 42, 146, 195, 65, 121, 231, 206, 117, 42, 9, 161, 238, 66, 111, + 151, 33, 234, 40, 140, 132, 216, 250, 38, 197, 106, 44, 198, 204, 87, 94, 65, 145, 101, 36, 171, 34, 132, + 58, 40, 181, 181, 4, 78, 56, 129, 182, 93, 187, 166, 87, 35, 109, 129, 212, 71, 132, 236, 56, 204, 170, 54, + 245, 182, 13, 250, 106, 57, 237, 92, 169, 64, 232, 204, 51, 147, 147, 96, 163, 135, 95, 85, 150, 113, 21, + 23, 227, 108, 217, 18, 133, 204, 185, 208, 167, 10, 141, 26, 87, 235, 55, 123, 253, 53, 108, 215, 129, 240, + 42, 70, 175, 252, 199, 29, 71, 187, 127, 254, 51, 103, 150, 12, 144, 106, 36, 190, 104, 17, 75, 222, 125, + 55, 237, 183, 102, 20, 193, 210, 55, 117, 182, 203, 64, 120, 213, 214, 144, 24, 208, 236, 226, 139, 41, 62, + 235, 44, 100, 11, 163, 87, 126, 191, 159, 153, 51, 103, 46, 89, 184, 112, 225, 42, 225, 171, 14, 213, 22, + 167, 0, 11, 80, 32, 88, 214, 65, 187, 48, 205, 26, 64, 215, 2, 204, 152, 57, 115, 249, 188, 249, 243, 87, + 250, 44, 76, 103, 201, 145, 8, 77, 206, 61, 151, 166, 191, 251, 93, 94, 84, 186, 233, 97, 182, 249, 235, + 205, 71, 55, 206, 158, 157, 115, 193, 123, 162, 186, 154, 54, 215, 95, 79, 241, 5, 23, 228, 165, 238, 77, + 155, 235, 108, 243, 109, 148, 14, 211, 188, 123, 246, 205, 159, 159, 241, 251, 236, 0, 201, 233, 36, 182, + 103, 15, 213, 91, 182, 100, 220, 55, 102, 102, 183, 226, 191, 205, 140, 45, 237, 54, 7, 122, 232, 83, 131, + 218, 194, 150, 0, 218, 63, 242, 8, 238, 22, 45, 80, 227, 113, 195, 255, 247, 104, 33, 57, 28, 40, 137, 4, + 211, 95, 122, 9, 53, 22, 75, 147, 217, 250, 152, 138, 218, 97, 222, 141, 180, 87, 9, 128, 212, 131, 114, + 218, 20, 212, 2, 72, 146, 68, 34, 145, 96, 240, 187, 239, 78, 230, 96, 159, 92, 77, 127, 37, 70, 175, 50, + 182, 141, 66, 122, 208, 26, 20, 8, 150, 5, 48, 17, 187, 235, 163, 88, 177, 84, 20, 171, 102, 200, 144, 33, + 83, 36, 73, 178, 54, 138, 37, 73, 148, 223, 122, 107, 122, 33, 204, 55, 45, 150, 54, 196, 13, 79, 223, 171, + 208, 7, 124, 249, 230, 155, 28, 216, 186, 21, 167, 133, 198, 174, 25, 80, 20, 112, 56, 104, 255, 232, 163, + 56, 194, 225, 140, 149, 73, 131, 157, 231, 90, 123, 111, 20, 57, 52, 107, 71, 34, 230, 200, 247, 46, 88, + 64, 162, 162, 34, 103, 81, 196, 92, 192, 225, 118, 83, 189, 110, 29, 213, 187, 118, 213, 33, 203, 122, 162, + 169, 247, 93, 178, 123, 138, 234, 80, 16, 23, 180, 90, 160, 213, 13, 55, 208, 236, 162, 139, 114, 154, 26, + 244, 4, 131, 44, 27, 57, 146, 77, 115, 230, 212, 177, 101, 200, 214, 204, 217, 110, 208, 23, 13, 52, 251, + 195, 31, 40, 62, 251, 108, 203, 163, 87, 243, 230, 205, 91, 53, 115, 230, 204, 101, 169, 175, 212, 155, + 138, 138, 246, 12, 118, 127, 86, 108, 116, 176, 207, 42, 104, 15, 232, 31, 74, 244, 150, 13, 49, 128, 73, + 147, 38, 45, 94, 178, 100, 201, 122, 175, 215, 107, 217, 23, 203, 145, 8, 197, 231, 158, 75, 147, 223, 255, + 62, 175, 163, 88, 70, 205, 138, 69, 193, 123, 197, 182, 109, 204, 233, 221, 59, 217, 66, 39, 71, 80, 82, + 30, 100, 109, 187, 116, 73, 175, 78, 218, 73, 215, 96, 199, 121, 55, 35, 89, 250, 121, 55, 170, 216, 210, + 174, 181, 189, 223, 124, 195, 254, 21, 43, 112, 88, 120, 109, 231, 26, 14, 183, 155, 157, 95, 126, 73, 45, + 153, 247, 141, 81, 234, 84, 47, 170, 206, 183, 200, 21, 152, 87, 13, 250, 143, 59, 142, 118, 93, 187, 30, + 108, 219, 146, 3, 56, 61, 30, 246, 127, 247, 29, 115, 94, 127, 61, 109, 40, 42, 70, 174, 236, 222, 223, + 209, 104, 110, 19, 0, 110, 55, 229, 183, 221, 102, 121, 244, 74, 85, 85, 6, 191, 251, 238, 68, 32, 162, + 139, 94, 233, 189, 175, 210, 228, 170, 16, 189, 178, 14, 5, 130, 101, 17, 12, 162, 88, 34, 201, 18, 181, + 88, 241, 68, 34, 81, 249, 222, 144, 33, 147, 45, 245, 196, 74, 69, 177, 202, 82, 90, 172, 124, 245, 197, + 50, 171, 38, 212, 70, 16, 88, 241, 254, 251, 108, 152, 53, 11, 79, 142, 28, 222, 33, 89, 85, 216, 250, 198, + 27, 211, 169, 66, 49, 98, 168, 95, 244, 237, 56, 180, 99, 215, 147, 44, 253, 48, 210, 145, 108, 30, 51, 6, + 135, 203, 117, 68, 243, 218, 208, 144, 28, 14, 226, 149, 149, 108, 157, 58, 21, 200, 124, 40, 209, 254, + 126, 51, 178, 105, 36, 102, 183, 251, 64, 120, 213, 107, 30, 218, 63, 254, 120, 78, 83, 131, 72, 18, 78, + 183, 155, 217, 111, 188, 65, 213, 206, 157, 25, 77, 183, 69, 146, 101, 68, 244, 237, 48, 208, 189, 23, 125, + 175, 154, 95, 126, 57, 69, 63, 251, 153, 165, 150, 23, 62, 159, 143, 175, 190, 250, 106, 237, 148, 41, 83, + 150, 164, 62, 50, 19, 183, 231, 219, 243, 120, 163, 65, 129, 96, 89, 15, 125, 154, 80, 95, 77, 88, 11, 240, + 217, 103, 159, 205, 95, 181, 106, 213, 22, 171, 163, 88, 154, 22, 75, 51, 196, 212, 112, 172, 23, 151, 35, + 29, 226, 70, 46, 46, 172, 98, 95, 66, 81, 132, 236, 7, 28, 138, 194, 140, 23, 95, 36, 86, 83, 131, 195, 74, + 18, 43, 64, 85, 20, 36, 167, 147, 14, 143, 61, 134, 171, 73, 19, 68, 199, 154, 99, 61, 103, 86, 204, 183, + 62, 5, 99, 70, 174, 244, 27, 134, 3, 216, 248, 233, 167, 28, 88, 187, 54, 119, 105, 90, 11, 225, 244, 249, + 216, 185, 112, 33, 123, 86, 174, 76, 47, 134, 250, 57, 209, 71, 172, 140, 140, 90, 237, 40, 180, 62, 212, + 128, 228, 57, 141, 147, 172, 14, 109, 250, 251, 223, 231, 180, 29, 142, 39, 24, 100, 221, 23, 95, 176, 114, + 248, 240, 116, 43, 38, 143, 238, 85, 79, 178, 236, 100, 42, 42, 206, 171, 6, 5, 144, 52, 223, 43, 11, 237, + 46, 52, 9, 202, 160, 65, 131, 38, 202, 178, 92, 101, 18, 189, 42, 104, 175, 114, 140, 2, 193, 178, 16, 135, + 97, 60, 26, 143, 70, 163, 251, 223, 27, 50, 100, 146, 149, 253, 9, 211, 81, 172, 91, 111, 77, 127, 121, + 190, 149, 133, 136, 155, 125, 54, 135, 247, 237, 203, 150, 177, 232, 221, 119, 113, 231, 80, 240, 174, 68, + 163, 4, 79, 57, 133, 114, 193, 128, 52, 31, 82, 133, 122, 152, 109, 16, 226, 38, 172, 189, 74, 64, 85, 69, + 5, 43, 223, 125, 23, 103, 99, 79, 19, 74, 18, 168, 42, 171, 222, 123, 47, 195, 161, 255, 112, 170, 112, + 243, 9, 70, 33, 248, 24, 16, 56, 229, 20, 202, 238, 191, 31, 37, 135, 134, 162, 14, 151, 139, 232, 254, + 253, 76, 239, 217, 19, 7, 153, 81, 105, 109, 136, 85, 154, 249, 162, 189, 138, 1, 45, 174, 184, 130, 176, + 197, 190, 87, 94, 175, 151, 21, 43, 86, 108, 156, 48, 113, 226, 34, 14, 106, 175, 140, 154, 58, 103, 56, + 183, 23, 96, 45, 10, 4, 43, 119, 48, 35, 89, 218, 133, 46, 141, 249, 228, 147, 185, 107, 214, 172, 217, + 110, 121, 20, 235, 151, 191, 164, 217, 165, 151, 26, 106, 177, 236, 186, 225, 139, 27, 221, 161, 180, 88, + 110, 146, 173, 76, 230, 247, 233, 195, 206, 175, 191, 206, 169, 1, 105, 162, 170, 138, 86, 157, 58, 209, + 52, 143, 220, 244, 235, 3, 137, 186, 233, 103, 82, 159, 185, 128, 149, 239, 191, 207, 246, 133, 11, 115, + 214, 136, 219, 10, 184, 3, 1, 182, 204, 158, 205, 198, 201, 147, 201, 77, 15, 0, 251, 192, 204, 80, 84, + 117, 187, 105, 255, 228, 147, 184, 115, 104, 40, 10, 201, 115, 49, 175, 95, 63, 118, 174, 94, 77, 16, 227, + 94, 131, 122, 75, 6, 13, 118, 32, 90, 102, 250, 17, 135, 223, 79, 217, 109, 183, 89, 62, 183, 46, 151, 139, + 65, 131, 7, 79, 138, 197, 98, 21, 146, 36, 197, 49, 118, 109, 47, 24, 139, 230, 24, 5, 130, 101, 49, 14, + 97, 60, 154, 17, 197, 170, 170, 174, 222, 59, 116, 216, 176, 47, 60, 86, 166, 82, 82, 141, 61, 75, 59, 119, + 6, 167, 51, 175, 54, 124, 109, 33, 213, 183, 208, 209, 71, 177, 180, 138, 194, 88, 69, 5, 211, 123, 246, + 76, 123, 133, 229, 4, 138, 2, 170, 74, 187, 199, 31, 199, 213, 186, 181, 161, 1, 105, 62, 204, 189, 17, + 140, 34, 90, 26, 241, 141, 199, 98, 204, 236, 222, 157, 68, 36, 210, 40, 245, 88, 14, 167, 147, 120, 117, + 53, 115, 95, 126, 57, 157, 218, 52, 74, 1, 254, 208, 160, 23, 182, 151, 220, 117, 23, 69, 255, 239, 255, + 229, 214, 80, 52, 16, 96, 203, 130, 5, 44, 26, 56, 144, 16, 153, 230, 174, 249, 96, 203, 32, 66, 111, 216, + 218, 226, 207, 127, 38, 104, 113, 207, 65, 159, 207, 199, 178, 229, 203, 55, 141, 27, 55, 110, 94, 234, + 163, 90, 204, 211, 131, 249, 178, 61, 52, 74, 20, 8, 86, 238, 96, 102, 60, 42, 94, 236, 140, 26, 53, 106, + 214, 154, 53, 107, 118, 88, 73, 178, 148, 104, 148, 226, 159, 253, 140, 102, 151, 95, 110, 40, 192, 134, + 99, 175, 67, 56, 218, 97, 102, 136, 41, 106, 54, 66, 192, 186, 47, 190, 200, 185, 55, 150, 82, 91, 139, + 175, 67, 7, 218, 61, 246, 88, 157, 199, 66, 113, 163, 62, 214, 115, 150, 171, 97, 84, 101, 231, 7, 182, 46, + 94, 204, 140, 23, 94, 192, 229, 243, 53, 46, 219, 6, 73, 194, 29, 12, 50, 175, 87, 47, 182, 47, 93, 138, + 15, 115, 29, 149, 157, 180, 61, 71, 58, 16, 94, 181, 117, 34, 14, 132, 207, 57, 135, 210, 59, 239, 68, 201, + 33, 185, 146, 156, 78, 18, 209, 40, 211, 122, 244, 64, 173, 173, 173, 227, 146, 159, 205, 181, 221, 46, 3, + 225, 21, 14, 22, 14, 184, 138, 138, 40, 189, 229, 22, 203, 139, 6, 156, 78, 39, 131, 7, 15, 158, 84, 91, + 91, 123, 64, 136, 94, 105, 190, 87, 34, 185, 210, 158, 191, 11, 218, 171, 28, 161, 17, 173, 122, 249, 131, + 44, 81, 172, 140, 84, 161, 36, 73, 137, 138, 138, 138, 61, 195, 134, 13, 155, 98, 101, 154, 16, 85, 69, 85, + 20, 74, 111, 187, 13, 201, 227, 49, 124, 84, 177, 251, 221, 164, 109, 126, 250, 202, 66, 61, 209, 242, 1, + 179, 95, 125, 149, 253, 155, 55, 231, 84, 116, 45, 87, 85, 209, 252, 138, 43, 104, 113, 253, 245, 121, 209, + 171, 48, 27, 196, 77, 67, 60, 15, 162, 111, 150, 147, 100, 154, 118, 241, 187, 239, 50, 175, 79, 31, 188, + 225, 112, 163, 33, 89, 190, 162, 34, 86, 140, 24, 193, 194, 62, 125, 240, 83, 63, 251, 133, 124, 133, 120, + 125, 138, 169, 43, 169, 168, 136, 246, 79, 61, 149, 108, 130, 109, 97, 211, 97, 61, 60, 193, 32, 139, 6, + 15, 230, 187, 5, 11, 210, 169, 65, 35, 91, 6, 163, 243, 98, 183, 243, 163, 215, 94, 181, 252, 203, 95, 8, + 158, 120, 162, 229, 209, 171, 229, 203, 151, 111, 26, 59, 118, 172, 62, 122, 165, 237, 59, 98, 91, 156, + 124, 93, 162, 26, 13, 26, 199, 138, 151, 191, 56, 148, 14, 171, 22, 80, 63, 26, 61, 122, 206, 134, 13, 27, + 118, 91, 29, 197, 10, 159, 126, 58, 45, 254, 244, 167, 188, 242, 197, 146, 116, 239, 197, 84, 161, 232, + 178, 173, 45, 212, 126, 160, 106, 199, 14, 102, 188, 252, 50, 14, 151, 203, 58, 115, 87, 61, 84, 21, 37, + 22, 163, 252, 193, 7, 241, 157, 120, 98, 90, 65, 154, 15, 250, 55, 51, 152, 69, 177, 68, 11, 13, 31, 48, + 173, 71, 15, 190, 124, 251, 109, 60, 193, 96, 206, 170, 58, 235, 5, 73, 194, 87, 92, 204, 202, 49, 99, 152, + 240, 216, 99, 105, 66, 158, 45, 66, 146, 207, 208, 147, 43, 45, 178, 18, 7, 202, 31, 126, 152, 192, 105, + 167, 229, 84, 216, 238, 246, 251, 217, 190, 108, 25, 115, 123, 245, 34, 64, 166, 238, 74, 108, 197, 100, + 230, 189, 102, 7, 152, 121, 138, 185, 90, 180, 160, 228, 166, 155, 44, 21, 182, 67, 90, 123, 53, 81, 136, + 94, 69, 169, 27, 193, 42, 104, 175, 26, 8, 5, 130, 149, 35, 212, 67, 139, 85, 75, 42, 138, 181, 111, 223, + 190, 157, 239, 191, 255, 254, 84, 75, 163, 88, 128, 26, 143, 83, 218, 185, 51, 206, 80, 200, 208, 236, 196, + 174, 119, 149, 81, 4, 197, 44, 93, 168, 165, 10, 87, 125, 252, 49, 171, 63, 253, 20, 79, 40, 148, 179, 227, + 82, 227, 113, 220, 205, 155, 211, 254, 233, 167, 81, 220, 110, 195, 206, 169, 118, 157, 115, 35, 136, 4, + 203, 172, 87, 164, 150, 242, 153, 252, 252, 243, 76, 124, 250, 105, 144, 164, 220, 53, 228, 206, 2, 135, + 203, 133, 47, 28, 102, 201, 7, 31, 48, 182, 91, 55, 164, 84, 58, 170, 62, 125, 237, 242, 29, 250, 200, 74, + 179, 43, 175, 164, 101, 167, 78, 200, 149, 149, 57, 251, 78, 201, 225, 64, 145, 101, 166, 245, 232, 65, + 188, 186, 58, 221, 204, 89, 223, 64, 91, 35, 190, 250, 115, 97, 183, 243, 34, 110, 2, 113, 160, 205, 77, + 55, 225, 107, 215, 14, 197, 194, 244, 160, 207, 231, 99, 217, 178, 101, 155, 198, 141, 27, 55, 63, 245, + 145, 145, 239, 149, 182, 44, 229, 195, 243, 118, 163, 71, 129, 96, 229, 30, 250, 194, 17, 35, 95, 44, 245, + 195, 225, 195, 167, 111, 216, 176, 97, 143, 165, 81, 172, 218, 90, 2, 39, 159, 76, 203, 60, 78, 91, 233, + 211, 83, 98, 11, 29, 81, 44, 235, 1, 166, 247, 232, 65, 229, 246, 237, 56, 173, 180, 198, 208, 65, 174, + 174, 166, 232, 188, 243, 40, 185, 247, 222, 188, 138, 28, 154, 65, 159, 170, 53, 50, 127, 245, 145, 76, 23, + 126, 249, 191, 255, 49, 236, 230, 155, 217, 177, 122, 53, 190, 226, 98, 156, 13, 32, 126, 151, 36, 9, 111, + 40, 132, 28, 139, 49, 225, 233, 167, 25, 251, 208, 67, 56, 162, 209, 244, 134, 110, 212, 60, 216, 174, 209, + 146, 195, 129, 62, 178, 162, 233, 174, 60, 29, 59, 210, 246, 177, 199, 32, 145, 176, 204, 81, 220, 8, 158, + 80, 136, 197, 67, 134, 176, 113, 214, 44, 66, 100, 94, 47, 70, 194, 118, 141, 100, 129, 125, 206, 139, 89, + 229, 160, 183, 109, 91, 90, 223, 112, 131, 229, 209, 65, 151, 211, 201, 224, 119, 223, 213, 180, 87, 122, + 223, 43, 45, 61, 152, 143, 238, 61, 141, 22, 5, 130, 149, 123, 232, 13, 145, 235, 136, 221, 37, 73, 146, + 247, 237, 219, 183, 115, 240, 224, 193, 19, 172, 142, 98, 41, 181, 181, 148, 220, 124, 51, 238, 22, 45, 50, + 188, 126, 160, 110, 36, 200, 78, 67, 140, 50, 232, 123, 197, 105, 139, 180, 40, 150, 13, 0, 21, 91, 183, + 50, 243, 181, 215, 146, 90, 172, 92, 165, 10, 1, 165, 186, 154, 146, 59, 238, 160, 232, 252, 243, 137, 147, + 63, 115, 110, 118, 30, 140, 230, 223, 171, 27, 62, 32, 12, 108, 154, 55, 143, 65, 215, 93, 199, 228, 30, + 61, 136, 28, 56, 128, 175, 168, 8, 151, 215, 107, 249, 249, 144, 156, 78, 188, 193, 32, 78, 175, 151, 213, + 147, 38, 49, 232, 186, 235, 152, 51, 112, 32, 126, 85, 37, 64, 118, 33, 181, 94, 239, 99, 55, 81, 245, 161, + 6, 186, 247, 218, 226, 164, 184, 92, 180, 127, 230, 25, 60, 173, 91, 39, 219, 225, 228, 8, 110, 159, 143, + 157, 43, 87, 50, 231, 181, 215, 210, 231, 66, 124, 16, 50, 59, 31, 199, 122, 222, 142, 116, 136, 169, 140, + 56, 80, 242, 247, 191, 227, 105, 221, 218, 82, 107, 6, 173, 114, 48, 165, 189, 18, 125, 175, 52, 130, 37, + 106, 175, 10, 198, 162, 13, 132, 2, 193, 202, 33, 14, 209, 4, 90, 172, 238, 136, 2, 210, 136, 145, 35, 103, + 173, 89, 179, 230, 123, 43, 163, 88, 106, 44, 134, 191, 125, 123, 90, 255, 237, 111, 25, 102, 152, 249, + 112, 87, 137, 155, 133, 94, 100, 109, 148, 42, 12, 2, 203, 63, 248, 128, 111, 39, 76, 192, 155, 195, 170, + 66, 85, 150, 145, 92, 46, 218, 61, 245, 20, 142, 20, 177, 205, 151, 244, 172, 6, 253, 70, 109, 100, 155, + 33, 146, 43, 109, 132, 1, 170, 171, 153, 218, 187, 55, 253, 174, 184, 130, 73, 47, 188, 192, 174, 117, 235, + 112, 123, 189, 248, 194, 97, 220, 62, 95, 82, 167, 117, 152, 132, 75, 74, 181, 89, 241, 4, 2, 248, 138, + 138, 80, 226, 113, 86, 78, 156, 200, 144, 155, 110, 226, 253, 219, 111, 103, 215, 234, 213, 20, 65, 70, + 149, 154, 152, 142, 210, 187, 131, 255, 16, 22, 70, 133, 204, 212, 96, 201, 125, 247, 81, 124, 193, 5, 57, + 117, 107, 151, 28, 14, 100, 89, 230, 139, 238, 221, 137, 85, 84, 24, 166, 6, 141, 200, 85, 250, 255, 207, + 217, 145, 89, 11, 241, 62, 23, 91, 226, 4, 78, 61, 149, 150, 127, 250, 147, 229, 149, 153, 14, 135, 131, + 126, 253, 251, 143, 55, 168, 28, 52, 74, 15, 230, 203, 22, 208, 232, 209, 248, 12, 106, 242, 19, 226, 125, + 102, 152, 38, 148, 36, 201, 87, 89, 89, 185, 103, 200, 208, 161, 83, 158, 126, 234, 169, 27, 99, 22, 62, + 65, 202, 145, 8, 109, 58, 117, 98, 247, 200, 145, 196, 55, 111, 206, 208, 52, 104, 79, 88, 118, 89, 184, + 204, 32, 70, 83, 140, 252, 49, 52, 102, 27, 3, 166, 61, 255, 60, 165, 103, 158, 137, 191, 105, 83, 228, 28, + 61, 169, 43, 209, 40, 254, 19, 78, 160, 237, 147, 79, 178, 241, 254, 251, 211, 79, 224, 226, 92, 231, 195, + 188, 67, 114, 222, 85, 146, 115, 15, 153, 100, 82, 191, 138, 107, 215, 156, 11, 168, 217, 177, 131, 169, + 189, 123, 243, 229, 192, 129, 180, 61, 235, 44, 78, 184, 240, 66, 218, 157, 125, 54, 205, 218, 181, 195, + 95, 92, 140, 211, 237, 78, 23, 37, 168, 138, 130, 248, 176, 45, 73, 82, 186, 42, 81, 85, 85, 226, 209, 40, + 85, 187, 118, 177, 227, 219, 111, 89, 63, 123, 54, 107, 167, 78, 101, 231, 250, 245, 56, 32, 221, 211, 78, + 31, 81, 19, 35, 38, 102, 70, 150, 249, 112, 126, 68, 24, 109, 252, 49, 160, 232, 194, 11, 105, 147, 99, 75, + 6, 72, 166, 6, 231, 190, 253, 54, 27, 102, 206, 164, 152, 186, 15, 65, 70, 68, 215, 206, 231, 64, 191, 14, + 117, 184, 243, 78, 92, 225, 176, 165, 36, 214, 239, 247, 179, 120, 241, 226, 117, 159, 125, 246, 217, 130, + 212, 71, 102, 190, 87, 133, 232, 85, 3, 163, 64, 176, 114, 12, 85, 85, 85, 41, 185, 75, 232, 247, 125, 189, + 14, 43, 10, 184, 71, 142, 28, 57, 235, 134, 78, 157, 126, 219, 177, 99, 199, 146, 90, 139, 202, 119, 213, + 68, 2, 119, 171, 86, 148, 220, 126, 59, 27, 159, 120, 2, 153, 228, 194, 165, 112, 112, 83, 180, 43, 68, + 210, 162, 109, 244, 90, 36, 69, 230, 96, 36, 75, 35, 88, 1, 96, 223, 230, 205, 76, 239, 217, 147, 203, 122, + 246, 68, 142, 199, 115, 166, 53, 145, 171, 170, 104, 126, 229, 149, 84, 47, 94, 204, 206, 65, 131, 12, 211, + 51, 118, 134, 54, 247, 112, 48, 202, 160, 57, 185, 35, 252, 91, 213, 253, 63, 18, 7, 55, 81, 15, 16, 143, + 70, 89, 55, 103, 14, 223, 204, 153, 131, 219, 225, 160, 168, 77, 27, 154, 181, 111, 79, 211, 118, 237, 104, + 82, 86, 70, 160, 105, 83, 124, 225, 48, 14, 183, 27, 173, 29, 84, 34, 22, 35, 114, 224, 0, 85, 187, 119, + 179, 127, 235, 86, 246, 110, 216, 192, 190, 77, 155, 168, 218, 183, 15, 133, 131, 105, 97, 81, 19, 166, 39, + 89, 34, 185, 202, 151, 13, 61, 27, 76, 43, 218, 74, 74, 104, 247, 244, 211, 73, 225, 121, 174, 26, 57, 147, + 170, 26, 92, 178, 132, 47, 223, 120, 131, 32, 117, 123, 12, 230, 131, 99, 59, 28, 156, 103, 141, 201, 104, + 36, 54, 252, 171, 95, 209, 236, 15, 127, 176, 212, 180, 85, 123, 0, 233, 63, 96, 192, 120, 89, 150, 43, 83, + 218, 171, 104, 106, 20, 180, 87, 199, 24, 5, 130, 213, 112, 48, 138, 98, 165, 157, 221, 17, 162, 88, 239, + 188, 243, 206, 196, 30, 61, 122, 220, 108, 21, 193, 2, 80, 106, 106, 104, 121, 213, 85, 236, 252, 240, 67, + 106, 87, 172, 72, 47, 94, 10, 7, 137, 137, 93, 22, 176, 108, 16, 163, 88, 46, 50, 243, 178, 218, 83, 100, + 8, 88, 49, 114, 36, 199, 93, 112, 1, 167, 94, 113, 5, 181, 185, 170, 150, 82, 85, 148, 72, 132, 178, 110, + 221, 168, 94, 190, 156, 232, 162, 69, 25, 41, 181, 124, 137, 30, 66, 102, 170, 80, 35, 237, 70, 196, 74, + 76, 37, 234, 253, 203, 100, 64, 86, 20, 170, 182, 109, 99, 255, 182, 109, 200, 95, 126, 153, 108, 134, 75, + 93, 82, 42, 238, 18, 98, 106, 216, 47, 188, 215, 68, 247, 122, 111, 52, 113, 232, 211, 81, 122, 157, 82, + 190, 64, 95, 201, 170, 146, 218, 117, 29, 14, 58, 60, 243, 12, 190, 246, 237, 115, 154, 26, 116, 56, 157, + 36, 106, 107, 153, 242, 236, 179, 36, 170, 171, 235, 120, 94, 101, 211, 93, 129, 125, 206, 133, 81, 132, + 48, 1, 168, 146, 68, 249, 61, 247, 224, 112, 185, 44, 141, 154, 251, 253, 126, 230, 206, 157, 187, 122, + 194, 132, 9, 139, 82, 31, 25, 9, 219, 11, 209, 171, 99, 132, 31, 130, 212, 224, 152, 195, 64, 139, 101, + 230, 238, 30, 5, 24, 253, 241, 199, 115, 150, 47, 95, 254, 157, 207, 194, 30, 122, 170, 44, 227, 12, 135, + 41, 187, 251, 238, 58, 206, 238, 226, 134, 175, 111, 25, 98, 167, 33, 86, 28, 137, 166, 163, 250, 212, 144, + 150, 30, 154, 214, 189, 123, 206, 13, 72, 213, 68, 2, 71, 32, 64, 251, 238, 221, 113, 54, 109, 154, 161, + 195, 202, 135, 121, 119, 234, 222, 235, 53, 112, 94, 146, 164, 199, 79, 50, 162, 20, 32, 169, 133, 211, 94, + 181, 247, 126, 97, 4, 129, 34, 160, 24, 104, 146, 122, 31, 18, 126, 62, 72, 82, 203, 165, 253, 76, 113, + 234, 223, 250, 223, 21, 20, 190, 83, 28, 126, 50, 83, 132, 70, 62, 88, 249, 52, 196, 235, 75, 131, 182, + 241, 183, 185, 247, 94, 154, 92, 124, 113, 78, 201, 21, 144, 116, 206, 239, 219, 151, 45, 11, 22, 16, 194, + 60, 85, 107, 86, 108, 96, 135, 33, 233, 222, 139, 68, 182, 217, 21, 87, 80, 252, 171, 95, 33, 91, 88, 57, + 40, 73, 18, 178, 44, 211, 167, 79, 159, 207, 84, 85, 173, 17, 162, 87, 5, 237, 85, 35, 129, 227, 208, 63, + 82, 128, 133, 48, 242, 196, 210, 34, 89, 81, 32, 42, 73, 82, 60, 18, 137, 236, 31, 56, 112, 224, 231, 46, + 139, 203, 216, 229, 234, 106, 154, 93, 116, 17, 197, 191, 254, 53, 49, 225, 96, 236, 126, 199, 137, 81, 7, + 179, 205, 94, 76, 11, 121, 73, 110, 190, 149, 223, 127, 207, 180, 30, 61, 112, 56, 157, 185, 51, 32, 5, + 148, 72, 132, 192, 41, 167, 80, 246, 196, 19, 134, 189, 10, 237, 14, 49, 202, 32, 26, 67, 234, 137, 150, + 102, 215, 96, 52, 68, 50, 164, 17, 32, 127, 150, 225, 51, 121, 239, 55, 248, 189, 70, 191, 91, 159, 150, + 210, 174, 25, 187, 69, 76, 14, 7, 122, 193, 117, 209, 111, 126, 67, 201, 61, 247, 160, 212, 212, 228, 244, + 123, 61, 193, 32, 155, 102, 207, 102, 254, 91, 111, 165, 83, 131, 245, 169, 226, 180, 235, 185, 16, 171, 6, + 101, 192, 17, 12, 82, 118, 199, 29, 201, 170, 65, 11, 3, 71, 129, 64, 128, 105, 211, 167, 47, 157, 62, 99, + 198, 210, 212, 215, 137, 228, 170, 160, 189, 106, 4, 40, 16, 172, 6, 66, 150, 40, 86, 157, 84, 33, 192, + 152, 177, 99, 231, 45, 92, 184, 112, 157, 223, 74, 83, 70, 85, 5, 135, 131, 210, 123, 238, 65, 77, 53, 130, + 206, 183, 22, 58, 96, 92, 213, 38, 218, 7, 104, 139, 122, 24, 88, 253, 233, 167, 44, 251, 240, 67, 60, 225, + 112, 78, 143, 73, 174, 170, 162, 249, 159, 255, 76, 139, 91, 111, 37, 70, 254, 185, 188, 235, 181, 50, 122, + 146, 43, 146, 44, 125, 52, 75, 140, 104, 153, 69, 182, 244, 81, 174, 0, 230, 100, 202, 136, 84, 101, 139, + 90, 233, 163, 59, 118, 219, 208, 179, 65, 159, 26, 212, 200, 149, 187, 109, 91, 218, 61, 247, 28, 146, 195, + 145, 211, 86, 56, 14, 151, 139, 200, 254, 253, 76, 126, 250, 105, 136, 199, 241, 113, 104, 207, 43, 187, + 167, 105, 245, 198, 173, 45, 110, 188, 49, 233, 138, 111, 161, 228, 195, 225, 112, 80, 91, 91, 171, 244, + 237, 219, 247, 51, 146, 15, 230, 245, 17, 182, 219, 125, 153, 177, 29, 10, 4, 171, 225, 113, 40, 45, 86, + 84, 146, 164, 88, 34, 145, 168, 236, 223, 191, 255, 120, 9, 44, 141, 174, 40, 145, 8, 69, 231, 156, 67, + 179, 171, 174, 162, 150, 252, 50, 194, 204, 102, 29, 160, 23, 59, 139, 173, 116, 102, 244, 236, 201, 174, + 85, 171, 112, 89, 152, 146, 173, 131, 148, 30, 171, 180, 91, 55, 130, 231, 158, 155, 215, 36, 203, 204, 54, + 67, 31, 205, 210, 8, 82, 144, 186, 41, 64, 35, 178, 148, 237, 85, 252, 255, 67, 100, 143, 90, 233, 91, 176, + 216, 125, 67, 55, 131, 120, 61, 137, 97, 115, 197, 227, 161, 237, 243, 207, 227, 41, 43, 179, 116, 211, + 175, 3, 73, 194, 229, 243, 49, 243, 229, 151, 217, 181, 122, 117, 90, 119, 37, 222, 127, 70, 69, 6, 118, + 220, 148, 204, 10, 8, 220, 165, 165, 148, 116, 238, 108, 121, 75, 156, 64, 32, 192, 231, 159, 127, 62, 127, + 193, 130, 5, 43, 201, 244, 189, 50, 138, 94, 165, 201, 85, 33, 122, 213, 176, 176, 227, 181, 108, 91, 212, + 67, 139, 149, 38, 89, 128, 250, 249, 132, 9, 139, 102, 205, 158, 189, 210, 210, 40, 22, 36, 91, 232, 220, + 117, 23, 174, 162, 34, 20, 221, 127, 211, 107, 9, 236, 58, 68, 227, 75, 35, 61, 150, 166, 197, 10, 0, 177, + 125, 251, 152, 242, 244, 211, 40, 137, 68, 78, 123, 229, 169, 137, 4, 14, 175, 151, 118, 207, 63, 143, 187, + 117, 235, 131, 173, 236, 201, 15, 61, 150, 217, 57, 208, 72, 141, 56, 247, 102, 209, 167, 112, 106, 132, + 132, 247, 226, 40, 210, 189, 138, 63, 175, 13, 145, 152, 105, 228, 74, 244, 191, 210, 71, 77, 236, 168, + 247, 57, 212, 48, 210, 93, 105, 41, 171, 210, 7, 224, 19, 160, 76, 0, 0, 32, 0, 73, 68, 65, 84, 31, 164, + 40, 199, 126, 87, 0, 222, 80, 136, 213, 227, 198, 177, 116, 200, 16, 194, 212, 213, 64, 26, 185, 232, 235, + 175, 159, 99, 61, 143, 135, 51, 215, 250, 34, 12, 25, 40, 185, 243, 78, 60, 165, 165, 168, 22, 86, 103, 58, + 157, 78, 42, 42, 42, 98, 125, 250, 244, 25, 15, 196, 83, 209, 43, 177, 231, 160, 70, 176, 10, 109, 113, + 142, 49, 28, 135, 254, 145, 2, 36, 73, 178, 108, 164, 96, 164, 197, 210, 187, 187, 199, 128, 72, 223, 190, + 125, 63, 77, 36, 18, 214, 70, 177, 106, 107, 241, 159, 120, 34, 45, 111, 185, 37, 163, 133, 78, 62, 64, + 156, 37, 179, 141, 94, 36, 91, 90, 175, 194, 77, 115, 230, 48, 191, 111, 95, 220, 129, 64, 78, 143, 79, + 137, 70, 241, 29, 119, 28, 229, 207, 61, 135, 226, 112, 24, 198, 238, 237, 124, 46, 244, 209, 32, 241, 28, + 232, 171, 250, 52, 194, 163, 145, 32, 35, 77, 86, 182, 232, 150, 254, 115, 125, 196, 202, 104, 51, 55, 107, + 135, 147, 47, 214, 25, 122, 232, 117, 87, 77, 255, 244, 39, 90, 222, 122, 107, 206, 201, 149, 203, 235, + 101, 223, 198, 141, 76, 125, 246, 217, 140, 158, 148, 122, 215, 118, 179, 84, 173, 93, 207, 133, 232, 216, + 30, 248, 233, 79, 105, 241, 231, 63, 91, 238, 45, 22, 8, 4, 248, 104, 244, 232, 153, 171, 86, 175, 94, 43, + 73, 146, 76, 93, 114, 37, 90, 255, 21, 180, 87, 199, 16, 5, 130, 213, 240, 48, 138, 98, 233, 73, 150, 118, + 195, 40, 179, 102, 207, 94, 62, 105, 242, 228, 69, 65, 139, 157, 199, 149, 72, 132, 214, 55, 223, 140, 183, + 67, 7, 226, 212, 125, 204, 177, 243, 157, 168, 39, 89, 218, 226, 173, 23, 93, 139, 35, 8, 204, 237, 213, + 139, 77, 179, 102, 225, 201, 161, 203, 59, 36, 245, 88, 197, 151, 92, 66, 171, 174, 93, 13, 83, 133, 249, + 128, 108, 154, 44, 163, 158, 133, 250, 200, 162, 94, 212, 174, 215, 96, 25, 137, 222, 15, 199, 165, 221, + 142, 254, 74, 245, 133, 62, 53, 168, 105, 129, 124, 167, 159, 78, 233, 147, 79, 38, 197, 214, 138, 62, 118, + 109, 29, 36, 135, 3, 21, 152, 242, 204, 51, 84, 239, 216, 65, 128, 250, 183, 194, 177, 27, 140, 230, 90, + 99, 55, 165, 247, 221, 135, 51, 16, 64, 181, 112, 174, 93, 46, 23, 59, 119, 238, 172, 26, 56, 112, 224, + 196, 212, 215, 212, 234, 134, 86, 56, 37, 214, 211, 228, 211, 210, 98, 43, 20, 8, 214, 177, 131, 88, 104, + 98, 216, 62, 39, 21, 250, 141, 245, 233, 211, 231, 179, 234, 234, 234, 132, 195, 97, 221, 233, 82, 19, 9, + 220, 45, 90, 208, 230, 238, 187, 235, 196, 146, 197, 3, 180, 43, 244, 145, 9, 125, 101, 155, 94, 143, 229, + 3, 164, 120, 156, 201, 79, 61, 69, 205, 158, 61, 57, 109, 8, 13, 73, 146, 213, 234, 206, 59, 41, 190, 252, + 114, 195, 166, 208, 118, 158, 123, 13, 250, 168, 144, 145, 248, 221, 168, 57, 180, 145, 165, 134, 207, 96, + 136, 101, 254, 70, 85, 105, 102, 105, 64, 253, 49, 230, 19, 140, 54, 252, 56, 224, 104, 209, 130, 182, 61, + 123, 226, 12, 135, 45, 77, 87, 25, 193, 19, 10, 177, 176, 127, 127, 214, 78, 153, 146, 97, 201, 80, 159, + 72, 34, 216, 243, 156, 232, 77, 69, 139, 47, 189, 148, 226, 11, 47, 68, 182, 184, 66, 51, 16, 8, 48, 100, + 232, 208, 41, 155, 55, 111, 254, 78, 136, 94, 105, 15, 228, 122, 114, 85, 136, 94, 29, 99, 20, 8, 214, 177, + 129, 222, 143, 78, 111, 219, 32, 62, 145, 40, 203, 150, 45, 251, 230, 227, 143, 63, 158, 109, 121, 20, 171, + 186, 154, 230, 87, 94, 73, 40, 37, 186, 206, 215, 199, 29, 113, 99, 215, 107, 178, 68, 146, 21, 4, 118, + 175, 89, 195, 180, 30, 61, 112, 122, 60, 57, 181, 110, 64, 81, 64, 81, 40, 127, 230, 25, 124, 167, 157, + 150, 119, 81, 68, 17, 102, 68, 75, 27, 98, 255, 66, 253, 48, 51, 9, 53, 106, 177, 162, 215, 243, 136, 17, + 51, 163, 77, 220, 142, 27, 121, 54, 24, 145, 43, 25, 144, 157, 78, 202, 186, 119, 199, 127, 242, 201, 40, + 22, 250, 48, 25, 193, 19, 12, 178, 121, 206, 28, 102, 191, 254, 122, 134, 153, 168, 17, 249, 181, 123, 213, + 160, 153, 169, 168, 20, 12, 82, 122, 223, 125, 201, 170, 109, 11, 121, 141, 199, 227, 97, 221, 186, 117, + 187, 6, 15, 30, 60, 133, 76, 91, 6, 189, 177, 168, 246, 208, 158, 143, 203, 185, 173, 80, 32, 88, 199, 22, + 135, 178, 108, 136, 74, 146, 20, 5, 228, 190, 253, 250, 125, 190, 107, 215, 174, 26, 43, 189, 177, 84, 69, + 193, 225, 118, 83, 250, 207, 127, 162, 58, 29, 201, 59, 82, 74, 14, 164, 84, 191, 221, 212, 171, 29, 135, + 67, 120, 213, 134, 83, 2, 119, 106, 120, 36, 240, 234, 70, 24, 248, 122, 228, 72, 150, 13, 31, 158, 115, + 235, 6, 53, 22, 195, 89, 92, 76, 219, 158, 61, 145, 154, 53, 77, 57, 62, 147, 222, 113, 236, 62, 255, 102, + 231, 67, 252, 183, 83, 120, 117, 165, 134, 91, 55, 60, 169, 113, 168, 207, 220, 194, 239, 112, 10, 191, 91, + 255, 157, 250, 207, 242, 97, 160, 123, 175, 74, 7, 163, 87, 173, 187, 118, 165, 201, 255, 253, 31, 114, + 174, 58, 22, 164, 224, 116, 187, 169, 217, 179, 135, 73, 79, 62, 129, 84, 91, 139, 95, 2, 159, 148, 188, + 175, 60, 82, 230, 57, 115, 74, 230, 231, 200, 14, 67, 156, 111, 109, 205, 84, 164, 228, 124, 183, 188, 229, + 22, 2, 167, 157, 106, 121, 229, 160, 199, 227, 97, 192, 192, 129, 227, 247, 237, 219, 183, 43, 213, 208, + 217, 168, 37, 78, 157, 212, 96, 33, 122, 117, 236, 80, 32, 88, 199, 14, 122, 45, 150, 246, 212, 97, 36, + 120, 151, 55, 109, 218, 180, 105, 232, 208, 161, 83, 2, 22, 139, 176, 229, 154, 26, 138, 126, 249, 75, 154, + 93, 115, 109, 50, 138, 34, 101, 146, 44, 187, 15, 113, 49, 212, 54, 114, 83, 146, 69, 106, 67, 0, 166, 63, + 223, 157, 29, 43, 150, 227, 182, 184, 130, 83, 15, 37, 18, 193, 127, 218, 105, 148, 117, 239, 142, 236, + 144, 144, 213, 131, 231, 64, 251, 27, 242, 229, 92, 212, 135, 44, 138, 68, 88, 36, 74, 34, 1, 211, 127, 46, + 110, 212, 226, 102, 109, 244, 125, 199, 250, 239, 207, 245, 208, 54, 122, 69, 74, 46, 34, 77, 175, 249, 51, + 173, 238, 188, 51, 231, 162, 118, 73, 146, 112, 184, 221, 76, 125, 254, 121, 118, 127, 187, 134, 160, 36, + 68, 29, 165, 131, 36, 75, 35, 193, 122, 98, 37, 222, 171, 118, 26, 218, 189, 169, 72, 16, 87, 193, 115, 92, + 71, 90, 223, 218, 25, 165, 198, 218, 72, 97, 170, 161, 243, 198, 225, 195, 135, 207, 78, 125, 36, 70, 175, + 196, 244, 96, 70, 229, 96, 129, 92, 29, 91, 20, 8, 214, 177, 135, 62, 194, 108, 36, 120, 143, 2, 234, 160, + 193, 131, 167, 172, 95, 191, 126, 183, 199, 226, 214, 46, 74, 44, 70, 155, 187, 239, 198, 217, 162, 57, + 113, 165, 110, 108, 57, 95, 238, 80, 45, 29, 161, 23, 90, 107, 22, 2, 90, 10, 35, 32, 65, 236, 64, 5, 147, + 158, 120, 146, 120, 36, 130, 195, 98, 71, 125, 61, 228, 202, 74, 154, 92, 118, 57, 173, 186, 117, 75, 174, + 144, 234, 15, 43, 182, 159, 109, 15, 171, 111, 153, 188, 217, 248, 33, 192, 168, 106, 38, 166, 128, 255, + 236, 159, 81, 242, 228, 83, 168, 241, 220, 138, 218, 1, 60, 225, 48, 95, 13, 25, 194, 215, 31, 125, 68, 24, + 29, 185, 34, 191, 220, 218, 141, 204, 91, 101, 53, 185, 112, 151, 220, 123, 31, 238, 22, 45, 147, 133, 4, + 22, 65, 147, 42, 188, 245, 246, 219, 227, 98, 177, 88, 133, 73, 67, 103, 141, 92, 105, 4, 171, 128, 70, + 128, 2, 193, 58, 182, 200, 86, 81, 40, 62, 157, 68, 37, 73, 74, 236, 221, 187, 119, 71, 255, 254, 253, 63, + 247, 122, 189, 214, 30, 68, 44, 134, 175, 67, 7, 90, 221, 113, 167, 161, 22, 200, 238, 16, 23, 111, 35, + 235, 134, 180, 78, 68, 216, 12, 66, 18, 108, 89, 180, 136, 153, 47, 189, 132, 219, 231, 75, 61, 94, 231, + 14, 73, 209, 251, 221, 20, 95, 243, 103, 98, 106, 254, 234, 177, 10, 176, 22, 134, 78, 237, 10, 184, 202, + 203, 104, 251, 210, 75, 56, 3, 126, 212, 68, 142, 69, 237, 129, 0, 91, 22, 46, 100, 70, 143, 255, 226, 231, + 224, 125, 228, 149, 140, 171, 6, 141, 44, 50, 236, 8, 49, 245, 16, 83, 33, 124, 225, 5, 52, 253, 227, 31, + 45, 143, 22, 6, 2, 1, 190, 248, 226, 139, 165, 147, 38, 77, 90, 68, 93, 237, 85, 86, 113, 123, 1, 199, 22, + 5, 130, 213, 56, 96, 100, 60, 106, 20, 197, 98, 196, 200, 145, 51, 23, 127, 245, 213, 6, 43, 27, 65, 3, 40, + 53, 53, 180, 236, 244, 23, 252, 167, 255, 132, 152, 146, 223, 46, 227, 98, 100, 68, 111, 221, 224, 145, 14, + 10, 169, 195, 192, 226, 65, 131, 248, 122, 244, 104, 188, 161, 80, 110, 15, 80, 81, 80, 19, 113, 202, 254, + 243, 20, 254, 95, 252, 156, 90, 165, 64, 178, 10, 200, 14, 67, 139, 0, 5, 212, 128, 159, 242, 151, 94, 198, + 211, 190, 163, 229, 58, 32, 61, 156, 110, 55, 145, 125, 251, 152, 248, 216, 163, 40, 53, 17, 252, 146, 113, + 213, 160, 70, 176, 244, 162, 118, 187, 193, 240, 137, 88, 1, 124, 94, 74, 187, 116, 69, 114, 56, 44, 21, + 182, 59, 157, 78, 106, 106, 106, 18, 111, 190, 249, 230, 88, 14, 250, 35, 154, 69, 175, 50, 10, 193, 11, + 233, 193, 99, 143, 2, 193, 58, 246, 16, 111, 2, 237, 38, 49, 50, 31, 141, 74, 146, 20, 171, 173, 173, 173, + 232, 221, 171, 215, 56, 56, 24, 58, 182, 228, 32, 100, 25, 103, 48, 68, 73, 151, 46, 201, 187, 84, 201, 76, + 83, 233, 9, 138, 157, 135, 81, 245, 90, 70, 165, 90, 234, 201, 91, 211, 99, 77, 121, 246, 89, 118, 174, 94, + 149, 115, 61, 150, 26, 143, 227, 240, 251, 105, 219, 243, 37, 220, 237, 218, 17, 207, 227, 115, 80, 24, 71, + 55, 16, 94, 211, 165, 200, 169, 7, 163, 146, 103, 158, 37, 244, 171, 95, 161, 84, 55, 140, 238, 234, 139, + 238, 207, 177, 107, 245, 55, 132, 36, 227, 212, 160, 216, 14, 71, 159, 30, 180, 211, 64, 120, 175, 55, 112, + 109, 113, 243, 205, 4, 127, 250, 83, 203, 171, 52, 3, 129, 0, 35, 71, 141, 154, 185, 116, 217, 178, 213, + 169, 175, 51, 138, 94, 213, 233, 57, 88, 32, 87, 141, 3, 5, 130, 213, 120, 160, 247, 197, 170, 67, 176, 82, + 175, 234, 164, 201, 147, 23, 79, 158, 60, 249, 171, 92, 8, 222, 155, 92, 248, 27, 154, 94, 125, 21, 113, + 50, 55, 246, 124, 24, 98, 91, 11, 35, 195, 75, 177, 141, 139, 63, 245, 239, 128, 4, 241, 189, 123, 153, + 248, 216, 99, 196, 170, 171, 115, 174, 199, 82, 162, 81, 60, 237, 218, 81, 254, 202, 203, 72, 225, 48, 178, + 160, 166, 48, 90, 232, 11, 163, 48, 84, 64, 73, 105, 128, 90, 62, 240, 0, 205, 174, 189, 54, 231, 21, 131, + 144, 212, 93, 45, 30, 244, 14, 95, 127, 52, 154, 34, 14, 222, 59, 62, 233, 224, 253, 163, 111, 77, 164, 17, + 45, 9, 251, 19, 45, 149, 100, 244, 202, 219, 177, 3, 173, 111, 255, 135, 229, 228, 202, 237, 118, 179, 125, + 251, 246, 138, 84, 75, 28, 37, 85, 81, 46, 250, 94, 21, 90, 226, 52, 114, 20, 8, 86, 227, 128, 94, 74, 33, + 154, 143, 214, 137, 98, 1, 181, 111, 246, 234, 53, 182, 170, 170, 42, 238, 180, 178, 119, 158, 170, 162, + 36, 18, 180, 185, 255, 126, 156, 205, 155, 145, 200, 195, 52, 149, 184, 64, 138, 162, 119, 51, 61, 150, + 151, 164, 30, 107, 235, 162, 197, 204, 120, 241, 69, 92, 62, 159, 165, 145, 67, 35, 40, 213, 213, 4, 127, + 254, 11, 74, 186, 119, 39, 225, 144, 50, 206, 131, 6, 187, 159, 135, 2, 142, 28, 250, 52, 149, 74, 178, + 130, 173, 248, 218, 107, 104, 117, 223, 125, 201, 214, 44, 57, 14, 96, 120, 66, 33, 54, 205, 158, 197, 140, + 23, 95, 36, 128, 160, 183, 146, 234, 39, 106, 183, 27, 244, 233, 88, 153, 131, 194, 246, 54, 93, 186, 224, + 110, 209, 194, 82, 97, 59, 128, 207, 231, 99, 192, 192, 129, 159, 111, 219, 182, 109, 171, 36, 73, 9, 204, + 201, 149, 232, 123, 85, 72, 13, 54, 34, 20, 8, 86, 227, 130, 145, 47, 150, 38, 120, 79, 63, 189, 72, 146, + 164, 172, 88, 177, 226, 219, 15, 135, 15, 159, 30, 180, 56, 138, 165, 214, 214, 226, 59, 254, 4, 90, 222, + 117, 151, 105, 27, 151, 124, 185, 123, 53, 146, 37, 26, 144, 102, 180, 210, 145, 50, 245, 88, 75, 134, 12, + 97, 217, 7, 31, 228, 220, 31, 11, 82, 149, 133, 87, 93, 69, 171, 7, 31, 50, 173, 44, 204, 151, 243, 80, 64, + 253, 97, 86, 49, 24, 56, 255, 60, 74, 158, 122, 26, 53, 30, 183, 180, 53, 139, 17, 92, 94, 47, 149, 219, + 183, 49, 225, 177, 199, 32, 90, 155, 161, 187, 242, 97, 222, 196, 89, 36, 87, 118, 37, 90, 25, 142, 237, + 42, 20, 93, 114, 49, 77, 47, 189, 12, 217, 226, 126, 131, 62, 159, 143, 165, 75, 151, 110, 30, 242, 222, + 123, 211, 48, 22, 182, 139, 190, 87, 5, 83, 209, 70, 138, 2, 193, 106, 60, 48, 90, 59, 245, 130, 119, 49, + 68, 172, 246, 235, 215, 239, 243, 205, 223, 125, 183, 207, 99, 113, 91, 23, 165, 186, 154, 22, 55, 220, + 136, 255, 172, 179, 136, 27, 68, 177, 236, 14, 113, 113, 23, 211, 134, 134, 122, 44, 14, 70, 180, 124, 192, + 212, 103, 159, 101, 235, 162, 133, 57, 111, 10, 13, 201, 202, 194, 22, 119, 222, 73, 211, 191, 221, 68, 76, + 77, 146, 172, 124, 58, 15, 5, 28, 30, 204, 42, 6, 221, 39, 253, 136, 178, 151, 94, 66, 242, 120, 44, 143, + 162, 232, 225, 112, 58, 81, 20, 133, 137, 143, 63, 206, 254, 13, 27, 235, 232, 174, 140, 170, 6, 197, 104, + 49, 216, 143, 92, 25, 205, 123, 66, 1, 41, 28, 162, 164, 75, 215, 212, 127, 176, 238, 174, 148, 36, 9, 73, + 146, 120, 227, 205, 55, 199, 70, 162, 209, 253, 58, 97, 187, 24, 189, 18, 211, 131, 133, 232, 85, 35, 68, + 129, 96, 53, 46, 24, 153, 143, 214, 73, 19, 146, 140, 98, 197, 119, 236, 216, 177, 189, 95, 255, 254, 227, + 189, 22, 87, 20, 170, 178, 140, 195, 231, 163, 228, 95, 255, 66, 118, 58, 211, 41, 170, 124, 138, 158, 232, + 73, 150, 81, 43, 29, 125, 20, 203, 47, 129, 92, 93, 205, 231, 15, 63, 156, 236, 87, 104, 177, 31, 89, 29, + 40, 10, 106, 109, 45, 109, 30, 123, 156, 240, 197, 23, 21, 236, 27, 126, 192, 48, 171, 24, 148, 218, 180, + 166, 252, 141, 55, 113, 181, 108, 133, 90, 91, 155, 243, 227, 112, 7, 2, 204, 126, 237, 85, 214, 126, 49, + 53, 237, 119, 229, 163, 174, 223, 149, 62, 61, 104, 55, 82, 165, 193, 172, 253, 80, 12, 104, 121, 231, 157, + 248, 79, 181, 222, 177, 61, 24, 12, 50, 97, 194, 132, 69, 147, 38, 77, 90, 152, 250, 200, 72, 123, 85, 71, + 216, 110, 233, 65, 20, 96, 9, 10, 4, 171, 113, 66, 79, 176, 12, 73, 22, 192, 251, 239, 191, 63, 99, 225, + 194, 133, 27, 252, 22, 87, 184, 41, 53, 53, 20, 253, 234, 87, 52, 187, 241, 134, 116, 159, 194, 124, 115, + 176, 211, 235, 177, 52, 146, 85, 71, 248, 174, 211, 99, 237, 249, 118, 77, 178, 29, 136, 36, 37, 203, 178, + 115, 8, 53, 145, 0, 135, 131, 210, 23, 94, 196, 119, 230, 153, 196, 148, 186, 43, 106, 97, 101, 205, 111, + 152, 218, 49, 132, 130, 148, 189, 250, 42, 222, 147, 78, 66, 177, 184, 169, 176, 17, 188, 69, 69, 124, 61, + 122, 52, 243, 223, 238, 147, 108, 226, 44, 220, 23, 250, 94, 131, 162, 238, 74, 188, 67, 236, 76, 180, 210, + 205, 179, 21, 240, 159, 254, 19, 90, 254, 237, 230, 164, 222, 205, 66, 56, 157, 78, 14, 28, 56, 16, 125, + 253, 141, 55, 198, 2, 49, 65, 216, 46, 166, 6, 11, 13, 157, 109, 130, 2, 193, 106, 124, 48, 139, 98, 213, + 73, 19, 74, 146, 84, 27, 139, 197, 42, 95, 123, 253, 245, 79, 20, 69, 177, 92, 124, 173, 212, 214, 210, + 250, 158, 123, 113, 183, 45, 79, 167, 10, 243, 109, 99, 215, 147, 44, 173, 186, 80, 175, 199, 242, 233, + 244, 88, 223, 140, 255, 156, 57, 189, 122, 225, 177, 184, 1, 183, 17, 212, 88, 12, 103, 184, 136, 242, 55, + 94, 199, 213, 161, 125, 198, 185, 72, 255, 76, 206, 143, 162, 128, 99, 1, 253, 57, 214, 236, 24, 18, 78, + 39, 109, 254, 251, 95, 66, 255, 239, 60, 148, 28, 183, 193, 129, 100, 228, 106, 219, 87, 95, 49, 249, 63, + 255, 201, 176, 48, 49, 138, 94, 153, 69, 174, 236, 70, 174, 140, 230, 62, 161, 128, 236, 116, 80, 242, 208, + 195, 56, 66, 33, 84, 89, 182, 244, 59, 3, 129, 0, 239, 189, 247, 222, 148, 213, 171, 87, 175, 149, 36, 73, + 38, 123, 244, 202, 72, 34, 91, 64, 35, 66, 129, 96, 53, 94, 24, 181, 208, 201, 104, 4, 157, 26, 202, 140, + 25, 51, 150, 140, 29, 55, 110, 94, 200, 98, 51, 76, 53, 30, 199, 211, 166, 13, 109, 186, 116, 77, 62, 46, + 25, 104, 128, 242, 233, 206, 214, 202, 176, 141, 170, 10, 51, 42, 11, 37, 8, 1, 95, 190, 241, 58, 171, 198, + 142, 197, 91, 84, 148, 243, 99, 83, 162, 17, 220, 229, 109, 41, 123, 243, 77, 164, 230, 205, 50, 180, 113, + 26, 242, 233, 92, 20, 96, 30, 185, 138, 3, 173, 159, 248, 55, 197, 87, 94, 133, 92, 81, 145, 243, 227, 112, + 122, 60, 212, 236, 217, 195, 248, 135, 30, 34, 126, 224, 0, 65, 49, 114, 85, 207, 170, 65, 187, 145, 43, + 17, 98, 163, 216, 24, 208, 236, 134, 27, 41, 58, 239, 60, 203, 163, 87, 94, 175, 151, 111, 190, 253, 246, + 251, 126, 253, 251, 79, 76, 125, 148, 45, 122, 149, 145, 80, 40, 68, 175, 26, 39, 10, 4, 171, 113, 226, + 176, 162, 88, 64, 252, 245, 215, 95, 31, 187, 123, 247, 238, 26, 151, 197, 62, 77, 114, 85, 21, 77, 175, + 184, 130, 240, 37, 151, 80, 107, 160, 1, 202, 7, 152, 165, 10, 245, 122, 44, 31, 66, 181, 148, 4, 110, 21, + 38, 254, 251, 223, 124, 191, 108, 89, 131, 136, 222, 149, 234, 106, 2, 167, 159, 65, 233, 107, 175, 161, 4, + 252, 5, 251, 134, 60, 134, 97, 228, 74, 77, 46, 0, 205, 239, 187, 151, 102, 183, 116, 70, 105, 0, 175, 43, + 135, 211, 9, 170, 202, 132, 199, 30, 99, 247, 55, 223, 16, 150, 234, 70, 117, 69, 221, 149, 81, 43, 28, 59, + 66, 92, 128, 51, 10, 10, 218, 181, 165, 205, 189, 247, 162, 88, 172, 119, 147, 36, 9, 151, 203, 69, 175, + 55, 223, 28, 123, 224, 192, 129, 221, 58, 97, 187, 70, 178, 140, 200, 85, 225, 150, 111, 196, 40, 16, 172, + 198, 141, 122, 69, 177, 36, 73, 146, 55, 110, 220, 184, 113, 224, 192, 129, 19, 2, 86, 187, 141, 167, 30, + 140, 74, 186, 117, 67, 106, 82, 156, 151, 222, 88, 144, 157, 100, 153, 249, 99, 5, 37, 136, 239, 223, 207, + 103, 15, 62, 216, 48, 162, 119, 146, 246, 13, 225, 11, 46, 164, 164, 71, 15, 18, 78, 39, 114, 129, 100, + 229, 29, 140, 170, 214, 100, 53, 105, 11, 208, 228, 198, 27, 104, 213, 165, 107, 82, 115, 149, 227, 160, + 133, 36, 73, 184, 3, 1, 102, 190, 242, 10, 223, 78, 154, 148, 209, 196, 89, 36, 87, 102, 78, 237, 233, 223, + 147, 211, 163, 180, 30, 70, 243, 175, 25, 185, 150, 60, 248, 16, 238, 214, 173, 81, 227, 214, 246, 119, 12, + 6, 2, 76, 154, 52, 105, 217, 39, 99, 198, 204, 77, 125, 84, 159, 232, 149, 2, 133, 232, 85, 99, 70, 129, + 96, 53, 94, 104, 55, 141, 34, 12, 179, 30, 133, 81, 64, 125, 103, 208, 160, 201, 203, 150, 47, 255, 206, + 242, 62, 133, 209, 40, 254, 147, 79, 166, 213, 61, 247, 36, 189, 177, 242, 220, 46, 64, 239, 143, 101, 212, + 74, 71, 20, 189, 239, 90, 181, 138, 9, 143, 63, 158, 252, 127, 173, 52, 126, 53, 129, 92, 81, 65, 241, 85, + 87, 211, 250, 201, 39, 146, 205, 185, 117, 45, 117, 32, 127, 207, 205, 15, 9, 25, 94, 87, 42, 132, 47, 187, + 148, 54, 255, 121, 10, 53, 22, 75, 158, 244, 28, 195, 19, 14, 179, 244, 253, 247, 153, 215, 183, 111, 134, + 168, 93, 140, 228, 106, 228, 74, 20, 182, 219, 89, 119, 37, 66, 156, 255, 90, 21, 138, 175, 184, 130, 38, + 151, 89, 239, 121, 229, 116, 58, 169, 168, 172, 140, 189, 242, 234, 171, 31, 147, 236, 55, 40, 174, 235, + 90, 207, 65, 163, 150, 56, 5, 114, 213, 200, 81, 32, 88, 141, 27, 135, 101, 219, 80, 83, 83, 179, 255, 149, + 87, 94, 249, 24, 85, 181, 94, 240, 94, 85, 69, 203, 191, 222, 68, 224, 156, 95, 16, 207, 83, 187, 0, 35, + 127, 44, 81, 244, 46, 166, 10, 245, 162, 247, 111, 39, 78, 100, 230, 203, 47, 225, 9, 4, 32, 199, 78, 239, + 0, 74, 101, 37, 205, 110, 233, 76, 139, 174, 93, 77, 73, 111, 62, 156, 147, 31, 26, 140, 82, 83, 49, 5, + 130, 191, 62, 159, 210, 30, 47, 130, 170, 230, 220, 235, 10, 192, 27, 10, 177, 105, 246, 108, 166, 60, 253, + 116, 178, 117, 84, 202, 7, 78, 20, 181, 27, 217, 49, 216, 93, 119, 101, 100, 70, 24, 87, 192, 217, 170, 21, + 37, 221, 186, 37, 231, 222, 98, 78, 19, 12, 6, 121, 231, 157, 119, 38, 173, 90, 181, 234, 80, 194, 118, + 173, 114, 176, 96, 203, 96, 19, 20, 8, 150, 61, 144, 205, 182, 33, 10, 68, 82, 131, 41, 95, 124, 177, 120, + 76, 46, 4, 239, 138, 130, 228, 241, 82, 250, 200, 35, 40, 126, 95, 222, 167, 10, 225, 16, 169, 66, 50, 133, + 190, 97, 96, 94, 223, 126, 44, 121, 127, 24, 222, 6, 112, 122, 71, 85, 81, 170, 171, 105, 121, 223, 253, + 52, 251, 251, 109, 5, 35, 210, 60, 128, 153, 145, 168, 239, 103, 103, 81, 246, 218, 235, 56, 188, 94, 203, + 83, 83, 70, 112, 251, 253, 236, 221, 176, 158, 79, 255, 245, 47, 212, 72, 36, 195, 169, 221, 72, 212, 174, + 57, 181, 107, 166, 162, 249, 0, 49, 53, 27, 7, 90, 119, 233, 130, 183, 67, 199, 100, 244, 208, 66, 248, + 124, 62, 86, 174, 92, 185, 189, 255, 128, 1, 19, 56, 216, 204, 217, 200, 84, 180, 96, 203, 96, 67, 20, 8, + 86, 227, 135, 81, 20, 75, 108, 161, 35, 70, 177, 162, 64, 252, 181, 87, 95, 29, 179, 99, 199, 142, 42, 183, + 213, 14, 239, 145, 26, 130, 63, 59, 155, 150, 255, 184, 35, 237, 141, 149, 143, 143, 82, 245, 177, 110, + 208, 74, 213, 181, 116, 137, 214, 224, 118, 202, 83, 79, 179, 113, 230, 12, 188, 22, 19, 92, 67, 40, 10, + 106, 52, 66, 171, 71, 30, 165, 248, 250, 235, 146, 70, 164, 106, 254, 145, 222, 31, 2, 140, 34, 39, 49, 5, + 220, 39, 159, 68, 89, 175, 222, 56, 138, 138, 80, 98, 185, 55, 18, 117, 122, 60, 212, 86, 86, 50, 174, 107, + 55, 170, 182, 110, 37, 36, 101, 22, 118, 24, 153, 137, 26, 245, 25, 180, 35, 209, 50, 60, 7, 42, 132, 47, + 190, 136, 230, 215, 94, 139, 92, 101, 109, 81, 129, 150, 101, 120, 229, 213, 87, 63, 174, 172, 172, 220, + 43, 73, 82, 28, 99, 97, 187, 97, 122, 176, 128, 198, 143, 2, 193, 178, 15, 196, 172, 129, 88, 85, 168, 39, + 89, 242, 166, 205, 155, 55, 247, 237, 215, 111, 188, 213, 90, 44, 72, 86, 178, 181, 250, 251, 223, 241, + 159, 241, 19, 98, 74, 221, 59, 62, 95, 238, 124, 145, 100, 137, 214, 13, 70, 253, 10, 53, 146, 229, 151, + 128, 104, 148, 79, 255, 245, 32, 187, 215, 174, 193, 109, 117, 193, 129, 1, 84, 89, 134, 68, 130, 146, 103, + 158, 161, 232, 143, 151, 165, 221, 222, 11, 169, 66, 251, 192, 44, 114, 229, 234, 216, 129, 242, 62, 125, + 113, 183, 106, 141, 106, 177, 91, 184, 17, 28, 78, 39, 146, 36, 241, 249, 227, 143, 177, 245, 171, 175, 12, + 43, 6, 141, 44, 25, 180, 244, 160, 6, 59, 147, 43, 200, 76, 13, 74, 77, 155, 82, 250, 224, 67, 169, 31, + 178, 246, 78, 10, 133, 66, 140, 27, 55, 110, 254, 132, 9, 19, 22, 164, 14, 65, 203, 68, 136, 209, 43, 173, + 37, 108, 65, 123, 101, 67, 20, 8, 150, 13, 32, 220, 76, 102, 81, 44, 237, 137, 71, 187, 65, 213, 193, 131, + 7, 127, 49, 127, 254, 252, 245, 1, 171, 155, 65, 203, 50, 142, 96, 144, 146, 199, 254, 141, 226, 118, 165, + 171, 216, 242, 121, 67, 23, 29, 169, 235, 35, 122, 175, 222, 190, 157, 113, 93, 186, 18, 217, 191, 191, 65, + 42, 11, 147, 154, 28, 137, 146, 255, 190, 64, 240, 183, 191, 73, 19, 95, 173, 3, 44, 228, 223, 57, 201, 23, + 152, 109, 236, 142, 242, 114, 202, 223, 238, 131, 167, 93, 59, 148, 72, 238, 93, 218, 37, 73, 194, 237, + 247, 51, 189, 103, 79, 86, 125, 250, 25, 69, 8, 122, 67, 234, 58, 181, 231, 139, 153, 40, 212, 61, 7, 162, + 37, 70, 235, 46, 93, 240, 157, 116, 146, 229, 237, 112, 220, 110, 55, 59, 118, 236, 168, 122, 229, 213, 87, + 63, 1, 226, 41, 187, 29, 125, 67, 103, 45, 114, 37, 106, 175, 10, 176, 17, 10, 4, 203, 94, 16, 163, 215, + 34, 201, 210, 123, 99, 197, 226, 241, 120, 229, 11, 47, 190, 56, 170, 182, 182, 86, 113, 88, 220, 206, 69, + 169, 169, 33, 124, 238, 185, 180, 184, 245, 182, 116, 170, 80, 111, 21, 144, 15, 208, 235, 177, 180, 13, + 165, 78, 20, 139, 204, 77, 40, 44, 193, 247, 203, 151, 51, 254, 225, 135, 65, 85, 113, 88, 236, 77, 102, 4, + 53, 30, 71, 242, 120, 40, 123, 253, 117, 252, 191, 250, 101, 70, 75, 157, 244, 207, 228, 252, 40, 10, 56, + 28, 152, 70, 77, 90, 182, 164, 172, 119, 111, 188, 39, 159, 220, 32, 45, 112, 0, 188, 225, 48, 11, 7, 15, + 102, 94, 191, 126, 132, 209, 181, 193, 201, 162, 187, 178, 187, 168, 93, 132, 248, 244, 26, 83, 33, 252, + 187, 223, 210, 188, 83, 167, 156, 56, 229, 123, 189, 94, 122, 247, 238, 253, 233, 166, 77, 155, 54, 75, + 146, 148, 224, 96, 228, 74, 27, 70, 205, 156, 11, 209, 43, 155, 161, 64, 176, 108, 2, 221, 77, 117, 40, + 219, 134, 8, 160, 46, 88, 176, 96, 197, 176, 247, 223, 159, 26, 204, 65, 59, 23, 37, 18, 161, 213, 221, + 119, 227, 61, 245, 212, 188, 109, 163, 3, 117, 159, 206, 205, 90, 233, 120, 165, 76, 77, 86, 88, 130, 111, + 39, 79, 230, 139, 238, 221, 113, 121, 189, 57, 239, 89, 8, 160, 198, 98, 72, 62, 63, 101, 111, 246, 194, + 127, 206, 47, 210, 231, 69, 108, 230, 145, 47, 231, 197, 238, 48, 37, 87, 45, 154, 83, 222, 175, 47, 254, + 51, 206, 104, 144, 22, 56, 144, 36, 87, 171, 199, 143, 103, 234, 115, 207, 225, 231, 224, 117, 44, 86, 203, + 138, 126, 87, 102, 186, 43, 59, 194, 204, 45, 223, 209, 180, 9, 37, 143, 60, 138, 36, 73, 168, 22, 91, 98, + 4, 2, 1, 102, 207, 153, 243, 237, 187, 67, 134, 76, 77, 125, 36, 174, 219, 154, 45, 131, 81, 67, 231, 2, + 185, 178, 25, 10, 4, 203, 6, 144, 36, 73, 19, 68, 170, 194, 208, 178, 64, 102, 230, 163, 81, 64, 233, 221, + 187, 247, 103, 107, 215, 173, 219, 229, 245, 122, 45, 61, 38, 53, 145, 192, 89, 84, 68, 233, 191, 31, 71, + 113, 187, 210, 85, 133, 249, 24, 49, 169, 111, 191, 66, 253, 8, 3, 11, 223, 125, 151, 185, 125, 250, 224, + 9, 133, 26, 196, 190, 65, 173, 173, 197, 89, 92, 76, 89, 175, 94, 120, 78, 79, 234, 228, 180, 39, 243, 244, + 207, 228, 252, 40, 10, 200, 6, 179, 77, 157, 226, 34, 74, 223, 120, 131, 192, 89, 63, 107, 48, 114, 229, 9, + 5, 217, 186, 120, 17, 227, 31, 126, 8, 103, 60, 78, 192, 32, 114, 37, 250, 93, 137, 228, 202, 238, 186, 43, + 17, 233, 180, 128, 154, 92, 72, 91, 119, 251, 23, 254, 31, 253, 200, 242, 212, 160, 211, 233, 164, 166, + 166, 38, 254, 226, 139, 47, 142, 82, 100, 185, 90, 72, 13, 30, 202, 84, 84, 133, 131, 123, 193, 177, 24, 5, + 28, 62, 10, 4, 203, 158, 208, 59, 188, 27, 154, 143, 74, 146, 148, 216, 179, 103, 207, 206, 87, 94, 121, + 229, 99, 103, 74, 192, 106, 37, 148, 234, 106, 194, 255, 239, 60, 154, 255, 227, 31, 105, 37, 102, 190, 11, + 5, 140, 68, 239, 162, 30, 75, 255, 244, 31, 4, 102, 188, 248, 34, 43, 70, 141, 196, 215, 16, 246, 13, 128, + 26, 141, 226, 106, 218, 140, 242, 190, 125, 241, 254, 228, 199, 233, 116, 97, 129, 100, 29, 123, 152, 145, + 43, 181, 184, 136, 178, 183, 222, 34, 248, 255, 206, 67, 110, 128, 22, 56, 144, 180, 99, 216, 183, 97, 35, + 99, 238, 255, 39, 241, 253, 7, 123, 12, 106, 215, 174, 22, 141, 53, 243, 187, 210, 96, 215, 173, 215, 208, + 243, 74, 133, 162, 75, 46, 166, 249, 95, 254, 98, 185, 161, 40, 36, 29, 219, 7, 13, 26, 52, 121, 201, 146, + 37, 171, 37, 73, 210, 108, 25, 244, 194, 118, 189, 45, 131, 254, 144, 11, 176, 9, 10, 4, 203, 126, 56, 148, + 249, 168, 94, 240, 206, 184, 113, 227, 230, 126, 250, 233, 167, 139, 172, 246, 198, 130, 164, 30, 171, 245, + 157, 119, 225, 59, 227, 244, 140, 6, 196, 249, 156, 42, 52, 243, 199, 210, 63, 249, 251, 72, 86, 22, 122, + 84, 149, 9, 143, 255, 155, 245, 51, 166, 227, 13, 53, 12, 201, 82, 162, 81, 220, 173, 90, 83, 214, 175, 63, + 222, 159, 252, 184, 208, 28, 186, 17, 192, 168, 90, 48, 73, 174, 138, 41, 123, 235, 45, 66, 231, 255, 186, + 65, 250, 11, 2, 184, 188, 94, 34, 251, 246, 241, 201, 253, 247, 83, 241, 221, 119, 132, 178, 244, 24, 20, + 91, 225, 228, 27, 185, 130, 131, 235, 85, 66, 1, 71, 203, 22, 148, 62, 242, 40, 170, 170, 90, 238, 150, + 239, 247, 251, 89, 182, 124, 249, 214, 183, 222, 126, 123, 124, 234, 43, 245, 142, 237, 162, 169, 168, 88, + 167, 146, 143, 110, 56, 63, 8, 20, 8, 150, 125, 161, 23, 188, 139, 182, 13, 98, 20, 43, 10, 196, 123, 190, + 244, 210, 232, 239, 191, 255, 190, 210, 106, 111, 44, 173, 170, 176, 244, 137, 39, 211, 6, 164, 25, 109, + 222, 201, 159, 149, 65, 175, 199, 202, 214, 20, 90, 44, 107, 15, 72, 160, 214, 212, 48, 182, 75, 87, 190, + 255, 122, 5, 158, 28, 104, 226, 140, 160, 68, 34, 184, 91, 181, 162, 172, 95, 127, 220, 63, 249, 73, 33, + 146, 117, 12, 161, 223, 208, 101, 14, 166, 5, 203, 223, 234, 77, 240, 188, 95, 35, 87, 84, 52, 200, 177, + 56, 93, 46, 228, 120, 156, 113, 255, 234, 198, 247, 203, 151, 19, 150, 140, 175, 91, 179, 62, 131, 118, 23, + 181, 27, 70, 17, 83, 85, 131, 109, 30, 121, 4, 239, 113, 199, 161, 90, 220, 204, 217, 225, 112, 32, 203, + 50, 61, 94, 120, 97, 84, 117, 117, 245, 126, 161, 153, 115, 182, 232, 85, 129, 88, 217, 28, 5, 130, 101, + 79, 152, 69, 177, 244, 169, 194, 8, 169, 84, 225, 166, 77, 155, 54, 191, 217, 171, 215, 56, 171, 181, 88, + 144, 140, 98, 133, 126, 241, 11, 90, 222, 117, 119, 134, 1, 105, 190, 85, 21, 66, 93, 127, 44, 141, 100, + 105, 105, 148, 140, 202, 66, 33, 205, 18, 146, 32, 186, 107, 23, 159, 220, 119, 31, 7, 182, 108, 193, 157, + 3, 143, 50, 35, 104, 36, 171, 109, 191, 126, 133, 116, 225, 49, 130, 89, 228, 138, 226, 34, 74, 223, 122, + 139, 224, 249, 191, 70, 169, 108, 24, 114, 229, 112, 58, 145, 92, 46, 38, 60, 254, 56, 235, 166, 77, 167, + 72, 52, 18, 165, 174, 37, 131, 222, 142, 193, 174, 164, 202, 8, 122, 67, 209, 226, 171, 175, 166, 233, 213, + 127, 66, 206, 129, 254, 45, 20, 10, 49, 236, 253, 247, 167, 205, 156, 57, 243, 43, 50, 61, 175, 244, 4, + 203, 200, 80, 180, 112, 139, 218, 20, 5, 130, 101, 95, 212, 199, 27, 75, 188, 129, 25, 50, 100, 200, 180, + 169, 83, 167, 174, 204, 73, 85, 97, 117, 53, 45, 111, 191, 157, 192, 185, 231, 228, 181, 1, 41, 212, 21, + 189, 103, 77, 23, 146, 105, 223, 176, 111, 253, 122, 62, 185, 239, 62, 34, 21, 21, 184, 114, 64, 118, 141, + 160, 68, 34, 184, 90, 181, 162, 172, 64, 178, 26, 28, 230, 145, 171, 226, 36, 185, 58, 239, 252, 6, 139, + 92, 73, 14, 7, 46, 159, 143, 105, 61, 254, 203, 178, 209, 163, 147, 118, 12, 164, 82, 217, 212, 21, 181, + 255, 96, 116, 87, 10, 184, 218, 183, 163, 228, 225, 135, 81, 227, 214, 247, 26, 244, 122, 189, 124, 251, + 237, 183, 59, 223, 120, 227, 141, 113, 128, 44, 52, 115, 22, 201, 149, 94, 212, 158, 239, 114, 214, 31, 4, + 10, 4, 203, 254, 208, 59, 188, 27, 69, 177, 34, 146, 36, 213, 170, 170, 26, 249, 239, 127, 255, 59, 114, + 255, 254, 253, 81, 151, 197, 222, 76, 170, 44, 227, 112, 123, 40, 125, 242, 63, 72, 69, 69, 73, 109, 9, + 249, 191, 137, 27, 165, 10, 221, 212, 141, 98, 137, 246, 13, 91, 151, 44, 97, 92, 215, 46, 200, 241, 56, + 78, 139, 83, 182, 102, 72, 70, 178, 90, 83, 214, 183, 31, 158, 2, 201, 106, 16, 152, 107, 174, 138, 40, + 125, 171, 55, 161, 243, 206, 111, 48, 205, 149, 36, 73, 120, 130, 65, 190, 124, 171, 55, 243, 6, 12, 36, + 76, 102, 58, 80, 187, 78, 197, 54, 56, 34, 177, 202, 39, 114, 165, 189, 87, 0, 89, 1, 89, 146, 40, 125, + 226, 9, 60, 109, 218, 160, 198, 173, 237, 53, 40, 73, 18, 14, 73, 226, 133, 23, 94, 24, 181, 103, 207, 158, + 157, 130, 231, 149, 89, 106, 48, 159, 159, 77, 127, 112, 40, 16, 44, 123, 227, 80, 130, 119, 61, 201, 82, + 190, 249, 246, 219, 117, 125, 250, 246, 253, 204, 159, 131, 54, 46, 74, 52, 66, 224, 199, 63, 166, 85, 183, + 174, 73, 135, 60, 53, 127, 73, 150, 94, 143, 165, 17, 173, 108, 36, 75, 251, 119, 145, 4, 107, 167, 77, + 103, 252, 163, 143, 34, 57, 28, 56, 156, 206, 6, 57, 102, 37, 18, 193, 221, 186, 53, 229, 125, 251, 225, + 61, 243, 167, 25, 36, 171, 176, 154, 91, 11, 179, 200, 149, 212, 178, 5, 229, 125, 251, 38, 35, 87, 13, 68, + 174, 0, 60, 225, 48, 139, 135, 12, 97, 122, 207, 151, 8, 80, 183, 218, 85, 139, 186, 26, 181, 193, 177, + 187, 83, 187, 30, 162, 49, 114, 12, 104, 118, 107, 103, 138, 46, 186, 24, 185, 202, 250, 170, 193, 80, 40, + 196, 136, 145, 35, 231, 76, 156, 52, 105, 97, 234, 35, 145, 92, 137, 158, 87, 122, 83, 209, 2, 242, 0, 5, + 130, 149, 31, 208, 19, 172, 108, 85, 133, 234, 192, 129, 3, 39, 207, 158, 61, 123, 77, 46, 82, 133, 114, + 85, 21, 45, 110, 252, 43, 69, 255, 247, 7, 98, 106, 126, 175, 24, 102, 149, 133, 217, 244, 88, 26, 209, 42, + 2, 86, 124, 242, 9, 147, 159, 123, 182, 193, 140, 72, 225, 96, 186, 176, 237, 192, 129, 248, 83, 233, 220, + 124, 245, 47, 59, 86, 48, 139, 92, 73, 173, 90, 82, 214, 175, 63, 193, 95, 254, 170, 193, 34, 87, 0, 222, + 162, 34, 86, 126, 252, 49, 147, 254, 243, 100, 186, 178, 213, 136, 252, 27, 85, 12, 138, 186, 43, 59, 147, + 43, 241, 1, 66, 59, 39, 49, 5, 124, 167, 159, 78, 155, 7, 186, 160, 70, 34, 88, 125, 229, 123, 189, 94, + 214, 175, 95, 191, 251, 165, 151, 95, 30, 13, 36, 82, 169, 65, 125, 244, 74, 75, 15, 214, 113, 108, 183, + 252, 128, 10, 104, 112, 20, 8, 150, 253, 97, 184, 158, 99, 66, 178, 82, 109, 116, 170, 159, 235, 222, 125, + 68, 69, 69, 69, 173, 213, 169, 66, 20, 5, 85, 85, 41, 121, 252, 223, 56, 203, 74, 51, 82, 133, 249, 184, + 106, 232, 73, 150, 62, 146, 101, 70, 178, 124, 82, 202, 136, 116, 240, 187, 204, 120, 249, 101, 60, 129, + 64, 131, 153, 249, 169, 209, 40, 142, 112, 210, 119, 41, 240, 235, 243, 11, 145, 44, 11, 97, 20, 185, 138, + 43, 224, 104, 91, 78, 249, 192, 255, 225, 255, 233, 153, 13, 26, 185, 242, 134, 195, 172, 157, 50, 133, 79, + 31, 126, 8, 87, 66, 78, 147, 43, 125, 197, 160, 104, 38, 42, 166, 6, 243, 137, 92, 105, 239, 211, 169, 218, + 96, 128, 210, 167, 159, 198, 17, 12, 166, 250, 121, 90, 7, 73, 146, 112, 56, 28, 244, 120, 225, 133, 143, + 118, 237, 218, 181, 83, 146, 164, 56, 198, 209, 43, 141, 92, 21, 218, 135, 230, 33, 10, 4, 43, 63, 32, 122, + 165, 100, 213, 98, 145, 36, 89, 242, 215, 95, 127, 253, 237, 219, 111, 191, 157, 147, 84, 161, 90, 91, 139, + 183, 188, 45, 37, 79, 60, 145, 100, 122, 121, 30, 37, 169, 111, 36, 75, 111, 224, 232, 147, 32, 4, 204, + 238, 221, 155, 185, 125, 251, 224, 9, 135, 27, 196, 237, 29, 146, 231, 40, 73, 178, 222, 38, 120, 209, 239, + 147, 36, 75, 205, 223, 115, 212, 16, 48, 218, 200, 227, 10, 184, 142, 235, 72, 249, 128, 129, 248, 126, + 242, 19, 148, 234, 134, 113, 104, 7, 240, 134, 66, 108, 158, 55, 151, 49, 255, 252, 39, 82, 36, 74, 64, 71, + 240, 181, 247, 70, 105, 193, 124, 104, 131, 163, 135, 222, 173, 189, 85, 215, 174, 4, 127, 246, 179, 156, + 244, 123, 12, 135, 195, 140, 24, 49, 98, 206, 231, 159, 127, 62, 143, 131, 158, 87, 34, 185, 42, 216, 50, + 252, 0, 80, 32, 88, 249, 5, 61, 201, 50, 75, 21, 70, 1, 181, 255, 192, 129, 147, 102, 207, 158, 189, 38, + 24, 8, 88, 126, 32, 114, 117, 21, 197, 127, 184, 148, 102, 183, 118, 206, 104, 8, 157, 175, 171, 71, 125, + 42, 11, 61, 24, 147, 44, 63, 48, 245, 191, 61, 88, 60, 120, 48, 222, 6, 38, 89, 146, 219, 67, 233, 27, 111, + 18, 190, 234, 138, 100, 74, 87, 45, 68, 178, 142, 4, 102, 145, 43, 207, 105, 167, 82, 254, 206, 32, 188, + 63, 250, 81, 131, 181, 191, 129, 36, 185, 218, 182, 108, 25, 163, 239, 190, 7, 185, 162, 130, 160, 120, + 205, 145, 105, 199, 160, 23, 181, 235, 237, 24, 236, 76, 180, 12, 83, 131, 42, 20, 253, 225, 18, 90, 252, + 237, 150, 156, 88, 50, 120, 189, 94, 214, 174, 93, 187, 251, 165, 151, 94, 250, 152, 186, 169, 193, 8, 153, + 228, 202, 168, 106, 176, 112, 219, 229, 9, 10, 4, 43, 127, 144, 205, 27, 203, 40, 138, 21, 75, 164, 82, + 133, 149, 85, 85, 214, 167, 10, 85, 21, 53, 26, 161, 205, 3, 93, 240, 157, 158, 223, 46, 239, 26, 14, 69, + 178, 50, 252, 134, 132, 8, 130, 150, 182, 153, 248, 212, 83, 44, 31, 57, 2, 111, 14, 28, 247, 205, 160, + 198, 99, 72, 146, 68, 73, 207, 151, 41, 254, 235, 141, 196, 213, 100, 101, 149, 62, 26, 147, 111, 231, 202, + 74, 24, 25, 87, 198, 20, 240, 254, 252, 108, 202, 7, 254, 15, 79, 121, 57, 74, 14, 218, 174, 152, 193, 19, + 12, 178, 115, 245, 106, 70, 223, 125, 23, 209, 221, 187, 51, 91, 224, 144, 153, 26, 20, 201, 85, 62, 217, + 49, 128, 137, 143, 141, 2, 206, 178, 50, 74, 255, 253, 4, 82, 14, 220, 218, 29, 14, 7, 146, 36, 241, 252, + 243, 207, 143, 216, 181, 123, 247, 142, 84, 213, 160, 184, 246, 106, 228, 202, 200, 177, 93, 60, 236, 2, + 242, 0, 5, 130, 149, 95, 48, 74, 21, 138, 6, 164, 98, 20, 171, 70, 146, 36, 229, 235, 175, 191, 254, 182, + 87, 239, 222, 159, 230, 36, 85, 152, 72, 224, 8, 133, 40, 125, 230, 25, 212, 80, 48, 239, 83, 133, 34, 244, + 246, 13, 70, 233, 66, 63, 7, 55, 189, 128, 4, 110, 89, 230, 179, 135, 31, 97, 245, 103, 159, 225, 43, 42, + 106, 176, 99, 85, 19, 9, 72, 36, 104, 243, 204, 179, 52, 187, 251, 174, 228, 99, 245, 15, 232, 92, 29, 41, + 244, 196, 83, 33, 153, 102, 141, 43, 16, 188, 240, 2, 202, 251, 245, 199, 217, 162, 5, 74, 36, 210, 96, + 199, 228, 14, 4, 216, 183, 113, 35, 31, 221, 125, 23, 149, 91, 182, 18, 22, 211, 130, 28, 90, 212, 158, + 111, 228, 74, 123, 175, 146, 178, 100, 112, 56, 40, 125, 250, 41, 220, 229, 229, 40, 49, 107, 221, 218, 33, + 89, 53, 56, 116, 232, 208, 25, 147, 38, 79, 22, 171, 6, 107, 56, 72, 174, 180, 244, 160, 166, 147, 45, 164, + 6, 243, 24, 5, 130, 149, 159, 16, 73, 150, 222, 225, 61, 162, 27, 106, 255, 254, 253, 39, 77, 155, 62, 125, + 117, 78, 12, 72, 107, 106, 8, 158, 117, 22, 173, 31, 124, 48, 109, 221, 144, 207, 254, 75, 102, 246, 13, + 134, 70, 164, 82, 230, 134, 23, 144, 192, 25, 143, 51, 182, 107, 23, 190, 153, 48, 161, 97, 73, 150, 44, + 163, 70, 163, 180, 124, 232, 97, 90, 62, 250, 8, 113, 41, 255, 181, 115, 71, 3, 253, 60, 164, 181, 61, 42, + 132, 174, 188, 130, 210, 183, 222, 78, 138, 167, 163, 209, 6, 59, 38, 119, 32, 192, 129, 45, 91, 24, 113, + 251, 237, 236, 95, 191, 33, 221, 2, 71, 31, 53, 21, 211, 130, 63, 4, 114, 165, 61, 105, 198, 128, 230, 119, + 220, 65, 241, 69, 151, 228, 36, 93, 235, 243, 249, 88, 185, 114, 229, 247, 47, 191, 242, 202, 39, 36, 13, + 69, 245, 110, 237, 162, 176, 93, 108, 230, 92, 136, 94, 229, 41, 10, 4, 43, 255, 32, 222, 172, 90, 248, 89, + 211, 98, 25, 86, 21, 42, 138, 82, 243, 236, 179, 207, 14, 223, 187, 119, 111, 141, 213, 189, 10, 1, 228, + 202, 74, 154, 255, 245, 38, 138, 174, 248, 35, 49, 53, 255, 31, 217, 244, 162, 119, 45, 253, 162, 39, 88, + 62, 131, 17, 148, 128, 72, 148, 177, 93, 187, 178, 126, 230, 12, 188, 69, 13, 211, 28, 26, 64, 85, 20, 148, + 234, 106, 154, 221, 117, 55, 173, 95, 120, 1, 217, 235, 41, 68, 178, 12, 96, 102, 88, 25, 87, 161, 201, + 205, 55, 83, 242, 210, 203, 72, 78, 39, 106, 204, 90, 211, 202, 108, 112, 251, 253, 84, 237, 216, 193, 232, + 187, 239, 98, 239, 218, 181, 89, 35, 87, 162, 168, 61, 223, 52, 87, 34, 180, 115, 163, 165, 108, 3, 191, + 252, 37, 173, 238, 191, 31, 165, 198, 250, 116, 173, 195, 225, 32, 145, 72, 40, 207, 60, 251, 236, 240, 3, + 7, 14, 236, 78, 85, 13, 26, 9, 219, 197, 170, 193, 124, 150, 165, 22, 64, 129, 96, 229, 43, 204, 82, 133, + 134, 81, 44, 73, 146, 148, 53, 107, 214, 172, 127, 249, 149, 87, 198, 120, 189, 94, 235, 237, 2, 84, 21, + 85, 150, 41, 125, 252, 9, 220, 39, 28, 79, 60, 207, 91, 233, 64, 246, 198, 208, 98, 186, 80, 219, 252, 180, + 116, 161, 214, 183, 80, 169, 172, 100, 244, 221, 119, 179, 113, 230, 172, 164, 240, 189, 161, 160, 170, 40, + 149, 149, 52, 249, 75, 39, 74, 123, 245, 66, 45, 46, 74, 235, 231, 10, 36, 203, 188, 228, 63, 1, 52, 239, + 218, 133, 214, 255, 249, 15, 36, 18, 168, 241, 120, 131, 29, 147, 219, 239, 167, 114, 231, 14, 70, 254, + 227, 31, 236, 88, 241, 117, 157, 254, 130, 126, 33, 114, 165, 23, 181, 231, 75, 3, 103, 13, 70, 122, 184, + 184, 2, 142, 150, 45, 41, 123, 246, 89, 28, 110, 55, 170, 44, 91, 254, 189, 161, 80, 136, 1, 73, 127, 193, + 37, 169, 143, 196, 212, 160, 70, 176, 226, 194, 40, 68, 175, 126, 0, 40, 16, 172, 252, 70, 182, 84, 97, 90, + 139, 149, 122, 101, 232, 208, 161, 83, 63, 27, 63, 126, 73, 40, 7, 34, 107, 53, 22, 195, 213, 170, 37, 165, + 207, 62, 139, 236, 113, 167, 133, 212, 249, 188, 105, 155, 217, 55, 24, 85, 22, 122, 117, 70, 164, 65, 9, + 18, 7, 42, 24, 117, 247, 221, 108, 152, 117, 12, 72, 86, 69, 5, 161, 139, 47, 161, 116, 192, 64, 28, 37, + 109, 50, 138, 20, 210, 63, 214, 112, 71, 212, 40, 96, 170, 235, 241, 184, 105, 245, 124, 119, 90, 254, 243, + 1, 148, 104, 52, 39, 27, 184, 25, 92, 62, 31, 149, 59, 119, 50, 234, 31, 255, 224, 251, 229, 203, 211, 105, + 193, 180, 198, 207, 160, 191, 160, 89, 197, 96, 190, 145, 43, 237, 252, 36, 128, 146, 167, 254, 131, 239, + 196, 19, 81, 114, 144, 178, 13, 4, 2, 204, 159, 63, 127, 195, 155, 111, 190, 57, 14, 80, 179, 164, 6, 99, + 20, 170, 6, 127, 80, 40, 16, 172, 252, 184, 205, 169, 94, 0, 0, 32, 0, 73, 68, 65, 84, 133, 89, 170, 80, + 47, 120, 215, 82, 133, 209, 255, 207, 222, 121, 199, 71, 81, 231, 255, 255, 245, 217, 94, 3, 132, 16, 210, + 20, 207, 243, 252, 234, 221, 121, 63, 239, 44, 119, 246, 126, 231, 89, 238, 108, 40, 189, 99, 161, 119, 8, + 10, 210, 5, 164, 23, 33, 128, 16, 90, 66, 145, 230, 33, 69, 41, 162, 130, 116, 16, 80, 138, 136, 244, 222, + 146, 237, 109, 62, 191, 63, 102, 103, 51, 59, 59, 179, 9, 152, 217, 148, 253, 60, 31, 143, 125, 36, 68, 36, + 51, 217, 221, 153, 87, 222, 239, 215, 251, 245, 6, 224, 31, 58, 116, 232, 103, 167, 79, 159, 46, 50, 24, + 12, 229, 126, 64, 156, 203, 5, 251, 35, 143, 34, 189, 91, 55, 126, 132, 166, 154, 251, 177, 0, 121, 145, + 37, 4, 145, 198, 203, 200, 18, 42, 89, 193, 162, 34, 44, 107, 223, 30, 167, 119, 238, 76, 172, 200, 2, 95, + 69, 179, 60, 240, 0, 110, 153, 59, 15, 250, 63, 222, 149, 212, 251, 11, 149, 50, 174, 104, 138, 29, 89, 19, + 39, 161, 86, 147, 166, 252, 200, 127, 57, 79, 165, 197, 67, 111, 50, 193, 91, 84, 132, 165, 239, 189, 135, + 115, 251, 15, 68, 42, 87, 17, 161, 30, 167, 45, 88, 157, 130, 68, 165, 136, 203, 246, 62, 0, 181, 223, 126, + 27, 53, 95, 122, 89, 149, 72, 6, 157, 78, 7, 135, 195, 225, 251, 112, 192, 128, 133, 94, 175, 215, 65, 8, + 17, 119, 8, 164, 173, 65, 169, 177, 157, 81, 205, 97, 2, 171, 250, 115, 35, 1, 164, 193, 211, 167, 79, 159, + 30, 58, 108, 216, 103, 90, 173, 86, 149, 100, 113, 206, 233, 68, 157, 54, 109, 35, 171, 116, 170, 187, 31, + 11, 40, 221, 147, 37, 142, 112, 48, 75, 218, 133, 118, 2, 4, 175, 95, 199, 146, 119, 223, 197, 153, 221, + 187, 19, 47, 178, 156, 78, 24, 110, 191, 29, 57, 179, 231, 192, 252, 232, 35, 124, 37, 139, 38, 151, 200, + 82, 18, 87, 154, 156, 28, 100, 231, 231, 195, 246, 252, 243, 8, 21, 23, 3, 52, 113, 63, 9, 157, 201, 4, + 207, 245, 235, 88, 218, 238, 61, 156, 221, 187, 55, 70, 92, 9, 175, 35, 185, 202, 85, 117, 12, 18, 149, 70, + 50, 8, 190, 43, 235, 67, 255, 64, 221, 46, 93, 248, 48, 209, 114, 126, 126, 8, 33, 48, 153, 76, 24, 59, + 118, 236, 255, 14, 28, 56, 112, 132, 16, 18, 66, 116, 87, 64, 16, 89, 114, 187, 6, 89, 245, 42, 9, 96, 2, + 171, 122, 35, 151, 179, 39, 22, 89, 210, 0, 60, 55, 0, 124, 241, 197, 23, 91, 11, 10, 11, 191, 179, 171, + 112, 51, 167, 28, 7, 202, 113, 200, 250, 112, 0, 244, 191, 187, 45, 41, 242, 177, 128, 248, 158, 172, 168, + 86, 33, 98, 61, 89, 86, 2, 120, 47, 93, 194, 103, 239, 188, 141, 147, 219, 182, 37, 94, 100, 185, 221, 208, + 214, 172, 133, 236, 188, 105, 176, 191, 241, 90, 36, 43, 75, 250, 156, 85, 183, 231, 77, 46, 134, 33, 4, + 254, 198, 109, 248, 203, 61, 200, 153, 59, 23, 230, 191, 222, 151, 208, 189, 130, 64, 216, 208, 126, 241, + 34, 22, 181, 106, 133, 147, 219, 182, 199, 136, 43, 105, 91, 80, 28, 197, 32, 39, 174, 170, 186, 208, 146, + 243, 93, 5, 57, 64, 83, 39, 13, 89, 67, 134, 64, 99, 48, 168, 210, 182, 181, 90, 173, 88, 179, 118, 237, + 190, 89, 249, 249, 235, 195, 135, 33, 54, 181, 75, 3, 69, 133, 204, 43, 113, 17, 184, 186, 189, 101, 24, + 18, 152, 192, 170, 254, 72, 91, 133, 210, 61, 133, 81, 166, 247, 112, 171, 48, 56, 114, 228, 200, 101, 7, + 14, 28, 56, 163, 74, 62, 150, 223, 15, 93, 221, 186, 200, 254, 104, 56, 56, 147, 49, 105, 226, 0, 148, 130, + 72, 133, 181, 58, 17, 211, 59, 98, 151, 67, 219, 8, 224, 189, 120, 9, 139, 219, 182, 229, 61, 89, 9, 140, + 112, 0, 192, 167, 190, 107, 117, 200, 24, 241, 49, 82, 59, 117, 76, 138, 21, 72, 98, 162, 50, 174, 158, + 125, 6, 57, 249, 179, 97, 184, 245, 214, 132, 174, 190, 1, 74, 196, 213, 146, 119, 222, 198, 217, 125, 251, + 144, 34, 153, 22, 52, 75, 218, 130, 210, 53, 56, 213, 93, 92, 69, 124, 87, 26, 130, 172, 193, 67, 96, 188, + 67, 29, 223, 149, 209, 104, 196, 169, 83, 167, 174, 13, 28, 48, 96, 17, 0, 111, 248, 186, 41, 173, 92, 9, + 2, 75, 44, 174, 170, 235, 91, 132, 33, 3, 19, 88, 201, 131, 82, 0, 169, 92, 171, 48, 80, 92, 92, 124, 181, + 127, 255, 254, 11, 189, 94, 111, 80, 171, 213, 150, 251, 193, 112, 46, 23, 108, 15, 63, 140, 244, 158, 61, + 249, 85, 58, 73, 224, 199, 18, 35, 22, 89, 194, 98, 104, 113, 187, 80, 124, 179, 20, 90, 61, 54, 2, 132, + 138, 138, 176, 180, 221, 123, 248, 245, 219, 111, 19, 154, 147, 5, 0, 52, 24, 0, 245, 249, 144, 214, 189, + 7, 234, 142, 28, 1, 206, 108, 170, 150, 34, 75, 218, 191, 9, 65, 20, 195, 208, 162, 57, 178, 38, 127, 2, + 141, 205, 150, 208, 0, 81, 128, 66, 111, 182, 192, 121, 241, 34, 22, 191, 221, 54, 202, 115, 101, 4, 255, + 26, 17, 139, 43, 233, 242, 230, 234, 46, 174, 34, 23, 54, 202, 43, 154, 180, 14, 29, 80, 227, 223, 255, 86, + 165, 186, 168, 209, 240, 183, 205, 193, 67, 134, 44, 62, 123, 238, 220, 153, 112, 90, 187, 52, 95, 80, 104, + 13, 138, 125, 87, 213, 189, 80, 207, 144, 192, 4, 86, 114, 32, 237, 228, 72, 13, 239, 210, 169, 66, 55, 33, + 132, 219, 177, 115, 231, 129, 137, 147, 38, 173, 82, 99, 87, 33, 0, 132, 156, 78, 164, 181, 104, 137, 26, + 175, 190, 154, 84, 126, 44, 185, 74, 150, 88, 100, 69, 130, 72, 17, 43, 178, 172, 4, 8, 21, 21, 99, 105, + 187, 118, 56, 186, 113, 99, 194, 219, 133, 224, 56, 112, 78, 39, 106, 54, 104, 136, 236, 79, 103, 66, 147, + 153, 81, 173, 68, 150, 82, 198, 85, 72, 175, 67, 157, 254, 253, 144, 62, 96, 32, 192, 113, 9, 205, 184, 2, + 0, 189, 197, 138, 162, 211, 167, 176, 184, 77, 107, 92, 144, 49, 180, 139, 219, 130, 82, 113, 37, 53, 180, + 3, 85, 95, 92, 137, 137, 242, 93, 81, 192, 246, 204, 211, 72, 239, 208, 65, 149, 37, 206, 0, 31, 201, 144, + 159, 159, 191, 97, 237, 218, 181, 219, 195, 223, 94, 42, 174, 228, 22, 57, 51, 113, 149, 132, 48, 129, 149, + 60, 72, 125, 160, 114, 203, 160, 165, 191, 129, 209, 188, 188, 188, 181, 95, 173, 91, 247, 147, 26, 209, + 13, 224, 56, 208, 96, 16, 89, 253, 250, 193, 240, 167, 63, 69, 77, 169, 37, 203, 149, 72, 218, 46, 148, + 102, 100, 41, 139, 172, 34, 44, 121, 247, 93, 28, 94, 187, 6, 166, 26, 53, 18, 123, 208, 148, 34, 84, 92, + 12, 203, 195, 15, 35, 103, 126, 1, 12, 247, 254, 165, 90, 76, 24, 42, 101, 92, 161, 118, 42, 50, 63, 249, + 4, 169, 173, 219, 128, 115, 185, 18, 26, 195, 0, 240, 187, 5, 175, 157, 56, 129, 133, 173, 91, 225, 252, + 143, 63, 69, 133, 136, 74, 43, 87, 226, 150, 96, 117, 109, 11, 2, 242, 166, 246, 0, 7, 232, 110, 171, 135, + 172, 65, 67, 0, 162, 81, 229, 121, 18, 34, 25, 70, 143, 25, 243, 57, 0, 78, 97, 145, 179, 120, 106, 80, + 186, 107, 144, 145, 68, 48, 129, 149, 124, 148, 117, 170, 208, 77, 8, 241, 113, 28, 231, 249, 112, 192, + 128, 5, 103, 207, 158, 85, 37, 186, 129, 6, 2, 208, 214, 172, 137, 236, 17, 195, 65, 106, 214, 168, 86, + 213, 144, 120, 200, 85, 178, 148, 130, 72, 149, 68, 22, 241, 120, 176, 162, 115, 23, 28, 88, 182, 140, 111, + 23, 170, 48, 245, 25, 15, 206, 233, 132, 161, 94, 61, 228, 228, 207, 129, 253, 229, 151, 224, 231, 74, 204, + 239, 2, 85, 165, 34, 41, 125, 189, 9, 139, 129, 245, 255, 119, 39, 114, 230, 206, 131, 237, 159, 255, 66, + 200, 225, 72, 232, 164, 32, 0, 24, 109, 54, 92, 60, 116, 8, 11, 91, 180, 192, 213, 163, 191, 196, 180, 5, + 165, 209, 30, 210, 56, 6, 65, 96, 9, 84, 39, 113, 37, 124, 46, 8, 97, 206, 108, 70, 246, 136, 17, 208, 103, + 101, 129, 250, 202, 127, 207, 160, 94, 175, 71, 81, 81, 145, 167, 95, 255, 254, 133, 30, 143, 167, 152, 16, + 226, 71, 184, 226, 143, 248, 235, 112, 34, 111, 3, 74, 19, 252, 2, 98, 84, 40, 76, 96, 37, 17, 162, 55, + 183, 184, 85, 24, 183, 146, 69, 8, 9, 158, 58, 117, 234, 244, 160, 193, 131, 23, 107, 52, 154, 136, 255, + 160, 60, 225, 220, 110, 88, 238, 249, 11, 50, 6, 12, 136, 90, 52, 92, 149, 171, 33, 55, 138, 92, 37, 75, + 110, 186, 80, 44, 178, 44, 97, 145, 245, 121, 247, 238, 216, 187, 112, 1, 76, 118, 187, 42, 209, 26, 241, + 224, 60, 30, 16, 179, 25, 153, 99, 199, 163, 118, 151, 206, 8, 105, 72, 149, 18, 201, 178, 147, 130, 97, + 51, 187, 229, 185, 103, 145, 61, 191, 0, 198, 187, 238, 74, 248, 164, 32, 0, 24, 237, 118, 156, 217, 187, + 23, 139, 90, 183, 194, 245, 19, 39, 100, 67, 68, 227, 137, 171, 234, 92, 185, 2, 74, 174, 17, 33, 202, 171, + 153, 186, 125, 115, 97, 123, 232, 97, 85, 6, 15, 8, 33, 48, 24, 12, 24, 62, 124, 248, 242, 159, 126, 250, + 233, 104, 56, 146, 65, 108, 106, 151, 139, 100, 136, 50, 182, 51, 113, 149, 124, 48, 129, 149, 100, 136, + 222, 228, 145, 235, 19, 74, 214, 55, 200, 37, 188, 123, 0, 208, 213, 171, 87, 111, 155, 57, 107, 214, 70, + 85, 90, 133, 224, 253, 88, 53, 95, 125, 13, 181, 223, 125, 151, 143, 59, 166, 177, 55, 233, 234, 72, 188, + 248, 6, 177, 39, 75, 58, 37, 38, 196, 56, 88, 9, 160, 11, 4, 176, 178, 87, 111, 108, 159, 249, 41, 12, 54, + 27, 136, 10, 34, 56, 30, 52, 16, 0, 231, 247, 161, 118, 183, 238, 200, 152, 48, 1, 168, 89, 163, 74, 172, + 215, 81, 170, 132, 4, 40, 80, 235, 221, 119, 144, 53, 249, 19, 104, 83, 82, 84, 243, 242, 196, 195, 148, + 146, 130, 227, 91, 182, 96, 81, 155, 214, 112, 158, 61, 23, 105, 11, 154, 17, 95, 92, 9, 21, 171, 234, 88, + 185, 18, 35, 46, 195, 251, 41, 80, 171, 73, 99, 212, 110, 210, 148, 175, 50, 170, 128, 221, 110, 199, 194, + 69, 139, 182, 46, 88, 184, 240, 235, 240, 151, 228, 76, 237, 210, 169, 65, 86, 185, 74, 114, 152, 192, 74, + 110, 164, 173, 66, 57, 145, 229, 14, 175, 126, 224, 70, 141, 26, 181, 226, 251, 239, 191, 63, 102, 181, 90, + 85, 56, 18, 10, 234, 118, 163, 110, 215, 46, 176, 61, 243, 116, 196, 244, 158, 12, 126, 44, 169, 200, 18, + 11, 45, 185, 74, 150, 89, 228, 193, 17, 218, 133, 38, 74, 177, 118, 192, 64, 124, 55, 97, 60, 244, 102, 51, + 52, 42, 76, 126, 198, 133, 227, 192, 21, 23, 195, 254, 242, 127, 144, 61, 111, 62, 244, 119, 223, 165, 24, + 74, 90, 25, 158, 71, 37, 113, 69, 237, 54, 100, 140, 30, 141, 58, 185, 125, 129, 80, 40, 225, 102, 118, + 128, 23, 87, 71, 190, 252, 18, 159, 189, 243, 54, 252, 151, 175, 196, 44, 110, 150, 134, 209, 86, 247, 40, + 6, 1, 57, 19, 41, 191, 196, 249, 239, 200, 200, 237, 203, 183, 5, 85, 208, 49, 22, 139, 5, 251, 246, 237, + 59, 51, 116, 232, 208, 37, 0, 130, 34, 223, 149, 184, 53, 40, 21, 87, 44, 150, 129, 193, 4, 86, 50, 34, + 105, 21, 70, 178, 249, 16, 63, 229, 221, 231, 243, 249, 138, 63, 232, 215, 175, 240, 202, 149, 43, 110, + 189, 94, 95, 254, 199, 21, 10, 129, 16, 45, 178, 134, 12, 133, 254, 246, 223, 69, 181, 154, 146, 73, 100, + 73, 247, 22, 42, 85, 178, 204, 50, 127, 222, 48, 122, 12, 214, 15, 27, 10, 173, 193, 0, 141, 78, 151, 200, + 83, 0, 192, 175, 215, 49, 253, 241, 143, 200, 153, 95, 0, 235, 139, 47, 240, 66, 89, 226, 203, 170, 104, + 98, 218, 76, 225, 150, 160, 246, 206, 63, 32, 103, 222, 124, 164, 188, 81, 31, 156, 211, 153, 112, 51, 59, + 33, 4, 166, 148, 20, 236, 91, 178, 4, 75, 58, 116, 0, 87, 236, 128, 85, 38, 161, 93, 44, 172, 140, 144, 95, + 129, 19, 249, 55, 19, 122, 6, 234, 161, 36, 136, 181, 217, 217, 200, 30, 62, 2, 196, 104, 4, 13, 6, 203, + 253, 251, 10, 171, 112, 250, 190, 255, 126, 65, 113, 113, 241, 21, 25, 223, 149, 88, 96, 137, 141, 237, + 172, 122, 197, 96, 2, 43, 89, 137, 35, 178, 100, 99, 27, 192, 139, 44, 238, 200, 145, 35, 191, 12, 30, 60, + 120, 177, 94, 175, 87, 199, 143, 229, 247, 65, 159, 145, 129, 236, 81, 163, 193, 217, 109, 85, 202, 207, + 243, 91, 41, 173, 146, 37, 183, 187, 208, 44, 250, 179, 153, 0, 54, 0, 91, 166, 207, 192, 170, 220, 92, 16, + 66, 160, 85, 97, 48, 161, 52, 56, 183, 27, 26, 155, 13, 153, 227, 39, 34, 173, 103, 15, 4, 245, 250, 152, + 231, 177, 34, 42, 89, 82, 161, 206, 129, 23, 127, 126, 10, 88, 159, 255, 23, 110, 41, 40, 132, 233, 158, + 123, 192, 57, 18, 187, 246, 6, 0, 136, 70, 3, 131, 205, 134, 237, 51, 103, 226, 127, 221, 187, 67, 227, + 245, 194, 34, 105, 11, 74, 115, 174, 140, 40, 17, 224, 201, 34, 174, 34, 227, 207, 28, 192, 153, 77, 200, + 26, 57, 18, 134, 122, 183, 129, 170, 16, 38, 74, 8, 129, 201, 104, 196, 136, 17, 35, 150, 255, 240, 195, + 15, 135, 8, 33, 114, 145, 12, 82, 83, 59, 243, 93, 49, 34, 48, 129, 149, 196, 200, 136, 44, 185, 0, 82, + 169, 208, 194, 242, 21, 43, 54, 207, 158, 61, 251, 27, 181, 252, 88, 156, 203, 5, 235, 125, 247, 35, 115, + 192, 0, 197, 196, 240, 234, 138, 82, 37, 75, 218, 46, 20, 139, 42, 105, 37, 203, 14, 96, 247, 162, 69, 88, + 222, 169, 19, 130, 94, 47, 116, 38, 83, 34, 79, 1, 0, 64, 253, 126, 80, 191, 15, 169, 29, 58, 33, 107, 90, + 30, 52, 89, 25, 21, 234, 203, 146, 126, 79, 10, 254, 117, 21, 212, 105, 81, 187, 123, 55, 100, 78, 156, 12, + 77, 5, 249, 173, 52, 90, 45, 244, 102, 51, 190, 25, 51, 6, 107, 7, 12, 128, 129, 227, 248, 182, 47, 98, + 147, 253, 5, 97, 37, 142, 98, 72, 38, 113, 37, 136, 226, 32, 128, 186, 31, 124, 0, 251, 99, 143, 129, 83, + 97, 137, 51, 192, 251, 174, 22, 45, 94, 188, 109, 126, 65, 193, 198, 240, 151, 220, 136, 157, 26, 84, 74, + 107, 167, 76, 92, 49, 152, 192, 98, 0, 209, 2, 75, 26, 221, 32, 222, 83, 40, 172, 210, 9, 141, 24, 57, 114, + 217, 214, 173, 91, 127, 85, 197, 143, 5, 32, 228, 116, 160, 230, 27, 245, 81, 187, 221, 123, 178, 166, 247, + 234, 124, 229, 82, 50, 190, 139, 119, 23, 138, 171, 24, 130, 200, 138, 8, 45, 2, 164, 16, 224, 167, 181, + 107, 177, 168, 109, 27, 184, 46, 95, 134, 94, 165, 176, 216, 184, 112, 28, 56, 71, 49, 172, 79, 61, 141, + 156, 5, 139, 96, 122, 244, 97, 4, 184, 146, 231, 82, 64, 237, 106, 150, 92, 123, 41, 192, 1, 154, 204, 186, + 200, 154, 54, 13, 181, 59, 119, 1, 13, 248, 43, 196, 111, 165, 213, 235, 65, 180, 90, 172, 253, 240, 67, + 124, 61, 126, 124, 84, 165, 74, 156, 115, 165, 228, 185, 170, 206, 226, 74, 76, 148, 169, 29, 64, 173, 86, + 173, 144, 218, 184, 137, 106, 166, 118, 139, 197, 130, 189, 123, 247, 158, 30, 60, 120, 240, 98, 240, 190, + 43, 105, 229, 74, 41, 80, 180, 178, 216, 12, 25, 149, 0, 38, 176, 146, 28, 133, 232, 6, 177, 31, 43, 42, + 27, 11, 188, 233, 221, 239, 241, 120, 138, 115, 251, 246, 157, 127, 233, 210, 37, 167, 26, 249, 88, 130, + 233, 61, 189, 75, 87, 216, 159, 127, 30, 126, 26, 235, 26, 173, 206, 87, 177, 178, 76, 23, 202, 121, 115, + 196, 213, 172, 26, 4, 56, 177, 109, 59, 22, 180, 104, 129, 171, 199, 142, 193, 168, 82, 197, 177, 52, 56, + 167, 19, 186, 204, 44, 100, 207, 152, 137, 90, 237, 222, 67, 80, 163, 137, 84, 37, 197, 168, 241, 124, 42, + 69, 48, 152, 30, 121, 24, 57, 11, 22, 193, 250, 244, 51, 224, 138, 139, 249, 178, 72, 130, 209, 25, 141, 8, + 250, 253, 88, 209, 165, 11, 182, 207, 153, 3, 27, 162, 197, 148, 116, 90, 80, 186, 91, 176, 186, 139, 43, + 185, 214, 160, 159, 3, 172, 207, 60, 133, 140, 94, 189, 64, 61, 30, 85, 90, 185, 66, 222, 85, 110, 110, + 238, 252, 98, 135, 227, 90, 216, 119, 21, 101, 151, 64, 108, 160, 40, 39, 122, 176, 214, 32, 3, 0, 19, 88, + 12, 196, 109, 21, 250, 17, 45, 178, 196, 126, 172, 208, 209, 163, 71, 127, 253, 112, 192, 0, 213, 242, 177, + 4, 147, 113, 214, 176, 161, 48, 254, 249, 79, 145, 22, 83, 178, 228, 99, 201, 137, 44, 97, 173, 142, 82, + 187, 80, 44, 178, 140, 224, 69, 214, 165, 67, 135, 80, 208, 172, 41, 78, 237, 216, 145, 248, 213, 58, 97, + 168, 207, 11, 80, 138, 58, 189, 115, 145, 57, 101, 10, 72, 221, 116, 190, 154, 5, 117, 90, 134, 114, 126, + 171, 32, 7, 4, 53, 26, 212, 106, 247, 30, 178, 103, 204, 132, 46, 43, 91, 181, 246, 82, 105, 232, 45, 22, + 184, 174, 92, 193, 226, 182, 109, 241, 227, 170, 85, 176, 19, 229, 202, 149, 82, 20, 67, 50, 136, 43, 177, + 65, 84, 8, 126, 205, 30, 54, 28, 208, 106, 85, 25, 66, 208, 104, 52, 208, 235, 245, 24, 50, 100, 200, 146, + 3, 63, 254, 120, 132, 16, 194, 65, 185, 53, 200, 124, 87, 140, 184, 48, 129, 197, 0, 16, 185, 40, 136, 43, + 241, 241, 2, 72, 133, 11, 13, 86, 173, 90, 245, 253, 180, 233, 211, 215, 169, 229, 199, 162, 126, 63, 116, + 53, 106, 33, 103, 244, 104, 144, 244, 58, 252, 40, 61, 152, 200, 146, 107, 23, 70, 60, 89, 162, 150, 161, + 17, 128, 157, 0, 174, 179, 231, 176, 160, 85, 43, 28, 90, 181, 10, 166, 148, 148, 132, 7, 146, 2, 188, 96, + 14, 57, 138, 97, 251, 231, 191, 112, 203, 162, 197, 48, 63, 241, 24, 47, 178, 100, 210, 223, 127, 211, 247, + 145, 124, 94, 210, 18, 204, 64, 102, 94, 30, 234, 244, 238, 3, 128, 242, 162, 175, 2, 48, 218, 108, 184, + 124, 244, 103, 20, 54, 107, 134, 19, 91, 183, 162, 134, 52, 134, 1, 177, 134, 118, 97, 200, 65, 188, 184, + 185, 186, 139, 43, 225, 115, 193, 212, 78, 82, 83, 145, 51, 102, 44, 116, 117, 234, 168, 146, 212, 14, 240, + 123, 6, 103, 206, 156, 185, 233, 179, 37, 75, 190, 13, 127, 73, 122, 205, 19, 251, 174, 148, 118, 13, 50, + 24, 0, 152, 192, 98, 196, 34, 22, 89, 114, 209, 13, 145, 223, 230, 132, 124, 172, 209, 163, 71, 127, 190, + 126, 195, 134, 131, 170, 153, 222, 61, 110, 152, 238, 186, 27, 89, 35, 71, 34, 100, 48, 68, 218, 75, 76, + 100, 197, 46, 136, 142, 185, 81, 135, 63, 183, 17, 62, 66, 97, 105, 199, 142, 216, 54, 243, 83, 24, 172, + 214, 196, 103, 101, 133, 225, 156, 78, 232, 178, 179, 145, 53, 253, 83, 164, 118, 237, 130, 144, 129, 159, + 50, 20, 87, 179, 110, 198, 200, 34, 253, 127, 56, 240, 226, 45, 192, 1, 230, 167, 158, 68, 206, 162, 197, + 176, 61, 247, 79, 132, 28, 142, 132, 71, 48, 0, 0, 194, 49, 12, 199, 191, 255, 30, 5, 77, 155, 225, 242, + 145, 35, 145, 116, 118, 185, 182, 160, 212, 115, 149, 108, 226, 42, 146, 132, 204, 241, 203, 182, 179, 70, + 12, 135, 233, 207, 127, 86, 117, 137, 243, 183, 223, 126, 123, 116, 228, 199, 31, 47, 3, 16, 10, 251, 77, + 229, 86, 225, 8, 213, 43, 161, 114, 197, 170, 87, 12, 89, 152, 192, 98, 68, 144, 73, 121, 23, 139, 44, 241, + 84, 161, 88, 100, 249, 130, 193, 160, 187, 111, 223, 190, 133, 199, 143, 31, 191, 106, 82, 105, 98, 45, + 228, 112, 32, 229, 233, 103, 80, 183, 127, 191, 200, 58, 29, 233, 13, 181, 58, 95, 217, 110, 84, 100, 153, + 73, 244, 106, 29, 33, 245, 93, 31, 12, 98, 205, 128, 129, 88, 55, 108, 24, 52, 122, 61, 180, 42, 228, 153, + 149, 5, 234, 245, 130, 6, 131, 168, 221, 165, 43, 178, 242, 243, 161, 251, 253, 237, 145, 96, 210, 155, + 121, 78, 149, 114, 146, 66, 38, 3, 106, 247, 236, 129, 172, 188, 105, 208, 101, 100, 84, 200, 202, 27, 128, + 143, 97, 48, 217, 237, 216, 183, 100, 9, 22, 182, 105, 13, 207, 133, 11, 49, 233, 236, 210, 182, 160, 32, + 172, 164, 226, 170, 58, 134, 136, 74, 137, 24, 66, 57, 254, 226, 147, 222, 247, 125, 216, 255, 245, 188, + 106, 207, 159, 209, 104, 196, 233, 211, 167, 175, 247, 201, 205, 157, 239, 243, 249, 156, 146, 188, 43, + 177, 192, 18, 42, 87, 82, 99, 59, 19, 87, 140, 24, 152, 192, 98, 68, 33, 241, 99, 137, 119, 21, 202, 166, + 188, 131, 23, 89, 193, 179, 103, 207, 158, 205, 237, 219, 119, 190, 207, 231, 11, 234, 84, 10, 184, 12, 57, + 28, 72, 109, 210, 20, 169, 111, 183, 77, 170, 117, 58, 2, 241, 166, 11, 101, 61, 89, 136, 77, 125, 183, 16, + 192, 10, 96, 243, 180, 105, 88, 222, 185, 19, 2, 94, 47, 244, 102, 115, 2, 207, 66, 4, 199, 129, 115, 56, + 96, 121, 232, 97, 100, 47, 92, 132, 148, 55, 94, 71, 128, 34, 198, 0, 31, 175, 154, 37, 39, 178, 57, 202, + 155, 161, 117, 255, 247, 7, 100, 207, 153, 139, 212, 142, 157, 64, 131, 65, 213, 218, 74, 165, 161, 209, + 233, 160, 55, 153, 240, 237, 132, 9, 88, 209, 189, 27, 224, 114, 195, 38, 19, 195, 32, 13, 17, 77, 54, 113, + 21, 99, 4, 165, 188, 154, 73, 109, 221, 10, 181, 91, 182, 84, 77, 92, 105, 181, 90, 132, 66, 161, 80, 110, + 110, 110, 193, 201, 147, 39, 79, 137, 246, 12, 42, 45, 114, 102, 19, 131, 140, 50, 193, 4, 22, 67, 9, 165, + 86, 161, 56, 27, 43, 226, 79, 32, 132, 208, 45, 91, 182, 236, 27, 49, 98, 196, 10, 147, 201, 164, 142, 199, + 135, 82, 80, 143, 7, 117, 123, 244, 68, 202, 75, 47, 38, 221, 100, 33, 80, 122, 132, 67, 76, 37, 11, 177, + 49, 14, 230, 112, 140, 195, 129, 47, 86, 97, 65, 203, 22, 184, 126, 250, 116, 133, 77, 24, 2, 124, 238, + 153, 214, 110, 71, 221, 143, 71, 161, 238, 232, 81, 32, 105, 169, 138, 6, 248, 120, 213, 45, 241, 46, 193, + 148, 134, 13, 144, 179, 96, 33, 204, 247, 63, 80, 97, 83, 130, 0, 63, 41, 72, 57, 14, 95, 244, 205, 197, + 250, 81, 163, 96, 226, 104, 84, 198, 149, 52, 134, 193, 132, 232, 105, 65, 113, 75, 48, 169, 196, 21, 248, + 0, 88, 251, 243, 255, 66, 221, 222, 125, 84, 155, 24, 36, 132, 192, 108, 54, 227, 227, 143, 63, 254, 223, + 55, 223, 126, 187, 39, 28, 38, 26, 207, 212, 206, 140, 237, 140, 50, 195, 4, 22, 35, 134, 50, 172, 210, + 137, 105, 21, 134, 31, 116, 246, 156, 57, 235, 10, 11, 11, 183, 218, 85, 154, 86, 19, 188, 51, 153, 67, + 135, 193, 116, 255, 253, 81, 225, 149, 201, 36, 178, 226, 173, 214, 81, 170, 100, 137, 111, 226, 194, 132, + 225, 233, 221, 123, 48, 191, 113, 35, 156, 220, 190, 29, 166, 148, 20, 160, 2, 204, 239, 0, 248, 133, 209, + 110, 55, 82, 222, 168, 143, 236, 69, 159, 193, 242, 212, 19, 178, 6, 120, 64, 94, 104, 9, 241, 11, 164, + 110, 58, 50, 38, 78, 64, 221, 143, 134, 67, 99, 177, 86, 72, 112, 168, 128, 193, 98, 133, 235, 234, 85, 44, + 110, 219, 22, 187, 22, 44, 140, 196, 48, 148, 53, 227, 42, 217, 42, 87, 194, 231, 194, 80, 130, 233, 175, + 247, 34, 235, 163, 225, 252, 215, 85, 242, 204, 217, 237, 118, 44, 90, 180, 104, 251, 140, 79, 63, 253, 50, + 252, 237, 163, 170, 243, 136, 53, 182, 71, 133, 137, 2, 76, 92, 49, 148, 97, 2, 139, 33, 75, 41, 41, 239, + 114, 209, 13, 238, 176, 41, 52, 56, 104, 240, 224, 197, 223, 111, 221, 170, 206, 82, 104, 240, 147, 133, + 90, 171, 21, 217, 99, 198, 64, 123, 91, 61, 85, 199, 253, 43, 51, 101, 77, 125, 23, 223, 204, 45, 64, 212, + 132, 97, 10, 1, 28, 167, 207, 160, 176, 101, 11, 252, 176, 120, 17, 140, 118, 27, 52, 154, 138, 49, 191, + 131, 82, 112, 14, 7, 244, 183, 220, 130, 204, 105, 51, 80, 167, 223, 7, 160, 118, 43, 223, 50, 164, 177, + 207, 105, 228, 133, 25, 174, 90, 89, 255, 245, 28, 114, 62, 91, 2, 251, 127, 254, 11, 206, 229, 2, 13, 4, + 42, 224, 36, 192, 155, 217, 237, 41, 56, 119, 96, 63, 230, 55, 110, 132, 95, 54, 111, 70, 74, 156, 24, 6, + 185, 182, 160, 32, 176, 164, 98, 186, 58, 139, 43, 225, 34, 19, 224, 0, 93, 189, 91, 145, 61, 118, 28, 180, + 41, 41, 170, 5, 192, 90, 173, 86, 108, 223, 190, 253, 196, 135, 3, 6, 44, 2, 16, 32, 132, 248, 80, 182, 61, + 131, 172, 114, 197, 40, 19, 76, 96, 49, 202, 66, 89, 163, 27, 220, 132, 16, 191, 219, 237, 46, 238, 213, + 171, 215, 252, 179, 103, 207, 22, 25, 141, 70, 85, 14, 136, 243, 122, 97, 184, 229, 22, 228, 140, 27, 7, + 212, 172, 153, 116, 147, 133, 2, 82, 145, 37, 215, 46, 20, 170, 89, 194, 132, 154, 216, 84, 45, 76, 24, + 194, 229, 198, 138, 238, 61, 176, 113, 196, 8, 104, 12, 186, 10, 51, 191, 3, 0, 245, 249, 64, 3, 1, 212, + 108, 251, 54, 178, 23, 46, 134, 233, 225, 127, 240, 237, 96, 209, 115, 204, 161, 100, 73, 51, 173, 89, 3, + 233, 67, 134, 32, 243, 147, 169, 37, 70, 246, 10, 186, 239, 9, 102, 246, 31, 191, 248, 31, 10, 154, 53, + 197, 213, 163, 191, 68, 197, 48, 152, 17, 22, 185, 165, 84, 174, 164, 109, 65, 169, 208, 170, 14, 200, 77, + 12, 6, 57, 0, 53, 107, 32, 123, 220, 120, 24, 234, 213, 3, 231, 241, 168, 242, 189, 141, 70, 35, 206, 158, + 61, 91, 212, 189, 71, 143, 57, 110, 183, 187, 72, 198, 212, 238, 6, 91, 133, 195, 248, 141, 48, 129, 197, + 80, 68, 38, 229, 93, 46, 186, 65, 90, 82, 119, 19, 66, 130, 199, 143, 31, 63, 217, 39, 55, 183, 32, 24, 12, + 134, 212, 50, 189, 115, 46, 23, 44, 127, 253, 27, 178, 62, 30, 137, 144, 104, 161, 112, 50, 139, 44, 37, + 243, 123, 100, 173, 14, 74, 12, 213, 98, 145, 101, 9, 255, 249, 155, 201, 159, 96, 89, 199, 78, 240, 57, + 157, 48, 84, 196, 122, 29, 1, 142, 3, 87, 92, 12, 227, 157, 255, 135, 172, 89, 179, 81, 187, 119, 47, 112, + 54, 43, 252, 225, 85, 59, 65, 142, 247, 232, 152, 159, 124, 2, 57, 159, 125, 134, 26, 77, 155, 130, 243, + 122, 43, 204, 200, 14, 240, 107, 111, 116, 38, 19, 190, 157, 48, 30, 75, 59, 116, 68, 240, 122, 81, 36, + 134, 65, 186, 180, 89, 46, 64, 84, 42, 174, 4, 170, 155, 176, 2, 148, 197, 21, 103, 208, 35, 107, 212, 40, + 152, 255, 118, 31, 56, 151, 75, 149, 239, 173, 211, 233, 16, 12, 6, 67, 185, 125, 251, 22, 28, 63, 126, + 252, 164, 130, 169, 93, 188, 10, 39, 8, 150, 119, 197, 184, 9, 152, 192, 98, 196, 69, 97, 149, 142, 176, + 175, 80, 105, 33, 180, 135, 16, 66, 191, 249, 230, 155, 61, 195, 134, 13, 83, 207, 244, 142, 112, 124, 195, + 191, 158, 71, 198, 160, 129, 252, 175, 152, 21, 184, 80, 184, 34, 137, 231, 201, 18, 218, 78, 98, 145, 37, + 158, 48, 20, 155, 223, 237, 4, 248, 113, 245, 106, 204, 111, 218, 4, 23, 143, 28, 129, 169, 130, 146, 223, + 5, 56, 175, 7, 8, 113, 168, 221, 190, 3, 114, 22, 241, 213, 44, 15, 5, 66, 53, 82, 144, 62, 104, 32, 178, + 166, 127, 10, 253, 109, 191, 171, 208, 170, 21, 0, 232, 205, 102, 4, 188, 94, 172, 232, 218, 5, 235, 71, + 141, 134, 81, 180, 176, 89, 26, 195, 32, 205, 184, 18, 214, 31, 37, 163, 184, 18, 183, 121, 131, 0, 234, + 14, 28, 8, 251, 63, 255, 5, 206, 81, 172, 202, 247, 38, 132, 192, 100, 50, 97, 248, 136, 17, 203, 55, 109, + 218, 36, 53, 181, 187, 16, 189, 10, 71, 136, 100, 96, 121, 87, 140, 155, 130, 9, 44, 70, 169, 72, 242, 177, + 34, 225, 202, 136, 227, 199, 10, 63, 232, 156, 185, 115, 215, 205, 153, 51, 103, 179, 90, 166, 119, 32, 28, + 223, 208, 168, 49, 106, 119, 233, 12, 63, 248, 214, 81, 178, 139, 44, 105, 86, 150, 32, 178, 164, 230, 119, + 139, 164, 146, 37, 236, 48, 188, 248, 211, 65, 204, 107, 212, 16, 63, 126, 177, 18, 166, 148, 148, 10, 11, + 37, 5, 0, 202, 133, 16, 42, 46, 134, 241, 206, 59, 145, 61, 99, 38, 50, 135, 14, 193, 173, 243, 230, 163, + 86, 243, 150, 128, 223, 15, 234, 173, 152, 68, 118, 1, 163, 221, 142, 43, 199, 126, 65, 65, 243, 102, 216, + 183, 226, 115, 229, 181, 55, 50, 123, 5, 197, 226, 74, 16, 88, 2, 73, 35, 174, 194, 113, 12, 105, 93, 187, + 160, 86, 163, 198, 170, 102, 149, 217, 237, 118, 204, 156, 53, 235, 187, 252, 252, 252, 117, 225, 67, 144, + 171, 92, 73, 91, 131, 44, 239, 138, 113, 83, 168, 211, 187, 97, 84, 103, 132, 14, 92, 8, 37, 214, 16, 241, + 106, 180, 200, 47, 226, 132, 16, 45, 165, 148, 12, 30, 50, 100, 201, 109, 183, 221, 86, 231, 137, 39, 158, + 184, 211, 161, 198, 197, 147, 82, 112, 46, 23, 210, 59, 117, 70, 232, 242, 37, 92, 159, 87, 0, 3, 248, 35, + 147, 78, 96, 85, 119, 8, 74, 110, 98, 194, 19, 67, 74, 123, 16, 128, 208, 104, 223, 15, 33, 128, 251, 234, + 53, 44, 237, 208, 17, 23, 15, 29, 198, 99, 29, 59, 66, 163, 213, 34, 168, 146, 225, 184, 44, 112, 94, 47, + 160, 209, 32, 181, 81, 99, 208, 64, 0, 33, 149, 170, 28, 101, 133, 104, 52, 48, 218, 108, 56, 180, 102, 13, + 86, 230, 246, 129, 251, 202, 85, 164, 144, 18, 1, 37, 136, 41, 19, 41, 169, 30, 138, 215, 222, 40, 249, + 173, 128, 234, 255, 154, 21, 139, 171, 0, 5, 106, 53, 107, 138, 58, 29, 59, 243, 109, 65, 149, 244, 139, + 221, 110, 199, 134, 13, 27, 14, 13, 31, 62, 124, 9, 98, 147, 218, 165, 190, 43, 89, 83, 59, 131, 113, 35, + 176, 10, 22, 163, 76, 72, 126, 107, 147, 51, 189, 139, 163, 27, 196, 166, 119, 159, 223, 239, 119, 246, + 232, 217, 115, 238, 225, 195, 135, 47, 153, 85, 10, 181, 164, 28, 7, 234, 247, 35, 163, 223, 135, 176, 255, + 251, 121, 248, 105, 172, 97, 34, 89, 174, 144, 210, 27, 181, 216, 151, 85, 150, 24, 7, 113, 242, 187, 145, + 227, 240, 245, 132, 9, 88, 210, 174, 29, 220, 215, 175, 195, 160, 210, 100, 104, 153, 225, 56, 126, 66, + 176, 2, 133, 30, 0, 104, 13, 6, 104, 13, 6, 108, 26, 59, 22, 139, 219, 189, 7, 127, 88, 92, 73, 215, 20, + 89, 72, 116, 117, 176, 52, 51, 59, 80, 61, 197, 149, 52, 70, 69, 120, 111, 250, 41, 96, 127, 241, 5, 100, + 124, 208, 143, 247, 207, 169, 148, 87, 102, 177, 88, 112, 248, 240, 225, 139, 189, 122, 245, 154, 239, 243, + 249, 92, 146, 137, 65, 165, 61, 131, 210, 72, 6, 102, 108, 103, 220, 16, 76, 96, 49, 202, 140, 66, 116, + 131, 224, 199, 82, 204, 199, 34, 132, 4, 47, 92, 184, 112, 190, 123, 143, 30, 179, 139, 138, 138, 220, 6, + 131, 65, 157, 227, 11, 6, 1, 66, 144, 57, 98, 36, 44, 15, 253, 3, 254, 36, 245, 99, 1, 209, 83, 103, 165, + 173, 214, 137, 248, 178, 36, 49, 14, 194, 215, 236, 4, 56, 248, 213, 87, 152, 219, 160, 1, 78, 239, 218, + 85, 97, 203, 162, 43, 11, 6, 171, 21, 222, 162, 34, 44, 109, 223, 30, 27, 198, 142, 133, 33, 24, 42, 213, + 111, 37, 22, 87, 82, 129, 85, 221, 197, 149, 152, 40, 113, 197, 1, 150, 71, 31, 70, 214, 240, 17, 124, 136, + 112, 40, 168, 202, 247, 52, 24, 12, 184, 122, 245, 170, 187, 107, 183, 110, 115, 46, 92, 188, 120, 129, 16, + 18, 68, 108, 229, 74, 26, 201, 32, 92, 219, 196, 173, 65, 85, 142, 143, 81, 125, 97, 2, 139, 113, 67, 40, + 152, 222, 149, 252, 88, 130, 105, 212, 69, 8, 225, 246, 237, 219, 119, 36, 183, 111, 223, 133, 0, 168, 86, + 37, 79, 15, 245, 251, 161, 49, 155, 249, 49, 239, 63, 253, 49, 18, 68, 154, 140, 149, 44, 160, 116, 243, + 123, 204, 146, 104, 130, 152, 80, 82, 51, 248, 188, 172, 107, 199, 142, 97, 126, 179, 166, 216, 158, 63, + 11, 122, 139, 165, 66, 163, 28, 42, 2, 18, 94, 214, 124, 106, 215, 46, 204, 105, 208, 0, 63, 173, 93, 139, + 20, 18, 93, 165, 18, 87, 174, 228, 22, 54, 39, 91, 229, 10, 144, 79, 227, 15, 112, 128, 241, 47, 247, 32, + 123, 236, 120, 104, 76, 38, 213, 50, 203, 194, 215, 25, 174, 79, 159, 62, 133, 7, 14, 28, 56, 34, 153, 24, + 20, 155, 218, 197, 123, 6, 5, 113, 197, 194, 68, 25, 191, 9, 38, 176, 24, 55, 140, 204, 82, 232, 82, 247, + 21, 134, 255, 76, 215, 172, 89, 179, 117, 212, 232, 209, 43, 45, 22, 139, 106, 85, 16, 234, 243, 65, 151, + 86, 7, 57, 147, 38, 67, 91, 239, 150, 164, 174, 100, 1, 101, 19, 89, 81, 129, 164, 136, 174, 102, 9, 66, + 193, 70, 0, 226, 246, 224, 139, 254, 31, 226, 243, 30, 221, 225, 119, 187, 43, 190, 101, 152, 32, 180, 122, + 61, 244, 22, 11, 182, 231, 207, 226, 243, 173, 126, 225, 243, 173, 196, 226, 84, 106, 102, 47, 77, 92, 9, + 84, 199, 140, 43, 1, 185, 56, 134, 0, 7, 232, 110, 255, 29, 114, 38, 77, 130, 46, 53, 21, 156, 74, 209, 26, + 194, 26, 156, 161, 195, 134, 125, 254, 213, 186, 117, 219, 195, 19, 131, 30, 68, 11, 43, 177, 184, 146, + 230, 93, 85, 204, 126, 37, 70, 181, 129, 9, 44, 198, 111, 69, 220, 46, 20, 118, 117, 41, 45, 133, 246, 0, + 160, 121, 121, 121, 107, 102, 207, 158, 189, 69, 205, 201, 66, 206, 227, 134, 225, 182, 219, 144, 51, 121, + 10, 52, 233, 117, 162, 42, 89, 226, 3, 79, 22, 74, 155, 48, 148, 6, 146, 202, 181, 12, 133, 188, 44, 27, + 128, 61, 75, 150, 98, 110, 195, 6, 56, 179, 119, 111, 181, 111, 25, 26, 44, 86, 248, 221, 110, 124, 222, + 163, 7, 86, 245, 255, 16, 196, 237, 137, 228, 91, 137, 91, 130, 210, 137, 76, 113, 12, 131, 120, 74, 176, + 186, 79, 10, 10, 40, 137, 43, 146, 153, 129, 236, 79, 62, 129, 254, 150, 91, 85, 11, 18, 5, 120, 83, 251, + 167, 51, 103, 126, 147, 159, 159, 175, 180, 6, 71, 108, 106, 247, 65, 33, 169, 157, 85, 175, 24, 55, 11, + 19, 88, 140, 155, 66, 33, 132, 52, 158, 31, 203, 5, 209, 58, 157, 193, 67, 134, 44, 254, 234, 171, 175, 14, + 170, 42, 178, 92, 46, 152, 255, 252, 103, 100, 79, 156, 8, 164, 164, 36, 109, 16, 169, 64, 188, 64, 82, + 193, 252, 46, 120, 178, 162, 214, 235, 72, 132, 131, 176, 44, 250, 210, 161, 195, 152, 215, 164, 49, 118, + 204, 158, 13, 189, 217, 12, 173, 74, 222, 186, 138, 130, 104, 52, 48, 165, 164, 224, 204, 190, 189, 152, + 219, 176, 1, 246, 44, 89, 2, 43, 74, 218, 127, 114, 226, 74, 26, 195, 144, 108, 1, 162, 2, 74, 226, 10, + 181, 106, 34, 123, 210, 100, 152, 238, 186, 91, 181, 32, 81, 128, 23, 87, 43, 87, 174, 220, 63, 116, 232, + 208, 165, 136, 158, 24, 20, 170, 87, 210, 214, 160, 180, 114, 149, 76, 151, 6, 134, 74, 48, 129, 197, 184, + 105, 202, 104, 122, 151, 75, 122, 247, 249, 253, 126, 119, 143, 158, 61, 231, 254, 240, 195, 15, 103, 212, + 218, 89, 8, 0, 33, 167, 19, 150, 135, 30, 70, 214, 184, 177, 224, 204, 38, 38, 178, 36, 159, 75, 39, 12, + 149, 132, 150, 69, 166, 101, 104, 15, 175, 216, 89, 217, 175, 31, 150, 119, 237, 10, 111, 113, 113, 181, + 105, 25, 106, 13, 6, 232, 140, 38, 108, 155, 57, 19, 243, 26, 53, 194, 165, 67, 135, 249, 149, 55, 10, 226, + 74, 218, 18, 20, 42, 87, 226, 252, 146, 100, 240, 91, 1, 177, 226, 138, 130, 79, 105, 167, 54, 43, 178, 39, + 76, 128, 245, 254, 251, 193, 57, 157, 170, 125, 127, 171, 213, 138, 93, 187, 118, 157, 236, 211, 167, 207, + 252, 80, 40, 228, 17, 77, 12, 74, 197, 149, 120, 98, 144, 237, 25, 100, 148, 59, 76, 96, 49, 126, 19, 165, + 44, 133, 22, 74, 239, 98, 211, 187, 80, 201, 10, 92, 189, 122, 245, 74, 215, 174, 93, 103, 159, 61, 123, + 182, 200, 100, 50, 169, 118, 140, 92, 113, 49, 236, 207, 62, 135, 204, 145, 35, 17, 210, 105, 17, 226, 162, + 199, 198, 129, 228, 19, 89, 74, 19, 134, 114, 129, 164, 241, 150, 69, 91, 8, 239, 205, 250, 97, 197, 10, + 204, 121, 243, 77, 28, 223, 250, 61, 31, 76, 170, 169, 186, 151, 22, 163, 205, 6, 207, 245, 235, 88, 214, + 185, 19, 86, 13, 24, 0, 184, 61, 176, 41, 8, 43, 169, 184, 18, 114, 174, 196, 109, 65, 97, 105, 179, 64, + 178, 136, 43, 177, 161, 157, 51, 153, 144, 53, 106, 52, 108, 79, 60, 137, 144, 138, 65, 162, 102, 179, 25, + 199, 143, 31, 191, 210, 177, 83, 167, 217, 69, 197, 197, 215, 8, 33, 1, 136, 174, 59, 144, 159, 24, 20, 7, + 137, 50, 113, 197, 40, 55, 170, 238, 85, 144, 81, 105, 144, 92, 140, 202, 106, 122, 119, 19, 66, 66, 71, + 127, 249, 229, 68, 231, 46, 93, 230, 184, 92, 46, 191, 94, 197, 169, 180, 144, 195, 129, 26, 255, 125, 5, + 25, 67, 135, 33, 72, 16, 169, 100, 37, 171, 200, 2, 228, 205, 239, 210, 188, 44, 217, 150, 33, 162, 133, + 134, 144, 254, 126, 245, 216, 49, 20, 52, 111, 129, 77, 227, 198, 129, 104, 181, 208, 171, 40, 154, 213, + 64, 163, 213, 194, 148, 146, 130, 95, 190, 249, 6, 179, 223, 172, 143, 253, 43, 87, 194, 22, 103, 74, 80, + 92, 205, 43, 203, 218, 27, 32, 121, 196, 149, 120, 191, 96, 72, 171, 69, 198, 176, 97, 72, 121, 241, 69, + 132, 138, 213, 11, 135, 53, 24, 12, 40, 42, 42, 114, 119, 233, 218, 117, 206, 233, 211, 167, 79, 203, 236, + 24, 148, 155, 24, 140, 49, 181, 51, 113, 197, 40, 47, 152, 192, 98, 148, 11, 225, 139, 146, 146, 31, 75, + 168, 98, 73, 227, 27, 220, 132, 16, 110, 199, 142, 29, 7, 250, 190, 255, 254, 2, 141, 70, 163, 90, 124, 3, + 40, 69, 200, 225, 64, 205, 6, 13, 144, 254, 225, 128, 164, 222, 91, 40, 70, 201, 151, 37, 8, 5, 241, 14, + 195, 168, 188, 44, 153, 106, 150, 141, 0, 58, 191, 31, 235, 199, 140, 65, 97, 171, 86, 184, 114, 252, 120, + 149, 49, 192, 235, 195, 1, 184, 27, 62, 254, 24, 133, 173, 91, 227, 250, 241, 19, 124, 75, 16, 34, 81, 37, + 60, 36, 126, 171, 178, 238, 20, 172, 252, 63, 133, 155, 71, 174, 114, 21, 20, 246, 11, 14, 29, 130, 154, + 111, 188, 129, 80, 81, 145, 106, 223, 95, 167, 211, 129, 227, 184, 80, 143, 158, 61, 11, 246, 238, 221, + 123, 136, 16, 194, 33, 126, 229, 74, 46, 76, 148, 137, 43, 70, 185, 194, 4, 22, 163, 188, 145, 138, 44, 33, + 233, 93, 220, 42, 20, 183, 11, 61, 0, 232, 202, 149, 43, 183, 12, 29, 58, 116, 133, 201, 100, 82, 175, 189, + 68, 41, 56, 167, 19, 169, 173, 90, 33, 173, 87, 79, 254, 234, 202, 68, 86, 169, 190, 44, 161, 101, 40, 8, + 10, 241, 148, 97, 84, 176, 38, 120, 241, 145, 66, 128, 99, 155, 55, 99, 118, 253, 250, 216, 179, 96, 65, + 165, 54, 192, 11, 217, 86, 151, 142, 28, 193, 252, 230, 205, 240, 245, 196, 137, 208, 7, 2, 178, 83, 130, + 66, 4, 131, 32, 40, 149, 90, 130, 201, 228, 183, 2, 226, 47, 111, 78, 31, 240, 33, 82, 27, 54, 82, 181, 45, + 168, 209, 104, 96, 48, 24, 48, 112, 224, 192, 165, 235, 215, 175, 223, 41, 89, 224, 172, 148, 119, 37, 180, + 5, 163, 242, 174, 24, 140, 242, 132, 9, 44, 70, 185, 33, 227, 199, 226, 16, 29, 66, 42, 180, 11, 163, 46, + 126, 66, 124, 195, 172, 252, 252, 175, 166, 76, 157, 186, 209, 102, 179, 169, 87, 245, 160, 20, 156, 195, + 129, 180, 246, 29, 144, 214, 189, 27, 47, 178, 100, 150, 67, 39, 27, 114, 190, 44, 241, 132, 161, 224, 205, + 138, 170, 100, 161, 164, 146, 37, 53, 192, 167, 16, 192, 127, 237, 26, 150, 247, 234, 133, 101, 93, 58, + 195, 125, 245, 42, 140, 118, 59, 191, 228, 176, 146, 160, 51, 26, 161, 51, 153, 176, 99, 206, 108, 204, + 126, 235, 45, 156, 220, 190, 35, 18, 28, 42, 151, 202, 46, 174, 214, 201, 173, 189, 73, 70, 113, 37, 70, + 44, 174, 2, 0, 234, 244, 238, 133, 212, 86, 173, 17, 114, 58, 85, 219, 47, 72, 8, 129, 213, 106, 197, 216, + 177, 99, 215, 20, 20, 22, 110, 68, 73, 28, 131, 11, 209, 191, 196, 41, 153, 218, 153, 239, 138, 161, 26, + 108, 217, 51, 163, 92, 161, 148, 82, 194, 171, 35, 225, 122, 43, 64, 36, 15, 141, 232, 163, 134, 16, 162, + 161, 148, 154, 71, 142, 28, 185, 60, 45, 45, 205, 222, 224, 173, 183, 238, 47, 86, 203, 175, 17, 94, 14, + 157, 214, 161, 35, 56, 151, 11, 87, 167, 230, 69, 142, 80, 56, 40, 138, 228, 186, 57, 10, 8, 231, 46, 124, + 46, 22, 12, 98, 67, 124, 244, 147, 23, 254, 72, 163, 255, 187, 134, 240, 2, 100, 223, 231, 255, 195, 169, + 93, 187, 241, 207, 126, 31, 224, 238, 231, 95, 64, 208, 231, 69, 72, 165, 228, 238, 178, 64, 8, 129, 193, + 102, 195, 245, 83, 39, 241, 213, 144, 33, 56, 176, 102, 109, 100, 42, 82, 156, 7, 22, 121, 136, 190, 46, + 94, 119, 35, 8, 170, 100, 21, 86, 74, 149, 171, 0, 128, 180, 30, 221, 81, 251, 189, 118, 224, 28, 14, 213, + 196, 21, 192, 199, 49, 204, 154, 53, 107, 243, 132, 137, 19, 191, 0, 192, 133, 227, 24, 196, 109, 65, 241, + 196, 160, 120, 13, 14, 51, 181, 51, 84, 135, 9, 44, 70, 185, 35, 17, 89, 194, 181, 55, 8, 101, 129, 69, 0, + 144, 176, 200, 194, 251, 239, 191, 95, 152, 154, 154, 106, 125, 238, 217, 103, 239, 118, 168, 213, 90, 224, + 56, 112, 94, 47, 210, 123, 247, 1, 0, 38, 178, 68, 72, 69, 22, 81, 248, 92, 92, 229, 210, 2, 208, 18, 64, + 75, 163, 171, 57, 194, 215, 157, 103, 206, 96, 241, 123, 237, 240, 183, 183, 222, 194, 147, 221, 187, 195, + 86, 167, 14, 124, 42, 142, 234, 43, 161, 53, 24, 160, 211, 27, 112, 96, 249, 114, 124, 53, 108, 40, 138, + 46, 92, 132, 157, 68, 79, 78, 70, 218, 161, 36, 250, 107, 66, 181, 74, 42, 174, 164, 254, 170, 100, 123, + 205, 68, 196, 21, 229, 203, 67, 117, 186, 118, 65, 90, 199, 78, 124, 206, 149, 138, 186, 37, 37, 37, 5, 43, + 62, 255, 252, 135, 65, 131, 7, 127, 6, 32, 16, 71, 92, 73, 39, 6, 197, 171, 112, 152, 184, 98, 168, 6, 107, + 17, 50, 84, 161, 148, 248, 6, 63, 228, 77, 239, 46, 66, 136, 223, 239, 247, 187, 186, 117, 235, 54, 119, + 231, 206, 157, 39, 108, 54, 155, 122, 7, 25, 10, 129, 134, 69, 86, 173, 214, 173, 16, 160, 0, 71, 163, 13, + 25, 201, 122, 229, 149, 138, 4, 165, 150, 161, 32, 70, 228, 166, 12, 45, 162, 255, 102, 37, 128, 137, 82, + 236, 88, 176, 0, 249, 111, 214, 199, 207, 27, 55, 192, 104, 183, 39, 110, 159, 33, 33, 48, 218, 108, 112, + 95, 185, 130, 229, 221, 186, 96, 73, 231, 206, 112, 95, 184, 136, 20, 81, 59, 80, 56, 110, 43, 162, 91, + 130, 66, 59, 80, 120, 136, 69, 101, 178, 86, 174, 98, 222, 220, 28, 16, 160, 64, 237, 119, 223, 70, 90, + 167, 206, 188, 184, 226, 212, 219, 52, 99, 183, 219, 177, 105, 211, 166, 163, 189, 122, 245, 154, 31, 12, + 6, 189, 225, 172, 43, 23, 98, 91, 131, 98, 83, 187, 120, 98, 144, 63, 126, 38, 174, 24, 42, 194, 4, 22, 67, + 53, 100, 38, 11, 227, 249, 177, 196, 147, 133, 129, 162, 162, 162, 171, 237, 59, 116, 200, 63, 124, 248, + 240, 69, 139, 197, 162, 222, 49, 10, 34, 43, 183, 47, 106, 54, 105, 12, 31, 229, 127, 19, 79, 102, 211, + 187, 128, 92, 101, 70, 131, 232, 9, 67, 113, 75, 77, 154, 254, 46, 246, 102, 9, 95, 79, 33, 73, 82, 167, + 199, 0, 0, 32, 0, 73, 68, 65, 84, 192, 245, 95, 143, 163, 176, 117, 27, 172, 204, 237, 3, 79, 113, 49, 140, + 106, 122, 238, 192, 87, 173, 12, 22, 11, 14, 172, 252, 31, 102, 190, 254, 26, 246, 44, 91, 206, 11, 41, + 165, 68, 118, 153, 84, 118, 177, 153, 93, 60, 41, 40, 254, 217, 36, 131, 184, 18, 35, 174, 92, 5, 0, 164, + 190, 243, 54, 210, 123, 231, 130, 122, 189, 170, 138, 43, 155, 205, 134, 61, 123, 246, 156, 238, 212, 185, + 115, 190, 219, 237, 46, 38, 132, 248, 17, 27, 199, 32, 13, 19, 149, 6, 137, 178, 21, 56, 12, 213, 97, 2, + 139, 145, 8, 196, 66, 171, 180, 117, 58, 66, 16, 105, 232, 220, 185, 115, 231, 218, 119, 232, 48, 75, 237, + 32, 82, 26, 10, 1, 193, 32, 50, 6, 12, 68, 173, 38, 141, 225, 167, 177, 198, 247, 100, 190, 18, 203, 137, + 44, 185, 41, 195, 168, 228, 119, 200, 79, 25, 154, 193, 199, 57, 152, 56, 14, 59, 10, 10, 145, 255, 198, + 235, 56, 184, 118, 45, 244, 22, 75, 249, 79, 26, 18, 2, 163, 221, 14, 247, 149, 43, 88, 209, 173, 43, 62, + 235, 208, 17, 174, 179, 231, 80, 67, 36, 162, 196, 213, 54, 105, 90, 189, 52, 130, 33, 153, 171, 86, 128, + 66, 229, 138, 242, 149, 171, 212, 119, 222, 70, 122, 159, 92, 112, 94, 47, 255, 126, 82, 9, 139, 197, 130, + 163, 71, 143, 94, 238, 208, 177, 227, 172, 171, 87, 175, 94, 38, 132, 4, 17, 91, 185, 18, 239, 24, 148, 21, + 87, 170, 29, 32, 131, 33, 130, 9, 44, 134, 170, 196, 153, 44, 20, 226, 27, 196, 34, 43, 234, 66, 73, 8, + 225, 126, 254, 249, 231, 95, 59, 118, 236, 152, 95, 84, 84, 228, 54, 26, 141, 234, 29, 103, 48, 8, 26, 12, + 162, 238, 128, 129, 168, 25, 71, 100, 37, 235, 149, 89, 90, 161, 137, 39, 178, 98, 86, 236, 144, 216, 41, + 67, 161, 154, 85, 116, 226, 36, 22, 189, 243, 14, 86, 244, 232, 14, 215, 165, 75, 48, 217, 237, 229, 82, + 205, 210, 25, 141, 208, 155, 205, 216, 183, 108, 89, 164, 106, 101, 65, 116, 213, 42, 34, 174, 100, 170, + 86, 44, 130, 33, 26, 89, 67, 187, 88, 92, 245, 238, 195, 87, 174, 84, 20, 87, 38, 147, 9, 231, 206, 159, + 47, 110, 215, 190, 253, 204, 83, 167, 78, 157, 13, 7, 137, 70, 236, 5, 136, 142, 99, 144, 19, 87, 44, 239, + 138, 145, 80, 152, 192, 98, 168, 78, 25, 226, 27, 196, 73, 239, 226, 11, 165, 139, 16, 66, 119, 239, 217, + 115, 168, 115, 231, 206, 115, 189, 94, 175, 223, 160, 98, 158, 18, 13, 6, 1, 137, 200, 146, 122, 178, 146, + 29, 165, 244, 119, 105, 219, 80, 174, 154, 37, 23, 231, 96, 11, 11, 155, 61, 75, 150, 98, 230, 107, 175, + 98, 247, 194, 5, 208, 153, 140, 55, 157, 2, 47, 44, 104, 190, 126, 230, 52, 150, 180, 111, 135, 165, 93, + 186, 196, 84, 173, 228, 150, 52, 11, 126, 49, 165, 224, 208, 100, 110, 9, 198, 23, 87, 239, 32, 189, 79, + 46, 168, 207, 167, 106, 229, 202, 104, 52, 162, 168, 168, 200, 221, 190, 93, 187, 89, 135, 15, 31, 62, 38, + 73, 105, 23, 11, 43, 182, 99, 144, 81, 105, 96, 2, 139, 145, 16, 202, 96, 122, 151, 174, 211, 17, 123, 178, + 232, 183, 223, 125, 183, 183, 71, 207, 158, 133, 28, 199, 113, 58, 157, 122, 195, 175, 130, 200, 202, 24, + 48, 16, 181, 218, 182, 134, 159, 2, 65, 214, 46, 140, 66, 90, 193, 17, 79, 212, 9, 43, 118, 20, 119, 25, + 202, 8, 45, 161, 154, 229, 190, 112, 17, 203, 123, 245, 198, 130, 54, 109, 112, 241, 231, 159, 249, 157, + 134, 55, 144, 236, 175, 55, 155, 161, 209, 233, 176, 61, 63, 31, 51, 95, 123, 29, 7, 86, 175, 129, 133, 40, + 120, 173, 80, 34, 174, 202, 178, 242, 38, 25, 171, 86, 82, 162, 66, 68, 41, 80, 187, 99, 7, 164, 247, 238, + 13, 170, 114, 91, 208, 96, 48, 192, 235, 245, 250, 59, 118, 236, 56, 119, 15, 159, 210, 46, 4, 137, 74, + 219, 130, 226, 214, 32, 19, 87, 140, 10, 135, 9, 44, 70, 194, 144, 136, 44, 177, 241, 93, 108, 122, 151, + 134, 4, 10, 158, 44, 186, 102, 205, 154, 173, 125, 223, 127, 127, 145, 78, 167, 131, 106, 43, 117, 16, 110, + 23, 6, 2, 168, 219, 247, 3, 164, 190, 251, 14, 155, 46, 148, 65, 174, 101, 24, 111, 202, 80, 169, 106, 36, + 22, 90, 86, 2, 216, 0, 28, 217, 248, 53, 102, 189, 241, 6, 54, 141, 31, 7, 46, 20, 130, 193, 106, 141, 27, + 80, 170, 209, 233, 96, 74, 73, 193, 185, 31, 15, 160, 160, 69, 115, 252, 175, 127, 127, 4, 174, 94, 229, + 171, 86, 144, 175, 90, 73, 197, 149, 56, 223, 74, 16, 87, 226, 188, 47, 241, 121, 39, 11, 138, 211, 130, 0, + 106, 119, 239, 142, 58, 61, 122, 170, 238, 185, 210, 233, 116, 8, 133, 66, 161, 110, 221, 187, 23, 108, + 222, 178, 101, 111, 41, 226, 74, 90, 185, 98, 89, 87, 140, 10, 133, 229, 96, 49, 18, 202, 13, 4, 145, 202, + 61, 44, 75, 150, 44, 249, 214, 106, 177, 24, 7, 13, 26, 244, 170, 215, 235, 69, 72, 165, 139, 59, 13, 133, + 0, 73, 78, 150, 158, 2, 90, 77, 116, 78, 150, 112, 224, 201, 138, 92, 48, 169, 248, 207, 226, 189, 124, 81, + 185, 89, 36, 92, 33, 18, 229, 102, 249, 195, 95, 215, 2, 240, 186, 92, 88, 55, 122, 12, 14, 174, 94, 141, + 167, 123, 245, 198, 31, 158, 124, 18, 65, 191, 31, 33, 191, 191, 228, 123, 19, 2, 131, 213, 10, 207, 245, + 235, 248, 102, 226, 4, 108, 155, 57, 19, 126, 143, 55, 18, 24, 42, 158, 114, 140, 248, 195, 72, 108, 96, + 168, 220, 14, 193, 100, 22, 86, 64, 252, 245, 55, 105, 61, 186, 71, 66, 122, 213, 156, 22, 212, 233, 116, + 208, 104, 52, 180, 87, 175, 94, 11, 191, 252, 242, 203, 237, 225, 47, 203, 137, 43, 165, 172, 43, 182, 192, + 153, 81, 161, 48, 129, 197, 72, 56, 97, 145, 5, 68, 95, 199, 229, 4, 149, 70, 252, 103, 66, 8, 40, 165, + 150, 57, 115, 231, 174, 183, 88, 44, 198, 62, 125, 250, 188, 224, 241, 120, 192, 169, 116, 145, 167, 161, + 16, 224, 241, 32, 189, 79, 46, 52, 54, 27, 46, 143, 26, 205, 95, 174, 53, 209, 55, 224, 100, 13, 36, 21, + 144, 254, 28, 148, 158, 72, 105, 149, 43, 34, 180, 68, 34, 75, 44, 192, 12, 0, 46, 252, 116, 16, 5, 173, + 90, 225, 222, 215, 95, 195, 19, 157, 187, 160, 230, 45, 183, 192, 239, 116, 66, 163, 215, 67, 103, 48, 224, + 240, 186, 117, 216, 48, 98, 56, 206, 253, 124, 20, 102, 240, 173, 70, 57, 97, 101, 32, 209, 129, 161, 98, + 113, 37, 28, 143, 248, 56, 229, 206, 47, 89, 136, 39, 174, 234, 244, 239, 135, 212, 214, 109, 84, 23, 87, + 90, 173, 22, 58, 157, 14, 253, 250, 245, 91, 186, 108, 249, 242, 205, 0, 40, 33, 68, 169, 114, 37, 245, 93, + 69, 137, 43, 6, 163, 162, 96, 2, 139, 81, 209, 136, 61, 89, 98, 228, 66, 196, 9, 33, 132, 80, 74, 45, 83, + 243, 242, 86, 91, 44, 22, 67, 231, 206, 157, 159, 117, 185, 92, 80, 235, 23, 84, 202, 113, 128, 219, 141, + 180, 142, 29, 65, 180, 90, 92, 30, 49, 146, 137, 44, 5, 228, 170, 89, 74, 66, 75, 108, 142, 23, 170, 89, + 58, 90, 82, 77, 242, 163, 68, 104, 249, 57, 14, 123, 22, 127, 134, 99, 95, 127, 141, 199, 59, 119, 193, + 189, 13, 26, 192, 113, 254, 60, 54, 141, 30, 141, 31, 150, 47, 135, 134, 82, 212, 32, 177, 38, 251, 136, + 200, 146, 17, 87, 101, 169, 90, 65, 230, 207, 213, 29, 57, 113, 21, 228, 128, 144, 86, 139, 244, 15, 251, + 163, 86, 243, 22, 224, 84, 220, 45, 8, 240, 226, 202, 100, 50, 97, 192, 128, 1, 43, 10, 10, 11, 55, 32, + 190, 184, 98, 158, 43, 70, 165, 133, 9, 44, 70, 133, 32, 105, 21, 2, 209, 2, 75, 46, 227, 82, 42, 178, 204, + 99, 198, 142, 93, 161, 215, 235, 117, 29, 58, 116, 120, 210, 225, 112, 168, 42, 178, 168, 211, 133, 180, + 246, 29, 160, 177, 88, 112, 113, 192, 64, 222, 148, 197, 68, 86, 12, 82, 145, 165, 84, 146, 20, 87, 179, + 196, 66, 75, 43, 169, 102, 9, 95, 215, 3, 240, 93, 186, 140, 213, 31, 124, 128, 131, 203, 151, 193, 113, + 254, 60, 46, 159, 62, 3, 11, 0, 29, 137, 174, 74, 69, 194, 65, 37, 237, 64, 165, 201, 64, 177, 16, 20, 159, + 71, 178, 161, 40, 174, 244, 58, 100, 124, 52, 28, 53, 223, 122, 11, 161, 226, 98, 85, 197, 149, 70, 163, + 129, 209, 104, 196, 71, 31, 125, 180, 42, 127, 246, 236, 175, 80, 34, 174, 164, 19, 198, 44, 235, 138, 81, + 233, 97, 2, 139, 81, 97, 196, 17, 89, 194, 38, 96, 165, 142, 19, 4, 145, 53, 98, 228, 200, 229, 70, 147, + 73, 223, 182, 117, 235, 71, 28, 78, 167, 106, 34, 11, 148, 34, 228, 112, 160, 86, 139, 86, 208, 88, 44, + 184, 208, 183, 47, 16, 8, 50, 145, 37, 131, 248, 103, 33, 252, 89, 90, 205, 146, 250, 178, 162, 90, 134, + 40, 169, 102, 9, 149, 172, 32, 248, 74, 84, 8, 192, 249, 157, 187, 64, 0, 212, 32, 177, 57, 92, 226, 170, + 149, 156, 215, 74, 248, 251, 210, 133, 213, 114, 199, 159, 76, 136, 223, 53, 130, 66, 9, 114, 0, 103, 54, + 33, 107, 244, 104, 164, 188, 244, 50, 66, 69, 69, 170, 30, 131, 70, 163, 129, 213, 106, 197, 168, 209, 163, + 191, 204, 155, 54, 109, 21, 248, 229, 205, 130, 152, 114, 66, 222, 119, 37, 136, 43, 65, 96, 49, 83, 59, + 163, 210, 192, 4, 22, 163, 66, 145, 17, 89, 194, 100, 33, 32, 211, 34, 20, 127, 45, 44, 178, 48, 104, 208, + 160, 197, 26, 66, 72, 235, 214, 173, 31, 86, 179, 146, 5, 74, 193, 57, 29, 168, 249, 86, 3, 16, 171, 21, + 231, 123, 244, 0, 117, 123, 160, 99, 34, 75, 22, 185, 106, 150, 248, 115, 105, 187, 80, 44, 182, 116, 36, + 186, 101, 40, 220, 65, 57, 0, 28, 137, 254, 255, 163, 170, 87, 18, 131, 187, 180, 29, 200, 170, 86, 177, + 72, 43, 87, 130, 184, 162, 53, 82, 144, 61, 126, 60, 108, 79, 61, 195, 87, 174, 84, 68, 16, 87, 19, 38, 76, + 216, 48, 97, 194, 132, 47, 192, 139, 43, 113, 0, 177, 52, 239, 138, 77, 12, 50, 42, 61, 76, 96, 49, 42, 28, + 133, 201, 66, 97, 165, 14, 16, 123, 111, 142, 124, 30, 54, 190, 211, 65, 131, 7, 127, 102, 181, 90, 13, 13, + 26, 52, 184, 95, 109, 145, 21, 42, 46, 70, 141, 23, 95, 134, 214, 106, 197, 217, 206, 157, 16, 184, 94, 12, + 61, 19, 89, 178, 72, 171, 89, 194, 148, 161, 92, 235, 80, 106, 116, 215, 9, 190, 42, 90, 226, 92, 14, 73, + 254, 173, 72, 5, 139, 68, 87, 171, 196, 237, 64, 230, 181, 82, 70, 90, 185, 18, 218, 130, 154, 58, 105, + 200, 154, 60, 25, 150, 191, 255, 3, 33, 135, 250, 226, 202, 98, 177, 96, 194, 196, 137, 27, 70, 141, 30, + 189, 28, 64, 40, 44, 174, 132, 138, 149, 80, 189, 146, 86, 174, 196, 226, 138, 249, 174, 24, 149, 14, 150, + 131, 197, 168, 20, 148, 18, 68, 42, 206, 200, 146, 91, 169, 227, 231, 56, 206, 151, 219, 183, 111, 225, + 194, 133, 11, 119, 217, 203, 105, 221, 74, 60, 66, 142, 98, 88, 159, 124, 10, 57, 51, 62, 133, 166, 110, + 58, 2, 92, 236, 216, 18, 187, 202, 151, 32, 173, 20, 41, 229, 102, 73, 195, 73, 133, 64, 80, 171, 240, 128, + 228, 17, 254, 186, 120, 169, 180, 56, 145, 93, 186, 234, 70, 43, 115, 44, 76, 92, 69, 183, 5, 181, 245, + 110, 69, 118, 254, 108, 88, 30, 252, 59, 56, 135, 67, 213, 99, 32, 132, 192, 98, 177, 96, 226, 164, 73, 27, + 71, 141, 26, 181, 2, 188, 184, 146, 205, 194, 67, 252, 105, 65, 38, 174, 24, 149, 14, 86, 193, 98, 84, 26, + 226, 100, 100, 1, 241, 59, 58, 132, 16, 130, 96, 48, 136, 62, 185, 185, 5, 20, 64, 131, 183, 222, 186, 79, + 213, 74, 22, 0, 206, 225, 128, 249, 254, 7, 144, 147, 159, 143, 51, 237, 218, 33, 240, 235, 113, 232, 194, + 191, 178, 8, 191, 185, 176, 74, 86, 9, 55, 226, 205, 210, 130, 191, 131, 106, 193, 139, 164, 136, 131, 153, + 68, 87, 192, 162, 218, 138, 80, 110, 7, 178, 170, 85, 52, 114, 149, 171, 0, 7, 24, 254, 120, 55, 178, 38, + 127, 2, 195, 109, 183, 241, 211, 130, 42, 66, 8, 129, 221, 110, 199, 244, 233, 211, 191, 27, 53, 106, 148, + 184, 114, 37, 252, 18, 37, 87, 185, 82, 156, 24, 4, 111, 136, 87, 245, 152, 25, 140, 27, 129, 85, 176, 24, + 149, 10, 153, 180, 119, 161, 51, 36, 77, 123, 23, 87, 178, 156, 8, 87, 178, 130, 193, 160, 55, 55, 55, 183, + 112, 65, 130, 42, 89, 156, 211, 9, 227, 93, 119, 35, 103, 246, 28, 232, 239, 249, 51, 171, 100, 149, 1, + 105, 159, 55, 94, 53, 43, 102, 221, 14, 162, 171, 85, 210, 170, 149, 156, 169, 157, 85, 173, 162, 81, 18, + 87, 166, 191, 63, 128, 156, 89, 249, 48, 220, 122, 43, 159, 115, 165, 34, 26, 141, 6, 118, 187, 29, 51, + 103, 206, 220, 50, 104, 240, 224, 37, 0, 130, 162, 202, 149, 216, 208, 238, 66, 201, 142, 65, 197, 253, + 130, 96, 111, 51, 70, 37, 132, 9, 44, 70, 165, 67, 36, 178, 132, 11, 168, 32, 178, 132, 118, 161, 116, 103, + 161, 184, 93, 232, 11, 6, 131, 222, 62, 125, 250, 20, 36, 76, 100, 185, 92, 48, 100, 103, 35, 103, 230, 44, + 152, 31, 125, 4, 126, 142, 79, 113, 96, 34, 43, 62, 114, 109, 195, 40, 95, 21, 74, 38, 1, 77, 113, 30, 74, + 194, 138, 133, 134, 70, 35, 205, 46, 224, 192, 191, 78, 253, 28, 96, 253, 215, 63, 145, 61, 109, 6, 180, + 169, 169, 224, 60, 30, 85, 143, 67, 240, 92, 77, 156, 52, 233, 235, 15, 7, 12, 88, 4, 192, 79, 8, 241, 33, + 250, 189, 236, 68, 172, 231, 202, 143, 104, 43, 30, 19, 87, 140, 74, 13, 19, 88, 140, 74, 137, 68, 100, 41, + 45, 135, 150, 10, 44, 39, 248, 189, 133, 190, 80, 40, 228, 203, 205, 205, 45, 88, 176, 112, 225, 238, 132, + 136, 44, 143, 7, 218, 154, 53, 145, 61, 101, 42, 236, 47, 191, 4, 63, 5, 66, 50, 34, 139, 221, 9, 162, 145, + 171, 102, 137, 43, 90, 226, 9, 65, 105, 128, 104, 188, 138, 149, 220, 170, 155, 100, 22, 87, 98, 34, 38, + 71, 10, 248, 41, 80, 163, 193, 155, 200, 154, 48, 1, 26, 179, 25, 212, 231, 83, 245, 123, 11, 211, 130, 19, + 39, 78, 220, 56, 114, 228, 200, 101, 0, 2, 18, 113, 37, 109, 11, 250, 16, 221, 22, 20, 155, 218, 133, 211, + 97, 48, 42, 37, 204, 131, 197, 168, 10, 200, 249, 177, 132, 143, 178, 247, 77, 193, 147, 149, 155, 155, 91, + 192, 133, 66, 180, 97, 195, 134, 247, 57, 213, 204, 201, 2, 64, 125, 62, 16, 131, 1, 153, 99, 198, 66, 151, + 86, 27, 215, 102, 205, 230, 47, 255, 154, 232, 3, 101, 190, 172, 88, 148, 2, 74, 195, 63, 190, 136, 56, + 149, 62, 123, 138, 65, 105, 146, 191, 147, 204, 40, 173, 190, 9, 1, 168, 221, 161, 61, 210, 186, 118, 3, + 13, 4, 64, 3, 126, 249, 127, 160, 156, 136, 76, 11, 78, 152, 176, 97, 212, 232, 209, 130, 161, 93, 16, 87, + 114, 57, 87, 114, 109, 65, 86, 185, 98, 84, 25, 152, 192, 98, 84, 90, 132, 42, 86, 216, 248, 46, 21, 89, + 114, 247, 218, 168, 207, 5, 145, 213, 187, 79, 159, 249, 110, 183, 219, 215, 166, 77, 27, 117, 115, 178, 0, + 208, 64, 0, 68, 171, 69, 122, 255, 1, 208, 214, 73, 199, 229, 143, 63, 6, 229, 16, 49, 191, 51, 145, 165, + 140, 156, 9, 94, 44, 188, 148, 158, 53, 37, 149, 205, 126, 190, 113, 196, 149, 78, 135, 58, 253, 62, 64, + 173, 22, 45, 85, 223, 43, 8, 240, 235, 111, 204, 102, 51, 38, 76, 156, 184, 97, 116, 137, 184, 18, 162, 24, + 156, 146, 143, 210, 182, 32, 243, 92, 49, 170, 36, 76, 96, 49, 170, 18, 210, 233, 194, 120, 247, 85, 65, + 156, 129, 82, 138, 129, 131, 6, 45, 166, 148, 162, 109, 219, 182, 15, 59, 157, 78, 213, 22, 68, 3, 252, + 146, 104, 234, 241, 160, 118, 251, 142, 208, 213, 73, 199, 197, 254, 253, 16, 240, 120, 89, 32, 105, 25, + 17, 139, 42, 225, 207, 226, 143, 101, 249, 255, 25, 202, 171, 111, 96, 183, 35, 115, 228, 8, 216, 95, 124, + 137, 143, 97, 80, 57, 217, 64, 216, 45, 56, 108, 216, 176, 213, 121, 211, 166, 173, 70, 73, 136, 168, 84, + 92, 73, 167, 5, 165, 226, 74, 238, 212, 24, 140, 74, 11, 19, 88, 140, 74, 143, 168, 146, 37, 124, 73, 184, + 216, 150, 118, 239, 141, 84, 178, 40, 165, 24, 52, 120, 240, 98, 183, 219, 237, 239, 212, 169, 211, 147, + 46, 151, 75, 85, 145, 5, 142, 3, 231, 116, 160, 198, 91, 111, 65, 87, 55, 29, 231, 187, 117, 67, 240, 242, + 21, 38, 178, 202, 136, 220, 207, 36, 94, 5, 139, 17, 141, 156, 184, 10, 112, 128, 54, 43, 19, 153, 227, 39, + 192, 252, 224, 131, 224, 84, 78, 103, 7, 0, 157, 78, 7, 189, 94, 143, 161, 67, 135, 174, 154, 62, 99, 198, + 26, 196, 23, 87, 241, 246, 11, 50, 207, 21, 163, 202, 193, 76, 238, 140, 170, 134, 224, 193, 16, 86, 234, + 8, 166, 119, 33, 194, 65, 26, 223, 32, 68, 56, 248, 0, 4, 70, 141, 30, 189, 124, 204, 216, 177, 235, 205, + 102, 51, 180, 90, 173, 202, 71, 74, 193, 21, 23, 195, 250, 248, 147, 200, 153, 51, 23, 186, 59, 126, 207, + 98, 28, 126, 3, 101, 241, 91, 49, 98, 39, 5, 67, 225, 73, 65, 195, 159, 255, 132, 156, 121, 243, 97, 126, + 224, 1, 213, 3, 68, 1, 94, 92, 233, 116, 58, 124, 208, 175, 223, 178, 233, 51, 102, 8, 149, 43, 105, 20, + 131, 216, 212, 30, 111, 121, 51, 131, 81, 229, 96, 2, 139, 81, 101, 160, 97, 16, 45, 178, 132, 233, 66, 37, + 145, 37, 206, 201, 242, 2, 8, 141, 27, 55, 238, 243, 143, 62, 250, 104, 149, 209, 104, 84, 95, 100, 1, 224, + 156, 14, 24, 239, 186, 11, 57, 115, 231, 193, 244, 208, 63, 88, 140, 3, 67, 53, 228, 98, 24, 2, 20, 176, + 62, 243, 20, 114, 102, 207, 129, 161, 94, 61, 213, 3, 68, 1, 64, 175, 215, 131, 16, 194, 245, 238, 221, + 123, 81, 65, 65, 193, 70, 240, 33, 160, 114, 226, 170, 180, 182, 32, 243, 93, 49, 170, 44, 76, 96, 49, 170, + 42, 101, 173, 100, 69, 253, 166, 28, 190, 200, 115, 121, 211, 166, 173, 233, 215, 175, 223, 50, 225, 183, + 108, 181, 225, 220, 110, 104, 211, 210, 144, 61, 99, 6, 236, 111, 188, 134, 128, 40, 198, 65, 154, 172, + 202, 96, 220, 40, 210, 209, 58, 193, 204, 30, 160, 64, 141, 166, 77, 144, 53, 121, 10, 52, 118, 187, 234, + 25, 87, 0, 96, 52, 26, 17, 8, 4, 2, 93, 187, 118, 45, 248, 108, 201, 146, 111, 17, 93, 185, 138, 170, 44, + 163, 236, 149, 43, 246, 214, 96, 84, 57, 152, 7, 139, 81, 229, 144, 172, 212, 1, 98, 61, 89, 81, 127, 93, + 242, 17, 132, 16, 74, 41, 53, 207, 155, 63, 127, 163, 203, 229, 242, 127, 244, 209, 71, 111, 24, 12, 6, + 173, 223, 175, 238, 152, 58, 245, 249, 64, 116, 58, 100, 142, 248, 24, 134, 156, 91, 112, 101, 194, 4, 80, + 142, 66, 167, 137, 62, 112, 230, 203, 98, 220, 8, 74, 147, 130, 156, 86, 131, 180, 222, 189, 145, 218, 246, + 109, 80, 175, 23, 84, 229, 215, 55, 0, 152, 76, 38, 56, 28, 14, 111, 151, 46, 93, 10, 190, 222, 180, 105, + 119, 216, 55, 41, 21, 87, 226, 132, 246, 210, 60, 87, 194, 105, 49, 24, 85, 14, 38, 176, 24, 85, 18, 5, + 145, 21, 68, 233, 5, 33, 138, 240, 206, 50, 74, 169, 121, 217, 242, 229, 223, 57, 156, 78, 239, 216, 49, + 99, 26, 154, 205, 102, 131, 79, 229, 160, 69, 26, 12, 2, 28, 135, 180, 110, 221, 161, 191, 245, 86, 92, + 236, 215, 15, 1, 151, 155, 153, 223, 25, 55, 133, 210, 164, 32, 169, 153, 130, 140, 143, 134, 35, 229, 197, + 151, 16, 114, 58, 85, 143, 97, 0, 0, 179, 217, 140, 75, 151, 47, 59, 219, 183, 111, 63, 119, 231, 206, 157, + 63, 134, 197, 85, 204, 74, 43, 148, 173, 45, 40, 62, 45, 6, 163, 74, 194, 90, 132, 140, 42, 139, 204, 222, + 66, 193, 147, 21, 64, 244, 90, 29, 217, 29, 103, 132, 16, 55, 33, 132, 174, 91, 183, 110, 231, 59, 239, + 190, 155, 95, 84, 84, 228, 54, 155, 205, 170, 95, 209, 41, 199, 33, 228, 112, 160, 198, 27, 245, 145, 157, + 159, 15, 237, 173, 57, 17, 243, 59, 235, 137, 48, 202, 138, 210, 164, 160, 238, 247, 183, 35, 123, 206, 60, + 216, 95, 120, 9, 161, 226, 226, 132, 136, 43, 171, 213, 138, 211, 167, 79, 95, 107, 217, 178, 229, 140, + 176, 184, 162, 136, 109, 9, 10, 147, 130, 194, 123, 82, 200, 186, 98, 109, 65, 70, 181, 132, 9, 44, 70, + 149, 230, 6, 68, 150, 216, 147, 21, 229, 1, 33, 132, 208, 45, 91, 182, 236, 111, 209, 178, 229, 140, 51, + 103, 206, 92, 183, 89, 173, 137, 56, 112, 132, 138, 139, 97, 126, 224, 65, 228, 204, 47, 132, 233, 193, 7, + 16, 224, 228, 215, 235, 48, 24, 82, 148, 38, 5, 205, 143, 63, 138, 156, 249, 243, 97, 186, 231, 30, 112, + 14, 245, 99, 24, 0, 192, 102, 179, 225, 167, 159, 126, 58, 223, 172, 121, 243, 105, 63, 253, 244, 211, 47, + 50, 226, 74, 110, 191, 160, 120, 253, 13, 51, 180, 51, 170, 37, 76, 96, 49, 170, 60, 101, 20, 89, 94, 68, + 87, 178, 164, 213, 44, 110, 255, 254, 253, 63, 55, 109, 214, 108, 218, 193, 67, 135, 46, 216, 109, 182, + 132, 28, 59, 231, 116, 66, 151, 153, 137, 236, 153, 179, 96, 127, 179, 62, 111, 126, 231, 152, 249, 157, + 33, 79, 60, 51, 123, 205, 166, 77, 144, 149, 55, 29, 218, 218, 105, 124, 58, 123, 2, 72, 73, 73, 193, 247, + 223, 127, 127, 162, 121, 139, 22, 211, 142, 31, 63, 126, 154, 16, 194, 33, 182, 114, 37, 77, 104, 151, 19, + 87, 172, 114, 197, 168, 118, 48, 129, 197, 168, 22, 148, 34, 178, 132, 229, 208, 66, 37, 75, 90, 205, 18, + 42, 89, 161, 227, 199, 143, 159, 106, 209, 162, 197, 180, 173, 219, 182, 157, 176, 219, 237, 137, 57, 118, + 175, 23, 68, 167, 71, 198, 240, 17, 168, 211, 183, 15, 66, 6, 61, 130, 92, 172, 176, 98, 119, 157, 228, 70, + 250, 90, 160, 224, 253, 86, 33, 163, 1, 233, 3, 7, 32, 125, 240, 96, 62, 84, 87, 101, 31, 33, 192, 135, + 247, 166, 164, 164, 96, 245, 234, 213, 7, 219, 190, 253, 246, 244, 75, 151, 46, 93, 34, 132, 4, 33, 249, + 197, 5, 177, 173, 65, 86, 185, 98, 36, 13, 76, 96, 49, 170, 13, 165, 228, 100, 137, 43, 89, 114, 237, 66, + 39, 194, 34, 235, 194, 133, 11, 23, 91, 183, 105, 51, 125, 213, 170, 85, 7, 83, 82, 82, 196, 9, 242, 234, + 29, 123, 48, 0, 206, 227, 65, 173, 119, 219, 33, 107, 234, 84, 144, 244, 58, 44, 148, 148, 17, 65, 206, + 111, 229, 231, 0, 146, 153, 129, 172, 25, 51, 80, 171, 101, 43, 112, 46, 55, 63, 68, 161, 50, 26, 141, 6, + 54, 155, 13, 243, 230, 207, 223, 217, 161, 99, 199, 124, 135, 195, 81, 20, 22, 87, 98, 81, 229, 64, 108, + 20, 131, 176, 91, 48, 0, 254, 125, 41, 44, 111, 22, 78, 139, 189, 188, 25, 213, 10, 38, 176, 24, 213, 21, + 225, 62, 36, 23, 70, 42, 246, 100, 197, 180, 50, 8, 33, 65, 135, 195, 81, 220, 177, 83, 167, 252, 57, 115, + 231, 238, 176, 217, 108, 208, 104, 18, 240, 86, 17, 146, 223, 159, 126, 6, 57, 133, 11, 96, 248, 235, 189, + 188, 200, 162, 172, 146, 149, 172, 72, 85, 135, 216, 111, 101, 122, 224, 62, 220, 82, 184, 0, 214, 199, 30, + 231, 205, 236, 42, 239, 20, 4, 74, 150, 54, 143, 159, 48, 225, 235, 220, 220, 220, 66, 191, 223, 239, 33, + 132, 4, 32, 159, 113, 37, 23, 197, 32, 8, 43, 161, 106, 69, 69, 213, 103, 6, 163, 90, 193, 4, 22, 163, 218, + 33, 170, 100, 1, 209, 34, 75, 104, 25, 42, 121, 178, 196, 34, 203, 31, 8, 4, 60, 239, 191, 255, 254, 130, + 49, 99, 199, 110, 48, 153, 76, 9, 9, 36, 5, 120, 95, 150, 225, 182, 219, 144, 51, 123, 14, 236, 245, 223, + 64, 128, 242, 173, 32, 230, 203, 74, 46, 148, 242, 173, 2, 20, 168, 209, 168, 33, 178, 243, 231, 64, 159, + 147, 147, 144, 100, 118, 0, 48, 24, 12, 208, 106, 181, 220, 135, 3, 6, 124, 62, 122, 244, 232, 21, 0, 2, + 225, 21, 84, 178, 213, 96, 200, 123, 174, 130, 16, 21, 102, 153, 184, 98, 84, 103, 88, 14, 22, 35, 25, 144, + 118, 217, 164, 58, 69, 238, 207, 28, 33, 196, 74, 41, 197, 184, 113, 227, 62, 191, 120, 225, 66, 241, 128, + 1, 3, 254, 99, 48, 24, 52, 106, 7, 146, 2, 0, 231, 241, 128, 24, 141, 200, 24, 49, 18, 166, 187, 239, 198, + 229, 145, 35, 65, 189, 62, 104, 89, 94, 86, 82, 160, 148, 111, 5, 179, 9, 233, 125, 251, 162, 102, 147, + 166, 160, 62, 31, 56, 175, 55, 33, 199, 99, 50, 153, 224, 118, 187, 253, 189, 122, 245, 90, 188, 122, 205, + 154, 109, 0, 16, 94, 61, 37, 93, 75, 37, 245, 91, 9, 45, 65, 193, 115, 21, 121, 191, 49, 113, 197, 168, + 238, 176, 10, 22, 163, 218, 18, 167, 146, 37, 94, 173, 163, 184, 32, 26, 37, 251, 11, 185, 130, 194, 194, + 13, 237, 218, 181, 155, 235, 116, 58, 189, 102, 179, 57, 49, 199, 31, 8, 128, 243, 122, 81, 171, 77, 91, + 100, 205, 156, 9, 205, 45, 44, 47, 171, 186, 35, 55, 216, 16, 201, 183, 186, 173, 30, 178, 242, 243, 81, + 179, 121, 11, 112, 238, 196, 248, 173, 0, 192, 98, 177, 224, 252, 249, 243, 197, 173, 90, 183, 158, 185, + 122, 205, 154, 109, 132, 16, 132, 87, 223, 72, 171, 86, 101, 89, 127, 195, 42, 87, 140, 164, 129, 9, 44, + 70, 50, 161, 228, 201, 18, 183, 11, 99, 218, 29, 132, 16, 15, 33, 4, 235, 214, 175, 223, 213, 162, 69, 139, + 25, 167, 79, 159, 190, 110, 77, 68, 86, 22, 0, 112, 28, 66, 197, 197, 176, 60, 244, 48, 110, 89, 184, 8, + 150, 167, 158, 84, 204, 203, 98, 119, 172, 170, 141, 244, 249, 19, 252, 86, 1, 14, 176, 62, 251, 12, 114, + 22, 44, 132, 229, 193, 191, 131, 75, 144, 223, 10, 0, 236, 118, 59, 126, 250, 233, 167, 243, 77, 154, 54, + 205, 219, 177, 99, 199, 79, 225, 140, 43, 55, 148, 133, 149, 82, 229, 42, 242, 123, 1, 19, 87, 140, 100, + 129, 9, 44, 70, 181, 71, 82, 201, 18, 79, 23, 202, 197, 56, 200, 138, 44, 240, 213, 44, 250, 195, 190, 125, + 71, 26, 53, 110, 60, 117, 215, 174, 93, 167, 83, 82, 82, 18, 118, 14, 156, 203, 5, 109, 157, 58, 200, 202, + 155, 134, 90, 29, 59, 32, 164, 209, 198, 228, 101, 1, 76, 100, 85, 85, 148, 252, 86, 65, 173, 22, 169, 93, + 58, 35, 115, 202, 20, 104, 83, 83, 19, 150, 111, 37, 196, 48, 172, 95, 191, 254, 231, 102, 205, 155, 231, + 253, 250, 235, 175, 167, 68, 25, 87, 74, 149, 43, 57, 207, 85, 84, 12, 3, 19, 87, 140, 100, 130, 9, 44, 70, + 210, 160, 32, 178, 164, 17, 14, 74, 198, 119, 65, 100, 133, 78, 159, 62, 125, 174, 69, 203, 150, 121, 159, + 127, 254, 249, 129, 148, 148, 148, 196, 76, 24, 130, 95, 22, 77, 67, 33, 164, 245, 232, 137, 204, 188, 169, + 64, 221, 116, 214, 50, 172, 6, 40, 181, 4, 73, 102, 93, 100, 230, 229, 161, 118, 183, 238, 64, 32, 152, + 144, 101, 205, 0, 63, 41, 104, 179, 217, 48, 103, 206, 156, 237, 239, 188, 251, 238, 204, 43, 87, 174, 92, + 33, 132, 132, 160, 252, 203, 135, 212, 208, 46, 53, 179, 51, 113, 197, 72, 74, 152, 201, 61, 137, 72, 68, + 158, 83, 21, 64, 240, 133, 11, 247, 50, 105, 192, 33, 149, 60, 56, 201, 71, 74, 8, 49, 135, 99, 28, 230, + 156, 60, 117, 234, 229, 247, 222, 125, 247, 49, 159, 207, 135, 96, 34, 60, 49, 161, 16, 56, 135, 3, 214, + 231, 254, 137, 91, 238, 184, 3, 23, 223, 127, 31, 238, 205, 91, 160, 35, 128, 134, 148, 252, 198, 36, 156, + 12, 123, 198, 43, 47, 114, 45, 65, 142, 2, 65, 10, 88, 30, 123, 4, 233, 67, 134, 65, 95, 175, 30, 223, 18, + 76, 16, 122, 189, 30, 90, 173, 150, 14, 27, 54, 236, 203, 169, 121, 121, 95, 2, 8, 134, 99, 24, 196, 1, + 189, 82, 51, 187, 56, 227, 74, 104, 9, 70, 25, 218, 193, 191, 111, 18, 118, 30, 12, 70, 101, 128, 85, 176, + 24, 201, 136, 84, 76, 73, 219, 133, 241, 246, 23, 70, 98, 28, 56, 142, 243, 141, 24, 49, 98, 105, 110, 223, + 190, 203, 57, 142, 11, 25, 141, 198, 132, 157, 0, 231, 112, 64, 159, 157, 131, 172, 153, 179, 80, 171, 99, + 7, 4, 53, 154, 152, 40, 7, 128, 85, 179, 42, 43, 74, 83, 130, 65, 141, 6, 169, 29, 218, 33, 107, 198, 76, + 232, 178, 178, 19, 22, 193, 0, 0, 102, 179, 25, 30, 143, 199, 215, 185, 75, 151, 5, 83, 243, 242, 86, 131, + 23, 87, 114, 49, 12, 98, 145, 37, 246, 92, 9, 149, 171, 24, 113, 149, 176, 147, 96, 48, 42, 17, 76, 96, 49, + 146, 21, 57, 145, 37, 220, 32, 202, 42, 178, 188, 0, 184, 194, 194, 194, 141, 109, 223, 126, 59, 255, 242, + 229, 203, 78, 139, 197, 146, 176, 19, 224, 124, 62, 128, 227, 144, 214, 179, 23, 178, 166, 77, 135, 38, 59, + 11, 126, 22, 76, 90, 233, 137, 17, 87, 97, 35, 187, 38, 59, 147, 111, 9, 246, 234, 3, 112, 28, 168, 47, 49, + 17, 12, 0, 191, 176, 249, 196, 201, 147, 87, 155, 183, 104, 49, 99, 229, 202, 149, 223, 19, 66, 168, 204, + 164, 160, 52, 157, 93, 206, 208, 30, 169, 244, 138, 78, 145, 193, 72, 74, 152, 192, 98, 36, 51, 114, 251, + 11, 197, 17, 14, 114, 34, 203, 33, 250, 232, 34, 132, 184, 9, 33, 244, 187, 239, 190, 219, 215, 184, 73, + 147, 188, 3, 7, 14, 156, 75, 164, 249, 157, 134, 66, 124, 250, 251, 51, 207, 32, 103, 209, 98, 88, 159, + 123, 54, 106, 97, 116, 228, 239, 37, 236, 136, 24, 74, 200, 166, 178, 135, 131, 67, 45, 207, 60, 133, 156, + 133, 139, 97, 123, 246, 57, 112, 197, 197, 160, 161, 80, 66, 142, 73, 48, 179, 111, 217, 178, 229, 120, + 195, 134, 13, 167, 238, 221, 187, 247, 72, 120, 82, 80, 105, 97, 115, 105, 49, 12, 76, 92, 49, 24, 97, 152, + 192, 98, 36, 59, 114, 34, 171, 180, 24, 135, 40, 145, 5, 126, 135, 33, 247, 203, 47, 191, 156, 108, 210, + 180, 233, 212, 229, 203, 151, 255, 152, 72, 243, 59, 192, 167, 191, 235, 234, 212, 65, 230, 148, 169, 72, + 235, 219, 23, 156, 217, 204, 210, 223, 43, 17, 74, 45, 193, 144, 201, 136, 218, 189, 123, 33, 115, 234, 52, + 232, 234, 214, 77, 104, 75, 80, 171, 213, 194, 102, 181, 98, 222, 188, 121, 187, 90, 183, 105, 51, 253, + 252, 249, 243, 23, 194, 102, 118, 105, 213, 86, 92, 185, 146, 155, 20, 100, 75, 155, 25, 12, 25, 152, 192, + 98, 48, 162, 111, 10, 98, 129, 165, 52, 97, 168, 212, 50, 12, 22, 21, 21, 21, 117, 238, 210, 101, 246, 184, + 113, 227, 54, 26, 141, 70, 232, 245, 250, 196, 157, 132, 223, 15, 234, 247, 163, 214, 187, 239, 34, 107, + 254, 60, 232, 255, 120, 55, 107, 25, 86, 2, 228, 90, 130, 126, 14, 208, 253, 225, 14, 100, 207, 153, 131, + 212, 246, 29, 128, 64, 0, 212, 231, 75, 216, 49, 25, 12, 6, 104, 52, 26, 110, 208, 224, 193, 171, 115, 251, + 246, 45, 116, 187, 221, 46, 209, 194, 102, 65, 84, 9, 15, 113, 75, 80, 174, 114, 37, 8, 44, 225, 20, 217, + 75, 140, 193, 0, 19, 88, 12, 134, 128, 220, 202, 28, 185, 74, 150, 210, 111, 247, 130, 200, 242, 113, 28, + 231, 31, 61, 102, 204, 231, 93, 186, 118, 93, 224, 118, 187, 19, 150, 252, 14, 0, 224, 56, 112, 197, 197, + 48, 255, 245, 111, 200, 46, 92, 128, 26, 205, 154, 242, 74, 145, 85, 179, 18, 142, 92, 75, 48, 40, 236, 18, + 108, 240, 22, 114, 22, 46, 130, 249, 129, 7, 249, 150, 32, 199, 41, 252, 43, 229, 143, 213, 106, 197, 181, + 235, 215, 93, 239, 188, 251, 238, 220, 25, 159, 126, 186, 22, 37, 102, 118, 165, 124, 171, 210, 42, 87, + 236, 165, 196, 96, 200, 192, 4, 22, 131, 17, 77, 188, 213, 58, 62, 68, 251, 178, 148, 68, 150, 135, 16, + 194, 125, 254, 249, 231, 223, 55, 105, 210, 100, 250, 209, 159, 127, 190, 100, 183, 219, 19, 122, 18, 156, + 203, 5, 141, 209, 136, 244, 193, 67, 144, 49, 101, 10, 52, 89, 153, 124, 102, 22, 171, 102, 37, 4, 233, + 207, 88, 72, 100, 39, 233, 105, 200, 24, 63, 30, 233, 31, 13, 135, 198, 106, 77, 88, 112, 40, 80, 226, 183, + 218, 183, 111, 223, 185, 70, 141, 26, 229, 109, 220, 184, 113, 183, 140, 153, 93, 168, 90, 149, 182, 180, + 89, 42, 174, 152, 102, 103, 48, 36, 48, 129, 197, 96, 196, 82, 214, 64, 82, 69, 145, 5, 192, 67, 8, 161, 7, + 126, 252, 241, 151, 6, 141, 26, 77, 89, 189, 102, 205, 161, 68, 251, 178, 104, 48, 8, 206, 233, 132, 237, + 223, 47, 32, 123, 241, 103, 176, 190, 248, 111, 4, 104, 73, 53, 43, 242, 247, 192, 238, 140, 229, 69, 169, + 70, 246, 69, 159, 193, 254, 202, 43, 252, 46, 193, 64, 32, 97, 199, 37, 132, 135, 126, 246, 217, 103, 63, + 52, 105, 218, 116, 234, 209, 163, 71, 79, 200, 172, 189, 17, 191, 134, 197, 226, 74, 174, 37, 200, 204, + 236, 12, 70, 41, 48, 129, 197, 96, 200, 163, 212, 46, 148, 174, 214, 17, 39, 191, 75, 127, 251, 119, 17, + 66, 130, 87, 175, 94, 189, 218, 174, 93, 187, 252, 177, 99, 199, 110, 52, 24, 12, 48, 24, 12, 9, 60, 11, + 10, 206, 225, 224, 13, 240, 19, 38, 33, 125, 248, 71, 64, 173, 154, 188, 200, 98, 213, 172, 114, 69, 206, + 107, 21, 228, 0, 106, 179, 34, 173, 223, 7, 188, 145, 61, 59, 27, 156, 195, 145, 176, 93, 130, 0, 96, 52, + 26, 161, 209, 104, 184, 161, 67, 135, 174, 237, 218, 173, 219, 188, 226, 226, 226, 98, 81, 50, 123, 105, + 107, 111, 132, 16, 81, 113, 229, 138, 137, 43, 6, 163, 12, 48, 129, 197, 96, 40, 83, 150, 9, 67, 185, 172, + 44, 177, 57, 216, 69, 8, 241, 135, 66, 33, 239, 152, 177, 99, 63, 111, 223, 190, 125, 65, 81, 81, 145, 59, + 97, 203, 162, 133, 19, 240, 251, 193, 121, 189, 168, 217, 176, 49, 114, 22, 127, 6, 243, 147, 79, 192, 31, + 142, 115, 144, 10, 3, 118, 199, 188, 49, 148, 170, 86, 126, 10, 24, 31, 184, 15, 217, 11, 23, 162, 86, 219, + 183, 65, 19, 108, 100, 7, 248, 124, 171, 75, 151, 46, 57, 90, 183, 105, 51, 59, 111, 218, 180, 53, 144, + 247, 91, 137, 127, 49, 144, 102, 92, 5, 194, 15, 22, 195, 192, 96, 220, 32, 76, 96, 49, 24, 241, 145, 182, + 11, 133, 172, 172, 178, 152, 223, 35, 55, 45, 66, 136, 151, 16, 66, 215, 172, 93, 187, 189, 65, 195, 134, + 121, 123, 246, 236, 57, 147, 146, 146, 146, 216, 245, 69, 148, 34, 228, 40, 134, 190, 222, 109, 200, 156, + 54, 3, 117, 250, 247, 3, 77, 177, 51, 111, 214, 111, 64, 41, 126, 129, 51, 155, 80, 187, 123, 55, 100, 207, + 153, 7, 227, 93, 119, 243, 235, 110, 18, 104, 100, 215, 104, 52, 145, 124, 171, 183, 26, 52, 152, 242, 237, + 183, 223, 238, 37, 132, 112, 55, 224, 183, 18, 86, 223, 8, 226, 74, 206, 115, 197, 96, 48, 226, 192, 4, 22, + 131, 81, 58, 210, 2, 133, 80, 201, 18, 214, 235, 40, 45, 138, 150, 107, 25, 114, 71, 143, 30, 61, 209, 168, + 113, 227, 169, 115, 231, 206, 221, 105, 181, 90, 161, 211, 37, 118, 37, 40, 245, 121, 65, 131, 1, 212, 108, + 211, 22, 217, 139, 23, 195, 244, 232, 35, 138, 225, 164, 236, 46, 42, 143, 244, 103, 67, 17, 246, 90, 113, + 128, 225, 222, 191, 32, 107, 222, 124, 212, 238, 220, 5, 0, 192, 121, 60, 9, 61, 54, 189, 94, 15, 147, 201, + 132, 105, 211, 166, 125, 223, 162, 101, 203, 233, 39, 79, 158, 60, 43, 227, 183, 146, 122, 174, 132, 221, + 130, 226, 24, 6, 165, 124, 43, 246, 178, 96, 48, 202, 0, 91, 246, 204, 96, 148, 13, 225, 166, 34, 93, 20, + 45, 125, 112, 10, 143, 72, 5, 128, 16, 98, 242, 120, 60, 206, 190, 239, 191, 191, 96, 255, 254, 253, 167, + 115, 115, 115, 95, 176, 219, 237, 6, 183, 219, 157, 184, 179, 9, 199, 57, 24, 127, 127, 7, 178, 102, 206, + 66, 209, 188, 185, 184, 58, 110, 28, 130, 197, 14, 232, 8, 64, 72, 201, 162, 104, 241, 137, 51, 98, 213, + 133, 80, 181, 130, 201, 136, 90, 239, 188, 131, 90, 111, 191, 3, 141, 217, 140, 80, 2, 151, 52, 11, 88, 44, + 22, 20, 21, 21, 121, 7, 14, 28, 248, 191, 101, 203, 151, 111, 5, 192, 133, 243, 173, 132, 86, 182, 244, 33, + 158, 16, 244, 33, 122, 159, 32, 243, 91, 49, 24, 191, 1, 86, 193, 98, 48, 110, 140, 210, 204, 239, 114, 45, + 67, 135, 228, 225, 10, 251, 96, 66, 133, 11, 22, 124, 221, 184, 73, 147, 233, 135, 14, 29, 186, 152, 240, + 150, 33, 0, 206, 235, 5, 13, 6, 81, 179, 77, 91, 228, 124, 182, 4, 230, 167, 158, 136, 84, 179, 164, 119, + 211, 100, 191, 187, 202, 85, 173, 130, 225, 170, 149, 241, 175, 255, 15, 89, 243, 231, 35, 173, 123, 15, + 16, 141, 6, 92, 34, 197, 50, 68, 17, 12, 251, 247, 159, 109, 208, 176, 97, 222, 178, 229, 203, 55, 3, 8, + 133, 247, 101, 222, 168, 223, 138, 153, 217, 25, 140, 114, 128, 9, 44, 6, 227, 198, 81, 50, 191, 203, 237, + 48, 84, 106, 201, 56, 195, 123, 12, 177, 127, 255, 254, 159, 27, 52, 108, 56, 101, 225, 194, 133, 123, 43, + 162, 101, 40, 84, 179, 244, 183, 223, 206, 123, 179, 134, 13, 5, 210, 106, 195, 207, 241, 249, 77, 201, + 110, 130, 151, 19, 86, 194, 130, 102, 206, 98, 70, 106, 247, 110, 200, 154, 95, 8, 243, 189, 127, 69, 40, + 129, 123, 4, 5, 244, 122, 61, 44, 22, 11, 230, 206, 157, 187, 171, 113, 227, 198, 121, 135, 14, 29, 58, 94, + 74, 190, 149, 210, 78, 65, 102, 102, 103, 48, 202, 17, 38, 176, 24, 140, 155, 67, 206, 252, 30, 111, 135, + 161, 146, 47, 203, 73, 8, 9, 21, 21, 21, 93, 239, 209, 179, 231, 252, 220, 190, 125, 87, 248, 124, 62, 191, + 197, 98, 73, 232, 201, 0, 0, 245, 122, 65, 3, 1, 212, 104, 210, 20, 57, 75, 150, 194, 246, 242, 139, 8, + 202, 228, 102, 1, 201, 115, 199, 149, 171, 226, 9, 185, 86, 166, 135, 31, 66, 206, 194, 69, 72, 237, 220, + 5, 32, 36, 225, 94, 43, 128, 111, 9, 122, 60, 30, 95, 207, 94, 189, 150, 246, 125, 255, 253, 66, 167, 211, + 233, 144, 172, 188, 145, 245, 2, 34, 90, 92, 137, 171, 86, 204, 204, 206, 96, 148, 19, 76, 96, 49, 24, 55, + 143, 248, 183, 124, 165, 228, 119, 169, 200, 18, 183, 10, 35, 213, 4, 66, 136, 159, 16, 18, 44, 40, 40, + 248, 186, 113, 227, 198, 211, 246, 239, 223, 127, 174, 34, 90, 134, 66, 53, 75, 151, 153, 137, 140, 9, 147, + 144, 49, 121, 18, 180, 183, 221, 138, 64, 146, 85, 179, 100, 77, 236, 148, 223, 33, 136, 212, 90, 72, 27, + 56, 0, 89, 249, 179, 97, 184, 251, 143, 252, 132, 96, 130, 171, 86, 66, 75, 240, 135, 31, 126, 56, 211, + 160, 97, 195, 105, 139, 23, 47, 254, 22, 177, 45, 193, 24, 49, 143, 216, 240, 80, 65, 92, 5, 193, 204, 236, + 12, 70, 185, 194, 4, 22, 131, 241, 219, 145, 75, 126, 47, 45, 47, 75, 234, 203, 114, 34, 156, 254, 190, + 255, 192, 129, 95, 26, 54, 106, 52, 117, 214, 172, 89, 219, 205, 38, 83, 98, 131, 73, 133, 19, 241, 251, + 193, 185, 221, 176, 189, 248, 18, 114, 150, 44, 69, 205, 214, 173, 16, 210, 235, 147, 162, 154, 37, 103, + 98, 15, 113, 64, 144, 2, 182, 23, 255, 141, 236, 37, 75, 81, 179, 69, 43, 208, 96, 16, 212, 155, 248, 170, + 149, 193, 96, 128, 201, 100, 194, 140, 25, 51, 182, 53, 110, 220, 56, 239, 224, 193, 131, 199, 194, 45, 65, + 105, 42, 123, 188, 133, 205, 138, 225, 161, 148, 39, 209, 167, 197, 96, 84, 59, 152, 192, 98, 48, 126, 35, + 148, 82, 136, 238, 72, 55, 99, 126, 23, 251, 179, 92, 132, 144, 160, 203, 229, 114, 244, 255, 240, 195, 69, + 29, 59, 119, 94, 120, 237, 218, 53, 151, 205, 102, 75, 232, 57, 241, 103, 66, 193, 57, 157, 208, 88, 109, + 72, 235, 255, 33, 178, 230, 205, 135, 225, 254, 191, 33, 192, 133, 19, 202, 197, 127, 21, 85, 95, 104, 41, + 85, 173, 2, 28, 160, 185, 237, 86, 212, 157, 52, 17, 25, 19, 39, 67, 159, 147, 3, 206, 145, 216, 92, 43, 1, + 155, 205, 134, 107, 215, 174, 185, 58, 116, 236, 184, 96, 224, 160, 65, 139, 93, 110, 183, 51, 220, 18, 20, + 170, 161, 241, 252, 86, 165, 134, 135, 50, 101, 197, 96, 148, 31, 76, 96, 49, 24, 229, 132, 68, 100, 197, + 107, 25, 10, 35, 242, 74, 149, 44, 33, 152, 148, 91, 185, 114, 229, 214, 250, 111, 190, 57, 101, 211, 166, + 77, 199, 82, 82, 82, 160, 213, 106, 19, 122, 78, 0, 248, 157, 134, 14, 7, 204, 247, 223, 143, 236, 121, 5, + 72, 27, 56, 0, 72, 75, 85, 108, 27, 86, 69, 98, 170, 86, 130, 247, 204, 96, 68, 205, 182, 109, 144, 179, + 100, 25, 236, 47, 189, 12, 206, 227, 73, 120, 26, 59, 192, 239, 18, 76, 73, 73, 193, 198, 141, 27, 127, + 121, 163, 126, 253, 41, 171, 86, 173, 218, 6, 62, 130, 193, 139, 18, 17, 37, 125, 29, 73, 215, 222, 200, + 137, 171, 72, 91, 144, 137, 43, 6, 163, 124, 97, 2, 139, 193, 40, 71, 36, 55, 41, 37, 145, 229, 67, 137, + 200, 146, 222, 24, 165, 222, 44, 238, 196, 137, 19, 103, 91, 181, 110, 61, 99, 216, 71, 31, 125, 69, 41, + 13, 154, 205, 230, 132, 157, 143, 24, 206, 237, 6, 229, 56, 212, 108, 217, 10, 57, 75, 151, 195, 254, 198, + 235, 8, 105, 52, 49, 123, 13, 171, 82, 53, 75, 110, 205, 77, 48, 108, 98, 55, 254, 227, 239, 200, 42, 44, + 68, 218, 7, 253, 160, 177, 218, 192, 57, 157, 9, 221, 33, 40, 96, 54, 155, 65, 41, 13, 13, 31, 49, 98, 125, + 155, 182, 109, 63, 13, 7, 135, 114, 132, 16, 57, 97, 165, 36, 174, 132, 101, 205, 66, 75, 80, 120, 109, 10, + 45, 193, 170, 242, 148, 49, 24, 85, 6, 38, 176, 24, 140, 114, 70, 114, 195, 18, 251, 178, 132, 27, 156, 32, + 178, 148, 124, 89, 197, 136, 222, 101, 24, 8, 6, 131, 190, 41, 83, 166, 172, 110, 220, 164, 201, 167, 7, + 15, 30, 188, 144, 146, 146, 2, 141, 166, 2, 222, 190, 130, 9, 62, 35, 3, 233, 163, 70, 35, 51, 127, 54, 12, + 127, 189, 87, 54, 59, 171, 50, 11, 45, 165, 118, 96, 144, 3, 72, 102, 6, 210, 135, 127, 132, 172, 57, 115, + 97, 252, 127, 255, 15, 156, 195, 1, 26, 12, 36, 252, 24, 5, 35, 251, 145, 35, 71, 46, 53, 105, 218, 244, + 211, 201, 147, 39, 127, 17, 12, 6, 189, 132, 144, 0, 226, 123, 249, 148, 34, 24, 100, 253, 86, 9, 62, 45, + 6, 35, 105, 96, 2, 139, 193, 80, 9, 25, 95, 86, 188, 61, 134, 241, 90, 134, 66, 102, 22, 221, 189, 123, + 247, 225, 183, 26, 52, 152, 50, 227, 211, 79, 183, 25, 12, 6, 24, 141, 198, 132, 158, 147, 0, 245, 251, + 193, 57, 157, 176, 60, 250, 40, 178, 10, 10, 81, 103, 224, 0, 144, 186, 117, 170, 196, 180, 161, 92, 166, + 21, 223, 14, 52, 32, 165, 121, 51, 228, 44, 91, 142, 148, 134, 141, 120, 19, 123, 5, 68, 47, 0, 128, 209, + 104, 132, 201, 100, 66, 126, 126, 254, 142, 55, 223, 122, 235, 147, 93, 187, 118, 29, 138, 147, 109, 85, + 154, 184, 18, 79, 9, 178, 150, 32, 131, 145, 32, 216, 170, 28, 6, 67, 69, 40, 165, 148, 240, 89, 11, 130, + 206, 16, 127, 46, 93, 175, 19, 66, 244, 20, 32, 128, 54, 218, 0, 0, 19, 184, 73, 68, 65, 84, 162, 184, 234, + 21, 2, 63, 134, 111, 114, 58, 157, 142, 129, 3, 7, 46, 254, 238, 187, 239, 126, 238, 223, 175, 223, 203, + 191, 251, 221, 239, 106, 56, 157, 78, 84, 196, 253, 146, 115, 185, 0, 173, 22, 53, 90, 182, 130, 245, 185, + 127, 226, 90, 222, 20, 20, 47, 88, 136, 144, 207, 47, 187, 114, 167, 34, 215, 237, 40, 101, 90, 133, 0, 88, + 30, 125, 24, 169, 221, 122, 192, 116, 223, 125, 160, 94, 47, 56, 135, 163, 2, 142, 144, 175, 90, 217, 108, + 54, 156, 58, 117, 202, 49, 104, 240, 224, 149, 107, 215, 174, 221, 13, 254, 121, 15, 130, 23, 77, 130, 32, + 247, 160, 164, 2, 42, 124, 46, 84, 70, 165, 137, 236, 76, 88, 49, 24, 21, 0, 171, 96, 49, 24, 42, 35, 211, + 50, 148, 78, 25, 10, 55, 70, 233, 148, 161, 208, 42, 140, 49, 192, 3, 224, 214, 175, 95, 191, 251, 141, + 250, 245, 39, 47, 94, 188, 248, 7, 139, 197, 82, 33, 113, 14, 0, 128, 80, 8, 92, 113, 49, 180, 181, 107, + 163, 206, 160, 33, 200, 94, 184, 16, 230, 167, 158, 44, 9, 41, 21, 221, 206, 43, 162, 154, 37, 219, 14, + 228, 248, 76, 43, 237, 239, 234, 161, 238, 216, 49, 200, 156, 53, 27, 38, 161, 29, 24, 72, 124, 59, 16, 40, + 73, 100, 95, 177, 98, 197, 143, 175, 189, 254, 250, 228, 181, 107, 215, 238, 32, 132, 132, 194, 107, 149, + 228, 90, 130, 197, 136, 246, 90, 73, 69, 150, 88, 96, 49, 113, 197, 96, 36, 24, 86, 193, 98, 48, 18, 132, + 164, 154, 5, 196, 46, 140, 150, 86, 175, 164, 85, 44, 225, 134, 25, 36, 132, 132, 0, 152, 46, 93, 186, 116, + 165, 123, 143, 30, 243, 191, 254, 250, 235, 195, 185, 185, 185, 255, 206, 201, 201, 177, 87, 84, 53, 139, + 6, 2, 160, 129, 0, 76, 247, 252, 5, 153, 211, 103, 192, 245, 213, 151, 184, 54, 97, 2, 252, 7, 15, 65, 67, + 1, 173, 38, 241, 11, 164, 99, 90, 149, 148, 207, 179, 210, 212, 72, 65, 106, 203, 150, 168, 209, 172, 57, + 180, 169, 169, 224, 92, 174, 10, 249, 153, 1, 124, 213, 202, 106, 181, 226, 210, 165, 75, 158, 17, 35, 71, + 174, 89, 188, 120, 241, 86, 240, 207, 49, 135, 146, 160, 90, 185, 138, 149, 80, 209, 146, 243, 89, 73, 19, + 217, 153, 184, 98, 48, 18, 12, 19, 88, 12, 70, 2, 145, 17, 89, 114, 62, 45, 241, 67, 44, 178, 196, 85, 47, + 65, 104, 153, 0, 24, 255, 183, 114, 229, 214, 29, 59, 119, 254, 250, 193, 7, 31, 188, 252, 210, 139, 47, + 254, 49, 16, 8, 192, 239, 247, 39, 236, 188, 196, 112, 30, 15, 64, 8, 108, 255, 126, 1, 150, 199, 30, 71, + 241, 226, 69, 184, 62, 45, 15, 129, 115, 23, 160, 5, 160, 73, 128, 208, 146, 19, 86, 33, 10, 80, 157, 14, + 182, 87, 254, 139, 90, 239, 181, 131, 225, 15, 127, 0, 117, 187, 249, 233, 192, 10, 66, 175, 215, 195, 100, + 50, 97, 237, 218, 181, 135, 7, 15, 25, 178, 242, 228, 201, 147, 103, 0, 128, 16, 226, 135, 124, 75, 80, 78, + 92, 137, 211, 216, 35, 45, 65, 137, 160, 98, 226, 138, 193, 72, 48, 164, 50, 252, 82, 115, 246, 236, 89, + 220, 121, 231, 157, 112, 185, 92, 137, 95, 13, 194, 96, 252, 70, 110, 246, 61, 68, 74, 94, 236, 36, 252, + 208, 0, 208, 134, 31, 58, 0, 122, 0, 198, 240, 195, 20, 126, 152, 195, 15, 75, 248, 99, 228, 235, 148, 82, + 13, 0, 221, 107, 175, 189, 246, 247, 94, 61, 123, 254, 51, 43, 43, 203, 86, 81, 213, 44, 1, 162, 213, 130, + 88, 172, 8, 158, 63, 135, 162, 252, 89, 40, 158, 63, 15, 92, 177, 19, 90, 2, 104, 72, 180, 176, 42, 143, + 119, 190, 82, 10, 59, 5, 96, 126, 244, 17, 212, 234, 212, 25, 230, 7, 31, 4, 245, 251, 65, 43, 72, 128, 10, + 216, 108, 54, 92, 185, 114, 197, 59, 118, 236, 216, 175, 230, 23, 20, 108, 225, 56, 206, 47, 170, 90, 41, + 85, 174, 164, 85, 43, 193, 196, 30, 85, 181, 162, 148, 82, 163, 209, 8, 131, 193, 64, 185, 155, 12, 68, + 245, 120, 60, 21, 250, 218, 97, 48, 110, 6, 74, 41, 22, 45, 90, 132, 250, 245, 235, 87, 244, 161, 48, 129, + 197, 96, 252, 86, 126, 203, 123, 72, 70, 100, 17, 240, 2, 75, 3, 94, 96, 9, 15, 177, 208, 50, 43, 60, 76, + 148, 82, 3, 0, 154, 145, 145, 145, 209, 167, 119, 239, 127, 255, 247, 191, 255, 189, 39, 24, 12, 86, 88, + 53, 75, 128, 232, 245, 32, 102, 51, 252, 63, 31, 193, 245, 233, 211, 225, 92, 182, 28, 240, 249, 34, 66, + 43, 230, 239, 223, 224, 191, 175, 100, 96, 231, 0, 24, 255, 244, 71, 212, 236, 208, 1, 214, 103, 159, 3, + 209, 104, 42, 100, 41, 179, 24, 189, 94, 15, 147, 209, 136, 117, 235, 215, 31, 29, 50, 116, 232, 255, 142, + 29, 59, 118, 10, 252, 75, 33, 128, 18, 17, 37, 21, 85, 226, 201, 64, 177, 145, 61, 128, 146, 74, 39, 95, + 172, 163, 148, 62, 246, 216, 99, 248, 228, 147, 79, 104, 221, 186, 117, 17, 12, 6, 111, 232, 248, 180, 90, + 45, 156, 78, 39, 30, 121, 228, 17, 156, 63, 127, 158, 93, 147, 25, 85, 138, 202, 36, 176, 88, 139, 144, + 193, 168, 64, 226, 76, 25, 106, 17, 219, 50, 84, 242, 101, 137, 189, 89, 38, 0, 166, 243, 231, 207, 95, + 232, 210, 181, 235, 188, 117, 235, 214, 221, 215, 187, 119, 239, 231, 235, 213, 171, 151, 82, 145, 213, 44, + 193, 159, 165, 191, 181, 30, 210, 135, 143, 64, 74, 195, 70, 184, 62, 117, 10, 220, 95, 126, 137, 80, 136, + 139, 17, 90, 101, 157, 56, 148, 19, 86, 92, 120, 50, 80, 127, 235, 45, 72, 125, 231, 29, 216, 95, 121, 21, + 26, 171, 181, 66, 125, 86, 64, 120, 66, 208, 106, 197, 133, 139, 23, 221, 253, 71, 143, 94, 183, 112, 209, + 162, 239, 41, 165, 126, 66, 8, 69, 137, 65, 93, 218, 10, 20, 183, 4, 197, 94, 171, 24, 19, 187, 208, 18, + 236, 222, 189, 59, 29, 54, 108, 216, 111, 26, 122, 176, 217, 108, 21, 178, 53, 128, 193, 168, 78, 48, 129, + 197, 96, 84, 48, 194, 141, 81, 226, 205, 18, 7, 66, 150, 69, 96, 9, 222, 172, 32, 248, 177, 126, 35, 0, + 178, 242, 139, 47, 182, 109, 221, 182, 237, 151, 110, 221, 186, 253, 235, 205, 250, 245, 255, 70, 8, 129, + 215, 235, 77, 220, 201, 73, 160, 62, 31, 168, 207, 7, 227, 159, 254, 132, 140, 201, 159, 192, 179, 109, 27, + 47, 180, 190, 249, 22, 132, 163, 81, 66, 43, 158, 63, 43, 158, 176, 210, 166, 167, 33, 181, 89, 11, 164, + 52, 108, 4, 109, 90, 109, 112, 46, 87, 133, 250, 172, 0, 126, 65, 179, 94, 175, 199, 202, 47, 190, 56, 56, + 124, 248, 240, 85, 39, 79, 157, 58, 11, 0, 225, 170, 149, 184, 37, 40, 53, 177, 139, 39, 3, 133, 118, 96, + 204, 170, 27, 74, 41, 173, 87, 175, 30, 62, 249, 228, 19, 250, 194, 11, 47, 36, 248, 236, 24, 12, 134, 28, + 76, 96, 49, 24, 149, 4, 153, 106, 86, 188, 188, 172, 120, 66, 43, 34, 182, 8, 33, 166, 203, 151, 47, 95, + 233, 219, 183, 239, 130, 181, 107, 215, 30, 200, 205, 205, 125, 225, 79, 127, 252, 99, 154, 203, 229, 66, + 40, 20, 74, 240, 25, 150, 64, 189, 94, 80, 66, 96, 254, 251, 223, 97, 122, 240, 65, 184, 55, 109, 66, 209, + 244, 105, 240, 108, 221, 10, 194, 65, 86, 104, 201, 254, 59, 40, 17, 86, 154, 154, 53, 80, 179, 113, 35, + 212, 104, 220, 20, 186, 236, 28, 80, 143, 187, 194, 242, 172, 4, 52, 26, 13, 172, 86, 43, 78, 158, 60, 233, + 24, 53, 106, 212, 218, 229, 43, 86, 236, 4, 16, 8, 123, 173, 132, 104, 14, 165, 138, 149, 184, 37, 24, 37, + 160, 33, 49, 178, 191, 244, 210, 75, 152, 58, 117, 42, 205, 206, 206, 78, 236, 9, 50, 24, 12, 69, 152, 192, + 98, 48, 42, 17, 34, 145, 5, 148, 136, 42, 57, 145, 37, 94, 191, 35, 22, 90, 226, 246, 81, 16, 97, 145, 69, + 41, 53, 108, 218, 180, 233, 135, 221, 187, 119, 31, 127, 247, 157, 119, 158, 106, 217, 178, 229, 195, 86, + 171, 85, 235, 114, 185, 18, 121, 122, 209, 80, 10, 206, 237, 6, 8, 129, 245, 169, 167, 96, 121, 236, 49, + 184, 191, 249, 6, 69, 51, 166, 193, 187, 117, 27, 66, 18, 161, 21, 245, 191, 2, 160, 28, 127, 130, 154, 20, + 27, 106, 188, 249, 22, 106, 52, 105, 10, 253, 237, 183, 131, 122, 60, 224, 28, 197, 137, 62, 155, 24, 76, + 38, 19, 0, 160, 160, 176, 112, 207, 152, 49, 99, 214, 94, 188, 120, 241, 82, 248, 169, 149, 86, 173, 148, + 218, 129, 113, 227, 23, 40, 165, 212, 98, 177, 160, 127, 255, 254, 180, 123, 247, 238, 208, 233, 216, 229, + 156, 193, 168, 76, 176, 119, 36, 131, 81, 201, 40, 165, 101, 24, 47, 198, 65, 92, 229, 136, 250, 92, 136, + 115, 112, 56, 28, 197, 31, 143, 26, 181, 98, 237, 151, 95, 254, 216, 167, 79, 159, 127, 63, 242, 200, 35, + 245, 124, 94, 47, 2, 21, 20, 174, 9, 128, 23, 90, 46, 23, 47, 180, 158, 126, 26, 150, 199, 5, 161, 53, 29, + 158, 173, 219, 64, 184, 240, 196, 161, 80, 209, 18, 42, 86, 54, 11, 82, 94, 121, 21, 53, 90, 180, 128, 225, + 206, 255, 227, 19, 216, 139, 43, 94, 88, 105, 181, 90, 88, 173, 86, 28, 56, 112, 224, 210, 240, 17, 35, + 214, 108, 218, 180, 105, 63, 0, 78, 166, 106, 37, 110, 11, 122, 17, 91, 181, 138, 231, 181, 162, 119, 221, + 117, 23, 230, 206, 157, 75, 239, 191, 255, 254, 4, 159, 33, 131, 193, 40, 11, 76, 96, 49, 24, 149, 148, + 155, 8, 38, 21, 139, 170, 128, 204, 35, 24, 246, 102, 25, 247, 237, 219, 247, 115, 179, 102, 205, 78, 189, + 249, 230, 155, 255, 232, 212, 177, 227, 211, 89, 89, 89, 86, 151, 203, 133, 155, 29, 233, 47, 23, 162, 132, + 214, 51, 176, 60, 254, 4, 220, 223, 124, 131, 235, 159, 242, 66, 139, 134, 35, 225, 181, 54, 11, 236, 175, + 188, 138, 154, 205, 154, 195, 240, 127, 255, 199, 239, 69, 172, 4, 194, 10, 0, 172, 86, 43, 156, 78, 103, + 112, 236, 216, 177, 155, 167, 77, 159, 254, 181, 211, 233, 44, 6, 34, 185, 86, 130, 137, 93, 90, 185, 146, + 138, 43, 37, 175, 21, 71, 41, 165, 26, 141, 6, 157, 59, 119, 198, 160, 65, 131, 168, 205, 102, 75, 240, 25, + 50, 24, 140, 178, 194, 4, 22, 131, 81, 137, 81, 168, 102, 9, 66, 75, 105, 194, 80, 234, 205, 18, 87, 66, + 34, 66, 43, 24, 12, 250, 10, 10, 10, 190, 222, 176, 97, 195, 161, 174, 93, 187, 62, 247, 250, 107, 175, + 221, 171, 209, 104, 224, 169, 224, 24, 131, 40, 161, 245, 212, 211, 176, 60, 254, 56, 220, 223, 111, 193, + 181, 217, 179, 161, 207, 206, 70, 173, 166, 77, 249, 138, 149, 223, 95, 225, 30, 43, 1, 131, 193, 0, 131, + 193, 128, 141, 95, 127, 125, 108, 196, 136, 17, 171, 15, 30, 60, 248, 43, 0, 132, 19, 247, 133, 170, 85, + 105, 194, 74, 92, 181, 18, 63, 151, 145, 248, 133, 204, 204, 76, 76, 159, 62, 157, 190, 248, 226, 139, 137, + 61, 65, 6, 131, 113, 195, 48, 129, 197, 96, 84, 1, 20, 226, 28, 34, 255, 25, 177, 21, 45, 57, 129, 37, 91, + 205, 58, 127, 254, 252, 133, 222, 189, 123, 23, 172, 88, 177, 98, 111, 207, 158, 61, 255, 121, 223, 223, + 254, 150, 229, 245, 120, 16, 184, 193, 252, 164, 114, 135, 82, 112, 238, 176, 208, 122, 244, 49, 88, 31, + 121, 20, 32, 4, 52, 20, 170, 52, 194, 74, 48, 177, 159, 56, 113, 162, 120, 236, 184, 113, 235, 151, 47, 95, + 190, 131, 227, 56, 95, 216, 107, 37, 222, 49, 41, 39, 172, 148, 22, 52, 7, 33, 169, 90, 1, 64, 163, 70, + 141, 48, 102, 204, 24, 90, 183, 110, 221, 132, 158, 35, 131, 193, 184, 57, 152, 192, 98, 48, 170, 8, 50, + 213, 44, 46, 206, 71, 105, 219, 80, 234, 205, 10, 128, 15, 39, 13, 132, 253, 89, 134, 45, 91, 182, 236, + 111, 208, 160, 193, 177, 198, 141, 26, 61, 252, 222, 123, 239, 61, 81, 183, 110, 93, 115, 133, 183, 13, + 129, 40, 51, 60, 42, 65, 48, 178, 128, 197, 98, 129, 207, 231, 227, 102, 206, 154, 181, 115, 210, 164, 73, + 27, 46, 95, 190, 124, 9, 252, 211, 19, 68, 108, 213, 74, 44, 178, 132, 175, 251, 69, 15, 113, 213, 42, 42, + 126, 33, 43, 43, 11, 227, 199, 143, 167, 111, 188, 241, 70, 130, 207, 144, 193, 96, 252, 22, 152, 192, 98, + 48, 170, 24, 113, 170, 89, 74, 190, 44, 105, 53, 75, 60, 153, 38, 124, 52, 18, 66, 140, 62, 159, 207, 51, + 115, 214, 172, 117, 107, 214, 174, 61, 208, 169, 99, 199, 103, 94, 123, 237, 181, 123, 77, 38, 19, 113, + 187, 221, 9, 60, 67, 5, 42, 137, 184, 18, 218, 129, 155, 55, 111, 62, 241, 241, 168, 81, 107, 247, 236, + 217, 243, 51, 0, 26, 14, 12, 245, 74, 30, 114, 237, 64, 177, 184, 138, 236, 149, 132, 76, 213, 170, 97, + 195, 134, 24, 55, 110, 28, 77, 79, 79, 79, 232, 57, 50, 24, 140, 223, 14, 19, 88, 12, 70, 21, 164, 148, + 106, 150, 82, 37, 75, 169, 93, 24, 211, 54, 60, 123, 246, 236, 249, 62, 185, 185, 11, 150, 46, 93, 186, + 187, 91, 183, 110, 207, 61, 244, 208, 67, 183, 6, 2, 1, 248, 124, 190, 68, 158, 102, 165, 66, 152, 14, 60, + 118, 236, 88, 209, 196, 73, 147, 54, 46, 91, 182, 108, 71, 40, 20, 146, 107, 7, 202, 85, 174, 228, 132, + 149, 162, 215, 170, 70, 141, 26, 24, 58, 116, 40, 109, 223, 190, 125, 98, 79, 146, 193, 96, 148, 27, 76, + 96, 49, 24, 85, 152, 56, 171, 118, 148, 76, 240, 114, 66, 203, 47, 249, 115, 128, 16, 98, 164, 148, 26, + 182, 239, 216, 113, 176, 73, 147, 38, 191, 254, 247, 191, 255, 189, 175, 67, 135, 14, 79, 223, 113, 199, + 29, 53, 220, 46, 23, 130, 21, 24, 82, 154, 104, 8, 33, 176, 90, 173, 112, 20, 23, 7, 38, 79, 158, 188, 61, + 47, 47, 111, 211, 181, 235, 215, 175, 0, 208, 200, 180, 3, 229, 196, 149, 56, 211, 74, 154, 107, 21, 83, + 181, 122, 246, 217, 103, 49, 101, 202, 20, 122, 199, 29, 119, 36, 244, 60, 25, 12, 70, 249, 194, 4, 22, + 131, 81, 197, 185, 129, 220, 44, 37, 3, 188, 95, 238, 163, 80, 205, 10, 134, 66, 190, 37, 75, 151, 110, 94, + 183, 126, 253, 79, 173, 90, 182, 124, 180, 121, 243, 230, 15, 165, 166, 166, 26, 42, 133, 63, 75, 101, 204, + 102, 51, 40, 165, 88, 181, 106, 213, 161, 241, 19, 38, 172, 59, 116, 232, 208, 9, 0, 8, 183, 3, 221, 80, + 174, 90, 73, 167, 3, 165, 194, 74, 104, 9, 70, 170, 86, 117, 234, 212, 193, 248, 241, 227, 233, 155, 111, + 190, 201, 246, 0, 50, 24, 213, 0, 38, 176, 24, 140, 106, 66, 25, 114, 179, 132, 138, 137, 82, 110, 150, 80, + 97, 49, 67, 82, 205, 2, 96, 44, 42, 42, 186, 62, 118, 220, 184, 149, 203, 150, 47, 223, 211, 161, 125, 251, + 167, 254, 243, 159, 255, 220, 99, 50, 153, 52, 30, 143, 167, 66, 151, 40, 171, 129, 193, 96, 128, 209, 104, + 196, 238, 221, 187, 207, 141, 159, 48, 97, 253, 198, 141, 27, 127, 4, 255, 179, 0, 74, 68, 147, 156, 145, + 93, 73, 88, 201, 166, 177, 67, 180, 9, 168, 105, 211, 166, 180, 97, 195, 134, 137, 57, 65, 6, 131, 161, 58, + 76, 96, 49, 24, 213, 136, 82, 170, 89, 26, 148, 173, 101, 40, 22, 91, 38, 72, 132, 214, 241, 227, 199, 207, + 244, 232, 217, 179, 96, 193, 130, 5, 127, 232, 208, 177, 227, 211, 79, 60, 254, 248, 237, 148, 210, 138, + 207, 207, 42, 7, 116, 58, 29, 44, 22, 11, 142, 253, 250, 107, 113, 94, 94, 222, 55, 75, 150, 44, 217, 225, + 243, 249, 92, 224, 127, 164, 1, 200, 123, 173, 196, 173, 64, 113, 88, 168, 52, 48, 84, 42, 172, 40, 80, + 242, 156, 177, 170, 21, 131, 81, 189, 96, 2, 139, 193, 168, 134, 132, 171, 89, 226, 47, 41, 69, 57, 40, + 229, 101, 73, 35, 4, 164, 21, 45, 195, 206, 93, 187, 14, 181, 106, 213, 234, 215, 103, 158, 121, 230, 207, + 29, 218, 183, 127, 234, 222, 123, 239, 205, 168, 170, 70, 120, 33, 207, 234, 202, 149, 43, 190, 105, 211, + 166, 109, 155, 57, 107, 214, 230, 107, 215, 174, 93, 1, 47, 172, 132, 176, 208, 120, 85, 43, 241, 127, 23, + 183, 3, 165, 94, 171, 168, 170, 21, 173, 110, 165, 63, 6, 131, 17, 129, 9, 44, 6, 163, 154, 18, 190, 119, + 223, 136, 9, 94, 201, 151, 21, 83, 205, 2, 31, 235, 96, 224, 56, 142, 124, 245, 213, 87, 187, 54, 109, 218, + 116, 232, 213, 87, 94, 185, 239, 237, 183, 223, 126, 252, 15, 127, 248, 67, 77, 111, 69, 239, 55, 44, 35, + 26, 141, 6, 22, 139, 5, 110, 183, 59, 84, 80, 80, 176, 239, 147, 41, 83, 190, 62, 121, 242, 228, 89, 32, + 226, 179, 18, 139, 39, 105, 213, 170, 44, 237, 64, 241, 207, 24, 144, 84, 173, 24, 12, 70, 245, 133, 9, 44, + 6, 163, 154, 35, 170, 102, 73, 219, 134, 74, 171, 118, 164, 190, 44, 185, 182, 161, 31, 225, 236, 44, 0, + 70, 191, 223, 239, 89, 184, 104, 209, 183, 171, 86, 173, 218, 215, 160, 65, 131, 7, 91, 180, 104, 241, 240, + 173, 183, 222, 106, 115, 187, 221, 8, 86, 116, 34, 188, 12, 132, 16, 152, 205, 102, 4, 131, 65, 186, 106, + 245, 234, 35, 147, 39, 77, 218, 120, 224, 199, 31, 127, 5, 191, 148, 153, 130, 63, 191, 223, 34, 172, 162, + 162, 23, 80, 242, 115, 103, 218, 138, 193, 72, 18, 152, 192, 98, 48, 146, 128, 27, 168, 102, 133, 192, 95, + 23, 228, 42, 90, 226, 135, 17, 209, 254, 44, 3, 0, 131, 195, 233, 44, 158, 62, 99, 198, 87, 203, 150, 47, + 223, 221, 164, 113, 227, 127, 52, 110, 220, 248, 239, 25, 25, 25, 230, 202, 36, 180, 204, 102, 51, 64, 8, + 54, 111, 222, 124, 124, 242, 228, 201, 95, 127, 191, 117, 235, 97, 240, 25, 96, 64, 201, 249, 41, 9, 171, + 178, 250, 172, 196, 226, 10, 0, 83, 86, 12, 70, 178, 193, 4, 22, 131, 145, 68, 200, 152, 224, 197, 15, 165, + 106, 150, 146, 249, 93, 252, 185, 9, 34, 127, 214, 229, 203, 151, 175, 142, 27, 63, 126, 213, 130, 133, 11, + 119, 54, 111, 214, 236, 161, 6, 13, 26, 220, 95, 187, 118, 109, 163, 199, 227, 169, 48, 161, 101, 50, 153, + 160, 213, 106, 177, 115, 231, 206, 51, 83, 243, 242, 54, 109, 216, 176, 225, 39, 142, 227, 124, 136, 94, + 111, 35, 87, 181, 242, 73, 62, 151, 230, 89, 201, 77, 7, 70, 242, 43, 152, 176, 98, 48, 146, 19, 38, 176, + 24, 140, 36, 68, 33, 9, 94, 248, 92, 35, 250, 154, 220, 180, 161, 184, 138, 37, 173, 106, 5, 0, 24, 132, + 138, 214, 249, 243, 231, 47, 142, 24, 57, 114, 69, 97, 97, 225, 246, 230, 205, 155, 63, 244, 234, 171, 175, + 254, 53, 45, 45, 45, 161, 66, 203, 100, 50, 65, 167, 211, 97, 223, 190, 125, 23, 166, 77, 159, 254, 237, + 234, 213, 171, 247, 5, 131, 65, 79, 248, 252, 131, 162, 227, 151, 138, 41, 165, 138, 149, 80, 181, 146, 10, + 43, 102, 98, 103, 48, 24, 17, 152, 192, 98, 48, 146, 24, 145, 208, 2, 162, 219, 134, 82, 243, 187, 116, + 113, 180, 212, 8, 239, 131, 200, 155, 37, 60, 194, 66, 75, 127, 242, 212, 169, 115, 131, 135, 12, 89, 154, + 63, 123, 246, 247, 45, 90, 180, 120, 232, 181, 176, 208, 82, 179, 117, 24, 17, 86, 63, 252, 112, 97, 230, + 172, 89, 155, 191, 88, 181, 106, 159, 223, 239, 23, 34, 23, 66, 136, 246, 89, 197, 171, 92, 73, 167, 41, + 229, 194, 66, 133, 143, 0, 110, 78, 88, 157, 62, 125, 26, 123, 247, 238, 133, 195, 225, 184, 217, 83, 46, + 23, 180, 90, 45, 92, 46, 23, 252, 126, 127, 133, 30, 7, 131, 81, 213, 33, 149, 225, 23, 172, 179, 103, 207, + 226, 206, 59, 239, 132, 203, 229, 130, 100, 180, 156, 193, 168, 244, 84, 134, 247, 80, 121, 64, 162, 223, + 124, 4, 124, 37, 139, 0, 208, 134, 63, 215, 133, 63, 215, 135, 31, 134, 240, 67, 16, 84, 66, 171, 208, 40, + 250, 104, 20, 253, 61, 3, 165, 148, 0, 32, 183, 222, 122, 107, 70, 147, 198, 141, 255, 241, 202, 43, 175, + 220, 155, 153, 153, 105, 246, 120, 60, 229, 54, 117, 40, 180, 2, 247, 239, 219, 119, 225, 211, 89, 179, 54, + 175, 94, 189, 122, 159, 40, 203, 74, 92, 177, 146, 171, 90, 137, 43, 86, 74, 6, 246, 168, 197, 204, 225, + 111, 75, 37, 31, 111, 138, 202, 244, 90, 98, 215, 98, 70, 85, 132, 82, 138, 69, 139, 22, 161, 126, 253, + 250, 21, 125, 40, 76, 96, 49, 24, 191, 149, 202, 240, 30, 42, 79, 74, 17, 90, 90, 240, 66, 75, 120, 136, + 133, 150, 88, 84, 73, 133, 150, 65, 244, 81, 31, 22, 90, 200, 200, 200, 168, 219, 184, 113, 227, 7, 95, + 127, 237, 181, 191, 221, 114, 203, 45, 86, 175, 215, 123, 83, 149, 19, 66, 8, 76, 38, 19, 52, 26, 13, 246, + 237, 219, 119, 97, 230, 172, 89, 155, 87, 173, 90, 181, 223, 239, 247, 59, 81, 34, 172, 196, 213, 54, 113, + 197, 74, 42, 170, 132, 135, 88, 88, 41, 165, 176, 151, 139, 176, 18, 168, 76, 175, 37, 118, 45, 102, 84, + 69, 152, 192, 146, 192, 4, 22, 163, 42, 83, 25, 222, 67, 229, 141, 140, 200, 18, 30, 154, 240, 67, 44, 180, + 196, 21, 45, 177, 152, 146, 171, 102, 137, 43, 90, 122, 74, 169, 6, 0, 77, 75, 75, 75, 123, 253, 245, 215, + 239, 107, 240, 214, 91, 247, 255, 254, 247, 191, 175, 17, 8, 4, 224, 245, 122, 203, 114, 156, 145, 125, + 129, 187, 119, 239, 62, 51, 115, 214, 172, 45, 235, 215, 175, 255, 81, 84, 177, 18, 90, 129, 130, 176, 18, + 79, 8, 202, 9, 43, 57, 3, 187, 180, 98, 21, 229, 179, 66, 57, 137, 43, 6, 131, 241, 219, 169, 76, 2, 139, + 121, 176, 24, 12, 70, 12, 10, 211, 134, 82, 127, 150, 220, 94, 195, 0, 120, 241, 36, 54, 190, 11, 254, 44, + 163, 228, 97, 32, 132, 232, 193, 79, 29, 94, 201, 203, 203, 91, 91, 80, 80, 176, 237, 229, 151, 95, 254, + 75, 195, 6, 13, 30, 188, 231, 207, 127, 78, 167, 0, 228, 118, 29, 10, 1, 161, 254, 64, 0, 223, 125, 247, + 221, 175, 249, 179, 103, 127, 191, 105, 211, 166, 195, 34, 243, 58, 135, 232, 86, 160, 156, 207, 202, 39, + 249, 111, 98, 127, 153, 216, 123, 198, 132, 21, 131, 193, 184, 97, 152, 192, 98, 48, 24, 138, 148, 34, 180, + 228, 204, 240, 98, 161, 37, 21, 55, 210, 246, 97, 164, 154, 37, 152, 225, 29, 14, 71, 81, 65, 65, 193, 55, + 75, 150, 44, 217, 245, 244, 83, 79, 221, 253, 255, 219, 187, 131, 157, 54, 142, 48, 128, 227, 223, 122, + 141, 15, 126, 6, 42, 85, 61, 114, 78, 233, 11, 240, 22, 245, 219, 149, 156, 57, 112, 40, 121, 131, 202, + 244, 20, 9, 170, 74, 229, 210, 67, 159, 192, 32, 76, 154, 108, 15, 241, 148, 217, 101, 108, 104, 89, 178, + 219, 242, 251, 73, 22, 144, 200, 97, 79, 209, 95, 51, 227, 111, 190, 95, 44, 14, 191, 59, 60, 252, 122, 54, + 155, 197, 205, 205, 77, 84, 85, 21, 243, 249, 60, 174, 175, 175, 63, 157, 158, 158, 254, 250, 195, 241, + 241, 79, 203, 229, 242, 170, 105, 154, 187, 205, 115, 230, 43, 86, 221, 97, 161, 221, 45, 192, 238, 25, + 171, 210, 133, 204, 15, 198, 46, 132, 176, 2, 158, 64, 96, 1, 143, 218, 49, 63, 43, 15, 172, 58, 218, 43, + 90, 211, 104, 175, 104, 165, 200, 202, 99, 171, 180, 162, 181, 183, 94, 175, 111, 126, 60, 59, 251, 249, + 236, 221, 187, 247, 223, 190, 121, 243, 205, 98, 177, 56, 60, 58, 58, 58, 248, 112, 119, 247, 241, 228, + 228, 228, 253, 241, 219, 183, 203, 139, 139, 139, 223, 55, 191, 171, 116, 198, 106, 87, 92, 149, 238, 89, + 220, 181, 98, 213, 235, 57, 43, 224, 117, 16, 88, 240, 76, 175, 236, 220, 96, 138, 140, 252, 218, 157, 109, + 91, 134, 211, 104, 207, 206, 234, 134, 214, 131, 192, 138, 78, 104, 53, 77, 211, 44, 207, 207, 47, 150, + 231, 231, 191, 28, 28, 28, 124, 181, 94, 175, 255, 188, 186, 186, 250, 35, 61, 67, 22, 86, 31, 162, 29, 80, + 165, 79, 3, 62, 54, 36, 116, 219, 1, 246, 8, 113, 5, 252, 67, 2, 11, 248, 55, 186, 241, 81, 69, 251, 122, + 152, 93, 219, 134, 165, 208, 154, 21, 190, 223, 219, 132, 86, 29, 17, 147, 203, 203, 203, 223, 34, 34, 170, + 170, 154, 68, 123, 210, 124, 233, 156, 85, 41, 172, 242, 109, 192, 252, 106, 155, 244, 220, 206, 89, 1, + 189, 17, 88, 192, 115, 228, 103, 178, 34, 218, 103, 150, 38, 177, 253, 32, 252, 93, 124, 254, 228, 225, 58, + 202, 113, 53, 203, 94, 117, 68, 212, 155, 176, 74, 191, 163, 52, 89, 190, 20, 87, 221, 51, 86, 165, 173, + 64, 97, 5, 244, 78, 96, 1, 207, 213, 221, 54, 236, 126, 226, 48, 133, 86, 29, 237, 48, 74, 103, 180, 242, + 161, 159, 15, 70, 57, 196, 253, 128, 211, 109, 129, 85, 218, 2, 236, 174, 88, 229, 219, 129, 194, 10, 120, + 113, 2, 11, 232, 203, 99, 161, 149, 98, 171, 123, 70, 107, 26, 247, 43, 90, 41, 148, 82, 92, 165, 45, 194, + 233, 230, 223, 138, 104, 111, 63, 230, 129, 86, 250, 68, 160, 176, 2, 6, 33, 176, 128, 190, 61, 117, 69, + 43, 69, 82, 29, 159, 131, 40, 5, 214, 94, 246, 74, 171, 87, 117, 220, 7, 86, 19, 229, 243, 93, 187, 38, + 175, 11, 43, 224, 139, 18, 88, 192, 75, 217, 22, 90, 41, 178, 210, 193, 248, 52, 222, 33, 31, 237, 144, + 194, 42, 223, 30, 236, 6, 86, 190, 85, 216, 93, 173, 18, 86, 192, 160, 4, 22, 240, 210, 182, 141, 118, 72, + 127, 151, 86, 179, 38, 113, 191, 162, 53, 141, 251, 43, 121, 210, 245, 60, 85, 225, 61, 249, 74, 88, 126, + 160, 222, 167, 2, 129, 65, 9, 44, 224, 75, 41, 197, 205, 199, 104, 175, 106, 229, 193, 52, 233, 188, 114, + 159, 58, 175, 124, 134, 149, 176, 2, 6, 39, 176, 128, 33, 148, 182, 15, 83, 28, 165, 75, 165, 243, 175, + 221, 105, 174, 221, 144, 50, 32, 20, 24, 21, 129, 5, 12, 105, 215, 129, 248, 244, 231, 85, 246, 125, 254, + 158, 238, 53, 54, 194, 10, 24, 13, 129, 5, 140, 65, 41, 180, 210, 207, 79, 121, 223, 182, 159, 1, 6, 49, + 154, 192, 218, 220, 37, 251, 247, 87, 224, 85, 218, 22, 76, 165, 45, 66, 128, 7, 198, 210, 17, 163, 8, 172, + 186, 174, 99, 127, 127, 63, 86, 171, 85, 212, 117, 61, 244, 227, 0, 227, 51, 142, 255, 49, 129, 81, 91, + 173, 86, 49, 159, 207, 135, 126, 140, 136, 136, 168, 198, 80, 122, 77, 211, 196, 237, 237, 237, 208, 143, + 1, 0, 252, 199, 205, 102, 179, 81, 44, 214, 140, 34, 176, 0, 0, 254, 79, 186, 179, 101, 0, 0, 120, 38, 129, + 5, 0, 208, 51, 129, 5, 0, 208, 51, 129, 5, 0, 208, 51, 129, 5, 0, 208, 51, 129, 5, 0, 208, 51, 129, 5, 0, + 208, 51, 129, 5, 0, 208, 51, 129, 5, 0, 208, 51, 129, 5, 0, 208, 51, 129, 5, 0, 208, 51, 129, 5, 0, 208, + 179, 191, 0, 222, 233, 176, 253, 2, 172, 58, 209, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130 + ); +Procedure WriteAsset( + Const ABaseDir, + ARelativeName : String; + Const AData; + ASize : Integer); +Var + LFileName, + LDirName : String; + LStream : TFileStream; +Begin + LFileName := + IncludeTrailingPathDelimiter(ABaseDir) + + ARelativeName; + LDirName := ExtractFileDir(LFileName); + If Not DirectoryExists(LDirName) Then + ForceDirectories(LDirName); + If FileExists(LFileName) Then + Exit; + LStream := TFileStream.Create( + LFileName, + fmCreate + ); + Try + LStream.WriteBuffer( + AData, + ASize + ); + Finally + LStream.Free; + End; +End; + +Const + CEditorAsset0 : Array[0..19001] Of Byte = ( + 91,80,97,99,107,97,103,101,93,13,10,78,97,109,101,61,66,111,111,116, + 115,116,114,97,112,13,10,69,110,97,98,108,101,100,61,49,13,10,74,115, + 70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106, + 115,13,10,70,111,114,109,97,116,86,101,114,115,105,111,110,61,49,13,10, + 79,114,100,101,114,61,49,48,13,10,13,10,91,67,111,109,112,111,110,101, + 110,116,46,99,111,110,116,97,105,110,101,114,93,13,10,78,97,109,101,61, + 67,111,110,116,97,105,110,101,114,13,10,78,97,109,101,67,108,97,115,115, + 61,82,69,83,84,68,87,67,111,110,116,97,105,110,101,114,13,10,80,97, + 108,101,116,116,101,61,76,97,121,111,117,116,13,10,74,115,70,105,108,101, + 78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67, + 108,97,115,115,84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67, + 108,97,115,115,61,99,111,110,116,97,105,110,101,114,32,112,45,51,13,10, + 72,105,110,116,61,67,111,110,116,97,105,110,101,114,13,10,67,108,97,115, + 115,73,99,111,110,61,105,99,111,110,115,47,99,111,110,116,97,105,110,101, + 114,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111, + 110,61,13,10,79,114,100,101,114,61,49,13,10,73,110,115,116,97,108,108, + 101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,99, + 111,110,116,97,105,110,101,114,95,102,108,117,105,100,93,13,10,78,97,109, + 101,61,67,111,110,116,97,105,110,101,114,32,70,108,117,105,100,13,10,78, + 97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,67,111,110,116,97, + 105,110,101,114,95,70,108,117,105,100,13,10,80,97,108,101,116,116,101,61, + 76,97,121,111,117,116,13,10,74,115,70,105,108,101,78,97,109,101,61,98, + 111,111,116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121, + 112,101,61,100,105,118,13,10,76,97,98,101,108,67,108,97,115,115,61,99, + 111,110,116,97,105,110,101,114,45,102,108,117,105,100,32,112,45,51,13,10, + 72,105,110,116,61,67,111,110,116,97,105,110,101,114,32,70,108,117,105,100, + 13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,99,111, + 110,116,97,105,110,101,114,95,102,108,117,105,100,46,98,109,112,13,10,104, + 116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101, + 114,61,50,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10, + 91,67,111,109,112,111,110,101,110,116,46,114,111,119,93,13,10,78,97,109, + 101,61,82,111,119,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83, + 84,68,87,82,111,119,13,10,80,97,108,101,116,116,101,61,76,97,121,111, + 117,116,13,10,74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115, + 116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,100, + 105,118,13,10,76,97,98,101,108,67,108,97,115,115,61,114,111,119,13,10, + 72,105,110,116,61,82,111,119,13,10,67,108,97,115,115,73,99,111,110,61, + 105,99,111,110,115,47,114,111,119,46,98,109,112,13,10,104,116,109,108,95, + 101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,51,13, + 10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109, + 112,111,110,101,110,116,46,99,111,108,117,109,110,115,95,54,95,54,93,13, + 10,78,97,109,101,61,67,111,108,117,109,110,115,32,54,32,43,32,54,13, + 10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,67,111,108, + 117,109,110,115,95,54,95,54,13,10,80,97,108,101,116,116,101,61,76,97, + 121,111,117,116,13,10,74,115,70,105,108,101,78,97,109,101,61,98,111,111, + 116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121,112,101, + 61,100,105,118,13,10,76,97,98,101,108,67,108,97,115,115,61,114,111,119, + 13,10,72,105,110,116,61,67,111,108,117,109,110,115,32,54,32,43,32,54, + 13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,99,111, + 108,117,109,110,115,95,54,95,54,46,98,109,112,13,10,104,116,109,108,95, + 101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,52,13, + 10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109, + 112,111,110,101,110,116,46,99,111,108,117,109,110,115,95,52,95,52,95,52, + 93,13,10,78,97,109,101,61,67,111,108,117,109,110,115,32,52,32,43,32, + 52,32,43,32,52,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83, + 84,68,87,67,111,108,117,109,110,115,95,52,95,52,95,52,13,10,80,97, + 108,101,116,116,101,61,76,97,121,111,117,116,13,10,74,115,70,105,108,101, + 78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67, + 108,97,115,115,84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67, + 108,97,115,115,61,114,111,119,13,10,72,105,110,116,61,67,111,108,117,109, + 110,115,32,52,32,43,32,52,32,43,32,52,13,10,67,108,97,115,115,73, + 99,111,110,61,105,99,111,110,115,47,99,111,108,117,109,110,115,95,52,95, + 52,95,52,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115, + 105,111,110,61,13,10,79,114,100,101,114,61,53,13,10,73,110,115,116,97, + 108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116, + 46,99,111,108,117,109,110,115,95,51,95,57,93,13,10,78,97,109,101,61, + 67,111,108,117,109,110,115,32,51,32,43,32,57,13,10,78,97,109,101,67, + 108,97,115,115,61,82,69,83,84,68,87,67,111,108,117,109,110,115,95,51, + 95,57,13,10,80,97,108,101,116,116,101,61,76,97,121,111,117,116,13,10, + 74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112, + 46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,100,105,118,13,10, + 76,97,98,101,108,67,108,97,115,115,61,114,111,119,13,10,72,105,110,116, + 61,67,111,108,117,109,110,115,32,51,32,43,32,57,13,10,67,108,97,115, + 115,73,99,111,110,61,105,99,111,110,115,47,99,111,108,117,109,110,115,95, + 51,95,57,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115, + 105,111,110,61,13,10,79,114,100,101,114,61,54,13,10,73,110,115,116,97, + 108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116, + 46,102,108,101,120,95,114,111,119,93,13,10,78,97,109,101,61,70,108,101, + 120,32,82,111,119,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83, + 84,68,87,70,108,101,120,95,82,111,119,13,10,80,97,108,101,116,116,101, + 61,76,97,121,111,117,116,13,10,74,115,70,105,108,101,78,97,109,101,61, + 98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84, + 121,112,101,61,100,105,118,13,10,76,97,98,101,108,67,108,97,115,115,61, + 100,45,102,108,101,120,32,103,97,112,45,50,13,10,72,105,110,116,61,70, + 108,101,120,32,82,111,119,13,10,67,108,97,115,115,73,99,111,110,61,105, + 99,111,110,115,47,102,108,101,120,95,114,111,119,46,98,109,112,13,10,104, + 116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101, + 114,61,55,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10, + 91,67,111,109,112,111,110,101,110,116,46,103,114,105,100,93,13,10,78,97, + 109,101,61,71,114,105,100,13,10,78,97,109,101,67,108,97,115,115,61,82, + 69,83,84,68,87,71,114,105,100,13,10,80,97,108,101,116,116,101,61,76, + 97,121,111,117,116,13,10,74,115,70,105,108,101,78,97,109,101,61,98,111, + 111,116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121,112, + 101,61,100,105,118,13,10,76,97,98,101,108,67,108,97,115,115,61,100,45, + 103,114,105,100,32,103,97,112,45,50,13,10,72,105,110,116,61,71,114,105, + 100,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,103, + 114,105,100,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115, + 105,111,110,61,13,10,79,114,100,101,114,61,56,13,10,73,110,115,116,97, + 108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116, + 46,104,101,97,100,105,110,103,95,104,49,93,13,10,78,97,109,101,61,72, + 101,97,100,105,110,103,32,72,49,13,10,78,97,109,101,67,108,97,115,115, + 61,82,69,83,84,68,87,72,101,97,100,105,110,103,95,72,49,13,10,80, + 97,108,101,116,116,101,61,67,111,110,116,101,110,116,13,10,74,115,70,105, + 108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13, + 10,67,108,97,115,115,84,121,112,101,61,104,49,13,10,76,97,98,101,108, + 67,108,97,115,115,61,13,10,72,105,110,116,61,72,101,97,100,105,110,103, + 32,72,49,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115, + 47,104,101,97,100,105,110,103,95,104,49,46,98,109,112,13,10,104,116,109, + 108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61, + 57,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67, + 111,109,112,111,110,101,110,116,46,104,101,97,100,105,110,103,95,104,50,93, + 13,10,78,97,109,101,61,72,101,97,100,105,110,103,32,72,50,13,10,78, + 97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,72,101,97,100,105, + 110,103,95,72,50,13,10,80,97,108,101,116,116,101,61,67,111,110,116,101, + 110,116,13,10,74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115, + 116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,104, + 50,13,10,76,97,98,101,108,67,108,97,115,115,61,13,10,72,105,110,116, + 61,72,101,97,100,105,110,103,32,72,50,13,10,67,108,97,115,115,73,99, + 111,110,61,105,99,111,110,115,47,104,101,97,100,105,110,103,95,104,50,46, + 98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61, + 13,10,79,114,100,101,114,61,49,48,13,10,73,110,115,116,97,108,108,101, + 100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,104,101, + 97,100,105,110,103,95,104,51,93,13,10,78,97,109,101,61,72,101,97,100, + 105,110,103,32,72,51,13,10,78,97,109,101,67,108,97,115,115,61,82,69, + 83,84,68,87,72,101,97,100,105,110,103,95,72,51,13,10,80,97,108,101, + 116,116,101,61,67,111,110,116,101,110,116,13,10,74,115,70,105,108,101,78, + 97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108, + 97,115,115,84,121,112,101,61,104,51,13,10,76,97,98,101,108,67,108,97, + 115,115,61,13,10,72,105,110,116,61,72,101,97,100,105,110,103,32,72,51, + 13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,104,101, + 97,100,105,110,103,95,104,51,46,98,109,112,13,10,104,116,109,108,95,101, + 120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,49,49,13, + 10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109, + 112,111,110,101,110,116,46,112,97,114,97,103,114,97,112,104,93,13,10,78, + 97,109,101,61,80,97,114,97,103,114,97,112,104,13,10,78,97,109,101,67, + 108,97,115,115,61,82,69,83,84,68,87,80,97,114,97,103,114,97,112,104, + 13,10,80,97,108,101,116,116,101,61,67,111,110,116,101,110,116,13,10,74, + 115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46, + 106,115,13,10,67,108,97,115,115,84,121,112,101,61,112,13,10,76,97,98, + 101,108,67,108,97,115,115,61,13,10,72,105,110,116,61,80,97,114,97,103, + 114,97,112,104,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110, + 115,47,112,97,114,97,103,114,97,112,104,46,98,109,112,13,10,104,116,109, + 108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61, + 49,50,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91, + 67,111,109,112,111,110,101,110,116,46,115,109,97,108,108,95,116,101,120,116, + 93,13,10,78,97,109,101,61,83,109,97,108,108,32,84,101,120,116,13,10, + 78,97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,83,109,97,108, + 108,95,84,101,120,116,13,10,80,97,108,101,116,116,101,61,67,111,110,116, + 101,110,116,13,10,74,115,70,105,108,101,78,97,109,101,61,98,111,111,116, + 115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61, + 115,109,97,108,108,13,10,76,97,98,101,108,67,108,97,115,115,61,13,10, + 72,105,110,116,61,83,109,97,108,108,32,84,101,120,116,13,10,67,108,97, + 115,115,73,99,111,110,61,105,99,111,110,115,47,115,109,97,108,108,95,116, + 101,120,116,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115, + 105,111,110,61,13,10,79,114,100,101,114,61,49,51,13,10,73,110,115,116, + 97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110, + 116,46,108,101,97,100,95,116,101,120,116,93,13,10,78,97,109,101,61,76, + 101,97,100,32,84,101,120,116,13,10,78,97,109,101,67,108,97,115,115,61, + 82,69,83,84,68,87,76,101,97,100,95,84,101,120,116,13,10,80,97,108, + 101,116,116,101,61,67,111,110,116,101,110,116,13,10,74,115,70,105,108,101, + 78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67, + 108,97,115,115,84,121,112,101,61,112,13,10,76,97,98,101,108,67,108,97, + 115,115,61,108,101,97,100,13,10,72,105,110,116,61,76,101,97,100,32,84, + 101,120,116,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115, + 47,108,101,97,100,95,116,101,120,116,46,98,109,112,13,10,104,116,109,108, + 95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,49, + 52,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67, + 111,109,112,111,110,101,110,116,46,105,109,97,103,101,93,13,10,78,97,109, + 101,61,73,109,97,103,101,13,10,78,97,109,101,67,108,97,115,115,61,82, + 69,83,84,68,87,73,109,97,103,101,13,10,80,97,108,101,116,116,101,61, + 67,111,110,116,101,110,116,13,10,74,115,70,105,108,101,78,97,109,101,61, + 98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84, + 121,112,101,61,105,109,103,13,10,76,97,98,101,108,67,108,97,115,115,61, + 105,109,103,45,102,108,117,105,100,32,114,111,117,110,100,101,100,13,10,72, + 105,110,116,61,73,109,97,103,101,13,10,67,108,97,115,115,73,99,111,110, + 61,105,99,111,110,115,47,105,109,97,103,101,46,98,109,112,13,10,104,116, + 109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114, + 61,49,53,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10, + 91,67,111,109,112,111,110,101,110,116,46,99,97,114,100,93,13,10,78,97, + 109,101,61,67,97,114,100,13,10,78,97,109,101,67,108,97,115,115,61,82, + 69,83,84,68,87,67,97,114,100,13,10,80,97,108,101,116,116,101,61,67, + 111,110,116,101,110,116,13,10,74,115,70,105,108,101,78,97,109,101,61,98, + 111,111,116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121, + 112,101,61,100,105,118,13,10,76,97,98,101,108,67,108,97,115,115,61,99, + 97,114,100,13,10,72,105,110,116,61,67,97,114,100,13,10,67,108,97,115, + 115,73,99,111,110,61,105,99,111,110,115,47,99,97,114,100,46,98,109,112, + 13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79, + 114,100,101,114,61,49,54,13,10,73,110,115,116,97,108,108,101,100,61,49, + 13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,99,97,114,100,95, + 119,105,116,104,95,102,111,111,116,101,114,93,13,10,78,97,109,101,61,67, + 97,114,100,32,87,105,116,104,32,70,111,111,116,101,114,13,10,78,97,109, + 101,67,108,97,115,115,61,82,69,83,84,68,87,67,97,114,100,95,87,105, + 116,104,95,70,111,111,116,101,114,13,10,80,97,108,101,116,116,101,61,67, + 111,110,116,101,110,116,13,10,74,115,70,105,108,101,78,97,109,101,61,98, + 111,111,116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121, + 112,101,61,100,105,118,13,10,76,97,98,101,108,67,108,97,115,115,61,99, + 97,114,100,13,10,72,105,110,116,61,67,97,114,100,32,87,105,116,104,32, + 70,111,111,116,101,114,13,10,67,108,97,115,115,73,99,111,110,61,105,99, + 111,110,115,47,99,97,114,100,95,119,105,116,104,95,102,111,111,116,101,114, + 46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110, + 61,13,10,79,114,100,101,114,61,49,55,13,10,73,110,115,116,97,108,108, + 101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,108, + 105,115,116,95,103,114,111,117,112,93,13,10,78,97,109,101,61,76,105,115, + 116,32,71,114,111,117,112,13,10,78,97,109,101,67,108,97,115,115,61,82, + 69,83,84,68,87,76,105,115,116,95,71,114,111,117,112,13,10,80,97,108, + 101,116,116,101,61,67,111,110,116,101,110,116,13,10,74,115,70,105,108,101, + 78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67, + 108,97,115,115,84,121,112,101,61,117,108,13,10,76,97,98,101,108,67,108, + 97,115,115,61,108,105,115,116,45,103,114,111,117,112,13,10,72,105,110,116, + 61,76,105,115,116,32,71,114,111,117,112,13,10,67,108,97,115,115,73,99, + 111,110,61,105,99,111,110,115,47,108,105,115,116,95,103,114,111,117,112,46, + 98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61, + 13,10,79,114,100,101,114,61,49,56,13,10,73,110,115,116,97,108,108,101, + 100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,98,97, + 100,103,101,93,13,10,78,97,109,101,61,66,97,100,103,101,13,10,78,97, + 109,101,67,108,97,115,115,61,82,69,83,84,68,87,66,97,100,103,101,13, + 10,80,97,108,101,116,116,101,61,67,111,110,116,101,110,116,13,10,74,115, + 70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106, + 115,13,10,67,108,97,115,115,84,121,112,101,61,115,112,97,110,13,10,76, + 97,98,101,108,67,108,97,115,115,61,98,97,100,103,101,13,10,72,105,110, + 116,61,66,97,100,103,101,13,10,67,108,97,115,115,73,99,111,110,61,105, + 99,111,110,115,47,98,97,100,103,101,46,98,109,112,13,10,104,116,109,108, + 95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,49, + 57,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67, + 111,109,112,111,110,101,110,116,46,104,111,114,105,122,111,110,116,97,108,95, + 114,117,108,101,93,13,10,78,97,109,101,61,72,111,114,105,122,111,110,116, + 97,108,32,82,117,108,101,13,10,78,97,109,101,67,108,97,115,115,61,82, + 69,83,84,68,87,72,111,114,105,122,111,110,116,97,108,95,82,117,108,101, + 13,10,80,97,108,101,116,116,101,61,67,111,110,116,101,110,116,13,10,74, + 115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46, + 106,115,13,10,67,108,97,115,115,84,121,112,101,61,104,114,13,10,76,97, + 98,101,108,67,108,97,115,115,61,13,10,72,105,110,116,61,72,111,114,105, + 122,111,110,116,97,108,32,82,117,108,101,13,10,67,108,97,115,115,73,99, + 111,110,61,105,99,111,110,115,47,104,111,114,105,122,111,110,116,97,108,95, + 114,117,108,101,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110, + 115,105,111,110,61,13,10,79,114,100,101,114,61,50,48,13,10,73,110,115, + 116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101, + 110,116,46,110,97,118,98,97,114,93,13,10,78,97,109,101,61,78,97,118, + 98,97,114,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68, + 87,78,97,118,98,97,114,13,10,80,97,108,101,116,116,101,61,78,97,118, + 105,103,97,116,105,111,110,13,10,74,115,70,105,108,101,78,97,109,101,61, + 98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84, + 121,112,101,61,110,97,118,13,10,76,97,98,101,108,67,108,97,115,115,61, + 110,97,118,98,97,114,13,10,72,105,110,116,61,78,97,118,98,97,114,13, + 10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,110,97,118, + 98,97,114,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115, + 105,111,110,61,13,10,79,114,100,101,114,61,50,49,13,10,73,110,115,116, + 97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110, + 116,46,110,97,118,95,112,105,108,108,115,93,13,10,78,97,109,101,61,78, + 97,118,32,80,105,108,108,115,13,10,78,97,109,101,67,108,97,115,115,61, + 82,69,83,84,68,87,78,97,118,95,80,105,108,108,115,13,10,80,97,108, + 101,116,116,101,61,78,97,118,105,103,97,116,105,111,110,13,10,74,115,70, + 105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115, + 13,10,67,108,97,115,115,84,121,112,101,61,117,108,13,10,76,97,98,101, + 108,67,108,97,115,115,61,110,97,118,13,10,72,105,110,116,61,78,97,118, + 32,80,105,108,108,115,13,10,67,108,97,115,115,73,99,111,110,61,105,99, + 111,110,115,47,110,97,118,95,112,105,108,108,115,46,98,109,112,13,10,104, + 116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101, + 114,61,50,50,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13, + 10,91,67,111,109,112,111,110,101,110,116,46,110,97,118,95,116,97,98,115, + 93,13,10,78,97,109,101,61,78,97,118,32,84,97,98,115,13,10,78,97, + 109,101,67,108,97,115,115,61,82,69,83,84,68,87,78,97,118,95,84,97, + 98,115,13,10,80,97,108,101,116,116,101,61,78,97,118,105,103,97,116,105, + 111,110,13,10,74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115, + 116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,117, + 108,13,10,76,97,98,101,108,67,108,97,115,115,61,110,97,118,13,10,72, + 105,110,116,61,78,97,118,32,84,97,98,115,13,10,67,108,97,115,115,73, + 99,111,110,61,105,99,111,110,115,47,110,97,118,95,116,97,98,115,46,98, + 109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13, + 10,79,114,100,101,114,61,50,51,13,10,73,110,115,116,97,108,108,101,100, + 61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,98,114,101, + 97,100,99,114,117,109,98,93,13,10,78,97,109,101,61,66,114,101,97,100, + 99,114,117,109,98,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83, + 84,68,87,66,114,101,97,100,99,114,117,109,98,13,10,80,97,108,101,116, + 116,101,61,78,97,118,105,103,97,116,105,111,110,13,10,74,115,70,105,108, + 101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10, + 67,108,97,115,115,84,121,112,101,61,111,108,13,10,76,97,98,101,108,67, + 108,97,115,115,61,98,114,101,97,100,99,114,117,109,98,13,10,72,105,110, + 116,61,66,114,101,97,100,99,114,117,109,98,13,10,67,108,97,115,115,73, + 99,111,110,61,105,99,111,110,115,47,98,114,101,97,100,99,114,117,109,98, + 46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110, + 61,13,10,79,114,100,101,114,61,50,52,13,10,73,110,115,116,97,108,108, + 101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,112, + 97,103,105,110,97,116,105,111,110,93,13,10,78,97,109,101,61,80,97,103, + 105,110,97,116,105,111,110,13,10,78,97,109,101,67,108,97,115,115,61,82, + 69,83,84,68,87,80,97,103,105,110,97,116,105,111,110,13,10,80,97,108, + 101,116,116,101,61,78,97,118,105,103,97,116,105,111,110,13,10,74,115,70, + 105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115, + 13,10,67,108,97,115,115,84,121,112,101,61,117,108,13,10,76,97,98,101, + 108,67,108,97,115,115,61,112,97,103,105,110,97,116,105,111,110,13,10,72, + 105,110,116,61,80,97,103,105,110,97,116,105,111,110,13,10,67,108,97,115, + 115,73,99,111,110,61,105,99,111,110,115,47,112,97,103,105,110,97,116,105, + 111,110,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105, + 111,110,61,13,10,79,114,100,101,114,61,50,53,13,10,73,110,115,116,97, + 108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116, + 46,116,101,120,116,95,101,100,105,116,93,13,10,78,97,109,101,61,84,101, + 120,116,32,69,100,105,116,13,10,78,97,109,101,67,108,97,115,115,61,82, + 69,83,84,68,87,84,101,120,116,95,69,100,105,116,13,10,80,97,108,101, + 116,116,101,61,70,111,114,109,115,13,10,74,115,70,105,108,101,78,97,109, + 101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108,97,115, + 115,84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67,108,97,115, + 115,61,109,98,45,51,13,10,72,105,110,116,61,84,101,120,116,32,69,100, + 105,116,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47, + 116,101,120,116,95,101,100,105,116,46,98,109,112,13,10,104,116,109,108,95, + 101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,50,54, + 13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111, + 109,112,111,110,101,110,116,46,112,97,115,115,119,111,114,100,95,101,100,105, + 116,93,13,10,78,97,109,101,61,80,97,115,115,119,111,114,100,32,69,100, + 105,116,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68,87, + 80,97,115,115,119,111,114,100,95,69,100,105,116,13,10,80,97,108,101,116, + 116,101,61,70,111,114,109,115,13,10,74,115,70,105,108,101,78,97,109,101, + 61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115, + 84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67,108,97,115,115, + 61,109,98,45,51,13,10,72,105,110,116,61,80,97,115,115,119,111,114,100, + 32,69,100,105,116,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111, + 110,115,47,112,97,115,115,119,111,114,100,95,101,100,105,116,46,98,109,112, + 13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79, + 114,100,101,114,61,50,55,13,10,73,110,115,116,97,108,108,101,100,61,49, + 13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,101,109,97,105,108, + 95,101,100,105,116,93,13,10,78,97,109,101,61,69,109,97,105,108,32,69, + 100,105,116,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68, + 87,69,109,97,105,108,95,69,100,105,116,13,10,80,97,108,101,116,116,101, + 61,70,111,114,109,115,13,10,74,115,70,105,108,101,78,97,109,101,61,98, + 111,111,116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121, + 112,101,61,100,105,118,13,10,76,97,98,101,108,67,108,97,115,115,61,109, + 98,45,51,13,10,72,105,110,116,61,69,109,97,105,108,32,69,100,105,116, + 13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,101,109, + 97,105,108,95,101,100,105,116,46,98,109,112,13,10,104,116,109,108,95,101, + 120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,50,56,13, + 10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109, + 112,111,110,101,110,116,46,115,101,97,114,99,104,95,101,100,105,116,93,13, + 10,78,97,109,101,61,83,101,97,114,99,104,32,69,100,105,116,13,10,78, + 97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,83,101,97,114,99, + 104,95,69,100,105,116,13,10,80,97,108,101,116,116,101,61,70,111,114,109, + 115,13,10,74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116, + 114,97,112,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,100,105, + 118,13,10,76,97,98,101,108,67,108,97,115,115,61,109,98,45,51,13,10, + 72,105,110,116,61,83,101,97,114,99,104,32,69,100,105,116,13,10,67,108, + 97,115,115,73,99,111,110,61,105,99,111,110,115,47,115,101,97,114,99,104, + 95,101,100,105,116,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101, + 110,115,105,111,110,61,13,10,79,114,100,101,114,61,50,57,13,10,73,110, + 115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110, + 101,110,116,46,110,117,109,98,101,114,95,101,100,105,116,93,13,10,78,97, + 109,101,61,78,117,109,98,101,114,32,69,100,105,116,13,10,78,97,109,101, + 67,108,97,115,115,61,82,69,83,84,68,87,78,117,109,98,101,114,95,69, + 100,105,116,13,10,80,97,108,101,116,116,101,61,70,111,114,109,115,13,10, + 74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112, + 46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,100,105,118,13,10, + 76,97,98,101,108,67,108,97,115,115,61,109,98,45,51,13,10,72,105,110, + 116,61,78,117,109,98,101,114,32,69,100,105,116,13,10,67,108,97,115,115, + 73,99,111,110,61,105,99,111,110,115,47,110,117,109,98,101,114,95,101,100, + 105,116,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105, + 111,110,61,13,10,79,114,100,101,114,61,51,48,13,10,73,110,115,116,97, + 108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116, + 46,100,101,99,105,109,97,108,95,101,100,105,116,93,13,10,78,97,109,101, + 61,68,101,99,105,109,97,108,32,69,100,105,116,13,10,78,97,109,101,67, + 108,97,115,115,61,82,69,83,84,68,87,68,101,99,105,109,97,108,95,69, + 100,105,116,13,10,80,97,108,101,116,116,101,61,70,111,114,109,115,13,10, + 74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112, + 46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,100,105,118,13,10, + 76,97,98,101,108,67,108,97,115,115,61,109,98,45,51,13,10,72,105,110, + 116,61,68,101,99,105,109,97,108,32,69,100,105,116,13,10,67,108,97,115, + 115,73,99,111,110,61,105,99,111,110,115,47,100,101,99,105,109,97,108,95, + 101,100,105,116,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110, + 115,105,111,110,61,13,10,79,114,100,101,114,61,51,49,13,10,73,110,115, + 116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101, + 110,116,46,109,111,110,101,121,95,101,100,105,116,93,13,10,78,97,109,101, + 61,77,111,110,101,121,32,69,100,105,116,13,10,78,97,109,101,67,108,97, + 115,115,61,82,69,83,84,68,87,77,111,110,101,121,95,69,100,105,116,13, + 10,80,97,108,101,116,116,101,61,70,111,114,109,115,13,10,74,115,70,105, + 108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13, + 10,67,108,97,115,115,84,121,112,101,61,100,105,118,13,10,76,97,98,101, + 108,67,108,97,115,115,61,109,98,45,51,13,10,72,105,110,116,61,77,111, + 110,101,121,32,69,100,105,116,13,10,67,108,97,115,115,73,99,111,110,61, + 105,99,111,110,115,47,109,111,110,101,121,95,101,100,105,116,46,98,109,112, + 13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79, + 114,100,101,114,61,51,50,13,10,73,110,115,116,97,108,108,101,100,61,49, + 13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,112,101,114,99,101, + 110,116,95,101,100,105,116,93,13,10,78,97,109,101,61,80,101,114,99,101, + 110,116,32,69,100,105,116,13,10,78,97,109,101,67,108,97,115,115,61,82, + 69,83,84,68,87,80,101,114,99,101,110,116,95,69,100,105,116,13,10,80, + 97,108,101,116,116,101,61,70,111,114,109,115,13,10,74,115,70,105,108,101, + 78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67, + 108,97,115,115,84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67, + 108,97,115,115,61,109,98,45,51,13,10,72,105,110,116,61,80,101,114,99, + 101,110,116,32,69,100,105,116,13,10,67,108,97,115,115,73,99,111,110,61, + 105,99,111,110,115,47,112,101,114,99,101,110,116,95,101,100,105,116,46,98, + 109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13, + 10,79,114,100,101,114,61,51,51,13,10,73,110,115,116,97,108,108,101,100, + 61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,100,97,116, + 101,95,112,105,99,107,101,114,93,13,10,78,97,109,101,61,68,97,116,101, + 32,80,105,99,107,101,114,13,10,78,97,109,101,67,108,97,115,115,61,82, + 69,83,84,68,87,68,97,116,101,95,80,105,99,107,101,114,13,10,80,97, + 108,101,116,116,101,61,70,111,114,109,115,13,10,74,115,70,105,108,101,78, + 97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108, + 97,115,115,84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67,108, + 97,115,115,61,109,98,45,51,13,10,72,105,110,116,61,68,97,116,101,32, + 80,105,99,107,101,114,13,10,67,108,97,115,115,73,99,111,110,61,105,99, + 111,110,115,47,100,97,116,101,95,112,105,99,107,101,114,46,98,109,112,13, + 10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114, + 100,101,114,61,51,52,13,10,73,110,115,116,97,108,108,101,100,61,49,13, + 10,13,10,91,67,111,109,112,111,110,101,110,116,46,116,105,109,101,95,112, + 105,99,107,101,114,93,13,10,78,97,109,101,61,84,105,109,101,32,80,105, + 99,107,101,114,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84, + 68,87,84,105,109,101,95,80,105,99,107,101,114,13,10,80,97,108,101,116, + 116,101,61,70,111,114,109,115,13,10,74,115,70,105,108,101,78,97,109,101, + 61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115, + 84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67,108,97,115,115, + 61,109,98,45,51,13,10,72,105,110,116,61,84,105,109,101,32,80,105,99, + 107,101,114,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115, + 47,116,105,109,101,95,112,105,99,107,101,114,46,98,109,112,13,10,104,116, + 109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114, + 61,51,53,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10, + 91,67,111,109,112,111,110,101,110,116,46,100,97,116,101,116,105,109,101,95, + 112,105,99,107,101,114,93,13,10,78,97,109,101,61,68,97,116,101,84,105, + 109,101,32,80,105,99,107,101,114,13,10,78,97,109,101,67,108,97,115,115, + 61,82,69,83,84,68,87,68,97,116,101,84,105,109,101,95,80,105,99,107, + 101,114,13,10,80,97,108,101,116,116,101,61,70,111,114,109,115,13,10,74, + 115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46, + 106,115,13,10,67,108,97,115,115,84,121,112,101,61,100,105,118,13,10,76, + 97,98,101,108,67,108,97,115,115,61,109,98,45,51,13,10,72,105,110,116, + 61,68,97,116,101,84,105,109,101,32,80,105,99,107,101,114,13,10,67,108, + 97,115,115,73,99,111,110,61,105,99,111,110,115,47,100,97,116,101,116,105, + 109,101,95,112,105,99,107,101,114,46,98,109,112,13,10,104,116,109,108,95, + 101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,51,54, + 13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111, + 109,112,111,110,101,110,116,46,109,111,110,116,104,95,112,105,99,107,101,114, + 93,13,10,78,97,109,101,61,77,111,110,116,104,32,80,105,99,107,101,114, + 13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,77,111, + 110,116,104,95,80,105,99,107,101,114,13,10,80,97,108,101,116,116,101,61, + 70,111,114,109,115,13,10,74,115,70,105,108,101,78,97,109,101,61,98,111, + 111,116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121,112, + 101,61,100,105,118,13,10,76,97,98,101,108,67,108,97,115,115,61,109,98, + 45,51,13,10,72,105,110,116,61,77,111,110,116,104,32,80,105,99,107,101, + 114,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,109, + 111,110,116,104,95,112,105,99,107,101,114,46,98,109,112,13,10,104,116,109, + 108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61, + 51,55,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91, + 67,111,109,112,111,110,101,110,116,46,119,101,101,107,95,112,105,99,107,101, + 114,93,13,10,78,97,109,101,61,87,101,101,107,32,80,105,99,107,101,114, + 13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,87,101, + 101,107,95,80,105,99,107,101,114,13,10,80,97,108,101,116,116,101,61,70, + 111,114,109,115,13,10,74,115,70,105,108,101,78,97,109,101,61,98,111,111, + 116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121,112,101, + 61,100,105,118,13,10,76,97,98,101,108,67,108,97,115,115,61,109,98,45, + 51,13,10,72,105,110,116,61,87,101,101,107,32,80,105,99,107,101,114,13, + 10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,119,101,101, + 107,95,112,105,99,107,101,114,46,98,109,112,13,10,104,116,109,108,95,101, + 120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,51,56,13, + 10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109, + 112,111,110,101,110,116,46,99,111,108,111,114,95,112,105,99,107,101,114,93, + 13,10,78,97,109,101,61,67,111,108,111,114,32,80,105,99,107,101,114,13, + 10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,67,111,108, + 111,114,95,80,105,99,107,101,114,13,10,80,97,108,101,116,116,101,61,70, + 111,114,109,115,13,10,74,115,70,105,108,101,78,97,109,101,61,98,111,111, + 116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121,112,101, + 61,100,105,118,13,10,76,97,98,101,108,67,108,97,115,115,61,109,98,45, + 51,13,10,72,105,110,116,61,67,111,108,111,114,32,80,105,99,107,101,114, + 13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,99,111, + 108,111,114,95,112,105,99,107,101,114,46,98,109,112,13,10,104,116,109,108, + 95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,51, + 57,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67, + 111,109,112,111,110,101,110,116,46,116,101,120,116,97,114,101,97,93,13,10, + 78,97,109,101,61,84,101,120,116,65,114,101,97,13,10,78,97,109,101,67, + 108,97,115,115,61,82,69,83,84,68,87,84,101,120,116,65,114,101,97,13, + 10,80,97,108,101,116,116,101,61,70,111,114,109,115,13,10,74,115,70,105, + 108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13, + 10,67,108,97,115,115,84,121,112,101,61,100,105,118,13,10,76,97,98,101, + 108,67,108,97,115,115,61,109,98,45,51,13,10,72,105,110,116,61,84,101, + 120,116,65,114,101,97,13,10,67,108,97,115,115,73,99,111,110,61,105,99, + 111,110,115,47,116,101,120,116,97,114,101,97,46,98,109,112,13,10,104,116, + 109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114, + 61,52,48,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10, + 91,67,111,109,112,111,110,101,110,116,46,115,101,108,101,99,116,93,13,10, + 78,97,109,101,61,83,101,108,101,99,116,13,10,78,97,109,101,67,108,97, + 115,115,61,82,69,83,84,68,87,83,101,108,101,99,116,13,10,80,97,108, + 101,116,116,101,61,70,111,114,109,115,13,10,74,115,70,105,108,101,78,97, + 109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108,97, + 115,115,84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67,108,97, + 115,115,61,109,98,45,51,13,10,72,105,110,116,61,83,101,108,101,99,116, + 13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,115,101, + 108,101,99,116,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110, + 115,105,111,110,61,13,10,79,114,100,101,114,61,52,49,13,10,73,110,115, + 116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101, + 110,116,46,109,117,108,116,105,95,115,101,108,101,99,116,93,13,10,78,97, + 109,101,61,77,117,108,116,105,32,83,101,108,101,99,116,13,10,78,97,109, + 101,67,108,97,115,115,61,82,69,83,84,68,87,77,117,108,116,105,95,83, + 101,108,101,99,116,13,10,80,97,108,101,116,116,101,61,70,111,114,109,115, + 13,10,74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114, + 97,112,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,100,105,118, + 13,10,76,97,98,101,108,67,108,97,115,115,61,109,98,45,51,13,10,72, + 105,110,116,61,77,117,108,116,105,32,83,101,108,101,99,116,13,10,67,108, + 97,115,115,73,99,111,110,61,105,99,111,110,115,47,109,117,108,116,105,95, + 115,101,108,101,99,116,46,98,109,112,13,10,104,116,109,108,95,101,120,116, + 101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,52,50,13,10,73, + 110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111, + 110,101,110,116,46,99,104,101,99,107,98,111,120,93,13,10,78,97,109,101, + 61,67,104,101,99,107,98,111,120,13,10,78,97,109,101,67,108,97,115,115, + 61,82,69,83,84,68,87,67,104,101,99,107,98,111,120,13,10,80,97,108, + 101,116,116,101,61,70,111,114,109,115,13,10,74,115,70,105,108,101,78,97, + 109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108,97, + 115,115,84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67,108,97, + 115,115,61,102,111,114,109,45,99,104,101,99,107,13,10,72,105,110,116,61, + 67,104,101,99,107,98,111,120,13,10,67,108,97,115,115,73,99,111,110,61, + 105,99,111,110,115,47,99,104,101,99,107,98,111,120,46,98,109,112,13,10, + 104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100, + 101,114,61,52,51,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10, + 13,10,91,67,111,109,112,111,110,101,110,116,46,115,119,105,116,99,104,93, + 13,10,78,97,109,101,61,83,119,105,116,99,104,13,10,78,97,109,101,67, + 108,97,115,115,61,82,69,83,84,68,87,83,119,105,116,99,104,13,10,80, + 97,108,101,116,116,101,61,70,111,114,109,115,13,10,74,115,70,105,108,101, + 78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67, + 108,97,115,115,84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67, + 108,97,115,115,61,102,111,114,109,45,99,104,101,99,107,13,10,72,105,110, + 116,61,83,119,105,116,99,104,13,10,67,108,97,115,115,73,99,111,110,61, + 105,99,111,110,115,47,115,119,105,116,99,104,46,98,109,112,13,10,104,116, + 109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114, + 61,52,52,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10, + 91,67,111,109,112,111,110,101,110,116,46,114,97,100,105,111,95,103,114,111, + 117,112,93,13,10,78,97,109,101,61,82,97,100,105,111,32,71,114,111,117, + 112,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,82, + 97,100,105,111,95,71,114,111,117,112,13,10,80,97,108,101,116,116,101,61, + 70,111,114,109,115,13,10,74,115,70,105,108,101,78,97,109,101,61,98,111, + 111,116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121,112, + 101,61,100,105,118,13,10,76,97,98,101,108,67,108,97,115,115,61,102,111, + 114,109,45,99,104,101,99,107,13,10,72,105,110,116,61,82,97,100,105,111, + 32,71,114,111,117,112,13,10,67,108,97,115,115,73,99,111,110,61,105,99, + 111,110,115,47,114,97,100,105,111,95,103,114,111,117,112,46,98,109,112,13, + 10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114, + 100,101,114,61,52,53,13,10,73,110,115,116,97,108,108,101,100,61,49,13, + 10,13,10,91,67,111,109,112,111,110,101,110,116,46,114,97,110,103,101,93, + 13,10,78,97,109,101,61,82,97,110,103,101,13,10,78,97,109,101,67,108, + 97,115,115,61,82,69,83,84,68,87,82,97,110,103,101,13,10,80,97,108, + 101,116,116,101,61,70,111,114,109,115,13,10,74,115,70,105,108,101,78,97, + 109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108,97, + 115,115,84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67,108,97, + 115,115,61,109,98,45,51,13,10,72,105,110,116,61,82,97,110,103,101,13, + 10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,114,97,110, + 103,101,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105, + 111,110,61,13,10,79,114,100,101,114,61,52,54,13,10,73,110,115,116,97, + 108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116, + 46,102,105,108,101,95,117,112,108,111,97,100,93,13,10,78,97,109,101,61, + 70,105,108,101,32,85,112,108,111,97,100,13,10,78,97,109,101,67,108,97, + 115,115,61,82,69,83,84,68,87,70,105,108,101,95,85,112,108,111,97,100, + 13,10,80,97,108,101,116,116,101,61,70,111,114,109,115,13,10,74,115,70, + 105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115, + 13,10,67,108,97,115,115,84,121,112,101,61,100,105,118,13,10,76,97,98, + 101,108,67,108,97,115,115,61,109,98,45,51,13,10,72,105,110,116,61,70, + 105,108,101,32,85,112,108,111,97,100,13,10,67,108,97,115,115,73,99,111, + 110,61,105,99,111,110,115,47,102,105,108,101,95,117,112,108,111,97,100,46, + 98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61, + 13,10,79,114,100,101,114,61,52,55,13,10,73,110,115,116,97,108,108,101, + 100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,105,110, + 112,117,116,95,103,114,111,117,112,93,13,10,78,97,109,101,61,73,110,112, + 117,116,32,71,114,111,117,112,13,10,78,97,109,101,67,108,97,115,115,61, + 82,69,83,84,68,87,73,110,112,117,116,95,71,114,111,117,112,13,10,80, + 97,108,101,116,116,101,61,70,111,114,109,115,13,10,74,115,70,105,108,101, + 78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67, + 108,97,115,115,84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67, + 108,97,115,115,61,105,110,112,117,116,45,103,114,111,117,112,13,10,72,105, + 110,116,61,73,110,112,117,116,32,71,114,111,117,112,13,10,67,108,97,115, + 115,73,99,111,110,61,105,99,111,110,115,47,105,110,112,117,116,95,103,114, + 111,117,112,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115, + 105,111,110,61,13,10,79,114,100,101,114,61,52,56,13,10,73,110,115,116, + 97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110, + 116,46,114,101,97,100,111,110,108,121,95,101,100,105,116,93,13,10,78,97, + 109,101,61,82,101,97,100,111,110,108,121,32,69,100,105,116,13,10,78,97, + 109,101,67,108,97,115,115,61,82,69,83,84,68,87,82,101,97,100,111,110, + 108,121,95,69,100,105,116,13,10,80,97,108,101,116,116,101,61,70,111,114, + 109,115,13,10,74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115, + 116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,100, + 105,118,13,10,76,97,98,101,108,67,108,97,115,115,61,109,98,45,51,13, + 10,72,105,110,116,61,82,101,97,100,111,110,108,121,32,69,100,105,116,13, + 10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,114,101,97, + 100,111,110,108,121,95,101,100,105,116,46,98,109,112,13,10,104,116,109,108, + 95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,52, + 57,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67, + 111,109,112,111,110,101,110,116,46,100,105,115,97,98,108,101,100,95,101,100, + 105,116,93,13,10,78,97,109,101,61,68,105,115,97,98,108,101,100,32,69, + 100,105,116,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68, + 87,68,105,115,97,98,108,101,100,95,69,100,105,116,13,10,80,97,108,101, + 116,116,101,61,70,111,114,109,115,13,10,74,115,70,105,108,101,78,97,109, + 101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108,97,115, + 115,84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67,108,97,115, + 115,61,109,98,45,51,13,10,72,105,110,116,61,68,105,115,97,98,108,101, + 100,32,69,100,105,116,13,10,67,108,97,115,115,73,99,111,110,61,105,99, + 111,110,115,47,100,105,115,97,98,108,101,100,95,101,100,105,116,46,98,109, + 112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10, + 79,114,100,101,114,61,53,48,13,10,73,110,115,116,97,108,108,101,100,61, + 49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,112,114,105,109, + 97,114,121,93,13,10,78,97,109,101,61,80,114,105,109,97,114,121,13,10, + 78,97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,80,114,105,109, + 97,114,121,13,10,80,97,108,101,116,116,101,61,66,117,116,116,111,110,115, + 13,10,74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114, + 97,112,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,98,117,116, + 116,111,110,13,10,76,97,98,101,108,67,108,97,115,115,61,98,116,110,32, + 98,116,110,45,112,114,105,109,97,114,121,13,10,72,105,110,116,61,80,114, + 105,109,97,114,121,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111, + 110,115,47,112,114,105,109,97,114,121,46,98,109,112,13,10,104,116,109,108, + 95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,53, + 49,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67, + 111,109,112,111,110,101,110,116,46,115,101,99,111,110,100,97,114,121,93,13, + 10,78,97,109,101,61,83,101,99,111,110,100,97,114,121,13,10,78,97,109, + 101,67,108,97,115,115,61,82,69,83,84,68,87,83,101,99,111,110,100,97, + 114,121,13,10,80,97,108,101,116,116,101,61,66,117,116,116,111,110,115,13, + 10,74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97, + 112,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,98,117,116,116, + 111,110,13,10,76,97,98,101,108,67,108,97,115,115,61,98,116,110,32,98, + 116,110,45,115,101,99,111,110,100,97,114,121,13,10,72,105,110,116,61,83, + 101,99,111,110,100,97,114,121,13,10,67,108,97,115,115,73,99,111,110,61, + 105,99,111,110,115,47,115,101,99,111,110,100,97,114,121,46,98,109,112,13, + 10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114, + 100,101,114,61,53,50,13,10,73,110,115,116,97,108,108,101,100,61,49,13, + 10,13,10,91,67,111,109,112,111,110,101,110,116,46,115,117,99,99,101,115, + 115,93,13,10,78,97,109,101,61,83,117,99,99,101,115,115,13,10,78,97, + 109,101,67,108,97,115,115,61,82,69,83,84,68,87,83,117,99,99,101,115, + 115,13,10,80,97,108,101,116,116,101,61,66,117,116,116,111,110,115,13,10, + 74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112, + 46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,98,117,116,116,111, + 110,13,10,76,97,98,101,108,67,108,97,115,115,61,98,116,110,32,98,116, + 110,45,115,117,99,99,101,115,115,13,10,72,105,110,116,61,83,117,99,99, + 101,115,115,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115, + 47,115,117,99,99,101,115,115,46,98,109,112,13,10,104,116,109,108,95,101, + 120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,53,51,13, + 10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109, + 112,111,110,101,110,116,46,100,97,110,103,101,114,93,13,10,78,97,109,101, + 61,68,97,110,103,101,114,13,10,78,97,109,101,67,108,97,115,115,61,82, + 69,83,84,68,87,68,97,110,103,101,114,13,10,80,97,108,101,116,116,101, + 61,66,117,116,116,111,110,115,13,10,74,115,70,105,108,101,78,97,109,101, + 61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115, + 84,121,112,101,61,98,117,116,116,111,110,13,10,76,97,98,101,108,67,108, + 97,115,115,61,98,116,110,32,98,116,110,45,100,97,110,103,101,114,13,10, + 72,105,110,116,61,68,97,110,103,101,114,13,10,67,108,97,115,115,73,99, + 111,110,61,105,99,111,110,115,47,100,97,110,103,101,114,46,98,109,112,13, + 10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114, + 100,101,114,61,53,52,13,10,73,110,115,116,97,108,108,101,100,61,49,13, + 10,13,10,91,67,111,109,112,111,110,101,110,116,46,119,97,114,110,105,110, + 103,93,13,10,78,97,109,101,61,87,97,114,110,105,110,103,13,10,78,97, + 109,101,67,108,97,115,115,61,82,69,83,84,68,87,87,97,114,110,105,110, + 103,13,10,80,97,108,101,116,116,101,61,66,117,116,116,111,110,115,13,10, + 74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112, + 46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,98,117,116,116,111, + 110,13,10,76,97,98,101,108,67,108,97,115,115,61,98,116,110,32,98,116, + 110,45,119,97,114,110,105,110,103,13,10,72,105,110,116,61,87,97,114,110, + 105,110,103,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115, + 47,119,97,114,110,105,110,103,46,98,109,112,13,10,104,116,109,108,95,101, + 120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,53,53,13, + 10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109, + 112,111,110,101,110,116,46,105,110,102,111,93,13,10,78,97,109,101,61,73, + 110,102,111,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68, + 87,73,110,102,111,13,10,80,97,108,101,116,116,101,61,66,117,116,116,111, + 110,115,13,10,74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115, + 116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,98, + 117,116,116,111,110,13,10,76,97,98,101,108,67,108,97,115,115,61,98,116, + 110,32,98,116,110,45,105,110,102,111,13,10,72,105,110,116,61,73,110,102, + 111,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,105, + 110,102,111,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115, + 105,111,110,61,13,10,79,114,100,101,114,61,53,54,13,10,73,110,115,116, + 97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110, + 116,46,108,105,103,104,116,93,13,10,78,97,109,101,61,76,105,103,104,116, + 13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,76,105, + 103,104,116,13,10,80,97,108,101,116,116,101,61,66,117,116,116,111,110,115, + 13,10,74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114, + 97,112,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,98,117,116, + 116,111,110,13,10,76,97,98,101,108,67,108,97,115,115,61,98,116,110,32, + 98,116,110,45,108,105,103,104,116,13,10,72,105,110,116,61,76,105,103,104, + 116,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,108, + 105,103,104,116,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110, + 115,105,111,110,61,13,10,79,114,100,101,114,61,53,55,13,10,73,110,115, + 116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101, + 110,116,46,100,97,114,107,93,13,10,78,97,109,101,61,68,97,114,107,13, + 10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,68,97,114, + 107,13,10,80,97,108,101,116,116,101,61,66,117,116,116,111,110,115,13,10, + 74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112, + 46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,98,117,116,116,111, + 110,13,10,76,97,98,101,108,67,108,97,115,115,61,98,116,110,32,98,116, + 110,45,100,97,114,107,13,10,72,105,110,116,61,68,97,114,107,13,10,67, + 108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,100,97,114,107,46, + 98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61, + 13,10,79,114,100,101,114,61,53,56,13,10,73,110,115,116,97,108,108,101, + 100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,108,105, + 110,107,93,13,10,78,97,109,101,61,76,105,110,107,13,10,78,97,109,101, + 67,108,97,115,115,61,82,69,83,84,68,87,76,105,110,107,13,10,80,97, + 108,101,116,116,101,61,66,117,116,116,111,110,115,13,10,74,115,70,105,108, + 101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10, + 67,108,97,115,115,84,121,112,101,61,98,117,116,116,111,110,13,10,76,97, + 98,101,108,67,108,97,115,115,61,98,116,110,32,98,116,110,45,108,105,110, + 107,13,10,72,105,110,116,61,76,105,110,107,13,10,67,108,97,115,115,73, + 99,111,110,61,105,99,111,110,115,47,108,105,110,107,46,98,109,112,13,10, + 104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100, + 101,114,61,53,57,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10, + 13,10,91,67,111,109,112,111,110,101,110,116,46,111,117,116,108,105,110,101, + 95,112,114,105,109,97,114,121,93,13,10,78,97,109,101,61,79,117,116,108, + 105,110,101,32,80,114,105,109,97,114,121,13,10,78,97,109,101,67,108,97, + 115,115,61,82,69,83,84,68,87,79,117,116,108,105,110,101,95,80,114,105, + 109,97,114,121,13,10,80,97,108,101,116,116,101,61,66,117,116,116,111,110, + 115,13,10,74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116, + 114,97,112,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,98,117, + 116,116,111,110,13,10,76,97,98,101,108,67,108,97,115,115,61,98,116,110, + 32,98,116,110,45,111,117,116,108,105,110,101,45,112,114,105,109,97,114,121, + 13,10,72,105,110,116,61,79,117,116,108,105,110,101,32,80,114,105,109,97, + 114,121,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47, + 111,117,116,108,105,110,101,95,112,114,105,109,97,114,121,46,98,109,112,13, + 10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114, + 100,101,114,61,54,48,13,10,73,110,115,116,97,108,108,101,100,61,49,13, + 10,13,10,91,67,111,109,112,111,110,101,110,116,46,115,109,97,108,108,95, + 98,117,116,116,111,110,93,13,10,78,97,109,101,61,83,109,97,108,108,32, + 66,117,116,116,111,110,13,10,78,97,109,101,67,108,97,115,115,61,82,69, + 83,84,68,87,83,109,97,108,108,95,66,117,116,116,111,110,13,10,80,97, + 108,101,116,116,101,61,66,117,116,116,111,110,115,13,10,74,115,70,105,108, + 101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10, + 67,108,97,115,115,84,121,112,101,61,98,117,116,116,111,110,13,10,76,97, + 98,101,108,67,108,97,115,115,61,98,116,110,32,98,116,110,45,112,114,105, + 109,97,114,121,32,98,116,110,45,115,109,13,10,72,105,110,116,61,83,109, + 97,108,108,32,66,117,116,116,111,110,13,10,67,108,97,115,115,73,99,111, + 110,61,105,99,111,110,115,47,115,109,97,108,108,95,98,117,116,116,111,110, + 46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110, + 61,13,10,79,114,100,101,114,61,54,49,13,10,73,110,115,116,97,108,108, + 101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,108, + 97,114,103,101,95,98,117,116,116,111,110,93,13,10,78,97,109,101,61,76, + 97,114,103,101,32,66,117,116,116,111,110,13,10,78,97,109,101,67,108,97, + 115,115,61,82,69,83,84,68,87,76,97,114,103,101,95,66,117,116,116,111, + 110,13,10,80,97,108,101,116,116,101,61,66,117,116,116,111,110,115,13,10, + 74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112, + 46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,98,117,116,116,111, + 110,13,10,76,97,98,101,108,67,108,97,115,115,61,98,116,110,32,98,116, + 110,45,112,114,105,109,97,114,121,32,98,116,110,45,108,103,13,10,72,105, + 110,116,61,76,97,114,103,101,32,66,117,116,116,111,110,13,10,67,108,97, + 115,115,73,99,111,110,61,105,99,111,110,115,47,108,97,114,103,101,95,98, + 117,116,116,111,110,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101, + 110,115,105,111,110,61,13,10,79,114,100,101,114,61,54,50,13,10,73,110, + 115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110, + 101,110,116,46,98,117,116,116,111,110,95,103,114,111,117,112,93,13,10,78, + 97,109,101,61,66,117,116,116,111,110,32,71,114,111,117,112,13,10,78,97, + 109,101,67,108,97,115,115,61,82,69,83,84,68,87,66,117,116,116,111,110, + 95,71,114,111,117,112,13,10,80,97,108,101,116,116,101,61,66,117,116,116, + 111,110,115,13,10,74,115,70,105,108,101,78,97,109,101,61,98,111,111,116, + 115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61, + 100,105,118,13,10,76,97,98,101,108,67,108,97,115,115,61,100,45,102,108, + 101,120,32,103,97,112,45,50,13,10,72,105,110,116,61,66,117,116,116,111, + 110,32,71,114,111,117,112,13,10,67,108,97,115,115,73,99,111,110,61,105, + 99,111,110,115,47,98,117,116,116,111,110,95,103,114,111,117,112,46,98,109, + 112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10, + 79,114,100,101,114,61,54,51,13,10,73,110,115,116,97,108,108,101,100,61, + 49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,99,114,117,100, + 95,116,111,111,108,98,97,114,93,13,10,78,97,109,101,61,67,82,85,68, + 32,84,111,111,108,98,97,114,13,10,78,97,109,101,67,108,97,115,115,61, + 82,69,83,84,68,87,67,82,85,68,95,84,111,111,108,98,97,114,13,10, + 80,97,108,101,116,116,101,61,66,117,116,116,111,110,115,13,10,74,115,70, + 105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115, + 13,10,67,108,97,115,115,84,121,112,101,61,100,105,118,13,10,76,97,98, + 101,108,67,108,97,115,115,61,100,45,102,108,101,120,32,103,97,112,45,50, + 13,10,72,105,110,116,61,67,82,85,68,32,84,111,111,108,98,97,114,13, + 10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,99,114,117, + 100,95,116,111,111,108,98,97,114,46,98,109,112,13,10,104,116,109,108,95, + 101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,54,52, + 13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111, + 109,112,111,110,101,110,116,46,97,108,101,114,116,95,112,114,105,109,97,114, + 121,93,13,10,78,97,109,101,61,65,108,101,114,116,32,80,114,105,109,97, + 114,121,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68,87, + 65,108,101,114,116,95,80,114,105,109,97,114,121,13,10,80,97,108,101,116, + 116,101,61,70,101,101,100,98,97,99,107,13,10,74,115,70,105,108,101,78, + 97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108, + 97,115,115,84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67,108, + 97,115,115,61,97,108,101,114,116,32,97,108,101,114,116,45,112,114,105,109, + 97,114,121,13,10,72,105,110,116,61,65,108,101,114,116,32,80,114,105,109, + 97,114,121,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115, + 47,97,108,101,114,116,95,112,114,105,109,97,114,121,46,98,109,112,13,10, + 104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100, + 101,114,61,54,53,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10, + 13,10,91,67,111,109,112,111,110,101,110,116,46,97,108,101,114,116,95,115, + 117,99,99,101,115,115,93,13,10,78,97,109,101,61,65,108,101,114,116,32, + 83,117,99,99,101,115,115,13,10,78,97,109,101,67,108,97,115,115,61,82, + 69,83,84,68,87,65,108,101,114,116,95,83,117,99,99,101,115,115,13,10, + 80,97,108,101,116,116,101,61,70,101,101,100,98,97,99,107,13,10,74,115, + 70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106, + 115,13,10,67,108,97,115,115,84,121,112,101,61,100,105,118,13,10,76,97, + 98,101,108,67,108,97,115,115,61,97,108,101,114,116,32,97,108,101,114,116, + 45,115,117,99,99,101,115,115,13,10,72,105,110,116,61,65,108,101,114,116, + 32,83,117,99,99,101,115,115,13,10,67,108,97,115,115,73,99,111,110,61, + 105,99,111,110,115,47,97,108,101,114,116,95,115,117,99,99,101,115,115,46, + 98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61, + 13,10,79,114,100,101,114,61,54,54,13,10,73,110,115,116,97,108,108,101, + 100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,97,108, + 101,114,116,95,100,97,110,103,101,114,93,13,10,78,97,109,101,61,65,108, + 101,114,116,32,68,97,110,103,101,114,13,10,78,97,109,101,67,108,97,115, + 115,61,82,69,83,84,68,87,65,108,101,114,116,95,68,97,110,103,101,114, + 13,10,80,97,108,101,116,116,101,61,70,101,101,100,98,97,99,107,13,10, + 74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112, + 46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,100,105,118,13,10, + 76,97,98,101,108,67,108,97,115,115,61,97,108,101,114,116,32,97,108,101, + 114,116,45,100,97,110,103,101,114,13,10,72,105,110,116,61,65,108,101,114, + 116,32,68,97,110,103,101,114,13,10,67,108,97,115,115,73,99,111,110,61, + 105,99,111,110,115,47,97,108,101,114,116,95,100,97,110,103,101,114,46,98, + 109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13, + 10,79,114,100,101,114,61,54,55,13,10,73,110,115,116,97,108,108,101,100, + 61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,112,114,111, + 103,114,101,115,115,93,13,10,78,97,109,101,61,80,114,111,103,114,101,115, + 115,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,80, + 114,111,103,114,101,115,115,13,10,80,97,108,101,116,116,101,61,70,101,101, + 100,98,97,99,107,13,10,74,115,70,105,108,101,78,97,109,101,61,98,111, + 111,116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121,112, + 101,61,100,105,118,13,10,76,97,98,101,108,67,108,97,115,115,61,112,114, + 111,103,114,101,115,115,13,10,72,105,110,116,61,80,114,111,103,114,101,115, + 115,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,112, + 114,111,103,114,101,115,115,46,98,109,112,13,10,104,116,109,108,95,101,120, + 116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,54,56,13,10, + 73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112, + 111,110,101,110,116,46,115,112,105,110,110,101,114,93,13,10,78,97,109,101, + 61,83,112,105,110,110,101,114,13,10,78,97,109,101,67,108,97,115,115,61, + 82,69,83,84,68,87,83,112,105,110,110,101,114,13,10,80,97,108,101,116, + 116,101,61,70,101,101,100,98,97,99,107,13,10,74,115,70,105,108,101,78, + 97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108, + 97,115,115,84,121,112,101,61,115,112,97,110,13,10,76,97,98,101,108,67, + 108,97,115,115,61,115,112,105,110,110,101,114,45,98,111,114,100,101,114,13, + 10,72,105,110,116,61,83,112,105,110,110,101,114,13,10,67,108,97,115,115, + 73,99,111,110,61,105,99,111,110,115,47,115,112,105,110,110,101,114,46,98, + 109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13, + 10,79,114,100,101,114,61,54,57,13,10,73,110,115,116,97,108,108,101,100, + 61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,97,99,99, + 111,114,100,105,111,110,93,13,10,78,97,109,101,61,65,99,99,111,114,100, + 105,111,110,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68, + 87,65,99,99,111,114,100,105,111,110,13,10,80,97,108,101,116,116,101,61, + 73,110,116,101,114,97,99,116,105,118,101,13,10,74,115,70,105,108,101,78, + 97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108, + 97,115,115,84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67,108, + 97,115,115,61,97,99,99,111,114,100,105,111,110,45,105,116,101,109,13,10, + 72,105,110,116,61,65,99,99,111,114,100,105,111,110,13,10,67,108,97,115, + 115,73,99,111,110,61,105,99,111,110,115,47,97,99,99,111,114,100,105,111, + 110,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111, + 110,61,13,10,79,114,100,101,114,61,55,48,13,10,73,110,115,116,97,108, + 108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46, + 99,111,108,108,97,112,115,101,93,13,10,78,97,109,101,61,67,111,108,108, + 97,112,115,101,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84, + 68,87,67,111,108,108,97,112,115,101,13,10,80,97,108,101,116,116,101,61, + 73,110,116,101,114,97,99,116,105,118,101,13,10,74,115,70,105,108,101,78, + 97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108, + 97,115,115,84,121,112,101,61,98,117,116,116,111,110,13,10,76,97,98,101, + 108,67,108,97,115,115,61,98,116,110,32,98,116,110,45,112,114,105,109,97, + 114,121,13,10,72,105,110,116,61,67,111,108,108,97,112,115,101,13,10,67, + 108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,99,111,108,108,97, + 112,115,101,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115, + 105,111,110,61,13,10,79,114,100,101,114,61,55,49,13,10,73,110,115,116, + 97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110, + 116,46,100,114,111,112,100,111,119,110,93,13,10,78,97,109,101,61,68,114, + 111,112,100,111,119,110,13,10,78,97,109,101,67,108,97,115,115,61,82,69, + 83,84,68,87,68,114,111,112,100,111,119,110,13,10,80,97,108,101,116,116, + 101,61,73,110,116,101,114,97,99,116,105,118,101,13,10,74,115,70,105,108, + 101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10, + 67,108,97,115,115,84,121,112,101,61,100,105,118,13,10,76,97,98,101,108, + 67,108,97,115,115,61,100,114,111,112,100,111,119,110,13,10,72,105,110,116, + 61,68,114,111,112,100,111,119,110,13,10,67,108,97,115,115,73,99,111,110, + 61,105,99,111,110,115,47,100,114,111,112,100,111,119,110,46,98,109,112,13, + 10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114, + 100,101,114,61,55,50,13,10,73,110,115,116,97,108,108,101,100,61,49,13, + 10,13,10,91,67,111,109,112,111,110,101,110,116,46,109,111,100,97,108,93, + 13,10,78,97,109,101,61,77,111,100,97,108,13,10,78,97,109,101,67,108, + 97,115,115,61,82,69,83,84,68,87,77,111,100,97,108,13,10,80,97,108, + 101,116,116,101,61,73,110,116,101,114,97,99,116,105,118,101,13,10,74,115, + 70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106, + 115,13,10,67,108,97,115,115,84,121,112,101,61,98,117,116,116,111,110,13, + 10,76,97,98,101,108,67,108,97,115,115,61,98,116,110,32,98,116,110,45, + 112,114,105,109,97,114,121,13,10,72,105,110,116,61,77,111,100,97,108,13, + 10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,109,111,100, + 97,108,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105, + 111,110,61,13,10,79,114,100,101,114,61,55,51,13,10,73,110,115,116,97, + 108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116, + 46,111,102,102,99,97,110,118,97,115,93,13,10,78,97,109,101,61,79,102, + 102,99,97,110,118,97,115,13,10,78,97,109,101,67,108,97,115,115,61,82, + 69,83,84,68,87,79,102,102,99,97,110,118,97,115,13,10,80,97,108,101, + 116,116,101,61,73,110,116,101,114,97,99,116,105,118,101,13,10,74,115,70, + 105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46,106,115, + 13,10,67,108,97,115,115,84,121,112,101,61,98,117,116,116,111,110,13,10, + 76,97,98,101,108,67,108,97,115,115,61,98,116,110,32,98,116,110,45,112, + 114,105,109,97,114,121,13,10,72,105,110,116,61,79,102,102,99,97,110,118, + 97,115,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47, + 111,102,102,99,97,110,118,97,115,46,98,109,112,13,10,104,116,109,108,95, + 101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,55,52, + 13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111, + 109,112,111,110,101,110,116,46,116,111,97,115,116,93,13,10,78,97,109,101, + 61,84,111,97,115,116,13,10,78,97,109,101,67,108,97,115,115,61,82,69, + 83,84,68,87,84,111,97,115,116,13,10,80,97,108,101,116,116,101,61,73, + 110,116,101,114,97,99,116,105,118,101,13,10,74,115,70,105,108,101,78,97, + 109,101,61,98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108,97, + 115,115,84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67,108,97, + 115,115,61,116,111,97,115,116,13,10,72,105,110,116,61,84,111,97,115,116, + 13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,116,111, + 97,115,116,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115, + 105,111,110,61,13,10,79,114,100,101,114,61,55,53,13,10,73,110,115,116, + 97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110, + 116,46,116,97,98,108,101,93,13,10,78,97,109,101,61,84,97,98,108,101, + 13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,84,97, + 98,108,101,13,10,80,97,108,101,116,116,101,61,68,97,116,97,13,10,74, + 115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112,46, + 106,115,13,10,67,108,97,115,115,84,121,112,101,61,116,97,98,108,101,13, + 10,76,97,98,101,108,67,108,97,115,115,61,116,97,98,108,101,32,116,97, + 98,108,101,45,115,116,114,105,112,101,100,13,10,72,105,110,116,61,84,97, + 98,108,101,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115, + 47,116,97,98,108,101,46,98,109,112,13,10,104,116,109,108,95,101,120,116, + 101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,55,54,13,10,73, + 110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111, + 110,101,110,116,46,98,111,114,100,101,114,101,100,95,116,97,98,108,101,93, + 13,10,78,97,109,101,61,66,111,114,100,101,114,101,100,32,84,97,98,108, + 101,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,66, + 111,114,100,101,114,101,100,95,84,97,98,108,101,13,10,80,97,108,101,116, + 116,101,61,68,97,116,97,13,10,74,115,70,105,108,101,78,97,109,101,61, + 98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84, + 121,112,101,61,116,97,98,108,101,13,10,76,97,98,101,108,67,108,97,115, + 115,61,116,97,98,108,101,32,116,97,98,108,101,45,98,111,114,100,101,114, + 101,100,13,10,72,105,110,116,61,66,111,114,100,101,114,101,100,32,84,97, + 98,108,101,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115, + 47,98,111,114,100,101,114,101,100,95,116,97,98,108,101,46,98,109,112,13, + 10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114, + 100,101,114,61,55,55,13,10,73,110,115,116,97,108,108,101,100,61,49,13, + 10,13,10,91,67,111,109,112,111,110,101,110,116,46,107,112,105,95,99,97, + 114,100,93,13,10,78,97,109,101,61,75,80,73,32,67,97,114,100,13,10, + 78,97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,75,80,73,95, + 67,97,114,100,13,10,80,97,108,101,116,116,101,61,68,97,115,104,98,111, + 97,114,100,13,10,74,115,70,105,108,101,78,97,109,101,61,98,111,111,116, + 115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61, + 100,105,118,13,10,76,97,98,101,108,67,108,97,115,115,61,99,97,114,100, + 13,10,72,105,110,116,61,75,80,73,32,67,97,114,100,13,10,67,108,97, + 115,115,73,99,111,110,61,105,99,111,110,115,47,107,112,105,95,99,97,114, + 100,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111, + 110,61,13,10,79,114,100,101,114,61,56,48,13,10,73,110,115,116,97,108, + 108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46, + 107,112,105,95,99,97,114,100,115,95,52,93,13,10,78,97,109,101,61,75, + 80,73,32,67,97,114,100,115,32,52,13,10,78,97,109,101,67,108,97,115, + 115,61,82,69,83,84,68,87,75,80,73,95,67,97,114,100,115,95,52,13, + 10,80,97,108,101,116,116,101,61,68,97,115,104,98,111,97,114,100,13,10, + 74,115,70,105,108,101,78,97,109,101,61,98,111,111,116,115,116,114,97,112, + 46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,100,105,118,13,10, + 76,97,98,101,108,67,108,97,115,115,61,114,111,119,13,10,72,105,110,116, + 61,75,80,73,32,67,97,114,100,115,32,52,13,10,67,108,97,115,115,73, + 99,111,110,61,105,99,111,110,115,47,107,112,105,95,99,97,114,100,115,95, + 52,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111, + 110,61,13,10,79,114,100,101,114,61,56,49,13,10,73,110,115,116,97,108, + 108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46, + 100,97,115,104,98,111,97,114,100,95,103,114,105,100,93,13,10,78,97,109, + 101,61,68,97,115,104,98,111,97,114,100,32,71,114,105,100,13,10,78,97, + 109,101,67,108,97,115,115,61,82,69,83,84,68,87,68,97,115,104,98,111, + 97,114,100,95,71,114,105,100,13,10,80,97,108,101,116,116,101,61,68,97, + 115,104,98,111,97,114,100,13,10,74,115,70,105,108,101,78,97,109,101,61, + 98,111,111,116,115,116,114,97,112,46,106,115,13,10,67,108,97,115,115,84, + 121,112,101,61,100,105,118,13,10,76,97,98,101,108,67,108,97,115,115,61, + 114,111,119,13,10,72,105,110,116,61,68,97,115,104,98,111,97,114,100,32, + 71,114,105,100,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110, + 115,47,100,97,115,104,98,111,97,114,100,95,103,114,105,100,46,98,109,112, + 13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79, + 114,100,101,114,61,56,53,13,10,73,110,115,116,97,108,108,101,100,61,49, + 13,10 + ); + CEditorAsset1 : Array[0..774] Of Byte = ( + 91,80,97,99,107,97,103,101,93,13,10,78,97,109,101,61,67,104,97,114, + 116,74,83,13,10,69,110,97,98,108,101,100,61,49,13,10,74,115,70,105, + 108,101,78,97,109,101,61,99,104,97,114,116,106,115,46,106,115,13,10,70, + 111,114,109,97,116,86,101,114,115,105,111,110,61,49,13,10,79,114,100,101, + 114,61,51,48,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,99, + 104,97,114,116,95,98,97,114,93,13,10,78,97,109,101,61,67,104,97,114, + 116,32,66,97,114,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83, + 84,68,87,67,104,97,114,116,95,66,97,114,13,10,80,97,108,101,116,116, + 101,61,68,97,115,104,98,111,97,114,100,13,10,74,115,70,105,108,101,78, + 97,109,101,61,99,104,97,114,116,106,115,46,106,115,13,10,67,108,97,115, + 115,84,121,112,101,61,99,97,110,118,97,115,13,10,76,97,98,101,108,67, + 108,97,115,115,61,13,10,72,105,110,116,61,67,104,97,114,116,32,66,97, + 114,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,99, + 104,97,114,116,95,98,97,114,46,98,109,112,13,10,104,116,109,108,95,101, + 120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,56,50,13, + 10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109, + 112,111,110,101,110,116,46,99,104,97,114,116,95,108,105,110,101,93,13,10, + 78,97,109,101,61,67,104,97,114,116,32,76,105,110,101,13,10,78,97,109, + 101,67,108,97,115,115,61,82,69,83,84,68,87,67,104,97,114,116,95,76, + 105,110,101,13,10,80,97,108,101,116,116,101,61,68,97,115,104,98,111,97, + 114,100,13,10,74,115,70,105,108,101,78,97,109,101,61,99,104,97,114,116, + 106,115,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,99,97,110, + 118,97,115,13,10,76,97,98,101,108,67,108,97,115,115,61,13,10,72,105, + 110,116,61,67,104,97,114,116,32,76,105,110,101,13,10,67,108,97,115,115, + 73,99,111,110,61,105,99,111,110,115,47,99,104,97,114,116,95,108,105,110, + 101,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111, + 110,61,13,10,79,114,100,101,114,61,56,51,13,10,73,110,115,116,97,108, + 108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46, + 99,104,97,114,116,95,112,105,101,93,13,10,78,97,109,101,61,67,104,97, + 114,116,32,80,105,101,13,10,78,97,109,101,67,108,97,115,115,61,82,69, + 83,84,68,87,67,104,97,114,116,95,80,105,101,13,10,80,97,108,101,116, + 116,101,61,68,97,115,104,98,111,97,114,100,13,10,74,115,70,105,108,101, + 78,97,109,101,61,99,104,97,114,116,106,115,46,106,115,13,10,67,108,97, + 115,115,84,121,112,101,61,99,97,110,118,97,115,13,10,76,97,98,101,108, + 67,108,97,115,115,61,13,10,72,105,110,116,61,67,104,97,114,116,32,80, + 105,101,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47, + 99,104,97,114,116,95,112,105,101,46,98,109,112,13,10,104,116,109,108,95, + 101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,56,52, + 13,10,73,110,115,116,97,108,108,101,100,61,49,13,10 + ); + CEditorAsset2 : Array[0..600] Of Byte = ( + 91,80,97,99,107,97,103,101,93,13,10,78,97,109,101,61,68,97,116,97, + 84,97,98,108,101,115,13,10,69,110,97,98,108,101,100,61,49,13,10,74, + 115,70,105,108,101,78,97,109,101,61,100,97,116,97,116,97,98,108,101,115, + 46,106,115,13,10,70,111,114,109,97,116,86,101,114,115,105,111,110,61,49, + 13,10,79,114,100,101,114,61,50,48,13,10,13,10,91,67,111,109,112,111, + 110,101,110,116,46,100,97,116,97,116,97,98,108,101,93,13,10,78,97,109, + 101,61,68,97,116,97,84,97,98,108,101,13,10,78,97,109,101,67,108,97, + 115,115,61,82,69,83,84,68,87,68,97,116,97,84,97,98,108,101,13,10, + 80,97,108,101,116,116,101,61,68,97,116,97,13,10,74,115,70,105,108,101, + 78,97,109,101,61,100,97,116,97,116,97,98,108,101,115,46,106,115,13,10, + 67,108,97,115,115,84,121,112,101,61,116,97,98,108,101,13,10,76,97,98, + 101,108,67,108,97,115,115,61,116,97,98,108,101,32,116,97,98,108,101,45, + 115,116,114,105,112,101,100,13,10,72,105,110,116,61,68,97,116,97,84,97, + 98,108,101,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115, + 47,100,97,116,97,116,97,98,108,101,46,98,109,112,13,10,104,116,109,108, + 95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,55, + 56,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67, + 111,109,112,111,110,101,110,116,46,100,97,116,97,116,97,98,108,101,95,99, + 114,117,100,93,13,10,78,97,109,101,61,68,97,116,97,84,97,98,108,101, + 32,67,82,85,68,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83, + 84,68,87,68,97,116,97,84,97,98,108,101,95,67,82,85,68,13,10,80, + 97,108,101,116,116,101,61,68,97,116,97,13,10,74,115,70,105,108,101,78, + 97,109,101,61,100,97,116,97,116,97,98,108,101,115,46,106,115,13,10,67, + 108,97,115,115,84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67, + 108,97,115,115,61,100,45,102,108,101,120,32,103,97,112,45,50,32,109,98, + 45,51,13,10,72,105,110,116,61,68,97,116,97,84,97,98,108,101,32,67, + 82,85,68,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115, + 47,100,97,116,97,116,97,98,108,101,95,99,114,117,100,46,98,109,112,13, + 10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114, + 100,101,114,61,55,57,13,10,73,110,115,116,97,108,108,101,100,61,49,13, + 10 + ); + CEditorAsset3 : Array[0..3712] Of Byte = ( + 91,80,97,99,107,97,103,101,93,13,10,78,97,109,101,61,83,116,97,110, + 100,97,114,100,13,10,69,110,97,98,108,101,100,61,49,13,10,74,115,70, + 105,108,101,78,97,109,101,61,115,116,97,110,100,97,114,100,46,106,115,13, + 10,70,111,114,109,97,116,86,101,114,115,105,111,110,61,49,13,10,79,114, + 100,101,114,61,48,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46, + 115,116,97,110,100,97,114,100,95,108,97,98,101,108,93,13,10,78,97,109, + 101,61,76,97,98,101,108,13,10,78,97,109,101,67,108,97,115,115,61,82, + 69,83,84,68,87,76,97,98,101,108,13,10,80,97,108,101,116,116,101,61, + 83,116,97,110,100,97,114,100,13,10,74,115,70,105,108,101,78,97,109,101, + 61,115,116,97,110,100,97,114,100,46,106,115,13,10,67,108,97,115,115,84, + 121,112,101,61,108,97,98,101,108,13,10,76,97,98,101,108,67,108,97,115, + 115,61,102,111,114,109,45,108,97,98,101,108,13,10,72,105,110,116,61,76, + 97,98,101,108,13,10,67,108,97,115,115,73,99,111,110,61,105,99,111,110, + 115,47,115,116,97,110,100,97,114,100,95,108,97,98,101,108,46,98,109,112, + 13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79, + 114,100,101,114,61,49,13,10,73,110,115,116,97,108,108,101,100,61,49,13, + 10,13,10,91,67,111,109,112,111,110,101,110,116,46,115,116,97,110,100,97, + 114,100,95,101,100,105,116,93,13,10,78,97,109,101,61,69,100,105,116,13, + 10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,69,100,105, + 116,13,10,80,97,108,101,116,116,101,61,83,116,97,110,100,97,114,100,13, + 10,74,115,70,105,108,101,78,97,109,101,61,115,116,97,110,100,97,114,100, + 46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,105,110,112,117,116, + 13,10,76,97,98,101,108,67,108,97,115,115,61,102,111,114,109,45,99,111, + 110,116,114,111,108,13,10,72,105,110,116,61,69,100,105,116,13,10,67,108, + 97,115,115,73,99,111,110,61,105,99,111,110,115,47,115,116,97,110,100,97, + 114,100,95,101,100,105,116,46,98,109,112,13,10,104,116,109,108,95,101,120, + 116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,50,13,10,73, + 110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111, + 110,101,110,116,46,115,116,97,110,100,97,114,100,95,109,101,109,111,93,13, + 10,78,97,109,101,61,77,101,109,111,13,10,78,97,109,101,67,108,97,115, + 115,61,82,69,83,84,68,87,77,101,109,111,13,10,80,97,108,101,116,116, + 101,61,83,116,97,110,100,97,114,100,13,10,74,115,70,105,108,101,78,97, + 109,101,61,115,116,97,110,100,97,114,100,46,106,115,13,10,67,108,97,115, + 115,84,121,112,101,61,116,101,120,116,97,114,101,97,13,10,76,97,98,101, + 108,67,108,97,115,115,61,102,111,114,109,45,99,111,110,116,114,111,108,13, + 10,72,105,110,116,61,77,101,109,111,13,10,67,108,97,115,115,73,99,111, + 110,61,105,99,111,110,115,47,115,116,97,110,100,97,114,100,95,109,101,109, + 111,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111, + 110,61,13,10,79,114,100,101,114,61,51,13,10,73,110,115,116,97,108,108, + 101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,115, + 116,97,110,100,97,114,100,95,98,117,116,116,111,110,93,13,10,78,97,109, + 101,61,66,117,116,116,111,110,13,10,78,97,109,101,67,108,97,115,115,61, + 82,69,83,84,68,87,66,117,116,116,111,110,13,10,80,97,108,101,116,116, + 101,61,83,116,97,110,100,97,114,100,13,10,74,115,70,105,108,101,78,97, + 109,101,61,115,116,97,110,100,97,114,100,46,106,115,13,10,67,108,97,115, + 115,84,121,112,101,61,98,117,116,116,111,110,13,10,76,97,98,101,108,67, + 108,97,115,115,61,98,116,110,32,98,116,110,45,112,114,105,109,97,114,121, + 13,10,72,105,110,116,61,66,117,116,116,111,110,13,10,67,108,97,115,115, + 73,99,111,110,61,105,99,111,110,115,47,115,116,97,110,100,97,114,100,95, + 98,117,116,116,111,110,46,98,109,112,13,10,104,116,109,108,95,101,120,116, + 101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,52,13,10,73,110, + 115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110, + 101,110,116,46,115,116,97,110,100,97,114,100,95,99,104,101,99,107,98,111, + 120,93,13,10,78,97,109,101,61,67,104,101,99,107,66,111,120,13,10,78, + 97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,67,104,101,99,107, + 66,111,120,13,10,80,97,108,101,116,116,101,61,83,116,97,110,100,97,114, + 100,13,10,74,115,70,105,108,101,78,97,109,101,61,115,116,97,110,100,97, + 114,100,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,100,105,118, + 13,10,76,97,98,101,108,67,108,97,115,115,61,102,111,114,109,45,99,104, + 101,99,107,13,10,72,105,110,116,61,67,104,101,99,107,66,111,120,13,10, + 67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,115,116,97,110, + 100,97,114,100,95,99,104,101,99,107,98,111,120,46,98,109,112,13,10,104, + 116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101, + 114,61,53,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10, + 91,67,111,109,112,111,110,101,110,116,46,115,116,97,110,100,97,114,100,95, + 114,97,100,105,111,93,13,10,78,97,109,101,61,82,97,100,105,111,66,117, + 116,116,111,110,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84, + 68,87,82,97,100,105,111,66,117,116,116,111,110,13,10,80,97,108,101,116, + 116,101,61,83,116,97,110,100,97,114,100,13,10,74,115,70,105,108,101,78, + 97,109,101,61,115,116,97,110,100,97,114,100,46,106,115,13,10,67,108,97, + 115,115,84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67,108,97, + 115,115,61,102,111,114,109,45,99,104,101,99,107,13,10,72,105,110,116,61, + 82,97,100,105,111,66,117,116,116,111,110,13,10,67,108,97,115,115,73,99, + 111,110,61,105,99,111,110,115,47,115,116,97,110,100,97,114,100,95,114,97, + 100,105,111,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115, + 105,111,110,61,13,10,79,114,100,101,114,61,54,13,10,73,110,115,116,97, + 108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116, + 46,115,116,97,110,100,97,114,100,95,99,111,109,98,111,98,111,120,93,13, + 10,78,97,109,101,61,67,111,109,98,111,66,111,120,13,10,78,97,109,101, + 67,108,97,115,115,61,82,69,83,84,68,87,67,111,109,98,111,66,111,120, + 13,10,80,97,108,101,116,116,101,61,83,116,97,110,100,97,114,100,13,10, + 74,115,70,105,108,101,78,97,109,101,61,115,116,97,110,100,97,114,100,46, + 106,115,13,10,67,108,97,115,115,84,121,112,101,61,115,101,108,101,99,116, + 13,10,76,97,98,101,108,67,108,97,115,115,61,102,111,114,109,45,115,101, + 108,101,99,116,13,10,72,105,110,116,61,67,111,109,98,111,66,111,120,13, + 10,67,108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,115,116,97, + 110,100,97,114,100,95,99,111,109,98,111,98,111,120,46,98,109,112,13,10, + 104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13,10,79,114,100, + 101,114,61,55,13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13, + 10,91,67,111,109,112,111,110,101,110,116,46,115,116,97,110,100,97,114,100, + 95,108,105,115,116,98,111,120,93,13,10,78,97,109,101,61,76,105,115,116, + 66,111,120,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68, + 87,76,105,115,116,66,111,120,13,10,80,97,108,101,116,116,101,61,83,116, + 97,110,100,97,114,100,13,10,74,115,70,105,108,101,78,97,109,101,61,115, + 116,97,110,100,97,114,100,46,106,115,13,10,67,108,97,115,115,84,121,112, + 101,61,115,101,108,101,99,116,13,10,76,97,98,101,108,67,108,97,115,115, + 61,102,111,114,109,45,115,101,108,101,99,116,13,10,72,105,110,116,61,76, + 105,115,116,66,111,120,13,10,67,108,97,115,115,73,99,111,110,61,105,99, + 111,110,115,47,115,116,97,110,100,97,114,100,95,108,105,115,116,98,111,120, + 46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110, + 61,13,10,79,114,100,101,114,61,56,13,10,73,110,115,116,97,108,108,101, + 100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,115,116, + 97,110,100,97,114,100,95,103,114,105,100,93,13,10,78,97,109,101,61,71, + 114,105,100,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68, + 87,71,114,105,100,13,10,80,97,108,101,116,116,101,61,83,116,97,110,100, + 97,114,100,13,10,74,115,70,105,108,101,78,97,109,101,61,115,116,97,110, + 100,97,114,100,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,116, + 97,98,108,101,13,10,76,97,98,101,108,67,108,97,115,115,61,116,97,98, + 108,101,32,116,97,98,108,101,45,115,116,114,105,112,101,100,13,10,72,105, + 110,116,61,71,114,105,100,13,10,67,108,97,115,115,73,99,111,110,61,105, + 99,111,110,115,47,115,116,97,110,100,97,114,100,95,103,114,105,100,46,98, + 109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105,111,110,61,13, + 10,79,114,100,101,114,61,57,13,10,73,110,115,116,97,108,108,101,100,61, + 49,13,10,13,10,91,67,111,109,112,111,110,101,110,116,46,115,116,97,110, + 100,97,114,100,95,105,109,97,103,101,93,13,10,78,97,109,101,61,73,109, + 97,103,101,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68, + 87,73,109,97,103,101,13,10,80,97,108,101,116,116,101,61,83,116,97,110, + 100,97,114,100,13,10,74,115,70,105,108,101,78,97,109,101,61,115,116,97, + 110,100,97,114,100,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61, + 105,109,103,13,10,76,97,98,101,108,67,108,97,115,115,61,105,109,103,45, + 102,108,117,105,100,13,10,72,105,110,116,61,73,109,97,103,101,13,10,67, + 108,97,115,115,73,99,111,110,61,105,99,111,110,115,47,115,116,97,110,100, + 97,114,100,95,105,109,97,103,101,46,98,109,112,13,10,104,116,109,108,95, + 101,120,116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,49,48, + 13,10,73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111, + 109,112,111,110,101,110,116,46,115,116,97,110,100,97,114,100,95,108,105,110, + 107,93,13,10,78,97,109,101,61,76,105,110,107,13,10,78,97,109,101,67, + 108,97,115,115,61,82,69,83,84,68,87,76,105,110,107,13,10,80,97,108, + 101,116,116,101,61,83,116,97,110,100,97,114,100,13,10,74,115,70,105,108, + 101,78,97,109,101,61,115,116,97,110,100,97,114,100,46,106,115,13,10,67, + 108,97,115,115,84,121,112,101,61,97,13,10,76,97,98,101,108,67,108,97, + 115,115,61,13,10,72,105,110,116,61,76,105,110,107,13,10,67,108,97,115, + 115,73,99,111,110,61,105,99,111,110,115,47,115,116,97,110,100,97,114,100, + 95,108,105,110,107,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101, + 110,115,105,111,110,61,13,10,79,114,100,101,114,61,49,49,13,10,73,110, + 115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110, + 101,110,116,46,115,116,97,110,100,97,114,100,95,112,97,110,101,108,93,13, + 10,78,97,109,101,61,80,97,110,101,108,13,10,78,97,109,101,67,108,97, + 115,115,61,82,69,83,84,68,87,80,97,110,101,108,13,10,80,97,108,101, + 116,116,101,61,83,116,97,110,100,97,114,100,13,10,74,115,70,105,108,101, + 78,97,109,101,61,115,116,97,110,100,97,114,100,46,106,115,13,10,67,108, + 97,115,115,84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67,108, + 97,115,115,61,98,111,114,100,101,114,32,114,111,117,110,100,101,100,32,112, + 45,51,13,10,72,105,110,116,61,80,97,110,101,108,13,10,67,108,97,115, + 115,73,99,111,110,61,105,99,111,110,115,47,115,116,97,110,100,97,114,100, + 95,112,97,110,101,108,46,98,109,112,13,10,104,116,109,108,95,101,120,116, + 101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,49,50,13,10,73, + 110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111, + 110,101,110,116,46,115,116,97,110,100,97,114,100,95,103,114,111,117,112,98, + 111,120,93,13,10,78,97,109,101,61,71,114,111,117,112,66,111,120,13,10, + 78,97,109,101,67,108,97,115,115,61,82,69,83,84,68,87,71,114,111,117, + 112,66,111,120,13,10,80,97,108,101,116,116,101,61,83,116,97,110,100,97, + 114,100,13,10,74,115,70,105,108,101,78,97,109,101,61,115,116,97,110,100, + 97,114,100,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,102,105, + 101,108,100,115,101,116,13,10,76,97,98,101,108,67,108,97,115,115,61,98, + 111,114,100,101,114,32,114,111,117,110,100,101,100,32,112,45,51,13,10,72, + 105,110,116,61,71,114,111,117,112,66,111,120,13,10,67,108,97,115,115,73, + 99,111,110,61,105,99,111,110,115,47,115,116,97,110,100,97,114,100,95,103, + 114,111,117,112,98,111,120,46,98,109,112,13,10,104,116,109,108,95,101,120, + 116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,49,51,13,10, + 73,110,115,116,97,108,108,101,100,61,49,13,10,13,10,91,67,111,109,112, + 111,110,101,110,116,46,115,116,97,110,100,97,114,100,95,112,114,111,103,114, + 101,115,115,93,13,10,78,97,109,101,61,80,114,111,103,114,101,115,115,66, + 97,114,13,10,78,97,109,101,67,108,97,115,115,61,82,69,83,84,68,87, + 80,114,111,103,114,101,115,115,66,97,114,13,10,80,97,108,101,116,116,101, + 61,83,116,97,110,100,97,114,100,13,10,74,115,70,105,108,101,78,97,109, + 101,61,115,116,97,110,100,97,114,100,46,106,115,13,10,67,108,97,115,115, + 84,121,112,101,61,100,105,118,13,10,76,97,98,101,108,67,108,97,115,115, + 61,112,114,111,103,114,101,115,115,13,10,72,105,110,116,61,80,114,111,103, + 114,101,115,115,66,97,114,13,10,67,108,97,115,115,73,99,111,110,61,105, + 99,111,110,115,47,115,116,97,110,100,97,114,100,95,112,114,111,103,114,101, + 115,115,46,98,109,112,13,10,104,116,109,108,95,101,120,116,101,110,115,105, + 111,110,61,13,10,79,114,100,101,114,61,49,52,13,10,73,110,115,116,97, + 108,108,101,100,61,49,13,10,13,10,91,67,111,109,112,111,110,101,110,116, + 46,115,116,97,110,100,97,114,100,95,104,105,100,100,101,110,93,13,10,78, + 97,109,101,61,72,105,100,100,101,110,70,105,101,108,100,13,10,78,97,109, + 101,67,108,97,115,115,61,82,69,83,84,68,87,72,105,100,100,101,110,70, + 105,101,108,100,13,10,80,97,108,101,116,116,101,61,83,116,97,110,100,97, + 114,100,13,10,74,115,70,105,108,101,78,97,109,101,61,115,116,97,110,100, + 97,114,100,46,106,115,13,10,67,108,97,115,115,84,121,112,101,61,105,110, + 112,117,116,13,10,76,97,98,101,108,67,108,97,115,115,61,13,10,72,105, + 110,116,61,72,105,100,100,101,110,70,105,101,108,100,13,10,67,108,97,115, + 115,73,99,111,110,61,105,99,111,110,115,47,115,116,97,110,100,97,114,100, + 95,104,105,100,100,101,110,46,98,109,112,13,10,104,116,109,108,95,101,120, + 116,101,110,115,105,111,110,61,13,10,79,114,100,101,114,61,49,53,13,10, + 73,110,115,116,97,108,108,101,100,61,49,13,10 + ); + CEditorAsset4 : Array[0..19522] Of Byte = ( + 47,47,32,82,69,83,84,32,68,97,116,97,119,97,114,101,32,72,84,77, + 76,32,69,100,105,116,111,114,32,112,97,99,107,97,103,101,32,99,108,97, + 115,115,101,115,13,10,47,47,32,84,104,101,32,101,120,112,111,114,116,101, + 100,32,99,108,97,115,115,32,105,115,32,116,104,101,32,115,111,117,114,99, + 101,32,111,102,32,116,104,101,32,99,111,109,112,111,110,101,110,116,32,105, + 109,112,108,101,109,101,110,116,97,116,105,111,110,32,72,84,77,76,46,13, + 10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87, + 67,111,110,116,97,105,110,101,114,32,123,13,10,32,115,116,97,116,105,99, + 32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116, + 97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111, + 100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101, + 72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114, + 101,116,117,114,110,32,96,60,100,105,118,32,99,108,97,115,115,61,34,99, + 111,110,116,97,105,110,101,114,32,112,45,51,34,62,67,111,110,116,97,105, + 110,101,114,60,47,100,105,118,62,96,59,13,10,32,125,13,10,125,13,10, + 13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68, + 87,67,111,110,116,97,105,110,101,114,95,70,108,117,105,100,32,123,13,10, + 32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117, + 101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110, + 116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99, + 32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41, + 32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,100,105,118,32,99, + 108,97,115,115,61,34,99,111,110,116,97,105,110,101,114,45,102,108,117,105, + 100,32,112,45,51,34,62,67,111,110,116,97,105,110,101,114,32,70,108,117, + 105,100,60,47,100,105,118,62,96,59,13,10,32,125,13,10,125,13,10,13, + 10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87, + 82,111,119,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97, + 108,32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112, + 108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10, + 32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111, + 112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32, + 96,60,100,105,118,32,99,108,97,115,115,61,34,114,111,119,34,62,60,100, + 105,118,32,99,108,97,115,115,61,34,99,111,108,34,62,67,111,108,117,109, + 110,60,47,100,105,118,62,60,47,100,105,118,62,96,59,13,10,32,125,13, + 10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82, + 69,83,84,68,87,67,111,108,117,109,110,115,95,54,95,54,32,123,13,10, + 32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117, + 101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110, + 116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99, + 32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41, + 32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,100,105,118,32,99, + 108,97,115,115,61,34,114,111,119,34,62,60,100,105,118,32,99,108,97,115, + 115,61,34,99,111,108,45,54,34,62,76,101,102,116,60,47,100,105,118,62, + 60,100,105,118,32,99,108,97,115,115,61,34,99,111,108,45,54,34,62,82, + 105,103,104,116,60,47,100,105,118,62,60,47,100,105,118,62,96,59,13,10, + 32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115, + 115,32,82,69,83,84,68,87,67,111,108,117,109,110,115,95,52,95,52,95, + 52,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32, + 61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97, + 99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115, + 116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116, + 105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60, + 100,105,118,32,99,108,97,115,115,61,34,114,111,119,34,62,60,100,105,118, + 32,99,108,97,115,115,61,34,99,111,108,45,52,34,62,79,110,101,60,47, + 100,105,118,62,60,100,105,118,32,99,108,97,115,115,61,34,99,111,108,45, + 52,34,62,84,119,111,60,47,100,105,118,62,60,100,105,118,32,99,108,97, + 115,115,61,34,99,111,108,45,52,34,62,84,104,114,101,101,60,47,100,105, + 118,62,60,47,100,105,118,62,96,59,13,10,32,125,13,10,125,13,10,13, + 10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87, + 67,111,108,117,109,110,115,95,51,95,57,32,123,13,10,32,115,116,97,116, + 105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32, + 115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39, + 98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97, + 116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32, + 32,114,101,116,117,114,110,32,96,60,100,105,118,32,99,108,97,115,115,61, + 34,114,111,119,34,62,60,100,105,118,32,99,108,97,115,115,61,34,99,111, + 108,45,51,34,62,83,105,100,101,98,97,114,60,47,100,105,118,62,60,100, + 105,118,32,99,108,97,115,115,61,34,99,111,108,45,57,34,62,67,111,110, + 116,101,110,116,60,47,100,105,118,62,60,47,100,105,118,62,96,59,13,10, + 32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115, + 115,32,82,69,83,84,68,87,70,108,101,120,95,82,111,119,32,123,13,10, + 32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117, + 101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110, + 116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99, + 32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41, + 32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,100,105,118,32,99, + 108,97,115,115,61,34,100,45,102,108,101,120,32,103,97,112,45,50,34,62, + 60,100,105,118,62,73,116,101,109,32,49,60,47,100,105,118,62,60,100,105, + 118,62,73,116,101,109,32,50,60,47,100,105,118,62,60,47,100,105,118,62, + 96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32, + 99,108,97,115,115,32,82,69,83,84,68,87,71,114,105,100,32,123,13,10, + 32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117, + 101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110, + 116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99, + 32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41, + 32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,100,105,118,32,99, + 108,97,115,115,61,34,100,45,103,114,105,100,32,103,97,112,45,50,34,62, + 60,100,105,118,62,73,116,101,109,32,49,60,47,100,105,118,62,60,100,105, + 118,62,73,116,101,109,32,50,60,47,100,105,118,62,60,47,100,105,118,62, + 96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32, + 99,108,97,115,115,32,82,69,83,84,68,87,72,101,97,100,105,110,103,95, + 72,49,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108, + 32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108, + 97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32, + 115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112, + 116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96, + 60,104,49,62,72,101,97,100,105,110,103,32,72,49,60,47,104,49,62,96, + 59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99, + 108,97,115,115,32,82,69,83,84,68,87,72,101,97,100,105,110,103,95,72, + 50,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32, + 61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97, + 99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115, + 116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116, + 105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60, + 104,50,62,72,101,97,100,105,110,103,32,72,50,60,47,104,50,62,96,59, + 13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108, + 97,115,115,32,82,69,83,84,68,87,72,101,97,100,105,110,103,95,72,51, + 32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61, + 32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99, + 101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116, + 97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105, + 111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,104, + 51,62,72,101,97,100,105,110,103,32,72,51,60,47,104,51,62,96,59,13, + 10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97, + 115,115,32,82,69,83,84,68,87,80,97,114,97,103,114,97,112,104,32,123, + 13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116, + 114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109, + 101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116, + 105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110, + 115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,112,62,80, + 97,114,97,103,114,97,112,104,32,116,101,120,116,60,47,112,62,96,59,13, + 10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97, + 115,115,32,82,69,83,84,68,87,83,109,97,108,108,95,84,101,120,116,32, + 123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32, + 116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101, + 109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97, + 116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111, + 110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,115,109, + 97,108,108,62,83,109,97,108,108,32,116,101,120,116,60,47,115,109,97,108, + 108,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114, + 116,32,99,108,97,115,115,32,82,69,83,84,68,87,76,101,97,100,95,84, + 101,120,116,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97, + 108,32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112, + 108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10, + 32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111, + 112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32, + 96,60,112,32,99,108,97,115,115,61,34,108,101,97,100,34,62,76,101,97, + 100,32,112,97,114,97,103,114,97,112,104,60,47,112,62,96,59,13,10,32, + 125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115, + 32,82,69,83,84,68,87,73,109,97,103,101,32,123,13,10,32,115,116,97, + 116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10, + 32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32, + 39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101, + 97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10, + 32,32,114,101,116,117,114,110,32,96,60,105,109,103,32,99,108,97,115,115, + 61,34,105,109,103,45,102,108,117,105,100,32,114,111,117,110,100,101,100,34, + 32,115,114,99,61,34,105,109,97,103,101,115,47,115,97,109,112,108,101,46, + 112,110,103,34,32,97,108,116,61,34,73,109,97,103,101,34,62,96,59,13, + 10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97, + 115,115,32,82,69,83,84,68,87,67,97,114,100,32,123,13,10,32,115,116, + 97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13, + 10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61, + 32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114, + 101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13, + 10,32,32,114,101,116,117,114,110,32,96,60,100,105,118,32,99,108,97,115, + 115,61,34,99,97,114,100,34,62,60,100,105,118,32,99,108,97,115,115,61, + 34,99,97,114,100,45,104,101,97,100,101,114,34,62,67,97,114,100,60,47, + 100,105,118,62,60,100,105,118,32,99,108,97,115,115,61,34,99,97,114,100, + 45,98,111,100,121,34,62,67,97,114,100,32,98,111,100,121,60,47,100,105, + 118,62,60,47,100,105,118,62,96,59,13,10,32,125,13,10,125,13,10,13, + 10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87, + 67,97,114,100,95,87,105,116,104,95,70,111,111,116,101,114,32,123,13,10, + 32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117, + 101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110, + 116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99, + 32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41, + 32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,100,105,118,32,99, + 108,97,115,115,61,34,99,97,114,100,34,62,60,100,105,118,32,99,108,97, + 115,115,61,34,99,97,114,100,45,104,101,97,100,101,114,34,62,72,101,97, + 100,101,114,60,47,100,105,118,62,60,100,105,118,32,99,108,97,115,115,61, + 34,99,97,114,100,45,98,111,100,121,34,62,66,111,100,121,60,47,100,105, + 118,62,60,100,105,118,32,99,108,97,115,115,61,34,99,97,114,100,45,102, + 111,111,116,101,114,34,62,70,111,111,116,101,114,60,47,100,105,118,62,60, + 47,100,105,118,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120, + 112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,76,105,115, + 116,95,71,114,111,117,112,32,123,13,10,32,115,116,97,116,105,99,32,118, + 105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97,116, + 105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121, + 39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84, + 77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116, + 117,114,110,32,96,60,117,108,32,99,108,97,115,115,61,34,108,105,115,116, + 45,103,114,111,117,112,34,62,60,108,105,32,99,108,97,115,115,61,34,108, + 105,115,116,45,103,114,111,117,112,45,105,116,101,109,34,62,73,116,101,109, + 32,49,60,47,108,105,62,60,108,105,32,99,108,97,115,115,61,34,108,105, + 115,116,45,103,114,111,117,112,45,105,116,101,109,34,62,73,116,101,109,32, + 50,60,47,108,105,62,60,47,117,108,62,96,59,13,10,32,125,13,10,125, + 13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83, + 84,68,87,66,97,100,103,101,32,123,13,10,32,115,116,97,116,105,99,32, + 118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97, + 116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100, + 121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72, + 84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101, + 116,117,114,110,32,96,60,115,112,97,110,32,99,108,97,115,115,61,34,98, + 97,100,103,101,34,62,66,97,100,103,101,60,47,115,112,97,110,62,96,59, + 13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108, + 97,115,115,32,82,69,83,84,68,87,72,111,114,105,122,111,110,116,97,108, + 95,82,117,108,101,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115, + 117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99, + 32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59, + 13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76, + 40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114, + 110,32,96,60,104,114,62,96,59,13,10,32,125,13,10,125,13,10,13,10, + 101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,78, + 97,118,98,97,114,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115, + 117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99, + 32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59, + 13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76, + 40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114, + 110,32,96,60,110,97,118,32,99,108,97,115,115,61,34,110,97,118,98,97, + 114,34,62,60,97,32,99,108,97,115,115,61,34,110,97,118,98,97,114,45, + 98,114,97,110,100,34,32,104,114,101,102,61,34,35,34,62,68,97,115,104, + 98,111,97,114,100,60,47,97,62,60,100,105,118,32,99,108,97,115,115,61, + 34,110,97,118,34,62,60,97,32,99,108,97,115,115,61,34,110,97,118,45, + 108,105,110,107,34,32,104,114,101,102,61,34,35,34,62,72,111,109,101,60, + 47,97,62,60,97,32,99,108,97,115,115,61,34,110,97,118,45,108,105,110, + 107,34,32,104,114,101,102,61,34,35,34,62,82,101,112,111,114,116,115,60, + 47,97,62,60,47,100,105,118,62,60,47,110,97,118,62,96,59,13,10,32, + 125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115, + 32,82,69,83,84,68,87,78,97,118,95,80,105,108,108,115,32,123,13,10, + 32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117, + 101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110, + 116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99, + 32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41, + 32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,117,108,32,99,108, + 97,115,115,61,34,110,97,118,34,62,60,108,105,62,60,97,32,99,108,97, + 115,115,61,34,110,97,118,45,108,105,110,107,32,98,116,110,32,98,116,110, + 45,112,114,105,109,97,114,121,34,32,104,114,101,102,61,34,35,34,62,79, + 110,101,60,47,97,62,60,47,108,105,62,60,108,105,62,60,97,32,99,108, + 97,115,115,61,34,110,97,118,45,108,105,110,107,34,32,104,114,101,102,61, + 34,35,34,62,84,119,111,60,47,97,62,60,47,108,105,62,60,47,117,108, + 62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116, + 32,99,108,97,115,115,32,82,69,83,84,68,87,78,97,118,95,84,97,98, + 115,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32, + 61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97, + 99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115, + 116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116, + 105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60, + 117,108,32,99,108,97,115,115,61,34,110,97,118,34,62,60,108,105,62,60, + 97,32,99,108,97,115,115,61,34,110,97,118,45,108,105,110,107,34,32,104, + 114,101,102,61,34,35,34,62,84,97,98,32,49,60,47,97,62,60,47,108, + 105,62,60,108,105,62,60,97,32,99,108,97,115,115,61,34,110,97,118,45, + 108,105,110,107,34,32,104,114,101,102,61,34,35,34,62,84,97,98,32,50, + 60,47,97,62,60,47,108,105,62,60,47,117,108,62,96,59,13,10,32,125, + 13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115,32, + 82,69,83,84,68,87,66,114,101,97,100,99,114,117,109,98,32,123,13,10, + 32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117, + 101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110, + 116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99, + 32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41, + 32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,111,108,32,99,108, + 97,115,115,61,34,98,114,101,97,100,99,114,117,109,98,34,62,60,108,105, + 62,72,111,109,101,60,47,108,105,62,60,108,105,62,47,32,68,97,115,104, + 98,111,97,114,100,60,47,108,105,62,60,47,111,108,62,96,59,13,10,32, + 125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115, + 32,82,69,83,84,68,87,80,97,103,105,110,97,116,105,111,110,32,123,13, + 10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114, + 117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101, + 110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105, + 99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115, + 41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,117,108,32,99, + 108,97,115,115,61,34,112,97,103,105,110,97,116,105,111,110,34,62,60,108, + 105,62,60,97,32,99,108,97,115,115,61,34,112,97,103,101,45,108,105,110, + 107,34,32,104,114,101,102,61,34,35,34,62,49,60,47,97,62,60,47,108, + 105,62,60,108,105,62,60,97,32,99,108,97,115,115,61,34,112,97,103,101, + 45,108,105,110,107,34,32,104,114,101,102,61,34,35,34,62,50,60,47,97, + 62,60,47,108,105,62,60,47,117,108,62,96,59,13,10,32,125,13,10,125, + 13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83, + 84,68,87,84,101,120,116,95,69,100,105,116,32,123,13,10,32,115,116,97, + 116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10, + 32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32, + 39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101, + 97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10, + 32,32,114,101,116,117,114,110,32,96,60,100,105,118,32,99,108,97,115,115, + 61,34,109,98,45,51,34,62,60,108,97,98,101,108,32,99,108,97,115,115, + 61,34,102,111,114,109,45,108,97,98,101,108,34,62,84,101,120,116,60,47, + 108,97,98,101,108,62,60,105,110,112,117,116,32,99,108,97,115,115,61,34, + 102,111,114,109,45,99,111,110,116,114,111,108,34,32,116,121,112,101,61,34, + 116,101,120,116,34,62,60,47,100,105,118,62,96,59,13,10,32,125,13,10, + 125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69, + 83,84,68,87,80,97,115,115,119,111,114,100,95,69,100,105,116,32,123,13, + 10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114, + 117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101, + 110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105, + 99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115, + 41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,100,105,118,32, + 99,108,97,115,115,61,34,109,98,45,51,34,62,60,108,97,98,101,108,32, + 99,108,97,115,115,61,34,102,111,114,109,45,108,97,98,101,108,34,62,80, + 97,115,115,119,111,114,100,60,47,108,97,98,101,108,62,60,105,110,112,117, + 116,32,99,108,97,115,115,61,34,102,111,114,109,45,99,111,110,116,114,111, + 108,34,32,116,121,112,101,61,34,112,97,115,115,119,111,114,100,34,62,60, + 47,100,105,118,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120, + 112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,69,109,97, + 105,108,95,69,100,105,116,32,123,13,10,32,115,116,97,116,105,99,32,118, + 105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97,116, + 105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121, + 39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84, + 77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116, + 117,114,110,32,96,60,100,105,118,32,99,108,97,115,115,61,34,109,98,45, + 51,34,62,60,108,97,98,101,108,32,99,108,97,115,115,61,34,102,111,114, + 109,45,108,97,98,101,108,34,62,69,45,109,97,105,108,60,47,108,97,98, + 101,108,62,60,105,110,112,117,116,32,99,108,97,115,115,61,34,102,111,114, + 109,45,99,111,110,116,114,111,108,34,32,116,121,112,101,61,34,101,109,97, + 105,108,34,62,60,47,100,105,118,62,96,59,13,10,32,125,13,10,125,13, + 10,13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84, + 68,87,83,101,97,114,99,104,95,69,100,105,116,32,123,13,10,32,115,116, + 97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13, + 10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61, + 32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114, + 101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13, + 10,32,32,114,101,116,117,114,110,32,96,60,100,105,118,32,99,108,97,115, + 115,61,34,109,98,45,51,34,62,60,108,97,98,101,108,32,99,108,97,115, + 115,61,34,102,111,114,109,45,108,97,98,101,108,34,62,83,101,97,114,99, + 104,60,47,108,97,98,101,108,62,60,105,110,112,117,116,32,99,108,97,115, + 115,61,34,102,111,114,109,45,99,111,110,116,114,111,108,34,32,116,121,112, + 101,61,34,115,101,97,114,99,104,34,62,60,47,100,105,118,62,96,59,13, + 10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97, + 115,115,32,82,69,83,84,68,87,78,117,109,98,101,114,95,69,100,105,116, + 32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61, + 32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99, + 101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116, + 97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105, + 111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,100, + 105,118,32,99,108,97,115,115,61,34,109,98,45,51,34,62,60,108,97,98, + 101,108,32,99,108,97,115,115,61,34,102,111,114,109,45,108,97,98,101,108, + 34,62,78,117,109,98,101,114,60,47,108,97,98,101,108,62,60,105,110,112, + 117,116,32,99,108,97,115,115,61,34,102,111,114,109,45,99,111,110,116,114, + 111,108,34,32,116,121,112,101,61,34,110,117,109,98,101,114,34,32,118,97, + 108,117,101,61,34,48,34,32,115,116,101,112,61,34,49,34,62,60,47,100, + 105,118,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111, + 114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,68,101,99,105,109, + 97,108,95,69,100,105,116,32,123,13,10,32,115,116,97,116,105,99,32,118, + 105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97,116, + 105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121, + 39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84, + 77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116, + 117,114,110,32,96,60,100,105,118,32,99,108,97,115,115,61,34,109,98,45, + 51,34,62,60,108,97,98,101,108,32,99,108,97,115,115,61,34,102,111,114, + 109,45,108,97,98,101,108,34,62,68,101,99,105,109,97,108,60,47,108,97, + 98,101,108,62,60,105,110,112,117,116,32,99,108,97,115,115,61,34,102,111, + 114,109,45,99,111,110,116,114,111,108,34,32,116,121,112,101,61,34,110,117, + 109,98,101,114,34,32,118,97,108,117,101,61,34,48,46,48,48,34,32,115, + 116,101,112,61,34,48,46,48,49,34,62,60,47,100,105,118,62,96,59,13, + 10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97, + 115,115,32,82,69,83,84,68,87,77,111,110,101,121,95,69,100,105,116,32, + 123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32, + 116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101, + 109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97, + 116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111, + 110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,100,105, + 118,32,99,108,97,115,115,61,34,109,98,45,51,34,62,60,108,97,98,101, + 108,32,99,108,97,115,115,61,34,102,111,114,109,45,108,97,98,101,108,34, + 62,86,97,108,117,101,60,47,108,97,98,101,108,62,60,100,105,118,32,99, + 108,97,115,115,61,34,105,110,112,117,116,45,103,114,111,117,112,34,62,60, + 115,112,97,110,32,99,108,97,115,115,61,34,105,110,112,117,116,45,103,114, + 111,117,112,45,116,101,120,116,34,62,82,36,60,47,115,112,97,110,62,60, + 105,110,112,117,116,32,99,108,97,115,115,61,34,102,111,114,109,45,99,111, + 110,116,114,111,108,34,32,116,121,112,101,61,34,110,117,109,98,101,114,34, + 32,118,97,108,117,101,61,34,48,46,48,48,34,32,115,116,101,112,61,34, + 48,46,48,49,34,62,60,47,100,105,118,62,60,47,100,105,118,62,96,59, + 13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108, + 97,115,115,32,82,69,83,84,68,87,80,101,114,99,101,110,116,95,69,100, + 105,116,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108, + 32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108, + 97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32, + 115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112, + 116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96, + 60,100,105,118,32,99,108,97,115,115,61,34,109,98,45,51,34,62,60,108, + 97,98,101,108,32,99,108,97,115,115,61,34,102,111,114,109,45,108,97,98, + 101,108,34,62,80,101,114,99,101,110,116,60,47,108,97,98,101,108,62,60, + 100,105,118,32,99,108,97,115,115,61,34,105,110,112,117,116,45,103,114,111, + 117,112,34,62,60,105,110,112,117,116,32,99,108,97,115,115,61,34,102,111, + 114,109,45,99,111,110,116,114,111,108,34,32,116,121,112,101,61,34,110,117, + 109,98,101,114,34,32,118,97,108,117,101,61,34,48,34,32,109,105,110,61, + 34,48,34,32,109,97,120,61,34,49,48,48,34,32,115,116,101,112,61,34, + 48,46,48,49,34,62,60,115,112,97,110,32,99,108,97,115,115,61,34,105, + 110,112,117,116,45,103,114,111,117,112,45,116,101,120,116,34,62,37,60,47, + 115,112,97,110,62,60,47,100,105,118,62,60,47,100,105,118,62,96,59,13, + 10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97, + 115,115,32,82,69,83,84,68,87,68,97,116,101,95,80,105,99,107,101,114, + 32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61, + 32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99, + 101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116, + 97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105, + 111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,100, + 105,118,32,99,108,97,115,115,61,34,109,98,45,51,34,62,60,108,97,98, + 101,108,32,99,108,97,115,115,61,34,102,111,114,109,45,108,97,98,101,108, + 34,62,68,97,116,101,60,47,108,97,98,101,108,62,60,105,110,112,117,116, + 32,99,108,97,115,115,61,34,102,111,114,109,45,99,111,110,116,114,111,108, + 34,32,116,121,112,101,61,34,100,97,116,101,34,62,60,47,100,105,118,62, + 96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32, + 99,108,97,115,115,32,82,69,83,84,68,87,84,105,109,101,95,80,105,99, + 107,101,114,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97, + 108,32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112, + 108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10, + 32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111, + 112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32, + 96,60,100,105,118,32,99,108,97,115,115,61,34,109,98,45,51,34,62,60, + 108,97,98,101,108,32,99,108,97,115,115,61,34,102,111,114,109,45,108,97, + 98,101,108,34,62,84,105,109,101,60,47,108,97,98,101,108,62,60,105,110, + 112,117,116,32,99,108,97,115,115,61,34,102,111,114,109,45,99,111,110,116, + 114,111,108,34,32,116,121,112,101,61,34,116,105,109,101,34,62,60,47,100, + 105,118,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111, + 114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,68,97,116,101,84, + 105,109,101,95,80,105,99,107,101,114,32,123,13,10,32,115,116,97,116,105, + 99,32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115, + 116,97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98, + 111,100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116, + 101,72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32, + 114,101,116,117,114,110,32,96,60,100,105,118,32,99,108,97,115,115,61,34, + 109,98,45,51,34,62,60,108,97,98,101,108,32,99,108,97,115,115,61,34, + 102,111,114,109,45,108,97,98,101,108,34,62,68,97,116,101,32,47,32,84, + 105,109,101,60,47,108,97,98,101,108,62,60,105,110,112,117,116,32,99,108, + 97,115,115,61,34,102,111,114,109,45,99,111,110,116,114,111,108,34,32,116, + 121,112,101,61,34,100,97,116,101,116,105,109,101,45,108,111,99,97,108,34, + 62,60,47,100,105,118,62,96,59,13,10,32,125,13,10,125,13,10,13,10, + 101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,77, + 111,110,116,104,95,80,105,99,107,101,114,32,123,13,10,32,115,116,97,116, + 105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32, + 115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39, + 98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97, + 116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32, + 32,114,101,116,117,114,110,32,96,60,100,105,118,32,99,108,97,115,115,61, + 34,109,98,45,51,34,62,60,108,97,98,101,108,32,99,108,97,115,115,61, + 34,102,111,114,109,45,108,97,98,101,108,34,62,77,111,110,116,104,60,47, + 108,97,98,101,108,62,60,105,110,112,117,116,32,99,108,97,115,115,61,34, + 102,111,114,109,45,99,111,110,116,114,111,108,34,32,116,121,112,101,61,34, + 109,111,110,116,104,34,62,60,47,100,105,118,62,96,59,13,10,32,125,13, + 10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82, + 69,83,84,68,87,87,101,101,107,95,80,105,99,107,101,114,32,123,13,10, + 32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117, + 101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110, + 116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99, + 32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41, + 32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,100,105,118,32,99, + 108,97,115,115,61,34,109,98,45,51,34,62,60,108,97,98,101,108,32,99, + 108,97,115,115,61,34,102,111,114,109,45,108,97,98,101,108,34,62,87,101, + 101,107,60,47,108,97,98,101,108,62,60,105,110,112,117,116,32,99,108,97, + 115,115,61,34,102,111,114,109,45,99,111,110,116,114,111,108,34,32,116,121, + 112,101,61,34,119,101,101,107,34,62,60,47,100,105,118,62,96,59,13,10, + 32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115, + 115,32,82,69,83,84,68,87,67,111,108,111,114,95,80,105,99,107,101,114, + 32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61, + 32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99, + 101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116, + 97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105, + 111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,100, + 105,118,32,99,108,97,115,115,61,34,109,98,45,51,34,62,60,108,97,98, + 101,108,32,99,108,97,115,115,61,34,102,111,114,109,45,108,97,98,101,108, + 34,62,67,111,108,111,114,60,47,108,97,98,101,108,62,60,105,110,112,117, + 116,32,99,108,97,115,115,61,34,102,111,114,109,45,99,111,110,116,114,111, + 108,34,32,116,121,112,101,61,34,99,111,108,111,114,34,32,118,97,108,117, + 101,61,34,35,48,100,54,101,102,100,34,62,60,47,100,105,118,62,96,59, + 13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108, + 97,115,115,32,82,69,83,84,68,87,84,101,120,116,65,114,101,97,32,123, + 13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116, + 114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109, + 101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116, + 105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110, + 115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,100,105,118, + 32,99,108,97,115,115,61,34,109,98,45,51,34,62,60,108,97,98,101,108, + 32,99,108,97,115,115,61,34,102,111,114,109,45,108,97,98,101,108,34,62, + 78,111,116,101,115,60,47,108,97,98,101,108,62,60,116,101,120,116,97,114, + 101,97,32,99,108,97,115,115,61,34,102,111,114,109,45,99,111,110,116,114, + 111,108,34,32,114,111,119,115,61,34,52,34,62,60,47,116,101,120,116,97, + 114,101,97,62,60,47,100,105,118,62,96,59,13,10,32,125,13,10,125,13, + 10,13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84, + 68,87,83,101,108,101,99,116,32,123,13,10,32,115,116,97,116,105,99,32, + 118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97, + 116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100, + 121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72, + 84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101, + 116,117,114,110,32,96,60,100,105,118,32,99,108,97,115,115,61,34,109,98, + 45,51,34,62,60,108,97,98,101,108,32,99,108,97,115,115,61,34,102,111, + 114,109,45,108,97,98,101,108,34,62,83,101,108,101,99,116,60,47,108,97, + 98,101,108,62,60,115,101,108,101,99,116,32,99,108,97,115,115,61,34,102, + 111,114,109,45,115,101,108,101,99,116,34,62,60,111,112,116,105,111,110,62, + 79,112,116,105,111,110,32,49,60,47,111,112,116,105,111,110,62,60,111,112, + 116,105,111,110,62,79,112,116,105,111,110,32,50,60,47,111,112,116,105,111, + 110,62,60,47,115,101,108,101,99,116,62,60,47,100,105,118,62,96,59,13, + 10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97, + 115,115,32,82,69,83,84,68,87,77,117,108,116,105,95,83,101,108,101,99, + 116,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32, + 61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97, + 99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115, + 116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116, + 105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60, + 100,105,118,32,99,108,97,115,115,61,34,109,98,45,51,34,62,60,108,97, + 98,101,108,32,99,108,97,115,115,61,34,102,111,114,109,45,108,97,98,101, + 108,34,62,77,117,108,116,105,112,108,101,60,47,108,97,98,101,108,62,60, + 115,101,108,101,99,116,32,99,108,97,115,115,61,34,102,111,114,109,45,115, + 101,108,101,99,116,34,32,109,117,108,116,105,112,108,101,62,60,111,112,116, + 105,111,110,62,79,112,116,105,111,110,32,49,60,47,111,112,116,105,111,110, + 62,60,111,112,116,105,111,110,62,79,112,116,105,111,110,32,50,60,47,111, + 112,116,105,111,110,62,60,47,115,101,108,101,99,116,62,60,47,100,105,118, + 62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116, + 32,99,108,97,115,115,32,82,69,83,84,68,87,67,104,101,99,107,98,111, + 120,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32, + 61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97, + 99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115, + 116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116, + 105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60, + 100,105,118,32,99,108,97,115,115,61,34,102,111,114,109,45,99,104,101,99, + 107,34,62,60,105,110,112,117,116,32,116,121,112,101,61,34,99,104,101,99, + 107,98,111,120,34,32,105,100,61,34,99,104,101,99,107,49,34,62,60,108, + 97,98,101,108,32,102,111,114,61,34,99,104,101,99,107,49,34,62,67,104, + 101,99,107,60,47,108,97,98,101,108,62,60,47,100,105,118,62,96,59,13, + 10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97, + 115,115,32,82,69,83,84,68,87,83,119,105,116,99,104,32,123,13,10,32, + 115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101, + 59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116, + 32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32, + 99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32, + 123,13,10,32,32,114,101,116,117,114,110,32,96,60,100,105,118,32,99,108, + 97,115,115,61,34,102,111,114,109,45,99,104,101,99,107,34,62,60,105,110, + 112,117,116,32,116,121,112,101,61,34,99,104,101,99,107,98,111,120,34,32, + 114,111,108,101,61,34,115,119,105,116,99,104,34,32,105,100,61,34,115,119, + 105,116,99,104,49,34,62,60,108,97,98,101,108,32,102,111,114,61,34,115, + 119,105,116,99,104,49,34,62,83,119,105,116,99,104,60,47,108,97,98,101, + 108,62,60,47,100,105,118,62,96,59,13,10,32,125,13,10,125,13,10,13, + 10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87, + 82,97,100,105,111,95,71,114,111,117,112,32,123,13,10,32,115,116,97,116, + 105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32, + 115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39, + 98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97, + 116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32, + 32,114,101,116,117,114,110,32,96,60,100,105,118,32,99,108,97,115,115,61, + 34,102,111,114,109,45,99,104,101,99,107,34,62,60,105,110,112,117,116,32, + 116,121,112,101,61,34,114,97,100,105,111,34,32,110,97,109,101,61,34,114, + 97,100,105,111,49,34,32,105,100,61,34,114,97,100,105,111,49,97,34,32, + 99,104,101,99,107,101,100,62,60,108,97,98,101,108,32,102,111,114,61,34, + 114,97,100,105,111,49,97,34,62,79,112,116,105,111,110,32,65,60,47,108, + 97,98,101,108,62,60,47,100,105,118,62,60,100,105,118,32,99,108,97,115, + 115,61,34,102,111,114,109,45,99,104,101,99,107,34,62,60,105,110,112,117, + 116,32,116,121,112,101,61,34,114,97,100,105,111,34,32,110,97,109,101,61, + 34,114,97,100,105,111,49,34,32,105,100,61,34,114,97,100,105,111,49,98, + 34,62,60,108,97,98,101,108,32,102,111,114,61,34,114,97,100,105,111,49, + 98,34,62,79,112,116,105,111,110,32,66,60,47,108,97,98,101,108,62,60, + 47,100,105,118,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120, + 112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,82,97,110, + 103,101,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108, + 32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108, + 97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32, + 115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112, + 116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96, + 60,100,105,118,32,99,108,97,115,115,61,34,109,98,45,51,34,62,60,108, + 97,98,101,108,32,99,108,97,115,115,61,34,102,111,114,109,45,108,97,98, + 101,108,34,62,82,97,110,103,101,60,47,108,97,98,101,108,62,60,105,110, + 112,117,116,32,99,108,97,115,115,61,34,102,111,114,109,45,114,97,110,103, + 101,34,32,116,121,112,101,61,34,114,97,110,103,101,34,32,109,105,110,61, + 34,48,34,32,109,97,120,61,34,49,48,48,34,32,118,97,108,117,101,61, + 34,53,48,34,62,60,47,100,105,118,62,96,59,13,10,32,125,13,10,125, + 13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83, + 84,68,87,70,105,108,101,95,85,112,108,111,97,100,32,123,13,10,32,115, + 116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101,59, + 13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116,32, + 61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32,99, + 114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32,123, + 13,10,32,32,114,101,116,117,114,110,32,96,60,100,105,118,32,99,108,97, + 115,115,61,34,109,98,45,51,34,62,60,108,97,98,101,108,32,99,108,97, + 115,115,61,34,102,111,114,109,45,108,97,98,101,108,34,62,70,105,108,101, + 60,47,108,97,98,101,108,62,60,105,110,112,117,116,32,99,108,97,115,115, + 61,34,102,111,114,109,45,99,111,110,116,114,111,108,34,32,116,121,112,101, + 61,34,102,105,108,101,34,62,60,47,100,105,118,62,96,59,13,10,32,125, + 13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115,32, + 82,69,83,84,68,87,73,110,112,117,116,95,71,114,111,117,112,32,123,13, + 10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114, + 117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101, + 110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105, + 99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115, + 41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,100,105,118,32, + 99,108,97,115,115,61,34,105,110,112,117,116,45,103,114,111,117,112,34,62, + 60,115,112,97,110,32,99,108,97,115,115,61,34,105,110,112,117,116,45,103, + 114,111,117,112,45,116,101,120,116,34,62,64,60,47,115,112,97,110,62,60, + 105,110,112,117,116,32,99,108,97,115,115,61,34,102,111,114,109,45,99,111, + 110,116,114,111,108,34,62,60,47,100,105,118,62,96,59,13,10,32,125,13, + 10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82, + 69,83,84,68,87,82,101,97,100,111,110,108,121,95,69,100,105,116,32,123, + 13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116, + 114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109, + 101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116, + 105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110, + 115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,100,105,118, + 32,99,108,97,115,115,61,34,109,98,45,51,34,62,60,108,97,98,101,108, + 32,99,108,97,115,115,61,34,102,111,114,109,45,108,97,98,101,108,34,62, + 82,101,97,100,111,110,108,121,60,47,108,97,98,101,108,62,60,105,110,112, + 117,116,32,99,108,97,115,115,61,34,102,111,114,109,45,99,111,110,116,114, + 111,108,34,32,116,121,112,101,61,34,116,101,120,116,34,32,118,97,108,117, + 101,61,34,82,101,97,100,111,110,108,121,34,32,114,101,97,100,111,110,108, + 121,62,60,47,100,105,118,62,96,59,13,10,32,125,13,10,125,13,10,13, + 10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87, + 68,105,115,97,98,108,101,100,95,69,100,105,116,32,123,13,10,32,115,116, + 97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13, + 10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61, + 32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114, + 101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13, + 10,32,32,114,101,116,117,114,110,32,96,60,100,105,118,32,99,108,97,115, + 115,61,34,109,98,45,51,34,62,60,108,97,98,101,108,32,99,108,97,115, + 115,61,34,102,111,114,109,45,108,97,98,101,108,34,62,68,105,115,97,98, + 108,101,100,60,47,108,97,98,101,108,62,60,105,110,112,117,116,32,99,108, + 97,115,115,61,34,102,111,114,109,45,99,111,110,116,114,111,108,34,32,116, + 121,112,101,61,34,116,101,120,116,34,32,118,97,108,117,101,61,34,68,105, + 115,97,98,108,101,100,34,32,100,105,115,97,98,108,101,100,62,60,47,100, + 105,118,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111, + 114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,80,114,105,109,97, + 114,121,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108, + 32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108, + 97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32, + 115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112, + 116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96, + 60,98,117,116,116,111,110,32,99,108,97,115,115,61,34,98,116,110,32,98, + 116,110,45,112,114,105,109,97,114,121,34,62,80,114,105,109,97,114,121,60, + 47,98,117,116,116,111,110,62,96,59,13,10,32,125,13,10,125,13,10,13, + 10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87, + 83,101,99,111,110,100,97,114,121,32,123,13,10,32,115,116,97,116,105,99, + 32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116, + 97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111, + 100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101, + 72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114, + 101,116,117,114,110,32,96,60,98,117,116,116,111,110,32,99,108,97,115,115, + 61,34,98,116,110,32,98,116,110,45,115,101,99,111,110,100,97,114,121,34, + 62,83,101,99,111,110,100,97,114,121,60,47,98,117,116,116,111,110,62,96, + 59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99, + 108,97,115,115,32,82,69,83,84,68,87,83,117,99,99,101,115,115,32,123, + 13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116, + 114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109, + 101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116, + 105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110, + 115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,98,117,116, + 116,111,110,32,99,108,97,115,115,61,34,98,116,110,32,98,116,110,45,115, + 117,99,99,101,115,115,34,62,83,117,99,99,101,115,115,60,47,98,117,116, + 116,111,110,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112, + 111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,68,97,110,103, + 101,114,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108, + 32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108, + 97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32, + 115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112, + 116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96, + 60,98,117,116,116,111,110,32,99,108,97,115,115,61,34,98,116,110,32,98, + 116,110,45,100,97,110,103,101,114,34,62,68,97,110,103,101,114,60,47,98, + 117,116,116,111,110,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101, + 120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,87,97, + 114,110,105,110,103,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115, + 117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99, + 32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59, + 13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76, + 40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114, + 110,32,96,60,98,117,116,116,111,110,32,99,108,97,115,115,61,34,98,116, + 110,32,98,116,110,45,119,97,114,110,105,110,103,34,62,87,97,114,110,105, + 110,103,60,47,98,117,116,116,111,110,62,96,59,13,10,32,125,13,10,125, + 13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83, + 84,68,87,73,110,102,111,32,123,13,10,32,115,116,97,116,105,99,32,118, + 105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97,116, + 105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121, + 39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84, + 77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116, + 117,114,110,32,96,60,98,117,116,116,111,110,32,99,108,97,115,115,61,34, + 98,116,110,32,98,116,110,45,105,110,102,111,34,62,73,110,102,111,60,47, + 98,117,116,116,111,110,62,96,59,13,10,32,125,13,10,125,13,10,13,10, + 101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,76, + 105,103,104,116,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117, + 97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32, + 112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13, + 10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40, + 111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110, + 32,96,60,98,117,116,116,111,110,32,99,108,97,115,115,61,34,98,116,110, + 32,98,116,110,45,108,105,103,104,116,34,62,76,105,103,104,116,60,47,98, + 117,116,116,111,110,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101, + 120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,68,97, + 114,107,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108, + 32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108, + 97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32, + 115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112, + 116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96, + 60,98,117,116,116,111,110,32,99,108,97,115,115,61,34,98,116,110,32,98, + 116,110,45,100,97,114,107,34,62,68,97,114,107,60,47,98,117,116,116,111, + 110,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114, + 116,32,99,108,97,115,115,32,82,69,83,84,68,87,76,105,110,107,32,123, + 13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116, + 114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109, + 101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116, + 105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110, + 115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,98,117,116, + 116,111,110,32,99,108,97,115,115,61,34,98,116,110,32,98,116,110,45,108, + 105,110,107,34,62,76,105,110,107,60,47,98,117,116,116,111,110,62,96,59, + 13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108, + 97,115,115,32,82,69,83,84,68,87,79,117,116,108,105,110,101,95,80,114, + 105,109,97,114,121,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115, + 117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99, + 32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59, + 13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76, + 40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114, + 110,32,96,60,98,117,116,116,111,110,32,99,108,97,115,115,61,34,98,116, + 110,32,98,116,110,45,111,117,116,108,105,110,101,45,112,114,105,109,97,114, + 121,34,62,79,117,116,108,105,110,101,32,80,114,105,109,97,114,121,60,47, + 98,117,116,116,111,110,62,96,59,13,10,32,125,13,10,125,13,10,13,10, + 101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,83, + 109,97,108,108,95,66,117,116,116,111,110,32,123,13,10,32,115,116,97,116, + 105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32, + 115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39, + 98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97, + 116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32, + 32,114,101,116,117,114,110,32,96,60,98,117,116,116,111,110,32,99,108,97, + 115,115,61,34,98,116,110,32,98,116,110,45,112,114,105,109,97,114,121,32, + 98,116,110,45,115,109,34,62,83,109,97,108,108,60,47,98,117,116,116,111, + 110,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114, + 116,32,99,108,97,115,115,32,82,69,83,84,68,87,76,97,114,103,101,95, + 66,117,116,116,111,110,32,123,13,10,32,115,116,97,116,105,99,32,118,105, + 115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105, + 99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39, + 59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77, + 76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117, + 114,110,32,96,60,98,117,116,116,111,110,32,99,108,97,115,115,61,34,98, + 116,110,32,98,116,110,45,112,114,105,109,97,114,121,32,98,116,110,45,108, + 103,34,62,76,97,114,103,101,60,47,98,117,116,116,111,110,62,96,59,13, + 10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97, + 115,115,32,82,69,83,84,68,87,66,117,116,116,111,110,95,71,114,111,117, + 112,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32, + 61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97, + 99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115, + 116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116, + 105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60, + 100,105,118,32,99,108,97,115,115,61,34,100,45,102,108,101,120,32,103,97, + 112,45,50,34,62,60,98,117,116,116,111,110,32,99,108,97,115,115,61,34, + 98,116,110,32,98,116,110,45,112,114,105,109,97,114,121,34,62,78,101,119, + 60,47,98,117,116,116,111,110,62,60,98,117,116,116,111,110,32,99,108,97, + 115,115,61,34,98,116,110,32,98,116,110,45,115,117,99,99,101,115,115,34, + 62,83,97,118,101,60,47,98,117,116,116,111,110,62,60,98,117,116,116,111, + 110,32,99,108,97,115,115,61,34,98,116,110,32,98,116,110,45,100,97,110, + 103,101,114,34,62,68,101,108,101,116,101,60,47,98,117,116,116,111,110,62, + 60,47,100,105,118,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101, + 120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,67,82, + 85,68,95,84,111,111,108,98,97,114,32,123,13,10,32,115,116,97,116,105, + 99,32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115, + 116,97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98, + 111,100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116, + 101,72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32, + 114,101,116,117,114,110,32,96,60,100,105,118,32,99,108,97,115,115,61,34, + 100,45,102,108,101,120,32,103,97,112,45,50,34,62,60,98,117,116,116,111, + 110,32,99,108,97,115,115,61,34,98,116,110,32,98,116,110,45,112,114,105, + 109,97,114,121,34,62,78,101,119,60,47,98,117,116,116,111,110,62,60,98, + 117,116,116,111,110,32,99,108,97,115,115,61,34,98,116,110,32,98,116,110, + 45,115,117,99,99,101,115,115,34,62,83,97,118,101,60,47,98,117,116,116, + 111,110,62,60,98,117,116,116,111,110,32,99,108,97,115,115,61,34,98,116, + 110,32,98,116,110,45,115,101,99,111,110,100,97,114,121,34,62,69,100,105, + 116,60,47,98,117,116,116,111,110,62,60,98,117,116,116,111,110,32,99,108, + 97,115,115,61,34,98,116,110,32,98,116,110,45,100,97,110,103,101,114,34, + 62,68,101,108,101,116,101,60,47,98,117,116,116,111,110,62,60,98,117,116, + 116,111,110,32,99,108,97,115,115,61,34,98,116,110,32,98,116,110,45,119, + 97,114,110,105,110,103,34,62,67,97,110,99,101,108,60,47,98,117,116,116, + 111,110,62,60,47,100,105,118,62,96,59,13,10,32,125,13,10,125,13,10, + 13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68, + 87,65,108,101,114,116,95,80,114,105,109,97,114,121,32,123,13,10,32,115, + 116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101,59, + 13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116,32, + 61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32,99, + 114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32,123, + 13,10,32,32,114,101,116,117,114,110,32,96,60,100,105,118,32,99,108,97, + 115,115,61,34,97,108,101,114,116,32,97,108,101,114,116,45,112,114,105,109, + 97,114,121,34,62,73,110,102,111,114,109,97,116,105,111,110,32,109,101,115, + 115,97,103,101,60,47,100,105,118,62,96,59,13,10,32,125,13,10,125,13, + 10,13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84, + 68,87,65,108,101,114,116,95,83,117,99,99,101,115,115,32,123,13,10,32, + 115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101, + 59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116, + 32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32, + 99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32, + 123,13,10,32,32,114,101,116,117,114,110,32,96,60,100,105,118,32,99,108, + 97,115,115,61,34,97,108,101,114,116,32,97,108,101,114,116,45,115,117,99, + 99,101,115,115,34,62,83,117,99,99,101,115,115,32,109,101,115,115,97,103, + 101,60,47,100,105,118,62,96,59,13,10,32,125,13,10,125,13,10,13,10, + 101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,65, + 108,101,114,116,95,68,97,110,103,101,114,32,123,13,10,32,115,116,97,116, + 105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32, + 115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39, + 98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97, + 116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32, + 32,114,101,116,117,114,110,32,96,60,100,105,118,32,99,108,97,115,115,61, + 34,97,108,101,114,116,32,97,108,101,114,116,45,100,97,110,103,101,114,34, + 62,69,114,114,111,114,32,109,101,115,115,97,103,101,60,47,100,105,118,62, + 96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32, + 99,108,97,115,115,32,82,69,83,84,68,87,80,114,111,103,114,101,115,115, + 32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61, + 32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99, + 101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116, + 97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105, + 111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,100, + 105,118,32,99,108,97,115,115,61,34,112,114,111,103,114,101,115,115,34,62, + 60,100,105,118,32,99,108,97,115,115,61,34,112,114,111,103,114,101,115,115, + 45,98,97,114,34,32,115,116,121,108,101,61,34,119,105,100,116,104,58,54, + 53,37,34,62,60,47,100,105,118,62,60,47,100,105,118,62,96,59,13,10, + 32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115, + 115,32,82,69,83,84,68,87,83,112,105,110,110,101,114,32,123,13,10,32, + 115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101, + 59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116, + 32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32, + 99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32, + 123,13,10,32,32,114,101,116,117,114,110,32,96,60,115,112,97,110,32,99, + 108,97,115,115,61,34,115,112,105,110,110,101,114,45,98,111,114,100,101,114, + 34,62,60,47,115,112,97,110,62,96,59,13,10,32,125,13,10,125,13,10, + 13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68, + 87,65,99,99,111,114,100,105,111,110,32,123,13,10,32,115,116,97,116,105, + 99,32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115, + 116,97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98, + 111,100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116, + 101,72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32, + 114,101,116,117,114,110,32,96,60,100,105,118,32,99,108,97,115,115,61,34, + 97,99,99,111,114,100,105,111,110,45,105,116,101,109,34,62,60,98,117,116, + 116,111,110,32,99,108,97,115,115,61,34,97,99,99,111,114,100,105,111,110, + 45,98,117,116,116,111,110,34,32,100,97,116,97,45,98,115,45,116,111,103, + 103,108,101,61,34,99,111,108,108,97,112,115,101,34,32,100,97,116,97,45, + 98,115,45,116,97,114,103,101,116,61,34,35,97,99,99,49,34,62,65,99, + 99,111,114,100,105,111,110,60,47,98,117,116,116,111,110,62,60,100,105,118, + 32,105,100,61,34,97,99,99,49,34,32,99,108,97,115,115,61,34,97,99, + 99,111,114,100,105,111,110,45,98,111,100,121,32,99,111,108,108,97,112,115, + 101,32,115,104,111,119,34,62,67,111,110,116,101,110,116,60,47,100,105,118, + 62,60,47,100,105,118,62,96,59,13,10,32,125,13,10,125,13,10,13,10, + 101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,67, + 111,108,108,97,112,115,101,32,123,13,10,32,115,116,97,116,105,99,32,118, + 105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97,116, + 105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121, + 39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84, + 77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116, + 117,114,110,32,96,60,98,117,116,116,111,110,32,99,108,97,115,115,61,34, + 98,116,110,32,98,116,110,45,112,114,105,109,97,114,121,34,32,100,97,116, + 97,45,98,115,45,116,111,103,103,108,101,61,34,99,111,108,108,97,112,115, + 101,34,32,100,97,116,97,45,98,115,45,116,97,114,103,101,116,61,34,35, + 99,111,108,108,97,112,115,101,49,34,62,84,111,103,103,108,101,60,47,98, + 117,116,116,111,110,62,60,100,105,118,32,105,100,61,34,99,111,108,108,97, + 112,115,101,49,34,32,99,108,97,115,115,61,34,99,111,108,108,97,112,115, + 101,34,62,60,100,105,118,32,99,108,97,115,115,61,34,99,97,114,100,32, + 99,97,114,100,45,98,111,100,121,34,62,67,111,108,108,97,112,115,101,100, + 32,99,111,110,116,101,110,116,60,47,100,105,118,62,60,47,100,105,118,62, + 96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32, + 99,108,97,115,115,32,82,69,83,84,68,87,68,114,111,112,100,111,119,110, + 32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61, + 32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99, + 101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116, + 97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105, + 111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,100, + 105,118,32,99,108,97,115,115,61,34,100,114,111,112,100,111,119,110,34,62, + 60,98,117,116,116,111,110,32,99,108,97,115,115,61,34,98,116,110,32,98, + 116,110,45,115,101,99,111,110,100,97,114,121,34,62,68,114,111,112,100,111, + 119,110,60,47,98,117,116,116,111,110,62,60,100,105,118,32,99,108,97,115, + 115,61,34,100,114,111,112,100,111,119,110,45,109,101,110,117,34,62,60,97, + 32,99,108,97,115,115,61,34,110,97,118,45,108,105,110,107,34,32,104,114, + 101,102,61,34,35,34,62,65,99,116,105,111,110,60,47,97,62,60,47,100, + 105,118,62,60,47,100,105,118,62,96,59,13,10,32,125,13,10,125,13,10, + 13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68, + 87,77,111,100,97,108,32,123,13,10,32,115,116,97,116,105,99,32,118,105, + 115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105, + 99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39, + 59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77, + 76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117, + 114,110,32,96,60,98,117,116,116,111,110,32,99,108,97,115,115,61,34,98, + 116,110,32,98,116,110,45,112,114,105,109,97,114,121,34,32,100,97,116,97, + 45,98,115,45,116,111,103,103,108,101,61,34,109,111,100,97,108,34,32,100, + 97,116,97,45,98,115,45,116,97,114,103,101,116,61,34,35,109,111,100,97, + 108,49,34,62,79,112,101,110,32,77,111,100,97,108,60,47,98,117,116,116, + 111,110,62,60,100,105,118,32,105,100,61,34,109,111,100,97,108,49,34,32, + 99,108,97,115,115,61,34,109,111,100,97,108,34,62,60,104,51,62,77,111, + 100,97,108,60,47,104,51,62,60,112,62,77,111,100,97,108,32,99,111,110, + 116,101,110,116,60,47,112,62,60,47,100,105,118,62,96,59,13,10,32,125, + 13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115,32, + 82,69,83,84,68,87,79,102,102,99,97,110,118,97,115,32,123,13,10,32, + 115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101, + 59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116, + 32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32, + 99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32, + 123,13,10,32,32,114,101,116,117,114,110,32,96,60,98,117,116,116,111,110, + 32,99,108,97,115,115,61,34,98,116,110,32,98,116,110,45,112,114,105,109, + 97,114,121,34,32,100,97,116,97,45,98,115,45,116,111,103,103,108,101,61, + 34,111,102,102,99,97,110,118,97,115,34,32,100,97,116,97,45,98,115,45, + 116,97,114,103,101,116,61,34,35,111,102,102,49,34,62,79,112,101,110,60, + 47,98,117,116,116,111,110,62,60,100,105,118,32,105,100,61,34,111,102,102, + 49,34,32,99,108,97,115,115,61,34,111,102,102,99,97,110,118,97,115,34, + 62,79,102,102,99,97,110,118,97,115,32,99,111,110,116,101,110,116,60,47, + 100,105,118,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112, + 111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,84,111,97,115, + 116,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32, + 61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97, + 99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115, + 116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116, + 105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60, + 100,105,118,32,99,108,97,115,115,61,34,116,111,97,115,116,34,62,84,111, + 97,115,116,32,110,111,116,105,102,105,99,97,116,105,111,110,60,47,100,105, + 118,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114, + 116,32,99,108,97,115,115,32,82,69,83,84,68,87,84,97,98,108,101,32, + 123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32, + 116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101, + 109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97, + 116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111, + 110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,116,97, + 98,108,101,32,99,108,97,115,115,61,34,116,97,98,108,101,32,116,97,98, + 108,101,45,115,116,114,105,112,101,100,34,62,60,116,104,101,97,100,62,60, + 116,114,62,60,116,104,62,78,97,109,101,60,47,116,104,62,60,116,104,62, + 86,97,108,117,101,60,47,116,104,62,60,47,116,114,62,60,47,116,104,101, + 97,100,62,60,116,98,111,100,121,62,60,116,114,62,60,116,100,62,73,116, + 101,109,60,47,116,100,62,60,116,100,62,49,48,48,60,47,116,100,62,60, + 47,116,114,62,60,47,116,98,111,100,121,62,60,47,116,97,98,108,101,62, + 96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32, + 99,108,97,115,115,32,82,69,83,84,68,87,66,111,114,100,101,114,101,100, + 95,84,97,98,108,101,32,123,13,10,32,115,116,97,116,105,99,32,118,105, + 115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105, + 99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39, + 59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77, + 76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117, + 114,110,32,96,60,116,97,98,108,101,32,99,108,97,115,115,61,34,116,97, + 98,108,101,32,116,97,98,108,101,45,98,111,114,100,101,114,101,100,34,62, + 60,116,104,101,97,100,62,60,116,114,62,60,116,104,62,73,68,60,47,116, + 104,62,60,116,104,62,78,97,109,101,60,47,116,104,62,60,47,116,114,62, + 60,47,116,104,101,97,100,62,60,116,98,111,100,121,62,60,116,114,62,60, + 116,100,62,49,60,47,116,100,62,60,116,100,62,73,116,101,109,60,47,116, + 100,62,60,47,116,114,62,60,47,116,98,111,100,121,62,60,47,116,97,98, + 108,101,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111, + 114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,75,80,73,95,67, + 97,114,100,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97, + 108,32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112, + 108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10, + 32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111, + 112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32, + 96,60,100,105,118,32,99,108,97,115,115,61,34,99,97,114,100,34,62,60, + 100,105,118,32,99,108,97,115,115,61,34,99,97,114,100,45,98,111,100,121, + 34,62,60,100,105,118,32,99,108,97,115,115,61,34,102,119,45,98,111,108, + 100,34,62,82,101,118,101,110,117,101,60,47,100,105,118,62,60,104,50,62, + 82,36,32,48,44,48,48,60,47,104,50,62,60,115,109,97,108,108,62,67, + 117,114,114,101,110,116,32,109,111,110,116,104,60,47,115,109,97,108,108,62, + 60,47,100,105,118,62,60,47,100,105,118,62,96,59,13,10,32,125,13,10, + 125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69, + 83,84,68,87,75,80,73,95,67,97,114,100,115,95,52,32,123,13,10,32, + 115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101, + 59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116, + 32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32, + 99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32, + 123,13,10,32,32,114,101,116,117,114,110,32,96,60,100,105,118,32,99,108, + 97,115,115,61,34,114,111,119,34,62,60,100,105,118,32,99,108,97,115,115, + 61,34,99,111,108,45,51,34,62,60,100,105,118,32,99,108,97,115,115,61, + 34,99,97,114,100,34,62,60,100,105,118,32,99,108,97,115,115,61,34,99, + 97,114,100,45,98,111,100,121,34,62,60,98,62,82,101,118,101,110,117,101, + 60,47,98,62,60,104,50,62,82,36,32,49,50,53,75,60,47,104,50,62, + 60,47,100,105,118,62,60,47,100,105,118,62,60,47,100,105,118,62,60,100, + 105,118,32,99,108,97,115,115,61,34,99,111,108,45,51,34,62,60,100,105, + 118,32,99,108,97,115,115,61,34,99,97,114,100,34,62,60,100,105,118,32, + 99,108,97,115,115,61,34,99,97,114,100,45,98,111,100,121,34,62,60,98, + 62,79,114,100,101,114,115,60,47,98,62,60,104,50,62,49,46,50,56,52, + 60,47,104,50,62,60,47,100,105,118,62,60,47,100,105,118,62,60,47,100, + 105,118,62,60,100,105,118,32,99,108,97,115,115,61,34,99,111,108,45,51, + 34,62,60,100,105,118,32,99,108,97,115,115,61,34,99,97,114,100,34,62, + 60,100,105,118,32,99,108,97,115,115,61,34,99,97,114,100,45,98,111,100, + 121,34,62,60,98,62,67,108,105,101,110,116,115,60,47,98,62,60,104,50, + 62,56,52,50,60,47,104,50,62,60,47,100,105,118,62,60,47,100,105,118, + 62,60,47,100,105,118,62,60,100,105,118,32,99,108,97,115,115,61,34,99, + 111,108,45,51,34,62,60,100,105,118,32,99,108,97,115,115,61,34,99,97, + 114,100,34,62,60,100,105,118,32,99,108,97,115,115,61,34,99,97,114,100, + 45,98,111,100,121,34,62,60,98,62,67,111,110,118,101,114,115,105,111,110, + 60,47,98,62,60,104,50,62,49,56,46,52,37,60,47,104,50,62,60,47, + 100,105,118,62,60,47,100,105,118,62,60,47,100,105,118,62,60,47,100,105, + 118,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114, + 116,32,99,108,97,115,115,32,82,69,83,84,68,87,68,97,115,104,98,111, + 97,114,100,95,71,114,105,100,32,123,13,10,32,115,116,97,116,105,99,32, + 118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97, + 116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100, + 121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72, + 84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101, + 116,117,114,110,32,96,60,100,105,118,32,99,108,97,115,115,61,34,114,111, + 119,34,62,60,100,105,118,32,99,108,97,115,115,61,34,99,111,108,45,51, + 34,62,60,100,105,118,32,99,108,97,115,115,61,34,99,97,114,100,34,62, + 60,100,105,118,32,99,108,97,115,115,61,34,99,97,114,100,45,98,111,100, + 121,34,62,75,80,73,32,49,60,47,100,105,118,62,60,47,100,105,118,62, + 60,47,100,105,118,62,60,100,105,118,32,99,108,97,115,115,61,34,99,111, + 108,45,51,34,62,60,100,105,118,32,99,108,97,115,115,61,34,99,97,114, + 100,34,62,60,100,105,118,32,99,108,97,115,115,61,34,99,97,114,100,45, + 98,111,100,121,34,62,75,80,73,32,50,60,47,100,105,118,62,60,47,100, + 105,118,62,60,47,100,105,118,62,60,100,105,118,32,99,108,97,115,115,61, + 34,99,111,108,45,54,34,62,60,99,97,110,118,97,115,32,105,100,61,34, + 100,97,115,104,67,104,97,114,116,34,62,60,47,99,97,110,118,97,115,62, + 60,47,100,105,118,62,60,47,100,105,118,62,96,59,13,10,32,125,13,10, + 125,13,10 + ); + CEditorAsset5 : Array[0..1659] Of Byte = ( + 47,47,32,82,69,83,84,32,68,97,116,97,119,97,114,101,32,72,84,77, + 76,32,69,100,105,116,111,114,32,112,97,99,107,97,103,101,32,99,108,97, + 115,115,101,115,13,10,47,47,32,84,104,101,32,101,120,112,111,114,116,101, + 100,32,99,108,97,115,115,32,105,115,32,116,104,101,32,115,111,117,114,99, + 101,32,111,102,32,116,104,101,32,99,111,109,112,111,110,101,110,116,32,105, + 109,112,108,101,109,101,110,116,97,116,105,111,110,32,72,84,77,76,46,13, + 10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87, + 67,104,97,114,116,95,66,97,114,32,123,13,10,32,115,116,97,116,105,99, + 32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116, + 97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111, + 100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101, + 72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114, + 101,116,117,114,110,32,96,60,99,97,110,118,97,115,32,105,100,61,34,99, + 104,97,114,116,66,97,114,34,32,119,105,100,116,104,61,34,54,48,48,34, + 32,104,101,105,103,104,116,61,34,50,54,48,34,62,60,47,99,97,110,118, + 97,115,62,60,115,99,114,105,112,116,62,110,101,119,32,67,104,97,114,116, + 40,100,111,99,117,109,101,110,116,46,103,101,116,69,108,101,109,101,110,116, + 66,121,73,100,40,34,99,104,97,114,116,66,97,114,34,41,44,123,116,121, + 112,101,58,34,98,97,114,34,44,100,97,116,97,58,123,108,97,98,101,108, + 115,58,91,34,65,34,44,34,66,34,44,34,67,34,93,44,100,97,116,97, + 115,101,116,115,58,91,123,108,97,98,101,108,58,34,86,97,108,117,101,115, + 34,44,100,97,116,97,58,91,49,48,44,50,48,44,49,53,93,125,93,125, + 125,41,59,60,47,115,99,114,105,112,116,62,96,59,13,10,32,125,13,10, + 32,115,116,97,116,105,99,32,109,111,117,110,116,40,101,108,101,109,101,110, + 116,44,32,111,112,116,105,111,110,115,41,32,123,32,105,102,40,116,121,112, + 101,111,102,32,67,104,97,114,116,33,61,61,34,117,110,100,101,102,105,110, + 101,100,34,41,123,110,101,119,32,67,104,97,114,116,40,101,108,101,109,101, + 110,116,44,123,116,121,112,101,58,34,98,97,114,34,44,100,97,116,97,58, + 123,108,97,98,101,108,115,58,91,34,65,34,44,34,66,34,44,34,67,34, + 93,44,100,97,116,97,115,101,116,115,58,91,123,108,97,98,101,108,58,34, + 86,97,108,117,101,115,34,44,100,97,116,97,58,91,49,48,44,50,48,44, + 49,53,93,125,93,125,125,41,59,125,32,125,13,10,125,13,10,13,10,101, + 120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,67,104, + 97,114,116,95,76,105,110,101,32,123,13,10,32,115,116,97,116,105,99,32, + 118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97, + 116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100, + 121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72, + 84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101, + 116,117,114,110,32,96,60,99,97,110,118,97,115,32,105,100,61,34,99,104, + 97,114,116,76,105,110,101,34,32,119,105,100,116,104,61,34,54,48,48,34, + 32,104,101,105,103,104,116,61,34,50,54,48,34,62,60,47,99,97,110,118, + 97,115,62,60,115,99,114,105,112,116,62,110,101,119,32,67,104,97,114,116, + 40,100,111,99,117,109,101,110,116,46,103,101,116,69,108,101,109,101,110,116, + 66,121,73,100,40,34,99,104,97,114,116,76,105,110,101,34,41,44,123,116, + 121,112,101,58,34,108,105,110,101,34,44,100,97,116,97,58,123,108,97,98, + 101,108,115,58,91,34,74,97,110,34,44,34,70,101,98,34,44,34,77,97, + 114,34,93,44,100,97,116,97,115,101,116,115,58,91,123,108,97,98,101,108, + 58,34,83,101,114,105,101,115,34,44,100,97,116,97,58,91,49,50,44,49, + 56,44,49,52,93,125,93,125,125,41,59,60,47,115,99,114,105,112,116,62, + 96,59,13,10,32,125,13,10,32,115,116,97,116,105,99,32,109,111,117,110, + 116,40,101,108,101,109,101,110,116,44,32,111,112,116,105,111,110,115,41,32, + 123,32,105,102,40,116,121,112,101,111,102,32,67,104,97,114,116,33,61,61, + 34,117,110,100,101,102,105,110,101,100,34,41,123,110,101,119,32,67,104,97, + 114,116,40,101,108,101,109,101,110,116,44,123,116,121,112,101,58,34,108,105, + 110,101,34,44,100,97,116,97,58,123,108,97,98,101,108,115,58,91,34,74, + 97,110,34,44,34,70,101,98,34,44,34,77,97,114,34,93,44,100,97,116, + 97,115,101,116,115,58,91,123,108,97,98,101,108,58,34,83,101,114,105,101, + 115,34,44,100,97,116,97,58,91,49,50,44,49,56,44,49,52,93,125,93, + 125,125,41,59,125,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116, + 32,99,108,97,115,115,32,82,69,83,84,68,87,67,104,97,114,116,95,80, + 105,101,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108, + 32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108, + 97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32, + 115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112, + 116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96, + 60,99,97,110,118,97,115,32,105,100,61,34,99,104,97,114,116,80,105,101, + 34,32,119,105,100,116,104,61,34,52,53,48,34,32,104,101,105,103,104,116, + 61,34,50,53,48,34,62,60,47,99,97,110,118,97,115,62,60,115,99,114, + 105,112,116,62,110,101,119,32,67,104,97,114,116,40,100,111,99,117,109,101, + 110,116,46,103,101,116,69,108,101,109,101,110,116,66,121,73,100,40,34,99, + 104,97,114,116,80,105,101,34,41,44,123,116,121,112,101,58,34,112,105,101, + 34,44,100,97,116,97,58,123,108,97,98,101,108,115,58,91,34,65,34,44, + 34,66,34,44,34,67,34,93,44,100,97,116,97,115,101,116,115,58,91,123, + 100,97,116,97,58,91,52,48,44,51,53,44,50,53,93,125,93,125,125,41, + 59,60,47,115,99,114,105,112,116,62,96,59,13,10,32,125,13,10,32,115, + 116,97,116,105,99,32,109,111,117,110,116,40,101,108,101,109,101,110,116,44, + 32,111,112,116,105,111,110,115,41,32,123,32,105,102,40,116,121,112,101,111, + 102,32,67,104,97,114,116,33,61,61,34,117,110,100,101,102,105,110,101,100, + 34,41,123,110,101,119,32,67,104,97,114,116,40,101,108,101,109,101,110,116, + 44,123,116,121,112,101,58,34,112,105,101,34,44,100,97,116,97,58,123,108, + 97,98,101,108,115,58,91,34,65,34,44,34,66,34,44,34,67,34,93,44, + 100,97,116,97,115,101,116,115,58,91,123,100,97,116,97,58,91,52,48,44, + 51,53,44,50,53,93,125,93,125,125,41,59,125,32,125,13,10,125,13,10 + ); + CEditorAsset6 : Array[0..1319] Of Byte = ( + 47,47,32,82,69,83,84,32,68,97,116,97,119,97,114,101,32,72,84,77, + 76,32,69,100,105,116,111,114,32,112,97,99,107,97,103,101,32,99,108,97, + 115,115,101,115,13,10,47,47,32,84,104,101,32,101,120,112,111,114,116,101, + 100,32,99,108,97,115,115,32,105,115,32,116,104,101,32,115,111,117,114,99, + 101,32,111,102,32,116,104,101,32,99,111,109,112,111,110,101,110,116,32,105, + 109,112,108,101,109,101,110,116,97,116,105,111,110,32,72,84,77,76,46,13, + 10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87, + 68,97,116,97,84,97,98,108,101,32,123,13,10,32,115,116,97,116,105,99, + 32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116, + 97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111, + 100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101, + 72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114, + 101,116,117,114,110,32,96,60,116,97,98,108,101,32,105,100,61,34,100,97, + 115,104,98,111,97,114,100,84,97,98,108,101,34,32,99,108,97,115,115,61, + 34,116,97,98,108,101,32,116,97,98,108,101,45,115,116,114,105,112,101,100, + 34,62,60,116,104,101,97,100,62,60,116,114,62,60,116,104,62,78,97,109, + 101,60,47,116,104,62,60,116,104,62,86,97,108,117,101,60,47,116,104,62, + 60,47,116,114,62,60,47,116,104,101,97,100,62,60,116,98,111,100,121,62, + 60,116,114,62,60,116,100,62,73,116,101,109,32,65,60,47,116,100,62,60, + 116,100,62,49,48,48,60,47,116,100,62,60,47,116,114,62,60,116,114,62, + 60,116,100,62,73,116,101,109,32,66,60,47,116,100,62,60,116,100,62,50, + 48,48,60,47,116,100,62,60,47,116,114,62,60,47,116,98,111,100,121,62, + 60,47,116,97,98,108,101,62,60,115,99,114,105,112,116,62,110,101,119,32, + 68,97,116,97,84,97,98,108,101,40,34,35,100,97,115,104,98,111,97,114, + 100,84,97,98,108,101,34,41,59,60,47,115,99,114,105,112,116,62,96,59, + 13,10,32,125,13,10,32,115,116,97,116,105,99,32,109,111,117,110,116,40, + 101,108,101,109,101,110,116,44,32,111,112,116,105,111,110,115,41,32,123,32, + 105,102,40,116,121,112,101,111,102,32,68,97,116,97,84,97,98,108,101,33, + 61,61,34,117,110,100,101,102,105,110,101,100,34,41,123,110,101,119,32,68, + 97,116,97,84,97,98,108,101,40,101,108,101,109,101,110,116,41,59,125,32, + 125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115, + 32,82,69,83,84,68,87,68,97,116,97,84,97,98,108,101,95,67,82,85, + 68,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32, + 61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97, + 99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115, + 116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116, + 105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60, + 100,105,118,32,99,108,97,115,115,61,34,100,45,102,108,101,120,32,103,97, + 112,45,50,32,109,98,45,51,34,62,60,98,117,116,116,111,110,32,99,108, + 97,115,115,61,34,98,116,110,32,98,116,110,45,112,114,105,109,97,114,121, + 34,62,78,101,119,60,47,98,117,116,116,111,110,62,60,98,117,116,116,111, + 110,32,99,108,97,115,115,61,34,98,116,110,32,98,116,110,45,115,117,99, + 99,101,115,115,34,62,83,97,118,101,60,47,98,117,116,116,111,110,62,60, + 98,117,116,116,111,110,32,99,108,97,115,115,61,34,98,116,110,32,98,116, + 110,45,100,97,110,103,101,114,34,62,68,101,108,101,116,101,60,47,98,117, + 116,116,111,110,62,60,47,100,105,118,62,60,116,97,98,108,101,32,105,100, + 61,34,99,114,117,100,84,97,98,108,101,34,32,99,108,97,115,115,61,34, + 116,97,98,108,101,32,116,97,98,108,101,45,115,116,114,105,112,101,100,32, + 116,97,98,108,101,45,98,111,114,100,101,114,101,100,34,62,60,116,104,101, + 97,100,62,60,116,114,62,60,116,104,62,73,68,60,47,116,104,62,60,116, + 104,62,78,97,109,101,60,47,116,104,62,60,116,104,62,83,116,97,116,117, + 115,60,47,116,104,62,60,47,116,114,62,60,47,116,104,101,97,100,62,60, + 116,98,111,100,121,62,60,116,114,62,60,116,100,62,49,60,47,116,100,62, + 60,116,100,62,82,101,99,111,114,100,60,47,116,100,62,60,116,100,62,65, + 99,116,105,118,101,60,47,116,100,62,60,47,116,114,62,60,47,116,98,111, + 100,121,62,60,47,116,97,98,108,101,62,60,115,99,114,105,112,116,62,110, + 101,119,32,68,97,116,97,84,97,98,108,101,40,34,35,99,114,117,100,84, + 97,98,108,101,34,41,59,60,47,115,99,114,105,112,116,62,96,59,13,10, + 32,125,13,10,32,115,116,97,116,105,99,32,109,111,117,110,116,40,101,108, + 101,109,101,110,116,44,32,111,112,116,105,111,110,115,41,32,123,32,105,102, + 40,116,121,112,101,111,102,32,68,97,116,97,84,97,98,108,101,33,61,61, + 34,117,110,100,101,102,105,110,101,100,34,38,38,101,108,101,109,101,110,116, + 38,38,101,108,101,109,101,110,116,46,110,101,120,116,69,108,101,109,101,110, + 116,83,105,98,108,105,110,103,41,123,110,101,119,32,68,97,116,97,84,97, + 98,108,101,40,101,108,101,109,101,110,116,46,110,101,120,116,69,108,101,109, + 101,110,116,83,105,98,108,105,110,103,41,59,125,32,125,13,10,125,13,10 + ); + CEditorAsset7 : Array[0..3501] Of Byte = ( + 47,47,32,82,69,83,84,32,68,97,116,97,119,97,114,101,32,72,84,77, + 76,32,69,100,105,116,111,114,32,112,97,99,107,97,103,101,32,99,108,97, + 115,115,101,115,13,10,47,47,32,84,104,101,32,101,120,112,111,114,116,101, + 100,32,99,108,97,115,115,32,105,115,32,116,104,101,32,115,111,117,114,99, + 101,32,111,102,32,116,104,101,32,99,111,109,112,111,110,101,110,116,32,105, + 109,112,108,101,109,101,110,116,97,116,105,111,110,32,72,84,77,76,46,13, + 10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87, + 76,97,98,101,108,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115, + 117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99, + 32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59, + 13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76, + 40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114, + 110,32,96,60,108,97,98,101,108,32,99,108,97,115,115,61,34,102,111,114, + 109,45,108,97,98,101,108,34,62,76,97,98,101,108,60,47,108,97,98,101, + 108,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114, + 116,32,99,108,97,115,115,32,82,69,83,84,68,87,69,100,105,116,32,123, + 13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116, + 114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109, + 101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116, + 105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110, + 115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,105,110,112, + 117,116,32,116,121,112,101,61,34,116,101,120,116,34,32,99,108,97,115,115, + 61,34,102,111,114,109,45,99,111,110,116,114,111,108,34,32,112,108,97,99, + 101,104,111,108,100,101,114,61,34,69,100,105,116,34,62,96,59,13,10,32, + 125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115, + 32,82,69,83,84,68,87,77,101,109,111,32,123,13,10,32,115,116,97,116, + 105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32, + 115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39, + 98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97, + 116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32, + 32,114,101,116,117,114,110,32,96,60,116,101,120,116,97,114,101,97,32,99, + 108,97,115,115,61,34,102,111,114,109,45,99,111,110,116,114,111,108,34,32, + 114,111,119,115,61,34,52,34,32,112,108,97,99,101,104,111,108,100,101,114, + 61,34,77,101,109,111,34,62,60,47,116,101,120,116,97,114,101,97,62,96, + 59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99, + 108,97,115,115,32,82,69,83,84,68,87,66,117,116,116,111,110,32,123,13, + 10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114, + 117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101, + 110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105, + 99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115, + 41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,98,117,116,116, + 111,110,32,116,121,112,101,61,34,98,117,116,116,111,110,34,32,99,108,97, + 115,115,61,34,98,116,110,32,98,116,110,45,112,114,105,109,97,114,121,34, + 62,66,117,116,116,111,110,60,47,98,117,116,116,111,110,62,96,59,13,10, + 32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115, + 115,32,82,69,83,84,68,87,67,104,101,99,107,66,111,120,32,123,13,10, + 32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117, + 101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110, + 116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99, + 32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41, + 32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,100,105,118,32,99, + 108,97,115,115,61,34,102,111,114,109,45,99,104,101,99,107,34,62,60,105, + 110,112,117,116,32,99,108,97,115,115,61,34,102,111,114,109,45,99,104,101, + 99,107,45,105,110,112,117,116,34,32,116,121,112,101,61,34,99,104,101,99, + 107,98,111,120,34,32,105,100,61,34,99,104,101,99,107,49,34,62,60,108, + 97,98,101,108,32,99,108,97,115,115,61,34,102,111,114,109,45,99,104,101, + 99,107,45,108,97,98,101,108,34,32,102,111,114,61,34,99,104,101,99,107, + 49,34,62,67,104,101,99,107,66,111,120,60,47,108,97,98,101,108,62,60, + 47,100,105,118,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120, + 112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,82,97,100, + 105,111,66,117,116,116,111,110,32,123,13,10,32,115,116,97,116,105,99,32, + 118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97, + 116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100, + 121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72, + 84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101, + 116,117,114,110,32,96,60,100,105,118,32,99,108,97,115,115,61,34,102,111, + 114,109,45,99,104,101,99,107,34,62,60,105,110,112,117,116,32,99,108,97, + 115,115,61,34,102,111,114,109,45,99,104,101,99,107,45,105,110,112,117,116, + 34,32,116,121,112,101,61,34,114,97,100,105,111,34,32,110,97,109,101,61, + 34,114,97,100,105,111,71,114,111,117,112,34,32,105,100,61,34,114,97,100, + 105,111,49,34,62,60,108,97,98,101,108,32,99,108,97,115,115,61,34,102, + 111,114,109,45,99,104,101,99,107,45,108,97,98,101,108,34,32,102,111,114, + 61,34,114,97,100,105,111,49,34,62,82,97,100,105,111,66,117,116,116,111, + 110,60,47,108,97,98,101,108,62,60,47,100,105,118,62,96,59,13,10,32, + 125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115, + 32,82,69,83,84,68,87,67,111,109,98,111,66,111,120,32,123,13,10,32, + 115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101, + 59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116, + 32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32, + 99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32, + 123,13,10,32,32,114,101,116,117,114,110,32,96,60,115,101,108,101,99,116, + 32,99,108,97,115,115,61,34,102,111,114,109,45,115,101,108,101,99,116,34, + 62,60,111,112,116,105,111,110,32,118,97,108,117,101,61,34,34,62,83,101, + 108,101,99,116,46,46,46,60,47,111,112,116,105,111,110,62,60,111,112,116, + 105,111,110,32,118,97,108,117,101,61,34,49,34,62,73,116,101,109,32,49, + 60,47,111,112,116,105,111,110,62,60,111,112,116,105,111,110,32,118,97,108, + 117,101,61,34,50,34,62,73,116,101,109,32,50,60,47,111,112,116,105,111, + 110,62,60,47,115,101,108,101,99,116,62,96,59,13,10,32,125,13,10,125, + 13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83, + 84,68,87,76,105,115,116,66,111,120,32,123,13,10,32,115,116,97,116,105, + 99,32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115, + 116,97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98, + 111,100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116, + 101,72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32, + 114,101,116,117,114,110,32,96,60,115,101,108,101,99,116,32,99,108,97,115, + 115,61,34,102,111,114,109,45,115,101,108,101,99,116,34,32,115,105,122,101, + 61,34,53,34,62,60,111,112,116,105,111,110,62,73,116,101,109,32,49,60, + 47,111,112,116,105,111,110,62,60,111,112,116,105,111,110,62,73,116,101,109, + 32,50,60,47,111,112,116,105,111,110,62,60,111,112,116,105,111,110,62,73, + 116,101,109,32,51,60,47,111,112,116,105,111,110,62,60,47,115,101,108,101, + 99,116,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111, + 114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,71,114,105,100,32, + 123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61,32, + 116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99,101, + 109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116,97, + 116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105,111, + 110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,116,97, + 98,108,101,32,99,108,97,115,115,61,34,116,97,98,108,101,32,116,97,98, + 108,101,45,115,116,114,105,112,101,100,34,62,60,116,104,101,97,100,62,60, + 116,114,62,60,116,104,62,73,68,60,47,116,104,62,60,116,104,62,78,97, + 109,101,60,47,116,104,62,60,116,104,62,86,97,108,117,101,60,47,116,104, + 62,60,47,116,114,62,60,47,116,104,101,97,100,62,60,116,98,111,100,121, + 62,60,116,114,62,60,116,100,62,49,60,47,116,100,62,60,116,100,62,73, + 116,101,109,60,47,116,100,62,60,116,100,62,86,97,108,117,101,60,47,116, + 100,62,60,47,116,114,62,60,47,116,98,111,100,121,62,60,47,116,97,98, + 108,101,62,96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111, + 114,116,32,99,108,97,115,115,32,82,69,83,84,68,87,73,109,97,103,101, + 32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32,61, + 32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97,99, + 101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115,116, + 97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116,105, + 111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60,105, + 109,103,32,99,108,97,115,115,61,34,105,109,103,45,102,108,117,105,100,34, + 32,115,114,99,61,34,105,109,97,103,101,115,47,115,97,109,112,108,101,46, + 112,110,103,34,32,97,108,116,61,34,73,109,97,103,101,34,62,96,59,13, + 10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108,97, + 115,115,32,82,69,83,84,68,87,76,105,110,107,32,123,13,10,32,115,116, + 97,116,105,99,32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13, + 10,32,115,116,97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61, + 32,39,98,111,100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114, + 101,97,116,101,72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13, + 10,32,32,114,101,116,117,114,110,32,96,60,97,32,104,114,101,102,61,34, + 35,34,62,76,105,110,107,60,47,97,62,96,59,13,10,32,125,13,10,125, + 13,10,13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83, + 84,68,87,80,97,110,101,108,32,123,13,10,32,115,116,97,116,105,99,32, + 118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116,97, + 116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100, + 121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72, + 84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101, + 116,117,114,110,32,96,60,100,105,118,32,99,108,97,115,115,61,34,98,111, + 114,100,101,114,32,114,111,117,110,100,101,100,32,112,45,51,34,62,80,97, + 110,101,108,60,47,100,105,118,62,96,59,13,10,32,125,13,10,125,13,10, + 13,10,101,120,112,111,114,116,32,99,108,97,115,115,32,82,69,83,84,68, + 87,71,114,111,117,112,66,111,120,32,123,13,10,32,115,116,97,116,105,99, + 32,118,105,115,117,97,108,32,61,32,116,114,117,101,59,13,10,32,115,116, + 97,116,105,99,32,112,108,97,99,101,109,101,110,116,32,61,32,39,98,111, + 100,121,39,59,13,10,32,115,116,97,116,105,99,32,99,114,101,97,116,101, + 72,84,77,76,40,111,112,116,105,111,110,115,41,32,123,13,10,32,32,114, + 101,116,117,114,110,32,96,60,102,105,101,108,100,115,101,116,32,99,108,97, + 115,115,61,34,98,111,114,100,101,114,32,114,111,117,110,100,101,100,32,112, + 45,51,34,62,60,108,101,103,101,110,100,32,99,108,97,115,115,61,34,102, + 108,111,97,116,45,110,111,110,101,32,119,45,97,117,116,111,32,112,120,45, + 50,34,62,71,114,111,117,112,66,111,120,60,47,108,101,103,101,110,100,62, + 67,111,110,116,101,110,116,60,47,102,105,101,108,100,115,101,116,62,96,59, + 13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32,99,108, + 97,115,115,32,82,69,83,84,68,87,80,114,111,103,114,101,115,115,66,97, + 114,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97,108,32, + 61,32,116,114,117,101,59,13,10,32,115,116,97,116,105,99,32,112,108,97, + 99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13,10,32,115, + 116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40,111,112,116, + 105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110,32,96,60, + 100,105,118,32,99,108,97,115,115,61,34,112,114,111,103,114,101,115,115,34, + 62,60,100,105,118,32,99,108,97,115,115,61,34,112,114,111,103,114,101,115, + 115,45,98,97,114,34,32,115,116,121,108,101,61,34,119,105,100,116,104,58, + 53,48,37,34,62,53,48,37,60,47,100,105,118,62,60,47,100,105,118,62, + 96,59,13,10,32,125,13,10,125,13,10,13,10,101,120,112,111,114,116,32, + 99,108,97,115,115,32,82,69,83,84,68,87,72,105,100,100,101,110,70,105, + 101,108,100,32,123,13,10,32,115,116,97,116,105,99,32,118,105,115,117,97, + 108,32,61,32,102,97,108,115,101,59,13,10,32,115,116,97,116,105,99,32, + 112,108,97,99,101,109,101,110,116,32,61,32,39,98,111,100,121,39,59,13, + 10,32,115,116,97,116,105,99,32,99,114,101,97,116,101,72,84,77,76,40, + 111,112,116,105,111,110,115,41,32,123,13,10,32,32,114,101,116,117,114,110, + 32,96,60,105,110,112,117,116,32,116,121,112,101,61,34,104,105,100,100,101, + 110,34,32,110,97,109,101,61,34,104,105,100,100,101,110,70,105,101,108,100, + 34,32,118,97,108,117,101,61,34,34,62,96,59,13,10,32,125,13,10,125, + 13,10 + ); + CEditorAsset8 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,232,229,238,232,229,238,232,229,238,232,229,238, + 232,229,238,232,229,238,232,229,238,232,229,238,232,229,238,232,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,249,246,246,252,250,250,252,250,250,252, + 250,250,252,250,250,252,250,250,252,250,250,252,250,250,252,250,250,252,250,250, + 252,250,250,252,250,250,252,250,250,252,250,250,252,250,250,249,246,245,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,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,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,247,247,255,255,255,234,205,220,202,129,167, + 204,134,171,204,133,170,204,133,170,204,133,170,204,133,170,204,133,170,204,133, + 170,204,133,170,204,133,170,204,133,170,204,133,170,204,134,171,201,127,166,222, + 178,201,254,253,254,250,248,248,239,233,230,255,253,252,254,252,251,238,232,229, + 252,250,250,255,255,255,203,130,168,235,207,219,246,233,236,244,227,232,244,228, + 233,244,228,233,244,228,233,244,228,233,244,228,233,244,228,233,244,228,233,244, + 228,233,244,228,233,244,228,232,245,232,235,199,123,163,248,236,243,254,255,254, + 238,232,228,254,252,251,254,252,251,238,232,229,252,250,250,255,255,255,202,128, + 167,248,238,240,255,255,255,255,255,254,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,254, + 255,255,255,202,129,167,247,234,241,254,255,254,238,232,228,254,252,251,254,252, + 251,238,233,229,251,249,250,255,255,255,222,177,201,198,119,160,203,131,168,202, + 128,166,202,128,166,202,128,166,202,128,166,202,128,166,202,128,166,202,128,166, + 202,128,166,202,128,166,202,128,166,203,130,167,200,123,162,210,148,181,253,250, + 252,252,251,251,238,232,229,254,252,251,254,252,251,238,233,229,252,251,251,255, + 255,255,255,255,255,254,252,253,252,248,251,253,249,251,253,249,251,253,249,251, + 253,249,251,253,249,251,253,249,251,253,249,251,253,249,251,253,249,251,253,249, + 251,253,249,251,252,249,251,255,255,255,255,255,255,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,250,250,255,255,255,244,230,238,216,162,191, + 216,163,191,216,163,191,216,163,191,216,163,191,216,163,191,216,163,191,216,163, + 191,216,163,191,216,163,191,216,163,191,216,163,191,217,164,192,214,158,188,236, + 209,223,255,255,255,252,250,250,238,233,229,254,252,251,254,252,251,238,232,229, + 252,249,250,255,255,255,206,138,173,219,169,193,229,193,209,227,188,206,227,188, + 206,227,188,206,227,188,206,227,188,206,227,188,206,227,188,206,227,188,206,227, + 188,206,227,188,206,227,188,206,227,188,206,199,122,162,249,240,246,253,254,253, + 238,232,228,254,252,251,254,252,251,238,232,229,252,250,250,255,255,255,202,129, + 167,255,255,251,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,204,134,170,246,232,240,254,255,255,238,232,228,254,252,251,254,252, + 251,238,233,229,252,249,249,255,255,255,212,153,185,205,136,171,213,154,183,211, + 150,181,211,151,181,211,151,181,211,151,181,211,151,181,211,151,181,211,151,181, + 211,151,181,211,151,181,211,151,181,212,151,181,210,148,179,202,130,168,251,245, + 249,253,252,252,238,232,229,254,252,251,254,252,251,238,233,229,252,251,251,255, + 255,255,253,251,252,236,210,224,235,208,223,236,209,223,236,209,223,236,209,223, + 236,209,223,236,209,223,236,209,223,236,209,223,236,209,223,236,209,223,235,209, + 223,234,208,222,235,206,221,249,241,245,255,255,255,252,250,250,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,255,255,255,253,251,252,236,210,224, + 235,208,223,236,209,223,236,209,223,236,209,223,236,209,223,236,209,223,236,209, + 223,236,209,223,236,209,223,236,209,223,236,209,223,241,215,229,234,205,220,249, + 241,246,255,255,255,252,250,250,238,233,229,254,252,251,254,252,251,238,233,229, + 252,249,249,255,255,255,212,153,185,205,136,171,213,154,183,211,150,181,211,151, + 181,211,151,181,211,151,181,211,151,181,211,151,181,211,151,181,211,151,181,212, + 151,182,212,151,181,183,121,150,214,152,185,201,129,166,251,245,249,253,252,252, + 238,232,229,254,252,251,254,252,251,238,232,229,252,250,250,255,255,255,202,129, + 167,255,255,251,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,227,238,226,82,83,67, + 234,249,236,211,141,177,245,231,238,254,255,255,238,232,228,254,252,251,254,252, + 251,238,232,229,252,249,249,255,255,255,206,138,173,219,170,194,229,194,209,227, + 188,206,227,189,207,227,189,207,227,189,207,227,189,207,227,189,207,227,189,207, + 227,188,206,228,190,209,206,166,183,171,129,144,205,165,182,203,126,167,248,240, + 244,253,253,253,238,232,228,254,252,251,254,252,251,238,233,229,252,250,251,255, + 255,255,245,230,238,214,158,188,214,158,188,214,158,188,214,158,188,214,158,188, + 214,158,188,214,158,188,214,158,188,214,158,188,214,158,188,214,157,187,219,162, + 193,227,172,202,217,157,189,235,208,222,255,255,255,252,250,250,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,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,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,255,255,255,255,255,255,254,253,254,254,253,254,254,253,254,254,253, + 254,254,253,254,254,253,254,254,253,254,254,253,254,254,253,254,254,253,254,254, + 253,254,254,253,254,254,253,254,254,253,254,255,255,255,255,255,255,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset9 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,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,255,255, + 255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255, + 255,255,255,255,255,0,0,0,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,255,255,255,255,255,255,255,255,255,255, + 255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0, + 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,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0, + 255,255,255,255,255,255,0,0,0,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,255,255,255, + 255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,0,0, + 0,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,255,255,255,255,255,255,0,0, + 0,0,0,0,255,255,255,0,0,0,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,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,0, + 0,0,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,255, + 255,255,255,255,255,255,255,255,0,0,0,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,255,255,0,0,0,255,255,255,255,255,255,255,255,255, + 0,0,0,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,255,255, + 255,255,255,0,0,0,255,255,255,0,0,0,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,255,255,255,255,255,255,255,255,0,0,0,255,255, + 255,0,0,0,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,255, + 255,255,255,255,255,255,255,255,255,255,0,0,0,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,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,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,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,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 + ); + CEditorAsset10 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,0,0,0,0,0,0,0,0,0,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,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, + 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,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,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,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,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,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,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,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,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0, + 0,0,0,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,0,0,0,255,255,255,255,255,255,0,0,0,255,255,255, + 255,255,255,0,0,0,0,0,0,0,0,0,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, + 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,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,0,0, + 0,0,0,0,0,0,0,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,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,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,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,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,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 + ); + CEditorAsset11 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,0,0,0,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,0,0, + 0,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,0,0,0,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset12 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,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,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,251,251,255,255,255,255,255,255,255,255,255,255,255,254,253,253,252,252,253, + 251,252,253,251,252,253,251,252,253,251,252,253,251,252,253,251,252,253,251,252, + 253,251,252,253,252,254,254,254,255,255,255,255,255,255,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255,255,255,255,255, + 255,254,254,253,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, + 253,254,253,255,255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,255,255,255,254,254,254,255,255,255,255,255,255,197, + 210,179,158,179,127,161,181,132,160,181,131,160,181,131,160,181,131,160,181,131, + 161,182,132,157,179,127,181,198,159,244,246,240,255,255,255,253,254,253,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,254, + 254,254,254,255,255,228,234,220,105,138,59,86,121,30,112,141,65,112,140,63, + 114,141,66,114,141,65,114,141,65,114,141,65,113,141,64,115,143,69,97,129, + 45,84,122,32,202,213,185,255,255,255,254,255,254,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,250,254,255,254,251,252,250,106,139,60, + 129,150,82,246,242,238,255,255,255,255,254,255,255,249,249,255,249,250,255,248, + 248,255,248,248,255,248,248,255,248,249,254,246,244,170,181,133,78,117,23,231, + 236,223,255,255,255,251,250,249,238,233,229,254,252,251,254,252,251,238,233,229, + 250,250,248,255,255,255,198,211,181,85,120,30,250,242,236,246,238,231,161,175, + 123,221,218,196,253,245,242,255,246,239,255,253,248,255,252,246,255,252,247,255, + 252,246,255,251,246,255,255,255,117,143,68,149,173,117,255,255,255,249,249,247, + 238,233,229,254,252,251,254,252,251,238,233,229,249,249,247,255,255,255,157,179, + 127,116,142,67,255,255,255,131,154,86,57,101,0,95,127,44,255,248,240,181, + 168,163,93,80,71,108,94,86,107,93,85,97,83,76,140,127,118,253,254,253, + 163,176,125,111,143,68,255,255,255,251,250,249,238,233,229,254,252,251,254,252, + 251,238,233,229,249,249,247,255,255,255,162,182,133,112,140,63,255,255,255,156, + 172,117,63,106,5,120,146,74,254,248,242,204,191,185,145,132,124,155,141,134, + 154,141,134,147,134,127,175,163,154,254,254,254,159,173,120,115,146,73,255,255, + 255,251,250,249,238,233,229,254,252,251,254,252,251,238,233,229,250,250,248,255, + 255,255,215,224,203,77,115,21,235,229,214,255,255,255,211,210,183,249,238,230, + 255,246,245,255,252,248,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,249,250,97,129,44,169,188,142,255,255,255,249,249,247,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,254,254,253,255,255,255,135,161,98, + 93,125,39,208,213,188,254,244,241,247,236,227,245,235,225,244,234,224,242,232, + 222,242,232,223,241,232,221,241,234,225,223,223,206,125,148,77,97,132,48,245, + 247,242,254,255,254,251,251,250,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,255,255,254,253,254,253,247,249,244,147,171,114,82,119,27,84,121, + 31,86,121,32,86,122,32,86,122,32,86,122,32,86,122,32,86,122,32,86, + 123,34,82,119,27,118,149,76,232,237,225,255,255,255,254,255,254,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255,255,255,255,255, + 255,255,255,255,255,255,255,237,241,232,206,217,191,209,219,194,208,218,194,208, + 218,194,208,218,194,208,218,194,209,219,194,206,216,190,226,232,217,255,255,255, + 255,255,255,254,254,254,255,255,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,255,255,255,255,255,255,254,255,254,253,254,252,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,254,254,254,254,254,253,255,255,255,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255, + 255,255,255,255,255,255,255,255,255,255,255,254,254,254,253,253,252,253,253,252, + 253,253,252,253,253,252,253,253,252,253,253,252,253,253,252,253,253,252,254,254, + 253,255,255,255,255,255,255,255,255,255,255,255,255,252,251,251,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,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,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,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,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset13 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128, + 128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128, + 128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128, + 128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,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,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,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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset14 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 255,253,252,253,251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249, + 246,244,249,246,244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252, + 253,251,250,253,251,250,253,251,249,254,253,252,246,242,240,237,231,227,239,234, + 230,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,230,237,231,227,246,242,240,254,253,252,253,251,249,255,253, + 252,246,242,240,238,232,229,252,251,250,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,252,251, + 250,238,232,229,246,242,240,255,253,252,253,251,250,237,231,227,253,252,252,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,253,252,252,237,231,227,253, + 251,250,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 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,255,255,255,255,255, + 239,234,231,249,246,244,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249,246,244,249,246, + 244,239,234,231,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,255, + 255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,255, + 255,255,255,255,254,255,255,254,255,254,254,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,254,255,255,254,255,255,254,255,255,255,255,255,255,255,255, + 255,255,254,255,255,254,255,255,254,255,255,255,255,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,255,255,255,255,254,253,255,255,255,255,255,255, + 255,255,255,255,255,255,255,254,254,254,254,254,255,255,255,255,255,255,255,255, + 255,255,255,255,254,254,253,255,255,255,255,254,254,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 255,255,255,255,255,255,253,248,247,252,247,246,252,246,245,255,254,254,255,255, + 255,255,255,255,254,254,254,249,249,243,250,249,244,251,250,246,255,255,255,255, + 255,255,255,255,255,251,246,247,251,247,248,250,245,247,255,255,255,255,255,255, + 239,233,230,249,246,244,249,246,244,239,233,229,255,255,255,231,187,175,205,111, + 86,209,121,98,207,117,93,209,123,99,250,233,232,238,239,223,171,160,71,168, + 156,64,170,159,69,164,152,55,213,207,161,252,250,251,202,148,166,181,101,130, + 186,111,138,182,103,131,197,134,157,251,246,248,240,235,232,249,245,243,249,245, + 244,239,234,231,255,255,255,207,117,93,239,204,195,250,240,236,250,241,238,216, + 144,122,235,180,175,215,218,162,185,175,100,246,245,235,246,244,233,225,221,184, + 168,160,66,254,242,250,183,101,131,246,232,238,247,233,240,247,239,242,185,107, + 135,234,210,220,244,244,239,248,244,242,249,245,244,239,234,231,255,255,255,210, + 126,103,245,221,214,255,255,255,255,255,255,234,173,155,138,76,64,131,127,78, + 206,198,135,255,255,255,255,255,255,245,243,217,135,122,32,124,104,102,184,115, + 139,255,251,254,255,252,255,255,255,255,191,120,146,234,211,220,244,244,239,248, + 244,242,249,245,244,239,234,231,255,255,255,209,125,103,246,222,216,255,255,255, + 255,255,255,234,173,155,144,83,72,138,135,85,206,197,135,255,255,255,255,255, + 255,245,244,219,137,125,35,134,114,114,185,115,140,255,253,255,255,254,255,255, + 255,255,191,121,146,234,211,220,244,244,239,248,244,242,249,245,244,239,234,231, + 255,255,255,207,118,94,236,197,186,247,232,226,247,232,228,214,139,117,238,184, + 179,216,219,164,183,172,94,241,239,223,240,238,222,221,216,174,170,162,68,255, + 245,253,182,99,130,242,223,230,243,225,233,243,230,235,184,105,133,234,212,220, + 244,244,239,248,244,242,249,246,244,239,233,229,255,255,255,234,194,183,206,115, + 90,209,123,100,208,119,95,211,129,106,250,236,235,241,242,228,175,164,80,169, + 157,66,171,160,71,166,154,59,217,211,171,252,250,251,207,156,173,182,103,131, + 187,113,140,183,104,133,201,142,163,252,248,249,240,235,231,249,245,244,249,246, + 244,239,234,231,255,255,255,255,255,255,255,255,255,254,253,253,254,253,252,255, + 255,255,255,255,255,255,255,255,255,255,255,254,253,252,254,254,253,255,255,254, + 255,255,255,255,255,255,255,255,255,254,253,253,254,254,254,254,252,253,255,255, + 255,255,255,255,239,233,231,249,246,244,249,246,244,239,234,231,255,255,255,254, + 254,253,255,255,255,255,255,255,255,255,255,255,255,254,255,254,254,254,255,254, + 255,255,254,255,255,255,255,255,255,255,255,255,254,254,253,255,255,255,254,254, + 254,255,255,255,255,255,255,255,255,255,254,254,254,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249,246,244,253,251,250,237,231,227, + 253,252,252,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,253,252,252, + 237,231,227,253,251,250,255,253,252,246,242,240,238,232,229,252,251,250,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,252,251,250,238,232,229,246,242,240,255,253,252,253,251, + 249,254,253,252,246,242,240,237,231,227,239,234,230,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,230,237,231, + 227,246,242,240,254,253,252,253,251,249,253,251,250,253,251,250,255,253,252,253, + 251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244, + 249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252,253,251,250,253, + 251,250 + ); + CEditorAsset15 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,255,255,255,255,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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, + 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,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,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,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, + 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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset16 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,255,255,255,255,255,255, + 255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset17 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,255,255,255,255,255,255, + 255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset18 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,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,0,0, + 0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,0,0,0,255,255,255,0, + 0,0,255,255,255,255,255,255,0,0,0,255,255,255,0,0,0,255,255,255, + 255,255,255,0,0,0,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,255, + 255,255,255,255,255,0,0,0,255,255,255,0,0,0,255,255,255,255,255,255, + 0,0,0,255,255,255,0,0,0,255,255,255,255,255,255,0,0,0,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,255,255,255,255,255,255,0,0,0, + 255,255,255,0,0,0,255,255,255,255,255,255,0,0,0,255,255,255,0,0, + 0,255,255,255,255,255,255,0,0,0,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,255,255,255,255,255,255,0,0,0,255,255,255,0,0,0,255,255, + 255,255,255,255,0,0,0,255,255,255,0,0,0,255,255,255,255,255,255,0, + 0,0,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,255,255,255,255,255, + 255,0,0,0,255,255,255,0,0,0,255,255,255,255,255,255,0,0,0,255, + 255,255,0,0,0,255,255,255,255,255,255,0,0,0,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,0,0,0,0,0,0,255,255,255,0, + 0,0,255,255,255,255,255,255,0,0,0,255,255,255,0,0,0,255,255,255, + 255,255,255,0,0,0,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,255,255,255,255,255,255, + 0,0,0,255,255,255,0,0,0,255,255,255,255,255,255,0,0,0,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,255,255,255,255,255,255,0,0,0,255,255,255,0,0, + 0,255,255,255,255,255,255,0,0,0,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,255,255, + 255,255,255,255,0,0,0,255,255,255,0,0,0,255,255,255,255,255,255,0, + 0,0,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,0,0,0,0,0,0,255, + 255,255,0,0,0,255,255,255,255,255,255,0,0,0,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,255,255,255,255,255,0,0,0,255,255,255, + 255,255,255,0,0,0,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,255,255,255,255,255,0,0,0,255,255,255,255,255,255,0,0,0,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,255,255,255,255,255,0,0, + 0,0,0,0,0,0,0,0,0,0,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,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, + 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,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,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,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, + 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 + ); + CEditorAsset19 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 255,253,252,253,251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249, + 246,244,249,246,244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252, + 253,251,250,253,251,250,253,251,249,254,253,252,246,242,240,237,231,227,239,234, + 230,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,230,237,231,227,246,242,240,254,253,252,253,251,249,255,253, + 252,246,242,240,238,232,229,251,249,248,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,251,249, + 248,238,232,228,246,242,240,255,253,252,253,251,250,237,231,227,253,252,252,255, + 255,255,255,255,255,254,252,253,254,253,253,254,253,253,254,253,253,254,253,253, + 254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253, + 253,254,253,253,254,253,253,254,254,254,255,255,255,253,252,252,237,231,227,253, + 251,250,249,246,244,239,233,230,255,255,255,224,191,203,182,103,132,186,111,138, + 186,110,137,186,110,137,186,110,137,186,110,137,186,110,137,186,110,137,186,110, + 137,186,110,137,186,110,137,186,110,137,186,110,137,186,110,137,186,112,138,182, + 102,131,212,167,183,255,255,255,239,233,230,249,246,244,248,245,243,240,237,233, + 250,245,247,179,98,127,232,205,215,243,228,234,242,225,232,243,226,233,243,226, + 233,243,226,233,243,226,233,243,226,233,243,226,233,243,226,233,243,226,233,243, + 226,233,243,226,233,243,226,233,242,227,233,240,222,229,180,98,127,239,221,228, + 243,242,237,248,244,242,248,245,243,241,238,234,248,239,243,185,110,137,255,250, + 252,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,192,122,147,233,209,218,244,244,239,248,244,242,248,245, + 243,241,238,234,248,240,244,184,107,134,252,246,250,250,238,237,255,251,254,254, + 250,251,254,249,251,254,250,252,254,249,251,254,247,249,254,249,251,254,250,252, + 254,250,252,254,250,252,254,250,252,254,250,252,253,249,251,254,254,254,190,118, + 144,234,211,220,244,244,239,248,244,242,248,245,243,241,238,234,248,239,242,186, + 112,140,246,228,229,200,96,67,224,163,149,255,255,255,254,250,252,254,248,250, + 255,255,255,255,255,255,255,252,255,255,251,253,255,251,253,255,251,253,255,251, + 253,255,251,253,254,250,252,255,255,255,190,118,144,234,211,220,244,244,239,248, + 244,242,248,245,243,241,238,234,248,240,243,185,107,135,251,244,246,225,166,151, + 189,68,35,222,158,142,255,252,253,255,255,255,249,234,232,229,177,165,252,242, + 243,255,252,253,255,250,252,255,251,253,255,251,253,255,251,253,254,250,252,255, + 255,255,190,118,144,234,211,220,244,244,239,248,244,242,248,245,243,241,238,234, + 248,240,244,184,107,134,251,244,247,255,255,255,232,186,175,191,70,37,217,143, + 124,229,180,168,198,91,62,187,61,26,220,153,136,255,255,255,254,249,250,255, + 251,253,255,251,253,255,251,253,254,250,252,255,255,255,190,118,144,234,211,220, + 244,244,239,248,244,242,248,245,243,241,238,234,248,240,244,184,108,135,251,242, + 246,255,251,252,255,255,255,235,195,185,193,78,46,191,71,39,218,148,130,232, + 185,174,192,75,43,239,205,198,255,255,255,254,249,250,255,251,253,255,250,252, + 253,248,249,255,255,255,190,118,144,234,211,220,244,244,239,248,244,242,248,245, + 243,241,238,234,248,240,244,184,108,135,251,243,246,255,253,255,254,248,250,255, + 255,255,242,215,210,241,212,206,255,255,255,255,255,255,216,140,121,200,96,68, + 252,245,245,254,251,252,254,248,249,255,254,255,255,255,255,255,255,255,190,118, + 143,234,211,220,244,244,239,248,244,242,248,245,243,241,238,234,248,240,244,184, + 108,135,251,243,246,255,253,255,255,250,253,254,249,251,255,255,255,255,255,255, + 254,249,250,254,251,252,251,241,241,198,91,62,218,148,130,255,255,255,255,255, + 255,252,244,243,229,179,168,253,243,241,191,122,148,234,211,219,244,244,239,248, + 244,242,248,245,243,241,238,234,248,240,244,184,108,135,251,243,246,255,253,255, + 255,250,253,255,251,253,254,249,251,254,249,251,255,251,253,254,249,250,255,255, + 255,237,199,191,192,75,43,234,193,184,225,168,154,199,92,64,190,68,35,240, + 207,197,193,127,154,233,209,217,244,244,239,248,244,242,248,245,243,241,238,234, + 248,240,244,184,108,135,251,243,246,255,253,255,255,250,253,255,251,253,255,251, + 253,255,251,253,255,251,253,255,251,253,254,249,250,255,255,255,218,146,128,188, + 63,29,196,84,54,216,142,122,241,214,209,254,252,252,190,117,143,234,211,220, + 244,244,239,248,244,242,248,245,243,241,238,234,248,240,244,184,108,135,251,243, + 246,255,253,255,255,250,253,255,251,253,255,251,253,255,251,253,255,251,253,255, + 251,253,255,250,252,255,252,253,252,242,242,228,176,163,246,225,222,255,255,255, + 255,255,255,255,255,255,190,118,144,234,211,220,244,244,239,248,244,242,248,245, + 243,241,238,234,248,240,244,185,109,136,250,241,244,254,250,253,254,247,251,254, + 248,251,254,248,251,254,248,251,254,248,251,254,248,251,254,248,251,254,248,250, + 254,250,253,255,255,255,255,254,255,253,246,248,252,245,248,254,252,252,190,119, + 145,234,211,220,244,244,239,248,244,242,248,245,243,241,238,234,248,239,243,182, + 104,131,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,189,116,142,233,209,218,244,245,240,248, + 244,242,249,245,244,239,234,231,253,251,252,190,121,145,195,129,153,207,155,173, + 206,151,171,206,152,172,206,152,172,206,152,172,206,152,172,206,152,172,206,152, + 172,206,152,172,206,152,172,206,152,172,206,152,172,206,151,171,206,154,173,201, + 142,163,182,104,132,248,239,242,241,238,234,248,245,243,253,251,250,236,230,226, + 253,253,252,250,244,246,213,168,184,211,164,181,212,165,181,211,164,181,211,164, + 181,211,164,181,211,164,181,211,164,181,211,164,181,211,164,181,211,164,181,211, + 164,181,211,164,181,211,165,181,211,165,182,210,162,179,243,229,235,254,255,254, + 236,230,226,253,251,250,255,253,252,246,242,240,238,232,228,253,253,252,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,254,255,254,238,232,228,246,242,240,255,253,252,253,251, + 249,254,253,252,246,242,240,237,230,227,238,231,228,238,231,229,238,231,229,238, + 231,229,238,231,229,238,231,229,238,231,229,238,231,229,238,231,229,238,231,229, + 238,231,229,238,231,229,238,231,229,238,231,229,238,231,229,238,231,228,237,230, + 226,246,242,240,254,253,252,253,251,249,253,251,250,253,251,250,255,253,252,253, + 251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244, + 249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252,253,251,250,253, + 251,250 + ); + CEditorAsset20 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 255,253,252,253,251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249, + 246,244,249,246,244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252, + 253,251,250,253,251,250,253,251,249,254,253,252,246,242,240,237,231,227,239,234, + 230,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,230,237,231,227,246,242,240,254,253,252,253,251,249,255,253, + 252,246,242,240,238,232,229,251,249,248,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,251,249, + 248,238,232,228,246,242,240,255,253,252,253,251,250,237,231,227,253,252,252,255, + 255,255,255,255,255,254,252,253,254,253,253,254,253,253,254,253,253,254,253,253, + 254,252,253,253,251,252,253,251,252,254,252,253,254,253,253,254,253,253,254,253, + 253,254,253,253,254,253,253,254,254,254,255,255,255,253,252,252,237,231,227,253, + 251,250,249,246,244,239,233,230,255,255,255,224,191,203,182,103,132,186,111,138, + 186,110,137,186,110,137,185,109,136,184,108,135,187,112,139,189,118,143,189,118, + 144,187,114,140,185,108,136,185,109,136,186,110,137,186,110,137,186,112,138,182, + 102,131,212,167,183,255,255,255,239,233,230,249,246,244,248,245,243,240,237,233, + 250,245,247,179,98,127,232,205,215,243,229,235,243,225,232,242,224,231,245,230, + 236,248,237,242,239,218,226,226,193,205,225,190,203,236,213,222,247,236,240,246, + 233,238,242,224,231,243,226,233,242,227,233,240,222,229,180,98,127,239,221,228, + 243,242,237,248,244,242,248,245,243,241,238,234,248,239,243,185,110,136,255,251, + 253,255,255,255,255,254,255,255,255,255,248,238,242,204,147,167,181,100,129,171, + 81,113,171,80,112,178,95,125,198,134,157,240,221,228,255,255,255,255,255,255, + 255,255,255,255,255,255,192,122,147,233,209,218,244,244,239,248,244,242,248,245, + 243,241,238,234,248,240,244,184,108,135,250,242,245,254,251,253,255,255,255,231, + 204,214,173,83,115,163,64,100,168,75,108,171,80,113,171,81,113,169,77,110, + 164,66,101,167,72,106,219,179,194,255,255,255,253,247,250,254,254,254,190,118, + 144,234,211,220,244,244,239,248,244,242,248,245,243,241,238,234,248,240,244,184, + 108,135,250,241,245,255,254,255,242,225,231,171,80,113,167,72,106,173,84,116, + 168,73,107,164,66,101,164,66,101,166,70,105,172,83,115,170,77,110,164,66, + 102,230,199,211,255,255,255,255,255,255,190,118,144,234,211,220,244,244,239,248, + 244,242,248,245,243,241,238,234,248,240,244,184,108,135,250,241,245,255,255,255, + 193,125,150,165,67,102,173,84,115,166,69,104,183,105,133,217,176,190,220,183, + 196,190,120,145,166,69,103,172,82,114,167,73,107,180,98,128,251,244,247,255, + 255,255,189,117,143,234,211,220,244,244,239,248,244,242,248,245,243,241,238,234, + 248,240,244,184,107,135,254,248,251,246,232,237,171,79,112,171,79,112,167,71, + 106,186,111,138,250,245,247,255,255,255,255,255,255,255,255,255,198,137,159,165, + 69,104,172,83,115,165,69,104,230,201,212,255,255,255,188,115,142,234,211,220, + 244,244,239,248,244,242,248,245,243,241,238,234,248,240,244,183,105,133,255,253, + 255,227,194,207,165,67,102,173,82,115,165,68,103,230,202,212,255,255,255,253, + 249,251,253,250,251,255,255,255,244,231,236,174,78,109,175,79,111,167,65,98, + 211,158,176,255,255,255,188,115,141,234,211,220,244,244,239,248,244,242,248,245, + 243,241,238,234,248,240,244,183,105,133,255,254,255,222,185,200,164,66,101,172, + 81,114,168,74,108,239,222,227,253,253,252,254,253,253,254,254,255,254,253,252, + 244,247,250,76,127,199,63,116,194,50,107,190,143,171,217,255,255,255,186,116, + 143,234,211,220,244,244,239,248,244,242,248,245,243,241,238,234,248,240,244,184, + 106,134,255,251,254,235,209,219,167,71,105,172,82,115,164,67,100,214,166,187, + 255,255,255,254,253,254,252,253,254,255,255,255,184,215,251,22,122,214,36,132, + 221,15,120,217,155,197,238,255,255,255,186,116,143,234,211,220,244,244,239,248, + 244,242,248,245,243,241,238,234,248,240,244,184,107,135,252,245,248,252,246,249, + 177,92,122,168,76,107,172,73,118,164,96,86,216,213,169,254,253,252,255,255, + 255,232,225,192,83,138,168,24,122,227,42,127,211,33,123,213,220,229,245,255, + 255,255,188,117,143,234,211,220,244,244,239,248,244,242,248,245,243,241,238,234, + 248,240,244,184,108,135,250,240,244,255,255,255,214,168,184,164,59,103,168,98, + 95,150,136,25,146,133,16,167,155,61,169,158,68,151,135,21,147,134,23,72, + 133,171,10,115,225,112,168,226,255,254,254,255,255,255,190,118,144,234,211,220, + 244,244,239,248,244,242,248,245,243,241,238,234,248,240,244,184,108,135,251,242, + 246,255,253,253,254,250,253,190,138,133,142,124,8,152,140,28,154,139,34,149, + 134,22,148,134,20,152,139,33,157,140,27,141,128,13,93,145,173,235,242,252, + 254,252,251,255,255,255,190,118,144,234,211,220,244,244,239,248,244,242,248,245, + 243,241,238,234,248,240,244,185,109,136,250,241,244,254,250,252,253,249,250,249, + 250,239,190,180,113,146,130,17,142,126,8,145,129,14,145,129,15,143,126,9, + 142,127,13,178,165,85,249,239,217,255,251,251,252,246,248,254,252,253,190,119, + 145,234,211,220,244,244,239,248,244,242,248,245,243,241,238,234,248,239,243,182, + 104,131,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,240,243,218, + 208,207,147,187,184,101,185,182,97,203,201,136,234,236,204,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,189,116,142,233,209,218,244,245,240,248, + 244,242,249,245,244,239,234,231,253,251,252,190,121,145,195,129,153,207,154,173, + 206,151,171,206,151,171,205,150,169,211,157,182,214,160,188,211,157,182,211,156, + 181,214,160,187,212,158,184,206,151,171,206,151,170,206,151,171,206,154,173,201, + 142,163,182,104,132,248,239,242,241,238,234,248,245,243,253,251,250,236,230,226, + 253,253,252,250,244,246,213,168,184,211,164,181,212,165,181,211,164,181,211,164, + 181,210,163,179,210,163,177,210,163,179,210,163,179,210,163,178,210,163,178,211, + 164,181,211,164,181,211,165,181,211,165,182,210,162,179,243,229,235,254,255,254, + 236,230,226,253,251,250,255,253,252,246,242,240,238,232,228,253,253,252,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,254,255,254,238,232,228,246,242,240,255,253,252,253,251, + 249,254,253,252,246,242,240,237,230,227,238,231,228,238,231,229,238,231,229,238, + 231,229,238,231,229,238,231,229,238,231,229,238,231,229,238,231,229,238,231,229, + 238,231,229,238,231,229,238,231,229,238,231,229,238,231,229,238,231,228,237,230, + 226,246,242,240,254,253,252,253,251,249,253,251,250,253,251,250,255,253,252,253, + 251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244, + 249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252,253,251,250,253, + 251,250 + ); + CEditorAsset21 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,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,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,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,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,255,255,255,255, + 255,255,255,255,255,255,255,255,0,0,0,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,0,0,0, + 0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,0,0,0,0,0,0,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, + 255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,0,0,0,0,0, + 0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,255, + 255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,0,0,0,255,255,255,255,255,255,255, + 255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0, + 0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0, + 0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,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,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,0,0,0,255,255, + 255,0,0,0,0,0,0,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, + 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,0,0,0,0,0,0,0,0,0,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,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,255,255,255,0,0,0,0,0,0,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,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,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,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,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,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,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,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,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,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,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,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 + ); + CEditorAsset22 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,232,229,238,232,229,238,232,229,238,232,229,238, + 232,229,238,232,229,238,232,229,238,232,229,238,232,229,238,232,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,249,246,246,252,250,250,252,250,250,252, + 250,250,252,250,250,252,250,250,252,250,250,252,250,250,252,250,250,252,250,250, + 252,250,250,252,250,250,252,250,250,252,250,250,252,250,250,249,246,245,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,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,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,247,247,255,255,255,234,205,220,202,129,167, + 204,134,171,204,133,170,204,133,170,204,133,170,204,133,170,204,133,170,204,133, + 170,204,133,170,204,133,170,204,133,170,204,133,170,204,134,171,201,127,166,222, + 178,201,254,253,254,250,248,248,239,233,230,255,253,252,254,252,251,238,232,229, + 252,250,250,255,255,255,203,130,168,235,207,219,246,233,236,244,227,232,244,228, + 233,244,228,233,244,228,233,244,228,233,244,228,233,244,228,233,244,228,233,244, + 228,233,244,228,233,244,228,232,245,232,235,199,123,163,248,236,243,254,255,254, + 238,232,228,254,252,251,254,252,251,238,232,229,252,250,250,255,255,255,202,128, + 167,248,238,240,255,255,255,255,255,254,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,254, + 255,255,255,202,129,167,247,234,241,254,255,254,238,232,228,254,252,251,254,252, + 251,238,233,229,251,249,250,255,255,255,222,177,201,198,119,160,203,131,168,202, + 128,166,202,128,166,202,128,166,202,128,166,202,128,166,202,128,166,202,128,166, + 202,128,166,202,128,166,202,128,166,203,130,167,200,123,162,210,148,181,253,250, + 252,252,251,251,238,232,229,254,252,251,254,252,251,238,233,229,252,251,251,255, + 255,255,255,255,255,254,252,253,252,248,251,253,249,251,253,249,251,253,249,251, + 253,249,251,253,249,251,253,249,251,253,249,251,253,249,251,253,249,251,253,249, + 251,253,249,251,252,249,251,255,255,255,255,255,255,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,250,250,255,255,255,244,230,238,216,162,191, + 216,163,191,216,163,191,216,163,191,216,163,191,216,163,191,216,163,191,216,163, + 191,216,163,191,216,163,191,216,163,191,216,163,191,217,164,192,214,158,188,236, + 209,223,255,255,255,252,250,250,238,233,229,254,252,251,254,252,251,238,232,229, + 252,249,250,255,255,255,206,138,173,219,169,193,229,193,209,227,188,206,227,188, + 206,227,188,206,227,188,206,227,188,206,227,188,206,227,188,206,227,188,206,227, + 188,206,227,188,206,227,188,206,227,188,206,199,122,162,249,240,246,253,254,253, + 238,232,228,254,252,251,254,252,251,238,232,229,252,250,250,255,255,255,202,129, + 167,255,255,251,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,204,134,170,246,232,240,254,255,255,238,232,228,254,252,251,254,252, + 251,238,233,229,252,249,249,255,255,255,212,153,185,205,136,171,213,154,183,211, + 150,181,211,151,181,211,151,181,211,151,181,211,151,181,211,151,181,211,151,181, + 211,151,181,211,151,181,211,151,181,212,151,181,210,148,179,202,130,168,251,245, + 249,253,252,252,238,232,229,254,252,251,254,252,251,238,233,229,252,251,251,255, + 255,255,253,251,252,236,210,224,235,208,223,236,209,223,236,209,223,236,209,223, + 236,209,223,236,209,223,236,209,223,236,209,223,236,209,223,236,209,223,235,209, + 223,234,208,222,235,206,221,249,241,245,255,255,255,252,250,250,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,255,255,255,253,251,252,236,210,224, + 235,208,223,236,209,223,236,209,223,236,209,223,236,209,223,236,209,223,236,209, + 223,236,209,223,236,209,223,236,209,223,236,209,223,241,215,229,234,205,220,249, + 241,246,255,255,255,252,250,250,238,233,229,254,252,251,254,252,251,238,233,229, + 252,249,249,255,255,255,212,153,185,205,136,171,213,154,183,211,150,181,211,151, + 181,211,151,181,211,151,181,211,151,181,211,151,181,211,151,181,211,151,181,212, + 151,182,212,151,181,183,121,150,214,152,185,201,129,166,251,245,249,253,252,252, + 238,232,229,254,252,251,254,252,251,238,232,229,252,250,250,255,255,255,202,129, + 167,255,255,251,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,227,238,226,82,83,67, + 234,249,236,211,141,177,245,231,238,254,255,255,238,232,228,254,252,251,254,252, + 251,238,232,229,252,249,249,255,255,255,206,138,173,219,170,194,229,194,209,227, + 188,206,227,189,207,227,189,207,227,189,207,227,189,207,227,189,207,227,189,207, + 227,188,206,228,190,209,206,166,183,171,129,144,205,165,182,203,126,167,248,240, + 244,253,253,253,238,232,228,254,252,251,254,252,251,238,233,229,252,250,251,255, + 255,255,245,230,238,214,158,188,214,158,188,214,158,188,214,158,188,214,158,188, + 214,158,188,214,158,188,214,158,188,214,158,188,214,158,188,214,157,187,219,162, + 193,227,172,202,217,157,189,235,208,222,255,255,255,252,250,250,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,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,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,255,255,255,255,255,255,254,253,254,254,253,254,254,253,254,254,253, + 254,254,253,254,254,253,254,254,253,254,254,253,254,254,253,254,254,253,254,254, + 253,254,254,253,254,254,253,254,254,253,254,255,255,255,255,255,255,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset23 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 255,253,252,253,251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249, + 246,244,249,246,244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252, + 253,251,250,253,251,250,253,251,249,254,253,252,246,242,240,237,231,227,239,234, + 230,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,230,237,231,227,246,242,240,254,253,252,253,251,249,255,253, + 252,246,242,240,238,232,229,252,251,250,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,252,251, + 250,238,232,229,246,242,240,255,253,252,253,251,250,237,231,227,253,252,252,255, + 255,255,255,255,255,255,255,255,255,255,255,254,253,254,254,252,253,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,254,253,254,255,255, + 255,254,254,253,255,254,254,255,255,255,255,255,255,253,252,252,237,231,227,253, + 251,250,249,246,244,239,234,231,255,255,255,255,255,255,255,255,255,255,255,255, + 254,253,253,255,255,255,255,255,255,252,248,249,237,217,224,226,195,206,227,197, + 208,240,223,229,255,255,255,255,255,255,253,251,250,253,251,250,253,251,250,254, + 254,254,255,255,255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 255,255,255,255,255,255,255,255,255,254,253,254,255,255,255,243,231,235,201,142, + 163,173,85,117,167,73,107,171,79,112,171,80,112,168,74,108,172,83,115,223, + 189,200,255,254,254,251,247,247,252,250,249,254,252,252,255,255,255,255,255,255, + 239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,255,255,255,254,253, + 253,255,255,255,221,185,198,168,73,107,181,100,129,209,159,177,244,229,235,250, + 240,245,250,240,244,237,215,223,207,154,175,202,145,166,253,250,250,255,255,255, + 255,254,253,254,252,252,255,255,255,255,255,255,239,234,231,249,246,244,249,246, + 244,239,234,231,255,255,255,254,253,253,255,255,255,220,181,195,160,57,94,212, + 162,181,198,135,157,175,89,120,225,190,203,255,255,255,255,250,253,255,255,255, + 255,248,245,248,234,236,245,233,239,234,211,217,246,235,238,255,255,255,255,254, + 254,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,255, + 254,254,241,227,232,163,64,99,222,183,197,237,214,223,159,57,94,164,65,101, + 178,94,125,254,248,250,254,252,253,238,203,197,197,90,62,204,109,83,248,229, + 227,201,142,166,174,86,118,251,247,248,255,254,254,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,255,254,255,255,255,255,195,130,154,186,109,137, + 255,255,255,248,237,242,189,116,142,167,71,105,218,176,192,255,252,253,255,255, + 255,214,136,116,192,77,45,190,71,38,228,172,157,255,254,255,171,79,111,213, + 168,184,255,255,255,255,254,255,239,234,231,249,246,244,249,246,244,239,233,230, + 255,255,255,249,242,245,169,76,109,225,189,202,254,254,254,255,250,253,253,245, + 249,244,227,234,255,255,255,254,248,250,255,253,254,241,211,205,201,99,72,205, + 114,88,245,225,223,254,255,253,207,151,171,179,97,126,255,255,255,255,255,255, + 239,234,231,249,246,244,249,246,244,238,232,229,255,255,255,233,211,218,168,74, + 108,244,227,233,255,254,255,254,247,250,255,250,253,255,254,255,254,248,251,255, + 249,252,255,248,252,255,255,255,252,240,242,255,249,255,255,255,255,255,255,255, + 228,196,208,169,77,110,247,240,242,255,255,255,239,233,230,249,246,244,249,246, + 244,238,232,229,255,255,255,231,205,214,169,77,110,248,234,240,255,254,255,252, + 246,251,252,246,251,252,246,250,255,249,252,255,249,252,255,249,252,254,248,250, + 253,252,253,164,191,135,122,161,79,229,238,220,239,210,224,167,75,107,245,235, + 238,255,255,255,239,233,230,249,246,244,249,246,244,239,232,229,255,255,255,239, + 223,228,167,72,106,238,214,223,254,254,254,255,255,253,255,255,255,255,255,255, + 255,249,252,254,249,252,248,246,248,252,254,255,198,212,179,73,131,16,75,130, + 18,130,176,92,228,186,205,170,80,112,251,246,248,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,255,255,255,254,253,253,176,90,121,209,158,178, + 255,255,255,199,193,233,105,104,208,193,189,234,255,254,254,255,248,252,255,255, + 254,255,255,255,223,229,212,95,145,44,72,128,14,170,204,145,201,128,158,188, + 119,143,255,255,255,255,254,255,239,234,231,249,246,244,249,246,244,239,234,231, + 255,254,255,255,255,255,215,173,189,171,77,109,234,225,239,73,76,203,48,46, + 188,62,62,195,237,230,247,245,248,251,123,192,223,160,208,230,255,255,255,222, + 225,210,201,222,185,239,215,225,165,66,102,233,209,217,255,255,255,255,254,255, + 239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,254,253,253,252,250, + 251,183,104,132,179,99,130,101,100,207,47,53,199,88,89,203,248,240,249,110, + 186,218,5,139,194,11,142,196,177,216,234,255,255,255,253,236,249,170,77,110, + 198,136,158,255,255,255,254,253,253,255,255,255,239,234,231,249,246,244,249,246, + 244,239,234,231,255,255,255,254,253,253,255,255,255,243,232,237,181,94,121,160, + 75,116,148,123,191,233,231,248,255,255,255,122,202,232,14,156,208,23,160,210, + 185,220,237,228,188,199,163,71,104,187,113,139,252,248,250,254,253,254,254,254, + 254,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,255, + 255,255,254,254,254,255,255,255,249,243,246,200,136,156,180,83,108,181,97,124, + 202,143,165,207,166,184,100,120,161,119,105,144,182,88,118,168,73,107,207,155, + 174,255,255,255,255,255,255,255,254,255,255,255,255,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,255,255,255,255,255,255,255,255,255,254,254,254, + 255,255,255,255,255,255,237,220,228,206,154,173,185,111,138,178,92,122,194,100, + 127,201,122,145,212,167,184,245,235,238,255,255,255,255,255,255,255,254,254,255, + 255,255,255,255,255,255,255,255,239,234,231,249,246,244,253,251,250,237,231,227, + 253,252,252,255,255,255,255,255,255,255,255,255,254,254,254,254,253,253,255,255, + 255,255,255,255,255,255,255,255,255,255,252,255,255,255,255,255,255,255,255,255, + 255,255,254,252,253,255,254,254,255,255,255,255,255,255,255,255,255,253,252,252, + 237,231,227,253,251,250,255,253,252,246,242,240,238,232,229,252,251,250,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,254,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,254,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,252,251,250,238,232,229,246,242,240,255,253,252,253,251, + 249,254,253,252,246,242,240,237,231,227,239,234,230,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,230,237,231, + 227,246,242,240,254,253,252,253,251,249,253,251,250,253,251,250,255,253,252,253, + 251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244, + 249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252,253,251,250,253, + 251,250 + ); + CEditorAsset24 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,255, + 255,255,255,255,255,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254, + 255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254, + 254,255,254,254,255,254,254,255,255,254,255,255,255,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,254,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,250,249,255,255,255,237,222,212,186,125,87,186,125,87,185,125,87,185,125, + 86,185,125,86,185,125,86,187,128,91,190,134,98,185,125,86,185,125,86,185, + 125,86,185,125,86,186,126,88,182,119,79,222,193,175,255,255,255,252,251,249, + 238,233,229,254,252,251,254,252,251,238,232,228,253,253,252,252,249,247,177,108, + 65,194,141,108,208,168,142,207,166,140,208,167,141,207,166,140,208,167,141,195, + 142,109,174,104,60,208,167,141,207,166,140,208,167,141,208,166,140,208,167,141, + 205,161,134,169,94,46,237,222,213,254,254,254,237,231,227,254,252,251,254,252, + 251,238,232,228,254,254,254,251,247,245,171,97,51,238,223,214,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,234,216,204,190,134,99,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,172,100,54,231,210, + 197,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228,254,254,254,251, + 247,245,172,100,54,231,210,196,254,252,251,253,250,249,254,252,251,253,250,249, + 254,252,251,228,204,189,188,129,92,254,252,251,253,251,249,254,252,251,254,251, + 250,254,252,251,249,243,241,172,99,53,232,212,201,255,255,255,237,231,227,254, + 252,251,254,252,251,238,232,228,254,254,254,251,247,245,172,99,53,231,211,198, + 254,254,253,253,252,251,254,254,253,253,252,251,254,254,253,228,205,190,188,130, + 93,254,254,253,253,253,251,254,254,253,254,253,252,254,254,253,249,245,242,172, + 99,53,232,212,200,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228, + 254,254,254,251,247,245,172,99,53,235,218,207,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,232,212,199,189,132,95,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,254,254,255,172,100,54,232,212,200,255,255,255, + 237,231,227,254,252,251,254,252,251,238,232,228,254,254,254,250,246,243,174,105, + 60,182,118,78,188,130,93,188,129,92,188,130,93,188,129,92,188,130,93,182, + 119,79,174,103,58,188,130,93,188,129,92,188,130,93,188,129,92,188,130,93, + 188,128,92,167,91,43,234,214,202,255,255,255,237,231,227,254,252,251,254,252, + 251,238,232,228,254,254,254,251,247,244,173,101,56,212,175,151,229,206,191,228, + 204,190,229,206,191,228,204,190,229,206,191,211,172,147,182,119,79,229,206,191, + 228,205,190,229,206,191,229,205,190,229,206,191,225,200,184,170,96,49,233,213, + 201,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228,254,254,254,251, + 247,245,172,99,52,236,220,209,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,233,213,200,189,132,96,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,172,100,54,232,212,200,255,255,255,237,231,227,254, + 252,251,254,252,251,238,232,228,254,254,254,251,247,245,172,99,53,231,211,197, + 254,253,252,253,251,250,254,253,252,253,251,250,254,253,252,228,205,189,188,130, + 92,254,253,252,253,252,250,254,253,252,254,252,251,254,253,252,249,244,242,172, + 99,53,232,212,200,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228, + 254,254,254,251,247,245,173,100,55,231,211,197,254,254,253,253,252,251,254,254, + 253,253,252,251,254,254,253,228,205,190,188,130,93,254,254,253,253,253,251,254, + 254,253,254,253,252,254,254,253,249,244,242,172,100,54,232,213,201,255,255,255, + 237,231,227,254,252,251,254,252,251,238,232,228,254,254,255,251,246,244,169,94, + 47,237,221,210,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,233, + 214,201,190,134,99,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,171,97,50,230,209,196,255,255,255,237,231,227,254,252,251,254,252, + 251,238,232,229,252,252,251,253,251,250,188,130,93,177,108,65,186,126,88,185, + 124,86,185,125,86,185,124,86,185,125,86,179,112,70,168,93,45,185,125,86, + 185,125,86,185,125,86,185,125,86,186,126,87,182,119,79,175,106,62,243,232, + 225,254,253,253,238,232,228,254,252,251,254,252,251,238,233,229,252,251,250,255, + 255,255,249,244,241,209,169,143,208,167,141,208,167,141,208,167,141,208,167,141, + 208,167,141,209,170,144,212,174,150,208,167,141,208,167,141,208,167,141,208,167, + 141,208,168,142,205,162,135,238,224,215,255,255,255,252,250,249,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,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,254,254,254,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,255,255,255,255,255,255,254,253,252,254,253,253,254,253,252,254,253, + 252,254,253,252,254,253,252,254,253,252,254,253,252,254,253,252,254,253,252,254, + 253,252,254,253,252,254,253,253,254,253,252,255,255,255,255,255,255,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset25 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,255, + 255,255,255,255,255,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254, + 255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254, + 254,255,254,254,255,254,254,255,255,254,255,255,255,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,254,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,250,249,255,255,255,237,222,212,186,125,87,186,125,87,185,125,87,185,125, + 86,185,125,86,185,125,86,187,128,91,190,134,98,185,125,86,185,125,86,185, + 125,86,185,125,86,186,126,88,182,119,79,222,193,175,255,255,255,252,251,249, + 238,233,229,254,252,251,254,252,251,238,232,228,253,253,252,252,249,247,177,108, + 65,194,141,108,208,168,142,207,166,140,208,167,141,207,166,140,208,167,141,195, + 142,109,174,104,60,208,167,141,207,166,140,208,167,141,208,166,140,208,167,141, + 205,161,134,169,94,46,237,222,213,254,254,254,237,231,227,254,252,251,254,252, + 251,238,232,228,254,254,254,251,247,245,171,97,51,238,223,214,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,234,216,204,190,134,99,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,172,100,54,231,210, + 197,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228,254,254,254,251, + 247,245,172,100,54,231,210,196,254,252,251,253,250,249,254,252,251,253,250,249, + 254,252,251,228,204,189,188,129,92,254,252,251,253,251,249,254,252,251,254,251, + 250,254,252,251,249,243,241,172,99,53,232,212,201,255,255,255,237,231,227,254, + 252,251,254,252,251,238,232,228,254,254,254,251,247,245,172,99,53,231,211,198, + 254,254,253,253,252,251,254,254,253,253,252,251,254,254,253,228,205,190,188,130, + 93,254,254,253,253,253,251,254,254,253,254,253,252,254,254,253,249,245,242,172, + 99,53,232,212,200,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228, + 254,254,254,251,247,245,172,99,53,235,218,207,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,232,212,199,189,132,95,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,254,254,255,172,100,54,232,212,200,255,255,255, + 237,231,227,254,252,251,254,252,251,238,232,228,254,254,254,250,246,243,174,105, + 60,182,118,78,188,130,93,188,129,92,188,130,93,188,129,92,188,130,93,182, + 119,79,174,103,58,188,130,93,188,129,92,188,130,93,188,129,92,188,130,93, + 188,128,92,167,91,43,234,214,202,255,255,255,237,231,227,254,252,251,254,252, + 251,238,232,228,254,254,254,251,247,244,173,101,56,212,175,151,229,206,191,228, + 204,190,229,206,191,228,204,190,229,206,191,211,172,147,182,119,79,229,206,191, + 228,205,190,229,206,191,229,205,190,229,206,191,225,200,184,170,96,49,233,213, + 201,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228,254,254,254,251, + 247,245,172,99,52,236,220,209,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,233,213,200,189,132,96,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,172,100,54,232,212,200,255,255,255,237,231,227,254, + 252,251,254,252,251,238,232,228,254,254,254,251,247,245,172,99,53,231,211,197, + 254,253,252,253,251,250,254,253,252,253,251,250,254,253,252,228,205,189,188,130, + 92,254,253,252,253,252,250,254,253,252,254,252,251,254,253,252,249,244,242,172, + 99,53,232,212,200,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228, + 254,254,254,251,247,245,173,100,55,231,211,197,254,254,253,253,252,251,254,254, + 253,253,252,251,254,254,253,228,205,190,188,130,93,254,254,253,253,253,251,254, + 254,253,254,253,252,254,254,253,249,244,242,172,100,54,232,213,201,255,255,255, + 237,231,227,254,252,251,254,252,251,238,232,228,254,254,255,251,246,244,169,94, + 47,237,221,210,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,233, + 214,201,190,134,99,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,171,97,50,230,209,196,255,255,255,237,231,227,254,252,251,254,252, + 251,238,232,229,252,252,251,253,251,250,188,130,93,177,108,65,186,126,88,185, + 124,86,185,125,86,185,124,86,185,125,86,179,112,70,168,93,45,185,125,86, + 185,125,86,185,125,86,185,125,86,186,126,87,182,119,79,175,106,62,243,232, + 225,254,253,253,238,232,228,254,252,251,254,252,251,238,233,229,252,251,250,255, + 255,255,249,244,241,209,169,143,208,167,141,208,167,141,208,167,141,208,167,141, + 208,167,141,209,170,144,212,174,150,208,167,141,208,167,141,208,167,141,208,167, + 141,208,168,142,205,162,135,238,224,215,255,255,255,252,250,249,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,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,254,254,254,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,255,255,255,255,255,255,254,253,252,254,253,253,254,253,252,254,253, + 252,254,253,252,254,253,252,254,253,252,254,253,252,254,253,252,254,253,252,254, + 253,252,254,253,252,254,253,253,254,253,252,255,255,255,255,255,255,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset26 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,255, + 255,255,255,255,255,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254, + 255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254, + 254,255,254,254,255,254,254,255,255,254,255,255,255,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,254,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,250,249,255,255,255,237,222,212,186,125,87,186,125,87,185,125,87,185,125, + 86,185,125,86,185,125,86,187,128,91,190,134,98,185,125,86,185,125,86,185, + 125,86,185,125,86,186,126,88,182,119,79,222,193,175,255,255,255,252,251,249, + 238,233,229,254,252,251,254,252,251,238,232,228,253,253,252,252,249,247,177,108, + 65,194,141,108,208,168,142,207,166,140,208,167,141,207,166,140,208,167,141,195, + 142,109,174,104,60,208,167,141,207,166,140,208,167,141,208,166,140,208,167,141, + 205,161,134,169,94,46,237,222,213,254,254,254,237,231,227,254,252,251,254,252, + 251,238,232,228,254,254,254,251,247,245,171,97,51,238,223,214,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,234,216,204,190,134,99,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,172,100,54,231,210, + 197,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228,254,254,254,251, + 247,245,172,100,54,231,210,196,254,252,251,253,250,249,254,252,251,253,250,249, + 254,252,251,228,204,189,188,129,92,254,252,251,253,251,249,254,252,251,254,251, + 250,254,252,251,249,243,241,172,99,53,232,212,201,255,255,255,237,231,227,254, + 252,251,254,252,251,238,232,228,254,254,254,251,247,245,172,99,53,231,211,198, + 254,254,253,253,252,251,254,254,253,253,252,251,254,254,253,228,205,190,188,130, + 93,254,254,253,253,253,251,254,254,253,254,253,252,254,254,253,249,245,242,172, + 99,53,232,212,200,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228, + 254,254,254,251,247,245,172,99,53,235,218,207,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,232,212,199,189,132,95,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,254,254,255,172,100,54,232,212,200,255,255,255, + 237,231,227,254,252,251,254,252,251,238,232,228,254,254,254,250,246,243,174,105, + 60,182,118,78,188,130,93,188,129,92,188,130,93,188,129,92,188,130,93,182, + 119,79,174,103,58,188,130,93,188,129,92,188,130,93,188,129,92,188,130,93, + 188,128,92,167,91,43,234,214,202,255,255,255,237,231,227,254,252,251,254,252, + 251,238,232,228,254,254,254,251,247,244,173,101,56,212,175,151,229,206,191,228, + 204,190,229,206,191,228,204,190,229,206,191,211,172,147,182,119,79,229,206,191, + 228,205,190,229,206,191,229,205,190,229,206,191,225,200,184,170,96,49,233,213, + 201,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228,254,254,254,251, + 247,245,172,99,52,236,220,209,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,233,213,200,189,132,96,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,172,100,54,232,212,200,255,255,255,237,231,227,254, + 252,251,254,252,251,238,232,228,254,254,254,251,247,245,172,99,53,231,211,197, + 254,253,252,253,251,250,254,253,252,253,251,250,254,253,252,228,205,189,188,130, + 92,254,253,252,253,252,250,254,253,252,254,252,251,254,253,252,249,244,242,172, + 99,53,232,212,200,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228, + 254,254,254,251,247,245,173,100,55,231,211,197,254,254,253,253,252,251,254,254, + 253,253,252,251,254,254,253,228,205,190,188,130,93,254,254,253,253,253,251,254, + 254,253,254,253,252,254,254,253,249,244,242,172,100,54,232,213,201,255,255,255, + 237,231,227,254,252,251,254,252,251,238,232,228,254,254,255,251,246,244,169,94, + 47,237,221,210,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,233, + 214,201,190,134,99,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,171,97,50,230,209,196,255,255,255,237,231,227,254,252,251,254,252, + 251,238,232,229,252,252,251,253,251,250,188,130,93,177,108,65,186,126,88,185, + 124,86,185,125,86,185,124,86,185,125,86,179,112,70,168,93,45,185,125,86, + 185,125,86,185,125,86,185,125,86,186,126,87,182,119,79,175,106,62,243,232, + 225,254,253,253,238,232,228,254,252,251,254,252,251,238,233,229,252,251,250,255, + 255,255,249,244,241,209,169,143,208,167,141,208,167,141,208,167,141,208,167,141, + 208,167,141,209,170,144,212,174,150,208,167,141,208,167,141,208,167,141,208,167, + 141,208,168,142,205,162,135,238,224,215,255,255,255,252,250,249,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,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,254,254,254,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,255,255,255,255,255,255,254,253,252,254,253,253,254,253,252,254,253, + 252,254,253,252,254,253,252,254,253,252,254,253,252,254,253,252,254,253,252,254, + 253,252,254,253,252,254,253,253,254,253,252,255,255,255,255,255,255,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset27 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,255, + 255,255,255,255,255,255,255,254,254,253,252,254,253,253,254,253,252,254,253,252, + 254,253,252,254,253,252,254,253,252,254,253,252,254,253,252,254,253,252,254,253, + 253,254,253,252,255,254,254,255,255,255,255,255,255,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,255,255,255,254,254,254,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,254, + 254,253,255,255,255,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,251,252,255,254,254,255,255,255,243,233,226,211,173,149,211,173,149,211,173, + 149,211,173,148,211,173,148,211,173,148,211,173,148,211,173,148,211,173,148,211, + 173,149,211,174,149,209,169,144,233,214,202,255,255,255,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,251,250,249,255,255,254,241,230, + 222,174,103,57,166,87,38,169,95,48,169,94,47,169,94,47,169,94,47,169, + 94,47,169,94,47,169,94,47,169,94,47,169,94,47,169,95,47,168,93,46, + 165,86,36,226,201,185,255,255,255,251,250,248,238,233,229,254,252,251,254,252, + 251,238,233,229,251,249,247,255,255,255,211,174,149,166,88,39,245,235,229,251, + 247,245,251,246,244,251,247,245,251,247,245,251,247,245,251,247,245,251,247,245, + 251,247,245,251,247,245,250,247,244,251,247,244,182,119,79,187,127,90,255,255, + 255,251,250,249,238,232,229,254,252,251,254,252,251,238,233,229,251,249,247,255, + 255,255,211,173,148,170,96,49,253,251,250,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,188,130,94,187,128,91,255,255,255,251,250,249,238,232,229,254, + 252,251,254,252,251,238,233,229,251,249,247,255,255,255,211,173,148,169,94,47, + 251,246,244,253,253,252,252,251,251,252,252,252,252,252,252,252,252,252,252,252, + 252,252,252,252,253,253,252,255,254,254,254,253,252,255,254,254,187,128,90,187, + 128,91,255,255,255,251,250,249,238,232,229,254,252,251,254,252,251,238,233,229, + 251,249,247,255,255,255,211,173,148,169,94,47,251,247,244,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,254,254,253,255,255,255,187,128,91,187,128,91,255,255,255,251,250,249, + 238,232,229,254,252,251,254,252,251,238,233,229,251,249,247,255,255,255,211,173, + 148,168,93,46,252,249,247,218,216,214,202,197,195,206,202,200,205,201,199,205, + 201,199,206,202,200,202,198,196,218,215,213,255,255,255,253,253,252,255,255,255, + 187,128,91,187,128,91,255,255,255,251,250,249,238,232,229,254,252,251,254,252, + 251,238,233,229,251,249,247,255,255,255,211,173,148,167,92,45,255,255,254,121, + 112,107,63,49,40,75,62,54,73,60,52,73,60,52,75,61,54,64,49,41, + 120,110,104,253,253,252,250,250,249,255,255,255,187,128,91,187,128,91,255,255, + 255,251,250,249,238,232,229,254,252,251,254,252,251,238,233,229,251,249,247,255, + 255,255,211,173,148,169,94,47,251,247,245,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,187,128,91,187,128,91,255,255,255,251,250,249,238,232,229,254, + 252,251,254,252,251,238,233,229,251,249,247,255,255,255,211,174,149,168,93,46, + 251,247,245,219,216,214,205,199,196,208,203,201,207,203,200,207,203,200,207,203, + 200,207,203,200,207,202,199,203,198,195,206,202,198,252,252,252,187,128,91,187, + 128,92,255,255,255,251,250,249,238,232,229,254,252,251,254,252,251,238,233,229, + 251,249,247,255,255,255,210,171,146,168,94,48,255,255,255,127,122,120,70,59, + 52,81,72,66,79,70,64,79,70,64,79,70,64,79,70,64,81,71,66,77, + 68,61,91,81,76,253,255,255,192,136,99,185,125,88,255,255,255,251,250,249, + 238,232,229,254,252,251,254,252,251,238,233,229,251,249,247,255,255,255,216,182, + 161,163,82,31,228,204,189,227,208,196,223,203,191,224,205,193,224,205,193,224, + 205,193,224,205,193,224,205,193,224,205,193,224,204,192,224,205,192,233,215,203, + 175,106,62,192,137,102,255,255,255,251,250,248,238,232,229,254,252,251,254,252, + 251,238,233,229,252,251,250,255,254,254,249,244,241,189,130,93,160,77,25,165, + 85,34,166,85,34,166,85,34,166,85,34,166,85,34,166,85,34,166,85,34, + 166,85,34,166,85,34,166,86,35,161,79,28,175,104,60,238,224,215,255,255, + 255,251,250,249,238,233,229,254,252,251,254,252,251,238,233,229,252,251,252,255, + 255,255,255,255,255,254,253,253,234,216,205,233,215,203,233,215,203,233,215,203, + 233,215,203,233,215,203,233,215,203,233,215,203,233,215,203,233,215,203,234,215, + 204,233,213,201,249,243,240,255,255,255,255,255,255,252,251,252,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,255,255,255,254,254,254,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,254, + 254,253,255,255,255,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,255,255,255,255,255,255,255,255,255,255,254,254,255,254,254,255,254, + 254,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255, + 254,254,255,254,254,255,254,253,255,255,255,255,255,255,255,255,255,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset28 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,255, + 255,255,255,255,255,255,255,254,254,253,252,254,253,253,254,253,252,254,253,252, + 254,253,252,254,253,252,254,253,252,254,253,252,254,253,252,254,253,252,254,253, + 253,254,253,252,255,254,254,255,255,255,255,255,255,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,255,255,255,254,254,254,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,254, + 254,253,255,255,255,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,251,252,255,254,254,255,255,255,243,233,226,211,173,149,211,173,149,211,173, + 149,211,173,148,211,173,148,211,173,148,211,173,148,211,173,148,211,173,148,211, + 173,149,211,174,149,209,169,144,233,214,202,255,255,255,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,251,250,249,255,255,254,241,230, + 222,174,103,57,166,87,38,169,95,48,169,94,47,169,94,47,169,94,47,169, + 94,47,169,94,47,169,94,47,169,94,47,169,94,47,169,95,47,168,93,46, + 165,86,36,226,201,185,255,255,255,251,250,248,238,233,229,254,252,251,254,252, + 251,238,233,229,251,249,247,255,255,255,211,174,149,166,88,39,245,235,229,251, + 247,245,251,246,244,251,247,245,251,247,245,251,247,245,251,247,245,251,247,245, + 251,247,245,251,247,245,250,247,244,251,247,244,182,119,79,187,127,90,255,255, + 255,251,250,249,238,232,229,254,252,251,254,252,251,238,233,229,251,249,247,255, + 255,255,211,173,148,170,96,49,253,251,250,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,188,130,94,187,128,91,255,255,255,251,250,249,238,232,229,254, + 252,251,254,252,251,238,233,229,251,249,247,255,255,255,211,173,148,169,94,47, + 251,246,244,253,253,252,252,251,251,252,252,252,252,252,252,252,252,252,252,252, + 252,252,252,252,253,253,252,255,254,254,254,253,252,255,254,254,187,128,90,187, + 128,91,255,255,255,251,250,249,238,232,229,254,252,251,254,252,251,238,233,229, + 251,249,247,255,255,255,211,173,148,169,94,47,251,247,244,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,254,254,253,255,255,255,187,128,91,187,128,91,255,255,255,251,250,249, + 238,232,229,254,252,251,254,252,251,238,233,229,251,249,247,255,255,255,211,173, + 148,168,93,46,252,249,247,218,216,214,202,197,195,206,202,200,205,201,199,205, + 201,199,206,202,200,202,198,196,218,215,213,255,255,255,253,253,252,255,255,255, + 187,128,91,187,128,91,255,255,255,251,250,249,238,232,229,254,252,251,254,252, + 251,238,233,229,251,249,247,255,255,255,211,173,148,167,92,45,255,255,254,121, + 112,107,63,49,40,75,62,54,73,60,52,73,60,52,75,61,54,64,49,41, + 120,110,104,253,253,252,250,250,249,255,255,255,187,128,91,187,128,91,255,255, + 255,251,250,249,238,232,229,254,252,251,254,252,251,238,233,229,251,249,247,255, + 255,255,211,173,148,169,94,47,251,247,245,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,187,128,91,187,128,91,255,255,255,251,250,249,238,232,229,254, + 252,251,254,252,251,238,233,229,251,249,247,255,255,255,211,174,149,168,93,46, + 251,247,245,219,216,214,205,199,196,208,203,201,207,203,200,207,203,200,207,203, + 200,207,203,200,207,202,199,203,198,195,206,202,198,252,252,252,187,128,91,187, + 128,92,255,255,255,251,250,249,238,232,229,254,252,251,254,252,251,238,233,229, + 251,249,247,255,255,255,210,171,146,168,94,48,255,255,255,127,122,120,70,59, + 52,81,72,66,79,70,64,79,70,64,79,70,64,79,70,64,81,71,66,77, + 68,61,91,81,76,253,255,255,192,136,99,185,125,88,255,255,255,251,250,249, + 238,232,229,254,252,251,254,252,251,238,233,229,251,249,247,255,255,255,216,182, + 161,163,82,31,228,204,189,227,208,196,223,203,191,224,205,193,224,205,193,224, + 205,193,224,205,193,224,205,193,224,205,193,224,204,192,224,205,192,233,215,203, + 175,106,62,192,137,102,255,255,255,251,250,248,238,232,229,254,252,251,254,252, + 251,238,233,229,252,251,250,255,254,254,249,244,241,189,130,93,160,77,25,165, + 85,34,166,85,34,166,85,34,166,85,34,166,85,34,166,85,34,166,85,34, + 166,85,34,166,85,34,166,86,35,161,79,28,175,104,60,238,224,215,255,255, + 255,251,250,249,238,233,229,254,252,251,254,252,251,238,233,229,252,251,252,255, + 255,255,255,255,255,254,253,253,234,216,205,233,215,203,233,215,203,233,215,203, + 233,215,203,233,215,203,233,215,203,233,215,203,233,215,203,233,215,203,234,215, + 204,233,213,201,249,243,240,255,255,255,255,255,255,252,251,252,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,255,255,255,254,254,254,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,254, + 254,253,255,255,255,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,255,255,255,255,255,255,255,255,255,255,254,254,255,254,254,255,254, + 254,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255, + 254,254,255,254,254,255,254,253,255,255,255,255,255,255,255,255,255,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset29 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,255, + 255,255,255,255,255,255,255,255,255,255,255,252,253,255,252,252,255,252,252,255, + 252,252,255,252,252,255,252,252,255,252,252,255,252,252,255,252,252,255,252,252, + 255,254,254,255,255,255,255,255,255,255,255,255,255,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,254,254,254,255, + 255,255,255,255,255,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,251,251,255,255,255,254,254,255,255,255,255,245,245,251,159,159,219,143,143, + 213,146,146,214,145,145,214,145,145,214,145,145,214,145,145,214,145,145,214,145, + 145,214,146,146,214,227,227,244,255,255,255,254,254,255,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255,255,255,254,253, + 254,247,247,252,96,96,195,61,61,181,93,93,193,91,90,191,91,91,192,91, + 91,192,91,91,192,91,91,192,91,90,191,93,93,193,77,76,187,63,63,183, + 224,224,243,254,254,255,254,254,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,253,253,255,255,255,255,204,204,236,49,49,177,236, + 233,242,255,255,253,255,255,251,255,255,251,255,255,251,255,255,251,255,255,251, + 255,255,251,255,255,251,255,255,252,76,76,187,145,145,214,254,254,255,252,252, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,253, + 253,255,255,255,255,200,200,235,63,63,182,243,240,244,253,250,247,249,246,246, + 250,247,246,250,247,246,250,247,246,250,247,246,250,247,246,248,245,245,255,255, + 251,97,97,194,153,153,217,255,255,255,252,252,255,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,253,253,255,255,255,255,201,201,235, + 60,60,181,240,237,243,255,252,248,251,248,247,252,249,247,252,249,247,252,249, + 247,252,249,247,252,249,247,251,248,247,254,253,250,80,80,188,99,99,197,244, + 244,251,254,254,255,251,250,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,253,253,255,255,255,255,201,201,235,60,60,181,241,238,243,255,252, + 248,251,248,247,252,249,247,252,249,247,252,249,247,252,249,247,250,247,246,255, + 255,251,152,151,213,71,71,186,79,79,189,107,107,199,253,253,254,251,251,251, + 238,232,229,254,252,251,254,252,251,238,233,229,252,251,251,253,253,255,255,255, + 255,201,201,235,60,60,181,241,238,243,255,252,248,251,248,247,252,249,247,252, + 249,247,252,249,247,252,249,247,250,247,246,255,255,251,82,81,189,139,139,212, + 200,200,234,46,46,176,245,245,252,255,255,252,238,232,229,254,252,251,254,252, + 251,238,233,229,252,251,251,253,253,255,255,255,255,201,201,235,60,60,181,241, + 238,243,255,252,248,251,248,247,252,249,247,252,249,247,252,249,247,252,249,247, + 250,247,246,255,254,251,186,185,225,57,57,180,52,52,178,145,145,213,255,255, + 255,250,250,250,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,253, + 253,255,255,255,255,201,201,235,60,60,181,241,238,243,255,252,248,251,248,247, + 252,249,247,252,249,247,252,249,247,252,249,247,252,249,247,250,247,246,255,255, + 253,91,91,192,127,127,207,255,255,255,253,253,255,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,253,253,255,255,255,255,201,201,235, + 61,61,182,239,236,242,252,249,247,248,245,246,249,246,246,249,246,246,249,246, + 246,249,246,246,249,246,246,246,244,245,251,251,250,92,92,192,150,150,216,254, + 254,255,252,252,255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,253,253,255,255,255,255,199,199,234,55,55,179,252,249,247,255,255, + 254,255,255,253,255,255,252,255,255,252,255,255,253,255,255,252,255,255,253,255, + 255,252,255,255,255,89,89,191,140,140,212,255,255,255,252,252,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,254,254,255,254,254, + 255,237,237,248,66,66,184,103,102,195,146,146,212,142,141,209,149,148,212,153, + 151,213,144,143,210,154,153,214,146,144,210,145,144,211,128,127,205,48,48,177, + 201,201,235,255,255,255,253,253,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,255,255,255,254,253,254,255,255,255,217,217,241,102, + 103,198,90,90,193,93,93,194,65,65,184,49,49,178,86,87,192,41,41,175, + 79,79,189,93,93,194,90,90,193,187,187,230,255,255,255,253,253,255,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255, + 255,255,255,255,255,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255, + 153,153,216,84,84,190,239,239,249,50,50,178,214,214,239,255,255,255,255,255, + 255,255,255,255,254,254,255,255,255,255,255,255,255,252,251,251,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,255,255,255,255,255,255,255,255,255, + 253,253,254,252,252,254,252,252,254,252,252,254,222,222,242,73,73,186,44,44, + 175,104,104,198,245,245,251,252,252,254,252,252,254,253,252,254,255,255,255,255, + 255,255,255,255,255,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,239,239,250,200,200,235,253,253,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,252,251,251,250,251,255, + 255,252,255,255,255,253,252,251,252,251,251,252,252,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,237,232,229,236,230,228,238,232,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset30 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,255,255,255,255,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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, + 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,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,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,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, + 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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset31 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,255,255,255,255,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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, + 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,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,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,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, + 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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset32 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,255, + 255,255,255,255,255,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254, + 255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254, + 254,255,254,254,255,254,254,255,254,255,255,255,255,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,254,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,250,250,255,255,255,249,216,218,234,104,112,234,104,111,234,104,111,234,104, + 111,234,104,111,234,104,111,234,108,115,235,114,121,234,104,111,234,104,111,234, + 104,111,234,104,111,234,105,113,233,97,105,245,183,187,255,255,255,252,250,250, + 238,233,229,254,252,251,254,252,251,238,232,228,253,253,252,254,248,248,231,85, + 92,237,122,129,241,154,159,241,152,156,241,153,158,241,152,157,241,153,158,237, + 124,130,230,80,88,241,153,158,241,152,157,241,153,158,241,152,157,241,153,158, + 240,146,151,228,67,76,250,216,219,254,254,254,238,231,227,254,252,251,254,252, + 251,238,232,228,253,255,254,254,246,246,229,72,80,250,217,220,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,249,210,211,235,114,121,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,229,75,83,249,203, + 206,254,255,255,238,230,227,254,252,251,254,252,251,238,232,228,253,255,254,254, + 246,246,229,75,83,248,201,205,255,252,252,255,250,250,255,252,252,255,250,250, + 255,252,252,247,196,198,234,108,115,255,252,252,255,250,250,255,252,252,255,251, + 251,255,252,252,254,242,242,229,74,82,249,206,209,254,255,255,238,230,227,254, + 252,251,254,252,251,238,232,228,253,255,254,254,246,246,229,74,82,248,203,206, + 255,253,253,255,251,251,255,253,253,255,251,251,255,253,253,247,197,199,234,109, + 116,255,253,253,255,251,251,255,253,253,255,252,252,255,253,253,254,243,244,229, + 74,82,249,205,208,254,255,255,238,230,227,254,252,251,254,252,251,238,232,228, + 253,255,254,254,246,246,229,74,82,249,211,214,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,248,205,207,234,111,118,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,254,254,229,75,83,249,205,208,254,255,255, + 238,230,227,254,252,251,254,252,251,238,232,228,253,255,254,254,244,245,231,80, + 88,233,96,104,234,110,117,234,109,116,234,109,116,234,109,116,234,109,116,233, + 97,105,230,78,87,234,109,116,234,109,116,234,109,116,234,109,116,234,109,116, + 234,109,116,228,65,73,249,207,210,254,255,255,238,230,227,254,252,251,254,252, + 251,238,232,228,253,255,254,254,245,246,230,76,84,242,161,166,247,198,201,247, + 196,199,247,198,200,247,196,199,247,198,200,241,158,162,232,97,105,247,198,200, + 247,196,199,247,198,200,247,197,200,247,198,200,246,191,194,229,70,79,249,206, + 209,254,255,255,238,230,227,254,252,251,254,252,251,238,232,228,253,255,254,254, + 246,246,229,73,81,249,213,216,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,248,206,208,234,112,118,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,229,75,83,249,205,208,254,255,255,238,230,227,254, + 252,251,254,252,251,238,232,228,253,255,254,254,246,246,229,74,82,248,202,205, + 255,253,253,255,251,251,255,253,253,255,251,251,255,253,253,247,196,198,234,109, + 116,255,253,253,255,251,251,255,253,253,255,252,252,255,253,253,254,243,243,229, + 74,82,249,205,208,254,255,255,238,230,227,254,252,251,254,252,251,238,232,228, + 253,255,254,254,246,246,229,75,83,248,203,206,255,253,253,255,251,251,255,253, + 253,255,251,251,255,253,253,247,197,199,234,109,116,255,253,253,255,251,251,255, + 253,253,255,252,252,255,253,253,254,243,243,229,75,83,249,206,209,254,255,255, + 238,230,227,254,252,251,254,252,251,238,232,228,253,255,254,254,245,245,228,68, + 77,249,214,216,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,248, + 207,208,235,114,121,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,229,72,80,249,202,205,254,255,255,238,230,227,254,252,251,254,252, + 251,238,232,229,252,252,251,255,250,250,235,109,116,231,84,93,234,105,112,234, + 103,110,234,104,111,234,103,110,234,104,111,232,89,97,228,66,75,234,104,111, + 234,103,110,234,104,111,234,103,111,234,105,112,233,97,105,231,81,89,252,228, + 230,253,253,253,238,231,228,254,252,251,254,252,251,238,233,229,252,250,250,255, + 255,255,253,242,243,241,155,160,241,153,158,241,153,158,241,153,158,241,153,158, + 241,153,158,241,156,160,242,160,165,241,153,158,241,153,158,241,153,158,241,153, + 158,241,154,159,240,147,152,250,219,221,255,255,255,252,250,250,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,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,254,254,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,255,255,255,255,255,255,255,253,253,255,253,253,255,253,253,255,253, + 253,255,253,253,255,253,253,255,253,253,255,253,253,255,253,253,255,253,253,255, + 253,253,255,253,253,255,253,253,255,252,253,255,255,255,255,255,255,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset33 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128, + 128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128, + 128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128, + 128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,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,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,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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset34 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128, + 128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128, + 128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128, + 128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,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,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,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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset35 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,0,0,0,0,0,0,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, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,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, + 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,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,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,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,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,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,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,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset36 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,0,0,0,0,0,0,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, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,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, + 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,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,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,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,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,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,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,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset37 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 255,253,252,253,251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249, + 246,244,249,246,244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252, + 253,251,250,253,251,250,253,251,249,254,253,252,246,242,240,237,231,227,239,234, + 230,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,230,237,231,227,246,242,240,254,253,252,253,251,249,255,253, + 252,246,242,240,238,232,229,252,251,250,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,252,251, + 250,238,232,229,246,242,240,255,253,252,253,251,250,237,231,227,253,252,252,255, + 255,255,254,254,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254, + 253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253, + 254,253,253,254,252,253,254,253,254,254,255,255,255,253,252,252,237,231,227,253, + 251,250,249,246,244,239,234,231,255,255,255,254,254,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,253,254,255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 254,255,255,255,255,255,250,252,254,203,225,246,205,226,246,205,226,246,205,226, + 246,205,226,246,205,226,246,205,226,246,205,226,246,205,226,246,205,226,246,205, + 226,246,205,225,246,208,228,247,180,211,241,234,243,251,255,255,255,254,255,255, + 239,234,231,249,246,244,249,246,244,238,234,231,254,255,255,236,244,251,78,151, + 223,45,131,217,55,137,218,52,135,217,53,136,218,53,136,218,53,136,218,53, + 136,218,52,135,217,53,136,218,53,136,218,53,136,218,54,136,218,43,129,215, + 4,107,209,47,132,217,217,232,248,254,255,255,238,233,231,249,246,244,249,246, + 244,236,232,230,255,255,255,151,194,236,65,143,221,245,249,253,240,248,254,246, + 254,255,240,247,253,241,248,253,240,247,253,243,250,255,246,253,255,240,247,253, + 241,248,253,239,247,253,247,253,255,224,240,254,122,176,230,68,145,221,112,170, + 228,255,255,255,236,232,230,249,246,244,249,246,244,236,232,230,255,255,255,145, + 190,235,91,158,225,255,255,255,246,251,255,228,230,230,255,255,255,255,255,255, + 255,255,255,244,248,250,231,233,234,255,255,255,255,255,255,255,255,255,239,242, + 244,235,238,239,255,255,255,134,184,232,101,164,227,255,255,255,236,232,230,249, + 246,244,249,246,244,236,232,230,255,255,255,146,191,235,86,156,225,234,231,229, + 188,187,187,119,108,102,224,221,219,214,215,216,224,221,219,176,172,170,129,119, + 113,224,221,219,213,213,214,224,221,219,159,154,150,137,130,127,232,230,229,124, + 178,231,102,165,227,255,255,255,236,232,230,249,246,244,249,246,244,236,232,230, + 255,255,255,145,190,234,91,162,230,175,163,154,113,103,96,94,80,72,135,124, + 117,131,121,115,135,124,117,116,104,97,97,83,74,135,124,117,130,121,114,135, + 124,117,110,98,91,93,80,73,177,164,155,131,185,237,101,164,226,255,255,255, + 236,232,230,249,246,244,249,246,244,236,232,230,255,255,255,146,191,235,84,154, + 222,255,255,255,224,227,230,136,127,121,255,255,255,254,255,255,255,255,255,206, + 206,206,148,141,136,255,255,255,252,255,255,255,255,255,185,183,180,163,159,157, + 255,255,255,123,176,228,102,165,227,255,255,255,236,232,230,249,246,244,249,246, + 244,236,232,230,255,255,255,146,191,235,85,155,224,249,249,248,208,209,210,129, + 120,114,247,246,245,236,239,242,247,246,245,193,191,190,141,132,127,247,246,245, + 234,237,240,247,246,245,174,171,167,153,147,145,250,249,248,124,178,230,102,165, + 227,255,255,255,236,232,230,249,246,244,249,246,244,236,232,230,255,255,255,145, + 190,234,91,162,231,170,158,148,108,97,90,94,79,71,128,116,108,125,114,107, + 128,116,108,112,100,92,96,82,73,128,116,108,124,113,107,128,116,108,107,95, + 87,90,77,70,172,159,149,131,185,237,101,164,226,255,255,255,236,232,230,249, + 246,244,249,246,244,236,232,230,255,255,255,146,191,235,85,155,223,250,250,249, + 207,208,210,121,111,104,249,248,247,237,241,243,249,248,247,191,189,187,134,125, + 119,249,248,247,235,239,241,249,248,247,170,166,162,147,141,138,251,250,249,124, + 177,229,102,165,227,255,255,255,236,232,230,249,246,244,249,246,244,236,232,230, + 255,255,255,146,191,235,88,157,224,255,255,255,227,232,236,181,179,178,251,255, + 255,245,251,254,251,255,255,219,222,223,188,186,186,251,255,255,244,249,253,251, + 255,255,208,209,210,194,195,196,254,255,255,127,180,231,103,166,227,255,255,255, + 236,232,230,249,246,244,249,246,244,236,232,230,255,255,255,144,190,235,77,150, + 223,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,120,176,231,97,162,226,255,255,255,236,232,230,249,246,244,249,246, + 244,238,233,231,254,255,255,220,234,248,55,137,218,68,145,221,77,150,222,73, + 147,220,76,150,223,75,150,223,76,150,223,75,149,222,74,148,221,76,150,223, + 75,150,222,76,150,223,74,148,221,75,148,221,75,149,222,43,130,216,191,217, + 243,255,255,255,237,233,230,249,246,244,249,246,244,239,234,231,254,255,255,255, + 255,255,227,239,250,158,198,237,162,200,238,162,200,238,162,200,238,162,200,238, + 162,200,238,162,200,238,162,200,238,162,200,238,162,200,238,162,200,238,162,200, + 238,163,201,238,156,197,237,210,228,247,255,255,255,254,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,255,255,255,254,254,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,253,254,254,255,255,255,239,234,231,249,246,244,253,251,250,237,231,227, + 253,252,252,255,255,255,253,254,254,251,253,254,251,253,254,251,253,254,251,253, + 254,251,253,254,251,253,254,251,253,254,251,253,254,251,253,254,251,253,254,251, + 253,254,251,253,254,251,253,254,251,253,254,253,253,254,255,255,255,253,252,252, + 237,231,227,253,251,250,255,253,252,246,242,240,238,232,229,252,251,250,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,252,251,250,238,232,229,246,242,240,255,253,252,253,251, + 249,254,253,252,246,242,240,237,231,227,239,234,230,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,230,237,231, + 227,246,242,240,254,253,252,253,251,249,253,251,250,253,251,250,255,253,252,253, + 251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244, + 249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252,253,251,250,253, + 251,250 + ); + CEditorAsset38 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,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,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,0, + 0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,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 + ); + CEditorAsset39 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 255,253,252,253,251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249, + 246,244,249,246,244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252, + 253,251,250,253,251,250,253,251,249,254,253,252,246,242,240,237,231,227,239,234, + 230,239,234,231,239,234,231,239,233,230,239,233,230,239,233,230,239,233,230,239, + 233,230,239,233,230,239,233,230,239,233,230,239,233,230,239,233,230,239,234,230, + 239,234,231,239,234,230,237,231,227,246,242,240,254,253,252,253,251,249,255,253, + 252,246,242,240,238,232,229,252,251,250,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,252,251, + 250,238,232,229,246,242,240,255,253,252,253,251,250,237,231,227,253,252,252,255, + 255,255,254,254,254,255,255,255,250,249,249,235,232,230,237,234,232,236,233,232, + 236,233,232,236,233,232,236,233,232,236,233,232,236,233,232,237,234,232,235,232, + 230,246,244,243,255,255,255,255,254,254,255,255,255,253,252,252,237,231,227,253, + 251,250,249,246,244,239,234,231,255,255,255,254,254,254,254,254,254,245,243,242, + 179,168,162,179,168,162,181,171,164,181,170,163,181,170,163,181,170,163,181,170, + 164,181,170,163,182,172,165,183,173,166,181,170,164,174,162,155,234,231,229,255, + 255,255,254,254,253,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 255,255,255,254,253,253,255,255,255,223,218,216,187,178,171,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,206,198,194,203,195,191,255,255,255,253,253,253,255,255,255, + 239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,254,253,253,255,255, + 255,225,220,218,193,184,178,248,247,246,191,185,182,193,187,184,193,187,184,193, + 187,184,194,188,184,191,184,181,238,237,236,253,252,252,254,254,254,206,199,195, + 207,200,196,255,255,255,253,253,253,255,255,255,239,234,231,249,246,244,249,246, + 244,239,234,231,255,255,255,254,253,253,255,255,255,224,219,217,194,185,179,244, + 243,243,151,142,136,153,144,138,153,144,138,153,144,138,154,145,139,149,139,133, + 227,225,223,252,252,252,255,255,255,206,199,195,206,199,195,255,255,255,253,253, + 253,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,254, + 253,253,255,255,255,225,220,218,189,180,174,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,206,199,195,206,199,195,255,255,255,253,253,253,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,255,255,255,254,253,253,255,255,255,224,220,217, + 194,185,180,241,240,239,134,123,116,136,125,118,136,125,118,136,125,118,136,125, + 118,137,125,118,135,124,117,150,139,134,253,253,253,206,199,195,207,200,195,255, + 255,255,253,253,253,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 255,255,255,254,253,253,255,255,255,223,218,215,194,185,180,255,255,255,221,219, + 217,224,221,220,224,221,220,224,221,220,224,221,220,224,222,220,223,220,218,226, + 224,223,255,255,255,211,205,201,203,196,192,255,255,255,253,253,253,255,255,255, + 239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,254,254,253,254,253, + 253,234,229,228,171,158,151,204,195,191,214,206,203,214,206,203,214,206,203,214, + 206,203,214,206,203,214,206,203,214,207,203,212,204,201,204,195,191,175,162,155, + 218,211,209,254,253,253,253,253,253,255,255,255,239,234,231,249,246,244,249,246, + 244,239,234,231,255,255,255,255,254,254,255,255,255,255,255,255,237,241,236,211, + 211,204,213,214,207,212,213,206,212,213,206,212,213,206,212,213,206,212,213,206, + 212,213,206,213,214,207,212,212,205,228,231,225,255,255,255,255,255,255,255,254, + 254,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,255, + 255,255,237,217,224,205,151,170,212,161,180,216,166,185,216,165,185,216,165,185, + 216,165,185,216,165,185,216,165,185,216,165,185,216,165,185,216,165,185,216,165, + 184,213,162,181,204,150,169,228,199,210,255,255,255,255,255,255,239,234,231,249, + 246,244,249,246,244,239,233,230,255,255,255,243,229,234,175,88,119,192,123,148, + 195,130,153,194,127,151,194,127,151,194,127,151,194,127,151,194,127,151,194,127, + 151,194,127,151,194,128,151,194,127,151,195,131,154,198,135,157,195,129,152,172, + 82,114,230,203,213,255,255,255,238,232,229,249,246,244,249,246,244,238,232,229, + 255,255,255,229,200,211,179,96,125,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,248,235,240,231,201,212,255,255,255,191,119,145,210,163,179,255,255,255, + 238,231,229,249,246,244,249,246,244,238,232,229,255,255,255,231,204,214,180,98, + 127,252,246,249,252,245,248,252,245,248,252,245,248,252,245,248,252,245,248,252, + 245,248,252,245,248,252,245,247,252,244,247,250,244,246,185,109,136,155,47,86, + 237,215,223,194,126,150,213,167,183,255,255,255,238,231,229,249,246,244,249,246, + 244,238,232,229,255,255,255,229,200,211,179,96,125,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,252,253,224,188,201,221,181,196,240,222,229,195,127,151,209,161, + 178,255,255,255,238,231,229,249,246,244,249,246,244,239,233,230,255,255,255,243, + 229,234,175,88,119,192,123,148,196,131,154,195,129,153,196,129,153,196,129,153, + 196,129,153,196,129,153,196,129,153,196,129,153,196,129,153,196,131,155,202,142, + 164,202,143,164,199,138,159,172,80,113,230,203,213,255,255,255,238,232,229,249, + 246,244,249,246,244,239,234,231,255,255,255,255,255,255,237,217,224,205,151,170, + 207,155,174,207,155,173,207,155,173,207,155,173,207,155,173,207,155,173,207,155, + 173,207,155,173,207,155,173,207,154,173,205,152,171,206,153,172,204,148,168,228, + 199,210,255,255,255,255,255,255,239,234,231,249,246,244,253,251,250,237,231,227, + 253,252,252,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,253,252,252, + 237,231,227,253,251,250,255,253,252,246,242,240,238,232,229,252,251,250,255,255, + 255,255,253,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255, + 254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254, + 255,253,254,255,254,255,252,251,250,238,232,229,246,242,240,255,253,252,253,251, + 249,254,253,252,246,242,240,237,231,227,239,234,230,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,230,237,231, + 227,246,242,240,254,253,252,253,251,249,253,251,250,253,251,250,255,253,252,253, + 251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244, + 249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252,253,251,250,253, + 251,250 + ); + CEditorAsset40 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,128,128, + 128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,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,128,128,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,128,128,128,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,128,128,128,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,128,128,128,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,0,0,0,255,255, + 255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,128,128, + 128,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,128, + 128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,0,0,0,0, + 0,0,0,0,0,0,0,0,128,128,128,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0, + 0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0, + 0,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,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,0,0,0,0,0,0,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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, + 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,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,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,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, + 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,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,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 + ); + CEditorAsset41 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,0,0,0,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,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, + 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,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,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,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,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,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,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,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,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,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, + 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,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,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,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,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,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,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,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,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,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, + 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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,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,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,255,255,255,255,255,255, + 255,255,255,0,0,0,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,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,255,255,255,255,255,255,0,0,0,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,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,255,255, + 255,0,0,0,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, + 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,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,0,0,0,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,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,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,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,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset42 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,255, + 255,255,255,255,255,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254, + 255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254, + 254,255,254,254,255,254,254,255,255,254,255,255,255,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,254,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,250,249,255,255,255,237,222,212,186,125,87,184,123,85,183,123,84,184,123, + 85,185,125,86,185,125,86,184,123,84,183,122,84,184,123,84,185,125,86,185, + 125,86,184,123,85,184,124,86,180,117,77,222,193,175,255,255,255,252,251,249, + 238,233,229,254,252,251,254,252,251,238,232,228,253,253,252,252,249,247,176,108, + 65,195,142,108,220,180,154,221,181,155,214,173,148,208,167,141,208,167,141,217, + 177,151,222,182,156,217,177,151,208,167,141,208,167,141,214,173,147,222,182,157, + 216,173,146,169,94,46,237,222,212,254,254,254,237,231,227,254,252,251,254,252, + 251,238,232,228,254,254,254,251,246,244,172,98,52,235,220,211,210,213,216,196, + 197,198,235,239,242,255,255,255,255,255,255,220,224,226,197,199,200,220,224,226, + 255,255,255,255,255,255,235,238,241,198,199,201,204,203,203,170,97,51,232,211, + 198,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228,254,254,254,248, + 244,241,185,114,68,148,121,104,122,114,108,150,140,134,110,97,90,249,247,246, + 213,208,206,106,92,84,151,142,137,106,92,84,213,208,206,249,247,246,110,97, + 90,150,141,134,124,115,110,120,68,36,242,219,205,255,255,255,237,231,227,254, + 252,251,254,252,251,238,232,228,254,254,254,248,244,241,187,116,70,128,101,84, + 202,199,196,255,255,255,125,114,108,246,245,245,197,193,191,154,143,136,255,255, + 255,154,143,136,197,193,191,246,245,245,125,114,108,255,255,255,206,204,202,107, + 60,32,243,220,205,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228, + 254,254,254,248,244,241,187,116,70,133,106,89,190,186,183,252,252,249,124,113, + 107,247,246,246,201,197,195,147,136,129,252,252,251,147,136,129,201,197,195,247, + 246,246,124,113,107,252,252,248,193,190,188,110,61,32,243,220,205,255,255,255, + 237,231,227,254,252,251,254,252,251,238,232,228,254,254,254,248,244,241,187,116, + 70,132,105,88,192,188,185,255,255,253,124,113,107,247,246,246,200,196,194,148, + 137,130,255,255,255,148,137,130,200,196,194,247,246,246,124,113,107,255,255,252, + 195,192,190,109,61,32,243,220,205,255,255,255,237,231,227,254,252,251,254,252, + 251,238,232,228,254,254,254,248,244,241,187,116,70,132,105,88,192,188,185,255, + 255,253,124,113,107,247,246,246,200,196,194,148,137,130,255,255,255,148,137,130, + 200,196,194,247,246,246,124,113,107,255,255,252,195,192,190,109,61,32,243,220, + 205,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228,254,254,254,248, + 244,241,187,116,70,133,106,89,190,186,183,252,252,249,124,113,107,247,246,246, + 201,197,195,147,136,129,252,252,251,147,136,129,201,197,195,247,246,246,124,113, + 107,252,252,248,193,190,188,110,61,32,243,220,205,255,255,255,237,231,227,254, + 252,251,254,252,251,238,232,228,254,254,254,248,244,241,187,116,70,128,101,84, + 202,199,196,255,255,255,125,114,108,246,245,245,197,193,191,154,143,136,255,255, + 255,154,143,136,197,193,191,246,245,245,125,114,108,255,255,255,206,204,202,107, + 60,32,243,220,205,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228, + 254,254,254,248,244,242,185,115,69,149,122,105,123,115,110,151,141,135,110,98, + 91,250,249,248,213,210,208,107,93,85,152,143,139,107,93,85,213,210,208,250, + 249,248,110,98,91,151,142,135,124,116,111,120,68,36,242,220,205,255,255,255, + 237,231,227,254,252,251,254,252,251,238,232,228,254,254,255,250,246,244,170,95, + 48,234,218,207,208,209,211,194,193,193,232,235,237,255,255,255,255,255,255,218, + 220,221,195,195,195,218,220,221,255,255,255,255,255,255,232,234,236,196,195,196, + 202,200,199,168,94,48,231,210,197,255,255,255,237,231,227,254,252,251,254,252, + 251,238,232,229,252,252,251,253,251,250,188,130,93,177,109,66,197,138,100,199, + 139,101,191,131,93,185,125,86,185,125,86,194,135,96,199,140,102,194,135,96, + 185,125,86,185,125,86,191,131,93,200,141,103,194,131,92,176,106,62,243,232, + 225,254,253,253,238,232,228,254,252,251,254,252,251,238,233,229,252,251,250,255, + 255,255,249,244,241,209,168,143,206,165,139,206,165,139,207,166,139,208,167,141, + 208,167,141,206,165,139,206,164,138,206,165,139,208,167,141,208,167,141,207,166, + 139,206,165,140,203,160,133,238,224,215,255,255,255,252,250,249,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,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,254,254,254,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,255,255,255,255,255,255,254,253,252,254,253,253,254,253,252,254,253, + 252,254,253,252,254,253,252,254,253,252,254,253,252,254,253,252,254,253,252,254, + 253,252,254,253,252,254,253,253,254,253,252,255,255,255,255,255,255,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset43 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,255, + 255,255,255,255,255,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254, + 255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254, + 254,255,254,254,255,254,254,255,255,254,255,255,255,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,254,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,250,249,255,255,255,237,222,212,186,125,87,186,125,87,185,125,87,185,125, + 86,185,125,86,185,125,86,187,128,91,190,134,98,185,125,86,185,125,86,185, + 125,86,185,125,86,186,126,88,182,119,79,222,193,175,255,255,255,252,251,249, + 238,233,229,254,252,251,254,252,251,238,232,228,253,253,252,252,249,247,177,108, + 65,194,141,108,208,168,142,207,166,140,208,167,141,207,166,140,208,167,141,195, + 142,109,174,104,60,208,167,141,207,166,140,208,167,141,208,166,140,208,167,141, + 205,161,134,169,94,46,237,222,213,254,254,254,237,231,227,254,252,251,254,252, + 251,238,232,228,254,254,254,251,247,245,171,97,51,238,223,214,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,234,216,204,190,134,99,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,172,100,54,231,210, + 197,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228,254,254,254,251, + 247,245,172,100,54,231,210,196,254,252,251,253,250,249,254,252,251,253,250,249, + 254,252,251,228,204,189,188,129,92,254,252,251,253,251,249,254,252,251,254,251, + 250,254,252,251,249,243,241,172,99,53,232,212,201,255,255,255,237,231,227,254, + 252,251,254,252,251,238,232,228,254,254,254,251,247,245,172,99,53,231,211,198, + 254,254,253,253,252,251,254,254,253,253,252,251,254,254,253,228,205,190,188,130, + 93,254,254,253,253,253,251,254,254,253,254,253,252,254,254,253,249,245,242,172, + 99,53,232,212,200,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228, + 254,254,254,251,247,245,172,99,53,235,218,207,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,232,212,199,189,132,95,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,254,254,255,172,100,54,232,212,200,255,255,255, + 237,231,227,254,252,251,254,252,251,238,232,228,254,254,254,250,246,243,174,105, + 60,182,118,78,188,130,93,188,129,92,188,130,93,188,129,92,188,130,93,182, + 119,79,174,103,58,188,130,93,188,129,92,188,130,93,188,129,92,188,130,93, + 188,128,92,167,91,43,234,214,202,255,255,255,237,231,227,254,252,251,254,252, + 251,238,232,228,254,254,254,251,247,244,173,101,56,212,175,151,229,206,191,228, + 204,190,229,206,191,228,204,190,229,206,191,211,172,147,182,119,79,229,206,191, + 228,205,190,229,206,191,229,205,190,229,206,191,225,200,184,170,96,49,233,213, + 201,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228,254,254,254,251, + 247,245,172,99,52,236,220,209,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,233,213,200,189,132,96,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,172,100,54,232,212,200,255,255,255,237,231,227,254, + 252,251,254,252,251,238,232,228,254,254,254,251,247,245,172,99,53,231,211,197, + 254,253,252,253,251,250,254,253,252,253,251,250,254,253,252,228,205,189,188,130, + 92,254,253,252,253,252,250,254,253,252,254,252,251,254,253,252,249,244,242,172, + 99,53,232,212,200,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228, + 254,254,254,251,247,245,173,100,55,231,211,197,254,254,253,253,252,251,254,254, + 253,253,252,251,254,254,253,228,205,190,188,130,93,254,254,253,253,253,251,254, + 254,253,254,253,252,254,254,253,249,244,242,172,100,54,232,213,201,255,255,255, + 237,231,227,254,252,251,254,252,251,238,232,228,254,254,255,251,246,244,169,94, + 47,237,221,210,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,233, + 214,201,190,134,99,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,171,97,50,230,209,196,255,255,255,237,231,227,254,252,251,254,252, + 251,238,232,229,252,252,251,253,251,250,188,130,93,177,108,65,186,126,88,185, + 124,86,185,125,86,185,124,86,185,125,86,179,112,70,168,93,45,185,125,86, + 185,125,86,185,125,86,185,125,86,186,126,87,182,119,79,175,106,62,243,232, + 225,254,253,253,238,232,228,254,252,251,254,252,251,238,233,229,252,251,250,255, + 255,255,249,244,241,209,169,143,208,167,141,208,167,141,208,167,141,208,167,141, + 208,167,141,209,170,144,212,174,150,208,167,141,208,167,141,208,167,141,208,167, + 141,208,168,142,205,162,135,238,224,215,255,255,255,252,250,249,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,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,254,254,254,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,255,255,255,255,255,255,254,253,252,254,253,253,254,253,252,254,253, + 252,254,253,252,254,253,252,254,253,252,254,253,252,254,253,252,254,253,252,254, + 253,252,254,253,252,254,253,253,254,253,252,255,255,255,255,255,255,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset44 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,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,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,251,251,255,255,255,254,254,254,246,245,244,245,244,243,245,244,244,245,244, + 244,245,244,244,245,244,244,245,244,244,245,244,243,246,245,244,254,254,254,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,251,251,250,255,255,255,243,242, + 242,87,75,67,73,59,51,77,63,55,76,62,54,76,62,54,76,62,54,77, + 63,55,73,59,51,87,75,67,243,242,242,255,255,255,254,254,254,255,255,255, + 255,255,255,255,255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,255,255,255,252,251,251,207,203,201,202,198,196,204, + 200,197,203,199,197,203,199,197,203,199,197,204,200,197,202,198,196,207,203,201, + 250,250,250,253,253,253,253,253,253,253,253,253,255,255,255,255,255,255,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,251,251,250,255,255,255,245,244,244,113,102,95, + 100,89,82,104,92,86,103,91,85,103,91,85,103,91,85,103,91,85,103,91, + 85,103,91,85,105,94,87,105,94,87,107,95,89,99,86,80,217,213,212,255, + 255,255,253,254,254,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 251,251,250,255,255,255,248,248,248,157,150,145,149,141,136,151,143,139,151,143, + 138,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138,151, + 143,138,151,143,139,148,140,136,229,227,226,255,255,255,254,254,254,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,251,251,250,255,255,255,248,248,248,157,150,145,149,141,136,151, + 143,139,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138, + 151,143,138,152,144,139,146,138,133,226,223,222,254,254,254,254,254,253,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,251,251,250,255, + 255,255,245,244,244,113,103,95,101,90,82,104,93,85,103,92,84,103,92,84, + 103,92,84,103,92,84,103,92,84,103,92,84,103,92,84,105,94,86,97,85, + 77,214,212,209,253,253,252,253,253,252,255,255,255,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,255,255,255,252,253,251,214,222,202,210,220,197,211,220,198,211,220, + 198,211,220,198,211,220,198,211,220,198,211,220,198,211,220,198,211,220,198,211, + 220,198,211,220,198,213,222,200,211,221,197,244,246,241,255,255,255,252,251,250, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,250,255,255,255,243,245, + 239,78,116,23,63,104,2,67,108,8,66,107,7,66,107,7,66,107,7,66, + 107,7,66,107,7,66,107,7,66,107,7,66,107,7,66,107,7,68,108,9, + 57,100,0,207,217,191,255,255,255,250,250,248,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,250,255,255,255,247,248,244,137,162,100,127,154,86,129, + 157,90,129,156,89,129,156,89,129,156,89,129,156,89,129,156,89,129,156,89, + 129,156,89,129,156,89,129,156,89,130,157,91,123,151,82,223,229,212,255,255, + 255,250,250,249,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,252,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,255,255,255,255,255,255,253,254,253, + 253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254, + 253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,254, + 254,254,255,255,255,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,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,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset45 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,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,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,251,251,255,255,255,254,254,254,246,245,244,245,244,243,245,244,244,245,244, + 244,245,244,244,245,244,244,245,244,244,245,244,243,246,245,244,254,254,254,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,251,251,250,255,255,255,243,242, + 242,87,75,67,73,59,51,77,63,55,76,62,54,76,62,54,76,62,54,77, + 63,55,73,59,51,87,75,67,243,242,242,255,255,255,254,254,254,255,255,255, + 255,255,255,255,255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,255,255,255,252,251,251,207,203,201,202,198,196,204, + 200,197,203,199,197,203,199,197,203,199,197,204,200,197,202,198,196,207,203,201, + 250,250,250,253,253,253,253,253,253,253,253,253,255,255,255,255,255,255,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,251,251,250,255,255,255,245,244,244,113,102,95, + 100,89,82,104,92,86,103,91,85,103,91,85,103,91,85,103,91,85,103,91, + 85,103,91,85,105,94,87,105,94,87,107,95,89,99,86,80,217,213,212,255, + 255,255,253,254,254,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 251,251,250,255,255,255,248,248,248,157,150,145,149,141,136,151,143,139,151,143, + 138,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138,151, + 143,138,151,143,139,148,140,136,229,227,226,255,255,255,254,254,254,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,251,251,250,255,255,255,248,248,248,157,150,145,149,141,136,151, + 143,139,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138, + 151,143,138,152,144,139,146,138,133,226,223,222,254,254,254,254,254,253,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,251,251,250,255, + 255,255,245,244,244,113,103,95,101,90,82,104,93,85,103,92,84,103,92,84, + 103,92,84,103,92,84,103,92,84,103,92,84,103,92,84,105,94,86,97,85, + 77,214,212,209,253,253,252,253,253,252,255,255,255,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,255,255,255,252,253,251,214,222,202,210,220,197,211,220,198,211,220, + 198,211,220,198,211,220,198,211,220,198,211,220,198,211,220,198,211,220,198,211, + 220,198,211,220,198,213,222,200,211,221,197,244,246,241,255,255,255,252,251,250, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,250,255,255,255,243,245, + 239,78,116,23,63,104,2,67,108,8,66,107,7,66,107,7,66,107,7,66, + 107,7,66,107,7,66,107,7,66,107,7,66,107,7,66,107,7,68,108,9, + 57,100,0,207,217,191,255,255,255,250,250,248,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,250,255,255,255,247,248,244,137,162,100,127,154,86,129, + 157,90,129,156,89,129,156,89,129,156,89,129,156,89,129,156,89,129,156,89, + 129,156,89,129,156,89,129,156,89,130,157,91,123,151,82,223,229,212,255,255, + 255,250,250,249,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,252,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,255,255,255,255,255,255,253,254,253, + 253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254, + 253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,254, + 254,254,255,255,255,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,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,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset46 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,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,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,251,251,255,255,255,254,254,254,246,245,244,245,244,243,245,244,244,245,244, + 244,245,244,244,245,244,244,245,244,244,245,244,243,246,245,244,254,254,254,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,251,251,250,255,255,255,243,242, + 242,87,75,67,73,59,51,77,63,55,76,62,54,76,62,54,76,62,54,77, + 63,55,73,59,51,87,75,67,243,242,242,255,255,255,254,254,254,255,255,255, + 255,255,255,255,255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,255,255,255,252,251,251,207,203,201,202,198,196,204, + 200,197,203,199,197,203,199,197,203,199,197,204,200,197,202,198,196,207,203,201, + 250,250,250,253,253,253,253,253,253,253,253,253,255,255,255,255,255,255,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,251,251,250,255,255,255,245,244,244,113,102,95, + 100,89,82,104,92,86,103,91,85,103,91,85,103,91,85,103,91,85,103,91, + 85,103,91,85,105,94,87,105,94,87,107,95,89,99,86,80,217,213,212,255, + 255,255,253,254,254,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 251,251,250,255,255,255,248,248,248,157,150,145,149,141,136,151,143,139,151,143, + 138,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138,151, + 143,138,151,143,139,148,140,136,229,227,226,255,255,255,254,254,254,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,251,251,250,255,255,255,248,248,248,157,150,145,149,141,136,151, + 143,139,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138, + 151,143,138,152,144,139,146,138,133,226,223,222,254,254,254,254,254,253,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,251,251,250,255, + 255,255,245,244,244,113,103,95,101,90,82,104,93,85,103,92,84,103,92,84, + 103,92,84,103,92,84,103,92,84,103,92,84,103,92,84,105,94,86,97,85, + 77,214,212,209,253,253,252,253,253,252,255,255,255,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,255,255,255,252,253,251,214,222,202,210,220,197,211,220,198,211,220, + 198,211,220,198,211,220,198,211,220,198,211,220,198,211,220,198,211,220,198,211, + 220,198,211,220,198,213,222,200,211,221,197,244,246,241,255,255,255,252,251,250, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,250,255,255,255,243,245, + 239,78,116,23,63,104,2,67,108,8,66,107,7,66,107,7,66,107,7,66, + 107,7,66,107,7,66,107,7,66,107,7,66,107,7,66,107,7,68,108,9, + 57,100,0,207,217,191,255,255,255,250,250,248,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,250,255,255,255,247,248,244,137,162,100,127,154,86,129, + 157,90,129,156,89,129,156,89,129,156,89,129,156,89,129,156,89,129,156,89, + 129,156,89,129,156,89,129,156,89,130,157,91,123,151,82,223,229,212,255,255, + 255,250,250,249,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,252,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,255,255,255,255,255,255,253,254,253, + 253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254, + 253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,254, + 254,254,255,255,255,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,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,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset47 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,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,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,251,251,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,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255, + 255,255,255,255,255,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,254,254,254,255,254,255,255,255,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,255,255,255,250,251,249,245,247,242,246,248,243,246,248,243,246,248, + 243,246,248,243,246,248,243,246,248,243,246,248,243,246,248,243,246,248,243,246, + 248,243,246,248,243,246,248,243,245,248,242,248,250,246,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,249,249,247,255,255,255,170,188, + 143,72,112,15,88,123,35,85,121,31,85,121,31,85,121,31,85,121,31,85, + 121,31,85,121,31,85,121,31,85,121,31,85,121,31,85,121,31,87,123,34, + 76,115,20,128,155,89,255,255,255,251,250,249,238,233,229,254,252,251,254,252, + 251,238,233,229,250,249,248,255,255,255,190,203,169,114,145,70,126,154,86,124, + 152,83,124,152,83,124,152,83,124,152,83,124,152,83,124,152,83,124,152,83, + 124,152,83,124,152,83,124,152,83,126,154,85,117,147,74,158,178,127,255,255, + 255,251,250,249,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,255,255,255,254,254,254,253,254,253, + 253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254, + 253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,254, + 254,253,255,255,255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,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,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,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,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,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,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset48 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,0,0,0,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,255,255, + 255,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0, + 0,255,255,255,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,255, + 255,255,255,255,255,0,0,0,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,255,0,0,0,255,255,255,0,0,0,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 0,0,0,255,255,255,255,255,255,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,0,0,0,255,255,255,255,255, + 255,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,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,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,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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset49 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,255,255,255,255,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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, + 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,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,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,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, + 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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset50 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 255,253,252,253,251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249, + 246,244,249,246,244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252, + 253,251,250,253,251,250,253,251,249,254,253,252,246,242,240,237,231,227,239,234, + 230,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,230,237,231,227,246,242,240,254,253,252,253,251,249,255,253, + 252,246,242,240,238,232,229,252,251,250,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,252,251, + 250,238,232,229,246,242,240,255,253,252,253,251,250,237,231,227,253,252,252,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,253,252,252,237,231,227,253, + 251,250,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 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,255,255,255,255,255, + 239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,254,254,255,252,253, + 254,252,253,254,252,253,254,252,253,254,252,253,254,252,253,254,251,253,254,251, + 253,254,251,253,254,251,253,254,251,253,254,251,253,254,251,253,254,251,253,254, + 251,253,254,251,253,254,253,254,255,255,255,255,239,234,231,249,246,244,249,246, + 244,239,234,231,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,255, + 255,254,255,255,239,234,231,249,246,244,249,246,244,238,233,231,255,255,255,231, + 241,250,145,190,235,143,189,234,144,190,234,143,189,234,144,190,235,122,176,231, + 115,172,229,116,173,229,116,173,229,116,173,229,116,173,229,116,173,229,116,173, + 229,117,173,230,117,174,230,113,171,229,205,225,246,255,255,255,237,233,231,249, + 246,244,249,246,244,242,236,231,241,247,254,144,190,233,187,216,239,184,214,239, + 184,215,239,184,215,239,186,216,240,128,180,232,110,170,229,116,174,232,116,176, + 234,116,175,234,116,175,234,116,176,234,116,175,233,112,172,230,116,173,230,101, + 165,227,48,133,217,230,241,252,245,237,232,248,245,244,248,245,244,247,238,232, + 227,239,252,125,179,230,229,240,246,216,234,245,219,235,245,219,235,245,217,234, + 245,255,255,255,255,255,255,255,255,250,253,247,242,254,249,243,254,249,243,253, + 248,242,255,251,245,255,255,255,255,255,255,255,255,255,52,136,218,203,225,248, + 251,241,233,247,244,243,248,245,244,246,238,232,229,240,252,128,180,230,220,235, + 245,209,230,244,211,231,244,211,231,244,210,230,244,236,243,250,250,252,254,175, + 172,171,112,101,95,123,113,108,121,113,107,117,106,101,139,132,128,241,246,251, + 245,250,252,239,246,253,54,136,218,207,227,248,250,241,233,247,244,243,248,245, + 244,246,238,232,229,240,252,127,180,230,221,236,245,210,230,244,212,231,244,212, + 231,244,211,230,244,241,248,253,250,253,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,241,249,254,53,136, + 218,206,227,248,250,241,233,247,244,243,248,245,244,246,238,232,229,240,252,127, + 180,230,221,236,245,210,230,244,212,231,244,212,231,244,211,230,244,240,246,251, + 252,254,255,210,210,210,176,172,169,182,178,176,181,177,175,181,177,175,182,178, + 176,176,172,170,200,197,195,245,251,254,53,135,217,206,227,248,250,241,233,247, + 244,243,248,245,244,246,238,232,229,240,252,128,180,230,219,235,245,209,229,244, + 211,230,244,211,230,244,210,229,244,237,244,250,251,253,254,178,175,173,116,106, + 100,127,118,112,125,116,110,125,116,110,126,117,112,118,108,103,158,152,148,245, + 252,254,53,135,217,207,227,248,250,241,233,247,244,243,248,245,244,247,238,232, + 227,239,252,124,178,229,232,242,247,220,236,246,222,237,246,222,237,246,221,236, + 246,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,49,134,218,203,226,248, + 251,241,233,247,244,243,249,246,244,241,235,231,245,249,254,153,195,235,171,207, + 236,169,205,237,169,206,237,169,206,237,171,207,237,104,166,227,83,154,224,86, + 155,223,84,153,221,84,153,222,84,153,222,84,153,222,84,153,222,84,153,221, + 88,156,223,75,149,222,59,139,219,236,244,253,243,236,232,248,245,244,249,246, + 244,238,233,231,255,255,255,240,246,252,161,200,238,159,198,237,160,199,238,159, + 199,238,160,199,238,149,192,236,146,190,235,146,191,235,146,191,235,146,191,235, + 146,191,235,146,191,235,146,191,235,146,191,235,147,191,235,144,189,235,224,236, + 249,255,255,255,237,233,231,249,246,244,249,246,244,239,234,231,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,255,255,254,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,255,255,255,254,254,255,252,253,254,252,253,254, + 252,253,254,252,253,254,252,253,254,251,253,254,251,253,254,251,253,254,251,253, + 254,251,253,254,251,253,254,251,253,254,251,253,254,251,253,254,251,253,254,251, + 253,254,253,254,254,255,255,255,239,234,231,249,246,244,253,251,250,237,231,227, + 253,252,252,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,253,252,252, + 237,231,227,253,251,250,255,253,252,246,242,240,238,232,229,252,251,250,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,252,251,250,238,232,229,246,242,240,255,253,252,253,251, + 249,254,253,252,246,242,240,237,231,227,239,234,230,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,230,237,231, + 227,246,242,240,254,253,252,253,251,249,253,251,250,253,251,250,255,253,252,253, + 251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244, + 249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252,253,251,250,253, + 251,250 + ); + CEditorAsset51 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,232,229,238,232,229,238,232,229,238,232,229,238, + 232,229,238,232,229,238,232,229,238,232,229,238,232,229,238,232,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,249,249,252,249,249,252, + 250,249,252,250,249,252,250,249,252,250,249,252,250,249,252,250,249,252,250,249, + 252,250,249,252,250,249,252,250,249,252,249,249,252,249,248,250,247,246,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,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,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,255,254,254,255,255,255,246,192,195, + 234,102,110,234,104,111,234,104,111,234,104,111,234,104,111,234,104,111,234,104, + 111,234,104,111,234,104,111,234,104,111,234,105,112,233,99,107,242,161,165,255, + 254,254,255,255,254,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,250,249,255,255,255,248,205,207,228,62,71,237,136,141,239,152,156,238,148, + 153,238,149,154,238,149,154,238,149,154,238,149,154,238,149,154,238,149,154,239, + 150,154,239,150,155,239,150,155,228,66,76,242,161,165,255,255,255,252,249,249, + 238,233,229,254,252,251,254,252,251,238,233,229,252,248,248,255,255,255,240,149, + 154,233,100,107,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,254,255,255,254,255,255,255,255,255, + 239,152,156,233,99,106,255,255,255,252,250,249,238,232,229,254,252,251,254,252, + 251,238,233,229,252,248,248,255,255,255,241,154,159,233,103,110,253,252,253,244, + 237,236,241,236,235,242,236,235,242,236,235,242,236,235,242,236,235,241,236,235, + 242,237,236,251,246,245,252,244,243,254,252,252,239,150,155,234,105,112,255,255, + 255,252,250,249,238,232,229,254,252,251,254,252,251,238,233,229,252,248,248,255, + 255,255,241,153,158,231,100,107,255,255,255,120,108,101,65,51,42,77,63,55, + 75,61,53,75,61,53,76,62,54,72,58,50,87,73,66,239,237,235,254,249, + 248,253,255,255,239,150,155,234,104,111,255,255,255,252,250,249,238,232,229,254, + 252,251,254,252,251,238,233,229,252,248,248,255,255,255,241,153,158,232,101,108, + 254,255,255,218,212,209,203,198,195,206,201,199,206,201,198,206,201,198,206,201, + 198,205,200,197,209,204,202,252,250,249,255,251,250,254,255,255,239,150,155,234, + 104,111,255,255,255,252,250,249,238,232,229,254,252,251,254,252,251,238,233,229, + 252,248,248,255,255,255,241,153,158,233,102,109,253,255,255,252,248,247,253,251, + 250,253,251,250,253,251,250,253,251,250,252,251,250,253,251,250,252,250,249,243, + 240,239,242,237,236,253,255,255,239,150,155,234,104,111,255,255,255,252,250,249, + 238,232,229,254,252,251,254,252,251,238,233,229,252,248,248,255,255,255,241,153, + 158,231,100,107,255,255,255,119,107,100,63,50,41,75,61,54,73,59,52,73, + 59,52,73,60,52,73,59,52,75,61,53,72,59,51,86,71,64,242,253,251, + 242,153,158,233,103,110,255,255,255,252,250,249,238,232,229,254,252,251,254,252, + 251,238,233,229,252,248,248,255,255,255,241,153,158,232,101,108,253,254,254,215, + 208,206,200,194,191,203,197,194,203,197,194,203,197,194,203,197,194,203,197,194, + 203,197,194,202,196,193,206,197,194,251,254,253,240,150,155,234,104,111,255,255, + 255,252,250,249,238,232,229,254,252,251,254,252,251,238,233,229,252,248,248,255, + 255,255,241,153,158,233,103,110,253,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,239,151,156,234,104,111,255,255,255,252,250,249,238,232,229,254, + 252,251,254,252,251,238,233,229,252,248,248,255,255,255,241,154,159,233,99,106, + 251,243,244,249,235,234,248,236,235,248,236,236,248,236,236,248,236,236,248,236, + 236,248,236,236,248,236,236,248,236,236,248,233,233,252,243,244,238,144,150,234, + 105,112,255,255,255,252,250,249,238,232,229,254,252,251,254,252,251,238,233,229, + 252,248,248,255,255,255,242,162,167,227,59,69,231,85,93,230,82,90,230,82, + 90,230,82,90,230,82,90,230,82,90,230,82,90,230,82,90,230,82,90,230, + 82,90,230,81,90,231,84,92,229,66,75,236,116,123,255,255,255,252,250,249, + 238,232,229,254,252,251,254,252,251,238,233,229,252,248,248,255,255,255,242,162, + 167,227,56,66,229,70,79,229,67,76,229,67,76,229,67,76,229,67,76,229, + 67,76,229,67,76,229,67,76,229,67,76,229,67,76,229,67,76,229,69,78, + 228,59,69,236,118,125,255,255,255,252,250,249,238,232,229,254,252,251,254,252, + 251,238,233,229,252,248,248,255,255,255,242,162,167,227,53,63,230,78,87,230, + 74,83,230,74,83,230,74,83,230,74,83,230,74,83,230,74,83,230,74,83, + 230,74,83,230,74,83,230,74,83,230,77,85,228,60,70,236,114,122,255,255, + 255,252,250,249,238,232,229,254,252,251,254,252,251,238,233,229,252,250,250,255, + 255,255,251,225,227,230,79,87,227,53,63,227,57,67,227,56,66,227,56,66, + 227,56,66,227,56,66,227,56,66,227,56,66,227,56,66,227,56,66,227,57, + 66,227,56,66,228,59,69,246,192,195,255,255,255,252,249,249,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,255,254,254,255,255,255,251,229,230, + 242,161,166,242,162,167,242,163,167,242,162,167,242,162,167,242,162,167,242,162, + 167,242,162,167,242,162,167,242,162,167,242,163,168,241,158,163,248,207,209,255, + 255,255,255,254,254,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,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,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,250,249,252,248,248,252,248,248,252,248,248,252,248,248,252,248,248,252, + 248,248,252,248,248,252,248,248,252,248,248,252,248,248,252,248,248,252,248,248, + 252,249,249,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset52 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,232,229,238,232,229,238,232,229,238,232,229,238, + 232,229,238,232,229,238,232,229,238,232,229,238,232,229,238,232,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,249,249,252,249,249,252, + 250,249,252,250,249,252,250,249,252,250,249,252,250,249,252,250,249,252,250,249, + 252,250,249,252,250,249,252,250,249,252,249,249,252,249,248,250,247,246,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,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,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,255,254,254,255,255,255,246,192,195, + 234,102,110,234,104,111,234,104,111,234,104,111,234,104,111,234,104,111,234,104, + 111,234,104,111,234,104,111,234,104,111,234,105,112,233,99,107,242,161,165,255, + 254,254,255,255,254,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,250,249,255,255,255,248,205,207,228,62,71,237,136,141,239,152,156,238,148, + 153,238,149,154,238,149,154,238,149,154,238,149,154,238,149,154,238,149,154,239, + 150,154,239,150,155,239,150,155,228,66,76,242,161,165,255,255,255,252,249,249, + 238,233,229,254,252,251,254,252,251,238,233,229,252,248,248,255,255,255,240,149, + 154,233,100,107,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,254,255,255,254,255,255,255,255,255, + 239,152,156,233,99,106,255,255,255,252,250,249,238,232,229,254,252,251,254,252, + 251,238,233,229,252,248,248,255,255,255,241,154,159,233,103,110,253,252,253,244, + 237,236,241,236,235,242,236,235,242,236,235,242,236,235,242,236,235,241,236,235, + 242,237,236,251,246,245,252,244,243,254,252,252,239,150,155,234,105,112,255,255, + 255,252,250,249,238,232,229,254,252,251,254,252,251,238,233,229,252,248,248,255, + 255,255,241,153,158,231,100,107,255,255,255,120,108,101,65,51,42,77,63,55, + 75,61,53,75,61,53,76,62,54,72,58,50,87,73,66,239,237,235,254,249, + 248,253,255,255,239,150,155,234,104,111,255,255,255,252,250,249,238,232,229,254, + 252,251,254,252,251,238,233,229,252,248,248,255,255,255,241,153,158,232,101,108, + 254,255,255,218,212,209,203,198,195,206,201,199,206,201,198,206,201,198,206,201, + 198,205,200,197,209,204,202,252,250,249,255,251,250,254,255,255,239,150,155,234, + 104,111,255,255,255,252,250,249,238,232,229,254,252,251,254,252,251,238,233,229, + 252,248,248,255,255,255,241,153,158,233,102,109,253,255,255,252,248,247,253,251, + 250,253,251,250,253,251,250,253,251,250,252,251,250,253,251,250,252,250,249,243, + 240,239,242,237,236,253,255,255,239,150,155,234,104,111,255,255,255,252,250,249, + 238,232,229,254,252,251,254,252,251,238,233,229,252,248,248,255,255,255,241,153, + 158,231,100,107,255,255,255,119,107,100,63,50,41,75,61,54,73,59,52,73, + 59,52,73,60,52,73,59,52,75,61,53,72,59,51,86,71,64,242,253,251, + 242,153,158,233,103,110,255,255,255,252,250,249,238,232,229,254,252,251,254,252, + 251,238,233,229,252,248,248,255,255,255,241,153,158,232,101,108,253,254,254,215, + 208,206,200,194,191,203,197,194,203,197,194,203,197,194,203,197,194,203,197,194, + 203,197,194,202,196,193,206,197,194,251,254,253,240,150,155,234,104,111,255,255, + 255,252,250,249,238,232,229,254,252,251,254,252,251,238,233,229,252,248,248,255, + 255,255,241,153,158,233,103,110,253,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,239,151,156,234,104,111,255,255,255,252,250,249,238,232,229,254, + 252,251,254,252,251,238,233,229,252,248,248,255,255,255,241,154,159,233,99,106, + 251,243,244,249,235,234,248,236,235,248,236,236,248,236,236,248,236,236,248,236, + 236,248,236,236,248,236,236,248,236,236,248,233,233,252,243,244,238,144,150,234, + 105,112,255,255,255,252,250,249,238,232,229,254,252,251,254,252,251,238,233,229, + 252,248,248,255,255,255,242,162,167,227,59,69,231,85,93,230,82,90,230,82, + 90,230,82,90,230,82,90,230,82,90,230,82,90,230,82,90,230,82,90,230, + 82,90,230,81,90,231,84,92,229,66,75,236,116,123,255,255,255,252,250,249, + 238,232,229,254,252,251,254,252,251,238,233,229,252,248,248,255,255,255,242,162, + 167,227,56,66,229,70,79,229,67,76,229,67,76,229,67,76,229,67,76,229, + 67,76,229,67,76,229,67,76,229,67,76,229,67,76,229,67,76,229,69,78, + 228,59,69,236,118,125,255,255,255,252,250,249,238,232,229,254,252,251,254,252, + 251,238,233,229,252,248,248,255,255,255,242,162,167,227,53,63,230,78,87,230, + 74,83,230,74,83,230,74,83,230,74,83,230,74,83,230,74,83,230,74,83, + 230,74,83,230,74,83,230,74,83,230,77,85,228,60,70,236,114,122,255,255, + 255,252,250,249,238,232,229,254,252,251,254,252,251,238,233,229,252,250,250,255, + 255,255,251,225,227,230,79,87,227,53,63,227,57,67,227,56,66,227,56,66, + 227,56,66,227,56,66,227,56,66,227,56,66,227,56,66,227,56,66,227,57, + 66,227,56,66,228,59,69,246,192,195,255,255,255,252,249,249,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,255,254,254,255,255,255,251,229,230, + 242,161,166,242,162,167,242,163,167,242,162,167,242,162,167,242,162,167,242,162, + 167,242,162,167,242,162,167,242,162,167,242,163,168,241,158,163,248,207,209,255, + 255,255,255,254,254,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,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,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,250,249,252,248,248,252,248,248,252,248,248,252,248,248,252,248,248,252, + 248,248,252,248,248,252,248,248,252,248,248,252,248,248,252,248,248,252,248,248, + 252,249,249,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset53 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,255,255,255,255,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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, + 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,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,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,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, + 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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset54 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,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,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,251,251,255,255,255,254,254,254,246,245,244,245,244,243,245,244,244,245,244, + 244,245,244,244,245,244,244,245,244,244,245,244,243,246,245,244,254,254,254,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,251,251,250,255,255,255,243,242, + 242,87,75,67,73,59,51,77,63,55,76,62,54,76,62,54,76,62,54,77, + 63,55,73,59,51,87,75,67,243,242,242,255,255,255,254,254,254,255,255,255, + 255,255,255,255,255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,255,255,255,252,251,251,207,203,201,202,198,196,204, + 200,197,203,199,197,203,199,197,203,199,197,204,200,197,202,198,196,207,203,201, + 250,250,250,253,253,253,253,253,253,253,253,253,255,255,255,255,255,255,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,251,251,250,255,255,255,245,244,244,113,102,95, + 100,89,82,104,92,86,103,91,85,103,91,85,103,91,85,103,91,85,103,91, + 85,103,91,85,105,94,87,105,94,87,107,95,89,99,86,80,217,213,212,255, + 255,255,253,254,254,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 251,251,250,255,255,255,248,248,248,157,150,145,149,141,136,151,143,139,151,143, + 138,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138,151, + 143,138,151,143,139,148,140,136,229,227,226,255,255,255,254,254,254,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,251,251,250,255,255,255,248,248,248,157,150,145,149,141,136,151, + 143,139,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138, + 151,143,138,152,144,139,146,138,133,226,223,222,254,254,254,254,254,253,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,251,251,250,255, + 255,255,245,244,244,113,103,95,101,90,82,104,93,85,103,92,84,103,92,84, + 103,92,84,103,92,84,103,92,84,103,92,84,103,92,84,105,94,86,97,85, + 77,214,212,209,253,253,252,253,253,252,255,255,255,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,255,255,255,252,253,251,214,222,202,210,220,197,211,220,198,211,220, + 198,211,220,198,211,220,198,211,220,198,211,220,198,211,220,198,211,220,198,211, + 220,198,211,220,198,213,222,200,211,221,197,244,246,241,255,255,255,252,251,250, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,250,255,255,255,243,245, + 239,78,116,23,63,104,2,67,108,8,66,107,7,66,107,7,66,107,7,66, + 107,7,66,107,7,66,107,7,66,107,7,66,107,7,66,107,7,68,108,9, + 57,100,0,207,217,191,255,255,255,250,250,248,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,250,255,255,255,247,248,244,137,162,100,127,154,86,129, + 157,90,129,156,89,129,156,89,129,156,89,129,156,89,129,156,89,129,156,89, + 129,156,89,129,156,89,129,156,89,130,157,91,123,151,82,223,229,212,255,255, + 255,250,250,249,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,252,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,255,255,255,255,255,255,253,254,253, + 253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254, + 253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,254, + 254,254,255,255,255,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,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,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset55 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,255,255,255,255,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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, + 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,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,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,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, + 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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset56 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 255,253,252,253,251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249, + 246,244,249,246,244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252, + 253,251,250,253,251,250,253,251,249,254,253,252,246,242,240,237,231,227,239,234, + 230,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,230,237,231,227,246,242,240,254,253,252,253,251,249,255,253, + 252,246,242,240,238,232,229,252,251,250,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,252,251, + 250,238,232,229,246,242,240,255,253,252,253,251,250,237,231,227,253,252,252,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,253,252,252,237,231,227,253, + 251,250,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 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,254,253,253,254,252,252,254, + 253,253,254,253,252,254,252,252,255,254,254,255,255,255,255,255,255,255,255,255, + 239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,255,255,255,255,254, + 254,255,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 254,253,254,253,253,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,254,254,255,255,255,255,255,255,239,234,231,249,246,244,249,246, + 244,239,234,231,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,254,255,255,255,255,255,255,243,221,214, + 225,169,153,214,138,117,218,149,131,233,191,180,252,248,246,255,255,255,255,254, + 253,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,255, + 255,255,249,238,235,247,231,227,255,255,255,255,254,254,255,255,255,255,254,254, + 255,255,255,244,222,216,221,159,141,193,77,45,192,74,42,198,92,64,196,85, + 54,190,68,35,204,109,83,245,225,220,255,255,255,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,255,255,255,253,250,250,208,118,94,205,110,85, + 254,252,251,255,254,254,254,254,253,253,253,252,247,236,233,200,101,74,191,75, + 43,213,138,117,240,216,210,251,244,242,248,235,232,231,185,173,196,86,56,201, + 101,74,249,238,235,255,255,255,239,233,230,249,246,244,249,246,244,239,232,228, + 255,255,255,233,192,181,190,67,34,226,172,157,255,254,254,254,253,253,255,254, + 253,255,255,255,254,237,233,205,96,67,202,86,55,248,220,213,255,255,255,255, + 255,255,255,255,255,255,255,255,238,207,198,191,70,38,222,159,142,255,255,255, + 239,232,228,249,246,244,249,245,244,239,233,229,255,255,255,212,132,111,199,94, + 65,253,248,247,255,255,255,255,254,254,252,250,250,220,217,215,199,161,150,170, + 77,51,169,76,49,191,136,120,216,211,209,246,244,243,255,254,254,253,252,251, + 255,255,255,208,121,96,202,103,76,254,251,250,240,236,232,249,245,243,249,245, + 244,239,234,230,255,255,255,205,114,89,205,113,88,255,255,255,254,254,254,255, + 255,255,243,242,241,80,64,53,64,45,32,70,55,45,69,55,44,68,50,38, + 64,45,34,217,213,211,255,255,255,252,251,250,255,254,253,217,145,125,197,88, + 59,253,247,246,240,237,235,249,245,243,249,246,244,239,233,229,255,255,255,213, + 135,114,198,91,62,252,246,244,254,253,253,254,252,252,252,250,249,229,225,224, + 208,169,157,177,78,51,176,78,50,200,146,130,227,225,223,249,247,246,255,255, + 255,254,254,254,255,255,255,207,117,93,203,105,79,254,251,251,239,235,232,249, + 245,244,249,246,244,239,232,228,255,255,255,235,196,186,190,67,33,225,169,154, + 255,255,255,255,255,255,255,255,255,255,255,255,255,247,245,205,100,72,199,82, + 51,244,211,203,255,255,255,255,254,254,254,253,253,255,255,255,233,193,182,191, + 69,36,223,164,148,255,255,255,239,232,228,249,246,244,249,246,244,239,234,231, + 255,255,255,254,252,252,213,133,112,191,71,38,221,159,142,244,222,216,249,238, + 235,241,216,209,216,146,127,193,79,49,198,92,64,245,229,225,253,253,253,254, + 253,253,254,253,253,254,253,253,213,135,113,201,100,72,250,242,239,255,255,255, + 239,233,230,249,246,244,249,246,244,239,234,231,255,255,255,255,254,254,252,246, + 244,214,138,118,191,71,38,193,76,45,196,86,56,192,74,42,192,74,42,218, + 150,131,245,225,220,255,255,255,255,255,254,255,255,255,255,254,254,255,255,255, + 250,241,239,248,234,230,255,255,255,255,255,255,239,234,231,249,246,244,249,246, + 244,239,234,231,255,255,255,255,254,254,255,255,255,255,255,255,240,211,203,224, + 167,151,217,148,129,226,172,157,242,218,212,255,255,255,255,255,255,255,254,254, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,254, + 254,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,255, + 255,255,255,254,254,255,254,254,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,254,254,255,254,253,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,254,254,255,254,254,255,255,255,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,255,255,255,255,255,255,255,255,255,255,255,255, + 254,253,253,254,252,252,254,253,252,254,252,252,254,253,253,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,239,234,231,249,246,244,253,251,250,237,231,227, + 253,252,252,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,253,252,252, + 237,231,227,253,251,250,255,253,252,246,242,240,238,232,229,252,251,250,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,252,251,250,238,232,229,246,242,240,255,253,252,253,251, + 249,254,253,252,246,242,240,237,231,227,239,234,230,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,230,237,231, + 227,246,242,240,254,253,252,253,251,249,253,251,250,253,251,250,255,253,252,253, + 251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244, + 249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252,253,251,250,253, + 251,250 + ); + CEditorAsset57 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,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,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,255,255,255,254,254,254,255,255,255, + 255,255,255,255,255,255,253,253,253,252,251,251,252,252,251,252,251,251,252,251, + 251,252,251,251,252,251,251,252,251,251,252,252,251,252,251,251,253,252,252,255, + 255,255,255,255,255,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,251,252,255,255,255,255,255,255,254,254,253,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,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,251,251,249,255,255,255,237,241, + 231,106,138,59,135,160,98,255,255,255,204,200,198,146,138,133,155,148,144,154, + 146,141,154,146,141,154,146,141,154,146,141,154,146,141,155,147,143,148,140,135, + 180,174,171,255,255,255,254,254,254,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,251,250,249,255,255,255,228,233,219,73,112,16,104,135,56,255, + 255,255,181,175,172,93,81,74,108,96,90,105,94,87,105,94,87,105,94,87, + 105,94,87,105,94,87,107,95,89,97,85,78,144,135,131,255,255,255,254,254, + 254,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255, + 255,254,255,255,255,228,234,219,239,242,234,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,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,255,255,255,254,254,254,255,255,255, + 255,255,255,255,255,255,253,253,253,250,249,249,250,250,250,250,250,250,250,250, + 250,250,250,250,250,250,250,250,250,250,250,250,250,250,249,249,251,251,251,255, + 255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,255,255,255,255,255,255,252,253,251,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,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,251,251,250,255,255,255,237,241, + 231,106,138,59,135,160,98,255,255,255,204,200,198,146,138,133,155,148,144,154, + 146,141,154,146,141,154,146,141,154,146,141,154,146,141,155,147,143,148,140,135, + 180,174,171,255,255,255,254,254,254,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,251,250,249,255,255,255,228,233,219,73,112,16,104,135,56,255, + 255,255,181,175,172,93,81,74,108,96,90,105,94,87,105,94,87,105,94,87, + 105,94,87,105,94,87,107,95,89,97,85,78,144,135,131,255,255,255,254,254, + 254,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255, + 255,254,255,255,255,228,234,219,239,242,234,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,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,255,255,255,254,254,254,255,255,255, + 255,255,255,255,255,255,253,253,253,250,249,249,250,250,250,250,250,250,250,250, + 250,250,250,250,250,250,250,250,250,250,250,250,250,250,249,249,251,251,251,255, + 255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,255,255,255,255,255,255,252,253,251,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,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,251,251,250,255,255,255,237,241, + 231,106,138,59,135,160,98,255,255,255,204,200,198,146,138,133,155,148,144,154, + 146,141,154,146,141,154,146,141,154,146,141,154,146,141,155,147,143,148,140,135, + 180,174,171,255,255,255,254,254,254,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,251,250,249,255,255,255,228,233,219,73,112,16,104,135,56,255, + 255,255,181,175,172,93,81,74,108,96,90,105,94,87,105,94,87,105,94,87, + 105,94,87,105,94,87,107,95,89,97,85,78,144,135,131,255,255,255,254,254, + 254,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,252,255, + 255,254,255,255,255,228,234,220,239,243,234,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,252,251,251,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,255,255,255,254,254,254,255,255,255, + 255,255,255,255,255,255,254,254,254,253,253,253,253,253,253,253,253,253,253,253, + 253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,254,253,253,255, + 255,255,255,255,255,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,255,255,255,255,255,255,254,255,254,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,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset58 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,232,229,238,232,229,238,232,229,238,232,229,238, + 232,229,238,232,229,238,232,229,238,232,229,238,232,229,238,232,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,252,252,241,236,233,239,234,231,247,246,244,251,249,249,251,249,249,251, + 250,249,251,250,249,251,250,249,251,250,249,251,250,249,251,250,249,251,250,249, + 251,250,249,251,250,249,251,250,249,251,249,249,251,250,249,247,246,244,239,233, + 231,241,236,233,254,252,252,253,251,250,255,253,252,246,243,240,239,235,231,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,239,234,231,246,243,240,255, + 253,252,255,253,252,239,233,230,250,249,248,252,252,252,149,141,136,104,93,86, + 112,101,96,110,98,93,110,98,93,110,98,93,110,98,93,110,98,93,110,98, + 93,110,98,93,110,98,93,110,98,93,110,98,93,111,100,94,108,97,91,123, + 113,108,240,238,238,251,251,249,238,233,229,255,253,252,254,252,251,235,229,226, + 255,255,255,169,163,159,105,92,84,198,193,188,190,180,175,195,191,182,195,192, + 183,195,191,183,195,192,183,195,192,183,195,192,183,195,192,183,195,192,183,195, + 191,183,196,192,183,192,185,178,199,192,187,136,125,117,124,115,109,255,255,255, + 236,230,227,254,252,251,254,252,251,235,229,226,255,255,255,147,140,136,152,141, + 134,255,255,255,255,248,244,241,209,221,239,206,218,239,207,219,239,206,219,239, + 206,219,239,206,219,239,206,219,239,206,219,240,207,219,238,203,216,247,228,232, + 255,255,255,201,192,186,109,98,92,255,255,255,237,231,227,254,252,251,254,252, + 251,235,229,226,255,255,255,152,145,141,143,131,125,253,253,253,204,143,172,174, + 65,123,181,80,133,180,78,132,180,78,132,180,78,132,180,78,132,180,78,132, + 180,78,132,180,79,133,178,75,130,180,81,133,245,226,232,192,185,177,112,101, + 95,255,255,255,237,231,227,254,252,251,254,252,251,235,229,226,255,255,255,151, + 144,140,145,132,126,255,255,255,186,96,142,212,152,184,251,245,248,250,242,246, + 251,245,248,251,245,248,251,245,248,251,245,248,251,244,247,251,245,248,247,237, + 242,178,74,130,238,203,217,195,192,183,111,99,94,255,255,255,237,231,227,254, + 252,251,254,252,251,235,229,226,255,255,255,151,144,140,145,132,126,255,255,255, + 188,102,146,215,159,188,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,252,248,250,180,79,133,239,207,219,195, + 191,183,111,99,94,255,255,255,237,231,227,254,252,251,254,252,251,235,229,226, + 255,255,255,151,144,140,145,132,126,255,255,255,188,101,145,214,157,187,255,254, + 254,254,251,252,255,254,254,255,254,254,255,254,254,255,254,254,255,253,253,255, + 254,254,251,244,247,180,78,132,239,206,219,195,191,183,111,99,94,255,255,255, + 237,231,227,254,252,251,254,252,251,235,229,226,255,255,255,151,144,140,145,132, + 126,255,255,255,188,101,145,214,157,187,255,255,255,254,252,253,255,255,255,255, + 255,255,255,255,255,255,255,255,255,254,254,255,255,255,251,245,248,180,78,132, + 239,206,219,195,191,183,111,99,94,255,255,255,237,231,227,254,252,251,254,252, + 251,235,229,226,255,255,255,151,144,140,145,132,126,255,255,255,188,101,145,214, + 157,187,255,255,255,254,252,253,255,255,255,255,255,255,255,255,255,255,255,255, + 255,254,254,255,255,255,251,245,248,180,78,132,239,206,219,195,191,183,111,99, + 94,255,255,255,237,231,227,254,252,251,254,252,251,235,229,226,255,255,255,151, + 144,140,145,132,126,255,255,255,188,101,145,214,156,186,254,253,254,253,250,252, + 254,253,254,254,253,254,254,253,254,254,253,254,254,252,253,254,253,254,250,243, + 247,180,78,132,239,206,219,195,191,183,111,99,94,255,255,255,237,231,227,254, + 252,251,254,252,251,235,229,226,255,255,255,151,144,140,145,132,126,255,255,255, + 188,102,145,216,163,191,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,181,80,133,239,206,219,195, + 191,183,111,99,94,255,255,255,237,231,227,254,252,251,254,252,251,235,229,226, + 255,255,255,151,144,140,145,132,126,255,255,255,187,98,143,203,130,169,235,207, + 222,234,204,220,235,206,221,235,206,221,235,206,221,235,206,221,235,206,221,235, + 206,221,232,200,217,176,68,126,239,204,218,195,192,183,111,99,94,255,255,255, + 237,231,227,254,252,251,254,252,251,235,229,226,255,255,255,152,146,142,144,131, + 125,252,252,251,215,170,189,177,75,128,179,77,130,178,76,129,178,75,129,178, + 75,129,178,75,129,178,75,129,178,75,129,178,77,130,176,71,126,190,107,149, + 248,236,238,191,182,176,113,102,97,255,255,255,237,231,227,254,252,251,254,252, + 251,235,229,226,255,255,255,145,137,133,150,139,132,255,255,255,255,255,253,255, + 248,247,255,247,247,255,247,247,255,247,247,255,247,247,255,247,247,255,247,247, + 255,247,247,255,247,247,255,245,246,255,254,250,255,255,255,201,192,187,105,94, + 87,255,255,255,237,231,227,254,252,251,254,252,251,236,230,227,255,255,255,191, + 186,183,93,79,71,148,139,133,144,132,126,146,136,129,146,137,129,146,137,129, + 146,137,129,146,137,129,146,137,129,146,137,129,146,137,129,146,136,129,147,137, + 129,144,133,126,150,140,134,105,92,84,150,142,138,255,255,255,236,230,227,254, + 252,251,255,253,252,239,234,230,250,248,247,255,255,255,191,186,183,144,136,131, + 152,144,140,150,142,138,150,142,138,150,142,138,150,142,138,150,142,138,150,142, + 138,150,142,138,150,142,138,150,142,138,150,142,138,151,143,139,147,139,135,168, + 161,157,255,255,255,251,250,249,239,233,230,255,253,252,255,253,252,246,243,240, + 240,235,231,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,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,247,245, + 244,249,248,247,249,248,247,249,248,247,249,248,247,249,248,247,249,248,247,249, + 248,247,249,248,247,249,248,247,249,248,247,249,248,247,249,248,247,249,248,247, + 249,248,247,247,245,243,239,234,231,241,236,233,254,252,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset59 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 255,253,252,253,251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249, + 246,244,249,246,244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252, + 253,251,250,253,251,250,253,251,249,254,253,252,246,242,240,237,231,227,239,234, + 230,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,230,237,231,227,246,242,240,254,253,252,253,251,249,255,253, + 252,246,242,240,238,232,229,252,251,250,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,252,251, + 250,238,232,229,246,242,240,255,253,252,253,251,250,237,231,227,253,252,252,255, + 255,255,255,255,255,255,255,255,254,254,254,252,253,252,253,253,252,253,254,253, + 253,253,252,253,253,252,254,254,254,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,253,252,252,237,231,227,253, + 251,250,249,246,244,239,234,231,255,255,255,255,255,255,255,255,255,254,254,254, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,254,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 255,255,255,255,255,255,254,254,254,255,255,255,255,255,255,189,210,168,133,171, + 94,118,161,75,135,173,97,194,213,174,255,255,255,255,255,255,254,254,254,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,254,254,253,255,255, + 255,232,240,225,113,158,68,87,140,34,134,172,95,153,185,121,131,170,91,85, + 139,31,119,162,76,237,243,232,254,254,254,251,252,250,253,254,253,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,239,234,231,249,246,244,249,246, + 244,239,234,231,255,255,255,254,254,254,246,249,244,102,150,54,114,158,70,240, + 245,235,255,255,255,255,255,255,255,255,255,233,240,227,110,156,64,113,158,68, + 255,255,255,255,255,255,255,255,255,254,255,254,254,254,254,255,255,255,255,255, + 255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231,254,255,254,255, + 255,255,165,193,136,93,144,42,248,250,246,255,255,255,252,253,251,252,253,252, + 251,252,250,255,255,255,222,233,212,78,133,22,136,175,98,161,191,132,207,222, + 192,255,255,255,255,255,255,254,254,254,255,255,255,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,255,255,255,253,254,253,103,151,55,172,198,146, + 255,255,255,251,252,250,255,255,255,253,254,253,255,255,255,173,199,147,89,140, + 36,98,147,49,87,136,36,108,152,62,81,136,27,123,164,82,235,241,228,255, + 255,255,254,254,253,255,255,255,239,234,231,249,246,244,249,246,244,238,234,230, + 255,255,255,239,244,233,88,141,35,212,226,199,254,255,254,253,254,252,253,254, + 252,255,255,255,167,195,139,68,127,10,202,220,184,213,236,196,68,82,27,230, + 219,229,244,253,238,110,154,65,98,148,49,242,246,237,254,254,253,255,255,255, + 239,234,231,249,246,244,249,246,244,238,234,230,255,255,255,242,246,237,90,142, + 38,207,222,191,254,254,253,251,252,250,255,255,255,223,233,212,75,131,19,201, + 220,183,241,235,240,120,110,98,67,55,37,95,80,70,188,180,179,255,255,254, + 99,148,50,148,181,114,255,255,255,254,255,254,239,234,231,249,246,244,249,246, + 244,239,234,231,254,255,254,255,255,255,113,158,68,154,186,122,255,255,255,248, + 250,246,255,255,254,152,184,120,117,162,73,249,245,249,103,83,82,86,110,45, + 74,87,34,189,178,181,99,87,74,191,180,183,208,228,191,86,139,33,245,248, + 242,255,255,255,238,234,230,249,246,244,249,246,244,239,234,231,254,255,254,255, + 255,255,188,210,167,79,134,23,227,235,217,255,255,255,255,255,255,112,158,68, + 164,194,136,255,253,255,177,190,158,97,157,43,90,98,56,232,225,230,224,222, + 218,112,97,91,244,250,239,87,140,34,214,226,201,255,255,255,238,233,228,249, + 246,244,249,246,244,239,234,231,255,255,255,253,254,253,255,255,255,133,172,95, + 85,138,30,204,220,188,254,254,253,117,160,73,163,192,133,207,218,193,83,120, + 35,170,207,139,156,143,141,222,219,217,221,218,215,113,98,93,247,251,243,87, + 140,35,211,224,197,255,255,255,238,233,228,249,246,244,249,246,244,239,234,231, + 255,255,255,254,254,254,254,254,253,250,252,249,155,186,123,82,136,27,99,148, + 50,91,143,40,92,145,40,100,146,53,77,67,47,173,164,160,147,136,130,168, + 159,154,98,85,73,196,186,188,215,232,201,85,138,31,242,246,237,255,255,255, + 238,234,230,249,246,244,249,246,244,239,234,231,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,229,237,220,178,202,154,158,188,127,75,131,19,196, + 217,176,248,243,248,133,123,114,71,55,42,94,80,69,196,189,187,255,255,255, + 111,156,66,136,173,98,255,255,255,254,255,254,239,234,231,249,246,244,249,246, + 244,239,234,231,255,255,255,255,255,255,255,255,255,255,255,254,253,254,253,255, + 255,255,255,255,255,255,255,255,150,183,117,83,136,28,212,227,198,255,255,255, + 198,187,191,239,234,238,255,255,253,129,168,90,86,139,33,234,240,227,254,254, + 254,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,254,254,253,252,253,251,252,253,251, + 253,253,252,152,185,120,80,135,25,110,155,64,150,186,115,132,172,92,87,139, + 34,105,152,58,221,232,211,255,255,255,254,254,253,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,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,219,230, + 208,154,186,122,127,166,87,137,174,100,187,208,165,253,253,252,255,255,255,254, + 254,253,255,255,255,255,255,255,239,234,231,249,246,244,253,251,250,237,231,227, + 253,252,252,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,254,254,254,253,254,252,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,253,254,253,255,255,255,255,255,255,253,252,252, + 237,231,227,253,251,250,255,253,252,246,242,240,238,232,229,252,251,250,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,254,255,253,254,255,254,254,255,254,254,255,254,255,255,255, + 255,255,255,255,255,255,252,251,250,238,232,229,246,242,240,255,253,252,253,251, + 249,254,253,252,246,242,240,237,231,227,239,234,230,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,230,237,231, + 227,246,242,240,254,253,252,253,251,249,253,251,250,253,251,250,255,253,252,253, + 251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244, + 249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252,253,251,250,253, + 251,250 + ); + CEditorAsset60 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,0,0,0,0,0,0,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, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,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, + 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,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,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,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,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,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,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,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset61 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,0,0,0,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,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 + ); + CEditorAsset62 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 255,253,252,253,251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249, + 246,244,249,246,244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252, + 253,251,250,253,251,250,253,251,249,254,253,252,246,242,240,237,231,227,239,234, + 230,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,230,237,231,227,246,242,240,254,253,252,253,251,249,255,253, + 252,246,242,240,238,232,229,252,251,250,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,252,251, + 250,238,232,229,246,242,240,255,253,252,253,251,250,237,231,227,253,252,252,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,253,252,252,237,231,227,253, + 251,250,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 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,255,255,255,255,255, + 239,234,231,249,246,244,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249,246,244,249,246, + 244,239,234,231,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,255, + 255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,255,255,255,255,255,255,255,254,254,254,253,252, + 254,253,252,255,254,254,255,255,255,255,255,255,254,254,254,253,253,253,254,254, + 254,255,255,255,255,255,255,255,255,255,254,253,253,253,253,253,254,254,254,255, + 255,255,255,255,255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 255,255,255,255,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255,254, + 254,254,254,254,255,255,255,255,255,255,255,255,255,255,254,254,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,254,254,254,255,255,255,255,255,255, + 239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,255,255,255,252,248, + 247,231,187,175,231,187,175,253,248,247,255,255,255,255,255,255,235,233,231,203, + 195,190,223,219,216,255,255,255,254,254,254,255,255,255,218,213,210,204,197,192, + 241,239,238,255,255,255,254,254,254,255,255,255,239,234,231,249,246,244,249,246, + 244,239,233,230,255,255,255,250,240,236,213,134,113,224,165,149,224,165,149,211, + 132,111,254,245,243,220,216,214,171,157,149,203,195,190,180,167,159,197,188,183, + 254,254,254,187,177,170,186,174,166,202,193,189,170,157,149,228,225,222,255,255, + 255,255,255,255,239,234,231,249,246,244,249,246,244,239,232,228,255,255,255,223, + 163,147,231,184,170,255,255,255,255,255,255,233,185,172,219,159,143,177,172,167, + 246,239,236,255,255,255,255,255,255,185,173,166,194,185,180,191,180,173,255,255, + 255,255,255,255,236,228,225,176,164,157,253,253,253,255,255,255,239,234,231,249, + 246,244,249,246,244,239,232,228,255,255,255,217,146,127,244,220,212,255,255,255, + 255,255,255,248,223,216,204,131,111,181,176,171,255,255,255,253,247,244,255,255, + 255,203,193,188,166,153,146,215,206,201,255,255,255,254,249,247,255,251,249,175, + 162,154,251,251,250,255,255,255,239,234,231,249,246,244,249,246,244,239,232,229, + 255,255,255,236,200,190,215,137,116,249,238,234,249,238,234,214,136,115,240,205, + 196,188,184,180,205,193,187,251,249,248,225,218,213,175,163,155,231,228,226,172, + 159,150,233,228,224,250,248,247,194,183,176,195,186,181,255,255,255,255,255,255, + 239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,255,255,255,232,189, + 177,213,134,112,213,134,112,231,188,177,255,255,255,249,247,247,188,178,172,173, + 161,154,179,167,160,235,232,230,255,255,255,227,223,221,176,164,157,174,161,154, + 195,186,181,253,253,253,254,254,254,255,255,255,239,234,231,249,246,244,249,246, + 244,239,234,231,255,255,255,255,254,254,255,255,255,254,253,253,254,253,253,255, + 255,255,254,254,254,255,255,255,255,255,255,251,250,250,255,255,255,255,255,255, + 254,254,254,255,255,255,255,255,255,251,251,250,255,255,255,255,255,255,255,255, + 255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,255, + 255,255,254,253,253,255,255,255,255,255,255,254,253,253,255,255,255,255,255,255, + 254,254,253,255,255,255,254,254,254,254,254,254,255,255,255,254,254,254,255,255, + 255,255,255,255,254,253,253,255,255,255,255,255,255,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249,246,244,253,251,250,237,231,227, + 253,252,252,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,253,252,252, + 237,231,227,253,251,250,255,253,252,246,242,240,238,232,229,252,251,250,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,252,251,250,238,232,229,246,242,240,255,253,252,253,251, + 249,254,253,252,246,242,240,237,231,227,239,234,230,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,230,237,231, + 227,246,242,240,254,253,252,253,251,249,253,251,250,253,251,250,255,253,252,253, + 251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244, + 249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252,253,251,250,253, + 251,250 + ); + CEditorAsset63 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 255,253,252,253,251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249, + 246,244,249,246,244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252, + 253,251,250,253,251,250,253,251,249,254,253,252,246,242,240,237,231,227,239,234, + 230,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,230,237,231,227,246,242,240,254,253,252,253,251,249,255,253, + 252,246,242,240,238,232,229,252,251,250,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,252,251, + 250,238,232,229,246,242,240,255,253,252,253,251,250,237,231,227,253,252,252,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,253,252,252,237,231,227,253, + 251,250,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 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,255,255,255,255,255, + 239,234,231,249,246,244,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249,246,244,249,246, + 244,239,234,231,255,255,255,254,254,254,254,253,253,254,254,253,254,253,253,254, + 253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253, + 254,253,253,254,253,253,254,253,253,254,253,253,254,254,253,254,253,253,254,254, + 254,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249, + 246,244,249,246,244,239,233,230,255,255,255,232,228,226,215,208,204,218,211,208, + 218,211,207,218,211,207,218,213,209,218,212,209,217,211,208,217,211,208,217,211, + 208,217,212,208,218,213,210,217,211,208,217,211,208,217,211,208,217,212,208,215, + 209,206,239,237,235,255,255,255,239,233,230,249,246,244,249,246,244,238,233,230, + 255,255,255,218,215,212,196,195,192,201,201,198,200,200,197,200,200,197,196,189, + 184,200,192,186,205,198,193,204,197,192,205,197,193,202,194,190,196,187,182,203, + 195,191,205,197,193,204,197,192,206,199,194,195,186,180,229,225,222,255,255,255, + 238,233,230,249,246,244,249,246,244,239,234,231,255,255,255,255,249,247,240,195, + 183,239,193,181,239,193,181,238,193,181,255,255,255,240,240,239,212,206,202,217, + 212,208,214,207,204,228,224,222,255,255,255,223,218,215,214,208,205,216,211,208, + 213,207,203,246,244,244,255,255,255,255,255,255,239,234,231,249,246,244,249,246, + 244,239,232,228,255,255,255,220,157,140,218,151,132,228,181,168,228,181,168,221, + 153,135,212,148,130,172,166,161,202,191,185,204,193,187,203,196,191,177,165,157, + 183,173,166,180,167,160,204,197,192,205,194,188,199,188,182,173,160,152,252,251, + 251,255,255,255,239,234,231,249,246,244,249,246,244,239,232,228,255,255,255,218, + 150,132,246,226,219,255,255,255,255,255,255,250,230,224,204,135,116,186,181,176, + 255,255,255,255,255,255,255,255,255,209,199,194,167,155,147,220,212,207,255,255, + 255,255,255,255,255,255,254,180,168,160,251,250,250,255,255,255,239,234,231,249, + 246,244,249,246,244,239,232,228,255,255,255,220,154,136,242,215,206,255,254,254, + 255,254,254,246,218,210,207,140,122,185,180,175,254,250,248,252,246,244,254,254, + 254,204,195,190,172,160,153,214,205,200,254,254,254,253,248,246,250,244,242,180, + 168,160,251,250,250,255,255,255,239,234,231,249,246,244,249,246,244,239,232,228, + 255,255,255,217,146,127,240,208,198,253,249,248,253,249,248,244,211,202,203,131, + 111,179,174,168,251,246,244,249,242,240,251,251,250,199,189,183,165,153,145,209, + 200,194,251,251,250,250,244,242,247,240,238,174,161,153,251,250,250,255,255,255, + 239,234,231,249,246,244,249,246,244,239,232,229,255,255,255,235,198,189,212,131, + 108,216,142,122,216,142,122,212,131,108,235,199,189,193,188,184,174,161,153,180, + 168,161,176,165,157,182,171,164,223,219,216,177,165,158,177,166,159,180,168,161, + 174,161,153,199,190,185,254,254,254,255,255,255,239,234,231,249,246,244,249,246, + 244,239,234,231,255,255,255,255,255,255,254,251,251,253,249,248,253,249,248,253, + 251,250,255,255,255,255,255,255,251,250,250,251,251,251,251,250,250,255,255,255, + 255,255,255,254,254,254,251,250,250,251,251,251,251,250,250,255,255,255,255,255, + 255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,255, + 254,254,255,255,255,255,255,255,255,255,255,255,255,255,254,253,253,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,254,254,254,255,255,255,255,255, + 255,255,255,255,255,255,255,254,254,254,255,255,255,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249,246,244,253,251,250,237,231,227, + 253,252,252,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,253,252,252, + 237,231,227,253,251,250,255,253,252,246,242,240,238,232,229,252,251,250,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,252,251,250,238,232,229,246,242,240,255,253,252,253,251, + 249,254,253,252,246,242,240,237,231,227,239,234,230,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,230,237,231, + 227,246,242,240,254,253,252,253,251,249,253,251,250,253,251,250,255,253,252,253, + 251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244, + 249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252,253,251,250,253, + 251,250 + ); + CEditorAsset64 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 255,253,252,253,251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249, + 246,244,249,246,244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252, + 253,251,250,253,251,250,253,251,249,254,253,252,246,242,240,237,231,227,239,234, + 230,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,230,237,231,227,246,242,240,254,253,252,253,251,249,255,253, + 252,246,242,240,238,232,229,252,251,250,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,252,251, + 250,238,232,229,246,242,240,255,253,252,253,251,250,237,231,227,253,252,252,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,253,252,252,237,231,227,253, + 251,250,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 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,255,255,255,255,255, + 239,234,231,249,246,244,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249,246,244,249,246, + 244,239,234,231,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,255, + 255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,255, + 255,255,255,254,254,255,255,254,255,254,254,255,254,254,255,254,254,255,254,254, + 255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254, + 254,255,254,254,255,255,254,255,254,254,255,255,255,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,255,255,255,255,254,254,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,254,255,254,254,239,234,231,249,246,244,249,246,244,239,233,230, + 255,255,255,255,255,255,253,250,249,254,251,250,253,250,250,253,251,250,253,251, + 250,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,253, + 251,250,253,251,250,253,251,250,254,251,250,253,249,248,255,255,255,255,255,255, + 239,233,230,249,246,244,249,245,243,240,235,232,253,248,247,216,143,123,201,99, + 72,203,105,78,203,105,78,202,103,76,203,105,78,203,105,78,203,105,78,203, + 105,78,203,105,78,203,105,78,203,105,78,203,105,78,203,105,78,203,105,78, + 203,106,79,202,102,75,209,125,101,249,237,234,240,238,235,249,245,243,248,243, + 241,244,246,245,235,193,182,202,101,73,242,217,210,244,220,212,242,215,206,245, + 221,214,242,213,205,242,213,205,239,210,202,239,210,202,239,210,202,239,210,202, + 241,213,205,241,212,204,239,210,202,239,210,202,238,208,199,241,217,211,210,122, + 98,222,158,141,244,249,248,248,243,240,248,243,241,244,247,246,231,184,172,210, + 124,101,255,255,255,225,167,151,207,114,89,236,198,187,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,220,152,134,220,151,133,244,249,248,248, + 243,240,248,243,241,244,247,246,231,185,173,212,129,107,241,211,203,191,73,41, + 196,85,56,197,89,60,253,238,233,243,238,236,142,128,121,138,124,116,140,127, + 119,132,118,110,233,226,222,210,201,197,129,115,107,143,130,122,129,114,105,200, + 198,195,227,157,137,218,151,133,244,249,248,248,243,240,248,243,241,244,247,246, + 231,186,174,211,126,103,246,226,220,196,87,58,191,71,39,206,113,88,254,244, + 241,246,239,236,174,162,156,171,159,153,173,161,155,167,155,148,239,231,228,223, + 214,210,165,152,146,175,163,157,165,151,144,216,213,211,225,154,135,219,152,134, + 244,249,248,248,243,240,248,243,241,244,248,247,231,182,170,209,122,97,255,255, + 255,246,225,219,230,180,166,253,246,243,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,220,152,134,219,148,129,244,249,249,248,243,240,248,244, + 242,242,242,240,241,213,206,199,94,65,218,148,128,221,156,137,223,162,144,220, + 152,134,219,148,129,219,149,129,216,146,126,216,146,126,216,146,126,216,145,126, + 218,148,129,218,147,128,216,145,126,216,146,126,215,145,125,218,150,131,201,98, + 69,231,184,171,243,246,244,248,243,241,249,246,244,239,233,230,255,255,255,236, + 199,190,217,147,127,219,151,132,218,148,130,218,150,132,219,151,133,219,151,133, + 219,151,133,219,151,133,219,151,133,219,151,133,219,151,133,219,151,133,219,151, + 133,219,151,133,219,152,134,217,147,128,230,183,170,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249,246,244,253,251,250,237,231,227, + 253,252,252,255,254,254,254,252,251,254,252,252,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,252,251,255,254,253,253,252,251, + 237,231,227,253,251,250,255,253,252,246,242,240,238,232,229,252,251,250,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,252,251,250,238,232,229,246,242,240,255,253,252,253,251, + 249,254,253,252,246,242,240,237,231,227,239,234,230,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,230,237,231, + 227,246,242,240,254,253,252,253,251,249,253,251,250,253,251,250,255,253,252,253, + 251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244, + 249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252,253,251,250,253, + 251,250 + ); + CEditorAsset65 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 255,253,252,253,251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249, + 246,244,249,246,244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252, + 253,251,250,253,251,250,253,251,249,254,253,252,246,242,240,237,231,227,239,234, + 230,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,230,237,231,227,246,242,240,254,253,252,253,251,249,255,253, + 252,246,242,240,238,232,229,252,251,250,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,252,251, + 250,238,232,229,246,242,240,255,253,252,253,251,250,237,231,227,253,252,252,255, + 255,255,254,254,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254, + 253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253, + 254,253,253,254,252,253,254,254,254,254,255,255,255,253,252,252,237,231,227,253, + 251,250,249,246,244,239,234,231,255,255,255,254,254,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,253,254,255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 254,255,255,255,255,255,250,252,254,203,225,246,205,226,246,205,226,246,205,226, + 246,205,226,246,205,226,246,205,226,246,205,226,246,205,226,246,205,226,246,205, + 226,246,205,226,246,206,226,246,201,223,245,239,246,252,255,255,255,254,255,255, + 239,234,231,249,246,244,249,246,244,238,234,231,254,255,255,236,244,251,78,151, + 223,45,131,217,55,137,218,52,135,217,53,136,218,53,136,218,53,136,218,53, + 136,218,52,135,217,53,136,218,53,136,218,53,136,218,53,136,218,54,136,218, + 50,134,218,56,138,219,215,231,247,255,255,255,238,233,231,249,246,244,249,246, + 244,236,232,230,255,255,255,151,194,236,65,143,221,245,249,253,240,248,254,246, + 254,255,240,247,253,241,248,253,240,247,253,243,250,255,246,253,255,240,247,253, + 241,248,253,240,247,253,244,251,255,241,251,255,249,251,253,102,166,228,105,166, + 227,255,255,255,236,232,230,249,246,244,249,246,244,236,232,230,255,255,255,145, + 190,235,91,158,225,255,255,255,246,251,255,228,230,230,255,255,255,255,255,255, + 255,255,255,244,248,250,231,233,234,255,255,255,255,255,255,255,255,255,240,243, + 244,231,236,238,255,255,255,131,182,232,101,165,227,255,255,255,236,232,230,249, + 246,244,249,246,244,236,232,230,255,255,255,146,191,235,86,156,225,234,231,229, + 188,187,187,119,108,102,224,221,219,214,215,216,224,221,219,176,172,170,129,119, + 113,224,221,219,213,213,214,224,221,219,159,154,150,138,131,127,234,231,229,125, + 178,231,102,165,227,255,255,255,236,232,230,249,246,244,249,246,244,236,232,230, + 255,255,255,145,190,234,91,162,230,175,163,154,113,103,96,94,80,72,135,124, + 117,131,121,115,135,124,117,116,104,97,97,83,74,135,124,117,130,121,114,135, + 124,117,110,98,91,93,80,73,177,164,155,131,185,237,101,164,226,255,255,255, + 236,232,230,249,246,244,249,246,244,236,232,230,255,255,255,146,191,235,84,154, + 222,255,255,255,224,227,230,136,127,121,255,255,255,254,255,255,255,255,255,206, + 206,206,148,141,136,255,255,255,252,255,255,255,255,255,185,183,180,163,159,157, + 255,255,255,123,176,228,102,165,227,255,255,255,236,232,230,249,246,244,249,246, + 244,236,232,230,255,255,255,146,191,235,85,155,224,249,249,248,208,209,210,129, + 120,114,247,246,245,236,239,242,247,246,245,193,191,190,141,132,127,247,246,245, + 234,237,240,247,246,245,174,171,167,153,147,145,250,249,248,124,178,230,102,165, + 227,255,255,255,236,232,230,249,246,244,249,246,244,236,232,230,255,255,255,145, + 190,234,91,162,231,170,158,148,108,97,90,94,79,71,128,116,108,125,114,107, + 128,116,108,112,100,92,96,82,73,128,116,108,124,113,107,128,116,108,107,95, + 87,90,77,70,172,159,149,131,185,237,101,164,226,255,255,255,236,232,230,249, + 246,244,249,246,244,236,232,230,255,255,255,146,191,235,85,155,223,250,250,249, + 207,208,210,121,111,104,249,248,247,237,241,243,249,248,247,191,189,187,134,125, + 119,249,248,247,235,239,241,249,248,247,170,166,162,147,141,138,251,250,249,124, + 177,229,102,165,227,255,255,255,236,232,230,249,246,244,249,246,244,236,232,230, + 255,255,255,146,191,235,88,157,224,255,255,255,227,232,236,181,179,178,251,255, + 255,245,251,254,251,255,255,219,222,223,188,186,186,251,255,255,244,249,253,251, + 255,255,208,209,210,194,195,196,254,255,255,127,180,231,103,166,227,255,255,255, + 236,232,230,249,246,244,249,246,244,236,232,230,255,255,255,144,190,235,77,150, + 223,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,120,176,231,97,162,226,255,255,255,236,232,230,249,246,244,249,246, + 244,238,233,231,254,255,255,220,234,248,55,137,218,68,145,221,77,150,222,73, + 147,220,76,150,223,75,150,223,76,150,223,75,149,222,74,148,221,76,150,223, + 75,150,222,76,150,223,74,148,221,75,148,221,75,149,222,43,130,216,191,217, + 243,255,255,255,237,233,230,249,246,244,249,246,244,239,234,231,254,255,255,255, + 255,255,227,239,250,158,198,237,162,200,238,162,200,238,162,200,238,162,200,238, + 162,200,238,162,200,238,162,200,238,162,200,238,162,200,238,162,200,238,162,200, + 238,163,201,238,156,197,237,210,228,247,255,255,255,254,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,255,255,255,254,254,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,253,254,254,255,255,255,239,234,231,249,246,244,253,251,250,237,231,227, + 253,252,252,255,255,255,253,254,254,251,253,254,251,253,254,251,253,254,251,253, + 254,251,253,254,251,253,254,251,253,254,251,253,254,251,253,254,251,253,254,251, + 253,254,251,253,254,251,253,254,251,253,254,253,253,254,255,255,255,253,252,252, + 237,231,227,253,251,250,255,253,252,246,242,240,238,232,229,252,251,250,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,252,251,250,238,232,229,246,242,240,255,253,252,253,251, + 249,254,253,252,246,242,240,237,231,227,239,234,230,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,230,237,231, + 227,246,242,240,254,253,252,253,251,249,253,251,250,253,251,250,255,253,252,253, + 251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244, + 249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252,253,251,250,253, + 251,250 + ); + CEditorAsset66 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,232,229,238,232,229,238,232,229,238,232,229,238, + 232,229,238,232,229,238,232,229,238,232,229,238,232,229,238,232,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,252,252,241,236,233,239,234,231,247,246,244,251,249,249,251,249,249,251, + 250,249,251,250,249,251,250,249,251,250,249,251,250,249,251,250,249,251,250,249, + 251,250,249,251,250,249,251,250,249,251,249,249,251,250,249,247,246,244,239,233, + 231,241,236,233,254,252,252,253,251,250,255,253,252,246,243,240,239,235,231,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,239,234,231,246,243,240,255, + 253,252,255,253,252,239,233,230,250,249,248,252,252,252,149,141,136,104,93,86, + 112,101,96,110,98,93,110,98,93,110,98,93,110,98,93,110,98,93,110,98, + 93,110,98,93,110,98,93,110,98,93,110,98,93,111,100,94,108,97,91,123, + 113,108,240,238,238,251,251,249,238,233,229,255,253,252,254,252,251,235,229,226, + 255,255,255,169,163,159,105,92,84,198,193,188,190,180,175,195,191,182,195,192, + 183,195,191,183,195,192,183,195,192,183,195,192,183,195,192,183,195,192,183,195, + 191,183,196,192,183,192,185,178,199,192,187,136,125,117,124,115,109,255,255,255, + 236,230,227,254,252,251,254,252,251,235,229,226,255,255,255,147,140,136,152,141, + 134,255,255,255,255,248,244,241,209,221,239,206,218,239,207,219,239,206,219,239, + 206,219,239,206,219,239,206,219,239,206,219,240,207,219,238,203,216,247,228,232, + 255,255,255,201,192,186,109,98,92,255,255,255,237,231,227,254,252,251,254,252, + 251,235,229,226,255,255,255,152,145,141,143,131,125,253,253,253,204,143,172,174, + 65,123,181,80,133,180,78,132,180,78,132,180,78,132,180,78,132,180,78,132, + 180,78,132,180,79,133,178,75,130,180,81,133,245,226,232,192,185,177,112,101, + 95,255,255,255,237,231,227,254,252,251,254,252,251,235,229,226,255,255,255,151, + 144,140,145,132,126,255,255,255,186,96,142,212,152,184,251,245,248,250,242,246, + 251,245,248,251,245,248,251,245,248,251,245,248,251,244,247,251,245,248,247,237, + 242,178,74,130,238,203,217,195,192,183,111,99,94,255,255,255,237,231,227,254, + 252,251,254,252,251,235,229,226,255,255,255,151,144,140,145,132,126,255,255,255, + 188,102,146,215,159,188,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,252,248,250,180,79,133,239,207,219,195, + 191,183,111,99,94,255,255,255,237,231,227,254,252,251,254,252,251,235,229,226, + 255,255,255,151,144,140,145,132,126,255,255,255,188,101,145,214,157,187,255,254, + 254,254,251,252,255,254,254,255,254,254,255,254,254,255,254,254,255,253,253,255, + 254,254,251,244,247,180,78,132,239,206,219,195,191,183,111,99,94,255,255,255, + 237,231,227,254,252,251,254,252,251,235,229,226,255,255,255,151,144,140,145,132, + 126,255,255,255,188,101,145,214,157,187,255,255,255,254,252,253,255,255,255,255, + 255,255,255,255,255,255,255,255,255,254,254,255,255,255,251,245,248,180,78,132, + 239,206,219,195,191,183,111,99,94,255,255,255,237,231,227,254,252,251,254,252, + 251,235,229,226,255,255,255,151,144,140,145,132,126,255,255,255,188,101,145,214, + 157,187,255,255,255,254,252,253,255,255,255,255,255,255,255,255,255,255,255,255, + 255,254,254,255,255,255,251,245,248,180,78,132,239,206,219,195,191,183,111,99, + 94,255,255,255,237,231,227,254,252,251,254,252,251,235,229,226,255,255,255,151, + 144,140,145,132,126,255,255,255,188,101,145,214,156,186,254,253,254,253,250,252, + 254,253,254,254,253,254,254,253,254,254,253,254,254,252,253,254,253,254,250,243, + 247,180,78,132,239,206,219,195,191,183,111,99,94,255,255,255,237,231,227,254, + 252,251,254,252,251,235,229,226,255,255,255,151,144,140,145,132,126,255,255,255, + 188,102,145,216,163,191,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,181,80,133,239,206,219,195, + 191,183,111,99,94,255,255,255,237,231,227,254,252,251,254,252,251,235,229,226, + 255,255,255,151,144,140,145,132,126,255,255,255,187,98,143,203,130,169,235,207, + 222,234,204,220,235,206,221,235,206,221,235,206,221,235,206,221,235,206,221,235, + 206,221,232,200,217,176,68,126,239,204,218,195,192,183,111,99,94,255,255,255, + 237,231,227,254,252,251,254,252,251,235,229,226,255,255,255,152,146,142,144,131, + 125,252,252,251,215,170,189,177,75,128,179,77,130,178,76,129,178,75,129,178, + 75,129,178,75,129,178,75,129,178,75,129,178,77,130,176,71,126,190,107,149, + 248,236,238,191,182,176,113,102,97,255,255,255,237,231,227,254,252,251,254,252, + 251,235,229,226,255,255,255,145,137,133,150,139,132,255,255,255,255,255,253,255, + 248,247,255,247,247,255,247,247,255,247,247,255,247,247,255,247,247,255,247,247, + 255,247,247,255,247,247,255,245,246,255,254,250,255,255,255,201,192,187,105,94, + 87,255,255,255,237,231,227,254,252,251,254,252,251,236,230,227,255,255,255,191, + 186,183,93,79,71,148,139,133,144,132,126,146,136,129,146,137,129,146,137,129, + 146,137,129,146,137,129,146,137,129,146,137,129,146,137,129,146,136,129,147,137, + 129,144,133,126,150,140,134,105,92,84,150,142,138,255,255,255,236,230,227,254, + 252,251,255,253,252,239,234,230,250,248,247,255,255,255,191,186,183,144,136,131, + 152,144,140,150,142,138,150,142,138,150,142,138,150,142,138,150,142,138,150,142, + 138,150,142,138,150,142,138,150,142,138,150,142,138,151,143,139,147,139,135,168, + 161,157,255,255,255,251,250,249,239,233,230,255,253,252,255,253,252,246,243,240, + 240,235,231,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,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,247,245, + 244,249,248,247,249,248,247,249,248,247,249,248,247,249,248,247,249,248,247,249, + 248,247,249,248,247,249,248,247,249,248,247,249,248,247,249,248,247,249,248,247, + 249,248,247,247,245,243,239,234,231,241,236,233,254,252,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset67 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,255,255,255,255,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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, + 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,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,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,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, + 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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset68 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 255,253,252,253,251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249, + 246,244,249,246,244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252, + 253,251,250,253,251,250,253,251,249,254,253,252,246,242,240,237,231,227,239,234, + 230,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,230,237,231,227,246,242,240,254,253,252,253,251,249,255,253, + 252,246,242,240,238,232,229,252,251,250,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,252,251, + 250,238,232,229,246,242,240,255,253,252,253,251,250,237,231,227,253,252,252,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,253,252,252,237,231,227,253, + 251,250,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 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,255,255,255,255,255, + 239,234,231,249,246,244,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249,246,244,249,246, + 244,239,234,231,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,255, + 255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,255,255,255,254,254,254,254,254,254,255,254,254, + 254,254,254,255,255,255,255,253,253,255,254,254,255,254,254,255,254,253,255,255, + 255,254,254,254,255,255,254,254,254,254,254,254,254,254,254,254,254,254,254,255, + 255,254,254,254,254,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 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,255,255,255,255,255, + 239,234,231,249,246,244,249,246,244,238,233,230,255,255,255,225,221,218,177,165, + 158,178,167,160,192,182,176,250,249,248,229,179,165,215,139,118,214,137,116,234, + 193,182,247,248,248,186,174,168,178,167,160,178,166,159,238,235,234,234,230,228, + 177,165,158,179,167,160,189,179,173,249,248,248,240,235,232,249,245,243,249,246, + 244,238,233,229,255,255,255,182,172,165,216,207,202,242,240,239,178,167,159,226, + 215,211,217,137,115,248,232,227,242,217,209,220,142,120,218,213,210,184,172,164, + 242,240,239,203,192,186,202,194,189,197,189,184,209,198,193,242,240,239,180,166, + 159,226,222,220,246,242,239,248,244,242,249,246,244,238,233,229,255,255,255,187, + 178,172,231,223,219,255,255,255,189,179,173,226,215,212,222,150,130,255,255,253, + 250,240,235,224,153,133,219,214,211,196,185,179,255,255,255,217,208,203,205,197, + 193,201,193,188,223,214,210,255,255,255,191,179,173,226,223,221,246,242,239,248, + 244,242,249,246,244,238,233,229,255,255,255,183,173,166,234,227,223,255,255,255, + 187,177,170,224,212,208,221,145,125,255,255,255,252,246,243,222,147,127,216,210, + 207,195,185,178,255,255,255,219,210,205,201,193,189,197,189,184,225,217,213,255, + 255,255,190,178,171,224,220,218,246,243,240,248,244,242,249,246,244,238,233,229, + 255,255,255,202,194,190,174,161,153,185,174,168,172,160,152,240,235,233,219,145, + 125,218,147,128,215,141,120,224,159,141,235,234,232,169,155,146,185,175,169,169, + 156,147,220,215,212,215,209,205,171,157,149,185,175,168,170,157,149,239,237,236, + 243,238,235,248,245,243,249,246,244,239,234,231,255,255,255,255,255,255,233,230, + 228,229,225,223,244,242,240,255,255,255,251,245,243,242,217,210,242,218,212,253, + 249,248,255,255,255,240,238,237,229,225,223,235,232,230,255,255,255,255,255,255, + 234,231,229,229,225,223,242,240,239,255,255,255,238,233,230,249,246,244,249,246, + 244,239,234,231,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 254,254,255,255,255,255,255,255,255,255,255,255,255,255,254,254,254,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,254,239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,255, + 255,255,254,254,254,254,254,254,254,254,254,255,255,255,255,254,254,255,254,253, + 255,254,253,255,255,254,255,255,255,254,254,254,254,254,254,254,254,254,255,255, + 255,255,255,255,254,254,254,254,254,254,254,254,254,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,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,255,255,255,255,255,239,234,231,249,246,244,253,251,250,237,231,227, + 253,252,252,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,253,252,252, + 237,231,227,253,251,250,255,253,252,246,242,240,238,232,229,252,251,250,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,252,251,250,238,232,229,246,242,240,255,253,252,253,251, + 249,254,253,252,246,242,240,237,231,227,239,234,230,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,230,237,231, + 227,246,242,240,254,253,252,253,251,249,253,251,250,253,251,250,255,253,252,253, + 251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244, + 249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252,253,251,250,253, + 251,250 + ); + CEditorAsset69 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,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,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,251,251,255,255,255,254,254,254,246,245,244,245,244,243,245,244,244,245,244, + 244,245,244,244,245,244,244,245,244,244,245,244,243,246,245,244,254,254,254,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,251,251,250,255,255,255,243,242, + 242,87,75,67,73,59,51,77,63,55,76,62,54,76,62,54,76,62,54,77, + 63,55,73,59,51,87,75,67,243,242,242,255,255,255,254,254,254,255,255,255, + 255,255,255,255,255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,255,255,255,252,251,251,207,203,201,202,198,196,204, + 200,197,203,199,197,203,199,197,203,199,197,204,200,197,202,198,196,207,203,201, + 250,250,250,253,253,253,253,253,253,253,253,253,255,255,255,255,255,255,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,251,251,250,255,255,255,245,244,244,113,102,95, + 100,89,82,104,92,86,103,91,85,103,91,85,103,91,85,103,91,85,103,91, + 85,103,91,85,105,94,87,105,94,87,107,95,89,99,86,80,217,213,212,255, + 255,255,253,254,254,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 251,251,250,255,255,255,248,248,248,157,150,145,149,141,136,151,143,139,151,143, + 138,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138,151, + 143,138,151,143,139,148,140,136,229,227,226,255,255,255,254,254,254,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,251,251,250,255,255,255,248,248,248,157,150,145,149,141,136,151, + 143,139,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138, + 151,143,138,152,144,139,146,138,133,226,223,222,254,254,254,254,254,253,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,251,251,250,255, + 255,255,245,244,244,113,103,95,101,90,82,104,93,85,103,92,84,103,92,84, + 103,92,84,103,92,84,103,92,84,103,92,84,103,92,84,105,94,86,97,85, + 77,214,212,209,253,253,252,253,253,252,255,255,255,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,255,255,255,252,253,251,214,222,202,210,220,197,211,220,198,211,220, + 198,211,220,198,211,220,198,211,220,198,211,220,198,211,220,198,211,220,198,211, + 220,198,211,220,198,213,222,200,211,221,197,244,246,241,255,255,255,252,251,250, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,250,255,255,255,243,245, + 239,78,116,23,63,104,2,67,108,8,66,107,7,66,107,7,66,107,7,66, + 107,7,66,107,7,66,107,7,66,107,7,66,107,7,66,107,7,68,108,9, + 57,100,0,207,217,191,255,255,255,250,250,248,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,250,255,255,255,247,248,244,137,162,100,127,154,86,129, + 157,90,129,156,89,129,156,89,129,156,89,129,156,89,129,156,89,129,156,89, + 129,156,89,129,156,89,129,156,89,130,157,91,123,151,82,223,229,212,255,255, + 255,250,250,249,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,252,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,255,255,255,255,255,255,253,254,253, + 253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254, + 253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,254, + 254,254,255,255,255,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,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,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset70 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0, + 0,0,0,0,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,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,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,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,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,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,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,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,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,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,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,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,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, + 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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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, + 0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0, + 0,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,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,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,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,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,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,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset71 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 255,253,252,253,251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249, + 246,244,249,246,244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252, + 253,251,250,253,251,250,253,251,249,254,253,252,246,242,240,237,231,227,239,234, + 230,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,230,237,231,227,246,242,240,254,253,252,253,251,249,255,253, + 252,246,242,240,238,232,229,252,251,250,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,253,255,255,253,255,255,254,255,255,255,255,255,252,251, + 250,238,232,229,246,242,240,255,253,252,253,251,250,237,231,227,253,252,252,255, + 255,255,255,255,255,254,254,254,255,255,255,253,253,253,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,254,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,254,254,254,255,255,255,253,252,252,237,231,227,253, + 251,250,249,246,244,239,234,231,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,254,253,253,255,255,255,255,255,255,255,255,255,255,255, + 255,254,254,255,255,255,255,241,247,253,130,181,232,91,158,225,191,217,243,255, + 255,255,253,254,254,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 255,255,255,253,253,253,255,255,255,211,207,205,90,75,65,225,222,220,255,255, + 255,252,252,252,255,255,255,255,255,255,255,255,255,253,254,255,252,253,254,84, + 154,224,42,129,216,89,157,225,20,117,212,191,217,243,255,255,255,253,254,255, + 239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,254,253,253,254,254, + 254,226,224,222,85,69,59,72,55,44,225,223,221,255,255,255,253,253,252,255, + 255,255,253,254,255,255,255,255,214,231,248,22,118,212,222,236,249,255,255,255, + 91,158,225,90,158,225,255,255,255,253,255,255,239,234,231,249,246,244,249,246, + 244,239,234,231,255,255,255,255,255,255,254,254,254,255,255,255,239,238,237,89, + 73,63,73,56,45,228,225,224,255,255,255,252,252,252,254,254,255,255,255,255, + 234,243,251,33,124,215,139,186,234,209,228,247,42,129,216,131,182,232,255,255, + 255,253,255,255,239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,255, + 255,255,255,255,255,253,252,252,255,255,255,238,237,236,82,65,55,90,74,64, + 244,243,242,255,255,255,253,253,253,253,254,255,255,255,255,170,205,240,33,124, + 214,24,119,213,83,154,224,239,245,252,254,254,255,254,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,255,255,255,255,255,255,255,255,255,255,255,255, + 252,252,252,255,255,255,221,218,217,66,48,37,98,83,74,244,243,242,255,255, + 255,253,253,253,254,255,255,255,255,255,236,244,252,213,230,247,255,255,255,255, + 255,255,254,255,255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,252,252,252,255,255, + 255,218,214,212,65,47,36,98,83,74,243,242,242,255,255,255,253,253,253,253, + 254,255,255,255,255,255,255,255,255,255,255,254,255,255,255,255,255,255,255,255, + 239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,252,252,251,255,255,255,218,214,212,65, + 47,36,98,84,74,244,242,242,255,255,255,253,253,253,254,254,255,253,254,255, + 255,255,255,255,255,255,255,255,255,255,255,255,239,234,231,249,246,244,249,246, + 244,239,234,231,255,255,255,255,255,255,255,255,255,254,255,255,252,253,254,252, + 253,254,255,255,255,252,252,252,255,255,255,218,214,212,65,47,36,98,83,74, + 244,243,242,255,255,255,254,254,253,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231,255,255,255,255, + 255,255,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 252,252,252,255,255,255,218,215,212,65,47,36,98,83,74,242,241,240,254,254, + 254,253,253,253,255,255,255,255,255,255,255,255,255,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,255,255,255,254,255,255,255,255,255,250,252,254, + 179,210,241,188,215,243,255,255,255,255,255,255,255,255,255,252,252,251,255,255, + 255,218,214,212,63,46,34,110,97,88,255,255,255,254,254,254,254,254,254,255, + 255,255,255,255,255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 255,255,255,254,254,255,245,249,253,76,150,222,28,122,213,25,119,213,99,163, + 227,252,253,254,254,254,255,255,255,255,251,251,251,255,255,255,205,201,198,51, + 32,20,129,117,110,255,255,255,255,255,255,254,254,254,255,255,255,255,255,255, + 239,234,231,249,246,244,249,246,244,239,234,231,252,254,255,255,255,255,159,198, + 237,34,125,215,235,243,251,217,232,248,24,119,213,188,215,243,255,255,255,252, + 253,254,255,255,255,252,252,251,255,255,255,191,185,182,49,30,18,130,118,110, + 247,247,246,253,253,253,254,254,254,255,255,255,239,234,231,249,246,244,249,246, + 244,239,234,231,252,254,255,255,255,255,149,192,236,42,129,216,255,255,255,239, + 245,252,28,121,214,180,211,241,255,255,255,252,253,254,255,255,255,255,255,255, + 252,252,251,255,255,255,192,186,183,45,26,13,164,156,151,255,255,255,252,252, + 252,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231,254,255,255,254, + 255,255,238,245,252,56,138,219,42,130,216,34,125,214,77,150,223,248,251,254, + 254,254,255,255,255,255,255,255,255,255,255,255,255,255,255,253,252,252,255,255, + 255,205,201,198,236,234,233,255,255,255,254,254,254,255,255,255,239,234,231,249, + 246,244,249,246,244,239,234,231,255,255,255,254,254,254,255,255,255,238,245,252, + 148,192,236,158,198,237,246,249,253,255,255,255,254,254,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,253,253,253,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,239,234,231,249,246,244,253,251,250,237,231,227, + 253,252,252,255,255,255,254,254,254,255,255,255,255,255,255,255,255,255,255,255, + 255,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,253,252,252,254,254,254,255,255,255,255,255,255,253,252,252, + 237,231,227,253,251,250,255,253,252,246,242,240,238,232,229,252,251,250,255,255, + 255,255,255,255,253,254,255,253,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,252,251,250,238,232,229,246,242,240,255,253,252,253,251, + 249,254,253,252,246,242,240,237,231,227,239,234,230,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,230,237,231, + 227,246,242,240,254,253,252,253,251,249,253,251,250,253,251,250,255,253,252,253, + 251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244, + 249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252,253,251,250,253, + 251,250 + ); + CEditorAsset72 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,255,255,255,255,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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, + 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,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,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,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, + 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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset73 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,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,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,251,251,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,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,255,255,255,255,255,255,253,254,254,252,254,254,252, + 254,254,252,254,254,252,254,254,252,254,254,252,254,254,252,254,254,252,254,254, + 254,254,254,255,255,255,255,255,255,255,255,255,255,254,254,255,254,254,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255, + 255,255,254,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,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,255,255,255,255,252,248,203,216,221, + 173,201,213,178,204,215,177,203,215,177,203,215,177,203,215,177,203,215,178,204, + 215,174,202,214,213,216,216,236,223,216,227,220,215,228,220,214,229,222,217,246, + 243,241,255,255,255,252,251,250,238,233,229,254,252,251,254,252,251,238,233,229, + 250,251,251,255,255,253,158,193,208,9,133,191,7,133,193,8,133,193,7,133, + 193,7,133,193,7,133,193,7,133,193,8,134,193,4,132,193,32,142,193,203, + 214,218,242,231,225,234,228,224,233,226,221,221,211,205,249,248,247,253,253,253, + 238,232,229,254,252,251,254,252,251,238,232,228,252,253,254,255,248,243,63,153, + 195,7,137,197,24,142,197,21,141,197,21,141,197,21,141,197,21,141,197,21, + 141,197,21,140,197,26,143,198,0,132,193,129,189,217,255,247,240,240,237,236, + 247,243,240,229,221,216,236,230,227,255,255,255,238,232,228,254,252,251,254,252, + 251,238,232,228,251,252,254,255,250,245,75,157,196,0,133,196,19,140,197,15, + 139,197,15,139,197,15,139,197,15,139,197,15,139,197,15,139,197,19,140,197, + 0,130,194,143,196,221,255,247,241,241,239,237,246,243,240,227,218,212,238,234, + 231,255,255,255,238,232,228,254,252,251,254,252,251,238,233,229,250,251,250,255, + 255,255,194,211,217,44,145,192,26,139,193,29,140,193,28,140,193,28,140,193, + 28,140,193,28,140,193,30,141,193,23,138,192,71,155,194,217,215,212,232,222, + 216,228,221,216,227,218,212,224,215,209,252,252,251,253,252,252,238,232,229,254, + 252,251,254,252,251,238,233,229,252,251,251,255,255,255,255,255,254,241,238,236, + 221,226,227,225,228,229,224,228,229,224,228,229,224,228,229,224,228,229,225,228, + 229,223,227,229,243,234,229,240,232,227,235,230,227,235,230,226,237,233,229,252, + 251,251,255,255,255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,255,255,255,253,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,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255,255,255,255,255, + 255,254,254,254,253,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,253,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,255,255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,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,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,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,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset74 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,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,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,253,254,254,251,253,254,253,253,254,253,253, + 254,251,253,254,253,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,251,251,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,252,253, + 254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,252, + 253,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255,255,255,255,255, + 255,255,255,255,255,255,255,254,254,255,255,255,255,219,232,245,123,168,217,70, + 134,203,70,134,203,123,168,217,219,232,245,255,255,255,254,254,255,255,255,255, + 255,255,255,255,255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,255,255,255,255,255,255,255,255,255,253,254,254,254, + 254,255,140,179,222,9,94,185,19,100,188,68,132,202,68,132,202,19,100,188, + 9,94,185,140,179,222,254,254,255,253,254,254,255,255,255,255,255,255,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255, + 255,255,255,255,255,252,253,254,255,255,255,142,181,223,0,83,181,122,168,218, + 233,241,249,255,255,255,255,255,255,233,241,249,122,168,218,0,83,181,142,181, + 223,255,255,255,252,253,254,255,255,255,255,255,255,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,255,255,255,253,253,255,255,255,255, + 222,233,246,9,93,186,122,168,218,255,255,255,255,255,255,202,220,240,202,220, + 240,255,255,255,255,255,255,122,168,218,9,93,186,222,233,246,255,255,255,253, + 253,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,255,255,255,251,252,254,255,255,255,123,168,217,19,100,188,240,245, + 251,252,253,254,118,165,216,12,95,186,12,95,186,118,165,216,252,253,254,240, + 245,251,19,100,188,123,168,217,255,255,255,251,252,254,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255,255,255,253,253, + 254,255,255,255,70,134,203,69,133,202,255,255,255,203,221,240,12,95,186,27, + 105,191,27,105,191,12,95,186,203,221,240,255,255,255,69,133,202,70,134,203, + 255,255,255,253,253,254,255,255,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,255,255,255,253,253,254,255,255,255,70,134,203,69, + 133,202,255,255,255,203,221,240,12,95,186,27,105,191,27,105,191,12,95,186, + 203,221,240,255,255,255,69,133,202,70,134,203,255,255,255,253,253,254,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255, + 255,255,251,252,254,255,255,255,123,168,217,19,100,188,240,245,251,252,253,254, + 118,165,216,12,95,186,12,95,186,118,165,216,252,253,254,240,245,251,19,100, + 188,123,168,217,255,255,255,251,252,254,255,255,255,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,255,255,255,253,253,255,255,255,255, + 222,233,246,9,93,186,122,168,218,255,255,255,255,255,255,202,220,240,202,220, + 240,255,255,255,255,255,255,122,168,218,9,93,186,222,233,246,255,255,255,253, + 253,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,255,255,255,255,255,255,252,253,254,255,255,255,142,181,223,0,83, + 181,122,168,218,233,241,249,255,255,255,255,255,255,233,241,249,122,168,218,0, + 83,181,142,181,223,255,255,255,252,253,254,255,255,255,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255,255,255,255,255, + 255,255,255,255,253,254,254,254,254,255,140,179,222,9,94,185,19,100,188,68, + 132,202,68,132,202,19,100,188,9,94,185,140,179,222,254,254,255,253,254,254, + 255,255,255,255,255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,255,255,255,255,255,255,255,255,255,255,255,255,254, + 254,255,255,255,255,219,232,245,123,168,217,70,134,203,70,134,203,123,168,217, + 219,232,245,255,255,255,254,254,255,255,255,255,255,255,255,255,255,255,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,252,253,254,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,252,253,254,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,252,251,251,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,253,254,254,251,253,254,253,253,254,253,253, + 254,251,253,254,253,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,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,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset75 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,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,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,251,251,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,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,254,254,255,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,252,253,254,255,255,255,255,255,255, + 252,253,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255, + 255,255,255,255,255,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,255,255,255,247,249,253,240,245,251,255,255,255,255,255,255,254,254, + 254,254,254,254,254,254,254,254,254,254,255,255,255,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,159,192,228,44,117, + 196,36,111,193,121,167,217,248,250,253,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,255,255,255,251,250,250,246,245,245,246,246,245,246,246,245,243,243, + 245,246,245,245,174,201,230,7,92,185,20,101,189,24,104,190,0,87,183,121, + 167,217,246,246,246,244,244,244,246,245,245,249,248,248,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,249,248,247,255,255,255,162,155, + 151,56,41,33,73,59,52,70,56,48,70,56,49,72,54,42,32,89,152,24, + 107,199,28,104,188,26,105,189,27,107,193,23,98,180,67,59,57,73,58,48, + 60,46,38,118,106,100,255,255,255,251,250,249,238,232,229,254,252,251,254,252, + 251,238,233,229,250,249,249,255,255,255,207,204,202,153,145,141,162,155,151,160, + 153,149,159,152,149,162,152,146,68,122,182,15,99,191,31,107,191,29,107,191, + 22,103,190,38,110,189,155,152,153,161,154,149,155,148,144,185,179,176,255,255, + 255,251,250,250,238,232,229,254,252,251,254,252,251,238,233,229,252,251,251,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 211,228,246,24,103,189,10,94,186,14,97,187,6,91,184,161,194,229,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,255,255,255,253,253,253,252,251,251, + 252,252,252,252,252,251,252,252,252,250,251,251,255,255,255,207,224,242,92,148, + 209,79,140,206,176,203,233,255,255,255,250,251,251,252,252,251,252,251,251,253, + 252,252,255,255,255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255,254, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,253, + 254,254,252,253,254,253,253,254,252,253,254,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,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,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,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,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset76 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,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,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,0, + 0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,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 + ); + CEditorAsset77 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,255, + 255,255,255,255,255,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254, + 255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254, + 254,255,254,254,255,254,254,255,255,254,255,255,255,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,254,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,250,249,255,255,255,237,222,212,186,125,87,184,123,85,183,123,84,184,123, + 85,185,125,86,185,125,86,184,123,84,183,122,84,184,123,84,185,125,86,185, + 125,86,184,123,85,184,124,86,180,117,77,222,193,175,255,255,255,252,251,249, + 238,233,229,254,252,251,254,252,251,238,232,228,253,253,252,252,249,247,176,108, + 65,195,142,108,220,180,154,221,181,155,214,173,148,208,167,141,208,167,141,217, + 177,151,222,182,156,217,177,151,208,167,141,208,167,141,214,173,147,222,182,157, + 216,173,146,169,94,46,237,222,212,254,254,254,237,231,227,254,252,251,254,252, + 251,238,232,228,254,254,254,251,246,244,172,98,52,235,220,211,210,213,216,196, + 197,198,235,239,242,255,255,255,255,255,255,220,224,226,197,199,200,220,224,226, + 255,255,255,255,255,255,235,238,241,198,199,201,204,203,203,170,97,51,232,211, + 198,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228,254,254,254,248, + 244,241,185,114,68,148,121,104,122,114,108,150,140,134,110,97,90,249,247,246, + 213,208,206,106,92,84,151,142,137,106,92,84,213,208,206,249,247,246,110,97, + 90,150,141,134,124,115,110,120,68,36,242,219,205,255,255,255,237,231,227,254, + 252,251,254,252,251,238,232,228,254,254,254,248,244,241,187,116,70,128,101,84, + 202,199,196,255,255,255,125,114,108,246,245,245,197,193,191,154,143,136,255,255, + 255,154,143,136,197,193,191,246,245,245,125,114,108,255,255,255,206,204,202,107, + 60,32,243,220,205,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228, + 254,254,254,248,244,241,187,116,70,133,106,89,190,186,183,252,252,249,124,113, + 107,247,246,246,201,197,195,147,136,129,252,252,251,147,136,129,201,197,195,247, + 246,246,124,113,107,252,252,248,193,190,188,110,61,32,243,220,205,255,255,255, + 237,231,227,254,252,251,254,252,251,238,232,228,254,254,254,248,244,241,187,116, + 70,132,105,88,192,188,185,255,255,253,124,113,107,247,246,246,200,196,194,148, + 137,130,255,255,255,148,137,130,200,196,194,247,246,246,124,113,107,255,255,252, + 195,192,190,109,61,32,243,220,205,255,255,255,237,231,227,254,252,251,254,252, + 251,238,232,228,254,254,254,248,244,241,187,116,70,132,105,88,192,188,185,255, + 255,253,124,113,107,247,246,246,200,196,194,148,137,130,255,255,255,148,137,130, + 200,196,194,247,246,246,124,113,107,255,255,252,195,192,190,109,61,32,243,220, + 205,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228,254,254,254,248, + 244,241,187,116,70,133,106,89,190,186,183,252,252,249,124,113,107,247,246,246, + 201,197,195,147,136,129,252,252,251,147,136,129,201,197,195,247,246,246,124,113, + 107,252,252,248,193,190,188,110,61,32,243,220,205,255,255,255,237,231,227,254, + 252,251,254,252,251,238,232,228,254,254,254,248,244,241,187,116,70,128,101,84, + 202,199,196,255,255,255,125,114,108,246,245,245,197,193,191,154,143,136,255,255, + 255,154,143,136,197,193,191,246,245,245,125,114,108,255,255,255,206,204,202,107, + 60,32,243,220,205,255,255,255,237,231,227,254,252,251,254,252,251,238,232,228, + 254,254,254,248,244,242,185,115,69,149,122,105,123,115,110,151,141,135,110,98, + 91,250,249,248,213,210,208,107,93,85,152,143,139,107,93,85,213,210,208,250, + 249,248,110,98,91,151,142,135,124,116,111,120,68,36,242,220,205,255,255,255, + 237,231,227,254,252,251,254,252,251,238,232,228,254,254,255,250,246,244,170,95, + 48,234,218,207,208,209,211,194,193,193,232,235,237,255,255,255,255,255,255,218, + 220,221,195,195,195,218,220,221,255,255,255,255,255,255,232,234,236,196,195,196, + 202,200,199,168,94,48,231,210,197,255,255,255,237,231,227,254,252,251,254,252, + 251,238,232,229,252,252,251,253,251,250,188,130,93,177,109,66,197,138,100,199, + 139,101,191,131,93,185,125,86,185,125,86,194,135,96,199,140,102,194,135,96, + 185,125,86,185,125,86,191,131,93,200,141,103,194,131,92,176,106,62,243,232, + 225,254,253,253,238,232,228,254,252,251,254,252,251,238,233,229,252,251,250,255, + 255,255,249,244,241,209,168,143,206,165,139,206,165,139,207,166,139,208,167,141, + 208,167,141,206,165,139,206,164,138,206,165,139,208,167,141,208,167,141,207,166, + 139,206,165,140,203,160,133,238,224,215,255,255,255,252,250,249,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,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,254,254,254,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,255,255,255,255,255,255,254,253,252,254,253,253,254,253,252,254,253, + 252,254,253,252,254,253,252,254,253,252,254,253,252,254,253,252,254,253,252,254, + 253,252,254,253,252,254,253,253,254,253,252,255,255,255,255,255,255,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset78 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,0,0,0,0, + 0,0,0,0,0,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, + 255,255,255,255,255,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,0,0,0,0,0,0, + 0,0,0,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,255,255, + 255,255,255,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,0,0,0,0,0,0,0,0, + 0,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,0,0,0,0,0,0,0,0,0,255,255, + 255,0,0,0,0,0,0,0,0,0,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,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,0,0,0,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,0,0,0,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,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,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0, + 0,0,0,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,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,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, + 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,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,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,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,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,0,0,0,0,0,0,0,0,0,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,0, + 0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 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,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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 + ); + CEditorAsset79 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,255,255,255,255,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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, + 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,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,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,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, + 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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset80 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,0,0,0,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,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 + ); + CEditorAsset81 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,255,255,255,255,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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, + 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,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,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,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, + 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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset82 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,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,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,251,251,255,255,255,254,254,254,246,245,244,245,244,243,245,244,244,245,244, + 244,245,244,244,245,244,244,245,244,244,245,244,243,246,245,244,254,254,254,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,251,251,250,255,255,255,243,242, + 242,87,75,67,73,59,51,77,63,55,76,62,54,76,62,54,76,62,54,77, + 63,55,73,59,51,87,75,67,243,242,242,255,255,255,254,254,254,255,255,255, + 255,255,255,255,255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,255,255,255,252,251,251,207,203,201,202,198,196,204, + 200,197,203,199,197,203,199,197,203,199,197,204,200,197,202,198,196,207,203,201, + 250,250,250,253,253,253,253,253,253,253,253,253,255,255,255,255,255,255,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,251,251,250,255,255,255,245,244,244,113,102,95, + 100,89,82,104,92,86,103,91,85,103,91,85,103,91,85,103,91,85,103,91, + 85,103,91,85,105,94,87,105,94,87,107,95,89,99,86,80,217,213,212,255, + 255,255,253,254,254,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 251,251,250,255,255,255,248,248,248,157,150,145,149,141,136,151,143,139,151,143, + 138,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138,151, + 143,138,151,143,139,148,140,136,229,227,226,255,255,255,254,254,254,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,251,251,250,255,255,255,248,248,248,157,150,145,149,141,136,151, + 143,139,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138,151,143,138, + 151,143,138,152,144,139,146,138,133,226,223,222,254,254,254,254,254,253,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,251,251,250,255, + 255,255,245,244,244,113,103,95,101,90,82,104,93,85,103,92,84,103,92,84, + 103,92,84,103,92,84,103,92,84,103,92,84,103,92,84,105,94,86,97,85, + 77,214,212,209,253,253,252,253,253,252,255,255,255,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,255,255,255,252,253,251,214,222,202,210,220,197,211,220,198,211,220, + 198,211,220,198,211,220,198,211,220,198,211,220,198,211,220,198,211,220,198,211, + 220,198,211,220,198,213,222,200,211,221,197,244,246,241,255,255,255,252,251,250, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,250,255,255,255,243,245, + 239,78,116,23,63,104,2,67,108,8,66,107,7,66,107,7,66,107,7,66, + 107,7,66,107,7,66,107,7,66,107,7,66,107,7,66,107,7,68,108,9, + 57,100,0,207,217,191,255,255,255,250,250,248,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,250,255,255,255,247,248,244,137,162,100,127,154,86,129, + 157,90,129,156,89,129,156,89,129,156,89,129,156,89,129,156,89,129,156,89, + 129,156,89,129,156,89,129,156,89,130,157,91,123,151,82,223,229,212,255,255, + 255,250,250,249,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,252,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,255,255,255,255,255,255,253,254,253, + 253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254, + 253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,253,254,253,254, + 254,254,255,255,255,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,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,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset83 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,253,255,255, + 252,254,255,253,255,255,254,255,255,252,254,255,253,254,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,255,255,255,255,255,255,255,255,255, + 255,255,255,254,254,255,253,254,254,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,253,254,254,255,255,255,255,255,255,255, + 255,255,255,255,255,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,251,251,255,255,255,255,255,255,255,255,255,254,255,255,255,255,255,255,255, + 255,202,229,242,127,192,223,79,169,211,78,169,211,108,183,219,182,219,237,251, + 253,254,255,255,255,253,254,255,255,255,255,255,255,255,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255,255,255,255,255, + 255,254,255,255,253,254,254,242,248,252,109,184,219,2,131,192,0,124,188,0, + 127,190,0,128,190,0,124,189,0,127,190,71,165,209,221,238,247,255,255,255, + 254,254,255,255,255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,255,255,255,254,254,255,253,254,254,252,253,254,72, + 166,210,0,124,189,31,145,199,129,193,224,192,224,239,196,226,240,151,204,229, + 54,157,205,0,126,189,33,147,200,215,235,245,254,255,255,253,254,254,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255, + 255,255,252,254,254,255,255,255,125,191,223,0,125,189,62,160,207,220,238,246, + 255,255,255,255,255,255,255,255,255,255,255,255,241,248,252,105,181,218,0,119, + 186,116,187,221,255,255,255,252,253,254,255,255,255,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,255,255,255,255,255,255,234,245,250, + 21,141,197,17,138,195,212,234,244,255,255,255,249,252,254,252,254,254,252,254, + 254,250,253,254,255,255,255,242,248,252,170,213,233,245,250,252,254,255,255,255, + 255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,252,254,255,255,255,255,166,212,233,0,125,189,96,178,216,255,255, + 255,251,253,254,255,255,255,255,255,255,255,255,255,255,255,255,254,254,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,252,254,255,255,255, + 255,138,197,226,1,122,187,144,201,228,254,254,255,251,253,254,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,254,255,255,252,253,254,254,255,255, + 255,255,255,255,255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,252,254,255,255,255,255,139,198,226,0,122,187,139, + 198,226,254,255,255,251,253,254,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,254,254,255,254,254,255,255,255,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,253, + 254,255,255,255,255,184,220,237,2,128,190,75,168,210,255,255,255,250,253,254, + 255,255,255,255,255,255,255,255,255,255,255,255,254,255,255,255,255,255,254,254, + 254,255,255,255,255,255,255,254,254,254,255,255,255,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,255,255,255,254,255,255,244,250,252, + 36,148,201,6,131,192,179,218,236,255,255,255,251,253,254,251,253,254,251,253, + 254,253,254,255,255,255,255,254,254,254,255,255,255,253,253,253,253,253,253,255, + 255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,255,255,255,252,253,254,255,255,255,166,211,233,0,128,191,30,145, + 199,174,215,235,255,255,255,255,255,255,255,255,255,255,255,255,249,252,253,255, + 255,254,238,237,236,109,98,92,109,98,92,238,237,236,254,254,254,251,250,250, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255,255,255,255,255, + 255,253,254,254,255,255,255,117,188,221,0,128,191,2,131,192,74,166,210,136, + 197,225,141,199,227,87,173,213,60,159,205,246,251,254,217,213,211,54,39,31, + 54,39,31,215,212,210,255,255,255,250,249,248,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,255,255,255,255,255,255,255,255,255,252,253,254,255, + 255,255,162,210,232,36,148,201,0,128,191,0,122,187,0,122,187,0,126,189, + 15,138,195,194,225,239,255,255,255,190,186,184,192,188,185,255,255,255,254,254, + 254,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255, + 255,255,255,255,255,255,255,255,255,255,255,254,254,255,255,255,255,244,250,252, + 183,220,237,138,198,226,137,197,226,166,211,233,231,243,249,253,254,254,254,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,252,251,251,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,252,254,254,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,252,252,252,252,252,252,255, + 255,255,255,255,255,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,253,254,255,252,254,255,252,254,255,252,254,255,254,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset84 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,255,255,255,255,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255, + 255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,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,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,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,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,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,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,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,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,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,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset85 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,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,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,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,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,255,255,255,255, + 255,255,255,255,255,255,255,255,0,0,0,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,0,0,0, + 0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,0,0,0,0,0,0,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, + 255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,0,0,0,0,0, + 0,0,0,0,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,255, + 255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,0,0,0,255,255,255,255,255,255,255, + 255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0, + 0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0, + 0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,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,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,0,0,0,255,255, + 255,0,0,0,0,0,0,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, + 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,0,0,0,0,0,0,0,0,0,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,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,255,255,255,0,0,0,0,0,0,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,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,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,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,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,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,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,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,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,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,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,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 + ); + CEditorAsset86 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,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,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255, + 255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,0,0,0,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,0,0,0,255,255,255,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,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,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 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,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,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,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,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,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,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,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,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 + ); + CEditorAsset87 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,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,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 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,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,0,0,0,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,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,0, + 0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,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,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,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset88 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 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,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,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,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255, + 255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128, + 128,128,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255, + 255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255, + 255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128, + 128,128,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255, + 255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255, + 255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128, + 128,128,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255, + 255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255, + 255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,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,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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 + ); + CEditorAsset89 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,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,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 0,0,0,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,255,255,255,255,255,255, + 255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,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,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,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,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,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,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 0,0,0,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,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,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,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,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,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,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,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,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,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 + ); + CEditorAsset90 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,255,255,255,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,0,0,0,0,0,0,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,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, + 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,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,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,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,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 255,255,255,0,0,0,0,0,0,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,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,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,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,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, + 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,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,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,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,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,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,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,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,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,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,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,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,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,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset91 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,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,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,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,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,0,0,0,255,255,255,255,255,255, + 255,255,255,255,255,255,0,0,0,255,255,255,0,0,0,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,255,255, + 255,255,255,255,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0, + 0,255,255,255,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,255,255,255,255,255,255,0,0,0,255,255,255,0,0,0,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,255,255,255, + 0,0,0,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 0,0,0,255,255,255,255,255,255,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,0,0,0,255,255,255,255,255, + 255,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,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,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,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,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, + 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,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,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset92 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,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,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,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,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,114,114,114, + 170,170,170,255,255,255,255,255,255,255,255,255,62,62,62,214,214,214,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,193,193,193,104,104,104,255,255,255,255,255, + 255,245,245,245,40,40,40,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,252,252,252,57,57,57,255,255,255,255,255,255,184,184,184,110,110,110,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,255,255,95,95,95,47, + 47,47,55,55,55,24,24,24,186,186,186,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,255,255,174,174,174,139,139,139,255,255,255,50,50,50, + 249,249,249,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,255,255, + 245,245,245,67,67,67,216,216,216,82,82,82,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,255,255,255,255,255,255,255,255,78,78,78,116,116, + 116,158,158,158,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,255, + 255,255,255,255,255,255,255,155,155,155,6,6,6,232,232,232,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,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,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,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,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,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,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,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,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,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 + ); + CEditorAsset93 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,255,255,255,255,255,255, + 255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,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,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255, + 255,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,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,255,255,255,255,255,0,0,0,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,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,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0, + 0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,0,0,0,0, + 0,0,0,0,0,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,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,255,255,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,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,0,0,0,0,0,0,0,0,0,255, + 255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,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,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,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,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,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,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,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,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,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,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset94 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 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,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,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,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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 + ); + CEditorAsset95 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,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,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,255,255,255,0,0,0,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,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,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,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,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, + 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,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,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset96 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,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,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,128,128,128,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,128,128,128,255,255,255,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,128,128,128,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,128,128,128,255,255,255,0,0,0,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 128,128,128,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,128,128,128,255, + 255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,128,128,128,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,128,128,128,255,255,255,0,0,0,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,128,128,128,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, + 128,128,128,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,128,128,128,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,128,128,128,255,255,255,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,128,128,128,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,128,128,128,255,255,255,0,0,0,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 128,128,128,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,128,128,128,255, + 255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,128,128,128,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,128,128,128,255,255,255,0,0,0,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,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,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,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,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, + 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,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,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset97 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 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,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,0,0,0,0,0,0,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,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,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,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,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,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,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 + ); + CEditorAsset98 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,0,0,0,0,0,0,0,0,0,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,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, + 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,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,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,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,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,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,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,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255,255, + 255,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,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,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,255,255,0,0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,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,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255,255, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0, + 0,0,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,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,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,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,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,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,0,0,0,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, + 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,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,0,0, + 0,0,0,0,0,0,0,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,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,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,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,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,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 + ); + CEditorAsset99 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,255,255,255,255,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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, + 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,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,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,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, + 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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset100 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 253,251,250,255,253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254, + 252,251,254,252,251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250, + 253,251,250,253,251,250,253,251,250,253,251,250,254,253,252,246,242,240,239,234, + 230,238,232,228,238,232,229,238,233,229,238,233,229,238,233,229,238,233,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,232,229, + 238,232,228,239,234,230,246,242,240,254,253,252,253,251,250,253,251,250,253,251, + 250,254,253,252,241,236,233,240,234,231,250,248,247,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,250,248,247,240,234, + 231,241,236,233,254,253,252,253,251,250,255,253,252,246,243,240,240,235,231,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,240,235,231,246,243,240,255, + 253,252,255,253,252,239,234,230,250,249,248,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,250,249,248,239,234,230,255,253,252,254,252,251,238,233,229, + 252,251,251,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,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255,255,255,255,255, + 255,255,255,255,253,254,255,251,253,254,251,252,254,251,252,254,251,252,254,251, + 252,254,251,252,254,251,252,254,251,252,254,251,252,254,251,252,254,253,253,254, + 255,255,255,255,255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,255,255,255,255,255,255,253,254,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,253,254,254,255,255,255,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255, + 255,255,254,254,255,255,255,255,228,237,247,142,181,224,126,170,219,129,173,220, + 128,172,220,128,172,220,127,172,220,129,173,220,140,180,222,140,179,223,135,176, + 221,206,223,241,255,255,255,254,254,255,255,255,255,252,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,254,254,255,255,255,255,207,223,241, + 28,105,191,41,112,192,68,131,198,66,128,197,67,128,197,66,128,197,67,130, + 198,61,125,196,9,93,185,6,92,185,38,111,191,15,97,187,161,194,229,255, + 255,255,254,254,255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 251,251,251,254,255,255,245,248,252,34,110,194,113,156,207,255,250,240,255,251, + 240,255,250,240,255,251,240,255,250,240,255,255,242,109,154,208,21,102,190,25, + 104,190,68,130,199,156,182,217,12,96,187,205,222,241,255,255,255,250,250,250, + 238,233,229,254,252,251,254,252,251,238,233,229,249,250,250,255,255,255,193,214, + 237,25,103,189,243,235,235,254,245,238,250,239,236,252,240,236,249,238,236,252, + 246,239,200,209,226,11,96,187,26,105,190,29,106,191,3,90,185,164,188,219, + 79,135,200,124,170,219,255,255,255,248,249,250,238,233,229,254,252,251,254,252, + 251,238,233,229,249,250,250,255,255,255,205,222,240,17,98,188,227,225,232,255, + 252,241,255,242,237,255,244,238,255,243,237,255,249,240,221,222,230,25,104,190, + 23,103,189,28,105,190,11,95,187,179,197,222,58,122,196,138,179,223,255,255, + 255,248,249,250,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,254, + 254,255,252,253,254,68,132,203,66,126,196,218,226,232,240,236,235,241,234,234, + 242,235,235,240,233,234,245,242,237,125,164,211,21,101,189,22,103,190,80,137, + 202,112,156,207,27,106,191,226,236,246,254,255,255,250,251,251,238,233,229,254, + 252,251,254,252,251,238,233,229,252,251,251,254,255,255,254,254,255,240,245,250, + 67,131,203,17,97,187,30,108,191,29,106,190,30,106,190,29,106,190,29,106, + 190,38,111,192,17,99,187,15,97,187,27,105,190,36,112,194,208,224,242,255, + 255,255,254,254,255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229, + 252,251,251,255,255,255,254,254,255,255,255,255,255,255,255,204,222,241,190,212, + 237,193,214,238,192,214,238,192,214,238,192,214,237,190,213,237,196,216,238,196, + 216,238,194,215,238,247,250,253,255,255,255,254,254,255,255,255,255,252,251,251, + 238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,255,255,255,255,255, + 255,254,254,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, + 253,254,254,255,255,255,255,255,255,252,251,251,238,233,229,254,252,251,254,252, + 251,238,233,229,252,251,251,255,255,255,255,255,255,255,255,255,254,255,255,253, + 253,254,252,253,254,252,253,254,252,253,254,252,253,254,252,253,254,252,253,254, + 252,253,254,252,253,254,252,253,254,254,254,255,255,255,255,255,255,255,255,255, + 255,252,251,251,238,233,229,254,252,251,254,252,251,238,233,229,252,251,251,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,252,251,251,238,233,229,254, + 252,251,255,253,252,239,234,230,250,249,248,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,250,249,248,239,234,230,255,253,252,255,253,252,246,243,240, + 240,235,231,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,240,235,231, + 246,243,240,255,253,252,253,251,250,254,253,252,241,236,233,240,234,231,250,248, + 247,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252, + 251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251,252,251,251, + 252,251,251,250,248,247,240,234,231,241,236,233,254,253,252,253,251,250,253,251, + 250,253,251,250,254,253,252,246,242,240,239,234,230,238,232,228,238,232,229,238, + 233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229,238,233,229, + 238,233,229,238,233,229,238,233,229,238,232,229,238,232,228,239,234,230,246,242, + 240,254,253,252,253,251,250,253,251,250,253,251,250,253,251,250,253,251,250,255, + 253,252,254,253,252,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251, + 254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252,251,254,252, + 251,254,252,251,254,252,251,254,253,252,255,253,252,253,251,250,253,251,250,253, + 251,250 + ); + CEditorAsset101 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128, + 128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128, + 128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,128, + 128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,128,128,128,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,128,128,128,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,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,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,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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset102 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,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,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,0, + 0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,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,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,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 + ); + CEditorAsset103 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,253,251,250,253,251,250, + 255,253,252,253,251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249, + 246,244,249,246,244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252, + 253,251,250,253,251,250,253,251,249,254,253,252,246,242,240,237,231,227,239,234, + 230,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,230,237,231,227,246,242,240,254,253,252,253,251,249,255,253, + 252,246,242,240,238,232,229,252,251,250,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,252,251, + 250,238,232,229,246,242,240,255,253,252,253,251,250,237,231,227,253,252,252,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,253,252,252,237,231,227,253, + 251,250,249,246,244,239,234,231,255,255,255,255,255,255,255,254,254,245,226,221, + 245,227,222,245,227,222,245,227,222,245,227,222,245,227,222,245,227,222,245,227, + 222,245,227,222,245,227,222,245,227,222,245,226,221,246,228,223,244,224,219,253, + 248,247,255,255,255,255,255,255,239,234,231,249,246,244,249,246,244,239,234,231, + 255,255,255,252,247,245,213,133,111,199,95,67,202,103,77,202,102,75,202,102, + 75,202,102,75,202,102,75,202,102,75,202,102,75,202,102,75,202,102,75,202, + 101,74,204,109,83,202,102,75,202,102,75,207,117,93,247,233,229,255,255,255, + 239,233,230,249,246,244,249,246,244,239,232,229,255,255,255,239,208,200,201,99, + 71,250,241,238,251,242,239,251,242,239,251,242,239,251,242,239,251,242,239,251, + 242,239,251,242,239,251,242,239,251,241,238,251,242,239,240,210,202,237,201,191, + 223,162,145,207,116,92,227,174,159,255,255,255,239,232,228,249,246,244,249,246, + 244,239,232,229,255,255,255,238,207,198,205,111,86,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,254,253,255,255,255,236,201,191,218,149,130,235,196,185,198,90,60,229,181, + 168,255,255,255,239,232,228,249,246,244,249,246,244,239,232,229,255,255,255,238, + 207,198,204,109,83,255,253,253,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,254,255,255, + 255,234,195,184,222,159,141,209,121,97,227,175,161,255,255,255,239,232,228,249, + 246,244,249,246,244,239,232,229,255,255,255,237,206,197,206,111,85,245,244,243, + 119,106,97,107,92,83,110,96,87,109,95,86,109,95,86,109,95,86,109,95, + 86,109,95,86,111,97,89,98,83,74,181,172,166,255,255,255,240,213,206,205, + 110,84,228,177,164,255,255,255,239,232,228,249,246,244,249,246,244,239,232,229, + 255,255,255,238,207,198,205,110,84,253,251,251,221,216,213,218,213,210,219,214, + 211,218,213,210,218,213,210,218,213,210,218,213,210,218,213,210,219,214,211,216, + 210,207,236,233,231,253,250,249,255,255,255,213,133,112,226,172,158,255,255,255, + 239,232,228,249,246,244,249,246,244,239,232,229,255,255,255,238,207,198,204,109, + 83,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,254, + 255,255,255,214,131,109,226,173,159,255,255,255,239,232,228,249,246,244,249,246, + 244,239,232,229,255,255,255,237,206,197,206,111,85,245,244,243,117,105,96,105, + 90,81,108,94,85,108,94,84,108,94,84,108,94,84,108,94,84,108,94,84, + 108,94,85,108,93,84,108,94,85,110,95,86,104,96,88,129,69,51,235,183, + 169,255,255,255,239,232,228,249,246,244,249,246,244,239,232,229,255,255,255,238, + 207,198,205,110,84,253,251,251,221,216,213,218,213,210,219,214,211,218,213,210, + 218,213,210,218,213,210,218,213,210,218,213,210,218,213,210,218,213,210,218,213, + 210,218,212,209,217,215,214,191,115,94,228,175,161,255,255,255,239,232,228,249, + 246,244,249,246,244,239,232,229,255,255,255,238,207,198,204,109,83,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,216, + 133,111,226,173,159,255,255,255,239,232,228,249,246,244,249,246,244,239,232,229, + 255,255,255,237,206,197,206,111,85,245,243,242,117,105,96,105,90,81,109,94, + 85,108,94,85,108,94,85,108,94,85,108,94,85,108,94,85,108,94,85,108, + 94,85,110,96,87,97,81,71,202,202,200,221,140,118,225,171,156,255,255,255, + 239,232,228,249,246,244,249,246,244,239,232,229,255,255,255,238,207,198,205,111, + 85,252,251,251,221,216,213,218,212,209,219,213,210,219,213,210,219,213,210,219, + 213,210,219,213,210,219,213,210,219,213,210,219,213,210,219,214,211,215,209,205, + 242,242,241,215,134,112,226,173,159,255,255,255,239,232,228,249,246,244,249,246, + 244,239,232,229,255,255,255,238,205,196,202,104,77,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,210,126,103,225,170, + 155,255,255,255,239,232,228,249,246,244,249,246,244,239,233,230,255,255,255,250, + 239,237,206,113,88,204,108,82,205,114,90,205,113,88,205,113,88,205,113,88, + 205,113,88,205,113,88,205,113,88,205,113,88,205,113,88,205,113,88,205,113, + 88,205,113,88,205,112,87,202,100,73,243,220,214,255,255,255,239,233,230,249, + 246,244,249,246,244,239,234,231,255,255,255,255,255,255,250,240,237,234,194,183, + 235,197,186,234,196,186,234,196,186,234,196,186,234,196,186,234,196,186,234,196, + 186,234,196,186,234,196,186,234,196,186,234,196,186,235,197,187,233,193,182,246, + 229,224,255,255,255,255,255,255,239,234,231,249,246,244,253,251,250,237,231,227, + 253,252,252,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,253,252,252, + 237,231,227,253,251,250,255,253,252,246,242,240,238,232,229,252,251,250,255,255, + 255,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255, + 254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254,255,254,254, + 255,254,254,255,255,255,252,251,250,238,232,229,246,242,240,255,253,252,253,251, + 249,254,253,252,246,242,240,237,231,227,239,234,230,239,234,231,239,234,231,239, + 234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,231, + 239,234,231,239,234,231,239,234,231,239,234,231,239,234,231,239,234,230,237,231, + 227,246,242,240,254,253,252,253,251,249,253,251,250,253,251,250,255,253,252,253, + 251,250,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244, + 249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246,244,249,246, + 244,249,246,244,249,246,244,249,246,244,253,251,250,255,253,252,253,251,250,253, + 251,250 + ); + CEditorAsset104 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,255, + 255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,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, + 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,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,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,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,0,0,0,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,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,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,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,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,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,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,0,0,0,255,255,255,255,255,255,255, + 255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0, + 0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255, + 0,0,0,0,0,0,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,0, + 0,0,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,0,0,0,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,0,0,0,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,0,0,0,0,0,0,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,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, + 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,0,0,0,0,0,0,0,0,0,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,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,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,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,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset105 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0, + 0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255,0, + 0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,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,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0, + 0,0,0,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,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,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,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,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,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,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,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 + ); + CEditorAsset106 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,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,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,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,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,255,255,255,255,255,255, + 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,255,255,255,255,255,255,0,0,0,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,128,128,128,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,255,255,255, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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, + 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,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,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,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, + 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,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,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); + CEditorAsset107 : Array[0..1781] Of Byte = ( + 66,77,246,6,0,0,0,0,0,0,54,0,0,0,40,0,0,0,24,0, + 0,0,24,0,0,0,1,0,24,0,0,0,0,0,192,6,0,0,196,14, + 0,0,196,14,0,0,0,0,0,0,0,0,0,0,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,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,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,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,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,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, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,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,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,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,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0, + 0,255,255,255,255,255,255,0,0,0,0,0,0,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, + 255,255,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,255,255,255,255,255,255,255,255,255,255,255,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,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, + 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,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,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,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,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,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,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,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,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255 + ); +Function RESTDWEnsureHTMLWebAssets : String; +Var + LBase : String; +Begin + LBase := + IncludeTrailingPathDelimiter( + GetEnvironmentVariable('TEMP') + ) + + 'RESTDataware' + PathDelim + + 'HTMLEditor' + PathDelim + + 'assets'; + If Not DirectoryExists(LBase) Then + ForceDirectories(LBase); + WriteAsset( + LBase, + 'bootstrap\css\bootstrap.min.css', + CAsset0[0], + SizeOf(CAsset0) + ); + WriteAsset( + LBase, + 'datatables\dataTables.dataTables.min.css', + CAsset1[0], + SizeOf(CAsset1) + ); + WriteAsset( + LBase, + 'bootstrap\js\bootstrap.bundle.min.js', + CAsset2[0], + SizeOf(CAsset2) + ); + WriteAsset( + LBase, + 'datatables\dataTables.min.js', + CAsset3[0], + SizeOf(CAsset3) + ); + WriteAsset( + LBase, + 'chartjs\chart.umd.min.js', + CAsset4[0], + SizeOf(CAsset4) + ); + WriteAsset( + LBase, + 'branding\rdw.jpg', + CAsset5[0], + SizeOf(CAsset5) + ); + WriteAsset( + LBase, + 'branding\logo-rdw-oficial.png', + CAsset6[0], + SizeOf(CAsset6) + ); + WriteAsset( + LBase, + 'Packages\Bootstrap.ini', + CEditorAsset0[0], + SizeOf(CEditorAsset0) + ); + WriteAsset( + LBase, + 'Packages\ChartJS.ini', + CEditorAsset1[0], + SizeOf(CEditorAsset1) + ); + WriteAsset( + LBase, + 'Packages\DataTables.ini', + CEditorAsset2[0], + SizeOf(CEditorAsset2) + ); + WriteAsset( + LBase, + 'Packages\Standard.ini', + CEditorAsset3[0], + SizeOf(CEditorAsset3) + ); + WriteAsset( + LBase, + 'Packages\bootstrap.js', + CEditorAsset4[0], + SizeOf(CEditorAsset4) + ); + WriteAsset( + LBase, + 'Packages\chartjs.js', + CEditorAsset5[0], + SizeOf(CEditorAsset5) + ); + WriteAsset( + LBase, + 'Packages\datatables.js', + CEditorAsset6[0], + SizeOf(CEditorAsset6) + ); + WriteAsset( + LBase, + 'Packages\standard.js', + CEditorAsset7[0], + SizeOf(CEditorAsset7) + ); + WriteAsset( + LBase, + 'icons\accordion.bmp', + CEditorAsset8[0], + SizeOf(CEditorAsset8) + ); + WriteAsset( + LBase, + 'icons\alert_danger.bmp', + CEditorAsset9[0], + SizeOf(CEditorAsset9) + ); + WriteAsset( + LBase, + 'icons\alert_primary.bmp', + CEditorAsset10[0], + SizeOf(CEditorAsset10) + ); + WriteAsset( + LBase, + 'icons\alert_success.bmp', + CEditorAsset11[0], + SizeOf(CEditorAsset11) + ); + WriteAsset( + LBase, + 'icons\badge.bmp', + CEditorAsset12[0], + SizeOf(CEditorAsset12) + ); + WriteAsset( + LBase, + 'icons\bordered_table.bmp', + CEditorAsset13[0], + SizeOf(CEditorAsset13) + ); + WriteAsset( + LBase, + 'icons\breadcrumb.bmp', + CEditorAsset14[0], + SizeOf(CEditorAsset14) + ); + WriteAsset( + LBase, + 'icons\button_group.bmp', + CEditorAsset15[0], + SizeOf(CEditorAsset15) + ); + WriteAsset( + LBase, + 'icons\card.bmp', + CEditorAsset16[0], + SizeOf(CEditorAsset16) + ); + WriteAsset( + LBase, + 'icons\card_with_footer.bmp', + CEditorAsset17[0], + SizeOf(CEditorAsset17) + ); + WriteAsset( + LBase, + 'icons\chart_bar.bmp', + CEditorAsset18[0], + SizeOf(CEditorAsset18) + ); + WriteAsset( + LBase, + 'icons\chart_line.bmp', + CEditorAsset19[0], + SizeOf(CEditorAsset19) + ); + WriteAsset( + LBase, + 'icons\chart_pie.bmp', + CEditorAsset20[0], + SizeOf(CEditorAsset20) + ); + WriteAsset( + LBase, + 'icons\checkbox.bmp', + CEditorAsset21[0], + SizeOf(CEditorAsset21) + ); + WriteAsset( + LBase, + 'icons\collapse.bmp', + CEditorAsset22[0], + SizeOf(CEditorAsset22) + ); + WriteAsset( + LBase, + 'icons\color_picker.bmp', + CEditorAsset23[0], + SizeOf(CEditorAsset23) + ); + WriteAsset( + LBase, + 'icons\columns_3_9.bmp', + CEditorAsset24[0], + SizeOf(CEditorAsset24) + ); + WriteAsset( + LBase, + 'icons\columns_4_4_4.bmp', + CEditorAsset25[0], + SizeOf(CEditorAsset25) + ); + WriteAsset( + LBase, + 'icons\columns_6_6.bmp', + CEditorAsset26[0], + SizeOf(CEditorAsset26) + ); + WriteAsset( + LBase, + 'icons\container.bmp', + CEditorAsset27[0], + SizeOf(CEditorAsset27) + ); + WriteAsset( + LBase, + 'icons\container_fluid.bmp', + CEditorAsset28[0], + SizeOf(CEditorAsset28) + ); + WriteAsset( + LBase, + 'icons\crud_toolbar.bmp', + CEditorAsset29[0], + SizeOf(CEditorAsset29) + ); + WriteAsset( + LBase, + 'icons\danger.bmp', + CEditorAsset30[0], + SizeOf(CEditorAsset30) + ); + WriteAsset( + LBase, + 'icons\dark.bmp', + CEditorAsset31[0], + SizeOf(CEditorAsset31) + ); + WriteAsset( + LBase, + 'icons\dashboard_grid.bmp', + CEditorAsset32[0], + SizeOf(CEditorAsset32) + ); + WriteAsset( + LBase, + 'icons\datatable.bmp', + CEditorAsset33[0], + SizeOf(CEditorAsset33) + ); + WriteAsset( + LBase, + 'icons\datatable_crud.bmp', + CEditorAsset34[0], + SizeOf(CEditorAsset34) + ); + WriteAsset( + LBase, + 'icons\date_picker.bmp', + CEditorAsset35[0], + SizeOf(CEditorAsset35) + ); + WriteAsset( + LBase, + 'icons\datetime_picker.bmp', + CEditorAsset36[0], + SizeOf(CEditorAsset36) + ); + WriteAsset( + LBase, + 'icons\decimal_edit.bmp', + CEditorAsset37[0], + SizeOf(CEditorAsset37) + ); + WriteAsset( + LBase, + 'icons\disabled_edit.bmp', + CEditorAsset38[0], + SizeOf(CEditorAsset38) + ); + WriteAsset( + LBase, + 'icons\dropdown.bmp', + CEditorAsset39[0], + SizeOf(CEditorAsset39) + ); + WriteAsset( + LBase, + 'icons\email_edit.bmp', + CEditorAsset40[0], + SizeOf(CEditorAsset40) + ); + WriteAsset( + LBase, + 'icons\file_upload.bmp', + CEditorAsset41[0], + SizeOf(CEditorAsset41) + ); + WriteAsset( + LBase, + 'icons\flex_row.bmp', + CEditorAsset42[0], + SizeOf(CEditorAsset42) + ); + WriteAsset( + LBase, + 'icons\grid.bmp', + CEditorAsset43[0], + SizeOf(CEditorAsset43) + ); + WriteAsset( + LBase, + 'icons\heading_h1.bmp', + CEditorAsset44[0], + SizeOf(CEditorAsset44) + ); + WriteAsset( + LBase, + 'icons\heading_h2.bmp', + CEditorAsset45[0], + SizeOf(CEditorAsset45) + ); + WriteAsset( + LBase, + 'icons\heading_h3.bmp', + CEditorAsset46[0], + SizeOf(CEditorAsset46) + ); + WriteAsset( + LBase, + 'icons\horizontal_rule.bmp', + CEditorAsset47[0], + SizeOf(CEditorAsset47) + ); + WriteAsset( + LBase, + 'icons\image.bmp', + CEditorAsset48[0], + SizeOf(CEditorAsset48) + ); + WriteAsset( + LBase, + 'icons\info.bmp', + CEditorAsset49[0], + SizeOf(CEditorAsset49) + ); + WriteAsset( + LBase, + 'icons\input_group.bmp', + CEditorAsset50[0], + SizeOf(CEditorAsset50) + ); + WriteAsset( + LBase, + 'icons\kpi_card.bmp', + CEditorAsset51[0], + SizeOf(CEditorAsset51) + ); + WriteAsset( + LBase, + 'icons\kpi_cards_4.bmp', + CEditorAsset52[0], + SizeOf(CEditorAsset52) + ); + WriteAsset( + LBase, + 'icons\large_button.bmp', + CEditorAsset53[0], + SizeOf(CEditorAsset53) + ); + WriteAsset( + LBase, + 'icons\lead_text.bmp', + CEditorAsset54[0], + SizeOf(CEditorAsset54) + ); + WriteAsset( + LBase, + 'icons\light.bmp', + CEditorAsset55[0], + SizeOf(CEditorAsset55) + ); + WriteAsset( + LBase, + 'icons\link.bmp', + CEditorAsset56[0], + SizeOf(CEditorAsset56) + ); + WriteAsset( + LBase, + 'icons\list_group.bmp', + CEditorAsset57[0], + SizeOf(CEditorAsset57) + ); + WriteAsset( + LBase, + 'icons\modal.bmp', + CEditorAsset58[0], + SizeOf(CEditorAsset58) + ); + WriteAsset( + LBase, + 'icons\money_edit.bmp', + CEditorAsset59[0], + SizeOf(CEditorAsset59) + ); + WriteAsset( + LBase, + 'icons\month_picker.bmp', + CEditorAsset60[0], + SizeOf(CEditorAsset60) + ); + WriteAsset( + LBase, + 'icons\multi_select.bmp', + CEditorAsset61[0], + SizeOf(CEditorAsset61) + ); + WriteAsset( + LBase, + 'icons\nav_pills.bmp', + CEditorAsset62[0], + SizeOf(CEditorAsset62) + ); + WriteAsset( + LBase, + 'icons\nav_tabs.bmp', + CEditorAsset63[0], + SizeOf(CEditorAsset63) + ); + WriteAsset( + LBase, + 'icons\navbar.bmp', + CEditorAsset64[0], + SizeOf(CEditorAsset64) + ); + WriteAsset( + LBase, + 'icons\number_edit.bmp', + CEditorAsset65[0], + SizeOf(CEditorAsset65) + ); + WriteAsset( + LBase, + 'icons\offcanvas.bmp', + CEditorAsset66[0], + SizeOf(CEditorAsset66) + ); + WriteAsset( + LBase, + 'icons\outline_primary.bmp', + CEditorAsset67[0], + SizeOf(CEditorAsset67) + ); + WriteAsset( + LBase, + 'icons\pagination.bmp', + CEditorAsset68[0], + SizeOf(CEditorAsset68) + ); + WriteAsset( + LBase, + 'icons\paragraph.bmp', + CEditorAsset69[0], + SizeOf(CEditorAsset69) + ); + WriteAsset( + LBase, + 'icons\password_edit.bmp', + CEditorAsset70[0], + SizeOf(CEditorAsset70) + ); + WriteAsset( + LBase, + 'icons\percent_edit.bmp', + CEditorAsset71[0], + SizeOf(CEditorAsset71) + ); + WriteAsset( + LBase, + 'icons\primary.bmp', + CEditorAsset72[0], + SizeOf(CEditorAsset72) + ); + WriteAsset( + LBase, + 'icons\progress.bmp', + CEditorAsset73[0], + SizeOf(CEditorAsset73) + ); + WriteAsset( + LBase, + 'icons\radio_group.bmp', + CEditorAsset74[0], + SizeOf(CEditorAsset74) + ); + WriteAsset( + LBase, + 'icons\range.bmp', + CEditorAsset75[0], + SizeOf(CEditorAsset75) + ); + WriteAsset( + LBase, + 'icons\readonly_edit.bmp', + CEditorAsset76[0], + SizeOf(CEditorAsset76) + ); + WriteAsset( + LBase, + 'icons\row.bmp', + CEditorAsset77[0], + SizeOf(CEditorAsset77) + ); + WriteAsset( + LBase, + 'icons\search_edit.bmp', + CEditorAsset78[0], + SizeOf(CEditorAsset78) + ); + WriteAsset( + LBase, + 'icons\secondary.bmp', + CEditorAsset79[0], + SizeOf(CEditorAsset79) + ); + WriteAsset( + LBase, + 'icons\select.bmp', + CEditorAsset80[0], + SizeOf(CEditorAsset80) + ); + WriteAsset( + LBase, + 'icons\small_button.bmp', + CEditorAsset81[0], + SizeOf(CEditorAsset81) + ); + WriteAsset( + LBase, + 'icons\small_text.bmp', + CEditorAsset82[0], + SizeOf(CEditorAsset82) + ); + WriteAsset( + LBase, + 'icons\spinner.bmp', + CEditorAsset83[0], + SizeOf(CEditorAsset83) + ); + WriteAsset( + LBase, + 'icons\standard_button.bmp', + CEditorAsset84[0], + SizeOf(CEditorAsset84) + ); + WriteAsset( + LBase, + 'icons\standard_checkbox.bmp', + CEditorAsset85[0], + SizeOf(CEditorAsset85) + ); + WriteAsset( + LBase, + 'icons\standard_combobox.bmp', + CEditorAsset86[0], + SizeOf(CEditorAsset86) + ); + WriteAsset( + LBase, + 'icons\standard_edit.bmp', + CEditorAsset87[0], + SizeOf(CEditorAsset87) + ); + WriteAsset( + LBase, + 'icons\standard_grid.bmp', + CEditorAsset88[0], + SizeOf(CEditorAsset88) + ); + WriteAsset( + LBase, + 'icons\standard_groupbox.bmp', + CEditorAsset89[0], + SizeOf(CEditorAsset89) + ); + WriteAsset( + LBase, + 'icons\standard_hidden.bmp', + CEditorAsset90[0], + SizeOf(CEditorAsset90) + ); + WriteAsset( + LBase, + 'icons\standard_image.bmp', + CEditorAsset91[0], + SizeOf(CEditorAsset91) + ); + WriteAsset( + LBase, + 'icons\standard_label.bmp', + CEditorAsset92[0], + SizeOf(CEditorAsset92) + ); + WriteAsset( + LBase, + 'icons\standard_link.bmp', + CEditorAsset93[0], + SizeOf(CEditorAsset93) + ); + WriteAsset( + LBase, + 'icons\standard_listbox.bmp', + CEditorAsset94[0], + SizeOf(CEditorAsset94) + ); + WriteAsset( + LBase, + 'icons\standard_memo.bmp', + CEditorAsset95[0], + SizeOf(CEditorAsset95) + ); + WriteAsset( + LBase, + 'icons\standard_panel.bmp', + CEditorAsset96[0], + SizeOf(CEditorAsset96) + ); + WriteAsset( + LBase, + 'icons\standard_progress.bmp', + CEditorAsset97[0], + SizeOf(CEditorAsset97) + ); + WriteAsset( + LBase, + 'icons\standard_radio.bmp', + CEditorAsset98[0], + SizeOf(CEditorAsset98) + ); + WriteAsset( + LBase, + 'icons\success.bmp', + CEditorAsset99[0], + SizeOf(CEditorAsset99) + ); + WriteAsset( + LBase, + 'icons\switch.bmp', + CEditorAsset100[0], + SizeOf(CEditorAsset100) + ); + WriteAsset( + LBase, + 'icons\table.bmp', + CEditorAsset101[0], + SizeOf(CEditorAsset101) + ); + WriteAsset( + LBase, + 'icons\text_edit.bmp', + CEditorAsset102[0], + SizeOf(CEditorAsset102) + ); + WriteAsset( + LBase, + 'icons\textarea.bmp', + CEditorAsset103[0], + SizeOf(CEditorAsset103) + ); + WriteAsset( + LBase, + 'icons\time_picker.bmp', + CEditorAsset104[0], + SizeOf(CEditorAsset104) + ); + WriteAsset( + LBase, + 'icons\toast.bmp', + CEditorAsset105[0], + SizeOf(CEditorAsset105) + ); + WriteAsset( + LBase, + 'icons\warning.bmp', + CEditorAsset106[0], + SizeOf(CEditorAsset106) + ); + WriteAsset( + LBase, + 'icons\week_picker.bmp', + CEditorAsset107[0], + SizeOf(CEditorAsset107) + ); + Result := LBase; +End; +end. diff --git a/CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLWebView.pas b/CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLWebView.pas new file mode 100644 index 000000000..ee23e9fd8 --- /dev/null +++ b/CORE/Source/Plugins/HTMLEditor/uRESTDWHTMLWebView.pas @@ -0,0 +1,1875 @@ +unit uRESTDWHTMLWebView; +{$IFDEF FPC} +{$mode delphi}{$H+} +{$ENDIF} +Interface +Uses + Classes, SysUtils, StrUtils, Controls, ExtCtrls, uRESTDWHTMLJSONCompat, uRESTDWHTMLWebAssets + {$IFDEF MSWINDOWS}, + Windows, uRESTDWPrivWVBrowser, uRESTDWPrivWVWindowParent, uRESTDWPrivWVLoader, uRESTDWPrivWVTypes, uRESTDWPrivWVEvents, + uRESTDWPrivWVTypeLibrary, uRESTDWPrivWVCoreWebView2Args + {$ENDIF}; +Type + TRESTDWHTMLWebViewErrorEvent = Procedure(Sender : TObject; + const AMessage : String) Of Object; + TRESTDWHTMLWebViewPageErrorEvent = Procedure(Sender : TObject; + const AKind, ASource, AMessage : String; + ALine, AColumn : Integer) Of Object; + TRESTDWHTMLWebViewElementSelectedEvent = Procedure(Sender : TObject; + const AElementID, ATagName, AText, AID, AClassName, + AOuterHTML : String) Of Object; + TRESTDWHTMLWebViewHTMLChangedEvent = Procedure(Sender : TObject; + const AHTML : String) Of Object; + TRESTDWHTMLWebViewObjectTreeEvent = Procedure(Sender : TObject; + const AJSON : String) Of Object; + TRESTDWHTMLWebViewDebugBreakpointEvent = Procedure(Sender : TObject; + ALine : Integer) Of Object; + TRESTDWHTMLWebViewDebugEvaluateEvent = Procedure(Sender : TObject; + ARequestID : Integer; const AExpression, AValue, AError : String; + ASuccess : Boolean) Of Object; + TDSWebViewDragOverEvent = Procedure(Sender, Source : TObject; + X, Y : Integer; State : TDragState; Var Accept : Boolean) Of Object; + TDSWebViewDragDropEvent = Procedure(Sender, Source : TObject; + X, Y : Integer) Of Object; + TRESTDWHTMLWebView = Class(TCustomControl) + Private + FHTML : String; + FPreviewFileName : String; + FPreviewFolder : String; + FAssetsFolder : String; + FVirtualHostsReady : Boolean; + FNavigationSerial : Integer; + FOnDesignDragOver : TDSWebViewDragOverEvent; + FOnDesignDragDrop : TDSWebViewDragDropEvent; + FReady : Boolean; + FStarted : Boolean; + FOnReady : TNotifyEvent; + FOnError : TRESTDWHTMLWebViewErrorEvent; + FOnPageError : TRESTDWHTMLWebViewPageErrorEvent; + FOnElementSelected : TRESTDWHTMLWebViewElementSelectedEvent; + FOnHTMLChanged : TRESTDWHTMLWebViewHTMLChangedEvent; + FOnObjectTree : TRESTDWHTMLWebViewObjectTreeEvent; + FOnDebugBreakpoint : TRESTDWHTMLWebViewDebugBreakpointEvent; + FOnDebugEvaluate : TRESTDWHTMLWebViewDebugEvaluateEvent; + FDebugCallFrameID : String; + FDebugScriptID : String; + FDebugSourceLine : Integer; + FDebugExpressions : TStringList; + {$IFDEF MSWINDOWS} + FWindowParent : TWVWindowParent; + FBrowser : TWVBrowser; + FInitTimer : TTimer; + FInitTicks : Integer; + FLoaderReadyTicks : Integer; + Procedure InitTimer(Sender : TObject); + Procedure BrowserAfterCreated(Sender : TObject); + Procedure BrowserInitializationError(Sender : TObject; + AErrorCode : HRESULT; const AErrorMessage : wvstring); + Procedure BrowserWebMessageReceived(Sender : TObject; + const AWebView : ICoreWebView2; + const AArgs : ICoreWebView2WebMessageReceivedEventArgs); + Procedure BrowserNavigationCompleted(Sender : TObject; + const AWebView : ICoreWebView2; + const AArgs : ICoreWebView2NavigationCompletedEventArgs); + Procedure BrowserDevToolsEventReceived(Sender : TObject; + const AWebView : ICoreWebView2; + const AArgs : ICoreWebView2DevToolsProtocolEventReceivedEventArgs; + const AEventName : wvstring; AEventID : Integer); + Procedure BrowserDevToolsMethodCompleted(Sender : TObject; + AErrorCode : HRESULT; const AResult : wvstring; AExecutionID : Integer); + Procedure InstallPageErrorBridge; + Function InjectPageErrorBridge(const AHTML : String) : String; + Procedure EmitPageError(const AKind, ASource, AMessage : String; + ALine, AColumn : Integer); + Procedure WindowDragOver(Sender, Source : TObject; + X, Y : Integer; State : TDragState; Var Accept : Boolean); + Procedure WindowDragDrop(Sender, Source : TObject; + X, Y : Integer); + {$ENDIF} + Procedure SetHTML(const AValue : String); + Procedure SetAssetsFolder(const AValue : String); + Function PrepareVirtualHosts : Boolean; + Protected + Procedure Resize; Override; + Public + Constructor Create(AOwner : TComponent); Override; + Destructor Destroy; Override; + Procedure Initialize; + Procedure Refresh; + Procedure DetachHost; + Procedure RebindHost; + Procedure OpenDevTools; + Procedure EnableDebugger; + Procedure DisableDebugger; + Procedure DebugResume; + Procedure DebugPause; + Procedure DebugStepInto; + Procedure DebugStepOver; + Procedure DebugStepOut; + Procedure DebugContinueToLine(ALine : Integer); + Procedure EvaluateDebugExpression(ARequestID : Integer; + const AExpression : String); + Procedure ModifyDebugExpression(ARequestID : Integer; + const AExpression, AValueExpression : String); + Procedure UpdateSelectedElement(const AProperty, AValue : String); + Procedure SelectElement(const AElementID : String); + Procedure InsertHTML(const AHTML : String); + Procedure InsertJSClass(const AJavaScript, AClassName, + AOptionsJSON, AHTMLExtension, AIdentity : String); + Procedure InsertHTMLAt(const AHTML : String; X, Y : Integer); + Procedure InsertJSClassAt(const AJavaScript, AClassName, + AOptionsJSON, AHTMLExtension, AIdentity : String; X, Y : Integer); + Procedure DeleteSelectedElement; + Procedure RequestHTML; + Property Ready : Boolean Read FReady; + Published + Property Align; + Property Anchors; + Property Visible; + Property Enabled; + Property HTML : String Read FHTML Write SetHTML; + Property AssetsFolder : String Read FAssetsFolder Write SetAssetsFolder; + Property OnReady : TNotifyEvent Read FOnReady Write FOnReady; + Property OnError : TRESTDWHTMLWebViewErrorEvent Read FOnError Write FOnError; + Property OnPageError : TRESTDWHTMLWebViewPageErrorEvent + Read FOnPageError Write FOnPageError; + Property OnElementSelected : TRESTDWHTMLWebViewElementSelectedEvent + Read FOnElementSelected Write FOnElementSelected; + Property OnHTMLChanged : TRESTDWHTMLWebViewHTMLChangedEvent + Read FOnHTMLChanged Write FOnHTMLChanged; + Property OnObjectTree : TRESTDWHTMLWebViewObjectTreeEvent + Read FOnObjectTree Write FOnObjectTree; + Property OnDebugBreakpoint : TRESTDWHTMLWebViewDebugBreakpointEvent + Read FOnDebugBreakpoint Write FOnDebugBreakpoint; + Property OnDebugEvaluate : TRESTDWHTMLWebViewDebugEvaluateEvent + Read FOnDebugEvaluate Write FOnDebugEvaluate; + Property OnDesignDragOver : TDSWebViewDragOverEvent + Read FOnDesignDragOver Write FOnDesignDragOver; + Property OnDesignDragDrop : TDSWebViewDragDropEvent + Read FOnDesignDragDrop Write FOnDesignDragDrop; + End; +Implementation +Var + GRESTDWHTMLWebViewCount : Integer = 0; +Function RESTDWEscapeJavaScriptString(Const AValue : String) : String; +Begin + Result := StringReplace(AValue, '\', '\\', [rfReplaceAll]); + Result := StringReplace(Result, #13, '\r', [rfReplaceAll]); + Result := StringReplace(Result, #10, '\n', [rfReplaceAll]); + Result := StringReplace(Result, #39, '\''', [rfReplaceAll]); + Result := StringReplace(Result, ' 0 Then + SetString( + Result, + LBuffer, + LLen + ) + Else + Result := ExtractFilePath(ParamStr(0)); + {$ELSE} + Result := GetEnvironmentVariable('TMPDIR'); + If Result = '' Then + Result := GetEnvironmentVariable('TEMP'); + If Result = '' Then + Result := ExtractFilePath(ParamStr(0)); + {$ENDIF} + Result := IncludeTrailingPathDelimiter(Result); +End; +Constructor TRESTDWHTMLWebView.Create(AOwner : TComponent); +Begin + Inherited Create(AOwner); + Inc(GRESTDWHTMLWebViewCount); + FHTML := ''; + FPreviewFolder := + RESTDWHTMLTempDir + + 'RESTDatawareWebPreview'; + If Not DirectoryExists(FPreviewFolder) Then + ForceDirectories(FPreviewFolder); + FPreviewFileName := + IncludeTrailingPathDelimiter(FPreviewFolder) + + 'index.html'; + FAssetsFolder := ''; + FVirtualHostsReady := False; + FNavigationSerial := 0; + FReady := False; + FStarted := False; + {$IFDEF MSWINDOWS} + FInitTicks := 0; + FLoaderReadyTicks := 0; + FWindowParent := TWVWindowParent.Create(Self); + FWindowParent.Parent := Self; + FWindowParent.Align := alClient; + FWindowParent.OnDragOver := WindowDragOver; + FWindowParent.OnDragDrop := WindowDragDrop; + FBrowser := TWVBrowser.Create(Self); + { Do not set DefaultURL here. + WebView4Delphi fires OnAfterCreated and only after it returns navigates to + DefaultURL. Setting about:blank would therefore overwrite the FormDesign + navigation started by BrowserAfterCreated. } + FBrowser.OnAfterCreated := BrowserAfterCreated; + FBrowser.OnInitializationError := BrowserInitializationError; + FBrowser.OnWebMessageReceived := BrowserWebMessageReceived; + FBrowser.OnNavigationCompleted := BrowserNavigationCompleted; + FWindowParent.Browser := FBrowser; + FInitTimer := TTimer.Create(Self); + FInitTimer.Enabled := False; + FInitTimer.Interval := 200; + FInitTimer.OnTimer := InitTimer; + {$ENDIF} +End; +Destructor TRESTDWHTMLWebView.Destroy; +Begin + {$IFDEF MSWINDOWS} + If Assigned(FInitTimer) Then + FInitTimer.Enabled := False; + If Assigned(FWindowParent) Then + FWindowParent.Browser := Nil; + If Assigned(FBrowser) Then + Begin + Try + FBrowser.IsVisible := False; + FBrowser.ParentWindow := 0; + Except + End; + FBrowser.Free; + FBrowser := Nil; + End; + If Assigned(FWindowParent) Then + Begin + FWindowParent.Free; + FWindowParent := Nil; + End; + If GRESTDWHTMLWebViewCount > 0 Then + Dec(GRESTDWHTMLWebViewCount); + If GRESTDWHTMLWebViewCount = 0 Then + DestroyGlobalWebView2Loader; + {$ENDIF} + FDebugExpressions.Free; + FDebugExpressions := Nil; + Inherited Destroy; +End; +Procedure TRESTDWHTMLWebView.Initialize; +Begin + {$IFDEF MSWINDOWS} + If FStarted Then + Exit; + FStarted := True; + FInitTicks := 0; + FLoaderReadyTicks := 0; + { Force creation of the native child host window before WebView2. } + FWindowParent.HandleNeeded; + If FWindowParent.Handle = 0 Then + Begin + FStarted := False; + If Assigned(FOnError) Then + FOnError( + Self, + 'TRESTDWHTMLWebView host window handle could not be created.' + ); + Exit; + End; + If GlobalWebView2Loader = Nil Then + Begin + GlobalWebView2Loader := TWVLoader.Create(Nil); + GlobalWebView2Loader.UseInternalLoader := True; + GlobalWebView2Loader.ShowMessageDlg := False; + GlobalWebView2Loader.UserDataFolder := + UTF8Decode( + RESTDWHTMLTempDir + + 'RESTDatawareWebView2_' + + IntToStr( + GetCurrentProcessId + ) + ); + GlobalWebView2Loader.StartWebView2; + End; + FInitTimer.Enabled := True; + {$ELSE} + FReady := False; + FStarted := False; + If Assigned(FOnError) Then + FOnError( + Self, + 'TRESTDWHTMLWebView is currently available on Windows/WebView2.' + ); + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.SetAssetsFolder( + const AValue : String); +Begin + If FAssetsFolder = AValue Then + Exit; + FAssetsFolder := AValue; + FVirtualHostsReady := False; + If FReady Then + PrepareVirtualHosts; +End; +Procedure TRESTDWHTMLWebView.SetHTML( + const AValue : String); +Begin + FHTML := AValue; + If FReady Then + Refresh; +End; +Function TRESTDWHTMLWebView.PrepareVirtualHosts : Boolean; +Var + LPreviewOK, + LAssetsOK : Boolean; +Begin + Result := False; + {$IFDEF MSWINDOWS} + If Not FReady Or + Not Assigned(FBrowser) Then + Exit; + If Not DirectoryExists(FPreviewFolder) Then + ForceDirectories(FPreviewFolder); + LPreviewOK := + FBrowser.SetVirtualHostNameToFolderMapping( + 'restdwpreview.local', + UTF8Decode( + ExpandFileName(FPreviewFolder) + ), + COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_ALLOW + ); + LAssetsOK := True; + If Trim(FAssetsFolder) <> '' Then + Begin + If Not DirectoryExists(FAssetsFolder) Then + Begin + EmitPageError( + 'Assets', + 'TRESTDWHTMLWebView', + 'Assets folder not found: ' + FAssetsFolder, + 0, + 0 + ); + LAssetsOK := False; + End + Else + LAssetsOK := + FBrowser.SetVirtualHostNameToFolderMapping( + 'restdwassets.local', + UTF8Decode( + ExpandFileName(FAssetsFolder) + ), + COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_ALLOW + ); + End; + FVirtualHostsReady := + LPreviewOK And LAssetsOK; + If Not LPreviewOK Then + EmitPageError( + 'WebView', + 'TRESTDWHTMLWebView', + 'Could not map internal preview host.', + 0, + 0 + ); + If Not LAssetsOK Then + EmitPageError( + 'WebView', + 'TRESTDWHTMLWebView', + 'Could not map internal assets host.', + 0, + 0 + ); + Result := FVirtualHostsReady; + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.Refresh; +Var + LText : TStringList; + LURL, + LHTML : String; +Begin + {$IFDEF MSWINDOWS} + If Not FReady Or + Not Assigned(FBrowser) Then + Exit; + If Not FVirtualHostsReady Then + If Not PrepareVirtualHosts Then + Exit; + LHTML := + InjectPageErrorBridge( + FHTML + ); + { ContextRules pages may keep a relative logo URL. Resolve it here at the + final WebView boundary so every preview path uses the REST Dataware asset host. } + LHTML := StringReplace( + LHTML, + 'src="./logo-rdw-oficial.png"', + 'src="https://restdwassets.local/branding/logo-rdw-oficial.png"', + [rfReplaceAll,rfIgnoreCase] + ); + LHTML := StringReplace( + LHTML, + 'src="logo-rdw-oficial.png"', + 'src="https://restdwassets.local/branding/logo-rdw-oficial.png"', + [rfReplaceAll,rfIgnoreCase] + ); + LHTML := StringReplace( + LHTML, + 'src="/logo-rdw-oficial.png"', + 'src="https://restdwassets.local/branding/logo-rdw-oficial.png"', + [rfReplaceAll,rfIgnoreCase] + ); + LText := TStringList.Create; + Try + LText.Text := LHTML; + { HTML preview must always be written as UTF-8. TStringList.SaveToFile without + an encoding uses the active ANSI code page and converts Página/Conteúdo/ + Configuração into mojibake in WebView2. } + LText.SaveToFile( + FPreviewFileName, + TEncoding.UTF8 + ); + Finally + LText.Free; + End; + Inc(FNavigationSerial); + { Each refresh uses a unique URL so WebView2 reloads the generated document. + Do not call Stop here: stopping immediately before Navigate can leave the + embedded controller with its gray host surface and no committed document. } + LURL := + 'https://restdwpreview.local/index.html?restdwrefresh=' + + IntToStr(FNavigationSerial); + If Not FBrowser.Navigate( + UTF8Decode(LURL) + ) Then + EmitPageError( + 'Navigation', + 'TRESTDWHTMLWebView', + 'WebView2 rejected the generated PageProducer refresh.', + 0, + 0 + ); + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.UpdateSelectedElement( + const AProperty, AValue : String); +Var + LScript : String; +Begin + {$IFDEF MSWINDOWS} + If Not FReady Or + Not Assigned(FBrowser) Then + Exit; + LScript := + '(function(){' + + 'var e=window.__restdwSelectedElement;if(!e){return;}' + + 'var p=' + #39 + RESTDWEscapeJavaScriptString(AProperty) + #39 + ';' + + 'var v=' + #39 + RESTDWEscapeJavaScriptString(AValue) + #39 + ';' + + 'if(p==="Text"){e.textContent=v;}' + + 'else if(p==="HTML"){e.outerHTML=v;}' + + 'else if(p==="ID"){e.id=v;}' + + 'else if(p==="Class"){e.className=v;}' + + 'else if(p==="Value"){e.value=v;e.setAttribute("value",v);}' + + 'else if(p==="Enabled"){if(v===""){e.removeAttribute("disabled");}else{e.disabled=(v.toLowerCase()==="false");}}' + + 'else if(p==="Required"){if(v===""){e.removeAttribute("required");}else{e.required=(v.toLowerCase()==="true");}}' + + 'else if(p==="ReadOnly"){if(v===""){e.removeAttribute("readonly");}else{e.readOnly=(v.toLowerCase()==="true");}}' + + 'else if(p==="Multiple"){if(v===""){e.removeAttribute("multiple");}else{e.multiple=(v.toLowerCase()==="true");}}' + + 'else{' + + ' var n=p.toLowerCase();' + + ' if(v===""){e.removeAttribute(n);}' + + ' else{e.setAttribute(n,v);}' + + '}' + + 'if(window.__restdwSyncHTML){window.__restdwSyncHTML();}' + + '})();'; + FBrowser.ExecuteScript( + UTF8Decode(LScript) + ); + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.SelectElement( + const AElementID : String); +Var + LScript : String; +Begin + {$IFDEF MSWINDOWS} + If Not FReady Or + Not Assigned(FBrowser) Or + (AElementID = '') Then + Exit; + LScript := + '(function(){' + + 'var e=document.querySelector("[data-restdw-editor-id=\"' + + RESTDWEscapeJavaScriptString(AElementID) + '\"]");' + + 'if(e&&window.__restdwSelectElement){window.__restdwSelectElement(e);' + + 'try{e.scrollIntoView({block:"nearest",inline:"nearest"});}catch(x){}}' + + '})();'; + FBrowser.ExecuteScript(UTF8Decode(LScript)); + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.InsertHTML( + const AHTML : String); +Var + LScript : String; +Begin + {$IFDEF MSWINDOWS} + If Not FReady Or + Not Assigned(FBrowser) Then + Exit; + LScript := + '(function(){' + + 'var h=' + #39 + RESTDWEscapeJavaScriptString(AHTML) + #39 + ';' + + 'var e=window.__restdwSelectedElement;' + + 'var n=null;' + + 'if(e){' + + ' var tag=(e.tagName||"").toLowerCase();' + + ' var container=(tag==="div"||tag==="section"||tag==="main"||tag==="header"||tag==="footer"||tag==="nav"||tag==="article"||tag==="aside"||tag==="form"||tag==="body");' + + ' if(container){e.insertAdjacentHTML("beforeend",h);n=e.lastElementChild;}' + + ' else if(e.parentNode){e.insertAdjacentHTML("afterend",h);n=e.nextElementSibling;}' + + '}else if(document.body){' + + ' document.body.insertAdjacentHTML("beforeend",h);' + + ' n=document.body.lastElementChild;' + + '}' + + 'if(window.__restdwSelectElement&&n){window.__restdwSelectElement(n);}' + + 'if(window.__restdwSyncHTML){window.__restdwSyncHTML();}' + + '})();'; + FBrowser.ExecuteScript( + UTF8Decode(LScript) + ); + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.InsertJSClass( + const AJavaScript, + AClassName, + AOptionsJSON, + AHTMLExtension, + AIdentity : String); +Var + LScript, + LClassScript : String; +Begin + {$IFDEF MSWINDOWS} + If Not FReady Or + Not Assigned(FBrowser) Then + Exit; + LClassScript := StringReplace(AJavaScript,'export default ','',[rfReplaceAll]); + LClassScript := StringReplace(LClassScript,'export ','',[rfReplaceAll]); + LScript := + '(function(){' + + LClassScript + + 'var o=JSON.parse(' + #39 + + RESTDWEscapeJavaScriptString(AOptionsJSON) + #39 + ');' + + 'var h=' + AClassName + '.createHTML(o);' + + 'if(h===undefined||h===null){h="";}h=String(h);' + + 'var ext=' + #39 + + RESTDWEscapeJavaScriptString(AHTMLExtension) + #39 + ';' + + 'var e=window.__restdwSelectedElement;' + + 'if(!e||e===document.documentElement){e=document.body;}' + + 'if(!e){return;}' + + 'var tag=(e.tagName||"").toLowerCase();' + + 'var c=(tag==="div"||tag==="section"||tag==="main"||tag==="header"||' + + 'tag==="footer"||tag==="nav"||tag==="article"||tag==="aside"||' + + 'tag==="form"||tag==="body");' + + 'var m=document.createElement("span");m.style.display="none";' + + 'var z=document.createElement("span");z.style.display="none";' + + 'if(c){e.appendChild(m);m.insertAdjacentElement("afterend",z);}' + + 'else if(e.parentNode){e.insertAdjacentElement("afterend",m);' + + 'm.insertAdjacentElement("afterend",z);}' + + 'else{document.body.appendChild(m);m.insertAdjacentElement("afterend",z);}' + + 'm.insertAdjacentHTML("afterend",h);' + + 'var n=m.nextElementSibling;' + + 'if(ext){z.insertAdjacentHTML("beforebegin",ext);}' + + 'm.remove();z.remove();' + + 'if(n){n.id=' + #39 + + RESTDWEscapeJavaScriptString(AIdentity) + #39 + ';' + + 'n.setAttribute("name",' + #39 + + RESTDWEscapeJavaScriptString(AIdentity) + #39 + ');' + + 'for(var k in o){if(Object.prototype.hasOwnProperty.call(o,k)){' + + 'n.setAttribute("data-laz-"+String(k).replace(/_/g,"-").toLowerCase(),' + + 'String(o[k]));}}' + + 'if(typeof ' + AClassName + '.mount==="function"){' + + AClassName + '.mount(n,o);}' + + '}' + + 'if(window.__restdwSelectElement&&n){window.__restdwSelectElement(n);}' + + 'if(window.__restdwSyncHTML){window.__restdwSyncHTML();}' + + '})();'; + FBrowser.ExecuteScript(UTF8Decode(LScript)); + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.InsertHTMLAt( + const AHTML : String; + X, Y : Integer); +Var + LScript : String; +Begin + {$IFDEF MSWINDOWS} + If Not FReady Or + Not Assigned(FBrowser) Then + Exit; + LScript := + '(function(){' + + 'var h=' + #39 + RESTDWEscapeJavaScriptString(AHTML) + #39 + ';' + + 'var x=' + IntToStr(X) + ';' + + 'var y=' + IntToStr(Y) + ';' + + 'var e=document.elementFromPoint(x,y);' + + 'var n=null;' + + 'if(e===document.documentElement){e=document.body;}' + + 'if(e){' + + ' var tag=(e.tagName||"").toLowerCase();' + + ' var container=(tag==="div"||tag==="section"||tag==="main"||tag==="header"||tag==="footer"||tag==="nav"||tag==="article"||tag==="aside"||tag==="form"||tag==="body");' + + ' if(container){' + + ' e.insertAdjacentHTML("beforeend",h);' + + ' n=e.lastElementChild;' + + ' }else if(e.parentNode){' + + ' e.insertAdjacentHTML("afterend",h);' + + ' n=e.nextElementSibling;' + + ' }' + + '}else if(document.body){' + + ' document.body.insertAdjacentHTML("beforeend",h);' + + ' n=document.body.lastElementChild;' + + '}' + + 'if(window.__restdwSelectElement&&n){window.__restdwSelectElement(n);}' + + 'if(window.__restdwSyncHTML){window.__restdwSyncHTML();}' + + '})();'; + FBrowser.ExecuteScript( + UTF8Decode(LScript) + ); + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.InsertJSClassAt( + const AJavaScript, + AClassName, + AOptionsJSON, + AHTMLExtension, + AIdentity : String; + X, Y : Integer); +Var + LScript, + LClassScript : String; +Begin + {$IFDEF MSWINDOWS} + If Not FReady Or + Not Assigned(FBrowser) Then + Exit; + LClassScript := StringReplace(AJavaScript,'export default ','',[rfReplaceAll]); + LClassScript := StringReplace(LClassScript,'export ','',[rfReplaceAll]); + LScript := + '(function(){' + + LClassScript + + 'var o=JSON.parse(' + #39 + + RESTDWEscapeJavaScriptString(AOptionsJSON) + #39 + ');' + + 'var h=' + AClassName + '.createHTML(o);' + + 'if(h===undefined||h===null){h="";}h=String(h);' + + 'var ext=' + #39 + + RESTDWEscapeJavaScriptString(AHTMLExtension) + #39 + ';' + + 'var x=' + IntToStr(X) + ';var y=' + IntToStr(Y) + ';' + + 'var e=document.elementFromPoint(x,y);' + + 'if(e===document.documentElement){e=document.body;}' + + 'var c=false;if(e){var tag=(e.tagName||"").toLowerCase();' + + 'c=(tag==="div"||tag==="section"||tag==="main"||tag==="header"||' + + 'tag==="footer"||tag==="nav"||tag==="article"||tag==="aside"||' + + 'tag==="form"||tag==="body");}' + + 'if(!e){e=document.body;c=true;}if(!e){return;}' + + 'var m=document.createElement("span");m.style.display="none";' + + 'var z=document.createElement("span");z.style.display="none";' + + 'if(c){e.appendChild(m);m.insertAdjacentElement("afterend",z);}' + + 'else if(e.parentNode){e.insertAdjacentElement("afterend",m);' + + 'm.insertAdjacentElement("afterend",z);}' + + 'else{document.body.appendChild(m);m.insertAdjacentElement("afterend",z);}' + + 'm.insertAdjacentHTML("afterend",h);' + + 'var n=m.nextElementSibling;' + + 'if(ext){z.insertAdjacentHTML("beforebegin",ext);}' + + 'm.remove();z.remove();' + + 'if(n){n.id=' + #39 + + RESTDWEscapeJavaScriptString(AIdentity) + #39 + ';' + + 'n.setAttribute("name",' + #39 + + RESTDWEscapeJavaScriptString(AIdentity) + #39 + ');' + + 'for(var k in o){if(Object.prototype.hasOwnProperty.call(o,k)){' + + 'n.setAttribute("data-laz-"+String(k).replace(/_/g,"-").toLowerCase(),' + + 'String(o[k]));}}' + + 'if(typeof ' + AClassName + '.mount==="function"){' + + AClassName + '.mount(n,o);}' + + '}' + + 'if(window.__restdwSelectElement&&n){window.__restdwSelectElement(n);}' + + 'if(window.__restdwSyncHTML){window.__restdwSyncHTML();}' + + '})();'; + FBrowser.ExecuteScript(UTF8Decode(LScript)); + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.DeleteSelectedElement; +Var + LScript : String; +Begin + {$IFDEF MSWINDOWS} + If Not FReady Or + Not Assigned(FBrowser) Then + Exit; + LScript := + '(function(){' + + 'var e=window.__restdwSelectedElement;' + + 'if(!e||e===document.body||e===document.documentElement){return;}' + + 'var p=e.parentElement;' + + 'e.remove();' + + 'window.__restdwSelectedElement=null;' + + 'if(window.__restdwSyncHTML){window.__restdwSyncHTML();}' + + 'if(window.__restdwSelectElement&&p&&p!==document.body&&p!==document.documentElement){window.__restdwSelectElement(p);}' + + '})();'; + FBrowser.ExecuteScript( + UTF8Decode(LScript) + ); + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.RequestHTML; +Begin + {$IFDEF MSWINDOWS} + If FReady And + Assigned(FBrowser) Then + FBrowser.ExecuteScript( + UTF8Decode( + 'if(window.__restdwSyncHTML){window.__restdwSyncHTML();}' + ) + ); + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.EnableDebugger; +Begin + {$IFDEF MSWINDOWS} + FDebugCallFrameID := ''; + FDebugScriptID := ''; + FDebugSourceLine := 0; + If FDebugExpressions = Nil Then + FDebugExpressions := TStringList.Create + Else + FDebugExpressions.Clear; + If FReady And + Assigned(FBrowser) Then + Begin + FBrowser.OnDevToolsProtocolEventReceived := + BrowserDevToolsEventReceived; + FBrowser.OnCallDevToolsProtocolMethodCompleted := + BrowserDevToolsMethodCompleted; + FBrowser.SubscribeToDevToolsProtocolEvent( + 'Debugger.paused', + 1 + ); + FBrowser.CallDevToolsProtocolMethod( + 'Debugger.enable', + '{}', + 0 + ); + End; + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.DisableDebugger; +Begin + {$IFDEF MSWINDOWS} + FDebugCallFrameID := ''; + FDebugScriptID := ''; + FDebugSourceLine := 0; + If FReady And + Assigned(FBrowser) Then + FBrowser.CallDevToolsProtocolMethod( + 'Debugger.disable', + '{}', + 0 + ); + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.DebugResume; +Begin + {$IFDEF MSWINDOWS} + If FReady And + Assigned(FBrowser) Then + FBrowser.CallDevToolsProtocolMethod( + 'Debugger.resume', + '{}', + 0 + ); + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.DebugPause; +Begin + {$IFDEF MSWINDOWS} + If FReady And + Assigned(FBrowser) Then + FBrowser.CallDevToolsProtocolMethod( + 'Debugger.pause', + '{}', + 0 + ); + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.DebugStepInto; +Begin + {$IFDEF MSWINDOWS} + If FReady And + Assigned(FBrowser) Then + FBrowser.CallDevToolsProtocolMethod( + 'Debugger.stepInto', + '{}', + 0 + ); + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.DebugStepOver; +Begin + {$IFDEF MSWINDOWS} + If FReady And + Assigned(FBrowser) Then + FBrowser.CallDevToolsProtocolMethod( + 'Debugger.stepOver', + '{}', + 0 + ); + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.DebugStepOut; +Begin + {$IFDEF MSWINDOWS} + If FReady And + Assigned(FBrowser) Then + FBrowser.CallDevToolsProtocolMethod( + 'Debugger.stepOut', + '{}', + 0 + ); + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.DebugContinueToLine( + ALine : Integer); +Var + LLocation, + LParams : TJSONObject; +Begin + {$IFDEF MSWINDOWS} + If Not FReady Or + Not Assigned(FBrowser) Or + (Trim(FDebugScriptID) = '') Or + (ALine < 1) Then + Exit; + LLocation := TJSONObject.Create; + LParams := TJSONObject.Create; + Try + LLocation.Add( + 'scriptId', + FDebugScriptID + ); + LLocation.Add( + 'lineNumber', + ALine - 1 + ); + LLocation.Add( + 'columnNumber', + 0 + ); + LParams.Add( + 'location', + LLocation + ); + FBrowser.CallDevToolsProtocolMethod( + 'Debugger.continueToLocation', + UTF8Decode( + LParams.AsJSON + ), + 0 + ); + LLocation := Nil; + Finally + LLocation.Free; + LParams.Free; + End; + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.EvaluateDebugExpression( + ARequestID : Integer; + const AExpression : String); +Var + LParams : TJSONObject; +Begin + {$IFDEF MSWINDOWS} + If Not FReady Or + Not Assigned(FBrowser) Or + (Trim(FDebugCallFrameID) = '') Then + Begin + If Assigned(FOnDebugEvaluate) Then + FOnDebugEvaluate( + Self, + ARequestID, + AExpression, + '', + 'No paused JavaScript call frame is available.', + False + ); + Exit; + End; + If FDebugExpressions = Nil Then + FDebugExpressions := TStringList.Create; + While FDebugExpressions.Count <= ARequestID Do + FDebugExpressions.Add(''); + FDebugExpressions[ARequestID] := AExpression; + LParams := TJSONObject.Create; + Try + LParams.Add( + 'callFrameId', + FDebugCallFrameID + ); + LParams.Add( + 'expression', + AExpression + ); + LParams.Add( + 'returnByValue', + True + ); + LParams.Add( + 'generatePreview', + True + ); + FBrowser.CallDevToolsProtocolMethod( + 'Debugger.evaluateOnCallFrame', + UTF8Decode( + LParams.AsJSON + ), + ARequestID + ); + Finally + LParams.Free; + End; + {$ELSE} + If Assigned(FOnDebugEvaluate) Then + FOnDebugEvaluate( + Self, + ARequestID, + AExpression, + '', + 'Debugger evaluation is available only on WebView2.', + False + ); + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.ModifyDebugExpression( + ARequestID : Integer; + const AExpression, AValueExpression : String); +Begin + EvaluateDebugExpression( + ARequestID, + '(' + + AExpression + + ' = (' + + AValueExpression + + '))' + ); +End; +Procedure TRESTDWHTMLWebView.OpenDevTools; +Begin + {$IFDEF MSWINDOWS} + If FReady And + Assigned(FBrowser) Then + FBrowser.OpenDevToolsWindow; + {$ENDIF} +End; +Procedure TRESTDWHTMLWebView.RebindHost; +{$IFDEF MSWINDOWS} +Begin + If Not Assigned(FWindowParent) Or + Not Assigned(FBrowser) Then + Exit; + FWindowParent.HandleNeeded; + If FWindowParent.Handle = 0 Then + Exit; + Try + FBrowser.IsVisible := False; + FBrowser.ParentWindow := 0; + FBrowser.ParentWindow := FWindowParent.Handle; + FWindowParent.UpdateSize; + FBrowser.NotifyParentWindowPositionChanged; + FBrowser.IsVisible := True; + FWindowParent.UpdateSize; + Refresh; + Except + On E : Exception Do + If Assigned(FOnError) Then + FOnError(Self,E.Message); + End; +End; +{$ELSE} +Begin +End; +{$ENDIF} +Procedure TRESTDWHTMLWebView.DetachHost; +{$IFDEF MSWINDOWS} +Begin + If Not Assigned(FBrowser) Then + Exit; + Try + FBrowser.IsVisible := False; + FBrowser.ParentWindow := 0; + Except + End; +End; +{$ELSE} +Begin +End; +{$ENDIF} +Procedure TRESTDWHTMLWebView.Resize; +Begin + Inherited Resize; + {$IFDEF MSWINDOWS} + If Assigned(FWindowParent) Then + FWindowParent.UpdateSize; + {$ENDIF} +End; +{$IFDEF MSWINDOWS} +Procedure TRESTDWHTMLWebView.InitTimer(Sender : TObject); +Begin + Inc(FInitTicks); + If FInitTicks > 100 Then + Begin + FInitTimer.Enabled := False; + FStarted := False; + If Assigned(FOnError) Then + FOnError( + Self, + 'TRESTDWHTMLWebView initialization timeout. WebView2 Runtime could not be initialized.' + ); + Exit; + End; + If GlobalWebView2Loader.InitializationError Then + Begin + FInitTimer.Enabled := False; + FStarted := False; + If Assigned(FOnError) Then + FOnError( + Self, + UTF8Encode( + GlobalWebView2Loader.ErrorMessage + ) + ); + Exit; + End; + If GlobalWebView2Loader.Initialized Then + Begin + { Cold-start stabilization. + On the first IDE use, WebView2Loader can report Initialized immediately + before its environment is fully settled for controller creation. Subsequent + openings work because that environment is already warm. + Wait only a few timer ticks after Initialized becomes true. Do not depend on + panel size or form geometry, and do not alter the normal warm-start path. } + Inc(FLoaderReadyTicks); + If FLoaderReadyTicks < 3 Then + Exit; + { Keep Candidate 103 retry behavior. If CreateBrowser returns False, leave + the timer enabled and retry on the next tick. } + If FBrowser.Initialized Then + Begin + FInitTimer.Enabled := False; + Exit; + End; + If FBrowser.CreateBrowser( + FWindowParent.Handle + ) Then + FInitTimer.Enabled := False; + End + Else + FLoaderReadyTicks := 0; +End; +Procedure TRESTDWHTMLWebView.WindowDragOver( + Sender, Source : TObject; + X, Y : Integer; + State : TDragState; + Var Accept : Boolean); +Begin + If Assigned(FOnDesignDragOver) Then + FOnDesignDragOver( + Self, + Source, + X, + Y, + State, + Accept + ); +End; +Procedure TRESTDWHTMLWebView.WindowDragDrop( + Sender, Source : TObject; + X, Y : Integer); +Begin + If Assigned(FOnDesignDragDrop) Then + FOnDesignDragDrop( + Self, + Source, + X, + Y + ); +End; +Procedure TRESTDWHTMLWebView.EmitPageError( + const AKind, ASource, AMessage : String; + ALine, AColumn : Integer); +Begin + If Assigned(FOnPageError) Then + FOnPageError( + Self, + AKind, + ASource, + AMessage, + ALine, + AColumn + ); +End; +Function TRESTDWHTMLWebView.InjectPageErrorBridge( + const AHTML : String) : String; +Const + LBridge = + ''; +Var + P : Integer; +Begin + Result := AHTML; + P := Pos( + '', + LowerCase(Result) + ); + If P > 0 Then + Insert( + LBridge, + Result, + P + Length('') + ) + Else + Begin + P := Pos( + ' 0 Then + Insert( + LBridge, + Result, + P + ) + Else + Result := LBridge + Result; + End; +End; +Procedure TRESTDWHTMLWebView.InstallPageErrorBridge; +Const + LBridgeScript = + '(function(){' + + ' if(window.__restdwErrorBridgeInstalled){return;}' + + ' window.__restdwErrorBridgeInstalled=true;' + + ' function clean(v){' + + ' if(v===undefined||v===null){return "";}' + + ' return String(v).replace(/\t/g," ").replace(/[\r\n]+/g," ");' + + ' }' + + ' function send(k,m,s,l,c){' + + ' try{' + + ' window.chrome.webview.postMessage(' + + ' "RESTDWERR\t"+clean(k)+"\t"+clean(l||0)+"\t"+clean(c||0)+"\t"+clean(s)+"\t"+clean(m)' + + ' );' + + ' }catch(e){}' + + ' }' + + ' window.addEventListener("error",function(e){' + + ' if(e.target&&e.target!==window){' + + ' var u=e.target.src||e.target.href||e.target.currentSrc||e.target.tagName||"resource";' + + ' send("Resource","Failed to load resource: "+u,u,0,0);' + + ' }else{' + + ' send("Error",e.message||"JavaScript error",e.filename||location.href,e.lineno||0,e.colno||0);' + + ' }' + + ' },true);' + + ' window.addEventListener("unhandledrejection",function(e){' + + ' var r=e.reason;' + + ' if(r&&r.__restdwReported){return;}' + + ' var m=(r&&r.message)?r.message:r;' + + ' send("Promise",m||"Unhandled promise rejection",location.href,0,0);' + + ' });' + + ' var ce=console.error;' + + ' console.error=function(){' + + ' send("Console Error",Array.prototype.join.call(arguments," "),location.href,0,0);' + + ' return ce.apply(console,arguments);' + + ' };' + + ' var cw=console.warn;' + + ' console.warn=function(){' + + ' send("Console Warning",Array.prototype.join.call(arguments," "),location.href,0,0);' + + ' return cw.apply(console,arguments);' + + ' };' + + '})();'; +Begin + If FReady And + Assigned(FBrowser) Then + FBrowser.AddScriptToExecuteOnDocumentCreated( + UTF8Decode(LBridgeScript) + ); +End; +Procedure TRESTDWHTMLWebView.BrowserWebMessageReceived( + Sender : TObject; + const AWebView : ICoreWebView2; + const AArgs : ICoreWebView2WebMessageReceivedEventArgs); +Const + CHTMLPrefix = 'RESTDWHTML'; + CObjectPrefix = 'RESTDWOBJ'; + CSELPRefix = 'RESTDWSEL'; + CBreakPrefix = 'RESTDWBREAK'; + CErrorPrefix = 'RESTDWERR'; +Var + LArgs : TCoreWebView2WebMessageReceivedEventArgs; + LMessage, + LKind, + LLineText, + LColumnText, + LSource, + LText : String; + P1, + P2, + P3, + P4, + P5 : Integer; + Function HasProtocol( + const AProtocol : String) : Boolean; + Begin + Result := + Copy( + LMessage, + 1, + Length(AProtocol) + 1 + ) = + AProtocol + #9; + End; + Function PayloadStart( + const AProtocol : String) : Integer; + Begin + Result := + Length(AProtocol) + 2; + End; + Function NextPart( + const AValue : String; + AStart : Integer; + Out ANext : Integer) : String; + Var + P : Integer; + Begin + P := PosEx( + #9, + AValue, + AStart + ); + If P = 0 Then + Begin + Result := + Copy( + AValue, + AStart, + MaxInt + ); + ANext := + Length(AValue) + 1; + End + Else + Begin + Result := + Copy( + AValue, + AStart, + P - AStart + ); + ANext := + P + 1; + End; + End; +Begin + LArgs := + TCoreWebView2WebMessageReceivedEventArgs.Create( + AArgs + ); + Try + { WebView2 already returns Unicode. Keep the message Unicode end-to-end. } + LMessage := + LArgs.WebMessageAsString; + Finally + LArgs.Free; + End; + { Full HTML synchronized by the design bridge. } + If HasProtocol(CHTMLPrefix) Then + Begin + If Assigned(FOnHTMLChanged) Then + FOnHTMLChanged( + Self, + Copy( + LMessage, + PayloadStart(CHTMLPrefix), + MaxInt + ) + ); + Exit; + End; + If HasProtocol(CObjectPrefix) Then + Begin + If Assigned(FOnObjectTree) Then + FOnObjectTree( + Self, + Copy( + LMessage, + PayloadStart(CObjectPrefix), + MaxInt + ) + ); + Exit; + End; + { Visual element selection: + RESTDWSEL editor-id tag text id class outerHTML + The old DataSnap parser used fixed offsets for "DSSEL". After the RESTDW + protocol rename those offsets no longer matched the prefix, so the Delphi + Object Inspector never received the selected element. } + If HasProtocol(CSELPRefix) Then + Begin + P1 := + PayloadStart(CSELPRefix); + LKind := + NextPart( + LMessage, + P1, + P2 + ); + LLineText := + NextPart( + LMessage, + P2, + P3 + ); + LColumnText := + NextPart( + LMessage, + P3, + P4 + ); + LSource := + NextPart( + LMessage, + P4, + P5 + ); + LText := + NextPart( + LMessage, + P5, + P1 + ); + If Assigned(FOnElementSelected) Then + FOnElementSelected( + Self, + LKind, + LLineText, + LColumnText, + LSource, + LText, + Copy( + LMessage, + P1, + MaxInt + ) + ); + Exit; + End; + { Debug breakpoint notification. } + If HasProtocol(CBreakPrefix) Then + Begin + FDebugSourceLine := + StrToIntDef( + Copy( + LMessage, + PayloadStart(CBreakPrefix), + MaxInt + ), + 0 + ); + Exit; + End; + { Page/console/runtime error notification. } + If Not HasProtocol(CErrorPrefix) Then + Exit; + P1 := + PayloadStart(CErrorPrefix); + LKind := + NextPart( + LMessage, + P1, + P2 + ); + LLineText := + NextPart( + LMessage, + P2, + P3 + ); + LColumnText := + NextPart( + LMessage, + P3, + P4 + ); + LSource := + NextPart( + LMessage, + P4, + P5 + ); + LText := + Copy( + LMessage, + P5, + MaxInt + ); + EmitPageError( + LKind, + LSource, + LText, + StrToIntDef( + LLineText, + 0 + ), + StrToIntDef( + LColumnText, + 0 + ) + ); +End; +Procedure TRESTDWHTMLWebView.BrowserDevToolsEventReceived( + Sender : TObject; + const AWebView : ICoreWebView2; + const AArgs : ICoreWebView2DevToolsProtocolEventReceivedEventArgs; + const AEventName : wvstring; + AEventID : Integer); +Var + LArgs : TCoreWebView2DevToolsProtocolEventReceivedEventArgs; + LData : TJSONData; + LObject, + LFrame, + LLocation : TJSONObject; + LFrames : TJSONArray; +Begin + If UTF8Encode(AEventName) <> 'Debugger.paused' Then + Exit; + LArgs := + TCoreWebView2DevToolsProtocolEventReceivedEventArgs.Create( + AArgs + ); + LData := Nil; + Try + LData := + GetJSON( + UTF8Encode( + LArgs.ParameterObjectAsJson + ) + ); + If (LData = Nil) Or + (LData.JSONType <> jtObject) Then + Exit; + LObject := + TJSONObject( + LData + ); + LFrames := + LObject.Arrays[ + 'callFrames' + ]; + If (LFrames = Nil) Or + (LFrames.Count = 0) Then + Exit; + LFrame := + LFrames.Objects[ + 0 + ]; + If LFrame = Nil Then + Exit; + FDebugCallFrameID := + LFrame.Get( + 'callFrameId', + '' + ); + LLocation := + LFrame.Objects[ + 'location' + ]; + If LLocation <> Nil Then + FDebugScriptID := + LLocation.Get( + 'scriptId', + '' + ); + If (FDebugSourceLine <= 0) And + (LLocation <> Nil) Then + FDebugSourceLine := + LLocation.Get( + 'lineNumber', + 0 + ) + 1; + If Assigned(FOnDebugBreakpoint) Then + FOnDebugBreakpoint( + Self, + FDebugSourceLine + ); + Finally + LData.Free; + LArgs.Free; + End; +End; +Procedure TRESTDWHTMLWebView.BrowserDevToolsMethodCompleted( + Sender : TObject; + AErrorCode : HRESULT; + const AResult : wvstring; + AExecutionID : Integer); +Var + LData, + LValueData : TJSONData; + LObject, + LResultObject, + LException : TJSONObject; + LExpression, + LValue, + LError : String; + LSuccess : Boolean; +Begin + If AExecutionID <= 0 Then + Exit; + LExpression := ''; + If (FDebugExpressions <> Nil) And + (AExecutionID < FDebugExpressions.Count) Then + LExpression := + FDebugExpressions[ + AExecutionID + ]; + LValue := ''; + LError := ''; + LSuccess := False; + LData := Nil; + If AErrorCode <> 0 Then + LError := + 'WebView debugger error ' + + IntToStr(AErrorCode) + Else + Begin + Try + LData := + GetJSON( + UTF8Encode( + AResult + ) + ); + If (LData <> Nil) And + (LData.JSONType = jtObject) Then + Begin + LObject := + TJSONObject( + LData + ); + LException := + LObject.Objects[ + 'exceptionDetails' + ]; + If LException <> Nil Then + LError := + LException.Get( + 'text', + 'JavaScript evaluation error' + ) + Else + Begin + LResultObject := + LObject.Objects[ + 'result' + ]; + If LResultObject <> Nil Then + Begin + LValueData := + LResultObject.Find( + 'value' + ); + If LValueData <> Nil Then + Begin + If LValueData.JSONType = jtString Then + LValue := + LValueData.AsString + Else + LValue := + LValueData.AsJSON; + End + Else + LValue := + LResultObject.Get( + 'description', + LResultObject.Get( + 'type', + '' + ) + ); + LSuccess := True; + End; + End; + End; + Except + On E : Exception Do + LError := E.Message; + End; + End; + LData.Free; + If Assigned(FOnDebugEvaluate) Then + FOnDebugEvaluate( + Self, + AExecutionID, + LExpression, + LValue, + LError, + LSuccess + ); +End; +Procedure TRESTDWHTMLWebView.BrowserNavigationCompleted( + Sender : TObject; + const AWebView : ICoreWebView2; + const AArgs : ICoreWebView2NavigationCompletedEventArgs); +Var + LArgs : TCoreWebView2NavigationCompletedEventArgs; +Begin + LArgs := TCoreWebView2NavigationCompletedEventArgs.Create( + AArgs + ); + Try + If Not LArgs.IsSuccess Then + Begin + { ConnectionAborted can be generated when WebView2 replaces an in-flight + navigation. It is not a page source error and must not pollute Error List. } + If Ord(LArgs.WebErrorStatus) <> 9 Then + EmitPageError( + 'Navigation', + 'TRESTDWHTMLWebView', + 'Page navigation failed. WebErrorStatus=' + + IntToStr(Ord(LArgs.WebErrorStatus)) + + ', HTTP=' + + IntToStr(LArgs.HttpStatusCode), + 0, + 0 + ); + End + Else If Assigned(FBrowser) Then + FBrowser.ExecuteScript( + UTF8Decode( + '(function(){' + + 'function send(){if(window.__restdwSendObjectTree){window.__restdwSendObjectTree();}}' + + 'send();setTimeout(send,80);setTimeout(send,250);setTimeout(send,600);' + + '})();' + ) + ); + Finally + LArgs.Free; + End; +End; +Procedure TRESTDWHTMLWebView.BrowserAfterCreated(Sender : TObject); +Begin + FReady := True; + FBrowser.WebMessageEnabled := True; + FVirtualHostsReady := False; + { First controller creation already received FWindowParent.Handle in + CreateBrowser. Do not detach/rebind it here: the form has only just become + visible and changing ParentWindow at this stage can leave WebView2 gray. } + FWindowParent.UpdateSize; + InstallPageErrorBridge; + PrepareVirtualHosts; + { The designer performs the single initial navigation in WebViewReady. } + If Assigned(FOnReady) Then + FOnReady(Self); +End; +Procedure TRESTDWHTMLWebView.BrowserInitializationError( + Sender : TObject; + AErrorCode : HRESULT; + const AErrorMessage : wvstring); +Begin + FReady := False; + If Assigned(FOnError) Then + FOnError( + Self, + UTF8Encode(AErrorMessage) + ); +End; +{$ENDIF} +End. diff --git a/CORE/Source/Plugins/SelfSigned/uRESTDWSelfSigned.pas b/CORE/Source/Plugins/SelfSigned/uRESTDWSelfSigned.pas index c8c9067bc..847d7e348 100644 --- a/CORE/Source/Plugins/SelfSigned/uRESTDWSelfSigned.pas +++ b/CORE/Source/Plugins/SelfSigned/uRESTDWSelfSigned.pas @@ -1,21 +1,21 @@ unit uRESTDWSelfSigned; -{$I ..\..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Plugins/SelfSigned/uRESTDWSelfSignedMacros.pas b/CORE/Source/Plugins/SelfSigned/uRESTDWSelfSignedMacros.pas index f3a601e7b..a5d6a38e9 100644 --- a/CORE/Source/Plugins/SelfSigned/uRESTDWSelfSignedMacros.pas +++ b/CORE/Source/Plugins/SelfSigned/uRESTDWSelfSignedMacros.pas @@ -1,21 +1,21 @@ unit uRESTDWSelfSignedMacros; -{$I ..\..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Plugins/SelfSigned/uRESTDWSelfSignedReg.pas b/CORE/Source/Plugins/SelfSigned/uRESTDWSelfSignedReg.pas index b604ef0df..5d2a27fba 100644 --- a/CORE/Source/Plugins/SelfSigned/uRESTDWSelfSignedReg.pas +++ b/CORE/Source/Plugins/SelfSigned/uRESTDWSelfSignedReg.pas @@ -1,21 +1,21 @@ unit uRESTDWSelfSignedReg; -{$I ..\..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. diff --git a/CORE/Source/Plugins/uRESTDWFMXHTMLEditor.pas b/CORE/Source/Plugins/uRESTDWFMXHTMLEditor.pas new file mode 100644 index 000000000..374ea6f3d --- /dev/null +++ b/CORE/Source/Plugins/uRESTDWFMXHTMLEditor.pas @@ -0,0 +1,44 @@ +unit uRESTDWFMXHTMLEditor; + +{$I uRESTDW.inc} + +interface + +uses + Classes, SysUtils; + +type + TRESTDWFMXHTMLEditor = class(TComponent) + private + FHTML : TStrings; + FEditorTitle : String; + procedure SetHTML(Value : TStrings); + public + constructor Create(AOwner : TComponent); override; + destructor Destroy; override; + published + property HTML : TStrings read FHTML write SetHTML; + property EditorTitle : String read FEditorTitle write FEditorTitle; + end; + +implementation + +constructor TRESTDWFMXHTMLEditor.Create(AOwner : TComponent); +begin + inherited Create(AOwner); + FHTML := TStringList.Create; + FEditorTitle := ''; +end; + +destructor TRESTDWFMXHTMLEditor.Destroy; +begin + FHTML.Free; + inherited Destroy; +end; + +procedure TRESTDWFMXHTMLEditor.SetHTML(Value : TStrings); +begin + FHTML.Assign(Value); +end; + +end. diff --git a/CORE/Source/Plugins/uRESTDWHTMLEditor.pas b/CORE/Source/Plugins/uRESTDWHTMLEditor.pas new file mode 100644 index 000000000..e80c78194 --- /dev/null +++ b/CORE/Source/Plugins/uRESTDWHTMLEditor.pas @@ -0,0 +1,36 @@ +unit uRESTDWHTMLEditor; +{$I uRESTDW.inc} +interface +uses + Classes, + SysUtils; +type + TRESTDWHTMLEditor = class(TComponent) + private + FHTML : TStrings; + FEditorTitle : String; + procedure SetHTML(Value : TStrings); + public + constructor Create(AOwner : TComponent); override; + destructor Destroy; override; + published + property HTML : TStrings read FHTML write SetHTML; + property EditorTitle : String read FEditorTitle write FEditorTitle; + end; +implementation +constructor TRESTDWHTMLEditor.Create(AOwner : TComponent); +begin + inherited Create(AOwner); + FHTML := TStringList.Create; + FEditorTitle := ''; +end; +destructor TRESTDWHTMLEditor.Destroy; +begin + FHTML.Free; + inherited Destroy; +end; +procedure TRESTDWHTMLEditor.SetHTML(Value : TStrings); +begin + FHTML.Assign(Value); +end; +end. From be9eead7397d785d55a6b291379c320e7eb48b1c Mon Sep 17 00:00:00 2001 From: Roniery Santos Cardoso Date: Tue, 8 Sep 2026 22:00:50 -0300 Subject: [PATCH 08/22] fix(sqleditor): correcoes no SQL Editor refs r4065, r4090 --- .../SQLEditor/RestDatawareCOREEditor.dpk | 2 +- .../Plugins/SQLEditor/uRESTDWSqlEditor.ddp | Bin 51 -> 0 bytes .../Plugins/SQLEditor/uRESTDWSqlEditor.pas | 1300 +++++++++-------- .../Plugins/SQLEditor/uRESTDWUpdSqlEditor.pas | 10 +- 4 files changed, 683 insertions(+), 629 deletions(-) delete mode 100644 CORE/Source/Plugins/SQLEditor/uRESTDWSqlEditor.ddp diff --git a/CORE/Source/Plugins/SQLEditor/RestDatawareCOREEditor.dpk b/CORE/Source/Plugins/SQLEditor/RestDatawareCOREEditor.dpk index 8b223b28f..96d5f3069 100644 --- a/CORE/Source/Plugins/SQLEditor/RestDatawareCOREEditor.dpk +++ b/CORE/Source/Plugins/SQLEditor/RestDatawareCOREEditor.dpk @@ -44,6 +44,6 @@ requires vcldb; contains - uDWSqlEditor in 'uDWSqlEditor.pas' {FrmDWSqlEditor}; + uRESTDWSqlEditor in 'uRESTDWSqlEditor.pas' {FrmDWSqlEditor}; end. diff --git a/CORE/Source/Plugins/SQLEditor/uRESTDWSqlEditor.ddp b/CORE/Source/Plugins/SQLEditor/uRESTDWSqlEditor.ddp deleted file mode 100644 index 4370276c196a7fa73d6f8917622cba1c4e033dee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51 zcmZRVaB=ks@bJ`g@pN<#a`e>;@DB=c^Y`)e=VxGe;K0Pl$;KI)SCUzhlbT}4#=r!G E07ZHWvj6}9 diff --git a/CORE/Source/Plugins/SQLEditor/uRESTDWSqlEditor.pas b/CORE/Source/Plugins/SQLEditor/uRESTDWSqlEditor.pas index 8c63ea6d4..704a74acc 100644 --- a/CORE/Source/Plugins/SQLEditor/uRESTDWSqlEditor.pas +++ b/CORE/Source/Plugins/SQLEditor/uRESTDWSqlEditor.pas @@ -1,623 +1,677 @@ -unit uRESTDWSqlEditor; - -{$I ..\..\..\Source\Includes\uRESTDW.inc} - -{ - REST Dataware . - Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON - de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores - Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. - - Membros do Grupo : - - XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. - Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. - Mobius One - Devel, Tester and Admin. - Gustavo - Criptografia and Devel. - Eloy - Devel. - Roniery - Devel. -} - -interface - -uses - SysUtils, Dialogs, Forms, ExtCtrls, StdCtrls, ComCtrls, DBGrids, - uRESTDWBasicDB, DB{$IFNDEF FPC}, Grids{$ENDIF}, Controls, - Classes, SyncObjs, - {$IFDEF FPC} - FormEditingIntf, PropEdits, lazideintf - {$ELSE} - DesignEditors, DesignIntf - {$ENDIF}; - -Const - cSelect = 'Select %s From %s'; - cInsert = 'Insert into %s (%s) Values (%s)'; - cDelete = 'Delete From %s Where '; - cUpdate = 'Update %s Set %s Where '; - - Type - TOnTrhFimBusca = procedure(Sender : TObject; evento : string; lstString : TStringList) of object; - PointerString = ^String; - - { TThrBancoDados } - - TThrBancoDados = class(TThread) - private - FRESTDWDatabase : TRESTDWDatabasebaseBase; - FEvent : TSimpleEvent; - FMustDie : boolean; - FTipoEvento : string; - FBuscar : string; - FMemString : TStringList; - FOnFimEvento : TOnTrhFimBusca; - protected - procedure Execute; override; - {$IFDEF FPC} - procedure TerminatedSet; {$IFNDEF NOGUI}override;{$ENDIF} - {$ENDIF} - procedure callFimBusca; - public - constructor Create; - destructor Destroy; override; - - procedure threadDie; - - procedure buscarTabelas; - procedure buscarFieldsNames(tabela : string); - published - property RESTDWDatabase : TRESTDWDatabasebaseBase read FRESTDWDatabase write FRESTDWDatabase; - property OnFimEvento : TOnTrhFimBusca read FOnFimEvento write FOnFimEvento; - end; - - { TFrmDWSqlEditor } - - TFrmDWSqlEditor = class(TForm) - BtnCancelar: TButton; - BtnExecute: TButton; - BtnOk: TButton; - DBGridRecord: TDBGrid; - PageControlResult: TPageControl; - PnlAction: TPanel; - PnlButton: TPanel; - PnlSQL: TPanel; - pSQLEditor: TPanel; - lbTables: TListBox; - labSql: TLabel; - Label1: TLabel; - lbFields: TListBox; - Label2: TLabel; - pSQLTypes: TPanel; - rbInsert: TRadioButton; - rbSelect: TRadioButton; - rbDelete: TRadioButton; - rbUpdate: TRadioButton; - TabSheetTable: TTabSheet; - pEditor: TPanel; - PageControl: TPageControl; - TabSheetSQL: TTabSheet; - Memo: TMemo; - Panel1: TPanel; - Label3: TLabel; - lbExecutedTime: TLabel; - tmClose: TTimer; - procedure BtnExecuteClick(Sender: TObject); - {$IFNDEF FPC} - procedure FormClose(Sender: TObject; var Action: TCloseAction); - {$ELSE} - procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); - {$ENDIF} - procedure FormShow(Sender: TObject); - procedure FormCreate(Sender: TObject); - procedure lbTablesClick(Sender: TObject); - procedure lbTablesKeyUp(Sender: TObject; var Key: Word; - Shift: TShiftState); - procedure MemoDragOver(Sender, Source: TObject; X, Y: Integer; - State: TDragState; var Accept: Boolean); - procedure MemoDragDrop(Sender, Source: TObject; X, Y: Integer); - procedure BtnCancelarClick(Sender: TObject); - procedure FormActivate(Sender: TObject); - procedure tmCloseTimer(Sender: TObject); - procedure BtnOkClick(Sender: TObject); - Private - { Private declarations } - DataSource : TDataSource; - RESTDWDatabase : TRESTDWDatabasebaseBase; - RESTDWClientSQL, - RESTDWClientSQLB : TRESTDWClientSQL; - vLastSelect, - vOldSQL : String; - pNewSQL : PointerString; - FThrBancoDados : TThrBancoDados; - FResModal : Cardinal; - Procedure SetFields; - Function BuildSQL : String; - Procedure SetDatabase(Value : TRESTDWDatabasebaseBase); - Procedure SetarControles(enab : boolean); - Procedure CarregarTabelas; - Procedure thrOnFimEvento(Sender : TObject; evento : string; lstString : TStringList); - Procedure thrOnTerminate(Sender : TObject); - Public - { Public declarations } - Procedure SetClientSQL(Value : TRESTDWClientSQL); - Property Database : TRESTDWDatabasebaseBase Read RESTDWDatabase Write SetDatabase; - Property NewSQL : PointerString Read pNewSQL Write pNewSQL; - End; - - Type - TRESTDWSQLEditor = Class(TStringProperty) - Public - Function GetAttributes : TPropertyAttributes; Override; - Procedure Edit; Override; - Function GetValue : String; Override; - procedure SetValue(const Value: string); Override; - End; - -Var - FrmDWSqlEditor : TFrmDWSqlEditor; - -Implementation - -{$IFDEF FPC} - {$R *.lfm} -{$ELSE} - {$R *.dfm} -{$ENDIF} - -Function TRESTDWSQLEditor.GetValue : String; -Begin - Result := Trim(TRESTDWClientSQL(GetComponent(0)).SQL.Text); - If Trim(Result) = '' Then - Result := 'Click here to set SQL...' -End; - -procedure TRESTDWSQLEditor.SetValue(const Value: string); -Var - objObj : TRESTDWClientSQL; -Begin - objObj := TRESTDWClientSQL(GetComponent(0)); - objObj.SQL.Text := Trim(Value); - Modified; // update na propridade do object inspector -end; - -Procedure TRESTDWSQLEditor.Edit; -Var - objObj : TRESTDWClientSQL; - vPointerString : String; -Begin - FrmDWSqlEditor := TFrmDWSqlEditor.Create(Application); - Try - objObj := TRESTDWClientSQL(GetComponent(0)); - FrmDWSqlEditor.SetClientSQL(objObj); - FrmDWSqlEditor.pNewSQL := @vPointerString; - vPointerString := ''; - FrmDWSqlEditor.ShowModal; - if vPointerString <> '' then - SetValue(vPointerString); -// objObj := Nil; - FreeAndNil(FrmDWSqlEditor); - Except - - End; -End; - -Function TRESTDWSQLEditor.GetAttributes: TPropertyAttributes; -Begin -//paAutoUpdate - Result := [paDialog]; -End; - -procedure TFrmDWSqlEditor.BtnCancelarClick(Sender: TObject); -begin - BtnCancelar.Tag := 1; - FResModal := mrCancel; - Close; -end; - -Procedure TFrmDWSqlEditor.BtnExecuteClick(Sender: TObject); -var - dti, dtf : TDateTime; -Begin - Screen.Cursor := crHourGlass; - Try - RESTDWClientSQLB.Close; -// RESTDWClientSQLB.BinaryRequest := RESTDWClientSQL.BinaryRequest; - RESTDWClientSQLB.SQL.Clear; - RESTDWClientSQLB.SQL.Add(Memo.Lines.Text); - - dti := Now; - RESTDWClientSQLB.Open; - dtf := Now; - Finally - lbExecutedTime.Caption := FormatDateTime('HH:nn:ss:zzz',dtf-dti); - Screen.Cursor := crDefault; - End; -End; - -procedure TFrmDWSqlEditor.BtnOkClick(Sender: TObject); -begin - pNewSQL^ := Trim(Memo.Lines.Text); - FResModal := mrOk; - Close; -end; - -procedure TFrmDWSqlEditor.FormActivate(Sender: TObject); -begin - CarregarTabelas; -end; - -{$IFNDEF FPC} -procedure TFrmDWSqlEditor.FormClose(Sender: TObject; var Action: TCloseAction); -{$ELSE} -procedure TFrmDWSqlEditor.FormClose(Sender: TObject; var CloseAction: TCloseAction); -{$ENDIF} -begin - If (FResModal = mrCancel) and (vOldSQL <> Memo.Text) and (BtnCancelar.Tag = 1) Then - Begin - {$IFDEF FPC} - If MessageDlg('SQL Editor', 'Realmente deseja sair ?', mtConfirmation, [mbYes, mbNo], 0) <> mrYes then - Begin - BtnCancelar.Tag := 0; - CloseAction:=caNone; - Exit; - End; - {$ELSE} - If MessageDlg('Realmente deseja sair ?', mtConfirmation, [mbYes, mbNo], 0) <> mrYes then - Begin - BtnCancelar.Tag := 0; - Action:=caNone; - Exit; - End; - {$ENDIF} - End; - BtnCancelar.Tag := 2; - if FThrBancoDados <> nil then - Begin - FThrBancoDados.threadDie; - tmClose.Enabled := True; - {$IFDEF FPC} - CloseAction := caNone; - {$ELSE} - Action := caNone; - {$ENDIF} - Exit; - End; - ModalResult := FResModal; // devido o clock (passa duas vezes) - RESTDWClientSQLB.Active := False; - FreeAndNil(RESTDWClientSQLB); - If Assigned(RESTDWDatabase) Then - RESTDWDatabase.Active := False; - FreeAndNil(DataSource); -// FrmDWSqlEditor := Nil; -// Release; -end; - -procedure TFrmDWSqlEditor.FormCreate(Sender: TObject); -begin - RESTDWClientSQLB := TRESTDWClientSQL.Create(Self); - DataSource := TDataSource.Create(Self); - vLastSelect := ''; - FResModal := mrNone; - - RESTDWDatabase := nil; - - FThrBancoDados := TThrBancoDados.Create; - FThrBancoDados.OnFimEvento := {$IFDEF FPC}@{$ENDIF}thrOnFimEvento; - FThrBancoDados.OnTerminate := {$IFDEF FPC}@{$ENDIF}thrOnTerminate; - - SetarControles(False); -end; - -procedure TFrmDWSqlEditor.FormShow(Sender: TObject); -begin - DataSource.DataSet := RESTDWClientSQLB; - DBGridRecord.DataSource := DataSource; - - If Assigned(RESTDWClientSQL) Then Begin - RESTDWDatabase := RESTDWClientSQL.DataBase; - RESTDWClientSQLB.DataBase := RESTDWDatabase; - end; - - FThrBancoDados.RESTDWDatabase := RESTDWDatabase; -end; - -Procedure TFrmDWSqlEditor.SetFields; -Begin - If (lbTables.Count > 0) And (lbTables.ItemIndex > -1) And - (vLastSelect <> lbTables.Items[lbTables.itemIndex]) Then - Begin - vLastSelect := lbTables.Items[lbTables.itemIndex]; - FThrBancoDados.buscarFieldsNames(vLastSelect); - End - Else If (lbTables.Count > 0) And (lbTables.ItemIndex = -1) Then - lbFields.Items.Clear; -End; - -procedure TFrmDWSqlEditor.thrOnFimEvento(Sender: TObject; evento: string; - lstString: TStringList); -begin - if evento = 'T' then begin - lbTables.Items.Text := lstString.Text; - If lbTables.Count > 0 Then Begin - SetarControles(True); - lbTables.ItemIndex := 0; - SetFields; - End; - end - else if evento = 'F' then begin - lbFields.Items.Text := lstString.Text; - end; -end; - -procedure TFrmDWSqlEditor.thrOnTerminate(Sender: TObject); -begin - FThrBancoDados := nil; -end; - -procedure TFrmDWSqlEditor.tmCloseTimer(Sender: TObject); -begin - tmClose.Enabled := False; - if FThrBancoDados <> nil then - tmClose.Enabled := True - else - Close; -end; - -procedure TFrmDWSqlEditor.SetarControles(enab: boolean); -begin - PnlButton.Enabled := enab; - PageControlResult.Enabled := enab; - pSQLEditor.Enabled := enab; -end; - -Procedure TFrmDWSqlEditor.SetClientSQL(Value: TRESTDWClientSQL); -Begin - RESTDWClientSQL := Value; - vOldSQL := ''; - Memo.Lines.Text := vOldSQL; - - if Assigned(RESTDWClientSQL) then begin - vOldSQL := RESTDWClientSQL.SQL.Text; - Memo.Lines.Text := vOldSQL; - end; -End; - -Procedure TFrmDWSqlEditor.SetDatabase(Value : TRESTDWDatabasebaseBase); -Begin - RESTDWClientSQLB.DataBase := Value; -End; - -procedure TFrmDWSqlEditor.lbTablesClick(Sender: TObject); -begin - SetFields; -end; - -procedure TFrmDWSqlEditor.lbTablesKeyUp(Sender: TObject; var Key: Word; - Shift: TShiftState); -begin - SetFields; -end; - -procedure TFrmDWSqlEditor.MemoDragOver(Sender, Source: TObject; X, - Y: Integer; State: TDragState; var Accept: Boolean); -begin - Accept := Source is Tlistbox; -end; - -Function TFrmDWSqlEditor.BuildSQL : String; -Var - I : Integer; - vFieldsA, - vFieldsB : String; -Begin - Result := ''; - vFieldsA := Result; - vFieldsB := Result; - If lbTables.itemIndex < 0 Then - Exit; - If rbSelect.Checked Then - Result := Format(cSelect, ['%s', lbTables.Items[lbTables.itemIndex]]); - If rbInsert.Checked Then - Result := Format(cInsert, [lbTables.Items[lbTables.itemIndex], '%s', '%s']); - If rbDelete.Checked Then - Result := Format(cDelete, [lbTables.Items[lbTables.itemIndex]]); - If rbUpdate.Checked Then - Result := Format(cUpdate, [lbTables.Items[lbTables.itemIndex], '%s']); - If lbFields.SelCount > 0 Then - Begin - If rbSelect.Checked Then - Begin - For I := 0 To lbFields.Count -1 Do - Begin - If lbFields.Selected[I] Then - If vFieldsA = '' Then - vFieldsA := lbFields.Items[I] - Else - vFieldsA := vFieldsA + ', ' + lbFields.Items[I]; - End; - Result := Format(Result, [vFieldsA]); - End - Else If rbInsert.Checked Then - Begin - For I := 0 To lbFields.Count -1 Do - Begin - If lbFields.Selected[I] Then - If vFieldsA = '' Then - vFieldsA := lbFields.Items[I] - Else - vFieldsA := vFieldsA + ', ' + lbFields.Items[I]; - If lbFields.Selected[I] Then - If vFieldsB = '' Then - vFieldsB := ':' + lbFields.Items[I] - Else - vFieldsB := vFieldsB + ', :' + lbFields.Items[I]; - End; - Result := Format(Result, [vFieldsA, vFieldsB]); - End - Else If rbUpdate.Checked Then - Begin - For I := 0 To lbFields.Count -1 Do - Begin - If lbFields.Selected[I] Then - If vFieldsA = '' Then - vFieldsA := lbFields.Items[I] + ' = :' + lbFields.Items[I] - Else - vFieldsA := vFieldsA + ', ' + lbFields.Items[I] + ' = :' + lbFields.Items[I]; - End; - Result := Format(Result, [vFieldsA]); - End; - End - Else - Begin - If rbSelect.Checked Then - Begin - Result := Format(Result, ['*']) - End - Else If rbInsert.Checked Then - Begin - For I := 0 To lbFields.Count -1 Do - Begin - If vFieldsA = '' Then - vFieldsA := lbFields.Items[I] - Else - vFieldsA := vFieldsA + ', ' + lbFields.Items[I]; - If vFieldsB = '' Then - vFieldsB := ':' + lbFields.Items[I] - Else - vFieldsB := vFieldsB + ', :' + lbFields.Items[I]; - End; - Result := Format(Result, [vFieldsA, vFieldsB]); - End - Else If rbUpdate.Checked Then - Begin - For I := 0 To lbFields.Count -1 Do - Begin - If vFieldsA = '' Then - vFieldsA := lbFields.Items[I] + ' = :' + lbFields.Items[I] - Else - vFieldsA := vFieldsA + ', ' + lbFields.Items[I] + ' = :' + lbFields.Items[I]; - End; - Result := Format(Result, [vFieldsA]); - End; - End; -End; - -procedure TFrmDWSqlEditor.CarregarTabelas; -begin - FThrBancoDados.buscarTabelas; -end; - -procedure TFrmDWSqlEditor.MemoDragDrop(Sender, Source: TObject; X, - Y: Integer); -begin - If Source = lbTables Then - If Trim(TMemo(Sender).Lines.Text) = '' Then - TMemo(Sender).Lines.Text := BuildSQL - Else - TMemo(Sender).Lines.Text := TMemo(Sender).Lines.Text + sLineBreak + BuildSQL; -end; - -{ TThrBancoDados } - -procedure TThrBancoDados.buscarFieldsNames(tabela: string); -begin - FTipoEvento := 'F'; - FBuscar := tabela; - FEvent.SetEvent; -end; - -procedure TThrBancoDados.buscarTabelas; -begin - FTipoEvento := 'T'; - FBuscar := ''; - FEvent.SetEvent; -end; - -procedure TThrBancoDados.callFimBusca; -var - vTipo : string; -begin - vTipo := FTipoEvento; - FTipoEvento := ''; // limpando para nao cair no while do Execute - if Assigned(FOnFimEvento) then - FOnFimEvento(Self,vTipo,FMemString); -end; - -constructor TThrBancoDados.Create; -begin - FRESTDWDatabase := nil; - FMustDie := False; - FEvent := TSimpleEvent.Create; - FMemString := TStringList.Create; - FreeOnTerminate := True; - {$IFDEF FPC} - inherited Create(False); - {$ELSE} - inherited Create(False); - {$ENDIF} -end; - -destructor TThrBancoDados.Destroy; -begin - FMemString.Free; - FEvent.Free; - - inherited; -end; - -procedure TThrBancoDados.Execute; -begin - while not Terminated do begin - {$IF (NOT DEFINED(FPC)) AND (CompilerVersion < 21)} - FEvent.WaitFor($FFFFFFFF);// INFINITE - {$ELSE} - FEvent.WaitFor(INFINITE); - {$IFEND} - - if FMustDie then begin - Terminate; - Break; - end; - - FMemString.Clear; - try - if FRESTDWDatabase <> nil then begin - if FTipoEvento = 'T' then - FRESTDWDatabase.GetTableNames(FMemString) - else if FTipoEvento = 'F' then - FRESTDWDatabase.GetFieldNames(FBuscar,FMemString); - end; - except - - end; - - if FMemString.Count > 0 then - Synchronize({$IFDEF FPC}@{$ENDIF}callFimBusca); - - if FMustDie then begin - Terminate; - Break; - end; - end; -end; - -{$IFDEF FPC} - procedure TThrBancoDados.TerminatedSet; - begin - {$IFNDEF NOGUI} inherited TerminatedSet;{$ENDIF} - DoTerminate; - end; -{$ENDIF} - -procedure TThrBancoDados.threadDie; -begin - FTipoEvento := ''; - FMustDie := True; - FEvent.SetEvent; -end; - -end. +unit uRESTDWSqlEditor; + +{$I uRESTDW.inc} + +{ + REST Dataware . + Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON + de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores + Pascal e com compatibilidade entre sistemas operacionais. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. + + Membros do Grupo : + + XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. + Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. + Flvio Motta - Member Tester and DEMO Developer. + Mobius One - Devel, Tester and Admin. + Gustavo - Criptografia and Devel. + Eloy - Devel. + Roniery - Devel. +} + +interface + +uses + SysUtils, Dialogs, Forms, ExtCtrls, StdCtrls, ComCtrls, DBGrids, + uRESTDWBasicDB, DB{$IFNDEF FPC}, Grids{$ENDIF}, Controls, + Classes, SyncObjs, + {$IFDEF FPC} + FormEditingIntf, PropEdits, lazideintf + {$ELSE} + DesignEditors, DesignIntf + {$ENDIF}; + +Const + cSelect = 'Select %s From %s'; + cInsert = 'Insert into %s (%s) Values (%s)'; + cDelete = 'Delete From %s Where '; + cUpdate = 'Update %s Set %s Where '; + + Type + TOnTrhFimBusca = procedure(Sender : TObject; evento : string; lstString : TStringList) of object; + PointerString = ^String; + + { TThrBancoDados } + + TThrBancoDados = class(TThread) + private + FRESTDWDatabase : TRESTDWDatabasebaseBase; + FEvent : TSimpleEvent; + FLock : TCriticalSection; + FMustDie : boolean; + FTipoEvento : string; + FTipoRetorno : string; + FBuscar : string; + FMemString : TStringList; + FOnFimEvento : TOnTrhFimBusca; + protected + procedure Execute; override; + {$IFDEF FPC} + procedure TerminatedSet; {$IFNDEF NOGUI}override;{$ENDIF} + {$ENDIF} + procedure callFimBusca; + public + constructor Create; + destructor Destroy; override; + + procedure threadDie; + + procedure buscarTabelas; + procedure buscarFieldsNames(tabela : string); + published + property RESTDWDatabase : TRESTDWDatabasebaseBase read FRESTDWDatabase write FRESTDWDatabase; + property OnFimEvento : TOnTrhFimBusca read FOnFimEvento write FOnFimEvento; + end; + + { TFrmDWSqlEditor } + + TFrmDWSqlEditor = class(TForm) + BtnCancelar: TButton; + BtnExecute: TButton; + BtnOk: TButton; + DBGridRecord: TDBGrid; + PageControlResult: TPageControl; + PnlAction: TPanel; + PnlButton: TPanel; + PnlSQL: TPanel; + pSQLEditor: TPanel; + lbTables: TListBox; + labSql: TLabel; + Label1: TLabel; + lbFields: TListBox; + Label2: TLabel; + pSQLTypes: TPanel; + rbInsert: TRadioButton; + rbSelect: TRadioButton; + rbDelete: TRadioButton; + rbUpdate: TRadioButton; + TabSheetTable: TTabSheet; + pEditor: TPanel; + PageControl: TPageControl; + TabSheetSQL: TTabSheet; + Memo: TMemo; + Panel1: TPanel; + Label3: TLabel; + lbExecutedTime: TLabel; + tmClose: TTimer; + procedure BtnExecuteClick(Sender: TObject); + {$IFNDEF FPC} + procedure FormClose(Sender: TObject; var Action: TCloseAction); + {$ELSE} + procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); + {$ENDIF} + procedure FormShow(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure lbTablesClick(Sender: TObject); + procedure lbTablesKeyUp(Sender: TObject; var Key: Word; + Shift: TShiftState); + procedure MemoDragOver(Sender, Source: TObject; X, Y: Integer; + State: TDragState; var Accept: Boolean); + procedure MemoDragDrop(Sender, Source: TObject; X, Y: Integer); + procedure BtnCancelarClick(Sender: TObject); + procedure FormActivate(Sender: TObject); + procedure tmCloseTimer(Sender: TObject); + procedure BtnOkClick(Sender: TObject); + Private + { Private declarations } + DataSource : TDataSource; + RESTDWDatabase : TRESTDWDatabasebaseBase; + RESTDWClientSQL, + RESTDWClientSQLB : TRESTDWClientSQL; + vLastSelect, + vOldSQL : String; + pNewSQL : PointerString; + FThrBancoDados : TThrBancoDados; + FResModal : Cardinal; + FTablesLoading : Boolean; + Procedure SetFields; + Function BuildSQL : String; + Procedure SetDatabase(Value : TRESTDWDatabasebaseBase); + Procedure SetarControles(enab : boolean); + Procedure CarregarTabelas; + Procedure thrOnFimEvento(Sender : TObject; evento : string; lstString : TStringList); + Procedure thrOnTerminate(Sender : TObject); + Public + { Public declarations } + Procedure SetClientSQL(Value : TRESTDWClientSQL); + Property Database : TRESTDWDatabasebaseBase Read RESTDWDatabase Write SetDatabase; + Property NewSQL : PointerString Read pNewSQL Write pNewSQL; + End; + + Type + TRESTDWSQLEditor = Class(TStringProperty) + Public + Function GetAttributes : TPropertyAttributes; Override; + Procedure Edit; Override; + Function GetValue : String; Override; + procedure SetValue(const Value: string); Override; + End; + +Var + FrmDWSqlEditor : TFrmDWSqlEditor; + +Implementation + +{$IFDEF FPC} + {$R *.lfm} +{$ELSE} + {$R *.dfm} +{$ENDIF} + +Function TRESTDWSQLEditor.GetValue : String; +Begin + Result := Trim(TRESTDWClientSQL(GetComponent(0)).SQL.Text); + If Trim(Result) = '' Then + Result := 'Click here to set SQL...' +End; + +procedure TRESTDWSQLEditor.SetValue(const Value: string); +Var + objObj : TRESTDWClientSQL; +Begin + objObj := TRESTDWClientSQL(GetComponent(0)); + objObj.SQL.Text := Trim(Value); + Modified; // update na propridade do object inspector +end; + +Procedure TRESTDWSQLEditor.Edit; +Var + objObj : TRESTDWClientSQL; + vPointerString : String; +Begin + FrmDWSqlEditor := TFrmDWSqlEditor.Create(Application); + Try + objObj := TRESTDWClientSQL(GetComponent(0)); + FrmDWSqlEditor.SetClientSQL(objObj); + FrmDWSqlEditor.pNewSQL := @vPointerString; + vPointerString := ''; + FrmDWSqlEditor.ShowModal; + if vPointerString <> '' then + SetValue(vPointerString); +// objObj := Nil; + FreeAndNil(FrmDWSqlEditor); + Except + + End; +End; + +Function TRESTDWSQLEditor.GetAttributes: TPropertyAttributes; +Begin +//paAutoUpdate + Result := [paDialog]; +End; + +procedure TFrmDWSqlEditor.BtnCancelarClick(Sender: TObject); +begin + BtnCancelar.Tag := 1; + FResModal := mrCancel; + Close; +end; + +Procedure TFrmDWSqlEditor.BtnExecuteClick(Sender: TObject); +var + dti, dtf : TDateTime; +Begin + Screen.Cursor := crHourGlass; + Try + RESTDWClientSQLB.Close; +// RESTDWClientSQLB.BinaryRequest := RESTDWClientSQL.BinaryRequest; + RESTDWClientSQLB.SQL.Clear; + RESTDWClientSQLB.SQL.Add(Memo.Lines.Text); + + dti := Now; + RESTDWClientSQLB.Open; + dtf := Now; + Finally + lbExecutedTime.Caption := FormatDateTime('HH:nn:ss:zzz',dtf-dti); + Screen.Cursor := crDefault; + End; +End; + +procedure TFrmDWSqlEditor.BtnOkClick(Sender: TObject); +begin + pNewSQL^ := Trim(Memo.Lines.Text); + FResModal := mrOk; + Close; +end; + +procedure TFrmDWSqlEditor.FormActivate(Sender: TObject); +begin + If (Not FTablesLoading) And (lbTables.Count = 0) Then + CarregarTabelas; +end; + +{$IFNDEF FPC} +procedure TFrmDWSqlEditor.FormClose(Sender: TObject; var Action: TCloseAction); +{$ELSE} +procedure TFrmDWSqlEditor.FormClose(Sender: TObject; var CloseAction: TCloseAction); +{$ENDIF} +begin + If (FResModal = mrCancel) and (vOldSQL <> Memo.Text) and (BtnCancelar.Tag = 1) Then + Begin + {$IFDEF FPC} + If MessageDlg('SQL Editor', 'Realmente deseja sair ?', mtConfirmation, [mbYes, mbNo], 0) <> mrYes then + Begin + BtnCancelar.Tag := 0; + CloseAction:=caNone; + Exit; + End; + {$ELSE} + If MessageDlg('Realmente deseja sair ?', mtConfirmation, [mbYes, mbNo], 0) <> mrYes then + Begin + BtnCancelar.Tag := 0; + Action:=caNone; + Exit; + End; + {$ENDIF} + End; + BtnCancelar.Tag := 2; + if FThrBancoDados <> nil then + Begin + FThrBancoDados.threadDie; + tmClose.Enabled := True; + {$IFDEF FPC} + CloseAction := caNone; + {$ELSE} + Action := caNone; + {$ENDIF} + Exit; + End; + ModalResult := FResModal; // devido o clock (passa duas vezes) + RESTDWClientSQLB.Active := False; + FreeAndNil(RESTDWClientSQLB); + If Assigned(RESTDWDatabase) Then + RESTDWDatabase.Active := False; + FreeAndNil(DataSource); +// FrmDWSqlEditor := Nil; +// Release; +end; + +procedure TFrmDWSqlEditor.FormCreate(Sender: TObject); +begin + RESTDWClientSQLB := TRESTDWClientSQL.Create(Self); + DataSource := TDataSource.Create(Self); + vLastSelect := ''; + FResModal := mrNone; + FTablesLoading := False; + + RESTDWDatabase := nil; + + FThrBancoDados := TThrBancoDados.Create; + FThrBancoDados.OnFimEvento := {$IFDEF FPC}@{$ENDIF}thrOnFimEvento; + FThrBancoDados.OnTerminate := {$IFDEF FPC}@{$ENDIF}thrOnTerminate; + + SetarControles(False); +end; + +procedure TFrmDWSqlEditor.FormShow(Sender: TObject); +begin + DataSource.DataSet := RESTDWClientSQLB; + DBGridRecord.DataSource := DataSource; + + If Assigned(RESTDWClientSQL) Then + Begin + RESTDWDatabase := RESTDWClientSQL.DataBase; + RESTDWClientSQLB.DataBase := RESTDWDatabase; + End; + + FThrBancoDados.RESTDWDatabase := RESTDWDatabase; + If Assigned(RESTDWDatabase) Then + SetarControles(True); +end; + +Procedure TFrmDWSqlEditor.SetFields; +Begin + If (lbTables.Count > 0) And (lbTables.ItemIndex > -1) And + (vLastSelect <> lbTables.Items[lbTables.itemIndex]) Then + Begin + vLastSelect := lbTables.Items[lbTables.itemIndex]; + FThrBancoDados.buscarFieldsNames(vLastSelect); + End + Else If (lbTables.Count > 0) And (lbTables.ItemIndex = -1) Then + lbFields.Items.Clear; +End; + +procedure TFrmDWSqlEditor.thrOnFimEvento(Sender: TObject; evento: string; + lstString: TStringList); +begin + If evento = 'T' Then + Begin + FTablesLoading := False; + lbTables.Items.Text := lstString.Text; + If lbTables.Count > 0 Then + Begin + lbTables.ItemIndex := 0; + SetFields; + End; + End + Else If evento = 'F' Then + Begin + lbFields.Items.Text := lstString.Text; + End; +end; + +procedure TFrmDWSqlEditor.thrOnTerminate(Sender: TObject); +begin + FThrBancoDados := nil; +end; + +procedure TFrmDWSqlEditor.tmCloseTimer(Sender: TObject); +begin + tmClose.Enabled := False; + if FThrBancoDados <> nil then + tmClose.Enabled := True + else + Close; +end; + +procedure TFrmDWSqlEditor.SetarControles(enab: boolean); +begin + PnlButton.Enabled := enab; + PageControlResult.Enabled := enab; + pSQLEditor.Enabled := enab; +end; + +Procedure TFrmDWSqlEditor.SetClientSQL(Value: TRESTDWClientSQL); +Begin + RESTDWClientSQL := Value; + vOldSQL := ''; + Memo.Lines.Text := vOldSQL; + + if Assigned(RESTDWClientSQL) then begin + vOldSQL := RESTDWClientSQL.SQL.Text; + Memo.Lines.Text := vOldSQL; + end; +End; + +Procedure TFrmDWSqlEditor.SetDatabase(Value : TRESTDWDatabasebaseBase); +Begin + RESTDWClientSQLB.DataBase := Value; +End; + +procedure TFrmDWSqlEditor.lbTablesClick(Sender: TObject); +begin + SetFields; +end; + +procedure TFrmDWSqlEditor.lbTablesKeyUp(Sender: TObject; var Key: Word; + Shift: TShiftState); +begin + SetFields; +end; + +procedure TFrmDWSqlEditor.MemoDragOver(Sender, Source: TObject; X, + Y: Integer; State: TDragState; var Accept: Boolean); +begin + Accept := Source is Tlistbox; +end; + +Function TFrmDWSqlEditor.BuildSQL : String; +Var + I : Integer; + vFieldsA, + vFieldsB : String; +Begin + Result := ''; + vFieldsA := Result; + vFieldsB := Result; + If lbTables.itemIndex < 0 Then + Exit; + If rbSelect.Checked Then + Result := Format(cSelect, ['%s', lbTables.Items[lbTables.itemIndex]]); + If rbInsert.Checked Then + Result := Format(cInsert, [lbTables.Items[lbTables.itemIndex], '%s', '%s']); + If rbDelete.Checked Then + Result := Format(cDelete, [lbTables.Items[lbTables.itemIndex]]); + If rbUpdate.Checked Then + Result := Format(cUpdate, [lbTables.Items[lbTables.itemIndex], '%s']); + If lbFields.SelCount > 0 Then + Begin + If rbSelect.Checked Then + Begin + For I := 0 To lbFields.Count -1 Do + Begin + If lbFields.Selected[I] Then + If vFieldsA = '' Then + vFieldsA := lbFields.Items[I] + Else + vFieldsA := vFieldsA + ', ' + lbFields.Items[I]; + End; + Result := Format(Result, [vFieldsA]); + End + Else If rbInsert.Checked Then + Begin + For I := 0 To lbFields.Count -1 Do + Begin + If lbFields.Selected[I] Then + If vFieldsA = '' Then + vFieldsA := lbFields.Items[I] + Else + vFieldsA := vFieldsA + ', ' + lbFields.Items[I]; + If lbFields.Selected[I] Then + If vFieldsB = '' Then + vFieldsB := ':' + lbFields.Items[I] + Else + vFieldsB := vFieldsB + ', :' + lbFields.Items[I]; + End; + Result := Format(Result, [vFieldsA, vFieldsB]); + End + Else If rbUpdate.Checked Then + Begin + For I := 0 To lbFields.Count -1 Do + Begin + If lbFields.Selected[I] Then + If vFieldsA = '' Then + vFieldsA := lbFields.Items[I] + ' = :' + lbFields.Items[I] + Else + vFieldsA := vFieldsA + ', ' + lbFields.Items[I] + ' = :' + lbFields.Items[I]; + End; + Result := Format(Result, [vFieldsA]); + End; + End + Else + Begin + If rbSelect.Checked Then + Begin + Result := Format(Result, ['*']) + End + Else If rbInsert.Checked Then + Begin + For I := 0 To lbFields.Count -1 Do + Begin + If vFieldsA = '' Then + vFieldsA := lbFields.Items[I] + Else + vFieldsA := vFieldsA + ', ' + lbFields.Items[I]; + If vFieldsB = '' Then + vFieldsB := ':' + lbFields.Items[I] + Else + vFieldsB := vFieldsB + ', :' + lbFields.Items[I]; + End; + Result := Format(Result, [vFieldsA, vFieldsB]); + End + Else If rbUpdate.Checked Then + Begin + For I := 0 To lbFields.Count -1 Do + Begin + If vFieldsA = '' Then + vFieldsA := lbFields.Items[I] + ' = :' + lbFields.Items[I] + Else + vFieldsA := vFieldsA + ', ' + lbFields.Items[I] + ' = :' + lbFields.Items[I]; + End; + Result := Format(Result, [vFieldsA]); + End; + End; +End; + +procedure TFrmDWSqlEditor.CarregarTabelas; +begin + If FThrBancoDados = Nil Then + Exit; + FTablesLoading := True; + FThrBancoDados.buscarTabelas; +end; + +procedure TFrmDWSqlEditor.MemoDragDrop(Sender, Source: TObject; X, + Y: Integer); +begin + If Source = lbTables Then + If Trim(TMemo(Sender).Lines.Text) = '' Then + TMemo(Sender).Lines.Text := BuildSQL + Else + TMemo(Sender).Lines.Text := TMemo(Sender).Lines.Text + sLineBreak + BuildSQL; +end; + +{ TThrBancoDados } + +procedure TThrBancoDados.buscarFieldsNames(tabela: string); +begin + FLock.Acquire; + Try + FTipoEvento := 'F'; + FBuscar := tabela; + FEvent.SetEvent; + Finally + FLock.Release; + End; +end; + +procedure TThrBancoDados.buscarTabelas; +begin + FLock.Acquire; + Try + FTipoEvento := 'T'; + FBuscar := ''; + FEvent.SetEvent; + Finally + FLock.Release; + End; +end; + +procedure TThrBancoDados.callFimBusca; +var + vTipo : string; +begin + vTipo := FTipoRetorno; + FTipoRetorno := ''; + if Assigned(FOnFimEvento) then + FOnFimEvento(Self,vTipo,FMemString); +end; + +constructor TThrBancoDados.Create; +begin + FRESTDWDatabase := nil; + FMustDie := False; + FEvent := TSimpleEvent.Create; + FLock := TCriticalSection.Create; + FMemString := TStringList.Create; + FreeOnTerminate := True; + {$IFDEF FPC} + inherited Create(False); + {$ELSE} + inherited Create(False); + {$ENDIF} +end; + +destructor TThrBancoDados.Destroy; +begin + FMemString.Free; + FEvent.Free; + FLock.Free; + + inherited; +end; + +procedure TThrBancoDados.Execute; +var + vTipoEvento, + vBuscar : String; +begin + while not Terminated do begin + {$IF (NOT DEFINED(FPC)) AND (CompilerVersion < 21)} + FEvent.WaitFor($FFFFFFFF);// INFINITE + {$ELSE} + FEvent.WaitFor(INFINITE); + {$IFEND} + + FLock.Acquire; + Try + FEvent.ResetEvent; + vTipoEvento := FTipoEvento; + vBuscar := FBuscar; + FTipoEvento := ''; + FBuscar := ''; + Finally + FLock.Release; + End; + + if FMustDie then begin + Terminate; + Break; + end; + + If vTipoEvento = '' Then + Continue; + + FMemString.Clear; + try + if FRESTDWDatabase <> nil then begin + if vTipoEvento = 'T' then + FRESTDWDatabase.GetTableNames(FMemString) + else if vTipoEvento = 'F' then + FRESTDWDatabase.GetFieldNames(vBuscar,FMemString); + end; + except + + end; + + if FMustDie then begin + Terminate; + Break; + end; + + FTipoRetorno := vTipoEvento; + Synchronize({$IFDEF FPC}@{$ENDIF}callFimBusca); + + if FMustDie then begin + Terminate; + Break; + end; + end; +end; + +{$IFDEF FPC} + procedure TThrBancoDados.TerminatedSet; + begin + {$IFNDEF NOGUI} inherited TerminatedSet;{$ENDIF} + DoTerminate; + end; +{$ENDIF} + +procedure TThrBancoDados.threadDie; +begin + FLock.Acquire; + Try + FTipoEvento := ''; + FBuscar := ''; + FMustDie := True; + FEvent.SetEvent; + Finally + FLock.Release; + End; +end; + +end. diff --git a/CORE/Source/Plugins/SQLEditor/uRESTDWUpdSqlEditor.pas b/CORE/Source/Plugins/SQLEditor/uRESTDWUpdSqlEditor.pas index 23713d7b1..7e9b994d0 100644 --- a/CORE/Source/Plugins/SQLEditor/uRESTDWUpdSqlEditor.pas +++ b/CORE/Source/Plugins/SQLEditor/uRESTDWUpdSqlEditor.pas @@ -1,21 +1,21 @@ unit uRESTDWUpdSqlEditor; -{$I ..\..\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware . Criado por XyberX (Gilbero Rocha da Silva), o REST Dataware tem como objetivo o uso de REST/JSON de maneira simples, em qualquer Compilador Pascal (Delphi, Lazarus e outros...). - O REST Dataware também tem por objetivo levar componentes compatíveis entre o Delphi e outros Compiladores + O REST Dataware tambm tem por objetivo levar componentes compatveis entre o Delphi e outros Compiladores Pascal e com compatibilidade entre sistemas operacionais. - Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal você usuário que precisa - de produtividade e flexibilidade para produção de Serviços REST/JSON, simplificando o processo para você programador. + Desenvolvido para ser usado de Maneira RAD, o REST Dataware tem como objetivo principal voc usurio que precisa + de produtividade e flexibilidade para produo de Servios REST/JSON, simplificando o processo para voc programador. Membros do Grupo : XyberX (Gilberto Rocha) - Admin - Criador e Administrador do pacote. Alexandre Abbade - Admin - Administrador do desenvolvimento de DEMOS, coordenador do Grupo. - Flávio Motta - Member Tester and DEMO Developer. + Flvio Motta - Member Tester and DEMO Developer. Mobius One - Devel, Tester and Admin. Gustavo - Criptografia and Devel. Eloy - Devel. From 715d94df35175a9b88feda82919d7e78240b3a1a Mon Sep 17 00:00:00 2001 From: Roniery Santos Cardoso Date: Tue, 8 Sep 2026 22:01:22 -0300 Subject: [PATCH 09/22] chore(inc): configura NativeDrive como padrao e atualiza ferramentas Ajusta uRESTDW.inc para suporte ao RESTDWMemtable/NativeDrive por padrao, adiciona includes de suporte (SynEdit, WebView2, DCPCrypt) e atualiza ShellTools/Wizards/Consts para Delphi e Lazarus. refs r4050 --- CORE/Source/Consts/uRESTDWConsts.pas | 8 +- CORE/Source/Includes/DWDCPcast256.inc | 178 ++ CORE/Source/Includes/DWDCPrijndael.inc | 871 ++++++++++ CORE/Source/Includes/SynEdit.inc | 1425 +++++++++++++++++ CORE/Source/Includes/SynEditJedi.inc | 1182 ++++++++++++++ CORE/Source/Includes/htmlcons.inc | 359 +++++ CORE/Source/Includes/uRESTDW.inc | 144 +- CORE/Source/Includes/uRESTDWPrivSynEdit.inc | 1425 +++++++++++++++++ CORE/Source/Includes/uWVVersion.inc | 12 + CORE/Source/Includes/webview2.inc | 518 ++++++ .../ShellTools/uRESTDWShellServicesDelphi.pas | 10 +- .../uRESTDWShellServicesLazarus.pas | 10 +- .../uRESTDWShellServicesRegDelphi.pas | 10 +- .../uRESTDWShellServicesRegLazarus.pas | 10 +- CORE/Source/Wizards/RDWCGIWizard.pas | 4 +- CORE/Source/Wizards/STLWizard.pas | 2 +- CORE/Source/Wizards/STLWizardreg.pas | 2 +- 17 files changed, 6074 insertions(+), 96 deletions(-) create mode 100644 CORE/Source/Includes/DWDCPcast256.inc create mode 100644 CORE/Source/Includes/DWDCPrijndael.inc create mode 100644 CORE/Source/Includes/SynEdit.inc create mode 100644 CORE/Source/Includes/SynEditJedi.inc create mode 100644 CORE/Source/Includes/htmlcons.inc create mode 100644 CORE/Source/Includes/uRESTDWPrivSynEdit.inc create mode 100644 CORE/Source/Includes/uWVVersion.inc create mode 100644 CORE/Source/Includes/webview2.inc diff --git a/CORE/Source/Consts/uRESTDWConsts.pas b/CORE/Source/Consts/uRESTDWConsts.pas index 28af857d8..478a79b7e 100644 --- a/CORE/Source/Consts/uRESTDWConsts.pas +++ b/CORE/Source/Consts/uRESTDWConsts.pas @@ -1,6 +1,6 @@ Unit uRESTDWConsts; -{$I ..\..\Source\Includes\uRESTDW.inc} +{$I uRESTDW.inc} { REST Dataware. @@ -59,9 +59,9 @@ GOffsetFromUTC : TDateTime = 0{$IFDEF HAS_DEPRECATED}deprecated{$ENDIF}; // controle de versão - RESTDWVersionINFO = 'v2.1.0-'; - RESTDWRelease = '3975'; - RESTDWCodeProject = 'Final Fantasy X - SourceForge'; + RESTDWVersionINFO = 'v2.1.1 Alpha -'; + RESTDWRelease = '4059'; + RESTDWCodeProject = 'Phoenix'; RESTDWVersao = RESTDWVersionINFO + RESTDWRelease + '(' + RESTDWCodeProject + ')'; RESTDWDialogoTitulo = 'REST DataWare Components ' + RESTDWVersao; RESTDWSobreTitulo = 'REST DataWare '+ RESTDWVersao; diff --git a/CORE/Source/Includes/DWDCPcast256.inc b/CORE/Source/Includes/DWDCPcast256.inc new file mode 100644 index 000000000..19c196fba --- /dev/null +++ b/CORE/Source/Includes/DWDCPcast256.inc @@ -0,0 +1,178 @@ +const + S1: array[0..255] of DWord= ( + $30fb40d4, $9fa0ff0b, $6beccd2f, $3f258c7a, $1e213f2f, $9C004dd3, + $6003e540, $cf9fc949, $bfd4af27, $88bbbdb5, $e2034090, $98d09675, + $6e63a0e0, $15c361d2, $c2e7661d, $22d4ff8e, $28683b6f, $c07fd059, + $ff2379c8, $775f50e2, $43c340d3, $df2f8656, $887ca41a, $a2d2bd2d, + $a1c9e0d6, $346c4819, $61b76d87, $22540f2f, $2abe32e1, $aa54166b, + $22568e3a, $a2d341d0, $66db40c8, $a784392f, $004dff2f, $2db9d2de, + $97943fac, $4a97c1d8, $527644b7, $b5f437a7, $b82cbaef, $d751d159, + $6ff7f0ed, $5a097a1f, $827b68d0, $90ecf52e, $22b0c054, $bc8e5935, + $4b6d2f7f, $50bb64a2, $d2664910, $bee5812d, $b7332290, $e93b159f, + $b48ee411, $4bff345d, $fd45c240, $ad31973f, $c4f6d02e, $55fc8165, + $d5b1caad, $a1ac2dae, $a2d4b76d, $c19b0C50, $882240f2, $0c6e4f38, + $a4e4bfd7, $4f5ba272, $564c1d2f, $c59c5319, $b949e354, $b04669fe, + $b1b6ab8a, $c71358dd, $6385c545, $110f935d, $57538ad5, $6a390493, + $e63d37e0, $2a54f6b3, $3a787d5f, $6276a0b5, $19a6fcdf, $7a42206a, + $29f9d4d5, $f61b1891, $bb72275e, $aa508167, $38901091, $c6b505eb, + $84c7cb8c, $2ad75a0f, $874a1427, $a2d1936b, $2ad286af, $aa56d291, + $d7894360, $425c750d, $93b39e26, $187184c9, $6c00b32d, $73e2bb14, + $a0bebc3c, $54623779, $64459eab, $3f328b82, $7718cf82, $59a2cea6, + $04ee002e, $89fe78e6, $3fab0950, $325ff6C2, $81383f05, $6963c5c8, + $76cb5ad6, $d49974c9, $ca180dcf, $380782d5, $c7fa5cf6, $8ac31511, + $35e79e13, $47da91d0, $f40f9086, $a7e2419e, $31366241, $051ef495, + $aa573b04, $4a805d8d, $548300d0, $00322a3c, $bf64cddf, $ba57a68e, + $75c6372b, $50afd341, $a7c13275, $915a0bf5, $6b54bfab, $2b0b1426, + $ab4cc9d7, $449ccd82, $f7fbf265, $ab85c5f3, $1b55db94, $aad4e324, + $cfa4bd3f, $2deaa3e2, $9e204d02, $c8bd25ac, $eadf55b3, $d5bd9e98, + $e31231b2, $2ad5ad6c, $954329de, $adbe4528, $d8710f69, $aa51c90f, + $aa786bf6, $22513f1e, $aa51a79b, $2ad344cc, $7b5a41f0, $d37cfbad, + $1b069505, $41ece491, $b4c332e6, $032268d4, $c9600acc, $ce387e6d, + $bf6bb16c, $6a70fb78, $0d03d9c9, $d4df39de, $e01063da, $4736f464, + $5ad328d8, $b347cc96, $75bb0fc3, $98511bfb, $4ffbcc35, $b58bcf6a, + $e11f0abc, $bfc5fe4a, $a70aec10, $ac39570a, $3f04442f, $6188b153, + $e0397a2e, $5727cb79, $9ceb418f, $1cacd68d, $2ad37c96, $0175cb9d, + $c69dff09, $c75b65f0, $d9db40d8, $ec0e7779, $4744ead4, $b11c3274, + $dd24cb9e, $7e1c54bd, $f01144f9, $d2240eb1, $9675b3fd, $a3ac3755, + $d47c27af, $51c85f4d, $56907596, $a5bb15e6, $580304f0, $ca042cf1, + $011a37ea, $8dbfaadb, $35ba3e4a, $3526ffa0, $c37b4d09, $bc306ed9, + $98a52666, $5648f725, $ff5e569d, $0ced63d0, $7c63b2cf, $700b45e1, + $d5ea50f1, $85a92872, $af1fbda7, $d4234870, $a7870bf3, $2d3b4d79, + $42e04198, $0cd0ede7, $26470db8, $f881814C, $474d6ad7, $7c0c5e5c, + $d1231959, $381b7298, $f5d2f4db, $ab838653, $6e2f1e23, $83719c9e, + $bd91e046, $9a56456e, $dc39200c, $20c8c571, $962bda1c, $e1e696ff, + $b141ab08, $7cca89b9, $1a69e783, $02cc4843, $a2f7c579, $429ef47d, + $427b169c, $5ac9f049, $dd8f0f00, $5c8165bf); + S2: array[0..255] of DWord= ( + $1f201094, $ef0ba75b, $69e3cf7e, $393f4380, $fe61cf7a, $eec5207a, + $55889c94, $72fc0651, $ada7ef79, $4e1d7235, $d55a63ce, $de0436ba, + $99c430ef, $5f0c0794, $18dcdb7d, $a1d6eff3, $a0b52f7b, $59e83605, + $ee15b094, $e9ffd909, $dc440086, $ef944459, $ba83ccb3, $e0c3cdfb, + $d1da4181, $3b092ab1, $f997f1c1, $a5e6cf7b, $01420ddb, $e4e7ef5b, + $25a1ff41, $e180f806, $1fc41080, $179bee7a, $d37ac6a9, $fe5830a4, + $98de8b7f, $77e83f4e, $79929269, $24fa9f7b, $e113c85b, $acc40083, + $d7503525, $f7ea615f, $62143154, $0d554b63, $5d681121, $c866c359, + $3d63cf73, $cee234c0, $d4d87e87, $5c672b21, $071f6181, $39f7627f, + $361e3084, $e4eb573b, $602f64a4, $d63acd9c, $1bbc4635, $9e81032d, + $2701f50c, $99847ab4, $a0e3df79, $ba6cf38c, $10843094, $2537a95e, + $f46f6ffe, $a1ff3b1f, $208cfb6a, $8f458c74, $d9e0a227, $4ec73a34, + $fc884f69, $3e4de8df, $ef0e0088, $3559648d, $8a45388c, $1d804366, + $721d9bfd, $a58684bb, $e8256333, $844e8212, $128d8098, $fed33fb4, + $ce280ae1, $27e19ba5, $d5a6c252, $e49754bd, $c5d655dd, $eb667064, + $77840b4d, $a1b6a801, $84db26a9, $e0b56714, $21f043b7, $e5d05860, + $54f03084, $066ff472, $a31aa153, $dadc4755, $b5625dbf, $68561be6, + $83ca6b94, $2d6ed23b, $eccf01db, $a6d3d0ba, $b6803d5c, $af77a709, + $33b4a34c, $397bc8d6, $5ee22b95, $5f0e5304, $81ed6f61, $20e74364, + $b45e1378, $de18639b, $881ca122, $b96726d1, $8049a7e8, $22b7da7b, + $5e552d25, $5272d237, $79d2951c, $c60d894c, $488cb402, $1ba4fe5b, + $a4b09f6b, $1ca815cf, $a20c3005, $8871df63, $b9de2fcb, $0cc6c9e9, + $0beeff53, $e3214517, $b4542835, $9f63293c, $ee41e729, $6e1d2d7c, + $50045286, $1e6685f3, $f33401c6, $30a22c95, $31a70850, $60930f13, + $73f98417, $a1269859, $ec645c44, $52c877a9, $cdff33a6, $a02b1741, + $7cbad9a2, $2180036f, $50d99c08, $cb3f4861, $c26bd765, $64a3f6ab, + $80342676, $25a75e7b, $e4e6d1fc, $20c710e6, $cdf0b680, $17844d3b, + $31eef84d, $7e0824e4, $2ccb49eb, $846a3bae, $8ff77888, $ee5d60f6, + $7af75673, $2fdd5cdb, $a11631c1, $30f66f43, $b3faec54, $157fd7fa, + $ef8579cc, $d152de58, $db2ffd5e, $8f32ce19, $306af97a, $02f03ef8, + $99319ad5, $c242fa0f, $a7e3ebb0, $c68e4906, $b8da230c, $80823028, + $dcdef3c8, $d35fb171, $088a1bc8, $bec0c560, $61a3c9e8, $bca8f54d, + $c72feffa, $22822e99, $82c570b4, $d8d94e89, $8b1c34bc, $301e16e6, + $273be979, $b0ffeaa6, $61d9b8c6, $00b24869, $b7ffce3f, $08dc283b, + $43daf65a, $f7e19798, $7619b72f, $8f1c9ba4, $dc8637a0, $16a7d3b1, + $9fc393b7, $a7136eeb, $c6bcc63e, $1a513742, $ef6828bc, $520365d6, + $2d6a77ab, $3527ed4b, $821fd216, $095c6e2e, $db92f2fb, $5eea29cb, + $145892f5, $91584f7f, $5483697b, $2667a8cc, $85196048, $8c4bacea, + $833860d4, $0d23e0f9, $6c387e8a, $0ae6d249, $b284600c, $d835731d, + $dcb1c647, $ac4c56ea, $3ebd81b3, $230eabb0, $6438bc87, $f0b5b1fa, + $8f5ea2b3, $fc184642, $0a036b7a, $4fb089bd, $649da589, $a345415e, + $5c038323, $3e5d3bb9, $43d79572, $7e6dd07c, $06dfdf1e, $6c6cc4ef, + $7160a539, $73bfbe70, $83877605, $4523ecf1); + S3: array[0..255] of DWord= ( + $8defc240, $25fa5d9f, $eb903dbf, $e810c907, $47607fff, $369fe44b, + $8c1fc644, $aececa90, $beb1f9bf, $eefbcaea, $e8cf1950, $51df07ae, + $920e8806, $f0ad0548, $e13c8d83, $927010d5, $11107d9f, $07647db9, + $b2e3e4d4, $3d4f285e, $b9afa820, $fade82e0, $a067268b, $8272792e, + $553fb2c0, $489ae22b, $d4ef9794, $125e3fbc, $21fffcee, $825b1bfd, + $9255c5ed, $1257a240, $4e1a8302, $bae07fff, $528246e7, $8e57140e, + $3373f7bf, $8c9f8188, $a6fc4ee8, $c982b5a5, $a8c01db7, $579fc264, + $67094f31, $f2bd3f5f, $40fff7c1, $1fb78dfc, $8e6bd2c1, $437be59b, + $99b03dbf, $b5dbc64b, $638dc0e6, $55819d99, $a197c81c, $4a012d6e, + $c5884a28, $ccc36f71, $b843c213, $6c0743f1, $8309893c, $0feddd5f, + $2f7fe850, $d7c07f7e, $02507fbf, $5afb9a04, $a747d2d0, $1651192e, + $af70bf3e, $58c31380, $5f98302e, $727cc3c4, $0a0fb402, $0f7fef82, + $8c96fdad, $5d2c2aae, $8ee99a49, $50da88b8, $8427f4a0, $1eac5790, + $796fb449, $8252dc15, $efbd7d9b, $a672597d, $ada840d8, $45f54504, + $fa5d7403, $e83ec305, $4f91751a, $925669c2, $23efe941, $a903f12e, + $60270df2, $0276e4b6, $94fd6574, $927985b2, $8276dbcb, $02778176, + $f8af918d, $4e48f79e, $8f616ddf, $e29d840e, $842f7d83, $340ce5c8, + $96bbb682, $93b4b148, $ef303cab, $984faf28, $779faf9b, $92dc560d, + $224d1e20, $8437aa88, $7d29dc96, $2756d3dc, $8b907cee, $b51fd240, + $e7c07ce3, $e566b4a1, $c3e9615e, $3cf8209d, $6094d1e3, $cd9ca341, + $5c76460e, $00ea983b, $d4d67881, $fd47572c, $f76cedd9, $bda8229c, + $127dadaa, $438a074e, $1f97c090, $081bdb8a, $93a07ebe, $b938ca15, + $97b03cff, $3dc2c0f8, $8d1ab2ec, $64380e51, $68cc7bfb, $d90f2788, + $12490181, $5de5ffd4, $dd7ef86a, $76a2e214, $b9a40368, $925d958f, + $4b39fffa, $ba39aee9, $a4ffd30b, $faf7933b, $6d498623, $193cbcfa, + $27627545, $825cf47a, $61bd8ba0, $d11e42d1, $cead04f4, $127ea392, + $10428db7, $8272a972, $9270c4a8, $127de50b, $285ba1c8, $3c62f44f, + $35c0eaa5, $e805d231, $428929fb, $b4fcdf82, $4fb66a53, $0e7dc15b, + $1f081fab, $108618ae, $fcfd086d, $f9ff2889, $694bcc11, $236a5cae, + $12deca4d, $2c3f8cc5, $d2d02dfe, $f8ef5896, $e4cf52da, $95155b67, + $494a488c, $b9b6a80c, $5c8f82bc, $89d36b45, $3a609437, $ec00c9a9, + $44715253, $0a874b49, $d773bc40, $7c34671c, $02717ef6, $4feb5536, + $a2d02fff, $d2bf60c4, $d43f03c0, $50b4ef6d, $07478cd1, $006e1888, + $a2e53f55, $b9e6d4bc, $a2048016, $97573833, $d7207d67, $de0f8f3d, + $72f87b33, $abcc4f33, $7688c55d, $7b00a6b0, $947b0001, $570075d2, + $f9bb88f8, $8942019e, $4264a5ff, $856302e0, $72dbd92b, $ee971b69, + $6ea22fde, $5f08ae2b, $af7a616d, $e5c98767, $cf1febd2, $61efc8c2, + $f1ac2571, $cc8239c2, $67214cb8, $b1e583d1, $b7dc3e62, $7f10bdce, + $f90a5c38, $0ff0443d, $606e6dc6, $60543a49, $5727c148, $2be98a1d, + $8ab41738, $20e1be24, $af96da0f, $68458425, $99833be5, $600d457d, + $282f9350, $8334b362, $d91d1120, $2b6d8da0, $642b1e31, $9c305a00, + $52bce688, $1b03588a, $f7baefd5, $4142ed9c, $a4315c11, $83323ec5, + $dfef4636, $a133c501, $e9d3531c, $ee353783); + S4: array[0..255] of DWord= ( + $9db30420, $1fb6e9de, $a7be7bef, $d273a298, $4a4f7bdb, $64ad8c57, + $85510443, $fa020ed1, $7e287aff, $e60fb663, $095f35a1, $79ebf120, + $fd059d43, $6497b7b1, $f3641f63, $241e4adf, $28147f5f, $4fa2b8cd, + $c9430040, $0cc32220, $fdd30b30, $c0a5374f, $1d2d00d9, $24147b15, + $ee4d111a, $0fca5167, $71ff904c, $2d195ffe, $1a05645f, $0c13fefe, + $081b08ca, $05170121, $80530100, $e83e5efe, $ac9af4f8, $7fe72701, + $d2b8ee5f, $06df4261, $bb9e9b8a, $7293ea25, $ce84ffdf, $f5718801, + $3dd64b04, $a26f263b, $7ed48400, $547eebe6, $446d4ca0, $6cf3d6f5, + $2649abdf, $aea0c7f5, $36338cc1, $503f7e93, $d3772061, $11b638e1, + $72500e03, $f80eb2bb, $abe0502e, $ec8d77de, $57971e81, $e14f6746, + $c9335400, $6920318f, $081dbb99, $ffc304a5, $4d351805, $7f3d5ce3, + $a6c866c6, $5d5bcca9, $daec6fea, $9f926f91, $9f46222f, $3991467d, + $a5bf6d8e, $1143c44f, $43958302, $d0214eeb, $022083b8, $3fb6180c, + $18f8931e, $281658e6, $26486e3e, $8bd78a70, $7477e4c1, $b506e07c, + $f32d0a25, $79098b02, $e4eabb81, $28123b23, $69dead38, $1574ca16, + $df871b62, $211c40b7, $a51a9ef9, $0014377b, $041e8ac8, $09114003, + $bd59e4d2, $e3d156d5, $4fe876d5, $2f91a340, $557be8de, $00eae4a7, + $0ce5c2ec, $4db4bba6, $e756bdff, $dd3369ac, $ec17b035, $06572327, + $99afc8b0, $56c8c391, $6b65811c, $5e146119, $6e85cb75, $be07c002, + $c2325577, $893ff4ec, $5bbfc92d, $d0ec3b25, $b7801ab7, $8d6d3b24, + $20c763ef, $c366a5fc, $9c382880, $0ace3205, $aac9548a, $eca1d7c7, + $041afa32, $1d16625a, $6701902c, $9b757a54, $31d477f7, $9126b031, + $36cc6fdb, $c70b8b46, $d9e66a48, $56e55a79, $026a4ceb, $52437eff, + $2f8f76b4, $0df980a5, $8674cde3, $edda04eb, $17a9be04, $2c18f4df, + $b7747f9d, $ab2af7b4, $efc34d20, $2e096b7c, $1741a254, $e5b6a035, + $213d42f6, $2c1c7c26, $61c2f50f, $6552daf9, $d2c231f8, $25130f69, + $d8167fa2, $0418f2c8, $001a96a6, $0d1526ab, $63315c21, $5e0a72ec, + $49bafefd, $187908d9, $8d0dbd86, $311170a7, $3e9b640c, $cc3e10d7, + $d5cad3b6, $0caec388, $f73001e1, $6c728aff, $71eae2a1, $1f9af36e, + $cfcbd12f, $c1de8417, $ac07be6b, $cb44a1d8, $8b9b0f56, $013988c3, + $b1c52fca, $b4be31cd, $d8782806, $12a3a4e2, $6f7de532, $58fd7eb6, + $d01ee900, $24adffc2, $f4990fc5, $9711aac5, $001d7b95, $82e5e7d2, + $109873f6, $00613096, $c32d9521, $ada121ff, $29908415, $7fbb977f, + $af9eb3db, $29c9ed2a, $5ce2a465, $a730f32c, $d0aa3fe8, $8a5cc091, + $d49e2ce7, $0ce454a9, $d60acd86, $015f1919, $77079103, $dea03af6, + $78a8565e, $dee356df, $21f05cbe, $8b75e387, $b3c50651, $b8a5c3ef, + $d8eeb6d2, $e523be77, $c2154529, $2f69efdf, $afe67afb, $f470c4b2, + $f3e0eb5b, $d6cc9876, $39e4460c, $1fda8538, $1987832f, $ca007367, + $a99144f8, $296b299e, $492fc295, $9266beab, $b5676e69, $9bd3ddda, + $df7e052f, $db25701c, $1b5e51ee, $f65324e6, $6afce36c, $0316cc04, + $8644213e, $b7dc59d0, $7965291f, $ccd6fd43, $41823979, $932bcdf6, + $b657c34d, $4edfd282, $7ae5290c, $3cb9536b, $851e20fe, $9833557e, + $13ecf0b0, $d3ffb372, $3f85c5c1, $0aef7ed2); + diff --git a/CORE/Source/Includes/DWDCPrijndael.inc b/CORE/Source/Includes/DWDCPrijndael.inc new file mode 100644 index 000000000..285f635ae --- /dev/null +++ b/CORE/Source/Includes/DWDCPrijndael.inc @@ -0,0 +1,871 @@ +const + MAXBC= 8; + MAXKC= 8; + + S: array[0..255] of byte= ( + 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, + 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, + 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, + 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, + 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, + 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, + 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, + 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, + 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, + 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, + 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, + 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, + 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, + 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, + 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, + 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22); + T1: array[0..255,0..3] of byte= ( + ($c6,$63,$63,$a5), ($f8,$7c,$7c,$84), ($ee,$77,$77,$99), ($f6,$7b,$7b,$8d), + ($ff,$f2,$f2,$0d), ($d6,$6b,$6b,$bd), ($de,$6f,$6f,$b1), ($91,$c5,$c5,$54), + ($60,$30,$30,$50), ($02,$01,$01,$03), ($ce,$67,$67,$a9), ($56,$2b,$2b,$7d), + ($e7,$fe,$fe,$19), ($b5,$d7,$d7,$62), ($4d,$ab,$ab,$e6), ($ec,$76,$76,$9a), + ($8f,$ca,$ca,$45), ($1f,$82,$82,$9d), ($89,$c9,$c9,$40), ($fa,$7d,$7d,$87), + ($ef,$fa,$fa,$15), ($b2,$59,$59,$eb), ($8e,$47,$47,$c9), ($fb,$f0,$f0,$0b), + ($41,$ad,$ad,$ec), ($b3,$d4,$d4,$67), ($5f,$a2,$a2,$fd), ($45,$af,$af,$ea), + ($23,$9c,$9c,$bf), ($53,$a4,$a4,$f7), ($e4,$72,$72,$96), ($9b,$c0,$c0,$5b), + ($75,$b7,$b7,$c2), ($e1,$fd,$fd,$1c), ($3d,$93,$93,$ae), ($4c,$26,$26,$6a), + ($6c,$36,$36,$5a), ($7e,$3f,$3f,$41), ($f5,$f7,$f7,$02), ($83,$cc,$cc,$4f), + ($68,$34,$34,$5c), ($51,$a5,$a5,$f4), ($d1,$e5,$e5,$34), ($f9,$f1,$f1,$08), + ($e2,$71,$71,$93), ($ab,$d8,$d8,$73), ($62,$31,$31,$53), ($2a,$15,$15,$3f), + ($08,$04,$04,$0c), ($95,$c7,$c7,$52), ($46,$23,$23,$65), ($9d,$c3,$c3,$5e), + ($30,$18,$18,$28), ($37,$96,$96,$a1), ($0a,$05,$05,$0f), ($2f,$9a,$9a,$b5), + ($0e,$07,$07,$09), ($24,$12,$12,$36), ($1b,$80,$80,$9b), ($df,$e2,$e2,$3d), + ($cd,$eb,$eb,$26), ($4e,$27,$27,$69), ($7f,$b2,$b2,$cd), ($ea,$75,$75,$9f), + ($12,$09,$09,$1b), ($1d,$83,$83,$9e), ($58,$2c,$2c,$74), ($34,$1a,$1a,$2e), + ($36,$1b,$1b,$2d), ($dc,$6e,$6e,$b2), ($b4,$5a,$5a,$ee), ($5b,$a0,$a0,$fb), + ($a4,$52,$52,$f6), ($76,$3b,$3b,$4d), ($b7,$d6,$d6,$61), ($7d,$b3,$b3,$ce), + ($52,$29,$29,$7b), ($dd,$e3,$e3,$3e), ($5e,$2f,$2f,$71), ($13,$84,$84,$97), + ($a6,$53,$53,$f5), ($b9,$d1,$d1,$68), ($00,$00,$00,$00), ($c1,$ed,$ed,$2c), + ($40,$20,$20,$60), ($e3,$fc,$fc,$1f), ($79,$b1,$b1,$c8), ($b6,$5b,$5b,$ed), + ($d4,$6a,$6a,$be), ($8d,$cb,$cb,$46), ($67,$be,$be,$d9), ($72,$39,$39,$4b), + ($94,$4a,$4a,$de), ($98,$4c,$4c,$d4), ($b0,$58,$58,$e8), ($85,$cf,$cf,$4a), + ($bb,$d0,$d0,$6b), ($c5,$ef,$ef,$2a), ($4f,$aa,$aa,$e5), ($ed,$fb,$fb,$16), + ($86,$43,$43,$c5), ($9a,$4d,$4d,$d7), ($66,$33,$33,$55), ($11,$85,$85,$94), + ($8a,$45,$45,$cf), ($e9,$f9,$f9,$10), ($04,$02,$02,$06), ($fe,$7f,$7f,$81), + ($a0,$50,$50,$f0), ($78,$3c,$3c,$44), ($25,$9f,$9f,$ba), ($4b,$a8,$a8,$e3), + ($a2,$51,$51,$f3), ($5d,$a3,$a3,$fe), ($80,$40,$40,$c0), ($05,$8f,$8f,$8a), + ($3f,$92,$92,$ad), ($21,$9d,$9d,$bc), ($70,$38,$38,$48), ($f1,$f5,$f5,$04), + ($63,$bc,$bc,$df), ($77,$b6,$b6,$c1), ($af,$da,$da,$75), ($42,$21,$21,$63), + ($20,$10,$10,$30), ($e5,$ff,$ff,$1a), ($fd,$f3,$f3,$0e), ($bf,$d2,$d2,$6d), + ($81,$cd,$cd,$4c), ($18,$0c,$0c,$14), ($26,$13,$13,$35), ($c3,$ec,$ec,$2f), + ($be,$5f,$5f,$e1), ($35,$97,$97,$a2), ($88,$44,$44,$cc), ($2e,$17,$17,$39), + ($93,$c4,$c4,$57), ($55,$a7,$a7,$f2), ($fc,$7e,$7e,$82), ($7a,$3d,$3d,$47), + ($c8,$64,$64,$ac), ($ba,$5d,$5d,$e7), ($32,$19,$19,$2b), ($e6,$73,$73,$95), + ($c0,$60,$60,$a0), ($19,$81,$81,$98), ($9e,$4f,$4f,$d1), ($a3,$dc,$dc,$7f), + ($44,$22,$22,$66), ($54,$2a,$2a,$7e), ($3b,$90,$90,$ab), ($0b,$88,$88,$83), + ($8c,$46,$46,$ca), ($c7,$ee,$ee,$29), ($6b,$b8,$b8,$d3), ($28,$14,$14,$3c), + ($a7,$de,$de,$79), ($bc,$5e,$5e,$e2), ($16,$0b,$0b,$1d), ($ad,$db,$db,$76), + ($db,$e0,$e0,$3b), ($64,$32,$32,$56), ($74,$3a,$3a,$4e), ($14,$0a,$0a,$1e), + ($92,$49,$49,$db), ($0c,$06,$06,$0a), ($48,$24,$24,$6c), ($b8,$5c,$5c,$e4), + ($9f,$c2,$c2,$5d), ($bd,$d3,$d3,$6e), ($43,$ac,$ac,$ef), ($c4,$62,$62,$a6), + ($39,$91,$91,$a8), ($31,$95,$95,$a4), ($d3,$e4,$e4,$37), ($f2,$79,$79,$8b), + ($d5,$e7,$e7,$32), ($8b,$c8,$c8,$43), ($6e,$37,$37,$59), ($da,$6d,$6d,$b7), + ($01,$8d,$8d,$8c), ($b1,$d5,$d5,$64), ($9c,$4e,$4e,$d2), ($49,$a9,$a9,$e0), + ($d8,$6c,$6c,$b4), ($ac,$56,$56,$fa), ($f3,$f4,$f4,$07), ($cf,$ea,$ea,$25), + ($ca,$65,$65,$af), ($f4,$7a,$7a,$8e), ($47,$ae,$ae,$e9), ($10,$08,$08,$18), + ($6f,$ba,$ba,$d5), ($f0,$78,$78,$88), ($4a,$25,$25,$6f), ($5c,$2e,$2e,$72), + ($38,$1c,$1c,$24), ($57,$a6,$a6,$f1), ($73,$b4,$b4,$c7), ($97,$c6,$c6,$51), + ($cb,$e8,$e8,$23), ($a1,$dd,$dd,$7c), ($e8,$74,$74,$9c), ($3e,$1f,$1f,$21), + ($96,$4b,$4b,$dd), ($61,$bd,$bd,$dc), ($0d,$8b,$8b,$86), ($0f,$8a,$8a,$85), + ($e0,$70,$70,$90), ($7c,$3e,$3e,$42), ($71,$b5,$b5,$c4), ($cc,$66,$66,$aa), + ($90,$48,$48,$d8), ($06,$03,$03,$05), ($f7,$f6,$f6,$01), ($1c,$0e,$0e,$12), + ($c2,$61,$61,$a3), ($6a,$35,$35,$5f), ($ae,$57,$57,$f9), ($69,$b9,$b9,$d0), + ($17,$86,$86,$91), ($99,$c1,$c1,$58), ($3a,$1d,$1d,$27), ($27,$9e,$9e,$b9), + ($d9,$e1,$e1,$38), ($eb,$f8,$f8,$13), ($2b,$98,$98,$b3), ($22,$11,$11,$33), + ($d2,$69,$69,$bb), ($a9,$d9,$d9,$70), ($07,$8e,$8e,$89), ($33,$94,$94,$a7), + ($2d,$9b,$9b,$b6), ($3c,$1e,$1e,$22), ($15,$87,$87,$92), ($c9,$e9,$e9,$20), + ($87,$ce,$ce,$49), ($aa,$55,$55,$ff), ($50,$28,$28,$78), ($a5,$df,$df,$7a), + ($03,$8c,$8c,$8f), ($59,$a1,$a1,$f8), ($09,$89,$89,$80), ($1a,$0d,$0d,$17), + ($65,$bf,$bf,$da), ($d7,$e6,$e6,$31), ($84,$42,$42,$c6), ($d0,$68,$68,$b8), + ($82,$41,$41,$c3), ($29,$99,$99,$b0), ($5a,$2d,$2d,$77), ($1e,$0f,$0f,$11), + ($7b,$b0,$b0,$cb), ($a8,$54,$54,$fc), ($6d,$bb,$bb,$d6), ($2c,$16,$16,$3a)); + T2: array[0..255,0..3] of byte= ( + ($a5,$c6,$63,$63), ($84,$f8,$7c,$7c), ($99,$ee,$77,$77), ($8d,$f6,$7b,$7b), + ($0d,$ff,$f2,$f2), ($bd,$d6,$6b,$6b), ($b1,$de,$6f,$6f), ($54,$91,$c5,$c5), + ($50,$60,$30,$30), ($03,$02,$01,$01), ($a9,$ce,$67,$67), ($7d,$56,$2b,$2b), + ($19,$e7,$fe,$fe), ($62,$b5,$d7,$d7), ($e6,$4d,$ab,$ab), ($9a,$ec,$76,$76), + ($45,$8f,$ca,$ca), ($9d,$1f,$82,$82), ($40,$89,$c9,$c9), ($87,$fa,$7d,$7d), + ($15,$ef,$fa,$fa), ($eb,$b2,$59,$59), ($c9,$8e,$47,$47), ($0b,$fb,$f0,$f0), + ($ec,$41,$ad,$ad), ($67,$b3,$d4,$d4), ($fd,$5f,$a2,$a2), ($ea,$45,$af,$af), + ($bf,$23,$9c,$9c), ($f7,$53,$a4,$a4), ($96,$e4,$72,$72), ($5b,$9b,$c0,$c0), + ($c2,$75,$b7,$b7), ($1c,$e1,$fd,$fd), ($ae,$3d,$93,$93), ($6a,$4c,$26,$26), + ($5a,$6c,$36,$36), ($41,$7e,$3f,$3f), ($02,$f5,$f7,$f7), ($4f,$83,$cc,$cc), + ($5c,$68,$34,$34), ($f4,$51,$a5,$a5), ($34,$d1,$e5,$e5), ($08,$f9,$f1,$f1), + ($93,$e2,$71,$71), ($73,$ab,$d8,$d8), ($53,$62,$31,$31), ($3f,$2a,$15,$15), + ($0c,$08,$04,$04), ($52,$95,$c7,$c7), ($65,$46,$23,$23), ($5e,$9d,$c3,$c3), + ($28,$30,$18,$18), ($a1,$37,$96,$96), ($0f,$0a,$05,$05), ($b5,$2f,$9a,$9a), + ($09,$0e,$07,$07), ($36,$24,$12,$12), ($9b,$1b,$80,$80), ($3d,$df,$e2,$e2), + ($26,$cd,$eb,$eb), ($69,$4e,$27,$27), ($cd,$7f,$b2,$b2), ($9f,$ea,$75,$75), + ($1b,$12,$09,$09), ($9e,$1d,$83,$83), ($74,$58,$2c,$2c), ($2e,$34,$1a,$1a), + ($2d,$36,$1b,$1b), ($b2,$dc,$6e,$6e), ($ee,$b4,$5a,$5a), ($fb,$5b,$a0,$a0), + ($f6,$a4,$52,$52), ($4d,$76,$3b,$3b), ($61,$b7,$d6,$d6), ($ce,$7d,$b3,$b3), + ($7b,$52,$29,$29), ($3e,$dd,$e3,$e3), ($71,$5e,$2f,$2f), ($97,$13,$84,$84), + ($f5,$a6,$53,$53), ($68,$b9,$d1,$d1), ($00,$00,$00,$00), ($2c,$c1,$ed,$ed), + ($60,$40,$20,$20), ($1f,$e3,$fc,$fc), ($c8,$79,$b1,$b1), ($ed,$b6,$5b,$5b), + ($be,$d4,$6a,$6a), ($46,$8d,$cb,$cb), ($d9,$67,$be,$be), ($4b,$72,$39,$39), + ($de,$94,$4a,$4a), ($d4,$98,$4c,$4c), ($e8,$b0,$58,$58), ($4a,$85,$cf,$cf), + ($6b,$bb,$d0,$d0), ($2a,$c5,$ef,$ef), ($e5,$4f,$aa,$aa), ($16,$ed,$fb,$fb), + ($c5,$86,$43,$43), ($d7,$9a,$4d,$4d), ($55,$66,$33,$33), ($94,$11,$85,$85), + ($cf,$8a,$45,$45), ($10,$e9,$f9,$f9), ($06,$04,$02,$02), ($81,$fe,$7f,$7f), + ($f0,$a0,$50,$50), ($44,$78,$3c,$3c), ($ba,$25,$9f,$9f), ($e3,$4b,$a8,$a8), + ($f3,$a2,$51,$51), ($fe,$5d,$a3,$a3), ($c0,$80,$40,$40), ($8a,$05,$8f,$8f), + ($ad,$3f,$92,$92), ($bc,$21,$9d,$9d), ($48,$70,$38,$38), ($04,$f1,$f5,$f5), + ($df,$63,$bc,$bc), ($c1,$77,$b6,$b6), ($75,$af,$da,$da), ($63,$42,$21,$21), + ($30,$20,$10,$10), ($1a,$e5,$ff,$ff), ($0e,$fd,$f3,$f3), ($6d,$bf,$d2,$d2), + ($4c,$81,$cd,$cd), ($14,$18,$0c,$0c), ($35,$26,$13,$13), ($2f,$c3,$ec,$ec), + ($e1,$be,$5f,$5f), ($a2,$35,$97,$97), ($cc,$88,$44,$44), ($39,$2e,$17,$17), + ($57,$93,$c4,$c4), ($f2,$55,$a7,$a7), ($82,$fc,$7e,$7e), ($47,$7a,$3d,$3d), + ($ac,$c8,$64,$64), ($e7,$ba,$5d,$5d), ($2b,$32,$19,$19), ($95,$e6,$73,$73), + ($a0,$c0,$60,$60), ($98,$19,$81,$81), ($d1,$9e,$4f,$4f), ($7f,$a3,$dc,$dc), + ($66,$44,$22,$22), ($7e,$54,$2a,$2a), ($ab,$3b,$90,$90), ($83,$0b,$88,$88), + ($ca,$8c,$46,$46), ($29,$c7,$ee,$ee), ($d3,$6b,$b8,$b8), ($3c,$28,$14,$14), + ($79,$a7,$de,$de), ($e2,$bc,$5e,$5e), ($1d,$16,$0b,$0b), ($76,$ad,$db,$db), + ($3b,$db,$e0,$e0), ($56,$64,$32,$32), ($4e,$74,$3a,$3a), ($1e,$14,$0a,$0a), + ($db,$92,$49,$49), ($0a,$0c,$06,$06), ($6c,$48,$24,$24), ($e4,$b8,$5c,$5c), + ($5d,$9f,$c2,$c2), ($6e,$bd,$d3,$d3), ($ef,$43,$ac,$ac), ($a6,$c4,$62,$62), + ($a8,$39,$91,$91), ($a4,$31,$95,$95), ($37,$d3,$e4,$e4), ($8b,$f2,$79,$79), + ($32,$d5,$e7,$e7), ($43,$8b,$c8,$c8), ($59,$6e,$37,$37), ($b7,$da,$6d,$6d), + ($8c,$01,$8d,$8d), ($64,$b1,$d5,$d5), ($d2,$9c,$4e,$4e), ($e0,$49,$a9,$a9), + ($b4,$d8,$6c,$6c), ($fa,$ac,$56,$56), ($07,$f3,$f4,$f4), ($25,$cf,$ea,$ea), + ($af,$ca,$65,$65), ($8e,$f4,$7a,$7a), ($e9,$47,$ae,$ae), ($18,$10,$08,$08), + ($d5,$6f,$ba,$ba), ($88,$f0,$78,$78), ($6f,$4a,$25,$25), ($72,$5c,$2e,$2e), + ($24,$38,$1c,$1c), ($f1,$57,$a6,$a6), ($c7,$73,$b4,$b4), ($51,$97,$c6,$c6), + ($23,$cb,$e8,$e8), ($7c,$a1,$dd,$dd), ($9c,$e8,$74,$74), ($21,$3e,$1f,$1f), + ($dd,$96,$4b,$4b), ($dc,$61,$bd,$bd), ($86,$0d,$8b,$8b), ($85,$0f,$8a,$8a), + ($90,$e0,$70,$70), ($42,$7c,$3e,$3e), ($c4,$71,$b5,$b5), ($aa,$cc,$66,$66), + ($d8,$90,$48,$48), ($05,$06,$03,$03), ($01,$f7,$f6,$f6), ($12,$1c,$0e,$0e), + ($a3,$c2,$61,$61), ($5f,$6a,$35,$35), ($f9,$ae,$57,$57), ($d0,$69,$b9,$b9), + ($91,$17,$86,$86), ($58,$99,$c1,$c1), ($27,$3a,$1d,$1d), ($b9,$27,$9e,$9e), + ($38,$d9,$e1,$e1), ($13,$eb,$f8,$f8), ($b3,$2b,$98,$98), ($33,$22,$11,$11), + ($bb,$d2,$69,$69), ($70,$a9,$d9,$d9), ($89,$07,$8e,$8e), ($a7,$33,$94,$94), + ($b6,$2d,$9b,$9b), ($22,$3c,$1e,$1e), ($92,$15,$87,$87), ($20,$c9,$e9,$e9), + ($49,$87,$ce,$ce), ($ff,$aa,$55,$55), ($78,$50,$28,$28), ($7a,$a5,$df,$df), + ($8f,$03,$8c,$8c), ($f8,$59,$a1,$a1), ($80,$09,$89,$89), ($17,$1a,$0d,$0d), + ($da,$65,$bf,$bf), ($31,$d7,$e6,$e6), ($c6,$84,$42,$42), ($b8,$d0,$68,$68), + ($c3,$82,$41,$41), ($b0,$29,$99,$99), ($77,$5a,$2d,$2d), ($11,$1e,$0f,$0f), + ($cb,$7b,$b0,$b0), ($fc,$a8,$54,$54), ($d6,$6d,$bb,$bb), ($3a,$2c,$16,$16)); + T3: array[0..255,0..3] of byte= ( + ($63,$a5,$c6,$63), ($7c,$84,$f8,$7c), ($77,$99,$ee,$77), ($7b,$8d,$f6,$7b), + ($f2,$0d,$ff,$f2), ($6b,$bd,$d6,$6b), ($6f,$b1,$de,$6f), ($c5,$54,$91,$c5), + ($30,$50,$60,$30), ($01,$03,$02,$01), ($67,$a9,$ce,$67), ($2b,$7d,$56,$2b), + ($fe,$19,$e7,$fe), ($d7,$62,$b5,$d7), ($ab,$e6,$4d,$ab), ($76,$9a,$ec,$76), + ($ca,$45,$8f,$ca), ($82,$9d,$1f,$82), ($c9,$40,$89,$c9), ($7d,$87,$fa,$7d), + ($fa,$15,$ef,$fa), ($59,$eb,$b2,$59), ($47,$c9,$8e,$47), ($f0,$0b,$fb,$f0), + ($ad,$ec,$41,$ad), ($d4,$67,$b3,$d4), ($a2,$fd,$5f,$a2), ($af,$ea,$45,$af), + ($9c,$bf,$23,$9c), ($a4,$f7,$53,$a4), ($72,$96,$e4,$72), ($c0,$5b,$9b,$c0), + ($b7,$c2,$75,$b7), ($fd,$1c,$e1,$fd), ($93,$ae,$3d,$93), ($26,$6a,$4c,$26), + ($36,$5a,$6c,$36), ($3f,$41,$7e,$3f), ($f7,$02,$f5,$f7), ($cc,$4f,$83,$cc), + ($34,$5c,$68,$34), ($a5,$f4,$51,$a5), ($e5,$34,$d1,$e5), ($f1,$08,$f9,$f1), + ($71,$93,$e2,$71), ($d8,$73,$ab,$d8), ($31,$53,$62,$31), ($15,$3f,$2a,$15), + ($04,$0c,$08,$04), ($c7,$52,$95,$c7), ($23,$65,$46,$23), ($c3,$5e,$9d,$c3), + ($18,$28,$30,$18), ($96,$a1,$37,$96), ($05,$0f,$0a,$05), ($9a,$b5,$2f,$9a), + ($07,$09,$0e,$07), ($12,$36,$24,$12), ($80,$9b,$1b,$80), ($e2,$3d,$df,$e2), + ($eb,$26,$cd,$eb), ($27,$69,$4e,$27), ($b2,$cd,$7f,$b2), ($75,$9f,$ea,$75), + ($09,$1b,$12,$09), ($83,$9e,$1d,$83), ($2c,$74,$58,$2c), ($1a,$2e,$34,$1a), + ($1b,$2d,$36,$1b), ($6e,$b2,$dc,$6e), ($5a,$ee,$b4,$5a), ($a0,$fb,$5b,$a0), + ($52,$f6,$a4,$52), ($3b,$4d,$76,$3b), ($d6,$61,$b7,$d6), ($b3,$ce,$7d,$b3), + ($29,$7b,$52,$29), ($e3,$3e,$dd,$e3), ($2f,$71,$5e,$2f), ($84,$97,$13,$84), + ($53,$f5,$a6,$53), ($d1,$68,$b9,$d1), ($00,$00,$00,$00), ($ed,$2c,$c1,$ed), + ($20,$60,$40,$20), ($fc,$1f,$e3,$fc), ($b1,$c8,$79,$b1), ($5b,$ed,$b6,$5b), + ($6a,$be,$d4,$6a), ($cb,$46,$8d,$cb), ($be,$d9,$67,$be), ($39,$4b,$72,$39), + ($4a,$de,$94,$4a), ($4c,$d4,$98,$4c), ($58,$e8,$b0,$58), ($cf,$4a,$85,$cf), + ($d0,$6b,$bb,$d0), ($ef,$2a,$c5,$ef), ($aa,$e5,$4f,$aa), ($fb,$16,$ed,$fb), + ($43,$c5,$86,$43), ($4d,$d7,$9a,$4d), ($33,$55,$66,$33), ($85,$94,$11,$85), + ($45,$cf,$8a,$45), ($f9,$10,$e9,$f9), ($02,$06,$04,$02), ($7f,$81,$fe,$7f), + ($50,$f0,$a0,$50), ($3c,$44,$78,$3c), ($9f,$ba,$25,$9f), ($a8,$e3,$4b,$a8), + ($51,$f3,$a2,$51), ($a3,$fe,$5d,$a3), ($40,$c0,$80,$40), ($8f,$8a,$05,$8f), + ($92,$ad,$3f,$92), ($9d,$bc,$21,$9d), ($38,$48,$70,$38), ($f5,$04,$f1,$f5), + ($bc,$df,$63,$bc), ($b6,$c1,$77,$b6), ($da,$75,$af,$da), ($21,$63,$42,$21), + ($10,$30,$20,$10), ($ff,$1a,$e5,$ff), ($f3,$0e,$fd,$f3), ($d2,$6d,$bf,$d2), + ($cd,$4c,$81,$cd), ($0c,$14,$18,$0c), ($13,$35,$26,$13), ($ec,$2f,$c3,$ec), + ($5f,$e1,$be,$5f), ($97,$a2,$35,$97), ($44,$cc,$88,$44), ($17,$39,$2e,$17), + ($c4,$57,$93,$c4), ($a7,$f2,$55,$a7), ($7e,$82,$fc,$7e), ($3d,$47,$7a,$3d), + ($64,$ac,$c8,$64), ($5d,$e7,$ba,$5d), ($19,$2b,$32,$19), ($73,$95,$e6,$73), + ($60,$a0,$c0,$60), ($81,$98,$19,$81), ($4f,$d1,$9e,$4f), ($dc,$7f,$a3,$dc), + ($22,$66,$44,$22), ($2a,$7e,$54,$2a), ($90,$ab,$3b,$90), ($88,$83,$0b,$88), + ($46,$ca,$8c,$46), ($ee,$29,$c7,$ee), ($b8,$d3,$6b,$b8), ($14,$3c,$28,$14), + ($de,$79,$a7,$de), ($5e,$e2,$bc,$5e), ($0b,$1d,$16,$0b), ($db,$76,$ad,$db), + ($e0,$3b,$db,$e0), ($32,$56,$64,$32), ($3a,$4e,$74,$3a), ($0a,$1e,$14,$0a), + ($49,$db,$92,$49), ($06,$0a,$0c,$06), ($24,$6c,$48,$24), ($5c,$e4,$b8,$5c), + ($c2,$5d,$9f,$c2), ($d3,$6e,$bd,$d3), ($ac,$ef,$43,$ac), ($62,$a6,$c4,$62), + ($91,$a8,$39,$91), ($95,$a4,$31,$95), ($e4,$37,$d3,$e4), ($79,$8b,$f2,$79), + ($e7,$32,$d5,$e7), ($c8,$43,$8b,$c8), ($37,$59,$6e,$37), ($6d,$b7,$da,$6d), + ($8d,$8c,$01,$8d), ($d5,$64,$b1,$d5), ($4e,$d2,$9c,$4e), ($a9,$e0,$49,$a9), + ($6c,$b4,$d8,$6c), ($56,$fa,$ac,$56), ($f4,$07,$f3,$f4), ($ea,$25,$cf,$ea), + ($65,$af,$ca,$65), ($7a,$8e,$f4,$7a), ($ae,$e9,$47,$ae), ($08,$18,$10,$08), + ($ba,$d5,$6f,$ba), ($78,$88,$f0,$78), ($25,$6f,$4a,$25), ($2e,$72,$5c,$2e), + ($1c,$24,$38,$1c), ($a6,$f1,$57,$a6), ($b4,$c7,$73,$b4), ($c6,$51,$97,$c6), + ($e8,$23,$cb,$e8), ($dd,$7c,$a1,$dd), ($74,$9c,$e8,$74), ($1f,$21,$3e,$1f), + ($4b,$dd,$96,$4b), ($bd,$dc,$61,$bd), ($8b,$86,$0d,$8b), ($8a,$85,$0f,$8a), + ($70,$90,$e0,$70), ($3e,$42,$7c,$3e), ($b5,$c4,$71,$b5), ($66,$aa,$cc,$66), + ($48,$d8,$90,$48), ($03,$05,$06,$03), ($f6,$01,$f7,$f6), ($0e,$12,$1c,$0e), + ($61,$a3,$c2,$61), ($35,$5f,$6a,$35), ($57,$f9,$ae,$57), ($b9,$d0,$69,$b9), + ($86,$91,$17,$86), ($c1,$58,$99,$c1), ($1d,$27,$3a,$1d), ($9e,$b9,$27,$9e), + ($e1,$38,$d9,$e1), ($f8,$13,$eb,$f8), ($98,$b3,$2b,$98), ($11,$33,$22,$11), + ($69,$bb,$d2,$69), ($d9,$70,$a9,$d9), ($8e,$89,$07,$8e), ($94,$a7,$33,$94), + ($9b,$b6,$2d,$9b), ($1e,$22,$3c,$1e), ($87,$92,$15,$87), ($e9,$20,$c9,$e9), + ($ce,$49,$87,$ce), ($55,$ff,$aa,$55), ($28,$78,$50,$28), ($df,$7a,$a5,$df), + ($8c,$8f,$03,$8c), ($a1,$f8,$59,$a1), ($89,$80,$09,$89), ($0d,$17,$1a,$0d), + ($bf,$da,$65,$bf), ($e6,$31,$d7,$e6), ($42,$c6,$84,$42), ($68,$b8,$d0,$68), + ($41,$c3,$82,$41), ($99,$b0,$29,$99), ($2d,$77,$5a,$2d), ($0f,$11,$1e,$0f), + ($b0,$cb,$7b,$b0), ($54,$fc,$a8,$54), ($bb,$d6,$6d,$bb), ($16,$3a,$2c,$16)); + T4: array[0..255,0..3] of byte= ( + ($63,$63,$a5,$c6), ($7c,$7c,$84,$f8), ($77,$77,$99,$ee), ($7b,$7b,$8d,$f6), + ($f2,$f2,$0d,$ff), ($6b,$6b,$bd,$d6), ($6f,$6f,$b1,$de), ($c5,$c5,$54,$91), + ($30,$30,$50,$60), ($01,$01,$03,$02), ($67,$67,$a9,$ce), ($2b,$2b,$7d,$56), + ($fe,$fe,$19,$e7), ($d7,$d7,$62,$b5), ($ab,$ab,$e6,$4d), ($76,$76,$9a,$ec), + ($ca,$ca,$45,$8f), ($82,$82,$9d,$1f), ($c9,$c9,$40,$89), ($7d,$7d,$87,$fa), + ($fa,$fa,$15,$ef), ($59,$59,$eb,$b2), ($47,$47,$c9,$8e), ($f0,$f0,$0b,$fb), + ($ad,$ad,$ec,$41), ($d4,$d4,$67,$b3), ($a2,$a2,$fd,$5f), ($af,$af,$ea,$45), + ($9c,$9c,$bf,$23), ($a4,$a4,$f7,$53), ($72,$72,$96,$e4), ($c0,$c0,$5b,$9b), + ($b7,$b7,$c2,$75), ($fd,$fd,$1c,$e1), ($93,$93,$ae,$3d), ($26,$26,$6a,$4c), + ($36,$36,$5a,$6c), ($3f,$3f,$41,$7e), ($f7,$f7,$02,$f5), ($cc,$cc,$4f,$83), + ($34,$34,$5c,$68), ($a5,$a5,$f4,$51), ($e5,$e5,$34,$d1), ($f1,$f1,$08,$f9), + ($71,$71,$93,$e2), ($d8,$d8,$73,$ab), ($31,$31,$53,$62), ($15,$15,$3f,$2a), + ($04,$04,$0c,$08), ($c7,$c7,$52,$95), ($23,$23,$65,$46), ($c3,$c3,$5e,$9d), + ($18,$18,$28,$30), ($96,$96,$a1,$37), ($05,$05,$0f,$0a), ($9a,$9a,$b5,$2f), + ($07,$07,$09,$0e), ($12,$12,$36,$24), ($80,$80,$9b,$1b), ($e2,$e2,$3d,$df), + ($eb,$eb,$26,$cd), ($27,$27,$69,$4e), ($b2,$b2,$cd,$7f), ($75,$75,$9f,$ea), + ($09,$09,$1b,$12), ($83,$83,$9e,$1d), ($2c,$2c,$74,$58), ($1a,$1a,$2e,$34), + ($1b,$1b,$2d,$36), ($6e,$6e,$b2,$dc), ($5a,$5a,$ee,$b4), ($a0,$a0,$fb,$5b), + ($52,$52,$f6,$a4), ($3b,$3b,$4d,$76), ($d6,$d6,$61,$b7), ($b3,$b3,$ce,$7d), + ($29,$29,$7b,$52), ($e3,$e3,$3e,$dd), ($2f,$2f,$71,$5e), ($84,$84,$97,$13), + ($53,$53,$f5,$a6), ($d1,$d1,$68,$b9), ($00,$00,$00,$00), ($ed,$ed,$2c,$c1), + ($20,$20,$60,$40), ($fc,$fc,$1f,$e3), ($b1,$b1,$c8,$79), ($5b,$5b,$ed,$b6), + ($6a,$6a,$be,$d4), ($cb,$cb,$46,$8d), ($be,$be,$d9,$67), ($39,$39,$4b,$72), + ($4a,$4a,$de,$94), ($4c,$4c,$d4,$98), ($58,$58,$e8,$b0), ($cf,$cf,$4a,$85), + ($d0,$d0,$6b,$bb), ($ef,$ef,$2a,$c5), ($aa,$aa,$e5,$4f), ($fb,$fb,$16,$ed), + ($43,$43,$c5,$86), ($4d,$4d,$d7,$9a), ($33,$33,$55,$66), ($85,$85,$94,$11), + ($45,$45,$cf,$8a), ($f9,$f9,$10,$e9), ($02,$02,$06,$04), ($7f,$7f,$81,$fe), + ($50,$50,$f0,$a0), ($3c,$3c,$44,$78), ($9f,$9f,$ba,$25), ($a8,$a8,$e3,$4b), + ($51,$51,$f3,$a2), ($a3,$a3,$fe,$5d), ($40,$40,$c0,$80), ($8f,$8f,$8a,$05), + ($92,$92,$ad,$3f), ($9d,$9d,$bc,$21), ($38,$38,$48,$70), ($f5,$f5,$04,$f1), + ($bc,$bc,$df,$63), ($b6,$b6,$c1,$77), ($da,$da,$75,$af), ($21,$21,$63,$42), + ($10,$10,$30,$20), ($ff,$ff,$1a,$e5), ($f3,$f3,$0e,$fd), ($d2,$d2,$6d,$bf), + ($cd,$cd,$4c,$81), ($0c,$0c,$14,$18), ($13,$13,$35,$26), ($ec,$ec,$2f,$c3), + ($5f,$5f,$e1,$be), ($97,$97,$a2,$35), ($44,$44,$cc,$88), ($17,$17,$39,$2e), + ($c4,$c4,$57,$93), ($a7,$a7,$f2,$55), ($7e,$7e,$82,$fc), ($3d,$3d,$47,$7a), + ($64,$64,$ac,$c8), ($5d,$5d,$e7,$ba), ($19,$19,$2b,$32), ($73,$73,$95,$e6), + ($60,$60,$a0,$c0), ($81,$81,$98,$19), ($4f,$4f,$d1,$9e), ($dc,$dc,$7f,$a3), + ($22,$22,$66,$44), ($2a,$2a,$7e,$54), ($90,$90,$ab,$3b), ($88,$88,$83,$0b), + ($46,$46,$ca,$8c), ($ee,$ee,$29,$c7), ($b8,$b8,$d3,$6b), ($14,$14,$3c,$28), + ($de,$de,$79,$a7), ($5e,$5e,$e2,$bc), ($0b,$0b,$1d,$16), ($db,$db,$76,$ad), + ($e0,$e0,$3b,$db), ($32,$32,$56,$64), ($3a,$3a,$4e,$74), ($0a,$0a,$1e,$14), + ($49,$49,$db,$92), ($06,$06,$0a,$0c), ($24,$24,$6c,$48), ($5c,$5c,$e4,$b8), + ($c2,$c2,$5d,$9f), ($d3,$d3,$6e,$bd), ($ac,$ac,$ef,$43), ($62,$62,$a6,$c4), + ($91,$91,$a8,$39), ($95,$95,$a4,$31), ($e4,$e4,$37,$d3), ($79,$79,$8b,$f2), + ($e7,$e7,$32,$d5), ($c8,$c8,$43,$8b), ($37,$37,$59,$6e), ($6d,$6d,$b7,$da), + ($8d,$8d,$8c,$01), ($d5,$d5,$64,$b1), ($4e,$4e,$d2,$9c), ($a9,$a9,$e0,$49), + ($6c,$6c,$b4,$d8), ($56,$56,$fa,$ac), ($f4,$f4,$07,$f3), ($ea,$ea,$25,$cf), + ($65,$65,$af,$ca), ($7a,$7a,$8e,$f4), ($ae,$ae,$e9,$47), ($08,$08,$18,$10), + ($ba,$ba,$d5,$6f), ($78,$78,$88,$f0), ($25,$25,$6f,$4a), ($2e,$2e,$72,$5c), + ($1c,$1c,$24,$38), ($a6,$a6,$f1,$57), ($b4,$b4,$c7,$73), ($c6,$c6,$51,$97), + ($e8,$e8,$23,$cb), ($dd,$dd,$7c,$a1), ($74,$74,$9c,$e8), ($1f,$1f,$21,$3e), + ($4b,$4b,$dd,$96), ($bd,$bd,$dc,$61), ($8b,$8b,$86,$0d), ($8a,$8a,$85,$0f), + ($70,$70,$90,$e0), ($3e,$3e,$42,$7c), ($b5,$b5,$c4,$71), ($66,$66,$aa,$cc), + ($48,$48,$d8,$90), ($03,$03,$05,$06), ($f6,$f6,$01,$f7), ($0e,$0e,$12,$1c), + ($61,$61,$a3,$c2), ($35,$35,$5f,$6a), ($57,$57,$f9,$ae), ($b9,$b9,$d0,$69), + ($86,$86,$91,$17), ($c1,$c1,$58,$99), ($1d,$1d,$27,$3a), ($9e,$9e,$b9,$27), + ($e1,$e1,$38,$d9), ($f8,$f8,$13,$eb), ($98,$98,$b3,$2b), ($11,$11,$33,$22), + ($69,$69,$bb,$d2), ($d9,$d9,$70,$a9), ($8e,$8e,$89,$07), ($94,$94,$a7,$33), + ($9b,$9b,$b6,$2d), ($1e,$1e,$22,$3c), ($87,$87,$92,$15), ($e9,$e9,$20,$c9), + ($ce,$ce,$49,$87), ($55,$55,$ff,$aa), ($28,$28,$78,$50), ($df,$df,$7a,$a5), + ($8c,$8c,$8f,$03), ($a1,$a1,$f8,$59), ($89,$89,$80,$09), ($0d,$0d,$17,$1a), + ($bf,$bf,$da,$65), ($e6,$e6,$31,$d7), ($42,$42,$c6,$84), ($68,$68,$b8,$d0), + ($41,$41,$c3,$82), ($99,$99,$b0,$29), ($2d,$2d,$77,$5a), ($0f,$0f,$11,$1e), + ($b0,$b0,$cb,$7b), ($54,$54,$fc,$a8), ($bb,$bb,$d6,$6d), ($16,$16,$3a,$2c)); + T5: array[0..255,0..3] of byte= ( + ($51,$f4,$a7,$50), ($7e,$41,$65,$53), ($1a,$17,$a4,$c3), ($3a,$27,$5e,$96), + ($3b,$ab,$6b,$cb), ($1f,$9d,$45,$f1), ($ac,$fa,$58,$ab), ($4b,$e3,$03,$93), + ($20,$30,$fa,$55), ($ad,$76,$6d,$f6), ($88,$cc,$76,$91), ($f5,$02,$4c,$25), + ($4f,$e5,$d7,$fc), ($c5,$2a,$cb,$d7), ($26,$35,$44,$80), ($b5,$62,$a3,$8f), + ($de,$b1,$5a,$49), ($25,$ba,$1b,$67), ($45,$ea,$0e,$98), ($5d,$fe,$c0,$e1), + ($c3,$2f,$75,$02), ($81,$4c,$f0,$12), ($8d,$46,$97,$a3), ($6b,$d3,$f9,$c6), + ($03,$8f,$5f,$e7), ($15,$92,$9c,$95), ($bf,$6d,$7a,$eb), ($95,$52,$59,$da), + ($d4,$be,$83,$2d), ($58,$74,$21,$d3), ($49,$e0,$69,$29), ($8e,$c9,$c8,$44), + ($75,$c2,$89,$6a), ($f4,$8e,$79,$78), ($99,$58,$3e,$6b), ($27,$b9,$71,$dd), + ($be,$e1,$4f,$b6), ($f0,$88,$ad,$17), ($c9,$20,$ac,$66), ($7d,$ce,$3a,$b4), + ($63,$df,$4a,$18), ($e5,$1a,$31,$82), ($97,$51,$33,$60), ($62,$53,$7f,$45), + ($b1,$64,$77,$e0), ($bb,$6b,$ae,$84), ($fe,$81,$a0,$1c), ($f9,$08,$2b,$94), + ($70,$48,$68,$58), ($8f,$45,$fd,$19), ($94,$de,$6c,$87), ($52,$7b,$f8,$b7), + ($ab,$73,$d3,$23), ($72,$4b,$02,$e2), ($e3,$1f,$8f,$57), ($66,$55,$ab,$2a), + ($b2,$eb,$28,$07), ($2f,$b5,$c2,$03), ($86,$c5,$7b,$9a), ($d3,$37,$08,$a5), + ($30,$28,$87,$f2), ($23,$bf,$a5,$b2), ($02,$03,$6a,$ba), ($ed,$16,$82,$5c), + ($8a,$cf,$1c,$2b), ($a7,$79,$b4,$92), ($f3,$07,$f2,$f0), ($4e,$69,$e2,$a1), + ($65,$da,$f4,$cd), ($06,$05,$be,$d5), ($d1,$34,$62,$1f), ($c4,$a6,$fe,$8a), + ($34,$2e,$53,$9d), ($a2,$f3,$55,$a0), ($05,$8a,$e1,$32), ($a4,$f6,$eb,$75), + ($0b,$83,$ec,$39), ($40,$60,$ef,$aa), ($5e,$71,$9f,$06), ($bd,$6e,$10,$51), + ($3e,$21,$8a,$f9), ($96,$dd,$06,$3d), ($dd,$3e,$05,$ae), ($4d,$e6,$bd,$46), + ($91,$54,$8d,$b5), ($71,$c4,$5d,$05), ($04,$06,$d4,$6f), ($60,$50,$15,$ff), + ($19,$98,$fb,$24), ($d6,$bd,$e9,$97), ($89,$40,$43,$cc), ($67,$d9,$9e,$77), + ($b0,$e8,$42,$bd), ($07,$89,$8b,$88), ($e7,$19,$5b,$38), ($79,$c8,$ee,$db), + ($a1,$7c,$0a,$47), ($7c,$42,$0f,$e9), ($f8,$84,$1e,$c9), ($00,$00,$00,$00), + ($09,$80,$86,$83), ($32,$2b,$ed,$48), ($1e,$11,$70,$ac), ($6c,$5a,$72,$4e), + ($fd,$0e,$ff,$fb), ($0f,$85,$38,$56), ($3d,$ae,$d5,$1e), ($36,$2d,$39,$27), + ($0a,$0f,$d9,$64), ($68,$5c,$a6,$21), ($9b,$5b,$54,$d1), ($24,$36,$2e,$3a), + ($0c,$0a,$67,$b1), ($93,$57,$e7,$0f), ($b4,$ee,$96,$d2), ($1b,$9b,$91,$9e), + ($80,$c0,$c5,$4f), ($61,$dc,$20,$a2), ($5a,$77,$4b,$69), ($1c,$12,$1a,$16), + ($e2,$93,$ba,$0a), ($c0,$a0,$2a,$e5), ($3c,$22,$e0,$43), ($12,$1b,$17,$1d), + ($0e,$09,$0d,$0b), ($f2,$8b,$c7,$ad), ($2d,$b6,$a8,$b9), ($14,$1e,$a9,$c8), + ($57,$f1,$19,$85), ($af,$75,$07,$4c), ($ee,$99,$dd,$bb), ($a3,$7f,$60,$fd), + ($f7,$01,$26,$9f), ($5c,$72,$f5,$bc), ($44,$66,$3b,$c5), ($5b,$fb,$7e,$34), + ($8b,$43,$29,$76), ($cb,$23,$c6,$dc), ($b6,$ed,$fc,$68), ($b8,$e4,$f1,$63), + ($d7,$31,$dc,$ca), ($42,$63,$85,$10), ($13,$97,$22,$40), ($84,$c6,$11,$20), + ($85,$4a,$24,$7d), ($d2,$bb,$3d,$f8), ($ae,$f9,$32,$11), ($c7,$29,$a1,$6d), + ($1d,$9e,$2f,$4b), ($dc,$b2,$30,$f3), ($0d,$86,$52,$ec), ($77,$c1,$e3,$d0), + ($2b,$b3,$16,$6c), ($a9,$70,$b9,$99), ($11,$94,$48,$fa), ($47,$e9,$64,$22), + ($a8,$fc,$8c,$c4), ($a0,$f0,$3f,$1a), ($56,$7d,$2c,$d8), ($22,$33,$90,$ef), + ($87,$49,$4e,$c7), ($d9,$38,$d1,$c1), ($8c,$ca,$a2,$fe), ($98,$d4,$0b,$36), + ($a6,$f5,$81,$cf), ($a5,$7a,$de,$28), ($da,$b7,$8e,$26), ($3f,$ad,$bf,$a4), + ($2c,$3a,$9d,$e4), ($50,$78,$92,$0d), ($6a,$5f,$cc,$9b), ($54,$7e,$46,$62), + ($f6,$8d,$13,$c2), ($90,$d8,$b8,$e8), ($2e,$39,$f7,$5e), ($82,$c3,$af,$f5), + ($9f,$5d,$80,$be), ($69,$d0,$93,$7c), ($6f,$d5,$2d,$a9), ($cf,$25,$12,$b3), + ($c8,$ac,$99,$3b), ($10,$18,$7d,$a7), ($e8,$9c,$63,$6e), ($db,$3b,$bb,$7b), + ($cd,$26,$78,$09), ($6e,$59,$18,$f4), ($ec,$9a,$b7,$01), ($83,$4f,$9a,$a8), + ($e6,$95,$6e,$65), ($aa,$ff,$e6,$7e), ($21,$bc,$cf,$08), ($ef,$15,$e8,$e6), + ($ba,$e7,$9b,$d9), ($4a,$6f,$36,$ce), ($ea,$9f,$09,$d4), ($29,$b0,$7c,$d6), + ($31,$a4,$b2,$af), ($2a,$3f,$23,$31), ($c6,$a5,$94,$30), ($35,$a2,$66,$c0), + ($74,$4e,$bc,$37), ($fc,$82,$ca,$a6), ($e0,$90,$d0,$b0), ($33,$a7,$d8,$15), + ($f1,$04,$98,$4a), ($41,$ec,$da,$f7), ($7f,$cd,$50,$0e), ($17,$91,$f6,$2f), + ($76,$4d,$d6,$8d), ($43,$ef,$b0,$4d), ($cc,$aa,$4d,$54), ($e4,$96,$04,$df), + ($9e,$d1,$b5,$e3), ($4c,$6a,$88,$1b), ($c1,$2c,$1f,$b8), ($46,$65,$51,$7f), + ($9d,$5e,$ea,$04), ($01,$8c,$35,$5d), ($fa,$87,$74,$73), ($fb,$0b,$41,$2e), + ($b3,$67,$1d,$5a), ($92,$db,$d2,$52), ($e9,$10,$56,$33), ($6d,$d6,$47,$13), + ($9a,$d7,$61,$8c), ($37,$a1,$0c,$7a), ($59,$f8,$14,$8e), ($eb,$13,$3c,$89), + ($ce,$a9,$27,$ee), ($b7,$61,$c9,$35), ($e1,$1c,$e5,$ed), ($7a,$47,$b1,$3c), + ($9c,$d2,$df,$59), ($55,$f2,$73,$3f), ($18,$14,$ce,$79), ($73,$c7,$37,$bf), + ($53,$f7,$cd,$ea), ($5f,$fd,$aa,$5b), ($df,$3d,$6f,$14), ($78,$44,$db,$86), + ($ca,$af,$f3,$81), ($b9,$68,$c4,$3e), ($38,$24,$34,$2c), ($c2,$a3,$40,$5f), + ($16,$1d,$c3,$72), ($bc,$e2,$25,$0c), ($28,$3c,$49,$8b), ($ff,$0d,$95,$41), + ($39,$a8,$01,$71), ($08,$0c,$b3,$de), ($d8,$b4,$e4,$9c), ($64,$56,$c1,$90), + ($7b,$cb,$84,$61), ($d5,$32,$b6,$70), ($48,$6c,$5c,$74), ($d0,$b8,$57,$42)); + T6: array[0..255,0..3] of byte= ( + ($50,$51,$f4,$a7), ($53,$7e,$41,$65), ($c3,$1a,$17,$a4), ($96,$3a,$27,$5e), + ($cb,$3b,$ab,$6b), ($f1,$1f,$9d,$45), ($ab,$ac,$fa,$58), ($93,$4b,$e3,$03), + ($55,$20,$30,$fa), ($f6,$ad,$76,$6d), ($91,$88,$cc,$76), ($25,$f5,$02,$4c), + ($fc,$4f,$e5,$d7), ($d7,$c5,$2a,$cb), ($80,$26,$35,$44), ($8f,$b5,$62,$a3), + ($49,$de,$b1,$5a), ($67,$25,$ba,$1b), ($98,$45,$ea,$0e), ($e1,$5d,$fe,$c0), + ($02,$c3,$2f,$75), ($12,$81,$4c,$f0), ($a3,$8d,$46,$97), ($c6,$6b,$d3,$f9), + ($e7,$03,$8f,$5f), ($95,$15,$92,$9c), ($eb,$bf,$6d,$7a), ($da,$95,$52,$59), + ($2d,$d4,$be,$83), ($d3,$58,$74,$21), ($29,$49,$e0,$69), ($44,$8e,$c9,$c8), + ($6a,$75,$c2,$89), ($78,$f4,$8e,$79), ($6b,$99,$58,$3e), ($dd,$27,$b9,$71), + ($b6,$be,$e1,$4f), ($17,$f0,$88,$ad), ($66,$c9,$20,$ac), ($b4,$7d,$ce,$3a), + ($18,$63,$df,$4a), ($82,$e5,$1a,$31), ($60,$97,$51,$33), ($45,$62,$53,$7f), + ($e0,$b1,$64,$77), ($84,$bb,$6b,$ae), ($1c,$fe,$81,$a0), ($94,$f9,$08,$2b), + ($58,$70,$48,$68), ($19,$8f,$45,$fd), ($87,$94,$de,$6c), ($b7,$52,$7b,$f8), + ($23,$ab,$73,$d3), ($e2,$72,$4b,$02), ($57,$e3,$1f,$8f), ($2a,$66,$55,$ab), + ($07,$b2,$eb,$28), ($03,$2f,$b5,$c2), ($9a,$86,$c5,$7b), ($a5,$d3,$37,$08), + ($f2,$30,$28,$87), ($b2,$23,$bf,$a5), ($ba,$02,$03,$6a), ($5c,$ed,$16,$82), + ($2b,$8a,$cf,$1c), ($92,$a7,$79,$b4), ($f0,$f3,$07,$f2), ($a1,$4e,$69,$e2), + ($cd,$65,$da,$f4), ($d5,$06,$05,$be), ($1f,$d1,$34,$62), ($8a,$c4,$a6,$fe), + ($9d,$34,$2e,$53), ($a0,$a2,$f3,$55), ($32,$05,$8a,$e1), ($75,$a4,$f6,$eb), + ($39,$0b,$83,$ec), ($aa,$40,$60,$ef), ($06,$5e,$71,$9f), ($51,$bd,$6e,$10), + ($f9,$3e,$21,$8a), ($3d,$96,$dd,$06), ($ae,$dd,$3e,$05), ($46,$4d,$e6,$bd), + ($b5,$91,$54,$8d), ($05,$71,$c4,$5d), ($6f,$04,$06,$d4), ($ff,$60,$50,$15), + ($24,$19,$98,$fb), ($97,$d6,$bd,$e9), ($cc,$89,$40,$43), ($77,$67,$d9,$9e), + ($bd,$b0,$e8,$42), ($88,$07,$89,$8b), ($38,$e7,$19,$5b), ($db,$79,$c8,$ee), + ($47,$a1,$7c,$0a), ($e9,$7c,$42,$0f), ($c9,$f8,$84,$1e), ($00,$00,$00,$00), + ($83,$09,$80,$86), ($48,$32,$2b,$ed), ($ac,$1e,$11,$70), ($4e,$6c,$5a,$72), + ($fb,$fd,$0e,$ff), ($56,$0f,$85,$38), ($1e,$3d,$ae,$d5), ($27,$36,$2d,$39), + ($64,$0a,$0f,$d9), ($21,$68,$5c,$a6), ($d1,$9b,$5b,$54), ($3a,$24,$36,$2e), + ($b1,$0c,$0a,$67), ($0f,$93,$57,$e7), ($d2,$b4,$ee,$96), ($9e,$1b,$9b,$91), + ($4f,$80,$c0,$c5), ($a2,$61,$dc,$20), ($69,$5a,$77,$4b), ($16,$1c,$12,$1a), + ($0a,$e2,$93,$ba), ($e5,$c0,$a0,$2a), ($43,$3c,$22,$e0), ($1d,$12,$1b,$17), + ($0b,$0e,$09,$0d), ($ad,$f2,$8b,$c7), ($b9,$2d,$b6,$a8), ($c8,$14,$1e,$a9), + ($85,$57,$f1,$19), ($4c,$af,$75,$07), ($bb,$ee,$99,$dd), ($fd,$a3,$7f,$60), + ($9f,$f7,$01,$26), ($bc,$5c,$72,$f5), ($c5,$44,$66,$3b), ($34,$5b,$fb,$7e), + ($76,$8b,$43,$29), ($dc,$cb,$23,$c6), ($68,$b6,$ed,$fc), ($63,$b8,$e4,$f1), + ($ca,$d7,$31,$dc), ($10,$42,$63,$85), ($40,$13,$97,$22), ($20,$84,$c6,$11), + ($7d,$85,$4a,$24), ($f8,$d2,$bb,$3d), ($11,$ae,$f9,$32), ($6d,$c7,$29,$a1), + ($4b,$1d,$9e,$2f), ($f3,$dc,$b2,$30), ($ec,$0d,$86,$52), ($d0,$77,$c1,$e3), + ($6c,$2b,$b3,$16), ($99,$a9,$70,$b9), ($fa,$11,$94,$48), ($22,$47,$e9,$64), + ($c4,$a8,$fc,$8c), ($1a,$a0,$f0,$3f), ($d8,$56,$7d,$2c), ($ef,$22,$33,$90), + ($c7,$87,$49,$4e), ($c1,$d9,$38,$d1), ($fe,$8c,$ca,$a2), ($36,$98,$d4,$0b), + ($cf,$a6,$f5,$81), ($28,$a5,$7a,$de), ($26,$da,$b7,$8e), ($a4,$3f,$ad,$bf), + ($e4,$2c,$3a,$9d), ($0d,$50,$78,$92), ($9b,$6a,$5f,$cc), ($62,$54,$7e,$46), + ($c2,$f6,$8d,$13), ($e8,$90,$d8,$b8), ($5e,$2e,$39,$f7), ($f5,$82,$c3,$af), + ($be,$9f,$5d,$80), ($7c,$69,$d0,$93), ($a9,$6f,$d5,$2d), ($b3,$cf,$25,$12), + ($3b,$c8,$ac,$99), ($a7,$10,$18,$7d), ($6e,$e8,$9c,$63), ($7b,$db,$3b,$bb), + ($09,$cd,$26,$78), ($f4,$6e,$59,$18), ($01,$ec,$9a,$b7), ($a8,$83,$4f,$9a), + ($65,$e6,$95,$6e), ($7e,$aa,$ff,$e6), ($08,$21,$bc,$cf), ($e6,$ef,$15,$e8), + ($d9,$ba,$e7,$9b), ($ce,$4a,$6f,$36), ($d4,$ea,$9f,$09), ($d6,$29,$b0,$7c), + ($af,$31,$a4,$b2), ($31,$2a,$3f,$23), ($30,$c6,$a5,$94), ($c0,$35,$a2,$66), + ($37,$74,$4e,$bc), ($a6,$fc,$82,$ca), ($b0,$e0,$90,$d0), ($15,$33,$a7,$d8), + ($4a,$f1,$04,$98), ($f7,$41,$ec,$da), ($0e,$7f,$cd,$50), ($2f,$17,$91,$f6), + ($8d,$76,$4d,$d6), ($4d,$43,$ef,$b0), ($54,$cc,$aa,$4d), ($df,$e4,$96,$04), + ($e3,$9e,$d1,$b5), ($1b,$4c,$6a,$88), ($b8,$c1,$2c,$1f), ($7f,$46,$65,$51), + ($04,$9d,$5e,$ea), ($5d,$01,$8c,$35), ($73,$fa,$87,$74), ($2e,$fb,$0b,$41), + ($5a,$b3,$67,$1d), ($52,$92,$db,$d2), ($33,$e9,$10,$56), ($13,$6d,$d6,$47), + ($8c,$9a,$d7,$61), ($7a,$37,$a1,$0c), ($8e,$59,$f8,$14), ($89,$eb,$13,$3c), + ($ee,$ce,$a9,$27), ($35,$b7,$61,$c9), ($ed,$e1,$1c,$e5), ($3c,$7a,$47,$b1), + ($59,$9c,$d2,$df), ($3f,$55,$f2,$73), ($79,$18,$14,$ce), ($bf,$73,$c7,$37), + ($ea,$53,$f7,$cd), ($5b,$5f,$fd,$aa), ($14,$df,$3d,$6f), ($86,$78,$44,$db), + ($81,$ca,$af,$f3), ($3e,$b9,$68,$c4), ($2c,$38,$24,$34), ($5f,$c2,$a3,$40), + ($72,$16,$1d,$c3), ($0c,$bc,$e2,$25), ($8b,$28,$3c,$49), ($41,$ff,$0d,$95), + ($71,$39,$a8,$01), ($de,$08,$0c,$b3), ($9c,$d8,$b4,$e4), ($90,$64,$56,$c1), + ($61,$7b,$cb,$84), ($70,$d5,$32,$b6), ($74,$48,$6c,$5c), ($42,$d0,$b8,$57)); + T7: array[0..255,0..3] of byte= ( + ($a7,$50,$51,$f4), ($65,$53,$7e,$41), ($a4,$c3,$1a,$17), ($5e,$96,$3a,$27), + ($6b,$cb,$3b,$ab), ($45,$f1,$1f,$9d), ($58,$ab,$ac,$fa), ($03,$93,$4b,$e3), + ($fa,$55,$20,$30), ($6d,$f6,$ad,$76), ($76,$91,$88,$cc), ($4c,$25,$f5,$02), + ($d7,$fc,$4f,$e5), ($cb,$d7,$c5,$2a), ($44,$80,$26,$35), ($a3,$8f,$b5,$62), + ($5a,$49,$de,$b1), ($1b,$67,$25,$ba), ($0e,$98,$45,$ea), ($c0,$e1,$5d,$fe), + ($75,$02,$c3,$2f), ($f0,$12,$81,$4c), ($97,$a3,$8d,$46), ($f9,$c6,$6b,$d3), + ($5f,$e7,$03,$8f), ($9c,$95,$15,$92), ($7a,$eb,$bf,$6d), ($59,$da,$95,$52), + ($83,$2d,$d4,$be), ($21,$d3,$58,$74), ($69,$29,$49,$e0), ($c8,$44,$8e,$c9), + ($89,$6a,$75,$c2), ($79,$78,$f4,$8e), ($3e,$6b,$99,$58), ($71,$dd,$27,$b9), + ($4f,$b6,$be,$e1), ($ad,$17,$f0,$88), ($ac,$66,$c9,$20), ($3a,$b4,$7d,$ce), + ($4a,$18,$63,$df), ($31,$82,$e5,$1a), ($33,$60,$97,$51), ($7f,$45,$62,$53), + ($77,$e0,$b1,$64), ($ae,$84,$bb,$6b), ($a0,$1c,$fe,$81), ($2b,$94,$f9,$08), + ($68,$58,$70,$48), ($fd,$19,$8f,$45), ($6c,$87,$94,$de), ($f8,$b7,$52,$7b), + ($d3,$23,$ab,$73), ($02,$e2,$72,$4b), ($8f,$57,$e3,$1f), ($ab,$2a,$66,$55), + ($28,$07,$b2,$eb), ($c2,$03,$2f,$b5), ($7b,$9a,$86,$c5), ($08,$a5,$d3,$37), + ($87,$f2,$30,$28), ($a5,$b2,$23,$bf), ($6a,$ba,$02,$03), ($82,$5c,$ed,$16), + ($1c,$2b,$8a,$cf), ($b4,$92,$a7,$79), ($f2,$f0,$f3,$07), ($e2,$a1,$4e,$69), + ($f4,$cd,$65,$da), ($be,$d5,$06,$05), ($62,$1f,$d1,$34), ($fe,$8a,$c4,$a6), + ($53,$9d,$34,$2e), ($55,$a0,$a2,$f3), ($e1,$32,$05,$8a), ($eb,$75,$a4,$f6), + ($ec,$39,$0b,$83), ($ef,$aa,$40,$60), ($9f,$06,$5e,$71), ($10,$51,$bd,$6e), + ($8a,$f9,$3e,$21), ($06,$3d,$96,$dd), ($05,$ae,$dd,$3e), ($bd,$46,$4d,$e6), + ($8d,$b5,$91,$54), ($5d,$05,$71,$c4), ($d4,$6f,$04,$06), ($15,$ff,$60,$50), + ($fb,$24,$19,$98), ($e9,$97,$d6,$bd), ($43,$cc,$89,$40), ($9e,$77,$67,$d9), + ($42,$bd,$b0,$e8), ($8b,$88,$07,$89), ($5b,$38,$e7,$19), ($ee,$db,$79,$c8), + ($0a,$47,$a1,$7c), ($0f,$e9,$7c,$42), ($1e,$c9,$f8,$84), ($00,$00,$00,$00), + ($86,$83,$09,$80), ($ed,$48,$32,$2b), ($70,$ac,$1e,$11), ($72,$4e,$6c,$5a), + ($ff,$fb,$fd,$0e), ($38,$56,$0f,$85), ($d5,$1e,$3d,$ae), ($39,$27,$36,$2d), + ($d9,$64,$0a,$0f), ($a6,$21,$68,$5c), ($54,$d1,$9b,$5b), ($2e,$3a,$24,$36), + ($67,$b1,$0c,$0a), ($e7,$0f,$93,$57), ($96,$d2,$b4,$ee), ($91,$9e,$1b,$9b), + ($c5,$4f,$80,$c0), ($20,$a2,$61,$dc), ($4b,$69,$5a,$77), ($1a,$16,$1c,$12), + ($ba,$0a,$e2,$93), ($2a,$e5,$c0,$a0), ($e0,$43,$3c,$22), ($17,$1d,$12,$1b), + ($0d,$0b,$0e,$09), ($c7,$ad,$f2,$8b), ($a8,$b9,$2d,$b6), ($a9,$c8,$14,$1e), + ($19,$85,$57,$f1), ($07,$4c,$af,$75), ($dd,$bb,$ee,$99), ($60,$fd,$a3,$7f), + ($26,$9f,$f7,$01), ($f5,$bc,$5c,$72), ($3b,$c5,$44,$66), ($7e,$34,$5b,$fb), + ($29,$76,$8b,$43), ($c6,$dc,$cb,$23), ($fc,$68,$b6,$ed), ($f1,$63,$b8,$e4), + ($dc,$ca,$d7,$31), ($85,$10,$42,$63), ($22,$40,$13,$97), ($11,$20,$84,$c6), + ($24,$7d,$85,$4a), ($3d,$f8,$d2,$bb), ($32,$11,$ae,$f9), ($a1,$6d,$c7,$29), + ($2f,$4b,$1d,$9e), ($30,$f3,$dc,$b2), ($52,$ec,$0d,$86), ($e3,$d0,$77,$c1), + ($16,$6c,$2b,$b3), ($b9,$99,$a9,$70), ($48,$fa,$11,$94), ($64,$22,$47,$e9), + ($8c,$c4,$a8,$fc), ($3f,$1a,$a0,$f0), ($2c,$d8,$56,$7d), ($90,$ef,$22,$33), + ($4e,$c7,$87,$49), ($d1,$c1,$d9,$38), ($a2,$fe,$8c,$ca), ($0b,$36,$98,$d4), + ($81,$cf,$a6,$f5), ($de,$28,$a5,$7a), ($8e,$26,$da,$b7), ($bf,$a4,$3f,$ad), + ($9d,$e4,$2c,$3a), ($92,$0d,$50,$78), ($cc,$9b,$6a,$5f), ($46,$62,$54,$7e), + ($13,$c2,$f6,$8d), ($b8,$e8,$90,$d8), ($f7,$5e,$2e,$39), ($af,$f5,$82,$c3), + ($80,$be,$9f,$5d), ($93,$7c,$69,$d0), ($2d,$a9,$6f,$d5), ($12,$b3,$cf,$25), + ($99,$3b,$c8,$ac), ($7d,$a7,$10,$18), ($63,$6e,$e8,$9c), ($bb,$7b,$db,$3b), + ($78,$09,$cd,$26), ($18,$f4,$6e,$59), ($b7,$01,$ec,$9a), ($9a,$a8,$83,$4f), + ($6e,$65,$e6,$95), ($e6,$7e,$aa,$ff), ($cf,$08,$21,$bc), ($e8,$e6,$ef,$15), + ($9b,$d9,$ba,$e7), ($36,$ce,$4a,$6f), ($09,$d4,$ea,$9f), ($7c,$d6,$29,$b0), + ($b2,$af,$31,$a4), ($23,$31,$2a,$3f), ($94,$30,$c6,$a5), ($66,$c0,$35,$a2), + ($bc,$37,$74,$4e), ($ca,$a6,$fc,$82), ($d0,$b0,$e0,$90), ($d8,$15,$33,$a7), + ($98,$4a,$f1,$04), ($da,$f7,$41,$ec), ($50,$0e,$7f,$cd), ($f6,$2f,$17,$91), + ($d6,$8d,$76,$4d), ($b0,$4d,$43,$ef), ($4d,$54,$cc,$aa), ($04,$df,$e4,$96), + ($b5,$e3,$9e,$d1), ($88,$1b,$4c,$6a), ($1f,$b8,$c1,$2c), ($51,$7f,$46,$65), + ($ea,$04,$9d,$5e), ($35,$5d,$01,$8c), ($74,$73,$fa,$87), ($41,$2e,$fb,$0b), + ($1d,$5a,$b3,$67), ($d2,$52,$92,$db), ($56,$33,$e9,$10), ($47,$13,$6d,$d6), + ($61,$8c,$9a,$d7), ($0c,$7a,$37,$a1), ($14,$8e,$59,$f8), ($3c,$89,$eb,$13), + ($27,$ee,$ce,$a9), ($c9,$35,$b7,$61), ($e5,$ed,$e1,$1c), ($b1,$3c,$7a,$47), + ($df,$59,$9c,$d2), ($73,$3f,$55,$f2), ($ce,$79,$18,$14), ($37,$bf,$73,$c7), + ($cd,$ea,$53,$f7), ($aa,$5b,$5f,$fd), ($6f,$14,$df,$3d), ($db,$86,$78,$44), + ($f3,$81,$ca,$af), ($c4,$3e,$b9,$68), ($34,$2c,$38,$24), ($40,$5f,$c2,$a3), + ($c3,$72,$16,$1d), ($25,$0c,$bc,$e2), ($49,$8b,$28,$3c), ($95,$41,$ff,$0d), + ($01,$71,$39,$a8), ($b3,$de,$08,$0c), ($e4,$9c,$d8,$b4), ($c1,$90,$64,$56), + ($84,$61,$7b,$cb), ($b6,$70,$d5,$32), ($5c,$74,$48,$6c), ($57,$42,$d0,$b8)); + T8: array[0..255,0..3] of byte= ( + ($f4,$a7,$50,$51), ($41,$65,$53,$7e), ($17,$a4,$c3,$1a), ($27,$5e,$96,$3a), + ($ab,$6b,$cb,$3b), ($9d,$45,$f1,$1f), ($fa,$58,$ab,$ac), ($e3,$03,$93,$4b), + ($30,$fa,$55,$20), ($76,$6d,$f6,$ad), ($cc,$76,$91,$88), ($02,$4c,$25,$f5), + ($e5,$d7,$fc,$4f), ($2a,$cb,$d7,$c5), ($35,$44,$80,$26), ($62,$a3,$8f,$b5), + ($b1,$5a,$49,$de), ($ba,$1b,$67,$25), ($ea,$0e,$98,$45), ($fe,$c0,$e1,$5d), + ($2f,$75,$02,$c3), ($4c,$f0,$12,$81), ($46,$97,$a3,$8d), ($d3,$f9,$c6,$6b), + ($8f,$5f,$e7,$03), ($92,$9c,$95,$15), ($6d,$7a,$eb,$bf), ($52,$59,$da,$95), + ($be,$83,$2d,$d4), ($74,$21,$d3,$58), ($e0,$69,$29,$49), ($c9,$c8,$44,$8e), + ($c2,$89,$6a,$75), ($8e,$79,$78,$f4), ($58,$3e,$6b,$99), ($b9,$71,$dd,$27), + ($e1,$4f,$b6,$be), ($88,$ad,$17,$f0), ($20,$ac,$66,$c9), ($ce,$3a,$b4,$7d), + ($df,$4a,$18,$63), ($1a,$31,$82,$e5), ($51,$33,$60,$97), ($53,$7f,$45,$62), + ($64,$77,$e0,$b1), ($6b,$ae,$84,$bb), ($81,$a0,$1c,$fe), ($08,$2b,$94,$f9), + ($48,$68,$58,$70), ($45,$fd,$19,$8f), ($de,$6c,$87,$94), ($7b,$f8,$b7,$52), + ($73,$d3,$23,$ab), ($4b,$02,$e2,$72), ($1f,$8f,$57,$e3), ($55,$ab,$2a,$66), + ($eb,$28,$07,$b2), ($b5,$c2,$03,$2f), ($c5,$7b,$9a,$86), ($37,$08,$a5,$d3), + ($28,$87,$f2,$30), ($bf,$a5,$b2,$23), ($03,$6a,$ba,$02), ($16,$82,$5c,$ed), + ($cf,$1c,$2b,$8a), ($79,$b4,$92,$a7), ($07,$f2,$f0,$f3), ($69,$e2,$a1,$4e), + ($da,$f4,$cd,$65), ($05,$be,$d5,$06), ($34,$62,$1f,$d1), ($a6,$fe,$8a,$c4), + ($2e,$53,$9d,$34), ($f3,$55,$a0,$a2), ($8a,$e1,$32,$05), ($f6,$eb,$75,$a4), + ($83,$ec,$39,$0b), ($60,$ef,$aa,$40), ($71,$9f,$06,$5e), ($6e,$10,$51,$bd), + ($21,$8a,$f9,$3e), ($dd,$06,$3d,$96), ($3e,$05,$ae,$dd), ($e6,$bd,$46,$4d), + ($54,$8d,$b5,$91), ($c4,$5d,$05,$71), ($06,$d4,$6f,$04), ($50,$15,$ff,$60), + ($98,$fb,$24,$19), ($bd,$e9,$97,$d6), ($40,$43,$cc,$89), ($d9,$9e,$77,$67), + ($e8,$42,$bd,$b0), ($89,$8b,$88,$07), ($19,$5b,$38,$e7), ($c8,$ee,$db,$79), + ($7c,$0a,$47,$a1), ($42,$0f,$e9,$7c), ($84,$1e,$c9,$f8), ($00,$00,$00,$00), + ($80,$86,$83,$09), ($2b,$ed,$48,$32), ($11,$70,$ac,$1e), ($5a,$72,$4e,$6c), + ($0e,$ff,$fb,$fd), ($85,$38,$56,$0f), ($ae,$d5,$1e,$3d), ($2d,$39,$27,$36), + ($0f,$d9,$64,$0a), ($5c,$a6,$21,$68), ($5b,$54,$d1,$9b), ($36,$2e,$3a,$24), + ($0a,$67,$b1,$0c), ($57,$e7,$0f,$93), ($ee,$96,$d2,$b4), ($9b,$91,$9e,$1b), + ($c0,$c5,$4f,$80), ($dc,$20,$a2,$61), ($77,$4b,$69,$5a), ($12,$1a,$16,$1c), + ($93,$ba,$0a,$e2), ($a0,$2a,$e5,$c0), ($22,$e0,$43,$3c), ($1b,$17,$1d,$12), + ($09,$0d,$0b,$0e), ($8b,$c7,$ad,$f2), ($b6,$a8,$b9,$2d), ($1e,$a9,$c8,$14), + ($f1,$19,$85,$57), ($75,$07,$4c,$af), ($99,$dd,$bb,$ee), ($7f,$60,$fd,$a3), + ($01,$26,$9f,$f7), ($72,$f5,$bc,$5c), ($66,$3b,$c5,$44), ($fb,$7e,$34,$5b), + ($43,$29,$76,$8b), ($23,$c6,$dc,$cb), ($ed,$fc,$68,$b6), ($e4,$f1,$63,$b8), + ($31,$dc,$ca,$d7), ($63,$85,$10,$42), ($97,$22,$40,$13), ($c6,$11,$20,$84), + ($4a,$24,$7d,$85), ($bb,$3d,$f8,$d2), ($f9,$32,$11,$ae), ($29,$a1,$6d,$c7), + ($9e,$2f,$4b,$1d), ($b2,$30,$f3,$dc), ($86,$52,$ec,$0d), ($c1,$e3,$d0,$77), + ($b3,$16,$6c,$2b), ($70,$b9,$99,$a9), ($94,$48,$fa,$11), ($e9,$64,$22,$47), + ($fc,$8c,$c4,$a8), ($f0,$3f,$1a,$a0), ($7d,$2c,$d8,$56), ($33,$90,$ef,$22), + ($49,$4e,$c7,$87), ($38,$d1,$c1,$d9), ($ca,$a2,$fe,$8c), ($d4,$0b,$36,$98), + ($f5,$81,$cf,$a6), ($7a,$de,$28,$a5), ($b7,$8e,$26,$da), ($ad,$bf,$a4,$3f), + ($3a,$9d,$e4,$2c), ($78,$92,$0d,$50), ($5f,$cc,$9b,$6a), ($7e,$46,$62,$54), + ($8d,$13,$c2,$f6), ($d8,$b8,$e8,$90), ($39,$f7,$5e,$2e), ($c3,$af,$f5,$82), + ($5d,$80,$be,$9f), ($d0,$93,$7c,$69), ($d5,$2d,$a9,$6f), ($25,$12,$b3,$cf), + ($ac,$99,$3b,$c8), ($18,$7d,$a7,$10), ($9c,$63,$6e,$e8), ($3b,$bb,$7b,$db), + ($26,$78,$09,$cd), ($59,$18,$f4,$6e), ($9a,$b7,$01,$ec), ($4f,$9a,$a8,$83), + ($95,$6e,$65,$e6), ($ff,$e6,$7e,$aa), ($bc,$cf,$08,$21), ($15,$e8,$e6,$ef), + ($e7,$9b,$d9,$ba), ($6f,$36,$ce,$4a), ($9f,$09,$d4,$ea), ($b0,$7c,$d6,$29), + ($a4,$b2,$af,$31), ($3f,$23,$31,$2a), ($a5,$94,$30,$c6), ($a2,$66,$c0,$35), + ($4e,$bc,$37,$74), ($82,$ca,$a6,$fc), ($90,$d0,$b0,$e0), ($a7,$d8,$15,$33), + ($04,$98,$4a,$f1), ($ec,$da,$f7,$41), ($cd,$50,$0e,$7f), ($91,$f6,$2f,$17), + ($4d,$d6,$8d,$76), ($ef,$b0,$4d,$43), ($aa,$4d,$54,$cc), ($96,$04,$df,$e4), + ($d1,$b5,$e3,$9e), ($6a,$88,$1b,$4c), ($2c,$1f,$b8,$c1), ($65,$51,$7f,$46), + ($5e,$ea,$04,$9d), ($8c,$35,$5d,$01), ($87,$74,$73,$fa), ($0b,$41,$2e,$fb), + ($67,$1d,$5a,$b3), ($db,$d2,$52,$92), ($10,$56,$33,$e9), ($d6,$47,$13,$6d), + ($d7,$61,$8c,$9a), ($a1,$0c,$7a,$37), ($f8,$14,$8e,$59), ($13,$3c,$89,$eb), + ($a9,$27,$ee,$ce), ($61,$c9,$35,$b7), ($1c,$e5,$ed,$e1), ($47,$b1,$3c,$7a), + ($d2,$df,$59,$9c), ($f2,$73,$3f,$55), ($14,$ce,$79,$18), ($c7,$37,$bf,$73), + ($f7,$cd,$ea,$53), ($fd,$aa,$5b,$5f), ($3d,$6f,$14,$df), ($44,$db,$86,$78), + ($af,$f3,$81,$ca), ($68,$c4,$3e,$b9), ($24,$34,$2c,$38), ($a3,$40,$5f,$c2), + ($1d,$c3,$72,$16), ($e2,$25,$0c,$bc), ($3c,$49,$8b,$28), ($0d,$95,$41,$ff), + ($a8,$01,$71,$39), ($0c,$b3,$de,$08), ($b4,$e4,$9c,$d8), ($56,$c1,$90,$64), + ($cb,$84,$61,$7b), ($32,$b6,$70,$d5), ($6c,$5c,$74,$48), ($b8,$57,$42,$d0)); + S5: array[0..255] of byte= ( + $52,$09,$6a,$d5, + $30,$36,$a5,$38, + $bf,$40,$a3,$9e, + $81,$f3,$d7,$fb, + $7c,$e3,$39,$82, + $9b,$2f,$ff,$87, + $34,$8e,$43,$44, + $c4,$de,$e9,$cb, + $54,$7b,$94,$32, + $a6,$c2,$23,$3d, + $ee,$4c,$95,$0b, + $42,$fa,$c3,$4e, + $08,$2e,$a1,$66, + $28,$d9,$24,$b2, + $76,$5b,$a2,$49, + $6d,$8b,$d1,$25, + $72,$f8,$f6,$64, + $86,$68,$98,$16, + $d4,$a4,$5c,$cc, + $5d,$65,$b6,$92, + $6c,$70,$48,$50, + $fd,$ed,$b9,$da, + $5e,$15,$46,$57, + $a7,$8d,$9d,$84, + $90,$d8,$ab,$00, + $8c,$bc,$d3,$0a, + $f7,$e4,$58,$05, + $b8,$b3,$45,$06, + $d0,$2c,$1e,$8f, + $ca,$3f,$0f,$02, + $c1,$af,$bd,$03, + $01,$13,$8a,$6b, + $3a,$91,$11,$41, + $4f,$67,$dc,$ea, + $97,$f2,$cf,$ce, + $f0,$b4,$e6,$73, + $96,$ac,$74,$22, + $e7,$ad,$35,$85, + $e2,$f9,$37,$e8, + $1c,$75,$df,$6e, + $47,$f1,$1a,$71, + $1d,$29,$c5,$89, + $6f,$b7,$62,$0e, + $aa,$18,$be,$1b, + $fc,$56,$3e,$4b, + $c6,$d2,$79,$20, + $9a,$db,$c0,$fe, + $78,$cd,$5a,$f4, + $1f,$dd,$a8,$33, + $88,$07,$c7,$31, + $b1,$12,$10,$59, + $27,$80,$ec,$5f, + $60,$51,$7f,$a9, + $19,$b5,$4a,$0d, + $2d,$e5,$7a,$9f, + $93,$c9,$9c,$ef, + $a0,$e0,$3b,$4d, + $ae,$2a,$f5,$b0, + $c8,$eb,$bb,$3c, + $83,$53,$99,$61, + $17,$2b,$04,$7e, + $ba,$77,$d6,$26, + $e1,$69,$14,$63, + $55,$21,$0c,$7d); + U1: array[0..255,0..3] of byte= ( + ($00,$00,$00,$00), ($0e,$09,$0d,$0b), ($1c,$12,$1a,$16), ($12,$1b,$17,$1d), + ($38,$24,$34,$2c), ($36,$2d,$39,$27), ($24,$36,$2e,$3a), ($2a,$3f,$23,$31), + ($70,$48,$68,$58), ($7e,$41,$65,$53), ($6c,$5a,$72,$4e), ($62,$53,$7f,$45), + ($48,$6c,$5c,$74), ($46,$65,$51,$7f), ($54,$7e,$46,$62), ($5a,$77,$4b,$69), + ($e0,$90,$d0,$b0), ($ee,$99,$dd,$bb), ($fc,$82,$ca,$a6), ($f2,$8b,$c7,$ad), + ($d8,$b4,$e4,$9c), ($d6,$bd,$e9,$97), ($c4,$a6,$fe,$8a), ($ca,$af,$f3,$81), + ($90,$d8,$b8,$e8), ($9e,$d1,$b5,$e3), ($8c,$ca,$a2,$fe), ($82,$c3,$af,$f5), + ($a8,$fc,$8c,$c4), ($a6,$f5,$81,$cf), ($b4,$ee,$96,$d2), ($ba,$e7,$9b,$d9), + ($db,$3b,$bb,$7b), ($d5,$32,$b6,$70), ($c7,$29,$a1,$6d), ($c9,$20,$ac,$66), + ($e3,$1f,$8f,$57), ($ed,$16,$82,$5c), ($ff,$0d,$95,$41), ($f1,$04,$98,$4a), + ($ab,$73,$d3,$23), ($a5,$7a,$de,$28), ($b7,$61,$c9,$35), ($b9,$68,$c4,$3e), + ($93,$57,$e7,$0f), ($9d,$5e,$ea,$04), ($8f,$45,$fd,$19), ($81,$4c,$f0,$12), + ($3b,$ab,$6b,$cb), ($35,$a2,$66,$c0), ($27,$b9,$71,$dd), ($29,$b0,$7c,$d6), + ($03,$8f,$5f,$e7), ($0d,$86,$52,$ec), ($1f,$9d,$45,$f1), ($11,$94,$48,$fa), + ($4b,$e3,$03,$93), ($45,$ea,$0e,$98), ($57,$f1,$19,$85), ($59,$f8,$14,$8e), + ($73,$c7,$37,$bf), ($7d,$ce,$3a,$b4), ($6f,$d5,$2d,$a9), ($61,$dc,$20,$a2), + ($ad,$76,$6d,$f6), ($a3,$7f,$60,$fd), ($b1,$64,$77,$e0), ($bf,$6d,$7a,$eb), + ($95,$52,$59,$da), ($9b,$5b,$54,$d1), ($89,$40,$43,$cc), ($87,$49,$4e,$c7), + ($dd,$3e,$05,$ae), ($d3,$37,$08,$a5), ($c1,$2c,$1f,$b8), ($cf,$25,$12,$b3), + ($e5,$1a,$31,$82), ($eb,$13,$3c,$89), ($f9,$08,$2b,$94), ($f7,$01,$26,$9f), + ($4d,$e6,$bd,$46), ($43,$ef,$b0,$4d), ($51,$f4,$a7,$50), ($5f,$fd,$aa,$5b), + ($75,$c2,$89,$6a), ($7b,$cb,$84,$61), ($69,$d0,$93,$7c), ($67,$d9,$9e,$77), + ($3d,$ae,$d5,$1e), ($33,$a7,$d8,$15), ($21,$bc,$cf,$08), ($2f,$b5,$c2,$03), + ($05,$8a,$e1,$32), ($0b,$83,$ec,$39), ($19,$98,$fb,$24), ($17,$91,$f6,$2f), + ($76,$4d,$d6,$8d), ($78,$44,$db,$86), ($6a,$5f,$cc,$9b), ($64,$56,$c1,$90), + ($4e,$69,$e2,$a1), ($40,$60,$ef,$aa), ($52,$7b,$f8,$b7), ($5c,$72,$f5,$bc), + ($06,$05,$be,$d5), ($08,$0c,$b3,$de), ($1a,$17,$a4,$c3), ($14,$1e,$a9,$c8), + ($3e,$21,$8a,$f9), ($30,$28,$87,$f2), ($22,$33,$90,$ef), ($2c,$3a,$9d,$e4), + ($96,$dd,$06,$3d), ($98,$d4,$0b,$36), ($8a,$cf,$1c,$2b), ($84,$c6,$11,$20), + ($ae,$f9,$32,$11), ($a0,$f0,$3f,$1a), ($b2,$eb,$28,$07), ($bc,$e2,$25,$0c), + ($e6,$95,$6e,$65), ($e8,$9c,$63,$6e), ($fa,$87,$74,$73), ($f4,$8e,$79,$78), + ($de,$b1,$5a,$49), ($d0,$b8,$57,$42), ($c2,$a3,$40,$5f), ($cc,$aa,$4d,$54), + ($41,$ec,$da,$f7), ($4f,$e5,$d7,$fc), ($5d,$fe,$c0,$e1), ($53,$f7,$cd,$ea), + ($79,$c8,$ee,$db), ($77,$c1,$e3,$d0), ($65,$da,$f4,$cd), ($6b,$d3,$f9,$c6), + ($31,$a4,$b2,$af), ($3f,$ad,$bf,$a4), ($2d,$b6,$a8,$b9), ($23,$bf,$a5,$b2), + ($09,$80,$86,$83), ($07,$89,$8b,$88), ($15,$92,$9c,$95), ($1b,$9b,$91,$9e), + ($a1,$7c,$0a,$47), ($af,$75,$07,$4c), ($bd,$6e,$10,$51), ($b3,$67,$1d,$5a), + ($99,$58,$3e,$6b), ($97,$51,$33,$60), ($85,$4a,$24,$7d), ($8b,$43,$29,$76), + ($d1,$34,$62,$1f), ($df,$3d,$6f,$14), ($cd,$26,$78,$09), ($c3,$2f,$75,$02), + ($e9,$10,$56,$33), ($e7,$19,$5b,$38), ($f5,$02,$4c,$25), ($fb,$0b,$41,$2e), + ($9a,$d7,$61,$8c), ($94,$de,$6c,$87), ($86,$c5,$7b,$9a), ($88,$cc,$76,$91), + ($a2,$f3,$55,$a0), ($ac,$fa,$58,$ab), ($be,$e1,$4f,$b6), ($b0,$e8,$42,$bd), + ($ea,$9f,$09,$d4), ($e4,$96,$04,$df), ($f6,$8d,$13,$c2), ($f8,$84,$1e,$c9), + ($d2,$bb,$3d,$f8), ($dc,$b2,$30,$f3), ($ce,$a9,$27,$ee), ($c0,$a0,$2a,$e5), + ($7a,$47,$b1,$3c), ($74,$4e,$bc,$37), ($66,$55,$ab,$2a), ($68,$5c,$a6,$21), + ($42,$63,$85,$10), ($4c,$6a,$88,$1b), ($5e,$71,$9f,$06), ($50,$78,$92,$0d), + ($0a,$0f,$d9,$64), ($04,$06,$d4,$6f), ($16,$1d,$c3,$72), ($18,$14,$ce,$79), + ($32,$2b,$ed,$48), ($3c,$22,$e0,$43), ($2e,$39,$f7,$5e), ($20,$30,$fa,$55), + ($ec,$9a,$b7,$01), ($e2,$93,$ba,$0a), ($f0,$88,$ad,$17), ($fe,$81,$a0,$1c), + ($d4,$be,$83,$2d), ($da,$b7,$8e,$26), ($c8,$ac,$99,$3b), ($c6,$a5,$94,$30), + ($9c,$d2,$df,$59), ($92,$db,$d2,$52), ($80,$c0,$c5,$4f), ($8e,$c9,$c8,$44), + ($a4,$f6,$eb,$75), ($aa,$ff,$e6,$7e), ($b8,$e4,$f1,$63), ($b6,$ed,$fc,$68), + ($0c,$0a,$67,$b1), ($02,$03,$6a,$ba), ($10,$18,$7d,$a7), ($1e,$11,$70,$ac), + ($34,$2e,$53,$9d), ($3a,$27,$5e,$96), ($28,$3c,$49,$8b), ($26,$35,$44,$80), + ($7c,$42,$0f,$e9), ($72,$4b,$02,$e2), ($60,$50,$15,$ff), ($6e,$59,$18,$f4), + ($44,$66,$3b,$c5), ($4a,$6f,$36,$ce), ($58,$74,$21,$d3), ($56,$7d,$2c,$d8), + ($37,$a1,$0c,$7a), ($39,$a8,$01,$71), ($2b,$b3,$16,$6c), ($25,$ba,$1b,$67), + ($0f,$85,$38,$56), ($01,$8c,$35,$5d), ($13,$97,$22,$40), ($1d,$9e,$2f,$4b), + ($47,$e9,$64,$22), ($49,$e0,$69,$29), ($5b,$fb,$7e,$34), ($55,$f2,$73,$3f), + ($7f,$cd,$50,$0e), ($71,$c4,$5d,$05), ($63,$df,$4a,$18), ($6d,$d6,$47,$13), + ($d7,$31,$dc,$ca), ($d9,$38,$d1,$c1), ($cb,$23,$c6,$dc), ($c5,$2a,$cb,$d7), + ($ef,$15,$e8,$e6), ($e1,$1c,$e5,$ed), ($f3,$07,$f2,$f0), ($fd,$0e,$ff,$fb), + ($a7,$79,$b4,$92), ($a9,$70,$b9,$99), ($bb,$6b,$ae,$84), ($b5,$62,$a3,$8f), + ($9f,$5d,$80,$be), ($91,$54,$8d,$b5), ($83,$4f,$9a,$a8), ($8d,$46,$97,$a3)); + U2: array[0..255,0..3] of byte= ( + ($00,$00,$00,$00), ($0b,$0e,$09,$0d), ($16,$1c,$12,$1a), ($1d,$12,$1b,$17), + ($2c,$38,$24,$34), ($27,$36,$2d,$39), ($3a,$24,$36,$2e), ($31,$2a,$3f,$23), + ($58,$70,$48,$68), ($53,$7e,$41,$65), ($4e,$6c,$5a,$72), ($45,$62,$53,$7f), + ($74,$48,$6c,$5c), ($7f,$46,$65,$51), ($62,$54,$7e,$46), ($69,$5a,$77,$4b), + ($b0,$e0,$90,$d0), ($bb,$ee,$99,$dd), ($a6,$fc,$82,$ca), ($ad,$f2,$8b,$c7), + ($9c,$d8,$b4,$e4), ($97,$d6,$bd,$e9), ($8a,$c4,$a6,$fe), ($81,$ca,$af,$f3), + ($e8,$90,$d8,$b8), ($e3,$9e,$d1,$b5), ($fe,$8c,$ca,$a2), ($f5,$82,$c3,$af), + ($c4,$a8,$fc,$8c), ($cf,$a6,$f5,$81), ($d2,$b4,$ee,$96), ($d9,$ba,$e7,$9b), + ($7b,$db,$3b,$bb), ($70,$d5,$32,$b6), ($6d,$c7,$29,$a1), ($66,$c9,$20,$ac), + ($57,$e3,$1f,$8f), ($5c,$ed,$16,$82), ($41,$ff,$0d,$95), ($4a,$f1,$04,$98), + ($23,$ab,$73,$d3), ($28,$a5,$7a,$de), ($35,$b7,$61,$c9), ($3e,$b9,$68,$c4), + ($0f,$93,$57,$e7), ($04,$9d,$5e,$ea), ($19,$8f,$45,$fd), ($12,$81,$4c,$f0), + ($cb,$3b,$ab,$6b), ($c0,$35,$a2,$66), ($dd,$27,$b9,$71), ($d6,$29,$b0,$7c), + ($e7,$03,$8f,$5f), ($ec,$0d,$86,$52), ($f1,$1f,$9d,$45), ($fa,$11,$94,$48), + ($93,$4b,$e3,$03), ($98,$45,$ea,$0e), ($85,$57,$f1,$19), ($8e,$59,$f8,$14), + ($bf,$73,$c7,$37), ($b4,$7d,$ce,$3a), ($a9,$6f,$d5,$2d), ($a2,$61,$dc,$20), + ($f6,$ad,$76,$6d), ($fd,$a3,$7f,$60), ($e0,$b1,$64,$77), ($eb,$bf,$6d,$7a), + ($da,$95,$52,$59), ($d1,$9b,$5b,$54), ($cc,$89,$40,$43), ($c7,$87,$49,$4e), + ($ae,$dd,$3e,$05), ($a5,$d3,$37,$08), ($b8,$c1,$2c,$1f), ($b3,$cf,$25,$12), + ($82,$e5,$1a,$31), ($89,$eb,$13,$3c), ($94,$f9,$08,$2b), ($9f,$f7,$01,$26), + ($46,$4d,$e6,$bd), ($4d,$43,$ef,$b0), ($50,$51,$f4,$a7), ($5b,$5f,$fd,$aa), + ($6a,$75,$c2,$89), ($61,$7b,$cb,$84), ($7c,$69,$d0,$93), ($77,$67,$d9,$9e), + ($1e,$3d,$ae,$d5), ($15,$33,$a7,$d8), ($08,$21,$bc,$cf), ($03,$2f,$b5,$c2), + ($32,$05,$8a,$e1), ($39,$0b,$83,$ec), ($24,$19,$98,$fb), ($2f,$17,$91,$f6), + ($8d,$76,$4d,$d6), ($86,$78,$44,$db), ($9b,$6a,$5f,$cc), ($90,$64,$56,$c1), + ($a1,$4e,$69,$e2), ($aa,$40,$60,$ef), ($b7,$52,$7b,$f8), ($bc,$5c,$72,$f5), + ($d5,$06,$05,$be), ($de,$08,$0c,$b3), ($c3,$1a,$17,$a4), ($c8,$14,$1e,$a9), + ($f9,$3e,$21,$8a), ($f2,$30,$28,$87), ($ef,$22,$33,$90), ($e4,$2c,$3a,$9d), + ($3d,$96,$dd,$06), ($36,$98,$d4,$0b), ($2b,$8a,$cf,$1c), ($20,$84,$c6,$11), + ($11,$ae,$f9,$32), ($1a,$a0,$f0,$3f), ($07,$b2,$eb,$28), ($0c,$bc,$e2,$25), + ($65,$e6,$95,$6e), ($6e,$e8,$9c,$63), ($73,$fa,$87,$74), ($78,$f4,$8e,$79), + ($49,$de,$b1,$5a), ($42,$d0,$b8,$57), ($5f,$c2,$a3,$40), ($54,$cc,$aa,$4d), + ($f7,$41,$ec,$da), ($fc,$4f,$e5,$d7), ($e1,$5d,$fe,$c0), ($ea,$53,$f7,$cd), + ($db,$79,$c8,$ee), ($d0,$77,$c1,$e3), ($cd,$65,$da,$f4), ($c6,$6b,$d3,$f9), + ($af,$31,$a4,$b2), ($a4,$3f,$ad,$bf), ($b9,$2d,$b6,$a8), ($b2,$23,$bf,$a5), + ($83,$09,$80,$86), ($88,$07,$89,$8b), ($95,$15,$92,$9c), ($9e,$1b,$9b,$91), + ($47,$a1,$7c,$0a), ($4c,$af,$75,$07), ($51,$bd,$6e,$10), ($5a,$b3,$67,$1d), + ($6b,$99,$58,$3e), ($60,$97,$51,$33), ($7d,$85,$4a,$24), ($76,$8b,$43,$29), + ($1f,$d1,$34,$62), ($14,$df,$3d,$6f), ($09,$cd,$26,$78), ($02,$c3,$2f,$75), + ($33,$e9,$10,$56), ($38,$e7,$19,$5b), ($25,$f5,$02,$4c), ($2e,$fb,$0b,$41), + ($8c,$9a,$d7,$61), ($87,$94,$de,$6c), ($9a,$86,$c5,$7b), ($91,$88,$cc,$76), + ($a0,$a2,$f3,$55), ($ab,$ac,$fa,$58), ($b6,$be,$e1,$4f), ($bd,$b0,$e8,$42), + ($d4,$ea,$9f,$09), ($df,$e4,$96,$04), ($c2,$f6,$8d,$13), ($c9,$f8,$84,$1e), + ($f8,$d2,$bb,$3d), ($f3,$dc,$b2,$30), ($ee,$ce,$a9,$27), ($e5,$c0,$a0,$2a), + ($3c,$7a,$47,$b1), ($37,$74,$4e,$bc), ($2a,$66,$55,$ab), ($21,$68,$5c,$a6), + ($10,$42,$63,$85), ($1b,$4c,$6a,$88), ($06,$5e,$71,$9f), ($0d,$50,$78,$92), + ($64,$0a,$0f,$d9), ($6f,$04,$06,$d4), ($72,$16,$1d,$c3), ($79,$18,$14,$ce), + ($48,$32,$2b,$ed), ($43,$3c,$22,$e0), ($5e,$2e,$39,$f7), ($55,$20,$30,$fa), + ($01,$ec,$9a,$b7), ($0a,$e2,$93,$ba), ($17,$f0,$88,$ad), ($1c,$fe,$81,$a0), + ($2d,$d4,$be,$83), ($26,$da,$b7,$8e), ($3b,$c8,$ac,$99), ($30,$c6,$a5,$94), + ($59,$9c,$d2,$df), ($52,$92,$db,$d2), ($4f,$80,$c0,$c5), ($44,$8e,$c9,$c8), + ($75,$a4,$f6,$eb), ($7e,$aa,$ff,$e6), ($63,$b8,$e4,$f1), ($68,$b6,$ed,$fc), + ($b1,$0c,$0a,$67), ($ba,$02,$03,$6a), ($a7,$10,$18,$7d), ($ac,$1e,$11,$70), + ($9d,$34,$2e,$53), ($96,$3a,$27,$5e), ($8b,$28,$3c,$49), ($80,$26,$35,$44), + ($e9,$7c,$42,$0f), ($e2,$72,$4b,$02), ($ff,$60,$50,$15), ($f4,$6e,$59,$18), + ($c5,$44,$66,$3b), ($ce,$4a,$6f,$36), ($d3,$58,$74,$21), ($d8,$56,$7d,$2c), + ($7a,$37,$a1,$0c), ($71,$39,$a8,$01), ($6c,$2b,$b3,$16), ($67,$25,$ba,$1b), + ($56,$0f,$85,$38), ($5d,$01,$8c,$35), ($40,$13,$97,$22), ($4b,$1d,$9e,$2f), + ($22,$47,$e9,$64), ($29,$49,$e0,$69), ($34,$5b,$fb,$7e), ($3f,$55,$f2,$73), + ($0e,$7f,$cd,$50), ($05,$71,$c4,$5d), ($18,$63,$df,$4a), ($13,$6d,$d6,$47), + ($ca,$d7,$31,$dc), ($c1,$d9,$38,$d1), ($dc,$cb,$23,$c6), ($d7,$c5,$2a,$cb), + ($e6,$ef,$15,$e8), ($ed,$e1,$1c,$e5), ($f0,$f3,$07,$f2), ($fb,$fd,$0e,$ff), + ($92,$a7,$79,$b4), ($99,$a9,$70,$b9), ($84,$bb,$6b,$ae), ($8f,$b5,$62,$a3), + ($be,$9f,$5d,$80), ($b5,$91,$54,$8d), ($a8,$83,$4f,$9a), ($a3,$8d,$46,$97)); + U3: array[0..255,0..3] of byte= ( + ($00,$00,$00,$00), ($0d,$0b,$0e,$09), ($1a,$16,$1c,$12), ($17,$1d,$12,$1b), + ($34,$2c,$38,$24), ($39,$27,$36,$2d), ($2e,$3a,$24,$36), ($23,$31,$2a,$3f), + ($68,$58,$70,$48), ($65,$53,$7e,$41), ($72,$4e,$6c,$5a), ($7f,$45,$62,$53), + ($5c,$74,$48,$6c), ($51,$7f,$46,$65), ($46,$62,$54,$7e), ($4b,$69,$5a,$77), + ($d0,$b0,$e0,$90), ($dd,$bb,$ee,$99), ($ca,$a6,$fc,$82), ($c7,$ad,$f2,$8b), + ($e4,$9c,$d8,$b4), ($e9,$97,$d6,$bd), ($fe,$8a,$c4,$a6), ($f3,$81,$ca,$af), + ($b8,$e8,$90,$d8), ($b5,$e3,$9e,$d1), ($a2,$fe,$8c,$ca), ($af,$f5,$82,$c3), + ($8c,$c4,$a8,$fc), ($81,$cf,$a6,$f5), ($96,$d2,$b4,$ee), ($9b,$d9,$ba,$e7), + ($bb,$7b,$db,$3b), ($b6,$70,$d5,$32), ($a1,$6d,$c7,$29), ($ac,$66,$c9,$20), + ($8f,$57,$e3,$1f), ($82,$5c,$ed,$16), ($95,$41,$ff,$0d), ($98,$4a,$f1,$04), + ($d3,$23,$ab,$73), ($de,$28,$a5,$7a), ($c9,$35,$b7,$61), ($c4,$3e,$b9,$68), + ($e7,$0f,$93,$57), ($ea,$04,$9d,$5e), ($fd,$19,$8f,$45), ($f0,$12,$81,$4c), + ($6b,$cb,$3b,$ab), ($66,$c0,$35,$a2), ($71,$dd,$27,$b9), ($7c,$d6,$29,$b0), + ($5f,$e7,$03,$8f), ($52,$ec,$0d,$86), ($45,$f1,$1f,$9d), ($48,$fa,$11,$94), + ($03,$93,$4b,$e3), ($0e,$98,$45,$ea), ($19,$85,$57,$f1), ($14,$8e,$59,$f8), + ($37,$bf,$73,$c7), ($3a,$b4,$7d,$ce), ($2d,$a9,$6f,$d5), ($20,$a2,$61,$dc), + ($6d,$f6,$ad,$76), ($60,$fd,$a3,$7f), ($77,$e0,$b1,$64), ($7a,$eb,$bf,$6d), + ($59,$da,$95,$52), ($54,$d1,$9b,$5b), ($43,$cc,$89,$40), ($4e,$c7,$87,$49), + ($05,$ae,$dd,$3e), ($08,$a5,$d3,$37), ($1f,$b8,$c1,$2c), ($12,$b3,$cf,$25), + ($31,$82,$e5,$1a), ($3c,$89,$eb,$13), ($2b,$94,$f9,$08), ($26,$9f,$f7,$01), + ($bd,$46,$4d,$e6), ($b0,$4d,$43,$ef), ($a7,$50,$51,$f4), ($aa,$5b,$5f,$fd), + ($89,$6a,$75,$c2), ($84,$61,$7b,$cb), ($93,$7c,$69,$d0), ($9e,$77,$67,$d9), + ($d5,$1e,$3d,$ae), ($d8,$15,$33,$a7), ($cf,$08,$21,$bc), ($c2,$03,$2f,$b5), + ($e1,$32,$05,$8a), ($ec,$39,$0b,$83), ($fb,$24,$19,$98), ($f6,$2f,$17,$91), + ($d6,$8d,$76,$4d), ($db,$86,$78,$44), ($cc,$9b,$6a,$5f), ($c1,$90,$64,$56), + ($e2,$a1,$4e,$69), ($ef,$aa,$40,$60), ($f8,$b7,$52,$7b), ($f5,$bc,$5c,$72), + ($be,$d5,$06,$05), ($b3,$de,$08,$0c), ($a4,$c3,$1a,$17), ($a9,$c8,$14,$1e), + ($8a,$f9,$3e,$21), ($87,$f2,$30,$28), ($90,$ef,$22,$33), ($9d,$e4,$2c,$3a), + ($06,$3d,$96,$dd), ($0b,$36,$98,$d4), ($1c,$2b,$8a,$cf), ($11,$20,$84,$c6), + ($32,$11,$ae,$f9), ($3f,$1a,$a0,$f0), ($28,$07,$b2,$eb), ($25,$0c,$bc,$e2), + ($6e,$65,$e6,$95), ($63,$6e,$e8,$9c), ($74,$73,$fa,$87), ($79,$78,$f4,$8e), + ($5a,$49,$de,$b1), ($57,$42,$d0,$b8), ($40,$5f,$c2,$a3), ($4d,$54,$cc,$aa), + ($da,$f7,$41,$ec), ($d7,$fc,$4f,$e5), ($c0,$e1,$5d,$fe), ($cd,$ea,$53,$f7), + ($ee,$db,$79,$c8), ($e3,$d0,$77,$c1), ($f4,$cd,$65,$da), ($f9,$c6,$6b,$d3), + ($b2,$af,$31,$a4), ($bf,$a4,$3f,$ad), ($a8,$b9,$2d,$b6), ($a5,$b2,$23,$bf), + ($86,$83,$09,$80), ($8b,$88,$07,$89), ($9c,$95,$15,$92), ($91,$9e,$1b,$9b), + ($0a,$47,$a1,$7c), ($07,$4c,$af,$75), ($10,$51,$bd,$6e), ($1d,$5a,$b3,$67), + ($3e,$6b,$99,$58), ($33,$60,$97,$51), ($24,$7d,$85,$4a), ($29,$76,$8b,$43), + ($62,$1f,$d1,$34), ($6f,$14,$df,$3d), ($78,$09,$cd,$26), ($75,$02,$c3,$2f), + ($56,$33,$e9,$10), ($5b,$38,$e7,$19), ($4c,$25,$f5,$02), ($41,$2e,$fb,$0b), + ($61,$8c,$9a,$d7), ($6c,$87,$94,$de), ($7b,$9a,$86,$c5), ($76,$91,$88,$cc), + ($55,$a0,$a2,$f3), ($58,$ab,$ac,$fa), ($4f,$b6,$be,$e1), ($42,$bd,$b0,$e8), + ($09,$d4,$ea,$9f), ($04,$df,$e4,$96), ($13,$c2,$f6,$8d), ($1e,$c9,$f8,$84), + ($3d,$f8,$d2,$bb), ($30,$f3,$dc,$b2), ($27,$ee,$ce,$a9), ($2a,$e5,$c0,$a0), + ($b1,$3c,$7a,$47), ($bc,$37,$74,$4e), ($ab,$2a,$66,$55), ($a6,$21,$68,$5c), + ($85,$10,$42,$63), ($88,$1b,$4c,$6a), ($9f,$06,$5e,$71), ($92,$0d,$50,$78), + ($d9,$64,$0a,$0f), ($d4,$6f,$04,$06), ($c3,$72,$16,$1d), ($ce,$79,$18,$14), + ($ed,$48,$32,$2b), ($e0,$43,$3c,$22), ($f7,$5e,$2e,$39), ($fa,$55,$20,$30), + ($b7,$01,$ec,$9a), ($ba,$0a,$e2,$93), ($ad,$17,$f0,$88), ($a0,$1c,$fe,$81), + ($83,$2d,$d4,$be), ($8e,$26,$da,$b7), ($99,$3b,$c8,$ac), ($94,$30,$c6,$a5), + ($df,$59,$9c,$d2), ($d2,$52,$92,$db), ($c5,$4f,$80,$c0), ($c8,$44,$8e,$c9), + ($eb,$75,$a4,$f6), ($e6,$7e,$aa,$ff), ($f1,$63,$b8,$e4), ($fc,$68,$b6,$ed), + ($67,$b1,$0c,$0a), ($6a,$ba,$02,$03), ($7d,$a7,$10,$18), ($70,$ac,$1e,$11), + ($53,$9d,$34,$2e), ($5e,$96,$3a,$27), ($49,$8b,$28,$3c), ($44,$80,$26,$35), + ($0f,$e9,$7c,$42), ($02,$e2,$72,$4b), ($15,$ff,$60,$50), ($18,$f4,$6e,$59), + ($3b,$c5,$44,$66), ($36,$ce,$4a,$6f), ($21,$d3,$58,$74), ($2c,$d8,$56,$7d), + ($0c,$7a,$37,$a1), ($01,$71,$39,$a8), ($16,$6c,$2b,$b3), ($1b,$67,$25,$ba), + ($38,$56,$0f,$85), ($35,$5d,$01,$8c), ($22,$40,$13,$97), ($2f,$4b,$1d,$9e), + ($64,$22,$47,$e9), ($69,$29,$49,$e0), ($7e,$34,$5b,$fb), ($73,$3f,$55,$f2), + ($50,$0e,$7f,$cd), ($5d,$05,$71,$c4), ($4a,$18,$63,$df), ($47,$13,$6d,$d6), + ($dc,$ca,$d7,$31), ($d1,$c1,$d9,$38), ($c6,$dc,$cb,$23), ($cb,$d7,$c5,$2a), + ($e8,$e6,$ef,$15), ($e5,$ed,$e1,$1c), ($f2,$f0,$f3,$07), ($ff,$fb,$fd,$0e), + ($b4,$92,$a7,$79), ($b9,$99,$a9,$70), ($ae,$84,$bb,$6b), ($a3,$8f,$b5,$62), + ($80,$be,$9f,$5d), ($8d,$b5,$91,$54), ($9a,$a8,$83,$4f), ($97,$a3,$8d,$46)); + U4: array[0..255,0..3] of byte= ( + ($00,$00,$00,$00), ($09,$0d,$0b,$0e), ($12,$1a,$16,$1c), ($1b,$17,$1d,$12), + ($24,$34,$2c,$38), ($2d,$39,$27,$36), ($36,$2e,$3a,$24), ($3f,$23,$31,$2a), + ($48,$68,$58,$70), ($41,$65,$53,$7e), ($5a,$72,$4e,$6c), ($53,$7f,$45,$62), + ($6c,$5c,$74,$48), ($65,$51,$7f,$46), ($7e,$46,$62,$54), ($77,$4b,$69,$5a), + ($90,$d0,$b0,$e0), ($99,$dd,$bb,$ee), ($82,$ca,$a6,$fc), ($8b,$c7,$ad,$f2), + ($b4,$e4,$9c,$d8), ($bd,$e9,$97,$d6), ($a6,$fe,$8a,$c4), ($af,$f3,$81,$ca), + ($d8,$b8,$e8,$90), ($d1,$b5,$e3,$9e), ($ca,$a2,$fe,$8c), ($c3,$af,$f5,$82), + ($fc,$8c,$c4,$a8), ($f5,$81,$cf,$a6), ($ee,$96,$d2,$b4), ($e7,$9b,$d9,$ba), + ($3b,$bb,$7b,$db), ($32,$b6,$70,$d5), ($29,$a1,$6d,$c7), ($20,$ac,$66,$c9), + ($1f,$8f,$57,$e3), ($16,$82,$5c,$ed), ($0d,$95,$41,$ff), ($04,$98,$4a,$f1), + ($73,$d3,$23,$ab), ($7a,$de,$28,$a5), ($61,$c9,$35,$b7), ($68,$c4,$3e,$b9), + ($57,$e7,$0f,$93), ($5e,$ea,$04,$9d), ($45,$fd,$19,$8f), ($4c,$f0,$12,$81), + ($ab,$6b,$cb,$3b), ($a2,$66,$c0,$35), ($b9,$71,$dd,$27), ($b0,$7c,$d6,$29), + ($8f,$5f,$e7,$03), ($86,$52,$ec,$0d), ($9d,$45,$f1,$1f), ($94,$48,$fa,$11), + ($e3,$03,$93,$4b), ($ea,$0e,$98,$45), ($f1,$19,$85,$57), ($f8,$14,$8e,$59), + ($c7,$37,$bf,$73), ($ce,$3a,$b4,$7d), ($d5,$2d,$a9,$6f), ($dc,$20,$a2,$61), + ($76,$6d,$f6,$ad), ($7f,$60,$fd,$a3), ($64,$77,$e0,$b1), ($6d,$7a,$eb,$bf), + ($52,$59,$da,$95), ($5b,$54,$d1,$9b), ($40,$43,$cc,$89), ($49,$4e,$c7,$87), + ($3e,$05,$ae,$dd), ($37,$08,$a5,$d3), ($2c,$1f,$b8,$c1), ($25,$12,$b3,$cf), + ($1a,$31,$82,$e5), ($13,$3c,$89,$eb), ($08,$2b,$94,$f9), ($01,$26,$9f,$f7), + ($e6,$bd,$46,$4d), ($ef,$b0,$4d,$43), ($f4,$a7,$50,$51), ($fd,$aa,$5b,$5f), + ($c2,$89,$6a,$75), ($cb,$84,$61,$7b), ($d0,$93,$7c,$69), ($d9,$9e,$77,$67), + ($ae,$d5,$1e,$3d), ($a7,$d8,$15,$33), ($bc,$cf,$08,$21), ($b5,$c2,$03,$2f), + ($8a,$e1,$32,$05), ($83,$ec,$39,$0b), ($98,$fb,$24,$19), ($91,$f6,$2f,$17), + ($4d,$d6,$8d,$76), ($44,$db,$86,$78), ($5f,$cc,$9b,$6a), ($56,$c1,$90,$64), + ($69,$e2,$a1,$4e), ($60,$ef,$aa,$40), ($7b,$f8,$b7,$52), ($72,$f5,$bc,$5c), + ($05,$be,$d5,$06), ($0c,$b3,$de,$08), ($17,$a4,$c3,$1a), ($1e,$a9,$c8,$14), + ($21,$8a,$f9,$3e), ($28,$87,$f2,$30), ($33,$90,$ef,$22), ($3a,$9d,$e4,$2c), + ($dd,$06,$3d,$96), ($d4,$0b,$36,$98), ($cf,$1c,$2b,$8a), ($c6,$11,$20,$84), + ($f9,$32,$11,$ae), ($f0,$3f,$1a,$a0), ($eb,$28,$07,$b2), ($e2,$25,$0c,$bc), + ($95,$6e,$65,$e6), ($9c,$63,$6e,$e8), ($87,$74,$73,$fa), ($8e,$79,$78,$f4), + ($b1,$5a,$49,$de), ($b8,$57,$42,$d0), ($a3,$40,$5f,$c2), ($aa,$4d,$54,$cc), + ($ec,$da,$f7,$41), ($e5,$d7,$fc,$4f), ($fe,$c0,$e1,$5d), ($f7,$cd,$ea,$53), + ($c8,$ee,$db,$79), ($c1,$e3,$d0,$77), ($da,$f4,$cd,$65), ($d3,$f9,$c6,$6b), + ($a4,$b2,$af,$31), ($ad,$bf,$a4,$3f), ($b6,$a8,$b9,$2d), ($bf,$a5,$b2,$23), + ($80,$86,$83,$09), ($89,$8b,$88,$07), ($92,$9c,$95,$15), ($9b,$91,$9e,$1b), + ($7c,$0a,$47,$a1), ($75,$07,$4c,$af), ($6e,$10,$51,$bd), ($67,$1d,$5a,$b3), + ($58,$3e,$6b,$99), ($51,$33,$60,$97), ($4a,$24,$7d,$85), ($43,$29,$76,$8b), + ($34,$62,$1f,$d1), ($3d,$6f,$14,$df), ($26,$78,$09,$cd), ($2f,$75,$02,$c3), + ($10,$56,$33,$e9), ($19,$5b,$38,$e7), ($02,$4c,$25,$f5), ($0b,$41,$2e,$fb), + ($d7,$61,$8c,$9a), ($de,$6c,$87,$94), ($c5,$7b,$9a,$86), ($cc,$76,$91,$88), + ($f3,$55,$a0,$a2), ($fa,$58,$ab,$ac), ($e1,$4f,$b6,$be), ($e8,$42,$bd,$b0), + ($9f,$09,$d4,$ea), ($96,$04,$df,$e4), ($8d,$13,$c2,$f6), ($84,$1e,$c9,$f8), + ($bb,$3d,$f8,$d2), ($b2,$30,$f3,$dc), ($a9,$27,$ee,$ce), ($a0,$2a,$e5,$c0), + ($47,$b1,$3c,$7a), ($4e,$bc,$37,$74), ($55,$ab,$2a,$66), ($5c,$a6,$21,$68), + ($63,$85,$10,$42), ($6a,$88,$1b,$4c), ($71,$9f,$06,$5e), ($78,$92,$0d,$50), + ($0f,$d9,$64,$0a), ($06,$d4,$6f,$04), ($1d,$c3,$72,$16), ($14,$ce,$79,$18), + ($2b,$ed,$48,$32), ($22,$e0,$43,$3c), ($39,$f7,$5e,$2e), ($30,$fa,$55,$20), + ($9a,$b7,$01,$ec), ($93,$ba,$0a,$e2), ($88,$ad,$17,$f0), ($81,$a0,$1c,$fe), + ($be,$83,$2d,$d4), ($b7,$8e,$26,$da), ($ac,$99,$3b,$c8), ($a5,$94,$30,$c6), + ($d2,$df,$59,$9c), ($db,$d2,$52,$92), ($c0,$c5,$4f,$80), ($c9,$c8,$44,$8e), + ($f6,$eb,$75,$a4), ($ff,$e6,$7e,$aa), ($e4,$f1,$63,$b8), ($ed,$fc,$68,$b6), + ($0a,$67,$b1,$0c), ($03,$6a,$ba,$02), ($18,$7d,$a7,$10), ($11,$70,$ac,$1e), + ($2e,$53,$9d,$34), ($27,$5e,$96,$3a), ($3c,$49,$8b,$28), ($35,$44,$80,$26), + ($42,$0f,$e9,$7c), ($4b,$02,$e2,$72), ($50,$15,$ff,$60), ($59,$18,$f4,$6e), + ($66,$3b,$c5,$44), ($6f,$36,$ce,$4a), ($74,$21,$d3,$58), ($7d,$2c,$d8,$56), + ($a1,$0c,$7a,$37), ($a8,$01,$71,$39), ($b3,$16,$6c,$2b), ($ba,$1b,$67,$25), + ($85,$38,$56,$0f), ($8c,$35,$5d,$01), ($97,$22,$40,$13), ($9e,$2f,$4b,$1d), + ($e9,$64,$22,$47), ($e0,$69,$29,$49), ($fb,$7e,$34,$5b), ($f2,$73,$3f,$55), + ($cd,$50,$0e,$7f), ($c4,$5d,$05,$71), ($df,$4a,$18,$63), ($d6,$47,$13,$6d), + ($31,$dc,$ca,$d7), ($38,$d1,$c1,$d9), ($23,$c6,$dc,$cb), ($2a,$cb,$d7,$c5), + ($15,$e8,$e6,$ef), ($1c,$e5,$ed,$e1), ($07,$f2,$f0,$f3), ($0e,$ff,$fb,$fd), + ($79,$b4,$92,$a7), ($70,$b9,$99,$a9), ($6b,$ae,$84,$bb), ($62,$a3,$8f,$b5), + ($5d,$80,$be,$9f), ($54,$8d,$b5,$91), ($4f,$9a,$a8,$83), ($46,$97,$a3,$8d)); + + rcon: array[0..29] of cardinal= ( + $01, $02, $04, $08, $10, $20, $40, $80, $1b, $36, $6c, $d8, $ab, $4d, $9a, + $2f, $5e, $bc, $63, $c6, $97, $35, $6a, $d4, $b3, $7d, $fa, $ef, $c5, $91); + \ No newline at end of file diff --git a/CORE/Source/Includes/SynEdit.inc b/CORE/Source/Includes/SynEdit.inc new file mode 100644 index 000000000..2bfa86ef3 --- /dev/null +++ b/CORE/Source/Includes/SynEdit.inc @@ -0,0 +1,1425 @@ +(******************************************************************************) +(* SynEdit Include File. This file was adapted from Brad Stowers' DFS.INC *) +(* file and used with permission. This will help reduce headaches when new *) +(* versions of Delphi and C++Builder are released, among other things. *) +(******************************************************************************) +(* Brad Stowers: bstowers@pobox.com *) +(* Delphi Free Stuff: http://delphifreestuff.com/ *) +(* February 24, 1999 *) +(******************************************************************************) +(* *) +(* Complete Boolean Evaluation compiler directive is turned off by including *) +(* this file. *) +(* The $ObjExportAll directive is turned on if compiling with C++Builder 3 or *) +(* higher. This is required for Delphi components built in Builder with *) +(* run-time packages. *) +(* *) +(* Here is a brief explanation of what each of the defines mean: *) +(* SYN_WIN32 : Compilation target is 32-bit Windows *) +(* SYN_COMPILER_2 : Delphi 2 or C++Builder 1 is the compiler. *) +(* SYN_COMPILER_2_UP : Delphi 2 or higher, or C++Builder 1 or higher is *) +(* the compiler. *) +(* SYN_COMPILER_3 : Delphi 3 or C++Builder 3 is the compiler. *) +(* SYN_COMPILER_3_UP : Delphi 3 or higher, or C++Builder 3 or higher is *) +(* the compiler. *) +(* SYN_COMPILER_4 : Delphi 4 or C++Builder 4 is the compiler. *) +(* SYN_COMPILER_4_UP : Delphi 4 or higher, or C++Builder 4 or higher is *) +(* the compiler. *) +(* SYN_COMPILER_5 : Delphi 5 or C++Builder 5 is the compiler. *) +(* SYN_COMPILER_5_UP : Delphi 5 or higher, or C++Builder 5 or higher is *) +(* the compiler. *) +(* SYN_COMPILER_6 : Delphi 6, C++Builder 6, Kylix 1 or Kylix 2 is *) +(* the compiler. *) +(* SYN_COMPILER_6_UP : Delphi 6, C++Builder 6, Kylix 1, Kylix 2 or higher *) +(* is the compiler. *) +(* SYN_COMPILER_7 : Delphi 7 or Kylix 3 is the compiler. *) +(* SYN_COMPILER_7_UP : Delphi 7, Kylix 3 or higher is the compiler. *) +(* SYN_COMPILER_9 : Delphi 2005 is the compiler. *) +(* SYN_COMPILER_9_UP : Delphi 2005 or higher is the compiler. *) +(* SYN_COMPILER_10 : Delphi 2006 is the compiler. *) +(* SYN_COMPILER_10_UP : Delphi 2006 or higher is the compiler. *) +(* SYN_COMPILER_11 : Delphi 2007 is the compiler. *) +(* SYN_COMPILER_11_UP : Delphi 2007 or higher is the compiler. *) +(* SYN_COMPILER_12 : Delphi 2009 is the compiler. *) +(* SYN_COMPILER_12_UP : Delphi 2009 or higher is the compiler. *) +(* SYN_COMPILER_14 : Delphi 2010 is the compiler. *) +(* SYN_COMPILER_14_UP : Delphi 2010 or higher is the compiler. *) +(* SYN_COMPILER_15 : Delphi XE is the compiler. *) +(* SYN_COMPILER_15_UP : Delphi XE or higher is the compiler. *) +(* SYN_COMPILER_16 : Delphi XE2 is the compiler. *) +(* SYN_COMPILER_16_UP : Delphi XE2 or higher is the compiler. *) +(* SYN_COMPILER_17 : Delphi XE3 is the compiler. *) +(* SYN_COMPILER_17_UP : Delphi XE3 or higher is the compiler. *) +(* SYN_COMPILER_18 : Delphi XE4 is the compiler. *) +(* SYN_COMPILER_18_UP : Delphi XE4 or higher is the compiler. *) +(* SYN_COMPILER_19 : Delphi XE5 is the compiler. *) +(* SYN_COMPILER_19_UP : Delphi XE5 or higher is the compiler. *) +(* SYN_COMPILER_20 : Delphi XE6 is the compiler. *) +(* SYN_COMPILER_20_UP : Delphi XE6 or higher is the compiler. *) +(* SYN_COMPILER_21 : Delphi XE7 is the compiler. *) +(* SYN_COMPILER_21_UP : Delphi XE7 or higher is the compiler. *) +(* SYN_COMPILER_22 : Delphi XE8 is the compiler. *) +(* SYN_COMPILER_22_UP : Delphi XE8 or higher is the compiler. *) +(* SYN_CPPB : Any version of C++Builder is being used. *) +(* SYN_CPPB_1 : C++B v1.0x is being used. *) +(* SYN_CPPB_3 : C++B v3.0x is being used. *) +(* SYN_CPPB_3_UP : C++B v3.0x or higher is being used. *) +(* SYN_CPPB_4 : C++B v4.0x is being used. *) +(* SYN_CPPB_4_UP : C++B v4.0x or higher is being used. *) +(* SYN_CPPB_5 : C++B v5.0x is being used. *) +(* SYN_CPPB_5_UP : C++B v5.0x or higher is being used. *) +(* SYN_CPPB_6 : C++B v6.0x is being used. *) +(* SYN_CPPB_6_UP : C++B v6.0x or higher is being used. *) +(* SYN_DELPHI : Any version of Delphi is being used. *) +(* SYN_DELPHI_PE : The personal edition of Delphi is being used. *) +(* SYN_DELPHI_2 : Delphi 2 is being used. *) +(* SYN_DELPHI_2_UP : Delphi 2 or higher is being used. *) +(* SYN_DELPHI_3 : Delphi 3 is being used. *) +(* SYN_DELPHI_3_UP : Delphi 3 or higher is being used. *) +(* SYN_DELPHI_4 : Delphi 4 is being used. *) +(* SYN_DELPHI_4_UP : Delphi 4 or higher is being used. *) +(* SYN_DELPHI_5 : Delphi 5 is being used. *) +(* SYN_DELPHI_5_UP : Delphi 5 or higher is being used. *) +(* SYN_DELPHI_6 : Delphi 6 is being used. *) +(* SYN_DELPHI_6_UP : Delphi 6 or higher is being used. *) +(* SYN_DELPHI_7 : Delphi 7 is being used. *) +(* SYN_DELPHI_7_UP : Delphi 7 or higher is being used. *) +(* SYN_DELPHI_8 : Delphi 8 is being used. *) +(* SYN_DELPHI_8_UP : Delphi 8 or higher is being used. *) +(* SYN_DELPHI_2005 : Delphi 2005 is being used. *) +(* SYN_DELPHI_2005_UP : Delphi 2005 or higher is being used. *) +(* SYN_DELPHI_2006 : Delphi 2006 is being used. *) +(* SYN_DELPHI_2006_UP : Delphi 2006 or higher is being used. *) +(* SYN_DELPHI_2007 : Delphi 2007 is being used. *) +(* SYN_DELPHI_2007_UP : Delphi 2007 or higher is being used. *) +(* SYN_DELPHI_2009 : Delphi 2009 is being used. *) +(* SYN_DELPHI_2009_UP : Delphi 2009 or higher is being used. *) +(* SYN_DELPHI_2010 : Delphi 2010 is being used. *) +(* SYN_DELPHI_2010_UP : Delphi 2010 or higher is being used. *) +(* SYN_DELPHI_XE : Delphi XE is being used. *) +(* SYN_DELPHI_XE_UP : Delphi XE or higher is being used. *) +(* SYN_DELPHI_XE2 : Delphi XE2 is being used. *) +(* SYN_DELPHI_XE2_UP : Delphi XE2 or higher is being used. *) +(* SYN_DELPHI_XE3 : Delphi XE3 is being used. *) +(* SYN_DELPHI_XE3_UP : Delphi XE3 or higher is being used. *) +(* SYN_DELPHI_XE4 : Delphi XE4 is being used. *) +(* SYN_DELPHI_XE4_UP : Delphi XE4 or higher is being used. *) +(* SYN_DELPHI_XE5 : Delphi XE5 is being used. *) +(* SYN_DELPHI_XE5_UP : Delphi XE5 or higher is being used. *) +(* SYN_DELPHI_XE6 : Delphi XE6 is being used. *) +(* SYN_DELPHI_XE6_UP : Delphi XE6 or higher is being used. *) +(* SYN_DELPHI_XE7 : Delphi XE7 is being used. *) +(* SYN_DELPHI_XE7_UP : Delphi XE7 or higher is being used. *) +(* SYN_DELPHI_XE8 : Delphi XE8 is being used. *) +(* SYN_DELPHI_XE8_UP : Delphi XE8 or higher is being used. *) +(* SYN_DELPHI_10 : Delphi RX 10 (Seattle) is being used. *) +(* SYN_DELPHI_10_UP : Delphi RX 10 or higher is being used. *) +(* SYN_DELPHI_10_1 : Delphi RX 10.1 (Berlin) is being used. *) +(* SYN_DELPHI_10_1_UP : Delphi RX 10.1 or higher is being used. *) +(* SYN_DELPHI_10_2 : Delphi RX 10.2 (Tokyo) is being used. *) +(* SYN_DELPHI_10_2_UP : Delphi RX 10.2 or higher is being used. *) +(* SYN_DELPHI_10_3 : Delphi RX 10.3 (Rio) is being used. *) +(* SYN_DELPHI_10_3_UP : Delphi RX 10.3 or higher is being used. *) +(* SYN_KYLIX : Kylix 1.0 is being using. *) +(******************************************************************************) + +{$DEFINE SYNEDIT_INCLUDE} + +{------------------------------------------------------------------------------} +{ Common compiler defines } +{ (remove the dot in front of a define to enable it) } +{------------------------------------------------------------------------------} + +{$B-,H+} // defaults are short evaluation of boolean values and long strings + +{.$DEFINE SYN_DEVELOPMENT_CHECKS} // additional tests for debugging +{$IFDEF SYN_DEVELOPMENT_CHECKS} + {$R+,Q+,S+,T+} +{$ENDIF} + +{------------------------------------------------------------------------------} +{ Pull in all defines from SynEditJedi.inc (must be done after the common } +{ compiler defines to work correctly). Use SynEdit-prefix to avoid problems } +{ with other versions of jedi.inc in the search-path. } +{------------------------------------------------------------------------------} + +{$I SynEditJedi.inc} + +{------------------------------------------------------------------------------} +{ SYN_LINUX and SYN_KYLIX defines } +{------------------------------------------------------------------------------} + +{$IFDEF LINUX} + {$DEFINE SYN_LINUX} + {$DEFINE SYN_KYLIX} + {$DEFINE SYN_COMPILER_6} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_6} +{$ENDIF} + +{------------------------------------------------------------------------------} +{ VERXXX to SYN_COMPILERX, SYN_DELPHIX and SYN_CPPBX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF VER370} + {$DEFINE SYN_COMPILER_37} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_13_0} +{$ENDIF} + +{$IFDEF VER360} + {$DEFINE SYN_COMPILER_29} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_12_0} +{$ENDIF} + +{$IFDEF VER350} + {$DEFINE SYN_COMPILER_28} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_11_0} +{$ENDIF} + +{$IFDEF VER340} + {$DEFINE SYN_COMPILER_27} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_10_4} +{$ENDIF} + +{$IFDEF VER330} + {$DEFINE SYN_COMPILER_26} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_10_3} +{$ENDIF} + +{$IFDEF VER320} + {$DEFINE SYN_COMPILER_25} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_10_2} +{$ENDIF} + +{$IFDEF VER310} + {$DEFINE SYN_COMPILER_24} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_10_1} +{$ENDIF} + +{$IFDEF VER300} + {$DEFINE SYN_COMPILER_23} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_10} +{$ENDIF} + +{$IFDEF VER290} + {$DEFINE SYN_COMPILER_22} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_XE8} +{$ENDIF} + +{$IFDEF VER280} + {$DEFINE SYN_COMPILER_21} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_XE7} +{$ENDIF} + +{$IFDEF VER270} + {$DEFINE SYN_COMPILER_20} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_XE6} +{$ENDIF} + +{$IFDEF VER260} + {$DEFINE SYN_COMPILER_19} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_XE5} +{$ENDIF} + +{$IFDEF VER250} + {$DEFINE SYN_COMPILER_18} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_XE4} +{$ENDIF} + +{$IFDEF VER240} + {$DEFINE SYN_COMPILER_17} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_XE3} +{$ENDIF} + +{$IFDEF VER230} + {$DEFINE SYN_COMPILER_16} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_XE2} +{$ENDIF} + +{$IFDEF VER220} + {$DEFINE SYN_COMPILER_15} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_XE} +{$ENDIF} + +{$IFDEF VER210} + {$DEFINE SYN_COMPILER_14} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_2010} +{$ENDIF} + +{$IFDEF VER200} + {$DEFINE SYN_COMPILER_12} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_2009} +{$ENDIF} + +{$IFDEF VER190} + {$DEFINE SYN_COMPILER_11} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_2007} +{$ENDIF} + +{$IFDEF VER180} + {$DEFINE SYN_COMPILER_10} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_2006} +{$ENDIF} + +{$IFDEF VER170} + {$DEFINE SYN_COMPILER_9} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_2005} +{$ENDIF} + +{$IFDEF VER160} + {$DEFINE SYN_COMPILER_8} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_8} +{$ENDIF} + +{$IFDEF VER150} + {$DEFINE SYN_COMPILER_7} + {$IFNDEF BCB} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_7} + {$ELSE} + {.$DEFINE SYN_CPPB} + {.$DEFINE SYN_CPPB_7} + {$ENDIF} +{$ENDIF} + +{$IFDEF VER140} + {$DEFINE SYN_COMPILER_6} + {$IFNDEF BCB} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_6} + {$ELSE} + {$DEFINE SYN_CPPB} + {$DEFINE SYN_CPPB_6} + {$ENDIF} +{$ENDIF} + +{$IFDEF VER130} + {$DEFINE SYN_COMPILER_5} + {$IFNDEF BCB} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_5} + {$ELSE} + {$DEFINE SYN_CPPB} + {$DEFINE SYN_CPPB_5} + {$ENDIF} +{$ENDIF} + +{$IFDEF VER125} + {$DEFINE SYN_COMPILER_4} + {$DEFINE SYN_CPPB} + {$DEFINE SYN_CPPB_4} +{$ENDIF} + +{$IFDEF VER120} + {$DEFINE SYN_COMPILER_4} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_4} +{$ENDIF} + +{$IFDEF VER110} + {$DEFINE SYN_COMPILER_3} + {$DEFINE SYN_CPPB} + {$DEFINE SYN_CPPB_3} +{$ENDIF} + +{$IFDEF VER100} + {$DEFINE SYN_COMPILER_3} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_3} +{$ENDIF} + +{$IFDEF VER93} + {$DEFINE SYN_COMPILER_2} { C++B v1 compiler is really v2 } + {$DEFINE SYN_CPPB} + {$DEFINE SYN_CPPB_1} +{$ENDIF} + +{$IFDEF VER90} + {$DEFINE SYN_COMPILER_2} + {$DEFINE SYN_DELPHI} + {$DEFINE SYN_DELPHI_2} +{$ENDIF} + +{$IFDEF SYN_COMPILER_2} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_3} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_4} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_5} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_6} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_7} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_8} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_9} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_10} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_11} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_12} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_14} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_15} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_16} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_17} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_18} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_19} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_20} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_21} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_22} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} + {$DEFINE SYN_COMPILER_22_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_23} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} + {$DEFINE SYN_COMPILER_22_UP} + {$DEFINE SYN_COMPILER_23_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_24} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} + {$DEFINE SYN_COMPILER_22_UP} + {$DEFINE SYN_COMPILER_23_UP} + {$DEFINE SYN_COMPILER_24_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_25} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} + {$DEFINE SYN_COMPILER_22_UP} + {$DEFINE SYN_COMPILER_23_UP} + {$DEFINE SYN_COMPILER_24_UP} + {$DEFINE SYN_COMPILER_25_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_26} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} + {$DEFINE SYN_COMPILER_22_UP} + {$DEFINE SYN_COMPILER_23_UP} + {$DEFINE SYN_COMPILER_24_UP} + {$DEFINE SYN_COMPILER_25_UP} + {$DEFINE SYN_COMPILER_26_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_27} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} + {$DEFINE SYN_COMPILER_22_UP} + {$DEFINE SYN_COMPILER_23_UP} + {$DEFINE SYN_COMPILER_24_UP} + {$DEFINE SYN_COMPILER_25_UP} + {$DEFINE SYN_COMPILER_26_UP} + {$DEFINE SYN_COMPILER_27_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_28} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} + {$DEFINE SYN_COMPILER_22_UP} + {$DEFINE SYN_COMPILER_23_UP} + {$DEFINE SYN_COMPILER_24_UP} + {$DEFINE SYN_COMPILER_25_UP} + {$DEFINE SYN_COMPILER_26_UP} + {$DEFINE SYN_COMPILER_27_UP} + {$DEFINE SYN_COMPILER_28_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_29} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} + {$DEFINE SYN_COMPILER_22_UP} + {$DEFINE SYN_COMPILER_23_UP} + {$DEFINE SYN_COMPILER_24_UP} + {$DEFINE SYN_COMPILER_25_UP} + {$DEFINE SYN_COMPILER_26_UP} + {$DEFINE SYN_COMPILER_27_UP} + {$DEFINE SYN_COMPILER_28_UP} + {$DEFINE SYN_COMPILER_29_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_37} + {$DEFINE SYN_COMPILER_1_UP} + {$DEFINE SYN_COMPILER_2_UP} + {$DEFINE SYN_COMPILER_3_UP} + {$DEFINE SYN_COMPILER_4_UP} + {$DEFINE SYN_COMPILER_5_UP} + {$DEFINE SYN_COMPILER_6_UP} + {$DEFINE SYN_COMPILER_7_UP} + {$DEFINE SYN_COMPILER_8_UP} + {$DEFINE SYN_COMPILER_9_UP} + {$DEFINE SYN_COMPILER_10_UP} + {$DEFINE SYN_COMPILER_11_UP} + {$DEFINE SYN_COMPILER_12_UP} + {$DEFINE SYN_COMPILER_14_UP} + {$DEFINE SYN_COMPILER_15_UP} + {$DEFINE SYN_COMPILER_16_UP} + {$DEFINE SYN_COMPILER_17_UP} + {$DEFINE SYN_COMPILER_18_UP} + {$DEFINE SYN_COMPILER_19_UP} + {$DEFINE SYN_COMPILER_20_UP} + {$DEFINE SYN_COMPILER_21_UP} + {$DEFINE SYN_COMPILER_22_UP} + {$DEFINE SYN_COMPILER_23_UP} + {$DEFINE SYN_COMPILER_24_UP} + {$DEFINE SYN_COMPILER_25_UP} + {$DEFINE SYN_COMPILER_26_UP} + {$DEFINE SYN_COMPILER_27_UP} + {$DEFINE SYN_COMPILER_28_UP} + {$DEFINE SYN_COMPILER_29_UP} + {$DEFINE SYN_COMPILER_37_UP} +{$ENDIF} + + +{$IFDEF SYN_DELPHI_2} + {$DEFINE SYN_DELPHI_2_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_3} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_4} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_5} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_6} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_7} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_8} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_2005} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_2006} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_2007} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_2009} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_2010} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_XE} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_XE2} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_XE3} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_XE4} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_XE5} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_XE6} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_XE7} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_XE8} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} + {$DEFINE SYN_DELPHI_XE8_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_10} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} + {$DEFINE SYN_DELPHI_XE8_UP} + {$DEFINE SYN_DELPHI_10_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_10_1} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} + {$DEFINE SYN_DELPHI_XE8_UP} + {$DEFINE SYN_DELPHI_10_1_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_10_2} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} + {$DEFINE SYN_DELPHI_XE8_UP} + {$DEFINE SYN_DELPHI_10_1_UP} + {$DEFINE SYN_DELPHI_10_2_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_10_3} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} + {$DEFINE SYN_DELPHI_XE8_UP} + {$DEFINE SYN_DELPHI_10_1_UP} + {$DEFINE SYN_DELPHI_10_2_UP} + {$DEFINE SYN_DELPHI_10_3_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_10_4} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} + {$DEFINE SYN_DELPHI_XE8_UP} + {$DEFINE SYN_DELPHI_10_1_UP} + {$DEFINE SYN_DELPHI_10_2_UP} + {$DEFINE SYN_DELPHI_10_3_UP} + {$DEFINE SYN_DELPHI_10_4_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_11_0} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} + {$DEFINE SYN_DELPHI_XE8_UP} + {$DEFINE SYN_DELPHI_10_1_UP} + {$DEFINE SYN_DELPHI_10_2_UP} + {$DEFINE SYN_DELPHI_10_3_UP} + {$DEFINE SYN_DELPHI_10_4_UP} + {$DEFINE SYN_DELPHI_11_0_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_12_0} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} + {$DEFINE SYN_DELPHI_XE8_UP} + {$DEFINE SYN_DELPHI_10_1_UP} + {$DEFINE SYN_DELPHI_10_2_UP} + {$DEFINE SYN_DELPHI_10_3_UP} + {$DEFINE SYN_DELPHI_10_4_UP} + {$DEFINE SYN_DELPHI_11_0_UP} + {$DEFINE SYN_DELPHI_12_0_UP} +{$ENDIF} + +{$IFDEF SYN_DELPHI_13_0} + {$DEFINE SYN_DELPHI_2_UP} + {$DEFINE SYN_DELPHI_3_UP} + {$DEFINE SYN_DELPHI_4_UP} + {$DEFINE SYN_DELPHI_5_UP} + {$DEFINE SYN_DELPHI_6_UP} + {$DEFINE SYN_DELPHI_7_UP} + {$DEFINE SYN_DELPHI_8_UP} + {$DEFINE SYN_DELPHI_2005_UP} + {$DEFINE SYN_DELPHI_2006_UP} + {$DEFINE SYN_DELPHI_2007_UP} + {$DEFINE SYN_DELPHI_2009_UP} + {$DEFINE SYN_DELPHI_2010_UP} + {$DEFINE SYN_DELPHI_XE_UP} + {$DEFINE SYN_DELPHI_XE2_UP} + {$DEFINE SYN_DELPHI_XE3_UP} + {$DEFINE SYN_DELPHI_XE4_UP} + {$DEFINE SYN_DELPHI_XE5_UP} + {$DEFINE SYN_DELPHI_XE6_UP} + {$DEFINE SYN_DELPHI_XE7_UP} + {$DEFINE SYN_DELPHI_XE8_UP} + {$DEFINE SYN_DELPHI_10_1_UP} + {$DEFINE SYN_DELPHI_10_2_UP} + {$DEFINE SYN_DELPHI_10_3_UP} + {$DEFINE SYN_DELPHI_10_4_UP} + {$DEFINE SYN_DELPHI_11_0_UP} + {$DEFINE SYN_DELPHI_12_0_UP} + {$DEFINE SYN_DELPHI_13_0_UP} +{$ENDIF} + +{$IFDEF SYN_CPPB_6} + {$DEFINE SYN_CPPB_3_UP} + {$DEFINE SYN_CPPB_4_UP} + {$DEFINE SYN_CPPB_5_UP} + {$DEFINE SYN_CPPB_6_UP} +{$ENDIF} + +{$IFDEF SYN_CPPB_3} + {$DEFINE SYN_CPPB_3_UP} +{$ENDIF} + +{$IFDEF SYN_COMPILER_3_UP} + {$DEFINE SYN_NO_COM_CLEANUP} +{$ENDIF} + +{$IFDEF SYN_CPPB_3_UP} + // C++Builder requires this if you use Delphi components in run-time packages. + {$ObjExportAll On} +{$ENDIF} + +{------------------------------------------------------------------------------} +{ MSWINDOWS and SYN_WIN32 } +{------------------------------------------------------------------------------} + +{$IFDEF SYN_KYLIX} + Kylix is no longer supported. Please refer to the branch 'Kylix' +{$ELSE} + {$IFNDEF SYN_COMPILER_16_UP} + {$DEFINE MSWINOWS} + {$ENDIF} + {$DEFINE SYN_WIN32} // deprecated, do not use +{$ENDIF} + +{------------------------------------------------------------------------------} +{ Please change this to suit your needs (to activate an option remove the dot } +{ in front of a DEFINE) } +{------------------------------------------------------------------------------} + +// "Heredoc" syntax highlighting +// If you enable the following statement and use highlighter(s) that have +// support for "Heredoc" strings as scheme(s) in SynMultiSyn, you must +// implement your own SynMultiSyn OnCustomRange event handler in order to +// properly store Range State information +{.$DEFINE SYN_HEREDOC} + +// Define OWN_UnicodeString_MEMMGR to speed up WideStrings-handling +{$IFDEF MSWINOWS} + {$IFNDEF UNICODE} + {$DEFINE OWN_UnicodeString_MEMMGR} + {$ENDIF} +{$ENDIF} + +// Turn this off if you don't need complex script support, since it is slower +{-$DEFINE SYN_UNISCRIBE} + +// Code Folding +{$IFDEF SYN_DELPHI_XE_UP} + {$DEFINE SYN_CodeFolding} +{$ENDIF} diff --git a/CORE/Source/Includes/SynEditJedi.inc b/CORE/Source/Includes/SynEditJedi.inc new file mode 100644 index 000000000..7ac23f543 --- /dev/null +++ b/CORE/Source/Includes/SynEditJedi.inc @@ -0,0 +1,1182 @@ +{$IFNDEF JEDI_INC} +{$DEFINE JEDI_INC} + +{**************************************************************************************************} +{ } +{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License");} +{ you may not use this file except in compliance with the License. You may obtain a copy of the } +{ License at http://www.mozilla.org/MPL/ } +{ } +{ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF } +{ ANY KIND, either express or implied. See the License for the specific language governing rights } +{ and limitations under the License. } +{ } +{ The Original Code is: jedi.inc. } +{ The Initial Developer of the Original Code is Project JEDI http://www.delphi-jedi.org } +{ } +{ Alternatively, the contents of this file may be used under the terms of the GNU Lesser General } +{ Public License (the "LGPL License"), in which case the provisions of the LGPL License are } +{ applicable instead of those above. If you wish to allow use of your version of this file only } +{ under the terms of the LGPL License and not to allow others to use your version of this file } +{ under the MPL, indicate your decision by deleting the provisions above and replace them with } +{ the notice and other provisions required by the LGPL License. If you do not delete the } +{ provisions above, a recipient may use your version of this file under either the MPL or the } +{ LGPL License. } +{ } +{ For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html } +{ } +{**************************************************************************************************} +{ } +{ This file defines various generic compiler directives used in different libraries, e.g. in the } +{ JEDI Code Library (JCL) and JEDI Visual Component Library Library (JVCL). The directives in } +{ this file are of generic nature and consist mostly of mappings from the VERXXX directives } +{ defined by Delphi, C++ Builder and FPC to friendly names such as DELPHI5 and } +{ SUPPORTS_WIDESTRING. These friendly names are subsequently used in the libraries to test for } +{ compiler versions and/or whether the compiler supports certain features (such as widestrings or } +{ 64 bit integers. The libraries provide an additional, library specific, include file. For the } +{ JCL e.g. this is jcl.inc. These files should be included in source files instead of this file } +{ (which is pulled in automatically). } +{ } +{**************************************************************************************************} +{ } +{ Last modified: $Date: 2009/01/06 16:26:01 $ } +{ Revision: $Rev:: 2446 $ } +{ Author: $Author: maelh $ } +{ } +{**************************************************************************************************} + +(* + +- Development environment directives + + This file defines two directives to indicate which development environment the + library is being compiled with. Currently this can either be Delphi, Kylix, + C++ Builder or FPC. + + Directive Description + ------------------------------------------------------------------------------ + DELPHI Defined if compiled with Delphi + KYLIX Defined if compiled with Kylix + DELPHICOMPILER Defined if compiled with Delphi or Kylix/Delphi + BCB Defined if compiled with C++ Builder + CPPBUILDER Defined if compiled with C++ Builder (alias for BCB) + BCBCOMPILER Defined if compiled with C++ Builder or Kylix/C++ + DELPHILANGUAGE Defined if compiled with Delphi, Kylix or C++ Builder + BORLAND Defined if compiled with Delphi, Kylix or C++ Builder + FPC Defined if compiled with FPC + +- Platform Directives + + Platform directives are not all explicitly defined in this file, some are + defined by the compiler itself. They are listed here only for completeness. + + Directive Description + ------------------------------------------------------------------------------ + WIN32 Defined when target platform is 32 bit Windows + WIN64 Defined when target platform is 64 bit Windows + MSWINDOWS Defined when target platform is 32 bit Windows + LINUX Defined when target platform is Linux + UNIX Defined when target platform is Unix-like (including Linux) + CLR Defined when target platform is .NET + +- Architecture directives. These are auto-defined by FPC + CPU32 and CPU64 are mostly for generic pointer size dependant differences rather + than for a specific architecture. + + CPU386 Defined when target platform is native x86 (win32) + CPUx86_64 Defined when target platform is native x86_64 (win64) + CPU32 Defined when target is 32-bit + CPU64 Defined when target is 64-bit + +- Visual library Directives + + The following directives indicate for a visual library. In a Delphi/BCB + (Win32) application you need to define the VisualCLX symbol in the project + options, if you want to use the VisualCLX library. Alternatively you can use + the IDE expert, which is distributed with the JCL to do this automatically. + + Directive Description + ------------------------------------------------------------------------------ + VCL Defined for Delphi/BCB (Win32) exactly if VisualCLX is not defined + VisualCLX Defined for Kylix; needs to be defined for Delphi/BCB to + use JCL with VisualCLX applications. + + +- Other cross-platform related defines + + These symbols are intended to help in writing portable code. + + Directive Description + ------------------------------------------------------------------------------ + PUREPASCAL Code is machine-independent (as opposed to assembler code) + Win32API Code is specific for the Win32 API; + use instead of "{$IFNDEF CLR} {$IFDEF MSWINDOWS}" constructs + + +- Delphi Versions + + The following directives are direct mappings from the VERXXX directives to a + friendly name of the associated compiler. These directives are only defined if + the compiler is Delphi (ie DELPHI is defined). + + Directive Description + ------------------------------------------------------------------------------ + DELPHI1 Defined when compiling with Delphi 1 + DELPHI2 Defined when compiling with Delphi 2 + DELPHI3 Defined when compiling with Delphi 3 + DELPHI4 Defined when compiling with Delphi 4 + DELPHI5 Defined when compiling with Delphi 5 + DELPHI6 Defined when compiling with Delphi 6 + DELPHI7 Defined when compiling with Delphi 7 + DELPHI8 Defined when compiling with Delphi 8 + DELPHI2005 Defined when compiling with Delphi 2005 + DELPHI9 Alias for DELPHI2005 + DELPHI10 Defined when compiling with Delphi Personality of BDS 4.0 + DELPHI2006 Alias for DELPHI10 + DELPHI11 Defined when compiling with Delphi 2007 for Win32 + DELPHI2007 Alias for DELPHI11 + DELPHI12 Defined when compiling with Delphi for Win32 2009 + DELPHI2009 Alias for DELPHI12 + DELPHI1_UP Defined when compiling with Delphi 1 or higher + DELPHI2_UP Defined when compiling with Delphi 2 or higher + DELPHI3_UP Defined when compiling with Delphi 3 or higher + DELPHI4_UP Defined when compiling with Delphi 4 or higher + DELPHI5_UP Defined when compiling with Delphi 5 or higher + DELPHI6_UP Defined when compiling with Delphi 6 or higher + DELPHI7_UP Defined when compiling with Delphi 7 or higher + DELPHI8_UP Defined when compiling with Delphi 8 or higher + DELPHI2005_UP Defined when compiling with Delphi 2005 or higher + DELPHI9_UP Alias for DELPHI2005_UP + DELPHI10_UP Defined when compiling with Delphi Personality of BDS 4.0 or higher + DELPHI2006_UP Alias for DELPHI10_UP + DELPHI11_UP Defined when compiling with Delphi 2007 for Win32 or higher + DELPHI2007_UP Alias for DELPHI11_UP + DELPHI12_UP Defined when compiling with Delphi for Win32 2009 or higher + DELPHI2009_UP Alias for DELPHI12_UP + + +- Kylix Versions + + The following directives are direct mappings from the VERXXX directives to a + friendly name of the associated compiler. These directives are only defined if + the compiler is Kylix (ie KYLIX is defined). + + Directive Description + ------------------------------------------------------------------------------ + KYLIX1 Defined when compiling with Kylix 1 + KYLIX2 Defined when compiling with Kylix 2 + KYLIX3 Defined when compiling with Kylix 3 + KYLIX1_UP Defined when compiling with Kylix 1 or higher + KYLIX2_UP Defined when compiling with Kylix 2 or higher + KYLIX3_UP Defined when compiling with Kylix 3 or higher + + +- Delphi Compiler Versions (Delphi / Kylix, not in BCB mode) + + Directive Description + ------------------------------------------------------------------------------ + DELPHICOMPILER1 Defined when compiling with Delphi 1 + DELPHICOMPILER2 Defined when compiling with Delphi 2 + DELPHICOMPILER3 Defined when compiling with Delphi 3 + DELPHICOMPILER4 Defined when compiling with Delphi 4 + DELPHICOMPILER5 Defined when compiling with Delphi 5 + DELPHICOMPILER6 Defined when compiling with Delphi 6 or Kylix 1, 2 or 3 + DELPHICOMPILER7 Defined when compiling with Delphi 7 + DELPHICOMPILER8 Defined when compiling with Delphi 8 + DELPHICOMPILER9 Defined when compiling with Delphi 2005 + DELPHICOMPILER10 Defined when compiling with Delphi Personality of BDS 4.0 + DELPHICOMPILER11 Defined when compiling with Delphi 2007 for Win32 + DELPHICOMPILER12 Defined when compiling with Delphi Personality of BDS 6.0 + DELPHICOMPILER1_UP Defined when compiling with Delphi 1 or higher + DELPHICOMPILER2_UP Defined when compiling with Delphi 2 or higher + DELPHICOMPILER3_UP Defined when compiling with Delphi 3 or higher + DELPHICOMPILER4_UP Defined when compiling with Delphi 4 or higher + DELPHICOMPILER5_UP Defined when compiling with Delphi 5 or higher + DELPHICOMPILER6_UP Defined when compiling with Delphi 6 or Kylix 1, 2 or 3 or higher + DELPHICOMPILER7_UP Defined when compiling with Delphi 7 or higher + DELPHICOMPILER8_UP Defined when compiling with Delphi 8 or higher + DELPHICOMPILER9_UP Defined when compiling with Delphi 2005 + DELPHICOMPILER10_UP Defined when compiling with Delphi Personality of BDS 4.0 or higher + DELPHICOMPILER11_UP Defined when compiling with Delphi 2007 for Win32 or higher + DELPHICOMPILER12_UP Defined when compiling with Delphi Personality of BDS 6.0 or higher + + +- C++ Builder Versions + + The following directives are direct mappings from the VERXXX directives to a + friendly name of the associated compiler. These directives are only defined if + the compiler is C++ Builder (ie BCB is defined). + + Directive Description + ------------------------------------------------------------------------------ + BCB1 Defined when compiling with C++ Builder 1 + BCB3 Defined when compiling with C++ Builder 3 + BCB4 Defined when compiling with C++ Builder 4 + BCB5 Defined when compiling with C++ Builder 5 + BCB6 Defined when compiling with C++ Builder 6 + BCB10 Defined when compiling with C++ Builder Personality of BDS 4.0 (also known as C++Builder 2006) + BCB11 Defined when compiling with C++ Builder Personality of RAD Studio 2007 (also known as C++Builder 2007) + BCB12 Defined when compiling with C++ Builder Personality of RAD Studio 2009 (also known as C++Builder 2009) + BCB1_UP Defined when compiling with C++ Builder 1 or higher + BCB3_UP Defined when compiling with C++ Builder 3 or higher + BCB4_UP Defined when compiling with C++ Builder 4 or higher + BCB5_UP Defined when compiling with C++ Builder 5 or higher + BCB6_UP Defined when compiling with C++ Builder 6 or higher + BCB10_UP Defined when compiling with C++ Builder Personality of BDS 4.0 or higher + BCB11_UP Defined when compiling with C++ Builder Personality of RAD Studio 2007 or higher + BCB12_UP Defined when compiling with C++ Builder Personality of RAD Studio 2009 or higher + + +- CodeGear RAD Studio / Borland Developer Studio Versions + + The following directives are direct mappings from the VERXXX directives to a + friendly name of the associated IDE. These directives are only defined if + the IDE is Borland Developer Studio Version 2 or above. + + Note: Borland Developer Studio 2006 is marketed as Delphi 2006 or C++Builder 2006, + but those provide only different labels for identical content. + + Directive Description + ------------------------------------------------------------------------------ + BDS Defined when compiling with a Borland Developer Studio version's dcc32.exe + BDS2 Defined when compiling with BDS 2.0 (Delphi 8) + BDS3 Defined when compiling with BDS 3.0 (Delphi 2005) + BDS4 Defined when compiling with BDS 4.0 (Borland Developer Studio 2006) + BDS5 Defined when compiling with BDS 5.0 (CodeGear RAD Studio 2007) + BDS6 Defined when compiling with BDS 6.0 (CodeGear RAD Studio 2009) + BDS2_UP Defined when compiling with BDS 2.0 or higher + BDS3_UP Defined when compiling with BDS 3.0 or higher + BDS4_UP Defined when compiling with BDS 4.0 or higher + BDS5_UP Defined when compiling with BDS 5.0 or higher + BDS6_UP Defined when compiling with BDS 6.0 or higher + +- Compiler Versions + + The following directives are direct mappings from the VERXXX directives to a + friendly name of the associated compiler. Unlike the DELPHI_X and BCB_X + directives, these directives are indepedent of the development environment. + That is, they are defined regardless of whether compilation takes place using + Delphi or C++ Builder. + + Directive Description + ------------------------------------------------------------------------------ + COMPILER1 Defined when compiling with Delphi 1 + COMPILER2 Defined when compiling with Delphi 2 or C++ Builder 1 + COMPILER3 Defined when compiling with Delphi 3 + COMPILER35 Defined when compiling with C++ Builder 3 + COMPILER4 Defined when compiling with Delphi 4 or C++ Builder 4 + COMPILER5 Defined when compiling with Delphi 5 or C++ Builder 5 + COMPILER6 Defined when compiling with Delphi 6 or C++ Builder 6 + COMPILER7 Defined when compiling with Delphi 7 + COMPILER8 Defined when compiling with Delphi 8 + COMPILER9 Defined when compiling with Delphi 9 + COMPILER10 Defined when compiling with Delphi or C++ Builder Personalities of BDS 4.0 + COMPILER11 Defined when compiling with Delphi 2007 for Win32 + COMPILER12 Defined when compiling with Delphi or C++ Builder Personalities of BDS 6.0 + COMPILER1_UP Defined when compiling with Delphi 1 or higher + COMPILER2_UP Defined when compiling with Delphi 2 or C++ Builder 1 or higher + COMPILER3_UP Defined when compiling with Delphi 3 or higher + COMPILER35_UP Defined when compiling with C++ Builder 3 or higher + COMPILER4_UP Defined when compiling with Delphi 4 or C++ Builder 4 or higher + COMPILER5_UP Defined when compiling with Delphi 5 or C++ Builder 5 or higher + COMPILER6_UP Defined when compiling with Delphi 6 or C++ Builder 6 or higher + COMPILER7_UP Defined when compiling with Delphi 7 + COMPILER8_UP Defined when compiling with Delphi 8 + COMPILER9_UP Defined when compiling with Delphi Personalities of BDS 3.0 + COMPILER10_UP Defined when compiling with Delphi or C++ Builder Personalities of BDS 4.0 or higher + COMPILER11_UP Defined when compiling with Delphi 2007 for Win32 or higher + COMPILER12_UP Defined when compiling with Delphi or C++ Builder Personalities of BDS 6.0 or higher + + +- RTL Versions + + Use e.g. following to determine the exact RTL version since version 14.0: + {$IFDEF CONDITIONALEXPRESSIONS} + {$IF Declared(RTLVersion) and (RTLVersion >= 14.2)} + // code for Delphi 6.02 or higher, Kylix 2 or higher, C++ Builder 6 or higher + ... + {$IFEND} + {$ENDIF} + + Directive Description + ------------------------------------------------------------------------------ + RTL80_UP Defined when compiling with Delphi 1 or higher + RTL90_UP Defined when compiling with Delphi 2 or higher + RTL93_UP Defined when compiling with C++ Builder 1 or higher + RTL100_UP Defined when compiling with Delphi 3 or higher + RTL110_UP Defined when compiling with C++ Builder 3 or higher + RTL120_UP Defined when compiling with Delphi 4 or higher + RTL125_UP Defined when compiling with C++ Builder 4 or higher + RTL130_UP Defined when compiling with Delphi 5 or C++ Builder 5 or higher + RTL140_UP Defined when compiling with Delphi 6, Kylix 1, 2 or 3 or C++ Builder 6 or higher + RTL150_UP Defined when compiling with Delphi 7 or higher + RTL160_UP Defined when compiling with Delphi 8 or higher + RTL170_UP Defined when compiling with Delphi Personalities of BDS 3.0 or higher + RTL180_UP Defined when compiling with Delphi or C++ Builder Personalities of BDS 4.0 or higher + RTL185_UP Defined when compiling with Delphi 2007 for Win32 or higher + RTL190_UP Defined when compiling with Delphi.NET of BDS 5.0 or later + RTL200_UP Defined when compiling with Delphi or C++ Builder Personalities of BDS 6.0 or later + + +- CLR Versions + + Directive Description + ------------------------------------------------------------------------------ + CLR Defined when compiling for .NET + CLR10 Defined when compiling for .NET 1.0 (may be overriden by FORCE_CLR10) + CLR10_UP Defined when compiling for .NET 1.0 or higher + CLR11 Defined when compiling for .NET 1.1 (may be overriden by FORCE_CLR11) + CLR11_UP Defined when compiling for .NET 1.1 or higher + CLR20 Defined when compiling for .NET 2.0 (may be overriden by FORCE_CLR20) + CLR20_UP Defined when compiling for .NET 2.0 or higher + + +- Feature Directives + + The features directives are used to test if the compiler supports specific + features, such as method overloading, and adjust the sources accordingly. Use + of these directives is preferred over the use of the DELPHI and COMPILER + directives. + + Directive Description + ------------------------------------------------------------------------------ + SUPPORTS_CONSTPARAMS Compiler supports const parameters (D1+) + SUPPORTS_SINGLE Compiler supports the Single type (D1+) + SUPPORTS_DOUBLE Compiler supports the Double type (D1+) + SUPPORTS_EXTENDED Compiler supports the Extended type (D1+) + SUPPORTS_CURRENCY Compiler supports the Currency type (D2+) + SUPPORTS_THREADVAR Compiler supports threadvar declarations (D2+) + SUPPORTS_OUTPARAMS Compiler supports out parameters (D3+) + SUPPORTS_VARIANT Compiler supports variant (D2+) + SUPPORTS_WIDECHAR Compiler supports the WideChar type (D2+) + SUPPORTS_WIDESTRING Compiler supports the WideString type (D3+/BCB3+) + SUPPORTS_INTERFACE Compiler supports interfaces (D3+/BCB3+) + SUPPORTS_DISPINTERFACE Compiler supports dispatch interfaces (D3+/BCB3+) + SUPPORTS_DISPID Compiler supports dispatch ids (D3+/BCB3+/FPC) + SUPPORTS_EXTSYM Compiler supports the $EXTERNALSYM directive (D4+/BCB3+) + SUPPORTS_NODEFINE Compiler supports the $NODEFINE directive (D4+/BCB3+) + SUPPORTS_LONGWORD Compiler supports the LongWord type (unsigned 32 bit) (D4+/BCB4+) + SUPPORTS_INT64 Compiler supports the Int64 type (D4+/BCB4+) + SUPPORTS_DYNAMICARRAYS Compiler supports dynamic arrays (D4+/BCB4+) + SUPPORTS_DEFAULTPARAMS Compiler supports default parameters (D4+/BCB4+) + SUPPORTS_OVERLOAD Compiler supports overloading (D4+/BCB4+) + SUPPORTS_IMPLEMENTS Compiler supports implements (D4+/BCB4+) + SUPPORTS_DEPRECATED Compiler supports the deprecated directive (D6+/BCB6+) + SUPPORTS_PLATFORM Compiler supports the platform directive (D6+/BCB6+) + SUPPORTS_LIBRARY Compiler supports the library directive (D6+/BCB6+/FPC) + SUPPORTS_LOCAL Compiler supports the local directive (D6+/BCB6+) + SUPPORTS_INLINE Compiler supports the inline directive (D9+/FPC) + SUPPORTS_FOR_IN Compiler supports for in loops (D9+) + SUPPORTS_NESTED_CONSTANTS Compiler supports nested constants (D9+) + SUPPORTS_NESTED_TYPES Compiler supports nested types (D9+) + SUPPORTS_ENHANCED_RECORDS Compiler supports class [operator|function|procedure] for record types (D9.NET, D10+) + SUPPORTS_CLASS_FIELDS Compiler supports class fields (D9.NET, D10+) + SUPPORTS_CLASS_HELPERS Compiler supports class helpers (D9.NET, D10+) + SUPPORTS_CLASS_OPERATORS Compiler supports class operators (D9.NET, D10+) + SUPPORTS_STRICT Compiler supports strict keyword (D9.NET, D10+) + SUPPORTS_STATIC Compiler supports static keyword (D9.NET, D10+) + SUPPORTS_FINAL Compiler supports final keyword (D9.NET, D10+) + SUPPORTS_GENERICS Compiler supports generic implementations (D11.net, D12+) + ACCEPT_DEPRECATED Compiler supports or ignores the deprecated directive (D6+/BCB6+/FPC) + ACCEPT_PLATFORM Compiler supports or ignores the platform directive (D6+/BCB6+/FPC) + ACCEPT_LIBRARY Compiler supports or ignores the library directive (D6+/BCB6+) + SUPPORTS_CUSTOMVARIANTS Compiler supports custom variants (D6+/BCB6+) + SUPPORTS_VARARGS Compiler supports varargs (D6+/BCB6+) + SUPPORTS_ENUMVALUE Compiler supports assigning ordinalities to values of enums (D6+/BCB6+) + SUPPORTS_DEPRECATED_WARNINGS Compiler supports deprecated warnings (D6+/BCB6+) + SUPPORTS_LIBRARY_WARNINGS Compiler supports library warnings (D6+/BCB6+) + SUPPORTS_PLATFORM_WARNINGS Compiler supports platform warnings (D6+/BCB6+) + SUPPORTS_UNSAFE_WARNINGS Compiler supports unsafe warnings (D7) + SUPPORTS_WEAKPACKAGEUNIT Compiler supports the WEAKPACKAGEUNIT directive + SUPPORTS_COMPILETIME_MESSAGES Compiler supports the MESSAGE directive + SUPPORTS_PACKAGES Compiler supports Packages + HAS_UNIT_LIBC Unit Libc exists (Kylix, FPC on Linux/x86) + HAS_UNIT_RTLCONSTS Unit RTLConsts exists (D6+/BCB6+/FPC) + HAS_UNIT_TYPES Unit Types exists (D6+/BCB6+/FPC) + HAS_UNIT_VARIANTS Unit Variants exists (D6+/BCB6+/FPC) + HAS_UNIT_STRUTILS Unit StrUtils exists (D6+/BCB6+/FPC) + HAS_UNIT_DATEUTILS Unit DateUtils exists (D6+/BCB6+/FPC) + HAS_UNIT_CONTNRS Unit contnrs exists (D6+/BCB6+/FPC) + HAS_UNIT_ANSISTRINGS Unit AnsiStrings exists (D12+) + XPLATFORM_RTL The RTL supports crossplatform function names (e.g. RaiseLastOSError) (D6+/BCB6+/FPC) + SUPPORTS_UNICODE string type is aliased to an unicode string (WideString or UnicodeString) (DX.net, D12+) + SUPPORTS_UNICODE_STRING Compiler supports UnicodeString (D12+) + + +- Compiler Settings + + The compiler settings directives indicate whether a specific compiler setting + is in effect. This facilitates changing compiler settings locally in a more + compact and readible manner. + + Directive Description + ------------------------------------------------------------------------------ + ALIGN_ON Compiling in the A+ state (no alignment) + BOOLEVAL_ON Compiling in the B+ state (complete boolean evaluation) + ASSERTIONS_ON Compiling in the C+ state (assertions on) + DEBUGINFO_ON Compiling in the D+ state (debug info generation on) + IMPORTEDDATA_ON Compiling in the G+ state (creation of imported data references) + LONGSTRINGS_ON Compiling in the H+ state (string defined as AnsiString) + IOCHECKS_ON Compiling in the I+ state (I/O checking enabled) + WRITEABLECONST_ON Compiling in the J+ state (typed constants can be modified) + LOCALSYMBOLS Compiling in the L+ state (local symbol generation) + TYPEINFO_ON Compiling in the M+ state (RTTI generation on) + OPTIMIZATION_ON Compiling in the O+ state (code optimization on) + OPENSTRINGS_ON Compiling in the P+ state (variable string parameters are openstrings) + OVERFLOWCHECKS_ON Compiling in the Q+ state (overflow checing on) + RANGECHECKS_ON Compiling in the R+ state (range checking on) + TYPEDADDRESS_ON Compiling in the T+ state (pointers obtained using the @ operator are typed) + SAFEDIVIDE_ON Compiling in the U+ state (save FDIV instruction through RTL emulation) + VARSTRINGCHECKS_ON Compiling in the V+ state (type checking of shortstrings) + STACKFRAMES_ON Compiling in the W+ state (generation of stack frames) + EXTENDEDSYNTAX_ON Compiling in the X+ state (Delphi extended syntax enabled) +*) + +{$DEFINE BORLAND} + +{ Set FreePascal to Delphi mode } +{$IFDEF FPC} + {$MODE DELPHI} + {$ASMMODE Intel} + {$UNDEF BORLAND} + // FPC defines CPU* and Unix automatically +{$ENDIF} + +{$IFDEF BORLAND} + {$IFDEF LINUX} + {$DEFINE KYLIX} + {$ENDIF LINUX} + {$IFNDEF CLR} + {$DEFINE CPU386} // For Borland compilers select the x86 compat assembler by default + {$DEFINE CPU32} // Assume Borland compilers are 32-bit (rather than 64-bit) + {$ENDIF ~CLR} +{$ENDIF BORLAND} + +{------------------------------------------------------------------------------} +{ VERXXX to COMPILERX, DELPHIX and BCBX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF BORLAND} + {$IFDEF KYLIX} + { Kylix is not a target of the private RESTDW Delphi HTML Designer. } + {$ELSE ~KYLIX} + + {$DEFINE UNKNOWN_COMPILER_VERSION} + + {$IFDEF VER80} + {$DEFINE COMPILER1} + {$DEFINE DELPHI1} + {$DEFINE DELPHICOMPILER1} + {$DEFINE RTL80_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER90} + {$DEFINE COMPILER2} + {$DEFINE DELPHI2} + {$DEFINE DELPHICOMPILER2} + {$DEFINE RTL90_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER93} + {$DEFINE COMPILER2} + {$DEFINE BCB1} + {$DEFINE BCB} + {$DEFINE RTL93_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER100} + {$DEFINE COMPILER3} + {$DEFINE DELPHI3} + {$DEFINE DELPHICOMPILER3} + {$DEFINE RTL100_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER110} + {$DEFINE COMPILER35} + {$DEFINE BCB3} + {$DEFINE RTL110_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER120} + {$DEFINE COMPILER4} + {$DEFINE DELPHI4} + {$DEFINE DELPHICOMPILER4} + {$DEFINE RTL120_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER125} + {$DEFINE COMPILER4} + {$DEFINE BCB4} + {$DEFINE BCB} + {$DEFINE RTL125_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER130} + {$DEFINE COMPILER5} + {$IFDEF BCB} + {$DEFINE BCB5} + {$ELSE} + {$DEFINE DELPHI5} + {$DEFINE DELPHICOMPILER5} + {$ENDIF} + {$DEFINE RTL130_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER140} + {$DEFINE COMPILER6} + {$IFDEF BCB} + {$DEFINE BCB6} + {$ELSE} + {$DEFINE DELPHI6} + {$DEFINE DELPHICOMPILER6} + {$ENDIF} + {$DEFINE RTL140_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER150} + {$DEFINE COMPILER7} + {$DEFINE DELPHI7} + {$DEFINE DELPHICOMPILER7} + {$DEFINE RTL150_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER160} + {$DEFINE BDS2} + {$DEFINE BDS} + {$IFDEF CLR} + {$DEFINE CLR10} + {$ENDIF CLR} + {$DEFINE COMPILER8} + {$DEFINE DELPHI8} + {$DEFINE DELPHICOMPILER8} + {$DEFINE RTL160_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER170} + {$DEFINE BDS3} + {$DEFINE BDS} + {$IFDEF CLR} + {$DEFINE CLR11} + {$ENDIF CLR} + {$DEFINE COMPILER9} + {$DEFINE DELPHI9} + {$DEFINE DELPHI2005} // synonym to DELPHI9 + {$DEFINE DELPHICOMPILER9} + {$DEFINE RTL170_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER180} + {$DEFINE BDS} + {$IFDEF CLR} + {$DEFINE CLR11} + {$ENDIF CLR} + {$IFDEF VER185} + {$DEFINE BDS5} + {$DEFINE COMPILER11} + {$IFDEF BCB} + {$DEFINE BCB11} + {$ELSE} + {$DEFINE DELPHI11} + {$DEFINE DELPHI2007} // synonym to DELPHI11 + {$DEFINE DELPHICOMPILER11} + {$ENDIF} + {$DEFINE RTL185_UP} + {$ELSE ~~VER185} + {$DEFINE BDS4} + {$DEFINE COMPILER10} + {$IFDEF BCB} + {$DEFINE BCB10} + {$ELSE} + {$DEFINE DELPHI10} + {$DEFINE DELPHI2006} // synonym to DELPHI10 + {$DEFINE DELPHICOMPILER10} + {$ENDIF} + {$DEFINE RTL180_UP} + {$ENDIF ~VER185} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER190} // Delphi 2007 for .NET + {$DEFINE BDS} + {$DEFINE BDS5} + {$IFDEF CLR} + {$DEFINE CLR20} + {$ENDIF CLR} + {$DEFINE COMPILER11} + {$DEFINE DELPHI11} + {$DEFINE DELPHI2007} // synonym to DELPHI11 + {$DEFINE DELPHICOMPILER11} + {$DEFINE RTL190_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF VER190} + + {$IFDEF VER200} // RAD Studio 2009 + {$DEFINE BDS} + {$DEFINE BDS6} + {$IFDEF CLR} + {$DEFINE CLR20} + {$ENDIF CLR} + {$DEFINE COMPILER12} + {$IFDEF BCB} + {$DEFINE BCB12} + {$ELSE} + {$DEFINE DELPHI12} + {$DEFINE DELPHI2009} // synonym to DELPHI12 + {$DEFINE DELPHICOMPILER12} + {$ENDIF BCB} + {$IFDEF CLR} + {$DEFINE RTL190_UP} + {$ELSE} + {$DEFINE RTL200_UP} + {$ENDIF} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF VER200} + + {$IFDEF UNKNOWN_COMPILER_VERSION} // adjust for newer version (always use latest version) + {$DEFINE BDS} + {$DEFINE BDS6} + {$DEFINE COMPILER12} + {$IFDEF BCB} + {$DEFINE BCB12} + {$ELSE} + {$DEFINE DELPHI12} + {$DEFINE DELPHI2009} // synonym to DELPHI12 + {$DEFINE DELPHICOMPILER12} + {$ENDIF BCB} + {$IFDEF CLR} + {$DEFINE RTL190_UP} + {$ELSE} + {$DEFINE RTL200_UP} + {$ENDIF} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$ENDIF ~KYLIX} + + {$IFDEF BCB} + {$DEFINE CPPBUILDER} + {$DEFINE BCBCOMPILER} + {$ELSE ~BCB} + {$DEFINE DELPHI} + {$DEFINE DELPHICOMPILER} + {$ENDIF ~BCB} + +{$ENDIF BORLAND} + +{------------------------------------------------------------------------------} +{ DELPHIX_UP from DELPHIX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF DELPHI12} {$DEFINE DELPHI12_UP} {$ENDIF} +{$IFDEF DELPHI11} {$DEFINE DELPHI11_UP} {$ENDIF} +{$IFDEF DELPHI10} {$DEFINE DELPHI10_UP} {$ENDIF} +{$IFDEF DELPHI9} {$DEFINE DELPHI9_UP} {$ENDIF} +{$IFDEF DELPHI8} {$DEFINE DELPHI8_UP} {$ENDIF} +{$IFDEF DELPHI7} {$DEFINE DELPHI7_UP} {$ENDIF} +{$IFDEF DELPHI6} {$DEFINE DELPHI6_UP} {$ENDIF} +{$IFDEF DELPHI5} {$DEFINE DELPHI5_UP} {$ENDIF} +{$IFDEF DELPHI4} {$DEFINE DELPHI4_UP} {$ENDIF} +{$IFDEF DELPHI3} {$DEFINE DELPHI3_UP} {$ENDIF} +{$IFDEF DELPHI2} {$DEFINE DELPHI2_UP} {$ENDIF} +{$IFDEF DELPHI1} {$DEFINE DELPHI1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ DELPHIX_UP from DELPHIX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF DELPHI12_UP} + {$DEFINE DELPHI2009_UP} // synonym to DELPHI12_UP + {$DEFINE DELPHI11_UP} +{$ENDIF} + +{$IFDEF DELPHI11_UP} + {$DEFINE DELPHI2007_UP} // synonym to DELPHI11_UP + {$DEFINE DELPHI10_UP} +{$ENDIF} + +{$IFDEF DELPHI10_UP} + {$DEFINE DELPHI2006_UP} // synonym to DELPHI10_UP + {$DEFINE DELPHI9_UP} +{$ENDIF} + +{$IFDEF DELPHI9_UP} + {$DEFINE DELPHI2005_UP} // synonym to DELPHI9_UP + {$DEFINE DELPHI8_UP} +{$ENDIF} + +{$IFDEF DELPHI8_UP} {$DEFINE DELPHI7_UP} {$ENDIF} +{$IFDEF DELPHI7_UP} {$DEFINE DELPHI6_UP} {$ENDIF} +{$IFDEF DELPHI6_UP} {$DEFINE DELPHI5_UP} {$ENDIF} +{$IFDEF DELPHI5_UP} {$DEFINE DELPHI4_UP} {$ENDIF} +{$IFDEF DELPHI4_UP} {$DEFINE DELPHI3_UP} {$ENDIF} +{$IFDEF DELPHI3_UP} {$DEFINE DELPHI2_UP} {$ENDIF} +{$IFDEF DELPHI2_UP} {$DEFINE DELPHI1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ BCBX_UP from BCBX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF BCB12} {$DEFINE BCB12_UP} {$ENDIF} +{$IFDEF BCB11} {$DEFINE BCB11_UP} {$ENDIF} +{$IFDEF BCB10} {$DEFINE BCB10_UP} {$ENDIF} +{$IFDEF BCB6} {$DEFINE BCB6_UP} {$ENDIF} +{$IFDEF BCB5} {$DEFINE BCB5_UP} {$ENDIF} +{$IFDEF BCB4} {$DEFINE BCB4_UP} {$ENDIF} +{$IFDEF BCB3} {$DEFINE BCB3_UP} {$ENDIF} +{$IFDEF BCB1} {$DEFINE BCB1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ BCBX_UP from BCBX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF BCB12_UP} {$DEFINE BCB11_UP} {$ENDIF} +{$IFDEF BCB11_UP} {$DEFINE BCB10_UP} {$ENDIF} +{$IFDEF BCB10_UP} {$DEFINE BCB6_UP} {$ENDIF} +{$IFDEF BCB6_UP} {$DEFINE BCB5_UP} {$ENDIF} +{$IFDEF BCB5_UP} {$DEFINE BCB4_UP} {$ENDIF} +{$IFDEF BCB4_UP} {$DEFINE BCB3_UP} {$ENDIF} +{$IFDEF BCB3_UP} {$DEFINE BCB1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ BDSX_UP from BDSX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF BDS6} {$DEFINE BDS6_UP} {$ENDIF} +{$IFDEF BDS5} {$DEFINE BDS5_UP} {$ENDIF} +{$IFDEF BDS4} {$DEFINE BDS4_UP} {$ENDIF} +{$IFDEF BDS3} {$DEFINE BDS3_UP} {$ENDIF} +{$IFDEF BDS2} {$DEFINE BDS2_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ BDSX_UP from BDSX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF BDS6_UP} {$DEFINE BDS5_UP} {$ENDIF} +{$IFDEF BDS5_UP} {$DEFINE BDS4_UP} {$ENDIF} +{$IFDEF BDS4_UP} {$DEFINE BDS3_UP} {$ENDIF} +{$IFDEF BDS3_UP} {$DEFINE BDS2_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ DELPHICOMPILERX_UP from DELPHICOMPILERX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF DELPHICOMPILER12} {$DEFINE DELPHICOMPILER12_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER11} {$DEFINE DELPHICOMPILER11_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER10} {$DEFINE DELPHICOMPILER10_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER9} {$DEFINE DELPHICOMPILER9_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER8} {$DEFINE DELPHICOMPILER8_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER7} {$DEFINE DELPHICOMPILER7_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER6} {$DEFINE DELPHICOMPILER6_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER5} {$DEFINE DELPHICOMPILER5_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER4} {$DEFINE DELPHICOMPILER4_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER3} {$DEFINE DELPHICOMPILER3_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER2} {$DEFINE DELPHICOMPILER2_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER1} {$DEFINE DELPHICOMPILER1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ DELPHICOMPILERX_UP from DELPHICOMPILERX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF DELPHICOMPILER12_UP} {$DEFINE DELPHICOMPILER11_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER11_UP} {$DEFINE DELPHICOMPILER10_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER10_UP} {$DEFINE DELPHICOMPILER9_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER9_UP} {$DEFINE DELPHICOMPILER8_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER8_UP} {$DEFINE DELPHICOMPILER7_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER8_UP} {$DEFINE DELPHICOMPILER7_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER7_UP} {$DEFINE DELPHICOMPILER6_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER6_UP} {$DEFINE DELPHICOMPILER5_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER5_UP} {$DEFINE DELPHICOMPILER4_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER4_UP} {$DEFINE DELPHICOMPILER3_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER3_UP} {$DEFINE DELPHICOMPILER2_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER2_UP} {$DEFINE DELPHICOMPILER1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ COMPILERX_UP from COMPILERX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF COMPILER12} {$DEFINE COMPILER12_UP} {$ENDIF} +{$IFDEF COMPILER11} {$DEFINE COMPILER11_UP} {$ENDIF} +{$IFDEF COMPILER10} {$DEFINE COMPILER10_UP} {$ENDIF} +{$IFDEF COMPILER9} {$DEFINE COMPILER9_UP} {$ENDIF} +{$IFDEF COMPILER8} {$DEFINE COMPILER8_UP} {$ENDIF} +{$IFDEF COMPILER7} {$DEFINE COMPILER7_UP} {$ENDIF} +{$IFDEF COMPILER6} {$DEFINE COMPILER6_UP} {$ENDIF} +{$IFDEF COMPILER5} {$DEFINE COMPILER5_UP} {$ENDIF} +{$IFDEF COMPILER4} {$DEFINE COMPILER4_UP} {$ENDIF} +{$IFDEF COMPILER35} {$DEFINE COMPILER35_UP} {$ENDIF} +{$IFDEF COMPILER3} {$DEFINE COMPILER3_UP} {$ENDIF} +{$IFDEF COMPILER2} {$DEFINE COMPILER2_UP} {$ENDIF} +{$IFDEF COMPILER1} {$DEFINE COMPILER1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ COMPILERX_UP from COMPILERX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF COMPILER12_UP} {$DEFINE COMPILER11_UP} {$ENDIF} +{$IFDEF COMPILER11_UP} {$DEFINE COMPILER10_UP} {$ENDIF} +{$IFDEF COMPILER10_UP} {$DEFINE COMPILER9_UP} {$ENDIF} +{$IFDEF COMPILER9_UP} {$DEFINE COMPILER8_UP} {$ENDIF} +{$IFDEF COMPILER8_UP} {$DEFINE COMPILER7_UP} {$ENDIF} +{$IFDEF COMPILER7_UP} {$DEFINE COMPILER6_UP} {$ENDIF} +{$IFDEF COMPILER6_UP} {$DEFINE COMPILER5_UP} {$ENDIF} +{$IFDEF COMPILER5_UP} {$DEFINE COMPILER4_UP} {$ENDIF} +{$IFDEF COMPILER4_UP} {$DEFINE COMPILER35_UP} {$ENDIF} +{$IFDEF COMPILER35_UP} {$DEFINE COMPILER3_UP} {$ENDIF} +{$IFDEF COMPILER3_UP} {$DEFINE COMPILER2_UP} {$ENDIF} +{$IFDEF COMPILER2_UP} {$DEFINE COMPILER1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ RTLX_UP from RTLX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF RTL200_UP} {$DEFINE RTL190_UP} {$ENDIF} +{$IFDEF RTL190_UP} {$DEFINE RTL185_UP} {$ENDIF} +{$IFDEF RTL185_UP} {$DEFINE RTL180_UP} {$ENDIF} +{$IFDEF RTL180_UP} {$DEFINE RTL170_UP} {$ENDIF} +{$IFDEF RTL170_UP} {$DEFINE RTL160_UP} {$ENDIF} +{$IFDEF RTL160_UP} {$DEFINE RTL150_UP} {$ENDIF} +{$IFDEF RTL150_UP} {$DEFINE RTL145_UP} {$ENDIF} +{$IFDEF RTL145_UP} {$DEFINE RTL142_UP} {$ENDIF} +{$IFDEF RTL142_UP} {$DEFINE RTL140_UP} {$ENDIF} +{$IFDEF RTL140_UP} {$DEFINE RTL130_UP} {$ENDIF} +{$IFDEF RTL130_UP} {$DEFINE RTL125_UP} {$ENDIF} +{$IFDEF RTL125_UP} {$DEFINE RTL120_UP} {$ENDIF} +{$IFDEF RTL120_UP} {$DEFINE RTL110_UP} {$ENDIF} +{$IFDEF RTL110_UP} {$DEFINE RTL100_UP} {$ENDIF} +{$IFDEF RTL100_UP} {$DEFINE RTL93_UP} {$ENDIF} +{$IFDEF RTL93_UP} {$DEFINE RTL90_UP} {$ENDIF} +{$IFDEF RTL90_UP} {$DEFINE RTL80_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ Check for CLR overrides of default detection } +{------------------------------------------------------------------------------} + +{$IFDEF CLR} + {$IFDEF FORCE_CLR10} + {$DEFINE CLR10} + {$UNDEF CLR11} + {$UNDEF CLR20} + {$ENDIF FORCE_CLR10} + + {$IFDEF FORCE_CLR11} + {$UNDEF CLR10} + {$DEFINE CLR11} + {$UNDEF CLR20} + {$ENDIF FORCE_CLR11} + + {$IFDEF FORCE_CLR20} + {$UNDEF CLR10} + {$UNDEF CLR11} + {$DEFINE CLR20} + {$ENDIF FORCE_CLR20} +{$ENDIF CLR} + +{------------------------------------------------------------------------------} +{ CLRX from CLRX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF CLR10} {$DEFINE CLR10_UP} {$ENDIF} +{$IFDEF CLR11} {$DEFINE CLR11_UP} {$ENDIF} +{$IFDEF CLR20} {$DEFINE CLR20_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ CLRX_UP from CLRX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF CLR20_UP} {$DEFINE CLR11_UP} {$ENDIF} +{$IFDEF CLR11_UP} {$DEFINE CLR10_UP} {$ENDIF} + +{------------------------------------------------------------------------------} + +{$IFDEF DELPHICOMPILER} + {$DEFINE DELPHILANGUAGE} +{$ENDIF} + +{$IFDEF BCBCOMPILER} + {$DEFINE DELPHILANGUAGE} +{$ENDIF} + +{------------------------------------------------------------------------------} +{ KYLIXX_UP from KYLIXX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF KYLIX3} {$DEFINE KYLIX3_UP} {$ENDIF} +{$IFDEF KYLIX2} {$DEFINE KYLIX2_UP} {$ENDIF} +{$IFDEF KYLIX1} {$DEFINE KYLIX1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ KYLIXX_UP from KYLIXX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF KYLIX3_UP} {$DEFINE KYLIX2_UP} {$ENDIF} +{$IFDEF KYLIX2_UP} {$DEFINE KYLIX1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ Map COMPILERX_UP to friendly feature names } +{------------------------------------------------------------------------------} + +{$IFDEF FPC} + {$IFDEF VER1_0} + Please use FPC 2.0 or higher to compile this. + {$ELSE} + {$DEFINE SUPPORTS_OUTPARAMS} + {$DEFINE SUPPORTS_WIDECHAR} + {$DEFINE SUPPORTS_WIDESTRING} + {$IFDEF HASINTF} + {$DEFINE SUPPORTS_INTERFACE} + {$ENDIF} + {$IFDEF HASVARIANT} + {$DEFINE SUPPORTS_VARIANT} + {$ENDIF} + {$IFDEF FPC_HAS_TYPE_SINGLE} + {$DEFINE SUPPORTS_SINGLE} + {$ENDIF} + {$IFDEF FPC_HAS_TYPE_DOUBLE} + {$DEFINE SUPPORTS_DOUBLE} + {$ENDIF} + {$IFDEF FPC_HAS_TYPE_EXTENDED} + {$DEFINE SUPPORTS_EXTENDED} + {$ENDIF} + {$IFDEF HASCURRENCY} + {$DEFINE SUPPORTS_CURRENCY} + {$ENDIF} + {$DEFINE SUPPORTS_THREADVAR} + {$DEFINE SUPPORTS_CONSTPARAMS} + {$DEFINE SUPPORTS_LONGWORD} + {$DEFINE SUPPORTS_INT64} + {$DEFINE SUPPORTS_DYNAMICARRAYS} + {$DEFINE SUPPORTS_DEFAULTPARAMS} + {$DEFINE SUPPORTS_OVERLOAD} + {$DEFINE ACCEPT_DEPRECATED} // 2.2 also gives warnings + {$DEFINE ACCEPT_PLATFORM} // 2.2 also gives warnings + {$DEFINE ACCEPT_LIBRARY} + {$DEFINE SUPPORTS_EXTSYM} + {$DEFINE SUPPORTS_NODEFINE} + + {$DEFINE SUPPORTS_CUSTOMVARIANTS} + {$DEFINE SUPPORTS_VARARGS} + {$DEFINE SUPPORTS_ENUMVALUE} + {$IFDEF LINUX} + {$DEFINE HAS_UNIT_LIBC} + {$ENDIF LINUX} + {$DEFINE HAS_UNIT_CONTNRS} + {$DEFINE HAS_UNIT_TYPES} + {$DEFINE HAS_UNIT_VARIANTS} + {$DEFINE HAS_UNIT_STRUTILS} + {$DEFINE HAS_UNIT_DATEUTILS} + {$DEFINE HAS_UNIT_RTLCONSTS} + + {$DEFINE XPLATFORM_RTL} + + {$IFDEF VER2_2} + {$DEFINE SUPPORTS_DISPINTERFACE} + {$DEFINE SUPPORTS_IMPLEMENTS} + {$DEFINE SUPPORTS_DISPID} + {$ELSE} + {$UNDEF SUPPORTS_DISPINTERFACE} + {$UNDEF SUPPORTS_IMPLEMENTS} + {$endif} + {$UNDEF SUPPORTS_UNSAFE_WARNINGS} + {$ENDIF} +{$ENDIF FPC} + +{$IFDEF CLR} + {$DEFINE SUPPORTS_UNICODE} +{$ENDIF CLR} + +{$IFDEF COMPILER1_UP} + {$DEFINE SUPPORTS_CONSTPARAMS} + {$DEFINE SUPPORTS_SINGLE} + {$DEFINE SUPPORTS_DOUBLE} + {$DEFINE SUPPORTS_EXTENDED} + {$DEFINE SUPPORTS_PACKAGES} +{$ENDIF COMPILER1_UP} + +{$IFDEF COMPILER2_UP} + {$DEFINE SUPPORTS_CURRENCY} + {$DEFINE SUPPORTS_THREADVAR} + {$DEFINE SUPPORTS_VARIANT} + {$DEFINE SUPPORTS_WIDECHAR} +{$ENDIF COMPILER2_UP} + +{$IFDEF COMPILER3_UP} + {$DEFINE SUPPORTS_OUTPARAMS} + {$DEFINE SUPPORTS_WIDESTRING} + {$DEFINE SUPPORTS_INTERFACE} + {$DEFINE SUPPORTS_DISPINTERFACE} + {$DEFINE SUPPORTS_DISPID} + {$DEFINE SUPPORTS_WEAKPACKAGEUNIT} +{$ENDIF COMPILER3_UP} + +{$IFDEF COMPILER35_UP} + {$DEFINE SUPPORTS_EXTSYM} + {$DEFINE SUPPORTS_NODEFINE} +{$ENDIF COMPILER35_UP} + +{$IFDEF COMPILER4_UP} + {$DEFINE SUPPORTS_LONGWORD} + {$DEFINE SUPPORTS_INT64} + {$DEFINE SUPPORTS_DYNAMICARRAYS} + {$DEFINE SUPPORTS_DEFAULTPARAMS} + {$DEFINE SUPPORTS_OVERLOAD} + {$DEFINE SUPPORTS_IMPLEMENTS} +{$ENDIF COMPILER4_UP} + +{$IFDEF COMPILER6_UP} + {$DEFINE SUPPORTS_DEPRECATED} + {$DEFINE SUPPORTS_LIBRARY} + {$DEFINE SUPPORTS_PLATFORM} + {$DEFINE SUPPORTS_LOCAL} + {$DEFINE ACCEPT_DEPRECATED} + {$DEFINE ACCEPT_PLATFORM} + {$DEFINE ACCEPT_LIBRARY} + {$DEFINE SUPPORTS_DEPRECATED_WARNINGS} + {$DEFINE SUPPORTS_LIBRARY_WARNINGS} + {$DEFINE SUPPORTS_PLATFORM_WARNINGS} + {$DEFINE SUPPORTS_CUSTOMVARIANTS} + {$DEFINE SUPPORTS_VARARGS} + {$DEFINE SUPPORTS_ENUMVALUE} + {$DEFINE SUPPORTS_COMPILETIME_MESSAGES} +{$ENDIF COMPILER6_UP} + +{$IFDEF COMPILER7_UP} + {$DEFINE SUPPORTS_UNSAFE_WARNINGS} +{$ENDIF COMPILER7_UP} + +{$IFDEF COMPILER9_UP} + {$DEFINE SUPPORTS_FOR_IN} + {$DEFINE SUPPORTS_INLINE} + {$DEFINE SUPPORTS_NESTED_CONSTANTS} + {$DEFINE SUPPORTS_NESTED_TYPES} + {$IFDEF CLR} + {$DEFINE SUPPORTS_ENHANCED_RECORDS} + {$DEFINE SUPPORTS_CLASS_FIELDS} + {$DEFINE SUPPORTS_CLASS_HELPERS} + {$DEFINE SUPPORTS_CLASS_OPERATORS} + {$DEFINE SUPPORTS_STRICT} + {$DEFINE SUPPORTS_STATIC} + {$DEFINE SUPPORTS_FINAL} + {$ENDIF CLR} +{$ENDIF COMPILER9_UP} + +{$IFDEF COMPILER10_UP} + {$DEFINE SUPPORTS_ENHANCED_RECORDS} + {$DEFINE SUPPORTS_CLASS_FIELDS} + {$DEFINE SUPPORTS_CLASS_HELPERS} + {$DEFINE SUPPORTS_CLASS_OPERATORS} + {$DEFINE SUPPORTS_STRICT} + {$DEFINE SUPPORTS_STATIC} + {$DEFINE SUPPORTS_FINAL} +{$ENDIF COMPILER10_UP} + +{$IFDEF COMPILER11_UP} + {$IFDEF CLR} + {$DEFINE SUPPORTS_GENERICS} + {$ENDIF CLR} +{$ENDIF COMPILER11_UP} + +{$IFDEF COMPILER12_UP} + {$DEFINE SUPPORTS_GENERICS} + {$DEFINE HAS_UNIT_ANSISTRINGS} + {$IFNDEF CLR} + {$DEFINE SUPPORTS_UNICODE} + {$DEFINE SUPPORTS_UNICODE_STRING} + {$ENDIF CLR} +{$ENDIF COMPILER12_UP} + +{$IFDEF RTL140_UP} + {$IFDEF LINUX} + {$DEFINE HAS_UNIT_LIBC} + {$ENDIF LINUX} + {$DEFINE HAS_UNIT_RTLCONSTS} + {$DEFINE HAS_UNIT_TYPES} + {$DEFINE HAS_UNIT_VARIANTS} + {$DEFINE HAS_UNIT_STRUTILS} + {$DEFINE HAS_UNIT_DATEUTILS} + {$DEFINE XPLATFORM_RTL} +{$ENDIF RTL140_UP} + +{$IFDEF RTL130_UP} + {$DEFINE HAS_UNIT_CONTNRS} +{$ENDIF RTL130_UP} + +{------------------------------------------------------------------------------} +{ Cross-platform related defines } +{------------------------------------------------------------------------------} + +{$IFNDEF CPU386} + {$DEFINE PUREPASCAL} +{$ENDIF} + +{$IFDEF WIN32} + {$DEFINE MSWINDOWS} // predefined for D6+/BCB6+ + {$DEFINE Win32API} +{$ENDIF} + +{$IFDEF DELPHILANGUAGE} + {$IFDEF LINUX} + {$DEFINE UNIX} + {$ENDIF} + + {$IFNDEF CONSOLE} + {$IFDEF LINUX} + {$DEFINE VisualCLX} + {$ENDIF} + {$IFNDEF VisualCLX} + {$DEFINE VCL} + {$ENDIF} + {$ENDIF ~CONSOLE} +{$ENDIF DELPHILANGUAGE} + +{------------------------------------------------------------------------------} +{ Compiler settings } +{------------------------------------------------------------------------------} + +{$IFOPT A+} {$DEFINE ALIGN_ON} {$ENDIF} +{$IFOPT B+} {$DEFINE BOOLEVAL_ON} {$ENDIF} +{$IFDEF COMPILER2_UP} + {$IFOPT C+} {$DEFINE ASSERTIONS_ON} {$ENDIF} +{$ENDIF} +{$IFOPT D+} {$DEFINE DEBUGINFO_ON} {$ENDIF} +{$IFOPT G+} {$DEFINE IMPORTEDDATA_ON} {$ENDIF} +{$IFDEF COMPILER2_UP} + {$IFOPT H+} {$DEFINE LONGSTRINGS_ON} {$ENDIF} +{$ENDIF} + +// Hints +{$IFOPT I+} {$DEFINE IOCHECKS_ON} {$ENDIF} +{$IFDEF COMPILER2_UP} + {$IFOPT J+} {$DEFINE WRITEABLECONST_ON} {$ENDIF} +{$ENDIF} +{$IFOPT L+} {$DEFINE LOCALSYMBOLS} {$ENDIF} +{$IFOPT M+} {$DEFINE TYPEINFO_ON} {$ENDIF} +{$IFOPT O+} {$DEFINE OPTIMIZATION_ON} {$ENDIF} +{$IFOPT P+} {$DEFINE OPENSTRINGS_ON} {$ENDIF} +{$IFOPT Q+} {$DEFINE OVERFLOWCHECKS_ON} {$ENDIF} +{$IFOPT R+} {$DEFINE RANGECHECKS_ON} {$ENDIF} + +// Real compatibility +{$IFOPT T+} {$DEFINE TYPEDADDRESS_ON} {$ENDIF} +{$IFOPT U+} {$DEFINE SAFEDIVIDE_ON} {$ENDIF} +{$IFOPT V+} {$DEFINE VARSTRINGCHECKS_ON} {$ENDIF} +{$IFOPT W+} {$DEFINE STACKFRAMES_ON} {$ENDIF} + +// Warnings +{$IFOPT X+} {$DEFINE EXTENDEDSYNTAX_ON} {$ENDIF} + +// for Delphi/BCB trial versions remove the point from the line below +{.$UNDEF SUPPORTS_WEAKPACKAGEUNIT} + +{$ENDIF ~JEDI_INC} diff --git a/CORE/Source/Includes/htmlcons.inc b/CORE/Source/Includes/htmlcons.inc new file mode 100644 index 000000000..6afc5b037 --- /dev/null +++ b/CORE/Source/Includes/htmlcons.inc @@ -0,0 +1,359 @@ +{Version 11} +//{$IFDEF CONDITIONALEXPRESSIONS} +// +// +// // Must be at the top... +// {$IF CompilerVersion >= 24.0} +// {$LEGACYIFEND ON} +// {$IFEND} +//{$ENDIF} +{$ifdef FPC} + +{ Identify FreePascal/Lazarus Compiler Version } + + {$define LCL} + {$mode delphi} + {$H+} + + {$define FPC_TODO} + + {$define MetaFileMissing} + + {$define HasStrictDelimiter} + + {$define ver100_plus} + {$define ver120_plus} + +{$else} + +{ Identify Delphi Compiler Version: + + # Compiler Version Compiler Defined Symbol + D23 Delphi 10 Seattle 30 VER300 + D22 Delphi XE8 29 VER290 + D21 Delphi XE7 28 VER280 + D20 Delphi XE6 27 VER270 + D19 Delphi XE5 26 VER260 + D18 Delphi XE4 25 VER250 + D17 Delphi XE3 24 VER240 + D16 Delphi XE2 23 VER230 + D15 Delphi XE 22 VER220 + D14 Delphi 2010 21 VER210 + D12 Delphi 2009 20 VER200 + D11 Delphi 2007 18.5 VER185 + D10 Delphi 2006 18 VER180 + D9 Delphi 2005 17 VER170 + D8 Delphi 8 16 VER160 + D7 Delphi 7 15 VER150 + D6 Delphi 6 14 VER140 + C++Builder 5 VER130 BCB + D5 Delphi 5 VER130 + C++Builder 4 VER125 + D4 Delphi 4 VER120 + C++Builder 3 VER110 + D3 Delphi 3 VER100 + C++Builder 1 VER93 + D2 Delphi 2 VER90 + D1 Delphi 1 VER80 + + Since Delphi 6 the version number can be found in the system constant System.CompilerVersion + + NOTICE: HtmlViewer no longer supports versions before Delphi 6 + BG, 20.11.2010: HtmlViewer sources use neither ver100_plus nor ver120_plus any more. + We keep the defines alive for custom code which might still use them. + + A complete list of version numbers can be found at: + + http://docwiki.embarcadero.com/RADStudio/XE8/de/Compiler-Versionen +} + + {$define VCL} + {$define Windows} + {$ifdef CONDITIONALEXPRESSIONS} {Delphi 6 and up} + {$define ver100_plus} + {$define ver120_plus} + {$ifdef ver140} + {$else} + {$define Delphi7_Plus} + {$define Compiler15_Plus} + {$ifdef ver150} + {$else} + {$define Compiler16_Plus} + {$ifdef ver160} + {$else} + {$define Compiler17_Plus} + {$ifdef ver170} + {$else} + {$define Compiler18_Plus} + {$ifdef ver180} + {$else} + {$define Compiler19_Plus} + {$ifdef ver185} + {$else} + {$define Compiler20_Plus} + {$ifdef ver200} + {$else} + {$define Compiler21_Plus} + {$ifdef ver210} + {$else} + {$define Compiler22_Plus} + {$ifdef ver220} + {$else} + {$define Compiler23_Plus} + {$ifdef ver230} + {$else} + {$define Compiler24_Plus} + {$ifdef ver240} + {$else} + {$define Compiler25_Plus} + {$ifdef ver250} + {$else} + {$define Compiler26_Plus} + {$ifdef ver260} + {$else} + {$define Compiler27_Plus} + {$ifdef ver270} + {$else} + {$define Compiler28_Plus} + {$ifdef ver280} + {$else} + {$define Compiler29_Plus} + {$ifdef ver290} + {$else} + {$define Compiler30_Plus} + {$ifdef ver300} + {$else} + {$endif} + {$endif} + {$endif} + {$endif} + {$endif} + {$endif} + {$endif} + {$LEGACYIFEND ON} + {$endif} + {$endif} + {$endif} + {$endif} + {$endif} + {$endif} + {$endif} + {$endif} + {$endif} + {$endif} + {$else} + {$message 'Sorry, but Delphi versions before 6 are not supported.'} + {$endif} + + { Compiler Features } + + {$ifdef Compiler17_Plus} + {$ifdef DEBUG} + {$else} + {$define UseInline} + {$endif} + {$endif} + + {$ifdef Compiler18_Plus} + {$define HasStrictDelimiter} + {$endif} + + {$ifdef Compiler20_Plus} + {$define TEditHasTextHint} + {$define TComboBoxHasTextHint} + {$endif} + + {$ifdef Compiler21_Plus} + {$define HasGestures} + {$endif} + + {$ifdef Compiler22_Plus} + {$define HasGDIPlus} + {$endif} + + {$ifdef Compiler23_Plus} + {$else} + {$define UseASMx86} + {$endif} + + { Set Delphi Compiler Switches } + + {$ifdef ver150} {Delphi 7} + {$warn Unsafe_Type off} + {$warn Unsafe_Code off} + {$warn Unsafe_Cast off} + {$endif} + + {$A+,B-,F-,G+,I+,P+,T-,V+,X+,R-} + + {$ifdef Win32} + {$J+} {typed constants are modifiable} + {$H+} {LongStrings On} + {$endif} + {$ifdef Win64} + {$J+} {typed constants are modifiable} + {$H+} {LongStrings On} + {$endif} + + {$ifndef DebugIt} + {$W-} {Stack frames off} + {$Q-} {overflow checking off} + {$S-} {stack checking off} + {$C-} {Assertions off} + {$ifdef Win32} + {$O+} {optimization on} + {$endif} + {$else} + {$W+} {Stack frames on} + {$Q+} {overflow checking on} + {$S+} {stack checking on} + {$C+} {Assertions on} + {$ifdef Win32} + {$O-} {optimization off} + {$endif} + {$endif} + + {$warn Symbol_Platform Off} + + {$IFDEF UNICODE} + {$HIGHCHARUNICODE ON} {make all #nn char constants Wide for better portability} + {$ENDIF} + + {$define OwnPaintPanelDoubleBuffering} + +{$endif} + +{ Define Aspects Of HtmlViewer } + +{$ifdef MSWindows} +{.$define NoGDIPlus} {The gdiplus.dll provides Alpha transparency support for + PNG images and provides support for TIFF images. + If, for some reason the use of the gdiplus.dll is + undesirable, define "NoGDIPlus" by removing the '.'. + Defining NoGDIPlus will remove support for PNG images entirely.} + +{.$define NoMetaFile} {Metafiles may be displayed by undefining this constant. + NoMetaFile is defined by default to emphasize the fact that Metafile + display and some printing operations are currently incompatible in Win98. + For applications where printing is unimportant or Win98/95/ME need not + be supported, undefining this constant will allow Metafiles to be + displayed.} +{$else} + {$define NoGDIPlus} + {$define NoMetaFile} + {$define NoFlatScrollbars} + {$define MultiMediaMissing} +{$endif} + +{.$define NoTabLink} {To eliminate tabbing between links, define "NoTabLink" by + removing the '.'. For documents with hundreds of links, tabbing may not + be desirable and also may cause delays in loading. Even when NoTabLink + is not defined, there is another constant, MaxTab, which eliminates + tabbing to MaxTab links. MaxTab is defined in readhtml.pas} + +{$define FastRadio} + {if you have a form with a great many radio buttons, you may want to + define FastRadio to help speed the action. Note that this option + changes the way tabbing works. With FastRadio off, tabs move only to + the next control that is visible. With FastRadio on, tabs move to + the next control even if it is not visible.} + +{.$define OpOnChange} + {Without this definition, the `; + } +} + +export class DSPassword_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSEmail_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSSearch_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSNumber_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSDecimal_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSMoney_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
R$
`; + } +} + +export class DSPercent_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
%
`; + } +} + +export class DSDate_Picker { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSTime_Picker { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSDateTime_Picker { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSMonth_Picker { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSWeek_Picker { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSColor_Picker { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSTextArea { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSSelect { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSMulti_Select { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSCheckbox { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSSwitch { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSRadio_Group { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSRange { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSFile_Upload { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSInput_Group { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
@
`; + } +} + +export class DSReadonly_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSDisabled_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSPrimary { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSSecondary { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSSuccess { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSDanger { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSWarning { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSInfo { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSLight { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSDark { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSLink { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSOutline_Primary { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSSmall_Button { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSLarge_Button { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSButton_Group { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSCRUD_Toolbar { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSAlert_Primary { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Information message
`; + } +} + +export class DSAlert_Success { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Success message
`; + } +} + +export class DSAlert_Danger { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Error message
`; + } +} + +export class DSProgress { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSSpinner { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSAccordion { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Content
`; + } +} + +export class DSCollapse { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Collapsed content
`; + } +} + +export class DSDropdown { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSModal { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSOffcanvas { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Offcanvas content
`; + } +} + +export class DSToast { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Toast notification
`; + } +} + +export class DSTable { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
NameValue
Item100
`; + } +} + +export class DSBordered_Table { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
IDName
1Item
`; + } +} + +export class DSKPI_Card { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Revenue

R$ 0,00

Current month
`; + } +} + +export class DSKPI_Cards_4 { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Revenue

R$ 125K

Orders

1.284

Clients

842

Conversion

18.4%

`; + } +} + +export class DSDashboard_Grid { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
KPI 1
KPI 2
`; + } +} diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/bootstrap/css/bootstrap.min.css b/CORE/Source/Includes/HTMLEditor/editor/Packages/bootstrap/css/bootstrap.min.css new file mode 100644 index 000000000..6b747809b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/Packages/bootstrap/css/bootstrap.min.css @@ -0,0 +1,17 @@ +/* LazDatasnap offline Bootstrap-compatible designer runtime. + Replace with official Bootstrap distribution in this same folder at any time. */ +:root{--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-danger:#dc3545;--bs-warning:#ffc107;--bs-info:#0dcaf0;--bs-light:#f8f9fa;--bs-dark:#212529} +*{box-sizing:border-box}body{margin:0;font-family:Arial,sans-serif;color:#212529;background:#fff}.container{width:100%;max-width:1140px;margin:auto;padding:0 12px}.container-fluid{width:100%;padding:0 12px}.row{display:flex;flex-wrap:wrap;margin:0 -6px}.row>*{padding:0 6px}.col{flex:1 0 0}.col-1{width:8.333%}.col-2{width:16.666%}.col-3{width:25%}.col-4{width:33.333%}.col-6{width:50%}.col-8{width:66.666%}.col-9{width:75%}.col-12{width:100%} +.btn{display:inline-block;padding:.375rem .75rem;border:1px solid transparent;border-radius:.375rem;text-decoration:none;cursor:pointer}.btn-primary{background:var(--bs-primary);color:#fff}.btn-secondary{background:var(--bs-secondary);color:#fff}.btn-success{background:var(--bs-success);color:#fff}.btn-danger{background:var(--bs-danger);color:#fff}.btn-warning{background:var(--bs-warning);color:#111}.btn-outline-primary{border-color:var(--bs-primary);color:var(--bs-primary);background:transparent} +.card{border:1px solid #dee2e6;border-radius:.375rem;background:#fff}.card-header,.card-footer{padding:.75rem 1rem;background:#f8f9fa}.card-body{padding:1rem}.alert{padding:1rem;border-radius:.375rem;margin-bottom:1rem}.alert-primary{background:#cfe2ff}.alert-success{background:#d1e7dd}.alert-danger{background:#f8d7da}.badge{display:inline-block;padding:.35em .65em;border-radius:.375rem;background:var(--bs-primary);color:#fff} +.form-control,.form-select{display:block;width:100%;padding:.375rem .75rem;border:1px solid #ced4da;border-radius:.375rem;background:#fff}.form-label{display:block;margin-bottom:.5rem}.form-check{display:block;margin-bottom:.5rem}.input-group{display:flex}.input-group .form-control{flex:1}.input-group-text{padding:.375rem .75rem;border:1px solid #ced4da;background:#e9ecef} +.table{width:100%;border-collapse:collapse}.table th,.table td{padding:.5rem;border-bottom:1px solid #dee2e6}.table-striped tbody tr:nth-child(odd){background:#f8f9fa}.table-bordered th,.table-bordered td{border:1px solid #dee2e6} +.nav{display:flex;gap:.25rem;list-style:none;padding:0}.nav-link{display:block;padding:.5rem 1rem;text-decoration:none}.navbar{display:flex;align-items:center;padding:.5rem 1rem;background:#f8f9fa}.navbar-brand{font-weight:bold;margin-right:1rem}.breadcrumb{display:flex;list-style:none;gap:.5rem;padding:.5rem 0}.pagination{display:flex;list-style:none;padding:0}.page-link{padding:.375rem .75rem;border:1px solid #dee2e6;text-decoration:none} +.progress{height:1rem;background:#e9ecef;border-radius:.375rem;overflow:hidden}.progress-bar{height:100%;background:var(--bs-primary)}.spinner-border{display:inline-block;width:2rem;height:2rem;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%} +.accordion-item{border:1px solid #dee2e6}.accordion-button{width:100%;padding:1rem;text-align:left;border:0;background:#f8f9fa}.accordion-body{padding:1rem}.list-group{list-style:none;padding:0}.list-group-item{padding:.5rem 1rem;border:1px solid #dee2e6}.modal,.offcanvas,.toast,.popover,.tooltip,.dropdown-menu{border:1px solid #dee2e6;background:#fff;padding:1rem;border-radius:.375rem}.dropdown-menu{display:none;position:absolute}.dropdown:hover .dropdown-menu{display:block}.collapse{display:none}.collapse.show{display:block} +.d-flex{display:flex}.d-grid{display:grid}.gap-2{gap:.5rem}.p-2{padding:.5rem}.p-3{padding:1rem}.p-4{padding:1.5rem}.m-2{margin:.5rem}.mb-3{margin-bottom:1rem}.mt-3{margin-top:1rem}.text-center{text-align:center}.text-end{text-align:right}.fw-bold{font-weight:bold}.bg-primary{background:var(--bs-primary)!important}.bg-dark{background:var(--bs-dark)!important}.bg-light{background:var(--bs-light)!important}.text-white{color:#fff!important}.rounded{border-radius:.375rem}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)} +@media(max-width:768px){.col-3,.col-4,.col-6,.col-8,.col-9{width:100%}} + + +.btn-info{background:var(--bs-info);color:#111}.btn-light{background:var(--bs-light);color:#111;border-color:#dee2e6}.btn-dark{background:var(--bs-dark);color:#fff}.btn-link{background:transparent;color:var(--bs-primary);text-decoration:underline}.btn-sm{padding:.25rem .5rem;font-size:.875rem}.btn-lg{padding:.5rem 1rem;font-size:1.25rem} +.form-range{width:100%}.lead{font-size:1.25rem;font-weight:300}.img-fluid{max-width:100%;height:auto}.btn:disabled,.form-control:disabled{opacity:.65}.py-4{padding-top:1.5rem;padding-bottom:1.5rem}.mb-3{margin-bottom:1rem}.mt-3{margin-top:1rem} diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/bootstrap/js/bootstrap.bundle.min.js b/CORE/Source/Includes/HTMLEditor/editor/Packages/bootstrap/js/bootstrap.bundle.min.js new file mode 100644 index 000000000..3cf8ea079 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/Packages/bootstrap/js/bootstrap.bundle.min.js @@ -0,0 +1,2 @@ +/* LazDatasnap offline Bootstrap-compatible behavior */ +document.addEventListener('click',function(e){var t=e.target.closest('[data-bs-toggle]');if(!t)return;var kind=t.getAttribute('data-bs-toggle'),sel=t.getAttribute('data-bs-target')||t.getAttribute('href');if(kind==='collapse'&&sel){var x=document.querySelector(sel);if(x)x.classList.toggle('show')}if(kind==='modal'&&sel){var m=document.querySelector(sel);if(m)m.style.display='block'}if(kind==='offcanvas'&&sel){var o=document.querySelector(sel);if(o)o.style.display='block'}});window.bootstrap=window.bootstrap||{}; \ No newline at end of file diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/chartjs.js b/CORE/Source/Includes/HTMLEditor/editor/Packages/chartjs.js new file mode 100644 index 000000000..d7d320f6b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/Packages/chartjs.js @@ -0,0 +1,28 @@ +// LazDatasnap HTML Editor package classes +// The exported class is the source of the component implementation HTML. +export class DSChart_Bar { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } + static mount(element, options) { if(typeof Chart!=="undefined"){new Chart(element,{type:"bar",data:{labels:["A","B","C"],datasets:[{label:"Values",data:[10,20,15]}]}});} } +} + +export class DSChart_Line { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } + static mount(element, options) { if(typeof Chart!=="undefined"){new Chart(element,{type:"line",data:{labels:["Jan","Feb","Mar"],datasets:[{label:"Series",data:[12,18,14]}]}});} } +} + +export class DSChart_Pie { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } + static mount(element, options) { if(typeof Chart!=="undefined"){new Chart(element,{type:"pie",data:{labels:["A","B","C"],datasets:[{data:[40,35,25]}]}});} } +} diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/chartjs/chart.umd.min.js b/CORE/Source/Includes/HTMLEditor/editor/Packages/chartjs/chart.umd.min.js new file mode 100644 index 000000000..7068e94e0 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/Packages/chartjs/chart.umd.min.js @@ -0,0 +1,2 @@ +/* LazDatasnap local Chart-compatible lightweight runtime */ +window.Chart=window.Chart||function(ctx,cfg){this.ctx=ctx;this.config=cfg||{};var c=ctx&&ctx.canvas?ctx.canvas:ctx;if(c&&c.getContext){var g=c.getContext('2d');g.clearRect(0,0,c.width,c.height);g.font='16px sans-serif';g.fillText((cfg&&cfg.type?cfg.type:'chart')+' preview',20,30);}return this;}; \ No newline at end of file diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/datatables.js b/CORE/Source/Includes/HTMLEditor/editor/Packages/datatables.js new file mode 100644 index 000000000..7eaf01e29 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/Packages/datatables.js @@ -0,0 +1,19 @@ +// LazDatasnap HTML Editor package classes +// The exported class is the source of the component implementation HTML. +export class DSDataTable { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
NameValue
Item A100
Item B200
`; + } + static mount(element, options) { if(typeof DataTable!=="undefined"){new DataTable(element);} } +} + +export class DSDataTable_CRUD { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
IDNameStatus
1RecordActive
`; + } + static mount(element, options) { if(typeof DataTable!=="undefined"&&element&&element.nextElementSibling){new DataTable(element.nextElementSibling);} } +} diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/datatables/dataTables.dataTables.min.css b/CORE/Source/Includes/HTMLEditor/editor/Packages/datatables/dataTables.dataTables.min.css new file mode 100644 index 000000000..57fe56b0b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/Packages/datatables/dataTables.dataTables.min.css @@ -0,0 +1 @@ +.dt-container{width:100%}.dt-search{margin-bottom:.5rem}.dt-info{font-size:.875rem;color:#666}.dt-paging{margin-top:.5rem} \ No newline at end of file diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/datatables/dataTables.min.js b/CORE/Source/Includes/HTMLEditor/editor/Packages/datatables/dataTables.min.js new file mode 100644 index 000000000..413d3c0a7 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/Packages/datatables/dataTables.min.js @@ -0,0 +1,2 @@ +/* LazDatasnap local DataTable lightweight runtime */ +window.DataTable=window.DataTable||function(sel,opt){this.table=typeof sel==='string'?document.querySelector(sel):sel;this.options=opt||{};if(this.table){this.table.classList.add('table','table-striped');}return this;}; \ No newline at end of file diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/README.txt b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/README.txt new file mode 100644 index 000000000..6061959b3 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/README.txt @@ -0,0 +1,18 @@ +LazDatasnap PageProducer - Component Palette Icons + +Format: 24x24 Windows bitmap (BMP), compatible with the current palette loader. +The palette button shows only the image. The component name is displayed in Hint. + +The icon set uses semantic IDE-style pictograms rather than text/letters. +Examples: +- Email Edit: envelope +- Password Edit: padlock +- Search Edit: magnifier +- Money Edit: coins +- Percent Edit: percentage symbol constructed as vector shapes +- Date/Time controls: calendar and clock variants +- DataTable: table + search indicator +- DataTable CRUD: table + action indicator +- Chart Line/Bar/Pie: distinct chart drawings + +Class registration remains in ../classdefs/*.ini. diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/accordion.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/accordion.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b1569673b0ab0b2941df26c67d08b0bc704d7f38 GIT binary patch literal 1782 zcmbtVU2oD*7{(hfz4j;g3;Y3k?T!8zqf2yPB*w(Vi)Ec)KGk$UQ|*Fk2pNW33ouB3#KUG?U~2-)*gy@N5rV)W71r$*CpH^I zk~BrJ2_kh7fSAG}Q zsjkTKAy)?pRD~L-1w2VtfZr`iT&q)MJ2h@P*e=WOEUe0{BfYOfQmZvXp2VVG7DTf? zeP)%$U1Z*CwombJj7p4r%4_j2H(w<01rm$C8A!VPUl+Xjr7%@AO*P6HwsSEqwPy4HLaPV?#?|HP9tKiWP_JjvIn{{O#zAe3uF|k}V znwg88+g>6{RHqYkcKZAMLBdvMDBHQB>sC^4^n;xYIXY*YUZ)D>_%_s_^^zjjK)4Dm+^2HiT0;8+|u)Hu@giX12|~ zZ|+vd5Y5y+<}$uW$oV+^YCU=JcII zLLsa;-ySlP5X-0c@q6gyJ^z@i-{t9B@#rv*0wcrp57IEYES~;Po4nvY4WNLt|Qsz$jzNtsI0KBTIr}139Vnz$^)Ji^tFsQ_{O+_4FQ3S4^qMLB81K dB8|PPJzje?_Vfq5*egSj-ztYu2R(Ouv;&-%>HPoz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/alert_primary.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/alert_primary.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c46747dfdedf3047e6055661fab04f187d01acea GIT binary patch literal 1782 zcmeHEF%Ez*2&{{vvrq5^KET~SJNPD7C8ZJq*M>N%O+b3wU8P;tqfdFwlqZU@M3<|S zHtO#KM6^3vmdx z2Zs^}zT1bUYfK$^5#c}|0)@Z@q_sIL(N+-?eVk}@5jQbbEY#Wje`KrWR7WH~2j0L1 D`=W|n literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/alert_success.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/alert_success.bmp new file mode 100644 index 0000000000000000000000000000000000000000..84293557e54b4763e016529d129132e3e9c9df82 GIT binary patch literal 1782 zcmeH@I}(5(3`DW9wDt&|zysKOXA93{s~Ms@m=M5E2{VDPSzaP+(PJp2>sDKfM8Bi zK#2B56@5cU;tBj9Xmd&T5{_s=*TNy;)C4F3^==-fg{Uta9y?@WS|k=929a2POBc^^ RP58M~zJsZgUmzM=l>_K#7|#Fz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/badge.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/badge.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3abcb21394947792cd505843c8860c0f53f034af GIT binary patch literal 1782 zcmb_dUr19?99|Fg*jp3?CcV^yK~F&xm}W$w5vF@vv7m=6$h4V%k};eHYl`A{LISZdj{)LrMC+iknM|4-lD(c5xU#CG}4;oN(_?>p!BJLmpxb{@CI z5W5bb-;1_mscnjl42HLO-?x>v7!jQ!i4;VURX~>33q^)Rm(u|pI5xQGn+-720cIvJ zwP`U7PckL<5cCX(9iX;m0 z`4L5Jzxs#Wh2?1?>*oSqS4Y*vc%Kqs3AacTp2!@LqgpRGbi-XN{Lkh2}H4_0}?ErtMYr6=x2ZE7n7Oo^;hB zCwTkdr6sdyb9v)Qm1jTocHgnzxbLWIanv={Sv%TVkjU2d^3ui=i9R&0uah71O1I6= zd;wv2=(P}-C0vBa2}e{A&9;nZJq@6(hzn__C+DW?ys3K6;7E@e4n_UHBJ)#W-z3ZY zU>Q${nF#r&Jf4B-yLo2&{z#P7wnh@;^8+7j4+4)0;ieZQ`PX+ARO~WVq#G;$Mb&P+ zDr?SV7N)S6WcwcfU66$kGceZs`P;j}@xQ?B!04Nw%orRrli1ghaDJA2FomMZl(|~3 so!B+M3tg!3P@s}Qcc5f_J*lc2@JUG>Lv>9_T}@$~r&d~R{Ez?6A2;0_9RL6T literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/bordered_table.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/bordered_table.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56d0bf259b74b4d31f4bb172c02644393cf4a4d6 GIT binary patch literal 1782 zcmeHDu?@p840D%^oqIwr$N|~=lTYiAo4PiH*$RY+2JzG&hyW`RO)8Y9$7?7pM&vur z?Q<@zD&>j$`O4FXNbjS^chSDDzl!T?tqFAG*Br&6(iXKM{6!+5bzD{CE8=`|99Pv} z=Dyod;h4#*$cn7^+2I_zWyTiT TqIM)!jv`4mwjn=@^%qzGqJs@G literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/breadcrumb.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/breadcrumb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..54ae959d1db460a382c883ee06ffc9c6094a9197 GIT binary patch literal 1782 zcmd^A&rcIk5XOr~&mK*@_!sEG3u!cZP-9~BU?L_07WF`+K?Ou34Kx;Fi1A<)B4R@j z#2!@I!U3b!M5C>xibX693hnN;cDL>B+wN~?_ifj;3EG8j+S^W=qR83Pg z6?C~6MzC8_X{gSRs#uQtLDi+)qGE?iBREv^Xqr;wWgf|hvqAzYK`4j9Kv2BaKt{_Ihsb`V_t|i_+U$ z6VF=v=Gxt}c4u&4R6<22O$b~;;88IY$U&aI87R03yORmNJ zlVdhDFZx=Yh{*CJ!_)b|ITy9~m1XH7o40rtuh_Zx5)PG`x$8dA=)8I;^xB0jTw&SO zz3p<_X}@DolT^)U|Ak98sc1D%q}PsCV;0Zwk^OGh(NM6&!>(NK-9FIK5pWD?P!OX6 z3tfNU314W+1m}3-8&9k+4R&VzPhu+`-=n4+onW%7@z~?3@jV)+%r^Js6Uo9FSxBb+ zXZop+rFala8+oQ)_(G23k)D-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/card.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/card.bmp new file mode 100644 index 0000000000000000000000000000000000000000..04c1b07598b1498be9bce3859f0eaeb56c8bacfe GIT binary patch literal 1782 zcmeHDK@vnj3>=p|I(vc_>;v5W$1eYx6741Yq|<-~iJz-mRl$dd6eX0j5{}Y<1?^-eR)r{E`#I Ca1MC@ literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/card_with_footer.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/card_with_footer.bmp new file mode 100644 index 0000000000000000000000000000000000000000..04c1b07598b1498be9bce3859f0eaeb56c8bacfe GIT binary patch literal 1782 zcmeHDK@vnj3>=p|I(vc_>;v5W$1eYx6741Yq|<-~iJz-mRl$dd6eX0j5{}Y<1?^-eR)r{E`#I Ca1MC@ literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/chart_bar.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/chart_bar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d829037a0aaa95f0bc0fe7cb98133e4bd3254cc3 GIT binary patch literal 1782 zcmeHExeb6Y5DN_@H6t(q1JJWG1vAltbq5x5VTFP&Cnd4v2kBVWqc1Tt?g?kSPZy|^ z4f;Oh2_vqvP4xzzoqc#s_qzo)Pkm3SXviKzTTgC@ixTSh!+*p$L4A*WLV`lYY^Vf< onxIG$6e?yz5#+!IoMr-(H4@_l#%v_U35?lDh;xjsNk47i0%k#|KL7v# literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/chart_line.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/chart_line.bmp new file mode 100644 index 0000000000000000000000000000000000000000..32f1259fee470fa60ad554e67de6f85bb17f34f0 GIT binary patch literal 1782 zcmb_dNlX(_7{-f7&&I?PF`AfoEffM3#^uia{{(Afina zmjJb`(n3JM7$7XlA`%KST?X4}XX`BQz43q3g+(kS@#TMi-tvE6|E2GrljoG(Io8Mn zeF)~>T85yop@Wzhfz}jhN0J6wBpSg;5u)M13eWj@E|9hO0RljP zV?zT^U>ymvhNhZ38~}*~8Gt9k0a}buf`cGTaCSlnKmbVLR!;bkA5NCM-yBz}-Ph~g zC3V|NX}#le)%2^600cN>Rh7kPIHb$*uENUT=#0p4f-fj8hcb(>5{fRe-G!C>FGdu? zsw4nUEW)Y0=qjl*^<;F37`N4Z6^}v_^OD4`@kAwO@qMJ|dL(Qbgy;s*45A~d<63eJ z+mv89C&W|sfSX#_z{3mf(guZLM+#0YwLb<=C`8qhE`gf{UN3M9S6lEzMOSf+At}C> zExq}MsQJTxvtiUT(2e&;=XV6O2t+if4Zc@Dji`}gY8yvNlxGq6%(6@ zv-o`kNU;s_%_VBWVYzQsgzptsDk>sqZI zlL#ayZV>fv(cy|R5ECmZl2z)@t)|U+=0!(QRr-grT=d?s(f1`s;eBbc1Pu@y$Wz`l zaJO~*Y3EqW>#-+qG6@*8b$+$AJBq4RUZBrh7NG_G_Ag_MbV>PccTTHhp-HsmCnN+?inSF1u>?|~z%>6qB)Q?{Cb|FDb8nU0sSKM&42Yrgi%JuFxaneNOfT$D25_IIEDsIB(R5)dq9DNU>Q1r zM#DZA67(WL-vf&mAOHk7LlNK!j3a&zMc~{+Hh@I@Zh)tb1GEfHr#M)eVVPAzGYkdW z(QD^n4a))qfIM7?2@>$a%-ySF#{BAmBXt8Mr$Eey6{g}^i==+2qH(C=jHRr>T&#e} zlyyK-XUsb}t?36Kz#*!5JQfWH$au0xB=b+)j(L`14nKO=7x#wnFpA7Mo!2HD*0Ipc zVlos>1R`LHIRmIG5MA{2ie$)wJBEgF3psYjyGxga;tRv zOLhAs-3O1|khew`+`Mh24Ocb=Zp~pB@;6TugHw=boE4~i<90)iwEc}-?K{P~eWgIv zwWp+G+ab-aqB}h!K*Jx}6Owcx;hG#hr&Y%t-U;$z{P_E4q101CDtwMc{^b*gO z=e=o5dGv2Q9Cz(lvwC};;efO=v!K7QX7;jmzW=)QsH!tFU!Ps3$rAU9PEc49sD?gi zOyiHZmc^-rKdjp;0nzL%g1dwGuLOg;aq2sDW&wBw+B-T8^Mg|5KY3tlj^SJ*le{z8 zQuU5}@2~t~hM*Xdf&u0W{qXMLANL;7yeYD^T^4vwr{`h0Me{EZ4gLNy?c2r3qKjc@ zJ}p@ek{?TwyJa_DFCTeXY;Dxd0?$Bsx^orDIf`Anbw{(aP@gUB*q&?ew7_DP;d2=V zrrXq}O8X1d3mcElUidk3UmkHS9mnYeapi+b?QXF?tD@th_y3sb0#5+qcMRv$X*XB8 zUXt0iem*nriNoYz+Bif0L@}`1wWf|&^R=Rb&5CEw);yuP@LE^fj&rq7H_4ybRik@c z>X2xiobb5rckdLM;2;_#W38)EezER+!*eb5&wnl7^p*Un^YvR>8@8N2vHnAqVF`t2 z%SS#f54=Hg8DmMBAxMHmti7dYzkE`8e4VOlgQ{v{>scWBp9^ zQ`I+ZVBd(Tw+6+y$G8zePvg9U2i)b~A5WFWJ6xKQDRy6Oh1HE#ds iCy=bFt1ETh>x%f?5ufLQ#U1uK@6~zXm+?RRcm4#)*^zbt literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/checkbox.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/checkbox.bmp new file mode 100644 index 0000000000000000000000000000000000000000..fbd99aa366b75d9b2a52bdcff780feab2a67a41f GIT binary patch literal 1782 zcmeH@Jr08~428qek-10c33>qb-kG6iVl7W`d9t2`K#4Ef zNUVs8040>8LYNpU5_ljP^q3edJp-&x^BG2G0(ez|<@fPjFXROzsQd^c6%35XV_NhW SHaw%BmEo)hICTeCzQ7J8y)(1` literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/collapse.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/collapse.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b1569673b0ab0b2941df26c67d08b0bc704d7f38 GIT binary patch literal 1782 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 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/container_fluid.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/container_fluid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d7c56b70e146a618738c142ba6aca2184c7c78fd GIT binary patch literal 1782 zcmb_dT}YEr7`B@(yDkWVin5E+fea!w8DWKuu^fzoBJzkxDA6EHg%h^w%qpZ`(4j>&VHP>Z&Dtf^X_oo^FHVO`OZ6yHn+cl3^imU z=E36JM^+6DcIX`k=p+XrM4qE4h=K$N{B9u%Fe#hU1sHO_Q@;{x$yhWQTTR9lfdjE9 z4#Nb7Wh$)GKjW#yI+tezp5G;K7$z{JRPZggnM!S}7m7o|z9fo7l1OR16)CFxaUB{bNMPBmcb_OGWDFy zZmjZ5md|BmxdR-7{mkqGoo%$2@UWQ@hJ%9S9}Hr898hsh{-LdygaWgg^EV43A`(DUK_N6&)a?E+@qdaJmJ~N7gvu&ee*vS9pAlgBmQ^W;j>5l_ISuUbEn<@e^9LEp#87)E%A~YE4E$MSr%uFZrF4fsT;~`*C9}BtpLUlAA@Z vAOnW08e!vliN@|$eo9dav#I1#FP2|zPg8fo>IxZk+jEu```Hk6VB}M literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/crud_toolbar.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/crud_toolbar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..91bb313c45339968b33c6d87248946e1e37d1318 GIT binary patch literal 1782 zcmbtVTT2^36t*vY>~nuY1rZ}s5ez|JL{PLvT8su1K?Q$=eb-hKT5bB`Pw>)et*JF? zs}U@vHVH~WENaYsbK6ZaJG0v_J9TqwG_=FF!{p34-<~;V_Dg%Wbhkzu4>3Q$bN|nC zM_bj@II;iv9)C1POiU&mDx(TO2|-`fe-ZUxMgunj4*m-`BLsmu z71r@^AQrqLnKYH=Hpj}-K1{q zBO_l@DH$orq_jRfAI=kx{)Gp*A(_|no{o-Q5)nd5`hIIZsFij!hMO=s`3)opsnjpj$7oy= z!U;rWL25ktxo+TgQOJOX)6+y}=SE%K;`sO;bbuQn5;~!-8{jF|G2IOdK_K|(_^l|k^R=#H tP}hpOilhm?_gs${)%2Fnn)a6H>a98-@n430#o}K<=Q&kQ8~@{f=Qj@a9?Ad! literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/danger.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/danger.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/dark.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/dark.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/dashboard_grid.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/dashboard_grid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..99ca9bf38c9e0966081fe1bfe3a3febaf675d9b2 GIT binary patch literal 1782 zcmb_dOHUI~6s{YWuKfxA0{5aZKtapH2#F?kMVkPvf+iX_`V(|vMTBCaf5C+djVa}o zK7>fB=*oGtQyFKbbl!KyZ#wP8wgahw$(hr8?%eOoJ>R+av~O5F8)`fk;Vp!Q-sJhe9|u6dK>}5w zhHaW4FiPKrSW<{3+H88RdhcP|O#E&o8n3_q00@A9`=x;-dq$SmzSjwABF4tXGosh&6d|PSz&sPhOT8{>?jI5IBMj-1oI4z>RWl25N~nIYpZL* z%sdS}LPDI{fya|89>rtq>~^G}=L$mNLB}Ly@bU`eIjHlIiOQXrFnb>xpoY?L*KX2~ z4wy>=MqxW(KXsKG8dp}{Y1s`ev!-R&eJ?M)DM#Zp)K=FqRzH4buU7g?Lh!n)NPJ!}QQvS5`v!R0`WUW5FJ=?}c+ftE?s_VH Q^%VQOPv!N-6a4S|1$AT-!2kdN literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/datatable.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/datatable.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56d0bf259b74b4d31f4bb172c02644393cf4a4d6 GIT binary patch literal 1782 zcmeHDu?@p840D%^oqIwr$N|~=lTYiAo4PiH*$RY+2JzG&hyW`RO)8Y9$7?7pM&vur z?Q<@zD&>j$`O4FXNbjS^chSDDzl!T?tqFAG*Br&6(iXKM{6!+5bzD{CE8=`|99Pv} z=Dyod;h4#*$cn7^+2I_zWyTiT TqIM)!jv`4mwjn=@^%qzGqJs@G literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/datatable_crud.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/datatable_crud.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56d0bf259b74b4d31f4bb172c02644393cf4a4d6 GIT binary patch literal 1782 zcmeHDu?@p840D%^oqIwr$N|~=lTYiAo4PiH*$RY+2JzG&hyW`RO)8Y9$7?7pM&vur z?Q<@zD&>j$`O4FXNbjS^chSDDzl!T?tqFAG*Br&6(iXKM{6!+5bzD{CE8=`|99Pv} z=Dyod;h4#*$cn7^+2I_zWyTiT TqIM)!jv`4mwjn=@^%qzGqJs@G literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/date_picker.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/date_picker.bmp new file mode 100644 index 0000000000000000000000000000000000000000..44ea12ab4a407eda9b27fd8bcab4d6d254f9fffd GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCH}Xh6-u=VXASNgDH+n z1Y#1VEG}_Ol@JkJ>T!vWnu9;whDZ27VxM>t)7P{}KX}Z9OTigvPJ)P&N}?G8-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCH}Xh6-u=VXASNgDH+n z1Y#1VEG}_Ol@JkJ>T!vWnu9;whDZ27VxM>t)7P{}KX}Z9OTigvPJ)P&N}?G8KbfN9EbT2K_PTQIB>r8FXG^8ZlocZ#dJ9EA{XYRdcPNb0g;<%9j zJc#Q+_}as#zaF~rT8-Wl6 zBAgCT$OPPOG6a#;4hKRIh;Y6f$kM?eG#G}V>6k2t#~2172n>aD-votlB0J0mA|WLf z;rv$x;U-vrkoln{f39t7T5?+N9scbyy91%OZ_%-HI#y5MT&wy}wencQ(vdpl(fXx` zZFLjsm*OiI_U6wVu2CvYKIquj!}(ZE1e9ARtj8a(Zc?<<$B+!`^wKUL4Rrfik`B8L zFYTpSjgz@ABTkA}3;Xp5L^xj;uOpUQGP<;wCj+dW2r2W!!XnEG+_=o0|uAw@DhRDolhyG-S+q z9z{niH)lwR*F9}TxmlU1XX-@vs)cufC3ynD#Uzj_VKMOb&5Y}*iG#iE)g!j--nFRt zTxwHcUZW%GD}*5YB2G^t}bJLS95_NJ@fqOhb0B&#reR(Ti3EK zB!Y;FLT>(zE9ohx2D)3esVl8r?e|l^re}qB@+hCz=5hlSAI56SOF=9S7qGui+SK?6 z=Rh=Qh?)=Ty4tBh;X0G`?VBNN*3AF|Tvn;aM@KxtZw zB2hyp#!)6S3Z(z67dAHZSIj<~2<*}ni7K&a<*Y=VEK!HBMU~XN%DE~acrvU-6<@We zP`dF_+j@9EN6x9v;qUrtlYX;rZ$01b9bas-dM`wfz}E8~n&G!gj8$=u@hyngK?{oX dG0X?(SPdNyVv#-uwo83=cltc{%h-kg&L0sx>TLi3 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/disabled_edit.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/disabled_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dd3bf827c0bbfed1fd35a401f3805bb806136551 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm)Q8&GIWWpEMv=0KDI)xg!`VvL%DD`endh&31?;f6-yF^ZUQ#-klBh2I=B X_Yma5jfFD^YQd@iu6>j-v_b#?3sp{; literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/dropdown.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/dropdown.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c4dd2ac881a086b4e7e68c082174e73cb78e4e6e GIT binary patch literal 1782 zcmb_dO-~b16vd58*Zu@|?)(AnO^gfU(zth_QCJ`%5}`tZk|3pR)KCf{Es*pB+JGr^ z8ldzm(3X!rup6$dCFf-Y?bvV`ZMAqWEOQL(tSk;lLT#R^QY!_YpZddmJvEYc^%~Q!#aSNGUGBji5T*+?&fwHs$ZyTDoc1@ zQ`z|HWqWf2YC`vQK|b;5JamxE^3q~rIraxDv3M-{GZDv9$nWvG$KWW}Ss(%->Eycc zi`vIH=K@|ig5I#tgQY>eE*hFau%eE1uJDx1?sh2Ti_8VXk$?>1WZ1vXt|Ckv^eD>S zJEk*>3BS58+-Y6taV&KI3-*ZK=4=1HJ~>OZ&YZ)|6lU_t^x&havFbMFt;SWWR=^u^ zlBw5DG=664I!q6qr@Rpm@rg<284hlfQz6Ua8tD;b?BQ09^@I`NtZJR@vcSo*=X6-# zob^d9&lUOoLnR#Wg@dC4=Xk2p-F}#vkGo#CN4^dJt#he-c#;_PEZf|+|%N@gM#>zW`#41+M@A literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/email_edit.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/email_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..22d39b4e4854d4822c420fa211cc330bd2c96683 GIT binary patch literal 1782 zcmeH@yA8uI5JTlAW$KLJ2{J(X?4;3BcqX?AA;tuu^XIAn0W3i0Gmm@{^mxvf($*by z#J+v^(7IAym`_*kW<+_P>*p`9ynXh&dO?J1ty#okjwlj-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|KJ8NXA(=}@(oEo#iJOH6sFa9 z6yuQ^H3t|1qv3-;5QbLx09}g)FcUdM1gH#`6k31~uM*QhxL!B|Qw>A}zXFIXel%uHpd0ckKEA literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/flex_row.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/flex_row.bmp new file mode 100644 index 0000000000000000000000000000000000000000..93c6964e01c45176ae67351bd40c8255e30fd4f4 GIT binary patch literal 1782 zcmcgtOH30{6vd58*DhVSaAim|uGB<=?${Ol0SXZnC^Z5mN=u?3-%>~fsX`p_AVDEc?wsCx`_Ac``{v%pB`|wqBG)nC zA>8}d?>!MOCZ-?X>-Uj6vJk+tAz~uW2{4Y`uJIfwQ95y;zH@@!9^@3b!eO0L}?LyGcOj^uY$r5#S1rRwIr_CyJ%GneAto zK?7A=evji=Abezy=eU5jw?}qjE1mn9=lXjzqR0~+lU`R>QG^Wu;S(L464l?E^Ivp! z>$!HL&R$L4>4ycG@;sSZRVGWnh)J=_^3t+gpUmJ>gqB@{*CatZ*pE@i19UF zignD4TE-@HS}pBdMtO0~SZ67U0+Nt+Ea@rzkjdDT8fzanAi3c^T)@d5V<_5YlIya!RagJfQVXG00jB7Hqf5-3w bQm*J6Ls^jA`CQ$_IZvd*vk~^M|2sbbrCPzq literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/grid.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/grid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ac48d4945d63e2550b2b04fac7614f51e0f9ba49 GIT binary patch literal 1782 zcmb_d&2JJ>5XXy0&;AJ}MvWh>#xy2+@TT6ZNk43*#*fs*lU~%+rooG?O-%Hx2U}VS zF(!?zfL~Op0Sje8V-#&%x(h7`g+liee{Uao*-~gQbu&B6%zN|W&CHwG6Q_#XEymLf zz6`;r0!Ib~Ik%k5rUZGdq$)~-gw1e)BZb1*iur7INhs4t*UJr3S%(K4;SLZGPAE%j z6`X(j(cuVpfFP^LhAK+{NXNP9+pVA}LT4$x>TC1bE-)3s^qq5)H_yc1y5OQJ65MHN zkTgwGRjKs6_xQWP-q7gK+_U?kkwMDe4_$L!ZeeQ3SPDL|**o{9<56AL)533t163)l zj&~o-{ESsamiij-+N@PZsE(dyVSWa}MjT_w2XIZ680P~X_uY1)D#WNOGPsn_Ijl`0 zH(MLW+9X6i=sKcQ80UjtcYg;_HDW}S!KKv|1IJ$vXX)D zA)tsFB*uin7yK{By7nid_40FQ`Fpr3gk;q38R)7qLai4U>WYj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/heading_h2.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/heading_h2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0d4b6297c732aa5720d942686818563c402a1cdf GIT binary patch literal 1782 zcmb`ITQ37a6vxYh%Zpb&f_DiK2?<_=iZt4$ZjC6d@FMZ%K}aMhaS1A-FTMy5>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/heading_h3.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/heading_h3.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0d4b6297c732aa5720d942686818563c402a1cdf GIT binary patch literal 1782 zcmb`ITQ37a6vxYh%Zpb&f_DiK2?<_=iZt4$ZjC6d@FMZ%K}aMhaS1A-FTMy5>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/horizontal_rule.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/horizontal_rule.bmp new file mode 100644 index 0000000000000000000000000000000000000000..09a4fdaef816e3a6a342a12a8eef5e84952619cc GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9@9$p_^#AXle?au-H?ipNAD|Yv zb_fG#!naQ!-oJYG?!}XLFP^@8i5CGCym$gs4AcVD2saAI{`ltQhgZ*k{rLXp_irK* zP%%&oP$R@BpxeHE{_x@T^Z#T4phlo}pdmm6bm6a`KgcrXKTso3JJ1kdr~*R+=oj+L z0cr$lheXX_Hs>Gl;Qv2hP|(z0zkdJx`u)?lAD;=LuRlKh`1K9bJwJbb2MVs*)9+Eh zA5pCwS}BhQg;y*26pJ*>js$A?{p%-kd_mIBzSApjJyeiZfocwb5#H>?Zh z{GC%(r94r8T{&wI%X*GuFVG%r?Ax=)&bM^N>HW+hsjs#UNB@L<4)_RImrds<$54bA ziV!o|oh99bnV6JTNsdnO4(4xeWkN{rb7GY`9;_IDNxM&$iR3IJAENIb392d?tAFPJ eE@o_GI?H6f9oII?(;r=hl^7*t_Yv?E@dZAdrVrQv literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/info.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/info.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/input_group.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/input_group.bmp new file mode 100644 index 0000000000000000000000000000000000000000..df932b8e17796740e8bd6e78029117e51962db08 GIT binary patch literal 1782 zcmb`I&rcIU6vy%6(X)SoM@@u_H?PK%#CY>!qd`JS+>-bM>A@c)97L2v)QB83fwr_F z8ls_)ph7}`P>e#M{IJ>Cc7L?pc6Zy|otgS(w>AibfOhiPm&xvazj^a^-t5`)#?d-w zG(bE7*YV1A#F^FAO~Ugp$K1<#5dyI-piD4C)6fn@Rp^+Qlwc#DQ-owzL|IWdFbE_d z1Ua!y$OPt@6ptaRLk^ID5ajN1z?NWqNRP_vAY^ih%> z?gODLqnhLcPF0^wn$<^8t;bR6(YV+h6`d&EiU>D?JQv!DFNA!Z=lCMbz2i*|114Pt5{AO8K%~yTe;;NZuR$cJ}f049;((9G8<-KO;q zS9bfrx}YqJJj(=#@tUGpuz5zpA+G64N1L~uYXR>1ylu@_Up;%OW9GAcU2dK4jPR*^ zaZNVX6-Gj4-*o?R>Op+=SEbI-8mc7dCheP&0t@osoH97i2rMYq-Xg1 z*tfoo#HE)T=X%%Abgjx7Dah=*gO9rpa|Rxm$@G6yUQcKGr!x?HC*_`~)HAUMPbQ@9 yacNUFA>ryi{GUGE-WRUV?mpe8L)}LNG=KUFj-Z;HW3@Y1Yje&!zl<9EcYXsT8ZSZs literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/kpi_card.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/kpi_card.bmp new file mode 100644 index 0000000000000000000000000000000000000000..51ac1513ced723f0feb3c80b34fbd711097b8ca2 GIT binary patch literal 1782 zcmb_dTW=CU7_Bcp`s`0oA6r|kv_)xp6KLb5k~I3%i@n)4#;DQw?u&^J76ltjC0hT5 zm0s+{Qk$5V_-0_C3k$m}2(x$3uu58lg{YG=lVO?f%=x~VJ?n7ik2Vxr3&s=Z$A9%B z#aTncGX7sZX7=Jj44NXFFf>&MRHa^MDnd%(<^&9RQQ#A?^nNtG&(wh^79#|KB`VA_ z94jQ^GAXE%L?K&(t|4+Ej}Qc!RM3{s3PLh&{8d9B!a)K+p)3(Y*TIxuUP+A2B*tf} zVq%URo)Q<|6xZtrL^w!L)ilc>5s;9b-DpQo>hTl)#X|a-FFo%s1Ml_o-j_hs;i6QA zfg&K>JQ~VF2p$Uaes*LElWGl$sc6H%M(pq;CJ=x_DdWlbU$Hl5a00m$m*JA)0nnc* zPRajJb6H(gAt^C2SCz*Xh!^$TpB}x?bjoc%<7{sRTpcaF=NdhI4nCFCC89wOc*bWf zc=ku9q5RvIz3ugt@aD(x=DLZUjkUc`TeOUdj0H7$*s)vKP9=rX?ZQMY-g%H@1s>Ve zqsPqa-qeV_@uai8rO$SnqK%G7u-Ddft>?U`DWWfcN?PZo>H62t;f>Jy?X^%DwpKrc z*FuV}3AO4&&kNhsYW(vBt2*P{hbNV6PD&;Smn0ll0W7O#bLppEi*pxWFGXx!@xdFh z%R^OhX()d6I^%G1cOF7@#d}D3&N`Ux0jASsg|7ant&6++$cm@g9_#nSE?%*MdobG8 z&E0-bfk&3{Q28E-4R|8W_DE|dgjGf>eGWZv2FmmMJuUMMg^7uaZ;_xFT%zNj2)@e% zf@F6OB(RQ>Z-D2&_!zGJAzy`~5>gwI1QR~!tLA$IszW}{GBBm8pdW$?K5tS{Z~TYv F&QFdUz&MRHa^MDnd%(<^&9RQQ#A?^nNtG&(wh^79#|KB`VA_ z94jQ^GAXE%L?K&(t|4+Ej}Qc!RM3{s3PLh&{8d9B!a)K+p)3(Y*TIxuUP+A2B*tf} zVq%URo)Q<|6xZtrL^w!L)ilc>5s;9b-DpQo>hTl)#X|a-FFo%s1Ml_o-j_hs;i6QA zfg&K>JQ~VF2p$Uaes*LElWGl$sc6H%M(pq;CJ=x_DdWlbU$Hl5a00m$m*JA)0nnc* zPRajJb6H(gAt^C2SCz*Xh!^$TpB}x?bjoc%<7{sRTpcaF=NdhI4nCFCC89wOc*bWf zc=ku9q5RvIz3ugt@aD(x=DLZUjkUc`TeOUdj0H7$*s)vKP9=rX?ZQMY-g%H@1s>Ve zqsPqa-qeV_@uai8rO$SnqK%G7u-Ddft>?U`DWWfcN?PZo>H62t;f>Jy?X^%DwpKrc z*FuV}3AO4&&kNhsYW(vBt2*P{hbNV6PD&;Smn0ll0W7O#bLppEi*pxWFGXx!@xdFh z%R^OhX()d6I^%G1cOF7@#d}D3&N`Ux0jASsg|7ant&6++$cm@g9_#nSE?%*MdobG8 z&E0-bfk&3{Q28E-4R|8W_DE|dgjGf>eGWZv2FmmMJuUMMg^7uaZ;_xFT%zNj2)@e% zf@F6OB(RQ>Z-D2&_!zGJAzy`~5>gwI1QR~!tLA$IszW}{GBBm8pdW$?K5tS{Z~TYv F&QFdUz-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/lead_text.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/lead_text.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0d4b6297c732aa5720d942686818563c402a1cdf GIT binary patch literal 1782 zcmb`ITQ37a6vxYh%Zpb&f_DiK2?<_=iZt4$ZjC6d@FMZ%K}aMhaS1A-FTMy5>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/light.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/light.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/link.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/link.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0ee9204b87ea0a4ec867b3cc58fb2563b265ab1d GIT binary patch literal 1782 zcmb_dT}YEr7`B@(yY8|qB&uDgq(KlXe-iU23dN|z3njYfM?tBJh_Wz*gv5*jksydg zK|uv|;T)L14YfJj#J{EcbL!^y?c4V4oNqnneBZXxU1;oZzQg%>p69&hecyAw)8*ps z3|{ik9>TX*{dVzQMn*r@2lgl*2cn@-2{lFu+K4FZs3wS9BqCEH`h9E8CGU#EyW-q- zb$|jQ=rkIECFrla>;zWruz&(0=*n>*O9|Pbh6)Ff(Ya4>kpB}=SfDFj-Hwh-sZ0oK zDM2SD%ZaU1=wS6PfQppCr3qHD6Gx`dNrDnRb>G0;v`zP7y1jYkS*u(BiG)RlkeU8g zoyfW;2fiI!U9jVhT$ zaXJ}?p(M2G9&RYrpFLu3Z}wS!Mg@P^<8pp|KTv&qq@fi1G99-=^|NakLwEn@zJko( z?|PUB9Kvmu*WAXsg3;>y@T{5b9WU$SgZkpE`Q8ppcwNg(Cn$K`b_}N;-W;kuMZ+P6 zm1QDHv({fjue#rs=jzI`^^b2`Op~Gzz!HVQvDn0&y3wm;a#ZrIx+1{<(^+v~-q>`} z*jU3gm~#UDjdR*#TFt)Vd`(gQ(ZZZ8ttQiIHercnzD%u8?|!d2K|`W%&BJs=)gE(O z)8M6(L=;$(5JIGg-L^QP>-kub`=KIdxbwl1Z6Ok3VZyo5jyGQ!yH+Vjqh1f}VHX?+ z#Jp$VTVKI`o9-q0$r1`0>q~~t=L)7VHmSG{&NO_{7ad%9-Gw>TKhWX#0ydZ*-O``Q zn(OUAtPzV1%cQ0Ao}n@u;SSnuh#xbRS94qANPUUq_cEPCyp;O|--^O?dkdrtWg0{l z34=P*-5O7oWKu~R-Z1wn)7f;t;(6{fjV-=;Ztc2{9PrOf0m({yRT-%*pWLjYfVbi? s!*gk~LL8YwheMTkDfb%vf9R{RCXyk6FhU`&z1hA~CCv{;X+}pf zBoJy8Y6}{^|5|PJWDr6Q2pkoXunCM1B7$+wWnt`Fd1{3-rZXXg91xr;P6L~IT?ihb zvIKY*36ihKFwxO8Y-U!Efe^(Q$*a!k82 zwKu$Jj3d6ex>%l@-d$VTT3Lwu&g$a&{A|J4Pvrm$yhJ$_ukIkoXo-3hCwa~!3`wem zA(hXSmdcUqyq%!3x=#rXr39M)bN+khjPF$6=O?ex%YE+DH}DOjb#yZ9={p+r4RGRp eOsJ~5-{Y^0sE?t$_NA}(vCnIi?2W(p?|cFU6em0Y literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/modal.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/modal.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0e2b936a784b84501158dff0f20bd83382543f66 GIT binary patch literal 1782 zcmc&#O-~b16vd58*Zu^5fqRV!iHK-obRi(15Q!iV;|ghP>0q&?UkG#|A%=|@qfjfA z7U>v>N+1vuBVXbI={L+2XgkxHH#44g3{Wh!!G$m9z1*4Jb9(Qad1ua+CXW|o#%Zjl zFi-xT$1+h-5slxcPN*}Jh(!_w6^cY;fQW@cBB1Qj)c^{~?HC&gFrjrO#Z#fF@_Pv6chGC1iKpbuc4Nq!GZenD<40MPqjlfU!(WpAzCWE7^Bi$Sy-}^j+t3PzfCtQ^XQD%*%t=J zk&tr`UT~FBXc@cr7oA$$w|=i8%d$wY?m?0ei*XLkV&4kYQ52a-StUVJQPA3d(0S^S zC0P=1a^*b`+>(Wzg8QnoEe`s!I?BGlD^bY)cxx;(x}oU&kI3xz=-lc7gg!3~pVP3j z%ZEL8huv&#ZzDupc=3Lu4Epz)=Bjm z^_dPNh36FR5G0a{EFf)~_SRQk+pmLzhD)EvT~Sv2#7J578oNPj@5}{*w!2enr8K>! z4jk%U^J5UzbDH*zNI*aV87Zrw-C;E$ArJa2#%|-I=g;~k@L@|CC6vW_)5Uheqs6=97s$fu*58_gNT3jKB zh;>6D2)IGmiUq9@hzW#6!(s&swJp+CD3!MFy?WjoGd^)ooXkw_n|tq>d(Yh5w`P-b zqK`P1V-LWZ{&h_dB_E$!=yj9H5)H9&9yg|!W3juOj(?ieQ3P@E9P1pm4}CD$EJmB< z!(UG$T;K?I&f`KPkgcWx7E%4b1Y7%cANl5!CmA8 ziBRpYTz+*9N4OJKDGoKRX)RDb*nRl+hBL)+&pS%UEmTV{CBiryp676GviBvbLuBcG zr;B2*RUSQA7!#$MedNx@p%D{sJgghZ{t1V7x*U76mM5u0?W2R#*laf_a)SU)Pk1jN zzcD6_2P&A|t7CRuS}^8zLdIKyZ3F;WZ*JeLoXR|u-`1XL*4Gk13MIvX3IQiv4J@j^ z0-3mz6p9-%cBIdhXDpF1bN6Sj+RFH*=0yyC>W3Mjg5p>$MjYB4=I!VG+ut`JHV!Y( z3zd-nLKTuWsi~);Y>CpNiIGWb{EvKg$20Nj}IH(TEd(L<{ z@8f6cxEl+j#ekic z1LChN+Z4RGIPX>lbE4p8jyx(%SEYGlYK%HJ8PnvSnnl$jN>wGje zGNw#TS{JxrclcUeO*JeJTb=5*$H9f?_>;&@{3uQ^L>8P+SknsycM4Xs1l&w=a9;TT>e`!~Po_0ZTHv zjV-8$wEMENCGpiQ_W%wh?jj}x2Q6q^ACmyUSg39336W{;w2%E|U*%C3Kouv2{l2gM NpFS`CGXBGV=L?Do;t&7; literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/month_picker.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/month_picker.bmp new file mode 100644 index 0000000000000000000000000000000000000000..44ea12ab4a407eda9b27fd8bcab4d6d254f9fffd GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCH}Xh6-u=VXASNgDH+n z1Y#1VEG}_Ol@JkJ>T!vWnu9;whDZ27VxM>t)7P{}KX}Z9OTigvPJ)P&N}?G8-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm*@#4%MuL~yCcB~BxAfYwpPJ#c5k8E6j1C625Nq6SC;1#zjzC63h`WCM{E q;4vRf8JvsDUR>gEjc5#9>fuf$iGgM~kV}$wxMECmMn#512mk;O;a!RV literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/nav_pills.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/nav_pills.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0663cb2bd45a2c3e82cf14392b660bcb4bc1c08b GIT binary patch literal 1782 zcmeH|O-~v@7{~F_W6ypBKS4i0@BJ)l^zNaJX-`dTXd;H7)k14!c>s6s{ZFZSjGqHV;FcDV5VU(i4`COo)fI` z{fM2@l5D9UZjH3|DU{FJIi{&AvJ?-&h$6EET;!$g_2u+&ih<#elKVTGtC!^xk2E>? zEQ0k)F*)3S`q>Hl{-)Qsxjso9OuL=nM17u3VIB*JNBoO3-mS!v-|ZALzo9~Fa&jVu z>B$e$f}hTq`B>oC^F9*r)yhQ{i3PoDvFJ)P$c9BR6P|LTP#D@cKSzeDCqG!4l1}Zs z?wt!yV@TvG{B}a{j*cAeeM8?+Wm8i_pIjRKBwIM=m@R%?K72Q*mI|BbjBt(#)%Chh!5S(z$ z`o=GERt?Y6zp$N|2^S#z^z9savUojUknm&G>W%xP8M%MM*g4Qrf(79nqrqelj^YVO d{+EN`6B^^-3hKx`*13DNGxt3GWpv=ba|_ouY{viq literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/nav_tabs.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/nav_tabs.bmp new file mode 100644 index 0000000000000000000000000000000000000000..627310a4e27d738cd7027bb68e63e11617efd672 GIT binary patch literal 1782 zcmd5-OK%cU6s{YWuKfxA0)K#e|A~nkSKXM{CUw!6_=t)Ig+wTcZ7q>Up}dCIP#9n+ z!)sb?tw3o>VL~QTm=}IC1Jt$}#jx>#8rO7d zZZ3l7@f*g_12HL*2puXi=7GRZr4yh|GEfy+=y9h<-@7Nx?#a<#YZDLv0av5}GJ)M` zHDqKpr2qmT;6^#1Rb+Wej!`&(8eH!Q3i&q@0|mIz)&G-6g(wP!HvdtLFjYlqv#;y8 z3EEcuutHO8k!Fi|O-luqDb$MeNEwMJQmsBPNq@` zXgs)?iukihf=WcP2_hX0#kV|}SQs`uIWijayBgoVf(P&m=QTLvV%{#{hIR-y0ywVA zuv}1i)o2@@o3d{)%>!!bf#1DhEHM|z=*rvY zdrW@pQC$v;Bx;}1<$T^e?p1O_9HpuX>`s1p-sk$HihWt&@kUUw(5l5$&Ze}tqc4bj z?{_@4XAe0#sSNs1zL?G|-2c4pkZ_aqI7t%8px0)4T1Z7PlkNR?LuAS?^Kl}BOmR8(giz8 z5WNp@0C>ss3m%=^fNKy%nb?M5>^^Z$mgjvQ=QD|!$}o6P!c6Y5+1;zNx##s?#ti;D FKLCY!P)q;- literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/navbar.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/navbar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8bf63b01ca52464f47c13273f3d9d386c1753882 GIT binary patch literal 1782 zcmds2T~E_s6vi7bz4jldf4~^yjV4BkUsp!CF%dHfl9-4_jQLnC!T@KmL?4LNY%YEgn#E>kJ813&Je)?$SSa83^rrXtdG1I0%EZaE73QgZVP=(k|ZG~34&r_u{H9NC<-~X Sk5#U(R;JIZ-{ZgkcYXoFSRtzb literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/number_edit.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/number_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..93c624b24dc79124375f07c4f27e69cbfd4baa95 GIT binary patch literal 1782 zcmb_dSx*yD6vh`HefB4q7+;K{uNtEQqC`avC{iPffv6w`h$R(jppp=+K#8mgASOr@ z5H&2eic2KMiX?1>F3{2`-Al`~)9K9kbp|Vv21~-tnXliubI;dvX6`+6G@0BP$B%g6 z9$dTEt{ps!i~E54pLYotzYxICK^Vt`fE4N5l0^b}5sGC(%gq1ji z3r`h>F zcbRT<84-wZp)Ns3uC%4ME?}OdIg>f8EDT>DNGx0bc%0koBkWGN(zlkZXHj&XsB9OS z7p%n6$nbD+ezrk7H#I#2?Ct3;FD?L?oSXu-H7cs55-cn0C$gjI$d%UgcJr%_#)6#8 zjFgjA;=9t)JHVn`k?33^NJVKO@aDDjD=7(molVj~M^@(|65CK0@;TqA!@R+0mPtxM zgqNsRtLtiHaKo>M;|AXibhNdA-0L+(%?CQEO$LezjQ^S_FDdkst9I84@S{pu^FRV( zb+~~qUp#+WD-TiualbjL4qq41-CCC~O3OHN;(k$nSz#XV_Vvq|XA?lg1z|Vu>czC= z<2`Nlo79!sqz?wEpW_pyw{od~-{J8BRqux@%Zfp4E)TG~tG%|S8s|XVw-hxW)OD%F zfWnOy`#dEO1Vz9~l|~@lgyARgZr9j7KLKAabJZpT|mDvO*7?7)MDjA!`5U zePLrmf8H9vi8vq7ZQ(xVlKF@zLw&A<;8*LZtH2?qr literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/offcanvas.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/offcanvas.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0e2b936a784b84501158dff0f20bd83382543f66 GIT binary patch literal 1782 zcmc&#O-~b16vd58*Zu^5fqRV!iHK-obRi(15Q!iV;|ghP>0q&?UkG#|A%=|@qfjfA z7U>v>N+1vuBVXbI={L+2XgkxHH#44g3{Wh!!G$m9z1*4Jb9(Qad1ua+CXW|o#%Zjl zFi-xT$1+h-5slxcPN*}Jh(!_w6^cY;fQW@cBB1Qj)c^{~?HC&gFrjrO#Z#fF@_Pv6chGC1iKpbuc4Nq!GZenD<40MPqjlfU!(WpAzCWE7^Bi$Sy-}^j+t3PzfCtQ^XQD%*%t=J zk&tr`UT~FBXc@cr7oA$$w|=i8%d$wY?m?0ei*XLkV&4kYQ52a-StUVJQPA3d(0S^S zC0P=1a^*b`+>(Wzg8QnoEe`s!I?BGlD^bY)cxx;(x}oU&kI3xz=-lc7gg!3~pVP3j z%ZEL8huv&#ZzDupc=3Lu4Epz)=Bjm z^_dPNh36FR5G0a{EFf)~_SRQk+pmLzhD)EvT~Sv2#7J578oNPj@5}{*w!2enr8K>! z4jk%U^J5UzbDH*zNI*aV87Zrw-C;E$ArJa2#%|-I=g;~-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/pagination.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/pagination.bmp new file mode 100644 index 0000000000000000000000000000000000000000..31c0f2745af76cc97133bb71d4649beb2c9cf2ae GIT binary patch literal 1782 zcmeHITW=CU6vh`HefB5#3;Y4T`)f3&FO9~;hsM;Tk{TPWU?R7cQo9%|tyHM3Nohz6 zrEIz1%57Jc%|h2**ag3xZMK3n0mGw{nUiz&obQ|2GiPS*-4}0~NV^Mp2jlkTxIr|N zDG2}GEq#zc2({NmAE*kXEOsX929S`*eN_NlTQ4VX+_pvKW6|aqc{wOi`kO}#IO463c2^VFz za4f@A&k^Z$SOeZQS(13RE?=~<^<1L@9-rHGb`%!)7Ui&%=#%8!1F2pXlF`hInbc`) z)BORi!{AnUH?SYrjD8Qn{A9P3av4!*Ngcu9*{0mJd>Vw9r9{Vbubv`DU7js0JxeD} z_WWMBlE;UU{m?<^OFj{U`4y4*>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/password_edit.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/password_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..fc433d639344844d426cfaed951ade7e4e2fc1e9 GIT binary patch literal 1782 zcmeHDISzm@3@ZyGGf&_JJb;})Gw>!>uo|d}l33-K5S5Zfw&SE7#-$GN^vE5e-J^jB;P|$p+cPd|K8s8%k(iVQiI`BY_`v_Uk1VOJ$nqYgO|YIP=G2XM z$)Lil{RJs(Cy(-+pWtL1q4Y!|CY1I8V(LxMY)_!HAQL1}yhv7g!CO2wcgT11^xwlb D-FHrz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/percent_edit.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/percent_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..381051daaacfa5b286d9ddc66987d5b5fbf7d843 GIT binary patch literal 1782 zcmb`IO=uHA6vyMmn;xV{l_EAMNU?q(*n)?ef?%V)*a|kD)O&7iQQAY}O|M#^Xgui2 zt6H%L%|QYlf@t&6RGTKYCNbvwJKdRG|1&RHlMRsy9cG8wH}C!S|7ISu!=vTBCfUwo zJb|aX{_K%6lgWkkkNfG7ju^PIjjnNqu~shrSJwk2q^5FK&Sz7x%}gSiNyK*CqX
z6KE9yl4EjeCEBis^3^}|7Zs={ zn9pT#riN-aa0s%^)Yo5g9|EFWsWDbhaOjlTe(MH|K%q6(jr)U@QjK4o5B1#h9h&yt zd9jJ?$X!tc%Ja#6?r7KCq@4&ls#y<{_~-7Fc{cF7pakPp6bY$n?3F+*zh69il>?CytoN1YJw-`Va4W`Sgjjh=XY6Kn{Ak#0DRH z>vOD{XZ@q|8&yTu4tLS0+L2%~@e8l*dUPXDk6cNoJ5{cU^KIHryoqKwELcbnt|0v$ pGkm@sB1uA(?uj|wW3U?TRn(xd)F{4fY`s@^=bo3pj9vKe`~jwpGsOS^ literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/primary.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/primary.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/progress.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/progress.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3c40b97b486c632e67b5a3a55b992ae5afc54ea1 GIT binary patch literal 1782 zcmcIlQBTuQ6t0N@e9;GEAOsALKJe_Ti7!47f0Txi2m`_+A@C0%(RbtS*i3YqXn?IF z6vo*?v~>C4xxA)zy#V||7>b~*2LEJ4WN zdhTH~JC0ab;714<XmG%UUD zdoB%vTLR9YfEY<3ww7aAC-rck0V3!S0T7{o?hPapf(SZ9kX2*@&oY<}h@eNW=6~og z&gnJaoX0W4?ri(U)8iL2ZnpaBgw!jD(&m@F58q1f3o)?W`dZu*MdL`64@$~GQ9UfT z92>Wwf!~`Szny2cL4G_)eHu=Ykrct&#mF4FKTD>TNTIlYRzKF2N~0=CJKxVemobLA zz09+wP{u>gd9k`Z{4PJXlz+1LC(`-x<6T*p!+(WuD?3ANqT2`CT! zUo-1DA(eZa&OciC8#ol+W|wnP=-T#a6SXJr@0xnMdSji2>IXhfvODGJmCX18nM{+3 z9z0znqw|?pYuR#XS349HNrXtH^pnznQ5rv2T!-8?4XG+0D{7?&*dEEMqpOxCpVWYA z^EajM`(lXcj-#&*G*E0P#jE4$VRXambnX}q>L=mvE2+K#okaQ=x@#hRHNid~Nws_9 IKm2zt00!+!ga7~l literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/radio_group.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/radio_group.bmp new file mode 100644 index 0000000000000000000000000000000000000000..17117c803df17e829082084fb9d3c4e0076e6368 GIT binary patch literal 1782 zcmcJQJx;?w5QR;H6baGLAaMaszyT1@QBea84Huw*7N`)nKuV8N5FtT9m0W<|&;()! z6gHrkBL>_HZaohX9Enzd$T-+Mbd>ueTR{YfWz7I@DyX1~Wo;yKPG^Hn%Dg5@Ur<#p^_cPFXOalxB zqDWDj|Dn`NBl^_?5jr9m7501Gtc(dmZ9gXWuEv;Y|s-szS z=j3{7vy9;ol4J@1FahW4aKr%U>heJar~05!nA^U-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9@9$p_^#AXle?au-H?ipNAD|Yv zb_fG#!naQ!-oJYG?!}XLFP^@8i5CGCym$gs4AcVD2saAI{`ltQhgZ*k{rLXp_irK* zP%%&oP$R@BpxeHE{_x@T^Z#T4phlo}pdmm6bm6a`KgcrXKTso3JJ1kdr~*R+=oj+L z0cr$lheQoQbN>DN4@6i2@#g&b3pE1Bz%&e(IsY&K&>7!<{{8S3>TzUwpcF21FdaYt zz!RO)BP#g^E0^E=@#`;|0<7lz{`KqI*RS8cfzapAUxDm(C!ev$>=a4eE0M8}A$&W~ zsBhoCefjbQDE0FPD2ma{`T65JP;k-g=@y!bp4KLA76xt>h8|{G3XwA;vX9GT?2*dc zE1i8%JZX!wwWX((fsLM8Syl>A%kN)5f$1L}U%!6-1PY!%b86&)zSayp`oS~`nEHSz@b6y`i788@doVSkiBR1fYLy#6bEr~|0ZUh^ Rl&e%M=OIRc%0>$69RTGBQiT8j literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/readonly_edit.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/readonly_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dd3bf827c0bbfed1fd35a401f3805bb806136551 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm)Q8&GIWWpEMv=0KDI)xg!`VvL%DD`endh&31?;f6-yF^ZUQ#-klBh2I=B X_Yma5jfFD^YQd@iu6>j-v_b#?3sp{; literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/row.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/row.bmp new file mode 100644 index 0000000000000000000000000000000000000000..93c6964e01c45176ae67351bd40c8255e30fd4f4 GIT binary patch literal 1782 zcmcgtOH30{6vd58*DhVSaAim|uGB<=?${Ol0SXZnC^Z5mN=u?3-%>~fsX`p_AVDEc?wsCx`_Ac``{v%pB`|wqBG)nC zA>8}d?>!MOCZ-?X>-Uj6vJk+tAz~uW2{4Y`uJIfwQ95y;zH@@!9^@3b!eO0L}?LyGcOj^uY$r5#S1rRwIr_CyJ%GneAto zK?7A=evji=Abezy=eU5jw?}qjE1mn9=lXjzqR0~+lU`R>QG^Wu;S(L464l?E^Ivp! z>$!HL&R$L4>4ycG@;sSZRVGWnh)J=_^3t+gpUmJ>gqB@{*CatZ*pE@i19UF zignD4TE-@HS}pBdMtO0~SZ67U0+Nt+Ea@rzkjdDT8fzanAi3c^T)@d5V<_5YlIya!RagJfQVXG00jB7Hqf5-3w bQm*J6Ls^jA`CQ$_IZvd*vk~^M|2sbbrCPzq literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/search_edit.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/search_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3bdafe4b01f9133e33935e98893a90ec17020387 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|1bhn@eV9tC<>WTLokyS8DRp~ z0$~8ngo|LBk4pru1(^Xc3YQj4akyT%6s8DV3Ks*H7F^=^&A}=QF$${`rXU{0c%*1; t4$x{eD-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/select.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/select.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dccce0f4c866e1c3cba1c55e25bab4e036b071d1 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm*@#4%MuL~yCcB~BxAfYwpPJ#c5k8E6j1C625Nq6SC;1#zjzC63h`WCM{E q;4vRf8JvsDUR>gEjc5#9>fuf$iGgM~kV}$wxMECmMn#512mk;O;a!RV literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/small_button.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/small_button.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/small_text.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/small_text.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0d4b6297c732aa5720d942686818563c402a1cdf GIT binary patch literal 1782 zcmb`ITQ37a6vxYh%Zpb&f_DiK2?<_=iZt4$ZjC6d@FMZ%K}aMhaS1A-FTMy5>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/spinner.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/spinner.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bdbc3c6d3f6810d35cf717261cc3aad3164c6b27 GIT binary patch literal 1782 zcmb_dOKTHR6rOg`rQ$+xWf27Z1zCv;H;SSz-MA2Ug54=X=_AsOMhX@MSE2|8E7XOe zjm@K@Z5k^UF%P0mO52#2_asf5G?}O0+%p+NW?BmNa^~h_?)QE7oO5qZ&RlHtacnp+ zpTu*-czT$}aXi-N575Jam=sAQ(-c{S$hN5Y*s$o{i!G~pl2s%Vyh)`@b zJ0U9QcQFkeqMmbyLF}Ih-Tk!2uT|z# z)hFLFj;Bl9i2vB5FY#iXwu7Lpj?A_ho?YdJ{imOQPYMkqdiJr=lyAIW=I+eg@~-F# zEInHttQP9x;ql-h*Icx)g|98tPt{FiEadw-mamIAMq^lYXw4nXBbaM%e*#BUZ8QGW z#C!v1CmmNX)idaQxR^$YT{>VP45VWQvy0Ayg%mgF#SE}j$A|<4wQ!a+Q?c~Sffpu4Em zbh7MPNZk*nkZg9dg=jku9T-!`wr}WwZicQ*LuP|~vu{9Wr#=QGjtTditSb`IG5Z+0 T>%R2WeeCljrT51F_}}>pvhY6o literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/standard_button.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/standard_button.bmp new file mode 100644 index 0000000000000000000000000000000000000000..af6c190a9e23c98db1f37472c0decadc0f29e9c6 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;qG((mB}y}@B21$o z@|fayM6hbXDu~ArpcGauSOqCJrvW#B8;;d#tb%YYSQ%KgU=_rw9WIDf3syn67OV_h YS|H*ikyyqb-kG6iVl7W`d9t2`K#4Ef zNUVs8040>8LYNpU5_ljP^q3edJp-&x^BG2G0(ez|<@fPjFXROzsQd^c6%35XV_NhW SHaw%BmEo)hICTeCzQ7J8y)(1` literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/standard_combobox.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/standard_combobox.bmp new file mode 100644 index 0000000000000000000000000000000000000000..73ba54340c8966b6b596f30591832e8db80c22f8 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKWE#zxB-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o!mApna&l4&&WlB^%50joI> zL7);eS*%=$NoZ2Yf}`eOh5#+X2Q3P4agnWttAPlTLBdUdFvu_gt9#Il9pw)15C8yi Cbaiq7 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/standard_grid.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/standard_grid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7872be7624edc7296d46049e80d8e2afb2ed8274 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|6m0$2a-&qc?eT~Lqh|aAf^aV z0akO61%bMdxj;6W2*egNHJE~Ex`wVfK#!0LM#C97c>qHXnTwfJfU=l^Xu60`Kcq$$ qQ2l6pAx98e$YVwgJiZ`O5E2rM_(g!S$QEHW2iXKXY&3I*85aP9NZ?rj literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/standard_groupbox.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/standard_groupbox.bmp new file mode 100644 index 0000000000000000000000000000000000000000..76158cc47bfa8b815bc417850ed0cab4e1a25264 GIT binary patch literal 1782 zcmeH@F%H5o5CokjC3T*_3-SPZ{!EcK(Zb0l)@hiaM501ivVFVWIVZkc?_;TBj`bXK zdd;C$rQG6tIkj1Xu{?f#tUr2q$HN@vS3vu~{4851WYk0kQV}%)LMoyrKuAT@1PG~! zngAgcQ4=7fB5DGJR76dHkcxD(6}s;4)4Kr)shz__GRJV#WDew7!(qN((fe#6>VL6M O{_I@qy?=Ah3p@c@dP|%D literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/standard_hidden.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/standard_hidden.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cb5d8ec794287aa2cde66f7b31901a6e2f4ba36d GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o!;Apna*5@@V`B|$$-DIRmM zN?{5@Ou`fgir|sLRF6k79x3w7X&?mfJD%$9!Sn^D2p&uENReR<#55vFO!I*vMCwIW MhSi)=!I2XJ0CqNx=>Px# literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/standard_image.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/standard_image.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a9e189beb4bdea722a2d57fd53fd9318c1cefa7f GIT binary patch literal 1782 zcmeHEF%H5o5K9+E=01TJ@BnuH%)pzvf)x|Xx?CfrVnRep>iBG5lHTsysnl`Bdcj;j zbE&A52kOr=XBA?3{rYGZo&JW0nf5nBniI(JmPtX=;wS##AP3>7h86>|7khZ9a@&(` zQEMmNA}l})^?~Hcog{X~Z>MSy^f~SV)=&Z%U~X02BV9o3UdK{8=~w~*RQpV?Qs6RG nQ;@b3`K=tZR%Ut(k*O>tWl2G5A$ed8Ee<54=Lxa@Ennab;??Nz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/standard_label.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/standard_label.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e740645619de8ed20f40f88a2c03de42356cd703 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tk)2sDrm=zEXw|A! za7WnL*uNPV6pFe*rEiEA;J9g~I%gaNSC5as$ zAFr>kZ*FcbAtAAA*DjLuA}e0EZe4eGH&DdL$mr+KpU6@qv4O$j?CgBw#*Lt$Ad)m< lD)#g9D=8_NH*X%M6iFhpXU}G1V|(%91xdO_6_3CW006*tc#Hr5 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/standard_link.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/standard_link.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f400df2909a699c3b6c204a29b4e7905fbf4983c GIT binary patch literal 1782 zcmeH^F%H5o5Clz=lA0&v1$jVv{!GD}(!$ASMyoq65@kdz*;%jW){ed2x2g5E*f?9i zjehB>wTG=guiiUo!|QAZzk$z7jxT>x`2Z>c>{A0OUu)68*&)!EGMP(o_Dia$u%m@Q zs?c3>2~`=>5Yrh@=WC7w-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|6m0$2a-&qd5C2FFb!DEK@-H! zg_wk<2CE>N8Z<6eEpWjGA^^ldxE5sdu?iw9z+_|9f>jVxFR}<$Em#GSbz!oxYQZXq xsTWxUs}{H*5y9L5F%7PTpy9|0Fxey1oM9Qxkffbla~nq_xVvNX%~x zDGT9{`*X^X3T3-{U*)0AUo)6yzX-ICf#1j6$<$D2YRr);3S-@po~mGf3bDZFRH4wj zNT@;~T0W-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCIHI1q{jhVH&WSgC>Zd z3o!{z4P3B+H~`cR*Me*mTo7msvN%>YL=9XEvKqMHs5$VU7!4of5CF1?Og}(n1Od=A f{NapdH6AV=b0AVAk!Ti?q!(E+nmMCftRVmZ5WD^z literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/standard_progress.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/standard_progress.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4ddf24900411555010e80d148e9a10aadfc2c16a GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#QAplDVB-3cYMzVgG2CU{Z t;09>wfn115XyOn-+{QGZsUMlmc^VvaL-ak3^+i%}5-ary~TTermv>eq1^R2_FRRjzhh7_Y>PI{M!@%f{R zkRyxRp#_$Z)I~3gl$12^0;6t1EJ;XRZif~U$p{1qiz}>8qRugPO~)Jod|SbW%n-n@ bowOAdK1Qqy##=;1!B|mCNU`gW#TWPhjxkh| literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/success.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/success.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/switch.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/switch.bmp new file mode 100644 index 0000000000000000000000000000000000000000..aa793e1efb166445e2ac39bfd1049834ebe67c7a GIT binary patch literal 1782 zcmb`I&1(}u7{(()K`KfPRck*EB1QiJ4}zDpSJAU5wu;6Cwec#p##Sgw@ehz(gq}(T zAu5DzHfcy|vDQ@7`jIxNF>Uj;n@wWAW_Pnbn@MA7J}5E6vy)-weSUf8-CUXmN=QUE`EZC2Z}5?Z zLO?i#U|3+RpfFCxBSLhGyEt-D5#^#N)s>8h?N*PoBV;?Y)~{SFqiS;KVu;H;mj(=ldt`g*1*K8wU2=$*fhABL+8DLWVgX_+T$e!Q|Wu*QvLsW3gg}CyBTu#0z{}$|e>*1=|Oi;|8|J=-7YBHZ|+J zFtPAp+6PO%P=mAN7qr)AfBy5GNnCswbKW4X&3@!z^kn eRyeJ?H^6DhJ%-!0CHHCz?|F(+@5cZ5?)(J=>NW=e literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/table.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/table.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56d0bf259b74b4d31f4bb172c02644393cf4a4d6 GIT binary patch literal 1782 zcmeHDu?@p840D%^oqIwr$N|~=lTYiAo4PiH*$RY+2JzG&hyW`RO)8Y9$7?7pM&vur z?Q<@zD&>j$`O4FXNbjS^chSDDzl!T?tqFAG*Br&6(iXKM{6!+5bzD{CE8=`|99Pv} z=Dyod;h4#*$cn7^+2I_zWyTiT TqIM)!jv`4mwjn=@^%qzGqJs@G literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/text_edit.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/text_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dd3bf827c0bbfed1fd35a401f3805bb806136551 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm)Q8&GIWWpEMv=0KDI)xg!`VvL%DD`endh&31?;f6-yF^ZUQ#-klBh2I=B X_Yma5jfFD^YQd@iu6>j-v_b#?3sp{; literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/textarea.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/textarea.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a937b000f14221a2e401e2c8416ef736beb68ab6 GIT binary patch literal 1782 zcmb_d$!`)-9L9@B&;AMCO+0zhn8q3om8D2pmb$c6V5nM+7ZWvj(t`(2ni7pME>+{9 z*5!Z;)H3OS(6U&h3;WUm$|^96znOX1W>aYO?h(JenK$fPc4mBFbfymMMI{_n&RfZ{rf~D|MD};jO$Z~NdK>w{E z7SPeHA|0wy@|dun>f`vZ7{72z80UNE^b)k?93QMCqac+{#u_>ae)?4M+@{e!W`W3`~1wNYXns z`5d@8kApBsBk!N>)Zu&?q;$O=^m`UP?tph5Vl!aH?{=;w<8-YGbdSjxnw${S;e55# zICtJV`p_FQ40iK1KB^g2_UTkIol3eDGTk7o$P8-vh(>Yi#NqVx%bhxV`r7ok;QHg&hCzAzbu-fO`XfF~1# zci!hB^7(b&U87(=8N!N>h`Eg0YwnxFtFIox+0FM##$Z~@l8!OOobEJnSxJm3_JFY; zKX-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|DXp{bR@*nl=~PKcp#cQ(~wQT z&&FduevO#2SdD@x!zzVU5SMyf;#ds<3gS|aOMJl1X}}GT-GKEgC@RD|jw000*F BUnl?o literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/toolbar_debug_breakpoint.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/toolbar_debug_breakpoint.bmp new file mode 100644 index 0000000000000000000000000000000000000000..40beae6989a09e87ea3af6a894e33f3814d6996b GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y!!QCOA{EGpc%K1v>FZxcMnDl_ zv}0<77(!4xE{z1WqiOv5^*;m=<9KAfaE)l%ak+dj=mq)_?rdWG3yeWzXCrHYuyJ`7 c9`(4i6VwPX0aH7X8sXZ3>fs3Ps*%h90Ns$PcK`qY literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/toolbar_debug_clear.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/toolbar_debug_clear.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4c4723933b3e9fda042b68d181908a3a7d9c4287 GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y1AT$HxjFF`A}a>6A%Ga|Fts4N zklDoOMb<*RjmRdGVIxF4Tq8kyMMNs#2-(4CY-CqK*g#$S`j_Dd$c1QutAx7&E`n7f x!~}?TWR*be$Xp;B%|^J@KnAAvVW1b6mkD|n?sv2hBVHrK1fY62f}1&P7yut#l<@!n literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/toolbar_debug_devtools.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/toolbar_debug_devtools.bmp new file mode 100644 index 0000000000000000000000000000000000000000..165a0f9c25ce1bdb4f1386cdf83b9c2b03ff83a5 GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y!%znC-ZsP|G>;Om5vUTYUNk`< zcVDIfGJ;rvrVOhf8G3;hp_vTlVzmM;i0neR7B~a03@!p>pb5fFKvsjP3?d8H3)h9! z<#1)lW+Dq>)rDpSF1^U&Xl!IF;8Iux;j(ZBR%H-DB1yPW5C)ODu-c1e)Nthj02lv{ A{{R30 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/toolbar_debug_start.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/toolbar_debug_start.bmp new file mode 100644 index 0000000000000000000000000000000000000000..45e52741701738d17dc004ca66358303a37d4f41 GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y!>|Cl@nU5A1E?2*$S?t@(RZ#E z5RqX5Trb=N;vImdmm~*Z>V-Q1D23k*xb(tJz@r_PUZ6M`_7bBD;uti03EGA11-M?~ Ut%GZaXd%fuWW8|qC<8eJ0D_{`(f|Me literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/toolbar_debug_stop.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/toolbar_debug_stop.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4f79e5ded59072054b4811597afba2e94f3ec27a GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y!-xkmGPSr6{;&b+a&Wkg3jt;E bXdl&!9B#uetbkDu^b{_HCt-|A;ST`-HQJ_$ literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/toolbar_help.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/toolbar_help.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cf2b09d75b88d83d999f2c627fd49adb435c767b GIT binary patch literal 822 zcmbu2u?@o@5Jid7M=4nVDXm?YK9WmnFT*Yjf#e08jtN)*&)~+%#g}|pppZyGI=KJ; zyW?uQqu5SI_l4^Gs)LZ5FDSpAxY!Wl{`YxrdcO5#OzxS|L0Z{XMx}#2++;u|`@XO6 z8BF9n&lyh=7#c9cFs$ne$qg_x0Iap+I6{8qLkPy0Pdxef!Z}BBSr#efo(I4tWYaV; o#*~s$s=`ymBhxf#t=qQs-h;-s24+A~1BfM{m=VlkU^oDjKf(vWV1+;;ihAG!#Q@?KijDbz)tvYMHzE<- z0l3WhPXqwkHPp@7l4%Y^XnrNbUxUOPh%+!rhzE)H7p4iw9wgozc)%iShYJn^bCCT4 z^bQ=6oiBhUync8Gh>!yZXd0>c6k-mVA>^5ZX$T&3fQoS;c$gqFu=)#G0g>#%X%56y G6p{d{WHaFa literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/toolbar_open.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/toolbar_open.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3bb431ebb5f665b9de37883a2c1b06549afa4ce5 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+;;ihAG!#Q@?KijDa|3v=Y6Du_pD zUO;va(2)2`|A|3x>)@u5XAaOVh*3kr9H1kK4nc-O(TpfL!VfTkXe zi$^-s24+A~1BfM{m=VlkU^oDjKf(vWV1+;;ihAG!#Q@?KijDa|BXcsn%}GLV zkD$2+XvnJCC?LXb8e9!A=KR6|knI}D=HLlx;=>uD5-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/week_picker.bmp b/CORE/Source/Includes/HTMLEditor/editor/Packages/icons/week_picker.bmp new file mode 100644 index 0000000000000000000000000000000000000000..44ea12ab4a407eda9b27fd8bcab4d6d254f9fffd GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCH}Xh6-u=VXASNgDH+n z1Y#1VEG}_Ol@JkJ>T!vWnu9;whDZ27VxM>t)7P{}KX}Z9OTigvPJ)P&N}?G8Label`; + } +} + +export class DSEdit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSMemo { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSButton { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSCheckBox { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSRadioButton { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class DSComboBox { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSListBox { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class DSGrid { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
IDNameValue
1ItemValue
`; + } +} + +export class DSImage { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `Image`; + } +} + +export class DSLink { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `Link`; + } +} + +export class DSPanel { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Panel
`; + } +} + +export class DSGroupBox { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
GroupBoxContent
`; + } +} + +export class DSProgressBar { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
50%
`; + } +} + +export class DSHiddenField { + static visual = false; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} diff --git a/CORE/Source/Includes/HTMLEditor/editor/README.txt b/CORE/Source/Includes/HTMLEditor/editor/README.txt new file mode 100644 index 000000000..3351f4350 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/README.txt @@ -0,0 +1,22 @@ +LazDatasnap Web Designer local libraries + +The editor and generated pages never require a CDN. + +Folders: + bootstrap/ + datatables/ + chartjs/ + plugins/ + +New visual components: +Place a *.dscomponent file in libs/editor/plugins. +Format: +[Component] +Name=My Widget +Category=Custom +HTML=
My Widget
+CSS=my-widget.css +JS=my-widget.js + +The editor scans this folder every time it opens and adds discovered components +to the visual palette. CSS/JS files stay local and can be referenced by the page. diff --git a/CORE/Source/Includes/HTMLEditor/editor/bootstrap/css/bootstrap.min.css b/CORE/Source/Includes/HTMLEditor/editor/bootstrap/css/bootstrap.min.css new file mode 100644 index 000000000..6b747809b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/bootstrap/css/bootstrap.min.css @@ -0,0 +1,17 @@ +/* LazDatasnap offline Bootstrap-compatible designer runtime. + Replace with official Bootstrap distribution in this same folder at any time. */ +:root{--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-danger:#dc3545;--bs-warning:#ffc107;--bs-info:#0dcaf0;--bs-light:#f8f9fa;--bs-dark:#212529} +*{box-sizing:border-box}body{margin:0;font-family:Arial,sans-serif;color:#212529;background:#fff}.container{width:100%;max-width:1140px;margin:auto;padding:0 12px}.container-fluid{width:100%;padding:0 12px}.row{display:flex;flex-wrap:wrap;margin:0 -6px}.row>*{padding:0 6px}.col{flex:1 0 0}.col-1{width:8.333%}.col-2{width:16.666%}.col-3{width:25%}.col-4{width:33.333%}.col-6{width:50%}.col-8{width:66.666%}.col-9{width:75%}.col-12{width:100%} +.btn{display:inline-block;padding:.375rem .75rem;border:1px solid transparent;border-radius:.375rem;text-decoration:none;cursor:pointer}.btn-primary{background:var(--bs-primary);color:#fff}.btn-secondary{background:var(--bs-secondary);color:#fff}.btn-success{background:var(--bs-success);color:#fff}.btn-danger{background:var(--bs-danger);color:#fff}.btn-warning{background:var(--bs-warning);color:#111}.btn-outline-primary{border-color:var(--bs-primary);color:var(--bs-primary);background:transparent} +.card{border:1px solid #dee2e6;border-radius:.375rem;background:#fff}.card-header,.card-footer{padding:.75rem 1rem;background:#f8f9fa}.card-body{padding:1rem}.alert{padding:1rem;border-radius:.375rem;margin-bottom:1rem}.alert-primary{background:#cfe2ff}.alert-success{background:#d1e7dd}.alert-danger{background:#f8d7da}.badge{display:inline-block;padding:.35em .65em;border-radius:.375rem;background:var(--bs-primary);color:#fff} +.form-control,.form-select{display:block;width:100%;padding:.375rem .75rem;border:1px solid #ced4da;border-radius:.375rem;background:#fff}.form-label{display:block;margin-bottom:.5rem}.form-check{display:block;margin-bottom:.5rem}.input-group{display:flex}.input-group .form-control{flex:1}.input-group-text{padding:.375rem .75rem;border:1px solid #ced4da;background:#e9ecef} +.table{width:100%;border-collapse:collapse}.table th,.table td{padding:.5rem;border-bottom:1px solid #dee2e6}.table-striped tbody tr:nth-child(odd){background:#f8f9fa}.table-bordered th,.table-bordered td{border:1px solid #dee2e6} +.nav{display:flex;gap:.25rem;list-style:none;padding:0}.nav-link{display:block;padding:.5rem 1rem;text-decoration:none}.navbar{display:flex;align-items:center;padding:.5rem 1rem;background:#f8f9fa}.navbar-brand{font-weight:bold;margin-right:1rem}.breadcrumb{display:flex;list-style:none;gap:.5rem;padding:.5rem 0}.pagination{display:flex;list-style:none;padding:0}.page-link{padding:.375rem .75rem;border:1px solid #dee2e6;text-decoration:none} +.progress{height:1rem;background:#e9ecef;border-radius:.375rem;overflow:hidden}.progress-bar{height:100%;background:var(--bs-primary)}.spinner-border{display:inline-block;width:2rem;height:2rem;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%} +.accordion-item{border:1px solid #dee2e6}.accordion-button{width:100%;padding:1rem;text-align:left;border:0;background:#f8f9fa}.accordion-body{padding:1rem}.list-group{list-style:none;padding:0}.list-group-item{padding:.5rem 1rem;border:1px solid #dee2e6}.modal,.offcanvas,.toast,.popover,.tooltip,.dropdown-menu{border:1px solid #dee2e6;background:#fff;padding:1rem;border-radius:.375rem}.dropdown-menu{display:none;position:absolute}.dropdown:hover .dropdown-menu{display:block}.collapse{display:none}.collapse.show{display:block} +.d-flex{display:flex}.d-grid{display:grid}.gap-2{gap:.5rem}.p-2{padding:.5rem}.p-3{padding:1rem}.p-4{padding:1.5rem}.m-2{margin:.5rem}.mb-3{margin-bottom:1rem}.mt-3{margin-top:1rem}.text-center{text-align:center}.text-end{text-align:right}.fw-bold{font-weight:bold}.bg-primary{background:var(--bs-primary)!important}.bg-dark{background:var(--bs-dark)!important}.bg-light{background:var(--bs-light)!important}.text-white{color:#fff!important}.rounded{border-radius:.375rem}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)} +@media(max-width:768px){.col-3,.col-4,.col-6,.col-8,.col-9{width:100%}} + + +.btn-info{background:var(--bs-info);color:#111}.btn-light{background:var(--bs-light);color:#111;border-color:#dee2e6}.btn-dark{background:var(--bs-dark);color:#fff}.btn-link{background:transparent;color:var(--bs-primary);text-decoration:underline}.btn-sm{padding:.25rem .5rem;font-size:.875rem}.btn-lg{padding:.5rem 1rem;font-size:1.25rem} +.form-range{width:100%}.lead{font-size:1.25rem;font-weight:300}.img-fluid{max-width:100%;height:auto}.btn:disabled,.form-control:disabled{opacity:.65}.py-4{padding-top:1.5rem;padding-bottom:1.5rem}.mb-3{margin-bottom:1rem}.mt-3{margin-top:1rem} diff --git a/CORE/Source/Includes/HTMLEditor/editor/bootstrap/js/bootstrap.bundle.min.js b/CORE/Source/Includes/HTMLEditor/editor/bootstrap/js/bootstrap.bundle.min.js new file mode 100644 index 000000000..3cf8ea079 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/bootstrap/js/bootstrap.bundle.min.js @@ -0,0 +1,2 @@ +/* LazDatasnap offline Bootstrap-compatible behavior */ +document.addEventListener('click',function(e){var t=e.target.closest('[data-bs-toggle]');if(!t)return;var kind=t.getAttribute('data-bs-toggle'),sel=t.getAttribute('data-bs-target')||t.getAttribute('href');if(kind==='collapse'&&sel){var x=document.querySelector(sel);if(x)x.classList.toggle('show')}if(kind==='modal'&&sel){var m=document.querySelector(sel);if(m)m.style.display='block'}if(kind==='offcanvas'&&sel){var o=document.querySelector(sel);if(o)o.style.display='block'}});window.bootstrap=window.bootstrap||{}; \ No newline at end of file diff --git a/CORE/Source/Includes/HTMLEditor/editor/branding/RESTDataware_banner.png b/CORE/Source/Includes/HTMLEditor/editor/branding/RESTDataware_banner.png new file mode 100644 index 0000000000000000000000000000000000000000..5f0c32052b957b830b9bb8f52d4737a5db4309fd GIT binary patch literal 823613 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

4%grZbLHIqN=gu;nHY09En&})ot5^HYC%fL}^1C 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%0D}~OChDd}G6$u@p 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≪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

-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 pf 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 z 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

vNB+ZTR)rdc7`vY`Pbp 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 J@na9 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 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/branding/lazdatasnap_banner.png b/CORE/Source/Includes/HTMLEditor/editor/branding/lazdatasnap_banner.png new file mode 100644 index 0000000000000000000000000000000000000000..5f0c32052b957b830b9bb8f52d4737a5db4309fd GIT binary patch literal 823613 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

4%grZbLHIqN=gu;nHY09En&})ot5^HYC%fL}^1C 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%0D}~OChDd}G6$u@p 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≪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

-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 pf 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 z z=ny3|t_8H@nw;6Oee2QfW7xM#SJw{hoB|zPTIfx-67rO-bl>sj9oxp^jnvf>^^Uu@ ze)YuZXiK6<>85slUyG$V7OBMaHr&~(-Djq8TV0PeOxh9XaRREInEMV)cQbo)q2saP z61m=?=a(VT{HlF5oX@g0kApk7Ep|1UuKNcLk8O_$m=DeAf<*~B$JWcrMv)aTHxtE% z2!)wNfDxQ$8qAqQ=Elra!$c9rI)o=mnPxDR4(J*wO_aQqicv9W%c%0~3WY-_L>Uqo z*q;#~l(hnt#NaT+)h5!U8ybv4A?#(YXXW~Oer2P7da-x0&F2>K#dX=}`rL`nK|~3o zC;}ufF@OPs*a8$FaR`jSD2&X4#I08D@Uhdq$6q{k=MH%P_uYSBDoN8UECz%n6bppW ze3*5W_xK1ZWPr*PkziR=N_o!$q6qWc<+($poVDJ01kBRHSuY6Ap>qI?pd-luS`nIr zH!QXqH&%;6`nf2dTHEPM){`^?5Nal}-nJR*R-Afvxob4XG)bO&_7KIC=i)60V?PrX zNPD)H=x=`g_WPHolH7OO_RgKHH{7-3gI_$ZA%UKM=F2ZWaCqC+9oyG0T?J#x`q4VF zbFRGs8Xmgq$alVJPgIEQxn5e3rgPUeo_z6QUCW&Zrz5Qu8n>RqRLs53nX?Q1#e(Zb znQ@;f(3;Tu!jp-FEwd%b4jk4^BF_DL-a-zz+jG6lTwB(+zHI9?T3-@}4pcv~<<~Q!x)q3RB)9aU(Ha3cbduFaYyKrIEUS0N)Mwi>P z@JeBk+dLKatYgS>zqpnbP6V-@@a|n`9b^uPdFO7ixsMTaL`4DKp)CY8Ix8Z+8A}bo zb-@6b7z+>L7&NgHYa!1$09U*N&wge*-SsL;Gj;lfyvSG)G-KG(lvW)&f)_8q#p|%% z^|1n_Wh{a1+c5@l20JUF1jeSZm*JIpUhC%`2td~->Rf2hHSaT*SyJBT-V5kRAt8Ze z?KEq5q_6-$nnbvCxEm!L>Tb{%4z&U$oI4KDM~&=7fPC%&5lOMNAQfEFdlBz}Pyst9 zUi8E`Pz0V~eFeH*>16Jm1RxON=X{%AXGjJaX~8Lj z7{mQCR{YvwkB!{kvNTd2KIls-w}>!G7apQ9%0R>@fM&399cnE41lSFQ%H!RRvZ{jAWnyetOr6+GSc@v zBIj}CJVGE%WhdHzYZEeST=}_3N;_EDpdw`p6>j1j3y=1E11cE61yBP8*Nz|I6puQp z1aP#SYg7-}ga((}tTUU`8yrdUA-n=lHTZAY@`C`)zT2YehD?#g7OAZ(L`Y&1tR z5Tpiqu2F`|&=Dq^s_SsH$!;jwY;yGACV$!J*UD}A#p)N>WfFK3G$Ev;tD-8EhdU5JluY zM==-z5VT4{Ql3zZ0v2>u1kiaQ0`_Ht9}#j@T8~s70ndVn%3!7VK<+@35+B+$PK=wov#=LUE$%-*U9(% zfPld-UX(BYC7HSa3Ii!%2kO|{;d_77t%?{$OfpMy;wpUpze41Iy$GOESWe*wy?BTr zcxY4*Qk5d_SZU>nS%CeptxP~jso>~QMu~uTJVc6CRm6eotrRH$t&k9vP*DV8Iuaou zC`9YLQed4kijYt%V$V8KN&&E#NGU~*C5|-_^!qk|CiTEDTXrXqv%c@yqau$Al}WTO ze9*X^6JTc|QVJC5@D$9lBDao37*H8)3>DEiQS9-v6q&+N@ZEG z-1TeTZkd^=Y0PZ6?-)?DA|H0<0j*iu-9W@Q>iYlw&EI(MJKvh-)))DfEi=FU8^53x z*}~a8UtU@xrI5gjcd5&QsDo7cojsSv3JjivivL~ypeo%cz|5q|084l(Gmk9Q7zXj} zLEmDK1QZegL?&_!FP^=2bEVsu7!w_>Eq8j>ilVe{3kS}-q!x9vJni-%)|hCjYw>{A zp$e^Mq7s~I(A>CMn5_4$zqy>LNLj5oQiv$IlX_FMIen||<;GifPx;(-ymWd+mia8t zi-=a%)4XqEqjV!qd;LzQ*tTukXTS1%cYU2A6!BD#ZO1_zfgw_gL18TscuPTM-FT&CR@E5ODa-`CT_*E(^L1nX79}xu5Z~fV_pBg zSIy<9H*)9$CK|_@&G$UG^J35a&WF#vYTxYL`^S&%ZFNx@lTZx{$(jk(#uKbX?0B*7 z{^E(HNA8%|J)x)Pl9{P^CUxNAk3YA**6uHNm2N;YFZT56=N83t z+JH|zk2RgV_Y5DQb&Ttjr>AipI*%SMz5urh;T|@IlKOz!*wD| zYP#d)g|+-j*Rm)VE1%E{x9l@lIxpTzquDXh=qKKt_8lUKTZ$6&2vSXj%iui0B2&INr@9b-jE01BZI z!uSLn-l|@_fR&IyE0?_((2s%$=p2b)OIzPM{_?G#`jaRB;>RC}werFvE99`A;UQtL z>i;OWnPJ(eC>Rx$qJbBgMI5sL8cp7NQbbCH$BWWR87*vq1VF?9#xd3!sA^b?#29GA zpb*h>)`L8Q0P8Dq&_K$O5FwkUJa}v;f@lQ}#Ip#Hbr9FpTE?fY2u2-7?OpEPv z{$1a07B9PN7qOeE$G_&5R#X(jdPmYWHtWjgtYZ|wuvqbdh*(v3l={1fcu^YnY#-mc zz483%MaODZ{Vl1{N;H$dr=lwaCHShAtAI{*sMXL39BozcuP>A zKBnhy`jjCp$bkYu(kd-nZ9Hm?*NY92yb$jKBGeaLK=~Uf1){;kQLT~KJnOcz0Cd)d zK!GrmLGN6cYmz4M?88xJ4+?=rtSiYXAR?>`B2rX~M4UM9JnQ9~(r7`W4%@dwzmM0f z^g7~F@fJ7-@F2eGR~pSm$$;HEj7CZ5U{b?cmQ8L8-qe@03F_>5#Juy0S}xv0%cfni415iPSj~X*iNj|X4q+j~1T2nJ*URQwYZ(Ot-6jw4W;av#FdCI1 z@#1qHx=v&`j|yBw37ms4rpJ;dha*R?%0QGuiON936;G#X)d|^FB=KQ3&LOxbWz`HK zsXz#?&>jec;06|gAyjp!;#D6N2}3}mZ0_=mA|n|N07M}uGh72R5ew*`MpYpohKeL# zK|`tz=(5aPhM?WyI^uye5CJJb1uh@Rk=0l8<|LF1zMl-QrA^G8e+c$0{}BFp zMANyQ1C9TXQ)~2su2eP|<~&N-bl?Kmq(cqyKm@lNk>s|h_CyI7@RAg zR_p*ZFb9@lWu`!gbSZuYI!q`)3#De3q3n1q#kc{7TPlemjMYPYOaflic@7J=pu`?4D&t>V`OZpPP|5uXDiH$;qG(Mhz>0*?I~h1&1|1@$+EjIuGaWqkQ9;I-Qi0o{Fc?+vUI(1 ziMRsm*b|0bw`WI$6k=Zk>U=mzQtF~e8 z$0r~7|JeHPVB5Cqyb~K?&b4+t`R4HMeK`Vnh$I055J`cd8Psg4Evl(jHs!Y3RVuse zGRtkZ?T&Vp%95KUwOXOXc9$rUt(GVTi3xxJB8LaOoZrp&o_q2RE6h2@@E>!oz4rz6 z4{+6t-0p>#`pccC%*8V*9WJ#KB43N@YwU~x8FT<#c0+Bn}!d4`cXw}YmK$I z5r?|k=(|TRpPtO*-J2(mT-r2%-~8(C;r`^g=PnN4*xjF0>%C%fuRj0GrZ?;LdvEWx zUw!-Fy~BD|_=A(!GR`N*PoKYv;}7BS}#)6wCmi==;^eAb?!Pu6xD>mLV_4H~ciivAdiV*j|>KWXNTHi%Ua0iMqz7yjU6+Rj@TtxE&E>1`Tp z+R#P`kz^K!n}aLo*Q$g1_@FshtGCxjes_N^jTLNy76h1~7y`H(2i4k#*2l5<;!AgC zLP25wM2=#0vUdy+!$FwN!$#@;!ykR>{P~^V_=Cz^-$=-ph@Qu4-b-uP>p3Q6Qj1E6 zYePRC0{MWhSnIEEZ?=c^cW=jUy>3it-(oLFYvXWq;)$i zTo9;4v8rPOSoHf6#F&~YBC}HYdtbfjKX(4=>A_pqPF}8icP8!bB<$|Zx6hAv@6UI+ z?2Y=9X*(MF_x9SaymByc{geB1iF*0!=r_N6{MC0Su{W%zjWN{oczIAhI${%Pf*~^V zN_A|vhe;u|ytgq^&3)^H*uhb{_XuWbh@(be!_Dz4yUqXcpMU3DZ?>YPc}79(dEfyS z&I&~aC?krXMgp}c+2fzf4=4?dF+F4vQrQF$g94UA!)7^LkR)^bsbcoEQ@+lg(iSOOvEDv70}QEku@!> zt=nPKKYM<2d-LAwxBb~3sOfQy4rOu#F=9d11jB|(M;vbYf9z~kTN~7S ztmkG3QQ-J6-V5-hwZd+_X1xGGc=5$OBN65gT)ZH2e*I+s=F7Kk&luFZ zjd46YgaM&LYXp0QOj(J#IE)d8o8#LzXT#FYo!+_e_PsD| z_{`ezZrwXO8kEC7_aFc47yoeU8^85W>zbTzMt=V66Lj^wKX*fz^%KMK0m*0k) zclr1jfgzd!`8G0uK!mn#6F59}BP&f9X@JbcLTan9-QUu6<}E6ah99f4XK#1$@~IS8?>@k@UsZ@dY>_V{JQ)||tp!Gi;9 zTP8;#YSXF#^amJDq>0c+n2J>u1T_T=L1QjL1vQIeG1|r!kH+rRFW20s{?N^DMNbxI zdhfQ~+=bWQ07uYU^HpopLkSKH-Tt*0Bb-@>aRK)ln*-M^0TC0%T0+%`pdYD=z~qsz zokvh3B#jcZCP!s|U@ZXSa8&jOZVu=?fk#2~6o0~%^XBygZ)K_y7iYSMXMML~_6 zv#7usY3mt1Sqw3>!6Le&BRHAC&RG~56lNDM;O)D3yl+V0N??z%F{xMj%W=s-Np22I z;2r~D14K*Of!g=_Bly8Y$r8)ko%(3yboaoy^n2Q-yW~nr8$IZ=uK0AkB-=`?U(QhxD4$J2^{l19{Q0H$bEG9p?nSuII3 z?FANx6UGKWQ|d!OBs<>mdx+T&gkCy@2qASu=ga_Fs(Hk8z{Hd}F)?tI%a}-!&_peL zl|(Dx;qExN64ye{SwJELK_oQo9AB&78g=7e?fhAZ)q<39;Zaiz;6b#L0bypG5Gq+R z6r>s;fX)YG@I7?l)M(5M#6UeWL-PQJ(wZ4a0F#VQSirXbT_kRN!1nS0Jlq~2xGeG1 z%h1*Xip;;m^0Nxk!bQ8#vUCiVg=nydfUUkyTm9`T@Mc)4)q{U`SN#LFCH!81bn^Nw zj)htB$jFh@e*~HgJNh7k>wzMS6%r5vfDvcOXqA}+S_%CVDU7LF2IblkxTEGw%~ zU8ztu0WJMssqC8|ZRT?Kxhx|!WN0a!zVdlyJ?MK#N!T4=J1kc&P_!l1%obQ^0wyF) zbLK^3T9PR-3ul-CWk}!{kn<`ff~bIK#7Vo%r+Vjz8IUkW%gzx3NH8EX?=Xo}N@fa< zz%htJQP9Nxmqe=pL|~Vk&){9g96L626h%#doHMZmK~0kI!jiWLH(}@BSr`m$rKvHo zUC^cZ93oQk%Q$A|C`K_`X7o}VkCFu=^<5=lty=^fff+bQ3EpY2%xh4h(?Q1!UU1N| zyKND1TR=LqQnP3QSzaxe6SJw<3n`1y30w`J3#Jl?r4u(%-btnw^_*DkOy&!7T&hZtR7A{Cwon_LJ_ zH~&6w_5AKk9ERxhsd?kQ{d@StITep!rJ&0F0u!ipenps-+4W zG}A6Inx`6$lhKI`OeM930U;V^xCVPx74Mi3+aReZ0Q2Q!`Brs6hDBLu5Qj2cFAC2w z%B(W*1cXt|O#8ipnT!C4n+RYosu)rPTHD-S+t@zXy%R)GEt{uA%ChJe{c1W7W@Hva zG{{RquXO!>IXRkh>3vZ|RZ~w0O$gpmQS=S14tVOR54n=>z4BFUr=>>|W3z$xg@-0! z0HP>q_?&hK>^Rg>g{C#V`s&R;^K+j#+Mj>@Td#lM`N#g3-~GzJ{LS6J@mGF)eQRV| zhoghtcXls5`t0`lT7TrW&$yHQW8cS17dF<%WmG$N=`_85$C|+HCtb zUL77`+NkY~vMbDkvEUum@ou~l(^Kah!`dbGu8rDP&Qjjy&6pAFKyP_&pYc6Jy5RIfccMVBm>S)H)9A|* z9u6fbube};$%2;~LKfFyC+$1uh?5P`RG|*i*3EoY*KM5Fu?|`V^Mg^<%JFf1_h34U zS_#fu5u_lB3}SFRpMm!{9D;MiY!sniB02Eh^#<$1@y^AKcV0gX0vAsA9^UA`bvT_& z&4@sOcGjs^#A!tZ_gO#v{+&xbyM0*g*3=Zme!N#5VXNfV2X-{YUjNeR@yDJx{qmh@ zxv@sYpeVr9+BRy*LD4EHN8`c9U>@3vYKTVb{oclUJejX=uZ;)AsqN7uA~`oLS;hsG z{`A&5G;xFD*^T}qkDoo5!2Evoeed6ij@-G?;RJ8quEv|AAa-_h_#^M%dErKNcZyFx zw7E0T^*;Xa<7+R!GpqZ4R2JhcKN#{+X|320;wK(2H=u}S*RF+t_~?b+yu@AMs`8+X z_YT1>Y?kL-eCiB8w9Y-SrU|Zr0<}MOr7yh89LsKFn%dK8Sv(7QhuLkFvSJ>Bif9lu z1Bn8dsy4|~)1!(Rljfpm-ZSySBAs~i28c|g+3&Nc?@jyCoM1?gFcG6}BQ81pm1i*B zs4usPI>*@?loHfH$#DRp=(rBC2?5Ij(9n??N|fHfGgB3Lx6!NYT7_Dn9hUVpnj;a} zT=!3$E6;7Zg3XYw&Ggtj4hw8`?2yr}wS0j6wY6b$T&u>>x;ww_!At-T=5lVs6D-&Z z-M(6uS$|O_qI4?}rLxTIoKnp#Q3<)mXuY-ZZ@qN?Z~n8Ft9i+rYeY_w%m|5c!-j$e zfdni8l4yV~52+M@lP;46ece(L1sp*t63hr!0%Su4CKCjSy>T%fm4JbWtZN*#tN`aH z3*~Z8>$?5AKXiQS>`m<2AgZ<{M`ckEHAoO*ON>D13oi(!5y(MNKnPg2&t4il`_TH= z+LO6itSfK??CdC@BkDPeE%iCItQpj29@+dq{rMl>9Pqrgpj0aQ*^M9g_*0ioPXFF9Mvur| z@$_*ugM!e|BA_EGSd`}y4yH03yWU12jOuYP=xr6aer9z1*8T0X>*wOeaC57Ib}%g0 z`^85-^2F0moqPPzO>&>PeK*$gcedR1;q>cIY#&@X9R{ay_YNZUZ|_xay=MxZN*5YM zW+IKjiqv~ZY35^{iz5sbkTNzkjgp@v@07)RiP+RQWpvW-rtvdd!~wO8ypet-Hm&PcyNfwUc~0p)&RCPsVw~F z20Zzwp1EY-e!WpNIk(F`ys-9^9887?1hjzLX9JYivEZc0C+SV7Ntq z{&-IWKmn_O&9S)>u57`-_rrX1*Ixf46ZF6cz+gsXm^!mUg(Y*rV(VE9p_NpLf|T;E2+T`k1rwy4 z2GNo&t=|h6T9Sj3d%|HpT^oSwyg!&@5n26-3Pd1g2_^@~%t z_np%*ah#9$-0Y-pn{wuoprc4sEG!GJTIdCqlK|(~AXr2j(X%7^Q zcRnD@pc9J`*;2JIhSmU#eKr*2V?1_Tp%t49F6zN>rLPL$fxouupjlBd7nR=225Yqk zjAjdeK&RO)yT&>~?ZSZuxswDR@IB#5Asx{J8VoM_)bT-f`0C5H2Y#=01nA8Cw(i2V zJd;WnB&_JI3n!C4=!eP*(K2iK;2X)+a0?zYE`obzOM^nUk)HJ5dum==w+Tuw#*=72I9nIgU1w zl$JU#a>dUB_jq^R1kC{iwa=Qv$duYlZk230mqy^Q_2vTygs3rF#$13)Fuc6ibg_A7NPvORAU6^ zNklBFFL_WnBPe=Ipxax01G;^8KCJ>1#Td$-3vC2&{nACiI*6$;bE2tF5B87l--~S^ z1_lg4$Ya~I*KgiiA7Th1VrJY1DSM6`hal_g<6h}YwEkNE{+(k*WY0|#MUfdo+oJ0M z_cqR6+TPi!?!R|?BCSV^f><6xR z@Ba3G`D>>xZGYq=kALwiU%&nOYp=cebrsv+Js{UVzCStlh;EP9kKUeKedfx0Zym-q zJal$#K5LC>#GZo|^X5_GJcO?P_1f;pz2NvjD68zPIp=pDuvGct_&!Dh^f`mx}htp>FXg;a61)Bvk$Mvj@Q3?;ov)TUM3HHZ; z1(tm|R_gUd%&Hbu##@^M!=wFh|2S-TKGXM=L0dtF?jP<9%JU_1 z)0`fc{msEk*H6^-Yy>t~53^XDS%3VA^Y1@hwDb7cZ`={LF+Me-l1}zd{Q78m6ymfU z>}*`Pbm8FOB&cFtefp8%?|t)du-gQv6b8isL-bLrQ~L-bhg)M z2F8XWnyaWJ;mN>K3`#9VjZyPM*32=*s0sWRqp0bE`=hGalBRhBllVAhmKFk)ghxnX zB}Ivv+N{-5tRFGQj))R`3Ph!9Le;dJqcuiss+N2KL~R`+xrq49m+xO1^~Eg2c;n_t zh2VO0a^v8WA2{{XAKB1pTRAlEzxD29Qp^1QOse?@FAvKmy!zg(@&h}m%%E*$lj4Ui z?-0VZ{ct#k%iDlvt>g!X8gxZkrV7#l+Ek61l9wv|yENtjL{U>SCh+6YKl%Fo|Ld>3 zV!bt5FAz|oVq)=mx%|7ILU~fH7 zZ5xxpuiFn~zGM_lXEj>n^wU$7vd_yh3l9(>L`i3X(ws)$%;b#NxfZ^H+9$=|B0g4_w*YJ&vsc0@w5C zw~Fg~@$k55RAAtp#EtcG`~1eYzj^odYxk+JgX3AbQQV%)PN+WkL;3XckALPzp8n#C z*KY35gImY`x-ThbJnm+ldkN?oee|o)n`M3YkoBP$t;cM>jrTFeU z>U?{2gla5;h8Uxfp(PW$aSQ@hxaapS_p&4a!Acv_L#;YnS^u(Mts z9f#li{Ehc^t7$|t9IpB4NmI`vBOqbh#t=kv;vEEYebM4{rIt3&JUfmz--2?D?;n{& za;g^E$1c+ke|qiFD_g($uaAz7X6JWGlxBC|j%N^K+WrGE##VDWP)*dBsjlMnH?0`K z(Mbpahilx<maRy0eWY5UC&q`J~BFh@cj44W*Emy09cY9Y~*uaReo z=uibxOZu|YJ&!Rv)cfMFj4K6O3l8xz3)Asv7#HQ}%R&F5>Wk4<3=WG!^6J^!Y}uA= zUD+s*fg|*k#=NS^&JjCf?mS9_g-_<4?4ruaJM2t427~+Ys%v@Zwbkrm0x;vUdW<41t11fqeTXa^0;_ayi5Lq zg+l~a%LJEc&=oY)3Nk6b3`lFT)r~+WoTcADju23@1Z4n7l&cAmA&QaZug;e_oym+* zj2X)U%QCq?ve(1={0+wlYQUaCYl-#(2*?J25{y#nia;dM88PuD6NST<6r&k{b7WwS zfE+|d&5Md9vg}eaHdvH!cfk8}WH)x4C$U|!Bmb_b`8B1mg?8YV4uow;`Tj6q!hF{{ z&az#0eM3TUXF~ijj$(V^LEzOPf*3RG}0rOU9@4e2{JnPDqw@yCv2h2~BkYwOtLOX7UjLa^_Jb zwN9EDeC@a3<4=JaO`_X&{2%=_Pyk{(5o=>0*A`AMvVHA6{X2gda0ZUk@jDeQoW3^@Q1n_-N?OrRh!dxk{~h(epC zHzF)D@EKDgNepLI3_%AyCsjmKpr&r(yb?81(eb$K_nbr}_Oofz3W$P6LH5WPo3?Em zGs_q!?3(*D)~&@h7HrIfOde4cG|FJqtE)yE**Y~;fJUtiN(8wxj|kC_$a}f-@|W+J zHq*V*GpnwT%QL6?)J6%$24_!=Dxm7xv4R3(T{jobUHm(L=a;_u*6rW?H(!0`>2u=& z75(^qAAa&nUw>tPdYeXcb9Y}t^v;z-Hm~HZ=(|g2x1N3UG|#o?`p-PJqjjqaAARWJ)+&FU7xu#KeFAG@FV*qQBt zyS5)rtrz`azr8h^MlLrtl=`CpPd>Eq*qP$-^BkD=BDnED6p!xD)NsQWEywX@|M@2` zY+c&^w_lrBTk^n-w#U^;yRkJMu#SVSpXpy1^{PV|M7S_6dLzDYet0xfXkc?tT)#WL zb3eXslYa68YacvUerZ&^c|V%-gSEcSnX=Rsh|LVm_57er zlZ6NSH@Xos0Ek$U9>g>qkW`f!LClh|Oe{vV95cwfO-a%-Qp{nGTt&3F4lRuzvfDGQ zQE4n;W~eE(n;&_ks@?E1Q;-+KgP1nksVo^k2^sgOG-#!k#t$tIey=`yxuNY*0Bq}KP|^=QvGLTY!T{bnmbJolV=uFXcAxj=Ib6M%VyfgI zu}Fes8>FsD1OVW&_uH=?|KdM;Tgx3PoT>tmr6b8=5r|oJvn2WuEyvsGv&=hT&Cd*x zto$wVA_$Z+dZ4L17y!xKxQD%h>yY=5UD@EmPkwep(1Soo_1_fZxKXqySlTU5d+Wwh3{kVfa(mGx5lVu ztfx;8|JGmqp-(@xb$zdS=|**TuYT&`%|S`GZ`Ci}tggLxI3DBs-hcMug~9#9$*X%O z*Y3~n9L~<|^acYYjJ~k8mbdHuAL!%Rjq%>?`Qh%o@UB?j3Du!-p9%*Ej3grC^}%4n z1L4u69gLU_o_ctbG2T52LQ=Qr`}pu9J9XU@5udzziaEUS>b0A<@7}w1^us^>{XhB9 zXTI=$~&qUR8(Py@@Ie#=|>zj@0vbSZoa4-o1G}kFg1^U?gJ4s@jIAnuq2pV3@QM zecE1q-QK$gU+j5D}^ov!$M; z0PKMr_6Dx45}p0=APuXaJybJ_kxuVMHV|Gr`yb7`Q&!xrgawrq^!3^uW}^ z#Y=Fu2X}5mXl;5dO#`3+3T^<8e*jNkz^^b|dj)bDiE?r(&(CRLl(D>A@B$3fHIYkK z#Ip)jS!h73fh~g^UGrdQ`Cn;AZ^6#Iz@1@1Z6P$kf@PY`1^FEH0N3Sv$-b+qN>>52 zQU(mX(rMMLk$FMn6(X;gJ=h`)1mGxzH*!~ciV!pMu$TBgAPG!?pqA^gL>~wur3N4q zbPPcjs&;yEtsd=RMb%EO991F5CaDL=08Pl1&Tw1YKgGib1ZD31< z-hB3xEEq2N&`+@1JheD-tL7%)E{v0`VTO(%pFg|DO`2?H;+%pSaJJnn5K&p34EiS30FUD}yNVHl6 zw%QtItN5M=TfN|qS9*2lx`i!e!4wBrO{G0x*IByQ7S< z(Fo}okBdIFm2SGlJH-`R_M+#)azN2K9HOmU`(00&bp3;7mPHmyN8cnyrz3x=`d-+^ zSH-q2CC88gdPBg|I11+%GB>eDeY-+78en4@_{ zF6p<50C_-$zl18n%wUowiX8n@Ac{dSnf6tZVN+sf097SM_SCW3Y=x?Bme@}S8kD>< zRgIEN5b3H&>0VB-5>@9YF^04Qt1aSL&=H*xA;uhoBLGgq25Mu4dD74S19;|B@RJ{-L*@OJV~Y|2S&d`A7siEd0Q{@Z!Y}_K z%x;orwFpS)QcrQ#c9SPAxp)ZC6e1X>zaq+vj*-BO%oQ%S!8t5@KD0`?hC|U2B1%v| zkTy6%=hzHmx~Oz%8%)BW#^gLT=O~3Gi6JFHkSK-_qKbln_B;-H#bg?)Is&=2RdXoO zNTD|{;S}L_kVxL4oA_R?1WKSXjV7|Z*)FGLQsXC^nY78hwDNe8n zBC1iO=Sw1t5ksradlkiYR^2;^p(%O}5xsLgM-VLl9v-(x(q^Pzx>O;diP%Sjjz1@sZT%o<3Ih8PkiLjpZ@dzczXR_e`gdL>u-%nNtD~; zCbV?#`q4*z^zsKD-tdiJ-C#5ZG)L#ppQho)>8;*(Uc2+<*KdCJ+Q}nlPhUPWJekD1 z_ov545r-P9`J?AYfBxf_XY+PcQd3Le`P%MW8jf}35H6qFynesdx_xM82mm2SKJqR4 zD>4yxS#X!xg#ex3XZcjs>x6~Vmv>Ef|0QHZecjvXT)yNs%BLX53MF%8f* zu?}%sHC2dBD{AQhfd&XfBBaz4HdW)k6ZXe-y|z{q!~V5fhllfK|ES%c)GgxSBnW{p z$0$wRraP4iw|g+Vef=KNs9YPj6Ls6Y@ueZCp9gsOV*h{tGf!U_(2Mt*U;G!hS=${d z_owYQ-#wVtpe|AXR7Ej2WVnCy@n_fm*B{y(J9z!ZWNpy9vtQ3@g<(IoT5$QHCpVwo z9^AjRcmA2v-+ue#{!ti@`-gXrY2>7e;Uu2l9DMi#7k7sJ@4mAi1B}*s0M55M+URX< z`04HaqjvTup56G-4{m?syYuTu^~WDB*G%qB8;tFw(a(P8U~98{Zuy$@gQUo5xQ zdW;CuXkU2c;NAUDGJM}tTW2@z1df~>&1a80onR73`d902?tMyTR;fnj_cV(rg@5WJCSaGo=#J_zSB%oo?T3% z3BbH+nOM|j^9GUBEHp6{X*TmYv@I3@Q2-)T&DEWuH=9iA$-Sv<6uv){(88p}Q|rKN ztkwkG-T%Z#KKjXLPTxLmzWB!8zy8kd`~>{Cys%Y#>$T%=UZ0$t)PqB)Tl?5En;WM$ zKKtc++Ef=d+{o$M*Cx}d?roO@<GeeIpk{{A;2 z7<$$q(!z9Jr-1sMd(EhJYeOCy{@@Q>{GG4ddGno_v)CW7N9a4gbY-iV#4mm6o$I^1 zhX=dWojr_)-+A@=-~XjwxpSi-D65mkty6#0ml~>*K#pP)A%~|l21yBzq?R%x0!WAj z*|Sfa`OFVIcIDFGD_?x=&VEw|8?O2GXudvjTN^!_*Jsa;c~IVcZ?6!1>cT)GymvS3 z&4NS>frDrpR5gLUQePj)qS9B509CCO?G-eiC`x?f5^oMbou3?sfA(wl8nK&uB-SfS zc_GZ^=6eFWsp6q*x= z2C+5taIkM*{Fc4)HXKZeTmb=87NVjVvWP+qq7lh72%-^V4AL7GH|tU1pv2D3bHdO9kkM#zC2pPgMC%_fN7)q<#}`5$v3=Q zXp+|^0mjt6*L>0OG4gRpb!m`Hm;9Z*cny89dBdHiN z%@?{?tVwB3304cb@U;yJ9SZg)k*kWqLw;5lP!%L8KAdpU($5m(704Ca(%VKuB$b9kMIFK3%jW`CG&3D z6#_9*;snU#PD9gbtG3{lHXd-ibT7>d#r?S01dmgPhUp z+QhoyN5=?Sn0Tz~y6zsCEBtkQfDMlwp1G_0S-sN}ks$$FbG=}Gzu63sJRqPzOJrk~ zHq!T-hjP?O&s}pWF7A?4_pUi|wTfU$_bhdMrvz4CIFc4e62jd7Ww`VrVFnp@pG}4( zgQ$^9Q~boD?ubH(8-&2gFSA0M>MRj}ghWOJ-UAvGJ=AE<<@Y5K$bm)x1Mkz`6dXh8 z(0Nh?Q41jv-jn!cNC*T5AZn^WoT|hqF__3f2uO@E8aom-i-wHJXbQmOF!x~rnS!cm zG_$2Cx~nil%#t2tdw5p*aB)XLzM2S9ew5Ixvto6P%jr7EQwl`Yh5c&r*KmdMpG&VX z&ruCLcmnSb$<)vcV+7G;7NGP(lJZZ8%w(!U6r(N-FBt*A>0Vbr1w_Y`8rj)l44}D9 zj8f(+YEHb8Bg?}KBSufe4t?oVBuavFr_VOAOMsbG#gz^$MHh2@E#waRl!t6AQgCl#Kk&gIfs~$MN5lh4lORik4nh_MaZ0)$~n@AIg#ZY zhvvZk?q9&&zokF(qv3*&H9=!gkOfqT_Qvb*d%pr-`*pyI3j_l+>O7p78H9Dax(BEDo|kkIt|rT5qdXq!CpGc$<>24dil5X?CT5Yvs!jwoGAtg2#W zo~SI@F~&q&FiB}FB1QrOY=ZRqJq3#jMh*>&!a0X0v(QHMm9&inF*PISD39SlqvoYS zfgL3?zw?|}(O`;51|m_J?992%!LYn>bAMjT+S-5$9~%Kf=EML)$0TU%oby~)H8YY= zvZ$4Vf;}Fcv~84H4SU7jBovkUvXH21_}mA7aNfdy_W$@VZ@hQYZ(q4TjlcQ(-?@AD z&V|!w?(g5`wV@xBp$^WK*4o*Jc3l5#ucUE*aPjQgl~ZLs8Lto4y(iZzZyeUY{2O0? z_s-<%!#hn=-JXO&zyH*g?VYio)ixEOL7}mJ>dfF5e&)HicjvFXyZfL1_+x`U1=YiO zI~*0pxVc`OIn}>+RDsFnzyUxitXuSZJlL24-MQB=7aBl@TH%7{nEn+eq~)rAH8%$m z5L0)Lr#XRwVbe<6g!#OwLzvgnv>KwQLDNbUm7MlL=a@aGES>@hnHWy1rfy>+^QIP6 zeVDgKLsOzzYqLgM)7mho8eo(dLYsQ^MBw0Xa^w1Kt=o@$^8L>}_t5YB!OJ)*aNM8I z)yDmA-ktyFzy8wS{IMr*9fdHdKKS_7qvwa;zJ1b^JsO$sgH}?EOG6x(eC+w1U;M$- z7ke}f*7kdsA6k36na*l0ixL=IX;)4St_*Ov#SfkC{oyM|>)T`WZb~QH=QpQ^)u};o zZnHlcm2cmj-k;d%?X}@fZ+6_uESws?oj-A9w9#`=vD;!EbOeOC_(j7fh<2>HyJ>e?QXwX@)zw*)TN7r2=`s%(M)H>{Ou0$8HWvN#(FQba7fvBV#HW3VU zF;-h_=K#F-Z|u(AyVvq)gw`maf`ddpq1;}XW9j6>LCXP2P{!a3U zAp#-+8fdgA(f5i*v*`(!KoX1f1hfWcSTH!xz2W(b+w-U=lV-G5@~NR4_l}QiP)kl{ zJwE1M37#%pI=$b>uYC5MfA!@X_oGMyADo|8Z+DI-N3+SsskJ*dcGdLq)$z#V&Za+i z`Rv+;d;PWBZ{MOYl@gg8pSiN;MuVcjAN#~360d&Z1E-%l+k5xfhu(hk;N7?0pfQst zG>RI1fsTMmo;7;<{9wbu+qWju<50CQ9Qo;_S|9W_&yII4tW)0|-EK}M_prIo--2gB`4>*MmyJFiyri38A9op;&|Pemjv_=^kM6oCP(aBz8h^zVJgmKD6=NvuDrjjE)Yg!Oq9N{L;-||JN_f zs~FQwo<>S3FDa?d5f_IOz+`VHa{Smsz2}}P4)@~AZ?wDnGV3ua49a3&8z47g(U@HB zNCnbf31yGxl>xGZ2xiPy^nGmg?j2#mS(^Q z6%fcRDQWE^-Qw3ah8B=#{9|o#uymp=aK}q8O?P)JFB|OQMwEk=Nn-1KI$al7 z)+@W<5-yxR9S>`zixgnR@}pfcld?{?pd;I|3lvRPL0TPpX;tC@SgE1z>>o*FlR+TQhr3q5}FcTj6xoxg2prjPOn*s)8(2$agC*#aSjJ;D4#FX~J z&}3(Xil(!xs5*x+7=rYA&N~n?@i-OLU|EKO)JBh>K*Y&NshR(kEt0F{01JV+%OD`- zfHP3RDdv{K2xgXMP)X}gGjlU79LM=x`A0uzzxRXs_)oyOhoN79RB&(`u6+aE_&T(A zxW{R^MnX)oTDSgp9y@4$HMl`&W7=~_qSPq}C=fNZM3N9i6?$dKL?VjFtzaD@ zlM{)~`!-@|B4-1arZgg$X^83WM#5M}^3D;>CvC4}B#6NfV0|>$>rduY)ik2ov>~Q? zK8b?N&T-*fGmqp6kwm0(#bIni%Ps`1n}~%EZ3N;VSV&OAUVreVKlZ|L9xa{q_s5-<}>Hk#T)om&1N_)Ifuy$F_$%rzgkt_V(K4v+MWo*3D6~ zd3yciu-@G2y?f*6TQ9vk)uMIw(ADkwPP0DJ4?emxIjCb%-k-%Nx+V1IKKaz$S@_3) z_~xapF(Za3lPG%!jTq04>a9zoYF^h(YcZr}M-+_;F=|%HSH$qnNeV>NxeRiAQ5Kj# zL={Ulw}2VrO+*RbYlvcM5kiPjwW`{t4OQKWVH+fhikT9(!3;Ce^f9L&YOHg_JuDo%(IdeviXU)7eb5NETPUPTTHGHhMd8Vvt zefQS9Z*XSp+}X9eyVd%*fBxaE$*t*kUzxPbr_Qfw6$ePCcKYLoHoe+hC`lAZViTrOM9L5msC7A35>f5S3Oev}x9QFJnq0H1YD_twnA)+4C|BSjswfl2 zC~X@NQAB5TJFh~YeKW7Qu-QCZJDlww&%ye;Cx@eR>-)E-<>|4^E3SrhYv}o8E}wgQ zc6WbvynC}es=VkNBRKv>b>TjBRM&q^l6Y@e2l89 zOq489InHJvqS8IV6WB;4u6Ew2sfc>dZ`_&3sc|1j0uU!D43JO~OJO-?SW+HsQ4qe$ zM(FnWreKEIf^LKgqEgk?#L=ezYd?PGumAWXn;X4Y+wS4?+=e^YpNOGE@dYOrZD%&j z+h6B+Q4o>6S89X_Yp9fRqoV2H-GDuAl+lMD*Tfeve z2Vd$xbY}bR{p$YR>E@ZW-da&x`=uA|Z1;Qp5TFi+>fe0(&U{iA>;1`Y7;N`Pqw&2r zPw@2iC*OCT4aySVe0OqbXZZj8g`fGq{15;0yI=dJT|R@+nps_)v?X)D2Ti2i-8yXe zSKd2m0#YNF9~zW9{;hkH{r!0lj@GZbqr?564(u$d53~h9gpS!xIhsU?y5rkg9z@ntdaYLw0grkGDWb2jEwyFNlxCEEn z6lzh_OnQAqfVvGLg9W_;$q78a}K5N=4mi^Mq zVl;_{mUfb$YQ9A0fXIx29k#*R+G1mXkfINnir|n-muLgooSw$pl4kAb&=*m{aby0j zl@4|`VIHswRyu$d+Pg5DfB{Ib8i5!F>u~N86hplAy6qp}(Se0IAj4n{&OU@Y=dn4q zTHyXoIJ$?Ldi(T&OvmDwyux*RupJu_zo#u8a||t`KnRvu&_yQ^bv-~t77Z8dluX!N zDQF_>(kr>=XyM1P1!y^)Y|`jIF-vUWaQPnQZjzMEOu!Hvci7v`eL+hkwi%#fi;}j$ zDY2(*3+h0@q@xj$ArmqKb**aFHGcykD56;#z?R{=&aToa5$Ry3nTwnMoZdpVQ);&c z8zLn}tD!C={iTzI(+SHu3U%gQBO)*ub<|cFfKNv4}D!CEc{$_nVQ% zwoCLN2rw?4}vm`D(hL6D`wX-A1JACtA7wms8URTs#IV z5cD*s;0Fuo7eHJ z#O?*uxzpm(yR#)cC6DzoU>9)_^C3nRW1qz=q$DnM{W9r~of$?g4H5y>5-f%t8e!dN zzt5&h2uLQ9@AXu(%4C)R&wy=h!rEo5k~9Kc7$1=l#n=I7Eyi+FYIkW*E() zQq8h8hEtX>TLwG-8Bpr#)f9;XLWxS8H^fQ1R59um;8pK@(XM|HfYL1o1n7~R#~vEy z{TCn*r`t^vO-W;3{*%&_o)65#Nq{3vS+fOuJCA>f6fv|`RY7C+VI^hVF#?iC0mKku zvWTQLiU~t2N#kWE?}#0RHbhYoO{N<(D@$&pnHeE^N9pOnL`<0^SCkH8jGAT*V31qr z*^|V8gx(_nNfbl^Q13mcs%cTUgt{+0k48n=FAwgY+_`sj_wHfYFZ+Gp25Fjxh?1Ex zk!TY;&lS!Pop*>VQJ9ekh$x5}85L{@%q*6=8VRBng{$WWbv^5kwwU3{!>2#=(F>pZ zite3E=C8fy$75(34MGS-2~R!$)F;3HW555+H{GzjbZ-5j)4h|uW_`O44*O+M1qrG} z;hW>8+&JYod*x{Q*dwRUpDMWuGs0ObTkHN)k6t*A_N)K$6&{a$-?veL++Nk5G*Yhh z=f`mt;9zf7H32*w*HP5OOf+YQGlNeR3@ASnq2sSvvRBymn0z4h3npYav?^^I>o&GQ zs=5uLZ5!GsA!t;|CqyJmU8h7*O*8;A5Y$yGs_YPhg4o&3k!Lh!L5ynAVq-WDDu|-c z0>#45t1z!xPjq9}^c~Zn=x+_@q4hm~R5!xh5=oFdcXp5W_QGTaqYc~`sxLqHwd-%~ z&L25}Hqoh`MN>L{0_I~N~n&EpOYKwkhv$WAgGs}g&gh_x-?N|A#?uIcbcAfSi zl)8Tw!_hMD;9d z1BL~00hbi6T!z)1;D|Y)*+gQ83|-0p6QXz5Cty+_8k(>OAsVs)DKY@1GROxe@wxxU z@_{Ama|&i;N+t-Zh>EPh)@q!ckW?4W4gd7>m;d~yEk7F{lgmqt#`C@ zapTUl>CV}$o#9{$d*~ez-QAtOdTV}ga`Nf-o&Le+PyK&?@#p_H|F`P)yVsRQF(?ym zZ2I1qj%M-Q_a?8sdsK^k;=^b0$&C*^vo0F{@BhQsufKD5YkS-}-QT+nJOQbtsgYF$ zaBb_-v(MbRHM{=C3Bte^7MnUWfdC~&%l<7BP$q~Xh9m||I2xCOvN$-Z5B4V?cK8(Z<^6zJ2Rk|MS;he)sx3#%Nckd0VSj`)20?g_dqFIn8pqM;zzT7(1 z``U{WHX9G29OLW+=Cuisp$__b>0xXG+`NTNjm{H#T^rgbKY^e6L44!8cI)dFT9_Qe z+6F+sxc99vJ+Yt+=0l+5Y-{EM3WhqHRIQV;0N+DsgDaue)A112M-a(hd%K?3*ft4N ziV9fOA%-kr1A_0dsaonA7b^-F4xuao9fsQ2YY{+))Kn0Ig~m)#BP82|Mo}oEh@%*2;YQE%OdTbs5vhCai|As+8rHH8=;3An`&*umrkoP*7E*evY)RhZXM z&Efnd9IU};4Z_UoV>`G5C&y4tA=WGBLjs8QKpXqA;OCEby)SxwEsFwROAd5$+@wOW z#C*x%iLSvX(TNNm9-9VNPv3VIpLZCc-mX*Hh2jr^m%_NUZ4A70X zy6Udw`$8s*>6-y*BlTR`zMBM40w4oJM(%keQc+VtM>&6yPsRX6fsCMPA?EX{Eu0v* zl(!6XekMhp7R6+kJ|D6e(J?Ss8<5e0f?D48CKpW7kCt%bt~5#k6pSF7YpH7)R?TOt z#Thtxf)?N;ru5GVvlyQl&kF-g=c%!UX(%O7AeAwbX*Qi`5OSDQ09P>Nss#oyLXgg< zkfM*w00c3DNeX{~iJ7eOr0O|uzYO+ZDc)+kye)T3 zwqXCQpoqHf2|2y}?)blu`IbuB(j$|14wQ?WAMmUpEPuknx7WFvRF^7}>GI3!hJl&; zlgzrR=~NAt=)CrzyO0)zUki@*_mY*CrLUbdl`iGHmrRoRQdeGNZq0dY8bJcKWS~jD z=B{UL>BZtuqf%5VcH*jmL;GU=c%r#sg2M~RmH%NnM71X5GY$GTLn)TGYmB0 zgd{4LoO(BtNyj-fO=sGC24Lb0F10M(gDF~SyVqWi`vp2jb*u9#%xWX{%$D6%h^oqt zlGviz`9jv|fGUgI6>=;Z0SP$gz%rdWU5U8}DW$?yiC7iDEVZ1NcAxZOTDL{`K-HKL4ML+LNQBa=im6cud6jmaBnU7u z<)3UKYDi2H)ffq>X+oOcrs*yMG<5?D)EHXR#9rZ2jh<(8%%yjT7J{K8LTZ~pOsXPk zL9B@?QJiB9VgTL)sIhmZD555Yrt9ndvT(DLIw-`HoKV}?>TRs`t0p+lZO|A^SS5%m zls&Itp$-5*Oi0w$(U+bWH9}}wLm+a6bA$qFF#r_=pc2FYLkP@11d}M_iGh(YG+}nq z44xY7-kpB)>o0uh!|$KB_O*Zere`erWpy+=ck%o${%?Q&z5T;C{@Ht%uRL>Ud$XQ| zUeCRCXY$^id z+?CUM^?f^&TJGGfXTdf~Y8u_E?B4BorU&nTrvKrGdh4E-26se3PIZBZxK?1A#HBg_ zl?4qDnJguuLNsJR%`{8y+Qd~dzE=S59&2k9BLHaIXuk*Ju}c^=HLIJL=Vz3MJ!yUM zo&iCkMoI2cOC*7m2NBU2lS>7Xyg~`Yg9+H2IX;?w_-S<8jiA&d=E+Br=4C-2x2zwD z0A#Koh^S*qg#MI#Aw)xn8N-p;!kETRn#m8zd78QAu%KC5;_z!1$q#J|O)UF^woTRw zt*RCo>S+s99!=-r{+!oCxjvlk9{Zim_Fy*Z;|H#cLbT6)bNBqkjosrWicKd?Rkdbr zb`q@gR-1}BX@2U7a}Te(AokT;&E3Y`-<>}+;!#Pe7R90%0E!4DCw|W7rZzNAr0Nv+ z=^z(*SC%%;j_{2)?!*0k9dCeV^m(YNl0e#;jIv$d%kq4b2dJsRAeTk}fiW5ofsoCE z&E{0Xho9O0%O5-YQy)6BF(yDen6$t5#@>JZ>o30f)%$jG?}clJAAaI=+X^~rt5|sF z2ql_xoJK^Zsr?UC)76q$uA)j^i-(92a|{ugn-D`3CTgnM5Spqb#uy`*NQj}SO$-#F zZh&H(&d;5{boJs60={?i_?=q^Vcvikl+KP0;A9^rM>bsxllj}%_QrqeqZiJP@871>zv}tIO~e|x`qAy` zFdPlTxiiC8cEh*duJ)>1!%^|ROXL6Uzxb=a`2YGBZ@hV@&pnKhTk1u)a;k(T5)3wa z^pU5A5X3W_RQSHDo1g#u3peiF8~5<$Ti3OnLDSg0;cYKR^DsF7&fCo&zVP+k+Y{!Z zozGQFqM3<`=1(;m7)p#;Jr(Hniwm2*F-vLj$3FA^4?OpXEA(G~{)LmHaQTUg<-p&& zw%;EQql52WJHGkN8%I@r3s-vf1%+0kSi&ocNcvifo-0d- zQJ#BjMO5S`zJURJw6dIEqbgGV$i6vxiRP$SXU=oW4AGeS%{Mp74&s0 z!x21s70;ft`zLtgrXslz6eON~gti9yxj(R1-vl=J#P`9|7x9%B?K>~V-2*o{iNw@k zE7CL5ww4$qX^j#>Z=HIDy4boBoQK&_LyD(%uut*wCBJt>_jhAk2|1RaO)DaKquU!4 zW-(%HqnH^ZY;5?o4Ge8;BTBStrlAG))Kn>O4H`k)e9)3s**PklMlqLx`#P6ZSg z3I@|jz~)GOk4}!XZa^xa0tTmebDN7Y3fjSan@4!>8W5usb7;eL9F1Xp%Lw6Q0wF*> zhY+BeLSoq-ytyH11DrR@*as^K1g3ux3JMOjIgD||2a1eQZrGX>3YAtXiuU3PeDZbo5D zE$pd@nY^dcA*K=&qkBlf+y3I@mx2$Cng1|C7W zTv9r)CW(P_dv{0t!DTmDJ^*&@V=j?Iat)b^C1VXcGzUz`WGVSYF8hR4AOsLui54ze z>zC35E{fhd<5frI?(j=X-W1}>pefsYGLRit+uTH0BKf-VK_&1>*LBsonE*IR3$mo>t^S8Ae4B;#1Itdc)yklyTL+{o>rKb={2hT= zCi5>wESLdSNlM7a%Os#=>C6lXkaI11W&p&D7S6$-bQdzNlD?3$2)4ivE$W#PrY1|! zlKg!5K>g7|F2f82?2agiVCcXxTgF>;ItylOFszm#11s7^MFi=P%Dbbsm93+L*xoX zPW+l&AVr>H6e0xR*+fK1#k^-ud9fU*%UQ)V@Pe+|JQ=E2vW=F!lIe+p1j)&gC;=(# zmV%rr24KXLyS<1^as^wifyaz>K(Jnqh9i~`V@z79rs#*J%_#vRImby4brkGgrmX^^huvikl zGlkd^Uw|AXJ(C?tR7(p40;u|eoGT=12#U zXCllJbh`DHz_Bz8NRc$ql*VvOsRk|qP#sh9H!-tGGz94utqi}y?i&XMLK6k%G&n&@ zGAKgovLRFvN?!m|T4yNZB9e+o)PcDd4v zYf@q@iLzsr6!*}gV3bJAqKaY&nru)+2&$#0(jy|Ps3ad*s{rO4DNtx7CJVSh%47ki zX9ar4(h8~-o|ur>m4)}r&N~fJ*@}`ZL_(a->Z8LsFb#)g;r-s>RDm4haMWvqR8`0f zYE^bb2*^}7alC!0==XN--krB$)GsiX&ZDRSVF>d0laEIU@4R!%JDNjpows!pqL~8Lbrghr{zRk*Y?eS?RJytqK#HOYz=Y0Y zY$H1d3?3l>)(VQ`5s!|l!+DURIH~I6!?_ZL5XE8}v=%+7LsUAR&E;4oRe0*s_M=xX z{l;&9b!~I)gU_6EAn(3%r`^y(*?6+UIR*s4&&}$(& z9E|((O4s_ug)_Z=pKso2U%3$?mz(RZ$Jo>`-Ym;uSzCQ(-1Ce!C}zN>(jWWE`IDot zb7n*KrfP8Uk@Z68t-Hqu^R-J`?&m*s;R9F4lWB9x*WVN*cSxF_E>n5jl z9dk}<(PV+3s@}OY*o#pmmo!mYWSnDD2r;)rFY%Nex3SBT6R4me5x89BlxT$@mZ%~M z2;^8hu{>eI(}R8yL$fSbT6QvKe)B>f&xVlP?UfYh?hKM^a}h~3hi6mp-i$bJ44Nov z*zflMlbZmeY77CH>uA$?4TVBeHOCPYrK;K6Cm%a?b=@7-`s%y;k3N2i`#3*wU;5^~ zr+04NghD_fkPq5kxwQW9 z*!Itl-n=>SefP*m&R#qu`;75P>`*`z>r!Sv<_q8(_710tXr`_(5mX>LbIPAS^NlaOSiN&i59fd_f|Ua{3&fpk z-Av-5G&x&PuT z)1worYKcsWhDaf%ohKslH(ok6GbGjV;D4g;~w6;P3=5U;lV&=lZqLWWE`WYfMZx6;i*&J(3(cj(QJyr z=(CsAg>z=CXoiRhg27hRzD0T{Hc07}vgueR)zUUdC*jY1vS2SL-`&pL}> zhKemCVA-YwriR{uSt8ox<_k{rWk8qO*HVVa(m>nl00zEa5E6MrW-}uK2@B?vq(q7( zumz`*ELkG29>@V0d^@%u~67-$*S&> zapbc4V`l6y0m2t0GLT(eT?bRvB^HUmY<@B^aw{1(?P6I5h$tO*5WCdd!gba0qzyUu zhBKomXk*A|aZ%%)V}I#2NmpxVgvqU%lV%GtJ!LD!q6=9y7p^yrvNu9<4xI-Cjlp7L zF#;lnV5vaOf)x%VB)SmBXsN1}7-Q73N1&=AL}Z#a+z{0?XjxKTZ_+)KE5k@y;Q}N; zh$4VuP?Ve;LjZa5Y2C7%%pl|_BexS9sFU&&Q^P2i5hekIn3%~lHHn}EOJPz#)S$TV z7iJ{*qMI%I*1RY0Fou{`-VoF!dCLUSjv36kY|l(zsH$m(NdtAuVlvJkAt81IXviVN zE~?fB!wQ`zsI}-Jnu>^;YlE5*Gm0pvB5@1?Nz_jnfz;wHW(LlqL{my~E)Y>{qbu1l z0gwcfd}v9xy$%Lk_81hJRBNs#W=%+pPxGEIsu|QxQmt`;kYdM37=y)DHFGF53-qz` zE=nTqCtI8nr(XE{;8RgV5JE6b&GumG7!iaRks(HmVv@gWNWIz!kS0jkklUrqk`plF zv{D#4GeXnMKXvp%KJaVDSvSx`zevVJHA`Q0S7hpaQhCfd5-|~FPiYsZmZ%wtfu)qs zB(P}nElVeDTb4c@0Ea!N5$0_afG9$i%!3%!>Q+K(Fg7ql?~zH;K)*whLkt28&at)< zASU=Ti6fPwSI#F5Gc`^68r}N(usS(8Ii9CJ`xxY*%jd?U!QnSv39SH8Rkf*#GmT6n zh$}q-9ULD2z>oag-~Ri5Ykg3D?OQkhcmK&>Kf3o?Z_E;dsv)tcBKe)2Gk5Ra=;+#p z4$Q1=8f{%OkN5Yh$=&_KgOl4gZduc4(QA%RKKjuQed77Y{@cIzD_{HS3wZYFw$gFW z#a3_Jt>3x1d-lxu-a+LN{_sn$`s)Yh&Y!E>FzmU#8z=2^S{76Rymfmn({_EUAJtAK zEwnN)d3>uxkvig?d-JwY7|?9qHdW}Yl}(I@{My~)uU$KN|8`NJFp%?vmck5Dih)EQk`Lgq)@y7NvqVbq&ZN zN)!c$1mK+dk{K{m!FxnUEzz~z$;-E@+lTe>TxKV;Mx`d0wlbMDMmn9$C-Zvma8g%o z+qOm&tGG3!k9_d)uRkJg<8+!dMTGr`|Er4jon#) zXZ_OEjW=GZj;Ffw@L343?(61o^8B;gq0)n6*e>bndU18ldxZUCyL!4@8~R2Rh+eui z|NKiwZy&`wby+vEKEh#`-3{B9$9QoBV+R{U-zyvd?A~uj8*Zmh+mG}LhX5EQ6;vhX z4pvd`9kdGO3ub~4tmsq6_(L-YYLnLXCR#^`ja=IH=QdI)A|OB%i_yGCLKM+E2km<& zRz+O*x>fSpfC-^$j8#BU2|^oV6e7ycOf|&hMj7p$vp-{Xh8{)h(t})hzS8=S`t&Flt_XQ z(}Dqn87O8c!kkLq(*rd9=W2ORn^dP%yKZJ`G_Tu~hHBc-)WJ-}a5ihX;1HWTxAts0 z52K#$3GS@NJ?nY<@uwf%Ebz-WYV9#7PWMh`k@gOomYpj&9MxJdu!C9q{a1Fbju`;n z+La!{!|QhHa`C~3#sCl{ldKb`EWxTpOvQ*mq9m0+af{MBO>92}ASP2F1yuWUKlbQf zVluV;`gOdtX}kDjS4kX)X75hSc2h#)AC8IUy!bp!J`d-?EV zYk%nnAOBMyJ-@j|G1x2bP5#x3yZ`F#$#?d&L0|Mn#ZKS%_u;6vzFpWJscPY!8hDQk z$V?dqv24!mDo|1mIw#sO!BWz}IRVI+a5k?K>vlS?+7Lt~G=Z6##!OXX!v7JfS!{Q< z$5XR^`dhEQ|M4?_>JyhpK@X?6S-`x~FtParEXw4_(Ay-u`R@MyB-AG-SfCtCU~?D_ zE7!<{E9*zIqocivh(7WC7iUfLxv$)5RiAtO!ke#Nd-uC<>GqmCd-lW6?D)A&?#u_< z{`{rU;fWq!Ke{k3MgxEC?St!&H1iO?`t9rY_S)WX@|9QauRnik;9yh$iw>B$#KTDx zgQ?(ef8nj&Q8?7%wPBqzJIha`qtOq{YSt0xv#u%XLs5j zS0X5FtG;laNWr35uUBH>F}dT>K+O@hiMW>5qp=5p5M@?} zR^X4mee0_)+OWX2J~`6kxum*~wpCzEkjj(V)X+#o<`*8qnbFAp;kr-lVRK!%FZK0XR;`>H?I;Qm6&8Fw1H)9TMHFj`t@@G2ewy&%aO?(SUk+$? z(zK1S$I&`&oJA#QsyJ(5?-1bU&?}LmwUx1DY9**yV^|V0Kw{j- z2Mh%(oDO*46uM~Jah*up@nUhA-df;DAccmKZ3HMQjE)r=~bLV$5qKFYw43cK}uE<^5862~42as`(&@9&3 zznb9OolJ=y6IwLJ&r=1hWx{zG%wd(vrNup%*1xi$QiGc;Cs0y0=4qyhr$t7*+lf-*r-qA!dYC4vGbxQ~jV2{Sk} z*T*J8+o)&s4i#u#DKeRXD+mdKL?S{!2__LKSusor(K#$V_IlI?sE#8DI3`1kLDKqw z0FH?Wk{W4*MyS!yEVpQNWw8m6xmeGW2BT4Praq-aQ>Py?w2$l8ugldR_Km>ChVX+sF6g0A3%U2Yn2 zp4f4!wuu6WYq#BpOaaStoa9E=B7Umb7~12{WPNq&lVwc_5_1v#Cb0 z7-Ly56Z(RQ#M%^Q0?KhQ0|0b@%#f;Ia-tzYd~+c;c4dDm3WS^*UBEb*J`mH~NmJfW z)v#+s&~yN>Y#MVehRBZD5gM8bx)d`uW=aVHCIZkzh+}2|3sC@pkVM6oE=F;LWkKU% zIj=&POAsiXV^3mM)lm%FnCTzHXa=H*ZLW@q99jC591 zwog6#{eSzv|J#4}AN;dF_`;X}%3u6z|IOe1d;jTw^ix4v1Ov7XSdL%+#kz*=&dwYE5+{lfFU;XmScWz(90=W=mMnC!ozwxDi{6GB~6y9RkIX&3i=_}zk zU%J;r{fmF*eOFEmUVVFi66ddf{+nAD&-K>U3a0+{_|(=w1YWv+c=zD=^m=JvQ*HYr zMzFIxy+_XWnV>O)zH>c2oX)5qicAb_SoDf{Rsa4=cih7prOpcAqI6(J%xwswS~nr6 z#R$YcL`6q!FhOi0G!pANT8_43HE)w4K@6%UwV#0~G(oLZKtLr`dF%HF;H#9 zK(W_1(F^BKZS4$fy@aATI>rD47!9E;fenI!A*_#KG=?f->0wliNBr@pPrbKapSrv; z*{ho4`S~$@^y%%kfmRhgLE+XnN-8M;jD~u7hYt5=Wh@`LI(p)4dE?sT#cTEHSVTo% zwUgu5CGA{NnBv#;r>MKABU=qqk`A^ z-18XwWPr!51p`0}0Po#xP8vIzQ{TfwTf8|WPdP-BwhX;8ZLHxi*xg2B(2Lvt%-A8~ zaih0R)M=BtRftZiL!4BpyE^;tHi9vGY0rWVa&Cf8-tBmfbR<8Er4gs8-)1W|28R0J@EaJ#LAEXoSix-|1*|CsHuh?rb6 zB8VutfMc zKny1*`cMDu-mkoH@8907Ct6s4h-=<4AOvk&t7^mOdU$$cAR>h5QVKvc9q@AUAXocn zn#LilQXRYVv4JFcNKg!Cb<2*8AZQE{6IqW%9gzT-1aQvC86p&X|6uwXpMUMJX}3=g zFK+ctZ@5V;tZk7L>p4I)2L@nG4TECq!baUT8YA`{0%>S^JEb2K-+p!fv){gU?{K;? z?48W<&b_1C`}J_6clE;BfG@oF;&-%}9-SOd+E}*w@~a1XC-upnynJTOT|7UyxjQ{` zc}qjsKbk*&`pn}G@4R^9{+pBd|NbAp{)Mk@{K8K?_vzC+3^*5j?Avt*$w;u&42eh-+1L9C{=azYdxtd zHAK(RAhZGm#9W8S4!}sGI7dXNiL(&_3B7ZsDJhArz_Re9I9ltC1|CHfZPqkVEJQ=X z7+J+O9A3FRxV;OryE?0t9RY$dB}hCfl?AMg^xyvpe(F*C)!)*CBkmV)=CnAk_jmE; zJ(^4b$w@Sc&{Rr<8>e}^#k)78s<2TQk7=z>`=x8<2AZZ3`IeU`86%7sTb)+!=vb*R zQ#rql&pe9d(7kgbw0D8lXl>nj!eIVR+f1hh2u0~jUjSOuv~AVKIFW%U36oKym=#d^>8Tw68T3VCupCj$F-Dt}B^ zphfJjV^zgatMgb6usX84w?S)o?0tCJ!N|k$9B$o*Y69T|*d=2UEP=1BngaUoVf`#A z?+ZtOt-w1n)FS|xL6P^JfM}t+lXGd|!mp83m@ed!F+M9y83TyAd=b>;1QOp@7ft87 z3{0gzh-PO;I_kRx>LV3hb+nTh!4Y{jG7Dm+5DXjvm_?zourxasP2G&ku4%*AX<=SZSOu{s?qQ)HPyBRDLE=n7NOP@5`P zo7#ZDk|akRYY_}w0{jRvCc{O7IGCz1X;9?cS*cNgz(k3%HwTFl_%YjDaOF4%W>LUl zqUV4EBqYlPWLYc7z7EhJz=#B>VCkTj&eF8(Tu)vP4N49dfF4AYkgj#j&}s%S2oYic zV(R_TK2F3ZkD z(?$8Z>(&PL-g~b>oxpKNn z`vqr*R`}3=tfdceK|NYZOs2pdoue2sImDK5p{%c_D0lke609UmfCzI3rz*slmBi$| zTU0ardISwRh&Zr zB(eU0rIpE4Vx+E=*PN%+!Gr`!JVXbH%3**;S$6S^NEV_ApemSXsx7yuxB&hG5s^hj zUaIBUmd{9}L|{l#2@rD^3Ia4vX|4nZR#{OZl7(8y`PimdFd2eGNs75hhZ9m0%UYgBQ6zR4gQx-` zhen+vQB0{=B6Li?;1I;jL@3UqL{r5yvhMK51Wd7wMb80Xh^lIda+1^-mE0Xej#RRh z9l+SJDP*(+W(meL*=isLAx~vV-jSG@1_?@zl7cC!q96i{5JOC6_&n|wT~s8KBVTwR zh^=VI93x65T#;0?qe+_t1E7S)NPv#+T!E@8qJ+7xJ5wa`00z(z0!WBN7)26Hj+qS2 zRM?S9beMF0|MHm$2Bf?46&5rig2gs2u{XGiJ^h6vG2 zdp)l~Bua8~6@>#e6G6boAA7i0((%EeFAG8W7{{Bz?@aeVUm;dhnr`o;spTGFsU-|8S z`ONbleesKbur~6lDq`d@w`itnPE8$a6oUAI!>n%S!2|V2!}qS=Iyu@!##lE<_|0#A z{cGR)MqAacKd254eG6LYL~LHyKlQ`UTwLq*h`#WZSKoN`t(JIRmu@I=J>lcpAH+DPO~ls&}=O&!YhL9B}x-aC5V zh0Rf`(6qgR!At-|l$|p(a&9yp_J{o&w-4%h}q;~yCPiKo|Z+^MVJ9zH*~GIE1UN9a z5+$O4R23yhLiECW)!fr}ciXq_!l2}5o+#YR+L-`A)hN{-3WwC&*eQ3$!1NcdOk%`$sVntrI+c zuAo`lV|w(g8+b@{vT9H`OjV`_t-W?Pytm)159oA{HoTRL`>lQMopygNkFCkmXS}Jl zK}5|lX1rLJ&0$ALxmGjGs4q;tREhGFr6SF2Izx<6iO3-(%Xr#*5SqmRW}OqzN=LqA zV2p|iTt%HUvOkr*Iv&GkdNQr6Ca7X+GEp<^cyEX(X{L|| zO83*4vMtG$ z)T8BgyX`T$huiM9dbDMATXGLelw`@0Wy>}tQevii|tol;nz8lWnXYaM<`u~5wWB9eNU;o9g-lL-a(mS*HJf#5Tb{&ouq6z9k zliGaoiI>lO?4r-V;P+i}j&PZ5?hjENm<8!dL`N;3yBV(kvDzBfN!Y+l^ieQ$T|yDwbWsNQ~O38v%;Bm(AbtU^eT z%Hu`*-rH9pFgP~vA!2v5oX!{DzH<8;-?*{)#Fjd^{_b>mwjQqg+t&`RZV!?ztvNP< zTUY%r{@UyRyH7s9zENMfGym%Kc<-IJ|H$_}wpADV_l`Fv^^NNXPn})+{trL;2XEcG z(W;U|KYZcQ4Ug6~>Bgb`#+U9t_vC1O%`I-qTwT_}4#wt5Yt^V!T!_r}J^`jorbtjY&;`9OXmqqIAaQbIY<1=W3t6 z0Px-w-h;?!tw7Pj`KoekmdqB*w(SHAydxrNB_Zg>T7_M*gs94^REI{XJ#0*T3ADD3 z4_`_jenzg}21zg)=y-^!mHW40Zx8R^)26|qHWO%;kuY_~=4%N1x;TQQaAun(6HJPn z*=2famB};`1N7!4VLD8^jg0uXY;%Gz#x#sdXQ+RW^@gPT|F@&$P884L!K!uIaK0fHJ!67s8M zNd@r0tnrx@N< zHYZ02EMqp|LFE#yIxj@4f2Q1D?}HEdgoFVMSBV(yVJ?06ld1NgrcnU09~U)5;Qq+F zuO$N#bI&kO0tgnPs(`BGLvzRMU0-xF1vK<%qTmRTnVcj6AVb2cR5c|8@|j@*s=ahW z1q)9V`btb%UqVq~j2M=tt9`hMp`(=`3DH3>9wNic1z8Dody`zx(Xd|7zLEm1yhkfo zDCa&7DbmWM-UEq{!BkT)RmeL-TZM+mGom4Zsu5-i5`HH{2TriZITg|ml6*G7tMim; zP$K3$d5_2zIwcPvP?k_sKnx~O4S*ma;9vk{#q+5))7(esHB_e%}MesN6(PvCDSqM9Fp=%UKea%{wav+p1WeQ!x*O=~iCu zo?F=WpCQlqK>J)05ip^gWZM=GdN*$&wq~2r}UI;O^`&(5(fi<*1ER83`ABxZk}{oKjjgnu2XhkW_5+5Arv*H z*!#|^0RVy@z+w(&DA9@voq+*Fp(wz}0N8e#qM0H)#9%&~%dijhNFOf)=TM_kK@!C~ z0-yOlnpxC9l!7VtB3nctwpD8h#7s|cXVj;wvS10!T)`Qzmh&L_LM5l8q12TE!D0cD zuw4i;)+oiw2GoBwT@5vR6 zfw*8oLPm1LVkSKrQp5m>oIfq{^}!%`0KP@o2Mg`A$gBVc8Lm`S9zk<)4~V)>kx>PS zh2&F5lqEacGl)I*03%!C+7y z9hRT}^l$yWfAr*NG6cSun(lXg|H}ZiC{R^sjJ-w;i~wRxM0~P}FaZh4O-AKhZ1D*M@ z0OEpNSr)OjyUY34ZykR0(z?atpnyioV4l^;fE+lkJXdbo#pC04avYdlnc@*Aw(>EM0)e~;hDGYpFO*IdwDltns;$})J)?C z*qB7Mlyp9u$JzA5FFy9YFJ1iQ&wl&e{dO;?dL~3yZ~&9g0-+g!DHTo=Rpa5)PhEKS z*>k`2dsqDC)~Mz`_QQ`owpCuae(&~;8B8h+feJQe91O88&hLyK^Z3~L(b(ZL4^3{j zw6j%h(&p}dyn27yD9;nl6R59LtsL=oQU2(Qo9Ak}^n?e@8Ckoq=FhJApfKAizU%Rk z5=a_vR@f|~1|hR{nF_|DCS6u(&y4^03+s%D> zMHRt-6o`0x4CK->0^)F|+U@k4?=50g56AVp2VIBY#x9vz7GyG-=_42Fzx4eV2b_CP zSP~?FZ|=j5BYFB<0jsAMt|TX_0@zRRiBBrwaN2nQ1cHn%LPS(33O<-F*c*)<74BDW z#-CpXX*&1$*%L$k;im^5y)b_6+~C4S`S^vwQDiNtm&j=IKNR0Yc_!W zsr=2~xcN`NcK6yoL0Qvi1luJ71Cbeu0TLUaF%q^0491gjHLRVartb^G2}FVH0fDb( z-t+1_)9gX11@*NyL}Cm5DeBzz`@PiyNgAvo_f>~&F|c%VPRc!|7dn^F*l8M;U}A; z?elBJ*zIf#Vq?w?zV+riww%&r5DxEr>)o~6M~^&ld6IBg?UZkQwLAXw)j#%$rwWn% ztJ7kAd=R>iJ~aBHAA9V7{=KVbA7B6X|JbvSZ83sPlT15(=*)05F0NdkUitQ(IdysE3DKt77au=Z$2m-(R#Tx}%LgdmHrK@TROLU&1nB%ZeEh1w9 zK4I6wy*svlq!QVAULC|^7KogdoR|R;nywA(rDx!!7lCW|;wyIjHcS_g)S}w)ERq@! zB_UrpLMFrzQ*4ujQ@C%>SLt7w6-*WYkPR&ca3$pVk(P+Wsz8Ji5=w7rSwYY(S5F)u zTF~~O;q3t#I3{oun}5<{&u6ddSTpbrG+#oA8^s@DL`jc205Ke^;DNt&{GTx0#RT9qDDL6J&(*#D6gQLMtg+zqN*uPvLDG0N$FAyxP&VRuZIHzVKp*5afyh1niT+3h}0*C}^ zIT70TA6A-!US_`<^q6S2$YV}0spUP@iWUSa(u0Q-P5?|M1`HO>)C9B--l*jQj#}T- z=)-Rc=+M-NNpe#v5B04_9!muCXi*U%b-=FAkDxOk^A12@F|+9*Fso;DY$1Jz9e%|u zH*}P}N^oL%JB@$z*PN*#t*od>NSw*Rr%{^KoT#Vy=!0pQ)hgg*LYm*S*o)*(`f;l& z)@uBdGd{Q~NZP6+X{!lVKY;7=ZV%3?`@IC_ioUH3UZ<*f_>L%0|E@Gz5qx^;cILT2 z>{6a8T2IkBwRf%l2JfI6AUlY`x{w2Cxx<1c`7{i*NA~n_q29n{;2rp~x7#5?J%kh? zP!87^g891Vf*XRS-X^ALHMQ#zFxlV+YQV1NsyhdOz@W@M+qdvg*Qg4qg=oqM=t)({ zBNB@CASYxiJX9qRLyCZC-Vw5;1d<@Mh6v7q3P=JZ&}2ra3T>y}0|9yuJ++BY#FF(R z4C&=xtAou1b%kY#&Ko;p2Wl9DHJw#8pn+#lKu}D{AencR1lmR&ks`#9p|%PDg=c`& zHqm(mfaNT)!(mO0DwMTP(@RLj3v&-cL2;4 zv%a9mt2BI`9ug@4lCjgW(zSIh2Dk;-&hhX7yH2ZG$^s7$biNP-mz`qHbBdPagfea! z^sB1QVQ+6CG5{5I4t#+tB$k>AAyQv}J$VO`BU3a4=Lq{^T0fD>nId)!KpAc$G0S>EQr0x0s^xK#DySGC zX||pLAm?@$o*+04a)}I0EVhxDP8kqps>+_Shq$b9Lz;>Fjvv>+0KAUjG~a#eeLo z3KB98W{U+^BgJ~Y5XXe32&5(wB`=F&7d6BSPdvfCe($YY617=0F{b6TyT5-owaL&+ z5Hbuwyf0H1Lg9yJhfh6y77>?A+1rozZr^$7eP@2@GjF`|sb-(iI>rm8Ok~E2mxHBqAp$+=Zokf?xy0~4^$oacRjT;S1 zSLi$qhow0E+?%@&>;vc5Ff^eFRQV*zj!h{wX}GTQ{l&qw3j%i3#+0UQ=-72_A_6k> zpec%pifS}lHc>6Fcc`65$EZYIkVV@yO?UOi!Bdwu4yW^jPLHO`5W2V!EXZ7OyfkCy zhJ|)IEQWvWPk!j-N9+IXmz(`V0ddv3Zw}hH6!fJZ`0mb;1;b&b38B@U$Ik7zDoVPx zKl6hjk=)szz5h&oZe#8Ctp=S(G*Bd8xJgBk?C$)rm$qJhVi@+CmmZtk{mTBra4;y} zxY-=f!emn4yxU$FxmlAA?lH^ZJ5`xz*~D4GYR#wn>F6LDg=QA-N?ae(#+r|Z&DxkQT=b7__$N2$h4a2P zx_oXt8u;2#UN~%y%FR)~=Fp_*@ZNrN_qf}h3?AO8a*0Wzc+Y!{{=!#|Z%yIC<-ySG z&iyzk+XAX{8-ChK)0r>9REv@UV1J(8ywkpRU%qfHxU=icvN5#+FsOa;dic_NLgS)6 zUToA=#(b#cgPdLt2q(An{$6G$QF0NrQ;H)ZK&CbKa>gt+0VBq;EQUovgOuitLp-Pb$E+AJ+KDE(mw012u6-X2!gWHZu$gpAS>kj~g22OGhITtg645w%TN@uI0~77#lCmrZV{f^ClTj4xcT;#8}pfr zwuZW}jtPjAV=3`-a_`oU+Oz5bQ=XsJK`BOiY6*4{t<`~T9)!PX1g)0_9HtkC=i ze)3QJzz==&Z~V1C9}aKqjA1d0U{($o9PjPNS#TlR)w^@gqyQMhWKdft?0I_JviFFP z*AjiaAqxZz(1004l~DN5-QKx_ z?VQ-raN?FT=~^StMlN*%hCtLTLkdYc(Wt~Ek|g8Or59?i&e9;G9wb^oLWi*vNdQ3T zye2?24PvSYW+K^W3@dZB>!bJrvpY+!m@6UzEr|<8Ggo1^jI(?5Y6zokG7%MsK_+MX zVB}2ccsCx+pnC@{KTe0Y^!^7`GdQ{r()JmM-mi@P4ret~ zUMZh)RpddIuoy6cGgN#)ul#_YD1W5({;2#pd+zLMECo(+wuo@5DavYFHhi$3_5kO_ zR>ngGbes+4`5+jX!7)1ShlQ(ejl3sKpsH=`TV{k{)FX2)I<&egY8ydsczaC1htod*!?%%>K@#Kx!c(6FM>kX+;OV9M#>T>t+eS z>KX?%H3%sH^&=<10xjgFHZhxm^o5QH0LTtO!8DU=dJ#1+Lf%;03XcsdW)otMA{GP2 zzH5fq6Tz_`J!A<>{zwzB%mgJ^1&#V&!3ng(pl|sh_Svi+SBQCb04i#d?PO$%u|p(O zG$LRIUx6k_$p9b)s|p;Aa5>i)A-2lI+y8d)lX+KoTwKayA#xK z-y+0Sa;8tB*#khG2VIyC?s7Gs%qh4-Bgp7S*n@Jt@ zzo|aL(l_U9HO$N)9ebd`{vDtHL@|ek4D6w*5dcE4lvb}90pJPgCTHUMFT)PX3Y_nY ziQa<{KqV548X2W164I9h0x{utubR?1ng&P@LLG18c;ESu7jwM zBXU3pf@!AA$PN%8Mo>j0tILcfg2= zw4BKbiL)By>WMJDPl?)UtV)P#28u*TOd^^Z=?zx8qFpNFVFVcDF;I#|9?>~T`AVYx z_z00aVJ2XMWkQ_h=wZ&;ts0$71clF0e9F^AKy(aX+a_3rXnVbGpT7gJT;hZNA($_6qLhRgvpW+3 zfk;GM{s{?FPWDOuJn9@0f_Ltup_&0-CVl_su7__uFB(ivp;P_tnf@iBsSR^hqj%~mmpdUy(Wz*wUJB>Bn_?5BxWdz zT<{8FZIaY6JI{ttR7Fyn&s!{AS%ILL1a`%lM=!nkt=Fc@<$v&>{^!5@>;L@SZ@pGC ziK@h;qU%DTl7TjDJ*dGKq7o$r!owIE(b=L^ zq&7xJ(6u3@w3xRk3MTupPdtBF!aw?#Ux`FqGDsTL_0EMea?u>Fb0>WUzWF`;8j*|n!=jK$csL6KMip>&5W+`B92VBq|CKn0;92+_2Y zE7xb&k77W6r0DANX?-nRc&vKjT(#z5bLm0@yRZS8L6)f_LFzP<$($p0 z1ORpAmUoX|+h2}H=QnF6!m^~K_SGBBjhR~EO@+wV$za__u)8xkJPN}zW&gkuNMPT- z+029LxUh+jNwzoi{f||Hf?nT?pSu-jiAM-)YwqHPCp5!8EsOnn>w)v&{+_>DPkZ-R)%nYp1yi@_Io$mFW>5}?qS>Hz&@E{^UfT=2vIw5Y(o7b zJVOR-^*vY*>L)cqp-N#u%ccLDKmV>{{Hx!6X1bX7{6j+O4Zz^MLj)#D`A{}j$PtN* z^P$rN-TIY`0*I)K2>`0nEn`vw$tXNAS9%c(F#s8jD|9~1mp}mQh;caP>KF{7D~Hu~ zeblxoCLENh3;9XnoqhL1V~-#TL9MLlAlNH+bhk?v*3hr4CoBD9zvj#4$yKxM4;g%N z)C&;F^3Uaf9o?M<^k8i2NtGlAn!%uQSdBm|hIswByM7RV_3L}UN7ay?Jm){WU4Gv~ z>+gGHbTCi<;;VQ5`RjW}#|&!|dT3yPmh!0{0rmbA$b!uk3e#c)Gl2NeMpb)Utg^;- zvYlHoGyCg=O-0x_>`C7}s&b`U=u2>j)P|JAin0*1D5(i4<;651IgZ`JG(u4zv4Mg^ zRFUZ(4Yyu<@819GpMBx(;gUvd1ZEDZ5iE|;GnOogs_nCnJaPH{y~V%r-Ot=ybgzD9 z0vf5k4f9!+j?gW|c-hi4x1gy0|xO)HgwdSddo1?=! z@7+H*gn@ni>fJ{lId|?%;gRS23mUmc&kX*}AAV}BcFw>Ec;Mf?)_w7f!!X7x@9b`$ z8{Lzz)P+J9rpL9Torfl8x2g|+=zTVwl~g`=Y5V7X?JFS=4A$qzF&)d+rLED0$6k2x z#b5X*|7dyRwXKPBMUd8t0d=j;Tby?kk^->;bfSn*c{Wn=EFCH$AcP z$iE%0s%7biRWTlUGeSV`xhUDplHg+50g-6xNiVtAiIhZLN7$PPyQ%x2CKw}OQ z*vav~g00N2NQGNrb`Ze8IW-Ld^TGw$yRtN~)OC5qxiYl$d4Rt3V5vWR27#oK+Efgw z9y5}4^Vlv73A(0(h)j@LtJe|Cq)TPx2#JlC3%GYH&8NzQ%K)*n!34={{VbqCYQcFp za~XycSWMySx8UwAlcT&-M(aVUcA|tgv=cQpGG@GJZ-HLz`FmxLekZ3n|C^lnl^*O1 zJun_3{0_9O*vb>%uVPo{sCFt5lk@zrO@Ry7E|RGbXi<=w6$K(;J8cx%k^(4r4*(F= zvenYEW6>ZpeGz~O+SD!B3PSUM7Fvsq)FWcf#zi29(rI@3S~5jNL|>4qk^y;2K}`S* zE$C_6$RWt8Nt7pxc|4JQXZazGij0s93CN+HOpdZVybp}5CT`SYqfZ=gr=Ivs8qWDI zfRkscs6jGhAcq;OgG828#SkzhQ&BD;C8!2S4APk^Ko#4@x+U;BRL;f&IG$NlFgjg# ztYTRR+I!bl{{aonRDr1%8uc&ui7bpP*E7{D2a`^?KmD{tPxCdaHqsx4F8BXMANYV( z5(ihUL$p4jma}7dD@Z4mX0jX%N($T$dypN(*ng&z^qr(WB8V&OA@;qt-t2ZV5bVGI_7nSyh9uxtP@*`&!9PmkniPnp4&NC+`nIRsNk z5llgo)dOS)P=e&ntXf$jkvV|D5ElzeqOQmlT*&$-B6JMQCec*-R8iMiWYAU^ir1bz&E2T49Lrqo; z9D`~?a1>fG)w*^nfU0!~rVs_xoCvlZMuBD_W}wNy&@qD=A&_@q3TUpRqQKI_aBM-6 z28_aS0hnx1u|z|Ih68juP4f@6qf?U(boT*6`oT_-650B5`x5&^R2 z1|9pDR78=ia(dycJ@rU(43D07%i!$g%& zY=qJ!4{>X=EbBs2*L4|Z0SLV+r5}oVQc(kSo;4~VYu3qt0$_|igQ|C>WlNrD28bG* zmNALY5Y)8iSeZHJtS3aEtsYRlt{``y#qtAGC7A+pZqkAoq?Eu+MUaT7f8ytw)Jjrm z3MM(Id!pfE%K955v}Czn3}%w7p8@F!N|P{`aMjcV5uIm^f|OOhmZBhV_KxM#oYIq- zrD%+lxu;Bk&PmExX;1@;x&m)o9we(mU*9`%&zU*oqF@n0BuxUK>^MdNAQQ-*ED<#Y zpV9vaVkjb6#0jcIoS!pEv@fefF@UxUgy=lSki7T4;N`MSNm9%eT8Q(;Img~FW{VU9 zGlfoa5~^7SL}Sq1y;&x^BXQFTGclv~j%q{$QC%zol50gNni`UarfC7So6TSS?cYtY z{crx(f4RO{{q_I&uM~qib)BiP!x$3+5mP&xZ>;Tn_(R|I#ozyo4c(2a@4or!JB#DS zl0XLudh0r#5O&lS!SRFr(%;lm(Q7 zdU|8`v!D6OfA&{@VlmfYiLc*mUcGX3{@jL%X(tuodchagi>8%>g@%CI!A3bK49^ew z6VILd?Au587U}ZkYWIFOYo#6yXHEOct;KQLdv0TRW?YI;g=S!_ZEUaq z)W;t~wV(Z!*Ny^K#o*HO55N48N1;uAV*}mY>9TbSKm5VVW^lMn7q%xK*l@RZ=U3mp zZ7Je>!Ga(jt>AH$7Lfvd^g~Z?PJEi{+t-g~M{#`zsH*PYnI3fb@Y!+sDs@19FhGws z6)dD0_;N^ZU7cfcKl>Zak?lv0*zj%py8=vEO(DgM}8~)lK>@VGDv7dG} z)7fgUzmVT~Yk6nJYeQNb#j|7Esx#?7HU341``F- zLFsfjxVG2+(%0_&&O6gLZ>QzlsjIZCuqbI@beV~ zqiHnusg1H|-TFX}yKy1!J3BCgy@j-$T-Yq`&g89I;r>x5&sX_KK1!~l8)0s=W$F`V z@!$!qvPW?pjdSB^>^*- zZ_NHlHGgQk+&gZj$B8%AXs19>Olk-~Y=(-EExA2{q7Su`8EF^52*oaJ4f*7lxVM#= zs^o*B{Pg4%!P@fo_8k<4)hS5dN`bZwF^Y&aF?30nZ3L#!bV<}3bc+Ru069wukgW|| zn;aZ~+0^Kbpc&zz)3(~)u69P#w~pm_hD7KmKl1U9{^X}V`1&{QK6!TYtv|R9se-ji z_Lh6s4}a(fpC-fWSC1ZkalM<{^sxQ@mv=VSivRoH`W3x(7it7RYdYM5`OQ0@{r$H; z`A43*_{^Etes9lj7w=x%f9=g%AAIKGe7Eh8ZeO2Ya>aJ-tCFVEL|{7PPrttVg*WcO z&_n5OzqNa7an#MG;JUQ04f>FzG#Ly3yMOABtPO04{CB;udpteb+xx&z|HSR< zw{Cpp%C|P(dj0diQ4UMO5W0kpnuyaSgp^&K8I*yUj+NA=$Bk*(HIW^)T~bkImXuES zH)feMvQ`(9LG2M{Z4f31(Zqp46evBJTH8tx?L<>jP%D^H6k=@0YP0;&I;jJqg5Sl>Mn7huJrLr^C zo?Jl=P4dOYnNXI?gO-J01djRMUi$qn$|ILxxddR;gl)9t(n3gtSk)9e4N=WdMVUN1 z2db%SGq(s=5w@HZ!J=5T8%0I)tw|+|5s{FPJOHZ(jj129WbpF?+*ky3=+NTI7_U7s zfE7&DqDco_fUhttOe0h^c(!VQZD+TyN9%A9&DWD90IN4^(U$(1T{lNG3ZgHxY8l!*v|@En}-^PtJF#F>p=lP&0h-*nAt=% zrc7@^w`x}*06Vh>;vT&W7XeX2>Xt}Dbe>ZTOvE0Fnux%cX0Zh`iBeQ4-cDG`+5>tRk&&2)sjq4ysF3yQ0~7&M$+;jDd%$e=K>p6`JKjgDgpr+?%T6*- z1g`9}JY@l82>|F^FY-bIcKt{yGl~0*9f9{i4hX*f>NhROck6*^kAm3HSesfLCsQvqQIg6jbH}E z5E2-}Vrgp=EJ{cT(To@uGjkr8!6CR@a|1wzB>g1aIU<5?DM%1HKn6n;v!(?TU;=h1 z1}c{2HT^*!QKtE9Y=9vw=g=ic(b$nnk6i)-CL#jGo_c18lCeI)9D`$1AXAG10F;1Y zPz20(6GIF@zLUE0;|U#4K?GN;Ycl{-lxR6*8v}`=%+NQwHpcM;>op7>VsLF|hO}H* zQE&FC%j6!aZ8S-g3QPShACpx`GegQS|q^Ab6ply?TM5e66$cs zj>TNJ41T%PvZAtfCWc5ELxTv)TsS$uliVe8rH00kcs>WPSQfIr>E_1}0)|L!gNvym zQH-il4M;j!wop{W&egS9O!x1J8BEro_HpNoZa6IB)MbrY7)YNvr20D`Jydu~7KFaU!I0I}TXdeAD zBLO?#VM?G;RsehiiIUM103;&0_uQkS)m-76cU%%GwrwC!8JW+BgqVVgkOUzlpnSf7 z-myec6I)ffbLYZVV5S_}lB9&BW@3iUi2;hmn9PjWnSqLtV`H4o8YcFI(fjZGsXGt9s*0a_lv*yudBKe1<@Rf zH3L!+BqJm>`4d0=lYi+?{_vaczVYin`*U*n;bpTJkKH0fX@ew*L3}kDjkn5z{>b|u z{i}cBr+)2oZ*6Z6>zZTGGwbEnw%=KISU4_69v80i#h~uA_{x=c{@365=8t{%bFJV$ zP&FA1*6ZfD3qgvCFRt14h}jt@8jbu8;MV%&`ptv?>C@LA8V~;D_gwh7-@pFoI;|I@ zWs??$JRS$-_olI3%s=&kwe3-Pf4^C@QUi#uj*jEi-DP6FbMKxI?j0{W!{t0xPXEI{ z{n2-R`I?7e zoH_U6i`Cj_l4W9-CB$v zJ%9i9p~T>vo>?0&TmQA!?tJWn7j<`0om(>nPkjEN$+H)$XD<(5f9Locx0>~>%9pMi zrQvXxM5|#H6LsWYySjLMt2n>z&N;5%$5-yg4XVzq@pnB{Kek30Nt-g|5HM(VJfH-a zcDA_wIyShqgKKmp9+xoUmjUfT`t zPRW(Ns99Cdk9pv7G7ymZlaFjthm!>quHFDl{hZn$=PWbB3k*~R5eDP&&Exbpe)FB5 z|H`!MJeNen8aF+1f#8h#PVfq(=+S6E%O84r%wLWEGr%qn4DJg2fIv_0&ZCtRFKU#u+9%~u4A|-8ftX3nGO>XjHG)^~wFwJUK<7

vNB+ZTR)rdc7`vY`Pbp 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 J@na9 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 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/branding/logo-rdw-oficial.png b/CORE/Source/Includes/HTMLEditor/editor/branding/logo-rdw-oficial.png new file mode 100644 index 0000000000000000000000000000000000000000..b88fc2b6f41ad319aa4bc5dabcec15ac6ca829b0 GIT binary patch literal 263172 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%0DQV$!BiDJlXR;o)BXT_YjC|Be)v>w8~hv?@sH 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

2iMkG|UqKsMkkV@FcEr!9IT};-pPk$=-SQWhj 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 G67@e2e(l!) literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/branding/rdw.jpg b/CORE/Source/Includes/HTMLEditor/editor/branding/rdw.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3cab0a5e771c01965dc8d7c80347a816bf6adc62 GIT binary patch literal 12076 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 +Icon=icons/button.bmp +Enabled=1 +Order=1 + +Icon: +- relative to libs/editor +- 24x24 bitmap +- shown alone in the palette button +- component Name is shown as the Hint + +To add a new visual HTML component: +1. create its 24x24 icon in libs/editor/icons +2. create its class definition .ini here +3. restart/reopen the PageProducer designer + +No source-code registration is required for components defined here. diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/accordion.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/accordion.ini new file mode 100644 index 000000000..fa88bcbd1 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/accordion.ini @@ -0,0 +1,8 @@ +[Component] +Name = Accordion +Category = Interactive +HTML =

+Icon = icons/accordion.bmp +Enabled = 1 +Order = 70 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/alert_danger.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/alert_danger.ini new file mode 100644 index 000000000..c9e24b141 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/alert_danger.ini @@ -0,0 +1,8 @@ +[Component] +Name = Alert Danger +Category = Feedback +HTML =
Error message
+Icon = icons/alert_danger.bmp +Enabled = 1 +Order = 67 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/alert_primary.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/alert_primary.ini new file mode 100644 index 000000000..0efcfa629 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/alert_primary.ini @@ -0,0 +1,8 @@ +[Component] +Name = Alert Primary +Category = Feedback +HTML =
Information message
+Icon = icons/alert_primary.bmp +Enabled = 1 +Order = 65 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/alert_success.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/alert_success.ini new file mode 100644 index 000000000..54525a2ab --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/alert_success.ini @@ -0,0 +1,8 @@ +[Component] +Name = Alert Success +Category = Feedback +HTML =
Success message
+Icon = icons/alert_success.bmp +Enabled = 1 +Order = 66 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/badge.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/badge.ini new file mode 100644 index 000000000..99a9190f6 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/badge.ini @@ -0,0 +1,8 @@ +[Component] +Name = Badge +Category = Content +HTML = Badge +Icon = icons/badge.bmp +Enabled = 1 +Order = 19 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/bordered_table.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/bordered_table.ini new file mode 100644 index 000000000..8e196c89d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/bordered_table.ini @@ -0,0 +1,8 @@ +[Component] +Name = Bordered Table +Category = Data +HTML =
IDName
1Item
+Icon = icons/bordered_table.bmp +Enabled = 1 +Order = 77 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/breadcrumb.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/breadcrumb.ini new file mode 100644 index 000000000..3ad0011fe --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/breadcrumb.ini @@ -0,0 +1,8 @@ +[Component] +Name = Breadcrumb +Category = Navigation +HTML = +Icon = icons/breadcrumb.bmp +Enabled = 1 +Order = 24 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/button_group.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/button_group.ini new file mode 100644 index 000000000..50b342a3b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/button_group.ini @@ -0,0 +1,8 @@ +[Component] +Name = Button Group +Category = Buttons +HTML =
+Icon = icons/button_group.bmp +Enabled = 1 +Order = 63 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/card.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/card.ini new file mode 100644 index 000000000..b2c26823e --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/card.ini @@ -0,0 +1,8 @@ +[Component] +Name = Card +Category = Content +HTML =
Card
Card body
+Icon = icons/card.bmp +Enabled = 1 +Order = 16 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/card_with_footer.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/card_with_footer.ini new file mode 100644 index 000000000..f434b4666 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/card_with_footer.ini @@ -0,0 +1,8 @@ +[Component] +Name = Card With Footer +Category = Content +HTML =
Header
Body
+Icon = icons/card_with_footer.bmp +Enabled = 1 +Order = 17 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/chart_bar.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/chart_bar.ini new file mode 100644 index 000000000..28111ae98 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/chart_bar.ini @@ -0,0 +1,8 @@ +[Component] +Name = Chart Bar +Category = Dashboard +HTML = +Icon = icons/chart_bar.bmp +Enabled = 1 +Order = 82 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/chart_line.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/chart_line.ini new file mode 100644 index 000000000..2983a300a --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/chart_line.ini @@ -0,0 +1,8 @@ +[Component] +Name = Chart Line +Category = Dashboard +HTML = +Icon = icons/chart_line.bmp +Enabled = 1 +Order = 83 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/chart_pie.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/chart_pie.ini new file mode 100644 index 000000000..c491b9478 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/chart_pie.ini @@ -0,0 +1,8 @@ +[Component] +Name = Chart Pie +Category = Dashboard +HTML = +Icon = icons/chart_pie.bmp +Enabled = 1 +Order = 84 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/checkbox.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/checkbox.ini new file mode 100644 index 000000000..f394ced6f --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/checkbox.ini @@ -0,0 +1,8 @@ +[Component] +Name = Checkbox +Category = Forms +HTML =
+Icon = icons/checkbox.bmp +Enabled = 1 +Order = 43 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/collapse.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/collapse.ini new file mode 100644 index 000000000..ea08e4d9a --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/collapse.ini @@ -0,0 +1,8 @@ +[Component] +Name = Collapse +Category = Interactive +HTML =
Collapsed content
+Icon = icons/collapse.bmp +Enabled = 1 +Order = 71 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/color_picker.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/color_picker.ini new file mode 100644 index 000000000..dcb2544dc --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/color_picker.ini @@ -0,0 +1,8 @@ +[Component] +Name = Color Picker +Category = Forms +HTML =
+Icon = icons/color_picker.bmp +Enabled = 1 +Order = 39 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/columns_3_9.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/columns_3_9.ini new file mode 100644 index 000000000..e52be56a4 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/columns_3_9.ini @@ -0,0 +1,8 @@ +[Component] +Name = Columns 3 + 9 +Category = Layout +HTML =
Sidebar
Content
+Icon = icons/columns_3_9.bmp +Enabled = 1 +Order = 6 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/columns_4_4_4.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/columns_4_4_4.ini new file mode 100644 index 000000000..81c38e42d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/columns_4_4_4.ini @@ -0,0 +1,8 @@ +[Component] +Name = Columns 4 + 4 + 4 +Category = Layout +HTML =
One
Two
Three
+Icon = icons/columns_4_4_4.bmp +Enabled = 1 +Order = 5 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/columns_6_6.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/columns_6_6.ini new file mode 100644 index 000000000..b8d9ef79b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/columns_6_6.ini @@ -0,0 +1,8 @@ +[Component] +Name = Columns 6 + 6 +Category = Layout +HTML =
Left
Right
+Icon = icons/columns_6_6.bmp +Enabled = 1 +Order = 4 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/container.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/container.ini new file mode 100644 index 000000000..8e95586d1 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/container.ini @@ -0,0 +1,8 @@ +[Component] +Name = Container +Category = Layout +HTML =
Container
+Icon = icons/container.bmp +Enabled = 1 +Order = 1 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/container_fluid.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/container_fluid.ini new file mode 100644 index 000000000..235944599 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/container_fluid.ini @@ -0,0 +1,8 @@ +[Component] +Name = Container Fluid +Category = Layout +HTML =
Container Fluid
+Icon = icons/container_fluid.bmp +Enabled = 1 +Order = 2 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/crud_toolbar.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/crud_toolbar.ini new file mode 100644 index 000000000..1c8393b46 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/crud_toolbar.ini @@ -0,0 +1,8 @@ +[Component] +Name = CRUD Toolbar +Category = Buttons +HTML =
+Icon = icons/crud_toolbar.bmp +Enabled = 1 +Order = 64 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/danger.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/danger.ini new file mode 100644 index 000000000..286025ec3 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/danger.ini @@ -0,0 +1,8 @@ +[Component] +Name = Danger +Category = Buttons +HTML = +Icon = icons/danger.bmp +Enabled = 1 +Order = 54 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/dark.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/dark.ini new file mode 100644 index 000000000..67c293ac5 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/dark.ini @@ -0,0 +1,8 @@ +[Component] +Name = Dark +Category = Buttons +HTML = +Icon = icons/dark.bmp +Enabled = 1 +Order = 58 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/dashboard_grid.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/dashboard_grid.ini new file mode 100644 index 000000000..123206924 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/dashboard_grid.ini @@ -0,0 +1,8 @@ +[Component] +Name = Dashboard Grid +Category = Dashboard +HTML =
KPI 1
KPI 2
+Icon = icons/dashboard_grid.bmp +Enabled = 1 +Order = 85 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/datatable.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/datatable.ini new file mode 100644 index 000000000..383e7b9d6 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/datatable.ini @@ -0,0 +1,8 @@ +[Component] +Name = DataTable +Category = Data +HTML =
NameValue
Item A100
Item B200
+Icon = icons/datatable.bmp +Enabled = 1 +Order = 78 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/datatable_crud.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/datatable_crud.ini new file mode 100644 index 000000000..882bf7e8b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/datatable_crud.ini @@ -0,0 +1,8 @@ +[Component] +Name = DataTable CRUD +Category = Data +HTML =
IDNameStatus
1RecordActive
+Icon = icons/datatable_crud.bmp +Enabled = 1 +Order = 79 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/date_picker.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/date_picker.ini new file mode 100644 index 000000000..2b34554c5 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/date_picker.ini @@ -0,0 +1,8 @@ +[Component] +Name = Date Picker +Category = Forms +HTML =
+Icon = icons/date_picker.bmp +Enabled = 1 +Order = 34 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/datetime_picker.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/datetime_picker.ini new file mode 100644 index 000000000..22d7af038 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/datetime_picker.ini @@ -0,0 +1,8 @@ +[Component] +Name = DateTime Picker +Category = Forms +HTML =
+Icon = icons/datetime_picker.bmp +Enabled = 1 +Order = 36 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/decimal_edit.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/decimal_edit.ini new file mode 100644 index 000000000..e8adf6cd2 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/decimal_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Decimal Edit +Category = Forms +HTML =
+Icon = icons/decimal_edit.bmp +Enabled = 1 +Order = 31 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/disabled_edit.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/disabled_edit.ini new file mode 100644 index 000000000..fe458ae79 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/disabled_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Disabled Edit +Category = Forms +HTML =
+Icon = icons/disabled_edit.bmp +Enabled = 1 +Order = 50 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/dropdown.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/dropdown.ini new file mode 100644 index 000000000..5ac57122e --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/dropdown.ini @@ -0,0 +1,8 @@ +[Component] +Name = Dropdown +Category = Interactive +HTML =
+Icon = icons/dropdown.bmp +Enabled = 1 +Order = 72 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/email_edit.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/email_edit.ini new file mode 100644 index 000000000..484cfdbaa --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/email_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Email Edit +Category = Forms +HTML =
+Icon = icons/email_edit.bmp +Enabled = 1 +Order = 28 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/file_upload.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/file_upload.ini new file mode 100644 index 000000000..c1d987e0a --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/file_upload.ini @@ -0,0 +1,8 @@ +[Component] +Name = File Upload +Category = Forms +HTML =
+Icon = icons/file_upload.bmp +Enabled = 1 +Order = 47 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/flex_row.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/flex_row.ini new file mode 100644 index 000000000..cfc8258eb --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/flex_row.ini @@ -0,0 +1,8 @@ +[Component] +Name = Flex Row +Category = Layout +HTML =
Item 1
Item 2
+Icon = icons/flex_row.bmp +Enabled = 1 +Order = 7 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/grid.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/grid.ini new file mode 100644 index 000000000..ee700c110 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/grid.ini @@ -0,0 +1,8 @@ +[Component] +Name = Grid +Category = Layout +HTML =
Item 1
Item 2
+Icon = icons/grid.bmp +Enabled = 1 +Order = 8 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/heading_h1.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/heading_h1.ini new file mode 100644 index 000000000..63cb8f33a --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/heading_h1.ini @@ -0,0 +1,8 @@ +[Component] +Name = Heading H1 +Category = Content +HTML =

Heading H1

+Icon = icons/heading_h1.bmp +Enabled = 1 +Order = 9 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/heading_h2.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/heading_h2.ini new file mode 100644 index 000000000..7c73431c0 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/heading_h2.ini @@ -0,0 +1,8 @@ +[Component] +Name = Heading H2 +Category = Content +HTML =

Heading H2

+Icon = icons/heading_h2.bmp +Enabled = 1 +Order = 10 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/heading_h3.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/heading_h3.ini new file mode 100644 index 000000000..7566e06e5 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/heading_h3.ini @@ -0,0 +1,8 @@ +[Component] +Name = Heading H3 +Category = Content +HTML =

Heading H3

+Icon = icons/heading_h3.bmp +Enabled = 1 +Order = 11 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/horizontal_rule.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/horizontal_rule.ini new file mode 100644 index 000000000..f709540cf --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/horizontal_rule.ini @@ -0,0 +1,8 @@ +[Component] +Name = Horizontal Rule +Category = Content +HTML =
+Icon = icons/horizontal_rule.bmp +Enabled = 1 +Order = 20 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/image.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/image.ini new file mode 100644 index 000000000..cb921d19a --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/image.ini @@ -0,0 +1,8 @@ +[Component] +Name = Image +Category = Content +HTML = Image +Icon = icons/image.bmp +Enabled = 1 +Order = 15 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/info.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/info.ini new file mode 100644 index 000000000..f45b32fef --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/info.ini @@ -0,0 +1,8 @@ +[Component] +Name = Info +Category = Buttons +HTML = +Icon = icons/info.bmp +Enabled = 1 +Order = 56 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/input_group.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/input_group.ini new file mode 100644 index 000000000..12cc8df74 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/input_group.ini @@ -0,0 +1,8 @@ +[Component] +Name = Input Group +Category = Forms +HTML =
@
+Icon = icons/input_group.bmp +Enabled = 1 +Order = 48 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/kpi_card.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/kpi_card.ini new file mode 100644 index 000000000..e23f82ad5 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/kpi_card.ini @@ -0,0 +1,8 @@ +[Component] +Name = KPI Card +Category = Dashboard +HTML =
Revenue

R$ 0,00

Current month
+Icon = icons/kpi_card.bmp +Enabled = 1 +Order = 80 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/kpi_cards_4.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/kpi_cards_4.ini new file mode 100644 index 000000000..e08af505c --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/kpi_cards_4.ini @@ -0,0 +1,8 @@ +[Component] +Name = KPI Cards 4 +Category = Dashboard +HTML =
Revenue

R$ 125K

Orders

1.284

Clients

842

Conversion

18.4%

+Icon = icons/kpi_cards_4.bmp +Enabled = 1 +Order = 81 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/large_button.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/large_button.ini new file mode 100644 index 000000000..89fcd7334 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/large_button.ini @@ -0,0 +1,8 @@ +[Component] +Name = Large Button +Category = Buttons +HTML = +Icon = icons/large_button.bmp +Enabled = 1 +Order = 62 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/lead_text.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/lead_text.ini new file mode 100644 index 000000000..7acb1e8fd --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/lead_text.ini @@ -0,0 +1,8 @@ +[Component] +Name = Lead Text +Category = Content +HTML =

Lead paragraph

+Icon = icons/lead_text.bmp +Enabled = 1 +Order = 14 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/light.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/light.ini new file mode 100644 index 000000000..6dbf96683 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/light.ini @@ -0,0 +1,8 @@ +[Component] +Name = Light +Category = Buttons +HTML = +Icon = icons/light.bmp +Enabled = 1 +Order = 57 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/link.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/link.ini new file mode 100644 index 000000000..c4fc2b683 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/link.ini @@ -0,0 +1,8 @@ +[Component] +Name = Link +Category = Buttons +HTML = +Icon = icons/link.bmp +Enabled = 1 +Order = 59 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/list_group.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/list_group.ini new file mode 100644 index 000000000..711e22345 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/list_group.ini @@ -0,0 +1,8 @@ +[Component] +Name = List Group +Category = Content +HTML =
  • Item 1
  • Item 2
+Icon = icons/list_group.bmp +Enabled = 1 +Order = 18 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/modal.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/modal.ini new file mode 100644 index 000000000..efdaf8f16 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/modal.ini @@ -0,0 +1,8 @@ +[Component] +Name = Modal +Category = Interactive +HTML = +Icon = icons/modal.bmp +Enabled = 1 +Order = 73 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/money_edit.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/money_edit.ini new file mode 100644 index 000000000..b20fc5ccc --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/money_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Money Edit +Category = Forms +HTML =
R$
+Icon = icons/money_edit.bmp +Enabled = 1 +Order = 32 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/month_picker.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/month_picker.ini new file mode 100644 index 000000000..a0fc2d45c --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/month_picker.ini @@ -0,0 +1,8 @@ +[Component] +Name = Month Picker +Category = Forms +HTML =
+Icon = icons/month_picker.bmp +Enabled = 1 +Order = 37 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/multi_select.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/multi_select.ini new file mode 100644 index 000000000..552120505 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/multi_select.ini @@ -0,0 +1,8 @@ +[Component] +Name = Multi Select +Category = Forms +HTML =
+Icon = icons/multi_select.bmp +Enabled = 1 +Order = 42 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/nav_pills.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/nav_pills.ini new file mode 100644 index 000000000..0e34c0851 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/nav_pills.ini @@ -0,0 +1,8 @@ +[Component] +Name = Nav Pills +Category = Navigation +HTML = +Icon = icons/nav_pills.bmp +Enabled = 1 +Order = 22 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/nav_tabs.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/nav_tabs.ini new file mode 100644 index 000000000..34fdb38f6 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/nav_tabs.ini @@ -0,0 +1,8 @@ +[Component] +Name = Nav Tabs +Category = Navigation +HTML = +Icon = icons/nav_tabs.bmp +Enabled = 1 +Order = 23 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/navbar.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/navbar.ini new file mode 100644 index 000000000..a462ba9e9 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/navbar.ini @@ -0,0 +1,8 @@ +[Component] +Name = Navbar +Category = Navigation +HTML = +Icon = icons/navbar.bmp +Enabled = 1 +Order = 21 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/number_edit.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/number_edit.ini new file mode 100644 index 000000000..bb788a207 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/number_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Number Edit +Category = Forms +HTML =
+Icon = icons/number_edit.bmp +Enabled = 1 +Order = 30 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/offcanvas.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/offcanvas.ini new file mode 100644 index 000000000..870d9bb14 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/offcanvas.ini @@ -0,0 +1,8 @@ +[Component] +Name = Offcanvas +Category = Interactive +HTML =
Offcanvas content
+Icon = icons/offcanvas.bmp +Enabled = 1 +Order = 74 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/outline_primary.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/outline_primary.ini new file mode 100644 index 000000000..ea2d1922b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/outline_primary.ini @@ -0,0 +1,8 @@ +[Component] +Name = Outline Primary +Category = Buttons +HTML = +Icon = icons/outline_primary.bmp +Enabled = 1 +Order = 60 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/pagination.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/pagination.ini new file mode 100644 index 000000000..bdd8dfa00 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/pagination.ini @@ -0,0 +1,8 @@ +[Component] +Name = Pagination +Category = Navigation +HTML = +Icon = icons/pagination.bmp +Enabled = 1 +Order = 25 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/paragraph.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/paragraph.ini new file mode 100644 index 000000000..28f63879e --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/paragraph.ini @@ -0,0 +1,8 @@ +[Component] +Name = Paragraph +Category = Content +HTML =

Paragraph text

+Icon = icons/paragraph.bmp +Enabled = 1 +Order = 12 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/password_edit.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/password_edit.ini new file mode 100644 index 000000000..d341b2730 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/password_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Password Edit +Category = Forms +HTML =
+Icon = icons/password_edit.bmp +Enabled = 1 +Order = 27 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/percent_edit.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/percent_edit.ini new file mode 100644 index 000000000..7464ca5db --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/percent_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Percent Edit +Category = Forms +HTML =
%
+Icon = icons/percent_edit.bmp +Enabled = 1 +Order = 33 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/primary.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/primary.ini new file mode 100644 index 000000000..9639472bb --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/primary.ini @@ -0,0 +1,8 @@ +[Component] +Name = Primary +Category = Buttons +HTML = +Icon = icons/primary.bmp +Enabled = 1 +Order = 51 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/progress.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/progress.ini new file mode 100644 index 000000000..e7cb58495 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/progress.ini @@ -0,0 +1,8 @@ +[Component] +Name = Progress +Category = Feedback +HTML =
+Icon = icons/progress.bmp +Enabled = 1 +Order = 68 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/radio_group.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/radio_group.ini new file mode 100644 index 000000000..2b68c2482 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/radio_group.ini @@ -0,0 +1,8 @@ +[Component] +Name = Radio Group +Category = Forms +HTML =
+Icon = icons/radio_group.bmp +Enabled = 1 +Order = 45 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/range.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/range.ini new file mode 100644 index 000000000..a1f803821 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/range.ini @@ -0,0 +1,8 @@ +[Component] +Name = Range +Category = Forms +HTML =
+Icon = icons/range.bmp +Enabled = 1 +Order = 46 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/readonly_edit.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/readonly_edit.ini new file mode 100644 index 000000000..096e09a0a --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/readonly_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Readonly Edit +Category = Forms +HTML =
+Icon = icons/readonly_edit.bmp +Enabled = 1 +Order = 49 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/row.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/row.ini new file mode 100644 index 000000000..d3930a5ff --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/row.ini @@ -0,0 +1,8 @@ +[Component] +Name = Row +Category = Layout +HTML =
Column
+Icon = icons/row.bmp +Enabled = 1 +Order = 3 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/search_edit.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/search_edit.ini new file mode 100644 index 000000000..c80f9c11a --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/search_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Search Edit +Category = Forms +HTML =
+Icon = icons/search_edit.bmp +Enabled = 1 +Order = 29 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/secondary.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/secondary.ini new file mode 100644 index 000000000..e7c19fafc --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/secondary.ini @@ -0,0 +1,8 @@ +[Component] +Name = Secondary +Category = Buttons +HTML = +Icon = icons/secondary.bmp +Enabled = 1 +Order = 52 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/select.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/select.ini new file mode 100644 index 000000000..c55b39352 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/select.ini @@ -0,0 +1,8 @@ +[Component] +Name = Select +Category = Forms +HTML =
+Icon = icons/select.bmp +Enabled = 1 +Order = 41 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/small_button.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/small_button.ini new file mode 100644 index 000000000..2f7f85d9b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/small_button.ini @@ -0,0 +1,8 @@ +[Component] +Name = Small Button +Category = Buttons +HTML = +Icon = icons/small_button.bmp +Enabled = 1 +Order = 61 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/small_text.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/small_text.ini new file mode 100644 index 000000000..54fe32a62 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/small_text.ini @@ -0,0 +1,8 @@ +[Component] +Name = Small Text +Category = Content +HTML = Small text +Icon = icons/small_text.bmp +Enabled = 1 +Order = 13 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/spinner.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/spinner.ini new file mode 100644 index 000000000..b57613c6e --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/spinner.ini @@ -0,0 +1,8 @@ +[Component] +Name = Spinner +Category = Feedback +HTML = +Icon = icons/spinner.bmp +Enabled = 1 +Order = 69 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_button.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_button.ini new file mode 100644 index 000000000..61bfd632d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_button.ini @@ -0,0 +1,7 @@ +[Component] +Name = Button +Category = Standard +HTML = +Icon = icons/standard_button.bmp +Enabled = 1 +Order = 4 diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_checkbox.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_checkbox.ini new file mode 100644 index 000000000..ddf988edc --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_checkbox.ini @@ -0,0 +1,7 @@ +[Component] +Name = CheckBox +Category = Standard +HTML =
+Icon = icons/standard_checkbox.bmp +Enabled = 1 +Order = 5 diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_combobox.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_combobox.ini new file mode 100644 index 000000000..5aab7ca7d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_combobox.ini @@ -0,0 +1,7 @@ +[Component] +Name = ComboBox +Category = Standard +HTML = +Icon = icons/standard_combobox.bmp +Enabled = 1 +Order = 7 diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_edit.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_edit.ini new file mode 100644 index 000000000..7398d712d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_edit.ini @@ -0,0 +1,7 @@ +[Component] +Name = Edit +Category = Standard +HTML = +Icon = icons/standard_edit.bmp +Enabled = 1 +Order = 2 diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_grid.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_grid.ini new file mode 100644 index 000000000..1c3117e8d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_grid.ini @@ -0,0 +1,7 @@ +[Component] +Name = Grid +Category = Standard +HTML =
IDNameValue
1ItemValue
+Icon = icons/standard_grid.bmp +Enabled = 1 +Order = 9 diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_groupbox.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_groupbox.ini new file mode 100644 index 000000000..f29631ca1 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_groupbox.ini @@ -0,0 +1,7 @@ +[Component] +Name = GroupBox +Category = Standard +HTML =
GroupBoxContent
+Icon = icons/standard_groupbox.bmp +Enabled = 1 +Order = 13 diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_hidden.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_hidden.ini new file mode 100644 index 000000000..21bdcc430 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_hidden.ini @@ -0,0 +1,7 @@ +[Component] +Name = HiddenField +Category = Standard +HTML = +Icon = icons/standard_hidden.bmp +Enabled = 1 +Order = 15 diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_image.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_image.ini new file mode 100644 index 000000000..f85977542 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_image.ini @@ -0,0 +1,7 @@ +[Component] +Name = Image +Category = Standard +HTML = Image +Icon = icons/standard_image.bmp +Enabled = 1 +Order = 10 diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_label.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_label.ini new file mode 100644 index 000000000..3a3c4cd7d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_label.ini @@ -0,0 +1,7 @@ +[Component] +Name = Label +Category = Standard +HTML = +Icon = icons/standard_label.bmp +Enabled = 1 +Order = 1 diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_link.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_link.ini new file mode 100644 index 000000000..f366c99b7 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_link.ini @@ -0,0 +1,7 @@ +[Component] +Name = Link +Category = Standard +HTML = Link +Icon = icons/standard_link.bmp +Enabled = 1 +Order = 11 diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_listbox.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_listbox.ini new file mode 100644 index 000000000..9f2aebb8f --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_listbox.ini @@ -0,0 +1,7 @@ +[Component] +Name = ListBox +Category = Standard +HTML = +Icon = icons/standard_listbox.bmp +Enabled = 1 +Order = 8 diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_memo.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_memo.ini new file mode 100644 index 000000000..63320a5f8 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_memo.ini @@ -0,0 +1,7 @@ +[Component] +Name = Memo +Category = Standard +HTML = +Icon = icons/standard_memo.bmp +Enabled = 1 +Order = 3 diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_panel.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_panel.ini new file mode 100644 index 000000000..6c1d8ac7d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_panel.ini @@ -0,0 +1,7 @@ +[Component] +Name = Panel +Category = Standard +HTML =
Panel
+Icon = icons/standard_panel.bmp +Enabled = 1 +Order = 12 diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_progress.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_progress.ini new file mode 100644 index 000000000..d4ab87e17 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_progress.ini @@ -0,0 +1,7 @@ +[Component] +Name = ProgressBar +Category = Standard +HTML =
50%
+Icon = icons/standard_progress.bmp +Enabled = 1 +Order = 14 diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_radio.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_radio.ini new file mode 100644 index 000000000..60da59568 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/standard_radio.ini @@ -0,0 +1,7 @@ +[Component] +Name = RadioButton +Category = Standard +HTML =
+Icon = icons/standard_radio.bmp +Enabled = 1 +Order = 6 diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/success.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/success.ini new file mode 100644 index 000000000..489d2a57f --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/success.ini @@ -0,0 +1,8 @@ +[Component] +Name = Success +Category = Buttons +HTML = +Icon = icons/success.bmp +Enabled = 1 +Order = 53 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/switch.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/switch.ini new file mode 100644 index 000000000..00f3c46d0 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/switch.ini @@ -0,0 +1,8 @@ +[Component] +Name = Switch +Category = Forms +HTML =
+Icon = icons/switch.bmp +Enabled = 1 +Order = 44 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/table.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/table.ini new file mode 100644 index 000000000..523d3b644 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/table.ini @@ -0,0 +1,8 @@ +[Component] +Name = Table +Category = Data +HTML =
NameValue
Item100
+Icon = icons/table.bmp +Enabled = 1 +Order = 76 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/text_edit.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/text_edit.ini new file mode 100644 index 000000000..ecdd6129a --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/text_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Text Edit +Category = Forms +HTML =
+Icon = icons/text_edit.bmp +Enabled = 1 +Order = 26 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/textarea.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/textarea.ini new file mode 100644 index 000000000..54d1e3f6d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/textarea.ini @@ -0,0 +1,8 @@ +[Component] +Name = TextArea +Category = Forms +HTML =
+Icon = icons/textarea.bmp +Enabled = 1 +Order = 40 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/time_picker.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/time_picker.ini new file mode 100644 index 000000000..be04fe182 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/time_picker.ini @@ -0,0 +1,8 @@ +[Component] +Name = Time Picker +Category = Forms +HTML =
+Icon = icons/time_picker.bmp +Enabled = 1 +Order = 35 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/toast.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/toast.ini new file mode 100644 index 000000000..7d3bdbf78 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/toast.ini @@ -0,0 +1,8 @@ +[Component] +Name = Toast +Category = Interactive +HTML =
Toast notification
+Icon = icons/toast.bmp +Enabled = 1 +Order = 75 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/warning.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/warning.ini new file mode 100644 index 000000000..12cd84197 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/warning.ini @@ -0,0 +1,8 @@ +[Component] +Name = Warning +Category = Buttons +HTML = +Icon = icons/warning.bmp +Enabled = 1 +Order = 55 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/classdefs/week_picker.ini b/CORE/Source/Includes/HTMLEditor/editor/classdefs/week_picker.ini new file mode 100644 index 000000000..d6b2066a0 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/classdefs/week_picker.ini @@ -0,0 +1,8 @@ +[Component] +Name = Week Picker +Category = Forms +HTML =
+Icon = icons/week_picker.bmp +Enabled = 1 +Order = 38 + diff --git a/CORE/Source/Includes/HTMLEditor/editor/datatables/dataTables.dataTables.min.css b/CORE/Source/Includes/HTMLEditor/editor/datatables/dataTables.dataTables.min.css new file mode 100644 index 000000000..57fe56b0b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/datatables/dataTables.dataTables.min.css @@ -0,0 +1 @@ +.dt-container{width:100%}.dt-search{margin-bottom:.5rem}.dt-info{font-size:.875rem;color:#666}.dt-paging{margin-top:.5rem} \ No newline at end of file diff --git a/CORE/Source/Includes/HTMLEditor/editor/datatables/dataTables.min.js b/CORE/Source/Includes/HTMLEditor/editor/datatables/dataTables.min.js new file mode 100644 index 000000000..413d3c0a7 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/datatables/dataTables.min.js @@ -0,0 +1,2 @@ +/* LazDatasnap local DataTable lightweight runtime */ +window.DataTable=window.DataTable||function(sel,opt){this.table=typeof sel==='string'?document.querySelector(sel):sel;this.options=opt||{};if(this.table){this.table.classList.add('table','table-striped');}return this;}; \ No newline at end of file diff --git a/CORE/Source/Includes/HTMLEditor/editor/help/index.html b/CORE/Source/Includes/HTMLEditor/editor/help/index.html new file mode 100644 index 000000000..0a4bf9136 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/help/index.html @@ -0,0 +1,133 @@ + + + + + +LazDatasnap Visual Web IDE Help + + + + +
+
+

LazDatasnap Visual Web IDE

+

Complete guide to designing PageProducer pages, editing code, inspecting components, debugging JavaScript and managing projects.

+
+
+ +
+
+
+
+

Getting started

+

New creates a complete PageProducer page structure with HTML header/body and the framework hooks expected by the designer.

+

Open loads an HTML page from disk. Save is enabled only when something changed and writes the edited page back to disk.

+

The IDE asks whether to save modified content before closing or replacing a document.

+
+
+ +
+
+

Form Designer

+

The WebViewer is the visual page designer. Click an element to select it instead of navigating the page.

+

Drag components from Component Palette to insert them. Selected elements can be removed with Delete.

+

Changes made in Object Inspector are reflected in the page and in the PageProducer source.

+
+
+ +
+
+

Component Palette

+

The Standard palette comes first and contains Label, Edit, Grid and the common controls.

+

Additional component classes and plugins are scanned and exposed in their corresponding palette pages.

+

The small selector above the palette changes only the IDE layout: Classic or Dark. It never changes the rendered web page.

+
+
+ +
+
+

Object Inspector

+

Properties displays valid properties for the selected HTML/component element. Empty optional values are not emitted until a value is supplied.

+

Events lists supported events. Double-clicking an event opens the Code Editor at the existing handler or creates and binds a new handler when necessary.

+

Removing an event handler from Object Inspector removes its component reference and cleans an unused empty handler scope when possible.

+
+
+ +
+
+

Code Editor

+

Full Code combines HTML, CSS and JavaScript with syntax highlighting. The section editors are also available independently.

+

Clicking Project Explorer entries navigates to the matching source position. The tree preserves nodes you expand or collapse.

+

When an event is selected from Form Designer, Code Editor opens directly on its handler and Object Inspector remains on Events.

+
+
+ +
+
+

JavaScript debugger

+
+ + + + + + + + + + + + + +
CommandShortcutPurpose
Run / ContinueF9Start or continue JavaScript debugging.
PauseDebug menuPause the running page.
Stop ProgramCtrl+F2End the debug session.
Run to CursorF4Continue execution to the current JavaScript line.
Step IntoF7Enter the called JavaScript routine.
Step OverF8Execute the current statement without entering the call.
Step OutShift+F8Continue until the current routine returns.
Evaluate / ModifyCtrl+F7Inspect or change a variable/expression in the paused call frame.
Toggle BreakpointF5Add or remove a breakpoint on the current JavaScript line.
+
+

You can also double-click the line-number gutter to add/remove a breakpoint. When execution stops, the IDE switches to Full Code and marks the current execution line. While paused, hovering a variable evaluates it; double-click its value hint to open Evaluate/Modify.

+
+
+ +
+
+

Project Explorer

+

Shows Page Options, HTML structure, CSS, JavaScript functions, assets and components.

+

Single-click navigation opens the Code Editor on the equivalent source location without forcing the whole tree open.

+
+
+ +
+
+

Errors and request log

+

Show Errors receives designer/page JavaScript errors with source, line and column. Double-clicking an entry navigates to the related code where applicable.

+

The request log records requests. Double-click a log row to inspect request details such as headers and complete payload.

+
+
+ +
+
+

Docking and layout

+

Project Explorer, Object Inspector, Show Errors, Form Designer and Component Palette participate in the IDE layout. Dockable panels can be shown again from the View menu.

+

Panel sizes and IDE settings are persisted. Classic keeps the Lazarus-style appearance; Dark applies dark designer colors.

+
+
+ +
+
+

Page events

+

Select Page Options to access page-level properties and events. Page events can be created from Object Inspector exactly like component events.

+

The default new page contains the required HTML structure so it can run immediately in the LazDatasnap PageProducer environment.

+
+
+
+ +
+Tip: Use Form Designer for visual composition, Object Inspector for properties/events, Project Explorer for navigation, and Full Code whenever you need direct source control. +
+
+ + + diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/README.txt b/CORE/Source/Includes/HTMLEditor/editor/icons/README.txt new file mode 100644 index 000000000..6061959b3 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/editor/icons/README.txt @@ -0,0 +1,18 @@ +LazDatasnap PageProducer - Component Palette Icons + +Format: 24x24 Windows bitmap (BMP), compatible with the current palette loader. +The palette button shows only the image. The component name is displayed in Hint. + +The icon set uses semantic IDE-style pictograms rather than text/letters. +Examples: +- Email Edit: envelope +- Password Edit: padlock +- Search Edit: magnifier +- Money Edit: coins +- Percent Edit: percentage symbol constructed as vector shapes +- Date/Time controls: calendar and clock variants +- DataTable: table + search indicator +- DataTable CRUD: table + action indicator +- Chart Line/Bar/Pie: distinct chart drawings + +Class registration remains in ../classdefs/*.ini. diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/accordion.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/accordion.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b1569673b0ab0b2941df26c67d08b0bc704d7f38 GIT binary patch literal 1782 zcmbtVU2oD*7{(hfz4j;g3;Y3k?T!8zqf2yPB*w(Vi)Ec)KGk$UQ|*Fk2pNW33ouB3#KUG?U~2-)*gy@N5rV)W71r$*CpH^I zk~BrJ2_kh7fSAG}Q zsjkTKAy)?pRD~L-1w2VtfZr`iT&q)MJ2h@P*e=WOEUe0{BfYOfQmZvXp2VVG7DTf? zeP)%$U1Z*CwombJj7p4r%4_j2H(w<01rm$C8A!VPUl+Xjr7%@AO*P6HwsSEqwPy4HLaPV?#?|HP9tKiWP_JjvIn{{O#zAe3uF|k}V znwg88+g>6{RHqYkcKZAMLBdvMDBHQB>sC^4^n;xYIXY*YUZ)D>_%_s_^^zjjK)4Dm+^2HiT0;8+|u)Hu@giX12|~ zZ|+vd5Y5y+<}$uW$oV+^YCU=JcII zLLsa;-ySlP5X-0c@q6gyJ^z@i-{t9B@#rv*0wcrp57IEYES~;Po4nvY4WNLt|Qsz$jzNtsI0KBTIr}139Vnz$^)Ji^tFsQ_{O+_4FQ3S4^qMLB81K dB8|PPJzje?_Vfq5*egSj-ztYu2R(Ouv;&-%>HPoz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/alert_primary.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/alert_primary.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c46747dfdedf3047e6055661fab04f187d01acea GIT binary patch literal 1782 zcmeHEF%Ez*2&{{vvrq5^KET~SJNPD7C8ZJq*M>N%O+b3wU8P;tqfdFwlqZU@M3<|S zHtO#KM6^3vmdx z2Zs^}zT1bUYfK$^5#c}|0)@Z@q_sIL(N+-?eVk}@5jQbbEY#Wje`KrWR7WH~2j0L1 D`=W|n literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/alert_success.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/alert_success.bmp new file mode 100644 index 0000000000000000000000000000000000000000..84293557e54b4763e016529d129132e3e9c9df82 GIT binary patch literal 1782 zcmeH@I}(5(3`DW9wDt&|zysKOXA93{s~Ms@m=M5E2{VDPSzaP+(PJp2>sDKfM8Bi zK#2B56@5cU;tBj9Xmd&T5{_s=*TNy;)C4F3^==-fg{Uta9y?@WS|k=929a2POBc^^ RP58M~zJsZgUmzM=l>_K#7|#Fz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/badge.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/badge.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3abcb21394947792cd505843c8860c0f53f034af GIT binary patch literal 1782 zcmb_dUr19?99|Fg*jp3?CcV^yK~F&xm}W$w5vF@vv7m=6$h4V%k};eHYl`A{LISZdj{)LrMC+iknM|4-lD(c5xU#CG}4;oN(_?>p!BJLmpxb{@CI z5W5bb-;1_mscnjl42HLO-?x>v7!jQ!i4;VURX~>33q^)Rm(u|pI5xQGn+-720cIvJ zwP`U7PckL<5cCX(9iX;m0 z`4L5Jzxs#Wh2?1?>*oSqS4Y*vc%Kqs3AacTp2!@LqgpRGbi-XN{Lkh2}H4_0}?ErtMYr6=x2ZE7n7Oo^;hB zCwTkdr6sdyb9v)Qm1jTocHgnzxbLWIanv={Sv%TVkjU2d^3ui=i9R&0uah71O1I6= zd;wv2=(P}-C0vBa2}e{A&9;nZJq@6(hzn__C+DW?ys3K6;7E@e4n_UHBJ)#W-z3ZY zU>Q${nF#r&Jf4B-yLo2&{z#P7wnh@;^8+7j4+4)0;ieZQ`PX+ARO~WVq#G;$Mb&P+ zDr?SV7N)S6WcwcfU66$kGceZs`P;j}@xQ?B!04Nw%orRrli1ghaDJA2FomMZl(|~3 so!B+M3tg!3P@s}Qcc5f_J*lc2@JUG>Lv>9_T}@$~r&d~R{Ez?6A2;0_9RL6T literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/bordered_table.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/bordered_table.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56d0bf259b74b4d31f4bb172c02644393cf4a4d6 GIT binary patch literal 1782 zcmeHDu?@p840D%^oqIwr$N|~=lTYiAo4PiH*$RY+2JzG&hyW`RO)8Y9$7?7pM&vur z?Q<@zD&>j$`O4FXNbjS^chSDDzl!T?tqFAG*Br&6(iXKM{6!+5bzD{CE8=`|99Pv} z=Dyod;h4#*$cn7^+2I_zWyTiT TqIM)!jv`4mwjn=@^%qzGqJs@G literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/breadcrumb.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/breadcrumb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..54ae959d1db460a382c883ee06ffc9c6094a9197 GIT binary patch literal 1782 zcmd^A&rcIk5XOr~&mK*@_!sEG3u!cZP-9~BU?L_07WF`+K?Ou34Kx;Fi1A<)B4R@j z#2!@I!U3b!M5C>xibX693hnN;cDL>B+wN~?_ifj;3EG8j+S^W=qR83Pg z6?C~6MzC8_X{gSRs#uQtLDi+)qGE?iBREv^Xqr;wWgf|hvqAzYK`4j9Kv2BaKt{_Ihsb`V_t|i_+U$ z6VF=v=Gxt}c4u&4R6<22O$b~;;88IY$U&aI87R03yORmNJ zlVdhDFZx=Yh{*CJ!_)b|ITy9~m1XH7o40rtuh_Zx5)PG`x$8dA=)8I;^xB0jTw&SO zz3p<_X}@DolT^)U|Ak98sc1D%q}PsCV;0Zwk^OGh(NM6&!>(NK-9FIK5pWD?P!OX6 z3tfNU314W+1m}3-8&9k+4R&VzPhu+`-=n4+onW%7@z~?3@jV)+%r^Js6Uo9FSxBb+ zXZop+rFala8+oQ)_(G23k)D-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/card.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/card.bmp new file mode 100644 index 0000000000000000000000000000000000000000..04c1b07598b1498be9bce3859f0eaeb56c8bacfe GIT binary patch literal 1782 zcmeHDK@vnj3>=p|I(vc_>;v5W$1eYx6741Yq|<-~iJz-mRl$dd6eX0j5{}Y<1?^-eR)r{E`#I Ca1MC@ literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/card_with_footer.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/card_with_footer.bmp new file mode 100644 index 0000000000000000000000000000000000000000..04c1b07598b1498be9bce3859f0eaeb56c8bacfe GIT binary patch literal 1782 zcmeHDK@vnj3>=p|I(vc_>;v5W$1eYx6741Yq|<-~iJz-mRl$dd6eX0j5{}Y<1?^-eR)r{E`#I Ca1MC@ literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/chart_bar.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/chart_bar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d829037a0aaa95f0bc0fe7cb98133e4bd3254cc3 GIT binary patch literal 1782 zcmeHExeb6Y5DN_@H6t(q1JJWG1vAltbq5x5VTFP&Cnd4v2kBVWqc1Tt?g?kSPZy|^ z4f;Oh2_vqvP4xzzoqc#s_qzo)Pkm3SXviKzTTgC@ixTSh!+*p$L4A*WLV`lYY^Vf< onxIG$6e?yz5#+!IoMr-(H4@_l#%v_U35?lDh;xjsNk47i0%k#|KL7v# literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/chart_line.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/chart_line.bmp new file mode 100644 index 0000000000000000000000000000000000000000..32f1259fee470fa60ad554e67de6f85bb17f34f0 GIT binary patch literal 1782 zcmb_dNlX(_7{-f7&&I?PF`AfoEffM3#^uia{{(Afina zmjJb`(n3JM7$7XlA`%KST?X4}XX`BQz43q3g+(kS@#TMi-tvE6|E2GrljoG(Io8Mn zeF)~>T85yop@Wzhfz}jhN0J6wBpSg;5u)M13eWj@E|9hO0RljP zV?zT^U>ymvhNhZ38~}*~8Gt9k0a}buf`cGTaCSlnKmbVLR!;bkA5NCM-yBz}-Ph~g zC3V|NX}#le)%2^600cN>Rh7kPIHb$*uENUT=#0p4f-fj8hcb(>5{fRe-G!C>FGdu? zsw4nUEW)Y0=qjl*^<;F37`N4Z6^}v_^OD4`@kAwO@qMJ|dL(Qbgy;s*45A~d<63eJ z+mv89C&W|sfSX#_z{3mf(guZLM+#0YwLb<=C`8qhE`gf{UN3M9S6lEzMOSf+At}C> zExq}MsQJTxvtiUT(2e&;=XV6O2t+if4Zc@Dji`}gY8yvNlxGq6%(6@ zv-o`kNU;s_%_VBWVYzQsgzptsDk>sqZI zlL#ayZV>fv(cy|R5ECmZl2z)@t)|U+=0!(QRr-grT=d?s(f1`s;eBbc1Pu@y$Wz`l zaJO~*Y3EqW>#-+qG6@*8b$+$AJBq4RUZBrh7NG_G_Ag_MbV>PccTTHhp-HsmCnN+?inSF1u>?|~z%>6qB)Q?{Cb|FDb8nU0sSKM&42Yrgi%JuFxaneNOfT$D25_IIEDsIB(R5)dq9DNU>Q1r zM#DZA67(WL-vf&mAOHk7LlNK!j3a&zMc~{+Hh@I@Zh)tb1GEfHr#M)eVVPAzGYkdW z(QD^n4a))qfIM7?2@>$a%-ySF#{BAmBXt8Mr$Eey6{g}^i==+2qH(C=jHRr>T&#e} zlyyK-XUsb}t?36Kz#*!5JQfWH$au0xB=b+)j(L`14nKO=7x#wnFpA7Mo!2HD*0Ipc zVlos>1R`LHIRmIG5MA{2ie$)wJBEgF3psYjyGxga;tRv zOLhAs-3O1|khew`+`Mh24Ocb=Zp~pB@;6TugHw=boE4~i<90)iwEc}-?K{P~eWgIv zwWp+G+ab-aqB}h!K*Jx}6Owcx;hG#hr&Y%t-U;$z{P_E4q101CDtwMc{^b*gO z=e=o5dGv2Q9Cz(lvwC};;efO=v!K7QX7;jmzW=)QsH!tFU!Ps3$rAU9PEc49sD?gi zOyiHZmc^-rKdjp;0nzL%g1dwGuLOg;aq2sDW&wBw+B-T8^Mg|5KY3tlj^SJ*le{z8 zQuU5}@2~t~hM*Xdf&u0W{qXMLANL;7yeYD^T^4vwr{`h0Me{EZ4gLNy?c2r3qKjc@ zJ}p@ek{?TwyJa_DFCTeXY;Dxd0?$Bsx^orDIf`Anbw{(aP@gUB*q&?ew7_DP;d2=V zrrXq}O8X1d3mcElUidk3UmkHS9mnYeapi+b?QXF?tD@th_y3sb0#5+qcMRv$X*XB8 zUXt0iem*nriNoYz+Bif0L@}`1wWf|&^R=Rb&5CEw);yuP@LE^fj&rq7H_4ybRik@c z>X2xiobb5rckdLM;2;_#W38)EezER+!*eb5&wnl7^p*Un^YvR>8@8N2vHnAqVF`t2 z%SS#f54=Hg8DmMBAxMHmti7dYzkE`8e4VOlgQ{v{>scWBp9^ zQ`I+ZVBd(Tw+6+y$G8zePvg9U2i)b~A5WFWJ6xKQDRy6Oh1HE#ds iCy=bFt1ETh>x%f?5ufLQ#U1uK@6~zXm+?RRcm4#)*^zbt literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/checkbox.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/checkbox.bmp new file mode 100644 index 0000000000000000000000000000000000000000..fbd99aa366b75d9b2a52bdcff780feab2a67a41f GIT binary patch literal 1782 zcmeH@Jr08~428qek-10c33>qb-kG6iVl7W`d9t2`K#4Ef zNUVs8040>8LYNpU5_ljP^q3edJp-&x^BG2G0(ez|<@fPjFXROzsQd^c6%35XV_NhW SHaw%BmEo)hICTeCzQ7J8y)(1` literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/collapse.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/collapse.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b1569673b0ab0b2941df26c67d08b0bc704d7f38 GIT binary patch literal 1782 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 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/container_fluid.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/container_fluid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d7c56b70e146a618738c142ba6aca2184c7c78fd GIT binary patch literal 1782 zcmb_dT}YEr7`B@(yDkWVin5E+fea!w8DWKuu^fzoBJzkxDA6EHg%h^w%qpZ`(4j>&VHP>Z&Dtf^X_oo^FHVO`OZ6yHn+cl3^imU z=E36JM^+6DcIX`k=p+XrM4qE4h=K$N{B9u%Fe#hU1sHO_Q@;{x$yhWQTTR9lfdjE9 z4#Nb7Wh$)GKjW#yI+tezp5G;K7$z{JRPZggnM!S}7m7o|z9fo7l1OR16)CFxaUB{bNMPBmcb_OGWDFy zZmjZ5md|BmxdR-7{mkqGoo%$2@UWQ@hJ%9S9}Hr898hsh{-LdygaWgg^EV43A`(DUK_N6&)a?E+@qdaJmJ~N7gvu&ee*vS9pAlgBmQ^W;j>5l_ISuUbEn<@e^9LEp#87)E%A~YE4E$MSr%uFZrF4fsT;~`*C9}BtpLUlAA@Z vAOnW08e!vliN@|$eo9dav#I1#FP2|zPg8fo>IxZk+jEu```Hk6VB}M literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/crud_toolbar.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/crud_toolbar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..91bb313c45339968b33c6d87248946e1e37d1318 GIT binary patch literal 1782 zcmbtVTT2^36t*vY>~nuY1rZ}s5ez|JL{PLvT8su1K?Q$=eb-hKT5bB`Pw>)et*JF? zs}U@vHVH~WENaYsbK6ZaJG0v_J9TqwG_=FF!{p34-<~;V_Dg%Wbhkzu4>3Q$bN|nC zM_bj@II;iv9)C1POiU&mDx(TO2|-`fe-ZUxMgunj4*m-`BLsmu z71r@^AQrqLnKYH=Hpj}-K1{q zBO_l@DH$orq_jRfAI=kx{)Gp*A(_|no{o-Q5)nd5`hIIZsFij!hMO=s`3)opsnjpj$7oy= z!U;rWL25ktxo+TgQOJOX)6+y}=SE%K;`sO;bbuQn5;~!-8{jF|G2IOdK_K|(_^l|k^R=#H tP}hpOilhm?_gs${)%2Fnn)a6H>a98-@n430#o}K<=Q&kQ8~@{f=Qj@a9?Ad! literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/danger.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/danger.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/dark.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/dark.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/dashboard_grid.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/dashboard_grid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..99ca9bf38c9e0966081fe1bfe3a3febaf675d9b2 GIT binary patch literal 1782 zcmb_dOHUI~6s{YWuKfxA0{5aZKtapH2#F?kMVkPvf+iX_`V(|vMTBCaf5C+djVa}o zK7>fB=*oGtQyFKbbl!KyZ#wP8wgahw$(hr8?%eOoJ>R+av~O5F8)`fk;Vp!Q-sJhe9|u6dK>}5w zhHaW4FiPKrSW<{3+H88RdhcP|O#E&o8n3_q00@A9`=x;-dq$SmzSjwABF4tXGosh&6d|PSz&sPhOT8{>?jI5IBMj-1oI4z>RWl25N~nIYpZL* z%sdS}LPDI{fya|89>rtq>~^G}=L$mNLB}Ly@bU`eIjHlIiOQXrFnb>xpoY?L*KX2~ z4wy>=MqxW(KXsKG8dp}{Y1s`ev!-R&eJ?M)DM#Zp)K=FqRzH4buU7g?Lh!n)NPJ!}QQvS5`v!R0`WUW5FJ=?}c+ftE?s_VH Q^%VQOPv!N-6a4S|1$AT-!2kdN literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/datatable.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/datatable.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56d0bf259b74b4d31f4bb172c02644393cf4a4d6 GIT binary patch literal 1782 zcmeHDu?@p840D%^oqIwr$N|~=lTYiAo4PiH*$RY+2JzG&hyW`RO)8Y9$7?7pM&vur z?Q<@zD&>j$`O4FXNbjS^chSDDzl!T?tqFAG*Br&6(iXKM{6!+5bzD{CE8=`|99Pv} z=Dyod;h4#*$cn7^+2I_zWyTiT TqIM)!jv`4mwjn=@^%qzGqJs@G literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/datatable_crud.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/datatable_crud.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56d0bf259b74b4d31f4bb172c02644393cf4a4d6 GIT binary patch literal 1782 zcmeHDu?@p840D%^oqIwr$N|~=lTYiAo4PiH*$RY+2JzG&hyW`RO)8Y9$7?7pM&vur z?Q<@zD&>j$`O4FXNbjS^chSDDzl!T?tqFAG*Br&6(iXKM{6!+5bzD{CE8=`|99Pv} z=Dyod;h4#*$cn7^+2I_zWyTiT TqIM)!jv`4mwjn=@^%qzGqJs@G literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/date_picker.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/date_picker.bmp new file mode 100644 index 0000000000000000000000000000000000000000..44ea12ab4a407eda9b27fd8bcab4d6d254f9fffd GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCH}Xh6-u=VXASNgDH+n z1Y#1VEG}_Ol@JkJ>T!vWnu9;whDZ27VxM>t)7P{}KX}Z9OTigvPJ)P&N}?G8-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCH}Xh6-u=VXASNgDH+n z1Y#1VEG}_Ol@JkJ>T!vWnu9;whDZ27VxM>t)7P{}KX}Z9OTigvPJ)P&N}?G8KbfN9EbT2K_PTQIB>r8FXG^8ZlocZ#dJ9EA{XYRdcPNb0g;<%9j zJc#Q+_}as#zaF~rT8-Wl6 zBAgCT$OPPOG6a#;4hKRIh;Y6f$kM?eG#G}V>6k2t#~2172n>aD-votlB0J0mA|WLf z;rv$x;U-vrkoln{f39t7T5?+N9scbyy91%OZ_%-HI#y5MT&wy}wencQ(vdpl(fXx` zZFLjsm*OiI_U6wVu2CvYKIquj!}(ZE1e9ARtj8a(Zc?<<$B+!`^wKUL4Rrfik`B8L zFYTpSjgz@ABTkA}3;Xp5L^xj;uOpUQGP<;wCj+dW2r2W!!XnEG+_=o0|uAw@DhRDolhyG-S+q z9z{niH)lwR*F9}TxmlU1XX-@vs)cufC3ynD#Uzj_VKMOb&5Y}*iG#iE)g!j--nFRt zTxwHcUZW%GD}*5YB2G^t}bJLS95_NJ@fqOhb0B&#reR(Ti3EK zB!Y;FLT>(zE9ohx2D)3esVl8r?e|l^re}qB@+hCz=5hlSAI56SOF=9S7qGui+SK?6 z=Rh=Qh?)=Ty4tBh;X0G`?VBNN*3AF|Tvn;aM@KxtZw zB2hyp#!)6S3Z(z67dAHZSIj<~2<*}ni7K&a<*Y=VEK!HBMU~XN%DE~acrvU-6<@We zP`dF_+j@9EN6x9v;qUrtlYX;rZ$01b9bas-dM`wfz}E8~n&G!gj8$=u@hyngK?{oX dG0X?(SPdNyVv#-uwo83=cltc{%h-kg&L0sx>TLi3 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/disabled_edit.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/disabled_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dd3bf827c0bbfed1fd35a401f3805bb806136551 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm)Q8&GIWWpEMv=0KDI)xg!`VvL%DD`endh&31?;f6-yF^ZUQ#-klBh2I=B X_Yma5jfFD^YQd@iu6>j-v_b#?3sp{; literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/dropdown.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/dropdown.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c4dd2ac881a086b4e7e68c082174e73cb78e4e6e GIT binary patch literal 1782 zcmb_dO-~b16vd58*Zu@|?)(AnO^gfU(zth_QCJ`%5}`tZk|3pR)KCf{Es*pB+JGr^ z8ldzm(3X!rup6$dCFf-Y?bvV`ZMAqWEOQL(tSk;lLT#R^QY!_YpZddmJvEYc^%~Q!#aSNGUGBji5T*+?&fwHs$ZyTDoc1@ zQ`z|HWqWf2YC`vQK|b;5JamxE^3q~rIraxDv3M-{GZDv9$nWvG$KWW}Ss(%->Eycc zi`vIH=K@|ig5I#tgQY>eE*hFau%eE1uJDx1?sh2Ti_8VXk$?>1WZ1vXt|Ckv^eD>S zJEk*>3BS58+-Y6taV&KI3-*ZK=4=1HJ~>OZ&YZ)|6lU_t^x&havFbMFt;SWWR=^u^ zlBw5DG=664I!q6qr@Rpm@rg<284hlfQz6Ua8tD;b?BQ09^@I`NtZJR@vcSo*=X6-# zob^d9&lUOoLnR#Wg@dC4=Xk2p-F}#vkGo#CN4^dJt#he-c#;_PEZf|+|%N@gM#>zW`#41+M@A literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/email_edit.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/email_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..22d39b4e4854d4822c420fa211cc330bd2c96683 GIT binary patch literal 1782 zcmeH@yA8uI5JTlAW$KLJ2{J(X?4;3BcqX?AA;tuu^XIAn0W3i0Gmm@{^mxvf($*by z#J+v^(7IAym`_*kW<+_P>*p`9ynXh&dO?J1ty#okjwlj-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|KJ8NXA(=}@(oEo#iJOH6sFa9 z6yuQ^H3t|1qv3-;5QbLx09}g)FcUdM1gH#`6k31~uM*QhxL!B|Qw>A}zXFIXel%uHpd0ckKEA literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/flex_row.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/flex_row.bmp new file mode 100644 index 0000000000000000000000000000000000000000..93c6964e01c45176ae67351bd40c8255e30fd4f4 GIT binary patch literal 1782 zcmcgtOH30{6vd58*DhVSaAim|uGB<=?${Ol0SXZnC^Z5mN=u?3-%>~fsX`p_AVDEc?wsCx`_Ac``{v%pB`|wqBG)nC zA>8}d?>!MOCZ-?X>-Uj6vJk+tAz~uW2{4Y`uJIfwQ95y;zH@@!9^@3b!eO0L}?LyGcOj^uY$r5#S1rRwIr_CyJ%GneAto zK?7A=evji=Abezy=eU5jw?}qjE1mn9=lXjzqR0~+lU`R>QG^Wu;S(L464l?E^Ivp! z>$!HL&R$L4>4ycG@;sSZRVGWnh)J=_^3t+gpUmJ>gqB@{*CatZ*pE@i19UF zignD4TE-@HS}pBdMtO0~SZ67U0+Nt+Ea@rzkjdDT8fzanAi3c^T)@d5V<_5YlIya!RagJfQVXG00jB7Hqf5-3w bQm*J6Ls^jA`CQ$_IZvd*vk~^M|2sbbrCPzq literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/grid.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/grid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ac48d4945d63e2550b2b04fac7614f51e0f9ba49 GIT binary patch literal 1782 zcmb_d&2JJ>5XXy0&;AJ}MvWh>#xy2+@TT6ZNk43*#*fs*lU~%+rooG?O-%Hx2U}VS zF(!?zfL~Op0Sje8V-#&%x(h7`g+liee{Uao*-~gQbu&B6%zN|W&CHwG6Q_#XEymLf zz6`;r0!Ib~Ik%k5rUZGdq$)~-gw1e)BZb1*iur7INhs4t*UJr3S%(K4;SLZGPAE%j z6`X(j(cuVpfFP^LhAK+{NXNP9+pVA}LT4$x>TC1bE-)3s^qq5)H_yc1y5OQJ65MHN zkTgwGRjKs6_xQWP-q7gK+_U?kkwMDe4_$L!ZeeQ3SPDL|**o{9<56AL)533t163)l zj&~o-{ESsamiij-+N@PZsE(dyVSWa}MjT_w2XIZ680P~X_uY1)D#WNOGPsn_Ijl`0 zH(MLW+9X6i=sKcQ80UjtcYg;_HDW}S!KKv|1IJ$vXX)D zA)tsFB*uin7yK{By7nid_40FQ`Fpr3gk;q38R)7qLai4U>WYj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/heading_h2.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/heading_h2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0d4b6297c732aa5720d942686818563c402a1cdf GIT binary patch literal 1782 zcmb`ITQ37a6vxYh%Zpb&f_DiK2?<_=iZt4$ZjC6d@FMZ%K}aMhaS1A-FTMy5>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/heading_h3.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/heading_h3.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0d4b6297c732aa5720d942686818563c402a1cdf GIT binary patch literal 1782 zcmb`ITQ37a6vxYh%Zpb&f_DiK2?<_=iZt4$ZjC6d@FMZ%K}aMhaS1A-FTMy5>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/horizontal_rule.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/horizontal_rule.bmp new file mode 100644 index 0000000000000000000000000000000000000000..09a4fdaef816e3a6a342a12a8eef5e84952619cc GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9@9$p_^#AXle?au-H?ipNAD|Yv zb_fG#!naQ!-oJYG?!}XLFP^@8i5CGCym$gs4AcVD2saAI{`ltQhgZ*k{rLXp_irK* zP%%&oP$R@BpxeHE{_x@T^Z#T4phlo}pdmm6bm6a`KgcrXKTso3JJ1kdr~*R+=oj+L z0cr$lheXX_Hs>Gl;Qv2hP|(z0zkdJx`u)?lAD;=LuRlKh`1K9bJwJbb2MVs*)9+Eh zA5pCwS}BhQg;y*26pJ*>js$A?{p%-kd_mIBzSApjJyeiZfocwb5#H>?Zh z{GC%(r94r8T{&wI%X*GuFVG%r?Ax=)&bM^N>HW+hsjs#UNB@L<4)_RImrds<$54bA ziV!o|oh99bnV6JTNsdnO4(4xeWkN{rb7GY`9;_IDNxM&$iR3IJAENIb392d?tAFPJ eE@o_GI?H6f9oII?(;r=hl^7*t_Yv?E@dZAdrVrQv literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/info.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/info.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/input_group.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/input_group.bmp new file mode 100644 index 0000000000000000000000000000000000000000..df932b8e17796740e8bd6e78029117e51962db08 GIT binary patch literal 1782 zcmb`I&rcIU6vy%6(X)SoM@@u_H?PK%#CY>!qd`JS+>-bM>A@c)97L2v)QB83fwr_F z8ls_)ph7}`P>e#M{IJ>Cc7L?pc6Zy|otgS(w>AibfOhiPm&xvazj^a^-t5`)#?d-w zG(bE7*YV1A#F^FAO~Ugp$K1<#5dyI-piD4C)6fn@Rp^+Qlwc#DQ-owzL|IWdFbE_d z1Ua!y$OPt@6ptaRLk^ID5ajN1z?NWqNRP_vAY^ih%> z?gODLqnhLcPF0^wn$<^8t;bR6(YV+h6`d&EiU>D?JQv!DFNA!Z=lCMbz2i*|114Pt5{AO8K%~yTe;;NZuR$cJ}f049;((9G8<-KO;q zS9bfrx}YqJJj(=#@tUGpuz5zpA+G64N1L~uYXR>1ylu@_Up;%OW9GAcU2dK4jPR*^ zaZNVX6-Gj4-*o?R>Op+=SEbI-8mc7dCheP&0t@osoH97i2rMYq-Xg1 z*tfoo#HE)T=X%%Abgjx7Dah=*gO9rpa|Rxm$@G6yUQcKGr!x?HC*_`~)HAUMPbQ@9 yacNUFA>ryi{GUGE-WRUV?mpe8L)}LNG=KUFj-Z;HW3@Y1Yje&!zl<9EcYXsT8ZSZs literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/kpi_card.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/kpi_card.bmp new file mode 100644 index 0000000000000000000000000000000000000000..51ac1513ced723f0feb3c80b34fbd711097b8ca2 GIT binary patch literal 1782 zcmb_dTW=CU7_Bcp`s`0oA6r|kv_)xp6KLb5k~I3%i@n)4#;DQw?u&^J76ltjC0hT5 zm0s+{Qk$5V_-0_C3k$m}2(x$3uu58lg{YG=lVO?f%=x~VJ?n7ik2Vxr3&s=Z$A9%B z#aTncGX7sZX7=Jj44NXFFf>&MRHa^MDnd%(<^&9RQQ#A?^nNtG&(wh^79#|KB`VA_ z94jQ^GAXE%L?K&(t|4+Ej}Qc!RM3{s3PLh&{8d9B!a)K+p)3(Y*TIxuUP+A2B*tf} zVq%URo)Q<|6xZtrL^w!L)ilc>5s;9b-DpQo>hTl)#X|a-FFo%s1Ml_o-j_hs;i6QA zfg&K>JQ~VF2p$Uaes*LElWGl$sc6H%M(pq;CJ=x_DdWlbU$Hl5a00m$m*JA)0nnc* zPRajJb6H(gAt^C2SCz*Xh!^$TpB}x?bjoc%<7{sRTpcaF=NdhI4nCFCC89wOc*bWf zc=ku9q5RvIz3ugt@aD(x=DLZUjkUc`TeOUdj0H7$*s)vKP9=rX?ZQMY-g%H@1s>Ve zqsPqa-qeV_@uai8rO$SnqK%G7u-Ddft>?U`DWWfcN?PZo>H62t;f>Jy?X^%DwpKrc z*FuV}3AO4&&kNhsYW(vBt2*P{hbNV6PD&;Smn0ll0W7O#bLppEi*pxWFGXx!@xdFh z%R^OhX()d6I^%G1cOF7@#d}D3&N`Ux0jASsg|7ant&6++$cm@g9_#nSE?%*MdobG8 z&E0-bfk&3{Q28E-4R|8W_DE|dgjGf>eGWZv2FmmMJuUMMg^7uaZ;_xFT%zNj2)@e% zf@F6OB(RQ>Z-D2&_!zGJAzy`~5>gwI1QR~!tLA$IszW}{GBBm8pdW$?K5tS{Z~TYv F&QFdUz&MRHa^MDnd%(<^&9RQQ#A?^nNtG&(wh^79#|KB`VA_ z94jQ^GAXE%L?K&(t|4+Ej}Qc!RM3{s3PLh&{8d9B!a)K+p)3(Y*TIxuUP+A2B*tf} zVq%URo)Q<|6xZtrL^w!L)ilc>5s;9b-DpQo>hTl)#X|a-FFo%s1Ml_o-j_hs;i6QA zfg&K>JQ~VF2p$Uaes*LElWGl$sc6H%M(pq;CJ=x_DdWlbU$Hl5a00m$m*JA)0nnc* zPRajJb6H(gAt^C2SCz*Xh!^$TpB}x?bjoc%<7{sRTpcaF=NdhI4nCFCC89wOc*bWf zc=ku9q5RvIz3ugt@aD(x=DLZUjkUc`TeOUdj0H7$*s)vKP9=rX?ZQMY-g%H@1s>Ve zqsPqa-qeV_@uai8rO$SnqK%G7u-Ddft>?U`DWWfcN?PZo>H62t;f>Jy?X^%DwpKrc z*FuV}3AO4&&kNhsYW(vBt2*P{hbNV6PD&;Smn0ll0W7O#bLppEi*pxWFGXx!@xdFh z%R^OhX()d6I^%G1cOF7@#d}D3&N`Ux0jASsg|7ant&6++$cm@g9_#nSE?%*MdobG8 z&E0-bfk&3{Q28E-4R|8W_DE|dgjGf>eGWZv2FmmMJuUMMg^7uaZ;_xFT%zNj2)@e% zf@F6OB(RQ>Z-D2&_!zGJAzy`~5>gwI1QR~!tLA$IszW}{GBBm8pdW$?K5tS{Z~TYv F&QFdUz-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/lead_text.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/lead_text.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0d4b6297c732aa5720d942686818563c402a1cdf GIT binary patch literal 1782 zcmb`ITQ37a6vxYh%Zpb&f_DiK2?<_=iZt4$ZjC6d@FMZ%K}aMhaS1A-FTMy5>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/light.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/light.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/link.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/link.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0ee9204b87ea0a4ec867b3cc58fb2563b265ab1d GIT binary patch literal 1782 zcmb_dT}YEr7`B@(yY8|qB&uDgq(KlXe-iU23dN|z3njYfM?tBJh_Wz*gv5*jksydg zK|uv|;T)L14YfJj#J{EcbL!^y?c4V4oNqnneBZXxU1;oZzQg%>p69&hecyAw)8*ps z3|{ik9>TX*{dVzQMn*r@2lgl*2cn@-2{lFu+K4FZs3wS9BqCEH`h9E8CGU#EyW-q- zb$|jQ=rkIECFrla>;zWruz&(0=*n>*O9|Pbh6)Ff(Ya4>kpB}=SfDFj-Hwh-sZ0oK zDM2SD%ZaU1=wS6PfQppCr3qHD6Gx`dNrDnRb>G0;v`zP7y1jYkS*u(BiG)RlkeU8g zoyfW;2fiI!U9jVhT$ zaXJ}?p(M2G9&RYrpFLu3Z}wS!Mg@P^<8pp|KTv&qq@fi1G99-=^|NakLwEn@zJko( z?|PUB9Kvmu*WAXsg3;>y@T{5b9WU$SgZkpE`Q8ppcwNg(Cn$K`b_}N;-W;kuMZ+P6 zm1QDHv({fjue#rs=jzI`^^b2`Op~Gzz!HVQvDn0&y3wm;a#ZrIx+1{<(^+v~-q>`} z*jU3gm~#UDjdR*#TFt)Vd`(gQ(ZZZ8ttQiIHercnzD%u8?|!d2K|`W%&BJs=)gE(O z)8M6(L=;$(5JIGg-L^QP>-kub`=KIdxbwl1Z6Ok3VZyo5jyGQ!yH+Vjqh1f}VHX?+ z#Jp$VTVKI`o9-q0$r1`0>q~~t=L)7VHmSG{&NO_{7ad%9-Gw>TKhWX#0ydZ*-O``Q zn(OUAtPzV1%cQ0Ao}n@u;SSnuh#xbRS94qANPUUq_cEPCyp;O|--^O?dkdrtWg0{l z34=P*-5O7oWKu~R-Z1wn)7f;t;(6{fjV-=;Ztc2{9PrOf0m({yRT-%*pWLjYfVbi? s!*gk~LL8YwheMTkDfb%vf9R{RCXyk6FhU`&z1hA~CCv{;X+}pf zBoJy8Y6}{^|5|PJWDr6Q2pkoXunCM1B7$+wWnt`Fd1{3-rZXXg91xr;P6L~IT?ihb zvIKY*36ihKFwxO8Y-U!Efe^(Q$*a!k82 zwKu$Jj3d6ex>%l@-d$VTT3Lwu&g$a&{A|J4Pvrm$yhJ$_ukIkoXo-3hCwa~!3`wem zA(hXSmdcUqyq%!3x=#rXr39M)bN+khjPF$6=O?ex%YE+DH}DOjb#yZ9={p+r4RGRp eOsJ~5-{Y^0sE?t$_NA}(vCnIi?2W(p?|cFU6em0Y literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/modal.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/modal.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0e2b936a784b84501158dff0f20bd83382543f66 GIT binary patch literal 1782 zcmc&#O-~b16vd58*Zu^5fqRV!iHK-obRi(15Q!iV;|ghP>0q&?UkG#|A%=|@qfjfA z7U>v>N+1vuBVXbI={L+2XgkxHH#44g3{Wh!!G$m9z1*4Jb9(Qad1ua+CXW|o#%Zjl zFi-xT$1+h-5slxcPN*}Jh(!_w6^cY;fQW@cBB1Qj)c^{~?HC&gFrjrO#Z#fF@_Pv6chGC1iKpbuc4Nq!GZenD<40MPqjlfU!(WpAzCWE7^Bi$Sy-}^j+t3PzfCtQ^XQD%*%t=J zk&tr`UT~FBXc@cr7oA$$w|=i8%d$wY?m?0ei*XLkV&4kYQ52a-StUVJQPA3d(0S^S zC0P=1a^*b`+>(Wzg8QnoEe`s!I?BGlD^bY)cxx;(x}oU&kI3xz=-lc7gg!3~pVP3j z%ZEL8huv&#ZzDupc=3Lu4Epz)=Bjm z^_dPNh36FR5G0a{EFf)~_SRQk+pmLzhD)EvT~Sv2#7J578oNPj@5}{*w!2enr8K>! z4jk%U^J5UzbDH*zNI*aV87Zrw-C;E$ArJa2#%|-I=g;~k@L@|CC6vW_)5Uheqs6=97s$fu*58_gNT3jKB zh;>6D2)IGmiUq9@hzW#6!(s&swJp+CD3!MFy?WjoGd^)ooXkw_n|tq>d(Yh5w`P-b zqK`P1V-LWZ{&h_dB_E$!=yj9H5)H9&9yg|!W3juOj(?ieQ3P@E9P1pm4}CD$EJmB< z!(UG$T;K?I&f`KPkgcWx7E%4b1Y7%cANl5!CmA8 ziBRpYTz+*9N4OJKDGoKRX)RDb*nRl+hBL)+&pS%UEmTV{CBiryp676GviBvbLuBcG zr;B2*RUSQA7!#$MedNx@p%D{sJgghZ{t1V7x*U76mM5u0?W2R#*laf_a)SU)Pk1jN zzcD6_2P&A|t7CRuS}^8zLdIKyZ3F;WZ*JeLoXR|u-`1XL*4Gk13MIvX3IQiv4J@j^ z0-3mz6p9-%cBIdhXDpF1bN6Sj+RFH*=0yyC>W3Mjg5p>$MjYB4=I!VG+ut`JHV!Y( z3zd-nLKTuWsi~);Y>CpNiIGWb{EvKg$20Nj}IH(TEd(L<{ z@8f6cxEl+j#ekic z1LChN+Z4RGIPX>lbE4p8jyx(%SEYGlYK%HJ8PnvSnnl$jN>wGje zGNw#TS{JxrclcUeO*JeJTb=5*$H9f?_>;&@{3uQ^L>8P+SknsycM4Xs1l&w=a9;TT>e`!~Po_0ZTHv zjV-8$wEMENCGpiQ_W%wh?jj}x2Q6q^ACmyUSg39336W{;w2%E|U*%C3Kouv2{l2gM NpFS`CGXBGV=L?Do;t&7; literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/month_picker.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/month_picker.bmp new file mode 100644 index 0000000000000000000000000000000000000000..44ea12ab4a407eda9b27fd8bcab4d6d254f9fffd GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCH}Xh6-u=VXASNgDH+n z1Y#1VEG}_Ol@JkJ>T!vWnu9;whDZ27VxM>t)7P{}KX}Z9OTigvPJ)P&N}?G8-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm*@#4%MuL~yCcB~BxAfYwpPJ#c5k8E6j1C625Nq6SC;1#zjzC63h`WCM{E q;4vRf8JvsDUR>gEjc5#9>fuf$iGgM~kV}$wxMECmMn#512mk;O;a!RV literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/nav_pills.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/nav_pills.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0663cb2bd45a2c3e82cf14392b660bcb4bc1c08b GIT binary patch literal 1782 zcmeH|O-~v@7{~F_W6ypBKS4i0@BJ)l^zNaJX-`dTXd;H7)k14!c>s6s{ZFZSjGqHV;FcDV5VU(i4`COo)fI` z{fM2@l5D9UZjH3|DU{FJIi{&AvJ?-&h$6EET;!$g_2u+&ih<#elKVTGtC!^xk2E>? zEQ0k)F*)3S`q>Hl{-)Qsxjso9OuL=nM17u3VIB*JNBoO3-mS!v-|ZALzo9~Fa&jVu z>B$e$f}hTq`B>oC^F9*r)yhQ{i3PoDvFJ)P$c9BR6P|LTP#D@cKSzeDCqG!4l1}Zs z?wt!yV@TvG{B}a{j*cAeeM8?+Wm8i_pIjRKBwIM=m@R%?K72Q*mI|BbjBt(#)%Chh!5S(z$ z`o=GERt?Y6zp$N|2^S#z^z9savUojUknm&G>W%xP8M%MM*g4Qrf(79nqrqelj^YVO d{+EN`6B^^-3hKx`*13DNGxt3GWpv=ba|_ouY{viq literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/nav_tabs.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/nav_tabs.bmp new file mode 100644 index 0000000000000000000000000000000000000000..627310a4e27d738cd7027bb68e63e11617efd672 GIT binary patch literal 1782 zcmd5-OK%cU6s{YWuKfxA0)K#e|A~nkSKXM{CUw!6_=t)Ig+wTcZ7q>Up}dCIP#9n+ z!)sb?tw3o>VL~QTm=}IC1Jt$}#jx>#8rO7d zZZ3l7@f*g_12HL*2puXi=7GRZr4yh|GEfy+=y9h<-@7Nx?#a<#YZDLv0av5}GJ)M` zHDqKpr2qmT;6^#1Rb+Wej!`&(8eH!Q3i&q@0|mIz)&G-6g(wP!HvdtLFjYlqv#;y8 z3EEcuutHO8k!Fi|O-luqDb$MeNEwMJQmsBPNq@` zXgs)?iukihf=WcP2_hX0#kV|}SQs`uIWijayBgoVf(P&m=QTLvV%{#{hIR-y0ywVA zuv}1i)o2@@o3d{)%>!!bf#1DhEHM|z=*rvY zdrW@pQC$v;Bx;}1<$T^e?p1O_9HpuX>`s1p-sk$HihWt&@kUUw(5l5$&Ze}tqc4bj z?{_@4XAe0#sSNs1zL?G|-2c4pkZ_aqI7t%8px0)4T1Z7PlkNR?LuAS?^Kl}BOmR8(giz8 z5WNp@0C>ss3m%=^fNKy%nb?M5>^^Z$mgjvQ=QD|!$}o6P!c6Y5+1;zNx##s?#ti;D FKLCY!P)q;- literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/navbar.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/navbar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8bf63b01ca52464f47c13273f3d9d386c1753882 GIT binary patch literal 1782 zcmds2T~E_s6vi7bz4jldf4~^yjV4BkUsp!CF%dHfl9-4_jQLnC!T@KmL?4LNY%YEgn#E>kJ813&Je)?$SSa83^rrXtdG1I0%EZaE73QgZVP=(k|ZG~34&r_u{H9NC<-~X Sk5#U(R;JIZ-{ZgkcYXoFSRtzb literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/number_edit.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/number_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..93c624b24dc79124375f07c4f27e69cbfd4baa95 GIT binary patch literal 1782 zcmb_dSx*yD6vh`HefB4q7+;K{uNtEQqC`avC{iPffv6w`h$R(jppp=+K#8mgASOr@ z5H&2eic2KMiX?1>F3{2`-Al`~)9K9kbp|Vv21~-tnXliubI;dvX6`+6G@0BP$B%g6 z9$dTEt{ps!i~E54pLYotzYxICK^Vt`fE4N5l0^b}5sGC(%gq1ji z3r`h>F zcbRT<84-wZp)Ns3uC%4ME?}OdIg>f8EDT>DNGx0bc%0koBkWGN(zlkZXHj&XsB9OS z7p%n6$nbD+ezrk7H#I#2?Ct3;FD?L?oSXu-H7cs55-cn0C$gjI$d%UgcJr%_#)6#8 zjFgjA;=9t)JHVn`k?33^NJVKO@aDDjD=7(molVj~M^@(|65CK0@;TqA!@R+0mPtxM zgqNsRtLtiHaKo>M;|AXibhNdA-0L+(%?CQEO$LezjQ^S_FDdkst9I84@S{pu^FRV( zb+~~qUp#+WD-TiualbjL4qq41-CCC~O3OHN;(k$nSz#XV_Vvq|XA?lg1z|Vu>czC= z<2`Nlo79!sqz?wEpW_pyw{od~-{J8BRqux@%Zfp4E)TG~tG%|S8s|XVw-hxW)OD%F zfWnOy`#dEO1Vz9~l|~@lgyARgZr9j7KLKAabJZpT|mDvO*7?7)MDjA!`5U zePLrmf8H9vi8vq7ZQ(xVlKF@zLw&A<;8*LZtH2?qr literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/offcanvas.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/offcanvas.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0e2b936a784b84501158dff0f20bd83382543f66 GIT binary patch literal 1782 zcmc&#O-~b16vd58*Zu^5fqRV!iHK-obRi(15Q!iV;|ghP>0q&?UkG#|A%=|@qfjfA z7U>v>N+1vuBVXbI={L+2XgkxHH#44g3{Wh!!G$m9z1*4Jb9(Qad1ua+CXW|o#%Zjl zFi-xT$1+h-5slxcPN*}Jh(!_w6^cY;fQW@cBB1Qj)c^{~?HC&gFrjrO#Z#fF@_Pv6chGC1iKpbuc4Nq!GZenD<40MPqjlfU!(WpAzCWE7^Bi$Sy-}^j+t3PzfCtQ^XQD%*%t=J zk&tr`UT~FBXc@cr7oA$$w|=i8%d$wY?m?0ei*XLkV&4kYQ52a-StUVJQPA3d(0S^S zC0P=1a^*b`+>(Wzg8QnoEe`s!I?BGlD^bY)cxx;(x}oU&kI3xz=-lc7gg!3~pVP3j z%ZEL8huv&#ZzDupc=3Lu4Epz)=Bjm z^_dPNh36FR5G0a{EFf)~_SRQk+pmLzhD)EvT~Sv2#7J578oNPj@5}{*w!2enr8K>! z4jk%U^J5UzbDH*zNI*aV87Zrw-C;E$ArJa2#%|-I=g;~-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/pagination.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/pagination.bmp new file mode 100644 index 0000000000000000000000000000000000000000..31c0f2745af76cc97133bb71d4649beb2c9cf2ae GIT binary patch literal 1782 zcmeHITW=CU6vh`HefB5#3;Y4T`)f3&FO9~;hsM;Tk{TPWU?R7cQo9%|tyHM3Nohz6 zrEIz1%57Jc%|h2**ag3xZMK3n0mGw{nUiz&obQ|2GiPS*-4}0~NV^Mp2jlkTxIr|N zDG2}GEq#zc2({NmAE*kXEOsX929S`*eN_NlTQ4VX+_pvKW6|aqc{wOi`kO}#IO463c2^VFz za4f@A&k^Z$SOeZQS(13RE?=~<^<1L@9-rHGb`%!)7Ui&%=#%8!1F2pXlF`hInbc`) z)BORi!{AnUH?SYrjD8Qn{A9P3av4!*Ngcu9*{0mJd>Vw9r9{Vbubv`DU7js0JxeD} z_WWMBlE;UU{m?<^OFj{U`4y4*>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/password_edit.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/password_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..fc433d639344844d426cfaed951ade7e4e2fc1e9 GIT binary patch literal 1782 zcmeHDISzm@3@ZyGGf&_JJb;})Gw>!>uo|d}l33-K5S5Zfw&SE7#-$GN^vE5e-J^jB;P|$p+cPd|K8s8%k(iVQiI`BY_`v_Uk1VOJ$nqYgO|YIP=G2XM z$)Lil{RJs(Cy(-+pWtL1q4Y!|CY1I8V(LxMY)_!HAQL1}yhv7g!CO2wcgT11^xwlb D-FHrz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/percent_edit.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/percent_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..381051daaacfa5b286d9ddc66987d5b5fbf7d843 GIT binary patch literal 1782 zcmb`IO=uHA6vyMmn;xV{l_EAMNU?q(*n)?ef?%V)*a|kD)O&7iQQAY}O|M#^Xgui2 zt6H%L%|QYlf@t&6RGTKYCNbvwJKdRG|1&RHlMRsy9cG8wH}C!S|7ISu!=vTBCfUwo zJb|aX{_K%6lgWkkkNfG7ju^PIjjnNqu~shrSJwk2q^5FK&Sz7x%}gSiNyK*CqX
z6KE9yl4EjeCEBis^3^}|7Zs={ zn9pT#riN-aa0s%^)Yo5g9|EFWsWDbhaOjlTe(MH|K%q6(jr)U@QjK4o5B1#h9h&yt zd9jJ?$X!tc%Ja#6?r7KCq@4&ls#y<{_~-7Fc{cF7pakPp6bY$n?3F+*zh69il>?CytoN1YJw-`Va4W`Sgjjh=XY6Kn{Ak#0DRH z>vOD{XZ@q|8&yTu4tLS0+L2%~@e8l*dUPXDk6cNoJ5{cU^KIHryoqKwELcbnt|0v$ pGkm@sB1uA(?uj|wW3U?TRn(xd)F{4fY`s@^=bo3pj9vKe`~jwpGsOS^ literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/primary.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/primary.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/progress.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/progress.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3c40b97b486c632e67b5a3a55b992ae5afc54ea1 GIT binary patch literal 1782 zcmcIlQBTuQ6t0N@e9;GEAOsALKJe_Ti7!47f0Txi2m`_+A@C0%(RbtS*i3YqXn?IF z6vo*?v~>C4xxA)zy#V||7>b~*2LEJ4WN zdhTH~JC0ab;714<XmG%UUD zdoB%vTLR9YfEY<3ww7aAC-rck0V3!S0T7{o?hPapf(SZ9kX2*@&oY<}h@eNW=6~og z&gnJaoX0W4?ri(U)8iL2ZnpaBgw!jD(&m@F58q1f3o)?W`dZu*MdL`64@$~GQ9UfT z92>Wwf!~`Szny2cL4G_)eHu=Ykrct&#mF4FKTD>TNTIlYRzKF2N~0=CJKxVemobLA zz09+wP{u>gd9k`Z{4PJXlz+1LC(`-x<6T*p!+(WuD?3ANqT2`CT! zUo-1DA(eZa&OciC8#ol+W|wnP=-T#a6SXJr@0xnMdSji2>IXhfvODGJmCX18nM{+3 z9z0znqw|?pYuR#XS349HNrXtH^pnznQ5rv2T!-8?4XG+0D{7?&*dEEMqpOxCpVWYA z^EajM`(lXcj-#&*G*E0P#jE4$VRXambnX}q>L=mvE2+K#okaQ=x@#hRHNid~Nws_9 IKm2zt00!+!ga7~l literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/radio_group.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/radio_group.bmp new file mode 100644 index 0000000000000000000000000000000000000000..17117c803df17e829082084fb9d3c4e0076e6368 GIT binary patch literal 1782 zcmcJQJx;?w5QR;H6baGLAaMaszyT1@QBea84Huw*7N`)nKuV8N5FtT9m0W<|&;()! z6gHrkBL>_HZaohX9Enzd$T-+Mbd>ueTR{YfWz7I@DyX1~Wo;yKPG^Hn%Dg5@Ur<#p^_cPFXOalxB zqDWDj|Dn`NBl^_?5jr9m7501Gtc(dmZ9gXWuEv;Y|s-szS z=j3{7vy9;ol4J@1FahW4aKr%U>heJar~05!nA^U-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9@9$p_^#AXle?au-H?ipNAD|Yv zb_fG#!naQ!-oJYG?!}XLFP^@8i5CGCym$gs4AcVD2saAI{`ltQhgZ*k{rLXp_irK* zP%%&oP$R@BpxeHE{_x@T^Z#T4phlo}pdmm6bm6a`KgcrXKTso3JJ1kdr~*R+=oj+L z0cr$lheQoQbN>DN4@6i2@#g&b3pE1Bz%&e(IsY&K&>7!<{{8S3>TzUwpcF21FdaYt zz!RO)BP#g^E0^E=@#`;|0<7lz{`KqI*RS8cfzapAUxDm(C!ev$>=a4eE0M8}A$&W~ zsBhoCefjbQDE0FPD2ma{`T65JP;k-g=@y!bp4KLA76xt>h8|{G3XwA;vX9GT?2*dc zE1i8%JZX!wwWX((fsLM8Syl>A%kN)5f$1L}U%!6-1PY!%b86&)zSayp`oS~`nEHSz@b6y`i788@doVSkiBR1fYLy#6bEr~|0ZUh^ Rl&e%M=OIRc%0>$69RTGBQiT8j literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/readonly_edit.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/readonly_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dd3bf827c0bbfed1fd35a401f3805bb806136551 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm)Q8&GIWWpEMv=0KDI)xg!`VvL%DD`endh&31?;f6-yF^ZUQ#-klBh2I=B X_Yma5jfFD^YQd@iu6>j-v_b#?3sp{; literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/row.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/row.bmp new file mode 100644 index 0000000000000000000000000000000000000000..93c6964e01c45176ae67351bd40c8255e30fd4f4 GIT binary patch literal 1782 zcmcgtOH30{6vd58*DhVSaAim|uGB<=?${Ol0SXZnC^Z5mN=u?3-%>~fsX`p_AVDEc?wsCx`_Ac``{v%pB`|wqBG)nC zA>8}d?>!MOCZ-?X>-Uj6vJk+tAz~uW2{4Y`uJIfwQ95y;zH@@!9^@3b!eO0L}?LyGcOj^uY$r5#S1rRwIr_CyJ%GneAto zK?7A=evji=Abezy=eU5jw?}qjE1mn9=lXjzqR0~+lU`R>QG^Wu;S(L464l?E^Ivp! z>$!HL&R$L4>4ycG@;sSZRVGWnh)J=_^3t+gpUmJ>gqB@{*CatZ*pE@i19UF zignD4TE-@HS}pBdMtO0~SZ67U0+Nt+Ea@rzkjdDT8fzanAi3c^T)@d5V<_5YlIya!RagJfQVXG00jB7Hqf5-3w bQm*J6Ls^jA`CQ$_IZvd*vk~^M|2sbbrCPzq literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/search_edit.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/search_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3bdafe4b01f9133e33935e98893a90ec17020387 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|1bhn@eV9tC<>WTLokyS8DRp~ z0$~8ngo|LBk4pru1(^Xc3YQj4akyT%6s8DV3Ks*H7F^=^&A}=QF$${`rXU{0c%*1; t4$x{eD-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/select.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/select.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dccce0f4c866e1c3cba1c55e25bab4e036b071d1 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm*@#4%MuL~yCcB~BxAfYwpPJ#c5k8E6j1C625Nq6SC;1#zjzC63h`WCM{E q;4vRf8JvsDUR>gEjc5#9>fuf$iGgM~kV}$wxMECmMn#512mk;O;a!RV literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/small_button.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/small_button.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/small_text.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/small_text.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0d4b6297c732aa5720d942686818563c402a1cdf GIT binary patch literal 1782 zcmb`ITQ37a6vxYh%Zpb&f_DiK2?<_=iZt4$ZjC6d@FMZ%K}aMhaS1A-FTMy5>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/spinner.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/spinner.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bdbc3c6d3f6810d35cf717261cc3aad3164c6b27 GIT binary patch literal 1782 zcmb_dOKTHR6rOg`rQ$+xWf27Z1zCv;H;SSz-MA2Ug54=X=_AsOMhX@MSE2|8E7XOe zjm@K@Z5k^UF%P0mO52#2_asf5G?}O0+%p+NW?BmNa^~h_?)QE7oO5qZ&RlHtacnp+ zpTu*-czT$}aXi-N575Jam=sAQ(-c{S$hN5Y*s$o{i!G~pl2s%Vyh)`@b zJ0U9QcQFkeqMmbyLF}Ih-Tk!2uT|z# z)hFLFj;Bl9i2vB5FY#iXwu7Lpj?A_ho?YdJ{imOQPYMkqdiJr=lyAIW=I+eg@~-F# zEInHttQP9x;ql-h*Icx)g|98tPt{FiEadw-mamIAMq^lYXw4nXBbaM%e*#BUZ8QGW z#C!v1CmmNX)idaQxR^$YT{>VP45VWQvy0Ayg%mgF#SE}j$A|<4wQ!a+Q?c~Sffpu4Em zbh7MPNZk*nkZg9dg=jku9T-!`wr}WwZicQ*LuP|~vu{9Wr#=QGjtTditSb`IG5Z+0 T>%R2WeeCljrT51F_}}>pvhY6o literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/standard_button.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/standard_button.bmp new file mode 100644 index 0000000000000000000000000000000000000000..af6c190a9e23c98db1f37472c0decadc0f29e9c6 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;qG((mB}y}@B21$o z@|fayM6hbXDu~ArpcGauSOqCJrvW#B8;;d#tb%YYSQ%KgU=_rw9WIDf3syn67OV_h YS|H*ikyyqb-kG6iVl7W`d9t2`K#4Ef zNUVs8040>8LYNpU5_ljP^q3edJp-&x^BG2G0(ez|<@fPjFXROzsQd^c6%35XV_NhW SHaw%BmEo)hICTeCzQ7J8y)(1` literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/standard_combobox.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/standard_combobox.bmp new file mode 100644 index 0000000000000000000000000000000000000000..73ba54340c8966b6b596f30591832e8db80c22f8 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKWE#zxB-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o!mApna&l4&&WlB^%50joI> zL7);eS*%=$NoZ2Yf}`eOh5#+X2Q3P4agnWttAPlTLBdUdFvu_gt9#Il9pw)15C8yi Cbaiq7 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/standard_grid.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/standard_grid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7872be7624edc7296d46049e80d8e2afb2ed8274 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|6m0$2a-&qc?eT~Lqh|aAf^aV z0akO61%bMdxj;6W2*egNHJE~Ex`wVfK#!0LM#C97c>qHXnTwfJfU=l^Xu60`Kcq$$ qQ2l6pAx98e$YVwgJiZ`O5E2rM_(g!S$QEHW2iXKXY&3I*85aP9NZ?rj literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/standard_groupbox.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/standard_groupbox.bmp new file mode 100644 index 0000000000000000000000000000000000000000..76158cc47bfa8b815bc417850ed0cab4e1a25264 GIT binary patch literal 1782 zcmeH@F%H5o5CokjC3T*_3-SPZ{!EcK(Zb0l)@hiaM501ivVFVWIVZkc?_;TBj`bXK zdd;C$rQG6tIkj1Xu{?f#tUr2q$HN@vS3vu~{4851WYk0kQV}%)LMoyrKuAT@1PG~! zngAgcQ4=7fB5DGJR76dHkcxD(6}s;4)4Kr)shz__GRJV#WDew7!(qN((fe#6>VL6M O{_I@qy?=Ah3p@c@dP|%D literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/standard_hidden.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/standard_hidden.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cb5d8ec794287aa2cde66f7b31901a6e2f4ba36d GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o!;Apna*5@@V`B|$$-DIRmM zN?{5@Ou`fgir|sLRF6k79x3w7X&?mfJD%$9!Sn^D2p&uENReR<#55vFO!I*vMCwIW MhSi)=!I2XJ0CqNx=>Px# literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/standard_image.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/standard_image.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a9e189beb4bdea722a2d57fd53fd9318c1cefa7f GIT binary patch literal 1782 zcmeHEF%H5o5K9+E=01TJ@BnuH%)pzvf)x|Xx?CfrVnRep>iBG5lHTsysnl`Bdcj;j zbE&A52kOr=XBA?3{rYGZo&JW0nf5nBniI(JmPtX=;wS##AP3>7h86>|7khZ9a@&(` zQEMmNA}l})^?~Hcog{X~Z>MSy^f~SV)=&Z%U~X02BV9o3UdK{8=~w~*RQpV?Qs6RG nQ;@b3`K=tZR%Ut(k*O>tWl2G5A$ed8Ee<54=Lxa@Ennab;??Nz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/standard_label.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/standard_label.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e740645619de8ed20f40f88a2c03de42356cd703 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tk)2sDrm=zEXw|A! za7WnL*uNPV6pFe*rEiEA;J9g~I%gaNSC5as$ zAFr>kZ*FcbAtAAA*DjLuA}e0EZe4eGH&DdL$mr+KpU6@qv4O$j?CgBw#*Lt$Ad)m< lD)#g9D=8_NH*X%M6iFhpXU}G1V|(%91xdO_6_3CW006*tc#Hr5 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/standard_link.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/standard_link.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f400df2909a699c3b6c204a29b4e7905fbf4983c GIT binary patch literal 1782 zcmeH^F%H5o5Clz=lA0&v1$jVv{!GD}(!$ASMyoq65@kdz*;%jW){ed2x2g5E*f?9i zjehB>wTG=guiiUo!|QAZzk$z7jxT>x`2Z>c>{A0OUu)68*&)!EGMP(o_Dia$u%m@Q zs?c3>2~`=>5Yrh@=WC7w-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|6m0$2a-&qd5C2FFb!DEK@-H! zg_wk<2CE>N8Z<6eEpWjGA^^ldxE5sdu?iw9z+_|9f>jVxFR}<$Em#GSbz!oxYQZXq xsTWxUs}{H*5y9L5F%7PTpy9|0Fxey1oM9Qxkffbla~nq_xVvNX%~x zDGT9{`*X^X3T3-{U*)0AUo)6yzX-ICf#1j6$<$D2YRr);3S-@po~mGf3bDZFRH4wj zNT@;~T0W-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCIHI1q{jhVH&WSgC>Zd z3o!{z4P3B+H~`cR*Me*mTo7msvN%>YL=9XEvKqMHs5$VU7!4of5CF1?Og}(n1Od=A f{NapdH6AV=b0AVAk!Ti?q!(E+nmMCftRVmZ5WD^z literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/standard_progress.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/standard_progress.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4ddf24900411555010e80d148e9a10aadfc2c16a GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#QAplDVB-3cYMzVgG2CU{Z t;09>wfn115XyOn-+{QGZsUMlmc^VvaL-ak3^+i%}5-ary~TTermv>eq1^R2_FRRjzhh7_Y>PI{M!@%f{R zkRyxRp#_$Z)I~3gl$12^0;6t1EJ;XRZif~U$p{1qiz}>8qRugPO~)Jod|SbW%n-n@ bowOAdK1Qqy##=;1!B|mCNU`gW#TWPhjxkh| literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/success.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/success.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/switch.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/switch.bmp new file mode 100644 index 0000000000000000000000000000000000000000..aa793e1efb166445e2ac39bfd1049834ebe67c7a GIT binary patch literal 1782 zcmb`I&1(}u7{(()K`KfPRck*EB1QiJ4}zDpSJAU5wu;6Cwec#p##Sgw@ehz(gq}(T zAu5DzHfcy|vDQ@7`jIxNF>Uj;n@wWAW_Pnbn@MA7J}5E6vy)-weSUf8-CUXmN=QUE`EZC2Z}5?Z zLO?i#U|3+RpfFCxBSLhGyEt-D5#^#N)s>8h?N*PoBV;?Y)~{SFqiS;KVu;H;mj(=ldt`g*1*K8wU2=$*fhABL+8DLWVgX_+T$e!Q|Wu*QvLsW3gg}CyBTu#0z{}$|e>*1=|Oi;|8|J=-7YBHZ|+J zFtPAp+6PO%P=mAN7qr)AfBy5GNnCswbKW4X&3@!z^kn eRyeJ?H^6DhJ%-!0CHHCz?|F(+@5cZ5?)(J=>NW=e literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/table.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/table.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56d0bf259b74b4d31f4bb172c02644393cf4a4d6 GIT binary patch literal 1782 zcmeHDu?@p840D%^oqIwr$N|~=lTYiAo4PiH*$RY+2JzG&hyW`RO)8Y9$7?7pM&vur z?Q<@zD&>j$`O4FXNbjS^chSDDzl!T?tqFAG*Br&6(iXKM{6!+5bzD{CE8=`|99Pv} z=Dyod;h4#*$cn7^+2I_zWyTiT TqIM)!jv`4mwjn=@^%qzGqJs@G literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/text_edit.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/text_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dd3bf827c0bbfed1fd35a401f3805bb806136551 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm)Q8&GIWWpEMv=0KDI)xg!`VvL%DD`endh&31?;f6-yF^ZUQ#-klBh2I=B X_Yma5jfFD^YQd@iu6>j-v_b#?3sp{; literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/textarea.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/textarea.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a937b000f14221a2e401e2c8416ef736beb68ab6 GIT binary patch literal 1782 zcmb_d$!`)-9L9@B&;AMCO+0zhn8q3om8D2pmb$c6V5nM+7ZWvj(t`(2ni7pME>+{9 z*5!Z;)H3OS(6U&h3;WUm$|^96znOX1W>aYO?h(JenK$fPc4mBFbfymMMI{_n&RfZ{rf~D|MD};jO$Z~NdK>w{E z7SPeHA|0wy@|dun>f`vZ7{72z80UNE^b)k?93QMCqac+{#u_>ae)?4M+@{e!W`W3`~1wNYXns z`5d@8kApBsBk!N>)Zu&?q;$O=^m`UP?tph5Vl!aH?{=;w<8-YGbdSjxnw${S;e55# zICtJV`p_FQ40iK1KB^g2_UTkIol3eDGTk7o$P8-vh(>Yi#NqVx%bhxV`r7ok;QHg&hCzAzbu-fO`XfF~1# zci!hB^7(b&U87(=8N!N>h`Eg0YwnxFtFIox+0FM##$Z~@l8!OOobEJnSxJm3_JFY; zKX-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|DXp{bR@*nl=~PKcp#cQ(~wQT z&&FduevO#2SdD@x!zzVU5SMyf;#ds<3gS|aOMJl1X}}GT-GKEgC@RD|jw000*F BUnl?o literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/toolbar_debug_breakpoint.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/toolbar_debug_breakpoint.bmp new file mode 100644 index 0000000000000000000000000000000000000000..40beae6989a09e87ea3af6a894e33f3814d6996b GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y!!QCOA{EGpc%K1v>FZxcMnDl_ zv}0<77(!4xE{z1WqiOv5^*;m=<9KAfaE)l%ak+dj=mq)_?rdWG3yeWzXCrHYuyJ`7 c9`(4i6VwPX0aH7X8sXZ3>fs3Ps*%h90Ns$PcK`qY literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/toolbar_debug_clear.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/toolbar_debug_clear.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4c4723933b3e9fda042b68d181908a3a7d9c4287 GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y1AT$HxjFF`A}a>6A%Ga|Fts4N zklDoOMb<*RjmRdGVIxF4Tq8kyMMNs#2-(4CY-CqK*g#$S`j_Dd$c1QutAx7&E`n7f x!~}?TWR*be$Xp;B%|^J@KnAAvVW1b6mkD|n?sv2hBVHrK1fY62f}1&P7yut#l<@!n literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/toolbar_debug_devtools.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/toolbar_debug_devtools.bmp new file mode 100644 index 0000000000000000000000000000000000000000..165a0f9c25ce1bdb4f1386cdf83b9c2b03ff83a5 GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y!%znC-ZsP|G>;Om5vUTYUNk`< zcVDIfGJ;rvrVOhf8G3;hp_vTlVzmM;i0neR7B~a03@!p>pb5fFKvsjP3?d8H3)h9! z<#1)lW+Dq>)rDpSF1^U&Xl!IF;8Iux;j(ZBR%H-DB1yPW5C)ODu-c1e)Nthj02lv{ A{{R30 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/toolbar_debug_start.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/toolbar_debug_start.bmp new file mode 100644 index 0000000000000000000000000000000000000000..45e52741701738d17dc004ca66358303a37d4f41 GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y!>|Cl@nU5A1E?2*$S?t@(RZ#E z5RqX5Trb=N;vImdmm~*Z>V-Q1D23k*xb(tJz@r_PUZ6M`_7bBD;uti03EGA11-M?~ Ut%GZaXd%fuWW8|qC<8eJ0D_{`(f|Me literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/toolbar_debug_stop.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/toolbar_debug_stop.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4f79e5ded59072054b4811597afba2e94f3ec27a GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y!-xkmGPSr6{;&b+a&Wkg3jt;E bXdl&!9B#uetbkDu^b{_HCt-|A;ST`-HQJ_$ literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/toolbar_help.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/toolbar_help.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cf2b09d75b88d83d999f2c627fd49adb435c767b GIT binary patch literal 822 zcmbu2u?@o@5Jid7M=4nVDXm?YK9WmnFT*Yjf#e08jtN)*&)~+%#g}|pppZyGI=KJ; zyW?uQqu5SI_l4^Gs)LZ5FDSpAxY!Wl{`YxrdcO5#OzxS|L0Z{XMx}#2++;u|`@XO6 z8BF9n&lyh=7#c9cFs$ne$qg_x0Iap+I6{8qLkPy0Pdxef!Z}BBSr#efo(I4tWYaV; o#*~s$s=`ymBhxf#t=qQs-h;-s24+A~1BfM{m=VlkU^oDjKf(vWV1+;;ihAG!#Q@?KijDbz)tvYMHzE<- z0l3WhPXqwkHPp@7l4%Y^XnrNbUxUOPh%+!rhzE)H7p4iw9wgozc)%iShYJn^bCCT4 z^bQ=6oiBhUync8Gh>!yZXd0>c6k-mVA>^5ZX$T&3fQoS;c$gqFu=)#G0g>#%X%56y G6p{d{WHaFa literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/toolbar_open.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/toolbar_open.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3bb431ebb5f665b9de37883a2c1b06549afa4ce5 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+;;ihAG!#Q@?KijDa|3v=Y6Du_pD zUO;va(2)2`|A|3x>)@u5XAaOVh*3kr9H1kK4nc-O(TpfL!VfTkXe zi$^-s24+A~1BfM{m=VlkU^oDjKf(vWV1+;;ihAG!#Q@?KijDa|BXcsn%}GLV zkD$2+XvnJCC?LXb8e9!A=KR6|knI}D=HLlx;=>uD5-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/editor/icons/week_picker.bmp b/CORE/Source/Includes/HTMLEditor/editor/icons/week_picker.bmp new file mode 100644 index 0000000000000000000000000000000000000000..44ea12ab4a407eda9b27fd8bcab4d6d254f9fffd GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCH}Xh6-u=VXASNgDH+n z1Y#1VEG}_Ol@JkJ>T!vWnu9;whDZ27VxM>t)7P{}KX}Z9OTigvPJ)P&N}?G8Container`; + } +} + +export class RESTDWContainer_Fluid { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Container Fluid
`; + } +} + +export class RESTDWRow { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Column
`; + } +} + +export class RESTDWColumns_6_6 { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Left
Right
`; + } +} + +export class RESTDWColumns_4_4_4 { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
One
Two
Three
`; + } +} + +export class RESTDWColumns_3_9 { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Sidebar
Content
`; + } +} + +export class RESTDWFlex_Row { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Item 1
Item 2
`; + } +} + +export class RESTDWGrid { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Item 1
Item 2
`; + } +} + +export class RESTDWHeading_H1 { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `

Heading H1

`; + } +} + +export class RESTDWHeading_H2 { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `

Heading H2

`; + } +} + +export class RESTDWHeading_H3 { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `

Heading H3

`; + } +} + +export class RESTDWParagraph { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `

Paragraph text

`; + } +} + +export class RESTDWSmall_Text { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `Small text`; + } +} + +export class RESTDWLead_Text { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `

Lead paragraph

`; + } +} + +export class RESTDWImage { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `Image`; + } +} + +export class RESTDWCard { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Card
Card body
`; + } +} + +export class RESTDWCard_With_Footer { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Header
Body
`; + } +} + +export class RESTDWList_Group { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
  • Item 1
  • Item 2
`; + } +} + +export class RESTDWBadge { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `Badge`; + } +} + +export class RESTDWHorizontal_Rule { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWNavbar { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWNav_Pills { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWNav_Tabs { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWBreadcrumb { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWPagination { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWText_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWPassword_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWEmail_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWSearch_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWNumber_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWDecimal_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWMoney_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
R$
`; + } +} + +export class RESTDWPercent_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
%
`; + } +} + +export class RESTDWDate_Picker { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWTime_Picker { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWDateTime_Picker { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWMonth_Picker { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWWeek_Picker { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWColor_Picker { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWTextArea { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWSelect { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWMulti_Select { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWCheckbox { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWSwitch { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWRadio_Group { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWRange { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWFile_Upload { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWInput_Group { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
@
`; + } +} + +export class RESTDWReadonly_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWDisabled_Edit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWPrimary { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWSecondary { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWSuccess { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWDanger { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWWarning { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWInfo { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWLight { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWDark { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWLink { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWOutline_Primary { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWSmall_Button { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWLarge_Button { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWButton_Group { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWCRUD_Toolbar { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWAlert_Primary { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Information message
`; + } +} + +export class RESTDWAlert_Success { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Success message
`; + } +} + +export class RESTDWAlert_Danger { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Error message
`; + } +} + +export class RESTDWProgress { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWSpinner { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWAccordion { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Content
`; + } +} + +export class RESTDWCollapse { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Collapsed content
`; + } +} + +export class RESTDWDropdown { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWModal { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWOffcanvas { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Offcanvas content
`; + } +} + +export class RESTDWToast { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Toast notification
`; + } +} + +export class RESTDWTable { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
NameValue
Item100
`; + } +} + +export class RESTDWBordered_Table { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
IDName
1Item
`; + } +} + +export class RESTDWKPI_Card { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Revenue

R$ 0,00

Current month
`; + } +} + +export class RESTDWKPI_Cards_4 { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Revenue

R$ 125K

Orders

1.284

Clients

842

Conversion

18.4%

`; + } +} + +export class RESTDWDashboard_Grid { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
KPI 1
KPI 2
`; + } +} diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/bootstrap/css/bootstrap.min.css b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/bootstrap/css/bootstrap.min.css new file mode 100644 index 000000000..8589b8f7b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/bootstrap/css/bootstrap.min.css @@ -0,0 +1,17 @@ +/* RESTDataware offline Bootstrap-compatible designer runtime. + Replace with official Bootstrap distribution in this same folder at any time. */ +:root{--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-danger:#dc3545;--bs-warning:#ffc107;--bs-info:#0dcaf0;--bs-light:#f8f9fa;--bs-dark:#212529} +*{box-sizing:border-box}body{margin:0;font-family:Arial,sans-serif;color:#212529;background:#fff}.container{width:100%;max-width:1140px;margin:auto;padding:0 12px}.container-fluid{width:100%;padding:0 12px}.row{display:flex;flex-wrap:wrap;margin:0 -6px}.row>*{padding:0 6px}.col{flex:1 0 0}.col-1{width:8.333%}.col-2{width:16.666%}.col-3{width:25%}.col-4{width:33.333%}.col-6{width:50%}.col-8{width:66.666%}.col-9{width:75%}.col-12{width:100%} +.btn{display:inline-block;padding:.375rem .75rem;border:1px solid transparent;border-radius:.375rem;text-decoration:none;cursor:pointer}.btn-primary{background:var(--bs-primary);color:#fff}.btn-secondary{background:var(--bs-secondary);color:#fff}.btn-success{background:var(--bs-success);color:#fff}.btn-danger{background:var(--bs-danger);color:#fff}.btn-warning{background:var(--bs-warning);color:#111}.btn-outline-primary{border-color:var(--bs-primary);color:var(--bs-primary);background:transparent} +.card{border:1px solid #dee2e6;border-radius:.375rem;background:#fff}.card-header,.card-footer{padding:.75rem 1rem;background:#f8f9fa}.card-body{padding:1rem}.alert{padding:1rem;border-radius:.375rem;margin-bottom:1rem}.alert-primary{background:#cfe2ff}.alert-success{background:#d1e7dd}.alert-danger{background:#f8d7da}.badge{display:inline-block;padding:.35em .65em;border-radius:.375rem;background:var(--bs-primary);color:#fff} +.form-control,.form-select{display:block;width:100%;padding:.375rem .75rem;border:1px solid #ced4da;border-radius:.375rem;background:#fff}.form-label{display:block;margin-bottom:.5rem}.form-check{display:block;margin-bottom:.5rem}.input-group{display:flex}.input-group .form-control{flex:1}.input-group-text{padding:.375rem .75rem;border:1px solid #ced4da;background:#e9ecef} +.table{width:100%;border-collapse:collapse}.table th,.table td{padding:.5rem;border-bottom:1px solid #dee2e6}.table-striped tbody tr:nth-child(odd){background:#f8f9fa}.table-bordered th,.table-bordered td{border:1px solid #dee2e6} +.nav{display:flex;gap:.25rem;list-style:none;padding:0}.nav-link{display:block;padding:.5rem 1rem;text-decoration:none}.navbar{display:flex;align-items:center;padding:.5rem 1rem;background:#f8f9fa}.navbar-brand{font-weight:bold;margin-right:1rem}.breadcrumb{display:flex;list-style:none;gap:.5rem;padding:.5rem 0}.pagination{display:flex;list-style:none;padding:0}.page-link{padding:.375rem .75rem;border:1px solid #dee2e6;text-decoration:none} +.progress{height:1rem;background:#e9ecef;border-radius:.375rem;overflow:hidden}.progress-bar{height:100%;background:var(--bs-primary)}.spinner-border{display:inline-block;width:2rem;height:2rem;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%} +.accordion-item{border:1px solid #dee2e6}.accordion-button{width:100%;padding:1rem;text-align:left;border:0;background:#f8f9fa}.accordion-body{padding:1rem}.list-group{list-style:none;padding:0}.list-group-item{padding:.5rem 1rem;border:1px solid #dee2e6}.modal,.offcanvas,.toast,.popover,.tooltip,.dropdown-menu{border:1px solid #dee2e6;background:#fff;padding:1rem;border-radius:.375rem}.dropdown-menu{display:none;position:absolute}.dropdown:hover .dropdown-menu{display:block}.collapse{display:none}.collapse.show{display:block} +.d-flex{display:flex}.d-grid{display:grid}.gap-2{gap:.5rem}.p-2{padding:.5rem}.p-3{padding:1rem}.p-4{padding:1.5rem}.m-2{margin:.5rem}.mb-3{margin-bottom:1rem}.mt-3{margin-top:1rem}.text-center{text-align:center}.text-end{text-align:right}.fw-bold{font-weight:bold}.bg-primary{background:var(--bs-primary)!important}.bg-dark{background:var(--bs-dark)!important}.bg-light{background:var(--bs-light)!important}.text-white{color:#fff!important}.rounded{border-radius:.375rem}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)} +@media(max-width:768px){.col-3,.col-4,.col-6,.col-8,.col-9{width:100%}} + + +.btn-info{background:var(--bs-info);color:#111}.btn-light{background:var(--bs-light);color:#111;border-color:#dee2e6}.btn-dark{background:var(--bs-dark);color:#fff}.btn-link{background:transparent;color:var(--bs-primary);text-decoration:underline}.btn-sm{padding:.25rem .5rem;font-size:.875rem}.btn-lg{padding:.5rem 1rem;font-size:1.25rem} +.form-range{width:100%}.lead{font-size:1.25rem;font-weight:300}.img-fluid{max-width:100%;height:auto}.btn:disabled,.form-control:disabled{opacity:.65}.py-4{padding-top:1.5rem;padding-bottom:1.5rem}.mb-3{margin-bottom:1rem}.mt-3{margin-top:1rem} diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/bootstrap/js/bootstrap.bundle.min.js b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/bootstrap/js/bootstrap.bundle.min.js new file mode 100644 index 000000000..da6faf326 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/bootstrap/js/bootstrap.bundle.min.js @@ -0,0 +1,2 @@ +/* RESTDataware offline Bootstrap-compatible behavior */ +document.addEventListener('click',function(e){var t=e.target.closest('[data-bs-toggle]');if(!t)return;var kind=t.getAttribute('data-bs-toggle'),sel=t.getAttribute('data-bs-target')||t.getAttribute('href');if(kind==='collapse'&&sel){var x=document.querySelector(sel);if(x)x.classList.toggle('show')}if(kind==='modal'&&sel){var m=document.querySelector(sel);if(m)m.style.display='block'}if(kind==='offcanvas'&&sel){var o=document.querySelector(sel);if(o)o.style.display='block'}});window.bootstrap=window.bootstrap||{}; \ No newline at end of file diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/chartjs.js b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/chartjs.js new file mode 100644 index 000000000..f123e25e3 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/chartjs.js @@ -0,0 +1,28 @@ +// REST Dataware HTML Editor package classes +// The exported class is the source of the component implementation HTML. +export class RESTDWChart_Bar { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } + static mount(element, options) { if(typeof Chart!=="undefined"){new Chart(element,{type:"bar",data:{labels:["A","B","C"],datasets:[{label:"Values",data:[10,20,15]}]}});} } +} + +export class RESTDWChart_Line { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } + static mount(element, options) { if(typeof Chart!=="undefined"){new Chart(element,{type:"line",data:{labels:["Jan","Feb","Mar"],datasets:[{label:"Series",data:[12,18,14]}]}});} } +} + +export class RESTDWChart_Pie { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } + static mount(element, options) { if(typeof Chart!=="undefined"){new Chart(element,{type:"pie",data:{labels:["A","B","C"],datasets:[{data:[40,35,25]}]}});} } +} diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/chartjs/chart.umd.min.js b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/chartjs/chart.umd.min.js new file mode 100644 index 000000000..f7b5816bc --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/chartjs/chart.umd.min.js @@ -0,0 +1,2 @@ +/* RESTDataware local Chart-compatible lightweight runtime */ +window.Chart=window.Chart||function(ctx,cfg){this.ctx=ctx;this.config=cfg||{};var c=ctx&&ctx.canvas?ctx.canvas:ctx;if(c&&c.getContext){var g=c.getContext('2d');g.clearRect(0,0,c.width,c.height);g.font='16px sans-serif';g.fillText((cfg&&cfg.type?cfg.type:'chart')+' preview',20,30);}return this;}; \ No newline at end of file diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/datatables.js b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/datatables.js new file mode 100644 index 000000000..7e1aeda70 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/datatables.js @@ -0,0 +1,19 @@ +// REST Dataware HTML Editor package classes +// The exported class is the source of the component implementation HTML. +export class RESTDWDataTable { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
NameValue
Item A100
Item B200
`; + } + static mount(element, options) { if(typeof DataTable!=="undefined"){new DataTable(element);} } +} + +export class RESTDWDataTable_CRUD { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
IDNameStatus
1RecordActive
`; + } + static mount(element, options) { if(typeof DataTable!=="undefined"&&element&&element.nextElementSibling){new DataTable(element.nextElementSibling);} } +} diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/datatables/dataTables.dataTables.min.css b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/datatables/dataTables.dataTables.min.css new file mode 100644 index 000000000..57fe56b0b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/datatables/dataTables.dataTables.min.css @@ -0,0 +1 @@ +.dt-container{width:100%}.dt-search{margin-bottom:.5rem}.dt-info{font-size:.875rem;color:#666}.dt-paging{margin-top:.5rem} \ No newline at end of file diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/datatables/dataTables.min.js b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/datatables/dataTables.min.js new file mode 100644 index 000000000..fee1773b1 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/datatables/dataTables.min.js @@ -0,0 +1,2 @@ +/* RESTDataware local DataTable lightweight runtime */ +window.DataTable=window.DataTable||function(sel,opt){this.table=typeof sel==='string'?document.querySelector(sel):sel;this.options=opt||{};if(this.table){this.table.classList.add('table','table-striped');}return this;}; \ No newline at end of file diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/README.txt b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/README.txt new file mode 100644 index 000000000..3ee7e9ca5 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/README.txt @@ -0,0 +1,18 @@ +RESTDataware PageProducer - Component Palette Icons + +Format: 24x24 Windows bitmap (BMP), compatible with the current palette loader. +The palette button shows only the image. The component name is displayed in Hint. + +The icon set uses semantic IDE-style pictograms rather than text/letters. +Examples: +- Email Edit: envelope +- Password Edit: padlock +- Search Edit: magnifier +- Money Edit: coins +- Percent Edit: percentage symbol constructed as vector shapes +- Date/Time controls: calendar and clock variants +- DataTable: table + search indicator +- DataTable CRUD: table + action indicator +- Chart Line/Bar/Pie: distinct chart drawings + +Class registration remains in ../classdefs/*.ini. diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/accordion.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/accordion.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b1569673b0ab0b2941df26c67d08b0bc704d7f38 GIT binary patch literal 1782 zcmbtVU2oD*7{(hfz4j;g3;Y3k?T!8zqf2yPB*w(Vi)Ec)KGk$UQ|*Fk2pNW33ouB3#KUG?U~2-)*gy@N5rV)W71r$*CpH^I zk~BrJ2_kh7fSAG}Q zsjkTKAy)?pRD~L-1w2VtfZr`iT&q)MJ2h@P*e=WOEUe0{BfYOfQmZvXp2VVG7DTf? zeP)%$U1Z*CwombJj7p4r%4_j2H(w<01rm$C8A!VPUl+Xjr7%@AO*P6HwsSEqwPy4HLaPV?#?|HP9tKiWP_JjvIn{{O#zAe3uF|k}V znwg88+g>6{RHqYkcKZAMLBdvMDBHQB>sC^4^n;xYIXY*YUZ)D>_%_s_^^zjjK)4Dm+^2HiT0;8+|u)Hu@giX12|~ zZ|+vd5Y5y+<}$uW$oV+^YCU=JcII zLLsa;-ySlP5X-0c@q6gyJ^z@i-{t9B@#rv*0wcrp57IEYES~;Po4nvY4WNLt|Qsz$jzNtsI0KBTIr}139Vnz$^)Ji^tFsQ_{O+_4FQ3S4^qMLB81K dB8|PPJzje?_Vfq5*egSj-ztYu2R(Ouv;&-%>HPoz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/alert_primary.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/alert_primary.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c46747dfdedf3047e6055661fab04f187d01acea GIT binary patch literal 1782 zcmeHEF%Ez*2&{{vvrq5^KET~SJNPD7C8ZJq*M>N%O+b3wU8P;tqfdFwlqZU@M3<|S zHtO#KM6^3vmdx z2Zs^}zT1bUYfK$^5#c}|0)@Z@q_sIL(N+-?eVk}@5jQbbEY#Wje`KrWR7WH~2j0L1 D`=W|n literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/alert_success.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/alert_success.bmp new file mode 100644 index 0000000000000000000000000000000000000000..84293557e54b4763e016529d129132e3e9c9df82 GIT binary patch literal 1782 zcmeH@I}(5(3`DW9wDt&|zysKOXA93{s~Ms@m=M5E2{VDPSzaP+(PJp2>sDKfM8Bi zK#2B56@5cU;tBj9Xmd&T5{_s=*TNy;)C4F3^==-fg{Uta9y?@WS|k=929a2POBc^^ RP58M~zJsZgUmzM=l>_K#7|#Fz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/badge.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/badge.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3abcb21394947792cd505843c8860c0f53f034af GIT binary patch literal 1782 zcmb_dUr19?99|Fg*jp3?CcV^yK~F&xm}W$w5vF@vv7m=6$h4V%k};eHYl`A{LISZdj{)LrMC+iknM|4-lD(c5xU#CG}4;oN(_?>p!BJLmpxb{@CI z5W5bb-;1_mscnjl42HLO-?x>v7!jQ!i4;VURX~>33q^)Rm(u|pI5xQGn+-720cIvJ zwP`U7PckL<5cCX(9iX;m0 z`4L5Jzxs#Wh2?1?>*oSqS4Y*vc%Kqs3AacTp2!@LqgpRGbi-XN{Lkh2}H4_0}?ErtMYr6=x2ZE7n7Oo^;hB zCwTkdr6sdyb9v)Qm1jTocHgnzxbLWIanv={Sv%TVkjU2d^3ui=i9R&0uah71O1I6= zd;wv2=(P}-C0vBa2}e{A&9;nZJq@6(hzn__C+DW?ys3K6;7E@e4n_UHBJ)#W-z3ZY zU>Q${nF#r&Jf4B-yLo2&{z#P7wnh@;^8+7j4+4)0;ieZQ`PX+ARO~WVq#G;$Mb&P+ zDr?SV7N)S6WcwcfU66$kGceZs`P;j}@xQ?B!04Nw%orRrli1ghaDJA2FomMZl(|~3 so!B+M3tg!3P@s}Qcc5f_J*lc2@JUG>Lv>9_T}@$~r&d~R{Ez?6A2;0_9RL6T literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/bordered_table.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/bordered_table.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56d0bf259b74b4d31f4bb172c02644393cf4a4d6 GIT binary patch literal 1782 zcmeHDu?@p840D%^oqIwr$N|~=lTYiAo4PiH*$RY+2JzG&hyW`RO)8Y9$7?7pM&vur z?Q<@zD&>j$`O4FXNbjS^chSDDzl!T?tqFAG*Br&6(iXKM{6!+5bzD{CE8=`|99Pv} z=Dyod;h4#*$cn7^+2I_zWyTiT TqIM)!jv`4mwjn=@^%qzGqJs@G literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/breadcrumb.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/breadcrumb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..54ae959d1db460a382c883ee06ffc9c6094a9197 GIT binary patch literal 1782 zcmd^A&rcIk5XOr~&mK*@_!sEG3u!cZP-9~BU?L_07WF`+K?Ou34Kx;Fi1A<)B4R@j z#2!@I!U3b!M5C>xibX693hnN;cDL>B+wN~?_ifj;3EG8j+S^W=qR83Pg z6?C~6MzC8_X{gSRs#uQtLDi+)qGE?iBREv^Xqr;wWgf|hvqAzYK`4j9Kv2BaKt{_Ihsb`V_t|i_+U$ z6VF=v=Gxt}c4u&4R6<22O$b~;;88IY$U&aI87R03yORmNJ zlVdhDFZx=Yh{*CJ!_)b|ITy9~m1XH7o40rtuh_Zx5)PG`x$8dA=)8I;^xB0jTw&SO zz3p<_X}@DolT^)U|Ak98sc1D%q}PsCV;0Zwk^OGh(NM6&!>(NK-9FIK5pWD?P!OX6 z3tfNU314W+1m}3-8&9k+4R&VzPhu+`-=n4+onW%7@z~?3@jV)+%r^Js6Uo9FSxBb+ zXZop+rFala8+oQ)_(G23k)D-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/card.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/card.bmp new file mode 100644 index 0000000000000000000000000000000000000000..04c1b07598b1498be9bce3859f0eaeb56c8bacfe GIT binary patch literal 1782 zcmeHDK@vnj3>=p|I(vc_>;v5W$1eYx6741Yq|<-~iJz-mRl$dd6eX0j5{}Y<1?^-eR)r{E`#I Ca1MC@ literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/card_with_footer.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/card_with_footer.bmp new file mode 100644 index 0000000000000000000000000000000000000000..04c1b07598b1498be9bce3859f0eaeb56c8bacfe GIT binary patch literal 1782 zcmeHDK@vnj3>=p|I(vc_>;v5W$1eYx6741Yq|<-~iJz-mRl$dd6eX0j5{}Y<1?^-eR)r{E`#I Ca1MC@ literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/chart_bar.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/chart_bar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d829037a0aaa95f0bc0fe7cb98133e4bd3254cc3 GIT binary patch literal 1782 zcmeHExeb6Y5DN_@H6t(q1JJWG1vAltbq5x5VTFP&Cnd4v2kBVWqc1Tt?g?kSPZy|^ z4f;Oh2_vqvP4xzzoqc#s_qzo)Pkm3SXviKzTTgC@ixTSh!+*p$L4A*WLV`lYY^Vf< onxIG$6e?yz5#+!IoMr-(H4@_l#%v_U35?lDh;xjsNk47i0%k#|KL7v# literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/chart_line.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/chart_line.bmp new file mode 100644 index 0000000000000000000000000000000000000000..32f1259fee470fa60ad554e67de6f85bb17f34f0 GIT binary patch literal 1782 zcmb_dNlX(_7{-f7&&I?PF`AfoEffM3#^uia{{(Afina zmjJb`(n3JM7$7XlA`%KST?X4}XX`BQz43q3g+(kS@#TMi-tvE6|E2GrljoG(Io8Mn zeF)~>T85yop@Wzhfz}jhN0J6wBpSg;5u)M13eWj@E|9hO0RljP zV?zT^U>ymvhNhZ38~}*~8Gt9k0a}buf`cGTaCSlnKmbVLR!;bkA5NCM-yBz}-Ph~g zC3V|NX}#le)%2^600cN>Rh7kPIHb$*uENUT=#0p4f-fj8hcb(>5{fRe-G!C>FGdu? zsw4nUEW)Y0=qjl*^<;F37`N4Z6^}v_^OD4`@kAwO@qMJ|dL(Qbgy;s*45A~d<63eJ z+mv89C&W|sfSX#_z{3mf(guZLM+#0YwLb<=C`8qhE`gf{UN3M9S6lEzMOSf+At}C> zExq}MsQJTxvtiUT(2e&;=XV6O2t+if4Zc@Dji`}gY8yvNlxGq6%(6@ zv-o`kNU;s_%_VBWVYzQsgzptsDk>sqZI zlL#ayZV>fv(cy|R5ECmZl2z)@t)|U+=0!(QRr-grT=d?s(f1`s;eBbc1Pu@y$Wz`l zaJO~*Y3EqW>#-+qG6@*8b$+$AJBq4RUZBrh7NG_G_Ag_MbV>PccTTHhp-HsmCnN+?inSF1u>?|~z%>6qB)Q?{Cb|FDb8nU0sSKM&42Yrgi%JuFxaneNOfT$D25_IIEDsIB(R5)dq9DNU>Q1r zM#DZA67(WL-vf&mAOHk7LlNK!j3a&zMc~{+Hh@I@Zh)tb1GEfHr#M)eVVPAzGYkdW z(QD^n4a))qfIM7?2@>$a%-ySF#{BAmBXt8Mr$Eey6{g}^i==+2qH(C=jHRr>T&#e} zlyyK-XUsb}t?36Kz#*!5JQfWH$au0xB=b+)j(L`14nKO=7x#wnFpA7Mo!2HD*0Ipc zVlos>1R`LHIRmIG5MA{2ie$)wJBEgF3psYjyGxga;tRv zOLhAs-3O1|khew`+`Mh24Ocb=Zp~pB@;6TugHw=boE4~i<90)iwEc}-?K{P~eWgIv zwWp+G+ab-aqB}h!K*Jx}6Owcx;hG#hr&Y%t-U;$z{P_E4q101CDtwMc{^b*gO z=e=o5dGv2Q9Cz(lvwC};;efO=v!K7QX7;jmzW=)QsH!tFU!Ps3$rAU9PEc49sD?gi zOyiHZmc^-rKdjp;0nzL%g1dwGuLOg;aq2sDW&wBw+B-T8^Mg|5KY3tlj^SJ*le{z8 zQuU5}@2~t~hM*Xdf&u0W{qXMLANL;7yeYD^T^4vwr{`h0Me{EZ4gLNy?c2r3qKjc@ zJ}p@ek{?TwyJa_DFCTeXY;Dxd0?$Bsx^orDIf`Anbw{(aP@gUB*q&?ew7_DP;d2=V zrrXq}O8X1d3mcElUidk3UmkHS9mnYeapi+b?QXF?tD@th_y3sb0#5+qcMRv$X*XB8 zUXt0iem*nriNoYz+Bif0L@}`1wWf|&^R=Rb&5CEw);yuP@LE^fj&rq7H_4ybRik@c z>X2xiobb5rckdLM;2;_#W38)EezER+!*eb5&wnl7^p*Un^YvR>8@8N2vHnAqVF`t2 z%SS#f54=Hg8DmMBAxMHmti7dYzkE`8e4VOlgQ{v{>scWBp9^ zQ`I+ZVBd(Tw+6+y$G8zePvg9U2i)b~A5WFWJ6xKQDRy6Oh1HE#ds iCy=bFt1ETh>x%f?5ufLQ#U1uK@6~zXm+?RRcm4#)*^zbt literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/checkbox.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/checkbox.bmp new file mode 100644 index 0000000000000000000000000000000000000000..fbd99aa366b75d9b2a52bdcff780feab2a67a41f GIT binary patch literal 1782 zcmeH@Jr08~428qek-10c33>qb-kG6iVl7W`d9t2`K#4Ef zNUVs8040>8LYNpU5_ljP^q3edJp-&x^BG2G0(ez|<@fPjFXROzsQd^c6%35XV_NhW SHaw%BmEo)hICTeCzQ7J8y)(1` literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/collapse.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/collapse.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b1569673b0ab0b2941df26c67d08b0bc704d7f38 GIT binary patch literal 1782 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 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/container_fluid.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/container_fluid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d7c56b70e146a618738c142ba6aca2184c7c78fd GIT binary patch literal 1782 zcmb_dT}YEr7`B@(yDkWVin5E+fea!w8DWKuu^fzoBJzkxDA6EHg%h^w%qpZ`(4j>&VHP>Z&Dtf^X_oo^FHVO`OZ6yHn+cl3^imU z=E36JM^+6DcIX`k=p+XrM4qE4h=K$N{B9u%Fe#hU1sHO_Q@;{x$yhWQTTR9lfdjE9 z4#Nb7Wh$)GKjW#yI+tezp5G;K7$z{JRPZggnM!S}7m7o|z9fo7l1OR16)CFxaUB{bNMPBmcb_OGWDFy zZmjZ5md|BmxdR-7{mkqGoo%$2@UWQ@hJ%9S9}Hr898hsh{-LdygaWgg^EV43A`(DUK_N6&)a?E+@qdaJmJ~N7gvu&ee*vS9pAlgBmQ^W;j>5l_ISuUbEn<@e^9LEp#87)E%A~YE4E$MSr%uFZrF4fsT;~`*C9}BtpLUlAA@Z vAOnW08e!vliN@|$eo9dav#I1#FP2|zPg8fo>IxZk+jEu```Hk6VB}M literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/crud_toolbar.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/crud_toolbar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..91bb313c45339968b33c6d87248946e1e37d1318 GIT binary patch literal 1782 zcmbtVTT2^36t*vY>~nuY1rZ}s5ez|JL{PLvT8su1K?Q$=eb-hKT5bB`Pw>)et*JF? zs}U@vHVH~WENaYsbK6ZaJG0v_J9TqwG_=FF!{p34-<~;V_Dg%Wbhkzu4>3Q$bN|nC zM_bj@II;iv9)C1POiU&mDx(TO2|-`fe-ZUxMgunj4*m-`BLsmu z71r@^AQrqLnKYH=Hpj}-K1{q zBO_l@DH$orq_jRfAI=kx{)Gp*A(_|no{o-Q5)nd5`hIIZsFij!hMO=s`3)opsnjpj$7oy= z!U;rWL25ktxo+TgQOJOX)6+y}=SE%K;`sO;bbuQn5;~!-8{jF|G2IOdK_K|(_^l|k^R=#H tP}hpOilhm?_gs${)%2Fnn)a6H>a98-@n430#o}K<=Q&kQ8~@{f=Qj@a9?Ad! literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/danger.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/danger.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/dark.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/dark.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/dashboard_grid.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/dashboard_grid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..99ca9bf38c9e0966081fe1bfe3a3febaf675d9b2 GIT binary patch literal 1782 zcmb_dOHUI~6s{YWuKfxA0{5aZKtapH2#F?kMVkPvf+iX_`V(|vMTBCaf5C+djVa}o zK7>fB=*oGtQyFKbbl!KyZ#wP8wgahw$(hr8?%eOoJ>R+av~O5F8)`fk;Vp!Q-sJhe9|u6dK>}5w zhHaW4FiPKrSW<{3+H88RdhcP|O#E&o8n3_q00@A9`=x;-dq$SmzSjwABF4tXGosh&6d|PSz&sPhOT8{>?jI5IBMj-1oI4z>RWl25N~nIYpZL* z%sdS}LPDI{fya|89>rtq>~^G}=L$mNLB}Ly@bU`eIjHlIiOQXrFnb>xpoY?L*KX2~ z4wy>=MqxW(KXsKG8dp}{Y1s`ev!-R&eJ?M)DM#Zp)K=FqRzH4buU7g?Lh!n)NPJ!}QQvS5`v!R0`WUW5FJ=?}c+ftE?s_VH Q^%VQOPv!N-6a4S|1$AT-!2kdN literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/datatable.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/datatable.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56d0bf259b74b4d31f4bb172c02644393cf4a4d6 GIT binary patch literal 1782 zcmeHDu?@p840D%^oqIwr$N|~=lTYiAo4PiH*$RY+2JzG&hyW`RO)8Y9$7?7pM&vur z?Q<@zD&>j$`O4FXNbjS^chSDDzl!T?tqFAG*Br&6(iXKM{6!+5bzD{CE8=`|99Pv} z=Dyod;h4#*$cn7^+2I_zWyTiT TqIM)!jv`4mwjn=@^%qzGqJs@G literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/datatable_crud.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/datatable_crud.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56d0bf259b74b4d31f4bb172c02644393cf4a4d6 GIT binary patch literal 1782 zcmeHDu?@p840D%^oqIwr$N|~=lTYiAo4PiH*$RY+2JzG&hyW`RO)8Y9$7?7pM&vur z?Q<@zD&>j$`O4FXNbjS^chSDDzl!T?tqFAG*Br&6(iXKM{6!+5bzD{CE8=`|99Pv} z=Dyod;h4#*$cn7^+2I_zWyTiT TqIM)!jv`4mwjn=@^%qzGqJs@G literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/date_picker.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/date_picker.bmp new file mode 100644 index 0000000000000000000000000000000000000000..44ea12ab4a407eda9b27fd8bcab4d6d254f9fffd GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCH}Xh6-u=VXASNgDH+n z1Y#1VEG}_Ol@JkJ>T!vWnu9;whDZ27VxM>t)7P{}KX}Z9OTigvPJ)P&N}?G8-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCH}Xh6-u=VXASNgDH+n z1Y#1VEG}_Ol@JkJ>T!vWnu9;whDZ27VxM>t)7P{}KX}Z9OTigvPJ)P&N}?G8KbfN9EbT2K_PTQIB>r8FXG^8ZlocZ#dJ9EA{XYRdcPNb0g;<%9j zJc#Q+_}as#zaF~rT8-Wl6 zBAgCT$OPPOG6a#;4hKRIh;Y6f$kM?eG#G}V>6k2t#~2172n>aD-votlB0J0mA|WLf z;rv$x;U-vrkoln{f39t7T5?+N9scbyy91%OZ_%-HI#y5MT&wy}wencQ(vdpl(fXx` zZFLjsm*OiI_U6wVu2CvYKIquj!}(ZE1e9ARtj8a(Zc?<<$B+!`^wKUL4Rrfik`B8L zFYTpSjgz@ABTkA}3;Xp5L^xj;uOpUQGP<;wCj+dW2r2W!!XnEG+_=o0|uAw@DhRDolhyG-S+q z9z{niH)lwR*F9}TxmlU1XX-@vs)cufC3ynD#Uzj_VKMOb&5Y}*iG#iE)g!j--nFRt zTxwHcUZW%GD}*5YB2G^t}bJLS95_NJ@fqOhb0B&#reR(Ti3EK zB!Y;FLT>(zE9ohx2D)3esVl8r?e|l^re}qB@+hCz=5hlSAI56SOF=9S7qGui+SK?6 z=Rh=Qh?)=Ty4tBh;X0G`?VBNN*3AF|Tvn;aM@KxtZw zB2hyp#!)6S3Z(z67dAHZSIj<~2<*}ni7K&a<*Y=VEK!HBMU~XN%DE~acrvU-6<@We zP`dF_+j@9EN6x9v;qUrtlYX;rZ$01b9bas-dM`wfz}E8~n&G!gj8$=u@hyngK?{oX dG0X?(SPdNyVv#-uwo83=cltc{%h-kg&L0sx>TLi3 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/disabled_edit.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/disabled_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dd3bf827c0bbfed1fd35a401f3805bb806136551 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm)Q8&GIWWpEMv=0KDI)xg!`VvL%DD`endh&31?;f6-yF^ZUQ#-klBh2I=B X_Yma5jfFD^YQd@iu6>j-v_b#?3sp{; literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/dropdown.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/dropdown.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c4dd2ac881a086b4e7e68c082174e73cb78e4e6e GIT binary patch literal 1782 zcmb_dO-~b16vd58*Zu@|?)(AnO^gfU(zth_QCJ`%5}`tZk|3pR)KCf{Es*pB+JGr^ z8ldzm(3X!rup6$dCFf-Y?bvV`ZMAqWEOQL(tSk;lLT#R^QY!_YpZddmJvEYc^%~Q!#aSNGUGBji5T*+?&fwHs$ZyTDoc1@ zQ`z|HWqWf2YC`vQK|b;5JamxE^3q~rIraxDv3M-{GZDv9$nWvG$KWW}Ss(%->Eycc zi`vIH=K@|ig5I#tgQY>eE*hFau%eE1uJDx1?sh2Ti_8VXk$?>1WZ1vXt|Ckv^eD>S zJEk*>3BS58+-Y6taV&KI3-*ZK=4=1HJ~>OZ&YZ)|6lU_t^x&havFbMFt;SWWR=^u^ zlBw5DG=664I!q6qr@Rpm@rg<284hlfQz6Ua8tD;b?BQ09^@I`NtZJR@vcSo*=X6-# zob^d9&lUOoLnR#Wg@dC4=Xk2p-F}#vkGo#CN4^dJt#he-c#;_PEZf|+|%N@gM#>zW`#41+M@A literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/email_edit.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/email_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..22d39b4e4854d4822c420fa211cc330bd2c96683 GIT binary patch literal 1782 zcmeH@yA8uI5JTlAW$KLJ2{J(X?4;3BcqX?AA;tuu^XIAn0W3i0Gmm@{^mxvf($*by z#J+v^(7IAym`_*kW<+_P>*p`9ynXh&dO?J1ty#okjwlj-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|KJ8NXA(=}@(oEo#iJOH6sFa9 z6yuQ^H3t|1qv3-;5QbLx09}g)FcUdM1gH#`6k31~uM*QhxL!B|Qw>A}zXFIXel%uHpd0ckKEA literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/flex_row.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/flex_row.bmp new file mode 100644 index 0000000000000000000000000000000000000000..93c6964e01c45176ae67351bd40c8255e30fd4f4 GIT binary patch literal 1782 zcmcgtOH30{6vd58*DhVSaAim|uGB<=?${Ol0SXZnC^Z5mN=u?3-%>~fsX`p_AVDEc?wsCx`_Ac``{v%pB`|wqBG)nC zA>8}d?>!MOCZ-?X>-Uj6vJk+tAz~uW2{4Y`uJIfwQ95y;zH@@!9^@3b!eO0L}?LyGcOj^uY$r5#S1rRwIr_CyJ%GneAto zK?7A=evji=Abezy=eU5jw?}qjE1mn9=lXjzqR0~+lU`R>QG^Wu;S(L464l?E^Ivp! z>$!HL&R$L4>4ycG@;sSZRVGWnh)J=_^3t+gpUmJ>gqB@{*CatZ*pE@i19UF zignD4TE-@HS}pBdMtO0~SZ67U0+Nt+Ea@rzkjdDT8fzanAi3c^T)@d5V<_5YlIya!RagJfQVXG00jB7Hqf5-3w bQm*J6Ls^jA`CQ$_IZvd*vk~^M|2sbbrCPzq literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/grid.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/grid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ac48d4945d63e2550b2b04fac7614f51e0f9ba49 GIT binary patch literal 1782 zcmb_d&2JJ>5XXy0&;AJ}MvWh>#xy2+@TT6ZNk43*#*fs*lU~%+rooG?O-%Hx2U}VS zF(!?zfL~Op0Sje8V-#&%x(h7`g+liee{Uao*-~gQbu&B6%zN|W&CHwG6Q_#XEymLf zz6`;r0!Ib~Ik%k5rUZGdq$)~-gw1e)BZb1*iur7INhs4t*UJr3S%(K4;SLZGPAE%j z6`X(j(cuVpfFP^LhAK+{NXNP9+pVA}LT4$x>TC1bE-)3s^qq5)H_yc1y5OQJ65MHN zkTgwGRjKs6_xQWP-q7gK+_U?kkwMDe4_$L!ZeeQ3SPDL|**o{9<56AL)533t163)l zj&~o-{ESsamiij-+N@PZsE(dyVSWa}MjT_w2XIZ680P~X_uY1)D#WNOGPsn_Ijl`0 zH(MLW+9X6i=sKcQ80UjtcYg;_HDW}S!KKv|1IJ$vXX)D zA)tsFB*uin7yK{By7nid_40FQ`Fpr3gk;q38R)7qLai4U>WYj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/heading_h2.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/heading_h2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0d4b6297c732aa5720d942686818563c402a1cdf GIT binary patch literal 1782 zcmb`ITQ37a6vxYh%Zpb&f_DiK2?<_=iZt4$ZjC6d@FMZ%K}aMhaS1A-FTMy5>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/heading_h3.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/heading_h3.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0d4b6297c732aa5720d942686818563c402a1cdf GIT binary patch literal 1782 zcmb`ITQ37a6vxYh%Zpb&f_DiK2?<_=iZt4$ZjC6d@FMZ%K}aMhaS1A-FTMy5>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/horizontal_rule.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/horizontal_rule.bmp new file mode 100644 index 0000000000000000000000000000000000000000..09a4fdaef816e3a6a342a12a8eef5e84952619cc GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9@9$p_^#AXle?au-H?ipNAD|Yv zb_fG#!naQ!-oJYG?!}XLFP^@8i5CGCym$gs4AcVD2saAI{`ltQhgZ*k{rLXp_irK* zP%%&oP$R@BpxeHE{_x@T^Z#T4phlo}pdmm6bm6a`KgcrXKTso3JJ1kdr~*R+=oj+L z0cr$lheXX_Hs>Gl;Qv2hP|(z0zkdJx`u)?lAD;=LuRlKh`1K9bJwJbb2MVs*)9+Eh zA5pCwS}BhQg;y*26pJ*>js$A?{p%-kd_mIBzSApjJyeiZfocwb5#H>?Zh z{GC%(r94r8T{&wI%X*GuFVG%r?Ax=)&bM^N>HW+hsjs#UNB@L<4)_RImrds<$54bA ziV!o|oh99bnV6JTNsdnO4(4xeWkN{rb7GY`9;_IDNxM&$iR3IJAENIb392d?tAFPJ eE@o_GI?H6f9oII?(;r=hl^7*t_Yv?E@dZAdrVrQv literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/info.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/info.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/input_group.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/input_group.bmp new file mode 100644 index 0000000000000000000000000000000000000000..df932b8e17796740e8bd6e78029117e51962db08 GIT binary patch literal 1782 zcmb`I&rcIU6vy%6(X)SoM@@u_H?PK%#CY>!qd`JS+>-bM>A@c)97L2v)QB83fwr_F z8ls_)ph7}`P>e#M{IJ>Cc7L?pc6Zy|otgS(w>AibfOhiPm&xvazj^a^-t5`)#?d-w zG(bE7*YV1A#F^FAO~Ugp$K1<#5dyI-piD4C)6fn@Rp^+Qlwc#DQ-owzL|IWdFbE_d z1Ua!y$OPt@6ptaRLk^ID5ajN1z?NWqNRP_vAY^ih%> z?gODLqnhLcPF0^wn$<^8t;bR6(YV+h6`d&EiU>D?JQv!DFNA!Z=lCMbz2i*|114Pt5{AO8K%~yTe;;NZuR$cJ}f049;((9G8<-KO;q zS9bfrx}YqJJj(=#@tUGpuz5zpA+G64N1L~uYXR>1ylu@_Up;%OW9GAcU2dK4jPR*^ zaZNVX6-Gj4-*o?R>Op+=SEbI-8mc7dCheP&0t@osoH97i2rMYq-Xg1 z*tfoo#HE)T=X%%Abgjx7Dah=*gO9rpa|Rxm$@G6yUQcKGr!x?HC*_`~)HAUMPbQ@9 yacNUFA>ryi{GUGE-WRUV?mpe8L)}LNG=KUFj-Z;HW3@Y1Yje&!zl<9EcYXsT8ZSZs literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/kpi_card.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/kpi_card.bmp new file mode 100644 index 0000000000000000000000000000000000000000..51ac1513ced723f0feb3c80b34fbd711097b8ca2 GIT binary patch literal 1782 zcmb_dTW=CU7_Bcp`s`0oA6r|kv_)xp6KLb5k~I3%i@n)4#;DQw?u&^J76ltjC0hT5 zm0s+{Qk$5V_-0_C3k$m}2(x$3uu58lg{YG=lVO?f%=x~VJ?n7ik2Vxr3&s=Z$A9%B z#aTncGX7sZX7=Jj44NXFFf>&MRHa^MDnd%(<^&9RQQ#A?^nNtG&(wh^79#|KB`VA_ z94jQ^GAXE%L?K&(t|4+Ej}Qc!RM3{s3PLh&{8d9B!a)K+p)3(Y*TIxuUP+A2B*tf} zVq%URo)Q<|6xZtrL^w!L)ilc>5s;9b-DpQo>hTl)#X|a-FFo%s1Ml_o-j_hs;i6QA zfg&K>JQ~VF2p$Uaes*LElWGl$sc6H%M(pq;CJ=x_DdWlbU$Hl5a00m$m*JA)0nnc* zPRajJb6H(gAt^C2SCz*Xh!^$TpB}x?bjoc%<7{sRTpcaF=NdhI4nCFCC89wOc*bWf zc=ku9q5RvIz3ugt@aD(x=DLZUjkUc`TeOUdj0H7$*s)vKP9=rX?ZQMY-g%H@1s>Ve zqsPqa-qeV_@uai8rO$SnqK%G7u-Ddft>?U`DWWfcN?PZo>H62t;f>Jy?X^%DwpKrc z*FuV}3AO4&&kNhsYW(vBt2*P{hbNV6PD&;Smn0ll0W7O#bLppEi*pxWFGXx!@xdFh z%R^OhX()d6I^%G1cOF7@#d}D3&N`Ux0jASsg|7ant&6++$cm@g9_#nSE?%*MdobG8 z&E0-bfk&3{Q28E-4R|8W_DE|dgjGf>eGWZv2FmmMJuUMMg^7uaZ;_xFT%zNj2)@e% zf@F6OB(RQ>Z-D2&_!zGJAzy`~5>gwI1QR~!tLA$IszW}{GBBm8pdW$?K5tS{Z~TYv F&QFdUz&MRHa^MDnd%(<^&9RQQ#A?^nNtG&(wh^79#|KB`VA_ z94jQ^GAXE%L?K&(t|4+Ej}Qc!RM3{s3PLh&{8d9B!a)K+p)3(Y*TIxuUP+A2B*tf} zVq%URo)Q<|6xZtrL^w!L)ilc>5s;9b-DpQo>hTl)#X|a-FFo%s1Ml_o-j_hs;i6QA zfg&K>JQ~VF2p$Uaes*LElWGl$sc6H%M(pq;CJ=x_DdWlbU$Hl5a00m$m*JA)0nnc* zPRajJb6H(gAt^C2SCz*Xh!^$TpB}x?bjoc%<7{sRTpcaF=NdhI4nCFCC89wOc*bWf zc=ku9q5RvIz3ugt@aD(x=DLZUjkUc`TeOUdj0H7$*s)vKP9=rX?ZQMY-g%H@1s>Ve zqsPqa-qeV_@uai8rO$SnqK%G7u-Ddft>?U`DWWfcN?PZo>H62t;f>Jy?X^%DwpKrc z*FuV}3AO4&&kNhsYW(vBt2*P{hbNV6PD&;Smn0ll0W7O#bLppEi*pxWFGXx!@xdFh z%R^OhX()d6I^%G1cOF7@#d}D3&N`Ux0jASsg|7ant&6++$cm@g9_#nSE?%*MdobG8 z&E0-bfk&3{Q28E-4R|8W_DE|dgjGf>eGWZv2FmmMJuUMMg^7uaZ;_xFT%zNj2)@e% zf@F6OB(RQ>Z-D2&_!zGJAzy`~5>gwI1QR~!tLA$IszW}{GBBm8pdW$?K5tS{Z~TYv F&QFdUz-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/lead_text.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/lead_text.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0d4b6297c732aa5720d942686818563c402a1cdf GIT binary patch literal 1782 zcmb`ITQ37a6vxYh%Zpb&f_DiK2?<_=iZt4$ZjC6d@FMZ%K}aMhaS1A-FTMy5>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/light.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/light.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/link.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/link.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0ee9204b87ea0a4ec867b3cc58fb2563b265ab1d GIT binary patch literal 1782 zcmb_dT}YEr7`B@(yY8|qB&uDgq(KlXe-iU23dN|z3njYfM?tBJh_Wz*gv5*jksydg zK|uv|;T)L14YfJj#J{EcbL!^y?c4V4oNqnneBZXxU1;oZzQg%>p69&hecyAw)8*ps z3|{ik9>TX*{dVzQMn*r@2lgl*2cn@-2{lFu+K4FZs3wS9BqCEH`h9E8CGU#EyW-q- zb$|jQ=rkIECFrla>;zWruz&(0=*n>*O9|Pbh6)Ff(Ya4>kpB}=SfDFj-Hwh-sZ0oK zDM2SD%ZaU1=wS6PfQppCr3qHD6Gx`dNrDnRb>G0;v`zP7y1jYkS*u(BiG)RlkeU8g zoyfW;2fiI!U9jVhT$ zaXJ}?p(M2G9&RYrpFLu3Z}wS!Mg@P^<8pp|KTv&qq@fi1G99-=^|NakLwEn@zJko( z?|PUB9Kvmu*WAXsg3;>y@T{5b9WU$SgZkpE`Q8ppcwNg(Cn$K`b_}N;-W;kuMZ+P6 zm1QDHv({fjue#rs=jzI`^^b2`Op~Gzz!HVQvDn0&y3wm;a#ZrIx+1{<(^+v~-q>`} z*jU3gm~#UDjdR*#TFt)Vd`(gQ(ZZZ8ttQiIHercnzD%u8?|!d2K|`W%&BJs=)gE(O z)8M6(L=;$(5JIGg-L^QP>-kub`=KIdxbwl1Z6Ok3VZyo5jyGQ!yH+Vjqh1f}VHX?+ z#Jp$VTVKI`o9-q0$r1`0>q~~t=L)7VHmSG{&NO_{7ad%9-Gw>TKhWX#0ydZ*-O``Q zn(OUAtPzV1%cQ0Ao}n@u;SSnuh#xbRS94qANPUUq_cEPCyp;O|--^O?dkdrtWg0{l z34=P*-5O7oWKu~R-Z1wn)7f;t;(6{fjV-=;Ztc2{9PrOf0m({yRT-%*pWLjYfVbi? s!*gk~LL8YwheMTkDfb%vf9R{RCXyk6FhU`&z1hA~CCv{;X+}pf zBoJy8Y6}{^|5|PJWDr6Q2pkoXunCM1B7$+wWnt`Fd1{3-rZXXg91xr;P6L~IT?ihb zvIKY*36ihKFwxO8Y-U!Efe^(Q$*a!k82 zwKu$Jj3d6ex>%l@-d$VTT3Lwu&g$a&{A|J4Pvrm$yhJ$_ukIkoXo-3hCwa~!3`wem zA(hXSmdcUqyq%!3x=#rXr39M)bN+khjPF$6=O?ex%YE+DH}DOjb#yZ9={p+r4RGRp eOsJ~5-{Y^0sE?t$_NA}(vCnIi?2W(p?|cFU6em0Y literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/modal.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/modal.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0e2b936a784b84501158dff0f20bd83382543f66 GIT binary patch literal 1782 zcmc&#O-~b16vd58*Zu^5fqRV!iHK-obRi(15Q!iV;|ghP>0q&?UkG#|A%=|@qfjfA z7U>v>N+1vuBVXbI={L+2XgkxHH#44g3{Wh!!G$m9z1*4Jb9(Qad1ua+CXW|o#%Zjl zFi-xT$1+h-5slxcPN*}Jh(!_w6^cY;fQW@cBB1Qj)c^{~?HC&gFrjrO#Z#fF@_Pv6chGC1iKpbuc4Nq!GZenD<40MPqjlfU!(WpAzCWE7^Bi$Sy-}^j+t3PzfCtQ^XQD%*%t=J zk&tr`UT~FBXc@cr7oA$$w|=i8%d$wY?m?0ei*XLkV&4kYQ52a-StUVJQPA3d(0S^S zC0P=1a^*b`+>(Wzg8QnoEe`s!I?BGlD^bY)cxx;(x}oU&kI3xz=-lc7gg!3~pVP3j z%ZEL8huv&#ZzDupc=3Lu4Epz)=Bjm z^_dPNh36FR5G0a{EFf)~_SRQk+pmLzhD)EvT~Sv2#7J578oNPj@5}{*w!2enr8K>! z4jk%U^J5UzbDH*zNI*aV87Zrw-C;E$ArJa2#%|-I=g;~k@L@|CC6vW_)5Uheqs6=97s$fu*58_gNT3jKB zh;>6D2)IGmiUq9@hzW#6!(s&swJp+CD3!MFy?WjoGd^)ooXkw_n|tq>d(Yh5w`P-b zqK`P1V-LWZ{&h_dB_E$!=yj9H5)H9&9yg|!W3juOj(?ieQ3P@E9P1pm4}CD$EJmB< z!(UG$T;K?I&f`KPkgcWx7E%4b1Y7%cANl5!CmA8 ziBRpYTz+*9N4OJKDGoKRX)RDb*nRl+hBL)+&pS%UEmTV{CBiryp676GviBvbLuBcG zr;B2*RUSQA7!#$MedNx@p%D{sJgghZ{t1V7x*U76mM5u0?W2R#*laf_a)SU)Pk1jN zzcD6_2P&A|t7CRuS}^8zLdIKyZ3F;WZ*JeLoXR|u-`1XL*4Gk13MIvX3IQiv4J@j^ z0-3mz6p9-%cBIdhXDpF1bN6Sj+RFH*=0yyC>W3Mjg5p>$MjYB4=I!VG+ut`JHV!Y( z3zd-nLKTuWsi~);Y>CpNiIGWb{EvKg$20Nj}IH(TEd(L<{ z@8f6cxEl+j#ekic z1LChN+Z4RGIPX>lbE4p8jyx(%SEYGlYK%HJ8PnvSnnl$jN>wGje zGNw#TS{JxrclcUeO*JeJTb=5*$H9f?_>;&@{3uQ^L>8P+SknsycM4Xs1l&w=a9;TT>e`!~Po_0ZTHv zjV-8$wEMENCGpiQ_W%wh?jj}x2Q6q^ACmyUSg39336W{;w2%E|U*%C3Kouv2{l2gM NpFS`CGXBGV=L?Do;t&7; literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/month_picker.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/month_picker.bmp new file mode 100644 index 0000000000000000000000000000000000000000..44ea12ab4a407eda9b27fd8bcab4d6d254f9fffd GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCH}Xh6-u=VXASNgDH+n z1Y#1VEG}_Ol@JkJ>T!vWnu9;whDZ27VxM>t)7P{}KX}Z9OTigvPJ)P&N}?G8-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm*@#4%MuL~yCcB~BxAfYwpPJ#c5k8E6j1C625Nq6SC;1#zjzC63h`WCM{E q;4vRf8JvsDUR>gEjc5#9>fuf$iGgM~kV}$wxMECmMn#512mk;O;a!RV literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/nav_pills.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/nav_pills.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0663cb2bd45a2c3e82cf14392b660bcb4bc1c08b GIT binary patch literal 1782 zcmeH|O-~v@7{~F_W6ypBKS4i0@BJ)l^zNaJX-`dTXd;H7)k14!c>s6s{ZFZSjGqHV;FcDV5VU(i4`COo)fI` z{fM2@l5D9UZjH3|DU{FJIi{&AvJ?-&h$6EET;!$g_2u+&ih<#elKVTGtC!^xk2E>? zEQ0k)F*)3S`q>Hl{-)Qsxjso9OuL=nM17u3VIB*JNBoO3-mS!v-|ZALzo9~Fa&jVu z>B$e$f}hTq`B>oC^F9*r)yhQ{i3PoDvFJ)P$c9BR6P|LTP#D@cKSzeDCqG!4l1}Zs z?wt!yV@TvG{B}a{j*cAeeM8?+Wm8i_pIjRKBwIM=m@R%?K72Q*mI|BbjBt(#)%Chh!5S(z$ z`o=GERt?Y6zp$N|2^S#z^z9savUojUknm&G>W%xP8M%MM*g4Qrf(79nqrqelj^YVO d{+EN`6B^^-3hKx`*13DNGxt3GWpv=ba|_ouY{viq literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/nav_tabs.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/nav_tabs.bmp new file mode 100644 index 0000000000000000000000000000000000000000..627310a4e27d738cd7027bb68e63e11617efd672 GIT binary patch literal 1782 zcmd5-OK%cU6s{YWuKfxA0)K#e|A~nkSKXM{CUw!6_=t)Ig+wTcZ7q>Up}dCIP#9n+ z!)sb?tw3o>VL~QTm=}IC1Jt$}#jx>#8rO7d zZZ3l7@f*g_12HL*2puXi=7GRZr4yh|GEfy+=y9h<-@7Nx?#a<#YZDLv0av5}GJ)M` zHDqKpr2qmT;6^#1Rb+Wej!`&(8eH!Q3i&q@0|mIz)&G-6g(wP!HvdtLFjYlqv#;y8 z3EEcuutHO8k!Fi|O-luqDb$MeNEwMJQmsBPNq@` zXgs)?iukihf=WcP2_hX0#kV|}SQs`uIWijayBgoVf(P&m=QTLvV%{#{hIR-y0ywVA zuv}1i)o2@@o3d{)%>!!bf#1DhEHM|z=*rvY zdrW@pQC$v;Bx;}1<$T^e?p1O_9HpuX>`s1p-sk$HihWt&@kUUw(5l5$&Ze}tqc4bj z?{_@4XAe0#sSNs1zL?G|-2c4pkZ_aqI7t%8px0)4T1Z7PlkNR?LuAS?^Kl}BOmR8(giz8 z5WNp@0C>ss3m%=^fNKy%nb?M5>^^Z$mgjvQ=QD|!$}o6P!c6Y5+1;zNx##s?#ti;D FKLCY!P)q;- literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/navbar.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/navbar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8bf63b01ca52464f47c13273f3d9d386c1753882 GIT binary patch literal 1782 zcmds2T~E_s6vi7bz4jldf4~^yjV4BkUsp!CF%dHfl9-4_jQLnC!T@KmL?4LNY%YEgn#E>kJ813&Je)?$SSa83^rrXtdG1I0%EZaE73QgZVP=(k|ZG~34&r_u{H9NC<-~X Sk5#U(R;JIZ-{ZgkcYXoFSRtzb literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/number_edit.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/number_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..93c624b24dc79124375f07c4f27e69cbfd4baa95 GIT binary patch literal 1782 zcmb_dSx*yD6vh`HefB4q7+;K{uNtEQqC`avC{iPffv6w`h$R(jppp=+K#8mgASOr@ z5H&2eic2KMiX?1>F3{2`-Al`~)9K9kbp|Vv21~-tnXliubI;dvX6`+6G@0BP$B%g6 z9$dTEt{ps!i~E54pLYotzYxICK^Vt`fE4N5l0^b}5sGC(%gq1ji z3r`h>F zcbRT<84-wZp)Ns3uC%4ME?}OdIg>f8EDT>DNGx0bc%0koBkWGN(zlkZXHj&XsB9OS z7p%n6$nbD+ezrk7H#I#2?Ct3;FD?L?oSXu-H7cs55-cn0C$gjI$d%UgcJr%_#)6#8 zjFgjA;=9t)JHVn`k?33^NJVKO@aDDjD=7(molVj~M^@(|65CK0@;TqA!@R+0mPtxM zgqNsRtLtiHaKo>M;|AXibhNdA-0L+(%?CQEO$LezjQ^S_FDdkst9I84@S{pu^FRV( zb+~~qUp#+WD-TiualbjL4qq41-CCC~O3OHN;(k$nSz#XV_Vvq|XA?lg1z|Vu>czC= z<2`Nlo79!sqz?wEpW_pyw{od~-{J8BRqux@%Zfp4E)TG~tG%|S8s|XVw-hxW)OD%F zfWnOy`#dEO1Vz9~l|~@lgyARgZr9j7KLKAabJZpT|mDvO*7?7)MDjA!`5U zePLrmf8H9vi8vq7ZQ(xVlKF@zLw&A<;8*LZtH2?qr literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/offcanvas.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/offcanvas.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0e2b936a784b84501158dff0f20bd83382543f66 GIT binary patch literal 1782 zcmc&#O-~b16vd58*Zu^5fqRV!iHK-obRi(15Q!iV;|ghP>0q&?UkG#|A%=|@qfjfA z7U>v>N+1vuBVXbI={L+2XgkxHH#44g3{Wh!!G$m9z1*4Jb9(Qad1ua+CXW|o#%Zjl zFi-xT$1+h-5slxcPN*}Jh(!_w6^cY;fQW@cBB1Qj)c^{~?HC&gFrjrO#Z#fF@_Pv6chGC1iKpbuc4Nq!GZenD<40MPqjlfU!(WpAzCWE7^Bi$Sy-}^j+t3PzfCtQ^XQD%*%t=J zk&tr`UT~FBXc@cr7oA$$w|=i8%d$wY?m?0ei*XLkV&4kYQ52a-StUVJQPA3d(0S^S zC0P=1a^*b`+>(Wzg8QnoEe`s!I?BGlD^bY)cxx;(x}oU&kI3xz=-lc7gg!3~pVP3j z%ZEL8huv&#ZzDupc=3Lu4Epz)=Bjm z^_dPNh36FR5G0a{EFf)~_SRQk+pmLzhD)EvT~Sv2#7J578oNPj@5}{*w!2enr8K>! z4jk%U^J5UzbDH*zNI*aV87Zrw-C;E$ArJa2#%|-I=g;~-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/pagination.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/pagination.bmp new file mode 100644 index 0000000000000000000000000000000000000000..31c0f2745af76cc97133bb71d4649beb2c9cf2ae GIT binary patch literal 1782 zcmeHITW=CU6vh`HefB5#3;Y4T`)f3&FO9~;hsM;Tk{TPWU?R7cQo9%|tyHM3Nohz6 zrEIz1%57Jc%|h2**ag3xZMK3n0mGw{nUiz&obQ|2GiPS*-4}0~NV^Mp2jlkTxIr|N zDG2}GEq#zc2({NmAE*kXEOsX929S`*eN_NlTQ4VX+_pvKW6|aqc{wOi`kO}#IO463c2^VFz za4f@A&k^Z$SOeZQS(13RE?=~<^<1L@9-rHGb`%!)7Ui&%=#%8!1F2pXlF`hInbc`) z)BORi!{AnUH?SYrjD8Qn{A9P3av4!*Ngcu9*{0mJd>Vw9r9{Vbubv`DU7js0JxeD} z_WWMBlE;UU{m?<^OFj{U`4y4*>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/password_edit.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/password_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..fc433d639344844d426cfaed951ade7e4e2fc1e9 GIT binary patch literal 1782 zcmeHDISzm@3@ZyGGf&_JJb;})Gw>!>uo|d}l33-K5S5Zfw&SE7#-$GN^vE5e-J^jB;P|$p+cPd|K8s8%k(iVQiI`BY_`v_Uk1VOJ$nqYgO|YIP=G2XM z$)Lil{RJs(Cy(-+pWtL1q4Y!|CY1I8V(LxMY)_!HAQL1}yhv7g!CO2wcgT11^xwlb D-FHrz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/percent_edit.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/percent_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..381051daaacfa5b286d9ddc66987d5b5fbf7d843 GIT binary patch literal 1782 zcmb`IO=uHA6vyMmn;xV{l_EAMNU?q(*n)?ef?%V)*a|kD)O&7iQQAY}O|M#^Xgui2 zt6H%L%|QYlf@t&6RGTKYCNbvwJKdRG|1&RHlMRsy9cG8wH}C!S|7ISu!=vTBCfUwo zJb|aX{_K%6lgWkkkNfG7ju^PIjjnNqu~shrSJwk2q^5FK&Sz7x%}gSiNyK*CqX
z6KE9yl4EjeCEBis^3^}|7Zs={ zn9pT#riN-aa0s%^)Yo5g9|EFWsWDbhaOjlTe(MH|K%q6(jr)U@QjK4o5B1#h9h&yt zd9jJ?$X!tc%Ja#6?r7KCq@4&ls#y<{_~-7Fc{cF7pakPp6bY$n?3F+*zh69il>?CytoN1YJw-`Va4W`Sgjjh=XY6Kn{Ak#0DRH z>vOD{XZ@q|8&yTu4tLS0+L2%~@e8l*dUPXDk6cNoJ5{cU^KIHryoqKwELcbnt|0v$ pGkm@sB1uA(?uj|wW3U?TRn(xd)F{4fY`s@^=bo3pj9vKe`~jwpGsOS^ literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/primary.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/primary.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/progress.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/progress.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3c40b97b486c632e67b5a3a55b992ae5afc54ea1 GIT binary patch literal 1782 zcmcIlQBTuQ6t0N@e9;GEAOsALKJe_Ti7!47f0Txi2m`_+A@C0%(RbtS*i3YqXn?IF z6vo*?v~>C4xxA)zy#V||7>b~*2LEJ4WN zdhTH~JC0ab;714<XmG%UUD zdoB%vTLR9YfEY<3ww7aAC-rck0V3!S0T7{o?hPapf(SZ9kX2*@&oY<}h@eNW=6~og z&gnJaoX0W4?ri(U)8iL2ZnpaBgw!jD(&m@F58q1f3o)?W`dZu*MdL`64@$~GQ9UfT z92>Wwf!~`Szny2cL4G_)eHu=Ykrct&#mF4FKTD>TNTIlYRzKF2N~0=CJKxVemobLA zz09+wP{u>gd9k`Z{4PJXlz+1LC(`-x<6T*p!+(WuD?3ANqT2`CT! zUo-1DA(eZa&OciC8#ol+W|wnP=-T#a6SXJr@0xnMdSji2>IXhfvODGJmCX18nM{+3 z9z0znqw|?pYuR#XS349HNrXtH^pnznQ5rv2T!-8?4XG+0D{7?&*dEEMqpOxCpVWYA z^EajM`(lXcj-#&*G*E0P#jE4$VRXambnX}q>L=mvE2+K#okaQ=x@#hRHNid~Nws_9 IKm2zt00!+!ga7~l literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/radio_group.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/radio_group.bmp new file mode 100644 index 0000000000000000000000000000000000000000..17117c803df17e829082084fb9d3c4e0076e6368 GIT binary patch literal 1782 zcmcJQJx;?w5QR;H6baGLAaMaszyT1@QBea84Huw*7N`)nKuV8N5FtT9m0W<|&;()! z6gHrkBL>_HZaohX9Enzd$T-+Mbd>ueTR{YfWz7I@DyX1~Wo;yKPG^Hn%Dg5@Ur<#p^_cPFXOalxB zqDWDj|Dn`NBl^_?5jr9m7501Gtc(dmZ9gXWuEv;Y|s-szS z=j3{7vy9;ol4J@1FahW4aKr%U>heJar~05!nA^U-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9@9$p_^#AXle?au-H?ipNAD|Yv zb_fG#!naQ!-oJYG?!}XLFP^@8i5CGCym$gs4AcVD2saAI{`ltQhgZ*k{rLXp_irK* zP%%&oP$R@BpxeHE{_x@T^Z#T4phlo}pdmm6bm6a`KgcrXKTso3JJ1kdr~*R+=oj+L z0cr$lheQoQbN>DN4@6i2@#g&b3pE1Bz%&e(IsY&K&>7!<{{8S3>TzUwpcF21FdaYt zz!RO)BP#g^E0^E=@#`;|0<7lz{`KqI*RS8cfzapAUxDm(C!ev$>=a4eE0M8}A$&W~ zsBhoCefjbQDE0FPD2ma{`T65JP;k-g=@y!bp4KLA76xt>h8|{G3XwA;vX9GT?2*dc zE1i8%JZX!wwWX((fsLM8Syl>A%kN)5f$1L}U%!6-1PY!%b86&)zSayp`oS~`nEHSz@b6y`i788@doVSkiBR1fYLy#6bEr~|0ZUh^ Rl&e%M=OIRc%0>$69RTGBQiT8j literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/readonly_edit.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/readonly_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dd3bf827c0bbfed1fd35a401f3805bb806136551 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm)Q8&GIWWpEMv=0KDI)xg!`VvL%DD`endh&31?;f6-yF^ZUQ#-klBh2I=B X_Yma5jfFD^YQd@iu6>j-v_b#?3sp{; literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/row.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/row.bmp new file mode 100644 index 0000000000000000000000000000000000000000..93c6964e01c45176ae67351bd40c8255e30fd4f4 GIT binary patch literal 1782 zcmcgtOH30{6vd58*DhVSaAim|uGB<=?${Ol0SXZnC^Z5mN=u?3-%>~fsX`p_AVDEc?wsCx`_Ac``{v%pB`|wqBG)nC zA>8}d?>!MOCZ-?X>-Uj6vJk+tAz~uW2{4Y`uJIfwQ95y;zH@@!9^@3b!eO0L}?LyGcOj^uY$r5#S1rRwIr_CyJ%GneAto zK?7A=evji=Abezy=eU5jw?}qjE1mn9=lXjzqR0~+lU`R>QG^Wu;S(L464l?E^Ivp! z>$!HL&R$L4>4ycG@;sSZRVGWnh)J=_^3t+gpUmJ>gqB@{*CatZ*pE@i19UF zignD4TE-@HS}pBdMtO0~SZ67U0+Nt+Ea@rzkjdDT8fzanAi3c^T)@d5V<_5YlIya!RagJfQVXG00jB7Hqf5-3w bQm*J6Ls^jA`CQ$_IZvd*vk~^M|2sbbrCPzq literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/search_edit.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/search_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3bdafe4b01f9133e33935e98893a90ec17020387 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|1bhn@eV9tC<>WTLokyS8DRp~ z0$~8ngo|LBk4pru1(^Xc3YQj4akyT%6s8DV3Ks*H7F^=^&A}=QF$${`rXU{0c%*1; t4$x{eD-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/select.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/select.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dccce0f4c866e1c3cba1c55e25bab4e036b071d1 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm*@#4%MuL~yCcB~BxAfYwpPJ#c5k8E6j1C625Nq6SC;1#zjzC63h`WCM{E q;4vRf8JvsDUR>gEjc5#9>fuf$iGgM~kV}$wxMECmMn#512mk;O;a!RV literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/small_button.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/small_button.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/small_text.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/small_text.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0d4b6297c732aa5720d942686818563c402a1cdf GIT binary patch literal 1782 zcmb`ITQ37a6vxYh%Zpb&f_DiK2?<_=iZt4$ZjC6d@FMZ%K}aMhaS1A-FTMy5>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/spinner.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/spinner.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bdbc3c6d3f6810d35cf717261cc3aad3164c6b27 GIT binary patch literal 1782 zcmb_dOKTHR6rOg`rQ$+xWf27Z1zCv;H;SSz-MA2Ug54=X=_AsOMhX@MSE2|8E7XOe zjm@K@Z5k^UF%P0mO52#2_asf5G?}O0+%p+NW?BmNa^~h_?)QE7oO5qZ&RlHtacnp+ zpTu*-czT$}aXi-N575Jam=sAQ(-c{S$hN5Y*s$o{i!G~pl2s%Vyh)`@b zJ0U9QcQFkeqMmbyLF}Ih-Tk!2uT|z# z)hFLFj;Bl9i2vB5FY#iXwu7Lpj?A_ho?YdJ{imOQPYMkqdiJr=lyAIW=I+eg@~-F# zEInHttQP9x;ql-h*Icx)g|98tPt{FiEadw-mamIAMq^lYXw4nXBbaM%e*#BUZ8QGW z#C!v1CmmNX)idaQxR^$YT{>VP45VWQvy0Ayg%mgF#SE}j$A|<4wQ!a+Q?c~Sffpu4Em zbh7MPNZk*nkZg9dg=jku9T-!`wr}WwZicQ*LuP|~vu{9Wr#=QGjtTditSb`IG5Z+0 T>%R2WeeCljrT51F_}}>pvhY6o literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/standard_button.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/standard_button.bmp new file mode 100644 index 0000000000000000000000000000000000000000..af6c190a9e23c98db1f37472c0decadc0f29e9c6 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;qG((mB}y}@B21$o z@|fayM6hbXDu~ArpcGauSOqCJrvW#B8;;d#tb%YYSQ%KgU=_rw9WIDf3syn67OV_h YS|H*ikyyqb-kG6iVl7W`d9t2`K#4Ef zNUVs8040>8LYNpU5_ljP^q3edJp-&x^BG2G0(ez|<@fPjFXROzsQd^c6%35XV_NhW SHaw%BmEo)hICTeCzQ7J8y)(1` literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/standard_combobox.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/standard_combobox.bmp new file mode 100644 index 0000000000000000000000000000000000000000..73ba54340c8966b6b596f30591832e8db80c22f8 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKWE#zxB-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o!mApna&l4&&WlB^%50joI> zL7);eS*%=$NoZ2Yf}`eOh5#+X2Q3P4agnWttAPlTLBdUdFvu_gt9#Il9pw)15C8yi Cbaiq7 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/standard_grid.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/standard_grid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7872be7624edc7296d46049e80d8e2afb2ed8274 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|6m0$2a-&qc?eT~Lqh|aAf^aV z0akO61%bMdxj;6W2*egNHJE~Ex`wVfK#!0LM#C97c>qHXnTwfJfU=l^Xu60`Kcq$$ qQ2l6pAx98e$YVwgJiZ`O5E2rM_(g!S$QEHW2iXKXY&3I*85aP9NZ?rj literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/standard_groupbox.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/standard_groupbox.bmp new file mode 100644 index 0000000000000000000000000000000000000000..76158cc47bfa8b815bc417850ed0cab4e1a25264 GIT binary patch literal 1782 zcmeH@F%H5o5CokjC3T*_3-SPZ{!EcK(Zb0l)@hiaM501ivVFVWIVZkc?_;TBj`bXK zdd;C$rQG6tIkj1Xu{?f#tUr2q$HN@vS3vu~{4851WYk0kQV}%)LMoyrKuAT@1PG~! zngAgcQ4=7fB5DGJR76dHkcxD(6}s;4)4Kr)shz__GRJV#WDew7!(qN((fe#6>VL6M O{_I@qy?=Ah3p@c@dP|%D literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/standard_hidden.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/standard_hidden.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cb5d8ec794287aa2cde66f7b31901a6e2f4ba36d GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o!;Apna*5@@V`B|$$-DIRmM zN?{5@Ou`fgir|sLRF6k79x3w7X&?mfJD%$9!Sn^D2p&uENReR<#55vFO!I*vMCwIW MhSi)=!I2XJ0CqNx=>Px# literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/standard_image.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/standard_image.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a9e189beb4bdea722a2d57fd53fd9318c1cefa7f GIT binary patch literal 1782 zcmeHEF%H5o5K9+E=01TJ@BnuH%)pzvf)x|Xx?CfrVnRep>iBG5lHTsysnl`Bdcj;j zbE&A52kOr=XBA?3{rYGZo&JW0nf5nBniI(JmPtX=;wS##AP3>7h86>|7khZ9a@&(` zQEMmNA}l})^?~Hcog{X~Z>MSy^f~SV)=&Z%U~X02BV9o3UdK{8=~w~*RQpV?Qs6RG nQ;@b3`K=tZR%Ut(k*O>tWl2G5A$ed8Ee<54=Lxa@Ennab;??Nz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/standard_label.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/standard_label.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e740645619de8ed20f40f88a2c03de42356cd703 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tk)2sDrm=zEXw|A! za7WnL*uNPV6pFe*rEiEA;J9g~I%gaNSC5as$ zAFr>kZ*FcbAtAAA*DjLuA}e0EZe4eGH&DdL$mr+KpU6@qv4O$j?CgBw#*Lt$Ad)m< lD)#g9D=8_NH*X%M6iFhpXU}G1V|(%91xdO_6_3CW006*tc#Hr5 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/standard_link.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/standard_link.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f400df2909a699c3b6c204a29b4e7905fbf4983c GIT binary patch literal 1782 zcmeH^F%H5o5Clz=lA0&v1$jVv{!GD}(!$ASMyoq65@kdz*;%jW){ed2x2g5E*f?9i zjehB>wTG=guiiUo!|QAZzk$z7jxT>x`2Z>c>{A0OUu)68*&)!EGMP(o_Dia$u%m@Q zs?c3>2~`=>5Yrh@=WC7w-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|6m0$2a-&qd5C2FFb!DEK@-H! zg_wk<2CE>N8Z<6eEpWjGA^^ldxE5sdu?iw9z+_|9f>jVxFR}<$Em#GSbz!oxYQZXq xsTWxUs}{H*5y9L5F%7PTpy9|0Fxey1oM9Qxkffbla~nq_xVvNX%~x zDGT9{`*X^X3T3-{U*)0AUo)6yzX-ICf#1j6$<$D2YRr);3S-@po~mGf3bDZFRH4wj zNT@;~T0W-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCIHI1q{jhVH&WSgC>Zd z3o!{z4P3B+H~`cR*Me*mTo7msvN%>YL=9XEvKqMHs5$VU7!4of5CF1?Og}(n1Od=A f{NapdH6AV=b0AVAk!Ti?q!(E+nmMCftRVmZ5WD^z literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/standard_progress.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/standard_progress.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4ddf24900411555010e80d148e9a10aadfc2c16a GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#QAplDVB-3cYMzVgG2CU{Z t;09>wfn115XyOn-+{QGZsUMlmc^VvaL-ak3^+i%}5-ary~TTermv>eq1^R2_FRRjzhh7_Y>PI{M!@%f{R zkRyxRp#_$Z)I~3gl$12^0;6t1EJ;XRZif~U$p{1qiz}>8qRugPO~)Jod|SbW%n-n@ bowOAdK1Qqy##=;1!B|mCNU`gW#TWPhjxkh| literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/success.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/success.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/switch.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/switch.bmp new file mode 100644 index 0000000000000000000000000000000000000000..aa793e1efb166445e2ac39bfd1049834ebe67c7a GIT binary patch literal 1782 zcmb`I&1(}u7{(()K`KfPRck*EB1QiJ4}zDpSJAU5wu;6Cwec#p##Sgw@ehz(gq}(T zAu5DzHfcy|vDQ@7`jIxNF>Uj;n@wWAW_Pnbn@MA7J}5E6vy)-weSUf8-CUXmN=QUE`EZC2Z}5?Z zLO?i#U|3+RpfFCxBSLhGyEt-D5#^#N)s>8h?N*PoBV;?Y)~{SFqiS;KVu;H;mj(=ldt`g*1*K8wU2=$*fhABL+8DLWVgX_+T$e!Q|Wu*QvLsW3gg}CyBTu#0z{}$|e>*1=|Oi;|8|J=-7YBHZ|+J zFtPAp+6PO%P=mAN7qr)AfBy5GNnCswbKW4X&3@!z^kn eRyeJ?H^6DhJ%-!0CHHCz?|F(+@5cZ5?)(J=>NW=e literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/table.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/table.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56d0bf259b74b4d31f4bb172c02644393cf4a4d6 GIT binary patch literal 1782 zcmeHDu?@p840D%^oqIwr$N|~=lTYiAo4PiH*$RY+2JzG&hyW`RO)8Y9$7?7pM&vur z?Q<@zD&>j$`O4FXNbjS^chSDDzl!T?tqFAG*Br&6(iXKM{6!+5bzD{CE8=`|99Pv} z=Dyod;h4#*$cn7^+2I_zWyTiT TqIM)!jv`4mwjn=@^%qzGqJs@G literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/text_edit.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/text_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dd3bf827c0bbfed1fd35a401f3805bb806136551 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm)Q8&GIWWpEMv=0KDI)xg!`VvL%DD`endh&31?;f6-yF^ZUQ#-klBh2I=B X_Yma5jfFD^YQd@iu6>j-v_b#?3sp{; literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/textarea.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/textarea.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a937b000f14221a2e401e2c8416ef736beb68ab6 GIT binary patch literal 1782 zcmb_d$!`)-9L9@B&;AMCO+0zhn8q3om8D2pmb$c6V5nM+7ZWvj(t`(2ni7pME>+{9 z*5!Z;)H3OS(6U&h3;WUm$|^96znOX1W>aYO?h(JenK$fPc4mBFbfymMMI{_n&RfZ{rf~D|MD};jO$Z~NdK>w{E z7SPeHA|0wy@|dun>f`vZ7{72z80UNE^b)k?93QMCqac+{#u_>ae)?4M+@{e!W`W3`~1wNYXns z`5d@8kApBsBk!N>)Zu&?q;$O=^m`UP?tph5Vl!aH?{=;w<8-YGbdSjxnw${S;e55# zICtJV`p_FQ40iK1KB^g2_UTkIol3eDGTk7o$P8-vh(>Yi#NqVx%bhxV`r7ok;QHg&hCzAzbu-fO`XfF~1# zci!hB^7(b&U87(=8N!N>h`Eg0YwnxFtFIox+0FM##$Z~@l8!OOobEJnSxJm3_JFY; zKX-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|DXp{bR@*nl=~PKcp#cQ(~wQT z&&FduevO#2SdD@x!zzVU5SMyf;#ds<3gS|aOMJl1X}}GT-GKEgC@RD|jw000*F BUnl?o literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/toolbar_debug_breakpoint.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/toolbar_debug_breakpoint.bmp new file mode 100644 index 0000000000000000000000000000000000000000..40beae6989a09e87ea3af6a894e33f3814d6996b GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y!!QCOA{EGpc%K1v>FZxcMnDl_ zv}0<77(!4xE{z1WqiOv5^*;m=<9KAfaE)l%ak+dj=mq)_?rdWG3yeWzXCrHYuyJ`7 c9`(4i6VwPX0aH7X8sXZ3>fs3Ps*%h90Ns$PcK`qY literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/toolbar_debug_clear.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/toolbar_debug_clear.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4c4723933b3e9fda042b68d181908a3a7d9c4287 GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y1AT$HxjFF`A}a>6A%Ga|Fts4N zklDoOMb<*RjmRdGVIxF4Tq8kyMMNs#2-(4CY-CqK*g#$S`j_Dd$c1QutAx7&E`n7f x!~}?TWR*be$Xp;B%|^J@KnAAvVW1b6mkD|n?sv2hBVHrK1fY62f}1&P7yut#l<@!n literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/toolbar_debug_devtools.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/toolbar_debug_devtools.bmp new file mode 100644 index 0000000000000000000000000000000000000000..165a0f9c25ce1bdb4f1386cdf83b9c2b03ff83a5 GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y!%znC-ZsP|G>;Om5vUTYUNk`< zcVDIfGJ;rvrVOhf8G3;hp_vTlVzmM;i0neR7B~a03@!p>pb5fFKvsjP3?d8H3)h9! z<#1)lW+Dq>)rDpSF1^U&Xl!IF;8Iux;j(ZBR%H-DB1yPW5C)ODu-c1e)Nthj02lv{ A{{R30 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/toolbar_debug_start.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/toolbar_debug_start.bmp new file mode 100644 index 0000000000000000000000000000000000000000..45e52741701738d17dc004ca66358303a37d4f41 GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y!>|Cl@nU5A1E?2*$S?t@(RZ#E z5RqX5Trb=N;vImdmm~*Z>V-Q1D23k*xb(tJz@r_PUZ6M`_7bBD;uti03EGA11-M?~ Ut%GZaXd%fuWW8|qC<8eJ0D_{`(f|Me literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/toolbar_debug_stop.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/toolbar_debug_stop.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4f79e5ded59072054b4811597afba2e94f3ec27a GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y!-xkmGPSr6{;&b+a&Wkg3jt;E bXdl&!9B#uetbkDu^b{_HCt-|A;ST`-HQJ_$ literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/toolbar_help.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/toolbar_help.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cf2b09d75b88d83d999f2c627fd49adb435c767b GIT binary patch literal 822 zcmbu2u?@o@5Jid7M=4nVDXm?YK9WmnFT*Yjf#e08jtN)*&)~+%#g}|pppZyGI=KJ; zyW?uQqu5SI_l4^Gs)LZ5FDSpAxY!Wl{`YxrdcO5#OzxS|L0Z{XMx}#2++;u|`@XO6 z8BF9n&lyh=7#c9cFs$ne$qg_x0Iap+I6{8qLkPy0Pdxef!Z}BBSr#efo(I4tWYaV; o#*~s$s=`ymBhxf#t=qQs-h;-s24+A~1BfM{m=VlkU^oDjKf(vWV1+;;ihAG!#Q@?KijDbz)tvYMHzE<- z0l3WhPXqwkHPp@7l4%Y^XnrNbUxUOPh%+!rhzE)H7p4iw9wgozc)%iShYJn^bCCT4 z^bQ=6oiBhUync8Gh>!yZXd0>c6k-mVA>^5ZX$T&3fQoS;c$gqFu=)#G0g>#%X%56y G6p{d{WHaFa literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/toolbar_open.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/toolbar_open.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3bb431ebb5f665b9de37883a2c1b06549afa4ce5 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+;;ihAG!#Q@?KijDa|3v=Y6Du_pD zUO;va(2)2`|A|3x>)@u5XAaOVh*3kr9H1kK4nc-O(TpfL!VfTkXe zi$^-s24+A~1BfM{m=VlkU^oDjKf(vWV1+;;ihAG!#Q@?KijDa|BXcsn%}GLV zkD$2+XvnJCC?LXb8e9!A=KR6|knI}D=HLlx;=>uD5-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/week_picker.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/Packages/icons/week_picker.bmp new file mode 100644 index 0000000000000000000000000000000000000000..44ea12ab4a407eda9b27fd8bcab4d6d254f9fffd GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCH}Xh6-u=VXASNgDH+n z1Y#1VEG}_Ol@JkJ>T!vWnu9;whDZ27VxM>t)7P{}KX}Z9OTigvPJ)P&N}?G8Label`; + } +} + +export class RESTDWEdit { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWMemo { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWButton { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWCheckBox { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWRadioButton { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
`; + } +} + +export class RESTDWComboBox { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWListBox { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} + +export class RESTDWGrid { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
IDNameValue
1ItemValue
`; + } +} + +export class RESTDWImage { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `Image`; + } +} + +export class RESTDWLink { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `Link`; + } +} + +export class RESTDWPanel { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
Panel
`; + } +} + +export class RESTDWGroupBox { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
GroupBoxContent
`; + } +} + +export class RESTDWProgressBar { + static visual = true; + static placement = 'body'; + static createHTML(options) { + return `
50%
`; + } +} + +export class RESTDWHiddenField { + static visual = false; + static placement = 'body'; + static createHTML(options) { + return ``; + } +} diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/README.txt b/CORE/Source/Includes/HTMLEditor/libs/editor/README.txt new file mode 100644 index 000000000..ae71b1829 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/README.txt @@ -0,0 +1,22 @@ +RESTDataware Web Designer local libraries + +The editor and generated pages never require a CDN. + +Folders: + bootstrap/ + datatables/ + chartjs/ + plugins/ + +New visual components: +Place a *.dscomponent file in libs/editor/plugins. +Format: +[Component] +Name=My Widget +Category=Custom +HTML=
My Widget
+CSS=my-widget.css +JS=my-widget.js + +The editor scans this folder every time it opens and adds discovered components +to the visual palette. CSS/JS files stay local and can be referenced by the page. diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/bootstrap/css/bootstrap.min.css b/CORE/Source/Includes/HTMLEditor/libs/editor/bootstrap/css/bootstrap.min.css new file mode 100644 index 000000000..8589b8f7b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/bootstrap/css/bootstrap.min.css @@ -0,0 +1,17 @@ +/* RESTDataware offline Bootstrap-compatible designer runtime. + Replace with official Bootstrap distribution in this same folder at any time. */ +:root{--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-danger:#dc3545;--bs-warning:#ffc107;--bs-info:#0dcaf0;--bs-light:#f8f9fa;--bs-dark:#212529} +*{box-sizing:border-box}body{margin:0;font-family:Arial,sans-serif;color:#212529;background:#fff}.container{width:100%;max-width:1140px;margin:auto;padding:0 12px}.container-fluid{width:100%;padding:0 12px}.row{display:flex;flex-wrap:wrap;margin:0 -6px}.row>*{padding:0 6px}.col{flex:1 0 0}.col-1{width:8.333%}.col-2{width:16.666%}.col-3{width:25%}.col-4{width:33.333%}.col-6{width:50%}.col-8{width:66.666%}.col-9{width:75%}.col-12{width:100%} +.btn{display:inline-block;padding:.375rem .75rem;border:1px solid transparent;border-radius:.375rem;text-decoration:none;cursor:pointer}.btn-primary{background:var(--bs-primary);color:#fff}.btn-secondary{background:var(--bs-secondary);color:#fff}.btn-success{background:var(--bs-success);color:#fff}.btn-danger{background:var(--bs-danger);color:#fff}.btn-warning{background:var(--bs-warning);color:#111}.btn-outline-primary{border-color:var(--bs-primary);color:var(--bs-primary);background:transparent} +.card{border:1px solid #dee2e6;border-radius:.375rem;background:#fff}.card-header,.card-footer{padding:.75rem 1rem;background:#f8f9fa}.card-body{padding:1rem}.alert{padding:1rem;border-radius:.375rem;margin-bottom:1rem}.alert-primary{background:#cfe2ff}.alert-success{background:#d1e7dd}.alert-danger{background:#f8d7da}.badge{display:inline-block;padding:.35em .65em;border-radius:.375rem;background:var(--bs-primary);color:#fff} +.form-control,.form-select{display:block;width:100%;padding:.375rem .75rem;border:1px solid #ced4da;border-radius:.375rem;background:#fff}.form-label{display:block;margin-bottom:.5rem}.form-check{display:block;margin-bottom:.5rem}.input-group{display:flex}.input-group .form-control{flex:1}.input-group-text{padding:.375rem .75rem;border:1px solid #ced4da;background:#e9ecef} +.table{width:100%;border-collapse:collapse}.table th,.table td{padding:.5rem;border-bottom:1px solid #dee2e6}.table-striped tbody tr:nth-child(odd){background:#f8f9fa}.table-bordered th,.table-bordered td{border:1px solid #dee2e6} +.nav{display:flex;gap:.25rem;list-style:none;padding:0}.nav-link{display:block;padding:.5rem 1rem;text-decoration:none}.navbar{display:flex;align-items:center;padding:.5rem 1rem;background:#f8f9fa}.navbar-brand{font-weight:bold;margin-right:1rem}.breadcrumb{display:flex;list-style:none;gap:.5rem;padding:.5rem 0}.pagination{display:flex;list-style:none;padding:0}.page-link{padding:.375rem .75rem;border:1px solid #dee2e6;text-decoration:none} +.progress{height:1rem;background:#e9ecef;border-radius:.375rem;overflow:hidden}.progress-bar{height:100%;background:var(--bs-primary)}.spinner-border{display:inline-block;width:2rem;height:2rem;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%} +.accordion-item{border:1px solid #dee2e6}.accordion-button{width:100%;padding:1rem;text-align:left;border:0;background:#f8f9fa}.accordion-body{padding:1rem}.list-group{list-style:none;padding:0}.list-group-item{padding:.5rem 1rem;border:1px solid #dee2e6}.modal,.offcanvas,.toast,.popover,.tooltip,.dropdown-menu{border:1px solid #dee2e6;background:#fff;padding:1rem;border-radius:.375rem}.dropdown-menu{display:none;position:absolute}.dropdown:hover .dropdown-menu{display:block}.collapse{display:none}.collapse.show{display:block} +.d-flex{display:flex}.d-grid{display:grid}.gap-2{gap:.5rem}.p-2{padding:.5rem}.p-3{padding:1rem}.p-4{padding:1.5rem}.m-2{margin:.5rem}.mb-3{margin-bottom:1rem}.mt-3{margin-top:1rem}.text-center{text-align:center}.text-end{text-align:right}.fw-bold{font-weight:bold}.bg-primary{background:var(--bs-primary)!important}.bg-dark{background:var(--bs-dark)!important}.bg-light{background:var(--bs-light)!important}.text-white{color:#fff!important}.rounded{border-radius:.375rem}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)} +@media(max-width:768px){.col-3,.col-4,.col-6,.col-8,.col-9{width:100%}} + + +.btn-info{background:var(--bs-info);color:#111}.btn-light{background:var(--bs-light);color:#111;border-color:#dee2e6}.btn-dark{background:var(--bs-dark);color:#fff}.btn-link{background:transparent;color:var(--bs-primary);text-decoration:underline}.btn-sm{padding:.25rem .5rem;font-size:.875rem}.btn-lg{padding:.5rem 1rem;font-size:1.25rem} +.form-range{width:100%}.lead{font-size:1.25rem;font-weight:300}.img-fluid{max-width:100%;height:auto}.btn:disabled,.form-control:disabled{opacity:.65}.py-4{padding-top:1.5rem;padding-bottom:1.5rem}.mb-3{margin-bottom:1rem}.mt-3{margin-top:1rem} diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/bootstrap/js/bootstrap.bundle.min.js b/CORE/Source/Includes/HTMLEditor/libs/editor/bootstrap/js/bootstrap.bundle.min.js new file mode 100644 index 000000000..da6faf326 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/bootstrap/js/bootstrap.bundle.min.js @@ -0,0 +1,2 @@ +/* RESTDataware offline Bootstrap-compatible behavior */ +document.addEventListener('click',function(e){var t=e.target.closest('[data-bs-toggle]');if(!t)return;var kind=t.getAttribute('data-bs-toggle'),sel=t.getAttribute('data-bs-target')||t.getAttribute('href');if(kind==='collapse'&&sel){var x=document.querySelector(sel);if(x)x.classList.toggle('show')}if(kind==='modal'&&sel){var m=document.querySelector(sel);if(m)m.style.display='block'}if(kind==='offcanvas'&&sel){var o=document.querySelector(sel);if(o)o.style.display='block'}});window.bootstrap=window.bootstrap||{}; \ No newline at end of file diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/branding/RESTDataware_banner.png b/CORE/Source/Includes/HTMLEditor/libs/editor/branding/RESTDataware_banner.png new file mode 100644 index 0000000000000000000000000000000000000000..5f0c32052b957b830b9bb8f52d4737a5db4309fd GIT binary patch literal 823613 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

4%grZbLHIqN=gu;nHY09En&})ot5^HYC%fL}^1C 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%0D}~OChDd}G6$u@p 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≪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

-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 pf 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 z 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

vNB+ZTR)rdc7`vY`Pbp z-udE{!Eua%Wv^Qx!(_mNwY9RYtFhYwJUZ+K7wQ=8bKg9A{o3AAl1z2&(%|sc?*7qK zXLHsDA%d@O?H+Yp&X2-{4Obh*l)mR9m&faW{LLG8Uj63v>$k68d-b()>pTzYIA2a` zj}R67vei~7Dd|Z;FNyVGkAB^|Xo4@iMpd=^gqQT4yLhlc>9;1u_P{-IX6QZMJnU}n zwPGl$!%-bW?4mYZ5TrJWL}f-0$*O8qD+|&Cls>*t>woxuR zO-C^V%kmcIICSC)AA`nL25X)Mez_2n?(zkgOz_)xp&VD;vNNTk;=ZuYJ>(##n6n;F zMb%Vd%;*DOIfJ-+Br5ROlXzwu_6+w9VoY9vlBx;DAfP~=4S}312V-`woiEumwQb(* z=4vDs9$kT+Aqk{R-Gr?5)z#t+ozq=>J&C zc?E{hz~Vj(F50BV`(VqNX~Lqk6fFS|g7-EYg9Gpt%;$J_7Y5EAc>)G&(9Hk|>H$3Y zBy8{C?Hh3Kx^*qEgR%fN7_7s_R&jJsr-#WDPVR}&=YVn;XBCN%)6~yu2b*K-r?{T) z)D?Y4p$9}x2Sqtrl6S624FEX%$W96`mU-Uj2`oFj7=R!dAX!pPik<H>oT_ORfY2AtjTTocAgs$qH|!S3>ZWY65e`e5s3t zNCZt0QZg0*wl)DfWHP}%dyv^klAuc|AXP;fs7=ZJj0-}(D5rd?j z)v3t{kO`DPlR@hJXcl$FAu@0)H5;7@v$#U<$y8`a5;Fb)$@P&=WYnl&01nwx9%}#q zF{zrga)Pq~HE>z`bZWBCqo4jbBIdTAvL^s!&xV#%R1_JlGgl!y>{=-*U;#2HJw(CK z+N=Rbu(M5r8gJc%ZmGbya?%^Xio6Bb=V+iO7Oyg5tGAb)XtW++=;&&*rr*IV&!1&A zl(p3;=p^H_GF$buqtyrG>5r|HS1LIVNCmr+O@(@8cb16*F%eLVVo0eGjltv;;C=G_ z*h$07dI(VF(w?>~Pr8y0oJUuHbKn?KMm43?Ed@cG6xD&a#bHvvMBxaEXK&# z2I~SeEi_AJCQ)?`2)L+nPLma|4F)s2byteQW(_PmWCuy5@Gu(FXkCkv_je&Kp{|Q@ zRaPaNC1ylJZ{)xvq8FUh45&p(NiDPhN$S#x!D5j@t7py?)`=L*=WukKLO{>vJ*y-z z9S+%dHmKcjKruiRC<`dOEhFsSk4-}WR-ik7&X+^Ix2K6btBEg~d6*uy3OE_1(Yp6# zS}Gr1*Sousu_{=o#Kp1bOdR{^Oq%72SlrW^NUhhnm{|56XK7kK^y-6hYND%#mV$ve z?^g9v>almKNMxpxlnaKetpP(cFk#0T>QC59zVee!%}zCY);A_3rEJsd%i(zlWs-s* zA&BNckQwA}es$x)>|E0PN1tt<@LhoGYq9i3ELP$x-5xb0T=&jI32!J6dJ7%KLCGwOHB+M{o-(?bX zMC{c1S#W_^dM7EGfFZJX2AGl(lV%W}0yuz^78`<5O zuPlD~fBl7rKJWoa7Gv~e5~CRdf+dY95Wv>RIkZ3j(?9uZKlh7m(Am73A9d*{TzL4x z^DjR?+p`-t?m9R6CqMW3AAI?lKl{f&{^ASIKJ&y@vq+LeTWgNeE_BPIINm(FxefQ; zzP7ftQLYu!Y5SXBdiVV=K8Xwa>g#*0I^PKbOx6d@(e&&?LrB^fEE7VoA>;avf8!n5 z-)EM^r(WKuZE4qYAaOPH0kV3#kRH%3?AqOJe5cpj+SEnu`1T zzwyqW`}pI3=0{(+IkR2y(eU+e?43WicK-YXZ_kep<{y4~CmHX$m8Sf znm_rWOKaQ95G2f-@%g%Q)&5@Vr|G$i<43njzwC;VQMElz=SDnvxT;)raUCnnPEr#9 z@30Zrn^~t&5UdTr66_!A@hlC-9zjBj$!uqgmp9$!m`AzbZ zL_ri3OieYJs*0+pNixYxFjHpkqdNVh2vm$1F|TnDX7ldO!Ln`J3b9$XzxLU0fBXYy zKk&p(+r{JK>9G~tJENo9)3qHM^62*6)&oCsrbv>|aWeSTE6dkzEdSI;)^8oQvkuy2 zx;%*=eRwk_`_kKs*6KoSIZXxIf!ibM&3kmZ1cm>-Lo4VR%{ zA>2R?a>GFU7^0PJLEZ7_G&3@qdjitaht~L7|cuQL~A)01`sTvZB5@g=4vH`kq5@T$bp&bp z?pp^(H`394Q$k?U;`cxQ_RavG*cs3EWhQ6PX?pnW_wIc7;fKHL z1Ly9|((awZ=bztx_3hoi^N)Yaj$0a5xR@&-R^Ed0Ccga9C(nZ%?an5H`tG~O<$Cq) z>-Qc#yEECE+`D^NcHxOfhoxb+OovD5pw%zEwR?AWiRjOqTf2Y%@bF;S93BBFHqn|x zx_t58?fuu^xcA(TKWEYI+*n>-oBYA+*WP^X#J_e(H*eb>5$n2`okGje1> zjd-xR?x>WM$gxD~V=88rj0$F-Q7~Y+Y}C_`^D$pu@0o|I z1Yl$b2FL|UGEk7F_XTCTyF_3IXrKY4gQA3;9azrrdSg`uXV268SPrI8RybLQ;n+an zcpqj<=o)Y}b`i0$>9HLhL0Q4Z7L03q_8B;T7McdgLke)?+pxcZJo zNN8*)`~Q_S%m7bTJrI0~_9 zbCyryU2vjl$J2aSKh5kVH7h>%$vFnXY1(L|3A0nR*J_rzDlpPXYDiD!psJ=x*^#NL z0=ph`n?(va?TK;>of_90Oz<0 zqxme+G(gY@*&x^}+fQB+1~BLvTh5_vSJqvRnsO{<_2#Bi2($_?0}_VL972pxcw`0x zkZ3*80|6210r_MxTH9tiCOD6(MvRih;%HSxJ(NkTD4?jI%EPPy9qek?!fa|H&`r%b zm~3H;aIB^VMnFulRTTihERsjYuGOOKfh`242%1*&GD7x-09=4*-*n4wbyE<*HUJYa zXUQd|1bL0f3`isilBz+UYXgE11c?Ai)!Np`VQL|3`XpZf16NeMzKxTyhR$x^v3X~) zRb)q&JJMv9bChUiDVZh#L`@2azCq7tA2V?O*Mri`&%ol3cr!w^l9Tem8!Y%Kyi)?}cD-t`nA?*I*Z>Z&=%x$xFE zi}RUlZWaTSrK<;33{hgrDIqllRazO)^74-W*s&UPA^E(6MRShw{sEa|Ncl+!){jJU zS>05SnE?TjIo})26`X;uxdWV!;D`Yk+a@xyL?LEppsCL{i7FX+#||NpSpRzi=eQpL z5r!1ZvTF<_C1O@JG-c>S%0LB`QeomV=G*_{Cj@(rT0zm->Yl>zVH9YtAFrRd;JQ768BG*7^162YWDa3 zyZ`=p@9fK-Z?N@&4 zN5AKLKlc8ewPOF~^!&qXo#Aqp4rd(_P1e_TE>&PU98JuCinKPF%o|N!7e+Ce1RJka zOoSdMLtj>IZF(NLD`%U+a+ify>=f?ETLVQ)MRoDSEi*8WrhacPe z&?7@Md;G#!h(|ls?|cQ0Z_QvZ#JTZcC`pNdN~STCh5wDO-ng~be(<}Wo6VXxUw;RO z17zUgkSb=R!K5w=-_4fZ`^`%m>swpXyT`BHOW(ZP{m~aEfBHwC{`pt-mI)k{qBN*z zds1GQl;?J;uV0_un862!l@_TU;JKak&wcy&pMB=-*X}r8n?yj*JgGDs&F`pv+MqmGo{zT zutEm*j=N4TZWEi83}CQ`_TFyXT=P2~o1ptMSsSo77%(EkXoqyGC`)v}g!!4zfB5(o zAtp7mltk5%n5rh}HR*uJd9`YWNUCU-vtxvk&C1*#k0KDG_PN6TiX)zF_9P#GJO-iD5e}3rCj~GFN!sl-+fA*_)XPu8F7fMxK zKF0VXPYj;eC|=)-*XADcGc4)$20e4epZrw$2!!%7sSgfkQ%cUt_g%K6wjwF^w^k&I zuKvsa^Oax!{rhnC46Hje1W`juwyF_8_C7G!DnnvsKtVC+1S&p>Y-jZ`kn(aqgtk~; zn=Rdk9-?3S_n!YpSK9yM|MzVe)aDq8FRZ)LVdz#5R#ogJQihbBeb}cLQFCUgH<=*= zXm-GxLSFEgK^vrvsjdeC5G0}Fu4(cdgBa#b8;|zUJ8%v(0GK6(f(8Rul~~mU0TqPi zDIG*4L?8%h%=+g(`snvOJO+Tnxg0FxxT3>g*Y?_^cCe|Y zKg=y^L(2J35pj+W?l0R#Ygn0~dG5V851xJI$6j{AXv(`EA)kWL{&G^=qJwT+VBt{# zH5sFU>&HO-`WW&6&j3wUv#1!s%oVsZ8T7cltVAFJ#U3AoBqIGj8T!3MZ!oYE=qE6d zfu$sQ?;Mh_bL^cc81?-`6(vH^DD4t_>4xLbbkMbs0-%}+kkb077}O~?RI)m0uD>mZ z*MJPUL=qnHEAL$Y%-62`O*(`%D?@C z8(X8H#|vlc*Y^)%XE3=0gN0-%Ga7iOseALSn>+7&*ao2NfJhNr@2?*=)lBvdm(y9- zecGP8xcTsfYG(MAD~H!^PRE;LX}g^bS}fU6s*Ta|*0G_PC+(K0tgqkOyLa3T*NXMa z<8R%X{mei4tt(%BvmARIfk-!e^6@|WQ=h!@tt*iYl6}Qiwf2;uNEidr^cW zNu76!m~~WHF(+bRu(4KM*d7+f2Zz&U+0JA2%3B9B@bgBtH;02!HCuE|h+Pshh*1GD z^j!_G4N^LGr8mT)Eb5xsWMgBqWKk4D3(2tJ-NUW~(nC3zw_-p{dBGz|e1+o)GV5TQ zrPZT7!qx@@zI7*j^9`uiXteG$fuV&Ckl1;^96t8Wd1nY=88ju0sh6x*j0H1kS(z){ z(L7zhEtu$$hiQ8U@9z_soHl0E&`~j{%fSGZL{eVlkaL#eNxa2UW*fqgZr?1!sr5QY{0d5 z;Jvr3v()1SQf`7+pY?DnDA@|he<~3>IZS=93YOy$3MaUu2jUI50`~TgfZkkl@)`1a zm&x)CfU~r_zd>jc(3P7ipLq7ZCj>LgeJh3&qFOKY&cBBw{UwuQFL}(BahO>S#ROu8 zNaPW4I zqLu?PgThmcph+wltsF6kz@CUvlH^8G3YrDO%$e4Af(OgjE?CkW2QxDE`2o_~$t}0l z9Hp3?cSY??OhR%V>H%sirCI&0{x*2>Y8Vw#u z2IU7Qlc}z-;s5{^lNgy0J4`8=BUdmH8c0#Fq|O&Sns_3b#h~2->7LUnTISI*5Si+# z1oFW5g8BZFAGf9oDH$_hPJST}nItO;G=->kI%UmTGXqs%2T4I9NKdcoul!6$&IHCh zbjlxm@&`jO@1biTDS&}zW6m;olwj;o6-0W@w_^a8uVKyF1&L;AWd)YhF{WgaAR$yW zj5i5_c8yLZxb!eRG-7P#w!3Fhp{{W_#3-iw~yOMO6{s zT3JHd3NkK(Ej#l>F<6pRR#;aYmQ5FMxK=J&Tg-AD7w3oFWJ2p()$*uW9yjd0EBx$0 zM6GZND)YVM7+!dmotIm;bl&p8UK*CRIk9xKtcG>ig+&X)u|J%p=7tQb0xLQ?ihxj* zl_p!xB7mz3j8U5iU29+rXeRvvxo2fUmZWnAt|4Wql}ZfGLsdJCnv#alPkn$;MOQ}8 zRe}c%378!MXcSBRp@I=cO{b5&{Kj9sZ8PCmk`R%Js2V%&k z&43H0UX&o9WNJXj#Mpz?au$FjpZZ$9_%J^Zb6Ety3SSJWsxfP#s2XIo3a(O_0Encb z{oGD75lBy_}A`>Bt7!&oryv)^BK*l6UgUN?J_I>ZZ{mte6z5Ca$ zzVXG+rEYoq{_C&&-fy4ZIDh3^Z*m1?;bK%#`{YmjsekL=`gcD4l~?}m-~QX5`~2s< zV?&6Yz4?vn$4By`Kk@R>;o@ihlYczxqIKodAN`Qy`s$6h|K;ajoi*@NpZYKY-Z|`U z>^04CBc%Zso~mwP)o6TlcfS4jg`tnnKljjh=)ZAwdUV)qT-ZRg=D1ng7&2qKNKJxk zGx@@shpF^bz1r$3Qd3K?b7tRd6xi!AA+nsxOtxC}D1?=MH`N3XeUwHlSyPn=06m+yd z-(DZ?C;6MddF!32r*e?YxO8#vcp%M>yl*F|zqz{{4nezizKEmouv>~7QW%!M^xD1k zjq$L+3zdfb_Cp`vJUevSn2P+-X9g1nG$TY+TPy_~lbMQXGD}uhB%+fN*GhBDRJ zMDEn*X^4H93m-rne=d+M|lp+m3wU z`bw$V$t*HAB0(_;ESgS4$%7_EfO#w5x;=|QN6r=^^W8;lX$x>YrRN{1Mu?$}RqgH^ z$N%LE`}?5;=U=;(3W3X8{3B2KPdznScJljgE#~SVcB9Ikc&L742wMf7B!5rY2-*IL zr%rlV=>o0K#6m8*<{IpHT>q`#x&7Lb0d&Yr9P%qK2ajG+4MTk}al zjBw>{*z0s2WbKS!^L=Sh^+Yj({VkUez(jw^7n;y0{~J(Q*%z6b_lb7{1>13=;PzBeEaw>{K|XxL!H~=W~PLSxT606 z5+W0dsrHai6txgh#22tWEHi9v1+iSwpsgRuXTh1SjJr8Omgih*7E{VsUw%V|C|wli zSVToFbV*`Fg4lIfIEzu+1(a;vF?MPaO%sw@lZ=&$8r>is-ge$pT3H-IY;ag<*V&yr z>o2{`BY*RiE5CGhyN&+QGaDaydi&KYlh^MaL?U_b{?|4A!e`(76CZo=sq=L^3pcME zxIi0^Jr-sEsGZsI+*D}*X*&JwfAw2U{Qjz{_YYdC%6J^pc)WYuUDz2FRhPiNcI6-% zb~4?%%q@_ zOwEX3du@1Tz1$gPT zjY5rzSa@!_Bqr9yf;b{|CT)|dx|lX$wn!V3no#G903J0+UcJ`?zqUc=9yJu59WKiu z8~R0bO_zS*H^Z#OYRF05;cf^4W2Z&MC~AhTD!3>ufoYNuHKaVLbfx!|7fn^|P2%kv zfqgMOR&7%`KoV`Ii3^t&+HV|0&7dUKm{c%{#5NKkFk6hhZ77*hK<_LW5c<&&6+{Fj z<@gdY<@0-u`IiBqFqkU=5mR2Kr|f0}$dv~KB2d7?L*oJm zhgy!Xs8evt3;z_iOw+hNwH^wmx>8g}9ugI;*uBcC70 zYXG91;D>r&Gy$TfENMe90LR46R1nZakg}D>z!aI8QDd?kjWNrfU@)_c;y4Y83ZtQoYFK}YZq;`Cj%n&O#?bF}@PVL9&kN6nyA_uzQ=bi;ae?KS04)WIbJW)Q z>Kx|9SH_|%JRo#`00d+}*w@MOvpSD^4FFJ+S;_$f2u`LS+l;7cGd@6d)21ybluZOD)!FoWb_ zDH}T=Lhm7UpbE<+oa75~Qjr~)01*I#3J|Q!U(lD!stSFDfDp|@Ep+`bwkW`RV2?2v zJBR^9OaYRBM??gP<_iQca@cfse5h+f@C7tWV}ro}laYuL!10kSm&OQ05E8_cD|dZo z+_8BF&Y>B^O!M!j2wVUtTFS9FG((Af zA0B3m z000s*)f^C!*>b0EG$F^4JQf2ZK~-Q>V?r@UT$BuwTt)ekDGC(86xB?fL-w#*%aNh6 zLnD_&l`;m#2nZ;@Ay(=uBoUi0B0vFXU8iVV49KB)hn~!t6{Cuoma`PhiKg!+0{NDg(s% zw37&(=Pp1DD{_LFN{@t~tez##_mGT=00VRcma(nMj#SiAPLzN|#q9nvFg1amF`q&r zCV0RsNPs|?VnP7+gp5eYp4BXGe~{S;Nrco2Am-z1M8wSPCNv|{oPRM*lJRN)n72yH zdDAVMd^U{_@XV-}cp?B2GxbtP%nTk?V;r%Bz5f( z%~I|%188o#VOe@|F0`Gc2WzI7xTp{U;Eob?p&M8(gtG8#hFPp9&>A0 zR0Wwj2QFuDOJ9%cqt?E?7pCfl;3gZ@y~D1k3o3m_?x=|c6=mf?LqEw-Wz@&djb3_u zTrzZOuA+^NV!zQ&p&l2Ho*RuO{^p(C#(bkjuB<$tzkK%En|H?SI9OwD^QnjG!c`Tz zvUuOc(WgFm{#Ui1E!ar+T7ZRZeT8?!nwr) zjyt$<*bGbh=##_Iz*U3dIKhqG_G;s;92%i@5klOqx_|$N9{>LLow<1|vqgO3Tygs- zefjO9;}Yt@pmu!k&Qgn7>!Jfm-qq`agJZaM^{B4Ommgi*bUo2;Ya=CWmQfi;BlptfQOWf6-R{~EBhc0$eCma@4_@@CIYA&=63t&l zS9@~HC(vpuj7u+;%`axZkj^bCpkMyRK5h&hM9@~qDHXlNivUy%`;cK@-e0Mwjq(9b zzut$ufLApE5V>)z|K;!8`QqEh%eBF)?=4^b=04z%Qp2`<>0$Smzwfahd}6I_0}~lR z7CS2T1cRK2)Tl(rjzWyydt$;oZXh_pbDYS|46qF`ijjBitc_9FaZ#eq8Z#lX7?yxW z!x2@b9v^{-l@3&ieNcO3%m2hjFCGQ{^tW~akbJ=ou;3K+Yj5m5`;o26lZbra(Q(Ci zb1EGcSkUH}ihOu2tMg#fd~lwt#JNi$E21QMLu z@!tLdD>_qGTRY>Uuf1zvuwH86|Ml;_{^1uM{p1I>kLR(%^xdC$;>UjIg}?jv{?*~# zC9XMAK~_tx;QVWEynXiK!+uy+UK-I54NEr|@FNeOFOcqC-2>C>w`Ryr$kxsbLy)cQ zLOKzHu90Dl4?TThzBsUjm0>Vo7t1f*F(MLL?G`oX}?w0Wpddg)0gIO^TF6y?3UG5le(%Cf zOKCsx(To4*|Lo6H7ta5S|LULaE+dmK9C}7o1tRND-AGQ_f2;kA2$*S#%bMb3jj%A& zX1YXI`1Osd^iDu4S9Ag*qD-Qo+Ao*Ny3*K&xe^-HR7^M;R3)kui`M(niozf5NzelK`~gXMKuZnVv^*cTpXJ7gNQagrpiZOLYya1MCN{h zLue|hk~-6rxX4ED2#lwx0z?S`OOLMLqR^5~*q1`$IFMSZVM+njG-BqqJEe!<9 z8spMH!NiEbl~4~DRFObD_yW$H$48$u1-N|!-n$8tO{i|(v&IAN7=lnYZ$RkNL zGtf-t2Nh$7h>)VN?>9WAU}ESXbwZR=f}o<@3pRmD)Xq#+yeEBN{FetY1R4~P(4oYX zXVNj62oaihSP!Y|RD!i;)2UVf)`5>Q7~_3!sY`?;U>cN52EsO&8dL*_3D!33ndc~o z-oKUe)qVZ`RFZX~>&hqR)VCC~D%+LlDl)U2!ayYQVA+P)=b>_OZJ+)ZDnq9+a9OjNbxYACntF&)pRhCQC!zTP3H^Go?|o$57{aQD zpUd0;hQt5}#2ACR@;m(XgOL?A#stm6VuaX%rT$pX3y7ipmnA?A6kX>L@ZM(8?~2nMW`hb9tXo+A-eNFS-~w`6u&&9mYB2VQfT1-tV1%LoLof#-{V1=l z!Ffm#j3Lf!ggBZYc|6#MrUldf}}PTB@YKhY-6>?F-m9>0Ct_J5u(K?u2(y$ z^Nc{DOED-Q&1XVjzI1Bni9Hjj&5tAu3L*ov(E4Sxm@uLe6EYkhL{!{4TR4ot3D>+_ zh*Mh|qp{6e-%dF!F@Rp=1d`T4A!cyli6`pL;^CCW`O{J zN~RDxD+?%?B0&%}qP$JY`<%XK1!x9DYyikydfeFH^(~%H7l((z%r>?v13ErRv#D5A zVl>s5#DKvlPf|=)dq4yO%?M}}Gf+TCQNYYGn?g!?T44f4%peM2-yst0^E(8hBBr1! z!py$%y(d;md{5F!vs5+r0I02HwvNSygW&{Gg4iK!BT zsphSgidsg5isrDlM9n%gNh#ww9g`u(sA?xb2S7$9=Dvj0he<(!9h-_PoQh?@mx*<4 zN?po=VghiER3&v0kVKWpspx7i4GNME2~&!R8nOWYxBu{Gzx=s>{WJgV|7UHy zCf1)bn;HWD!1w>)um1XHufF-U%DJR5&N?-t!iU+>aAWJ?XPEyI95xXNQlDs~b1=B~{-0o-02pQk%SCIBLn0sL7&v@{z6W5@XbZ zgEnsNi-QC%>`R3JQdag6hLZ@;}c!OiVrF;64sw%3Z~{^H`L0ujHxNH-7C zo!$8lJu`k}FBkvL zCoX>A$@O3P#_{@yHqO^^mY~q_n2)c`_L}hMrn_-<`Ox<8yPq3wlt>1W6v;+Ib`BAd zvat{Q3U|&4t7hbcO77uW7A>i059iX{h|Wq^>=SeSGe6fNRr?X@>XJS=?93amloS9& zBwzf!P;2Ej%I2w*(h8!3z$bSGRl_c(7=@_RUc`VQDx$Ha3FDok)~jD@^{I95Oq+Q? zwc%R1+sYT;Jl2G9-bG|ZYo^_;!hPeGpN{D(*Mm9dmh$Ae;(IUq3UTgKlCi@iIX?)w z8LMiP!O*I`&lFZzXhbm0Sxi$CRU$rW?45l@Ce}9FR}~O|fmd+UOkP7nA~1v`y^+*t zwI5J0Ly#Ul2xNtO_4Vb~lL9)39f(kY_1g61OZO93JE{~5*m5NH+ zU@1XLP!y0v6ux;Qy#1}4|JR>-@qhUAt>6C4724Ut7=MaU&(=$pbTgiD_WLX`gK;si3@gY5En5&-V(%`GT+&G1u@ z)x4)ibMyy}u%aLs5iG;mZTf*HM(x2ecFWPur0W8R^&kdRP|F7%8A8Ni_5%+!?|)?Q zcVC%L(*%48v9*ve#!2l51;-#K3fK%tF{8dJwt|H8Eo|#6Z}}Qq#lL#MXNpP0+BQ1o zlyp9C3?Q`8R86BLjLU^KOB{HcA49Q@j-gWxksU!)Q;jiL>U7>(TJ12C05W=a?OWFt zcc-8HH-F^+^5;MC^{?D+mfdn0Bs!S|7$G777ID^HzdyhFj`y`cGgcXrnnAEVdO_W8!T@%o970b7bn|myg2L%gm4rJhx3DA zod=WY@%(6S;m&*RY+MYFceYd|?aOkv89c@gY+P3{!V`~O`tcw8GD0%F0>|O1L zuYc|vU;NxZ`yYP&nqalL=3jd55|dteZ_gA6NmKw(Q_495NeX6!)V0ZRdimMGpZ^mN zzx2Mr(UgAUHxGaJbGy?fdB;(qD2he0=`=)10G5)bq+EDWnI9jVnSi!5k5p{>*}inM zZhfO(&S7yBi=hKS6~mrrr1@;DE=yk&nj|#Ku;@UHy(>qRuUw8*ikJo&t=H_GbAm)_ zZZ@^@>&THtmDNlj%$Je?!4ad0ni@F<>Bs#D*q1XLo5e1fD+)C-KtC8@N|s{m zqKXic37Xm};a)6P$~XcP<`QN zd3>wy98Hgh&%4CX6N4cDkln1BtAc3P>nZ+N_5?;TC#M)E%Njt!VBt16?Iy~#h*!7H zW)y|1v-Sd_Tw6=#fO*k6z(Yl-o0U`~vPc8d%_{36hPZ>RxG{0tP~RXI=r)I$gpLcD zCxa^p)P#z^0Sv-*Oyh70!PO{43cd^7){AQjdcd58S*)8=(*o=gLyZ-}F`Ti}}LtQhI5bAGxvo0|>$h&~Z0AbvsUt70_Yfn=QcyO=uTLdNv z&SKhv#La!Spsw?FNjdq$hkohM4i5OigL+zDU*Tj96yN31YIf{#d5QxhN}N?r60|@w zECVReiy78VA+NPXNV`Z3cIC1sI*zq>G=238BoIv_Bvhmeyui(@AZ@kk!s-B(0`EBJ z{fyvBfhANIgXipRTdf%$TbLmn&+$~eEqnlAEsDXf*$o46oHvRcR;5bD}YY?H|J|^KZBQyw+wU`4bS7{fRNyS;= z1_^+Hxqh^i6)adR{ql9v!8d2DMlJ!AK#BVmLFNvW zP$k|*rJ$V=2bdzd&*x|aMzmEokQU!;k&+9c>nJG=n@J7_pr}{$7-5Iao{&>SL?MzF zVyRDHBXJN5{B6!{&%`G46BQvU!AKRCjZZTw!XVm8#cvA|vic z>pForz#M$GB$%j&G8S^$^xhg`8=XTLiaSg|L`_4pwsCW2-9HKxF>akg7{4?!*y=n9V{d`b()LW%V~$)h zrDU;@loUiwLqX8ZMb+!1l*yf^t_CJ>8;A)))NntP@+hStwQZa)!rmbbTb=K5F^5r% zOypYP(0jiraIVHM-)RJ?ic7SvSSM#qg<=pu!fNiA0I0$M7^*CCq5YYPSHe~NM^2{h z1x`>kqgssO7=ybJyzPjArfCARId3;*7*)%3Mg;eYOsH3==_HWnO0Of{J%5OZ&6M4P za0oKw38Fxl1YVWuy2G1$5FsW9)t%B5ysufR+VccddCJoexk5tNy~DYJCx%T5!bH|Y z30>2~uwC^f)tNizqP5%LyEH+4cG5*h9^lBa3zk)8y?1cPAvzQ7qE%W{ME=@e``O?9@~^R_ zAmV1ttSLn$%HEZOv-8v8G+ue(Bj@+t+PiuD@=-VkLH=jD=Z@(q~^-{4+oCk-z!Q`tQ8ocbBi74*Ea5`SA0fF4wN@$FHqs zvvx6yE_8Oc@9&+yb~AkTMgWpPZNK-_LO%NJ<-LYw7uAikz&mAV9plss#-^1Z08+K0 zrlytO=}!tmcfnsXxVtdG1;lbTXZS3NdL&Sp_IiobtnxZ7KM zAe&7-JKG%HJhYZi&WAT|$2QEyrd?i=%ggcA>&yZRx?vYdt`Wj1JHnIk zo0-hKsDdDYbyv5HO}xLdex($_oYm3i;Dzf4 zUB|22LzsmO{yXpXhz+@t8$H&Q0K`akc^^Ohzk2;B(l34R?r(gx$F&(wdN`nZytiy4 z^=WrL!58~MQ>(EQviiw`c2zI9J5`vvO`w`dI1CzdQM0yfvX)%5s8(AVxe8O-o;fKA zsBJKx69H4YQ>g7M@Nj-!wmt84b}G(HK`07_B!`FTxT z0rJqk^vu;yKDYOU*Y>)=|KWf2n}7a4{!b5<^FR5|{!@SOhd=h4U%K_5|AoK!;CH?Z zA|b2Zmy0A06A?}9@Lf!AYSj=^KW3IjN>PIZW^*w1=JD$BvSGPdEF5X_l(MAcBE$deCz^lc$LVMP`~3HR$JE;~Q!^)3lNeaw zYSMDI40*H)&6L1SOp3hC{boD%BMA{pyJ+VJEsK@Ge3#it$sOvz>d|&sjoTGgXC?K; zl`!#VrsbC9;uzaSWF~@9O`_Fi1_65MgRK4b`j!SFluaDzv5&6wrz6tHp^uc2tYBASwx^_xIn!b2stPkML=4 zkM1Bwc=j>F6(UrMOLP!Ii`fhZ2RJ+i3r_Cg{oCkAyz(+$e;s%4(RW5)k0{CDBpm~; z$zTX`9A2f^cIZUvU1`EfeoV!rc4v}f9-?}SRgV>{TBo7?Z61npQ1 zk4Ym@O-ax9h@$*a*y$X^s?xo50yJ)HNY?!s1#VvSuimoIDj6C`j!hPb{tw!0c)O zQ;cwPRgk-C89a2XgEo64f?=cGK~P{AJk1b2%wVKx?WW*v73VIzrB zC#KaO?+P$%*N4*N6xrR75gP$WYm7)ebZl9jNTjBOykrjzvwPD@A}d)@{E3+#D%Knf zSLawcd{d{)%~gp7C3z{jx5TU?iQsl>-LZfK`wJ}gxMW}KQRw*mOddSSWZp*D;Af{G zffYYLF;~>|lSG)+&|H_gAzl)A|#l ztc#0QbwYg?tA;Y05`d^P$_n&xfCBHX)yipNH-!)hdsbJY$0(v55Pb(M^j&8g0E;k# z$S3_OQBh|@h~(}uQmw3J$9m&wgejVKGSg4+YXg9sz3qsAGP)L+dJvk=kjkz&wo{yG zfiT(#Vhkg!00IL{VUEy16C^@M41?9>lo?zhp)v%~wxq>%^w=VgfI-B^5zJUD$(7E} zeY3%GAD->XO&$w9d|;-u-ncM`DJRzgW{_W~BfQjL5kZTm0dC|@$x#y2o#0K2!vo9~ z*qmZLcu@#JnEJuj8B87{)qa^dN_qUuatBAQzq%^3*TJOb>2mG=xv6si%*SoIPAp_-_2)d4zrRik7i~}oQtO+HEl~% zRo0srWG2OI*p>bZC++A+;%v-u*Hl>6Sdt1^yk1`(2gZXpsRjkGy0!^-nu z(~+2TGukGYYw4{CA|hjN zYBrp#|JYCc*pL3?5B!_|{J-?z_Ntq=M0$Sz_TJ&4O9bNjLBGE^c=5(Fzx|bONs!ak z*?5-yaJG81J-mAP?Qeejz3QLl|zVQ5C|Mhp* zXTz|~B(govM~D20XBPLjvy-ns@DOk8hwBHyil3h)S007_yI;Teo%xe=QS;jei*|3E3fUX&dOK5a`p?q`9P)Xq}h*wHigT0H1i*LZt*8RcXYYqdgt0s zt+I2mPvJbPc|Fr7eOpv-QTS9vd7_AYp$NS=x2@Q~`ZhK-LN)Z!<92!d<10hmrxc)? z6;o9uaCLQ0DjsIgZZ}Lcjiaj3q)b4ox&Yg5$5MPo3^P^FMY)UPsBIJhpWZ+Hp4YCX z?f4)5wKp%%fLMmAbEmr@KZ74=+P&8x1v-ZGWd;_k4@^Qy!jtD!=_I6XCIkc}gspI9I(Ol?2_ zlY=MR^G^EC5C(WUQJLoJN~&5F=(%{w;3AQZE``^Qn$JDG{M6O?r=H$>@wi>KM1)nJ zfAM$k{>*RO`76Kj?yJwVKl%Ny=6>T=DQ6QzNdl=_op-BRO_pd;Fgs9xt|0ZVr}4I` z5n;@Fy4p4|sQHj|vl)zRwOVh75h6PDrQcL?j-}*PPp*zA+o7BcdQS8I{8!%p#y4(L z6EF;D0$B9!!`DA~^#@u01z7xyI;@)@Yw7#oucgKK{4DO7(xeEm(qr> z-Wh-MeW%$BT2S9UT-k>XGAEpz>;LH&Z{1upcTR~G0S-T1Au!T-xYzOYsZKe&9YfD| zCk(#BTJP{CW+LJjN|s$}NL8J%9a2&2h=(x^Lrz0+x73fdO4gsBLCuFkm*!qzo5X>@ zqGO@G&a$Wb5B+2<2Mxeb0tJAm>AdfAe+MXk^RNEx|Lf6>KmAkR^UZJGJwHz`KYRIT zx%cqf@6l{8-#-81KlG^|_~h}O+v~sdSHJYDzw$q<-gxuFXtaNXt51X24VKiSz|1zA z)&27;$Mfq4%RA?ND|~jRU$>iQpV{vsHhmcfzOo1#m7L1$w;vr`pRZ513R+$|DDU2W zlpi*W@ZjEu{mFKA>GF%uKllCL^Wuw#?H>6Xx6Xe0zy3?ZyI&uI|M~xDeQ^A*f9liE z|I|PEkNx@E?{2^Oi>5}TH3Gcr>rLC9$ssezlyQ;38dK(-M~4|z|MT!+E>GI?>HK zTk$e#Hw%`WL7|N~sTG%i;e3-*F@hBhO$;%{E|gpX!OZ$~E^2Kf{rQ+0Ax9aC7c0eA z>r%IUJ0c)lYiJ7GGO?6la5V|6DO}KfG zm2VgNt6c}mJxpg}0_))cM4(8q1qn(ERm#0jq9_Ij0-A5h7T)BXjj3S$!V`aW@o)!}$r; zpG|}yk|{h1tAc>wS{$SVL8yU{qAtQrrCEeLDhM!*k>F&-0fxC3oj#KbUQ8QnTZWh> z01^veM1h4grCP+6s#anG`*wqI@I0bqX9=$6V24`mlk;xP6CgsdBPY&c0F_~q&JbN} z767I=tIpsoktdcaakGe?lnBOvAv8?n)qCO>&=p4Bsx`Yf7?TU?34HC|a3Bt3#Yo`r zP!DpGTXBaAi8DbILg!oU2M92q^E&y54=@WJ7_p<}lJeHt1)ZJfdgH5=S4Pu(ffx}R zIzRV*tR^o~^C_yz75(#FRy_%fC6EUI+e2HRH{m0 zlkU?E90~A}5F1E9N?=0C6G?}~Q}5jzFa&`YAfi-=kE0kFoQT#d@3(FaFrBTD)n$%A z-n8g9P$goJf&)nni4)qE059q+kU*AefFGE~`6%w5s@)6##x2HzYHVyfBDf}UzzD^? zZRl_wvikbm%qC}9)q+%BZ#^CWxMWvzx1Fu6KGzH+JdQ@pMTsh5|lY+j0R3 z_11IE+O%8~Rv~cx+5uulHbH^lPJQpv5Q;IgWmac1B@lu*Q7M^2==)M@hHg~cF?cB! z0|Lw9824xYdyB5k6wyW7ILy=?!GsRmkt|Y2av`hf%f-< zLq5FQr@=@#FbN?tI3iocCrM5gg(Wl`u-Yaev>j#z%h|ZRM5Q>vU0AcplDn3+8-#h3 zZP{nPvZQOzb!Yd7d-sOz05jd2+cQrGOS0a`$(fNv56+S6hs8liFkeKtN#JpS>0_l{ zW$blLoXrSSl3Ge$Hl~Gha!_!hF{!lBl0)0f_M)q4DLX3hZm#0H-gDg^IMpp*zL0Hc zUH8-;6=|vA-m1kS5Rul!ZUs-*K35^g&UHYfl(Sl4332REva+bFF)E=#$eDIW)^0V; z_ZX2X5_m$%PFq$p5Rotk7I&mv+=*F0%v_%uWLhCztU3{P#+0gW3xEWU65vqttc5Gj zP{h1qqMey?N}+AcT!^fqKBwX;rP00Ql5u&Ma_hKwrDMT(b5n3$_pR={O7*+=l}9wXjwqe zX@kL$shve9XE8XT8ZZF|LUb}EV$&iB^>;6kL*$&i-H%tU?0x?yKl$H&;rl=M_S@j% zWqojIe)*Z}4<8OWnasQAKl1ETFI@YJ|IIJG`{BJfZx*#k z`Inx1`Nnd&6c;+aGCxb`KeVG~7QEH{qxrRGj?Viu+gmWln@=4q=JD<}w{tvq(7beI z&V*z-3-ZF%HgQ>vHebZB&AjOT-n-|#*Gimido3n$CLWa=2I2Hkuf%8Pn{S`z@rzfj zk@>QjG5*fi&fa{`$EIz%Fh2{&-stbVeTKrHdEw~2 zlYWSTqt=UO(S!Y&K=%%3{iE%8vH|lePw&5SAm8`V<;^*b2_LL5pT%o)diF@tTHAe2 z+?dFH0nufN9$EPrD#Y3iEoW>xC+3A{9*I)e93u zeIrahP=;#d@?tuGska~V;|{4or#Oc*F>?iKQSB;L42lTT)LLSZx)`W>60eEBqS*GS z0{dJi3W8;I2LdJHHy=Fu;m=$@KHmSOUwH6me(c2?`(3a8H{LqEHH6o$&mMkw+Aczv zNz37*SN$hm-}~(K_J4doH_N73%0c5VT#g;%EIB*ZgEF(nIj0E}v*QvnS5B$BL0&$=aX|X5Q zm*KgC_LWP^Ph4$Zy*z*RxZ9ga{p3sWdyj^{`Cm4z5^nrz+%1wPp5$TK58 zSjKC6jXPAmsB@H{bC)qf4DN=<2Rn81yvRw=j&wd`>SuIW&vrmz(8IJwbi-`06zNs|NHlP%3GHO z31O3vQiVqx?#=7@eAuBs{Ne;)3e&qVKiT}?T`A4&BJ?zglpV;W5OdSUydBit+%y+A zbwHRcZQzBwmJj#y#<>v&nGr&u`5bM7Ry>MB5CkE(Mi5bCG||`Rw14QQ4}a&4Tf_FV z=VzPw(fngC9en!b8}Hw~uLlboOUL2Te)!5)Pk!#N{QTzZJ>DxY2ao#j9!zO2-j4`O zvzd=$={KKvVe$G?dv6@KA8zvMJYT-tz4GGz`|mvZnO}JGPKHInICLcC;d5X zc(#bky=FP4#o-LOU*CBT!@1o)9fZ2}BhTF2yL{XZ=0E#OUtisND;|XwdGpR!f9@~; z)%Jh=Pd@$f%|G_f{Imb<|K%HY|7&OkZnX0@lv1V(pLvR%@HGArrXXknky{8b^%%vA zl~T^vE<_SVgqy%DfFm}tN#*u~a}n;^SY;diSaQ)kruv*zGdFMBrke!^f9KZuH{UF+ z%w^7H)z=bXN}h`~O^9%JbhFN^bTiM%bJFEO^WyV+fBrvv^rhdkzHfNG2yBaa%)N}G zkK0V-^Zkw}XiCDuLP|Eh!3nAgu52Qk!q(fugO{6M(}P9>Ez*oG|UihSlB!Q+XY-}Ya-k57CO%Nh1&v^=0;?e4}il-|Rf za^YL=!U_)daeRzWk6cD@KrQ}IgcDfcx*G;vY^0wkg+1P#`$a7A0)C5&{G->+P{kwF zwYh8Lg^K(5MdBV8kbIVT;rz8)-4zwst=H_bXy?eH)>=ww9K_F2oEer-0XmO4;xrA|(018nmzCwhYkn7ycCf9ozj2IlaLVR5v z?mQD_^4e&VnqUP5CgPk*JrGEPYj%lTio3xgP%tDDqSe*|V{gG_G(XX{BW J@na9 zLfhfwA^J7;4v-5To?x>w7(kBfYT)Xb(OvND;+nE4x{M36rhj*(>&ZFJMV;v})6A+( z@bUC=l5_fW^5fq%N^-Tzj(q|IyNmGDlddS0MnpoE{o-FDA+KvGnL@uL^tc;%kxQuM zlw#Ax9$A<)X=vFDY4jjevPE~>VdDYU3}!0Dp^!jY+!PXt2(Df){Gtv=%EGN)9w6_mS=reMH7Kc+F-Id_*;w}K342wNF5gQjJ~SS8xE23Xe8_zB|9@r-PA#3rAnG$*(q=_ z*9;E3-Zf(=CNZ3xI5~H7@uF&$)textD8!pqG-nb>a90Z<4!sqHt4m;2XJ9!CYSa&& z#zM@Yi)mCl*V&@+QA_d2ez+gt7)N)fCQ585r#z4~K~kZihbcN|q#S2lCN7xI_ZdFY zA)P`6k}mcZiV1*V=E2>2*bRB*e#oxO)cCVe*r)UktPrj$`lbY zuM2D9V!j@Vnc1|cLDA{^cdM23Ix#0zud-eOBuEGnL~<^!Mh*g+CK6FL%R6u$i@2FP zS;?k#--;??&pBBT5ssl@;XD*AF2ZhZYG5$e(j3D*#0uPZz;jX}&Pmn4!aD#Wk7E{Y z>hQ`8BAl~@$RUP277n3gv!Y>E_Zr3_j${AaDU;;4(;aJbi zp{0VD>R!vIEC;(LHA8ILG8X2@Etdk_q%Z&G8{hw_m*@M}uD>$>gFo`UfBi52<%hTL z#gjx$(=@Zqx9%=ym+s#_{rc~Hb={BiOZy0IO6KU&8bA6c|Iqh+?j!HNap%SBN1|A7 z@@AcVHvjO^`Mve9Ol{8Augj&I$J<-0?YXz}_Nklud8_A-`YZGJ2VOh6ydQt{YY(5j zHh^WhJWC-^al_FuTNw7LAu z-@p6!-&pqr&%Ag9(8-(l! zs6d#6@oKeeIV4?elLK08NF^1^2F+QEHC_9`qt&&ZbRetcVj@brVO-VN z)oxrh7}i-lvDDLQnlS$acPrL(@zEyTKT8y6P6cfT)E3wi{K^a3a_z+F?yP>^{)fMM z{^x$}k>%oHhPH#6vD87#gm;}Pf^Zn50X4`<6}*rKPZq@p3~@-N!W`zDeca=iKRZGxb_&_ z$!*rec}Iao7&#S*4Vi`Ki>BUb?V?ND92yS7nbg$VrhDTSoqjc}w(V>=%lF1+ zMorhQ&(nI9%uqw`X_G^cJZ2ribOCa;uBFS@+R)nBs+>RUhgFdf(pYK(bnKG{X=lOQ z({^y3m~PmmFQ=NtuDav~P07_XjU2d)*-ELxY&g0Fnn-CZ*~qe2mUGDi39A`wIz4nX z62_F&o3_J`=N?Z?NUBo@kN1<+XtQ-Q3_TwGr1Y-pFrBQ_hHo`QhOH>q9V&TT*1`ju-a2yc8%fA@C~$Wun@ z{pfN$I;Q0%z4sv=o>_l_K@es*7D|K12nh&F#DF{^8Q?XI0LZS?Wq4er@g2?Nq8s)^ zlcql4o}{qAX%{%GAE$xIb(eU#*kP+r?f;4>6ZWiAYel?D3*6mH(Ohbh$S-PXLd5Jz zVbw)>5lNiJ0d)vPO+eAfYt2lkTlb=7o?StMySoWfXhZ5Vk&`<&tQSop0KzpbpQc4C^DE#JvIXNGMYPLBhtkBs;di;YDl5o1G+w=naK()PX|G6s4gU9`~ zz$Lq>xjHu-8fm)5ipDOCCD$8G6*(yjLPQ(E4XGpbPJ~RzD~Ay?pPX9TVX=oM)0iQR zoSl?GslV?c-uHFZ^LVCX7gJT+z2t1tPlOic?#11R!cH#9JSFiSpHA;SB}_}P=`yP^ znCX?dt6aOqNl-(Egz4Mh$;V`sTT_)p!g}$Dsx~geG)S)J zK1{9(!<6k}VipEFRI_U~v?Ky@#DJ#dad7NpdWZ;-a+(&da0o*JjT;Yv>T;<5@+H6= z_QZ(H9BSzMCuDzIw}@yvxDp3X84PeebHXIB(BfG^M7c~Pe6PiM!EDa4MJg2+0=Efk zz3r=F3`a{IwwA^!ECWk@MmibV7TnT$3JY&(NyuY%b8dLG z9v3s&+v9^n5%`#>AJwymj)|xaAd2&tk&+R3vr28}ES!=S^)b`gnYImkDbmn_gO*=)@@qIihGTpeC-rncqSV7pFDOTyeVQi_eEnTzKd zVw94zo9AsNB2#yTE3xo|6GF8X?CQzW>w3B`c9j8=AocdIn@PA6OFi*4bD0jwYXrz^ zdgUSnh#lskGH9$!PE5KeiAXJ2S^c@H`Af~*O=Q}F62WRNxGLeRo5iLh7B@Kf@#y(t zj=Vc+VvPr^!ogbQJ7pyiCvJuCHq9BaG1hDCA)bcVpDai!&Y*Dgv}@?14!LjI7(Q~WZ4ER zu-)pVdQ|(|J>c%kJj6=e`DVg zh5hBz&p-R{&V&1JeCxA+_zMO6_N|RbyVz?vwQs+1`tG}bk4yQUkH0csgvt(l`|jpD zAFMLt?e|v8rdup#VUDZULouR~p1pRs>|{U4^G_Xo=DF_fS$X$l)X-kqb2Bh_z8{ut zxO8Xs;h=37i#miOI1q#=#?Z8Ue`|8MxD0yfVE(`S;`P0j#>DFp_s+}B<8E(1_>%9m zh)uUC_Nf;a+3nt%wqv$!dEr|36Q4VNuKO}#DH9i-;Jhk}XY-q>rW~JAcO>xd6U+G@I#{1C;I9LWFM8yobwXAW-PPNc&hcyaze z|M-4o2QXJmr%Am`QQe@Z7+@A=qMWCidWA#n-sDtAMHRR+394!8XcNfn@y>Nxv+gEG zQ=hTEgLeyAt0^Q*nlS8eEncHNG{K>#AT=|bQZBU@!^}cthT0XafU(Vx*8M24HTPjG zn?5lK>1YpFiO%C3@MOJPnGEFwfy zicyudIp7v0xcjV)ZDe;-H*=3o%wrK@;h6j0O{s}!BHSs6mqJa$f!jrs`tjhPx%J_R zH)2B8Cu-W4uD1V+&)u9yWW{&hAHH+Hf92&%-@c#UxHI_dXgC?JEW%Mk1Wz@ufD0Al z<1m`J5uw!VbVZnZeN8-0GjN~~!^vj59*iV_fVRbsR5fkKDu`{j$EkZ0z^A?2qQeB1 zWH<92`s%SeYL>zxbug2bccn4}SbJ zUwrLv{Q67luia&CyfOF9`TFdgx9)!MJHJD#_uBc~MkNu4t6EL_fjJ0soOX_0QHo6N$6O`6Pj$Bxfgm zPHNd0Xd0Q%nmm>|Qh`IFm^urI$b5!_L&R9-GinGKoU=<8OsD4+6KnR8lk3!60X;_4 zT!^hmCLm1NZo$ILZ5vdxWhZtHm@lXiFA6O*^~S0To5_pOlPHua@l$68yCmO}F6rHW z0?eU1^07^_y|5$>D9M#jwjeQfvf@^p7)Xu)7%X8-&}92ZG;fWG`i6%y%NxA+ZTsL> zY8x^G2bj^xsr9{@VgC|$GidSt9A!iS+RhJ-UOnL_wU)i`Fg;2{{aT7wD)9_N-`R zQp2P|O(Y3!uA@=arDyXoqbP{9pidfR9L<}SK}fxEbR8W=h{7>Y5a)^cLV>+#eO=Xg z_=WdDO~r^H+%`rD@U+#_q|3u7%$i(BwSv0DF|CAVhIy$~VTPJ91LB&!{`5Onq=k-6 z&9j?%B7lOKm7;J+sE4v3A`a~8Wl#!$kg0>8c$U+|DTKnzNC-v}nT0Cx8SWg(YJH7K zQw~u|y$y>aKw2VrY%!nV(lHUE@9Vo6A(Cd4;u2h1uwd_)a>Dil-)st)#@^ikhL_5H zxj2^s6nNrXo?;TY{f?bK+R4%C;LNZiQu!ptetb$;nS#5>IPU}&7nR28 z`|!v2bG1*wy`l^Q5y6YQDTHB|B;w{?)atWVz=6GjzN#9Ci3rjKcegS7#n7T+&V?u7 ziA>8%FJ4STCz`CHksPpyVS~^@7_2_)hyuo~5fEFl;`14sd+t5VsEqFFBG5AJh+;t3 zfq-lnhe`W2k$@Dni#PG33~>%&RH<3@#7je_ZpB4lPF1{Z3SxJ~&b*8eF-p#ySKmv5|AhbNdutD9TTO~bbCrml*rX^-dTjda3 zYvaK759snW%GpjI`F5kk6dQ5%rgagE;``UxVdK{0Eatv=Rxss02a(u_Ceu>78Rj#v zrCj8~bWTKIXV$>fH8gLD39Iw6-B#o_4I5V_cMD|Ob5F*m#4v6-&M0ltY&o-4B`HEl zD0^&3QyIt7Cmpl7Po6+wxKl1hL_!SnFq0a%l_00*_U-SCAKXC~DYguF>_XSckRXEE zw<5u)>~Jm9Nw}Iz>rY>!FMNt$c+S819sk<5_0mE3Lto&A$E4+ahSRfh=YgLN&AWGL z^j0Eblwnhd_2^3X>{IFLWq?xI6PwCV zm@45+uC7{kHfS&yZY)xjWUA_>5(0xvCvbxnW8taKHIW5*$~(}s!>otHVDg zlE?lhe&UC}_}LflpPaq=k*9y>H-6{O{ri7zb9%pa_LqL~?|TS8{>Q%m;GlVMf2ARu6}xqRb#mU%55l9f z@wrzHU%c7<@|WHyTjwrzR&FfXE6dG)<#f8w*3K6^t>?vHDC1#Qms)f)#N|7i2Z?d|)I%DpmPd1jy3 zw-5R&%+KvfFxw8rh3}q~`zQK|>+P#II5McF@|hfX^_Ug*=7;GtwasZ+uhOCFE6;bA zqAlEBxg_yw^QBwczx8|DZaJIHwWs^2fU*bReeOF=yW)_7z z11v&#eC5=;w(`MEjfsky10e{ee{Bj1J(lv;BuHJd6RFxRlrt?7Dh8+ydf+q-N~ZH8 z%0)$ZCzG1;YxSjHr$}<42CJOWDS~7Uh{y!`#l(JARj{nL!=@kiW1EYfuZPW0ATkbV zF>khmzWu?2((8kV+hJRlEzrnc{o14d;kR#RY46-R`Q+8+g_jS%{p$}q+x*aLSAEnE zbGeW3ojYmF{P9=#%96kNVfuUT=4_O*OjR5v@6e$=M`= zZWjOFzw+Uie{J(0yt=*qeE0dQ%}1^_&o1M$dve_Jtl>ah=Pb#5D84OrKHBME_xkeT zy4*TV@1CW1Ps{1b)7D@H0|XR;%$X-nQ+6-zFk|BYaML!|59Ya|LcPvJh$^YN4&&WR zDb;&uusZQKH)ev>?ZkAN#RQIlSxV9g{SBmSDXSCZWDercY_|i{NLqtH>vTgrGdxPu zr1iKsZqM&+tQgwJ{rK9`^MC2bUU_aWesF7jcxC>L_tzV39&Pc)gY@2`oDYkYbZyZD zg2U_kx1Q8;pc=@Ux?nYtZC;hfs>U=?!_7^LixAv{@cR$eX=~iLH4$xlv8;V;;KHP! zn^w!U)#Xm^Y+C;~qbKOizRT3x&Qvq~H9Z!ixT6$kL8Qw^i|Q}%$97EGiEb-uVOnxe z_Y{$`*qBWLQwQ=rxA5B{O=+i%0a^A~>p!FS#y;{V%!^3$Jq z`CtCYA9(e5fA`L}-@fy?Ph3AbY~FhFkv~|`zGEE8;oICib#1(N$MZl?*Tl!IZN{`( zZ?^jI(QxUTZihhI z)tIwZ^0$Z#1B$8^9a15poNBOIqwvAOED(^26&urT->>E%CYmoo6a3DdK})`JNsjmJ zbenXP`Tk53hCzd{tM!}YZc``mf>V5fU=yN-UCk9!>&Pt3yC%?}Rd9y+jAxAxJ+^~s zd8{?0UFpQXYo;+(l_o0L?;CntJb40`Q1e-JP!d56r19AvQ$q^go*2No)=9$61gQ^4 zcZX$|)9Tc_Il4K;NP%b=P1- zdH*`hY%}=15AAeAvzcE#=4YS7vmc4)x5rx__``<)g9DaFSnOlFo+dv2B*X{18PJ7* z@JU1b?_;f8{C|CiWO-~(^CxLRyBW|ETW>cbQ~RR6*iu1x77%Fy@0rk?(P8|8*XM~fEjcI5hRi{Q1>#7&cREW zc)Xn9;ED>U2*-fjbFT^Lx%JfkG=Dko!Wi3pc|V2n~r)8BHRWnggn{Gj-ys zyP~?&kcK6&w~l(uLSmH>*f89h23_Z|rO*(H6?Io|p!q(Pzjh@f4P>%`3&x8_DL-vMrXI@f#R za;z2co#4#z_%44O6NC80HAAwKWpF*SNA^0-#WM&+uFoFek zA{$G!f4Bld5@j;J3AWwh9m8`(}6)6KA4LK;4E z%egN4(RQ@ALau-q-e&X@KomCadK zB`gA>l*@DsPDH{^REtp)xdFsAYvDfajUCKF6IR2Bc{+F(22dSIDP>0GR&iCvOMSEv zHIW(Abuo=86)$CKNLP||{j+LzI#jYfA*DhhyXJnC2lM`-ySy(=qvOWXkjpSOU0lSt zSkURi`Oxg(GtiHRlk_E)Eq#Xj!_JM4H$(G5;5T;V*sbTlfCe zf8meceenL5fA7l=9z8_PP1{P8I9fB8`OVAC;_&Ua9{sa_=AXEBFu%O_{J;Hw{1<-b z>+gKx^RJ(5hQIRHf9t_%`t)nh%v(7D`oiy@j;m7IWn=1H$Det1|D!kN^N3&gjayqS zU-iU2RKdhi<+{j3?4VTa6#;ZN`BG#p5FUA0yKC+;Mijx5beZy zH2{c7>@poV(KL0snD0!n1~T~0^?NZuuFHt&&f;mVKP7E>w;5)pY}gE`wkw9BL$S@E z+)`1eF}JOqov+c#XoNtq3HJv3Pyfz)ch4y3_6I(8{KCyHkq^Yb z`n64>`1&*Q`c>X+$hz?DG4Zm3BC)KK0XLHFkFHM3j5|TH+NN3I{)+mNjx7H7g~=5;Lf~z*G-Gy3y$ywzLloGY2QUXfP!YX&0P7`Oy`^Jqt%APtj{^AbzLi6C}XNJWgUAEBm~vs zwr=4f4z`-_4QDVcU$}L) zdhg`ayN;Lb!w+u#M?d}F|3Ck&f9g;FiO>Juw?6pHOUK81F;S+VWCdbAD$Q_o^~%Es z2l@6xayU0|L)V!2y}l^Z@~G8e(3E^Jf9t&ey?g1|83)(chUL-n^7Z3036@zxlSClh z;mv2x?>vP^@AFKMz_S)1mb8(>#u~eFbN2GbU%vah$COrlfa8~6x%0vM>vzBTL;u@< zu(xQJ^LXiaHf)BW6ie<75vEC-&N1?0 z(Gul;9a1SoSRRE$akcV(tvQ*hrm<8y$He)fX#g|@I|(32%hGZlt;U3>QoJ~`RRb7- zQu3U=U096@uaRAgH&H+a1A+6081he@u zmn_4eJ_1CVog>N+=1NGY_G#5IaH(Hz3sFJ<@hZT+cXrq?)XqgMea` z2CN5c&b{p8grsRGa?ReQF{>i9?B*e|J6W&A zohT4HNB5FJL;}-96e_ycoir6{#ME7t=0V`D+B6d8&34u2zLe2s3y3fS9K=9gO#4C% z=Zi)gX>k$6hMCdK$+MZ8G$8j70dk3y6Qzy2sjHJw9jd9DwFGl=l2AEX4nf>)r`??e z?jD5H+=aaCs7?h6r+}Jcl2G?2uGvS;%xuXCh^;L5C`c*UG(#0-Qzs5CjL_2d+=HN< zq2FQ{T*UYHsOkLh7|SE>S4Iu@V!5CU4!23u{+Pcr4I<+b$2X~KJrz1%``NiydR-|_ zL`|fUG&Gb4gTa}mx!#jU{nO0DrVn@8?_p|q?yi{~t+}29?wWJtL~drxTx(=zRUF7x zytZpV4udAGYZ)t61v!;Tprc6>Sr`Or0|3jp!h_U|CZ{Sns8+b0P?8cLk=!W_E|I)c zaE4n!(;&3);+m1&w7}Q_Lb2G877qb2q72{`1mpoRA~2#L`HpbS(^=Fs4kd&@B~71~ zDa2~?%O%tfoY%z?93jFTnqfTYR0znU7DY(_p(Jk_R9R!LTzSKV1uZt1@3EPs5e~4E zs%x1>%1kayst)ybHZ9h3nG}LGuawiSuu_1QsW^yAad#sS3#oc87MiNJ^irs6YktIa zRAPjd%IFS+$hpR*I_&KShix0Aq|OKddj}j_Tc5fFYFa{4G-x}Bs|__dM`x$rHq^~z z+;}ePLGox_D}Xa;x4<|SchiFUrn8jWSsVtHr^4vu0l>t^2Vh3!gR$+G8d0t*5)oiq(Ie6}ZWV{#%H6Rl3N85p8j zV<&)DvD9oPAp|p3aLx);@wwCi83)#^A#f9!Tm$m*h;Ce$rHp4QdcT(sA4wVHV88wH zH|=Zh2z17++`pIG2G2hmKmKaEatUAldU|w1EHdv%#M`}jLVoM(n{6iH@a*$^`OsDy zxqpY+)(Yo>FG! zidv(3|JU5&uIYbqIB#kfNakwtsoMCdsbLl8Q3dQ;i(^wWg}Lr{g9Hkah7s<b- zH&az2)}oWLdXhO*8eLOzad?fKn)!~M;?5-XfOn!hgUnf~HpHnoIhT@4HW8^gK_;ps z7ZzDA=OH$m^L5fvBUBZ~OYS9m)5`NtUv7PS_x3$4ZbZ_?;@F&Rw*wDjN-Ac=%sDCV zzOowXi!wAp6{R4w^HgXUMstK1!)(?FgM+K9>;9#y-QLmLZ@#G@K>yuUc%<}b@u6+Hy)uYYu$rr9%*^^;Cwggol;Hl3`;kl4) zax)L(O0)6mymXB`eL3FxaI39e*>CgN_UN!lrTF=H{pRKCUAQ{KkALoPL7s}ee`4?4 z&0!W<%fs8_n6)p1j`{jC2dhV`lY5)1`}nEP9em$Q^J{x@ax(NIgSp0ynf>&%zw;>N zlAk$@uU=X{bv$1LzIGHN6V=xkATsUD>Eh@FPYznpFpg(r4q8a4;RTm_8@sm}p1ssu z3i!y?R@H8w=JCXyx)%55@&5b$rM>u63-faPZ2R<4Q>Q;eD(-c#0M`kw<-3*PMWdv; z8lMylJx=7=W5DiiBvh{upVB$RQ<#ous#omRo~HFgSKY+<5;s%vsTx*+znogQ5 zVD6Lo${{RP=fw0lR>MqIT+P>;p(bz6&xduN`=nO1#frfO@DvQYG1u|x>;#}SfB1~{H-_7+pCK=ZkMMH`SZ^<*E*c6baUb_?fKJt z(;P>4X}hX*uRlc{f=l4ZN=hij99|1|*u@W<5I%U6PFCP~!wzPqMF(PYGOwyzz+c^y_1U954vNu6{plxD4(vJ(|nBVbxMUH!!qVftFl~tEq{E zDJAcf0UG;zq#OSckXUHifQqZZ|n&Z zR831gTQf|t+36alT{^X{LMMe{z3MBTyeiD#PX5llb1Eh%#%v@YN6wr#v9V;)r6skR z>jcYVBeT~*4)4slKAooeMFPktzTw5@ZQA%5F_5;{u8_xO9xv^6rKp;R`ZDzkqh2k4 z)x#CkyNQT*Gc0nT6lG?1q+IGZ)%U}8J1+OBEoTJiK}=FzURy*6d$> ze(&zXvpXN2w@2~l%GJAF4vx^Sr8{L~d%34ZC;hNoB%|7z6#r0?J z{QQ6CdAk|>mCyarJAdmhmC{d`nQAA5n|S~N8L@{TB^4OJq~=MzsJBr#8;G1FkD1)& z^FZXe6ui=*_Qu?e?$#-ktNlq=AduYBdgH3C)y+-rL{rnl2?}W@b^H=pIabu)ml^A6J8F zW~P$0^3#HFR&}*z-jqH!9k)S*T6aFZuP2Xm++wRE%-XpKc^Y*`8Q-CP?IM^44jdx8 z8DTmssL7Aqk7On1Vg)3WvJ=%kVC{d|lmTa|4!a!z?g`Mbf42+kNn-4-7a1UMb&A+= zBHS2cND1YkO9Vx;>@s6Dx4}rr30l02V0H#7Rm6*1h6Q+W3R6IV;}nhv5o)Lg*3$=e zau4kR<=$iK1gN4YTxb~Z?mJ!vTO8o2n>3%{1EBA*e&}x{93SA)Rb0A;l(4vr{Uf+y zeu%webG}P= zUHHOk7Opl=%rE9pB)ilP1Lg=kdB=9<*xi}%wEVY}NqF}wB@jpi0bq7#M5&daQY`1f zLLmwXAaF+>OS6%$QTQ zyiN6jCISgdBc^3CVG)~o9vqHbJ2q>tGDp6eB-7AE2*non=5hIw&&WHJVNVAyP@y zZ!9znu#>OX1qOF-I^sa>49+?ffFS~cFZLkO2}nIiC~b^DO(!5mpb*_0p$RZ;8rD*B zb|MYzJm=U@?oAENESQ@?on^Bv)BVm=$9U#mve(c$Gh!R8pzq5tIuS?b8euHPXJ=*6 zacqsnV+$}3D?$_$oh@ZH_t`$mP-15#E0edg5Jw`Cek&zA3Dg52)fSO1z9G|Ccz8n;fglzdu&51c+#5?y(Db7Nr=;_0O2INF8*lvc|DY0@&bh;j!wFQ(BqAZ%diA>P?t>)w*M1h(* zY&u$`#~whhK^wp%vIuLbXq{=|!@$M1VUiD2qCZs#*TgKC5&@If86v?|s~fexX1s>& zcKP;dW~`x}T5lpICZ2wgX7#mMxtRc&DKoQ35ZMKC>MGr8(t(L8l>>yj9GUFrQ@y?N zZdfD`v0JSS(++yVT1%cp4v26&@5X*mHEBYKqUr$WR74oYU}~D+4$V1sEf^fw-9$ul z?Q^1*$f}V?h?q!14Vy|oCJbeNZ{|cfE1W_Q0%?`K6O&pqYi6^V8OH69i`I`qnBAwJ zkqJzc#3{JHx9^-C-F$i|>ozE?XNeNX zRF5vrf8Yzxf8Qsb|C9gXfBcXAAO75I5iZTTAN;;geDbwdKKrp}uRnD#JKn#0uOFLW z3%T{dYF!F9>}t!saMT^X^GM(Oo9~Wp=l%H9_5GVy7F{QrWHE1;VCvV7+HCEjVG0c~ zHL8a#2F2%InjJ3|ztQ>KL?^w@4)^chTOV}t;;V}OPlyuZhP_@l>jw{4$d6C#sjJ(x)hSO)&$NA`(03IbpB`KQ4_ zDz;U0t+cY^yiERr-PtD*fbHlK&=2lRBk0zHJeZ%G{^pyTN1OCVKf3qDXJ)P7vro@% zHAAL&co<76&vlEoZJ4k)jLi;YqVB4Y8bX;wba1z6w7ZK->?)jfxkgoFUhnHE<#2)c z*$Kcd++kCyqUKF7ahi9o&N{ZK4+C1#4z+}OyjI+H>>T?ujBDG94vnBOYh%)@zSrobKa+dMeBVw zDW^7W`|-K!$K9-ZbL21I^ZlXRxYB*!^X-kL%o{vd`CjX`-hM zDKHRopUUZ`=OAiUtRyYwpb#`E2TtzRpHXmlfhm!D*P!j1|#pdZ^I5=r) z>zM?mV@03Rsg)8*#pwNqYho~)1h>YhKkxMHU;T+2Kk(Y&Klhj4|IRxjbra{j9y;to zKs%)^c7)*O6bO{_>deM1ckrAE zN-c9Fp3(And3f`whp_`EFhdQn=H=Ia>L2;BhwC%xe16cb?-9y~qr<#@@H2nsOW*U_ zAAjblWg&l*^gL}bZ-_^zlMq-fui|n)@6Dv)qDC{GNNZ3Mvx zAWSRSH`zJG}QIV}4Skk&XgaG-wcvE$ba7e2v7LC{Rz`N?@Uj%j9lz- zly@fx^_{Sx&ir;e>M9y@ih_x;;_zA*0i+UwtqL%~>_w*&B%+$5^c~O4vqAupTIhy3 z3Yj2f`S4%byxEO2$-P7yf}!w zxb1$@*ikjmnUflbU4*qhuZts+FsYgmI1=2aS`8+TW5q>i(e2vXmbd{7?VQ>UY2(AW zlVEk~?HtXF#+8q~aiC%A=j@?DQJkDO2h!r2FI=s7Leu(0AyA->)B9FZ?XGx;XqF&D zB2YlTuDfo8meR(J+($V1cO5bLZh2V0vVIqz>hZO^qXmI>_x^-j-Q`_vdNZpUfi6z< ztH}#Y&|UVYK2*Rkqd;EF-93_eGm?(Z?`tYfE+TNnuqsU# zHP?2P=Iq@}plZrv<}|uMgK*c%Fq#mglRQ`{4ySs+Y*pmO$i<;r3aO!F3X%J5Hshud zH|@7ZPOXt`a%h^8tYmjsDY}0-u! z;<1g}bz%}XR9)4iFcvYZNgb|_CRLLl)g8l8Dr(0JMQyjF_KDP9=P(m}zqXSqfZx<) z;y1&s7)`0I-MSW)KF3}e6&0)LV5&2BpTJ+dBLmg*YP-lPJ5`=EAR>>Or2rADD!`Ao z4Rt5C%l=gDbVW#C6y~WKlZwJIVV-qL>(nSvPKjd(v0=$BOhiGb8dy*}Wz5oqNhQpj zb7{I(B9}3hQY%+vI`v0FU{{kEmWvK#V=jO8fAgn5^XX6ioB#U1@!-K(6N2evovuqd z5Lwn)7ppC49Lq2&5jSmc$1tR+QSUB+&HTOF56D%OQlBM;oXK+Sq_9p{BFU+;*ePce ziXkv(6XuktsK$BQZ?>QPzEAx>{_TJI*S~t_=YHnDPDQ1O9NIFL`C=~*>F592FP%O( zD?|CjXFmN>;J^9vzud1+LYOgG9<^U>Uw{3z@A=rXw@?J@??G#04I%$2V`S)`K?laCUFIyf%OO>EmGZ&f6#6AgOK7 zw`r?+?z1jhF@P5fiA*k(lUq?@y0WC#t~7_U@Vzh08upJ~x_o=%fAMeMx^vGL(p+op z2VUQMdN1gp2XiS&MdWPolhYg{jq5yY{bW6)_4c^w+A?0wVX^R1^u>c_!4z4oCv8Hpske9=sFdWt8 zevOPx&9AzLb#RS~PHkhlSj?e9wRWdFR^21@7*R{52Rhu$geeFKkpL0`M`30Ikx&}T zuo-KR#-=!ru~hq)Ulh>l#$y-dn3fQA!d%oql(P1H4k89@hMclzEyI|HQex9QI_vYj z)Aq^@ZsP~{&Y!zxkZ8pD_9-9Fb)&2A+_`+b{Qj2?bg*Ch?G=Z3Wri=l)O`G!tT(pF zV8shp_|j}zPpi6`Gi36LfQVsb(qEWb2*KP{Z7QDzpfX&z?m*~Uch0Q-CIJ^1PS!&8@!ZeF``?Z}_G7Oou3t}f*LJ9#x~ z&LY9CFL7-l08-YJwF_cqHj740<#@5I9O8*z87?RLZJ+*w zpSI=vKlzJ4zt~%3HJq+}Iin?e4nOx-{`Q~wV?Xrlv&X;nrCaX}dCcsC*|Nj=;IjpC z+J5jJ(*hK&PoM-BJLv<<+rRZ&v%|}$s|}FGa~)*=<&QmoemdSe$ttqm`1zSOL7ug&AxeB_ejN%yDOJjy&t^XI(_xWKL5(Id;Q(B7oWTI-WxAG^|?ymRwaU|j>R~TstZdHZrfSD)0mq!O9sX;lxT5CJ`5#~B}6G%0W9V%)oNv>ijY64eZClTTXyxLMLqA1 z{mq%lwH_Bu)DGslL7wP7kJD{7#U6hD?B^du8$a>a?obDj2MP%LumVe?hz0tbe{hb>g`;2v0Tc#OWscIEBN9nMb2SIG+c6Q5>4JG0jG zaG87zlRSPZcF~i5lK-ih*%Q?+q8%*h$uyDUi7&DH_sW?g+T#o5P}4#S6;3M0#VHtmC-^Y#FqL(0R)XfnvRJ% zC3P#(1_9W{`F`iwg$(2n?zf|64NY)|6)MFU8d~nzRCm;T{`MfGI9rCN18~;7Y}5*g6Z8C>6xcXZy5WxfX)3 ztK+e`^@;JKpn|K{=N>z-qnSe@QGmI3E%uMW5yKWKc^;?#(-s`EgBbngC*V`PJ|gO$YaN2g$pW@JS$YQ4(dwMOv*^QmZeFc3rlMktOP>oa1NHsCE>k`&-R$WBG)Js7r zbz)YHx~KqwlDtl%b~r(DP##^g*F(J8=db#(W)2A$3yMMuB#<;r*@){Q;&gykvRzRrIK6-YG{KmmsE3_^99WoR0^$69T9MvwC_<$w$d9jv2ZSq(GL%K zw#53>HoX^PfiL%Yx#t~YwMD-!2L~J)E^8W#1tJy+4OxY1I{Fd0!WaWLGy4D6_2;p+ zZP|Gr_Kh*-Tx++dyXSVV@2cgimMpQ@h^;Bxv?5u7WGSEwK}g^Pf@~#-;Xp>OPqS#TSz*ek4B4wE&O-U3YtA{w$RBglJOc)g;7L5ZjhT(ojUg{=Q7K3-FE4zWNP)@#)Y`!E2TPA}JY6G?}&U z-70r(*<>CVn9aEiAvUZkTa`Qabe;J8K^Y34tn={||MVy3+%&)T8>dM_+X@GuR0vMR zkB`Dgh*In^$MlkkLmD<1acNh!@wf5{Y4rEm^IT_^3Y5|&I(6}99q$= z)vyGR1O`Df2n4eb!~|aZD2176|6um=3)fd?=clLZH^2Gy554&8wd2Ew4^Ew!*aAx_ z9)#=M9-@d)>Wc%++)QFFXxi3Xi+UPT4UIV19J#{9f)H4%u4W*Snpx#W;LHt5Q8UhQ z@~3|6fA;#fzWO`A_|NCFSj|SnkcMx)`?de&fA(Mg)PMWmtk;kB4i3rLS>jaokM_<_ z($D|QFI>6t%=0flJ3W}c@XWQ_Z-4Z?ci%j@e|K-c0Z0oG7Ju`<{)OND!teb*|Jr|W zbp7Bz{#!qhvV@4Wo`3cAx88d1WOea<-~O@Zwu8QRd!70c2(wAV!Q|=d2a~{EvgP5l z2|o35{b0h?7*P|7Kp=1c1fCsHO0lDbT-jS3OoYuqm^borL;u!yKK0-I+QTbX!XN$c z;>D#*BKizAC!rYV^*Z79&0k>eep+Ybwa~NjL!V6O}VA~FoQ+9 zlAb$`$A|43=l0-a%Pub*$H26IWuA%Nz0)g)QX~YLwlW^>Y&R~}`pB_EefK8}rX5X| z$#gV0kB}f-RwUOa^KP41TP$oGPi<6E3U)q;Q zm`;d@8u3ZXY(`)vlq$jUB^$?gSumK5?)e%6cOQT3%Qm#?tNF^irjG<^%z`_D!Z><>rch&8;MXm3B+6s}K?8EX{gQ%JMgmb1Pb9EANQT$%AC@~Y&mb8H1Eeeh~?r6B%`4B%TJADo z*92y&)&6$5U42|ffbsv?{e^K}xGXVHMVE>T8}oK3#neYgO(0i;X~~cX4#W;)FkgT1 zmGjqs0~9F)=IDj593Q;!^!}H=^v&+yWDU8=%=6g$G`Z(7ry!>o9($VK{=3}-lgTuFh9zV-kZMk z;_=OA?tS^U1tp)|x&8L*=cii^q)IQna^rhG^U~|DouHIB2?%7uouOH@9npJ_)&(U> zUY|d(?L(pg2G6;fESAqc^}@~P{@lO)$$#zBH*ViL|Gkxe>5Iqbr>k4v{33ZL5^1^M zMjt*rX_xzma}FJf6M1YRS&8ggESCy^b|=~`o7ieYIa4Y&GO5<37E&scwh4_iO_126!BVy$Bs>DC zVhm}}VNg|fuSFSX+t@@Vb~s`qL$8lfZk}CDF-!dZMBJ0yAAce;_6OUwpZIg% z6(o+^p8DDoz0YSf+5;HwqtBvl9+)m6WNrpH1##7}OiB&K!GOV2L6l0n^`aERrJrSt z!ivBE36B+mVu(`7K`^S-^1e-&G!Q|`aLu=!5uLj_rR?XYIJkoO68#ox(B8&Focd$7)a5_$ z_%o*-BA^UmCn7Bf5fl)_+bO^($(?<^M+|Q#^zb%qAKDYRa=h>0atZI?v2E0=m&YzK z9*>iyB(&osgM=(wEulcUe8l==cC|kaRM*_ch={I{I(2Fy6I;=m0UFmqTr*b6En6{( zl_m)*JMWc`7u~M)48$l2F;eP1XD_85^qmN0>mrDPVG9bV@?U)c(iU7fPyxdLV$7$A zEtz`G9t2H`)Yq&NNpLrCq%^n|XF(Z8i?=F3UQy68{v-w-C`bFh>wb;GA8xW+z9vXIF_`lby5!EK(`H-C%p+ z02wnjzFbgANP{oubaVs?esPM~)Y}GqZ#G9RV1`U(y|(Q}B{G;aTd3P(=G56%Q8J9s zZ~f?6yf{g-fM;LihYv6;as4Sgd{kB!3rl4Yhdh^O}QYV(`Mzo?f5`xBBt`I{EJPck+p&f&{ z`bT4sdchM2fh)d*nMl|wgnW!`c`bgc+iI?iXC`vD;$sn^KY@p+pYIsmywv_<#~4fl zLJ&81Gpij)086bpB6sH~T9kH&Z@8D7oUDR^hMa^fG$_S6O64C>U@KLhb}Pk9iOh?~ zCc=$C?ixhg++AmFfct8-=~Di=pZ&$3{n>xnHlb-7cht)45ST!k3I`FU(&tGVLKFL; zu(0;oN+5=5g++r1nv1kS0@q1hOR3?t5V$V)ViQ1Il1XGhh^P(W;hlF*@7!XRZpa~s zFsE%lowT>#eC_Xl{debk2YbuC5UBK}yVx!c7cN8%&yM!8a0mUJU;Ww(AIv}SgP%Eh z_}oAFiGN07!$rS;_1eSD@Sp!*fBdtbef4lA;(2r0KmEZMU;fa|x4!cB>B;(RHGK2# zgYWqCbL~Jk4w}Q`_|Bc}*{Z*~h{ub#deEJ$hZ|RCA9#An!~Cghvni7%Q}^jSlA~lN zM^<-&I<|vx;2@OD&pX=|y?uWZLO4(O&JSJr$TRIrhoa`Dez*_=hQUbr=3cnE+yf&J z7~WJ!bEQ#YSJ~`NkG%$!!(v6PsH&l;jb^c(AKT6QpectYNNA)DfS2tSzxUdM{L;~j z*V-N0m4;G#HZ`!NUf+0B-nif0I!*1B+1Z12S`UYNvts&FUp%|L(r0h%-O2f*H`{)l zG=_U8HlNbf1t0BmDNb(nYQ>HzyIZJ^+ua)Ps+_*+*P|VwnQMfz<~6qB^5=f%KlvYh z^nd)_Pi@v~A~ADjhruz{lhqNU2Ftu!l8D@#nJ=TM?!MU$IhS@y{h(c!&D>G}p%hOU z+g`ntob;_XA5Lc_ZE`y8^}M5bX0%JRlXM zOes-!fniP7qit}08k+RyfAl-uv=j|d#u|lP67!P%Tn(SqBFM6m9t2h77 z-}|WxbuUU1y(=1Qn>MTaCuOz1b?0P#>pseW644JN?kxZCAO8G&cJv(|x$?>^{ORxe z_S+91-TT%zOfqTbL+6{p_HG=0+xJ|&_2p0f$e+4)xcFyZ`{Ho6;wzJr_ukDzi2Dmq ze&b;O`B_WXkM7(%-JT`7#)bU$N&g$K;r`j`cfNVMb1&P|)qC&d^AmU?k@VmMhw<>n zjeqyw`{UpF(sH}%4)&Wb{)=x|$R~Hsx;I{rvuR#!!oft7e(4u}sekZ5CRdQ&3*al) zt`tq{^?6Dv%+=Zh=DyD)W1PL#;LwglHpUCxoxDrs?7|KXros%hq0@Fgefgs=z4q0& zR;zP~QuSLRp3bJT$pq%ZptX=YXBD@+SvO<{i^cO#Edue`$;I-<(o&(mzp`vjSGgsN z^LV-%wwu8mEIjnt*~u}P%}Xx1WG%(afY5iD;elnn$p*lB4$;(_ruwxlCyh-oH3k~t z7^o1;Y&vV(NyvRpLne3GK|Si^`?vwX9uIs^Hj0F-5 zE|(Ca)kxp}_p4E-+F{0i@trS*0Co#g&|rOrv;}$~z!N-x0<3qE%Hx2ivGmB{*fnie=xJ4ox!IM}EBXN;lCZ;Z{s?`C z=>ifkY*2c5z+^#j0`2`tmFImqF#3b8;y>V(qUtf(Srgx{4bkN>8Bg|YYlZC)S1e9^@HQG0_5yFWoijO#7H1*}p^auTblH+|!y-JH5r<%xHqmJ zTA{i*1hEvjkSR>vim~h%B?bx9wm#}&01M)TCSY|QqUFSCYZQZL16L=NOGG zF`qy1t~UdP32Sy{aG)5yiHH$iNQo%e!Hj3YVpK49*&p7vFlCv02)4h()obXs&QZ_L zig|Dc1>r!f7G@M0xmXP`qFsd4Q`gyq0nf8#ln_@J=-u5$1Iy*!&8!x+uqI7rAutH0 zl)5sKXn@d)szO56w0}U;nYWD}UBPNo1VK$uv=tMvV&X1Ph=>`f0!$KUGV{gKWfq1` zS@>dWa4h$TTqAkgPyu)nhm^Vj9KvR>*Ip~ROk%K$b0-Sx4N`(oJ@}%Th&xKw!)yHE zk9f&Ir>miT_g&jwcpLEHXPe_s#C1-$-^(|y$g8i0wkcnFtK7Ng4aLb}@QfhQc4Z>t zuD>!eiAC6m3`UQi3pKsTEH;^Ph@J#Pm!#zwB?gFaSK$|C99SZ=!%W@D>yp2&#djTo zb&YRozH1~fhj66}xiEXhe6V=EhmZ>~2Z1?*q>X0gX3Sz*x7tQbMXeqqm>Do8hOoJp zQawQoClP>1VdGCUUTmZ7&0VRwAx3fpg}@xbNV5+0&c;LtL`0PP%#Ao97e%nxFmW)W zG!%xEp)hgXrRS8!4jmzP7iPE$hgv7kMCa@7e08fIk~D#uDFcOFh@`r!8KzF|lWAZH znvFO}kjl@_eQqa#U^$KSmb$;G1A`S6fq`lpJu{1N&e}AwX@e>}P#vu$hMdwb{LDWl zH{!Uw`gDJBmWFORjet!j&1BX}h;9lMi4@zIQ#!e~D&FqLNI@>Tb<*zP{d?c>-OqjG z*$=<<=G$NY#+x~En9bGV=zTj#Gn zdvvheTO71Ule1N)&bDmBNm2&yE!w9J+M}kO&tuxAYG}y@20|bvbe%mqPX-=RQKro% zPv>!c-d|{0o#*|%=K8Yv3TXZVEDeyxXdK(t5x( zx9VT>Cu&W0$PR!3SU03x#CtwF+vc2vC2RTe8xLZ<{>)*h2b7#JZRv2o8MY}I?ss;7 zt69jl{ao^=UYUIKTKlEfPrkKkinO;Az5Duhl`t!1In#Md&tD6B0m}-it6-NW_k%kW zx?fgTk9lgCz3+IgHE>N9nL-fePyr|kblJMBr`vLGQ{F!5zIC#F>!f@4JiUFEAFfl{ zs1HW9{Dp~Gh>3zQhjtnv?m}izB5&f~`NcQ?>}PHW^OyrA)Ju3o-HZi%Rq@&VB9A%Q zW9V$#4Sf#bOUr-#16RK5>GosK>@OBEw6V`FYMZmws#Jp#kGTw}KS6Y=^hO6%RqD-} zxMq>mU}m}0#H~3H0;jAJM1s@^zN*#RxvRP$4_jCPMG6EfVCGrNMAMS~*r%WUpZ{Ag z|NUQl!@3@`8M(2hk9_3DfAN=p_|wlH{CA(b^E1Ep&i8%%N)W!k)wdpO8N3X5et+`n zjp^ z2|b}0AYiWZWL+eXW@JT4)c42((m*MB>X8$M?4@`rUJR<$-bEC~RHc?eQZnKE(c*gZ z*Z#_n{n3xz*sjh)tWG@_riu>YT6yb6OiVHcNOu#MFptG3fR0o0I5X!`qSW?C8jrbk z;s}8QyDP;8A-XBGQ#XC|yT6RIp=LqTISRqUGdK3X_k)KoKezu+e)?C|U*B*eB=Fh9 z({_7$4>WP_wimsn0g=!!nyBY%*;{NZ|F^&TJHPNN{O|v{AN&(P_{#jL#eeiy|K|45 zeQpW~TX4!3KCGGP%fIwb*>lMqFQ=9*y3em)pD&jrvNxYk;2(bBpcM*%on6V-?%(|S zqg!|Ho~Psu5hHCk)n~%NO}C{#zjr(Q;#cp!^=P=ba~8$SDn}w#Zc(#R%D~ zA4->%0g_BCjT3{~R+^THNu*YrItS_c-qk|GB$Rqnb*pTW$YyR&3NY_S(_GF~m;NB% z-N1wZhL(Ew`~51qh@xjP! zvL8f{8yePby@OF(cr`hNC(5>H6mZi3ChQ+jKf%QVcLNOCIX4vy1kZp1`UGf)frO$y z+rxB;VL*4`nm~e507kw51#jjg5qa>G&}}fCf(#*|ROP6~ach*O?(=mQ^?K3<^!vKu z{r#>V^4g90I1%HQt)1ll{w}fK_tsv%hnMezjfa}cjF`iAmeeN&z`B5_hW1Jp%#Uf+ z*}+WRC1@eWGmiG z+uWNl+BT%5Ah)4F9Smk}TB)@S)k;}Io&=IWWhkYPsgJHM8eP1a-6k|_%_nGD5YRNl zf__^ocwt&e>G}km$>W^jjER+5LEr*%qCn(eD>3v%Lqqs@}G8=tgxbj;4!oN8!saSlH4`94t~0(WcVm5t4yv^xh1 zNZfT-rO9N)OLl8Pj`nL@rgBod{a}BegDC zE-&aB+1Moqcjq440q4iYKN`^$=5$#DGy;ZpY1GlaY4ithlQ}eQaMhgVmq2 z`rV;g&@eePJ(fzHb~UR^FsBHRmsC&fkU*FDDOE3NwEb&w4j@O2kN_)yASZ|bfE6g9 zoeP0FOlFXVhR#Do>CsG~8EzIL`k|KWp`D;@+zkUz0!l&29vUjy>vuG}%;MG)=SUmW zOY)&34Q`6b)MqnxLu#oQx|Q2t@bQLOG6GXd4u>YVAp{el+RQ!HB=M*mKdDphJVDMi zCT7+|EcbE!I|q`f&IEArqhAo3{QMl6=Zjk9S;+c} z+-FIOys`O$iWZPHO~_$qo`PGw;%qFYshzFG+=^1N9U{Xyie*b%4Gmqaw5T^h_LrDU zT|3*KYTEPDQx7d2->`P-4<44yS%FCiZCw%!+ce$BwVN?g?gu9dAxKWTC75|2)2y+f z+*@~6LKFMW&rga&az_u&61zzgNvNGLT;eSDXQ^gIhe6whF4p;LzdcOnyqrcMI~DaA z>qTBn2=bdCx?1H z)lv~+s9fiw8bfe5Ern|Xyn&gk@-vFYHo9`Gngq>+nL%yaxO?KF?xt4bV2@1%W+bfY z0VFru$Q3VUmRU%1x%>%Dy`4m6hD%WeF$b=(hblsIAR;gzfnq~oBT{CH4b-y3oPw6I zSk<(cBQ~O?xNwa=n>tK6@Q|{q#Ws|h_cWtjgLV_e+=f&{XgX=sX>-wAG3QArmunz$ zvos85)rC8b%q1%Uk=crRm7hSx5ZXv0xwtuT2x>GGC$k`7KA-NDtT{>p#+*Z=n4 z_+Q<9`&@{pdrNZZHeI^}L-LTNi9{H>p2?>B2lM@-?!xYT>%rl{?BV^}zxz91y>oax z^rdtbClj@J{;0fo{gprZ-5<&B@7>*$)UF=nul(jaAN;f5ef-Sio9~{z{r02Jf938+ zUpmGG(CbHD+FNJ3b89`{Yo2@I;Qqs*ztExg`F>-aPA3h7`@y=d1mQ_!Gi#zj@^ffB&lo{YAR{sL#d+PfdwknTLcA-)NuN;|bI89_Qkz({?TZai-4CYLj%v%xO4&~8BesIy>TBUc_<=vC+&C~A9)8Xz~&$rh1YJ<8t zz+eF};*1&!6KC4>Rk;(!V+P3Fie*AFYoar{%-g}1a5WD?re4=VW0J_M7M82lP||oR z&|TB0nGM<3+nz++x!QmFJ|TvFo!u=1=jUr=FMaWA;mvm+{pwq1kNTXu;z>XJp)3F1 z_dg$DIs4v3zV`!*tJkMry*2#C*Uvur)a0eBZBT9J%@^KWl~m>vuGJil%MJ^StQ?1$ zjarEsjeTdRY#k@7vtZ3>K050j-d};P!pg`Mek{;E-uW_=z0}(jQvY}V(#L=JrRlwm z{cHdG-+FYC_L3+!027lldnz=;Q}gf_Kl{{&4@A?(RvT)kB*cV2{^^&$`-KAl&m2vA z*X>{czJ6=_&b^CC+&hT=?3`Y{I=QTi=5b{CeI|ji8`ivHHY-HARGiHyed-8OyLGZf zXWlXeP)YgqdzNKnm@0^ZdxjQhu0jvWKqWz)RLKnH1Rt%VLc|0HVsIAE8QCnW6>5v)>ppq&eg-cr;d3Vr3th;P2Hvt z)5(zDd$0{Hm#)`rVYw*%zHZO-V!(t6eSdoIr+?z-pZ>_lzwfgzpS|^nT7KuX`)NIJ z!|CM061+K3;{5RR=%tS?q&fNWuPpbQ?T|Lx#3UprLk>+SI%eKY9mEnO2Cgk|X8Htn z*XGmN(ZSq`Zr5qLm`{%mXE&~0{p63F=6JF~oXmu^47RsFJv!PyTud$NPzsS#$<}p0 z@|ov<>`#8zm%sYv&;Q0Z-Z?E_zqLYiHeJlxdnYMQd9&({Z|>i_w*vXoH}R7zHP*4s!uC7hr+`M%5k7u zK?{U^($exOZC0p?k`-`(7g&ve;W7RF(v6UM%odnWfx??)>}cjl2|B=y(rTO=+a-nz zkfEI*ggR@H17IHuA%0&s{1aW<@5_1NaZLL0A6B5~7!tmO(!(pBGcd5T6X+#h#mDK> zcNEV$=MmMmhWE=%PXyA4P-BI))1j6jjj5oDuiHJ_h)8&3layRxcL2PaE9wU%^0)*h zr@#(@yAI|Bq}AUcUa}HGQ^jm|$Lf4rYaIarRDujc9{QX+r6BbK)J$X31kJ@6raF?T zg}rDQRLyIVUu=0aFa@?ex-CLOMCdyZgGP%Fa`Ito($u{VLdzbgh&B!8dlY8qw#Wr$ z5TSN5Vm?)k6k)=yz8kZNVx@79;ve~_p!S;*TaFDmQJ=NygWgm?4{a|-E{tV&g|m~} ze8!DXDM;dKSe<$rRG20cY8y`3(`pw%m(k5MQl*@{rm2LiqO8>gMB+_@k`N{o$iswG zkvg9rqiv`Z>Mr299)@?Bug6hQx{Pks4xQ>KVd2U=8VRcmx7{OjCm2a!0((tb7JK{! ziAO!6n%!z$NEE1z_O$B2R!81>-2Ab83Bm~dcGqH6W5Uj6R9m#_R;;$KR$MU%%wzYK znfJZbcBQgokI|G*T2p0nD%6q;~FS z=UAOP12NKa31Wv@+t9(akS_|%yWXX>Zi~Ky6WzJ%tz=W2pP)I$^%sc*UeNa-#^S(j z?T0sT1?SqJ6RAC98-}rb1C{QwRtRG5N49?SzSB*iuU4Ac5U(&C3`v zB#@S|bE=y5J(UoM0+`)_Zjgr$<@^+jgx8 z=+h;xUi0T)%Kc!cXR=wjt2b>3t#@5+C(_KQ;>M_Vg>izJt2tP*iWe2<*pL(^cg)+LKl1D-L3%pu#nGoMvY*yKBmQ7D1dy?o8FYE~lY(h>m@c zEVWjg30`e4AgT?0#AKJfgi<|6BxBzY%-wRPu?7XEH3~b94}%DuwLii1WzwFDl|IgZMVQ?(d55EFR}1VXMye|3XN2twkn zF@(O$eb$tffUZmP`GgpusV)fHp+Xqsrn|yyplGG3y99OviAWS?sccj&-X%J?@#1{3 zxcm0&!G|d9nt%N7|L2eH-jN_-+8{JBw97U+dC4|eOf1*Wb6c{t^XBk)FE%NqZPGMZ zw%_{Jo!4=H(|6OuJuOLE`Ov4H`*;834<9d^yPF;j-@JJc=JS%%dk@yDdv_k)J2^O7 zY`nX_$u}pl&n85v(-=aGao+geRFQ2+y4{vpWGyNnHX{a^vr%B&I0#pk%O)@rrh(+L zsbF^;^3h2SW^$mIsqRV%c7Icgn!BnxE+;hFeP%`&f6bY&@GgpCWNurrrhd>;yf`Kk@g0BqGWNI|GO0q&t35(574XN$bZ;h;U%$2e zuYc{mFWlR_dtSOOYj)VKl01lqh=@305Sf!1xz+1dq3)`tid+DvYJfD5W)kvw>jh3) z7htnRm`3sBW8?W~iK(n*9d8;>MbYp>0@Zyc*gO*Xy6`Qqu{cy52eEp=zZ1T*FStFRX@$IdB`BC@1 z&oA4Wg|o}9ryT;dB8A5ySB#VyB4z=h9&vT-v$rVC$$HbT1{^TRt48~{rsFX@#@S73 zou`4Keb3YFoGqR`{EzR-$Fqn(**w+Rp=Azm( zLQGk$n5la))jC(XX@3DL9vhm^%^iW9$#VI?(^o$7^wP|~_N{ji0|ZX&v-w-+`rm)? z{-<6%8a!OPvYgEYz_(8G;5=)1e-ZYZeje!3vsQg|W2-CxcMe=F4D}PjL{+e59ue1< zG)i*=aW@p?BEcf}a^Bm66UxDIW&IR)sokgJCWry40hPu*!Z3P#v_K1aaxxBx6PZuL z(beX7F*`nJkM^e5j}NY0ncvuNmy>2XZ|7||UN)uQo}8Rf0Pl#cyPVo?EiocgcSOy4 z0o2yV`t+>+pz)|e97TIA=IyjC80!t{7a`#)_tXW28xUKs2?z<5X9Zyj?vwb1Z{Ghu z{KS`j``12~&d+)O%IwO`;lXRgH&lXeGA!`2oiC>sy%ch4B2tIOIl8S@)8m(3{n!T& z_Ybqt?|t)bN+xnzuY@weMZpy^nnAgP;5((}?r!d9sW5?w|hMfAH2T zAAaS7Pv3m*_{G^Iv~bV4SaQm6i-DQKmFI4(;&8gU4@(e}29)}Idbe#p`GFVrPj&nH zy{_A=mwW9-iiaZc@bKDAnl;lGpTF|dbK7@*tLQK!%@7X3oY==a;%p zKk@?~{j2}spZ?Wf{o+6RXJ5Rx&h2cnIZu$Cj8#*kUGQ(tYF()Nsn_~6nB15hL6kYKcwgDNkZ=9?ZK0kPc+&BFM%&4b)({=ccTu* zypw+FXXlb^fBB%p6ZR~%Q8j>rcRzBa+!2F!@2bf787YP!aQD6k;9U<@5WJ}8{P-(3 z0X3IbimM_-3gTJo>XjPy>^f+e#(Hek>{ehywq!gBAkvaT6HHyRn%Zb*RdYwmX6vDy zFuS>d0+*sCIm`IjY^DN3(-5<}J7=c}1MKQ08ATd8cX(_l66OnWf{3dj_XrJXG6UKL z77HS`p&Jd=m-=ASkU5!C4wx?k%r~2yx8^#MguVKY6vn7cVQ$ES3KO}<2F6qdv*gTB zrXj;!s}efjquhJH@nWXgOF=UMJB9&>=sPFJ-X1w{Vkm=Ksxlv7fC2%oyFM(37iggE zxm)(VD_~IRJr5oym5~Kylpd{sss+`lR#Ac|PY>OrWM8kl-cP2EBCLru#+f_$T&Aa;e;?;e%jjoOA!{mT=%0xB{CN0&r zvLrODd@`k`p>{%PODN;qY}pau=F$j&+-nGsfY`7p&_bQlcC3`%^)AtfiZs)Lnziv_ zt24|durlWC&1k#z(?{4pq`jr*gv|<}B_I6i6&xPXFi5|$(%0G8NziYdK+CysHzr`|4P*r+k3>=$b#@}hox#ANBlS=bBTdN#u1lb22kw)`G6nVW1c(#?ZK} z&r%3s?=W;*TAvjsgeDMCcTw_S&4g$G6N-B3b+&BMpm*}Q{uJ$Bi8J<#E(bJ|){hT-@%*&w>8;nhQmndD#>n^BZUa}V z35QFYqZXAw)9GZk6wRK7oQAU5Sl4Ok)e6i=#>Osl^-{8yQXLaD2yF&tCSg){z;eB= zcBP8!J5vsX2tZDWS=5w>n5ASR!3Yk+*iBQdMrI=i+8_72lbNYo8LSkg3JRt%2v8T` z6|q@QIhISEZLF9C(X5q-;pUnP80O9(3bL#0bvM}9;Owdn=Q0$DgujwT2iazh)r z6d$&wh7wA#AR>WF(yHs$#gF*>jKLjhYQ>Gk zOtqA{G1g=p`7)?Yu2z6Ha2*Wl45-x-M5X93=>GK&{HOoNzxV6E@-zRwVI0qr+-==gmixw!QY;;e%WE-}uIZ zo8Nv@9ry2aDxol+pL7@N{^@Ir8QZf*an|tRGLpFj=0(-~APhLByYZ>oGfa(YVcckn z8Yjb%gkn}dpDgtPfcfLV1?`Zo<3%xAX{v(^?oPs{&O~si)^d-Lq2uPnkB@FOA>@v3 z&^~F1;^bv06qp&09&LWR^J~`^uJX*)>Gg&5op$S-VdtlXdYR7KhZp6ie)IH|>x~4C z!S3D5&tAcgzOwwt9z$)|NVAGkyd;zT&#eEUbP?nPR4D#9>huJ@eUBtWj|Bv2VPtF*}o>g$aXhdUScTW@VI zI$l_QZo$()4|@AYzkc%e-R-~g$zum@?gU$VIdi~+>cIRKb zy?WzefA>CoKFcSG1Qxu6C0aeYI-5=#wZ5LaD#5JQI}k?p(_;_;GYG16^;++uV`SBK zzD_kCat^|!lr$6vm0~$53#YymG25(>3fft0=iSM={yMrHR_o!d)BN_slYjNax6rg+ z6qClL(|`WWhrj;DgIAwFjvZayZjN!VMcD`1~piLX5vBsH*IX2 z#j-hCG*|bUtINgp!|9Eq>C?x{>-)3ggW0SN(?%jY3rcYzHaCWqtm-A_v^u>QvCa-K zxgiFwv(zZ=)coKW%p8$+mD*-ID^R5}jgUUn+164nVLBVK=3%s}Sh0G)(yX4#?i39o z_M|iko>Y^{f??!C_uzc}`S+TOIK%vK`TPr5pZ0Hjov3(r*TRQae0AF0d*DTpGIB5T znO$t%6?r;n2*3KpZ_S`=8 z!A~{IK9z>kMQJB|u$)bt zXnAx#TiW><9G28lvF^Mzn{M;1bA9di-kn~b33zz8#*k$%9zA>W&dKKRrRNCo?l<3d z%cdb^kJCx+x2i58r6`HG>*aP(a~_Q0IyRZ^G>qA#Z9?d}oD~R|AMJMqkG}P&eg6La z+wW+%cIH5S?Z*E8BzVr$wA9hs!T{tuC`ZjSPP{}o*(e{+XFB znI@OVk6cE5M+m#n;Nt;%v}}xs23+=zJqfyJdaT;jn=BKe>>M0EdNE?C8I|4ZVqSE7 zCw=$oD}jI@5SCeVGr*ifm6=$?Frv3Out6)WkiaDsb+cm3Oe|yWECe$%1PUQI5nOk` zDqZ#3utVAja|mFtxYn=56rzMCdeK_&OazHOnXzXK328HK8i*-pZ>Kb0QnTRgg>BaL z*$itShUuJ}xer^H08Oa79}>=;+15>s12q%4XJV2Fof4dFFb?F!#!w*>H%u@y=fEY~ zY$nmY=!iU&>a`(L=r;?&Y;xe?8M7}5QxKQyd!}VI3fV1Af|p>$u%H`6;%Hh6ys^g z>ko$I0Xw;^kOxSh(2y_x$9U_XK;1OgU7(JA!MgWFt~vQ zuDCoVsu9fd)+&`y)@WM_5eG*+^w46`gmtI4-tjj0e4k!;fhbbmVmimeTi&h8>VkAl z0vsGM2Tuh~#DUvZILP@%Lj+H0Q|R?~&<3Bim@Y71pjRZu>3uLTnc&JXnvO2c&_t@Q z%w#4k;q;-JAvQwlF=9GrW@eGi#)yQ4m>q$LI1hT+KI3XN`rS^0x;2d-UFGQlnw7OE}EA{d(#WX25;^f0tHCswl9u9FLGL4ddanKg{mi+K>apVL}ksWSL(KtLzsyu)E&NPQ4Y*I z25p`0xHj*iCP8$UUU6`pR(H(W5ne&+yCNZmX@xw{Zfja|Pp&18O*bsARw2r~YZt1s zK@|={3_+NIVz!HnRbGz~L5p(a+MT7YsLf&lEXZ}kq15-e_PfVOt`;M+AVknY%xLI~ z2*IqVx;w|{>O`n(33Z##rzCELv?7$iPSp1~G$I6O8L>nnu?eY9UYl_OOv&6uWal^W zD&VRa36H-giK@jQM5bz?iK?ZZ#FoqHSHJR`zx)gTR3Z@vGsKodyAN`5CbxDHFHRp= zc5e5ddGRCb(+6iK51UCNpg4^@X;L1xU2@ADTNhAE>dF$N;W&w6ygJ95=lL6NJ-T-D zm}iqP?Ou8LTHc;B%kj0Pk-zxCr`C_oLMzqJl>iYc>+Ms=?WdkQc=~v{oQ%0SdVh@F zp0N3hb9hC*Djd$lpvt7Q%X5 zR)u9eI*qFa8ug>frAoPEwWcMI6T7+GN-#ynCvzJbUH)UYFXomUqhI|^i8oSIp)as1j_Ln!6LS7#2d>5t3kH__;?ua|Zy z>aa07xqFT{dDAxk=r`ZFf7amXE8yZ}h+Nx5NtN743y&u{XGVw-O^mUPZf(FMhPDZ0 z5D_OIa{ky-|JVPv45_pGctfk{7 zI}*I@a3^&>0*2G6P>BLRfg-33rEo$@?b6X;^Qzdt#+w)obUFZ`f6 zKA!f)C!n}!UVE57|JFq>aqj>h+?yON_`wAL)^$F)<0W>mL7W+iS&&I1&h)jr+h2O; z;%o1nfAe&B?@@ogwN3BE99g(&z(iq64a0#Y*Bv;AVwTV1tvfZS_QF6&h12|mywr{)k{4-y>_XUIo z;t;uW-v7gY_4cp5{_b{TSTy7Y0opLc_6+ikEf%RfySEo3zwscwyH*Oqj8sO)4}el^ z_u`J^00}{uQ!ZsUEY@>7GYDknwJQu}^_<8=L*IS;`NKc|XTJUa{SQ93eGsS-#KvU; z0#968nlC5&Q##&n_m;Ec!m;`RA{_d~JT~wbkd}K7H-&ZzA*rAh4HA#BhYY{r2iH z%_bO5DKJm>Lc4f)e)8Ufx3(AO!^4Lh6_)eGrZj%RqcpRq>NypP?Ru^Ivv&Wbr{KfAZ~bnF)<&97 zn#D9QtEr`Jzt{Q?e$R)ttM#w_)|-F#CqExsTE^-3ee&ATQT)Q!AH92jTML$q*kHmS zAu!UALSTwv-Dd%XCb}W37jp^0&Bv|q7%nGbW+8`(a1e4(2tok7G1b%4i>%uBsV zjm-&07){N0NcBd7Lhbx|KLE+!kIt!$W#w^S8XPFDJ?_8f`v)FC?F$wblUcT!H$8_%pH}9L&@N*ImMh97RXfsm6H>fL#KE zsRW`MPb#FGfvhnEB_4$kxv^n$bg+tLc@CAy}u-d)p_E^pI zVqrodkdRNNTn6hma6?fL(Dzucd_Tj~FV2xW2g@i;3ZvdA$AVS{6VxCyLI!KYy3_>I zZYtqXf2>N-2=1YsZM_ubu?T$^107?}Rs$SxsGATO6Ci=zNsGSk*0R$yA4f*&?^}Rc zT28>|3M4l-vp{Gk93wy&deed!;SLih)t(2hOJ*W~$;x#vAw{(drpjl-lu`)M`Y^j2flXznb7%(Z#!!zyjk0H;>^6= z`sO0H6Cw4@+PS6JvO0#r_OC?UrbnlUErt%8Go(cG1?GFMyStOzD%Dch08(16C+Mzmd&3U2KpCo=oZ5wYXfOTa|kc`TShkhjh4)>C`=w5p|ogzaRIPI5_Zj#<?OM}rY#ABGSn$`nL@}zCRWQ{DZj)NL>-#ciXvx7WcB#= z9Vhlw;4q0%c=G6hZX$p1!^{1>ei7s9ylnb#>kAigB7ILG2A1H(wJ!i^RuHt*HZCV- z2HB_u5e)0I{^CNL;Oz_!#27S?M-maMXo+lKQdQzw(M@iyMeA`uRUu&J>cx|>R;UP_T5BbQf;JEZPQxpp$|9%psyYc;JV?qCtXg9I?NsHwt{2MtYx z8H!Q|hrm6~ylb2Gf!^WSXWXoCGM%26v%8>wq zVm=Q|!>P~CRC=?brl5Mt1emBFN}s6jw3>hjV>4Px>T1H|X0eGS+_I$J1fbl<9vVl_B-pJ|J7Tbe108De0Hb1alE%b-+SxJcR%#0mu|gwfA#k1@&4YV4V%+M zOsUuXz@K^b%FR8QH)Hi0cF~D?lu$MEdixq5ZEiGzjdwHkt`^dFS`3Z#R`sF9)t5Y&Dy}h~9p#6{&jLtB_{$j0WrDe09+Mr;mq;u()oq`0R)XhL;7CRLp@1d1 zoo?~YN#5}0;iL7R`OKAzq<3y@=7)Q^S6OX-_+xvA^DFPH@aBVIIiWxQ*@KTCMJ=Z0 zEOOf0=iVKD>#faqJ=@m4xtx@UNXQJtbzf|#7Kl;f8b`{JY@rTED*n0GPHDLZsIFF& zd$du6L(9`PESKSE(mu7{9?!zfgDD4j^M3cKa{aTIv9&&8bn;`cxEft&mP z;FsV0>p%IP&-RIc^VM@#>F@o8@A&XO&d*crLiL(Ocdy)^qGo2qu%e(#>`q-$j?P3= z+javvLXgwbZBZL?Nkajl45lrwHXHAh7L4LV*&c3E(SzlL3TTz)(^+Spu+tcR`Ux?)EVl}O(#dZ)SuN8{5=Z$IPF43+U45+4T zc6Bf_jophWmm!s=ZPdIUbV%b#C=VGzDJfDyh~NF`kDZi&ZNmPS#7Qy%|G*0$X&l5xz?2(0XzgdL zFMgdS&6J62Y>kOj>vc`8UbdV6&7b@1cf5G~FMsd7I9opV)Zw+|WZCl7{dhQQ4(F3u z!;?ltBnZQtsFsAgnVAly*NYxn&6&PyT1NH2a)_anT9jGSG$ZRfhyY}2L0D_&EL?SD z-t92YRN3u8*sKEWMoFk1;h2SXdN+*B4dCszR|PtIfsjM^j0-I9(MMzcoO%2!|9d+`HjU;jLE0*hZ{ zc+ZQOo~K){-GBGa#k;HSCx85B-}vJ1QR7^a*Cqus!1|MQ3J*~d%xpchSC`qq0>eP>CuUHwe(TlI%di^VBZ+@v| z4v^&{_UoRN*)0&h=TonI?4@UZ>gPYV%4J)4(#FPVHsu*pw@I5$laEYTcF<}Z5@GtaoH|$G_#cAfiXEi z>R|~SG2cUoP~+{&wRZv#+4VB=TcZ%;k595Ybn=eSjK^H$GT`)4ZO@_Z!egYg^-@Ta z#|8w%fW1SkPUzv*M>jcxnh_5?`rtt>Be<7a0oS5>MY)6)S8xnd5Y*b&`l{C?ED;5+ zHJ{iOKTu_tUA`y0i(M0-j?3KL2qD_hQfMdVjq)H-Ehs7#(po8sh7bWOw1%i3JR!_XdP_bi~@tnM$-qWja6r4J_6N*7{n387~rNv zMzCrkBsZrZ*=XH?wz}900iFjhijo1wHu3q1HRt9I%eZ!vrc>VAw?QRm9}+M3AS|KL zJaE5NX{ho-&pb;fcYQJQ^EKkc#bF?U=xMY^Nm!hv z%f5b4V#AtUbH!svQ*~8W50QwSBbUK~_ z7E^RiCo3-&g~UAc3A8eikP9c3oXnK_&f5ml2Ft_1Z9LhAdne_}in$bLnN0#_I^Sz8 zm)P>Q$B^C4DIiP;?6D2p>E0pXh*IW952f#X*4igtJ=m=63%`3_JWLyZ_0|3B*ZB5( zCwEWz-kk!cW*%VZwT!U{9_-z1VcC^D|oa(YM7RB1BLK+G%t{ zW`emDtL}!KC?nMwWNxak0t-AO<5(wcG}D#|Au==d+nlq8C@}^RBIcpXG!jy!az{!U z^Bv>!Xm?2FAk5_Oz@ldMIEC&k>}DK;Wh*s17DJ6NFnH`0*s)s7EJ`Fmt# zR_nsdFy#<6mr7xvacM$YiZN9p5=*^3+HTKQm&?#nI0T20n*=bsgnDN%ViFNy5}^c*zv!0-|Mz#tN-Yo4S#BPbIQ zg+_8#2@IlU8e$~ZOycvy;7r6#zgAW6`t8R)`$K>HkN=7P%m4O2(QL61CcZ?~hESLo z)L1DZYz8$n)2W2OQwKb!)J|GwZRXQgKJffYH5;of93jo(YD{befrMU?w$7+>PM~YP4Ss$=l}Z04$r~A`t$eZ)AoP( z@#QCuT8A6lgWTEr&wlmdoh_dZ<;KxMXzUT$6~x%?pijHUvF`wWV}C$>c(pOSciMmD zL5|aAW}E-;Pu~22=cfWnig(xEg*G-ZW|M}7ZMqoBniu1ikku1)CflIByQHk z@Xi|lyMOlP-~N~PwzS8g*va`PUz+__fALetl2;eo7{zy+P2t+aKtvGc3Y9RnU0Rdq zGHk_Q;-t3e`VfSIWbkeJGIpjuUNeuNU#JF`}I2#oR zhZBl%moRY=vi`#Qt!ekdjXfJ_MZO~d(k1DPcWtol&cu&v5yrzmYD%!OqU&}mrDWzY zhHWaYMJ$_UVx|x{0A#R&IK6Uo^!DrbpoB?Fv1Ja|ZtO1)8@tPh3{wIiAa*mgK&8*u z=goJ0^hywa>)u6%KeH$Q#wYe}KWwMgRc~F&YNJ7KJmrmj*g6U>buQTbvOF%8&2VW8 zVy*_kZhi5ipLyv|eD{aUA@u=bMr5T_l#rH`haJF)gsfP-uke^V!S3L$m$2GuJK9Oi zBYUd~G2@vDE2dFS0cIP1_VrCI@FJ=`I zL=F~V2_^M_agZ=OFrT^(uuKu23Yohqn!pj0WgGUV+-1}3FmMAZBLvqBAuK-l;g9^l z4}I=izhy&@R?s+Y2NcFEPLJYgE}#F_t*?LX^T=xs%5d!lv<=8OGDmhHH|3ViD9+kG zoo(L!hLf|*Xhz5#2uK%g!^cO_xgl)e4wdUnNvOM0Wq|J=VY@+U_F0;9jQYKGs z@X(5|xFOq6b;L1LzS}4hF<>mLMK^sPz#sjN@BQf2XRXKUzxnxhe*5RhhbBzhCMay^ zGfC4(e)SVCe%}v$`Zs_5OZQJU&pdOiboyx3U99@m`SR%C+A3>?OB1T2xrstTgy3c& za1hRQj&^UNWJQQvp`j9m-Q6t4P;d2cccGNBi1gi%Gi%Yxv#VEq9jC^Ln|BYpu|Dq! z^fC}51z{3$^O{v+mT_M)XrU(`r|%0Vjl}|^otFInPyIWMd{wRs>=D69ES0F}Uaz5| g&dg1NQVj6_AB`tZ8s;h-bpQYW07*qoM6N<$f*5~#*8l(j literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/branding/lazdatasnap_banner.png b/CORE/Source/Includes/HTMLEditor/libs/editor/branding/lazdatasnap_banner.png new file mode 100644 index 0000000000000000000000000000000000000000..5f0c32052b957b830b9bb8f52d4737a5db4309fd GIT binary patch literal 823613 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

4%grZbLHIqN=gu;nHY09En&})ot5^HYC%fL}^1C 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%0D}~OChDd}G6$u@p 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≪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

-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 pf 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 z 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

vNB+ZTR)rdc7`vY`Pbp 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 J@na9 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 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/branding/logo-rdw-oficial.png b/CORE/Source/Includes/HTMLEditor/libs/editor/branding/logo-rdw-oficial.png new file mode 100644 index 0000000000000000000000000000000000000000..b88fc2b6f41ad319aa4bc5dabcec15ac6ca829b0 GIT binary patch literal 263172 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%0DQV$!BiDJlXR;o)BXT_YjC|Be)v>w8~hv?@sH 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

2iMkG|UqKsMkkV@FcEr!9IT};-pPk$=-SQWhj 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 G67@e2e(l!) literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/branding/rdw.jpg b/CORE/Source/Includes/HTMLEditor/libs/editor/branding/rdw.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3cab0a5e771c01965dc8d7c80347a816bf6adc62 GIT binary patch literal 12076 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 +Icon=icons/button.bmp +Enabled=1 +Order=1 + +Icon: +- relative to libs/editor +- 24x24 bitmap +- shown alone in the palette button +- component Name is shown as the Hint + +To add a new visual HTML component: +1. create its 24x24 icon in libs/editor/icons +2. create its class definition .ini here +3. restart/reopen the PageProducer designer + +No source-code registration is required for components defined here. diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/accordion.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/accordion.ini new file mode 100644 index 000000000..fa88bcbd1 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/accordion.ini @@ -0,0 +1,8 @@ +[Component] +Name = Accordion +Category = Interactive +HTML =

+Icon = icons/accordion.bmp +Enabled = 1 +Order = 70 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/alert_danger.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/alert_danger.ini new file mode 100644 index 000000000..c9e24b141 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/alert_danger.ini @@ -0,0 +1,8 @@ +[Component] +Name = Alert Danger +Category = Feedback +HTML =
Error message
+Icon = icons/alert_danger.bmp +Enabled = 1 +Order = 67 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/alert_primary.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/alert_primary.ini new file mode 100644 index 000000000..0efcfa629 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/alert_primary.ini @@ -0,0 +1,8 @@ +[Component] +Name = Alert Primary +Category = Feedback +HTML =
Information message
+Icon = icons/alert_primary.bmp +Enabled = 1 +Order = 65 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/alert_success.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/alert_success.ini new file mode 100644 index 000000000..54525a2ab --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/alert_success.ini @@ -0,0 +1,8 @@ +[Component] +Name = Alert Success +Category = Feedback +HTML =
Success message
+Icon = icons/alert_success.bmp +Enabled = 1 +Order = 66 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/badge.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/badge.ini new file mode 100644 index 000000000..99a9190f6 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/badge.ini @@ -0,0 +1,8 @@ +[Component] +Name = Badge +Category = Content +HTML = Badge +Icon = icons/badge.bmp +Enabled = 1 +Order = 19 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/bordered_table.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/bordered_table.ini new file mode 100644 index 000000000..8e196c89d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/bordered_table.ini @@ -0,0 +1,8 @@ +[Component] +Name = Bordered Table +Category = Data +HTML =
IDName
1Item
+Icon = icons/bordered_table.bmp +Enabled = 1 +Order = 77 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/breadcrumb.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/breadcrumb.ini new file mode 100644 index 000000000..3ad0011fe --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/breadcrumb.ini @@ -0,0 +1,8 @@ +[Component] +Name = Breadcrumb +Category = Navigation +HTML = +Icon = icons/breadcrumb.bmp +Enabled = 1 +Order = 24 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/button_group.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/button_group.ini new file mode 100644 index 000000000..50b342a3b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/button_group.ini @@ -0,0 +1,8 @@ +[Component] +Name = Button Group +Category = Buttons +HTML =
+Icon = icons/button_group.bmp +Enabled = 1 +Order = 63 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/card.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/card.ini new file mode 100644 index 000000000..b2c26823e --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/card.ini @@ -0,0 +1,8 @@ +[Component] +Name = Card +Category = Content +HTML =
Card
Card body
+Icon = icons/card.bmp +Enabled = 1 +Order = 16 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/card_with_footer.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/card_with_footer.ini new file mode 100644 index 000000000..f434b4666 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/card_with_footer.ini @@ -0,0 +1,8 @@ +[Component] +Name = Card With Footer +Category = Content +HTML =
Header
Body
+Icon = icons/card_with_footer.bmp +Enabled = 1 +Order = 17 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/chart_bar.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/chart_bar.ini new file mode 100644 index 000000000..28111ae98 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/chart_bar.ini @@ -0,0 +1,8 @@ +[Component] +Name = Chart Bar +Category = Dashboard +HTML = +Icon = icons/chart_bar.bmp +Enabled = 1 +Order = 82 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/chart_line.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/chart_line.ini new file mode 100644 index 000000000..2983a300a --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/chart_line.ini @@ -0,0 +1,8 @@ +[Component] +Name = Chart Line +Category = Dashboard +HTML = +Icon = icons/chart_line.bmp +Enabled = 1 +Order = 83 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/chart_pie.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/chart_pie.ini new file mode 100644 index 000000000..c491b9478 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/chart_pie.ini @@ -0,0 +1,8 @@ +[Component] +Name = Chart Pie +Category = Dashboard +HTML = +Icon = icons/chart_pie.bmp +Enabled = 1 +Order = 84 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/checkbox.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/checkbox.ini new file mode 100644 index 000000000..f394ced6f --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/checkbox.ini @@ -0,0 +1,8 @@ +[Component] +Name = Checkbox +Category = Forms +HTML =
+Icon = icons/checkbox.bmp +Enabled = 1 +Order = 43 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/collapse.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/collapse.ini new file mode 100644 index 000000000..ea08e4d9a --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/collapse.ini @@ -0,0 +1,8 @@ +[Component] +Name = Collapse +Category = Interactive +HTML =
Collapsed content
+Icon = icons/collapse.bmp +Enabled = 1 +Order = 71 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/color_picker.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/color_picker.ini new file mode 100644 index 000000000..dcb2544dc --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/color_picker.ini @@ -0,0 +1,8 @@ +[Component] +Name = Color Picker +Category = Forms +HTML =
+Icon = icons/color_picker.bmp +Enabled = 1 +Order = 39 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/columns_3_9.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/columns_3_9.ini new file mode 100644 index 000000000..e52be56a4 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/columns_3_9.ini @@ -0,0 +1,8 @@ +[Component] +Name = Columns 3 + 9 +Category = Layout +HTML =
Sidebar
Content
+Icon = icons/columns_3_9.bmp +Enabled = 1 +Order = 6 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/columns_4_4_4.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/columns_4_4_4.ini new file mode 100644 index 000000000..81c38e42d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/columns_4_4_4.ini @@ -0,0 +1,8 @@ +[Component] +Name = Columns 4 + 4 + 4 +Category = Layout +HTML =
One
Two
Three
+Icon = icons/columns_4_4_4.bmp +Enabled = 1 +Order = 5 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/columns_6_6.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/columns_6_6.ini new file mode 100644 index 000000000..b8d9ef79b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/columns_6_6.ini @@ -0,0 +1,8 @@ +[Component] +Name = Columns 6 + 6 +Category = Layout +HTML =
Left
Right
+Icon = icons/columns_6_6.bmp +Enabled = 1 +Order = 4 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/container.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/container.ini new file mode 100644 index 000000000..8e95586d1 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/container.ini @@ -0,0 +1,8 @@ +[Component] +Name = Container +Category = Layout +HTML =
Container
+Icon = icons/container.bmp +Enabled = 1 +Order = 1 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/container_fluid.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/container_fluid.ini new file mode 100644 index 000000000..235944599 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/container_fluid.ini @@ -0,0 +1,8 @@ +[Component] +Name = Container Fluid +Category = Layout +HTML =
Container Fluid
+Icon = icons/container_fluid.bmp +Enabled = 1 +Order = 2 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/crud_toolbar.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/crud_toolbar.ini new file mode 100644 index 000000000..1c8393b46 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/crud_toolbar.ini @@ -0,0 +1,8 @@ +[Component] +Name = CRUD Toolbar +Category = Buttons +HTML =
+Icon = icons/crud_toolbar.bmp +Enabled = 1 +Order = 64 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/danger.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/danger.ini new file mode 100644 index 000000000..286025ec3 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/danger.ini @@ -0,0 +1,8 @@ +[Component] +Name = Danger +Category = Buttons +HTML = +Icon = icons/danger.bmp +Enabled = 1 +Order = 54 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/dark.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/dark.ini new file mode 100644 index 000000000..67c293ac5 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/dark.ini @@ -0,0 +1,8 @@ +[Component] +Name = Dark +Category = Buttons +HTML = +Icon = icons/dark.bmp +Enabled = 1 +Order = 58 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/dashboard_grid.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/dashboard_grid.ini new file mode 100644 index 000000000..123206924 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/dashboard_grid.ini @@ -0,0 +1,8 @@ +[Component] +Name = Dashboard Grid +Category = Dashboard +HTML =
KPI 1
KPI 2
+Icon = icons/dashboard_grid.bmp +Enabled = 1 +Order = 85 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/datatable.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/datatable.ini new file mode 100644 index 000000000..383e7b9d6 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/datatable.ini @@ -0,0 +1,8 @@ +[Component] +Name = DataTable +Category = Data +HTML =
NameValue
Item A100
Item B200
+Icon = icons/datatable.bmp +Enabled = 1 +Order = 78 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/datatable_crud.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/datatable_crud.ini new file mode 100644 index 000000000..882bf7e8b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/datatable_crud.ini @@ -0,0 +1,8 @@ +[Component] +Name = DataTable CRUD +Category = Data +HTML =
IDNameStatus
1RecordActive
+Icon = icons/datatable_crud.bmp +Enabled = 1 +Order = 79 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/date_picker.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/date_picker.ini new file mode 100644 index 000000000..2b34554c5 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/date_picker.ini @@ -0,0 +1,8 @@ +[Component] +Name = Date Picker +Category = Forms +HTML =
+Icon = icons/date_picker.bmp +Enabled = 1 +Order = 34 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/datetime_picker.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/datetime_picker.ini new file mode 100644 index 000000000..22d7af038 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/datetime_picker.ini @@ -0,0 +1,8 @@ +[Component] +Name = DateTime Picker +Category = Forms +HTML =
+Icon = icons/datetime_picker.bmp +Enabled = 1 +Order = 36 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/decimal_edit.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/decimal_edit.ini new file mode 100644 index 000000000..e8adf6cd2 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/decimal_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Decimal Edit +Category = Forms +HTML =
+Icon = icons/decimal_edit.bmp +Enabled = 1 +Order = 31 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/disabled_edit.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/disabled_edit.ini new file mode 100644 index 000000000..fe458ae79 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/disabled_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Disabled Edit +Category = Forms +HTML =
+Icon = icons/disabled_edit.bmp +Enabled = 1 +Order = 50 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/dropdown.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/dropdown.ini new file mode 100644 index 000000000..5ac57122e --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/dropdown.ini @@ -0,0 +1,8 @@ +[Component] +Name = Dropdown +Category = Interactive +HTML =
+Icon = icons/dropdown.bmp +Enabled = 1 +Order = 72 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/email_edit.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/email_edit.ini new file mode 100644 index 000000000..484cfdbaa --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/email_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Email Edit +Category = Forms +HTML =
+Icon = icons/email_edit.bmp +Enabled = 1 +Order = 28 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/file_upload.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/file_upload.ini new file mode 100644 index 000000000..c1d987e0a --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/file_upload.ini @@ -0,0 +1,8 @@ +[Component] +Name = File Upload +Category = Forms +HTML =
+Icon = icons/file_upload.bmp +Enabled = 1 +Order = 47 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/flex_row.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/flex_row.ini new file mode 100644 index 000000000..cfc8258eb --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/flex_row.ini @@ -0,0 +1,8 @@ +[Component] +Name = Flex Row +Category = Layout +HTML =
Item 1
Item 2
+Icon = icons/flex_row.bmp +Enabled = 1 +Order = 7 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/grid.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/grid.ini new file mode 100644 index 000000000..ee700c110 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/grid.ini @@ -0,0 +1,8 @@ +[Component] +Name = Grid +Category = Layout +HTML =
Item 1
Item 2
+Icon = icons/grid.bmp +Enabled = 1 +Order = 8 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/heading_h1.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/heading_h1.ini new file mode 100644 index 000000000..63cb8f33a --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/heading_h1.ini @@ -0,0 +1,8 @@ +[Component] +Name = Heading H1 +Category = Content +HTML =

Heading H1

+Icon = icons/heading_h1.bmp +Enabled = 1 +Order = 9 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/heading_h2.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/heading_h2.ini new file mode 100644 index 000000000..7c73431c0 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/heading_h2.ini @@ -0,0 +1,8 @@ +[Component] +Name = Heading H2 +Category = Content +HTML =

Heading H2

+Icon = icons/heading_h2.bmp +Enabled = 1 +Order = 10 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/heading_h3.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/heading_h3.ini new file mode 100644 index 000000000..7566e06e5 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/heading_h3.ini @@ -0,0 +1,8 @@ +[Component] +Name = Heading H3 +Category = Content +HTML =

Heading H3

+Icon = icons/heading_h3.bmp +Enabled = 1 +Order = 11 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/horizontal_rule.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/horizontal_rule.ini new file mode 100644 index 000000000..f709540cf --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/horizontal_rule.ini @@ -0,0 +1,8 @@ +[Component] +Name = Horizontal Rule +Category = Content +HTML =
+Icon = icons/horizontal_rule.bmp +Enabled = 1 +Order = 20 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/image.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/image.ini new file mode 100644 index 000000000..cb921d19a --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/image.ini @@ -0,0 +1,8 @@ +[Component] +Name = Image +Category = Content +HTML = Image +Icon = icons/image.bmp +Enabled = 1 +Order = 15 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/info.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/info.ini new file mode 100644 index 000000000..f45b32fef --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/info.ini @@ -0,0 +1,8 @@ +[Component] +Name = Info +Category = Buttons +HTML = +Icon = icons/info.bmp +Enabled = 1 +Order = 56 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/input_group.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/input_group.ini new file mode 100644 index 000000000..12cc8df74 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/input_group.ini @@ -0,0 +1,8 @@ +[Component] +Name = Input Group +Category = Forms +HTML =
@
+Icon = icons/input_group.bmp +Enabled = 1 +Order = 48 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/kpi_card.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/kpi_card.ini new file mode 100644 index 000000000..e23f82ad5 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/kpi_card.ini @@ -0,0 +1,8 @@ +[Component] +Name = KPI Card +Category = Dashboard +HTML =
Revenue

R$ 0,00

Current month
+Icon = icons/kpi_card.bmp +Enabled = 1 +Order = 80 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/kpi_cards_4.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/kpi_cards_4.ini new file mode 100644 index 000000000..e08af505c --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/kpi_cards_4.ini @@ -0,0 +1,8 @@ +[Component] +Name = KPI Cards 4 +Category = Dashboard +HTML =
Revenue

R$ 125K

Orders

1.284

Clients

842

Conversion

18.4%

+Icon = icons/kpi_cards_4.bmp +Enabled = 1 +Order = 81 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/large_button.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/large_button.ini new file mode 100644 index 000000000..89fcd7334 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/large_button.ini @@ -0,0 +1,8 @@ +[Component] +Name = Large Button +Category = Buttons +HTML = +Icon = icons/large_button.bmp +Enabled = 1 +Order = 62 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/lead_text.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/lead_text.ini new file mode 100644 index 000000000..7acb1e8fd --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/lead_text.ini @@ -0,0 +1,8 @@ +[Component] +Name = Lead Text +Category = Content +HTML =

Lead paragraph

+Icon = icons/lead_text.bmp +Enabled = 1 +Order = 14 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/light.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/light.ini new file mode 100644 index 000000000..6dbf96683 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/light.ini @@ -0,0 +1,8 @@ +[Component] +Name = Light +Category = Buttons +HTML = +Icon = icons/light.bmp +Enabled = 1 +Order = 57 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/link.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/link.ini new file mode 100644 index 000000000..c4fc2b683 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/link.ini @@ -0,0 +1,8 @@ +[Component] +Name = Link +Category = Buttons +HTML = +Icon = icons/link.bmp +Enabled = 1 +Order = 59 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/list_group.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/list_group.ini new file mode 100644 index 000000000..711e22345 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/list_group.ini @@ -0,0 +1,8 @@ +[Component] +Name = List Group +Category = Content +HTML =
  • Item 1
  • Item 2
+Icon = icons/list_group.bmp +Enabled = 1 +Order = 18 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/modal.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/modal.ini new file mode 100644 index 000000000..efdaf8f16 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/modal.ini @@ -0,0 +1,8 @@ +[Component] +Name = Modal +Category = Interactive +HTML = +Icon = icons/modal.bmp +Enabled = 1 +Order = 73 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/money_edit.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/money_edit.ini new file mode 100644 index 000000000..b20fc5ccc --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/money_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Money Edit +Category = Forms +HTML =
R$
+Icon = icons/money_edit.bmp +Enabled = 1 +Order = 32 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/month_picker.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/month_picker.ini new file mode 100644 index 000000000..a0fc2d45c --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/month_picker.ini @@ -0,0 +1,8 @@ +[Component] +Name = Month Picker +Category = Forms +HTML =
+Icon = icons/month_picker.bmp +Enabled = 1 +Order = 37 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/multi_select.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/multi_select.ini new file mode 100644 index 000000000..552120505 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/multi_select.ini @@ -0,0 +1,8 @@ +[Component] +Name = Multi Select +Category = Forms +HTML =
+Icon = icons/multi_select.bmp +Enabled = 1 +Order = 42 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/nav_pills.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/nav_pills.ini new file mode 100644 index 000000000..0e34c0851 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/nav_pills.ini @@ -0,0 +1,8 @@ +[Component] +Name = Nav Pills +Category = Navigation +HTML = +Icon = icons/nav_pills.bmp +Enabled = 1 +Order = 22 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/nav_tabs.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/nav_tabs.ini new file mode 100644 index 000000000..34fdb38f6 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/nav_tabs.ini @@ -0,0 +1,8 @@ +[Component] +Name = Nav Tabs +Category = Navigation +HTML = +Icon = icons/nav_tabs.bmp +Enabled = 1 +Order = 23 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/navbar.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/navbar.ini new file mode 100644 index 000000000..a462ba9e9 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/navbar.ini @@ -0,0 +1,8 @@ +[Component] +Name = Navbar +Category = Navigation +HTML = +Icon = icons/navbar.bmp +Enabled = 1 +Order = 21 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/number_edit.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/number_edit.ini new file mode 100644 index 000000000..bb788a207 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/number_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Number Edit +Category = Forms +HTML =
+Icon = icons/number_edit.bmp +Enabled = 1 +Order = 30 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/offcanvas.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/offcanvas.ini new file mode 100644 index 000000000..870d9bb14 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/offcanvas.ini @@ -0,0 +1,8 @@ +[Component] +Name = Offcanvas +Category = Interactive +HTML =
Offcanvas content
+Icon = icons/offcanvas.bmp +Enabled = 1 +Order = 74 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/outline_primary.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/outline_primary.ini new file mode 100644 index 000000000..ea2d1922b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/outline_primary.ini @@ -0,0 +1,8 @@ +[Component] +Name = Outline Primary +Category = Buttons +HTML = +Icon = icons/outline_primary.bmp +Enabled = 1 +Order = 60 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/pagination.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/pagination.ini new file mode 100644 index 000000000..bdd8dfa00 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/pagination.ini @@ -0,0 +1,8 @@ +[Component] +Name = Pagination +Category = Navigation +HTML = +Icon = icons/pagination.bmp +Enabled = 1 +Order = 25 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/paragraph.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/paragraph.ini new file mode 100644 index 000000000..28f63879e --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/paragraph.ini @@ -0,0 +1,8 @@ +[Component] +Name = Paragraph +Category = Content +HTML =

Paragraph text

+Icon = icons/paragraph.bmp +Enabled = 1 +Order = 12 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/password_edit.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/password_edit.ini new file mode 100644 index 000000000..d341b2730 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/password_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Password Edit +Category = Forms +HTML =
+Icon = icons/password_edit.bmp +Enabled = 1 +Order = 27 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/percent_edit.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/percent_edit.ini new file mode 100644 index 000000000..7464ca5db --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/percent_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Percent Edit +Category = Forms +HTML =
%
+Icon = icons/percent_edit.bmp +Enabled = 1 +Order = 33 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/primary.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/primary.ini new file mode 100644 index 000000000..9639472bb --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/primary.ini @@ -0,0 +1,8 @@ +[Component] +Name = Primary +Category = Buttons +HTML = +Icon = icons/primary.bmp +Enabled = 1 +Order = 51 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/progress.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/progress.ini new file mode 100644 index 000000000..e7cb58495 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/progress.ini @@ -0,0 +1,8 @@ +[Component] +Name = Progress +Category = Feedback +HTML =
+Icon = icons/progress.bmp +Enabled = 1 +Order = 68 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/radio_group.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/radio_group.ini new file mode 100644 index 000000000..2b68c2482 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/radio_group.ini @@ -0,0 +1,8 @@ +[Component] +Name = Radio Group +Category = Forms +HTML =
+Icon = icons/radio_group.bmp +Enabled = 1 +Order = 45 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/range.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/range.ini new file mode 100644 index 000000000..a1f803821 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/range.ini @@ -0,0 +1,8 @@ +[Component] +Name = Range +Category = Forms +HTML =
+Icon = icons/range.bmp +Enabled = 1 +Order = 46 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/readonly_edit.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/readonly_edit.ini new file mode 100644 index 000000000..096e09a0a --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/readonly_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Readonly Edit +Category = Forms +HTML =
+Icon = icons/readonly_edit.bmp +Enabled = 1 +Order = 49 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/row.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/row.ini new file mode 100644 index 000000000..d3930a5ff --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/row.ini @@ -0,0 +1,8 @@ +[Component] +Name = Row +Category = Layout +HTML =
Column
+Icon = icons/row.bmp +Enabled = 1 +Order = 3 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/search_edit.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/search_edit.ini new file mode 100644 index 000000000..c80f9c11a --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/search_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Search Edit +Category = Forms +HTML =
+Icon = icons/search_edit.bmp +Enabled = 1 +Order = 29 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/secondary.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/secondary.ini new file mode 100644 index 000000000..e7c19fafc --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/secondary.ini @@ -0,0 +1,8 @@ +[Component] +Name = Secondary +Category = Buttons +HTML = +Icon = icons/secondary.bmp +Enabled = 1 +Order = 52 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/select.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/select.ini new file mode 100644 index 000000000..c55b39352 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/select.ini @@ -0,0 +1,8 @@ +[Component] +Name = Select +Category = Forms +HTML =
+Icon = icons/select.bmp +Enabled = 1 +Order = 41 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/small_button.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/small_button.ini new file mode 100644 index 000000000..2f7f85d9b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/small_button.ini @@ -0,0 +1,8 @@ +[Component] +Name = Small Button +Category = Buttons +HTML = +Icon = icons/small_button.bmp +Enabled = 1 +Order = 61 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/small_text.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/small_text.ini new file mode 100644 index 000000000..54fe32a62 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/small_text.ini @@ -0,0 +1,8 @@ +[Component] +Name = Small Text +Category = Content +HTML = Small text +Icon = icons/small_text.bmp +Enabled = 1 +Order = 13 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/spinner.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/spinner.ini new file mode 100644 index 000000000..b57613c6e --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/spinner.ini @@ -0,0 +1,8 @@ +[Component] +Name = Spinner +Category = Feedback +HTML = +Icon = icons/spinner.bmp +Enabled = 1 +Order = 69 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_button.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_button.ini new file mode 100644 index 000000000..61bfd632d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_button.ini @@ -0,0 +1,7 @@ +[Component] +Name = Button +Category = Standard +HTML = +Icon = icons/standard_button.bmp +Enabled = 1 +Order = 4 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_checkbox.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_checkbox.ini new file mode 100644 index 000000000..ddf988edc --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_checkbox.ini @@ -0,0 +1,7 @@ +[Component] +Name = CheckBox +Category = Standard +HTML =
+Icon = icons/standard_checkbox.bmp +Enabled = 1 +Order = 5 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_combobox.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_combobox.ini new file mode 100644 index 000000000..5aab7ca7d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_combobox.ini @@ -0,0 +1,7 @@ +[Component] +Name = ComboBox +Category = Standard +HTML = +Icon = icons/standard_combobox.bmp +Enabled = 1 +Order = 7 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_edit.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_edit.ini new file mode 100644 index 000000000..7398d712d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_edit.ini @@ -0,0 +1,7 @@ +[Component] +Name = Edit +Category = Standard +HTML = +Icon = icons/standard_edit.bmp +Enabled = 1 +Order = 2 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_grid.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_grid.ini new file mode 100644 index 000000000..1c3117e8d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_grid.ini @@ -0,0 +1,7 @@ +[Component] +Name = Grid +Category = Standard +HTML =
IDNameValue
1ItemValue
+Icon = icons/standard_grid.bmp +Enabled = 1 +Order = 9 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_groupbox.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_groupbox.ini new file mode 100644 index 000000000..f29631ca1 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_groupbox.ini @@ -0,0 +1,7 @@ +[Component] +Name = GroupBox +Category = Standard +HTML =
GroupBoxContent
+Icon = icons/standard_groupbox.bmp +Enabled = 1 +Order = 13 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_hidden.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_hidden.ini new file mode 100644 index 000000000..21bdcc430 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_hidden.ini @@ -0,0 +1,7 @@ +[Component] +Name = HiddenField +Category = Standard +HTML = +Icon = icons/standard_hidden.bmp +Enabled = 1 +Order = 15 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_image.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_image.ini new file mode 100644 index 000000000..f85977542 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_image.ini @@ -0,0 +1,7 @@ +[Component] +Name = Image +Category = Standard +HTML = Image +Icon = icons/standard_image.bmp +Enabled = 1 +Order = 10 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_label.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_label.ini new file mode 100644 index 000000000..3a3c4cd7d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_label.ini @@ -0,0 +1,7 @@ +[Component] +Name = Label +Category = Standard +HTML = +Icon = icons/standard_label.bmp +Enabled = 1 +Order = 1 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_link.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_link.ini new file mode 100644 index 000000000..f366c99b7 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_link.ini @@ -0,0 +1,7 @@ +[Component] +Name = Link +Category = Standard +HTML = Link +Icon = icons/standard_link.bmp +Enabled = 1 +Order = 11 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_listbox.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_listbox.ini new file mode 100644 index 000000000..9f2aebb8f --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_listbox.ini @@ -0,0 +1,7 @@ +[Component] +Name = ListBox +Category = Standard +HTML = +Icon = icons/standard_listbox.bmp +Enabled = 1 +Order = 8 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_memo.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_memo.ini new file mode 100644 index 000000000..63320a5f8 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_memo.ini @@ -0,0 +1,7 @@ +[Component] +Name = Memo +Category = Standard +HTML = +Icon = icons/standard_memo.bmp +Enabled = 1 +Order = 3 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_panel.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_panel.ini new file mode 100644 index 000000000..6c1d8ac7d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_panel.ini @@ -0,0 +1,7 @@ +[Component] +Name = Panel +Category = Standard +HTML =
Panel
+Icon = icons/standard_panel.bmp +Enabled = 1 +Order = 12 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_progress.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_progress.ini new file mode 100644 index 000000000..d4ab87e17 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_progress.ini @@ -0,0 +1,7 @@ +[Component] +Name = ProgressBar +Category = Standard +HTML =
50%
+Icon = icons/standard_progress.bmp +Enabled = 1 +Order = 14 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_radio.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_radio.ini new file mode 100644 index 000000000..60da59568 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/standard_radio.ini @@ -0,0 +1,7 @@ +[Component] +Name = RadioButton +Category = Standard +HTML =
+Icon = icons/standard_radio.bmp +Enabled = 1 +Order = 6 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/success.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/success.ini new file mode 100644 index 000000000..489d2a57f --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/success.ini @@ -0,0 +1,8 @@ +[Component] +Name = Success +Category = Buttons +HTML = +Icon = icons/success.bmp +Enabled = 1 +Order = 53 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/switch.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/switch.ini new file mode 100644 index 000000000..00f3c46d0 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/switch.ini @@ -0,0 +1,8 @@ +[Component] +Name = Switch +Category = Forms +HTML =
+Icon = icons/switch.bmp +Enabled = 1 +Order = 44 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/table.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/table.ini new file mode 100644 index 000000000..523d3b644 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/table.ini @@ -0,0 +1,8 @@ +[Component] +Name = Table +Category = Data +HTML =
NameValue
Item100
+Icon = icons/table.bmp +Enabled = 1 +Order = 76 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/text_edit.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/text_edit.ini new file mode 100644 index 000000000..ecdd6129a --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/text_edit.ini @@ -0,0 +1,8 @@ +[Component] +Name = Text Edit +Category = Forms +HTML =
+Icon = icons/text_edit.bmp +Enabled = 1 +Order = 26 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/textarea.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/textarea.ini new file mode 100644 index 000000000..54d1e3f6d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/textarea.ini @@ -0,0 +1,8 @@ +[Component] +Name = TextArea +Category = Forms +HTML =
+Icon = icons/textarea.bmp +Enabled = 1 +Order = 40 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/time_picker.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/time_picker.ini new file mode 100644 index 000000000..be04fe182 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/time_picker.ini @@ -0,0 +1,8 @@ +[Component] +Name = Time Picker +Category = Forms +HTML =
+Icon = icons/time_picker.bmp +Enabled = 1 +Order = 35 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/toast.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/toast.ini new file mode 100644 index 000000000..7d3bdbf78 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/toast.ini @@ -0,0 +1,8 @@ +[Component] +Name = Toast +Category = Interactive +HTML =
Toast notification
+Icon = icons/toast.bmp +Enabled = 1 +Order = 75 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/warning.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/warning.ini new file mode 100644 index 000000000..12cd84197 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/warning.ini @@ -0,0 +1,8 @@ +[Component] +Name = Warning +Category = Buttons +HTML = +Icon = icons/warning.bmp +Enabled = 1 +Order = 55 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/week_picker.ini b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/week_picker.ini new file mode 100644 index 000000000..d6b2066a0 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/classdefs/week_picker.ini @@ -0,0 +1,8 @@ +[Component] +Name = Week Picker +Category = Forms +HTML =
+Icon = icons/week_picker.bmp +Enabled = 1 +Order = 38 + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/datatables/dataTables.dataTables.min.css b/CORE/Source/Includes/HTMLEditor/libs/editor/datatables/dataTables.dataTables.min.css new file mode 100644 index 000000000..57fe56b0b --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/datatables/dataTables.dataTables.min.css @@ -0,0 +1 @@ +.dt-container{width:100%}.dt-search{margin-bottom:.5rem}.dt-info{font-size:.875rem;color:#666}.dt-paging{margin-top:.5rem} \ No newline at end of file diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/datatables/dataTables.min.js b/CORE/Source/Includes/HTMLEditor/libs/editor/datatables/dataTables.min.js new file mode 100644 index 000000000..fee1773b1 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/datatables/dataTables.min.js @@ -0,0 +1,2 @@ +/* RESTDataware local DataTable lightweight runtime */ +window.DataTable=window.DataTable||function(sel,opt){this.table=typeof sel==='string'?document.querySelector(sel):sel;this.options=opt||{};if(this.table){this.table.classList.add('table','table-striped');}return this;}; \ No newline at end of file diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/help/index.html b/CORE/Source/Includes/HTMLEditor/libs/editor/help/index.html new file mode 100644 index 000000000..25802ecd2 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/help/index.html @@ -0,0 +1,133 @@ + + + + + +RESTDataware Visual Web IDE Help + + + + +
+
+

RESTDataware Visual Web IDE

+

Complete guide to designing PageProducer pages, editing code, inspecting components, debugging JavaScript and managing projects.

+
+
+ +
+
+
+
+

Getting started

+

New creates a complete PageProducer page structure with HTML header/body and the framework hooks expected by the designer.

+

Open loads an HTML page from disk. Save is enabled only when something changed and writes the edited page back to disk.

+

The IDE asks whether to save modified content before closing or replacing a document.

+
+
+ +
+
+

Form Designer

+

The WebViewer is the visual page designer. Click an element to select it instead of navigating the page.

+

Drag components from Component Palette to insert them. Selected elements can be removed with Delete.

+

Changes made in Object Inspector are reflected in the page and in the PageProducer source.

+
+
+ +
+
+

Component Palette

+

The Standard palette comes first and contains Label, Edit, Grid and the common controls.

+

Additional component classes and plugins are scanned and exposed in their corresponding palette pages.

+

The small selector above the palette changes only the IDE layout: Classic or Dark. It never changes the rendered web page.

+
+
+ +
+
+

Object Inspector

+

Properties displays valid properties for the selected HTML/component element. Empty optional values are not emitted until a value is supplied.

+

Events lists supported events. Double-clicking an event opens the Code Editor at the existing handler or creates and binds a new handler when necessary.

+

Removing an event handler from Object Inspector removes its component reference and cleans an unused empty handler scope when possible.

+
+
+ +
+
+

Code Editor

+

Full Code combines HTML, CSS and JavaScript with syntax highlighting. The section editors are also available independently.

+

Clicking Project Explorer entries navigates to the matching source position. The tree preserves nodes you expand or collapse.

+

When an event is selected from Form Designer, Code Editor opens directly on its handler and Object Inspector remains on Events.

+
+
+ +
+
+

JavaScript debugger

+
+ + + + + + + + + + + + + +
CommandShortcutPurpose
Run / ContinueF9Start or continue JavaScript debugging.
PauseDebug menuPause the running page.
Stop ProgramCtrl+F2End the debug session.
Run to CursorF4Continue execution to the current JavaScript line.
Step IntoF7Enter the called JavaScript routine.
Step OverF8Execute the current statement without entering the call.
Step OutShift+F8Continue until the current routine returns.
Evaluate / ModifyCtrl+F7Inspect or change a variable/expression in the paused call frame.
Toggle BreakpointF5Add or remove a breakpoint on the current JavaScript line.
+
+

You can also double-click the line-number gutter to add/remove a breakpoint. When execution stops, the IDE switches to Full Code and marks the current execution line. While paused, hovering a variable evaluates it; double-click its value hint to open Evaluate/Modify.

+
+
+ +
+
+

Project Explorer

+

Shows Page Options, HTML structure, CSS, JavaScript functions, assets and components.

+

Single-click navigation opens the Code Editor on the equivalent source location without forcing the whole tree open.

+
+
+ +
+
+

Errors and request log

+

Show Errors receives designer/page JavaScript errors with source, line and column. Double-clicking an entry navigates to the related code where applicable.

+

The request log records requests. Double-click a log row to inspect request details such as headers and complete payload.

+
+
+ +
+
+

Docking and layout

+

Project Explorer, Object Inspector, Show Errors, Form Designer and Component Palette participate in the IDE layout. Dockable panels can be shown again from the View menu.

+

Panel sizes and IDE settings are persisted. Classic keeps the Lazarus-style appearance; Dark applies dark designer colors.

+
+
+ +
+
+

Page events

+

Select Page Options to access page-level properties and events. Page events can be created from Object Inspector exactly like component events.

+

The default new page contains the required HTML structure so it can run immediately in the RESTDataware PageProducer environment.

+
+
+
+ +
+Tip: Use Form Designer for visual composition, Object Inspector for properties/events, Project Explorer for navigation, and Full Code whenever you need direct source control. +
+
+ + + diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/README.txt b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/README.txt new file mode 100644 index 000000000..3ee7e9ca5 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/README.txt @@ -0,0 +1,18 @@ +RESTDataware PageProducer - Component Palette Icons + +Format: 24x24 Windows bitmap (BMP), compatible with the current palette loader. +The palette button shows only the image. The component name is displayed in Hint. + +The icon set uses semantic IDE-style pictograms rather than text/letters. +Examples: +- Email Edit: envelope +- Password Edit: padlock +- Search Edit: magnifier +- Money Edit: coins +- Percent Edit: percentage symbol constructed as vector shapes +- Date/Time controls: calendar and clock variants +- DataTable: table + search indicator +- DataTable CRUD: table + action indicator +- Chart Line/Bar/Pie: distinct chart drawings + +Class registration remains in ../classdefs/*.ini. diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/accordion.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/accordion.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b1569673b0ab0b2941df26c67d08b0bc704d7f38 GIT binary patch literal 1782 zcmbtVU2oD*7{(hfz4j;g3;Y3k?T!8zqf2yPB*w(Vi)Ec)KGk$UQ|*Fk2pNW33ouB3#KUG?U~2-)*gy@N5rV)W71r$*CpH^I zk~BrJ2_kh7fSAG}Q zsjkTKAy)?pRD~L-1w2VtfZr`iT&q)MJ2h@P*e=WOEUe0{BfYOfQmZvXp2VVG7DTf? zeP)%$U1Z*CwombJj7p4r%4_j2H(w<01rm$C8A!VPUl+Xjr7%@AO*P6HwsSEqwPy4HLaPV?#?|HP9tKiWP_JjvIn{{O#zAe3uF|k}V znwg88+g>6{RHqYkcKZAMLBdvMDBHQB>sC^4^n;xYIXY*YUZ)D>_%_s_^^zjjK)4Dm+^2HiT0;8+|u)Hu@giX12|~ zZ|+vd5Y5y+<}$uW$oV+^YCU=JcII zLLsa;-ySlP5X-0c@q6gyJ^z@i-{t9B@#rv*0wcrp57IEYES~;Po4nvY4WNLt|Qsz$jzNtsI0KBTIr}139Vnz$^)Ji^tFsQ_{O+_4FQ3S4^qMLB81K dB8|PPJzje?_Vfq5*egSj-ztYu2R(Ouv;&-%>HPoz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/alert_primary.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/alert_primary.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c46747dfdedf3047e6055661fab04f187d01acea GIT binary patch literal 1782 zcmeHEF%Ez*2&{{vvrq5^KET~SJNPD7C8ZJq*M>N%O+b3wU8P;tqfdFwlqZU@M3<|S zHtO#KM6^3vmdx z2Zs^}zT1bUYfK$^5#c}|0)@Z@q_sIL(N+-?eVk}@5jQbbEY#Wje`KrWR7WH~2j0L1 D`=W|n literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/alert_success.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/alert_success.bmp new file mode 100644 index 0000000000000000000000000000000000000000..84293557e54b4763e016529d129132e3e9c9df82 GIT binary patch literal 1782 zcmeH@I}(5(3`DW9wDt&|zysKOXA93{s~Ms@m=M5E2{VDPSzaP+(PJp2>sDKfM8Bi zK#2B56@5cU;tBj9Xmd&T5{_s=*TNy;)C4F3^==-fg{Uta9y?@WS|k=929a2POBc^^ RP58M~zJsZgUmzM=l>_K#7|#Fz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/badge.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/badge.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3abcb21394947792cd505843c8860c0f53f034af GIT binary patch literal 1782 zcmb_dUr19?99|Fg*jp3?CcV^yK~F&xm}W$w5vF@vv7m=6$h4V%k};eHYl`A{LISZdj{)LrMC+iknM|4-lD(c5xU#CG}4;oN(_?>p!BJLmpxb{@CI z5W5bb-;1_mscnjl42HLO-?x>v7!jQ!i4;VURX~>33q^)Rm(u|pI5xQGn+-720cIvJ zwP`U7PckL<5cCX(9iX;m0 z`4L5Jzxs#Wh2?1?>*oSqS4Y*vc%Kqs3AacTp2!@LqgpRGbi-XN{Lkh2}H4_0}?ErtMYr6=x2ZE7n7Oo^;hB zCwTkdr6sdyb9v)Qm1jTocHgnzxbLWIanv={Sv%TVkjU2d^3ui=i9R&0uah71O1I6= zd;wv2=(P}-C0vBa2}e{A&9;nZJq@6(hzn__C+DW?ys3K6;7E@e4n_UHBJ)#W-z3ZY zU>Q${nF#r&Jf4B-yLo2&{z#P7wnh@;^8+7j4+4)0;ieZQ`PX+ARO~WVq#G;$Mb&P+ zDr?SV7N)S6WcwcfU66$kGceZs`P;j}@xQ?B!04Nw%orRrli1ghaDJA2FomMZl(|~3 so!B+M3tg!3P@s}Qcc5f_J*lc2@JUG>Lv>9_T}@$~r&d~R{Ez?6A2;0_9RL6T literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/bordered_table.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/bordered_table.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56d0bf259b74b4d31f4bb172c02644393cf4a4d6 GIT binary patch literal 1782 zcmeHDu?@p840D%^oqIwr$N|~=lTYiAo4PiH*$RY+2JzG&hyW`RO)8Y9$7?7pM&vur z?Q<@zD&>j$`O4FXNbjS^chSDDzl!T?tqFAG*Br&6(iXKM{6!+5bzD{CE8=`|99Pv} z=Dyod;h4#*$cn7^+2I_zWyTiT TqIM)!jv`4mwjn=@^%qzGqJs@G literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/breadcrumb.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/breadcrumb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..54ae959d1db460a382c883ee06ffc9c6094a9197 GIT binary patch literal 1782 zcmd^A&rcIk5XOr~&mK*@_!sEG3u!cZP-9~BU?L_07WF`+K?Ou34Kx;Fi1A<)B4R@j z#2!@I!U3b!M5C>xibX693hnN;cDL>B+wN~?_ifj;3EG8j+S^W=qR83Pg z6?C~6MzC8_X{gSRs#uQtLDi+)qGE?iBREv^Xqr;wWgf|hvqAzYK`4j9Kv2BaKt{_Ihsb`V_t|i_+U$ z6VF=v=Gxt}c4u&4R6<22O$b~;;88IY$U&aI87R03yORmNJ zlVdhDFZx=Yh{*CJ!_)b|ITy9~m1XH7o40rtuh_Zx5)PG`x$8dA=)8I;^xB0jTw&SO zz3p<_X}@DolT^)U|Ak98sc1D%q}PsCV;0Zwk^OGh(NM6&!>(NK-9FIK5pWD?P!OX6 z3tfNU314W+1m}3-8&9k+4R&VzPhu+`-=n4+onW%7@z~?3@jV)+%r^Js6Uo9FSxBb+ zXZop+rFala8+oQ)_(G23k)D-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/card.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/card.bmp new file mode 100644 index 0000000000000000000000000000000000000000..04c1b07598b1498be9bce3859f0eaeb56c8bacfe GIT binary patch literal 1782 zcmeHDK@vnj3>=p|I(vc_>;v5W$1eYx6741Yq|<-~iJz-mRl$dd6eX0j5{}Y<1?^-eR)r{E`#I Ca1MC@ literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/card_with_footer.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/card_with_footer.bmp new file mode 100644 index 0000000000000000000000000000000000000000..04c1b07598b1498be9bce3859f0eaeb56c8bacfe GIT binary patch literal 1782 zcmeHDK@vnj3>=p|I(vc_>;v5W$1eYx6741Yq|<-~iJz-mRl$dd6eX0j5{}Y<1?^-eR)r{E`#I Ca1MC@ literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/chart_bar.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/chart_bar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d829037a0aaa95f0bc0fe7cb98133e4bd3254cc3 GIT binary patch literal 1782 zcmeHExeb6Y5DN_@H6t(q1JJWG1vAltbq5x5VTFP&Cnd4v2kBVWqc1Tt?g?kSPZy|^ z4f;Oh2_vqvP4xzzoqc#s_qzo)Pkm3SXviKzTTgC@ixTSh!+*p$L4A*WLV`lYY^Vf< onxIG$6e?yz5#+!IoMr-(H4@_l#%v_U35?lDh;xjsNk47i0%k#|KL7v# literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/chart_line.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/chart_line.bmp new file mode 100644 index 0000000000000000000000000000000000000000..32f1259fee470fa60ad554e67de6f85bb17f34f0 GIT binary patch literal 1782 zcmb_dNlX(_7{-f7&&I?PF`AfoEffM3#^uia{{(Afina zmjJb`(n3JM7$7XlA`%KST?X4}XX`BQz43q3g+(kS@#TMi-tvE6|E2GrljoG(Io8Mn zeF)~>T85yop@Wzhfz}jhN0J6wBpSg;5u)M13eWj@E|9hO0RljP zV?zT^U>ymvhNhZ38~}*~8Gt9k0a}buf`cGTaCSlnKmbVLR!;bkA5NCM-yBz}-Ph~g zC3V|NX}#le)%2^600cN>Rh7kPIHb$*uENUT=#0p4f-fj8hcb(>5{fRe-G!C>FGdu? zsw4nUEW)Y0=qjl*^<;F37`N4Z6^}v_^OD4`@kAwO@qMJ|dL(Qbgy;s*45A~d<63eJ z+mv89C&W|sfSX#_z{3mf(guZLM+#0YwLb<=C`8qhE`gf{UN3M9S6lEzMOSf+At}C> zExq}MsQJTxvtiUT(2e&;=XV6O2t+if4Zc@Dji`}gY8yvNlxGq6%(6@ zv-o`kNU;s_%_VBWVYzQsgzptsDk>sqZI zlL#ayZV>fv(cy|R5ECmZl2z)@t)|U+=0!(QRr-grT=d?s(f1`s;eBbc1Pu@y$Wz`l zaJO~*Y3EqW>#-+qG6@*8b$+$AJBq4RUZBrh7NG_G_Ag_MbV>PccTTHhp-HsmCnN+?inSF1u>?|~z%>6qB)Q?{Cb|FDb8nU0sSKM&42Yrgi%JuFxaneNOfT$D25_IIEDsIB(R5)dq9DNU>Q1r zM#DZA67(WL-vf&mAOHk7LlNK!j3a&zMc~{+Hh@I@Zh)tb1GEfHr#M)eVVPAzGYkdW z(QD^n4a))qfIM7?2@>$a%-ySF#{BAmBXt8Mr$Eey6{g}^i==+2qH(C=jHRr>T&#e} zlyyK-XUsb}t?36Kz#*!5JQfWH$au0xB=b+)j(L`14nKO=7x#wnFpA7Mo!2HD*0Ipc zVlos>1R`LHIRmIG5MA{2ie$)wJBEgF3psYjyGxga;tRv zOLhAs-3O1|khew`+`Mh24Ocb=Zp~pB@;6TugHw=boE4~i<90)iwEc}-?K{P~eWgIv zwWp+G+ab-aqB}h!K*Jx}6Owcx;hG#hr&Y%t-U;$z{P_E4q101CDtwMc{^b*gO z=e=o5dGv2Q9Cz(lvwC};;efO=v!K7QX7;jmzW=)QsH!tFU!Ps3$rAU9PEc49sD?gi zOyiHZmc^-rKdjp;0nzL%g1dwGuLOg;aq2sDW&wBw+B-T8^Mg|5KY3tlj^SJ*le{z8 zQuU5}@2~t~hM*Xdf&u0W{qXMLANL;7yeYD^T^4vwr{`h0Me{EZ4gLNy?c2r3qKjc@ zJ}p@ek{?TwyJa_DFCTeXY;Dxd0?$Bsx^orDIf`Anbw{(aP@gUB*q&?ew7_DP;d2=V zrrXq}O8X1d3mcElUidk3UmkHS9mnYeapi+b?QXF?tD@th_y3sb0#5+qcMRv$X*XB8 zUXt0iem*nriNoYz+Bif0L@}`1wWf|&^R=Rb&5CEw);yuP@LE^fj&rq7H_4ybRik@c z>X2xiobb5rckdLM;2;_#W38)EezER+!*eb5&wnl7^p*Un^YvR>8@8N2vHnAqVF`t2 z%SS#f54=Hg8DmMBAxMHmti7dYzkE`8e4VOlgQ{v{>scWBp9^ zQ`I+ZVBd(Tw+6+y$G8zePvg9U2i)b~A5WFWJ6xKQDRy6Oh1HE#ds iCy=bFt1ETh>x%f?5ufLQ#U1uK@6~zXm+?RRcm4#)*^zbt literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/checkbox.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/checkbox.bmp new file mode 100644 index 0000000000000000000000000000000000000000..fbd99aa366b75d9b2a52bdcff780feab2a67a41f GIT binary patch literal 1782 zcmeH@Jr08~428qek-10c33>qb-kG6iVl7W`d9t2`K#4Ef zNUVs8040>8LYNpU5_ljP^q3edJp-&x^BG2G0(ez|<@fPjFXROzsQd^c6%35XV_NhW SHaw%BmEo)hICTeCzQ7J8y)(1` literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/collapse.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/collapse.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b1569673b0ab0b2941df26c67d08b0bc704d7f38 GIT binary patch literal 1782 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 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/container_fluid.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/container_fluid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d7c56b70e146a618738c142ba6aca2184c7c78fd GIT binary patch literal 1782 zcmb_dT}YEr7`B@(yDkWVin5E+fea!w8DWKuu^fzoBJzkxDA6EHg%h^w%qpZ`(4j>&VHP>Z&Dtf^X_oo^FHVO`OZ6yHn+cl3^imU z=E36JM^+6DcIX`k=p+XrM4qE4h=K$N{B9u%Fe#hU1sHO_Q@;{x$yhWQTTR9lfdjE9 z4#Nb7Wh$)GKjW#yI+tezp5G;K7$z{JRPZggnM!S}7m7o|z9fo7l1OR16)CFxaUB{bNMPBmcb_OGWDFy zZmjZ5md|BmxdR-7{mkqGoo%$2@UWQ@hJ%9S9}Hr898hsh{-LdygaWgg^EV43A`(DUK_N6&)a?E+@qdaJmJ~N7gvu&ee*vS9pAlgBmQ^W;j>5l_ISuUbEn<@e^9LEp#87)E%A~YE4E$MSr%uFZrF4fsT;~`*C9}BtpLUlAA@Z vAOnW08e!vliN@|$eo9dav#I1#FP2|zPg8fo>IxZk+jEu```Hk6VB}M literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/crud_toolbar.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/crud_toolbar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..91bb313c45339968b33c6d87248946e1e37d1318 GIT binary patch literal 1782 zcmbtVTT2^36t*vY>~nuY1rZ}s5ez|JL{PLvT8su1K?Q$=eb-hKT5bB`Pw>)et*JF? zs}U@vHVH~WENaYsbK6ZaJG0v_J9TqwG_=FF!{p34-<~;V_Dg%Wbhkzu4>3Q$bN|nC zM_bj@II;iv9)C1POiU&mDx(TO2|-`fe-ZUxMgunj4*m-`BLsmu z71r@^AQrqLnKYH=Hpj}-K1{q zBO_l@DH$orq_jRfAI=kx{)Gp*A(_|no{o-Q5)nd5`hIIZsFij!hMO=s`3)opsnjpj$7oy= z!U;rWL25ktxo+TgQOJOX)6+y}=SE%K;`sO;bbuQn5;~!-8{jF|G2IOdK_K|(_^l|k^R=#H tP}hpOilhm?_gs${)%2Fnn)a6H>a98-@n430#o}K<=Q&kQ8~@{f=Qj@a9?Ad! literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/danger.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/danger.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/dark.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/dark.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/dashboard_grid.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/dashboard_grid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..99ca9bf38c9e0966081fe1bfe3a3febaf675d9b2 GIT binary patch literal 1782 zcmb_dOHUI~6s{YWuKfxA0{5aZKtapH2#F?kMVkPvf+iX_`V(|vMTBCaf5C+djVa}o zK7>fB=*oGtQyFKbbl!KyZ#wP8wgahw$(hr8?%eOoJ>R+av~O5F8)`fk;Vp!Q-sJhe9|u6dK>}5w zhHaW4FiPKrSW<{3+H88RdhcP|O#E&o8n3_q00@A9`=x;-dq$SmzSjwABF4tXGosh&6d|PSz&sPhOT8{>?jI5IBMj-1oI4z>RWl25N~nIYpZL* z%sdS}LPDI{fya|89>rtq>~^G}=L$mNLB}Ly@bU`eIjHlIiOQXrFnb>xpoY?L*KX2~ z4wy>=MqxW(KXsKG8dp}{Y1s`ev!-R&eJ?M)DM#Zp)K=FqRzH4buU7g?Lh!n)NPJ!}QQvS5`v!R0`WUW5FJ=?}c+ftE?s_VH Q^%VQOPv!N-6a4S|1$AT-!2kdN literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/datatable.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/datatable.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56d0bf259b74b4d31f4bb172c02644393cf4a4d6 GIT binary patch literal 1782 zcmeHDu?@p840D%^oqIwr$N|~=lTYiAo4PiH*$RY+2JzG&hyW`RO)8Y9$7?7pM&vur z?Q<@zD&>j$`O4FXNbjS^chSDDzl!T?tqFAG*Br&6(iXKM{6!+5bzD{CE8=`|99Pv} z=Dyod;h4#*$cn7^+2I_zWyTiT TqIM)!jv`4mwjn=@^%qzGqJs@G literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/datatable_crud.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/datatable_crud.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56d0bf259b74b4d31f4bb172c02644393cf4a4d6 GIT binary patch literal 1782 zcmeHDu?@p840D%^oqIwr$N|~=lTYiAo4PiH*$RY+2JzG&hyW`RO)8Y9$7?7pM&vur z?Q<@zD&>j$`O4FXNbjS^chSDDzl!T?tqFAG*Br&6(iXKM{6!+5bzD{CE8=`|99Pv} z=Dyod;h4#*$cn7^+2I_zWyTiT TqIM)!jv`4mwjn=@^%qzGqJs@G literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/date_picker.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/date_picker.bmp new file mode 100644 index 0000000000000000000000000000000000000000..44ea12ab4a407eda9b27fd8bcab4d6d254f9fffd GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCH}Xh6-u=VXASNgDH+n z1Y#1VEG}_Ol@JkJ>T!vWnu9;whDZ27VxM>t)7P{}KX}Z9OTigvPJ)P&N}?G8-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCH}Xh6-u=VXASNgDH+n z1Y#1VEG}_Ol@JkJ>T!vWnu9;whDZ27VxM>t)7P{}KX}Z9OTigvPJ)P&N}?G8KbfN9EbT2K_PTQIB>r8FXG^8ZlocZ#dJ9EA{XYRdcPNb0g;<%9j zJc#Q+_}as#zaF~rT8-Wl6 zBAgCT$OPPOG6a#;4hKRIh;Y6f$kM?eG#G}V>6k2t#~2172n>aD-votlB0J0mA|WLf z;rv$x;U-vrkoln{f39t7T5?+N9scbyy91%OZ_%-HI#y5MT&wy}wencQ(vdpl(fXx` zZFLjsm*OiI_U6wVu2CvYKIquj!}(ZE1e9ARtj8a(Zc?<<$B+!`^wKUL4Rrfik`B8L zFYTpSjgz@ABTkA}3;Xp5L^xj;uOpUQGP<;wCj+dW2r2W!!XnEG+_=o0|uAw@DhRDolhyG-S+q z9z{niH)lwR*F9}TxmlU1XX-@vs)cufC3ynD#Uzj_VKMOb&5Y}*iG#iE)g!j--nFRt zTxwHcUZW%GD}*5YB2G^t}bJLS95_NJ@fqOhb0B&#reR(Ti3EK zB!Y;FLT>(zE9ohx2D)3esVl8r?e|l^re}qB@+hCz=5hlSAI56SOF=9S7qGui+SK?6 z=Rh=Qh?)=Ty4tBh;X0G`?VBNN*3AF|Tvn;aM@KxtZw zB2hyp#!)6S3Z(z67dAHZSIj<~2<*}ni7K&a<*Y=VEK!HBMU~XN%DE~acrvU-6<@We zP`dF_+j@9EN6x9v;qUrtlYX;rZ$01b9bas-dM`wfz}E8~n&G!gj8$=u@hyngK?{oX dG0X?(SPdNyVv#-uwo83=cltc{%h-kg&L0sx>TLi3 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/disabled_edit.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/disabled_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dd3bf827c0bbfed1fd35a401f3805bb806136551 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm)Q8&GIWWpEMv=0KDI)xg!`VvL%DD`endh&31?;f6-yF^ZUQ#-klBh2I=B X_Yma5jfFD^YQd@iu6>j-v_b#?3sp{; literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/dropdown.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/dropdown.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c4dd2ac881a086b4e7e68c082174e73cb78e4e6e GIT binary patch literal 1782 zcmb_dO-~b16vd58*Zu@|?)(AnO^gfU(zth_QCJ`%5}`tZk|3pR)KCf{Es*pB+JGr^ z8ldzm(3X!rup6$dCFf-Y?bvV`ZMAqWEOQL(tSk;lLT#R^QY!_YpZddmJvEYc^%~Q!#aSNGUGBji5T*+?&fwHs$ZyTDoc1@ zQ`z|HWqWf2YC`vQK|b;5JamxE^3q~rIraxDv3M-{GZDv9$nWvG$KWW}Ss(%->Eycc zi`vIH=K@|ig5I#tgQY>eE*hFau%eE1uJDx1?sh2Ti_8VXk$?>1WZ1vXt|Ckv^eD>S zJEk*>3BS58+-Y6taV&KI3-*ZK=4=1HJ~>OZ&YZ)|6lU_t^x&havFbMFt;SWWR=^u^ zlBw5DG=664I!q6qr@Rpm@rg<284hlfQz6Ua8tD;b?BQ09^@I`NtZJR@vcSo*=X6-# zob^d9&lUOoLnR#Wg@dC4=Xk2p-F}#vkGo#CN4^dJt#he-c#;_PEZf|+|%N@gM#>zW`#41+M@A literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/email_edit.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/email_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..22d39b4e4854d4822c420fa211cc330bd2c96683 GIT binary patch literal 1782 zcmeH@yA8uI5JTlAW$KLJ2{J(X?4;3BcqX?AA;tuu^XIAn0W3i0Gmm@{^mxvf($*by z#J+v^(7IAym`_*kW<+_P>*p`9ynXh&dO?J1ty#okjwlj-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|KJ8NXA(=}@(oEo#iJOH6sFa9 z6yuQ^H3t|1qv3-;5QbLx09}g)FcUdM1gH#`6k31~uM*QhxL!B|Qw>A}zXFIXel%uHpd0ckKEA literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/flex_row.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/flex_row.bmp new file mode 100644 index 0000000000000000000000000000000000000000..93c6964e01c45176ae67351bd40c8255e30fd4f4 GIT binary patch literal 1782 zcmcgtOH30{6vd58*DhVSaAim|uGB<=?${Ol0SXZnC^Z5mN=u?3-%>~fsX`p_AVDEc?wsCx`_Ac``{v%pB`|wqBG)nC zA>8}d?>!MOCZ-?X>-Uj6vJk+tAz~uW2{4Y`uJIfwQ95y;zH@@!9^@3b!eO0L}?LyGcOj^uY$r5#S1rRwIr_CyJ%GneAto zK?7A=evji=Abezy=eU5jw?}qjE1mn9=lXjzqR0~+lU`R>QG^Wu;S(L464l?E^Ivp! z>$!HL&R$L4>4ycG@;sSZRVGWnh)J=_^3t+gpUmJ>gqB@{*CatZ*pE@i19UF zignD4TE-@HS}pBdMtO0~SZ67U0+Nt+Ea@rzkjdDT8fzanAi3c^T)@d5V<_5YlIya!RagJfQVXG00jB7Hqf5-3w bQm*J6Ls^jA`CQ$_IZvd*vk~^M|2sbbrCPzq literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/grid.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/grid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ac48d4945d63e2550b2b04fac7614f51e0f9ba49 GIT binary patch literal 1782 zcmb_d&2JJ>5XXy0&;AJ}MvWh>#xy2+@TT6ZNk43*#*fs*lU~%+rooG?O-%Hx2U}VS zF(!?zfL~Op0Sje8V-#&%x(h7`g+liee{Uao*-~gQbu&B6%zN|W&CHwG6Q_#XEymLf zz6`;r0!Ib~Ik%k5rUZGdq$)~-gw1e)BZb1*iur7INhs4t*UJr3S%(K4;SLZGPAE%j z6`X(j(cuVpfFP^LhAK+{NXNP9+pVA}LT4$x>TC1bE-)3s^qq5)H_yc1y5OQJ65MHN zkTgwGRjKs6_xQWP-q7gK+_U?kkwMDe4_$L!ZeeQ3SPDL|**o{9<56AL)533t163)l zj&~o-{ESsamiij-+N@PZsE(dyVSWa}MjT_w2XIZ680P~X_uY1)D#WNOGPsn_Ijl`0 zH(MLW+9X6i=sKcQ80UjtcYg;_HDW}S!KKv|1IJ$vXX)D zA)tsFB*uin7yK{By7nid_40FQ`Fpr3gk;q38R)7qLai4U>WYj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/heading_h2.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/heading_h2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0d4b6297c732aa5720d942686818563c402a1cdf GIT binary patch literal 1782 zcmb`ITQ37a6vxYh%Zpb&f_DiK2?<_=iZt4$ZjC6d@FMZ%K}aMhaS1A-FTMy5>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/heading_h3.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/heading_h3.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0d4b6297c732aa5720d942686818563c402a1cdf GIT binary patch literal 1782 zcmb`ITQ37a6vxYh%Zpb&f_DiK2?<_=iZt4$ZjC6d@FMZ%K}aMhaS1A-FTMy5>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/horizontal_rule.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/horizontal_rule.bmp new file mode 100644 index 0000000000000000000000000000000000000000..09a4fdaef816e3a6a342a12a8eef5e84952619cc GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9@9$p_^#AXle?au-H?ipNAD|Yv zb_fG#!naQ!-oJYG?!}XLFP^@8i5CGCym$gs4AcVD2saAI{`ltQhgZ*k{rLXp_irK* zP%%&oP$R@BpxeHE{_x@T^Z#T4phlo}pdmm6bm6a`KgcrXKTso3JJ1kdr~*R+=oj+L z0cr$lheXX_Hs>Gl;Qv2hP|(z0zkdJx`u)?lAD;=LuRlKh`1K9bJwJbb2MVs*)9+Eh zA5pCwS}BhQg;y*26pJ*>js$A?{p%-kd_mIBzSApjJyeiZfocwb5#H>?Zh z{GC%(r94r8T{&wI%X*GuFVG%r?Ax=)&bM^N>HW+hsjs#UNB@L<4)_RImrds<$54bA ziV!o|oh99bnV6JTNsdnO4(4xeWkN{rb7GY`9;_IDNxM&$iR3IJAENIb392d?tAFPJ eE@o_GI?H6f9oII?(;r=hl^7*t_Yv?E@dZAdrVrQv literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/info.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/info.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/input_group.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/input_group.bmp new file mode 100644 index 0000000000000000000000000000000000000000..df932b8e17796740e8bd6e78029117e51962db08 GIT binary patch literal 1782 zcmb`I&rcIU6vy%6(X)SoM@@u_H?PK%#CY>!qd`JS+>-bM>A@c)97L2v)QB83fwr_F z8ls_)ph7}`P>e#M{IJ>Cc7L?pc6Zy|otgS(w>AibfOhiPm&xvazj^a^-t5`)#?d-w zG(bE7*YV1A#F^FAO~Ugp$K1<#5dyI-piD4C)6fn@Rp^+Qlwc#DQ-owzL|IWdFbE_d z1Ua!y$OPt@6ptaRLk^ID5ajN1z?NWqNRP_vAY^ih%> z?gODLqnhLcPF0^wn$<^8t;bR6(YV+h6`d&EiU>D?JQv!DFNA!Z=lCMbz2i*|114Pt5{AO8K%~yTe;;NZuR$cJ}f049;((9G8<-KO;q zS9bfrx}YqJJj(=#@tUGpuz5zpA+G64N1L~uYXR>1ylu@_Up;%OW9GAcU2dK4jPR*^ zaZNVX6-Gj4-*o?R>Op+=SEbI-8mc7dCheP&0t@osoH97i2rMYq-Xg1 z*tfoo#HE)T=X%%Abgjx7Dah=*gO9rpa|Rxm$@G6yUQcKGr!x?HC*_`~)HAUMPbQ@9 yacNUFA>ryi{GUGE-WRUV?mpe8L)}LNG=KUFj-Z;HW3@Y1Yje&!zl<9EcYXsT8ZSZs literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/kpi_card.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/kpi_card.bmp new file mode 100644 index 0000000000000000000000000000000000000000..51ac1513ced723f0feb3c80b34fbd711097b8ca2 GIT binary patch literal 1782 zcmb_dTW=CU7_Bcp`s`0oA6r|kv_)xp6KLb5k~I3%i@n)4#;DQw?u&^J76ltjC0hT5 zm0s+{Qk$5V_-0_C3k$m}2(x$3uu58lg{YG=lVO?f%=x~VJ?n7ik2Vxr3&s=Z$A9%B z#aTncGX7sZX7=Jj44NXFFf>&MRHa^MDnd%(<^&9RQQ#A?^nNtG&(wh^79#|KB`VA_ z94jQ^GAXE%L?K&(t|4+Ej}Qc!RM3{s3PLh&{8d9B!a)K+p)3(Y*TIxuUP+A2B*tf} zVq%URo)Q<|6xZtrL^w!L)ilc>5s;9b-DpQo>hTl)#X|a-FFo%s1Ml_o-j_hs;i6QA zfg&K>JQ~VF2p$Uaes*LElWGl$sc6H%M(pq;CJ=x_DdWlbU$Hl5a00m$m*JA)0nnc* zPRajJb6H(gAt^C2SCz*Xh!^$TpB}x?bjoc%<7{sRTpcaF=NdhI4nCFCC89wOc*bWf zc=ku9q5RvIz3ugt@aD(x=DLZUjkUc`TeOUdj0H7$*s)vKP9=rX?ZQMY-g%H@1s>Ve zqsPqa-qeV_@uai8rO$SnqK%G7u-Ddft>?U`DWWfcN?PZo>H62t;f>Jy?X^%DwpKrc z*FuV}3AO4&&kNhsYW(vBt2*P{hbNV6PD&;Smn0ll0W7O#bLppEi*pxWFGXx!@xdFh z%R^OhX()d6I^%G1cOF7@#d}D3&N`Ux0jASsg|7ant&6++$cm@g9_#nSE?%*MdobG8 z&E0-bfk&3{Q28E-4R|8W_DE|dgjGf>eGWZv2FmmMJuUMMg^7uaZ;_xFT%zNj2)@e% zf@F6OB(RQ>Z-D2&_!zGJAzy`~5>gwI1QR~!tLA$IszW}{GBBm8pdW$?K5tS{Z~TYv F&QFdUz&MRHa^MDnd%(<^&9RQQ#A?^nNtG&(wh^79#|KB`VA_ z94jQ^GAXE%L?K&(t|4+Ej}Qc!RM3{s3PLh&{8d9B!a)K+p)3(Y*TIxuUP+A2B*tf} zVq%URo)Q<|6xZtrL^w!L)ilc>5s;9b-DpQo>hTl)#X|a-FFo%s1Ml_o-j_hs;i6QA zfg&K>JQ~VF2p$Uaes*LElWGl$sc6H%M(pq;CJ=x_DdWlbU$Hl5a00m$m*JA)0nnc* zPRajJb6H(gAt^C2SCz*Xh!^$TpB}x?bjoc%<7{sRTpcaF=NdhI4nCFCC89wOc*bWf zc=ku9q5RvIz3ugt@aD(x=DLZUjkUc`TeOUdj0H7$*s)vKP9=rX?ZQMY-g%H@1s>Ve zqsPqa-qeV_@uai8rO$SnqK%G7u-Ddft>?U`DWWfcN?PZo>H62t;f>Jy?X^%DwpKrc z*FuV}3AO4&&kNhsYW(vBt2*P{hbNV6PD&;Smn0ll0W7O#bLppEi*pxWFGXx!@xdFh z%R^OhX()d6I^%G1cOF7@#d}D3&N`Ux0jASsg|7ant&6++$cm@g9_#nSE?%*MdobG8 z&E0-bfk&3{Q28E-4R|8W_DE|dgjGf>eGWZv2FmmMJuUMMg^7uaZ;_xFT%zNj2)@e% zf@F6OB(RQ>Z-D2&_!zGJAzy`~5>gwI1QR~!tLA$IszW}{GBBm8pdW$?K5tS{Z~TYv F&QFdUz-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/lead_text.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/lead_text.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0d4b6297c732aa5720d942686818563c402a1cdf GIT binary patch literal 1782 zcmb`ITQ37a6vxYh%Zpb&f_DiK2?<_=iZt4$ZjC6d@FMZ%K}aMhaS1A-FTMy5>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/light.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/light.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/link.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/link.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0ee9204b87ea0a4ec867b3cc58fb2563b265ab1d GIT binary patch literal 1782 zcmb_dT}YEr7`B@(yY8|qB&uDgq(KlXe-iU23dN|z3njYfM?tBJh_Wz*gv5*jksydg zK|uv|;T)L14YfJj#J{EcbL!^y?c4V4oNqnneBZXxU1;oZzQg%>p69&hecyAw)8*ps z3|{ik9>TX*{dVzQMn*r@2lgl*2cn@-2{lFu+K4FZs3wS9BqCEH`h9E8CGU#EyW-q- zb$|jQ=rkIECFrla>;zWruz&(0=*n>*O9|Pbh6)Ff(Ya4>kpB}=SfDFj-Hwh-sZ0oK zDM2SD%ZaU1=wS6PfQppCr3qHD6Gx`dNrDnRb>G0;v`zP7y1jYkS*u(BiG)RlkeU8g zoyfW;2fiI!U9jVhT$ zaXJ}?p(M2G9&RYrpFLu3Z}wS!Mg@P^<8pp|KTv&qq@fi1G99-=^|NakLwEn@zJko( z?|PUB9Kvmu*WAXsg3;>y@T{5b9WU$SgZkpE`Q8ppcwNg(Cn$K`b_}N;-W;kuMZ+P6 zm1QDHv({fjue#rs=jzI`^^b2`Op~Gzz!HVQvDn0&y3wm;a#ZrIx+1{<(^+v~-q>`} z*jU3gm~#UDjdR*#TFt)Vd`(gQ(ZZZ8ttQiIHercnzD%u8?|!d2K|`W%&BJs=)gE(O z)8M6(L=;$(5JIGg-L^QP>-kub`=KIdxbwl1Z6Ok3VZyo5jyGQ!yH+Vjqh1f}VHX?+ z#Jp$VTVKI`o9-q0$r1`0>q~~t=L)7VHmSG{&NO_{7ad%9-Gw>TKhWX#0ydZ*-O``Q zn(OUAtPzV1%cQ0Ao}n@u;SSnuh#xbRS94qANPUUq_cEPCyp;O|--^O?dkdrtWg0{l z34=P*-5O7oWKu~R-Z1wn)7f;t;(6{fjV-=;Ztc2{9PrOf0m({yRT-%*pWLjYfVbi? s!*gk~LL8YwheMTkDfb%vf9R{RCXyk6FhU`&z1hA~CCv{;X+}pf zBoJy8Y6}{^|5|PJWDr6Q2pkoXunCM1B7$+wWnt`Fd1{3-rZXXg91xr;P6L~IT?ihb zvIKY*36ihKFwxO8Y-U!Efe^(Q$*a!k82 zwKu$Jj3d6ex>%l@-d$VTT3Lwu&g$a&{A|J4Pvrm$yhJ$_ukIkoXo-3hCwa~!3`wem zA(hXSmdcUqyq%!3x=#rXr39M)bN+khjPF$6=O?ex%YE+DH}DOjb#yZ9={p+r4RGRp eOsJ~5-{Y^0sE?t$_NA}(vCnIi?2W(p?|cFU6em0Y literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/modal.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/modal.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0e2b936a784b84501158dff0f20bd83382543f66 GIT binary patch literal 1782 zcmc&#O-~b16vd58*Zu^5fqRV!iHK-obRi(15Q!iV;|ghP>0q&?UkG#|A%=|@qfjfA z7U>v>N+1vuBVXbI={L+2XgkxHH#44g3{Wh!!G$m9z1*4Jb9(Qad1ua+CXW|o#%Zjl zFi-xT$1+h-5slxcPN*}Jh(!_w6^cY;fQW@cBB1Qj)c^{~?HC&gFrjrO#Z#fF@_Pv6chGC1iKpbuc4Nq!GZenD<40MPqjlfU!(WpAzCWE7^Bi$Sy-}^j+t3PzfCtQ^XQD%*%t=J zk&tr`UT~FBXc@cr7oA$$w|=i8%d$wY?m?0ei*XLkV&4kYQ52a-StUVJQPA3d(0S^S zC0P=1a^*b`+>(Wzg8QnoEe`s!I?BGlD^bY)cxx;(x}oU&kI3xz=-lc7gg!3~pVP3j z%ZEL8huv&#ZzDupc=3Lu4Epz)=Bjm z^_dPNh36FR5G0a{EFf)~_SRQk+pmLzhD)EvT~Sv2#7J578oNPj@5}{*w!2enr8K>! z4jk%U^J5UzbDH*zNI*aV87Zrw-C;E$ArJa2#%|-I=g;~k@L@|CC6vW_)5Uheqs6=97s$fu*58_gNT3jKB zh;>6D2)IGmiUq9@hzW#6!(s&swJp+CD3!MFy?WjoGd^)ooXkw_n|tq>d(Yh5w`P-b zqK`P1V-LWZ{&h_dB_E$!=yj9H5)H9&9yg|!W3juOj(?ieQ3P@E9P1pm4}CD$EJmB< z!(UG$T;K?I&f`KPkgcWx7E%4b1Y7%cANl5!CmA8 ziBRpYTz+*9N4OJKDGoKRX)RDb*nRl+hBL)+&pS%UEmTV{CBiryp676GviBvbLuBcG zr;B2*RUSQA7!#$MedNx@p%D{sJgghZ{t1V7x*U76mM5u0?W2R#*laf_a)SU)Pk1jN zzcD6_2P&A|t7CRuS}^8zLdIKyZ3F;WZ*JeLoXR|u-`1XL*4Gk13MIvX3IQiv4J@j^ z0-3mz6p9-%cBIdhXDpF1bN6Sj+RFH*=0yyC>W3Mjg5p>$MjYB4=I!VG+ut`JHV!Y( z3zd-nLKTuWsi~);Y>CpNiIGWb{EvKg$20Nj}IH(TEd(L<{ z@8f6cxEl+j#ekic z1LChN+Z4RGIPX>lbE4p8jyx(%SEYGlYK%HJ8PnvSnnl$jN>wGje zGNw#TS{JxrclcUeO*JeJTb=5*$H9f?_>;&@{3uQ^L>8P+SknsycM4Xs1l&w=a9;TT>e`!~Po_0ZTHv zjV-8$wEMENCGpiQ_W%wh?jj}x2Q6q^ACmyUSg39336W{;w2%E|U*%C3Kouv2{l2gM NpFS`CGXBGV=L?Do;t&7; literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/month_picker.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/month_picker.bmp new file mode 100644 index 0000000000000000000000000000000000000000..44ea12ab4a407eda9b27fd8bcab4d6d254f9fffd GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCH}Xh6-u=VXASNgDH+n z1Y#1VEG}_Ol@JkJ>T!vWnu9;whDZ27VxM>t)7P{}KX}Z9OTigvPJ)P&N}?G8-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm*@#4%MuL~yCcB~BxAfYwpPJ#c5k8E6j1C625Nq6SC;1#zjzC63h`WCM{E q;4vRf8JvsDUR>gEjc5#9>fuf$iGgM~kV}$wxMECmMn#512mk;O;a!RV literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/nav_pills.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/nav_pills.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0663cb2bd45a2c3e82cf14392b660bcb4bc1c08b GIT binary patch literal 1782 zcmeH|O-~v@7{~F_W6ypBKS4i0@BJ)l^zNaJX-`dTXd;H7)k14!c>s6s{ZFZSjGqHV;FcDV5VU(i4`COo)fI` z{fM2@l5D9UZjH3|DU{FJIi{&AvJ?-&h$6EET;!$g_2u+&ih<#elKVTGtC!^xk2E>? zEQ0k)F*)3S`q>Hl{-)Qsxjso9OuL=nM17u3VIB*JNBoO3-mS!v-|ZALzo9~Fa&jVu z>B$e$f}hTq`B>oC^F9*r)yhQ{i3PoDvFJ)P$c9BR6P|LTP#D@cKSzeDCqG!4l1}Zs z?wt!yV@TvG{B}a{j*cAeeM8?+Wm8i_pIjRKBwIM=m@R%?K72Q*mI|BbjBt(#)%Chh!5S(z$ z`o=GERt?Y6zp$N|2^S#z^z9savUojUknm&G>W%xP8M%MM*g4Qrf(79nqrqelj^YVO d{+EN`6B^^-3hKx`*13DNGxt3GWpv=ba|_ouY{viq literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/nav_tabs.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/nav_tabs.bmp new file mode 100644 index 0000000000000000000000000000000000000000..627310a4e27d738cd7027bb68e63e11617efd672 GIT binary patch literal 1782 zcmd5-OK%cU6s{YWuKfxA0)K#e|A~nkSKXM{CUw!6_=t)Ig+wTcZ7q>Up}dCIP#9n+ z!)sb?tw3o>VL~QTm=}IC1Jt$}#jx>#8rO7d zZZ3l7@f*g_12HL*2puXi=7GRZr4yh|GEfy+=y9h<-@7Nx?#a<#YZDLv0av5}GJ)M` zHDqKpr2qmT;6^#1Rb+Wej!`&(8eH!Q3i&q@0|mIz)&G-6g(wP!HvdtLFjYlqv#;y8 z3EEcuutHO8k!Fi|O-luqDb$MeNEwMJQmsBPNq@` zXgs)?iukihf=WcP2_hX0#kV|}SQs`uIWijayBgoVf(P&m=QTLvV%{#{hIR-y0ywVA zuv}1i)o2@@o3d{)%>!!bf#1DhEHM|z=*rvY zdrW@pQC$v;Bx;}1<$T^e?p1O_9HpuX>`s1p-sk$HihWt&@kUUw(5l5$&Ze}tqc4bj z?{_@4XAe0#sSNs1zL?G|-2c4pkZ_aqI7t%8px0)4T1Z7PlkNR?LuAS?^Kl}BOmR8(giz8 z5WNp@0C>ss3m%=^fNKy%nb?M5>^^Z$mgjvQ=QD|!$}o6P!c6Y5+1;zNx##s?#ti;D FKLCY!P)q;- literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/navbar.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/navbar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8bf63b01ca52464f47c13273f3d9d386c1753882 GIT binary patch literal 1782 zcmds2T~E_s6vi7bz4jldf4~^yjV4BkUsp!CF%dHfl9-4_jQLnC!T@KmL?4LNY%YEgn#E>kJ813&Je)?$SSa83^rrXtdG1I0%EZaE73QgZVP=(k|ZG~34&r_u{H9NC<-~X Sk5#U(R;JIZ-{ZgkcYXoFSRtzb literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/number_edit.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/number_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..93c624b24dc79124375f07c4f27e69cbfd4baa95 GIT binary patch literal 1782 zcmb_dSx*yD6vh`HefB4q7+;K{uNtEQqC`avC{iPffv6w`h$R(jppp=+K#8mgASOr@ z5H&2eic2KMiX?1>F3{2`-Al`~)9K9kbp|Vv21~-tnXliubI;dvX6`+6G@0BP$B%g6 z9$dTEt{ps!i~E54pLYotzYxICK^Vt`fE4N5l0^b}5sGC(%gq1ji z3r`h>F zcbRT<84-wZp)Ns3uC%4ME?}OdIg>f8EDT>DNGx0bc%0koBkWGN(zlkZXHj&XsB9OS z7p%n6$nbD+ezrk7H#I#2?Ct3;FD?L?oSXu-H7cs55-cn0C$gjI$d%UgcJr%_#)6#8 zjFgjA;=9t)JHVn`k?33^NJVKO@aDDjD=7(molVj~M^@(|65CK0@;TqA!@R+0mPtxM zgqNsRtLtiHaKo>M;|AXibhNdA-0L+(%?CQEO$LezjQ^S_FDdkst9I84@S{pu^FRV( zb+~~qUp#+WD-TiualbjL4qq41-CCC~O3OHN;(k$nSz#XV_Vvq|XA?lg1z|Vu>czC= z<2`Nlo79!sqz?wEpW_pyw{od~-{J8BRqux@%Zfp4E)TG~tG%|S8s|XVw-hxW)OD%F zfWnOy`#dEO1Vz9~l|~@lgyARgZr9j7KLKAabJZpT|mDvO*7?7)MDjA!`5U zePLrmf8H9vi8vq7ZQ(xVlKF@zLw&A<;8*LZtH2?qr literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/offcanvas.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/offcanvas.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0e2b936a784b84501158dff0f20bd83382543f66 GIT binary patch literal 1782 zcmc&#O-~b16vd58*Zu^5fqRV!iHK-obRi(15Q!iV;|ghP>0q&?UkG#|A%=|@qfjfA z7U>v>N+1vuBVXbI={L+2XgkxHH#44g3{Wh!!G$m9z1*4Jb9(Qad1ua+CXW|o#%Zjl zFi-xT$1+h-5slxcPN*}Jh(!_w6^cY;fQW@cBB1Qj)c^{~?HC&gFrjrO#Z#fF@_Pv6chGC1iKpbuc4Nq!GZenD<40MPqjlfU!(WpAzCWE7^Bi$Sy-}^j+t3PzfCtQ^XQD%*%t=J zk&tr`UT~FBXc@cr7oA$$w|=i8%d$wY?m?0ei*XLkV&4kYQ52a-StUVJQPA3d(0S^S zC0P=1a^*b`+>(Wzg8QnoEe`s!I?BGlD^bY)cxx;(x}oU&kI3xz=-lc7gg!3~pVP3j z%ZEL8huv&#ZzDupc=3Lu4Epz)=Bjm z^_dPNh36FR5G0a{EFf)~_SRQk+pmLzhD)EvT~Sv2#7J578oNPj@5}{*w!2enr8K>! z4jk%U^J5UzbDH*zNI*aV87Zrw-C;E$ArJa2#%|-I=g;~-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/pagination.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/pagination.bmp new file mode 100644 index 0000000000000000000000000000000000000000..31c0f2745af76cc97133bb71d4649beb2c9cf2ae GIT binary patch literal 1782 zcmeHITW=CU6vh`HefB5#3;Y4T`)f3&FO9~;hsM;Tk{TPWU?R7cQo9%|tyHM3Nohz6 zrEIz1%57Jc%|h2**ag3xZMK3n0mGw{nUiz&obQ|2GiPS*-4}0~NV^Mp2jlkTxIr|N zDG2}GEq#zc2({NmAE*kXEOsX929S`*eN_NlTQ4VX+_pvKW6|aqc{wOi`kO}#IO463c2^VFz za4f@A&k^Z$SOeZQS(13RE?=~<^<1L@9-rHGb`%!)7Ui&%=#%8!1F2pXlF`hInbc`) z)BORi!{AnUH?SYrjD8Qn{A9P3av4!*Ngcu9*{0mJd>Vw9r9{Vbubv`DU7js0JxeD} z_WWMBlE;UU{m?<^OFj{U`4y4*>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/password_edit.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/password_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..fc433d639344844d426cfaed951ade7e4e2fc1e9 GIT binary patch literal 1782 zcmeHDISzm@3@ZyGGf&_JJb;})Gw>!>uo|d}l33-K5S5Zfw&SE7#-$GN^vE5e-J^jB;P|$p+cPd|K8s8%k(iVQiI`BY_`v_Uk1VOJ$nqYgO|YIP=G2XM z$)Lil{RJs(Cy(-+pWtL1q4Y!|CY1I8V(LxMY)_!HAQL1}yhv7g!CO2wcgT11^xwlb D-FHrz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/percent_edit.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/percent_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..381051daaacfa5b286d9ddc66987d5b5fbf7d843 GIT binary patch literal 1782 zcmb`IO=uHA6vyMmn;xV{l_EAMNU?q(*n)?ef?%V)*a|kD)O&7iQQAY}O|M#^Xgui2 zt6H%L%|QYlf@t&6RGTKYCNbvwJKdRG|1&RHlMRsy9cG8wH}C!S|7ISu!=vTBCfUwo zJb|aX{_K%6lgWkkkNfG7ju^PIjjnNqu~shrSJwk2q^5FK&Sz7x%}gSiNyK*CqX
z6KE9yl4EjeCEBis^3^}|7Zs={ zn9pT#riN-aa0s%^)Yo5g9|EFWsWDbhaOjlTe(MH|K%q6(jr)U@QjK4o5B1#h9h&yt zd9jJ?$X!tc%Ja#6?r7KCq@4&ls#y<{_~-7Fc{cF7pakPp6bY$n?3F+*zh69il>?CytoN1YJw-`Va4W`Sgjjh=XY6Kn{Ak#0DRH z>vOD{XZ@q|8&yTu4tLS0+L2%~@e8l*dUPXDk6cNoJ5{cU^KIHryoqKwELcbnt|0v$ pGkm@sB1uA(?uj|wW3U?TRn(xd)F{4fY`s@^=bo3pj9vKe`~jwpGsOS^ literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/primary.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/primary.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/progress.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/progress.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3c40b97b486c632e67b5a3a55b992ae5afc54ea1 GIT binary patch literal 1782 zcmcIlQBTuQ6t0N@e9;GEAOsALKJe_Ti7!47f0Txi2m`_+A@C0%(RbtS*i3YqXn?IF z6vo*?v~>C4xxA)zy#V||7>b~*2LEJ4WN zdhTH~JC0ab;714<XmG%UUD zdoB%vTLR9YfEY<3ww7aAC-rck0V3!S0T7{o?hPapf(SZ9kX2*@&oY<}h@eNW=6~og z&gnJaoX0W4?ri(U)8iL2ZnpaBgw!jD(&m@F58q1f3o)?W`dZu*MdL`64@$~GQ9UfT z92>Wwf!~`Szny2cL4G_)eHu=Ykrct&#mF4FKTD>TNTIlYRzKF2N~0=CJKxVemobLA zz09+wP{u>gd9k`Z{4PJXlz+1LC(`-x<6T*p!+(WuD?3ANqT2`CT! zUo-1DA(eZa&OciC8#ol+W|wnP=-T#a6SXJr@0xnMdSji2>IXhfvODGJmCX18nM{+3 z9z0znqw|?pYuR#XS349HNrXtH^pnznQ5rv2T!-8?4XG+0D{7?&*dEEMqpOxCpVWYA z^EajM`(lXcj-#&*G*E0P#jE4$VRXambnX}q>L=mvE2+K#okaQ=x@#hRHNid~Nws_9 IKm2zt00!+!ga7~l literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/radio_group.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/radio_group.bmp new file mode 100644 index 0000000000000000000000000000000000000000..17117c803df17e829082084fb9d3c4e0076e6368 GIT binary patch literal 1782 zcmcJQJx;?w5QR;H6baGLAaMaszyT1@QBea84Huw*7N`)nKuV8N5FtT9m0W<|&;()! z6gHrkBL>_HZaohX9Enzd$T-+Mbd>ueTR{YfWz7I@DyX1~Wo;yKPG^Hn%Dg5@Ur<#p^_cPFXOalxB zqDWDj|Dn`NBl^_?5jr9m7501Gtc(dmZ9gXWuEv;Y|s-szS z=j3{7vy9;ol4J@1FahW4aKr%U>heJar~05!nA^U-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9@9$p_^#AXle?au-H?ipNAD|Yv zb_fG#!naQ!-oJYG?!}XLFP^@8i5CGCym$gs4AcVD2saAI{`ltQhgZ*k{rLXp_irK* zP%%&oP$R@BpxeHE{_x@T^Z#T4phlo}pdmm6bm6a`KgcrXKTso3JJ1kdr~*R+=oj+L z0cr$lheQoQbN>DN4@6i2@#g&b3pE1Bz%&e(IsY&K&>7!<{{8S3>TzUwpcF21FdaYt zz!RO)BP#g^E0^E=@#`;|0<7lz{`KqI*RS8cfzapAUxDm(C!ev$>=a4eE0M8}A$&W~ zsBhoCefjbQDE0FPD2ma{`T65JP;k-g=@y!bp4KLA76xt>h8|{G3XwA;vX9GT?2*dc zE1i8%JZX!wwWX((fsLM8Syl>A%kN)5f$1L}U%!6-1PY!%b86&)zSayp`oS~`nEHSz@b6y`i788@doVSkiBR1fYLy#6bEr~|0ZUh^ Rl&e%M=OIRc%0>$69RTGBQiT8j literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/readonly_edit.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/readonly_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dd3bf827c0bbfed1fd35a401f3805bb806136551 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm)Q8&GIWWpEMv=0KDI)xg!`VvL%DD`endh&31?;f6-yF^ZUQ#-klBh2I=B X_Yma5jfFD^YQd@iu6>j-v_b#?3sp{; literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/row.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/row.bmp new file mode 100644 index 0000000000000000000000000000000000000000..93c6964e01c45176ae67351bd40c8255e30fd4f4 GIT binary patch literal 1782 zcmcgtOH30{6vd58*DhVSaAim|uGB<=?${Ol0SXZnC^Z5mN=u?3-%>~fsX`p_AVDEc?wsCx`_Ac``{v%pB`|wqBG)nC zA>8}d?>!MOCZ-?X>-Uj6vJk+tAz~uW2{4Y`uJIfwQ95y;zH@@!9^@3b!eO0L}?LyGcOj^uY$r5#S1rRwIr_CyJ%GneAto zK?7A=evji=Abezy=eU5jw?}qjE1mn9=lXjzqR0~+lU`R>QG^Wu;S(L464l?E^Ivp! z>$!HL&R$L4>4ycG@;sSZRVGWnh)J=_^3t+gpUmJ>gqB@{*CatZ*pE@i19UF zignD4TE-@HS}pBdMtO0~SZ67U0+Nt+Ea@rzkjdDT8fzanAi3c^T)@d5V<_5YlIya!RagJfQVXG00jB7Hqf5-3w bQm*J6Ls^jA`CQ$_IZvd*vk~^M|2sbbrCPzq literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/search_edit.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/search_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3bdafe4b01f9133e33935e98893a90ec17020387 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|1bhn@eV9tC<>WTLokyS8DRp~ z0$~8ngo|LBk4pru1(^Xc3YQj4akyT%6s8DV3Ks*H7F^=^&A}=QF$${`rXU{0c%*1; t4$x{eD-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/select.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/select.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dccce0f4c866e1c3cba1c55e25bab4e036b071d1 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm*@#4%MuL~yCcB~BxAfYwpPJ#c5k8E6j1C625Nq6SC;1#zjzC63h`WCM{E q;4vRf8JvsDUR>gEjc5#9>fuf$iGgM~kV}$wxMECmMn#512mk;O;a!RV literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/small_button.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/small_button.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/small_text.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/small_text.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0d4b6297c732aa5720d942686818563c402a1cdf GIT binary patch literal 1782 zcmb`ITQ37a6vxYh%Zpb&f_DiK2?<_=iZt4$ZjC6d@FMZ%K}aMhaS1A-FTMy5>Yj*e zBB2tLx}>Vzt~I-}^>2r!wk@0L=D(BEnK{2Xb7uCmTFd8XqE9K>V!TCPZ&uXOXf`mu zS-{@tL^M<+Okpa?kR+-VmEaO{X9fs-!2kMm@AKaIydK}tH=iS0*)-pe25Ei z!4QWwUP1I@G;u9B!krxr3{fPQ6AT25^)+=BCEBX8hRRYV*yuq&M%h~NGzEvngZ6NL zcW-O+V8^w;{UzAwK|djcem^l(Qci4Cy`kW+eIX|UJ!XqZXKOQ9TlEU{b{L^Pv#HC_ zba8fywWy55B*~8;2+pOs#p!X!jNLIanL_r3sd3Nk4LHcWf`gyx_Yyx-!D0LQGoIyH z`~2kC&9xhm$T9^mDJPO2tGT;HXKUA6+nN*A+hOR`YtK)QC_XFP;RH^m_Qg2(bkE&; z$Cs{?%dKB@=H5BEa&i1yG#(OvpCxvmL$8g4g;lofn*O}%zT8x*?awc_Xbvyd!68IQ zq#F}Mz#W3P*8Cf-@(x|g_$f3LTM6M7aA3r&1pS#33in>8%s!}-kNIc(l1DuT1 VF;v%#)YS~ud4`JA#((_pd;%5y_#XfO literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/spinner.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/spinner.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bdbc3c6d3f6810d35cf717261cc3aad3164c6b27 GIT binary patch literal 1782 zcmb_dOKTHR6rOg`rQ$+xWf27Z1zCv;H;SSz-MA2Ug54=X=_AsOMhX@MSE2|8E7XOe zjm@K@Z5k^UF%P0mO52#2_asf5G?}O0+%p+NW?BmNa^~h_?)QE7oO5qZ&RlHtacnp+ zpTu*-czT$}aXi-N575Jam=sAQ(-c{S$hN5Y*s$o{i!G~pl2s%Vyh)`@b zJ0U9QcQFkeqMmbyLF}Ih-Tk!2uT|z# z)hFLFj;Bl9i2vB5FY#iXwu7Lpj?A_ho?YdJ{imOQPYMkqdiJr=lyAIW=I+eg@~-F# zEInHttQP9x;ql-h*Icx)g|98tPt{FiEadw-mamIAMq^lYXw4nXBbaM%e*#BUZ8QGW z#C!v1CmmNX)idaQxR^$YT{>VP45VWQvy0Ayg%mgF#SE}j$A|<4wQ!a+Q?c~Sffpu4Em zbh7MPNZk*nkZg9dg=jku9T-!`wr}WwZicQ*LuP|~vu{9Wr#=QGjtTditSb`IG5Z+0 T>%R2WeeCljrT51F_}}>pvhY6o literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/standard_button.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/standard_button.bmp new file mode 100644 index 0000000000000000000000000000000000000000..af6c190a9e23c98db1f37472c0decadc0f29e9c6 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;qG((mB}y}@B21$o z@|fayM6hbXDu~ArpcGauSOqCJrvW#B8;;d#tb%YYSQ%KgU=_rw9WIDf3syn67OV_h YS|H*ikyyqb-kG6iVl7W`d9t2`K#4Ef zNUVs8040>8LYNpU5_ljP^q3edJp-&x^BG2G0(ez|<@fPjFXROzsQd^c6%35XV_NhW SHaw%BmEo)hICTeCzQ7J8y)(1` literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/standard_combobox.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/standard_combobox.bmp new file mode 100644 index 0000000000000000000000000000000000000000..73ba54340c8966b6b596f30591832e8db80c22f8 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKWE#zxB-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o!mApna&l4&&WlB^%50joI> zL7);eS*%=$NoZ2Yf}`eOh5#+X2Q3P4agnWttAPlTLBdUdFvu_gt9#Il9pw)15C8yi Cbaiq7 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/standard_grid.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/standard_grid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7872be7624edc7296d46049e80d8e2afb2ed8274 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|6m0$2a-&qc?eT~Lqh|aAf^aV z0akO61%bMdxj;6W2*egNHJE~Ex`wVfK#!0LM#C97c>qHXnTwfJfU=l^Xu60`Kcq$$ qQ2l6pAx98e$YVwgJiZ`O5E2rM_(g!S$QEHW2iXKXY&3I*85aP9NZ?rj literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/standard_groupbox.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/standard_groupbox.bmp new file mode 100644 index 0000000000000000000000000000000000000000..76158cc47bfa8b815bc417850ed0cab4e1a25264 GIT binary patch literal 1782 zcmeH@F%H5o5CokjC3T*_3-SPZ{!EcK(Zb0l)@hiaM501ivVFVWIVZkc?_;TBj`bXK zdd;C$rQG6tIkj1Xu{?f#tUr2q$HN@vS3vu~{4851WYk0kQV}%)LMoyrKuAT@1PG~! zngAgcQ4=7fB5DGJR76dHkcxD(6}s;4)4Kr)shz__GRJV#WDew7!(qN((fe#6>VL6M O{_I@qy?=Ah3p@c@dP|%D literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/standard_hidden.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/standard_hidden.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cb5d8ec794287aa2cde66f7b31901a6e2f4ba36d GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o!;Apna*5@@V`B|$$-DIRmM zN?{5@Ou`fgir|sLRF6k79x3w7X&?mfJD%$9!Sn^D2p&uENReR<#55vFO!I*vMCwIW MhSi)=!I2XJ0CqNx=>Px# literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/standard_image.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/standard_image.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a9e189beb4bdea722a2d57fd53fd9318c1cefa7f GIT binary patch literal 1782 zcmeHEF%H5o5K9+E=01TJ@BnuH%)pzvf)x|Xx?CfrVnRep>iBG5lHTsysnl`Bdcj;j zbE&A52kOr=XBA?3{rYGZo&JW0nf5nBniI(JmPtX=;wS##AP3>7h86>|7khZ9a@&(` zQEMmNA}l})^?~Hcog{X~Z>MSy^f~SV)=&Z%U~X02BV9o3UdK{8=~w~*RQpV?Qs6RG nQ;@b3`K=tZR%Ut(k*O>tWl2G5A$ed8Ee<54=Lxa@Ennab;??Nz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/standard_label.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/standard_label.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e740645619de8ed20f40f88a2c03de42356cd703 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tk)2sDrm=zEXw|A! za7WnL*uNPV6pFe*rEiEA;J9g~I%gaNSC5as$ zAFr>kZ*FcbAtAAA*DjLuA}e0EZe4eGH&DdL$mr+KpU6@qv4O$j?CgBw#*Lt$Ad)m< lD)#g9D=8_NH*X%M6iFhpXU}G1V|(%91xdO_6_3CW006*tc#Hr5 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/standard_link.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/standard_link.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f400df2909a699c3b6c204a29b4e7905fbf4983c GIT binary patch literal 1782 zcmeH^F%H5o5Clz=lA0&v1$jVv{!GD}(!$ASMyoq65@kdz*;%jW){ed2x2g5E*f?9i zjehB>wTG=guiiUo!|QAZzk$z7jxT>x`2Z>c>{A0OUu)68*&)!EGMP(o_Dia$u%m@Q zs?c3>2~`=>5Yrh@=WC7w-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|6m0$2a-&qd5C2FFb!DEK@-H! zg_wk<2CE>N8Z<6eEpWjGA^^ldxE5sdu?iw9z+_|9f>jVxFR}<$Em#GSbz!oxYQZXq xsTWxUs}{H*5y9L5F%7PTpy9|0Fxey1oM9Qxkffbla~nq_xVvNX%~x zDGT9{`*X^X3T3-{U*)0AUo)6yzX-ICf#1j6$<$D2YRr);3S-@po~mGf3bDZFRH4wj zNT@;~T0W-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCIHI1q{jhVH&WSgC>Zd z3o!{z4P3B+H~`cR*Me*mTo7msvN%>YL=9XEvKqMHs5$VU7!4of5CF1?Og}(n1Od=A f{NapdH6AV=b0AVAk!Ti?q!(E+nmMCftRVmZ5WD^z literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/standard_progress.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/standard_progress.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4ddf24900411555010e80d148e9a10aadfc2c16a GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#QAplDVB-3cYMzVgG2CU{Z t;09>wfn115XyOn-+{QGZsUMlmc^VvaL-ak3^+i%}5-ary~TTermv>eq1^R2_FRRjzhh7_Y>PI{M!@%f{R zkRyxRp#_$Z)I~3gl$12^0;6t1EJ;XRZif~U$p{1qiz}>8qRugPO~)Jod|SbW%n-n@ bowOAdK1Qqy##=;1!B|mCNU`gW#TWPhjxkh| literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/success.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/success.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89cc93a6fddf9d209225dcb12a25cc0d0b343c4c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/switch.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/switch.bmp new file mode 100644 index 0000000000000000000000000000000000000000..aa793e1efb166445e2ac39bfd1049834ebe67c7a GIT binary patch literal 1782 zcmb`I&1(}u7{(()K`KfPRck*EB1QiJ4}zDpSJAU5wu;6Cwec#p##Sgw@ehz(gq}(T zAu5DzHfcy|vDQ@7`jIxNF>Uj;n@wWAW_Pnbn@MA7J}5E6vy)-weSUf8-CUXmN=QUE`EZC2Z}5?Z zLO?i#U|3+RpfFCxBSLhGyEt-D5#^#N)s>8h?N*PoBV;?Y)~{SFqiS;KVu;H;mj(=ldt`g*1*K8wU2=$*fhABL+8DLWVgX_+T$e!Q|Wu*QvLsW3gg}CyBTu#0z{}$|e>*1=|Oi;|8|J=-7YBHZ|+J zFtPAp+6PO%P=mAN7qr)AfBy5GNnCswbKW4X&3@!z^kn eRyeJ?H^6DhJ%-!0CHHCz?|F(+@5cZ5?)(J=>NW=e literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/table.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/table.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56d0bf259b74b4d31f4bb172c02644393cf4a4d6 GIT binary patch literal 1782 zcmeHDu?@p840D%^oqIwr$N|~=lTYiAo4PiH*$RY+2JzG&hyW`RO)8Y9$7?7pM&vur z?Q<@zD&>j$`O4FXNbjS^chSDDzl!T?tqFAG*Br&6(iXKM{6!+5bzD{CE8=`|99Pv} z=Dyod;h4#*$cn7^+2I_zWyTiT TqIM)!jv`4mwjn=@^%qzGqJs@G literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/text_edit.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/text_edit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dd3bf827c0bbfed1fd35a401f3805bb806136551 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0tku2*3iKG#b;5r0IvL#$^ts zI4%*0Ntm)Q8&GIWWpEMv=0KDI)xg!`VvL%DD`endh&31?;f6-yF^ZUQ#-klBh2I=B X_Yma5jfFD^YQd@iu6>j-v_b#?3sp{; literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/textarea.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/textarea.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a937b000f14221a2e401e2c8416ef736beb68ab6 GIT binary patch literal 1782 zcmb_d$!`)-9L9@B&;AMCO+0zhn8q3om8D2pmb$c6V5nM+7ZWvj(t`(2ni7pME>+{9 z*5!Z;)H3OS(6U&h3;WUm$|^96znOX1W>aYO?h(JenK$fPc4mBFbfymMMI{_n&RfZ{rf~D|MD};jO$Z~NdK>w{E z7SPeHA|0wy@|dun>f`vZ7{72z80UNE^b)k?93QMCqac+{#u_>ae)?4M+@{e!W`W3`~1wNYXns z`5d@8kApBsBk!N>)Zu&?q;$O=^m`UP?tph5Vl!aH?{=;w<8-YGbdSjxnw${S;e55# zICtJV`p_FQ40iK1KB^g2_UTkIol3eDGTk7o$P8-vh(>Yi#NqVx%bhxV`r7ok;QHg&hCzAzbu-fO`XfF~1# zci!hB^7(b&U87(=8N!N>h`Eg0YwnxFtFIox+0FM##$Z~@l8!OOobEJnSxJm3_JFY; zKX-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|DXp{bR@*nl=~PKcp#cQ(~wQT z&&FduevO#2SdD@x!zzVU5SMyf;#ds<3gS|aOMJl1X}}GT-GKEgC@RD|jw000*F BUnl?o literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/toolbar_debug_breakpoint.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/toolbar_debug_breakpoint.bmp new file mode 100644 index 0000000000000000000000000000000000000000..40beae6989a09e87ea3af6a894e33f3814d6996b GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y!!QCOA{EGpc%K1v>FZxcMnDl_ zv}0<77(!4xE{z1WqiOv5^*;m=<9KAfaE)l%ak+dj=mq)_?rdWG3yeWzXCrHYuyJ`7 c9`(4i6VwPX0aH7X8sXZ3>fs3Ps*%h90Ns$PcK`qY literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/toolbar_debug_clear.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/toolbar_debug_clear.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4c4723933b3e9fda042b68d181908a3a7d9c4287 GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y1AT$HxjFF`A}a>6A%Ga|Fts4N zklDoOMb<*RjmRdGVIxF4Tq8kyMMNs#2-(4CY-CqK*g#$S`j_Dd$c1QutAx7&E`n7f x!~}?TWR*be$Xp;B%|^J@KnAAvVW1b6mkD|n?sv2hBVHrK1fY62f}1&P7yut#l<@!n literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/toolbar_debug_devtools.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/toolbar_debug_devtools.bmp new file mode 100644 index 0000000000000000000000000000000000000000..165a0f9c25ce1bdb4f1386cdf83b9c2b03ff83a5 GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y!%znC-ZsP|G>;Om5vUTYUNk`< zcVDIfGJ;rvrVOhf8G3;hp_vTlVzmM;i0neR7B~a03@!p>pb5fFKvsjP3?d8H3)h9! z<#1)lW+Dq>)rDpSF1^U&Xl!IF;8Iux;j(ZBR%H-DB1yPW5C)ODu-c1e)Nthj02lv{ A{{R30 literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/toolbar_debug_start.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/toolbar_debug_start.bmp new file mode 100644 index 0000000000000000000000000000000000000000..45e52741701738d17dc004ca66358303a37d4f41 GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y!>|Cl@nU5A1E?2*$S?t@(RZ#E z5RqX5Trb=N;vImdmm~*Z>V-Q1D23k*xb(tJz@r_PUZ6M`_7bBD;uti03EGA11-M?~ Ut%GZaXd%fuWW8|qC<8eJ0D_{`(f|Me literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/toolbar_debug_stop.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/toolbar_debug_stop.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4f79e5ded59072054b4811597afba2e94f3ec27a GIT binary patch literal 1254 zcmZ?rea6B724+A~1BgYSn2|vOEWQCKe}oT$!2&?y!-xkmGPSr6{;&b+a&Wkg3jt;E bXdl&!9B#uetbkDu^b{_HCt-|A;ST`-HQJ_$ literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/toolbar_help.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/toolbar_help.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cf2b09d75b88d83d999f2c627fd49adb435c767b GIT binary patch literal 822 zcmbu2u?@o@5Jid7M=4nVDXm?YK9WmnFT*Yjf#e08jtN)*&)~+%#g}|pppZyGI=KJ; zyW?uQqu5SI_l4^Gs)LZ5FDSpAxY!Wl{`YxrdcO5#OzxS|L0Z{XMx}#2++;u|`@XO6 z8BF9n&lyh=7#c9cFs$ne$qg_x0Iap+I6{8qLkPy0Pdxef!Z}BBSr#efo(I4tWYaV; o#*~s$s=`ymBhxf#t=qQs-h;-s24+A~1BfM{m=VlkU^oDjKf(vWV1+;;ihAG!#Q@?KijDbz)tvYMHzE<- z0l3WhPXqwkHPp@7l4%Y^XnrNbUxUOPh%+!rhzE)H7p4iw9wgozc)%iShYJn^bCCT4 z^bQ=6oiBhUync8Gh>!yZXd0>c6k-mVA>^5ZX$T&3fQoS;c$gqFu=)#G0g>#%X%56y G6p{d{WHaFa literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/toolbar_open.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/toolbar_open.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3bb431ebb5f665b9de37883a2c1b06549afa4ce5 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+;;ihAG!#Q@?KijDa|3v=Y6Du_pD zUO;va(2)2`|A|3x>)@u5XAaOVh*3kr9H1kK4nc-O(TpfL!VfTkXe zi$^-s24+A~1BfM{m=VlkU^oDjKf(vWV1+;;ihAG!#Q@?KijDa|BXcsn%}GLV zkD$2+XvnJCC?LXb8e9!A=KR6|knI}D=HLlx;=>uD5-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|0o#BApna;!ZaRV64s2W0;^FF zC0M1f3gS|aOB|~qKtWvUk;NPE0*J}T>XGe27RPH$1M%h{n~#f)Y%j7JT;j-TklDD@ f;}S>Ki_FHO9wJ3NiEJzyn<|E&nK{ZG#vuRzduEwz literal 0 HcmV?d00001 diff --git a/CORE/Source/Includes/HTMLEditor/libs/editor/icons/week_picker.bmp b/CORE/Source/Includes/HTMLEditor/libs/editor/icons/week_picker.bmp new file mode 100644 index 0000000000000000000000000000000000000000..44ea12ab4a407eda9b27fd8bcab4d6d254f9fffd GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKf(vWV1+>9|8NH|kCH}Xh6-u=VXASNgDH+n z1Y#1VEG}_Ol@JkJ>T!vWnu9;whDZ27VxM>t)7P{}KX}Z9OTigvPJ)P&N}?G8// + +No Windows-specific unit/API may be referenced by the common PageProducer +editor. Platform-specific code must be isolated by IFDEF/backend units. diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/android/aarch64/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/android/aarch64/README.txt new file mode 100644 index 000000000..c3e3f1c50 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/android/aarch64/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=android +CPU=aarch64 + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/android/arm/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/android/arm/README.txt new file mode 100644 index 000000000..070758ffa --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/android/arm/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=android +CPU=arm + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/android/i386/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/android/i386/README.txt new file mode 100644 index 000000000..96a60a499 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/android/i386/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=android +CPU=i386 + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/android/x86_64/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/android/x86_64/README.txt new file mode 100644 index 000000000..220aa547c --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/android/x86_64/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=android +CPU=x86_64 + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/darwin/aarch64/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/darwin/aarch64/README.txt new file mode 100644 index 000000000..0e48e2d73 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/darwin/aarch64/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=darwin +CPU=aarch64 + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/darwin/x86_64/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/darwin/x86_64/README.txt new file mode 100644 index 000000000..1d8e2fb79 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/darwin/x86_64/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=darwin +CPU=x86_64 + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/freebsd/aarch64/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/freebsd/aarch64/README.txt new file mode 100644 index 000000000..18d642c8a --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/freebsd/aarch64/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=freebsd +CPU=aarch64 + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/freebsd/i386/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/freebsd/i386/README.txt new file mode 100644 index 000000000..eb02910e6 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/freebsd/i386/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=freebsd +CPU=i386 + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/freebsd/x86_64/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/freebsd/x86_64/README.txt new file mode 100644 index 000000000..14fc515a0 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/freebsd/x86_64/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=freebsd +CPU=x86_64 + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/ios/aarch64/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/ios/aarch64/README.txt new file mode 100644 index 000000000..580c53bab --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/ios/aarch64/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=ios +CPU=aarch64 + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/ios/arm/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/ios/arm/README.txt new file mode 100644 index 000000000..572f80eae --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/ios/arm/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=ios +CPU=arm + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/ios/x86_64/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/ios/x86_64/README.txt new file mode 100644 index 000000000..9324d1b86 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/ios/x86_64/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=ios +CPU=x86_64 + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/linux/aarch64/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/linux/aarch64/README.txt new file mode 100644 index 000000000..ca5217ff6 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/linux/aarch64/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=linux +CPU=aarch64 + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/linux/arm/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/linux/arm/README.txt new file mode 100644 index 000000000..776bded5d --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/linux/arm/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=linux +CPU=arm + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/linux/i386/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/linux/i386/README.txt new file mode 100644 index 000000000..a422602f2 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/linux/i386/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=linux +CPU=i386 + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/linux/x86_64/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/linux/x86_64/README.txt new file mode 100644 index 000000000..193d37641 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/linux/x86_64/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=linux +CPU=x86_64 + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/windows/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/windows/README.txt new file mode 100644 index 000000000..b8db4860f --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/windows/README.txt @@ -0,0 +1,11 @@ +Windows native WebView2 loader layout + +windows/i386/WebView2Loader.dll + copied from project bin32 and verified as PE i386. + +windows/x86_64/WebView2Loader.dll + copied from project bin64 and verified as PE x86_64. + +windows/aarch64/ + no ARM64 binary exists in the current base, therefore no incompatible + DLL is copied there. Use the official Microsoft ARM64 WebView2Loader.dll. diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/windows/aarch64/MISSING-WebView2Loader-ARM64.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/windows/aarch64/MISSING-WebView2Loader-ARM64.txt new file mode 100644 index 000000000..31d53c1e2 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/windows/aarch64/MISSING-WebView2Loader-ARM64.txt @@ -0,0 +1,7 @@ +WebView2Loader.dll ARM64 is not present in the current RESTDataware source package. + +Do NOT copy the x64 DLL into this directory. +For an ARM64 Windows build, place the official Microsoft ARM64 WebView2Loader.dll here. +The project currently contains validated PE binaries only for: +- windows/i386 +- windows/x86_64 diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/windows/aarch64/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/windows/aarch64/README.txt new file mode 100644 index 000000000..a376b6c02 --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/windows/aarch64/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=windows +CPU=aarch64 + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/windows/i386/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/windows/i386/README.txt new file mode 100644 index 000000000..8d205abbb --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/windows/i386/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=windows +CPU=i386 + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). diff --git a/CORE/Source/Includes/HTMLEditor/libs/webview/platform/windows/x86_64/README.txt b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/windows/x86_64/README.txt new file mode 100644 index 000000000..129aab2fc --- /dev/null +++ b/CORE/Source/Includes/HTMLEditor/libs/webview/platform/windows/x86_64/README.txt @@ -0,0 +1,12 @@ +RESTDataware TDSWebView native backend location +SysOp=windows +CPU=x86_64 + +Keep native runtime libraries for this exact operating system/processor here. +Do not copy binaries from another SysOp/CPU. + +The common component API remains Laz.Datasnap.DSWebView.TDSWebView. +Windows currently uses the embedded WebView2/WebView4Delphi backend already +shipped with Laz.Datasnap. Other platform backends must use the native +browser engine for their SysOp and must preserve the same DOM editor bridge +(DSSEL/DSHTML/error bridge/InsertHTMLAt/Object Inspector/Delete). From 6e7326e5f0ea14e456f19d358858a4d8119fa62e Mon Sep 17 00:00:00 2001 From: Roniery Santos Cardoso Date: Tue, 8 Sep 2026 22:01:48 -0300 Subject: [PATCH 11/22] chore: remove plugin Htmlviewer legado (substituido pelo HTML Designer) Remove o componente Htmlviewer antigo (incluindo o pacote Extras/TntUnicode), agora substituido pelo novo HTML Designer (Webpascal). refs r4030-r4032, r4034 --- .../Htmlviewer/Extras/TntUnicode/.gitignore | 2 - .../Extras/TntUnicode/CBuilder/TntLibD.bpk | 158 - .../Extras/TntUnicode/CBuilder/TntLibD.cpp | 19 - .../Extras/TntUnicode/CBuilder/TntLibR.bpk | 165 - .../Extras/TntUnicode/CBuilder/TntLibR.cpp | 18 - .../Delphi/bds4/TntUnicodeVcl.bdsproj | 183 - .../TntUnicode/Delphi/bds4/TntUnicodeVcl.cfg | 33 - .../TntUnicode/Delphi/bds4/TntUnicodeVcl.dpk | 71 - .../Delphi/bds4/TntUnicodeVcl_Design.bdsproj | 183 - .../Delphi/bds4/TntUnicodeVcl_Design.cfg | 36 - .../Delphi/bds4/TntUnicodeVcl_Design.dpk | 56 - .../Delphi/d6/TntUnicodeVcl_D60.cfg | 32 - .../Delphi/d6/TntUnicodeVcl_D60.dof | 87 - .../Delphi/d6/TntUnicodeVcl_D60.dpk | 57 - .../Delphi/d6/TntUnicodeVcl_R60.cfg | 32 - .../Delphi/d6/TntUnicodeVcl_R60.dof | 87 - .../Delphi/d6/TntUnicodeVcl_R60.dpk | 71 - .../TntUnicode/Delphi/d6/TntUnicode_6.bpg | 23 - .../Delphi/d7/TntUnicodeVcl_D70.cfg | 34 - .../Delphi/d7/TntUnicodeVcl_D70.dof | 136 - .../Delphi/d7/TntUnicodeVcl_D70.dpk | 56 - .../Delphi/d7/TntUnicodeVcl_D70_DATASNAP.cfg | 35 - .../Delphi/d7/TntUnicodeVcl_D70_DATASNAP.dof | 136 - .../Delphi/d7/TntUnicodeVcl_D70_DATASNAP.dpk | 37 - .../Delphi/d7/TntUnicodeVcl_R70.cfg | 32 - .../Delphi/d7/TntUnicodeVcl_R70.dof | 87 - .../Delphi/d7/TntUnicodeVcl_R70.dpk | 72 - .../TntUnicode/Delphi/d7/TntUnicode_7.bpg | 23 - .../Delphi/d9/TntUnicodeVcl_D90.bdsproj | 172 - .../Delphi/d9/TntUnicodeVcl_D90.cfg | 35 - .../Delphi/d9/TntUnicodeVcl_D90.dpk | 55 - .../Delphi/d9/TntUnicodeVcl_R90.bdsproj | 172 - .../Delphi/d9/TntUnicodeVcl_R90.cfg | 32 - .../Delphi/d9/TntUnicodeVcl_R90.dpk | 72 - .../TntUnicode/Design/TntActions_Design.pas | 183 - .../Extras/TntUnicode/Design/TntActnList.dcr | Bin 484 -> 0 bytes .../Extras/TntUnicode/Design/TntButtons.dcr | Bin 928 -> 0 bytes .../Extras/TntUnicode/Design/TntComCtrls.dcr | Bin 6776 -> 0 bytes .../TntUnicode/Design/TntComCtrls_Design.pas | 228 - .../Design/TntDBClientActns_Design.pas | 36 - .../Extras/TntUnicode/Design/TntDBCtrls.dcr | Bin 3620 -> 0 bytes .../TntUnicode/Design/TntDBGrids_Design.pas | 58 - .../Design/TntDesignEditors_Design.pas | 196 - .../Extras/TntUnicode/Design/TntDialogs.dcr | Bin 936 -> 0 bytes .../Extras/TntUnicode/Design/TntExtCtrls.dcr | Bin 3592 -> 0 bytes .../Extras/TntUnicode/Design/TntExtDlgs.dcr | Bin 960 -> 0 bytes .../Extras/TntUnicode/Design/TntForms.dcr | Bin 920 -> 0 bytes .../TntUnicode/Design/TntForms_Design.pas | 422 - .../Extras/TntUnicode/Design/TntGrids.dcr | Bin 932 -> 0 bytes .../Extras/TntUnicode/Design/TntMenus.dcr | Bin 928 -> 0 bytes .../TntUnicode/Design/TntMenus_Design.pas | 391 - .../Extras/TntUnicode/Design/TntStdCtrls.dcr | Bin 5392 -> 0 bytes .../TntUnicode/Design/TntStrEdit_Design.dfm | 135 - .../TntUnicode/Design/TntStrEdit_Design.pas | 419 - .../Design/TntUnicodeVcl_Register.pas | 132 - .../Design/TntWideStringProperty_Design.pas | 400 - .../TntUnicode/Example/ExampleUnicode.cfg | 35 - .../TntUnicode/Example/ExampleUnicode.dof | 87 - .../TntUnicode/Example/ExampleUnicode.dpr | 13 - .../Extras/TntUnicode/Example/MainFrm.dfm | 143 - .../Extras/TntUnicode/Example/MainFrm.pas | 72 - .../Htmlviewer/Extras/TntUnicode/License.rtf | 52 - .../Htmlviewer/Extras/TntUnicode/Readme.txt | 53 - .../Extras/TntUnicode/Reset Tnt Palette.reg | Bin 1669 -> 0 bytes .../TntUnicode/Source/ActiveIMM_TLB.pas | 1374 -- .../Extras/TntUnicode/Source/TntActnList.pas | 835 - .../Extras/TntUnicode/Source/TntAxCtrls.pas | 191 - .../Extras/TntUnicode/Source/TntBandActn.pas | 92 - .../Extras/TntUnicode/Source/TntButtons.pas | 982 - .../Extras/TntUnicode/Source/TntCheckLst.pas | 184 - .../Extras/TntUnicode/Source/TntClasses.pas | 1799 -- .../Extras/TntUnicode/Source/TntClipBrd.pas | 86 - .../Extras/TntUnicode/Source/TntComCtrls.pas | 5058 ----- .../Extras/TntUnicode/Source/TntCompilers.inc | 356 - .../Extras/TntUnicode/Source/TntControls.pas | 1099 -- .../Extras/TntUnicode/Source/TntDB.pas | 900 - .../Extras/TntUnicode/Source/TntDBActns.pas | 594 - .../TntUnicode/Source/TntDBClientActns.pas | 197 - .../Extras/TntUnicode/Source/TntDBCtrls.pas | 2195 --- .../Extras/TntUnicode/Source/TntDBGrids.pas | 1175 -- .../Extras/TntUnicode/Source/TntDBLogDlg.dfm | 108 - .../Extras/TntUnicode/Source/TntDBLogDlg.pas | 133 - .../Extras/TntUnicode/Source/TntDialogs.pas | 981 - .../Extras/TntUnicode/Source/TntExtActns.pas | 1400 -- .../Extras/TntUnicode/Source/TntExtCtrls.pas | 1062 - .../Extras/TntUnicode/Source/TntExtDlgs.pas | 317 - .../Extras/TntUnicode/Source/TntFileCtrl.pas | 118 - .../TntUnicode/Source/TntFormatStrUtils.pas | 503 - .../Extras/TntUnicode/Source/TntForms.pas | 954 - .../Extras/TntUnicode/Source/TntGraphics.pas | 142 - .../Extras/TntUnicode/Source/TntGrids.pas | 675 - .../Extras/TntUnicode/Source/TntListActns.pas | 207 - .../Extras/TntUnicode/Source/TntMenus.pas | 1146 -- .../Extras/TntUnicode/Source/TntRegistry.pas | 148 - .../Extras/TntUnicode/Source/TntStdActns.pas | 1922 -- .../Extras/TntUnicode/Source/TntStdCtrls.pas | 3215 --- .../Extras/TntUnicode/Source/TntSysUtils.pas | 1883 -- .../Extras/TntUnicode/Source/TntSystem.pas | 1397 -- .../TntUnicode/Source/TntWideStrUtils.pas | 451 - .../TntUnicode/Source/TntWideStrings.pas | 831 - .../Extras/TntUnicode/Source/TntWindows.pas | 1452 -- CORE/Source/Plugins/Htmlviewer/HTMLEd1.dfm | 196 - CORE/Source/Plugins/Htmlviewer/HTMLEd1.lfm | 204 - CORE/Source/Plugins/Htmlviewer/HTMLEd1.pas | 452 - .../Plugins/Htmlviewer/HTMLEditorDSG.dpr | 18 - .../Plugins/Htmlviewer/HtmlHelp/HTMLVIEW.hhk | 1252 -- .../Htmlviewer/HtmlHelp/THtmlViewer.chm | Bin 160984 -> 0 bytes .../Htmlviewer/HtmlHelp/THtmlViewer.hhp | 253 - .../HtmlHelp/html/_body__attributes.htm | 61 - .../HtmlHelp/html/activeviewer_property.htm | 36 - .../HtmlHelp/html/assign_tbuffer_method.htm | 35 - .../HtmlHelp/html/assignto_tbuffer_method.htm | 35 - .../HtmlHelp/html/asstring_tbuffer_method.htm | 37 - .../html/backbuttonenabled_property.htm | 38 - .../HtmlHelp/html/base_property.htm | 39 - .../HtmlHelp/html/basetarget_property.htm | 33 - .../HtmlHelp/html/borderstyle_property.htm | 36 - .../HtmlHelp/html/caretpos_property.htm | 44 - .../HtmlHelp/html/charset_property.htm | 32 - .../HtmlHelp/html/class_hierarchy.htm | 332 - .../Htmlviewer/HtmlHelp/html/clear_method.htm | 31 - .../HtmlHelp/html/clearhistory_method.htm | 34 - .../html/codepage_tbuffer_property.htm | 34 - .../Htmlviewer/HtmlHelp/html/contents.htm | 98 - .../HtmlHelp/html/convert_tbuffer_method.htm | 42 - .../Htmlviewer/HtmlHelp/html/copyright.htm | 31 - .../HtmlHelp/html/copytoclipboard_method.htm | 42 - .../HtmlHelp/html/currentfile_property.htm | 29 - .../HtmlHelp/html/defbackground_property.htm | 36 - .../HtmlHelp/html/deffontcolor_property.htm | 37 - .../HtmlHelp/html/deffontname_property.htm | 32 - .../HtmlHelp/html/deffontsize_property.htm | 32 - .../html/defhotspotcolor_property.htm | 36 - .../html/defoverlinkcolor_property.htm | 36 - .../HtmlHelp/html/defprefontname_property.htm | 32 - .../html/defvisitedlinkcolor_property.htm | 38 - .../HtmlHelp/html/displaypostoxy_method.htm | 57 - .../HtmlHelp/html/dither_property.htm | 41 - .../HtmlHelp/html/documentsource_property.htm | 34 - .../HtmlHelp/html/dostohtml_function.htm | 45 - .../html/event_thtmlvieweronhotspotclick.htm | 58 - .../event_thtmlvieweronhotspotcovered.htm | 56 - .../Htmlviewer/HtmlHelp/html/find_method.htm | 47 - .../HtmlHelp/html/finddisplaypos_method.htm | 39 - .../HtmlHelp/html/findsourcepos_method.htm | 39 - .../html/formcontrollist_property.htm | 88 - .../HtmlHelp/html/formdata_property.htm | 110 - .../HtmlHelp/html/fulldisplaysize_method.htm | 37 - .../HtmlHelp/html/fvoptions_property.htm | 87 - .../html/fwdbuttonenabled_property.htm | 38 - .../HtmlHelp/html/getcharatpos_method.htm | 40 - .../HtmlHelp/html/getpostquery_method.htm | 47 - .../HtmlHelp/html/getseltextbuf_method.htm | 37 - .../html/getstring_tbuffer_method.htm | 37 - .../HtmlHelp/html/getviewerurlbase_method.htm | 31 - .../HtmlHelp/html/goback_method.htm | 40 - .../Htmlviewer/HtmlHelp/html/gofwd_method.htm | 40 - .../Plugins/Htmlviewer/HtmlHelp/html/help.css | 17 - .../HtmlHelp/html/history_property.htm | 31 - .../HtmlHelp/html/historyindex_property.htm | 31 - .../html/historymaxcount_property.htm | 32 - .../html/hscrollbarposition_property.htm | 38 - .../html/hscrollbarrange_property.htm | 36 - .../html/htmlexpandfilename_method.htm | 49 - .../Htmlviewer/HtmlHelp/html/htmltodos.htm | 43 - .../HtmlHelp/html/htoptions_property.htm | 73 - .../HtmlHelp/html/idcontrol_property.htm | 60 - .../HtmlHelp/html/iddisplay_property.htm | 33 - .../html/imagecachecount_property.htm | 36 - .../HtmlHelp/html/insertimage_method.htm | 58 - .../HtmlHelp/html/linkattributes_property.htm | 46 - .../HtmlHelp/html/linktext_property.htm | 48 - .../Htmlviewer/HtmlHelp/html/load_method.htm | 41 - .../HtmlHelp/html/loadfrombuffer_method.htm | 62 - .../HtmlHelp/html/loadfromdocument_method.htm | 41 - .../HtmlHelp/html/loadfromfile_method.htm | 46 - .../HtmlHelp/html/loadfromstream_method.htm | 41 - .../HtmlHelp/html/loadfromstring_method.htm | 40 - .../HtmlHelp/html/loadimagefile_method.htm | 42 - .../HtmlHelp/html/loadstrings_method.htm | 50 - .../html/loadtargetfromfile_method.htm | 51 - .../HtmlHelp/html/loadtextfile_method.htm | 42 - .../HtmlHelp/html/loadtextstrings_method.htm | 41 - .../HtmlHelp/html/loadurl_method.htm | 41 - .../HtmlHelp/html/makebitmap_method.htm | 53 - .../HtmlHelp/html/makemetafile_method.htm | 56 - .../html/makepagedmetafiles_method.htm | 48 - ...arginheight_and_marginwidth_properties.htm | 34 - .../HtmlHelp/html/maxvertical_property.htm | 31 - .../HtmlHelp/html/name_tbuffer_property.htm | 29 - .../HtmlHelp/html/namelist_property.htm | 31 - .../HtmlHelp/html/nextchar_tbuffer_method.htm | 39 - .../HtmlHelp/html/noselect_property.htm | 31 - .../HtmlHelp/html/numprinterpages_method.htm | 50 - .../html/onblankwindowrequest_event.htm | 75 - .../HtmlHelp/html/onbufferrequest_event.htm | 43 - .../HtmlHelp/html/onfilebrowse_event.htm | 44 - .../HtmlHelp/html/onfilerequest_event.htm | 43 - .../HtmlHelp/html/onformsubmit_event.htm | 44 - .../HtmlHelp/html/ongetpostrequest_event.htm | 42 - .../HtmlHelp/html/onhistorychange_event.htm | 32 - .../html/onhotspottargetclick_event.htm | 64 - .../html/onhotspottargetcovered_event.htm | 68 - .../HtmlHelp/html/onhtstreamrequest_event.htm | 42 - .../HtmlHelp/html/onimageclick_event.htm | 71 - .../HtmlHelp/html/onimageover_event.htm | 37 - .../HtmlHelp/html/onimagerequest_event.htm | 88 - .../HtmlHelp/html/oninclude_event.htm | 53 - .../Htmlviewer/HtmlHelp/html/onlink_event.htm | 31 - .../Htmlviewer/HtmlHelp/html/onmeta_event.htm | 31 - .../HtmlHelp/html/onmetarefresh_event.htm | 33 - .../HtmlHelp/html/onmousedouble_event.htm | 31 - .../HtmlHelp/html/onobjectblur_event.htm | 40 - .../HtmlHelp/html/onobjectchange_event.htm | 42 - .../HtmlHelp/html/onobjectclick_event.htm | 94 - .../HtmlHelp/html/onobjectfocus_event.htm | 40 - .../HtmlHelp/html/onobjecttag_event.htm | 48 - .../HtmlHelp/html/onpanelcreate_event.htm | 45 - .../HtmlHelp/html/onpaneldestroy_event.htm | 41 - .../HtmlHelp/html/onpanelprint_event.htm | 45 - .../HtmlHelp/html/onparsebegin_event.htm | 52 - .../HtmlHelp/html/onparseend_event.htm | 36 - ...onprintheader_and_onprintfooter_events.htm | 47 - ...tmlheader_and_onprinthtmlfooter_events.htm | 43 - .../HtmlHelp/html/onprocessing_event.htm | 33 - .../HtmlHelp/html/onprogress_event.htm | 34 - .../HtmlHelp/html/onrightclick_event.htm | 37 - .../HtmlHelp/html/onscript_event.htm | 32 - .../HtmlHelp/html/onsoundrequest_event.htm | 31 - .../HtmlHelp/html/onstreamrequest_event.htm | 43 - .../HtmlHelp/html/onstringsrequest_event.htm | 43 - .../HtmlHelp/html/onviewerclear_event.htm | 31 - ...nt__abortprint__and_closeprint_methods.htm | 52 - .../HtmlHelp/html/palette_property.htm | 73 - .../HtmlHelp/html/peekchar_tbuffer_method.htm | 39 - .../html/position_tbuffer_property.htm | 35 - .../HtmlHelp/html/positionto_method.htm | 38 - .../Htmlviewer/HtmlHelp/html/print_method.htm | 42 - .../HtmlHelp/html/printmargin_properties.htm | 47 - .../HtmlHelp/html/printscale_property.htm | 34 - .../HtmlHelp/html/processing_property.htm | 37 - .../html/prop_thtmlviewer_quirksmode.htm | 30 - .../html/prop_thtmlviewerdocumenttitle.htm | 30 - .../html/prop_thtmlviewerposition.htm | 58 - .../HtmlHelp/html/ptinobject_method.htm | 33 - .../Htmlviewer/HtmlHelp/html/reference.htm | 28 - .../HtmlHelp/html/reformat_method.htm | 35 - .../Htmlviewer/HtmlHelp/html/reformatting.htm | 15 - .../HtmlHelp/html/reload_method.htm | 31 - .../HtmlHelp/html/replaceimage_method.htm | 47 - .../HtmlHelp/html/selectall_method.htm | 38 - .../HtmlHelp/html/sellength_property.htm | 42 - .../HtmlHelp/html/selstart_property.htm | 41 - .../HtmlHelp/html/seltext_property.htm | 37 - .../HtmlHelp/html/serverroot_property.htm | 41 - .../html/setting_up_a_history_list.htm | 41 - .../HtmlHelp/html/size_tbuffer_method.htm | 35 - .../html/special_html_tags_and_attributes.htm | 82 - .../HtmlHelp/html/supported_elements.htm | 342 - .../HtmlHelp/html/supported_properties.htm | 395 - .../HtmlHelp/html/target_property.htm | 37 - .../HtmlHelp/html/tframebrowser_component.htm | 37 - .../HtmlHelp/html/tframebrowser_events.htm | 58 - .../HtmlHelp/html/tframebrowser_methods.htm | 41 - .../html/tframebrowser_properties.htm | 64 - .../HtmlHelp/html/tframeviewer_component.htm | 37 - .../HtmlHelp/html/tframeviewer_events.htm | 60 - .../HtmlHelp/html/tframeviewer_methods.htm | 43 - .../HtmlHelp/html/tframeviewerproperties.htm | 66 - .../Htmlviewer/HtmlHelp/html/tfreelist.htm | 19 - .../HtmlHelp/html/things_you_should_know.htm | 84 - .../HtmlHelp/html/thtmlviewer_component.htm | 37 - .../HtmlHelp/html/thtmlviewer_events.htm | 57 - .../HtmlHelp/html/thtmlviewer_methods.htm | 61 - .../HtmlHelp/html/thtmlviewerproperties.htm | 80 - .../HtmlHelp/html/titleattr_property.htm | 35 - .../HtmlHelp/html/titlehistory_property.htm | 31 - .../HtmlHelp/html/type_tbuffcodepage.htm | 28 - .../Htmlviewer/HtmlHelp/html/type_tbuffer.htm | 59 - .../html/type_tbufferrequestevent.htm | 47 - .../HtmlHelp/html/type_tfilebrowseevent.htm | 27 - .../HtmlHelp/html/type_tfilerequestevent.htm | 45 - .../HtmlHelp/html/type_tformsubmitevent.htm | 58 - .../HtmlHelp/html/type_tgetimageevent.htm | 42 - .../html/type_tgetpostrequestevent.htm | 52 - .../html/type_tgetpostrequestexevent.htm | 51 - .../HtmlHelp/html/type_tgetstreamevent.htm | 37 - .../HtmlHelp/html/type_thotspotclickevent.htm | 37 - .../HtmlHelp/html/type_thotspotevent.htm | 33 - .../html/type_thotspottargetclickevent.htm | 41 - .../html/type_thotspottargetevent_.htm | 29 - .../Htmlviewer/HtmlHelp/html/type_thtchar.htm | 41 - .../HtmlHelp/html/type_thtmlfiletype.htm | 36 - .../HtmlHelp/html/type_thtmlpageprinted.htm | 69 - .../HtmlHelp/html/type_thtobjectevent.htm | 54 - .../HtmlHelp/html/type_thtprogressevent.htm | 35 - .../HtmlHelp/html/type_thtquirksmode.htm | 45 - .../HtmlHelp/html/type_thtstring.htm | 41 - .../HtmlHelp/html/type_thtstrings.htm | 45 - .../HtmlHelp/html/type_timageclickevent.htm | 33 - .../HtmlHelp/html/type_timageoverevent.htm | 33 - .../HtmlHelp/html/type_tincludetype.htm | 45 - .../HtmlHelp/html/type_tlinktype.htm | 29 - .../HtmlHelp/html/type_tmetarefreshtype.htm | 33 - .../HtmlHelp/html/type_tmetatype.htm | 33 - .../HtmlHelp/html/type_tobjectclickevent.htm | 46 - .../HtmlHelp/html/type_tobjecttagevent.htm | 55 - .../HtmlHelp/html/type_tpageprinted.htm | 77 - .../HtmlHelp/html/type_tpanelcreateevent.htm | 41 - .../HtmlHelp/html/type_tpaneldestroyevent.htm | 37 - .../HtmlHelp/html/type_tpanelprintevent.htm | 57 - .../HtmlHelp/html/type_tprocessingevent.htm | 31 - .../HtmlHelp/html/type_trightclickevent.htm | 53 - .../HtmlHelp/html/type_tscriptevent.htm | 27 - .../HtmlHelp/html/type_tsoundtype.htm | 27 - .../html/type_tstreamrequestevent.htm | 43 - .../html/type_tstringsrequestevent.htm | 45 - .../html/type_twindowrequestevent.htm | 31 - .../Plugins/Htmlviewer/HtmlHelp/html/url.htm | 17 - .../Htmlviewer/HtmlHelp/html/url_property.htm | 41 - .../using_the_tframebrowser_component.htm | 51 - .../html/using_the_tframeviewer_component.htm | 47 - .../html/using_the_thtmlviewer_component.htm | 48 - .../HtmlHelp/html/viewerfromtarget_method.htm | 42 - .../HtmlHelp/html/viewers_property.htm | 43 - .../HtmlHelp/html/viewimages_property.htm | 34 - .../html/visitedmaxcount_property.htm | 34 - .../vscrollbar__hscrollbar_properties.htm | 44 - .../html/vscrollbarposition_property.htm | 40 - .../html/vscrollbarrange_property.htm | 38 - .../Htmlviewer/HtmlHelp/html/waitstream.htm | 15 - .../HtmlHelp/html/xytodisplaypos_method.htm | 43 - .../Plugins/Htmlviewer/HtmlHelp/htmlview.hhc | 895 - .../Htmlviewer/HtmlHelp/images/bm0.gif | Bin 970 -> 0 bytes .../Htmlviewer/HtmlHelp/images/bm1.gif | Bin 972 -> 0 bytes .../Htmlviewer/HtmlHelp/images/bm2.gif | Bin 991 -> 0 bytes .../Htmlviewer/HtmlHelp/images/bm3.gif | Bin 824 -> 0 bytes .../Htmlviewer/HtmlHelp/images/bm4.gif | Bin 824 -> 0 bytes .../Htmlviewer/HtmlHelp/images/bm5.gif | Bin 889 -> 0 bytes .../Htmlviewer/HtmlHelp/images/bm6.gif | Bin 835 -> 0 bytes .../Htmlviewer/HtmlHelp/images/bm7.gif | Bin 869 -> 0 bytes .../Htmlviewer/HtmlHelp/images/bm8.gif | Bin 1080 -> 0 bytes .../Htmlviewer/HtmlHelp/images/bm9.gif | Bin 944 -> 0 bytes .../Htmlviewer/HtmlHelp/images/smallcheck.gif | Bin 1012 -> 0 bytes .../Htmlviewer/HtmlHelp/images/v114.png | Bin 5347 -> 0 bytes .../Htmlviewer/HtmlHelp/images/v115.png | Bin 5347 -> 0 bytes .../Htmlviewer/HtmlHelp/images/v116.png | Bin 5347 -> 0 bytes .../Htmlviewer/HtmlHelp/images/v117.png | Bin 5347 -> 0 bytes .../Htmlviewer/HtmlHelp/images/v118.png | Bin 5347 -> 0 bytes .../Htmlviewer/HtmlHelp/images/v119.png | Bin 5347 -> 0 bytes .../Htmlviewer/HtmlHelp/images/v945.png | Bin 5347 -> 0 bytes .../dwpackage/Delphi/D24/DWhtmlEditor.dpk | 75 - .../dwpackage/Delphi/D24/DWhtmlEditor.dproj | 638 - .../Delphi/D24/htmlEditorPG.groupproj | 48 - .../Htmlviewer/source/AlphaBlendUn.pas | 330 - .../source/BegaHtmlPrintPreviewForm.pas | 198 - .../Htmlviewer/source/BegaMetaFilePrinter.pas | 620 - .../Plugins/Htmlviewer/source/BegaPreview.dfm | 1166 -- .../Plugins/Htmlviewer/source/BegaPreview.lfm | 1198 -- .../Plugins/Htmlviewer/source/BegaPreview.pas | 1143 -- .../Htmlviewer/source/BegaPreviewForm.dfm | 17 - .../Htmlviewer/source/BegaPreviewForm.lfm | 16 - .../Htmlviewer/source/BegaPreviewForm.pas | 174 - .../Htmlviewer/source/BegaPreviewPanel.pas | 643 - .../Htmlviewer/source/BegaScrollBox.pas | 1252 -- .../Plugins/Htmlviewer/source/BegaZoom.pas | 242 - .../Plugins/Htmlviewer/source/BuffConv.pas | 2037 -- .../Htmlviewer/source/BuffConvArrays.pas | 12237 ------------ .../Plugins/Htmlviewer/source/DitherUnit.pas | 1785 -- .../Plugins/Htmlviewer/source/FramBrwz.pas | 1250 -- .../Htmlviewer/source/FrameViewerReg.pas | 83 - .../Plugins/Htmlviewer/source/GDIPL2A.pas | 698 - .../Plugins/Htmlviewer/source/HSLUtils.pas | 247 - .../Htmlviewer/source/HTMLCompEdit.pas | 96 - .../Plugins/Htmlviewer/source/HTMLGif2.pas | 370 - .../Plugins/Htmlviewer/source/HTMLSubs.pas | 16451 ---------------- .../Plugins/Htmlviewer/source/HTMLUn2.pas | 3600 ---- .../Plugins/Htmlviewer/source/HtmlBuffer.pas | 1762 -- .../Plugins/Htmlviewer/source/HtmlCaches.pas | 223 - .../Plugins/Htmlviewer/source/HtmlFonts.pas | 330 - .../Plugins/Htmlviewer/source/HtmlGlobals.pas | 1713 -- .../Plugins/Htmlviewer/source/HtmlImages.pas | 2631 --- .../Plugins/Htmlviewer/source/HtmlSymb.pas | 926 - .../Plugins/Htmlviewer/source/Htmlsbs1.pas | 1728 -- .../Htmlviewer/source/MetaFilePrinter.pas | 596 - .../Htmlviewer/source/Obj/DelphiZLib.obj | Bin 5008 -> 0 bytes .../Plugins/Htmlviewer/source/Obj/adler32.obj | Bin 1148 -> 0 bytes .../Htmlviewer/source/Obj/compress.obj | Bin 674 -> 0 bytes .../Plugins/Htmlviewer/source/Obj/crc32.obj | Bin 11372 -> 0 bytes .../Plugins/Htmlviewer/source/Obj/deflate.obj | Bin 9466 -> 0 bytes .../Plugins/Htmlviewer/source/Obj/infback.obj | Bin 7746 -> 0 bytes .../Plugins/Htmlviewer/source/Obj/inffast.obj | Bin 2361 -> 0 bytes .../Plugins/Htmlviewer/source/Obj/inflate.obj | Bin 11383 -> 0 bytes .../Htmlviewer/source/Obj/inftrees.obj | Bin 2397 -> 0 bytes .../Plugins/Htmlviewer/source/Obj/trees.obj | Bin 11677 -> 0 bytes .../Plugins/Htmlviewer/source/ReadHTML.pas | 5107 ----- .../Plugins/Htmlviewer/source/StylePars.pas | 1911 -- .../Plugins/Htmlviewer/source/StyleTypes.pas | 1301 -- .../Plugins/Htmlviewer/source/StyleUn.pas | 4086 ---- .../Plugins/Htmlviewer/source/URLSubs.pas | 977 - .../Plugins/Htmlviewer/source/UrlConn.pas | 1156 -- .../Plugins/Htmlviewer/source/framview.pas | 4778 ----- .../Plugins/Htmlviewer/source/htmlcomp.lrs | 260 - .../Plugins/Htmlviewer/source/htmlcons.inc | 359 - .../Plugins/Htmlviewer/source/htmlgif1.pas | 2234 --- .../Plugins/Htmlviewer/source/htmlmisc.pas | 1264 -- .../Plugins/Htmlviewer/source/htmlun2.lrs | 89 - .../Plugins/Htmlviewer/source/htmlview.pas | 5565 ------ .../Plugins/Htmlviewer/source/msimg32.pas | 177 - .../Plugins/Htmlviewer/source/vwPrint.pas | 572 - .../Htmlviewer/source/widestringslcl.pas | 1318 -- 411 files changed, 143299 deletions(-) delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/.gitignore delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/CBuilder/TntLibD.bpk delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/CBuilder/TntLibD.cpp delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/CBuilder/TntLibR.bpk delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/CBuilder/TntLibR.cpp delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl.bdsproj delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl.cfg delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl.dpk delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl_Design.bdsproj delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl_Design.cfg delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl_Design.dpk delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_D60.cfg delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_D60.dof delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_D60.dpk delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_R60.cfg delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_R60.dof delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_R60.dpk delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicode_6.bpg delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70.cfg delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70.dof delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70.dpk delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70_DATASNAP.cfg delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70_DATASNAP.dof delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70_DATASNAP.dpk delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_R70.cfg delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_R70.dof delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_R70.dpk delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicode_7.bpg delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_D90.bdsproj delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_D90.cfg delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_D90.dpk delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_R90.bdsproj delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_R90.cfg delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_R90.dpk delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntActions_Design.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntActnList.dcr delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntButtons.dcr delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntComCtrls.dcr delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntComCtrls_Design.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntDBClientActns_Design.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntDBCtrls.dcr delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntDBGrids_Design.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntDesignEditors_Design.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntDialogs.dcr delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntExtCtrls.dcr delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntExtDlgs.dcr delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntForms.dcr delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntForms_Design.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntGrids.dcr delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntMenus.dcr delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntMenus_Design.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntStdCtrls.dcr delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntStrEdit_Design.dfm delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntStrEdit_Design.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntUnicodeVcl_Register.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntWideStringProperty_Design.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/ExampleUnicode.cfg delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/ExampleUnicode.dof delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/ExampleUnicode.dpr delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/MainFrm.dfm delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/MainFrm.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/License.rtf delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Readme.txt delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Reset Tnt Palette.reg delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/ActiveIMM_TLB.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntActnList.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntAxCtrls.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntBandActn.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntButtons.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntCheckLst.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntClasses.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntClipBrd.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntComCtrls.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntCompilers.inc delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntControls.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDB.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBActns.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBClientActns.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBCtrls.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBGrids.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBLogDlg.dfm delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBLogDlg.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDialogs.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntExtActns.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntExtCtrls.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntExtDlgs.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntFileCtrl.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntFormatStrUtils.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntForms.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntGraphics.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntGrids.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntListActns.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntMenus.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntRegistry.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntStdActns.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntStdCtrls.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntSysUtils.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntSystem.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntWideStrUtils.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntWideStrings.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntWindows.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/HTMLEd1.dfm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HTMLEd1.lfm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HTMLEd1.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/HTMLEditorDSG.dpr delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/HTMLVIEW.hhk delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/THtmlViewer.chm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/THtmlViewer.hhp delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/_body__attributes.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/activeviewer_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/assign_tbuffer_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/assignto_tbuffer_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/asstring_tbuffer_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/backbuttonenabled_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/base_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/basetarget_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/borderstyle_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/caretpos_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/charset_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/class_hierarchy.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/clear_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/clearhistory_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/codepage_tbuffer_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/contents.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/convert_tbuffer_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/copyright.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/copytoclipboard_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/currentfile_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defbackground_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/deffontcolor_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/deffontname_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/deffontsize_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defhotspotcolor_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defoverlinkcolor_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defprefontname_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defvisitedlinkcolor_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/displaypostoxy_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/dither_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/documentsource_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/dostohtml_function.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/event_thtmlvieweronhotspotclick.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/event_thtmlvieweronhotspotcovered.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/find_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/finddisplaypos_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/findsourcepos_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/formcontrollist_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/formdata_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/fulldisplaysize_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/fvoptions_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/fwdbuttonenabled_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getcharatpos_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getpostquery_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getseltextbuf_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getstring_tbuffer_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getviewerurlbase_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/goback_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/gofwd_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/help.css delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/history_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/historyindex_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/historymaxcount_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/hscrollbarposition_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/hscrollbarrange_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/htmlexpandfilename_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/htmltodos.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/htoptions_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/idcontrol_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/iddisplay_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/imagecachecount_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/insertimage_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/linkattributes_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/linktext_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/load_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfrombuffer_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfromdocument_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfromfile_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfromstream_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfromstring_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadimagefile_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadstrings_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadtargetfromfile_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadtextfile_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadtextstrings_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadurl_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/makebitmap_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/makemetafile_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/makepagedmetafiles_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/marginheight_and_marginwidth_properties.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/maxvertical_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/name_tbuffer_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/namelist_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/nextchar_tbuffer_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/noselect_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/numprinterpages_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onblankwindowrequest_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onbufferrequest_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onfilebrowse_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onfilerequest_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onformsubmit_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/ongetpostrequest_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onhistorychange_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onhotspottargetclick_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onhotspottargetcovered_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onhtstreamrequest_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onimageclick_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onimageover_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onimagerequest_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/oninclude_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onlink_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onmeta_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onmetarefresh_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onmousedouble_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjectblur_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjectchange_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjectclick_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjectfocus_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjecttag_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onpanelcreate_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onpaneldestroy_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onpanelprint_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onparsebegin_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onparseend_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onprintheader_and_onprintfooter_events.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onprinthtmlheader_and_onprinthtmlfooter_events.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onprocessing_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onprogress_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onrightclick_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onscript_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onsoundrequest_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onstreamrequest_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onstringsrequest_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onviewerclear_event.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/openprint__abortprint__and_closeprint_methods.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/palette_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/peekchar_tbuffer_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/position_tbuffer_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/positionto_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/print_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/printmargin_properties.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/printscale_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/processing_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/prop_thtmlviewer_quirksmode.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/prop_thtmlviewerdocumenttitle.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/prop_thtmlviewerposition.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/ptinobject_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/reference.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/reformat_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/reformatting.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/reload_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/replaceimage_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/selectall_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/sellength_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/selstart_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/seltext_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/serverroot_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/setting_up_a_history_list.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/size_tbuffer_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/special_html_tags_and_attributes.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/supported_elements.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/supported_properties.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/target_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframebrowser_component.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframebrowser_events.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframebrowser_methods.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframebrowser_properties.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframeviewer_component.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframeviewer_events.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframeviewer_methods.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframeviewerproperties.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tfreelist.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/things_you_should_know.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/thtmlviewer_component.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/thtmlviewer_events.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/thtmlviewer_methods.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/thtmlviewerproperties.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/titleattr_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/titlehistory_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tbuffcodepage.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tbuffer.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tbufferrequestevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tfilebrowseevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tfilerequestevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tformsubmitevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tgetimageevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tgetpostrequestevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tgetpostrequestexevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tgetstreamevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thotspotclickevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thotspotevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thotspottargetclickevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thotspottargetevent_.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtchar.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtmlfiletype.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtmlpageprinted.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtobjectevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtprogressevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtquirksmode.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtstring.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtstrings.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_timageclickevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_timageoverevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tincludetype.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tlinktype.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tmetarefreshtype.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tmetatype.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tobjectclickevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tobjecttagevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tpageprinted.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tpanelcreateevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tpaneldestroyevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tpanelprintevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tprocessingevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_trightclickevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tscriptevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tsoundtype.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tstreamrequestevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tstringsrequestevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_twindowrequestevent.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/url.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/url_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/using_the_tframebrowser_component.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/using_the_tframeviewer_component.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/using_the_thtmlviewer_component.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/viewerfromtarget_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/viewers_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/viewimages_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/visitedmaxcount_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/vscrollbar__hscrollbar_properties.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/vscrollbarposition_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/vscrollbarrange_property.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/waitstream.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/xytodisplaypos_method.htm delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/htmlview.hhc delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm0.gif delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm1.gif delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm2.gif delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm3.gif delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm4.gif delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm5.gif delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm6.gif delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm7.gif delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm8.gif delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm9.gif delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/smallcheck.gif delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v114.png delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v115.png delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v116.png delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v117.png delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v118.png delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v119.png delete mode 100644 CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v945.png delete mode 100644 CORE/Source/Plugins/Htmlviewer/dwpackage/Delphi/D24/DWhtmlEditor.dpk delete mode 100644 CORE/Source/Plugins/Htmlviewer/dwpackage/Delphi/D24/DWhtmlEditor.dproj delete mode 100644 CORE/Source/Plugins/Htmlviewer/dwpackage/Delphi/D24/htmlEditorPG.groupproj delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/AlphaBlendUn.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/BegaHtmlPrintPreviewForm.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/BegaMetaFilePrinter.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/BegaPreview.dfm delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/BegaPreview.lfm delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/BegaPreview.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/BegaPreviewForm.dfm delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/BegaPreviewForm.lfm delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/BegaPreviewForm.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/BegaPreviewPanel.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/BegaScrollBox.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/BegaZoom.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/BuffConv.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/BuffConvArrays.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/DitherUnit.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/FramBrwz.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/FrameViewerReg.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/GDIPL2A.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/HSLUtils.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/HTMLCompEdit.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/HTMLGif2.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/HTMLSubs.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/HTMLUn2.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/HtmlBuffer.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/HtmlCaches.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/HtmlFonts.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/HtmlGlobals.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/HtmlImages.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/HtmlSymb.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/Htmlsbs1.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/MetaFilePrinter.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/Obj/DelphiZLib.obj delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/Obj/adler32.obj delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/Obj/compress.obj delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/Obj/crc32.obj delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/Obj/deflate.obj delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/Obj/infback.obj delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/Obj/inffast.obj delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/Obj/inflate.obj delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/Obj/inftrees.obj delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/Obj/trees.obj delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/ReadHTML.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/StylePars.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/StyleTypes.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/StyleUn.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/URLSubs.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/UrlConn.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/framview.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/htmlcomp.lrs delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/htmlcons.inc delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/htmlgif1.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/htmlmisc.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/htmlun2.lrs delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/htmlview.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/msimg32.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/vwPrint.pas delete mode 100644 CORE/Source/Plugins/Htmlviewer/source/widestringslcl.pas diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/.gitignore b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/.gitignore deleted file mode 100644 index 6c4bd5adf..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.dcu - diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/CBuilder/TntLibD.bpk b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/CBuilder/TntLibD.bpk deleted file mode 100644 index 13b292e14..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/CBuilder/TntLibD.bpk +++ /dev/null @@ -1,158 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -[Version Info] -IncludeVerInfo=1 -AutoIncBuild=0 -MajorVer=1 -MinorVer=0 -Release=0 -Build=0 -Debug=0 -PreRelease=0 -Special=0 -Private=0 -DLL=0 -Locale=1033 -CodePage=1252 - -[Version Info Keys] -CompanyName= -FileDescription= -FileVersion=1.0.0.0 -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename= -ProductName= -ProductVersion=1.0.0.0 - -[Debugging] -DebugSourceDirs=$(BCB)\source\vcl - -[Parameters] -RunParams= -Launcher= -UseLauncher=0 -DebugCWD= -HostApplication= -RemoteHost= -RemotePath= -RemoteLauncher= -RemoteCWD= -RemoteDebug=0 - -[Compiler] -ShowInfoMsgs=0 -LinkDebugVcl=0 -LinkCGLIB=0 - -[Language] -ActiveLang= -ProjectLang= -RootDir= - -[Linker] -LibPrefix= -LibSuffix= -LibVersion= - - \ No newline at end of file diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/CBuilder/TntLibD.cpp b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/CBuilder/TntLibD.cpp deleted file mode 100644 index db61223ba..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/CBuilder/TntLibD.cpp +++ /dev/null @@ -1,19 +0,0 @@ -//--------------------------------------------------------------------------- - -#include -#pragma hdrstop -USEFORMNS("..\Design\TntStrEdit_Design.pas", Tntstredit_design, TntStrEditDlg); /* TTntForm: File Type */ -//--------------------------------------------------------------------------- -#pragma package(smart_init) -//--------------------------------------------------------------------------- - -// Package source. -//--------------------------------------------------------------------------- - -#pragma argsused -int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*) -{ - return 1; -} -//--------------------------------------------------------------------------- - \ No newline at end of file diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/CBuilder/TntLibR.bpk b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/CBuilder/TntLibR.bpk deleted file mode 100644 index 38ae072b1..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/CBuilder/TntLibR.bpk +++ /dev/null @@ -1,165 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -[Version Info] -IncludeVerInfo=1 -AutoIncBuild=0 -MajorVer=1 -MinorVer=0 -Release=0 -Build=0 -Debug=0 -PreRelease=0 -Special=0 -Private=0 -DLL=0 -Locale=1033 -CodePage=1252 - -[Version Info Keys] -CompanyName= -FileDescription= -FileVersion=1.0.0.0 -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename= -ProductName= -ProductVersion=1.0.0.0 - -[Debugging] -DebugSourceDirs=$(BCB)\source\vcl - -[Parameters] -RunParams= -Launcher= -UseLauncher=0 -DebugCWD= -HostApplication= -RemoteHost= -RemotePath= -RemoteLauncher= -RemoteCWD= -RemoteDebug=0 - -[Compiler] -ShowInfoMsgs=0 -LinkDebugVcl=0 -LinkCGLIB=0 - -[Language] -ActiveLang= -ProjectLang= -RootDir= - -[Linker] -LibPrefix= -LibSuffix= -LibVersion= - - \ No newline at end of file diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/CBuilder/TntLibR.cpp b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/CBuilder/TntLibR.cpp deleted file mode 100644 index d6261ec23..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/CBuilder/TntLibR.cpp +++ /dev/null @@ -1,18 +0,0 @@ -//--------------------------------------------------------------------------- - -#include -#pragma hdrstop -USEFORMNS("..\Source\TntDBLogDlg.pas", Tntdblogdlg, TntLoginDialog); -//--------------------------------------------------------------------------- -#pragma package(smart_init) -//--------------------------------------------------------------------------- - -// Package source. -//--------------------------------------------------------------------------- - -#pragma argsused -int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*) -{ - return 1; -} -//--------------------------------------------------------------------------- diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl.bdsproj b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl.bdsproj deleted file mode 100644 index f7d9594ba..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl.bdsproj +++ /dev/null @@ -1,183 +0,0 @@ - - - - - - - - - - - - TntUnicodeVcl.dpk - - - 7.0 - - - 8 - 0 - 1 - 1 - 0 - 0 - 1 - 1 - 1 - 0 - 0 - 1 - 0 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 0 - 1 - 0 - 1 - 1 - 1 - True - True - - - 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 - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - - - - 0 - 44 - 1 - False - False - False - 16384 - 1048576 - 4194304 - TntWare Unicode Controls - Runtime - False - - - - - - - - - - - False - - - - - - False - - - - - - False - - True - - False - False - - - - $00000000 - - - - True - False - 2 - 3 - 0 - 1 - False - False - False - False - False - 1033 - 1252 - - - - - 2.3.0.1 - - - - - - 2.3.0.1 - - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl.cfg b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl.cfg deleted file mode 100644 index b1959555c..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl.cfg +++ /dev/null @@ -1,33 +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 --JL --cg --H+ --W+ --M --$M16384,1048576 --K$00400000 diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl.dpk b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl.dpk deleted file mode 100644 index 4abbedbc9..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl.dpk +++ /dev/null @@ -1,71 +0,0 @@ -package TntUnicodeVcl; - -{$R *.res} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$OVERFLOWCHECKS ON} -{$RANGECHECKS ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS ON} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'TntWare Unicode Controls - Runtime'} -{$LIBSUFFIX '100'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - vcl, - vclx, - vcldb, - vclactnband; - -contains - ActiveIMM_TLB in '..\..\Source\ActiveIMM_TLB.pas', - TntSystem in '..\..\Source\TntSystem.pas', - TntAxCtrls in '..\..\Source\TntAxCtrls.pas', - TntClipbrd in '..\..\Source\TntClipbrd.pas', - TntWindows in '..\..\Source\TntWindows.pas', - TntSysUtils in '..\..\Source\TntSysUtils.pas', - TntClasses in '..\..\Source\TntClasses.pas', - TntDialogs in '..\..\Source\TntDialogs.pas', - TntFileCtrl in '..\..\Source\TntFileCtrl.pas', - TntExtDlgs in '..\..\Source\TntExtDlgs.pas', - TntRegistry in '..\..\Source\TntRegistry.pas', - TntGraphics in '..\..\Source\TntGraphics.pas', - TntControls in '..\..\Source\TntControls.pas', - TntActnList in '..\..\Source\TntActnList.pas', - TntMenus in '..\..\Source\TntMenus.pas', - TntForms in '..\..\Source\TntForms.pas', - TntStdCtrls in '..\..\Source\TntStdCtrls.pas', - TntExtCtrls in '..\..\Source\TntExtCtrls.pas', - TntButtons in '..\..\Source\TntButtons.pas', - TntCheckLst in '..\..\Source\TntCheckLst.pas', - TntGrids in '..\..\Source\TntGrids.pas', - TntComCtrls in '..\..\Source\TntComCtrls.pas', - TntDB in '..\..\Source\TntDB.pas', - TntDBCtrls in '..\..\Source\TntDBCtrls.pas', - TntDBGrids in '..\..\Source\TntDBGrids.pas', - TntStdActns in '..\..\Source\TntStdActns.pas', - TntExtActns in '..\..\Source\TntExtActns.pas', - TntListActns in '..\..\Source\TntListActns.pas', - TntDBActns in '..\..\Source\TntDBActns.pas', - TntBandActn in '..\..\Source\TntBandActn.pas', - TntDBLogDlg in '..\..\Source\TntDBLogDlg.pas', - TntFormatStrUtils in '..\..\Source\TntFormatStrUtils.pas', - TntWideStrUtils in '..\..\Source\TntWideStrUtils.pas'; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl_Design.bdsproj b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl_Design.bdsproj deleted file mode 100644 index df302ed3a..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl_Design.bdsproj +++ /dev/null @@ -1,183 +0,0 @@ - - - - - - - - - - - - TntUnicodeVcl_Design.dpk - - - 7.0 - - - 8 - 0 - 1 - 1 - 0 - 0 - 1 - 1 - 1 - 0 - 0 - 1 - 0 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 0 - 1 - 0 - 1 - 1 - 1 - True - True - - - 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 - True - True - True - True - True - True - True - False - False - False - True - True - True - True - True - - - - 0 - 44 - 1 - False - False - False - 16384 - 1048576 - 4194304 - TntWare Unicode Controls - False - - - - - - - - - - - False - - - - - - False - - - - - - False - - True - - False - False - - - - $00000000 - - - - True - False - 2 - 3 - 0 - 1 - False - False - False - False - False - 1033 - 1252 - - - - - 2.3.0.1 - - - - - - 2.3.0.1 - - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl_Design.cfg b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl_Design.cfg deleted file mode 100644 index eeb2522da..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl_Design.cfg +++ /dev/null @@ -1,36 +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 --JL --cg --H+ --W+ --M --$M16384,1048576 --K$00400000 --w-UNSAFE_TYPE --w-UNSAFE_CODE --w-UNSAFE_CAST diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl_Design.dpk b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl_Design.dpk deleted file mode 100644 index 514e91df4..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/bds4/TntUnicodeVcl_Design.dpk +++ /dev/null @@ -1,56 +0,0 @@ -package TntUnicodeVcl_Design; - -{$R *.res} -{$R '..\..\Design\TntComCtrls.dcr'} -{$R '..\..\Design\TntDBCtrls.dcr'} -{$R '..\..\Design\TntStdCtrls.dcr'} -{$R '..\..\Design\TntActnList.dcr'} -{$R '..\..\Design\TntMenus.dcr'} -{$R '..\..\Design\TntExtCtrls.dcr'} -{$R '..\..\Design\TntForms.dcr'} -{$R '..\..\Design\TntGrids.dcr'} -{$R '..\..\Design\TntButtons.dcr'} -{$R '..\..\Design\TntDialogs.dcr'} -{$R '..\..\Design\TntExtDlgs.dcr'} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$OVERFLOWCHECKS ON} -{$RANGECHECKS ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS ON} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'TntWare Unicode Controls'} -{$LIBSUFFIX '100'} -{$DESIGNONLY} -{$IMPLICITBUILD ON} - -requires - TntUnicodeVcl, - designide, - dcldb; - -contains - TntForms_Design in '..\..\Design\TntForms_Design.pas', - TntComCtrls_Design in '..\..\Design\TntComCtrls_Design.pas', - TntDBGrids_Design in '..\..\Design\TntDBGrids_Design.pas', - TntDesignEditors_Design in '..\..\Design\TntDesignEditors_Design.pas', - TntStrEdit_Design in '..\..\Design\TntStrEdit_Design.pas', - TntUnicodeVcl_Register in '..\..\Design\TntUnicodeVcl_Register.pas', - TntActions_Design in '..\..\Design\TntActions_Design.pas', - TntMenus_Design in '..\..\Design\TntMenus_Design.pas'; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_D60.cfg b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_D60.cfg deleted file mode 100644 index 78a35d3de..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_D60.cfg +++ /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/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_D60.dof b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_D60.dof deleted file mode 100644 index 96f6653eb..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_D60.dof +++ /dev/null @@ -1,87 +0,0 @@ -[FileVersion] -Version=6.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=1 -R=1 -S=0 -T=1 -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=Tnt Unicode Controls -[Directories] -OutputDir= -UnitOutputDir= -PackageDLLOutputDir= -PackageDCPOutputDir= -SearchPath= -Packages= -Conditionals= -DebugSourceDirs= -UsePackages=0 -[Parameters] -RunParams= -HostApplication= -Launcher= -UseLauncher=0 -DebugCWD= -[Language] -ActiveLang= -ProjectLang=$00000409 -RootDir= -[Version Info] -IncludeVerInfo=1 -AutoIncBuild=0 -MajorVer=2 -MinorVer=3 -Release=0 -Build=1 -Debug=0 -PreRelease=0 -Special=0 -Private=0 -DLL=0 -Locale=1033 -CodePage=1252 -[Version Info Keys] -CompanyName= -FileDescription= -FileVersion=2.3.0.1 -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename= -ProductName= -ProductVersion=2.3.0.1 -Comments= diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_D60.dpk b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_D60.dpk deleted file mode 100644 index 1217ba9e3..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_D60.dpk +++ /dev/null @@ -1,57 +0,0 @@ -package TntUnicodeVcl_D60; - -{$R *.res} -{$R '..\..\Design\TntComCtrls.dcr'} -{$R '..\..\Design\TntDBCtrls.dcr'} -{$R '..\..\Design\TntStdCtrls.dcr'} -{$R '..\..\Design\TntActnList.dcr'} -{$R '..\..\Design\TntMenus.dcr'} -{$R '..\..\Design\TntExtCtrls.dcr'} -{$R '..\..\Design\TntForms.dcr'} -{$R '..\..\Design\TntGrids.dcr'} -{$R '..\..\Design\TntButtons.dcr'} -{$R '..\..\Design\TntDialogs.dcr'} -{$R '..\..\Design\TntExtDlgs.dcr'} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$OVERFLOWCHECKS ON} -{$RANGECHECKS ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS ON} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Tnt Unicode Controls'} -{$DESIGNONLY} -{$IMPLICITBUILD ON} - -requires - dclact, - dcldb, - designide, - TntUnicodeVcl_R60; - -contains - TntForms_Design in '..\..\Design\TntForms_Design.pas', - TntComCtrls_Design in '..\..\Design\TntComCtrls_Design.pas', - TntDBGrids_Design in '..\..\Design\TntDBGrids_Design.pas', - TntDesignEditors_Design in '..\..\Design\TntDesignEditors_Design.pas', - TntWideStringProperty_Design in '..\..\Design\TntWideStringProperty_Design.pas', - TntMenus_Design in '..\..\Design\TntMenus_Design.pas', - TntStrEdit_Design in '..\..\Design\TntStrEdit_Design.pas', - TntUnicodeVcl_Register in '..\..\Design\TntUnicodeVcl_Register.pas', - TntActions_Design in '..\..\Design\TntActions_Design.pas'; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_R60.cfg b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_R60.cfg deleted file mode 100644 index 78a35d3de..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_R60.cfg +++ /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/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_R60.dof b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_R60.dof deleted file mode 100644 index 102f4b0c5..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_R60.dof +++ /dev/null @@ -1,87 +0,0 @@ -[FileVersion] -Version=6.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=1 -R=1 -S=0 -T=1 -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=Tnt Unicode Controls - Runtime -[Directories] -OutputDir= -UnitOutputDir= -PackageDLLOutputDir= -PackageDCPOutputDir= -SearchPath= -Packages= -Conditionals= -DebugSourceDirs= -UsePackages=0 -[Parameters] -RunParams= -HostApplication= -Launcher= -UseLauncher=0 -DebugCWD= -[Language] -ActiveLang= -ProjectLang=$00000409 -RootDir= -[Version Info] -IncludeVerInfo=1 -AutoIncBuild=0 -MajorVer=2 -MinorVer=3 -Release=0 -Build=1 -Debug=0 -PreRelease=0 -Special=0 -Private=0 -DLL=0 -Locale=1033 -CodePage=1252 -[Version Info Keys] -CompanyName= -FileDescription= -FileVersion=2.3.0.1 -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename= -ProductName= -ProductVersion=2.3.0.1 -Comments= diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_R60.dpk b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_R60.dpk deleted file mode 100644 index 80ce16f75..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicodeVcl_R60.dpk +++ /dev/null @@ -1,71 +0,0 @@ -package TntUnicodeVcl_R60; - -{$R *.res} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$OVERFLOWCHECKS ON} -{$RANGECHECKS ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS ON} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Tnt Unicode Controls - Runtime'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - vcl, - vclx, - vcldb, - dclact; - -contains - ActiveIMM_TLB in '..\..\Source\ActiveIMM_TLB.pas', - TntSystem in '..\..\Source\TntSystem.pas', - TntAxCtrls in '..\..\Source\TntAxCtrls.pas', - TntClipbrd in '..\..\Source\TntClipbrd.pas', - TntWindows in '..\..\Source\TntWindows.pas', - TntSysUtils in '..\..\Source\TntSysUtils.pas', - TntClasses in '..\..\Source\TntClasses.pas', - TntDialogs in '..\..\Source\TntDialogs.pas', - TntFileCtrl in '..\..\Source\TntFileCtrl.pas', - TntExtDlgs in '..\..\Source\TntExtDlgs.pas', - TntRegistry in '..\..\Source\TntRegistry.pas', - TntGraphics in '..\..\Source\TntGraphics.pas', - TntControls in '..\..\Source\TntControls.pas', - TntActnList in '..\..\Source\TntActnList.pas', - TntMenus in '..\..\Source\TntMenus.pas', - TntForms in '..\..\Source\TntForms.pas', - TntStdCtrls in '..\..\Source\TntStdCtrls.pas', - TntExtCtrls in '..\..\Source\TntExtCtrls.pas', - TntButtons in '..\..\Source\TntButtons.pas', - TntCheckLst in '..\..\Source\TntCheckLst.pas', - TntGrids in '..\..\Source\TntGrids.pas', - TntComCtrls in '..\..\Source\TntComCtrls.pas', - TntDB in '..\..\Source\TntDB.pas', - TntDBCtrls in '..\..\Source\TntDBCtrls.pas', - TntDBGrids in '..\..\Source\TntDBGrids.pas', - TntStdActns in '..\..\Source\TntStdActns.pas', - TntExtActns in '..\..\Source\TntExtActns.pas', - TntListActns in '..\..\Source\TntListActns.pas', - TntDBActns in '..\..\Source\TntDBActns.pas', - TntBandActn in '..\..\Source\TntBandActn.pas', - TntDBLogDlg in '..\..\Source\TntDBLogDlg.pas', - TntFormatStrUtils in '..\..\Source\TntFormatStrUtils.pas', - TntWideStrings in '..\..\Source\TntWideStrings.pas', - TntWideStrUtils in '..\..\Source\TntWideStrUtils.pas'; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicode_6.bpg b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicode_6.bpg deleted file mode 100644 index abdc8bd01..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d6/TntUnicode_6.bpg +++ /dev/null @@ -1,23 +0,0 @@ -#------------------------------------------------------------------------------ -VERSION = BWS.01 -#------------------------------------------------------------------------------ -!ifndef ROOT -ROOT = $(MAKEDIR)\.. -!endif -#------------------------------------------------------------------------------ -MAKE = $(ROOT)\bin\make.exe -$(MAKEFLAGS) -f$** -DCC = $(ROOT)\bin\dcc32.exe $** -BRCC = $(ROOT)\bin\brcc32.exe $** -#------------------------------------------------------------------------------ -PROJECTS = TntUnicodeVcl_R60.bpl TntUnicodeVcl_D60.bpl -#------------------------------------------------------------------------------ -default: $(PROJECTS) -#------------------------------------------------------------------------------ - -TntUnicodeVcl_R60.bpl: TntUnicodeVcl_R60.dpk - $(DCC) - -TntUnicodeVcl_D60.bpl: TntUnicodeVcl_D60.dpk - $(DCC) - - diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70.cfg b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70.cfg deleted file mode 100644 index a0119e529..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70.cfg +++ /dev/null @@ -1,34 +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 --LE"c:\program files (x86)\borland\delphi7\Projects\Bpl" --LN"c:\program files (x86)\borland\delphi7\Projects\Bpl" diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70.dof b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70.dof deleted file mode 100644 index 67603dc8d..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70.dof +++ /dev/null @@ -1,136 +0,0 @@ -[FileVersion] -Version=7.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=1 -R=1 -S=0 -T=1 -U=0 -V=1 -W=0 -X=1 -Y=1 -Z=1 -ShowHints=1 -ShowWarnings=1 -UnitAliases= -NamespacePrefix= -SymbolDeprecated=1 -SymbolLibrary=1 -SymbolPlatform=1 -UnitLibrary=1 -UnitPlatform=1 -UnitDeprecated=1 -HResultCompat=1 -HidingMember=1 -HiddenVirtual=1 -Garbage=1 -BoundsError=1 -ZeroNilCompat=1 -StringConstTruncated=1 -ForLoopVarVarPar=1 -TypedConstVarPar=1 -AsgToTypedConst=1 -CaseLabelRange=1 -ForVariable=1 -ConstructingAbstract=1 -ComparisonFalse=1 -ComparisonTrue=1 -ComparingSignedUnsigned=1 -CombiningSignedUnsigned=1 -UnsupportedConstruct=1 -FileOpen=1 -FileOpenUnitSrc=1 -BadGlobalSymbol=1 -DuplicateConstructorDestructor=1 -InvalidDirective=1 -PackageNoLink=1 -PackageThreadVar=1 -ImplicitImport=1 -HPPEMITIgnored=1 -NoRetVal=1 -UseBeforeDef=1 -ForLoopVarUndef=1 -UnitNameMismatch=1 -NoCFGFileFound=1 -MessageDirective=1 -ImplicitVariants=1 -UnicodeToLocale=1 -LocaleToUnicode=1 -ImagebaseMultiple=1 -SuspiciousTypecast=1 -PrivatePropAccessor=1 -UnsafeType=1 -UnsafeCode=1 -UnsafeCast=1 -[Linker] -MapFile=0 -OutputObjs=0 -ConsoleApp=1 -DebugInfo=0 -RemoteSymbols=0 -MinStackSize=16384 -MaxStackSize=1048576 -ImageBase=4194304 -ExeDescription=Tnt Unicode Controls -[Directories] -OutputDir= -UnitOutputDir= -PackageDLLOutputDir= -PackageDCPOutputDir= -SearchPath= -Packages= -Conditionals= -DebugSourceDirs= -UsePackages=0 -[Parameters] -RunParams= -HostApplication= -Launcher= -UseLauncher=0 -DebugCWD= -[Language] -ActiveLang= -ProjectLang= -RootDir= -[Version Info] -IncludeVerInfo=1 -AutoIncBuild=0 -MajorVer=2 -MinorVer=3 -Release=0 -Build=1 -Debug=0 -PreRelease=0 -Special=0 -Private=0 -DLL=0 -Locale=1033 -CodePage=1252 -[Version Info Keys] -CompanyName= -FileDescription= -FileVersion=2.3.0.1 -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename= -ProductName= -ProductVersion=2.3.0.1 -Comments= diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70.dpk b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70.dpk deleted file mode 100644 index 10771e3ff..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70.dpk +++ /dev/null @@ -1,56 +0,0 @@ -package TntUnicodeVcl_D70; - -{$R *.res} -{$R '..\..\Design\TntComCtrls.dcr'} -{$R '..\..\Design\TntDBCtrls.dcr'} -{$R '..\..\Design\TntStdCtrls.dcr'} -{$R '..\..\Design\TntActnList.dcr'} -{$R '..\..\Design\TntMenus.dcr'} -{$R '..\..\Design\TntExtCtrls.dcr'} -{$R '..\..\Design\TntForms.dcr'} -{$R '..\..\Design\TntGrids.dcr'} -{$R '..\..\Design\TntButtons.dcr'} -{$R '..\..\Design\TntDialogs.dcr'} -{$R '..\..\Design\TntExtDlgs.dcr'} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$OVERFLOWCHECKS ON} -{$RANGECHECKS ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS ON} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Tnt Unicode Controls'} -{$DESIGNONLY} -{$IMPLICITBUILD ON} - -requires - dcldb, - designide, - TntUnicodeVcl_R70; - -contains - TntForms_Design in '..\..\Design\TntForms_Design.pas', - TntComCtrls_Design in '..\..\Design\TntComCtrls_Design.pas', - TntDBGrids_Design in '..\..\Design\TntDBGrids_Design.pas', - TntDesignEditors_Design in '..\..\Design\TntDesignEditors_Design.pas', - TntWideStringProperty_Design in '..\..\Design\TntWideStringProperty_Design.pas', - TntMenus_Design in '..\..\Design\TntMenus_Design.pas', - TntStrEdit_Design in '..\..\Design\TntStrEdit_Design.pas', - TntUnicodeVcl_Register in '..\..\Design\TntUnicodeVcl_Register.pas', - TntActions_Design in '..\..\Design\TntActions_Design.pas'; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70_DATASNAP.cfg b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70_DATASNAP.cfg deleted file mode 100644 index d31bd60be..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70_DATASNAP.cfg +++ /dev/null @@ -1,35 +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 --w-UNSAFE_TYPE --w-UNSAFE_CODE --w-UNSAFE_CAST diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70_DATASNAP.dof b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70_DATASNAP.dof deleted file mode 100644 index aa71dcbde..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70_DATASNAP.dof +++ /dev/null @@ -1,136 +0,0 @@ -[FileVersion] -Version=7.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=1 -R=1 -S=0 -T=1 -U=0 -V=1 -W=0 -X=1 -Y=1 -Z=1 -ShowHints=1 -ShowWarnings=1 -UnitAliases= -NamespacePrefix= -SymbolDeprecated=1 -SymbolLibrary=1 -SymbolPlatform=1 -UnitLibrary=1 -UnitPlatform=1 -UnitDeprecated=1 -HResultCompat=1 -HidingMember=1 -HiddenVirtual=1 -Garbage=1 -BoundsError=1 -ZeroNilCompat=1 -StringConstTruncated=1 -ForLoopVarVarPar=1 -TypedConstVarPar=1 -AsgToTypedConst=1 -CaseLabelRange=1 -ForVariable=1 -ConstructingAbstract=1 -ComparisonFalse=1 -ComparisonTrue=1 -ComparingSignedUnsigned=1 -CombiningSignedUnsigned=1 -UnsupportedConstruct=1 -FileOpen=1 -FileOpenUnitSrc=1 -BadGlobalSymbol=1 -DuplicateConstructorDestructor=1 -InvalidDirective=1 -PackageNoLink=1 -PackageThreadVar=1 -ImplicitImport=1 -HPPEMITIgnored=1 -NoRetVal=1 -UseBeforeDef=1 -ForLoopVarUndef=1 -UnitNameMismatch=1 -NoCFGFileFound=1 -MessageDirective=1 -ImplicitVariants=1 -UnicodeToLocale=1 -LocaleToUnicode=1 -ImagebaseMultiple=1 -SuspiciousTypecast=1 -PrivatePropAccessor=1 -UnsafeType=0 -UnsafeCode=0 -UnsafeCast=0 -[Linker] -MapFile=0 -OutputObjs=0 -ConsoleApp=1 -DebugInfo=0 -RemoteSymbols=0 -MinStackSize=16384 -MaxStackSize=1048576 -ImageBase=4194304 -ExeDescription=Tnt Unicode Controls -[Directories] -OutputDir= -UnitOutputDir= -PackageDLLOutputDir= -PackageDCPOutputDir= -SearchPath= -Packages= -Conditionals= -DebugSourceDirs= -UsePackages=0 -[Parameters] -RunParams= -HostApplication= -Launcher= -UseLauncher=0 -DebugCWD= -[Language] -ActiveLang= -ProjectLang= -RootDir=C:\dev\library\TntUnicodeVcl\Packages\ -[Version Info] -IncludeVerInfo=1 -AutoIncBuild=0 -MajorVer=2 -MinorVer=3 -Release=0 -Build=1 -Debug=0 -PreRelease=0 -Special=0 -Private=0 -DLL=0 -Locale=1033 -CodePage=1252 -[Version Info Keys] -CompanyName= -FileDescription= -FileVersion=2.3.0.1 -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename= -ProductName= -ProductVersion=2.3.0.1 -Comments= diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70_DATASNAP.dpk b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70_DATASNAP.dpk deleted file mode 100644 index b29faa5ec..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_D70_DATASNAP.dpk +++ /dev/null @@ -1,37 +0,0 @@ -package TntUnicodeVcl_D70_DATASNAP; - -{$R *.res} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$OVERFLOWCHECKS ON} -{$RANGECHECKS ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS ON} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Tnt Unicode Controls'} -{$DESIGNONLY} -{$IMPLICITBUILD ON} - -requires - dclmid, - TntUnicodeVcl_D70; - -contains - TntDBClientActns in '..\..\TntDBClientActns.pas', - TntDBClientActns_Design in '..\..\Design\TntDBClientActns_Design.pas'; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_R70.cfg b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_R70.cfg deleted file mode 100644 index 78a35d3de..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_R70.cfg +++ /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/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_R70.dof b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_R70.dof deleted file mode 100644 index 4c08da963..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_R70.dof +++ /dev/null @@ -1,87 +0,0 @@ -[FileVersion] -Version=6.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=1 -R=1 -S=0 -T=1 -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=Tnt Unicode Controls - Runtime -[Directories] -OutputDir= -UnitOutputDir= -PackageDLLOutputDir= -PackageDCPOutputDir= -SearchPath= -Packages= -Conditionals= -DebugSourceDirs= -UsePackages=0 -[Parameters] -RunParams= -HostApplication= -Launcher= -UseLauncher=0 -DebugCWD= -[Language] -ActiveLang= -ProjectLang= -RootDir= -[Version Info] -IncludeVerInfo=1 -AutoIncBuild=0 -MajorVer=2 -MinorVer=3 -Release=0 -Build=1 -Debug=0 -PreRelease=0 -Special=0 -Private=0 -DLL=0 -Locale=1033 -CodePage=1252 -[Version Info Keys] -CompanyName= -FileDescription= -FileVersion=2.3.0.1 -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename= -ProductName= -ProductVersion=2.3.0.1 -Comments= diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_R70.dpk b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_R70.dpk deleted file mode 100644 index e17355c68..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicodeVcl_R70.dpk +++ /dev/null @@ -1,72 +0,0 @@ -package TntUnicodeVcl_R70; - -{$R *.res} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$OVERFLOWCHECKS ON} -{$RANGECHECKS ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS ON} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Tnt Unicode Controls - Runtime'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - vcl, - vclx, - vcldb, - dsnap, - vclactnband; - -contains - ActiveIMM_TLB in '..\..\Source\ActiveIMM_TLB.pas', - TntSystem in '..\..\Source\TntSystem.pas', - TntAxCtrls in '..\..\Source\TntAxCtrls.pas', - TntClipbrd in '..\..\Source\TntClipbrd.pas', - TntWindows in '..\..\Source\TntWindows.pas', - TntSysUtils in '..\..\Source\TntSysUtils.pas', - TntClasses in '..\..\Source\TntClasses.pas', - TntDialogs in '..\..\Source\TntDialogs.pas', - TntFileCtrl in '..\..\Source\TntFileCtrl.pas', - TntExtDlgs in '..\..\Source\TntExtDlgs.pas', - TntRegistry in '..\..\Source\TntRegistry.pas', - TntGraphics in '..\..\Source\TntGraphics.pas', - TntControls in '..\..\Source\TntControls.pas', - TntActnList in '..\..\Source\TntActnList.pas', - TntMenus in '..\..\Source\TntMenus.pas', - TntForms in '..\..\Source\TntForms.pas', - TntStdCtrls in '..\..\Source\TntStdCtrls.pas', - TntExtCtrls in '..\..\Source\TntExtCtrls.pas', - TntButtons in '..\..\Source\TntButtons.pas', - TntCheckLst in '..\..\Source\TntCheckLst.pas', - TntGrids in '..\..\Source\TntGrids.pas', - TntComCtrls in '..\..\Source\TntComCtrls.pas', - TntDB in '..\..\Source\TntDB.pas', - TntDBCtrls in '..\..\Source\TntDBCtrls.pas', - TntDBGrids in '..\..\Source\TntDBGrids.pas', - TntStdActns in '..\..\Source\TntStdActns.pas', - TntExtActns in '..\..\Source\TntExtActns.pas', - TntListActns in '..\..\Source\TntListActns.pas', - TntDBActns in '..\..\Source\TntDBActns.pas', - TntBandActn in '..\..\Source\TntBandActn.pas', - TntDBLogDlg in '..\..\Source\TntDBLogDlg.pas', - TntFormatStrUtils in '..\..\Source\TntFormatStrUtils.pas', - TntWideStrings in '..\..\Source\TntWideStrings.pas', - TntWideStrUtils in '..\..\Source\TntWideStrUtils.pas'; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicode_7.bpg b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicode_7.bpg deleted file mode 100644 index 387c423aa..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d7/TntUnicode_7.bpg +++ /dev/null @@ -1,23 +0,0 @@ -#------------------------------------------------------------------------------ -VERSION = BWS.01 -#------------------------------------------------------------------------------ -!ifndef ROOT -ROOT = $(MAKEDIR)\.. -!endif -#------------------------------------------------------------------------------ -MAKE = $(ROOT)\bin\make.exe -$(MAKEFLAGS) -f$** -DCC = $(ROOT)\bin\dcc32.exe $** -BRCC = $(ROOT)\bin\brcc32.exe $** -#------------------------------------------------------------------------------ -PROJECTS = TntUnicodeVcl_R70.bpl TntUnicodeVcl_D70.bpl -#------------------------------------------------------------------------------ -default: $(PROJECTS) -#------------------------------------------------------------------------------ - -TntUnicodeVcl_R70.bpl: TntUnicodeVcl_R70.dpk - $(DCC) - -TntUnicodeVcl_D70.bpl: TntUnicodeVcl_D70.dpk - $(DCC) - - diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_D90.bdsproj b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_D90.bdsproj deleted file mode 100644 index fbeceaa76..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_D90.bdsproj +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - - - - - - - TntUnicodeVcl_D90.dpk - - - 7.0 - - - 8 - 0 - 1 - 1 - 0 - 0 - 1 - 1 - 1 - 0 - 0 - 1 - 0 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 0 - 1 - 0 - 1 - 1 - 1 - True - True - - - 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 - True - True - True - True - True - True - True - False - False - False - True - True - True - - - 0 - 0 - 1 - False - False - False - 16384 - 1048576 - 4194304 - Tnt Unicode Controls - - - - - - - - - - - False - - - - - - False - - - - - - False - - - - $00000000 - - - - True - False - 2 - 3 - 0 - 1 - False - False - False - False - False - 1033 - 1252 - - - - - 2.3.0.1 - - - - - - 2.3.0.1 - - - diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_D90.cfg b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_D90.cfg deleted file mode 100644 index d31bd60be..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_D90.cfg +++ /dev/null @@ -1,35 +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 --w-UNSAFE_TYPE --w-UNSAFE_CODE --w-UNSAFE_CAST diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_D90.dpk b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_D90.dpk deleted file mode 100644 index 75a5c1d9f..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_D90.dpk +++ /dev/null @@ -1,55 +0,0 @@ -package TntUnicodeVcl_D90; - -{$R *.res} -{$R '..\..\Design\TntComCtrls.dcr'} -{$R '..\..\Design\TntDBCtrls.dcr'} -{$R '..\..\Design\TntStdCtrls.dcr'} -{$R '..\..\Design\TntActnList.dcr'} -{$R '..\..\Design\TntMenus.dcr'} -{$R '..\..\Design\TntExtCtrls.dcr'} -{$R '..\..\Design\TntForms.dcr'} -{$R '..\..\Design\TntGrids.dcr'} -{$R '..\..\Design\TntButtons.dcr'} -{$R '..\..\Design\TntDialogs.dcr'} -{$R '..\..\Design\TntExtDlgs.dcr'} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$OVERFLOWCHECKS ON} -{$RANGECHECKS ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS ON} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Tnt Unicode Controls'} -{$DESIGNONLY} -{$IMPLICITBUILD ON} - -requires - dcldb, - designide, - TntUnicodeVcl_R90; - -contains - TntForms_Design in '..\..\Design\TntForms_Design.pas', - TntComCtrls_Design in '..\..\Design\TntComCtrls_Design.pas', - TntDBGrids_Design in '..\..\Design\TntDBGrids_Design.pas', - TntDesignEditors_Design in '..\..\Design\TntDesignEditors_Design.pas', - TntStrEdit_Design in '..\..\Design\TntStrEdit_Design.pas', - TntUnicodeVcl_Register in '..\..\Design\TntUnicodeVcl_Register.pas', - TntActions_Design in '..\..\Design\TntActions_Design.pas', - TntMenus_Design in '..\..\Design\TntMenus_Design.pas'; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_R90.bdsproj b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_R90.bdsproj deleted file mode 100644 index 0e96a82b2..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_R90.bdsproj +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - - - - - - - TntUnicodeVcl_R90.dpk - - - 7.0 - - - 8 - 0 - 1 - 1 - 0 - 0 - 1 - 1 - 1 - 0 - 0 - 1 - 0 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 0 - 1 - 0 - 1 - 1 - 1 - True - True - - - 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 - True - True - True - True - True - True - True - True - True - True - True - True - True - - - 0 - 0 - 1 - False - False - False - 16384 - 1048576 - 4194304 - Tnt Unicode Controls - Runtime - - - - - - - - - - - False - - - - - - False - - - - - - False - - - - $00000000 - - - - True - False - 2 - 3 - 0 - 1 - False - False - False - False - False - 1033 - 1252 - - - - - 2.3.0.1 - - - - - - 2.3.0.1 - - - diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_R90.cfg b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_R90.cfg deleted file mode 100644 index 78a35d3de..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_R90.cfg +++ /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/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_R90.dpk b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_R90.dpk deleted file mode 100644 index 3aabc494f..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Delphi/d9/TntUnicodeVcl_R90.dpk +++ /dev/null @@ -1,72 +0,0 @@ -package TntUnicodeVcl_R90; - -{$R *.res} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$OVERFLOWCHECKS ON} -{$RANGECHECKS ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS ON} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Tnt Unicode Controls - Runtime'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - vcl, - vclx, - vcldb, - dsnap, - vclactnband; - -contains - ActiveIMM_TLB in '..\..\Source\ActiveIMM_TLB.pas', - TntSystem in '..\..\Source\TntSystem.pas', - TntAxCtrls in '..\..\Source\TntAxCtrls.pas', - TntClipbrd in '..\..\Source\TntClipbrd.pas', - TntWindows in '..\..\Source\TntWindows.pas', - TntSysUtils in '..\..\Source\TntSysUtils.pas', - TntClasses in '..\..\Source\TntClasses.pas', - TntDialogs in '..\..\Source\TntDialogs.pas', - TntFileCtrl in '..\..\Source\TntFileCtrl.pas', - TntExtDlgs in '..\..\Source\TntExtDlgs.pas', - TntRegistry in '..\..\Source\TntRegistry.pas', - TntGraphics in '..\..\Source\TntGraphics.pas', - TntControls in '..\..\Source\TntControls.pas', - TntActnList in '..\..\Source\TntActnList.pas', - TntMenus in '..\..\Source\TntMenus.pas', - TntForms in '..\..\Source\TntForms.pas', - TntStdCtrls in '..\..\Source\TntStdCtrls.pas', - TntExtCtrls in '..\..\Source\TntExtCtrls.pas', - TntButtons in '..\..\Source\TntButtons.pas', - TntCheckLst in '..\..\Source\TntCheckLst.pas', - TntGrids in '..\..\Source\TntGrids.pas', - TntComCtrls in '..\..\Source\TntComCtrls.pas', - TntDB in '..\..\Source\TntDB.pas', - TntDBCtrls in '..\..\Source\TntDBCtrls.pas', - TntDBGrids in '..\..\Source\TntDBGrids.pas', - TntStdActns in '..\..\Source\TntStdActns.pas', - TntExtActns in '..\..\Source\TntExtActns.pas', - TntListActns in '..\..\Source\TntListActns.pas', - TntDBActns in '..\..\Source\TntDBActns.pas', - TntBandActn in '..\..\Source\TntBandActn.pas', - TntDBLogDlg in '..\..\Source\TntDBLogDlg.pas', - TntFormatStrUtils in '..\..\Source\TntFormatStrUtils.pas', - TntWideStrings in '..\..\Source\TntWideStrings.pas', - TntWideStrUtils in '..\..\Source\TntWideStrUtils.pas'; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntActions_Design.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntActions_Design.pas deleted file mode 100644 index 7b1dea8a4..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntActions_Design.pas +++ /dev/null @@ -1,183 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntActions_Design; - -{$INCLUDE ..\Source\TntCompilers.inc} - -interface - -procedure Register; - -implementation - -uses - Classes, ActnList, TntActnList, StdActns, TntStdActns, - ExtActns, TntExtActns, ListActns, TntListActns, BandActn, TntBandActn, - DBActns, TntDBActns, TntDesignEditors_Design; - -procedure Register; -begin - RegisterClass(TTntAction); - // StdActns - RegisterClass(TTntEditAction); - RegisterClass(TTntEditCut); - RegisterClass(TTntEditCopy); - RegisterClass(TTntEditPaste); - RegisterClass(TTntEditSelectAll); - RegisterClass(TTntEditUndo); - RegisterClass(TTntEditDelete); - RegisterClass(TTntWindowAction); - RegisterClass(TTntWindowClose); - RegisterClass(TTntWindowCascade); - RegisterClass(TTntWindowTileHorizontal); - RegisterClass(TTntWindowTileVertical); - RegisterClass(TTntWindowMinimizeAll); - RegisterClass(TTntWindowArrange); - RegisterClass(TTntHelpAction); - RegisterClass(TTntHelpContents); - RegisterClass(TTntHelpTopicSearch); - RegisterClass(TTntHelpOnHelp); - RegisterClass(TTntHelpContextAction); - RegisterClass(TTntFileOpen); - RegisterClass(TTntFileOpenWith); - RegisterClass(TTntFileSaveAs); - RegisterClass(TTntFilePrintSetup); - RegisterClass(TTntFileExit); - RegisterClass(TTntSearchFind); - RegisterClass(TTntSearchReplace); - RegisterClass(TTntSearchFindFirst); - RegisterClass(TTntSearchFindNext); - RegisterClass(TTntFontEdit); - RegisterClass(TTntColorSelect); - RegisterClass(TTntPrintDlg); - // ExtActns - RegisterClass(TTntFileRun); - RegisterClass(TTntRichEditAction); - RegisterClass(TTntRichEditBold); - RegisterClass(TTntRichEditItalic); - RegisterClass(TTntRichEditUnderline); - RegisterClass(TTntRichEditStrikeOut); - RegisterClass(TTntRichEditBullets); - RegisterClass(TTntRichEditAlignLeft); - RegisterClass(TTntRichEditAlignRight); - RegisterClass(TTntRichEditAlignCenter); - RegisterClass(TTntPreviousTab); - RegisterClass(TTntNextTab); - RegisterClass(TTntOpenPicture); - RegisterClass(TTntSavePicture); - RegisterClass(TTntURLAction); - RegisterClass(TTntBrowseURL); - RegisterClass(TTntDownLoadURL); - RegisterClass(TTntSendMail); - RegisterClass(TTntListControlCopySelection); - RegisterClass(TTntListControlDeleteSelection); - RegisterClass(TTntListControlSelectAll); - RegisterClass(TTntListControlClearSelection); - RegisterClass(TTntListControlMoveSelection); - // ListActns - RegisterClass(TTntStaticListAction); - RegisterClass(TTntVirtualListAction); - {$IFDEF COMPILER_7_UP} - RegisterClass(TTntFilePageSetup); - {$ENDIF} - // DBActns - RegisterClass(TTntDataSetAction); - RegisterClass(TTntDataSetFirst); - RegisterClass(TTntDataSetPrior); - RegisterClass(TTntDataSetNext); - RegisterClass(TTntDataSetLast); - RegisterClass(TTntDataSetInsert); - RegisterClass(TTntDataSetDelete); - RegisterClass(TTntDataSetEdit); - RegisterClass(TTntDataSetPost); - RegisterClass(TTntDataSetCancel); - RegisterClass(TTntDataSetRefresh); - // BandActn - RegisterClass(TTntCustomizeActionBars); -end; - -//------------------------ - -function GetTntActionClass(OldActionClass: TContainedActionClass): TContainedActionClass; -begin - Result := TContainedActionClass(GetClass('TTnt' + Copy(OldActionClass.ClassName, 2, Length(OldActionClass.ClassName)))); -end; - -type - TAccessContainedAction = class(TContainedAction); - -function UpgradeAction(ActionList: TTntActionList; OldAction: TContainedAction): TContainedAction; -var - Name: TComponentName; - i: integer; - NewActionClass: TContainedActionClass; -begin - Result := nil; - if (OldAction = nil) or (OldAction.Owner = nil) or (OldAction.Name = '') then - Exit; - - NewActionClass := GetTntActionClass(TContainedActionClass(OldAction.ClassType)); - if NewActionClass <> nil then begin - // create new action - Result := NewActionClass.Create(OldAction.Owner) as TContainedAction; - Include(TAccessContainedAction(Result).FComponentStyle, csTransient); - // copy base class info - Result.ActionComponent := OldAction.ActionComponent; - Result.Category := OldAction.Category; { Assign Category before ActionList/Index to avoid flicker. } - Result.ActionList := ActionList; - Result.Index := OldAction.Index; - // assign props - Result.Assign(OldAction); - // point all links to this new action - for i := TAccessContainedAction(OldAction).FClients.Count - 1 downto 0 do - TBasicActionLink(TAccessContainedAction(OldAction).FClients[i]).Action := Result; - // free old object, preserve name... - Name := OldAction.Name; - OldAction.Free; - Result.Name := Name; { link up to old name } - Exclude(TAccessContainedAction(Result).FComponentStyle, csTransient); - end; -end; - -procedure TntActionList_UpgradeActionListItems(ActionList: TTntActionList); -var - DesignerNotify: IDesignerNotify; - Designer: ITntDesigner; - TntSelections: TTntDesignerSelections; - i: integer; - OldAction, NewAction: TContainedAction; -begin - DesignerNotify := FindRootDesigner(ActionList); - if (DesignerNotify <> nil) then begin - DesignerNotify.QueryInterface(ITntDesigner, Designer); - if (Designer <> nil) then begin - TntSelections := TTntDesignerSelections.Create; - try - Designer.GetSelections(TntSelections); - for i := ActionList.ActionCount - 1 downto 0 do begin - OldAction := ActionList.Actions[i]; - NewAction := UpgradeAction(ActionList, OldAction); - if (NewAction <> nil) then - TntSelections.ReplaceSelection(OldAction, NewAction); - end; - Designer.SetSelections(TntSelections); - finally - TntSelections.Free; - end; - end; - end; -end; - -initialization - UpgradeActionListItemsProc := TntActionList_UpgradeActionListItems; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntActnList.dcr b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntActnList.dcr deleted file mode 100644 index f585e26a0a7a52823bd3c1785f06a835c5433ca5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 484 zcmZvXu};J=42J(hNMySkZ@iI*U;xnpBm@II$Zds*Y_W7hMuxlu8?CbRkup@GoB7?e zNJzM~{pF8iCjfAut5zreG1&lDR8-IK!tarOgImUXJaP5F{LIyAyWReL1l&1Nr#H=2r^hY~l|&3Y2clGtOlGQ4FXEJH`E$4vBZy~WXx8(zD_c_+vBPl?lf zkl%HE;xo~Q?%8hy#~dNJRNHLH@h;?Aa=g{sx0oo{#RoE(qE$k%ifE|%Ok-uW4e z_cfg2ipousqIMT%|3bTbE-~%O5yiACSWUZX`~QPdJ4vSmOuM$+m1)tn*SRhLLDt1dr;sgwS_e*rNbRf_-s diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntComCtrls.dcr b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntComCtrls.dcr deleted file mode 100644 index 9f1b07fa379f45afc99f08e89dd13902c9b84210..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6776 zcmds+&uSb;5XRe)L7jtHAAR)EN5cjpNWfOSLJs~TVXYJL7JD$v__TBD4hhULF*@WG z0yYJ8zi;;D&t}*B58fWk?7!{qtAEk92d{TK|J~h#>|Y);Me(sUuOruaF)(c#TNO6 zvo~+pj0XHd`s0k+gI`EzSp!x|;^V;qdfrZV_`{x|Eil8eu7KaSxc~Y1+ji@26Z9Ur zEs4h$*gwsEbX6JV`;izl%@{OIhFM24oaVk6fgzu7DPU-t3{8`v=>`l&V3;3OM~24vV;F{BO2#nw7#pt)gLf`?Fhqs4S7-pa(VzPoU)rRA8*P^^OBilD zM&2g28yF9Fz;hj1%jXh@);|{+nw<8btTa zp9C#W7K@{sRd>1llCf|IV(W;*C-2ewJY%qmUj7(^rZYe3?#!<&(VOJQ#HR;dgE687 z2guJf`PD7$7z-1|!jhVayV*A%1w*?b`q;p;^RNfMuMl4IW8q7;jakeVW}(k5tz6l8 zOum!F{8>rUWgexi0;IZI@*`3)wxyZO*f^dCU&tPvz0RJZ)ob%knj?8YZ>40QPU_e74S$laZwH~4UgYe$xIJgjxWHto7Ay$RYu-}$- z;*)C^lW~L_Ly`5xSnz3XRb5L=mf9DRTgCpS<{Cd{Ex9%ONNydsa7eY})~vb4w{cCz z#aD`eEaR(zP-q6ot=T>pfTcDKTRcM=aL64qJuRViEjyX`nLV}8$`yC#=RiU(85bWT zCWn~SY`CAg8b6mgsm&`VuGey&FNJZ4c|ME8VedGllC^d*|sq9iPjbw0C}V zl#Y)i4twy19qj(YbwtaYrU&QxyFRl8EyiI2kpGe?es*qu{+fNa zw`cc8erwv7jJ>@F3GcYllw;oBT5QqHbvXq;)p1IGS=ZqAP1fX>{dq>y>DaFHzb;yh zCTOcG#+Cj9jW=w&CZoOcx@*1&#@#~vuQGv`k1x_+SeAMEAA!vFvP diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntComCtrls_Design.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntComCtrls_Design.pas deleted file mode 100644 index 60fb5c5db..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntComCtrls_Design.pas +++ /dev/null @@ -1,228 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntComCtrls_Design; - -{$INCLUDE ..\Source\TntCompilers.inc} - -interface - -uses - DesignIntf, DesignMenus, DesignEditors, Classes, ComCtrls; - -type - IPrepareMenuItem = IMenuItem; - - TTntListViewEditor = class(TComponentEditor) - public - procedure ExecuteVerb(Index: Integer); override; - function GetVerb(Index: Integer): string{TNT-ALLOW string}; override; - function GetVerbCount: Integer; override; - end; - - TTntPageControlEditor = class(TDefaultEditor) - private - function PageControl: TPageControl{TNT-ALLOW TPageControl}; - public - procedure ExecuteVerb(Index: Integer); override; - function GetVerb(Index: Integer): string{TNT-ALLOW string}; override; - function GetVerbCount: Integer; override; - procedure PrepareItem(Index: Integer; const AItem: IPrepareMenuItem); override; - end; - - TTntStatusBarEditor = class(TComponentEditor) - public - procedure ExecuteVerb(Index: Integer); override; - function GetVerb(Index: Integer): string{TNT-ALLOW string}; override; - function GetVerbCount: Integer; override; - end; - - TTntToolBarEditor = class(TComponentEditor) - public - procedure ExecuteVerb(Index: Integer); override; - function GetVerb(Index: Integer): string{TNT-ALLOW string}; override; - function GetVerbCount: Integer; override; - end; - -procedure Register; - -implementation - -uses - SysUtils, DsnConst, TntComCtrls, TntDesignEditors_Design; - -procedure Register; -begin - RegisterComponentEditor(TTntListView, TTntListViewEditor); - RegisterComponentEditor(TTntPageControl, TTntPageControlEditor); - RegisterComponentEditor(TTntTabSheet, TTntPageControlEditor); - RegisterComponentEditor(TTntStatusBar, TTntStatusBarEditor); - RegisterComponentEditor(TTntToolBar, TTntToolBarEditor); - RegisterComponentEditor(TTntToolButton, TTntToolBarEditor); -end; - -{ TTntListViewEditor } - -function TTntListViewEditor.GetVerbCount: Integer; -begin - Result := 2; -end; - -function TTntListViewEditor.GetVerb(Index: Integer): string{TNT-ALLOW string}; -begin - case Index of - 0: Result := SListColumnsEditor; - 1: Result := SListItemsEditor; - end; -end; - -procedure TTntListViewEditor.ExecuteVerb(Index: Integer); -begin - case Index of - 0: EditPropertyWithDialog(Component, 'Columns', Designer); - 1: EditPropertyWithDialog(Component, 'Items', Designer); - end; -end; - -{ TTntPageControlEditor } - -function TTntPageControlEditor.PageControl: TPageControl{TNT-ALLOW TPageControl}; -begin - if Component is TTabSheet{TNT-ALLOW TTabSheet} then - Result := TTabSheet{TNT-ALLOW TTabSheet}(Component).PageControl - else - Result := Component as TPageControl{TNT-ALLOW TPageControl}; -end; - -function TTntPageControlEditor.GetVerbCount: Integer; -begin - Result := 4; -end; - -function TTntPageControlEditor.GetVerb(Index: Integer): string{TNT-ALLOW string}; -begin - case Index of - 0: Result := SNewPage; - 1: Result := SNextPage; - 2: Result := SPrevPage; - 3: Result := SDeletePage; - end; -end; - -procedure TTntPageControlEditor.PrepareItem(Index: Integer; const AItem: IPrepareMenuItem); -begin - AItem.Enabled := (Index <> 3) or (PageControl.PageCount > 0); -end; - -type TAccessPageControl = class(TPageControl{TNT-ALLOW TPageControl}); - -procedure TTntPageControlEditor.ExecuteVerb(Index: Integer); - - procedure CreateNewTabSheet; - var - NewTabsheet: TTntTabSheet; - begin - NewTabSheet := TTntTabSheet.Create(PageControl.Owner); - NewTabSheet.PageControl := Self.PageControl; - with NewTabSheet do begin - Name := Designer.UniqueName(ClassName); - Caption := Name; - Visible := True; - end; - PageControl.ActivePage := NewTabSheet; - end; - -begin - case Index of - 0: CreateNewTabSheet; - 1: PageControl.SelectNextPage(True, False); - 2: PageControl.SelectNextPage(False, False); - 3: if PageControl.ActivePage <> nil then - PageControl.ActivePage.Free; - end; -end; - -{ TTntStatusBarEditor } - -function TTntStatusBarEditor.GetVerbCount: Integer; -begin - Result := 1; -end; - -function TTntStatusBarEditor.GetVerb(Index: Integer): string{TNT-ALLOW string}; -begin - case Index of - 0: Result := SStatusBarPanelEdit; - end; -end; - -procedure TTntStatusBarEditor.ExecuteVerb(Index: Integer); -begin - case Index of - 0: EditPropertyWithDialog(Component, 'Panels', Designer); - end; -end; - -{ TTntToolBarEditor } - -procedure TTntToolBarEditor.ExecuteVerb(Index: Integer); -var - ToolBar: TTntToolBar; - ToolButton: TTntToolButton; - I, J: Integer; - NewName: WideString; -begin - Assert(Index in [0, 1]); - - if Component is TTntToolBar then - ToolBar := TTntToolBar(Component) - else if (Component is TTntToolButton) and (TTntToolButton(Component).Parent is TTntToolBar) then - ToolBar := TTntToolBar(TTntToolButton(Component).Parent) - else - Exit; - - ToolButton := TTntToolButton.Create(Component.Owner); - - I := 1; - repeat - NewName := 'TntToolButton' + IntToStr(I); - for J := 0 to ToolBar.ControlCount - 1 do - if WideSameText(ToolBar.Controls[J].Name, NewName) then - NewName := ''; - Inc(I); - until NewName <> ''; - ToolButton.Name := NewName; - - if Index = 1 then begin - ToolButton.Style := tbsSeparator; - ToolButton.Width := 8; - end; - - for I := 0 to ToolBar.ControlCount - 1 do - ToolButton.Left := ToolButton.Left + ToolBar.Controls[I].Width; - - ToolButton.Parent := ToolBar; -end; - -function TTntToolBarEditor.GetVerb(Index: Integer): string{TNT-ALLOW string}; -begin - case Index of - 0: Result := SNewToolButton; - 1: Result := SNewToolSeparator; - end; -end; - -function TTntToolBarEditor.GetVerbCount: Integer; -begin - Result := 2; -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntDBClientActns_Design.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntDBClientActns_Design.pas deleted file mode 100644 index c48e80568..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntDBClientActns_Design.pas +++ /dev/null @@ -1,36 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntDBClientActns_Design; - -{$INCLUDE ..\Source\TntCompilers.inc} - -interface - -uses - Classes; - -procedure Register; - -implementation - -uses - TntDBClientActns; - -procedure Register; -begin - // DBClientActns - RegisterClass(TTntClientDataSetApply); - RegisterClass(TTntClientDataSetRevert); - RegisterClass(TTntClientDataSetUndo); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntDBCtrls.dcr b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntDBCtrls.dcr deleted file mode 100644 index 8052106515c1341e4ac35879a24c0e0094dd6e0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3620 zcmdUyF>ljQ5XY}HQi2$qv13Q}AZ1|);EEztjH)8_V_0Iand||{Ph!Z3stkMuqzokT z(0-&0mijUs|GRrHKw35k;iZnxf8RU5yr1vhD-qE#4rV)G{?gn5(NieQ59k7)H#kyy zPA}+`PVoI2c1D+*KEvTrFJ3%`aTJaNGWi(s?r${_{;00)gm0KQYPz|(!3`OpoY+qI zwlOog&}te))4?;^b-$1sQ$|~rO%6Mkdo|8tt3EY*l`#21BYpD~t;nx5W{xK(-qT_s z{wreNer;!Bi@yA}6kYw>&oi|pj$eM56@|w4?QFIzs~p3k!Lprws;WX;>z0eMVvj+T z&b5oGa^5?!o%^9XXZrMxZc&P$JLl0&`u?o{o?%93%5U!&$~;MvpOOeSW9X7DO((|C zbjgmyn!gPHPcnRhu-kcff^2++oQ!RM^G{H^TG>@Hg}hRBnu@MgcA6@fT*<$j)2{0> zWtVrHb=Ni8toa8W-kGwKn6Q;y&RK?Ant$P0tp__zOPN8i3yD)8 zrT#X%mvjzxX+%f+%g%;qc{jj|J~ehO83CWo0>B=tXmUpIG-f0|XwKMqN z$-6-!)y-ANFE0 z?rQHc8jZ%`nTKLaVZ?Q`W!+Odta}?B=r%eSMqTnR>gj}%jm~sEm-vXI>t1{o7^=SJ zbq9v?G3wv?>WZayjvKz^FKZTt<6GbGdM&l{k?MTKEidP)^BSXW=cdaq;6u?vDSZ!} zr_8r_=1Ag8Q@inQikEF$m+RPM?{Z)Mogx3uu=9*hk30wtsqNjnK=#qb!8|4_;sUFy=e`F{Aksa*Fu1leB*lF*-#%=;Y+k2LCdZxRU zjARAO=pDU{7_kQKo+E0XHY<;KQ<+htP{&*;uWD|4&q{o3|KcjyWY<SzV;^wjETp?0XFrtjeYhwsUeikSca diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntDBGrids_Design.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntDBGrids_Design.pas deleted file mode 100644 index 34a6bce02..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntDBGrids_Design.pas +++ /dev/null @@ -1,58 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntDBGrids_Design; - -{$INCLUDE ..\Source\TntCompilers.inc} - -interface - -uses - DesignEditors, DesignIntf; - -type - TTntDBGridEditor = class(TComponentEditor) - public - procedure ExecuteVerb(Index: Integer); override; - function GetVerb(Index: Integer): string{TNT-ALLOW string}; override; - function GetVerbCount: Integer; override; - end; - -procedure Register; - -implementation - -uses - TntDBGrids, DsnDBCst, TntDesignEditors_Design; - -procedure Register; -begin - RegisterComponentEditor(TTntDBGrid, TTntDBGridEditor); -end; - -{ TTntDBGridEditor } - -function TTntDBGridEditor.GetVerbCount: Integer; -begin - Result := 1; -end; - -function TTntDBGridEditor.GetVerb(Index: Integer): string{TNT-ALLOW string}; -begin - Result := DsnDBCst.SDBGridColEditor; -end; - -procedure TTntDBGridEditor.ExecuteVerb(Index: Integer); -begin - EditPropertyWithDialog(Component, 'Columns', Designer); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntDesignEditors_Design.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntDesignEditors_Design.pas deleted file mode 100644 index b5e63db35..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntDesignEditors_Design.pas +++ /dev/null @@ -1,196 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntDesignEditors_Design; - -{$INCLUDE ..\Source\TntCompilers.inc} - -interface - -uses - Classes, Forms, TypInfo, DesignIntf, DesignEditors; - -type - ITntDesigner = IDesigner; - - TTntDesignerSelections = class(TInterfacedObject, IDesignerSelections) - private - FList: TList; - {$IFDEF COMPILER_9_UP} - function GetDesignObject(Index: Integer): IDesignObject; - {$ENDIF} - protected - function Add(const Item: TPersistent): Integer; - function Equals(const List: IDesignerSelections): Boolean; - function Get(Index: Integer): TPersistent; - function GetCount: Integer; - property Count: Integer read GetCount; - property Items[Index: Integer]: TPersistent read Get; default; - public - constructor Create; virtual; - destructor Destroy; override; - procedure ReplaceSelection(const OldInst, NewInst: TPersistent); - end; - -function GetObjectInspectorForm: TCustomForm; -procedure EditPropertyWithDialog(Component: TPersistent; const PropName: AnsiString; const Designer: ITntDesigner); - -implementation - -uses - SysUtils; - -{ TTntDesignerSelections } - -function TTntDesignerSelections.Add(const Item: TPersistent): Integer; -begin - Result := FList.Add(Item); -end; - -constructor TTntDesignerSelections.Create; -begin - inherited; - FList := TList.Create; -end; - -destructor TTntDesignerSelections.Destroy; -begin - FList.Free; - inherited; -end; - -function TTntDesignerSelections.Equals(const List: IDesignerSelections): Boolean; -var - I: Integer; -begin - Result := False; - if List.Count <> Count then Exit; - for I := 0 to Count - 1 do - begin - if Items[I] <> List[I] then Exit; - end; - Result := True; -end; - -function TTntDesignerSelections.Get(Index: Integer): TPersistent; -begin - Result := TPersistent(FList[Index]); -end; - -function TTntDesignerSelections.GetCount: Integer; -begin - Result := FList.Count; -end; - -{$IFDEF COMPILER_9_UP} -function TTntDesignerSelections.GetDesignObject(Index: Integer): IDesignObject; -begin - Result := nil; {TODO: Figure out what IDesignerSelections.GetDesignObject is all about. Must wait for more documentation!} -end; -{$ENDIF} - -procedure TTntDesignerSelections.ReplaceSelection(const OldInst, NewInst: TPersistent); -var - Idx: Integer; -begin - Idx := FList.IndexOf(OldInst); - if Idx <> -1 then - FList[Idx] := NewInst; -end; - -{//------------------------------ -// Helpful discovery routines to explore the components and classes inside the IDE... -// -procedure EnumerateComponents(Comp: TComponent); -var - i: integer; -begin - for i := Comp.ComponentCount - 1 downto 0 do - MessageBoxW(0, PWideChar(WideString(Comp.Components[i].Name + ': ' + Comp.Components[i].ClassName)), - PWideChar(WideString(Comp.Name)), 0); -end; - -procedure EnumerateClasses(Comp: TComponent); -var - AClass: TClass; -begin - AClass := Comp.ClassType; - repeat - MessageBoxW(0, PWideChar(WideString(AClass.ClassName)), - PWideChar(WideString(Comp.Name)), 0); - AClass := Aclass.ClassParent; - until AClass = nil; -end; -//------------------------------} - -//------------------------------ -function GetIdeMainForm: TCustomForm; -var - Comp: TComponent; -begin - Result := nil; - if Application <> nil then begin - Comp := Application.FindComponent('AppBuilder'); - if Comp is TCustomForm then - Result := TCustomForm(Comp); - end; -end; - -function GetObjectInspectorForm: TCustomForm; -var - Comp: TComponent; - IdeMainForm: TCustomForm; -begin - Result := nil; - IdeMainForm := GetIdeMainForm; - if IdeMainForm <> nil then begin - Comp := IdeMainForm.FindComponent('PropertyInspector'); - if Comp is TCustomForm then - Result := TCustomForm(Comp); - end; -end; - -{ TPropertyEditorWithDialog } -type - TPropertyEditorWithDialog = class - private - FPropName: AnsiString; - procedure CheckEditProperty(const Prop: IProperty); - procedure EditProperty(Component: TPersistent; const PropName: AnsiString; const Designer: ITntDesigner); - end; - -procedure TPropertyEditorWithDialog.CheckEditProperty(const Prop: IProperty); -begin - if Prop.GetName = FPropName then - Prop.Edit; -end; - -procedure TPropertyEditorWithDialog.EditProperty(Component: TPersistent; const PropName: AnsiString; const Designer: ITntDesigner); -var - Components: IDesignerSelections; -begin - FPropName := PropName; - Components := TDesignerSelections.Create; - Components.Add(Component); - GetComponentProperties(Components, [tkClass], Designer, CheckEditProperty); -end; - -procedure EditPropertyWithDialog(Component: TPersistent; const PropName: AnsiString; const Designer: ITntDesigner); -begin - with TPropertyEditorWithDialog.Create do - try - EditProperty(Component, PropName, Designer); - finally - Free; - end; -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntDialogs.dcr b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntDialogs.dcr deleted file mode 100644 index 3a953b0a1fde80b858799fc61ccf659d3268b262..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 936 zcmdUsu}Z^09LB#I(Llg-)UBhV&>@S95D`HdL2>pG1c&N&TLTUm9r6-|4mRA-K7bF= zC(sN<0)d|2|1JqA9bNpI|J~Q`E|-7u1Aqa`7+17El=gsACdTaGmcJ3}24}d#IbvMW zT_M3mcTc~6wA=nUra5e?2Nw@`-gYT~7nE`nM_QJ`a=GM!G$@mC6Gzvx!LZQ@yw(o6 za~N?D?T_I_nU#8)Ja|!6**s0@Gxh0zR4Nl+l^gN?MD{aJQ?){9^Lt=#gZWHyk)G&!9)EG=Q!>CYH`1I~y#1^@s6 diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntExtCtrls.dcr b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntExtCtrls.dcr deleted file mode 100644 index e6ba64957f82f6c3eea3bdd39bb4df0b59d07d5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3592 zcmds)L2DaF6vro(KwEl{k2xBhdK63`g#?^58{~i+1*a|j7z-Bc_OyEl%z&Xf_Mk6O z&><3gus=XPM2@{#hk^$Jo&NuCX0(=(a|}+OvpavieKVTTZ{M4VQc4}-@;+RUJ7ym! zHHOFgZ`9BDdyVTy^-}$c>m)`V96ao&PTxa3jMoDd+=m!rzcotXpK6-W;0}qaQJ0sO zc)&@q@u9&z%+o6ytx;K$7LiFegHmO4FSe;nk(pAgu(n7Ynt7*fX3#gplm*6|$B`=BHq${^%0sr zTJVco{E?NXKfY@MwWDVD<=b0z3~q1!cie2AA9Lx<;dgnS%g+FAkn(`sM1wE6iO!rO zH_^lSd=75Z&y;fH_72+n&79mY{?z+{YqRwVV-LMYhpeS8{HAg)lW%PNrr@hXGsA(j zavNryE|_f5nj~(v$hW7M=gm6#LQSP!o}xWL)qJi_w{Pm#kb5S)uXtNgKdH14`)T_Qu{T+Om(n0wR))s49)dSE5@M5{`2FK9eK?j=8SFU2$WL}MJ(Owk-4 zH8W{q+10+jW{CKCk2PVxY?@XX6q0odtKDz zmi!jnk|wvL$t`JeOPbu0X6_{|xfjQ8>#nb@k$cfE?VUOnN^W$KRe2--;##`~+io>r#nw|kj)Oe83TKtZ&2oGYes*ZGK_z)- z%WQRC;D=K0SJq|c7iLfiKR3KEv!WD!t}(NGG7)~x4p1fw;pc3@@+thBZSwq|T=+R_ z`cuDQ-tqj>-}Im5$UACw$Sb56v=r{+sBLbxeru1-B>53HgHHROmo$Vk+8%yyvEQA5 zAkUmHck1T1{RHz%oi%l|vFatMF^8nbIBTW{W1Lx_AD5-pWBgLkN7g{2ZYHh44}Hb2 z!7JpS{51@ z*7}T}gkk-7@QBHyhFV9zRu@ZXF<}_}!Z5~@;Wi!&xA9<@{A8$8JQ=3($uN$uDRwkx W^8$-F(z+ClMVw(SqQj)_xc>*fx-2^Y diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntExtDlgs.dcr b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntExtDlgs.dcr deleted file mode 100644 index 8f766ba8cbad6571d106c3baa7b0a7856cf9883f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 960 zcmdUsKTE?v7{;H9U?7Ba)UBgmqi9h$6UI5(xIzb~IKm#s zmpJ2SpQAR8(ZxZ%LbJKExms+O$#xwLSi8lw*Gm9=A%yMNGGz!%r&CVopVghR9b5bV z3iDd82v+HwmGgp))>aQekt8uCZu-|jvHUQ895YYEQwSyRb-t7)_xie?zEZLY&-ms8 zjKkLlR>RaGsr+tk#*(@)dP_=ATk%TwR^CBI$D&!N)F zxlZ41g^>F?1*@}gGAJZB)e2eDbGmbf|COxc*(J#i$^K)W303nn_atkc=Kd1H6C*9l z)At9IF!vgIX2S6FrS>h)Z~}NE%hUgg$~Rb^;Upr@%J8J`c+z(~Yv1xj diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntForms.dcr b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntForms.dcr deleted file mode 100644 index c4dbd69e1f3de14cc2dd352b03777d52fe163813..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 920 zcmd6ku};H442E4)iQCe#V@F0t#sYx}s00i=Mz*vQ-f|K{Muxlu8;Ne|Bi)$I{LYU)-QvhWo;%Mag!VK!+&B+YSAzv2mceY{#AI)rspCa!35_`w`-9x==dZfGD^Ivt#=U~;% zSaoai+^Sn+_YK{QBXnz|%2j>e$oo{Kx*4l(#;Tifgl@(Gx*4l(#zC~VnwRAo7aO!! gIY!a{*2yN$!zmL=U~8Q%PFQXVa4xUwZ9ZZOKU-~eyZ`_I diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntForms_Design.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntForms_Design.pas deleted file mode 100644 index 5a924bcb2..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntForms_Design.pas +++ /dev/null @@ -1,422 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntForms_Design; - -{$INCLUDE ..\Source\TntCompilers.inc} - -interface - -uses - Classes, Windows, DesignIntf, ToolsApi; - -type HICON = LongWord; - -type - TTntNewFormWizard = class(TNotifierObject, IOTAWizard, IOTARepositoryWizard, - IOTAFormWizard - {$IFDEF COMPILER_6_UP}, IOTARepositoryWizard60{$ENDIF} - {$IFDEF COMPILER_9_UP}, IOTARepositoryWizard80{$ENDIF}) - protected - function ThisFormName: WideString; - function ThisFormClass: TComponentClass; virtual; abstract; - function ThisFormUnit: WideString; - public - // IOTAWizard - function GetIDString: AnsiString; - function GetName: AnsiString; virtual; - function GetState: TWizardState; - procedure Execute; - // IOTARepositoryWizard - function GetAuthor: AnsiString; - function GetComment: AnsiString; virtual; abstract; - function GetPage: AnsiString; - function GetGlyph: HICON; - {$IFDEF COMPILER_6_UP} - // IOTARepositoryWizard60 - function GetDesigner: AnsiString; - {$ENDIF} - {$IFDEF COMPILER_9_UP} - // IOTARepositoryWizard80 - function GetGalleryCategory: IOTAGalleryCategory; - function GetPersonality: AnsiString; - {$ENDIF} - end; - -procedure Register; - -implementation - -uses - TntForms, DesignEditors, WCtlForm, TypInfo, SysUtils; - -type - TTntNewTntFormWizard = class(TTntNewFormWizard) - protected - function ThisFormClass: TComponentClass; override; - public - function GetName: AnsiString; override; - function GetComment: AnsiString; override; - end; - - TTntNewTntFrameWizard = class(TTntNewFormWizard) - protected - function ThisFormClass: TComponentClass; override; - public - function GetName: AnsiString; override; - function GetComment: AnsiString; override; - end; - - TTntFrameCustomModule = class(TWinControlCustomModule) - public - function Nestable: Boolean; override; - end; - - TTntFormCustomModule = class(TCustomModule) - public - class function DesignClass: TComponentClass; override; - end; - -procedure Register; -begin - RegisterCustomModule(TTntFrame, TTntFrameCustomModule); - RegisterPackageWizard(TTntNewTntFrameWizard.Create); - //-- - RegisterCustomModule(TTntForm, TTntFormCustomModule); - //-- - RegisterPackageWizard(TTntNewTntFormWizard.Create); -end; - -function GetFirstModuleSupporting(const IID: TGUID): IOTAModule; -var - ModuleServices: IOTAModuleServices; - i: integer; -begin - Result := nil; - if Assigned(BorlandIDEServices) then - begin - // look for the first project - ModuleServices := BorlandIDEServices as IOTAModuleServices; - for i := 0 to ModuleServices.ModuleCount - 1 do - if Supports(ModuleServices.Modules[i], IID, Result) then - Break; - end; -end; - -function MyGetActiveProject: IOTAProject; -{$IFDEF COMPILER_7_UP} -begin - Result := ToolsAPI.GetActiveProject; -{$ELSE} -var - ProjectGroup: IOTAProjectGroup; -begin - ProjectGroup := GetFirstModuleSupporting(IOTAProjectGroup) as IOTAProjectGroup; - if ProjectGroup = nil then - Result := nil - else - Result := ProjectGroup.ActiveProject; -{$ENDIF} - if (Result = nil) then - Result := GetFirstModuleSupporting(IOTAProject) as IOTAProject; -end; - -{ TTntNewFormCreator } -type - TTntNewFormCreator = class(TInterfacedObject, IOTACreator, IOTAModuleCreator) - private - FAncestorName: WideString; - FUnitName: WideString; - public - // IOTACreator - function GetCreatorType: AnsiString; - function GetExisting: Boolean; - function GetFileSystem: AnsiString; - function GetOwner: IOTAModule; - function GetUnnamed: Boolean; - // IOTAModuleCreator - function GetAncestorName: AnsiString; - function GetImplFileName: AnsiString; - function GetIntfFileName: AnsiString; - function GetFormName: AnsiString; - function GetMainForm: Boolean; - function GetShowForm: Boolean; - function GetShowSource: Boolean; - function NewFormFile(const FormIdent, AncestorIdent: AnsiString): IOTAFile; - function NewImplSource(const ModuleIdent, FormIdent, AncestorIdent: AnsiString): IOTAFile; - function NewIntfSource(const ModuleIdent, FormIdent, AncestorIdent: AnsiString): IOTAFile; - procedure FormCreated(const FormEditor: IOTAFormEditor); - public - constructor Create(const UnitName, AncestorName: WideString); - end; - - TTntSourceFile = class(TInterfacedObject, IOTAFile) - private - FSource: AnsiString; - public - function GetSource: AnsiString; - function GetAge: TDateTime; - constructor Create(const Source: AnsiString); - end; - -constructor TTntNewFormCreator.Create(const UnitName, AncestorName: WideString); -begin - inherited Create; - FUnitName := UnitName; - FAncestorName := AncestorName; -end; - -procedure TTntNewFormCreator.FormCreated(const FormEditor: IOTAFormEditor); -begin -end; - -function TTntNewFormCreator.GetAncestorName: AnsiString; -begin - Result := FAncestorName; -end; - -function TTntNewFormCreator.GetCreatorType: AnsiString; -begin - Result := sForm; -end; - -function TTntNewFormCreator.GetExisting: Boolean; -begin - Result := False; -end; - -function TTntNewFormCreator.GetFileSystem: AnsiString; -begin - Result := ''; -end; - -function TTntNewFormCreator.GetFormName: AnsiString; -begin - Result := ''; -end; - -function TTntNewFormCreator.GetImplFileName: AnsiString; -begin - Result := ''; -end; - -function TTntNewFormCreator.GetIntfFileName: AnsiString; -begin - Result := ''; -end; - -function TTntNewFormCreator.GetMainForm: Boolean; -begin - Result := False; -end; - -function TTntNewFormCreator.GetOwner: IOTAModule; -begin - Result := MyGetActiveProject; -end; - -function TTntNewFormCreator.GetShowForm: Boolean; -begin - Result := True; -end; - -function TTntNewFormCreator.GetShowSource: Boolean; -begin - Result := True; -end; - -function TTntNewFormCreator.GetUnnamed: Boolean; -begin - Result := True; -end; - -function TTntNewFormCreator.NewFormFile(const FormIdent, AncestorIdent: AnsiString): IOTAFile; -begin - Result := nil; -end; - -function TTntNewFormCreator.NewImplSource(const ModuleIdent, FormIdent, AncestorIdent: AnsiString): IOTAFile; -const - cSource = - 'unit %s;' + #13#10 + - '' + #13#10 + - 'interface' + #13#10 + - '' + #13#10 + - 'uses' + #13#10 + - ' Windows, Messages, SysUtils' + {$IFDEF COMPILER_6_UP}', Variants' + {$ENDIF} - ', Classes, Graphics, Controls, Forms,' + #13#10 + ' Dialogs, %s;' + #13#10 + - '' + #13#10 + - 'type' + #13#10 + - ' T%s = class(T%s)' + #13#10 + - ' private' + #13#10 + - ' { Private declarations }' + #13#10 + - ' public' + #13#10 + - ' { Public declarations }' + #13#10 + - ' end;' + #13#10 + - '' + #13#10 + - 'var' + #13#10 + - ' %s: T%s;' + #13#10 + - '' + #13#10 + - 'implementation' + #13#10 + - '' + #13#10 + - '{$R *.DFM}' + #13#10 + - '' + #13#10 + - 'end.'; -begin - Result := TTntSourceFile.Create(Format{TNT-ALLOW Format}(cSource, - [ModuleIdent, FUnitName, FormIdent, AncestorIdent, FormIdent, FormIdent])); -end; - -function TTntNewFormCreator.NewIntfSource(const ModuleIdent, FormIdent, AncestorIdent: AnsiString): IOTAFile; -begin - Result := nil; -end; - -{ TTntNewFormWizard } - -function TTntNewFormWizard.ThisFormName: WideString; -begin - Result := ThisFormClass.ClassName; - Delete(Result, 1, 1); // drop the 'T' -end; - -function TTntNewFormWizard.ThisFormUnit: WideString; -begin - Result := GetTypeData(ThisFormClass.ClassInfo).UnitName; -end; - -function TTntNewFormWizard.GetName: AnsiString; -begin - Result := ThisFormName; -end; - -function TTntNewFormWizard.GetAuthor: AnsiString; -begin - Result := 'Troy Wolbrink'; -end; - -function TTntNewFormWizard.GetPage: AnsiString; -begin - Result := 'New'; -end; - -function TTntNewFormWizard.GetGlyph: HICON; -begin - Result := 0; -end; - -function TTntNewFormWizard.GetState: TWizardState; -begin - Result := [wsEnabled]; -end; - -function TTntNewFormWizard.GetIDString: AnsiString; -begin - Result := 'Tnt.Create_'+ThisFormName+'.Wizard'; -end; - -procedure TTntNewFormWizard.Execute; -var - Module: IOTAModule; -begin - Module := (BorlandIDEServices as IOTAModuleServices).CreateModule(TTntNewFormCreator.Create(ThisFormUnit, ThisFormName)); -end; - -{$IFDEF COMPILER_6_UP} -function TTntNewFormWizard.GetDesigner: AnsiString; -begin - Result := dVCL; -end; -{$ENDIF} - -{$IFDEF COMPILER_9_UP} -function TTntNewFormWizard.GetGalleryCategory: IOTAGalleryCategory; -var - Manager: IOTAGalleryCategoryManager; -begin - Result := nil; - Manager := BorlandIDEServices as IOTAGalleryCategoryManager; - if Assigned(Manager) then - Result := Manager.FindCategory(sCategoryDelphiNew); -end; - -function TTntNewFormWizard.GetPersonality: AnsiString; -begin - Result := sDelphiPersonality; -end; -{$ENDIF} - -{ TTntSourceFile } - -constructor TTntSourceFile.Create(const Source: AnsiString); -begin - FSource := Source; -end; - -function TTntSourceFile.GetAge: TDateTime; -begin - Result := -1; -end; - -function TTntSourceFile.GetSource: AnsiString; -begin - Result := FSource; -end; - -{ TTntNewTntFormWizard } - -function TTntNewTntFormWizard.ThisFormClass: TComponentClass; -begin - Result := TTntForm; -end; - -function TTntNewTntFormWizard.GetName: AnsiString; -begin - Result := ThisFormName + ' (Unicode)' -end; - -function TTntNewTntFormWizard.GetComment: AnsiString; -begin - Result := 'Creates a new Unicode enabled TntForm'; -end; - -{ TTntNewTntFrameWizard } - -function TTntNewTntFrameWizard.ThisFormClass: TComponentClass; -begin - Result := TTntFrame; -end; - -function TTntNewTntFrameWizard.GetName: AnsiString; -begin - Result := ThisFormName + ' (Unicode)' -end; - -function TTntNewTntFrameWizard.GetComment: AnsiString; -begin - Result := 'Creates a new Unicode enabled TntFrame'; -end; - -{ TTntFrameCustomModule } - -function TTntFrameCustomModule.Nestable: Boolean; -begin - Result := True; -end; - -{ TTntFormCustomModule } - -class function TTntFormCustomModule.DesignClass: TComponentClass; -begin - Result := TTntForm; -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntGrids.dcr b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntGrids.dcr deleted file mode 100644 index 2297c342bc5d1447652a8162f238c599faee06ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 932 zcmdUtu};G<5QeX)QnR^Z$BsM#0|Q8wFiRr=60gxMFyWz6PwL>2Auqv3A}@WUjNOj^ zV!JIBFTgeD`~Bx^IsQsSv_y)eg!~meA-aJhaz!urt&oBb0re5H67%_DTJ$x< zBIksXy~JLBhbO{A-lu{Q66tBb-{XZIPK%_1F`ZY4b9kzXWONqoXU*}2f7`B0lV?^v zuJU2jQ+wx$s;#b79Rg-aQ+24Q>qcKph+nbQwPrXR`tKe-dl}XgKih8GG>w^I=-*qM zgA6jZZC@FY^@m6w+nq7C_SV*s`%e8JA~TMi`oUUg=9ABy{rb|^{WX%$9I#Gxa?|OR z-z|)De$Qa2j66yhN?3|d+8Te`md`@Vu%krGF1Nuge^8f diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntMenus.dcr b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntMenus.dcr deleted file mode 100644 index edc3deb49c7c9f8ad5509856ec18314e03d97cef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 928 zcmc(dzfQwI48~nliQDMdu_KSbSfpcMDCq$2(Vne< z+UJO}Jwvb4!9@5GbDl6lBAE_{0~YLXHff$P=JP5^A55W0L1oc=xfvFCTd#uDSVe0Q z(~3y^>iQTfO%iJC&AxcgIwIyGwBHxMd+!>lk1?XY{b;}aw+1@*k@gui-e0<=X@~l* zc^Q1c-i-&2)a_*#aR!U6$ga{VR>!C-=;D7$UvHbrGoGJM@LN(vOK@BMA^4B{Ks@x% z!A9CO3#Y=5!&P#ASmAV)oS$iY2+pt9&M#~92~b{>oZkwaRfF@}fqdbI_dC}ho$*^k vC+stRYt)S48$b9l25F6-^MG&s&<8E?FPUG~xE*}c#?NXHKYd3J)@R}i2|jdh diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntMenus_Design.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntMenus_Design.pas deleted file mode 100644 index c3102169c..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntMenus_Design.pas +++ /dev/null @@ -1,391 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntMenus_Design; - -{$INCLUDE ..\Source\TntCompilers.inc} - -{*******************************************************} -{ Special Thanks to Francisco Leong for getting these } -{ menu designer enhancements to work w/o MnuBuild. } -{*******************************************************} - -interface - -{$IFDEF COMPILER_6} // Delphi 6 and BCB 6 have MnuBuild available - {$DEFINE MNUBUILD_AVAILABLE} -{$ENDIF} - -{$IFDEF COMPILER_7} // Delphi 7 has MnuBuild available - {$DEFINE MNUBUILD_AVAILABLE} -{$ENDIF} - -uses - Windows, Classes, Menus, Messages, - {$IFDEF MNUBUILD_AVAILABLE} MnuBuild, {$ENDIF} - DesignEditors, DesignIntf; - -type - TTntMenuEditor = class(TComponentEditor) - public - procedure ExecuteVerb(Index: Integer); override; - function GetVerb(Index: Integer): string{TNT-ALLOW string}; override; - function GetVerbCount: Integer; override; - end; - -procedure Register; - -implementation - -uses - {$IFDEF MNUBUILD_AVAILABLE} MnuConst, {$ELSE} DesignWindows, {$ENDIF} SysUtils, Graphics, ActnList, - Controls, Forms, TntDesignEditors_Design, TntActnList, TntMenus; - -procedure Register; -begin - RegisterComponentEditor(TTntMainMenu, TTntMenuEditor); - RegisterComponentEditor(TTntPopupMenu, TTntMenuEditor); -end; - -function GetMenuBuilder: TForm{TNT-ALLOW TForm}; -{$IFDEF MNUBUILD_AVAILABLE} -begin - Result := MenuEditor; -{$ELSE} -var - Comp: TComponent; -begin - Result := nil; - if Application <> nil then - begin - Comp := Application.FindComponent('MenuBuilder'); - if Comp is TForm{TNT-ALLOW TForm} then - Result := TForm{TNT-ALLOW TForm}(Comp); - end; -{$ENDIF} -end; - -{$IFDEF DELPHI_9} // verified against Delphi 9 -type - THackMenuBuilder = class(TDesignWindow) - protected - Fields: array[1..26] of TObject; - FWorkMenu: TMenuItem{TNT-ALLOW TMenuItem}; - end; -{$ENDIF} - -{$IFDEF COMPILER_10_UP} -{$IFDEF DELPHI_10} // NOT verified against Delphi 10 -type - THackMenuBuilder = class(TDesignWindow) - protected - Fields: array[1..26] of TObject; - FWorkMenu: TMenuItem{TNT-ALLOW TMenuItem}; - end; -{$ENDIF} -{$ENDIF} - -function GetMenuBuilder_WorkMenu(MenuBuilder: TForm{TNT-ALLOW TForm}): TMenuItem{TNT-ALLOW TMenuItem}; -begin - if MenuBuilder = nil then - Result := nil - else begin - {$IFDEF MNUBUILD_AVAILABLE} - Result := MenuEditor.WorkMenu; - {$ELSE} - Result := THackMenuBuilder(MenuBuilder).FWorkMenu; - Assert((Result = nil) or (Result is TMenuItem{TNT-ALLOW TMenuItem}), - 'TNT Internal Error: THackMenuBuilder has incorrect internal layout.'); - {$ENDIF} - end; -end; - -{$IFDEF DELPHI_9} // verified against Delphi 9 -type - THackMenuItemWin = class(TCustomControl) - protected - FxxxxCaptionExtent: Integer; - FMenuItem: TMenuItem{TNT-ALLOW TMenuItem}; - end; -{$ENDIF} - -{$IFDEF DELPHI_10} // beta: NOT verified against Delphi 10 -type - THackMenuItemWin = class(TCustomControl) - protected - FxxxxCaptionExtent: Integer; - FMenuItem: TMenuItem{TNT-ALLOW TMenuItem}; - end; -{$ENDIF} - -function GetMenuItem(Control: TWinControl; DoVerify: Boolean = True): TMenuItem{TNT-ALLOW TMenuItem}; -begin - {$IFDEF MNUBUILD_AVAILABLE} - if Control is TMenuItemWin then - Result := TMenuItemWin(Control).MenuItem - {$ELSE} - if Control.ClassName = 'TMenuItemWin' then begin - Result := THackMenuItemWin(Control).FMenuItem; - Assert((Result = nil) or (Result is TMenuItem{TNT-ALLOW TMenuItem}), 'TNT Internal Error: Unexpected TMenuItem field layout.'); - end - {$ENDIF} - else if DoVerify then - raise Exception.Create('TNT Internal Error: Control is not a TMenuItemWin.') - else - Result := nil; -end; - -procedure SetMenuItem(Control: TWinControl; Item: TMenuItem{TNT-ALLOW TMenuItem}); -begin - {$IFDEF MNUBUILD_AVAILABLE} - if Control is TMenuItemWin then - TMenuItemWin(Control).MenuItem := Item - {$ELSE} - if Control.ClassName = 'TMenuItemWin' then begin - THackMenuItemWin(Control).FMenuItem := Item; - Item.FreeNotification(Control); - end - {$ENDIF} - else - raise Exception.Create('TNT Internal Error: Control is not a TMenuItemWin.'); -end; - -procedure ReplaceMenuItem(Control: TWinControl; ANewItem: TMenuItem{TNT-ALLOW TMenuItem}); -var - OldItem: TMenuItem{TNT-ALLOW TMenuItem}; - OldName: string{TNT-ALLOW string}; -begin - OldItem := GetMenuItem(Control, True); - Assert(OldItem <> nil); - OldName := OldItem.Name; - FreeAndNil(OldItem); - ANewItem.Name := OldName; { assume old name } - SetMenuItem(Control, ANewItem); -end; - -{ TTntMenuBuilderChecker } - -type - TMenuBuilderChecker = class(TComponent) - private - FMenuBuilder: TForm{TNT-ALLOW TForm}; - FCheckMenuAction: TTntAction; - FLastCaption: string{TNT-ALLOW string}; - FLastActiveControl: TControl; - FLastMenuItem: TMenuItem{TNT-ALLOW TMenuItem}; - procedure CheckMenuItems(Sender: TObject); - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - end; - -var MenuBuilderChecker: TMenuBuilderChecker = nil; - -constructor TMenuBuilderChecker.Create(AOwner: TComponent); -begin - inherited; - MenuBuilderChecker := Self; - FCheckMenuAction := TTntAction.Create(Self); - FCheckMenuAction.OnUpdate := CheckMenuItems; - FCheckMenuAction.OnExecute := CheckMenuItems; - FMenuBuilder := AOwner as TForm{TNT-ALLOW TForm}; - FMenuBuilder.Action := FCheckMenuAction; -end; - -destructor TMenuBuilderChecker.Destroy; -begin - FMenuBuilder := nil; - MenuBuilderChecker := nil; - inherited; -end; - -type TAccessTntMenuItem = class(TTntMenuItem); - -function CreateTntMenuItem(OldItem: TMenuItem{TNT-ALLOW TMenuItem}): TTntMenuItem; -var - OldName: AnsiString; - OldParent: TMenuItem{TNT-ALLOW TMenuItem}; - OldIndex: Integer; - OldItemsList: TList; - j: integer; -begin - // item should be converted. - OldItemsList := TList.Create; - try - // clone properties - Result := TTntMenuItem.Create(OldItem.Owner); - TAccessTntMenuItem(Result).FComponentStyle := OldItem.ComponentStyle; {csTransient hides item from object inspector} - Result.Action := OldItem.Action; - Result.AutoCheck := OldItem.AutoCheck; - Result.AutoHotkeys := OldItem.AutoHotkeys; - Result.AutoLineReduction := OldItem.AutoLineReduction; - Result.Bitmap := OldItem.Bitmap; - Result.Break := OldItem.Break; - Result.Caption := OldItem.Caption; - Result.Checked := OldItem.Checked; - Result.Default := OldItem.Default; - Result.Enabled := OldItem.Enabled; - Result.GroupIndex := OldItem.GroupIndex; - Result.HelpContext := OldItem.HelpContext; - Result.Hint := OldItem.Hint; - Result.ImageIndex := OldItem.ImageIndex; - Result.MenuIndex := OldItem.MenuIndex; - Result.RadioItem := OldItem.RadioItem; - Result.ShortCut := OldItem.ShortCut; - Result.SubMenuImages := OldItem.SubMenuImages; - Result.Visible := OldItem.Visible; - Result.Tag := OldItem.Tag; - - // clone events - Result.OnAdvancedDrawItem := OldItem.OnAdvancedDrawItem; - Result.OnClick := OldItem.OnClick; - Result.OnDrawItem := OldItem.OnDrawItem; - Result.OnMeasureItem := OldItem.OnMeasureItem; - - // remember name, parent, index, children - OldName := OldItem.Name; - OldParent := OldItem.Parent; - OldIndex := OldItem.MenuIndex; - for j := OldItem.Count - 1 downto 0 do begin - OldItemsList.Insert(0, OldItem.Items[j]); - OldItem.Remove(OldItem.Items[j]); - end; - - // clone final parts of old item - for j := 0 to OldItemsList.Count - 1 do - Result.Add(TMenuItem{TNT-ALLOW TMenuItem}(OldItemsList[j])); { add children } - if OldParent <> nil then - OldParent.Insert(OldIndex, Result); { insert into parent } - finally - OldItemsList.Free; - end; -end; - -procedure CheckMenuItemWin(MenuItemWin: TWinControl; PartOfATntMenu: Boolean); -var - OldItem: TMenuItem{TNT-ALLOW TMenuItem}; -begin - OldItem := GetMenuItem(MenuItemWin); - if OldItem = nil then - exit; - if (OldItem.ClassType = TMenuItem{TNT-ALLOW TMenuItem}) - and (PartOfATntMenu or (OldItem.Parent is TTntMenuItem)) then - begin - if MenuItemWin.Focused then - MenuItemWin.Parent.SetFocus; {Lose focus and regain later to ensure object inspector gets updated.} - ReplaceMenuItem(MenuItemWin, CreateTntMenuItem(OldItem)); - end else if (OldItem.ClassType = TTntMenuItem) - and (OldItem.Parent = nil) and (OldItem.Caption = '') and (OldItem.Name = '') - and not (PartOfATntMenu or (OldItem.Parent is TTntMenuItem)) then begin - if MenuItemWin.Focused then - MenuItemWin.Parent.SetFocus; {Lose focus and regain later to ensure object inspector gets updated.} - ReplaceMenuItem(MenuItemWin, TMenuItem{TNT-ALLOW TMenuItem}.Create(OldItem.Owner)); - end; -end; - -procedure TMenuBuilderChecker.CheckMenuItems(Sender: TObject); -var - a, i: integer; - MenuWin: TWinControl; - MenuItemWin: TWinControl; - SaveFocus: HWND; - PartOfATntMenu: Boolean; - WorkMenu: TMenuItem{TNT-ALLOW TMenuItem}; -begin - if (FMenuBuilder <> nil) - and (FMenuBuilder.Action = FCheckMenuAction) then begin - if (FLastCaption <> FMenuBuilder.Caption) - or (FLastActiveControl <> FMenuBuilder.ActiveControl) - or (FLastMenuItem <> GetMenuItem(FMenuBuilder.ActiveControl, False)) - then begin - try - try - with FMenuBuilder do begin - WorkMenu := GetMenuBuilder_WorkMenu(FMenuBuilder); - PartOfATntMenu := (WorkMenu <> nil) - and ((WorkMenu.Owner is TTntMainMenu) or (WorkMenu.Owner is TTntPopupMenu)); - SaveFocus := Windows.GetFocus; - for a := ComponentCount - 1 downto 0 do begin - {$IFDEF MNUBUILD_AVAILABLE} - if Components[a] is TMenuWin then begin - {$ELSE} - if Components[a].ClassName = 'TMenuWin' then begin - {$ENDIF} - MenuWin := Components[a] as TWinControl; - with MenuWin do begin - for i := ComponentCount - 1 downto 0 do begin - {$IFDEF MNUBUILD_AVAILABLE} - if Components[i] is TMenuItemWin then begin - {$ELSE} - if Components[i].ClassName = 'TMenuItemWin' then begin - {$ENDIF} - MenuItemWin := Components[i] as TWinControl; - CheckMenuItemWin(MenuItemWin, PartOfATntMenu); - end; - end; - end; - end; - end; - if SaveFocus <> Windows.GetFocus then - Windows.SetFocus(SaveFocus); - end; - except - on E: Exception do begin - FMenuBuilder.Action := nil; - end; - end; - finally - FLastCaption := FMenuBuilder.Caption; - FLastActiveControl := FMenuBuilder.ActiveControl; - FLastMenuItem := GetMenuItem(FMenuBuilder.ActiveControl, False); - end; - end; - end; -end; - -{ TTntMenuEditor } - -function TTntMenuEditor.GetVerbCount: Integer; -begin - Result := 1; -end; - -{$IFNDEF MNUBUILD_AVAILABLE} -resourcestring - SMenuDesigner = 'Menu Designer...'; -{$ENDIF} - -function TTntMenuEditor.GetVerb(Index: Integer): string{TNT-ALLOW string}; -begin - Result := SMenuDesigner; -end; - -procedure TTntMenuEditor.ExecuteVerb(Index: Integer); -var - MenuBuilder: TForm{TNT-ALLOW TForm}; -begin - EditPropertyWithDialog(Component, 'Items', Designer); - MenuBuilder := GetMenuBuilder; - if Assigned(MenuBuilder) then begin - if (MenuBuilderChecker = nil) or (MenuBuilderChecker.FMenuBuilder <> MenuBuilder) then begin - MenuBuilderChecker.Free; - MenuBuilderChecker := TMenuBuilderChecker.Create(MenuBuilder); - end; - EditPropertyWithDialog(Component, 'Items', Designer); // update menu builder caption - end; -end; - -initialization - -finalization - MenuBuilderChecker.Free; // design package might be recompiled - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntStdCtrls.dcr b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntStdCtrls.dcr deleted file mode 100644 index b3a5aec6521b58439c81e98f965248b6439399fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5392 zcmds*Kabl+5XHyA0osl(UAjz}B1MW6=Q|m(kvlUu+kig?J1Uj72*3qWs7#?RkuEx@ z$bBRh0>p0f-pmfAJ4*uWD)OF5J`Z>K@5eVgl!(YnEIHc(`KYC5B0nIK^LO$AfA6ro zmZ`kO*4y*vFD_hv5AmWb&&0wnag4()ir}BbXdA2{u|#=zc)$)`6gSy6Sle}GNu@;z zE)#mXj+1uW5ocZFonlHmy?~x)YoU|Wl+jVD)RcIZe^;*8f3KHK-qdwH&G-M@BVKQE zo$K{q%Tee1-`Qu%UF+rY9%Ip`&iCu(pB$_4%&}+Hew{hO@=JM&R_|cSX z>bpuGk@8EGLaWIySv>c&ti_>Mt8}4Ur{tF|=#RW1zcCJeV}J1TCGG`2!21J%RavwWXt!+m;3b2!F%N2|}wi&(G_krGHyzckB*Nb}3`Y+UbiuZCD=sntJbGab9uEf=Q-aokadf1%a z)8nTU++#SeYK?DayLcX`6&~nAA8lZFiF@23C%N7@a_qElA9R0k3O!d59&GD%RujC^f_yPIz z9baQ@=jK7@NDmgR9(2uGD3*H@cyM0k8|Ke>=|m4g#}H$p2caSHYQTf8=|R&Wk=+RCqFsS`QRtp19i)dyh84L4F_8LX1Hm+N@4*-CU_8?%sB6H zP6SDv_mbc#HWQuqtRf8LrUTHO+&B*1lg@hy1Dc6)!$F#WW3Msq=>d5t%zIcNonvh+ z3Qzrc>p~Yi8fTGXPqc$|i|5Y$neY5^X1VM5x$hQu;ql7rq+(wW1Nm7MKN!EJud)n< zUoX83#;?JbO{H@m`y=%Y#?Rtfx1`4UD?dBVp#1bJVHotnw4w>7&G08E9p43hKjTf@ zpZo6MJAUc0?tGd(zZnnWiR3)MK0%*N+s=oi3{#u)c3}*=YTM?yF^uH4Eey9JlP&8P zFjQR_sxAzzzcP$-90x|C2fGR09B6HTxHDnfmgtvm4tVfAYL`0@yusfUc-~nGJ-fQ4 zJcz2o diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntStrEdit_Design.dfm b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntStrEdit_Design.dfm deleted file mode 100644 index 8d21ef09d..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntStrEdit_Design.dfm +++ /dev/null @@ -1,135 +0,0 @@ -object TntStrEditDlg: TTntStrEditDlg - Left = 267 - Top = 258 - BorderStyle = bsDialog - Caption = 'Wide String List Editor' - ClientHeight = 279 - ClientWidth = 430 - Color = clBtnFace - ParentFont = True - OldCreateOrder = True - PopupMenu = StringEditorMenu - Position = poScreenCenter - OnCreate = FormCreate - PixelsPerInch = 96 - TextHeight = 13 - object TntGroupBox1: TTntGroupBox - Left = 8 - Top = 3 - Width = 413 - Height = 234 - TabOrder = 4 - object LineCount: TTntLabel - Left = 9 - Top = 9 - Width = 169 - Height = 17 - AutoSize = False - Caption = '0 lines' - end - object UnicodeEnabledLbl: TTntLabel - Left = 325 - Top = 9 - Width = 79 - Height = 13 - Alignment = taRightJustify - Caption = 'Unicode Enabled' - Font.Charset = DEFAULT_CHARSET - Font.Color = clGreen - Font.Height = -11 - Font.Name = 'MS Shell Dlg 2' - Font.Style = [] - ParentFont = False - Visible = False - end - object Memo: TTntMemo - Left = 8 - Top = 28 - Width = 397 - Height = 197 - ScrollBars = ssBoth - TabOrder = 0 - WordWrap = False - OnChange = UpdateStatus - OnKeyDown = Memo1KeyDown - end - end - object CodeWndBtn: TTntButton - Left = 8 - Top = 248 - Width = 75 - Height = 25 - Caption = '&Code Editor...' - Enabled = False - TabOrder = 0 - OnClick = CodeWndBtnClick - end - object HelpButton: TTntButton - Left = 345 - Top = 248 - Width = 75 - Height = 25 - Caption = '&Help' - TabOrder = 3 - OnClick = HelpButtonClick - end - object OKButton: TTntButton - Left = 185 - Top = 248 - Width = 75 - Height = 25 - Caption = '&OK' - Default = True - ModalResult = 1 - TabOrder = 1 - end - object CancelButton: TTntButton - Left = 265 - Top = 248 - Width = 75 - Height = 25 - Cancel = True - Caption = 'Cancel' - ModalResult = 2 - TabOrder = 2 - end - object OpenDialog: TTntOpenDialog - HelpContext = 26040 - DefaultExt = 'TXT' - Filter = - 'Text files (*.TXT)|*.TXT|Config files (*.SYS;*.INI)|*.SYS;*.INI|' + - 'Batch files (*.BAT)|*.BAT|All files (*.*)|*.*' - Options = [ofHideReadOnly, ofShowHelp, ofPathMustExist, ofFileMustExist, ofEnableSizing] - Title = 'Load string list' - Left = 200 - Top = 88 - end - object SaveDialog: TTntSaveDialog - HelpContext = 26050 - Filter = - 'Text files (*.TXT)|*.TXT|Config files (*.SYS;*.INI)|*.SYS;*.INI|' + - 'Batch files (*.BAT)|*.BAT|All files (*.*)|*.*' - Options = [ofOverwritePrompt, ofHideReadOnly, ofShowHelp, ofPathMustExist, ofEnableSizing] - Title = 'Save string list' - Left = 228 - Top = 88 - end - object StringEditorMenu: TTntPopupMenu - Left = 168 - Top = 88 - object LoadItem: TTntMenuItem - Caption = '&Load...' - OnClick = FileOpenClick - end - object SaveItem: TTntMenuItem - Caption = '&Save...' - OnClick = FileSaveClick - end - object CodeEditorItem: TTntMenuItem - Caption = '&Code Editor...' - Enabled = False - Visible = False - OnClick = CodeWndBtnClick - end - end -end diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntStrEdit_Design.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntStrEdit_Design.pas deleted file mode 100644 index 449508b69..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntStrEdit_Design.pas +++ /dev/null @@ -1,419 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntStrEdit_Design; - -{$INCLUDE ..\Source\TntCompilers.inc} - -// The following unit is adapted from StrEdit.pas. - -interface - -uses - Windows, Classes, Graphics, Controls, Buttons, Menus, StdCtrls, - TntStdCtrls, ExtCtrls, DesignEditors, DesignIntf, - TntForms, TntMenus, TntClasses, TntDialogs; - -type - TTntStrEditDlg = class(TTntForm) - CodeWndBtn: TTntButton; - OpenDialog: TTntOpenDialog; - SaveDialog: TTntSaveDialog; - HelpButton: TTntButton; - OKButton: TTntButton; - CancelButton: TTntButton; - StringEditorMenu: TTntPopupMenu; - LoadItem: TTntMenuItem; - SaveItem: TTntMenuItem; - CodeEditorItem: TTntMenuItem; - TntGroupBox1: TTntGroupBox; - UnicodeEnabledLbl: TTntLabel; - Memo: TTntMemo; - LineCount: TTntLabel; - procedure FileOpenClick(Sender: TObject); - procedure FileSaveClick(Sender: TObject); - procedure HelpButtonClick(Sender: TObject); - procedure CodeWndBtnClick(Sender: TObject); - procedure FormCreate(Sender: TObject); - procedure Memo1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); - procedure UpdateStatus(Sender: TObject); - private - SingleLine: WideString; - MultipleLines: WideString; - protected - FModified: Boolean; - function GetLines: TTntStrings; - procedure SetLines(const Value: TTntStrings); - function GetLinesControl: TWinControl; - public - property Lines: TTntStrings read GetLines write SetLines; - procedure PrepareForWideStringEdit; - end; - -type - TWideStringListProperty = class(TClassProperty) - protected - function EditDialog: TTntStrEditDlg; virtual; - function GetStrings: TTntStrings; virtual; - procedure SetStrings(const Value: TTntStrings); virtual; - public - function GetAttributes: TPropertyAttributes; override; - procedure Edit; override; - end; - -procedure Register; - -implementation - -{$R *.dfm} - -uses - ActiveX, Forms, SysUtils, DesignConst, ToolsAPI, IStreams, LibHelp, - StFilSys, TypInfo, TntSystem, TntDesignEditors_Design; - -procedure Register; -begin - RegisterPropertyEditor(TypeInfo(TTntStrings), nil, '', TWideStringListProperty); -end; - -{$IFDEF COMPILER_10_UP} -type - TStringsModuleCreator = class(TInterfacedObject, IOTACreator, IOTAModuleCreator) - private - FFileName: AnsiString; - FStream: TStringStream{TNT-ALLOW TStringStream}; - FAge: TDateTime; - public - constructor Create(const FileName: AnsiString; Stream: TStringStream{TNT-ALLOW TStringStream}; Age: TDateTime); - destructor Destroy; override; - { IOTACreator } - function GetCreatorType: AnsiString; - function GetExisting: Boolean; - function GetFileSystem: AnsiString; - function GetOwner: IOTAModule; - function GetUnnamed: Boolean; - { IOTAModuleCreator } - function GetAncestorName: AnsiString; - function GetImplFileName: AnsiString; - function GetIntfFileName: AnsiString; - function GetFormName: AnsiString; - function GetMainForm: Boolean; - function GetShowForm: Boolean; - function GetShowSource: Boolean; - function NewFormFile(const FormIdent, AncestorIdent: AnsiString): IOTAFile; - function NewImplSource(const ModuleIdent, FormIdent, AncestorIdent: AnsiString): IOTAFile; - function NewIntfSource(const ModuleIdent, FormIdent, AncestorIdent: AnsiString): IOTAFile; - procedure FormCreated(const FormEditor: IOTAFormEditor); - end; - - TOTAFile = class(TInterfacedObject, IOTAFile) - private - FSource: AnsiString; - FAge: TDateTime; - public - constructor Create(const ASource: AnsiString; AAge: TDateTime); - { IOTAFile } - function GetSource: AnsiString; - function GetAge: TDateTime; - end; - -{ TOTAFile } - -constructor TOTAFile.Create(const ASource: AnsiString; AAge: TDateTime); -begin - inherited Create; - FSource := ASource; - FAge := AAge; -end; - -function TOTAFile.GetAge: TDateTime; -begin - Result := FAge; -end; - -function TOTAFile.GetSource: AnsiString; -begin - Result := FSource; -end; - -{ TStringsModuleCreator } - -constructor TStringsModuleCreator.Create(const FileName: AnsiString; Stream: TStringStream{TNT-ALLOW TStringStream}; - Age: TDateTime); -begin - inherited Create; - FFileName := FileName; - FStream := Stream; - FAge := Age; -end; - -destructor TStringsModuleCreator.Destroy; -begin - FStream.Free; - inherited; -end; - -procedure TStringsModuleCreator.FormCreated(const FormEditor: IOTAFormEditor); -begin - { Nothing to do } -end; - -function TStringsModuleCreator.GetAncestorName: AnsiString; -begin - Result := ''; -end; - -function TStringsModuleCreator.GetCreatorType: AnsiString; -begin - Result := sText; -end; - -function TStringsModuleCreator.GetExisting: Boolean; -begin - Result := True; -end; - -function TStringsModuleCreator.GetFileSystem: AnsiString; -begin - Result := sTStringsFileSystem; -end; - -function TStringsModuleCreator.GetFormName: AnsiString; -begin - Result := ''; -end; - -function TStringsModuleCreator.GetImplFileName: AnsiString; -begin - Result := FFileName; -end; - -function TStringsModuleCreator.GetIntfFileName: AnsiString; -begin - Result := ''; -end; - -function TStringsModuleCreator.GetMainForm: Boolean; -begin - Result := False; -end; - -function TStringsModuleCreator.GetOwner: IOTAModule; -begin - Result := nil; -end; - -function TStringsModuleCreator.GetShowForm: Boolean; -begin - Result := False; -end; - -function TStringsModuleCreator.GetShowSource: Boolean; -begin - Result := True; -end; - -function TStringsModuleCreator.GetUnnamed: Boolean; -begin - Result := False; -end; - -function TStringsModuleCreator.NewFormFile(const FormIdent, - AncestorIdent: AnsiString): IOTAFile; -begin - Result := nil; -end; - -function TStringsModuleCreator.NewImplSource(const ModuleIdent, FormIdent, - AncestorIdent: AnsiString): IOTAFile; -begin - Result := TOTAFile.Create(FStream.DataString, FAge); -end; - -function TStringsModuleCreator.NewIntfSource(const ModuleIdent, FormIdent, - AncestorIdent: AnsiString): IOTAFile; -begin - Result := nil; -end; -{$ENDIF} - -{ TTntStrEditDlg } - -procedure TTntStrEditDlg.FormCreate(Sender: TObject); -begin - HelpContext := hcDStringListEditor; - OpenDialog.HelpContext := hcDStringListLoad; - SaveDialog.HelpContext := hcDStringListSave; - SingleLine := srLine; - MultipleLines := srLines; - UnicodeEnabledLbl.Visible := IsWindowUnicode(Memo.Handle); -end; - -procedure TTntStrEditDlg.PrepareForWideStringEdit; -begin - Caption := 'WideString Editor'; - CodeWndBtn.Visible := False; - CodeEditorItem.Visible := False; -end; - -procedure TTntStrEditDlg.FileOpenClick(Sender: TObject); -begin - with OpenDialog do - if Execute then Lines.LoadFromFile(FileName); -end; - -procedure TTntStrEditDlg.FileSaveClick(Sender: TObject); -begin - SaveDialog.FileName := OpenDialog.FileName; - with SaveDialog do - if Execute then Lines.SaveToFile(FileName); -end; - -procedure TTntStrEditDlg.HelpButtonClick(Sender: TObject); -begin - Application.HelpContext(HelpContext); -end; - -procedure TTntStrEditDlg.CodeWndBtnClick(Sender: TObject); -begin - ModalResult := mrYes; -end; - -function TTntStrEditDlg.GetLinesControl: TWinControl; -begin - Result := Memo; -end; - -procedure TTntStrEditDlg.Memo1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); -begin - if Key = VK_ESCAPE then CancelButton.Click; -end; - -procedure TTntStrEditDlg.UpdateStatus(Sender: TObject); -var - Count: Integer; - LineText: WideString; -begin - if Sender = Memo then FModified := True; - Count := Lines.Count; - if Count = 1 then LineText := SingleLine - else LineText := MultipleLines; - LineCount.Caption := WideFormat('%d %s', [Count, LineText]); -end; - -function TTntStrEditDlg.GetLines: TTntStrings; -begin - Result := Memo.Lines; -end; - -procedure TTntStrEditDlg.SetLines(const Value: TTntStrings); -begin - Memo.Lines.Assign(Value); -end; - -{ TWideStringListProperty } - -function TWideStringListProperty.EditDialog: TTntStrEditDlg; -begin - Result := TTntStrEditDlg.Create(Application); -end; - -function TWideStringListProperty.GetAttributes: TPropertyAttributes; -begin - Result := inherited GetAttributes + [paDialog] - [paSubProperties]; -end; - -function TWideStringListProperty.GetStrings: TTntStrings; -begin - Result := TTntStrings(GetOrdValue); -end; - -procedure TWideStringListProperty.SetStrings(const Value: TTntStrings); -begin - SetOrdValue(Longint(Value)); -end; - -procedure TWideStringListProperty.Edit; -{$IFDEF COMPILER_10_UP} -const - DotSep = '.'; // Temp fix for opening the strings in the editor. -var - Ident: AnsiString; - Component: TComponent; - Module: IOTAModule; - Editor: IOTAEditor; - ModuleServices: IOTAModuleServices; - Stream: TStringStream{TNT-ALLOW TStringStream}; - Age: TDateTime; -{$ENDIF} -begin - {$IFDEF COMPILER_10_UP} - Component := TComponent(GetComponent(0)); - ModuleServices := BorlandIDEServices as IOTAModuleServices; - if (TObject(Component) is TComponent) - and (Component.Owner = Self.Designer.GetRoot) - and (Self.Designer.GetRoot.Name <> '') - then begin - Ident := Self.Designer.GetRoot.Name + DotSep + - Component.Name + DotSep + GetName; - Ident := Self.Designer.GetDesignerExtension + DotSep + Ident; - Module := ModuleServices.FindModule(Ident); - end else begin - Ident := ''; - Module := nil; - end; - if (Module <> nil) and (Module.GetModuleFileCount > 0) then - Module.GetModuleFileEditor(0).Show - else - {$ENDIF} - with EditDialog do - try - if GetObjectInspectorForm <> nil then - Font.Assign(GetObjectInspectorForm.Font); - Lines := GetStrings; - UpdateStatus(nil); - FModified := False; - ActiveControl := GetLinesControl; - {$IFDEF COMPILER_10_UP} - CodeEditorItem.Enabled := Ident <> ''; - CodeWndBtn.Enabled := Ident <> ''; - {$ENDIF} - case ShowModal of - mrOk: SetStrings(Lines); - {$IFDEF COMPILER_10_UP} - mrYes: - begin - // this used to be done in LibMain's TLibrary.Create but now its done here - // the unregister is done over in ComponentDesigner's finalization - //StFilSys.Register; - Stream := TStringStream{TNT-ALLOW TStringStream}.Create(WideStringToUTF8(Lines.Text)); - Stream.Position := 0; - Age := Now; - Module := ModuleServices.CreateModule( - TStringsModuleCreator.Create(Ident, Stream, Age)); - if Module <> nil then - begin - with StringsFileSystem.GetTStringsProperty(Ident, Component, GetName) do - DiskAge := DateTimeToFileDate(Age); - Editor := Module.GetModuleFileEditor(0); - if FModified then - Editor.MarkModified; - Editor.Show; - end; - end; - {$ENDIF} - end; - finally - Free; - end; -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntUnicodeVcl_Register.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntUnicodeVcl_Register.pas deleted file mode 100644 index 06b6ea627..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntUnicodeVcl_Register.pas +++ /dev/null @@ -1,132 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntUnicodeVcl_Register; - -{$INCLUDE ..\Source\TntCompilers.inc} - -interface - -{ TODO: Install program (handle Std, Prof, Ent versions) (ie. no database stuff for personal edition) } -{ TODO: $IFDEF DelphiPersonalEdition } - -procedure Register; - -implementation - -uses - Classes, DB, TntForms, TntMenus, TntStdCtrls, TntCheckLst, TntGrids, TntExtCtrls, TntComCtrls, - TntButtons, TntDB, TntDBCtrls, TntDBGrids, TntActnList, TntDialogs, TntExtDlgs, DesignIntf; - -const - TNT_STANDARD = 'Tnt Standard'; - TNT_ADDITIONAL = 'Tnt Additional'; - TNT_WIN32 = 'Tnt Win32'; - TNT_DATA_CONTROLS = 'Tnt Data Controls'; - TNT_DIALOGS = 'Tnt Dialogs'; - -procedure Register; -begin - {$IFDEF COMPILER_9_UP} - // ForceDemandLoadState(dlDisable); - {$ENDIF} - - // ------- Standard ------- - RegisterComponents(TNT_STANDARD, [TTntMainMenu]); - RegisterComponents(TNT_STANDARD, [TTntPopupMenu]); - RegisterComponents(TNT_STANDARD, [TTntLabel]); - RegisterComponents(TNT_STANDARD, [TTntEdit]); - RegisterComponents(TNT_STANDARD, [TTntMemo]); - RegisterComponents(TNT_STANDARD, [TTntButton]); - RegisterComponents(TNT_STANDARD, [TTntCheckBox]); - RegisterComponents(TNT_STANDARD, [TTntRadioButton]); - RegisterComponents(TNT_STANDARD, [TTntListBox]); - RegisterComponents(TNT_STANDARD, [TTntComboBox]); - RegisterComponents(TNT_STANDARD, [TTntScrollBar]); - RegisterComponents(TNT_STANDARD, [TTntGroupBox]); - RegisterComponents(TNT_STANDARD, [TTntRadioGroup]); - RegisterComponents(TNT_STANDARD, [TTntPanel]); - RegisterComponents(TNT_STANDARD, [TTntActionList]); - - // ------- Additional ------- - RegisterComponents(TNT_ADDITIONAL, [TTntBitBtn]); - RegisterComponents(TNT_ADDITIONAL, [TTntSpeedButton]); - { -- TTntMaskEdit goes here -- } - RegisterComponents(TNT_ADDITIONAL, [TTntStringGrid]); - RegisterComponents(TNT_ADDITIONAL, [TTntDrawGrid]); - RegisterComponents(TNT_ADDITIONAL, [TTntImage]); - RegisterComponents(TNT_ADDITIONAL, [TTntShape]); - RegisterComponents(TNT_ADDITIONAL, [TTntBevel]); - RegisterComponents(TNT_ADDITIONAL, [TTntScrollBox]); - RegisterComponents(TNT_ADDITIONAL, [TTntCheckListBox]); - RegisterComponents(TNT_ADDITIONAL, [TTntSplitter]); - RegisterComponents(TNT_ADDITIONAL, [TTntStaticText]); - RegisterComponents(TNT_ADDITIONAL, [TTntControlBar]); - - // ------- Win32 ------- - RegisterComponents(TNT_WIN32, [TTntTabControl]); - RegisterComponents(TNT_WIN32, [TTntPageControl]); - RegisterComponents(TNT_WIN32, [TTntRichEdit]); - RegisterComponents(TNT_WIN32, [TTntTrackBar]); - RegisterComponents(TNT_WIN32, [TTntProgressBar]); - RegisterComponents(TNT_WIN32, [TTntUpDown]); - { -- TTntHotKey goes here -- } - { -- TTntAnimate goes here -- } - RegisterComponents(TNT_WIN32, [TTntDateTimePicker]); - RegisterComponents(TNT_WIN32, [TTntMonthCalendar]); - RegisterComponents(TNT_WIN32, [TTntTreeView]); - RegisterComponents(TNT_WIN32, [TTntListView]); - { -- TTntHeader goes here -- } - RegisterComponents(TNT_WIN32, [TTntStatusBar]); - RegisterComponents(TNT_WIN32, [TTntToolBar]); - { -- TTntCoolBar goes here -- } - RegisterComponents(TNT_WIN32, [TTntPageScroller]); - { -- TTntComboBoxEx goes here -- } - - // ------- System ------- - RegisterComponents(TNT_ADDITIONAL, [TTntPaintBox]); - { -- TTntMediaPlayer goes here -- } - { -- TTntOleContainer goes here -- } - - // ------- Data Controls ------- - RegisterComponents(TNT_DATA_CONTROLS, [TTntDBGrid]); - { -- TTntDBNavigator goes here -- } - RegisterComponents(TNT_DATA_CONTROLS, [TTntDBText]); - RegisterComponents(TNT_DATA_CONTROLS, [TTntDBEdit]); - RegisterComponents(TNT_DATA_CONTROLS, [TTntDBMemo]); - { -- TTntDBImage goes here -- } - { -- TTntDBListBox goes here -- } - RegisterComponents(TNT_DATA_CONTROLS, [TTntDBComboBox]); - RegisterComponents(TNT_DATA_CONTROLS, [TTntDBCheckBox]); - RegisterComponents(TNT_DATA_CONTROLS, [TTntDBRadioGroup]); - { -- TTntDBLookupListBox goes here -- } - { -- TTntDBLookupComboBox goes here -- } - RegisterComponents(TNT_DATA_CONTROLS, [TTntDBRichEdit]); - { -- TTntDBCtrlGrid here -- } - { -- TTntDBLookupListBox goes here -- } - { -- TTntDBChart goes here -- } - - // ------- Dialogs ------- - RegisterComponents(TNT_DIALOGS, [TTntOpenDialog]); - RegisterComponents(TNT_DIALOGS, [TTntSaveDialog]); - RegisterComponents(TNT_DIALOGS, [TTntOpenPictureDialog]); - RegisterComponents(TNT_DIALOGS, [TTntSavePictureDialog]); - - // --------- Fields -------------- - RegisterTntFields; - - // --------- Classes -------------- - RegisterClass(TTntMenuItem); - RegisterClass(TTntTabSheet); - RegisterClass(TTntToolButton); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntWideStringProperty_Design.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntWideStringProperty_Design.pas deleted file mode 100644 index 46c2ce26b..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Design/TntWideStringProperty_Design.pas +++ /dev/null @@ -1,400 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntWideStringProperty_Design; - -{$INCLUDE ..\Source\TntCompilers.inc} - -interface - -{*****************************************************} -{ TWideCharProperty-editor implemented by Maël Hörz } -{*****************************************************} - -{$IFDEF COMPILER_9_UP} - {$MESSAGE FATAL 'The Object Inspector in Delphi 9 is already Unicode enabled.'} -{$ENDIF} - -uses - Classes, Messages, Windows, Graphics, TypInfo, TntDesignEditors_Design, - DesignIntf, DesignEditors, VCLEditors; - -type - TWideStringProperty = class(TPropertyEditor, ICustomPropertyDrawing) - private - FActivateWithoutGetValue: Boolean; - FPropList: PInstPropList; - protected - procedure SetPropEntry(Index: Integer; AInstance: TPersistent; APropInfo: PPropInfo); override; - function GetWideStrValueAt(Index: Integer): WideString; dynamic; - function GetWideStrValue: WideString; - procedure SetWideStrValue(const Value: WideString); dynamic; - function GetWideVisualValue: WideString; - public - constructor Create(const ADesigner: ITntDesigner; APropCount: Integer); override; - destructor Destroy; override; - procedure Activate; override; - procedure PropDrawName(ACanvas: TCanvas; const ARect: TRect; ASelected: Boolean); - procedure PropDrawValue(ACanvas: TCanvas; const ARect: TRect; ASelected: Boolean); - function AllEqual: Boolean; override; - function GetEditLimit: Integer; override; - function GetValue: AnsiString; override; - procedure SetValue(const Value: AnsiString); override; - {$IFDEF MULTI_LINE_STRING_EDITOR} - function GetAttributes: TPropertyAttributes; override; - procedure Edit; override; - {$ENDIF} - end; - - TWideCaptionProperty = class(TWideStringProperty) - public - function GetAttributes: TPropertyAttributes; override; - end; - - TWideCharProperty = class(TWideStringProperty) - protected - {$IFDEF COMPILER_7_UP} - function GetIsDefault: Boolean; override; - {$ENDIF} - function GetWideStrValueAt(Index: Integer): WideString; override; - procedure SetWideStrValue(const Value: WideString); override; - public - function GetAttributes: TPropertyAttributes; override; - function GetEditLimit: Integer; override; - end; - -procedure Register; - -implementation - -uses - Controls, Forms, SysUtils, StdCtrls, TntGraphics, TntControls, - TntSysUtils, TntSystem, Consts, - RTLConsts; - -procedure Register; -begin - RegisterPropertyEditor(TypeInfo(WideString), nil, '', TWideStringProperty); - RegisterPropertyEditor(TypeInfo(TWideCaption), nil, '', TWideCaptionProperty); - RegisterPropertyEditor(TypeInfo(WideChar), nil, '', TWideCharProperty); -end; - -function GetOIInspListBox: TWinControl; -var - ObjectInspectorForm: TCustomForm; - Comp: TComponent; -begin - Result := nil; - ObjectInspectorForm := GetObjectInspectorForm; - if ObjectInspectorForm <> nil then begin - Comp := ObjectInspectorForm.FindComponent('PropList'); - if Comp is TWinControl then - Result := TWinControl(Comp); - end; -end; - -function GetOIPropInspEdit: TCustomEdit{TNT-ALLOW TCustomEdit}; -var - OIInspListBox: TWinControl; - Comp: TComponent; -begin - Result := nil; - OIInspListBox := GetOIInspListBox; - if OIInspListBox <> nil then begin - Comp := OIInspListBox.FindComponent('EditControl'); - if Comp is TCustomEdit{TNT-ALLOW TCustomEdit} then - Result := TCustomEdit{TNT-ALLOW TCustomEdit}(Comp); - end; -end; -//------------------------------ - -type TAccessWinControl = class(TWinControl); - -{ TWideStringProperty } - -var - WideStringPropertyCount: Integer = 0; - -constructor TWideStringProperty.Create(const ADesigner: ITntDesigner; APropCount: Integer); -begin - inherited; - Inc(WideStringPropertyCount); - GetMem(FPropList, APropCount * SizeOf(TInstProp)); -end; - -procedure ConvertObjectInspectorBackToANSI; -var - Edit: TCustomEdit{TNT-ALLOW TCustomEdit}; -begin - if (Win32PlatformIsUnicode) then begin - Edit := GetOIPropInspEdit; - if Assigned(Edit) - and IsWindowUnicode(Edit.Handle) then - TAccessWinControl(Edit).RecreateWnd; - end; -end; - -destructor TWideStringProperty.Destroy; -begin - Dec(WideStringPropertyCount); - if (WideStringPropertyCount = 0) then - ConvertObjectInspectorBackToANSI; - if FPropList <> nil then - FreeMem(FPropList, PropCount * SizeOf(TInstProp)); - inherited; -end; - -{$IFDEF DELPHI_7} // verified against VCL source in Delphi 7 -type - THackPropertyEditor = class - FDesigner: IDesigner; - FPropList: PInstPropList; - end; -{$ENDIF} - -procedure TWideStringProperty.Activate; -var - Edit: TCustomEdit{TNT-ALLOW TCustomEdit}; -begin - FActivateWithoutGetValue := True; - if (Win32PlatformIsUnicode) then begin - Edit := GetOIPropInspEdit; - if Assigned(Edit) - and (not IsWindowUnicode(Edit.Handle)) then - ReCreateUnicodeWnd(Edit, 'EDIT', True); - end; -end; - -procedure TWideStringProperty.SetPropEntry(Index: Integer; - AInstance: TPersistent; APropInfo: PPropInfo); -begin - inherited; - with FPropList^[Index] do - begin - Instance := AInstance; - PropInfo := APropInfo; - end; -end; - -function TWideStringProperty.GetWideStrValueAt(Index: Integer): WideString; -begin - with FPropList^[Index] do Result := GetWideStrProp(Instance, PropInfo); -end; - -function TWideStringProperty.GetWideStrValue: WideString; -begin - Result := GetWideStrValueAt(0); -end; - -procedure TWideStringProperty.SetWideStrValue(const Value: WideString); -var - I: Integer; -begin - for I := 0 to PropCount - 1 do - with FPropList^[I] do SetWideStrProp(Instance, PropInfo, Value); - Modified; -end; - -function TWideStringProperty.GetWideVisualValue: WideString; -begin - if AllEqual then - Result := GetWideStrValue - else - Result := ''; -end; - -procedure TWideStringProperty.PropDrawName(ACanvas: TCanvas; const ARect: TRect; ASelected: Boolean); -begin - DefaultPropertyDrawName(Self, ACanvas, ARect); -end; - -procedure TWideStringProperty.PropDrawValue(ACanvas: TCanvas; const ARect: TRect; ASelected: Boolean); -begin - WideCanvasTextRect(ACanvas, ARect, ARect.Left + 1, ARect.Top + 1, GetWideVisualValue); -end; - -function TWideStringProperty.AllEqual: Boolean; -var - I: Integer; - V: WideString; -begin - Result := False; - if PropCount > 1 then - begin - V := GetWideStrValue; - for I := 1 to PropCount - 1 do - if GetWideStrValueAt(I) <> V then Exit; - end; - Result := True; -end; - -function TWideStringProperty.GetEditLimit: Integer; -var - Edit: TCustomEdit{TNT-ALLOW TCustomEdit}; -begin - Result := MaxInt; - // GetEditLimit is called right before the inplace editor text has been set - if Win32PlatformIsUnicode then begin - Edit := GetOIPropInspEdit; - if Assigned(Edit) then begin - TntControl_SetText(Edit, GetWideStrValue); - TntControl_SetHint(Edit, GetWideStrValue); - end; - end; -end; - -function TWideStringProperty.GetValue: AnsiString; -begin - FActivateWithoutGetValue := False; - Result := WideStringToStringEx(GetWideStrValue, CP_ACP{TNT-ALLOW CP_ACP}); // use the same code page as the inplace editor -end; - -procedure TWideStringProperty.SetValue(const Value: AnsiString); -var - Edit: TCustomEdit{TNT-ALLOW TCustomEdit}; -begin - if (not FActivateWithoutGetValue) then begin - Edit := GetOIPropInspEdit; - if Assigned(Edit) and Win32PlatformIsUnicode then - SetWideStrValue(TntControl_GetText(Edit)) - else - SetWideStrValue(StringToWideStringEx(Value, CP_ACP{TNT-ALLOW CP_ACP})); // use the same code page as the inplace editor - end; -end; - -{$IFDEF MULTI_LINE_STRING_EDITOR} -function TWideStringProperty.GetAttributes: TPropertyAttributes; -begin - Result := inherited GetAttributes + [paDialog]; -end; - -procedure TWideStringProperty.Edit; -var - Temp: WideString; -begin - with TTntStrEditDlg.Create(Application) do - try - PrepareForWideStringEdit; - Memo.Text := GetWideStrValue; - UpdateStatus(nil); - if ShowModal = mrOk then begin - Temp := Memo.Text; - while (Length(Temp) > 0) and (Temp[Length(Temp)] < ' ') do - System.Delete(Temp, Length(Temp), 1); { trim control characters from end } - SetWideStrValue(Temp); - end; - finally - Free; - end; -end; -{$ENDIF} - -{ TWideCaptionProperty } - -function TWideCaptionProperty.GetAttributes: TPropertyAttributes; -begin - Result := inherited GetAttributes + [paAutoUpdate]; -end; - -{ TWideCharProperty } - -function TWideCharProperty.GetAttributes: TPropertyAttributes; -begin - Result := [paMultiSelect, paRevertable]; -end; - -function TWideCharProperty.GetEditLimit: Integer; -begin - inherited GetEditLimit; - Result := 63; -end; - -{$IFDEF COMPILER_7_UP} -function TWideCharProperty.GetIsDefault: Boolean; -var - i: Integer; - OldPropList: PInstPropList; -begin - Result := True; - if PropCount > 0 then - begin - OldPropList := THackPropertyEditor(Self).FPropList; - // The memory FPropList points to is write-protected. - // In the constructor we dynamically allocated our own PropList, - // which can be written, so point there instead. - THackPropertyEditor(Self).FPropList := FPropList; - - // Delphi can't handle WideChar-type, but does well with Word-type, - // which has exactly the same size as WideChar (i.e. 2 Bytes) - for i := 0 to PropCount - 1 do - FPropList^[i].PropInfo^.PropType^ := TypeInfo(Word); - - Result := inherited GetIsDefault; - - for i := 0 to PropCount - 1 do - FPropList^[i].PropInfo^.PropType^ := TypeInfo(WideChar); - - THackPropertyEditor(Self).FPropList := OldPropList; - end; -end; -{$ENDIF} - -function IsCharGraphic(C: WideChar): Boolean; -begin - if Win32PlatformIsUnicode then - Result := not IsWideCharCntrl(C) and not IsWideCharSpace(C) - else // representation as charcode avoids corruption on ANSI-systems - Result := (C >= #33) and (C <= #127); -end; - -function TWideCharProperty.GetWideStrValueAt(Index: Integer): WideString; -var - C: WideChar; -begin - with FPropList^[Index] do - C := WideChar(GetOrdProp(Instance, PropInfo)); - - if IsCharGraphic(C) then - Result := C - else - Result := WideFormat('#%d', [Ord(C)]); -end; - -procedure TWideCharProperty.SetWideStrValue(const Value: WideString); -var - C: Longint; - I: Integer; -begin - if Length(Value) = 0 then - C := 0 - else if Length(Value) = 1 then - C := Ord(Value[1]) - else if Value[1] = '#' then - C := StrToInt(Copy(Value, 2, Maxint)) - else - raise EPropertyError.Create(SInvalidPropertyValue); - - with GetTypeData(GetPropType)^ do - if (C < MinValue) or (C > MaxValue) then - raise EPropertyError.CreateFmt(SOutOfRange, [MinValue, MaxValue]); - - for I := 0 to PropCount - 1 do - with FPropList^[I] do SetOrdProp(Instance, PropInfo, C); - - Modified; -end; - -initialization - -finalization - ConvertObjectInspectorBackToANSI; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/ExampleUnicode.cfg b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/ExampleUnicode.cfg deleted file mode 100644 index 16f469b8e..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/ExampleUnicode.cfg +++ /dev/null @@ -1,35 +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 --w-UNSAFE_TYPE --w-UNSAFE_CODE --w-UNSAFE_CAST diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/ExampleUnicode.dof b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/ExampleUnicode.dof deleted file mode 100644 index 0d8e8cc07..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/ExampleUnicode.dof +++ /dev/null @@ -1,87 +0,0 @@ -[FileVersion] -Version=6.0 -[Compiler] -A=8 -B=0 -C=1 -D=1 -E=0 -F=0 -G=1 -H=1 -I=1 -J=1 -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= -[Directories] -OutputDir= -UnitOutputDir= -PackageDLLOutputDir= -PackageDCPOutputDir= -SearchPath= -Packages= -Conditionals= -DebugSourceDirs= -UsePackages=0 -[Parameters] -RunParams= -HostApplication= -Launcher= -UseLauncher=0 -DebugCWD= -[Language] -ActiveLang= -ProjectLang=$00000409 -RootDir= -[Version Info] -IncludeVerInfo=0 -AutoIncBuild=0 -MajorVer=2 -MinorVer=3 -Release=0 -Build=1 -Debug=0 -PreRelease=0 -Special=0 -Private=0 -DLL=0 -Locale=1033 -CodePage=1252 -[Version Info Keys] -CompanyName= -FileDescription= -FileVersion=2.3.0.1 -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename= -ProductName= -ProductVersion=2.3.0.1 -Comments= diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/ExampleUnicode.dpr b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/ExampleUnicode.dpr deleted file mode 100644 index dc3c0b35b..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/ExampleUnicode.dpr +++ /dev/null @@ -1,13 +0,0 @@ -program ExampleUnicode; - -uses - Forms, - MainFrm in 'MainFrm.pas' {MainForm}; - -{$R *.RES} - -begin - Application.Initialize; - Application.CreateForm(TMainForm, MainForm); - Application.Run; -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/MainFrm.dfm b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/MainFrm.dfm deleted file mode 100644 index 965f281a6..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/MainFrm.dfm +++ /dev/null @@ -1,143 +0,0 @@ -object MainForm: TMainForm - Left = 266 - Top = 190 - Width = 559 - Height = 451 - Caption = 'MainForm' - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'MS Shell Dlg 2' - Font.Style = [] - OldCreateOrder = True - OnCreate = FormCreate - PixelsPerInch = 96 - TextHeight = 13 - object Label1: TTntLabel - Left = 16 - Top = 16 - Width = 184 - Height = 13 - Caption = 'TntEdit (Data aware version available)' - end - object Label2: TTntLabel - Left = 16 - Top = 64 - Width = 217 - Height = 13 - Caption = 'TntComboBox (Data aware version available)' - end - object Label3: TTntLabel - Left = 16 - Top = 176 - Width = 50 - Height = 13 - Caption = 'TntListBox' - end - object Label4: TTntLabel - Left = 256 - Top = 176 - Width = 79 - Height = 13 - Caption = 'TntCheckListBox' - end - object Label5: TTntLabel - Left = 16 - Top = 304 - Width = 44 - Height = 13 - Caption = 'TntMemo' - end - object Label6: TTntLabel - Left = 16 - Top = 120 - Width = 217 - Height = 49 - Caption = - 'This program will fully support Unicode characters only when run' + - 'ning on Windows NT/2000/XP.' - AutoSize = False - Font.Charset = DEFAULT_CHARSET - Font.Color = clNavy - Font.Height = -11 - Font.Name = 'MS Shell Dlg 2' - Font.Style = [fsBold] - ParentFont = False - WordWrap = True - end - object TntComboBox1: TTntComboBox - Left = 16 - Top = 80 - Width = 185 - Height = 21 - ItemHeight = 13 - TabOrder = 0 - end - object TntEdit1: TTntEdit - Left = 16 - Top = 32 - Width = 185 - Height = 21 - TabOrder = 1 - end - object TntMemo1: TTntMemo - Left = 16 - Top = 320 - Width = 481 - Height = 89 - TabOrder = 2 - end - object TntListBox1: TTntListBox - Left = 16 - Top = 192 - Width = 225 - Height = 97 - ItemHeight = 13 - TabOrder = 3 - end - object TntCheckListBox1: TTntCheckListBox - Left = 256 - Top = 192 - Width = 241 - Height = 97 - ItemHeight = 13 - TabOrder = 4 - end - object Button1: TTntButton - Left = 256 - Top = 8 - Width = 241 - Height = 25 - Caption = 'TntEdit.Text -> Form.Caption' - TabOrder = 5 - OnClick = Button1Click - end - object Button2: TTntButton - Left = 256 - Top = 40 - Width = 241 - Height = 25 - Caption = 'Add TntEdit.Text to TntComboBox.Items' - TabOrder = 6 - OnClick = Button2Click - end - object Button3: TTntButton - Left = 256 - Top = 72 - Width = 241 - Height = 25 - Caption = 'Add TntEdit.Text to TntListBox.Items' - TabOrder = 7 - OnClick = Button3Click - end - object Button4: TTntButton - Left = 256 - Top = 104 - Width = 241 - Height = 25 - Caption = 'Add TntEdit.Text to TntCheckListBox.Items' - TabOrder = 8 - OnClick = Button4Click - end -end diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/MainFrm.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/MainFrm.pas deleted file mode 100644 index ef977dd81..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Example/MainFrm.pas +++ /dev/null @@ -1,72 +0,0 @@ -unit MainFrm; - -interface - -uses - Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, - TntForms, StdCtrls, CheckLst, TntStdCtrls, TntDBCtrls, TntCheckLst; - -type - TMainForm = class(TTntForm) - TntComboBox1: TTntComboBox; - TntEdit1: TTntEdit; - TntMemo1: TTntMemo; - TntListBox1: TTntListBox; - TntCheckListBox1: TTntCheckListBox; - Label1: TTntLabel; - Label2: TTntLabel; - Label3: TTntLabel; - Label4: TTntLabel; - Label5: TTntLabel; - Button1: TTntButton; - Button2: TTntButton; - Button3: TTntButton; - Button4: TTntButton; - Label6: TTntLabel; - procedure FormCreate(Sender: TObject); - procedure Button1Click(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - procedure Button4Click(Sender: TObject); - private - { Private declarations } - public - { Public declarations } - end; - -var - MainForm: TMainForm; - -implementation - -{$R *.DFM} - -procedure TMainForm.FormCreate(Sender: TObject); -begin - if Win32Platform = VER_PLATFORM_WIN32_NT then - Font.Name := 'MS Shell Dlg 2' - else - Font.Name := 'MS Shell Dlg'; -end; - -procedure TMainForm.Button1Click(Sender: TObject); -begin - Caption := TntEdit1.Text; -end; - -procedure TMainForm.Button2Click(Sender: TObject); -begin - TntComboBox1.Items.Add(TntEdit1.Text); -end; - -procedure TMainForm.Button3Click(Sender: TObject); -begin - TntListBox1.Items.Add(TntEdit1.Text); -end; - -procedure TMainForm.Button4Click(Sender: TObject); -begin - TntCheckListbox1.Items.Add(TntEdit1.Text); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/License.rtf b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/License.rtf deleted file mode 100644 index 7000069ce..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/License.rtf +++ /dev/null @@ -1,52 +0,0 @@ -{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff0\deff0\stshfdbch14\stshfloch0\stshfhich0\stshfbi0\deflang1033\deflangfe1042{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f14\froman\fcharset136\fprq2{\*\panose 02020300000000000000}PMingLiU{\*\falt \'b7\'73\'b2\'d3\'a9\'fa\'c5\'e9};} -{\f36\fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Tahoma;}{\f37\froman\fcharset136\fprq2{\*\panose 02020300000000000000}@PMingLiU;}{\f38\fscript\fcharset0\fprq2{\*\panose 030f0702030302020204}Comic Sans MS;} -{\f39\froman\fcharset238\fprq2 Times New Roman CE;}{\f40\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f42\froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\froman\fcharset162\fprq2 Times New Roman Tur;} -{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\f181\froman\fcharset0\fprq2 PMingLiU Western{\*\falt \'b7\'73\'b2\'d3\'a9\'fa\'c5\'e9};}{\f399\fswiss\fcharset238\fprq2 Tahoma CE;}{\f400\fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f402\fswiss\fcharset161\fprq2 Tahoma Greek;} -{\f403\fswiss\fcharset162\fprq2 Tahoma Tur;}{\f404\fbidi \fswiss\fcharset177\fprq2 Tahoma (Hebrew);}{\f405\fbidi \fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f406\fswiss\fcharset186\fprq2 Tahoma Baltic;} -{\f407\fswiss\fcharset163\fprq2 Tahoma (Vietnamese);}{\f408\fswiss\fcharset222\fprq2 Tahoma (Thai);}{\f411\froman\fcharset0\fprq2 @PMingLiU Western;}{\f419\fscript\fcharset238\fprq2 Comic Sans MS CE;}{\f420\fscript\fcharset204\fprq2 Comic Sans MS Cyr;} -{\f422\fscript\fcharset161\fprq2 Comic Sans MS Greek;}{\f423\fscript\fcharset162\fprq2 Comic Sans MS Tur;}{\f426\fscript\fcharset186\fprq2 Comic Sans MS Baltic;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255; -\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0; -\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 -\fs24\lang1033\langfe1042\loch\f0\hich\af0\dbch\af14\cgrid\langnp1033\langfenp1042 \snext0 Normal;}{\*\cs10 \additive \ssemihidden Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv -\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \snext11 \ssemihidden Normal Table;}} -{\*\latentstyles\lsdstimax156\lsdlockeddef0}{\*\rsidtbl \rsid12926494}{\*\generator Microsoft Word 11.0.8106;}{\info{\operator HP Authorized Customer}{\creatim\yr2007\mo1\dy2\hr16\min30}{\revtim\yr2007\mo1\dy2\hr16\min30}{\version2}{\edmins0}{\nofpages1} -{\nofwords166}{\nofchars949}{\nofcharsws1113}{\vern24611}{\*\password 00000000}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}{\xmlns2 urn:schemas-microsoft-com:office:smarttags}} -\paperw12240\paperh15840\margl1800\margr1800\margt1440\margb1440\gutter0\ltrsect -\widowctrl\ftnbj\aenddoc\donotembedsysfont0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3 -\jcompress\viewkind4\viewscale200\rsidroot12926494 \fet0{\*\wgrffmtfilter 013f}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnqc\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2 -\pnucltr\pnqc\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnqc\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnqc\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (} -{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} -{\*\pnseclvl9\pnlcrm\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 -\fs24\lang1033\langfe1042\loch\af0\hich\af0\dbch\af14\cgrid\langnp1033\langfenp1042 {\rtlch\fcs1 \ab\af38\afs28 \ltrch\fcs0 \b\f38\fs28\cf1\insrsid12926494 \hich\af38\dbch\af14\loch\f38 TntWare Delphi Unicode Controls}{\rtlch\fcs1 \ab\af36 \ltrch\fcs0 -\b\f36\cf1\insrsid12926494 -\par }{\rtlch\fcs1 \af36\afs16 \ltrch\fcs0 \f36\fs16\cf1\insrsid12926494 \hich\af36\dbch\af14\loch\f36 }{\rtlch\fcs1 \af36\afs16 \ltrch\fcs0 \f36\fs16\insrsid12926494 \hich\af36\dbch\af14\loch\f36 http\hich\af36\dbch\af14\loch\f36 :// -\hich\af36\dbch\af14\loch\f36 www\hich\af36\dbch\af14\loch\f36 .\hich\af36\dbch\af14\loch\f36 tntware\hich\af36\dbch\af14\loch\f36 .\hich\af36\dbch\af14\loch\f36 com\hich\af36\dbch\af14\loch\f36 /\hich\af36\dbch\af14\loch\f36 delphicontrols -\hich\af36\dbch\af14\loch\f36 /\hich\af36\dbch\af14\loch\f36 unicode\hich\af36\dbch\af14\loch\f36 /}{\rtlch\fcs1 \af36\afs16 \ltrch\fcs0 \f36\fs16\cf1\insrsid12926494 -\par -\par }\pard \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0\pararsid12926494 {\rtlch\fcs1 \ai\af36\afs16 \ltrch\fcs0 \i\f36\fs16\cf1\insrsid12926494 \hich\af36\dbch\af14\loch\f36 Copyright \hich\af36\dbch\af14\loch\f36 ( -\hich\af36\dbch\af14\loch\f36 c\hich\af36\dbch\af14\loch\f36 ) \hich\af36\dbch\af14\loch\f36 2002-200}{\rtlch\fcs1 \ai\af36\afs16 \ltrch\fcs0 \i\f36\fs16\cf1\insrsid12926494 \hich\af36\dbch\af14\loch\f36 7}{\rtlch\fcs1 \ai\af36\afs16 \ltrch\fcs0 -\i\f36\fs16\cf1\insrsid12926494 \hich\af36\dbch\af14\loch\f36 , {\*\xmlopen\xmlns2{\factoidname PersonName}}\hich\af36\dbch\af14\loch\f36 Troy Wolbrink{\*\xmlclose} \hich\af36\dbch\af14\loch\f36 (\hich\af36\dbch\af14\loch\f36 www -\hich\af36\dbch\af14\loch\f36 .\hich\af36\dbch\af14\loch\f36 tntware\hich\af36\dbch\af14\loch\f36 .\hich\af36\dbch\af14\loch\f36 com\hich\af36\dbch\af14\loch\f36 ) -\par }\pard \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \af36\afs16 \ltrch\fcs0 \f36\fs16\cf1\insrsid12926494 -\par }\pard \ltrpar\ql \li0\ri0\nowidctlpar\brdrb\brdrs\brdrw15\brsp20 \wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \ab\af36\afs16 \ltrch\fcs0 \b\f36\fs16\cf1\insrsid12926494 \hich\af36\dbch\af14\loch\f36 License -\par }\pard \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \af36\afs16 \ltrch\fcs0 \f36\fs16\cf1\insrsid12926494 \hich\af36\dbch\af14\loch\f36 Redistribution and use in binary forms\hich\af36\dbch\af14\loch\f36 , -\hich\af36\dbch\af14\loch\f36 with or without modification\hich\af36\dbch\af14\loch\f36 , \hich\af36\dbch\af14\loch\f36 are permitted\hich\af36\dbch\af14\loch\f36 . \hich\af36\dbch\af14\loch\f36 Redistribution and use in source forms -\hich\af36\dbch\af14\loch\f36 , \hich\af36\dbch\af14\loch\f36 with or without modification\hich\af36\dbch\af14\loch\f36 , \hich\af36\dbch\af14\loch\f36 are permitted provided that the redistributions of source code retain the above copyright -\hich\af36\dbch\af14\loch\f36 . -\par -\par }\pard \ltrpar\ql \li0\ri0\nowidctlpar\brdrb\brdrs\brdrw15\brsp20 \wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \ab\af36\afs16 \ltrch\fcs0 \b\f36\fs16\cf1\insrsid12926494 \hich\af36\dbch\af14\loch\f36 Disclaim\hich\af36\dbch\af14\loch\f36 er -\par }\pard \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \af36\afs16 \ltrch\fcs0 \f36\fs16\cf1\insrsid12926494 \hich\af36\dbch\af14\loch\f36 This software is provided by the author \hich\af36\dbch\af14\loch\f36 " -\hich\af36\dbch\af14\loch\f36 as is\hich\af36\dbch\af14\loch\f36 " \hich\af36\dbch\af14\loch\f36 and any express or implied warranties\hich\af36\dbch\af14\loch\f36 , \hich\af36\dbch\af14\loch\f36 including\hich\af36\dbch\af14\loch\f36 , -\hich\af36\dbch\af14\loch\f36 but not limited to\hich\af36\dbch\af14\loch\f36 , \hich\af36\dbch\af14\loch\f36 the implied warranties of merchantability and fitness for a particular purpose are disclaimed\hich\af36\dbch\af14\loch\f36 . -\hich\af36\dbch\af14\loch\f36 In no event shall the author be liable f\hich\af36\dbch\af14\loch\f36 or any direct\hich\af36\dbch\af14\loch\f36 , \hich\af36\dbch\af14\loch\f36 indirect\hich\af36\dbch\af14\loch\f36 , \hich\af36\dbch\af14\loch\f36 incidental -\hich\af36\dbch\af14\loch\f36 , \hich\af36\dbch\af14\loch\f36 special\hich\af36\dbch\af14\loch\f36 , \hich\af36\dbch\af14\loch\f36 exemplary\hich\af36\dbch\af14\loch\f36 , \hich\af36\dbch\af14\loch\f36 or consequential damages -\hich\af36\dbch\af14\loch\f36 (\hich\af36\dbch\af14\loch\f36 including\hich\af36\dbch\af14\loch\f36 , \hich\af36\dbch\af14\loch\f36 but not limited to\hich\af36\dbch\af14\loch\f36 , \hich\af36\dbch\af14\loch\f36 procurement of substitute goods or services -\hich\af36\dbch\af14\loch\f36 ; \hich\af36\dbch\af14\loch\f36 loss of use\hich\af36\dbch\af14\loch\f36 , \hich\af36\dbch\af14\loch\f36 data\hich\af36\dbch\af14\loch\f36 , \hich\af36\dbch\af14\loch\f36 or profits\hich\af36\dbch\af14\loch\f36 ; -\hich\af36\dbch\af14\loch\f36 or business interruption\hich\af36\dbch\af14\loch\f36 ) \hich\af36\dbch\af14\loch\f36 however caused and on any theory of liab\hich\af36\dbch\af14\loch\f36 ility\hich\af36\dbch\af14\loch\f36 , \hich\af36\dbch\af14\loch\f36 -whether in contract\hich\af36\dbch\af14\loch\f36 , \hich\af36\dbch\af14\loch\f36 strict liability\hich\af36\dbch\af14\loch\f36 , \hich\af36\dbch\af14\loch\f36 or tort \hich\af36\dbch\af14\loch\f36 (\hich\af36\dbch\af14\loch\f36 -including negligence or otherwise\hich\af36\dbch\af14\loch\f36 ) \hich\af36\dbch\af14\loch\f36 arising in any way out of the use of this software\hich\af36\dbch\af14\loch\f36 , \hich\af36\dbch\af14\loch\f36 -even if advised of the possibility of such damage\hich\af36\dbch\af14\loch\f36 . -\par }{\rtlch\fcs1 \af36\afs20 \ltrch\fcs0 \f36\fs20\insrsid12926494 -\par }} \ No newline at end of file diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Readme.txt b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Readme.txt deleted file mode 100644 index a2d8f7995..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Readme.txt +++ /dev/null @@ -1,53 +0,0 @@ - ** Tnt Delphi UNICODE Controls Project ** - -Website: http://tnt.ccci.org/delphi_unicode_controls/ -Email: troy.wolbrink@ccci.org - -These controls are provided as-is, with no implied warranty. They are freely available for you to use in your own projects. Please let me know if you have found them helpful. Also, please let me know if you find any bugs or other areas of needed improvement. - - ----Delphi Installation-------------------------- - -The most simple way to install these components is by opening the appropriate design package in Delphi and clicking on the big "Install" button. For instance, Delphi 5's design package is TntUnicodeVcl_D50.dpk. - -For BCB 2006 and newer, open the appropriate design package in the packages\bcbx\ folder using the Delphi personality. After compiling and installing, you should be able to use the components in both the Delphi and BCB personality. Remember to set the library path in menu "Tools->Options" for both the C++ Builder and the Delphi. - - ----A note on fonts---------------------- - -The default TFont uses "MS Sans Serif" which doesn't work well with most non-ANSI characters. I'd recommend using a TrueType font such as "Tahoma" if it is installed on the machine. To make TFont use a different font like "Tahoma" add this to the first line in the project: - - Graphics.DefFontData.Name := 'Tahoma'; - -You might have to include "Graphics" in the file's uses clauses. Furthermore, adding this line of code to the project will cause the changed setting to only be applied at runtime, not at design time. To make a designtime change, you'd have to add this line to the initialization section of a unit in a design package. - -Regarding the IDE, I use GExperts to change the font of the Object Inspector. The Wide String List editor uses the font used by the object inspector. - -Also keep in mind that the font used by certain message boxes come from that set by Windows' Display properties. - - ----Background---------------------------- - -Designing software for an international audience, I've always wanted to write a full UNICODE application. My approach so far, has been to write Unicode on the inside, and MBCS on the outside. This has always been frustrating, because (even on Windows NT/2000/XP which provide native Unicode window controls) the WideStrings inside my application and databases were always confined to an ANSI VCL. And, since the VCL was designed to wrap the low-level Windows details, why shouldn't the VCL hide the fact that sometimes native Unicode controls are not possible on the given version of Windows. I believe the VCL should be written with a Unicode interface, even if it must (at times) deal with an ANSI operating system. For example, TEdit should expose Text as a WideString, even if it has to convert the WideString to an AnsiString on the Windows 9X platform. - -In the past, the ANSI VCL may have made a little sense, considering that there were many more users of Windows 9X, than Windows NT. There would have been some performance penalty to use WideStrings on the Windows 9X platform. But with the faster computers of today, and with more people using platforms such as Windows 2000 and Windows XP, the ANSI VCL just doesn't make sense anymore. In fact, having to use the the ANSI VCL on Windows NT/2000/XP is slower because of the constant conversion to and from UNICODE inside Windows. - -My coding signature is Tnt. I will use this to denote my classes from others. - -For more information about me: -Some of my software projects (all written in Delphi). - TntMPD (contact manager for missionaries) - - Jesus Film Screen Saver - - ActiveX SCR control - - ----Design Goals---------------------------- - -I want the controls to work on Windows 95, 98, ME, NT, 2000, XP, etc. I want a single EXE for all platforms. Of course, full UNICODE support is only truly available on NT/2000/XP. In other words, the controls should automatically scale to take advantage of native Unicode support when possible. - -I want the controls to inherit from the Delphi VCL. I want to reuse as much code as possible. For the most part this makes sense. The only sticky part is where text messages get passed around. But I believe I've gotten past this through strategic subclassing at various points in the message flow chain. To give a rough comparison of why this is so important, check out the following chart which compares the lines of code in the VCL for a given control (4,397 in all), and the lines of code required in my descendent controls (655 in all). Besides saving lines of code, I get the advantage of automatically inheriting new features as new versions of Delphi come out. One such example is the AlphaBlending feature in the Delphi 6 TForm. Even though I use Delphi 5 now, I won't have to add any code to get this new feature. - ----More Interesting Information---------------------------- -Case Study: Porting an MFC Application to Unicode: It looks like the FrontPage 2002 team did the roughly the same thing to MFC as what I'm doing to the VCL. They did this with the same goal in mind: to support Unicode as much as possible depending on the support offered by Windows. Another goal was "Don’t abandon MFC; don’t rewrite app". Because they still want to support Windows 9X using the same worldwide EXE used everywhere. They couldn't just compile with the _UNICODE directive. They had to start with the ANSI MFC, strategically subclassing window procedures at just the right places. Hmmm... sounds familiar. \ No newline at end of file diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Reset Tnt Palette.reg b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Reset Tnt Palette.reg deleted file mode 100644 index 649c0f7a39ac42144b4c8fead218cd83dfbc00d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1669 zcmeH{%}T>S7)8%o@Et<-N@=WJbzx1Y(jq0XRH;&gq%{x{Ne6s;^` nil then - begin - FIntf := nil; - end; -end; - -function TCActiveIMM.GetDefaultInterface: IActiveIMMApp; -begin - if FIntf = nil then - Connect; - Assert(FIntf <> nil, 'DefaultInterface is NULL. Component is not connected to Server. You must call ''Connect'' or ''ConnectTo'' before this operation'); - Result := FIntf; -end; - -constructor TCActiveIMM.Create(AOwner: TComponent); -begin - inherited Create(AOwner); -{$IFDEF LIVE_SERVER_AT_DESIGN_TIME} - FProps := TCActiveIMMProperties.Create(Self); -{$ENDIF} -end; - -destructor TCActiveIMM.Destroy; -begin -{$IFDEF LIVE_SERVER_AT_DESIGN_TIME} - FProps.Free; -{$ENDIF} - inherited Destroy; -end; - -{$IFDEF LIVE_SERVER_AT_DESIGN_TIME} -function TCActiveIMM.GetServerProperties: TCActiveIMMProperties; -begin - Result := FProps; -end; -{$ENDIF} - -function TCActiveIMM.AssociateContext(var hWnd: _RemotableHandle; hIME: LongWord; - out phPrev: LongWord): HResult; -begin - Result := DefaultInterface.AssociateContext(hWnd, hIME, phPrev); -end; - -function TCActiveIMM.ConfigureIMEA(var hKL: Pointer; var hWnd: _RemotableHandle; dwMode: LongWord; - var pData: REGISTERWORDA): HResult; -begin - Result := DefaultInterface.ConfigureIMEA(hKL, hWnd, dwMode, pData); -end; - -function TCActiveIMM.ConfigureIMEW(var hKL: Pointer; var hWnd: _RemotableHandle; dwMode: LongWord; - var pData: REGISTERWORDW): HResult; -begin - Result := DefaultInterface.ConfigureIMEW(hKL, hWnd, dwMode, pData); -end; - -function TCActiveIMM.CreateContext(out phIMC: LongWord): HResult; -begin - Result := DefaultInterface.CreateContext(phIMC); -end; - -function TCActiveIMM.DestroyContext(hIME: LongWord): HResult; -begin - Result := DefaultInterface.DestroyContext(hIME); -end; - -function TCActiveIMM.EnumRegisterWordA(var hKL: Pointer; szReading: PAnsiChar; dwStyle: LongWord; - szRegister: PAnsiChar; var pData: Pointer; - out pEnum: IEnumRegisterWordA): HResult; -begin - Result := DefaultInterface.EnumRegisterWordA(hKL, szReading, dwStyle, szRegister, pData, pEnum); -end; - -function TCActiveIMM.EnumRegisterWordW(var hKL: Pointer; szReading: PWideChar; dwStyle: LongWord; - szRegister: PWideChar; var pData: Pointer; - out pEnum: IEnumRegisterWordW): HResult; -begin - Result := DefaultInterface.EnumRegisterWordW(hKL, szReading, dwStyle, szRegister, pData, pEnum); -end; - -function TCActiveIMM.EscapeA(var hKL: Pointer; hIMC: LongWord; uEscape: SYSUINT; - var pData: Pointer; out plResult: LONG_PTR): HResult; -begin - Result := DefaultInterface.EscapeA(hKL, hIMC, uEscape, pData, plResult); -end; - -function TCActiveIMM.EscapeW(var hKL: Pointer; hIMC: LongWord; uEscape: SYSUINT; - var pData: Pointer; out plResult: LONG_PTR): HResult; -begin - Result := DefaultInterface.EscapeW(hKL, hIMC, uEscape, pData, plResult); -end; - -function TCActiveIMM.GetCandidateListA(hIMC: LongWord; dwIndex: LongWord; uBufLen: SYSUINT; - out pCandList: CANDIDATELIST; out puCopied: SYSUINT): HResult; -begin - Result := DefaultInterface.GetCandidateListA(hIMC, dwIndex, uBufLen, pCandList, puCopied); -end; - -function TCActiveIMM.GetCandidateListW(hIMC: LongWord; dwIndex: LongWord; uBufLen: SYSUINT; - out pCandList: CANDIDATELIST; out puCopied: SYSUINT): HResult; -begin - Result := DefaultInterface.GetCandidateListW(hIMC, dwIndex, uBufLen, pCandList, puCopied); -end; - -function TCActiveIMM.GetCandidateListCountA(hIMC: LongWord; out pdwListSize: LongWord; - out pdwBufLen: LongWord): HResult; -begin - Result := DefaultInterface.GetCandidateListCountA(hIMC, pdwListSize, pdwBufLen); -end; - -function TCActiveIMM.GetCandidateListCountW(hIMC: LongWord; out pdwListSize: LongWord; - out pdwBufLen: LongWord): HResult; -begin - Result := DefaultInterface.GetCandidateListCountW(hIMC, pdwListSize, pdwBufLen); -end; - -function TCActiveIMM.GetCandidateWindow(hIMC: LongWord; dwIndex: LongWord; - out pCandidate: CANDIDATEFORM): HResult; -begin - Result := DefaultInterface.GetCandidateWindow(hIMC, dwIndex, pCandidate); -end; - -function TCActiveIMM.GetCompositionFontA(hIMC: LongWord; out plf: LOGFONTA): HResult; -begin - Result := DefaultInterface.GetCompositionFontA(hIMC, plf); -end; - -function TCActiveIMM.GetCompositionFontW(hIMC: LongWord; out plf: LOGFONTW): HResult; -begin - Result := DefaultInterface.GetCompositionFontW(hIMC, plf); -end; - -function TCActiveIMM.GetCompositionStringA(hIMC: LongWord; dwIndex: LongWord; dwBufLen: LongWord; - out plCopied: Integer; out pBuf: Pointer): HResult; -begin - Result := DefaultInterface.GetCompositionStringA(hIMC, dwIndex, dwBufLen, plCopied, pBuf); -end; - -function TCActiveIMM.GetCompositionStringW(hIMC: LongWord; dwIndex: LongWord; dwBufLen: LongWord; - out plCopied: Integer; out pBuf: Pointer): HResult; -begin - Result := DefaultInterface.GetCompositionStringW(hIMC, dwIndex, dwBufLen, plCopied, pBuf); -end; - -function TCActiveIMM.GetCompositionWindow(hIMC: LongWord; out pCompForm: COMPOSITIONFORM): HResult; -begin - Result := DefaultInterface.GetCompositionWindow(hIMC, pCompForm); -end; - -function TCActiveIMM.GetContext(var hWnd: _RemotableHandle; out phIMC: LongWord): HResult; -begin - Result := DefaultInterface.GetContext(hWnd, phIMC); -end; - -function TCActiveIMM.GetConversionListA(var hKL: Pointer; hIMC: LongWord; pSrc: PAnsiChar; - uBufLen: SYSUINT; uFlag: SYSUINT; out pDst: CANDIDATELIST; - out puCopied: SYSUINT): HResult; -begin - Result := DefaultInterface.GetConversionListA(hKL, hIMC, pSrc, uBufLen, uFlag, pDst, puCopied); -end; - -function TCActiveIMM.GetConversionListW(var hKL: Pointer; hIMC: LongWord; pSrc: PWideChar; - uBufLen: SYSUINT; uFlag: SYSUINT; out pDst: CANDIDATELIST; - out puCopied: SYSUINT): HResult; -begin - Result := DefaultInterface.GetConversionListW(hKL, hIMC, pSrc, uBufLen, uFlag, pDst, puCopied); -end; - -function TCActiveIMM.GetConversionStatus(hIMC: LongWord; out pfdwConversion: LongWord; - out pfdwSentence: LongWord): HResult; -begin - Result := DefaultInterface.GetConversionStatus(hIMC, pfdwConversion, pfdwSentence); -end; - -function TCActiveIMM.GetDefaultIMEWnd(var hWnd: _RemotableHandle; out phDefWnd: wireHWND): HResult; -begin - Result := DefaultInterface.GetDefaultIMEWnd(hWnd, phDefWnd); -end; - -function TCActiveIMM.GetDescriptionA(var hKL: Pointer; uBufLen: SYSUINT; szDescription: PAnsiChar; - out puCopied: SYSUINT): HResult; -begin - Result := DefaultInterface.GetDescriptionA(hKL, uBufLen, szDescription, puCopied); -end; - -function TCActiveIMM.GetDescriptionW(var hKL: Pointer; uBufLen: SYSUINT; szDescription: PWideChar; - out puCopied: SYSUINT): HResult; -begin - Result := DefaultInterface.GetDescriptionW(hKL, uBufLen, szDescription, puCopied); -end; - -function TCActiveIMM.GetGuideLineA(hIMC: LongWord; dwIndex: LongWord; dwBufLen: LongWord; - pBuf: PAnsiChar; out pdwResult: LongWord): HResult; -begin - Result := DefaultInterface.GetGuideLineA(hIMC, dwIndex, dwBufLen, pBuf, pdwResult); -end; - -function TCActiveIMM.GetGuideLineW(hIMC: LongWord; dwIndex: LongWord; dwBufLen: LongWord; - pBuf: PWideChar; out pdwResult: LongWord): HResult; -begin - Result := DefaultInterface.GetGuideLineW(hIMC, dwIndex, dwBufLen, pBuf, pdwResult); -end; - -function TCActiveIMM.GetIMEFileNameA(var hKL: Pointer; uBufLen: SYSUINT; szFileName: PAnsiChar; - out puCopied: SYSUINT): HResult; -begin - Result := DefaultInterface.GetIMEFileNameA(hKL, uBufLen, szFileName, puCopied); -end; - -function TCActiveIMM.GetIMEFileNameW(var hKL: Pointer; uBufLen: SYSUINT; szFileName: PWideChar; - out puCopied: SYSUINT): HResult; -begin - Result := DefaultInterface.GetIMEFileNameW(hKL, uBufLen, szFileName, puCopied); -end; - -function TCActiveIMM.GetOpenStatus(hIMC: LongWord): HResult; -begin - Result := DefaultInterface.GetOpenStatus(hIMC); -end; - -function TCActiveIMM.GetProperty(var hKL: Pointer; fdwIndex: LongWord; out pdwProperty: LongWord): HResult; -begin - Result := DefaultInterface.GetProperty(hKL, fdwIndex, pdwProperty); -end; - -function TCActiveIMM.GetRegisterWordStyleA(var hKL: Pointer; nItem: SYSUINT; - out pStyleBuf: STYLEBUFA; out puCopied: SYSUINT): HResult; -begin - Result := DefaultInterface.GetRegisterWordStyleA(hKL, nItem, pStyleBuf, puCopied); -end; - -function TCActiveIMM.GetRegisterWordStyleW(var hKL: Pointer; nItem: SYSUINT; - out pStyleBuf: STYLEBUFW; out puCopied: SYSUINT): HResult; -begin - Result := DefaultInterface.GetRegisterWordStyleW(hKL, nItem, pStyleBuf, puCopied); -end; - -function TCActiveIMM.GetStatusWindowPos(hIMC: LongWord; out pptPos: tagPOINT): HResult; -begin - Result := DefaultInterface.GetStatusWindowPos(hIMC, pptPos); -end; - -function TCActiveIMM.GetVirtualKey(var hWnd: _RemotableHandle; out puVirtualKey: SYSUINT): HResult; -begin - Result := DefaultInterface.GetVirtualKey(hWnd, puVirtualKey); -end; - -function TCActiveIMM.InstallIMEA(szIMEFileName: PAnsiChar; szLayoutText: PAnsiChar; out phKL: Pointer): HResult; -begin - Result := DefaultInterface.InstallIMEA(szIMEFileName, szLayoutText, phKL); -end; - -function TCActiveIMM.InstallIMEW(szIMEFileName: PWideChar; szLayoutText: PWideChar; - out phKL: Pointer): HResult; -begin - Result := DefaultInterface.InstallIMEW(szIMEFileName, szLayoutText, phKL); -end; - -function TCActiveIMM.IsIME(var hKL: Pointer): HResult; -begin - Result := DefaultInterface.IsIME(hKL); -end; - -function TCActiveIMM.IsUIMessageA(var hWndIME: _RemotableHandle; msg: SYSUINT; wParam: UINT_PTR; - lParam: LONG_PTR): HResult; -begin - Result := DefaultInterface.IsUIMessageA(hWndIME, msg, wParam, lParam); -end; - -function TCActiveIMM.IsUIMessageW(var hWndIME: _RemotableHandle; msg: SYSUINT; wParam: UINT_PTR; - lParam: LONG_PTR): HResult; -begin - Result := DefaultInterface.IsUIMessageW(hWndIME, msg, wParam, lParam); -end; - -function TCActiveIMM.NotifyIME(hIMC: LongWord; dwAction: LongWord; dwIndex: LongWord; - dwValue: LongWord): HResult; -begin - Result := DefaultInterface.NotifyIME(hIMC, dwAction, dwIndex, dwValue); -end; - -function TCActiveIMM.REGISTERWORDA(var hKL: Pointer; szReading: PAnsiChar; dwStyle: LongWord; - szRegister: PAnsiChar): HResult; -begin - Result := DefaultInterface.REGISTERWORDA(hKL, szReading, dwStyle, szRegister); -end; - -function TCActiveIMM.REGISTERWORDW(var hKL: Pointer; szReading: PWideChar; dwStyle: LongWord; - szRegister: PWideChar): HResult; -begin - Result := DefaultInterface.REGISTERWORDW(hKL, szReading, dwStyle, szRegister); -end; - -function TCActiveIMM.ReleaseContext(var hWnd: _RemotableHandle; hIMC: LongWord): HResult; -begin - Result := DefaultInterface.ReleaseContext(hWnd, hIMC); -end; - -function TCActiveIMM.SetCandidateWindow(hIMC: LongWord; var pCandidate: CANDIDATEFORM): HResult; -begin - Result := DefaultInterface.SetCandidateWindow(hIMC, pCandidate); -end; - -function TCActiveIMM.SetCompositionFontA(hIMC: LongWord; var plf: LOGFONTA): HResult; -begin - Result := DefaultInterface.SetCompositionFontA(hIMC, plf); -end; - -function TCActiveIMM.SetCompositionFontW(hIMC: LongWord; var plf: LOGFONTW): HResult; -begin - Result := DefaultInterface.SetCompositionFontW(hIMC, plf); -end; - -function TCActiveIMM.SetCompositionStringA(hIMC: LongWord; dwIndex: LongWord; var pComp: Pointer; - dwCompLen: LongWord; var pRead: Pointer; - dwReadLen: LongWord): HResult; -begin - Result := DefaultInterface.SetCompositionStringA(hIMC, dwIndex, pComp, dwCompLen, pRead, dwReadLen); -end; - -function TCActiveIMM.SetCompositionStringW(hIMC: LongWord; dwIndex: LongWord; var pComp: Pointer; - dwCompLen: LongWord; var pRead: Pointer; - dwReadLen: LongWord): HResult; -begin - Result := DefaultInterface.SetCompositionStringW(hIMC, dwIndex, pComp, dwCompLen, pRead, dwReadLen); -end; - -function TCActiveIMM.SetCompositionWindow(hIMC: LongWord; var pCompForm: COMPOSITIONFORM): HResult; -begin - Result := DefaultInterface.SetCompositionWindow(hIMC, pCompForm); -end; - -function TCActiveIMM.SetConversionStatus(hIMC: LongWord; fdwConversion: LongWord; - fdwSentence: LongWord): HResult; -begin - Result := DefaultInterface.SetConversionStatus(hIMC, fdwConversion, fdwSentence); -end; - -function TCActiveIMM.SetOpenStatus(hIMC: LongWord; fOpen: Integer): HResult; -begin - Result := DefaultInterface.SetOpenStatus(hIMC, fOpen); -end; - -function TCActiveIMM.SetStatusWindowPos(hIMC: LongWord; var pptPos: tagPOINT): HResult; -begin - Result := DefaultInterface.SetStatusWindowPos(hIMC, pptPos); -end; - -function TCActiveIMM.SimulateHotKey(var hWnd: _RemotableHandle; dwHotKeyID: LongWord): HResult; -begin - Result := DefaultInterface.SimulateHotKey(hWnd, dwHotKeyID); -end; - -function TCActiveIMM.UnregisterWordA(var hKL: Pointer; szReading: PAnsiChar; dwStyle: LongWord; - szUnregister: PAnsiChar): HResult; -begin - Result := DefaultInterface.UnregisterWordA(hKL, szReading, dwStyle, szUnregister); -end; - -function TCActiveIMM.UnregisterWordW(var hKL: Pointer; szReading: PWideChar; dwStyle: LongWord; - szUnregister: PWideChar): HResult; -begin - Result := DefaultInterface.UnregisterWordW(hKL, szReading, dwStyle, szUnregister); -end; - -function TCActiveIMM.Activate(fRestoreLayout: Integer): HResult; -begin - Result := DefaultInterface.Activate(fRestoreLayout); -end; - -function TCActiveIMM.Deactivate: HResult; -begin - Result := DefaultInterface.Deactivate; -end; - -function TCActiveIMM.OnDefWindowProc(var hWnd: _RemotableHandle; msg: SYSUINT; wParam: UINT_PTR; - lParam: LONG_PTR; out plResult: LONG_PTR): HResult; -begin - Result := DefaultInterface.OnDefWindowProc(hWnd, msg, wParam, lParam, plResult); -end; - -function TCActiveIMM.FilterClientWindows(var aaClassList: Word; uSize: SYSUINT): HResult; -begin - Result := DefaultInterface.FilterClientWindows(aaClassList, uSize); -end; - -function TCActiveIMM.GetCodePageA(var hKL: Pointer; out uCodePage: SYSUINT): HResult; -begin - Result := DefaultInterface.GetCodePageA(hKL, uCodePage); -end; - -function TCActiveIMM.GetLangId(var hKL: Pointer; out plid: Word): HResult; -begin - Result := DefaultInterface.GetLangId(hKL, plid); -end; - -function TCActiveIMM.AssociateContextEx(var hWnd: _RemotableHandle; hIMC: LongWord; - dwFlags: LongWord): HResult; -begin - Result := DefaultInterface.AssociateContextEx(hWnd, hIMC, dwFlags); -end; - -function TCActiveIMM.DisableIME(idThread: LongWord): HResult; -begin - Result := DefaultInterface.DisableIME(idThread); -end; - -function TCActiveIMM.GetImeMenuItemsA(hIMC: LongWord; dwFlags: LongWord; dwType: LongWord; - var pImeParentMenu: IMEMENUITEMINFOA; - out pImeMenu: IMEMENUITEMINFOA; dwSize: LongWord; - out pdwResult: LongWord): HResult; -begin - Result := DefaultInterface.GetImeMenuItemsA(hIMC, dwFlags, dwType, pImeParentMenu, pImeMenu, - dwSize, pdwResult); -end; - -function TCActiveIMM.GetImeMenuItemsW(hIMC: LongWord; dwFlags: LongWord; dwType: LongWord; - var pImeParentMenu: IMEMENUITEMINFOW; - out pImeMenu: IMEMENUITEMINFOW; dwSize: LongWord; - out pdwResult: LongWord): HResult; -begin - Result := DefaultInterface.GetImeMenuItemsW(hIMC, dwFlags, dwType, pImeParentMenu, pImeMenu, - dwSize, pdwResult); -end; - -function TCActiveIMM.EnumInputContext(idThread: LongWord; out ppEnum: IEnumInputContext): HResult; -begin - Result := DefaultInterface.EnumInputContext(idThread, ppEnum); -end; - -{$IFDEF LIVE_SERVER_AT_DESIGN_TIME} -constructor TCActiveIMMProperties.Create(AServer: TCActiveIMM); -begin - inherited Create; - FServer := AServer; -end; - -function TCActiveIMMProperties.GetDefaultInterface: IActiveIMMApp; -begin - Result := FServer.DefaultInterface; -end; - -{$ENDIF} - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntActnList.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntActnList.pas deleted file mode 100644 index a5d9c9794..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntActnList.pas +++ /dev/null @@ -1,835 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntActnList; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Classes, Controls, ActnList, Buttons, ExtCtrls, ComCtrls, StdCtrls, Menus; - -type -{TNT-WARN TActionList} - TTntActionList = class(TActionList{TNT-ALLOW TActionList}) - private - FCheckActionsTimer: TTimer; - procedure CheckActions(Sender: TObject); - public - constructor Create(AOwner: TComponent); override; - end; - - ITntAction = interface - ['{59D0AE37-8161-4AD6-9102-14B28E5761EB}'] - end; - -//--------------------------------------------------------------------------------------------- -// ACTIONS -//--------------------------------------------------------------------------------------------- - -{TNT-WARN TCustomAction} - TTntCustomAction = class(TCustomAction{TNT-ALLOW TCustomAction}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - public - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TAction} - TTntAction = class(TAction{TNT-ALLOW TAction}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -//--------------------------------------------------------------------------------------------- - -// MENU ACTION LINK -//--------------------------------------------------------------------------------------------- - -{TNT-WARN TMenuActionLink} - TTntMenuActionLink = class(TMenuActionLink{TNT-ALLOW TMenuActionLink}) - protected - function IsCaptionLinked: Boolean; override; - function IsHintLinked: Boolean; override; - procedure SetCaption(const Value: string{TNT-ALLOW string}); override; - procedure SetHint(const Value: string{TNT-ALLOW string}); override; - end; - -//--------------------------------------------------------------------------------------------- -// CONTROL ACTION LINKS -//--------------------------------------------------------------------------------------------- - -{TNT-WARN TListViewActionLink} - TTntListViewActionLink = class(TListViewActionLink{TNT-ALLOW TListViewActionLink}) - protected - function IsCaptionLinked: Boolean; override; - function IsHintLinked: Boolean; override; - procedure SetCaption(const Value: string{TNT-ALLOW string}); override; - procedure SetHint(const Value: string{TNT-ALLOW string}); override; - end; - -{TNT-WARN TComboBoxExActionLink} - TTntComboBoxExActionLink = class(TComboBoxExActionLink{TNT-ALLOW TComboBoxExActionLink}) - protected - function IsCaptionLinked: Boolean; override; - function IsHintLinked: Boolean; override; - procedure SetCaption(const Value: string{TNT-ALLOW string}); override; - procedure SetHint(const Value: string{TNT-ALLOW string}); override; - end; - -{TNT-WARN TSpeedButtonActionLink} - TTntSpeedButtonActionLink = class(TSpeedButtonActionLink{TNT-ALLOW TSpeedButtonActionLink}) - protected - function IsCaptionLinked: Boolean; override; - function IsHintLinked: Boolean; override; - procedure SetCaption(const Value: string{TNT-ALLOW string}); override; - procedure SetHint(const Value: string{TNT-ALLOW string}); override; - {$IFDEF COMPILER_10_UP} - function IsImageIndexLinked: Boolean; override; - procedure SetImageIndex(Value: Integer); override; - {$ENDIF} - end; - -{$IFDEF COMPILER_10_UP} -{TNT-WARN TBitBtnActionLink} - TTntBitBtnActionLink = class(TBitBtnActionLink{TNT-ALLOW TBitBtnActionLink}) - protected - function IsCaptionLinked: Boolean; override; - function IsHintLinked: Boolean; override; - procedure SetCaption(const Value: string{TNT-ALLOW string}); override; - procedure SetHint(const Value: string{TNT-ALLOW string}); override; - {$IFDEF COMPILER_10_UP} - function IsImageIndexLinked: Boolean; override; - procedure SetImageIndex(Value: Integer); override; - {$ENDIF} - end; -{$ENDIF} - -{TNT-WARN TToolButtonActionLink} - TTntToolButtonActionLink = class(TToolButtonActionLink{TNT-ALLOW TToolButtonActionLink}) - protected - function IsCaptionLinked: Boolean; override; - function IsHintLinked: Boolean; override; - procedure SetCaption(const Value: string{TNT-ALLOW string}); override; - procedure SetHint(const Value: string{TNT-ALLOW string}); override; - end; - -{TNT-WARN TButtonActionLink} - TTntButtonActionLink = class(TButtonActionLink{TNT-ALLOW TButtonActionLink}) - protected - function IsCaptionLinked: Boolean; override; - function IsHintLinked: Boolean; override; - procedure SetCaption(const Value: string{TNT-ALLOW string}); override; - procedure SetHint(const Value: string{TNT-ALLOW string}); override; - end; - -{TNT-WARN TWinControlActionLink} - TTntWinControlActionLink = class(TWinControlActionLink{TNT-ALLOW TWinControlActionLink}) - protected - function IsCaptionLinked: Boolean; override; - function IsHintLinked: Boolean; override; - procedure SetCaption(const Value: string{TNT-ALLOW string}); override; - procedure SetHint(const Value: string{TNT-ALLOW string}); override; - end; - -{TNT-WARN TControlActionLink} - TTntControlActionLink = class(TControlActionLink{TNT-ALLOW TControlActionLink}) - protected - function IsCaptionLinked: Boolean; override; - function IsHintLinked: Boolean; override; - procedure SetCaption(const Value: string{TNT-ALLOW string}); override; - procedure SetHint(const Value: string{TNT-ALLOW string}); override; - end; - -//--------------------------------------------------------------------------------------------- -// helper procs -//--------------------------------------------------------------------------------------------- - -//-- TCustomAction helper routines -procedure TntAction_SetCaption(Action: TCustomAction{TNT-ALLOW TCustomAction}; const Value: WideString); -function TntAction_GetCaption(Action: TCustomAction{TNT-ALLOW TCustomAction}): WideString; -function TntAction_GetNewCaption(Action: TCustomAction{TNT-ALLOW TCustomAction}; const Default: WideString): WideString; -procedure TntAction_SetHint(Action: TCustomAction{TNT-ALLOW TCustomAction}; const Value: WideString); -function TntAction_GetHint(Action: TCustomAction{TNT-ALLOW TCustomAction}): WideString; -function TntAction_GetNewHint(Action: TCustomAction{TNT-ALLOW TCustomAction}; const Default: WideString): WideString; -procedure TntAction_AfterInherited_Assign(Action: TCustomAction{TNT-ALLOW TCustomAction}; Source: TPersistent); - -// -- TControl helper routines -function TntControl_GetActionLinkClass(Control: TControl; InheritedLinkClass: TControlActionLinkClass): TControlActionLinkClass; -procedure TntControl_BeforeInherited_ActionChange(Control: TControl; Sender: TObject; CheckDefaults: Boolean); - -// -- TControlActionLink helper routines -function TntActionLink_IsCaptionLinked(InheritedIsCaptionLinked: Boolean; Action: TBasicAction; FClient: TControl): Boolean; -function TntActionLink_IsHintLinked(InheritedIsHintLinked: Boolean; Action: TBasicAction; FClient: TControl): Boolean; -procedure TntActionLink_SetCaption(IsCaptionLinked: Boolean; Action: TBasicAction; FClient: TControl; const Value: string{TNT-ALLOW string}); -procedure TntActionLink_SetHint(IsHintLinked: Boolean; Action: TBasicAction; FClient: TControl; const Value: string{TNT-ALLOW string}); - -type - TUpgradeActionListItemsProc = procedure (ActionList: TTntActionList); - -var - UpgradeActionListItemsProc: TUpgradeActionListItemsProc; - -implementation - -uses - SysUtils, TntMenus, TntClasses, TntControls; - -{ TActionListList } - -type - TActionListList = class(TList) - private - FActionList: TTntActionList; - protected - procedure Notify(Ptr: Pointer; Action: TListNotification); override; - end; - -procedure TActionListList.Notify(Ptr: Pointer; Action: TListNotification); -begin - inherited; - if (Action = lnAdded) and (FActionList <> nil) and (Ptr <> nil) - and (not Supports(TObject(Ptr), ITntAction)) then - begin - FActionList.FCheckActionsTimer.Enabled := False; - FActionList.FCheckActionsTimer.Enabled := True; - end; -end; - -{ THackActionList } - -type -{$IFDEF COMPILER_6} // verified against VCL source in Delphi 6 and BCB 6 - THackCustomActionList = class(TComponent) - private - FActions: TList; - end; -{$ENDIF} -{$IFDEF DELPHI_7} // verified against VCL source in Delphi 7 - THackCustomActionList = class(TComponent) - private - FActions: TList; - end; -{$ENDIF} -{$IFDEF DELPHI_9} // verified against VCL source in Delphi 9 - THackCustomActionList = class(TComponent) - private - FActions: TList; - end; -{$ENDIF} -{$IFDEF DELPHI_10} // verified against VCL source in Delphi 10 - THackCustomActionList = class(TComponent) - private - FActions: TList; - end; -{$ENDIF} - -{ TTntActionList } - -constructor TTntActionList.Create(AOwner: TComponent); -begin - inherited; - if (csDesigning in ComponentState) then begin - FCheckActionsTimer := TTimer.Create(Self); - FCheckActionsTimer.Enabled := False; - FCheckActionsTimer.Interval := 50; - FCheckActionsTimer.OnTimer := CheckActions; - // - THackCustomActionList(Self).FActions.Free; - THackCustomActionList(Self).FActions := TActionListList.Create; - TActionListList(THackCustomActionList(Self).FActions).FActionList := Self; - end; -end; - -procedure TTntActionList.CheckActions(Sender: TObject); -begin - if FCheckActionsTimer <> nil then begin - FCheckActionsTimer.Enabled := False; - end; - Assert(csDesigning in ComponentState); - Assert(Assigned(UpgradeActionListItemsProc)); - UpgradeActionListItemsProc(Self); -end; - -{ TCustomActionHelper } - -type - TCustomActionHelper = class(TComponent) - private - FAction: TCustomAction{TNT-ALLOW TCustomAction}; - private - FCaption: WideString; - FSettingNewCaption: Boolean; - FOldWideCaption: WideString; - FNewAnsiCaption: AnsiString; - procedure SetAnsiCaption(const Value: AnsiString); - function SettingNewCaption: Boolean; - procedure SetCaption(const Value: WideString); - function GetCaption: WideString; - private - FHint: WideString; - FSettingNewHint: Boolean; - FOldWideHint: WideString; - FNewAnsiHint: AnsiString; - procedure SetAnsiHint(const Value: AnsiString); - function SettingNewHint: Boolean; - procedure SetHint(const Value: WideString); - function GetHint: WideString; - end; - -procedure TCustomActionHelper.SetAnsiCaption(const Value: AnsiString); -begin - FAction.Caption := Value; - if (Value = '') and (FNewAnsiCaption <> '') then - FOldWideCaption := ''; -end; - -function TCustomActionHelper.SettingNewCaption: Boolean; -begin - Result := FSettingNewCaption and (FAction.Caption <> FNewAnsiCaption); -end; - -function TCustomActionHelper.GetCaption: WideString; -begin - if SettingNewCaption then - Result := FOldWideCaption - else - Result := GetSyncedWideString(FCaption, FAction.Caption) -end; - -procedure TCustomActionHelper.SetCaption(const Value: WideString); -begin - FOldWideCaption := GetCaption; - FNewAnsiCaption := Value; - FSettingNewCaption := True; - try - SetSyncedWideString(Value, FCaption, FAction.Caption, SetAnsiCaption) - finally - FSettingNewCaption := False; - end; -end; - -procedure TCustomActionHelper.SetAnsiHint(const Value: AnsiString); -begin - FAction.Hint := Value; - if (Value = '') and (FNewAnsiHint <> '') then - FOldWideHint := ''; -end; - -function TCustomActionHelper.SettingNewHint: Boolean; -begin - Result := FSettingNewHint and (FAction.Hint <> FNewAnsiHint); -end; - -function TCustomActionHelper.GetHint: WideString; -begin - if SettingNewHint then - Result := FOldWideHint - else - Result := GetSyncedWideString(FHint, FAction.Hint) -end; - -procedure TCustomActionHelper.SetHint(const Value: WideString); -begin - FOldWideHint := GetHint; - FNewAnsiHint := Value; - FSettingNewHint := True; - try - SetSyncedWideString(Value, FHint, FAction.Hint, SetAnsiHint) - finally - FSettingNewHint := False; - end; -end; - -function FindActionHelper(Action: TCustomAction{TNT-ALLOW TCustomAction}): TCustomActionHelper; -var - i: integer; -begin - Assert(Action <> nil); - Result := nil; - if Supports(Action, ITntAction) then begin - for i := 0 to Action.ComponentCount - 1 do begin - if Action.Components[i] is TCustomActionHelper then begin - Result := TCustomActionHelper(Action.Components[i]); - break; - end; - end; - if Result = nil then begin - Result := TCustomActionHelper.Create(Action); - Result.FAction := Action; - end; - end; -end; - -//-- TCustomAction helper routines - -procedure TntAction_SetCaption(Action: TCustomAction{TNT-ALLOW TCustomAction}; const Value: WideString); -begin - if Supports(Action, ITntAction) then - with FindActionHelper(Action) do - SetCaption(Value) - else - Action.Caption := Value; -end; - -function TntAction_GetCaption(Action: TCustomAction{TNT-ALLOW TCustomAction}): WideString; -begin - if Supports(Action, ITntAction) then - with FindActionHelper(Action) do - Result := GetCaption - else - Result := Action.Caption; -end; - -function TntAction_GetNewCaption(Action: TCustomAction{TNT-ALLOW TCustomAction}; const Default: WideString): WideString; -begin - Result := Default; - if Supports(Action, ITntAction) then - with FindActionHelper(Action) do - if SettingNewCaption then - Result := FCaption; -end; - -procedure TntAction_SetHint(Action: TCustomAction{TNT-ALLOW TCustomAction}; const Value: WideString); -begin - if Supports(Action, ITntAction) then - with FindActionHelper(Action) do - SetHint(Value) - else - Action.Hint := Value; -end; - -function TntAction_GetHint(Action: TCustomAction{TNT-ALLOW TCustomAction}): WideString; -begin - if Supports(Action, ITntAction) then - with FindActionHelper(Action) do - Result := GetHint - else - Result := Action.Hint; -end; - -function TntAction_GetNewHint(Action: TCustomAction{TNT-ALLOW TCustomAction}; const Default: WideString): WideString; -begin - Result := Default; - if Supports(Action, ITntAction) then - with FindActionHelper(Action) do - if SettingNewHint then - Result := FHint; -end; - -procedure TntAction_AfterInherited_Assign(Action: TCustomAction{TNT-ALLOW TCustomAction}; Source: TPersistent); -begin - with Action do begin - if (Source is TCustomAction{TNT-ALLOW TCustomAction}) then begin - Caption := TntAction_GetCaption(Source as TCustomAction{TNT-ALLOW TCustomAction}); - Hint := TntAction_GetHint(Source as TCustomAction{TNT-ALLOW TCustomAction}); - end else if (Source is TControl) then begin - Caption := TntControl_GetText(Source as TControl); - Hint := TntControl_GetHint(Source as TControl); - end; - end; -end; - -// -- TControl helper routines - -function TntControl_GetActionLinkClass(Control: TControl; InheritedLinkClass: TControlActionLinkClass): TControlActionLinkClass; -begin - if Control is TCustomListView{TNT-ALLOW TCustomListView} then - Result := TTntListViewActionLink - else if Control is TComboBoxEx then - Result := TTntComboBoxExActionLink - else if Control is TSpeedButton{TNT-ALLOW TSpeedButton} then - Result := TTntSpeedButtonActionLink - {$IFDEF COMPILER_10_UP} - else if Control is TBitBtn{TNT-ALLOW TBitBtn} then - Result := TTntBitBtnActionLink - {$ENDIF} - else if Control is TToolButton{TNT-ALLOW TToolButton} then - Result := TTntToolButtonActionLink - else if Control is TButtonControl then - Result := TTntButtonActionLink - else if Control is TWinControl then - Result := TTntWinControlActionLink - else - Result := TTntControlActionLink; - - Assert(Result.ClassParent = InheritedLinkClass); -end; - -procedure TntControl_BeforeInherited_ActionChange(Control: TControl; Sender: TObject; CheckDefaults: Boolean); -begin - if (Sender is TCustomAction{TNT-ALLOW TCustomAction}) and Supports(Sender, ITntAction) then begin - if not CheckDefaults or (TntControl_GetText(Control) = '') or (TntControl_GetText(Control) = Control.Name) then - TntControl_SetText(Control, TntAction_GetCaption(TCustomAction{TNT-ALLOW TCustomAction}(Sender))); - if not CheckDefaults or (TntControl_GetHint(Control) = '') then - TntControl_SetHint(Control, TntAction_GetHint(TCustomAction{TNT-ALLOW TCustomAction}(Sender))); - end; -end; - -// -- TControlActionLink helper routines - -function TntActionLink_IsCaptionLinked(InheritedIsCaptionLinked: Boolean; Action: TBasicAction; FClient: TControl): Boolean; -begin - Result := InheritedIsCaptionLinked - and (TntAction_GetCaption(Action as TCustomAction{TNT-ALLOW TCustomAction}) = TntControl_GetText(FClient)); -end; - -function TntActionLink_IsHintLinked(InheritedIsHintLinked: Boolean; Action: TBasicAction; FClient: TControl): Boolean; -begin - Result := InheritedIsHintLinked - and (TntAction_GetHint(Action as TCustomAction{TNT-ALLOW TCustomAction}) = TntControl_GetHint(FClient)); -end; - -procedure TntActionLink_SetCaption(IsCaptionLinked: Boolean; Action: TBasicAction; FClient: TControl; const Value: string{TNT-ALLOW string}); -begin - if IsCaptionLinked then - TntControl_SetText(FClient, TntAction_GetNewCaption(Action as TCustomAction{TNT-ALLOW TCustomAction}, Value)); -end; - -procedure TntActionLink_SetHint(IsHintLinked: Boolean; Action: TBasicAction; FClient: TControl; const Value: string{TNT-ALLOW string}); -begin - if IsHintLinked then - TntControl_SetHint(FClient, TntAction_GetNewHint(Action as TCustomAction{TNT-ALLOW TCustomAction}, Value)); -end; - -//--------------------------------------------------------------------------------------------- -// ACTIONS -//--------------------------------------------------------------------------------------------- - -{ TTntCustomAction } - -procedure TTntCustomAction.Assign(Source: TPersistent); -begin - inherited; - TntAction_AfterInherited_Assign(Self, Source); -end; - -procedure TTntCustomAction.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntCustomAction.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntCustomAction.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntCustomAction.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntCustomAction.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntAction } - -procedure TTntAction.Assign(Source: TPersistent); -begin - inherited; - TntAction_AfterInherited_Assign(Self, Source); -end; - -procedure TTntAction.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntAction.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntAction.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntAction.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntAction.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -//--------------------------------------------------------------------------------------------- -// MENU ACTION LINK -//--------------------------------------------------------------------------------------------- - -{ TTntMenuActionLink } - -function TTntMenuActionLink.IsCaptionLinked: Boolean; -begin - Result := inherited IsCaptionLinked - and WideSameCaption(TntAction_GetCaption(Action as TCustomAction{TNT-ALLOW TCustomAction}), (FClient as TTntMenuItem).Caption); -end; - -function TTntMenuActionLink.IsHintLinked: Boolean; -begin - Result := inherited IsHintLinked - and (TntAction_GetHint(Action as TCustomAction{TNT-ALLOW TCustomAction}) = (FClient as TTntMenuItem).Hint); -end; - -procedure TTntMenuActionLink.SetCaption(const Value: string{TNT-ALLOW string}); -begin - if IsCaptionLinked then - (FClient as TTntMenuItem).Caption := TntAction_GetNewCaption(Action as TCustomAction{TNT-ALLOW TCustomAction}, Value); -end; - -procedure TTntMenuActionLink.SetHint(const Value: string{TNT-ALLOW string}); -begin - if IsHintLinked then - (FClient as TTntMenuItem).Hint := TntAction_GetNewHint(Action as TCustomAction{TNT-ALLOW TCustomAction}, Value); -end; - -//--------------------------------------------------------------------------------------------- -// CONTROL ACTION LINKS -//--------------------------------------------------------------------------------------------- - -{ TTntListViewActionLink } - -function TTntListViewActionLink.IsCaptionLinked: Boolean; -begin - Result := TntActionLink_IsCaptionLinked(inherited IsCaptionLinked, Action, FClient); -end; - -function TTntListViewActionLink.IsHintLinked: Boolean; -begin - Result := TntActionLink_IsHintLinked(inherited IsHintLinked, Action, FClient); -end; - -procedure TTntListViewActionLink.SetCaption(const Value: string{TNT-ALLOW string}); -begin - TntActionLink_SetCaption(IsCaptionLinked, Action, FClient, Value); -end; - -procedure TTntListViewActionLink.SetHint(const Value: string{TNT-ALLOW string}); -begin - TntActionLink_SetHint(IsHintLinked, Action, FClient, Value); -end; - -{ TTntComboBoxExActionLink } - -function TTntComboBoxExActionLink.IsCaptionLinked: Boolean; -begin - Result := TntActionLink_IsCaptionLinked(inherited IsCaptionLinked, Action, FClient); -end; - -function TTntComboBoxExActionLink.IsHintLinked: Boolean; -begin - Result := TntActionLink_IsHintLinked(inherited IsHintLinked, Action, FClient); -end; - -procedure TTntComboBoxExActionLink.SetCaption(const Value: string{TNT-ALLOW string}); -begin - TntActionLink_SetCaption(IsCaptionLinked, Action, FClient, Value); -end; - -procedure TTntComboBoxExActionLink.SetHint(const Value: string{TNT-ALLOW string}); -begin - TntActionLink_SetHint(IsHintLinked, Action, FClient, Value); -end; - -{ TTntSpeedButtonActionLink } - -function TTntSpeedButtonActionLink.IsCaptionLinked: Boolean; -begin - Result := TntActionLink_IsCaptionLinked(inherited IsCaptionLinked, Action, FClient); -end; - -function TTntSpeedButtonActionLink.IsHintLinked: Boolean; -begin - Result := TntActionLink_IsHintLinked(inherited IsHintLinked, Action, FClient); -end; - -procedure TTntSpeedButtonActionLink.SetCaption(const Value: string{TNT-ALLOW string}); -begin - TntActionLink_SetCaption(IsCaptionLinked, Action, FClient, Value); -end; - -procedure TTntSpeedButtonActionLink.SetHint(const Value: string{TNT-ALLOW string}); -begin - TntActionLink_SetHint(IsHintLinked, Action, FClient, Value); -end; - -{$IFDEF COMPILER_10_UP} -// bug fix for VCL where ImageIndex on Action ALWAYS overrides the Glyph. - -function TTntSpeedButtonActionLink.IsImageIndexLinked: Boolean; -begin - Result := Action is TCustomAction{TNT-ALLOW TCustomAction}; // taken from TActionLink.IsImageIndexLinked -end; - -procedure TTntSpeedButtonActionLink.SetImageIndex(Value: Integer); -begin - ; // taken from TActionLink.IsImageIndexLinked -end; -{$ENDIF} - -{$IFDEF COMPILER_10_UP} -{ TTntBitBtnActionLink } - -function TTntBitBtnActionLink.IsCaptionLinked: Boolean; -begin - Result := TntActionLink_IsCaptionLinked(inherited IsCaptionLinked, Action, FClient); -end; - -function TTntBitBtnActionLink.IsHintLinked: Boolean; -begin - Result := TntActionLink_IsHintLinked(inherited IsHintLinked, Action, FClient); -end; - -procedure TTntBitBtnActionLink.SetCaption(const Value: string{TNT-ALLOW string}); -begin - TntActionLink_SetCaption(IsCaptionLinked, Action, FClient, Value); -end; - -procedure TTntBitBtnActionLink.SetHint(const Value: string{TNT-ALLOW string}); -begin - TntActionLink_SetHint(IsHintLinked, Action, FClient, Value); -end; - -{$IFDEF COMPILER_10_UP} -// bug fix for VCL where ImageIndex on Action ALWAYS overrides the Glyph. - -function TTntBitBtnActionLink.IsImageIndexLinked: Boolean; -begin - Result := Action is TCustomAction{TNT-ALLOW TCustomAction}; // taken from TActionLink.IsImageIndexLinked -end; - -procedure TTntBitBtnActionLink.SetImageIndex(Value: Integer); -begin - ; // taken from TActionLink.IsImageIndexLinked -end; -{$ENDIF} - -{$ENDIF} - -{ TTntToolButtonActionLink } - -function TTntToolButtonActionLink.IsCaptionLinked: Boolean; -begin - Result := TntActionLink_IsCaptionLinked(inherited IsCaptionLinked, Action, FClient); -end; - -function TTntToolButtonActionLink.IsHintLinked: Boolean; -begin - Result := TntActionLink_IsHintLinked(inherited IsHintLinked, Action, FClient); -end; - -procedure TTntToolButtonActionLink.SetCaption(const Value: string{TNT-ALLOW string}); -begin - TntActionLink_SetCaption(IsCaptionLinked, Action, FClient, Value); -end; - -procedure TTntToolButtonActionLink.SetHint(const Value: string{TNT-ALLOW string}); -begin - TntActionLink_SetHint(IsHintLinked, Action, FClient, Value); -end; - -{ TTntButtonActionLink } - -function TTntButtonActionLink.IsCaptionLinked: Boolean; -begin - Result := TntActionLink_IsCaptionLinked(inherited IsCaptionLinked, Action, FClient); -end; - -function TTntButtonActionLink.IsHintLinked: Boolean; -begin - Result := TntActionLink_IsHintLinked(inherited IsHintLinked, Action, FClient); -end; - -procedure TTntButtonActionLink.SetCaption(const Value: string{TNT-ALLOW string}); -begin - TntActionLink_SetCaption(IsCaptionLinked, Action, FClient, Value); -end; - -procedure TTntButtonActionLink.SetHint(const Value: string{TNT-ALLOW string}); -begin - TntActionLink_SetHint(IsHintLinked, Action, FClient, Value); -end; - -{ TTntWinControlActionLink } - -function TTntWinControlActionLink.IsCaptionLinked: Boolean; -begin - Result := TntActionLink_IsCaptionLinked(inherited IsCaptionLinked, Action, FClient); -end; - -function TTntWinControlActionLink.IsHintLinked: Boolean; -begin - Result := TntActionLink_IsHintLinked(inherited IsHintLinked, Action, FClient); -end; - -procedure TTntWinControlActionLink.SetCaption(const Value: string{TNT-ALLOW string}); -begin - TntActionLink_SetCaption(IsCaptionLinked, Action, FClient, Value); -end; - -procedure TTntWinControlActionLink.SetHint(const Value: string{TNT-ALLOW string}); -begin - TntActionLink_SetHint(IsHintLinked, Action, FClient, Value); -end; - -{ TTntControlActionLink } - -function TTntControlActionLink.IsCaptionLinked: Boolean; -begin - Result := TntActionLink_IsCaptionLinked(inherited IsCaptionLinked, Action, FClient); -end; - -function TTntControlActionLink.IsHintLinked: Boolean; -begin - Result := TntActionLink_IsHintLinked(inherited IsHintLinked, Action, FClient); -end; - -procedure TTntControlActionLink.SetCaption(const Value: string{TNT-ALLOW string}); -begin - TntActionLink_SetCaption(IsCaptionLinked, Action, FClient, Value); -end; - -procedure TTntControlActionLink.SetHint(const Value: string{TNT-ALLOW string}); -begin - TntActionLink_SetHint(IsHintLinked, Action, FClient, Value); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntAxCtrls.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntAxCtrls.pas deleted file mode 100644 index 5363b66ad..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntAxCtrls.pas +++ /dev/null @@ -1,191 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntAxCtrls; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - ComObj, StdVcl, - {$IFNDEF COMPILER_10_UP} - TntWideStrings, - {$ELSE} - WideStrings, - {$ENDIF} - TntClasses; - -type - TWideStringsAdapter = class(TAutoIntfObject, IStrings, IWideStringsAdapter) - private - FStrings: TWideStrings; - protected - { IWideStringsAdapter } - procedure ReferenceStrings(S: TWideStrings); - procedure ReleaseStrings; - { IStrings } - function Get_ControlDefault(Index: Integer): OleVariant; safecall; - procedure Set_ControlDefault(Index: Integer; Value: OleVariant); safecall; - function Count: Integer; safecall; - function Get_Item(Index: Integer): OleVariant; safecall; - procedure Set_Item(Index: Integer; Value: OleVariant); safecall; - procedure Remove(Index: Integer); safecall; - procedure Clear; safecall; - function Add(Item: OleVariant): Integer; safecall; - function _NewEnum: IUnknown; safecall; - public - constructor Create(Strings: TTntStrings); - end; - -implementation - -uses - Classes, ActiveX, Variants; - -{ TStringsEnumerator } - -type - TStringsEnumerator = class(TContainedObject, IEnumString) - private - FIndex: Integer; // index of next unread string - FStrings: IStrings; - public - constructor Create(const Strings: IStrings); - function Next(celt: Longint; out elt; - pceltFetched: PLongint): HResult; stdcall; - function Skip(celt: Longint): HResult; stdcall; - function Reset: HResult; stdcall; - function Clone(out enm: IEnumString): HResult; stdcall; - end; - -constructor TStringsEnumerator.Create(const Strings: IStrings); -begin - inherited Create(Strings); - FStrings := Strings; -end; - -function TStringsEnumerator.Next(celt: Longint; out elt; pceltFetched: PLongint): HResult; -var - I: Integer; -begin - I := 0; - while (I < celt) and (FIndex < FStrings.Count) do - begin - TPointerList(elt)[I] := PWideChar(WideString(FStrings.Item[FIndex])); - Inc(I); - Inc(FIndex); - end; - if pceltFetched <> nil then pceltFetched^ := I; - if I = celt then Result := S_OK else Result := S_FALSE; -end; - -function TStringsEnumerator.Skip(celt: Longint): HResult; -begin - if (FIndex + celt) <= FStrings.Count then - begin - Inc(FIndex, celt); - Result := S_OK; - end - else - begin - FIndex := FStrings.Count; - Result := S_FALSE; - end; -end; - -function TStringsEnumerator.Reset: HResult; -begin - FIndex := 0; - Result := S_OK; -end; - -function TStringsEnumerator.Clone(out enm: IEnumString): HResult; -begin - try - enm := TStringsEnumerator.Create(FStrings); - TStringsEnumerator(enm).FIndex := FIndex; - Result := S_OK; - except - Result := E_UNEXPECTED; - end; -end; - -{ TWideStringsAdapter } - -constructor TWideStringsAdapter.Create(Strings: TTntStrings); -var - StdVcl: ITypeLib; -begin - OleCheck(LoadRegTypeLib(LIBID_STDVCL, 4, 0, 0, StdVcl)); - inherited Create(StdVcl, IStrings); - FStrings := Strings; -end; - -procedure TWideStringsAdapter.ReferenceStrings(S: TWideStrings); -begin - FStrings := S; -end; - -procedure TWideStringsAdapter.ReleaseStrings; -begin - FStrings := nil; -end; - -function TWideStringsAdapter.Get_ControlDefault(Index: Integer): OleVariant; -begin - Result := Get_Item(Index); -end; - -procedure TWideStringsAdapter.Set_ControlDefault(Index: Integer; Value: OleVariant); -begin - Set_Item(Index, Value); -end; - -function TWideStringsAdapter.Count: Integer; -begin - Result := 0; - if FStrings <> nil then Result := FStrings.Count; -end; - -function TWideStringsAdapter.Get_Item(Index: Integer): OleVariant; -begin - Result := NULL; - if (FStrings <> nil) then Result := WideString(FStrings[Index]); -end; - -procedure TWideStringsAdapter.Set_Item(Index: Integer; Value: OleVariant); -begin - if (FStrings <> nil) then FStrings[Index] := Value; -end; - -procedure TWideStringsAdapter.Remove(Index: Integer); -begin - if FStrings <> nil then FStrings.Delete(Index); -end; - -procedure TWideStringsAdapter.Clear; -begin - if FStrings <> nil then FStrings.Clear; -end; - -function TWideStringsAdapter.Add(Item: OleVariant): Integer; -begin - Result := -1; - if FStrings <> nil then Result := FStrings.Add(Item); -end; - -function TWideStringsAdapter._NewEnum: IUnknown; -begin - Result := TStringsEnumerator.Create(Self); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntBandActn.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntBandActn.pas deleted file mode 100644 index 28c496b60..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntBandActn.pas +++ /dev/null @@ -1,92 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntBandActn; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Classes, BandActn, TntActnList; - -type -{TNT-WARN TCustomizeActionBars} - TTntCustomizeActionBars = class(TCustomizeActionBars{TNT-ALLOW TCustomizeActionBars}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -implementation - -uses - ActnList, TntClasses; - -{TNT-IGNORE-UNIT} - -procedure TntBandActn_AfterInherited_Assign(Action: TCustomAction{TNT-ALLOW TCustomAction}; Source: TPersistent); -begin - TntAction_AfterInherited_Assign(Action, Source); - // TCustomizeActionBars - if (Action is TCustomizeActionBars) and (Source is TCustomizeActionBars) then begin - TCustomizeActionBars(Action).ActionManager := TCustomizeActionBars(Source).ActionManager; - end; -end; - -//------------------------- -// TNT BAND ACTN -//------------------------- - -{ TTntCustomizeActionBars } - -procedure TTntCustomizeActionBars.Assign(Source: TPersistent); -begin - inherited; - TntBandActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntCustomizeActionBars.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntCustomizeActionBars.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntCustomizeActionBars.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntCustomizeActionBars.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntCustomizeActionBars.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntButtons.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntButtons.pas deleted file mode 100644 index 1adfbc6d3..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntButtons.pas +++ /dev/null @@ -1,982 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntButtons; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Windows, Messages, Classes, Controls, Graphics, StdCtrls, - ExtCtrls, CommCtrl, Buttons, - TntControls; - -type - ITntGlyphButton = interface - ['{15D7E501-1E33-4293-8B45-716FB3B14504}'] - function GetButtonGlyph: Pointer; - procedure UpdateInternalGlyphList; - end; - -{TNT-WARN TSpeedButton} - TTntSpeedButton = class(TSpeedButton {TNT-ALLOW TSpeedButton}, ITntGlyphButton) - private - FPaintInherited: Boolean; - function GetCaption: TWideCaption; - procedure SetCaption(const Value: TWideCaption); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsCaptionStored: Boolean; - function IsHintStored: Boolean; - procedure CMHintShow(var Message: TMessage); message CM_HINTSHOW; - procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR; - protected - function GetButtonGlyph: Pointer; - procedure UpdateInternalGlyphList; dynamic; - procedure PaintButton; dynamic; - procedure Paint; override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - published - property Caption: TWideCaption read GetCaption write SetCaption stored IsCaptionStored; - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TBitBtn} - TTntBitBtn = class(TBitBtn {TNT-ALLOW TBitBtn}, ITntGlyphButton) - private - FPaintInherited: Boolean; - FMouseInControl: Boolean; - function IsCaptionStored: Boolean; - function GetCaption: TWideCaption; - procedure SetCaption(const Value: TWideCaption); - function IsHintStored: Boolean; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR; - procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM; - procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER; - procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE; - protected - function GetButtonGlyph: Pointer; - procedure UpdateInternalGlyphList; dynamic; - procedure DrawItem(const DrawItemStruct: TDrawItemStruct); dynamic; - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - published - property Caption: TWideCaption read GetCaption write SetCaption stored IsCaptionStored; - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -procedure TButtonGlyph_CalcButtonLayout(Control: TControl; DC: HDC; const Client: TRect; - const Offset: TPoint; const Caption: WideString; Layout: TButtonLayout; - Margin, Spacing: Integer; var GlyphPos: TPoint; var TextBounds: TRect; - BiDiFlags: Integer {$IFDEF COMPILER_7_UP}; WordWrap: Boolean {$ENDIF}); - -function TButtonGlyph_Draw(Control: TControl; Canvas: TCanvas; const Client: TRect; - const Offset: TPoint; const Caption: WideString; Layout: TButtonLayout; Margin: Integer; - Spacing: Integer; State: TButtonState; Transparent: Boolean; - BiDiFlags: Longint {$IFDEF COMPILER_7_UP}; WordWrap: Boolean {$ENDIF}): TRect; - -implementation - -uses - SysUtils, ActnList, TntForms, TntStdCtrls, TypInfo, RTLConsts, TntWindows, - {$IFDEF THEME_7_UP} Themes, {$ENDIF} TntClasses, TntActnList, TntSysUtils; - -type - EAbortPaint = class(EAbort); - -// Many routines in this unit are nearly the same as those found in Buttons.pas. They are -// included here because the VCL implementation of TButtonGlyph is completetly inaccessible. - -type - THackButtonGlyph_D6_D7_D9 = class - protected - FOriginal: TBitmap; - FGlyphList: TImageList; - FIndexs: array[TButtonState] of Integer; - FxxxxTransparentColor: TColor; - FNumGlyphs: TNumGlyphs; - end; - - THackBitBtn_D6_D7_D9 = class(TButton{TNT-ALLOW TButton}) - protected - FCanvas: TCanvas; - FGlyph: Pointer; - FxxxxStyle: TButtonStyle; - FxxxxKind: TBitBtnKind; - FxxxxLayout: TButtonLayout; - FxxxxSpacing: Integer; - FxxxxMargin: Integer; - IsFocused: Boolean; - end; - - THackSpeedButton_D6_D7_D9 = class(TGraphicControl) - protected - FxxxxGroupIndex: Integer; - FGlyph: Pointer; - FxxxxDown: Boolean; - FDragging: Boolean; - end; - - {$IFDEF COMPILER_6} // verified against VCL source in Delphi 6 and BCB 6 - THackButtonGlyph = THackButtonGlyph_D6_D7_D9; - THackBitBtn = THackBitBtn_D6_D7_D9; - THackSpeedButton = THackSpeedButton_D6_D7_D9; - {$ENDIF} - {$IFDEF DELPHI_7} // verified against VCL source in Delphi 7 - THackButtonGlyph = THackButtonGlyph_D6_D7_D9; - THackBitBtn = THackBitBtn_D6_D7_D9; - THackSpeedButton = THackSpeedButton_D6_D7_D9; - {$ENDIF} - {$IFDEF DELPHI_9} // verified against VCL source in Delphi 9 - THackButtonGlyph = THackButtonGlyph_D6_D7_D9; - THackBitBtn = THackBitBtn_D6_D7_D9; - THackSpeedButton = THackSpeedButton_D6_D7_D9; - {$ENDIF} - {$IFDEF DELPHI_10} // verified against VCL source in Delphi 10 - THackButtonGlyph = THackButtonGlyph_D6_D7_D9; - THackBitBtn = THackBitBtn_D6_D7_D9; - THackSpeedButton = THackSpeedButton_D6_D7_D9; - {$ENDIF} - -function GetButtonGlyph(Control: TControl): THackButtonGlyph; -var - GlyphButton: ITntGlyphButton; -begin - if Control.GetInterface(ITntGlyphButton, GlyphButton) then - Result := GlyphButton.GetButtonGlyph - else - raise ETntInternalError.Create('Internal Error: Control does not support ITntGlyphButton.'); -end; - -procedure UpdateInternalGlyphList(Control: TControl); -var - GlyphButton: ITntGlyphButton; -begin - if Control.GetInterface(ITntGlyphButton, GlyphButton) then - GlyphButton.UpdateInternalGlyphList - else - raise ETntInternalError.Create('Internal Error: Control does not support ITntGlyphButton.'); -end; - -function TButtonGlyph_CreateButtonGlyph(Control: TControl; State: TButtonState): Integer; -var - ButtonGlyph: THackButtonGlyph; - NumGlyphs: Integer; -begin - ButtonGlyph := GetButtonGlyph(Control); - NumGlyphs := ButtonGlyph.FNumGlyphs; - - if (State = bsDown) and (NumGlyphs < 3) then State := bsUp; - Result := ButtonGlyph.FIndexs[State]; - if (Result = -1) then begin - UpdateInternalGlyphList(Control); - Result := ButtonGlyph.FIndexs[State]; - end; -end; - -procedure TButtonGlyph_DrawButtonGlyph(Control: TControl; Canvas: TCanvas; const GlyphPos: TPoint; - State: TButtonState; Transparent: Boolean); -var - ButtonGlyph: THackButtonGlyph; - Glyph: TBitmap; - GlyphList: TImageList; - Index: Integer; - {$IFDEF THEME_7_UP} - Details: TThemedElementDetails; - R: TRect; - Button: TThemedButton; - {$ENDIF} -begin - ButtonGlyph := GetButtonGlyph(Control); - Glyph := ButtonGlyph.FOriginal; - GlyphList := ButtonGlyph.FGlyphList; - if Glyph = nil then Exit; - if (Glyph.Width = 0) or (Glyph.Height = 0) then Exit; - Index := TButtonGlyph_CreateButtonGlyph(Control, State); - with GlyphPos do - {$IFDEF THEME_7_UP} - if ThemeServices.ThemesEnabled then begin - R.TopLeft := GlyphPos; - R.Right := R.Left + Glyph.Width div ButtonGlyph.FNumGlyphs; - R.Bottom := R.Top + Glyph.Height; - case State of - bsDisabled: - Button := tbPushButtonDisabled; - bsDown, - bsExclusive: - Button := tbPushButtonPressed; - else - // bsUp - Button := tbPushButtonNormal; - end; - Details := ThemeServices.GetElementDetails(Button); - ThemeServices.DrawIcon(Canvas.Handle, Details, R, GlyphList.Handle, Index); - end else - {$ENDIF} - if Transparent or (State = bsExclusive) then - ImageList_DrawEx(GlyphList.Handle, Index, Canvas.Handle, X, Y, 0, 0, - clNone, clNone, ILD_Transparent) - else - ImageList_DrawEx(GlyphList.Handle, Index, Canvas.Handle, X, Y, 0, 0, - ColorToRGB(clBtnFace), clNone, ILD_Normal); -end; - -procedure TButtonGlyph_DrawButtonText(Canvas: TCanvas; const Caption: WideString; - TextBounds: TRect; State: TButtonState; - BiDiFlags: LongInt {$IFDEF COMPILER_7_UP}; WordWrap: Boolean {$ENDIF}); -begin - with Canvas do - begin - Brush.Style := bsClear; - if State = bsDisabled then - begin - OffsetRect(TextBounds, 1, 1); - Font.Color := clBtnHighlight; - - {$IFDEF COMPILER_7_UP} - if WordWrap then - Tnt_DrawTextW(Handle, PWideChar(Caption), Length(Caption), TextBounds, - DT_CENTER or DT_VCENTER or BiDiFlags or DT_WORDBREAK) - else - {$ENDIF} - Tnt_DrawTextW(Handle, PWideChar(Caption), Length(Caption), TextBounds, - DT_CENTER or DT_VCENTER or BiDiFlags); - - OffsetRect(TextBounds, -1, -1); - Font.Color := clBtnShadow; - - {$IFDEF COMPILER_7_UP} - if WordWrap then - Tnt_DrawTextW(Handle, PWideChar(Caption), Length(Caption), TextBounds, - DT_CENTER or DT_WORDBREAK or BiDiFlags) { TODO: Figure out why DT_VCENTER is not used } - else - {$ENDIF} - Tnt_DrawTextW(Handle, PWideChar(Caption), Length(Caption), TextBounds, - DT_CENTER or DT_VCENTER or BiDiFlags); - - end else - begin - {$IFDEF COMPILER_7_UP} - if WordWrap then - Tnt_DrawTextW(Handle, PWideChar(Caption), Length(Caption), TextBounds, - DT_CENTER or DT_WORDBREAK or BiDiFlags) { TODO: Figure out why DT_VCENTER is not used } - else - {$ENDIF} - Tnt_DrawTextW(Handle, PWideChar(Caption), Length(Caption), TextBounds, - DT_CENTER or DT_VCENTER or BiDiFlags); - end; - end; -end; - -procedure TButtonGlyph_CalcButtonLayout(Control: TControl; DC: HDC; const Client: TRect; - const Offset: TPoint; const Caption: WideString; Layout: TButtonLayout; - Margin, Spacing: Integer; var GlyphPos: TPoint; var TextBounds: TRect; - BiDiFlags: Integer {$IFDEF COMPILER_7_UP}; WordWrap: Boolean {$ENDIF}); -var - TextPos: TPoint; - ClientSize, - GlyphSize, - TextSize: TPoint; - TotalSize: TPoint; - Glyph: TBitmap; - NumGlyphs: Integer; - ButtonGlyph: THackButtonGlyph; -begin - ButtonGlyph := GetButtonGlyph(Control); - Glyph := ButtonGlyph.FOriginal; - NumGlyphs := ButtonGlyph.FNumGlyphs; - - if (BiDiFlags and DT_RIGHT) = DT_RIGHT then - if Layout = blGlyphLeft then - Layout := blGlyphRight - else - if Layout = blGlyphRight then - Layout := blGlyphLeft; - - // Calculate the item sizes. - ClientSize := Point(Client.Right - Client.Left, Client.Bottom - Client.Top); - - if Assigned(Glyph) then - GlyphSize := Point(Glyph.Width div NumGlyphs, Glyph.Height) - else - GlyphSize := Point(0, 0); - - if Length(Caption) > 0 then - begin - {$IFDEF COMPILER_7_UP} - TextBounds := Rect(0, 0, Client.Right - Client.Left - GlyphSize.X - 3, 0); { TODO: Figure out why GlyphSize.X is in here. } - {$ELSE} - TextBounds := Rect(0, 0, Client.Right - Client.Left, 0); - {$ENDIF} - - {$IFDEF COMPILER_7_UP} - if WordWrap then - Tnt_DrawTextW(DC, PWideChar(Caption), Length(Caption), TextBounds, DT_WORDBREAK - or DT_CALCRECT or BiDiFlags) - else - {$ENDIF} - Tnt_DrawTextW(DC, PWideChar(Caption), Length(Caption), TextBounds, DT_CALCRECT or BiDiFlags); - - TextSize := Point(TextBounds.Right - TextBounds.Left, TextBounds.Bottom - TextBounds.Top); - end - else - begin - TextBounds := Rect(0, 0, 0, 0); - TextSize := Point(0, 0); - end; - - // If the layout has the glyph on the right or the left, then both the text and the glyph are centered vertically. - // If the glyph is on the top or the bottom, then both the text and the glyph are centered horizontally. - if Layout in [blGlyphLeft, blGlyphRight] then - begin - GlyphPos.Y := (ClientSize.Y - GlyphSize.Y + 1) div 2; - TextPos.Y := (ClientSize.Y - TextSize.Y + 1) div 2; - end - else - begin - GlyphPos.X := (ClientSize.X - GlyphSize.X + 1) div 2; - TextPos.X := (ClientSize.X - TextSize.X + 1) div 2; - end; - - // If there is no text or no bitmap, then Spacing is irrelevant. - if (TextSize.X = 0) or (GlyphSize.X = 0) then - Spacing := 0; - - // Adjust Margin and Spacing. - if Margin = -1 then - begin - if Spacing = -1 then - begin - TotalSize := Point(GlyphSize.X + TextSize.X, GlyphSize.Y + TextSize.Y); - if Layout in [blGlyphLeft, blGlyphRight] then - Margin := (ClientSize.X - TotalSize.X) div 3 - else - Margin := (ClientSize.Y - TotalSize.Y) div 3; - Spacing := Margin; - end - else - begin - TotalSize := Point(GlyphSize.X + Spacing + TextSize.X, GlyphSize.Y + Spacing + TextSize.Y); - if Layout in [blGlyphLeft, blGlyphRight] then - Margin := (ClientSize.X - TotalSize.X + 1) div 2 - else - Margin := (ClientSize.Y - TotalSize.Y + 1) div 2; - end; - end - else - begin - if Spacing = -1 then - begin - TotalSize := Point(ClientSize.X - (Margin + GlyphSize.X), ClientSize.Y - (Margin + GlyphSize.Y)); - if Layout in [blGlyphLeft, blGlyphRight] then - Spacing := (TotalSize.X - TextSize.X) div 2 - else - Spacing := (TotalSize.Y - TextSize.Y) div 2; - end; - end; - - case Layout of - blGlyphLeft: - begin - GlyphPos.X := Margin; - TextPos.X := GlyphPos.X + GlyphSize.X + Spacing; - end; - blGlyphRight: - begin - GlyphPos.X := ClientSize.X - Margin - GlyphSize.X; - TextPos.X := GlyphPos.X - Spacing - TextSize.X; - end; - blGlyphTop: - begin - GlyphPos.Y := Margin; - TextPos.Y := GlyphPos.Y + GlyphSize.Y + Spacing; - end; - blGlyphBottom: - begin - GlyphPos.Y := ClientSize.Y - Margin - GlyphSize.Y; - TextPos.Y := GlyphPos.Y - Spacing - TextSize.Y; - end; - end; - - // Fixup the Result variables. - with GlyphPos do - begin - Inc(X, Client.Left + Offset.X); - Inc(Y, Client.Top + Offset.Y); - end; - - {$IFDEF THEME_7_UP} - { Themed text is not shifted, but gets a different color. } - if ThemeServices.ThemesEnabled then - OffsetRect(TextBounds, TextPos.X + Client.Left, TextPos.Y + Client.Top) - else - {$ENDIF} - OffsetRect(TextBounds, TextPos.X + Client.Left + Offset.X, TextPos.Y + Client.Top + Offset.Y); -end; - -function TButtonGlyph_Draw(Control: TControl; Canvas: TCanvas; const Client: TRect; - const Offset: TPoint; const Caption: WideString; Layout: TButtonLayout; Margin: Integer; - Spacing: Integer; State: TButtonState; Transparent: Boolean; - BiDiFlags: Longint {$IFDEF COMPILER_7_UP}; WordWrap: Boolean {$ENDIF}): TRect; -var - GlyphPos: TPoint; -begin - TButtonGlyph_CalcButtonLayout(Control, Canvas.Handle, Client, Offset, Caption, Layout, Margin, - Spacing, GlyphPos, Result, BiDiFlags {$IFDEF COMPILER_7_UP}, WordWrap {$ENDIF}); - TButtonGlyph_DrawButtonGlyph(Control, Canvas, GlyphPos, State, Transparent); - TButtonGlyph_DrawButtonText(Canvas, Caption, Result, State, - BiDiFlags {$IFDEF COMPILER_7_UP}, WordWrap {$ENDIF}); -end; - -{ TTntSpeedButton } - -procedure TTntSpeedButton.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntSpeedButton.IsCaptionStored: Boolean; -begin - Result := TntControl_IsCaptionStored(Self) -end; - -function TTntSpeedButton.GetCaption: TWideCaption; -begin - Result := TntControl_GetText(Self); -end; - -procedure TTntSpeedButton.SetCaption(const Value: TWideCaption); -begin - TntControl_SetText(Self, Value); -end; - -function TTntSpeedButton.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -function TTntSpeedButton.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntSpeedButton.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntSpeedButton.CMHintShow(var Message: TMessage); -begin - ProcessCMHintShowMsg(Message); - inherited; -end; - -procedure TTntSpeedButton.CMDialogChar(var Message: TCMDialogChar); -begin - with Message do - if IsWideCharAccel(CharCode, Caption) and Enabled and Visible and - (Parent <> nil) and Parent.Showing then - begin - Click; - Result := 1; - end else - inherited; -end; - -function TTntSpeedButton.GetButtonGlyph: Pointer; -begin - Result := THackSpeedButton(Self).FGlyph; -end; - -procedure TTntSpeedButton.UpdateInternalGlyphList; -begin - FPaintInherited := True; - try - Repaint; - finally - FPaintInherited := False; - end; - Invalidate; - raise EAbortPaint.Create(''); -end; - -procedure TTntSpeedButton.Paint; -begin - if FPaintInherited then - inherited - else - PaintButton; -end; - -procedure TTntSpeedButton.PaintButton; -const - DownStyles: array[Boolean] of Integer = (BDR_RAISEDINNER, BDR_SUNKENOUTER); - FillStyles: array[Boolean] of Integer = (BF_MIDDLE, 0); -var - PaintRect: TRect; - DrawFlags: Integer; - Offset: TPoint; - {$IFDEF THEME_7_UP} - Button: TThemedButton; - ToolButton: TThemedToolBar; - Details: TThemedElementDetails; - {$ENDIF} -begin - try - if not Enabled then - begin - FState := bsDisabled; - THackSpeedButton(Self).FDragging := False; - end - else if FState = bsDisabled then - if Down and (GroupIndex <> 0) then - FState := bsExclusive - else - FState := bsUp; - Canvas.Font := Self.Font; - - {$IFDEF THEME_7_UP} - if ThemeServices.ThemesEnabled then - begin - {$IFDEF COMPILER_7_UP} - PerformEraseBackground(Self, Canvas.Handle); - {$ENDIF} - SelectObject(Canvas.Handle, Canvas.Font.Handle); { For some reason, PerformEraseBackground sometimes messes the font up. } - - if not Enabled then - Button := tbPushButtonDisabled - else - if FState in [bsDown, bsExclusive] then - Button := tbPushButtonPressed - else - if MouseInControl then - Button := tbPushButtonHot - else - Button := tbPushButtonNormal; - - ToolButton := ttbToolbarDontCare; - if Flat then - begin - case Button of - tbPushButtonDisabled: - Toolbutton := ttbButtonDisabled; - tbPushButtonPressed: - Toolbutton := ttbButtonPressed; - tbPushButtonHot: - Toolbutton := ttbButtonHot; - tbPushButtonNormal: - Toolbutton := ttbButtonNormal; - end; - end; - - PaintRect := ClientRect; - if ToolButton = ttbToolbarDontCare then - begin - Details := ThemeServices.GetElementDetails(Button); - ThemeServices.DrawElement(Canvas.Handle, Details, PaintRect); - PaintRect := ThemeServices.ContentRect(Canvas.Handle, Details, PaintRect); - end - else - begin - Details := ThemeServices.GetElementDetails(ToolButton); - ThemeServices.DrawElement(Canvas.Handle, Details, PaintRect); - PaintRect := ThemeServices.ContentRect(Canvas.Handle, Details, PaintRect); - end; - - if Button = tbPushButtonPressed then - begin - // A pressed speed button has a white text. This applies however only to flat buttons. - if ToolButton <> ttbToolbarDontCare then - Canvas.Font.Color := clHighlightText; - Offset := Point(1, 0); - end - else - Offset := Point(0, 0); - TButtonGlyph_Draw(Self, Canvas, PaintRect, Offset, Caption, Layout, Margin, Spacing, FState, - Transparent, DrawTextBiDiModeFlags(0) {$IFDEF COMPILER_7_UP}, False {$ENDIF}); - end - else - {$ENDIF} - begin - PaintRect := Rect(0, 0, Width, Height); - if not Flat then - begin - DrawFlags := DFCS_BUTTONPUSH or DFCS_ADJUSTRECT; - if FState in [bsDown, bsExclusive] then - DrawFlags := DrawFlags or DFCS_PUSHED; - DrawFrameControl(Canvas.Handle, PaintRect, DFC_BUTTON, DrawFlags); - end - else - begin - if (FState in [bsDown, bsExclusive]) or - (MouseInControl and (FState <> bsDisabled)) or - (csDesigning in ComponentState) then - DrawEdge(Canvas.Handle, PaintRect, DownStyles[FState in [bsDown, bsExclusive]], - FillStyles[Transparent] or BF_RECT) - else if not Transparent then - begin - Canvas.Brush.Color := Color; - Canvas.FillRect(PaintRect); - end; - InflateRect(PaintRect, -1, -1); - end; - if FState in [bsDown, bsExclusive] then - begin - if (FState = bsExclusive) and (not Flat or not MouseInControl) then - begin - Canvas.Brush.Bitmap := AllocPatternBitmap(clBtnFace, clBtnHighlight); - Canvas.FillRect(PaintRect); - end; - Offset.X := 1; - Offset.Y := 1; - end - else - begin - Offset.X := 0; - Offset.Y := 0; - end; - TButtonGlyph_Draw(Self, Canvas, PaintRect, Offset, Caption, - Layout, Margin, Spacing, FState, Transparent, - DrawTextBiDiModeFlags(0) {$IFDEF COMPILER_7_UP}, False {$ENDIF}); - end; - except - on E: EAbortPaint do - ; - else - raise; - end; -end; - -function TTntSpeedButton.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{$IFDEF COMPILER_10_UP} -type - TAccessGraphicControl = class(TGraphicControl); -{$ENDIF} - -procedure TTntSpeedButton.ActionChange(Sender: TObject; CheckDefaults: Boolean); -{$IFDEF COMPILER_10_UP} -// bug fix for VCL where ImageIndex on Action ALWAYS overrides the Glyph. -type - CallActionChange = procedure(Sender: TObject; CheckDefaults: Boolean) of object; -var - M: TMethod; -{$ENDIF} -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - {$IFNDEF COMPILER_10_UP} - inherited; - {$ELSE} - // call TGraphicControl.ActionChange (bypass TSpeedButton.ActionChange) - M.Code := @TAccessGraphicControl.ActionChange; - M.Data := Self; - CallActionChange(M)(Sender, CheckDefaults); - // call Delphi2005's TSpeedButton.ActionChange - if Sender is TCustomAction{TNT-ALLOW TCustomAction} then - with TCustomAction{TNT-ALLOW TCustomAction}(Sender) do - begin - if CheckDefaults or (Self.GroupIndex = 0) then - Self.GroupIndex := GroupIndex; - { Copy image from action's imagelist } - if (Glyph.Empty) and (ActionList <> nil) and (ActionList.Images <> nil) and - (ImageIndex >= 0) and (ImageIndex < ActionList.Images.Count) then - CopyImage(ActionList.Images, ImageIndex); - end; - {$ENDIF} -end; - -{ TTntBitBtn } - -procedure TTntBitBtn.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, 'BUTTON'); -end; - -procedure TTntBitBtn.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntBitBtn.IsCaptionStored: Boolean; -var - BaseClass: TClass; - PropInfo: PPropInfo; -begin - Assert(Self is TButton{TNT-ALLOW TButton}); - Assert(Self is TBitBtn{TNT-ALLOW TBitBtn}); - if Kind = bkCustom then - // don't use TBitBtn, it's broken for Kind <> bkCustom - BaseClass := TButton{TNT-ALLOW TButton} - else begin - //TBitBtn has it's own storage specifier, based upon the button kind - BaseClass := TBitBtn{TNT-ALLOW TBitBtn}; - end; - PropInfo := GetPropInfo(BaseClass, 'Caption'); - if PropInfo = nil then - raise EPropertyError.CreateResFmt(PResStringRec(@SUnknownProperty), ['Caption']); - Result := IsStoredProp(Self, PropInfo); -end; - -function TTntBitBtn.GetCaption: TWideCaption; -begin - Result := TntControl_GetText(Self) -end; - -procedure TTntBitBtn.SetCaption(const Value: TWideCaption); -begin - TntControl_SetText(Self, Value); -end; - -function TTntBitBtn.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -function TTntBitBtn.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntBitBtn.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntBitBtn.CMDialogChar(var Message: TCMDialogChar); -begin - TntButton_CMDialogChar(Self, Message); -end; - -function TTntBitBtn.GetButtonGlyph: Pointer; -begin - Result := THackBitBtn(Self).FGlyph; -end; - -procedure TTntBitBtn.UpdateInternalGlyphList; -begin - FPaintInherited := True; - try - Repaint; - finally - FPaintInherited := False; - end; - Invalidate; - raise EAbortPaint.Create(''); -end; - -procedure TTntBitBtn.CNDrawItem(var Message: TWMDrawItem); -begin - if FPaintInherited then - inherited - else - DrawItem(Message.DrawItemStruct^); -end; - -procedure TTntBitBtn.DrawItem(const DrawItemStruct: TDrawItemStruct); -var - IsDown, IsDefault: Boolean; - State: TButtonState; - R: TRect; - Flags: Longint; - FCanvas: TCanvas; - IsFocused: Boolean; - {$IFDEF THEME_7_UP} - Details: TThemedElementDetails; - Button: TThemedButton; - Offset: TPoint; - {$ENDIF} -begin - try - FCanvas := THackBitBtn(Self).FCanvas; - IsFocused := THackBitBtn(Self).IsFocused; - FCanvas.Handle := DrawItemStruct.hDC; - R := ClientRect; - - with DrawItemStruct do - begin - FCanvas.Handle := hDC; - FCanvas.Font := Self.Font; - IsDown := itemState and ODS_SELECTED <> 0; - IsDefault := itemState and ODS_FOCUS <> 0; - - if not Enabled then State := bsDisabled - else if IsDown then State := bsDown - else State := bsUp; - end; - - {$IFDEF THEME_7_UP} - if ThemeServices.ThemesEnabled then - begin - if not Enabled then - Button := tbPushButtonDisabled - else - if IsDown then - Button := tbPushButtonPressed - else - if FMouseInControl then - Button := tbPushButtonHot - else - if IsFocused or IsDefault then - Button := tbPushButtonDefaulted - else - Button := tbPushButtonNormal; - - Details := ThemeServices.GetElementDetails(Button); - // Parent background. - ThemeServices.DrawParentBackground(Handle, DrawItemStruct.hDC, @Details, True); - // Button shape. - ThemeServices.DrawElement(DrawItemStruct.hDC, Details, DrawItemStruct.rcItem); - R := ThemeServices.ContentRect(FCanvas.Handle, Details, DrawItemStruct.rcItem); - - if Button = tbPushButtonPressed then - Offset := Point(1, 0) - else - Offset := Point(0, 0); - TButtonGlyph_Draw(Self, FCanvas, R, Offset, Caption, Layout, Margin, Spacing, State, False, - DrawTextBiDiModeFlags(0) {$IFDEF COMPILER_7_UP}, Self.WordWrap {$ENDIF}); - - if IsFocused and IsDefault then - begin - FCanvas.Pen.Color := clWindowFrame; - FCanvas.Brush.Color := clBtnFace; - DrawFocusRect(FCanvas.Handle, R); - end; - end - else - {$ENDIF} - begin - R := ClientRect; - - Flags := DFCS_BUTTONPUSH or DFCS_ADJUSTRECT; - if IsDown then Flags := Flags or DFCS_PUSHED; - if DrawItemStruct.itemState and ODS_DISABLED <> 0 then - Flags := Flags or DFCS_INACTIVE; - - { DrawFrameControl doesn't allow for drawing a button as the - default button, so it must be done here. } - if IsFocused or IsDefault then - begin - FCanvas.Pen.Color := clWindowFrame; - FCanvas.Pen.Width := 1; - FCanvas.Brush.Style := bsClear; - FCanvas.Rectangle(R.Left, R.Top, R.Right, R.Bottom); - - { DrawFrameControl must draw within this border } - InflateRect(R, -1, -1); - end; - - { DrawFrameControl does not draw a pressed button correctly } - if IsDown then - begin - FCanvas.Pen.Color := clBtnShadow; - FCanvas.Pen.Width := 1; - FCanvas.Brush.Color := clBtnFace; - FCanvas.Rectangle(R.Left, R.Top, R.Right, R.Bottom); - InflateRect(R, -1, -1); - end - else - DrawFrameControl(DrawItemStruct.hDC, R, DFC_BUTTON, Flags); - - if IsFocused then - begin - R := ClientRect; - InflateRect(R, -1, -1); - end; - - FCanvas.Font := Self.Font; - if IsDown then - OffsetRect(R, 1, 1); - - TButtonGlyph_Draw(Self, FCanvas, R, Point(0, 0), Caption, Layout, Margin, Spacing, State, - False, DrawTextBiDiModeFlags(0) {$IFDEF COMPILER_7_UP}, Self.WordWrap {$ENDIF}); - - if IsFocused and IsDefault then - begin - R := ClientRect; - InflateRect(R, -4, -4); - FCanvas.Pen.Color := clWindowFrame; - FCanvas.Brush.Color := clBtnFace; - DrawFocusRect(FCanvas.Handle, R); - end; - end; - FCanvas.Handle := 0; - except - on E: EAbortPaint do - ; - else - raise; - end; -end; - -procedure TTntBitBtn.CMMouseEnter(var Message: TMessage); -begin - FMouseInControl := True; - inherited; -end; - -procedure TTntBitBtn.CMMouseLeave(var Message: TMessage); -begin - FMouseInControl := False; - inherited; -end; - -{$IFDEF COMPILER_10_UP} -type - TAccessButton = class(TButton{TNT-ALLOW TButton}); -{$ENDIF} - -procedure TTntBitBtn.ActionChange(Sender: TObject; CheckDefaults: Boolean); -{$IFDEF COMPILER_10_UP} -// bug fix for VCL where ImageIndex on Action ALWAYS overrides the Glyph. -type - CallActionChange = procedure(Sender: TObject; CheckDefaults: Boolean) of object; -var - M: TMethod; -{$ENDIF} -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - {$IFNDEF COMPILER_10_UP} - inherited; - {$ELSE} - // call TButton.ActionChange (bypass TBitBtn.ActionChange) - M.Code := @TAccessButton.ActionChange; - M.Data := Self; - CallActionChange(M)(Sender, CheckDefaults); - // call Delphi2005's TBitBtn.ActionChange - if Sender is TCustomAction{TNT-ALLOW TCustomAction} then - with TCustomAction{TNT-ALLOW TCustomAction}(Sender) do - begin - { Copy image from action's imagelist } - if (Glyph.Empty) and (ActionList <> nil) and (ActionList.Images <> nil) and - (ImageIndex >= 0) and (ImageIndex < ActionList.Images.Count) then - CopyImage(ActionList.Images, ImageIndex); - end; - {$ENDIF} -end; - -function TTntBitBtn.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntCheckLst.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntCheckLst.pas deleted file mode 100644 index 748616952..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntCheckLst.pas +++ /dev/null @@ -1,184 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntCheckLst; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Classes, Messages, Windows, Controls, StdCtrls, CheckLst, - TntClasses, TntControls, TntStdCtrls; - -type -{TNT-WARN TCheckListBox} - TTntCheckListBox = class(TCheckListBox{TNT-ALLOW TCheckListBox}, IWideCustomListControl) - private - FItems: TTntStrings; - FSaveItems: TTntStrings; - FSaveTopIndex: Integer; - FSaveItemIndex: Integer; - FSaved_ItemEnabled: array of Boolean; - FSaved_State: array of TCheckBoxState; - FSaved_Header: array of Boolean; - FOnData: TLBGetWideDataEvent; - procedure SetItems(const Value: TTntStrings); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - procedure LBGetText(var Message: TMessage); message LB_GETTEXT; - procedure LBGetTextLen(var Message: TMessage); message LB_GETTEXTLEN; - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - procedure CreateWnd; override; - procedure DestroyWnd; override; - procedure DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState); override; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - procedure CopySelection(Destination: TCustomListControl); override; - procedure AddItem(const Item: WideString; AObject: TObject); reintroduce; virtual; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - property Items: TTntStrings read FItems write SetItems; - property OnData: TLBGetWideDataEvent read FOnData write FOnData; - end; - -implementation - -uses - SysUtils, Math, TntActnList; - -{ TTntCheckListBox } - -constructor TTntCheckListBox.Create(AOwner: TComponent); -begin - inherited; - FItems := TTntListBoxStrings.Create; - TTntListBoxStrings(FItems).ListBox := Self; -end; - -destructor TTntCheckListBox.Destroy; -begin - FreeAndNil(FItems); - inherited; -end; - -procedure TTntCheckListBox.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, 'LISTBOX'); -end; - -procedure TTntCheckListBox.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -procedure TTntCheckListBox.CreateWnd; -var - i: integer; -begin - inherited; - TntListBox_AfterInherited_CreateWnd(Self, FSaveItems, FItems, FSaveTopIndex, FSaveItemIndex); - if Length(FSaved_ItemEnabled) > 0 then begin - for i := 0 to Min(Items.Count - 1, High(FSaved_ItemEnabled)) do begin - ItemEnabled[i] := FSaved_ItemEnabled[i]; - State[i] := FSaved_State[i]; - Header[i] := FSaved_Header[i]; - end; - SetLength(FSaved_ItemEnabled, 0); - SetLength(FSaved_State, 0); - SetLength(FSaved_Header, 0); - end; -end; - -procedure TTntCheckListBox.DestroyWnd; -var - i: integer; -begin - SetLength(FSaved_ItemEnabled, Items.Count); - SetLength(FSaved_State, Items.Count); - SetLength(FSaved_Header, Items.Count); - for i := 0 to Items.Count - 1 do begin - FSaved_ItemEnabled[i] := ItemEnabled[i]; - FSaved_State[i] := State[i]; - FSaved_Header[i] := Header[i]; - end; - TntListBox_BeforeInherited_DestroyWnd(Self, FSaveItems, FItems, FSaveTopIndex, FSaveItemIndex); - inherited; -end; - -procedure TTntCheckListBox.SetItems(const Value: TTntStrings); -begin - FItems.Assign(Value); -end; - -procedure TTntCheckListBox.DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState); -begin - inherited; - if not Assigned(OnDrawItem) then - TntListBox_DrawItem_Text(Self, Items, Index, Rect); -end; - -function TTntCheckListBox.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -function TTntCheckListBox.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntCheckListBox.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntCheckListBox.AddItem(const Item: WideString; AObject: TObject); -begin - TntListBox_AddItem(Items, Item, AObject); -end; - -procedure TTntCheckListBox.CopySelection(Destination: TCustomListControl); -begin - TntListBox_CopySelection(Self, Items, Destination); -end; - -procedure TTntCheckListBox.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCheckListBox.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -procedure TTntCheckListBox.LBGetText(var Message: TMessage); -begin - if not TntCustomListBox_LBGetText(Self, OnData, Message) then - inherited; -end; - -procedure TTntCheckListBox.LBGetTextLen(var Message: TMessage); -begin - if not TntCustomListBox_LBGetTextLen(Self, OnData, Message) then - inherited; -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntClasses.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntClasses.pas deleted file mode 100644 index d2ff0245d..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntClasses.pas +++ /dev/null @@ -1,1799 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntClasses; - -{$INCLUDE TntCompilers.inc} - -interface - -{ TODO: Consider: TTntRegIniFile, TTntMemIniFile (consider if UTF8 fits into this solution). } - -{***********************************************} -{ WideChar-streaming implemented by Maël Hörz } -{***********************************************} - -uses - Classes, SysUtils, Windows, TntSysUtils, - {$IFNDEF COMPILER_10_UP} - TntWideStrings, - {$ELSE} - WideStrings, - {$ENDIF} - ActiveX, Contnrs; - -{ Exception classes } - -type - EWideFileStreamError = class(WideException) - constructor Create(ResStringRec: PResStringRec; const FileName: WideString); - end; - EWideFCreateError = class(EWideFileStreamError); - EWideFOpenError = class(EWideFileStreamError); - -// ......... introduced ......... -type - TTntStreamCharSet = (csAnsi, csUnicode, csUnicodeSwapped, csUtf8); - -function AutoDetectCharacterSet(Stream: TStream): TTntStreamCharSet; - -//--------------------------------------------------------------------------------------------- -// Tnt - Classes -//--------------------------------------------------------------------------------------------- - -{TNT-WARN ExtractStrings} -{TNT-WARN LineStart} -{TNT-WARN TStringStream} // TODO: Implement a TWideStringStream - -// A potential implementation of TWideStringStream can be found at: -// http://kdsxml.cvs.sourceforge.net/kdsxml/Global/KDSClasses.pas?revision=1.10&view=markup - -procedure TntPersistent_AfterInherited_DefineProperties(Filer: TFiler; Instance: TPersistent); - -type -{TNT-WARN TFileStream} - TTntFileStream = class(THandleStream) - public - constructor Create(const FileName: WideString; Mode: Word); - destructor Destroy; override; - end; - -{TNT-WARN TMemoryStream} - TTntMemoryStream = class(TMemoryStream{TNT-ALLOW TMemoryStream}) - public - procedure LoadFromFile(const FileName: WideString); - procedure SaveToFile(const FileName: WideString); - end; - -{TNT-WARN TResourceStream} - TTntResourceStream = class(TCustomMemoryStream) - private - HResInfo: HRSRC; - HGlobal: THandle; - procedure Initialize(Instance: THandle; Name, ResType: PWideChar); - public - constructor Create(Instance: THandle; const ResName: WideString; ResType: PWideChar); - constructor CreateFromID(Instance: THandle; ResID: Word; ResType: PWideChar); - destructor Destroy; override; - function Write(const Buffer; Count: Longint): Longint; override; - procedure SaveToFile(const FileName: WideString); - end; - - TTntStrings = class; - -{TNT-WARN TAnsiStrings} - TAnsiStrings{TNT-ALLOW TAnsiStrings} = class(TStrings{TNT-ALLOW TStrings}) - public - procedure LoadFromFile(const FileName: WideString); reintroduce; - procedure SaveToFile(const FileName: WideString); reintroduce; - procedure LoadFromFileEx(const FileName: WideString; CodePage: Cardinal); - procedure SaveToFileEx(const FileName: WideString; CodePage: Cardinal); - procedure LoadFromStreamEx(Stream: TStream; CodePage: Cardinal); virtual; abstract; - procedure SaveToStreamEx(Stream: TStream; CodePage: Cardinal); virtual; abstract; - end; - - TAnsiStringsForWideStringsAdapter = class(TAnsiStrings{TNT-ALLOW TAnsiStrings}) - private - FWideStrings: TTntStrings; - FAdapterCodePage: Cardinal; - protected - function Get(Index: Integer): AnsiString; override; - procedure Put(Index: Integer; const S: AnsiString); override; - function GetCount: Integer; override; - function GetObject(Index: Integer): TObject; override; - procedure PutObject(Index: Integer; AObject: TObject); override; - procedure SetUpdateState(Updating: Boolean); override; - function AdapterCodePage: Cardinal; dynamic; - public - constructor Create(AWideStrings: TTntStrings; _AdapterCodePage: Cardinal = 0); - procedure Clear; override; - procedure Delete(Index: Integer); override; - procedure Insert(Index: Integer; const S: AnsiString); override; - procedure LoadFromStreamEx(Stream: TStream; CodePage: Cardinal); override; - procedure SaveToStreamEx(Stream: TStream; CodePage: Cardinal); override; - end; - -{TNT-WARN TStrings} - TTntStrings = class(TWideStrings) - private - FLastFileCharSet: TTntStreamCharSet; - FAnsiStrings: TAnsiStrings{TNT-ALLOW TAnsiStrings}; - procedure SetAnsiStrings(const Value: TAnsiStrings{TNT-ALLOW TAnsiStrings}); - procedure ReadData(Reader: TReader); - procedure ReadDataUTF7(Reader: TReader); - procedure ReadDataUTF8(Reader: TReader); - procedure WriteDataUTF7(Writer: TWriter); - protected - procedure DefineProperties(Filer: TFiler); override; - public - constructor Create; - destructor Destroy; override; - - procedure LoadFromFile(const FileName: WideString); override; - procedure LoadFromStream(Stream: TStream); override; - procedure LoadFromStream_BOM(Stream: TStream; WithBOM: Boolean); virtual; - - procedure SaveToFile(const FileName: WideString); override; - procedure SaveToStream(Stream: TStream); override; - procedure SaveToStream_BOM(Stream: TStream; WithBOM: Boolean); virtual; - - property LastFileCharSet: TTntStreamCharSet read FLastFileCharSet; - published - property AnsiStrings: TAnsiStrings{TNT-ALLOW TAnsiStrings} read FAnsiStrings write SetAnsiStrings stored False; - end; - -{ TTntStringList class } - - TTntStringList = class; - TWideStringListSortCompare = function(List: TTntStringList; Index1, Index2: Integer): Integer; - -{TNT-WARN TStringList} - TTntStringList = class(TTntStrings) - private - FUpdating: Boolean; - FList: PWideStringItemList; - FCount: Integer; - FCapacity: Integer; - FSorted: Boolean; - FDuplicates: TDuplicates; - FCaseSensitive: Boolean; - FOnChange: TNotifyEvent; - FOnChanging: TNotifyEvent; - procedure ExchangeItems(Index1, Index2: Integer); - procedure Grow; - procedure QuickSort(L, R: Integer; SCompare: TWideStringListSortCompare); - procedure SetSorted(Value: Boolean); - procedure SetCaseSensitive(const Value: Boolean); - protected - procedure Changed; virtual; - procedure Changing; virtual; - function Get(Index: Integer): WideString; override; - function GetCapacity: Integer; override; - function GetCount: Integer; override; - function GetObject(Index: Integer): TObject; override; - procedure Put(Index: Integer; const S: WideString); override; - procedure PutObject(Index: Integer; AObject: TObject); override; - procedure SetCapacity(NewCapacity: Integer); override; - procedure SetUpdateState(Updating: Boolean); override; - function CompareStrings(const S1, S2: WideString): Integer; override; - procedure InsertItem(Index: Integer; const S: WideString; AObject: TObject); virtual; - public - destructor Destroy; override; - function Add(const S: WideString): Integer; override; - function AddObject(const S: WideString; AObject: TObject): Integer; override; - procedure Clear; override; - procedure Delete(Index: Integer); override; - procedure Exchange(Index1, Index2: Integer); override; - function Find(const S: WideString; var Index: Integer): Boolean; virtual; - function IndexOf(const S: WideString): Integer; override; - function IndexOfName(const Name: WideString): Integer; override; - procedure Insert(Index: Integer; const S: WideString); override; - procedure InsertObject(Index: Integer; const S: WideString; - AObject: TObject); override; - procedure Sort; virtual; - procedure CustomSort(Compare: TWideStringListSortCompare); virtual; - property Duplicates: TDuplicates read FDuplicates write FDuplicates; - property Sorted: Boolean read FSorted write SetSorted; - property CaseSensitive: Boolean read FCaseSensitive write SetCaseSensitive; - property OnChange: TNotifyEvent read FOnChange write FOnChange; - property OnChanging: TNotifyEvent read FOnChanging write FOnChanging; - end; - -// ......... introduced ......... -type - TListTargetCompare = function (Item, Target: Pointer): Integer; - -function FindSortedListByTarget(List: TList; TargetCompare: TListTargetCompare; - Target: Pointer; var Index: Integer): Boolean; - -function ClassIsRegistered(const clsid: TCLSID): Boolean; - -var - RuntimeUTFStreaming: Boolean; - -type - TBufferedAnsiString = class(TObject) - private - FStringBuffer: AnsiString; - LastWriteIndex: Integer; - public - procedure Clear; - procedure AddChar(const wc: AnsiChar); - procedure AddString(const s: AnsiString); - procedure AddBuffer(Buff: PAnsiChar; Chars: Integer); - function Value: AnsiString; - function BuffPtr: PAnsiChar; - end; - - TBufferedWideString = class(TObject) - private - FStringBuffer: WideString; - LastWriteIndex: Integer; - public - procedure Clear; - procedure AddChar(const wc: WideChar); - procedure AddString(const s: WideString); - procedure AddBuffer(Buff: PWideChar; Chars: Integer); - function Value: WideString; - function BuffPtr: PWideChar; - end; - - TBufferedStreamReader = class(TStream) - private - FStream: TStream; - FStreamSize: Integer; - FBuffer: array of Byte; - FBufferSize: Integer; - FBufferStartPosition: Integer; - FVirtualPosition: Integer; - procedure UpdateBufferFromPosition(StartPos: Integer); - public - constructor Create(Stream: TStream; BufferSize: Integer = 1024); - function Read(var Buffer; Count: Longint): Longint; override; - function Write(const Buffer; Count: Longint): Longint; override; - function Seek(Offset: Longint; Origin: Word): Longint; override; - end; - -// "synced" wide string -type TSetAnsiStrEvent = procedure(const Value: AnsiString) of object; -function GetSyncedWideString(var WideStr: WideString; const AnsiStr: AnsiString): WideString; -procedure SetSyncedWideString(const Value: WideString; var WideStr: WideString; - const AnsiStr: AnsiString; SetAnsiStr: TSetAnsiStrEvent); - -type - TWideComponentHelper = class(TComponent) - private - FComponent: TComponent; - protected - procedure Notification(AComponent: TComponent; Operation: TOperation); override; - public - constructor Create(AOwner: TComponent); override; - constructor CreateHelper(AOwner: TComponent; ComponentHelperList: TComponentList); - end; - -function FindWideComponentHelper(ComponentHelperList: TComponentList; Component: TComponent): TWideComponentHelper; - -implementation - -uses - RTLConsts, ComObj, Math, - Registry, TypInfo, TntSystem; - -{ EWideFileStreamError } - -constructor EWideFileStreamError.Create(ResStringRec: PResStringRec; - const FileName: WideString); -begin - inherited CreateResFmt(ResStringRec, [WideExpandFileName(FileName), - WideSysErrorMessage(GetLastError)]); -end; - -{ TntPersistent } - -//=========================================================================== -// The Delphi 5 Classes.pas never supported the streaming of WideStrings. -// The Delphi 6 Classes.pas supports WideString streaming. But it's too bad that -// the Delphi 6 IDE doesn't use the updated Classes.pas. Switching between Form/Text -// mode corrupts extended characters in WideStrings even under Delphi 6. -// Delphi 7 seems to finally get right. But let's keep the UTF7 support at design time -// to enable sharing source code with previous versions of Delphi. -// -// The purpose of this solution is to store WideString properties which contain -// non-ASCII chars in the form of UTF7 under the old property name + '_UTF7'. -// -// Special thanks go to Francisco Leong for helping to develop this solution. -// - -{ TTntWideStringPropertyFiler } -type - TTntWideStringPropertyFiler = class - private - FInstance: TPersistent; - FPropInfo: PPropInfo; - procedure ReadDataUTF8(Reader: TReader); - procedure ReadDataUTF7(Reader: TReader); - procedure WriteDataUTF7(Writer: TWriter); - public - procedure DefineProperties(Filer: TFiler; Instance: TPersistent; PropName: AnsiString); - end; - -function ReaderNeedsUtfHelp(Reader: TReader): Boolean; -begin - if Reader.Owner = nil then - Result := False { designtime - visual form inheritance ancestor } - else if csDesigning in Reader.Owner.ComponentState then - {$IFDEF COMPILER_7_UP} - Result := False { Delphi 7+: designtime - doesn't need UTF help. } - {$ELSE} - Result := True { Delphi 6: designtime - always needs UTF help. } - {$ENDIF} - else - Result := RuntimeUTFStreaming; { runtime } -end; - -procedure TTntWideStringPropertyFiler.ReadDataUTF8(Reader: TReader); -begin - if ReaderNeedsUtfHelp(Reader) then - SetWideStrProp(FInstance, FPropInfo, UTF8ToWideString(Reader.ReadString)) - else - Reader.ReadString; { do nothing with Result } -end; - -procedure TTntWideStringPropertyFiler.ReadDataUTF7(Reader: TReader); -begin - if ReaderNeedsUtfHelp(Reader) then - SetWideStrProp(FInstance, FPropInfo, UTF7ToWideString(Reader.ReadString)) - else - Reader.ReadString; { do nothing with Result } -end; - -procedure TTntWideStringPropertyFiler.WriteDataUTF7(Writer: TWriter); -begin - Writer.WriteString(WideStringToUTF7(GetWideStrProp(FInstance, FPropInfo))); -end; - -procedure TTntWideStringPropertyFiler.DefineProperties(Filer: TFiler; Instance: TPersistent; - PropName: AnsiString); - - {$IFNDEF COMPILER_7_UP} - function HasData: Boolean; - var - CurrPropValue: WideString; - begin - // must be stored - Result := IsStoredProp(Instance, FPropInfo); - if Result - and (Filer.Ancestor <> nil) - and (GetPropInfo(Filer.Ancestor, PropName, [tkWString]) <> nil) then - begin - // must be different than ancestor - CurrPropValue := GetWideStrProp(Instance, FPropInfo); - Result := CurrPropValue <> GetWideStrProp(Filer.Ancestor, GetPropInfo(Filer.Ancestor, PropName)); - end; - if Result then begin - // must be non-blank and different than UTF8 (implies all ASCII <= 127) - CurrPropValue := GetWideStrProp(Instance, FPropInfo); - Result := (CurrPropValue <> '') and (WideStringToUTF8(CurrPropValue) <> CurrPropValue); - end; - end; - {$ENDIF} - -begin - FInstance := Instance; - FPropInfo := GetPropInfo(Instance, PropName, [tkWString]); - if FPropInfo <> nil then begin - // must be published (and of type WideString) - Filer.DefineProperty(PropName + 'W', ReadDataUTF8, nil, False); - {$IFDEF COMPILER_7_UP} - Filer.DefineProperty(PropName + '_UTF7', ReadDataUTF7, WriteDataUTF7, False); - {$ELSE} - Filer.DefineProperty(PropName + '_UTF7', ReadDataUTF7, WriteDataUTF7, HasData); - {$ENDIF} - end; - FInstance := nil; - FPropInfo := nil; -end; - -{ TTntWideCharPropertyFiler } -type - TTntWideCharPropertyFiler = class - private - FInstance: TPersistent; - FPropInfo: PPropInfo; - {$IFNDEF COMPILER_9_UP} - FWriter: TWriter; - procedure GetLookupInfo(var Ancestor: TPersistent; - var Root, LookupRoot, RootAncestor: TComponent); - {$ENDIF} - procedure ReadData_W(Reader: TReader); - procedure ReadDataUTF7(Reader: TReader); - procedure WriteData_W(Writer: TWriter); - function ReadChar(Reader: TReader): WideChar; - public - procedure DefineProperties(Filer: TFiler; Instance: TPersistent; PropName: AnsiString); - end; - -{$IFNDEF COMPILER_9_UP} -type - TGetLookupInfoEvent = procedure(var Ancestor: TPersistent; - var Root, LookupRoot, RootAncestor: TComponent) of object; - -function AncestorIsValid(Ancestor: TPersistent; Root, RootAncestor: TComponent): Boolean; -begin - Result := (Ancestor <> nil) and (RootAncestor <> nil) and - Root.InheritsFrom(RootAncestor.ClassType); -end; - -function IsDefaultOrdPropertyValue(Instance: TObject; PropInfo: PPropInfo; - OnGetLookupInfo: TGetLookupInfoEvent): Boolean; -var - Ancestor: TPersistent; - LookupRoot: TComponent; - RootAncestor: TComponent; - Root: TComponent; - AncestorValid: Boolean; - Value: Longint; - Default: LongInt; -begin - Ancestor := nil; - Root := nil; - LookupRoot := nil; - RootAncestor := nil; - - if Assigned(OnGetLookupInfo) then - OnGetLookupInfo(Ancestor, Root, LookupRoot, RootAncestor); - - AncestorValid := AncestorIsValid(Ancestor, Root, RootAncestor); - - Result := True; - if (PropInfo^.GetProc <> nil) and (PropInfo^.SetProc <> nil) then - begin - Value := GetOrdProp(Instance, PropInfo); - if AncestorValid then - Result := Value = GetOrdProp(Ancestor, PropInfo) - else - begin - Default := PPropInfo(PropInfo)^.Default; - Result := (Default <> LongInt($80000000)) and (Value = Default); - end; - end; -end; - -procedure TTntWideCharPropertyFiler.GetLookupInfo(var Ancestor: TPersistent; - var Root, LookupRoot, RootAncestor: TComponent); -begin - Ancestor := FWriter.Ancestor; - Root := FWriter.Root; - LookupRoot := FWriter.LookupRoot; - RootAncestor := FWriter.RootAncestor; -end; -{$ENDIF} - -function TTntWideCharPropertyFiler.ReadChar(Reader: TReader): WideChar; -var - Temp: WideString; -begin - case Reader.NextValue of - vaWString: - Temp := Reader.ReadWideString; - vaString: - Temp := Reader.ReadString; - else - raise EReadError.Create(SInvalidPropertyValue); - end; - - if Length(Temp) > 1 then - raise EReadError.Create(SInvalidPropertyValue); - Result := Temp[1]; -end; - -procedure TTntWideCharPropertyFiler.ReadData_W(Reader: TReader); -begin - SetOrdProp(FInstance, FPropInfo, Ord(ReadChar(Reader))); -end; - -procedure TTntWideCharPropertyFiler.ReadDataUTF7(Reader: TReader); -var - S: WideString; -begin - S := UTF7ToWideString(Reader.ReadString); - if S = '' then - SetOrdProp(FInstance, FPropInfo, 0) - else - SetOrdProp(FInstance, FPropInfo, Ord(S[1])) -end; - -type TAccessWriter = class(TWriter); - -procedure TTntWideCharPropertyFiler.WriteData_W(Writer: TWriter); -var - L: Integer; - Temp: WideString; -begin - Temp := WideChar(GetOrdProp(FInstance, FPropInfo)); - - TAccessWriter(Writer).WriteValue(vaWString); - L := Length(Temp); - Writer.Write(L, SizeOf(Integer)); - Writer.Write(Pointer(@Temp[1])^, L * 2); -end; - -procedure TTntWideCharPropertyFiler.DefineProperties(Filer: TFiler; - Instance: TPersistent; PropName: AnsiString); - - {$IFNDEF COMPILER_9_UP} - function HasData: Boolean; - var - CurrPropValue: Integer; - begin - // must be stored - Result := IsStoredProp(Instance, FPropInfo); - if Result and (Filer.Ancestor <> nil) and - (GetPropInfo(Filer.Ancestor, PropName, [tkWChar]) <> nil) then - begin - // must be different than ancestor - CurrPropValue := GetOrdProp(Instance, FPropInfo); - Result := CurrPropValue <> GetOrdProp(Filer.Ancestor, GetPropInfo(Filer.Ancestor, PropName)); - end; - if Result and (Filer is TWriter) then - begin - FWriter := TWriter(Filer); - Result := not IsDefaultOrdPropertyValue(Instance, FPropInfo, GetLookupInfo); - end; - end; - {$ENDIF} - -begin - FInstance := Instance; - FPropInfo := GetPropInfo(Instance, PropName, [tkWChar]); - if FPropInfo <> nil then - begin - // must be published (and of type WideChar) - {$IFDEF COMPILER_9_UP} - Filer.DefineProperty(PropName + 'W', ReadData_W, WriteData_W, False); - {$ELSE} - Filer.DefineProperty(PropName + 'W', ReadData_W, WriteData_W, HasData); - {$ENDIF} - Filer.DefineProperty(PropName + '_UTF7', ReadDataUTF7, nil, False); - end; - FInstance := nil; - FPropInfo := nil; -end; - -procedure TntPersistent_AfterInherited_DefineProperties(Filer: TFiler; Instance: TPersistent); -var - I, Count: Integer; - PropInfo: PPropInfo; - PropList: PPropList; - WideStringFiler: TTntWideStringPropertyFiler; - WideCharFiler: TTntWideCharPropertyFiler; -begin - Count := GetTypeData(Instance.ClassInfo)^.PropCount; - if Count > 0 then - begin - WideStringFiler := TTntWideStringPropertyFiler.Create; - try - WideCharFiler := TTntWideCharPropertyFiler.Create; - try - GetMem(PropList, Count * SizeOf(Pointer)); - try - GetPropInfos(Instance.ClassInfo, PropList); - for I := 0 to Count - 1 do - begin - PropInfo := PropList^[I]; - if (PropInfo = nil) then - break; - if (PropInfo.PropType^.Kind = tkWString) then - WideStringFiler.DefineProperties(Filer, Instance, PropInfo.Name) - else if (PropInfo.PropType^.Kind = tkWChar) then - WideCharFiler.DefineProperties(Filer, Instance, PropInfo.Name) - end; - finally - FreeMem(PropList, Count * SizeOf(Pointer)); - end; - finally - WideCharFiler.Free; - end; - finally - WideStringFiler.Free; - end; - end; -end; - -{ TTntFileStream } - -constructor TTntFileStream.Create(const FileName: WideString; Mode: Word); -var - CreateHandle: Integer; - {$IFDEF DELPHI_7_UP} - ErrorMessage: WideString; - {$ENDIF} -begin - if Mode = fmCreate then - begin - CreateHandle := WideFileCreate(FileName); - if CreateHandle < 0 then begin - {$IFDEF DELPHI_7_UP} - ErrorMessage := WideSysErrorMessage(GetLastError); - raise EWideFCreateError.CreateFmt(SFCreateErrorEx, [WideExpandFileName(FileName), ErrorMessage]); - {$ELSE} - raise EWideFCreateError.CreateFmt(SFCreateError, [WideExpandFileName(FileName)]); - {$ENDIF} - end; - end - else - begin - CreateHandle := WideFileOpen(FileName, Mode); - if CreateHandle < 0 then begin - {$IFDEF DELPHI_7_UP} - ErrorMessage := WideSysErrorMessage(GetLastError); - raise EWideFOpenError.CreateFmt(SFOpenErrorEx, [WideExpandFileName(FileName), ErrorMessage]); - {$ELSE} - raise EWideFOpenError.CreateFmt(SFOpenError, [WideExpandFileName(FileName)]); - {$ENDIF} - end; - end; - inherited Create(CreateHandle); -end; - -destructor TTntFileStream.Destroy; -begin - if Handle >= 0 then FileClose(Handle); -end; - -{ TTntMemoryStream } - -procedure TTntMemoryStream.LoadFromFile(const FileName: WideString); -var - Stream: TStream; -begin - Stream := TTntFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); - try - LoadFromStream(Stream); - finally - Stream.Free; - end; -end; - -procedure TTntMemoryStream.SaveToFile(const FileName: WideString); -var - Stream: TStream; -begin - Stream := TTntFileStream.Create(FileName, fmCreate); - try - SaveToStream(Stream); - finally - Stream.Free; - end; -end; - -{ TTntResourceStream } - -constructor TTntResourceStream.Create(Instance: THandle; const ResName: WideString; - ResType: PWideChar); -begin - inherited Create; - Initialize(Instance, PWideChar(ResName), ResType); -end; - -constructor TTntResourceStream.CreateFromID(Instance: THandle; ResID: Word; - ResType: PWideChar); -begin - inherited Create; - Initialize(Instance, PWideChar(ResID), ResType); -end; - -procedure TTntResourceStream.Initialize(Instance: THandle; Name, ResType: PWideChar); - - procedure Error; - begin - raise EResNotFound.CreateFmt(SResNotFound, [Name]); - end; - -begin - HResInfo := FindResourceW(Instance, Name, ResType); - if HResInfo = 0 then Error; - HGlobal := LoadResource(Instance, HResInfo); - if HGlobal = 0 then Error; - SetPointer(LockResource(HGlobal), SizeOfResource(Instance, HResInfo)); -end; - -destructor TTntResourceStream.Destroy; -begin - UnlockResource(HGlobal); - FreeResource(HGlobal); { Technically this is not necessary (MS KB #193678) } - inherited Destroy; -end; - -function TTntResourceStream.Write(const Buffer; Count: Longint): Longint; -begin - raise EStreamError.CreateRes(PResStringRec(@SCantWriteResourceStreamError)); -end; - -procedure TTntResourceStream.SaveToFile(const FileName: WideString); -var - Stream: TStream; -begin - Stream := TTntFileStream.Create(FileName, fmCreate); - try - SaveToStream(Stream); - finally - Stream.Free; - end; -end; - -{ TAnsiStrings } - -procedure TAnsiStrings{TNT-ALLOW TAnsiStrings}.LoadFromFile(const FileName: WideString); -var - Stream: TStream; -begin - Stream := TTntFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); - try - LoadFromStream(Stream); - finally - Stream.Free; - end; -end; - -procedure TAnsiStrings{TNT-ALLOW TAnsiStrings}.SaveToFile(const FileName: WideString); -var - Stream: TStream; -begin - Stream := TTntFileStream.Create(FileName, fmCreate); - try - SaveToStream(Stream); - finally - Stream.Free; - end; -end; - -procedure TAnsiStrings{TNT-ALLOW TAnsiStrings}.LoadFromFileEx(const FileName: WideString; CodePage: Cardinal); -var - Stream: TStream; -begin - Stream := TTntFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); - try - LoadFromStreamEx(Stream, CodePage); - finally - Stream.Free; - end; -end; - -procedure TAnsiStrings{TNT-ALLOW TAnsiStrings}.SaveToFileEx(const FileName: WideString; CodePage: Cardinal); -var - Stream: TStream; -begin - Stream := TTntFileStream.Create(FileName, fmCreate); - try - if (CodePage = CP_UTF8) then - Stream.WriteBuffer(PAnsiChar(UTF8_BOM)^, Length(UTF8_BOM)); - SaveToStreamEx(Stream, CodePage); - finally - Stream.Free; - end; -end; - -{ TAnsiStringsForWideStringsAdapter } - -constructor TAnsiStringsForWideStringsAdapter.Create(AWideStrings: TTntStrings; _AdapterCodePage: Cardinal); -begin - inherited Create; - FWideStrings := AWideStrings; - FAdapterCodePage := _AdapterCodePage; -end; - -function TAnsiStringsForWideStringsAdapter.AdapterCodePage: Cardinal; -begin - if FAdapterCodePage = 0 then - Result := TntSystem.DefaultSystemCodePage - else - Result := FAdapterCodePage; -end; - -procedure TAnsiStringsForWideStringsAdapter.Clear; -begin - FWideStrings.Clear; -end; - -procedure TAnsiStringsForWideStringsAdapter.Delete(Index: Integer); -begin - FWideStrings.Delete(Index); -end; - -function TAnsiStringsForWideStringsAdapter.Get(Index: Integer): AnsiString; -begin - Result := WideStringToStringEx(FWideStrings.Get(Index), AdapterCodePage); -end; - -procedure TAnsiStringsForWideStringsAdapter.Put(Index: Integer; const S: AnsiString); -begin - FWideStrings.Put(Index, StringToWideStringEx(S, AdapterCodePage)); -end; - -function TAnsiStringsForWideStringsAdapter.GetCount: Integer; -begin - Result := FWideStrings.GetCount; -end; - -procedure TAnsiStringsForWideStringsAdapter.Insert(Index: Integer; const S: AnsiString); -begin - FWideStrings.Insert(Index, StringToWideStringEx(S, AdapterCodePage)); -end; - -function TAnsiStringsForWideStringsAdapter.GetObject(Index: Integer): TObject; -begin - Result := FWideStrings.GetObject(Index); -end; - -procedure TAnsiStringsForWideStringsAdapter.PutObject(Index: Integer; AObject: TObject); -begin - FWideStrings.PutObject(Index, AObject); -end; - -procedure TAnsiStringsForWideStringsAdapter.SetUpdateState(Updating: Boolean); -begin - FWideStrings.SetUpdateState(Updating); -end; - -procedure TAnsiStringsForWideStringsAdapter.LoadFromStreamEx(Stream: TStream; CodePage: Cardinal); -var - Size: Integer; - S: AnsiString; -begin - BeginUpdate; - try - Size := Stream.Size - Stream.Position; - SetString(S, nil, Size); - Stream.Read(Pointer(S)^, Size); - FWideStrings.SetTextStr(StringToWideStringEx(S, CodePage)); - finally - EndUpdate; - end; -end; - -procedure TAnsiStringsForWideStringsAdapter.SaveToStreamEx(Stream: TStream; CodePage: Cardinal); -var - S: AnsiString; -begin - S := WideStringToStringEx(FWideStrings.GetTextStr, CodePage); - Stream.WriteBuffer(Pointer(S)^, Length(S)); -end; - -{ TTntStrings } - -constructor TTntStrings.Create; -begin - inherited; - FAnsiStrings := TAnsiStringsForWideStringsAdapter.Create(Self); - FLastFileCharSet := csUnicode; -end; - -destructor TTntStrings.Destroy; -begin - FreeAndNil(FAnsiStrings); - inherited; -end; - -procedure TTntStrings.SetAnsiStrings(const Value: TAnsiStrings{TNT-ALLOW TAnsiStrings}); -begin - FAnsiStrings.Assign(Value); -end; - -procedure TTntStrings.DefineProperties(Filer: TFiler); - - {$IFNDEF COMPILER_7_UP} - function DoWrite: Boolean; - begin - if Filer.Ancestor <> nil then - begin - Result := True; - if Filer.Ancestor is TWideStrings then - Result := not Equals(TWideStrings(Filer.Ancestor)) - end - else Result := Count > 0; - end; - - function DoWriteAsUTF7: Boolean; - var - i: integer; - begin - Result := False; - for i := 0 to Count - 1 do begin - if (Strings[i] <> '') and (WideStringToUTF8(Strings[i]) <> Strings[i]) then begin - Result := True; - break; { found a string with non-ASCII chars (> 127) } - end; - end; - end; - {$ENDIF} - -begin - inherited DefineProperties(Filer); { Handles main 'Strings' property.' } - Filer.DefineProperty('WideStrings', ReadData, nil, False); - Filer.DefineProperty('WideStringsW', ReadDataUTF8, nil, False); - {$IFDEF COMPILER_7_UP} - Filer.DefineProperty('WideStrings_UTF7', ReadDataUTF7, WriteDataUTF7, False); - {$ELSE} - Filer.DefineProperty('WideStrings_UTF7', ReadDataUTF7, WriteDataUTF7, DoWrite and DoWriteAsUTF7); - {$ENDIF} -end; - -procedure TTntStrings.LoadFromFile(const FileName: WideString); -var - Stream: TStream; -begin - Stream := TTntFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); - try - FLastFileCharSet := AutoDetectCharacterSet(Stream); - Stream.Position := 0; - LoadFromStream(Stream); - finally - Stream.Free; - end; -end; - -procedure TTntStrings.LoadFromStream(Stream: TStream); -begin - LoadFromStream_BOM(Stream, True); -end; - -procedure TTntStrings.LoadFromStream_BOM(Stream: TStream; WithBOM: Boolean); -var - DataLeft: Integer; - StreamCharSet: TTntStreamCharSet; - SW: WideString; - SA: AnsiString; -begin - BeginUpdate; - try - if WithBOM then - StreamCharSet := AutoDetectCharacterSet(Stream) - else - StreamCharSet := csUnicode; - DataLeft := Stream.Size - Stream.Position; - if (StreamCharSet in [csUnicode, csUnicodeSwapped]) then - begin - // BOM indicates Unicode text stream - if DataLeft < SizeOf(WideChar) then - SW := '' - else begin - SetLength(SW, DataLeft div SizeOf(WideChar)); - Stream.Read(PWideChar(SW)^, DataLeft); - if StreamCharSet = csUnicodeSwapped then - StrSwapByteOrder(PWideChar(SW)); - end; - SetTextStr(SW); - end - else if StreamCharSet = csUtf8 then - begin - // BOM indicates UTF-8 text stream - SetLength(SA, DataLeft div SizeOf(AnsiChar)); - Stream.Read(PAnsiChar(SA)^, DataLeft); - SetTextStr(UTF8ToWideString(SA)); - end - else - begin - // without byte order mark it is assumed that we are loading ANSI text - SetLength(SA, DataLeft div SizeOf(AnsiChar)); - Stream.Read(PAnsiChar(SA)^, DataLeft); - SetTextStr(SA); - end; - finally - EndUpdate; - end; -end; - -procedure TTntStrings.ReadData(Reader: TReader); -begin - if Reader.NextValue in [vaString, vaLString] then - SetTextStr(Reader.ReadString) {JCL compatiblity} - else if Reader.NextValue = vaWString then - SetTextStr(Reader.ReadWideString) {JCL compatiblity} - else begin - BeginUpdate; - try - Clear; - Reader.ReadListBegin; - while not Reader.EndOfList do - if Reader.NextValue in [vaString, vaLString] then - Add(Reader.ReadString) {TStrings compatiblity} - else - Add(Reader.ReadWideString); - Reader.ReadListEnd; - finally - EndUpdate; - end; - end; -end; - -procedure TTntStrings.ReadDataUTF7(Reader: TReader); -begin - Reader.ReadListBegin; - if ReaderNeedsUtfHelp(Reader) then - begin - BeginUpdate; - try - Clear; - while not Reader.EndOfList do - Add(UTF7ToWideString(Reader.ReadString)) - finally - EndUpdate; - end; - end else begin - while not Reader.EndOfList do - Reader.ReadString; { do nothing with Result } - end; - Reader.ReadListEnd; -end; - -procedure TTntStrings.ReadDataUTF8(Reader: TReader); -begin - Reader.ReadListBegin; - if ReaderNeedsUtfHelp(Reader) - or (Count = 0){ Legacy support where 'WideStrings' was never written in lieu of WideStringsW } - then begin - BeginUpdate; - try - Clear; - while not Reader.EndOfList do - Add(UTF8ToWideString(Reader.ReadString)) - finally - EndUpdate; - end; - end else begin - while not Reader.EndOfList do - Reader.ReadString; { do nothing with Result } - end; - Reader.ReadListEnd; -end; - -procedure TTntStrings.SaveToFile(const FileName: WideString); -var - Stream: TStream; -begin - Stream := TTntFileStream.Create(FileName, fmCreate); - try - SaveToStream(Stream); - finally - Stream.Free; - end; -end; - -procedure TTntStrings.SaveToStream(Stream: TStream); -begin - SaveToStream_BOM(Stream, True); -end; - -procedure TTntStrings.SaveToStream_BOM(Stream: TStream; WithBOM: Boolean); -// Saves the currently loaded text into the given stream. -// WithBOM determines whether to write a byte order mark or not. -var - SW: WideString; - BOM: WideChar; -begin - if WithBOM then begin - BOM := UNICODE_BOM; - Stream.WriteBuffer(BOM, SizeOf(WideChar)); - end; - SW := GetTextStr; - Stream.WriteBuffer(PWideChar(SW)^, Length(SW) * SizeOf(WideChar)); -end; - -procedure TTntStrings.WriteDataUTF7(Writer: TWriter); -var - I: Integer; -begin - Writer.WriteListBegin; - for I := 0 to Count-1 do - Writer.WriteString(WideStringToUTF7(Get(I))); - Writer.WriteListEnd; -end; - -{ TTntStringList } - -destructor TTntStringList.Destroy; -begin - FOnChange := nil; - FOnChanging := nil; - inherited Destroy; - if FCount <> 0 then Finalize(FList^[0], FCount); - FCount := 0; - SetCapacity(0); -end; - -function TTntStringList.Add(const S: WideString): Integer; -begin - Result := AddObject(S, nil); -end; - -function TTntStringList.AddObject(const S: WideString; AObject: TObject): Integer; -begin - if not Sorted then - Result := FCount - else - if Find(S, Result) then - case Duplicates of - dupIgnore: Exit; - dupError: Error(PResStringRec(@SDuplicateString), 0); - end; - InsertItem(Result, S, AObject); -end; - -procedure TTntStringList.Changed; -begin - if (not FUpdating) and Assigned(FOnChange) then - FOnChange(Self); -end; - -procedure TTntStringList.Changing; -begin - if (not FUpdating) and Assigned(FOnChanging) then - FOnChanging(Self); -end; - -procedure TTntStringList.Clear; -begin - if FCount <> 0 then - begin - Changing; - Finalize(FList^[0], FCount); - FCount := 0; - SetCapacity(0); - Changed; - end; -end; - -procedure TTntStringList.Delete(Index: Integer); -begin - if (Index < 0) or (Index >= FCount) then Error(PResStringRec(@SListIndexError), Index); - Changing; - Finalize(FList^[Index]); - Dec(FCount); - if Index < FCount then - System.Move(FList^[Index + 1], FList^[Index], - (FCount - Index) * SizeOf(TWideStringItem)); - Changed; -end; - -procedure TTntStringList.Exchange(Index1, Index2: Integer); -begin - if (Index1 < 0) or (Index1 >= FCount) then Error(PResStringRec(@SListIndexError), Index1); - if (Index2 < 0) or (Index2 >= FCount) then Error(PResStringRec(@SListIndexError), Index2); - Changing; - ExchangeItems(Index1, Index2); - Changed; -end; - -procedure TTntStringList.ExchangeItems(Index1, Index2: Integer); -var - Temp: Integer; - Item1, Item2: PWideStringItem; -begin - Item1 := @FList^[Index1]; - Item2 := @FList^[Index2]; - Temp := Integer(Item1^.FString); - Integer(Item1^.FString) := Integer(Item2^.FString); - Integer(Item2^.FString) := Temp; - Temp := Integer(Item1^.FObject); - Integer(Item1^.FObject) := Integer(Item2^.FObject); - Integer(Item2^.FObject) := Temp; -end; - -function TTntStringList.Find(const S: WideString; var Index: Integer): Boolean; -var - L, H, I, C: Integer; -begin - Result := False; - L := 0; - H := FCount - 1; - while L <= H do - begin - I := (L + H) shr 1; - C := CompareStrings(FList^[I].FString, S); - if C < 0 then L := I + 1 else - begin - H := I - 1; - if C = 0 then - begin - Result := True; - if Duplicates <> dupAccept then L := I; - end; - end; - end; - Index := L; -end; - -function TTntStringList.Get(Index: Integer): WideString; -begin - if (Index < 0) or (Index >= FCount) then Error(PResStringRec(@SListIndexError), Index); - Result := FList^[Index].FString; -end; - -function TTntStringList.GetCapacity: Integer; -begin - Result := FCapacity; -end; - -function TTntStringList.GetCount: Integer; -begin - Result := FCount; -end; - -function TTntStringList.GetObject(Index: Integer): TObject; -begin - if (Index < 0) or (Index >= FCount) then Error(PResStringRec(@SListIndexError), Index); - Result := FList^[Index].FObject; -end; - -procedure TTntStringList.Grow; -var - Delta: Integer; -begin - if FCapacity > 64 then Delta := FCapacity div 4 else - if FCapacity > 8 then Delta := 16 else - Delta := 4; - SetCapacity(FCapacity + Delta); -end; - -function TTntStringList.IndexOf(const S: WideString): Integer; -begin - if not Sorted then Result := inherited IndexOf(S) else - if not Find(S, Result) then Result := -1; -end; - -function TTntStringList.IndexOfName(const Name: WideString): Integer; -var - NameKey: WideString; -begin - if not Sorted then - Result := inherited IndexOfName(Name) - else begin - // use sort to find index more quickly - NameKey := Name + NameValueSeparator; - Find(NameKey, Result); - if (Result < 0) or (Result > Count - 1) then - Result := -1 - else if CompareStrings(NameKey, Copy(Strings[Result], 1, Length(NameKey))) <> 0 then - Result := -1 - end; -end; - -procedure TTntStringList.Insert(Index: Integer; const S: WideString); -begin - InsertObject(Index, S, nil); -end; - -procedure TTntStringList.InsertObject(Index: Integer; const S: WideString; - AObject: TObject); -begin - if Sorted then Error(PResStringRec(@SSortedListError), 0); - if (Index < 0) or (Index > FCount) then Error(PResStringRec(@SListIndexError), Index); - InsertItem(Index, S, AObject); -end; - -procedure TTntStringList.InsertItem(Index: Integer; const S: WideString; AObject: TObject); -begin - Changing; - if FCount = FCapacity then Grow; - if Index < FCount then - System.Move(FList^[Index], FList^[Index + 1], - (FCount - Index) * SizeOf(TWideStringItem)); - with FList^[Index] do - begin - Pointer(FString) := nil; - FObject := AObject; - FString := S; - end; - Inc(FCount); - Changed; -end; - -procedure TTntStringList.Put(Index: Integer; const S: WideString); -begin - if Sorted then Error(PResStringRec(@SSortedListError), 0); - if (Index < 0) or (Index >= FCount) then Error(PResStringRec(@SListIndexError), Index); - Changing; - FList^[Index].FString := S; - Changed; -end; - -procedure TTntStringList.PutObject(Index: Integer; AObject: TObject); -begin - if (Index < 0) or (Index >= FCount) then Error(PResStringRec(@SListIndexError), Index); - Changing; - FList^[Index].FObject := AObject; - Changed; -end; - -procedure TTntStringList.QuickSort(L, R: Integer; SCompare: TWideStringListSortCompare); -var - I, J, P: Integer; -begin - repeat - I := L; - J := R; - P := (L + R) shr 1; - repeat - while SCompare(Self, I, P) < 0 do Inc(I); - while SCompare(Self, J, P) > 0 do Dec(J); - if I <= J then - begin - ExchangeItems(I, J); - if P = I then - P := J - else if P = J then - P := I; - Inc(I); - Dec(J); - end; - until I > J; - if L < J then QuickSort(L, J, SCompare); - L := I; - until I >= R; -end; - -procedure TTntStringList.SetCapacity(NewCapacity: Integer); -begin - ReallocMem(FList, NewCapacity * SizeOf(TWideStringItem)); - FCapacity := NewCapacity; -end; - -procedure TTntStringList.SetSorted(Value: Boolean); -begin - if FSorted <> Value then - begin - if Value then Sort; - FSorted := Value; - end; -end; - -procedure TTntStringList.SetUpdateState(Updating: Boolean); -begin - FUpdating := Updating; - if Updating then Changing else Changed; -end; - -function WideStringListCompareStrings(List: TTntStringList; Index1, Index2: Integer): Integer; -begin - Result := List.CompareStrings(List.FList^[Index1].FString, - List.FList^[Index2].FString); -end; - -procedure TTntStringList.Sort; -begin - CustomSort(WideStringListCompareStrings); -end; - -procedure TTntStringList.CustomSort(Compare: TWideStringListSortCompare); -begin - if not Sorted and (FCount > 1) then - begin - Changing; - QuickSort(0, FCount - 1, Compare); - Changed; - end; -end; - -function TTntStringList.CompareStrings(const S1, S2: WideString): Integer; -begin - if CaseSensitive then - Result := WideCompareStr(S1, S2) - else - Result := WideCompareText(S1, S2); -end; - -procedure TTntStringList.SetCaseSensitive(const Value: Boolean); -begin - if Value <> FCaseSensitive then - begin - FCaseSensitive := Value; - if Sorted then Sort; - end; -end; - -//------------------------- TntClasses introduced procs ---------------------------------- - -function AutoDetectCharacterSet(Stream: TStream): TTntStreamCharSet; -var - ByteOrderMark: WideChar; - BytesRead: Integer; - Utf8Test: array[0..2] of AnsiChar; -begin - // Byte Order Mark - ByteOrderMark := #0; - if (Stream.Size - Stream.Position) >= SizeOf(ByteOrderMark) then begin - BytesRead := Stream.Read(ByteOrderMark, SizeOf(ByteOrderMark)); - if (ByteOrderMark <> UNICODE_BOM) and (ByteOrderMark <> UNICODE_BOM_SWAPPED) then begin - ByteOrderMark := #0; - Stream.Seek(-BytesRead, soFromCurrent); - if (Stream.Size - Stream.Position) >= Length(Utf8Test) * SizeOf(AnsiChar) then begin - BytesRead := Stream.Read(Utf8Test[0], Length(Utf8Test) * SizeOf(AnsiChar)); - if Utf8Test <> UTF8_BOM then - Stream.Seek(-BytesRead, soFromCurrent); - end; - end; - end; - // Test Byte Order Mark - if ByteOrderMark = UNICODE_BOM then - Result := csUnicode - else if ByteOrderMark = UNICODE_BOM_SWAPPED then - Result := csUnicodeSwapped - else if Utf8Test = UTF8_BOM then - Result := csUtf8 - else - Result := csAnsi; -end; - -function FindSortedListByTarget(List: TList; TargetCompare: TListTargetCompare; - Target: Pointer; var Index: Integer): Boolean; -var - L, H, I, C: Integer; -begin - Result := False; - L := 0; - H := List.Count - 1; - while L <= H do - begin - I := (L + H) shr 1; - C := TargetCompare(List[i], Target); - if C < 0 then L := I + 1 else - begin - H := I - 1; - if C = 0 then - begin - Result := True; - L := I; - end; - end; - end; - Index := L; -end; - -function ClassIsRegistered(const clsid: TCLSID): Boolean; -var - OleStr: POleStr; - Reg: TRegIniFile; - Key, Filename: WideString; -begin - // First, check to see if there is a ProgID. This will tell if the - // control is registered on the machine. No ProgID, control won't run - Result := ProgIDFromCLSID(clsid, OleStr) = S_OK; - if not Result then Exit; //Bail as soon as anything goes wrong. - - // Next, make sure that the file is actually there by rooting it out - // of the registry - Key := WideFormat('\SOFTWARE\Classes\CLSID\%s', [GUIDToString(clsid)]); - Reg := TRegIniFile.Create; - try - Reg.RootKey := HKEY_LOCAL_MACHINE; - Result := Reg.OpenKeyReadOnly(Key); - if not Result then Exit; // Bail as soon as anything goes wrong. - - FileName := Reg.ReadString('InProcServer32', '', EmptyStr); - if (Filename = EmptyStr) then // try another key for the file name - begin - FileName := Reg.ReadString('InProcServer', '', EmptyStr); - end; - Result := Filename <> EmptyStr; - if not Result then Exit; - Result := WideFileExists(Filename); - finally - Reg.Free; - end; -end; - -{ TBufferedAnsiString } - -procedure TBufferedAnsiString.Clear; -begin - LastWriteIndex := 0; - if Length(FStringBuffer) > 0 then - FillChar(FStringBuffer[1], Length(FStringBuffer) * SizeOf(AnsiChar), 0); -end; - -procedure TBufferedAnsiString.AddChar(const wc: AnsiChar); -const - MIN_GROW_SIZE = 32; - MAX_GROW_SIZE = 256; -var - GrowSize: Integer; -begin - Inc(LastWriteIndex); - if LastWriteIndex > Length(FStringBuffer) then begin - GrowSize := Max(MIN_GROW_SIZE, Length(FStringBuffer)); - GrowSize := Min(GrowSize, MAX_GROW_SIZE); - SetLength(FStringBuffer, Length(FStringBuffer) + GrowSize); - FillChar(FStringBuffer[LastWriteIndex], GrowSize * SizeOf(AnsiChar), 0); - end; - FStringBuffer[LastWriteIndex] := wc; -end; - -procedure TBufferedAnsiString.AddString(const s: AnsiString); -var - LenS: Integer; - BlockSize: Integer; - AllocSize: Integer; -begin - LenS := Length(s); - if LenS > 0 then begin - Inc(LastWriteIndex); - if LastWriteIndex + LenS - 1 > Length(FStringBuffer) then begin - // determine optimum new allocation size - BlockSize := Length(FStringBuffer) div 2; - if BlockSize < 8 then - BlockSize := 8; - AllocSize := ((LenS div BlockSize) + 1) * BlockSize; - // realloc buffer - SetLength(FStringBuffer, Length(FStringBuffer) + AllocSize); - FillChar(FStringBuffer[Length(FStringBuffer) - AllocSize + 1], AllocSize * SizeOf(AnsiChar), 0); - end; - CopyMemory(@FStringBuffer[LastWriteIndex], @s[1], LenS * SizeOf(AnsiChar)); - Inc(LastWriteIndex, LenS - 1); - end; -end; - -procedure TBufferedAnsiString.AddBuffer(Buff: PAnsiChar; Chars: Integer); -var - i: integer; -begin - for i := 1 to Chars do begin - if Buff^ = #0 then - break; - AddChar(Buff^); - Inc(Buff); - end; -end; - -function TBufferedAnsiString.Value: AnsiString; -begin - Result := PAnsiChar(FStringBuffer); -end; - -function TBufferedAnsiString.BuffPtr: PAnsiChar; -begin - Result := PAnsiChar(FStringBuffer); -end; - -{ TBufferedWideString } - -procedure TBufferedWideString.Clear; -begin - LastWriteIndex := 0; - if Length(FStringBuffer) > 0 then - FillChar(FStringBuffer[1], Length(FStringBuffer) * SizeOf(WideChar), 0); -end; - -procedure TBufferedWideString.AddChar(const wc: WideChar); -const - MIN_GROW_SIZE = 32; - MAX_GROW_SIZE = 256; -var - GrowSize: Integer; -begin - Inc(LastWriteIndex); - if LastWriteIndex > Length(FStringBuffer) then begin - GrowSize := Max(MIN_GROW_SIZE, Length(FStringBuffer)); - GrowSize := Min(GrowSize, MAX_GROW_SIZE); - SetLength(FStringBuffer, Length(FStringBuffer) + GrowSize); - FillChar(FStringBuffer[LastWriteIndex], GrowSize * SizeOf(WideChar), 0); - end; - FStringBuffer[LastWriteIndex] := wc; -end; - -procedure TBufferedWideString.AddString(const s: WideString); -var - i: integer; -begin - for i := 1 to Length(s) do - AddChar(s[i]); -end; - -procedure TBufferedWideString.AddBuffer(Buff: PWideChar; Chars: Integer); -var - i: integer; -begin - for i := 1 to Chars do begin - if Buff^ = #0 then - break; - AddChar(Buff^); - Inc(Buff); - end; -end; - -function TBufferedWideString.Value: WideString; -begin - Result := PWideChar(FStringBuffer); -end; - -function TBufferedWideString.BuffPtr: PWideChar; -begin - Result := PWideChar(FStringBuffer); -end; - -{ TBufferedStreamReader } - -constructor TBufferedStreamReader.Create(Stream: TStream; BufferSize: Integer = 1024); -begin - // init stream - FStream := Stream; - FStreamSize := Stream.Size; - // init buffer - FBufferSize := BufferSize; - SetLength(FBuffer, BufferSize); - FBufferStartPosition := -FBufferSize; { out of any useful range } - // init virtual position - FVirtualPosition := 0; -end; - -function TBufferedStreamReader.Seek(Offset: Integer; Origin: Word): Longint; -begin - case Origin of - soFromBeginning: FVirtualPosition := Offset; - soFromCurrent: Inc(FVirtualPosition, Offset); - soFromEnd: FVirtualPosition := FStreamSize + Offset; - end; - Result := FVirtualPosition; -end; - -procedure TBufferedStreamReader.UpdateBufferFromPosition(StartPos: Integer); -begin - try - FStream.Position := StartPos; - FStream.Read(FBuffer[0], FBufferSize); - FBufferStartPosition := StartPos; - except - FBufferStartPosition := -FBufferSize; { out of any useful range } - raise; - end; -end; - -function TBufferedStreamReader.Read(var Buffer; Count: Integer): Longint; -var - BytesLeft: Integer; - FirstBufferRead: Integer; - StreamDirectRead: Integer; - Buf: PAnsiChar; -begin - if (FVirtualPosition >= 0) and (Count >= 0) then - begin - Result := FStreamSize - FVirtualPosition; - if Result > 0 then - begin - if Result > Count then - Result := Count; - - Buf := @Buffer; - BytesLeft := Result; - - // try to read what is left in buffer - FirstBufferRead := FBufferStartPosition + FBufferSize - FVirtualPosition; - if (FirstBufferRead < 0) or (FirstBufferRead > FBufferSize) then - FirstBufferRead := 0; - FirstBufferRead := Min(FirstBufferRead, Result); - if FirstBufferRead > 0 then begin - Move(FBuffer[FVirtualPosition - FBufferStartPosition], Buf[0], FirstBufferRead); - Dec(BytesLeft, FirstBufferRead); - end; - - if BytesLeft > 0 then begin - // The first read in buffer was not enough - StreamDirectRead := (BytesLeft div FBufferSize) * FBufferSize; - FStream.Position := FVirtualPosition + FirstBufferRead; - FStream.Read(Buf[FirstBufferRead], StreamDirectRead); - Dec(BytesLeft, StreamDirectRead); - - if BytesLeft > 0 then begin - // update buffer, and read what is left - UpdateBufferFromPosition(FStream.Position); - Move(FBuffer[0], Buf[FirstBufferRead + StreamDirectRead], BytesLeft); - end; - end; - - Inc(FVirtualPosition, Result); - Exit; - end; - end; - Result := 0; -end; - -function TBufferedStreamReader.Write(const Buffer; Count: Integer): Longint; -begin - raise ETntInternalError.Create('Internal Error: class can not write.'); - Result := 0; -end; - -//-------- synced wide string ----------------- - -function GetSyncedWideString(var WideStr: WideString; const AnsiStr: AnsiString): WideString; -begin - if AnsiString(WideStr) <> (AnsiStr) then begin - WideStr := AnsiStr; {AnsiStr changed. Keep WideStr in sync.} - end; - Result := WideStr; -end; - -procedure SetSyncedWideString(const Value: WideString; var WideStr: WideString; - const AnsiStr: AnsiString; SetAnsiStr: TSetAnsiStrEvent); -begin - if Value <> GetSyncedWideString(WideStr, AnsiStr) then - begin - if (not WideSameStr(Value, AnsiString(Value))) {unicode chars lost in conversion} - and (AnsiStr = AnsiString(Value)) {AnsiStr is not going to change} - then begin - SetAnsiStr(''); {force the change} - end; - WideStr := Value; - SetAnsiStr(Value); - end; -end; - -{ TWideComponentHelper } - -function CompareComponentHelperToTarget(Item, Target: Pointer): Integer; -begin - if Integer(TWideComponentHelper(Item).FComponent) < Integer(Target) then - Result := -1 - else if Integer(TWideComponentHelper(Item).FComponent) > Integer(Target) then - Result := 1 - else - Result := 0; -end; - -function FindWideComponentHelperIndex(ComponentHelperList: TComponentList; Component: TComponent; var Index: Integer): Boolean; -begin - // find Component in sorted wide caption list (list is sorted by TWideComponentHelper.FComponent) - Result := FindSortedListByTarget(ComponentHelperList, CompareComponentHelperToTarget, Component, Index); -end; - -constructor TWideComponentHelper.Create(AOwner: TComponent); -begin - raise ETntInternalError.Create('TNT Internal Error: TWideComponentHelper.Create should never be encountered.'); -end; - -constructor TWideComponentHelper.CreateHelper(AOwner: TComponent; ComponentHelperList: TComponentList); -var - Index: Integer; -begin - // don't use direct ownership for memory management - inherited Create(nil); - FComponent := AOwner; - FComponent.FreeNotification(Self); - - // insert into list according to sort - FindWideComponentHelperIndex(ComponentHelperList, FComponent, Index); - ComponentHelperList.Insert(Index, Self); -end; - -procedure TWideComponentHelper.Notification(AComponent: TComponent; Operation: TOperation); -begin - inherited; - if (AComponent = FComponent) and (Operation = opRemove) then begin - FComponent := nil; - Free; - end; -end; - -function FindWideComponentHelper(ComponentHelperList: TComponentList; Component: TComponent): TWideComponentHelper; -var - Index: integer; -begin - if FindWideComponentHelperIndex(ComponentHelperList, Component, Index) then begin - Result := TWideComponentHelper(ComponentHelperList[Index]); - Assert(Result.FComponent = Component, 'TNT Internal Error: FindWideComponentHelperIndex failed.'); - end else - Result := nil; -end; - -initialization - RuntimeUTFStreaming := False; { Delphi 6 and higher don't need UTF help at runtime. } - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntClipBrd.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntClipBrd.pas deleted file mode 100644 index e6c5a27c4..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntClipBrd.pas +++ /dev/null @@ -1,86 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntClipBrd; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Windows, Clipbrd; - -type -{TNT-WARN TClipboard} - TTntClipboard = class(TClipboard{TNT-ALLOW TClipboard}) - private - function GetAsWideText: WideString; - procedure SetAsWideText(const Value: WideString); - public - property AsWideText: WideString read GetAsWideText write SetAsWideText; - property AsText: WideString read GetAsWideText write SetAsWideText; - end; - -{TNT-WARN Clipboard} -function TntClipboard: TTntClipboard; - -implementation - -{ TTntClipboard } - -function TTntClipboard.GetAsWideText: WideString; -var - Data: THandle; -begin - Open; - Data := GetClipboardData(CF_UNICODETEXT); - try - if Data <> 0 then - Result := PWideChar(GlobalLock(Data)) - else - Result := ''; - finally - if Data <> 0 then GlobalUnlock(Data); - Close; - end; - if (Data = 0) or (Result = '') then - Result := inherited AsText -end; - -procedure TTntClipboard.SetAsWideText(const Value: WideString); -begin - Open; - try - inherited AsText := Value; {Ensures ANSI compatiblity across platforms.} - SetBuffer(CF_UNICODETEXT, PWideChar(Value)^, (Length(Value) + 1) * SizeOf(WideChar)); - finally - Close; - end; -end; - -//------------------------------------------ - -var - GTntClipboard: TTntClipboard; - -function TntClipboard: TTntClipboard; -begin - if GTntClipboard = nil then - GTntClipboard := TTntClipboard.Create; - Result := GTntClipboard; -end; - -initialization - -finalization - GTntClipboard.Free; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntComCtrls.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntComCtrls.pas deleted file mode 100644 index 0c12b2fcd..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntComCtrls.pas +++ /dev/null @@ -1,5058 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntComCtrls; - -{$INCLUDE TntCompilers.inc} - -interface - -{ TODO: TTntCustomListView events - reintroduce ones that refer to ansi classes (ie. TListItem) } -{ TODO: Handle RichEdit CRLF emulation at the WndProc level. } -{ TODO: TTntCustomTreeView events - reintroduce ones that refer to ansi classes (ie. TTreeNode) } -{ TODO: THotKey, Tanimate, TCoolBar (TCoolBand) } -{ TODO: TToolBar: Unicode-enable TBN_GETBUTTONINFO/DoGetButton } -{ TODO: TToolBar: Unicode-enable handling of CN_DIALOGCHAR, WM_SYSCOMMAND, FindButtonFromAccel } - -uses - Classes, Controls, ListActns, Menus, ComCtrls, Messages, - Windows, CommCtrl, Contnrs, TntControls, TntClasses, Graphics, TntSysUtils; - -type - TTntCustomListView = class; - TTntListItems = class; - -{TNT-WARN TListColumn} - TTntListColumn = class(TListColumn{TNT-ALLOW TListColumn}) - private - FCaption: WideString; - procedure SetInheritedCaption(const Value: AnsiString); - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - end; - -{TNT-WARN TListColumns} - TTntListColumns = class(TListColumns{TNT-ALLOW TListColumns}) - private - function GetItem(Index: Integer): TTntListColumn; - procedure SetItem(Index: Integer; Value: TTntListColumn); - public - constructor Create(AOwner: TTntCustomListView); - function Add: TTntListColumn; - function Owner: TTntCustomListView; - property Items[Index: Integer]: TTntListColumn read GetItem write SetItem; default; - end; - -{TNT-WARN TListItem} - TTntListItem = class(TListItem{TNT-ALLOW TListItem}) - private - FCaption: WideString; - FSubItems: TTntStrings; - procedure SetInheritedCaption(const Value: AnsiString); - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - procedure SetSubItems(const Value: TTntStrings); - function GetListView: TTntCustomListView; - function GetTntOwner: TTntListItems; - public - constructor Create(AOwner: TListItems{TNT-ALLOW TListItems}); virtual; - destructor Destroy; override; - property Owner: TTntListItems read GetTntOwner; - property ListView: TTntCustomListView read GetListView; - procedure Assign(Source: TPersistent); override; - property Caption: WideString read GetCaption write SetCaption; - property SubItems: TTntStrings read FSubItems write SetSubItems; - end; - - TTntListItemsEnumerator = class - private - FIndex: Integer; - FListItems: TTntListItems; - public - constructor Create(AListItems: TTntListItems); - function GetCurrent: TTntListItem; - function MoveNext: Boolean; - property Current: TTntListItem read GetCurrent; - end; - -{TNT-WARN TListItems} - TTntListItems = class(TListItems{TNT-ALLOW TListItems}) - private - function GetItem(Index: Integer): TTntListItem; - procedure SetItem(Index: Integer; const Value: TTntListItem); - public - function Owner: TTntCustomListView; - property Item[Index: Integer]: TTntListItem read GetItem write SetItem; default; - function Add: TTntListItem; - function AddItem(Item: TTntListItem; Index: Integer = -1): TTntListItem; - function GetEnumerator: TTntListItemsEnumerator; - function Insert(Index: Integer): TTntListItem; - end; - - TTntLVEditedEvent = procedure(Sender: TObject; Item: TTntListItem; var S: WideString) of object; - TTntLVOwnerDataFindEvent = procedure(Sender: TObject; Find: TItemFind; - const FindString: WideString; const FindPosition: TPoint; FindData: Pointer; - StartIndex: Integer; Direction: TSearchDirection; Wrap: Boolean; - var Index: Integer) of object; - -{TNT-WARN TCustomListView} - _TntInternalCustomListView = class(TCustomListView{TNT-ALLOW TCustomListView}) - private - PWideFindString: PWideChar; - CurrentDispInfo: PLVDispInfoW; - OriginalDispInfoMask: Cardinal; - function OwnerDataFindW(Find: TItemFind; const FindString: WideString; - const FindPosition: TPoint; FindData: Pointer; StartIndex: Integer; - Direction: TSearchDirection; Wrap: Boolean): Integer; virtual; abstract; - function OwnerDataFetchW(Item: TListItem{TNT-ALLOW TListItem}; Request: TItemRequest): Boolean; virtual; abstract; - protected - function OwnerDataFind(Find: TItemFind; const FindString: AnsiString; - const FindPosition: TPoint; FindData: Pointer; StartIndex: Integer; - Direction: TSearchDirection; Wrap: Boolean): Integer; override; - function OwnerDataFetch(Item: TListItem{TNT-ALLOW TListItem}; Request: TItemRequest): Boolean; override; - end; - - TTntCustomListView = class(_TntInternalCustomListView, IWideCustomListControl) - private - FEditHandle: THandle; - FEditInstance: Pointer; - FDefEditProc: Pointer; - FOnEdited: TTntLVEditedEvent; - FOnDataFind: TTntLVOwnerDataFindEvent; - procedure EditWndProcW(var Message: TMessage); - procedure BeginChangingWideItem; - procedure EndChangingWideItem; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - function GetListColumns: TTntListColumns; - procedure SetListColumns(const Value: TTntListColumns); - function ColumnFromIndex(Index: Integer): TTntListColumn; - function GetColumnFromTag(Tag: Integer): TTntListColumn; - function OwnerDataFindW(Find: TItemFind; const FindString: WideString; - const FindPosition: TPoint; FindData: Pointer; StartIndex: Integer; - Direction: TSearchDirection; Wrap: Boolean): Integer; override; - function OwnerDataFetchW(Item: TListItem{TNT-ALLOW TListItem}; Request: TItemRequest): Boolean; override; - function GetDropTarget: TTntListItem; - procedure SetDropTarget(const Value: TTntListItem); - function GetItemFocused: TTntListItem; - procedure SetItemFocused(const Value: TTntListItem); - function GetSelected: TTntListItem; - procedure SetSelected(const Value: TTntListItem); - function GetTopItem: TTntListItem; - private - FSavedItems: TObjectList; - FTestingForSortProc: Boolean; - FChangingWideItemCount: Integer; - FTempItem: TTntListItem; - function AreItemsStored: Boolean; - function GetItems: TTntListItems; - procedure SetItems(Value: TTntListItems); - procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY; - function GetItemW(Value: TLVItemW): TTntListItem; - procedure WMNotify(var Message: TWMNotify); message WM_NOTIFY; - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - procedure CreateWnd; override; - procedure DestroyWnd; override; - procedure WndProc(var Message: TMessage); override; - function OwnerDataFetch(Item: TListItem{TNT-ALLOW TListItem}; Request: TItemRequest): Boolean; reintroduce; virtual; - function CreateListItem: TListItem{TNT-ALLOW TListItem}; override; - function CreateListItems: TListItems{TNT-ALLOW TListItems}; override; - property Items: TTntListItems read GetItems write SetItems stored AreItemsStored; - procedure Edit(const Item: TLVItem); override; - function OwnerDataFind(Find: TItemFind; const FindString: WideString; - const FindPosition: TPoint; FindData: Pointer; StartIndex: Integer; - Direction: TSearchDirection; Wrap: Boolean): Integer; reintroduce; virtual; - property Columns: TTntListColumns read GetListColumns write SetListColumns; - procedure DrawItem(Item: TListItem{TNT-ALLOW TListItem}; Rect: TRect; State: TOwnerDrawState); override; - property OnEdited: TTntLVEditedEvent read FOnEdited write FOnEdited; - property OnDataFind: TTntLVOwnerDataFindEvent read FOnDataFind write FOnDataFind; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - property Column[Index: Integer]: TTntListColumn read ColumnFromIndex; - procedure CopySelection(Destination: TCustomListControl); override; - procedure AddItem(const Item: WideString; AObject: TObject); reintroduce; virtual; - function FindCaption(StartIndex: Integer; Value: WideString; Partial, - Inclusive, Wrap: Boolean): TTntListItem; - function GetSearchString: WideString; - function StringWidth(S: WideString): Integer; - public - property DropTarget: TTntListItem read GetDropTarget write SetDropTarget; - property ItemFocused: TTntListItem read GetItemFocused write SetItemFocused; - property Selected: TTntListItem read GetSelected write SetSelected; - property TopItem: TTntListItem read GetTopItem; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TListView} - TTntListView = class(TTntCustomListView) - published - property Action; - property Align; - property AllocBy; - property Anchors; - property BevelEdges; - property BevelInner; - property BevelOuter; - property BevelKind default bkNone; - property BevelWidth; - property BiDiMode; - property BorderStyle; - property BorderWidth; - property Checkboxes; - property Color; - property Columns; - property ColumnClick; - property Constraints; - property Ctl3D; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property Font; - property FlatScrollBars; - property FullDrag; - property GridLines; - property HideSelection; - property HotTrack; - property HotTrackStyles; - property HoverTime; - property IconOptions; - property Items; - property LargeImages; - property MultiSelect; - property OwnerData; - property OwnerDraw; - property ReadOnly default False; - property RowSelect; - property ParentBiDiMode; - property ParentColor default False; - property ParentFont; - property ParentShowHint; - property PopupMenu; - property ShowColumnHeaders; - property ShowWorkAreas; - property ShowHint; - property SmallImages; - property SortType; - property StateImages; - property TabOrder; - property TabStop default True; - property ViewStyle; - property Visible; - property OnAdvancedCustomDraw; - property OnAdvancedCustomDrawItem; - property OnAdvancedCustomDrawSubItem; - property OnChange; - property OnChanging; - property OnClick; - property OnColumnClick; - property OnColumnDragged; - property OnColumnRightClick; - property OnCompare; - property OnContextPopup; - property OnCustomDraw; - property OnCustomDrawItem; - property OnCustomDrawSubItem; - property OnData; - property OnDataFind; - property OnDataHint; - property OnDataStateChange; - property OnDblClick; - property OnDeletion; - property OnDrawItem; - property OnEdited; - property OnEditing; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnGetImageIndex; - property OnGetSubItemImage; - property OnDragDrop; - property OnDragOver; - property OnInfoTip; - property OnInsert; - property OnKeyDown; - property OnKeyPress; - property OnKeyUp; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - property OnResize; - property OnSelectItem; - property OnStartDock; - property OnStartDrag; - end; - -type -{TNT-WARN TToolButton} - TTntToolButton = class(TToolButton{TNT-ALLOW TToolButton}) - private - procedure CMVisibleChanged(var Message: TMessage); message CM_VISIBLECHANGED; - function GetCaption: TWideCaption; - procedure SetCaption(const Value: TWideCaption); - function IsCaptionStored: Boolean; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - procedure CMHintShow(var Message: TMessage); message CM_HINTSHOW; - function GetMenuItem: TMenuItem{TNT-ALLOW TMenuItem}; - procedure SetMenuItem(const Value: TMenuItem{TNT-ALLOW TMenuItem}); - protected - procedure DefineProperties(Filer: TFiler); override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - function GetActionLinkClass: TControlActionLinkClass; override; - published - property Caption: TWideCaption read GetCaption write SetCaption stored IsCaptionStored; - property Hint: WideString read GetHint write SetHint stored IsHintStored; - property MenuItem: TMenuItem{TNT-ALLOW TMenuItem} read GetMenuItem write SetMenuItem; - end; - -type -{TNT-WARN TToolBar} - TTntToolBar = class(TToolBar{TNT-ALLOW TToolBar}) - private - FCaption: WideString; - procedure TBInsertButtonA(var Message: TMessage); message TB_INSERTBUTTONA; - procedure WMGetText(var Message: TWMGetText); message WM_GETTEXT; - procedure WMGetTextLength(var Message: TWMGetTextLength); message WM_GETTEXTLENGTH; - procedure WMSetText(var Message: TWMSetText); message WM_SETTEXT; - function GetMenu: TMainMenu{TNT-ALLOW TMainMenu}; - procedure SetMenu(const Value: TMainMenu{TNT-ALLOW TMainMenu}); - private - function GetCaption: WideString; - function GetHint: WideString; - function IsCaptionStored: Boolean; - function IsHintStored: Boolean; - procedure SetCaption(const Value: WideString); - procedure SetHint(const Value: WideString); - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - function GetActionLinkClass: TControlActionLinkClass; override; - published - property Caption: WideString read GetCaption write SetCaption stored IsCaptionStored; - property Hint: WideString read GetHint write SetHint stored IsHintStored; - property Menu: TMainMenu{TNT-ALLOW TMainMenu} read GetMenu write SetMenu; - end; - -type -{TNT-WARN TCustomRichEdit} - TTntCustomRichEdit = class(TCustomRichEdit{TNT-ALLOW TCustomRichEdit}) - private - FRichEditStrings: TTntStrings; - FPrintingTextLength: Integer; - procedure WMGetTextLength(var Message: TWMGetTextLength); message WM_GETTEXTLENGTH; - procedure SetRichEditStrings(const Value: TTntStrings); - function GetWideSelText: WideString; - function GetText: WideString; - procedure SetWideSelText(const Value: WideString); - procedure SetText(const Value: WideString); - function GetHint: WideString; - function IsHintStored: Boolean; - procedure SetHint(const Value: WideString); - procedure SetRTFText(Flags: DWORD; const Value: AnsiString); - protected - procedure CreateParams(var Params: TCreateParams); override; - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure CreateWnd; override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - procedure KeyDown(var Key: Word; Shift: TShiftState); override; - function GetSelText: string{TNT-ALLOW string}; override; - function CharPosToGet(RawWin32CharPos: Integer): Integer; deprecated; // use EmulatedCharPos() - function CharPosToSet(EmulatedCharPos: Integer): Integer; deprecated; // use RawWin32CharPos() - function GetSelStart: Integer; reintroduce; virtual; - procedure SetSelStart(const Value: Integer); reintroduce; virtual; - function GetSelLength: Integer; reintroduce; virtual; - procedure SetSelLength(const Value: Integer); reintroduce; virtual; - function LineBreakStyle: TTntTextLineBreakStyle; - property Lines: TTntStrings read FRichEditStrings write SetRichEditStrings; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - // - function EmulatedCharPos(RawWin32CharPos: Integer): Integer; - function RawWin32CharPos(EmulatedCharPos: Integer): Integer; - // - procedure Print(const Caption: string{TNT-ALLOW string}); override; - property SelText: WideString read GetWideSelText write SetWideSelText; - property SelStart: Integer read GetSelStart write SetSelStart; - property SelLength: Integer read GetSelLength write SetSelLength; - property Text: WideString read GetText write SetText; - function FindText(const SearchStr: WideString; StartPos, - Length: Integer; Options: TSearchTypes): Integer; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TRichEdit} - TTntRichEdit = class(TTntCustomRichEdit) - published - property Align; - property Alignment; - property Anchors; - property BevelEdges; - property BevelInner; - property BevelOuter; - property BevelKind default bkNone; - property BevelWidth; - property BiDiMode; - property BorderStyle; - property BorderWidth; - property Color; - property Ctl3D; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property Font; - property HideSelection; - property HideScrollBars; - property ImeMode; - property ImeName; - property Constraints; - property Lines; - property MaxLength; - property ParentBiDiMode; - property ParentColor; - property ParentCtl3D; - property ParentFont; - property ParentShowHint; - property PlainText; - property PopupMenu; - property ReadOnly; - property ScrollBars; - property ShowHint; - property TabOrder; - property TabStop default True; - property Visible; - property WantTabs; - property WantReturns; - property WordWrap; - property OnChange; - property OnClick; - property OnContextPopup; - property OnDblClick; - property OnDragDrop; - property OnDragOver; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnKeyDown; - property OnKeyPress; - property OnKeyUp; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - property OnMouseWheel; - property OnMouseWheelDown; - property OnMouseWheelUp; - property OnProtectChange; - property OnResizeRequest; - property OnSaveClipboard; - property OnSelectionChange; - property OnStartDock; - property OnStartDrag; - end; - -type -{TNT-WARN TCustomTabControl} - TTntCustomTabControl = class(TCustomTabControl{TNT-ALLOW TCustomTabControl}) - private - FTabs: TTntStrings; - FSaveTabIndex: Integer; - FSaveTabs: TTntStrings; - function GetTabs: TTntStrings; - procedure SetTabs(const Value: TTntStrings); - procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR; - function GetHint: WideString; - function IsHintStored: Boolean; - procedure SetHint(const Value: WideString); - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - procedure CreateWnd; override; - procedure DestroyWnd; override; - property Tabs: TTntStrings read GetTabs write SetTabs; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TTabControl} - TTntTabControl = class(TTntCustomTabControl) - public - property DisplayRect; - published - property Align; - property Anchors; - property BiDiMode; - property Constraints; - property DockSite; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property Font; - property HotTrack; - property Images; - property MultiLine; - property MultiSelect; - property OwnerDraw; - property ParentBiDiMode; - property ParentFont; - property ParentShowHint; - property PopupMenu; - property RaggedRight; - property ScrollOpposite; - property ShowHint; - property Style; - property TabHeight; - property TabOrder; - property TabPosition; - property Tabs; - property TabIndex; // must be after Tabs - property TabStop; - property TabWidth; - property Visible; - property OnChange; - property OnChanging; - property OnContextPopup; - property OnDockDrop; - property OnDockOver; - property OnDragDrop; - property OnDragOver; - property OnDrawTab; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnGetImageIndex; - property OnGetSiteInfo; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - property OnResize; - property OnStartDock; - property OnStartDrag; - property OnUnDock; - end; - -type -{TNT-WARN TTabSheet} - TTntTabSheet = class(TTabSheet{TNT-ALLOW TTabSheet}) - private - Force_Inherited_WMSETTEXT: Boolean; - function IsCaptionStored: Boolean; - function GetCaption: TWideCaption; - procedure SetCaption(const Value: TWideCaption); - procedure WMSetText(var Message: TWMSetText); message WM_SETTEXT; - function GetHint: WideString; - function IsHintStored: Boolean; - procedure SetHint(const Value: WideString); - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - published - property Caption: TWideCaption read GetCaption write SetCaption stored IsCaptionStored; - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TPageControl} - TTntPageControl = class(TPageControl{TNT-ALLOW TPageControl}) - private - FNewDockSheet: TTntTabSheet; - function IsHintStored: Boolean; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR; - procedure CMDockNotification(var Message: TCMDockNotification); message CM_DOCKNOTIFICATION; - procedure CMDockClient(var Message: TCMDockClient); message CM_DOCKCLIENT; - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - procedure WndProc(var Message: TMessage); override; - procedure DoAddDockClient(Client: TControl; const ARect: TRect); override; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TTrackBar} - TTntTrackBar = class(TTrackBar{TNT-ALLOW TTrackBar}) - private - function IsHintStored: Boolean; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TProgressBar} - TTntProgressBar = class(TProgressBar{TNT-ALLOW TProgressBar}) - private - function IsHintStored: Boolean; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TCustomUpDown} - TTntCustomUpDown = class(TCustomUpDown{TNT-ALLOW TCustomUpDown}) - private - function IsHintStored: Boolean; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TUpDown} - TTntUpDown = class(TTntCustomUpDown) - published - property AlignButton; - property Anchors; - property Associate; - property ArrowKeys; - property Enabled; - property Hint; - property Min; - property Max; - property Increment; - property Constraints; - property Orientation; - property ParentShowHint; - property PopupMenu; - property Position; - property ShowHint; - property TabOrder; - property TabStop; - property Thousands; - property Visible; - property Wrap; - property OnChanging; - property OnChangingEx; - property OnContextPopup; - property OnClick; - property OnEnter; - property OnExit; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - end; - -{TNT-WARN TDateTimePicker} - TTntDateTimePicker = class(TDateTimePicker{TNT-ALLOW TDateTimePicker}) - private - FHadFirstMouseClick: Boolean; - function IsHintStored: Boolean; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN; - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure CreateWnd; override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TMonthCalendar} - TTntMonthCalendar = class(TMonthCalendar{TNT-ALLOW TMonthCalendar}) - private - function IsHintStored: Boolean; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function GetDate: TDate; - procedure SetDate(const Value: TDate); - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - public - procedure ForceGetMonthInfo; - published - property Date: TDate read GetDate write SetDate; - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TPageScroller} - TTntPageScroller = class(TPageScroller{TNT-ALLOW TPageScroller}) - private - function IsHintStored: Boolean; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -type -{TNT-WARN TStatusPanel} - TTntStatusPanel = class(TStatusPanel{TNT-ALLOW TStatusPanel}) - private - FText: WideString; - function GetText: Widestring; - procedure SetText(const Value: Widestring); - procedure SetInheritedText(const Value: AnsiString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Text: Widestring read GetText write SetText; - end; - -{TNT-WARN TStatusPanels} - TTntStatusPanels = class(TStatusPanels{TNT-ALLOW TStatusPanels}) - private - function GetItem(Index: Integer): TTntStatusPanel; - procedure SetItem(Index: Integer; Value: TTntStatusPanel); - public - function Add: TTntStatusPanel; - function AddItem(Item: TTntStatusPanel; Index: Integer): TTntStatusPanel; - function Insert(Index: Integer): TTntStatusPanel; - property Items[Index: Integer]: TTntStatusPanel read GetItem write SetItem; default; - end; - -{TNT-WARN TCustomStatusBar} - TTntCustomStatusBar = class(TCustomStatusBar{TNT-ALLOW TCustomStatusBar}) - private - FSimpleText: WideString; - function GetSimpleText: WideString; - procedure SetSimpleText(const Value: WideString); - procedure SetInheritedSimpleText(const Value: AnsiString); - function SyncLeadingTabs(const WideVal: WideString; const AnsiVal: AnsiString): WideString; - function GetHint: WideString; - function IsHintStored: Boolean; - procedure SetHint(const Value: WideString); - procedure WMGetTextLength(var Message: TWMGetTextLength); message WM_GETTEXTLENGTH; - function GetPanels: TTntStatusPanels; - procedure SetPanels(const Value: TTntStatusPanels); - protected - procedure DefineProperties(Filer: TFiler); override; - function CreatePanels: TStatusPanels{TNT-ALLOW TStatusPanels}; override; - function GetPanelClass: TStatusPanelClass; override; - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure WndProc(var Msg: TMessage); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - public - function ExecuteAction(Action: TBasicAction): Boolean; override; - property Panels: TTntStatusPanels read GetPanels write SetPanels; - property SimpleText: WideString read GetSimpleText write SetSimpleText; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TStatusBar} - TTntStatusBar = class(TTntCustomStatusBar) - private - function GetOnDrawPanel: TDrawPanelEvent; - procedure SetOnDrawPanel(const Value: TDrawPanelEvent); - published - property Action; - property AutoHint default False; - property Align default alBottom; - property Anchors; - property BiDiMode; - property BorderWidth; - property Color default clBtnFace; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property Font stored IsFontStored; - property Constraints; - property Panels; - property ParentBiDiMode; - property ParentColor default False; - property ParentFont default False; - property ParentShowHint; - property PopupMenu; - property ShowHint; - property SimplePanel {$IFDEF COMPILER_7_UP} default False {$ENDIF}; - property SimpleText; - property SizeGrip default True; - property UseSystemFont default True; - property Visible; - property OnClick; - property OnContextPopup; - property OnCreatePanelClass; - property OnDblClick; - property OnDragDrop; - property OnDragOver; - property OnEndDock; - property OnEndDrag; - property OnHint; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - // Required for backwards compatibility with the old event signature - property OnDrawPanel: TDrawPanelEvent read GetOnDrawPanel write SetOnDrawPanel; - property OnResize; - property OnStartDock; - property OnStartDrag; - end; - -type - TTntTreeNodes = class; - TTntCustomTreeView = class; - -{TNT-WARN TTreeNode} - TTntTreeNode = class(TTreeNode{TNT-ALLOW TTreeNode}) - private - FText: WideString; - procedure SetText(const Value: WideString); - procedure SetInheritedText(const Value: AnsiString); - function GetText: WideString; - function GetItem(Index: Integer): TTntTreeNode; - function GetNodeOwner: TTntTreeNodes; - function GetParent: TTntTreeNode; - function GetTreeView: TTntCustomTreeView; - procedure SetItem(Index: Integer; const Value: TTntTreeNode); - function IsEqual(Node: TTntTreeNode): Boolean; - procedure ReadData(Stream: TStream; Info: PNodeInfo); - procedure WriteData(Stream: TStream; Info: PNodeInfo); - public - procedure Assign(Source: TPersistent); override; - function getFirstChild: TTntTreeNode; {GetFirstChild conflicts with C++ macro} - function GetLastChild: TTntTreeNode; - function GetNext: TTntTreeNode; - function GetNextChild(Value: TTntTreeNode): TTntTreeNode; - function getNextSibling: TTntTreeNode; {GetNextSibling conflicts with C++ macro} - function GetNextVisible: TTntTreeNode; - function GetPrev: TTntTreeNode; - function GetPrevChild(Value: TTntTreeNode): TTntTreeNode; - function getPrevSibling: TTntTreeNode; {GetPrevSibling conflicts with a C++ macro} - function GetPrevVisible: TTntTreeNode; - property Item[Index: Integer]: TTntTreeNode read GetItem write SetItem; default; - property Owner: TTntTreeNodes read GetNodeOwner; - property Parent: TTntTreeNode read GetParent; - property Text: WideString read GetText write SetText; - property TreeView: TTntCustomTreeView read GetTreeView; - end; - - TTntTreeNodeClass = class of TTntTreeNode; - - TTntTreeNodesEnumerator = class - private - FIndex: Integer; - FTreeNodes: TTntTreeNodes; - public - constructor Create(ATreeNodes: TTntTreeNodes); - function GetCurrent: TTntTreeNode; - function MoveNext: Boolean; - property Current: TTntTreeNode read GetCurrent; - end; - -{TNT-WARN TTreeNodes} - TTntTreeNodes = class(TTreeNodes{TNT-ALLOW TTreeNodes}) - private - function GetNodeFromIndex(Index: Integer): TTntTreeNode; - function GetNodesOwner: TTntCustomTreeView; - procedure ClearCache; - procedure ReadData(Stream: TStream); - procedure WriteData(Stream: TStream); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - function Add(Sibling: TTntTreeNode; const S: WideString): TTntTreeNode; - function AddChild(Parent: TTntTreeNode; const S: WideString): TTntTreeNode; - function AddChildFirst(Parent: TTntTreeNode; const S: WideString): TTntTreeNode; - function AddChildObject(Parent: TTntTreeNode; const S: WideString; - Ptr: Pointer): TTntTreeNode; - function AddChildObjectFirst(Parent: TTntTreeNode; const S: WideString; - Ptr: Pointer): TTntTreeNode; - function AddFirst(Sibling: TTntTreeNode; const S: WideString): TTntTreeNode; - function AddObject(Sibling: TTntTreeNode; const S: WideString; - Ptr: Pointer): TTntTreeNode; - function AddObjectFirst(Sibling: TTntTreeNode; const S: WideString; - Ptr: Pointer): TTntTreeNode; - function Insert(Sibling: TTntTreeNode; const S: WideString): TTntTreeNode; - function InsertObject(Sibling: TTntTreeNode; const S: WideString; - Ptr: Pointer): TTntTreeNode; - function InsertNode(Node, Sibling: TTntTreeNode; const S: WideString; - Ptr: Pointer): TTntTreeNode; - function AddNode(Node, Relative: TTntTreeNode; const S: WideString; - Ptr: Pointer; Method: TNodeAttachMode): TTntTreeNode; - public - function GetFirstNode: TTntTreeNode; - function GetEnumerator: TTntTreeNodesEnumerator; - function GetNode(ItemId: HTreeItem): TTntTreeNode; - property Item[Index: Integer]: TTntTreeNode read GetNodeFromIndex; default; - property Owner: TTntCustomTreeView read GetNodesOwner; - end; - - TTntTVEditedEvent = procedure(Sender: TObject; Node: TTntTreeNode; var S: WideString) of object; - -{TNT-WARN TCustomTreeView} - _TntInternalCustomTreeView = class(TCustomTreeView{TNT-ALLOW TCustomTreeView}) - private - function Wide_FindNextToSelect: TTntTreeNode; virtual; abstract; - function Inherited_FindNextToSelect: TTreeNode{TNT-ALLOW TTreeNode}; - public - function FindNextToSelect: TTreeNode{TNT-ALLOW TTreeNode}; override; - end; - - TTntCustomTreeView = class(_TntInternalCustomTreeView) - private - FSavedNodeText: TTntStrings; - FSavedSortType: TSortType; - FOnEdited: TTntTVEditedEvent; - FTestingForSortProc: Boolean; - FEditHandle: THandle; - FEditInstance: Pointer; - FDefEditProc: Pointer; - function GetTreeNodes: TTntTreeNodes; - procedure SetTreeNodes(const Value: TTntTreeNodes); - procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY; - procedure WMNotify(var Message: TWMNotify); message WM_NOTIFY; - function GetNodeFromItem(const Item: TTVItem): TTntTreeNode; - procedure EditWndProcW(var Message: TMessage); - function Wide_FindNextToSelect: TTntTreeNode; override; - function GetDropTarget: TTntTreeNode; - function GetSelected: TTntTreeNode; - function GetSelection(Index: Integer): TTntTreeNode; - function GetTopItem: TTntTreeNode; - procedure SetDropTarget(const Value: TTntTreeNode); - procedure SetSelected(const Value: TTntTreeNode); - procedure SetTopItem(const Value: TTntTreeNode); - function GetHint: WideString; - function IsHintStored: Boolean; - procedure SetHint(const Value: WideString); - protected - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure CreateWnd; override; - procedure DestroyWnd; override; - procedure DefineProperties(Filer: TFiler); override; - procedure WndProc(var Message: TMessage); override; - procedure Edit(const Item: TTVItem); override; - function CreateNode: TTreeNode{TNT-ALLOW TTreeNode}; override; - function CreateNodes: TTreeNodes{TNT-ALLOW TTreeNodes}; override; - property Items: TTntTreeNodes read GetTreeNodes write SetTreeNodes; - property OnEdited: TTntTVEditedEvent read FOnEdited write FOnEdited; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - procedure LoadFromFile(const FileName: WideString); - procedure LoadFromStream(Stream: TStream); - procedure SaveToFile(const FileName: WideString); - procedure SaveToStream(Stream: TStream); - function GetNodeAt(X, Y: Integer): TTntTreeNode; - property DropTarget: TTntTreeNode read GetDropTarget write SetDropTarget; - property Selected: TTntTreeNode read GetSelected write SetSelected; - property TopItem: TTntTreeNode read GetTopItem write SetTopItem; - property Selections[Index: Integer]: TTntTreeNode read GetSelection; - function GetSelections(AList: TList): TTntTreeNode; - function FindNextToSelect: TTntTreeNode; reintroduce; virtual; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TTreeView} - TTntTreeView = class(TTntCustomTreeView) - published - property Align; - property Anchors; - property AutoExpand; - property BevelEdges; - property BevelInner; - property BevelOuter; - property BevelKind default bkNone; - property BevelWidth; - property BiDiMode; - property BorderStyle; - property BorderWidth; - property ChangeDelay; - property Color; - property Ctl3D; - property Constraints; - property DragKind; - property DragCursor; - property DragMode; - property Enabled; - property Font; - property HideSelection; - property HotTrack; - property Images; - property Indent; - property MultiSelect; - property MultiSelectStyle; - property ParentBiDiMode; - property ParentColor default False; - property ParentCtl3D; - property ParentFont; - property ParentShowHint; - property PopupMenu; - property ReadOnly; - property RightClickSelect; - property RowSelect; - property ShowButtons; - property ShowHint; - property ShowLines; - property ShowRoot; - property SortType; - property StateImages; - property TabOrder; - property TabStop default True; - property ToolTips; - property Visible; - property OnAddition; - property OnAdvancedCustomDraw; - property OnAdvancedCustomDrawItem; - property OnChange; - property OnChanging; - property OnClick; - property OnCollapsed; - property OnCollapsing; - property OnCompare; - property OnContextPopup; - property OnCreateNodeClass; - property OnCustomDraw; - property OnCustomDrawItem; - property OnDblClick; - property OnDeletion; - property OnDragDrop; - property OnDragOver; - property OnEdited; - property OnEditing; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnExpanding; - property OnExpanded; - property OnGetImageIndex; - property OnGetSelectedIndex; - property OnKeyDown; - property OnKeyPress; - property OnKeyUp; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - property OnStartDock; - property OnStartDrag; - { Items must be published after OnGetImageIndex and OnGetSelectedIndex } - property Items; - end; - -implementation - -uses - Forms, SysUtils, TntGraphics, ImgList, TntSystem, TntStdCtrls, StdCtrls, - RichEdit, ActiveIMM_TLB, TntForms, ComStrs, TntMenus, - TntActnList, TntStdActns, TntWindows, - {$IFNDEF COMPILER_10_UP} - TntWideStrings, - {$ELSE} - WideStrings, - {$ENDIF} - {$IFDEF COMPILER_9_UP} WideStrUtils {$ELSE} TntWideStrUtils {$ENDIF}; - -procedure CreateUnicodeHandle_ComCtl(Control: TWinControl; const Params: TCreateParams; - const SubClass: WideString); -begin - Assert(SubClass <> '', 'TNT Internal Error: Only call CreateUnicodeHandle_ComCtl for Common Controls.'); - CreateUnicodeHandle(Control, Params, SubClass); - if Win32PlatformIsUnicode then - SendMessageW(Control.Handle, CCM_SETUNICODEFORMAT, Integer(True), 0); -end; - -{ TTntListColumn } - -procedure TTntListColumn.Assign(Source: TPersistent); -begin - inherited; - if Source is TTntListColumn then - Caption := TTntListColumn(Source).Caption - else if Source is TListColumn{TNT-ALLOW TListColumn} then - FCaption := TListColumn{TNT-ALLOW TListColumn}(Source).Caption; -end; - -procedure TTntListColumn.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -procedure TTntListColumn.SetInheritedCaption(const Value: AnsiString); -begin - inherited Caption := Value; -end; - -function TTntListColumn.GetCaption: WideString; -begin - Result := GetSyncedWideString(FCaption, inherited Caption); -end; - -procedure TTntListColumn.SetCaption(const Value: WideString); -begin - SetSyncedWideString(Value, FCaption, inherited Caption, SetInheritedCaption); -end; - -{ TTntListColumns } - -{$IFDEF COMPILER_6} // verified against VCL source in Delphi 6 and BCB 6 -type - THackCollection = class(TPersistent) - protected - FItemClass: TCollectionItemClass; - end; -{$ENDIF} -{$IFDEF DELPHI_7} // verified against VCL source in Delphi 7 -type - THackCollection = class(TPersistent) - protected - FItemClass: TCollectionItemClass; - end; -{$ENDIF} -{$IFDEF DELPHI_9} // verified against VCL source in Delphi 9 -type - THackCollection = class(TPersistent) - protected - FItemClass: TCollectionItemClass; - end; -{$ENDIF} -{$IFDEF DELPHI_10} // verified against VCL source in Delphi 10 -type - THackCollection = class(TPersistent) - protected - FItemClass: TCollectionItemClass; - end; -{$ENDIF} - -constructor TTntListColumns.Create(AOwner: TTntCustomListView); -begin - inherited Create(AOwner); - Assert(THackCollection(Self).FItemClass = Self.ItemClass, 'Internal Error in TTntListColumns.Create().'); - THackCollection(Self).FItemClass := TTntListColumn -end; - -function TTntListColumns.Owner: TTntCustomListView; -begin - Result := inherited Owner as TTntCustomListView; -end; - -function TTntListColumns.Add: TTntListColumn; -begin - Result := (inherited Add) as TTntListColumn; -end; - -function TTntListColumns.GetItem(Index: Integer): TTntListColumn; -begin - Result := inherited Items[Index] as TTntListColumn; -end; - -procedure TTntListColumns.SetItem(Index: Integer; Value: TTntListColumn); -begin - inherited SetItem(Index, Value); -end; - -{ TWideSubItems } -type - TWideSubItems = class(TTntStringList) - private - FIgnoreInherited: Boolean; - FInheritedOwner: TListItem{TNT-ALLOW TListItem}; - FOwner: TTntListItem; - protected - procedure Put(Index: Integer; const S: WideString); override; - function GetObject(Index: Integer): TObject; override; - procedure PutObject(Index: Integer; AObject: TObject); override; - procedure SetUpdateState(Updating: Boolean); override; - public - procedure Insert(Index: Integer; const S: WideString); override; - function AddObject(const S: WideString; AObject: TObject): Integer; override; - procedure Clear; override; - procedure Delete(Index: Integer); override; - public - constructor Create(AOwner: TTntListItem); - end; - -constructor TWideSubItems.Create(AOwner: TTntListItem); -begin - inherited Create; - FInheritedOwner := AOwner; - FOwner := AOwner; -end; - -function TWideSubItems.AddObject(const S: WideString; AObject: TObject): Integer; -begin - FOwner.ListView.BeginChangingWideItem; - try - Result := inherited AddObject(S, AObject); - if (not FIgnoreInherited) then - FInheritedOwner.SubItems.AddObject(S, AObject); - finally - FOwner.ListView.EndChangingWideItem; - end; -end; - -procedure TWideSubItems.Clear; -begin - FOwner.ListView.BeginChangingWideItem; - try - inherited; - if (not FIgnoreInherited) then - FInheritedOwner.SubItems.Clear; - finally - FOwner.ListView.EndChangingWideItem; - end; -end; - -procedure TWideSubItems.Delete(Index: Integer); -begin - FOwner.ListView.BeginChangingWideItem; - try - inherited; - if (not FIgnoreInherited) then - FInheritedOwner.SubItems.Delete(Index); - finally - FOwner.ListView.EndChangingWideItem; - end; -end; - -procedure TWideSubItems.Insert(Index: Integer; const S: WideString); -begin - FOwner.ListView.BeginChangingWideItem; - try - inherited; - if (not FIgnoreInherited) then - FInheritedOwner.SubItems.Insert(Index, S); - finally - FOwner.ListView.EndChangingWideItem; - end; -end; - -procedure TWideSubItems.Put(Index: Integer; const S: WideString); -begin - FOwner.ListView.BeginChangingWideItem; - try - inherited; - if (not FIgnoreInherited) then - FInheritedOwner.SubItems[Index] := S; - finally - FOwner.ListView.EndChangingWideItem; - end; -end; - -function TWideSubItems.GetObject(Index: Integer): TObject; -begin - Result := FInheritedOwner.SubItems.Objects[Index]; -end; - -procedure TWideSubItems.PutObject(Index: Integer; AObject: TObject); -begin - FInheritedOwner.SubItems.Objects[Index] := AObject; -end; - -type TAccessStrings = class(TStrings{TNT-ALLOW TStrings}); - -procedure TWideSubItems.SetUpdateState(Updating: Boolean); -begin - inherited; - TAccessStrings(FInheritedOwner.SubItems).SetUpdateState(Updating); -end; - -{ TTntListItem } - -constructor TTntListItem.Create(AOwner: TListItems{TNT-ALLOW TListItems}); -begin - inherited Create(AOwner); - FSubItems := TWideSubItems.Create(Self); -end; - -destructor TTntListItem.Destroy; -begin - inherited; - FreeAndNil(FSubItems); -end; - -function TTntListItem.GetCaption: WideString; -begin - Result := GetSyncedWideString(FCaption, inherited Caption); -end; - -procedure TTntListItem.SetInheritedCaption(const Value: AnsiString); -begin - inherited Caption := Value; -end; - -procedure TTntListItem.SetCaption(const Value: WideString); -begin - ListView.BeginChangingWideItem; - try - SetSyncedWideString(Value, FCaption, inherited Caption, SetInheritedCaption); - finally - ListView.EndChangingWideItem; - end; -end; - -procedure TTntListItem.Assign(Source: TPersistent); -begin - if Source is TTntListItem then - with Source as TTntListItem do - begin - Self.Caption := Caption; - Self.Data := Data; - Self.ImageIndex := ImageIndex; - Self.Indent := Indent; - Self.OverlayIndex := OverlayIndex; - Self.StateIndex := StateIndex; - Self.SubItems := SubItems; - Self.Checked := Checked; - end - else inherited Assign(Source); -end; - -procedure TTntListItem.SetSubItems(const Value: TTntStrings); -begin - if Value <> nil then - FSubItems.Assign(Value); -end; - -function TTntListItem.GetTntOwner: TTntListItems; -begin - Result := ListView.Items; -end; - -function TTntListItem.GetListView: TTntCustomListView; -begin - Result := ((inherited Owner).Owner as TTntCustomListView); -end; - -{ TTntListItemsEnumerator } - -constructor TTntListItemsEnumerator.Create(AListItems: TTntListItems); -begin - inherited Create; - FIndex := -1; - FListItems := AListItems; -end; - -function TTntListItemsEnumerator.GetCurrent: TTntListItem; -begin - Result := FListItems[FIndex]; -end; - -function TTntListItemsEnumerator.MoveNext: Boolean; -begin - Result := FIndex < FListItems.Count - 1; - if Result then - Inc(FIndex); -end; - -{ TTntListItems } - -function TTntListItems.Add: TTntListItem; -begin - Result := (inherited Add) as TTntListItem; -end; - -function TTntListItems.AddItem(Item: TTntListItem; Index: Integer): TTntListItem; -begin - Result := (inherited AddItem(Item, Index)) as TTntListItem; -end; - -function TTntListItems.Insert(Index: Integer): TTntListItem; -begin - Result := (inherited Insert(Index)) as TTntListItem; -end; - -function TTntListItems.GetItem(Index: Integer): TTntListItem; -begin - Result := (inherited Item[Index]) as TTntListItem; -end; - -function TTntListItems.Owner: TTntCustomListView; -begin - Result := (inherited Owner) as TTntCustomListView; -end; - -procedure TTntListItems.SetItem(Index: Integer; const Value: TTntListItem); -begin - inherited Item[Index] := Value; -end; - -function TTntListItems.GetEnumerator: TTntListItemsEnumerator; -begin - Result := TTntListItemsEnumerator.Create(Self); -end; - -{ TSavedListItem } -type - TSavedListItem = class - FCaption: WideString; - FSubItems: TTntStrings; - constructor Create; - destructor Destroy; override; - end; - -constructor TSavedListItem.Create; -begin - inherited; - FSubItems := TTntStringList.Create; -end; - -destructor TSavedListItem.Destroy; -begin - FSubItems.Free; - inherited; -end; - -{ _TntInternalCustomListView } - -function _TntInternalCustomListView.OwnerDataFind(Find: TItemFind; - const FindString: AnsiString; const FindPosition: TPoint; - FindData: Pointer; StartIndex: Integer; Direction: TSearchDirection; - Wrap: Boolean): Integer; -var - WideFindString: WideString; -begin - if Assigned(PWideFindString) then - WideFindString := PWideFindString - else - WideFindString := FindString; - Result := OwnerDataFindW(Find, WideFindString, FindPosition, FindData, StartIndex, Direction, Wrap); -end; - -function _TntInternalCustomListView.OwnerDataFetch(Item: TListItem{TNT-ALLOW TListItem}; - Request: TItemRequest): Boolean; -begin - if (CurrentDispInfo <> nil) - and (OriginalDispInfoMask and LVIF_TEXT <> 0) then begin - (Item as TTntListItem).FCaption := CurrentDispInfo.item.pszText - end; - (Item as TTntListItem).FSubItems.Clear; - Result := OwnerDataFetchW(Item, Request); -end; - -{ TTntCustomListView } - -{$IFDEF COMPILER_6} // verified against VCL source in Delphi 6 and BCB 6 -type - THackCustomListView = class(TCustomMultiSelectListControl) - protected - FxxxCanvas: TCanvas; - FxxxBorderStyle: TBorderStyle; - FxxxViewStyle: TViewStyle; - FxxxReadOnly: Boolean; - FxxxLargeImages: TCustomImageList; - FxxxSmallImages: TCustomImageList; - FxxxStateImages: TCustomImageList; - FxxxDragImage: TDragImageList; - FxxxMultiSelect: Boolean; - FxxxSortType: TSortType; - FxxxColumnClick: Boolean; - FxxxShowColumnHeaders: Boolean; - FxxxListItems: TListItems{TNT-ALLOW TListItems}; - FxxxClicked: Boolean; - FxxxRClicked: Boolean; - FxxxIconOptions: TIconOptions; - FxxxHideSelection: Boolean; - FListColumns: TListColumns{TNT-ALLOW TListColumns}; - end; -{$ENDIF} -{$IFDEF DELPHI_7} // verified against VCL source in Delphi 7 -type - THackCustomListView = class(TCustomMultiSelectListControl) - protected - FxxxCanvas: TCanvas; - FxxxBorderStyle: TBorderStyle; - FxxxViewStyle: TViewStyle; - FxxxReadOnly: Boolean; - FxxxLargeImages: TCustomImageList; - FxxxSmallImages: TCustomImageList; - FxxxStateImages: TCustomImageList; - FxxxDragImage: TDragImageList; - FxxxMultiSelect: Boolean; - FxxxSortType: TSortType; - FxxxColumnClick: Boolean; - FxxxShowColumnHeaders: Boolean; - FxxxListItems: TListItems{TNT-ALLOW TListItems}; - FxxxClicked: Boolean; - FxxxRClicked: Boolean; - FxxxIconOptions: TIconOptions; - FxxxHideSelection: Boolean; - FListColumns: TListColumns{TNT-ALLOW TListColumns}; - end; -{$ENDIF} -{$IFDEF DELPHI_9} // verified against VCL source in Delphi 9 -type - THackCustomListView = class(TCustomMultiSelectListControl) - protected - FxxxCanvas: TCanvas; - FxxxBorderStyle: TBorderStyle; - FxxxViewStyle: TViewStyle; - FxxxReadOnly: Boolean; - FxxxLargeImages: TCustomImageList; - FxxxSmallImages: TCustomImageList; - FxxxStateImages: TCustomImageList; - FxxxDragImage: TDragImageList; - FxxxMultiSelect: Boolean; - FxxxSortType: TSortType; - FxxxColumnClick: Boolean; - FxxxShowColumnHeaders: Boolean; - FxxxListItems: TListItems{TNT-ALLOW TListItems}; - FxxxClicked: Boolean; - FxxxRClicked: Boolean; - FxxxIconOptions: TIconOptions; - FxxxHideSelection: Boolean; - FListColumns: TListColumns{TNT-ALLOW TListColumns}; - end; -{$ENDIF} -{$IFDEF DELPHI_10} // verified against VCL source in Delphi 10 -type - THackCustomListView = class(TCustomMultiSelectListControl) - protected - FxxxCanvas: TCanvas; - FxxxBorderStyle: TBorderStyle; - FxxxViewStyle: TViewStyle; - FxxxReadOnly: Boolean; - FxxxLargeImages: TCustomImageList; - FxxxSaveSelectedIndex: Integer; - FxxxSmallImages: TCustomImageList; - FxxxStateImages: TCustomImageList; - FxxxDragImage: TDragImageList; - FxxxMultiSelect: Boolean; - FxxxSortType: TSortType; - FxxxColumnClick: Boolean; - FxxxShowColumnHeaders: Boolean; - FxxxListItems: TListItems{TNT-ALLOW TListItems}; - FxxxClicked: Boolean; - FxxxRClicked: Boolean; - FxxxIconOptions: TIconOptions; - FxxxHideSelection: Boolean; - FListColumns: TListColumns{TNT-ALLOW TListColumns}; - end; -{$ENDIF} - -var - ComCtrls_DefaultListViewSort: TLVCompare = nil; - -constructor TTntCustomListView.Create(AOwner: TComponent); -begin - inherited; - FEditInstance := Classes.MakeObjectInstance(EditWndProcW); - // create list columns - Assert(THackCustomListView(Self).FListColumns = inherited Columns, 'Internal Error in TTntCustomListView.Create().'); - FreeAndNil(THackCustomListView(Self).FListColumns); - THackCustomListView(Self).FListColumns := TTntListColumns.Create(Self); -end; - -destructor TTntCustomListView.Destroy; -begin - inherited; - Classes.FreeObjectInstance(FEditInstance); - FreeAndNil(FSavedItems); -end; - -procedure TTntCustomListView.CreateWindowHandle(const Params: TCreateParams); - - procedure Capture_ComCtrls_DefaultListViewSort; - begin - FTestingForSortProc := True; - try - AlphaSort; - finally - FTestingForSortProc := False; - end; - end; - -var - Column: TLVColumn; -begin - CreateUnicodeHandle_ComCtl(Self, Params, WC_LISTVIEW); - if (Win32PlatformIsUnicode) then begin - if not Assigned(ComCtrls_DefaultListViewSort) then - Capture_ComCtrls_DefaultListViewSort; - // the only way I could get editing to work is after a column had been inserted - Column.mask := 0; - ListView_InsertColumn(Handle, 0, Column); - ListView_DeleteColumn(Handle, 0); - end; -end; - -procedure TTntCustomListView.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -procedure TTntCustomListView.CreateWnd; -begin - inherited; - FreeAndNil(FSavedItems); -end; - -procedure TTntCustomListView.DestroyWnd; -var - i: integer; - FSavedItem: TSavedListItem; - Item: TTntListItem; -begin - if (not (csDestroying in ComponentState)) and (not OwnerData) then begin - FreeAndNil(FSavedItems); // fixes a bug on Windows 95. - FSavedItems := TObjectList.Create(True); - for i := 0 to Items.Count - 1 do begin - FSavedItem := TSavedListItem.Create; - Item := Items[i]; - FSavedItem.FCaption := Item.FCaption; - FSavedItem.FSubItems.Assign(Item.FSubItems); - FSavedItems.Add(FSavedItem) - end; - end; - inherited; -end; - -function TTntCustomListView.GetDropTarget: TTntListItem; -begin - Result := inherited DropTarget as TTntListItem; -end; - -procedure TTntCustomListView.SetDropTarget(const Value: TTntListItem); -begin - inherited DropTarget := Value; -end; - -function TTntCustomListView.GetItemFocused: TTntListItem; -begin - Result := inherited ItemFocused as TTntListItem; -end; - -procedure TTntCustomListView.SetItemFocused(const Value: TTntListItem); -begin - inherited ItemFocused := Value; -end; - -function TTntCustomListView.GetSelected: TTntListItem; -begin - Result := inherited Selected as TTntListItem; -end; - -procedure TTntCustomListView.SetSelected(const Value: TTntListItem); -begin - inherited Selected := Value; -end; - -function TTntCustomListView.GetTopItem: TTntListItem; -begin - Result := inherited TopItem as TTntListItem; -end; - -function TTntCustomListView.GetListColumns: TTntListColumns; -begin - Result := inherited Columns as TTntListColumns; -end; - -procedure TTntCustomListView.SetListColumns(const Value: TTntListColumns); -begin - inherited Columns := Value; -end; - -{$IFDEF COMPILER_6} // verified against VCL source in Delphi 6 and BCB 6 -type - THackListColumn = class(TCollectionItem) - protected - FxxxAlignment: TAlignment; - FxxxAutoSize: Boolean; - FxxxCaption: AnsiString; - FxxxMaxWidth: TWidth; - FxxxMinWidth: TWidth; - FxxxImageIndex: TImageIndex; - FxxxPrivateWidth: TWidth; - FxxxWidth: TWidth; - FOrderTag: Integer; - end; -{$ENDIF} -{$IFDEF DELPHI_7} // verified against VCL source in Delphi 7 -type - THackListColumn = class(TCollectionItem) - protected - FxxxAlignment: TAlignment; - FxxxAutoSize: Boolean; - FxxxCaption: AnsiString; - FxxxMaxWidth: TWidth; - FxxxMinWidth: TWidth; - FxxxImageIndex: TImageIndex; - FxxxPrivateWidth: TWidth; - FxxxWidth: TWidth; - FOrderTag: Integer; - end; -{$ENDIF} -{$IFDEF DELPHI_9} // verified against VCL source in Delphi 9 -type - THackListColumn = class(TCollectionItem) - protected - FxxxxxxxxAlignment: TAlignment; - FxxxxAutoSize: Boolean; - FxxxxCaption: AnsiString; - FxxxxMaxWidth: TWidth; - FxxxxMinWidth: TWidth; - FxxxxImageIndex: TImageIndex; - FxxxxPrivateWidth: TWidth; - FxxxxWidth: TWidth; - FOrderTag: Integer; - end; -{$ENDIF} -{$IFDEF DELPHI_10} // verified against VCL source in Delphi 10 -type - THackListColumn = class(TCollectionItem) - protected - FxxxxxxxxAlignment: TAlignment; - FxxxxAutoSize: Boolean; - FxxxxCaption: AnsiString; - FxxxxMaxWidth: TWidth; - FxxxxMinWidth: TWidth; - FxxxxImageIndex: TImageIndex; - FxxxxPrivateWidth: TWidth; - FxxxxWidth: TWidth; - FOrderTag: Integer; - end; -{$ENDIF} - -function TTntCustomListView.GetColumnFromTag(Tag: Integer): TTntListColumn; -var - I: Integer; -begin - for I := 0 to Columns.Count - 1 do - begin - Result := Columns[I]; - if THackListColumn(Result).FOrderTag = Tag then Exit; - end; - Result := nil; -end; - -function TTntCustomListView.ColumnFromIndex(Index: Integer): TTntListColumn; -begin - Result := inherited Column[Index] as TTntListColumn; -end; - -function TTntCustomListView.AreItemsStored: Boolean; -begin - if Assigned(Action) then - begin - if Action is TCustomListAction{TNT-ALLOW TCustomListAction} then - Result := False - else - Result := True; - end - else - Result := not OwnerData; -end; - -function TTntCustomListView.GetItems: TTntListItems; -begin - Result := inherited Items as TTntListItems; -end; - -procedure TTntCustomListView.SetItems(Value: TTntListItems); -begin - inherited Items := Value; -end; - -type TTntListItemClass = class of TTntListItem; - -function TTntCustomListView.CreateListItem: TListItem{TNT-ALLOW TListItem}; -var - LClass: TClass; - TntLClass: TTntListItemClass; -begin - LClass := TTntListItem; - if Assigned(OnCreateItemClass) then - OnCreateItemClass(Self, TListItemClass(LClass)); - if not LClass.InheritsFrom(TTntListItem) then - raise ETntInternalError.Create('Internal Error: OnCreateItemClass.ItemClass must inherit from TTntListItem.'); - TntLClass := TTntListItemClass(LClass); - Result := TntLClass.Create(inherited Items); - if FTempItem = nil then - FTempItem := Result as TTntListItem; { In Delphi 5/6/7/9/10, the first item created is the temp item } - { TODO: Verify that D11 creates a temp item in its constructor. } -end; - -function TTntCustomListView.CreateListItems: TListItems{TNT-ALLOW TListItems}; -begin - Result := TTntListItems.Create(Self); -end; - -function TTntCustomListView.GetItemW(Value: TLVItemW): TTntListItem; -begin - with Value do begin - if (mask and LVIF_PARAM) <> 0 then - Result := TListItem{TNT-ALLOW TListItem}(lParam) as TTntListItem - else if iItem >= 0 then - Result := Items[IItem] - else if OwnerData then - Result := FTempItem - else - Result := nil - end; -end; - -function TTntCustomListView.OwnerDataFetchW(Item: TListItem{TNT-ALLOW TListItem}; Request: TItemRequest): Boolean; -begin - Result := OwnerDataFetch(Item, Request); -end; - -function TTntCustomListView.OwnerDataFetch(Item: TListItem{TNT-ALLOW TListItem}; Request: TItemRequest): Boolean; -begin - if Assigned(OnData) then - begin - OnData(Self, Item); - Result := True; - end - else Result := False; -end; - -function TntDefaultListViewSort(Item1, Item2: TTntListItem; lParam: Integer): Integer; stdcall; -begin - Assert(Win32PlatformIsUnicode); - with Item1 do - if Assigned(ListView.OnCompare) then - ListView.OnCompare(ListView, Item1, Item2, lParam, Result) - else Result := lstrcmpw(PWideChar(Item1.Caption), PWideChar(Item2.Caption)); -end; - -procedure TTntCustomListView.WndProc(var Message: TMessage); -var - Item: TTntListItem; - InheritedItem: TListItem{TNT-ALLOW TListItem}; - SubItem: Integer; - SavedItem: TSavedListItem; - PCol: PLVColumn; - Col: TTntListColumn; -begin - with Message do begin - // restore previous values (during CreateWnd) - if (FSavedItems <> nil) and (FChangingWideItemCount = 0) and (Msg = LVM_SETITEMTEXTA) then begin - Item := Items[wParam]; - SavedItem := TSavedListItem(FSavedItems[wParam]); - if (Msg = LVM_SETITEMTEXTA) and (PLVItem(lParam).iSubItem = 0) then - Item.FCaption := SavedItem.FCaption - else begin - SubItem := PLVItem(lParam).iSubItem - 1; - TWideSubItems(Item.SubItems).FIgnoreInherited := True; - try - if SubItem < Item.SubItems.Count then begin - Item.SubItems[SubItem] := SavedItem.FSubItems[SubItem]; - Item.SubItems.Objects[SubItem] := SavedItem.FSubItems.Objects[SubItem] - end else if SubItem = Item.SubItems.Count then - Item.SubItems.AddObject(SavedItem.FSubItems[SubItem], SavedItem.FSubItems.Objects[SubItem]) - else - Item.SubItems.Assign(SavedItem.FSubItems) - finally - TWideSubItems(Item.SubItems).FIgnoreInherited := False; - end; - end; - end; - - // sync wide with ansi - if (FSavedItems = nil) and (FChangingWideItemCount = 0) and (Msg = LVM_UPDATE) then begin - Item := Items[wParam]; - InheritedItem := Item; - TWideSubItems(Item.SubItems).FIgnoreInherited := True; - try - Item.SubItems.Assign(InheritedItem.SubItems) - finally - TWideSubItems(Item.SubItems).FIgnoreInherited := False; - end; - end; - - if (FSavedItems = nil) and (FChangingWideItemCount = 0) and (Msg = LVM_SETITEMTEXTA) then begin - if OwnerData then - Item := FTempItem - else - Item := Items[wParam]; - InheritedItem := Item; - if (Msg = LVM_SETITEMTEXTA) and (PLVItem(lParam).iSubItem = 0) then - Item.FCaption := InheritedItem.Caption - else begin - SubItem := PLVItem(lParam).iSubItem - 1; - TWideSubItems(Item.SubItems).FIgnoreInherited := True; - try - if SubItem < Item.SubItems.Count then begin - Item.SubItems[SubItem] := InheritedItem.SubItems[SubItem]; - Item.SubItems.Objects[SubItem] := InheritedItem.SubItems.Objects[SubItem] - end else if SubItem = Item.SubItems.Count then - Item.SubItems.AddObject(InheritedItem.SubItems[SubItem], InheritedItem.SubItems.Objects[SubItem]) - else - Item.SubItems.Assign(InheritedItem.SubItems) - finally - TWideSubItems(Item.SubItems).FIgnoreInherited := False; - end; - end; - end; - - // capture ANSI version of DefaultListViewSort from ComCtrls - if (FTestingForSortProc) - and (Msg = LVM_SORTITEMS) then begin - ComCtrls_DefaultListViewSort := Pointer(lParam); - exit; - end; - - if (Msg = LVM_SETCOLUMNA) then begin - // make sure that wide column caption stays in sync with ANSI - PCol := PLVColumn(lParam); - if (PCol.mask and LVCF_TEXT) <> 0 then begin - Col := GetColumnFromTag(wParam); - if (Col <> nil) and (AnsiString(Col.Caption) <> PCol.pszText) then begin - Col.FCaption := PCol.pszText; - end; - end; - end; - - if (Win32PlatformIsUnicode) - and (Msg = LVM_SETITEMTEXTA) and (PLVItem(lParam).pszText = LPSTR_TEXTCALLBACK) then - // Unicode:: call wide version of text call back instead - Result := SendMessageW(Handle, LVM_SETITEMTEXTW, WParam, LParam) - else if (Win32PlatformIsUnicode) - and (Msg = LVM_SORTITEMS) and (Pointer(lParam) = @ComCtrls_DefaultListViewSort) then - // Unicode:: call wide version of sort proc instead - Result := SendMessageW(Handle, LVM_SORTITEMS, wParam, Integer(@TntDefaultListViewSort)) - else if (Win32PlatformIsUnicode) - and (Msg = LVM_SETCOLUMNA) and ((PLVColumn(lParam).mask and LVCF_TEXT) <> 0) - and (GetColumnFromTag(wParam) <> nil) then begin - PLVColumn(lParam).pszText := PAnsiChar(PWideChar(GetColumnFromTag(wParam).FCaption)); - Result := SendMessageW(Handle, LVM_SETCOLUMNW, wParam, lParam); - end else begin - if (Msg = LVM_SETEXTENDEDLISTVIEWSTYLE) and CheckBoxes then begin - { fix a bug in TCustomListView.ResetExStyles } - lParam := lParam or LVS_EX_SUBITEMIMAGES or LVS_EX_INFOTIP; - end; - inherited; - end; - end; -end; - -procedure TTntCustomListView.WMNotify(var Message: TWMNotify); -begin - inherited; - // capture updated info after inherited - with Message.NMHdr^ do - case code of - HDN_ENDTRACKW: - begin - Message.NMHdr^.code := HDN_ENDTRACKA; - try - inherited - finally - Message.NMHdr^.code := HDN_ENDTRACKW; - end; - end; - HDN_DIVIDERDBLCLICKW: - begin - Message.NMHdr^.code := HDN_DIVIDERDBLCLICKA; - try - inherited - finally - Message.NMHdr^.code := HDN_DIVIDERDBLCLICKW; - end; - end; - end; -end; - -procedure TTntCustomListView.CNNotify(var Message: TWMNotify); -var - Item: TTntListItem; -begin - if (not Win32PlatformIsUnicode) then - inherited - else begin - with Message do - begin - case NMHdr^.code of - HDN_TRACKW: - begin - NMHdr^.code := HDN_TRACKA; - try - inherited; - finally - NMHdr^.code := HDN_TRACKW; - end; - end; - LVN_GETDISPINFOW: - begin - // call inherited without the LVIF_TEXT flag - CurrentDispInfo := PLVDispInfoW(NMHdr); - try - OriginalDispInfoMask := PLVDispInfoW(NMHdr)^.item.mask; - - PLVDispInfoW(NMHdr)^.item.mask := PLVDispInfoW(NMHdr)^.item.mask and (not LVIF_TEXT); - try - NMHdr^.code := LVN_GETDISPINFOA; - try - inherited; - finally - NMHdr^.code := LVN_GETDISPINFOW; - end; - finally - if (OriginalDispInfoMask and LVIF_TEXT <> 0) then - PLVDispInfoW(NMHdr)^.item.mask := PLVDispInfoW(NMHdr)^.item.mask or LVIF_TEXT; - end; - finally - CurrentDispInfo := nil; - end; - - // handle any text info - with PLVDispInfoW(NMHdr)^.item do - begin - if (mask and LVIF_TEXT) <> 0 then - begin - Item := GetItemW(PLVDispInfoW(NMHdr)^.item); - if iSubItem = 0 then - WStrLCopy(pszText, PWideChar(Item.Caption), cchTextMax - 1) - else begin - with Item.SubItems do begin - if iSubItem <= Count then - WStrLCopy(pszText, PWideChar(Strings[iSubItem - 1]), cchTextMax - 1) - else pszText[0] := #0; - end; - end; - end; - end; - end; - LVN_ODFINDITEMW: - with PNMLVFindItem(NMHdr)^ do - begin - if ((lvfi.flags and LVFI_PARTIAL) <> 0) or ((lvfi.flags and LVFI_STRING) <> 0) then - PWideFindString := TLVFindInfoW(lvfi).psz - else - PWideFindString := nil; - lvfi.psz := nil; - NMHdr^.code := LVN_ODFINDITEMA; - try - inherited; {will Result in call to OwnerDataFind} - finally - TLVFindInfoW(lvfi).psz := PWideFindString; - NMHdr^.code := LVN_ODFINDITEMW; - PWideFindString := nil; - end; - end; - LVN_BEGINLABELEDITW: - begin - Item := GetItemW(PLVDispInfoW(NMHdr)^.item); - if not CanEdit(Item) then Result := 1; - if Result = 0 then - begin - FEditHandle := ListView_GetEditControl(Handle); - FDefEditProc := Pointer(GetWindowLongW(FEditHandle, GWL_WNDPROC)); - SetWindowLongW(FEditHandle, GWL_WNDPROC, LongInt(FEditInstance)); - end; - end; - LVN_ENDLABELEDITW: - with PLVDispInfoW(NMHdr)^ do - if (item.pszText <> nil) and (item.IItem <> -1) then - Edit(TLVItemA(item)); - LVN_GETINFOTIPW: - begin - NMHdr^.code := LVN_GETINFOTIPA; - try - inherited; - finally - NMHdr^.code := LVN_GETINFOTIPW; - end; - end; - else - inherited; - end; - end; - end; -end; - -function TTntCustomListView.OwnerDataFindW(Find: TItemFind; - const FindString: WideString; const FindPosition: TPoint; - FindData: Pointer; StartIndex: Integer; Direction: TSearchDirection; - Wrap: Boolean): Integer; -begin - Result := OwnerDataFind(Find, FindString, FindPosition, FindData, StartIndex, Direction, Wrap); -end; - -function TTntCustomListView.OwnerDataFind(Find: TItemFind; const FindString: WideString; - const FindPosition: TPoint; FindData: Pointer; StartIndex: Integer; - Direction: TSearchDirection; Wrap: Boolean): Integer; -var - AnsiEvent: TLVOwnerDataFindEvent; -begin - Result := -1; - if Assigned(OnDataFind) then - OnDataFind(Self, Find, FindString, FindPosition, FindData, StartIndex, Direction, Wrap, Result) - else if Assigned(inherited OnDataFind) then begin - AnsiEvent := inherited OnDataFind; - AnsiEvent(Self, Find, FindString, FindPosition, FindData, StartIndex, Direction, - Wrap, Result); - end; -end; - -procedure TTntCustomListView.Edit(const Item: TLVItem); -var - S: WideString; - AnsiS: AnsiString; - EditItem: TTntListItem; - AnsiEvent: TLVEditedEvent; -begin - if (not Win32PlatformIsUnicode) then - S := Item.pszText - else - S := TLVItemW(Item).pszText; - EditItem := GetItemW(TLVItemW(Item)); - if Assigned(OnEdited) then - OnEdited(Self, EditItem, S) - else if Assigned(inherited OnEdited) then - begin - AnsiEvent := inherited OnEdited; - AnsiS := S; - AnsiEvent(Self, EditItem, AnsiS); - S := AnsiS; - end; - if EditItem <> nil then - EditItem.Caption := S; -end; - -procedure TTntCustomListView.EditWndProcW(var Message: TMessage); -begin - Assert(Win32PlatformIsUnicode); - try - with Message do - begin - case Msg of - WM_KEYDOWN, - WM_SYSKEYDOWN: if DoKeyDown(TWMKey(Message)) then Exit; - WM_CHAR: - begin - MakeWMCharMsgSafeForAnsi(Message); - try - if DoKeyPress(TWMKey(Message)) then Exit; - finally - RestoreWMCharMsg(Message); - end; - end; - WM_KEYUP, - WM_SYSKEYUP: if DoKeyUp(TWMKey(Message)) then Exit; - CN_KEYDOWN, - CN_CHAR, CN_SYSKEYDOWN, - CN_SYSCHAR: - begin - WndProc(Message); - Exit; - end; - end; - Result := CallWindowProcW(FDefEditProc, FEditHandle, Msg, WParam, LParam); - end; - except - Application.HandleException(Self); - end; -end; - -procedure TTntCustomListView.BeginChangingWideItem; -begin - Inc(FChangingWideItemCount); -end; - -procedure TTntCustomListView.EndChangingWideItem; -begin - if FChangingWideItemCount > 0 then - Dec(FChangingWideItemCount); -end; - -procedure TTntCustomListView.DrawItem(Item: TListItem{TNT-ALLOW TListItem}; Rect: TRect; - State: TOwnerDrawState); -begin - TControlCanvas(Canvas).UpdateTextFlags; - if Assigned(OnDrawItem) then OnDrawItem(Self, Item, Rect, State) - else - begin - Canvas.FillRect(Rect); - WideCanvasTextOut(Canvas, Rect.Left + 2, Rect.Top, Item.Caption); - end; -end; - -procedure TTntCustomListView.CopySelection(Destination: TCustomListControl); -var - I: Integer; -begin - for I := 0 to Items.Count - 1 do - if Items[I].Selected then - WideListControl_AddItem(Destination, Items[I].Caption, Items[I].Data); -end; - -procedure TTntCustomListView.AddItem(const Item: WideString; AObject: TObject); -begin - with Items.Add do - begin - Caption := Item; - Data := AObject; - end; -end; - -//------------- - -function TTntCustomListView.FindCaption(StartIndex: Integer; Value: WideString; - Partial, Inclusive, Wrap: Boolean): TTntListItem; -const - FullString: array[Boolean] of Integer = (0, LVFI_PARTIAL); - Wraps: array[Boolean] of Integer = (0, LVFI_WRAP); -var - Info: TLVFindInfoW; - Index: Integer; -begin - if (not Win32PlatformIsUnicode) then - Result := inherited FindCaption(StartIndex, Value, Partial, Inclusive, Wrap) as TTntListItem - else begin - with Info do - begin - flags := LVFI_STRING or FullString[Partial] or Wraps[Wrap]; - psz := PWideChar(Value); - end; - if Inclusive then Dec(StartIndex); - Index := SendMessageW(Handle, LVM_FINDITEMW, StartIndex, Longint(@Info)); - if Index <> -1 then Result := Items[Index] - else Result := nil; - end; -end; - -function TTntCustomListView.StringWidth(S: WideString): Integer; -begin - if (not Win32PlatformIsUnicode) then - Result := inherited StringWidth(S) - else - Result := SendMessageW(Handle, LVM_GETSTRINGWIDTHW, 0, Longint(PWideChar(S))) -end; - -function TTntCustomListView.GetSearchString: WideString; -var - Buffer: array[0..1023] of WideChar; -begin - if (not Win32PlatformIsUnicode) then - Result := inherited GetSearchString - else begin - Result := ''; - if HandleAllocated - and Bool(SendMessageW(Handle, LVM_GETISEARCHSTRINGW, 0, Longint(PWideChar(@Buffer[0])))) then - Result := Buffer; - end; -end; - -function TTntCustomListView.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntCustomListView.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntCustomListView.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntCustomListView.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomListView.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntToolButton } - -procedure TTntToolButton.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -procedure TTntToolButton.CMVisibleChanged(var Message: TMessage); -begin - inherited; - RefreshControl; -end; - -function TTntToolButton.GetCaption: TWideCaption; -begin - Result := TntControl_GetText(Self); -end; - -procedure TTntToolButton.SetCaption(const Value: TWideCaption); -begin - TntControl_SetText(Self, Value); - RefreshControl; { causes button to be removed and reinserted with TB_INSERTBUTTON } -end; - -function TTntToolButton.IsCaptionStored: Boolean; -begin - Result := TntControl_IsCaptionStored(Self) -end; - -function TTntToolButton.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntToolButton.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -function TTntToolButton.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -procedure TTntToolButton.CMHintShow(var Message: TMessage); -begin - ProcessCMHintShowMsg(Message); - inherited; -end; - -procedure TTntToolButton.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntToolButton.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -function TTntToolButton.GetMenuItem: TMenuItem{TNT-ALLOW TMenuItem}; -begin - Result := inherited MenuItem; -end; - -procedure TTntToolButton.SetMenuItem(const Value: TMenuItem{TNT-ALLOW TMenuItem}); -begin - inherited MenuItem := Value; - if Value is TTntMenuItem then begin - Caption := TTntMenuItem(Value).Caption; - Hint := TTntMenuItem(Value).Hint; - end; -end; - -{ TTntToolBar } - -procedure TTntToolBar.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle_ComCtl(Self, Params, TOOLBARCLASSNAME); -end; - -procedure TTntToolBar.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -procedure TTntToolBar.TBInsertButtonA(var Message: TMessage); -var - Button: TTntToolButton; - Buffer: WideString; -begin - if Win32PlatformIsUnicode - and (PTBButton(Message.LParam).iString <> -1) - and (Buttons[Message.WParam] is TTntToolButton) then - begin - Button := TTntToolButton(Buttons[Message.WParam]); - Buffer := Button.Caption + WideChar(#0); - PTBButton(Message.LParam).iString := - SendMessage(Handle, TB_ADDSTRINGW, 0, Integer(PWideChar(Buffer))); - end; - inherited; -end; - -{ Need to read/write caption ourselves - default wndproc seems to discard it. } - -procedure TTntToolBar.WMGetText(var Message: TWMGetText); -begin - if (not Win32PlatformIsUnicode) or (WindowHandle = 0) then - inherited - else - with Message do - Result := WStrLen(WStrLCopy(PWideChar(Text), PWideChar(FCaption), TextMax - 1)); -end; - -procedure TTntToolBar.WMGetTextLength(var Message: TWMGetTextLength); -begin - if (not Win32PlatformIsUnicode) or (WindowHandle = 0) then - inherited - else - Message.Result := Length(FCaption); -end; - -procedure TTntToolBar.WMSetText(var Message: TWMSetText); -begin - if (not Win32PlatformIsUnicode) or (WindowHandle = 0) then - inherited - else - with Message do - SetString(FCaption, PWideChar(Text), WStrLen(PWideChar(Text))); -end; - -function TTntToolBar.GetCaption: WideString; -begin - Result := TntControl_GetText(Self); -end; - -procedure TTntToolBar.SetCaption(const Value: WideString); -begin - TntControl_SetText(Self, Value); -end; - -function TTntToolBar.IsCaptionStored: Boolean; -begin - Result := TntControl_IsCaptionStored(Self); -end; - -function TTntToolBar.GetHint: WideString; -begin - Result := TntControl_GetHint(Self); -end; - -procedure TTntToolBar.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -function TTntToolBar.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -procedure TTntToolBar.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntToolBar.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -function TTntToolBar.GetMenu: TMainMenu{TNT-ALLOW TMainMenu}; -begin - Result := inherited Menu; -end; - -procedure TTntToolBar.SetMenu(const Value: TMainMenu{TNT-ALLOW TMainMenu}); -var - I: Integer; -begin - if (Menu <> Value) then begin - inherited Menu := Value; - if Assigned(Menu) then begin - // get rid of TToolButton(s) - for I := ButtonCount - 1 downto 0 do - Buttons[I].Free; - // add TTntToolButton(s) - for I := Menu.Items.Count - 1 downto 0 do - begin - with TTntToolButton.Create(Self) do - try - AutoSize := True; - Grouped := True; - Parent := Self; - MenuItem := Menu.Items[I]; - except - Free; - raise; - end; - end; - end; - end; -end; - -{ TTntRichEditStrings } -type - TTntRichEditStrings = class(TTntMemoStrings) - private - RichEdit: TCustomRichEdit{TNT-ALLOW TCustomRichEdit}; - procedure EnableChange(const Value: Boolean); - protected - procedure SetTextStr(const Value: WideString); override; - public - constructor Create; - procedure AddStrings(Strings: TWideStrings); overload; override; - //-- - procedure LoadFromStream_BOM(Stream: TStream; WithBOM: Boolean); override; - procedure SaveToStream_BOM(Stream: TStream; WithBOM: Boolean); override; - procedure LoadFromFile(const FileName: WideString); override; - procedure SaveToFile(const FileName: WideString); override; - end; - -constructor TTntRichEditStrings.Create; -begin - inherited Create; - FRichEditMode := True; -end; - -procedure TTntRichEditStrings.AddStrings(Strings: TWideStrings); -var - SelChange: TNotifyEvent; -begin - SelChange := TTntCustomRichEdit(RichEdit).OnSelectionChange; - TTntCustomRichEdit(RichEdit).OnSelectionChange := nil; - try - inherited; - finally - TTntCustomRichEdit(RichEdit).OnSelectionChange := SelChange; - end; -end; - -procedure TTntRichEditStrings.EnableChange(const Value: Boolean); -var - EventMask: Longint; -begin - with RichEdit do - begin - if Value then - EventMask := SendMessage(Handle, EM_GETEVENTMASK, 0, 0) or ENM_CHANGE - else - EventMask := SendMessage(Handle, EM_GETEVENTMASK, 0, 0) and not ENM_CHANGE; - SendMessage(Handle, EM_SETEVENTMASK, 0, EventMask); - end; -end; - -procedure TTntRichEditStrings.SetTextStr(const Value: WideString); -begin - EnableChange(False); - try - inherited; - finally - EnableChange(True); - end; -end; - -type TAccessCustomRichEdit = class(TCustomRichEdit{TNT-ALLOW TCustomRichEdit}); - -procedure TTntRichEditStrings.LoadFromStream_BOM(Stream: TStream; WithBOM: Boolean); -begin - if TAccessCustomRichEdit(RichEdit).PlainText then - inherited LoadFromStream_BOM(Stream, WithBOM) - else - TAccessCustomRichEdit(RichEdit).Lines.LoadFromStream(Stream); -end; - -procedure TTntRichEditStrings.SaveToStream_BOM(Stream: TStream; WithBOM: Boolean); -begin - if TAccessCustomRichEdit(RichEdit).PlainText then - inherited SaveToStream_BOM(Stream, WithBOM) - else - TAccessCustomRichEdit(RichEdit).Lines.SaveToStream(Stream); -end; - -procedure TTntRichEditStrings.LoadFromFile(const FileName: WideString); -begin - if TAccessCustomRichEdit(RichEdit).PlainText then - inherited LoadFromFile(FileName) - else - TAccessCustomRichEdit(RichEdit).Lines.LoadFromFile(FileName); -end; - -procedure TTntRichEditStrings.SaveToFile(const FileName: WideString); -begin - if TAccessCustomRichEdit(RichEdit).PlainText then - inherited SaveToFile(FileName) - else - TAccessCustomRichEdit(RichEdit).Lines.SaveToFile(FileName); -end; - -{ TTntCustomRichEdit } - -constructor TTntCustomRichEdit.Create(AOwner: TComponent); -begin - inherited; - FRichEditStrings := TTntRichEditStrings.Create; - TTntRichEditStrings(FRichEditStrings).FMemo := Self; - TTntRichEditStrings(FRichEditStrings).FMemoLines := TAccessCustomRichEdit(Self).Lines; - TTntRichEditStrings(FRichEditStrings).FLineBreakStyle := Self.LineBreakStyle; - TTntRichEditStrings(FRichEditStrings).RichEdit := Self; -end; - -var - FRichEdit20Module: THandle = 0; - -function IsRichEdit20Available: Boolean; -const - RICHED20_DLL = 'RICHED20.DLL'; -begin - if FRichEdit20Module = 0 then - FRichEdit20Module := Tnt_LoadLibraryW(RICHED20_DLL); - Result := FRichEdit20Module <> 0; -end; - -{function IsRichEdit30Available: Boolean; -begin - Result := False; - exit; - Result := IsRichEdit20Available and (Win32MajorVersion >= 5); -end;} - -procedure TTntCustomRichEdit.CreateParams(var Params: TCreateParams); -begin - inherited CreateParams(Params); - if WordWrap then - Params.Style := Params.Style and not WS_HSCROLL; // more compatible with RichEdit 1.0 -end; - -procedure TTntCustomRichEdit.CreateWindowHandle(const Params: TCreateParams); -begin - if Win32PlatformIsUnicode and IsRichEdit20Available then - CreateUnicodeHandle(Self, Params, RICHEDIT_CLASSW) - else - inherited -end; - -var - AIMM: IActiveIMMApp = nil; - -function EnableActiveIMM: Boolean; -begin - if AIMM <> nil then - Result := True - else begin - Result := False; - try - if ClassIsRegistered(CLASS_CActiveIMM) then begin - AIMM := CoCActiveIMM.Create; - AIMM.Activate(1); - Result := True; - end; - except - AIMM := nil; - end; - end; -end; - -procedure TTntCustomRichEdit.CreateWnd; -const - EM_SETEDITSTYLE = WM_USER + 204; - SES_USEAIMM = 64; -begin - inherited; - // Only supported in RichEdit 3.0, but this flag is harmless to RichEdit1.0 or RichEdit 2.0 - if EnableActiveIMM then - SendMessage(Handle, EM_SETEDITSTYLE, SES_USEAIMM, SES_USEAIMM); -end; - -procedure TTntCustomRichEdit.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -destructor TTntCustomRichEdit.Destroy; -begin - FreeAndNil(FRichEditStrings); - inherited; -end; - -procedure TTntCustomRichEdit.KeyDown(var Key: Word; Shift: TShiftState); -begin - inherited; - if (not WantReturns) and (Key = VK_RETURN) and (Shift <> [ssCtrl]) then - Key := 0; -end; - -function TTntCustomRichEdit.LineBreakStyle: TTntTextLineBreakStyle; -begin - if Win32PlatformIsUnicode and IsRichEdit20Available then - Result := tlbsCR - else - Result := tlbsCRLF; -end; - -procedure TTntCustomRichEdit.SetRichEditStrings(const Value: TTntStrings); -begin - FRichEditStrings.Assign(Value); -end; - -function TTntCustomRichEdit.GetSelText: string{TNT-ALLOW string}; -begin - Result := GetWideSelText; -end; - -function TTntCustomRichEdit.GetWideSelText: WideString; -var - CharRange: TCharRange; - Length: Integer; -begin - if (not IsWindowUnicode(Handle)) then - Result := inherited GetSelText - else begin - SendMessageW(Handle, EM_EXGETSEL, 0, Longint(@CharRange)); - SetLength(Result, CharRange.cpMax - CharRange.cpMin + 1); - Length := SendMessageW(Handle, EM_GETSELTEXT, 0, Longint(PWideChar(Result))); - SetLength(Result, Length); - end; - if LineBreakStyle <> tlbsCRLF then - Result := TntAdjustLineBreaks(Result, tlbsCRLF) -end; - -type - TSetTextEx = record - flags:dword; - codepage:uint; - end; - -procedure TTntCustomRichEdit.SetRTFText(Flags: DWORD; const Value: AnsiString); -const - EM_SETTEXTEX = (WM_USER + 97); -var - Info: TSetTextEx; -begin - Info.flags := Flags; - Info.codepage := CP_ACP{TNT-ALLOW CP_ACP}; - SendMessage(Handle, EM_SETTEXTEX, Integer(@Info), Integer(PAnsiChar(Value))); -end; - -procedure TTntCustomRichEdit.SetWideSelText(const Value: WideString); -const - ST_SELECTION = 2; -begin - if Win32PlatformIsUnicode and IsRichEdit20Available and IsRTF(Value) then begin - // emulate RichEdit 1.0 so that RTF code is inserted as RTF (not plain text) - SetRTFText(ST_SELECTION, Value) - end else - TntCustomEdit_SetSelText(Self, TntAdjustLineBreaks(Value, LineBreakStyle)); -end; - -function TTntCustomRichEdit.GetText: WideString; -begin - Result := TntControl_GetText(Self); - if (LineBreakStyle <> tlbsCRLF) then - Result := TntAdjustLineBreaks(Result, tlbsCRLF); -end; - -procedure TTntCustomRichEdit.SetText(const Value: WideString); -const - ST_DEFAULT = 0; -begin - if Win32PlatformIsUnicode and IsRichEdit20Available and IsRTF(Value) then begin - // emulate RichEdit 1.0 so that RTF code is inserted as RTF (not plain text) - SetRTFText(ST_DEFAULT, Value) - end else if Value <> Text then - TntControl_SetText(Self, TntAdjustLineBreaks(Value, LineBreakStyle)); -end; - -function TTntCustomRichEdit.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntCustomRichEdit.GetHint: WideString; -begin - Result := TntControl_GetHint(Self); -end; - -procedure TTntCustomRichEdit.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntCustomRichEdit.WMGetTextLength(var Message: TWMGetTextLength); -begin - if FPrintingTextLength <> 0 then - Message.Result := FPrintingTextLength - else - inherited; -end; - -procedure TTntCustomRichEdit.Print(const Caption: string{TNT-ALLOW string}); -begin - if (LineBreakStyle <> tlbsCRLF) then - FPrintingTextLength := TntAdjustLineBreaksLength(Text, LineBreakStyle) - else - FPrintingTextLength := 0; - try - inherited - finally - FPrintingTextLength := 0; - end; -end; - -{$WARN SYMBOL_DEPRECATED OFF} - -function TTntCustomRichEdit.CharPosToGet(RawWin32CharPos: Integer): Integer; -begin - Result := EmulatedCharPos(RawWin32CharPos); -end; - -function TTntCustomRichEdit.CharPosToSet(EmulatedCharPos: Integer): Integer; -begin - Result := RawWin32CharPos(EmulatedCharPos); -end; -{$WARN SYMBOL_DEPRECATED ON} - -function TTntCustomRichEdit.EmulatedCharPos(RawWin32CharPos: Integer): Integer; -var - i: Integer; - ThisLine: Integer; - CharCount: Integer; - Line_Start: Integer; - NumLineBreaks: Integer; -begin - if (LineBreakStyle = tlbsCRLF) or (RawWin32CharPos <= 0) then - Result := RawWin32CharPos - else begin - Assert(Win32PlatformIsUnicode); - ThisLine := SendMessageW(Handle, EM_EXLINEFROMCHAR, 0, RawWin32CharPos); - if (not WordWrap) then - NumLineBreaks := ThisLine - else begin - CharCount := 0; - for i := 0 to ThisLine - 1 do - Inc(CharCount, TntMemo_LineLength(Handle, i)); - Line_Start := TntMemo_LineStart(Handle, ThisLine); - NumLineBreaks := Line_Start - CharCount; - end; - Result := RawWin32CharPos + NumLineBreaks; {inflate CR -> CR/LF} - end; -end; - -function TTntCustomRichEdit.RawWin32CharPos(EmulatedCharPos: Integer): Integer; -var - Line: Integer; - NumLineBreaks: Integer; - CharCount: Integer; - Line_Start: Integer; - LineLength: Integer; -begin - if (LineBreakStyle = tlbsCRLF) or (EmulatedCharPos <= 0) then - Result := EmulatedCharPos - else begin - Assert(Win32PlatformIsUnicode); - NumLineBreaks := 0; - CharCount := 0; - for Line := 0 to Lines.Count do begin - Line_Start := TntMemo_LineStart(Handle, Line); - if EmulatedCharPos < (Line_Start + NumLineBreaks) then - break; {found it (it must have been the line separator)} - if Line_Start > CharCount then begin - Inc(NumLineBreaks); - Inc(CharCount); - end; - LineLength := TntMemo_LineLength(Handle, Line, Line_Start); - Inc(CharCount, LineLength); - if (EmulatedCharPos >= (Line_Start + NumLineBreaks)) - and (EmulatedCharPos < (Line_Start + LineLength + NumLineBreaks)) then - break; {found it} - end; - Result := EmulatedCharPos - NumLineBreaks; {deflate CR/LF -> CR} - end; -end; - -function TTntCustomRichEdit.FindText(const SearchStr: WideString; - StartPos, Length: Integer; Options: TSearchTypes): Integer; -const - EM_FINDTEXTEXW = WM_USER + 124; -const - FR_DOWN = $00000001; - FR_WHOLEWORD = $00000002; - FR_MATCHCASE = $00000004; -var - Find: TFindTextW; - Flags: Integer; -begin - if (not Win32PlatformIsUnicode) then - Result := inherited FindText(SearchStr, StartPos, Length, Options) - else begin - with Find.chrg do - begin - cpMin := RawWin32CharPos(StartPos); - cpMax := RawWin32CharPos(StartPos + Length); - end; - Flags := FR_DOWN; { RichEdit 2.0 and later needs this } - if stWholeWord in Options then Flags := Flags or FR_WHOLEWORD; - if stMatchCase in Options then Flags := Flags or FR_MATCHCASE; - Find.lpstrText := PWideChar(SearchStr); - Result := SendMessageW(Handle, EM_FINDTEXT, Flags, LongInt(@Find)); - Result := EmulatedCharPos(Result); - end; -end; - -function TTntCustomRichEdit.GetSelStart: Integer; -begin - Result := TntCustomEdit_GetSelStart(Self); - Result := EmulatedCharPos(Result); -end; - -procedure TTntCustomRichEdit.SetSelStart(const Value: Integer); -begin - TntCustomEdit_SetSelStart(Self, RawWin32CharPos(Value)); -end; - -function TTntCustomRichEdit.GetSelLength: Integer; -var - CharRange: TCharRange; -begin - if (LineBreakStyle = tlbsCRLF) then - Result := TntCustomEdit_GetSelLength(Self) - else begin - Assert(Win32PlatformIsUnicode); - SendMessageW(Handle, EM_EXGETSEL, 0, Longint(@CharRange)); - Result := EmulatedCharPos(CharRange.cpMax) - EmulatedCharPos(CharRange.cpMin); - end; -end; - -procedure TTntCustomRichEdit.SetSelLength(const Value: Integer); -var - StartPos: Integer; - SelEnd: Integer; -begin - if (LineBreakStyle = tlbsCRLF) then - TntCustomEdit_SetSelLength(Self, Value) - else begin - StartPos := Self.SelStart; - SelEnd := StartPos + Value; - inherited SetSelLength(RawWin32CharPos(SelEnd) - RawWin32CharPos(StartPos)); - end; -end; - -procedure TTntCustomRichEdit.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomRichEdit.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntTabStrings } - -type TAccessCustomTabControl = class(TCustomTabControl{TNT-ALLOW TCustomTabControl}); - -type - TTntTabStrings = class(TTntStrings) - private - FTabControl: TCustomTabControl{TNT-ALLOW TCustomTabControl}; - FAnsiTabs: TStrings{TNT-ALLOW TStrings}; - protected - function Get(Index: Integer): WideString; override; - function GetCount: Integer; override; - function GetObject(Index: Integer): TObject; override; - procedure Put(Index: Integer; const S: WideString); override; - procedure PutObject(Index: Integer; AObject: TObject); override; - procedure SetUpdateState(Updating: Boolean); override; - public - procedure Clear; override; - procedure Delete(Index: Integer); override; - procedure Insert(Index: Integer; const S: WideString); override; - end; - -procedure TabControlError(const S: WideString); -begin - raise EListError.Create(S); -end; - -procedure TTntTabStrings.Clear; -begin - FAnsiTabs.Clear; -end; - -procedure TTntTabStrings.Delete(Index: Integer); -begin - FAnsiTabs.Delete(Index); -end; - -function TTntTabStrings.GetCount: Integer; -begin - Result := FAnsiTabs.Count; -end; - -function TTntTabStrings.GetObject(Index: Integer): TObject; -begin - Result := FAnsiTabs.Objects[Index]; -end; - -procedure TTntTabStrings.PutObject(Index: Integer; AObject: TObject); -begin - FAnsiTabs.Objects[Index] := AObject; -end; - -procedure TTntTabStrings.SetUpdateState(Updating: Boolean); -begin - inherited; - TAccessStrings(FAnsiTabs).SetUpdateState(Updating); -end; - -function TTntTabStrings.Get(Index: Integer): WideString; -const - RTL: array[Boolean] of LongInt = (0, TCIF_RTLREADING); -var - TCItem: TTCItemW; - Buffer: array[0..4095] of WideChar; -begin - if (not Win32PlatformIsUnicode) then - Result := FAnsiTabs[Index] - else begin - TCItem.mask := TCIF_TEXT or RTL[FTabControl.UseRightToLeftReading]; - TCItem.pszText := Buffer; - TCItem.cchTextMax := SizeOf(Buffer); - if SendMessageW(FTabControl.Handle, TCM_GETITEMW, Index, Longint(@TCItem)) = 0 then - TabControlError(WideFormat(sTabFailRetrieve, [Index])); - Result := Buffer; - end; -end; - -function GetTabControlImageIndex(Self: TCustomTabControl{TNT-ALLOW TCustomTabControl}; TabIndex: Integer): Integer; -begin - Result := TabIndex; - with TAccessCustomTabControl(Self) do - if Assigned(OnGetImageIndex) then OnGetImageIndex(Self, TabIndex, Result); -end; - -procedure TTntTabStrings.Put(Index: Integer; const S: WideString); -const - RTL: array[Boolean] of LongInt = (0, TCIF_RTLREADING); -var - TCItem: TTCItemW; -begin - if (not Win32PlatformIsUnicode) then - FAnsiTabs[Index] := S - else begin - TCItem.mask := TCIF_TEXT or RTL[FTabControl.UseRightToLeftReading] or TCIF_IMAGE; - TCItem.pszText := PWideChar(S); - TCItem.iImage := GetTabControlImageIndex(FTabControl, Index); - if SendMessageW(FTabControl.Handle, TCM_SETITEMW, Index, Longint(@TCItem)) = 0 then - TabControlError(WideFormat(sTabFailSet, [S, Index])); - TAccessCustomTabControl(FTabControl).UpdateTabImages; - end; -end; - -procedure TTntTabStrings.Insert(Index: Integer; const S: WideString); -const - RTL: array[Boolean] of LongInt = (0, TCIF_RTLREADING); -var - TCItem: TTCItemW; -begin - if (not Win32PlatformIsUnicode) then - FAnsiTabs.Insert(Index, S) - else begin - TCItem.mask := TCIF_TEXT or RTL[FTabControl.UseRightToLeftReading] or TCIF_IMAGE; - TCItem.pszText := PWideChar(S); - TCItem.iImage := GetTabControlImageIndex(FTabControl, Index); - if SendMessageW(FTabControl.Handle, TCM_INSERTITEMW, Index, Longint(@TCItem)) < 0 then - TabControlError(WideFormat(sTabFailSet, [S, Index])); - TAccessCustomTabControl(FTabControl).UpdateTabImages; - end; -end; - -{ TTntCustomTabControl } - -constructor TTntCustomTabControl.Create(AOwner: TComponent); -begin - inherited; - FTabs := TTntTabStrings.Create; - TTntTabStrings(FTabs).FTabControl := Self; - TTntTabStrings(FTabs).FAnsiTabs := inherited Tabs; -end; - -destructor TTntCustomTabControl.Destroy; -begin - TTntTabStrings(FTabs).FTabControl := nil; - TTntTabStrings(FTabs).FAnsiTabs := nil; - FreeAndNil(FTabs); - FreeAndNil(FSaveTabs); - inherited; -end; - -procedure TTntCustomTabControl.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle_ComCtl(Self, Params, WC_TABCONTROL); -end; - -procedure TTntCustomTabControl.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -procedure TTntCustomTabControl.CreateWnd; -begin - inherited; - if FSaveTabs <> nil then - begin - FTabs.Assign(FSaveTabs); - FreeAndNil(FSaveTabs); - TabIndex := FSaveTabIndex; - end; -end; - -procedure TTntCustomTabControl.DestroyWnd; -begin - if (FTabs <> nil) and (FTabs.Count > 0) then - begin - FSaveTabs := TTntStringList.Create; - FSaveTabs.Assign(FTabs); - FSaveTabIndex := TabIndex; - end; - inherited; -end; - -function TTntCustomTabControl.GetTabs: TTntStrings; -begin - if FSaveTabs <> nil then - Result := FSaveTabs // Use FSaveTabs while the window is deallocated - else - Result := FTabs; -end; - -procedure TTntCustomTabControl.SetTabs(const Value: TTntStrings); -begin - FTabs.Assign(Value); -end; - -function TTntCustomTabControl.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntCustomTabControl.GetHint: WideString; -begin - Result := TntControl_GetHint(Self); -end; - -procedure TTntCustomTabControl.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntCustomTabControl.CMDialogChar(var Message: TCMDialogChar); -var - I: Integer; -begin - for I := 0 to Tabs.Count - 1 do - if IsWideCharAccel(Message.CharCode, Tabs[I]) and CanShowTab(I) and CanFocus then - begin - Message.Result := 1; - if CanChange then - begin - TabIndex := I; - Change; - end; - Exit; - end; - Broadcast(Message); -end; - -procedure TTntCustomTabControl.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomTabControl.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntTabSheet } - -procedure TTntTabSheet.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, ''); -end; - -function TTntTabSheet.IsCaptionStored: Boolean; -begin - Result := TntControl_IsCaptionStored(Self); -end; - -function TTntTabSheet.GetCaption: TWideCaption; -begin - Result := TntControl_GetText(Self); -end; - -procedure TTntTabSheet.SetCaption(const Value: TWideCaption); -begin - TntControl_SetText(Self, Value); -end; - -procedure TTntTabSheet.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntTabSheet.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntTabSheet.GetHint: WideString; -begin - Result := TntControl_GetHint(Self); -end; - -procedure TTntTabSheet.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntTabSheet.WMSetText(var Message: TWMSetText); -begin - if (not Win32PlatformIsUnicode) - or (HandleAllocated) - or (Message.Text = AnsiString(TntControl_GetText(Self))) - or (Force_Inherited_WMSETTEXT) then - inherited - else begin - // NT, handle not allocated and text is different - Force_Inherited_WMSETTEXT := True; - try - TntControl_SetText(Self, Message.Text) { sync WideCaption with ANSI Caption } - finally - Force_Inherited_WMSETTEXT := FALSE; - end; - end; -end; - -procedure TTntTabSheet.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntTabSheet.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntPageControl } - -procedure TTntPageControl.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle_ComCtl(Self, Params, WC_TABCONTROL); -end; - -procedure TTntPageControl.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntPageControl.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntPageControl.GetHint: WideString; -begin - Result := TntControl_GetHint(Self); -end; - -procedure TTntPageControl.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntPageControl.WndProc(var Message: TMessage); -const - RTL: array[Boolean] of Cardinal = (0, TCIF_RTLREADING); -var - TCItemA: PTCItemA; - TabSheet: TTabSheet{TNT-ALLOW TTabSheet}; - Text: WideString; -begin - if (not Win32PlatformIsUnicode) then - inherited - else begin - case Message.Msg of - TCM_SETITEMA: - begin - TCItemA := PTCItemA(Message.lParam); - if ((TCItemA.mask and TCIF_PARAM) = TCIF_PARAM) then - TabSheet := TObject(TCItemA.lParam) as TTabSheet{TNT-ALLOW TTabSheet} - else if ((TCItemA.mask and TCIF_TEXT) = TCIF_TEXT) - and (Message.wParam >= 0) and (Message.wParam <= Tabs.Count - 1) then - TabSheet := Tabs.Objects[Message.wParam] as TTabSheet{TNT-ALLOW TTabSheet} - else - TabSheet := nil; - - if TabSheet = nil then begin - // will always be followed by TCM_SETITEMA(TCIF_PARAM) if TCIF_TEXT is present - TCItemA.mask := TCItemA.mask and (not TCIF_TEXT); - end else begin - // convert message to unicode, add text - Message.Msg := TCM_SETITEMW; - TCItemA.mask := TCItemA.mask or TCIF_TEXT or RTL[UseRightToLeftReading]; - if TabSheet is TTntTabSheet then - Text := TTntTabSheet(TabSheet).Caption - else - Text := TabSheet.Caption; - TCItemA.pszText := PAnsiChar(PWideChar(Text)); - end; - end; - TCM_INSERTITEMA: - begin - TCItemA := PTCItemA(Message.lParam); - // will always be followed by TCM_SETITEMA(TCIF_PARAM) if TCIF_TEXT is present - TCItemA.mask := TCItemA.mask and (not TCIF_TEXT); - end; - end; - inherited; - end; -end; - -procedure TTntPageControl.CMDialogChar(var Message: TCMDialogChar); -var - I: Integer; - TabText: WideString; -begin - for I := 0 to PageCount - 1 do begin - if Pages[i] is TTntTabSheet then - TabText := TTntTabSheet(Pages[i]).Caption - else - TabText := Pages[i].Caption; - if IsWideCharAccel(Message.CharCode, TabText) and CanShowTab(Pages[i].TabIndex) and CanFocus then - begin - Message.Result := 1; - if CanChange then - begin - TabIndex := Pages[i].TabIndex; - Change; - end; - Exit; - end; - end; - Broadcast(Message); -end; - -procedure TTntPageControl.CMDockClient(var Message: TCMDockClient); -var - IsVisible: Boolean; - DockCtl: TControl; -begin - Message.Result := 0; - FNewDockSheet := TTntTabSheet.Create(Self); - try - try - DockCtl := Message.DockSource.Control; - if DockCtl is TCustomForm then - FNewDockSheet.Caption := TntControl_GetText(DockCtl); - FNewDockSheet.PageControl := Self; - DockCtl.Dock(Self, Message.DockSource.DockRect); - except - FNewDockSheet.Free; - raise; - end; - IsVisible := DockCtl.Visible; - FNewDockSheet.TabVisible := IsVisible; - if IsVisible then ActivePage := FNewDockSheet; - DockCtl.Align := alClient; - finally - FNewDockSheet := nil; - end; -end; - -procedure TTntPageControl.DoAddDockClient(Client: TControl; const ARect: TRect); -begin - if FNewDockSheet <> nil then - Client.Parent := FNewDockSheet; -end; - -procedure TTntPageControl.CMDockNotification(var Message: TCMDockNotification); -var - I: Integer; - S: WideString; - Page: TTabSheet{TNT-ALLOW TTabSheet}; -begin - Page := GetPageFromDockClient(Message.Client); - if (Message.NotifyRec.ClientMsg <> WM_SETTEXT) - or (Page = nil) or (not (Page is TTntTabSheet)) then - inherited - else begin - if (Message.Client is TWinControl) - and (TWinControl(Message.Client).HandleAllocated) - and IsWindowUnicode(TWinControl(Message.Client).Handle) then - S := PWideChar(Message.NotifyRec.MsgLParam) - else - S := PAnsiChar(Message.NotifyRec.MsgLParam); - { Search for first CR/LF and end string there } - for I := 1 to Length(S) do - if S[I] in [CR, LF] then - begin - SetLength(S, I - 1); - Break; - end; - TTntTabSheet(Page).Caption := S; - end; -end; - -procedure TTntPageControl.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntPageControl.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntTrackBar } - -procedure TTntTrackBar.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle_ComCtl(Self, Params, TRACKBAR_CLASS); -end; - -procedure TTntTrackBar.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntTrackBar.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntTrackBar.GetHint: WideString; -begin - Result := TntControl_GetHint(Self); -end; - -procedure TTntTrackBar.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntTrackBar.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntTrackBar.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntProgressBar } - -procedure TTntProgressBar.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle_ComCtl(Self, Params, PROGRESS_CLASS); -end; - -procedure TTntProgressBar.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntProgressBar.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntProgressBar.GetHint: WideString; -begin - Result := TntControl_GetHint(Self); -end; - -procedure TTntProgressBar.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntProgressBar.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntProgressBar.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntCustomUpDown } - -procedure TTntCustomUpDown.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle_ComCtl(Self, Params, UPDOWN_CLASS); -end; - -procedure TTntCustomUpDown.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntCustomUpDown.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntCustomUpDown.GetHint: WideString; -begin - Result := TntControl_GetHint(Self); -end; - -procedure TTntCustomUpDown.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntCustomUpDown.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomUpDown.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntDateTimePicker } - -procedure TTntDateTimePicker.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle_ComCtl(Self, Params, DATETIMEPICK_CLASS); -end; - -procedure TTntDateTimePicker.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntDateTimePicker.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntDateTimePicker.GetHint: WideString; -begin - Result := TntControl_GetHint(Self); -end; - -procedure TTntDateTimePicker.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntDateTimePicker.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntDateTimePicker.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -procedure TTntDateTimePicker.CreateWnd; -var - SaveChecked: Boolean; -begin - FHadFirstMouseClick := False; - SaveChecked := Checked; - inherited; - // This fixes an issue where TDateTimePicker.CNNotify causes "FChecked := True" to occur - // during window creation. This issue results in .Checked to read True even though - // it is not visually checked. - Checked := SaveChecked; -end; - -procedure TTntDateTimePicker.WMLButtonDown(var Message: TWMLButtonDown); - - procedure UpdateValues; - var - Hdr: TNMDateTimeChange; - begin - Hdr.nmhdr.hwndFrom := Handle; - Hdr.nmhdr.idFrom := 0; - Hdr.nmhdr.code := DTN_DATETIMECHANGE; - Hdr.dwFlags := DateTime_GetSystemTime(Handle, Hdr.st); - if (Hdr.dwFlags <> Cardinal(GDT_ERROR)) then begin - if Hdr.dwFlags = GDT_NONE then - ZeroMemory(@Hdr.st, SizeOf(Hdr.st)); - Perform(CN_NOTIFY, Integer(Handle), Integer(@Hdr)); - end; - end; - -begin - inherited; - if ShowCheckBox and (not FHadFirstMouseClick) then begin - FHadFirstMouseClick := True; - UpdateValues; // Sometimes the first mouse click doesn't result in WM_NOTIFY. - end; -end; - -{ TTntMonthCalendar } - -procedure TTntMonthCalendar.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle_ComCtl(Self, Params, MONTHCAL_CLASS); - if Win32PlatformIsUnicode then begin - { For some reason WM_NOTIFY:MCN_GETDAYSTATE never gets called. } - ForceGetMonthInfo; - end; -end; - -procedure TTntMonthCalendar.ForceGetMonthInfo; -var - Hdr: TNMDayState; - Days: array of TMonthDayState; - Range: array[1..2] of TSystemTime; -begin - // populate Days array - Hdr.nmhdr.hwndFrom := Handle; - Hdr.nmhdr.idFrom := 0; - Hdr.nmhdr.code := MCN_GETDAYSTATE; - Hdr.cDayState := MonthCal_GetMonthRange(Handle, GMR_DAYSTATE, @Range[1]); - Hdr.stStart := Range[1]; - SetLength(Days, Hdr.cDayState); - Hdr.prgDayState := @Days[0]; - SendMessage(Handle, CN_NOTIFY, Integer(Handle), Integer(@Hdr)); - // update day state - SendMessage(Handle, MCM_SETDAYSTATE, Hdr.cDayState, Longint(Hdr.prgDayState)) -end; - -procedure TTntMonthCalendar.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntMonthCalendar.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntMonthCalendar.GetHint: WideString; -begin - Result := TntControl_GetHint(Self); -end; - -procedure TTntMonthCalendar.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -function TTntMonthCalendar.GetDate: TDate; -begin - Result := Trunc(inherited Date); { Fixes issue where Date always reflects time of saving dfm. } -end; - -procedure TTntMonthCalendar.SetDate(const Value: TDate); -begin - inherited Date := Trunc(Value); -end; - -procedure TTntMonthCalendar.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntMonthCalendar.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntPageScroller } - -procedure TTntPageScroller.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle_ComCtl(Self, Params, WC_PAGESCROLLER); -end; - -procedure TTntPageScroller.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntPageScroller.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntPageScroller.GetHint: WideString; -begin - Result := TntControl_GetHint(Self); -end; - -procedure TTntPageScroller.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntPageScroller.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntPageScroller.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntStatusPanel } - -procedure TTntStatusPanel.Assign(Source: TPersistent); -begin - inherited; - if Source is TTntStatusPanel then - Text := TTntStatusPanel(Source).Text; -end; - -procedure TTntStatusPanel.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntStatusPanel.GetText: Widestring; -begin - Result := GetSyncedWideString(FText, inherited Text); -end; - -procedure TTntStatusPanel.SetInheritedText(const Value: AnsiString); -begin - inherited Text := Value; -end; - -procedure TTntStatusPanel.SetText(const Value: Widestring); -begin - SetSyncedWideString(Value, FText, inherited Text, SetInheritedText); -end; - -{ TTntStatusPanels } - -function TTntStatusPanels.GetItem(Index: Integer): TTntStatusPanel; -begin - Result := (inherited GetItem(Index)) as TTntStatusPanel; -end; - -procedure TTntStatusPanels.SetItem(Index: Integer; Value: TTntStatusPanel); -begin - inherited SetItem(Index, Value); -end; - -function TTntStatusPanels.Add: TTntStatusPanel; -begin - Result := (inherited Add) as TTntStatusPanel; -end; - -function TTntStatusPanels.AddItem(Item: TTntStatusPanel; Index: Integer): TTntStatusPanel; -begin - Result := (inherited AddItem(Item, Index)) as TTntStatusPanel; -end; - -function TTntStatusPanels.Insert(Index: Integer): TTntStatusPanel; -begin - Result := (inherited Insert(Index)) as TTntStatusPanel; -end; - -{ TTntCustomStatusBar } - -function TTntCustomStatusBar.GetHint: WideString; -begin - Result := TntControl_GetHint(Self); -end; - -procedure TTntCustomStatusBar.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -function TTntCustomStatusBar.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntCustomStatusBar.CreatePanels: TStatusPanels{TNT-ALLOW TStatusPanels}; -begin - Result := TTntStatusPanels.Create(Self); -end; - -function TTntCustomStatusBar.GetPanelClass: TStatusPanelClass; -begin - Result := TTntStatusPanel; -end; - -function TTntCustomStatusBar.SyncLeadingTabs(const WideVal: WideString; const AnsiVal: AnsiString): WideString; - - function CountLeadingTabs(const Val: WideString): Integer; - var - i: integer; - begin - Result := 0; - for i := 1 to Length(Val) do begin - if Val[i] <> #9 then break; - Inc(Result); - end; - end; - -var - AnsiTabCount: Integer; - WideTabCount: Integer; -begin - AnsiTabCount := CountLeadingTabs(AnsiVal); - WideTabCount := CountLeadingTabs(WideVal); - Result := WideVal; - while WideTabCount < AnsiTabCount do begin - Insert(#9, Result, 1); - Inc(WideTabCount); - end; - while WideTabCount > AnsiTabCount do begin - Delete(Result, 1, 1); - Dec(WideTabCount); - end; -end; - -function TTntCustomStatusBar.GetSimpleText: WideString; -begin - FSimpleText := SyncLeadingTabs(FSimpleText, inherited SimpleText); - Result := GetSyncedWideString(FSimpleText, inherited SimpleText); -end; - -procedure TTntCustomStatusBar.SetInheritedSimpleText(const Value: AnsiString); -begin - inherited SimpleText := Value; -end; - -procedure TTntCustomStatusBar.SetSimpleText(const Value: WideString); -begin - SetSyncedWideString(Value, FSimpleText, inherited SimpleText, SetInheritedSimpleText); -end; - -procedure TTntCustomStatusBar.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -procedure TTntCustomStatusBar.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle_ComCtl(Self, Params, STATUSCLASSNAME); -end; - -procedure TTntCustomStatusBar.WndProc(var Msg: TMessage); -const - SB_SIMPLEID = Integer($FF); -var - iPart: Integer; - szText: PAnsiChar; - WideText: WideString; -begin - if Win32PlatformIsUnicode and (Msg.Msg = SB_SETTEXTA) and ((Msg.WParam and SBT_OWNERDRAW) = 0) - then begin - // convert SB_SETTEXTA message to Unicode - iPart := (Msg.WParam and SB_SIMPLEID); - szText := PAnsiChar(Msg.LParam); - if iPart = SB_SIMPLEID then - WideText := SimpleText - else if Panels.Count > 0 then - WideText := Panels[iPart].Text - else begin - WideText := szText; - end; - WideText := SyncLeadingTabs(WideText, szText); - Msg.Result := SendMessageW(Handle, SB_SETTEXTW, Msg.wParam, Integer(PWideChar(WideText))); - end else - inherited; -end; - -procedure TTntCustomStatusBar.WMGetTextLength(var Message: TWMGetTextLength); -begin - Message.Result := Length(SimpleText); -end; - -procedure TTntCustomStatusBar.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomStatusBar.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -function TTntCustomStatusBar.GetPanels: TTntStatusPanels; -begin - Result := inherited Panels as TTntStatusPanels; -end; - -procedure TTntCustomStatusBar.SetPanels(const Value: TTntStatusPanels); -begin - inherited Panels := Value; -end; - -function TTntCustomStatusBar.ExecuteAction(Action: TBasicAction): Boolean; -begin - if AutoHint and (Action is TTntHintAction) and not DoHint then - begin - if SimplePanel or (Panels.Count = 0) then - SimpleText := TTntHintAction(Action).Hint else - Panels[0].Text := TTntHintAction(Action).Hint; - Result := True; - end - else Result := inherited ExecuteAction(Action); -end; - -{ TTntStatusBar } - -function TTntStatusBar.GetOnDrawPanel: TDrawPanelEvent; -begin - Result := TDrawPanelEvent(inherited OnDrawPanel); -end; - -procedure TTntStatusBar.SetOnDrawPanel(const Value: TDrawPanelEvent); -begin - inherited OnDrawPanel := TCustomDrawPanelEvent(Value); -end; - -{ TTntTreeNode } - -function TTntTreeNode.IsEqual(Node: TTntTreeNode): Boolean; -begin - Result := (Text = Node.Text) and (Data = Node.Data); -end; - -procedure TTntTreeNode.ReadData(Stream: TStream; Info: PNodeInfo); -var - I, Size, ItemCount: Integer; - LNode: TTntTreeNode; - Utf8Text: AnsiString; -begin - Owner.ClearCache; - Stream.ReadBuffer(Size, SizeOf(Size)); - Stream.ReadBuffer(Info^, Size); - - if Pos(UTF8_BOM, Info^.Text) = 1 then begin - Utf8Text := Copy(Info^.Text, Length(UTF8_BOM) + 1, MaxInt); - try - Text := UTF8ToWideString(Utf8Text); - except - Text := Utf8Text; - end; - end else - Text := Info^.Text; - - ImageIndex := Info^.ImageIndex; - SelectedIndex := Info^.SelectedIndex; - StateIndex := Info^.StateIndex; - OverlayIndex := Info^.OverlayIndex; - Data := Info^.Data; - ItemCount := Info^.Count; - for I := 0 to ItemCount - 1 do - begin - LNode := Owner.AddChild(Self, ''); - LNode.ReadData(Stream, Info); - Owner.Owner.Added(LNode); - end; -end; - -procedure TTntTreeNode.WriteData(Stream: TStream; Info: PNodeInfo); -var - I, Size, L, ItemCount: Integer; - WideLen: Integer; Utf8Text: AnsiString; -begin - WideLen := 255; - repeat - Utf8Text := UTF8_BOM + WideStringToUTF8(Copy(Text, 1, WideLen)); - L := Length(Utf8Text); - Dec(WideLen); - until - L <= 255; - - Size := SizeOf(TNodeInfo) + L - 255; - Info^.Text := Utf8Text; - Info^.ImageIndex := ImageIndex; - Info^.SelectedIndex := SelectedIndex; - Info^.OverlayIndex := OverlayIndex; - Info^.StateIndex := StateIndex; - Info^.Data := Data; - ItemCount := Count; - Info^.Count := ItemCount; - Stream.WriteBuffer(Size, SizeOf(Size)); - Stream.WriteBuffer(Info^, Size); - for I := 0 to ItemCount - 1 do - Item[I].WriteData(Stream, Info); -end; - -procedure TTntTreeNode.Assign(Source: TPersistent); -var - Node: TTntTreeNode; -begin - inherited; - if (not Deleting) and (Source is TTntTreeNode) then - begin - Node := TTntTreeNode(Source); - Text := Node.Text; - end; -end; - -function TTntTreeNode.GetText: WideString; -begin - Result := GetSyncedWideString(FText, inherited Text); -end; - -procedure TTntTreeNode.SetInheritedText(const Value: AnsiString); -begin - inherited Text := Value; -end; - -procedure TTntTreeNode.SetText(const Value: WideString); -begin - SetSyncedWideString(Value, FText, inherited Text, SetInheritedText); -end; - -function TTntTreeNode.getFirstChild: TTntTreeNode; -begin - Result := inherited getFirstChild as TTntTreeNode; -end; - -function TTntTreeNode.GetItem(Index: Integer): TTntTreeNode; -begin - Result := inherited Item[Index] as TTntTreeNode; -end; - -procedure TTntTreeNode.SetItem(Index: Integer; const Value: TTntTreeNode); -begin - inherited Item[Index] := Value; -end; - -function TTntTreeNode.GetLastChild: TTntTreeNode; -begin - Result := inherited GetLastChild as TTntTreeNode; -end; - -function TTntTreeNode.GetNext: TTntTreeNode; -begin - Result := inherited GetNext as TTntTreeNode; -end; - -function TTntTreeNode.GetNextChild(Value: TTntTreeNode): TTntTreeNode; -begin - Result := inherited GetNextChild(Value) as TTntTreeNode; -end; - -function TTntTreeNode.getNextSibling: TTntTreeNode; -begin - Result := inherited getNextSibling as TTntTreeNode; -end; - -function TTntTreeNode.GetNextVisible: TTntTreeNode; -begin - Result := inherited GetNextVisible as TTntTreeNode; -end; - -function TTntTreeNode.GetNodeOwner: TTntTreeNodes; -begin - Result := inherited Owner as TTntTreeNodes; -end; - -function TTntTreeNode.GetParent: TTntTreeNode; -begin - Result := inherited Parent as TTntTreeNode; -end; - -function TTntTreeNode.GetPrev: TTntTreeNode; -begin - Result := inherited GetPrev as TTntTreeNode; -end; - -function TTntTreeNode.GetPrevChild(Value: TTntTreeNode): TTntTreeNode; -begin - Result := inherited GetPrevChild(Value) as TTntTreeNode; -end; - -function TTntTreeNode.getPrevSibling: TTntTreeNode; -begin - Result := inherited getPrevSibling as TTntTreeNode; -end; - -function TTntTreeNode.GetPrevVisible: TTntTreeNode; -begin - Result := inherited GetPrevVisible as TTntTreeNode; -end; - -function TTntTreeNode.GetTreeView: TTntCustomTreeView; -begin - Result := inherited TreeView as TTntCustomTreeView; -end; - -{ TTntTreeNodesEnumerator } - -constructor TTntTreeNodesEnumerator.Create(ATreeNodes: TTntTreeNodes); -begin - inherited Create; - FIndex := -1; - FTreeNodes := ATreeNodes; -end; - -function TTntTreeNodesEnumerator.GetCurrent: TTntTreeNode; -begin - Result := FTreeNodes[FIndex]; -end; - -function TTntTreeNodesEnumerator.MoveNext: Boolean; -begin - Result := FIndex < FTreeNodes.Count - 1; - if Result then - Inc(FIndex); -end; - -{ TTntTreeNodes } - -{$IFDEF COMPILER_6} // verified against VCL source in Delphi 6 and BCB 6 -type - THackTreeNodes = class(TPersistent) - protected - FxxxOwner: TCustomTreeView{TNT-ALLOW TCustomTreeView}; - FxxxUpdateCount: Integer; - FNodeCache: TNodeCache; - FReading: Boolean; - end; -{$ENDIF} -{$IFDEF DELPHI_7} // verified against VCL source in Delphi 7 -type - THackTreeNodes = class(TPersistent) - protected - FxxxOwner: TCustomTreeView{TNT-ALLOW TCustomTreeView}; - FxxxUpdateCount: Integer; - FNodeCache: TNodeCache; - FReading: Boolean; - end; -{$ENDIF} -{$IFDEF DELPHI_9} // verified against VCL source in Delphi 9 -type - THackTreeNodes = class(TPersistent) - protected - FxxxOwner: TCustomTreeView{TNT-ALLOW TCustomTreeView}; - FxxxUpdateCount: Integer; - FNodeCache: TNodeCache; - FReading: Boolean; - end; -{$ENDIF} -{$IFDEF DELPHI_10} // verified against VCL source in Delphi 10 -type - THackTreeNodes = class(TPersistent) - protected - FxxxOwner: TCustomTreeView{TNT-ALLOW TCustomTreeView}; - FxxxUpdateCount: Integer; - FNodeCache: TNodeCache; - FReading: Boolean; - end; -{$ENDIF} - -procedure SaveNodeTextToStrings(Nodes: TTntTreeNodes; sList: TTntStrings); -var - ANode: TTntTreeNode; -begin - sList.Clear; - if Nodes.Count > 0 then - begin - ANode := Nodes[0]; - while ANode <> nil do - begin - sList.Add(ANode.Text); - ANode := ANode.GetNext; - end; - end; -end; - -procedure TTntTreeNodes.Assign(Source: TPersistent); -var - TreeNodes: TTntTreeNodes; - MemStream: TTntMemoryStream; -begin - ClearCache; - if Source is TTntTreeNodes then - begin - TreeNodes := TTntTreeNodes(Source); - Clear; - MemStream := TTntMemoryStream.Create; - try - TreeNodes.WriteData(MemStream); - MemStream.Position := 0; - ReadData(MemStream); - finally - MemStream.Free; - end; - end else - inherited Assign(Source); -end; - -function TTntTreeNodes.GetNodeFromIndex(Index: Integer): TTntTreeNode; -begin - Result := inherited Item[Index] as TTntTreeNode; -end; - -function TTntTreeNodes.AddChildFirst(Parent: TTntTreeNode; const S: WideString): TTntTreeNode; -begin - Result := AddNode(nil, Parent, S, nil, naAddChildFirst); -end; - -function TTntTreeNodes.AddChildObjectFirst(Parent: TTntTreeNode; const S: WideString; - Ptr: Pointer): TTntTreeNode; -begin - Result := AddNode(nil, Parent, S, Ptr, naAddChildFirst); -end; - -function TTntTreeNodes.AddChild(Parent: TTntTreeNode; const S: WideString): TTntTreeNode; -begin - Result := AddNode(nil, Parent, S, nil, naAddChild); -end; - -function TTntTreeNodes.AddChildObject(Parent: TTntTreeNode; const S: WideString; - Ptr: Pointer): TTntTreeNode; -begin - Result := AddNode(nil, Parent, S, Ptr, naAddChild); -end; - -function TTntTreeNodes.AddFirst(Sibling: TTntTreeNode; const S: WideString): TTntTreeNode; -begin - Result := AddNode(nil, Sibling, S, nil, naAddFirst); -end; - -function TTntTreeNodes.AddObjectFirst(Sibling: TTntTreeNode; const S: WideString; - Ptr: Pointer): TTntTreeNode; -begin - Result := AddNode(nil, Sibling, S, Ptr, naAddFirst); -end; - -function TTntTreeNodes.Add(Sibling: TTntTreeNode; const S: WideString): TTntTreeNode; -begin - Result := AddNode(nil, Sibling, S, nil, naAdd); -end; - -function TTntTreeNodes.AddObject(Sibling: TTntTreeNode; const S: WideString; - Ptr: Pointer): TTntTreeNode; -begin - Result := AddNode(nil, Sibling, S, Ptr, naAdd); -end; - -function TTntTreeNodes.Insert(Sibling: TTntTreeNode; const S: WideString): TTntTreeNode; -begin - Result := AddNode(nil, Sibling, S, nil, naInsert); -end; - -function TTntTreeNodes.InsertObject(Sibling: TTntTreeNode; const S: WideString; - Ptr: Pointer): TTntTreeNode; -begin - Result := AddNode(nil, Sibling, S, Ptr, naInsert); -end; - -function TTntTreeNodes.InsertNode(Node, Sibling: TTntTreeNode; const S: WideString; - Ptr: Pointer): TTntTreeNode; -begin - Result := AddNode(Node, Sibling, S, Ptr, naInsert); -end; - -function TTntTreeNodes.AddNode(Node, Relative: TTntTreeNode; const S: WideString; - Ptr: Pointer; Method: TNodeAttachMode): TTntTreeNode; -begin - Result := inherited AddNode(Node, Relative, '', Ptr, Method) as TTntTreeNode; - Result.Text := S; -end; - -function TTntTreeNodes.GetNode(ItemId: HTreeItem): TTntTreeNode; -begin - Result := inherited GetNode(ItemID) as TTntTreeNode; -end; - -function TTntTreeNodes.GetFirstNode: TTntTreeNode; -begin - Result := inherited GetFirstNode as TTntTreeNode; -end; - -function TTntTreeNodes.GetEnumerator: TTntTreeNodesEnumerator; -begin - Result := TTntTreeNodesEnumerator.Create(Self); -end; - -function TTntTreeNodes.GetNodesOwner: TTntCustomTreeView; -begin - Result := inherited Owner as TTntCustomTreeView; -end; - -procedure TTntTreeNodes.ClearCache; -begin - THackTreeNodes(Self).FNodeCache.CacheNode := nil; -end; - -procedure TTntTreeNodes.DefineProperties(Filer: TFiler); - - function WriteNodes: Boolean; - var - I: Integer; - Nodes: TTntTreeNodes; - begin - Nodes := TTntTreeNodes(Filer.Ancestor); - if Nodes = nil then - Result := Count > 0 - else if Nodes.Count <> Count then - Result := True - else - begin - Result := False; - for I := 0 to Count - 1 do - begin - Result := not Item[I].IsEqual(Nodes[I]); - if Result then - Break; - end - end; - end; - -begin - inherited DefineProperties(Filer); - Filer.DefineBinaryProperty('Utf8Data', ReadData, WriteData, WriteNodes); -end; - -procedure TTntTreeNodes.ReadData(Stream: TStream); -var - I, Count: Integer; - NodeInfo: TNodeInfo; - LNode: TTntTreeNode; - LHandleAllocated: Boolean; -begin - LHandleAllocated := Owner.HandleAllocated; - if LHandleAllocated then - BeginUpdate; - THackTreeNodes(Self).FReading := True; - try - Clear; - Stream.ReadBuffer(Count, SizeOf(Count)); - for I := 0 to Count - 1 do - begin - LNode := Add(nil, ''); - LNode.ReadData(Stream, @NodeInfo); - Owner.Added(LNode); - end; - finally - THackTreeNodes(Self).FReading := False; - if LHandleAllocated then - EndUpdate; - end; -end; - -procedure TTntTreeNodes.WriteData(Stream: TStream); -var - I: Integer; - Node: TTntTreeNode; - NodeInfo: TNodeInfo; -begin - I := 0; - Node := GetFirstNode; - while Node <> nil do - begin - Inc(I); - Node := Node.GetNextSibling; - end; - Stream.WriteBuffer(I, SizeOf(I)); - Node := GetFirstNode; - while Node <> nil do - begin - Node.WriteData(Stream, @NodeInfo); - Node := Node.GetNextSibling; - end; -end; - -{ TTntTreeStrings } - -type - TTntTreeStrings = class(TTntStringList) - protected - function GetBufStart(Buffer: PWideChar; var Level: Integer): PWideChar; - public - procedure SaveToTree(Tree: TTntCustomTreeView); - procedure LoadFromTree(Tree: TTntCustomTreeView); - end; - -function TTntTreeStrings.GetBufStart(Buffer: PWideChar; var Level: Integer): PWideChar; -begin - Level := 0; - while Buffer^ in [WideChar(' '), WideChar(#9)] do - begin - Inc(Buffer); - Inc(Level); - end; - Result := Buffer; -end; - -procedure TTntTreeStrings.SaveToTree(Tree: TTntCustomTreeView); -var - ANode, NextNode: TTntTreeNode; - ALevel, i: Integer; - CurrStr: WideString; - Owner: TTntTreeNodes; -begin - Owner := Tree.Items; - Owner.BeginUpdate; - try - try - Owner.Clear; - ANode := nil; - for i := 0 to Count - 1 do - begin - CurrStr := GetBufStart(PWideChar(Strings[i]), ALevel); - if ANode = nil then - ANode := Owner.AddChild(nil, CurrStr) - else if ANode.Level = ALevel then - ANode := Owner.AddChild(ANode.Parent, CurrStr) - else if ANode.Level = (ALevel - 1) then - ANode := Owner.AddChild(ANode, CurrStr) - else if ANode.Level > ALevel then - begin - NextNode := ANode.Parent; - while NextNode.Level > ALevel do - NextNode := NextNode.Parent; - ANode := Owner.AddChild(NextNode.Parent, CurrStr); - end - else - raise ETreeViewError.CreateFmt(sInvalidLevelEx, [ALevel, CurrStr]); - end; - finally - Owner.EndUpdate; - end; - except - Owner.Owner.Invalidate; // force repaint on exception - raise; - end; -end; - -procedure TTntTreeStrings.LoadFromTree(Tree: TTntCustomTreeView); -const - TabChar = #9; -var - i: Integer; - ANode: TTntTreeNode; - NodeStr: WideString; - Owner: TTntTreeNodes; -begin - Clear; - Owner := Tree.Items; - if Owner.Count > 0 then - begin - ANode := Owner[0]; - while ANode <> nil do - begin - NodeStr := ''; - for i := 0 to ANode.Level - 1 do NodeStr := NodeStr + TabChar; - NodeStr := NodeStr + ANode.Text; - Add(NodeStr); - ANode := ANode.GetNext; - end; - end; -end; - -{ _TntInternalCustomTreeView } - -function _TntInternalCustomTreeView.FindNextToSelect: TTreeNode{TNT-ALLOW TTreeNode}; -begin - Result := Wide_FindNextToSelect; -end; - -function _TntInternalCustomTreeView.Inherited_FindNextToSelect: TTreeNode{TNT-ALLOW TTreeNode}; -begin - Result := inherited FindNextToSelect; -end; - -{ TTntCustomTreeView } - -function TntDefaultTreeViewSort(Node1, Node2: TTntTreeNode; lParam: Integer): Integer; stdcall; -begin - with Node1 do - if Assigned(TreeView.OnCompare) then - TreeView.OnCompare(TreeView, Node1, Node2, lParam, Result) - else Result := lstrcmpw(PWideChar(Node1.Text), PWideChar(Node2.Text)); -end; - -constructor TTntCustomTreeView.Create(AOwner: TComponent); -begin - inherited; - FEditInstance := Classes.MakeObjectInstance(EditWndProcW); -end; - -destructor TTntCustomTreeView.Destroy; -begin - Destroying; - Classes.FreeObjectInstance(FEditInstance); - FreeAndNil(FSavedNodeText); - inherited; -end; - -var - ComCtrls_DefaultTreeViewSort: TTVCompare = nil; - -procedure TTntCustomTreeView.CreateWindowHandle(const Params: TCreateParams); - - procedure Capture_ComCtrls_DefaultTreeViewSort; - begin - FTestingForSortProc := True; - try - AlphaSort; - finally - FTestingForSortProc := False; - end; - end; - -begin - CreateUnicodeHandle_ComCtl(Self, Params, WC_TREEVIEW); - if (Win32PlatformIsUnicode) then begin - if not Assigned(ComCtrls_DefaultTreeViewSort) then - Capture_ComCtrls_DefaultTreeViewSort; - end; -end; - -procedure TTntCustomTreeView.CreateWnd; -begin - inherited; - if FSavedNodeText <> nil then begin - FreeAndNil(FSavedNodeText); - SortType := FSavedSortType; - end; -end; - -procedure TTntCustomTreeView.DestroyWnd; -begin - if (not (csDestroying in ComponentState)) then begin - FSavedNodeText := TTntStringList.Create; - FSavedSortType := SortType; - SortType := stNone; // when recreating window, we are expecting items to come back in same order - SaveNodeTextToStrings(Items, FSavedNodeText); - end; - inherited; -end; - -procedure TTntCustomTreeView.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntCustomTreeView.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntCustomTreeView.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntCustomTreeView.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntCustomTreeView.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomTreeView.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -function TTntCustomTreeView.CreateNode: TTreeNode{TNT-ALLOW TTreeNode}; -var - LClass: TClass; - TntLClass: TTntTreeNodeClass; -begin - LClass := TTntTreeNode; - if Assigned(OnCreateNodeClass) then - OnCreateNodeClass(Self, TTreeNodeClass(LClass)); - if not LClass.InheritsFrom(TTntTreeNode) then - raise ETntInternalError.Create('Internal Error: OnCreateNodeClass.ItemClass must inherit from TTntTreeNode.'); - TntLClass := TTntTreeNodeClass(LClass); - Result := TntLClass.Create(inherited Items); -end; - -function TTntCustomTreeView.CreateNodes: TTreeNodes{TNT-ALLOW TTreeNodes}; -begin - Result := TTntTreeNodes.Create(Self); -end; - -function TTntCustomTreeView.GetTreeNodes: TTntTreeNodes; -begin - Result := inherited Items as TTntTreeNodes; -end; - -procedure TTntCustomTreeView.SetTreeNodes(const Value: TTntTreeNodes); -begin - Items.Assign(Value); -end; - -function TTntCustomTreeView.GetNodeFromItem(const Item: TTVItem): TTntTreeNode; -begin - Result := nil; - if Items <> nil then - with Item do - if (state and TVIF_PARAM) <> 0 then - Result := Pointer(lParam) - else - Result := Items.GetNode(hItem); -end; - -function TTntCustomTreeView.Wide_FindNextToSelect: TTntTreeNode; -begin - Result := FindNextToSelect; -end; - -function TTntCustomTreeView.FindNextToSelect: TTntTreeNode; -begin - Result := Inherited_FindNextToSelect as TTntTreeNode; -end; - -function TTntCustomTreeView.GetDropTarget: TTntTreeNode; -begin - Result := inherited DropTarget as TTntTreeNode; -end; - -function TTntCustomTreeView.GetNodeAt(X, Y: Integer): TTntTreeNode; -begin - Result := inherited GetNodeAt(X, Y) as TTntTreeNode; -end; - -function TTntCustomTreeView.GetSelected: TTntTreeNode; -begin - Result := inherited Selected as TTntTreeNode; -end; - -function TTntCustomTreeView.GetSelection(Index: Integer): TTntTreeNode; -begin - Result := inherited Selections[Index] as TTntTreeNode; -end; - -function TTntCustomTreeView.GetSelections(AList: TList): TTntTreeNode; -begin - Result := inherited GetSelections(AList) as TTntTreeNode; -end; - -function TTntCustomTreeView.GetTopItem: TTntTreeNode; -begin - Result := inherited TopItem as TTntTreeNode; -end; - -procedure TTntCustomTreeView.SetDropTarget(const Value: TTntTreeNode); -begin - inherited DropTarget := Value; -end; - -procedure TTntCustomTreeView.SetSelected(const Value: TTntTreeNode); -begin - inherited Selected := Value; -end; - -procedure TTntCustomTreeView.SetTopItem(const Value: TTntTreeNode); -begin - inherited TopItem := Value; -end; - -procedure TTntCustomTreeView.WndProc(var Message: TMessage); -type - PTVSortCB = ^TTVSortCB; -begin - with Message do begin - // capture ANSI version of DefaultTreeViewSort from ComCtrls - if (FTestingForSortProc) - and (Msg = TVM_SORTCHILDRENCB) then begin - ComCtrls_DefaultTreeViewSort := PTVSortCB(lParam).lpfnCompare; - exit; - end; - - if (Win32PlatformIsUnicode) - and (Msg = TVM_SORTCHILDRENCB) - and (@PTVSortCB(lParam).lpfnCompare = @ComCtrls_DefaultTreeViewSort) then - begin - // Unicode:: call wide version of sort proc instead - PTVSortCB(lParam)^.lpfnCompare := TTVCompare(@TntDefaultTreeViewSort); - Result := SendMessageW(Handle, TVM_SORTCHILDRENCB, wParam, lParam); - end else - inherited; - end; -end; - -procedure TTntCustomTreeView.CNNotify(var Message: TWMNotify); -var - Node: TTntTreeNode; -begin - if (not Win32PlatformIsUnicode) then - inherited - else begin - with Message do begin - case NMHdr^.code of - TVN_BEGINDRAGW: - begin - NMHdr^.code := TVN_BEGINDRAGA; - try - inherited; - finally - NMHdr^.code := TVN_BEGINDRAGW; - end; - end; - TVN_BEGINLABELEDITW: - begin - with PTVDispInfo(NMHdr)^ do - if Dragging or not CanEdit(GetNodeFromItem(item)) then - Result := 1; - if Result = 0 then - begin - FEditHandle := TreeView_GetEditControl(Handle); - FDefEditProc := Pointer(GetWindowLongW(FEditHandle, GWL_WNDPROC)); - SetWindowLongW(FEditHandle, GWL_WNDPROC, LongInt(FEditInstance)); - end; - end; - TVN_ENDLABELEDITW: - Edit(PTVDispInfo(NMHdr)^.item); - TVN_ITEMEXPANDINGW: - begin - NMHdr^.code := TVN_ITEMEXPANDINGA; - try - inherited; - finally - NMHdr^.code := TVN_ITEMEXPANDINGW; - end; - end; - TVN_ITEMEXPANDEDW: - begin - NMHdr^.code := TVN_ITEMEXPANDEDA; - try - inherited; - finally - NMHdr^.code := TVN_ITEMEXPANDEDW; - end; - end; - TVN_DELETEITEMW: - begin - NMHdr^.code := TVN_DELETEITEMA; - try - inherited; - finally - NMHdr^.code := TVN_DELETEITEMW; - end; - end; - TVN_SETDISPINFOW: - with PTVDispInfo(NMHdr)^ do - begin - Node := GetNodeFromItem(item); - if (Node <> nil) and ((item.mask and TVIF_TEXT) <> 0) then - Node.Text := TTVItemW(item).pszText; - end; - TVN_GETDISPINFOW: - with PTVDispInfo(NMHdr)^ do - begin - Node := GetNodeFromItem(item); - if Node <> nil then - begin - if (item.mask and TVIF_TEXT) <> 0 then begin - if (FSavedNodeText <> nil) - and (FSavedNodeText.Count > 0) - and (AnsiString(FSavedNodeText[0]) = AnsiString(Node.Text)) then - begin - Node.FText := FSavedNodeText[0]; // recover saved text - FSavedNodeText.Delete(0); - end; - WStrLCopy(TTVItemW(item).pszText, PWideChar(Node.Text), item.cchTextMax - 1); - end; - - if (item.mask and TVIF_IMAGE) <> 0 then - begin - GetImageIndex(Node); - item.iImage := Node.ImageIndex; - end; - if (item.mask and TVIF_SELECTEDIMAGE) <> 0 then - begin - GetSelectedIndex(Node); - item.iSelectedImage := Node.SelectedIndex; - end; - end; - end; - else - inherited; - end; - end; - end; -end; - -procedure TTntCustomTreeView.WMNotify(var Message: TWMNotify); -var - Node: TTntTreeNode; - FWideText: WideString; - MaxTextLen: Integer; - Pt: TPoint; -begin - with Message do - if NMHdr^.code = TTN_NEEDTEXTW then - begin - // Work around NT COMCTL32 problem with tool tips >= 80 characters - GetCursorPos(Pt); - Pt := ScreenToClient(Pt); - Node := GetNodeAt(Pt.X, Pt.Y); - if (Node = nil) or (Node.Text = '') or - (PToolTipTextW(NMHdr)^.uFlags and TTF_IDISHWND = 0) then Exit; - if (GetComCtlVersion >= ComCtlVersionIE4) - or {Borland's VCL wrongly uses "and"} (Length(Node.Text) < 80) then - begin - DefaultHandler(Message); - Exit; - end; - FWideText := Node.Text; - MaxTextLen := SizeOf(PToolTipTextW(NMHdr)^.szText) div SizeOf(WideChar); - if Length(FWideText) >= MaxTextLen then - SetLength(FWideText, MaxTextLen - 1); - PToolTipTextW(NMHdr)^.lpszText := PWideChar(FWideText); - FillChar(PToolTipTextW(NMHdr)^.szText, MaxTextLen, 0); - Move(Pointer(FWideText)^, PToolTipTextW(NMHdr)^.szText, Length(FWideText) * SizeOf(WideChar)); - PToolTipTextW(NMHdr)^.hInst := 0; - SetWindowPos(NMHdr^.hwndFrom, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE or - SWP_NOSIZE or SWP_NOMOVE or SWP_NOOWNERZORDER); - Result := 1; - end - else inherited; -end; - -procedure TTntCustomTreeView.Edit(const Item: TTVItem); -var - S: WideString; - AnsiS: AnsiString; - Node: TTntTreeNode; - AnsiEvent: TTVEditedEvent; -begin - with Item do - begin - Node := GetNodeFromItem(Item); - if pszText <> nil then - begin - if Win32PlatformIsUnicode then - S := TTVItemW(Item).pszText - else - S := pszText; - - if Assigned(FOnEdited) then - FOnEdited(Self, Node, S) - else if Assigned(inherited OnEdited) then - begin - AnsiEvent := inherited OnEdited; - AnsiS := S; - AnsiEvent(Self, Node, AnsiS); - S := AnsiS; - end; - - if Node <> nil then Node.Text := S; - end - else if Assigned(OnCancelEdit) then - OnCancelEdit(Self, Node); - end; -end; - -procedure TTntCustomTreeView.EditWndProcW(var Message: TMessage); -begin - Assert(Win32PlatformIsUnicode); - try - with Message do - begin - case Msg of - WM_KEYDOWN, - WM_SYSKEYDOWN: if DoKeyDown(TWMKey(Message)) then Exit; - WM_CHAR: - begin - MakeWMCharMsgSafeForAnsi(Message); - try - if DoKeyPress(TWMKey(Message)) then Exit; - finally - RestoreWMCharMsg(Message); - end; - end; - WM_KEYUP, - WM_SYSKEYUP: if DoKeyUp(TWMKey(Message)) then Exit; - CN_KEYDOWN, - CN_CHAR, CN_SYSKEYDOWN, - CN_SYSCHAR: - begin - WndProc(Message); - Exit; - end; - end; - Result := CallWindowProcW(FDefEditProc, FEditHandle, Msg, WParam, LParam); - end; - except - Application.HandleException(Self); - end; -end; - -procedure TTntCustomTreeView.LoadFromFile(const FileName: WideString); -var - TreeStrings: TTntTreeStrings; -begin - TreeStrings := TTntTreeStrings.Create; - try - TreeStrings.LoadFromFile(FileName); - TreeStrings.SaveToTree(Self); - finally - TreeStrings.Free; - end; -end; - -procedure TTntCustomTreeView.LoadFromStream(Stream: TStream); -var - TreeStrings: TTntTreeStrings; -begin - TreeStrings := TTntTreeStrings.Create; - try - TreeStrings.LoadFromStream(Stream); - TreeStrings.SaveToTree(Self); - finally - TreeStrings.Free; - end; -end; - -procedure TTntCustomTreeView.SaveToFile(const FileName: WideString); -var - TreeStrings: TTntTreeStrings; -begin - TreeStrings := TTntTreeStrings.Create; - try - TreeStrings.LoadFromTree(Self); - TreeStrings.SaveToFile(FileName); - finally - TreeStrings.Free; - end; -end; - -procedure TTntCustomTreeView.SaveToStream(Stream: TStream); -var - TreeStrings: TTntTreeStrings; -begin - TreeStrings := TTntTreeStrings.Create; - try - TreeStrings.LoadFromTree(Self); - TreeStrings.SaveToStream(Stream); - finally - TreeStrings.Free; - end; -end; - -initialization - -finalization - if Assigned(AIMM) then - AIMM.Deactivate; - if FRichEdit20Module <> 0 then - FreeLibrary(FRichEdit20Module); - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntCompilers.inc b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntCompilers.inc deleted file mode 100644 index 39eb95e91..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntCompilers.inc +++ /dev/null @@ -1,356 +0,0 @@ -//---------------------------------------------------------------------------------------------------------------------- -// Include file to determine which compiler is currently being used to build the project/component. -// This file uses ideas from Brad Stowers DFS.inc file (www.delphifreestuff.com). -// -// Portions created by Mike Lischke are Copyright -// (C) 1999-2002 Dipl. Ing. Mike Lischke. All Rights Reserved. -//---------------------------------------------------------------------------------------------------------------------- -// The following symbols are defined: -// -// COMPILER_1 : Kylix/Delphi/BCB 1.x is the compiler. -// COMPILER_1_UP : Kylix/Delphi/BCB 1.x or higher is the compiler. -// COMPILER_2 : Kylix/Delphi 2.x or BCB 1.x is the compiler. -// COMPILER_2_UP : Kylix/Delphi 2.x or higher, or BCB 1.x or higher is the compiler. -// COMPILER_3 : Kylix/Delphi/BCB 3.x is the compiler. -// COMPILER_3_UP : Kylix/Delphi/BCB 3.x or higher is the compiler. -// COMPILER_4 : Kylix/Delphi/BCB 4.x is the compiler. -// COMPILER_4_UP : Kylix/Delphi/BCB 4.x or higher is the compiler. -// COMPILER_5 : Kylix/Delphi/BCB 5.x is the compiler. -// COMPILER_5_UP : Kylix/Delphi/BCB 5.x or higher is the compiler. -// COMPILER_6 : Kylix/Delphi/BCB 6.x is the compiler. -// COMPILER_6_UP : Kylix/Delphi/BCB 6.x or higher is the compiler. -// COMPILER_7 : Kylix/Delphi/BCB 7.x is the compiler. -// COMPILER_7_UP : Kylix/Delphi/BCB 7.x or higher is the compiler. -// -// Only defined if Windows is the target: -// CPPB : Any version of BCB is being used. -// CPPB_1 : BCB v1.x is being used. -// CPPB_3 : BCB v3.x is being used. -// CPPB_3_UP : BCB v3.x or higher is being used. -// CPPB_4 : BCB v4.x is being used. -// CPPB_4_UP : BCB v4.x or higher is being used. -// CPPB_5 : BCB v5.x is being used. -// CPPB_5_UP : BCB v5.x or higher is being used. -// CPPB_6 : BCB v6.x is being used. -// CPPB_6_UP : BCB v6.x or higher is being used. -// -// Only defined if Windows is the target: -// DELPHI : Any version of Delphi is being used. -// DELPHI_1 : Delphi v1.x is being used. -// DELPHI_2 : Delphi v2.x is being used. -// DELPHI_2_UP : Delphi v2.x or higher is being used. -// DELPHI_3 : Delphi v3.x is being used. -// DELPHI_3_UP : Delphi v3.x or higher is being used. -// DELPHI_4 : Delphi v4.x is being used. -// DELPHI_4_UP : Delphi v4.x or higher is being used. -// DELPHI_5 : Delphi v5.x is being used. -// DELPHI_5_UP : Delphi v5.x or higher is being used. -// DELPHI_6 : Delphi v6.x is being used. -// DELPHI_6_UP : Delphi v6.x or higher is being used. -// DELPHI_7 : Delphi v7.x is being used. -// DELPHI_7_UP : Delphi v7.x or higher is being used. -// -// Only defined if Linux is the target: -// KYLIX : Any version of Kylix is being used. -// KYLIX_1 : Kylix 1.x is being used. -// KYLIX_1_UP : Kylix 1.x or higher is being used. -// KYLIX_2 : Kylix 2.x is being used. -// KYLIX_2_UP : Kylix 2.x or higher is being used. -// KYLIX_3 : Kylix 3.x is being used. -// KYLIX_3_UP : Kylix 3.x or higher is being used. -// -// Only defined if Linux is the target: -// QT_CLX : Trolltech's QT library is being used. -//---------------------------------------------------------------------------------------------------------------------- - -{$ifdef Win32} - - {$ifdef VER180} - {$define COMPILER_10} - {$define DELPHI} - {$define DELPHI_10} - {$endif} - - {$ifdef VER170} - {$define COMPILER_9} - {$define DELPHI} - {$define DELPHI_9} - {$endif} - - {$ifdef VER150} - {$define COMPILER_7} - {$define DELPHI} - {$define DELPHI_7} - {$endif} - - {$ifdef VER140} - {$define COMPILER_6} - {$ifdef BCB} - {$define CPPB} - {$define CPPB_6} - {$else} - {$define DELPHI} - {$define DELPHI_6} - {$endif} - {$endif} - - {$ifdef VER130} - {$define COMPILER_5} - {$ifdef BCB} - {$define CPPB} - {$define CPPB_5} - {$else} - {$define DELPHI} - {$define DELPHI_5} - {$endif} - {$endif} - - {$ifdef VER125} - {$define COMPILER_4} - {$define CPPB} - {$define CPPB_4} - {$endif} - - {$ifdef VER120} - {$define COMPILER_4} - {$define DELPHI} - {$define DELPHI_4} - {$endif} - - {$ifdef VER110} - {$define COMPILER_3} - {$define CPPB} - {$define CPPB_3} - {$endif} - - {$ifdef VER100} - {$define COMPILER_3} - {$define DELPHI} - {$define DELPHI_3} - {$endif} - - {$ifdef VER93} - {$define COMPILER_2} // C++ Builder v1 compiler is really v2 - {$define CPPB} - {$define CPPB_1} - {$endif} - - {$ifdef VER90} - {$define COMPILER_2} - {$define DELPHI} - {$define DELPHI_2} - {$endif} - - {$ifdef VER80} - {$define COMPILER_1} - {$define DELPHI} - {$define DELPHI_1} - {$endif} - - {$ifdef DELPHI_2} - {$define DELPHI_2_UP} - {$endif} - - {$ifdef DELPHI_3} - {$define DELPHI_2_UP} - {$define DELPHI_3_UP} - {$endif} - - {$ifdef DELPHI_4} - {$define DELPHI_2_UP} - {$define DELPHI_3_UP} - {$define DELPHI_4_UP} - {$endif} - - {$ifdef DELPHI_5} - {$define DELPHI_2_UP} - {$define DELPHI_3_UP} - {$define DELPHI_4_UP} - {$define DELPHI_5_UP} - {$endif} - - {$ifdef DELPHI_6} - {$define DELPHI_2_UP} - {$define DELPHI_3_UP} - {$define DELPHI_4_UP} - {$define DELPHI_5_UP} - {$define DELPHI_6_UP} - {$endif} - - {$ifdef DELPHI_7} - {$define DELPHI_2_UP} - {$define DELPHI_3_UP} - {$define DELPHI_4_UP} - {$define DELPHI_5_UP} - {$define DELPHI_6_UP} - {$define DELPHI_7_UP} - {$endif} - - {$ifdef DELPHI_9} - {$define DELPHI_2_UP} - {$define DELPHI_3_UP} - {$define DELPHI_4_UP} - {$define DELPHI_5_UP} - {$define DELPHI_6_UP} - {$define DELPHI_7_UP} - {$define DELPHI_9_UP} - {$endif} - - {$ifdef DELPHI_10} - {$define DELPHI_2_UP} - {$define DELPHI_3_UP} - {$define DELPHI_4_UP} - {$define DELPHI_5_UP} - {$define DELPHI_6_UP} - {$define DELPHI_7_UP} - {$define DELPHI_9_UP} - {$define DELPHI_10_UP} - {$endif} - - {$ifdef CPPB_3} - {$define CPPB_3_UP} - {$endif} - - {$ifdef CPPB_4} - {$define CPPB_3_UP} - {$define CPPB_4_UP} - {$endif} - - {$ifdef CPPB_5} - {$define CPPB_3_UP} - {$define CPPB_4_UP} - {$define CPPB_5_UP} - {$endif} - - {$ifdef CPPB_6} - {$define CPPB_3_UP} - {$define CPPB_4_UP} - {$define CPPB_5_UP} - {$define CPPB_6_UP} - {$endif} - - {$ifdef CPPB_3_UP} - // C++ Builder requires this if you use Delphi components in run-time packages. - {$ObjExportAll On} - {$endif} - -{$else (not Windows)} - // Linux is the target - {$define QT_CLX} - - {$define KYLIX} - {$define KYLIX_1} - {$define KYLIX_1_UP} - - {$ifdef VER150} - {$define COMPILER_7} - {$define KYLIX_3} - {$endif} - - {$ifdef VER140} - {$define COMPILER_6} - {$define KYLIX_2} - {$endif} - - {$ifdef KYLIX_2} - {$define KYLIX_2_UP} - {$endif} - - {$ifdef KYLIX_3} - {$define KYLIX_2_UP} - {$define KYLIX_3_UP} - {$endif} - -{$endif} - -// Compiler defines common to all platforms. -{$ifdef COMPILER_1} - {$define COMPILER_1_UP} -{$endif} - -{$ifdef COMPILER_2} - {$define COMPILER_1_UP} - {$define COMPILER_2_UP} -{$endif} - -{$ifdef COMPILER_3} - {$define COMPILER_1_UP} - {$define COMPILER_2_UP} - {$define COMPILER_3_UP} -{$endif} - -{$ifdef COMPILER_4} - {$define COMPILER_1_UP} - {$define COMPILER_2_UP} - {$define COMPILER_3_UP} - {$define COMPILER_4_UP} -{$endif} - -{$ifdef COMPILER_5} - {$define COMPILER_1_UP} - {$define COMPILER_2_UP} - {$define COMPILER_3_UP} - {$define COMPILER_4_UP} - {$define COMPILER_5_UP} -{$endif} - -{$ifdef COMPILER_6} - {$define COMPILER_1_UP} - {$define COMPILER_2_UP} - {$define COMPILER_3_UP} - {$define COMPILER_4_UP} - {$define COMPILER_5_UP} - {$define COMPILER_6_UP} -{$endif} - -{$ifdef COMPILER_7} - {$define COMPILER_1_UP} - {$define COMPILER_2_UP} - {$define COMPILER_3_UP} - {$define COMPILER_4_UP} - {$define COMPILER_5_UP} - {$define COMPILER_6_UP} - {$define COMPILER_7_UP} -{$endif} - -{$ifdef COMPILER_9} - {$define COMPILER_1_UP} - {$define COMPILER_2_UP} - {$define COMPILER_3_UP} - {$define COMPILER_4_UP} - {$define COMPILER_5_UP} - {$define COMPILER_6_UP} - {$define COMPILER_7_UP} - {$define COMPILER_9_UP} -{$endif} - -{$ifdef COMPILER_10} - {$define COMPILER_1_UP} - {$define COMPILER_2_UP} - {$define COMPILER_3_UP} - {$define COMPILER_4_UP} - {$define COMPILER_5_UP} - {$define COMPILER_6_UP} - {$define COMPILER_7_UP} - {$define COMPILER_9_UP} - {$define COMPILER_10_UP} -{$endif} - -//---------------------------------------------------------------------------------------------------------------------- - -{$ALIGN ON} -{$BOOLEVAL OFF} - -{$ifdef COMPILER_7_UP} - {$define THEME_7_UP} { Allows experimental theme support on pre-Delphi 7. } -{$endif} - -{$IFDEF COMPILER_6_UP} -{$WARN SYMBOL_PLATFORM OFF} { We are going to use Win32 specific symbols! } -{$ENDIF} - -{$IFDEF COMPILER_7_UP} -{$WARN UNSAFE_CODE OFF} { We are not going to be "safe"! } -{$WARN UNSAFE_TYPE OFF} -{$WARN UNSAFE_CAST OFF} -{$ENDIF} \ No newline at end of file diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntControls.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntControls.pas deleted file mode 100644 index 3b48d1eb1..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntControls.pas +++ /dev/null @@ -1,1099 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntControls; - -{$INCLUDE TntCompilers.inc} - -{ - Windows NT provides support for native Unicode windows. To add Unicode support to a - TWinControl descendant, override CreateWindowHandle() and call CreateUnicodeHandle(). - - One major reason this works is because the VCL only uses the ANSI version of - SendMessage() -- SendMessageA(). If you call SendMessageA() on a UNICODE - window, Windows deals with the ANSI/UNICODE conversion automatically. So - for example, if the VCL sends WM_SETTEXT to a window using SendMessageA, - Windows actually *expects* a PAnsiChar even if the target window is a UNICODE - window. So caling SendMessageA with PChars causes no problems. - - A problem in the VCL has to do with the TControl.Perform() method. Perform() - calls the window procedure directly and assumes an ANSI window. This is a - problem if, for example, the VCL calls Perform(WM_SETTEXT, ...) passing in a - PAnsiChar which eventually gets passed downto DefWindowProcW() which expects a PWideChar. - - This is the reason for SubClassUnicodeControl(). This procedure will subclass the - Windows WndProc, and the TWinControl.WindowProc pointer. It will determine if the - message came from Windows or if the WindowProc was called directly. It will then - call SendMessageA() for Windows to perform proper conversion on certain text messages. - - Another problem has to do with TWinControl.DoKeyPress(). It is called from the WM_CHAR - message. It casts the WideChar to an AnsiChar, and sends the resulting character to - DefWindowProc. In order to avoid this, the DefWindowProc is subclassed as well. WindowProc - will make a WM_CHAR message safe for ANSI handling code by converting the char code to - #FF before passing it on. It stores the original WideChar in the .Unused field of TWMChar. - The code #FF is converted back to the WideChar before passing onto DefWindowProc. -} - -{ - Things to consider when designing new controls: - 1) Check that a WideString Hint property is published. - 2) If descending from TWinControl, override CreateWindowHandle(). - 3) If not descending from TWinControl, handle CM_HINTSHOW message. - 4) Check to make sure that CN_CHAR, CN_SYSCHAR and CM_DIALOGCHAR are handled properly. - 5) If descending from TWinControl, verify Unicode chars are preserved after RecreateWnd. - 6) Consider using storage specifiers for Hint and Caption properties. - 7) If any class could possibly have published WideString properties, - override DefineProperties and call TntPersistent_AfterInherited_DefineProperties. - 8) Check if TTntThemeManager needs to be updated. - 9) Override GetActionLinkClass() and ActionChange(). - 10) If class updates Application.Hint then update TntApplication.Hint instead. -} - -interface - -{ TODO: Unicode enable .OnKeyPress event } - -uses - Classes, Windows, Messages, Controls, Menus; - - -{TNT-WARN TCaption} -type TWideCaption = type WideString; - -// caption/text management -function TntControl_IsCaptionStored(Control: TControl): Boolean; -function TntControl_GetStoredText(Control: TControl; const Default: WideString): WideString; -procedure TntControl_SetStoredText(Control: TControl; const Value: WideString); -function TntControl_GetText(Control: TControl): WideString; -procedure TntControl_SetText(Control: TControl; const Text: WideString); - -// hint management -function TntControl_IsHintStored(Control: TControl): Boolean; -function TntControl_GetHint(Control: TControl): WideString; -procedure TntControl_SetHint(Control: TControl; const Value: WideString); - -function WideGetHint(Control: TControl): WideString; -function WideGetShortHint(const Hint: WideString): WideString; -function WideGetLongHint(const Hint: WideString): WideString; -procedure ProcessCMHintShowMsg(var Message: TMessage); - -type - TTntCustomHintWindow = class(THintWindow) - private - FActivating: Boolean; - FBlockPaint: Boolean; - function GetCaption: TWideCaption; - procedure SetCaption(const Value: TWideCaption); - procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED; - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; -{$IFNDEF COMPILER_7_UP} - procedure CreateParams(var Params: TCreateParams); override; -{$ENDIF} - procedure Paint; override; - public - procedure ActivateHint(Rect: TRect; const AHint: AnsiString); override; - procedure ActivateHintData(Rect: TRect; const AHint: AnsiString; AData: Pointer); override; - function CalcHintRect(MaxWidth: Integer; const AHint: AnsiString; AData: Pointer): TRect; override; - property Caption: TWideCaption read GetCaption write SetCaption; - end; - - TTntHintWindow = class(TTntCustomHintWindow) - public - procedure ActivateHint(Rect: TRect; const AHint: WideString); reintroduce; - procedure ActivateHintData(Rect: TRect; const AHint: WideString; AData: Pointer); reintroduce; - function CalcHintRect(MaxWidth: Integer; const AHint: WideString; AData: Pointer): TRect; reintroduce; - end; - -// text/char message -function IsTextMessage(Msg: UINT): Boolean; -procedure MakeWMCharMsgSafeForAnsi(var Message: TMessage); -procedure RestoreWMCharMsg(var Message: TMessage); -function GetWideCharFromWMCharMsg(Message: TWMChar): WideChar; -procedure SetWideCharForWMCharMsg(var Message: TWMChar; Ch: WideChar); - -// register/create window -procedure SubClassUnicodeControl(Control: TWinControl; Params_Caption: PAnsiChar; IDEWindow: Boolean = False); -procedure RegisterUnicodeClass(Params: TCreateParams; out WideWinClassName: WideString; IDEWindow: Boolean = False); -procedure CreateUnicodeHandle(Control: TWinControl; const Params: TCreateParams; - const SubClass: WideString; IDEWindow: Boolean = False); -procedure ReCreateUnicodeWnd(Control: TWinControl; Subclass: WideString; IDEWindow: Boolean = False); - -type - IWideCustomListControl = interface - ['{C1801F41-51E9-4DB5-8DB8-58AC86698C2E}'] - procedure AddItem(const Item: WideString; AObject: TObject); - end; - -procedure WideListControl_AddItem(Control: TCustomListControl; const Item: WideString; AObject: TObject); - -var - _IsShellProgramming: Boolean = False; - -var - TNT_WM_DESTROY: Cardinal; - -implementation - -uses - ActnList, Forms, SysUtils, Contnrs, - TntGraphics, TntWindows, TntClasses, TntMenus, TntSysUtils; - -type - TAccessControl = class(TControl); - TAccessWinControl = class(TWinControl); - TAccessControlActionLink = class(TControlActionLink{TNT-ALLOW TControlActionLink}); - -//----------------------------------------------- WIDE CAPTION HOLDERS -------- - -{ TWideControlHelper } - -var - WideControlHelpers: TComponentList = nil; - -type - TWideControlHelper = class(TWideComponentHelper) - private - FControl: TControl; - FWideCaption: WideString; - FWideHint: WideString; - procedure SetAnsiText(const Value: AnsiString); - procedure SetAnsiHint(const Value: AnsiString); - public - constructor Create(AOwner: TControl); reintroduce; - property WideCaption: WideString read FWideCaption; - property WideHint: WideString read FWideHint; - end; - -constructor TWideControlHelper.Create(AOwner: TControl); -begin - inherited CreateHelper(AOwner, WideControlHelpers); - FControl := AOwner; -end; - -procedure TWideControlHelper.SetAnsiText(const Value: AnsiString); -begin - TAccessControl(FControl).Text := Value; -end; - -procedure TWideControlHelper.SetAnsiHint(const Value: AnsiString); -begin - FControl.Hint := Value; -end; - -function FindWideControlHelper(Control: TControl; CreateIfNotFound: Boolean = True): TWideControlHelper; -begin - Result := TWideControlHelper(FindWideComponentHelper(WideControlHelpers, Control)); - if (Result = nil) and CreateIfNotFound then - Result := TWideControlHelper.Create(Control); -end; - -//----------------------------------------------- GET/SET WINDOW CAPTION/HINT ------------- - -function TntControl_IsCaptionStored(Control: TControl): Boolean; -begin - with TAccessControl(Control) do - Result := (ActionLink = nil) or not TAccessControlActionLink(ActionLink).IsCaptionLinked; -end; - -function TntControl_GetStoredText(Control: TControl; const Default: WideString): WideString; -var - WideControlHelper: TWideControlHelper; -begin - WideControlHelper := FindWideControlHelper(Control, False); - if WideControlHelper <> nil then - Result := WideControlHelper.WideCaption - else - Result := Default; -end; - -procedure TntControl_SetStoredText(Control: TControl; const Value: WideString); -begin - FindWideControlHelper(Control).FWideCaption := Value; - TAccessControl(Control).Text := Value; -end; - -function TntControl_GetText(Control: TControl): WideString; -var - WideControlHelper: TWideControlHelper; -begin - if (not Win32PlatformIsUnicode) - or ((Control is TWinControl) and TWinControl(Control).HandleAllocated and (not IsWindowUnicode(TWinControl(Control).Handle))) then - // Win9x / non-unicode handle - Result := TAccessControl(Control).Text - else if (not (Control is TWinControl)) then begin - // non-windowed TControl - WideControlHelper := FindWideControlHelper(Control, False); - if WideControlHelper = nil then - Result := TAccessControl(Control).Text - else - Result := GetSyncedWideString(WideControlHelper.FWideCaption, TAccessControl(Control).Text); - end else if (not TWinControl(Control).HandleAllocated) then begin - // NO HANDLE - Result := TntControl_GetStoredText(Control, TAccessControl(Control).Text) - end else begin - // UNICODE & HANDLE - SetLength(Result, GetWindowTextLengthW(TWinControl(Control).Handle) + 1); - GetWindowTextW(TWinControl(Control).Handle, PWideChar(Result), Length(Result)); - SetLength(Result, Length(Result) - 1); - end; -end; - -procedure TntControl_SetText(Control: TControl; const Text: WideString); -begin - if (not Win32PlatformIsUnicode) - or ((Control is TWinControl) and TWinControl(Control).HandleAllocated and (not IsWindowUnicode(TWinControl(Control).Handle))) then - // Win9x / non-unicode handle - TAccessControl(Control).Text := Text - else if (not (Control is TWinControl)) then begin - // non-windowed TControl - with FindWideControlHelper(Control) do - SetSyncedWideString(Text, FWideCaption, TAccessControl(Control).Text, SetAnsiText) - end else if (not TWinControl(Control).HandleAllocated) then begin - // NO HANDLE - TntControl_SetStoredText(Control, Text); - end else if TntControl_GetText(Control) <> Text then begin - // UNICODE & HANDLE - Tnt_SetWindowTextW(TWinControl(Control).Handle, PWideChar(Text)); - Control.Perform(CM_TEXTCHANGED, 0, 0); - end; -end; - -// hint management ----------------------------------------------------------------------- - -function TntControl_IsHintStored(Control: TControl): Boolean; -begin - with TAccessControl(Control) do - Result := (ActionLink = nil) or not TAccessControlActionLink(ActionLink).IsHintLinked; -end; - -function TntControl_GetHint(Control: TControl): WideString; -var - WideControlHelper: TWideControlHelper; -begin - if (not Win32PlatformIsUnicode) then - Result := Control.Hint - else begin - WideControlHelper := FindWideControlHelper(Control, False); - if WideControlHelper <> nil then - Result := GetSyncedWideString(WideControlHelper.FWideHint, Control.Hint) - else - Result := Control.Hint; - end; -end; - -procedure TntControl_SetHint(Control: TControl; const Value: WideString); -begin - if (not Win32PlatformIsUnicode) then - Control.Hint := Value - else - with FindWideControlHelper(Control) do - SetSyncedWideString(Value, FWideHint, Control.Hint, SetAnsiHint); -end; - -function WideGetHint(Control: TControl): WideString; -begin - while Control <> nil do - if TntControl_GetHint(Control) = '' then - Control := Control.Parent - else - begin - Result := TntControl_GetHint(Control); - Exit; - end; - Result := ''; -end; - -function WideGetShortHint(const Hint: WideString): WideString; -var - I: Integer; -begin - I := Pos('|', Hint); - if I = 0 then - Result := Hint else - Result := Copy(Hint, 1, I - 1); -end; - -function WideGetLongHint(const Hint: WideString): WideString; -var - I: Integer; -begin - I := Pos('|', Hint); - if I = 0 then - Result := Hint else - Result := Copy(Hint, I + 1, Maxint); -end; - -//---------------------------------------------------------------------------------------- - -var UnicodeCreationControl: TWinControl = nil; - -function IsUnicodeCreationControl(Handle: HWND): Boolean; -begin - Result := (UnicodeCreationControl <> nil) - and (UnicodeCreationControl.HandleAllocated) - and (UnicodeCreationControl.Handle = Handle); -end; - -function WMNotifyFormatResult(FromHandle: HWND): Integer; -begin - if Win32PlatformIsUnicode - and (IsWindowUnicode(FromHandle) or IsUnicodeCreationControl(FromHandle)) then - Result := NFR_UNICODE - else - Result := NFR_ANSI; -end; - -function IsTextMessage(Msg: UINT): Boolean; -begin - // WM_CHAR is omitted because of the special handling it receives - Result := (Msg = WM_SETTEXT) - or (Msg = WM_GETTEXT) - or (Msg = WM_GETTEXTLENGTH); -end; - -const - ANSI_UNICODE_HOLDER = $FF; - -procedure MakeWMCharMsgSafeForAnsi(var Message: TMessage); -begin - with TWMChar(Message) do begin - Assert(Msg = WM_CHAR); - if not _IsShellProgramming then - Assert(Unused = 0) - else begin - Assert((Unused = 0) or (CharCode <= Word(High(AnsiChar)))); - // When a Unicode control is embedded under non-Delphi Unicode - // window something strange happens - if (Unused <> 0) then begin - CharCode := (Unused shl 8) or CharCode; - end; - end; - if (CharCode > Word(High(AnsiChar))) then begin - Unused := CharCode; - CharCode := ANSI_UNICODE_HOLDER; - end; - end; -end; - -procedure RestoreWMCharMsg(var Message: TMessage); -begin - with TWMChar(Message) do begin - Assert(Message.Msg = WM_CHAR); - if (Unused > 0) - and (CharCode = ANSI_UNICODE_HOLDER) then - CharCode := Unused; - Unused := 0; - end; -end; - -function GetWideCharFromWMCharMsg(Message: TWMChar): WideChar; -begin - if (Message.CharCode = ANSI_UNICODE_HOLDER) - and (Message.Unused <> 0) then - Result := WideChar(Message.Unused) - else - Result := WideChar(Message.CharCode); -end; - -procedure SetWideCharForWMCharMsg(var Message: TWMChar; Ch: WideChar); -begin - Message.CharCode := Word(Ch); - Message.Unused := 0; - MakeWMCharMsgSafeForAnsi(TMessage(Message)); -end; - -//----------------------------------------------------------------------------------- -type - TWinControlTrap = class(TComponent) - private - WinControl_ObjectInstance: Pointer; - ObjectInstance: Pointer; - DefObjectInstance: Pointer; - function IsInSubclassChain(Control: TWinControl): Boolean; - procedure SubClassWindowProc; - private - FControl: TAccessWinControl; - Handle: THandle; - PrevWin32Proc: Pointer; - PrevDefWin32Proc: Pointer; - PrevWindowProc: TWndMethod; - private - LastWin32Msg: UINT; - Win32ProcLevel: Integer; - IDEWindow: Boolean; - DestroyTrap: Boolean; - TestForNull: Boolean; - FoundNull: Boolean; - {$IFDEF TNT_VERIFY_WINDOWPROC} - LastVerifiedWindowProc: TWndMethod; - {$ENDIF} - procedure Win32Proc(var Message: TMessage); - procedure DefWin32Proc(var Message: TMessage); - procedure WindowProc(var Message: TMessage); - private - procedure SubClassControl(Params_Caption: PAnsiChar); - procedure UnSubClassUnicodeControl; - protected - procedure Notification(AComponent: TComponent; Operation: TOperation); override; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - end; - -constructor TWinControlTrap.Create(AOwner: TComponent); -begin - FControl := TAccessWinControl(AOwner as TWinControl); - inherited Create(nil); - FControl.FreeNotification(Self); - - WinControl_ObjectInstance := Classes.MakeObjectInstance(FControl.MainWndProc); - ObjectInstance := Classes.MakeObjectInstance(Win32Proc); - DefObjectInstance := Classes.MakeObjectInstance(DefWin32Proc); -end; - -destructor TWinControlTrap.Destroy; -begin - Classes.FreeObjectInstance(ObjectInstance); - Classes.FreeObjectInstance(DefObjectInstance); - Classes.FreeObjectInstance(WinControl_ObjectInstance); - inherited; -end; - -procedure TWinControlTrap.Notification(AComponent: TComponent; Operation: TOperation); -begin - inherited; - if (AComponent = FControl) and (Operation = opRemove) then begin - FControl := nil; - if Win32ProcLevel = 0 then - Free - else - DestroyTrap := True; - end; -end; - -procedure TWinControlTrap.SubClassWindowProc; -begin - if not IsInSubclassChain(FControl) then begin - PrevWindowProc := FControl.WindowProc; - FControl.WindowProc := Self.WindowProc; - end; - {$IFDEF TNT_VERIFY_WINDOWPROC} - LastVerifiedWindowProc := FControl.WindowProc; - {$ENDIF} -end; - -procedure TWinControlTrap.SubClassControl(Params_Caption: PAnsiChar); -begin - // initialize trap object - Handle := FControl.Handle; - PrevWin32Proc := Pointer(GetWindowLongW(FControl.Handle, GWL_WNDPROC)); - PrevDefWin32Proc := FControl.DefWndProc; - - // subclass Window Procedures - SetWindowLongW(FControl.Handle, GWL_WNDPROC, Integer(ObjectInstance)); - FControl.DefWndProc := DefObjectInstance; - SubClassWindowProc; - - // For some reason, caption gets garbled after calling SetWindowLongW(.., GWL_WNDPROC). - TntControl_SetText(FControl, TntControl_GetStoredText(FControl, Params_Caption)); -end; - -function SameWndMethod(A, B: TWndMethod): Boolean; -begin - Result := @A = @B; -end; - -var - PendingRecreateWndTrapList: TComponentList = nil; - -procedure TWinControlTrap.UnSubClassUnicodeControl; -begin - // remember caption for future window creation - if not (csDestroying in FControl.ComponentState) then - TntControl_SetStoredText(FControl, TntControl_GetText(FControl)); - - // restore window procs (restore WindowProc only if we are still the direct subclass) - if SameWndMethod(FControl.WindowProc, Self.WindowProc) then - FControl.WindowProc := PrevWindowProc; - TAccessWinControl(FControl).DefWndProc := PrevDefWin32Proc; - SetWindowLongW(FControl.Handle, GWL_WNDPROC, Integer(PrevWin32Proc)); - - if IDEWindow then - DestroyTrap := True - else if not (csDestroying in FControl.ComponentState) then - // control not being destroyed, probably recreating window - PendingRecreateWndTrapList.Add(Self); -end; - -var - Finalized: Boolean; { If any tnt controls are still around after finalization it must be due to a memory leak. - Windows will still try to send a WM_DESTROY, but we will just ignore it if we're finalized. } - -procedure TWinControlTrap.Win32Proc(var Message: TMessage); -begin - if (not Finalized) then begin - Inc(Win32ProcLevel); - try - with Message do begin - {$IFDEF TNT_VERIFY_WINDOWPROC} - if not SameWndMethod(FControl.WindowProc, LastVerifiedWindowProc) then begin - SubClassWindowProc; - LastVerifiedWindowProc := FControl.WindowProc; - end; - {$ENDIF} - LastWin32Msg := Msg; - Result := CallWindowProcW(PrevWin32Proc, Handle, Msg, wParam, lParam); - end; - finally - Dec(Win32ProcLevel); - end; - if (Win32ProcLevel = 0) and (DestroyTrap) then - Free; - end else if (Message.Msg = WM_DESTROY) or (Message.Msg = TNT_WM_DESTROY) then - FControl.WindowHandle := 0 -end; - -procedure TWinControlTrap.DefWin32Proc(var Message: TMessage); - - function IsChildEdit(AHandle: HWND): Boolean; - var - AHandleClass: WideString; - begin - Result := False; - if (FControl.Handle = GetParent(Handle)) then begin - // child control - SetLength(AHandleClass, 255); - SetLength(AHandleClass, GetClassNameW(AHandle, PWideChar(AHandleClass), Length(AHandleClass))); - Result := WideSameText(AHandleClass, 'EDIT'); - end; - end; - -begin - with Message do begin - if Msg = WM_NOTIFYFORMAT then - Result := WMNotifyFormatResult(HWND(Message.wParam)) - else begin - if (Msg = WM_CHAR) then begin - RestoreWMCharMsg(Message) - end; - if (Msg = WM_IME_CHAR) and (not _IsShellProgramming) and (not Win32PlatformIsXP) then - begin - { In Windows XP, DefWindowProc handles WM_IME_CHAR fine for VCL windows. } - { Before XP, DefWindowProc will sometimes produce incorrect, non-Unicode WM_CHAR. } - { Also, using PostMessageW on Windows 2000 didn't always produce the correct results. } - Message.Result := SendMessageW(Handle, WM_CHAR, wParam, lParam) - end else if (Msg = WM_IME_CHAR) and (_IsShellProgramming) then begin - { When a Tnt control is hosted by a non-delphi control, DefWindowProc doesn't always work even on XP. } - if IsChildEdit(Handle) then - Message.Result := Integer(PostMessageW(Handle, WM_CHAR, wParam, lParam)) // native edit child control - else - Message.Result := SendMessageW(Handle, WM_CHAR, wParam, lParam); - end else begin - if (Msg = WM_DESTROY) then begin - UnSubClassUnicodeControl; {The reason for doing this in DefWin32Proc is because in D9, TWinControl.WMDestroy() does a perform(WM_TEXT) operation. } - end; - { Normal DefWindowProc } - Result := CallWindowProcW(PrevDefWin32Proc, Handle, Msg, wParam, lParam); - end; - end; - end; -end; - -procedure ProcessCMHintShowMsg(var Message: TMessage); -begin - if Win32PlatformIsUnicode then begin - with TCMHintShow(Message) do begin - if (HintInfo.HintWindowClass = THintWindow) - or (HintInfo.HintWindowClass.InheritsFrom(TTntCustomHintWindow)) then begin - if (HintInfo.HintWindowClass = THintWindow) then - HintInfo.HintWindowClass := TTntCustomHintWindow; - HintInfo.HintData := HintInfo; - HintInfo.HintStr := WideGetShortHint(WideGetHint(HintInfo.HintControl)); - end; - end; - end; -end; - -function TWinControlTrap.IsInSubclassChain(Control: TWinControl): Boolean; -var - Message: TMessage; -begin - if SameWndMethod(Control.WindowProc, TAccessWinControl(Control).WndProc) then - Result := False { no subclassing } - else if SameWndMethod(Control.WindowProc, Self.WindowProc) then - Result := True { directly subclassed } - else begin - TestForNull := True; - FoundNull := False; - ZeroMemory(@Message, SizeOf(Message)); - Message.Msg := WM_NULL; - Control.WindowProc(Message); - Result := FoundNull; { indirectly subclassed } - end; -end; - -procedure TWinControlTrap.WindowProc(var Message: TMessage); -var - CameFromWindows: Boolean; -begin - if TestForNull and (Message.Msg = WM_NULL) then - FoundNull := True; - - if (not FControl.HandleAllocated) then - FControl.WndProc(Message) - else begin - CameFromWindows := LastWin32Msg <> WM_NULL; - LastWin32Msg := WM_NULL; - with Message do begin - if Msg = CM_HINTSHOW then - ProcessCMHintShowMsg(Message); - if (not CameFromWindows) - and (IsTextMessage(Msg)) then - Result := SendMessageA(Handle, Msg, wParam, lParam) - else begin - if (Msg = WM_CHAR) then begin - MakeWMCharMsgSafeForAnsi(Message); - end; - PrevWindowProc(Message) - end; - if (Msg = TNT_WM_DESTROY) then - UnSubClassUnicodeControl; {The reason for doing this in DefWin32Proc is because in D9, TWinControl.WMDestroy() does a perform(WM_TEXT) operation. } - end; - end; -end; - -//---------------------------------------------------------------------------------- - -function FindOrCreateWinControlTrap(Control: TWinControl): TWinControlTrap; -var - i: integer; -begin - // find or create trap object - Result := nil; - for i := PendingRecreateWndTrapList.Count - 1 downto 0 do begin - if TWinControlTrap(PendingRecreateWndTrapList[i]).FControl = Control then begin - Result := TWinControlTrap(PendingRecreateWndTrapList[i]); - PendingRecreateWndTrapList.Delete(i); - break; { found it } - end; - end; - if Result = nil then - Result := TWinControlTrap.Create(Control); -end; - -procedure SubClassUnicodeControl(Control: TWinControl; Params_Caption: PAnsiChar; IDEWindow: Boolean = False); -var - WinControlTrap: TWinControlTrap; -begin - if not IsWindowUnicode(Control.Handle) then - raise ETntInternalError.Create('Internal Error: SubClassUnicodeControl.Control is not Unicode.'); - - WinControlTrap := FindOrCreateWinControlTrap(Control); - WinControlTrap.SubClassControl(Params_Caption); - WinControlTrap.IDEWindow := IDEWindow; -end; - - -//----------------------------------------------- CREATE/DESTROY UNICODE HANDLE - -var - WindowAtom: TAtom; - ControlAtom: TAtom; - WindowAtomString: AnsiString; - ControlAtomString: AnsiString; - -type - TWndProc = function(HWindow: HWnd; Message, WParam, LParam: Longint): Longint; stdcall; - -function InitWndProcW(HWindow: HWnd; Message, WParam, LParam: Longint): Longint; stdcall; - - function GetObjectInstance(Control: TWinControl): Pointer; - var - WinControlTrap: TWinControlTrap; - begin - WinControlTrap := FindOrCreateWinControlTrap(Control); - PendingRecreateWndTrapList.Add(WinControlTrap); - Result := WinControlTrap.WinControl_ObjectInstance; - end; - -var - ObjectInstance: Pointer; -begin - TAccessWinControl(CreationControl).WindowHandle := HWindow; - ObjectInstance := GetObjectInstance(CreationControl); - {Controls.InitWndProc converts control to ANSI here by calling SetWindowLongA()!} - SetWindowLongW(HWindow, GWL_WNDPROC, Integer(ObjectInstance)); - if (GetWindowLongW(HWindow, GWL_STYLE) and WS_CHILD <> 0) - and (GetWindowLongW(HWindow, GWL_ID) = 0) then - SetWindowLongW(HWindow, GWL_ID, Integer(HWindow)); - SetProp(HWindow, MakeIntAtom(ControlAtom), THandle(CreationControl)); - SetProp(HWindow, MakeIntAtom(WindowAtom), THandle(CreationControl)); - CreationControl := nil; - Result := TWndProc(ObjectInstance)(HWindow, Message, WParam, lParam); -end; - -procedure RegisterUnicodeClass(Params: TCreateParams; out WideWinClassName: WideString; IDEWindow: Boolean = False); -const - UNICODE_CLASS_EXT = '.UnicodeClass'; -var - TempClass: TWndClassW; - WideClass: TWndClassW; - ClassRegistered: Boolean; - InitialProc: TFNWndProc; -begin - if IDEWindow then - InitialProc := @InitWndProc - else - InitialProc := @InitWndProcW; - - with Params do begin - WideWinClassName := WinClassName + UNICODE_CLASS_EXT; - ClassRegistered := GetClassInfoW(hInstance, PWideChar(WideWinClassName), TempClass); - if (not ClassRegistered) or (TempClass.lpfnWndProc <> InitialProc) - then begin - if ClassRegistered then Win32Check(Windows.UnregisterClassW(PWideChar(WideWinClassName), hInstance)); - // Prepare a TWndClassW record - WideClass := TWndClassW(WindowClass); - WideClass.hInstance := hInstance; - WideClass.lpfnWndProc := InitialProc; - if not Tnt_Is_IntResource(PWideChar(WindowClass.lpszMenuName)) then begin - WideClass.lpszMenuName := PWideChar(WideString(WindowClass.lpszMenuName)); - end; - WideClass.lpszClassName := PWideChar(WideWinClassName); - - // Register the UNICODE class - if RegisterClassW(WideClass) = 0 then RaiseLastOSError; - end; - end; -end; - -procedure CreateUnicodeHandle(Control: TWinControl; const Params: TCreateParams; - const SubClass: WideString; IDEWindow: Boolean = False); -var - TempSubClass: TWndClassW; - WideWinClassName: WideString; - Handle: THandle; -begin - if (not Win32PlatformIsUnicode) then begin - with Params do - TAccessWinControl(Control).WindowHandle := CreateWindowEx(ExStyle, WinClassName, - Caption, Style, X, Y, Width, Height, WndParent, 0, WindowClass.hInstance, Param); - end else begin - // SubClass the unicode version of this control by getting the correct DefWndProc - if (SubClass <> '') - and GetClassInfoW(Params.WindowClass.hInstance, PWideChar(SubClass), TempSubClass) then - TAccessWinControl(Control).DefWndProc := TempSubClass.lpfnWndProc - else - TAccessWinControl(Control).DefWndProc := @DefWindowProcW; - - // make sure Unicode window class is registered - RegisterUnicodeClass(Params, WideWinClassName, IDEWindow); - - // Create UNICODE window handle - UnicodeCreationControl := Control; - try - with Params do - Handle := CreateWindowExW(ExStyle, PWideChar(WideWinClassName), nil, - Style, X, Y, Width, Height, WndParent, 0, hInstance, Param); - if Handle = 0 then - RaiseLastOSError; - TAccessWinControl(Control).WindowHandle := Handle; - if IDEWindow then - SetWindowLongW(Handle, GWL_WNDPROC, GetWindowLong(Handle, GWL_WNDPROC)); - finally - UnicodeCreationControl := nil; - end; - - SubClassUnicodeControl(Control, Params.Caption, IDEWindow); - end; -end; - -procedure ReCreateUnicodeWnd(Control: TWinControl; Subclass: WideString; IDEWindow: Boolean = False); -var - WasFocused: Boolean; - Params: TCreateParams; -begin - with TAccessWinControl(Control) do begin - WasFocused := Focused; - DestroyHandle; - CreateParams(Params); - CreationControl := Control; - CreateUnicodeHandle(Control, Params, SubClass, IDEWindow); - StrDispose{TNT-ALLOW StrDispose}(WindowText); - WindowText := nil; - Perform(WM_SETFONT, Integer(Font.Handle), 1); - if AutoSize then AdjustSize; - UpdateControlState; - if WasFocused and (WindowHandle <> 0) then Windows.SetFocus(WindowHandle); - end; -end; - -{ TTntCustomHintWindow procs } - -function DataPointsToHintInfoForTnt(AData: Pointer): Boolean; -begin - try - Result := (AData <> nil) - and (PHintInfo(AData).HintData = AData) {points to self} - and (PHintInfo(AData).HintWindowClass.InheritsFrom(TTntCustomHintWindow)); - except - Result := False; - end; -end; - -function ExtractTntHintCaption(AData: Pointer): WideString; -var - Control: TControl; - WideHint: WideString; - AnsiHintWithShortCut: AnsiString; - ShortCut: TShortCut; -begin - Result := PHintInfo(AData).HintStr; - if Result <> '' then begin - Control := PHintInfo(AData).HintControl; - WideHint := WideGetShortHint(WideGetHint(Control)); - if (AnsiString(WideHint) = PHintInfo(AData).HintStr) then - Result := WideHint - else if Application.HintShortCuts and (Control <> nil) - and (Control.Action is TCustomAction{TNT-ALLOW TCustomAction}) then begin - ShortCut := TCustomAction{TNT-ALLOW TCustomAction}(Control.Action).ShortCut; - if (ShortCut <> scNone) then - begin - AnsiHintWithShortCut := Format{TNT-ALLOW Format}('%s (%s)', [WideHint, ShortCutToText{TNT-ALLOW ShortCutToText}(ShortCut)]); - if AnsiHintWithShortCut = PHintInfo(AData).HintStr then - Result := WideFormat('%s (%s)', [WideHint, WideShortCutToText(ShortCut)]); - end; - end; - end; -end; - -{ TTntCustomHintWindow } - -procedure TTntCustomHintWindow.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, ''); -end; - -{$IFNDEF COMPILER_7_UP} -procedure TTntCustomHintWindow.CreateParams(var Params: TCreateParams); -const - CS_DROPSHADOW = $00020000; -begin - inherited; - if Win32PlatformIsXP then { Enable drop shadow effect on Windows XP and later. } - Params.WindowClass.Style := Params.WindowClass.Style or CS_DROPSHADOW; -end; -{$ENDIF} - -function TTntCustomHintWindow.GetCaption: TWideCaption; -begin - Result := TntControl_GetText(Self) -end; - -procedure TTntCustomHintWindow.SetCaption(const Value: TWideCaption); -begin - TntControl_SetText(Self, Value); -end; - -procedure TTntCustomHintWindow.Paint; -var - R: TRect; -begin - if FBlockPaint then - exit; - if (not Win32PlatformIsUnicode) then - inherited - else begin - R := ClientRect; - Inc(R.Left, 2); - Inc(R.Top, 2); - Canvas.Font.Color := Screen.HintFont.Color; - Tnt_DrawTextW(Canvas.Handle, PWideChar(Caption), -1, R, DT_LEFT or DT_NOPREFIX or - DT_WORDBREAK or DrawTextBiDiModeFlagsReadingOnly); - end; -end; - -procedure TTntCustomHintWindow.CMTextChanged(var Message: TMessage); -begin - { Avoid flicker when calling ActivateHint } - if FActivating then Exit; - Width := WideCanvasTextWidth(Canvas, Caption) + 6; - Height := WideCanvasTextHeight(Canvas, Caption) + 6; -end; - -procedure TTntCustomHintWindow.ActivateHint(Rect: TRect; const AHint: AnsiString); -var - SaveActivating: Boolean; -begin - SaveActivating := FActivating; - try - FActivating := True; - inherited; - finally - FActivating := SaveActivating; - end; -end; - -procedure TTntCustomHintWindow.ActivateHintData(Rect: TRect; const AHint: AnsiString; AData: Pointer); -var - SaveActivating: Boolean; -begin - if (not Win32PlatformIsUnicode) - or (not DataPointsToHintInfoForTnt(AData)) then - inherited - else begin - FBlockPaint := True; - try - SaveActivating := FActivating; - try - FActivating := True; - inherited; - Caption := ExtractTntHintCaption(AData); - finally - FActivating := SaveActivating; - end; - finally - FBlockPaint := False; - end; - Invalidate; - end; -end; - -function TntHintWindow_CalcHintRect(HintWindow: TTntCustomHintWindow; MaxWidth: Integer; const AHint: WideString): TRect; -begin - Result := Rect(0, 0, MaxWidth, 0); - Tnt_DrawTextW(HintWindow.Canvas.Handle, PWideChar(AHint), -1, Result, DT_CALCRECT or DT_LEFT or - DT_WORDBREAK or DT_NOPREFIX or HintWindow.DrawTextBiDiModeFlagsReadingOnly); - Inc(Result.Right, 6); - Inc(Result.Bottom, 2); -end; - -function TTntCustomHintWindow.CalcHintRect(MaxWidth: Integer; const AHint: AnsiString; AData: Pointer): TRect; -var - WideHintStr: WideString; -begin - if (not Win32PlatformIsUnicode) - or (not DataPointsToHintInfoForTnt(AData)) then - Result := inherited CalcHintRect(MaxWidth, AHint, AData) - else begin - WideHintStr := ExtractTntHintCaption(AData); - Result := TntHintWindow_CalcHintRect(Self, MaxWidth, WideHintStr); - end; -end; - -{ TTntHintWindow } - -procedure TTntHintWindow.ActivateHint(Rect: TRect; const AHint: WideString); -var - SaveActivating: Boolean; -begin - SaveActivating := FActivating; - try - FActivating := True; - Caption := AHint; - inherited ActivateHint(Rect, AHint); - finally - FActivating := SaveActivating; - end; -end; - -procedure TTntHintWindow.ActivateHintData(Rect: TRect; const AHint: WideString; AData: Pointer); -var - SaveActivating: Boolean; -begin - FBlockPaint := True; - try - SaveActivating := FActivating; - try - FActivating := True; - Caption := AHint; - inherited ActivateHintData(Rect, AHint, AData); - finally - FActivating := SaveActivating; - end; - finally - FBlockPaint := False; - end; - Invalidate; -end; - -function TTntHintWindow.CalcHintRect(MaxWidth: Integer; const AHint: WideString; AData: Pointer): TRect; -begin - Result := TntHintWindow_CalcHintRect(Self, MaxWidth, AHint); -end; - -procedure WideListControl_AddItem(Control: TCustomListControl; const Item: WideString; AObject: TObject); -var - WideControl: IWideCustomListControl; -begin - if Control.GetInterface(IWideCustomListControl, WideControl) then - WideControl.AddItem(Item, AObject) - else - Control.AddItem(Item, AObject); -end; - -procedure InitControls; - - procedure InitAtomStrings_D6_D7_D9; - var - Controls_HInstance: Cardinal; - begin - Controls_HInstance := FindClassHInstance(TWinControl); - WindowAtomString := Format{TNT-ALLOW Format}('Delphi%.8X',[GetCurrentProcessID]); - ControlAtomString := Format{TNT-ALLOW Format}('ControlOfs%.8X%.8X', [Controls_HInstance, GetCurrentThreadID]); - end; - - {$IFDEF COMPILER_6} // verified against VCL source in Delphi 6 and BCB 6 - procedure InitAtomStrings; - begin - InitAtomStrings_D6_D7_D9; - end; - {$ENDIF} - {$IFDEF DELPHI_7} // verified against VCL source in Delphi 7 - procedure InitAtomStrings; - begin - InitAtomStrings_D6_D7_D9; - end; - {$ENDIF} - {$IFDEF DELPHI_9} // verified against VCL source in Delphi 9 - procedure InitAtomStrings; - begin - InitAtomStrings_D6_D7_D9; - end; - {$ENDIF} - {$IFDEF DELPHI_10} // verified against VCL source in Delphi 10 - procedure InitAtomStrings; - begin - InitAtomStrings_D6_D7_D9; - end; - {$ENDIF} - -begin - InitAtomStrings; - WindowAtom := WinCheckH(GlobalAddAtom(PAnsiChar(WindowAtomString))); - ControlAtom := WinCheckH(GlobalAddAtom(PAnsiChar(ControlAtomString))); -end; - -initialization - TNT_WM_DESTROY := RegisterWindowMessage('TntUnicodeVcl.DestroyWindow'); - WideControlHelpers := TComponentList.Create(True); - PendingRecreateWndTrapList := TComponentList.Create(False); - InitControls; - -finalization - GlobalDeleteAtom(ControlAtom); - GlobalDeleteAtom(WindowAtom); - FreeAndNil(WideControlHelpers); - FreeAndNil(PendingRecreateWndTrapList); - Finalized := True; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDB.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDB.pas deleted file mode 100644 index 83c6da27b..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDB.pas +++ /dev/null @@ -1,900 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntDB; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Classes, DB; - -type -{TNT-WARN TDateTimeField} - TTntDateTimeField = class(TDateTimeField{TNT-ALLOW TDateTimeField}) - protected - procedure SetAsString(const Value: AnsiString); override; - end; - -{TNT-WARN TDateField} - TTntDateField = class(TDateField{TNT-ALLOW TDateField}) - protected - procedure SetAsString(const Value: AnsiString); override; - end; - -{TNT-WARN TTimeField} - TTntTimeField = class(TTimeField{TNT-ALLOW TTimeField}) - protected - procedure SetAsString(const Value: AnsiString); override; - end; - - TFieldGetWideTextEvent = procedure(Sender: TField; var Text: WideString; - DoDisplayText: Boolean) of object; - TFieldSetWideTextEvent = procedure(Sender: TField; const Text: WideString) of object; - - IWideStringField = interface - ['{679C5F1A-4356-4696-A8F3-9C7C6970A9F6}'] - {$IFNDEF COMPILER_10_UP} - function GetAsWideString: WideString; - procedure SetAsWideString(const Value: WideString); - {$ENDIF} - function GetWideDisplayText: WideString; - function GetWideEditText: WideString; - procedure SetWideEditText(const Value: WideString); - //-- - {$IFNDEF COMPILER_10_UP} - property AsWideString: WideString read GetAsWideString write SetAsWideString{inherited}; - {$ENDIF} - property WideDisplayText: WideString read GetWideDisplayText; - property WideText: WideString read GetWideEditText write SetWideEditText; - end; - -{TNT-WARN TWideStringField} - TTntWideStringField = class(TWideStringField{TNT-ALLOW TWideStringField}, IWideStringField) - private - FOnGetText: TFieldGetWideTextEvent; - FOnSetText: TFieldSetWideTextEvent; - procedure SetOnGetText(const Value: TFieldGetWideTextEvent); - procedure SetOnSetText(const Value: TFieldSetWideTextEvent); - procedure LegacyGetText(Sender: TField; var AnsiText: AnsiString; DoDisplayText: Boolean); - procedure LegacySetText(Sender: TField; const AnsiText: AnsiString); - function GetWideDisplayText: WideString; - function GetWideEditText: WideString; - procedure SetWideEditText(const Value: WideString); - protected - {$IFNDEF COMPILER_10_UP} - function GetAsWideString: WideString; - {$ENDIF} - public - property Value: WideString read GetAsWideString write SetAsWideString; - property DisplayText{TNT-ALLOW DisplayText}: WideString read GetWideDisplayText; - property Text: WideString read GetWideEditText write SetWideEditText; - {$IFNDEF COMPILER_10_UP} - property AsWideString: WideString read GetAsWideString write SetAsWideString; - {$ENDIF} - property WideDisplayText: WideString read GetWideDisplayText; - property WideText: WideString read GetWideEditText write SetWideEditText; - published - property OnGetText: TFieldGetWideTextEvent read FOnGetText write SetOnGetText; - property OnSetText: TFieldSetWideTextEvent read FOnSetText write SetOnSetText; - end; - - TTntStringFieldEncodingMode = (emNone, emUTF8, emUTF7, emFixedCodePage, emFixedCodePage_Safe); - - //------------------------------------------------------------------------------------------- - // Comments on TTntStringFieldEncodingMode: - // - // emNone - Works like TStringField. - // emUTF8 - Should work well most databases. - // emUTF7 - Almost guaranteed to work with any database. Wasteful in database space. - // emFixedCodePage - Only tested it with Access 97, which doesn't support Unicode. - // emFixedCodePage_Safe - Like emFixedCodePage but uses char<=#128. Wasteful in database space. - // - // Only emUTF8 and emUTF7 fully support Unicode. - //------------------------------------------------------------------------------------------- - - TTntStringFieldCodePageEnum = (fcpOther, - fcpThai, fcpJapanese, fcpSimplifiedChinese, fcpTraditionalChinese, fcpKorean, - fcpCentralEuropean, fcpCyrillic, fcpLatinWestern, fcpGreek, fcpTurkish, - fcpHebrew, fcpArabic, fcpBaltic, fcpVietnamese); - -const - TntStringFieldCodePageEnumMap: array[TTntStringFieldCodePageEnum] of Word = (0, - 874, 932, 936, 950, 949, - 1250, 1251, 1252, 1253, 1254, - 1255, 1256, 1257, 1258); - -type -{TNT-WARN TStringField} - TTntStringField = class(TStringField{TNT-ALLOW TStringField},IWideStringField) - private - FOnGetText: TFieldGetWideTextEvent; - FOnSetText: TFieldSetWideTextEvent; - FEncodingMode: TTntStringFieldEncodingMode; - FFixedCodePage: Word; - FRawVariantAccess: Boolean; - procedure SetOnGetText(const Value: TFieldGetWideTextEvent); - procedure SetOnSetText(const Value: TFieldSetWideTextEvent); - procedure LegacyGetText(Sender: TField; var AnsiText: AnsiString; DoDisplayText: Boolean); - procedure LegacySetText(Sender: TField; const AnsiText: AnsiString); - function GetWideDisplayText: WideString; - function GetWideEditText: WideString; - procedure SetWideEditText(const Value: WideString); - function GetFixedCodePageEnum: TTntStringFieldCodePageEnum; - procedure SetFixedCodePageEnum(const Value: TTntStringFieldCodePageEnum); - function IsFixedCodePageStored: Boolean; - protected - {$IFDEF COMPILER_10_UP} - function GetAsWideString: WideString; override; - procedure SetAsWideString(const Value: WideString); override; - {$ELSE} - function GetAsWideString: WideString; virtual; - procedure SetAsWideString(const Value: WideString); virtual; - {$ENDIF} - function GetAsVariant: Variant; override; - procedure SetVarValue(const Value: Variant); override; - function GetAsString: string{TNT-ALLOW string}; override; - procedure SetAsString(const Value: string{TNT-ALLOW string}); override; - public - constructor Create(AOwner: TComponent); override; - property Value: WideString read GetAsWideString write SetAsWideString; - property DisplayText{TNT-ALLOW DisplayText}: WideString read GetWideDisplayText; - property Text: WideString read GetWideEditText write SetWideEditText; - {$IFNDEF COMPILER_10_UP} - property AsWideString: WideString read GetAsWideString write SetAsWideString; - {$ENDIF} - property WideDisplayText: WideString read GetWideDisplayText; - property WideText: WideString read GetWideEditText write SetWideEditText; - published - property EncodingMode: TTntStringFieldEncodingMode read FEncodingMode write FEncodingMode default emUTF8; - property FixedCodePageEnum: TTntStringFieldCodePageEnum read GetFixedCodePageEnum write SetFixedCodePageEnum stored False; - property FixedCodePage: Word read FFixedCodePage write FFixedCodePage stored IsFixedCodePageStored; - property RawVariantAccess: Boolean read FRawVariantAccess write FRawVariantAccess default False; - property OnGetText: TFieldGetWideTextEvent read FOnGetText write SetOnGetText; - property OnSetText: TFieldSetWideTextEvent read FOnSetText write SetOnSetText; - end; - -//====================== -type -{TNT-WARN TMemoField} - TTntMemoField = class(TMemoField{TNT-ALLOW TMemoField}, IWideStringField) - private - FOnGetText: TFieldGetWideTextEvent; - FOnSetText: TFieldSetWideTextEvent; - FEncodingMode: TTntStringFieldEncodingMode; - FFixedCodePage: Word; - FRawVariantAccess: Boolean; - procedure SetOnGetText(const Value: TFieldGetWideTextEvent); - procedure SetOnSetText(const Value: TFieldSetWideTextEvent); - procedure LegacyGetText(Sender: TField; var AnsiText: AnsiString; DoDisplayText: Boolean); - procedure LegacySetText(Sender: TField; const AnsiText: AnsiString); - function GetWideDisplayText: WideString; - function GetWideEditText: WideString; - procedure SetWideEditText(const Value: WideString); - function GetFixedCodePageEnum: TTntStringFieldCodePageEnum; - procedure SetFixedCodePageEnum(const Value: TTntStringFieldCodePageEnum); - function IsFixedCodePageStored: Boolean; - protected - {$IFDEF COMPILER_10_UP} - function GetAsWideString: WideString; override; - procedure SetAsWideString(const Value: WideString); override; - {$ELSE} - function GetAsWideString: WideString; virtual; - procedure SetAsWideString(const Value: WideString); virtual; - {$ENDIF} - function GetAsVariant: Variant; override; - procedure SetVarValue(const Value: Variant); override; - function GetAsString: string{TNT-ALLOW string}; override; - procedure SetAsString(const Value: string{TNT-ALLOW string}); override; - public - constructor Create(AOwner: TComponent); override; - property Value: WideString read GetAsWideString write SetAsWideString; - property DisplayText{TNT-ALLOW DisplayText}: WideString read GetWideDisplayText; - property Text: WideString read GetWideEditText write SetWideEditText; - {$IFNDEF COMPILER_10_UP} - property AsWideString: WideString read GetAsWideString write SetAsWideString; - {$ENDIF} - property WideDisplayText: WideString read GetWideDisplayText; - property WideText: WideString read GetWideEditText write SetWideEditText; - published - property EncodingMode: TTntStringFieldEncodingMode read FEncodingMode write FEncodingMode default emUTF8; - property FixedCodePageEnum: TTntStringFieldCodePageEnum read GetFixedCodePageEnum write SetFixedCodePageEnum stored False; - property FixedCodePage: Word read FFixedCodePage write FFixedCodePage stored IsFixedCodePageStored; - property RawVariantAccess: Boolean read FRawVariantAccess write FRawVariantAccess default False; - property OnGetText: TFieldGetWideTextEvent read FOnGetText write SetOnGetText; - property OnSetText: TFieldSetWideTextEvent read FOnSetText write SetOnSetText; - end; - -//====================== -function GetTntFieldClass(FieldClass: TFieldClass): TFieldClass; - -function GetWideDisplayName(Field: TField): WideString; deprecated; // for Unicode-enabled functionality, use Delphi 2006 or newer -function GetWideDisplayLabel(Field: TField): WideString; deprecated; // for Unicode-enabled functionality, use Delphi 2006 or newer -procedure SetWideDisplayLabel(Field: TField; const Value: WideString); deprecated; // for Unicode-enabled functionality, use Delphi 2006 or newer - -{TNT-WARN AsString} -{TNT-WARN DisplayText} - -function GetAsWideString(Field: TField): WideString; -procedure SetAsWideString(Field: TField; const Value: WideString); - -function GetWideDisplayText(Field: TField): WideString; - -function GetWideText(Field: TField): WideString; -procedure SetWideText(Field: TField; const Value: WideString); - -procedure RegisterTntFields; - -{ TTntWideStringField / TTntStringField common handlers } -procedure TntWideStringField_GetWideText(Field: TField; - var Text: WideString; DoDisplayText: Boolean); -function TntWideStringField_GetWideDisplayText(Field: TField; - OnGetText: TFieldGetWideTextEvent): WideString; -function TntWideStringField_GetWideEditText(Field: TField; - OnGetText: TFieldGetWideTextEvent): WideString; -procedure TntWideStringField_SetWideText(Field: TField; - const Value: WideString); -procedure TntWideStringField_SetWideEditText(Field: TField; - OnSetText: TFieldSetWideTextEvent; const Value: WideString); - - -implementation - -uses - SysUtils, MaskUtils, Variants, Contnrs, TntSystem, TntSysUtils; - -function GetTntFieldClass(FieldClass: TFieldClass): TFieldClass; -begin - if FieldClass = TDateTimeField{TNT-ALLOW TDateTimeField} then - Result := TTntDateTimeField - else if FieldClass = TDateField{TNT-ALLOW TDateField} then - Result := TTntDateField - else if FieldClass = TTimeField{TNT-ALLOW TTimeField} then - Result := TTntTimeField - else if FieldClass = TWideStringField{TNT-ALLOW TWideStringField} then - Result := TTntWideStringField - else if FieldClass = TStringField{TNT-ALLOW TStringField} then - Result := TTntStringField - else - Result := FieldClass; -end; - -function GetWideDisplayName(Field: TField): WideString; -begin - Result := Field.DisplayName; -end; - -function GetWideDisplayLabel(Field: TField): WideString; -begin - Result := Field.DisplayLabel; -end; - -procedure SetWideDisplayLabel(Field: TField; const Value: WideString); -begin - Field.DisplayLabel := Value; -end; - -function GetAsWideString(Field: TField): WideString; -{$IFDEF COMPILER_10_UP} -begin - if (Field.ClassType = TMemoField{TNT-ALLOW TMemoField}) then - Result := VarToWideStr(Field.AsVariant) { works for NexusDB BLOB Wide } - else - Result := Field.AsWideString -end; -{$ELSE} -var - WideField: IWideStringField; -begin - if Field.GetInterface(IWideStringField, WideField) then - Result := WideField.AsWideString - else if (Field is TWideStringField{TNT-ALLOW TWideStringField}) then - begin - if Field.IsNull then - // This fixes a bug in TWideStringField.GetAsWideString which does not handle Null at all. - Result := '' - else - Result := TWideStringField{TNT-ALLOW TWideStringField}(Field).Value - end else if (Field is TMemoField{TNT-ALLOW TMemoField}) then - Result := VarToWideStr(Field.AsVariant) { works for NexusDB BLOB Wide } - else - Result := Field.AsString{TNT-ALLOW AsString}; -end; -{$ENDIF} - -procedure SetAsWideString(Field: TField; const Value: WideString); -{$IFDEF COMPILER_10_UP} -begin - if (Field.ClassType = TMemoField{TNT-ALLOW TMemoField}) then - Field.AsVariant := Value { works for NexusDB BLOB Wide } - else - Field.AsWideString := Value; -end; -{$ELSE} -var - WideField: IWideStringField; -begin - if Field.GetInterface(IWideStringField, WideField) then - WideField.AsWideString := Value - else if (Field is TWideStringField{TNT-ALLOW TWideStringField}) then - TWideStringField{TNT-ALLOW TWideStringField}(Field).Value := Value - else if (Field is TMemoField{TNT-ALLOW TMemoField}) then - Field.AsVariant := Value { works for NexusDB BLOB Wide } - else - Field.AsString{TNT-ALLOW AsString} := Value; -end; -{$ENDIF} - -function GetWideDisplayText(Field: TField): WideString; -var - WideField: IWideStringField; -begin - if Field.GetInterface(IWideStringField, WideField) then - Result := WideField.WideDisplayText - else if (Field is TWideStringField{TNT-ALLOW TWideStringField}) - and (not Assigned(Field.OnGetText)) then - Result := GetAsWideString(Field) - else - Result := Field.DisplayText{TNT-ALLOW DisplayText}; -end; - -function GetWideText(Field: TField): WideString; -var - WideField: IWideStringField; -begin - if Field.GetInterface(IWideStringField, WideField) then - Result := WideField.WideText - else if (Field is TWideStringField{TNT-ALLOW TWideStringField}) - and (not Assigned(Field.OnGetText)) then - Result := GetAsWideString(Field) - else - Result := Field.Text; -end; - -procedure SetWideText(Field: TField; const Value: WideString); -var - WideField: IWideStringField; -begin - if Field.GetInterface(IWideStringField, WideField) then - WideField.WideText := Value - else if (Field is TWideStringField{TNT-ALLOW TWideStringField}) - and (not Assigned(Field.OnSetText)) then - SetAsWideString(Field, Value) - else - Field.Text := Value -end; - -{ TTntDateTimeField } - -procedure TTntDateTimeField.SetAsString(const Value: AnsiString); -begin - if Value = '' then - inherited - else - SetAsDateTime(TntStrToDateTime(Value)); -end; - -{ TTntDateField } - -procedure TTntDateField.SetAsString(const Value: AnsiString); -begin - if Value = '' then - inherited - else - SetAsDateTime(TntStrToDate(Value)); -end; - -{ TTntTimeField } - -procedure TTntTimeField.SetAsString(const Value: AnsiString); -begin - if Value = '' then - inherited - else - SetAsDateTime(TntStrToTime(Value)); -end; - -{ TTntWideStringField / TTntStringField common handlers } - -procedure TntWideStringField_LegacyGetText(Sender: TField; OnGetText: TFieldGetWideTextEvent; - var AnsiText: AnsiString; DoDisplayText: Boolean); -var - WideText: WideString; -begin - if Assigned(OnGetText) then begin - WideText := AnsiText; - OnGetText(Sender, WideText, DoDisplayText); - AnsiText := WideText; - end; -end; - -procedure TntWideStringField_LegacySetText(Sender: TField; OnSetText: TFieldSetWideTextEvent; - const AnsiText: AnsiString); -begin - if Assigned(OnSetText) then - OnSetText(Sender, AnsiText); -end; - -procedure TntWideStringField_GetWideText(Field: TField; - var Text: WideString; DoDisplayText: Boolean); -var - WideStringField: IWideStringField; -begin - Field.GetInterface(IWideStringField, WideStringField); - Assert(WideStringField <> nil); - if DoDisplayText and (Field.EditMaskPtr <> '') then - { to gain the mask, we lose Unicode! } - Text := FormatMaskText(Field.EditMaskPtr, GetAsWideString(Field)) - else - Text := GetAsWideString(Field); -end; - -function TntWideStringField_GetWideDisplayText(Field: TField; - OnGetText: TFieldGetWideTextEvent): WideString; -begin - Result := ''; - if Assigned(OnGetText) then - OnGetText(Field, Result, True) - else if Assigned(Field.OnGetText) then - Result := Field.DisplayText{TNT-ALLOW DisplayText} {we lose Unicode to handle this event} - else - TntWideStringField_GetWideText(Field, Result, True); -end; - -function TntWideStringField_GetWideEditText(Field: TField; - OnGetText: TFieldGetWideTextEvent): WideString; -begin - Result := ''; - if Assigned(OnGetText) then - OnGetText(Field, Result, False) - else if Assigned(Field.OnGetText) then - Result := Field.Text {we lose Unicode to handle this event} - else - TntWideStringField_GetWideText(Field, Result, False); -end; - -procedure TntWideStringField_SetWideText(Field: TField; - const Value: WideString); -{$IFDEF COMPILER_10_UP} -begin - Field.AsWideString := Value; -end; -{$ELSE} -var - WideStringField: IWideStringField; -begin - Field.GetInterface(IWideStringField, WideStringField); - Assert(WideStringField <> nil); - WideStringField.SetAsWideString(Value); -end; -{$ENDIF} - -procedure TntWideStringField_SetWideEditText(Field: TField; - OnSetText: TFieldSetWideTextEvent; const Value: WideString); -begin - if Assigned(OnSetText) then - OnSetText(Field, Value) - else if Assigned(Field.OnSetText) then - Field.Text := Value {we lose Unicode to handle this event} - else - TntWideStringField_SetWideText(Field, Value); -end; - -{ TTntWideStringField } - -{$IFNDEF COMPILER_10_UP} -function TTntWideStringField.GetAsWideString: WideString; -begin - if not GetData(@Result, False) then - Result := ''; {fixes a bug in inherited which has unpredictable results for NULL} -end; -{$ENDIF} - -procedure TTntWideStringField.LegacyGetText(Sender: TField; var AnsiText: AnsiString; - DoDisplayText: Boolean); -begin - TntWideStringField_LegacyGetText(Sender, OnGetText, AnsiText, DoDisplayText); -end; - -procedure TTntWideStringField.LegacySetText(Sender: TField; const AnsiText: AnsiString); -begin - TntWideStringField_LegacySetText(Sender, OnSetText, AnsiText); -end; - -procedure TTntWideStringField.SetOnGetText(const Value: TFieldGetWideTextEvent); -begin - FOnGetText := Value; - if Assigned(OnGetText) then - inherited OnGetText := LegacyGetText - else - inherited OnGetText := nil; -end; - -procedure TTntWideStringField.SetOnSetText(const Value: TFieldSetWideTextEvent); -begin - FOnSetText := Value; - if Assigned(OnSetText) then - inherited OnSetText := LegacySetText - else - inherited OnSetText := nil; -end; - -function TTntWideStringField.GetWideDisplayText: WideString; -begin - Result := TntWideStringField_GetWideDisplayText(Self, OnGetText); -end; - -function TTntWideStringField.GetWideEditText: WideString; -begin - Result := TntWideStringField_GetWideEditText(Self, OnGetText); -end; - -procedure TTntWideStringField.SetWideEditText(const Value: WideString); -begin - TntWideStringField_SetWideEditText(Self, OnSetText, Value); -end; - -(* This stuffing method works with CJK codepages - intended to store accented characters in Access 97 *) - -function SafeStringToWideStringEx(const S: AnsiString; Codepage: Word): WideString; -var - R: AnsiString; - i: Integer; -begin - R := ''; - i := 1; - while i <= Length(S) do - begin - if (S[i] = #128) then - begin - Inc(i); - if S[i] = #128 then - R := R + #128 - else - R := R + Chr(Ord(S[i]) + 128); - Inc(i); - end - else - begin - R := R + S[I]; - Inc(i); - end; - end; - Result := StringToWideStringEx(R, CodePage); -end; - -function SafeWideStringToStringEx(const W: WideString; CodePage: Word): AnsiString; -var - TempS: AnsiString; - i: integer; -begin - TempS := WideStringToStringEx(W, CodePage); - Result := ''; - for i := 1 to Length(TempS) do - begin - if TempS[i] > #128 then - Result := Result + #128 + Chr(Ord(TempS[i]) - 128) - else if TempS[i] = #128 then - Result := Result + #128 + #128 - else - Result := Result + TempS[i]; - end; -end; - -{ TTntStringField } - -constructor TTntStringField.Create(AOwner: TComponent); -begin - inherited; - FEncodingMode := emUTF8; - FFixedCodePage := TntStringFieldCodePageEnumMap[fcpLatinWestern] -end; - -function TTntStringField.GetFixedCodePageEnum: TTntStringFieldCodePageEnum; -var - i: TTntStringFieldCodePageEnum; -begin - Result := fcpOther; - for i := Low(TntStringFieldCodePageEnumMap) to High(TntStringFieldCodePageEnumMap) do begin - if TntStringFieldCodePageEnumMap[i] = FixedCodePage then begin - Result := i; - Break; {found it} - end; - end; -end; - -procedure TTntStringField.SetFixedCodePageEnum(const Value: TTntStringFieldCodePageEnum); -begin - if (Value <> fcpOther) then - FixedCodePage := TntStringFieldCodePageEnumMap[Value]; -end; - -function TTntStringField.GetAsVariant: Variant; -begin - if RawVariantAccess then - Result := inherited GetAsVariant - else if IsNull then - Result := Null - else - Result := GetAsWideString; -end; - -procedure TTntStringField.SetVarValue(const Value: Variant); -begin - if RawVariantAccess then - inherited - else - SetAsWideString(Value); -end; - -function TTntStringField.GetAsWideString: WideString; -begin - case EncodingMode of - emNone: Result := (inherited GetAsString); - emUTF8: Result := UTF8ToWideString(inherited GetAsString); - emUTF7: try - Result := UTF7ToWideString(inherited GetAsString); - except - Result := inherited GetAsString; - end; - emFixedCodePage: Result := StringToWideStringEx(inherited GetAsString, FixedCodePage); - emFixedCodePage_Safe: Result := SafeStringToWideStringEx(inherited GetAsString, FixedCodePage); - else - raise ETntInternalError.Create('Internal Error: Unexpected EncodingMode'); - end; -end; - -procedure TTntStringField.SetAsWideString(const Value: WideString); -begin - case EncodingMode of - emNone: inherited SetAsString(Value); - emUTF8: inherited SetAsString(WideStringToUTF8(Value)); - emUTF7: inherited SetAsString(WideStringToUTF7(Value)); - emFixedCodePage: inherited SetAsString(WideStringToStringEx(Value, FixedCodePage)); - emFixedCodePage_Safe: inherited SetAsString(SafeWideStringToStringEx(Value, FixedCodePage)); - else - raise ETntInternalError.Create('Internal Error: Unexpected EncodingMode'); - end; -end; - -function TTntStringField.GetAsString: string{TNT-ALLOW string}; -begin - if EncodingMode = emNone then - Result := inherited GetAsString - else - Result := GetAsWideString; -end; - -procedure TTntStringField.SetAsString(const Value: string{TNT-ALLOW string}); -begin - if EncodingMode = emNone then - inherited SetAsString(Value) - else - SetAsWideString(Value); -end; - -procedure TTntStringField.LegacyGetText(Sender: TField; var AnsiText: AnsiString; - DoDisplayText: Boolean); -begin - TntWideStringField_LegacyGetText(Sender, OnGetText, AnsiText, DoDisplayText); -end; - -procedure TTntStringField.LegacySetText(Sender: TField; const AnsiText: AnsiString); -begin - TntWideStringField_LegacySetText(Sender, OnSetText, AnsiText); -end; - -procedure TTntStringField.SetOnGetText(const Value: TFieldGetWideTextEvent); -begin - FOnGetText := Value; - if Assigned(OnGetText) then - inherited OnGetText := LegacyGetText - else - inherited OnGetText := nil; -end; - -procedure TTntStringField.SetOnSetText(const Value: TFieldSetWideTextEvent); -begin - FOnSetText := Value; - if Assigned(OnSetText) then - inherited OnSetText := LegacySetText - else - inherited OnSetText := nil; -end; - -function TTntStringField.GetWideDisplayText: WideString; -begin - Result := TntWideStringField_GetWideDisplayText(Self, OnGetText) -end; - -function TTntStringField.GetWideEditText: WideString; -begin - Result := TntWideStringField_GetWideEditText(Self, OnGetText); -end; - -procedure TTntStringField.SetWideEditText(const Value: WideString); -begin - TntWideStringField_SetWideEditText(Self, OnSetText, Value); -end; - -function TTntStringField.IsFixedCodePageStored: Boolean; -begin - Result := EncodingMode = emFixedCodePage; -end; - -//--------------------------------------------------------------------------------------------- -{ TTntMemoField } - -constructor TTntMemoField.Create(AOwner: TComponent); -begin - inherited; - FEncodingMode := emUTF8; - FFixedCodePage := TntStringFieldCodePageEnumMap[fcpLatinWestern] -end; - -function TTntMemoField.GetFixedCodePageEnum: TTntStringFieldCodePageEnum; -var - i: TTntStringFieldCodePageEnum; -begin - Result := fcpOther; - for i := Low(TntStringFieldCodePageEnumMap) to High(TntStringFieldCodePageEnumMap) do begin - if TntStringFieldCodePageEnumMap[i] = FixedCodePage then begin - Result := i; - Break; {found it} - end; - end; -end; - -procedure TTntMemoField.SetFixedCodePageEnum(const Value: TTntStringFieldCodePageEnum); -begin - if (Value <> fcpOther) then - FixedCodePage := TntStringFieldCodePageEnumMap[Value]; -end; - -function TTntMemoField.GetAsVariant: Variant; -begin - if RawVariantAccess then - Result := inherited GetAsVariant - else if IsNull then - Result := Null - else - Result := GetAsWideString; -end; - -procedure TTntMemoField.SetVarValue(const Value: Variant); -begin - if RawVariantAccess then - inherited - else - SetAsWideString(Value); -end; - -function TTntMemoField.GetAsWideString: WideString; -begin - case EncodingMode of - emNone: Result := (inherited GetAsString); - emUTF8: Result := UTF8ToWideString(inherited GetAsString); - emUTF7: try - Result := UTF7ToWideString(inherited GetAsString); - except - Result := inherited GetAsString; - end; - emFixedCodePage: Result := StringToWideStringEx(inherited GetAsString, FixedCodePage); - emFixedCodePage_Safe: Result := SafeStringToWideStringEx(inherited GetAsString, FixedCodePage); - else - raise ETntInternalError.Create('Internal Error: Unexpected EncodingMode'); - end; -end; - -procedure TTntMemoField.SetAsWideString(const Value: WideString); -begin - case EncodingMode of - emNone: inherited SetAsString(Value); - emUTF8: inherited SetAsString(WideStringToUTF8(Value)); - emUTF7: inherited SetAsString(WideStringToUTF7(Value)); - emFixedCodePage: inherited SetAsString(WideStringToStringEx(Value, FixedCodePage)); - emFixedCodePage_Safe: inherited SetAsString(SafeWideStringToStringEx(Value, FixedCodePage)); - else - raise ETntInternalError.Create('Internal Error: Unexpected EncodingMode'); - end; -end; - -function TTntMemoField.GetAsString: string{TNT-ALLOW string}; -begin - if EncodingMode = emNone then - Result := inherited GetAsString - else - Result := GetAsWideString; -end; - -procedure TTntMemoField.SetAsString(const Value: string{TNT-ALLOW string}); -begin - if EncodingMode = emNone then - inherited SetAsString(Value) - else - SetAsWideString(Value); -end; - -procedure TTntMemoField.LegacyGetText(Sender: TField; var AnsiText: AnsiString; - DoDisplayText: Boolean); -begin - TntWideStringField_LegacyGetText(Sender, OnGetText, AnsiText, DoDisplayText); -end; - -procedure TTntMemoField.LegacySetText(Sender: TField; const AnsiText: AnsiString); -begin - TntWideStringField_LegacySetText(Sender, OnSetText, AnsiText); -end; - -procedure TTntMemoField.SetOnGetText(const Value: TFieldGetWideTextEvent); -begin - FOnGetText := Value; - if Assigned(OnGetText) then - inherited OnGetText := LegacyGetText - else - inherited OnGetText := nil; -end; - -procedure TTntMemoField.SetOnSetText(const Value: TFieldSetWideTextEvent); -begin - FOnSetText := Value; - if Assigned(OnSetText) then - inherited OnSetText := LegacySetText - else - inherited OnSetText := nil; -end; - -function TTntMemoField.GetWideDisplayText: WideString; -begin - Result := TntWideStringField_GetWideDisplayText(Self, OnGetText) -end; - -function TTntMemoField.GetWideEditText: WideString; -begin - Result := TntWideStringField_GetWideEditText(Self, OnGetText); -end; - -procedure TTntMemoField.SetWideEditText(const Value: WideString); -begin - TntWideStringField_SetWideEditText(Self, OnSetText, Value); -end; - -function TTntMemoField.IsFixedCodePageStored: Boolean; -begin - Result := EncodingMode = emFixedCodePage; -end; -//================================================================== -procedure RegisterTntFields; -begin - RegisterFields([TTntDateTimeField]); - RegisterFields([TTntDateField]); - RegisterFields([TTntTimeField]); - RegisterFields([TTntWideStringField]); - RegisterFields([TTntStringField]); - RegisterFields([TTntMemoField]); -end; - -type PFieldClass = ^TFieldClass; - -initialization -{$IFDEF TNT_FIELDS} - PFieldClass(@DefaultFieldClasses[ftDate])^ := TTntDateField; - PFieldClass(@DefaultFieldClasses[ftTime])^ := TTntTimeField; - PFieldClass(@DefaultFieldClasses[ftDateTime])^ := TTntDateTimeField; - PFieldClass(@DefaultFieldClasses[ftWideString])^ := TTntWideStringField; - PFieldClass(@DefaultFieldClasses[ftString])^ := TTntStringField; - PFieldClass(@DefaultFieldClasses[ftFixedChar])^ := TTntStringField; -{$ENDIF} - -finalization - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBActns.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBActns.pas deleted file mode 100644 index 1874d72e0..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBActns.pas +++ /dev/null @@ -1,594 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntDBActns; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Classes, ActnList, DBActns, TntActnList; - -type -{TNT-WARN TDataSetAction} - TTntDataSetAction = class(TDataSetAction{TNT-ALLOW TDataSetAction}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TDataSetFirst} - TTntDataSetFirst = class(TDataSetFirst{TNT-ALLOW TDataSetFirst}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TDataSetPrior} - TTntDataSetPrior = class(TDataSetPrior{TNT-ALLOW TDataSetPrior}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TDataSetNext} - TTntDataSetNext = class(TDataSetNext{TNT-ALLOW TDataSetNext}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TDataSetLast} - TTntDataSetLast = class(TDataSetLast{TNT-ALLOW TDataSetLast}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TDataSetInsert} - TTntDataSetInsert = class(TDataSetInsert{TNT-ALLOW TDataSetInsert}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TDataSetDelete} - TTntDataSetDelete = class(TDataSetDelete{TNT-ALLOW TDataSetDelete}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TDataSetEdit} - TTntDataSetEdit = class(TDataSetEdit{TNT-ALLOW TDataSetEdit}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TDataSetPost} - TTntDataSetPost = class(TDataSetPost{TNT-ALLOW TDataSetPost}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TDataSetCancel} - TTntDataSetCancel = class(TDataSetCancel{TNT-ALLOW TDataSetCancel}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TDataSetRefresh} - TTntDataSetRefresh = class(TDataSetRefresh{TNT-ALLOW TDataSetRefresh}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -procedure TntDBActn_AfterInherited_Assign(Action: TCustomAction{TNT-ALLOW TCustomAction}; Source: TPersistent); - -implementation - -uses - TntClasses; - -{TNT-IGNORE-UNIT} - -procedure TntDBActn_AfterInherited_Assign(Action: TCustomAction{TNT-ALLOW TCustomAction}; Source: TPersistent); -begin - TntAction_AfterInherited_Assign(Action, Source); - // TDataSetAction - if (Action is TDataSetAction) and (Source is TDataSetAction) then begin - TDataSetAction(Action).DataSource := TDataSetAction(Source).DataSource; - end; -end; - -//------------------------- -// TNT DB ACTNS -//------------------------- - -{ TTntDataSetAction } - -procedure TTntDataSetAction.Assign(Source: TPersistent); -begin - inherited; - TntDBActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntDataSetAction.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntDataSetAction.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntDataSetAction.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntDataSetAction.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntDataSetAction.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntDataSetFirst } - -procedure TTntDataSetFirst.Assign(Source: TPersistent); -begin - inherited; - TntDBActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntDataSetFirst.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntDataSetFirst.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntDataSetFirst.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntDataSetFirst.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntDataSetFirst.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntDataSetPrior } - -procedure TTntDataSetPrior.Assign(Source: TPersistent); -begin - inherited; - TntDBActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntDataSetPrior.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntDataSetPrior.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntDataSetPrior.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntDataSetPrior.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntDataSetPrior.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntDataSetNext } - -procedure TTntDataSetNext.Assign(Source: TPersistent); -begin - inherited; - TntDBActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntDataSetNext.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntDataSetNext.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntDataSetNext.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntDataSetNext.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntDataSetNext.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntDataSetLast } - -procedure TTntDataSetLast.Assign(Source: TPersistent); -begin - inherited; - TntDBActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntDataSetLast.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntDataSetLast.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntDataSetLast.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntDataSetLast.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntDataSetLast.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntDataSetInsert } - -procedure TTntDataSetInsert.Assign(Source: TPersistent); -begin - inherited; - TntDBActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntDataSetInsert.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntDataSetInsert.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntDataSetInsert.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntDataSetInsert.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntDataSetInsert.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntDataSetDelete } - -procedure TTntDataSetDelete.Assign(Source: TPersistent); -begin - inherited; - TntDBActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntDataSetDelete.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntDataSetDelete.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntDataSetDelete.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntDataSetDelete.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntDataSetDelete.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntDataSetEdit } - -procedure TTntDataSetEdit.Assign(Source: TPersistent); -begin - inherited; - TntDBActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntDataSetEdit.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntDataSetEdit.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntDataSetEdit.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntDataSetEdit.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntDataSetEdit.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntDataSetPost } - -procedure TTntDataSetPost.Assign(Source: TPersistent); -begin - inherited; - TntDBActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntDataSetPost.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntDataSetPost.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntDataSetPost.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntDataSetPost.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntDataSetPost.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntDataSetCancel } - -procedure TTntDataSetCancel.Assign(Source: TPersistent); -begin - inherited; - TntDBActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntDataSetCancel.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntDataSetCancel.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntDataSetCancel.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntDataSetCancel.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntDataSetCancel.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntDataSetRefresh } - -procedure TTntDataSetRefresh.Assign(Source: TPersistent); -begin - inherited; - TntDBActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntDataSetRefresh.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntDataSetRefresh.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntDataSetRefresh.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntDataSetRefresh.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntDataSetRefresh.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBClientActns.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBClientActns.pas deleted file mode 100644 index e9a8e83eb..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBClientActns.pas +++ /dev/null @@ -1,197 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntDBClientActns; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Classes, ActnList, DBClientActns, TntActnList; - -type -{TNT-WARN TClientDataSetApply} - TTntClientDataSetApply = class(TClientDataSetApply{TNT-ALLOW TClientDataSetApply}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TClientDataSetRevert} - TTntClientDataSetRevert = class(TClientDataSetRevert{TNT-ALLOW TClientDataSetRevert}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TClientDataSetUndo} - TTntClientDataSetUndo = class(TClientDataSetUndo{TNT-ALLOW TClientDataSetUndo}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -implementation - -uses - TntClasses, TntDBActns; - -{TNT-IGNORE-UNIT} - -procedure TntDBClientActn_AfterInherited_Assign(Action: TCustomAction{TNT-ALLOW TCustomAction}; Source: TPersistent); -begin - TntDBActn_AfterInherited_Assign(Action, Source); - // TClientDataSetApply - if (Action is TClientDataSetApply) and (Source is TClientDataSetApply) then begin - TClientDataSetApply(Action).MaxErrors := TClientDataSetApply(Source).MaxErrors; - TClientDataSetApply(Action).DisplayErrorDlg := TClientDataSetApply(Source).DisplayErrorDlg; - end; - // TClientDataSetUndo - if (Action is TClientDataSetUndo) and (Source is TClientDataSetUndo) then begin - TClientDataSetUndo(Action).FollowChange := TClientDataSetUndo(Source).FollowChange; - end; -end; - -//------------------------- -// TNT DB ACTNS -//------------------------- - -{ TTntClientDataSetApply } - -procedure TTntClientDataSetApply.Assign(Source: TPersistent); -begin - inherited; - TntDBClientActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntClientDataSetApply.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntClientDataSetApply.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntClientDataSetApply.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntClientDataSetApply.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntClientDataSetApply.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntClientDataSetRevert } - -procedure TTntClientDataSetRevert.Assign(Source: TPersistent); -begin - inherited; - TntDBClientActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntClientDataSetRevert.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntClientDataSetRevert.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntClientDataSetRevert.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntClientDataSetRevert.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntClientDataSetRevert.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntClientDataSetUndo } - -procedure TTntClientDataSetUndo.Assign(Source: TPersistent); -begin - inherited; - TntDBClientActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntClientDataSetUndo.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntClientDataSetUndo.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntClientDataSetUndo.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntClientDataSetUndo.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntClientDataSetUndo.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBCtrls.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBCtrls.pas deleted file mode 100644 index 611b1d056..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBCtrls.pas +++ /dev/null @@ -1,2195 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntDBCtrls; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Classes, Windows, Messages, DB, DBCtrls, Controls, StdCtrls, - TntClasses, TntStdCtrls, TntControls, TntComCtrls, TntExtCtrls; - -type -{TNT-WARN TPaintControl} - TTntPaintControl = class - private - FOwner: TWinControl; - FClassName: WideString; - FHandle: HWnd; - FObjectInstance: Pointer; - FDefWindowProc: Pointer; - FCtl3dButton: Boolean; - function GetHandle: HWnd; - procedure SetCtl3DButton(Value: Boolean); - procedure WndProc(var Message: TMessage); - public - constructor Create(AOwner: TWinControl; const ClassName: WideString); - destructor Destroy; override; - procedure DestroyHandle; - property Ctl3DButton: Boolean read FCtl3dButton write SetCtl3dButton; - property Handle: HWnd read GetHandle; - end; - -type -{TNT-WARN TDBEdit} - TTntDBEdit = class(TDBEdit{TNT-ALLOW TDBEdit}) - private - InheritedDataChange: TNotifyEvent; - FPasswordChar: WideChar; - procedure DataChange(Sender: TObject); - procedure UpdateData(Sender: TObject); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - procedure WMPaint(var Message: TWMPaint); message WM_PAINT; - function GetTextMargins: TPoint; - function GetPasswordChar: WideChar; - procedure SetPasswordChar(const Value: WideChar); - procedure CMEnter(var Message: TCMEnter); message CM_ENTER; - private - function GetSelStart: Integer; reintroduce; virtual; - procedure SetSelStart(const Value: Integer); reintroduce; virtual; - function GetSelLength: Integer; reintroduce; virtual; - procedure SetSelLength(const Value: Integer); reintroduce; virtual; - function GetSelText: WideString; reintroduce; - procedure SetSelText(const Value: WideString); - function GetText: WideString; - procedure SetText(const Value: WideString); - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure CreateWnd; override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - public - constructor Create(AOwner: TComponent); override; - property SelText: WideString read GetSelText write SetSelText; - property SelStart: Integer read GetSelStart write SetSelStart; - property SelLength: Integer read GetSelLength write SetSelLength; - property Text: WideString read GetText write SetText; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - property PasswordChar: WideChar read GetPasswordChar write SetPasswordChar default #0; - end; - -{TNT-WARN TDBText} - TTntDBText = class(TDBText{TNT-ALLOW TDBText}) - private - FDataLink: TFieldDataLink; - InheritedDataChange: TNotifyEvent; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - procedure CMHintShow(var Message: TMessage); message CM_HINTSHOW; - procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR; - function GetCaption: TWideCaption; - function IsCaptionStored: Boolean; - procedure SetCaption(const Value: TWideCaption); - function GetFieldText: WideString; - procedure DataChange(Sender: TObject); - protected - procedure DefineProperties(Filer: TFiler); override; - function GetLabelText: WideString; reintroduce; virtual; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - procedure DoDrawText(var Rect: TRect; Flags: Longint); override; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - property Caption: TWideCaption read GetCaption write SetCaption stored IsCaptionStored; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TDBComboBox} - TTntCustomDBComboBox = class(TDBComboBox{TNT-ALLOW TDBComboBox}, - IWideCustomListControl) - private - FDataLink: TFieldDataLink; - FFilter: WideString; - FLastTime: Cardinal; - procedure UpdateData(Sender: TObject); - procedure EditingChange(Sender: TObject); - procedure CMEnter(var Message: TCMEnter); message CM_ENTER; - procedure SetReadOnly; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - procedure WMChar(var Message: TWMChar); message WM_CHAR; - private - FItems: TTntStrings; - FSaveItems: TTntStrings; - FSaveItemIndex: integer; - function GetItems: TTntStrings; - procedure SetItems(const Value: TTntStrings); reintroduce; - function GetSelStart: Integer; - procedure SetSelStart(const Value: Integer); - function GetSelLength: Integer; - procedure SetSelLength(const Value: Integer); - function GetSelText: WideString; - procedure SetSelText(const Value: WideString); - function GetText: WideString; - procedure SetText(const Value: WideString); - - procedure CNCommand(var Message: TWMCommand); message CN_COMMAND; - protected - procedure DataChange(Sender: TObject); - function GetAutoComplete_UniqueMatchOnly: Boolean; dynamic; - function GetAutoComplete_PreserveDataEntryCase: Boolean; dynamic; - procedure DoEditCharMsg(var Message: TWMChar); virtual; - function GetFieldValue: Variant; virtual; - procedure SetFieldValue(const Value: Variant); virtual; - function GetComboValue: Variant; virtual; abstract; - procedure SetComboValue(const Value: Variant); virtual; abstract; - {$IFDEF DELPHI_7} // fix for Delphi 7 only - function GetItemsClass: TCustomComboBoxStringsClass; override; - {$ENDIF} - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - procedure CreateWnd; override; - procedure DestroyWnd; override; - procedure WndProc(var Message: TMessage); override; - procedure ComboWndProc(var Message: TMessage; ComboWnd: HWnd; ComboProc: Pointer); override; - procedure KeyPress(var Key: AnsiChar); override; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - procedure CopySelection(Destination: TCustomListControl); override; - procedure AddItem(const Item: WideString; AObject: TObject); reintroduce; virtual; - public - property SelText: WideString read GetSelText write SetSelText; - property SelStart: Integer read GetSelStart write SetSelStart; - property SelLength: Integer read GetSelLength write SetSelLength; - property Text: WideString read GetText write SetText; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - property Items: TTntStrings read GetItems write SetItems; - end; - - TTntDBComboBox = class(TTntCustomDBComboBox) - protected - function GetFieldValue: Variant; override; - procedure SetFieldValue(const Value: Variant); override; - function GetComboValue: Variant; override; - procedure SetComboValue(const Value: Variant); override; - end; - -type -{TNT-WARN TDBCheckBox} - TTntDBCheckBox = class(TDBCheckBox{TNT-ALLOW TDBCheckBox}) - private - function GetCaption: TWideCaption; - procedure SetCaption(const Value: TWideCaption); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsCaptionStored: Boolean; - function IsHintStored: Boolean; - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - procedure Toggle; override; - published - property Caption: TWideCaption read GetCaption write SetCaption stored IsCaptionStored; - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TDBRichEdit} - TTntDBRichEdit = class(TTntCustomRichEdit) - private - FDataLink: TFieldDataLink; - FAutoDisplay: Boolean; - FFocused: Boolean; - FMemoLoaded: Boolean; - FDataSave: AnsiString; - procedure BeginEditing; - procedure DataChange(Sender: TObject); - procedure EditingChange(Sender: TObject); - function GetDataField: WideString; - function GetDataSource: TDataSource; - function GetField: TField; - function GetReadOnly: Boolean; - procedure SetDataField(const Value: WideString); - procedure SetDataSource(Value: TDataSource); - procedure SetReadOnly(Value: Boolean); - procedure SetAutoDisplay(Value: Boolean); - procedure SetFocused(Value: Boolean); - procedure UpdateData(Sender: TObject); - procedure WMCut(var Message: TMessage); message WM_CUT; - procedure WMPaste(var Message: TMessage); message WM_PASTE; - procedure CMEnter(var Message: TCMEnter); message CM_ENTER; - procedure CMExit(var Message: TCMExit); message CM_EXIT; - procedure WMLButtonDblClk(var Message: TWMLButtonDblClk); message WM_LBUTTONDBLCLK; - procedure CMGetDataLink(var Message: TMessage); message CM_GETDATALINK; - procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY; - protected - procedure InternalLoadMemo; dynamic; - procedure InternalSaveMemo; dynamic; - protected - procedure Change; override; - procedure KeyDown(var Key: Word; Shift: TShiftState); override; - procedure KeyPress(var Key: AnsiChar); override; - procedure Loaded; override; - procedure Notification(AComponent: TComponent; Operation: TOperation); override; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - function ExecuteAction(Action: TBasicAction): Boolean; override; - procedure LoadMemo; virtual; - function UpdateAction(Action: TBasicAction): Boolean; override; - function UseRightToLeftAlignment: Boolean; override; - property Field: TField read GetField; - published - property Align; - property Alignment; - property Anchors; - property AutoDisplay: Boolean read FAutoDisplay write SetAutoDisplay default True; - property BevelEdges; - property BevelInner; - property BevelOuter; - property BevelKind; - property BevelWidth; - property BiDiMode; - property BorderStyle; - property Color; - property Constraints; - property Ctl3D; - property DataField: WideString read GetDataField write SetDataField; - property DataSource: TDataSource read GetDataSource write SetDataSource; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property Font; - property HideSelection; - property HideScrollBars; - property ImeMode; - property ImeName; - property MaxLength; - property ParentBiDiMode; - property ParentColor; - property ParentCtl3D; - property ParentFont; - property ParentShowHint; - property PlainText; - property PopupMenu; - property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False; - property ScrollBars; - property ShowHint; - property TabOrder; - property TabStop; - property Visible; - property WantReturns; - property WantTabs; - property WordWrap; - property OnChange; - property OnClick; - property OnContextPopup; - property OnDblClick; - property OnDragDrop; - property OnDragOver; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnKeyDown; - property OnKeyPress; - property OnKeyUp; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - property OnResizeRequest; - property OnSelectionChange; - property OnProtectChange; - property OnSaveClipboard; - property OnStartDock; - property OnStartDrag; - end; - -type -{TNT-WARN TDBMemo} - TTntDBMemo = class(TTntCustomMemo) - private - FDataLink: TFieldDataLink; - FAutoDisplay: Boolean; - FFocused: Boolean; - FMemoLoaded: Boolean; - FPaintControl: TTntPaintControl; - procedure DataChange(Sender: TObject); - procedure EditingChange(Sender: TObject); - function GetDataField: WideString; - function GetDataSource: TDataSource; - function GetField: TField; - function GetReadOnly: Boolean; - procedure SetDataField(const Value: WideString); - procedure SetDataSource(Value: TDataSource); - procedure SetReadOnly(Value: Boolean); - procedure SetAutoDisplay(Value: Boolean); - procedure SetFocused(Value: Boolean); - procedure UpdateData(Sender: TObject); - procedure WMCut(var Message: TMessage); message WM_CUT; - procedure WMPaste(var Message: TMessage); message WM_PASTE; - procedure WMUndo(var Message: TMessage); message WM_UNDO; - procedure CMEnter(var Message: TCMEnter); message CM_ENTER; - procedure CMExit(var Message: TCMExit); message CM_EXIT; - procedure WMLButtonDblClk(var Message: TWMLButtonDblClk); message WM_LBUTTONDBLCLK; - procedure WMPaint(var Message: TWMPaint); message WM_PAINT; - procedure CMGetDataLink(var Message: TMessage); message CM_GETDATALINK; - protected - procedure Change; override; - procedure KeyDown(var Key: Word; Shift: TShiftState); override; - procedure KeyPress(var Key: Char{TNT-ALLOW Char}); override; - procedure Loaded; override; - procedure Notification(AComponent: TComponent; - Operation: TOperation); override; - procedure WndProc(var Message: TMessage); override; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - function ExecuteAction(Action: TBasicAction): Boolean; override; - procedure LoadMemo; virtual; - function UpdateAction(Action: TBasicAction): Boolean; override; - function UseRightToLeftAlignment: Boolean; override; - property Field: TField read GetField; - published - property Align; - property Alignment; - property Anchors; - property AutoDisplay: Boolean read FAutoDisplay write SetAutoDisplay default True; - property BevelEdges; - property BevelInner; - property BevelOuter; - property BevelKind; - property BevelWidth; - property BiDiMode; - property BorderStyle; - property Color; - property Constraints; - property Ctl3D; - property DataField: WideString read GetDataField write SetDataField; - property DataSource: TDataSource read GetDataSource write SetDataSource; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property Font; - property HideSelection; - property ImeMode; - property ImeName; - property MaxLength; - property ParentBiDiMode; - property ParentColor; - property ParentCtl3D; - property ParentFont; - property ParentShowHint; - property PopupMenu; - property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False; - property ScrollBars; - property ShowHint; - property TabOrder; - property TabStop; - property Visible; - property WantReturns; - property WantTabs; - property WordWrap; - property OnChange; - property OnClick; - property OnContextPopup; - property OnDblClick; - property OnDragDrop; - property OnDragOver; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnKeyDown; - property OnKeyPress; - property OnKeyUp; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - property OnStartDock; - property OnStartDrag; - end; - -{ TDBRadioGroup } -type - TTntDBRadioGroup = class(TTntCustomRadioGroup) - private - FDataLink: TFieldDataLink; - FValue: WideString; - FValues: TTntStrings; - FInSetValue: Boolean; - FOnChange: TNotifyEvent; - procedure DataChange(Sender: TObject); - procedure UpdateData(Sender: TObject); - function GetDataField: WideString; - function GetDataSource: TDataSource; - function GetField: TField; - function GetReadOnly: Boolean; - function GetButtonValue(Index: Integer): WideString; - procedure SetDataField(const Value: WideString); - procedure SetDataSource(Value: TDataSource); - procedure SetReadOnly(Value: Boolean); - procedure SetValue(const Value: WideString); - procedure SetItems(Value: TTntStrings); - procedure SetValues(Value: TTntStrings); - procedure CMExit(var Message: TCMExit); message CM_EXIT; - procedure CMGetDataLink(var Message: TMessage); message CM_GETDATALINK; - protected - procedure Change; dynamic; - procedure Click; override; - procedure KeyPress(var Key: Char{TNT-ALLOW Char}); override; - function CanModify: Boolean; override; - procedure Notification(AComponent: TComponent; Operation: TOperation); override; - property DataLink: TFieldDataLink read FDataLink; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - function ExecuteAction(Action: TBasicAction): Boolean; override; - function UpdateAction(Action: TBasicAction): Boolean; override; - function UseRightToLeftAlignment: Boolean; override; - property Field: TField read GetField; - property ItemIndex; - property Value: WideString read FValue write SetValue; - published - property Align; - property Anchors; - property BiDiMode; - property Caption; - property Color; - property Columns; - property Constraints; - property Ctl3D; - property DataField: WideString read GetDataField write SetDataField; - property DataSource: TDataSource read GetDataSource write SetDataSource; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property Font; - property Items write SetItems; - {$IFDEF COMPILER_7_UP} - property ParentBackground; - {$ENDIF} - property ParentBiDiMode; - property ParentColor; - property ParentCtl3D; - property ParentFont; - property ParentShowHint; - property PopupMenu; - property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False; - property ShowHint; - property TabOrder; - property TabStop; - property Values: TTntStrings read FValues write SetValues; - property Visible; - property OnChange: TNotifyEvent read FOnChange write FOnChange; - property OnClick; - property OnContextPopup; - property OnDragDrop; - property OnDragOver; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnStartDock; - property OnStartDrag; - end; - -implementation - -uses - Forms, SysUtils, Graphics, Variants, TntDB, - TntActnList, TntGraphics, TntSysUtils, RichEdit, Mask; - -function FieldIsBlobLike(Field: TField): Boolean; -begin - Result := False; - if Assigned(Field) then begin - if (Field.IsBlob) - or (Field.DataType in [Low(TBlobType).. High(TBlobType)]) then - Result := True - else if (Field is TWideStringField{TNT-ALLOW TWideStringField}) - and (Field.Size = MaxInt) then - Result := True; { wide string field filling in for a blob field } - end; -end; - -{ TTntPaintControl } - -type - TAccessWinControl = class(TWinControl); - -constructor TTntPaintControl.Create(AOwner: TWinControl; const ClassName: WideString); -begin - FOwner := AOwner; - FClassName := ClassName; -end; - -destructor TTntPaintControl.Destroy; -begin - DestroyHandle; -end; - -procedure TTntPaintControl.DestroyHandle; -begin - if FHandle <> 0 then DestroyWindow(FHandle); - Classes.FreeObjectInstance(FObjectInstance); - FHandle := 0; - FObjectInstance := nil; -end; - -function TTntPaintControl.GetHandle: HWnd; -var - Params: TCreateParams; -begin - if FHandle = 0 then - begin - FObjectInstance := Classes.MakeObjectInstance(WndProc); - TAccessWinControl(FOwner).CreateParams(Params); - Params.Style := Params.Style and not (WS_HSCROLL or WS_VSCROLL); - if (not Win32PlatformIsUnicode) then begin - with Params do - FHandle := CreateWindowEx(ExStyle, PAnsiChar(AnsiString(FClassName)), - PAnsiChar(TAccessWinControl(FOwner).Text), Style or WS_VISIBLE, - X, Y, Width, Height, Application.Handle, 0, HInstance, nil); - FDefWindowProc := Pointer(GetWindowLong(FHandle, GWL_WNDPROC)); - SetWindowLong(FHandle, GWL_WNDPROC, Integer(FObjectInstance)); - end else begin - with Params do - FHandle := CreateWindowExW(ExStyle, PWideChar(FClassName), - PWideChar(TntControl_GetText(FOwner)), Style or WS_VISIBLE, - X, Y, Width, Height, Application.Handle, 0, HInstance, nil); - FDefWindowProc := Pointer(GetWindowLongW(FHandle, GWL_WNDPROC)); - SetWindowLongW(FHandle, GWL_WNDPROC, Integer(FObjectInstance)); - end; - SendMessage(FHandle, WM_SETFONT, Integer(TAccessWinControl(FOwner).Font.Handle), 1); - end; - Result := FHandle; -end; - -procedure TTntPaintControl.SetCtl3DButton(Value: Boolean); -begin - if FHandle <> 0 then DestroyHandle; - FCtl3DButton := Value; -end; - -procedure TTntPaintControl.WndProc(var Message: TMessage); -begin - with Message do - if (Msg >= CN_CTLCOLORMSGBOX) and (Msg <= CN_CTLCOLORSTATIC) then - Result := FOwner.Perform(Msg, WParam, LParam) - else if (not Win32PlatformIsUnicode) then - Result := CallWindowProcA(FDefWindowProc, FHandle, Msg, WParam, LParam) - else - Result := CallWindowProcW(FDefWindowProc, FHandle, Msg, WParam, LParam); -end; - -{ THackFieldDataLink } -type - THackFieldDataLink_D6_D7_D9 = class(TDataLink) - protected - FxxxField: TField; - FxxxFieldName: string{TNT-ALLOW string}; - FxxxControl: TComponent; - FxxxEditing: Boolean; - FModified: Boolean; - end; - -{$IFDEF COMPILER_6} // verified against VCL source in Delphi 6 and BCB 6 - THackFieldDataLink = THackFieldDataLink_D6_D7_D9; -{$ENDIF} -{$IFDEF DELPHI_7} // verified against VCL source in Delphi 7 - THackFieldDataLink = THackFieldDataLink_D6_D7_D9; -{$ENDIF} -{$IFDEF DELPHI_9} // verified against VCL source in Delphi 9 - THackFieldDataLink = THackFieldDataLink_D6_D7_D9; -{$ENDIF} -{$IFDEF DELPHI_10} // verified against VCL source in Delphi 10 - THackFieldDataLink = class(TDataLink) - protected - FxxxField: TField; - FxxxFieldName: WideString; - FxxxControl: TComponent; - FxxxEditing: Boolean; - FModified: Boolean; - end; -{$ENDIF} - -{ TTntDBEdit } - -type - THackDBEdit_D6_D7_D9 = class(TCustomMaskEdit) - protected - FDataLink: TFieldDataLink; - FCanvas: TControlCanvas; - FAlignment: TAlignment; - FFocused: Boolean; - end; - -{$IFDEF COMPILER_6} // verified against VCL source in Delphi 6 and BCB 6 - THackDBEdit = THackDBEdit_D6_D7_D9; -{$ENDIF} -{$IFDEF DELPHI_7} // verified against VCL source in Delphi 7 - THackDBEdit = THackDBEdit_D6_D7_D9; -{$ENDIF} -{$IFDEF DELPHI_9} // verified against VCL source in Delphi 9 - THackDBEdit = THackDBEdit_D6_D7_D9; -{$ENDIF} -{$IFDEF DELPHI_10} // verified against VCL source in Delphi 10 - THackDBEdit = THackDBEdit_D6_D7_D9; -{$ENDIF} - -constructor TTntDBEdit.Create(AOwner: TComponent); -begin - inherited; - InheritedDataChange := THackDBEdit(Self).FDataLink.OnDataChange; - THackDBEdit(Self).FDataLink.OnDataChange := DataChange; - THackDBEdit(Self).FDataLink.OnUpdateData := UpdateData; -end; - -procedure TTntDBEdit.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, 'EDIT'); -end; - -procedure TTntDBEdit.CreateWnd; -begin - inherited; - TntCustomEdit_AfterInherited_CreateWnd(Self, FPasswordChar); -end; - -procedure TTntDBEdit.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntDBEdit.GetSelStart: Integer; -begin - Result := TntCustomEdit_GetSelStart(Self); -end; - -procedure TTntDBEdit.SetSelStart(const Value: Integer); -begin - TntCustomEdit_SetSelStart(Self, Value); -end; - -function TTntDBEdit.GetSelLength: Integer; -begin - Result := TntCustomEdit_GetSelLength(Self); -end; - -procedure TTntDBEdit.SetSelLength(const Value: Integer); -begin - TntCustomEdit_SetSelLength(Self, Value); -end; - -function TTntDBEdit.GetSelText: WideString; -begin - Result := TntCustomEdit_GetSelText(Self); -end; - -procedure TTntDBEdit.SetSelText(const Value: WideString); -begin - TntCustomEdit_SetSelText(Self, Value); -end; - -function TTntDBEdit.GetPasswordChar: WideChar; -begin - Result := TntCustomEdit_GetPasswordChar(Self, FPasswordChar) -end; - -procedure TTntDBEdit.SetPasswordChar(const Value: WideChar); -begin - TntCustomEdit_SetPasswordChar(Self, FPasswordChar, Value); -end; - -function TTntDBEdit.GetText: WideString; -begin - Result := TntControl_GetText(Self); -end; - -procedure TTntDBEdit.SetText(const Value: WideString); -begin - TntControl_SetText(Self, Value); -end; - -procedure TTntDBEdit.DataChange(Sender: TObject); -begin - with THackDBEdit(Self), Self do begin - if Field = nil then - InheritedDataChange(Sender) - else begin - if FAlignment <> Field.Alignment then - begin - EditText := ''; {forces update} - FAlignment := Field.Alignment; - end; - EditMask := Field.EditMask; - if not (csDesigning in ComponentState) then - begin - if (Field.DataType in [ftString, ftWideString]) and (MaxLength = 0) then - MaxLength := Field.Size; - end; - if FFocused and FDataLink.CanModify then - Text := GetWideText(Field) - else - begin - Text := GetWideDisplayText(Field); - if FDataLink.Editing and THackFieldDataLink(FDataLink).FModified then - Modified := True; - end; - end; - end; -end; - -procedure TTntDBEdit.UpdateData(Sender: TObject); -begin - ValidateEdit; - SetWideText(Field, Text); -end; - -procedure TTntDBEdit.CMEnter(var Message: TCMEnter); -var - SaveFarEast: Boolean; -begin - SaveFarEast := SysLocale.FarEast; - try - SysLocale.FarEast := False; - inherited; // inherited tries to work around Win95 FarEast bug, but introduces others - finally - SysLocale.FarEast := SaveFarEast; - end; -end; - -function TTntDBEdit.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntDBEdit.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntDBEdit.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntDBEdit.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntDBEdit.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -procedure TTntDBEdit.WMPaint(var Message: TWMPaint); -const - AlignStyle : array[Boolean, TAlignment] of DWORD = - ((WS_EX_LEFT, WS_EX_RIGHT, WS_EX_LEFT), - (WS_EX_RIGHT, WS_EX_LEFT, WS_EX_LEFT)); -var - ALeft: Integer; - _Margins: TPoint; - R: TRect; - DC: HDC; - PS: TPaintStruct; - S: WideString; - AAlignment: TAlignment; - I: Integer; -begin - with THackDBEdit(Self), Self do begin - AAlignment := FAlignment; - if UseRightToLeftAlignment then ChangeBiDiModeAlignment(AAlignment); - if ((AAlignment = taLeftJustify) or FFocused) and (not (csPaintCopy in ControlState)) - or (not Win32PlatformIsUnicode) then - begin - inherited; - Exit; - end; - { Since edit controls do not handle justification unless multi-line (and - then only poorly) we will draw right and center justify manually unless - the edit has the focus. } - if FCanvas = nil then - begin - FCanvas := TControlCanvas.Create; - FCanvas.Control := Self; - end; - DC := Message.DC; - if DC = 0 then DC := BeginPaint(Handle, PS); - FCanvas.Handle := DC; - try - FCanvas.Font := Font; - with FCanvas do - begin - R := ClientRect; - if not (NewStyleControls and Ctl3D) and (BorderStyle = bsSingle) then - begin - Brush.Color := clWindowFrame; - FrameRect(R); - InflateRect(R, -1, -1); - end; - Brush.Color := Color; - if not Enabled then - Font.Color := clGrayText; - if (csPaintCopy in ControlState) and (Field <> nil) then - begin - S := GetWideDisplayText(Field); - case CharCase of - ecUpperCase: - S := Tnt_WideUpperCase(S); - ecLowerCase: - S := Tnt_WideLowerCase(S); - end; - end else - S := Text { EditText? }; - if PasswordChar <> #0 then - for I := 1 to Length(S) do S[I] := PasswordChar; - _Margins := GetTextMargins; - case AAlignment of - taLeftJustify: ALeft := _Margins.X; - taRightJustify: ALeft := ClientWidth - WideCanvasTextWidth(FCanvas, S) - _Margins.X - 1; - else - ALeft := (ClientWidth - WideCanvasTextWidth(FCanvas, S)) div 2; - end; - if SysLocale.MiddleEast then UpdateTextFlags; - WideCanvasTextRect(FCanvas, R, ALeft, _Margins.Y, S); - end; - finally - FCanvas.Handle := 0; - if Message.DC = 0 then EndPaint(Handle, PS); - end; - end; -end; - -function TTntDBEdit.GetTextMargins: TPoint; -var - DC: HDC; - SaveFont: HFont; - I: Integer; - SysMetrics, Metrics: TTextMetric; -begin - if NewStyleControls then - begin - if BorderStyle = bsNone then I := 0 else - if Ctl3D then I := 1 else I := 2; - Result.X := SendMessage(Handle, EM_GETMARGINS, 0, 0) and $0000FFFF + I; - Result.Y := I; - end else - begin - if BorderStyle = bsNone then I := 0 else - begin - DC := GetDC(0); - GetTextMetrics(DC, SysMetrics); - SaveFont := SelectObject(DC, Font.Handle); - GetTextMetrics(DC, Metrics); - SelectObject(DC, SaveFont); - ReleaseDC(0, DC); - I := SysMetrics.tmHeight; - if I > Metrics.tmHeight then I := Metrics.tmHeight; - I := I div 4; - end; - Result.X := I; - Result.Y := I; - end; -end; - -{ TTntDBText } - -constructor TTntDBText.Create(AOwner: TComponent); -begin - inherited; - FDataLink := TDataLink(Perform(CM_GETDATALINK, 0, 0)) as TFieldDataLink; - InheritedDataChange := FDataLink.OnDataChange; - FDataLink.OnDataChange := DataChange; -end; - -destructor TTntDBText.Destroy; -begin - FDataLink := nil; - inherited; -end; - -procedure TTntDBText.CMDialogChar(var Message: TCMDialogChar); -begin - TntLabel_CMDialogChar(Self, Message, Caption); -end; - -function TTntDBText.IsCaptionStored: Boolean; -begin - Result := TntControl_IsCaptionStored(Self) -end; - -function TTntDBText.GetCaption: TWideCaption; -begin - Result := TntControl_GetText(Self); -end; - -procedure TTntDBText.SetCaption(const Value: TWideCaption); -begin - TntControl_SetText(Self, Value); -end; - -procedure TTntDBText.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntDBText.GetLabelText: WideString; -begin - if csPaintCopy in ControlState then - Result := GetFieldText - else - Result := Caption; -end; - -procedure TTntDBText.DoDrawText(var Rect: TRect; Flags: Integer); -begin - if not TntLabel_DoDrawText(Self, Rect, Flags, GetLabelText) then - inherited; -end; - -function TTntDBText.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntDBText.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntDBText.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntDBText.CMHintShow(var Message: TMessage); -begin - ProcessCMHintShowMsg(Message); - inherited; -end; - -procedure TTntDBText.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntDBText.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -function TTntDBText.GetFieldText: WideString; -begin - if Field <> nil then - Result := GetWideDisplayText(Field) - else - if csDesigning in ComponentState then Result := Name else Result := ''; -end; - -procedure TTntDBText.DataChange(Sender: TObject); -begin - Caption := GetFieldText; -end; - -{ TTntCustomDBComboBox } - -constructor TTntCustomDBComboBox.Create(AOwner: TComponent); -begin - inherited; - FItems := TTntComboBoxStrings.Create; - TTntComboBoxStrings(FItems).ComboBox := Self; - FDataLink := TDataLink(Perform(CM_GETDATALINK, 0, 0)) as TFieldDataLink; - FDataLink.OnDataChange := DataChange; - FDataLink.OnUpdateData := UpdateData; - FDataLink.OnEditingChange := EditingChange; -end; - -destructor TTntCustomDBComboBox.Destroy; -begin - FreeAndNil(FItems); - FreeAndNil(FSaveItems); - FDataLink := nil; - inherited; -end; - -procedure TTntCustomDBComboBox.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, 'COMBOBOX'); -end; - -procedure TTntCustomDBComboBox.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -type - TAccessCustomComboBox = class(TCustomComboBox{TNT-ALLOW TCustomComboBox}); - -procedure TTntCustomDBComboBox.CreateWnd; -var - PreInheritedAnsiText: AnsiString; -begin - PreInheritedAnsiText := TAccessCustomComboBox(Self).Text; - inherited; - TntCombo_AfterInherited_CreateWnd(Self, Items, FSaveItems, FSaveItemIndex, PreInheritedAnsiText); -end; - -procedure TTntCustomDBComboBox.DestroyWnd; -var - SavedText: WideString; -begin - if not (csDestroyingHandle in ControlState) then begin { avoid recursion when parent is TToolBar and system font changes. } - TntCombo_BeforeInherited_DestroyWnd(Self, Items, FSaveItems, ItemIndex, FSaveItemIndex, SavedText); - inherited; - TntControl_SetStoredText(Self, SavedText); - end; -end; - -procedure TTntCustomDBComboBox.SetReadOnly; -begin - if (Style in [csDropDown, csSimple]) and HandleAllocated then - SendMessage(EditHandle, EM_SETREADONLY, Ord(not FDataLink.CanModify), 0); -end; - -procedure TTntCustomDBComboBox.EditingChange(Sender: TObject); -begin - SetReadOnly; -end; - -procedure TTntCustomDBComboBox.CMEnter(var Message: TCMEnter); -var - SaveFarEast: Boolean; -begin - SaveFarEast := SysLocale.FarEast; - try - SysLocale.FarEast := False; - inherited; // inherited tries to work around Win95 FarEast bug, but introduces others - finally - SysLocale.FarEast := SaveFarEast; - end; -end; - -procedure TTntCustomDBComboBox.WndProc(var Message: TMessage); -begin - if (not (csDesigning in ComponentState)) - and (Message.Msg = CB_SHOWDROPDOWN) - and (Message.WParam = 0) - and (not FDataLink.Editing) then begin - DataChange(Self); {Restore text} - Dispatch(Message); {Do NOT call inherited!} - end else - inherited WndProc(Message); -end; - -procedure TTntCustomDBComboBox.ComboWndProc(var Message: TMessage; ComboWnd: HWnd; ComboProc: Pointer); -begin - if not TntCombo_ComboWndProc(Self, Message, ComboWnd, ComboProc, DoEditCharMsg) then - inherited; -end; - -procedure TTntCustomDBComboBox.KeyPress(var Key: AnsiChar); -var - SaveAutoComplete: Boolean; -begin - TntCombo_BeforeKeyPress(Self, SaveAutoComplete); - try - inherited; - finally - TntCombo_AfterKeyPress(Self, SaveAutoComplete); - end; -end; - -procedure TTntCustomDBComboBox.DoEditCharMsg(var Message: TWMChar); -begin - TntCombo_AutoCompleteKeyPress(Self, Items, Message, - GetAutoComplete_UniqueMatchOnly, GetAutoComplete_PreserveDataEntryCase); -end; - -procedure TTntCustomDBComboBox.WMChar(var Message: TWMChar); -begin - TntCombo_AutoSearchKeyPress(Self, Items, Message, FFilter, FLastTime); - inherited; -end; - -function TTntCustomDBComboBox.GetItems: TTntStrings; -begin - Result := FItems; -end; - -procedure TTntCustomDBComboBox.SetItems(const Value: TTntStrings); -begin - FItems.Assign(Value); - DataChange(Self); -end; - -function TTntCustomDBComboBox.GetSelStart: Integer; -begin - Result := TntCombo_GetSelStart(Self); -end; - -procedure TTntCustomDBComboBox.SetSelStart(const Value: Integer); -begin - TntCombo_SetSelStart(Self, Value); -end; - -function TTntCustomDBComboBox.GetSelLength: Integer; -begin - Result := TntCombo_GetSelLength(Self); -end; - -procedure TTntCustomDBComboBox.SetSelLength(const Value: Integer); -begin - TntCombo_SetSelLength(Self, Value); -end; - -function TTntCustomDBComboBox.GetSelText: WideString; -begin - Result := TntCombo_GetSelText(Self); -end; - -procedure TTntCustomDBComboBox.SetSelText(const Value: WideString); -begin - TntCombo_SetSelText(Self, Value); -end; - -function TTntCustomDBComboBox.GetText: WideString; -begin - Result := TntControl_GetText(Self); -end; - -procedure TTntCustomDBComboBox.SetText(const Value: WideString); -begin - TntControl_SetText(Self, Value); -end; - -procedure TTntCustomDBComboBox.CNCommand(var Message: TWMCommand); -begin - if not TntCombo_CNCommand(Self, Items, Message) then - inherited; -end; - -function TTntCustomDBComboBox.GetFieldValue: Variant; -begin - Result := Field.Value; -end; - -procedure TTntCustomDBComboBox.SetFieldValue(const Value: Variant); -begin - Field.Value := Value; -end; - -procedure TTntCustomDBComboBox.DataChange(Sender: TObject); -begin - if not (Style = csSimple) and DroppedDown then Exit; - if Field <> nil then - SetComboValue(GetFieldValue) - else - if csDesigning in ComponentState then - SetComboValue(Name) - else - SetComboValue(Null); -end; - -procedure TTntCustomDBComboBox.UpdateData(Sender: TObject); -begin - SetFieldValue(GetComboValue); -end; - -function TTntCustomDBComboBox.GetAutoComplete_PreserveDataEntryCase: Boolean; -begin - Result := True; -end; - -function TTntCustomDBComboBox.GetAutoComplete_UniqueMatchOnly: Boolean; -begin - Result := False; -end; - -function TTntCustomDBComboBox.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntCustomDBComboBox.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntCustomDBComboBox.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntCustomDBComboBox.AddItem(const Item: WideString; AObject: TObject); -begin - TntComboBox_AddItem(Items, Item, AObject); -end; - -procedure TTntCustomDBComboBox.CopySelection(Destination: TCustomListControl); -begin - TntComboBox_CopySelection(Items, ItemIndex, Destination); -end; - -procedure TTntCustomDBComboBox.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomDBComboBox.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{$IFDEF DELPHI_7} // fix for Delphi 7 only -function TTntCustomDBComboBox.GetItemsClass: TCustomComboBoxStringsClass; -begin - Result := TD7PatchedComboBoxStrings; -end; -{$ENDIF} - -{ TTntDBComboBox } - -function TTntDBComboBox.GetFieldValue: Variant; -begin - Result := GetWideText(Field); -end; - -procedure TTntDBComboBox.SetFieldValue(const Value: Variant); -begin - SetWideText(Field, Value); -end; - -procedure TTntDBComboBox.SetComboValue(const Value: Variant); -var - I: Integer; - Redraw: Boolean; - OldValue: WideString; - NewValue: WideString; -begin - OldValue := VarToWideStr(GetComboValue); - NewValue := VarToWideStr(Value); - - if NewValue <> OldValue then - begin - if Style <> csDropDown then - begin - Redraw := (Style <> csSimple) and HandleAllocated; - if Redraw then Items.BeginUpdate; - try - if NewValue = '' then I := -1 else I := Items.IndexOf(NewValue); - ItemIndex := I; - finally - Items.EndUpdate; - end; - if I >= 0 then Exit; - end; - if Style in [csDropDown, csSimple] then Text := NewValue; - end; -end; - -function TTntDBComboBox.GetComboValue: Variant; -var - I: Integer; -begin - if Style in [csDropDown, csSimple] then Result := Text else - begin - I := ItemIndex; - if I < 0 then Result := '' else Result := Items[I]; - end; -end; - -{ TTntDBCheckBox } - -procedure TTntDBCheckBox.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, 'BUTTON'); -end; - -procedure TTntDBCheckBox.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntDBCheckBox.IsCaptionStored: Boolean; -begin - Result := TntControl_IsCaptionStored(Self); -end; - -function TTntDBCheckBox.GetCaption: TWideCaption; -begin - Result := TntControl_GetText(Self) -end; - -procedure TTntDBCheckBox.SetCaption(const Value: TWideCaption); -begin - TntControl_SetText(Self, Value); -end; - -function TTntDBCheckBox.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntDBCheckBox.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntDBCheckBox.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntDBCheckBox.Toggle; -var - FDataLink: TDataLink; -begin - inherited; - FDataLink := TDataLink(Perform(CM_GETDATALINK, 0, 0)) as TFieldDataLink; - FDataLink.UpdateRecord; -end; - -procedure TTntDBCheckBox.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntDBCheckBox.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntDBRichEdit } - -constructor TTntDBRichEdit.Create(AOwner: TComponent); -begin - inherited Create(AOwner); - inherited ReadOnly := True; - FAutoDisplay := True; - FDataLink := TFieldDataLink.Create; - FDataLink.Control := Self; - FDataLink.OnDataChange := DataChange; - FDataLink.OnEditingChange := EditingChange; - FDataLink.OnUpdateData := UpdateData; -end; - -destructor TTntDBRichEdit.Destroy; -begin - FDataLink.Free; - FDataLink := nil; - inherited Destroy; -end; - -procedure TTntDBRichEdit.Loaded; -begin - inherited Loaded; - if (csDesigning in ComponentState) then - DataChange(Self) -end; - -procedure TTntDBRichEdit.Notification(AComponent: TComponent; Operation: TOperation); -begin - inherited; - if (Operation = opRemove) and (FDataLink <> nil) and - (AComponent = DataSource) then DataSource := nil; -end; - -function TTntDBRichEdit.UseRightToLeftAlignment: Boolean; -begin - Result := DBUseRightToLeftAlignment(Self, Field); -end; - -procedure TTntDBRichEdit.BeginEditing; -begin - if not FDataLink.Editing then - try - if FieldIsBlobLike(Field) then - FDataSave := Field.AsString{TNT-ALLOW AsString}; - FDataLink.Edit; - finally - FDataSave := ''; - end; -end; - -procedure TTntDBRichEdit.KeyDown(var Key: Word; Shift: TShiftState); -begin - inherited KeyDown(Key, Shift); - if FMemoLoaded then - begin - if (Key = VK_DELETE) or (Key = VK_BACK) or - ((Key = VK_INSERT) and (ssShift in Shift)) or - (((Key = Ord('V')) or (Key = Ord('X'))) and (ssCtrl in Shift)) then - BeginEditing; - end; -end; - -procedure TTntDBRichEdit.KeyPress(var Key: AnsiChar); -begin - inherited KeyPress(Key); - if FMemoLoaded then - begin - if (Key in [#32..#255]) and (Field <> nil) and - not Field.IsValidChar(Key) then - begin - MessageBeep(0); - Key := #0; - end; - case Key of - ^H, ^I, ^J, ^M, ^V, ^X, #32..#255: - BeginEditing; - #27: - FDataLink.Reset; - end; - end else - begin - if Key = #13 then LoadMemo; - Key := #0; - end; -end; - -procedure TTntDBRichEdit.Change; -begin - if FMemoLoaded then - FDataLink.Modified; - FMemoLoaded := True; - inherited Change; -end; - -procedure TTntDBRichEdit.CNNotify(var Message: TWMNotify); -begin - inherited; - if Message.NMHdr^.code = EN_PROTECTED then - Message.Result := 0 { allow the operation (otherwise the control might appear stuck) } -end; - -function TTntDBRichEdit.GetDataSource: TDataSource; -begin - Result := FDataLink.DataSource; -end; - -procedure TTntDBRichEdit.SetDataSource(Value: TDataSource); -begin - FDataLink.DataSource := Value; - if Value <> nil then Value.FreeNotification(Self); -end; - -function TTntDBRichEdit.GetDataField: WideString; -begin - Result := FDataLink.FieldName; -end; - -procedure TTntDBRichEdit.SetDataField(const Value: WideString); -begin - FDataLink.FieldName := Value; -end; - -function TTntDBRichEdit.GetReadOnly: Boolean; -begin - Result := FDataLink.ReadOnly; -end; - -procedure TTntDBRichEdit.SetReadOnly(Value: Boolean); -begin - FDataLink.ReadOnly := Value; -end; - -function TTntDBRichEdit.GetField: TField; -begin - Result := FDataLink.Field; -end; - -procedure TTntDBRichEdit.InternalLoadMemo; -var - Stream: TStringStream{TNT-ALLOW TStringStream}; -begin - if PlainText then - Text := GetAsWideString(Field) - else begin - Stream := TStringStream{TNT-ALLOW TStringStream}.Create(Field.AsString{TNT-ALLOW AsString}); - try - Lines.LoadFromStream(Stream); - finally - Stream.Free; - end; - end; -end; - -procedure TTntDBRichEdit.LoadMemo; -begin - if not FMemoLoaded and Assigned(Field) and FieldIsBlobLike(Field) then - begin - try - InternalLoadMemo; - FMemoLoaded := True; - except - { Rich Edit Load failure } - on E:EOutOfResources do - Lines.Text := WideFormat('(%s)', [E.Message]); - end; - EditingChange(Self); - end; -end; - -procedure TTntDBRichEdit.DataChange(Sender: TObject); -begin - if Field <> nil then - if FieldIsBlobLike(Field) then - begin - if FAutoDisplay or (FDataLink.Editing and FMemoLoaded) then - begin - { Check if the data has changed since we read it the first time } - if (FDataSave <> '') and (FDataSave = Field.AsString{TNT-ALLOW AsString}) then Exit; - FMemoLoaded := False; - LoadMemo; - end else - begin - Text := WideFormat('(%s)', [Field.DisplayName]); - FMemoLoaded := False; - end; - end else - begin - if FFocused and FDataLink.CanModify then - Text := GetWideText(Field) - else - Text := GetWideDisplayText(Field); - FMemoLoaded := True; - end - else - begin - if csDesigning in ComponentState then Text := Name else Text := ''; - FMemoLoaded := False; - end; - if HandleAllocated then - RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_ERASE or RDW_FRAME); -end; - -procedure TTntDBRichEdit.EditingChange(Sender: TObject); -begin - inherited ReadOnly := not (FDataLink.Editing and FMemoLoaded); -end; - -procedure TTntDBRichEdit.InternalSaveMemo; -var - Stream: TStringStream{TNT-ALLOW TStringStream}; -begin - if PlainText then - SetAsWideString(Field, Text) - else begin - Stream := TStringStream{TNT-ALLOW TStringStream}.Create(''); - try - Lines.SaveToStream(Stream); - Field.AsString{TNT-ALLOW AsString} := Stream.DataString; - finally - Stream.Free; - end; - end; -end; - -procedure TTntDBRichEdit.UpdateData(Sender: TObject); -begin - if FieldIsBlobLike(Field) then - InternalSaveMemo - else - SetAsWideString(Field, Text); -end; - -procedure TTntDBRichEdit.SetFocused(Value: Boolean); -begin - if FFocused <> Value then - begin - FFocused := Value; - if not Assigned(Field) or not FieldIsBlobLike(Field) then - FDataLink.Reset; - end; -end; - -procedure TTntDBRichEdit.CMEnter(var Message: TCMEnter); -begin - SetFocused(True); - inherited; -end; - -procedure TTntDBRichEdit.CMExit(var Message: TCMExit); -begin - try - FDataLink.UpdateRecord; - except - SetFocus; - raise; - end; - SetFocused(False); - inherited; -end; - -procedure TTntDBRichEdit.SetAutoDisplay(Value: Boolean); -begin - if FAutoDisplay <> Value then - begin - FAutoDisplay := Value; - if Value then LoadMemo; - end; -end; - -procedure TTntDBRichEdit.WMLButtonDblClk(var Message: TWMLButtonDblClk); -begin - if not FMemoLoaded then LoadMemo else inherited; -end; - -procedure TTntDBRichEdit.WMCut(var Message: TMessage); -begin - BeginEditing; - inherited; -end; - -procedure TTntDBRichEdit.WMPaste(var Message: TMessage); -begin - BeginEditing; - inherited; -end; - -procedure TTntDBRichEdit.CMGetDataLink(var Message: TMessage); -begin - Message.Result := Integer(FDataLink); -end; - -function TTntDBRichEdit.ExecuteAction(Action: TBasicAction): Boolean; -begin - Result := inherited ExecuteAction(Action) or (FDataLink <> nil) and - FDataLink.ExecuteAction(Action); -end; - -function TTntDBRichEdit.UpdateAction(Action: TBasicAction): Boolean; -begin - Result := inherited UpdateAction(Action) or (FDataLink <> nil) and - FDataLink.UpdateAction(Action); -end; - -{ TTntDBMemo } - -constructor TTntDBMemo.Create(AOwner: TComponent); -begin - inherited Create(AOwner); - inherited ReadOnly := True; - ControlStyle := ControlStyle + [csReplicatable]; - FAutoDisplay := True; - FDataLink := TFieldDataLink.Create; - FDataLink.Control := Self; - FDataLink.OnDataChange := DataChange; - FDataLink.OnEditingChange := EditingChange; - FDataLink.OnUpdateData := UpdateData; - FPaintControl := TTntPaintControl.Create(Self, 'EDIT'); -end; - -destructor TTntDBMemo.Destroy; -begin - FPaintControl.Free; - FDataLink.Free; - FDataLink := nil; - inherited Destroy; -end; - -procedure TTntDBMemo.Loaded; -begin - inherited Loaded; - if (csDesigning in ComponentState) then DataChange(Self); -end; - -procedure TTntDBMemo.Notification(AComponent: TComponent; - Operation: TOperation); -begin - inherited Notification(AComponent, Operation); - if (Operation = opRemove) and (FDataLink <> nil) and - (AComponent = DataSource) then DataSource := nil; -end; - -function TTntDBMemo.UseRightToLeftAlignment: Boolean; -begin - Result := DBUseRightToLeftAlignment(Self, Field); -end; - -procedure TTntDBMemo.KeyDown(var Key: Word; Shift: TShiftState); -begin - inherited KeyDown(Key, Shift); - if FMemoLoaded then - begin - if (Key = VK_DELETE) or ((Key = VK_INSERT) and (ssShift in Shift)) then - FDataLink.Edit; - end; -end; - -procedure TTntDBMemo.KeyPress(var Key: Char{TNT-ALLOW Char}); -begin - inherited KeyPress(Key); - if FMemoLoaded then - begin - if (Key in [#32..#255]) and (FDataLink.Field <> nil) and - not FDataLink.Field.IsValidChar(Key) then - begin - MessageBeep(0); - Key := #0; - end; - case Key of - ^H, ^I, ^J, ^M, ^V, ^X, #32..#255: - FDataLink.Edit; - #27: - FDataLink.Reset; - end; - end else - begin - if Key = #13 then LoadMemo; - Key := #0; - end; -end; - -procedure TTntDBMemo.Change; -begin - if FMemoLoaded then FDataLink.Modified; - FMemoLoaded := True; - inherited Change; -end; - -function TTntDBMemo.GetDataSource: TDataSource; -begin - Result := FDataLink.DataSource; -end; - -procedure TTntDBMemo.SetDataSource(Value: TDataSource); -begin - if not (FDataLink.DataSourceFixed and (csLoading in ComponentState)) then - FDataLink.DataSource := Value; - if Value <> nil then Value.FreeNotification(Self); -end; - -function TTntDBMemo.GetDataField: WideString; -begin - Result := FDataLink.FieldName; -end; - -procedure TTntDBMemo.SetDataField(const Value: WideString); -begin - FDataLink.FieldName := Value; -end; - -function TTntDBMemo.GetReadOnly: Boolean; -begin - Result := FDataLink.ReadOnly; -end; - -procedure TTntDBMemo.SetReadOnly(Value: Boolean); -begin - FDataLink.ReadOnly := Value; -end; - -function TTntDBMemo.GetField: TField; -begin - Result := FDataLink.Field; -end; - -procedure TTntDBMemo.LoadMemo; -begin - if not FMemoLoaded and Assigned(FDataLink.Field) and FieldIsBlobLike(FDataLink.Field) then - begin - try - Lines.Text := GetAsWideString(FDataLink.Field); - FMemoLoaded := True; - except - { Memo too large } - on E:EInvalidOperation do - Lines.Text := WideFormat('(%s)', [E.Message]); - end; - EditingChange(Self); - end; -end; - -procedure TTntDBMemo.DataChange(Sender: TObject); -begin - if FDataLink.Field <> nil then - if FieldIsBlobLike(FDataLink.Field) then - begin - if FAutoDisplay or (FDataLink.Editing and FMemoLoaded) then - begin - FMemoLoaded := False; - LoadMemo; - end else - begin - Text := WideFormat('(%s)', [FDataLink.Field.DisplayName]); - FMemoLoaded := False; - EditingChange(Self); - end; - end else - begin - if FFocused and FDataLink.CanModify then - Text := GetWideText(FDataLink.Field) - else - Text := GetWideDisplayText(FDataLink.Field); - FMemoLoaded := True; - end - else - begin - if csDesigning in ComponentState then Text := Name else Text := ''; - FMemoLoaded := False; - end; - if HandleAllocated then - RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_ERASE or RDW_FRAME); -end; - -procedure TTntDBMemo.EditingChange(Sender: TObject); -begin - inherited ReadOnly := not (FDataLink.Editing and FMemoLoaded); -end; - -procedure TTntDBMemo.UpdateData(Sender: TObject); -begin - SetAsWideString(FDataLink.Field, Text); -end; - -procedure TTntDBMemo.SetFocused(Value: Boolean); -begin - if FFocused <> Value then - begin - FFocused := Value; - if not Assigned(FDataLink.Field) or not FieldIsBlobLike(FDataLink.Field) then - FDataLink.Reset; - end; -end; - -procedure TTntDBMemo.WndProc(var Message: TMessage); -begin - with Message do - if (Msg = WM_CREATE) or (Msg = WM_WINDOWPOSCHANGED) or - (Msg = CM_FONTCHANGED) then FPaintControl.DestroyHandle; - inherited; -end; - -procedure TTntDBMemo.CMEnter(var Message: TCMEnter); -begin - SetFocused(True); - inherited; -end; - -procedure TTntDBMemo.CMExit(var Message: TCMExit); -begin - try - FDataLink.UpdateRecord; - except - SetFocus; - raise; - end; - SetFocused(False); - inherited; -end; - -procedure TTntDBMemo.SetAutoDisplay(Value: Boolean); -begin - if FAutoDisplay <> Value then - begin - FAutoDisplay := Value; - if Value then LoadMemo; - end; -end; - -procedure TTntDBMemo.WMLButtonDblClk(var Message: TWMLButtonDblClk); -begin - if not FMemoLoaded then LoadMemo else inherited; -end; - -procedure TTntDBMemo.WMCut(var Message: TMessage); -begin - FDataLink.Edit; - inherited; -end; - -procedure TTntDBMemo.WMUndo(var Message: TMessage); -begin - FDataLink.Edit; - inherited; -end; - -procedure TTntDBMemo.WMPaste(var Message: TMessage); -begin - FDataLink.Edit; - inherited; -end; - -procedure TTntDBMemo.CMGetDataLink(var Message: TMessage); -begin - Message.Result := Integer(FDataLink); -end; - -procedure TTntDBMemo.WMPaint(var Message: TWMPaint); -var - S: WideString; -begin - if not (csPaintCopy in ControlState) then - inherited - else begin - if FDataLink.Field <> nil then - if FieldIsBlobLike(FDataLink.Field) then - begin - if FAutoDisplay then - S := TntAdjustLineBreaks(GetAsWideString(FDataLink.Field)) else - S := WideFormat('(%s)', [FDataLink.Field.DisplayName]); - end else - S := GetWideDisplayText(FDataLink.Field); - if (not Win32PlatformIsUnicode) then - SendMessageA(FPaintControl.Handle, WM_SETTEXT, 0, Integer(PAnsiChar(AnsiString(S)))) - else begin - SendMessageW(FPaintControl.Handle, WM_SETTEXT, 0, Integer(PWideChar(S))); - end; - SendMessage(FPaintControl.Handle, WM_ERASEBKGND, Integer(Message.DC), 0); - SendMessage(FPaintControl.Handle, WM_PAINT, Integer(Message.DC), 0); - end; -end; - -function TTntDBMemo.ExecuteAction(Action: TBasicAction): Boolean; -begin - Result := inherited ExecuteAction(Action) or (FDataLink <> nil) and - FDataLink.ExecuteAction(Action); -end; - -function TTntDBMemo.UpdateAction(Action: TBasicAction): Boolean; -begin - Result := inherited UpdateAction(Action) or (FDataLink <> nil) and - FDataLink.UpdateAction(Action); -end; - -{ TTntDBRadioGroup } - -constructor TTntDBRadioGroup.Create(AOwner: TComponent); -begin - inherited Create(AOwner); - FDataLink := TFieldDataLink.Create; - FDataLink.Control := Self; - FDataLink.OnDataChange := DataChange; - FDataLink.OnUpdateData := UpdateData; - FValues := TTntStringList.Create; -end; - -destructor TTntDBRadioGroup.Destroy; -begin - FDataLink.Free; - FDataLink := nil; - FValues.Free; - inherited Destroy; -end; - -procedure TTntDBRadioGroup.Notification(AComponent: TComponent; - Operation: TOperation); -begin - inherited Notification(AComponent, Operation); - if (Operation = opRemove) and (FDataLink <> nil) and - (AComponent = DataSource) then DataSource := nil; -end; - -function TTntDBRadioGroup.UseRightToLeftAlignment: Boolean; -begin - Result := inherited UseRightToLeftAlignment; -end; - -procedure TTntDBRadioGroup.DataChange(Sender: TObject); -begin - if FDataLink.Field <> nil then - Value := GetWideText(FDataLink.Field) else - Value := ''; -end; - -procedure TTntDBRadioGroup.UpdateData(Sender: TObject); -begin - if FDataLink.Field <> nil then - SetWideText(FDataLink.Field, Value); -end; - -function TTntDBRadioGroup.GetDataSource: TDataSource; -begin - Result := FDataLink.DataSource; -end; - -procedure TTntDBRadioGroup.SetDataSource(Value: TDataSource); -begin - FDataLink.DataSource := Value; - if Value <> nil then Value.FreeNotification(Self); -end; - -function TTntDBRadioGroup.GetDataField: WideString; -begin - Result := FDataLink.FieldName; -end; - -procedure TTntDBRadioGroup.SetDataField(const Value: WideString); -begin - FDataLink.FieldName := Value; -end; - -function TTntDBRadioGroup.GetReadOnly: Boolean; -begin - Result := FDataLink.ReadOnly; -end; - -procedure TTntDBRadioGroup.SetReadOnly(Value: Boolean); -begin - FDataLink.ReadOnly := Value; -end; - -function TTntDBRadioGroup.GetField: TField; -begin - Result := FDataLink.Field; -end; - -function TTntDBRadioGroup.GetButtonValue(Index: Integer): WideString; -begin - if (Index < FValues.Count) and (FValues[Index] <> '') then - Result := FValues[Index] - else if Index < Items.Count then - Result := Items[Index] - else - Result := ''; -end; - -procedure TTntDBRadioGroup.SetValue(const Value: WideString); -var - WasFocused: Boolean; - I, Index: Integer; -begin - if FValue <> Value then - begin - FInSetValue := True; - try - WasFocused := (ItemIndex > -1) and (Buttons[ItemIndex].Focused); - Index := -1; - for I := 0 to Items.Count - 1 do - if Value = GetButtonValue(I) then - begin - Index := I; - Break; - end; - ItemIndex := Index; - // Move the focus rect along with the selected index - if WasFocused then - Buttons[ItemIndex].SetFocus; - finally - FInSetValue := False; - end; - FValue := Value; - Change; - end; -end; - -procedure TTntDBRadioGroup.CMExit(var Message: TCMExit); -begin - try - FDataLink.UpdateRecord; - except - if ItemIndex >= 0 then - (Controls[ItemIndex] as TTntRadioButton).SetFocus else - (Controls[0] as TTntRadioButton).SetFocus; - raise; - end; - inherited; -end; - -procedure TTntDBRadioGroup.CMGetDataLink(var Message: TMessage); -begin - Message.Result := Integer(FDataLink); -end; - -procedure TTntDBRadioGroup.Click; -begin - if not FInSetValue then - begin - inherited Click; - if ItemIndex >= 0 then Value := GetButtonValue(ItemIndex); - if FDataLink.Editing then FDataLink.Modified; - end; -end; - -procedure TTntDBRadioGroup.SetItems(Value: TTntStrings); -begin - Items.Assign(Value); - DataChange(Self); -end; - -procedure TTntDBRadioGroup.SetValues(Value: TTntStrings); -begin - FValues.Assign(Value); - DataChange(Self); -end; - -procedure TTntDBRadioGroup.Change; -begin - if Assigned(FOnChange) then FOnChange(Self); -end; - -procedure TTntDBRadioGroup.KeyPress(var Key: Char{TNT-ALLOW Char}); -begin - inherited KeyPress(Key); - case Key of - #8, ' ': FDataLink.Edit; - #27: FDataLink.Reset; - end; -end; - -function TTntDBRadioGroup.CanModify: Boolean; -begin - Result := FDataLink.Edit; -end; - -function TTntDBRadioGroup.ExecuteAction(Action: TBasicAction): Boolean; -begin - Result := inherited ExecuteAction(Action) or (DataLink <> nil) and - DataLink.ExecuteAction(Action); -end; - -function TTntDBRadioGroup.UpdateAction(Action: TBasicAction): Boolean; -begin - Result := inherited UpdateAction(Action) or (DataLink <> nil) and - DataLink.UpdateAction(Action); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBGrids.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBGrids.pas deleted file mode 100644 index 35804e580..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBGrids.pas +++ /dev/null @@ -1,1175 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntDBGrids; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Classes, TntClasses, Controls, Windows, Grids, DBGrids, Messages, DBCtrls, DB, TntStdCtrls; - -type -{TNT-WARN TColumnTitle} - TTntColumnTitle = class(TColumnTitle{TNT-ALLOW TColumnTitle}) - private - FCaption: WideString; - procedure SetInheritedCaption(const Value: AnsiString); - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function IsCaptionStored: Boolean; - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - procedure RestoreDefaults; override; - function DefaultCaption: WideString; - published - property Caption: WideString read GetCaption write SetCaption stored IsCaptionStored; - end; - -{TNT-WARN TColumn} -type - TTntColumn = class(TColumn{TNT-ALLOW TColumn}) - private - FWidePickList: TTntStrings; - function GetWidePickList: TTntStrings; - procedure SetWidePickList(const Value: TTntStrings); - procedure HandlePickListChange(Sender: TObject); - function GetTitle: TTntColumnTitle; - procedure SetTitle(const Value: TTntColumnTitle); - protected - procedure DefineProperties(Filer: TFiler); override; - function CreateTitle: TColumnTitle{TNT-ALLOW TColumnTitle}; override; - public - destructor Destroy; override; - property WidePickList: TTntStrings read GetWidePickList write SetWidePickList; - published -{TNT-WARN PickList} - property PickList{TNT-ALLOW PickList}: TTntStrings read GetWidePickList write SetWidePickList; - property Title: TTntColumnTitle read GetTitle write SetTitle; - end; - - { TDBGridInplaceEdit adds support for a button on the in-place editor, - which can be used to drop down a table-based lookup list, a stringlist-based - pick list, or (if button style is esEllipsis) fire the grid event - OnEditButtonClick. } - -type - TDBGridInplaceEdit{TNT-ALLOW TDBGridInplaceEdit} = class(TInplaceEditList) - private - {$IFDEF COMPILER_6} // verified against VCL source in Delphi 6 and BCB 6 - FDataList: TDBLookupListBox; // 1st field - Delphi/BCB 6 TCustomDBGrid assumes this - FUseDataList: Boolean; // 2nd field - Delphi/BCB 6 TCustomDBGrid assumes this - {$ENDIF} - {$IFDEF DELPHI_7} // verified against VCL source in Delphi 7 - FDataList: TDBLookupListBox; // 1st field - Delphi 7 TCustomDBGrid assumes this - FUseDataList: Boolean; // 2nd field - Delphi 7 TCustomDBGrid assumes this - {$ENDIF} - {$IFDEF DELPHI_9} // verified against VCL source in Delphi 9 - FDataList: TDBLookupListBox; // 1st field - Delphi 9 TCustomDBGrid assumes this - FUseDataList: Boolean; // 2nd field - Delphi 9 TCustomDBGrid assumes this - {$ENDIF} - {$IFDEF DELPHI_10} // verified against VCL source in Delphi 10 - FDataList: TDBLookupListBox; // 1st field - Delphi 10 TCustomDBGrid assumes this - FUseDataList: Boolean; // 2nd field - Delphi 10 TCustomDBGrid assumes this - {$ENDIF} - FLookupSource: TDatasource; - FWidePickListBox: TTntCustomListbox; - function GetWidePickListBox: TTntCustomListbox; - protected - procedure CloseUp(Accept: Boolean); override; - procedure DoEditButtonClick; override; - procedure DropDown; override; - procedure UpdateContents; override; - property UseDataList: Boolean read FUseDataList; - public - constructor Create(Owner: TComponent); override; - property DataList: TDBLookupListBox read FDataList; - property WidePickListBox: TTntCustomListbox read GetWidePickListBox; - end; - -type -{TNT-WARN TDBGridInplaceEdit} - TTntDBGridInplaceEdit = class(TDBGridInplaceEdit{TNT-ALLOW TDBGridInplaceEdit}) - private - FInDblClick: Boolean; - FBlockSetText: Boolean; - procedure WMSetText(var Message: TWMSetText); message WM_SETTEXT; - protected - function GetText: WideString; virtual; - procedure SetText(const Value: WideString); virtual; - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure UpdateContents; override; - procedure DblClick; override; - public - property Text: WideString read GetText write SetText; - end; - -{TNT-WARN TDBGridColumns} - TTntDBGridColumns = class(TDBGridColumns{TNT-ALLOW TDBGridColumns}) - private - function GetColumn(Index: Integer): TTntColumn; - procedure SetColumn(Index: Integer; const Value: TTntColumn); - public - function Add: TTntColumn; - property Items[Index: Integer]: TTntColumn read GetColumn write SetColumn; default; - end; - - TTntGridDataLink = class(TGridDataLink) - private - OriginalSetText: TFieldSetTextEvent; - procedure GridUpdateFieldText(Sender: TField; const Text: AnsiString); - protected - procedure UpdateData; override; - procedure RecordChanged(Field: TField); override; - end; - -{TNT-WARN TCustomDBGrid} - TTntCustomDBGrid = class(TCustomDBGrid{TNT-ALLOW TCustomDBGrid}) - private - FEditText: WideString; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - procedure WMChar(var Msg: TWMChar); message WM_CHAR; - function GetColumns: TTntDBGridColumns; - procedure SetColumns(const Value: TTntDBGridColumns); - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure ShowEditorChar(Ch: WideChar); dynamic; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - function CreateColumns: TDBGridColumns{TNT-ALLOW TDBGridColumns}; override; - property Columns: TTntDBGridColumns read GetColumns write SetColumns; - function CreateEditor: TInplaceEdit{TNT-ALLOW TInplaceEdit}; override; - function CreateDataLink: TGridDataLink; override; - function GetEditText(ACol, ARow: Longint): WideString; reintroduce; - procedure DrawCell(ACol, ARow: Integer; ARect: TRect; AState: TGridDrawState); override; - procedure SetEditText(ACol, ARow: Longint; const Value: AnsiString); override; - public - procedure DefaultDrawColumnCell(const Rect: TRect; DataCol: Integer; - Column: TTntColumn; State: TGridDrawState); dynamic; - procedure DefaultDrawDataCell(const Rect: TRect; Field: TField; - State: TGridDrawState); - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TDBGrid} - TTntDBGrid = class(TTntCustomDBGrid) - public - property Canvas; - property SelectedRows; - published - property Align; - property Anchors; - property BiDiMode; - property BorderStyle; - property Color; - property Columns stored False; //StoreColumns; - property Constraints; - property Ctl3D; - property DataSource; - property DefaultDrawing; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property FixedColor; - property Font; - property ImeMode; - property ImeName; - property Options; - property ParentBiDiMode; - property ParentColor; - property ParentCtl3D; - property ParentFont; - property ParentShowHint; - property PopupMenu; - property ReadOnly; - property ShowHint; - property TabOrder; - property TabStop; - property TitleFont; - property Visible; - property OnCellClick; - property OnColEnter; - property OnColExit; - property OnColumnMoved; - property OnDrawDataCell; { obsolete } - property OnDrawColumnCell; - property OnDblClick; - property OnDragDrop; - property OnDragOver; - property OnEditButtonClick; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnKeyDown; - property OnKeyPress; - property OnKeyUp; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - property OnMouseWheel; - property OnMouseWheelDown; - property OnMouseWheelUp; - property OnStartDock; - property OnStartDrag; - property OnTitleClick; - end; - -implementation - -uses - SysUtils, TntControls, Math, Variants, Forms, - TntGraphics, Graphics, TntDB, TntActnList, TntSysUtils, TntWindows; - -{ TTntColumnTitle } - -procedure TTntColumnTitle.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntColumnTitle.DefaultCaption: WideString; -var - Field: TField; -begin - Field := Column.Field; - if Assigned(Field) then - Result := Field.DisplayName - else - Result := Column.FieldName; -end; - -function TTntColumnTitle.IsCaptionStored: Boolean; -begin - Result := (cvTitleCaption in Column.AssignedValues) and - (FCaption <> DefaultCaption); -end; - -procedure TTntColumnTitle.SetInheritedCaption(const Value: AnsiString); -begin - inherited Caption := Value; -end; - -function TTntColumnTitle.GetCaption: WideString; -begin - if cvTitleCaption in Column.AssignedValues then - Result := GetSyncedWideString(FCaption, inherited Caption) - else - Result := DefaultCaption; -end; - -procedure TTntColumnTitle.SetCaption(const Value: WideString); -begin - if not (Column as TTntColumn).IsStored then - inherited Caption := Value - else begin - if (cvTitleCaption in Column.AssignedValues) and (Value = FCaption) then Exit; - SetSyncedWideString(Value, FCaption, inherited Caption, SetInheritedCaption); - end; -end; - -procedure TTntColumnTitle.Assign(Source: TPersistent); -begin - inherited Assign(Source); - if Source is TTntColumnTitle then - begin - if cvTitleCaption in TTntColumnTitle(Source).Column.AssignedValues then - Caption := TTntColumnTitle(Source).Caption; - end; -end; - -procedure TTntColumnTitle.RestoreDefaults; -begin - FCaption := ''; - inherited; -end; - -{ TTntColumn } - -procedure TTntColumn.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntColumn.CreateTitle: TColumnTitle{TNT-ALLOW TColumnTitle}; -begin - Result := TTntColumnTitle.Create(Self); -end; - -function TTntColumn.GetTitle: TTntColumnTitle; -begin - Result := (inherited Title) as TTntColumnTitle; -end; - -procedure TTntColumn.SetTitle(const Value: TTntColumnTitle); -begin - inherited Title := Value; -end; - -function TTntColumn.GetWidePickList: TTntStrings; -begin - if FWidePickList = nil then begin - FWidePickList := TTntStringList.Create; - TTntStringList(FWidePickList).OnChange := HandlePickListChange; - end; - Result := FWidePickList; -end; - -procedure TTntColumn.SetWidePickList(const Value: TTntStrings); -begin - if Value = nil then - begin - FWidePickList.Free; - FWidePickList := nil; - (inherited PickList{TNT-ALLOW PickList}).Clear; - Exit; - end; - WidePickList.Assign(Value); -end; - -procedure TTntColumn.HandlePickListChange(Sender: TObject); -begin - inherited PickList{TNT-ALLOW PickList}.Assign(WidePickList); -end; - -destructor TTntColumn.Destroy; -begin - inherited; - FWidePickList.Free; -end; - -{ TTntPopupListbox } -type - TTntPopupListbox = class(TTntCustomListbox) - private - FSearchText: WideString; - FSearchTickCount: Longint; - protected - procedure CreateParams(var Params: TCreateParams); override; - procedure CreateWnd; override; - procedure WMChar(var Message: TWMChar); message WM_CHAR; - procedure KeyPressW(var Key: WideChar); - procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; - end; - -procedure TTntPopupListbox.CreateParams(var Params: TCreateParams); -begin - inherited CreateParams(Params); - with Params do - begin - Style := Style or WS_BORDER; - ExStyle := WS_EX_TOOLWINDOW or WS_EX_TOPMOST; - AddBiDiModeExStyle(ExStyle); - WindowClass.Style := CS_SAVEBITS; - end; -end; - -procedure TTntPopupListbox.CreateWnd; -begin - inherited CreateWnd; - Windows.SetParent(Handle, 0); - CallWindowProc(DefWndProc, Handle, wm_SetFocus, 0, 0); -end; - -procedure TTntPopupListbox.WMChar(var Message: TWMChar); -var - Key: WideChar; -begin - Key := GetWideCharFromWMCharMsg(Message); - KeyPressW(Key); - SetWideCharForWMCharMsg(Message, Key); - inherited; -end; - -procedure TTntPopupListbox.KeypressW(var Key: WideChar); -var - TickCount: Integer; -begin - case Key of - #8, #27: FSearchText := ''; - #32..High(WideChar): - begin - TickCount := GetTickCount; - if TickCount - FSearchTickCount > 2000 then FSearchText := ''; - FSearchTickCount := TickCount; - if Length(FSearchText) < 32 then FSearchText := FSearchText + Key; - if IsWindowUnicode(Handle) then - SendMessageW(Handle, LB_SelectString, WORD(-1), Longint(PWideChar(FSearchText))) - else - SendMessageA(Handle, LB_SelectString, WORD(-1), Longint(PAnsiChar(AnsiString(FSearchText)))); - Key := #0; - end; - end; -end; - -procedure TTntPopupListbox.MouseUp(Button: TMouseButton; Shift: TShiftState; - X, Y: Integer); -begin - inherited MouseUp(Button, Shift, X, Y); - (Owner as TDBGridInplaceEdit{TNT-ALLOW TDBGridInplaceEdit}).CloseUp((X >= 0) and (Y >= 0) and - (X < Width) and (Y < Height)); -end; - -{ TTntPopupDataList } -type - TTntPopupDataList = class(TPopupDataList) - protected - procedure Paint; override; - end; - -procedure TTntPopupDataList.Paint; -var - FRecordIndex: Integer; - FRecordCount: Integer; - FKeySelected: Boolean; - FKeyField: TField; - - procedure UpdateListVars; - begin - if ListActive then - begin - FRecordIndex := ListLink.ActiveRecord; - FRecordCount := ListLink.RecordCount; - FKeySelected := not VarIsNull(KeyValue) or - not ListLink.DataSet.BOF; - end else - begin - FRecordIndex := 0; - FRecordCount := 0; - FKeySelected := False; - end; - - FKeyField := nil; - if ListLink.Active and (KeyField <> '') then - FKeyField := GetFieldProperty(ListLink.DataSet, Self, KeyField); - end; - - function VarEquals(const V1, V2: Variant): Boolean; - begin - Result := False; - try - Result := V1 = V2; - except - end; - end; - -var - I, J, W, X, TxtWidth, TxtHeight, LastFieldIndex: Integer; - S: WideString; - R: TRect; - Selected: Boolean; - Field: TField; - AAlignment: TAlignment; -begin - UpdateListVars; - Canvas.Font := Font; - TxtWidth := WideCanvasTextWidth(Canvas, '0'); - TxtHeight := WideCanvasTextHeight(Canvas, '0'); - LastFieldIndex := ListFields.Count - 1; - if ColorToRGB(Color) <> ColorToRGB(clBtnFace) then - Canvas.Pen.Color := clBtnFace else - Canvas.Pen.Color := clBtnShadow; - for I := 0 to RowCount - 1 do - begin - if Enabled then - Canvas.Font.Color := Font.Color else - Canvas.Font.Color := clGrayText; - Canvas.Brush.Color := Color; - Selected := not FKeySelected and (I = 0); - R.Top := I * TxtHeight; - R.Bottom := R.Top + TxtHeight; - if I < FRecordCount then - begin - ListLink.ActiveRecord := I; - if not VarIsNull(KeyValue) and - VarEquals(FKeyField.Value, KeyValue) then - begin - Canvas.Font.Color := clHighlightText; - Canvas.Brush.Color := clHighlight; - Selected := True; - end; - R.Right := 0; - for J := 0 to LastFieldIndex do - begin - Field := ListFields[J]; - if J < LastFieldIndex then - W := Field.DisplayWidth * TxtWidth + 4 else - W := ClientWidth - R.Right; - S := GetWideDisplayText(Field); - X := 2; - AAlignment := Field.Alignment; - if UseRightToLeftAlignment then ChangeBiDiModeAlignment(AAlignment); - case AAlignment of - taRightJustify: X := W - WideCanvasTextWidth(Canvas, S) - 3; - taCenter: X := (W - WideCanvasTextWidth(Canvas, S)) div 2; - end; - R.Left := R.Right; - R.Right := R.Right + W; - if SysLocale.MiddleEast then TControlCanvas(Canvas).UpdateTextFlags; - WideCanvasTextRect(Canvas, R, R.Left + X, R.Top, S); - if J < LastFieldIndex then - begin - Canvas.MoveTo(R.Right, R.Top); - Canvas.LineTo(R.Right, R.Bottom); - Inc(R.Right); - if R.Right >= ClientWidth then Break; - end; - end; - end; - R.Left := 0; - R.Right := ClientWidth; - if I >= FRecordCount then Canvas.FillRect(R); - if Selected then - Canvas.DrawFocusRect(R); - end; - if FRecordCount <> 0 then ListLink.ActiveRecord := FRecordIndex; -end; - -//----------------------------------------------------------------------------------------- -// TDBGridInplaceEdit - Delphi 6 and higher -//----------------------------------------------------------------------------------------- - -constructor TDBGridInplaceEdit{TNT-ALLOW TDBGridInplaceEdit}.Create(Owner: TComponent); -begin - inherited Create(Owner); - FLookupSource := TDataSource.Create(Self); -end; - -function TDBGridInplaceEdit{TNT-ALLOW TDBGridInplaceEdit}.GetWidePickListBox: TTntCustomListBox; -var - PopupListbox: TTntPopupListbox; -begin - if not Assigned(FWidePickListBox) then - begin - PopupListbox := TTntPopupListbox.Create(Self); - PopupListbox.Visible := False; - PopupListbox.Parent := Self; - PopupListbox.OnMouseUp := ListMouseUp; - PopupListbox.IntegralHeight := True; - PopupListbox.ItemHeight := 11; - FWidePickListBox := PopupListBox; - end; - Result := FWidePickListBox; -end; - -procedure TDBGridInplaceEdit{TNT-ALLOW TDBGridInplaceEdit}.CloseUp(Accept: Boolean); -var - MasterField: TField; - ListValue: Variant; -begin - if ListVisible then - begin - if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0); - if ActiveList = DataList then - ListValue := DataList.KeyValue - else - if WidePickListBox.ItemIndex <> -1 then - ListValue := WidePickListBox.Items[WidePickListBox.ItemIndex]; - SetWindowPos(ActiveList.Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or - SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW); - ListVisible := False; - if Assigned(FDataList) then - FDataList.ListSource := nil; - FLookupSource.Dataset := nil; - Invalidate; - if Accept then - if ActiveList = DataList then - with Grid as TTntCustomDBGrid, Columns[SelectedIndex].Field do - begin - MasterField := DataSet.FieldByName(KeyFields); - if MasterField.CanModify and DataLink.Edit then - MasterField.Value := ListValue; - end - else - if (not VarIsNull(ListValue)) and EditCanModify then - with Grid as TTntCustomDBGrid do - SetWideText(Columns[SelectedIndex].Field, ListValue) - end; -end; - -procedure TDBGridInplaceEdit{TNT-ALLOW TDBGridInplaceEdit}.DoEditButtonClick; -begin - (Grid as TTntCustomDBGrid).EditButtonClick; -end; - -type TAccessTntCustomListbox = class(TTntCustomListbox); - -procedure TDBGridInplaceEdit{TNT-ALLOW TDBGridInplaceEdit}.DropDown; -var - Column: TTntColumn; - I, J, Y: Integer; -begin - if not ListVisible then - begin - with (Grid as TTntCustomDBGrid) do - Column := Columns[SelectedIndex] as TTntColumn; - if ActiveList = FDataList then - with Column.Field do - begin - FDataList.Color := Color; - FDataList.Font := Font; - FDataList.RowCount := Column.DropDownRows; - FLookupSource.DataSet := LookupDataSet; - FDataList.KeyField := LookupKeyFields; - FDataList.ListField := LookupResultField; - FDataList.ListSource := FLookupSource; - FDataList.KeyValue := DataSet.FieldByName(KeyFields).Value; - end - else if ActiveList = WidePickListBox then - begin - WidePickListBox.Items.Assign(Column.WidePickList); - DropDownRows := Column.DropDownRows; - // this is needed as inherited doesn't know about our WidePickListBox - if (DropDownRows > 0) and (WidePickListBox.Items.Count >= DropDownRows) then - WidePickListBox.Height := DropDownRows * TAccessTntCustomListbox(WidePickListBox as TTntCustomListbox).ItemHeight + 4 - else - WidePickListBox.Height := WidePickListBox.Items.Count * TAccessTntCustomListbox(WidePickListBox as TTntCustomListbox).ItemHeight + 4; - if Text = '' then - WidePickListBox.ItemIndex := -1 - else - WidePickListBox.ItemIndex := WidePickListBox.Items.IndexOf(Text); - J := WidePickListBox.ClientWidth; - for I := 0 to WidePickListBox.Items.Count - 1 do - begin - Y := WideCanvasTextWidth(WidePickListBox.Canvas, WidePickListBox.Items[I]); - if Y > J then J := Y; - end; - WidePickListBox.ClientWidth := J; - end; - end; - inherited DropDown; -end; - -procedure TDBGridInplaceEdit{TNT-ALLOW TDBGridInplaceEdit}.UpdateContents; -var - Column: TTntColumn; -begin - inherited UpdateContents; - if EditStyle = esPickList then - ActiveList := WidePickListBox; - if FUseDataList then - begin - if FDataList = nil then - begin - FDataList := TTntPopupDataList.Create(Self); - FDataList.Visible := False; - FDataList.Parent := Self; - FDataList.OnMouseUp := ListMouseUp; - end; - ActiveList := FDataList; - end; - with (Grid as TTntCustomDBGrid) do - Column := Columns[SelectedIndex] as TTntColumn; - Self.ReadOnly := Column.ReadOnly; - Font.Assign(Column.Font); - ImeMode := Column.ImeMode; - ImeName := Column.ImeName; -end; - -//----------------------------------------------------------------------------------------- - -{ TTntDBGridInplaceEdit } - -procedure TTntDBGridInplaceEdit.CreateWindowHandle(const Params: TCreateParams); -begin - TntCustomEdit_CreateWindowHandle(Self, Params); -end; - -function TTntDBGridInplaceEdit.GetText: WideString; -begin - Result := TntControl_GetText(Self); -end; - -procedure TTntDBGridInplaceEdit.SetText(const Value: WideString); -begin - TntControl_SetText(Self, Value); -end; - -procedure TTntDBGridInplaceEdit.WMSetText(var Message: TWMSetText); -begin - if (not FBlockSetText) then - inherited; -end; - -procedure TTntDBGridInplaceEdit.UpdateContents; -var - Grid: TTntCustomDBGrid; -begin - Grid := Self.Grid as TTntCustomDBGrid; - EditMask := Grid.GetEditMask(Grid.Col, Grid.Row); - Text := Grid.GetEditText(Grid.Col, Grid.Row); - MaxLength := Grid.GetEditLimit; - - FBlockSetText := True; - try - inherited; - finally - FBlockSetText := False; - end; -end; - -procedure TTntDBGridInplaceEdit.DblClick; -begin - FInDblClick := True; - try - inherited; - finally - FInDblClick := False; - end; -end; - -{ TTntGridDataLink } - -procedure TTntGridDataLink.GridUpdateFieldText(Sender: TField; const Text: AnsiString); -begin - Sender.OnSetText := OriginalSetText; - if Assigned(Sender) then - SetWideText(Sender, (Grid as TTntCustomDBGrid).FEditText); -end; - -procedure TTntGridDataLink.RecordChanged(Field: TField); -var - CField: TField; -begin - inherited; - if Grid.HandleAllocated then begin - CField := Grid.SelectedField; - if ((Field = nil) or (CField = Field)) and - (Assigned(CField) and (GetWideText(CField) <> (Grid as TTntCustomDBGrid).FEditText)) then - begin - with (Grid as TTntCustomDBGrid) do begin - InvalidateEditor; - if InplaceEditor <> nil then InplaceEditor.Deselect; - end; - end; - end; -end; - -procedure TTntGridDataLink.UpdateData; -var - Field: TField; -begin - Field := (Grid as TTntCustomDBGrid).SelectedField; - // remember "set text" - if Field <> nil then - OriginalSetText := Field.OnSetText; - try - // redirect "set text" to self - if Field <> nil then - Field.OnSetText := GridUpdateFieldText; - inherited; // clear modified ! - finally - // redirect "set text" to field - if Field <> nil then - Field.OnSetText := OriginalSetText; - // forget original "set text" - OriginalSetText := nil; - end; -end; - -{ TTntDBGridColumns } - -function TTntDBGridColumns.Add: TTntColumn; -begin - Result := inherited Add as TTntColumn; -end; - -function TTntDBGridColumns.GetColumn(Index: Integer): TTntColumn; -begin - Result := inherited Items[Index] as TTntColumn; -end; - -procedure TTntDBGridColumns.SetColumn(Index: Integer; const Value: TTntColumn); -begin - inherited Items[Index] := Value; -end; - -{ TTntCustomDBGrid } - -procedure TTntCustomDBGrid.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, ''); -end; - -type TAccessCustomGrid = class(TCustomGrid); - -procedure TTntCustomDBGrid.WMChar(var Msg: TWMChar); -begin - if (goEditing in TAccessCustomGrid(Self).Options) - and (AnsiChar(Msg.CharCode) in [^H, #32..#255]) then begin - RestoreWMCharMsg(TMessage(Msg)); - ShowEditorChar(WideChar(Msg.CharCode)); - end else - inherited; -end; - -procedure TTntCustomDBGrid.ShowEditorChar(Ch: WideChar); -begin - ShowEditor; - if InplaceEditor <> nil then begin - if Win32PlatformIsUnicode then - PostMessageW(InplaceEditor.Handle, WM_CHAR, Word(Ch), 0) - else - PostMessageA(InplaceEditor.Handle, WM_CHAR, Word(Ch), 0); - end; -end; - -procedure TTntCustomDBGrid.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntCustomDBGrid.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntCustomDBGrid.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntCustomDBGrid.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -function TTntCustomDBGrid.CreateColumns: TDBGridColumns{TNT-ALLOW TDBGridColumns}; -begin - Result := TTntDBGridColumns.Create(Self, TTntColumn); -end; - -function TTntCustomDBGrid.GetColumns: TTntDBGridColumns; -begin - Result := inherited Columns as TTntDBGridColumns; -end; - -procedure TTntCustomDBGrid.SetColumns(const Value: TTntDBGridColumns); -begin - inherited Columns := Value; -end; - -function TTntCustomDBGrid.CreateEditor: TInplaceEdit{TNT-ALLOW TInplaceEdit}; -begin - Result := TTntDBGridInplaceEdit.Create(Self); -end; - -function TTntCustomDBGrid.CreateDataLink: TGridDataLink; -begin - Result := TTntGridDataLink.Create(Self); -end; - -function TTntCustomDBGrid.GetEditText(ACol, ARow: Integer): WideString; -var - Field: TField; -begin - Field := GetColField(RawToDataColumn(ACol)); - if Field = nil then - Result := '' - else - Result := GetWideText(Field); - FEditText := Result; -end; - -procedure TTntCustomDBGrid.SetEditText(ACol, ARow: Integer; const Value: AnsiString); -begin - if (InplaceEditor as TTntDBGridInplaceEdit).FInDblClick then - FEditText := Value - else - FEditText := (InplaceEditor as TTntDBGridInplaceEdit).Text; - inherited; -end; - -//----------------- DRAW CELL PROCS -------------------------------------------------- -var - DrawBitmap: TBitmap = nil; - -procedure WriteText(ACanvas: TCanvas; ARect: TRect; DX, DY: Integer; - const Text: WideString; Alignment: TAlignment; ARightToLeft: Boolean); -const - AlignFlags : array [TAlignment] of Integer = - ( DT_LEFT or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX, - DT_RIGHT or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX, - DT_CENTER or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX ); - RTL: array [Boolean] of Integer = (0, DT_RTLREADING); -var - B, R: TRect; - Hold, Left: Integer; - I: TColorRef; -begin - I := ColorToRGB(ACanvas.Brush.Color); - if GetNearestColor(ACanvas.Handle, I) = I then - begin { Use ExtTextOutW for solid colors } - { In BiDi, because we changed the window origin, the text that does not - change alignment, actually gets its alignment changed. } - if (ACanvas.CanvasOrientation = coRightToLeft) and (not ARightToLeft) then - ChangeBiDiModeAlignment(Alignment); - case Alignment of - taLeftJustify: - Left := ARect.Left + DX; - taRightJustify: - Left := ARect.Right - WideCanvasTextWidth(ACanvas, Text) - 3; - else { taCenter } - Left := ARect.Left + (ARect.Right - ARect.Left) div 2 - - (WideCanvasTextWidth(ACanvas, Text) div 2); - end; - WideCanvasTextRect(ACanvas, ARect, Left, ARect.Top + DY, Text); - end - else begin { Use FillRect and Drawtext for dithered colors } - DrawBitmap.Canvas.Lock; - try - with DrawBitmap, ARect do { Use offscreen bitmap to eliminate flicker and } - begin { brush origin tics in painting / scrolling. } - Width := Max(Width, Right - Left); - Height := Max(Height, Bottom - Top); - R := Rect(DX, DY, Right - Left - 1, Bottom - Top - 1); - B := Rect(0, 0, Right - Left, Bottom - Top); - end; - with DrawBitmap.Canvas do - begin - Font := ACanvas.Font; - Font.Color := ACanvas.Font.Color; - Brush := ACanvas.Brush; - Brush.Style := bsSolid; - FillRect(B); - SetBkMode(Handle, TRANSPARENT); - if (ACanvas.CanvasOrientation = coRightToLeft) then - ChangeBiDiModeAlignment(Alignment); - Tnt_DrawTextW(Handle, PWideChar(Text), Length(Text), R, - AlignFlags[Alignment] or RTL[ARightToLeft]); - end; - if (ACanvas.CanvasOrientation = coRightToLeft) then - begin - Hold := ARect.Left; - ARect.Left := ARect.Right; - ARect.Right := Hold; - end; - ACanvas.CopyRect(ARect, DrawBitmap.Canvas, B); - finally - DrawBitmap.Canvas.Unlock; - end; - end; -end; - -procedure TTntCustomDBGrid.DefaultDrawDataCell(const Rect: TRect; Field: TField; - State: TGridDrawState); -var - Alignment: TAlignment; - Value: WideString; -begin - Alignment := taLeftJustify; - Value := ''; - if Assigned(Field) then - begin - Alignment := Field.Alignment; - Value := GetWideDisplayText(Field); - end; - WriteText(Canvas, Rect, 2, 2, Value, Alignment, - UseRightToLeftAlignmentForField(Field, Alignment)); -end; - -procedure TTntCustomDBGrid.DefaultDrawColumnCell(const Rect: TRect; - DataCol: Integer; Column: TTntColumn; State: TGridDrawState); -var - Value: WideString; -begin - Value := ''; - if Assigned(Column.Field) then - Value := GetWideDisplayText(Column.Field); - WriteText(Canvas, Rect, 2, 2, Value, Column.Alignment, - UseRightToLeftAlignmentForField(Column.Field, Column.Alignment)); -end; - -procedure TTntCustomDBGrid.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); -var - FrameOffs: Byte; - - procedure DrawTitleCell(ACol, ARow: Integer; Column: TTntColumn; var AState: TGridDrawState); - const - ScrollArrows: array [Boolean, Boolean] of Integer = - ((DFCS_SCROLLRIGHT, DFCS_SCROLLLEFT), (DFCS_SCROLLLEFT, DFCS_SCROLLRIGHT)); - var - MasterCol: TColumn{TNT-ALLOW TColumn}; - TitleRect, TxtRect, ButtonRect: TRect; - I: Integer; - InBiDiMode: Boolean; - begin - TitleRect := CalcTitleRect(Column, ARow, MasterCol); - - if MasterCol = nil then - begin - Canvas.FillRect(ARect); - Exit; - end; - - Canvas.Font := MasterCol.Title.Font; - Canvas.Brush.Color := MasterCol.Title.Color; - if [dgRowLines, dgColLines] * Options = [dgRowLines, dgColLines] then - InflateRect(TitleRect, -1, -1); - TxtRect := TitleRect; - I := GetSystemMetrics(SM_CXHSCROLL); - if ((TxtRect.Right - TxtRect.Left) > I) and MasterCol.Expandable then - begin - Dec(TxtRect.Right, I); - ButtonRect := TitleRect; - ButtonRect.Left := TxtRect.Right; - I := SaveDC(Canvas.Handle); - try - Canvas.FillRect(ButtonRect); - InflateRect(ButtonRect, -1, -1); - IntersectClipRect(Canvas.Handle, ButtonRect.Left, - ButtonRect.Top, ButtonRect.Right, ButtonRect.Bottom); - InflateRect(ButtonRect, 1, 1); - { DrawFrameControl doesn't draw properly when orienatation has changed. - It draws as ExtTextOutW does. } - InBiDiMode := Canvas.CanvasOrientation = coRightToLeft; - if InBiDiMode then { stretch the arrows box } - Inc(ButtonRect.Right, GetSystemMetrics(SM_CXHSCROLL) + 4); - DrawFrameControl(Canvas.Handle, ButtonRect, DFC_SCROLL, - ScrollArrows[InBiDiMode, MasterCol.Expanded] or DFCS_FLAT); - finally - RestoreDC(Canvas.Handle, I); - end; - end; - with (MasterCol.Title as TTntColumnTitle) do - WriteText(Canvas, TxtRect, FrameOffs, FrameOffs, Caption, Alignment, IsRightToLeft); - if [dgRowLines, dgColLines] * Options = [dgRowLines, dgColLines] then - begin - InflateRect(TitleRect, 1, 1); - DrawEdge(Canvas.Handle, TitleRect, BDR_RAISEDINNER, BF_BOTTOMRIGHT); - DrawEdge(Canvas.Handle, TitleRect, BDR_RAISEDINNER, BF_TOPLEFT); - end; - AState := AState - [gdFixed]; // prevent box drawing later - end; - -var - OldActive: Integer; - Highlight: Boolean; - Value: WideString; - DrawColumn: TTntColumn; -begin - if csLoading in ComponentState then - begin - Canvas.Brush.Color := Color; - Canvas.FillRect(ARect); - Exit; - end; - - if (gdFixed in AState) and (RawToDataColumn(ACol) < 0) then - begin - inherited; - exit; - end; - - Dec(ARow, FixedRows); - ACol := RawToDataColumn(ACol); - - if (gdFixed in AState) and ([dgRowLines, dgColLines] * Options = - [dgRowLines, dgColLines]) then - begin - InflateRect(ARect, -1, -1); - FrameOffs := 1; - end - else - FrameOffs := 2; - - with Canvas do - begin - DrawColumn := Columns[ACol] as TTntColumn; - if not DrawColumn.Showing then Exit; - if not (gdFixed in AState) then - begin - Font := DrawColumn.Font; - Brush.Color := DrawColumn.Color; - end; - if ARow < 0 then - DrawTitleCell(ACol, ARow + FixedRows, DrawColumn, AState) - else if (DataLink = nil) or not DataLink.Active then - FillRect(ARect) - else - begin - Value := ''; - OldActive := DataLink.ActiveRecord; - try - DataLink.ActiveRecord := ARow; - if Assigned(DrawColumn.Field) then - Value := GetWideDisplayText(DrawColumn.Field); - Highlight := HighlightCell(ACol, ARow, Value, AState); - if Highlight then - begin - Brush.Color := clHighlight; - Font.Color := clHighlightText; - end; - if not Enabled then - Font.Color := clGrayText; - if DefaultDrawing then - DefaultDrawColumnCell(ARect, ACol, DrawColumn, AState); - if Columns.State = csDefault then - DrawDataCell(ARect, DrawColumn.Field, AState); - DrawColumnCell(ARect, ACol, DrawColumn, AState); - finally - DataLink.ActiveRecord := OldActive; - end; - if DefaultDrawing and (gdSelected in AState) - and ((dgAlwaysShowSelection in Options) or Focused) - and not (csDesigning in ComponentState) - and not (dgRowSelect in Options) - and (UpdateLock = 0) - and (ValidParentForm(Self).ActiveControl = Self) then - Windows.DrawFocusRect(Handle, ARect); - end; - end; - if (gdFixed in AState) and ([dgRowLines, dgColLines] * Options = - [dgRowLines, dgColLines]) then - begin - InflateRect(ARect, 1, 1); - DrawEdge(Canvas.Handle, ARect, BDR_RAISEDINNER, BF_BOTTOMRIGHT); - DrawEdge(Canvas.Handle, ARect, BDR_RAISEDINNER, BF_TOPLEFT); - end; -end; - -procedure TTntCustomDBGrid.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomDBGrid.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -initialization - DrawBitmap := TBitmap.Create; - -finalization - DrawBitmap.Free; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBLogDlg.dfm b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBLogDlg.dfm deleted file mode 100644 index a9b5fdc37..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBLogDlg.dfm +++ /dev/null @@ -1,108 +0,0 @@ -object TntLoginDialog: TTntLoginDialog - Left = 307 - Top = 131 - ActiveControl = Password - BorderStyle = bsDialog - Caption = 'Database Login' - ClientHeight = 147 - ClientWidth = 273 - Color = clBtnFace - ParentFont = True - - Position = poScreenCenter - OnShow = FormShow - PixelsPerInch = 96 - TextHeight = 13 - object OKButton: TTntButton - Left = 109 - Top = 114 - Width = 75 - Height = 25 - Caption = '&OK' - Default = True - ModalResult = 1 - TabOrder = 0 - end - object CancelButton: TTntButton - Left = 190 - Top = 114 - Width = 75 - Height = 25 - Cancel = True - Caption = 'Cancel' - ModalResult = 2 - TabOrder = 1 - end - object Panel: TTntPanel - Left = 8 - Top = 7 - Width = 257 - Height = 98 - BevelInner = bvRaised - BevelOuter = bvLowered - TabOrder = 2 - object Label3: TTntLabel - Left = 10 - Top = 6 - Width = 50 - Height = 13 - Caption = 'Database:' - end - object DatabaseName: TTntLabel - Left = 91 - Top = 6 - Width = 3 - Height = 13 - end - object Bevel: TTntBevel - Left = 1 - Top = 24 - Width = 254 - Height = 9 - Shape = bsTopLine - end - object Panel1: TTntPanel - Left = 2 - Top = 31 - Width = 253 - Height = 65 - Align = alBottom - BevelOuter = bvNone - TabOrder = 0 - object Label1: TTntLabel - Left = 8 - Top = 8 - Width = 56 - Height = 13 - Caption = '&User Name:' - FocusControl = UserName - end - object Label2: TTntLabel - Left = 8 - Top = 36 - Width = 50 - Height = 13 - Caption = '&Password:' - FocusControl = Password - end - object UserName: TTntEdit - Left = 86 - Top = 5 - Width = 153 - Height = 21 - MaxLength = 31 - TabOrder = 0 - end - object Password: TTntEdit - Left = 86 - Top = 33 - Width = 153 - Height = 21 - MaxLength = 31 - PasswordCharW = #9679 - TabOrder = 1 - PasswordChar_UTF7 = '+Jc8' - end - end - end -end diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBLogDlg.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBLogDlg.pas deleted file mode 100644 index 0be1cb8fd..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDBLogDlg.pas +++ /dev/null @@ -1,133 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntDBLogDlg; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - SysUtils, Windows, Messages, Classes, Graphics, - TntForms, TntStdCtrls, TntExtCtrls, StdCtrls, ExtCtrls, Controls; - -type - TTntLoginDialog = class(TTntForm) - Panel: TTntPanel; - Bevel: TTntBevel; - DatabaseName: TTntLabel; - OKButton: TTntButton; - CancelButton: TTntButton; - Panel1: TTntPanel; - Label1: TTntLabel; - Label2: TTntLabel; - Label3: TTntLabel; - Password: TTntEdit; - UserName: TTntEdit; - procedure FormShow(Sender: TObject); - end; - -{TNT-WARN LoginDialog} -function TntLoginDialog(const ADatabaseName: WideString; - var AUserName, APassword: WideString): Boolean; - -{TNT-WARN LoginDialogEx} -function TntLoginDialogEx(const ADatabaseName: WideString; - var AUserName, APassword: WideString; NameReadOnly: Boolean): Boolean; - -{TNT-WARN RemoteLoginDialog} -function TntRemoteLoginDialog(var AUserName, APassword: WideString): Boolean; - -implementation - -{$R *.dfm} - -uses - Forms, VDBConsts; - -function TntLoginDialog(const ADatabaseName: WideString; - var AUserName, APassword: WideString): Boolean; -begin - with TTntLoginDialog.Create(Application) do - try - DatabaseName.Caption := ADatabaseName; - UserName.Text := AUserName; - Result := False; - if AUserName = '' then ActiveControl := UserName; - if ShowModal = mrOk then - begin - AUserName := UserName.Text; - APassword := Password.Text; - Result := True; - end; - finally - Free; - end; -end; - -function TntLoginDialogEx(const ADatabaseName: WideString; - var AUserName, APassword: WideString; NameReadOnly: Boolean): Boolean; -begin - with TTntLoginDialog.Create(Application) do - try - DatabaseName.Caption := ADatabaseName; - UserName.Text := AUserName; - Result := False; - if NameReadOnly then - UserName.Enabled := False - else - if AUserName = '' then ActiveControl := UserName; - if ShowModal = mrOk then - begin - AUserName := UserName.Text; - APassword := Password.Text; - Result := True; - end; - finally - Free; - end; -end; - -function TntRemoteLoginDialog(var AUserName, APassword: WideString): Boolean; -begin - with TTntLoginDialog.Create(Application) do - try - Caption := SRemoteLogin; - Bevel.Visible := False; - DatabaseName.Visible := False; - Label3.Visible := False; - Panel.Height := Panel.Height - Bevel.Top; - OKButton.Top := OKButton.Top - Bevel.Top; - CancelButton.Top := CancelButton.Top - Bevel.Top; - Height := Height - Bevel.Top; - UserName.Text := AUserName; - Result := False; - if AUserName = '' then ActiveControl := UserName; - if ShowModal = mrOk then - begin - AUserName := UserName.Text; - APassword := Password.Text; - Result := True; - end; - finally - Free; - end; -end; - -{ TTntLoginDialog } - -procedure TTntLoginDialog.FormShow(Sender: TObject); -begin - if (DatabaseName.Width + DatabaseName.Left) >= Panel.ClientWidth then - DatabaseName.Width := (Panel.ClientWidth - DatabaseName.Left) - 5; -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDialogs.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDialogs.pas deleted file mode 100644 index 6285c2ff6..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntDialogs.pas +++ /dev/null @@ -1,981 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntDialogs; - -{$INCLUDE TntCompilers.inc} - -interface - -{ TODO: TFindDialog and TReplaceDialog. } -{ TODO: Property editor for TTntOpenDialog.Filter } - -uses - Classes, Messages, CommDlg, Windows, Dialogs, - TntClasses, TntForms, TntSysUtils; - -type -{TNT-WARN TIncludeItemEvent} - TIncludeItemEventW = procedure (const OFN: TOFNotifyExW; var Include: Boolean) of object; - -{TNT-WARN TOpenDialog} - TTntOpenDialog = class(TOpenDialog{TNT-ALLOW TOpenDialog}) - private - FDefaultExt: WideString; - FFileName: TWideFileName; - FFilter: WideString; - FInitialDir: WideString; - FTitle: WideString; - FFiles: TTntStrings; - FOnIncludeItem: TIncludeItemEventW; - function GetDefaultExt: WideString; - procedure SetInheritedDefaultExt(const Value: AnsiString); - procedure SetDefaultExt(const Value: WideString); - function GetFileName: TWideFileName; - procedure SetFileName(const Value: TWideFileName); - function GetFilter: WideString; - procedure SetInheritedFilter(const Value: AnsiString); - procedure SetFilter(const Value: WideString); - function GetInitialDir: WideString; - procedure SetInheritedInitialDir(const Value: AnsiString); - procedure SetInitialDir(const Value: WideString); - function GetTitle: WideString; - procedure SetInheritedTitle(const Value: AnsiString); - procedure SetTitle(const Value: WideString); - function GetFiles: TTntStrings; - private - FProxiedOpenFilenameA: TOpenFilenameA; - protected - FAllowDoCanClose: Boolean; - procedure DefineProperties(Filer: TFiler); override; - function CanCloseW(var OpenFileName: TOpenFileNameW): Boolean; - function DoCanClose: Boolean; override; - procedure GetFileNamesW(var OpenFileName: TOpenFileNameW); - procedure DoIncludeItem(const OFN: TOFNotifyEx; var Include: Boolean); override; - procedure WndProc(var Message: TMessage); override; - function DoExecuteW(Func: Pointer; ParentWnd: HWND): Bool; overload; - function DoExecuteW(Func: Pointer): Bool; overload; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - function Execute: Boolean; override; - {$IFDEF COMPILER_9_UP} - function Execute(ParentWnd: HWND): Boolean; override; - {$ENDIF} - property Files: TTntStrings read GetFiles; - published - property DefaultExt: WideString read GetDefaultExt write SetDefaultExt; - property FileName: TWideFileName read GetFileName write SetFileName; - property Filter: WideString read GetFilter write SetFilter; - property InitialDir: WideString read GetInitialDir write SetInitialDir; - property Title: WideString read GetTitle write SetTitle; - property OnIncludeItem: TIncludeItemEventW read FOnIncludeItem write FOnIncludeItem; - end; - -{TNT-WARN TSaveDialog} - TTntSaveDialog = class(TTntOpenDialog) - public - function Execute: Boolean; override; - {$IFDEF COMPILER_9_UP} - function Execute(ParentWnd: HWND): Boolean; override; - {$ENDIF} - end; - -{ Message dialog } - -{TNT-WARN CreateMessageDialog} -function WideCreateMessageDialog(const Msg: WideString; DlgType: TMsgDlgType; - Buttons: TMsgDlgButtons): TTntForm;overload; -function WideCreateMessageDialog(const Msg: WideString; DlgType: TMsgDlgType; - Buttons: TMsgDlgButtons; DefaultButton: TMsgDlgBtn): TTntForm; overload; - -{TNT-WARN MessageDlg} -function WideMessageDlg(const Msg: WideString; DlgType: TMsgDlgType; - Buttons: TMsgDlgButtons; HelpCtx: Longint): Integer; overload; -function WideMessageDlg(const Msg: WideString; DlgType: TMsgDlgType; - Buttons: TMsgDlgButtons; HelpCtx: Longint; DefaultButton: TMsgDlgBtn): Integer; overload; - -{TNT-WARN MessageDlgPos} -function WideMessageDlgPos(const Msg: WideString; DlgType: TMsgDlgType; - Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer): Integer; overload; -function WideMessageDlgPos(const Msg: WideString; DlgType: TMsgDlgType; - Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer; DefaultButton: TMsgDlgBtn): Integer; overload; - -{TNT-WARN MessageDlgPosHelp} -function WideMessageDlgPosHelp(const Msg: WideString; DlgType: TMsgDlgType; - Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer; - const HelpFileName: WideString): Integer; overload; -function WideMessageDlgPosHelp(const Msg: WideString; DlgType: TMsgDlgType; - Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer; - const HelpFileName: WideString; DefaultButton: TMsgDlgBtn): Integer; overload; - -{TNT-WARN ShowMessage} -procedure WideShowMessage(const Msg: WideString); -{TNT-WARN ShowMessageFmt} -procedure WideShowMessageFmt(const Msg: WideString; Params: array of const); -{TNT-WARN ShowMessagePos} -procedure WideShowMessagePos(const Msg: WideString; X, Y: Integer); - -{ Input dialog } - -{TNT-WARN InputQuery} -function WideInputQuery(const ACaption, APrompt: WideString; - var Value: WideString): Boolean; -{TNT-WARN InputBox} -function WideInputBox(const ACaption, APrompt, ADefault: WideString): WideString; - -{TNT-WARN PromptForFileName} -function WidePromptForFileName(var AFileName: WideString; const AFilter: WideString = ''; - const ADefaultExt: WideString = ''; const ATitle: WideString = ''; - const AInitialDir: WideString = ''; SaveDialog: Boolean = False): Boolean; - -function GetModalParentWnd: HWND; - -implementation - -uses - Controls, Forms, Types, SysUtils, Graphics, Consts, Math, - TntWindows, TntStdCtrls, TntClipBrd, TntExtCtrls, - {$IFDEF COMPILER_9_UP} WideStrUtils, {$ENDIF} TntWideStrUtils; - -function GetModalParentWnd: HWND; -begin - {$IFDEF COMPILER_9} - Result := Application.ActiveFormHandle; - {$ELSE} - Result := 0; - {$ENDIF} - {$IFDEF COMPILER_10_UP} - if Application.ModalPopupMode <> pmNone then - begin - Result := Application.ActiveFormHandle; - end; - {$ENDIF} - if Result = 0 then begin - Result := Application.Handle; - end; -end; - -var - ProxyExecuteDialog: TTntOpenDialog; - -function ProxyGetOpenFileNameA(var OpenFile: TOpenFilename): Bool; stdcall; -begin - ProxyExecuteDialog.FProxiedOpenFilenameA := OpenFile; - Result := False; { as if user hit "Cancel". } -end; - -{ TTntOpenDialog } - -constructor TTntOpenDialog.Create(AOwner: TComponent); -begin - inherited; - FFiles := TTntStringList.Create; -end; - -destructor TTntOpenDialog.Destroy; -begin - FreeAndNil(FFiles); - inherited; -end; - -procedure TTntOpenDialog.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntOpenDialog.GetDefaultExt: WideString; -begin - Result := GetSyncedWideString(FDefaultExt, inherited DefaultExt); -end; - -procedure TTntOpenDialog.SetInheritedDefaultExt(const Value: AnsiString); -begin - inherited DefaultExt := Value; -end; - -procedure TTntOpenDialog.SetDefaultExt(const Value: WideString); -begin - SetSyncedWideString(Value, FDefaultExt, inherited DefaultExt, SetInheritedDefaultExt); -end; - -function TTntOpenDialog.GetFileName: TWideFileName; -var - Path: array[0..MAX_PATH] of WideChar; -begin - if Win32PlatformIsUnicode and NewStyleControls and (Handle <> 0) then begin - // get filename from handle - SendMessageW(GetParent(Handle), CDM_GETFILEPATH, SizeOf(Path), Integer(@Path)); - Result := Path; - end else - Result := GetSyncedWideString(WideString(FFileName), inherited FileName); -end; - -procedure TTntOpenDialog.SetFileName(const Value: TWideFileName); -begin - FFileName := Value; - inherited FileName := Value; -end; - -function TTntOpenDialog.GetFilter: WideString; -begin - Result := GetSyncedWideString(FFilter, inherited Filter); -end; - -procedure TTntOpenDialog.SetInheritedFilter(const Value: AnsiString); -begin - inherited Filter := Value; -end; - -procedure TTntOpenDialog.SetFilter(const Value: WideString); -begin - SetSyncedWideString(Value, FFilter, inherited Filter, SetInheritedFilter); -end; - -function TTntOpenDialog.GetInitialDir: WideString; -begin - Result := GetSyncedWideString(FInitialDir, inherited InitialDir); -end; - -procedure TTntOpenDialog.SetInheritedInitialDir(const Value: AnsiString); -begin - inherited InitialDir := Value; -end; - -procedure TTntOpenDialog.SetInitialDir(const Value: WideString); - - function RemoveTrailingPathDelimiter(const Value: WideString): WideString; - var - L: Integer; - begin - // remove trailing path delimiter (except 'C:\') - L := Length(Value); - if (L > 1) and WideIsPathDelimiter(Value, L) and not WideIsDelimiter(':', Value, L - 1) then - Dec(L); - Result := Copy(Value, 1, L); - end; - -begin - SetSyncedWideString(RemoveTrailingPathDelimiter(Value), FInitialDir, - inherited InitialDir, SetInheritedInitialDir); -end; - -function TTntOpenDialog.GetTitle: WideString; -begin - Result := GetSyncedWideString(FTitle, inherited Title) -end; - -procedure TTntOpenDialog.SetInheritedTitle(const Value: AnsiString); -begin - inherited Title := Value; -end; - -procedure TTntOpenDialog.SetTitle(const Value: WideString); -begin - SetSyncedWideString(Value, FTitle, inherited Title, SetInheritedTitle); -end; - -function TTntOpenDialog.GetFiles: TTntStrings; -begin - if (not Win32PlatformIsUnicode) then - FFiles.Assign(inherited Files); - Result := FFiles; -end; - -function TTntOpenDialog.DoCanClose: Boolean; -begin - if FAllowDoCanClose then - Result := inherited DoCanClose - else - Result := True; -end; - -function TTntOpenDialog.CanCloseW(var OpenFileName: TOpenFileNameW): Boolean; -begin - GetFileNamesW(OpenFileName); - FAllowDoCanClose := True; - try - Result := DoCanClose; - finally - FAllowDoCanClose := False; - end; - FFiles.Clear; - inherited Files.Clear; -end; - -procedure TTntOpenDialog.DoIncludeItem(const OFN: TOFNotifyEx; var Include: Boolean); -begin - // CDN_INCLUDEITEM -> DoIncludeItem() is only be available on Windows 2000 + - // Therefore, just cast OFN as a TOFNotifyExW, since that's what it really is. - if Win32PlatformIsUnicode and Assigned(FOnIncludeItem) then - FOnIncludeItem(TOFNotifyExW(OFN), Include) -end; - -procedure TTntOpenDialog.WndProc(var Message: TMessage); -begin - Message.Result := 0; - if (Message.Msg = WM_INITDIALOG) and not (ofOldStyleDialog in Options) then begin - { If not ofOldStyleDialog then DoShow on CDN_INITDONE, not WM_INITDIALOG } - Exit; - end; - if Win32PlatformIsUnicode - and (Message.Msg = WM_NOTIFY) then begin - case (POFNotify(Message.LParam)^.hdr.code) of - CDN_FILEOK: - if not CanCloseW(POFNotifyW(Message.LParam)^.lpOFN^) then - begin - Message.Result := 1; - SetWindowLong(Handle, DWL_MSGRESULT, Message.Result); - Exit; - end; - end; - end; - inherited WndProc(Message); -end; - -function TTntOpenDialog.DoExecuteW(Func: Pointer): Bool; -begin - Result := DoExecuteW(Func, GetModalParentWnd); -end; - -function TTntOpenDialog.DoExecuteW(Func: Pointer; ParentWnd: HWND): Bool; -var - OpenFilename: TOpenFilenameW; - - function GetResNamePtr(var ScopedStringStorage: WideString; lpszName: PAnsiChar): PWideChar; - // duplicated from TntTrxResourceUtils.pas - begin - if Tnt_Is_IntResource(PWideChar(lpszName)) then - Result := PWideChar(lpszName) - else begin - ScopedStringStorage := lpszName; - Result := PWideChar(ScopedStringStorage); - end; - end; - - function AllocFilterStr(const S: WideString): WideString; - var - P: PWideChar; - begin - Result := ''; - if S <> '' then - begin - Result := S + #0#0; // double null terminators (an additional zero added in case Description/Filter pair not even.) - P := WStrScan(PWideChar(Result), '|'); - while P <> nil do - begin - P^ := #0; - Inc(P); - P := WStrScan(P, '|'); - end; - end; - end; - -var - TempTemplate, TempFilter, TempFilename, TempExt: WideString; -begin - FFiles.Clear; - - // 1. Init inherited dialog defaults. - // 2. Populate OpenFileName record with ansi defaults - ProxyExecuteDialog := Self; - try - DoExecute(@ProxyGetOpenFileNameA); - finally - ProxyExecuteDialog := nil; - end; - OpenFileName := TOpenFilenameW(FProxiedOpenFilenameA); - - with OpenFilename do - begin - if not IsWindow(hWndOwner) then begin - hWndOwner := ParentWnd; - end; - // Filter (PChar -> PWideChar) - TempFilter := AllocFilterStr(Filter); - lpstrFilter := PWideChar(TempFilter); - // FileName (PChar -> PWideChar) - SetLength(TempFilename, nMaxFile + 2); - lpstrFile := PWideChar(TempFilename); - FillChar(lpstrFile^, (nMaxFile + 2) * SizeOf(WideChar), 0); - WStrLCopy(lpstrFile, PWideChar(FileName), nMaxFile); - // InitialDir (PChar -> PWideChar) - if (InitialDir = '') and ForceCurrentDirectory then - lpstrInitialDir := '.' - else - lpstrInitialDir := PWideChar(InitialDir); - // Title (PChar -> PWideChar) - lpstrTitle := PWideChar(Title); - // DefaultExt (PChar -> PWideChar) - TempExt := DefaultExt; - if (TempExt = '') and (Flags and OFN_EXPLORER = 0) then - begin - TempExt := WideExtractFileExt(Filename); - Delete(TempExt, 1, 1); - end; - if TempExt <> '' then - lpstrDefExt := PWideChar(TempExt); - // resource template (PChar -> PWideChar) - lpTemplateName := GetResNamePtr(TempTemplate, Template); - // start modal dialog - Result := TaskModalDialog(Func, OpenFileName); - if Result then - begin - GetFileNamesW(OpenFilename); - if (Flags and OFN_EXTENSIONDIFFERENT) <> 0 then - Options := Options + [ofExtensionDifferent] - else - Options := Options - [ofExtensionDifferent]; - if (Flags and OFN_READONLY) <> 0 then - Options := Options + [ofReadOnly] - else - Options := Options - [ofReadOnly]; - FilterIndex := nFilterIndex; - end; - end; -end; - -procedure TTntOpenDialog.GetFileNamesW(var OpenFileName: TOpenFileNameW); -var - Separator: WideChar; - - procedure ExtractFileNamesW(P: PWideChar); - var - DirName, FileName: TWideFileName; - FileList: TWideStringDynArray; - i: integer; - begin - FileList := ExtractStringsFromStringArray(P, Separator); - if Length(FileList) = 0 then - FFiles.Add('') - else begin - DirName := FileList[0]; - if Length(FileList) = 1 then - FFiles.Add(DirName) - else begin - // prepare DirName - if WideLastChar(DirName) <> WideString(PathDelim) then - DirName := DirName + PathDelim; - // add files - for i := 1 {second item} to High(FileList) do begin - FileName := FileList[i]; - // prepare FileName - if (FileName[1] <> PathDelim) - and ((Length(FileName) <= 3) or (FileName[2] <> DriveDelim) or (FileName[3] <> PathDelim)) - then - FileName := DirName + FileName; - // add to list - FFiles.Add(FileName); - end; - end; - end; - end; - -var - P: PWideChar; -begin - Separator := #0; - if (ofAllowMultiSelect in Options) and - ((ofOldStyleDialog in Options) or not NewStyleControls) then - Separator := ' '; - with OpenFileName do - begin - if ofAllowMultiSelect in Options then - begin - ExtractFileNamesW(lpstrFile); - FileName := FFiles[0]; - end else - begin - P := lpstrFile; - FileName := ExtractStringFromStringArray(P, Separator); - FFiles.Add(FileName); - end; - end; - - // Sync inherited Files - inherited Files.Assign(FFiles); -end; - -function TTntOpenDialog.Execute: Boolean; -begin - if (not Win32PlatformIsUnicode) then - Result := DoExecute(@GetOpenFileNameA) - else - Result := DoExecuteW(@GetOpenFileNameW); -end; - -{$IFDEF COMPILER_9_UP} -function TTntOpenDialog.Execute(ParentWnd: HWND): Boolean; -begin - if (not Win32PlatformIsUnicode) then - Result := DoExecute(@GetOpenFileNameA, ParentWnd) - else - Result := DoExecuteW(@GetOpenFileNameW, ParentWnd); -end; -{$ENDIF} - -{ TTntSaveDialog } - -function TTntSaveDialog.Execute: Boolean; -begin - if (not Win32PlatformIsUnicode) then - Result := DoExecute(@GetSaveFileNameA) - else - Result := DoExecuteW(@GetSaveFileNameW); -end; - -{$IFDEF COMPILER_9_UP} -function TTntSaveDialog.Execute(ParentWnd: HWND): Boolean; -begin - if (not Win32PlatformIsUnicode) then - Result := DoExecute(@GetSaveFileNameA, ParentWnd) - else - Result := DoExecuteW(@GetSaveFileNameW, ParentWnd); -end; -{$ENDIF} - -{ Message dialog } - -function GetAveCharSize(Canvas: TCanvas): TPoint; -var - I: Integer; - Buffer: array[0..51] of WideChar; - tm: TTextMetric; -begin - for I := 0 to 25 do Buffer[I] := WideChar(I + Ord('A')); - for I := 0 to 25 do Buffer[I + 26] := WideChar(I + Ord('a')); - GetTextMetrics(Canvas.Handle, tm); - GetTextExtentPointW(Canvas.Handle, Buffer, 52, TSize(Result)); - Result.X := (Result.X div 26 + 1) div 2; - Result.Y := tm.tmHeight; -end; - -type - TTntMessageForm = class(TTntForm) - private - Message: TTntLabel; - procedure HelpButtonClick(Sender: TObject); - protected - procedure CustomKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); - function GetFormText: WideString; - public - constructor CreateNew(AOwner: TComponent); reintroduce; - end; - -constructor TTntMessageForm.CreateNew(AOwner: TComponent); -var - NonClientMetrics: TNonClientMetrics; -begin - inherited CreateNew(AOwner); - NonClientMetrics.cbSize := sizeof(NonClientMetrics); - if SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @NonClientMetrics, 0) then - Font.Handle := CreateFontIndirect(NonClientMetrics.lfMessageFont); -end; - -procedure TTntMessageForm.HelpButtonClick(Sender: TObject); -begin - Application.HelpContext(HelpContext); -end; - -procedure TTntMessageForm.CustomKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); -begin - if (Shift = [ssCtrl]) and (Key = Word('C')) then - begin - Beep; - TntClipboard.AsWideText := GetFormText; - end; -end; - -function TTntMessageForm.GetFormText: WideString; -var - DividerLine, ButtonCaptions: WideString; - I: integer; -begin - DividerLine := StringOfChar('-', 27) + sLineBreak; - for I := 0 to ComponentCount - 1 do - if Components[I] is TTntButton then - ButtonCaptions := ButtonCaptions + TTntButton(Components[I]).Caption + - StringOfChar(' ', 3); - ButtonCaptions := Tnt_WideStringReplace(ButtonCaptions,'&','', [rfReplaceAll]); - Result := DividerLine + Caption + sLineBreak + DividerLine + Message.Caption + sLineBreak - + DividerLine + ButtonCaptions + sLineBreak + DividerLine; -end; - -function GetMessageCaption(MsgType: TMsgDlgType): WideString; -begin - case MsgType of - mtWarning: Result := SMsgDlgWarning; - mtError: Result := SMsgDlgError; - mtInformation: Result := SMsgDlgInformation; - mtConfirmation: Result := SMsgDlgConfirm; - mtCustom: Result := ''; - else - raise ETntInternalError.Create('Unexpected MsgType in GetMessageCaption.'); - end; -end; - -function GetButtonCaption(MsgDlgBtn: TMsgDlgBtn): WideString; -begin - case MsgDlgBtn of - mbYes: Result := SMsgDlgYes; - mbNo: Result := SMsgDlgNo; - mbOK: Result := SMsgDlgOK; - mbCancel: Result := SMsgDlgCancel; - mbAbort: Result := SMsgDlgAbort; - mbRetry: Result := SMsgDlgRetry; - mbIgnore: Result := SMsgDlgIgnore; - mbAll: Result := SMsgDlgAll; - mbNoToAll: Result := SMsgDlgNoToAll; - mbYesToAll: Result := SMsgDlgYesToAll; - mbHelp: Result := SMsgDlgHelp; - else - raise ETntInternalError.Create('Unexpected MsgDlgBtn in GetButtonCaption.'); - end; -end; - -var - IconIDs: array[TMsgDlgType] of PAnsiChar = (IDI_EXCLAMATION, IDI_HAND, - IDI_ASTERISK, IDI_QUESTION, nil); - ButtonNames: array[TMsgDlgBtn] of WideString = ( - 'Yes', 'No', 'OK', 'Cancel', 'Abort', 'Retry', 'Ignore', 'All', 'NoToAll', - 'YesToAll', 'Help'); - ModalResults: array[TMsgDlgBtn] of Integer = ( - mrYes, mrNo, mrOk, mrCancel, mrAbort, mrRetry, mrIgnore, mrAll, mrNoToAll, - mrYesToAll, 0); - -function WideCreateMessageDialog(const Msg: WideString; DlgType: TMsgDlgType; - Buttons: TMsgDlgButtons; DefaultButton: TMsgDlgBtn): TTntForm; -const - mcHorzMargin = 8; - mcVertMargin = 8; - mcHorzSpacing = 10; - mcVertSpacing = 10; - mcButtonWidth = 50; - mcButtonHeight = 14; - mcButtonSpacing = 4; -var - DialogUnits: TPoint; - HorzMargin, VertMargin, HorzSpacing, VertSpacing, ButtonWidth, - ButtonHeight, ButtonSpacing, ButtonCount, ButtonGroupWidth, - IconTextWidth, IconTextHeight, X, ALeft: Integer; - B, CancelButton: TMsgDlgBtn; - IconID: PAnsiChar; - ATextRect: TRect; - ThisButtonWidth: integer; - LButton: TTntButton; -begin - Result := TTntMessageForm.CreateNew(Application); - with Result do - begin - BorderStyle := bsDialog; // By doing this first, it will work on WINE. - BiDiMode := Application.BiDiMode; - Canvas.Font := Font; - KeyPreview := True; - Position := poDesigned; - OnKeyDown := TTntMessageForm(Result).CustomKeyDown; - DialogUnits := GetAveCharSize(Canvas); - HorzMargin := MulDiv(mcHorzMargin, DialogUnits.X, 4); - VertMargin := MulDiv(mcVertMargin, DialogUnits.Y, 8); - HorzSpacing := MulDiv(mcHorzSpacing, DialogUnits.X, 4); - VertSpacing := MulDiv(mcVertSpacing, DialogUnits.Y, 8); - ButtonWidth := MulDiv(mcButtonWidth, DialogUnits.X, 4); - for B := Low(TMsgDlgBtn) to High(TMsgDlgBtn) do - begin - if B in Buttons then - begin - ATextRect := Rect(0,0,0,0); - Tnt_DrawTextW(Canvas.Handle, - PWideChar(GetButtonCaption(B)), -1, - ATextRect, DT_CALCRECT or DT_LEFT or DT_SINGLELINE or - DrawTextBiDiModeFlagsReadingOnly); - with ATextRect do ThisButtonWidth := Right - Left + 8; - if ThisButtonWidth > ButtonWidth then - ButtonWidth := ThisButtonWidth; - end; - end; - ButtonHeight := MulDiv(mcButtonHeight, DialogUnits.Y, 8); - ButtonSpacing := MulDiv(mcButtonSpacing, DialogUnits.X, 4); - SetRect(ATextRect, 0, 0, Screen.Width div 2, 0); - Tnt_DrawTextW(Canvas.Handle, PWideChar(Msg), Length(Msg) + 1, ATextRect, - DT_EXPANDTABS or DT_CALCRECT or DT_WORDBREAK or - DrawTextBiDiModeFlagsReadingOnly); - IconID := IconIDs[DlgType]; - IconTextWidth := ATextRect.Right; - IconTextHeight := ATextRect.Bottom; - if IconID <> nil then - begin - Inc(IconTextWidth, 32 + HorzSpacing); - if IconTextHeight < 32 then IconTextHeight := 32; - end; - ButtonCount := 0; - for B := Low(TMsgDlgBtn) to High(TMsgDlgBtn) do - if B in Buttons then Inc(ButtonCount); - ButtonGroupWidth := 0; - if ButtonCount <> 0 then - ButtonGroupWidth := ButtonWidth * ButtonCount + - ButtonSpacing * (ButtonCount - 1); - ClientWidth := Max(IconTextWidth, ButtonGroupWidth) + HorzMargin * 2; - ClientHeight := IconTextHeight + ButtonHeight + VertSpacing + - VertMargin * 2; - Left := (Screen.Width div 2) - (Width div 2); - Top := (Screen.Height div 2) - (Height div 2); - if DlgType <> mtCustom then - Caption := GetMessageCaption(DlgType) - else - Caption := TntApplication.Title; - if IconID <> nil then - with TTntImage.Create(Result) do - begin - Name := 'Image'; - Parent := Result; - Picture.Icon.Handle := LoadIcon(0, IconID); - SetBounds(HorzMargin, VertMargin, 32, 32); - end; - TTntMessageForm(Result).Message := TTntLabel.Create(Result); - with TTntMessageForm(Result).Message do - begin - Name := 'Message'; - Parent := Result; - WordWrap := True; - Caption := Msg; - BoundsRect := ATextRect; - BiDiMode := Result.BiDiMode; - ALeft := IconTextWidth - ATextRect.Right + HorzMargin; - if UseRightToLeftAlignment then - ALeft := Result.ClientWidth - ALeft - Width; - SetBounds(ALeft, VertMargin, - ATextRect.Right, ATextRect.Bottom); - end; - if mbCancel in Buttons then CancelButton := mbCancel else - if mbNo in Buttons then CancelButton := mbNo else - CancelButton := mbOk; - X := (ClientWidth - ButtonGroupWidth) div 2; - for B := Low(TMsgDlgBtn) to High(TMsgDlgBtn) do - if B in Buttons then - begin - LButton := TTntButton.Create(Result); - with LButton do - begin - Name := ButtonNames[B]; - Parent := Result; - Caption := GetButtonCaption(B); - ModalResult := ModalResults[B]; - if B = DefaultButton then - begin - Default := True; - ActiveControl := LButton; - end; - if B = CancelButton then - Cancel := True; - SetBounds(X, IconTextHeight + VertMargin + VertSpacing, - ButtonWidth, ButtonHeight); - Inc(X, ButtonWidth + ButtonSpacing); - if B = mbHelp then - OnClick := TTntMessageForm(Result).HelpButtonClick; - end; - end; - end; -end; - -function WideCreateMessageDialog(const Msg: WideString; DlgType: TMsgDlgType; - Buttons: TMsgDlgButtons): TTntForm; -var - DefaultButton: TMsgDlgBtn; -begin - if mbOk in Buttons then DefaultButton := mbOk else - if mbYes in Buttons then DefaultButton := mbYes else - DefaultButton := mbRetry; - Result := WideCreateMessageDialog(Msg, DlgType, Buttons, DefaultButton); -end; - -function WideMessageDlg(const Msg: WideString; DlgType: TMsgDlgType; - Buttons: TMsgDlgButtons; HelpCtx: Longint; DefaultButton: TMsgDlgBtn): Integer; -begin - Result := WideMessageDlgPosHelp(Msg, DlgType, Buttons, HelpCtx, -1, -1, '', DefaultButton); -end; - -function WideMessageDlg(const Msg: WideString; DlgType: TMsgDlgType; - Buttons: TMsgDlgButtons; HelpCtx: Longint): Integer; -begin - Result := WideMessageDlgPosHelp(Msg, DlgType, Buttons, HelpCtx, -1, -1, ''); -end; - -function WideMessageDlgPos(const Msg: WideString; DlgType: TMsgDlgType; - Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer; DefaultButton: TMsgDlgBtn): Integer; -begin - Result := WideMessageDlgPosHelp(Msg, DlgType, Buttons, HelpCtx, X, Y, '', DefaultButton); -end; - -function WideMessageDlgPos(const Msg: WideString; DlgType: TMsgDlgType; - Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer): Integer; -begin - Result := WideMessageDlgPosHelp(Msg, DlgType, Buttons, HelpCtx, X, Y, ''); -end; - -function _Internal_WideMessageDlgPosHelp(Dlg: TTntForm; HelpCtx: Longint; X, Y: Integer; - const HelpFileName: WideString): Integer; -begin - with Dlg do - try - HelpContext := HelpCtx; - HelpFile := HelpFileName; - if X >= 0 then Left := X; - if Y >= 0 then Top := Y; - if (Y < 0) and (X < 0) then Position := poScreenCenter; - Result := ShowModal; - finally - Free; - end; -end; - -function WideMessageDlgPosHelp(const Msg: WideString; DlgType: TMsgDlgType; - Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer; - const HelpFileName: WideString; DefaultButton: TMsgDlgBtn): Integer; -begin - Result := _Internal_WideMessageDlgPosHelp( - WideCreateMessageDialog(Msg, DlgType, Buttons, DefaultButton), HelpCtx, X, Y, HelpFileName); -end; - -function WideMessageDlgPosHelp(const Msg: WideString; DlgType: TMsgDlgType; - Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer; - const HelpFileName: WideString): Integer; -begin - Result := _Internal_WideMessageDlgPosHelp( - WideCreateMessageDialog(Msg, DlgType, Buttons), HelpCtx, X, Y, HelpFileName); -end; - -procedure WideShowMessage(const Msg: WideString); -begin - WideShowMessagePos(Msg, -1, -1); -end; - -procedure WideShowMessageFmt(const Msg: WideString; Params: array of const); -begin - WideShowMessage(WideFormat(Msg, Params)); -end; - -procedure WideShowMessagePos(const Msg: WideString; X, Y: Integer); -begin - WideMessageDlgPos(Msg, mtCustom, [mbOK], 0, X, Y); -end; - -{ Input dialog } - -function WideInputQuery(const ACaption, APrompt: WideString; var Value: WideString): Boolean; -var - Form: TTntForm; - Prompt: TTntLabel; - Edit: TTntEdit; - DialogUnits: TPoint; - ButtonTop, ButtonWidth, ButtonHeight: Integer; -begin - Result := False; - Form := TTntForm.Create(Application); - with Form do begin - try - BorderStyle := bsDialog; // By doing this first, it will work on WINE. - Canvas.Font := Font; - DialogUnits := GetAveCharSize(Canvas); - Caption := ACaption; - ClientWidth := MulDiv(180, DialogUnits.X, 4); - Position := poScreenCenter; - Prompt := TTntLabel.Create(Form); - with Prompt do - begin - Parent := Form; - Caption := APrompt; - Left := MulDiv(8, DialogUnits.X, 4); - Top := MulDiv(8, DialogUnits.Y, 8); - Constraints.MaxWidth := MulDiv(164, DialogUnits.X, 4); - WordWrap := True; - end; - Edit := TTntEdit.Create(Form); - with Edit do - begin - Parent := Form; - Left := Prompt.Left; - Top := Prompt.Top + Prompt.Height + 5; - Width := MulDiv(164, DialogUnits.X, 4); - MaxLength := 255; - Text := Value; - SelectAll; - end; - ButtonTop := Edit.Top + Edit.Height + 15; - ButtonWidth := MulDiv(50, DialogUnits.X, 4); - ButtonHeight := MulDiv(14, DialogUnits.Y, 8); - with TTntButton.Create(Form) do - begin - Parent := Form; - Caption := SMsgDlgOK; - ModalResult := mrOk; - Default := True; - SetBounds(MulDiv(38, DialogUnits.X, 4), ButtonTop, ButtonWidth, - ButtonHeight); - end; - with TTntButton.Create(Form) do - begin - Parent := Form; - Caption := SMsgDlgCancel; - ModalResult := mrCancel; - Cancel := True; - SetBounds(MulDiv(92, DialogUnits.X, 4), Edit.Top + Edit.Height + 15, ButtonWidth, - ButtonHeight); - Form.ClientHeight := Top + Height + 13; - end; - if ShowModal = mrOk then - begin - Value := Edit.Text; - Result := True; - end; - finally - Form.Free; - end; - end; -end; - -function WideInputBox(const ACaption, APrompt, ADefault: WideString): WideString; -begin - Result := ADefault; - WideInputQuery(ACaption, APrompt, Result); -end; - -function WidePromptForFileName(var AFileName: WideString; const AFilter: WideString = ''; - const ADefaultExt: WideString = ''; const ATitle: WideString = ''; - const AInitialDir: WideString = ''; SaveDialog: Boolean = False): Boolean; -var - Dialog: TTntOpenDialog; -begin - if SaveDialog then - begin - Dialog := TTntSaveDialog.Create(nil); - Dialog.Options := Dialog.Options + [ofOverwritePrompt]; - end - else - Dialog := TTntOpenDialog.Create(nil); - with Dialog do - try - Title := ATitle; - DefaultExt := ADefaultExt; - if AFilter = '' then - Filter := SDefaultFilter else - Filter := AFilter; - InitialDir := AInitialDir; - FileName := AFileName; - Result := Execute; - if Result then - AFileName := FileName; - finally - Free; - end; -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntExtActns.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntExtActns.pas deleted file mode 100644 index b54fd02f3..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntExtActns.pas +++ /dev/null @@ -1,1400 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntExtActns; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Classes, TntActnList, ExtActns; - -type -{TNT-WARN TCustomFileRun} - TTntCustomFileRun = class(TCustomFileRun{TNT-ALLOW TCustomFileRun}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - public - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TFileRun} - TTntFileRun = class(TFileRun{TNT-ALLOW TFileRun}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TRichEditAction} - TTntRichEditAction = class(TRichEditAction{TNT-ALLOW TRichEditAction}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TRichEditBold} - TTntRichEditBold = class(TRichEditBold{TNT-ALLOW TRichEditBold}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TRichEditItalic} - TTntRichEditItalic = class(TRichEditItalic{TNT-ALLOW TRichEditItalic}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TRichEditUnderline} - TTntRichEditUnderline = class(TRichEditUnderline{TNT-ALLOW TRichEditUnderline}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TRichEditStrikeOut} - TTntRichEditStrikeOut = class(TRichEditStrikeOut{TNT-ALLOW TRichEditStrikeOut}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TRichEditBullets} - TTntRichEditBullets = class(TRichEditBullets{TNT-ALLOW TRichEditBullets}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TRichEditAlignLeft} - TTntRichEditAlignLeft = class(TRichEditAlignLeft{TNT-ALLOW TRichEditAlignLeft}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TRichEditAlignRight} - TTntRichEditAlignRight = class(TRichEditAlignRight{TNT-ALLOW TRichEditAlignRight}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TRichEditAlignCenter} - TTntRichEditAlignCenter = class(TRichEditAlignCenter{TNT-ALLOW TRichEditAlignCenter}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TTabAction} - TTntTabAction = class(TTabAction{TNT-ALLOW TTabAction}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - public - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TPreviousTab} - TTntPreviousTab = class(TPreviousTab{TNT-ALLOW TPreviousTab}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TNextTab} - TTntNextTab = class(TNextTab{TNT-ALLOW TNextTab}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TOpenPicture} - TTntOpenPicture = class(TOpenPicture{TNT-ALLOW TOpenPicture}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TSavePicture} - TTntSavePicture = class(TSavePicture{TNT-ALLOW TSavePicture}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TURLAction} - TTntURLAction = class(TURLAction{TNT-ALLOW TURLAction}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TBrowseURL} - TTntBrowseURL = class(TBrowseURL{TNT-ALLOW TBrowseURL}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TDownLoadURL} - TTntDownLoadURL = class(TDownLoadURL{TNT-ALLOW TDownLoadURL}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TSendMail} - TTntSendMail = class(TSendMail{TNT-ALLOW TSendMail}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TListControlAction} - TTntListControlAction = class(TListControlAction{TNT-ALLOW TListControlAction}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - public - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TListControlCopySelection} - TTntListControlCopySelection = class(TListControlCopySelection{TNT-ALLOW TListControlCopySelection}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TListControlDeleteSelection} - TTntListControlDeleteSelection = class(TListControlDeleteSelection{TNT-ALLOW TListControlDeleteSelection}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TListControlSelectAll} - TTntListControlSelectAll = class(TListControlSelectAll{TNT-ALLOW TListControlSelectAll}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TListControlClearSelection} - TTntListControlClearSelection = class(TListControlClearSelection{TNT-ALLOW TListControlClearSelection}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TListControlMoveSelection} - TTntListControlMoveSelection = class(TListControlMoveSelection{TNT-ALLOW TListControlMoveSelection}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -implementation - -uses - ActnList, TntStdActns, TntClasses; - -{TNT-IGNORE-UNIT} - -procedure TntExtActn_AfterInherited_Assign(Action: TCustomAction{TNT-ALLOW TCustomAction}; Source: TPersistent); -begin - TntStdActn_AfterInherited_Assign(Action, Source); - // TCustomFileRun - if (Action is TCustomFileRun) and (Source is TCustomFileRun) then begin - TCustomFileRun(Action).Browse := TCustomFileRun(Source).Browse; - if TCustomFileRun(Source).BrowseDlg.Owner <> Source then - TCustomFileRun(Action).BrowseDlg := TCustomFileRun(Source).BrowseDlg - else begin - { Carry over dialog properties. Currently TOpenDialog doesn't support Assign. } - { TCustomFileRun(Action).BrowseDlg.Assign(TCustomFileRun(Source).BrowseDlg); } - end; - TCustomFileRun(Action).Directory := TCustomFileRun(Source).Directory; - TCustomFileRun(Action).FileName := TCustomFileRun(Source).FileName; - TCustomFileRun(Action).Operation := TCustomFileRun(Source).Operation; - TCustomFileRun(Action).ParentControl := TCustomFileRun(Source).ParentControl; - TCustomFileRun(Action).Parameters := TCustomFileRun(Source).Parameters; - TCustomFileRun(Action).ShowCmd := TCustomFileRun(Source).ShowCmd; - end; - // TTabAction - if (Action is TTabAction) and (Source is TTabAction) then begin - TTabAction(Action).SkipHiddenTabs := TTabAction(Source).SkipHiddenTabs; - TTabAction(Action).TabControl := TTabAction(Source).TabControl; - TTabAction(Action).Wrap := TTabAction(Source).Wrap; - TTabAction(Action).BeforeTabChange := TTabAction(Source).BeforeTabChange; - TTabAction(Action).AfterTabChange := TTabAction(Source).AfterTabChange; - TTabAction(Action).OnValidateTab := TTabAction(Source).OnValidateTab; - end; - // TNextTab - if (Action is TNextTab) and (Source is TNextTab) then begin - TNextTab(Action).LastTabCaption := TNextTab(Source).LastTabCaption; - TNextTab(Action).OnFinish := TNextTab(Source).OnFinish; - end; - // TURLAction - if (Action is TURLAction) and (Source is TURLAction) then begin - TURLAction(Action).URL := TURLAction(Source).URL; - end; - // TBrowseURL - if (Action is TBrowseURL) and (Source is TBrowseURL) then begin - {$IFDEF COMPILER_7_UP} - TBrowseURL(Action).BeforeBrowse := TBrowseURL(Source).BeforeBrowse; - TBrowseURL(Action).AfterBrowse := TBrowseURL(Source).AfterBrowse; - {$ENDIF} - end; - // TDownloadURL - if (Action is TDownloadURL) and (Source is TDownloadURL) then begin - TDownloadURL(Action).FileName := TDownloadURL(Source).FileName; - {$IFDEF COMPILER_7_UP} - TDownloadURL(Action).BeforeDownload := TDownloadURL(Source).BeforeDownload; - TDownloadURL(Action).AfterDownload := TDownloadURL(Source).AfterDownload; - {$ENDIF} - TDownloadURL(Action).OnDownloadProgress := TDownloadURL(Source).OnDownloadProgress; - end; - // TSendMail - if (Action is TSendMail) and (Source is TSendMail) then begin - TSendMail(Action).Text := TSendMail(Source).Text; - end; - // TListControlAction - if (Action is TListControlAction) and (Source is TListControlAction) then begin - TListControlAction(Action).ListControl := TListControlAction(Source).ListControl; - end; - // TListControlCopySelection - if (Action is TListControlCopySelection) and (Source is TListControlCopySelection) then begin - TListControlCopySelection(Action).Destination := TListControlCopySelection(Source).Destination; - end; -end; - -//------------------------- -// TNT EXT ACTNS -//------------------------- - -{ TTntCustomFileRun } - -procedure TTntCustomFileRun.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntCustomFileRun.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntCustomFileRun.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntCustomFileRun.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntCustomFileRun.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntCustomFileRun.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntFileRun } - -procedure TTntFileRun.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntFileRun.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntFileRun.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntFileRun.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntFileRun.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntFileRun.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntRichEditAction } - -procedure TTntRichEditAction.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntRichEditAction.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntRichEditAction.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntRichEditAction.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntRichEditAction.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntRichEditAction.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntRichEditBold } - -procedure TTntRichEditBold.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntRichEditBold.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntRichEditBold.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntRichEditBold.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntRichEditBold.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntRichEditBold.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntRichEditItalic } - -procedure TTntRichEditItalic.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntRichEditItalic.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntRichEditItalic.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntRichEditItalic.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntRichEditItalic.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntRichEditItalic.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntRichEditUnderline } - -procedure TTntRichEditUnderline.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntRichEditUnderline.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntRichEditUnderline.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntRichEditUnderline.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntRichEditUnderline.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntRichEditUnderline.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntRichEditStrikeOut } - -procedure TTntRichEditStrikeOut.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntRichEditStrikeOut.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntRichEditStrikeOut.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntRichEditStrikeOut.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntRichEditStrikeOut.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntRichEditStrikeOut.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntRichEditBullets } - -procedure TTntRichEditBullets.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntRichEditBullets.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntRichEditBullets.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntRichEditBullets.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntRichEditBullets.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntRichEditBullets.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntRichEditAlignLeft } - -procedure TTntRichEditAlignLeft.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntRichEditAlignLeft.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntRichEditAlignLeft.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntRichEditAlignLeft.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntRichEditAlignLeft.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntRichEditAlignLeft.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntRichEditAlignRight } - -procedure TTntRichEditAlignRight.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntRichEditAlignRight.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntRichEditAlignRight.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntRichEditAlignRight.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntRichEditAlignRight.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntRichEditAlignRight.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntRichEditAlignCenter } - -procedure TTntRichEditAlignCenter.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntRichEditAlignCenter.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntRichEditAlignCenter.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntRichEditAlignCenter.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntRichEditAlignCenter.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntRichEditAlignCenter.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntTabAction } - -procedure TTntTabAction.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntTabAction.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntTabAction.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntTabAction.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntTabAction.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntTabAction.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntPreviousTab } - -procedure TTntPreviousTab.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntPreviousTab.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntPreviousTab.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntPreviousTab.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntPreviousTab.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntPreviousTab.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntNextTab } - -procedure TTntNextTab.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntNextTab.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntNextTab.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntNextTab.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntNextTab.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntNextTab.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntOpenPicture } - -procedure TTntOpenPicture.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntOpenPicture.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntOpenPicture.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntOpenPicture.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntOpenPicture.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntOpenPicture.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntSavePicture } - -procedure TTntSavePicture.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntSavePicture.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntSavePicture.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntSavePicture.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntSavePicture.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntSavePicture.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntURLAction } - -procedure TTntURLAction.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntURLAction.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntURLAction.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntURLAction.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntURLAction.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntURLAction.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntBrowseURL } - -procedure TTntBrowseURL.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntBrowseURL.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntBrowseURL.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntBrowseURL.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntBrowseURL.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntBrowseURL.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntDownLoadURL } - -procedure TTntDownLoadURL.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntDownLoadURL.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntDownLoadURL.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntDownLoadURL.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntDownLoadURL.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntDownLoadURL.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntSendMail } - -procedure TTntSendMail.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntSendMail.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntSendMail.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntSendMail.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntSendMail.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntSendMail.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntListControlAction } - -procedure TTntListControlAction.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntListControlAction.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntListControlAction.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntListControlAction.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntListControlAction.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntListControlAction.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntListControlCopySelection } - -procedure TTntListControlCopySelection.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntListControlCopySelection.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntListControlCopySelection.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntListControlCopySelection.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntListControlCopySelection.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntListControlCopySelection.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntListControlDeleteSelection } - -procedure TTntListControlDeleteSelection.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntListControlDeleteSelection.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntListControlDeleteSelection.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntListControlDeleteSelection.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntListControlDeleteSelection.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntListControlDeleteSelection.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntListControlSelectAll } - -procedure TTntListControlSelectAll.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntListControlSelectAll.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntListControlSelectAll.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntListControlSelectAll.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntListControlSelectAll.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntListControlSelectAll.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntListControlClearSelection } - -procedure TTntListControlClearSelection.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntListControlClearSelection.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntListControlClearSelection.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntListControlClearSelection.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntListControlClearSelection.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntListControlClearSelection.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntListControlMoveSelection } - -procedure TTntListControlMoveSelection.Assign(Source: TPersistent); -begin - inherited; - TntExtActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntListControlMoveSelection.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntListControlMoveSelection.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntListControlMoveSelection.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntListControlMoveSelection.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntListControlMoveSelection.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntExtCtrls.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntExtCtrls.pas deleted file mode 100644 index 2584aa4a0..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntExtCtrls.pas +++ /dev/null @@ -1,1062 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntExtCtrls; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Classes, Messages, Controls, ExtCtrls, TntClasses, TntControls, TntStdCtrls, TntGraphics; - -type -{TNT-WARN TShape} - TTntShape = class(TShape{TNT-ALLOW TShape}) - private - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - procedure CMHintShow(var Message: TMessage); message CM_HINTSHOW; - protected - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TPaintBox} - TTntPaintBox = class(TPaintBox{TNT-ALLOW TPaintBox}) - private - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - procedure CMHintShow(var Message: TMessage); message CM_HINTSHOW; - protected - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TImage} - TTntImage = class(TImage{TNT-ALLOW TImage}) - private - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - procedure CMHintShow(var Message: TMessage); message CM_HINTSHOW; - function GetPicture: TTntPicture; - procedure SetPicture(const Value: TTntPicture); - protected - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - public - constructor Create(AOwner: TComponent); override; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - property Picture: TTntPicture read GetPicture write SetPicture; - end; - -{TNT-WARN TBevel} - TTntBevel = class(TBevel{TNT-ALLOW TBevel}) - private - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - procedure CMHintShow(var Message: TMessage); message CM_HINTSHOW; - protected - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TCustomPanel} - TTntCustomPanel = class(TCustomPanel{TNT-ALLOW TCustomPanel}) - private - function GetCaption: TWideCaption; - procedure SetCaption(const Value: TWideCaption); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsCaptionStored: Boolean; - function IsHintStored: Boolean; - protected - procedure Paint; override; - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - property Caption: TWideCaption read GetCaption write SetCaption stored IsCaptionStored; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TPanel} - TTntPanel = class(TTntCustomPanel) - public - property DockManager; - published - property Align; - property Alignment; - property Anchors; - property AutoSize; - property BevelEdges; - property BevelInner; - property BevelKind; - property BevelOuter; - property BevelWidth; - property BiDiMode; - property BorderWidth; - property BorderStyle; - property Caption; - property Color; - property Constraints; - property Ctl3D; - property UseDockManager default True; - property DockSite; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property FullRepaint; - property Font; - property Locked; - {$IFDEF COMPILER_10_UP} - property Padding; - {$ENDIF} - property ParentBiDiMode; - {$IFDEF COMPILER_7_UP} - property ParentBackground; - {$ENDIF} - property ParentColor; - property ParentCtl3D; - property ParentFont; - property ParentShowHint; - property PopupMenu; - property ShowHint; - property TabOrder; - property TabStop; - {$IFDEF COMPILER_9_UP} - property VerticalAlignment; - {$ENDIF} - property Visible; - {$IFDEF COMPILER_9_UP} - property OnAlignInsertBefore; - property OnAlignPosition; - {$ENDIF} - property OnCanResize; - property OnClick; - property OnConstrainedResize; - property OnContextPopup; - property OnDockDrop; - property OnDockOver; - property OnDblClick; - property OnDragDrop; - property OnDragOver; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnGetSiteInfo; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - property OnResize; - property OnStartDock; - property OnStartDrag; - property OnUnDock; - end; - -{TNT-WARN TCustomControlBar} - TTntCustomControlBar = class(TCustomControlBar{TNT-ALLOW TCustomControlBar}) - private - function IsHintStored: Boolean; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TControlBar} - TTntControlBar = class(TTntCustomControlBar) - public - property Canvas; - published - property Align; - property Anchors; - property AutoDock; - property AutoDrag; - property AutoSize; - property BevelEdges; - property BevelInner; - property BevelOuter; - property BevelKind; - property BevelWidth; - property BorderWidth; - property Color {$IFDEF COMPILER_7_UP} nodefault {$ENDIF}; - property Constraints; - {$IFDEF COMPILER_10_UP} - property CornerEdge; - {$ENDIF} - property DockSite; - property DragCursor; - property DragKind; - property DragMode; - {$IFDEF COMPILER_10_UP} - property DrawingStyle; - {$ENDIF} - property Enabled; - {$IFDEF COMPILER_10_UP} - property GradientDirection; - property GradientEndColor; - property GradientStartColor; - {$ENDIF} - {$IFDEF COMPILER_7_UP} - property ParentBackground default True; - {$ENDIF} - property ParentColor; - property ParentCtl3D; - property ParentFont; - property ParentShowHint; - property Picture; - property PopupMenu; - property RowSize; - property RowSnap; - property ShowHint; - property TabOrder; - property TabStop; - property Visible; - {$IFDEF COMPILER_9_UP} - property OnAlignInsertBefore; - property OnAlignPosition; - {$ENDIF} - property OnBandDrag; - property OnBandInfo; - property OnBandMove; - property OnBandPaint; - {$IFDEF COMPILER_9_UP} - property OnBeginBandMove; - property OnEndBandMove; - {$ENDIF} - property OnCanResize; - property OnClick; - property OnConstrainedResize; - property OnContextPopup; - property OnDockDrop; - property OnDockOver; - property OnDblClick; - property OnDragDrop; - property OnDragOver; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnGetSiteInfo; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - property OnPaint; - property OnResize; - property OnStartDock; - property OnStartDrag; - property OnUnDock; - end; - -{TNT-WARN TCustomRadioGroup} - TTntCustomRadioGroup = class(TTntCustomGroupBox) - private - FButtons: TList; - FItems: TTntStrings; - FItemIndex: Integer; - FColumns: Integer; - FReading: Boolean; - FUpdating: Boolean; - function GetButtons(Index: Integer): TTntRadioButton; - procedure ArrangeButtons; - procedure ButtonClick(Sender: TObject); - procedure ItemsChange(Sender: TObject); - procedure SetButtonCount(Value: Integer); - procedure SetColumns(Value: Integer); - procedure SetItemIndex(Value: Integer); - procedure SetItems(Value: TTntStrings); - procedure UpdateButtons; - procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED; - procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED; - procedure WMSize(var Message: TWMSize); message WM_SIZE; - protected - procedure Loaded; override; - procedure ReadState(Reader: TReader); override; - function CanModify: Boolean; virtual; - procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override; - property Columns: Integer read FColumns write SetColumns default 1; - property ItemIndex: Integer read FItemIndex write SetItemIndex default -1; - property Items: TTntStrings read FItems write SetItems; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - procedure FlipChildren(AllLevels: Boolean); override; - property Buttons[Index: Integer]: TTntRadioButton read GetButtons; - end; - -{TNT-WARN TRadioGroup} - TTntRadioGroup = class(TTntCustomRadioGroup) - published - property Align; - property Anchors; - property BiDiMode; - property Caption; - property Color; - property Columns; - property Ctl3D; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property Font; - property ItemIndex; - property Items; - property Constraints; - property ParentBiDiMode; - {$IFDEF COMPILER_7_UP} - property ParentBackground default True; - {$ENDIF} - property ParentColor; - property ParentCtl3D; - property ParentFont; - property ParentShowHint; - property PopupMenu; - property ShowHint; - property TabOrder; - property TabStop; - property Visible; - property OnClick; - property OnContextPopup; - property OnDragDrop; - property OnDragOver; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnStartDock; - property OnStartDrag; - end; - -{TNT-WARN TSplitter} - TTntSplitter = class(TSplitter{TNT-ALLOW TSplitter}) - private - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - procedure CMHintShow(var Message: TMessage); message CM_HINTSHOW; - protected - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -implementation - -uses - Windows, Graphics, Forms, {$IFDEF THEME_7_UP} Themes, {$ENDIF} - TntSysUtils, TntWindows, TntActnList; - -{ TTntShape } - -procedure TTntShape.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntShape.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -function TTntShape.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntShape.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntShape.CMHintShow(var Message: TMessage); -begin - ProcessCMHintShowMsg(Message); - inherited; -end; - -procedure TTntShape.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntShape.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntPaintBox } - -procedure TTntPaintBox.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntPaintBox.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -function TTntPaintBox.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntPaintBox.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntPaintBox.CMHintShow(var Message: TMessage); -begin - ProcessCMHintShowMsg(Message); - inherited; -end; - -procedure TTntPaintBox.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntPaintBox.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -type -{$IFDEF COMPILER_6} // verified against VCL source in Delphi 6 and BCB 6 - THackImage = class(TGraphicControl) - protected - FPicture: TPicture{TNT-ALLOW TPicture}; - end; -{$ENDIF} -{$IFDEF DELPHI_7} // verified against VCL source in Delphi 7 - THackImage = class(TGraphicControl) - protected - FPicture: TPicture{TNT-ALLOW TPicture}; - end; -{$ENDIF} -{$IFDEF DELPHI_9} // verified against VCL source in Delphi 9 - THackImage = class(TGraphicControl) - private - FPicture: TPicture{TNT-ALLOW TPicture}; - end; -{$ENDIF} -{$IFDEF DELPHI_10} // verified against VCL source in Delphi 10 - THackImage = class(TGraphicControl) - private - FPicture: TPicture{TNT-ALLOW TPicture}; - end; -{$ENDIF} - -{ TTntImage } - -constructor TTntImage.Create(AOwner: TComponent); -var - OldPicture: TPicture{TNT-ALLOW TPicture}; -begin - inherited; - OldPicture := THackImage(Self).FPicture; - THackImage(Self).FPicture := TTntPicture.Create; - Picture.OnChange := OldPicture.OnChange; - Picture.OnProgress := OldPicture.OnProgress; - OldPicture.Free; -end; - -function TTntImage.GetPicture: TTntPicture; -begin - Result := inherited Picture as TTntPicture; -end; - -procedure TTntImage.SetPicture(const Value: TTntPicture); -begin - inherited Picture := Value; -end; - -procedure TTntImage.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntImage.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -function TTntImage.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntImage.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntImage.CMHintShow(var Message: TMessage); -begin - ProcessCMHintShowMsg(Message); - inherited; -end; - -procedure TTntImage.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntImage.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntBevel } - -procedure TTntBevel.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntBevel.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -function TTntBevel.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntBevel.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntBevel.CMHintShow(var Message: TMessage); -begin - ProcessCMHintShowMsg(Message); - inherited; -end; - -procedure TTntBevel.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntBevel.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntCustomPanel } - -procedure TTntCustomPanel.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, ''); -end; - -procedure TTntCustomPanel.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntCustomPanel.IsCaptionStored: Boolean; -begin - Result := TntControl_IsCaptionStored(Self); -end; - -function TTntCustomPanel.GetCaption: TWideCaption; -begin - Result := TntControl_GetText(Self) -end; - -procedure TTntCustomPanel.SetCaption(const Value: TWideCaption); -begin - TntControl_SetText(Self, Value); -end; - -procedure TTntCustomPanel.Paint; -const - Alignments: array[TAlignment] of Longint = (DT_LEFT, DT_RIGHT, DT_CENTER); -var - Rect: TRect; - TopColor, BottomColor: TColor; - FontHeight: Integer; - Flags: Longint; - - procedure AdjustColors(Bevel: TPanelBevel); - begin - TopColor := clBtnHighlight; - if Bevel = bvLowered then TopColor := clBtnShadow; - BottomColor := clBtnShadow; - if Bevel = bvLowered then BottomColor := clBtnHighlight; - end; - -begin - if (not Win32PlatformIsUnicode) then - inherited - else begin - Rect := GetClientRect; - if BevelOuter <> bvNone then - begin - AdjustColors(BevelOuter); - Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth); - end; - {$IFDEF THEME_7_UP} - if ThemeServices.ThemesEnabled {$IFDEF COMPILER_7_UP} and ParentBackground {$ENDIF} then - InflateRect(Rect, -BorderWidth, -BorderWidth) - else - {$ENDIF} - begin - Frame3D(Canvas, Rect, Color, Color, BorderWidth); - end; - if BevelInner <> bvNone then - begin - AdjustColors(BevelInner); - Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth); - end; - with Canvas do - begin - {$IFDEF THEME_7_UP} - if not ThemeServices.ThemesEnabled {$IFDEF COMPILER_7_UP} or not ParentBackground {$ENDIF} then - {$ENDIF} - begin - Brush.Color := Color; - FillRect(Rect); - end; - Brush.Style := bsClear; - Font := Self.Font; - FontHeight := WideCanvasTextHeight(Canvas, 'W'); - with Rect do - begin - Top := ((Bottom + Top) - FontHeight) div 2; - Bottom := Top + FontHeight; - end; - Flags := DT_EXPANDTABS or DT_VCENTER or Alignments[Alignment]; - Flags := DrawTextBiDiModeFlags(Flags); - Tnt_DrawTextW(Handle, PWideChar(Caption), -1, Rect, Flags); - end; - end; -end; - -function TTntCustomPanel.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -function TTntCustomPanel.GetHint: WideString; -begin - Result := TntControl_GetHint(Self); -end; - -procedure TTntCustomPanel.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntCustomPanel.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomPanel.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntCustomControlBar } - -procedure TTntCustomControlBar.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, ''); -end; - -procedure TTntCustomControlBar.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntCustomControlBar.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntCustomControlBar.GetHint: WideString; -begin - Result := TntControl_GetHint(Self); -end; - -procedure TTntCustomControlBar.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntCustomControlBar.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomControlBar.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntGroupButton } - -type - TTntGroupButton = class(TTntRadioButton) - private - FInClick: Boolean; - procedure CNCommand(var Message: TWMCommand); message CN_COMMAND; - protected - procedure KeyDown(var Key: Word; Shift: TShiftState); override; - procedure KeyPress(var Key: Char{TNT-ALLOW Char}); override; - public - constructor InternalCreate(RadioGroup: TTntCustomRadioGroup); - destructor Destroy; override; - end; - -constructor TTntGroupButton.InternalCreate(RadioGroup: TTntCustomRadioGroup); -begin - inherited Create(RadioGroup); - RadioGroup.FButtons.Add(Self); - Visible := False; - Enabled := RadioGroup.Enabled; - ParentShowHint := False; - OnClick := RadioGroup.ButtonClick; - Parent := RadioGroup; -end; - -destructor TTntGroupButton.Destroy; -begin - TTntCustomRadioGroup(Owner).FButtons.Remove(Self); - inherited Destroy; -end; - -procedure TTntGroupButton.CNCommand(var Message: TWMCommand); -begin - if not FInClick then - begin - FInClick := True; - try - if ((Message.NotifyCode = BN_CLICKED) or - (Message.NotifyCode = BN_DOUBLECLICKED)) and - TTntCustomRadioGroup(Parent).CanModify then - inherited; - except - Application.HandleException(Self); - end; - FInClick := False; - end; -end; - -procedure TTntGroupButton.KeyPress(var Key: Char{TNT-ALLOW Char}); -begin - inherited KeyPress(Key); - TTntCustomRadioGroup(Parent).KeyPress(Key); - if (Key = #8) or (Key = ' ') then - begin - if not TTntCustomRadioGroup(Parent).CanModify then Key := #0; - end; -end; - -procedure TTntGroupButton.KeyDown(var Key: Word; Shift: TShiftState); -begin - inherited KeyDown(Key, Shift); - TTntCustomRadioGroup(Parent).KeyDown(Key, Shift); -end; - -{ TTntCustomRadioGroup } - -constructor TTntCustomRadioGroup.Create(AOwner: TComponent); -begin - inherited Create(AOwner); - ControlStyle := [csSetCaption, csDoubleClicks {$IFDEF COMPILER_7_UP}, csParentBackground {$ENDIF}]; - FButtons := TList.Create; - FItems := TTntStringList.Create; - TTntStringList(FItems).OnChange := ItemsChange; - FItemIndex := -1; - FColumns := 1; -end; - -destructor TTntCustomRadioGroup.Destroy; -begin - SetButtonCount(0); - TTntStringList(FItems).OnChange := nil; - FItems.Free; - FButtons.Free; - inherited Destroy; -end; - -procedure TTntCustomRadioGroup.FlipChildren(AllLevels: Boolean); -begin - { The radio buttons are flipped using BiDiMode } -end; - -procedure TTntCustomRadioGroup.ArrangeButtons; -var - ButtonsPerCol, ButtonWidth, ButtonHeight, TopMargin, I: Integer; - DC: HDC; - SaveFont: HFont; - Metrics: TTextMetric; - DeferHandle: THandle; - ALeft: Integer; -begin - if (FButtons.Count <> 0) and not FReading then - begin - DC := GetDC(0); - SaveFont := SelectObject(DC, Font.Handle); - GetTextMetrics(DC, Metrics); - SelectObject(DC, SaveFont); - ReleaseDC(0, DC); - ButtonsPerCol := (FButtons.Count + FColumns - 1) div FColumns; - ButtonWidth := (Width - 10) div FColumns; - I := Height - Metrics.tmHeight - 5; - ButtonHeight := I div ButtonsPerCol; - TopMargin := Metrics.tmHeight + 1 + (I mod ButtonsPerCol) div 2; - DeferHandle := BeginDeferWindowPos(FButtons.Count); - try - for I := 0 to FButtons.Count - 1 do - with TTntGroupButton(FButtons[I]) do - begin - BiDiMode := Self.BiDiMode; - ALeft := (I div ButtonsPerCol) * ButtonWidth + 8; - if UseRightToLeftAlignment then - ALeft := Self.ClientWidth - ALeft - ButtonWidth; - DeferHandle := DeferWindowPos(DeferHandle, Handle, 0, - ALeft, - (I mod ButtonsPerCol) * ButtonHeight + TopMargin, - ButtonWidth, ButtonHeight, - SWP_NOZORDER or SWP_NOACTIVATE); - Visible := True; - end; - finally - EndDeferWindowPos(DeferHandle); - end; - end; -end; - -procedure TTntCustomRadioGroup.ButtonClick(Sender: TObject); -begin - if not FUpdating then - begin - FItemIndex := FButtons.IndexOf(Sender); - Changed; - Click; - end; -end; - -procedure TTntCustomRadioGroup.ItemsChange(Sender: TObject); -begin - if not FReading then - begin - if FItemIndex >= FItems.Count then FItemIndex := FItems.Count - 1; - UpdateButtons; - end; -end; - -procedure TTntCustomRadioGroup.Loaded; -begin - inherited Loaded; - ArrangeButtons; -end; - -procedure TTntCustomRadioGroup.ReadState(Reader: TReader); -begin - FReading := True; - inherited ReadState(Reader); - FReading := False; - UpdateButtons; -end; - -procedure TTntCustomRadioGroup.SetButtonCount(Value: Integer); -begin - while FButtons.Count < Value do TTntGroupButton.InternalCreate(Self); - while FButtons.Count > Value do TTntGroupButton(FButtons.Last).Free; -end; - -procedure TTntCustomRadioGroup.SetColumns(Value: Integer); -begin - if Value < 1 then Value := 1; - if Value > 16 then Value := 16; - if FColumns <> Value then - begin - FColumns := Value; - ArrangeButtons; - Invalidate; - end; -end; - -procedure TTntCustomRadioGroup.SetItemIndex(Value: Integer); -begin - if FReading then FItemIndex := Value else - begin - if Value < -1 then Value := -1; - if Value >= FButtons.Count then Value := FButtons.Count - 1; - if FItemIndex <> Value then - begin - if FItemIndex >= 0 then - TTntGroupButton(FButtons[FItemIndex]).Checked := False; - FItemIndex := Value; - if FItemIndex >= 0 then - TTntGroupButton(FButtons[FItemIndex]).Checked := True; - end; - end; -end; - -procedure TTntCustomRadioGroup.SetItems(Value: TTntStrings); -begin - FItems.Assign(Value); -end; - -procedure TTntCustomRadioGroup.UpdateButtons; -var - I: Integer; -begin - SetButtonCount(FItems.Count); - for I := 0 to FButtons.Count - 1 do - TTntGroupButton(FButtons[I]).Caption := FItems[I]; - if FItemIndex >= 0 then - begin - FUpdating := True; - TTntGroupButton(FButtons[FItemIndex]).Checked := True; - FUpdating := False; - end; - ArrangeButtons; - Invalidate; -end; - -procedure TTntCustomRadioGroup.CMEnabledChanged(var Message: TMessage); -var - I: Integer; -begin - inherited; - for I := 0 to FButtons.Count - 1 do - TTntGroupButton(FButtons[I]).Enabled := Enabled; -end; - -procedure TTntCustomRadioGroup.CMFontChanged(var Message: TMessage); -begin - inherited; - ArrangeButtons; -end; - -procedure TTntCustomRadioGroup.WMSize(var Message: TWMSize); -begin - inherited; - ArrangeButtons; -end; - -function TTntCustomRadioGroup.CanModify: Boolean; -begin - Result := True; -end; - -procedure TTntCustomRadioGroup.GetChildren(Proc: TGetChildProc; Root: TComponent); -begin -end; - -function TTntCustomRadioGroup.GetButtons(Index: Integer): TTntRadioButton; -begin - Result := TTntRadioButton(FButtons[Index]); -end; - -{ TTntSplitter } - -procedure TTntSplitter.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntSplitter.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -function TTntSplitter.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntSplitter.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntSplitter.CMHintShow(var Message: TMessage); -begin - ProcessCMHintShowMsg(Message); - inherited; -end; - -procedure TTntSplitter.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntSplitter.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntExtDlgs.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntExtDlgs.pas deleted file mode 100644 index bd763e5e3..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntExtDlgs.pas +++ /dev/null @@ -1,317 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntExtDlgs; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Classes, Windows, TntDialogs, TntExtCtrls, TntStdCtrls, TntButtons; - -type -{TNT-WARN TOpenPictureDialog} - TTntOpenPictureDialog = class(TTntOpenDialog) - private - FPicturePanel: TTntPanel; - FPictureLabel: TTntLabel; - FPreviewButton: TTntSpeedButton; - FPaintPanel: TTntPanel; - FImageCtrl: TTntImage; - FSavedFilename: WideString; - function IsFilterStored: Boolean; - procedure PreviewKeyPress(Sender: TObject; var Key: Char{TNT-ALLOW Char}); - protected - procedure PreviewClick(Sender: TObject); virtual; - procedure DoClose; override; - procedure DoSelectionChange; override; - procedure DoShow; override; - property ImageCtrl: TTntImage read FImageCtrl; - property PictureLabel: TTntLabel read FPictureLabel; - published - property Filter stored IsFilterStored; - public - constructor Create(AOwner: TComponent); override; - function Execute: Boolean; override; - {$IFDEF COMPILER_9_UP} - function Execute(ParentWnd: HWND): Boolean; override; - {$ENDIF} - end; - -{TNT-WARN TSavePictureDialog} - TTntSavePictureDialog = class(TTntOpenPictureDialog) - public - function Execute: Boolean; override; - {$IFDEF COMPILER_9_UP} - function Execute(ParentWnd: HWND): Boolean; override; - {$ENDIF} - end; - -implementation - -uses - ExtDlgs, {ExtDlgs is needed for a linked resource} Dialogs, Consts, Messages, - Graphics, Math, Controls, Forms, SysUtils, CommDlg, TntSysUtils, TntForms; - -{ TTntSilentPaintPanel } - -type - TTntSilentPaintPanel = class(TTntPanel) - protected - procedure WMPaint(var Msg: TWMPaint); message WM_PAINT; - end; - -procedure TTntSilentPaintPanel.WMPaint(var Msg: TWMPaint); -begin - try - inherited; - except - Caption := SInvalidImage; - end; -end; - -{ TTntOpenPictureDialog } - -constructor TTntOpenPictureDialog.Create(AOwner: TComponent); -begin - inherited; - Filter := GraphicFilter(TGraphic); - FPicturePanel := TTntPanel.Create(Self); - with FPicturePanel do - begin - Name := 'PicturePanel'; - Caption := ''; - SetBounds(204, 5, 169, 200); - BevelOuter := bvNone; - BorderWidth := 6; - TabOrder := 1; - FPictureLabel := TTntLabel.Create(Self); - with FPictureLabel do - begin - Name := 'PictureLabel'; - Caption := ''; - SetBounds(6, 6, 157, 23); - Align := alTop; - AutoSize := False; - Parent := FPicturePanel; - end; - FPreviewButton := TTntSpeedButton.Create(Self); - with FPreviewButton do - begin - Name := 'PreviewButton'; - SetBounds(77, 1, 23, 22); - Enabled := False; - Glyph.LoadFromResourceName(FindClassHInstance(TOpenPictureDialog{TNT-ALLOW TOpenPictureDialog}), 'PREVIEWGLYPH'); - Hint := SPreviewLabel; - ParentShowHint := False; - ShowHint := True; - OnClick := PreviewClick; - Parent := FPicturePanel; - end; - FPaintPanel := TTntSilentPaintPanel.Create(Self); - with FPaintPanel do - begin - Name := 'PaintPanel'; - Caption := ''; - SetBounds(6, 29, 157, 145); - Align := alClient; - BevelInner := bvRaised; - BevelOuter := bvLowered; - TabOrder := 0; - FImageCtrl := TTntImage.Create(Self); - Parent := FPicturePanel; - with FImageCtrl do - begin - Name := 'PaintBox'; - Align := alClient; - OnDblClick := PreviewClick; - Parent := FPaintPanel; - Proportional := True; - Stretch := True; - Center := True; - IncrementalDisplay := True; - end; - end; - end; -end; - -procedure TTntOpenPictureDialog.DoClose; -begin - inherited; - { Hide any hint windows left behind } - Application.HideHint; -end; - -procedure TTntOpenPictureDialog.DoSelectionChange; -var - FullName: WideString; - ValidPicture: Boolean; - - function ValidFile(const FileName: WideString): Boolean; - begin - Result := WideFileGetAttr(FileName) <> $FFFFFFFF; - end; - -begin - FullName := FileName; - if FullName <> FSavedFilename then - begin - FSavedFilename := FullName; - ValidPicture := WideFileExists(FullName) and ValidFile(FullName); - if ValidPicture then - try - FImageCtrl.Picture.LoadFromFile(FullName); - FPictureLabel.Caption := WideFormat(SPictureDesc, - [FImageCtrl.Picture.Width, FImageCtrl.Picture.Height]); - FPreviewButton.Enabled := True; - FPaintPanel.Caption := ''; - except - ValidPicture := False; - end; - if not ValidPicture then - begin - FPictureLabel.Caption := SPictureLabel; - FPreviewButton.Enabled := False; - FImageCtrl.Picture := nil; - FPaintPanel.Caption := srNone; - end; - end; - inherited; -end; - -procedure TTntOpenPictureDialog.DoShow; -var - PreviewRect, StaticRect: TRect; -begin - { Set preview area to entire dialog } - GetClientRect(Handle, PreviewRect); - StaticRect := GetStaticRect; - { Move preview area to right of static area } - PreviewRect.Left := StaticRect.Left + (StaticRect.Right - StaticRect.Left); - Inc(PreviewRect.Top, 4); - FPicturePanel.BoundsRect := PreviewRect; - FPreviewButton.Left := FPaintPanel.BoundsRect.Right - FPreviewButton.Width - 2; - FImageCtrl.Picture := nil; - FSavedFilename := ''; - FPaintPanel.Caption := srNone; - FPicturePanel.ParentWindow := Handle; - inherited; -end; - -function TTntOpenPictureDialog.Execute: Boolean; -begin - if NewStyleControls and not (ofOldStyleDialog in Options) then - Template := 'DLGTEMPLATE' else - Template := nil; - Result := inherited Execute; -end; - -{$IFDEF COMPILER_9_UP} -function TTntOpenPictureDialog.Execute(ParentWnd: HWND): Boolean; -begin - if NewStyleControls and not (ofOldStyleDialog in Options) then - Template := 'DLGTEMPLATE' else - Template := nil; - Result := inherited Execute(ParentWnd); -end; -{$ENDIF} - -function TTntOpenPictureDialog.IsFilterStored: Boolean; -begin - Result := not (Filter = GraphicFilter(TGraphic)); -end; - -procedure TTntOpenPictureDialog.PreviewClick(Sender: TObject); -var - PreviewForm: TTntForm; - Panel: TTntPanel; -begin - PreviewForm := TTntForm.Create(Self); - with PreviewForm do - try - Name := 'PreviewForm'; - BorderStyle := bsSizeToolWin; // By doing this first, it will work on WINE. - Visible := False; - Caption := SPreviewLabel; - KeyPreview := True; - Position := poScreenCenter; - OnKeyPress := PreviewKeyPress; - Panel := TTntPanel.Create(PreviewForm); - with Panel do - begin - Name := 'Panel'; - Caption := ''; - Align := alClient; - BevelOuter := bvNone; - BorderStyle := bsSingle; - BorderWidth := 5; - Color := clWindow; - Parent := PreviewForm; - DoubleBuffered := True; - with TTntImage.Create(PreviewForm) do - begin - Name := 'Image'; - Align := alClient; - Stretch := True; - Proportional := True; - Center := True; - Picture.Assign(FImageCtrl.Picture); - Parent := Panel; - end; - end; - if FImageCtrl.Picture.Width > 0 then - begin - ClientWidth := Min(Monitor.Width * 3 div 4, - FImageCtrl.Picture.Width + (ClientWidth - Panel.ClientWidth)+ 10); - ClientHeight := Min(Monitor.Height * 3 div 4, - FImageCtrl.Picture.Height + (ClientHeight - Panel.ClientHeight) + 10); - end; - ShowModal; - finally - Free; - end; -end; - -procedure TTntOpenPictureDialog.PreviewKeyPress(Sender: TObject; var Key: Char{TNT-ALLOW Char}); -begin - if Key = Char{TNT-ALLOW Char}(VK_ESCAPE) then - (Sender as TTntForm).Close; -end; - -{ TSavePictureDialog } -function TTntSavePictureDialog.Execute: Boolean; -begin - if NewStyleControls and not (ofOldStyleDialog in Options) then - Template := 'DLGTEMPLATE' else - Template := nil; - - if (not Win32PlatformIsUnicode) then - Result := DoExecute(@GetSaveFileNameA) - else - Result := DoExecuteW(@GetSaveFileNameW); -end; - -{$IFDEF COMPILER_9_UP} -function TTntSavePictureDialog.Execute(ParentWnd: HWND): Boolean; -begin - if NewStyleControls and not (ofOldStyleDialog in Options) then - Template := 'DLGTEMPLATE' else - Template := nil; - - if (not Win32PlatformIsUnicode) then - Result := DoExecute(@GetSaveFileNameA, ParentWnd) - else - Result := DoExecuteW(@GetSaveFileNameW, ParentWnd); -end; -{$ENDIF} - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntFileCtrl.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntFileCtrl.pas deleted file mode 100644 index d99517026..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntFileCtrl.pas +++ /dev/null @@ -1,118 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntFileCtrl; - -{$INCLUDE TntCompilers.inc} - -interface - -{$WARN UNIT_PLATFORM OFF} - -uses - Classes, Windows, FileCtrl; - -{TNT-WARN SelectDirectory} -function WideSelectDirectory(const Caption: WideString; const Root: WideString; - var Directory: WideString): Boolean; - -implementation - -uses - SysUtils, Forms, ActiveX, ShlObj, ShellApi, TntSysUtils, TntWindows; - -function SelectDirCB_W(Wnd: HWND; uMsg: UINT; lParam, lpData: LPARAM): Integer stdcall; -begin - if (uMsg = BFFM_INITIALIZED) and (lpData <> 0) then - SendMessageW(Wnd, BFFM_SETSELECTIONW, Integer(True), lpdata); - result := 0; -end; - -function WideSelectDirectory(const Caption: WideString; const Root: WideString; - var Directory: WideString): Boolean; -{$IFNDEF COMPILER_7_UP} -const - BIF_NEWDIALOGSTYLE = $0040; - BIF_USENEWUI = BIF_NEWDIALOGSTYLE or BIF_EDITBOX; -{$ENDIF} -var - WindowList: Pointer; - BrowseInfo: TBrowseInfoW; - Buffer: PWideChar; - OldErrorMode: Cardinal; - RootItemIDList, ItemIDList: PItemIDList; - ShellMalloc: IMalloc; - IDesktopFolder: IShellFolder; - Eaten, Flags: LongWord; - AnsiDirectory: AnsiString; -begin - if (not Win32PlatformIsUnicode) then begin - AnsiDirectory := Directory; - Result := SelectDirectory{TNT-ALLOW SelectDirectory}(Caption, Root, AnsiDirectory); - Directory := AnsiDirectory; - end else begin - Result := False; - if not WideDirectoryExists(Directory) then - Directory := ''; - FillChar(BrowseInfo, SizeOf(BrowseInfo), 0); - if (ShGetMalloc(ShellMalloc) = S_OK) and (ShellMalloc <> nil) then - begin - Buffer := ShellMalloc.Alloc(MAX_PATH * SizeOf(WideChar)); - try - RootItemIDList := nil; - if Root <> '' then - begin - SHGetDesktopFolder(IDesktopFolder); - IDesktopFolder.ParseDisplayName(Application.Handle, nil, - POleStr(Root), Eaten, RootItemIDList, Flags); - end; - with BrowseInfo do - begin - {$IFDEF COMPILER_9_UP} - hWndOwner := Application.ActiveFormHandle; - {$ELSE} - hWndOwner := Application.Handle; - {$ENDIF} - pidlRoot := RootItemIDList; - pszDisplayName := Buffer; - lpszTitle := PWideChar(Caption); - ulFlags := BIF_RETURNONLYFSDIRS; - if Win32MajorVersion >= 5 then - ulFlags := ulFlags or BIF_USENEWUI; - if Directory <> '' then - begin - lpfn := SelectDirCB_W; - lParam := Integer(PWideChar(Directory)); - end; - end; - WindowList := DisableTaskWindows(0); - OldErrorMode := SetErrorMode(SEM_FAILCRITICALERRORS); - try - ItemIDList := Tnt_ShBrowseForFolderW(BrowseInfo); - finally - SetErrorMode(OldErrorMode); - EnableTaskWindows(WindowList); - end; - Result := ItemIDList <> nil; - if Result then - begin - Tnt_ShGetPathFromIDListW(ItemIDList, Buffer); - ShellMalloc.Free(ItemIDList); - Directory := Buffer; - end; - finally - ShellMalloc.Free(Buffer); - end; - end; - end; -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntFormatStrUtils.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntFormatStrUtils.pas deleted file mode 100644 index 2b409e4ef..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntFormatStrUtils.pas +++ /dev/null @@ -1,503 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntFormatStrUtils; - -{$INCLUDE TntCompilers.inc} - -interface - -// this unit provides functions to work with format strings - -uses - TntSysUtils; - -function GetCanonicalFormatStr(const _FormatString: WideString): WideString; -{$IFNDEF COMPILER_9_UP} -function ReplaceFloatingArgumentsInFormatString(const _FormatString: WideString; - const Args: array of const - {$IFDEF COMPILER_7_UP}; FormatSettings: PFormatSettings{$ENDIF}): WideString; -{$ENDIF} -procedure CompareFormatStrings(FormatStr1, FormatStr2: WideString); -function FormatStringsAreCompatible(FormatStr1, FormatStr2: WideString): Boolean; - -type - EFormatSpecError = class(ETntGeneralError); - -implementation - -uses - SysUtils, Math, TntClasses; - -resourcestring - SInvalidFormatSpecifier = 'Invalid Format Specifier: %s'; - SMismatchedArgumentTypes = 'Argument types for index %d do not match. (%s <> %s)'; - SMismatchedArgumentCounts = 'Number of format specifiers do not match.'; - -type - TFormatSpecifierType = (fstInteger, fstFloating, fstPointer, fstString); - -function GetFormatSpecifierType(const FormatSpecifier: WideString): TFormatSpecifierType; -var - LastChar: WideChar; -begin - LastChar := TntWideLastChar(FormatSpecifier); - case LastChar of - 'd', 'D', 'u', 'U', 'x', 'X': - result := fstInteger; - 'e', 'E', 'f', 'F', 'g', 'G', 'n', 'N', 'm', 'M': - result := fstFloating; - 'p', 'P': - result := fstPointer; - 's', 'S': - result := fstString - else - raise ETntInternalError.CreateFmt('Internal Error: Unexpected format type (%s)', [LastChar]); - end; -end; - -type - TFormatStrParser = class(TObject) - private - ParsedString: TBufferedWideString; - PFormatString: PWideChar; - LastIndex: Integer; - ExplicitCount: Integer; - ImplicitCount: Integer; - procedure RaiseInvalidFormatSpecifier; - function ParseChar(c: WideChar): Boolean; - procedure ForceParseChar(c: WideChar); - function ParseDigit: Boolean; - function ParseInteger: Boolean; - procedure ForceParseType; - function PeekDigit: Boolean; - function PeekIndexSpecifier(out Index: Integer): Boolean; - public - constructor Create(const _FormatString: WideString); - destructor Destroy; override; - function ParseFormatSpecifier: Boolean; - end; - -constructor TFormatStrParser.Create(const _FormatString: WideString); -begin - inherited Create; - PFormatString := PWideChar(_FormatString); - ExplicitCount := 0; - ImplicitCount := 0; - LastIndex := -1; - ParsedString := TBufferedWideString.Create; -end; - -destructor TFormatStrParser.Destroy; -begin - FreeAndNil(ParsedString); - inherited; -end; - -procedure TFormatStrParser.RaiseInvalidFormatSpecifier; -begin - raise EFormatSpecError.CreateFmt(SInvalidFormatSpecifier, [ParsedString.Value + PFormatString]); -end; - -function TFormatStrParser.ParseChar(c: WideChar): Boolean; -begin - result := False; - if PFormatString^ = c then begin - result := True; - ParsedString.AddChar(c); - Inc(PFormatString); - end; -end; - -procedure TFormatStrParser.ForceParseChar(c: WideChar); -begin - if not ParseChar(c) then - RaiseInvalidFormatSpecifier; -end; - -function TFormatStrParser.PeekDigit: Boolean; -begin - result := False; - if (PFormatString^ <> #0) - and (PFormatString^ >= '0') - and (PFormatString^ <= '9') then - result := True; -end; - -function TFormatStrParser.ParseDigit: Boolean; -begin - result := False; - if PeekDigit then begin - result := True; - ForceParseChar(PFormatString^); - end; -end; - -function TFormatStrParser.ParseInteger: Boolean; -const - MAX_INT_DIGITS = 6; -var - digitcount: integer; -begin - digitcount := 0; - While ParseDigit do begin - inc(digitcount); - end; - result := (digitcount > 0); - if digitcount > MAX_INT_DIGITS then - RaiseInvalidFormatSpecifier; -end; - -procedure TFormatStrParser.ForceParseType; -begin - if PFormatString^ = #0 then - RaiseInvalidFormatSpecifier; - - case PFormatString^ of - 'd', 'u', 'x', 'e', 'f', 'g', 'n', 'm', 'p', 's', - 'D', 'U', 'X', 'E', 'F', 'G', 'N', 'M', 'P', 'S': - begin - // do nothing - end - else - RaiseInvalidFormatSpecifier; - end; - ForceParseChar(PFormatString^); -end; - -function TFormatStrParser.PeekIndexSpecifier(out Index: Integer): Boolean; -var - SaveParsedString: WideString; - SaveFormatString: PWideChar; -begin - SaveParsedString := ParsedString.Value; - SaveFormatString := PFormatString; - try - ParsedString.Clear; - Result := False; - Index := -1; - if ParseInteger then begin - Index := StrToInt(ParsedString.Value); - if ParseChar(':') then - Result := True; - end; - finally - ParsedString.Clear; - ParsedString.AddString(SaveParsedString); - PFormatString := SaveFormatString; - end; -end; - -function TFormatStrParser.ParseFormatSpecifier: Boolean; -var - ExplicitIndex: Integer; -begin - Result := False; - // Parse entire format specifier - ForceParseChar('%'); - if (PFormatString^ <> #0) - and (not ParseChar(' ')) - and (not ParseChar('%')) then begin - if PeekIndexSpecifier(ExplicitIndex) then begin - Inc(ExplicitCount); - LastIndex := Max(LastIndex, ExplicitIndex); - end else begin - Inc(ImplicitCount); - Inc(LastIndex); - ParsedString.AddString(IntToStr(LastIndex)); - ParsedString.AddChar(':'); - end; - if ParseChar('*') then - begin - Inc(ImplicitCount); - Inc(LastIndex); - ParseChar(':'); - end else if ParseInteger then - ParseChar(':'); - ParseChar('-'); - if ParseChar('*') then begin - Inc(ImplicitCount); - Inc(LastIndex); - end else - ParseInteger; - if ParseChar('.') then begin - if not ParseChar('*') then - ParseInteger; - end; - ForceParseType; - Result := True; - end; -end; - -//----------------------------------- - -function GetCanonicalFormatStr(const _FormatString: WideString): WideString; -var - PosSpec: Integer; -begin - with TFormatStrParser.Create(_FormatString) do - try - // loop until no more '%' - PosSpec := Pos('%', PFormatString); - While PosSpec <> 0 do begin - try - // delete everything up until '%' - ParsedString.AddBuffer(PFormatString, PosSpec - 1); - Inc(PFormatString, PosSpec - 1); - // parse format specifier - ParseFormatSpecifier; - finally - PosSpec := Pos('%', PFormatString); - end; - end; - if ((ExplicitCount = 0) and (ImplicitCount = 1)) {simple expression} - or ((ExplicitCount > 0) and (ImplicitCount = 0)) {nothing converted} then - result := _FormatString {original} - else - result := ParsedString.Value + PFormatString; - finally - Free; - end; -end; - -{$IFNDEF COMPILER_9_UP} -function ReplaceFloatingArgumentsInFormatString(const _FormatString: WideString; - const Args: array of const - {$IFDEF COMPILER_7_UP}; FormatSettings: PFormatSettings{$ENDIF}): WideString; -{ This function replaces floating point format specifiers with their actual formatted values. - It also adds index specifiers so that the other format specifiers don't lose their place. - The reason for this is that WideFormat doesn't correctly format floating point specifiers. - See QC#4254. } -var - Parser: TFormatStrParser; - PosSpec: Integer; - Output: TBufferedWideString; -begin - Output := TBufferedWideString.Create; - try - Parser := TFormatStrParser.Create(_FormatString); - with Parser do - try - // loop until no more '%' - PosSpec := Pos('%', PFormatString); - While PosSpec <> 0 do begin - try - // delete everything up until '%' - Output.AddBuffer(PFormatString, PosSpec - 1); - Inc(PFormatString, PosSpec - 1); - // parse format specifier - ParsedString.Clear; - if (not ParseFormatSpecifier) - or (GetFormatSpecifierType(ParsedString.Value) <> fstFloating) then - Output.AddBuffer(ParsedString.BuffPtr, MaxInt) - {$IFDEF COMPILER_7_UP} - else if Assigned(FormatSettings) then - Output.AddString(Format{TNT-ALLOW Format}(ParsedString.Value, Args, FormatSettings^)) - {$ENDIF} - else - Output.AddString(Format{TNT-ALLOW Format}(ParsedString.Value, Args)); - finally - PosSpec := Pos('%', PFormatString); - end; - end; - Output.AddString(PFormatString); - finally - Free; - end; - Result := Output.Value; - finally - Output.Free; - end; -end; -{$ENDIF} - -procedure GetFormatArgs(const _FormatString: WideString; FormatArgs: TTntStrings); -var - PosSpec: Integer; -begin - with TFormatStrParser.Create(_FormatString) do - try - FormatArgs.Clear; - // loop until no more '%' - PosSpec := Pos('%', PFormatString); - While PosSpec <> 0 do begin - try - // delete everything up until '%' - Inc(PFormatString, PosSpec - 1); - // add format specifier to list - ParsedString.Clear; - if ParseFormatSpecifier then - FormatArgs.Add(ParsedString.Value); - finally - PosSpec := Pos('%', PFormatString); - end; - end; - finally - Free; - end; -end; - -function GetExplicitIndex(const FormatSpecifier: WideString): Integer; -var - IndexStr: WideString; - PosColon: Integer; -begin - result := -1; - PosColon := Pos(':', FormatSpecifier); - if PosColon <> 0 then begin - IndexStr := Copy(FormatSpecifier, 2, PosColon - 2); - result := StrToInt(IndexStr); - end; -end; - -function GetMaxIndex(FormatArgs: TTntStrings): Integer; -var - i: integer; - RunningIndex: Integer; - ExplicitIndex: Integer; -begin - result := -1; - RunningIndex := -1; - for i := 0 to FormatArgs.Count - 1 do begin - ExplicitIndex := GetExplicitIndex(FormatArgs[i]); - if ExplicitIndex <> -1 then - RunningIndex := ExplicitIndex - else - inc(RunningIndex); - result := Max(result, RunningIndex); - end; -end; - -procedure UpdateTypeList(FormatArgs, TypeList: TTntStrings); -var - i: integer; - f: WideString; - SpecType: TFormatSpecifierType; - ExplicitIndex: Integer; - MaxIndex: Integer; - RunningIndex: Integer; -begin - // set count of TypeList to accomodate maximum index - MaxIndex := GetMaxIndex(FormatArgs); - TypeList.Clear; - for i := 0 to MaxIndex do - TypeList.Add(''); - - // for each arg... - RunningIndex := -1; - for i := 0 to FormatArgs.Count - 1 do begin - f := FormatArgs[i]; - ExplicitIndex := GetExplicitIndex(f); - SpecType := GetFormatSpecifierType(f); - - // determine running arg index - if ExplicitIndex <> -1 then - RunningIndex := ExplicitIndex - else - inc(RunningIndex); - - if TypeList[RunningIndex] <> '' then begin - // already exists in list, check for compatibility - if TypeList.Objects[RunningIndex] <> TObject(SpecType) then - raise EFormatSpecError.CreateFmt(SMismatchedArgumentTypes, - [RunningIndex, TypeList[RunningIndex], f]); - end else begin - // not in list so update it - TypeList[RunningIndex] := f; - TypeList.Objects[RunningIndex] := TObject(SpecType); - end; - end; -end; - -procedure CompareFormatStrings(FormatStr1, FormatStr2: WideString); -var - ArgList1: TTntStringList; - ArgList2: TTntStringList; - TypeList1: TTntStringList; - TypeList2: TTntStringList; - i: integer; -begin - ArgList1 := nil; - ArgList2 := nil; - TypeList1 := nil; - TypeList2 := nil; - try - ArgList1 := TTntStringList.Create; - ArgList2 := TTntStringList.Create; - TypeList1 := TTntStringList.Create; - TypeList2 := TTntStringList.Create; - - GetFormatArgs(FormatStr1, ArgList1); - UpdateTypeList(ArgList1, TypeList1); - - GetFormatArgs(FormatStr2, ArgList2); - UpdateTypeList(ArgList2, TypeList2); - - if TypeList1.Count <> TypeList2.Count then - raise EFormatSpecError.Create(SMismatchedArgumentCounts + CRLF + CRLF + '> ' + FormatStr1 + CRLF + '> ' + FormatStr2); - - for i := 0 to TypeList1.Count - 1 do begin - if TypeList1.Objects[i] <> TypeList2.Objects[i] then begin - raise EFormatSpecError.CreateFmt(SMismatchedArgumentTypes, - [i, TypeList1[i], TypeList2[i]]); - end; - end; - - finally - ArgList1.Free; - ArgList2.Free; - TypeList1.Free; - TypeList2.Free; - end; -end; - -function FormatStringsAreCompatible(FormatStr1, FormatStr2: WideString): Boolean; -var - ArgList1: TTntStringList; - ArgList2: TTntStringList; - TypeList1: TTntStringList; - TypeList2: TTntStringList; - i: integer; -begin - ArgList1 := nil; - ArgList2 := nil; - TypeList1 := nil; - TypeList2 := nil; - try - ArgList1 := TTntStringList.Create; - ArgList2 := TTntStringList.Create; - TypeList1 := TTntStringList.Create; - TypeList2 := TTntStringList.Create; - - GetFormatArgs(FormatStr1, ArgList1); - UpdateTypeList(ArgList1, TypeList1); - - GetFormatArgs(FormatStr2, ArgList2); - UpdateTypeList(ArgList2, TypeList2); - - Result := (TypeList1.Count = TypeList2.Count); - if Result then begin - for i := 0 to TypeList1.Count - 1 do begin - if TypeList1.Objects[i] <> TypeList2.Objects[i] then begin - Result := False; - break; - end; - end; - end; - finally - ArgList1.Free; - ArgList2.Free; - TypeList1.Free; - TypeList2.Free; - end; -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntForms.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntForms.pas deleted file mode 100644 index db9d64c61..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntForms.pas +++ /dev/null @@ -1,954 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntForms; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Windows, Messages, SysUtils, Classes, Controls, Forms, TntControls; - -type -{TNT-WARN TScrollBox} - TTntScrollBox = class(TScrollBox{TNT-ALLOW TScrollBox}) - private - FWMSizeCallCount: Integer; - function IsHintStored: Boolean; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - procedure WMSize(var Message: TWMSize); message WM_SIZE; - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TCustomFrame} - TTntCustomFrame = class(TCustomFrame{TNT-ALLOW TCustomFrame}) - private - function IsHintStored: Boolean; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TFrame} - TTntFrame = class(TTntCustomFrame) - published - property Align; - property Anchors; - property AutoScroll; - property AutoSize; - property BiDiMode; - property Constraints; - property DockSite; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property Color nodefault; - property Ctl3D; - property Font; - {$IFDEF COMPILER_10_UP} - property Padding; - {$ENDIF} - {$IFDEF COMPILER_7_UP} - property ParentBackground default True; - {$ENDIF} - property ParentBiDiMode; - property ParentColor; - property ParentCtl3D; - property ParentFont; - property ParentShowHint; - property PopupMenu; - property ShowHint; - property TabOrder; - property TabStop; - property Visible; - {$IFDEF COMPILER_9_UP} - property OnAlignInsertBefore; - property OnAlignPosition; - {$ENDIF} - property OnCanResize; - property OnClick; - property OnConstrainedResize; - property OnContextPopup; - property OnDblClick; - property OnDockDrop; - property OnDockOver; - property OnDragDrop; - property OnDragOver; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnGetSiteInfo; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - property OnMouseWheel; - property OnMouseWheelDown; - property OnMouseWheelUp; - property OnResize; - property OnStartDock; - property OnStartDrag; - property OnUnDock; - end; - -{TNT-WARN TForm} - TTntForm = class(TForm{TNT-ALLOW TForm}) - private - function GetCaption: TWideCaption; - procedure SetCaption(const Value: TWideCaption); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsCaptionStored: Boolean; - function IsHintStored: Boolean; - procedure WMMenuSelect(var Message: TWMMenuSelect); message WM_MENUSELECT; - procedure CMBiDiModeChanged(var Message: TMessage); message CM_BIDIMODECHANGED; - procedure WMWindowPosChanging(var Message: TMessage); message WM_WINDOWPOSCHANGING; - protected - procedure UpdateActions; override; - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DestroyWindowHandle; override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - function CreateDockManager: IDockManager; override; - public - constructor Create(AOwner: TComponent); override; - procedure DefaultHandler(var Message); override; - published - property Caption: TWideCaption read GetCaption write SetCaption stored IsCaptionStored; - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - - TTntApplication = class(TComponent) - private - FMainFormChecked: Boolean; - FHint: WideString; - FTntAppIdleEventControl: TControl; - FSettingChangeTime: Cardinal; - FTitle: WideString; - function GetHint: WideString; - procedure SetAnsiAppHint(const Value: AnsiString); - procedure SetHint(const Value: WideString); - function GetExeName: WideString; - function IsDlgMsg(var Msg: TMsg): Boolean; - procedure DoIdle; - function GetTitle: WideString; - procedure SetTitle(const Value: WideString); - procedure SetAnsiApplicationTitle(const Value: AnsiString); - function ApplicationMouseControlHint: WideString; - protected - function WndProc(var Message: TMessage): Boolean; - function ProcessMessage(var Msg: TMsg): Boolean; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - function MessageBox(const Text, Caption: PWideChar; Flags: Longint): Integer; - procedure ShowException(E: Exception); - property Hint: WideString read GetHint write SetHint; - property ExeName: WideString read GetExeName; - property SettingChangeTime: Cardinal read FSettingChangeTime; - property Title: WideString read GetTitle write SetTitle; - end; - -{TNT-WARN IsAccel} -function IsWideCharAccel(CharCode: Word; const Caption: WideString): Boolean; - -{TNT-WARN PeekMessage} -{TNT-WARN PeekMessageA} -{TNT-WARN PeekMessageW} -procedure EnableManualPeekMessageWithRemove; -procedure DisableManualPeekMessageWithRemove; - -type - TFormProc = procedure (Form: TForm{TNT-ALLOW TForm}); - -var - TntApplication: TTntApplication; - -procedure InitTntEnvironment; - -implementation - -uses - Consts, RTLConsts, Menus, FlatSB, StdActns, Graphics, MultiMon, - TntSystem, TntSysUtils, TntMenus, TntActnList, TntStdActns, TntClasses; - -function IsWideCharAccel(CharCode: Word; const Caption: WideString): Boolean; -var - W: WideChar; -begin - W := KeyUnicode(CharCode); - Result := WideSameText(W, WideGetHotKey(Caption)); -end; - -{ TTntScrollBox } - -procedure TTntScrollBox.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, ''); -end; - -procedure TTntScrollBox.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntScrollBox.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntScrollBox.GetHint: WideString; -begin - Result := TntControl_GetHint(Self); -end; - -procedure TTntScrollBox.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntScrollBox.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntScrollBox.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -procedure TTntScrollBox.WMSize(var Message: TWMSize); -begin - Inc(FWMSizeCallCount); - try - if FWMSizeCallCount < 32 then { Infinite recursion was encountered on Win 9x. } - inherited; - finally - Dec(FWMSizeCallCount); - end; -end; - -{ TTntCustomFrame } - -procedure TTntCustomFrame.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, ''); -end; - -procedure TTntCustomFrame.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntCustomFrame.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntCustomFrame.GetHint: WideString; -begin - Result := TntControl_GetHint(Self); -end; - -procedure TTntCustomFrame.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntCustomFrame.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomFrame.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntForm } - -constructor TTntForm.Create(AOwner: TComponent); -begin - // standard construction technique (look at TForm.Create) - GlobalNameSpace.BeginWrite; - try - CreateNew(AOwner); - if (ClassType <> TTntForm) and not (csDesigning in ComponentState) then - begin - Include(FFormState, fsCreating); - try - if not InitInheritedComponent(Self, TTntForm) then - raise EResNotFound.CreateFmt(SResNotFound, [ClassName]); - finally - Exclude(FFormState, fsCreating); - end; - if OldCreateOrder then DoCreate; - end; - finally - GlobalNameSpace.EndWrite; - end; -end; - -procedure TTntForm.CreateWindowHandle(const Params: TCreateParams); -var - NewParams: TCreateParams; - WideWinClassName: WideString; -begin - if (not Win32PlatformIsUnicode) then - inherited - else if (FormStyle = fsMDIChild) and not (csDesigning in ComponentState) then - begin - if (Application.MainForm = nil) or - (Application.MainForm.ClientHandle = 0) then - raise EInvalidOperation.Create(SNoMDIForm); - RegisterUnicodeClass(Params, WideWinClassName); - DefWndProc := @DefMDIChildProcW; - WindowHandle := CreateMDIWindowW(PWideChar(WideWinClassName), - nil, Params.style, Params.X, Params.Y, Params.Width, Params.Height, - Application.MainForm.ClientHandle, hInstance, Longint(Params.Param)); - if WindowHandle = 0 then - RaiseLastOSError; - SubClassUnicodeControl(Self, Params.Caption); - Include(FFormState, fsCreatedMDIChild); - end else - begin - NewParams := Params; - NewParams.ExStyle := NewParams.ExStyle and not WS_EX_LAYERED; - CreateUnicodeHandle(Self, NewParams, ''); - Exclude(FFormState, fsCreatedMDIChild); - end; - if AlphaBlend then begin - // toggle AlphaBlend to force update - AlphaBlend := False; - AlphaBlend := True; - end else if TransparentColor then begin - // toggle TransparentColor to force update - TransparentColor := False; - TransparentColor := True; - end; -end; - -procedure TTntForm.DestroyWindowHandle; -begin - if Win32PlatformIsUnicode then - UninitializeFlatSB(Handle); { Bug in VCL: Without this there might be a resource leak. } - inherited; -end; - -procedure TTntForm.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -procedure TTntForm.DefaultHandler(var Message); -begin - if (ClientHandle <> 0) - and (Win32PlatformIsUnicode) then begin - with TMessage(Message) do begin - if (Msg = WM_SIZE) then - Result := DefWindowProcW(Handle, Msg, wParam, lParam) - else - Result := DefFrameProcW(Handle, ClientHandle, Msg, wParam, lParam); - if (Msg = WM_DESTROY) then - Perform(TNT_WM_DESTROY, 0, 0); { This ensures that the control is Unsubclassed. } - end; - end else - inherited DefaultHandler(Message); -end; - -function TTntForm.IsCaptionStored: Boolean; -begin - Result := TntControl_IsCaptionStored(Self); -end; - -function TTntForm.GetCaption: TWideCaption; -begin - Result := TntControl_GetText(Self) -end; - -procedure TTntForm.SetCaption(const Value: TWideCaption); -begin - TntControl_SetText(Self, Value) -end; - -function TTntForm.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntForm.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntForm.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntForm.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntForm.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -procedure TTntForm.WMMenuSelect(var Message: TWMMenuSelect); -var - MenuItem: TMenuItem{TNT-ALLOW TMenuItem}; - ID: Integer; - FindKind: TFindItemKind; -begin - if Menu <> nil then - with Message do - begin - MenuItem := nil; - if (MenuFlag <> $FFFF) or (IDItem <> 0) then - begin - FindKind := fkCommand; - ID := IDItem; - if MenuFlag and MF_POPUP <> 0 then - begin - FindKind := fkHandle; - ID := Integer(GetSubMenu(Menu, ID)); - end; - MenuItem := Self.Menu.FindItem(ID, FindKind); - end; - if MenuItem <> nil then - TntApplication.Hint := WideGetLongHint(WideGetMenuItemHint(MenuItem)) - else - TntApplication.Hint := ''; - end; -end; - -procedure TTntForm.UpdateActions; -begin - inherited; - TntApplication.DoIdle; -end; - -procedure TTntForm.CMBiDiModeChanged(var Message: TMessage); -var - Loop: Integer; -begin - inherited; - for Loop := 0 to ComponentCount - 1 do - if Components[Loop] is TMenu then - FixMenuBiDiProblem(TMenu(Components[Loop])); -end; - -procedure TTntForm.WMWindowPosChanging(var Message: TMessage); -begin - inherited; - // This message *sometimes* means that the Menu.BiDiMode changed. - FixMenuBiDiProblem(Menu); -end; - -function TTntForm.CreateDockManager: IDockManager; -begin - if (DockManager = nil) and DockSite and UseDockManager then - HandleNeeded; // force TNT subclassing to occur first - Result := inherited CreateDockManager; -end; - -{ TTntApplication } - -constructor TTntApplication.Create(AOwner: TComponent); -begin - inherited; - Application.HookMainWindow(WndProc); - FSettingChangeTime := GetTickCount; - TntSysUtils._SettingChangeTime := GetTickCount; -end; - -destructor TTntApplication.Destroy; -begin - FreeAndNil(FTntAppIdleEventControl); - Application.UnhookMainWindow(WndProc); - inherited; -end; - -function TTntApplication.GetHint: WideString; -begin - // check to see if the hint has already been set on application.idle - if Application.Hint = AnsiString(ApplicationMouseControlHint) then - FHint := ApplicationMouseControlHint; - // get the synced string - Result := GetSyncedWideString(FHint, Application.Hint) -end; - -procedure TTntApplication.SetAnsiAppHint(const Value: AnsiString); -begin - Application.Hint := Value; -end; - -procedure TTntApplication.SetHint(const Value: WideString); -begin - SetSyncedWideString(Value, FHint, Application.Hint, SetAnsiAppHint); -end; - -function TTntApplication.GetExeName: WideString; -begin - Result := WideParamStr(0); -end; - -function TTntApplication.GetTitle: WideString; -begin - if (Application.Handle <> 0) and Win32PlatformIsUnicode then begin - SetLength(Result, DefWindowProcW(Application.Handle, WM_GETTEXTLENGTH, 0, 0) + 1); - DefWindowProcW(Application.Handle, WM_GETTEXT, Length(Result), Integer(PWideChar(Result))); - SetLength(Result, Length(Result) - 1); - end else - Result := GetSyncedWideString(FTitle, Application.Title); -end; - -procedure TTntApplication.SetAnsiApplicationTitle(const Value: AnsiString); -begin - Application.Title := Value; -end; - -procedure TTntApplication.SetTitle(const Value: WideString); -begin - if (Application.Handle <> 0) and Win32PlatformIsUnicode then begin - if (GetTitle <> Value) or (FTitle <> '') then begin - DefWindowProcW(Application.Handle, WM_SETTEXT, 0, lParam(PWideChar(Value))); - FTitle := ''; - end - end else - SetSyncedWideString(Value, FTitle, Application.Title, SetAnsiApplicationTitle); -end; - -{$IFDEF COMPILER_6} // verified against VCL source in Delphi 6 and BCB 6 -type - THackApplication = class(TComponent) - protected - FxxxxxxxxxHandle: HWnd; - FxxxxxxxxxBiDiMode: TBiDiMode; - FxxxxxxxxxBiDiKeyboard: AnsiString; - FxxxxxxxxxNonBiDiKeyboard: AnsiString; - FxxxxxxxxxObjectInstance: Pointer; - FxxxxxxxxxMainForm: TForm{TNT-ALLOW TForm}; - FMouseControl: TControl; - end; -{$ENDIF} -{$IFDEF DELPHI_7} // verified against VCL source in Delphi 7 -type - THackApplication = class(TComponent) - protected - FxxxxxxxxxHandle: HWnd; - FxxxxxxxxxBiDiMode: TBiDiMode; - FxxxxxxxxxBiDiKeyboard: AnsiString; - FxxxxxxxxxNonBiDiKeyboard: AnsiString; - FxxxxxxxxxObjectInstance: Pointer; - FxxxxxxxxxMainForm: TForm{TNT-ALLOW TForm}; - FMouseControl: TControl; - end; -{$ENDIF} -{$IFDEF DELPHI_9} // verified against VCL source in Delphi 9 -type - THackApplication = class(TComponent) - protected - FxxxxxxxxxHandle: HWnd; - FxxxxxxxxxBiDiMode: TBiDiMode; - FxxxxxxxxxBiDiKeyboard: AnsiString; - FxxxxxxxxxNonBiDiKeyboard: AnsiString; - FxxxxxxxxxObjectInstance: Pointer; - FxxxxxxxxxMainForm: TForm{TNT-ALLOW TForm}; - FMouseControl: TControl; - end; -{$ENDIF} -{$IFDEF DELPHI_10} // verified against VCL source in Delphi 10 -type - THackApplication = class(TComponent) - protected - FxxxxxxxxxHandle: HWnd; - FxxxxxxxxxBiDiMode: TBiDiMode; - FxxxxxxxxxBiDiKeyboard: AnsiString; - FxxxxxxxxxNonBiDiKeyboard: AnsiString; - FxxxxxxxxxObjectInstance: Pointer; - FxxxxxxxxxMainForm: TForm{TNT-ALLOW TForm}; - FMouseControl: TControl; - end; -{$ENDIF} - -function TTntApplication.ApplicationMouseControlHint: WideString; -var - MouseControl: TControl; -begin - MouseControl := THackApplication(Application).FMouseControl; - Result := WideGetLongHint(WideGetHint(MouseControl)); -end; - -procedure TTntApplication.DoIdle; -begin - // update TntApplication.Hint only when Ansi encodings are the same... (otherwise there are problems with action menus) - if Application.Hint = AnsiString(ApplicationMouseControlHint) then - Hint := ApplicationMouseControlHint; -end; - -function TTntApplication.IsDlgMsg(var Msg: TMsg): Boolean; -begin - Result := False; - if (Application.DialogHandle <> 0) then begin - if IsWindowUnicode(Application.DialogHandle) then - Result := IsDialogMessageW(Application.DialogHandle, Msg) - else - Result := IsDialogMessageA(Application.DialogHandle, Msg); - end; -end; - -type - TTntAppIdleEventControl = class(TControl) - protected - procedure OnIdle(Sender: TObject); - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - end; - -constructor TTntAppIdleEventControl.Create(AOwner: TComponent); -begin - inherited; - ParentFont := False; { This allows Parent (Application) to be in another module. } - Parent := Application.MainForm; - Visible := True; - Action := TTntAction.Create(Self); - Action.OnExecute := OnIdle; - Action.OnUpdate := OnIdle; - TntApplication.FTntAppIdleEventControl := Self; -end; - -destructor TTntAppIdleEventControl.Destroy; -begin - if TntApplication <> nil then - TntApplication.FTntAppIdleEventControl := nil; - inherited; -end; - -procedure TTntAppIdleEventControl.OnIdle(Sender: TObject); -begin - TntApplication.DoIdle; -end; - -function TTntApplication.ProcessMessage(var Msg: TMsg): Boolean; -var - Handled: Boolean; -begin - Result := False; - // Check Main Form - if (not FMainFormChecked) and (Application.MainForm <> nil) then begin - if not (Application.MainForm is TTntForm) then begin - // This control will help ensure that DoIdle is called - TTntAppIdleEventControl.Create(Application.MainForm); - end; - FMainFormChecked := True; - end; - // Check for Unicode char messages - if (Msg.message = WM_CHAR) - and (Msg.wParam > Integer(High(AnsiChar))) - and IsWindowUnicode(Msg.hwnd) - and ((Application.DialogHandle = 0) or IsWindowUnicode(Application.DialogHandle)) - then begin - Result := True; - // more than 8-bit WM_CHAR destined for Unicode window - Handled := False; - if Assigned(Application.OnMessage) then - Application.OnMessage(Msg, Handled); - Application.CancelHint; - // dispatch msg if not a dialog message - if (not Handled) and (not IsDlgMsg(Msg)) then - DispatchMessageW(Msg); - end; -end; - -function TTntApplication.WndProc(var Message: TMessage): Boolean; -var - BasicAction: TBasicAction; -begin - Result := False; { not handled } - if (Message.Msg = WM_SETTINGCHANGE) then begin - FSettingChangeTime := GetTickCount; - TntSysUtils._SettingChangeTime := FSettingChangeTime; - end; - if (Message.Msg = WM_CREATE) - and (FTitle <> '') then begin - SetTitle(FTitle); - FTitle := ''; - end; - if (Message.Msg = CM_ACTIONEXECUTE) then begin - BasicAction := TBasicAction(Message.LParam); - if (BasicAction.ClassType = THintAction{TNT-ALLOW THintAction}) - and (THintAction{TNT-ALLOW THintAction}(BasicAction).Hint = AnsiString(Hint)) - then begin - Result := True; - Message.Result := 1; - with TTntHintAction.Create(Self) do - begin - Hint := Self.Hint; - try - Execute; - finally - Free; - end; - end; - end; - end; -end; - -function TTntApplication.MessageBox(const Text, Caption: PWideChar; - Flags: Integer): Integer; -var - ActiveWindow, TaskActiveWindow: HWnd; - WindowList: Pointer; - MBMonitor, AppMonitor: HMonitor; - MonInfo: TMonitorInfo; - Rect: TRect; - FocusState: TFocusState; -begin - with Application do - begin -{$IFDEF DELPHI_9_UP} - ActiveWindow := ActiveFormHandle; -{$ELSE} - ActiveWindow := GetActiveWindow; - if ActiveWindow = 0 then - ActiveWindow := GetLastActivePopup(Handle); -{$ENDIF} - if ActiveWindow = 0 then - TaskActiveWindow := Handle - else - TaskActiveWindow := ActiveWindow; - MBMonitor := MonitorFromWindow(ActiveWindow, MONITOR_DEFAULTTONEAREST); - AppMonitor := MonitorFromWindow(Handle, MONITOR_DEFAULTTONEAREST); - if MBMonitor <> AppMonitor then - begin - MonInfo.cbSize := Sizeof(TMonitorInfo); - GetMonitorInfo(MBMonitor, @MonInfo); - GetWindowRect(Handle, Rect); - SetWindowPos(Handle, 0, - MonInfo.rcMonitor.Left + ((MonInfo.rcMonitor.Right - MonInfo.rcMonitor.Left) div 2), - MonInfo.rcMonitor.Top + ((MonInfo.rcMonitor.Bottom - MonInfo.rcMonitor.Top) div 2), - 0, 0, SWP_NOACTIVATE or SWP_NOREDRAW or SWP_NOSIZE or SWP_NOZORDER); - end; - WindowList := DisableTaskWindows(ActiveWindow); - FocusState := SaveFocusState; - if UseRightToLeftReading then Flags := Flags or MB_RTLREADING; - try - Result := Windows.MessageBoxW(TaskActiveWindow, Text, Caption, Flags); - finally - if MBMonitor <> AppMonitor then - SetWindowPos(Handle, 0, - Rect.Left + ((Rect.Right - Rect.Left) div 2), - Rect.Top + ((Rect.Bottom - Rect.Top) div 2), - 0, 0, SWP_NOACTIVATE or SWP_NOREDRAW or SWP_NOSIZE or SWP_NOZORDER); - EnableTaskWindows(WindowList); - SetActiveWindow(ActiveWindow); - RestoreFocusState(FocusState); - end; - end; -end; - -procedure TTntApplication.ShowException(E: Exception); -var - Msg: WideString; -begin - // Because of OverwriteProcedure call in TntSystem-unit, Self could point - // to a TApplication instance instead of a TTntApplication instance, thus - // causing access violations. Therefore frame the whole code with a - // "with TntApplication do"-statement. - - with TntApplication do - begin - if E is WideException then - begin - Msg := WideException(E).Message; - if (Msg <> '') and (TntWideLastChar(Msg) > '.') then Msg := Msg + '.'; - MessageBox(PWideChar(Msg), PWideChar(Title), MB_OK + MB_ICONSTOP); - end - else - begin - Msg := Exception(E).Message; - if (Msg <> '') and (TntWideLastChar(Msg) > '.') then Msg := Msg + '.'; - MessageBox(PWideChar(Msg), PWideChar(Title), MB_OK + MB_ICONSTOP); - end - end -end; - -//=========================================================================== -// The NT GetMessage Hook is needed to support entering Unicode -// characters directly from the keyboard (bypassing the IME). -// Special thanks go to Francisco Leong for developing this solution. -// -// Example: -// 1. Install "Turkic" language support. -// 2. Add "Azeri (Latin)" as an input locale. -// 3. In an EDIT, enter Shift+I. (You should see a capital "I" with dot.) -// 4. In an EDIT, enter single quote (US Keyboard). (You should see an upturned "e".) -// -var - ManualPeekMessageWithRemove: Integer = 0; - -procedure EnableManualPeekMessageWithRemove; -begin - Inc(ManualPeekMessageWithRemove); -end; - -procedure DisableManualPeekMessageWithRemove; -begin - if (ManualPeekMessageWithRemove > 0) then - Dec(ManualPeekMessageWithRemove); -end; - -var - NTGetMessageHook: HHOOK; - -function GetMessageForNT(Code: Integer; wParam: Integer; lParam: Integer): LRESULT; stdcall; -var - ThisMsg: PMSG; -begin - if (Code >= 0) - and (wParam = PM_REMOVE) - and (ManualPeekMessageWithRemove = 0) then - begin - ThisMsg := PMSG(lParam); - if (TntApplication <> nil) - and TntApplication.ProcessMessage(ThisMsg^) then - ThisMsg.message := WM_NULL; { clear for further processing } - end; - Result := CallNextHookEx(NTGetMessageHook, Code, wParam, lParam); -end; - -procedure CreateGetMessageHookForNT; -begin - Assert(Win32Platform = VER_PLATFORM_WIN32_NT); - NTGetMessageHook := SetWindowsHookExW(WH_GETMESSAGE, GetMessageForNT, 0, GetCurrentThreadID); - if NTGetMessageHook = 0 then - RaiseLastOSError; -end; - -//--------------------------------------------------------------------------------------------- -// Tnt Environment Setup -//--------------------------------------------------------------------------------------------- - -procedure InitTntEnvironment; - - function GetDefaultFont: WideString; - - function RunningUnderIDE: Boolean; - begin - Result := ModuleIsPackage and - ( WideSameText(WideExtractFileName(WideGetModuleFileName(0)), 'bds.exe') - or WideSameText(WideExtractFileName(WideGetModuleFileName(0)), 'delphi32.exe') - or WideSameText(WideExtractFileName(WideGetModuleFileName(0)), 'bcb.exe')); - end; - - function GetProfileStr(const Section, Key, Default: AnsiString; MaxLen: Integer): AnsiString; - var - Len: Integer; - begin - SetLength(Result, MaxLen + 1); - Len := GetProfileString(PAnsiChar(Section), PAnsiChar(Key), PAnsiChar(Default), - PAnsiChar(Result), Length(Result)); - SetLength(Result, Len); - end; - - procedure SetProfileStr(const Section, Key, Value: AnsiString); - var - DummyResult: Cardinal; - begin - try - Win32Check(WriteProfileString(PAnsiChar(Section), PAnsiChar(Key), PAnsiChar(Value))); - if Win32Platform = VER_PLATFORM_WIN32_WINDOWS then - WriteProfileString(nil, nil, nil); {this flushes the WIN.INI cache} - SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, Integer(PAnsiChar(Section)), - SMTO_NORMAL, 250, DummyResult); - except - on E: Exception do begin - E.Message := 'Couldn''t create font substitutes.' + CRLF + E.Message; - Application.HandleException(nil); - end; - end; - end; - - var - ShellDlgFontName_1: WideString; - ShellDlgFontName_2: WideString; - begin - ShellDlgFontName_1 := GetProfileStr('FontSubstitutes', 'MS Shell Dlg', '', LF_FACESIZE); - if ShellDlgFontName_1 = '' then begin - ShellDlgFontName_1 := 'MS Sans Serif'; - SetProfileStr('FontSubstitutes', 'MS Shell Dlg', ShellDlgFontName_1); - end; - ShellDlgFontName_2 := GetProfileStr('FontSubstitutes', 'MS Shell Dlg 2', '', LF_FACESIZE); - if ShellDlgFontName_2 = '' then begin - if Screen.Fonts.IndexOf('Tahoma') <> -1 then - ShellDlgFontName_2 := 'Tahoma' - else - ShellDlgFontName_2 := ShellDlgFontName_1; - SetProfileStr('FontSubstitutes', 'MS Shell Dlg 2', ShellDlgFontName_2); - end; - if RunningUnderIDE then begin - Result := 'MS Shell Dlg 2' {Delphi is running} - end else - Result := ShellDlgFontName_2; - end; - -begin - // Tnt Environment Setup - InstallTntSystemUpdates; - DefFontData.Name := GetDefaultFont; - Forms.HintWindowClass := TntControls.TTntHintWindow; -end; - -initialization - TntApplication := TTntApplication.Create(nil); - if Win32Platform = VER_PLATFORM_WIN32_NT then - CreateGetMessageHookForNT; - -finalization - if NTGetMessageHook <> 0 then begin - UnhookWindowsHookEx(NTGetMessageHook) // no Win32Check, fails in too many cases, and doesn't matter - end; - FreeAndNil(TntApplication); - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntGraphics.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntGraphics.pas deleted file mode 100644 index 6d07319da..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntGraphics.pas +++ /dev/null @@ -1,142 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntGraphics; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Graphics, Windows; - -{TNT-WARN TextRect} -procedure WideCanvasTextRect(Canvas: TCanvas; Rect: TRect; X, Y: Integer; const Text: WideString); -{TNT-WARN TextOut} -procedure WideCanvasTextOut(Canvas: TCanvas; X, Y: Integer; const Text: WideString); -{TNT-WARN TextExtent} -function WideCanvasTextExtent(Canvas: TCanvas; const Text: WideString): TSize; -function WideDCTextExtent(hDC: THandle; const Text: WideString): TSize; -{TNT-WARN TextWidth} -function WideCanvasTextWidth(Canvas: TCanvas; const Text: WideString): Integer; -{TNT-WARN TextHeight} -function WideCanvasTextHeight(Canvas: TCanvas; const Text: WideString): Integer; - -type -{TNT-WARN TPicture} - TTntPicture = class(TPicture{TNT-ALLOW TPicture}) - public - procedure LoadFromFile(const Filename: WideString); - procedure SaveToFile(const Filename: WideString); - end; - -implementation - -uses - SysUtils, TntSysUtils; - -type - TAccessCanvas = class(TCanvas); - -procedure WideCanvasTextRect(Canvas: TCanvas; Rect: TRect; X, Y: Integer; const Text: WideString); -var - Options: Longint; -begin - with TAccessCanvas(Canvas) do begin - Changing; - RequiredState([csHandleValid, csFontValid, csBrushValid]); - Options := ETO_CLIPPED or TextFlags; - if Brush.Style <> bsClear then - Options := Options or ETO_OPAQUE; - if ((TextFlags and ETO_RTLREADING) <> 0) and - (CanvasOrientation = coRightToLeft) then Inc(X, WideCanvasTextWidth(Canvas, Text) + 1); - Windows.ExtTextOutW(Handle, X, Y, Options, @Rect, PWideChar(Text), - Length(Text), nil); - Changed; - end; -end; - -procedure WideCanvasTextOut(Canvas: TCanvas; X, Y: Integer; const Text: WideString); -begin - with TAccessCanvas(Canvas) do begin - Changing; - RequiredState([csHandleValid, csFontValid, csBrushValid]); - if CanvasOrientation = coRightToLeft then Inc(X, WideCanvasTextWidth(Canvas, Text) + 1); - Windows.ExtTextOutW(Handle, X, Y, TextFlags, nil, PWideChar(Text), - Length(Text), nil); - MoveTo(X + WideCanvasTextWidth(Canvas, Text), Y); - Changed; - end; -end; - -function WideDCTextExtent(hDC: THandle; const Text: WideString): TSize; -begin - Result.cx := 0; - Result.cy := 0; - Windows.GetTextExtentPoint32W(hDC, PWideChar(Text), Length(Text), Result); -end; - -function WideCanvasTextExtent(Canvas: TCanvas; const Text: WideString): TSize; -begin - with TAccessCanvas(Canvas) do begin - RequiredState([csHandleValid, csFontValid]); - Result := WideDCTextExtent(Handle, Text); - end; -end; - -function WideCanvasTextWidth(Canvas: TCanvas; const Text: WideString): Integer; -begin - Result := WideCanvasTextExtent(Canvas, Text).cX; -end; - -function WideCanvasTextHeight(Canvas: TCanvas; const Text: WideString): Integer; -begin - Result := WideCanvasTextExtent(Canvas, Text).cY; -end; - -{ TTntPicture } - -procedure TTntPicture.LoadFromFile(const Filename: WideString); -var - ShortName: WideString; -begin - ShortName := WideExtractShortPathName(Filename); - if WideSameText(WideExtractFileExt(FileName), '.jpeg') // the short name ends with ".JPE"! - or (ShortName = '') then // GetShortPathName failed - inherited LoadFromFile(FileName) - else - inherited LoadFromFile(WideExtractShortPathName(Filename)); -end; - -procedure TTntPicture.SaveToFile(const Filename: WideString); -var - TempFile: WideString; -begin - if Graphic <> nil then begin - // create to temp file (ansi safe file name) - repeat - TempFile := WideExtractFilePath(Filename) + IntToStr(Random(MaxInt)) + WideExtractFileExt(Filename); - until not WideFileExists(TempFile); - CloseHandle(WideFileCreate(TempFile)); // make it a real file so that it has a temp - try - // save - Graphic.SaveToFile(WideExtractShortPathName(TempFile)); - // rename - WideDeleteFile(Filename); - if not WideRenameFile(TempFile, FileName) then - RaiseLastOSError; - finally - WideDeleteFile(TempFile); - end; - end; -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntGrids.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntGrids.pas deleted file mode 100644 index a97937f38..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntGrids.pas +++ /dev/null @@ -1,675 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntGrids; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Classes, TntClasses, Grids, Windows, Controls, Messages; - -type -{TNT-WARN TInplaceEdit} - TTntInplaceEdit = class(TInplaceEdit{TNT-ALLOW TInplaceEdit}) - private - function GetText: WideString; - procedure SetText(const Value: WideString); - protected - procedure UpdateContents; override; - procedure CreateWindowHandle(const Params: TCreateParams); override; - public - property Text: WideString read GetText write SetText; - end; - - TTntGetEditEvent = procedure (Sender: TObject; ACol, ARow: Longint; var Value: WideString) of object; - TTntSetEditEvent = procedure (Sender: TObject; ACol, ARow: Longint; const Value: WideString) of object; - -{TNT-WARN TCustomDrawGrid} - _TTntInternalCustomDrawGrid = class(TCustomDrawGrid{TNT-ALLOW TCustomDrawGrid}) - private - FSettingEditText: Boolean; - procedure InternalSetEditText(ACol, ARow: Longint; const Value: string{TNT-ALLOW string}); dynamic; abstract; - protected - procedure SetEditText(ACol, ARow: Longint; const Value: string{TNT-ALLOW string}); override; - end; - - TTntCustomDrawGrid = class(_TTntInternalCustomDrawGrid) - private - FOnGetEditText: TTntGetEditEvent; - FOnSetEditText: TTntSetEditEvent; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - procedure WMChar(var Msg: TWMChar); message WM_CHAR; - protected - function CreateEditor: TInplaceEdit{TNT-ALLOW TInplaceEdit}; override; - procedure InternalSetEditText(ACol, ARow: Longint; const Value: string{TNT-ALLOW string}); override; - function GetEditText(ACol, ARow: Longint): WideString; reintroduce; virtual; - procedure SetEditText(ACol, ARow: Longint; const Value: WideString); reintroduce; virtual; - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure ShowEditorChar(Ch: WideChar); dynamic; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - property OnGetEditText: TTntGetEditEvent read FOnGetEditText write FOnGetEditText; - property OnSetEditText: TTntSetEditEvent read FOnSetEditText write FOnSetEditText; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TDrawGrid} - TTntDrawGrid = class(TTntCustomDrawGrid) - published - property Align; - property Anchors; - property BevelEdges; - property BevelInner; - property BevelKind; - property BevelOuter; - property BevelWidth; - property BiDiMode; - property BorderStyle; - property Color; - property ColCount; - property Constraints; - property Ctl3D; - property DefaultColWidth; - property DefaultRowHeight; - property DefaultDrawing; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property FixedColor; - property FixedCols; - property RowCount; - property FixedRows; - property Font; - property GridLineWidth; - property Options; - property ParentBiDiMode; - property ParentColor; - property ParentCtl3D; - property ParentFont; - property ParentShowHint; - property PopupMenu; - property ScrollBars; - property ShowHint; - property TabOrder; - property Visible; - property VisibleColCount; - property VisibleRowCount; - property OnClick; - property OnColumnMoved; - property OnContextPopup; - property OnDblClick; - property OnDragDrop; - property OnDragOver; - property OnDrawCell; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnGetEditMask; - property OnGetEditText; - property OnKeyDown; - property OnKeyPress; - property OnKeyUp; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - property OnMouseWheelDown; - property OnMouseWheelUp; - property OnRowMoved; - property OnSelectCell; - property OnSetEditText; - property OnStartDock; - property OnStartDrag; - property OnTopLeftChanged; - end; - - TTntStringGrid = class; - -{TNT-WARN TStringGridStrings} - TTntStringGridStrings = class(TTntStrings) - private - FIsCol: Boolean; - FColRowIndex: Integer; - FGrid: TTntStringGrid; - function GridAnsiStrings: TStrings{TNT-ALLOW TStrings}; - protected - function Get(Index: Integer): WideString; override; - procedure Put(Index: Integer; const S: WideString); override; - function GetCount: Integer; override; - function GetObject(Index: Integer): TObject; override; - procedure PutObject(Index: Integer; AObject: TObject); override; - procedure SetUpdateState(Updating: Boolean); override; - public - constructor Create(AGrid: TTntStringGrid; AIndex: Longint); - function Add(const S: WideString): Integer; override; - procedure Assign(Source: TPersistent); override; - procedure Clear; override; - procedure Delete(Index: Integer); override; - procedure Insert(Index: Integer; const S: WideString); override; - end; - -{TNT-WARN TStringGrid} - _TTntInternalStringGrid = class(TStringGrid{TNT-ALLOW TStringGrid}) - private - FSettingEditText: Boolean; - procedure InternalSetEditText(ACol, ARow: Longint; const Value: string{TNT-ALLOW string}); dynamic; abstract; - protected - procedure SetEditText(ACol, ARow: Longint; const Value: string{TNT-ALLOW string}); override; - end; - - TTntStringGrid = class(_TTntInternalStringGrid) - private - FCreatedRowStrings: TStringList{TNT-ALLOW TStringList}; - FCreatedColStrings: TStringList{TNT-ALLOW TStringList}; - FOnGetEditText: TTntGetEditEvent; - FOnSetEditText: TTntSetEditEvent; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - procedure WMChar(var Msg: TWMChar); message WM_CHAR; - function GetCells(ACol, ARow: Integer): WideString; - procedure SetCells(ACol, ARow: Integer; const Value: WideString); - function FindGridStrings(const IsCol: Boolean; const ListIndex: Integer): TTntStrings; - function GetCols(Index: Integer): TTntStrings; - function GetRows(Index: Integer): TTntStrings; - procedure SetCols(Index: Integer; const Value: TTntStrings); - procedure SetRows(Index: Integer; const Value: TTntStrings); - protected - function CreateEditor: TInplaceEdit{TNT-ALLOW TInplaceEdit}; override; - procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); override; - procedure InternalSetEditText(ACol, ARow: Longint; const Value: string{TNT-ALLOW string}); override; - function GetEditText(ACol, ARow: Longint): WideString; reintroduce; virtual; - procedure SetEditText(ACol, ARow: Longint; const Value: WideString); reintroduce; virtual; - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure ShowEditorChar(Ch: WideChar); dynamic; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - property Cells[ACol, ARow: Integer]: WideString read GetCells write SetCells; - property Cols[Index: Integer]: TTntStrings read GetCols write SetCols; - property Rows[Index: Integer]: TTntStrings read GetRows write SetRows; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - property OnGetEditText: TTntGetEditEvent read FOnGetEditText write FOnGetEditText; - property OnSetEditText: TTntSetEditEvent read FOnSetEditText write FOnSetEditText; - end; - -implementation - -uses - SysUtils, TntSystem, TntGraphics, TntControls, TntStdCtrls, TntActnList, TntSysUtils; - -{ TBinaryCompareAnsiStringList } -type - TBinaryCompareAnsiStringList = class(TStringList{TNT-ALLOW TStringList}) - protected - function CompareStrings(const S1, S2: string{TNT-ALLOW string}): Integer; override; - end; - -function TBinaryCompareAnsiStringList.CompareStrings(const S1, S2: string{TNT-ALLOW string}): Integer; -begin - // must compare strings via binary for speed - if S1 = S2 then - result := 0 - else if S1 < S2 then - result := -1 - else - result := 1; -end; - -{ TTntInplaceEdit } - -procedure TTntInplaceEdit.CreateWindowHandle(const Params: TCreateParams); -begin - TntCustomEdit_CreateWindowHandle(Self, Params); -end; - -function TTntInplaceEdit.GetText: WideString; -begin - if IsMasked then - Result := inherited Text - else - Result := TntControl_GetText(Self); -end; - -procedure TTntInplaceEdit.SetText(const Value: WideString); -begin - if IsMasked then - inherited Text := Value - else - TntControl_SetText(Self, Value); -end; - -type TAccessCustomGrid = class(TCustomGrid); - -procedure TTntInplaceEdit.UpdateContents; -begin - Text := ''; - with TAccessCustomGrid(Grid) do - Self.EditMask := GetEditMask(Col, Row); - if (Grid is TTntStringGrid) then - with (Grid as TTntStringGrid) do - Self.Text := GetEditText(Col, Row) - else if (Grid is TTntCustomDrawGrid) then - with (Grid as TTntCustomDrawGrid) do - Self.Text := GetEditText(Col, Row) - else - with TAccessCustomGrid(Grid) do - Self.Text := GetEditText(Col, Row); - with TAccessCustomGrid(Grid) do - Self.MaxLength := GetEditLimit; -end; - -{ _TTntInternalCustomDrawGrid } - -procedure _TTntInternalCustomDrawGrid.SetEditText(ACol, ARow: Integer; const Value: string{TNT-ALLOW string}); -begin - if FSettingEditText then - inherited - else - InternalSetEditText(ACol, ARow, Value); -end; - - -{ TTntCustomDrawGrid } - -function TTntCustomDrawGrid.CreateEditor: TInplaceEdit{TNT-ALLOW TInplaceEdit}; -begin - Result := TTntInplaceEdit.Create(Self); -end; - -procedure TTntCustomDrawGrid.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, ''); -end; - -procedure TTntCustomDrawGrid.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntCustomDrawGrid.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntCustomDrawGrid.GetHint: WideString; -begin - Result := TntControl_GetHint(Self); -end; - -procedure TTntCustomDrawGrid.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -function TTntCustomDrawGrid.GetEditText(ACol, ARow: Integer): WideString; -begin - Result := ''; - if Assigned(FOnGetEditText) then FOnGetEditText(Self, ACol, ARow, Result); -end; - -procedure TTntCustomDrawGrid.InternalSetEditText(ACol, ARow: Integer; const Value: string{TNT-ALLOW string}); -begin - if not FSettingEditText then - SetEditText(ACol, ARow, TntControl_GetText(InplaceEditor)); -end; - -procedure TTntCustomDrawGrid.SetEditText(ACol, ARow: Integer; const Value: WideString); -begin - if Assigned(FOnSetEditText) then FOnSetEditText(Self, ACol, ARow, Value); -end; - -procedure TTntCustomDrawGrid.WMChar(var Msg: TWMChar); -begin - if (goEditing in Options) - and (AnsiChar(Msg.CharCode) in [^H, #32..#255]) then begin - RestoreWMCharMsg(TMessage(Msg)); - ShowEditorChar(WideChar(Msg.CharCode)); - end else - inherited; -end; - -procedure TTntCustomDrawGrid.ShowEditorChar(Ch: WideChar); -begin - ShowEditor; - if InplaceEditor <> nil then begin - if Win32PlatformIsUnicode then - PostMessageW(InplaceEditor.Handle, WM_CHAR, Word(Ch), 0) - else - PostMessageA(InplaceEditor.Handle, WM_CHAR, Word(Ch), 0); - end; -end; - -procedure TTntCustomDrawGrid.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomDrawGrid.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntStringGridStrings } - -procedure TTntStringGridStrings.Assign(Source: TPersistent); -var - UTF8Strings: TStringList{TNT-ALLOW TStringList}; - i: integer; -begin - UTF8Strings := TStringList{TNT-ALLOW TStringList}.Create; - try - if Source is TStrings{TNT-ALLOW TStrings} then begin - for i := 0 to TStrings{TNT-ALLOW TStrings}(Source).Count - 1 do - UTF8Strings.AddObject(WideStringToUTF8(WideString(TStrings{TNT-ALLOW TStrings}(Source).Strings[i])), - TStrings{TNT-ALLOW TStrings}(Source).Objects[i]); - GridAnsiStrings.Assign(UTF8Strings); - end else if Source is TTntStrings then begin - for i := 0 to TTntStrings(Source).Count - 1 do - UTF8Strings.AddObject(WideStringToUTF8(TTntStrings(Source).Strings[i]), - TTntStrings(Source).Objects[i]); - GridAnsiStrings.Assign(UTF8Strings); - end else - GridAnsiStrings.Assign(Source); - finally - UTF8Strings.Free; - end; -end; - -function TTntStringGridStrings.GridAnsiStrings: TStrings{TNT-ALLOW TStrings}; -begin - Assert(Assigned(FGrid)); - if FIsCol then - Result := TStringGrid{TNT-ALLOW TStringGrid}(FGrid).Cols[FColRowIndex] - else - Result := TStringGrid{TNT-ALLOW TStringGrid}(FGrid).Rows[FColRowIndex]; -end; - -procedure TTntStringGridStrings.Clear; -begin - GridAnsiStrings.Clear; -end; - -procedure TTntStringGridStrings.Delete(Index: Integer); -begin - GridAnsiStrings.Delete(Index); -end; - -function TTntStringGridStrings.GetCount: Integer; -begin - Result := GridAnsiStrings.Count; -end; - -function TTntStringGridStrings.Get(Index: Integer): WideString; -begin - Result := UTF8ToWideString(GridAnsiStrings[Index]); -end; - -procedure TTntStringGridStrings.Put(Index: Integer; const S: WideString); -begin - GridAnsiStrings[Index] := WideStringToUTF8(S); -end; - -procedure TTntStringGridStrings.Insert(Index: Integer; const S: WideString); -begin - GridAnsiStrings.Insert(Index, WideStringToUTF8(S)); -end; - -function TTntStringGridStrings.Add(const S: WideString): Integer; -begin - Result := GridAnsiStrings.Add(WideStringToUTF8(S)); -end; - -function TTntStringGridStrings.GetObject(Index: Integer): TObject; -begin - Result := GridAnsiStrings.Objects[Index]; -end; - -procedure TTntStringGridStrings.PutObject(Index: Integer; AObject: TObject); -begin - GridAnsiStrings.Objects[Index] := AObject; -end; - -type TAccessStrings = class(TStrings{TNT-ALLOW TStrings}); - -procedure TTntStringGridStrings.SetUpdateState(Updating: Boolean); -begin - TAccessStrings(GridAnsiStrings).SetUpdateState(Updating); -end; - -constructor TTntStringGridStrings.Create(AGrid: TTntStringGrid; AIndex: Integer); -begin - inherited Create; - FGrid := AGrid; - if AIndex > 0 then begin - FIsCol := False; - FColRowIndex := AIndex - 1; - end else begin - FIsCol := True; - FColRowIndex := -AIndex - 1; - end; -end; - -{ _TTntInternalStringGrid } - -procedure _TTntInternalStringGrid.SetEditText(ACol, ARow: Integer; const Value: string{TNT-ALLOW string}); -begin - if FSettingEditText then - inherited - else - InternalSetEditText(ACol, ARow, Value); -end; - -{ TTntStringGrid } - -constructor TTntStringGrid.Create(AOwner: TComponent); -begin - inherited; - FCreatedRowStrings := TBinaryCompareAnsiStringList.Create; - FCreatedRowStrings.Sorted := True; - FCreatedRowStrings.Duplicates := dupError; - FCreatedColStrings := TBinaryCompareAnsiStringList.Create; - FCreatedColStrings.Sorted := True; - FCreatedColStrings.Duplicates := dupError; -end; - -destructor TTntStringGrid.Destroy; -var - i: integer; -begin - for i := FCreatedColStrings.Count - 1 downto 0 do - FCreatedColStrings.Objects[i].Free; - for i := FCreatedRowStrings.Count - 1 downto 0 do - FCreatedRowStrings.Objects[i].Free; - FreeAndNil(FCreatedColStrings); - FreeAndNil(FCreatedRowStrings); - inherited; -end; - -function TTntStringGrid.CreateEditor: TInplaceEdit{TNT-ALLOW TInplaceEdit}; -begin - Result := TTntInplaceEdit.Create(Self); -end; - -procedure TTntStringGrid.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, ''); -end; - -procedure TTntStringGrid.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntStringGrid.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntStringGrid.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntStringGrid.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -function TTntStringGrid.GetCells(ACol, ARow: Integer): WideString; -begin - Result := UTF8ToWideString(inherited Cells[ACol, ARow]) -end; - -procedure TTntStringGrid.SetCells(ACol, ARow: Integer; const Value: WideString); -var - UTF8Str: AnsiString; -begin - UTF8Str := WideStringToUTF8(Value); - if inherited Cells[ACol, ARow] <> UTF8Str then - inherited Cells[ACol, ARow] := UTF8Str; -end; - -function TTntStringGrid.FindGridStrings(const IsCol: Boolean; const ListIndex: Integer): TTntStrings; -var - idx: integer; - SrcStrings: TStrings{TNT-ALLOW TStrings}; - RCIndex: Integer; -begin - if IsCol then - SrcStrings := FCreatedColStrings - else - SrcStrings := FCreatedRowStrings; - Assert(Assigned(SrcStrings)); - idx := SrcStrings.IndexOf(IntToStr(ListIndex)); - if idx <> -1 then - Result := SrcStrings.Objects[idx] as TTntStrings - else begin - if IsCol then RCIndex := -ListIndex - 1 else RCIndex := ListIndex + 1; - Result := TTntStringGridStrings.Create(Self, RCIndex); - SrcStrings.AddObject(IntToStr(ListIndex), Result); - end; -end; - -function TTntStringGrid.GetCols(Index: Integer): TTntStrings; -begin - Result := FindGridStrings(True, Index); -end; - -function TTntStringGrid.GetRows(Index: Integer): TTntStrings; -begin - Result := FindGridStrings(False, Index); -end; - -procedure TTntStringGrid.SetCols(Index: Integer; const Value: TTntStrings); -begin - FindGridStrings(True, Index).Assign(Value); -end; - -procedure TTntStringGrid.SetRows(Index: Integer; const Value: TTntStrings); -begin - FindGridStrings(False, Index).Assign(Value); -end; - -procedure TTntStringGrid.DrawCell(ACol, ARow: Integer; ARect: TRect; AState: TGridDrawState); -var - SaveDefaultDrawing: Boolean; -begin - if DefaultDrawing then - WideCanvasTextRect(Canvas, ARect, ARect.Left+2, ARect.Top+2, Cells[ACol, ARow]); - SaveDefaultDrawing := DefaultDrawing; - try - DefaultDrawing := False; - inherited DrawCell(ACol, ARow, ARect, AState); - finally - DefaultDrawing := SaveDefaultDrawing; - end; -end; - -function TTntStringGrid.GetEditText(ACol, ARow: Integer): WideString; -begin - Result := Cells[ACol, ARow]; - if Assigned(FOnGetEditText) then FOnGetEditText(Self, ACol, ARow, Result); -end; - -procedure TTntStringGrid.InternalSetEditText(ACol, ARow: Integer; const Value: string{TNT-ALLOW string}); -begin - if not FSettingEditText then - SetEditText(ACol, ARow, TntControl_GetText(InplaceEditor)); -end; - -procedure TTntStringGrid.SetEditText(ACol, ARow: Integer; const Value: WideString); -begin - FSettingEditText := True; - try - inherited SetEditText(ACol, ARow, WideStringToUTF8(Value)); - finally - FSettingEditText := False; - end; - if Assigned(FOnSetEditText) then FOnSetEditText(Self, ACol, ARow, Value); -end; - -procedure TTntStringGrid.WMChar(var Msg: TWMChar); -begin - if (goEditing in Options) - and (AnsiChar(Msg.CharCode) in [^H, #32..#255]) then begin - RestoreWMCharMsg(TMessage(Msg)); - ShowEditorChar(WideChar(Msg.CharCode)); - end else - inherited; -end; - -procedure TTntStringGrid.ShowEditorChar(Ch: WideChar); -begin - ShowEditor; - if InplaceEditor <> nil then begin - if Win32PlatformIsUnicode then - PostMessageW(InplaceEditor.Handle, WM_CHAR, Word(Ch), 0) - else - PostMessageA(InplaceEditor.Handle, WM_CHAR, Word(Ch), 0); - end; -end; - -procedure TTntStringGrid.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntStringGrid.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntListActns.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntListActns.pas deleted file mode 100644 index ffd7eb260..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntListActns.pas +++ /dev/null @@ -1,207 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntListActns; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Classes, TntActnList, ListActns; - -type -{TNT-WARN TCustomListAction} - TTntCustomListAction = class(TCustomListAction{TNT-ALLOW TCustomListAction}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - public - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TStaticListAction} - TTntStaticListAction = class(TStaticListAction{TNT-ALLOW TStaticListAction}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TVirtualListAction} - TTntVirtualListAction = class(TVirtualListAction{TNT-ALLOW TVirtualListAction}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -implementation - -uses - ActnList, TntClasses; - -{TNT-IGNORE-UNIT} - -type TAccessCustomListAction = class(TCustomListAction); - -procedure TntListActn_AfterInherited_Assign(Action: TCustomAction{TNT-ALLOW TCustomAction}; Source: TPersistent); -begin - TntAction_AfterInherited_Assign(Action, Source); - // TCustomListAction - if (Action is TCustomListAction) and (Source is TCustomListAction) then begin - TAccessCustomListAction(Action).Images := TAccessCustomListAction(Source).Images; - TAccessCustomListAction(Action).OnGetItemCount := TAccessCustomListAction(Source).OnGetItemCount; - TAccessCustomListAction(Action).OnItemSelected := TAccessCustomListAction(Source).OnItemSelected; - TAccessCustomListAction(Action).Active := TAccessCustomListAction(Source).Active; - TAccessCustomListAction(Action).ItemIndex := TAccessCustomListAction(Source).ItemIndex; - end; - // TStaticListAction - if (Action is TStaticListAction) and (Source is TStaticListAction) then begin - TStaticListAction(Action).Items := TStaticListAction(Source).Items; - TStaticListAction(Action).OnGetItem := TStaticListAction(Source).OnGetItem; - end; - // TVirtualListAction - if (Action is TVirtualListAction) and (Source is TVirtualListAction) then begin - TVirtualListAction(Action).OnGetItem := TVirtualListAction(Source).OnGetItem; - end; -end; - -//------------------------- -// TNT LIST ACTNS -//------------------------- - -{ TTntCustomListAction } - -procedure TTntCustomListAction.Assign(Source: TPersistent); -begin - inherited; - TntListActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntCustomListAction.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntCustomListAction.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntCustomListAction.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntCustomListAction.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntCustomListAction.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntStaticListAction } - -procedure TTntStaticListAction.Assign(Source: TPersistent); -begin - inherited; - TntListActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntStaticListAction.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntStaticListAction.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntStaticListAction.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntStaticListAction.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntStaticListAction.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntVirtualListAction } - -procedure TTntVirtualListAction.Assign(Source: TPersistent); -begin - inherited; - TntListActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntVirtualListAction.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntVirtualListAction.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntVirtualListAction.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntVirtualListAction.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntVirtualListAction.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntMenus.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntMenus.pas deleted file mode 100644 index e6cdbc888..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntMenus.pas +++ /dev/null @@ -1,1146 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntMenus; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Windows, Classes, Menus, Graphics, Messages; - -type -{TNT-WARN TMenuItem} - TTntMenuItem = class(TMenuItem{TNT-ALLOW TMenuItem}) - private - FIgnoreMenuChanged: Boolean; - FCaption: WideString; - FHint: WideString; - FKeyboardLayout: HKL; - function GetCaption: WideString; - procedure SetInheritedCaption(const Value: AnsiString); - procedure SetCaption(const Value: WideString); - function IsCaptionStored: Boolean; - procedure UpdateMenuString(ParentMenu: TMenu); - function GetAlignmentDrawStyle: Word; - function MeasureItemTextWidth(ACanvas: TCanvas; const Text: WideString): Integer; - function GetHint: WideString; - procedure SetInheritedHint(const Value: AnsiString); - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - protected - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TMenuActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - procedure MenuChanged(Rebuild: Boolean); override; - procedure AdvancedDrawItem(ACanvas: TCanvas; ARect: TRect; - State: TOwnerDrawState; TopLevel: Boolean); override; - procedure DoDrawText(ACanvas: TCanvas; const ACaption: WideString; - var Rect: TRect; Selected: Boolean; Flags: Integer); - procedure MeasureItem(ACanvas: TCanvas; var Width, Height: Integer); override; - public - procedure InitiateAction; override; - procedure Loaded; override; - function Find(ACaption: WideString): TMenuItem{TNT-ALLOW TMenuItem}; - published - property Caption: WideString read GetCaption write SetCaption stored IsCaptionStored; - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TMainMenu} - TTntMainMenu = class(TMainMenu{TNT-ALLOW TMainMenu}) - protected - procedure DoChange(Source: TMenuItem{TNT-ALLOW TMenuItem}; Rebuild: Boolean); override; - public - {$IFDEF COMPILER_9_UP} - function CreateMenuItem: TMenuItem{TNT-ALLOW TMenuItem}; override; - {$ENDIF} - end; - -{TNT-WARN TPopupMenu} - TTntPopupMenu = class(TPopupMenu{TNT-ALLOW TPopupMenu}) - protected - procedure DoChange(Source: TMenuItem{TNT-ALLOW TMenuItem}; Rebuild: Boolean); override; - public - constructor Create(AOwner: TComponent); override; - {$IFDEF COMPILER_9_UP} - function CreateMenuItem: TMenuItem{TNT-ALLOW TMenuItem}; override; - {$ENDIF} - destructor Destroy; override; - procedure Popup(X, Y: Integer); override; - end; - -{TNT-WARN NewSubMenu} -function WideNewSubMenu(const ACaption: WideString; hCtx: THelpContext; - const AName: TComponentName; const Items: array of TTntMenuItem; - AEnabled: Boolean): TTntMenuItem; -{TNT-WARN NewItem} -function WideNewItem(const ACaption: WideString; AShortCut: TShortCut; - AChecked, AEnabled: Boolean; AOnClick: TNotifyEvent; hCtx: THelpContext; - const AName: TComponentName): TTntMenuItem; - -function MessageToShortCut(Msg: TWMKeyDown): TShortCut; - -{TNT-WARN ShortCutToText} -function WideShortCutToText(WordShortCut: Word): WideString; -{TNT-WARN TextToShortCut} -function WideTextToShortCut(Text: WideString): TShortCut; -{TNT-WARN GetHotKey} -function WideGetHotkey(const Text: WideString): WideString; -{TNT-WARN StripHotkey} -function WideStripHotkey(const Text: WideString): WideString; -{TNT-WARN AnsiSameCaption} -function WideSameCaption(const Text1, Text2: WideString): Boolean; - -function WideGetMenuItemCaption(MenuItem: TMenuItem{TNT-ALLOW TMenuItem}): WideString; -function WideGetMenuItemHint(MenuItem: TMenuItem{TNT-ALLOW TMenuItem}): WideString; - -procedure NoOwnerDrawTopLevelItems(Menu: TMainMenu{TNT-ALLOW TMainMenu}); - -procedure FixMenuBiDiProblem(Menu: TMenu); - -function MenuItemHasBitmap(MenuItem: TMenuItem{TNT-ALLOW TMenuItem}): Boolean; - -type - TTntPopupList = class(TPopupList) - private - SavedPopupList: TPopupList; - protected - procedure WndProc(var Message: TMessage); override; - end; - -var - TntPopupList: TTntPopupList; - -implementation - -uses - Forms, SysUtils, Consts, ActnList, ImgList, TntControls, TntGraphics, - TntActnList, TntClasses, TntForms, TntSysUtils, TntWindows; - -function WideNewSubMenu(const ACaption: WideString; hCtx: THelpContext; - const AName: TComponentName; const Items: array of TTntMenuItem; - AEnabled: Boolean): TTntMenuItem; -var - I: Integer; -begin - Result := TTntMenuItem.Create(nil); - for I := Low(Items) to High(Items) do - Result.Add(Items[I]); - Result.Caption := ACaption; - Result.HelpContext := hCtx; - Result.Name := AName; - Result.Enabled := AEnabled; -end; - -function WideNewItem(const ACaption: WideString; AShortCut: TShortCut; - AChecked, AEnabled: Boolean; AOnClick: TNotifyEvent; hCtx: THelpContext; - const AName: TComponentName): TTntMenuItem; -begin - Result := TTntMenuItem.Create(nil); - with Result do - begin - Caption := ACaption; - ShortCut := AShortCut; - OnClick := AOnClick; - HelpContext := hCtx; - Checked := AChecked; - Enabled := AEnabled; - Name := AName; - end; -end; - -function MessageToShortCut(Msg: TWMKeyDown): TShortCut; -var - ShiftState: TShiftState; -begin - ShiftState := Forms.KeyDataToShiftState(TWMKeyDown(Msg).KeyData); - Result := Menus.ShortCut(TWMKeyDown(Msg).CharCode, ShiftState); -end; - -function WideGetSpecialName(WordShortCut: Word): WideString; -var - ScanCode: Integer; - KeyName: array[0..255] of WideChar; -begin - Assert(Win32PlatformIsUnicode); - Result := ''; - ScanCode := MapVirtualKeyW(WordRec(WordShortCut).Lo, 0) shl 16; - if ScanCode <> 0 then - begin - GetKeyNameTextW(ScanCode, KeyName, SizeOf(KeyName)); - Result := KeyName; - end; -end; - -function WideGetKeyboardChar(Key: Word): WideChar; -var - LatinNumChar: WideChar; -begin - Assert(Win32PlatformIsUnicode); - Result := WideChar(MapVirtualKeyW(Key, 2)); - if (Key in [$30..$39]) then - begin - // Check to see if "0" - "9" can be used if all that differs is shift state - LatinNumChar := WideChar(Key - $30 + Ord('0')); - if (Result <> LatinNumChar) - and (Byte(Key) = WordRec(VkKeyScanW(LatinNumChar)).Lo) then // .Hi would be the shift state - Result := LatinNumChar; - end; -end; - -function WideShortCutToText(WordShortCut: Word): WideString; -var - Name: WideString; -begin - if (not Win32PlatformIsUnicode) - or (WordRec(WordShortCut).Lo in [$08..$09 {BKSP, TAB}, $0D {ENTER}, $1B {ESC}, $20..$28 {Misc Nav}, - $2D..$2E {INS, DEL}, $70..$87 {F1 - F24}]) - then - Result := ShortCutToText{TNT-ALLOW ShortCutToText}(WordShortCut) - else begin - case WordRec(WordShortCut).Lo of - $30..$39: Name := WideGetKeyboardChar(WordRec(WordShortCut).Lo); {1-9,0} - $41..$5A: Name := WideGetKeyboardChar(WordRec(WordShortCut).Lo); {A-Z} - $60..$69: Name := WideGetKeyboardChar(WordRec(WordShortCut).Lo); {numpad 1-9,0} - else - Name := WideGetSpecialName(WordShortCut); - end; - if Name <> '' then - begin - Result := ''; - if WordShortCut and scShift <> 0 then Result := Result + SmkcShift; - if WordShortCut and scCtrl <> 0 then Result := Result + SmkcCtrl; - if WordShortCut and scAlt <> 0 then Result := Result + SmkcAlt; - Result := Result + Name; - end - else Result := ''; - end; -end; - -{ This function is *very* slow. Use sparingly. Return 0 if no VK code was - found for the text } - -function WideTextToShortCut(Text: WideString): TShortCut; - - { If the front of Text is equal to Front then remove the matching piece - from Text and return True, otherwise return False } - - function CompareFront(var Text: WideString; const Front: WideString): Boolean; - begin - Result := (Pos(Front, Text) = 1); - if Result then - Delete(Text, 1, Length(Front)); - end; - -var - Key: TShortCut; - Shift: TShortCut; -begin - Result := 0; - Shift := 0; - while True do - begin - if CompareFront(Text, SmkcShift) then Shift := Shift or scShift - else if CompareFront(Text, '^') then Shift := Shift or scCtrl - else if CompareFront(Text, SmkcCtrl) then Shift := Shift or scCtrl - else if CompareFront(Text, SmkcAlt) then Shift := Shift or scAlt - else Break; - end; - if Text = '' then Exit; - for Key := $08 to $255 do { Copy range from table in ShortCutToText } - if WideSameText(Text, WideShortCutToText(Key)) then - begin - Result := Key or Shift; - Exit; - end; -end; - -function WideGetHotkeyPos(const Text: WideString): Integer; -var - I, L: Integer; -begin - Result := 0; - I := 1; - L := Length(Text); - while I <= L do - begin - if (Text[I] = cHotkeyPrefix) and (L - I >= 1) then - begin - Inc(I); - if Text[I] <> cHotkeyPrefix then - Result := I; // this might not be the last - end; - Inc(I); - end; -end; - -function WideGetHotkey(const Text: WideString): WideString; -var - I: Integer; -begin - I := WideGetHotkeyPos(Text); - if I = 0 then - Result := '' - else - Result := Text[I]; -end; - -function WideStripHotkey(const Text: WideString): WideString; -var - I: Integer; -begin - Result := Text; - I := 1; - while I <= Length(Result) do - begin - if Result[I] = cHotkeyPrefix then - if SysLocale.FarEast - and ((I > 1) and (Length(Result) - I >= 2) - and (Result[I - 1] = '(') and (Result[I + 2] = ')')) then begin - Delete(Result, I - 1, 4); - Dec(I, 2); - end else - Delete(Result, I, 1); - Inc(I); - end; -end; - -function WideSameCaption(const Text1, Text2: WideString): Boolean; -begin - Result := WideSameText(WideStripHotkey(Text1), WideStripHotkey(Text2)); -end; - -function WideSameCaptionStr(const Text1, Text2: WideString): Boolean; -begin - Result := WideSameStr(WideStripHotkey(Text1), WideStripHotkey(Text2)); -end; - -function WideGetMenuItemCaption(MenuItem: TMenuItem{TNT-ALLOW TMenuItem}): WideString; -begin - if MenuItem is TTntMenuItem then - Result := TTntMenuItem(MenuItem).Caption - else - Result := MenuItem.Caption; -end; - -function WideGetMenuItemHint(MenuItem: TMenuItem{TNT-ALLOW TMenuItem}): WideString; -begin - if MenuItem is TTntMenuItem then - Result := TTntMenuItem(MenuItem).Hint - else - Result := MenuItem.Hint; -end; - -procedure NoOwnerDrawTopLevelItems(Menu: TMainMenu{TNT-ALLOW TMainMenu}); -{If top-level items are created as owner-drawn, they will not appear as raised -buttons when the mouse hovers over them. The VCL will often create top-level -items as owner-drawn even when they don't need to be (owner-drawn state can be -set on an item-by-item basis). This routine turns off the owner-drawn flag for -top-level items if it appears unnecessary} - - function ItemHasValidImage(Item: TMenuItem{TNT-ALLOW TMenuItem}): boolean; - var - Images: TCustomImageList; - begin - Assert(Item <> nil, 'TNT Internal Error: ItemHasValidImage: item = nil'); - Images := Item.GetImageList; - Result := (Assigned(Images) and (Item.ImageIndex >= 0) and (Item.ImageIndex < Images.Count)) - or (MenuItemHasBitmap(Item) and (not Item.Bitmap.Empty)) - end; - -var - HM: HMenu; - i: integer; - Info: TMenuItemInfoA; - Item: TMenuItem{TNT-ALLOW TMenuItem}; - Win98Plus: boolean; -begin - if Assigned(Menu) then begin - Win98Plus:= (Win32MajorVersion > 4) - or((Win32MajorVersion = 4) and (Win32MinorVersion > 0)); - if not Win98Plus then - Exit; {exit if Windows 95 or NT 4.0} - HM:= Menu.Handle; - Info.cbSize:= sizeof(Info); - for i := 0 to GetMenuItemCount(HM) - 1 do begin - Info.fMask:= MIIM_FTYPE or MIIM_ID; - if not GetMenuItemInfo(HM, i, true, Info) then - Break; - if Info.fType and MFT_OWNERDRAW <> 0 then begin - Item:= Menu.FindItem(Info.wID, fkCommand); - if not Assigned(Item) then - continue; - if Assigned(Item.OnDrawItem) - or Assigned(Item.OnAdvancedDrawItem) - or ItemHasValidImage(Item) then - Continue; - Info.fMask:= MIIM_FTYPE or MIIM_STRING; - Info.fType:= (Info.fType and not MFT_OWNERDRAW) or MFT_STRING; - if Win32PlatformIsUnicode and (Item is TTntMenuItem) then begin - // Unicode - TMenuItemInfoW(Info).dwTypeData:= PWideChar(TTntMenuItem(Item).Caption); - SetMenuItemInfoW(HM, i, true, TMenuItemInfoW(Info)); - end else begin - // Ansi - Info.dwTypeData:= PAnsiChar(Item.Caption); - SetMenuItemInfoA(HM, i, true, Info); - end; - end; - end; - end; -end; - -{ TTntMenuItem's utility procs } - -procedure SyncHotKeyPosition(const Source: WideString; var Dest: WideString); -var - I: Integer; - FarEastHotString: WideString; -begin - if (AnsiString(Source) <> AnsiString(Dest)) - and WideSameCaptionStr(AnsiString(Source), AnsiString(Dest)) then begin - // when reduced to ansi, the only difference is hot key positions - Dest := WideStripHotkey(Dest); - I := 1; - while I <= Length(Source) do - begin - if Source[I] = cHotkeyPrefix then begin - if SysLocale.FarEast - and ((I > 1) and (Length(Source) - I >= 2) - and (Source[I - 1] = '(') and (Source[I + 2] = ')')) then begin - FarEastHotString := Copy(Source, I - 1, 4); - Dec(I); - Insert(FarEastHotString, Dest, I); - Inc(I, 3); - end else begin - Insert(cHotkeyPrefix, Dest, I); - Inc(I); - end; - end; - Inc(I); - end; - // test work - if AnsiString(Source) <> AnsiString(Dest) then - raise ETntInternalError.CreateFmt('Internal Error: SyncHotKeyPosition Failed ("%s" <> "%s").', - [AnsiString(Source), AnsiString(Dest)]); - end; -end; - -procedure UpdateMenuItems(Items: TMenuItem{TNT-ALLOW TMenuItem}; ParentMenu: TMenu); -var - i: integer; -begin - if (Items.ComponentState * [csReading, csDestroying] = []) then begin - for i := Items.Count - 1 downto 0 do - UpdateMenuItems(Items[i], ParentMenu); - if Items is TTntMenuItem then - TTntMenuItem(Items).UpdateMenuString(ParentMenu); - end; -end; - -procedure FixMenuBiDiProblem(Menu: TMenu); -var - i: integer; -begin - // TMenu sometimes sets bidi on first visible item which can convert caption to ansi - if (SysLocale.MiddleEast) - and (Menu <> nil) - and (Menu.Items.Count > 0) then - begin - for i := 0 to Menu.Items.Count - 1 do begin - if Menu.Items[i].Visible then begin - if (Menu.Items[i] is TTntMenuItem) then - (Menu.Items[i] as TTntMenuItem).UpdateMenuString(Menu); - break; // found first visible menu item! - end; - end; - end; -end; - - -{$IFDEF COMPILER_6} // verified against VCL source in Delphi 6 and BCB 6 -type - THackMenuItem = class(TComponent) - protected - FxxxxCaption: Ansistring; - FxxxxHandle: HMENU; - FxxxxChecked: Boolean; - FxxxxEnabled: Boolean; - FxxxxDefault: Boolean; - FxxxxAutoHotkeys: TMenuItemAutoFlag; - FxxxxAutoLineReduction: TMenuItemAutoFlag; - FxxxxRadioItem: Boolean; - FxxxxVisible: Boolean; - FxxxxGroupIndex: Byte; - FxxxxImageIndex: TImageIndex; - FxxxxActionLink: TMenuActionLink{TNT-ALLOW TMenuActionLink}; - FxxxxBreak: TMenuBreak; - FBitmap: TBitmap; - FxxxxCommand: Word; - FxxxxHelpContext: THelpContext; - FxxxxHint: AnsiString; - FxxxxItems: TList; - FxxxxShortCut: TShortCut; - FxxxxParent: TMenuItem{TNT-ALLOW TMenuItem}; - FMerged: TMenuItem{TNT-ALLOW TMenuItem}; - FMergedWith: TMenuItem{TNT-ALLOW TMenuItem}; - end; -{$ENDIF} -{$IFDEF DELPHI_7} // verified against VCL source in Delphi 7 -type - THackMenuItem = class(TComponent) - protected - FxxxxCaption: AnsiString; - FxxxxHandle: HMENU; - FxxxxChecked: Boolean; - FxxxxEnabled: Boolean; - FxxxxDefault: Boolean; - FxxxxAutoHotkeys: TMenuItemAutoFlag; - FxxxxAutoLineReduction: TMenuItemAutoFlag; - FxxxxRadioItem: Boolean; - FxxxxVisible: Boolean; - FxxxxGroupIndex: Byte; - FxxxxImageIndex: TImageIndex; - FxxxxActionLink: TMenuActionLink{TNT-ALLOW TMenuActionLink}; - FxxxxBreak: TMenuBreak; - FBitmap: TBitmap; - FxxxxCommand: Word; - FxxxxHelpContext: THelpContext; - FxxxxHint: AnsiString; - FxxxxItems: TList; - FxxxxShortCut: TShortCut; - FxxxxParent: TMenuItem{TNT-ALLOW TMenuItem}; - FMerged: TMenuItem{TNT-ALLOW TMenuItem}; - FMergedWith: TMenuItem{TNT-ALLOW TMenuItem}; - end; -{$ENDIF} -{$IFDEF DELPHI_9} // verified against VCL source in Delphi 9 -type - THackMenuItem = class(TComponent) - protected - FxxxxCaption: AnsiString; - FxxxxHandle: HMENU; - FxxxxChecked: Boolean; - FxxxxEnabled: Boolean; - FxxxxDefault: Boolean; - FxxxxAutoHotkeys: TMenuItemAutoFlag; - FxxxxAutoLineReduction: TMenuItemAutoFlag; - FxxxxRadioItem: Boolean; - FxxxxVisible: Boolean; - FxxxxGroupIndex: Byte; - FxxxxImageIndex: TImageIndex; - FxxxxActionLink: TMenuActionLink{TNT-ALLOW TMenuActionLink}; - FxxxxBreak: TMenuBreak; - FBitmap: TBitmap; - FxxxxCommand: Word; - FxxxxHelpContext: THelpContext; - FxxxxHint: AnsiString; - FxxxxItems: TList; - FxxxxShortCut: TShortCut; - FxxxxParent: TMenuItem{TNT-ALLOW TMenuItem}; - FMerged: TMenuItem{TNT-ALLOW TMenuItem}; - FMergedWith: TMenuItem{TNT-ALLOW TMenuItem}; - end; -{$ENDIF} -{$IFDEF DELPHI_10} // verified against VCL source in Delphi 10 -type - THackMenuItem = class(TComponent) - protected - FxxxxCaption: AnsiString; - FxxxxHandle: HMENU; - FxxxxChecked: Boolean; - FxxxxEnabled: Boolean; - FxxxxDefault: Boolean; - FxxxxAutoHotkeys: TMenuItemAutoFlag; - FxxxxAutoLineReduction: TMenuItemAutoFlag; - FxxxxRadioItem: Boolean; - FxxxxVisible: Boolean; - FxxxxGroupIndex: Byte; - FxxxxImageIndex: TImageIndex; - FxxxxActionLink: TMenuActionLink{TNT-ALLOW TMenuActionLink}; - FxxxxBreak: TMenuBreak; - FBitmap: TBitmap; - FxxxxCommand: Word; - FxxxxHelpContext: THelpContext; - FxxxxHint: AnsiString; - FxxxxItems: TList; - FxxxxShortCut: TShortCut; - FxxxxParent: TMenuItem{TNT-ALLOW TMenuItem}; - FMerged: TMenuItem{TNT-ALLOW TMenuItem}; - FMergedWith: TMenuItem{TNT-ALLOW TMenuItem}; - end; -{$ENDIF} - -function MenuItemHasBitmap(MenuItem: TMenuItem{TNT-ALLOW TMenuItem}): Boolean; -begin - Result := Assigned(THackMenuItem(MenuItem).FBitmap); -end; - -{ TTntMenuItem } - -procedure TTntMenuItem.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -type TAccessActionlink = class(TActionLink); - -procedure TTntMenuItem.InitiateAction; -begin - if GetKeyboardLayout(0) <> FKeyboardLayout then - MenuChanged(False); - inherited; -end; - -function TTntMenuItem.IsCaptionStored: Boolean; -begin - Result := (ActionLink = nil) or (not TAccessActionlink(ActionLink).IsCaptionLinked); -end; - -procedure TTntMenuItem.SetInheritedCaption(const Value: AnsiString); -begin - inherited Caption := Value; -end; - -function TTntMenuItem.GetCaption: WideString; -begin - if (AnsiString(FCaption) <> inherited Caption) - and WideSameCaptionStr(AnsiString(FCaption), inherited Caption) then - begin - // only difference is hotkey position, update caption with new hotkey position - SyncHotKeyPosition(inherited Caption, FCaption); - end; - Result := GetSyncedWideString(FCaption, (inherited Caption)); -end; - -procedure TTntMenuItem.SetCaption(const Value: WideString); -begin - GetCaption; // auto adjust for hot key changes - SetSyncedWideString(Value, FCaption, (inherited Caption), SetInheritedCaption); -end; - -function TTntMenuItem.GetHint: WideString; -begin - Result := GetSyncedWideString(FHint, inherited Hint); -end; - -procedure TTntMenuItem.SetInheritedHint(const Value: AnsiString); -begin - inherited Hint := Value; -end; - -procedure TTntMenuItem.SetHint(const Value: WideString); -begin - SetSyncedWideString(Value, FHint, inherited Hint, SetInheritedHint); -end; - -function TTntMenuItem.IsHintStored: Boolean; -begin - Result := (ActionLink = nil) or not TAccessActionlink(ActionLink).IsHintLinked; -end; - -procedure TTntMenuItem.Loaded; -begin - inherited; - UpdateMenuString(GetParentMenu); -end; - -procedure TTntMenuItem.MenuChanged(Rebuild: Boolean); -begin - if (not FIgnoreMenuChanged) then begin - inherited; - UpdateMenuItems(Self, GetParentMenu); - FixMenuBiDiProblem(GetParentMenu); - end; -end; - -procedure TTntMenuItem.UpdateMenuString(ParentMenu: TMenu); -var - ParentHandle: THandle; - - function NativeMenuTypeIsString: Boolean; - var - MenuItemInfo: TMenuItemInfoW; - Buffer: array[0..79] of WideChar; - begin - MenuItemInfo.cbSize := 44; // Required for Windows NT 4.0 - MenuItemInfo.fMask := MIIM_TYPE; - MenuItemInfo.dwTypeData := Buffer; // ?? - MenuItemInfo.cch := Length(Buffer); // ?? - Result := GetMenuItemInfoW(ParentHandle, Command, False, MenuItemInfo) - and ((MenuItemInfo.fType and (MFT_BITMAP or MFT_SEPARATOR or MFT_OWNERDRAW)) = 0) - end; - - function NativeMenuString: WideString; - var - Len: Integer; - begin - Assert(Win32PlatformIsUnicode); - Len := GetMenuStringW(ParentHandle, Command, nil, 0, MF_BYCOMMAND); - if Len = 0 then - Result := '' - else begin - SetLength(Result, Len + 1); - Len := GetMenuStringW(ParentHandle, Command, PWideChar(Result), Len + 1, MF_BYCOMMAND); - SetLength(Result, Len); - end; - end; - - procedure SetMenuString(const Value: WideString); - var - MenuItemInfo: TMenuItemInfoW; - Buffer: array[0..79] of WideChar; - begin - MenuItemInfo.cbSize := 44; // Required for Windows NT 4.0 - MenuItemInfo.fMask := MIIM_TYPE; - MenuItemInfo.dwTypeData := Buffer; // ?? - MenuItemInfo.cch := Length(Buffer); // ?? - if GetMenuItemInfoW(ParentHandle, Command, False, MenuItemInfo) - and ((MenuItemInfo.fType and (MFT_BITMAP or MFT_SEPARATOR or MFT_OWNERDRAW)) = 0) then - begin - MenuItemInfo.dwTypeData := PWideChar(Value); - MenuItemInfo.cch := Length(Value); - Win32Check(SetMenuItemInfoW(ParentHandle, Command, False, MenuItemInfo)); - end; - end; - - function SameEvent(A, B: TMenuMeasureItemEvent): Boolean; - begin - Result := @A = @B; - end; - -var - MenuCaption: WideString; -begin - FKeyboardLayout := GetKeyboardLayout(0); - if Parent = nil then - ParentHandle := 0 - else if (THackMenuItem(Self.Parent).FMergedWith <> nil) then - ParentHandle := THackMenuItem(Self.Parent).FMergedWith.Handle - else - ParentHandle := Parent.Handle; - - if (Win32PlatformIsUnicode) - and (Parent <> nil) and (ParentMenu <> nil) - and (ComponentState * [csReading, csDestroying] = []) - and (Visible) - and (NativeMenuTypeIsString) then begin - MenuCaption := Caption; - if (Count = 0) - and ((ShortCut <> scNone) - and ((Parent = nil) or (Parent.Parent <> nil) or not (Parent.Owner is TMainMenu{TNT-ALLOW TMainMenu}))) then - MenuCaption := MenuCaption + #9 + WideShortCutToText(ShortCut); - if (NativeMenuString <> MenuCaption) then - begin - SetMenuString(MenuCaption); - if ((Parent = ParentMenu.Items) or (THackMenuItem(Self.Parent).FMergedWith <> nil)) - and (ParentMenu is TMainMenu{TNT-ALLOW TMainMenu}) - and (ParentMenu.WindowHandle <> 0) then - DrawMenuBar(ParentMenu.WindowHandle) {top level menu bar items} - end; - end; -end; - -function TTntMenuItem.GetAlignmentDrawStyle: Word; -const - Alignments: array[TPopupAlignment] of Word = (DT_LEFT, DT_RIGHT, DT_CENTER); -var - ParentMenu: TMenu; - Alignment: TPopupAlignment; -begin - ParentMenu := GetParentMenu; - if ParentMenu is TMenu then - Alignment := paLeft - else if ParentMenu is TPopupMenu{TNT-ALLOW TPopupMenu} then - Alignment := TPopupMenu{TNT-ALLOW TPopupMenu}(ParentMenu).Alignment - else - Alignment := paLeft; - Result := Alignments[Alignment]; -end; - -procedure TTntMenuItem.AdvancedDrawItem(ACanvas: TCanvas; ARect: TRect; - State: TOwnerDrawState; TopLevel: Boolean); - - procedure DrawMenuText(BiDi: Boolean); - var - ImageList: TCustomImageList; - DrawImage, DrawGlyph: Boolean; - GlyphRect, SaveRect: TRect; - DrawStyle: Longint; - Selected: Boolean; - Win98Plus: Boolean; - Win2K: Boolean; - begin - ImageList := GetImageList; - Selected := odSelected in State; - Win98Plus := (Win32MajorVersion > 4) or - ((Win32MajorVersion = 4) and (Win32MinorVersion > 0)); - Win2K := (Win32MajorVersion > 4) and (Win32Platform = VER_PLATFORM_WIN32_NT); - with ACanvas do - begin - GlyphRect.Left := ARect.Left + 1; - DrawImage := (ImageList <> nil) and ((ImageIndex > -1) and - (ImageIndex < ImageList.Count) or Checked and ((not MenuItemHasBitmap(Self)) or - Bitmap.Empty)); - if DrawImage or MenuItemHasBitmap(Self) and not Bitmap.Empty then - begin - DrawGlyph := True; - if DrawImage then - GlyphRect.Right := GlyphRect.Left + ImageList.Width - else begin - { Need to add BitmapWidth/Height properties for TMenuItem if we're to - support them. Right now let's hardcode them to 16x16. } - GlyphRect.Right := GlyphRect.Left + 16; - end; - { Draw background pattern brush if selected } - if Checked then - begin - Inc(GlyphRect.Right); - if not Selected then - Brush.Bitmap := AllocPatternBitmap(clBtnFace, clBtnHighlight); - Inc(GlyphRect.Left); - end; - if Checked then - Dec(GlyphRect.Right); - end else begin - if (ImageList <> nil) and (not TopLevel) then - GlyphRect.Right := GlyphRect.Left + ImageList.Width - else - GlyphRect.Right := GlyphRect.Left; - DrawGlyph := False; - end; - if BiDi then begin - SaveRect := GlyphRect; - GlyphRect.Left := ARect.Right - (SaveRect.Right - ARect.Left); - GlyphRect.Right := ARect.Right - (SaveRect.Left - ARect.Left); - end; - with GlyphRect do begin - Dec(Left); - Inc(Right, 2); - end; - if Selected then begin - if DrawGlyph then begin - if BiDi then - ARect.Right := GlyphRect.Left - 1 - else - ARect.Left := GlyphRect.Right + 1; - end; - if not (Win98Plus and TopLevel) then - Brush.Color := clHighlight; - end; - if TopLevel and Win98Plus and (not Selected) - {$IFDEF COMPILER_7_UP} - and (not Win32PlatformIsXP) - {$ENDIF} - then - OffsetRect(ARect, 0, -1); - if not (Selected and DrawGlyph) then begin - if BiDi then - ARect.Right := GlyphRect.Left - 1 - else - ARect.Left := GlyphRect.Right + 1; - end; - Inc(ARect.Left, 2); - Dec(ARect.Right, 1); - DrawStyle := DT_EXPANDTABS or DT_SINGLELINE or GetAlignmentDrawStyle; - if Win2K and (odNoAccel in State) then - DrawStyle := DrawStyle or DT_HIDEPREFIX; - { Calculate vertical layout } - SaveRect := ARect; - if odDefault in State then - Font.Style := [fsBold]; - DoDrawText(ACanvas, Caption, ARect, Selected, DrawStyle or DT_CALCRECT or DT_NOCLIP); - if BiDi then begin - { the DT_CALCRECT does not take into account alignment } - ARect.Left := SaveRect.Left; - ARect.Right := SaveRect.Right; - end; - OffsetRect(ARect, 0, ((SaveRect.Bottom - SaveRect.Top) - (ARect.Bottom - ARect.Top)) div 2); - if TopLevel and Selected and Win98Plus - {$IFDEF COMPILER_7_UP} - and (not Win32PlatformIsXP) - {$ENDIF} - then - OffsetRect(ARect, 1, 0); - DoDrawText(ACanvas, Caption, ARect, Selected, DrawStyle); - if (ShortCut <> scNone) and not TopLevel then - begin - if BiDi then begin - ARect.Left := 10; - ARect.Right := ARect.Left + WideCanvasTextWidth(ACanvas, WideShortCutToText(ShortCut)); - end else begin - ARect.Left := ARect.Right; - ARect.Right := SaveRect.Right - 10; - end; - DoDrawText(ACanvas, WideShortCutToText(ShortCut), ARect, Selected, DT_RIGHT); - end; - end; - end; - -var - ParentMenu: TMenu; - SaveCaption: WideString; - SaveShortCut: TShortCut; -begin - ParentMenu := GetParentMenu; - if (not Win32PlatformIsUnicode) - or (Self.IsLine) - or ( (ParentMenu <> nil) and (ParentMenu.OwnerDraw or (GetImageList <> nil)) - and (Assigned(OnAdvancedDrawItem) or Assigned(OnDrawItem)) ) then - inherited - else begin - SaveCaption := Caption; - SaveShortCut := ShortCut; - try - FIgnoreMenuChanged := True; - try - Caption := ''; - ShortCut := scNone; - finally - FIgnoreMenuChanged := False; - end; - inherited; - finally - FIgnoreMenuChanged := True; - try - Caption := SaveCaption; - ShortCut := SaveShortcut; - finally - FIgnoreMenuChanged := False; - end; - end; - DrawMenuText((ParentMenu <> nil) and (ParentMenu.IsRightToLeft)) - end; -end; - -procedure TTntMenuItem.DoDrawText(ACanvas: TCanvas; const ACaption: WideString; - var Rect: TRect; Selected: Boolean; Flags: Longint); -var - Text: WideString; - ParentMenu: TMenu; -begin - if (not Win32PlatformIsUnicode) - or (IsLine) then - inherited DoDrawText(ACanvas, ACaption, Rect, Selected, Flags) - else begin - ParentMenu := GetParentMenu; - if (ParentMenu <> nil) and (ParentMenu.IsRightToLeft) then - begin - if Flags and DT_LEFT = DT_LEFT then - Flags := Flags and (not DT_LEFT) or DT_RIGHT - else if Flags and DT_RIGHT = DT_RIGHT then - Flags := Flags and (not DT_RIGHT) or DT_LEFT; - Flags := Flags or DT_RTLREADING; - end; - Text := ACaption; - if (Flags and DT_CALCRECT <> 0) and ((Text = '') or - (Text[1] = cHotkeyPrefix) and (Text[2] = #0)) then Text := Text + ' '; - with ACanvas do - begin - Brush.Style := bsClear; - if Default then - Font.Style := Font.Style + [fsBold]; - if not Enabled then - begin - if not Selected then - begin - OffsetRect(Rect, 1, 1); - Font.Color := clBtnHighlight; - Tnt_DrawTextW(Handle, PWideChar(Text), Length(Text), Rect, Flags); - OffsetRect(Rect, -1, -1); - end; - if Selected and (ColorToRGB(clHighlight) = ColorToRGB(clBtnShadow)) then - Font.Color := clBtnHighlight else - Font.Color := clBtnShadow; - end; - Tnt_DrawTextW(Handle, PWideChar(Text), Length(Text), Rect, Flags); - end; - end; -end; - -function TTntMenuItem.MeasureItemTextWidth(ACanvas: TCanvas; const Text: WideString): Integer; -var - R: TRect; -begin - FillChar(R, SizeOf(R), 0); - DoDrawText(ACanvas, Text, R, False, - GetAlignmentDrawStyle or DT_EXPANDTABS or DT_SINGLELINE or DT_NOCLIP or DT_CALCRECT); - Result := R.Right - R.Left; -end; - -procedure TTntMenuItem.MeasureItem(ACanvas: TCanvas; var Width, Height: Integer); -var - SaveMeasureItemEvent: TMenuMeasureItemEvent; -begin - if (not Win32PlatformIsUnicode) - or (Self.IsLine) then - inherited - else begin - SaveMeasureItemEvent := inherited OnMeasureItem; - try - inherited OnMeasureItem := nil; - inherited; - Inc(Width, MeasureItemTextWidth(ACanvas, Caption)); - Dec(Width, MeasureItemTextWidth(ACanvas, inherited Caption)); - if ShortCut <> scNone then begin - Inc(Width, MeasureItemTextWidth(ACanvas, WideShortCutToText(ShortCut))); - Dec(Width, MeasureItemTextWidth(ACanvas, ShortCutToText{TNT-ALLOW ShortCutToText}(ShortCut))); - end; - finally - inherited OnMeasureItem := SaveMeasureItemEvent; - end; - if Assigned(OnMeasureItem) then OnMeasureItem(Self, ACanvas, Width, Height); - end; -end; - -function TTntMenuItem.Find(ACaption: WideString): TMenuItem{TNT-ALLOW TMenuItem}; -var - I: Integer; -begin - Result := nil; - ACaption := WideStripHotkey(ACaption); - for I := 0 to Count - 1 do - if WideSameText(ACaption, WideStripHotkey(WideGetMenuItemCaption(Items[I]))) then - begin - Result := Items[I]; - System.Break; - end; -end; - -function TTntMenuItem.GetActionLinkClass: TMenuActionLinkClass; -begin - Result := TTntMenuActionLink; -end; - -procedure TTntMenuItem.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - if (Sender is TCustomAction{TNT-ALLOW TCustomAction}) and Supports(Sender, ITntAction) then begin - if not CheckDefaults or (Caption = '') then - Caption := TntAction_GetCaption(TCustomAction{TNT-ALLOW TCustomAction}(Sender)); - if not CheckDefaults or (Hint = '') then - Hint := TntAction_GetHint(TCustomAction{TNT-ALLOW TCustomAction}(Sender)); - end; - inherited; -end; - -{ TTntMainMenu } - -{$IFDEF COMPILER_9_UP} -function TTntMainMenu.CreateMenuItem: TMenuItem{TNT-ALLOW TMenuItem}; -begin - Result := TTntMenuItem.Create(Self); -end; -{$ENDIF} - -procedure TTntMainMenu.DoChange(Source: TMenuItem{TNT-ALLOW TMenuItem}; Rebuild: Boolean); -begin - inherited; - UpdateMenuItems(Items, Self); - if (THackMenuItem(Items).FMerged <> nil) then begin - UpdateMenuItems(THackMenuItem(Items).FMerged, Self); - end; -end; - -{ TTntPopupMenu } - -constructor TTntPopupMenu.Create(AOwner: TComponent); -begin - inherited; - PopupList.Remove(Self); - if TntPopupList <> nil then - TntPopupList.Add(Self); -end; - -{$IFDEF COMPILER_9_UP} -function TTntPopupMenu.CreateMenuItem: TMenuItem{TNT-ALLOW TMenuItem}; -begin - Result := TTntMenuItem.Create(Self); -end; -{$ENDIF} - -destructor TTntPopupMenu.Destroy; -begin - if TntPopupList <> nil then - TntPopupList.Remove(Self); - PopupList.Add(Self); - inherited; -end; - -procedure TTntPopupMenu.DoChange(Source: TMenuItem{TNT-ALLOW TMenuItem}; Rebuild: Boolean); -begin - inherited; - UpdateMenuItems(Items, Self); -end; - -procedure TTntPopupMenu.Popup(X, Y: Integer); -begin - Menus.PopupList := TntPopupList; - try - inherited; - finally - Menus.PopupList := TntPopupList.SavedPopupList; - end; -end; - -{ TTntPopupList } - -procedure TTntPopupList.WndProc(var Message: TMessage); -var - I, Item: Integer; - MenuItem: TMenuItem{TNT-ALLOW TMenuItem}; - FindKind: TFindItemKind; -begin - case Message.Msg of - WM_ENTERMENULOOP: - begin - Menus.PopupList := SavedPopupList; - for i := 0 to Count - 1 do - FixMenuBiDiProblem(Items[i]); - end; - WM_MENUSELECT: - with TWMMenuSelect(Message) do - begin - FindKind := fkCommand; - if MenuFlag and MF_POPUP <> 0 then FindKind := fkHandle; - for I := 0 to Count - 1 do - begin - if FindKind = fkHandle then - begin - if Menu <> 0 then - Item := Integer(GetSubMenu(Menu, IDItem)) else - Item := -1; - end - else - Item := IDItem; - MenuItem := TPopupMenu{TNT-ALLOW TPopupMenu}(Items[I]).FindItem(Item, FindKind); - if MenuItem <> nil then - begin - TntApplication.Hint := WideGetLongHint(WideGetMenuItemHint(MenuItem)); - Exit; - end; - end; - TntApplication.Hint := ''; - end; - end; - inherited; -end; - -initialization - TntPopupList := TTntPopupList.Create; - TntPopupList.SavedPopupList := Menus.PopupList; - -finalization - FreeAndNil(TntPopupList); - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntRegistry.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntRegistry.pas deleted file mode 100644 index 75b7dd0d6..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntRegistry.pas +++ /dev/null @@ -1,148 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntRegistry; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Registry, Windows, TntClasses; - -{TNT-WARN TRegistry} -type - TTntRegistry = class(TRegistry{TNT-ALLOW TRegistry}) - private - procedure WriteStringEx(dwType: DWORD; const Name, Value: WideString); - public - procedure GetKeyNames(Strings: TTntStrings); - procedure GetValueNames(Strings: TTntStrings); - function ReadString(const Name: WideString): WideString; - procedure WriteString(const Name, Value: WideString); - procedure WriteExpandString(const Name, Value: WideString); - end; - -implementation - -uses - RTLConsts, SysUtils, TntSysUtils; - -{ TTntRegistry } - -procedure TTntRegistry.GetKeyNames(Strings: TTntStrings); -var - Len: DWORD; - I: Integer; - Info: TRegKeyInfo; - S: WideString; -begin - if (not Win32PlatformIsUnicode) then - inherited GetKeyNames(Strings.AnsiStrings) - else begin - Strings.Clear; - if GetKeyInfo(Info) then - begin - SetLength(S, (Info.MaxSubKeyLen + 1) * 2); - for I := 0 to Info.NumSubKeys - 1 do - begin - Len := (Info.MaxSubKeyLen + 1) * 2; - if RegEnumKeyExW(CurrentKey, I, PWideChar(S), Len, nil, nil, nil, nil) = ERROR_SUCCESS then - Strings.Add(PWideChar(S)); - end; - end; - end; -end; - -{$IFNDEF COMPILER_9_UP} // fix declaration for RegEnumValueW (lpValueName is a PWideChar) -function RegEnumValueW(hKey: HKEY; dwIndex: DWORD; lpValueName: PWideChar; - var lpcbValueName: DWORD; lpReserved: Pointer; lpType: PDWORD; - lpData: PByte; lpcbData: PDWORD): Longint; stdcall; external advapi32 name 'RegEnumValueW'; -{$ENDIF} - -procedure TTntRegistry.GetValueNames(Strings: TTntStrings); -var - Len: DWORD; - I: Integer; - Info: TRegKeyInfo; - S: WideString; -begin - if (not Win32PlatformIsUnicode) then - inherited GetValueNames(Strings.AnsiStrings) - else begin - Strings.Clear; - if GetKeyInfo(Info) then - begin - SetLength(S, Info.MaxValueLen + 1); - for I := 0 to Info.NumValues - 1 do - begin - Len := Info.MaxValueLen + 1; - RegEnumValueW(CurrentKey, I, PWideChar(S), Len, nil, nil, nil, nil); - Strings.Add(PWideChar(S)); - end; - end; - end; -end; - -function TTntRegistry.ReadString(const Name: WideString): WideString; -var - DataType: Cardinal; - BufSize: Cardinal; -begin - if (not Win32PlatformIsUnicode) then - result := inherited ReadString(Name) - else begin - // get length and type - DataType := REG_NONE; - if RegQueryValueExW(CurrentKey, PWideChar(Name), nil, - @DataType, nil, @BufSize) <> ERROR_SUCCESS then - Result := '' - else begin - // check type - if not (DataType in [REG_SZ, REG_EXPAND_SZ]) then - raise ERegistryException.CreateFmt(SInvalidRegType, [Name]); - if BufSize = 1 then - BufSize := SizeOf(WideChar); // sometimes this occurs for single character values! - SetLength(Result, BufSize div SizeOf(WideChar)); - if RegQueryValueExW(CurrentKey, PWideChar(Name), nil, - @DataType, PByte(PWideChar(Result)), @BufSize) <> ERROR_SUCCESS then - raise ERegistryException.CreateFmt(SRegGetDataFailed, [Name]); - Result := PWideChar(Result); - end - end -end; - -procedure TTntRegistry.WriteStringEx(dwType: DWORD; const Name, Value: WideString); -begin - Assert(dwType in [REG_SZ, REG_EXPAND_SZ]); - if (not Win32PlatformIsUnicode) then begin - if dwType = REG_SZ then - inherited WriteString(Name, Value) - else - inherited WriteExpandString(Name, Value); - end else begin - if RegSetValueExW(CurrentKey, PWideChar(Name), 0, dwType, - PWideChar(Value), (Length(Value) + 1) * SizeOf(WideChar)) <> ERROR_SUCCESS then - raise ERegistryException.CreateFmt(SRegSetDataFailed, [Name]); - end; -end; - -procedure TTntRegistry.WriteString(const Name, Value: WideString); -begin - WriteStringEx(REG_SZ, Name, Value); -end; - -procedure TTntRegistry.WriteExpandString(const Name, Value: WideString); -begin - WriteStringEx(REG_EXPAND_SZ, Name, Value); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntStdActns.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntStdActns.pas deleted file mode 100644 index c2c10a50f..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntStdActns.pas +++ /dev/null @@ -1,1922 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntStdActns; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Classes, ActnList, TntActnList, StdActns, TntDialogs; - -type -{TNT-WARN THintAction} - TTntHintAction = class(THintAction{TNT-ALLOW THintAction}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - public - property Caption: WideString read GetCaption write SetCaption; - published - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TEditAction} - TTntEditAction = class(TEditAction{TNT-ALLOW TEditAction}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TEditCut} - TTntEditCut = class(TEditCut{TNT-ALLOW TEditCut}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TEditCopy} - TTntEditCopy = class(TEditCopy{TNT-ALLOW TEditCopy}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TEditPaste} - TTntEditPaste = class(TEditPaste{TNT-ALLOW TEditPaste}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TEditSelectAll} - TTntEditSelectAll = class(TEditSelectAll{TNT-ALLOW TEditSelectAll}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TEditUndo} - TTntEditUndo = class(TEditUndo{TNT-ALLOW TEditUndo}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TEditDelete} - TTntEditDelete = class(TEditDelete{TNT-ALLOW TEditDelete}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - procedure UpdateTarget(Target: TObject); override; - procedure ExecuteTarget(Target: TObject); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TWindowAction} - TTntWindowAction = class(TWindowAction{TNT-ALLOW TWindowAction}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TWindowClose} - TTntWindowClose = class(TWindowClose{TNT-ALLOW TWindowClose}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TWindowCascade} - TTntWindowCascade = class(TWindowCascade{TNT-ALLOW TWindowCascade}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TWindowTileHorizontal} - TTntWindowTileHorizontal = class(TWindowTileHorizontal{TNT-ALLOW TWindowTileHorizontal}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TWindowTileVertical} - TTntWindowTileVertical = class(TWindowTileVertical{TNT-ALLOW TWindowTileVertical}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TWindowMinimizeAll} - TTntWindowMinimizeAll = class(TWindowMinimizeAll{TNT-ALLOW TWindowMinimizeAll}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TWindowArrange} - TTntWindowArrange = class(TWindowArrange{TNT-ALLOW TWindowArrange}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN THelpAction} - TTntHelpAction = class(THelpAction{TNT-ALLOW THelpAction}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN THelpContents} - TTntHelpContents = class(THelpContents{TNT-ALLOW THelpContents}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN THelpTopicSearch} - TTntHelpTopicSearch = class(THelpTopicSearch{TNT-ALLOW THelpTopicSearch}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN THelpOnHelp} - TTntHelpOnHelp = class(THelpOnHelp{TNT-ALLOW THelpOnHelp}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN THelpContextAction} - TTntHelpContextAction = class(THelpContextAction{TNT-ALLOW THelpContextAction}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TCommonDialogAction} - TTntCommonDialogAction = class(TCommonDialogAction{TNT-ALLOW TCommonDialogAction}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - public - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TFileAction} - TTntFileAction = class(TFileAction{TNT-ALLOW TFileAction}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - public - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TFileOpen} - TTntFileOpen = class(TFileOpen{TNT-ALLOW TFileOpen}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function GetDialog: TTntOpenDialog; - protected - procedure DefineProperties(Filer: TFiler); override; - function GetDialogClass: TCommonDialogClass; override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Dialog: TTntOpenDialog read GetDialog; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TFileOpenWith} - TTntFileOpenWith = class(TFileOpenWith{TNT-ALLOW TFileOpenWith}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function GetDialog: TTntOpenDialog; - protected - procedure DefineProperties(Filer: TFiler); override; - function GetDialogClass: TCommonDialogClass; override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Dialog: TTntOpenDialog read GetDialog; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TFileSaveAs} - TTntFileSaveAs = class(TFileSaveAs{TNT-ALLOW TFileSaveAs}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function GetDialog: TTntSaveDialog; - protected - procedure DefineProperties(Filer: TFiler); override; - function GetDialogClass: TCommonDialogClass; override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Dialog: TTntSaveDialog read GetDialog; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TFilePrintSetup} - TTntFilePrintSetup = class(TFilePrintSetup{TNT-ALLOW TFilePrintSetup}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - - {$IFDEF COMPILER_7_UP} -{TNT-WARN TFilePageSetup} - TTntFilePageSetup = class(TFilePageSetup{TNT-ALLOW TFilePageSetup}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - {$ENDIF} - -{TNT-WARN TFileExit} - TTntFileExit = class(TFileExit{TNT-ALLOW TFileExit}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TSearchAction} - TTntSearchAction = class(TSearchAction{TNT-ALLOW TSearchAction}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - public - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TSearchFind} - TTntSearchFind = class(TSearchFind{TNT-ALLOW TSearchFind}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TSearchReplace} - TTntSearchReplace = class(TSearchReplace{TNT-ALLOW TSearchReplace}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TSearchFindFirst} - TTntSearchFindFirst = class(TSearchFindFirst{TNT-ALLOW TSearchFindFirst}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TSearchFindNext} - TTntSearchFindNext = class(TSearchFindNext{TNT-ALLOW TSearchFindNext}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TFontEdit} - TTntFontEdit = class(TFontEdit{TNT-ALLOW TFontEdit}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TColorSelect} - TTntColorSelect = class(TColorSelect{TNT-ALLOW TColorSelect}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -{TNT-WARN TPrintDlg} - TTntPrintDlg = class(TPrintDlg{TNT-ALLOW TPrintDlg}, ITntAction) - private - function GetCaption: WideString; - procedure SetCaption(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - protected - procedure DefineProperties(Filer: TFiler); override; - public - procedure Assign(Source: TPersistent); override; - published - property Caption: WideString read GetCaption write SetCaption; - property Hint: WideString read GetHint write SetHint; - end; - -procedure TntStdActn_AfterInherited_Assign(Action: TCustomAction{TNT-ALLOW TCustomAction}; Source: TPersistent); - -implementation - -uses - Dialogs, TntClasses; - -{TNT-IGNORE-UNIT} - -procedure TntStdActn_AfterInherited_Assign(Action: TCustomAction{TNT-ALLOW TCustomAction}; Source: TPersistent); -begin - TntAction_AfterInherited_Assign(Action, Source); - // TCommonDialogAction - if (Action is TCommonDialogAction) and (Source is TCommonDialogAction) then begin - TCommonDialogAction(Action).BeforeExecute := TCommonDialogAction(Source).BeforeExecute; - TCommonDialogAction(Action).OnAccept := TCommonDialogAction(Source).OnAccept; - TCommonDialogAction(Action).OnCancel := TCommonDialogAction(Source).OnCancel; - end; - // TFileOpen - if (Action is TFileOpen) and (Source is TFileOpen) then begin - {$IFDEF COMPILER_7_UP} - TFileOpen(Action).UseDefaultApp := TFileOpen(Source).UseDefaultApp; - {$ENDIF} - end; - // TFileOpenWith - if (Action is TFileOpenWith) and (Source is TFileOpenWith) then begin - TFileOpenWith(Action).FileName := TFileOpenWith(Source).FileName; - {$IFDEF COMPILER_7_UP} - TFileOpenWith(Action).AfterOpen := TFileOpenWith(Source).AfterOpen; - {$ENDIF} - end; - // TSearchFindNext - if (Action is TSearchFindNext) and (Source is TSearchFindNext) then begin - TSearchFindNext(Action).SearchFind := TSearchFindNext(Source).SearchFind; - end; -end; - -//------------------------- -// TNT STD ACTNS -//------------------------- - -{ TTntHintAction } - -procedure TTntHintAction.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntHintAction.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntHintAction.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntHintAction.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntHintAction.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntHintAction.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntEditAction } - -procedure TTntEditAction.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntEditAction.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntEditAction.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntEditAction.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntEditAction.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntEditAction.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntEditCut } - -procedure TTntEditCut.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntEditCut.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntEditCut.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntEditCut.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntEditCut.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntEditCut.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntEditCopy } - -procedure TTntEditCopy.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntEditCopy.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntEditCopy.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntEditCopy.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntEditCopy.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntEditCopy.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntEditPaste } - -procedure TTntEditPaste.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntEditPaste.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntEditPaste.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntEditPaste.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntEditPaste.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntEditPaste.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntEditSelectAll } - -procedure TTntEditSelectAll.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntEditSelectAll.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntEditSelectAll.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntEditSelectAll.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntEditSelectAll.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntEditSelectAll.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntEditUndo } - -procedure TTntEditUndo.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntEditUndo.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntEditUndo.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntEditUndo.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntEditUndo.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntEditUndo.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntEditDelete } - -procedure TTntEditDelete.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntEditDelete.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntEditDelete.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntEditDelete.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntEditDelete.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntEditDelete.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -procedure TTntEditDelete.UpdateTarget(Target: TObject); -begin - Enabled := True; -end; - -procedure TTntEditDelete.ExecuteTarget(Target: TObject); -begin - if GetControl(Target).SelLength = 0 then - GetControl(Target).SelLength := 1; - GetControl(Target).ClearSelection -end; - -{ TTntWindowAction } - -procedure TTntWindowAction.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntWindowAction.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntWindowAction.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntWindowAction.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntWindowAction.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntWindowAction.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntWindowClose } - -procedure TTntWindowClose.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntWindowClose.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntWindowClose.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntWindowClose.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntWindowClose.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntWindowClose.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntWindowCascade } - -procedure TTntWindowCascade.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntWindowCascade.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntWindowCascade.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntWindowCascade.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntWindowCascade.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntWindowCascade.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntWindowTileHorizontal } - -procedure TTntWindowTileHorizontal.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntWindowTileHorizontal.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntWindowTileHorizontal.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntWindowTileHorizontal.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntWindowTileHorizontal.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntWindowTileHorizontal.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntWindowTileVertical } - -procedure TTntWindowTileVertical.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntWindowTileVertical.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntWindowTileVertical.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntWindowTileVertical.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntWindowTileVertical.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntWindowTileVertical.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntWindowMinimizeAll } - -procedure TTntWindowMinimizeAll.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntWindowMinimizeAll.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntWindowMinimizeAll.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntWindowMinimizeAll.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntWindowMinimizeAll.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntWindowMinimizeAll.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntWindowArrange } - -procedure TTntWindowArrange.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntWindowArrange.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntWindowArrange.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntWindowArrange.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntWindowArrange.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntWindowArrange.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntHelpAction } - -procedure TTntHelpAction.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntHelpAction.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntHelpAction.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntHelpAction.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntHelpAction.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntHelpAction.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntHelpContents } - -procedure TTntHelpContents.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntHelpContents.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntHelpContents.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntHelpContents.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntHelpContents.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntHelpContents.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntHelpTopicSearch } - -procedure TTntHelpTopicSearch.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntHelpTopicSearch.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntHelpTopicSearch.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntHelpTopicSearch.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntHelpTopicSearch.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntHelpTopicSearch.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntHelpOnHelp } - -procedure TTntHelpOnHelp.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntHelpOnHelp.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntHelpOnHelp.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntHelpOnHelp.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntHelpOnHelp.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntHelpOnHelp.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntHelpContextAction } - -procedure TTntHelpContextAction.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntHelpContextAction.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntHelpContextAction.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntHelpContextAction.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntHelpContextAction.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntHelpContextAction.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntCommonDialogAction } - -procedure TTntCommonDialogAction.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntCommonDialogAction.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntCommonDialogAction.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntCommonDialogAction.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntCommonDialogAction.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntCommonDialogAction.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntFileAction } - -procedure TTntFileAction.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntFileAction.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntFileAction.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntFileAction.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntFileAction.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntFileAction.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntFileOpen } - -procedure TTntFileOpen.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntFileOpen.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntFileOpen.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntFileOpen.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntFileOpen.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntFileOpen.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -function TTntFileOpen.GetDialog: TTntOpenDialog; -begin - Result := inherited Dialog as TTntOpenDialog; -end; - -function TTntFileOpen.GetDialogClass: TCommonDialogClass; -begin - Result := TTntOpenDialog; -end; - -{ TTntFileOpenWith } - -procedure TTntFileOpenWith.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntFileOpenWith.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntFileOpenWith.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntFileOpenWith.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntFileOpenWith.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntFileOpenWith.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -function TTntFileOpenWith.GetDialog: TTntOpenDialog; -begin - Result := inherited Dialog as TTntOpenDialog; -end; - -function TTntFileOpenWith.GetDialogClass: TCommonDialogClass; -begin - Result := TTntOpenDialog; -end; - -{ TTntFileSaveAs } - -procedure TTntFileSaveAs.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntFileSaveAs.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntFileSaveAs.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntFileSaveAs.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntFileSaveAs.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntFileSaveAs.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -function TTntFileSaveAs.GetDialog: TTntSaveDialog; -begin - Result := TOpenDialog(inherited Dialog) as TTntSaveDialog; -end; - -function TTntFileSaveAs.GetDialogClass: TCommonDialogClass; -begin - Result := TTntSaveDialog; -end; - -{ TTntFilePrintSetup } - -procedure TTntFilePrintSetup.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntFilePrintSetup.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntFilePrintSetup.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntFilePrintSetup.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntFilePrintSetup.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntFilePrintSetup.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - - {$IFDEF COMPILER_7_UP} - -{ TTntFilePageSetup } - -procedure TTntFilePageSetup.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntFilePageSetup.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntFilePageSetup.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntFilePageSetup.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntFilePageSetup.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntFilePageSetup.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - {$ENDIF} - -{ TTntFileExit } - -procedure TTntFileExit.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntFileExit.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntFileExit.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntFileExit.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntFileExit.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntFileExit.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntSearchAction } - -procedure TTntSearchAction.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntSearchAction.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntSearchAction.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntSearchAction.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntSearchAction.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntSearchAction.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntSearchFind } - -procedure TTntSearchFind.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntSearchFind.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntSearchFind.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntSearchFind.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntSearchFind.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntSearchFind.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntSearchReplace } - -procedure TTntSearchReplace.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntSearchReplace.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntSearchReplace.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntSearchReplace.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntSearchReplace.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntSearchReplace.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntSearchFindFirst } - -procedure TTntSearchFindFirst.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntSearchFindFirst.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntSearchFindFirst.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntSearchFindFirst.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntSearchFindFirst.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntSearchFindFirst.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntSearchFindNext } - -procedure TTntSearchFindNext.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntSearchFindNext.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntSearchFindNext.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntSearchFindNext.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntSearchFindNext.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntSearchFindNext.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntFontEdit } - -procedure TTntFontEdit.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntFontEdit.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntFontEdit.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntFontEdit.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntFontEdit.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntFontEdit.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntColorSelect } - -procedure TTntColorSelect.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntColorSelect.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntColorSelect.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntColorSelect.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntColorSelect.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntColorSelect.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -{ TTntPrintDlg } - -procedure TTntPrintDlg.Assign(Source: TPersistent); -begin - inherited; - TntStdActn_AfterInherited_Assign(Self, Source); -end; - -procedure TTntPrintDlg.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntPrintDlg.GetCaption: WideString; -begin - Result := TntAction_GetCaption(Self); -end; - -procedure TTntPrintDlg.SetCaption(const Value: WideString); -begin - TntAction_SetCaption(Self, Value); -end; - -function TTntPrintDlg.GetHint: WideString; -begin - Result := TntAction_GetHint(Self); -end; - -procedure TTntPrintDlg.SetHint(const Value: WideString); -begin - TntAction_SetHint(Self, Value); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntStdCtrls.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntStdCtrls.pas deleted file mode 100644 index db53e5740..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntStdCtrls.pas +++ /dev/null @@ -1,3215 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntStdCtrls; - -{$INCLUDE TntCompilers.inc} - -interface - -{ TODO: Implement TCustomListBox.KeyPress, OnDataFind. } - -uses - Windows, Messages, Classes, Controls, TntControls, StdCtrls, Graphics, - TntClasses, TntSysUtils; - -{TNT-WARN TCustomEdit} -type - TTntCustomEdit = class(TCustomEdit{TNT-ALLOW TCustomEdit}) - private - FPasswordChar: WideChar; - procedure SetSelText(const Value: WideString); - function GetText: WideString; - procedure SetText(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - function GetPasswordChar: WideChar; - procedure SetPasswordChar(const Value: WideChar); - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure CreateWnd; override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - function GetSelStart: Integer; reintroduce; virtual; - procedure SetSelStart(const Value: Integer); reintroduce; virtual; - function GetSelLength: Integer; reintroduce; virtual; - procedure SetSelLength(const Value: Integer); reintroduce; virtual; - function GetSelText: WideString; reintroduce; virtual; - property PasswordChar: WideChar read GetPasswordChar write SetPasswordChar default #0; - public - property SelText: WideString read GetSelText write SetSelText; - property SelStart: Integer read GetSelStart write SetSelStart; - property SelLength: Integer read GetSelLength write SetSelLength; - property Text: WideString read GetText write SetText; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TEdit} - TTntEdit = class(TTntCustomEdit) - published - property Align; - property Anchors; - property AutoSelect; - property AutoSize; - property BevelEdges; - property BevelInner; - property BevelKind default bkNone; - property BevelOuter; - property BevelWidth; - property BiDiMode; - property BorderStyle; - property CharCase; - property Color; - property Constraints; - property Ctl3D; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property Font; - property HideSelection; - property ImeMode; - property ImeName; - property MaxLength; - property OEMConvert; - property ParentBiDiMode; - property ParentColor; - property ParentCtl3D; - property ParentFont; - property ParentShowHint; - property PasswordChar; - property PopupMenu; - property ReadOnly; - property ShowHint; - property TabOrder; - property TabStop; - property Text; - property Visible; - property OnChange; - property OnClick; - property OnContextPopup; - property OnDblClick; - property OnDragDrop; - property OnDragOver; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnKeyDown; - property OnKeyPress; - property OnKeyUp; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - property OnStartDock; - property OnStartDrag; - end; - -type - TTntCustomMemo = class; - - TTntMemoStrings = class(TTntStrings) - protected - FMemo: TCustomMemo{TNT-ALLOW TCustomMemo}; - FMemoLines: TStrings{TNT-ALLOW TStrings}; - FRichEditMode: Boolean; - FLineBreakStyle: TTntTextLineBreakStyle; - function Get(Index: Integer): WideString; override; - function GetCount: Integer; override; - function GetTextStr: WideString; override; - procedure Put(Index: Integer; const S: WideString); override; - procedure SetUpdateState(Updating: Boolean); override; - public - constructor Create; - procedure SetTextStr(const Value: WideString); override; - procedure Clear; override; - procedure Delete(Index: Integer); override; - procedure Insert(Index: Integer; const S: WideString); override; - end; - -{TNT-WARN TCustomMemo} - TTntCustomMemo = class(TCustomMemo{TNT-ALLOW TCustomMemo}) - private - FLines: TTntStrings; - procedure SetSelText(const Value: WideString); - function GetText: WideString; - procedure SetText(const Value: WideString); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - procedure SetLines(const Value: TTntStrings); virtual; - function GetSelStart: Integer; reintroduce; virtual; - procedure SetSelStart(const Value: Integer); reintroduce; virtual; - function GetSelLength: Integer; reintroduce; virtual; - procedure SetSelLength(const Value: Integer); reintroduce; virtual; - function GetSelText: WideString; reintroduce; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - property SelText: WideString read GetSelText write SetSelText; - property SelStart: Integer read GetSelStart write SetSelStart; - property SelLength: Integer read GetSelLength write SetSelLength; - property Text: WideString read GetText write SetText; - property Lines: TTntStrings read FLines write SetLines; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TMemo} - TTntMemo = class(TTntCustomMemo) - published - property Align; - property Alignment; - property Anchors; - property BevelEdges; - property BevelInner; - property BevelKind default bkNone; - property BevelOuter; - property BiDiMode; - property BorderStyle; - property Color; - property Constraints; - property Ctl3D; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property Font; - property HideSelection; - property ImeMode; - property ImeName; - property Lines; - property MaxLength; - property OEMConvert; - property ParentBiDiMode; - property ParentColor; - property ParentCtl3D; - property ParentFont; - property ParentShowHint; - property PopupMenu; - property ReadOnly; - property ScrollBars; - property ShowHint; - property TabOrder; - property TabStop; - property Visible; - property WantReturns; - property WantTabs; - property WordWrap; - property OnChange; - property OnClick; - property OnContextPopup; - property OnDblClick; - property OnDragDrop; - property OnDragOver; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnKeyDown; - property OnKeyPress; - property OnKeyUp; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - property OnStartDock; - property OnStartDrag; - end; - - TTntComboBoxStrings = class(TTntStrings) - protected - function Get(Index: Integer): WideString; override; - function GetCount: Integer; override; - function GetObject(Index: Integer): TObject; override; - procedure PutObject(Index: Integer; AObject: TObject); override; - procedure SetUpdateState(Updating: Boolean); override; - public - ComboBox: TCustomComboBox{TNT-ALLOW TCustomComboBox}; - function Add(const S: WideString): Integer; override; - procedure Clear; override; - procedure Delete(Index: Integer); override; - function IndexOf(const S: WideString): Integer; override; - procedure Insert(Index: Integer; const S: WideString); override; - end; - -type - TWMCharMsgHandler = procedure(var Message: TWMChar) of object; - -{$IFDEF DELPHI_7} // fix for Delphi 7 only -{ TD7PatchedComboBoxStrings } -type - TD7PatchedComboBoxStrings = class(TCustomComboBoxStrings) - protected - function Get(Index: Integer): string{TNT-ALLOW string}; override; - public - function Add(const S: string{TNT-ALLOW string}): Integer; override; - procedure Insert(Index: Integer; const S: string{TNT-ALLOW string}); override; - end; -{$ENDIF} - -type - ITntComboFindString = interface - ['{63BEBEF4-B1A2-495A-B558-7487B66F6827}'] - function FindString(const Value: WideString; StartPos: Integer): Integer; - end; - -{TNT-WARN TCustomComboBox} -type - TTntCustomComboBox = class(TCustomComboBox{TNT-ALLOW TCustomComboBox}, - IWideCustomListControl) - private - FItems: TTntStrings; - FSaveItems: TTntStrings; - FSaveItemIndex: Integer; - FFilter: WideString; - FLastTime: Cardinal; - function GetItems: TTntStrings; - function GetSelStart: Integer; - procedure SetSelStart(const Value: Integer); - function GetSelLength: Integer; - procedure SetSelLength(const Value: Integer); - function GetSelText: WideString; - procedure SetSelText(const Value: WideString); - function GetText: WideString; - procedure SetText(const Value: WideString); - procedure CNCommand(var Message: TWMCommand); message CN_COMMAND; - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - procedure WMChar(var Message: TWMChar); message WM_CHAR; - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - procedure DestroyWnd; override; - function GetAutoComplete_UniqueMatchOnly: Boolean; dynamic; - function GetAutoComplete_PreserveDataEntryCase: Boolean; dynamic; - procedure DoEditCharMsg(var Message: TWMChar); virtual; - procedure CreateWnd; override; - procedure ComboWndProc(var Message: TMessage; ComboWnd: HWnd; ComboProc: Pointer); override; - procedure DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState); override; - procedure KeyPress(var Key: AnsiChar); override; - {$IFDEF DELPHI_7} // fix for Delphi 7 only - function GetItemsClass: TCustomComboBoxStringsClass; override; - {$ENDIF} - procedure SetItems(const Value: TTntStrings); reintroduce; virtual; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - procedure CopySelection(Destination: TCustomListControl); override; - procedure AddItem(const Item: WideString; AObject: TObject); reintroduce; virtual; - public - property SelText: WideString read GetSelText write SetSelText; - property SelStart: Integer read GetSelStart write SetSelStart; - property SelLength: Integer read GetSelLength write SetSelLength; - property Text: WideString read GetText write SetText; - property Items: TTntStrings read GetItems write SetItems; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TComboBox} - TTntComboBox = class(TTntCustomComboBox) - published - property Align; - property AutoComplete default True; - {$IFDEF COMPILER_9_UP} - property AutoCompleteDelay default 500; - {$ENDIF} - property AutoDropDown default False; - {$IFDEF COMPILER_7_UP} - property AutoCloseUp default False; - {$ENDIF} - property BevelEdges; - property BevelInner; - property BevelKind default bkNone; - property BevelOuter; - property Style; {Must be published before Items} - property Anchors; - property BiDiMode; - property CharCase; - property Color; - property Constraints; - property Ctl3D; - property DragCursor; - property DragKind; - property DragMode; - property DropDownCount; - property Enabled; - property Font; - property ImeMode; - property ImeName; - property ItemHeight; - property ItemIndex default -1; - property MaxLength; - property ParentBiDiMode; - property ParentColor; - property ParentCtl3D; - property ParentFont; - property ParentShowHint; - property PopupMenu; - property ShowHint; - property Sorted; - property TabOrder; - property TabStop; - property Text; - property Visible; - property OnChange; - property OnClick; - property OnCloseUp; - property OnContextPopup; - property OnDblClick; - property OnDragDrop; - property OnDragOver; - property OnDrawItem; - property OnDropDown; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnKeyDown; - property OnKeyPress; - property OnKeyUp; - property OnMeasureItem; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnSelect; - property OnStartDock; - property OnStartDrag; - property Items; { Must be published after OnMeasureItem } - end; - - TLBGetWideDataEvent = procedure(Control: TWinControl; Index: Integer; - var Data: WideString) of object; - - TAccessCustomListBox = class(TCustomListBox{TNT-ALLOW TCustomListBox}); - - TTntListBoxStrings = class(TTntStrings) - private - FListBox: TAccessCustomListBox; - function GetListBox: TCustomListBox{TNT-ALLOW TCustomListBox}; - procedure SetListBox(const Value: TCustomListBox{TNT-ALLOW TCustomListBox}); - protected - procedure Put(Index: Integer; const S: WideString); override; - function Get(Index: Integer): WideString; override; - function GetCount: Integer; override; - function GetObject(Index: Integer): TObject; override; - procedure PutObject(Index: Integer; AObject: TObject); override; - procedure SetUpdateState(Updating: Boolean); override; - public - function Add(const S: WideString): Integer; override; - procedure Clear; override; - procedure Delete(Index: Integer); override; - procedure Exchange(Index1, Index2: Integer); override; - function IndexOf(const S: WideString): Integer; override; - procedure Insert(Index: Integer; const S: WideString); override; - procedure Move(CurIndex, NewIndex: Integer); override; - property ListBox: TCustomListBox{TNT-ALLOW TCustomListBox} read GetListBox write SetListBox; - end; - -{TNT-WARN TCustomListBox} -type - TTntCustomListBox = class(TCustomListBox{TNT-ALLOW TCustomListBox}, IWideCustomListControl) - private - FItems: TTntStrings; - FSaveItems: TTntStrings; - FSaveTopIndex: Integer; - FSaveItemIndex: Integer; - FOnData: TLBGetWideDataEvent; - procedure SetItems(const Value: TTntStrings); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - procedure LBGetText(var Message: TMessage); message LB_GETTEXT; - procedure LBGetTextLen(var Message: TMessage); message LB_GETTEXTLEN; - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - procedure CreateWnd; override; - procedure DestroyWnd; override; - procedure DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState); override; - property OnData: TLBGetWideDataEvent read FOnData write FOnData; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - procedure CopySelection(Destination: TCustomListControl); override; - procedure AddItem(const Item: WideString; AObject: TObject); reintroduce; virtual; - property Items: TTntStrings read FItems write SetItems; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TListBox} - TTntListBox = class(TTntCustomListBox) - published - property Style; - property AutoComplete; - {$IFDEF COMPILER_9_UP} - property AutoCompleteDelay; - {$ENDIF} - property Align; - property Anchors; - property BevelEdges; - property BevelInner; - property BevelKind default bkNone; - property BevelOuter; - property BevelWidth; - property BiDiMode; - property BorderStyle; - property Color; - property Columns; - property Constraints; - property Ctl3D; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property ExtendedSelect; - property Font; - property ImeMode; - property ImeName; - property IntegralHeight; - property ItemHeight; - property Items; - property MultiSelect; - property ParentBiDiMode; - property ParentColor; - property ParentCtl3D; - property ParentFont; - property ParentShowHint; - property PopupMenu; - property ScrollWidth; - property ShowHint; - property Sorted; - property TabOrder; - property TabStop; - property TabWidth; - property Visible; - property OnClick; - property OnContextPopup; - property OnData; - property OnDataFind; - property OnDataObject; - property OnDblClick; - property OnDragDrop; - property OnDragOver; - property OnDrawItem; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnKeyDown; - property OnKeyPress; - property OnKeyUp; - property OnMeasureItem; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - property OnStartDock; - property OnStartDrag; - end; - -{TNT-WARN TCustomLabel} - TTntCustomLabel = class(TCustomLabel{TNT-ALLOW TCustomLabel}) - private - function GetCaption: TWideCaption; - procedure SetCaption(const Value: TWideCaption); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsCaptionStored: Boolean; - function IsHintStored: Boolean; - procedure CMHintShow(var Message: TMessage); message CM_HINTSHOW; - procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR; - protected - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - function GetLabelText: WideString; reintroduce; virtual; - procedure DoDrawText(var Rect: TRect; Flags: Longint); override; - property Caption: TWideCaption read GetCaption write SetCaption stored IsCaptionStored; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TLabel} - TTntLabel = class(TTntCustomLabel) - published - property Align; - property Alignment; - property Anchors; - property AutoSize; - property BiDiMode; - property Caption; - property Color {$IFDEF COMPILER_7_UP} nodefault {$ENDIF}; - property Constraints; - property DragCursor; - property DragKind; - property DragMode; - {$IFDEF COMPILER_9_UP} - property EllipsisPosition; - {$ENDIF} - property Enabled; - property FocusControl; - property Font; - property ParentBiDiMode; - property ParentColor; - property ParentFont; - property ParentShowHint; - property PopupMenu; - property ShowAccelChar; - property ShowHint; - property Transparent; - property Layout; - property Visible; - property WordWrap; - property OnClick; - property OnContextPopup; - property OnDblClick; - property OnDragDrop; - property OnDragOver; - property OnEndDock; - property OnEndDrag; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - property OnMouseMove; - property OnMouseUp; - property OnMouseEnter; - property OnMouseLeave; - property OnStartDock; - property OnStartDrag; - end; - -{TNT-WARN TButton} - TTntButton = class(TButton{TNT-ALLOW TButton}) - private - function GetCaption: TWideCaption; - procedure SetCaption(const Value: TWideCaption); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsCaptionStored: Boolean; - function IsHintStored: Boolean; - procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR; - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - published - property Caption: TWideCaption read GetCaption write SetCaption stored IsCaptionStored; - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TCustomCheckBox} - TTntCustomCheckBox = class(TCustomCheckBox{TNT-ALLOW TCustomCheckBox}) - private - function GetCaption: TWideCaption; - procedure SetCaption(const Value: TWideCaption); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsCaptionStored: Boolean; - function IsHintStored: Boolean; - procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR; - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - public - property Caption: TWideCaption read GetCaption write SetCaption stored IsCaptionStored; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TCheckBox} - TTntCheckBox = class(TTntCustomCheckBox) - published - property Action; - property Align; - property Alignment; - property AllowGrayed; - property Anchors; - property BiDiMode; - property Caption; - property Checked; - property Color {$IFDEF COMPILER_7_UP} nodefault {$ENDIF}; - property Constraints; - property Ctl3D; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property Font; - property ParentBiDiMode; - property ParentColor; - property ParentCtl3D; - property ParentFont; - property ParentShowHint; - property PopupMenu; - property ShowHint; - property State; - property TabOrder; - property TabStop; - property Visible; - {$IFDEF COMPILER_7_UP} - property WordWrap; - {$ENDIF} - property OnClick; - property OnContextPopup; - property OnDragDrop; - property OnDragOver; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnKeyDown; - property OnKeyPress; - property OnKeyUp; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - property OnStartDock; - property OnStartDrag; - end; - -{TNT-WARN TRadioButton} - TTntRadioButton = class(TRadioButton{TNT-ALLOW TRadioButton}) - private - function GetCaption: TWideCaption; - procedure SetCaption(const Value: TWideCaption); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsCaptionStored: Boolean; - function IsHintStored: Boolean; - procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR; - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - published - property Caption: TWideCaption read GetCaption write SetCaption stored IsCaptionStored; - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TScrollBar} - TTntScrollBar = class(TScrollBar{TNT-ALLOW TScrollBar}) - private - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsHintStored: Boolean; - protected - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TCustomGroupBox} - TTntCustomGroupBox = class(TCustomGroupBox{TNT-ALLOW TCustomGroupBox}) - private - function GetCaption: TWideCaption; - procedure SetCaption(const Value: TWideCaption); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsCaptionStored: Boolean; - function IsHintStored: Boolean; - procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR; - protected - procedure Paint; override; - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - property Caption: TWideCaption read GetCaption write SetCaption stored IsCaptionStored; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TGroupBox} - TTntGroupBox = class(TTntCustomGroupBox) - published - property Align; - property Anchors; - property BiDiMode; - property Caption; - property Color; - property Constraints; - property Ctl3D; - property DockSite; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property Font; - {$IFDEF COMPILER_10_UP} - property Padding; - {$ENDIF} - {$IFDEF COMPILER_7_UP} - property ParentBackground default True; - {$ENDIF} - property ParentBiDiMode; - property ParentColor; - property ParentCtl3D; - property ParentFont; - property ParentShowHint; - property PopupMenu; - property ShowHint; - property TabOrder; - property TabStop; - property Visible; - {$IFDEF COMPILER_9_UP} - property OnAlignInsertBefore; - property OnAlignPosition; - {$ENDIF} - property OnClick; - property OnContextPopup; - property OnDblClick; - property OnDragDrop; - property OnDockDrop; - property OnDockOver; - property OnDragOver; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnGetSiteInfo; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - property OnStartDock; - property OnStartDrag; - property OnUnDock; - end; - -{TNT-WARN TCustomStaticText} - TTntCustomStaticText = class(TCustomStaticText{TNT-ALLOW TCustomStaticText}) - private - procedure AdjustBounds; - function GetCaption: TWideCaption; - procedure SetCaption(const Value: TWideCaption); - function GetHint: WideString; - procedure SetHint(const Value: WideString); - function IsCaptionStored: Boolean; - function IsHintStored: Boolean; - procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR; - protected - procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED; - procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED; - procedure Loaded; override; - procedure SetAutoSize(AValue: boolean); override; - procedure CreateWindowHandle(const Params: TCreateParams); override; - procedure DefineProperties(Filer: TFiler); override; - function GetActionLinkClass: TControlActionLinkClass; override; - procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override; - property Caption: TWideCaption read GetCaption write SetCaption stored IsCaptionStored; - public - constructor Create(AOwner: TComponent); override; - published - property Hint: WideString read GetHint write SetHint stored IsHintStored; - end; - -{TNT-WARN TStaticText} - TTntStaticText = class(TTntCustomStaticText) - published - property Align; - property Alignment; - property Anchors; - property AutoSize; - property BevelEdges; - property BevelInner; - property BevelKind default bkNone; - property BevelOuter; - property BiDiMode; - property BorderStyle; - property Caption; - property Color {$IFDEF COMPILER_7_UP} nodefault {$ENDIF}; - property Constraints; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property FocusControl; - property Font; - property ParentBiDiMode; - property ParentColor; - property ParentFont; - property ParentShowHint; - property PopupMenu; - property ShowAccelChar; - property ShowHint; - property TabOrder; - property TabStop; - {$IFDEF COMPILER_7_UP} - property Transparent; - {$ENDIF} - property Visible; - property OnClick; - property OnContextPopup; - property OnDblClick; - property OnDragDrop; - property OnDragOver; - property OnEndDock; - property OnEndDrag; - {$IFDEF COMPILER_9_UP} - property OnMouseActivate; - {$ENDIF} - property OnMouseDown; - {$IFDEF COMPILER_10_UP} - property OnMouseEnter; - property OnMouseLeave; - {$ENDIF} - property OnMouseMove; - property OnMouseUp; - property OnStartDock; - property OnStartDrag; - end; - -procedure TntCombo_AfterInherited_CreateWnd(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; - Items: TTntStrings; var FSaveItems: TTntStrings; FSaveItemIndex: integer; PreInheritedAnsiText: AnsiString); -procedure TntCombo_BeforeInherited_DestroyWnd(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; - Items: TTntStrings; var FSaveItems: TTntStrings; ItemIndex: integer; var FSaveItemIndex: integer; - var SavedText: WideString); -function TntCombo_ComboWndProc(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; - var Message: TMessage; ComboWnd: HWnd; ComboProc: Pointer; DoEditCharMsg: TWMCharMsgHandler): Boolean; -function TntCombo_CNCommand(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; Items: TTntStrings; var Message: TWMCommand): Boolean; -function TntCombo_GetSelStart(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}): Integer; -procedure TntCombo_SetSelStart(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; const Value: Integer); -function TntCombo_GetSelLength(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}): Integer; -procedure TntCombo_SetSelLength(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; const Value: Integer); -function TntCombo_GetSelText(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}): WideString; -procedure TntCombo_SetSelText(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; const Value: WideString); -procedure TntCombo_BeforeKeyPress(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; var SaveAutoComplete: Boolean); -procedure TntCombo_AfterKeyPress(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; var SaveAutoComplete: Boolean); -procedure TntCombo_DropDown_PreserveSelection(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}); -procedure TntComboBox_AddItem(Items: TTntStrings; const Item: WideString; AObject: TObject); -procedure TntComboBox_CopySelection(Items: TTntStrings; ItemIndex: Integer; - Destination: TCustomListControl); -procedure TntCombo_AutoSearchKeyPress(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; - Items: TTntStrings; var Message: TWMChar; var FFilter: WideString; var FLastTime: Cardinal); -procedure TntCombo_AutoCompleteKeyPress(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; - Items: TTntStrings; var Message: TWMChar; - AutoComplete_UniqueMatchOnly, AutoComplete_PreserveDataEntryCase: Boolean); -procedure TntCombo_DefaultDrawItem(Canvas: TCanvas; Index: Integer; Rect: TRect; - State: TOwnerDrawState; Items: TTntStrings); - -procedure TntCustomEdit_CreateWindowHandle(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}; const Params: TCreateParams); -procedure TntCustomEdit_AfterInherited_CreateWnd(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}; var FPasswordChar: WideChar); -function TntCustomEdit_GetSelStart(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}): Integer; -procedure TntCustomEdit_SetSelStart(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}; const Value: Integer); -function TntCustomEdit_GetSelLength(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}): Integer; -procedure TntCustomEdit_SetSelLength(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}; const Value: Integer); -function TntCustomEdit_GetSelText(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}): WideString; -procedure TntCustomEdit_SetSelText(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}; const Value: WideString); -function TntCustomEdit_GetPasswordChar(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}; var FPasswordChar: WideChar): WideChar; -procedure TntCustomEdit_SetPasswordChar(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}; var FPasswordChar: WideChar; const Value: WideChar); - - -function TntMemo_LineStart(Handle: THandle; Index: Integer): Integer; -function TntMemo_LineLength(Handle: THandle; Index: Integer; StartPos: Integer = -1): Integer; - -procedure TntListBox_AfterInherited_CreateWnd(ListBox: TCustomListBox{TNT-ALLOW TCustomListBox}; - var FSaveItems: TTntStrings; FItems: TTntStrings; FSaveTopIndex, FSaveItemIndex: Integer); -procedure TntListBox_BeforeInherited_DestroyWnd(ListBox: TCustomListBox{TNT-ALLOW TCustomListBox}; - var FSaveItems: TTntStrings; const FItems: TTntStrings; var FSaveTopIndex, FSaveItemIndex: Integer); -procedure TntListBox_DrawItem_Text(ListBox: TCustomListBox{TNT-ALLOW TCustomListBox}; Items: TTntStrings; Index: Integer; Rect: TRect); -procedure TntListBox_AddItem(Items: TTntStrings; const Item: WideString; AObject: TObject); -procedure TntListBox_CopySelection(ListBox: TCustomListbox{TNT-ALLOW TCustomListbox}; - Items: TTntStrings; Destination: TCustomListControl); -function TntCustomListBox_LBGetText(ListBox: TCustomListBox{TNT-ALLOW TCustomListBox}; OnData: TLBGetWideDataEvent; var Message: TMessage): Boolean; -function TntCustomListBox_LBGetTextLen(ListBox: TCustomListBox{TNT-ALLOW TCustomListBox}; OnData: TLBGetWideDataEvent; var Message: TMessage): Boolean; - -function TntLabel_DoDrawText(Control: TCustomLabel{TNT-ALLOW TCustomLabel}; var Rect: TRect; Flags: Integer; const GetLabelText: WideString): Boolean; -procedure TntLabel_CMDialogChar(Control: TCustomLabel{TNT-ALLOW TCustomLabel}; var Message: TCMDialogChar; const Caption: WideString); - -procedure TntButton_CMDialogChar(Button: TButton{TNT-ALLOW TButton}; var Message: TCMDialogChar); - -implementation - -uses - Forms, SysUtils, Consts, RichEdit, ComStrs, - RTLConsts, {$IFDEF THEME_7_UP} Themes, {$ENDIF} - TntForms, TntGraphics, TntActnList, TntWindows, - {$IFDEF COMPILER_9_UP} WideStrUtils, {$ENDIF} TntWideStrUtils; - -{ TTntCustomEdit } - -procedure TntCustomEdit_CreateWindowHandle(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}; const Params: TCreateParams); -var - P: TCreateParams; -begin - if SysLocale.FarEast - and (not Win32PlatformIsUnicode) - and ((Params.Style and ES_READONLY) <> 0) then begin - // Work around Far East Win95 API/IME bug. - P := Params; - P.Style := P.Style and (not ES_READONLY); - CreateUnicodeHandle(Edit, P, 'EDIT'); - if Edit.HandleAllocated then - SendMessage(Edit.Handle, EM_SETREADONLY, Ord(True), 0); - end else - CreateUnicodeHandle(Edit, Params, 'EDIT'); -end; - -procedure TntCustomEdit_AfterInherited_CreateWnd(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}; var FPasswordChar: WideChar); -var - PasswordChar: WideChar; -begin - PasswordChar := TntCustomEdit_GetPasswordChar(Edit, FPasswordChar); - if Win32PlatformIsUnicode then - SendMessageW(Edit.Handle, EM_SETPASSWORDCHAR, Ord(PasswordChar), 0); -end; - -function TntCustomEdit_GetSelStart(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}): Integer; -begin - if Win32PlatformIsUnicode then - Result := Edit.SelStart - else - Result := Length(WideString(Copy(Edit.Text, 1, Edit.SelStart))); -end; - -procedure TntCustomEdit_SetSelStart(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}; const Value: Integer); -begin - if Win32PlatformIsUnicode then - Edit.SelStart := Value - else - Edit.SelStart := Length(AnsiString(Copy(TntControl_GetText(Edit), 1, Value))); -end; - -function TntCustomEdit_GetSelLength(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}): Integer; -begin - if Win32PlatformIsUnicode then - Result := Edit.SelLength - else - Result := Length(TntCustomEdit_GetSelText(Edit)); -end; - -procedure TntCustomEdit_SetSelLength(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}; const Value: Integer); -var - StartPos: Integer; -begin - if Win32PlatformIsUnicode then - Edit.SelLength := Value - else begin - StartPos := TntCustomEdit_GetSelStart(Edit); - Edit.SelLength := Length(AnsiString(Copy(TntControl_GetText(Edit), StartPos + 1, Value))); - end; -end; - -function TntCustomEdit_GetSelText(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}): WideString; -begin - if Win32PlatformIsUnicode then - Result := Copy(TntControl_GetText(Edit), Edit.SelStart + 1, Edit.SelLength) - else - Result := Edit.SelText -end; - -procedure TntCustomEdit_SetSelText(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}; const Value: WideString); -begin - if Win32PlatformIsUnicode then - SendMessageW(Edit.Handle, EM_REPLACESEL, 0, Longint(PWideChar(Value))) - else - Edit.SelText := Value; -end; - -function WideCharToAnsiChar(const C: WideChar): AnsiChar; -begin - if C <= High(AnsiChar) then - Result := AnsiChar(C) - else - Result := '*'; -end; - -type TAccessCustomEdit = class(TCustomEdit{TNT-ALLOW TCustomEdit}); - -function TntCustomEdit_GetPasswordChar(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}; var FPasswordChar: WideChar): WideChar; -begin - if TAccessCustomEdit(Edit).PasswordChar <> WideCharToAnsiChar(FPasswordChar) then - FPasswordChar := WideChar(TAccessCustomEdit(Edit).PasswordChar); - Result := FPasswordChar; -end; - -procedure TntCustomEdit_SetPasswordChar(Edit: TCustomEdit{TNT-ALLOW TCustomEdit}; var FPasswordChar: WideChar; const Value: WideChar); -var - SaveWindowHandle: Integer; - PasswordCharSetHere: Boolean; -begin - if TntCustomEdit_GetPasswordChar(Edit, FPasswordChar) <> Value then - begin - FPasswordChar := Value; - PasswordCharSetHere := Win32PlatformIsUnicode and Edit.HandleAllocated; - SaveWindowHandle := TAccessCustomEdit(Edit).WindowHandle; - try - if PasswordCharSetHere then - TAccessCustomEdit(Edit).WindowHandle := 0; // this prevents TCustomEdit from actually changing it - TAccessCustomEdit(Edit).PasswordChar := WideCharToAnsiChar(FPasswordChar); - finally - TAccessCustomEdit(Edit).WindowHandle := SaveWindowHandle; - end; - if PasswordCharSetHere then - begin - Assert(Win32PlatformIsUnicode); - Assert(Edit.HandleAllocated); - SendMessageW(Edit.Handle, EM_SETPASSWORDCHAR, Ord(FPasswordChar), 0); - Edit.Invalidate; - end; - end; -end; - -procedure TTntCustomEdit.CreateWindowHandle(const Params: TCreateParams); -begin - TntCustomEdit_CreateWindowHandle(Self, Params); -end; - -procedure TTntCustomEdit.CreateWnd; -begin - inherited; - TntCustomEdit_AfterInherited_CreateWnd(Self, FPasswordChar); -end; - -procedure TTntCustomEdit.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntCustomEdit.GetSelStart: Integer; -begin - Result := TntCustomEdit_GetSelStart(Self); -end; - -procedure TTntCustomEdit.SetSelStart(const Value: Integer); -begin - TntCustomEdit_SetSelStart(Self, Value); -end; - -function TTntCustomEdit.GetSelLength: Integer; -begin - Result := TntCustomEdit_GetSelLength(Self); -end; - -procedure TTntCustomEdit.SetSelLength(const Value: Integer); -begin - TntCustomEdit_SetSelLength(Self, Value); -end; - -function TTntCustomEdit.GetSelText: WideString; -begin - Result := TntCustomEdit_GetSelText(Self); -end; - -procedure TTntCustomEdit.SetSelText(const Value: WideString); -begin - TntCustomEdit_SetSelText(Self, Value); -end; - -function TTntCustomEdit.GetPasswordChar: WideChar; -begin - Result := TntCustomEdit_GetPasswordChar(Self, FPasswordChar); -end; - -procedure TTntCustomEdit.SetPasswordChar(const Value: WideChar); -begin - TntCustomEdit_SetPasswordChar(Self, FPasswordChar, Value); -end; - -function TTntCustomEdit.GetText: WideString; -begin - Result := TntControl_GetText(Self); -end; - -procedure TTntCustomEdit.SetText(const Value: WideString); -begin - TntControl_SetText(Self, Value); -end; - -function TTntCustomEdit.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntCustomEdit.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntCustomEdit.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntCustomEdit.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomEdit.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntMemoStrings } - -constructor TTntMemoStrings.Create; -begin - inherited; - FLineBreakStyle := tlbsCRLF; -end; - -function TTntMemoStrings.GetCount: Integer; -begin - Result := FMemoLines.Count; -end; - -function TntMemo_LineStart(Handle: THandle; Index: Integer): Integer; -begin - Assert(Win32PlatformIsUnicode); - Result := SendMessageW(Handle, EM_LINEINDEX, Index, 0); -end; - -function TntMemo_LineLength(Handle: THandle; Index: Integer; StartPos: Integer = -1): Integer; -begin - Assert(Win32PlatformIsUnicode); - if StartPos = -1 then - StartPos := TntMemo_LineStart(Handle, Index); - if StartPos < 0 then - Result := 0 - else - Result := SendMessageW(Handle, EM_LINELENGTH, StartPos, 0); -end; - -function TTntMemoStrings.Get(Index: Integer): WideString; -var - Len: Integer; -begin - if (not IsWindowUnicode(FMemo.Handle)) then - Result := FMemoLines[Index] - else begin - SetLength(Result, TntMemo_LineLength(FMemo.Handle, Index)); - if Length(Result) > 0 then begin - if Length(Result) > High(Word) then - raise EOutOfResources.Create(SOutlineLongLine); - Word((PWideChar(Result))^) := Length(Result); - Len := SendMessageW(FMemo.Handle, EM_GETLINE, Index, Longint(PWideChar(Result))); - SetLength(Result, Len); - end; - end; -end; - -procedure TTntMemoStrings.Put(Index: Integer; const S: WideString); -var - StartPos: Integer; -begin - if (not IsWindowUnicode(FMemo.Handle)) then - FMemoLines[Index] := S - else begin - StartPos := TntMemo_LineStart(FMemo.Handle, Index); - if StartPos >= 0 then - begin - SendMessageW(FMemo.Handle, EM_SETSEL, StartPos, StartPos + TntMemo_LineLength(FMemo.Handle, Index)); - SendMessageW(FMemo.Handle, EM_REPLACESEL, 0, Longint(PWideChar(S))); - end; - end; -end; - -procedure TTntMemoStrings.Insert(Index: Integer; const S: Widestring); - - function RichEditSelStartW: Integer; - var - CharRange: TCharRange; - begin - SendMessageW(FMemo.Handle, EM_EXGETSEL, 0, Longint(@CharRange)); - Result := CharRange.cpMin; - end; - -var - StartPos, LineLen: Integer; - Line: WideString; -begin - if (not IsWindowUnicode(FMemo.Handle)) then - FMemoLines.Insert(Index, S) - else begin - if Index >= 0 then - begin - StartPos := TntMemo_LineStart(FMemo.Handle, Index); - if StartPos >= 0 then - Line := S + CRLF - else begin - StartPos := TntMemo_LineStart(FMemo.Handle, Index - 1); - LineLen := TntMemo_LineLength(FMemo.Handle, Index - 1); - if LineLen = 0 then - Exit; - Inc(StartPos, LineLen); - Line := CRLF + s; - end; - SendMessageW(FMemo.Handle, EM_SETSEL, StartPos, StartPos); - - if (FRichEditMode) - and (FLineBreakStyle <> tlbsCRLF) then begin - Line := TntAdjustLineBreaks(Line, FLineBreakStyle); - if Line = CR then - Line := CRLF; { This helps a ReadOnly RichEdit 4.1 control to insert a blank line. } - SendMessageW(FMemo.Handle, EM_REPLACESEL, 0, Longint(PWideChar(Line))); - if Line = CRLF then - Line := CR; - end else - SendMessageW(FMemo.Handle, EM_REPLACESEL, 0, Longint(PWideChar(Line))); - - if (FRichEditMode) - and (RichEditSelStartW <> (StartPos + Length(Line))) then - raise EOutOfResources.Create(sRichEditInsertError); - end; - end; -end; - -procedure TTntMemoStrings.Delete(Index: Integer); -begin - FMemoLines.Delete(Index); -end; - -procedure TTntMemoStrings.Clear; -begin - FMemoLines.Clear; -end; - -type TAccessStrings = class(TStrings{TNT-ALLOW TStrings}); - -procedure TTntMemoStrings.SetUpdateState(Updating: Boolean); -begin - TAccessStrings(FMemoLines).SetUpdateState(Updating); -end; - -function TTntMemoStrings.GetTextStr: WideString; -begin - if (not FRichEditMode) then - Result := TntControl_GetText(FMemo) - else - Result := inherited GetTextStr; -end; - -procedure TTntMemoStrings.SetTextStr(const Value: WideString); -var - NewText: WideString; -begin - NewText := TntAdjustLineBreaks(Value, FLineBreakStyle); - if NewText <> GetTextStr then begin - FMemo.HandleNeeded; - TntControl_SetText(FMemo, NewText); - end; -end; - -{ TTntCustomMemo } - -constructor TTntCustomMemo.Create(AOwner: TComponent); -begin - inherited; - FLines := TTntMemoStrings.Create; - TTntMemoStrings(FLines).FMemo := Self; - TTntMemoStrings(FLines).FMemoLines := TCustomMemo{TNT-ALLOW TCustomMemo}(Self).Lines; -end; - -destructor TTntCustomMemo.Destroy; -begin - FreeAndNil(FLines); - inherited; -end; - -procedure TTntCustomMemo.SetLines(const Value: TTntStrings); -begin - FLines.Assign(Value); -end; - -procedure TTntCustomMemo.CreateWindowHandle(const Params: TCreateParams); -begin - TntCustomEdit_CreateWindowHandle(Self, Params); -end; - -procedure TTntCustomMemo.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntCustomMemo.GetSelStart: Integer; -begin - Result := TntCustomEdit_GetSelStart(Self); -end; - -procedure TTntCustomMemo.SetSelStart(const Value: Integer); -begin - TntCustomEdit_SetSelStart(Self, Value); -end; - -function TTntCustomMemo.GetSelLength: Integer; -begin - Result := TntCustomEdit_GetSelLength(Self); -end; - -procedure TTntCustomMemo.SetSelLength(const Value: Integer); -begin - TntCustomEdit_SetSelLength(Self, Value); -end; - -function TTntCustomMemo.GetSelText: WideString; -begin - Result := TntCustomEdit_GetSelText(Self); -end; - -procedure TTntCustomMemo.SetSelText(const Value: WideString); -begin - TntCustomEdit_SetSelText(Self, Value); -end; - -function TTntCustomMemo.GetText: WideString; -begin - Result := TntControl_GetText(Self); -end; - -procedure TTntCustomMemo.SetText(const Value: WideString); -begin - TntControl_SetText(Self, Value); -end; - -function TTntCustomMemo.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self); -end; - -function TTntCustomMemo.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntCustomMemo.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntCustomMemo.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomMemo.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{$IFDEF DELPHI_7} // fix for Delphi 7 only -function TD7PatchedComboBoxStrings.Get(Index: Integer): string{TNT-ALLOW string}; -var - Len: Integer; -begin - Len := SendMessage(ComboBox.Handle, CB_GETLBTEXTLEN, Index, 0); - if Len > 0 then - begin - SetLength(Result, Len); - SendMessage(ComboBox.Handle, CB_GETLBTEXT, Index, Longint(PChar{TNT-ALLOW PChar}(Result))); - end - else - SetLength(Result, 0); -end; - -function TD7PatchedComboBoxStrings.Add(const S: string{TNT-ALLOW string}): Integer; -begin - Result := SendMessage(ComboBox.Handle, CB_ADDSTRING, 0, Longint(PChar{TNT-ALLOW PChar}(S))); - if Result < 0 then - raise EOutOfResources.Create(SInsertLineError); -end; - -procedure TD7PatchedComboBoxStrings.Insert(Index: Integer; const S: string{TNT-ALLOW string}); -begin - if SendMessage(ComboBox.Handle, CB_INSERTSTRING, Index, - Longint(PChar{TNT-ALLOW PChar}(S))) < 0 then - raise EOutOfResources.Create(SInsertLineError); -end; -{$ENDIF} - -{ TTntComboBoxStrings } - -function TTntComboBoxStrings.GetCount: Integer; -begin - Result := ComboBox.Items.Count; -end; - -function TTntComboBoxStrings.Get(Index: Integer): WideString; -var - Len: Integer; -begin - if (not IsWindowUnicode(ComboBox.Handle)) then - Result := ComboBox.Items[Index] - else begin - Len := SendMessageW(ComboBox.Handle, CB_GETLBTEXTLEN, Index, 0); - if Len = CB_ERR then - Result := '' - else begin - SetLength(Result, Len + 1); - Len := SendMessageW(ComboBox.Handle, CB_GETLBTEXT, Index, Longint(PWideChar(Result))); - if Len = CB_ERR then - Result := '' - else - Result := PWideChar(Result); - end; - end; -end; - -function TTntComboBoxStrings.GetObject(Index: Integer): TObject; -begin - Result := ComboBox.Items.Objects[Index]; -end; - -procedure TTntComboBoxStrings.PutObject(Index: Integer; AObject: TObject); -begin - ComboBox.Items.Objects[Index] := AObject; -end; - -function TTntComboBoxStrings.Add(const S: WideString): Integer; -begin - if (not IsWindowUnicode(ComboBox.Handle)) then - Result := ComboBox.Items.Add(S) - else begin - Result := SendMessageW(ComboBox.Handle, CB_ADDSTRING, 0, Longint(PWideChar(S))); - if Result < 0 then - raise EOutOfResources.Create(SInsertLineError); - end; -end; - -procedure TTntComboBoxStrings.Insert(Index: Integer; const S: WideString); -begin - if (not IsWindowUnicode(ComboBox.Handle)) then - ComboBox.Items.Insert(Index, S) - else begin - if SendMessageW(ComboBox.Handle, CB_INSERTSTRING, Index, Longint(PWideChar(S))) < 0 then - raise EOutOfResources.Create(SInsertLineError); - end; -end; - -procedure TTntComboBoxStrings.Delete(Index: Integer); -begin - ComboBox.Items.Delete(Index); -end; - -procedure TTntComboBoxStrings.Clear; -var - S: WideString; -begin - S := TntControl_GetText(ComboBox); - SendMessage(ComboBox.Handle, CB_RESETCONTENT, 0, 0); - TntControl_SetText(ComboBox, S); - ComboBox.Update; -end; - -procedure TTntComboBoxStrings.SetUpdateState(Updating: Boolean); -begin - TAccessStrings(ComboBox.Items).SetUpdateState(Updating); -end; - -function TTntComboBoxStrings.IndexOf(const S: WideString): Integer; -begin - if (not IsWindowUnicode(ComboBox.Handle)) then - Result := ComboBox.Items.IndexOf(S) - else - Result := SendMessageW(ComboBox.Handle, CB_FINDSTRINGEXACT, -1, LongInt(PWideChar(S))); -end; - -{ TTntCustomComboBox } - -type TAccessCustomComboBox = class(TCustomComboBox{TNT-ALLOW TCustomComboBox}); - -procedure TntCombo_AfterInherited_CreateWnd(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; - Items: TTntStrings; var FSaveItems: TTntStrings; FSaveItemIndex: integer; PreInheritedAnsiText: AnsiString); -begin - if (not Win32PlatformIsUnicode) then begin - TAccessCustomComboBox(Combo).Text := PreInheritedAnsiText; - end else begin - with TAccessCustomComboBox(Combo) do - begin - if ListHandle <> 0 then begin - // re-extract FDefListProc as a Unicode proc - SetWindowLongA(ListHandle, GWL_WNDPROC, Integer(FDefListProc)); - FDefListProc := Pointer(GetWindowLongW(ListHandle, GWL_WNDPROC)); - // override with FListInstance as a Unicode proc - SetWindowLongW(ListHandle, GWL_WNDPROC, Integer(FListInstance)); - end; - SetWindowLongW(EditHandle, GWL_WNDPROC, GetWindowLong(EditHandle, GWL_WNDPROC)); - end; - if FSaveItems <> nil then - begin - Items.Assign(FSaveItems); - FreeAndNil(FSaveItems); - if FSaveItemIndex <> -1 then - begin - if Items.Count < FSaveItemIndex then FSaveItemIndex := Items.Count; - SendMessage(Combo.Handle, CB_SETCURSEL, FSaveItemIndex, 0); - end; - end; - TntControl_SetText(Combo, TntControl_GetStoredText(Combo, TAccessCustomComboBox(Combo).Text)); - end; -end; - -procedure TntCombo_BeforeInherited_DestroyWnd(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; - Items: TTntStrings; var FSaveItems: TTntStrings; ItemIndex: integer; var FSaveItemIndex: integer; - var SavedText: WideString); -begin - Assert(not (csDestroyingHandle in Combo.ControlState)); - if (Win32PlatformIsUnicode) then begin - SavedText := TntControl_GetText(Combo); - if (Items.Count > 0) then - begin - FSaveItems := TTntStringList.Create; - FSaveItems.Assign(Items); - FSaveItemIndex:= ItemIndex; - Items.Clear; { This keeps TCustomComboBox from creating its own FSaveItems. (this kills the original ItemIndex) } - end; - end; -end; - -function TntCombo_ComboWndProc(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; - var Message: TMessage; ComboWnd: HWnd; ComboProc: Pointer; DoEditCharMsg: TWMCharMsgHandler): Boolean; - - procedure CallDefaultWindowProc; - begin - with Message do begin { call default wnd proc } - if IsWindowUnicode(ComboWnd) then - Result := CallWindowProcW(ComboProc, ComboWnd, Msg, WParam, LParam) - else - Result := CallWindowProcA(ComboProc, ComboWnd, Msg, WParam, LParam); - end; - end; - - function DoWideKeyPress(Message: TWMChar): Boolean; - begin - DoEditCharMsg(Message); - Result := (Message.CharCode = 0); - end; - -begin - Result := False; - try - if (Message.Msg = WM_CHAR) then begin - // WM_CHAR - Result := True; - if IsWindowUnicode(ComboWnd) then - MakeWMCharMsgSafeForAnsi(Message); - try - if TAccessCustomComboBox(Combo).DoKeyPress(TWMKey(Message)) then Exit; - if DoWideKeyPress(TWMKey(Message)) then Exit; - finally - if IsWindowUnicode(ComboWnd) then - RestoreWMCharMsg(Message); - end; - with TWMKey(Message) do begin - if ((CharCode = VK_RETURN) or (CharCode = VK_ESCAPE)) and Combo.DroppedDown then begin - Combo.DroppedDown := False; - Exit; - end; - end; - CallDefaultWindowProc; - end else if (IsWindowUnicode(ComboWnd)) then begin - // UNICODE - if IsTextMessage(Message.Msg) - or (Message.Msg = EM_REPLACESEL) - or (Message.Msg = WM_IME_COMPOSITION) - then begin - // message w/ text parameter - Result := True; - CallDefaultWindowProc; - end else if (Message.Msg = WM_IME_CHAR) then begin - // WM_IME_CHAR - Result := True; - with Message do { convert to WM_CHAR } - Result := SendMessageW(ComboWnd, WM_CHAR, WParam, LParam); - end; - end; - except - Application.HandleException(Combo); - end; -end; - -function TntCombo_CNCommand(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; Items: TTntStrings; var Message: TWMCommand): Boolean; -begin - Result := False; - if Message.NotifyCode = CBN_SELCHANGE then begin - Result := True; - TntControl_SetText(Combo, Items[Combo.ItemIndex]); - TAccessCustomComboBox(Combo).Click; - TAccessCustomComboBox(Combo).Select; - end; -end; - -function TntCombo_GetSelStart(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}): Integer; -begin - if Win32PlatformIsUnicode then - Result := Combo.SelStart - else - Result := Length(WideString(Copy(TAccessCustomComboBox(Combo).Text, 1, Combo.SelStart))); -end; - -procedure TntCombo_SetSelStart(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; const Value: Integer); -begin - if Win32PlatformIsUnicode then - Combo.SelStart := Value - else - Combo.SelStart := Length(AnsiString(Copy(TntControl_GetText(Combo), 1, Value))); -end; - -function TntCombo_GetSelLength(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}): Integer; -begin - if Win32PlatformIsUnicode then - Result := Combo.SelLength - else - Result := Length(TntCombo_GetSelText(Combo)); -end; - -procedure TntCombo_SetSelLength(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; const Value: Integer); -var - StartPos: Integer; -begin - if Win32PlatformIsUnicode then - Combo.SelLength := Value - else begin - StartPos := TntCombo_GetSelStart(Combo); - Combo.SelLength := Length(AnsiString(Copy(TntControl_GetText(Combo), StartPos + 1, Value))); - end; -end; - -function TntCombo_GetSelText(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}): WideString; -begin - if Win32PlatformIsUnicode then begin - Result := ''; - if TAccessCustomComboBox(Combo).Style < csDropDownList then - Result := Copy(TntControl_GetText(Combo), Combo.SelStart + 1, Combo.SelLength); - end else - Result := Combo.SelText -end; - -procedure TntCombo_SetSelText(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; const Value: WideString); -begin - if Win32PlatformIsUnicode then begin - if TAccessCustomComboBox(Combo).Style < csDropDownList then - begin - Combo.HandleNeeded; - SendMessageW(TAccessCustomComboBox(Combo).EditHandle, EM_REPLACESEL, 0, Longint(PWideChar(Value))); - end; - end else - Combo.SelText := Value -end; - -procedure TntCombo_BeforeKeyPress(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; var SaveAutoComplete: Boolean); -begin - SaveAutoComplete := TAccessCustomComboBox(Combo).AutoComplete; - TAccessCustomComboBox(Combo).AutoComplete := False; -end; - -procedure TntCombo_AfterKeyPress(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; var SaveAutoComplete: Boolean); -begin - TAccessCustomComboBox(Combo).AutoComplete := SaveAutoComplete; -end; - -procedure TntCombo_DropDown_PreserveSelection(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}); -var - OldSelStart, OldSelLength: Integer; - OldText: WideString; -begin - OldText := TntControl_GetText(Combo); - OldSelStart := TntCombo_GetSelStart(Combo); - OldSelLength := TntCombo_GetSelLength(Combo); - Combo.DroppedDown := True; - TntControl_SetText(Combo, OldText); - TntCombo_SetSelStart(Combo, OldSelStart); - TntCombo_SetSelLength(Combo ,OldSelLength); -end; - -procedure TntComboBox_AddItem(Items: TTntStrings; const Item: WideString; AObject: TObject); -begin - Items.AddObject(Item, AObject); -end; - -procedure TntComboBox_CopySelection(Items: TTntStrings; ItemIndex: Integer; - Destination: TCustomListControl); -begin - if ItemIndex <> -1 then - WideListControl_AddItem(Destination, Items[ItemIndex], Items.Objects[ItemIndex]); -end; - -function TntCombo_FindString(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; - StartPos: Integer; const Text: WideString): Integer; -var - ComboFindString: ITntComboFindString; -begin - if Combo.GetInterface(ITntComboFindString, ComboFindString) then - Result := ComboFindString.FindString(Text, StartPos) - else if IsWindowUnicode(Combo.Handle) then - Result := SendMessageW(Combo.Handle, CB_FINDSTRING, StartPos, Integer(PWideChar(Text))) - else - Result := SendMessageA(Combo.Handle, CB_FINDSTRING, StartPos, Integer(PAnsiChar(AnsiString(Text)))) -end; - -function TntCombo_FindUniqueString(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; - StartPos: Integer; const Text: WideString): Integer; -var - Match_1, Match_2: Integer; -begin - Result := CB_ERR; - Match_1 := TntCombo_FindString(Combo, -1, Text); - if Match_1 <> CB_ERR then begin - Match_2 := TntCombo_FindString(Combo, Match_1, Text); - if Match_2 = Match_1 then - Result := Match_1; - end; -end; - -function TntCombo_AutoSelect(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; Items: TTntStrings; - const SearchText: WideString; UniqueMatchOnly: Boolean; UseDataEntryCase: Boolean): Boolean; -var - Idx: Integer; - ValueChange: Boolean; -begin - if UniqueMatchOnly then - Idx := TntCombo_FindUniqueString(Combo, -1, SearchText) - else - Idx := TntCombo_FindString(Combo, -1, SearchText); - Result := (Idx <> CB_ERR); - if Result then begin - if TAccessCustomComboBox(Combo).Style = csDropDown then - ValueChange := not WideSameStr(TntControl_GetText(Combo), Items[Idx]) - else - ValueChange := Idx <> Combo.ItemIndex; - {$IFDEF COMPILER_7_UP} - // auto-closeup - if Combo.AutoCloseUp and (Items.IndexOf(SearchText) <> -1) then - Combo.DroppedDown := False; - {$ENDIF} - // select item - Combo.ItemIndex := Idx; - // update edit - if (TAccessCustomComboBox(Combo).Style in [csDropDown, csSimple]) then begin - if UseDataEntryCase then begin - // preserve case of characters as they are entered - TntControl_SetText(Combo, SearchText + Copy(Items[Combo.ItemIndex], Length(SearchText) + 1, MaxInt)); - end else begin - TntControl_SetText(Combo, Items[Idx]); - end; - // select the rest of the string - TntCombo_SetSelStart(Combo, Length(SearchText)); - TntCombo_SetSelLength(Combo, Length(TntControl_GetText(Combo)) - TntCombo_GetSelStart(Combo)); - end; - // notify events - if ValueChange then begin - TAccessCustomComboBox(Combo).Click; - TAccessCustomComboBox(Combo).Select; - end; - end; -end; - -procedure TntCombo_AutoSearchKeyPress(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; - Items: TTntStrings; var Message: TWMChar; var FFilter: WideString; var FLastTime: Cardinal); -var - Key: WideChar; -begin - if TAccessCustomComboBox(Combo).Style in [csSimple, csDropDown] then - exit; - if not Combo.AutoComplete then - exit; - Key := GetWideCharFromWMCharMsg(Message); - try - case Ord(Key) of - VK_ESCAPE: - exit; - VK_TAB: - if Combo.AutoDropDown and Combo.DroppedDown then - Combo.DroppedDown := False; - VK_BACK: - Delete(FFilter, Length(FFilter), 1); - else begin - if Combo.AutoDropDown and (not Combo.DroppedDown) then - Combo.DroppedDown := True; - // reset FFilter if it's been too long (1.25 sec) { Windows XP is actually 2 seconds! } - if GetTickCount - FLastTime >= 1250 then - FFilter := ''; - FLastTime := GetTickCount; - // if AutoSelect works, remember new FFilter - if TntCombo_AutoSelect(Combo, Items, FFilter + Key, False, True) then begin - FFilter := FFilter + Key; - Key := #0; - end; - end; - end; - finally - SetWideCharForWMCharMsg(Message, Key); - end; -end; - -procedure TntCombo_AutoCompleteKeyPress(Combo: TCustomComboBox{TNT-ALLOW TCustomComboBox}; - Items: TTntStrings; var Message: TWMChar; - AutoComplete_UniqueMatchOnly, AutoComplete_PreserveDataEntryCase: Boolean); -var - Key: WideChar; - FindText: WideString; -begin - Assert(TAccessCustomComboBox(Combo).Style in [csSimple, csDropDown], 'Internal Error: TntCombo_AutoCompleteKeyPress is only for csSimple and csDropDown style combo boxes.'); - if not Combo.AutoComplete then exit; - Key := GetWideCharFromWMCharMsg(Message); - try - case Ord(Key) of - VK_ESCAPE: - exit; - VK_TAB: - if Combo.AutoDropDown and Combo.DroppedDown then - Combo.DroppedDown := False; - VK_BACK: - exit; - else begin - if Combo.AutoDropDown and (not Combo.DroppedDown) then - TntCombo_DropDown_PreserveSelection(Combo); - // AutoComplete only if the selection is at the very end - if ((TntCombo_GetSelStart(Combo) + TntCombo_GetSelLength(Combo)) - = Length(TntControl_GetText(Combo))) then - begin - FindText := Copy(TntControl_GetText(Combo), 1, TntCombo_GetSelStart(Combo)) + Key; - if TntCombo_AutoSelect(Combo, Items, FindText, AutoComplete_UniqueMatchOnly, AutoComplete_PreserveDataEntryCase) then - begin - Key := #0; - end; - end; - end; - end; - finally - SetWideCharForWMCharMsg(Message, Key); - end; -end; - -//-- -constructor TTntCustomComboBox.Create(AOwner: TComponent); -begin - inherited; - FItems := TTntComboBoxStrings.Create; - TTntComboBoxStrings(FItems).ComboBox := Self; -end; - -destructor TTntCustomComboBox.Destroy; -begin - FreeAndNil(FItems); - FreeAndNil(FSaveItems); - inherited; -end; - -procedure TTntCustomComboBox.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, 'COMBOBOX'); -end; - -procedure TTntCustomComboBox.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -procedure TTntCustomComboBox.CreateWnd; -var - PreInheritedAnsiText: AnsiString; -begin - PreInheritedAnsiText := TAccessCustomComboBox(Self).Text; - inherited; - TntCombo_AfterInherited_CreateWnd(Self, Items, FSaveItems, FSaveItemIndex, PreInheritedAnsiText); -end; - -procedure TTntCustomComboBox.DestroyWnd; -var - SavedText: WideString; -begin - if not (csDestroyingHandle in ControlState) then begin { avoid recursion when parent is TToolBar and system font changes. } - TntCombo_BeforeInherited_DestroyWnd(Self, Items, FSaveItems, ItemIndex, FSaveItemIndex, SavedText); - inherited; - TntControl_SetStoredText(Self, SavedText); - end; -end; - -procedure TTntCustomComboBox.ComboWndProc(var Message: TMessage; ComboWnd: HWnd; ComboProc: Pointer); -begin - if not TntCombo_ComboWndProc(Self, Message, ComboWnd, ComboProc, DoEditCharMsg) then - inherited; -end; - -procedure TTntCustomComboBox.KeyPress(var Key: AnsiChar); -var - SaveAutoComplete: Boolean; -begin - TntCombo_BeforeKeyPress(Self, SaveAutoComplete); - try - inherited; - finally - TntCombo_AfterKeyPress(Self, SaveAutoComplete); - end; -end; - -procedure TTntCustomComboBox.DoEditCharMsg(var Message: TWMChar); -begin - TntCombo_AutoCompleteKeyPress(Self, Items, Message, - GetAutoComplete_UniqueMatchOnly, GetAutoComplete_PreserveDataEntryCase); -end; - -procedure TTntCustomComboBox.WMChar(var Message: TWMChar); -begin - TntCombo_AutoSearchKeyPress(Self, Items, Message, FFilter, FLastTime); - if Message.CharCode <> 0 then - inherited; -end; - -procedure TntCombo_DefaultDrawItem(Canvas: TCanvas; Index: Integer; Rect: TRect; - State: TOwnerDrawState; Items: TTntStrings); -begin - Canvas.FillRect(Rect); - if Index >= 0 then - WideCanvasTextOut(Canvas, Rect.Left + 2, Rect.Top, Items[Index]); -end; - -procedure TTntCustomComboBox.DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState); -begin - TControlCanvas(Canvas).UpdateTextFlags; - if Assigned(OnDrawItem) then - OnDrawItem(Self, Index, Rect, State) - else - TntCombo_DefaultDrawItem(Canvas, Index, Rect, State, Items); -end; - -function TTntCustomComboBox.GetItems: TTntStrings; -begin - Result := FItems; -end; - -procedure TTntCustomComboBox.SetItems(const Value: TTntStrings); -begin - FItems.Assign(Value); -end; - -function TTntCustomComboBox.GetSelStart: Integer; -begin - Result := TntCombo_GetSelStart(Self); -end; - -procedure TTntCustomComboBox.SetSelStart(const Value: Integer); -begin - TntCombo_SetSelStart(Self, Value); -end; - -function TTntCustomComboBox.GetSelLength: Integer; -begin - Result := TntCombo_GetSelLength(Self); -end; - -procedure TTntCustomComboBox.SetSelLength(const Value: Integer); -begin - TntCombo_SetSelLength(Self, Value); -end; - -function TTntCustomComboBox.GetSelText: WideString; -begin - Result := TntCombo_GetSelText(Self); -end; - -procedure TTntCustomComboBox.SetSelText(const Value: WideString); -begin - TntCombo_SetSelText(Self, Value); -end; - -function TTntCustomComboBox.GetText: WideString; -begin - Result := TntControl_GetText(Self); -end; - -procedure TTntCustomComboBox.SetText(const Value: WideString); -begin - TntControl_SetText(Self, Value); -end; - -procedure TTntCustomComboBox.CNCommand(var Message: TWMCommand); -begin - if not TntCombo_CNCommand(Self, Items, Message) then - inherited; -end; - -function TTntCustomComboBox.GetAutoComplete_PreserveDataEntryCase: Boolean; -begin - Result := True; -end; - -function TTntCustomComboBox.GetAutoComplete_UniqueMatchOnly: Boolean; -begin - Result := False; -end; - -function TTntCustomComboBox.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -function TTntCustomComboBox.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntCustomComboBox.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntCustomComboBox.AddItem(const Item: WideString; AObject: TObject); -begin - TntComboBox_AddItem(Items, Item, AObject); -end; - -procedure TTntCustomComboBox.CopySelection(Destination: TCustomListControl); -begin - TntComboBox_CopySelection(Items, ItemIndex, Destination); -end; - -procedure TTntCustomComboBox.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomComboBox.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{$IFDEF DELPHI_7} // fix for Delphi 7 only -function TTntCustomComboBox.GetItemsClass: TCustomComboBoxStringsClass; -begin - Result := TD7PatchedComboBoxStrings; -end; -{$ENDIF} - -{ TTntListBoxStrings } - -function TTntListBoxStrings.GetListBox: TCustomListBox{TNT-ALLOW TCustomListBox}; -begin - Result := TCustomListBox{TNT-ALLOW TCustomListBox}(FListBox); -end; - -procedure TTntListBoxStrings.SetListBox(const Value: TCustomListBox{TNT-ALLOW TCustomListBox}); -begin - FListBox := TAccessCustomListBox(Value); -end; - -function TTntListBoxStrings.GetCount: Integer; -begin - Result := ListBox.Items.Count; -end; - -function TTntListBoxStrings.Get(Index: Integer): WideString; -var - Len: Integer; -begin - if (not IsWindowUnicode(ListBox.Handle)) then - Result := ListBox.Items[Index] - else begin - Len := SendMessageW(ListBox.Handle, LB_GETTEXTLEN, Index, 0); - if Len = LB_ERR then - Error(SListIndexError, Index) - else begin - SetLength(Result, Len + 1); - Len := SendMessageW(ListBox.Handle, LB_GETTEXT, Index, Longint(PWideChar(Result))); - if Len = LB_ERR then - Result := '' - else - Result := PWideChar(Result); - end; - end; -end; - -function TTntListBoxStrings.GetObject(Index: Integer): TObject; -begin - Result := ListBox.Items.Objects[Index]; -end; - -procedure TTntListBoxStrings.Put(Index: Integer; const S: WideString); -var - I: Integer; - TempData: Longint; -begin - I := ListBox.ItemIndex; - TempData := FListBox.InternalGetItemData(Index); - // Set the Item to 0 in case it is an object that gets freed during Delete - FListBox.InternalSetItemData(Index, 0); - Delete(Index); - InsertObject(Index, S, nil); - FListBox.InternalSetItemData(Index, TempData); - ListBox.ItemIndex := I; -end; - -procedure TTntListBoxStrings.PutObject(Index: Integer; AObject: TObject); -begin - ListBox.Items.Objects[Index] := AObject; -end; - -function TTntListBoxStrings.Add(const S: WideString): Integer; -begin - if (not IsWindowUnicode(ListBox.Handle)) then - Result := ListBox.Items.Add(S) - else begin - Result := SendMessageW(ListBox.Handle, LB_ADDSTRING, 0, Longint(PWideChar(S))); - if Result < 0 then - raise EOutOfResources.Create(SInsertLineError); - end; -end; - -procedure TTntListBoxStrings.Insert(Index: Integer; const S: WideString); -begin - if (not IsWindowUnicode(ListBox.Handle)) then - ListBox.Items.Insert(Index, S) - else begin - if SendMessageW(ListBox.Handle, LB_INSERTSTRING, Index, Longint(PWideChar(S))) < 0 then - raise EOutOfResources.Create(SInsertLineError); - end; -end; - -procedure TTntListBoxStrings.Delete(Index: Integer); -begin - FListBox.DeleteString(Index); -end; - -procedure TTntListBoxStrings.Exchange(Index1, Index2: Integer); -var - TempData: Longint; - TempString: WideString; -begin - BeginUpdate; - try - TempString := Strings[Index1]; - TempData := FListBox.InternalGetItemData(Index1); - Strings[Index1] := Strings[Index2]; - FListBox.InternalSetItemData(Index1, FListBox.InternalGetItemData(Index2)); - Strings[Index2] := TempString; - FListBox.InternalSetItemData(Index2, TempData); - if ListBox.ItemIndex = Index1 then - ListBox.ItemIndex := Index2 - else if ListBox.ItemIndex = Index2 then - ListBox.ItemIndex := Index1; - finally - EndUpdate; - end; -end; - -procedure TTntListBoxStrings.Clear; -begin - FListBox.ResetContent; -end; - -procedure TTntListBoxStrings.SetUpdateState(Updating: Boolean); -begin - TAccessStrings(ListBox.Items).SetUpdateState(Updating); -end; - -function TTntListBoxStrings.IndexOf(const S: WideString): Integer; -begin - if (not IsWindowUnicode(ListBox.Handle)) then - Result := ListBox.Items.IndexOf(S) - else - Result := SendMessageW(ListBox.Handle, LB_FINDSTRINGEXACT, -1, LongInt(PWideChar(S))); -end; - -procedure TTntListBoxStrings.Move(CurIndex, NewIndex: Integer); -var - TempData: Longint; - TempString: WideString; -begin - BeginUpdate; - FListBox.FMoving := True; - try - if CurIndex <> NewIndex then - begin - TempString := Get(CurIndex); - TempData := FListBox.InternalGetItemData(CurIndex); - FListBox.InternalSetItemData(CurIndex, 0); - Delete(CurIndex); - Insert(NewIndex, TempString); - FListBox.InternalSetItemData(NewIndex, TempData); - end; - finally - FListBox.FMoving := False; - EndUpdate; - end; -end; - -//-- list box helper procs - -procedure TntListBox_AfterInherited_CreateWnd(ListBox: TCustomListBox{TNT-ALLOW TCustomListBox}; - var FSaveItems: TTntStrings; FItems: TTntStrings; FSaveTopIndex, FSaveItemIndex: Integer); -begin - if FSaveItems <> nil then - begin - FItems.Assign(FSaveItems); - FreeAndNil(FSaveItems); - ListBox.TopIndex := FSaveTopIndex; - ListBox.ItemIndex := FSaveItemIndex; - end; -end; - -procedure TntListBox_BeforeInherited_DestroyWnd(ListBox: TCustomListBox{TNT-ALLOW TCustomListBox}; - var FSaveItems: TTntStrings; const FItems: TTntStrings; var FSaveTopIndex, FSaveItemIndex: Integer); -begin - if (FItems.Count > 0) - and (not (TAccessCustomListBox(ListBox).Style in [lbVirtual, lbVirtualOwnerDraw])) - then begin - FSaveItems := TTntStringList.Create; - FSaveItems.Assign(FItems); - FSaveTopIndex := ListBox.TopIndex; - FSaveItemIndex := ListBox.ItemIndex; - ListBox.Items.Clear; { This keeps TCustomListBox from creating its own FSaveItems. (this kills the original ItemIndex) } - end; -end; - -procedure TntListBox_DrawItem_Text(ListBox: TCustomListBox{TNT-ALLOW TCustomListBox}; Items: TTntStrings; Index: Integer; Rect: TRect); -var - Flags: Integer; - Canvas: TCanvas; -begin - Canvas := TAccessCustomListBox(ListBox).Canvas; - Canvas.FillRect(Rect); - if Index < Items.Count then - begin - Flags := ListBox.DrawTextBiDiModeFlags(DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX); - if not ListBox.UseRightToLeftAlignment then - Inc(Rect.Left, 2) - else - Dec(Rect.Right, 2); - Tnt_DrawTextW(Canvas.Handle, PWideChar(Items[Index]), Length(Items[Index]), Rect, Flags); - end; -end; - -procedure TntListBox_AddItem(Items: TTntStrings; const Item: WideString; AObject: TObject); -begin - Items.AddObject(PWideChar(Item), AObject); -end; - -procedure TntListBox_CopySelection(ListBox: TCustomListbox{TNT-ALLOW TCustomListbox}; - Items: TTntStrings; Destination: TCustomListControl); -var - I: Integer; -begin - if ListBox.MultiSelect then - begin - for I := 0 to Items.Count - 1 do - if ListBox.Selected[I] then - WideListControl_AddItem(Destination, PWideChar(Items[I]), Items.Objects[I]); - end - else - if Listbox.ItemIndex <> -1 then - WideListControl_AddItem(Destination, PWideChar(Items[ListBox.ItemIndex]), Items.Objects[ListBox.ItemIndex]); -end; - -function TntCustomListBox_GetOwnerData(ListBox: TCustomListBox{TNT-ALLOW TCustomListBox}; OnData: TLBGetWideDataEvent; Index: Integer; out Data: WideString): Boolean; -var - AnsiData: AnsiString; -begin - Result := False; - Data := ''; - if (Index > -1) and (Index < ListBox.Count) then begin - if Assigned(OnData) then begin - OnData(ListBox, Index, Data); - Result := True; - end else if Assigned(TAccessCustomListBox(ListBox).OnData) then begin - AnsiData := ''; - TAccessCustomListBox(ListBox).OnData(ListBox, Index, AnsiData); - Data := AnsiData; - Result := True; - end; - end; -end; - -function TntCustomListBox_LBGetText(ListBox: TCustomListBox{TNT-ALLOW TCustomListBox}; OnData: TLBGetWideDataEvent; var Message: TMessage): Boolean; -var - S: WideString; - AnsiS: AnsiString; -begin - if TAccessCustomListBox(ListBox).Style in [lbVirtual, lbVirtualOwnerDraw] then - begin - Result := True; - if TntCustomListBox_GetOwnerData(ListBox, OnData, Message.WParam, S) then begin - if Win32PlatformIsUnicode then begin - WStrCopy(PWideChar(Message.LParam), PWideChar(S)); - Message.Result := Length(S); - end else begin - AnsiS := S; - StrCopy{TNT-ALLOW StrCopy}(PAnsiChar(Message.LParam), PAnsiChar(AnsiS)); - Message.Result := Length(AnsiS); - end; - end - else - Message.Result := LB_ERR; - end - else - Result := False; -end; - -function TntCustomListBox_LBGetTextLen(ListBox: TCustomListBox{TNT-ALLOW TCustomListBox}; OnData: TLBGetWideDataEvent; var Message: TMessage): Boolean; -var - S: WideString; -begin - if TAccessCustomListBox(ListBox).Style in [lbVirtual, lbVirtualOwnerDraw] then - begin - Result := True; - if TntCustomListBox_GetOwnerData(ListBox, OnData, Message.WParam, S) then begin - if Win32PlatformIsUnicode then - Message.Result := Length(S) - else - Message.Result := Length(AnsiString(S)); - end else - Message.Result := LB_ERR; - end - else - Result := False; -end; - -{ TTntCustomListBox } - -constructor TTntCustomListBox.Create(AOwner: TComponent); -begin - inherited; - FItems := TTntListBoxStrings.Create; - TTntListBoxStrings(FItems).ListBox := Self; -end; - -destructor TTntCustomListBox.Destroy; -begin - FreeAndNil(FItems); - FreeAndNil(FSaveItems); - inherited; -end; - -procedure TTntCustomListBox.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, 'LISTBOX'); -end; - -procedure TTntCustomListBox.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -procedure TTntCustomListBox.CreateWnd; -begin - inherited; - TntListBox_AfterInherited_CreateWnd(Self, FSaveItems, FItems, FSaveTopIndex, FSaveItemIndex); -end; - -procedure TTntCustomListBox.DestroyWnd; -begin - TntListBox_BeforeInherited_DestroyWnd(Self, FSaveItems, FItems, FSaveTopIndex, FSaveItemIndex); - inherited; -end; - -procedure TTntCustomListBox.SetItems(const Value: TTntStrings); -begin - FItems.Assign(Value); -end; - -procedure TTntCustomListBox.DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState); -begin - if Assigned(OnDrawItem) then - OnDrawItem(Self, Index, Rect, State) - else - TntListBox_DrawItem_Text(Self, Items, Index, Rect); -end; - -function TTntCustomListBox.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -function TTntCustomListBox.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntCustomListBox.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntCustomListBox.AddItem(const Item: WideString; AObject: TObject); -begin - TntListBox_AddItem(Items, Item, AObject); -end; - -procedure TTntCustomListBox.CopySelection(Destination: TCustomListControl); -begin - TntListBox_CopySelection(Self, Items, Destination); -end; - -procedure TTntCustomListBox.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomListBox.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -procedure TTntCustomListBox.LBGetText(var Message: TMessage); -begin - if not TntCustomListBox_LBGetText(Self, OnData, Message) then - inherited; -end; - -procedure TTntCustomListBox.LBGetTextLen(var Message: TMessage); -begin - if not TntCustomListBox_LBGetTextLen(Self, OnData, Message) then - inherited; -end; - -// --- label helper procs - -type TAccessCustomLabel = class(TCustomLabel{TNT-ALLOW TCustomLabel}); - -function TntLabel_DoDrawText(Control: TCustomLabel{TNT-ALLOW TCustomLabel}; var Rect: TRect; Flags: Integer; const GetLabelText: WideString): Boolean; -{$IFDEF COMPILER_9_UP} -const - EllipsisStr = '...'; - Ellipsis: array[TEllipsisPosition] of Longint = (0, DT_PATH_ELLIPSIS, - DT_END_ELLIPSIS, DT_WORD_ELLIPSIS); -{$ENDIF} -var - Text: WideString; - ShowAccelChar: Boolean; - Canvas: TCanvas; - {$IFDEF COMPILER_9_UP} - DText: WideString; - NewRect: TRect; - Height: Integer; - Delim: Integer; - {$ENDIF} -begin - Result := False; - if Win32PlatformIsUnicode then begin - Result := True; - Text := GetLabelText; - ShowAccelChar := TAccessCustomLabel(Control).ShowAccelChar; - Canvas := Control.Canvas; - if (Flags and DT_CALCRECT <> 0) and ((Text = '') or ShowAccelChar and - (Text[1] = '&') and (Text[2] = #0)) then Text := Text + ' '; - if not ShowAccelChar then Flags := Flags or DT_NOPREFIX; - Flags := Control.DrawTextBiDiModeFlags(Flags); - Canvas.Font := TAccessCustomLabel(Control).Font; - {$IFDEF COMPILER_9_UP} - if (TAccessCustomLabel(Control).EllipsisPosition <> epNone) - and (not TAccessCustomLabel(Control).AutoSize) then - begin - DText := Text; - Flags := Flags and not (DT_EXPANDTABS or DT_CALCRECT); - Flags := Flags or Ellipsis[TAccessCustomLabel(Control).EllipsisPosition]; - if TAccessCustomLabel(Control).WordWrap - and (TAccessCustomLabel(Control).EllipsisPosition in [epEndEllipsis, epWordEllipsis]) then - begin - repeat - NewRect := Rect; - Dec(NewRect.Right, WideCanvasTextWidth(Canvas, EllipsisStr)); - Tnt_DrawTextW(Canvas.Handle, PWideChar(DText), Length(DText), NewRect, Flags or DT_CALCRECT); - Height := NewRect.Bottom - NewRect.Top; - if (Height > TAccessCustomLabel(Control).ClientHeight) - and (Height > Canvas.Font.Height) then - begin - Delim := WideLastDelimiter(' '#9, Text); - if Delim = 0 then - Delim := Length(Text); - Dec(Delim); - Text := Copy(Text, 1, Delim); - DText := Text + EllipsisStr; - if Text = '' then - Break; - end else - Break; - until False; - end; - if Text <> '' then - Text := DText; - end; - {$ENDIF} - if not Control.Enabled then - begin - OffsetRect(Rect, 1, 1); - Canvas.Font.Color := clBtnHighlight; - Tnt_DrawTextW(Canvas.Handle, PWideChar(Text), Length(Text), Rect, Flags); - OffsetRect(Rect, -1, -1); - Canvas.Font.Color := clBtnShadow; - Tnt_DrawTextW(Canvas.Handle, PWideChar(Text), Length(Text), Rect, Flags); - end - else - Tnt_DrawTextW(Canvas.Handle, PWideChar(Text), Length(Text), Rect, Flags); - end; -end; - -procedure TntLabel_CMDialogChar(Control: TCustomLabel{TNT-ALLOW TCustomLabel}; var Message: TCMDialogChar; const Caption: WideString); -var - FocusControl: TWinControl; - ShowAccelChar: Boolean; -begin - FocusControl := TAccessCustomLabel(Control).FocusControl; - ShowAccelChar := TAccessCustomLabel(Control).ShowAccelChar; - if (FocusControl <> nil) and Control.Enabled and ShowAccelChar and - IsWideCharAccel(Message.CharCode, Caption) then - with FocusControl do - if CanFocus then - begin - SetFocus; - Message.Result := 1; - end; -end; - -{ TTntCustomLabel } - -procedure TTntCustomLabel.CMDialogChar(var Message: TCMDialogChar); -begin - TntLabel_CMDialogChar(Self, Message, Caption); -end; - -function TTntCustomLabel.IsCaptionStored: Boolean; -begin - Result := TntControl_IsCaptionStored(Self) -end; - -function TTntCustomLabel.GetCaption: TWideCaption; -begin - Result := TntControl_GetText(Self); -end; - -procedure TTntCustomLabel.SetCaption(const Value: TWideCaption); -begin - TntControl_SetText(Self, Value); -end; - -procedure TTntCustomLabel.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntCustomLabel.GetLabelText: WideString; -begin - Result := Caption; -end; - -procedure TTntCustomLabel.DoDrawText(var Rect: TRect; Flags: Integer); -begin - if not TntLabel_DoDrawText(Self, Rect, Flags, GetLabelText) then - inherited; -end; - -function TTntCustomLabel.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -function TTntCustomLabel.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntCustomLabel.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntCustomLabel.CMHintShow(var Message: TMessage); -begin - ProcessCMHintShowMsg(Message); - inherited; -end; - -procedure TTntCustomLabel.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomLabel.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntButton } - -procedure TntButton_CMDialogChar(Button: TButton{TNT-ALLOW TButton}; var Message: TCMDialogChar); -begin - with Message do - if IsWideCharAccel(Message.CharCode, TntControl_GetText(Button)) - and Button.CanFocus then - begin - Button.Click; - Result := 1; - end else - Button.Broadcast(Message); -end; - -procedure TTntButton.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, 'BUTTON'); -end; - -procedure TTntButton.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -procedure TTntButton.CMDialogChar(var Message: TCMDialogChar); -begin - TntButton_CMDialogChar(Self, Message); -end; - -function TTntButton.IsCaptionStored: Boolean; -begin - Result := TntControl_IsCaptionStored(Self) -end; - -function TTntButton.GetCaption: TWideCaption; -begin - Result := TntControl_GetText(Self) -end; - -procedure TTntButton.SetCaption(const Value: TWideCaption); -begin - TntControl_SetText(Self, Value); -end; - -function TTntButton.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -function TTntButton.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntButton.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntButton.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntButton.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntCustomCheckBox } - -procedure TTntCustomCheckBox.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, 'BUTTON'); -end; - -procedure TTntCustomCheckBox.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -procedure TTntCustomCheckBox.CMDialogChar(var Message: TCMDialogChar); -begin - with Message do - if IsWideCharAccel(Message.CharCode, Caption) - and CanFocus then - begin - SetFocus; - if Focused then Toggle; - Result := 1; - end else - Broadcast(Message); -end; - -function TTntCustomCheckBox.IsCaptionStored: Boolean; -begin - Result := TntControl_IsCaptionStored(Self) -end; - -function TTntCustomCheckBox.GetCaption: TWideCaption; -begin - Result := TntControl_GetText(Self) -end; - -procedure TTntCustomCheckBox.SetCaption(const Value: TWideCaption); -begin - TntControl_SetText(Self, Value); -end; - -function TTntCustomCheckBox.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -function TTntCustomCheckBox.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntCustomCheckBox.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntCustomCheckBox.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomCheckBox.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntRadioButton } - -procedure TTntRadioButton.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, 'BUTTON'); -end; - -procedure TTntRadioButton.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -procedure TTntRadioButton.CMDialogChar(var Message: TCMDialogChar); -begin - with Message do - if IsWideCharAccel(Message.CharCode, Caption) - and CanFocus then - begin - SetFocus; - Result := 1; - end else - Broadcast(Message); -end; - -function TTntRadioButton.IsCaptionStored: Boolean; -begin - Result := TntControl_IsCaptionStored(Self); -end; - -function TTntRadioButton.GetCaption: TWideCaption; -begin - Result := TntControl_GetText(Self) -end; - -procedure TTntRadioButton.SetCaption(const Value: TWideCaption); -begin - TntControl_SetText(Self, Value); -end; - -function TTntRadioButton.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -function TTntRadioButton.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntRadioButton.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntRadioButton.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntRadioButton.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntScrollBar } - -procedure TTntScrollBar.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, 'SCROLLBAR'); -end; - -procedure TTntScrollBar.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -function TTntScrollBar.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -function TTntScrollBar.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntScrollBar.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntScrollBar.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntScrollBar.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntCustomGroupBox } - -procedure TTntCustomGroupBox.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, ''); -end; - -procedure TTntCustomGroupBox.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -procedure TTntCustomGroupBox.CMDialogChar(var Message: TCMDialogChar); -begin - with Message do - if IsWideCharAccel(Message.CharCode, Caption) - and CanFocus then - begin - SelectFirst; - Result := 1; - end else - Broadcast(Message); -end; - -function TTntCustomGroupBox.IsCaptionStored: Boolean; -begin - Result := TntControl_IsCaptionStored(Self); -end; - -function TTntCustomGroupBox.GetCaption: TWideCaption; -begin - Result := TntControl_GetText(Self) -end; - -procedure TTntCustomGroupBox.SetCaption(const Value: TWideCaption); -begin - TntControl_SetText(Self, Value); -end; - -procedure TTntCustomGroupBox.Paint; - - {$IFDEF THEME_7_UP} - procedure PaintThemedGroupBox; - var - CaptionRect: TRect; - OuterRect: TRect; - Size: TSize; - Box: TThemedButton; - Details: TThemedElementDetails; - begin - with Canvas do begin - if Caption <> '' then - begin - GetTextExtentPoint32W(Handle, PWideChar(Caption), Length(Caption), Size); - CaptionRect := Rect(0, 0, Size.cx, Size.cy); - if not UseRightToLeftAlignment then - OffsetRect(CaptionRect, 8, 0) - else - OffsetRect(CaptionRect, Width - 8 - CaptionRect.Right, 0); - end - else - CaptionRect := Rect(0, 0, 0, 0); - - OuterRect := ClientRect; - OuterRect.Top := (CaptionRect.Bottom - CaptionRect.Top) div 2; - with CaptionRect do - ExcludeClipRect(Handle, Left, Top, Right, Bottom); - if Enabled then - Box := tbGroupBoxNormal - else - Box := tbGroupBoxDisabled; - Details := ThemeServices.GetElementDetails(Box); - ThemeServices.DrawElement(Handle, Details, OuterRect); - - SelectClipRgn(Handle, 0); - if Text <> '' then - ThemeServices.DrawText{TNT-ALLOW DrawText}(Handle, Details, Caption, CaptionRect, DT_LEFT, 0); - end; - end; - {$ENDIF} - - procedure PaintGroupBox; - var - H: Integer; - R: TRect; - Flags: Longint; - begin - with Canvas do begin - H := WideCanvasTextHeight(Canvas, '0'); - R := Rect(0, H div 2 - 1, Width, Height); - if Ctl3D then - begin - Inc(R.Left); - Inc(R.Top); - Brush.Color := clBtnHighlight; - FrameRect(R); - OffsetRect(R, -1, -1); - Brush.Color := clBtnShadow; - end else - Brush.Color := clWindowFrame; - FrameRect(R); - if Caption <> '' then - begin - if not UseRightToLeftAlignment then - R := Rect(8, 0, 0, H) - else - R := Rect(R.Right - WideCanvasTextWidth(Canvas, Caption) - 8, 0, 0, H); - Flags := DrawTextBiDiModeFlags(DT_SINGLELINE); - Tnt_DrawTextW(Handle, PWideChar(Caption), Length(Caption), R, Flags or DT_CALCRECT); - Brush.Color := Color; - Tnt_DrawTextW(Handle, PWideChar(Caption), Length(Caption), R, Flags); - end; - end; - end; - -begin - if (not Win32PlatformIsUnicode) then - inherited - else - begin - Canvas.Font := Self.Font; - {$IFDEF THEME_7_UP} - if ThemeServices.ThemesEnabled then - PaintThemedGroupBox - else - PaintGroupBox; - {$ELSE} - PaintGroupBox; - {$ENDIF} - end; -end; - -function TTntCustomGroupBox.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -function TTntCustomGroupBox.GetHint: WideString; -begin - Result := TntControl_GetHint(Self); -end; - -procedure TTntCustomGroupBox.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntCustomGroupBox.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomGroupBox.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -{ TTntCustomStaticText } - -constructor TTntCustomStaticText.Create(AOwner: TComponent); -begin - inherited; - AdjustBounds; -end; - -procedure TTntCustomStaticText.CMFontChanged(var Message: TMessage); -begin - inherited; - AdjustBounds; -end; - -procedure TTntCustomStaticText.CMTextChanged(var Message: TMessage); -begin - inherited; - AdjustBounds; -end; - -procedure TTntCustomStaticText.Loaded; -begin - inherited; - AdjustBounds; -end; - -procedure TTntCustomStaticText.SetAutoSize(AValue: boolean); -begin - inherited; - if AValue then - AdjustBounds; -end; - -procedure TTntCustomStaticText.CreateWindowHandle(const Params: TCreateParams); -begin - CreateUnicodeHandle(Self, Params, 'STATIC'); -end; - -procedure TTntCustomStaticText.DefineProperties(Filer: TFiler); -begin - inherited; - TntPersistent_AfterInherited_DefineProperties(Filer, Self); -end; - -procedure TTntCustomStaticText.CMDialogChar(var Message: TCMDialogChar); -begin - if (FocusControl <> nil) and Enabled and ShowAccelChar and - IsWideCharAccel(Message.CharCode, Caption) then - with FocusControl do - if CanFocus then - begin - SetFocus; - Message.Result := 1; - end; -end; - -function TTntCustomStaticText.IsCaptionStored: Boolean; -begin - Result := TntControl_IsCaptionStored(Self) -end; - -procedure TTntCustomStaticText.AdjustBounds; -var - DC: HDC; - SaveFont: HFont; - TextSize: TSize; -begin - if not (csReading in ComponentState) and AutoSize then - begin - DC := GetDC(0); - SaveFont := SelectObject(DC, Font.Handle); - GetTextExtentPoint32W(DC, PWideChar(Caption), Length(Caption), TextSize); - SelectObject(DC, SaveFont); - ReleaseDC(0, DC); - SetBounds(Left, Top, - TextSize.cx + (GetSystemMetrics(SM_CXBORDER) * 4), - TextSize.cy + (GetSystemMetrics(SM_CYBORDER) * 4)); - end; -end; - -function TTntCustomStaticText.GetCaption: TWideCaption; -begin - Result := TntControl_GetText(Self) -end; - -procedure TTntCustomStaticText.SetCaption(const Value: TWideCaption); -begin - TntControl_SetText(Self, Value); -end; - -function TTntCustomStaticText.IsHintStored: Boolean; -begin - Result := TntControl_IsHintStored(Self) -end; - -function TTntCustomStaticText.GetHint: WideString; -begin - Result := TntControl_GetHint(Self) -end; - -procedure TTntCustomStaticText.SetHint(const Value: WideString); -begin - TntControl_SetHint(Self, Value); -end; - -procedure TTntCustomStaticText.ActionChange(Sender: TObject; CheckDefaults: Boolean); -begin - TntControl_BeforeInherited_ActionChange(Self, Sender, CheckDefaults); - inherited; -end; - -function TTntCustomStaticText.GetActionLinkClass: TControlActionLinkClass; -begin - Result := TntControl_GetActionLinkClass(Self, inherited GetActionLinkClass); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntSysUtils.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntSysUtils.pas deleted file mode 100644 index ff0364da1..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntSysUtils.pas +++ /dev/null @@ -1,1883 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntSysUtils; - -{$INCLUDE TntCompilers.inc} - -interface - -{ TODO: Consider: more filename functions from SysUtils } -{ TODO: Consider: string functions from StrUtils. } - -uses - Types, SysUtils, Windows; - -//--------------------------------------------------------------------------------------------- -// Tnt - Types -//--------------------------------------------------------------------------------------------- - -// ......... introduced ......... -type - WideException = class(Exception) - private - FMessage: WideString; - procedure SetMessage(const Value: WideString); - public - constructor Create(const Msg: WideString); - constructor CreateFmt(const Msg: WideString; const Args: array of const); - constructor CreateRes(Ident: Integer); overload; - constructor CreateRes(ResStringRec: PResStringRec); overload; - constructor CreateResFmt(Ident: Integer; const Args: array of const); overload; - constructor CreateResFmt(ResStringRec: PResStringRec; const Args: array of const); overload; - constructor CreateHelp(const Msg: WideString; AHelpContext: Integer); - constructor CreateFmtHelp(const Msg: WideString; const Args: array of const; - AHelpContext: Integer); - constructor CreateResHelp(Ident: Integer; AHelpContext: Integer); overload; - constructor CreateResHelp(ResStringRec: PResStringRec; AHelpContext: Integer); overload; - constructor CreateResFmtHelp(ResStringRec: PResStringRec; const Args: array of const; - AHelpContext: Integer); overload; - constructor CreateResFmtHelp(Ident: Integer; const Args: array of const; - AHelpContext: Integer); overload; - property Message: WideString read FMessage write SetMessage; - end; - - EWideOSError = class(WideException) - public - ErrorCode: DWORD; - end; - - // The user of the application did something plainly wrong. - ETntUserError = class(Exception); - // A general error occured. (ie. file didn't exist, server didn't return data, etc.) - ETntGeneralError = class(Exception); - // Like Assert(). An error occured that should never have happened, send me a bug report now! - ETntInternalError = class(Exception); - -//--------------------------------------------------------------------------------------------- -// Tnt - SysUtils -//--------------------------------------------------------------------------------------------- - -// ......... SBCS and MBCS functions with WideString replacements in SysUtils.pas ......... - -{TNT-WARN CompareStr} {TNT-WARN AnsiCompareStr} -{TNT-WARN SameStr} {TNT-WARN AnsiSameStr} -{TNT-WARN SameText} {TNT-WARN AnsiSameText} -{TNT-WARN CompareText} {TNT-WARN AnsiCompareText} -{TNT-WARN UpperCase} {TNT-WARN AnsiUpperCase} -{TNT-WARN LowerCase} {TNT-WARN AnsiLowerCase} - -{TNT-WARN AnsiPos} { --> Pos() supports WideString. } -{TNT-WARN FmtStr} -{TNT-WARN Format} -{TNT-WARN FormatBuf} - -// ......... MBCS Byte Type Procs ......... - -{TNT-WARN ByteType} -{TNT-WARN StrByteType} -{TNT-WARN ByteToCharIndex} -{TNT-WARN ByteToCharLen} -{TNT-WARN CharToByteIndex} -{TNT-WARN CharToByteLen} - -// ........ null-terminated string functions ......... - -{TNT-WARN StrEnd} -{TNT-WARN StrLen} -{TNT-WARN StrLCopy} -{TNT-WARN StrCopy} -{TNT-WARN StrECopy} -{TNT-WARN StrPLCopy} -{TNT-WARN StrPCopy} -{TNT-WARN StrLComp} -{TNT-WARN AnsiStrLComp} -{TNT-WARN StrComp} -{TNT-WARN AnsiStrComp} -{TNT-WARN StrLIComp} -{TNT-WARN AnsiStrLIComp} -{TNT-WARN StrIComp} -{TNT-WARN AnsiStrIComp} -{TNT-WARN StrLower} -{TNT-WARN AnsiStrLower} -{TNT-WARN StrUpper} -{TNT-WARN AnsiStrUpper} -{TNT-WARN StrPos} -{TNT-WARN AnsiStrPos} -{TNT-WARN StrScan} -{TNT-WARN AnsiStrScan} -{TNT-WARN StrRScan} -{TNT-WARN AnsiStrRScan} -{TNT-WARN StrLCat} -{TNT-WARN StrCat} -{TNT-WARN StrMove} -{TNT-WARN StrPas} -{TNT-WARN StrAlloc} -{TNT-WARN StrBufSize} -{TNT-WARN StrNew} -{TNT-WARN StrDispose} - -{TNT-WARN AnsiExtractQuotedStr} -{TNT-WARN AnsiLastChar} -{TNT-WARN AnsiStrLastChar} -{TNT-WARN QuotedStr} -{TNT-WARN AnsiQuotedStr} -{TNT-WARN AnsiDequotedStr} - -// ........ string functions ......... - -{$IFNDEF COMPILER_9_UP} - // - // pre-Delphi 9 issues w/ WideFormatBuf, WideFmtStr and WideFormat - // - - {$IFDEF COMPILER_7_UP} - type - PFormatSettings = ^TFormatSettings; - {$ENDIF} - - // SysUtils.WideFormatBuf doesn't correctly handle numeric specifiers. - function Tnt_WideFormatBuf(var Buffer; BufLen: Cardinal; const FormatStr; - FmtLen: Cardinal; const Args: array of const): Cardinal; {$IFDEF COMPILER_7_UP} overload; {$ENDIF} - - {$IFDEF COMPILER_7_UP} - function Tnt_WideFormatBuf(var Buffer; BufLen: Cardinal; const FormatStr; - FmtLen: Cardinal; const Args: array of const; - const FormatSettings: TFormatSettings): Cardinal; overload; - {$ENDIF} - - // SysUtils.WideFmtStr doesn't handle string lengths > 4096. - procedure Tnt_WideFmtStr(var Result: WideString; const FormatStr: WideString; - const Args: array of const); {$IFDEF COMPILER_7_UP} overload; {$ENDIF} - - {$IFDEF COMPILER_7_UP} - procedure Tnt_WideFmtStr(var Result: WideString; const FormatStr: WideString; - const Args: array of const; const FormatSettings: TFormatSettings); overload; - {$ENDIF} - - {---------------------------------------------------------------------------------------- - Without the FormatSettings parameter, Tnt_WideFormat is *NOT* necessary... - TntSystem.InstallTntSystemUpdates([tsFixWideFormat]); - will fix WideFormat as well as WideFmtStr. - ----------------------------------------------------------------------------------------} - function Tnt_WideFormat(const FormatStr: WideString; const Args: array of const): WideString; {$IFDEF COMPILER_7_UP} overload; {$ENDIF} - - {$IFDEF COMPILER_7_UP} - function Tnt_WideFormat(const FormatStr: WideString; const Args: array of const; - const FormatSettings: TFormatSettings): WideString; overload; - {$ENDIF} - -{$ENDIF} - -function WideLoadStr(Ident: Integer): WideString; -function WideFmtLoadStr(Ident: Integer; const Args: array of const): WideString; - -{TNT-WARN WideUpperCase} // SysUtils.WideUpperCase is broken on Win9x for D6, D7, D9. -function Tnt_WideUpperCase(const S: WideString): WideString; -{TNT-WARN WideLowerCase} // SysUtils.WideLowerCase is broken on Win9x for D6, D7, D9. -function Tnt_WideLowerCase(const S: WideString): WideString; - -function TntWideLastChar(const S: WideString): WideChar; - -{TNT-WARN StringReplace} -{TNT-WARN WideStringReplace} // <-- WideStrUtils.WideStringReplace uses SysUtils.WideUpperCase which is broken on Win9x. -function Tnt_WideStringReplace(const S, OldPattern, NewPattern: WideString; - Flags: TReplaceFlags; WholeWord: Boolean = False): WideString; - -{TNT-WARN AdjustLineBreaks} -type TTntTextLineBreakStyle = (tlbsLF, tlbsCRLF, tlbsCR); -function TntAdjustLineBreaksLength(const S: WideString; Style: TTntTextLineBreakStyle = tlbsCRLF): Integer; -function TntAdjustLineBreaks(const S: WideString; Style: TTntTextLineBreakStyle = tlbsCRLF): WideString; - -{TNT-WARN WrapText} -function WideWrapText(const Line, BreakStr: WideString; const BreakChars: TSysCharSet; - MaxCol: Integer): WideString; overload; -function WideWrapText(const Line: WideString; MaxCol: Integer): WideString; overload; - -// ........ filename manipulation ......... - -{TNT-WARN SameFileName} // doesn't apply to Unicode filenames, use WideSameText -{TNT-WARN AnsiCompareFileName} // doesn't apply to Unicode filenames, use WideCompareText -{TNT-WARN AnsiLowerCaseFileName} // doesn't apply to Unicode filenames, use WideLowerCase -{TNT-WARN AnsiUpperCaseFileName} // doesn't apply to Unicode filenames, use WideUpperCase - -{TNT-WARN IncludeTrailingBackslash} -function WideIncludeTrailingBackslash(const S: WideString): WideString; -{TNT-WARN IncludeTrailingPathDelimiter} -function WideIncludeTrailingPathDelimiter(const S: WideString): WideString; -{TNT-WARN ExcludeTrailingBackslash} -function WideExcludeTrailingBackslash(const S: WideString): WideString; -{TNT-WARN ExcludeTrailingPathDelimiter} -function WideExcludeTrailingPathDelimiter(const S: WideString): WideString; -{TNT-WARN IsDelimiter} -function WideIsDelimiter(const Delimiters, S: WideString; Index: Integer): Boolean; -{TNT-WARN IsPathDelimiter} -function WideIsPathDelimiter(const S: WideString; Index: Integer): Boolean; -{TNT-WARN LastDelimiter} -function WideLastDelimiter(const Delimiters, S: WideString): Integer; -{TNT-WARN ChangeFileExt} -function WideChangeFileExt(const FileName, Extension: WideString): WideString; -{TNT-WARN ExtractFilePath} -function WideExtractFilePath(const FileName: WideString): WideString; -{TNT-WARN ExtractFileDir} -function WideExtractFileDir(const FileName: WideString): WideString; -{TNT-WARN ExtractFileDrive} -function WideExtractFileDrive(const FileName: WideString): WideString; -{TNT-WARN ExtractFileName} -function WideExtractFileName(const FileName: WideString): WideString; -{TNT-WARN ExtractFileExt} -function WideExtractFileExt(const FileName: WideString): WideString; -{TNT-WARN ExtractRelativePath} -function WideExtractRelativePath(const BaseName, DestName: WideString): WideString; - -// ........ file management routines ......... - -{TNT-WARN ExpandFileName} -function WideExpandFileName(const FileName: WideString): WideString; -{TNT-WARN ExtractShortPathName} -function WideExtractShortPathName(const FileName: WideString): WideString; -{TNT-WARN FileCreate} -function WideFileCreate(const FileName: WideString): Integer; -{TNT-WARN FileOpen} -function WideFileOpen(const FileName: WideString; Mode: LongWord): Integer; -{TNT-WARN FileAge} -function WideFileAge(const FileName: WideString): Integer; overload; -function WideFileAge(const FileName: WideString; out FileDateTime: TDateTime): Boolean; overload; -{TNT-WARN DirectoryExists} -function WideDirectoryExists(const Name: WideString): Boolean; -{TNT-WARN FileExists} -function WideFileExists(const Name: WideString): Boolean; -{TNT-WARN FileGetAttr} -function WideFileGetAttr(const FileName: WideString): Cardinal; -{TNT-WARN FileSetAttr} -function WideFileSetAttr(const FileName: WideString; Attr: Integer): Boolean; -{TNT-WARN FileIsReadOnly} -function WideFileIsReadOnly(const FileName: WideString): Boolean; -{TNT-WARN FileSetReadOnly} -function WideFileSetReadOnly(const FileName: WideString; ReadOnly: Boolean): Boolean; -{TNT-WARN ForceDirectories} -function WideForceDirectories(Dir: WideString): Boolean; -{TNT-WARN FileSearch} -function WideFileSearch(const Name, DirList: WideString): WideString; -{TNT-WARN RenameFile} -function WideRenameFile(const OldName, NewName: WideString): Boolean; -{TNT-WARN DeleteFile} -function WideDeleteFile(const FileName: WideString): Boolean; -{TNT-WARN CopyFile} -function WideCopyFile(FromFile, ToFile: WideString; FailIfExists: Boolean): Boolean; - - -{TNT-WARN TFileName} -type - TWideFileName = type WideString; - -{TNT-WARN TSearchRec} // <-- FindFile - warning on TSearchRec is all that is necessary -type - TSearchRecW = record - Time: Integer; - Size: Int64; - Attr: Integer; - Name: TWideFileName; - ExcludeAttr: Integer; - FindHandle: THandle; - FindData: TWin32FindDataW; - end; -function WideFindFirst(const Path: WideString; Attr: Integer; var F: TSearchRecW): Integer; -function WideFindNext(var F: TSearchRecW): Integer; -procedure WideFindClose(var F: TSearchRecW); - -{TNT-WARN CreateDir} -function WideCreateDir(const Dir: WideString): Boolean; -{TNT-WARN RemoveDir} -function WideRemoveDir(const Dir: WideString): Boolean; -{TNT-WARN GetCurrentDir} -function WideGetCurrentDir: WideString; -{TNT-WARN SetCurrentDir} -function WideSetCurrentDir(const Dir: WideString): Boolean; - - -// ........ date/time functions ......... - -{TNT-WARN TryStrToDateTime} -function TntTryStrToDateTime(Str: WideString; out DateTime: TDateTime): Boolean; -{TNT-WARN TryStrToDate} -function TntTryStrToDate(Str: WideString; out DateTime: TDateTime): Boolean; -{TNT-WARN TryStrToTime} -function TntTryStrToTime(Str: WideString; out DateTime: TDateTime): Boolean; - -{ introduced } -function ValidDateTimeStr(Str: WideString): Boolean; -function ValidDateStr(Str: WideString): Boolean; -function ValidTimeStr(Str: WideString): Boolean; - -{TNT-WARN StrToDateTime} -function TntStrToDateTime(Str: WideString): TDateTime; -{TNT-WARN StrToDate} -function TntStrToDate(Str: WideString): TDateTime; -{TNT-WARN StrToTime} -function TntStrToTime(Str: WideString): TDateTime; -{TNT-WARN StrToDateTimeDef} -function TntStrToDateTimeDef(Str: WideString; Default: TDateTime): TDateTime; -{TNT-WARN StrToDateDef} -function TntStrToDateDef(Str: WideString; Default: TDateTime): TDateTime; -{TNT-WARN StrToTimeDef} -function TntStrToTimeDef(Str: WideString; Default: TDateTime): TDateTime; - -{TNT-WARN CurrToStr} -{TNT-WARN CurrToStrF} -function TntCurrToStr(Value: Currency; lpFormat: PCurrencyFmtW = nil): WideString; -{TNT-WARN StrToCurr} -function TntStrToCurr(const S: WideString): Currency; -{TNT-WARN StrToCurrDef} -function ValidCurrencyStr(const S: WideString): Boolean; -function TntStrToCurrDef(const S: WideString; const Default: Currency): Currency; -function GetDefaultCurrencyFmt: TCurrencyFmtW; - -// ........ misc functions ......... - -{TNT-WARN GetLocaleStr} -function WideGetLocaleStr(LocaleID: LCID; LocaleType: Integer; const Default: WideString): WideString; -{TNT-WARN SysErrorMessage} -function WideSysErrorMessage(ErrorCode: Integer): WideString; -procedure WideRaiseLastOSError; - -// ......... introduced ......... - -function WideLibraryErrorMessage(const LibName: WideString; Dll: THandle; ErrorCode: Integer): WideString; - -const - CR = WideChar(#13); - LF = WideChar(#10); - CRLF = WideString(#13#10); - WideLineSeparator = WideChar($2028); - -var - Win32PlatformIsUnicode: Boolean; - Win32PlatformIsXP: Boolean; - Win32PlatformIs2003: Boolean; - Win32PlatformIsVista: Boolean; - -{$IFNDEF COMPILER_7_UP} -function CheckWin32Version(AMajor: Integer; AMinor: Integer = 0): Boolean; -{$ENDIF} -function WinCheckH(RetVal: Cardinal): Cardinal; -function WinCheckFileH(RetVal: Cardinal): Cardinal; -function WinCheckP(RetVal: Pointer): Pointer; - -function WideGetModuleFileName(Instance: HModule): WideString; -function WideSafeLoadLibrary(const Filename: Widestring; - ErrorMode: UINT = SEM_NOOPENFILEERRORBOX): HMODULE; -function WideLoadPackage(const Name: Widestring): HMODULE; - -function IsWideCharUpper(WC: WideChar): Boolean; -function IsWideCharLower(WC: WideChar): Boolean; -function IsWideCharDigit(WC: WideChar): Boolean; -function IsWideCharSpace(WC: WideChar): Boolean; -function IsWideCharPunct(WC: WideChar): Boolean; -function IsWideCharCntrl(WC: WideChar): Boolean; -function IsWideCharBlank(WC: WideChar): Boolean; -function IsWideCharXDigit(WC: WideChar): Boolean; -function IsWideCharAlpha(WC: WideChar): Boolean; -function IsWideCharAlphaNumeric(WC: WideChar): Boolean; - -function WideTextPos(const SubStr, S: WideString): Integer; - -function ExtractStringArrayStr(P: PWideChar): WideString; -function ExtractStringFromStringArray(var P: PWideChar; Separator: WideChar = #0): WideString; -function ExtractStringsFromStringArray(P: PWideChar; Separator: WideChar = #0): TWideStringDynArray; - -function IsWideCharMappableToAnsi(const WC: WideChar): Boolean; -function IsWideStringMappableToAnsi(const WS: WideString): Boolean; -function IsRTF(const Value: WideString): Boolean; - -function ENG_US_FloatToStr(Value: Extended): WideString; -function ENG_US_StrToFloat(const S: WideString): Extended; - -//--------------------------------------------------------------------------------------------- -// Tnt - Variants -//--------------------------------------------------------------------------------------------- - -// ........ Variants.pas has WideString versions of these functions ......... -{TNT-WARN VarToStr} -{TNT-WARN VarToStrDef} - -var - _SettingChangeTime: Cardinal; - -implementation - -uses - ActiveX, ComObj, SysConst, - {$IFDEF COMPILER_9_UP} WideStrUtils, {$ENDIF} TntWideStrUtils, - TntSystem, TntWindows, TntFormatStrUtils; - -//--------------------------------------------------------------------------------------------- -// Tnt - Types -//--------------------------------------------------------------------------------------------- - -{ WideException } - -constructor WideException.Create(const Msg: WideString); -begin - FMessage := Msg; - inherited Message := FMessage; -end; - -constructor WideException.CreateFmt(const Msg: WideString; - const Args: array of const); -begin - FMessage := WideFormat(Msg, Args); - inherited Message := FMessage; -end; - -constructor WideException.CreateRes(Ident: Integer); -begin - FMessage := WideLoadStr(Ident); - inherited Message := FMessage; -end; - -constructor WideException.CreateRes(ResStringRec: PResStringRec); -begin - FMessage := WideLoadResString(ResStringRec); - inherited Message := FMessage; -end; - -constructor WideException.CreateResFmt(Ident: Integer; - const Args: array of const); -begin - FMessage := WideFormat(WideLoadStr(Ident), Args); - inherited Message := FMessage; -end; - -constructor WideException.CreateResFmt(ResStringRec: PResStringRec; - const Args: array of const); -begin - FMessage := WideFormat(WideLoadResString(ResStringRec), Args); - inherited Message := FMessage; -end; - -constructor WideException.CreateHelp(const Msg: WideString; - AHelpContext: Integer); -begin - FMessage := Msg; - inherited Message := FMessage; - inherited HelpContext := AHelpContext; -end; - -constructor WideException.CreateFmtHelp(const Msg: WideString; - const Args: array of const; AHelpContext: Integer); -begin - FMessage := WideFormat(Msg, Args); - inherited Message := FMessage; - inherited HelpContext := AHelpContext; -end; - -constructor WideException.CreateResHelp(Ident: Integer; AHelpContext: Integer); -begin - FMessage := WideLoadStr(Ident); - inherited Message := FMessage; - inherited HelpContext := AHelpContext; -end; - -constructor WideException.CreateResHelp(ResStringRec: PResStringRec; - AHelpContext: Integer); -begin - FMessage := WideLoadResString(ResStringRec); - inherited Message := FMessage; - inherited HelpContext := AHelpContext; -end; - -constructor WideException.CreateResFmtHelp(Ident: Integer; - const Args: array of const; AHelpContext: Integer); -begin - FMessage := WideFormat(WideLoadStr(Ident), Args); - inherited Message := FMessage; - inherited HelpContext := AHelpContext; -end; - -constructor WideException.CreateResFmtHelp(ResStringRec: PResStringRec; - const Args: array of const; AHelpContext: Integer); -begin - FMessage := WideFormat(WideLoadResString(ResStringRec), Args); - inherited Message := FMessage; - inherited HelpContext := AHelpContext; -end; - -procedure WideException.SetMessage(const Value: WideString); -begin - FMessage := Value; - inherited Message := FMessage; -end; - -//--------------------------------------------------------------------------------------------- -// Tnt - SysUtils -//--------------------------------------------------------------------------------------------- - -{$IFNDEF COMPILER_9_UP} - - function _Tnt_WideFormatBuf(var Buffer; BufLen: Cardinal; const FormatStr; - FmtLen: Cardinal; const Args: array of const - {$IFDEF COMPILER_7_UP}; const FormatSettings: PFormatSettings {$ENDIF}): Cardinal; - var - OldFormat: WideString; - NewFormat: WideString; - begin - SetString(OldFormat, PWideChar(@FormatStr), FmtLen); - { The reason for this is that WideFormat doesn't correctly format floating point specifiers. - See QC#4254. } - NewFormat := ReplaceFloatingArgumentsInFormatString(OldFormat, Args{$IFDEF COMPILER_7_UP}, FormatSettings{$ENDIF}); - {$IFDEF COMPILER_7_UP} - if FormatSettings <> nil then - Result := WideFormatBuf(Buffer, BufLen, Pointer(NewFormat)^, - Length(NewFormat), Args, FormatSettings^) - else - {$ENDIF} - Result := WideFormatBuf(Buffer, BufLen, Pointer(NewFormat)^, - Length(NewFormat), Args); - end; - - function Tnt_WideFormatBuf(var Buffer; BufLen: Cardinal; const FormatStr; - FmtLen: Cardinal; const Args: array of const): Cardinal; - begin - Result := _Tnt_WideFormatBuf(Buffer, BufLen, FormatStr, FmtLen, Args{$IFDEF COMPILER_7_UP}, nil{$ENDIF}); - end; - - {$IFDEF COMPILER_7_UP} - function Tnt_WideFormatBuf(var Buffer; BufLen: Cardinal; const FormatStr; - FmtLen: Cardinal; const Args: array of const; const FormatSettings: TFormatSettings): Cardinal; - begin - Result := _Tnt_WideFormatBuf(Buffer, BufLen, FormatStr, FmtLen, Args, @FormatSettings); - end; - {$ENDIF} - - procedure _Tnt_WideFmtStr(var Result: WideString; const FormatStr: WideString; - const Args: array of const{$IFDEF COMPILER_7_UP}; const FormatSettings: PFormatSettings{$ENDIF}); - var - Len, BufLen: Integer; - Buffer: array[0..4095] of WideChar; - begin - BufLen := Length(Buffer); // Fixes buffer overwrite issue. (See QC #4703, #4744) - if Length(FormatStr) < (Length(Buffer) - (Length(Buffer) div 4)) then - Len := _Tnt_WideFormatBuf(Buffer, Length(Buffer) - 1, Pointer(FormatStr)^, - Length(FormatStr), Args{$IFDEF COMPILER_7_UP}, FormatSettings{$ENDIF}) - else - begin - BufLen := Length(FormatStr); - Len := BufLen; - end; - if Len >= BufLen - 1 then - begin - while Len >= BufLen - 1 do - begin - Inc(BufLen, BufLen); - Result := ''; // prevent copying of existing data, for speed - SetLength(Result, BufLen); - Len := _Tnt_WideFormatBuf(Pointer(Result)^, BufLen - 1, Pointer(FormatStr)^, - Length(FormatStr), Args{$IFDEF COMPILER_7_UP}, FormatSettings{$ENDIF}); - end; - SetLength(Result, Len); - end - else - SetString(Result, Buffer, Len); - end; - - procedure Tnt_WideFmtStr(var Result: WideString; const FormatStr: WideString; - const Args: array of const); - begin - _Tnt_WideFmtStr(Result, FormatStr, Args{$IFDEF COMPILER_7_UP}, nil{$ENDIF}); - end; - - {$IFDEF COMPILER_7_UP} - procedure Tnt_WideFmtStr(var Result: WideString; const FormatStr: WideString; - const Args: array of const; const FormatSettings: TFormatSettings); - begin - _Tnt_WideFmtStr(Result, FormatStr, Args, @FormatSettings); - end; - {$ENDIF} - - {---------------------------------------------------------------------------------------- - Without the FormatSettings parameter, Tnt_WideFormat is *NOT* necessary... - TntSystem.InstallTntSystemUpdates([tsFixWideFormat]); - will fix WideFormat as well as WideFmtStr. - ----------------------------------------------------------------------------------------} - function Tnt_WideFormat(const FormatStr: WideString; const Args: array of const): WideString; - begin - Tnt_WideFmtStr(Result, FormatStr, Args); - end; - - {$IFDEF COMPILER_7_UP} - function Tnt_WideFormat(const FormatStr: WideString; const Args: array of const; - const FormatSettings: TFormatSettings): WideString; - begin - Tnt_WideFmtStr(Result, FormatStr, Args, FormatSettings); - end; - {$ENDIF} - -{$ENDIF} - -type - PWStrData = ^TWStrData; - TWStrData = record - Ident: Integer; - Str: WideString; - end; - -function EnumStringModules(Instance: Longint; Data: Pointer): Boolean; -var - ResStringRec: TResStringRec; -begin - with PWStrData(Data)^ do - begin - ResStringRec.Module^ := Instance; - ResStringRec.Identifier := Ident; - Str := WideLoadResString(@ResStringRec); - Result := Str = ''; - end; -end; - -function WideFindStringResource(Ident: Integer): WideString; -var - StrData: TWStrData; -begin - StrData.Ident := Ident; - StrData.Str := ''; - EnumResourceModules(EnumStringModules, @StrData); - Result := StrData.Str; -end; - -function WideLoadStr(Ident: Integer): WideString; -begin - Result := WideFindStringResource(Ident); -end; - -function WideFmtLoadStr(Ident: Integer; const Args: array of const): WideString; -begin - WideFmtStr(Result, WideFindStringResource(Ident), Args); -end; - -function Tnt_WideUpperCase(const S: WideString): WideString; -begin - {$IFNDEF COMPILER_10_UP} - { SysUtils.WideUpperCase is broken for Win9x. } - Result := S; - if Length(Result) > 0 then - Tnt_CharUpperBuffW(PWideChar(Result), Length(Result)); - {$ELSE} - Result := SysUtils.WideUpperCase{TNT-ALLOW WideUpperCase}(S); - {$ENDIF} -end; - -function Tnt_WideLowerCase(const S: WideString): WideString; -begin - {$IFNDEF COMPILER_10_UP} - { SysUtils.WideLowerCase is broken for Win9x. } - Result := S; - if Length(Result) > 0 then - Tnt_CharLowerBuffW(PWideChar(Result), Length(Result)); - {$ELSE} - Result := SysUtils.WideLowerCase{TNT-ALLOW WideLowerCase}(S); - {$ENDIF} -end; - -function TntWideLastChar(const S: WideString): WideChar; -var - P: PWideChar; -begin - P := WideLastChar(S); - if P = nil then - Result := #0 - else - Result := P^; -end; - -function Tnt_WideStringReplace(const S, OldPattern, NewPattern: WideString; - Flags: TReplaceFlags; WholeWord: Boolean = False): WideString; - - function IsWordSeparator(WC: WideChar): Boolean; - begin - Result := (WC = WideChar(#0)) - or IsWideCharSpace(WC) - or IsWideCharPunct(WC); - end; - -var - SearchStr, Patt, NewStr: WideString; - Offset: Integer; - PrevChar, NextChar: WideChar; -begin - if rfIgnoreCase in Flags then - begin - SearchStr := Tnt_WideUpperCase(S); - Patt := Tnt_WideUpperCase(OldPattern); - end else - begin - SearchStr := S; - Patt := OldPattern; - end; - NewStr := S; - Result := ''; - while SearchStr <> '' do - begin - Offset := Pos(Patt, SearchStr); - if Offset = 0 then - begin - Result := Result + NewStr; - Break; - end; // done - - if (WholeWord) then - begin - if (Offset = 1) then - PrevChar := TntWideLastChar(Result) - else - PrevChar := NewStr[Offset - 1]; - - if Offset + Length(OldPattern) <= Length(NewStr) then - NextChar := NewStr[Offset + Length(OldPattern)] - else - NextChar := WideChar(#0); - - if (not IsWordSeparator(PrevChar)) - or (not IsWordSeparator(NextChar)) then - begin - Result := Result + Copy(NewStr, 1, Offset + Length(OldPattern) - 1); - NewStr := Copy(NewStr, Offset + Length(OldPattern), MaxInt); - SearchStr := Copy(SearchStr, Offset + Length(Patt), MaxInt); - continue; - end; - end; - - Result := Result + Copy(NewStr, 1, Offset - 1) + NewPattern; - NewStr := Copy(NewStr, Offset + Length(OldPattern), MaxInt); - if not (rfReplaceAll in Flags) then - begin - Result := Result + NewStr; - Break; - end; - SearchStr := Copy(SearchStr, Offset + Length(Patt), MaxInt); - end; -end; - -function TntAdjustLineBreaksLength(const S: WideString; Style: TTntTextLineBreakStyle = tlbsCRLF): Integer; -var - Source, SourceEnd: PWideChar; -begin - Source := Pointer(S); - SourceEnd := Source + Length(S); - Result := Length(S); - while Source < SourceEnd do - begin - case Source^ of - #10, WideLineSeparator: - if Style = tlbsCRLF then - Inc(Result); - #13: - if Style = tlbsCRLF then - if Source[1] = #10 then - Inc(Source) - else - Inc(Result) - else - if Source[1] = #10 then - Dec(Result); - end; - Inc(Source); - end; -end; - -function TntAdjustLineBreaks(const S: WideString; Style: TTntTextLineBreakStyle = tlbsCRLF): WideString; -var - Source, SourceEnd, Dest: PWideChar; - DestLen: Integer; -begin - Source := Pointer(S); - SourceEnd := Source + Length(S); - DestLen := TntAdjustLineBreaksLength(S, Style); - SetString(Result, nil, DestLen); - Dest := Pointer(Result); - while Source < SourceEnd do begin - case Source^ of - #10, WideLineSeparator: - begin - if Style in [tlbsCRLF, tlbsCR] then - begin - Dest^ := #13; - Inc(Dest); - end; - if Style in [tlbsCRLF, tlbsLF] then - begin - Dest^ := #10; - Inc(Dest); - end; - Inc(Source); - end; - #13: - begin - if Style in [tlbsCRLF, tlbsCR] then - begin - Dest^ := #13; - Inc(Dest); - end; - if Style in [tlbsCRLF, tlbsLF] then - begin - Dest^ := #10; - Inc(Dest); - end; - Inc(Source); - if Source^ = #10 then Inc(Source); - end; - else - Dest^ := Source^; - Inc(Dest); - Inc(Source); - end; - end; -end; - -function WideWrapText(const Line, BreakStr: WideString; const BreakChars: TSysCharSet; - MaxCol: Integer): WideString; - - function WideCharIn(C: WideChar; SysCharSet: TSysCharSet): Boolean; - begin - Result := (C <= High(AnsiChar)) and (AnsiChar(C) in SysCharSet); - end; - -const - QuoteChars = ['''', '"']; -var - Col, Pos: Integer; - LinePos, LineLen: Integer; - BreakLen, BreakPos: Integer; - QuoteChar, CurChar: WideChar; - ExistingBreak: Boolean; -begin - Col := 1; - Pos := 1; - LinePos := 1; - BreakPos := 0; - QuoteChar := ' '; - ExistingBreak := False; - LineLen := Length(Line); - BreakLen := Length(BreakStr); - Result := ''; - while Pos <= LineLen do - begin - CurChar := Line[Pos]; - if CurChar = BreakStr[1] then - begin - if QuoteChar = ' ' then - begin - ExistingBreak := WideSameText(BreakStr, Copy(Line, Pos, BreakLen)); - if ExistingBreak then - begin - Inc(Pos, BreakLen-1); - BreakPos := Pos; - end; - end - end - else if WideCharIn(CurChar, BreakChars) then - begin - if QuoteChar = ' ' then BreakPos := Pos - end - else if WideCharIn(CurChar, QuoteChars) then - begin - if CurChar = QuoteChar then - QuoteChar := ' ' - else if QuoteChar = ' ' then - QuoteChar := CurChar; - end; - Inc(Pos); - Inc(Col); - if not (WideCharIn(QuoteChar, QuoteChars)) and (ExistingBreak or - ((Col > MaxCol) and (BreakPos > LinePos))) then - begin - Col := Pos - BreakPos; - Result := Result + Copy(Line, LinePos, BreakPos - LinePos + 1); - if not (WideCharIn(CurChar, QuoteChars)) then - while Pos <= LineLen do - begin - if WideCharIn(Line[Pos], BreakChars) then - Inc(Pos) - else if Copy(Line, Pos, Length(sLineBreak)) = sLineBreak then - Inc(Pos, Length(sLineBreak)) - else - break; - end; - if not ExistingBreak and (Pos < LineLen) then - Result := Result + BreakStr; - Inc(BreakPos); - LinePos := BreakPos; - ExistingBreak := False; - end; - end; - Result := Result + Copy(Line, LinePos, MaxInt); -end; - -function WideWrapText(const Line: WideString; MaxCol: Integer): WideString; -begin - Result := WideWrapText(Line, sLineBreak, [' ', '-', #9], MaxCol); { do not localize } -end; - -function WideIncludeTrailingBackslash(const S: WideString): WideString; -begin - Result := WideIncludeTrailingPathDelimiter(S); -end; - -function WideIncludeTrailingPathDelimiter(const S: WideString): WideString; -begin - Result := S; - if not WideIsPathDelimiter(Result, Length(Result)) then Result := Result + PathDelim; -end; - -function WideExcludeTrailingBackslash(const S: WideString): WideString; -begin - Result := WideExcludeTrailingPathDelimiter(S); -end; - -function WideExcludeTrailingPathDelimiter(const S: WideString): WideString; -begin - Result := S; - if WideIsPathDelimiter(Result, Length(Result)) then - SetLength(Result, Length(Result)-1); -end; - -function WideIsDelimiter(const Delimiters, S: WideString; Index: Integer): Boolean; -begin - Result := False; - if (Index <= 0) or (Index > Length(S)) then exit; - Result := WStrScan(PWideChar(Delimiters), S[Index]) <> nil; -end; - -function WideIsPathDelimiter(const S: WideString; Index: Integer): Boolean; -begin - Result := (Index > 0) and (Index <= Length(S)) and (S[Index] = PathDelim); -end; - -function WideLastDelimiter(const Delimiters, S: WideString): Integer; -var - P: PWideChar; -begin - Result := Length(S); - P := PWideChar(Delimiters); - while Result > 0 do - begin - if (S[Result] <> #0) and (WStrScan(P, S[Result]) <> nil) then - Exit; - Dec(Result); - end; -end; - -function WideChangeFileExt(const FileName, Extension: WideString): WideString; -var - I: Integer; -begin - I := WideLastDelimiter('.\:',Filename); - if (I = 0) or (FileName[I] <> '.') then I := MaxInt; - Result := Copy(FileName, 1, I - 1) + Extension; -end; - -function WideExtractFilePath(const FileName: WideString): WideString; -var - I: Integer; -begin - I := WideLastDelimiter('\:', FileName); - Result := Copy(FileName, 1, I); -end; - -function WideExtractFileDir(const FileName: WideString): WideString; -var - I: Integer; -begin - I := WideLastDelimiter(DriveDelim + PathDelim,Filename); - if (I > 1) and (FileName[I] = PathDelim) and - (not (FileName[I - 1] in [WideChar(PathDelim), WideChar(DriveDelim)])) then Dec(I); - Result := Copy(FileName, 1, I); -end; - -function WideExtractFileDrive(const FileName: WideString): WideString; -var - I, J: Integer; -begin - if (Length(FileName) >= 2) and (FileName[2] = DriveDelim) then - Result := Copy(FileName, 1, 2) - else if (Length(FileName) >= 2) and (FileName[1] = PathDelim) and - (FileName[2] = PathDelim) then - begin - J := 0; - I := 3; - While (I < Length(FileName)) and (J < 2) do - begin - if FileName[I] = PathDelim then Inc(J); - if J < 2 then Inc(I); - end; - if FileName[I] = PathDelim then Dec(I); - Result := Copy(FileName, 1, I); - end else Result := ''; -end; - -function WideExtractFileName(const FileName: WideString): WideString; -var - I: Integer; -begin - I := WideLastDelimiter('\:', FileName); - Result := Copy(FileName, I + 1, MaxInt); -end; - -function WideExtractFileExt(const FileName: WideString): WideString; -var - I: Integer; -begin - I := WideLastDelimiter('.\:', FileName); - if (I > 0) and (FileName[I] = '.') then - Result := Copy(FileName, I, MaxInt) else - Result := ''; -end; - -function WideExtractRelativePath(const BaseName, DestName: WideString): WideString; -var - BasePath, DestPath: WideString; - BaseLead, DestLead: PWideChar; - BasePtr, DestPtr: PWideChar; - - function WideExtractFilePathNoDrive(const FileName: WideString): WideString; - begin - Result := WideExtractFilePath(FileName); - Delete(Result, 1, Length(WideExtractFileDrive(FileName))); - end; - - function Next(var Lead: PWideChar): PWideChar; - begin - Result := Lead; - if Result = nil then Exit; - Lead := WStrScan(Lead, PathDelim); - if Lead <> nil then - begin - Lead^ := #0; - Inc(Lead); - end; - end; - -begin - if WideSameText(WideExtractFileDrive(BaseName), WideExtractFileDrive(DestName)) then - begin - BasePath := WideExtractFilePathNoDrive(BaseName); - DestPath := WideExtractFilePathNoDrive(DestName); - BaseLead := Pointer(BasePath); - BasePtr := Next(BaseLead); - DestLead := Pointer(DestPath); - DestPtr := Next(DestLead); - while (BasePtr <> nil) and (DestPtr <> nil) and WideSameText(BasePtr, DestPtr) do - begin - BasePtr := Next(BaseLead); - DestPtr := Next(DestLead); - end; - Result := ''; - while BaseLead <> nil do - begin - Result := Result + '..' + PathDelim; { Do not localize } - Next(BaseLead); - end; - if (DestPtr <> nil) and (DestPtr^ <> #0) then - Result := Result + DestPtr + PathDelim; - if DestLead <> nil then - Result := Result + DestLead; // destlead already has a trailing backslash - Result := Result + WideExtractFileName(DestName); - end - else - Result := DestName; -end; - -function WideExpandFileName(const FileName: WideString): WideString; -var - FName: PWideChar; - Buffer: array[0..MAX_PATH - 1] of WideChar; -begin - SetString(Result, Buffer, Tnt_GetFullPathNameW(PWideChar(FileName), MAX_PATH, Buffer, FName)); -end; - -function WideExtractShortPathName(const FileName: WideString): WideString; -var - Buffer: array[0..MAX_PATH - 1] of WideChar; -begin - SetString(Result, Buffer, Tnt_GetShortPathNameW(PWideChar(FileName), Buffer, MAX_PATH)); -end; - -function WideFileCreate(const FileName: WideString): Integer; -begin - Result := Integer(Tnt_CreateFileW(PWideChar(FileName), GENERIC_READ or GENERIC_WRITE, - 0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)) -end; - -function WideFileOpen(const FileName: WideString; Mode: LongWord): Integer; -const - AccessMode: array[0..2] of LongWord = ( - GENERIC_READ, - GENERIC_WRITE, - GENERIC_READ or GENERIC_WRITE); - ShareMode: array[0..4] of LongWord = ( - 0, - 0, - FILE_SHARE_READ, - FILE_SHARE_WRITE, - FILE_SHARE_READ or FILE_SHARE_WRITE); -begin - Result := Integer(Tnt_CreateFileW(PWideChar(FileName), AccessMode[Mode and 3], - ShareMode[(Mode and $F0) shr 4], nil, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, 0)); -end; - -function WideFileAge(const FileName: WideString): Integer; -var - Handle: THandle; - FindData: TWin32FindDataW; - LocalFileTime: TFileTime; -begin - Handle := Tnt_FindFirstFileW(PWideChar(FileName), FindData); - if Handle <> INVALID_HANDLE_VALUE then - begin - Windows.FindClose(Handle); - if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then - begin - FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime); - if FileTimeToDosDateTime(LocalFileTime, LongRec(Result).Hi, LongRec(Result).Lo) then - Exit - end; - end; - Result := -1; -end; - -function WideFileAge(const FileName: WideString; out FileDateTime: TDateTime): Boolean; -var - Handle: THandle; - FindData: TWin32FindDataW; - LSystemTime: TSystemTime; - LocalFileTime: TFileTime; -begin - Result := False; - Handle := Tnt_FindFirstFileW(PWideChar(FileName), FindData); - if Handle <> INVALID_HANDLE_VALUE then - begin - Windows.FindClose(Handle); - if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then - begin - Result := True; - FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime); - FileTimeToSystemTime(LocalFileTime, LSystemTime); - with LSystemTime do - FileDateTime := EncodeDate(wYear, wMonth, wDay) + - EncodeTime(wHour, wMinute, wSecond, wMilliSeconds); - end; - end; -end; - -function WideDirectoryExists(const Name: WideString): Boolean; -var - Code: Cardinal; -begin - Code := WideFileGetAttr(Name); - Result := (Code <> INVALID_FILE_ATTRIBUTES) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0); -end; - -function WideFileExists(const Name: WideString): Boolean; -var - Handle: THandle; - FindData: TWin32FindDataW; -begin - Result := False; - Handle := Tnt_FindFirstFileW(PWideChar(Name), FindData); - if Handle <> INVALID_HANDLE_VALUE then - begin - Windows.FindClose(Handle); - if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then - Result := True; - end; -end; - -function WideFileGetAttr(const FileName: WideString): Cardinal; -begin - Result := Tnt_GetFileAttributesW(PWideChar(FileName)); -end; - -function WideFileSetAttr(const FileName: WideString; Attr: Integer): Boolean; -begin - Result := Tnt_SetFileAttributesW(PWideChar(FileName), Attr) -end; - -function WideFileIsReadOnly(const FileName: WideString): Boolean; -begin - Result := (Tnt_GetFileAttributesW(PWideChar(FileName)) and faReadOnly) <> 0; -end; - -function WideFileSetReadOnly(const FileName: WideString; ReadOnly: Boolean): Boolean; -var - Flags: Integer; -begin - Result := False; - Flags := Tnt_GetFileAttributesW(PWideChar(FileName)); - if Flags = -1 then Exit; - if ReadOnly then - Flags := Flags or faReadOnly - else - Flags := Flags and not faReadOnly; - Result := Tnt_SetFileAttributesW(PWideChar(FileName), Flags); -end; - -function WideForceDirectories(Dir: WideString): Boolean; -begin - Result := True; - if Length(Dir) = 0 then - raise ETntGeneralError.Create(SCannotCreateDir); - Dir := WideExcludeTrailingBackslash(Dir); - if (Length(Dir) < 3) or WideDirectoryExists(Dir) - or (WideExtractFilePath(Dir) = Dir) then Exit; // avoid 'xyz:\' problem. - Result := WideForceDirectories(WideExtractFilePath(Dir)); - if Result then - Result := Tnt_CreateDirectoryW(PWideChar(Dir), nil) -end; - -function WideFileSearch(const Name, DirList: WideString): WideString; -var - I, P, L: Integer; - C: WideChar; -begin - Result := Name; - P := 1; - L := Length(DirList); - while True do - begin - if WideFileExists(Result) then Exit; - while (P <= L) and (DirList[P] = PathSep) do Inc(P); - if P > L then Break; - I := P; - while (P <= L) and (DirList[P] <> PathSep) do - Inc(P); - Result := Copy(DirList, I, P - I); - C := TntWideLastChar(Result); - if (C <> DriveDelim) and (C <> PathDelim) then - Result := Result + PathDelim; - Result := Result + Name; - end; - Result := ''; -end; - -function WideRenameFile(const OldName, NewName: WideString): Boolean; -begin - Result := Tnt_MoveFileW(PWideChar(OldName), PWideChar(NewName)) -end; - -function WideDeleteFile(const FileName: WideString): Boolean; -begin - Result := Tnt_DeleteFileW(PWideChar(FileName)) -end; - -function WideCopyFile(FromFile, ToFile: WideString; FailIfExists: Boolean): Boolean; -begin - Result := Tnt_CopyFileW(PWideChar(FromFile), PWideChar(ToFile), FailIfExists) -end; - -function _WideFindMatchingFile(var F: TSearchRecW): Integer; -var - LocalFileTime: TFileTime; -begin - with F do - begin - while FindData.dwFileAttributes and ExcludeAttr <> 0 do - if not Tnt_FindNextFileW(FindHandle, FindData) then - begin - Result := GetLastError; - Exit; - end; - FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime); - FileTimeToDosDateTime(LocalFileTime, LongRec(Time).Hi, LongRec(Time).Lo); - Size := (Int64(FindData.nFileSizeHigh) shl 32) + FindData.nFileSizeLow; - Attr := FindData.dwFileAttributes; - Name := FindData.cFileName; - end; - Result := 0; -end; - -function WideFindFirst(const Path: WideString; Attr: Integer; var F: TSearchRecW): Integer; -const - faSpecial = faHidden or faSysFile {$IFNDEF COMPILER_9_UP} or faVolumeID {$ENDIF} or faDirectory; -begin - F.ExcludeAttr := not Attr and faSpecial; - F.FindHandle := Tnt_FindFirstFileW(PWideChar(Path), F.FindData); - if F.FindHandle <> INVALID_HANDLE_VALUE then - begin - Result := _WideFindMatchingFile(F); - if Result <> 0 then WideFindClose(F); - end else - Result := GetLastError; -end; - -function WideFindNext(var F: TSearchRecW): Integer; -begin - if Tnt_FindNextFileW(F.FindHandle, F.FindData) then - Result := _WideFindMatchingFile(F) else - Result := GetLastError; -end; - -procedure WideFindClose(var F: TSearchRecW); -begin - if F.FindHandle <> INVALID_HANDLE_VALUE then - begin - Windows.FindClose(F.FindHandle); - F.FindHandle := INVALID_HANDLE_VALUE; - end; -end; - -function WideCreateDir(const Dir: WideString): Boolean; -begin - Result := Tnt_CreateDirectoryW(PWideChar(Dir), nil); -end; - -function WideRemoveDir(const Dir: WideString): Boolean; -begin - Result := Tnt_RemoveDirectoryW(PWideChar(Dir)); -end; - -function WideGetCurrentDir: WideString; -begin - SetLength(Result, MAX_PATH); - Tnt_GetCurrentDirectoryW(MAX_PATH, PWideChar(Result)); - Result := PWideChar(Result); -end; - -function WideSetCurrentDir(const Dir: WideString): Boolean; -begin - Result := Tnt_SetCurrentDirectoryW(PWideChar(Dir)); -end; - -//============================================================================================= -//== DATE/TIME STRING PARSING ================================================================ -//============================================================================================= - -function _IntTryStrToDateTime(Str: WideString; Flags: Integer; out DateTime: TDateTime): HResult; -begin - Result := VarDateFromStr(Str, GetThreadLocale, Flags, Double(DateTime)); - if (not Succeeded(Result)) then begin - if (Flags = VAR_TIMEVALUEONLY) - and SysUtils.TryStrToTime{TNT-ALLOW TryStrToTime}(Str, DateTime) then - Result := S_OK // SysUtils seems confident (works for date = "dd.MM.yy" and time = "H.mm.ss") - else if (Flags = VAR_DATEVALUEONLY) - and SysUtils.TryStrToDate{TNT-ALLOW TryStrToDate}(Str, DateTime) then - Result := S_OK // SysUtils seems confident - else if (Flags = 0) - and SysUtils.TryStrToDateTime{TNT-ALLOW TryStrToDateTime}(Str, DateTime) then - Result := S_OK // SysUtils seems confident - end; -end; - -function TntTryStrToDateTime(Str: WideString; out DateTime: TDateTime): Boolean; -begin - Result := Succeeded(_IntTryStrToDateTime(Str, 0, DateTime)); -end; - -function TntTryStrToDate(Str: WideString; out DateTime: TDateTime): Boolean; -begin - Result := Succeeded(_IntTryStrToDateTime(Str, VAR_DATEVALUEONLY, DateTime)); -end; - -function TntTryStrToTime(Str: WideString; out DateTime: TDateTime): Boolean; -begin - Result := Succeeded(_IntTryStrToDateTime(Str, VAR_TIMEVALUEONLY, DateTime)); -end; - -function ValidDateTimeStr(Str: WideString): Boolean; -var - Temp: TDateTime; -begin - Result := Succeeded(_IntTryStrToDateTime(Str, 0, Temp)); -end; - -function ValidDateStr(Str: WideString): Boolean; -var - Temp: TDateTime; -begin - Result := Succeeded(_IntTryStrToDateTime(Str, VAR_DATEVALUEONLY, Temp)); -end; - -function ValidTimeStr(Str: WideString): Boolean; -var - Temp: TDateTime; -begin - Result := Succeeded(_IntTryStrToDateTime(Str, VAR_TIMEVALUEONLY, Temp)); -end; - -function TntStrToDateTimeDef(Str: WideString; Default: TDateTime): TDateTime; -begin - if not TntTryStrToDateTime(Str, Result) then - Result := Default; -end; - -function TntStrToDateDef(Str: WideString; Default: TDateTime): TDateTime; -begin - if not TntTryStrToDate(Str, Result) then - Result := Default; -end; - -function TntStrToTimeDef(Str: WideString; Default: TDateTime): TDateTime; -begin - if not TntTryStrToTime(Str, Result) then - Result := Default; -end; - -function _IntStrToDateTime(Str: WideString; Flags: Integer; ErrorFormatStr: WideString): TDateTime; -begin - try - OleCheck(_IntTryStrToDateTime(Str, Flags, Result)); - except - on E: Exception do begin - E.Message := E.Message + CRLF + WideFormat(ErrorFormatStr, [Str]); - raise EConvertError.Create(E.Message); - end; - end; -end; - -function TntStrToDateTime(Str: WideString): TDateTime; -begin - Result := _IntStrToDateTime(Str, 0, SInvalidDateTime); -end; - -function TntStrToDate(Str: WideString): TDateTime; -begin - Result := _IntStrToDateTime(Str, VAR_DATEVALUEONLY, SInvalidDate); -end; - -function TntStrToTime(Str: WideString): TDateTime; -begin - Result := _IntStrToDateTime(Str, VAR_TIMEVALUEONLY, SInvalidTime); -end; - -//============================================================================================= -//== CURRENCY STRING PARSING ================================================================= -//============================================================================================= - -function TntCurrToStr(Value: Currency; lpFormat: PCurrencyFmtW = nil): WideString; -const - MAX_BUFF_SIZE = 64; // can a currency string actually be larger? -var - ValueStr: WideString; -begin - // format lpValue using ENG-US settings - ValueStr := ENG_US_FloatToStr(Value); - // get currency format - SetLength(Result, MAX_BUFF_SIZE); - if 0 = Tnt_GetCurrencyFormatW(GetThreadLocale, 0, PWideChar(ValueStr), - lpFormat, PWideChar(Result), Length(Result)) - then begin - RaiseLastOSError; - end; - Result := PWideChar(Result); -end; - -function TntStrToCurr(const S: WideString): Currency; -begin - try - OleCheck(VarCyFromStr(S, GetThreadLocale, 0, Result)); - except - on E: Exception do begin - E.Message := E.Message + CRLF + WideFormat(SInvalidCurrency, [S]); - raise EConvertError.Create(E.Message); - end; - end; -end; - -function ValidCurrencyStr(const S: WideString): Boolean; -var - Dummy: Currency; -begin - Result := Succeeded(VarCyFromStr(S, GetThreadLocale, 0, Dummy)); -end; - -function TntStrToCurrDef(const S: WideString; const Default: Currency): Currency; -begin - if not Succeeded(VarCyFromStr(S, GetThreadLocale, 0, Result)) then - Result := Default; -end; - -threadvar - Currency_DecimalSep: WideString; - Currency_ThousandSep: WideString; - Currency_CurrencySymbol: WideString; - -function GetDefaultCurrencyFmt: TCurrencyFmtW; -begin - ZeroMemory(@Result, SizeOf(Result)); - Result.NumDigits := StrToIntDef(WideGetLocaleStr(GetThreadLocale, LOCALE_ICURRDIGITS, '2'), 2); - Result.LeadingZero := StrToIntDef(WideGetLocaleStr(GetThreadLocale, LOCALE_ILZERO, '1'), 1); - Result.Grouping := StrToIntDef(Copy(WideGetLocaleStr(GetThreadLocale, LOCALE_SMONGROUPING, '3;0'), 1, 1), 3); - Currency_DecimalSep := WideGetLocaleStr(GetThreadLocale, LOCALE_SMONDECIMALSEP, '.'); - Result.lpDecimalSep := PWideChar(Currency_DecimalSep); - Currency_ThousandSep := WideGetLocaleStr(GetThreadLocale, LOCALE_SMONTHOUSANDSEP, ','); - Result.lpThousandSep := PWideChar(Currency_ThousandSep); - Result.NegativeOrder := StrToIntDef(WideGetLocaleStr(GetThreadLocale, LOCALE_INEGCURR, '0'), 0); - Result.PositiveOrder := StrToIntDef(WideGetLocaleStr(GetThreadLocale, LOCALE_ICURRENCY, '0'), 0); - Currency_CurrencySymbol := WideGetLocaleStr(GetThreadLocale, LOCALE_SCURRENCY, ''); - Result.lpCurrencySymbol := PWideChar(Currency_CurrencySymbol); -end; - -//============================================================================================= - -function WideGetLocaleStr(LocaleID: LCID; LocaleType: Integer; const Default: WideString): WideString; -var - L: Integer; -begin - if (not Win32PlatformIsUnicode) then - Result := GetLocaleStr{TNT-ALLOW GetLocaleStr}(LocaleID, LocaleType, Default) - else begin - SetLength(Result, 255); - L := GetLocaleInfoW(LocaleID, LocaleType, PWideChar(Result), Length(Result)); - if L > 0 then - SetLength(Result, L - 1) - else - Result := Default; - end; -end; - -function WideSysErrorMessage(ErrorCode: Integer): WideString; -begin - Result := WideLibraryErrorMessage('system', 0, ErrorCode); -end; - -procedure WideRaiseLastOSError; -var - LastError: Integer; - Error: EWideOSError; -begin - LastError := GetLastError; - if LastError <> 0 then - Error := EWideOSError.Create(WideSysErrorMessage(LastError)) - else - Error := EWideOSError.CreateRes(PResStringRec(@SUnkOSError)); - Error.ErrorCode := LastError; - raise Error; -end; - -function WideLibraryErrorMessage(const LibName: WideString; Dll: THandle; ErrorCode: Integer): WideString; -var - Len: Integer; - AnsiResult: AnsiString; - Flags: Cardinal; -begin - Flags := FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS or FORMAT_MESSAGE_ARGUMENT_ARRAY; - if Dll <> 0 then - Flags := Flags or FORMAT_MESSAGE_FROM_HMODULE; - if Win32PlatformIsUnicode then begin - SetLength(Result, 256); - Len := FormatMessageW(Flags, Pointer(Dll), ErrorCode, 0, PWideChar(Result), Length(Result), nil); - SetLength(Result, Len); - end else begin - SetLength(AnsiResult, 256); - Len := FormatMessageA(Flags, Pointer(Dll), ErrorCode, 0, PAnsiChar(AnsiResult), Length(AnsiResult), nil); - SetLength(AnsiResult, Len); - Result := AnsiResult; - end; - if Trim(Result) = '' then - Result := WideFormat('Unspecified error (%d) from %s.', [ErrorCode, LibName]); -end; - -{$IFNDEF COMPILER_7_UP} -function CheckWin32Version(AMajor: Integer; AMinor: Integer = 0): Boolean; -begin - Result := (Win32MajorVersion > AMajor) or - ((Win32MajorVersion = AMajor) and - (Win32MinorVersion >= AMinor)); -end; -{$ENDIF} - -function WinCheckH(RetVal: Cardinal): Cardinal; -begin - if RetVal = 0 then RaiseLastOSError; - Result := RetVal; -end; - -function WinCheckFileH(RetVal: Cardinal): Cardinal; -begin - if RetVal = INVALID_HANDLE_VALUE then RaiseLastOSError; - Result := RetVal; -end; - -function WinCheckP(RetVal: Pointer): Pointer; -begin - if RetVal = nil then RaiseLastOSError; - Result := RetVal; -end; - -function WideGetModuleFileName(Instance: HModule): WideString; -begin - SetLength(Result, MAX_PATH); - WinCheckH(Tnt_GetModuleFileNameW(Instance, PWideChar(Result), Length(Result))); - Result := PWideChar(Result) -end; - -function WideSafeLoadLibrary(const Filename: Widestring; ErrorMode: UINT): HMODULE; -var - OldMode: UINT; - FPUControlWord: Word; -begin - OldMode := SetErrorMode(ErrorMode); - try - asm - FNSTCW FPUControlWord - end; - try - Result := Tnt_LoadLibraryW(PWideChar(Filename)); - finally - asm - FNCLEX - FLDCW FPUControlWord - end; - end; - finally - SetErrorMode(OldMode); - end; -end; - -function WideLoadPackage(const Name: Widestring): HMODULE; -begin - Result := WideSafeLoadLibrary(Name); - if Result = 0 then - begin - raise EPackageError.CreateFmt(sErrorLoadingPackage, [Name, WideSysErrorMessage(GetLastError)]); - end; - try - InitializePackage(Result); - except - FreeLibrary(Result); - raise; - end; -end; - -function _WideCharType(WC: WideChar; dwInfoType: Cardinal): Word; -begin - Win32Check(Tnt_GetStringTypeExW(GetThreadLocale, dwInfoType, PWideChar(@WC), 1, Result)) -end; - -function IsWideCharUpper(WC: WideChar): Boolean; -begin - Result := (_WideCharType(WC, CT_CTYPE1) and C1_UPPER) <> 0; -end; - -function IsWideCharLower(WC: WideChar): Boolean; -begin - Result := (_WideCharType(WC, CT_CTYPE1) and C1_LOWER) <> 0; -end; - -function IsWideCharDigit(WC: WideChar): Boolean; -begin - Result := (_WideCharType(WC, CT_CTYPE1) and C1_DIGIT) <> 0; -end; - -function IsWideCharSpace(WC: WideChar): Boolean; -begin - Result := (_WideCharType(WC, CT_CTYPE1) and C1_SPACE) <> 0; -end; - -function IsWideCharPunct(WC: WideChar): Boolean; -begin - Result := (_WideCharType(WC, CT_CTYPE1) and C1_PUNCT) <> 0; -end; - -function IsWideCharCntrl(WC: WideChar): Boolean; -begin - Result := (_WideCharType(WC, CT_CTYPE1) and C1_CNTRL) <> 0; -end; - -function IsWideCharBlank(WC: WideChar): Boolean; -begin - Result := (_WideCharType(WC, CT_CTYPE1) and C1_BLANK) <> 0; -end; - -function IsWideCharXDigit(WC: WideChar): Boolean; -begin - Result := (_WideCharType(WC, CT_CTYPE1) and C1_XDIGIT) <> 0; -end; - -function IsWideCharAlpha(WC: WideChar): Boolean; -begin - Result := (_WideCharType(WC, CT_CTYPE1) and C1_ALPHA) <> 0; -end; - -function IsWideCharAlphaNumeric(WC: WideChar): Boolean; -begin - Result := (_WideCharType(WC, CT_CTYPE1) and (C1_ALPHA + C1_DIGIT)) <> 0; -end; - -function WideTextPos(const SubStr, S: WideString): Integer; -begin - Result := Pos(Tnt_WideUpperCase(SubStr), Tnt_WideUpperCase(S)); -end; - -function FindDoubleTerminator(P: PWideChar): PWideChar; -begin - Result := P; - while True do begin - Result := WStrScan(Result, #0); - Inc(Result); - if Result^ = #0 then begin - Dec(Result); - break; - end; - end; -end; - -function ExtractStringArrayStr(P: PWideChar): WideString; -var - PEnd: PWideChar; -begin - PEnd := FindDoubleTerminator(P); - Inc(PEnd, 2); // move past #0#0 - SetString(Result, P, PEnd - P); -end; - -function ExtractStringFromStringArray(var P: PWideChar; Separator: WideChar = #0): WideString; -var - Start: PWideChar; -begin - Start := P; - P := WStrScan(Start, Separator); - if P = nil then begin - Result := Start; - P := WStrEnd(Start); - end else begin - SetString(Result, Start, P - Start); - Inc(P); - end; -end; - -function ExtractStringsFromStringArray(P: PWideChar; Separator: WideChar = #0): TWideStringDynArray; -const - GROW_COUNT = 256; -var - Count: Integer; - Item: WideString; -begin - Count := 0; - SetLength(Result, GROW_COUNT); - Item := ExtractStringFromStringArray(P, Separator); - While Item <> '' do begin - if Count > High(Result) then - SetLength(Result, Length(Result) + GROW_COUNT); - Result[Count] := Item; - Inc(Count); - Item := ExtractStringFromStringArray(P, Separator); - end; - SetLength(Result, Count); -end; - -function IsWideCharMappableToAnsi(const WC: WideChar): Boolean; -var - UsedDefaultChar: BOOL; -begin - WideCharToMultiByte(DefaultSystemCodePage, 0, PWideChar(@WC), 1, nil, 0, nil, @UsedDefaultChar); - Result := not UsedDefaultChar; -end; - -function IsWideStringMappableToAnsi(const WS: WideString): Boolean; -var - UsedDefaultChar: BOOL; -begin - WideCharToMultiByte(DefaultSystemCodePage, 0, PWideChar(WS), Length(WS), nil, 0, nil, @UsedDefaultChar); - Result := not UsedDefaultChar; -end; - -function IsRTF(const Value: WideString): Boolean; -const - RTF_BEGIN_1 = WideString('{\RTF'); - RTF_BEGIN_2 = WideString('{URTF'); -begin - Result := (WideTextPos(RTF_BEGIN_1, Value) = 1) - or (WideTextPos(RTF_BEGIN_2, Value) = 1); -end; - -{$IFDEF COMPILER_7_UP} -var - Cached_ENG_US_FormatSettings: TFormatSettings; - Cached_ENG_US_FormatSettings_Time: Cardinal; - -function ENG_US_FormatSettings: TFormatSettings; -begin - if Cached_ENG_US_FormatSettings_Time = _SettingChangeTime then - Result := Cached_ENG_US_FormatSettings - else begin - GetLocaleFormatSettings(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)), Result); - Result.DecimalSeparator := '.'; // ignore overrides - Cached_ENG_US_FormatSettings := Result; - Cached_ENG_US_FormatSettings_Time := _SettingChangeTime; - end; - end; - -function ENG_US_FloatToStr(Value: Extended): WideString; -begin - Result := FloatToStr(Value, ENG_US_FormatSettings); -end; - -function ENG_US_StrToFloat(const S: WideString): Extended; -begin - if not TextToFloat(PAnsiChar(AnsiString(S)), Result, fvExtended, ENG_US_FormatSettings) then - Result := StrToFloat(S); // try using native format -end; - -{$ELSE} - -function ENG_US_FloatToStr(Value: Extended): WideString; -var - SaveDecimalSep: AnsiChar; -begin - SaveDecimalSep := SysUtils.DecimalSeparator; - try - SysUtils.DecimalSeparator := '.'; - Result := FloatToStr(Value); - finally - SysUtils.DecimalSeparator := SaveDecimalSep; - end; -end; - -function ENG_US_StrToFloat(const S: WideString): Extended; -var - SaveDecimalSep: AnsiChar; -begin - try - SaveDecimalSep := SysUtils.DecimalSeparator; - try - SysUtils.DecimalSeparator := '.'; - Result := StrToFloat(S); - finally - SysUtils.DecimalSeparator := SaveDecimalSep; - end; - except - if SysUtils.DecimalSeparator <> '.' then - Result := StrToFloat(S) // try using native format - else - raise; - end; -end; -{$ENDIF} - -//--------------------------------------------------------------------------------------------- -// Tnt - Variants -//--------------------------------------------------------------------------------------------- - -initialization - Win32PlatformIsUnicode := (Win32Platform = VER_PLATFORM_WIN32_NT); - Win32PlatformIsXP := ((Win32MajorVersion = 5) and (Win32MinorVersion >= 1)) - or (Win32MajorVersion > 5); - Win32PlatformIs2003 := ((Win32MajorVersion = 5) and (Win32MinorVersion >= 2)) - or (Win32MajorVersion > 5); - Win32PlatformIsVista := (Win32MajorVersion >= 6); - -finalization - Currency_DecimalSep := ''; {make memory sleuth happy} - Currency_ThousandSep := ''; {make memory sleuth happy} - Currency_CurrencySymbol := ''; {make memory sleuth happy} - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntSystem.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntSystem.pas deleted file mode 100644 index 823becce0..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntSystem.pas +++ /dev/null @@ -1,1397 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntSystem; - -{$INCLUDE TntCompilers.inc} - -{*****************************************************************************} -{ Special thanks go to Francisco Leong for originating the design for } -{ WideString-enabled resourcestrings. } -{*****************************************************************************} - -interface - -uses - Windows; - -// These functions should not be used by Delphi code since conversions are implicit. -{TNT-WARN WideCharToString} -{TNT-WARN WideCharLenToString} -{TNT-WARN WideCharToStrVar} -{TNT-WARN WideCharLenToStrVar} -{TNT-WARN StringToWideChar} - -// ................ ANSI TYPES ................ -{TNT-WARN Char} -{TNT-WARN PChar} -{TNT-WARN String} - -{TNT-WARN CP_ACP} // <-- use DefaultSystemCodePage -function DefaultSystemCodePage: Cardinal; // implicitly used when converting AnsiString <--> WideString. - -var - WideCustomLoadResString: function(ResStringRec: PResStringRec; var Value: WideString): Boolean; - -{TNT-WARN LoadResString} -function WideLoadResString(ResStringRec: PResStringRec): WideString; -{TNT-WARN ParamCount} -function WideParamCount: Integer; -{TNT-WARN ParamStr} -function WideParamStr(Index: Integer): WideString; - -// ......... introduced ......... - -const - { Each Unicode stream should begin with the code U+FEFF, } - { which the standard defines as the *byte order mark*. } - UNICODE_BOM = WideChar($FEFF); - UNICODE_BOM_SWAPPED = WideChar($FFFE); - UTF8_BOM = AnsiString(#$EF#$BB#$BF); - -function WideStringToUTF8(const S: WideString): AnsiString; -function UTF8ToWideString(const S: AnsiString): WideString; - -function WideStringToUTF7(const W: WideString): AnsiString; -function UTF7ToWideString(const S: AnsiString): WideString; - -function StringToWideStringEx(const S: AnsiString; CodePage: Cardinal): WideString; -function WideStringToStringEx(const WS: WideString; CodePage: Cardinal): AnsiString; - -function UCS2ToWideString(const Value: AnsiString): WideString; -function WideStringToUCS2(const Value: WideString): AnsiString; - -function CharSetToCodePage(ciCharset: UINT): Cardinal; -function LCIDToCodePage(ALcid: LCID): Cardinal; -function KeyboardCodePage: Cardinal; -function KeyUnicode(CharCode: Word): WideChar; - -procedure StrSwapByteOrder(Str: PWideChar); - -type - TTntSystemUpdate = - (tsWideResourceStrings, - {$IFNDEF COMPILER_9_UP}tsFixImplicitCodePage, tsFixWideStrConcat, tsFixWideFormat, {$ENDIF} - tsWideExceptions - ); - TTntSystemUpdateSet = set of TTntSystemUpdate; - -const - AllTntSystemUpdates = [Low(TTntSystemUpdate)..High(TTntSystemUpdate)]; - -procedure InstallTntSystemUpdates(Updates: TTntSystemUpdateSet = AllTntSystemUpdates); - -implementation - -uses - SysUtils, Variants, Forms, TntWindows, TntSysUtils, TntForms; - -var - GDefaultSystemCodePage: Cardinal; - -function DefaultSystemCodePage: Cardinal; -begin - Result := GDefaultSystemCodePage; -end; - -var - IsDebugging: Boolean; - -function WideLoadResString(ResStringRec: PResStringRec): WideString; -const - MAX_RES_STRING_SIZE = 4097; { MSDN documents this as the maximum size of a string in table. } -var - Buffer: array [0..MAX_RES_STRING_SIZE] of WideChar; { Buffer leaves room for null terminator. } - PCustom: PAnsiChar; -begin - if Assigned(WideCustomLoadResString) and WideCustomLoadResString(ResStringRec, Result) then - exit; { a custom resourcestring has been loaded. } - - if ResStringRec = nil then - Result := '' - else if ResStringRec.Identifier < 64*1024 then - SetString(Result, Buffer, - Tnt_LoadStringW(FindResourceHInstance(ResStringRec.Module^), - ResStringRec.Identifier, Buffer, MAX_RES_STRING_SIZE)) - else begin - // custom string pointer - PCustom := PAnsiChar(ResStringRec.Identifier); { I would like to use PWideChar, but this would break legacy code. } - if (StrLen{TNT-ALLOW StrLen}(PCustom) > Cardinal(Length(UTF8_BOM))) - and CompareMem(PCustom, PAnsiChar(UTF8_BOM), Length(UTF8_BOM)) then - // detected UTF8 - Result := UTF8ToWideString(PAnsiChar(PCustom + Length(UTF8_BOM))) - else - // normal - Result := PCustom; - end; -end; - -function WideGetParamStr(P: PWideChar; var Param: WideString): PWideChar; -var - i, Len: Integer; - Start, S, Q: PWideChar; -begin - while True do - begin - while (P[0] <> #0) and (P[0] <= ' ') do - Inc(P); - if (P[0] = '"') and (P[1] = '"') then Inc(P, 2) else Break; - end; - Len := 0; - Start := P; - while P[0] > ' ' do - begin - if P[0] = '"' then - begin - Inc(P); - while (P[0] <> #0) and (P[0] <> '"') do - begin - Q := P + 1; - Inc(Len, Q - P); - P := Q; - end; - if P[0] <> #0 then - Inc(P); - end - else - begin - Q := P + 1; - Inc(Len, Q - P); - P := Q; - end; - end; - - SetLength(Param, Len); - - P := Start; - S := PWideChar(Param); - i := 0; - while P[0] > ' ' do - begin - if P[0] = '"' then - begin - Inc(P); - while (P[0] <> #0) and (P[0] <> '"') do - begin - Q := P + 1; - while P < Q do - begin - S[i] := P^; - Inc(P); - Inc(i); - end; - end; - if P[0] <> #0 then Inc(P); - end - else - begin - Q := P + 1; - while P < Q do - begin - S[i] := P^; - Inc(P); - Inc(i); - end; - end; - end; - - Result := P; -end; - -function WideParamCount: Integer; -var - P: PWideChar; - S: WideString; -begin - P := WideGetParamStr(GetCommandLineW, S); - Result := 0; - while True do - begin - P := WideGetParamStr(P, S); - if S = '' then Break; - Inc(Result); - end; -end; - -function WideParamStr(Index: Integer): WideString; -var - P: PWideChar; -begin - if Index = 0 then - Result := WideGetModuleFileName(0) - else - begin - P := GetCommandLineW; - while True do - begin - P := WideGetParamStr(P, Result); - if (Index = 0) or (Result = '') then Break; - Dec(Index); - end; - end; -end; - -function WideStringToUTF8(const S: WideString): AnsiString; -begin - Result := UTF8Encode(S); -end; - -function UTF8ToWideString(const S: AnsiString): WideString; -begin - Result := UTF8Decode(S); -end; - - { ======================================================================= } - { Original File: ConvertUTF7.c } - { Author: David B. Goldsmith } - { Copyright (C) 1994, 1996 Taligent, Inc. All rights reserved. } - { } - { This code is copyrighted. Under the copyright laws, this code may not } - { be copied, in whole or part, without prior written consent of Taligent. } - { } - { Taligent grants the right to use this code as long as this ENTIRE } - { copyright notice is reproduced in the code. The code is provided } - { AS-IS, AND TALIGENT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR } - { IMPLIED, INCLUDING, BUT NOT LIMITED TO IMPLIED WARRANTIES OF } - { MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT } - { WILL TALIGENT BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING, } - { WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS } - { INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY } - { LOSS) ARISING OUT OF THE USE OR INABILITY TO USE THIS CODE, EVEN } - { IF TALIGENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. } - { BECAUSE SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF } - { LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE } - { LIMITATION MAY NOT APPLY TO YOU. } - { } - { RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the } - { government is subject to restrictions as set forth in subparagraph } - { (c)(l)(ii) of the Rights in Technical Data and Computer Software } - { clause at DFARS 252.227-7013 and FAR 52.227-19. } - { } - { This code may be protected by one or more U.S. and International } - { Patents. } - { } - { TRADEMARKS: Taligent and the Taligent Design Mark are registered } - { trademarks of Taligent, Inc. } - { ======================================================================= } - -type UCS2 = Word; - -const - _base64: AnsiString = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - _direct: AnsiString = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789''(),-./:?'; - _optional: AnsiString = '!"#$%&*;<=>@[]^_`{|}'; - _spaces: AnsiString = #9#13#10#32; - -var - base64: PAnsiChar; - invbase64: array[0..127] of SmallInt; - direct: PAnsiChar; - optional: PAnsiChar; - spaces: PAnsiChar; - mustshiftsafe: array[0..127] of AnsiChar; - mustshiftopt: array[0..127] of AnsiChar; - -var - needtables: Boolean = True; - -procedure Initialize_UTF7_Data; -begin - base64 := PAnsiChar(_base64); - direct := PAnsiChar(_direct); - optional := PAnsiChar(_optional); - spaces := PAnsiChar(_spaces); -end; - -procedure tabinit; -var - i: Integer; - limit: Integer; -begin - i := 0; - while (i < 128) do - begin - mustshiftopt[i] := #1; - mustshiftsafe[i] := #1; - invbase64[i] := -1; - Inc(i); - end { For }; - limit := Length(_Direct); - i := 0; - while (i < limit) do - begin - mustshiftopt[Integer(direct[i])] := #0; - mustshiftsafe[Integer(direct[i])] := #0; - Inc(i); - end { For }; - limit := Length(_Spaces); - i := 0; - while (i < limit) do - begin - mustshiftopt[Integer(spaces[i])] := #0; - mustshiftsafe[Integer(spaces[i])] := #0; - Inc(i); - end { For }; - limit := Length(_Optional); - i := 0; - while (i < limit) do - begin - mustshiftopt[Integer(optional[i])] := #0; - Inc(i); - end { For }; - limit := Length(_Base64); - i := 0; - while (i < limit) do - begin - invbase64[Integer(base64[i])] := i; - Inc(i); - end { For }; - needtables := False; -end; { tabinit } - -function WRITE_N_BITS(x: UCS2; n: Integer; var BITbuffer: Cardinal; var bufferbits: Integer): Integer; -begin - BITbuffer := BITbuffer or (x and (not (-1 shl n))) shl (32 - n - bufferbits); - bufferbits := bufferbits + n; - Result := bufferbits; -end; { WRITE_N_BITS } - -function READ_N_BITS(n: Integer; var BITbuffer: Cardinal; var bufferbits: Integer): UCS2; -var - buffertemp: Cardinal; -begin - buffertemp := BITbuffer shr (32 - n); - BITbuffer := BITbuffer shl n; - bufferbits := bufferbits - n; - Result := UCS2(buffertemp); -end; { READ_N_BITS } - -function ConvertUCS2toUTF7(var sourceStart: PWideChar; sourceEnd: PWideChar; - var targetStart: PAnsiChar; targetEnd: PAnsiChar; optional: Boolean; - verbose: Boolean): Integer; -var - r: UCS2; - target: PAnsiChar; - source: PWideChar; - BITbuffer: Cardinal; - bufferbits: Integer; - shifted: Boolean; - needshift: Boolean; - done: Boolean; - mustshift: PAnsiChar; -begin - Initialize_UTF7_Data; - Result := 0; - BITbuffer := 0; - bufferbits := 0; - shifted := False; - source := sourceStart; - target := targetStart; - r := 0; - if needtables then - tabinit; - if optional then - mustshift := @mustshiftopt[0] - else - mustshift := @mustshiftsafe[0]; - repeat - done := source >= sourceEnd; - if not Done then - begin - r := Word(source^); - Inc(Source); - end { If }; - needshift := (not done) and ((r > $7F) or (mustshift[r] <> #0)); - if needshift and (not shifted) then - begin - if (Target >= TargetEnd) then - begin - Result := 2; - break; - end { If }; - target^ := '+'; - Inc(target); - { Special case handling of the SHIFT_IN character } - if (r = UCS2('+')) then - begin - if (target >= targetEnd) then - begin - Result := 2; - break; - end; - target^ := '-'; - Inc(target); - end - else - shifted := True; - end { If }; - if shifted then - begin - { Either write the character to the bit buffer, or pad } - { the bit buffer out to a full base64 character. } - { } - if needshift then - WRITE_N_BITS(r, 16, BITbuffer, bufferbits) - else - WRITE_N_BITS(0, (6 - (bufferbits mod 6)) mod 6, BITbuffer, - bufferbits); - { Flush out as many full base64 characters as possible } - { from the bit buffer. } - { } - while (target < targetEnd) and (bufferbits >= 6) do - begin - Target^ := base64[READ_N_BITS(6, BITbuffer, bufferbits)]; - Inc(Target); - end { While }; - if (bufferbits >= 6) then - begin - if (target >= targetEnd) then - begin - Result := 2; - break; - end { If }; - end { If }; - if (not needshift) then - begin - { Write the explicit shift out character if } - { 1) The caller has requested we always do it, or } - { 2) The directly encoded character is in the } - { base64 set, or } - { 3) The directly encoded character is SHIFT_OUT. } - { } - if verbose or ((not done) and ((invbase64[r] >= 0) or (r = - Integer('-')))) then - begin - if (target >= targetEnd) then - begin - Result := 2; - Break; - end { If }; - Target^ := '-'; - Inc(Target); - end { If }; - shifted := False; - end { If }; - { The character can be directly encoded as ASCII. } - end { If }; - if (not needshift) and (not done) then - begin - if (target >= targetEnd) then - begin - Result := 2; - break; - end { If }; - Target^ := AnsiChar(r); - Inc(Target); - end { If }; - until (done); - sourceStart := source; - targetStart := target; -end; { ConvertUCS2toUTF7 } - -function ConvertUTF7toUCS2(var sourceStart: PAnsiChar; sourceEnd: PAnsiChar; - var targetStart: PWideChar; targetEnd: PWideChar): Integer; -var - target: PWideChar { Register }; - source: PAnsiChar { Register }; - BITbuffer: Cardinal { & "Address Of" Used }; - bufferbits: Integer { & "Address Of" Used }; - shifted: Boolean { Used In Boolean Context }; - first: Boolean { Used In Boolean Context }; - wroteone: Boolean; - base64EOF: Boolean; - base64value: Integer; - done: Boolean; - c: UCS2; - prevc: UCS2; - junk: UCS2 { Used In Boolean Context }; -begin - Initialize_UTF7_Data; - Result := 0; - BITbuffer := 0; - bufferbits := 0; - shifted := False; - first := False; - wroteone := False; - source := sourceStart; - target := targetStart; - c := 0; - if needtables then - tabinit; - repeat - { read an ASCII character c } - done := Source >= SourceEnd; - if (not done) then - begin - c := Word(Source^); - Inc(Source); - end { If }; - if shifted then - begin - { We're done with a base64 string if we hit EOF, it's not a valid } - { ASCII character, or it's not in the base64 set. } - { } - base64value := invbase64[c]; - base64EOF := (done or (c > $7F)) or (base64value < 0); - if base64EOF then - begin - shifted := False; - { If the character causing us to drop out was SHIFT_IN or } - { SHIFT_OUT, it may be a special escape for SHIFT_IN. The } - { test for SHIFT_IN is not necessary, but allows an alternate } - { form of UTF-7 where SHIFT_IN is escaped by SHIFT_IN. This } - { only works for some values of SHIFT_IN. } - { } - if ((not done) and ((c = Integer('+')) or (c = Integer('-')))) then - begin - { get another character c } - prevc := c; - Done := Source >= SourceEnd; - if (not Done) then - begin - c := Word(Source^); - Inc(Source); - { If no base64 characters were encountered, and the } - { character terminating the shift sequence was } - { SHIFT_OUT, then it's a special escape for SHIFT_IN. } - { } - end; - if first and (prevc = Integer('-')) then - begin - { write SHIFT_IN unicode } - if (target >= targetEnd) then - begin - Result := 2; - break; - end { If }; - Target^ := WideChar('+'); - Inc(Target); - end - else - begin - if (not wroteone) then - begin - Result := 1; - end { If }; - end { Else }; - ; - end { If } - else - begin - if (not wroteone) then - begin - Result := 1; - end { If }; - end { Else }; - end { If } - else - begin - { Add another 6 bits of base64 to the bit buffer. } - WRITE_N_BITS(base64value, 6, BITbuffer, - bufferbits); - first := False; - end { Else }; - { Extract as many full 16 bit characters as possible from the } - { bit buffer. } - { } - while (bufferbits >= 16) and (target < targetEnd) do - begin - { write a unicode } - Target^ := WideChar(READ_N_BITS(16, BITbuffer, bufferbits)); - Inc(Target); - wroteone := True; - end { While }; - if (bufferbits >= 16) then - begin - if (target >= targetEnd) then - begin - Result := 2; - Break; - end; - end { If }; - if (base64EOF) then - begin - junk := READ_N_BITS(bufferbits, BITbuffer, bufferbits); - if (junk <> 0) then - begin - Result := 1; - end { If }; - end { If }; - end { If }; - if (not shifted) and (not done) then - begin - if (c = Integer('+')) then - begin - shifted := True; - first := True; - wroteone := False; - end { If } - else - begin - { It must be a directly encoded character. } - if (c > $7F) then - begin - Result := 1; - end { If }; - if (target >= targetEnd) then - begin - Result := 2; - break; - end { If }; - Target^ := WideChar(c); - Inc(Target); - end { Else }; - end { If }; - until (done); - sourceStart := source; - targetStart := target; -end; { ConvertUTF7toUCS2 } - - {*****************************************************************************} - { Thanks to Francisco Leong for providing the Pascal conversion of } - { ConvertUTF7.c (by David B. Goldsmith) } - {*****************************************************************************} - -resourcestring - SBufferOverflow = 'Buffer overflow'; - SInvalidUTF7 = 'Invalid UTF7'; - -function WideStringToUTF7(const W: WideString): AnsiString; -var - SourceStart, SourceEnd: PWideChar; - TargetStart, TargetEnd: PAnsiChar; -begin - if W = '' then - Result := '' - else - begin - SetLength(Result, Length(W) * 7); // Assume worst case - SourceStart := PWideChar(@W[1]); - SourceEnd := PWideChar(@W[Length(W)]) + 1; - TargetStart := PAnsiChar(@Result[1]); - TargetEnd := PAnsiChar(@Result[Length(Result)]) + 1; - if ConvertUCS2toUTF7(SourceStart, SourceEnd, TargetStart, - TargetEnd, True, False) <> 0 - then - raise ETntInternalError.Create(SBufferOverflow); - SetLength(Result, TargetStart - PAnsiChar(@Result[1])); - end; -end; - -function UTF7ToWideString(const S: AnsiString): WideString; -var - SourceStart, SourceEnd: PAnsiChar; - TargetStart, TargetEnd: PWideChar; -begin - if (S = '') then - Result := '' - else - begin - SetLength(Result, Length(S)); // Assume Worst case - SourceStart := PAnsiChar(@S[1]); - SourceEnd := PAnsiChar(@S[Length(S)]) + 1; - TargetStart := PWideChar(@Result[1]); - TargetEnd := PWideChar(@Result[Length(Result)]) + 1; - case ConvertUTF7toUCS2(SourceStart, SourceEnd, TargetStart, - TargetEnd) of - 1: raise ETntGeneralError.Create(SInvalidUTF7); - 2: raise ETntInternalError.Create(SBufferOverflow); - end; - SetLength(Result, TargetStart - PWideChar(@Result[1])); - end; -end; - -function StringToWideStringEx(const S: AnsiString; CodePage: Cardinal): WideString; -var - InputLength, - OutputLength: Integer; -begin - if CodePage = CP_UTF7 then - Result := UTF7ToWideString(S) // CP_UTF7 not supported on Windows 95 - else if CodePage = CP_UTF8 then - Result := UTF8ToWideString(S) // CP_UTF8 not supported on Windows 95 - else begin - InputLength := Length(S); - OutputLength := MultiByteToWideChar(CodePage, 0, PAnsiChar(S), InputLength, nil, 0); - SetLength(Result, OutputLength); - MultiByteToWideChar(CodePage, 0, PAnsiChar(S), InputLength, PWideChar(Result), OutputLength); - end; -end; - -function WideStringToStringEx(const WS: WideString; CodePage: Cardinal): AnsiString; -var - InputLength, - OutputLength: Integer; -begin - if CodePage = CP_UTF7 then - Result := WideStringToUTF7(WS) // CP_UTF7 not supported on Windows 95 - else if CodePage = CP_UTF8 then - Result := WideStringToUTF8(WS) // CP_UTF8 not supported on Windows 95 - else begin - InputLength := Length(WS); - OutputLength := WideCharToMultiByte(CodePage, 0, PWideChar(WS), InputLength, nil, 0, nil, nil); - SetLength(Result, OutputLength); - WideCharToMultiByte(CodePage, 0, PWideChar(WS), InputLength, PAnsiChar(Result), OutputLength, nil, nil); - end; -end; - -function UCS2ToWideString(const Value: AnsiString): WideString; -begin - if Length(Value) = 0 then - Result := '' - else - SetString(Result, PWideChar(@Value[1]), Length(Value) div SizeOf(WideChar)) -end; - -function WideStringToUCS2(const Value: WideString): AnsiString; -begin - if Length(Value) = 0 then - Result := '' - else - SetString(Result, PAnsiChar(@Value[1]), Length(Value) * SizeOf(WideChar)) -end; - -{ Windows.pas doesn't declare TranslateCharsetInfo() correctly. } -function TranslateCharsetInfo(lpSrc: PDWORD; var lpCs: TCharsetInfo; dwFlags: DWORD): BOOL; stdcall; external gdi32 name 'TranslateCharsetInfo'; - -function CharSetToCodePage(ciCharset: UINT): Cardinal; -var - C: TCharsetInfo; -begin - Win32Check(TranslateCharsetInfo(PDWORD(ciCharset), C, TCI_SRCCHARSET)); - Result := C.ciACP -end; - -function LCIDToCodePage(ALcid: LCID): Cardinal; -var - Buf: array[0..6] of AnsiChar; -begin - GetLocaleInfo(ALcid, LOCALE_IDefaultAnsiCodePage, Buf, 6); - Result := StrToIntDef(Buf, GetACP); -end; - -function KeyboardCodePage: Cardinal; -begin - Result := LCIDToCodePage(GetKeyboardLayout(0) and $FFFF); -end; - -function KeyUnicode(CharCode: Word): WideChar; -var - AChar: AnsiChar; -begin - // converts the given character (as it comes with a WM_CHAR message) into its - // corresponding Unicode character depending on the active keyboard layout - if CharCode <= Word(High(AnsiChar)) then begin - AChar := AnsiChar(CharCode); - MultiByteToWideChar(KeyboardCodePage, MB_USEGLYPHCHARS, @AChar, 1, @Result, 1); - end else - Result := WideChar(CharCode); -end; - -procedure StrSwapByteOrder(Str: PWideChar); -var - P: PWord; -begin - P := PWord(Str); - While (P^ <> 0) do begin - P^ := MakeWord(HiByte(P^), LoByte(P^)); - Inc(P); - end; -end; - -//-------------------------------------------------------------------- -// LoadResString() -// -// This system function is used to retrieve a resourcestring and -// return the result as an AnsiString. If we believe that the result -// is only a temporary value, and that it will be immediately -// assigned to a WideString or a Variant, then we will save the -// Unicode result as well as a reference to the original Ansi string. -// WStrFromPCharLen() or VarFromLStr() will return this saved -// Unicode string if it appears to receive the most recent result -// of LoadResString. -//-------------------------------------------------------------------- - - - //=========================================================================================== - // - // function CodeMatchesPatternForUnicode(...); - // - // GIVEN: SomeWideString := SSomeResString; { WideString := resourcestring } - // - // Delphi will compile this statement into the following: - // ------------------------------------------------- - // TempAnsiString := LoadResString(@SSomeResString); - // LINE 1: lea edx,[SomeTempAnsiString] - // LINE 2: mov eax,[@SomeResString] - // LINE 3: call LoadResString - // - // WStrFromLStr(SomeWideString, TempAnsiString); { SomeWideString := TempAnsiString } - // LINE 4: mov edx,[SomeTempAnsiString] - // LINE 5: mov/lea eax [@SomeWideString] - // LINE 6: call @WStrFromLStr - // ------------------------------------------------- - // - // The order in which the parameters are prepared for WStrFromLStr (ie LINE 4 & 5) is - // reversed when assigning a non-temporary AnsiString to a WideString. - // - // This code, for example, results in LINE 4 and LINE 5 being swapped. - // - // SomeAnsiString := SSomeResString; - // SomeWideString := SomeAnsiString; - // - // Since we know the "signature" used by the compiler, we can detect this pattern. - // If we believe it is only temporary, we can save the Unicode results for later - // retrieval from WStrFromLStr. - // - // One final note: When assigning a resourcestring to a Variant, the same patterns exist. - //=========================================================================================== - -function CodeMatchesPatternForUnicode(PLine4: PAnsiChar): Boolean; -const - SIZEOF_OPCODE = 1 {byte}; - MOV_16_OPCODE = AnsiChar($8B); { we'll assume operand size is 16 bits } - MOV_32_OPCODE = AnsiChar($B8); { we'll assume operand size is 32 bits } - LEA_OPCODE = AnsiChar($8D); { operand size can be 16 or 40 bits } - CALL_OPCODE = AnsiChar($E8); { assumed operand size is 32 bits } - BREAK_OPCODE = AnsiChar($CC); {in a breakpoint} -var - PLine1: PAnsiChar; - PLine2: PAnsiChar; - PLine3: PAnsiChar; - DataSize: Integer; // bytes in first LEA operand -begin - Result := False; - - PLine3 := PLine4 - SizeOf(CALL_OPCODE) - 4; - PLine2 := PLine3 - SizeOf(MOV_32_OPCODE) - 4; - - // figure PLine1 and operand size - DataSize := 2; { try 16 bit operand for line 1 } - PLine1 := PLine2 - DataSize - SizeOf(LEA_OPCODE); - if (PLine1^ <> LEA_OPCODE) and (not (IsDebugging and (PLine1^ = BREAK_OPCODE))) then - begin - DataSize := 5; { try 40 bit operand for line 1 } - PLine1 := PLine2 - DataSize - SizeOf(LEA_OPCODE); - end; - if (PLine1^ = LEA_OPCODE) or (IsDebugging and (PLine1^ = BREAK_OPCODE)) then - begin - if CompareMem(PLine1 + SIZEOF_OPCODE, PLine4 + SIZEOF_OPCODE, DataSize) then - begin - // After this check, it seems to match the WideString <- (temp) AnsiString pattern - Result := True; // It is probably OK. (The side effects of being wrong aren't very bad.) - end; - end; -end; - -threadvar - PLastResString: PAnsiChar; - LastResStringValue: AnsiString; - LastWideResString: WideString; - -procedure FreeTntSystemThreadVars; -begin - LastResStringValue := ''; - LastWideResString := ''; -end; - -procedure Custom_System_EndThread(ExitCode: Integer); -begin - FreeTntSystemThreadVars; - {$IFDEF COMPILER_10_UP} - if Assigned(SystemThreadEndProc) then - SystemThreadEndProc(ExitCode); - {$ENDIF} - ExitThread(ExitCode); -end; - -function Custom_System_LoadResString(ResStringRec: PResStringRec): AnsiString; -var - ReturnAddr: Pointer; -begin - // get return address - asm - PUSH ECX - MOV ECX, [EBP + 4] - MOV ReturnAddr, ECX - POP ECX - end; - // check calling code pattern - if CodeMatchesPatternForUnicode(ReturnAddr) then begin - // result will probably be assigned to an intermediate AnsiString - // on its way to either a WideString or Variant. - LastWideResString := WideLoadResString(ResStringRec); - Result := LastWideResString; - LastResStringValue := Result; - if Result = '' then - PLastResString := nil - else - PLastResString := PAnsiChar(Result); - end else begin - // result will probably be assigned to an actual AnsiString variable. - PLastResString := nil; - Result := WideLoadResString(ResStringRec); - end; -end; - -//-------------------------------------------------------------------- -// WStrFromPCharLen() -// -// This system function is used to assign an AnsiString to a WideString. -// It has been modified to assign Unicode results from LoadResString. -// Another purpose of this function is to specify the code page. -//-------------------------------------------------------------------- - -procedure Custom_System_WStrFromPCharLen(var Dest: WideString; Source: PAnsiChar; Length: Integer); -var - DestLen: Integer; - Buffer: array[0..2047] of WideChar; - Local_PLastResString: Pointer; -begin - Local_PLastResString := PLastResString; - if (Local_PLastResString <> nil) - and (Local_PLastResString = Source) - and (System.Length(LastResStringValue) = Length) - and (LastResStringValue = Source) then begin - // use last unicode resource string - PLastResString := nil; { clear for further use } - Dest := LastWideResString; - end else begin - if Local_PLastResString <> nil then - PLastResString := nil; { clear for further use } - if Length <= 0 then - begin - Dest := ''; - Exit; - end; - if Length + 1 < High(Buffer) then - begin - DestLen := MultiByteToWideChar(DefaultSystemCodePage, 0, Source, Length, Buffer, - High(Buffer)); - if DestLen > 0 then - begin - SetLength(Dest, DestLen); - Move(Pointer(@Buffer[0])^, Pointer(Dest)^, DestLen * SizeOf(WideChar)); - Exit; - end; - end; - DestLen := (Length + 1); - SetLength(Dest, DestLen); // overallocate, trim later - DestLen := MultiByteToWideChar(DefaultSystemCodePage, 0, Source, Length, Pointer(Dest), - DestLen); - if DestLen < 0 then - DestLen := 0; - SetLength(Dest, DestLen); - end; -end; - -{$IFNDEF COMPILER_9_UP} - -//-------------------------------------------------------------------- -// LStrFromPWCharLen() -// -// This system function is used to assign an WideString to an AnsiString. -// It has not been modified from its original purpose other than to specify the code page. -//-------------------------------------------------------------------- - -procedure Custom_System_LStrFromPWCharLen(var Dest: AnsiString; Source: PWideChar; Length: Integer); -var - DestLen: Integer; - Buffer: array[0..4095] of AnsiChar; -begin - if Length <= 0 then - begin - Dest := ''; - Exit; - end; - if Length + 1 < (High(Buffer) div sizeof(WideChar)) then - begin - DestLen := WideCharToMultiByte(DefaultSystemCodePage, 0, Source, - Length, Buffer, High(Buffer), - nil, nil); - if DestLen >= 0 then - begin - SetLength(Dest, DestLen); - Move(Pointer(@Buffer[0])^, PAnsiChar(Dest)^, DestLen); - Exit; - end; - end; - - DestLen := (Length + 1) * sizeof(WideChar); - SetLength(Dest, DestLen); // overallocate, trim later - DestLen := WideCharToMultiByte(DefaultSystemCodePage, 0, Source, Length, Pointer(Dest), DestLen, - nil, nil); - if DestLen < 0 then - DestLen := 0; - SetLength(Dest, DestLen); -end; - -//-------------------------------------------------------------------- -// WStrToString() -// -// This system function is used to assign an WideString to an short string. -// It has not been modified from its original purpose other than to specify the code page. -//-------------------------------------------------------------------- - -procedure Custom_System_WStrToString(Dest: PShortString; const Source: WideString; MaxLen: Integer); -var - SourceLen, DestLen: Integer; - Buffer: array[0..511] of AnsiChar; -begin - if MaxLen > 255 then MaxLen := 255; - SourceLen := Length(Source); - if SourceLen >= MaxLen then SourceLen := MaxLen; - if SourceLen = 0 then - DestLen := 0 - else begin - DestLen := WideCharToMultiByte(DefaultSystemCodePage, 0, Pointer(Source), SourceLen, - Buffer, SizeOf(Buffer), nil, nil); - if DestLen > MaxLen then DestLen := MaxLen; - end; - Dest^[0] := Chr(DestLen); - if DestLen > 0 then Move(Buffer, Dest^[1], DestLen); -end; - -{$ENDIF} - -//-------------------------------------------------------------------- -// VarFromLStr() -// -// This system function is used to assign an AnsiString to a Variant. -// It has been modified to assign Unicode results from LoadResString. -//-------------------------------------------------------------------- - -procedure Custom_System_VarFromLStr(var V: TVarData; const Value: AnsiString); -const - varDeepData = $BFE8; -var - Local_PLastResString: Pointer; -begin - if (V.VType and varDeepData) <> 0 then - VarClear(PVariant(@V)^); - - Local_PLastResString := PLastResString; - if (Local_PLastResString <> nil) - and (Local_PLastResString = PAnsiChar(Value)) - and (LastResStringValue = Value) then begin - // use last unicode resource string - PLastResString := nil; { clear for further use } - V.VOleStr := nil; - V.VType := varOleStr; - WideString(Pointer(V.VOleStr)) := Copy(LastWideResString, 1, MaxInt); - end else begin - if Local_PLastResString <> nil then - PLastResString := nil; { clear for further use } - V.VString := nil; - V.VType := varString; - AnsiString(V.VString) := Value; - end; -end; - -{$IFNDEF COMPILER_9_UP} - -//-------------------------------------------------------------------- -// WStrCat3() A := B + C; -// -// This system function is used to concatenate two strings into one result. -// This function is added because A := '' + '' doesn't necessarily result in A = ''; -//-------------------------------------------------------------------- - -procedure Custom_System_WStrCat3(var Dest: WideString; const Source1, Source2: WideString); - - function NewWideString(CharLength: Longint): Pointer; - var - _NewWideString: function(CharLength: Longint): Pointer; - begin - asm - PUSH ECX - MOV ECX, offset System.@NewWideString; - MOV _NewWideString, ECX - POP ECX - end; - Result := _NewWideString(CharLength); - end; - - procedure WStrSet(var S: WideString; P: PWideChar); - var - Temp: Pointer; - begin - Temp := Pointer(InterlockedExchange(Integer(S), Integer(P))); - if Temp <> nil then - WideString(Temp) := ''; - end; - -var - Source1Len, Source2Len: Integer; - NewStr: PWideChar; -begin - Source1Len := Length(Source1); - Source2Len := Length(Source2); - if (Source1Len <> 0) or (Source2Len <> 0) then - begin - NewStr := NewWideString(Source1Len + Source2Len); - Move(Pointer(Source1)^, Pointer(NewStr)^, Source1Len * sizeof(WideChar)); - Move(Pointer(Source2)^, NewStr[Source1Len], Source2Len * sizeof(WideChar)); - WStrSet(Dest, NewStr); - end else - Dest := ''; -end; - -{$ENDIF} - -//-------------------------------------------------------------------- -// System proc replacements -//-------------------------------------------------------------------- - -type - POverwrittenData = ^TOverwrittenData; - TOverwrittenData = record - Location: Pointer; - OldCode: array[0..6] of Byte; - end; - -procedure OverwriteProcedure(OldProcedure, NewProcedure: pointer; Data: POverwrittenData = nil); -{ OverwriteProcedure originally from Igor Siticov } -{ Modified by Jacques Garcia Vazquez } -var - x: PAnsiChar; - y: integer; - ov2, ov: cardinal; - p: pointer; -begin - if Assigned(Data) and (Data.Location <> nil) then - exit; { procedure already overwritten } - - // need six bytes in place of 5 - x := PAnsiChar(OldProcedure); - if not VirtualProtect(Pointer(x), 6, PAGE_EXECUTE_READWRITE, @ov) then - RaiseLastOSError; - - // if a jump is present then a redirect is found - // $FF25 = jmp dword ptr [xxx] - // This redirect is normally present in bpl files, but not in exe files - p := OldProcedure; - - if Word(p^) = $25FF then - begin - Inc(Integer(p), 2); // skip the jump - // get the jump address p^ and dereference it p^^ - p := Pointer(Pointer(p^)^); - - // release the memory - if not VirtualProtect(Pointer(x), 6, ov, @ov2) then - RaiseLastOSError; - - // re protect the correct one - x := PAnsiChar(p); - if not VirtualProtect(Pointer(x), 6, PAGE_EXECUTE_READWRITE, @ov) then - RaiseLastOSError; - end; - - if Assigned(Data) then - begin - Move(x^, Data.OldCode, 6); - { Assign Location last so that Location <> nil only if OldCode is properly initialized. } - Data.Location := x; - end; - - x[0] := AnsiChar($E9); - y := integer(NewProcedure) - integer(p) - 5; - x[1] := AnsiChar(y and 255); - x[2] := AnsiChar((y shr 8) and 255); - x[3] := AnsiChar((y shr 16) and 255); - x[4] := AnsiChar((y shr 24) and 255); - - if not VirtualProtect(Pointer(x), 6, ov, @ov2) then - RaiseLastOSError; -end; - -procedure RestoreProcedure(OriginalProc: Pointer; Data: TOverwrittenData); -var - ov, ov2: Cardinal; -begin - if Data.Location <> nil then begin - if not VirtualProtect(Data.Location, 6, PAGE_EXECUTE_READWRITE, @ov) then - RaiseLastOSError; - Move(Data.OldCode, Data.Location^, 6); - if not VirtualProtect(Data.Location, 6, ov, @ov2) then - RaiseLastOSError; - end; -end; - -function Addr_System_EndThread: Pointer; -begin - Result := @System.EndThread; -end; - -function Addr_System_LoadResString: Pointer; -begin - Result := @System.LoadResString{TNT-ALLOW LoadResString}; -end; - -function Addr_System_WStrFromPCharLen: Pointer; -asm - mov eax, offset System.@WStrFromPCharLen; -end; - -{$IFNDEF COMPILER_9_UP} -function Addr_System_LStrFromPWCharLen: Pointer; -asm - mov eax, offset System.@LStrFromPWCharLen; -end; - -function Addr_System_WStrToString: Pointer; -asm - mov eax, offset System.@WStrToString; -end; -{$ENDIF} - -function Addr_System_VarFromLStr: Pointer; -asm - mov eax, offset System.@VarFromLStr; -end; - -function Addr_System_WStrCat3: Pointer; -asm - mov eax, offset System.@WStrCat3; -end; - -var - System_EndThread_Code, - System_LoadResString_Code, - System_WStrFromPCharLen_Code, - {$IFNDEF COMPILER_9_UP} - System_LStrFromPWCharLen_Code, - System_WStrToString_Code, - {$ENDIF} - System_VarFromLStr_Code, - {$IFNDEF COMPILER_9_UP} - System_WStrCat3_Code, - SysUtils_WideFmtStr_Code, - {$ENDIF} - Forms_TApplication_ShowException_Code, - SysUtils_RaiseLastOsError_Code: TOverwrittenData; - -procedure InstallEndThreadOverride; -begin - OverwriteProcedure(Addr_System_EndThread, @Custom_System_EndThread, @System_EndThread_Code); -end; - -procedure InstallStringConversionOverrides; -begin - OverwriteProcedure(Addr_System_WStrFromPCharLen, @Custom_System_WStrFromPCharLen, @System_WStrFromPCharLen_Code); - {$IFNDEF COMPILER_9_UP} - OverwriteProcedure(Addr_System_LStrFromPWCharLen, @Custom_System_LStrFromPWCharLen, @System_LStrFromPWCharLen_Code); - OverwriteProcedure(Addr_System_WStrToString, @Custom_System_WStrToString, @System_WStrToString_Code); - {$ENDIF} -end; - -procedure InstallWideResourceStrings; -begin - OverwriteProcedure(Addr_System_LoadResString, @Custom_System_LoadResString, @System_LoadResString_Code); - OverwriteProcedure(Addr_System_VarFromLStr, @Custom_System_VarFromLStr, @System_VarFromLStr_Code); -end; - -{$IFNDEF COMPILER_9_UP} -procedure InstallWideStringConcatenationFix; -begin - OverwriteProcedure(Addr_System_WStrCat3, @Custom_System_WStrCat3, @System_WStrCat3_Code); -end; - -procedure InstallWideFormatFixes; -begin - OverwriteProcedure(@SysUtils.WideFmtStr, @TntSysUtils.Tnt_WideFmtStr, @SysUtils_WideFmtStr_Code); -end; -{$ENDIF} - -procedure InstallWideExceptions; -begin - OverwriteProcedure(@Forms.TApplication.ShowException, @TTntApplication.ShowException, @Forms_TApplication_ShowException_Code); - OverwriteProcedure(@SysUtils.RaiseLastOsError, @TntSysUtils.WideRaiseLastOsError, @SysUtils_RaiseLastOsError_Code); -end; - -procedure InstallTntSystemUpdates(Updates: TTntSystemUpdateSet = AllTntSystemUpdates); -begin - InstallEndThreadOverride; - if tsWideResourceStrings in Updates then begin - InstallStringConversionOverrides; - InstallWideResourceStrings; - end; - {$IFNDEF COMPILER_9_UP} - if tsFixImplicitCodePage in Updates then begin - InstallStringConversionOverrides; - { CP_ACP is the code page used by the non-Unicode Windows API. } - GDefaultSystemCodePage := CP_ACP{TNT-ALLOW CP_ACP}; - end; - if tsFixWideStrConcat in Updates then begin - InstallWideStringConcatenationFix; - end; - if tsFixWideFormat in Updates then begin - InstallWideFormatFixes; - end; - {$ENDIF} - if tsWideExceptions in Updates then begin - InstallWideExceptions - end; -end; - -{$IFNDEF COMPILER_9_UP} -var - StartupDefaultUserCodePage: Cardinal; -{$ENDIF} - -procedure UninstallSystemOverrides; -begin - RestoreProcedure(Addr_System_EndThread, System_EndThread_Code); - // String Conversion - RestoreProcedure(Addr_System_WStrFromPCharLen, System_WStrFromPCharLen_Code); - {$IFNDEF COMPILER_9_UP} - RestoreProcedure(Addr_System_LStrFromPWCharLen, System_LStrFromPWCharLen_Code); - RestoreProcedure(Addr_System_WStrToString, System_WStrToString_Code); - GDefaultSystemCodePage := StartupDefaultUserCodePage; - {$ENDIF} - // Wide resourcestring - RestoreProcedure(Addr_System_LoadResString, System_LoadResString_Code); - RestoreProcedure(Addr_System_VarFromLStr, System_VarFromLStr_Code); - {$IFNDEF COMPILER_9_UP} - // WideString concat fix - RestoreProcedure(Addr_System_WStrCat3, System_WStrCat3_Code); - // WideFormat fixes - RestoreProcedure(@SysUtils.WideFmtStr, SysUtils_WideFmtStr_Code); - {$ENDIF} - // Wide exception - RestoreProcedure(@Forms.TApplication.ShowException, Forms_TApplication_ShowException_Code); - RestoreProcedure(@SysUtils.RaiseLastOsError, SysUtils_RaiseLastOsError_Code); -end; - -initialization - {$IFDEF COMPILER_9_UP} - GDefaultSystemCodePage := GetACP; - {$ELSE} - {$IFDEF COMPILER_7_UP} - if (Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion >= 5) then - GDefaultSystemCodePage := CP_THREAD_ACP // Win 2K/XP/... - else - GDefaultSystemCodePage := LCIDToCodePage(GetThreadLocale); // Win NT4/95/98/ME - {$ELSE} - GDefaultSystemCodePage := CP_ACP{TNT-ALLOW CP_ACP}; - {$ENDIF} - {$ENDIF} - {$IFNDEF COMPILER_9_UP} - StartupDefaultUserCodePage := DefaultSystemCodePage; - {$ENDIF} - IsDebugging := DebugHook > 0; - -finalization - UninstallSystemOverrides; - FreeTntSystemThreadVars; { Make MemorySleuth happy. } - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntWideStrUtils.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntWideStrUtils.pas deleted file mode 100644 index ede13f308..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntWideStrUtils.pas +++ /dev/null @@ -1,451 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntWideStrUtils; - -{$INCLUDE TntCompilers.inc} - -interface - -{ Wide string manipulation functions } - -{$IFNDEF COMPILER_9_UP} -function WStrAlloc(Size: Cardinal): PWideChar; -function WStrBufSize(const Str: PWideChar): Cardinal; -{$ENDIF} -{$IFNDEF COMPILER_10_UP} -function WStrMove(Dest: PWideChar; const Source: PWideChar; Count: Cardinal): PWideChar; -{$ENDIF} -{$IFNDEF COMPILER_9_UP} -function WStrNew(const Str: PWideChar): PWideChar; -procedure WStrDispose(Str: PWideChar); -{$ENDIF} -//--------------------------------------------------------------------------------------------- -{$IFNDEF COMPILER_9_UP} -function WStrLen(Str: PWideChar): Cardinal; -function WStrEnd(Str: PWideChar): PWideChar; -{$ENDIF} -{$IFNDEF COMPILER_10_UP} -function WStrCat(Dest: PWideChar; const Source: PWideChar): PWideChar; -{$ENDIF} -{$IFNDEF COMPILER_9_UP} -function WStrCopy(Dest, Source: PWideChar): PWideChar; -function WStrLCopy(Dest, Source: PWideChar; MaxLen: Cardinal): PWideChar; -function WStrPCopy(Dest: PWideChar; const Source: WideString): PWideChar; -function WStrPLCopy(Dest: PWideChar; const Source: WideString; MaxLen: Cardinal): PWideChar; -{$ENDIF} -{$IFNDEF COMPILER_10_UP} -function WStrScan(const Str: PWideChar; Chr: WideChar): PWideChar; -// WStrComp and WStrPos were introduced as broken in Delphi 2006, but fixed in Delphi 2006 Update 2 -function WStrComp(Str1, Str2: PWideChar): Integer; -function WStrPos(Str, SubStr: PWideChar): PWideChar; -{$ENDIF} -function Tnt_WStrComp(Str1, Str2: PWideChar): Integer; deprecated; -function Tnt_WStrPos(Str, SubStr: PWideChar): PWideChar; deprecated; - -{ ------------ introduced --------------- } -function WStrECopy(Dest, Source: PWideChar): PWideChar; -function WStrLComp(Str1, Str2: PWideChar; MaxLen: Cardinal): Integer; -function WStrLIComp(Str1, Str2: PWideChar; MaxLen: Cardinal): Integer; -function WStrIComp(Str1, Str2: PWideChar): Integer; -function WStrLower(Str: PWideChar): PWideChar; -function WStrUpper(Str: PWideChar): PWideChar; -function WStrRScan(const Str: PWideChar; Chr: WideChar): PWideChar; -function WStrLCat(Dest: PWideChar; const Source: PWideChar; MaxLen: Cardinal): PWideChar; -function WStrPas(const Str: PWideChar): WideString; - -{ SysUtils.pas } //------------------------------------------------------------------------- - -{$IFNDEF COMPILER_10_UP} -function WideLastChar(const S: WideString): PWideChar; -function WideQuotedStr(const S: WideString; Quote: WideChar): WideString; -{$ENDIF} -{$IFNDEF COMPILER_9_UP} -function WideExtractQuotedStr(var Src: PWideChar; Quote: WideChar): Widestring; -{$ENDIF} -{$IFNDEF COMPILER_10_UP} -function WideDequotedStr(const S: WideString; AQuote: WideChar): WideString; -{$ENDIF} - -implementation - -uses - {$IFDEF COMPILER_9_UP} WideStrUtils, {$ENDIF} Math, Windows, TntWindows; - -{$IFNDEF COMPILER_9_UP} -function WStrAlloc(Size: Cardinal): PWideChar; -begin - Size := SizeOf(Cardinal) + (Size * SizeOf(WideChar)); - GetMem(Result, Size); - PCardinal(Result)^ := Size; - Inc(PAnsiChar(Result), SizeOf(Cardinal)); -end; - -function WStrBufSize(const Str: PWideChar): Cardinal; -var - P: PWideChar; -begin - P := Str; - Dec(PAnsiChar(P), SizeOf(Cardinal)); - Result := PCardinal(P)^ - SizeOf(Cardinal); - Result := Result div SizeOf(WideChar); -end; -{$ENDIF} - -{$IFNDEF COMPILER_10_UP} -function WStrMove(Dest: PWideChar; const Source: PWideChar; Count: Cardinal): PWideChar; -var - Length: Integer; -begin - Result := Dest; - Length := Count * SizeOf(WideChar); - Move(Source^, Dest^, Length); -end; -{$ENDIF} - -{$IFNDEF COMPILER_9_UP} -function WStrNew(const Str: PWideChar): PWideChar; -var - Size: Cardinal; -begin - if Str = nil then Result := nil else - begin - Size := WStrLen(Str) + 1; - Result := WStrMove(WStrAlloc(Size), Str, Size); - end; -end; - -procedure WStrDispose(Str: PWideChar); -begin - if Str <> nil then - begin - Dec(PAnsiChar(Str), SizeOf(Cardinal)); - FreeMem(Str, Cardinal(Pointer(Str)^)); - end; -end; -{$ENDIF} - -//--------------------------------------------------------------------------------------------- - -{$IFNDEF COMPILER_9_UP} -function WStrLen(Str: PWideChar): Cardinal; -begin - Result := WStrEnd(Str) - Str; -end; - -function WStrEnd(Str: PWideChar): PWideChar; -begin - // returns a pointer to the end of a null terminated string - Result := Str; - While Result^ <> #0 do - Inc(Result); -end; -{$ENDIF} - -{$IFNDEF COMPILER_10_UP} -function WStrCat(Dest: PWideChar; const Source: PWideChar): PWideChar; -begin - Result := Dest; - WStrCopy(WStrEnd(Dest), Source); -end; -{$ENDIF} - -{$IFNDEF COMPILER_9_UP} -function WStrCopy(Dest, Source: PWideChar): PWideChar; -begin - Result := WStrLCopy(Dest, Source, MaxInt); -end; - -function WStrLCopy(Dest, Source: PWideChar; MaxLen: Cardinal): PWideChar; -var - Count: Cardinal; -begin - // copies a specified maximum number of characters from Source to Dest - Result := Dest; - Count := 0; - While (Count < MaxLen) and (Source^ <> #0) do begin - Dest^ := Source^; - Inc(Source); - Inc(Dest); - Inc(Count); - end; - Dest^ := #0; -end; - -function WStrPCopy(Dest: PWideChar; const Source: WideString): PWideChar; -begin - Result := WStrLCopy(Dest, PWideChar(Source), Length(Source)); -end; - -function WStrPLCopy(Dest: PWideChar; const Source: WideString; MaxLen: Cardinal): PWideChar; -begin - Result := WStrLCopy(Dest, PWideChar(Source), MaxLen); -end; -{$ENDIF} - -{$IFNDEF COMPILER_10_UP} -function WStrScan(const Str: PWideChar; Chr: WideChar): PWideChar; -begin - Result := Str; - while Result^ <> Chr do - begin - if Result^ = #0 then - begin - Result := nil; - Exit; - end; - Inc(Result); - end; -end; - -function WStrComp(Str1, Str2: PWideChar): Integer; -begin - Result := WStrLComp(Str1, Str2, MaxInt); -end; - -function WStrPos(Str, SubStr: PWideChar): PWideChar; -var - PSave: PWideChar; - P: PWideChar; - PSub: PWideChar; -begin - // returns a pointer to the first occurance of SubStr in Str - Result := nil; - if (Str <> nil) and (Str^ <> #0) and (SubStr <> nil) and (SubStr^ <> #0) then begin - P := Str; - While P^ <> #0 do begin - if P^ = SubStr^ then begin - // investigate possibility here - PSave := P; - PSub := SubStr; - While (P^ = PSub^) do begin - Inc(P); - Inc(PSub); - if (PSub^ = #0) then begin - Result := PSave; - exit; // found a match - end; - if (P^ = #0) then - exit; // no match, hit end of string - end; - P := PSave; - end; - Inc(P); - end; - end; -end; -{$ENDIF} - -function Tnt_WStrComp(Str1, Str2: PWideChar): Integer; deprecated; -begin - Result := WStrComp(Str1, Str2); -end; - -function Tnt_WStrPos(Str, SubStr: PWideChar): PWideChar; deprecated; -begin - Result := WStrPos(Str, SubStr); -end; - -//------------------------------------------------------------------------------ - -function WStrECopy(Dest, Source: PWideChar): PWideChar; -begin - Result := WStrEnd(WStrCopy(Dest, Source)); -end; - -function WStrComp_EX(Str1, Str2: PWideChar; MaxLen: Cardinal; dwCmpFlags: Cardinal): Integer; -var - Len1, Len2: Integer; -begin - if MaxLen = Cardinal(MaxInt) then begin - Len1 := -1; - Len2 := -1; - end else begin - Len1 := Min(WStrLen(Str1), MaxLen); - Len2 := Min(WStrLen(Str2), MaxLen); - end; - Result := Tnt_CompareStringW(GetThreadLocale, dwCmpFlags, Str1, Len1, Str2, Len2) - 2; -end; - -function WStrLComp(Str1, Str2: PWideChar; MaxLen: Cardinal): Integer; -begin - Result := WStrComp_EX(Str1, Str2, MaxLen, 0); -end; - -function WStrLIComp(Str1, Str2: PWideChar; MaxLen: Cardinal): Integer; -begin - Result := WStrComp_EX(Str1, Str2, MaxLen, NORM_IGNORECASE); -end; - -function WStrIComp(Str1, Str2: PWideChar): Integer; -begin - Result := WStrLIComp(Str1, Str2, MaxInt); -end; - -function WStrLower(Str: PWideChar): PWideChar; -begin - Result := Str; - Tnt_CharLowerBuffW(Str, WStrLen(Str)) -end; - -function WStrUpper(Str: PWideChar): PWideChar; -begin - Result := Str; - Tnt_CharUpperBuffW(Str, WStrLen(Str)) -end; - -function WStrRScan(const Str: PWideChar; Chr: WideChar): PWideChar; -var - MostRecentFound: PWideChar; -begin - if Chr = #0 then - Result := WStrEnd(Str) - else - begin - Result := nil; - MostRecentFound := Str; - while True do - begin - while MostRecentFound^ <> Chr do - begin - if MostRecentFound^ = #0 then - Exit; - Inc(MostRecentFound); - end; - Result := MostRecentFound; - Inc(MostRecentFound); - end; - end; -end; - -function WStrLCat(Dest: PWideChar; const Source: PWideChar; MaxLen: Cardinal): PWideChar; -begin - Result := Dest; - WStrLCopy(WStrEnd(Dest), Source, MaxLen - WStrLen(Dest)); -end; - -function WStrPas(const Str: PWideChar): WideString; -begin - Result := Str; -end; - -//--------------------------------------------------------------------------------------------- - -{$IFNDEF COMPILER_10_UP} -function WideLastChar(const S: WideString): PWideChar; -begin - if S = '' then - Result := nil - else - Result := @S[Length(S)]; -end; - -function WideQuotedStr(const S: WideString; Quote: WideChar): WideString; -var - P, Src, - Dest: PWideChar; - AddCount: Integer; -begin - AddCount := 0; - P := WStrScan(PWideChar(S), Quote); - while (P <> nil) do - begin - Inc(P); - Inc(AddCount); - P := WStrScan(P, Quote); - end; - - if AddCount = 0 then - Result := Quote + S + Quote - else - begin - SetLength(Result, Length(S) + AddCount + 2); - Dest := PWideChar(Result); - Dest^ := Quote; - Inc(Dest); - Src := PWideChar(S); - P := WStrScan(Src, Quote); - repeat - Inc(P); - Move(Src^, Dest^, 2 * (P - Src)); - Inc(Dest, P - Src); - Dest^ := Quote; - Inc(Dest); - Src := P; - P := WStrScan(Src, Quote); - until P = nil; - P := WStrEnd(Src); - Move(Src^, Dest^, 2 * (P - Src)); - Inc(Dest, P - Src); - Dest^ := Quote; - end; -end; -{$ENDIF} - -{$IFNDEF COMPILER_9_UP} -function WideExtractQuotedStr(var Src: PWideChar; Quote: WideChar): Widestring; -var - P, Dest: PWideChar; - DropCount: Integer; -begin - Result := ''; - if (Src = nil) or (Src^ <> Quote) then Exit; - Inc(Src); - DropCount := 1; - P := Src; - Src := WStrScan(Src, Quote); - while Src <> nil do // count adjacent pairs of quote chars - begin - Inc(Src); - if Src^ <> Quote then Break; - Inc(Src); - Inc(DropCount); - Src := WStrScan(Src, Quote); - end; - if Src = nil then Src := WStrEnd(P); - if ((Src - P) <= 1) then Exit; - if DropCount = 1 then - SetString(Result, P, Src - P - 1) - else - begin - SetLength(Result, Src - P - DropCount); - Dest := PWideChar(Result); - Src := WStrScan(P, Quote); - while Src <> nil do - begin - Inc(Src); - if Src^ <> Quote then Break; - Move(P^, Dest^, (Src - P) * SizeOf(WideChar)); - Inc(Dest, Src - P); - Inc(Src); - P := Src; - Src := WStrScan(Src, Quote); - end; - if Src = nil then Src := WStrEnd(P); - Move(P^, Dest^, (Src - P - 1) * SizeOf(WideChar)); - end; -end; -{$ENDIF} - -{$IFNDEF COMPILER_10_UP} -function WideDequotedStr(const S: WideString; AQuote: WideChar): WideString; -var - LText : PWideChar; -begin - LText := PWideChar(S); - Result := WideExtractQuotedStr(LText, AQuote); - if Result = '' then - Result := S; -end; -{$ENDIF} - - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntWideStrings.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntWideStrings.pas deleted file mode 100644 index ea5b7b0a0..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntWideStrings.pas +++ /dev/null @@ -1,831 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntWideStrings; - -{$INCLUDE TntCompilers.inc} - -interface - -{$IFDEF COMPILER_10_UP} - {$MESSAGE FATAL 'Do not refer to TntWideStrings.pas. It works correctly in Delphi 2006.'} -{$ENDIF} - -uses - Classes; - -{******************************************************************************} -{ } -{ Delphi 2005 introduced TWideStrings in WideStrings.pas. } -{ Unfortunately, it was not ready for prime time. } -{ Setting CommaText is not consistent, and it relies on CharNextW } -{ Which is only available on Windows NT+. } -{ } -{******************************************************************************} - -type - TWideStrings = class; - -{ IWideStringsAdapter interface } -{ Maintains link between TWideStrings and IWideStrings implementations } - - IWideStringsAdapter = interface - ['{25FE0E3B-66CB-48AA-B23B-BCFA67E8F5DA}'] - procedure ReferenceStrings(S: TWideStrings); - procedure ReleaseStrings; - end; - - TWideStringsEnumerator = class - private - FIndex: Integer; - FStrings: TWideStrings; - public - constructor Create(AStrings: TWideStrings); - function GetCurrent: WideString; - function MoveNext: Boolean; - property Current: WideString read GetCurrent; - end; - -{ TWideStrings class } - - TWideStrings = class(TPersistent) - private - FDefined: TStringsDefined; - FDelimiter: WideChar; - FQuoteChar: WideChar; - {$IFDEF COMPILER_7_UP} - FNameValueSeparator: WideChar; - {$ENDIF} - FUpdateCount: Integer; - FAdapter: IWideStringsAdapter; - function GetCommaText: WideString; - function GetDelimitedText: WideString; - function GetName(Index: Integer): WideString; - function GetValue(const Name: WideString): WideString; - procedure ReadData(Reader: TReader); - procedure SetCommaText(const Value: WideString); - procedure SetDelimitedText(const Value: WideString); - procedure SetStringsAdapter(const Value: IWideStringsAdapter); - procedure SetValue(const Name, Value: WideString); - procedure WriteData(Writer: TWriter); - function GetDelimiter: WideChar; - procedure SetDelimiter(const Value: WideChar); - function GetQuoteChar: WideChar; - procedure SetQuoteChar(const Value: WideChar); - function GetNameValueSeparator: WideChar; - {$IFDEF COMPILER_7_UP} - procedure SetNameValueSeparator(const Value: WideChar); - {$ENDIF} - function GetValueFromIndex(Index: Integer): WideString; - procedure SetValueFromIndex(Index: Integer; const Value: WideString); - protected - procedure AssignTo(Dest: TPersistent); override; - procedure DefineProperties(Filer: TFiler); override; - procedure Error(const Msg: WideString; Data: Integer); overload; - procedure Error(Msg: PResStringRec; Data: Integer); overload; - function ExtractName(const S: WideString): WideString; - function Get(Index: Integer): WideString; virtual; abstract; - function GetCapacity: Integer; virtual; - function GetCount: Integer; virtual; abstract; - function GetObject(Index: Integer): TObject; virtual; - function GetTextStr: WideString; virtual; - procedure Put(Index: Integer; const S: WideString); virtual; - procedure PutObject(Index: Integer; AObject: TObject); virtual; - procedure SetCapacity(NewCapacity: Integer); virtual; - procedure SetTextStr(const Value: WideString); virtual; - procedure SetUpdateState(Updating: Boolean); virtual; - property UpdateCount: Integer read FUpdateCount; - function CompareStrings(const S1, S2: WideString): Integer; virtual; - public - destructor Destroy; override; - function Add(const S: WideString): Integer; virtual; - function AddObject(const S: WideString; AObject: TObject): Integer; virtual; - procedure Append(const S: WideString); - procedure AddStrings(Strings: TStrings{TNT-ALLOW TStrings}); overload; virtual; - procedure AddStrings(Strings: TWideStrings); overload; virtual; - procedure Assign(Source: TPersistent); override; - procedure BeginUpdate; - procedure Clear; virtual; abstract; - procedure Delete(Index: Integer); virtual; abstract; - procedure EndUpdate; - function Equals(Strings: TWideStrings): Boolean; - procedure Exchange(Index1, Index2: Integer); virtual; - function GetEnumerator: TWideStringsEnumerator; - function GetTextW: PWideChar; virtual; - function IndexOf(const S: WideString): Integer; virtual; - function IndexOfName(const Name: WideString): Integer; virtual; - function IndexOfObject(AObject: TObject): Integer; virtual; - procedure Insert(Index: Integer; const S: WideString); virtual; abstract; - procedure InsertObject(Index: Integer; const S: WideString; - AObject: TObject); virtual; - procedure LoadFromFile(const FileName: WideString); virtual; - procedure LoadFromStream(Stream: TStream); virtual; - procedure Move(CurIndex, NewIndex: Integer); virtual; - procedure SaveToFile(const FileName: WideString); virtual; - procedure SaveToStream(Stream: TStream); virtual; - procedure SetTextW(const Text: PWideChar); virtual; - property Capacity: Integer read GetCapacity write SetCapacity; - property CommaText: WideString read GetCommaText write SetCommaText; - property Count: Integer read GetCount; - property Delimiter: WideChar read GetDelimiter write SetDelimiter; - property DelimitedText: WideString read GetDelimitedText write SetDelimitedText; - property Names[Index: Integer]: WideString read GetName; - property Objects[Index: Integer]: TObject read GetObject write PutObject; - property QuoteChar: WideChar read GetQuoteChar write SetQuoteChar; - property Values[const Name: WideString]: WideString read GetValue write SetValue; - property ValueFromIndex[Index: Integer]: WideString read GetValueFromIndex write SetValueFromIndex; - property NameValueSeparator: WideChar read GetNameValueSeparator {$IFDEF COMPILER_7_UP} write SetNameValueSeparator {$ENDIF}; - property Strings[Index: Integer]: WideString read Get write Put; default; - property Text: WideString read GetTextStr write SetTextStr; - property StringsAdapter: IWideStringsAdapter read FAdapter write SetStringsAdapter; - end; - - PWideStringItem = ^TWideStringItem; - TWideStringItem = record - FString: WideString; - FObject: TObject; - end; - - PWideStringItemList = ^TWideStringItemList; - TWideStringItemList = array[0..MaxListSize] of TWideStringItem; - -implementation - -uses - Windows, SysUtils, TntSystem, {$IFDEF COMPILER_9_UP} WideStrUtils, {$ELSE} TntWideStrUtils, {$ENDIF} - TntSysUtils, TntClasses; - -{ TWideStringsEnumerator } - -constructor TWideStringsEnumerator.Create(AStrings: TWideStrings); -begin - inherited Create; - FIndex := -1; - FStrings := AStrings; -end; - -function TWideStringsEnumerator.GetCurrent: WideString; -begin - Result := FStrings[FIndex]; -end; - -function TWideStringsEnumerator.MoveNext: Boolean; -begin - Result := FIndex < FStrings.Count - 1; - if Result then - Inc(FIndex); -end; - -{ TWideStrings } - -destructor TWideStrings.Destroy; -begin - StringsAdapter := nil; - inherited; -end; - -function TWideStrings.Add(const S: WideString): Integer; -begin - Result := GetCount; - Insert(Result, S); -end; - -function TWideStrings.AddObject(const S: WideString; AObject: TObject): Integer; -begin - Result := Add(S); - PutObject(Result, AObject); -end; - -procedure TWideStrings.Append(const S: WideString); -begin - Add(S); -end; - -procedure TWideStrings.AddStrings(Strings: TStrings{TNT-ALLOW TStrings}); -var - I: Integer; -begin - BeginUpdate; - try - for I := 0 to Strings.Count - 1 do - AddObject(Strings[I], Strings.Objects[I]); - finally - EndUpdate; - end; -end; - -procedure TWideStrings.AddStrings(Strings: TWideStrings); -var - I: Integer; -begin - BeginUpdate; - try - for I := 0 to Strings.Count - 1 do - AddObject(Strings[I], Strings.Objects[I]); - finally - EndUpdate; - end; -end; - -procedure TWideStrings.Assign(Source: TPersistent); -begin - if Source is TWideStrings then - begin - BeginUpdate; - try - Clear; - FDefined := TWideStrings(Source).FDefined; - {$IFDEF COMPILER_7_UP} - FNameValueSeparator := TWideStrings(Source).FNameValueSeparator; - {$ENDIF} - FQuoteChar := TWideStrings(Source).FQuoteChar; - FDelimiter := TWideStrings(Source).FDelimiter; - AddStrings(TWideStrings(Source)); - finally - EndUpdate; - end; - end - else if Source is TStrings{TNT-ALLOW TStrings} then - begin - BeginUpdate; - try - Clear; - {$IFDEF COMPILER_7_UP} - FNameValueSeparator := WideChar(TStrings{TNT-ALLOW TStrings}(Source).NameValueSeparator); - {$ENDIF} - FQuoteChar := WideChar(TStrings{TNT-ALLOW TStrings}(Source).QuoteChar); - FDelimiter := WideChar(TStrings{TNT-ALLOW TStrings}(Source).Delimiter); - AddStrings(TStrings{TNT-ALLOW TStrings}(Source)); - finally - EndUpdate; - end; - end - else - inherited Assign(Source); -end; - -procedure TWideStrings.AssignTo(Dest: TPersistent); -var - I: Integer; -begin - if Dest is TWideStrings then Dest.Assign(Self) - else if Dest is TStrings{TNT-ALLOW TStrings} then - begin - TStrings{TNT-ALLOW TStrings}(Dest).BeginUpdate; - try - TStrings{TNT-ALLOW TStrings}(Dest).Clear; - {$IFDEF COMPILER_7_UP} - TStrings{TNT-ALLOW TStrings}(Dest).NameValueSeparator := AnsiChar(NameValueSeparator); - {$ENDIF} - TStrings{TNT-ALLOW TStrings}(Dest).QuoteChar := AnsiChar(QuoteChar); - TStrings{TNT-ALLOW TStrings}(Dest).Delimiter := AnsiChar(Delimiter); - for I := 0 to Count - 1 do - TStrings{TNT-ALLOW TStrings}(Dest).AddObject(Strings[I], Objects[I]); - finally - TStrings{TNT-ALLOW TStrings}(Dest).EndUpdate; - end; - end - else - inherited AssignTo(Dest); -end; - -procedure TWideStrings.BeginUpdate; -begin - if FUpdateCount = 0 then SetUpdateState(True); - Inc(FUpdateCount); -end; - -procedure TWideStrings.DefineProperties(Filer: TFiler); - - function DoWrite: Boolean; - begin - if Filer.Ancestor <> nil then - begin - Result := True; - if Filer.Ancestor is TWideStrings then - Result := not Equals(TWideStrings(Filer.Ancestor)) - end - else Result := Count > 0; - end; - -begin - Filer.DefineProperty('Strings', ReadData, WriteData, DoWrite); -end; - -procedure TWideStrings.EndUpdate; -begin - Dec(FUpdateCount); - if FUpdateCount = 0 then SetUpdateState(False); -end; - -function TWideStrings.Equals(Strings: TWideStrings): Boolean; -var - I, Count: Integer; -begin - Result := False; - Count := GetCount; - if Count <> Strings.GetCount then Exit; - for I := 0 to Count - 1 do if Get(I) <> Strings.Get(I) then Exit; - Result := True; -end; - -procedure TWideStrings.Error(const Msg: WideString; Data: Integer); - - function ReturnAddr: Pointer; - asm - MOV EAX,[EBP+4] - end; - -begin - raise EStringListError.CreateFmt(Msg, [Data]) at ReturnAddr; -end; - -procedure TWideStrings.Error(Msg: PResStringRec; Data: Integer); -begin - Error(WideLoadResString(Msg), Data); -end; - -procedure TWideStrings.Exchange(Index1, Index2: Integer); -var - TempObject: TObject; - TempString: WideString; -begin - BeginUpdate; - try - TempString := Strings[Index1]; - TempObject := Objects[Index1]; - Strings[Index1] := Strings[Index2]; - Objects[Index1] := Objects[Index2]; - Strings[Index2] := TempString; - Objects[Index2] := TempObject; - finally - EndUpdate; - end; -end; - -function TWideStrings.ExtractName(const S: WideString): WideString; -var - P: Integer; -begin - Result := S; - P := Pos(NameValueSeparator, Result); - if P <> 0 then - SetLength(Result, P-1) else - SetLength(Result, 0); -end; - -function TWideStrings.GetCapacity: Integer; -begin // descendents may optionally override/replace this default implementation - Result := Count; -end; - -function TWideStrings.GetCommaText: WideString; -var - LOldDefined: TStringsDefined; - LOldDelimiter: WideChar; - LOldQuoteChar: WideChar; -begin - LOldDefined := FDefined; - LOldDelimiter := FDelimiter; - LOldQuoteChar := FQuoteChar; - Delimiter := ','; - QuoteChar := '"'; - try - Result := GetDelimitedText; - finally - FDelimiter := LOldDelimiter; - FQuoteChar := LOldQuoteChar; - FDefined := LOldDefined; - end; -end; - -function TWideStrings.GetDelimitedText: WideString; -var - S: WideString; - P: PWideChar; - I, Count: Integer; -begin - Count := GetCount; - if (Count = 1) and (Get(0) = '') then - Result := WideString(QuoteChar) + QuoteChar - else - begin - Result := ''; - for I := 0 to Count - 1 do - begin - S := Get(I); - P := PWideChar(S); - while not ((P^ in [WideChar(#0)..WideChar(' ')]) or (P^ = QuoteChar) or (P^ = Delimiter)) do - Inc(P); - if (P^ <> #0) then S := WideQuotedStr(S, QuoteChar); - Result := Result + S + Delimiter; - end; - System.Delete(Result, Length(Result), 1); - end; -end; - -function TWideStrings.GetName(Index: Integer): WideString; -begin - Result := ExtractName(Get(Index)); -end; - -function TWideStrings.GetObject(Index: Integer): TObject; -begin - Result := nil; -end; - -function TWideStrings.GetEnumerator: TWideStringsEnumerator; -begin - Result := TWideStringsEnumerator.Create(Self); -end; - -function TWideStrings.GetTextW: PWideChar; -begin - Result := WStrNew(PWideChar(GetTextStr)); -end; - -function TWideStrings.GetTextStr: WideString; -var - I, L, Size, Count: Integer; - P: PWideChar; - S, LB: WideString; -begin - Count := GetCount; - Size := 0; - LB := sLineBreak; - for I := 0 to Count - 1 do Inc(Size, Length(Get(I)) + Length(LB)); - SetString(Result, nil, Size); - P := Pointer(Result); - for I := 0 to Count - 1 do - begin - S := Get(I); - L := Length(S); - if L <> 0 then - begin - System.Move(Pointer(S)^, P^, L * SizeOf(WideChar)); - Inc(P, L); - end; - L := Length(LB); - if L <> 0 then - begin - System.Move(Pointer(LB)^, P^, L * SizeOf(WideChar)); - Inc(P, L); - end; - end; -end; - -function TWideStrings.GetValue(const Name: WideString): WideString; -var - I: Integer; -begin - I := IndexOfName(Name); - if I >= 0 then - Result := Copy(Get(I), Length(Name) + 2, MaxInt) else - Result := ''; -end; - -function TWideStrings.IndexOf(const S: WideString): Integer; -begin - for Result := 0 to GetCount - 1 do - if CompareStrings(Get(Result), S) = 0 then Exit; - Result := -1; -end; - -function TWideStrings.IndexOfName(const Name: WideString): Integer; -var - P: Integer; - S: WideString; -begin - for Result := 0 to GetCount - 1 do - begin - S := Get(Result); - P := Pos(NameValueSeparator, S); - if (P <> 0) and (CompareStrings(Copy(S, 1, P - 1), Name) = 0) then Exit; - end; - Result := -1; -end; - -function TWideStrings.IndexOfObject(AObject: TObject): Integer; -begin - for Result := 0 to GetCount - 1 do - if GetObject(Result) = AObject then Exit; - Result := -1; -end; - -procedure TWideStrings.InsertObject(Index: Integer; const S: WideString; - AObject: TObject); -begin - Insert(Index, S); - PutObject(Index, AObject); -end; - -procedure TWideStrings.LoadFromFile(const FileName: WideString); -var - Stream: TStream; -begin - Stream := TTntFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); - try - LoadFromStream(Stream); - finally - Stream.Free; - end; -end; - -procedure TWideStrings.LoadFromStream(Stream: TStream); -var - Size: Integer; - S: WideString; -begin - BeginUpdate; - try - Size := Stream.Size - Stream.Position; - SetString(S, nil, Size div SizeOf(WideChar)); - Stream.Read(Pointer(S)^, Length(S) * SizeOf(WideChar)); - SetTextStr(S); - finally - EndUpdate; - end; -end; - -procedure TWideStrings.Move(CurIndex, NewIndex: Integer); -var - TempObject: TObject; - TempString: WideString; -begin - if CurIndex <> NewIndex then - begin - BeginUpdate; - try - TempString := Get(CurIndex); - TempObject := GetObject(CurIndex); - Delete(CurIndex); - InsertObject(NewIndex, TempString, TempObject); - finally - EndUpdate; - end; - end; -end; - -procedure TWideStrings.Put(Index: Integer; const S: WideString); -var - TempObject: TObject; -begin - TempObject := GetObject(Index); - Delete(Index); - InsertObject(Index, S, TempObject); -end; - -procedure TWideStrings.PutObject(Index: Integer; AObject: TObject); -begin -end; - -procedure TWideStrings.ReadData(Reader: TReader); -begin - if Reader.NextValue in [vaString, vaLString] then - SetTextStr(Reader.ReadString) {JCL compatiblity} - else if Reader.NextValue = vaWString then - SetTextStr(Reader.ReadWideString) {JCL compatiblity} - else begin - BeginUpdate; - try - Clear; - Reader.ReadListBegin; - while not Reader.EndOfList do - if Reader.NextValue in [vaString, vaLString] then - Add(Reader.ReadString) {TStrings compatiblity} - else - Add(Reader.ReadWideString); - Reader.ReadListEnd; - finally - EndUpdate; - end; - end; -end; - -procedure TWideStrings.SaveToFile(const FileName: WideString); -var - Stream: TStream; -begin - Stream := TTntFileStream.Create(FileName, fmCreate); - try - SaveToStream(Stream); - finally - Stream.Free; - end; -end; - -procedure TWideStrings.SaveToStream(Stream: TStream); -var - SW: WideString; -begin - SW := GetTextStr; - Stream.WriteBuffer(PWideChar(SW)^, Length(SW) * SizeOf(WideChar)); -end; - -procedure TWideStrings.SetCapacity(NewCapacity: Integer); -begin - // do nothing - descendents may optionally implement this method -end; - -procedure TWideStrings.SetCommaText(const Value: WideString); -begin - Delimiter := ','; - QuoteChar := '"'; - SetDelimitedText(Value); -end; - -procedure TWideStrings.SetStringsAdapter(const Value: IWideStringsAdapter); -begin - if FAdapter <> nil then FAdapter.ReleaseStrings; - FAdapter := Value; - if FAdapter <> nil then FAdapter.ReferenceStrings(Self); -end; - -procedure TWideStrings.SetTextW(const Text: PWideChar); -begin - SetTextStr(Text); -end; - -procedure TWideStrings.SetTextStr(const Value: WideString); -var - P, Start: PWideChar; - S: WideString; -begin - BeginUpdate; - try - Clear; - P := Pointer(Value); - if P <> nil then - while P^ <> #0 do - begin - Start := P; - while not (P^ in [WideChar(#0), WideChar(#10), WideChar(#13)]) and (P^ <> WideLineSeparator) do - Inc(P); - SetString(S, Start, P - Start); - Add(S); - if P^ = #13 then Inc(P); - if P^ = #10 then Inc(P); - if P^ = WideLineSeparator then Inc(P); - end; - finally - EndUpdate; - end; -end; - -procedure TWideStrings.SetUpdateState(Updating: Boolean); -begin -end; - -procedure TWideStrings.SetValue(const Name, Value: WideString); -var - I: Integer; -begin - I := IndexOfName(Name); - if Value <> '' then - begin - if I < 0 then I := Add(''); - Put(I, Name + NameValueSeparator + Value); - end else - begin - if I >= 0 then Delete(I); - end; -end; - -procedure TWideStrings.WriteData(Writer: TWriter); -var - I: Integer; -begin - Writer.WriteListBegin; - for I := 0 to Count-1 do begin - Writer.WriteWideString(Get(I)); - end; - Writer.WriteListEnd; -end; - -procedure TWideStrings.SetDelimitedText(const Value: WideString); -var - P, P1: PWideChar; - S: WideString; -begin - BeginUpdate; - try - Clear; - P := PWideChar(Value); - while P^ in [WideChar(#1)..WideChar(' ')] do - Inc(P); - while P^ <> #0 do - begin - if P^ = QuoteChar then - S := WideExtractQuotedStr(P, QuoteChar) - else - begin - P1 := P; - while (P^ > ' ') and (P^ <> Delimiter) do - Inc(P); - SetString(S, P1, P - P1); - end; - Add(S); - while P^ in [WideChar(#1)..WideChar(' ')] do - Inc(P); - if P^ = Delimiter then - begin - P1 := P; - Inc(P1); - if P1^ = #0 then - Add(''); - repeat - Inc(P); - until not (P^ in [WideChar(#1)..WideChar(' ')]); - end; - end; - finally - EndUpdate; - end; -end; - -function TWideStrings.GetDelimiter: WideChar; -begin - if not (sdDelimiter in FDefined) then - Delimiter := ','; - Result := FDelimiter; -end; - -function TWideStrings.GetQuoteChar: WideChar; -begin - if not (sdQuoteChar in FDefined) then - QuoteChar := '"'; - Result := FQuoteChar; -end; - -procedure TWideStrings.SetDelimiter(const Value: WideChar); -begin - if (FDelimiter <> Value) or not (sdDelimiter in FDefined) then - begin - Include(FDefined, sdDelimiter); - FDelimiter := Value; - end -end; - -procedure TWideStrings.SetQuoteChar(const Value: WideChar); -begin - if (FQuoteChar <> Value) or not (sdQuoteChar in FDefined) then - begin - Include(FDefined, sdQuoteChar); - FQuoteChar := Value; - end -end; - -function TWideStrings.CompareStrings(const S1, S2: WideString): Integer; -begin - Result := WideCompareText(S1, S2); -end; - -function TWideStrings.GetNameValueSeparator: WideChar; -begin - {$IFDEF COMPILER_7_UP} - if not (sdNameValueSeparator in FDefined) then - NameValueSeparator := '='; - Result := FNameValueSeparator; - {$ELSE} - Result := '='; - {$ENDIF} -end; - -{$IFDEF COMPILER_7_UP} -procedure TWideStrings.SetNameValueSeparator(const Value: WideChar); -begin - if (FNameValueSeparator <> Value) or not (sdNameValueSeparator in FDefined) then - begin - Include(FDefined, sdNameValueSeparator); - FNameValueSeparator := Value; - end -end; -{$ENDIF} - -function TWideStrings.GetValueFromIndex(Index: Integer): WideString; -begin - if Index >= 0 then - Result := Copy(Get(Index), Length(Names[Index]) + 2, MaxInt) else - Result := ''; -end; - -procedure TWideStrings.SetValueFromIndex(Index: Integer; const Value: WideString); -begin - if Value <> '' then - begin - if Index < 0 then Index := Add(''); - Put(Index, Names[Index] + NameValueSeparator + Value); - end - else - if Index >= 0 then Delete(Index); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntWindows.pas b/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntWindows.pas deleted file mode 100644 index 3ae9133a3..000000000 --- a/CORE/Source/Plugins/Htmlviewer/Extras/TntUnicode/Source/TntWindows.pas +++ /dev/null @@ -1,1452 +0,0 @@ - -{*****************************************************************************} -{ } -{ Tnt Delphi Unicode Controls } -{ http://www.tntware.com/delphicontrols/unicode/ } -{ Version: 2.3.0 } -{ } -{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } -{ } -{*****************************************************************************} - -unit TntWindows; - -{$INCLUDE TntCompilers.inc} - -interface - -uses - Windows, ShellApi, ShlObj; - -// ......... compatibility - -const - DT_NOFULLWIDTHCHARBREAK = $00080000; - -const - INVALID_FILE_ATTRIBUTES = DWORD(-1); - -// ................ ANSI TYPES ................ -{TNT-WARN LPSTR} -{TNT-WARN PLPSTR} -{TNT-WARN LPCSTR} -{TNT-WARN LPCTSTR} -{TNT-WARN LPTSTR} - -// ........ EnumResourceTypesW, EnumResourceNamesW and EnumResourceLanguagesW are supposed .... -// ........ to work on Win95/98/ME but have caused access violations in testing on Win95 ...... -// .. TNT--WARN EnumResourceTypes .. -// .. TNT--WARN EnumResourceTypesA .. -// .. TNT--WARN EnumResourceNames .. -// .. TNT--WARN EnumResourceNamesA .. -// .. TNT--WARN EnumResourceLanguages .. -// .. TNT--WARN EnumResourceLanguagesA .. - -//------------------------------------------------------------------------------------------ - -// ......... The Unicode form of these functions are supported on Windows 95/98/ME ......... -{TNT-WARN ExtTextOut} -{TNT-WARN ExtTextOutA} -{TNT-WARN Tnt_ExtTextOutW} - -{TNT-WARN FindResource} -{TNT-WARN FindResourceA} -{TNT-WARN Tnt_FindResourceW} - -{TNT-WARN FindResourceEx} -{TNT-WARN FindResourceExA} -{TNT-WARN Tnt_FindResourceExW} - -{TNT-WARN GetCharWidth} -{TNT-WARN GetCharWidthA} -{TNT-WARN Tnt_GetCharWidthW} - -{TNT-WARN GetCommandLine} -{TNT-WARN GetCommandLineA} -{TNT-WARN Tnt_GetCommandLineW} - -{TNT-WARN GetTextExtentPoint} -{TNT-WARN GetTextExtentPointA} -{TNT-WARN Tnt_GetTextExtentPointW} - -{TNT-WARN GetTextExtentPoint32} -{TNT-WARN GetTextExtentPoint32A} -{TNT-WARN Tnt_GetTextExtentPoint32W} - -{TNT-WARN lstrcat} -{TNT-WARN lstrcatA} -{TNT-WARN Tnt_lstrcatW} - -{TNT-WARN lstrcpy} -{TNT-WARN lstrcpyA} -{TNT-WARN Tnt_lstrcpyW} - -{TNT-WARN lstrlen} -{TNT-WARN lstrlenA} -{TNT-WARN Tnt_lstrlenW} - -{TNT-WARN MessageBox} -{TNT-WARN MessageBoxA} -{TNT-WARN Tnt_MessageBoxW} - -{TNT-WARN MessageBoxEx} -{TNT-WARN MessageBoxExA} -{TNT-WARN Tnt_MessageBoxExA} - -{TNT-WARN TextOut} -{TNT-WARN TextOutA} -{TNT-WARN Tnt_TextOutW} - -//------------------------------------------------------------------------------------------ - -{TNT-WARN LOCALE_USER_DEFAULT} // <-- use GetThreadLocale -{TNT-WARN LOCALE_SYSTEM_DEFAULT} // <-- use GetThreadLocale - -//------------------------------------------------------------------------------------------ -// compatiblity -//------------------------------------------------------------------------------------------ -{$IFNDEF COMPILER_9_UP} -type - TStartupInfoA = _STARTUPINFOA; - TStartupInfoW = record - cb: DWORD; - lpReserved: PWideChar; - lpDesktop: PWideChar; - lpTitle: PWideChar; - dwX: DWORD; - dwY: DWORD; - dwXSize: DWORD; - dwYSize: DWORD; - dwXCountChars: DWORD; - dwYCountChars: DWORD; - dwFillAttribute: DWORD; - dwFlags: DWORD; - wShowWindow: Word; - cbReserved2: Word; - lpReserved2: PByte; - hStdInput: THandle; - hStdOutput: THandle; - hStdError: THandle; - end; - -function CreateProcessW{TNT-ALLOW CreateProcessW}(lpApplicationName: PWideChar; lpCommandLine: PWideChar; - lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; - bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer; - lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfoW; - var lpProcessInformation: TProcessInformation): BOOL; stdcall; external kernel32 name 'CreateProcessW'; - -{$ENDIF} -//------------------------------------------------------------------------------------------ - -{TNT-WARN SetWindowText} -{TNT-WARN SetWindowTextA} -{TNT-WARN SetWindowTextW} -function Tnt_SetWindowTextW(hWnd: HWND; lpString: PWideChar): BOOL; - -{TNT-WARN RemoveDirectory} -{TNT-WARN RemoveDirectoryA} -{TNT-WARN RemoveDirectoryW} -function Tnt_RemoveDirectoryW(lpPathName: PWideChar): BOOL; - -{TNT-WARN GetShortPathName} -{TNT-WARN GetShortPathNameA} -{TNT-WARN GetShortPathNameW} -function Tnt_GetShortPathNameW(lpszLongPath: PWideChar; lpszShortPath: PWideChar; - cchBuffer: DWORD): DWORD; - -{TNT-WARN GetFullPathName} -{TNT-WARN GetFullPathNameA} -{TNT-WARN GetFullPathNameW} -function Tnt_GetFullPathNameW(lpFileName: PWideChar; nBufferLength: DWORD; - lpBuffer: PWideChar; var lpFilePart: PWideChar): DWORD; - -{TNT-WARN CreateFile} -{TNT-WARN CreateFileA} -{TNT-WARN CreateFileW} -function Tnt_CreateFileW(lpFileName: PWideChar; dwDesiredAccess, dwShareMode: DWORD; - lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; - hTemplateFile: THandle): THandle; - -{TNT-WARN FindFirstFile} -{TNT-WARN FindFirstFileA} -{TNT-WARN FindFirstFileW} -function Tnt_FindFirstFileW(lpFileName: PWideChar; var lpFindFileData: TWIN32FindDataW): THandle; - -{TNT-WARN FindNextFile} -{TNT-WARN FindNextFileA} -{TNT-WARN FindNextFileW} -function Tnt_FindNextFileW(hFindFile: THandle; var lpFindFileData: TWIN32FindDataW): BOOL; - -{TNT-WARN GetFileAttributes} -{TNT-WARN GetFileAttributesA} -{TNT-WARN GetFileAttributesW} -function Tnt_GetFileAttributesW(lpFileName: PWideChar): DWORD; - -{TNT-WARN SetFileAttributes} -{TNT-WARN SetFileAttributesA} -{TNT-WARN SetFileAttributesW} -function Tnt_SetFileAttributesW(lpFileName: PWideChar; dwFileAttributes: DWORD): BOOL; - -{TNT-WARN CreateDirectory} -{TNT-WARN CreateDirectoryA} -{TNT-WARN CreateDirectoryW} -function Tnt_CreateDirectoryW(lpPathName: PWideChar; - lpSecurityAttributes: PSecurityAttributes): BOOL; - -{TNT-WARN MoveFile} -{TNT-WARN MoveFileA} -{TNT-WARN MoveFileW} -function Tnt_MoveFileW(lpExistingFileName, lpNewFileName: PWideChar): BOOL; - -{TNT-WARN CopyFile} -{TNT-WARN CopyFileA} -{TNT-WARN CopyFileW} -function Tnt_CopyFileW(lpExistingFileName, lpNewFileName: PWideChar; bFailIfExists: BOOL): BOOL; - -{TNT-WARN DeleteFile} -{TNT-WARN DeleteFileA} -{TNT-WARN DeleteFileW} -function Tnt_DeleteFileW(lpFileName: PWideChar): BOOL; - -{TNT-WARN DrawText} -{TNT-WARN DrawTextA} -{TNT-WARN DrawTextW} -function Tnt_DrawTextW(hDC: HDC; lpString: PWideChar; nCount: Integer; - var lpRect: TRect; uFormat: UINT): Integer; - -{TNT-WARN GetDiskFreeSpace} -{TNT-WARN GetDiskFreeSpaceA} -{TNT-WARN GetDiskFreeSpaceW} -function Tnt_GetDiskFreeSpaceW(lpRootPathName: PWideChar; var lpSectorsPerCluster, - lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters: DWORD): BOOL; - -{TNT-WARN GetVolumeInformation} -{TNT-WARN GetVolumeInformationA} -{TNT-WARN GetVolumeInformationW} -function Tnt_GetVolumeInformationW(lpRootPathName: PWideChar; lpVolumeNameBuffer: PWideChar; - nVolumeNameSize: DWORD; lpVolumeSerialNumber: PDWORD; - var lpMaximumComponentLength, lpFileSystemFlags: DWORD; lpFileSystemNameBuffer: PWideChar; - nFileSystemNameSize: DWORD): BOOL; - -{TNT-WARN GetModuleFileName} -{TNT-WARN GetModuleFileNameA} -{TNT-WARN GetModuleFileNameW} -function Tnt_GetModuleFileNameW(hModule: HINST; lpFilename: PWideChar; nSize: DWORD): DWORD; - -{TNT-WARN GetTempPath} -{TNT-WARN GetTempPathA} -{TNT-WARN GetTempPathW} -function Tnt_GetTempPathW(nBufferLength: DWORD; lpBuffer: PWideChar): DWORD; - -{TNT-WARN GetTempFileName} -{TNT-WARN GetTempFileNameA} -{TNT-WARN GetTempFileNameW} -function Tnt_GetTempFileNameW(lpPathName, lpPrefixString: PWideChar; uUnique: UINT; - lpTempFileName: PWideChar): UINT; - -{TNT-WARN GetWindowsDirectory} -{TNT-WARN GetWindowsDirectoryA} -{TNT-WARN GetWindowsDirectoryW} -function Tnt_GetWindowsDirectoryW(lpBuffer: PWideChar; uSize: UINT): UINT; - -{TNT-WARN GetSystemDirectory} -{TNT-WARN GetSystemDirectoryA} -{TNT-WARN GetSystemDirectoryW} -function Tnt_GetSystemDirectoryW(lpBuffer: PWideChar; uSize: UINT): UINT; - -{TNT-WARN GetCurrentDirectory} -{TNT-WARN GetCurrentDirectoryA} -{TNT-WARN GetCurrentDirectoryW} -function Tnt_GetCurrentDirectoryW(nBufferLength: DWORD; lpBuffer: PWideChar): DWORD; - -{TNT-WARN SetCurrentDirectory} -{TNT-WARN SetCurrentDirectoryA} -{TNT-WARN SetCurrentDirectoryW} -function Tnt_SetCurrentDirectoryW(lpPathName: PWideChar): BOOL; - -{TNT-WARN GetComputerName} -{TNT-WARN GetComputerNameA} -{TNT-WARN GetComputerNameW} -function Tnt_GetComputerNameW(lpBuffer: PWideChar; var nSize: DWORD): BOOL; - -{TNT-WARN GetUserName} -{TNT-WARN GetUserNameA} -{TNT-WARN GetUserNameW} -function Tnt_GetUserNameW(lpBuffer: PWideChar; var nSize: DWORD): BOOL; - -{TNT-WARN ShellExecute} -{TNT-WARN ShellExecuteA} -{TNT-WARN ShellExecuteW} -function Tnt_ShellExecuteW(hWnd: HWND; Operation, FileName, Parameters, - Directory: PWideChar; ShowCmd: Integer): HINST; - -{TNT-WARN LoadLibrary} -{TNT-WARN LoadLibraryA} -{TNT-WARN LoadLibraryW} -function Tnt_LoadLibraryW(lpLibFileName: PWideChar): HMODULE; - -{TNT-WARN LoadLibraryEx} -{TNT-WARN LoadLibraryExA} -{TNT-WARN LoadLibraryExW} -function Tnt_LoadLibraryExW(lpLibFileName: PWideChar; hFile: THandle; dwFlags: DWORD): HMODULE; - -{TNT-WARN CreateProcess} -{TNT-WARN CreateProcessA} -{TNT-WARN CreateProcessW} -function Tnt_CreateProcessW(lpApplicationName: PWideChar; lpCommandLine: PWideChar; - lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; - bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer; - lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfoW; - var lpProcessInformation: TProcessInformation): BOOL; - -{TNT-WARN GetCurrencyFormat} -{TNT-WARN GetCurrencyFormatA} -{TNT-WARN GetCurrencyFormatW} -function Tnt_GetCurrencyFormatW(Locale: LCID; dwFlags: DWORD; lpValue: PWideChar; - lpFormat: PCurrencyFmtW; lpCurrencyStr: PWideChar; cchCurrency: Integer): Integer; - -{TNT-WARN CompareString} -{TNT-WARN CompareStringA} -{TNT-WARN CompareStringW} -function Tnt_CompareStringW(Locale: LCID; dwCmpFlags: DWORD; lpString1: PWideChar; - cchCount1: Integer; lpString2: PWideChar; cchCount2: Integer): Integer; - -{TNT-WARN CharUpper} -{TNT-WARN CharUpperA} -{TNT-WARN CharUpperW} -function Tnt_CharUpperW(lpsz: PWideChar): PWideChar; - -{TNT-WARN CharUpperBuff} -{TNT-WARN CharUpperBuffA} -{TNT-WARN CharUpperBuffW} -function Tnt_CharUpperBuffW(lpsz: PWideChar; cchLength: DWORD): DWORD; - -{TNT-WARN CharLower} -{TNT-WARN CharLowerA} -{TNT-WARN CharLowerW} -function Tnt_CharLowerW(lpsz: PWideChar): PWideChar; - -{TNT-WARN CharLowerBuff} -{TNT-WARN CharLowerBuffA} -{TNT-WARN CharLowerBuffW} -function Tnt_CharLowerBuffW(lpsz: PWideChar; cchLength: DWORD): DWORD; - -{TNT-WARN GetStringTypeEx} -{TNT-WARN GetStringTypeExA} -{TNT-WARN GetStringTypeExW} -function Tnt_GetStringTypeExW(Locale: LCID; dwInfoType: DWORD; - lpSrcStr: PWideChar; cchSrc: Integer; var lpCharType): BOOL; - -{TNT-WARN LoadString} -{TNT-WARN LoadStringA} -{TNT-WARN LoadStringW} -function Tnt_LoadStringW(hInstance: HINST; uID: UINT; lpBuffer: PWideChar; nBufferMax: Integer): Integer; - -{TNT-WARN InsertMenuItem} -{TNT-WARN InsertMenuItemA} -{TNT-WARN InsertMenuItemW} -function Tnt_InsertMenuItemW(hMenu: HMENU; uItem: DWORD; fByPosition: BOOL; lpmii: tagMenuItemINFOW): BOOL; - -{TNT-WARN ExtractIconEx} -{TNT-WARN ExtractIconExA} -{TNT-WARN ExtractIconExW} -function Tnt_ExtractIconExW(lpszFile: PWideChar; nIconIndex: Integer; - var phiconLarge, phiconSmall: HICON; nIcons: UINT): UINT; - -{TNT-WARN ExtractAssociatedIcon} -{TNT-WARN ExtractAssociatedIconA} -{TNT-WARN ExtractAssociatedIconW} -function Tnt_ExtractAssociatedIconW(hInst: HINST; lpIconPath: PWideChar; - var lpiIcon: Word): HICON; - -{TNT-WARN GetFileVersionInfoSize} -{TNT-WARN GetFileVersionInfoSizeA} -{TNT-WARN GetFileVersionInfoSizeW} -function Tnt_GetFileVersionInfoSizeW(lptstrFilename: PWideChar; var lpdwHandle: DWORD): DWORD; - -{TNT-WARN GetFileVersionInfo} -{TNT-WARN GetFileVersionInfoA} -{TNT-WARN GetFileVersionInfoW} -function Tnt_GetFileVersionInfoW(lptstrFilename: PWideChar; dwHandle, dwLen: DWORD; - lpData: Pointer): BOOL; - -const - VQV_FIXEDFILEINFO = '\'; - VQV_VARFILEINFO_TRANSLATION = '\VarFileInfo\Translation'; - VQV_STRINGFILEINFO = '\StringFileInfo'; - - VER_COMMENTS = 'Comments'; - VER_INTERNALNAME = 'InternalName'; - VER_PRODUCTNAME = 'ProductName'; - VER_COMPANYNAME = 'CompanyName'; - VER_LEGALCOPYRIGHT = 'LegalCopyright'; - VER_PRODUCTVERSION = 'ProductVersion'; - VER_FILEDESCRIPTION = 'FileDescription'; - VER_LEGALTRADEMARKS = 'LegalTrademarks'; - VER_PRIVATEBUILD = 'PrivateBuild'; - VER_FILEVERSION = 'FileVersion'; - VER_ORIGINALFILENAME = 'OriginalFilename'; - VER_SPECIALBUILD = 'SpecialBuild'; - -{TNT-WARN VerQueryValue} -{TNT-WARN VerQueryValueA} -{TNT-WARN VerQueryValueW} -function Tnt_VerQueryValueW(pBlock: Pointer; lpSubBlock: PWideChar; - var lplpBuffer: Pointer; var puLen: UINT): BOOL; - -type - TSHNameMappingHeaderA = record - cNumOfMappings: Cardinal; - lpNM: PSHNAMEMAPPINGA; - end; - PSHNameMappingHeaderA = ^TSHNameMappingHeaderA; - - TSHNameMappingHeaderW = record - cNumOfMappings: Cardinal; - lpNM: PSHNAMEMAPPINGW; - end; - PSHNameMappingHeaderW = ^TSHNameMappingHeaderW; - -{TNT-WARN SHFileOperation} -{TNT-WARN SHFileOperationA} -{TNT-WARN SHFileOperationW} // <-- no stub on early Windows 95 -function Tnt_SHFileOperationW(var lpFileOp: TSHFileOpStructW): Integer; - -{TNT-WARN SHFreeNameMappings} -procedure Tnt_SHFreeNameMappings(hNameMappings: THandle); - -{TNT-WARN SHBrowseForFolder} -{TNT-WARN SHBrowseForFolderA} -{TNT-WARN SHBrowseForFolderW} // <-- no stub on early Windows 95 -function Tnt_SHBrowseForFolderW(var lpbi: TBrowseInfoW): PItemIDList; - -{TNT-WARN SHGetPathFromIDList} -{TNT-WARN SHGetPathFromIDListA} -{TNT-WARN SHGetPathFromIDListW} // <-- no stub on early Windows 95 -function Tnt_SHGetPathFromIDListW(pidl: PItemIDList; pszPath: PWideChar): BOOL; - -{TNT-WARN SHGetFileInfo} -{TNT-WARN SHGetFileInfoA} -{TNT-WARN SHGetFileInfoW} // <-- no stub on early Windows 95 -function Tnt_SHGetFileInfoW(pszPath: PWideChar; dwFileAttributes: DWORD; - var psfi: TSHFileInfoW; cbFileInfo, uFlags: UINT): DWORD; - -// ......... introduced ......... -function Tnt_Is_IntResource(ResStr: LPCWSTR): Boolean; - -function LANGIDFROMLCID(lcid: LCID): WORD; -function MAKELANGID(usPrimaryLanguage, usSubLanguage: WORD): WORD; -function MAKELCID(wLanguageID: WORD; wSortID: WORD = SORT_DEFAULT): LCID; -function PRIMARYLANGID(lgid: WORD): WORD; -function SORTIDFROMLCID(lcid: LCID): WORD; -function SUBLANGID(lgid: WORD): WORD; - -implementation - -uses - SysUtils, Math, TntSysUtils, - {$IFDEF COMPILER_9_UP} WideStrUtils, {$ENDIF} TntWideStrUtils; - -function _PAnsiCharWithNil(const S: AnsiString): PAnsiChar; -begin - if S = '' then - Result := nil {Win9x needs nil for some parameters instead of empty strings} - else - Result := PAnsiChar(S); -end; - -function _PWideCharWithNil(const S: WideString): PWideChar; -begin - if S = '' then - Result := nil {Win9x needs nil for some parameters instead of empty strings} - else - Result := PWideChar(S); -end; - -function _WStr(lpString: PWideChar; cchCount: Integer): WideString; -begin - if cchCount = -1 then - Result := lpString - else - Result := Copy(WideString(lpString), 1, cchCount); -end; - -procedure _MakeWideWin32FindData(var WideFindData: TWIN32FindDataW; AnsiFindData: TWIN32FindDataA); -begin - CopyMemory(@WideFindData, @AnsiFindData, - Integer(@WideFindData.cFileName) - Integer(@WideFindData)); - WStrPCopy(WideFindData.cFileName, AnsiFindData.cFileName); - WStrPCopy(WideFindData.cAlternateFileName, AnsiFindData.cAlternateFileName); -end; - -function Tnt_SetWindowTextW(hWnd: HWND; lpString: PWideChar): BOOL; -begin - if Win32PlatformIsUnicode then - Result := SetWindowTextW{TNT-ALLOW SetWindowTextW}(hWnd, lpString) - else - Result := SetWindowTextA{TNT-ALLOW SetWindowTextA}(hWnd, PAnsiChar(AnsiString(lpString))); -end; - -//----------------------------- - -type - TPathLengthResultOption = (poAllowDirectoryMode, poZeroSmallBuff, poExactCopy, poExactCopySubPaths); - TPathLengthResultOptions = set of TPathLengthResultOption; - -procedure _ExactStrCopyW(pDest, pSource: PWideChar; Count: Integer); -var - i: integer; -begin - for i := 1 to Count do begin - pDest^ := pSource^; - Inc(PSource); - Inc(pDest); - end; -end; - -procedure _ExactCopySubPaths(pDest, pSource: PWideChar; Count: Integer); -var - i: integer; - OriginalSource: PWideChar; - PNextSlash: PWideChar; -begin - if Count >= 4 then begin - OriginalSource := pSource; - PNextSlash := WStrScan(pSource, '\'); - for i := 1 to Count - 1 do begin - // determine next path delimiter - if pSource > pNextSlash then begin - PNextSlash := WStrScan(pSource, '\'); - end; - // leave if no more sub paths - if (PNextSlash = nil) - or ((pNextSlash - OriginalSource) >= Count) then begin - exit; - end; - // copy char - pDest^ := pSource^; - Inc(PSource); - Inc(pDest); - end; - end; -end; - -function _HandlePathLengthResult(nBufferLength: DWORD; lpBuffer: PWideChar; const AnsiBuff: AnsiString; Options: TPathLengthResultOptions): Integer; -var - WideBuff: WideString; -begin - WideBuff := AnsiBuff; - if nBufferLength > Cardinal(Length(WideBuff)) then begin - // normal - Result := Length(WideBuff); - WStrLCopy(lpBuffer, PWideChar(WideBuff), nBufferLength); - end else if (poExactCopy in Options) then begin - // exact - Result := nBufferLength; - _ExactStrCopyW(lpBuffer, PWideChar(WideBuff), nBufferLength); - end else begin - // other - if (poAllowDirectoryMode in Options) - and (nBufferLength = Cardinal(Length(WideBuff))) then begin - Result := Length(WideBuff) + 1; - WStrLCopy(lpBuffer, PWideChar(WideBuff), nBufferLength - 1); - end else begin - Result := Length(WideBuff) + 1; - if (nBufferLength > 0) then begin - if (poZeroSmallBuff in Options) then - lpBuffer^ := #0 - else if (poExactCopySubPaths in Options) then - _ExactCopySubPaths(lpBuffer, PWideChar(WideBuff), nBufferLength); - end; - end; - end; -end; - -function _HandleStringLengthResult(nBufferLength: DWORD; lpBuffer: PWideChar; const AnsiBuff: AnsiString; Options: TPathLengthResultOptions): Integer; -var - WideBuff: WideString; -begin - WideBuff := AnsiBuff; - if nBufferLength >= Cardinal(Length(WideBuff)) then begin - // normal - Result := Length(WideBuff); - WStrLCopy(lpBuffer, PWideChar(WideBuff), nBufferLength); - end else if nBufferLength = 0 then - Result := Length(WideBuff) - else - Result := 0; -end; - -//------------------------------------------- - -function Tnt_RemoveDirectoryW(lpPathName: PWideChar): BOOL; -begin - if Win32PlatformIsUnicode then - Result := RemoveDirectoryW{TNT-ALLOW RemoveDirectoryW}(PWideChar(lpPathName)) - else - Result := RemoveDirectoryA{TNT-ALLOW RemoveDirectoryA}(PAnsiChar(AnsiString(lpPathName))); -end; - -function Tnt_GetShortPathNameW(lpszLongPath: PWideChar; lpszShortPath: PWideChar; - cchBuffer: DWORD): DWORD; -var - AnsiBuff: AnsiString; -begin - if Win32PlatformIsUnicode then - Result := GetShortPathNameW{TNT-ALLOW GetShortPathNameW}(lpszLongPath, lpszShortPath, cchBuffer) - else begin - SetLength(AnsiBuff, MAX_PATH * 2); - SetLength(AnsiBuff, GetShortPathNameA{TNT-ALLOW GetShortPathNameA}(PAnsiChar(AnsiString(lpszLongPath)), - PAnsiChar(AnsiBuff), Length(AnsiBuff))); - Result := _HandlePathLengthResult(cchBuffer, lpszShortPath, AnsiBuff, [poExactCopySubPaths]); - end; -end; - -function Tnt_GetFullPathNameW(lpFileName: PWideChar; nBufferLength: DWORD; - lpBuffer: PWideChar; var lpFilePart: PWideChar): DWORD; -var - AnsiBuff: AnsiString; - AnsiFilePart: PAnsiChar; - AnsiLeadingChars: Integer; - WideLeadingChars: Integer; -begin - if Win32PlatformIsUnicode then - Result := GetFullPathNameW{TNT-ALLOW GetFullPathNameW}(lpFileName, nBufferLength, lpBuffer, lpFilePart) - else begin - SetLength(AnsiBuff, MAX_PATH * 2); - SetLength(AnsiBuff, GetFullPathNameA{TNT-ALLOW GetFullPathNameA}(PAnsiChar(AnsiString(lpFileName)), - Length(AnsiBuff), PAnsiChar(AnsiBuff), AnsiFilePart)); - Result := _HandlePathLengthResult(nBufferLength, lpBuffer, AnsiBuff, [poZeroSmallBuff]); - // deal w/ lpFilePart - if (AnsiFilePart = nil) or (nBufferLength < Result) then - lpFilePart := nil - else begin - AnsiLeadingChars := AnsiFilePart - PAnsiChar(AnsiBuff); - WideLeadingChars := Length(WideString(Copy(AnsiBuff, 1, AnsiLeadingChars))); - lpFilePart := lpBuffer + WideLeadingChars; - end; - end; -end; - -function Tnt_CreateFileW(lpFileName: PWideChar; dwDesiredAccess, dwShareMode: DWORD; - lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; - hTemplateFile: THandle): THandle; -begin - if Win32PlatformIsUnicode then - Result := CreateFileW{TNT-ALLOW CreateFileW}(lpFileName, dwDesiredAccess, dwShareMode, - lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile) - else - Result := CreateFileA{TNT-ALLOW CreateFileA}(PAnsiChar(AnsiString(lpFileName)), dwDesiredAccess, dwShareMode, - lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile) -end; - -function Tnt_FindFirstFileW(lpFileName: PWideChar; var lpFindFileData: TWIN32FindDataW): THandle; -var - Ansi_lpFindFileData: TWIN32FindDataA; -begin - if Win32PlatformIsUnicode then - Result := FindFirstFileW{TNT-ALLOW FindFirstFileW}(lpFileName, lpFindFileData) - else begin - Result := FindFirstFileA{TNT-ALLOW FindFirstFileA}(PAnsiChar(AnsiString(lpFileName)), - Ansi_lpFindFileData); - if Result <> INVALID_HANDLE_VALUE then - _MakeWideWin32FindData(lpFindFileData, Ansi_lpFindFileData); - end; -end; - -function Tnt_FindNextFileW(hFindFile: THandle; var lpFindFileData: TWIN32FindDataW): BOOL; -var - Ansi_lpFindFileData: TWIN32FindDataA; -begin - if Win32PlatformIsUnicode then - Result := FindNextFileW{TNT-ALLOW FindNextFileW}(hFindFile, lpFindFileData) - else begin - Result := FindNextFileA{TNT-ALLOW FindNextFileA}(hFindFile, Ansi_lpFindFileData); - if Result then - _MakeWideWin32FindData(lpFindFileData, Ansi_lpFindFileData); - end; -end; - -function Tnt_GetFileAttributesW(lpFileName: PWideChar): DWORD; -begin - if Win32PlatformIsUnicode then - Result := GetFileAttributesW{TNT-ALLOW GetFileAttributesW}(lpFileName) - else - Result := GetFileAttributesA{TNT-ALLOW GetFileAttributesA}(PAnsiChar(AnsiString(lpFileName))); -end; - -function Tnt_SetFileAttributesW(lpFileName: PWideChar; dwFileAttributes: DWORD): BOOL; -begin - if Win32PlatformIsUnicode then - Result := SetFileAttributesW{TNT-ALLOW SetFileAttributesW}(lpFileName, dwFileAttributes) - else - Result := SetFileAttributesA{TNT-ALLOW SetFileAttributesA}(PAnsiChar(AnsiString(lpFileName)), dwFileAttributes); -end; - -function Tnt_CreateDirectoryW(lpPathName: PWideChar; - lpSecurityAttributes: PSecurityAttributes): BOOL; -begin - if Win32PlatformIsUnicode then - Result := CreateDirectoryW{TNT-ALLOW CreateDirectoryW}(lpPathName, lpSecurityAttributes) - else - Result := CreateDirectoryA{TNT-ALLOW CreateDirectoryA}(PAnsiChar(AnsiString(lpPathName)), lpSecurityAttributes); -end; - -function Tnt_MoveFileW(lpExistingFileName, lpNewFileName: PWideChar): BOOL; -begin - if Win32PlatformIsUnicode then - Result := MoveFileW{TNT-ALLOW MoveFileW}(lpExistingFileName, lpNewFileName) - else - Result := MoveFileA{TNT-ALLOW MoveFileA}(PAnsiChar(AnsiString(lpExistingFileName)), PAnsiChar(AnsiString(lpNewFileName))); -end; - -function Tnt_CopyFileW(lpExistingFileName, lpNewFileName: PWideChar; bFailIfExists: BOOL): BOOL; -begin - if Win32PlatformIsUnicode then - Result := CopyFileW{TNT-ALLOW CopyFileW}(lpExistingFileName, lpNewFileName, bFailIfExists) - else - Result := CopyFileA{TNT-ALLOW CopyFileA}(PAnsiChar(AnsiString(lpExistingFileName)), - PAnsiChar(AnsiString(lpNewFileName)), bFailIfExists); -end; - -function Tnt_DeleteFileW(lpFileName: PWideChar): BOOL; -begin - if Win32PlatformIsUnicode then - Result := DeleteFileW{TNT-ALLOW DeleteFileW}(lpFileName) - else - Result := DeleteFileA{TNT-ALLOW DeleteFileA}(PAnsiChar(AnsiString(lpFileName))); -end; - -function Tnt_DrawTextW(hDC: HDC; lpString: PWideChar; nCount: Integer; - var lpRect: TRect; uFormat: UINT): Integer; -begin - if Win32PlatformIsUnicode then - Result := DrawTextW{TNT-ALLOW DrawTextW}(hDC, lpString, nCount, lpRect, uFormat) - else - Result := DrawTextA{TNT-ALLOW DrawTextA}(hDC, - PAnsiChar(AnsiString(_WStr(lpString, nCount))), -1, lpRect, uFormat); -end; - -function Tnt_GetDiskFreeSpaceW(lpRootPathName: PWideChar; var lpSectorsPerCluster, - lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters: DWORD): BOOL; -begin - if Win32PlatformIsUnicode then - Result := GetDiskFreeSpaceW{TNT-ALLOW GetDiskFreeSpaceW}(lpRootPathName, - lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters) - else - Result := GetDiskFreeSpaceA{TNT-ALLOW GetDiskFreeSpaceA}(PAnsiChar(AnsiString(lpRootPathName)), - lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters) -end; - -function Tnt_GetVolumeInformationW(lpRootPathName: PWideChar; lpVolumeNameBuffer: PWideChar; - nVolumeNameSize: DWORD; lpVolumeSerialNumber: PDWORD; - var lpMaximumComponentLength, lpFileSystemFlags: DWORD; lpFileSystemNameBuffer: PWideChar; - nFileSystemNameSize: DWORD): BOOL; -var - AnsiFileSystemNameBuffer: AnsiString; - AnsiVolumeNameBuffer: AnsiString; - AnsiBuffLen: DWORD; -begin - if Win32PlatformIsUnicode then - Result := GetVolumeInformationW{TNT-ALLOW GetVolumeInformationW}(lpRootPathName, lpVolumeNameBuffer, nVolumeNameSize, lpVolumeSerialNumber, lpMaximumComponentLength, lpFileSystemFlags, lpFileSystemNameBuffer, nFileSystemNameSize) - else begin - SetLength(AnsiVolumeNameBuffer, MAX_COMPUTERNAME_LENGTH + 1); - SetLength(AnsiFileSystemNameBuffer, MAX_COMPUTERNAME_LENGTH + 1); - AnsiBuffLen := Length(AnsiFileSystemNameBuffer); - Result := GetVolumeInformationA{TNT-ALLOW GetVolumeInformationA}(PAnsiChar(AnsiString(lpRootPathName)), PAnsiChar(AnsiVolumeNameBuffer), AnsiBuffLen, lpVolumeSerialNumber, lpMaximumComponentLength, lpFileSystemFlags, PAnsiChar(AnsiFileSystemNameBuffer), AnsiBuffLen); - if Result then begin - SetLength(AnsiFileSystemNameBuffer, AnsiBuffLen); - if (nFileSystemNameSize <= AnsiBuffLen) or (Length(AnsiFileSystemNameBuffer) = 0) then - Result := False - else begin - WStrPLCopy(lpFileSystemNameBuffer, AnsiFileSystemNameBuffer, nFileSystemNameSize); - WStrPLCopy(lpVolumeNameBuffer, AnsiVolumeNameBuffer, nVolumeNameSize); - end; - end; - end; -end; - -function Tnt_GetModuleFileNameW(hModule: HINST; lpFilename: PWideChar; nSize: DWORD): DWORD; -var - AnsiBuff: AnsiString; -begin - if Win32PlatformIsUnicode then - Result := GetModuleFileNameW{TNT-ALLOW GetModuleFileNameW}(hModule, lpFilename, nSize) - else begin - SetLength(AnsiBuff, MAX_PATH); - SetLength(AnsiBuff, GetModuleFileNameA{TNT-ALLOW GetModuleFileNameA}(hModule, PAnsiChar(AnsiBuff), Length(AnsiBuff))); - Result := _HandlePathLengthResult(nSize, lpFilename, AnsiBuff, [poExactCopy]); - end; -end; - -function Tnt_GetTempPathW(nBufferLength: DWORD; lpBuffer: PWideChar): DWORD; -var - AnsiBuff: AnsiString; -begin - if Win32PlatformIsUnicode then - Result := GetTempPathW{TNT-ALLOW GetTempPathW}(nBufferLength, lpBuffer) - else begin - SetLength(AnsiBuff, MAX_PATH); - SetLength(AnsiBuff, GetTempPathA{TNT-ALLOW GetTempPathA}(Length(AnsiBuff), PAnsiChar(AnsiBuff))); - Result := _HandlePathLengthResult(nBufferLength, lpBuffer, AnsiBuff, [poAllowDirectoryMode, poZeroSmallBuff]); - end; -end; - -function Tnt_GetTempFileNameW(lpPathName, lpPrefixString: PWideChar; uUnique: UINT; - lpTempFileName: PWideChar): UINT; -var - AnsiBuff: AnsiString; -begin - if Win32PlatformIsUnicode then - Result := GetTempFileNameW{TNT-ALLOW GetTempFileNameW}(lpPathName, lpPrefixString, uUnique, lpTempFileName) - else begin - SetLength(AnsiBuff, MAX_PATH); - Result := GetTempFileNameA{TNT-ALLOW GetTempFileNameA}(PAnsiChar(AnsiString(lpPathName)), PAnsiChar(lpPrefixString), uUnique, PAnsiChar(AnsiBuff)); - AnsiBuff := PAnsiChar(AnsiBuff); - _HandlePathLengthResult(MAX_PATH, lpTempFileName, AnsiBuff, [poZeroSmallBuff]); - end; -end; - -function Tnt_GetWindowsDirectoryW(lpBuffer: PWideChar; uSize: UINT): UINT; -var - AnsiBuff: AnsiString; -begin - if Win32PlatformIsUnicode then - Result := GetWindowsDirectoryW{TNT-ALLOW GetWindowsDirectoryW}(lpBuffer, uSize) - else begin - SetLength(AnsiBuff, MAX_PATH); - SetLength(AnsiBuff, GetWindowsDirectoryA{TNT-ALLOW GetWindowsDirectoryA}(PAnsiChar(AnsiBuff), Length(AnsiBuff))); - Result := _HandlePathLengthResult(uSize, lpBuffer, AnsiBuff, []); - end; -end; - -function Tnt_GetSystemDirectoryW(lpBuffer: PWideChar; uSize: UINT): UINT; -var - AnsiBuff: AnsiString; -begin - if Win32PlatformIsUnicode then - Result := GetSystemDirectoryW{TNT-ALLOW GetSystemDirectoryW}(lpBuffer, uSize) - else begin - SetLength(AnsiBuff, MAX_PATH); - SetLength(AnsiBuff, GetSystemDirectoryA{TNT-ALLOW GetSystemDirectoryA}(PAnsiChar(AnsiBuff), Length(AnsiBuff))); - Result := _HandlePathLengthResult(uSize, lpBuffer, AnsiBuff, []); - end; -end; - -function Tnt_GetCurrentDirectoryW(nBufferLength: DWORD; lpBuffer: PWideChar): DWORD; -var - AnsiBuff: AnsiString; -begin - if Win32PlatformIsUnicode then - Result := GetCurrentDirectoryW{TNT-ALLOW GetCurrentDirectoryW}(nBufferLength, lpBuffer) - else begin - SetLength(AnsiBuff, MAX_PATH); - SetLength(AnsiBuff, GetCurrentDirectoryA{TNT-ALLOW GetCurrentDirectoryA}(Length(AnsiBuff), PAnsiChar(AnsiBuff))); - Result := _HandlePathLengthResult(nBufferLength, lpBuffer, AnsiBuff, [poAllowDirectoryMode, poZeroSmallBuff]); - end; -end; - -function Tnt_SetCurrentDirectoryW(lpPathName: PWideChar): BOOL; -begin - if Win32PlatformIsUnicode then - Result := SetCurrentDirectoryW{TNT-ALLOW SetCurrentDirectoryW}(lpPathName) - else - Result := SetCurrentDirectoryA{TNT-ALLOW SetCurrentDirectoryA}(PAnsiChar(AnsiString(lpPathName))); -end; - -function Tnt_GetComputerNameW(lpBuffer: PWideChar; var nSize: DWORD): BOOL; -var - AnsiBuff: AnsiString; - AnsiBuffLen: DWORD; -begin - if Win32PlatformIsUnicode then - Result := GetComputerNameW{TNT-ALLOW GetComputerNameW}(lpBuffer, nSize) - else begin - SetLength(AnsiBuff, MAX_COMPUTERNAME_LENGTH + 1); - AnsiBuffLen := Length(AnsiBuff); - Result := GetComputerNameA{TNT-ALLOW GetComputerNameA}(PAnsiChar(AnsiBuff), AnsiBuffLen); - if Result then begin - SetLength(AnsiBuff, AnsiBuffLen); - if (nSize <= AnsiBuffLen) or (Length(AnsiBuff) = 0) then begin - nSize := AnsiBuffLen + 1; - Result := False; - end else begin - WStrPLCopy(lpBuffer, AnsiBuff, nSize); - nSize := WStrLen(lpBuffer); - end; - end; - end; -end; - -function Tnt_GetUserNameW(lpBuffer: PWideChar; var nSize: DWORD): BOOL; -var - AnsiBuff: AnsiString; - AnsiBuffLen: DWORD; -begin - if Win32PlatformIsUnicode then - Result := GetUserNameW{TNT-ALLOW GetUserNameW}(lpBuffer, nSize) - else begin - SetLength(AnsiBuff, 255); - AnsiBuffLen := Length(AnsiBuff); - Result := GetUserNameA{TNT-ALLOW GetUserNameA}(PAnsiChar(AnsiBuff), AnsiBuffLen); - if Result then begin - SetLength(AnsiBuff, AnsiBuffLen); - if (nSize <= AnsiBuffLen) or (Length(AnsiBuff) = 0) then begin - nSize := AnsiBuffLen + 1; - Result := False; - end else begin - WStrPLCopy(lpBuffer, AnsiBuff, nSize); - nSize := WStrLen(lpBuffer); - end; - end; - end; -end; - -function Tnt_ShellExecuteW(hWnd: HWND; Operation, FileName, Parameters, - Directory: PWideChar; ShowCmd: Integer): HINST; -begin - if Win32PlatformIsUnicode then - Result := ShellExecuteW{TNT-ALLOW ShellExecuteW}(hWnd, _PWideCharWithNil(WideString(Operation)), - FileName, Parameters, - Directory, ShowCmd) - else begin - Result := ShellExecuteA{TNT-ALLOW ShellExecuteA}(hWnd, _PAnsiCharWithNil(AnsiString(Operation)), - _PAnsiCharWithNil(AnsiString(FileName)), _PAnsiCharWithNil(AnsiString(Parameters)), - _PAnsiCharWithNil(AnsiString(Directory)), ShowCmd) - end; -end; - -function Tnt_LoadLibraryW(lpLibFileName: PWideChar): HMODULE; -begin - if Win32PlatformIsUnicode then - Result := LoadLibraryW{TNT-ALLOW LoadLibraryW}(lpLibFileName) - else - Result := LoadLibraryA{TNT-ALLOW LoadLibraryA}(PAnsiChar(AnsiString(lpLibFileName))); -end; - -function Tnt_LoadLibraryExW(lpLibFileName: PWideChar; hFile: THandle; dwFlags: DWORD): HMODULE; -begin - if Win32PlatformIsUnicode then - Result := LoadLibraryExW{TNT-ALLOW LoadLibraryExW}(lpLibFileName, hFile, dwFlags) - else - Result := LoadLibraryExA{TNT-ALLOW LoadLibraryExA}(PAnsiChar(AnsiString(lpLibFileName)), hFile, dwFlags); -end; - -function Tnt_CreateProcessW(lpApplicationName: PWideChar; lpCommandLine: PWideChar; - lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; - bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer; - lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfoW; - var lpProcessInformation: TProcessInformation): BOOL; -var - AnsiStartupInfo: TStartupInfoA; -begin - if Win32PlatformIsUnicode then begin - Result := CreateProcessW{TNT-ALLOW CreateProcessW}(lpApplicationName, lpCommandLine, - lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, - lpCurrentDirectory, lpStartupInfo, lpProcessInformation) - end else begin - CopyMemory(@AnsiStartupInfo, @lpStartupInfo, SizeOf(TStartupInfo)); - AnsiStartupInfo.lpReserved := _PAnsiCharWithNil(AnsiString(lpStartupInfo.lpReserved)); - AnsiStartupInfo.lpDesktop := _PAnsiCharWithNil(AnsiString(lpStartupInfo.lpDesktop)); - AnsiStartupInfo.lpTitle := _PAnsiCharWithNil(AnsiString(lpStartupInfo.lpTitle)); - Result := CreateProcessA{TNT-ALLOW CreateProcessA}(_PAnsiCharWithNil(AnsiString(lpApplicationName)), - _PAnsiCharWithNil(AnsiString(lpCommandLine)), - lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, - _PAnsiCharWithNil(AnsiString(lpCurrentDirectory)), AnsiStartupInfo, lpProcessInformation); - end; -end; - -function Tnt_GetCurrencyFormatW(Locale: LCID; dwFlags: DWORD; lpValue: PWideChar; - lpFormat: PCurrencyFmtW; lpCurrencyStr: PWideChar; cchCurrency: Integer): Integer; -const - MAX_ANSI_BUFF_SIZE = 64; // can a currency string actually be larger? -var - AnsiFormat: TCurrencyFmtA; - PAnsiFormat: PCurrencyFmtA; - AnsiBuff: AnsiString; -begin - if Win32PlatformIsUnicode then - Result := GetCurrencyFormatW{TNT-ALLOW GetCurrencyFormatW}(Locale, dwFlags, lpValue, lpFormat, lpCurrencyStr, cchCurrency) - else begin - if lpFormat = nil then - PAnsiFormat := nil - else begin - ZeroMemory(@AnsiFormat, SizeOf(AnsiFormat)); - AnsiFormat.NumDigits := lpFormat.NumDigits; - AnsiFormat.LeadingZero := lpFormat.LeadingZero; - AnsiFormat.Grouping := lpFormat.Grouping; - AnsiFormat.lpDecimalSep := PAnsiChar(AnsiString(lpFormat.lpDecimalSep)); - AnsiFormat.lpThousandSep := PAnsiChar(AnsiString(lpFormat.lpThousandSep)); - AnsiFormat.NegativeOrder := lpFormat.NegativeOrder; - AnsiFormat.PositiveOrder := lpFormat.PositiveOrder; - AnsiFormat.lpCurrencySymbol := PAnsiChar(AnsiString(lpFormat.lpCurrencySymbol)); - PAnsiFormat := @AnsiFormat; - end; - SetLength(AnsiBuff, MAX_ANSI_BUFF_SIZE); - SetLength(AnsiBuff, GetCurrencyFormatA{TNT-ALLOW GetCurrencyFormatA}(Locale, dwFlags, - PAnsiChar(AnsiString(lpValue)), PAnsiFormat, PAnsiChar(AnsiBuff), MAX_ANSI_BUFF_SIZE)); - Result := _HandleStringLengthResult(cchCurrency, lpCurrencyStr, AnsiBuff, []); - end; -end; - -function Tnt_CompareStringW(Locale: LCID; dwCmpFlags: DWORD; lpString1: PWideChar; - cchCount1: Integer; lpString2: PWideChar; cchCount2: Integer): Integer; -var - WideStr1, WideStr2: WideString; - AnsiStr1, AnsiStr2: AnsiString; -begin - if Win32PlatformIsUnicode then - Result := CompareStringW{TNT-ALLOW CompareStringW}(Locale, dwCmpFlags, lpString1, cchCount1, lpString2, cchCount2) - else begin - WideStr1 := _WStr(lpString1, cchCount1); - WideStr2 := _WStr(lpString2, cchCount2); - if (dwCmpFlags = 0) then begin - // binary comparison - if WideStr1 < WideStr2 then - Result := 1 - else if WideStr1 = WideStr2 then - Result := 2 - else - Result := 3; - end else begin - AnsiStr1 := WideStr1; - AnsiStr2 := WideStr2; - Result := CompareStringA{TNT-ALLOW CompareStringA}(Locale, dwCmpFlags, - PAnsiChar(AnsiStr1), -1, PAnsiChar(AnsiStr2), -1); - end; - end; -end; - -function Tnt_CharUpperW(lpsz: PWideChar): PWideChar; -var - AStr: AnsiString; - WStr: WideString; -begin - if Win32PlatformIsUnicode then - Result := CharUpperW{TNT-ALLOW CharUpperW}(lpsz) - else begin - if HiWord(Cardinal(lpsz)) = 0 then begin - // literal char mode - Result := lpsz; - if IsWideCharMappableToAnsi(WideChar(lpsz)) then begin - AStr := WideChar(lpsz); // single character may be more than one byte - CharUpperA{TNT-ALLOW CharUpperA}(PAnsiChar(AStr)); - WStr := AStr; // should always be single wide char - if Length(WStr) = 1 then - Result := PWideChar(WStr[1]); - end - end else begin - // null-terminated string mode - Result := lpsz; - while lpsz^ <> #0 do begin - lpsz^ := WideChar(Tnt_CharUpperW(PWideChar(lpsz^))); - Inc(lpsz); - end; - end; - end; -end; - -function Tnt_CharUpperBuffW(lpsz: PWideChar; cchLength: DWORD): DWORD; -var - i: integer; -begin - if Win32PlatformIsUnicode then - Result := CharUpperBuffW{TNT-ALLOW CharUpperBuffW}(lpsz, cchLength) - else begin - Result := cchLength; - for i := 1 to cchLength do begin - lpsz^ := WideChar(Tnt_CharUpperW(PWideChar(lpsz^))); - Inc(lpsz); - end; - end; -end; - -function Tnt_CharLowerW(lpsz: PWideChar): PWideChar; -var - AStr: AnsiString; - WStr: WideString; -begin - if Win32PlatformIsUnicode then - Result := CharLowerW{TNT-ALLOW CharLowerW}(lpsz) - else begin - if HiWord(Cardinal(lpsz)) = 0 then begin - // literal char mode - Result := lpsz; - if IsWideCharMappableToAnsi(WideChar(lpsz)) then begin - AStr := WideChar(lpsz); // single character may be more than one byte - CharLowerA{TNT-ALLOW CharLowerA}(PAnsiChar(AStr)); - WStr := AStr; // should always be single wide char - if Length(WStr) = 1 then - Result := PWideChar(WStr[1]); - end - end else begin - // null-terminated string mode - Result := lpsz; - while lpsz^ <> #0 do begin - lpsz^ := WideChar(Tnt_CharLowerW(PWideChar(lpsz^))); - Inc(lpsz); - end; - end; - end; -end; - -function Tnt_CharLowerBuffW(lpsz: PWideChar; cchLength: DWORD): DWORD; -var - i: integer; -begin - if Win32PlatformIsUnicode then - Result := CharLowerBuffW{TNT-ALLOW CharLowerBuffW}(lpsz, cchLength) - else begin - Result := cchLength; - for i := 1 to cchLength do begin - lpsz^ := WideChar(Tnt_CharLowerW(PWideChar(lpsz^))); - Inc(lpsz); - end; - end; -end; - -function Tnt_GetStringTypeExW(Locale: LCID; dwInfoType: DWORD; - lpSrcStr: PWideChar; cchSrc: Integer; var lpCharType): BOOL; -var - AStr: AnsiString; -begin - if Win32PlatformIsUnicode then - Result := GetStringTypeExW{TNT-ALLOW GetStringTypeExW}(Locale, dwInfoType, lpSrcStr, cchSrc, lpCharType) - else begin - AStr := _WStr(lpSrcStr, cchSrc); - Result := GetStringTypeExA{TNT-ALLOW GetStringTypeExA}(Locale, dwInfoType, - PAnsiChar(AStr), -1, lpCharType); - end; -end; - -function Win9x_LoadStringW(hInstance: HINST; uID: UINT; lpBuffer: PWideChar; nBufferMax: Integer): Integer; -// This function originated by the WINE Project. -// It was translated to Pascal by Francisco Leong. -// It was further modified by Troy Wolbrink. -var - hmem: HGLOBAL; - hrsrc: THandle; - p: PWideChar; - string_num, i: Integer; - block: Integer; -begin - Result := 0; - // Netscape v3 fix... - if (HIWORD(uID) = $FFFF) then begin - uID := UINT(-(Integer(uID))); - end; - // figure block, string_num - block := ((uID shr 4) and $FFFF) + 1; // bits 4 - 19, mask out bits 20 - 31, inc by 1 - string_num := uID and $000F; - // get handle & pointer to string block - hrsrc := FindResource{TNT-ALLOW FindResource}(hInstance, MAKEINTRESOURCE(block), RT_STRING); - if (hrsrc <> 0) then - begin - hmem := LoadResource(hInstance, hrsrc); - if (hmem <> 0) then - begin - p := LockResource(hmem); - // walk the block to the requested string - for i := 0 to string_num - 1 do begin - p := p + Integer(p^) + 1; - end; - Result := Integer(p^); { p points to the length of string } - Inc(p); { p now points to the actual string } - if (lpBuffer <> nil) and (nBufferMax > 0) then - begin - Result := min(nBufferMax - 1, Result); { max length to copy } - if (Result > 0) then begin - CopyMemory(lpBuffer, p, Result * sizeof(WideChar)); - end; - lpBuffer[Result] := WideChar(0); { null terminate } - end; - end; - end; -end; - -function Tnt_LoadStringW(hInstance: HINST; uID: UINT; lpBuffer: PWideChar; nBufferMax: Integer): Integer; -begin - if Win32PlatformIsUnicode then - Result := Windows.LoadStringW{TNT-ALLOW LoadStringW}(hInstance, uID, lpBuffer, nBufferMax) - else - Result := Win9x_LoadStringW(hInstance, uID, lpBuffer, nBufferMax); -end; - -function Tnt_InsertMenuItemW(hMenu: HMENU; uItem: DWORD; fByPosition: BOOL; lpmii: TMenuItemInfoW): BOOL; -begin - if Win32PlatformIsUnicode then - Result := InsertMenuItemW{TNT-ALLOW InsertMenuItemW}(hMenu, uItem, fByPosition, lpmii) - else begin - TMenuItemInfoA(lpmii).dwTypeData := PAnsiChar(AnsiString(lpmii.dwTypeData)); - Result := InsertMenuItemA{TNT-ALLOW InsertMenuItemA}(hMenu, uItem, fByPosition, TMenuItemInfoA(lpmii)); - end; -end; - -function Tnt_ExtractIconExW(lpszFile: PWideChar; nIconIndex: Integer; - var phiconLarge, phiconSmall: HICON; nIcons: UINT): UINT; -begin - if Win32PlatformIsUnicode then - Result := ExtractIconExW{TNT-ALLOW ExtractIconExW}(lpszFile, - nIconIndex, phiconLarge, phiconSmall, nIcons) - else - Result := ExtractIconExA{TNT-ALLOW ExtractIconExA}(PAnsiChar(AnsiString(lpszFile)), - nIconIndex, phiconLarge, phiconSmall, nIcons); -end; - -function Tnt_ExtractAssociatedIconW(hInst: HINST; lpIconPath: PWideChar; - var lpiIcon: Word): HICON; -begin - if Win32PlatformIsUnicode then - Result := ExtractAssociatedIconW{TNT-ALLOW ExtractAssociatedIconW}(hInst, lpIconPath, lpiIcon) - else - Result := ExtractAssociatedIconA{TNT-ALLOW ExtractAssociatedIconA}(hInst, - PAnsiChar(AnsiString(lpIconPath)), lpiIcon) -end; - -function Tnt_GetFileVersionInfoSizeW(lptstrFilename: PWideChar; var lpdwHandle: DWORD): DWORD; -begin - if Win32PlatformIsUnicode then - Result := GetFileVersionInfoSizeW{TNT-ALLOW GetFileVersionInfoSizeW}(lptstrFilename, lpdwHandle) - else - Result := GetFileVersionInfoSizeA{TNT-ALLOW GetFileVersionInfoSizeA}(PAnsiChar(AnsiString(lptstrFilename)), lpdwHandle); -end; - -function Tnt_GetFileVersionInfoW(lptstrFilename: PWideChar; dwHandle, dwLen: DWORD; - lpData: Pointer): BOOL; -begin - if Win32PlatformIsUnicode then - Result := GetFileVersionInfoW{TNT-ALLOW GetFileVersionInfoW}(lptstrFilename, dwHandle, dwLen, lpData) - else - Result := GetFileVersionInfoA{TNT-ALLOW GetFileVersionInfoA}(PAnsiChar(AnsiString(lptstrFilename)), dwHandle, dwLen, lpData); -end; - -var - Last_VerQueryValue_String: WideString; - -function Tnt_VerQueryValueW(pBlock: Pointer; lpSubBlock: PWideChar; - var lplpBuffer: Pointer; var puLen: UINT): BOOL; -var - AnsiBuff: AnsiString; -begin - if Win32PlatformIsUnicode then - Result := VerQueryValueW{TNT-ALLOW VerQueryValueW}(pBlock, lpSubBlock, lplpBuffer, puLen) - else begin - Result := VerQueryValueA{TNT-ALLOW VerQueryValueA}(pBlock, PAnsiChar(AnsiString(lpSubBlock)), lplpBuffer, puLen); - if WideTextPos(VQV_STRINGFILEINFO, lpSubBlock) <> 1 then - else begin - { /StringFileInfo, convert ansi result to unicode } - SetString(AnsiBuff, PAnsiChar(lplpBuffer), puLen); - Last_VerQueryValue_String := AnsiBuff; - lplpBuffer := PWideChar(Last_VerQueryValue_String); - puLen := Length(Last_VerQueryValue_String); - end; - end; -end; - -//--------------------------------------------------------------------------------------- -// Wide functions from Shell32.dll should be loaded dynamically (no stub on early Win95) -//--------------------------------------------------------------------------------------- - -type - TSHFileOperationW = function(var lpFileOp: TSHFileOpStructW): Integer; stdcall; - TSHBrowseForFolderW = function(var lpbi: TBrowseInfoW): PItemIDList; stdcall; - TSHGetPathFromIDListW = function(pidl: PItemIDList; pszPath: PWideChar): BOOL; stdcall; - TSHGetFileInfoW = function(pszPath: PWideChar; dwFileAttributes: DWORD; - var psfi: TSHFileInfoW; cbFileInfo, uFlags: UINT): DWORD; stdcall; - -var - Safe_SHFileOperationW: TSHFileOperationW = nil; - Safe_SHBrowseForFolderW: TSHBrowseForFolderW = nil; - Safe_SHGetPathFromIDListW: TSHGetPathFromIDListW = nil; - Safe_SHGetFileInfoW: TSHGetFileInfoW = nil; - -var Shell32DLL: HModule = 0; - -procedure LoadWideShell32Procs; -begin - if Shell32DLL = 0 then begin - Shell32DLL := WinCheckH(Tnt_LoadLibraryW('shell32.dll')); - Safe_SHFileOperationW := WinCheckP(GetProcAddress(Shell32DLL, 'SHFileOperationW')); - Safe_SHBrowseForFolderW := WinCheckP(GetProcAddress(Shell32DLL, 'SHBrowseForFolderW')); - Safe_SHGetPathFromIDListW := WinCheckP(GetProcAddress(Shell32DLL, 'SHGetPathFromIDListW')); - Safe_SHGetFileInfoW := WinCheckP(GetProcAddress(Shell32DLL, 'SHGetFileInfoW')); - end; -end; - -function Tnt_SHFileOperationW(var lpFileOp: TSHFileOpStructW): Integer; -var - AnsiFileOp: TSHFileOpStructA; - MapCount: Integer; - PAnsiMap: PSHNameMappingA; - PWideMap: PSHNameMappingW; - OldPath: WideString; - NewPath: WideString; - i: integer; -begin - if Win32PlatformIsUnicode then begin - LoadWideShell32Procs; - Result := Safe_SHFileOperationW(lpFileOp); - end else begin - AnsiFileOp := TSHFileOpStructA(lpFileOp); - // convert PChar -> PWideChar - if lpFileOp.pFrom = nil then - AnsiFileOp.pFrom := nil - else - AnsiFileOp.pFrom := PAnsiChar(AnsiString(ExtractStringArrayStr(lpFileOp.pFrom))); - if lpFileOp.pTo = nil then - AnsiFileOp.pTo := nil - else - AnsiFileOp.pTo := PAnsiChar(AnsiString(ExtractStringArrayStr(lpFileOp.pTo))); - AnsiFileOp.lpszProgressTitle := PAnsiChar(AnsiString(lpFileOp.lpszProgressTitle)); - Result := SHFileOperationA{TNT-ALLOW SHFileOperationA}(AnsiFileOp); - // return struct results - lpFileOp.fAnyOperationsAborted := AnsiFileOp.fAnyOperationsAborted; - lpFileOp.hNameMappings := nil; - if (AnsiFileOp.hNameMappings <> nil) - and ((FOF_WANTMAPPINGHANDLE and AnsiFileOp.fFlags) <> 0) then begin - // alloc mem - MapCount := PSHNameMappingHeaderA(AnsiFileOp.hNameMappings).cNumOfMappings; - lpFileOp.hNameMappings := - AllocMem(SizeOf({hNameMappings}Cardinal) + SizeOf(TSHNameMappingW) * MapCount); - PSHNameMappingHeaderW(lpFileOp.hNameMappings).cNumOfMappings := MapCount; - // init pointers - PAnsiMap := PSHNameMappingHeaderA(AnsiFileOp.hNameMappings).lpNM; - PWideMap := PSHNameMappingHeaderW(lpFileOp.hNameMappings).lpNM; - for i := 1 to MapCount do begin - // old path - OldPath := Copy(PAnsiMap.pszOldPath, 1, PAnsiMap.cchOldPath); - PWideMap.pszOldPath := WStrNew(PWideChar(OldPath)); - PWideMap.cchOldPath := WStrLen(PWideMap.pszOldPath); - // new path - NewPath := Copy(PAnsiMap.pszNewPath, 1, PAnsiMap.cchNewPath); - PWideMap.pszNewPath := WStrNew(PWideChar(NewPath)); - PWideMap.cchNewPath := WStrLen(PWideMap.pszNewPath); - // next record - Inc(PAnsiMap); - Inc(PWideMap); - end; - end; - end; -end; - -procedure Tnt_SHFreeNameMappings(hNameMappings: THandle); -var - i: integer; - MapCount: Integer; - PWideMap: PSHNameMappingW; -begin - if Win32PlatformIsUnicode then - SHFreeNameMappings{TNT-ALLOW SHFreeNameMappings}(hNameMappings) - else begin - // free strings - MapCount := PSHNameMappingHeaderW(hNameMappings).cNumOfMappings; - PWideMap := PSHNameMappingHeaderW(hNameMappings).lpNM; - for i := 1 to MapCount do begin - WStrDispose(PWideMap.pszOldPath); - WStrDispose(PWideMap.pszNewPath); - Inc(PWideMap); - end; - // free struct - FreeMem(Pointer(hNameMappings)); - end; -end; - -function Tnt_SHBrowseForFolderW(var lpbi: TBrowseInfoW): PItemIDList; -var - AnsiInfo: TBrowseInfoA; - AnsiBuffer: array[0..MAX_PATH] of AnsiChar; -begin - if Win32PlatformIsUnicode then begin - LoadWideShell32Procs; - Result := Safe_SHBrowseForFolderW(lpbi); - end else begin - AnsiInfo := TBrowseInfoA(lpbi); - AnsiInfo.lpszTitle := PAnsiChar(AnsiString(lpbi.lpszTitle)); - if lpbi.pszDisplayName <> nil then - AnsiInfo.pszDisplayName := AnsiBuffer; - Result := SHBrowseForFolderA{TNT-ALLOW SHBrowseForFolderA}(AnsiInfo); - if lpbi.pszDisplayName <> nil then - WStrPCopy(lpbi.pszDisplayName, AnsiInfo.pszDisplayName); - lpbi.iImage := AnsiInfo.iImage; - end; -end; - -function Tnt_SHGetPathFromIDListW(pidl: PItemIDList; pszPath: PWideChar): BOOL; -var - AnsiPath: AnsiString; -begin - if Win32PlatformIsUnicode then begin - LoadWideShell32Procs; - Result := Safe_SHGetPathFromIDListW(pidl, pszPath); - end else begin - SetLength(AnsiPath, MAX_PATH); - Result := SHGetPathFromIDListA{TNT-ALLOW SHGetPathFromIDListA}(pidl, PAnsiChar(AnsiPath)); - if Result then - WStrPCopy(pszPath, PAnsiChar(AnsiPath)) - end; -end; - -function Tnt_SHGetFileInfoW(pszPath: PWideChar; dwFileAttributes: DWORD; - var psfi: TSHFileInfoW; cbFileInfo, uFlags: UINT): DWORD; -var - SHFileInfoA: TSHFileInfoA; -begin - if Win32PlatformIsUnicode then begin - LoadWideShell32Procs; - Result := Safe_SHGetFileInfoW(pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags) - end else begin - Result := SHGetFileInfoA{TNT-ALLOW SHGetFileInfoA}(PAnsiChar(AnsiString(pszPath)), - dwFileAttributes, SHFileInfoA, SizeOf(TSHFileInfoA), uFlags); - // update pfsi... - ZeroMemory(@psfi, SizeOf(TSHFileInfoW)); - psfi.hIcon := SHFileInfoA.hIcon; - psfi.iIcon := SHFileInfoA.iIcon; - psfi.dwAttributes := SHFileInfoA.dwAttributes; - WStrPLCopy(psfi.szDisplayName, SHFileInfoA.szDisplayName, MAX_PATH); - WStrPLCopy(psfi.szTypeName, SHFileInfoA.szTypeName, 80); - end; -end; - - -function Tnt_Is_IntResource(ResStr: LPCWSTR): Boolean; -begin - Result := HiWord(Cardinal(ResStr)) = 0; -end; - -function LANGIDFROMLCID(lcid: LCID): WORD; -begin - Result := LoWord(lcid); -end; - -function MAKELANGID(usPrimaryLanguage, usSubLanguage: WORD): WORD; -begin - Result := (usSubLanguage shl 10) or usPrimaryLanguage; -end; - -function MAKELCID(wLanguageID: WORD; wSortID: WORD = SORT_DEFAULT): LCID; -begin - Result := MakeLong(wLanguageID, wSortID); -end; - -function PRIMARYLANGID(lgid: WORD): WORD; -begin - Result := lgid and $03FF; -end; - -function SORTIDFROMLCID(lcid: LCID): WORD; -begin - Result := HiWord(lcid); -end; - -function SUBLANGID(lgid: WORD): WORD; -begin - Result := lgid shr 10; -end; - -initialization - -finalization - if Shell32DLL <> 0 then - FreeLibrary(Shell32DLL); - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/HTMLEd1.dfm b/CORE/Source/Plugins/Htmlviewer/HTMLEd1.dfm deleted file mode 100644 index 1a003f639..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HTMLEd1.dfm +++ /dev/null @@ -1,196 +0,0 @@ -object Form1: TForm1 - Left = 496 - Top = 218 - Caption = 'HTML Editor' - ClientHeight = 416 - ClientWidth = 806 - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'MS Sans Serif' - Font.Style = [] - Menu = MainMenu1 - OldCreateOrder = True - Position = poScreenCenter - OnCloseQuery = FormCloseQuery - OnCreate = FormCreate - OnResize = FormResize - OnShow = FormShow - PixelsPerInch = 96 - TextHeight = 13 - object Splitter: TSplitter - Left = 507 - Top = 0 - Width = 5 - Height = 397 - Align = alRight - ExplicitLeft = 513 - ExplicitTop = -6 - end - object Panel3: TPanel - Left = 0 - Top = 397 - Width = 806 - Height = 19 - Align = alBottom - Alignment = taLeftJustify - BevelInner = bvLowered - BevelOuter = bvNone - TabOrder = 0 - end - object Viewer: THtmlViewer - Left = 512 - Top = 0 - Width = 294 - Height = 397 - BorderStyle = htFocused - DefBackground = clWindow - DefFontName = 'Times New Roman' - DefPreFontName = 'Courier New' - HistoryMaxCount = 0 - HtOptions = [htShowDummyCaret] - NoSelect = False - PrintMarginBottom = 2.000000000000000000 - PrintMarginLeft = 2.000000000000000000 - PrintMarginRight = 2.000000000000000000 - PrintMarginTop = 2.000000000000000000 - PrintScale = 1.000000000000000000 - OnHotSpotClick = ViewerHotSpotClick - OnHotSpotCovered = ViewerHotSpotCovered - Align = alRight - TabOrder = 1 - OnMouseUp = ViewerMouseUp - Touch.InteractiveGestures = [igPan] - Touch.InteractiveGestureOptions = [igoPanSingleFingerHorizontal, igoPanSingleFingerVertical, igoPanInertia] - end - object pEditor: TPanel - Left = 0 - Top = 0 - Width = 507 - Height = 397 - Align = alClient - BevelOuter = bvNone - TabOrder = 2 - object RichEdit: TRichEdit - Left = 0 - Top = 26 - Width = 507 - Height = 371 - Align = alClient - Font.Charset = ANSI_CHARSET - Font.Color = clWindowText - Font.Height = -13 - Font.Name = 'Courier New' - Font.Style = [] - ParentFont = False - PlainText = True - ScrollBars = ssBoth - TabOrder = 0 - WordWrap = False - Zoom = 100 - OnChange = RichEdChange - OnSelectionChange = RichEditSelectionChange - end - object bButtons: TPanel - Left = 0 - Top = 0 - Width = 507 - Height = 26 - Align = alTop - BevelOuter = bvNone - TabOrder = 1 - object Button1: TButton - Tag = 3 - Left = 48 - Top = 1 - Width = 25 - Height = 25 - Caption = 'B' - TabOrder = 0 - OnClick = ButtonClick - end - object Button2: TButton - Tag = 1 - Left = 72 - Top = 1 - Width = 25 - Height = 25 - Caption = 'I' - TabOrder = 1 - OnClick = ButtonClick - end - object Button3: TButton - Tag = 2 - Left = 96 - Top = 1 - Width = 25 - Height = 25 - Caption = 'U' - TabOrder = 2 - OnClick = ButtonClick - end - end - end - object MainMenu1: TMainMenu - Left = 400 - object File1: TMenuItem - Caption = '&File' - object New1: TMenuItem - Caption = '&New' - OnClick = New1Click - end - object NewHTML: TMenuItem - Caption = 'New &HTML' - OnClick = New1Click - end - object Open1: TMenuItem - Caption = '&Open' - ShortCut = 114 - OnClick = Open1Click - end - object Save1: TMenuItem - Caption = '&Save' - ShortCut = 113 - OnClick = Save1Click - end - object Saveas1: TMenuItem - Caption = 'Save to File' - OnClick = Saveas1Click - end - object N2: TMenuItem - Caption = '-' - end - object ExitItem: TMenuItem - Caption = 'E&xit' - OnClick = ExitItemClick - end - end - object Edit1: TMenuItem - Caption = '&Edit' - object Copy1: TMenuItem - Caption = '&Copy' - ShortCut = 16429 - OnClick = EditCopy - end - object Cut1: TMenuItem - Caption = 'Cu&t' - ShortCut = 8238 - OnClick = EditCut - end - object Paste1: TMenuItem - Caption = '&Paste' - ShortCut = 8237 - OnClick = EditPaste - end - end - end - object OpenDialog: TOpenDialog - DefaultExt = 'htm' - Filter = 'HTML Files|*.htm; *.html|All Files|*.*' - Left = 440 - end - object SaveDialog1: TSaveDialog - Left = 472 - end -end diff --git a/CORE/Source/Plugins/Htmlviewer/HTMLEd1.lfm b/CORE/Source/Plugins/Htmlviewer/HTMLEd1.lfm deleted file mode 100644 index 5688266f7..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HTMLEd1.lfm +++ /dev/null @@ -1,204 +0,0 @@ -object Form1: TForm1 - Left = 213 - Top = 177 - Width = 708 - Height = 475 - Caption = 'Form1' - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'MS Sans Serif' - Font.Style = [] - Menu = MainMenu1 - OnCloseQuery = FormCloseQuery - OnCreate = FormCreate - OnResize = FormResize - OnShow = FormShow - PixelsPerInch = 96 - object Panel1: TPanel - Left = 0 - Top = 0 - Width = 700 - Height = 41 - Align = alTop - TabOrder = 0 - object Button1: TButton - Tag = 3 - Left = 246 - Top = 6 - Width = 25 - Height = 25 - Caption = 'B' - TabOrder = 0 - OnClick = ButtonClick - end - object Button2: TButton - Tag = 1 - Left = 270 - Top = 6 - Width = 25 - Height = 25 - Caption = 'I' - TabOrder = 1 - OnClick = ButtonClick - end - object Button3: TButton - Tag = 2 - Left = 294 - Top = 6 - Width = 25 - Height = 25 - Caption = 'U' - TabOrder = 2 - OnClick = ButtonClick - end - end - object Panel: TPanel - Left = 0 - Top = 41 - Width = 700 - Height = 369 - Align = alClient - BevelOuter = bvNone - TabOrder = 1 - object Splitter: TSplitter - Left = 0 - Top = 207 - Width = 700 - Height = 5 - Cursor = crVSplit - Align = alTop - OnMoved = SplitterMoved - end - object RichEdit: TMemo - Left = 0 - Top = 0 - Width = 700 - Height = 209 - Align = alTop - Font.Charset = ANSI_CHARSET - Font.Color = clWindowText - Font.Height = -13 - Font.Name = 'Courier New' - Font.Style = [] - ParentFont = False - ScrollBars = ssBoth - TabOrder = 0 - WordWrap = False - OnChange = RichEdChange - end - object Panel2: TPanel - Left = 0 - Top = 212 - Width = 700 - Height = 155 - Align = alClient - BevelOuter = bvLowered - BevelWidth = 2 - Caption = 'Panel2' - Color = clWindow - TabOrder = 1 - object Viewer: THTMLViewer - Left = 0 - Top = 0 - Width = 696 - Height = 151 - Cursor = 2 - OnHotSpotCovered = ViewerHotSpotCovered - OnHotSpotClick = ViewerHotSpotClick - TabOrder = 0 - Align = alClient - DefBackground = clWindow - BorderStyle = htFocused - HistoryMaxCount = 0 - DefFontName = 'Times New Roman' - DefPreFontName = 'Courier New' - NoSelect = False - CharSet = DEFAULT_CHARSET - PrintMarginLeft = 2 - PrintMarginRight = 2 - PrintMarginTop = 2 - PrintMarginBottom = 2 - htOptions = [htShowDummyCaret] - OnMouseUp = ViewerMouseUp - end - end - end - object Panel3: TPanel - Left = 0 - Top = 410 - Width = 700 - Height = 19 - Align = alBottom - Alignment = taLeftJustify - BevelInner = bvLowered - BevelOuter = bvNone - TabOrder = 2 - end - object MainMenu1: TMainMenu - Left = 400 - Top = 8 - object File1: TMenuItem - Caption = '&File' - object New1: TMenuItem - Caption = '&New' - OnClick = New1Click - end - object NewHTML: TMenuItem - Caption = 'New &HTML' - OnClick = New1Click - end - object Open1: TMenuItem - Caption = '&Open' - ShortCut = 114 - OnClick = Open1Click - end - object Save1: TMenuItem - Caption = '&Save' - ShortCut = 113 - OnClick = Save1Click - end - object Saveas1: TMenuItem - Caption = 'Save &as' - OnClick = Saveas1Click - end - object N2: TMenuItem - Caption = '-' - end - object ExitItem: TMenuItem - Caption = 'E&xit' - OnClick = ExitItemClick - end - end - object Edit1: TMenuItem - Caption = '&Edit' - object Copy1: TMenuItem - Caption = '&Copy' - ShortCut = 16429 - OnClick = EditCopy - end - object Cut1: TMenuItem - Caption = 'Cu&t' - ShortCut = 8238 - OnClick = EditCut - end - object Paste1: TMenuItem - Caption = '&Paste' - ShortCut = 8237 - OnClick = EditPaste - end - end - object About1: TMenuItem - Caption = '&About' - OnClick = About1Click - end - end - object OpenDialog: TOpenDialog - DefaultExt = 'htm' - Filter = 'HTML Files|*.htm; *.html|All Files|*.*' - Left = 440 - end - object SaveDialog1: TSaveDialog - Left = 472 - end -end diff --git a/CORE/Source/Plugins/Htmlviewer/HTMLEd1.pas b/CORE/Source/Plugins/Htmlviewer/HTMLEd1.pas deleted file mode 100644 index e9f2a41aa..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HTMLEd1.pas +++ /dev/null @@ -1,452 +0,0 @@ -unit HTMLEd1; - -{$include .\source\htmlcons.inc} - -interface - -uses - {$ifdef FPC} - LCLIntf, LCLType, LMessages, FileUtil, ShellAPI, - {$else} - ShellAPI, Windows, - {$endif} - {$ifdef HasSystemUITypes} - System.UITypes, - {$endif} - Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, - ExtCtrls, Menus, StdCtrls, ComCtrls, - HtmlGlobals, StyleTypes, Htmlview, StyleUn, HTMLUn2; - -type -{$ifdef FPC} - TRichEdit = TMemo; -{$endif} - - TForm1 = class(TForm) - MainMenu1: TMainMenu; - File1: TMenuItem; - Open1: TMenuItem; - OpenDialog: TOpenDialog; - New1: TMenuItem; - Save1: TMenuItem; - Saveas1: TMenuItem; - ExitItem: TMenuItem; - SaveDialog1: TSaveDialog; - Edit1: TMenuItem; - Copy1: TMenuItem; - Cut1: TMenuItem; - Paste1: TMenuItem; - N2: TMenuItem; - NewHTML: TMenuItem; - Panel3: TPanel; - Viewer: THtmlViewer; - Splitter: TSplitter; - pEditor: TPanel; - RichEdit: TRichEdit; - bButtons: TPanel; - Button1: TButton; - Button2: TButton; - Button3: TButton; - procedure ButtonClick(Sender: TObject); - procedure EditCopy(Sender: TObject); - procedure EditCut(Sender: TObject); - procedure EditPaste(Sender: TObject); - procedure ExitItemClick(Sender: TObject); - procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); - procedure FormCreate(Sender: TObject); - procedure FormShow(Sender: TObject); - procedure New1Click(Sender: TObject); - procedure Open1Click(Sender: TObject); - procedure RichEdChange(Sender: TObject); - procedure RichEditSelectionChange(Sender: TObject); - procedure Save1Click(Sender: TObject); - procedure Saveas1Click(Sender: TObject); - procedure ViewerMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); -{$ifdef UNICODE} - procedure ViewerHotSpotClick(Sender: TObject; const SRC: string; var Handled: Boolean); - procedure ViewerHotSpotCovered(Sender: TObject; const SRC: string); -{$else} - procedure ViewerHotSpotClick(Sender: TObject; const SRC: WideString; var Handled: Boolean); - procedure ViewerHotSpotCovered(Sender: TObject; const SRC: WideString); -{$endif} - procedure FormResize(Sender: TObject); - procedure SplitterMoved(Sender: TObject); - private - ViewerOK, RichOK: Boolean; - SizeRatio: Double; -{$ifdef FPC} - FSelStart, FSelLength: Integer; -{$endif} - procedure CheckFileSave; -{$ifdef MsWindows} - procedure WMDropFiles(var Msg: TWMDropFiles); message WM_DROPFILES; -{$endif} - - public - CurrentFile: String; - procedure LoadFile(Filename: String); -{$ifdef FPC} - procedure UpdateActions; override; -{$endif} - end; - -var - Form1: TForm1; - -implementation - -{$ifdef FPC} - {$R *.lfm} -{$else} - {$R *.dfm} -{$endif} - -const - InitText = ''^m^j''^m^j''^m^j''^m^j+ - ''^m^j^m^j^m^j''^m^j''^m^j; - -procedure TForm1.FormCreate(Sender: TObject); -begin -{$ifdef MsWindows} - DragAcceptFiles(Handle, True); -{$endif} - RichEdit.Modified := False; - SizeRatio := 0.5; -end; - -procedure TForm1.Open1Click(Sender: TObject); -begin - CheckFileSave; - if CurrentFile <> '' then - OpenDialog.InitialDir := ExtractFilePath(CurrentFile) - else - OpenDialog.InitialDir := ExtractFilePath(ParamStr(0)); - OpenDialog.FilterIndex := 1; - if OpenDialog.Execute then - LoadFile(OpenDialog.Filename); -end; - -procedure TForm1.Saveas1Click(Sender: TObject); -begin - SaveDialog1.InitialDir := ExtractFilePath(CurrentFile); - SaveDialog1.Filename := ExtractFilename(CurrentFile); - if SaveDialog1.Execute then - begin - RichEdit.Lines.SaveToFile(SaveDialog1.FileName); - CurrentFile := SaveDialog1.FileName; - Caption := CurrentFile; - RichEdit.Modified := False; - end; -end; - -procedure TForm1.Save1Click(Sender: TObject); -begin - if CurrentFile = '' then - SaveAs1Click(Sender) - else - begin - RichEdit.Lines.SaveToFile(CurrentFile); - RichEdit.Modified := False; - end; -end; - -procedure TForm1.RichEdChange(Sender: TObject); -{TRichEdit OnChange handler} -var - Position: integer; - Text: string; -begin - if RichOK then - begin - Position := Viewer.Position; -{$ifdef Compiler16_Plus} - Text := StringReplace(RichEdit.Text, #$0D#$0A, #$0A, [rfReplaceAll]); -{$else} - Text := RichEdit.Text; -{$endif} - Viewer.LoadFromString(Text); - ViewerOK := True; - Viewer.Position := Position; - RichEditSelectionChange(Nil); - end; -end; - -procedure TForm1.RichEditSelectionChange(Sender: TObject); -{TRichEdit OnSelectionChange handler} -var - Pos1, Pos2, X, Y, VPos, SStr, SLen: integer; -begin - if ViewerOK then - begin - SStr := RichEdit.SelStart; - SLen := RichEdit.SelLength; - if SStr+SLen > Length(RichEdit.Text) then - SLen := Length(RichEdit.Text)-SStr; - Pos1 := Viewer.FindDisplayPos(SStr*2, False); - if Pos1 < 0 then {means it's past end} - Pos1 := Viewer.FindDisplayPos(SStr*2, True); - if SLen <> 0 then - begin - Pos2 := Viewer.FindDisplayPos((SStr+SLen)*2, False); - if Pos2 < 0 then - Pos2 := Viewer.FindDisplayPos((SStr+SLen-1)*2, False); {fix for above} - end - else - Pos2 := Pos1; - if (Pos1 >= 0) and Viewer.DisplayPosToXY(Pos1, X, Y) then - begin - {see if Viewer is positioned properly} - VPos := Viewer.VScrollBarPosition; - if (Y < VPos) or - (Y > VPos +Viewer.ClientHeight-20) then - Viewer.VScrollBarPosition := (Y - Viewer.ClientHeight div 2); - Viewer.SelStart := Pos1; - Viewer.SelLength := Pos2-Pos1; - end; - Panel3.Caption := Format('Edit.SelStart %d, Edit.SelLength %d, Viewer.SelStart %d, Viewer.SelLength %d', [SStr, SLen, Pos1, Pos2-Pos1]); - end; -end; - -procedure TForm1.ViewerMouseUp(Sender: TObject; Button: TMouseButton; - Shift: TShiftState; X, Y: Integer); -var - Pos, Pos2, VSelLength, VSelStart: integer; -begin - if not ViewerOK then Exit; - ViewerOK := False; - try - VSelStart := Viewer.SelStart; - VSelLength := Viewer.SelLength; - if VSelLength < 0 then - begin - VSelLength := -VSelLength; - Dec(VSelStart, VSelLength); - end; - - Pos := Viewer.FindSourcePos(VSelStart); - if Pos >= 0 then - begin - if VSelLength = 0 then - Pos2 := Pos - else - Pos2 := Viewer.FindSourcePos(VSelStart + VSelLength); - RichEdit.SelStart := Pos div 2; - RichEdit.SelLength := (Pos2-Pos) div 2; -{$ifdef FPC} - FSelStart := RichEdit.SelStart; - FSelLength := RichEdit.SelLength; -{$endif} - RichEdit.SetFocus; -{$ifdef MsWindows} - PostMessage(RichEdit.handle, EM_SCROLLCARET, 0, 0); {8.03} -{$endif} - end; - finally - ViewerOK := True; - end; -end; - -procedure TForm1.New1Click(Sender: TObject); -begin - if RichEdit.Modified then - SaveAs1Click(Nil); - RichEdit.Text := ''; - Viewer.Clear; - ViewerOK := True; - RichOK := True; - if CurrentFile <> '' then - CurrentFile := ExtractFilePath(CurrentFile) - else - CurrentFile := ExtractFilePath(ParamStr(0)); - CurrentFile := CurrentFile+'Untitled.htm'; - Caption := CurrentFile; - if Sender = NewHTML then - begin - RichEdit.Text := InitText; - RichOK := True; - RichEdit.Modified := False; - end; -end; - -procedure TForm1.FormShow(Sender: TObject); -var - S: string; - I: integer; -begin - if ParamCount >= 1 then - begin {Parameter is file to load} - S := CmdLine; - I := Pos('" ', S); - if I > 0 then - Delete(S, 1, I+1) {delete EXE name in quotes} - else - Delete(S, 1, Length(ParamStr(0))); {in case no quote marks} - I := Pos('"', S); - while I > 0 do {remove any quotes from parameter} - begin - Delete(S, I, 1); - I := Pos('"', S); - end; - LoadFile(S); - end - else - New1Click(Sender); -end; - -procedure TForm1.EditCut(Sender: TObject); -begin - RichEdit.CutToClipboard; -end; - -procedure TForm1.EditCopy(Sender: TObject); -begin - RichEdit.CopyToClipboard; -end; - -procedure TForm1.EditPaste(Sender: TObject); -begin - RichEdit.PasteFromClipboard; -end; - -procedure TForm1.CheckFileSave; -var - SaveResp: Integer; -begin - if not RichEdit.Modified then Exit; - SaveResp := MessageDlg(Format('Save changes to %s?', [CurrentFile]), mtConfirmation, mbYesNoCancel, 0); - case SaveResp of - idYes: Save1Click(Self); - idNo: {Nothing}; - idCancel: Abort; - end; -end; - -procedure TForm1.ExitItemClick(Sender: TObject); -begin - Close; -end; - -procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean); -begin - try - CheckFileSave; - except - CanClose := False; - end; -end; - -{$ifdef MsWindows} -procedure TForm1.WMDropFiles(var Msg: TWMDropFiles); -var - CFileName: array[0..MAX_PATH] of Char; -begin - try - if DragQueryFile(Msg.Drop, 0, CFileName, MAX_PATH) > 0 then - begin - CheckFileSave; - LoadFile(CFileName); - Msg.Result := 0; - end; - finally - DragFinish(Msg.Drop); - end; -end; -{$endif} - -//-- BG ---------------------------------------------------------- 06.01.2015 -- -procedure TForm1.ButtonClick(Sender: TObject); -var - C: char; -begin - case TButton(Sender).Tag of - 1: C := 'I'; - 2: C := 'U'; - 3: C := 'B'; - else - exit; - end; - with RichEdit do - begin - SelText := '<'+C+'>'+SelText+''; - SetFocus; - end; -end; - -procedure TForm1.ViewerHotSpotClick(Sender: TObject; const SRC: ThtString; var Handled: Boolean); -{HotspotClick handler} -var - I: integer; - ID: string; -begin - I := Pos('IDEXPAND_', Uppercase(SRC)); - if I=1 then - begin - ID := Copy(SRC, 10, Length(SRC)-9); - if Viewer.IDDisplay[ID+'Minus'] = High(ThtDisplayStyle) then - Viewer.IDDisplay[ID+'Minus'] := Low(ThtDisplayStyle) - else - Viewer.IDDisplay[ID+'Minus'] := Succ(Viewer.IDDisplay[ID+'Minus']); - Viewer.IDDisplay[ID+'Plus'] := Viewer.IDDisplay[ID+'Minus']; -// Viewer.IDDisplay[ID+'Plus'] := not Viewer.IDDisplay[ID+'Plus']; -// Viewer.IDDisplay[ID+'Minus'] := not Viewer.IDDisplay[ID+'Minus']; - Viewer.Reformat; - Handled := True; - Exit; - end; - - {allow only local links to work} - if (Length(SRC) > 0) and (Trim(SRC)[1] = '#') then - Handled := False - else - Handled := True; -end; - -procedure TForm1.ViewerHotSpotCovered(Sender: TObject; const SRC: ThtString); -begin - if SRC = '' then - Panel3.Caption := '' - else if Viewer.Target <> '' then - Panel3.Caption := 'Target: '+Viewer.Target+' URL: '+SRC - else - Panel3.Caption := 'URL: '+SRC -end; - -procedure TForm1.FormResize(Sender: TObject); -begin - RichEdit.Height := Round((pEditor.Height - Splitter.Height) * SizeRatio); -end; - -Procedure TForm1.SplitterMoved(Sender: TObject); -begin - SizeRatio := pEditor.Height / (pEditor.Height - Splitter.Height); -end; - -//-- BG ---------------------------------------------------------- 08.01.2011 -- -procedure TForm1.LoadFile(Filename: String); -begin -{$ifdef LCL} - SetCurrentDirUTF8(ExtractFilePath(Filename)); -{$else} - SetCurrentDir(ExtractFilePath(Filename)); -{$endif} - CurrentFile := Filename; - Caption := CurrentFile; - RichEdit.Lines.LoadFromFile(Filename); - RichEdit.SetFocus; - RichEdit.Modified := False; -end; - -{$ifdef LCL} -//-- BG ---------------------------------------------------------- 06.01.2015 -- -procedure TForm1.UpdateActions; -begin - if (RichEdit.SelStart <> FSelStart) or (RichEdit.SelLength <> FSelLength) then - begin - FSelStart := RichEdit.SelStart; - FSelLength := RichEdit.SelLength; - RichEditSelectionChange(RichEdit); - end; -end; -{$endif} - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/HTMLEditorDSG.dpr b/CORE/Source/Plugins/Htmlviewer/HTMLEditorDSG.dpr deleted file mode 100644 index de1314671..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HTMLEditorDSG.dpr +++ /dev/null @@ -1,18 +0,0 @@ -program HTMLEditorDSG; - -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} - -uses - {$IFDEF FPC} - Interfaces, - {$ENDIF } - Forms, - HTMLEd1 in 'HTMLEd1.pas' {Form1}; - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/HTMLVIEW.hhk b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/HTMLVIEW.hhk deleted file mode 100644 index 67dd8a5f3..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/HTMLVIEW.hhk +++ /dev/null @@ -1,1252 +0,0 @@ - - - - -
    -
  • - - - - -
  • - - - - - - -
  • - - - - -
  • - - - - - - - - - - -
  • - - - - -
  • - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - -
  • - - - - -
  • - - - - - - -
  • - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - -
  • - - - - -
  • - - - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - - - - - - - -
  • - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - - - - - - - - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - -
  • - - - - -
  • - - - - - - - - - - - - - - - - - - - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - - - - - - - - - - - - - - - - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - -
  • - - - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - -
  • - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - - - -
  • - - - - - - -
  • - - - - -
  • - - - - - - - - - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - - - - - - - - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - -
  • - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
  • - - - - -
diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/THtmlViewer.chm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/THtmlViewer.chm deleted file mode 100644 index ffc06451045752d60e28ef4bcc8cad37c897e795..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160984 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�Z~oybkY~Ddj`WR_duTOw40$>nDBiL#}C2=6xO!P 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
    D)RZ3Mp!3K5SM08#(hxMbUYJA-WdQ4>Ag~^E6eJ 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 diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/THtmlViewer.hhp b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/THtmlViewer.hhp deleted file mode 100644 index be8ba5e2f..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/THtmlViewer.hhp +++ /dev/null @@ -1,253 +0,0 @@ -[OPTIONS] -Auto Index=Yes -Compatibility=1.1 or later -Compiled file=THtmlViewer.chm -Contents file=HtmlView.hhc -Default topic=html\contents.htm -Display compile progress=Yes -Full-text search=Yes -Language=0x409 Englisch (USA) -Title=THtmlViewer Components - - -[FILES] -html\_body__attributes.htm -html\activeviewer_property.htm -html\assign_tbuffer_method.htm -html\assignto_tbuffer_method.htm -html\asstring_tbuffer_method.htm -html\backbuttonenabled_property.htm -html\base_property.htm -html\basetarget_property.htm -html\borderstyle_property.htm -html\caretpos_property.htm -html\charset_property.htm -html\class_hierarchy.htm -html\clear_method.htm -html\clearhistory_method.htm -html\codepage_tbuffer_property.htm -html\contents.htm -html\convert_tbuffer_method.htm -html\copyright.htm -html\copytoclipboard_method.htm -html\currentfile_property.htm -html\defbackground_property.htm -html\deffontcolor_property.htm -html\deffontname_property.htm -html\deffontsize_property.htm -html\defhotspotcolor_property.htm -html\defoverlinkcolor_property.htm -html\defprefontname_property.htm -html\defvisitedlinkcolor_property.htm -html\displaypostoxy_method.htm -html\dither_property.htm -html\documentsource_property.htm -html\dostohtml_function.htm -html\event_thtmlvieweronhotspotclick.htm -html\event_thtmlvieweronhotspotcovered.htm -html\find_method.htm -html\finddisplaypos_method.htm -html\findsourcepos_method.htm -html\formcontrollist_property.htm -html\formdata_property.htm -html\fulldisplaysize_method.htm -html\fvoptions_property.htm -html\fwdbuttonenabled_property.htm -html\getcharatpos_method.htm -html\getpostquery_method.htm -html\getseltextbuf_method.htm -html\getstring_tbuffer_method.htm -html\getviewerurlbase_method.htm -html\goback_method.htm -html\gofwd_method.htm -html\history_property.htm -html\historyindex_property.htm -html\historymaxcount_property.htm -html\hscrollbarposition_property.htm -html\hscrollbarrange_property.htm -html\htmlexpandfilename_method.htm -html\htmltodos.htm -html\htoptions_property.htm -html\idcontrol_property.htm -html\iddisplay_property.htm -html\imagecachecount_property.htm -html\insertimage_method.htm -html\linkattributes_property.htm -html\linktext_property.htm -html\load_method.htm -html\loadfrombuffer_method.htm -html\loadfromfile_method.htm -html\loadfromstream_method.htm -html\loadfromstring_method.htm -html\loadimagefile_method.htm -html\loadstrings_method.htm -html\loadtargetfromfile_method.htm -html\loadtextfile_method.htm -html\loadtextstrings_method.htm -html\loadurl_method.htm -html\makebitmap_method.htm -html\makemetafile_method.htm -html\makepagedmetafiles_method.htm -html\marginheight_and_marginwidth_properties.htm -html\maxvertical_property.htm -html\name_tbuffer_property.htm -html\namelist_property.htm -html\nextchar_tbuffer_method.htm -html\noselect_property.htm -html\numprinterpages_method.htm -html\onblankwindowrequest_event.htm -html\onbufferrequest_event.htm -html\onfilebrowse_event.htm -html\onfilerequest_event.htm -html\onformsubmit_event.htm -html\ongetpostrequest_event.htm -html\onhistorychange_event.htm -html\onhotspottargetclick_event.htm -html\onhotspottargetcovered_event.htm -html\onhtstreamrequest_event.htm -html\onimageclick_event.htm -html\onimageover_event.htm -html\onimagerequest_event.htm -html\oninclude_event.htm -html\onlink_event.htm -html\onmeta_event.htm -html\onmetarefresh_event.htm -html\onmousedouble_event.htm -html\onobjectblur_event.htm -html\onobjectchange_event.htm -html\onobjectclick_event.htm -html\onobjectfocus_event.htm -html\onobjecttag_event.htm -html\onpanelcreate_event.htm -html\onpaneldestroy_event.htm -html\onpanelprint_event.htm -html\onparsebegin_event.htm -html\onparseend_event.htm -html\onprintheader_and_onprintfooter_events.htm -html\onprinthtmlheader_and_onprinthtmlfooter_events.htm -html\onprocessing_event.htm -html\onprogress_event.htm -html\onrightclick_event.htm -html\onscript_event.htm -html\onsoundrequest_event.htm -html\onstreamrequest_event.htm -html\onstringsrequest_event.htm -html\onviewerclear_event.htm -html\openprint__abortprint__and_closeprint_methods.htm -html\palette_property.htm -html\peekchar_tbuffer_method.htm -html\position_tbuffer_property.htm -html\positionto_method.htm -html\print_method.htm -html\printmargin_properties.htm -html\printscale_property.htm -html\processing_property.htm -html\prop_thtmlviewer_quirksmode.htm -html\prop_thtmlviewerdocumenttitle.htm -html\prop_thtmlviewerposition.htm -html\ptinobject_method.htm -html\reference.htm -html\reformat_method.htm -html\reformatting.htm -html\reload_method.htm -html\replaceimage_method.htm -html\selectall_method.htm -html\sellength_property.htm -html\selstart_property.htm -html\seltext_property.htm -html\serverroot_property.htm -html\setting_up_a_history_list.htm -html\size_tbuffer_method.htm -html\special_html_tags_and_attributes.htm -html\supported_elements.htm -html\supported_properties.htm -html\target_property.htm -html\tframebrowser_component.htm -html\tframebrowser_events.htm -html\tframebrowser_methods.htm -html\tframebrowser_properties.htm -html\tframeviewer_component.htm -html\tframeviewer_events.htm -html\tframeviewer_methods.htm -html\tframeviewerproperties.htm -html\tfreelist.htm -html\things_you_should_know.htm -html\thtmlviewer_component.htm -html\thtmlviewer_events.htm -html\thtmlviewer_methods.htm -html\thtmlviewerproperties.htm -html\titleattr_property.htm -html\titlehistory_property.htm -html\type_tbuffcodepage.htm -html\type_tbufferrequestevent.htm -html\type_tfilebrowseevent.htm -html\type_tfilerequestevent.htm -html\type_tformsubmitevent.htm -html\type_tgetimageevent.htm -html\type_tgetpostrequestevent.htm -html\type_tgetpostrequestexevent.htm -html\type_tgetstreamevent.htm -html\type_thotspotclickevent.htm -html\type_thotspotevent.htm -html\type_thotspottargetclickevent.htm -html\type_thotspottargetevent_.htm -html\type_thtmlfiletype.htm -html\type_thtmlpageprinted.htm -html\type_thtobjectevent.htm -html\type_thtprogressevent.htm -html\type_thtquirksmode.htm -html\type_thtstring.htm -html\type_thtstrings.htm -html\type_timageclickevent.htm -html\type_timageoverevent.htm -html\type_tincludetype.htm -html\type_tlinktype.htm -html\type_tmetarefreshtype.htm -html\type_tmetatype.htm -html\type_tobjectclickevent.htm -html\type_tobjecttagevent.htm -html\type_tpageprinted.htm -html\type_tpanelcreateevent.htm -html\type_tpaneldestroyevent.htm -html\type_tpanelprintevent.htm -html\type_tprocessingevent.htm -html\type_trightclickevent.htm -html\type_tscriptevent.htm -html\type_tsoundtype.htm -html\type_tstreamrequestevent.htm -html\type_tstringsrequestevent.htm -html\type_twindowrequestevent.htm -html\url.htm -html\url_property.htm -html\using_the_tframebrowser_component.htm -html\using_the_tframeviewer_component.htm -html\using_the_thtmlviewer_component.htm -html\viewerfromtarget_method.htm -html\viewers_property.htm -html\viewimages_property.htm -html\visitedmaxcount_property.htm -html\vscrollbar__hscrollbar_properties.htm -html\vscrollbarposition_property.htm -html\vscrollbarrange_property.htm -html\waitstream.htm -html\xytodisplaypos_method.htm -images\smallcheck.gif -images\v114.png -images\v115.png -images\v945.png - -[ALIAS] -DocumentTitle_Property = html\prop_thtmlviewerdocumenttitle.htm -OnHotSpotClick_Event = html\event_thtmlvieweronhotspotclick.htm -1NA1XUA = html\event_thtmlvieweronhotspotcovered.htm -Position_Property = html\prop_thtmlviewerposition.htm -132O05N = html\target_property.htm -Target_Property = html\target_property.htm -prop_ThtmlViewerURL = html\url_property.htm -J10061 = html\url_property.htm -prop_ThtmlViewerVScrollBarPosition = html\vscrollbarposition_property.htm -prop_ThtmlViewerVScrollBarRange = html\vscrollbarrange_property.htm -prop_ThtmlViewerViewImages = html\viewimages_property.htm - -[INFOTYPES] - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/_body__attributes.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/_body__attributes.htm deleted file mode 100644 index af7d741a9..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/_body__attributes.htm +++ /dev/null @@ -1,61 +0,0 @@ - - - - -<body> attributes - - - - - - - - - - - - - - -
    - -

    THtmlViewer supports color and background information attributes entered with the HTML <body> tag. Thus each document may have a customized appearance. Color and background information entered in this manner overrides the default information specified by the DefFontColor, DefHotSpotColor, DefBackground, DefVisitedLinkColor, DefOverLinkColor properties.

    - -

    The following <body> attributes are supported in this version:

    - -

    Text="RRGGBB"

    - -

    The hex number entered determines the normal text color.

    - -

    Link="RRGGBB"

    - -

    The hex number entered determines the link (HotSpot) color.

    - -

    VLink="RRGGBB"

    - -

    The hex number entered determines the color of a link which has been previously visited.

    - -

    OLink="RRGGBB"

    - -

    The hex number entered determines the link color when the mouse passes over it. A defined OLink value will make the links active even if fvOverLinksActive or htOverLinksActive are not set..

    - -

    BgColor="RRGGBB"

    - -

    The hex number entered determines the background color.

    - -

    Background="imagefilename"

    - -

    The Background attribute specifies an image file. When ViewImages is set, this image will be tiled to form the background of the document.

    - -

    HTML hex entries are 2 digits of red, 2 digits of green, and 2 digits of blue. Note that this order is the reverse of normal color entries in Windows. Also, most HTML browsers require all six digits including leading zeros.

    - -

    Example

    - -

    <body text="00FF00" link="FF0000"

    - -

    bgcolor="000000" background="marble.gif">

    - -

    produces green text, red hotspots on a black background. If ViewImages is set, marble.gif will be tiled to form the background.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/activeviewer_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/activeviewer_property.htm deleted file mode 100644 index 6678f9dd3..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/activeviewer_property.htm +++ /dev/null @@ -1,36 +0,0 @@ - - - - -ActiveViewer Property - - - - - - - - - - -

    ActiveViewer Property

    -
    - -

    Applies to

    - -

    TFrameViewer and TFrameBrowser components

    - -

    Description

    - -

    property ActiveViewer: THtmlViewer;

    - -

    Read only and run time only. The ActiveViewer property returns the currently selected or most recently selected THtmlViewer in the Frameset.

    - -

    See Also:

    - -

    ViewerFromTarget Method

    - -

    Viewers Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/assign_tbuffer_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/assign_tbuffer_method.htm deleted file mode 100644 index 3c3e27293..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/assign_tbuffer_method.htm +++ /dev/null @@ -1,35 +0,0 @@ - - - - -TBuffer.Assign Method - - - - - - - - - -

    Assign Method

    -
    - -

    Applies to

    - -

    TBuffer class

    - -

    Declaration

    - -

    procedure Assign(Source: TBuffer); virtual;

    - -

    Description

    -

    The Assign method copies one buffer to another.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/assignto_tbuffer_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/assignto_tbuffer_method.htm deleted file mode 100644 index 22bac48bf..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/assignto_tbuffer_method.htm +++ /dev/null @@ -1,35 +0,0 @@ - - - - -TBuffer.AssignTo Method - - - - - - - - - -

    Assign Method

    -
    - -

    Applies to

    - -

    TBuffer class

    - -

    Declaration

    - -

    procedure AssignTo(Destin: TObject); virtual;

    - -

    Description

    -

    The AssignTo method can assign the buffer to a TMemoryStream.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/asstring_tbuffer_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/asstring_tbuffer_method.htm deleted file mode 100644 index 1099104fd..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/asstring_tbuffer_method.htm +++ /dev/null @@ -1,37 +0,0 @@ - - - - -TBuffer.AsString Method - - - - - - - - - -

    AsString Method

    -
    - -

    Applies to

    - -

    TBuffer class

    - -

    Declaration

    - -

    function AsString: TBuffString; {$ifdef UseInline} inline; {$endif}

    - -

    Description

    -

    The AsString method returns the rest of the buffer converted to unicode.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/backbuttonenabled_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/backbuttonenabled_property.htm deleted file mode 100644 index 3894c317c..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/backbuttonenabled_property.htm +++ /dev/null @@ -1,38 +0,0 @@ - - - - -BackButtonEnabled Property - - - - - - - - - - -

    BackButtonEnabled Property

    -
    - -

    Applies to

    - -

    TFrameViewer and TFrameBrowser components

    - -

    Declaration

    - -

    property BackButtonEnabled: Boolean;

    - -

    Read only and run time only. The BackButtonEnabled property is true if the history list can move backwards. A Back button can then be enabled.

    - -

    See also:

    - -

    GoBack method

    - -

    FwdButtonEnabled property

    - -

    For additional information on setting up a history list, see Setting up a History List.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/base_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/base_property.htm deleted file mode 100644 index e8e3e189b..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/base_property.htm +++ /dev/null @@ -1,39 +0,0 @@ - - - - -Base Property - - - - - - - - - - - -

    Base Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Description

    - -

    property Base: string;

    - -

    Run time only. The Base property returns the document's base directory as given in the <base> tag.

    - -

    The Base property may also be assigned. In order for this to be effective, the assignment must be made before the document is loaded. A <base> tag in the document will override an assignment.

    - -

    See Also

    - -

    HTMLExpandFilename method

    - -

    BaseTarget Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/basetarget_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/basetarget_property.htm deleted file mode 100644 index ad7f69772..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/basetarget_property.htm +++ /dev/null @@ -1,33 +0,0 @@ - - - - -BaseTarget Property - - - - - - - - - -

    BaseTarget Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Description

    - -

    property BaseTarget: string;

    - -

    Read only and run time only. The BaseTarget property returns the Target attribute (if any) accompanying the <base> tag.

    - -

    See Also

    - -

    Base Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/borderstyle_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/borderstyle_property.htm deleted file mode 100644 index 4a8013fdf..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/borderstyle_property.htm +++ /dev/null @@ -1,36 +0,0 @@ - - - - -BorderStyle Property - - - - - - - - - - -

    BorderStyle Property

    -
    - -

    Applies to

    - -

    THtmlViewer components

    - -

    Declaration

    - -

    property BorderStyle: THTMLBorderStyle;

    - -

    The BorderStyle property works slightly different from that for most Delphi components. BorderStyle may be assigned the following values:

    - -

    htFocusedThe border will appear when the viewer has the focus.

    - -

    htNoneNever any border.

    - -

    htSingleA single line border will always be present.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/caretpos_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/caretpos_property.htm deleted file mode 100644 index d8d16b368..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/caretpos_property.htm +++ /dev/null @@ -1,44 +0,0 @@ - - - - -CaretPos Property - - - - - - - - - - -

    CaretPos Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property CaretPos: LongInt;

    - -

    The CaretPos property indicates the character position of the caret marker.

    - -

    Setting CaretPos equal to zero will insure that text searches start from the beginning of the document.

    - -

    The caret position may be made visible by setting htShowDummyCaret in the THtmlViewer htOptions property.

    - -

    See Also:

    - -

    SelStart Property

    - -

    SelLength Property

    - -

    DisplayPosToXY Method

    - -

    GetCharAtPos Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/charset_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/charset_property.htm deleted file mode 100644 index a7171cc4f..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/charset_property.htm +++ /dev/null @@ -1,32 +0,0 @@ - - - - -Charset Property - - - - - - - - - - -

    Charset Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property Charset: TFontCharset;

    - -

    The Charset property specifies which character set is to be used. Before changing the character set to anything but DEFAULT_CHARSET, be sure the proper fonts are installed.

    - -

    Character sets which read right to left are currently not supported.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/class_hierarchy.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/class_hierarchy.htm deleted file mode 100644 index a73a0d128..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/class_hierarchy.htm +++ /dev/null @@ -1,332 +0,0 @@ - - - - -Class Hierarchy - - - - - - - - - - - - -

    Class Hierarchy

    -
    - -

    Class is implemented in unit: -

    HtmlUn2.pas -

    HtmlSubs.pas -

    HtmlSbs1.pas -

    HtmlView.pas -

    FramView.pas -

    FramBrwz.pas -

    - - -

    WinControl Classes

    - - - - - - - - - - - - -
    -

    ThtControlBase -

    -

    -

    TViewerBase -

    The public components' base class -

    -

    THtmlFrameBase -

    Allows THtmlViewer to realize it is embedded in a TFrame -

    -

    TFrameBase -

    The internal frame components' base class -

    - - -

    Viewer Component Classes

    - - - - - - - - - - - - - - - - - -
    -

    TViewerBase -

    The public components' base class -

    -

    THtmlViewerBase -

    What a ThtDocument knows about it's owning viewer. -

    -

    TFrameViewerBase -

    -

    THtmlViewer -

    Renders and displays an HTML document (ThtDocument) -

    -

    TFVBase -

    Renders and displays an HTML frameset (TFrameSetBase) -

    -

    TFrameViewer -

    Handles files only. -

    -

    TFrameBrowser -

    Prepared to handle streams from local file systems or any protocols
    in URLs your implementation of event OnGetPostRequest supports. -

    - - -

    Frameset Classes

    - - - - - - - - - - - - - - - - - - - - -
    -

    TFrameBase -

    The frameset base class -

    -

    TViewerFrameBase -

    Holds a THtmlViewer or TSubFrameSetBase -

    -

    TSubFrameSetBase -

    Holds one or more TFrames and/or TSubFrameSets -

    -

    TfvFrame -

    Used by TFrameViewer -

    -

    TbrFrame -

    Used by TFrameBrowser -

    -

    TFrameSetBase -

    The master frameset held, rendered, and displayed by a TFVBase -

    -

    TSubFrameSet -

    Used by TFrameViewer -

    -

    TbrSubFrameSet -

    Used by TFrameBrowser -

    -

    TFrameSet -

    Used by TFrameViewer -

    -

    TbrFrameSet -

    Used by TFrameBrowser -

    - - -

    HTML Document Classes

    - - - - - - - - - - - - - - - - - - - -
    -

    TIDObject -

    Any document part, that has a name and a position and thus can be addressed via '#id' resp. '#name'. -

    -

    THtmlNode -

    -

    -

    TChPosObj -

    Deprecated. -

    -

    TSectionBase -

    -

    -

    TSection -

    Inline content. Text with embedded inline objects of type
    TFloatingObj. -

    Derivate: -

      -
    • TPreFormated -
    -
    -

    TBlockBase -

    -

    -

    THtmlTable -

    -

    -

    TPage -

    -

    -

    THorzLine -

    -

    - - - -

      - - - - - - - - - - - - - - - - -
    -

    TBlockBase -

    -

    -

    TBlock -

    Owns: -

    -

    Derivates: -

    -
    -

    TFloatingObj -

    -

    -

    TSizeableObj -

    -

    -

    TFormControlObj -

    Derivates: -

    - -
    -

    TControlObj -

    Derivates: -

    -
    -

    TImageObj -

    -

    - -

      - - - - - - - - - - - - - - - -
    -

    TSectionBaseList -

    A list of TSectionBase that owns its objects. -

    -

    TCellBasic -

    Content of block elements -

    -

    TCell -

    -

    -

    TBlockCell -

    Content of block elements like <p>, <div>, ... -

    -

    TCellObjCell -

    Content of table cells <th> and <td> -

    -

    ThtDocument -

    Content of <body> -

    - -

      - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/clear_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/clear_method.htm deleted file mode 100644 index 91dc498bd..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/clear_method.htm +++ /dev/null @@ -1,31 +0,0 @@ - - - - -Clear Method - - - - - - - - - -

    Clear Method

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    procedure Clear;

    - -

    Description

    - -

    The Clear method clears the current document from the view window and deallocates the memory used.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/clearhistory_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/clearhistory_method.htm deleted file mode 100644 index b8682a816..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/clearhistory_method.htm +++ /dev/null @@ -1,34 +0,0 @@ - - - - -ClearHistory Method - - - - - - - - - - -

    ClearHistory Method

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    procedure ClearHistory;

    - -

    Description

    - -

    The ClearHistory method clears the History List.

    - -

    For additional information on setting up a history list, see Setting up a History List.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/codepage_tbuffer_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/codepage_tbuffer_property.htm deleted file mode 100644 index 2904df709..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/codepage_tbuffer_property.htm +++ /dev/null @@ -1,34 +0,0 @@ - - - - -TBuffer.CodePage Property - - - - - - - - - -

    CodePage Property

    -
    - -

    Applies to

    -

    TBuffer class

    - -

    Declaration

    -

    property CodePage: TBuffCodePage;

    - -

    Description

    -

    The property CodePage gets and sets the code page of the byte array in the buffer.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/contents.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/contents.htm deleted file mode 100644 index 1eb5c6119..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/contents.htm +++ /dev/null @@ -1,98 +0,0 @@ - - - - -Introduction - - - - - -
    -NOTICE: most help content still as of version 9.45. The label at the top left egde of each page shows the version of its last update. -
    - - - - - -

    THtmlViewer, TFrameViewer, and TFrameBrowser Components

    -Copyright Information -
    - -

    The HTML component set consists of the THtmlViewer, TFrameViewer, and TFrameBrowser components. All three are HTML document display components:

    - -
    -
    - THtmlViewer -
    - The basic component. THtmlViewer displays single (non-frame) documents. It forms the basis for the other two components. - -
    - TFrameViewer -
    - Displays both Frame and single HTML documents. TFrameViewer is oriented more for local disk file use. - -
    - TFrameBrowser -
    - Also displays Frame and single HTML documents. However, TFrameBrower is oriented toward Internet style protocols and URL usage. - Additional code and/or components are generally required to use TFrameBrowser. - Demos FrameBrowserUsingIndy9, FrameBrowserUsingIndy10 and FrameBrowserUsingICSv7 offer and use such additional code. The demos are using internet access components - Indy Version 9, - Indy Version 10, resp. - ICS Version 7. - -
    - -

    -Version 11 of the HtmlViewer components supports most of the HTML 3.2 specifications with many additional popular HTML 4.01 and HTML 5 enhancements. Please refer to the list of supported elements. -Many Cascading Style Sheet properties are also supported. Please refer to the list of supported style properties. -

    - -
      -
    • Cascading Stylesheets
    • -
    • Frames
    • -
    • Animated GIFs
    • -
    • Bitmap, GIF, JPEG, and PNG Images -
        -
      • Transparent images
      • -
      • Image caching
      • -
      • Left and Right floating images
      • -
      • IsMap support for images used as anchors
      • -
      • Client side image maps (UseMap)
      • -
      • Image sizing through Height and Width attributes
      • -
      -
    • -
    • Large HTML files
    • -
    • HTML Tables
    • -
    • HTML Forms
    • -
    • Font sizes, styles, and colors with HTML tags or default settings
    • -
    • Background colors and images
    • -
    • Formatted printing of the HTML document
    • -
    • Print Preview
    • -
    • Text search
    • -
    • Copy to clipboard
    • -
    • Subscripts and Superscripts
    • -
    • Touch Gestures Support (built-in panning, requires Delphi >= 2010)
    • -
    - -

    While HTML documents are normally associated with the Internet World Wide Web, they are also very useful for displaying all kinds of textual material such as documentation, help files, etc. -Graphics are also easily incorporated in these documents.

    - -

    Updates

    - -

    For the most recent version of the HTML components and for information on what's coming, check in occasionally at:

    - -

    https://github.com/BerndGabriel/HtmlViewer

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/convert_tbuffer_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/convert_tbuffer_method.htm deleted file mode 100644 index 29533e3fa..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/convert_tbuffer_method.htm +++ /dev/null @@ -1,42 +0,0 @@ - - - - -TBuffer.Convert Methods - - - - - - - - - -

    Convert Methods

    -
    - -

    Applies to

    - -

    TBuffer class

    - -

    Declaration

    -

    -class function Convert(Text: PByte; ByteCount: Integer; CodePage: TBuffCodePage): TBuffString; overload; {$ifdef UseInline} inline; {$endif}
    -class function Convert(Text: TBuffString; CodePage: TBuffCodePage): TBuffString; overload; {$ifdef UseInline} inline; {$endif}
    -class function Convert(Text: PByte; ByteCount: Integer; CodePage, InitialCodePage: TBuffCodePage): TBuffString; overload; {$ifdef UseInline} inline; {$endif}
    -

    - -

    Description

    -

    The Convert methods convert byte arrays to unicode.

    -

    The 1st method simply converts Text from CodePage to unicode.

    -

    If you have loaded a text into a unicode string, but actually the text is not coded in unicode, then you can use the 2nd method to convert it to unicode.

    -

    The 3rd method is like the second, but the miscoded string is in a byte array like in the 1st method.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/copyright.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/copyright.htm deleted file mode 100644 index fe27b86cf..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/copyright.htm +++ /dev/null @@ -1,31 +0,0 @@ - - - - -Copyright - - - - - - - - - -

    Documentation and Program Copyright

    -
    - -

    -Copyright © 1995-2008 by L. David Baldwin
    -Copyright © 2008-2014 by HtmlViewer Team
    - -

    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.

    - -

    Note that the source modules, HTMLGIF1.PAS, DITHERUNIT.PAS, URLCONID9.PAS, and URLCONID10.PAS are covered by separate copyright notices located in those modules.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/copytoclipboard_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/copytoclipboard_method.htm deleted file mode 100644 index 60baae556..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/copytoclipboard_method.htm +++ /dev/null @@ -1,42 +0,0 @@ - - - - -CopyToClipboard Method - - - - - - - - - - -

    CopyToClipboard Method

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    procedure CopyToClipboard;

    - -

    Description

    - -

    The CopyToClipboard method copies the selected text to the clipboard.

    - -

    See also

    - -

    SelectAll Method

    - -

    SelLength Property

    - -

    SelText Property

    - -

    GetSelTextBuf Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/currentfile_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/currentfile_property.htm deleted file mode 100644 index 9597c9bca..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/currentfile_property.htm +++ /dev/null @@ -1,29 +0,0 @@ - - - - -CurrentFile Property - - - - - - - - - -

    CurrentFile Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer components

    - -

    Declaration

    - -

    property CurrentFile: String;

    - -

    Read only and run time only. The CurrentFile property returns the full path and filename of the file currently loaded. If no file is loaded or the load was accomplished using the LoadFromBuffer method, CurrentFile will be an empty string.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defbackground_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defbackground_property.htm deleted file mode 100644 index 284b101f5..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defbackground_property.htm +++ /dev/null @@ -1,36 +0,0 @@ - - - - -DefBackground Property - - - - - - - - - - -

    DefBackground Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property DefBackground: TColor;

    - -

    Description

    - -

    DefBackground sets the viewer's default background color. This is the background color when no background information is present in the HTML document file. Either clBtnFace or clWindow are appropriate values.

    - -

    See Also

    - -

    <body> attributes

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/deffontcolor_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/deffontcolor_property.htm deleted file mode 100644 index 3f2305ac6..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/deffontcolor_property.htm +++ /dev/null @@ -1,37 +0,0 @@ - - - - -DefFontColor Property - - - - - - - - - - - -

    DefFontColor Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property DefFontColor: TColor;

    - -

    Description

    - -

    DefFontColor sets the viewer's default text color. This is the color used when no text attribute information is present in the HTML document file.

    - -

    See Also

    - -

    <body> attributes

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/deffontname_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/deffontname_property.htm deleted file mode 100644 index 601230eac..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/deffontname_property.htm +++ /dev/null @@ -1,32 +0,0 @@ - - - - -DefFontName Property - - - - - - - - - - -

    DefFontName Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property DefFontName String;

    - -

    Description

    - -

    DefFontName sets the viewer's font name.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/deffontsize_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/deffontsize_property.htm deleted file mode 100644 index 1bc2a45b2..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/deffontsize_property.htm +++ /dev/null @@ -1,32 +0,0 @@ - - - - -DefFontSize Property - - - - - - - - - - -

    DefFontSize Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property DefFontSize: Integer;

    - -

    Description

    - -

    DefFontSize sets the default font size for the viewer's normal text. The value entered is the point size. Headings, spacing, and other various sizes are scaled appropriately.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defhotspotcolor_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defhotspotcolor_property.htm deleted file mode 100644 index 6be685486..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defhotspotcolor_property.htm +++ /dev/null @@ -1,36 +0,0 @@ - - - - -DefHotSpotColor Property - - - - - - - - - - -

    DefHotSpotColor Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property DefHotSpotColor: TColor;

    - -

    Description

    - -

    DefHotSpotColor sets the viewer's default color for links. This is the color used if the link color is not otherwise specified in the HTML document file.

    - -

    See Also

    - -

    <body> attributes

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defoverlinkcolor_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defoverlinkcolor_property.htm deleted file mode 100644 index 273df50af..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defoverlinkcolor_property.htm +++ /dev/null @@ -1,36 +0,0 @@ - - - - -DefOverLinkColor Property - - - - - - - - - - -

    DefOverLinkColor Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property DefOverLinkColor: TColor;

    - -

    Description

    - -

    DefOverLinkColor sets the default color for links when the mouse is over the link and the fvOverLinksActive option is set. This is the color used if the active link color is not otherwise specified in the HTML document file.

    - -

    See Also

    - -

    <body> attributes

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defprefontname_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defprefontname_property.htm deleted file mode 100644 index 1832fd64f..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defprefontname_property.htm +++ /dev/null @@ -1,32 +0,0 @@ - - - - -DefPreFontName Property - - - - - - - - - - -

    DefPreFontName Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property DefPreFontName String;

    - -

    Description

    - -

    DefPreFontName sets the viewer's font name for fonts used with the <pre>, <code>, and similar tags. Normally a non-proportional font should be selected.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defvisitedlinkcolor_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defvisitedlinkcolor_property.htm deleted file mode 100644 index f7cfc713d..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/defvisitedlinkcolor_property.htm +++ /dev/null @@ -1,38 +0,0 @@ - - - - -DefVisitedLinkColor Property - - - - - - - - - - -

    DefVisitedLinkColor Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property DefVisitedLinkColor: TColor;

    - -

    Description

    - -

    DefVisitedLinkColor sets the default color for links which have been previously visited. This is the color used if the VLink attribute is absent from the <body> tag in the HTML document file.

    - -

    See Also

    - -

    VisitedMaxCount Property

    - -

    <body> attributes

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/displaypostoxy_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/displaypostoxy_method.htm deleted file mode 100644 index e4116f0f7..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/displaypostoxy_method.htm +++ /dev/null @@ -1,57 +0,0 @@ - - - - -DisplayPosToXY Method - - - - - - - - - -

    DisplayPosToXY Method

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    function DisplayPosToXY(DisplayPos: integer; var X, Y: integer): boolean;

    - -

    Description

    - -

    Given a character position in the display, DisplayPosToXY finds the X and Y location of the character on the display. Dimensions are in pixels relative to the upper left corner of the display.

    - -

    DisplayPosToXY returns False if the requested position does not exist.

    - -

    Example:

    - -

    The following code will check to see if the selected position is within the currently displayed area If not it will position the display to insure that it is

    - -

    if Viewer.DisplayPosToXY(Viewer.SelStart, X, Y) then

    - -

    begin

    - -

    VPos := Viewer.VScrollBarPosition;

    - -

    if (Y < VPos) or (Y > VPos +Viewer.ClientHeight-20) then

    - -

    Viewer.VScrollBarPosition := (Y - Viewer.ClientHeight div 2);

    - -

    end;

    - -

    See Also:

    - -

    SelStart Property

    - -

    FindSourcePos Method

    - -

    FindDisplayPos Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/dither_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/dither_property.htm deleted file mode 100644 index 0691f5495..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/dither_property.htm +++ /dev/null @@ -1,41 +0,0 @@ - - - - -Dither Property - - - - - - - - - -

    Dither Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property Dither: Boolean;

    - -

    Description

    - -

    The Dither property determines if color dithering is to be used when rendering images. This property is normally True so as to accommodate images with varying palettes.

    - -

    In cases where a common palette is used by all images, this property may be set to False for quicker and better rendition.

    - -

    Usage Note

    - -

    The Dither property has an effect in 256 color mode only.

    - -

    See Also

    - -

    Palette property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/documentsource_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/documentsource_property.htm deleted file mode 100644 index b09096809..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/documentsource_property.htm +++ /dev/null @@ -1,34 +0,0 @@ - - - - -DocumentSource Property - - - - - - - - - - -

    DocumentSource Property

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    property DocumentSource: String;

    - -

    Read only and run time only. The DocumentSource property contains the HTML source for the document being displayed. Any modifications made in the OnParseBegin event are present in the DocumentSource string.

    - -

    See Also:

    - -

    OnParseBegin Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/dostohtml_function.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/dostohtml_function.htm deleted file mode 100644 index a48ae558b..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/dostohtml_function.htm +++ /dev/null @@ -1,45 +0,0 @@ - - - - -DosToHTML Function - - - - - - - - - -

    DosToHTML Function

    -
    - -

    Unit

    - -

    URLSubs

    - -

    Syntax

    - -

    function DosToHTML(FileName: String): string;

    - -

    Description

    - -

    The DosToHTML function converts a Dos style filename to one in URL style. If the filename is in URL format to begin with, no change takes place.

    - -

    Note: The file:/// protocol is not added by the DosToHTML function.

    - -

    Example

    - -

    After the call,

    - -

    S := DosToHTML('c:\Big\Images\Glass.bmp');

    - -

    S will contain 'c|/Big/Images/Glass.bmp'.

    - -

    See Also:

    - -

    HTMLToDos Function

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/event_thtmlvieweronhotspotclick.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/event_thtmlvieweronhotspotclick.htm deleted file mode 100644 index b3d2501d6..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/event_thtmlvieweronhotspotclick.htm +++ /dev/null @@ -1,58 +0,0 @@ - - - - -OnHotSpotClick Event - - - - - - - - - - -

    OnHotSpotClick Event

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    property OnHotSpotClick: THotSpotClickEvent;

    - -

    Description

    - -

    The OnHotSpotClick event occurs when the mouse is over an hypertext link and the left mouse button is clicked. See the THotSpotClickEvent type for information on the parameters.

    - -

    Example

    - -

    The following code may be used to load the hypertext link URL into an Edit box when a mouse click occurs:

    - -

    Viewer.OnHotSpotClick := HotSpotClick;

    - -

    ....

    - -

    procedure TForm1.HotSpotClick(Sender: TObject; const URL: String;

    - -

    var Handled: Boolean);

    - -

    begin

    - -

    Handled := False;

    - -

    Edit1.Text := HTMLToDos(URL);

    - -

    end;

    - -

    See Also:

    - -

    LinkAttributes Property

    - -

    LinkText Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/event_thtmlvieweronhotspotcovered.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/event_thtmlvieweronhotspotcovered.htm deleted file mode 100644 index 1e19227ad..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/event_thtmlvieweronhotspotcovered.htm +++ /dev/null @@ -1,56 +0,0 @@ - - - - -OnHotSpotCovered Event - - - - - - - - - - -

    OnHotSpotCovered Event

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    property OnHotSpotCovered: THotSpotEvent;

    - -

    Description

    - -

    The OnSpotCovered event occurs when the mouse is moved over or away from an hypertext link. This event may be used to display the destination URL of a hypertext link to allow the user to decide if it should be selected.

    - -

    Example

    - -

    The following code may be used to provide a status line display of the hypertext link at the mouse position:

    - -

    Viewer.OnHotSpotCovered := HotSpotChange;

    - -

    ...

    - -

    procedure TForm1.HotSpotChange(Sender: TObject; const URL: string);

    - -

    begin

    - -

    Panel1.Caption := URL;

    - -

    end;

    - -

    See Also:

    - -

    htOverLinksActive option

    - -

    LinkAttributes Property

    - -

    LinkText Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/find_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/find_method.htm deleted file mode 100644 index 082180c70..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/find_method.htm +++ /dev/null @@ -1,47 +0,0 @@ - - - - -Find and FindEx Methods - - - - - - - - - -

    Find and FindEx Methods

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    function Find(const S: WideString; MatchCase: boolean): boolean;

    - -

    function FindEx(const S: WideString; MatchCase, Reverse: boolean): boolean;

    - -

    Description

    - -

    Use the FindEx method for new programs. The Find method exists for backwards compatibility only.

    - -

    The FindEx method searches through the HTML document for the string, S, returning True if the string is found. If MatchCase is True, a case sensitive search is made. If Reverse is True, the search is made in the reverse direction.

    - -

    Text is searched starting at the current caret position. As each match is found, the text is highlighted, and the caret is placed at the further end of the matched string.

    - -

    Note that in many cases, the caret will not be visible. However, it is still possible to place the virtual caret at any position by left clicking with the mouse.

    - -

    To make the caret visible, see the htOptions and fvOptions propeties.

    - -

    See Also:

    - -

    SelText Property

    - -

    SelStart Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/finddisplaypos_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/finddisplaypos_method.htm deleted file mode 100644 index 487db1908..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/finddisplaypos_method.htm +++ /dev/null @@ -1,39 +0,0 @@ - - - - -FindDisplayPos Method - - - - - - - - - -

    FindDisplayPos Method

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    function FindDisplayPos(SourcePos: integer; Prev: boolean): integer;

    - -

    Description

    - -

    Given a character position in the HTML source, FindDisplayPos finds the nearest equivalent character position in the displayed document.

    - -

    If there is no exact equivalent character position, setting Prev True will find the nearest previous character position. Otherwise the next position will be returned.

    - -

    See Also:

    - -

    SelStart Property

    - -

    FindSourcePos Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/findsourcepos_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/findsourcepos_method.htm deleted file mode 100644 index 24f749925..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/findsourcepos_method.htm +++ /dev/null @@ -1,39 +0,0 @@ - - - - -FindSourcePos Method - - - - - - - - - -

    FindSourcePos Method

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    function FindSourcePos(DisplayPos: integer): integer;

    - -

    Description

    - -

    Given a character position in the display, FindSourcePos finds the equivalent position in the HTML source document.

    - -

    Note that the display position is that value given by the SelStart property.

    - -

    See Also:

    - -

    SelStart Property

    - -

    FindDisplayPos Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/formcontrollist_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/formcontrollist_property.htm deleted file mode 100644 index facd18f5a..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/formcontrollist_property.htm +++ /dev/null @@ -1,88 +0,0 @@ - - - - -FormControlList Property - - - - - - - - - - -

    FormControlList Property

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    property FormControlList: TList;

    - -

    Read only and run time only. The FormControlList contains a list of all the Form controls contained in the currently displayed document. This list enables the programmer to access the controls to read or initialize them while displayed on screen. Some hints on using this list:

    - -

    Declare htmlsubs.pas and htmlsbs1 in your uses clause.

    - -

    Study the definition of TFormControlObj and its decendents (in htmlsubs.pas) as you will probably need to access the fields and methods to make use of the FormControlList.

    - -

    Give any control you want to access a distinctive Name (the Name= item) when defining it in the HTML document. This name can be used to identify the control when searching through the list.

    - -

    The FormControlList is used by THtmlViewer. Do not Free this list.

    - -

    Examples:

    - -

    In the code below, clicking Button4 causes the first form in the document to be submitted. (Viewer is the THtmlViewer displaying the document.)

    - -

    procedure TForm1.Button4Click(Sender: TObject);

    - -

    begin

    - -

    if Viewer.FormControlList.Count > 0 then

    - -

    TFormControlObj(Viewer.FormControlList.Items[0]).MyForm.SubmitTheForm('');

    - -

    end;

    - -

    In the following, clicking Button5 initializes the TEdit control with the name, "Address"

    - -

    procedure TForm1.Button5Click(Sender: TObject);

    - -

    var

    - -

    I: integer;

    - -

    begin

    - -

    with Viewer.FormControlList do

    - -

    for I := 0 to Count -1 do

    - -

    if CompareText(TFormControlObj(Items[I]).Name, 'Address') = 0 then

    - -

    begin

    - -

    if TFormControlObj(Items[I]).TheControl is TEdit then

    - -

    TEdit(TFormControlObj(Items[I]).TheControl).Text := '144 Sands Point';

    - -

    Exit;

    - -

    end;

    - -

    end;

    - -

    See Also:

    - -

    FormData Property

    - -

    OnFormSubmit Event

    - -

    IDControl Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/formdata_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/formdata_property.htm deleted file mode 100644 index a1ee7db99..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/formdata_property.htm +++ /dev/null @@ -1,110 +0,0 @@ - - - - -FormData Property - - - - - - - - - - -

    FormData Property

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    property FormData: TFreeList;

    - -

    The FormData Property is used internally by THtmlViewer for storing and restoring HTML Form data in HTML documents. Users may also use this property for the same purpose or to read and/or modify Form data.

    - -

    As read from THtmlViewer, the FormData consists of a list of TStringLists, one TStringList for each Form in the document. Each string in the TStringList consists of a Name, Value pair separated by an '=' sign:

    - -

    <name>=<value>

    - -

    where <name> is the Name attribute assigned to the form control and <value> is the value entered (or the default value if none has been entered).

    - -

    When an assignment is made to FormData, the same format is used.

    - -

    Example 1:

    - -

    The following shows code for saving and later restoring all the Form data in a document:

    - -

    var

    - -

    List: TFreeList; {htmlun2 must be in Uses clause}

    - -

    procedure TForm1.SaveButtonClick(Sender: TObject);

    - -

    begin

    - -

    List := Viewer.FormData;

    - -

    end;

    - -

    procedure TForm1.RestoreButtonClick(Sender: TObject);

    - -

    begin

    - -

    if Assigned(List) then

    - -

    begin

    - -

    Viewer.FormData := List;

    - -

    List.Free;

    - -

    List := Nil;

    - -

    end;

    - -

    end;

    - -

    Example 2:

    - -

    In the following, two controls in the first form are modified:

    - -

    procedure TForm1.Button4Click(Sender: TObject);

    - -

    var

    - -

    AList: TFreeList;

    - -

    St: TStringList;

    - -

    begin

    - -

    AList := TFreeList.Create;

    - -

    St := TStringList.Create;

    - -

    St.Add('Name=David');

    - -

    St.Add('Address=144 Sands Point Dr.');

    - -

    AList.Add(St);

    - -

    Viewer.FormData := AList;

    - -

    AList.Free;

    - -

    end;

    - -

    See Also

    - -

    FormControlList Property

    - -

    OnFormSubmit Event

    - -

    IDControl Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/fulldisplaysize_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/fulldisplaysize_method.htm deleted file mode 100644 index a5c547cee..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/fulldisplaysize_method.htm +++ /dev/null @@ -1,37 +0,0 @@ - - - - -FullDisplaySize Method - - - - - - - - - -

    FullDisplaySize Method

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    function FullDisplaySize(FormatWidth: integer): TSize;

    - -

    Description

    - -

    Use the FullDisplaySize method to determine the overall height and width of the current document when it is formatted to a particular width.

    - -

    FormatWidthThe format width desired. Most text will wrap to this width.

    - -

    Result.cxThe full width of the formatted document. This may exceed FormatWidth if there are items that can't be compressed or wrapped.

    - -

    Result.cyThe height of the document for the FormatWidth selected.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/fvoptions_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/fvoptions_property.htm deleted file mode 100644 index 6ea010124..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/fvoptions_property.htm +++ /dev/null @@ -1,87 +0,0 @@ - - - - -fvOptions Property - - - - - - - - - - - -

    fvOptions Property

    -
    - -

    Applies to

    - -

    TFrameViewer and TFrameBrowser components

    - -

    Description

    - -

    property fvOptions: set of (fvMetaRefresh, fvNoBorder, fvOverLinksActive, fvNoLinkUnderline,

    - -

    fvPrintTableBackground, fvPrintBackground, fvShowVScroll, fvNoFocusRect,

    - -

    fvNoWheelMouse);

    - -

    The fvOptions property currently has the following items:

    - -

    fvMetaRefresh

    - -

    Turns on the response to the <META Http-Equiv="refresh" ...> tag allowing the document to be replaced as specified by the Contents attribute.

    - -

    fvNoBorder

    - -

    Turns off TFrameViewer's extra outer border. Use in design phase only.

    - -

    fvNoFocusRect

    - -

    Turns off the black outer rectangle which appears when a frame has the focus. Note that this rectangle never shows if fvNoBorder is active.

    - -

    fvNoLinkUnderline

    - -

    Turns off underlines on links.

    - -

    fvOverLinksActive

    - -

    When set, link color will change when the mouse is over the link. Color is determined by the special olink attribute of the <body> tag, if present. If this attribute is absent, the DefOverLinkColor property determines the color.

    - -

    fvPrintMonchromeBlack

    - -

    If set, monochrome printers will always print black. This is set by default since some monochrome printers apparently will not print anything but black.

    - -

    fvPrintBackground

    - -

    If set, allows all background images and colors to be printed. This is off by default.

    - -

    fvPrintTableBackground

    - -

    If set, allows Table background colors to be printed. This is set by default.

    - -

    fvShowVScroll

    - -

    htShowVScroll alters the way the vertical scrollbar is displayed. If fvShowVScroll is not set, no vertical scrollbar is shown if none is needed. If fvShowVScroll is set, the vertical scrollbar will always be shown but may be shown as disabled.

    - -

    fvNoWheelMouse

    - -

    fvNoWheelMouse disables the mouse wheel so that the middle button may be used for other purposes.

    - -

    fvShowDummyCaret

    - -

    Shows the current character position when text is not otherwise selected.

    - -

    fvNoLinkHilite

    - -

    If set, prevents the selection or highlighting of portions of links. This can make clicking a link more reliable by avoiding the possibility of making a selection instead.

    - -

    See Also:

    - -

    htOptions Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/fwdbuttonenabled_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/fwdbuttonenabled_property.htm deleted file mode 100644 index cc3afa69d..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/fwdbuttonenabled_property.htm +++ /dev/null @@ -1,38 +0,0 @@ - - - - -FwdButtonEnabled Property - - - - - - - - - - -

    FwdButtonEnabled Property

    -
    - -

    Applies to

    - -

    TFrameViewer and TFrameBrowser components

    - -

    Declaration

    - -

    property FwdButtonEnabled: Boolean;

    - -

    Read only and run time only. The FwdButtonEnabled property is true if the TFrameViewer history list can move forward. A Forward button can then be enabled.

    - -

    See also:

    - -

    GoFwd method

    - -

    BackButtonEnabled property

    - -

    For additional information on setting up a history list, see Setting up a History List.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getcharatpos_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getcharatpos_method.htm deleted file mode 100644 index ec601edf5..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getcharatpos_method.htm +++ /dev/null @@ -1,40 +0,0 @@ - - - - -GetCharAtPos Method - - - - - - - - - - -

    GetCharAtPos Method

    -
    - -

    Applies to

    - -

    THtmlViewer, component

    - -

    Declaration

    - -

    function GetCharAtPos(Pos: integer; var Ch: WideChar; var Font: TFont): boolean;

    - -

    Description

    - -

    Given Pos, a position in the display, the character at that position is returned as well as its font. Character position is sequential and starts with 0.

    - -

    The function returns false if Pos is out of range.

    - -

    See also

    - -

    SelStart Property

    - -

    CaretPos Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getpostquery_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getpostquery_method.htm deleted file mode 100644 index 042ee5c6b..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getpostquery_method.htm +++ /dev/null @@ -1,47 +0,0 @@ - - - - -GetPostQuery Method - - - - - - - - - -

    GetPostQuery Method

    -
    - -

    Applies to

    - -

    TFrameBrowser component

    - -

    Declaration

    - -

    procedure GetPostQuery(const URL, Query: string; IsGet: boolean);

    - -

    Description

    - -

    The GetPostQuery method may be used to initiate loading a document in TFrameBrowser. It is similar to the LoadURL method but also allows the Posting of Form data. The parameters are:

    - -

    URL, the document to be loaded. It must be a full URL and include the protocol.

    - -

    Query, the form data to be submitted.

    - -

    IsGet, True for a Get, False for a Post.

    - -

    Following the GetPostQuery call, one or more OnGetPostRequest and OnImageRequest events will occur. The user must respond to these events by supplying the requested HTML and images in TMemoryStream form.

    - -

    See also:

    - -

    OnGetPostRequest Event

    - -

    OnImageRequest Event

    - -

    LoadURL Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getseltextbuf_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getseltextbuf_method.htm deleted file mode 100644 index 6a3802614..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getseltextbuf_method.htm +++ /dev/null @@ -1,37 +0,0 @@ - - - - -GetSelTextBuf Method - - - - - - - - - -

    GetSelTextBuf Method

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    function GetSelTextBuf(Buffer: PWideChar, BuffSize: integer): integer;

    - -

    Description

    - -

    The GetSelTextBuf method copies the selected text into the buffer pointed to by Buffer, up to a maximum of BufSize characters, and returns the number of characters copied. For TFrameViewer.GetSetTextBuf, the selected text copied is that of the currently active Frame.

    - -

    See also

    - -

    SelText Property

    - -

    SelLength Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getstring_tbuffer_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getstring_tbuffer_method.htm deleted file mode 100644 index 7c7886d98..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getstring_tbuffer_method.htm +++ /dev/null @@ -1,37 +0,0 @@ - - - - -TBuffer.GetString Method - - - - - - - - - -

    GetString Method

    -
    - -

    Applies to

    - -

    TBuffer class

    - -

    Declaration

    - -

    function GetString(FromIndex, UntilIndex: Integer): TBuffString; {$ifdef UseInline} inline; {$endif}

    - -

    Description

    -

    The GetString method returns a partial string of the buffer converted to unicode.

    -

    The partial string starts with the FromIndexth byte and ends before the UntilIndexth byte.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getviewerurlbase_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getviewerurlbase_method.htm deleted file mode 100644 index 04fec2d31..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/getviewerurlbase_method.htm +++ /dev/null @@ -1,31 +0,0 @@ - - - - -GetViewerURLBase Method - - - - - - - - - -

    GetViewerURLBase Method

    -
    - -

    Applies to

    - -

    TFrameBrowser component

    - -

    Declaration

    - -

    function GetViewerURLBase(Viewer: THtmlViewer): string;

    - -

    Description

    - -

    Given a THtmlViewer currently displayed in TFrameBrowser, this function returns the portion of the URL up to and including the last forward slash.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/goback_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/goback_method.htm deleted file mode 100644 index fd4a523e9..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/goback_method.htm +++ /dev/null @@ -1,40 +0,0 @@ - - - - -GoBack Method - - - - - - - - - - -

    GoBack Method

    -
    - -

    Applies to

    - -

    TFrameViewer and TFrameBrowser components

    - -

    Declaration

    - -

    procedure GoBack;

    - -

    Description

    - -

    The GoBack method is designed to be called when a Back button is pressed to move back in a TFrameViewer's history list.

    - -

    See also:

    - -

    GoFwd method

    - -

    BackButtonEnabled property

    - -

    For additional information on setting up a history list, see Setting up a History List.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/gofwd_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/gofwd_method.htm deleted file mode 100644 index dc5bd7614..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/gofwd_method.htm +++ /dev/null @@ -1,40 +0,0 @@ - - - - -GoFwd Method - - - - - - - - - - -

    GoFwd Method

    -
    - -

    Applies to

    - -

    TFrameViewer and TFrameBrowser components

    - -

    Declaration

    - -

    procedure GoFwd;

    - -

    Description

    - -

    The GoFwd method is designed to be called when a Forward button is pressed to move forward in a TFrameViewer's history list.

    - -

    See also:

    - -

    GoBack method

    - -

    FwdButtonEnabled property

    - -

    For additional information on setting up a history list, see Setting up a History List.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/help.css b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/help.css deleted file mode 100644 index 99938fc95..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/help.css +++ /dev/null @@ -1,17 +0,0 @@ -body { font: 10pt Verdana; margin-top:30pt; } -body { background: url("../images/v945.png") no-repeat; } -body.v114 { background: url("../images/v114.png") no-repeat; } -body.v115 { background: url("../images/v115.png") no-repeat; } -body.v116 { background: url("../images/v116.png") no-repeat; } -body.v117 { background: url("../images/v117.png") no-repeat; } -body.v118 { background: url("../images/v118.png") no-repeat; } -body.v119 { background: url("../images/v119.png") no-repeat; } - -h1 { font-size: 12pt; } -h2 { font-size: 11pt; } -.deprecated { color: red; } -h3 { font-size: 10pt; } - -ul.SeeAlso { list-style-type: none; } -ul.level1 { list-style-image: url(../images/bm3.gif) } -ul.level2 { list-style-image: url(../images/bm4.gif) } diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/history_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/history_property.htm deleted file mode 100644 index 64fc77cf4..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/history_property.htm +++ /dev/null @@ -1,31 +0,0 @@ - - - - -History Property - - - - - - - - - -

    History Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property History: TStrings;

    - -

    Read only and run time only. The History property contains a list of the most recently loaded document filenames with the current filename at index 0.

    - -

    For additional information on setting up a history list, see Setting up a History List.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/historyindex_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/historyindex_property.htm deleted file mode 100644 index 2f6239025..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/historyindex_property.htm +++ /dev/null @@ -1,31 +0,0 @@ - - - - -HistoryIndex Property - - - - - - - - - -

    HistoryIndex Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property HistoryIndex: Integer;

    - -

    Run Time only. The HistoryIndex property shows which history item represents the currently loaded file and file position. Setting HistoryIndex to a new value automatically causes the loading and positioning of the applicable file.

    - -

    For further information on setting up a History list, see Setting up a History List.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/historymaxcount_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/historymaxcount_property.htm deleted file mode 100644 index eef2f35a1..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/historymaxcount_property.htm +++ /dev/null @@ -1,32 +0,0 @@ - - - - -HistoryMaxCount Property - - - - - - - - - - -

    HistoryMaxCount Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property HistoryMaxCount: Integer;

    - -

    The HistoryMaxCount property determines the number of History items which will be maintained. If HistoryMaxCount is 0, then no history list will be maintained.

    - -

    For further information on setting up a History list, see Setting up a History List.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/hscrollbarposition_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/hscrollbarposition_property.htm deleted file mode 100644 index 5a5d843b9..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/hscrollbarposition_property.htm +++ /dev/null @@ -1,38 +0,0 @@ - - - - -HScrollBarPosition Property - - - - - - - - - - -

    HScrollBarPosition Property

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    property HScrollBarPosition: Integer;

    - -

    Description

    - -

    The HScrollBarPosition Property gives access to the viewer's horizontal scrollbar.

    - -

    See Also:

    - -

    HScrollBarRange Property

    - -

    VScrollBarPosition Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/hscrollbarrange_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/hscrollbarrange_property.htm deleted file mode 100644 index 441e85557..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/hscrollbarrange_property.htm +++ /dev/null @@ -1,36 +0,0 @@ - - - - -HScrollBarRange Property - - - - - - - - - - -

    HScrollBarRange Property

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    property HScrollBarRange: Integer;

    - -

    The HScrollBarRange Property gives access to the viewer's horizontal scrollbar range value.

    - -

    See Also:

    - -

    HScrollBarPosition Property

    - -

    VScrollBarRange Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/htmlexpandfilename_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/htmlexpandfilename_method.htm deleted file mode 100644 index 2b5fe9e37..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/htmlexpandfilename_method.htm +++ /dev/null @@ -1,49 +0,0 @@ - - - - -HTMLExpandFilename Method - - - - - - - - - - - -

    HTMLExpandFilename Method

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer components

    - -

    Declaration

    - -

    function HTMLExpandFilename(const Filename: string): string;

    - -

    Description

    - -

    HTMLExpandFilename converts an HTML style file URL to a Dos filename and adds an appropriate path. The path added depends on:

    - -

    1.If the URL starts with a '/' or '\', the path defined by the ServerRoot property is used.

    - -

    2.If the <base> tag specifies "DosPath", then no path is added. Files are then searched for in the usual Dos/Windows manner.

    - -

    3.If the <base> tag specifies another path then that path will be added. File locations are then relative to the base path.

    - -

    4.If there is no <base> tag, then the path of the current HTML file is used. File locations are then relative to that directory.

    - -

    See also

    - -

    Base Property

    - -

    HTMLToDos Function

    - -

    ServerRoot property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/htmltodos.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/htmltodos.htm deleted file mode 100644 index 4a92b8f4a..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/htmltodos.htm +++ /dev/null @@ -1,43 +0,0 @@ - - - - -HTMLToDos - - - - - - - - - -

    HTMLToDos Function

    -
    - -

    Unit

    - -

    HTMLun2

    - -

    Syntax

    - -

    function HTMLToDos(FileName: String): string;

    - -

    Description

    - -

    The HTMLToDos function converts an HTML style filename to one for Dos. If the filename is in Dos format to begin with, no change takes place.

    - -

    Example

    - -

    After the call,

    - -

    S := HTMLToDos('file:///c|/Big/Images/Glass.bmp');

    - -

    S will contain 'c:\Big\Images\Glass.bmp'.

    - -

    See Also:

    - -

    DosToHTML Function

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/htoptions_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/htoptions_property.htm deleted file mode 100644 index 1fa42722d..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/htoptions_property.htm +++ /dev/null @@ -1,73 +0,0 @@ - - - - -htOptions Property - - - - - - - - - - - -

    htOptions Property

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Description

    - -

    property htOptions: set of (htOverLinksActive,htNoLinkUnderline, htPrintBackground,

    - -

    htPrintTableBackground, htShowDummyCaret, htShowVScroll);

    - -

    The htOptions property currently has the following items:

    - -

    htOverLinksActive

    - -

    When set, link color will change when the mouse is over the link. Color is determined by the special olink attribute of the <body> tag, if present. If this attribute is absent, the DefOverLinkColor property determines the color.

    - -

    htNoLinkUnderline

    - -

    Turns off underlines on links.

    - -

    htPrintMonchromeBlack

    - -

    If set, monochrome printers will always print black. This is set by default since some monochrome printers apparently will not print anything but black.

    - -

    htPrintBackground

    - -

    If set, allows all background images and colors to be printed. This is off by default.

    - -

    htPrintTableBackground

    - -

    If set, allows Table background colors to be printed. This is set by default.

    - -

    htShowDummyCaret

    - -

    Shows the current character position when text is not otherwise selected.

    - -

    htShowVScroll

    - -

    htShowVScroll alters the way the vertical scrollbar is displayed. If htShowVScroll is not set, no vertical scrollbar is shown if none is needed. If htShowVScroll is set, the vertical scrollbar will always be shown but may be shown as disabled.

    - -

    htNoWheelMouse

    - -

    htNoWheelMouse disables the mouse wheel so that the middle button may be used for other purposes.

    - -

    htNoLinkHilite

    - -

    If set, prevents the selection or highlighting of portions of links. This can make clicking a link more reliable by avoiding the possibility of making a selection instead.

    - -

    See Also:

    - -

    fvOptions Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/idcontrol_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/idcontrol_property.htm deleted file mode 100644 index 5b0168228..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/idcontrol_property.htm +++ /dev/null @@ -1,60 +0,0 @@ - - - - -IDControl Property - - - - - - - - - - -

    IDControl Property

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    property IDControl[const ID: string]: TObject;

    - -

    Read only and run time only. The IDControl Property provides an easy way to get the instance handle of a Form control or image using the ID attribute defined in the control's HTML tag.

    - -

    For a hidden form control the return is of type THiddenFormControlObj.

    - -

    Example:

    - -

    In the following, clicking Button1 checks the RadioButton control with the ID, "Rad1"

    - -

    procedure TForm1.Button1Click(Sender: TObject);

    - -

    var

    - -

    Obj: TObject;

    - -

    begin

    - -

    Obj := Viewer.IDControl['Rad1'];

    - -

    if (Obj is TRadioButton) then

    - -

    TRadioButton(Obj).Checked := True;

    - -

    end;

    - -

    See Also:

    - -

    FormControlList Property

    - -

    FormData Property

    - -

    OnFormSubmit Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/iddisplay_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/iddisplay_property.htm deleted file mode 100644 index f8c0f950f..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/iddisplay_property.htm +++ /dev/null @@ -1,33 +0,0 @@ - - - - -IDDisplay Property - - - - - - - - - -

    IDDisplay Property

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    property IDDisplay[const ID: string]: boolean;

    - -

    The IDDisplay Property provides an easy way to control the display of a block of HTML text. Typical blocks that can be controled include <div>, <p>, <ul>, <form>, <table>, etc. The block tag must contain an ID= attribute to identify it. Setting IDDisplay to False hides the block and setting it to True displays the block.

    - -

    See Also:

    - -

    Reformat Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/imagecachecount_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/imagecachecount_property.htm deleted file mode 100644 index 1389c0005..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/imagecachecount_property.htm +++ /dev/null @@ -1,36 +0,0 @@ - - - - -ImageCacheCount Property - - - - - - - - - - -

    ImageCacheCount Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property ImageCacheCount: Integer;

    - -

    To save time in reloading HTML files with images, image caching may be used to save images already loaded. The ImageCacheCount property determines the extent to which this is done.

    - -

    With an ImageCacheCount of 5, for instance, images will be saved through 5 document reloads. If the image is not used during that period, it will be dropped from the cache. However, anytime an image is used, the count is reset to zero and it will remain for 5 more reloads.

    - -

    The default value for ImageCacheCount is 5. A value of 0 indicates no caching. The cache may be flushed by setting the count to 0 temporarily and then resetting it to the desired value.

    - -

    Since image storage can use a lot of memory, care should be taken not to overdo the amount of caching.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/insertimage_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/insertimage_method.htm deleted file mode 100644 index da4f52717..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/insertimage_method.htm +++ /dev/null @@ -1,58 +0,0 @@ - - - - -InsertImage Method - - - - - - - - - - -

    InsertImage Method

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    TFrameViewer Declaration

    - -

    function InsertImage(Viewer: THtmlViewer; const Src: string; Stream: TMemoryStream): boolean;

    - -

    THtmlViewer Declaration

    - -

    function InsertImage(const Src: string; Stream: TMemoryStream): boolean;

    - -

    Description

    - -

    The InsertImage method allows images previously requested by the OnImageRequest event to be loaded at a later time. This allows images to be downloaded and inserted when available.

    - -

    SrcThe identifier for the image originally obtained from the OnImageRequest event

    - -

    ViewerThe destination THtmlViewer. This parameter is applicable to the TFrameViewer InsertImage method only. This parameter is obtained from the Sender parameter of the original OnImageRequest event.

    - -

    StreamThe TMemoryStream being returned containing the image. Stream may contain a bitmap, GIF, JPEG, or PNG image. Returning a value of Nil will cause and error bitmap to be displayed for the image.

    - -

    ReturnA True result indicates the image was accepted. A return of False indicates the image cannot be accepted at this time because something else in being processed. Another attempt should be made later.

    - -

    A typical scenario for using the InsertImage method is as follows:

    - -

    The HTML file is loaded. As this is processed, a series of OnImageRequest events occur.

    - -

    The special WaitStream value is returned to the OnImageRequest event. This indicates that the image will be provided later. The Src and Sender parameters are saved.

    - -

    The images are then downloaded. Meanwhile the HTML file is displayed with default images.

    - -

    As the image information is obtained, the InsertImage method is called and the image is displayed.

    - -

    See also:

    - -

    OnImageRequest Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/linkattributes_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/linkattributes_property.htm deleted file mode 100644 index ab195b37c..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/linkattributes_property.htm +++ /dev/null @@ -1,46 +0,0 @@ - - - - -LinkAttributes Property - - - - - - - - - - -

    LinkAttributes Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property LinkAttributes: TStringList;

    - -

    The LinkAttributes property is valid within the following link related event handlers:

    - -

    OnHotspotClick

    - -

    OnHotspotCovered

    - -

    OnHotspotTargetClick

    - -

    OnHotspotTargetCovered

    - -

    LinkAttributes is a TStringList containing all the attributes present in a link tag. Individual attributes may be accessed using TStringList's Values property, as:

    - -

    Destination := Viewer.LinkAttributes.Values['href'];

    - -

    See Also:

    - -

    LinkText Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/linktext_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/linktext_property.htm deleted file mode 100644 index 1a482c30e..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/linktext_property.htm +++ /dev/null @@ -1,48 +0,0 @@ - - - - -LinkText Property - - - - - - - - - - -

    LinkText Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property LinkText: String;

    - -

    The LinkText property is valid within the following link related event handlers:

    - -

    OnHotspotClick

    - -

    OnHotspotCovered

    - -

    OnHotspotTargetClick

    - -

    OnHotspotTargetCovered

    - -

    LinkText contains the displayed text between the <a> tag and its terminating </a> tag. For example, if the HTML is:

    - -

    <a href="#GoThere">This is a <b>Link</b></a>

    - -

    LinkText will contain "This is a Link".

    - -

    See Also:

    - -

    LinkAttributes Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/load_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/load_method.htm deleted file mode 100644 index f52fcb030..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/load_method.htm +++ /dev/null @@ -1,41 +0,0 @@ - - - - -Load Method - - - - - - - - - -

    Load Method

    -
    - -

    Applies to

    - -

    TFrameViewer component

    - -

    Declaration

    - -

    procedure Load(const SRC: String);

    - -

    Description

    - -

    The Load method is used to initiate loading of an HTML document when using one of the OnBufferRequest, OnFileRequest, OnStreamRequest, or OnStringsRequest event handlers. SRC is the identifier of the document to be loaded. This method causes an immediate call to the appropriate event handler.

    - -

    See also:

    - -

    OnBufferRequest Event

    - -

    OnFileRequest Event

    - -

    OnStreamRequest Event

    - -

    OnStringsRequest Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfrombuffer_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfrombuffer_method.htm deleted file mode 100644 index 80f6ceffb..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfrombuffer_method.htm +++ /dev/null @@ -1,62 +0,0 @@ - - - - -LoadFromBuffer Method - - - - - - - - - -

    LoadFromBuffer Method

    -
    - -

    Applies to

    -

    THtmlViewer component

    - -

    Deprecated

    -

    Use methods LoadFromDocument or LoadFromString instead.

    - -

    Declaration

    - -

    procedure LoadFromBuffer(Buffer: PChar; BufSize: LongInt; const Reference: ThtString = '');

    - -

    Description

    - -

    The LoadFromBuffer method loads an HTML document from a memory buffer. BufSize is the number of characters to be loaded. A terminating null character is not required.

    - -

    Reference is an optional reference parameter.

    - -

    Example

    - -

    Assume an HTML document exists in a TMemo object. The following code could be used to then copy the document to an THtmlViewer object:

    - -
    -var
    -	Buffer: PChar;
    -	Size: integer;
    -begin
    -	Size := Memo1.GetTextLen;
    -	Inc(Size);
    -	GetMem(Buffer, Size);
    -	Memo1.GetTextBuf(Buffer,Size);
    -	Viewer.LoadFromBuffer(Buffer, Size-1);
    -	FreeMem(Buffer, Size);
    -end;
    -
    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfromdocument_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfromdocument_method.htm deleted file mode 100644 index 090d3f876..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfromdocument_method.htm +++ /dev/null @@ -1,41 +0,0 @@ - - - - -LoadFromDocument Method - - - - - - - - - -

    LoadFromDocument Method

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    procedure LoadFromDocument(ADocument: TBuffer; const Reference: ThtString = ''; DocType: THtmlFileType = HtmlType);

    - -

    Description

    - -

    The LoadFromDocument method loads a document of the given type from a Document.

    - -

    Reference is an optional reference parameter.

    - -

    See also

    - - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfromfile_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfromfile_method.htm deleted file mode 100644 index 09323f5b9..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfromfile_method.htm +++ /dev/null @@ -1,46 +0,0 @@ - - - - -LoadFromFile Method - - - - - - - - - -

    LoadFromFile Method

    -
    - -

    Applies to

    -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    procedure LoadFromFile(const FileName: ThtString; DocType: THtmlFileType = HtmlType);

    - -

    Description

    - -

    The LoadFromFile method loads a document of the given type for viewing, where Filename is the name and DocType the type of the file to be loaded.

    - -

    Filename may optionally contain a document position identifier separated from the actual filename by a # sign.

    - -

    Example

    -
    -Viewer.LoadFromFile('MyHTML.htm#Contents');
    -
    - -

    would load MyHTML.htm and position the view to the location where the "Contents" target was defined.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfromstream_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfromstream_method.htm deleted file mode 100644 index fecc2987d..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfromstream_method.htm +++ /dev/null @@ -1,41 +0,0 @@ - - - - -LoadFromStream Method - - - - - - - - - -

    LoadFromStream Method

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    procedure LoadFromStream(AStream: TStream; const Reference: ThtString = ''; DocType: THtmlFileType = HtmlType);

    - -

    Description

    - -

    The LoadFromStream method loads a document of the given type from a stream.

    - -

    Reference is an optional reference parameter.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfromstring_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfromstring_method.htm deleted file mode 100644 index 427780d18..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadfromstring_method.htm +++ /dev/null @@ -1,40 +0,0 @@ - - - - -LoadFromString Method - - - - - - - - - -

    LoadFromString Method

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    procedure LoadFromString(const S: ThtString; const Reference: ThtString = ''; DocType: THtmlFileType = HtmlType);

    - -

    Description

    - -

    The LoadFromString method loads a document of the given type from a string.

    - -

    Reference is an optional reference parameter.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadimagefile_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadimagefile_method.htm deleted file mode 100644 index 5924fbc69..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadimagefile_method.htm +++ /dev/null @@ -1,42 +0,0 @@ - - - - -LoadImageFile Method - - - - - - - - - -

    LoadImageFile Method

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer components

    - -

    Deprecated

    -

    Use method LoadFromFile instead.

    - -

    Declaration

    - -

    procedure LoadImageFile(const Filename: ThtString);

    - -

    Description

    - -

    The LoadImageFile method loads a Bitmap, GIF, JPEG, or PNG image for viewing. Filename is the name of the image file to be loaded.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadstrings_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadstrings_method.htm deleted file mode 100644 index 9d2c3f43b..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadstrings_method.htm +++ /dev/null @@ -1,50 +0,0 @@ - - - - -LoadStrings Method - - - - - - - - - -

    LoadStrings Method

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Deprecated

    -

    Use method LoadFromString instead.

    - -

    Declaration

    - -

    procedure LoadStrings(Strings: ThtStrings; const Reference: ThtString = '');

    - -

    Description

    - -

    The LoadStrings method loads an HTML document from a TStrings object.

    - -

    Reference is an optional reference parameter.

    - -

    Example

    - -

    Assume an HTML document exists in a TMemo object. The following line of code could be used to then copy the document to an THtmlViewer object:

    - -
    Viewer.LoadStrings(Memo1.Lines);
    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadtargetfromfile_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadtargetfromfile_method.htm deleted file mode 100644 index abc02cde2..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadtargetfromfile_method.htm +++ /dev/null @@ -1,51 +0,0 @@ - - - - -LoadTargetFromFile Method - - - - - - - - - -

    LoadTargetFromFile Method

    -
    - -

    Applies to

    - -

    TFrameViewer component

    - -

    Declaration

    - -

    procedure LoadTargetFromFile(const Target, Filename: String);

    - -

    Description

    - -

    The LoadTargetFromFile method loads an HTML document into a target frame. Target is the name of the frame where the document is to be displayed, and Filename is the name of the file to be loaded.

    - -

    Filename may optionally contain a document position identifier separated from the actual filename by a # sign.

    - -

    Filenames with extensions .bmp, .gif,.jpg, .jpeg,.png, are loaded as images. Filenames with the extension .txt are loaded as text files.

    - -

    Example

    - -

    FrameViewer.LoadTargetFromFile('RightWin', 'MyHTML.htm#Contents');

    - -

    would load MyHTML.htm into the frame named RightWin and position the view to the location where the "Contents" position was defined.

    - -

    See also:

    - -

    LoadFromFile Method

    - -

    LoadStrings Method

    - -

    LoadFromBuffer Method

    - -

    LoadFromStream Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadtextfile_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadtextfile_method.htm deleted file mode 100644 index 9c356fb55..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadtextfile_method.htm +++ /dev/null @@ -1,42 +0,0 @@ - - - - -LoadTextFile Method - - - - - - - - - -

    LoadTextFile Method

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Deprecated

    -

    Use method LoadFromFile instead.

    - -

    Declaration

    - -

    procedure LoadTextFile(const Filename: ThtString);

    - -

    Description

    - -

    The LoadTextFile method loads a file for viewing treating it as an ASCII text file. If the file is an HTML file, it will be displayed as text showing the HTML tags, etc.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadtextstrings_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadtextstrings_method.htm deleted file mode 100644 index 3b496c50c..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadtextstrings_method.htm +++ /dev/null @@ -1,41 +0,0 @@ - - - - -LoadTextStrings Method - - - - - - - - - -

    LoadTextStrings Method

    -
    - -

    Applies to

    -

    THtmlViewer component

    - -

    Deprecated

    -

    Use method LoadFromString instead.

    - -

    Declaration

    - -

    procedure LoadTextStrings(Strings: ThtStrings);

    - -

    Description

    - -

    The LoadTextStrings method loads a document from a ThtStrings object treating it as plain text.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadurl_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadurl_method.htm deleted file mode 100644 index 697df20b2..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/loadurl_method.htm +++ /dev/null @@ -1,41 +0,0 @@ - - - - -LoadURL Method - - - - - - - - - -

    LoadURL Method

    -
    - -

    Applies to

    - -

    TFrameBrowser component

    - -

    Declaration

    - -

    procedure LoadURL(const URL: string);

    - -

    Description

    - -

    The LoadURL method is used to initiate loading a document in TFrameBrowser. URL must be a full URL and include the protocol.

    - -

    Following the LoadURL call, one or more OnGetPostRequest and OnImageRequest events will occur. The user must respond to these events by supplying the requested HTML and images in TMemoryStream form.

    - -

    See also:

    - -

    OnGetPostRequest Event

    - -

    OnImageRequest Event

    - -

    GetPostQuery Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/makebitmap_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/makebitmap_method.htm deleted file mode 100644 index b59814e13..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/makebitmap_method.htm +++ /dev/null @@ -1,53 +0,0 @@ - - - - -MakeBitmap Method - - - - - - - - - -

    MakeBitmap Method

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    function MakeBitmap(YTop, FormatWidth, Width, Height: integer): TBitmap;

    - -

    Description

    - -

    The MakeBitmap method produces a bitmap of a portion of the document currently loaded.

    - -

    YTopThe top of the bitmap in pixels. 0 would be the start of the document.

    - -

    FormatWidthThe width to which the HTML is to be formatted. Text would typically wrap at this width.

    - -

    WidthThe width of the bitmap. This might be greater than FormatWidth.

    - -

    HeightThe height of the bitmap.

    - -

    Usage Notes

    - -

    The bitmaps generated can be very large. Currently, the maximum Height allowed is 4000 pixels so some sort of paging is required for large documents.

    - -

    Before calling MakeBitmap, use the FullDisplaySize method to ascertain the overall formatted size so that the MakeBitmap parameters can be properly set. The Width returned by FullDisplaySize may exceed FormatWidth if the contents can't be successfully wrapped. This Width should be used to specify the bitmap width. Alternatively, FormatWidth may be set to this Width and FullDisplaySize called again to obtain the new Height.

    - -

    To make a series of bitmaps that can be pieced together, use values for YTop of 0, Height, 2*Height, etc.

    - -

    See Also:

    - -

    FullDisplaySize Method

    - -

    MakeMetafile Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/makemetafile_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/makemetafile_method.htm deleted file mode 100644 index 2bffd8a12..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/makemetafile_method.htm +++ /dev/null @@ -1,56 +0,0 @@ - - - - -MakeMetafile Method - - - - - - - - - - -

    MakeMetafile Method

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    function MakeMetafile(YTop, FormatWidth, Width, Height: integer): TMetafile;

    - -

    Description

    - -

    The MakeMetafile method produces a metafile of a portion of the document currently loaded.

    - -

    YTopThe top of the metafile in pixels. 0 would be the start of the document.

    - -

    FormatWidthThe width to which the HTML is to be formatted. Text would typically wrap at this width.

    - -

    WidthThe width of the metafile. This might be greater than FormatWidth.

    - -

    HeightThe height of the metafile.

    - -

    Usage Notes

    - -

    Currently, the maximum Height allowed is 4000 pixels so some sort of paging is required for large documents.

    - -

    Before calling MakeMetafile, use the FullDisplaySize method to ascertain the overall formatted size so that the MakeMetafile parameters can be properly set. The Width returned by FullDisplaySize may exceed FormatWidth if the contents can't be successfully wrapped. This Width should be used to specify the metafile width. Alternatively, FormatWidth may be set to this Width and FullDisplaySize called again to obtain the new Height.

    - -

    To make a series of metafiles that can be pieced together, use values for YTop of 0, Height, 2*Height, etc.

    - -

    See Also:

    - -

    FullDisplaySize Method

    - -

    MakeBitmap Method

    - -

    MakePagedMetafiles Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/makepagedmetafiles_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/makepagedmetafiles_method.htm deleted file mode 100644 index 307fef423..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/makepagedmetafiles_method.htm +++ /dev/null @@ -1,48 +0,0 @@ - - - - -MakePagedMetafiles Method - - - - - - - - - - -

    MakePagedMetafiles Method

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    function MakePagedMetafiles(Width, Height: integer): TList;

    - -

    Description

    - -

    The MakePagedMetafiles method produces a series of metafiles of an HTML document divided into pages.

    - -

    ResultA TList of TMetafiles.

    - -

    WidthThe width of the metafiles.

    - -

    HeightThe height of the metafiles.

    - -

    This function differs from MakeMetafile in that it is sensitive to the CSS Page-Break properties and the <Page> tag. It also does not split text lines and makes an attempt to keep from splitting tables.

    - -

    No extra margins are included in the Width and Height dimension. If margins are required, they should be added when the metafiles are displayed.

    - -

    See Also:

    - -

    MakeMetafile Method

    - -

    MakeBitmap Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/marginheight_and_marginwidth_properties.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/marginheight_and_marginwidth_properties.htm deleted file mode 100644 index 7cf15bd8e..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/marginheight_and_marginwidth_properties.htm +++ /dev/null @@ -1,34 +0,0 @@ - - - - -MarginHeight and MarginWidth Properties - - - - - - - - - - -

    MarginHeight and MarginWidth Properties

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    property MarginHeight: Integer;

    - -

    property MarginWidth: Integer;

    - -

    These two properties determine the margins around the THtmlViewer display. Values are in pixels.

    - -

    The default vertical margin is 5 and the default horizontal margin is 10.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/maxvertical_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/maxvertical_property.htm deleted file mode 100644 index d8596b69a..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/maxvertical_property.htm +++ /dev/null @@ -1,31 +0,0 @@ - - - - -MaxVertical Property - - - - - - - - - -

    MaxVertical Property

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Description

    - -

    property MaxVertical: integer;

    - -

    MaxVertical gives the height in pixels of the document as it is currently formatted. This height may be used to adjust THtmlViewer's height to just fit a small document.

    - -

    Note that MaxVertical will ordinarily change if the document width changes.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/name_tbuffer_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/name_tbuffer_property.htm deleted file mode 100644 index d50c360c8..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/name_tbuffer_property.htm +++ /dev/null @@ -1,29 +0,0 @@ - - - - -TBuffer.Name Property - - - - - - - - - -

    Name Property

    -
    - -

    Applies to

    -

    TBuffer class

    - -

    Declaration

    -

    property Name: TBuffString;

    - -

    Description

    -

    The property Name gets and sets the name of the buffer.

    -

    Usually this would be the URL or filename of the buffer.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/namelist_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/namelist_property.htm deleted file mode 100644 index 8cc491ac3..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/namelist_property.htm +++ /dev/null @@ -1,31 +0,0 @@ - - - - -NameList Property - - - - - - - - - -

    NameList Property

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    property NameList: TStringList;

    - -

    Read only and run time only. NameList contains a list of all the anchor names (the Name= attribute of the <A> tag) and ID identifiers (the ID= attributes) contained in the currently displayed document.

    - -

    NameList is used by THtmlViewer. Do not Free this list.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/nextchar_tbuffer_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/nextchar_tbuffer_method.htm deleted file mode 100644 index 028149b07..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/nextchar_tbuffer_method.htm +++ /dev/null @@ -1,39 +0,0 @@ - - - - -TBuffer.NextChar Method - - - - - - - - - -

    NextChar Method

    -
    - -

    Applies to

    - -

    TBuffer class

    - -

    Declaration

    - -

    function NextChar: TBuffChar; {$ifdef UseInline} inline; {$endif}

    - -

    Description

    -

    The NextChar method returns the next unicode character.

    -

    One or more bytes might be consumed while retrieving the next unicode character. The Position is advanced accordingly.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/noselect_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/noselect_property.htm deleted file mode 100644 index 44a419855..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/noselect_property.htm +++ /dev/null @@ -1,31 +0,0 @@ - - - - -NoSelect Property - - - - - - - - - -

    NoSelect Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property NoSelect: Boolean;

    - -

    Description

    - -

    Set the NoSelect property to True if you wish to prevent the user from selecting text with the mouse. The default value is False.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/numprinterpages_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/numprinterpages_method.htm deleted file mode 100644 index ac0bf0603..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/numprinterpages_method.htm +++ /dev/null @@ -1,50 +0,0 @@ - - - - -NumPrinterPages Method - - - - - - - - - - -

    NumPrinterPages Method

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    function NumPrinterPages: integer; overload;

    - -

    function NumPrinterPages(var WidthRatio: double): integer; overload;

    - -

    Description

    - -

    This function returns the total number of pages which will be printed.

    - -

    The optional WidthRatio parameter gives an indication if the print output will extend beyond the allowed width. If WidthRatio is 1.0, the entire print job will fil. If WidthRatio is 1.25, something in the print job will extend 25% beyond the allowed width. A WidthRatio value less than 1.0 will not occur.

    - -

    WidthRatio may be used to set the PrintScale property to insure all printing will be within the margins using code similar to:

    - -

    if WidthRatio > 1.0 then

    - -

    Viewer.PrintScale := Viewer.PrintScale * WidthRatio;

    - -

    Note: The NumPrinterPages function can be slow in some situations as it simulates the entire print job.

    - -

    See also:

    - -

    Print Method

    - -

    PrintScale Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onblankwindowrequest_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onblankwindowrequest_event.htm deleted file mode 100644 index 9fb5a372d..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onblankwindowrequest_event.htm +++ /dev/null @@ -1,75 +0,0 @@ - - - - -OnBlankWindowRequest Event - - - - - - - - - -

    OnBlankWindowRequest Event

    -
    - -

    Applies to

    - -

    TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnBlankWindowRequest: TWindowRequestEvent;

    - -

    Description

    - -

    The OnBlankWindowRequest event occurs when the URL Target attribute is either "_blank" or has a window name not defined elsewhere in the HTML document. The user should then open a new window for the URL. An easy way to do this is to launch a second instance of the program.

    - -

    Example

    - -

    This event handler opens a new instance of the program and passes it the URL.

    - -

    procedure TForm1.WindowRequest(Sender: TObject; const Target,

    - -

    URL: string);

    - -

    var

    - -

    S, Dest: string[255];

    - -

    I: integer;

    - -

    PC: array[0..255] of char;

    - -

    begin

    - -

    S := URL;

    - -

    I := Pos('#', S);

    - -

    if I >= 1 then

    - -

    begin

    - -

    Dest := System.Copy(S, I, 255); {local destination}

    - -

    S := System.Copy(S, 1, I-1); {the file name}

    - -

    end

    - -

    else

    - -

    Dest := ''; {no local destination}

    - -

    S := FrameViewer.HTMLExpandFileName(S);

    - -

    if FileExists(S) then

    - -

    WinExec(StrPCopy(PC, ParamStr(0)+' '+S+Dest), sw_Show);

    - -

    end;

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onbufferrequest_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onbufferrequest_event.htm deleted file mode 100644 index b22657eb7..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onbufferrequest_event.htm +++ /dev/null @@ -1,43 +0,0 @@ - - - - -OnBufferRequest Event - - - - - - - - - -

    OnBufferRequest Event

    -
    - -

    Applies to

    - -

    TFrameViewer component

    - -

    Declaration

    - -

    property OnBufferRequest: TBufferRequestEvent;

    - -

    Description

    - -

    An OnBufferRequest event handler allows the program to respond with an HTML document in buffer form whenever a new document is requested.

    - -

    See the TBufferRequestEvent type for usage information.

    - -

    See Also

    - -

    OnFileRequest Event

    - -

    OnStreamRequest Event

    - -

    OnStringsRequest Event

    - -

    Load Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onfilebrowse_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onfilebrowse_event.htm deleted file mode 100644 index 357a5b7ed..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onfilebrowse_event.htm +++ /dev/null @@ -1,44 +0,0 @@ - - - - -OnFileBrowse Event - - - - - - - - - - -

    OnFileBrowse Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    Type TFileBrowseEvent = procedure(Sender, Obj: TObject; var S: string) of Object;

    - -

    property OnFileBrowse: TFileBrowseEvent;

    - -

    Description

    - -

    An <input> tag with a type attribute of file, as

    - -

    <input type="file" ...>

    - -

    displays as an edit box with an associated Browse button. The OnFileBrowse event is triggered when the Browse button is clicked.

    - -

    SenderThe THtmlViewer containing the Browse button.

    - -

    ObjThe TEditFormControlObj of the edit box.

    - -

    SOn input, S will be the contents of the edit box. The event handler would presumably display a file dialogbox and return the filename selected in S.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onfilerequest_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onfilerequest_event.htm deleted file mode 100644 index 2731d44b2..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onfilerequest_event.htm +++ /dev/null @@ -1,43 +0,0 @@ - - - - -OnFileRequest Event - - - - - - - - - -

    OnFileRequest Event

    -
    - -

    Applies to

    - -

    TFrameViewer component

    - -

    Declaration

    - -

    property OnFileRequest: TFileRequestEvent;

    - -

    Description

    - -

    An OnFileRequest event handler allows the program to respond with an HTML document in file form whenever a new document is requested.

    - -

    See the TFileRequestEvent type for usage information.

    - -

    See Also

    - -

    OnBufferRequest Event

    - -

    OnStreamRequest Event

    - -

    OnStringsRequest Event

    - -

    Load Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onformsubmit_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onformsubmit_event.htm deleted file mode 100644 index 5bb8e2e12..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onformsubmit_event.htm +++ /dev/null @@ -1,44 +0,0 @@ - - - - -OnFormSubmit Event - - - - - - - - - - -

    OnFormSubmit Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer and TFrameBrowser components

    - -

    THtmlViewer and TFrameViewer Declaration

    - -

    property OnFormSubmit: TFormSubmitEvent;

    - -

    TFrameBrowser Declaration

    - -

    property OnFormSubmit: TbrFormSubmitEvent;

    - -

    Description

    - -

    The OnFormSubmit event occurs when an HTML Form's submit button is depressed. See the Type TFormSubmitEvent and TbrFormSubmitEvent description for details on the passed parameters.

    - -

    See Also:

    - -

    FormControlList Property

    - -

    FormData Property

    - -

    IDControl Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/ongetpostrequest_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/ongetpostrequest_event.htm deleted file mode 100644 index 86b373aa4..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/ongetpostrequest_event.htm +++ /dev/null @@ -1,42 +0,0 @@ - - - - -OnGetPostRequest Event - - - - - - - - - - -

    OnGetPostRequest and OnGetPostRequestEx Event

    -
    - -

    Applies to

    - -

    TFrameBrowser component

    - -

    Declaration

    - -

    property OnGetPostRequest: TGetPostRequestEvent;

    - -

    property OnGetPostRequestEx: TGetPostRequestExEvent;

    - -

    Description

    - -

    These event handlers allows the program to respond with an HTML document in stream form whenever a new document is requested.

    - -

    The OnGetPostRequest event is retained for backwards compatibility. Use the OnGetPostRequestEx event for new applications -- it has additional parameters.

    - -

    See the TGetPostRequestEvent and TGetPostRequestExEvent type for usage information.

    - -

    See Also

    - -

    OnImageRequest Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onhistorychange_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onhistorychange_event.htm deleted file mode 100644 index 80c83f31a..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onhistorychange_event.htm +++ /dev/null @@ -1,32 +0,0 @@ - - - - -OnHistoryChange Event - - - - - - - - - - -

    OnHistoryChange Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer and TFrameBrowser components

    - -

    Declaration

    - -

    property OnHistoryChange: TNotifyEvent;

    - -

    Description

    - -

    The OnHistoryChange event occurs whenever the history list changes. For further information on history lists, see Setting up a History List.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onhotspottargetclick_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onhotspottargetclick_event.htm deleted file mode 100644 index fbb12d88e..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onhotspottargetclick_event.htm +++ /dev/null @@ -1,64 +0,0 @@ - - - - -OnHotSpotTargetClick Event - - - - - - - - - - -

    OnHotSpotTargetClick Event

    -
    - -

    Applies to

    - -

    TFrameViewer, and TFrameBrowser component

    - -

    Declaration

    - -

    property OnHotSpotTargetClick: THotSpotTargetClickEvent;

    - -

    Description

    - -

    The OnHotSpotTargetClick event occurs when the mouse is over an hypertext link and the left mouse button is clicked. See the THotSpotTargetClickEvent type for information on the parameters.

    - -

    Example

    - -

    The following code may be used to load the hypertext link URL and its Target attribute into an Edit box when a mouse click occurs:

    - -

    Viewer.OnHotSpotTargetClick := HotSpotTargetClick;

    - -

    ....

    - -

    procedure TForm1.HotSpotTargetClick(Sender: TObject;

    - -

    const Target, URL: String; var Handled: Boolean);

    - -

    begin

    - -

    Handled := False;

    - -

    if Target <> '' then

    - -

    Edit1.Text := 'Target: '+Target+' URL: '+URL

    - -

    else

    - -

    Edit1.Text := 'URL: '+URL

    - -

    end;

    - -

    See Also:

    - -

    LinkAttributes Property

    - -

    LinkText Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onhotspottargetcovered_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onhotspottargetcovered_event.htm deleted file mode 100644 index 2f4daaa90..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onhotspottargetcovered_event.htm +++ /dev/null @@ -1,68 +0,0 @@ - - - - -OnHotSpotTargetCovered Event - - - - - - - - - - -

    OnHotSpotTargetCovered Event

    -
    - -

    Applies to

    - -

    TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnHotSpotTargetCovered: THotSpotTargetEvent;

    - -

    Description

    - -

    The OnSpotTargetCovered event occurs when the mouse is moved over or away from an hypertext link. This event may be used to display the destination URL of a hypertext link to allow the user to decide if it should be selected.

    - -

    Example

    - -

    The following code may be used to provide a status line display of the hypertext link at the mouse position:

    - -

    Viewer.OnHotSpotTargetCovered := HotSpotChange;

    - -

    ...

    - -

    procedure TForm1.HotSpotTargetChange(Sender: TObject;

    - -

    const Target, URL: string);

    - -

    begin

    - -

    if URL = '' then

    - -

    Panel2.Caption := ''

    - -

    else if Target <> '' then

    - -

    Panel2.Caption := 'Target: '+Target+' URL: '+URL

    - -

    else

    - -

    Panel2.Caption := 'URL: '+URL

    - -

    end;

    - -

    See Also:

    - -

    fvOverLinksActive Option

    - -

    LinkAttributes Property

    - -

    LinkText Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onhtstreamrequest_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onhtstreamrequest_event.htm deleted file mode 100644 index 07a626581..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onhtstreamrequest_event.htm +++ /dev/null @@ -1,42 +0,0 @@ - - - - -OnhtStreamRequest Event - - - - - - - - - - -

    OnhtStreamRequest Event

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    property OnhtStreamRequest: TGetStreamEvent;

    - -

    Description

    - -

    An OnhtStreamRequest event handler allows the program to respond with an HTML document in stream form whenever a new document is requested. Currently, this event is only used for linked stylesheet document requests.

    - -

    See the TGetStreamEvent type for usage information.

    - -

    See Also

    - -

    LoadFromStream Method

    - -

    LoadStrings Method

    - -

    LoadFromBuffer Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onimageclick_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onimageclick_event.htm deleted file mode 100644 index dfd299a9a..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onimageclick_event.htm +++ /dev/null @@ -1,71 +0,0 @@ - - - - -OnImageClick Event - - - - - - - - - -

    OnImageClick Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnImageClick: TImageClickEvent;

    - -

    Description

    - -

    The OnImageClick event occurs when the mouse is over an image and either mouse button is clicked. See the TImageClickEvent type for information on the parameters.

    - -

    Example

    - -

    The following code may be used to popup a menu when right clicking on an image:

    - -

    procedure TForm1.ImageClick(Sender, Obj: TObject;

    - -

    Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

    - -

    var

    - -

    Pt: TPoint;

    - -

    begin

    - -

    if Button = mbRight then

    - -

    if (Obj is TImageObj) then

    - -

    begin

    - -

    FoundObject := TImageObj(Obj);

    - -

    GetCursorPos(Pt);

    - -

    PopupMenu.Popup(Pt.X, Pt.Y);

    - -

    end;

    - -

    end;

    - -

    Here FoundObject is a TForm1 field used to save the calling TImageObj for use after the menu selection has been made. See the TImageObj type definition in HTMLSUBS.PAS for further imformation on this type. In particular, the field, TImageObj.Source, holds the image's filename, and the property, TImageObj.Bitmap, can be used to obtain a copy of the bitmap itself.

    - -

    See also:

    - -

    OnImageOver Event

    - -

    OnObjectClick Event

    - -

    OnRightClick Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onimageover_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onimageover_event.htm deleted file mode 100644 index cf52669aa..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onimageover_event.htm +++ /dev/null @@ -1,37 +0,0 @@ - - - - -OnImageOver Event - - - - - - - - - -

    OnImageOver Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnImageOver: TImageOverEvent;

    - -

    Description

    - -

    The OnImageOver event occurs when the mouse is moved over an image. See the TImageOverEvent type for information on the parameters.

    - -

    See also:

    - -

    OnImageClick Event

    - -

    Active Images

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onimagerequest_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onimagerequest_event.htm deleted file mode 100644 index a0c2fb588..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onimagerequest_event.htm +++ /dev/null @@ -1,88 +0,0 @@ - - - - -OnImageRequest Event - - - - - - - - - - - - -

    OnImageRequest Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnImageRequest: TGetImageEvent;

    - -

    Description

    - -

    The OnImageRequest event occurs when one or the HTML components encounters an image request and the ViewImages property is set. You can use the OnImageRequest event to supply an image stored in stream form. The stream may contain a Bitmap, GIF (including animated), JPEG, or PNG image.

    - -

    The image may also be supplied at a later time if it is necessary to download it. To indicate the image will be supplied later, return the special TMemoryStream value, WaitStream, rather that an actual stream. The InsertImage method may be used when the image is available.

    - -

    Usage Note

    - -

    The TMemoryStream returned is not freed by the caller. The User must free this later.

    - -

    Example

    - -

    This event handler converts an image file to a TMemoryStream object for test purposes.

    - -

    var

    - -

    MStream: TMemoryStream;

    - -

    ......

    - -

    procedure TForm1.ImageRequest(Sender: TObject; const SRC: string;

    - -

    var Stream: TMemoryStream);

    - -

    var

    - -

    Filename: string[80];

    - -

    begin

    - -

    Stream := Nil; {in case of error}

    - -

    Filename := FrameViewer.HTMLExpandFilename(SRC);

    - -

    if FileExists(Filename) then

    - -

    try

    - -

    if not Assigned(MStream) then

    - -

    MStream := TMemoryStream.Create;

    - -

    MStream.LoadFromFile(FileName);

    - -

    Stream := MStream;

    - -

    except

    - -

    end;

    - -

    end;

    - -

    See Also

    - -

    Type TGetImageEvent

    - -

    InsertImage Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/oninclude_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/oninclude_event.htm deleted file mode 100644 index fb14dc01a..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/oninclude_event.htm +++ /dev/null @@ -1,53 +0,0 @@ - - - - -OnInclude Event - - - - - - - - - -

    OnInclude Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnInclude: TIncludeType;

    - -

    Description

    - -

    The OnInclude event allows text to be inserted in an HTML document at load time. Within the HTML document, the OnInclude event is generated when server side include syntax is encountered. See the TIncludeType for more information on the parameters and on the server side include syntax.

    - -

    Example

    - -

    The OnInclude handler below could be used to fill in the current date in an HTML document

    - -

    procedure TForm1.DoInclude(Sender: TObject; const Command: string; Params: TStrings;

    - -

    var S: string);

    - -

    begin

    - -

    if CompareText(Command, 'Date') = 0 then

    - -

    S := DateToStr(Date)

    - -

    Params.Free;

    - -

    end;

    - -

    In the HTML document, the following would be replaced in its entirety by the generated string.

    - -

    <!--#date -->

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onlink_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onlink_event.htm deleted file mode 100644 index 420772cf7..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onlink_event.htm +++ /dev/null @@ -1,31 +0,0 @@ - - - - -OnLink Event - - - - - - - - - -

    OnLink Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnLink: TLinkType;

    - -

    Description

    - -

    The OnLink event occurs when a <LINK> tag is found while the HTML file is being parsed. See the Type TLinkType description for details on the passed parameters.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onmeta_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onmeta_event.htm deleted file mode 100644 index 11769fa3a..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onmeta_event.htm +++ /dev/null @@ -1,31 +0,0 @@ - - - - -OnMeta Event - - - - - - - - - -

    OnMeta Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnMeta: TMetaType;

    - -

    Description

    - -

    The OnMeta event occurs when a <METAt> tag is found while the HTML file is being parsed. See the Type TMetaType description for details on the passed parameters.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onmetarefresh_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onmetarefresh_event.htm deleted file mode 100644 index 4bf7978e4..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onmetarefresh_event.htm +++ /dev/null @@ -1,33 +0,0 @@ - - - - -OnMetaRefresh Event - - - - - - - - - -

    OnMetaRefresh Event

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    property OnMetaRefresh: TMetaRefreshType;

    - -

    Description

    - -

    The OnMetaRefresh event occurs when a <META> tag is found with the Http_Eq="refresh" attribute. This event may be used to load a file to refresh the display. See the Type TMetaRefreshType description for details on the passed parameters.

    - -

    TFrameViewer handles this event internally as specified by the fvMetaRefresh option.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onmousedouble_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onmousedouble_event.htm deleted file mode 100644 index 74a41d5a0..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onmousedouble_event.htm +++ /dev/null @@ -1,31 +0,0 @@ - - - - -OnMouseDouble Event - - - - - - - - - -

    OnMouseDouble Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnMouseDouble: TMouseEvent;

    - -

    Description

    - -

    The OnMouseDouble event occurs when the mouse left button is double clicked within THtmlViewer or TFrameViewer.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjectblur_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjectblur_event.htm deleted file mode 100644 index 2a1608746..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjectblur_event.htm +++ /dev/null @@ -1,40 +0,0 @@ - - - - -OnObjectBlur Event - - - - - - - - - - -

    OnObjectBlur Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declarations

    - -

    property OnObjectBlur: ThtObjectEvent;

    - -

    Description

    - -

    The OnObjectBlur event occurs when an Object loses the focus. Currently, all Form controls support this event. The Form Control must have an OnBlur="string" attribute in its definition for this event to occur. See the ThtObjectEvent type for further information on the parameters.

    - -

    See Also

    - -

    OnObjectFocus Event

    - -

    OnObjectChange Event

    - -

    OnObjectClick Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjectchange_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjectchange_event.htm deleted file mode 100644 index 80c75fd42..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjectchange_event.htm +++ /dev/null @@ -1,42 +0,0 @@ - - - - -OnObjectChange Event - - - - - - - - - - -

    OnObjectChange Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declarations

    - -

    property OnObjectChange: ThtObjectEvent;

    - -

    Description

    - -

    The OnObjectChange event occurs when an Object loses the focus and a change has been made in its contents. The event occurs before the OnObjectBlur event. Currently, all Form controls support this event. The Form Control must have an OnChange="string" attribute in its definition for this event to occur. See the ThtObjectEvent type for further information on the parameters.

    - -

    See the OpOnChange compiler directive which forces an immediate event for changes in <select> controls..

    - -

    See Also

    - -

    OnObjectFocus Event

    - -

    OnObjectBlur Event

    - -

    OnObjectClick Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjectclick_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjectclick_event.htm deleted file mode 100644 index d6c9e5982..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjectclick_event.htm +++ /dev/null @@ -1,94 +0,0 @@ - - - - -OnObjectClick Event - - - - - - - - - - -

    OnObjectClick Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnObjectClick: TObjectClickEvent;

    - -

    Description

    - -

    The OnObjectClick event occurs when the mouse is left clicked on an Object. Currently, all Form controls support this event. See the TObjectClickEvent type for information on the parameters.

    - -

    Example

    - -

    The following handler will display the status of radio buttons and checkboxes whenever they are changed. Display only occurs for those controls having the OnClick="display" attribute:

    - -

    procedure TForm1.ObjectClick(Sender, Obj: TObject; const OnClick: String);

    - -

    var

    - -

    S: string;

    - -

    begin

    - -

    if OnClick = 'display' then

    - -

    begin

    - -

    if Obj is TFormControlObj then

    - -

    with TFormControlObj(Obj) do

    - -

    begin

    - -

    if TheControl is TCheckBox then

    - -

    with TCheckBox(TheControl) do

    - -

    begin

    - -

    S := Value + ' is ';

    - -

    if Checked then S := S + 'checked'

    - -

    else S := S + 'unchecked';

    - -

    MessageDlg(S, mtCustom, [mbOK], 0);

    - -

    end

    - -

    else if TheControl is TRadioButton then

    - -

    with TRadioButton(TheControl) do

    - -

    begin

    - -

    S := Value + ' is checked';

    - -

    MessageDlg(S, mtCustom, [mbOK], 0);

    - -

    end;

    - -

    end;

    - -

    end;

    - -

    end;

    - -

    See also:

    - -

    OnImageClick Event

    - -

    OnImageOver Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjectfocus_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjectfocus_event.htm deleted file mode 100644 index 5f8e8902e..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjectfocus_event.htm +++ /dev/null @@ -1,40 +0,0 @@ - - - - -OnObjectFocus Event - - - - - - - - - - -

    OnObjectFocus Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declarations

    - -

    property OnObjectFocus: ThtObjectEvent;

    - -

    Description

    - -

    The OnObjectFocus event occurs when an Object gains the focus. Currently, all Form controls support this event. The Form Control must have an OnFocus="string" attribute in its definition for this event to occur. See the ThtObjectEvent type for further information on the parameters.

    - -

    See Also

    - -

    OnObjectBlur Event

    - -

    OnObjectChange Event

    - -

    OnObjectClick Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjecttag_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjecttag_event.htm deleted file mode 100644 index be449d101..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onobjecttag_event.htm +++ /dev/null @@ -1,48 +0,0 @@ - - - - -OnObjectTag Event - - - - - - - - - - - - -

    OnObjectTag Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnObjectTag: TObjectTagEvent;

    - -

    Description

    - -

    The OnObjectTag event occurs when an <object> tag is encountered at document load time. This event may be used by the programmer to respond appropriately to the <object> tag. The HTML <object> tag is used to insert special devices (such as Macromedia Flash) into an HTML document.

    - -

    The OnObjectTag event is similar to the OnPanelCreate event in that a ThvPanel is created to provide a base for whatever object is specified. However, the calling sequence and data provided differ and are appropriate for the <object> tag.

    - -

    See Also:

    - -

    Type TObjectTagEvent

    - -

    <PANEL> tag

    - -

    OnPanelCreate Event

    - -

    OnPanelPrint Event

    - -

    OnPanelDestroy Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onpanelcreate_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onpanelcreate_event.htm deleted file mode 100644 index 3696c4aff..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onpanelcreate_event.htm +++ /dev/null @@ -1,45 +0,0 @@ - - - - -OnPanelCreate Event - - - - - - - - - - - -

    OnPanelCreate Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnPanelCreate: TPanelCreateEvent;

    - -

    Description

    - -

    The OnPanelCreate event occurs when a <PANEL> tag is encountered at document load time. This event may be used to set up the components to be displayed on the panel

    - -

    See Also:

    - -

    Type TPanelCreateEvent

    - -

    <PANEL> tag

    - -

    OnPanelPrint Event

    - -

    OnPanelDestroy Event

    - -

    OnObjectTag Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onpaneldestroy_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onpaneldestroy_event.htm deleted file mode 100644 index eb879b6e6..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onpaneldestroy_event.htm +++ /dev/null @@ -1,41 +0,0 @@ - - - - -OnPanelDestroy Event - - - - - - - - - -

    OnPanelDestroy Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnPanelDestroy: TPanelDestroyEvent;

    - -

    Description

    - -

    The OnPanelDestroy event occurs when a document containing a <PANEL> or <OBJECT> tag is disposed of. This event allows for the cleanup of any objects created for the panel display.

    - -

    See Also:

    - -

    Type TPanelDestroyEvent

    - -

    <PANEL> tag

    - -

    OnPanelCreate Event

    - -

    OnObjectTag Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onpanelprint_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onpanelprint_event.htm deleted file mode 100644 index 9ddf479b3..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onpanelprint_event.htm +++ /dev/null @@ -1,45 +0,0 @@ - - - - -OnPanelPrint Event - - - - - - - - - - - - - -

    OnPanelPrint Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnPanelPrint: TPanelPrintEvent;

    - -

    Description

    - -

    The OnPanelPrint event occurs when a <PANEL> or <OBJECT> is to be printed. This event may be used to supply a bitmap to indicate how the panel should be printed.

    - -

    See Also:

    - -

    Type TPanelPrintEvent

    - -

    <PANEL> tag

    - -

    OnPanelCreate Event

    - -

    OnObjectTag Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onparsebegin_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onparsebegin_event.htm deleted file mode 100644 index 9f14327d8..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onparsebegin_event.htm +++ /dev/null @@ -1,52 +0,0 @@ - - - - -OnParseBegin Event - - - - - - - - - - -

    OnParseBegin Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    Type TParseEvent = procedure(Sender: TObject; var Source: string) of Object;

    - -

    property OnParseBegin: TParseEvent;

    - -

    Description

    - -

    The OnParseBegin event occurs just prior to parsing an HTML document.

    - -

    SenderThe THtmlViewer doing the parsing.

    - -

    SourceThe complete HTML document which will be parsed. This string may be saved, examined, and/or even modified. If the document were encrypted, this event could be used to unencrypt it.

    - -

    Usage Restrictions

    - -

    The TFrameViewer/TFrameBrowser Viewers property does not contain valid information at the time of the OnParseBegin event.

    - -

    If the source is an image file, Source will contain an empty string.

    - -

    This event does not provide any way to handle a linked Style Sheet document.

    - -

    See Also:

    - -

    DocumentSource Property

    - -

    OnParseEnd Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onparseend_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onparseend_event.htm deleted file mode 100644 index 49e8f429b..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onparseend_event.htm +++ /dev/null @@ -1,36 +0,0 @@ - - - - -OnParseEnd Event - - - - - - - - - - -

    OnParseEnd Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnParseEnd: TNotifyEvent;

    - -

    Description

    - -

    The OnParseEnd event occurs when parsing is finished. Sender is the THtmlViewer doing the parsing.

    - -

    See Also

    - -

    OnParseBegin Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onprintheader_and_onprintfooter_events.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onprintheader_and_onprintfooter_events.htm deleted file mode 100644 index 6aaafa059..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onprintheader_and_onprintfooter_events.htm +++ /dev/null @@ -1,47 +0,0 @@ - - - - -OnPrintHeader and OnPrintFooter Events - - - - - - - - - - - - - -

    OnPrintHeader and OnPrintFooter Events

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnPrintHeader: TPagePrinted;

    - -

    property OnPrintFooter: TPagePrinted;

    - -

    Description

    - -

    The OnPrintHeader and OnPrintFooter events occur as each page is printed allowing the user to add a header and/or footer to the page. See the TPagePrinted Type for further information and an example.

    - -

    Note:

    - -

    These events are present to support existing applications. For new work, the OnPrintHTMLHeader and OnPrintHTMLFooter events provide additional features and ease of use.

    - -

    See Also:

    - -

    PrintMargin Properties

    - -

    OPrintHTMLHeader and OnPrintHTMLFooter events

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onprinthtmlheader_and_onprinthtmlfooter_events.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onprinthtmlheader_and_onprinthtmlfooter_events.htm deleted file mode 100644 index 1c4f91775..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onprinthtmlheader_and_onprinthtmlfooter_events.htm +++ /dev/null @@ -1,43 +0,0 @@ - - - - -OnPrintHTMLHeader and OnPrintHTMLFooter Events - - - - - - - - - - - - - -

    OnPrintHTMLHeader and OnPrintHTMLFooter Events

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnPrintHTMLHeader: ThtmlPagePrinted;

    - -

    property OnPrintHTMLFooter: ThtmlPagePrinted;

    - -

    Description

    - -

    The OnPrintHTMLHeader and OnPrintHTMLFooter events occur as each page is printed allowing the user to add a header and/or footer to the page.

    - -

    See the ThtmlPagePrinted Type for usage information for these events.

    - -

    See Also:

    - -

    PrintMargin Properties

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onprocessing_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onprocessing_event.htm deleted file mode 100644 index 7f9f7414f..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onprocessing_event.htm +++ /dev/null @@ -1,33 +0,0 @@ - - - - -OnProcessing Event - - - - - - - - - -

    OnProcessing Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnProcessing: TProcessingEvent;

    - -

    Description

    - -

    The OnProcessing event occurs whenever the viewer either begins or finishes an operation. This event may be used to disable menu items and/or buttons during time consuming operations.

    - -

    See the TProcessingEvent type for information on the parameters.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onprogress_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onprogress_event.htm deleted file mode 100644 index 5bdf9e5fe..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onprogress_event.htm +++ /dev/null @@ -1,34 +0,0 @@ - - - - -OnProgress Event - - - - - - - - - - -

    OnProgress Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declarations

    - -

    property OnProgress: ThtProgressEvent;

    - -

    Description

    - -

    The OnProgress event gives information about the progress of parsing and formatting an HTML document when it is loaded. For large documents, this may be a slow operation.

    - -

    See the ThtProgressEvent help topic for information on the parameters.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onrightclick_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onrightclick_event.htm deleted file mode 100644 index 2d85ccb64..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onrightclick_event.htm +++ /dev/null @@ -1,37 +0,0 @@ - - - - -OnRightClick Event - - - - - - - - - -

    OnRightClick Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnRightClick: TRightClickEvent;

    - -

    Description

    - -

    The OnRightClick event occurs when the right button is clicked anywhere within THtmlViewer or TFrameViewer. It's purpose is to supply sufficient information for a popup menu. See the Type TRightClickEvent description for the details on the parameters.

    - -

    See also:

    - -

    OnImageClick Event

    - -

    OnObjectClick Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onscript_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onscript_event.htm deleted file mode 100644 index 852ed0380..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onscript_event.htm +++ /dev/null @@ -1,32 +0,0 @@ - - - - -OnScript Event - - - - - - - - - - -

    OnScript Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnScript: TScriptEvent;

    - -

    Description

    - -

    The OnScript event occurs when a <script> tag is found while the HTML file is being parsed. See the Type TScriptEvent description for details on the passed parameters.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onsoundrequest_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onsoundrequest_event.htm deleted file mode 100644 index 996d10016..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onsoundrequest_event.htm +++ /dev/null @@ -1,31 +0,0 @@ - - - - -OnSoundRequest Event - - - - - - - - - -

    OnSoundRequest Event

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property OnSoundRequest: TSoundType;

    - -

    Description

    - -

    The OnSoundRequest event occurs when the <BGSOUND> tag is encountered at load time. See the TSoundType type for information on the parameters.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onstreamrequest_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onstreamrequest_event.htm deleted file mode 100644 index 8bc50c30b..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onstreamrequest_event.htm +++ /dev/null @@ -1,43 +0,0 @@ - - - - -OnStreamRequest Event - - - - - - - - - -

    OnStreamRequest Event

    -
    - -

    Applies to

    - -

    TFrameViewer component

    - -

    Declaration

    - -

    property OnStreamRequest: TStreamRequestEvent;

    - -

    Description

    - -

    An OnStreamRequest event handler allows the program to respond with an HTML document in stream form whenever a new document is requested.

    - -

    See the TStreamRequestEvent type for usage information.

    - -

    See Also

    - -

    OnBufferRequest Event

    - -

    OnFileRequest Event

    - -

    OnStringsRequest Event

    - -

    Load Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onstringsrequest_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onstringsrequest_event.htm deleted file mode 100644 index 282ef99e0..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onstringsrequest_event.htm +++ /dev/null @@ -1,43 +0,0 @@ - - - - -OnStringsRequest Event - - - - - - - - - -

    OnStringsRequest Event

    -
    - -

    Applies to

    - -

    TFrameViewer component

    - -

    Declaration

    - -

    property OnStringsRequest: TStringsRequestEvent;

    - -

    Description

    - -

    An OnStringsRequest event handler allows the program to respond with an HTML document in TStrings form whenever a new document is requested.

    - -

    See the TStringsRequestEvent type for usage information.

    - -

    See Also

    - -

    OnBufferRequest Event

    - -

    OnFileRequest Event

    - -

    OnStreamRequest Event

    - -

    Load Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onviewerclear_event.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onviewerclear_event.htm deleted file mode 100644 index 1b0acc63f..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/onviewerclear_event.htm +++ /dev/null @@ -1,31 +0,0 @@ - - - - -OnViewerClear Event - - - - - - - - - -

    OnViewerClear Event

    -
    - -

    Applies to

    - -

    TFrameBrowser component

    - -

    Declaration

    - -

    property OnViewerClear: TNotifyEvent;

    - -

    Description

    - -

    The OnViewerClear event occurs when one of TFrameBrowser's THtmlViewer panes is being cleared or freed. Any pending operations for that THtmlViewer such as images being loaded should be aborted at this time. The Sender parameter for this event is the THtmlViewer being cleared.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/openprint__abortprint__and_closeprint_methods.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/openprint__abortprint__and_closeprint_methods.htm deleted file mode 100644 index 8d8a0788c..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/openprint__abortprint__and_closeprint_methods.htm +++ /dev/null @@ -1,52 +0,0 @@ - - - - -OpenPrint, AbortPrint, and ClosePrint Methods - - - - - - - - - - - - -

    OpenPrint, AbortPrint, and ClosePrint Methods

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declarations

    - -

    procedure OpenPrint;

    - -

    procedure AbortPrint;

    - -

    procedure ClosePrint;

    - -

    Description

    - -

    For most printing situations, these methods would not be used as a simple call to the Print method but be sufficient. However, these methods might prove useful when it is desired to print several odd pages of a document or to even make changes in the document between portions printed.

    - -

    Once OpenPrint is called, the printer will remain open until ClosePrint (or AbortPrint) is called. While open, the Print method may be called successively to print various portions of the document.

    - -

    AbortPrint is provided to close the printer and cancel any portions not yet printed.

    - -

    Example

    - -

    Viewer.OpenPrint;

    - -

    Viewer.Print(1, 1);

    - -

    Viewer.Print(22, 24);

    - -

    Viewer.ClosePrint;

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/palette_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/palette_property.htm deleted file mode 100644 index a9df57cb9..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/palette_property.htm +++ /dev/null @@ -1,73 +0,0 @@ - - - - -Palette Property - - - - - - - - - -

    Palette Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property Palette: HPalette;

    - -

    Description

    - -

    In order to best display many images each of which may have its own palette, the THtmlViewer component normally color dithers each image to a compromise rainbow palette. The Palette property allows the user to access this palette or to change it.

    - -

    A common reason for wishing to change the palette is when the user has complete control of all the images to be displayed and the images all use the same palette.

    - -

    Usage Notes

    - -

    The Palette property has no effect in modes other than 256 color mode.

    - -

    Palettes are copied when read or written.

    - -

    Example

    - -

    Assume that all images will use a common palette. The following shows code in the form's OnCreate event handler which uses the palette from one of those images to change THtmlViewer's palette.

    - -

    procedure TForm1.FormCreate(Sender: TObject);

    - -

    var

    - -

    Bitmap: TBitmap;

    - -

    begin

    - -

    Bitmap := TBitmap.Create;

    - -

    {Load a bitmap that has the common palette}

    - -

    Bitmap.LoadFromFile(ExtractFilePath(ParamStr(0))+'myimage.bmp');

    - -

    {Replace the palette with the common palette}

    - -

    Viewer.Palette := Bitmap.Palette;

    - -

    Bitmap.Free;

    - -

    {no need to dither the images now}

    - -

    Viewer.Dither := False;

    - -

    end;

    - -

    See Also

    - -

    Dither property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/peekchar_tbuffer_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/peekchar_tbuffer_method.htm deleted file mode 100644 index 918bea02b..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/peekchar_tbuffer_method.htm +++ /dev/null @@ -1,39 +0,0 @@ - - - - -TBuffer.PeekChar Method - - - - - - - - - -

    PeekChar Method

    -
    - -

    Applies to

    - -

    TBuffer class

    - -

    Declaration

    - -

    function PeekChar: TBuffChar; {$ifdef UseInline} inline; {$endif}

    - -

    Description

    -

    The PeekChar method returns the next unicode character without advancing the Position.

    -

    As the Position is not advanced subsequent calls to PeekChar always return the same character.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/position_tbuffer_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/position_tbuffer_property.htm deleted file mode 100644 index 4ec1c2b4f..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/position_tbuffer_property.htm +++ /dev/null @@ -1,35 +0,0 @@ - - - - -TBuffer.Position Property - - - - - - - - - -

    Position Property

    -
    - -

    Applies to

    -

    TBuffer class

    - -

    Declaration

    -

    property Position: Integer;

    - -

    Description

    -

    The property Position gets and sets the position in the byte array.

    -

    The NextChar method will read the next character starting at this Position.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/positionto_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/positionto_method.htm deleted file mode 100644 index e856055af..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/positionto_method.htm +++ /dev/null @@ -1,38 +0,0 @@ - - - - -PositionTo Method - - - - - - - - - - -

    PositionTo Method

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    procedure PositionTo(Dest: String);

    - -

    Description

    - -

    Dest is a target name defined within the HTML document. PositionTo positions the document display to that location.

    - -

    Example

    - -

    Viewer.PositionTo('#Contents');

    - -

    The # sign may be omitted if desired.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/print_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/print_method.htm deleted file mode 100644 index a481b15ce..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/print_method.htm +++ /dev/null @@ -1,42 +0,0 @@ - - - - -Print Method - - - - - - - - - - -

    Print Method

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    procedure Print(FromPage, ToPage: integer);

    - -

    Description

    - -

    Print prints the current document starting with FromPage and ending with ToPage. Pages start at page 1.

    - -

    Example

    - -

    Viewer.Print(1, 9999);

    - -

    will print the entire document.

    - -

    See Also:

    - -

    OpenPrint, and ClosePrint methods

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/printmargin_properties.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/printmargin_properties.htm deleted file mode 100644 index 77ea5f116..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/printmargin_properties.htm +++ /dev/null @@ -1,47 +0,0 @@ - - - - -PrintMargin Properties - - - - - - - - - - - - - - - -

    PrintMargin Properties

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declarations

    - -

    property PrintMarginLeft: Double;

    - -

    property PrintMarginRight: Double;

    - -

    property PrintMarginTop: Double;

    - -

    property PrintMarginBottom: Double;

    - -

    The Print Margin Properties determine the margin dimensions when printing. Dimensions are in centimeters.

    - -

    See Also

    - -

    OPrintHTMLHeader and OnPrintHTMLFooter events

    - -

    OnPrintHeader and OnPrintFooter events

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/printscale_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/printscale_property.htm deleted file mode 100644 index 6fdbdb9fe..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/printscale_property.htm +++ /dev/null @@ -1,34 +0,0 @@ - - - - -PrintScale Property - - - - - - - - - - -

    PrintScale Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declarations

    - -

    property PrintScale: Double;

    - -

    The PrintScale Property determines the scale of the printed output. The default value is 1.0 which scales a "screen inch" to one inch on the printer. Larger values allow more print per page and smaller values magnify the printing. Values of 0.75 to 1.25 would be appropriate.

    - -

    See Also

    - -

    Print Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/processing_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/processing_property.htm deleted file mode 100644 index 3944efd5d..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/processing_property.htm +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Processing Property - - - - - - - - - -

    Processing Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property Processing: Boolean;

    - -

    Description

    - -

    Read only. The Processing property is set true whenever the viewer is busy processing data from a previous operation.

    - -

    Some operations such as loading a file with many images may require a lengthy processing time. During this time, most other calls to the viewer will be ignored. The Processing property serves as a flag to indicate when calls can be made.

    - -

    See Also:

    - -

    OnProcessing Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/prop_thtmlviewer_quirksmode.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/prop_thtmlviewer_quirksmode.htm deleted file mode 100644 index 8acad84fb..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/prop_thtmlviewer_quirksmode.htm +++ /dev/null @@ -1,30 +0,0 @@ - - - - -QuirksMode Property - - - - - - - - - - -

    QuirksMode Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property QuirksMode: THtQuirksMode;

    - -

    Default is qmStandard.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/prop_thtmlviewerdocumenttitle.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/prop_thtmlviewerdocumenttitle.htm deleted file mode 100644 index 674d59781..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/prop_thtmlviewerdocumenttitle.htm +++ /dev/null @@ -1,30 +0,0 @@ - - - - -DocumentTitle Property - - - - - - - - - - -

    DocumentTitle Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property DocumentTitle: String;

    - -

    Read only and run time only. The DocumentTitle property returns the document's title as found between the <title> tags.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/prop_thtmlviewerposition.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/prop_thtmlviewerposition.htm deleted file mode 100644 index f81008411..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/prop_thtmlviewerposition.htm +++ /dev/null @@ -1,58 +0,0 @@ - - - - -Position Property - - - - - - - - - - -

    Position Property

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    property Position: LongInt;

    - -

    Description

    - -

    The Position property is a coded number (LongInt) which specifies the part of the document appearing at the top of the window. Since this number is relatively independent of document reformatting, it may be used to save a position to be returned to at a later time.

    - -

    Specifying a Position of 0 will take you to the top of the document. Other values are not easily calculated.

    - -

    For an alternate method of positioning, see:

    - -

    VScrollBarPosition Property

    - -

    VScrollBarRange Property

    - -

    Example

    - -

    var

    - -

    SavePos: LongInt;

    - -

    ....

    - -

    SavePos := Viewer.Position; {save the position}

    - -

    ....

    - -

    {intervening operations which may reformat the document}

    - -

    ....

    - -

    Viewer.Position := SavePos; {return to original spot in document}

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/ptinobject_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/ptinobject_method.htm deleted file mode 100644 index c79216629..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/ptinobject_method.htm +++ /dev/null @@ -1,33 +0,0 @@ - - - - -PtInObject Method - - - - - - - - - -

    PtInObject Method

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    function PtInObject(X, Y: integer; var Obj: TObject): boolean;

    - -

    Description

    - -

    PtInObject determines if the point, (X,Y), is within a particular displayed object. X and Y are THtmlViewer client coordinates, and Obj is the TObject displayed at that coordinate.

    - -

    Currently, the only objects tested are images (TImageObj). PtInObject may be used to ascertain information about images.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/reference.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/reference.htm deleted file mode 100644 index eadc0bda2..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/reference.htm +++ /dev/null @@ -1,28 +0,0 @@ - - - - -Reference - - - - - -

    Reference Parameter

    -
    -

    -The Reference parameter defines a path for partial filenames found in the document. -Path information is often required if the document is loaded from something other than a file. -Generally, this parameter would be a filename or path name where images or linked documents could be found. -

    - -

    Usage Example:

    - -Viewer.LoadFromString(S, 'C:\MyDirectory\'); - -

    will load the document in String, S, and add the path, 'C:\MyDirectory\', to any partial filenames found in the document.

    - -

    The Reference parameter is optional.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/reformat_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/reformat_method.htm deleted file mode 100644 index b08d2e7b3..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/reformat_method.htm +++ /dev/null @@ -1,35 +0,0 @@ - - - - -Reformat Method - - - - - - - - - -

    Reformat Method

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    procedure Reformat;

    - -

    Description

    - -

    The Reformat method causes the layout of a document to be recalculated. This may be necessary after using IDDisplay to hide or show a block of text.

    - -

    See Also:

    - -

    IDDisplay Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/reformatting.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/reformatting.htm deleted file mode 100644 index a4a45ea0f..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/reformatting.htm +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Reformatting - - - - - -

    Reformatting THtmlViewer Content

    -
    -

    Reformatting occurs mainly when the window width is resized causing line wrap to change. Reformatting can also occur when ViewImages is toggled. - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/reload_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/reload_method.htm deleted file mode 100644 index 37fe8d02a..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/reload_method.htm +++ /dev/null @@ -1,31 +0,0 @@ - - - - -Reload Method - - - - - - - - - -

    Reload Method

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    procedure ReLoad;

    - -

    Description

    - -

    The ReLoad method reloads the previously loaded file or frameset. It take into account the mode in which the file was originally loaded (HTML, text, or image mode).

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/replaceimage_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/replaceimage_method.htm deleted file mode 100644 index a4db863f7..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/replaceimage_method.htm +++ /dev/null @@ -1,47 +0,0 @@ - - - - -ReplaceImage Method - - - - - - - - - - - -

    ReplaceImage Method

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    procedure ReplaceImage(Const NameID: String; NewImage: TStream);

    - -

    Description

    - -

    ReplaceImage will replace an existing image in the displayed document with a new image.

    - -

    NameIdThe Name or ID attribute assigned in the relevant <img> tag.

    - -

    NewImageThe new image in stream form. The image format (bmp, gif, etc.) may be in any format currently supported by THtmlViewer.

    - -

    Usage Notes:

    - -

    The replaced image will have the same position and size as the original image.

    - -

    The NewImage stream is not freed by ReplaceImage. It may be freed imediately after the call.

    - -

    See Also:

    - -

    MouseOver images

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/selectall_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/selectall_method.htm deleted file mode 100644 index dc0a14b1e..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/selectall_method.htm +++ /dev/null @@ -1,38 +0,0 @@ - - - - -SelectAll Method - - - - - - - - - - -

    SelectAll Method

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    procedure SelectAll;

    - -

    Description

    - -

    The SelectAll method selects all the document text. This might be used to copy all the text to the clipboard.

    - -

    See Also:

    - -

    SelLength Property

    - -

    CopyToClipboard Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/sellength_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/sellength_property.htm deleted file mode 100644 index ae7c31c93..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/sellength_property.htm +++ /dev/null @@ -1,42 +0,0 @@ - - - - -SelLength Property - - - - - - - - - - -

    SelLength Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property SelLength: LongInt;

    - -

    Description

    - -

    The SelLength property gives the number of characters currently selected. Its value may be positive or negative indicating the direction of selection. The starting value of the selection is given by the SelStart property.

    - -

    The SelLength property may be set to 0 to clear text selection.

    - -

    See Also:

    - -

    SelStart Property

    - -

    SelectAll Method

    - -

    CopyToClipboard Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/selstart_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/selstart_property.htm deleted file mode 100644 index 622cce206..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/selstart_property.htm +++ /dev/null @@ -1,41 +0,0 @@ - - - - -SelStart Property - - - - - - - - - -

    SelStart Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property SelStart: LongInt;

    - -

    Description

    - -

    SelStart specifies the first character of selected text or the current position in the display if there is no selection. Character count starts with 0.

    - -

    To make the current position visible even when no text is selected, see the htShowDummyCaret value in the htOptions property.

    - -

    See Also:

    - -

    SelLength Property

    - -

    DisplayPosToXY Method

    - -

    GetCharAtPos Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/seltext_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/seltext_property.htm deleted file mode 100644 index a5d4173a4..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/seltext_property.htm +++ /dev/null @@ -1,37 +0,0 @@ - - - - -SelText Property - - - - - - - - - -

    SelText Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property SelText: WideString;

    - -

    Description

    - -

    Read only and run time only. The SelText property returns the selected text in string form. For TFrameViewer.or TFrameBrowser, this would be the selection in the currently active frame.

    - -

    See Also

    - -

    GetSelTextBuf Method

    - -

    CopyToClipBoard Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/serverroot_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/serverroot_property.htm deleted file mode 100644 index 489ac866b..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/serverroot_property.htm +++ /dev/null @@ -1,41 +0,0 @@ - - - - -ServerRoot Property - - - - - - - - - -

    ServerRoot Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer components

    - -

    Description

    - -

    property ServerRoot: string;

    - -

    The ServerRoot property establishes an effective root directory on disk. URLs which begin with a slash (or backslash) are considered to be relative to this directory. If no ServerRoot is specified, the root is taken to be the root directory of the current drive.

    - -

    Example

    - -

    ServerRoot := 'C:\MyDirectory';

    - -

    The URL:

    - -

    /images/new.gif

    - -

    will be now be translated to:

    - -

    C\MyDirectory\images\new.gif

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/setting_up_a_history_list.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/setting_up_a_history_list.htm deleted file mode 100644 index ec0619f13..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/setting_up_a_history_list.htm +++ /dev/null @@ -1,41 +0,0 @@ - - - - -Setting up a History List - - - - - - - - - -

    Setting up a History List

    -
    - -

    A history list is useful for backtracking to earlier loaded documents or places previously visited in the same document. From the users point of view, histories are normally accessed as menu items and/or Back/Forward buttons.

    - -

    The key properties and events relating to history lists are the History, TitleHistory, HistoryIndex, and HistoryMaxCount properties, the ClearHistory method, and the OnHistoryChange event.

    - -

    1.Set HistoryMaxCount to the number of list items wanted. HistoryMaxCount should be set to 0 if no history list is desired.

    - -

    2.History (TStrings) will be automatically updated with filenames as files are loaded and positions changed. The History strings may be used as menu items or as listbox contents. Ordering is such that the current file is at index 0.

    - -

    3.TitleHistory (TStrings) will be automatically updated with document titles as files are loaded and positions changed. The TitleHistory strings may be used as menu items or as listbox contents. Ordering is such that the current file is at index 0.

    - -

    4.An OnHistoryChange event occurs each time the history list changes. A method responding to this event may be used to determine which buttons and/or menu items are visible, grayed, or checked.

    - -

    5.The HistoryIndex property may be read to determine which history list item is currently active. Setting of the HistoryIndex property to a new value loads and positions the appropriate file. HistoryIndex can not be set outside the range of the current history list.

    - -

    6.The ClearHistory method may be used to clear the History List.

    - -

    For TFrameViewer, History and TitleHistory list only changes in the main document, and HistoryIndex manipulates only the main document history list. However, TFrameViewer maintains an addtional history structure which keeps track of local changes within the Frames of the current main document. The key items for the local history list are the GoFwd and GoBack methods and the FwdButtonEnabled and BackButtonEnabled properties.

    - -

    7.The GoFwd and GoBack methods should be called by forward and back buttons to move through the local history list. Once the limits of the local history list are reached, these methods will also move through the main history list.

    - -

    8.The FwdButtonEnabled and BackButtonEnabled properties may be checked in the OnHistoryChange event handler to ascertain if the forward and back buttons should be enabled.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/size_tbuffer_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/size_tbuffer_method.htm deleted file mode 100644 index b4afda7cc..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/size_tbuffer_method.htm +++ /dev/null @@ -1,35 +0,0 @@ - - - - -TBuffer.Size Method - - - - - - - - - -

    Size Method

    -
    - -

    Applies to

    - -

    TBuffer class

    - -

    Declaration

    - -

    function Size: Integer; {$ifdef UseInline} inline; {$endif}

    - -

    Description

    -

    The Size method returns the total number of bytes in the buffer.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/special_html_tags_and_attributes.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/special_html_tags_and_attributes.htm deleted file mode 100644 index c1116241e..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/special_html_tags_and_attributes.htm +++ /dev/null @@ -1,82 +0,0 @@ - - - - -Special HTML Tags and Attributes - - - - - - - - - - - -

    Special HTML Tags and Attributes

    -
    - -

    The HTML components use several non-standard Tags which may be used for special purposes.

    - -

    <PAGE>

    - -

    Attributes:

    - -

    none

    - -

    The <PAGE> tag causes printing to end on the current page and a new page started. It has no effect on the displayed document.

    - -

    Note: The <PAGE> tag does not work correctly in documents which use CSS absolute positioning. Use the CSS page-break properties instead.

    - - - - - - -

    <PANEL>

    - -

    Attributes:

    - -

    NAME=string

    - -

    TYPE=string

    - -

    SRC=string

    - -

    ALT=string

    - -

    HEIGHT=n

    - -

    WIDTH=n

    - -

    ALIGN=top|middle|bottom|left|right

    - -

    HSPACE=n

    - -

    The <PANEL> tag may be used to place a ThvPanel in a displayed HTML document. The ThvPanel in turn may be used as a base for adding other Delphi VCL components. For all practical purposes, ThvPanel is equivalent to TPanel.

    - -

    <PANEL> is similar in usage to the <IMG> tag and may be used anywhere an <IMG> might be appropriate. When the ThvPanel is created at load time, an OnPanelCreate event is generated. When the document is disposed of, there is an OnPanelDestroy event. These events allow the programmer to manage the contents of the panel.

    - -

    The NAME, TYPE, and SRC attributes are passed as parameters in the OnPanelCreate event and NAME is also assigned to the Panel's Name property. TYPE and SRC are not otherwise used and are there for the programmer's convenience. The ALT string appears when the document is printed if there is no OnPanelPrint event handler.

    - -

    The HEIGHT, WIDTH, ALIGN, and HSPACE attributes are similar to those of the <IMG> tag.

    - -

    By default, the panel is displayed with a white background and a black border. However, these and other properties may be changed in the OnPanelCreate event handler. The only properties which can't be changed at that time are the Top and Left properties. Even the Height and Width may be changed in the handler.

    - -

    Special Note:

    - -

    The <OBJECT> tag also has a similar OnObjectTag event which produces a ThvPanel to be used as a base for the object.

    - -

    See Also:

    - -

    OnPanelCreate Event

    - -

    OnPanelDestroy Event

    - -

    OnPanelPrint Event

    - -

    OnObjectTag Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/supported_elements.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/supported_elements.htm deleted file mode 100644 index 160ced34e..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/supported_elements.htm +++ /dev/null @@ -1,342 +0,0 @@ - - - - -Supported HTML Tags and Attributes - - - - - - - - - - - - - - - -

    Summary of Supported Tags and Attributes

    -
    -
    -
    Version 11 additions are shown in blue
    -
    - - - - - -
    - -
    -

    Document Tags

    -
    <HTML>...</HTML>
    -<HEAD>...</HEAD>
    -<STYLE>...</STYLE>
    -<BASE>
    -   HREF=base
    -<TITLE>...</TITLE>
    -<BODY>...</BODY>
    -   BACKGROUND=bitmap
    -   TEXT=color
    -   BGCOLOR=color
    -   LINK=color
    -   VLINK=color
    -   OLINK=color
    -   MARGINWIDTH=n
    -   MARGINHEIGHT=n
    -   BGPROPERTIES=fixed
    -   TOPMARGIN=n
    -   LEFTMARGIN=n
    - -

    Physical Phrase Markup Tags

    -
    <B>...</B>
    -<I>...</I>
    -<U>...</U>
    -<TT>...</TT>
    -<S>...</S>
    -<FONT>...</FONT>
    -   SIZE=n  (n=1..7) or SIZE=+-n (incremental change)
    -   COLOR=color
    -   FACE=facename
    -<SUB>...</SUB>
    -<SUP>...</SUP>
    -<BIG>...</BIG>
    -<SMALL>...</SMALL>
    -<STRIKE>...</STRIKE>
    -<NOBR>...</NOBR>
    -
    - -

    Logical Phrase Markup Tags

    -
    <EM>...</EM>
    -<STRONG>...</STRONG>
    -<CITE>...</CITE>
    -<VAR>...</VAR>
    -<CODE>...</CODE>
    -<KBD>...</KBD>
    -<SAMP>...</SAMP>
    -<MARK>...</MARK>
    -<DFN>...</DFN>
    -<ABBR>...</ABBR>
    -<ACRONYM>...</ACRONYM>
    -<INS>...</MARK>
    -<DEL>...</DEL>
    -
    - -

    Block Tags

    -
    <P>...(</P>)
    -    ALIGN=left|center|right|justify
    -<ADDRESS>...</ADDRESS>
    -<BLOCKQUOTE>...</BLOCKQUOTE>
    -<PRE>...</PRE>
    -<CENTER>...</CENTER>
    -<DIV>...</DIV>
    -    ALIGN=left|center|right|justify
    -<HEADER>...</HEADER>
    -    ALIGN=left|center|right|justify
    -<FOOTER>...</FOOTER>
    -    ALIGN=left|center|right|justify
    -<SECTION>...</SECTION>
    -    ALIGN=left|center|right|justify
    -<ARTICLE>...</ARTICLE>
    -    ALIGN=left|center|right|justify
    -<NAV>...</NAV>
    -    ALIGN=left|center|right|justify
    -<ASIDE>...<ASIDE/>
    -    ALIGN=left|center|right|justify
    -<HGROUP>...</HGROUP>    
    -    ALIGN=left|center|right|justify
    -
    - -

    Lists

    -
    <OL>...</OL>
    -   START=value
    -   TYPE=1|a|A|i|I
    -<UL>...</UL>
    -   PLAIN
    -   TYPE=plain|none
    -<DIR>...</DIR>
    -<MENU>...</MENU>
    -  <LI>...(</LI>)
    -    VALUE=n
    - -

    Description List

    -
    <DL>...</DL>
    -  <DD>...</DD>
    -  <DT>...</DT>
    - -

    Tables

    -
    <TABLE>...<TABLE>
    -   BORDER or BORDER=n
    -   FRAME=void|above|below|hsides|lhs|rhs|vsides|box|border
    -   RULES=none|rows|cols|all
    -   ALIGN=left|center|right
    -   CELLSPACING=value
    -   CELLPADDING=value
    -   WIDTH=n|n%
    -   BACKGROUND=image
    -   BGCOLOR=color
    -   BORDERCOLOR=color
    -   BORDERCOLORLIGHT=color
    -   BORDERCOLORDARK=color
    -   HSPACE=n
    -   VSPACE=n
    -   HEIGHT=n|n%
    -<COLGROUP>...</COLGROUP>
    -   VALIGN=top|center|bottom
    -   ALIGN=left|center|right
    -   WIDTH=n|n%|n*
    -<COL>
    -   VALIGN=top|center|bottom
    -   ALIGN=left|center|right
    -   WIDTH=n|n%|n*
    -   SPAN=n
    -<CAPTION>...</CAPTION>
    -   ALIGN=top|bottom
    -<TR>...</TR>
    -   VALIGN=top|center|bottom
    -   ALIGN=left|center|right
    -   BGCOLOR=color
    -   HEIGHT=n|n%
    -<TH>...</TH>, <TD>...</TD>
    -   ROWSPAN=n
    -   COLSPAN=n
    -   WIDTH=n|n%
    -   HEIGHT=n|n%
    -   VALIGN=top|center|bottom
    -   ALIGN=left|center|right
    -   BGCOLOR=color
    -   NOWRAP
    -<THEAD><TBODY><TFOOT>   (printing)
    - -

    Forms

    -
    <FORM>...</FORM>
    -   METHOD=post|get
    -   ACTION=url
    -<FIELDSET>...</FIELDSET>
    -<LEGEND>...</LEGEND>
    -<INPUT>...</INPUT>
    -   TYPE=text|password|submit|reset|radio|checkbox|hidden|image|button|file
    -   NAME=string
    -   VALUE=string
    -   PLACEHOLDER=string
    -   SIZE=chars       (text, password)
    -   MAXLENGTH=chars  (text, password)
    -   CHECKED          (radio, checkbox)
    -   ONCLICK=string   (button, radio, checkbox, edit)
    -   TABINDEX=n
    -   DISABLE
    -<SELECT>...</SELECT>
    -   NAME=string
    -   PLACEHOLDER=string
    -   MULTIPLE
    -   SIZE=lines
    -   OnClick
    -   <OPTION>...(</OPTION>)
    -      SELECTED
    -      VALUE=string
    -   TABINDEX=n
    -   DISABLE
    -<TEXTAREA>...</TEXTAREA>
    -   NAME=string
    -   PLACEHOLDER=string
    -   ROWS=n
    -   COLS=n
    -   WRAP=off|soft|hard
    -   OnClick
    -   TABINDEX=n
    -   DISABLE
    -<OPTION>...</OPTION>
    - -

    Character Level Elements

    -
    <BR>
    -   CLEAR=left|right
    -<WBR>
    -<IMG>
    -   SRC=image
    -   ALT=string
    -   ALIGN=top|middle|bottom|left|right
    -   BORDER=n
    -   WIDTH=n,n%
    -   HEIGHT=n,n%
    -   TRANSP   (non-standard, Lower Left pixel defines transparent color
    -   IMAGEMAP
    -   USEMAP=url (local URL only)
    -   HSPACE=n
    -   VSPACE=n
    -   ACTIVE
    -<OBJECT>...</OBJECT>
    -   ALT=string
    -   ALIGN=top|middle|bottom|left|right
    -   WIDTH=n,n%
    -   HEIGHT=n,n%
    -   HSPACE=n
    -   VSPACE=n
    -<PARAM>
    -   NAME=string
    -   VALUE=string
    - -

    Anchors

    -
    <A>...</A>
    -   HREF=url
    -   NAME=string
    -   TABINDEX=n
    - -

    Client Side Image Maps

    -
    <MAP>...</MAP>
    -   NAME=string
    -<AREA>
    -   SHAPE=RECT|CIRC|CIRCLE|POLY|POLYGON
    -   COORDS="n1, n2, ...., nn"
    -   HREF=url
    -   NOHREF
    -   TITLE=title
    -
    - -

    Miscellaneous

    -
    <Hn>...</Hn>   n = 1..6
    -   ALIGN=left|center|right
    -<HR>
    -   SIZE=n
    -   WIDTH=n|n%
    -   COLOR=color
    -   ALIGN=left|center|right
    -   NOSHADE
    -<BASEFONT>
    -   SIZE=n  (n=1..7) or SIZE=+-n (incremental change)
    -<BGSOUND>
    -   SRC=filename
    -   LOOP=n
    -<Span>
    -   Style
    - -

    Frame Syntax

    -
    <FRAMESET>...</FRAMESET>
    -   ROWS|COLS=n1, n2, .., nn  (absolute, %, or *)
    -   BORDER=n         (Main FRAMESET only)
    -   FRAMEBORDER=n    (Main FRAMESET only)
    -<FRAME>
    -   SRC=filename
    -   NAME=windowname
    -   SCROLLING=yes|no|auto
    -   NORESIZE
    -   MARGINHEIGHT=n
    -   MARGINWIDTH=n
    -<NOFRAMES>...</NOFRAMES>
    -
    - -

    Color Syntax

    -

    Color information may consist of -

      -
    • a hexidecimal red, green, and blue value such as #FF8000 or -
    • a decimal color triple like RGB(255, 128, 0) or -
    • via hue, saturation and luminance like HSL(180, 255, 128) or -
    • be one of the -following identifiers:

      -

      Black, Maroon, Green, Olive, Navy, Purple, Teal, Gray, -Silver, Red, Lime, Yellow, Blue, Fuchsia, Aqua, white, Aliceblue, Antiquewhite, Aquamarine, Azure, Beige, Bisque, -Blanchedalmond, Blueviolet, Brown, Burlywood, Cadetblue, Chartreuse, Chocolate, Coral, Cornflowerblue, Cornsilk, -Crimson, Cyan, Darkblue, Darkcyan, Darkgoldenrod, Darkgray, Darkgreen, Darkkhaki, Darkmagenta, Darkolivegreen, -Darkorange, Darkorchid, Darkred, Darksalmon, Darkseagreen, Darkslateblue, Darkslategray, Darkturquoise, -Darkviolet, Deeppink, Deepskyblue, Dimgray, Dodgerblue, Firebrick, Floralwhite, Forestgreen, Gainsboro, -Ghostwhite, Gold, Goldenrod, Greenyellow, Honeydew, Hotpink, Indianred, Indigo, Ivory, Khaki, Lavender, -Lavenderblush, Lawngreen, Lemonchiffon, Lightblue, Lightcoral, Lightcyan, Lightgoldenrodyellow, Lightgreen, -Lightgrey, Lightpink, Lightsalmon, Lightseagreen, Lightskyblue, Lightslategray, Lightsteelblue, Lightyellow, -Limegreen, Linen, Magenta, Mediumaquamarine, Mediumblue, Mediumorchid, Mediumpurple, Mediumseagreen, -Mediumslateblue, Mediumspringgreen, Mediumturquoise, Mediumvioletred, Midnightblue, Mintcream, Mistyrose, -Moccasin, Navajowhite, Oldlace, Olivedrab, Orange, Orangered, Orchid, Palegoldenrod, Palegreen, Paleturquoise, -Palevioletred, Papayawhip, Peachpuff, Peru, Pink, Plum, Powderblue, Rosybrown, Royalblue, Saddlebrown, Salmon, -Sandybrown, Seagreen, Seashell, Sienna, Skyblue, Slateblue, Slategray, Snow, Springgreen, Steelblue, Tan, Thistle, -Tomato, Turquoise, Violet, Wheat, Whitesmoke, Yellowgreen, - -background, activecaption, inactivecaption, menu, window, -windowframe, menutext, windowtext, captiontext, activeborder, -inactiveborder, appworkSpace, highlight, hightlighttext, buttonface, -buttonshadow, graytext, buttontext, inactivecaptiontext, buttonhighlight, -threeddarkshadow, threedlightshadow, infotext, infobackground, scrollbar, -threedface, threedhighlight, threedshadow.

      -
    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/supported_properties.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/supported_properties.htm deleted file mode 100644 index 02bfd49af..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/supported_properties.htm +++ /dev/null @@ -1,395 +0,0 @@ - - - - -Supported CSS Properties - - - - - - - - - - -

    Cascading Style Sheet Support

    -
    -
    -
    Version 10 additions are shown in red
    -
    Version 11 additions are shown in blue
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Pseudo-Classes
    Pseudo-ClassSupportedUnsupported
     :linkCheckmark 
     :visitedCheckmark 
     :active Checkmark
     :hoverCheckmark 
     :first-letter Checkmark
     :first-line Checkmark
    -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    CSS1 Properties
    PropertySupportedUnsupported
    Background (shorthand)Checkmark(see specific properties) -  
    Background-attachmentCheckmarkfixed, scroll 
    Background-colorCheckmark 
    Background-imagemost block tagsinline tags
    Background-positionCheckmark 
    Background-repeatCheckmark 
    Border (shorthand)Checkmark(see specific properties) -  Note 1
    Border-style (shorthand)Checkmark -  
    Border-top..left (shorthand)Checkmark(see specific properties) -  
    Border-top..left-colorCheckmark 
    Border-top..left-styleCheckmark 
    Border-top..left-widthCheckmark 
    Border-color (shorthand)Checkmark 
    ClearCheckmark  
    ColorCheckmark 
    Displaynone, inline (<li> only)block, inline (all other tags), list-item
    FloatCheckmark 
    Font (shorthand)Checkmark(see specific properties) -  
    Font-familyCheckmark 
    Font-sizeCheckmark 
    Font-stylenormal, italicoblique
    Font-variantnormal, small-caps 
    Font-weightnormal, bold, 100..900bolder, lighter
    HeightCheckmark most cases  
    Letter-spacingCheckmark 
    Line-heightCheckmark 
    List-style (shorthand)Checkmark(see specific properties) -  
    List-style-imageCheckmark 
    List-style-position Checkmark
    List-style-typeCheckmark 
    Margin (shorthand)Checkmark(see specific properties) -  
    Margin-top..leftCheckmark table cells
    Padding (shorthand)Checkmark 
    Padding-top..leftCheckmark 
    Text-alignCheckmark 
    Text-decortationnone, line-through, underlineoverline, blink
    Text-indentCheckmark 
    Text-transformuppercase, lowercase, nonecapitalize
    Vertical-aligntop, text-top, middle, baseline, bottom, sub, supertext-bottom Note 2
    WidthCheckmark 
    Word-spacing Checkmark
    -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    CSS2 Properties
    PropertySupportedUnsupported
    Clip Checkmark
    Empty-cellsCheckmark 
    LeftCheckmark 
    Overflowhiddenscroll
    Page-break-before/afteralways, auto left, right
    Page-break-insideavoid, auto  
    Position Checkmark block tags inline tagsNote 3
    Top Checkmark 
    Visibility hidden, visible. Block tags onlyinherit
    White-space nowrap, normalpre, pre-wrap, pre-line
    Word-Wrap break-word
    Z-index Checkmark 
    -

    - - - - - - - - - - - - - - - - - -
    NOTES
    1Limited support for inline borders.
    2Vertical-Align supported for images and form controls only.
    3Position is supported for block tags only.
    -

     

    - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/target_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/target_property.htm deleted file mode 100644 index 6ffb8b677..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/target_property.htm +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Target Property - - - - - - - - - -

    Target Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property Target: String;

    - -

    Description

    - -

    Read only and run time only. The Target property returns the Target attribute (if any) accompanying the most recently selected (left mouse click) URL.

    - -

    The Target attribute specifies the destination window or frame for the URL.

    - -

    See Also

    - -

    URL Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframebrowser_component.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframebrowser_component.htm deleted file mode 100644 index 7e6496e9d..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframebrowser_component.htm +++ /dev/null @@ -1,37 +0,0 @@ - - - - -TFrameBrowser Component - - - - - - - - - -

    TFrameBrowser Component

    -Properties -Methods -Events -Tasks -
    - -

    Unit

    - -

    FramBrwz.Pas

    - -

    Description

    - -

    TFrameBrowser is designed to handle Internet style URL requests and accepts its input from streams. This makes it especially suitable for connecting to an HTTP component for online use. In addition, specialized protocols may be easily developed to allow reading HTML documents from other sources such as compressed files, program resources, etc.

    - -

    See Also:

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframebrowser_events.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframebrowser_events.htm deleted file mode 100644 index 5f8b4d044..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframebrowser_events.htm +++ /dev/null @@ -1,58 +0,0 @@ - - - - -TFrameBrowser Events - - - - - - - - - -

    TFrameBrowser Events

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Key Events
     
    OnBlankWindowRequest
    OnFileBrowse
    OnGetPostRequest
    OnGetPostRequestEx
    OnHistoryChange
    OnHotSpotTargetCovered
    OnHotSpotTargetClick
    OnImageClick
    OnImageOver
    OnImageRequest
    OnInclude
    OnLink
    OnMeta
    OnMouseDouble
    OnObjectBlur
    OnObjectChange
    OnObjectClick
    OnObjectFocus
    OnObjectTag
    OnPanelCreate
    OnPanelDestroy
    OnPanelPrint
    OnParseBegin
    OnParseEnd
    OnPrintHTMLHeader
    OnPrintHTMLFooter
    OnPrintFooter
    OnPrintHeader
    OnProcessing
    OnProgress
    OnScript
    OnSoundRequest
    OnRightClick
    OnViewerClear
    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframebrowser_methods.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframebrowser_methods.htm deleted file mode 100644 index f2c447535..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframebrowser_methods.htm +++ /dev/null @@ -1,41 +0,0 @@ - - - - -TFrameBrowser Methods - - - - - - - - - -

    TFrameBrowser Methods

    -
    - - - - - - - - - - - - - - - - - - - - -
    Clear
    ClearHistory
    CopyToClipboard
    Find
    FindEx
    GetPostQuery
    GetSelTextBuf
    GetViewerURLBase
    GoBack
    GoFwd
    InsertImage
    LoadURL
    NumPrinterPages
    Print
    Reload
    SelectAll
    ViewerFromTarget
    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframebrowser_properties.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframebrowser_properties.htm deleted file mode 100644 index 24810595e..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframebrowser_properties.htm +++ /dev/null @@ -1,64 +0,0 @@ - - - - -TFrameBrowser Properties - - - - - - - - - -

    TFrameBrowser Properties

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Key Properties
    Run Time Only Properties
     
    ActiveViewer
    BackButtonEnabled
    Base
    BaseTarget
    CaretPos
    CharSet
    DefOverLinkColor
    DefBackground
    DefFontColor
    DefFontName
    DefFontSize
    DefHotSpotColor
    DefPreFontName
    DefVisitedLinkColor
    DocumentTitle
    Dither
    fvOptions
    FwdButtonEnabled
    History
    HistoryIndex
    HistoryMaxCount
    ImageCacheCount
    LinkAttributes
    LinkText
    NoSelect
    Palette
    PrintMarginXXXX
    PrintScale
    Processing
    Quirksmode
    SelLength
    SelStart
    SelText
    Target
    TitleHistory
    URL
    Viewers
    ViewImages
    VisitedMaxCount
    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframeviewer_component.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframeviewer_component.htm deleted file mode 100644 index 34c8eecc5..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframeviewer_component.htm +++ /dev/null @@ -1,37 +0,0 @@ - - - - -TFrameViewer Component - - - - - - - - - -

    TFrameViewer Component

    -Properties -Methods -Events -Tasks -
    - -

    Unit

    - -

    FramView.Pas

    - -

    Description

    - -

    The TFrameViewer component can display one or more HTML documents in a window subdivided into frames. If only single documents are desired, use the THtmlViewer component to save overhead.

    - -

    See Also:

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframeviewer_events.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframeviewer_events.htm deleted file mode 100644 index 44714d090..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframeviewer_events.htm +++ /dev/null @@ -1,60 +0,0 @@ - - - - -TFrameViewer Events - - - - - - - - - -

    TFrameViewer Events

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Key Events
     
    OnBlankWindowRequest
    OnBufferRequest
    OnFileBrowse
    OnFileRequest
    OnFormSubmit
    OnHistoryChange
    OnHotSpotTargetCovered
    OnHotSpotTargetClick
    OnImageClick
    OnImageOver
    OnImageRequest
    OnInclude
    OnLink
    OnMeta
    OnMouseDouble
    OnObjectBlur
    OnObjectChange
    OnObjectClick
    OnObjectFocus
    OnObjectTag
    OnPanelCreate
    OnPanelDestroy
    OnPanelPrint
    OnParseBegin
    OnParseEnd
    OnPrintHTMLHeader
    OnPrintHTMLFooter
    OnPrintFooter
    OnPrintHeader
    OnProcessing
    OnProgress
    OnScript
    OnSoundRequest
    OnStreamRequest
    OnStringsRequest
    OnRightClick
    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframeviewer_methods.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframeviewer_methods.htm deleted file mode 100644 index ed788b93d..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframeviewer_methods.htm +++ /dev/null @@ -1,43 +0,0 @@ - - - - -TFrameViewer Methods - - - - - - - - - -

    TFrameViewer Methods

    -
    - - - - - - - - - - - - - - - - - - - - - - -
    Clear
    ClearHistory
    CopyToClipboard
    Find
    FindEx
    GetSelTextBuf
    GoBack
    GoFwd
    HTMLExpandFilename
    InsertImage
    Load
    LoadFromFile
    LoadImageFile
    LoadTargetFromFile
    NumPrinterPages
    Print
    Reload
    SelectAll
    ViewerFromTarget
    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframeviewerproperties.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframeviewerproperties.htm deleted file mode 100644 index 97c536c3d..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tframeviewerproperties.htm +++ /dev/null @@ -1,66 +0,0 @@ - - - - -TFrameViewerProperties - - - - - - - - - -

    TFrameViewer Properties

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Key Properties
    Run Time Only Properties
     
    ActiveViewer
    BackButtonEnabled
    Base
    BaseTarget
    CaretPos
    CharSet
    CurrentFile
    DefOverLinkColor
    DefBackground
    DefFontColor
    DefFontName
    DefFontSize
    DefHotSpotColor
    DefPreFontName
    DefVisitedLinkColor
    DocumentTitle
    Dither
    fvOptions
    FwdButtonEnabled
    History
    HistoryIndex
    HistoryMaxCount
    ImageCacheCount
    LinkAttributes
    LinkText
    NoSelect
    Palette
    PrintMarginXXXX
    PrintScale
    Processing
    Quirksmode
    SelLength
    SelStart
    SelText
    ServerRoot
    Target
    TitleHistory
    URL
    Viewers
    ViewImages
    VisitedMaxCount
    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tfreelist.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tfreelist.htm deleted file mode 100644 index 83e5d0733..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/tfreelist.htm +++ /dev/null @@ -1,19 +0,0 @@ - - - - -TFreeList - - - - - -

    TFreeList is similar to TList but all contained elements must be descendents of TObject.

    -
    - -

    When Freeing or Clearing a TFreeList, all contained TObjects are also Freed.

    - -

    TFreeList is defined in htmlun2.pas.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/things_you_should_know.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/things_you_should_know.htm deleted file mode 100644 index a03966dd8..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/things_you_should_know.htm +++ /dev/null @@ -1,84 +0,0 @@ - - - - -Things You Should Know - - - - - - - - - - - - - - - - - - - - - -

    Things You Should Know

    -
    - -

    Compile Time Options

    - -

    Several compile time options are controlled by defining symbols. You can find these in the HTMLCONS.INC file. Most of these symbols are initially not defined. To make any one (or all) of these symbols active, remove the "." from the {$.Define XXXX} sequence and recompile the code.

    - -

    GdiPlus.dll Support

    - -

    The GdiPlus.dll provides support for PNG, TIFF, JPEG, ICO, EMF, WMF, EXIF, and BMP images.

    - -

    Defining NoGdiPlus will remove support for TIFF, ICO, EMF, WMF, and EXIF images entirely. If the GdiPlus.dll is not present or NoGdiPlus is defined most images will still be displayed but less nice than with GdiPlus.dll. Complied with NoGdiPlus by Delphi does not support PNG images.

    - -

    The GdiPlus.dll is present on all WinXP systems and has often been loaded on other systems by other applications. If it is not present on your system, it can be downloaded (at no charge) at http://www.microsoft.com/downloads/.

    - -

    Metafile support

    - -

    Metafile display and some printing operations are incompatible with Win95/98/ME. For applications running on these systems define NoMetaFile

    - -

    Ability to Tab between Links

    - -

    To eliminate tabbing between links, define NoTabLink. For documents with hundreds of links, tabbing may not be desirable and also may cause delays in loading. Even when NoTabLink is not defined, there is another constant, MaxTab, which eliminates tabbing to MaxTab links. MaxTab is defined in readhtml.pas

    - -

    FastRadio

    - -

    if you have a form with a great many radio buttons, you may want to define FastRadio to help speed the action. Note that this option changes the way tabbing works. With FastRadio off, tabs move only to the next control that is visible. With FastRadio on, tabs move to the next control even if it is not visible.

    - -

    Quirks

    - -

    Quirks mode makes changes which simulate some of the quirks of other browsers. The HTML components now support a property QuirksMode that replaces and enhances the previous compiler symbol.

    - -

    OpOnChange

    - -

    Without this definition, the <select> form controls (TListbox and TCombobox) will issue the OnObjectChange event only when the control loses the focus which is according to HTML specs. Defining OpOnChange simulates the way IExplorer does it, issuing the OnChange event immediately when a change is made.

    - -

    Mouseover Images

    - -

    A Mouseover Image is one that changes when the mouse passes over it. The HTML components use a special syntax to implement mouseover images. It's done with the <img> tag as follows:

    - -

    the SRC="..." attribute should specify an animated GIF image

    - -

    Add an Active attribute

    - -

    With the Active attribute, the GIF will normally just display the first frame. When the mouse passes over or is clicked, it will display the second or third frame respecively if there are 2 or 3 frames or will animate if there are more than 3 frames.

    - -

    Global Object Id

    - -

    Defining UseGlobalObjectId gives each HTML element an application wide unique ID even if there is no ID or NAME attribute given in the HTML document. The unique ID is composed of 'GOID-' and a consecutive number starting with 1

    - -

    Legacy Style Type Names

    -

    Style types have been renamed to Tht.. to meet the Delphi style guide that types should start with a 'T'. As long as you did not change your code accordingly you can define UseOldStyleTypes.

    - -

    See Also:

    - -

    ReplaceImage Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/thtmlviewer_component.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/thtmlviewer_component.htm deleted file mode 100644 index f3800f3de..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/thtmlviewer_component.htm +++ /dev/null @@ -1,37 +0,0 @@ - - - - -THtmlViewer Component - - - - - - - - - -

    THtmlViewer Component

    -Properties -Methods -Events -Tasks -
    - -

    Unit

    - -

    HTMLView.Pas

    - -

    Description

    - -

    The THtmlViewer component displays single HTML documents. Documents may be loaded from disk files, memory buffers, StringLists, or streams.

    - -

    See Also:

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/thtmlviewer_events.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/thtmlviewer_events.htm deleted file mode 100644 index 99a738b33..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/thtmlviewer_events.htm +++ /dev/null @@ -1,57 +0,0 @@ - - - - -THtmlViewer Events - - - - - - - - - -

    THtmlViewer Events

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Key Events
     
    OnFileBrowse
    OnFormSubmit
    OnHistoryChange
    OnHotSpotCovered
    OnHotSpotClick
    OnhtStreamRequest
    OnImageClick
    OnImageOver
    OnImageRequest
    OnInclude
    OnLink
    OnMeta
    OnMetaRefresh
    OnMouseDouble
    OnObjectBlur
    OnObjectChange
    OnObjectClick
    OnObjectFocus
    OnObjectTag
    OnPanelCreate
    OnPanelDestroy
    OnPanelPrint
    OnParseBegin
    OnParseEnd
    OnPrintHTMLHeader
    OnPrintHTMLFooter
    OnPrintHeader
    OnPrintFooter
    OnProcessing
    OnProgress
    OnScript
    OnSoundRequest
    OnRightClick
    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/thtmlviewer_methods.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/thtmlviewer_methods.htm deleted file mode 100644 index 3e2b47d44..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/thtmlviewer_methods.htm +++ /dev/null @@ -1,61 +0,0 @@ - - - - -THtmlViewer Methods - - - - - - - - - -

    THtmlViewer Methods

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    AbortPrint
    Clear
    ClearHistory
    ClosePrint
    CopyToClipboard
    DisplayPosToXY
    Find
    FindEx
    FindDisplayPos
    FindSourcePos
    FullDisplaySize
    GetCharAtPos
    GetSelTextBuf
    HTMLExpandFilename
    InsertImage
    LoadFromBuffer ( Deprecated )
    LoadFromDocument
    LoadFromFile
    LoadFromStream
    LoadFromString
    LoadImageFile
    LoadStrings
    LoadTextFile
    LoadTextStrings
    MakeBitmap
    MakeMetafile
    MakePagedMetafiles
    NumPrinterPages
    OpenPrint
    PositionTo
    Print
    PtInObject
    Reformat
    Reload
    ReplaceImage
    SelectAll
    XYToDisplayPos
    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/thtmlviewerproperties.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/thtmlviewerproperties.htm deleted file mode 100644 index b9659a88c..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/thtmlviewerproperties.htm +++ /dev/null @@ -1,80 +0,0 @@ - - - - -ThtmlViewerProperties - - - - - - - - - -

    THtmlViewer Properties

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Key Properties
    Run Time Only Properties
     
    Base
    BaseTarget
    BorderStyle
    CaretPos
    CharSet
    CurrentFile
    DefOverLinkColor
    DefBackground
    DefFontColor
    DefFontName
    DefFontSize
    DefHotSpotColor
    DefPreFontName
    DefVisitedLinkColor
    DocumentSource
    DocumentTitle
    Dither
    FormControlList
    FormData
    History
    HistoryIndex
    HistoryMaxCount
    HScrollBar
    HScrollBarPosition
    HScrollBarRange
    htOptions
    IDControl
    IDDisplay
    ImageCacheCount
    LinkAttributes
    LinkText
    MarginHeight
    MarginWidth
    MaxVertical
    NameList
    NoSelect
    Palette
    Position
    PrintMarginXXXX
    PrintScale
    Processing
    Quirksmode
    SelLength
    SelStart
    SelText
    ServerRoot
    Target
    TitleAttr
    TitleHistory
    URL
    ViewImages
    VisitedMaxCount
    VScrollBar
    VScrollBarPosition
    VScrollBarRange
    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/titleattr_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/titleattr_property.htm deleted file mode 100644 index aa734dac3..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/titleattr_property.htm +++ /dev/null @@ -1,35 +0,0 @@ - - - - -TitleAttr Property - - - - - - - - - - - -

    TitleAttr Property

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    property TitleAttr: String;

    - -

    Read only and run time only. The TitleAttr property returns the string defined by a Title="..." attribute in the HTML tag which relates to the current mouse cursor position. The Title attribute may be added to almost all HTML tags. An OnMouseMove handler can examine TitleAttr and uses its value in a hint window to provide hints or other tooltip information relevant to portions of the HTML document.

    - -

    Usage Note:

    - -

    TitleAttr returns the Alt attribute for <img> tags if no Title attribute is present.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/titlehistory_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/titlehistory_property.htm deleted file mode 100644 index 4b57f346a..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/titlehistory_property.htm +++ /dev/null @@ -1,31 +0,0 @@ - - - - -TitleHistory Property - - - - - - - - - -

    TitleHistory Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property TitleHistory: TStrings;

    - -

    Read only and run time only. The TitleHistory property contains a list of the most recently loaded document titles with the current title at index 0.

    - -

    For additional information on setting up a history list, see Setting up a History List.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tbuffcodepage.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tbuffcodepage.htm deleted file mode 100644 index 141d85652..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tbuffcodepage.htm +++ /dev/null @@ -1,28 +0,0 @@ - - - - -Type TBuffCodePage - - - - - - - - - -

    TBuffCodePage Class

    -
    - -

    Unit

    -

    HtmlBuffer.Pas

    - -

    Declaration

    -

    TBuffCodePage = LongInt;

    - -

    Description

    -

    Type TBuffCodePage is used for code page numbers.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tbuffer.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tbuffer.htm deleted file mode 100644 index 2125411d7..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tbuffer.htm +++ /dev/null @@ -1,59 +0,0 @@ - - - - -TBuffer Class - - - - - - - - - -

    TBuffer Class

    -Properties -Methods -
    - -

    Unit

    - -

    HtmlBuffer.Pas

    - -

    Description

    - -

    Class TBuffer converts from byte arrays of almost any character code to unicode.

    - -

    See also

    - - -

    Properties

    - - - - - - -
    Key Properties
     
    CodePage
    Name
    Position
    - -

    Methods

    - - - - - - - - - - - -
    Key Methods
     
    Assign
    AssignTo
    AsString
    Convert
    GetString
    NextChar
    PeekChar
    Size
    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tbufferrequestevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tbufferrequestevent.htm deleted file mode 100644 index 3ed0d3860..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tbufferrequestevent.htm +++ /dev/null @@ -1,47 +0,0 @@ - - - - -Type TBufferRequestEvent - - - - - -

    Type TBufferRequestEvent

    -
    - -

    Declaration

    - -

    TBufferRequestEvent = procedure(Sender: TObject; const SRC: string;

    - -

    var Buffer: PChar; var BuffSize: LongInt) of Object;

    - -

    Description

    - -

    The TBufferRequestEvent type is the type for the OnBufferRequest event. This event allows a handler to respond with an HTML document in buffer form when a request is made for a new document. The parameters are:

    - -

    SRCA string identifying the document requested. This string will usually be taken from a SRC= attribute.

    - -

    BufferThe buffer containing the HTML text supplied by the event handler.

    - -

    BuffSizeThe size of the buffer. A terminating null is not required.

    - -

    The following points are important in writing the event handler:

    - -

    TFrameViewer will not change or free the buffer.

    - -

    In general, you must respond with a valid Buffer. If Nil is returned for the Buffer parameter, TFrameViewer will attempt to load the file identified by SRC. However, this is unreliable unless SRC contains a filename with the full path.

    - -

    Only one of the event handlers in the group, OnBufferRequest, OnFileRequest, OnStreamRequest, and OnStringsRequest, may be active at the same time.

    - -

    See also:

    - -

    OnFileRequest Event

    - -

    OnStreamRequest Event

    - -

    OnStringsRequest Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tfilebrowseevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tfilebrowseevent.htm deleted file mode 100644 index 79f80ac78..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tfilebrowseevent.htm +++ /dev/null @@ -1,27 +0,0 @@ - - - - -Type TFileBrowseEvent - - - - - -

    Type TFileBrowseEvent

    -
    - -

    Declaration

    - -

    TFileBrowseEvent = procedure(Sender, Obj: TObject; var S: string) of Object;

    - -

    Description

    - -

    The TMetaType type points to a method that might process the contents of a <META> HTML tag. Sender is the THtmlViewer which encounters the <META> tag. The other three parameters are the values of <META> tag attributes with the same name.

    - -

    See also:

    - -

    OnFileBrowse Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tfilerequestevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tfilerequestevent.htm deleted file mode 100644 index d362a990e..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tfilerequestevent.htm +++ /dev/null @@ -1,45 +0,0 @@ - - - - -Type TFileRequestEvent - - - - - -

    Type TFileRequestEvent

    -
    - -

    Declaration

    - -

    TFileRequestEvent = procedure(Sender: TObject; const SRC: string;

    - -

    var NewName: string) of Object;

    - -

    Description

    - -

    The TFileRequestEvent type is the type for the OnFileRequest event. This event allows a handler to respond with an HTML document in file form when a request is made for a new document. The parameters are:

    - -

    SRCA string identifying the document requested. This string will usually be taken from a SRC= attribute.

    - -

    NewFileThe name of the file containing the HTML text supplied by the event handler.

    - -

    The following points are important in writing the event handler:

    - -

    If an empty string is returned for the NewFile parameter, TFrameViewer will default to loading the file identified by SRC.

    - -

    In general, you must respond with a valid NewFile. If an empty string is returned for the NewFile parameter, TFrameViewer will attempt to load the file identified by SRC. However, this is unreliable unless SRC contains a filename with the full path.

    - -

    Only one of the event handlers in the group, OnBufferRequest, OnFileRequest, OnStreamRequest, and OnStringsRequest, may be active at the same time.

    - -

    See also:

    - -

    OnBufferRequest Event

    - -

    OnStreamRequest Event

    - -

    OnStringsRequest Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tformsubmitevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tformsubmitevent.htm deleted file mode 100644 index eb73243db..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tformsubmitevent.htm +++ /dev/null @@ -1,58 +0,0 @@ - - - - -Type TFormSubmitEvent - - - - - - - - - - -

    Types TFormSubmitEvent and TbrFormSubmitEvent

    -
    - -

    THtmlViewer and TFrameViewer Declaration

    - -

    TFormSubmitEvent = procedure(Sender: TObject; const Action,

    - -

    Target, EncType, Method: string; Results: TStringList) of Object;

    - -

    TFrameBrowser Declaration

    - -

    TbrFormSubmitEvent = procedure(Sender: TObject; Viewer: THtmlViewer; const Action,

    - -

    Target, EncType, Method: string; Results: TStringList; var Handled: boolean) of Object;

    - -

    Description

    - -

    The TFormSubmitEvent and TbrFormSubmitEvent types are the types for the OnFormSubmit event. This event occurs when the submit button of an HTML Form is depressed. The first four parameters are specified as attributes to the <form> tag in the HTML document.

    - -

    Actionthe URL to which the form content is to be sent,

    - -

    Targetthe destination frame

    - -

    EncTypethe Mime type encoding for the Post Method

    - -

    Methodthe HTTP method (GET or POST) for sending information.

    - -

    Resultsis a TStringList representing the entries of the form's control elements. Entries in the TStringList are in the form:

    - -

    NAME=VALUE

    - -

    In general, NAME is the name attribute found in the control's tag and VALUE is either the value attribute or the field entry the user enters in the form's control.

    - -

    Handled(TFrameBrowser only) Set Handled to True to prevent the default handling of the OnFormSubmit event. If Handled is not set to True, TFrameBrowser will handle the Form submission.

    - -

    Note: The TStringList, Results, should be freed when the user is finished with the data unless Handled is False.

    - -

    See also:

    - -

    OnFormSubmit Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tgetimageevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tgetimageevent.htm deleted file mode 100644 index 2d0a9339e..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tgetimageevent.htm +++ /dev/null @@ -1,42 +0,0 @@ - - - - -Type TGetImageEvent - - - - - - - - - - -

    Type TGetImageEvent

    -
    - -

    Declaration

    - -

    TGetImageEvent = procedure(Sender: TObject;

    - -

    const SRC: string; var Stream: TMemoryStream) of Object;

    - -

    Description

    - -

    The TGetImageEvent type points to a method that handles image request events.

    - -

    SenderThe THtmlViewer requesting the image.

    - -

    SRCThe SRC= string recovered from the <img> tag. For TFrameBrowser, SRC has been expanded into a full URL including the protocol.

    - -

    StreamThe TMemoryStream returned containing the image. The TMemoryStream may contain a bitmap, GIF, JPEG, or PNG image.

    - -

    If a stream can't be supplied because of an error condition, etc., a Nil value should be returned.

    - -

    See also:

    - -

    OnImageRequest Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tgetpostrequestevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tgetpostrequestevent.htm deleted file mode 100644 index c8f8ffc35..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tgetpostrequestevent.htm +++ /dev/null @@ -1,52 +0,0 @@ - - - - -Type TGetPostRequestEvent - - - - - - - - - - -

    Type TGetPostRequestEvent

    -
    - -

    Declaration

    - -

    TGetPostRequestEvent = procedure(Sender: TObject; IsGet: boolean;

    - -

    const URL, Query: string; Reload: boolean;

    - -

    var NewURL: string; var DocType: ThtmlFileType;

    - -

    var Stream: TMemoryStream) of Object;

    - -

    Description

    - -

    The TGetPostRequestEvent type is the type for the OnGetPostRequest event. This event allows a handler to respond with a document or image in stream form when a request is made for a new document. The parameters are:

    - -

    IsGetSet if the request is a Get (as opposed to Post) request.

    - -

    URLThe URL defining the request. This is a full URL and includes the protocol.

    - -

    QueryA possible query string.

    - -

    ReloadSet if a cached copy is not to be used.

    - -

    NewURLThis value is returned if the document had been relocated. This allows further requests to be made to the correct location.

    - -

    DocTypeThe type of item found, HTMLType, TextType, or ImgType.

    - -

    StreamThe requested item in stream form.

    - -

    See also:

    - -

    OnGetPostRequest Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tgetpostrequestexevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tgetpostrequestexevent.htm deleted file mode 100644 index 819e9d8d0..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tgetpostrequestexevent.htm +++ /dev/null @@ -1,51 +0,0 @@ - - - - -Type TGetPostRequestExEvent - - - - - -

    Type TGetPostRequestExEvent

    -
    - -

    Declaration

    - -

    TGetPostRequestExEvent = procedure(Sender: TObject; IsGet: boolean;

    - -

    const URL, Query, EncType, Referer: string; Reload: boolean;

    - -

    var NewURL: string; var DocType: ThtmlFileType;

    - -

    var Stream: TMemoryStream) of Object;

    - -

    Description

    - -

    The TGetPostRequestExEvent type is the type for the OnGetPostRequestEx event. This event allows a handler to respond with a document or image in stream form when a request is made for a new document. The parameters are:

    - -

    IsGetSet if the request is a Get (as opposed to Post) request.

    - -

    URLThe URL defining the request. This is a full URL and includes the protocol.

    - -

    QueryA possible query string.

    - -

    EncTypeThe EncType attribute of the <form> tag from which a Post was made..

    - -

    RefererThe URL from which the request is made.

    - -

    ReloadSet if a cached copy is not to be used.

    - -

    NewURLThis value is returned if the document had been relocated. This allows further requests to be made to the correct location.

    - -

    DocTypeThe type of item found, HTMLType, TextType, or ImgType.

    - -

    StreamThe requested item in stream form.

    - -

    See also:

    - -

    OnGetPostRequest and OnGetPostRequestEx Events

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tgetstreamevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tgetstreamevent.htm deleted file mode 100644 index 364f7a7ba..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tgetstreamevent.htm +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Type TGetStreamEvent - - - - - - - - - -

    Type TGetStreamEvent

    -
    - -

    Declaration

    - -

    TGetStreamEvent = procedure(Sender: TObject; const SRC: string;

    - -

    var Stream: TMemoryStream) of Object;

    - -

    Description

    - -

    The TGetStreamEvent type is the type for the OnhtStreamRequest event. This event allows a handler to respond with an HTML document in stream form when a request is made for a new document. The parameters are:

    - -

    SRCA string identifying the document requested.

    - -

    StreamThe stream returned by the event handler containing the HTML text.

    - -

    See also:

    - -

    OnhtStreamRequest Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thotspotclickevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thotspotclickevent.htm deleted file mode 100644 index 15451af44..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thotspotclickevent.htm +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Type THotSpotClickEvent - - - - - -

    Type THotSpotClickEvent

    -
    - -

    Declaration

    - -

    THotSpotClickEvent = procedure(Sender: TObject;

    - -

    const URL: string; var Handled: Boolean) of Object;

    - -

    Description

    - -

    The THotSpotClickEvent type is the type for hot spot click events. These events occur when the mouse is clicked on a hypertext link. URL is the string referenced by the hot spot.

    - -

    The method which processes the THotSpotClickEvent should returned Handled = True if it wants no further handling of the URL. If Handled is set to false, THtmlViewer will perform default handling.

    - -

    IsMap

    - -

    If the URL comes from an image used as an anchor and the IsMap attribute is used, the X, Y pixel position will be passed appended to the URL in the form "?x,y".

    - -

    See also:

    - -

    OnHotSpotClick Event

    - -

    OnHotSpotCovered Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thotspotevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thotspotevent.htm deleted file mode 100644 index 135bf8dcd..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thotspotevent.htm +++ /dev/null @@ -1,33 +0,0 @@ - - - - -Type THotSpotEvent - - - - - - - - - -

    Type THotSpotEvent

    -
    - -

    Declaration

    - -

    THotSpotEvent = procedure(Sender: TObject;

    - -

    const URL: string) of Object;

    - -

    Description

    - -

    The THotSpotEvent type is the type for the hot spot covered event. This event occurs when the mouse is positioned over a hypertext link. URL is the string referenced by the hot spot.

    - -

    See also:

    - -

    OnHotSpotCovered Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thotspottargetclickevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thotspottargetclickevent.htm deleted file mode 100644 index 48cdf468d..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thotspottargetclickevent.htm +++ /dev/null @@ -1,41 +0,0 @@ - - - - -Type THotSpotTargetClickEvent - - - - - -

    Type THotSpotTargetClickEvent

    -
    - -

    Declaration

    - -

    THotSpotTargetClickEvent = procedure(Sender: TObject;

    - -

    const Target, URL: string; var Handled: Boolean) of Object;

    - -

    Description

    - -

    The THotSpotTargetClickEvent type is the type for hot spot click events with the TFrameViewer and TFrameBrowser components. These events occur when the mouse is clicked on a hypertext link.

    - -

    URLThe string referenced by the hot spot. For TFrameBrowser, URL is expanded into a full URL. The original link text may be obtained with the URL property, if necessary.

    - -

    TargetThe Target attribute (if any) specifying the target window or frame.

    - -

    The method which processes the THotSpotTargetClickEvent should return Handled equal to True if it wants no further handling of the URL. If Handled is set to false, default handling will be performed.

    - -

    IsMap

    - -

    If the URL comes from an image used as an anchor and the IsMap attribute is used, the X, Y pixel position will be passed appended to the URL in the form "?x,y".

    - -

    See also:

    - -

    OnHotSpotTargetClick Event

    - -

    OnHotSpotTargetCovered Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thotspottargetevent_.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thotspottargetevent_.htm deleted file mode 100644 index 7ba343f4f..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thotspottargetevent_.htm +++ /dev/null @@ -1,29 +0,0 @@ - - - - -Type THotSpotTargetEvent; - - - - - -

    Type THotSpotTargetEvent;

    -
    - -

    Declaration

    - -

    THotSpotTargetEvent = procedure(Sender: TObject;

    - -

    const Target, URL: string) of Object;

    - -

    Description

    - -

    The THotSpotTargetEvent type is the type for the TFrameViewer and TFrameBrowser OnHotspotTargetCovered event. This event occurs when the mouse is positioned over a hypertext link. URL is the string referenced by the hot spot and Target is the (optional) associated target window or frame. For TFrameBrowser, URL is expanded into a full URL.

    - -

    See also:

    - -

    OnHotSpotTargetCovered Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtchar.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtchar.htm deleted file mode 100644 index 18c555c50..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtchar.htm +++ /dev/null @@ -1,41 +0,0 @@ - - - - -Types ThtChar, TBuffChar - - - - - - - - - - -

    Types ThtChar, TBuffChar

    -
    - -

    Unit

    - -

    HtmlGlobals.Pas (ThtChar)
    HtmlBuffer.pas (TBuffChar)

    - -

    Declaration

    - -

    Depending on the compiler switch UNICODE ThtChar is set to an available unicode character type.

    -

    If UNICODE is defined it is set to Char otherwize to WideChar.

    - -

    Description

    - -

    Type ThtChar is the character type used in HtmlViewer code.

    -

    Type TBuffChar is an alias for ThtChar and is used in HtmlBuffer.pas.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtmlfiletype.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtmlfiletype.htm deleted file mode 100644 index a2061d46e..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtmlfiletype.htm +++ /dev/null @@ -1,36 +0,0 @@ - - - - -Type ThtmlFileType - - - - - - - - - - -

    Type THtmlFileType

    -
    - -

    Unit

    - -

    HTMLView.Pas

    - -

    Declaration

    - -

    THtmlFileType = (HTMLType, TextType, ImgType, XHtmlType, OtherType);

    - -

    Description

    - -

    Type THtmlFileType indicates a document type.

    - -

    See also:

    - -

    Type TGetPostRequestEvent

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtmlpageprinted.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtmlpageprinted.htm deleted file mode 100644 index d20f54f73..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtmlpageprinted.htm +++ /dev/null @@ -1,69 +0,0 @@ - - - - -Type ThtmlPagePrinted - - - - - - - - - -

    Type ThtmlPagePrinted

    -
    - -

    Declaration

    - -

    ThtmlPagePrinted = procedure(Sender: TObject; HFViewer: THtmlViewer;

    - -

    NumPage: Integer; LastPage: boolean;

    - -

    var XL, XR: integer;

    - -

    var StopPrinting: Boolean) of Object;;

    - -

    Description

    - -

    The ThtmlPagePrinted type is the type for the OnPrintHTMLHeader and OnPrintHTMLFooter events. These events occur as each page is printed allowing the user to add an HTML formatted header and/or footer to the page.

    - -

    SenderThe THtmlViewer which is printing.

    - -

    HFViewerThe THtmlViewer to take the header or footer document.

    - -

    NumPageThe current page number.

    - -

    LastPageA boolean set to True for the last page.

    - -

    XL, XRHeader/footer left and right pixel boundaries.

    - -

    StopPrintingSet this True to abort the print job.

    - -

    Usage Notes:

    - -

    These events print (or preview) HTML documents which serve as headers and footers for the print job. This is done by using two ThtmlViewers, one positioned for the header and the other for the footer. These ThtmlViewers are used only for printing and are never visible. The user supplies an event handler which loads the desired HTML into the THtmlViewer (the HFViewer parameter).

    - -

    The event handler need not be concerned with creating or destroying the THtmlViewer as this is done automatically. The THtmlViewer comes with default settings with the exception of the MarginHeight propertywhich is set at 0. It's only necessary to load the desired HTML using any of the usual load methods. If the header or footer does not change between pages, it need only be loaded once. However, if the HTML does change, it can be reloaded for each page.

    - -

    The header THtmlViewer is positioned so that it's bottom edge is directly above the print job text. This is true regardless of the amount of text. Thus if there is too much text, the early text will disappear off the top of the page. The user needs to insure that the PrintMarginTop property is set adequately. Note that the MarginHeight attribute (<body> tag) can be used to set the spacing at the bottom of the header text.

    - -

    The footer THtmlViewer is positioned so that it's top is directly below the print job text. In this case, excessive text will flow off the bottom of the page. Again, the MarginHeight attribute can be used to control the spacing at the top of the footer.

    - -

    The XL and XR parameters can be used to control the left and right side positioning of the header or footer. These parameters are preset to values such that the header or footer will align with the print job. Hence, in most cases, these parameters can be ignored. If it's desired to extend the header or footer into the normal margin area, then these parameter would be useful. Note that for proper text alignment, the MarginWidth attribute (<body> tag) must be the same for both the print job and the header or footer.

    - -

    See also:

    - -

    MarginHeight Property

    - -

    MarginWidth Property

    - -

    PrintMargin Properties

    - -

    OnPrintHeader

    - -

    OnPrintFooter

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtobjectevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtobjectevent.htm deleted file mode 100644 index 4b6d624b3..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtobjectevent.htm +++ /dev/null @@ -1,54 +0,0 @@ - - - - -Type ThtObjectEvent - - - - - -

    Type ThtObjectEvent

    -
    - -

    Declaration

    - -

    ThtObjectEvent = procedure(Sender, Obj: TObject; const Attribute: string) of Object;

    - -

    Description

    - -

    The ThtObjectEvent type is the type for OnObjectFocus, OnObjectBlur, and OnObjectChange events.

    - -

    In the above, SenderThe THtmlViewer where the Object is located and Obj is a pointer to the clicked object.

    - -

    Attribute is the string assigned to the OnFocus, OnBlur, or OnChange attribute of the object's HTML tag.

    - -

    Form controls currently support these events. Form controls are descendents of TFormControlObj. In particular, the TheControl property can give access to the underlying Delphi controls, such as TEdit, TButton, and TCheckbox with code similar to:

    - -
    if (Obj is TFormControlObj) then
    -    with TFormControlObj(Obj) do
    -        if (TheControl is TButton) then 
    -            .....
    - - - - -

    TFormControlObj's base class THtmlNode also has an AttributeValue Property with which special user attributes can be accessed:

    - -
    if (Obj is THtmlNode) then
    -    AttrValue := THtmlNode(Obj).AttributeValue['MyAttr'];
    - -

    See also:

    - -

    OnObjectFocus Event

    - -

    OnObjectBlur Event

    - -

    OnObjectChange Event

    - -

    OnObjectClick Event

    - -

    OnImageClick Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtprogressevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtprogressevent.htm deleted file mode 100644 index f8f67f5db..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtprogressevent.htm +++ /dev/null @@ -1,35 +0,0 @@ - - - - -Type ThtProgressEvent - - - - - -

    Type ThtProgressEvent

    -
    - -

    Declaration

    - -

    TProgressStage = (psStarting, psRunning, psEnding);

    - -

    ThtProgresstEvent = procedure(Sender: TObject; Stage: TProgressStage;

    - -

    PercentDone: integer) of Object;

    - -

    Description

    - -

    The ThtProgressEvent type is the type for the OnProgress event.

    - -

    SenderThe THtmlViewer doing the parsing and formatting.

    - -

    StageThe stage in the action.

    - -

    PercentDoneAn approximation to the percentage of completion.

    - -

    Note that the TProgressStage type is defined in Graphics.pas.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtquirksmode.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtquirksmode.htm deleted file mode 100644 index 96d1b5cde..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtquirksmode.htm +++ /dev/null @@ -1,45 +0,0 @@ - - - - -Type ThtmlFileType - - - - - - - - - - -

    Type THtQuirksMode

    -
    - -

    Unit

    - -

    HTMLUn2.Pas

    - -

    Declaration

    - -

    THtQuirksMode = (qmDetect, qmStandards, qmQuirks);

    - -

    Description

    - -

    Type THtQuirksMode indicates a quirks mode.

    - -
    -
    qmDetect -
    Tries to detected the need to consider quirks automatically by analysing the document. Documents without any HTML version infos and those before HTML 4.0 are considered to rely on browser quirks. -
    qmStandards -
    Renders documents normally. -
    qmQuirks -
    Renders documents simulating most common quirks of browser versions at the time before HTML 4.0. -
    - -

    See also:

    - -

    Property QuirksMode

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtstring.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtstring.htm deleted file mode 100644 index b240b3091..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtstring.htm +++ /dev/null @@ -1,41 +0,0 @@ - - - - -Types ThtString, TBuffString - - - - - - - - - - -

    Types ThtString, TBuffString

    -
    - -

    Unit

    - -

    HtmlGlobals.Pas (ThtString)
    HtmlBuffer.pas (TBuffString)

    - -

    Declaration

    - -

    Depending on the compiler switch UNICODE ThtString is set to an available unicode string type.

    -

    If UNICODE is defined it is set to string otherwize to WideString.

    - -

    Description

    - -

    Type ThtString is the string type uses in HtmlViewer code.

    -

    Type TBuffString is an alias for ThtString and is used in HtmlBuffer.pas.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtstrings.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtstrings.htm deleted file mode 100644 index 8b5ff1e07..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_thtstrings.htm +++ /dev/null @@ -1,45 +0,0 @@ - - - - -Type ThtStrings - - - - - - - - - - -

    Types ThtStrings, ThtStringList

    -
    - -

    Unit

    - -

    HtmlGlobals.Pas

    - -

    Declaration

    - -

    ThtStrings and ThtStringList are lists of ThtStrings.

    -

    Depending on the compiler switch UNICODE they are set to the lists of the available unicode string type.

    -

    - If UNICODE is defined ThtStrings is set to TStrings otherwize to TWideStrings. -
    - If UNICODE is defined ThtStringList is set to TStringList otherwize to TWideStringList. -

    - -

    Description

    - -

    Type ThtString is the string type uses in HtmlViewer code.

    - -

    See also

    - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_timageclickevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_timageclickevent.htm deleted file mode 100644 index da7cec50c..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_timageclickevent.htm +++ /dev/null @@ -1,33 +0,0 @@ - - - - -Type TImageClickEvent - - - - - -

    Type TImageClickEvent

    -
    - -

    Declaration

    - -

    TImageClickEvent = procedure(Sender, Obj: TObject; Button: TMouseButton;

    - -

    Shift: TShiftState; X, Y: Integer) of Object;

    - -

    Description

    - -

    The TImageClickEvent type is the type for OnImageClick events. These events occur when the mouse is clicked when over an image.

    - -

    In the above, Sender is the THtmlViewer and Obj is the TImageObj where the click occured. X and Y are the position of the cursor within the image.

    - -

    See also:

    - -

    OnImageClick Event

    - -

    OnImageOver Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_timageoverevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_timageoverevent.htm deleted file mode 100644 index 10664c9e5..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_timageoverevent.htm +++ /dev/null @@ -1,33 +0,0 @@ - - - - -Type TImageOverEvent - - - - - -

    Type TImageOverEvent

    -
    - -

    Declaration

    - -

    TImageOverEvent = procedure(Sender, Obj: TObject; Shift: TShiftState;

    - -

    X, Y: Integer) of Object;

    - -

    Description

    - -

    The TImageOverEvent type is the type for OnImageOver events. These events occur when the mouse is moved over an image.

    - -

    In the above, Sender is the THtmlViewer and Obj is the TImageObj where the click occured. X and Y are the position of the cursor within the image.

    - -

    See also:

    - -

    OnImageOver Event

    - -

    OnImageClick Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tincludetype.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tincludetype.htm deleted file mode 100644 index f65cee74d..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tincludetype.htm +++ /dev/null @@ -1,45 +0,0 @@ - - - - -Type TIncludeType - - - - - -

    Type TIncludeType

    -
    - -

    Declaration

    - -

    TIncludeType = procedure (Sender: TObject; const Command: string;

    - -

    Params: TStrings; var IString: string) of Object;

    - -

    Description

    - -

    The TIncludeType type is the type for OnInclude events. These events occur when server side include syntax is encountered in the HTML document at load time.

    - -

    The server side include syntax takes the form:

    - -

    <!--#command arg1="value1" arg2="value2" ... -->

    - -

    The '#' distinguishes this syntax from an ordinary comment. The command word appears as the Command parameter in the event call. The command word may be followed by zero or more arg,value pairs. These are formed into a TStringList object to make up the Params parameter. For use in THtmlViewer, TFrameViewer, TFrameBrowzer, the parameters can be anything that's convenient.

    - -

    The HTML text to be inserted is passed back in IString. This string replaces the entire original include statement.

    - -

    Note that:

    - -

    Quotes are stripped from the Value parts of Params.

    - -

    The event handler should contain a Params.Free; statement. -Since version 11.1 freeing Params is done by THtmlViewer, TFrameViewer, resp. TFrameBrowser and you MUST NOT do it. -

    - -

    See also:

    - -

    OnInclude Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tlinktype.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tlinktype.htm deleted file mode 100644 index e38aa2d9d..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tlinktype.htm +++ /dev/null @@ -1,29 +0,0 @@ - - - - -Type TLinkType - - - - - -

    Type TLinkType

    -
    - -

    Declaration

    - -

    TLinkType = procedure(Sender: TObject; const Rel, Rev, Href: string)

    - -

    of Object;

    - -

    Description

    - -

    The TLinkType type points to a method that might process the contents of a <LINK> HTML tag. Sender is the THtmlViewer, TFrameViewer, or TFrameBrowser which encounters the <LINK> tag. The other three parameters are the values of <LINK> tag attributes with the same name.

    - -

    See also:

    - -

    OnLink Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tmetarefreshtype.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tmetarefreshtype.htm deleted file mode 100644 index 0338e9da5..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tmetarefreshtype.htm +++ /dev/null @@ -1,33 +0,0 @@ - - - - -Type TMetaRefreshType - - - - - -

    Type TMetaRefreshType

    -
    - -

    Declaration

    - -

    TMetaRefreshType = procedure(Sender: TObject; Delay: integer;

    - -

    const URL: string) of Object;

    - -

    Description

    - -

    The TMetaRefreshType type points to a method that might process the contents of a <META .Http_Eq="refresh"> tag. Delay is the time delay in seconds and URL, the html document used to refresh the display. These parameters are parsed from the Contents= attribute.

    - -

    Note that the Http_Eq="refresh" Meta event is handled internally for TFrameViewer.

    - -

    See also:

    - -

    OnMetaRefresh Event

    - -

    OnMeta Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tmetatype.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tmetatype.htm deleted file mode 100644 index 68146b604..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tmetatype.htm +++ /dev/null @@ -1,33 +0,0 @@ - - - - -Type TMetaType - - - - - -

    Type TMetaType

    -
    - -

    Declaration

    - -

    TMetaType = procedure(Sender: TObject; const HttpEq, Name,

    - -

    Content: string) of Object;

    - -

    Description

    - -

    The TMetaType type points to a method that might process the contents of a <META> HTML tag. Sender is the THtmlViewer which encounters the <META> tag. The other three parameters are the values of <META> tag attributes with the same name.

    - -

    Note that the Http_Eq="refresh" Meta event is handled separately in the OnMetaRefresh event for THtmlViewer and internally for TFrameViewer.

    - -

    See also:

    - -

    OnMeta Event

    - -

    OnMetaRefresh Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tobjectclickevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tobjectclickevent.htm deleted file mode 100644 index 36d6091ad..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tobjectclickevent.htm +++ /dev/null @@ -1,46 +0,0 @@ - - - - -Type TObjectClickEvent - - - - - -

    Type TObjectClickEvent

    -
    - -

    Declaration

    - -

    TObjectClickEvent = procedure(Sender, Obj: TObject; const OnClick: string) of Object;

    - -

    Description

    - -

    The TObjectClickEvent type is the type for OnObjectClick events. These events occur when the mouse is clicked on an Object.

    - -

    In the above, Sender is the THtmlViewer where the Object is located and Obj is a pointer to the clicked object. OnClick is the string assigned to the OnClick attribute of the object's HTML tag.

    - -

    Form controls currently support the OnObjectClick event. These objects are descendents of TFormControlObj. In particular, the TheControl property can give access to the underlying Delphi controls, such as TButton, TRadiobutton, and TCheckbox with code similar to:

    - -
    if (Obj is TFormControlObj) then
    -    with TFormControlObj(Obj) do
    -        if (TheControl is TButton) then 
    -            .....
    - - - - -

    TFormControlObj's base class THtmlNode also has an AttributeValue Property with which special user attributes can be accessed:

    - -
    if (Obj is THtmlNode) then
    -    AttrValue := THtmlNode(Obj).AttributeValue['MyAttr'];
    - -

    See also:

    - -

    OnObjectClick Event

    - -

    OnImageClick Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tobjecttagevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tobjecttagevent.htm deleted file mode 100644 index 152b65c62..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tobjecttagevent.htm +++ /dev/null @@ -1,55 +0,0 @@ - - - - -Type TObjectTagEvent - - - - - - - - - -

    Type TObjectTagEvent

    -
    - -

    Declaration

    - -

    TObjectTagEvent = procedure(Sender: TObject; Panel: ThvPanel;

    - -

    const Attributes, Params: TStringList; var WantPanel: boolean) of Object;

    - -

    Description

    - -

    The TObjectTagEvent type is the type for the OnObjectTag event. This event occurs when an <object> tag is encountered at document load time.

    - -

    Senderthe THtmlViewer displaying the ThvPanel.

    - -

    Panelthe ThvPanel (similar to TPanel) created for the display. Its Name property has been assigned to the NAME attribute value and its Height and Width properties have been assigned the values of the HEIGHT and WIDTH attributes.

    - -

    Attributesa TStringList containing all the attributes found in the <object> tag. Individual attributes may be accessed using TStringList's Values property, as:

    - -

    ClassId := Attributes.Values['classid'];

    - -

    Paramsa TStringList containing the Name and Value attributes of all the <param> tags that immediately follow the <object> tag.

    - -

    WantPanela boolean which should be set by the user. Setting WantPanel True indicates the ThvPanel is to be used. If, for some reason, the program can't make use of the ThvPanel, this parameter should be set to False and the panel will be free'd.

    - -

    Usage Notes:

    - -

    The two TStringLists are free'd by THtmlViewer immediately on return from the event. Any data needed after the event should be saved in the event handler.

    - -

    If WantPanel is returned True, then HTML between the <object> and </object> tags is ignored. If WantPanel is False, then HTML following the <object> and <param> tags is displayed and acted on. It is possible to have a second <object> tag here providing a second choice for display.

    - -

    The OnPanelPrint and OnPanelDestroy events will also be initiated by the ThvPanel created for the <object> tag.

    - -

    See also:

    - -

    OnObjecTag Event

    - -

    <PANEL> Tag

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tpageprinted.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tpageprinted.htm deleted file mode 100644 index f1d967451..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tpageprinted.htm +++ /dev/null @@ -1,77 +0,0 @@ - - - - -Type TPagePrinted - - - - - -

    Type TPagePrinted

    -
    - -

    Declaration

    - -

    TPagePrinted = procedure(Sender: TObject; Canvas : TCanvas ;

    - -

    NumPage, W, H: Integer ;

    - -

    var StopPrinting : Boolean) of Object;

    - -

    Description

    - -

    The TPagePrinted type is the type for the OnPrintHeader and OnPrintFooter events. These events occur as each page is printed allowing the user to add a header and/or footer to the page.

    - -

    Canvas is the drawing canvas on which to draw the header or footer having its origin at the upper left corner of the header or footer area with a width, W, and height, H. The actual size of the header/footer areas is determined by the PrintMarginTop and PrintMarginBottom property settings.

    - -

    NumPage is the current page number. StopPrinting may be set to True to stop printing.

    - -

    Example:

    - -

    This code prints the document title and filename in the header area.

    - -

    procedure TForm1.PrintHeader(Sender: TObject; const Canvas: TCanvas;

    - -

    NumPage, W, H: Integer; var StopPrinting: Boolean);

    - -

    var

    - -

    AFont: TFont;

    - -

    begin

    - -

    AFont := TFont.Create;

    - -

    AFont.Name := 'Arial';

    - -

    AFont.Size := 8;

    - -

    with Canvas do

    - -

    begin

    - -

    Font.Assign(AFont);

    - -

    SetTextAlign(Handle, TA_Top or TA_Left);

    - -

    TextOut(50, 40, Viewer.DocumentTitle);

    - -

    SetTextAlign(Handle, TA_Top or TA_Right);

    - -

    TextOut(W-50, 40, Viewer.CurrentFile);

    - -

    end;

    - -

    AFont.Free;

    - -

    end;

    - -

    See also:

    - -

    OnPrintHTMLHeader

    - -

    OnPrintHTMLFooter

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tpanelcreateevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tpanelcreateevent.htm deleted file mode 100644 index a498dde23..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tpanelcreateevent.htm +++ /dev/null @@ -1,41 +0,0 @@ - - - - -Type TPanelCreateEvent - - - - - - - - - -

    Type TPanelCreateEvent

    -
    - -

    Declaration

    - -

    TPanelCreateEvent = procedure(Sender: TObject; const AName, AType, SRC: string;

    - -

    Panel: ThvPanel) of Object;

    - -

    Description

    - -

    The TPanelCreateEvent type is the type for the OnPanelCreate event. This event occurs when a <PANEL> tag is encountered at document load time.

    - -

    Sender is the THtmlViewer displaying the ThvPanel.

    - -

    Panel is the ThvPanel (similar to TPanel) created for the display. Its Name property has been assigned to the NAME attribute value and its Height and Width properties have been assigned the values of the HEIGHT and WIDTH attributes.

    - -

    AType and SRC contains the value assigned to the TYPE and SRC attributes.

    - -

    See also:

    - -

    OnPanelCreate Event

    - -

    <PANEL> Tag

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tpaneldestroyevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tpaneldestroyevent.htm deleted file mode 100644 index db2d1cac3..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tpaneldestroyevent.htm +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Type TPanelDestroyEvent - - - - - - - - - -

    Type TPanelDestroyEvent

    -
    - -

    Declaration

    - -

    TPanelDestroyEvent = procedure(Sender: TObject; Panel: ThvPanel) of Object;

    - -

    Description

    - -

    The TPanelDestroyEvent type is the type for the OnPanelDestroy event.

    - -

    Sender is the THtmlViewer displaying the ThvPanel.

    - -

    Panel is the ThvPanel (similar to TPanel) created for the display.

    - -

    See also:

    - -

    OnPanelDestroy Event

    - -

    <PANEL> Tag

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tpanelprintevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tpanelprintevent.htm deleted file mode 100644 index b3f8e9042..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tpanelprintevent.htm +++ /dev/null @@ -1,57 +0,0 @@ - - - - -Type TPanelPrintEvent - - - - - - - - - -

    Type TPanelPrintEvent

    -
    - -

    Declaration

    - -

    TPanelPrintEvent = procedure(Sender: TObject; Panel: ThvPanel; const Bitmap: TBitmap) of Object;

    - -

    Description

    - -

    The TPanelPrintEvent type is the type for the OnPanelPrint event. This event occurs when a PANEL tag is encountered when the document is printed.

    - -

    Sender is the THtmlViewer displaying the ThvPanel.

    - -

    Panel is the ThvPanel (similar to TPanel) created for the display.

    - -

    Bitmap is the bitmap that will be printed for the panel. The event handler should draw the desired results on the bitmap's canvas.

    - -

    Example:

    - -

    The following event handler is satisfactory for panels constructed with VCL controls:

    - -

    procedure TForm1.ViewerPanelPrint(Sender: TObject; Panel: ThvPanel; const Bitmap: TBitmap);

    - -

    begin

    - -

    Bitmap.Canvas.Lock;

    - -

    Panel.PaintTo(Bitmap.Canvas, 0, 0);

    - -

    Bitmap.Canvas.Unlock;

    - -

    end;

    - -

    See also:

    - -

    OnPanelPrint Event

    - -

    <PANEL> Tag

    - -

    OnObjectTag Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tprocessingevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tprocessingevent.htm deleted file mode 100644 index 1edc46f2e..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tprocessingevent.htm +++ /dev/null @@ -1,31 +0,0 @@ - - - - -Type TProcessingEvent - - - - - -

    Type TProcessingEvent

    -
    - -

    Declaration

    - -

    TProcessingEvent = procedure(Sender: TObject;

    - -

    ProcessingOn: boolean) of Object;

    - -

    Description

    - -

    The TProcessingEvent type is the type for the OnProcessing event. This event occurs whenever the viewer begins or finishes an operation.

    - -

    ProcessingOn is set True at the start of an operation and False when the operation is completed.

    - -

    See also:

    - -

    OnProcessing Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_trightclickevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_trightclickevent.htm deleted file mode 100644 index 33c613bfe..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_trightclickevent.htm +++ /dev/null @@ -1,53 +0,0 @@ - - - - -Type TRightClickEvent - - - - - -

    Type TRightClickEvent

    -
    - -

    Declaration

    - -

    TRightClickEvent = procedure(Sender: TObject;

    - -

    Parameters: TRightClickParameters) of Object;

    - -

    Description

    - -

    The TRightClickEvent type points to a handler for the OnRightClick event. Sender is the THtmlViewer where the click occured. Parameters is a record whose fields contain information for constructing a popup menu. This form of parameter passing is used to allow additional fields to be added in the future.

    - -

    Currently TRightClickParameters is defined as follows:

    - -

    TRightClickParameters = Class(TObject)

    - -

    URL, Target: string;

    - -

    Image: TImageObj;

    - -

    ImageX, ImageY: integer;

    - -

    ClickWord: string;

    - -

    end;

    - -

    URL and Target are information about an anchor. These fields are blank if the mouse is not over an anchor.

    - -

    Image is a pointer to the TImageObject managing an underlying image. ImageX and ImageY give the X and Y position within the image.

    - -

    ClickWord is the word underneath the mouse pointer, if any.

    - -

    See also:

    - -

    OnRightClick Event

    - -

    OnImageClick Event

    - -

    OnObjectClick Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tscriptevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tscriptevent.htm deleted file mode 100644 index 92ea4ce33..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tscriptevent.htm +++ /dev/null @@ -1,27 +0,0 @@ - - - - -Type TScriptEvent - - - - - -

    Type TScriptEvent

    -
    - -

    Declaration

    - -

    TScriptEvent = procedure(Sender: TObject; Const Name, Language, Script: String;

    - -

    Description

    - -

    The TScriptEvent type points to a method that might process the contents of a <script> ... </script> HTML tag sequence. Name and Language are the Name= and Language= attributes recovered from the <script> tag and Script is the entire text between the tags.

    - -

    See also:

    - -

    OnScript Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tsoundtype.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tsoundtype.htm deleted file mode 100644 index e153995a6..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tsoundtype.htm +++ /dev/null @@ -1,27 +0,0 @@ - - - - -Type TSoundType - - - - - -

    TSoundType Type

    -
    - -

    Declaration

    - -

    TSoundType = procedure (Sender: TObject; const SRC: string; Loop: integer;

    - -

    Terminate: boolean) of Object;

    - -

    Description

    - -

    The TSoundType type is the type for OnSoundRequest events. These events occur when the <BGSOUND> tag is encountered at load time and at any other time when it is appropriate to terminate the sound.

    - -

    In the above, Sender is the THtmlViewer or TFrameViewer loading the document, SRC and Loop are the values of these atttributes, and Terminate is a boolean indicating if the sound should be terminated.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tstreamrequestevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tstreamrequestevent.htm deleted file mode 100644 index 20167ed04..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tstreamrequestevent.htm +++ /dev/null @@ -1,43 +0,0 @@ - - - - -Type TStreamRequestEvent - - - - - -

    Type TStreamRequestEvent

    -
    - -

    Declaration

    - -

    TStreamRequestEvent = procedure(Sender: TObject; const SRC: string;

    - -

    var Stream: TStream) of Object;

    - -

    Description

    - -

    The TStreamRequestEvent type is the type for the OnStreamRequest event. This event allows a handler to respond with an HTML document in stream form when a request is made for a new document. The parameters are:

    - -

    SRCA string identifying the document requested. This string will usually be taken from a SRC= attribute.

    - -

    StreamThe stream containing the HTML text supplied by the event handler.

    - -

    The following points are important in writing the event handler:

    - -

    In general, you must respond with a valid Stream parameter. If NIL is returned for the Stream parameter, TFrameViewer will attempt to load the file identified by SRC. However, this is unreliable unless SRC contains a filename with the full path.

    - -

    Only one of the event handlers in the group, OnBufferRequest, OnFileRequest, OnStreamRequest, and OnStringsRequest, may be active at the same time.

    - -

    See also:

    - -

    OnBufferRequest Event

    - -

    OnFileRequest Event

    - -

    OnStringsRequest Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tstringsrequestevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tstringsrequestevent.htm deleted file mode 100644 index f56e85dad..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_tstringsrequestevent.htm +++ /dev/null @@ -1,45 +0,0 @@ - - - - -Type TStringsRequestEvent - - - - - -

    Type TStringsRequestEvent

    -
    - -

    Declaration

    - -

    TStringsRequestEvent = procedure(Sender: TObject; const SRC: string;

    - -

    var Strings: TStrings) of Object;

    - -

    Description

    - -

    The TStringsRequestEvent type is the type for the OnStringsRequest event. This event allows a handler to respond with an HTML document in TStrings form when a request is made for a new document. The parameters are:

    - -

    SRCA string identifying the document requested. This string will usually be taken from a SRC= attribute.

    - -

    StringsThe TStrings object containing the HTML text supplied by the event handler.

    - -

    The following points are important in writing the event handler:

    - -

    TFrameViewer will not change or free the TStrings object.

    - -

    In general, you must respond with a valid Strings parameter. If NIL is returned for the Strings parameter, TFrameViewer will attempt to load the file identified by SRC. However, this is unreliable unless SRC contains a filename with the full path.

    - -

    Only one of the event handlers in the group, OnBufferRequest, OnFileRequest, OnStreamRequest, and OnStringsRequest, may be active at the same time.

    - -

    See also:

    - -

    OnBufferRequest Event

    - -

    OnFileRequest Event

    - -

    OnStreamRequest Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_twindowrequestevent.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_twindowrequestevent.htm deleted file mode 100644 index 8270e60cf..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/type_twindowrequestevent.htm +++ /dev/null @@ -1,31 +0,0 @@ - - - - -Type TWindowRequestEvent - - - - - -

    Type TWindowRequestEvent

    -
    - -

    Declaration

    - -

    TWindowRequestEvent = procedure(Sender: TObject;

    - -

    const Target, URL: string) of Object;

    - -

    Description

    - -

    The TWindowRequestEvent type is the type for window request events. These events occur when a Target Frame of "_blank" is specified or if the Target name does not match any of the current Frame names.

    - -

    Generally, the user would want to open a new window to handle the URL when this event occurs.

    - -

    See also:

    - -

    OnBlankWindowRequest Event

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/url.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/url.htm deleted file mode 100644 index 13ed39628..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/url.htm +++ /dev/null @@ -1,17 +0,0 @@ - - - - -URL - - - - - -

    URL - Uniform Resource Locator

    -
    - -

    A sequence of characters for specifying Internet resources. In HTML documents these specify hypertext link targets, image files, etc. As loosely interpreted for DOS HTML viewers, an URL can be a DOS path and filename.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/url_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/url_property.htm deleted file mode 100644 index 9ecdeaed6..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/url_property.htm +++ /dev/null @@ -1,41 +0,0 @@ - - - - -URL Property - - - - - - - - - -

    URL Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property URL: String;

    - -

    Description

    - -

    Read only and run time only. The URL property returns the most recently selected (left mouse click) URL.

    - -

    The URL property contains the URL exactly as it is read from the document. In some cases, it may be necessary to do some conversion to the string before using it. Depending on your application and the documents you are using, you might want to:

    - -

    Convert from Internet format to Dos format using the HTMLToDos function.

    - -

    Add a path if it doesn't already have one. The Base property provides the base path. If the Base property is empty, the path expected is generally that of the HTML document.

    - -

    See Also

    - -

    Target Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/using_the_tframebrowser_component.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/using_the_tframebrowser_component.htm deleted file mode 100644 index 01d6192a8..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/using_the_tframebrowser_component.htm +++ /dev/null @@ -1,51 +0,0 @@ - - - - -Using the TFrameBrowser Component - - - - - - - - - -

    Using the TFrameBrowser Component

    -
    - -

    TFrameBrowser Reference

    - -

    To use the TFrameBrowser component, you must have event handlers that respond to the OnGetPostRequest and the OnImageRequest events. These events occur whenever a document or an image for a document is requested. These events require that the document or image be returned in stream form. In some cases, the return of the stream may be delayed to allow for downloading the information.

    - -

    The general sequence of loading a document is as follows:

    - -

    Call the LoadURL method. The URL parameter supplied should be a full URL and include the protocol desired.

    - -

    An immediate OnGetPostRequest event will occur. Respond with the stream requested.

    - -

    Assuming the document contains images, a number of OnImageRequest events will occur. Again respond with a stream for each.

    - -

    Once the document is loaded, additional events will occur when links are selected, etc.

    - -

    Tasks

    - -

    To customize response to clicking on a hotspot, respond to the OnHotSpotTargetClick event.

    - -

    To implement a status line which shows what URL a hot spot corresponds to, respond to the OnHotSpotTargetCovered event.

    - -

    To access the properties and methods of the currently active THtmlViewer, use the ActiveViewer Property.

    - -

    -Use the DefFontName, DefFontSize, DefFontColor, DefHotSpotColor, -and DefBackground properties to change the default font and color characteristics for general display. -Use the HTML <body> tag and it's attributes to specify the appearance of a particular HTML document. -

    - -

    To implement a history list and/or Back|Forward buttons, see Setting up a History List.

    - -

    GIF and PNG Images designed to be transparent are displayed as such automatically.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/using_the_tframeviewer_component.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/using_the_tframeviewer_component.htm deleted file mode 100644 index 7cf82f7ce..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/using_the_tframeviewer_component.htm +++ /dev/null @@ -1,47 +0,0 @@ - - - - -Using the TFrameViewer Component - - - - - - - - - -

    Using the TFrameViewer Component

    -
    - -

    TFrameViewer Reference

    - -

    Tasks

    - -

    To load an HTML document or HTML Frame document from a file, use the LoadFromFile method.

    - -

    To customize response to clicking on a hotspot, respond to the OnHotSpotTargetClick event.

    - -

    To implement a status line which shows what URL a hot spot corresponds to, respond to the OnHotSpotTargetCovered event.

    - -

    To access the properties and methods of the currently active THtmlViewer, use the ActiveViewer Property.

    - -

    -Use the DefFontName, DefFontSize, DefFontColor, DefHotSpotColor, -and DefBackground properties to change the default font and color characteristics for general display. -Use the HTML <body> tag and it's attributes to specify the appearance of a particular HTML document. -

    - -

    To implement a history list and/or Back|Forward buttons, see Setting up a History List.

    - -

    GIF and PNG Images designed to be transparent are displayed as such automatically.

    - -

    -To work with documents in buffer, special file, stream, or TStrings form, use an OnBufferRequest, OnFileRequest, OnStreamRequest, -or OnStringsRequest event handler. -Initiate document loading using the Load method. -

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/using_the_thtmlviewer_component.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/using_the_thtmlviewer_component.htm deleted file mode 100644 index cbd1341f5..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/using_the_thtmlviewer_component.htm +++ /dev/null @@ -1,48 +0,0 @@ - - - - -Using The THtmlViewer Component - - - - - - - - - -

    Using The THtmlViewer Component

    -
    - -

    THtmlViewer Reference

    - -

    Tasks

    - -

    -To load an HTML document from a file, use the LoadFromFile method. -To load a document from a stream, use the LoadFromStream method. -To load a document from a unicode string, use the LoadFromString method. -To load a document from an ansistring, use a TBuffer and the LoadFromBuffer method. ( Deprecated ) -To load a document from an ansistring, use a TBuffer and the LoadFromDocument method. -

    - -

    -Use the Position property to save a location in a document and return to it later. -For positioning to a Name field in the document, use the PositionTo method. -

    - -

    To customize response to clicking on a hotspot, respond to the OnHotSpotClick event.

    - -

    To implement a status line which shows what URL a hot spot corresponds to, respond to the OnHotSpotCovered event.

    - -

    -Use the DefFontName, DefFontSize, DefFontColor, DefHotSpotColor, -and DefBackground properties to change the default font and color characteristics for general display. -Use the HTML <body> tag and it's attributes to specify the appearance of a particular HTML document. -

    - -

    To implement a history list and/or Back|Forward buttons, see Setting up a History List.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/viewerfromtarget_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/viewerfromtarget_method.htm deleted file mode 100644 index 83daa31f7..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/viewerfromtarget_method.htm +++ /dev/null @@ -1,42 +0,0 @@ - - - - -ViewerFromTarget Method - - - - - - - - - - -

    ViewerFromTarget Method

    -
    - -

    Applies to

    - -

    TFrameViewer and TFrameBrowser components

    - -

    Declaration

    - -

    function ViewerFromTarget(const Target: String): THtmlViewer;

    - -

    Description

    - -

    The ViewerFromTarget method returns a pointer to the THtmlViewer contained in the named Frame. Target is the name of the Frame containing the viewer.

    - -

    Usage notes:

    - -

    Strictly speaking, a Target name refers to a Frame and a Frame may contain more than one THtmlViewer or may contain other Frames. The ViewerFromTarget method returns Nil if the Target Frame contains other than a single THtmlViewer.

    - -

    See Also:

    - -

    ActiveViewer Property

    - -

    Viewers Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/viewers_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/viewers_property.htm deleted file mode 100644 index bb87ba0d9..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/viewers_property.htm +++ /dev/null @@ -1,43 +0,0 @@ - - - - -Viewers Property - - - - - - - - - -

    Viewers Property

    -
    - -

    Applies to

    - -

    TFrameViewer and TFrameBrowser components

    - -

    Description

    - -

    property Viewers: TStrings;

    - -

    Read only and run time only. The Viewers property lists all the currently displayed THtmlViewers in a Frame HTML document. The THtmlViewers are itemized in the Objects part of the TStrings return.

    - -

    The String associated with the Object contains information to assist in identifying which viewer is which. The String portion contains combinations of the letters, l, t, r, and b which indicates if that particular viewer touches the Left, Top, Right, or Bottom sides of the overall Frame.

    - -

    Some Examples:

    - -

    A combination, "tr" would indicate the viewer is in the top right corner.

    - -

    A combination, "lbr" would indicate the viewer is the one on the bottom.

    - -

    See Also:

    - -

    ActiveViewer Property

    - -

    ViewerFromTarget Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/viewimages_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/viewimages_property.htm deleted file mode 100644 index 33018d7bd..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/viewimages_property.htm +++ /dev/null @@ -1,34 +0,0 @@ - - - - -ViewImages Property - - - - - - - - - - -

    ViewImages Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property ViewImages: Boolean

    - -

    Description

    - -

    The ViewImages property determines whether inline images are drawn or simulated with a standard marker image.

    - -

    If ViewImages is True and an image error occurs, an error image is displayed.

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/visitedmaxcount_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/visitedmaxcount_property.htm deleted file mode 100644 index 2d2bf213f..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/visitedmaxcount_property.htm +++ /dev/null @@ -1,34 +0,0 @@ - - - - -VisitedMaxCount Property - - - - - - - - - - -

    VisitedMaxCount Property

    -
    - -

    Applies to

    - -

    THtmlViewer, TFrameViewer, and TFrameBrowser components

    - -

    Declaration

    - -

    property VisitedMaxCount: Integer;

    - -

    The VisitedMaxCount property determines the number of visited links which will be stored. If VisitedMaxCount is 0, then special coloring of visited links will be disabled. The default value is 50.

    - -

    See also:

    - -

    DefVisitedLinkColor Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/vscrollbar__hscrollbar_properties.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/vscrollbar__hscrollbar_properties.htm deleted file mode 100644 index 59816bcfc..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/vscrollbar__hscrollbar_properties.htm +++ /dev/null @@ -1,44 +0,0 @@ - - - - -VScrollBar, HScrollBar Properties - - - - - - - - - - -

    VScrollbar and HScrollbar Properties

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    property HScrollbar: TScrollbar;

    - -

    property VScrollbar: T32Scrollbar;

    - -

    Description

    - -

    The Scrollbar Properties give access to the THtmlViewer's scrollbars.

    - -

    See Also:

    - -

    HScrollBarRange Property

    - -

    HScrollBarPosition Property

    - -

    VScrollBarRange Property

    - -

    VScrollBarPosition Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/vscrollbarposition_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/vscrollbarposition_property.htm deleted file mode 100644 index d4d91f1a7..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/vscrollbarposition_property.htm +++ /dev/null @@ -1,40 +0,0 @@ - - - - -VScrollBarPosition Property - - - - - - - - - - -

    VScrollBarPosition Property

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    property VScrollBarPosition: Integer;

    - -

    Description

    - -

    The VScrollBarPosition Property gives access to the viewer's vertical scrollbar. This can be used for document positioning in situations where reformatting will not occur.

    - -

    See Also:

    - -

    VScrollBarRange Property

    - -

    Position Property

    - -

    HScrollBarPosition Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/vscrollbarrange_property.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/vscrollbarrange_property.htm deleted file mode 100644 index d4736093b..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/vscrollbarrange_property.htm +++ /dev/null @@ -1,38 +0,0 @@ - - - - -VScrollBarRange Property - - - - - - - - - - -

    VScrollBarRange Property

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    property VScrollBarRange: Integer;

    - -

    The VScrollBarRange Property gives access to the viewer's vertical scrollbar range value.

    - -

    See Also:

    - -

    VScrollBarPosition Property

    - -

    Position Property

    - -

    HScrollBarRange Property

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/waitstream.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/waitstream.htm deleted file mode 100644 index 794e81a21..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/waitstream.htm +++ /dev/null @@ -1,15 +0,0 @@ - - - - -WaitStream - - - - - -

    WaitStream is defined in htmlun2.pas. Include htmlun2 in your Uses clause.

    -
    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/xytodisplaypos_method.htm b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/xytodisplaypos_method.htm deleted file mode 100644 index c19bb0ccc..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/html/xytodisplaypos_method.htm +++ /dev/null @@ -1,43 +0,0 @@ - - - - -XYToDisplayPos Method - - - - - - - - - -

    XYToDisplayPos Method

    -
    - -

    Applies to

    - -

    THtmlViewer component

    - -

    Declaration

    - -

    function XYToDisplayPos(X, Y: integer): integer;

    - -

    Description

    - -

    Given X, Y coordinates on the display, XYToDisplayPos finds the display character position for that location. Dimensions are in pixels relative to the upper left corner of the display. The character position returned is the same as would be returned by the SelStart property if the mouse were clicked at that location.

    - -

    XYToDisplayPos returns -1 for X, Y locations where there is no text.

    - -

    See Also:

    - -

    DisplayPosToXY Method

    - -

    SelStart Property

    - -

    FindSourcePos Method

    - -

    FindDisplayPos Method

    - - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/htmlview.hhc b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/htmlview.hhc deleted file mode 100644 index 8a6f4f326..000000000 --- a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/htmlview.hhc +++ /dev/null @@ -1,895 +0,0 @@ - - - - - - - -
      -
    • - - -
        -
      • - - - -
      • - - - -
          -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        -
      • - - - -
          -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        -
      • - - - -
          -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        -
      • - - - -
      • - - - -
      • - - -
          -
        • - - - -
        • - - - -
        • - - - -
        -
      • - - -
          -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        -
      -
    • - - -
        -
      • - - -
          -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        -
      • - - -
          -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        -
      • - - -
          -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        -
      • - - -
          -
        • - - - -
        • - - - -
        -
      • - - -
          -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        • - - - -
        -
      • - - -
          -
        • - - - -
        -
      -
    • - - - -
    - - diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm0.gif b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm0.gif deleted file mode 100644 index 6c0bdd3ab319be3337d5e7bb94c5ecd35ccd6e20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 970 zcmZ`&O^6j_6g`T`5Wz4g!i$$(3UtU>h#*EoaKX?wI?Om5`$6&wY7yk38fX;PHfb?HKIaa)DZBBT&Zc-?RIeen3+yWD%uJ?DIH=h%)nw;kxB zi>GLZ%O5UZtY2hAknC5zkN)yicYUh^g(y^E3MyO?id4WL1~r(01~-Hu4TUF!64rp> zL=ahA4soc%9CWxN9O*zn0vfOY10IM#29S`1CM>~(CnAvvK&7pt)=1Rbs3x?w6j2p5 zQHr`~h^A=uR=JL;Qq@&MH4DI0tX0jFrfwRhX<8zMt<|WcIyIL>jjVDRf~7Q;4RfEo5z- zVlI-xWBDuAwlpJ+ZVY2uLDqCNR;?W;gG{oL5NGMJDmmR5&U98h5-gEceL;_U49s9< zCdpE6HJtQhBr^$wpyXBB)l?Z)T$M~qQKWfc(hyxDBvLAz%Apx#+GxDlQ%>FjUE)(*XM^Y+rYTSs5n{=xI%sfDrc zH%uNm7(boAdvbH9tDT<@-<#Xi8CmRneqsF7Tl=3~dc0<1@5J`+o{YTs#UCqAPfqXn z=H7kt#3?idT(jh+=rju+4|?h%ZIMcOpmS`o}528_~_Rk uw;k&J@YUN#Ub;85`S)WpgYS-C`tr50Ro}k8dw%@=E!XePzOZ@~M*jmiU6_af diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm1.gif b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm1.gif deleted file mode 100644 index 43ff25fe459f15dc1a53dc5c227691891e69fb39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 972 zcmZ`&L1+|K5PcSey%ZH~@UXRWiV^f+wc3&%hN>}w2cfh`n!{8~DQ)p!$)!+uw53|a zK*&WT!Wb3Q_TYl{kU|+rVp8K>h?k+4UWF=xwQT3--Ve*)9cJE}_uk*5$41^g_-Pki zyg)l#|8V_c{URfRWWVZt^w+Pt>suWtM4<{(P~nPDqyh#psKE?0xFHN_C_EvQum%h# zg2>`>h(jIbpu-*ENCyHE(0~OP@IVAIfP^G8VF@NY5s6FyDs3ILMxx$EHKDboh^nZG zQq)C5G)1eo%5_YYs;(NUSpcSDt!kz;b<;3S(-J9ctwtr)sX7dU$Q;-S&gpAU|@?K$=D7w>%a_{QmbmtP;AygAnU=*ij1)dN3&GC%Rt+LhIN uXV!lE_U~Vhe6#<|$8#sPEEOqvMIk0^*hW`Ud@1eE; diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm2.gif b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm2.gif deleted file mode 100644 index 9743600f12c9a2a27d7370c1f9ff1223295af029..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 991 zcmZ`&JBSrl5Irjf#X^v%Oeut(=;uS!q#e3Qk@#qq?U5=HgB$Ub=PoB*Rn&R zfm$d-Jv2fyv^8>?tQ&-eS!)v&QWf zVUbp5lp<~ diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm3.gif b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm3.gif deleted file mode 100644 index 30e51f2c99e4d2f04180461b5d41a76b1828750c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 824 zcmZ`&J&qPp3^N6=z!gA5h=PKG4kQ|jf}dN2n^;2P94RO$_XeNgB;f{h6cmf!_Cy-J znJ9^4`^|?>@87)se1(VjgAh}Ev^{mHK)Ia z8qUze9Y&7w8QP}IF>S6HjcOUBUTQf@FLw#3ka6lGkLHlpLQ$>iV0THSDY>*I95!d6 zKI;TIAepD=TYa|dmRi$tYda&;ox7+(8@@Pk~r>v0d)LCQMS}UH_ zD$G00t66!qE5L=&i`yxRhp{Wp92cvO7F}oJlwID6Iq~5L)I2bAH&`snVv=YI9<=lwf(@b({y8CW&| diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm4.gif b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm4.gif deleted file mode 100644 index 7af210b097492b968e1cfe8684cb137613a5c47b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 824 zcmZ`&JFXN!4D%BLo`55Oh!6z@1szB<76qSMgqv7G;v6X`DBlqbCkZ#8qo7zkuV_&+l+p`}&y?^ui^EDpe56;o;N4J;qOR_ELlKKUg+begz<$x%HL=z&0FtG$0)nKC= zYD~k8Z3M3b3Vnbvf`tv&pavZDK!X{0umc!n&}c)(7&g|xq842ALW@~=u?v88)?ptK z&Kc!`*|Lf(c2UJCy12#krkvBH$RSN`0GidO+D$d5>E<>gvUFNolsKZr6{Ec7%=b{k z8G5+G*ik;9ZORA8(JT!Cci4!O9>f>7X;hwhJ z+c6`$BQa{uLL*yYJ};x@_}g=~oUz9{ArDU=Go8lNeEIu(=9~WWo?qq#;rthH{RB_1 hAAh`=A7Ad>dGY-F%`bm_c=z2Szk2rb{?!%U{sW*BRp9^t diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm5.gif b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm5.gif deleted file mode 100644 index 4318f635f41e682dac616bc796b89c3ec6128d9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 889 zcmZuwJ!@8B3_ajiYY_)UL5gM*M4SXGE(iRmib(0;B$9U0AK-q(!Qv*aB2h%}FE~XM zI=eYW+?;fBaCl8R8@N38h9oEFoae6Jy0La?YZWW_g9+_D+B?)=n#jyW=NDM)9ews& z2M8lbI3Xg4B#MB;9CWxtj&P)-96iqj3O<7oLJHMb0ShqT0Rr#<@6I7}8%u3DNySWslEL90eL(^-wyQn>EyV{v?(QLGEn~7nW zmSt^D`!E7I2PQ_IR$}}%AJyCkJ3P~~yv1nVO|jX`LZM7G^4tuI(br?PjL3|vXz<4A zk=@;eoy*1FUlH#l{r5hf?;C{q7qIjIXO@nyg@1aobnM)o~gc{?(%wKb}56^zi3>ynJ&Pe0uo6$Bp;9 WuaBKQ^?2vvhs`&4PafQlEB^o`c5X=k diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm6.gif b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm6.gif deleted file mode 100644 index 4849f20518f92bf4cefe4092245d2c3540c12ae7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 835 zcmZ`&JBk!g5G?V-A}(lPWMGGj7;NT(NkxjcX!RN!6f1(6c!OTpLl}0jfq{o;Z(wF% zFji0QgW=6I-Bn#xZ{EIpbMfl^BRs?(?9uU~<0b!+x?9r0^#cya%eTMzfCz#_5+aId zVhAK6!9*sMs6;0wVZ0D1nk4noTvU+0AL%qZpbghZ@$fhcg5eFr0GjQLShVWY;2=J3|Up zs6!LNs@a8d*D$XIz*@a5oGV{KSsP#8%x2)=}o-(<44C!e%y4HukzpHNapZEOI zF9`czz{we&pIidnpYGl{JO6Tief9bD{)@{WkAK}>J$d@!=l5?PZ@8GLK+qVX-D#8~FMDKO~vV%=h2h++E*1K995bg9+^(?GE*qCNgu|`7O4)qtAZp z0AU0PCqx91L=kY9gARAd5sq|}qvx4G!Dlc+NTC`lU;zd^pg;sNPyr+?!GtH2h(snT zfr1rS@PZ0a$U+qW+N?t#5XQ8!z~0h~G`dm7Fs8ALUEApnCq)LCWc2{2`DEQGXE@VY z&L(M^QWqtLm|}^|++zAYs9*#$SizRVa)x?R$w+3hlC6;y8_A0*Mlp+31Z3!O@{va| zq*YL>W;WPvk||7SDiemyEabCJBR5FTQ|oI!Te?fGaHXrfM|O7?c5Wi1luBwREYy6w zQ=tfDs6uUzrJAI7T`IC~f-2RXS*e+OH?B%5@p#%1s~RfG`^Pq@IvXPDTFZgP|*z)oiA2|B#9g<1yR%{ z4y?v5%}7Jj2P<#{H}S!oF_#%_zFdMBm9wc}q{ip{?Y$p-{J!sU?>YCJ^ZVLYt$e=i z4JM|4s2ogvFm)k+0qzc?y7TOJZ(ArVp`2$_%zg%ByRk|?PXluXH$LMibW zBp@xoWFQAcav8Ca7^xAA%*c(xh@99-oYV8B|YMhWYQ3XScr#22oabP4qEJi710Pny2f0%l>vq^ zoDmEvYRW=d)=B0hNj#*#tYu48Kw%13geGK8XJgjNF~ETUG6^=M9?g=$3~mTR#>0*j zsoCc+&&PmpWM&*l<(k6*3wR&`M9!4*GVN^23^T4wrliPRyihKP#_sIF8BXR<3{ojH zR_sY9O5Uu+HPymx>aHG|W~A=5#h@&8zn& z&5q)K-t#m0g7TlhM0HhqtggA^w0-|U?R0+i!kbaM>ydd+?wEY}vlS1`XnAhFW1#)R zS(Ul-r=Lkkz3yM9682WPy}w4?sYhPC~b?Y~|6&a3YxR|Z;o7b}jW7P&Gd^;BbNBmCv^=`8tAAcibl*RS?& z=x>z4wuzCi-(B|8iLuJWFE!h02P+LfPrg35e&*9RhTgiN=MP@%>AZM#;rRKF8d`U^ z++DEw$Gz=eoV>rN_0MlRUK(0+qV-hQx!!4qj`nr7Z5rLO{qHmXwSInc|Cvt~PaLa! zwe`RchnJszt@mu_*xaq_E;Za=yshtrlLJrfoAb@@mp?uJ-Gbq|n@iuj_1Eb7cZQpG O{(AS$?Q7HPXvqT=`_*3n diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm9.gif b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/bm9.gif deleted file mode 100644 index b3c37255e447898a21e6c2d38afd062eb4ead40c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 944 zcmZ`&L5LP)5Pc=df*ve9m?DmQNRmy#1QR_xL6ohfLs)7Nj3gc;kAh0V1Ca>PgY2p| zrzkq6MqWgiQbBK$h(wnO^e6}(JSc4Q?cEQ4zW*O)-kbN{_wSzG_0g6C?_xDxU>q%c zv~a0^Ntr2WzU%XtU%2}2Z+$=*LBa_UK_pQG9Oj_I9dd*t9pz{|6DarqMhGcXa|JBG zfCm(aKn5y+ge92pgc6a+L?uwL0t;SHAqrWj0zez<&<6=)jIzMq(u_2^QN}Q)v5ei@ zL?@rn8(a(llCKlo(=)CAM;lG4DYIBbdPowjGuO)RRg^GLw~T zkF3~CUQ{uPS*#);L&M33J&GY(1+{BtgWF9qg(*#C!ca37^07`cH%a5E{WTw3x=XHb zrK`Lld%7FDHcm(>mDEXCsP%Z4LJ`VPg*qNfwMg&2RAfH}RjMI^%sPG+QNHoR~fh+&zQWgSlEFbr}Ini%%96C-c);hOv44$t%~Z!=nVOKde` zp-`rpdAtmZ;jhQoG9ojwqRE@5A$z(TyO#4WpGEwv*SzPcenA-j1x(Cg&35ui{CR5e zTkCgTi63u$ziiFqz7Kmb5s9b-~9RYqo3UW=ARqKmTcI0_u_AV-8}hn{n80+ F`yV@hjClY6 diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/smallcheck.gif b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/smallcheck.gif deleted file mode 100644 index a3afece7af18d5f960c0cc5135b50ebf0728645c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1012 zcmZ?wbhEHb6lV}*_|Cv^;J|_8N#`fEM2;E@7}%Fu3dZn{Q39q-?y$^`~BLr zmgMCBTetpSy0qBK>;IG~&s$o~0Y$R2j|Bz&_wst~LQUt^dvg<3s^^JT$rHf z(jjBVu^^&wK}WZMCriYQKn0Hu+Zq9lOraDGNz)7oAI6DC4@_1_xTo>s!4p0PbKEb}63NTuT$GwvlA5BBU!;(mpOTrD31lZ#@^ZN( ZmSv_WI3?z!lxODga%rIOHF>!htO3HLrA7b% diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v114.png b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v114.png deleted file mode 100644 index b694c3eda2f11828050a98eea6589ef151b25ab7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5347 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 N{s)(I-uuLsKLC-V2=D*^ diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v116.png b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v116.png deleted file mode 100644 index cb9eafb136cdb2ff9800892e150aaf2aa9d85874..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5347 zcmds5YiwNA5uUqVukF}Qh~uCrP_MW`()Dzv~K5S4gJJW3zp zM*}E*Naa_dYE=TM`XjU;XlYti$f0Uz5;=j2I8h*W?AVU8yY{|!@9w?*zPWd<@7_d) z{^^g7b#~4?&&-)Q=j{5Kn{V3GzijO?5$WHudH5FKYcbYzXYl#Q)61U+avr{A(?;2Q z_|jPrnY*@a8Wx{_zxmsqUx3r|z~*m0EYiD*!;xRUum;SoN49LgvFl{lCkH?Gg&j?`B1l^!eXgmky&vc^;fah~fIeYpP60Xa=+t!4pOf1j+U39e(?@s|13;l<9#>x(2h7EJvR&sc>W=9yg}WQh-+E<6 z9(#U+I`FVkT#vg-`J*o^%B|9r={(`{_1{k7woA#KKe|HtR&_}#(;=4+UDW0m$11X= zj}|J|^itB*w^I5BE*85Av|)d~vlMJgkU8gsaC=EU{^He=P6vBK zhg`@i!LyK*vy~EV)TQ}+_wBr_|NMYB@JU}(J}(Zk!*yttc}NUV%Dtg%`M zjE7Oda-)^aDKI+j9qcIZ1mA2~QSL73xQYc#*8^+2B|BZyIJjiJ>PZi7MzsTNOPf#H zC=Um%QmIN2k9Dn5k{aGKJ!7D?m7?Ha5ETuUc7TZqPFR`v0v33*IP^F-U`}lng|DC7 z`i`vo;(%=Z?q#ZWj?1x;tfVt3`Rom=RmS;J&~ocCbMlBB-M3rv(;vu*f4&jbMV>z5 z`%Rp+8ZHqYT0(47+IHXg`f!6#ZGK=*S#Sj}&UL5hFa)zF8Jd|Wz%iyxiQ~W)=3*Y+ zrdlyC6Yq}5*#5n$^4?!x!jm0B9$z~=ynfntxW)s+FoaknmQ0i>Wwv^I@q)}KhCJrN zmJIBSN-EG-$g`w0rchsx1zNCrpF`0b-fRyL6vhtFkt=rt)`KvKMvuwF^_pijy z0{q~i?^K{-!C4M=?t&79tA$8)V5XH*C-?}Xqqpx(h#G1DZK0oi=C^aB^e0AfQpL6{`2omzqer~lW`N=UEKlG-|A}RiC89x*xMP1E~6N7I&chvWA7#${rpQ`*0 z#;+?KY5wyCz(@$Nw4fpuCR#~|ji8Fj<)k(Pq!UTaBvJi#eRBtdz1-GCOua zvLB3UQj??m+Hz?l%*pnhBmTmfF{zj4rDw&((!2Un>FDf1wD>M!)7322QUkYHO6|3R#E#T1wWY9?*$6kNVJhpkbAhS&a#MWJh{qo#| xxRnL%@1*>HLHp>IRs-Kk@E(ose*7cje&y;7yY`h2>*cWJ#+!!sZv4(u{{iIKQnmm9 diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v117.png b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v117.png deleted file mode 100644 index 04bc15f5be6875ee1e84783bc062696a77c54138..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5347 zcmds5S!|S56h1T4jbc%tRuqlV-~+~lm;gSg50V-z1QlZxqXyI`9}F%SLjo_DxJ7+Y z-om&M&?8Y>PN=B{Z)4M)sin>&p0NyKKoHC3 zCC(Z9IfWS{M1>NbQ9QX&B&1j03cM;ZnelCGO0|5Bsbekm{JtB9;1vUrJhDsGiPY7L zj9|gFUomrnwQdO`MIVvD^mFOeGaZ&AmmUnf1}#w`)+|*xDuQHeMke_b!~u(&<#m?}OaPqUM;o zz}>KXj}&qqIM@wMNqO(!4b+PDqFG4jq)W118fTx6Ez&1FCyzyXc*ltyMrnBXpJk=S zIqPnkoT|oAlhm${dgbdKy%OXr5(E_~A|{iDD_{V5|iu3exql{=ZQTf$zb zgh^>UZ?2p-w@nW>2Ba1H0p;O=k;PGn111*g^l8{Lyf9gt-@jH;sc3F^w$LFfWkh+M zCud@;l)o?Ig#kglCjs*P&OT{wsgrA0T&RiDP%Etf0CD4}^eL%tK40dvE|d|Rcw0X_ z6l!8)(90pI3@R4DIfJ8Mb^H>6jpn z7>_SEeg!%j02mfCWz;2EV$o>oZMy#c>HKb3vgx8+x8~vq6H2j9cHqnGh=dD3tBQG* zd~OoSjYWwSa1s`<$ylut6H_lVnF2HA^CV5R8^lgB*q;efKsW1wiqSGy_HARxJS4di9nz#BC4U!;32LE zWV(mEmN-nD_#~PuzOUn$qy2d~dLS)ppS&vGv++_jJBtIYn!$N)GAEhz5ZWxxiF}k; z8s|LMshw8l*#~4mB*TnGQxgye&R|W?Q`V)*wPFO>OLrfT#n;c1RgWx+aKSt9X}{Ft z?z;M>wkR=x5r$-YFb={ADmYd%Vc(=Lhz0yN6`S$_0{a zOzHKaF;Hf~_=&0)Y&j$reSMr(y|3QfJhhpg|2Yix>zS7`9O~>iL%(5iu@fg?Woz~Q zNnlJq8HT^Ne7W^i&kd|^t?7i7vJ}SC(*5gh>DseX*@wUR5LdP%F2^!9o)V5}0_d)0 z%fLBgUtbZA!&u<fm$G%7@a7B3&8c+#8pw_NZ{{X z4cO^xA1`g8&z7&+6+&mMRKTQ8{~_H6zm&5_4`4f`-0%{o^j_M^cn^{}?4jlxZ>E z_3AHSxmdvOo}?z$fN!t{B$>j^uFhd$G5E&QW|iQaStwZ>hYfzb+`uHBR&gfm7z5w0 zK~9445y_9^0w3;`fv){B^k=6g)zkU4AI|i|=zPs{yTdWeMqy%9W?j%Gvs*8fRQ)VS zDhfiKnX?1mhiAk-nM^bB1?c;_)T`COU6mgnlF^`ut3b(#@70L_G|6QtJNjX2(l1~mEk|1;Xf?!J55*8 zTsiXjtF)X(Gcs$nR=s#AoESVM#mO;U-?j4pVjSX`=a}gZCk%~ R?-s_^ar3S1J6CMj_7^do{y+c# diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v118.png b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v118.png deleted file mode 100644 index f1723196a99d6b896bf4db3193e3103050f277fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5347 zcmds4S!|qF6+ScL-LX@rCPYn8DkW4h3UVV%kPslXa+SrTpsMN;wi1Lyq>2_=0hP)F zMWUoirMC15Duh~B6)$0tk``4(g#<)Olg4Qz$K7H(d+s^k+3vZ^@55iceRo&K4ILuVwRg|p9T<0^Z)$77@1HJp{{}M8d+eUxm*#-@|7@{qNvj$J!7_ja^uQ~`{aD9Hnj@R>Nt?`QjwZhreAF)e z7SWe7uv-%u*bw{3*gsO3K|%ynX%M{t>w!gNn)K-D80DCTjr@o_q>Z=QNM+MAnr48l zl#pCrB+)F=jGn@V8@zG#1T8$82wTZlh{59wtO08I8$3*a ztH(uQQ(6g~I(LvWF}4`W*xHWDV@%IiWi~l3m2ycA4eeOre#L}}IV6Qeks0(W(;_7# zRYP+1nzsx-m27r38juw&id!LwOxD66G>M@=@dT0BNtLQ(7Uv~{(($r+;4A%309i;7 zn1Uwv@iY>-GKH;|<4Pd~?@^NhZA!X|(RrgmDnRasa0FK?z)fT_^4QdeBb^^G^gMt^ zzZwpRdfg%G)rw@(DOtF38C$g|kACBegoS6Bv|zW%L`7uk5@>EcC|7W%w8Ku79Z6T% z!LOp9I6fx_K66t3{QOiXQ;gU9JLF%B%E^a5b&1pN>C2Nv`Ng60^7Vm}a$x5PdGwnj z^4^7H9t9kIpE-5*W((o0TNg}B%od+wNYA_a% z59HYJl>Gjgi&8GuasKKWtStiZtI5LveV`Qv3M|y+=^u^C^h7}p|M9c(#lE=ZT;OcKV1ra6Jxyw znl@_Kr?nt1ZR>iZbHhf^8jdt^coWs)g^|OVD&pp=LqQusy0QI8rdK5Ykr#GKBH@Zo zM|7$xUXSvoCNBq%axybOJJt8}bO$lL!|l+W+~c&O*Jp#vp7 zNMwMhOG27Eu^_#hWnp$&e){5>Kod(t&Wj=oqRi4k(GG0*^3oEcu*Ny=UhZ=?#>{Gj z9?77bJT$GSrya*ZqbBeBS)V-r^D%ky(1>()H_Oep^vazNZgYu6W1<1fEjii_;w=(u zYLi@MQRb#6UBz-JR{`fLj|Z@7wRF0;UVRw88k}j4_=!HqG`^xDUd;yX0<9?Z$OPU7 zwTDSISCzSBQF=DDA)czd_1AgX_2o^n`KEQwr&9?N@>3YZMFRT_y->&_xwN}H%D4$j zs1#S6mqxh%0d_o$KCp0a6HA`2g7FP!qa{nHr0o)*oZa*&8-8pI7g0?PKCwf-_e{Se znqo4H3aTD;Bi-z)9mK$blmVz#t5T^{T*a30A;_-_1!E7|SAeaEy&byBy4;X(#X;*^ z22#%$lOzv=HM3<~QPmo35KI2Wk&JvA+b_VmP2iAxVn?@}$C=~e>YE2p^zBny{DF49 zP>?Jh>ta49#bVJVwt#Og1{elMtal!6H_ju5m3Azm!&^~d9;-Igv9ApE(RqFeIdbEM>G1_w6%Y|?0aB4&Ky1t*?b~y^55SYzK&72lDQ}j)zx+{Bk4+YPdY~GYb2LxkT+;jW(cdIjaWU>Ncffw85}#Cu1uFeERh3 zX`&UQnbO#Z2P44$FvaYmOul_W#!enpBj;ax5zn=6OW2Mz96UCBW;$-1n#yome?L>=QtoxzeCMFQRisp$lM1fQR=ngfTum`NvT-PA(~KO+ zVAO(}uK9Z{_%$(DnR-x@0F^4^;ay6O$;9cu$SjiLe<7DnyQCP*hhn?y*>eF8Be!E5 ziM646EljcrFFO>>xs5bJ+M1p<0JSwlgOVVV|1L~n)FMtNg0Q9aVD$;m@v)e;_GB*)f*ulbhF9=UM*S&KyZ z_OmL}gf{Lwawb@wo0LjEt=FsZ|CeKc-BK$TvA9_|JN(F+ao_a9_xJ2O*tMH6?!E2y L!K1g{_t<{`ePob` diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v119.png b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v119.png deleted file mode 100644 index 9676ea2dd28e6614e946564338bc3bd4a2b0974d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5347 zcmds4Yiu0V6+Sz**X!6xFgPi~M(GcOREa7=NkB;S2gqqitk4RzC_r1F{e^@CC z_|+f1t2_7J^Z4#L_ndoX_Ni}Qzh&i$i&lup%B|Op-GK25^b0d-JpXih)vqw5cHXe% zTG@AeWEzX~568ERiO=7QukC#vl)k&KyJ@FL{{`$R`Q-~2g4lcS*6o{nKk8jKv}w&i z{(@a1LqFO&cFlKo^rdzT?VW+d|7S~m8Mm6g@7EyMK=;wxODH)p8u?r&M~cLC<2uG$ zN{>3+mo^kj!0<#iouB$b+rN-mfKRb)`L;O8B*Y-jWD6~wAPI@^$=t-1>-OFeOWF}AwKc_n|+ikg0D$Gi0 zZUzzc<*sk7kNk-yRGkBtd3?r&Q)dvV3LGL>OiE8Vw2o1-i1Fx|E>XnDBPeJZO-xmm za-18Fqb{N$a-L+}inyG|C#0S@J@8@^9I2SpEz?bv}m?;t;D` z@#Oi3vhsr~-;nPC^JkBKfNRiR#O3}WuGdZ}Ufb!B-u~6%`HtjHegF@G)@_q_5G@w} zvs1WNykL6#7y%S-u)_{m4*YIP4(^?jCN^(2+qx0u!-G}+t8qRIGae_lg%Sb$;*%fA z+iw))Cx6%=)v_y(-#Q^{Mlv#f+r?^vW(e>#a*$_QGIGAtt$n^YCpYbU#^3wwy{RZ- ztPArfeG65dsvkrJhG=vErYDscU;pE$^1uu0bLu9Y_EY#Om+;oU03sRl|a z-xGQ|FxEyrVJPs#LDq5C%a^0<24}EL3~eUo|kKG9?^B~!>ZJ)p6+3?9alq% zfv)eQ#p%hQHWX0JPX!UHqQ3K9E#Q6Sg=L+-ScRhzx{i&c(IOrK8&eV2OpOdEoli?u z!-;c^cH@1Q$etf(<-zeIGBli#6{~wBopCf3DQ|MgId|n%VR|-d3sNc12aYlQ8i~7Z@Apq+rGYO58g1K} zN*F9#qC)$~HWV<|6}Q<69IGG=`E@}67iBbxltl!i`JqVICCc>>ni0`d!sH5_TR;^NyQ~y3B*+ctO;y#IaXT-~|L@_^jcQ5qlUd2Vdj$VL z@-jF)s%SAWk=uWr_0#>UB!joOgKscK%GXB#XeV!)YAYUQ3+V*ZwIO2>(Nqy@;!+5s z@+cD%3Rx|J_W+&g1$+!M0XR}8o<#fr(WBbVt?ieR*O_a$-V@8^& zNEy7zoh}3vm(NLc1) ze-0a!IjNWPQq51vboPkkKb}yhauct1Xm>0^9NGTFA%A`fFUM+8`c|)%{-F`+;@?($ z_h?y38WCUHe7Vs!A)k#Fn5+^K596Vr)yuO|%$<-G$D6P2gMf1VnmP{Op$NK>>iZnPO_vc{uq5+}(EtPmIb*Gs5!XlZ0px_?kk{AIUk zE8QMT5{+r&wr7s})tOV$TA0`THv0c^^pP!IvyQ_p%fxSYozrfwJnC)u&ALI_xOMaO LWBabX?Xmv?O;1N{ diff --git a/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v945.png b/CORE/Source/Plugins/Htmlviewer/HtmlHelp/images/v945.png deleted file mode 100644 index 689598a5c68179b0d9c3f64c8201a15b361d69e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5347 zcmds5Yj9Op75?tMNp4;whK3j+v_4u!M;xY8svy)+21)~^Dz;Pb33dF@aYnRdoXI%- zgIa0rbextS)>@^Gv<}W>>W|t|#j&>3k^+Xd7D5S-cggGC+}xYo$GP|Tt#!^i94?{e zmp@#YbN1eAeQWKt)?Rz>bMw%b?%24Xc5y9$1?{)3-^%vWd|Iok`2N#C!;@?x_ix>} z4xK03E^<(H&*qKm;mY6s!_PiWPR;jk+kQV#ca1y|{OZ@OWX5;5Z`lyOB>Bv8vvSpVU<1Dwkp<@-2O6`AzoHEg-8$w>#J0~b)p=Wy@l<)%W!C4C*p zEA5xvd+d*n06AtzmfkJOcAh5*Ff@%OAvB(+l`CLUKoLe4i+RQh1qZ3bI8u{iOooeH zUtAH)5_H7MB&AZv!wxVu49uh@$uvfu`pTEKWN3!jngPplAg7K56ad&Y3bVs~k(*t` zQmAw5i+#3==S$Pfw&)a)N=_g_hx55C9{9#B>QaSGCT)Vx#R7vGV)?NaB?|$u>)Q{U z&8Cak|Fg5`Iy{aNS9I;|AHiDNYd}dup01CK=JYibm~77k!ySj9N!FavN8v z`{fC&+uo)Q4W7*)n=2rvJU8<|uPqh5@9ICMUK9-WV! zM_pqjmakoiuk89LY8!ZIkpdt5ft|K`6vV0!sjSBI6z3S}_f{;!@|)p3mB}$%j=CQh z@qJRm<*&PbcmtmKNe?=1KZ<7Vty(%$RUP#*?mMD}WCb{W{>grPo=E@?7b!U*SuyF# zJU@MLHR81uD6;O(982QBp3_KAIrz@QpVYl+Ks{|mIUrVzlqe15cZm>L$ zc-<3}%3U!ZYQ3Qz_dR`606q9%4{|&JWIqU5M#b9MewZPki}OZ!j+VKN`-z%0MD*phL9{F-ozSn0kg_eF*0J%$AhEs25?K1F z2ISKYp5J#44l}drt|eZ15%cKXUHJH#h1mSP>v7B1uEpA~U+Z~I^;iEefJ47Lk01a2 zbDBh5Ip1!H+oAV(0w)fQV%65gn(!b7^Fdl+GT0KGmZSb+-x*|*<2)~>y}@k#MKeO7g-)98j%tYlP10* zdfAC8^55?2#>l&Aev_8a*iwx(+m~W3A2}s2BR?SHIox2=Q~dfE9nfNX>4^?o4`A;} z*OialEHCF0cXn8}yf0Bo#Tr>x9VRo3SBwY@WJ<>JZRvqPjM*@l+L}Y(_OHv;%BB+- zc9`O$c-lyv0p?Mw>cG_HO$l5%U0Fr1p%3E*h%(-q2W2d zL2U|kO0aywJhxQjDVV}Ue-8%UIm$AeK+}@z6&}W6=TkjyRc!;R7c?QtZ!o2(5AkP{ zk#^b9tO>|x1~Oy$7=Z{TyiWxikjP{pj)!sV>q>eeo5pJ;DBe*M{io1(>_v>6>7vgu zoPXm5H65&&*v;n)JW=>b#G;P#CXZH#n0tW=O16SB5Oq2t4yh&KU4`a@xr%DQmeP+f zGjdSKN)`A)n;7gt-|<7Z$e`qdz3;delqg-{)7|^tbc_7q7KujrR3OgPt74F`3i;=Y zpIPmBFF!sVg!{rU;})2$n68QdOdweH)p?&S;;=ml%E{02446c2dIIT*A&mAM#rU~y z4QjCaFE*X126OAcUR(CQ;wFcBc#J1e)7XN#MQw;x@@Fg099KRWY{v4|3`iT6h54ai zG%&*&rd)3Ba^7re9Lb^6$czsnpGh*v3H_KD2(6TvF*O@s)~@{4!!iw1=_1FI$H}JY zi^sAiPzVR&LxSJ}P+7-xgdO(8^h0ndH7Cc*m%#~D)k`Hc;q;&Pg*5|>Ihldf?`(SH zgqs=bM`314>$_b3zZkpxGB4({DDXb&{(Z-P^}Dt{(^vVs$23Ll8}3-&xo*dv{{VG9 B8AJd8 diff --git a/CORE/Source/Plugins/Htmlviewer/dwpackage/Delphi/D24/DWhtmlEditor.dpk b/CORE/Source/Plugins/Htmlviewer/dwpackage/Delphi/D24/DWhtmlEditor.dpk deleted file mode 100644 index 8c8880b5f..000000000 --- a/CORE/Source/Plugins/Htmlviewer/dwpackage/Delphi/D24/DWhtmlEditor.dpk +++ /dev/null @@ -1,75 +0,0 @@ -package DWhtmlEditor; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$ENDIF IMPLICITBUILDING} -{$IMPLICITBUILD ON} - -requires - rtl, - dcldb, - VclSmp; - -contains - AlphaBlendUn in '..\..\..\source\AlphaBlendUn.pas', - BegaHtmlPrintPreviewForm in '..\..\..\source\BegaHtmlPrintPreviewForm.pas', - BegaMetaFilePrinter in '..\..\..\source\BegaMetaFilePrinter.pas', - BegaPreview in '..\..\..\source\BegaPreview.pas' {BegaCustomPreviewFrame: TFrame}, - BegaPreviewForm in '..\..\..\source\BegaPreviewForm.pas' {BegaCustomPrintPreviewForm}, - BegaPreviewPanel in '..\..\..\source\BegaPreviewPanel.pas', - BegaScrollBox in '..\..\..\source\BegaScrollBox.pas', - BegaZoom in '..\..\..\source\BegaZoom.pas', - BuffConv in '..\..\..\source\BuffConv.pas', - BuffConvArrays in '..\..\..\source\BuffConvArrays.pas', - DitherUnit in '..\..\..\source\DitherUnit.pas', - FramBrwz in '..\..\..\source\FramBrwz.pas', - FrameViewerReg in '..\..\..\source\FrameViewerReg.pas', - framview in '..\..\..\source\framview.pas', - GDIPL2A in '..\..\..\source\GDIPL2A.pas', - HSLUtils in '..\..\..\source\HSLUtils.pas', - HtmlBuffer in '..\..\..\source\HtmlBuffer.pas', - HtmlCaches in '..\..\..\source\HtmlCaches.pas', - HTMLCompEdit in '..\..\..\source\HTMLCompEdit.pas', - HtmlFonts in '..\..\..\source\HtmlFonts.pas', - htmlgif1 in '..\..\..\source\htmlgif1.pas', - HTMLGif2 in '..\..\..\source\HTMLGif2.pas', - HtmlGlobals in '..\..\..\source\HtmlGlobals.pas', - HtmlImages in '..\..\..\source\HtmlImages.pas', - Htmlsbs1 in '..\..\..\source\Htmlsbs1.pas', - HTMLSubs in '..\..\..\source\HTMLSubs.pas', - HtmlSymb in '..\..\..\source\HtmlSymb.pas', - HTMLUn2 in '..\..\..\source\HTMLUn2.pas', - htmlview in '..\..\..\source\htmlview.pas', - MetaFilePrinter in '..\..\..\source\MetaFilePrinter.pas', - msimg32 in '..\..\..\source\msimg32.pas', - ReadHTML in '..\..\..\source\ReadHTML.pas', - StylePars in '..\..\..\source\StylePars.pas', - StyleTypes in '..\..\..\source\StyleTypes.pas', - StyleUn in '..\..\..\source\StyleUn.pas', - UrlConn in '..\..\..\source\UrlConn.pas', - URLSubs in '..\..\..\source\URLSubs.pas', - vwPrint in '..\..\..\source\vwPrint.pas'; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/dwpackage/Delphi/D24/DWhtmlEditor.dproj b/CORE/Source/Plugins/Htmlviewer/dwpackage/Delphi/D24/DWhtmlEditor.dproj deleted file mode 100644 index 08850a74b..000000000 --- a/CORE/Source/Plugins/Htmlviewer/dwpackage/Delphi/D24/DWhtmlEditor.dproj +++ /dev/null @@ -1,638 +0,0 @@ - - - {972EBBB6-6C1C-49BF-BC1C-94DE860CD8CB} - DWhtmlEditor.dpk - 18.6 - FMX - True - Debug - Win32 - 3 - Package - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_1 - true - true - - - true - Base - true - - - true - true - System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) - DWhtmlEditor - All - .\$(Platform)\$(Config) - .\$(Platform)\$(Config) - false - false - false - false - false - - - None - android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar - - - None - - - None - - - None - - - 1033 - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - 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= - Debug - - - 1033 - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - 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= - Debug - - - DEBUG;$(DCC_Define) - true - false - true - true - true - - - false - - - false - RELEASE;$(DCC_Define) - 0 - 0 - - - - MainSource - - - - - - - - -
    BegaCustomPreviewFrame
    - dfm - TFrame -
    - -
    BegaCustomPrintPreviewForm
    - dfm -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - -
    - - Delphi.Personality.12 - Package - - - - DWhtmlEditor.dpk - - - - - - true - - - - - true - - - - - true - - - - - true - - - - - true - - - - - true - - - - - DWhtmlEditor.bpl - 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\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 - - - 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 - - - - - ..\$(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 - - - - - - - - - - - - - - False - False - False - False - False - True - True - - - 12 - - - - -
    diff --git a/CORE/Source/Plugins/Htmlviewer/dwpackage/Delphi/D24/htmlEditorPG.groupproj b/CORE/Source/Plugins/Htmlviewer/dwpackage/Delphi/D24/htmlEditorPG.groupproj deleted file mode 100644 index 84c3003d2..000000000 --- a/CORE/Source/Plugins/Htmlviewer/dwpackage/Delphi/D24/htmlEditorPG.groupproj +++ /dev/null @@ -1,48 +0,0 @@ - - - {40FCEF6B-18F5-4D83-96E2-6F9B76C70917} - - - - - - - - - - - Default.Personality.12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/CORE/Source/Plugins/Htmlviewer/source/AlphaBlendUn.pas b/CORE/Source/Plugins/Htmlviewer/source/AlphaBlendUn.pas deleted file mode 100644 index 7cbc4df47..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/AlphaBlendUn.pas +++ /dev/null @@ -1,330 +0,0 @@ -{ -Version 11.3 -Copyright 2012 by J. Peter Mugaas - -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. - -Note that the source modules HTMLGIF1.PAS and DITHERUNIT.PAS -are covered by separate copyright notices located in those modules. - -} -unit AlphaBlendUn; -{$I htmlcons.inc} - -interface -{$ifdef MsWindows} - -uses - Windows, vcl.Graphics, Types, SysUtils, - HTMLUn2, HtmlGlobals, msimg32; - -function TransparentTextOutput(ACanvas : TCanvas; - const AX, AY : Integer; - ATxt : PWideChar; const ALen : Integer; - const ATop, AHeight : Integer; - const AOpacity : Byte; const ABreakExtra, ABreakCount : Integer) : Integer; {$ifdef UseInline} inline; {$endif} -procedure TransparentCircle(ACanvas : TCanvas; const AX, AY, ARad: Integer; const AOpacity : Byte); {$ifdef UseInline} inline; {$endif} -procedure TransparentEllipse(ACanvas : TCanvas; const ALeftX, ALeftY, ARightX, ARightY : Integer; const AOpacity : Byte); {$ifdef UseInline} inline; {$endif} -procedure TransparentRectangle(ACanvas : TCanvas; const ALeftX, ALeftY, ARightX, ARightY : Integer; const AOpacity : Byte); {$ifdef UseInline} inline; {$endif} -procedure TransparentDrawFocusRect(ACanvas : TCanvas; ARect : TRect; const AOpacity : Byte); {$ifdef UseInline} inline; {$endif} -procedure TransparentWrapTextW(ACanvas : TCanvas; const AX, AY, AWidth, AHeight : Integer; const AStr : ThtString; const AOpacity : Byte); {$ifdef UseInline} inline; {$endif} -function TransparentExtTextOutW(ACanvas : TCanvas; X, Y: Integer; Options: Longint; - Rect: PRect; Str: PWideChar; Count: Longint; Dx: PInteger; const AOpacity : Byte): BOOL; {$ifdef UseInline} inline; {$endif} -procedure TransparentFillRect(ACanvas : TCanvas; ARect : TRect; const AOpacity : Byte); {$ifdef UseInline} inline; {$endif} - -{Set up a bitmap that we will draw to. This will then be superimposed on the canvas -with the AlphaBlend function.} -function SetupAlphaBlendBmp(ASrcCanvas : TCanvas; const AWidth, AHeight : Integer) : vcl.Graphics.TBitmap; {$ifdef UseInline} inline; {$endif} -procedure AlphaDrawTransparentBitmap(ASource: vcl.Graphics.TBitmap; - ADest: TCanvas; - ASrcLeft, ASrcTop, ASrcWidth, ASrcHeight : Integer; - ADestLeft, ADestTop, ADestWidth, ADestHeight : Integer; - AOpacity: Byte); overload; {$ifdef UseInline} inline; {$endif} -procedure AlphaDrawTransparentBitmap(Source: vcl.Graphics.TBitmap; Destination: TCanvas; DestRect: TRect; Opacity: Byte); overload; {$ifdef UseInline} inline; {$endif} -procedure AlphaDrawTransparentBitmap(Source: vcl.Graphics.TBitmap; SourceRect: TRect; Destination: TCanvas; DestRect: TRect; Opacity: Byte); overload; {$ifdef UseInline} inline; {$endif} - -{$endif MsWindows} -implementation -{$ifdef MsWindows} - -{ -These were barrowed from Vcl.GraphUtil -Copyright(c) 1995-2011 Embarcadero Technologies, Inc. -} -procedure AlphaDrawTransparentBitmap(ASource: vcl.Graphics.TBitmap; - ADest: TCanvas; - ASrcLeft, ASrcTop, ASrcWidth, ASrcHeight : Integer; - ADestLeft, ADestTop, ADestWidth, ADestHeight : Integer; - AOpacity: Byte); -var - BlendFunc: t_BLENDFUNCTION; -begin - BlendFunc.BlendOp := c_AC_SRC_OVER; - BlendFunc.BlendFlags := 0; - BlendFunc.SourceConstantAlpha := AOpacity; - if ASource.PixelFormat = pf32bit then - BlendFunc.AlphaFormat := c_AC_SRC_ALPHA - else - BlendFunc.AlphaFormat := 0; - jpm_AlphaBlend(ADest.Handle, ADestLeft, ADestTop, ADestWidth, ADestHeight, - ASource.Canvas.Handle, ASrcLeft, ASrcTop , ASrcWidth, ASrcHeight, BlendFunc); -end; - -procedure AlphaDrawTransparentBitmap(Source: vcl.Graphics.TBitmap; Destination: TCanvas; DestRect: TRect; Opacity: Byte); -var - BlendFunc: t_BLENDFUNCTION; -begin - BlendFunc.BlendOp := c_AC_SRC_OVER; - BlendFunc.BlendFlags := 0; - BlendFunc.SourceConstantAlpha := Opacity; - if Source.PixelFormat = pf32bit then - BlendFunc.AlphaFormat := c_AC_SRC_ALPHA - else - BlendFunc.AlphaFormat := 0; - jpm_AlphaBlend(Destination.Handle, DestRect.Left, DestRect.Top, DestRect.Right - DestRect.Left, DestRect.Bottom - DestRect.Top, - Source.Canvas.Handle, 0, 0, Source.Width, Source.Height, BlendFunc); -end; - -procedure AlphaDrawTransparentBitmap(Source: vcl.Graphics.TBitmap; SourceRect: TRect; Destination: TCanvas; DestRect: TRect; Opacity: Byte); -var - BlendFunc: t_BLENDFUNCTION; -begin - BlendFunc.BlendOp := c_AC_SRC_OVER; - BlendFunc.BlendFlags := 0; - BlendFunc.SourceConstantAlpha := Opacity; - if Source.PixelFormat = pf32bit then - BlendFunc.AlphaFormat := c_AC_SRC_ALPHA - else - BlendFunc.AlphaFormat := 0; - jpm_AlphaBlend(Destination.Handle, DestRect.Left, DestRect.Top, DestRect.Right - DestRect.Left, DestRect.Bottom - DestRect.Top, - Source.Canvas.Handle, SourceRect.Left, SourceRect.Top, SourceRect.Right - SourceRect.Left, SourceRect.Bottom - SourceRect.Top, BlendFunc); -end; - -function SetupAlphaBlendBmp(ASrcCanvas : TCanvas; const AWidth, AHeight : Integer) : vcl.Graphics.TBitmap; -begin - Result := vcl.Graphics.TBitmap.Create; - Result.Width := AWidth; - Result.height := AHeight; - Result.Canvas.Font.Assign(ASrcCanvas.Font); - Result.Canvas.Brush.Assign(ASrcCanvas.Brush); - Result.Canvas.Pen.Assign(ASrcCanvas.Pen); -end; - -function TransparentExtTextOutW(ACanvas : TCanvas; X, Y: Integer; Options: Longint; - Rect: PRect; Str: PWideChar; Count: Longint; Dx: PInteger; const AOpacity : Byte): BOOL; -var - LB : vcl.Graphics.TBitmap; -begin - if Assigned(jpm_AlphaBlend) then begin - if (AOpacity = $FF) then begin - Result := ExtTextOutW(ACanvas.Handle,X,Y,Options,Rect,Str,Count,Dx); - end else begin - LB := SetupAlphaBlendBmp(ACanvas,Rect^.Right - Rect^.Left,Rect^.Bottom - Rect^.Top); - try - Result := ExtTextOutW(LB.Canvas.Handle,X,Y,Options,Rect,Str,Count,Dx); - AlphaDrawTransparentBitmap(LB, ACanvas,Rect^,AOpacity); - finally - LB.Free; - end; - end; - end else begin - Result := ExtTextOutW(ACanvas.Handle,X,Y,Options,Rect,Str,Count,Dx); - end; -end; - -function TransparentTextOutput(ACanvas : TCanvas; - const AX, AY : Integer; - ATxt : PWideChar; const ALen : Integer; - const ATop, AHeight : Integer; - const AOpacity : Byte; const ABreakExtra, ABreakCount : Integer) : Integer; - -var - LB : vcl.Graphics.TBitmap; - LSize : TSize; - -begin - if Assigned(jpm_AlphaBlend) then begin - if (AOpacity = $FF) then begin - Windows.TextOutW(ACanvas.Handle, AX, AY, ATxt, ALen); - Result := AX + GetTextExtent(ACanvas.Handle, ATxt, ALen).cx; - end else begin - GetTSize(ACanvas.Handle,PWideChar(ATxt), ALen,LSize); - LB := SetupAlphaBlendBmp(ACanvas, LSize.cx, AHeight ); - try - SetTextAlign(LB.Canvas.Handle, TA_BASELINE); - SetTextJustification(LB.Canvas.Handle, ABreakExtra, ABreakCount); - Windows.TextOutW(LB.Canvas.Handle,0, AY - ATop,ATxt,ALen); - AlphaDrawTransparentBitmap(LB, ACanvas, - 0, 0, LSize.cx, AHeight, - AX, ATop, LSize.cx, AHeight, - AOpacity); - Result := AX + LSize.cx; - finally - LB.Free; - end; - end; - end else begin - TextOutW(ACanvas.Handle, AX, AY, PWideChar(ATxt), ALen); - Result := AX + GetTextExtent(ACanvas.Handle, PWideChar(ATxt), ALen).cx; - end; -end; - -procedure TransparentDrawFocusRect(ACanvas : TCanvas; ARect : TRect; const AOpacity : Byte); - -var - LB: vcl.Graphics.TBitmap; - Width, Height: Integer; -begin - if Assigned(jpm_AlphaBlend) then begin - if (AOpacity = $FF) then begin - ACanvas.DrawFocusRect(ARect); - end else begin - Width := ARect.Right - ARect.Left; - Height := ARect.Bottom - ARect.Top; - LB := SetupAlphaBlendBmp(ACanvas,Width,Height); - try - LB.Canvas.DrawFocusRect(Rect(0,0,Width,Height )); - AlphaDrawTransparentBitmap(LB, ACanvas,ARect,AOpacity); - finally - LB.Free; - end; - end; - end else begin - ACanvas.DrawFocusRect(ARect); - end; -end; - -procedure TransparentEllipse(ACanvas : TCanvas; const ALeftX, ALeftY, ARightX, ARightY : Integer; const AOpacity : Byte); -var - LB : vcl.Graphics.TBitmap; -begin - if Assigned(jpm_AlphaBlend) then begin - - if (AOpacity = $FF) then begin - ACanvas.Ellipse(ALeftX, ALeftY, ARightX, ARightY); - end else begin - LB := SetupAlphaBlendBmp(ACanvas,ARightX - ALeftX,ARightY - ALeftY); - try - LB.Canvas.Ellipse(0,0,ARightX - ALeftX,ARightY - ALeftY); - AlphaDrawTransparentBitmap(LB, ACanvas,Rect(ALeftX,ALeftY,ARightX,ARightY),AOpacity); - finally - LB.Free; - end; - end; - end else begin - ACanvas.Ellipse(ALeftX, ALeftY, ARightX, ARightY); - end; -end; - -procedure TransparentCircle(ACanvas : TCanvas; const AX, AY, ARad: Integer; const AOpacity : Byte); -var - LB : vcl.Graphics.TBitmap; -begin - if Assigned(jpm_AlphaBlend) then begin - - if (AOpacity = $FF) then begin - ACanvas.Ellipse(AX, AY - ARad, AX + ARad, AY); - end else begin - LB := SetupAlphaBlendBmp(ACanvas,ARad,AY); - try - LB.Canvas.Ellipse(0,0,ARad,AY); - AlphaDrawTransparentBitmap(LB, ACanvas,Rect(AX,AY - ARad,AX + ARad,AY),AOpacity); - finally - LB.Free; - end; - end; - end else begin - ACanvas.Ellipse(AX, AY - ARad, AX + ARad, AY); - end; -end; - -procedure TransparentRectangle(ACanvas : TCanvas; const ALeftX, ALeftY, ARightX, ARightY : Integer; const AOpacity : Byte); -var - LB : vcl.Graphics.TBitmap; -begin - if Assigned(jpm_AlphaBlend) then begin - - if (AOpacity = $FF) then begin - ACanvas.Rectangle(ALeftX,ALeftY,ARightX,ARightY); - end else begin - LB := SetupAlphaBlendBmp(ACanvas,ARightX - ALeftX,ARightY - ALeftY); - try - LB.Canvas.Rectangle(0,0,ARightX - ALeftX,ARightY - ALeftY); - AlphaDrawTransparentBitmap(LB, ACanvas,Rect(ALeftX,ALeftY,ARightX,ARightY),AOpacity); - - finally - LB.Free; - end; - end; - end else begin - ACanvas.Rectangle(ALeftX,ALeftY,ARightX,ARightY); - end; -end; - -procedure TransparentWrapTextW(ACanvas : TCanvas; const AX, AY, AWidth, AHeight : Integer; const AStr : ThtString; const AOpacity : Byte); -var - LB : vcl.Graphics.TBitmap; -begin - if Assigned(jpm_AlphaBlend) then begin - if (AOpacity = $FF) then begin - WrapTextW(ACanvas, AX, AY, AWidth, AHeight,AStr); - end else begin - LB := SetupAlphaBlendBmp(ACanvas,AWidth,AHeight); - try - WrapTextW(ACanvas,0,0,AWidth,AHeight,AStr); - AlphaDrawTransparentBitmap(LB, ACanvas,Rect(AX,AY,AWidth+AX,AHeight+AY),AOpacity); - finally - LB.Free; - end; - end; - end else begin - WrapTextW(ACanvas, AX, AY, AWidth, AHeight,AStr); - end; -end; - -procedure TransparentFillRect(ACanvas : TCanvas; ARect : TRect; const AOpacity : Byte); -var - LR : TRect; - LB : vcl.Graphics.TBitmap; - Width, Height: Integer; -begin - if Assigned(jpm_AlphaBlend) then begin - if (AOpacity = $FF) then begin - ACanvas.FillRect(ARect); - end else begin - Width := ARect.Right - ARect.Left; - Height := ARect.Bottom - ARect.Top; - LB := SetupAlphaBlendBmp(ACanvas, Width, Height); - try - LR.Left := 0; - LR.Top := 0; - LR.Right := Width; - LR.Bottom := Height; - LB.Canvas.FillRect(LR); - AlphaDrawTransparentBitmap(LB, LR, ACanvas, ARect, AOpacity); - finally - LB.Free; - end; - end - end else begin - ACanvas.FillRect(ARect); - end; -end; - -{$endif MsWindows} -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/BegaHtmlPrintPreviewForm.pas b/CORE/Source/Plugins/Htmlviewer/source/BegaHtmlPrintPreviewForm.pas deleted file mode 100644 index b9efca3bf..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/BegaHtmlPrintPreviewForm.pas +++ /dev/null @@ -1,198 +0,0 @@ -{------------------------------------------------------------------------------- -Copyright (C) 2006-2012 by Bernd Gabriel. - -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. --------------------------------------------------------------------------------} - -unit BegaHtmlPrintPreviewForm; - -{$include htmlcons.inc} - -interface -{$ifndef NoFlatScrollbars} -{$ifndef NoMetaFile} - -uses -{$ifdef LCL} - LclIntf, LclType, PrintersDlgs, -{$else} - Windows, -{$endif} - vcl.Controls, vcl.Forms, Types, vcl.Printers, //Math, - // shared units - HtmlView, - FramView, - // own units - BegaMetaFilePrinter, - BegaPreview, - BegaPreviewForm; - -type - TBegaHtmlPrintPreviewForm = class(TBegaCustomPrintPreviewForm) - private - FFrameViewer: TFVBase; // TFrameViewer or TFrameBrowser - FHtmlViewer: THtmlViewer; - function canPrint: Boolean; - function CurrentViewer: THtmlViewer; - function PreviewGetSize(Sender: TObject; MFPrinter: TBegaMetaFilePrinter; out Width, Height: Integer): Boolean; - procedure PreviewCreatePages(Sender: TObject; MFPrinter: TBegaMetaFilePrinter; var Done: Boolean); - procedure PreviewPrintPages(Sender: TObject; MFPrinter: TBegaMetaFilePrinter; FirstPage, LastPage, Copies: Integer); - procedure setFrameViewer(const Value: TFVBase); - procedure setHtmlViewer(const Value: THtmlViewer); - procedure updateEvents; - public - property FrameViewer: TFVBase read FFrameViewer write setFrameViewer; - property HtmlViewer: THtmlViewer read FHtmlViewer write setHtmlViewer; - end; - -{$endif NoMetaFile} -{$endif NoFlatScrollbars} -implementation -{$ifndef NoFlatScrollbars} -{$ifndef NoMetaFile} - -//- BG ----------------------------------------------------------- 26.03.2007 -- -function TBegaHtmlPrintPreviewForm.canPrint: Boolean; -begin - Result := poPrintEnabled in Preview.PreviewOptions; -end; - -//- BG ----------------------------------------------------------- 26.03.2007 -- -function TBegaHtmlPrintPreviewForm.CurrentViewer: THtmlViewer; -begin - if FHtmlViewer <> nil then - Result := FHtmlViewer - else if FFrameViewer <> nil then - Result := FFrameViewer.ActiveViewer - else - Result := nil; -end; - -//- BG ----------------------------------------------------------- 26.03.2007 -- -procedure TBegaHtmlPrintPreviewForm.PreviewCreatePages(Sender: TObject; MFPrinter: TBegaMetaFilePrinter; var Done: Boolean); -var - OldCursor: TCursor; - Viewer: THtmlViewer; -begin - Viewer := CurrentViewer; - if canPrint and (Viewer <> nil) then - begin - OldCursor := Screen.Cursor; - Screen.Cursor := crHourGlass; - try - MFPrinter.PrintMargins := Rect( - round(Viewer.PrintMarginLeft * 10.0), - round(Viewer.PrintMarginTop * 10.0), - round(Viewer.PrintMarginRight * 10.0), - round(Viewer.PrintMarginBottom * 10.0)); - Viewer.PrintScale := 1.0 / MFPrinter.PrintScale; - Viewer.PrintPreview(MFPrinter); - Done := True; - finally - Screen.Cursor := OldCursor; - end; - end; -end; - -//- BG ----------------------------------------------------------- 14.03.2006 -- -function TBegaHtmlPrintPreviewForm.PreviewGetSize(Sender: TObject; MFPrinter: TBegaMetaFilePrinter; out Width, Height: Integer): Boolean; -var - OldCursor: TCursor; - Viewer: THtmlViewer; -begin - Viewer := CurrentViewer; - Result := canPrint and (Viewer <> nil); - if Result then - begin - OldCursor := Screen.Cursor; - Screen.Cursor := crHourGlass; - try - MFPrinter.PrintMargins := Rect( - round(Viewer.PrintMarginLeft * 10.0), - round(Viewer.PrintMarginTop * 10.0), - round(Viewer.PrintMarginRight * 10.0), - round(Viewer.PrintMarginBottom * 10.0)); - Viewer.PrintScale := 1.0 / MFPrinter.PrintScale; - Viewer.NumPrinterPages(MFPrinter, Width, Height); - finally - Screen.Cursor := OldCursor; - end; - end; -end; - -//- BG ----------------------------------------------------------- 30.03.2007 -- -procedure TBegaHtmlPrintPreviewForm.PreviewPrintPages(Sender: TObject; - MFPrinter: TBegaMetaFilePrinter; FirstPage, LastPage, Copies: Integer); -var - OldCursor: TCursor; - Viewer: THtmlViewer; - CopyNo: Integer; -begin - Viewer := CurrentViewer; - if canPrint and (Viewer <> nil) then - begin - OldCursor := Screen.Cursor; - Screen.Cursor := crHourGlass; - try - for CopyNo := 1 to Copies do - Viewer.Print(FirstPage, LastPage); - finally - Screen.Cursor := OldCursor; - end; - end; -end; - -//- BG ----------------------------------------------------------- 26.03.2007 -- -procedure TBegaHtmlPrintPreviewForm.setFrameViewer(const Value: TFVBase); -begin - FFrameViewer := Value; - FHtmlViewer := nil; - updateEvents; - Preview.createPages; -end; - -//- BG ----------------------------------------------------------- 26.03.2007 -- -procedure TBegaHtmlPrintPreviewForm.setHtmlViewer( - const Value: THtmlViewer); -begin - FFrameViewer := nil; - FHtmlViewer := Value; - updateEvents; - Preview.createPages; -end; - -//- BG ----------------------------------------------------------- 27.03.2007 -- -procedure TBegaHtmlPrintPreviewForm.updateEvents; -begin - if CurrentViewer <> nil then - begin - Preview.OnGetContentSize := PreviewGetSize; - Preview.OnCreatePages := PreviewCreatePages; - Preview.OnPrintPages := PreviewPrintPages; - end - else - begin - Preview.OnGetContentSize := nil; - Preview.OnCreatePages := nil; - Preview.OnPrintPages := nil; - end; -end; - -{$endif NoMetaFile} -{$endif NoFlatScrollbars} -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/BegaMetaFilePrinter.pas b/CORE/Source/Plugins/Htmlviewer/source/BegaMetaFilePrinter.pas deleted file mode 100644 index fcb340689..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/BegaMetaFilePrinter.pas +++ /dev/null @@ -1,620 +0,0 @@ -{------------------------------------------------------------------------------- -Copyright (C) 2006-2012 by Bernd Gabriel. - -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. --------------------------------------------------------------------------------} - -{$include htmlcons.inc} - -unit BegaMetaFilePrinter; - -interface -{$ifndef NoMetaFile} - -uses -{$ifdef MSWindows} - Windows, -{$endif} - Classes, Messages, SysUtils, -{$ifdef LCL} - LclIntf, LclType, LMessages, -{$endif} - vcl.Dialogs, vcl.Controls, vcl.Forms, vcl.Graphics, Math, vcl.Printers, Types, - // - MetaFilePrinter; - -type - TBegaMetaFilePrinter = class; - - TBegaRect = record - Left: Integer; - Top: Integer; - Width: Integer; - Height: Integer; - end; - - TBegaSize = record - Width: Integer; - Height: Integer; - end; - -//------------------------------------------------------------------------------ -// BG, 11.03.2006: IBegaPrintable: interface of objects, printable by TBegaMetaFilePrinter -//------------------------------------------------------------------------------ - - IBegaPrintable = interface - function getHeight: Integer; - function getWidth: Integer; - procedure beforeFirstPage(PageWidth, PageHeight: Integer; out PrintWidth, PrintHeight: Integer); - procedure print(Canvas: TCanvas; var PrintedWidth, PrintedHeight: Integer); - property Height: Integer read getHeight; - property Width: Integer read getWidth; - end; - -//------------------------------------------------------------------------------ -// BG, 11.03.2006: TBegaPrintable: helps printing controls via TBegaMetaFilePrinter -//------------------------------------------------------------------------------ - - TBegaPrintable = class(TInterfacedObject, IBegaPrintable) - protected - function getHeight: Integer; virtual; abstract; - function getWidth: Integer; virtual; abstract; - procedure beforeFirstPage(PageWidth, PageHeight: Integer; out PrintWidth, PrintHeight: Integer); virtual; - procedure print(Canvas: TCanvas; var PrintedWidth, PrintedHeight: Integer); virtual; abstract; - public - property Height: Integer read getHeight; - property Width: Integer read getWidth; - end; - - //BG, 11.03.2006 - TBegaPrintableControl = class(TBegaPrintable, IBegaPrintable) - private - FControl: TControl; - public - constructor create(ControlToPrint: TControl); - function getHeight: Integer; override; - function getWidth: Integer; override; - procedure print(Canvas: TCanvas; var PrintedWidth, PrintedHeight: Integer); override; - end; - - //BG, 05.12.2006 - TBegaPrintableGraphic = class(TBegaPrintable, IBegaPrintable) - private - FGraphic: TGraphic; - public - constructor create(GraphicToPrint: TGraphic); - function getHeight: Integer; override; - function getWidth: Integer; override; - procedure print(Canvas: TCanvas; var PrintedWidth, PrintedHeight: Integer); override; - end; - -//------------------------------------------------------------------------------ -// BG, 11.03.2006: TBegaMetaFilePrinter: advanced print previews with TMetaFilePrinter -//------------------------------------------------------------------------------ - - //BG, 11.03.2006 - TBegaMetaFilePrinter = class(TMetaFilePrinter) - private - FPrintScale: double; // > 1 enlarges print/preview - FPrintMargins: TRect; // in millimeters - FOwnsPages: Boolean; - function getPreviewPrintArea: TBegaRect; - function getPrintArea: TBegaRect; // in pixels - function getPrintMargins: TRect; // FPrintMargins in pixels - procedure doBeforeFirstPage(out PreviewArea: TBegaRect; out WDpi: Integer; out hrgnClip: HRGN); - function getPreviewPaperArea: TBegaRect; - function getPaperArea: TBegaRect; - function printer2preview(Value: TBegaRect): TBegaRect; - function printer2previewX(Value: Integer): Integer; - function printer2previewY(Value: Integer): Integer; - function getPageCount: Integer; - public - constructor Create(AOwner: TComponent); override; - function getPreviewArea(PrintArea: TBegaRect; WDpi: Integer): TBegaRect; - procedure addPage(Page: TMetaFile); - procedure addPages(Source: TBegaMetaFilePrinter; RemovePagesFromSource: Boolean); - procedure clear; - procedure copySettingsFrom(Source: TBegaMetaFilePrinter); - procedure preview(Printable: IBegaPrintable); - procedure print(Printable: IBegaPrintable; FirstPage: Integer = 1; LastPage: Integer = 9999); - procedure printDoc(Printer: TPrinter; FirstPage: Integer = 1; LastPage: Integer = 9999; Copies: Integer = 1); - procedure printTo(Printer: TPrinter; FirstPage: Integer = 1; LastPage: Integer = 9999); - procedure updatePrinterCaps; - property PageCount: Integer read getPageCount; - property PaperArea: TBegaRect read getPaperArea; // in printer pixels - property PrintArea: TBegaRect read getPrintArea; // in printer pixels - property PreviewPaperArea: TBegaRect read getPreviewPaperArea; // in screen pixels - property PreviewPrintArea: TBegaRect read getPreviewPrintArea; // in screen pixels - property PrintMargins: TRect read FPrintMargins write FPrintMargins; // in millimeters - property PrintScale: double read FPrintScale write FPrintScale; - end; - -{$endif NoMetaFile} -implementation -{$ifndef NoMetaFile} - -{ TBegaPrintable } - -procedure TBegaPrintable.beforeFirstPage( - PageWidth, PageHeight: Integer; - out PrintWidth, PrintHeight: Integer); -begin - PrintWidth := Width; - PrintHeight := Height; -end; - -{ TBegaPrintableControl } - -//- BG ----------------------------------------------------------- 11.03.2006 -- -constructor TBegaPrintableControl.create(ControlToPrint: TControl); -begin - inherited create; - FControl := ControlToPrint; -end; - -//- BG ----------------------------------------------------------- 05.12.2006 -- -function TBegaPrintableControl.getHeight: Integer; -begin - Result := FControl.Height; -end; - -//- BG ----------------------------------------------------------- 05.12.2006 -- -function TBegaPrintableControl.getWidth: Integer; -begin - Result := FControl.Width; -end; - -//- BG ----------------------------------------------------------- 11.03.2006 -- -procedure TBegaPrintableControl.print(Canvas: TCanvas; - var PrintedWidth, PrintedHeight: Integer); -begin - IntersectClipRect(Canvas.Handle, 0, 0, FControl.Width, FControl.Height); - FControl.Perform(WM_PAINT, Integer(Canvas.Handle), 0); -end; - -{ TBegaPrintableGraphic } - -type - TBegaGraphic = class(TGraphic) - end; - -//- BG ----------------------------------------------------------- 04.12.2006 -- -constructor TBegaPrintableGraphic.create(GraphicToPrint: TGraphic); -begin - inherited create; - FGraphic := GraphicToPrint; -end; - -//- BG ----------------------------------------------------------- 05.12.2006 -- -function TBegaPrintableGraphic.getHeight: Integer; -begin - Result := FGraphic.Width; -end; - -//- BG ----------------------------------------------------------- 05.12.2006 -- -function TBegaPrintableGraphic.getWidth: Integer; -begin - Result := FGraphic.Height; -end; - -//- BG ----------------------------------------------------------- 04.12.2006 -- -procedure TBegaPrintableGraphic.print(Canvas: TCanvas; var PrintedWidth, - PrintedHeight: Integer); -begin - IntersectClipRect(Canvas.Handle, 0, 0, FGraphic.Width, FGraphic.Height); - TBegaGraphic(FGraphic).Draw(Canvas, Rect(0, 0, FGraphic.Width, FGraphic.Height)); -end; - -{ TBegaMetaFilePrinter } - -//- BG ----------------------------------------------------------- 20.04.2006 -- -procedure TBegaMetaFilePrinter.addPage(Page: TMetaFile); -begin - FMFList.add(Page); -end; - -//- BG ----------------------------------------------------------- 20.04.2006 -- -procedure TBegaMetaFilePrinter.addPages(Source: TBegaMetaFilePrinter; RemovePagesFromSource: Boolean); -var - NewCount: Integer; - Index: Integer; -begin - NewCount := FMFList.Count + Source.FMFList.Count; - if FMFList.Capacity < NewCount then - FMFList.Capacity := NewCount; - for Index := 0 to Source.FMFList.Count - 1 do - FMFList.add(Source.FMFList[Index]); - FOwnsPages := RemovePagesFromSource; - if RemovePagesFromSource then - Source.FMFList.clear; -end; - -//- BG ----------------------------------------------------------- 29.04.2006 -- -procedure TBegaMetaFilePrinter.clear; -begin - if FOwnsPages then - FreeMetaFiles - else - begin - FMFList.clear; - FreeAndNil(FCurCanvas); - end; -end; - -//- BG ----------------------------------------------------------- 29.04.2006 -- -procedure TBegaMetaFilePrinter.copySettingsFrom(Source: TBegaMetaFilePrinter); -begin - FPrintScale := Source.FPrintScale; - FPrintMargins := Source.FPrintMargins; - // - assign(Source); -end; - -//- BG ----------------------------------------------------------- 10.03.2006 -- -constructor TBegaMetaFilePrinter.create(AOwner: TComponent); -begin - inherited create(AOwner); - FPrintScale := 1.0; - FPrintMargins.Left := 20; - FPrintMargins.Right := 20; - FPrintMargins.Top := 20; - FPrintMargins.Bottom := 20; - FOwnsPages := True; - - try - if Printer.Printers.Count > 0 then - GetPrinterCapsOf(Printer); - except - on E: EPrinter do - begin - Printer.Refresh; - if Printer.Printers.Count > 0 then - GetPrinterCapsOf(Printer); - end; - end; -end; - -//- BG ----------------------------------------------------------- 12.03.2006 -- -procedure TBegaMetaFilePrinter.doBeforeFirstPage( - out PreviewArea: TBegaRect; - out WDpi: Integer; - out hrgnClip: HRGN); -var - Area: TBegaRect; -begin - Area := getPrintArea; - PreviewArea := printer2preview(Area); - WDpi := ceil(Screen.PixelsPerInch / PrintScale); - hrgnClip := CreateRectRgn( - Area.Left, - Area.Top, - Area.Left + Area.Width - 1, - Area.Top + Area.Height - 1); -end; - -//- BG ----------------------------------------------------------- 23.03.2007 -- -function TBegaMetaFilePrinter.getPageCount: Integer; -begin - Result := PageNumber; -end; - -//- BG ----------------------------------------------------------- 24.03.2007 -- -function TBegaMetaFilePrinter.getPaperArea: TBegaRect; -begin - Result.Left := 0; - Result.Top := 0; - Result.Width := PaperWidth; - Result.Height := PaperHeight; -end; - -//- BG ----------------------------------------------------------- 12.03.2006 -- -function TBegaMetaFilePrinter.getPreviewArea(PrintArea: TBegaRect; WDpi: Integer): TBegaRect; -begin - Result.Left := MulDiv(PrintArea.Left , WDpi, PixelsPerInchX); - Result.Top := MulDiv(PrintArea.Top , WDpi, PixelsPerInchY); - Result.Width := MulDiv(PrintArea.Width , WDpi, PixelsPerInchX); - Result.Height := MulDiv(PrintArea.Height, WDpi, PixelsPerInchY); -end; - -//- BG ----------------------------------------------------------- 23.03.2007 -- -function TBegaMetaFilePrinter.getPreviewPaperArea: TBegaRect; -begin - // converts PrinterMargins given in mm to preview pixels - Result := printer2preview(PaperArea); -end; - -//- BG ----------------------------------------------------------- 23.03.2007 -- -function TBegaMetaFilePrinter.getPreviewPrintArea: TBegaRect; -begin - Result := printer2preview(PrintArea) -end; - -//- BG ----------------------------------------------------------- 12.03.2006 -- -function TBegaMetaFilePrinter.getPrintArea: TBegaRect; -var - Margins: TRect; -begin - // printer area without margins in printer pixels - Margins := getPrintMargins; - Result.Left := max(Margins.Left, OffsetX); - Result.Top := max(Margins.Top, OffsetY); - Result.Width := min(max(PaperWidth - Result.Left - Margins.Right, 0), PageWidth); - Result.Height := min(max(PaperHeight - Result.Top - Margins.Bottom, 0), PageHeight); -end; - -//- BG ----------------------------------------------------------- 11.03.2006 -- -function TBegaMetaFilePrinter.getPrintMargins: TRect; -begin - // converts PrinterMargins given in mm to printer pixels - Result.Left := Floor(FPrintMargins.Left / 25.4 * PixelsPerInchX); - Result.Top := Floor(FPrintMargins.Top / 25.4 * PixelsPerInchY); - Result.Right := Ceil(FPrintMargins.Right / 25.4 * PixelsPerInchX); - Result.Bottom := Ceil(FPrintMargins.Bottom / 25.4 * PixelsPerInchY); -end; - -//- BG ----------------------------------------------------------- 12.03.2006 -- -procedure TBegaMetaFilePrinter.preview(Printable: IBegaPrintable); -var - DC: HDC; - Done: boolean; - hrgnClip: HRGN; - PreviewArea: TBegaRect; - PrintedHeight: Integer; - PrintedWidth: Integer; - SaveIndex: Integer; - WDpi: integer; - XOrigin: Integer; - XPixels: Integer; - YOrigin: Integer; - YPixels: Integer; -begin - hrgnClip := 0; - BeginDoc; - try - doBeforeFirstPage(PreviewArea, WDpi, hrgnClip); - Printable.beforeFirstPage(PreviewArea.Width, PreviewArea.Height, XPixels, YPixels); - - Done := False; - YOrigin := 0; - while not Done and (YOrigin < YPixels) do - begin - XOrigin := 0; - while not Done and (XOrigin < XPixels) do - begin - // first page is created in BeginDoc - if (XOrigin <> 0) or (YOrigin <> 0) then - NewPage; - - // prepare canvas - DC := Canvas.Handle; - SetMapMode(DC, mm_AnIsotropic); - SetWindowExtEx(DC, WDpi, WDpi, nil); - SetViewportExtEx(DC, PixelsPerInchX, PixelsPerInchY, nil); - SetWindowOrgEx(DC, XOrigin - PreviewArea.Left, YOrigin - PreviewArea.Top, nil); - SelectClipRgn(DC, hrgnClip); - - // print a page - Canvas.Lock; - SaveIndex := SaveDC(DC); - PrintedWidth := PreviewArea.Width; - PrintedHeight:= PreviewArea.Height; - Printable.print(Canvas, PrintedWidth, PrintedHeight); - RestoreDC(DC, SaveIndex); - Canvas.Unlock; - - // notify that a page has been printed - //Application.ProcessMessages; - if Assigned(FOnPageEvent) then - FOnPageEvent(Self, FMFList.Count, Done); - - // proceed to next page - if PrintedWidth > 0 then - inc(XOrigin, min(PrintedWidth, PreviewArea.Width)) - else - XOrigin := XPixels; - end; - // proceed to next page - if PrintedHeight > 0 then - inc(YOrigin, min(PrintedHeight, PreviewArea.Height)) - else - YOrigin := YPixels; - end; - finally - if hRgnClip <> 0 then - DeleteObject(hrgnClip); - EndDoc; - end; -end; - -//- BG ----------------------------------------------------------- 12.03.2006 -- -procedure TBegaMetaFilePrinter.print(Printable: IBegaPrintable; FirstPage, LastPage: Integer); -var - CurrentCanvas: TCanvas; - CurrentPage: Integer; - DC: HDC; - Done: boolean; - hrgnClip: HRGN; - NoPrintCanvas: TCanvas; - PreviewArea: TBegaRect; - PrintedHeight: Integer; - PrintedWidth: Integer; - SaveIndex: Integer; - WDpi: integer; - XOrigin: Integer; - XPixels: Integer; - YOrigin: Integer; - YPixels: Integer; -begin - if FirstPage > 1 then - NoPrintCanvas := TCanvas.Create - else - NoPrintCanvas := nil; - - hrgnClip := 0; - Printer.BeginDoc; - try - getPrinterCapsOf(Printer); - doBeforeFirstPage(PreviewArea, WDpi, hrgnClip); - Printable.beforeFirstPage(PreviewArea.Width, PreviewArea.Height, XPixels, YPixels); - - Done := False; - YOrigin := 0; - CurrentPage := 1; - while not Done and (YOrigin < YPixels) do - begin - XOrigin := 0; - while not Done and (XOrigin < XPixels) do - begin - // first page is created in BeginDoc - if (XOrigin <> 0) or (YOrigin <> 0) then - begin - Printer.NewPage; - inc(CurrentPage); - end; - if CurrentPage < FirstPage then - CurrentCanvas := NoPrintCanvas - else - CurrentCanvas := Printer.Canvas; - - // prepare canvas - DC := CurrentCanvas.Handle; - SetMapMode(DC, mm_AnIsotropic); - SetWindowExtEx(DC, WDpi, WDpi, nil); - SetViewportExtEx(DC, PixelsPerInchX, PixelsPerInchY, nil); - SetWindowOrgEx(DC, XOrigin - PreviewArea.Left, YOrigin - PreviewArea.Top, nil); - SelectClipRgn(DC, hrgnClip); - - // print a page - CurrentCanvas.Lock; - SaveIndex := SaveDC(DC); - PrintedWidth := PreviewArea.Width; - PrintedHeight:= PreviewArea.Height; - Printable.print(CurrentCanvas, PrintedWidth, PrintedHeight); - RestoreDC(DC, SaveIndex); - CurrentCanvas.Unlock; - - // notify that a page has been printed - //Application.ProcessMessages; - if Assigned(FOnPageEvent) then - FOnPageEvent(Self, CurrentPage, Done); - - // proceed to next page - if CurrentPage >= LastPage then - Done := True - else if PrintedWidth > 0 then - inc(XOrigin, min(PrintedWidth, PreviewArea.Width)) - else - XOrigin := XPixels; - end; - // proceed to next page - if PrintedHeight > 0 then - inc(YOrigin, min(PrintedHeight, PreviewArea.Height)) - else - YOrigin := YPixels; - end; - finally - NoPrintCanvas.free; - if hRgnClip <> 0 then - DeleteObject(hrgnClip); - Printer.EndDoc; - end; -end; - -//- BG ----------------------------------------------------------- 27.05.2006 -- -procedure TBegaMetaFilePrinter.printDoc(Printer: TPrinter; FirstPage, LastPage, Copies: Integer); -var - Index: Integer; -begin - Printer.BeginDoc; - try - for Index := 1 to Copies do - printTo(Printer, FirstPage, LastPage); - Printer.EndDoc; - except - Printer.Abort; - raise; - end; -end; - -//- BG ----------------------------------------------------------- 24.03.2007 -- -function TBegaMetaFilePrinter.printer2preview(Value: TBegaRect): TBegaRect; -begin - Result.Left := printer2previewX(Value.Left); - Result.Top := printer2previewY(Value.Top); - Result.Width := printer2previewX(Value.Width); - Result.Height := printer2previewY(Value.Height); -end; - -//- BG ----------------------------------------------------------- 24.03.2007 -- -function TBegaMetaFilePrinter.printer2previewX(Value: Integer): Integer; -begin - Result := Round(Value * Screen.PixelsPerInch / (PrintScale * PixelsPerInchX)); -end; - -//- BG ----------------------------------------------------------- 24.03.2007 -- -function TBegaMetaFilePrinter.printer2previewY(Value: Integer): Integer; -begin - Result := Round(Value * Screen.PixelsPerInch / (PrintScale * PixelsPerInchY)); -end; - -//- BG ----------------------------------------------------------- 10.04.2006 -- -procedure TBegaMetaFilePrinter.printTo(Printer: TPrinter; FirstPage, LastPage: Integer); -var - CurrentPage: Integer; - MetaFile: TMetafile; - Done: Boolean; - Area: TBegaRect; -begin - Area := self.PrintArea; - Area.Left := min(OffsetX, Area.Left); - Area.Top := min(OffsetY, Area.Top); - Done := True; - if LastPage > FMFList.Count then - LastPage := FMFList.Count; - for CurrentPage := FirstPage to LastPage do - begin - MetaFile := MetaFiles[CurrentPage - 1]; - Printer.Canvas.StretchDraw( - Rect( - -Area.Left, - -Area.Top, - Printer.PageWidth - Area.Left, - Printer.PageHeight - Area.Top), - MetaFile); - - // notify that a page has been printed - if Assigned(FOnPageEvent) then - begin - FOnPageEvent(Self, CurrentPage, Done); - if Done then - break; - end; - - if CurrentPage < LastPage then - Printer.NewPage; - end; -end; - -//- BG ----------------------------------------------------------- 15.03.2006 -- -procedure TBegaMetaFilePrinter.updatePrinterCaps; -begin - getPrinterCapsOf(Printer); -end; - -{$endif NoMetaFile} -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/BegaPreview.dfm b/CORE/Source/Plugins/Htmlviewer/source/BegaPreview.dfm deleted file mode 100644 index 86800ec47..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/BegaPreview.dfm +++ /dev/null @@ -1,1166 +0,0 @@ -object BegaCustomPreviewFrame: TBegaCustomPreviewFrame - Left = 0 - Top = 0 - Width = 800 - Height = 600 - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - ParentShowHint = False - ShowHint = True - TabOrder = 0 - object StatBarPanel: TPanel - Left = 0 - Top = 583 - Width = 800 - Height = 17 - Align = alBottom - BevelOuter = bvNone - Font.Charset = DEFAULT_CHARSET - Font.Color = clBlack - Font.Height = -11 - Font.Name = 'Arial' - Font.Style = [] - ParentFont = False - TabOrder = 1 - object CurrentPageLabel: TPanel - Left = 0 - Top = 0 - Width = 121 - Height = 17 - Hint = 'Displays the number of the first visible page' - Align = alLeft - BevelOuter = bvLowered - Caption = 'Current page' - TabOrder = 0 - end - object PreviewZoomLabel: TPanel - Left = 242 - Top = 0 - Width = 121 - Height = 17 - Hint = 'Displays the current preview zoom level (100% = normal)' - Align = alLeft - BevelOuter = bvLowered - Caption = 'Preview zoom' - TabOrder = 1 - end - object Panel1: TPanel - Left = 363 - Top = 0 - Width = 437 - Height = 17 - Hint = 'Displays Help for the object beneath the mouse' - Align = alClient - BevelOuter = bvLowered - TabOrder = 2 - object HintLabel: TLabel - Left = 8 - Top = 5 - Width = 3 - Height = 14 - Hint = 'Displays Help for the object beneath the mouse' - end - end - object ContentZoomLabel: TPanel - Left = 121 - Top = 0 - Width = 121 - Height = 17 - Hint = 'Displays the current content zoom level (100% = normal)' - Align = alLeft - BevelOuter = bvLowered - Caption = 'Content zoom' - TabOrder = 3 - end - end - object ToolBar: TToolBar - Left = 0 - Top = 0 - Width = 800 - Height = 56 - AutoSize = True - BorderWidth = 1 - Caption = 'ToolBar' - EdgeInner = esNone - EdgeOuter = esNone - Images = imgList - ParentShowHint = False - ShowHint = True - TabOrder = 0 - object ReportProperties: TToolButton - Left = 0 - Top = 0 - Caption = 'ReportProperties' - ImageIndex = 8 - OnClick = ReportPropertiesClick - end - object PrinterSetup: TToolButton - Left = 23 - Top = 0 - Hint = 'Setup printer...' - Caption = 'PrinterSetup' - ImageIndex = 0 - ParentShowHint = False - ShowHint = True - OnClick = PrinterSetupClick - end - object Print: TToolButton - Left = 46 - Top = 0 - Hint = 'Print shown document...' - Caption = 'Print' - ImageIndex = 1 - ParentShowHint = False - ShowHint = True - OnClick = PrintClick - end - object SendMail: TToolButton - Left = 69 - Top = 0 - Hint = 'Send e-mail with shown document...' - Caption = 'SendMail' - ImageIndex = 10 - Visible = False - OnClick = SendMailClick - end - object SaveFile: TToolButton - Left = 92 - Top = 0 - Hint = 'Save shown document as HTML file...' - Caption = 'SaveFile' - ImageIndex = 2 - ParentShowHint = False - ShowHint = True - Visible = False - OnClick = SaveFileClick - end - object OpenInExcel: TToolButton - Left = 115 - Top = 0 - Hint = 'Open shown document in '#39'MS Excel'#39 - Caption = 'OpenInExcel' - ImageIndex = 18 - OnClick = OpenInExcelClick - end - object ContentZoomSeparator: TToolButton - Left = 138 - Top = 0 - Width = 8 - Caption = 'ContentZoomSeparator' - ImageIndex = 4 - Style = tbsSeparator - end - object ContentZoomBoxLabel: TLabel - Left = 146 - Top = 0 - Width = 39 - Height = 22 - Alignment = taCenter - AutoSize = False - Caption = 'Content'#13#10'zoom' - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -9 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - Layout = tlCenter - end - object ContentZoomBox: TComboBox - Left = 185 - Top = 0 - Width = 81 - Height = 21 - Hint = 'Content zoom' - Style = csDropDownList - TabOrder = 4 - OnChange = ContentZoomBoxChange - Items.Strings = ( - 'Fit to page' - 'Fit to height' - 'Fit to width' - '25%' - '50%' - '75%' - '100%' - '125%' - '150%' - '200%' - '300%' - '400%' - '800%') - end - object ContentFitHeight: TToolButton - Left = 266 - Top = 0 - Hint = 'Fit content to page height' - AllowAllUp = True - Caption = 'ContentFitHeight' - Grouped = True - ImageIndex = 11 - Style = tbsCheck - OnClick = ContentFitHeightClick - end - object ContentFitWidth: TToolButton - Left = 289 - Top = 0 - Hint = 'Fit content to page width' - AllowAllUp = True - Caption = 'Send' - Grouped = True - ImageIndex = 12 - ParentShowHint = False - ShowHint = True - Style = tbsCheck - OnClick = ContentFitWidthClick - end - object ToolButton2: TToolButton - Left = 312 - Top = 0 - Width = 8 - Caption = 'ToolButton2' - ImageIndex = 5 - Style = tbsSeparator - end - object FirstPage: TToolButton - Left = 320 - Top = 0 - Hint = 'Go to first page of document' - Caption = 'FirstPage' - ImageIndex = 3 - ParentShowHint = False - ShowHint = True - OnClick = FirstPageClick - end - object PrevPage: TToolButton - Left = 343 - Top = 0 - Hint = 'Go to previous page of document' - AllowAllUp = True - Caption = 'PrevPage' - Grouped = True - ImageIndex = 4 - ParentShowHint = False - ShowHint = True - OnClick = PrevPageClick - end - object cboxPage: TComboBox - Left = 366 - Top = 0 - Width = 145 - Height = 22 - Hint = 'List of all pages of this report' - Style = csDropDownList - TabOrder = 5 - OnChange = PageChange - end - object NextPage: TToolButton - Left = 511 - Top = 0 - Hint = 'Go to next page of document' - Caption = 'NextPage' - ImageIndex = 5 - ParentShowHint = False - ShowHint = True - OnClick = NextPageClick - end - object LastPage: TToolButton - Left = 534 - Top = 0 - Hint = 'Go to last page of document' - Caption = 'LastPage' - ImageIndex = 6 - OnClick = LastPageClick - end - object AllOnOne: TToolButton - Left = 557 - Top = 0 - Hint = 'Show all rows of this document on 1 page' - Caption = 'AllOnOne' - ImageIndex = 7 - Style = tbsCheck - Visible = False - OnClick = AllOnOneClick - end - object ToolButton9: TToolButton - Left = 0 - Top = 0 - Width = 8 - Caption = 'ToolButton9' - ImageIndex = 9 - Wrap = True - Style = tbsSeparator - end - object Label2: TLabel - Left = 0 - Top = 30 - Width = 41 - Height = 22 - Alignment = taCenter - AutoSize = False - Caption = 'Preview'#13#10'zoom' - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -9 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - Layout = tlCenter - end - object ZoomBox: TComboBox - Left = 41 - Top = 30 - Width = 81 - Height = 22 - Hint = 'Preview zoom' - Style = csDropDownList - TabOrder = 0 - OnChange = ZoomBoxChange - Items.Strings = ( - 'Fit to page' - 'Fit to height' - 'Fit to width' - '25%' - '50%' - '75%' - '100%' - '125%' - '150%' - '200%' - '300%' - '400%' - 'Custom') - end - object FitHeight: TToolButton - Left = 122 - Top = 30 - Hint = 'Fit preview to page height' - AllowAllUp = True - Caption = 'FitHeight' - Grouped = True - ImageIndex = 11 - ParentShowHint = False - ShowHint = True - Style = tbsCheck - OnClick = FitHeightClick - end - object FitWidth: TToolButton - Left = 145 - Top = 30 - Hint = 'Fit preview to page width' - AllowAllUp = True - Caption = 'FitWidth' - Grouped = True - ImageIndex = 12 - Style = tbsCheck - OnClick = FitWidthClick - end - object ToolButton14: TToolButton - Left = 168 - Top = 30 - Width = 8 - Caption = 'ToolButton14' - ImageIndex = 16 - Style = tbsSeparator - end - object Label3: TLabel - Left = 176 - Top = 30 - Width = 37 - Height = 22 - Alignment = taCenter - AutoSize = False - Caption = 'Pages per row' - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -9 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - Layout = tlCenter - WordWrap = True - end - object PagesPerRow: TSpinEdit - Left = 213 - Top = 30 - Width = 59 - Height = 22 - MaxValue = 100 - MinValue = 1 - TabOrder = 1 - Value = 1 - OnChange = PagesPerRowChange - end - object Label4: TLabel - Left = 272 - Top = 30 - Width = 29 - Height = 22 - Alignment = taCenter - AutoSize = False - Caption = 'Rows' - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -9 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - Layout = tlCenter - WordWrap = True - end - object RowsPerPreview: TSpinEdit - Left = 301 - Top = 30 - Width = 59 - Height = 22 - MaxValue = 100 - MinValue = 1 - TabOrder = 2 - Value = 1 - OnChange = RowsPerPreviewChange - end - object ToolButton11: TToolButton - Left = 360 - Top = 30 - Width = 8 - Caption = 'ToolButton11' - ImageIndex = 16 - Style = tbsSeparator - end - object Zooming: TToolButton - Left = 368 - Top = 30 - Hint = 'Selects the Zoom Tool to zoom in or out' - AllowAllUp = True - Caption = 'Zooming' - Grouped = True - ImageIndex = 13 - Style = tbsCheck - OnClick = ZoomingClick - end - object Panning: TToolButton - Left = 391 - Top = 30 - Hint = 'Selects the Hand Tool to pan across the Page' - AllowAllUp = True - Caption = 'Panning' - Grouped = True - ImageIndex = 14 - ParentShowHint = False - ShowHint = True - Style = tbsCheck - OnClick = PanningClick - end - object ToolButton10: TToolButton - Left = 414 - Top = 30 - Width = 8 - Caption = 'ToolButton10' - Style = tbsSeparator - end - object Grid: TToolButton - Left = 422 - Top = 30 - Hint = 'Show/Hide Grid' - Caption = 'Grid' - ImageIndex = 15 - Style = tbsCheck - OnClick = GridClick - end - object UnitsBox: TComboBox - Left = 445 - Top = 30 - Width = 81 - Height = 22 - Style = csDropDownList - TabOrder = 3 - OnChange = UnitsBoxChange - Items.Strings = ( - 'Inches' - 'Centimeters') - end - end - object imgList: TImageList - Left = 196 - Top = 112 - Bitmap = { - 494C010113001800280010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 - 0000000000003600000028000000400000005000000001002000000000000050 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000084848400008400008484 - 8400008400008484840000840000848484000084000084848400008400008484 - 8400008400008484840000840000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000008484840000840000848484000084 - 0000848484000084000084848400008400008484840000840000848484000084 - 0000848484000084000084848400008400000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000 - FF00000000000000000000000000000000000084000084848400FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF0000840000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000 - FF00000000000000000000000000000000008484840000840000FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0084848400008400008484 - 8400008400008484840084848400008400000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000FF000000FF00000000000000000000000000000000000000 - 0000000000000000000000000000000000000084000084848400FFFFFF000084 - 0000848484000084000084848400008400008484840000840000FFFFFF000084 - 0000848484000084000000840000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000FF000000FF000000FF0000000000000000000000 - 0000000000000000000000000000000000008484840000840000FFFFFF008484 - 84000084000084848400008400008484840000840000FFFFFF00008400008484 - 840000840000FFFFFF0084848400008400000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000FF000000FF000000FF00000000000000 - 0000000000000000000000000000000000000084000084848400FFFFFF000084 - 000084848400008400008484840000840000FFFFFF0000840000848484000084 - 000084848400FFFFFF0000840000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000FF000000FF000000FF000000 - 0000000000000000000000000000000000008484840000840000FFFFFF00FFFF - FF00008400008484840000840000FFFFFF000084000084848400008400008484 - 840000840000FFFFFF0084848400008400000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000FF000000FF000000 - 0000000000000000000000000000000000000084000084848400FFFFFF00FFFF - FF00FFFFFF0000840000FFFFFF0000840000848484000084000084848400FFFF - FF00FFFFFF00FFFFFF0000840000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000FF0000000000000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000000000FF000000 - FF00000000000000000000000000000000008484840000840000FFFFFF00FFFF - FF0000840000FFFFFF0000840000848484000084000084848400008400008484 - 8400FFFFFF00FFFFFF0084848400008400000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000FF000000FF00000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000FF000000FF00000000000000000000000000000000000000FF000000 - FF00000000000000000000000000000000000084000084848400FFFFFF000084 - 0000FFFFFF000084000084848400008400008484840000840000848484000084 - 000084848400FFFFFF0000840000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000FF000000FF000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000FF000000FF000000FF000000000000000000000000000000FF000000 - FF00000000000000000000000000000000008484840000840000FFFFFF008484 - 840000840000848484000084000084848400FFFFFF0084848400008400008484 - 840000840000FFFFFF0084848400008400000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000FF000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000FF000000FF000000FF000000FF000000FF000000FF000000 - 0000000000000000000000000000000000000084000084848400FFFFFF000084 - 0000848484000084000084848400FFFFFF00FFFFFF00FFFFFF00848484000084 - 000084848400FFFFFF0000840000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000FF000000FF000000FF000000FF00000000000000 - 0000000000000000000000000000000000008484840000840000FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF0084848400008400000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000084000084848400008400008484 - 8400008400008484840000840000848484000084000084848400008400008484 - 8400008400008484840000840000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000840000848484000084 - 0000848484000084000084848400008400008484840000840000848484000084 - 0000848484000084000084848400000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000FFFF - FF00FFFFFF000000000000000000000000000000000080808000808080000000 - 0000808080008080800000000000808080008080800000000000808080008080 - 8000000000008080800080808000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00000000000000 - 0000FFFFFF00FFFFFF0000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000000000000808080000000000000FFFF00808080000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00000000000000 - 000000000000FFFFFF0000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 800080808000808080008080800080808000000000000000000000FFFF000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF0000000000FFFFFF0000000000FFFFFF0000000000FFFFFF00000000000000 - 0000000000000000000000000000000000000000000080808000808080000000 - 0000808080008080800000000000808080008080800000000000808080008080 - 8000000000008080800080808000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000080808000FFFF - FF00C0C0C000FFFFFF00C0C0C000FFFFFF008080800000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF0000000000FFFFFF0000000000FFFFFF0000000000FFFFFF00000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000008080800080808000FFFFFF00C0C0 - C000FFFFFF000000FF00FFFFFF00C0C0C000FFFFFF0080808000808080000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF0000000000FFFFFF0000000000FFFFFF0000000000FFFFFF00000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000080808000C0C0C000FFFF - FF00C0C0C0000000FF00C0C0C000FFFFFF00C0C0C00080808000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF0000000000FFFFFF0000000000FFFFFF0000000000FFFFFF00000000000000 - 0000000000000000000000000000000000000000000080808000808080000000 - 0000808080008080800000000000808080008080800000000000808080008080 - 8000000000008080800080808000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000080808000FFFFFF000000 - FF000000FF000000FF000000FF000000FF00FFFFFF0080808000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF0000000000FFFFFF0000000000FFFFFF0000000000FFFFFF00000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000080808000C0C0C000FFFF - FF00C0C0C0000000FF00C0C0C000FFFFFF00C0C0C00080808000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000FFFFFF0000000000FFFFFF0000000000FFFFFF00000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000008080800080808000FFFFFF00C0C0 - C000FFFFFF000000FF00FFFFFF00C0C0C000FFFFFF0080808000808080000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000FFFFFF0000000000FFFFFF0000000000FFFFFF00000000000000 - 0000000000000000000000000000000000000000000080808000808080000000 - 0000808080008080800000000000808080008080800000000000808080008080 - 8000000000008080800080808000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000080808000FFFF - FF00C0C0C000FFFFFF00C0C0C000FFFFFF008080800000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000FFFFFF0000000000FFFFFF00000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000808080008080800080808000808080000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000FFFFFF000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000000000000808080000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000303030009F9F9F00000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000030303000EFEFEF00FFFFFF009F9F9F000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FF000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00000000000000000000000000000000008484 - 8400000000000000000000000000000000000000000000000000000000003030 - 3000EFEFEF00FFFFFF00FFFFFF00FFFFFF009F9F9F0000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FF000000FF000000FF000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF000000000084848400C6C6C600C6C6C600848484000000 - 000084848400000000000000000000000000000000000000000030303000EFEF - EF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF009F9F9F00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FF000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF000000000084848400C6C6C600C6C6C600FFFF0000848484008484 - 8400000000000000000000000000000000000000000030303000EFEFEF00FFB2 - 7F00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFD8BF00FFFFFF009F9F9F000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FF000000FF000000FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000C6C6C600C6C6C600C6C6C600C6C6C60084848400C6C6 - C60000000000000000000000000000000000000000009F9F9F00FFB27F00FFFF - FF00FFD8BF00FFFFFF00FFD8BF00FFD8BF00FFD8BF00FFB27F00FFFFFF009F9F - 9F00000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FF000000FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000C6C6C600FFFF0000C6C6C600C6C6C60084848400C6C6 - C6000000000000000000000000000000000000000000000000009F9F9F00FFD8 - BF00FFFFFF00FFFFFF00FFFFFF00FFB27F00FFD8BF00FFD8BF00FFFFFF00FFFF - FF009F9F9F000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FF000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF000000000084848400FFFF0000FFFF0000C6C6C600848484008484 - 8400000000000000000000000000000000000000000000000000000000009F9F - 9F00DFDFDF00DFDFDF00FFFFFF00FFFFFF00FFB27F00FFD8BF00FFFFFF00FFFF - FF00FFFFFF009F9F9F0000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FF000000FF000000FF000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF000000000084848400C6C6C600C6C6C600848484000000 - 0000000000000000000000000000000000000000000000000000000000003030 - 30007F7F7F007F7F7F00FFFFFF00FFFFFF00FFFFFF00FFD8BF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF009F9F9F00000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FF000000FFFFFF00FFFFFF0000000000000000000000 - 00000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000006060 - 600060606000AFAFAF00FFFFFF00EFEFEF006F6F6F00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00EFEFEF00303030000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FF000000FF000000FFFFFF0000000000FFFFFF00FFFF - FF000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00000000000000 - 000000000000000000000000000000000000000000000000000060606000DFDF - DF00FFFFFF00FFFFFF00EFEFEF006F6F6F00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00EFEFEF0030303000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FF000000FFFFFF0000000000FFFFFF000000 - 00000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00000000000000000000000000000000000000 - 000000000000000000000000000000000000000000006F6F6F007F7F7F007F7F - 7F00FFFFFF00EFEFEF004D4D4D009F9F9F00FFFFFF00BFE1BF003FA53F00FFFF - FF00EFEFEF003030300000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000000000000000 - 00000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF0000000000FFFFFF0000000000000000000000 - 0000000000000000000000000000000000003030300060606000606060006060 - 6000606060004D4D4D00777777001D1D1D009F9F9F003FA53F0000880000AFD1 - AF00303030000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000003B3B3B003B3B - 3B003B3B3B003B3B3B001D1D1D0000000000000000009F9F9F00AFD1AF003030 - 3000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000303030000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000084848400848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000008484840084848400000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000084848400848484000000000000000000000000008484 - 8400848484008484840000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000008484840000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000084848400000000000000000000000000000000008484 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000FF000000000000848484008484840084848400848484008484 - 8400848484008484840084848400848484008484840084848400848484008484 - 840084848400848484008484840084848400848484000000000000FF00000000 - 0000000000000000000000000000000000008484840084848400848484008484 - 84008484840084848400848484000000000000FF000000000000000000008484 - 84000000000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000FF000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000848484008484840000000000000000000000 - 000000000000000000000000000000000000000000000000000000FF000000FF - 0000000000000000000000000000000000008484840000000000000000000000 - 00000000000000000000000000000000000000FF000000FF0000000000008484 - 84000000000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000000000000000FF - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 000000FF000000FF00000000000084848400848484000000000000FF000000FF - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 000000FF0000000000000000000000000000848484000000000000FF000000FF - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF00000000 - 00000000000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000FF000000FF - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 000000FF000000FF00000000000084848400848484000000000000FF000000FF - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 000000FF000000FF00000000000000000000848484000000000000FF000000FF - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 00000000000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000000000000000FF - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 000000FF000000FF00000000000084848400848484000000000000FF000000FF - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 000000FF0000000000000000000000000000848484000000000000FF000000FF - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF00000000 - 00000000000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000FF000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000FF000000FF - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000FF000000FF0000000000008484 - 84000000000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000FF00000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000FF000000000000000000008484 - 84000000000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0008000 - 8000C0C0C0000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000008000 - 8000800080008000800080008000800080008000800080008000800080008000 - 8000800080000000000000000000000000000000000000000000C6C6C600C6C6 - C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C6000000 - 0000C6C6C6000000000000000000000000000000000000000000008484000084 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000000000000084840000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0008000 - 8000C0C0C0000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000C6C6C60000000000000000000000000000000000008484000084 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000000000000084840000000000000000000000000000000000848484008484 - 8400848484000000000000000000000000008484840084848400000000000000 - 000000000000000000000000000000000000000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0008000 - 8000C0C0C00000000000000000000000000000000000C6C6C600C6C6C600C6C6 - C600C6C6C600C6C6C600C6C6C60000FFFF0000FFFF0000FFFF00C6C6C600C6C6 - C600000000000000000000000000000000000000000000000000008484000084 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000000000000084840000000000000000000000000000000000000000000000 - 0000848484000000000000000000000000000000000084848400000000000000 - 000000000000000000000000000000000000000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0008000 - 8000C0C0C00000000000000000000000000000000000C6C6C600C6C6C600C6C6 - C600C6C6C600C6C6C600C6C6C600848484008484840084848400C6C6C600C6C6 - C60000000000C6C6C60000000000000000000000000000000000008484000084 - 8400000000000000000000000000000000000000000000000000000000000000 - 000000000000008484000000000000000000000000000000000000FF00000000 - 000084848400000000000000000000FF00000000000084848400848484008484 - 840084848400848484008484840084848400000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0008000 - 8000C0C0C0000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000C6C6C600C6C6C600000000000000000000000000008484000084 - 8400008484000084840000848400008484000084840000848400008484000084 - 840000848400008484000000000000000000000000000000000000FF00000000 - 0000848484000000000000FF000000FF00000000000000000000000000000000 - 000000000000000000000000000084848400000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0008000 - 8000C0C0C00000000000000000000000000000000000C6C6C600C6C6C600C6C6 - C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C6000000 - 0000C6C6C60000000000C6C6C600000000000000000000000000008484000084 - 8400000000000000000000000000000000000000000000000000000000000000 - 000000848400008484000000000000000000000000000000000000FF00000000 - 00000000000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 000000FF000000FF00000000000084848400000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0008000 - 8000C0C0C0000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000C6C6 - C60000000000C6C6C60000000000000000000000000000000000008484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000008484000000000000000000000000000000000000FF00000000 - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 000000FF000000FF00000000000084848400000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0008000 - 8000C0C0C000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 - 0000C6C6C60000000000C6C6C600000000000000000000000000008484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000008484000000000000000000000000000000000000FF00000000 - 00000000000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 000000FF000000FF00000000000084848400000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0008000 - 8000C0C0C0000000000000000000000000000000000000000000000000000000 - 0000FFFFFF000000000000000000000000000000000000000000FFFFFF000000 - 0000000000000000000000000000000000000000000000000000008484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000008484000000000000000000000000000000000000FF00000000 - 0000848484000000000000FF000000FF00000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00000000000000000000000000000000000000000000000000008484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000008484000000000000000000000000000000000000FF00000000 - 000084848400000000000000000000FF00000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000008000 - 800080008000800080008000800080008000800080008000800000000000C0C0 - C000000000000000000000000000000000000000000000000000000000000000 - 000000000000FFFFFF000000000000000000000000000000000000000000FFFF - FF00000000000000000000000000000000000000000000000000008484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF000000000000000000000000000000000000000000008484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000424D3E000000000000003E000000 - 2800000040000000500000000100010000000000800200000000000000000000 - 000000000000000000000000FFFFFF00FFFFFFFF80010000FFFFFFFF00000000 - FF3FF00F00000000FF3FF00F00000000FF3FF9FF00000000FF3FFC7F00000000 - FF3FFE3F00000000FF3FFF1F00000000FF3FFF9F00000000FB3FFFCF00000000 - F93FF3CF00000000FC3FF1CF00000000FE3FF81F00000000FF3FFC3F00000000 - FFFFFFFF00000000FFFFFFFF80010000FFFFFFFDF01FFFFFFFFFFFF8E00FEDB7 - 6006FFF1C007EDB77FFEFFE3C00380017FFEFFC7C001EDB77FFEE08FC011EDB7 - 6006C01FC01980017FFE803FC01FEDB77FFE001FC01FEDB77FFE001FC01F8001 - 6006001FC01FEDB77FFE001FE01FEDB77FFE001FF01F80010000803FF01FEDB7 - FFFFC07FFC3FEDB7FFFFE0FFFC7FFFFFFFFF001CF9FFC003C0030018F0FFDFFB - C0030011E07FDFFBC0030003C03FD00BC0030007801FDFFBC0030007800FDFFB - C00300070007D00BC00300078003DFFBC0030007C001DFFBC003000FE000D00B - C003001FC000DFFBC007001FC001DFFBC00F001F0003D00BC01F003F0007DFFB - C03F007F810FDFFBFFFF00FFFF9FC003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFCFFFF3FFCE3E5B7F8FFFF1FFC61D9B7F000000F0021DDB7 - E00000070001E1B7C00000030001FDB7800000010001DDB7C00000030001E3B7 - E00180078001FFB7F1FFFF8FFE21FFB7F9FFFF9FFE71FFB7FFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC003FFFFFFFFFFFFC003C007C001FFFF - C00380038031FFFFC00300018031C73FC00300018031863FC003000180018400 - C003000080018000C003000080018000C00380008FF18000C003C0008FF18000 - C003E0018FF18001C003E0078FF1847FC007F0078FF18E7FC00FF0038FF5FFFF - C01FF8038001FFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000 - 000000000000} - end - object PrintDialog: TPrintDialog - Left = 80 - Top = 116 - end - object PrinterSetupDialog: TPrinterSetupDialog - Left = 80 - Top = 180 - end -end diff --git a/CORE/Source/Plugins/Htmlviewer/source/BegaPreview.lfm b/CORE/Source/Plugins/Htmlviewer/source/BegaPreview.lfm deleted file mode 100644 index 9a6e5f350..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/BegaPreview.lfm +++ /dev/null @@ -1,1198 +0,0 @@ -object BegaCustomPreviewFrame: TBegaCustomPreviewFrame - Left = 0 - Top = 0 - Width = 590 - Height = 550 - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - ParentShowHint = False - ShowHint = True - TabOrder = 0 - object StatBarPanel: TPanel - Left = 0 - Top = 533 - Width = 590 - Height = 17 - Align = alBottom - BevelOuter = bvNone - Font.Charset = DEFAULT_CHARSET - Font.Color = clBlack - Font.Height = -11 - Font.Name = 'Arial' - Font.Style = [] - ParentFont = False - TabOrder = 1 - object CurrentPageLabel: TPanel - Left = 0 - Top = 0 - Width = 121 - Height = 17 - Hint = 'Displays the number of the first visible page' - Align = alLeft - BevelOuter = bvLowered - Caption = 'Current page' - TabOrder = 0 - end - object PreviewZoomLabel: TPanel - Left = 242 - Top = 0 - Width = 121 - Height = 17 - Hint = 'Displays the current preview zoom level (100% = normal)' - Align = alLeft - BevelOuter = bvLowered - Caption = 'Preview zoom' - TabOrder = 1 - end - object Panel1: TPanel - Left = 363 - Top = 0 - Width = 227 - Height = 17 - Hint = 'Displays Help for the object beneath the mouse' - Align = alClient - BevelOuter = bvLowered - TabOrder = 2 - object HintLabel: TLabel - Left = 8 - Top = 5 - Width = 3 - Height = 14 - Hint = 'Displays Help for the object beneath the mouse' - end - end - object ContentZoomLabel: TPanel - Left = 121 - Top = 0 - Width = 121 - Height = 17 - Hint = 'Displays the current content zoom level (100% = normal)' - Align = alLeft - BevelOuter = bvLowered - Caption = 'Content zoom' - TabOrder = 3 - end - end - object ToolBar: TToolBar - Left = 0 - Top = 0 - Width = 590 - Height = 56 - AutoSize = True - BorderWidth = 1 - Caption = 'ToolBar' - EdgeInner = esNone - EdgeOuter = esNone - Images = imgList - ParentShowHint = False - ShowHint = True - TabOrder = 0 - object ReportProperties: TToolButton - Left = 0 - Top = 0 - Caption = 'ReportProperties' - ImageIndex = 8 - OnClick = ReportPropertiesClick - end - object PrinterSetup: TToolButton - Left = 23 - Top = 0 - Hint = 'Setup printer...' - Caption = 'PrinterSetup' - ImageIndex = 0 - ParentShowHint = False - ShowHint = True - OnClick = PrinterSetupClick - end - object Print: TToolButton - Left = 46 - Top = 0 - Hint = 'Print shown document...' - Caption = 'Print' - ImageIndex = 1 - ParentShowHint = False - ShowHint = True - OnClick = PrintClick - end - object SendMail: TToolButton - Left = 69 - Top = 0 - Hint = 'Send e-mail with shown document...' - Caption = 'SendMail' - ImageIndex = 10 - Visible = False - OnClick = SendMailClick - end - object SaveFile: TToolButton - Left = 92 - Top = 0 - Hint = 'Save shown document as HTML file...' - Caption = 'SaveFile' - ImageIndex = 2 - ParentShowHint = False - ShowHint = True - Visible = False - OnClick = SaveFileClick - end - object OpenInExcel: TToolButton - Left = 115 - Top = 0 - Hint = 'Open shown document in '#39'MS Excel'#39 - Caption = 'OpenInExcel' - ImageIndex = 18 - OnClick = OpenInExcelClick - end - object ContentZoomSeparator: TToolButton - Left = 138 - Top = 0 - Width = 8 - Caption = 'ContentZoomSeparator' - ImageIndex = 4 - Style = tbsSeparator - end - object ContentZoomBoxLabel: TLabel - Left = 146 - Top = 0 - Width = 39 - Height = 22 - Alignment = taCenter - AutoSize = False - Caption = 'Content'#13#10'zoom' - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -9 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - Layout = tlCenter - end - object ContentZoomBox: TComboBox - Left = 185 - Top = 0 - Width = 81 - Height = 21 - Hint = 'Content zoom' - Style = csDropDownList - ItemHeight = 13 - TabOrder = 4 - OnChange = ContentZoomBoxChange - Items.Strings = ( - 'Fit to page' - 'Fit to height' - 'Fit to width' - '25%' - '50%' - '75%' - '100%' - '125%' - '150%' - '200%' - '300%' - '400%' - '800%') - end - object ContentFitHeight: TToolButton - Left = 266 - Top = 0 - Hint = 'Fit content to page height' - AllowAllUp = True - Caption = 'ContentFitHeight' - Grouped = True - ImageIndex = 11 - Style = tbsCheck - OnClick = ContentFitHeightClick - end - object ContentFitWidth: TToolButton - Left = 289 - Top = 0 - Hint = 'Fit content to page width' - AllowAllUp = True - Caption = 'Send' - Grouped = True - ImageIndex = 12 - ParentShowHint = False - ShowHint = True - Style = tbsCheck - OnClick = ContentFitWidthClick - end - object ToolButton2: TToolButton - Left = 312 - Top = 0 - Width = 8 - Caption = 'ToolButton2' - ImageIndex = 5 - Style = tbsSeparator - end - object FirstPage: TToolButton - Left = 320 - Top = 0 - Hint = 'Go to first page of document' - Caption = 'FirstPage' - ImageIndex = 3 - ParentShowHint = False - ShowHint = True - OnClick = FirstPageClick - end - object PrevPage: TToolButton - Left = 343 - Top = 0 - Hint = 'Go to previous page of document' - AllowAllUp = True - Caption = 'PrevPage' - Grouped = True - ImageIndex = 4 - ParentShowHint = False - ShowHint = True - OnClick = PrevPageClick - end - object cboxPage: TComboBox - Left = 366 - Top = 0 - Width = 145 - Height = 21 - Hint = 'List of all pages of this report' - Style = csDropDownList - ItemHeight = 13 - TabOrder = 5 - OnChange = PageChange - end - object NextPage: TToolButton - Left = 511 - Top = 0 - Hint = 'Go to next page of document' - Caption = 'NextPage' - ImageIndex = 5 - ParentShowHint = False - ShowHint = True - OnClick = NextPageClick - end - object LastPage: TToolButton - Left = 534 - Top = 0 - Hint = 'Go to last page of document' - Caption = 'LastPage' - ImageIndex = 6 - OnClick = LastPageClick - end - object AllOnOne: TToolButton - Left = 557 - Top = 0 - Hint = 'Show all rows of this document on 1 page' - Caption = 'AllOnOne' - ImageIndex = 7 - Style = tbsCheck - Visible = False - OnClick = AllOnOneClick - end - object ToolButton9: TToolButton - Left = 0 - Top = 0 - Width = 8 - Caption = 'ToolButton9' - ImageIndex = 9 - Wrap = True - Style = tbsSeparator - end - object Label2: TLabel - Left = 0 - Top = 30 - Width = 41 - Height = 22 - Alignment = taCenter - AutoSize = False - Caption = 'Preview'#13#10'zoom' - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -9 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - Layout = tlCenter - end - object ZoomBox: TComboBox - Left = 41 - Top = 30 - Width = 81 - Height = 21 - Hint = 'Preview zoom' - Style = csDropDownList - ItemHeight = 13 - TabOrder = 0 - OnChange = ZoomBoxChange - Items.Strings = ( - 'Fit to page' - 'Fit to height' - 'Fit to width' - '25%' - '50%' - '75%' - '100%' - '125%' - '150%' - '200%' - '300%' - '400%' - 'Custom') - end - object FitHeight: TToolButton - Left = 122 - Top = 30 - Hint = 'Fit preview to page height' - AllowAllUp = True - Caption = 'FitHeight' - Grouped = True - ImageIndex = 11 - ParentShowHint = False - ShowHint = True - Style = tbsCheck - OnClick = FitHeightClick - end - object FitWidth: TToolButton - Left = 145 - Top = 30 - Hint = 'Fit preview to page width' - AllowAllUp = True - Caption = 'FitWidth' - Grouped = True - ImageIndex = 12 - Style = tbsCheck - OnClick = FitWidthClick - end - object ToolButton14: TToolButton - Left = 168 - Top = 30 - Width = 8 - Caption = 'ToolButton14' - ImageIndex = 16 - Style = tbsSeparator - end - object Label3: TLabel - Left = 176 - Top = 30 - Width = 37 - Height = 22 - Alignment = taCenter - AutoSize = False - Caption = 'Pages per row' - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -9 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - Layout = tlCenter - WordWrap = True - end - object PagesPerRow: TSpinEdit - Left = 213 - Top = 30 - Width = 59 - Height = 22 - MaxValue = 100 - MinValue = 1 - TabOrder = 1 - Value = 1 - OnChange = PagesPerRowChange - end - object Label4: TLabel - Left = 272 - Top = 30 - Width = 29 - Height = 22 - Alignment = taCenter - AutoSize = False - Caption = 'Rows' - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -9 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - Layout = tlCenter - WordWrap = True - end - object RowsPerPreview: TSpinEdit - Left = 301 - Top = 30 - Width = 59 - Height = 22 - MaxValue = 100 - MinValue = 1 - TabOrder = 2 - Value = 1 - OnChange = RowsPerPreviewChange - end - object ToolButton11: TToolButton - Left = 360 - Top = 30 - Width = 8 - Caption = 'ToolButton11' - ImageIndex = 16 - Style = tbsSeparator - end - object Zooming: TToolButton - Left = 368 - Top = 30 - Hint = 'Selects the Zoom Tool to zoom in or out' - AllowAllUp = True - Caption = 'Zooming' - Grouped = True - ImageIndex = 13 - Style = tbsCheck - OnClick = ZoomingClick - end - object Panning: TToolButton - Left = 391 - Top = 30 - Hint = 'Selects the Hand Tool to pan across the Page' - AllowAllUp = True - Caption = 'Panning' - Grouped = True - ImageIndex = 14 - ParentShowHint = False - ShowHint = True - Style = tbsCheck - OnClick = PanningClick - end - object ToolButton10: TToolButton - Left = 414 - Top = 30 - Width = 8 - Caption = 'ToolButton10' - Style = tbsSeparator - end - object Grid: TToolButton - Left = 422 - Top = 30 - Hint = 'Show/Hide Grid' - Caption = 'Grid' - ImageIndex = 15 - Style = tbsCheck - OnClick = GridClick - end - object UnitsBox: TComboBox - Left = 445 - Top = 30 - Width = 81 - Height = 21 - Style = csDropDownList - ItemHeight = 13 - TabOrder = 3 - OnChange = UnitsBoxChange - Items.Strings = ( - 'Inches' - 'Centimeters') - end - end - object PreviewBox: TBegaZoomBox - Left = 0 - Top = 56 - Width = 590 - Height = 477 - HorzScrollBar.Tracking = True - VertScrollBar.Tracking = True - Align = alClient - TabOrder = 2 - OnResize = PreviewBoxResize - object PreviewPanel: TBegaMetafilePreviewPanel - Left = 0 - Top = 0 - Width = 348 - Height = 448 - BevelOuter = bvNone - BevelWidth = 0 - Color = clBtnShadow - CommonColumnWidth = 0 - CommonRowHeight = 0 - TabOrder = 0 - OnMouseDown = PreviewPanelMouseDown - OnMouseMove = PreviewPanelMouseMove - OnMouseUp = PreviewPanelMouseUp - OnPaintPage = PreviewPanelPaintPage - OnUpdatePreview = PreviewPanelUpdatePreview - end - end - object imgList: TImageList - Left = 196 - Top = 112 - Bitmap = { - 494C010113001800100010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 - 0000000000003600000028000000400000005000000001002000000000000050 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000084848400008400008484 - 8400008400008484840000840000848484000084000084848400008400008484 - 8400008400008484840000840000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000008484840000840000848484000084 - 0000848484000084000084848400008400008484840000840000848484000084 - 0000848484000084000084848400008400000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000 - FF00000000000000000000000000000000000084000084848400FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF0000840000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000 - FF00000000000000000000000000000000008484840000840000FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0084848400008400008484 - 8400008400008484840084848400008400000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000FF000000FF00000000000000000000000000000000000000 - 0000000000000000000000000000000000000084000084848400FFFFFF000084 - 0000848484000084000084848400008400008484840000840000FFFFFF000084 - 0000848484000084000000840000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000FF000000FF000000FF0000000000000000000000 - 0000000000000000000000000000000000008484840000840000FFFFFF008484 - 84000084000084848400008400008484840000840000FFFFFF00008400008484 - 840000840000FFFFFF0084848400008400000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000FF000000FF000000FF00000000000000 - 0000000000000000000000000000000000000084000084848400FFFFFF000084 - 000084848400008400008484840000840000FFFFFF0000840000848484000084 - 000084848400FFFFFF0000840000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000FF000000FF000000FF000000 - 0000000000000000000000000000000000008484840000840000FFFFFF00FFFF - FF00008400008484840000840000FFFFFF000084000084848400008400008484 - 840000840000FFFFFF0084848400008400000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000FF000000FF000000 - 0000000000000000000000000000000000000084000084848400FFFFFF00FFFF - FF00FFFFFF0000840000FFFFFF0000840000848484000084000084848400FFFF - FF00FFFFFF00FFFFFF0000840000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000FF0000000000000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000000000FF000000 - FF00000000000000000000000000000000008484840000840000FFFFFF00FFFF - FF0000840000FFFFFF0000840000848484000084000084848400008400008484 - 8400FFFFFF00FFFFFF0084848400008400000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000FF000000FF00000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000FF000000FF00000000000000000000000000000000000000FF000000 - FF00000000000000000000000000000000000084000084848400FFFFFF000084 - 0000FFFFFF000084000084848400008400008484840000840000848484000084 - 000084848400FFFFFF0000840000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000FF000000FF000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000FF000000FF000000FF000000000000000000000000000000FF000000 - FF00000000000000000000000000000000008484840000840000FFFFFF008484 - 840000840000848484000084000084848400FFFFFF0084848400008400008484 - 840000840000FFFFFF0084848400008400000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000FF000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000FF000000FF000000FF000000FF000000FF000000FF000000 - 0000000000000000000000000000000000000084000084848400FFFFFF000084 - 0000848484000084000084848400FFFFFF00FFFFFF00FFFFFF00848484000084 - 000084848400FFFFFF0000840000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000FF000000FF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000FF000000FF000000FF000000FF00000000000000 - 0000000000000000000000000000000000008484840000840000FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF0084848400008400000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000084000084848400008400008484 - 8400008400008484840000840000848484000084000084848400008400008484 - 8400008400008484840000840000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000840000848484000084 - 0000848484000084000084848400008400008484840000840000848484000084 - 0000848484000084000084848400000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000FFFF - FF00FFFFFF000000000000000000000000000000000080808000808080000000 - 0000808080008080800000000000808080008080800000000000808080008080 - 8000000000008080800080808000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00000000000000 - 0000FFFFFF00FFFFFF0000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000000000000808080000000000000FFFF00808080000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00000000000000 - 000000000000FFFFFF0000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 800080808000808080008080800080808000000000000000000000FFFF000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF0000000000FFFFFF0000000000FFFFFF0000000000FFFFFF00000000000000 - 0000000000000000000000000000000000000000000080808000808080000000 - 0000808080008080800000000000808080008080800000000000808080008080 - 8000000000008080800080808000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000080808000FFFF - FF00C0C0C000FFFFFF00C0C0C000FFFFFF008080800000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF0000000000FFFFFF0000000000FFFFFF0000000000FFFFFF00000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000008080800080808000FFFFFF00C0C0 - C000FFFFFF000000FF00FFFFFF00C0C0C000FFFFFF0080808000808080000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF0000000000FFFFFF0000000000FFFFFF0000000000FFFFFF00000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000080808000C0C0C000FFFF - FF00C0C0C0000000FF00C0C0C000FFFFFF00C0C0C00080808000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF0000000000FFFFFF0000000000FFFFFF0000000000FFFFFF00000000000000 - 0000000000000000000000000000000000000000000080808000808080000000 - 0000808080008080800000000000808080008080800000000000808080008080 - 8000000000008080800080808000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000080808000FFFFFF000000 - FF000000FF000000FF000000FF000000FF00FFFFFF0080808000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF0000000000FFFFFF0000000000FFFFFF0000000000FFFFFF00000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000080808000C0C0C000FFFF - FF00C0C0C0000000FF00C0C0C000FFFFFF00C0C0C00080808000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000FFFFFF0000000000FFFFFF0000000000FFFFFF00000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000008080800080808000FFFFFF00C0C0 - C000FFFFFF000000FF00FFFFFF00C0C0C000FFFFFF0080808000808080000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000FFFFFF0000000000FFFFFF0000000000FFFFFF00000000000000 - 0000000000000000000000000000000000000000000080808000808080000000 - 0000808080008080800000000000808080008080800000000000808080008080 - 8000000000008080800080808000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000080808000FFFF - FF00C0C0C000FFFFFF00C0C0C000FFFFFF008080800000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000FFFFFF0000000000FFFFFF00000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000808080008080800080808000808080000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000FFFFFF000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000080808000000000000000000080808000000000000000 - 0000808080000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000008080 - 8000000000000000000000000000808080000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000303030009F9F9F00000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000030303000EFEFEF00FFFFFF009F9F9F000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FF000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00000000000000000000000000000000008484 - 8400000000000000000000000000000000000000000000000000000000003030 - 3000EFEFEF00FFFFFF00FFFFFF00FFFFFF009F9F9F0000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FF000000FF000000FF000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF000000000084848400C6C6C600C6C6C600848484000000 - 000084848400000000000000000000000000000000000000000030303000EFEF - EF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF009F9F9F00000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FF000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF000000000084848400C6C6C600C6C6C600FFFF0000848484008484 - 8400000000000000000000000000000000000000000030303000EFEFEF00FFB2 - 7F00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFD8BF00FFFFFF009F9F9F000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FF000000FF000000FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000C6C6C600C6C6C600C6C6C600C6C6C60084848400C6C6 - C60000000000000000000000000000000000000000009F9F9F00FFB27F00FFFF - FF00FFD8BF00FFFFFF00FFD8BF00FFD8BF00FFD8BF00FFB27F00FFFFFF009F9F - 9F00000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FF000000FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000C6C6C600FFFF0000C6C6C600C6C6C60084848400C6C6 - C6000000000000000000000000000000000000000000000000009F9F9F00FFD8 - BF00FFFFFF00FFFFFF00FFFFFF00FFB27F00FFD8BF00FFD8BF00FFFFFF00FFFF - FF009F9F9F000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FF000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF000000000084848400FFFF0000FFFF0000C6C6C600848484008484 - 8400000000000000000000000000000000000000000000000000000000009F9F - 9F00DFDFDF00DFDFDF00FFFFFF00FFFFFF00FFB27F00FFD8BF00FFFFFF00FFFF - FF00FFFFFF009F9F9F0000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FF000000FF000000FF000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF000000000084848400C6C6C600C6C6C600848484000000 - 0000000000000000000000000000000000000000000000000000000000003030 - 30007F7F7F007F7F7F00FFFFFF00FFFFFF00FFFFFF00FFD8BF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF009F9F9F00000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FF000000FFFFFF00FFFFFF0000000000000000000000 - 00000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000006060 - 600060606000AFAFAF00FFFFFF00EFEFEF006F6F6F00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00EFEFEF00303030000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FF000000FF000000FFFFFF0000000000FFFFFF00FFFF - FF000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00000000000000 - 000000000000000000000000000000000000000000000000000060606000DFDF - DF00FFFFFF00FFFFFF00EFEFEF006F6F6F00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00EFEFEF0030303000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FF000000FFFFFF0000000000FFFFFF000000 - 00000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00000000000000000000000000000000000000 - 000000000000000000000000000000000000000000006F6F6F007F7F7F007F7F - 7F00FFFFFF00EFEFEF004D4D4D009F9F9F00FFFFFF00BFE1BF003FA53F00FFFF - FF00EFEFEF003030300000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000000000000000 - 00000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF0000000000FFFFFF0000000000000000000000 - 0000000000000000000000000000000000003030300060606000606060006060 - 6000606060004D4D4D00777777001D1D1D009F9F9F003FA53F0000880000AFD1 - AF00303030000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000003B3B3B003B3B - 3B003B3B3B003B3B3B001D1D1D0000000000000000009F9F9F00AFD1AF003030 - 3000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000303030000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000084848400848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000008484840084848400000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000084848400848484000000000000000000000000008484 - 8400848484008484840000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000008484840000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000084848400000000000000000000000000000000008484 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000FF000000000000848484008484840084848400848484008484 - 8400848484008484840084848400848484008484840084848400848484008484 - 840084848400848484008484840084848400848484000000000000FF00000000 - 0000000000000000000000000000000000008484840084848400848484008484 - 84008484840084848400848484000000000000FF000000000000000000008484 - 84000000000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000FF000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000848484008484840000000000000000000000 - 000000000000000000000000000000000000000000000000000000FF000000FF - 0000000000000000000000000000000000008484840000000000000000000000 - 00000000000000000000000000000000000000FF000000FF0000000000008484 - 84000000000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000000000000000FF - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 000000FF000000FF00000000000084848400848484000000000000FF000000FF - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 000000FF0000000000000000000000000000848484000000000000FF000000FF - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF00000000 - 00000000000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000FF000000FF - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 000000FF000000FF00000000000084848400848484000000000000FF000000FF - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 000000FF000000FF00000000000000000000848484000000000000FF000000FF - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 00000000000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000000000000000FF - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 000000FF000000FF00000000000084848400848484000000000000FF000000FF - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 000000FF0000000000000000000000000000848484000000000000FF000000FF - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF00000000 - 00000000000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000FF000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000FF000000FF - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000FF000000FF0000000000008484 - 84000000000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000FF00000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000FF000000000000000000008484 - 84000000000000FF000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0008000 - 8000C0C0C0000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000008000 - 8000800080008000800080008000800080008000800080008000800080008000 - 8000800080000000000000000000000000000000000000000000C6C6C600C6C6 - C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C6000000 - 0000C6C6C6000000000000000000000000000000000000000000008484000084 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000000000000084840000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0008000 - 8000C0C0C0000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000C6C6C60000000000000000000000000000000000008484000084 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000000000000084840000000000000000000000000000000000848484008484 - 8400848484000000000000000000000000008484840084848400000000000000 - 000000000000000000000000000000000000000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0008000 - 8000C0C0C00000000000000000000000000000000000C6C6C600C6C6C600C6C6 - C600C6C6C600C6C6C600C6C6C60000FFFF0000FFFF0000FFFF00C6C6C600C6C6 - C600000000000000000000000000000000000000000000000000008484000084 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000000000000084840000000000000000000000000000000000000000000000 - 0000848484000000000000000000000000000000000084848400000000000000 - 000000000000000000000000000000000000000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0008000 - 8000C0C0C00000000000000000000000000000000000C6C6C600C6C6C600C6C6 - C600C6C6C600C6C6C600C6C6C600848484008484840084848400C6C6C600C6C6 - C60000000000C6C6C60000000000000000000000000000000000008484000084 - 8400000000000000000000000000000000000000000000000000000000000000 - 000000000000008484000000000000000000000000000000000000FF00000000 - 000084848400000000000000000000FF00000000000084848400848484008484 - 840084848400848484008484840084848400000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0008000 - 8000C0C0C0000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000C6C6C600C6C6C600000000000000000000000000008484000084 - 8400008484000084840000848400008484000084840000848400008484000084 - 840000848400008484000000000000000000000000000000000000FF00000000 - 0000848484000000000000FF000000FF00000000000000000000000000000000 - 000000000000000000000000000084848400000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0008000 - 8000C0C0C00000000000000000000000000000000000C6C6C600C6C6C600C6C6 - C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C6000000 - 0000C6C6C60000000000C6C6C600000000000000000000000000008484000084 - 8400000000000000000000000000000000000000000000000000000000000000 - 000000848400008484000000000000000000000000000000000000FF00000000 - 00000000000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 000000FF000000FF00000000000084848400000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0008000 - 8000C0C0C0000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000C6C6 - C60000000000C6C6C60000000000000000000000000000000000008484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000008484000000000000000000000000000000000000FF00000000 - 000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 000000FF000000FF00000000000084848400000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0008000 - 8000C0C0C000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 - 0000C6C6C60000000000C6C6C600000000000000000000000000008484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000008484000000000000000000000000000000000000FF00000000 - 00000000000000FF000000FF000000FF000000FF000000FF000000FF000000FF - 000000FF000000FF00000000000084848400000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000C0C0C0008000 - 8000C0C0C0000000000000000000000000000000000000000000000000000000 - 0000FFFFFF000000000000000000000000000000000000000000FFFFFF000000 - 0000000000000000000000000000000000000000000000000000008484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000008484000000000000000000000000000000000000FF00000000 - 0000848484000000000000FF000000FF00000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00000000000000000000000000000000000000000000000000008484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000008484000000000000000000000000000000000000FF00000000 - 000084848400000000000000000000FF00000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000008000 - 800080008000800080008000800080008000800080008000800000000000C0C0 - C000000000000000000000000000000000000000000000000000000000000000 - 000000000000FFFFFF000000000000000000000000000000000000000000FFFF - FF00000000000000000000000000000000000000000000000000008484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000C0C0 - C000C0C0C00080008000C0C0C000C0C0C000C0C0C000C0C0C000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF000000000000000000000000000000000000000000008484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000424D3E000000000000003E000000 - 2800000040000000500000000100010000000000800200000000000000000000 - 000000000000000000000000FFFFFF00FFFFFFFF80010000FFFFFFFF00000000 - FF3FF00F00000000FF3FF00F00000000FF3FF9FF00000000FF3FFC7F00000000 - FF3FFE3F00000000FF3FFF1F00000000FF3FFF9F00000000FB3FFFCF00000000 - F93FF3CF00000000FC3FF1CF00000000FE3FF81F00000000FF3FFC3F00000000 - FFFFFFFF00000000FFFFFFFF80010000FFFFFFFDF01FFFFFFFFFFFF8E00FEDB7 - 6006FFF1C007EDB77FFEFFE3C00380017FFEFFC7C001EDB77FFEE08FC011EDB7 - 6006C01FC01980017FFE803FC01FEDB77FFE001FC01FEDB77FFE001FC01F8001 - 6006001FC01FEDB77FFE001FE01FEDB77FFE001FF01F80010000803FF01FEDB7 - FFFFC07FFC3FEDB7FFFFE0FFFC7FFFFFFFFF001CF9FFC003C0030018F0FFDFFB - C0030011E07FDFFBC0030003C03FD00BC0030007801FDFFBC0030007800FDFFB - C00300070007D00BC00300078003DFFBC0030007C001DFFBC003000FE000D00B - C003001FC000DFFBC007001FC001DFFBC00F001F0003D00BC01F003F0007DFFB - C03F007F810FDFFBFFFF00FFFF9FC003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFCFFFF3FFCE3E5B7F8FFFF1FFC61D9B7F000000F0021DDB7 - E00000070001E1B7C00000030001FDB7800000010001DDB7C00000030001E3B7 - E00180078001FFB7F1FFFF8FFE21FFB7F9FFFF9FFE71FFB7FFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC003FFFFFFFFFFFFC003C007C001FFFF - C00380038031FFFFC00300018031C73FC00300018031863FC003000180018400 - C003000080018000C003000080018000C00380008FF18000C003C0008FF18000 - C003E0018FF18001C003E0078FF1847FC007F0078FF18E7FC00FF0038FF5FFFF - C01FF8038001FFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000 - 000000000000} - end - object PrintDialog: TPrintDialog - Left = 80 - Top = 116 - end - object PrinterSetupDialog: TPrinterSetupDialog - Left = 80 - Top = 180 - end -end diff --git a/CORE/Source/Plugins/Htmlviewer/source/BegaPreview.pas b/CORE/Source/Plugins/Htmlviewer/source/BegaPreview.pas deleted file mode 100644 index 78cab1803..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/BegaPreview.pas +++ /dev/null @@ -1,1143 +0,0 @@ -{------------------------------------------------------------------------------- -Copyright (C) 2006-2014 by Bernd Gabriel. - -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. --------------------------------------------------------------------------------} - -{$include htmlcons.inc} - -unit BegaPreview; - -interface -{$ifndef NoFlatScrollbars} -{$ifndef NoMetaFile} - -uses - Classes, SysUtils, -{$ifdef LCL} - LclIntf, LclType, PrintersDlgs, -{$else} - Windows, Messages, vcl.ImgList, vcl.ToolWin, -{$endif} - vcl.Graphics, vcl.Controls, vcl.Forms, Math, - vcl.StdCtrls, vcl.ExtCtrls, vcl.Buttons, vcl.Printers, vcl.samples.Spin, vcl.ComCtrls, - vcl.Dialogs, - // shared units - MetaFilePrinter, - // own units - BegaMetaFilePrinter, - BegaPreviewPanel, - BegaZoom, BegaScrollBox, System.ImageList; - -const - crZoom = 40; - crHandDrag = 41; - ZOOMFACTOR = 1.11111111111111111111; - - -//- BG ----------------------------------------------------------- 22.12.2006 -- -// use actions and you get all what you want! visible and enabled and event! -type - TBegaPreviewOption = ( - poPrinterSetupEnabled, - poPrintEnabled, - poAllOnOneEnabled, - poSaveFileEnabled, - poSendMailEnabled, - poOpenInExcelEnabled, - poEditReportPropertiesEnabled, - poContentZoomVisible); - TBegaPreviewOptions = set of TBegaPreviewOption; -const - CBegaPreviewOptionsDefault = [ - poPrinterSetupEnabled, - poPrintEnabled, - poAllOnOneEnabled, - poSaveFileEnabled, - poSendMailEnabled, - poContentZoomVisible]; - -type - TBegaEditEvent = procedure(Sender: TObject; var Edited: Boolean) of Object; - TBegaAllOnOneEvent = procedure(Sender: TObject; const AllOnOne: Boolean) of Object; - TBegaGetPageEvent = function(Sender: TObject; PageNo: Integer): String of object; - TBegaMetaFileGetSizeEvent = function(Sender: TObject; MFPrinter: TBegaMetaFilePrinter; out Width, Height: Integer): Boolean of object; - TBegaMetaFilePrinterEvent = procedure(Sender: TObject; MFPrinter: TBegaMetaFilePrinter; var Done: Boolean) of object; - TBegaMetaFilePrintPagesEvent = procedure(Sender: TObject; MFPrinter: TBegaMetaFilePrinter; FirstPage, LastPage, Copies: Integer) of object; - TBegaMetaFileSetupEvent = procedure(Sender: TObject; out Changed: Boolean) of object; - - TBegaCustomPreviewFrame = class(TFrame) - AllOnOne: TToolButton; - cboxPage: TComboBox; - ContentFitHeight: TToolButton; - ContentFitWidth: TToolButton; - ContentZoomBox: TComboBox; - ContentZoomLabel: TPanel; - CurrentPageLabel: TPanel; - FirstPage: TToolButton; - FitHeight: TToolButton; - FitWidth: TToolButton; - Grid: TToolButton; - HintLabel: TLabel; - imgList: TImageList; - ContentZoomBoxLabel: TLabel; - Label2: TLabel; - LastPage: TToolButton; - NextPage: TToolButton; - OpenInExcel: TToolButton; - Panel1: TPanel; - Panning: TToolButton; - PreviewZoomLabel: TPanel; - PrevPage: TToolButton; - Print: TToolButton; - PrintDialog: TPrintDialog; - PrinterSetup: TToolButton; - PrinterSetupDialog: TPrinterSetupDialog; - SaveFile: TToolButton; - SendMail: TToolButton; - StatBarPanel: TPanel; - ToolBar: TToolBar; - ContentZoomSeparator: TToolButton; - ToolButton10: TToolButton; - ToolButton11: TToolButton; - ToolButton14: TToolButton; - ToolButton2: TToolButton; - ToolButton9: TToolButton; - UnitsBox: TComboBox; - ZoomBox: TComboBox; - Zooming: TToolButton; - ReportProperties: TToolButton; - PagesPerRow: TSpinEdit; - Label3: TLabel; - Label4: TLabel; - RowsPerPreview: TSpinEdit; - PreviewBox: TBegaZoomBox; - PreviewPanel: TBegaMetafilePreviewPanel; - procedure AllOnOneClick(Sender: TObject); - procedure ContentFitHeightClick(Sender: TObject); - procedure ContentFitWidthClick(Sender: TObject); - procedure ContentZoomBoxChange(Sender: TObject); - procedure FirstPageClick(Sender: TObject); - procedure FitHeightClick(Sender: TObject); - procedure FitWidthClick(Sender: TObject); - procedure GridClick(Sender: TObject); - procedure LastPageClick(Sender: TObject); - procedure NextPageClick(Sender: TObject); - procedure OpenInExcelClick(Sender: TObject); - procedure PageChange(Sender: TObject); - procedure PagesPerRowChange(Sender: TObject); - procedure PanningClick(Sender: TObject); - procedure PreviewBoxResize(Sender: TObject); - procedure PreviewPanelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); - procedure PreviewPanelMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); - procedure PreviewPanelMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); - procedure PreviewPanelUpdatePreview(Sender: TBegaCustomPreviewPanel; var Width, Height: Integer); - procedure PrevPageClick(Sender: TObject); - procedure PrintClick(Sender: TObject); - procedure PrinterSetupClick(Sender: TObject); - procedure ReportPropertiesClick(Sender: TObject); - procedure RowsPerPreviewChange(Sender: TObject); - procedure SaveFileClick(Sender: TObject); - procedure SendMailClick(Sender: TObject); - procedure UnitsBoxChange(Sender: TObject); - procedure ZoomBoxChange(Sender: TObject); - procedure ZoomingClick(Sender: TObject); - procedure PreviewPanelPaintPage(Sender: TBegaCellPreviewPanel; Canvas: TCanvas; PageIndex: Integer); - private - FMFPrinter: TBegaMetaFilePrinter; - FOnAllOnOne: TBegaAllOnOneEvent; - FOnCreatePages: TBegaMetaFilePrinterEvent; - FOnEditReportProperties: TBegaEditEvent; - FOnGetContentSize: TBegaMetaFileGetSizeEvent; - FOnGetPageTitle: TBegaGetPageEvent; - FOnOpenInExcel: TNotifyEvent; - FOnPrinterSetup: TBegaMetaFileSetupEvent; - FOnPrintPages: TBegaMetaFilePrintPagesEvent; - FOnSaveFile: TNotifyEvent; - FOnSendMail: TNotifyEvent; - FOptions: TBegaPreviewOptions; - FZoom: double; - Moving: Boolean; - function getContentSize(out ContentSize: TBegaSize): Boolean; - function getLastAvailablePage: Integer; - function getPage(Index: Integer): TMetafile; - function getPageCount: Integer; - function getVisiblePageCount: Integer; - function PixelsPerInch: Integer; - procedure printPages(FirstPage, LastPage, Copies: Integer); - procedure setCurrentPage(Val: integer); - procedure setOptions(const Value: TBegaPreviewOptions); - procedure setContentZoomMode(Zoom: TBegaZoomMode); - procedure setPreviewZoomMode(Zoom: TBegaZoomMode); - property LastAvailablePage: Integer read getLastAvailablePage; // due to visible page count - property VisiblePageCount: Integer read getVisiblePageCount; - property Zoom: Double read FZoom write FZoom; - function getContentZoomMode: TBegaZoomMode; - function getPreviewZoomMode: TBegaZoomMode; - function getCurrentPage: Integer; - protected - procedure Loaded; override; - // - function buttonEnabled(Button: TBegaPreviewOption): Boolean; virtual; - // doGetSize() calculates size of all pages, which enables content zoom. - function canGetContentSize: Boolean; virtual; - procedure doGetContentSize(var Done: Boolean; out Width, Height: Integer); virtual; - // doCreatePageMenu() populates MFPrinter with pages - procedure doCreatePageMenu(var Done: Boolean); virtual; - // doCreatePages() populates MFPrinter with pages - procedure doCreatePages(var Done: Boolean); virtual; - // doPrintPages() prints pages of MFPrinter or do you prefer printing elsehow? - procedure doPrintPages(var Done: Boolean); virtual; - // doPrinterSetup(): override or use OnPrinterSetup to reduce number of printer setup dialogs: - procedure doPrinterSetup(var Done, Changed: Boolean); virtual; - // - procedure doAllOnOne(var Done: Boolean); virtual; - // - procedure doOpenInExcel(var Done: Boolean); virtual; - // - procedure updateBox; - procedure updateContentZoom; - procedure updatePage; - procedure updatePageMenu; - property CurrentPage: Integer read getCurrentPage write SetCurrentPage; // 1..n - property MFPrinter: TBegaMetaFilePrinter read FMFPrinter; - property OnAllOnOne: TBegaAllOnOneEvent read FOnAllOnOne write FOnAllOnOne; - property OnCreatePages: TBegaMetaFilePrinterEvent read FOnCreatePages write FOnCreatePages; - property OnEditReportProperties: TBegaEditEvent read FOnEditReportProperties write FOnEditReportProperties; - property OnGetContentSize: TBegaMetaFileGetSizeEvent read FOnGetContentSize write FOnGetContentSize; - property OnGetPageTitle: TBegaGetPageEvent read FOnGetPageTitle write FOnGetPageTitle; - property OnOpenInExcel: TNotifyEvent read FOnOpenInExcel write FOnOpenInExcel; - property OnPrinterSetup: TBegaMetaFileSetupEvent read FOnPrinterSetup write FOnPrinterSetup; - property OnPrintPages: TBegaMetaFilePrintPagesEvent read FOnPrintPages write FOnPrintPages; - property OnSaveFile: TNotifyEvent read FOnSaveFile write FOnSaveFile; - property OnSendMail: TNotifyEvent read FOnSendMail write FOnSendMail; - property PageCount: Integer read getPageCount; - property Pages[Index: Integer]: TMetafile read getPage; - property PreviewOptions: TBegaPreviewOptions read FOptions write setOptions default CBegaPreviewOptionsDefault; - property ContentZoomMode: TBegaZoomMode read getContentZoomMode write setContentZoomMode stored false; // is stored in ContentZoomBox - property PreviewZoomMode: TBegaZoomMode read getPreviewZoomMode write setPreviewZoomMode stored false; // is stored in ZoomBox - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - procedure createPages; - procedure updateActions; - end; - - //BG, 20.04.2006: split: TBegaPreviewFrame - TBegaPreviewFrame = class(TBegaCustomPreviewFrame) - published - property ContentZoomMode; - property OnCreatePages; - property OnEditReportProperties; - property OnGetContentSize; - property OnGetPageTitle; - property OnOpenInExcel; - property OnPrinterSetup; - property OnPrintPages; - property OnSaveFile; - property OnSendMail; - property PreviewOptions; - property PreviewZoomMode; - end; - -procedure loadPreviewCursors; - -{$endif NoMetaFile} -{$endif NoFlatScrollbars} -implementation -{$ifndef NoFlatScrollbars} -{$ifndef NoMetaFile} - -{$ifdef UseVCLStyles} -uses - System.Types, - System.UITypes, - Vcl.Themes; -{$endif} - -{$ifdef LCL} - {$R *.lfm} -{$else} - {$R *.dfm} - {$R ZoomAndHandCursor.res} -{$endif} - -//- BG ----------------------------------------------------------- 04.11.2006 -- -var PreviewCursorsLoaded: Boolean; -procedure loadPreviewCursors; -begin - if not PreviewCursorsLoaded then - begin - PreviewCursorsLoaded := True; -{$ifndef LCL} - Screen.Cursors[crZoom] := LoadCursor(hInstance, 'BEGA_ZOOM_CURSOR'); - Screen.Cursors[crHandDrag] := LoadCursor(hInstance, 'BEGA_HAND_CURSOR'); -{$endif} - end; -end; - -//- BG ----------------------------------------------------------- 04.11.2006 -- -function zoom2ZoomMode(Zoom: Double): TBegaZoomMode; -begin - case round(Zoom * 100) of - 25: Result := zm25; - 50: Result := zm50; - 75: Result := zm75; - 100: Result := zm100; - 125: Result := zm125; - 150: Result := zm150; - 200: Result := zm200; - 300: Result := zm300; - 400: Result := zm400; - else - Result := zmCustom; - end; -end; - -//- BG ----------------------------------------------------------- 25.05.2006 -- -function TBegaCustomPreviewFrame.buttonEnabled( - Button: TBegaPreviewOption): Boolean; -begin - Result := Button in PreviewOptions; -end; - -//- BG ----------------------------------------------------------- 20.04.2006 -- -function TBegaCustomPreviewFrame.canGetContentSize: Boolean; -begin - Result := assigned(FOnGetContentSize); -end; - -//- BG ----------------------------------------------------------- 15.03.2006 -- -procedure TBegaCustomPreviewFrame.ContentFitHeightClick(Sender: TObject); -begin - ContentZoomBox.ItemIndex := 1; - updateContentZoom; - createPages; -end; - -//- BG ----------------------------------------------------------- 15.03.2006 -- -procedure TBegaCustomPreviewFrame.ContentFitWidthClick(Sender: TObject); -begin - ContentZoomBox.ItemIndex := 2; - updateContentZoom; - createPages; -end; - -//- BG ----------------------------------------------------------- 14.03.2006 -- -procedure TBegaCustomPreviewFrame.ContentZoomBoxChange(Sender: TObject); -begin - updateContentZoom; - createPages; -end; - -//- BG ----------------------------------------------------------- 21.02.2006 -- -constructor TBegaCustomPreviewFrame.Create(AOwner: TComponent); -begin - inherited; - FOptions := CBegaPreviewOptionsDefault; - FZoom := 1.0; - ZoomBox.ItemIndex := 0; - ContentZoomBox.ItemIndex := 6; - UnitsBox.ItemIndex := 0; - loadPreviewCursors; -// ZoomingClick(Zooming); - FMFPrinter := TBegaMetaFilePrinter.Create(Self); - updateActions; -end; - -//- BG ----------------------------------------------------------- 21.02.2006 -- -procedure TBegaCustomPreviewFrame.createPages; -var - Done: Boolean; -begin - Done := False; - MFPrinter.updatePrinterCaps; - MFPrinter.clear; - doCreatePages(Done); - if Done then - begin - updateBox; - updatePageMenu; - CurrentPage := 1; - end; - updatePage; - updateActions; -end; - -//- BG ----------------------------------------------------------- 06.03.2006 -- -destructor TBegaCustomPreviewFrame.Destroy; -begin - MFPrinter.free; - inherited; -end; - -//- BG ----------------------------------------------------------- 22.12.2006 -- -procedure TBegaCustomPreviewFrame.doAllOnOne(var Done: Boolean); -begin - if assigned(FOnAllOnOne) then - FOnAllOnOne(self, AllOnOne.Down); - // there is no default 'all' action -end; - -//- BG ----------------------------------------------------------- 26.04.2006 -- -procedure TBegaCustomPreviewFrame.doCreatePageMenu(var Done: Boolean); -var - Index: Integer; -begin - cboxPage.Clear; - if assigned(FOnGetPageTitle) then - for Index := 1 to PageCount do - cboxPage.Items.Add(FOnGetPageTitle(self, Index)) - else - for Index := 1 to PageCount do - cboxPage.Items.Add(intToStr(Index)); - if PageCount > 0 then - cboxPage.ItemIndex := 0; -end; - -//- BG ----------------------------------------------------------- 06.03.2006 -- -procedure TBegaCustomPreviewFrame.doCreatePages(var Done: Boolean); -begin - if assigned(FOnCreatePages) then - FOnCreatePages(self, MFPrinter, Done); - // there is no default page generation -end; - -//- BG ----------------------------------------------------------- 14.03.2006 -- -procedure TBegaCustomPreviewFrame.doGetContentSize(var Done: Boolean; out Width, Height: Integer); -begin - if assigned(FOnGetContentSize) then - Done := FOnGetContentSize(self, MFPrinter, Width, Height) - // there is no default content size calculation -end; - -//- BG ----------------------------------------------------------- 22.12.2006 -- -procedure TBegaCustomPreviewFrame.doOpenInExcel(var Done: Boolean); -begin - if assigned(FOnOpenInExcel) then - begin - Done := True; - FOnOpenInExcel(self); - end; - // there is no default opening in excel -end; - -//- BG ----------------------------------------------------------- 15.03.2006 -- -procedure TBegaCustomPreviewFrame.doPrinterSetup(var Done, Changed: Boolean); -begin - if assigned(FOnPrinterSetup) then - begin - Done := True; - FOnPrinterSetup(self, Changed); - end; - if not Done then - begin - Done := True; - Changed := PrinterSetupDialog.Execute; - end; -end; - -//- BG ----------------------------------------------------------- 06.03.2006 -- -procedure TBegaCustomPreviewFrame.doPrintPages(var Done: Boolean); -var - FirstPage, LastPage, Copies: Integer; -begin - if not Done then - begin - //BG, 10.04.2006: print metafiles by myself: - Done := True; - PrintDialog.MinPage := 1; - PrintDialog.MaxPage := PageCount; - PrintDialog.Options := [poPageNums, poWarning]; - if PrintDialog.Execute then - begin - FirstPage := 1; - LastPage := 0; - case PrintDialog.PrintRange of - prAllPages: - begin - FirstPage := PrintDialog.MinPage; - LastPage := PrintDialog.MaxPage; - end; - prPageNums: - begin - FirstPage := PrintDialog.FromPage; - LastPage := PrintDialog.ToPage; - end; - end; - //BG, 14.10.2010: if destination printer does the copying, the we print 1 copy only and let the printer sweat. -{$ifdef LCL} - if Printer.CanRenderCopies then -{$else LCL} - if pcCopies in Printer.Capabilities then -{$endif LCL} - Copies := 1 - else - Copies := PrintDialog.Copies; - if assigned(FOnPrintPages) then - FOnPrintPages(self, MFPrinter, FirstPage, LastPage, Copies) - else - printPages(FirstPage, LastPage, Copies); - end; - end; -end; - -//- BG ----------------------------------------------------------- 06.03.2006 -- -procedure TBegaCustomPreviewFrame.FirstPageClick(Sender: TObject); -begin - CurrentPage := 1; -end; - -//------------------------------------------------------------------------------ -procedure TBegaCustomPreviewFrame.FitHeightClick(Sender: TObject); -begin - ZoomBox.ItemIndex := 1; - ZoomBoxChange(nil); -end; - -//------------------------------------------------------------------------------ -procedure TBegaCustomPreviewFrame.FitWidthClick(Sender: TObject); -begin - ZoomBox.ItemIndex := 2; - ZoomBoxChange(nil); -end; - -//- BG ----------------------------------------------------------- 20.04.2006 -- -function TBegaCustomPreviewFrame.getContentSize( - out ContentSize: TBegaSize): Boolean; -begin - Result := False; - ContentSize.Width := 0; - ContentSize.Height := 0; - doGetContentSize(Result, ContentSize.Width, ContentSize.Height); -end; - -//- BG ----------------------------------------------------------- 03.11.2006 -- -function TBegaCustomPreviewFrame.getContentZoomMode: TBegaZoomMode; -var - Index: Integer; -begin - Index := ContentZoomBox.ItemIndex; - if Index >= 0 then - Result := TBegaZoomMode(Index) - else - Result := zmFitToPage; -end; - -//- BG ----------------------------------------------------------- 08.11.2006 -- -function TBegaCustomPreviewFrame.getCurrentPage: Integer; -begin - Result := PreviewPanel.FirstPage + 1; -end; - -//- BG ----------------------------------------------------------- 28.04.2006 -- -function TBegaCustomPreviewFrame.getLastAvailablePage: Integer; -begin - Result := PageCount - VisiblePageCount + 1; -end; - -//- BG ----------------------------------------------------------- 27.04.2006 -- -function TBegaCustomPreviewFrame.getPage(Index: Integer): TMetafile; -begin - Result := MFPrinter.MetaFiles[Index]; -end; - -//- BG ----------------------------------------------------------- 26.04.2006 -- -function TBegaCustomPreviewFrame.getPageCount: Integer; -begin - Result := MFPrinter.LastAvailablePage; -end; - -//- BG ----------------------------------------------------------- 03.11.2006 -- -function TBegaCustomPreviewFrame.getPreviewZoomMode: TBegaZoomMode; -var - Index: Integer; -begin - Index := ZoomBox.ItemIndex; - if Index >= 0 then - Result := TBegaZoomMode(Index) - else - Result := zmFitToPage; -end; - -//- BG ----------------------------------------------------------- 08.04.2006 -- -function TBegaCustomPreviewFrame.getVisiblePageCount: Integer; -begin - Result := PagesPerRow.Value; - if RowsPerPreview.Value > 1 then - Result := PagesPerRow.Value * RowsPerPreview.Value; -end; - -//------------------------------------------------------------------------------ -procedure TBegaCustomPreviewFrame.GridClick(Sender: TObject); -begin - updatePage; -end; - -//- BG ----------------------------------------------------------- 06.03.2006 -- -procedure TBegaCustomPreviewFrame.LastPageClick(Sender: TObject); -begin - CurrentPage := LastAvailablePage; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -procedure TBegaCustomPreviewFrame.Loaded; -begin - inherited; - PreviewPanel.MFPrinter := MFPrinter; -end; - -//- BG ----------------------------------------------------------- 06.03.2006 -- -procedure TBegaCustomPreviewFrame.NextPageClick(Sender: TObject); -begin - CurrentPage := CurrentPage + 1; -end; - -//- BG ----------------------------------------------------------- 06.03.2006 -- -procedure TBegaCustomPreviewFrame.PageChange(Sender: TObject); -var - Index: Integer; -begin - Index := cboxPage.ItemIndex; - if Index >= 0 then - CurrentPage := Index + 1; -end; - -//- BG ----------------------------------------------------------- 06.11.2006 -- -procedure TBegaCustomPreviewFrame.PagesPerRowChange(Sender: TObject); -begin - PreviewPanel.ColumnCount := PagesPerRow.Value; - updateBox; -end; - -//------------------------------------------------------------------------------ -procedure TBegaCustomPreviewFrame.PanningClick(Sender: TObject); -begin - if Panning.Down then - PreviewPanel.Cursor := crHandDrag - else - PreviewPanel.Cursor := crDefault; -end; - -//------------------------------------------------------------------------------ -function TBegaCustomPreviewFrame.PixelsPerInch: Integer; -var - Form: TCustomForm; -begin - if csDesigning in ComponentState then - begin - Result := Screen.PixelsPerInch; - exit; - end; - Form := GetParentForm(self); - if Form is TForm then - Result := TForm(Form).PixelsPerInch -{$ifndef LCL} - else if Form is TCustomActiveForm then - Result := TCustomActiveForm(Form).PixelsPerInch -{$endif LCL} - else - Result := Screen.PixelsPerInch; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -procedure TBegaCustomPreviewFrame.PreviewBoxResize(Sender: TObject); -begin - updateBox; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -procedure TBegaCustomPreviewFrame.PreviewPanelUpdatePreview( - Sender: TBegaCustomPreviewPanel; var Width, Height: Integer); -begin - Width := max(Width, PreviewBox.ClientWidth); - Height := max(Height, PreviewBox.ClientHeight); - - {Make sure the scroll bars are hidden if not needed} - if (Width <= PreviewBox.ClientWidth) and (Height <= PreviewBox.ClientHeight) then - begin - PreviewBox.HorzScrollBar.Visible := False; - PreviewBox.VertScrollBar.Visible := False; - end - else - begin - PreviewBox.HorzScrollBar.Visible := True; - PreviewBox.VertScrollBar.Visible := True; - end; - -end; - -//- BG ----------------------------------------------------------- 06.03.2006 -- -procedure TBegaCustomPreviewFrame.PrevPageClick(Sender: TObject); -begin - CurrentPage := CurrentPage - 1; -end; - -//- BG ----------------------------------------------------------- 06.03.2006 -- -procedure TBegaCustomPreviewFrame.PrintClick(Sender: TObject); -var - Done: Boolean; -begin - Done := False; - doPrintPages(Done); -end; - -//- BG ----------------------------------------------------------- 15.03.2006 -- -procedure TBegaCustomPreviewFrame.PrinterSetupClick(Sender: TObject); -var - Done, Changed: Boolean; -begin - Done := False; - Changed := False; - doPrinterSetup(Done, Changed); - if Changed then - begin - MFPrinter.updatePrinterCaps; - updateContentZoom; - createPages; - end; -end; - -//- BG ----------------------------------------------------------- 27.05.2006 -- -procedure TBegaCustomPreviewFrame.printPages(FirstPage, LastPage, Copies: Integer); -var - OldCursor: TCursor; -begin - OldCursor := Screen.Cursor; - Screen.Cursor := crHourGlass; - try - MFPrinter.printDoc(Printer, FirstPage, LastPage, Copies); - finally - Screen.Cursor := OldCursor; - end; -end; - -//- BG ----------------------------------------------------------- 27.08.2006 -- -procedure TBegaCustomPreviewFrame.ReportPropertiesClick(Sender: TObject); -var - Edited: Boolean; -begin - Edited := False; - if assigned(FOnEditReportProperties) then - FOnEditReportProperties(self, Edited); - if Edited then - updatePage; -end; - -//- BG ----------------------------------------------------------- 06.04.2006 -- -procedure TBegaCustomPreviewFrame.SaveFileClick(Sender: TObject); -begin - if assigned(FOnSaveFile) then - FOnSaveFile(self); -end; - -//- BG ----------------------------------------------------------- 06.04.2006 -- -procedure TBegaCustomPreviewFrame.SendMailClick(Sender: TObject); -begin - if assigned(FOnSendMail) then - FOnSendMail(self); -end; - -//- BG ----------------------------------------------------------- 06.03.2006 -- -procedure TBegaCustomPreviewFrame.SetCurrentPage(Val: integer); -begin - if CurrentPage <> Val then - begin - cboxPage.ItemIndex := Val - 1; - PreviewPanel.FirstPage := Val - 1; - updateActions; - end; -end; - -//- BG ----------------------------------------------------------- 03.11.2006 -- -procedure TBegaCustomPreviewFrame.setContentZoomMode(Zoom: TBegaZoomMode); -begin - ContentZoomBox.ItemIndex := ord(Zoom); - ContentZoomBoxChange(ContentZoomBox); -end; - -//- BG ----------------------------------------------------------- 06.04.2006 -- -procedure TBegaCustomPreviewFrame.setOptions(const Value: TBegaPreviewOptions); -begin - if FOptions <> Value then - begin - FOptions := Value; - updateActions; - end; -end; - -//- BG ----------------------------------------------------------- 03.11.2006 -- -procedure TBegaCustomPreviewFrame.setPreviewZoomMode(Zoom: TBegaZoomMode); -begin - ZoomBox.ItemIndex := ord(Zoom); - ZoomBoxChange(ZoomBox); -end; - -//------------------------------------------------------------------------------ -procedure TBegaCustomPreviewFrame.UnitsBoxChange(Sender: TObject); -begin - if Grid.down then - updatePage; -end; - -//- BG ----------------------------------------------------------- 06.03.2006 -- -procedure TBegaCustomPreviewFrame.updateActions; -var - LastDocPage: Integer; - LastAvlPage: Integer; - LastVisPage: Integer; - canZoomContent: Boolean; -begin - canZoomContent := poContentZoomVisible in FOptions; - if canZoomContent then - begin - ContentZoomLabel.Caption := Format('Content zoom %1.0n', [MFPrinter.PrintScale * 100]) + '%'; - end - else - ContentZoomLabel.Caption := ''; - - PreviewZoomLabel.Caption := Format('Preview zoom %1.0n', [Zoom * 100]) + '%'; - LastDocPage := PageCount; - LastAvlPage := LastAvailablePage; - LastVisPage := min(CurrentPage + VisiblePageCount - 1, LastDocPage); - FirstPage.Enabled := CurrentPage > 1; - PrevPage.Enabled := FirstPage.Enabled; - if CurrentPage <= 0 then - CurrentPageLabel.Caption := 'No pages' - else if LastVisPage = CurrentPage then - CurrentPageLabel.Caption := Format('Page %d of %d', [CurrentPage, LastDocPage]) - else - CurrentPageLabel.Caption := Format('Pages %d..%d of %d', [CurrentPage, LastVisPage, LastDocPage]); - NextPage.Enabled := CurrentPage < LastAvlPage; - LastPage.Enabled := NextPage.Enabled; - cboxPage.Enabled := LastAvlPage > 1; -// if CurrentPage <= 0 then -// cboxPage.ItemIndex := 0 -// else -// cboxPage.ItemIndex := CurrentPage - 1; - - SendMail.Visible := assigned(FOnSendMail); - SendMail.Enabled := buttonEnabled(poSendMailEnabled); - SaveFile.Visible := assigned(FOnSaveFile); - SaveFile.Enabled := buttonEnabled(poSaveFileEnabled); - OpenInExcel.Visible := assigned(FOnOpenInExcel); - OpenInExcel.Enabled := buttonEnabled(poOpenInExcelEnabled); - AllOnOne.Visible := assigned(FOnAllOnOne); - AllOnOne.Enabled := buttonEnabled(poAllOnOneEnabled); - ReportProperties.Visible := assigned(FOnEditReportProperties); - ReportProperties.Enabled := buttonEnabled(poEditReportPropertiesEnabled); - PrinterSetup.Enabled := buttonEnabled(poPrinterSetupEnabled); - Print.Enabled := buttonEnabled(poPrintEnabled); - - ContentZoomSeparator.Visible := canZoomContent; - ContentZoomBoxLabel.Visible := canZoomContent; - ContentZoomBox.Visible := canZoomContent; - ContentFitHeight.Visible := canZoomContent; - ContentFitWidth.Visible := canZoomContent; - ContentFitHeight.Enabled := canGetContentSize; - ContentFitWidth.Enabled := canGetContentSize; - ContentFitHeight.Down := ContentZoomBox.ItemIndex = 1; - ContentFitWidth.Down := ContentZoomBox.ItemIndex = 2; - - FitHeight.Down := ZoomBox.ItemIndex = 1; - FitWidth.Down := ZoomBox.ItemIndex = 2; - - Panning.Enabled := PreviewBox.VertScrollBar.Visible or PreviewBox.HorzScrollBar.Visible or (PreviewPanel.Left <> 0) or (PreviewPanel.Top <> 0); - if not Panning.Enabled then - begin - Panning.Down := False; - PanningClick(Panning); - end; -end; - -//- BG ----------------------------------------------------------- 06.11.2006 -- -procedure TBegaCustomPreviewFrame.updateBox; -var - z: double; - WidthInInch: double; - HeightInInch: double; - - function calcZoomFactor( - PreviewPixelCount: Integer; - PreviewBorderPixelCount: Integer; - PreviewPixelsBetweenPages: Integer; - PreviewPixelsPerInch: Integer; - PageCount: Integer; - PaperSizeInInch: double): double; - begin - Result := (PreviewPixelCount - 2 * PreviewBorderPixelCount - (max(0, PageCount - 1)) * PreviewPixelsBetweenPages) - / (PreviewPixelsPerInch * PaperSizeInInch * PageCount); - end; - - function calcZoomFactorX(): double; - begin - Result := calcZoomFactor( - PreviewBox.ClientWidth, - PreviewPanel.BorderWidth, - PreviewPanel.InnerWidth, - PixelsPerInch, - PreviewPanel.ColumnCount, - WidthInInch); - end; - - function calcZoomFactorY(): double; - begin - Result := calcZoomFactor( - PreviewBox.ClientHeight, - PreviewPanel.BorderWidth, - PreviewPanel.InnerWidth, - PixelsPerInch, - PreviewPanel.RowCount, - HeightInInch); - end; - -begin - if (MFPrinter.PaperWidth <> 0) and (MFPrinter.PixelsPerInchX <> 0) then - WidthInInch := MFPrinter.PaperWidth / MFPrinter.PixelsPerInchX - else - WidthInInch := 8.5; - - if (MFPrinter.PaperHeight <> 0) and (MFPrinter.PixelsPerInchY <> 0) then - HeightInInch := MFPrinter.PaperHeight / MFPrinter.PixelsPerInchY - else - HeightInInch := 11; - - if ZoomBox.ItemIndex = -1 then - ZoomBox.ItemIndex := 0; - case ZoomBox.ItemIndex of - 0: z := min(calcZoomFactorX, calcZoomFactorY); - 1: z := calcZoomFactorY; - 2: z := calcZoomFactorX; - 3: z := 0.25; - 4: z := 0.50; - 5: z := 0.75; - 6: z := 1.00; - 7: z := 1.25; - 8: z := 1.50; - 9: z := 2.00; - 10: z := 3.00; - 11: z := 4.00; - else - z := Zoom; - end; - Zoom := z; - PreviewPanel.MFPrinter := MFPrinter; - PreviewPanel.updatePreview( - trunc(PixelsPerInch * z * WidthInInch), - trunc(PixelsPerInch * z * HeightInInch)); - updateActions; -end; - -//- BG ----------------------------------------------------------- 15.03.2006 -- -procedure TBegaCustomPreviewFrame.updateContentZoom; -var - z: Double; - PreviewArea: TBegaRect; - ContentSize: TBegaSize; -begin - z := MFPrinter.PrintScale; - case ContentZoomBox.ItemIndex of - 0: // fit to size - begin - PreviewArea := MFPrinter.getPreviewArea(MFPrinter.PrintArea, Screen.PixelsPerInch); - if getContentSize(ContentSize) then - z := min( - PreviewArea.Height / ContentSize.Height, - PreviewArea.Width / ContentSize.Width); - end; - 1: // fit to height - begin - PreviewArea := MFPrinter.getPreviewArea(MFPrinter.PrintArea, Screen.PixelsPerInch); - if getContentSize(ContentSize) then - z := PreviewArea.Height / ContentSize.Height; - end; - 2: // fit to width - begin - PreviewArea := MFPrinter.getPreviewArea(MFPrinter.PrintArea, Screen.PixelsPerInch); - if getContentSize(ContentSize) then - z := PreviewArea.Width / ContentSize.Width; - end; - 3: z := 0.25; - 4: z := 0.50; - 5: z := 0.75; - 6: z := 1.00; - 7: z := 1.25; - 8: z := 1.50; - 9: z := 2.00; - 10: z := 3.00; - 11: z := 4.00; - 12: z := 8.00; - end; - - MFPrinter.PrintScale := z; - updateActions; -end; - -//- BG ----------------------------------------------------------- 21.02.2006 -- -procedure TBegaCustomPreviewFrame.updatePage; -begin - PreviewPanel.invalidate; -end; - -//- BG ----------------------------------------------------------- 26.04.2006 -- -procedure TBegaCustomPreviewFrame.updatePageMenu; -var - Done: Boolean; -begin - Done := False; - doCreatePageMenu(Done); -end; - -//------------------------------------------------------------------------------ -procedure TBegaCustomPreviewFrame.ZoomBoxChange(Sender: TObject); -begin - updateBox; -end; - -//------------------------------------------------------------------------------ -procedure TBegaCustomPreviewFrame.ZoomingClick(Sender: TObject); -begin - if Zooming.Down then - PreviewPanel.Cursor := crZoom - else - PreviewPanel.Cursor := crDefault; -end; - -//- BG ----------------------------------------------------------- 06.11.2006 -- -procedure TBegaCustomPreviewFrame.PreviewPanelMouseDown(Sender: TObject; - Button: TMouseButton; Shift: TShiftState; X, Y: Integer); -var - sx, sy : single; - Pos: TPoint; -begin - if Zooming.Down then - begin - sx := X / PreviewPanel.Width; - sy := Y / PreviewPanel.Height; - - if (ssLeft in Shift) and (Zoom < 100.0) then - Zoom := Zoom * ZOOMFACTOR; - if (ssRight in Shift) and (Zoom > 0.01) then - Zoom := Zoom / ZOOMFACTOR; - ZoomBox.ItemIndex := ord(zoom2ZoomMode(Zoom)); - - updateBox; - - PreviewBox.HorzScrollBar.Position := round(sx * PreviewPanel.Width) - PreviewBox.Width div 2; - PreviewBox.VertScrollBar.Position := round(sy * PreviewPanel.Height) - PreviewBox.Height div 2; - end - else if Panning.Down then - begin - Moving := True; - Pos := TControl(Sender).ClientToParent(Point(X, Y), PreviewBox); - PreviewBox.MouseDown(Button, Shift, Pos.X, Pos.Y); - end; -end; - -//- BG ----------------------------------------------------------- 06.11.2006 -- -procedure TBegaCustomPreviewFrame.PreviewPanelMouseMove(Sender: TObject; - Shift: TShiftState; X, Y: Integer); -var - Pos: TPoint; -begin - if Moving then - begin - Pos := TControl(Sender).ClientToParent(Point(X, Y), PreviewBox); - PreviewBox.MouseMove(Shift, Pos.X, Pos.Y); - PreviewPanel.UpdatePreview; - end; -end; - -//- BG ----------------------------------------------------------- 06.11.2006 -- -procedure TBegaCustomPreviewFrame.PreviewPanelMouseUp(Sender: TObject; - Button: TMouseButton; Shift: TShiftState; X, Y: Integer); -var - Pos: TPoint; -begin - if Moving then - begin - Moving := False; - Pos := TControl(Sender).ClientToParent(Point(X, Y), PreviewBox); - PreviewBox.MouseUp(Button, Shift, Pos.X, Pos.Y); - PreviewPanel.UpdatePreview; - end; -end; - -//-- BG ---------------------------------------------------------- 31.08.2009 -- -procedure TBegaCustomPreviewFrame.PreviewPanelPaintPage(Sender: TBegaCellPreviewPanel; - Canvas: TCanvas; PageIndex: Integer); -var - x, x1: Integer; - y, y1: Integer; - Factor: Double; -begin - if Grid.Down then - begin - SetWindowOrgEx(Canvas.Handle, 0, 0, nil); - Canvas.Pen.Color := clLtGray; - if UnitsBox.ItemIndex = 0 then - Factor := 1.0 - else - Factor := 2.54; - - for x := 1 to Round(MFPrinter.PaperWidth / MFPrinter.PixelsPerInchX * Factor) do - begin - x1 := Round(MFPrinter.PixelsPerInchX * x / Factor); - Canvas.MoveTo(x1, 0); - Canvas.LineTo(x1, MFPrinter.PaperHeight); - end; - - for y := 1 to Round(MFPrinter.PaperHeight / MFPrinter.PixelsPerInchY * Factor) do - begin - y1 := Round(MFPrinter.PixelsPerInchY * y / Factor); - Canvas.MoveTo(0, y1); - Canvas.LineTo(MFPrinter.PaperWidth, y1); - end; - end; -end; - -//- BG ----------------------------------------------------------- 08.11.2006 -- -procedure TBegaCustomPreviewFrame.RowsPerPreviewChange(Sender: TObject); -begin - PreviewPanel.RowCount := RowsPerPreview.Value; - updateBox; -end; - -//- BG ----------------------------------------------------------- 22.12.2006 -- -procedure TBegaCustomPreviewFrame.AllOnOneClick(Sender: TObject); -var - Done: Boolean; -begin - Done := False; - doAllOnOne(done); - if Done then - updatePage; -end; - -//- BG ----------------------------------------------------------- 22.12.2006 -- -procedure TBegaCustomPreviewFrame.OpenInExcelClick(Sender: TObject); -var - Done: Boolean; -begin - Done := False; - doOpenInExcel(done); -end; - -{$endif NoMetaFile} -{$endif NoFlatScrollbars} -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/BegaPreviewForm.dfm b/CORE/Source/Plugins/Htmlviewer/source/BegaPreviewForm.dfm deleted file mode 100644 index 78614e672..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/BegaPreviewForm.dfm +++ /dev/null @@ -1,17 +0,0 @@ -object BegaCustomPrintPreviewForm: TBegaCustomPrintPreviewForm - Left = 431 - Top = 144 - Caption = 'Print preview' - ClientHeight = 741 - ClientWidth = 1008 - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'MS Shell Dlg 2' - Font.Style = [] - OldCreateOrder = False - Position = poOwnerFormCenter - PixelsPerInch = 96 - TextHeight = 13 -end diff --git a/CORE/Source/Plugins/Htmlviewer/source/BegaPreviewForm.lfm b/CORE/Source/Plugins/Htmlviewer/source/BegaPreviewForm.lfm deleted file mode 100644 index 1f3d096a5..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/BegaPreviewForm.lfm +++ /dev/null @@ -1,16 +0,0 @@ -object BegaCustomPrintPreviewForm: TBegaCustomPrintPreviewForm - Left = 363 - Top = 142 - Caption = 'Print preview' - ClientHeight = 602 - ClientWidth = 854 - 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 -end diff --git a/CORE/Source/Plugins/Htmlviewer/source/BegaPreviewForm.pas b/CORE/Source/Plugins/Htmlviewer/source/BegaPreviewForm.pas deleted file mode 100644 index 35cf548e5..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/BegaPreviewForm.pas +++ /dev/null @@ -1,174 +0,0 @@ -{------------------------------------------------------------------------------- -Copyright (C) 2006-2012 by Bernd Gabriel. - -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. --------------------------------------------------------------------------------} - -{$include htmlcons.inc} - -unit BegaPreviewForm; - -interface -{$ifndef NoFlatScrollbars} -{$ifndef NoMetaFile} - -uses - Classes, SysUtils, -{$ifdef LCL} - LclIntf, LclType, PrintersDlgs, -{$else} - Windows, -{$endif} - Variants, vcl.Graphics, vcl.Controls, vcl.Forms, vcl.Dialogs, - // own units - BegaMetaFilePrinter, - BegaPreview; - -type - TBegaCustomPrintPreviewForm = class(TForm) - private - FMargins: TRect; - protected - procedure UpdateActions; override; - public - Preview: TBegaPreviewFrame; - constructor Create(AOwner: TComponent); override; - property PrintMargins: TRect read FMargins write FMargins; // in mm - end; - - TBegaPrintPreviewForm = class(TBegaCustomPrintPreviewForm) - private - FPrintable: IBegaPrintable; - function PreviewGetSize(Sender: TObject; MFPrinter: TBegaMetaFilePrinter; out Width, Height: Integer): Boolean; - procedure PreviewCreatePages(Sender: TObject; MFPrinter: TBegaMetaFilePrinter; var Done: Boolean); - procedure setPrintable(const Value: IBegaPrintable); - public - property PrintableIntf: IBegaPrintable read FPrintable write setPrintable; - end; - - TBegaMetaFilePrintPreviewForm = class(TBegaCustomPrintPreviewForm) - private - FMetafilePrinter: TBegaMetaFilePrinter; - procedure PreviewCreatePages(Sender: TObject; MFPrinter: TBegaMetaFilePrinter; var Done: Boolean); - procedure setMetafilePrinter(const Value: TBegaMetaFilePrinter); - public - property MetafilePrinter: TBegaMetaFilePrinter read FMetafilePrinter write setMetafilePrinter; - end; - -{$endif NoMetaFile} -{$endif NoFlatScrollbars} -implementation -{$ifndef NoFlatScrollbars} -{$ifndef NoMetaFile} - -{$ifdef LCL} - {$R *.lfm} -{$else} - {$R *.dfm} -{$endif} - -{ TBegaPreviewForm } - -//- BG ----------------------------------------------------------- 03.11.2006 -- -constructor TBegaCustomPrintPreviewForm.Create(AOwner: TComponent); -begin - inherited; - Preview := TBegaPreviewFrame.create(Self); - Preview.Parent := self; - Preview.Align := alClient; -end; - -//- BG ----------------------------------------------------------- 03.11.2006 -- -procedure TBegaCustomPrintPreviewForm.UpdateActions; -begin - inherited; - Preview.updateActions; -end; - -{ TBegaPrintPreviewForm } - -//- BG ----------------------------------------------------------- 04.12.2006 -- -procedure TBegaPrintPreviewForm.PreviewCreatePages(Sender: TObject; - MFPrinter: TBegaMetaFilePrinter; var Done: Boolean); -begin - MFPrinter.PrintMargins := PrintMargins; - MFPrinter.preview(FPrintable); - Done := True; -end; - -//- BG ----------------------------------------------------------- 04.12.2006 -- -function TBegaPrintPreviewForm.PreviewGetSize(Sender: TObject; - MFPrinter: TBegaMetaFilePrinter; out Width, Height: Integer): Boolean; -begin - Width := FPrintable.Width; - Height := FPrintable.Height; - Result := True; -end; - -//- BG ----------------------------------------------------------- 05.12.2006 -- -procedure TBegaPrintPreviewForm.setPrintable(const Value: IBegaPrintable); -begin - if FPrintable <> Value then - begin - FPrintable := Value; - if Value = nil then - begin - Preview.OnCreatePages := nil; - Preview.OnGetContentSize := nil; - end - else - begin - Preview.OnCreatePages := PreviewCreatePages; - Preview.OnGetContentSize := PreviewGetSize; - end; - end; -end; - -{ TBegaMetaFilePrintPreviewForm } - -//- BG ----------------------------------------------------------- 22.03.2007 -- -procedure TBegaMetaFilePrintPreviewForm.PreviewCreatePages(Sender: TObject; - MFPrinter: TBegaMetaFilePrinter; var Done: Boolean); -begin - MFPrinter.addPages(FMetafilePrinter, False); - MFPrinter.copySettingsFrom(FMetafilePrinter); - Done := True; -end; - -//- BG ----------------------------------------------------------- 22.03.2007 -- -procedure TBegaMetaFilePrintPreviewForm.setMetafilePrinter( - const Value: TBegaMetaFilePrinter); -begin - if FMetafilePrinter <> Value then - begin - FMetafilePrinter := Value; - if Value = nil then - begin - Preview.OnCreatePages := nil; - end - else - begin - Preview.OnCreatePages := PreviewCreatePages; - end; - end; - Preview.createPages; -end; - -{$endif NoMetaFile} -{$endif NoFlatScrollbars} -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/BegaPreviewPanel.pas b/CORE/Source/Plugins/Htmlviewer/source/BegaPreviewPanel.pas deleted file mode 100644 index 38dc8e37a..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/BegaPreviewPanel.pas +++ /dev/null @@ -1,643 +0,0 @@ -{------------------------------------------------------------------------------- -Copyright (C) 2006-2012 by Bernd Gabriel. - -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. --------------------------------------------------------------------------------} - -{$include htmlcons.inc} - -unit BegaPreviewPanel; - -interface -{$ifndef NoMetaFile} - -uses -{$ifdef MSWindows} - Windows, -{$endif} - Classes, -{$ifdef LCL} - LclIntf, LclType, HtmlMisc, WideStringsLcl, -{$endif LCL} - vcl.Controls, vcl.ExtCtrls, vcl.Graphics, Math, - // own units - BegaMetaFilePrinter; - -type - TBegaCustomPreviewPanel = class; - - TBegaUpdatePreviewEvent = procedure(Sender: TBegaCustomPreviewPanel; var Width, Height: Integer) of object; - - //BG, 05.11.2006 - TBegaCustomPreviewPanel = class(TCustomPanel) - private - FColumnCount: Integer; - FColumnWidth: Integer; - FInnerWidth: Integer; - FRowCount: Integer; - FRowHeight: Integer; - FOnUpdatePreview: TBegaUpdatePreviewEvent; - function getColumnWidth(Column: Integer): Integer; - function getRowCount: Integer; - function getRowHeight(Row: Integer): Integer; - function setColumnWidthIfNew(const Value: Integer): Boolean; - function setRowHeightIfNew(const Value: Integer): Boolean; - procedure doUpdatePreview(var Width, Height: Integer); - procedure setColumnCount(const Value: Integer); - procedure setColumnWidth(const Value: Integer); - procedure setInnerWidth(const Value: Integer); - procedure setRowCount(const Value: Integer); - procedure setRowHeight(const Value: Integer); - protected - function getCell(Column, Row: Integer): TControl; virtual; abstract; - function getCellCount: Integer; virtual; abstract; - function indexOfCell(Column, Row: Integer): Integer; - property CommonColumnWidth: Integer read FColumnWidth write setColumnWidth; - property CommonRowHeight: Integer read FRowHeight write setRowHeight; - property CellCount: Integer read getCellCount; - property Cells[Column: Integer; Row: Integer]: TControl read getCell; default; - property ColumnCount: Integer read FColumnCount write setColumnCount default 1; - property ColumnWidth[Column: Integer]: Integer read getColumnWidth; - property InnerWidth: Integer read FInnerWidth write setInnerWidth default 4; - property OnUpdatePreview: TBegaUpdatePreviewEvent read FOnUpdatePreview write FOnUpdatePreview; - property RowCount: Integer read getRowCount write setRowCount default 1; - property RowHeight[Row: Integer]: Integer read getRowHeight; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - procedure updateColumnWidth; - procedure updateRowHeight; - procedure updatePreview; overload; virtual; - procedure updatePreview(NewCommonColumnWidth, NewCommonRowHeight: Integer); overload; - end; - - //BG, 05.11.2006 - TBegaCellPreviewPanel = class(TBegaCustomPreviewPanel) - private - FCells: TList; - function getItem(Index: Integer): TControl; - protected - function createCell(Column, Row: Integer): TControl; virtual; abstract; - function getCell(Column, Row: Integer): TControl; override; - function getCellCount: Integer; override; - property Items[Index: Integer]: TControl read getItem; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - end; - - //BG, 05.11.2006 - - { TBegaMetafilePreviewCell } - - TBegaMetafilePreviewCell = class(TGraphicControl) - protected - procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; - procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; - procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; - procedure Paint; override; - public - constructor Create(AOwner: TComponent); override; - end; - - //BG, 05.11.2006 - TBegaMetaFilePageEvent = procedure(Sender: TBegaCellPreviewPanel; Canvas: TCanvas; PageIndex: Integer) of object; - - //BG, 05.11.2006 - TBegaMetafilePreviewPanel = class(TBegaCellPreviewPanel) - private - FMFPrinter: TBegaMetaFilePrinter; - FFirstPage: Integer; - FOnPaintPage: TBegaMetaFilePageEvent; - procedure setMFPrinter(const Value: TBegaMetaFilePrinter); - procedure doPaintPage(Cell: TBegaMetafilePreviewCell); - procedure setFirstPage(const Value: Integer); - protected - function createCell(Column, Row: Integer): TControl; override; - function getCellCount: Integer; override; - procedure Paint; override; - public - procedure updatePreview; override; - property FirstPage: Integer read FFirstPage write setFirstPage; - property MFPrinter: TBegaMetaFilePrinter read FMFPrinter write setMFPrinter; - published - property Align; - property Alignment; - property Anchors; - property AutoSize; - property BevelInner; - property BevelOuter; - property BevelWidth; - property BiDiMode; - property BorderStyle; - property BorderWidth; - property Color; - property ColumnCount; - property CommonColumnWidth; - property CommonRowHeight; - property Constraints; -{$ifndef LCL} - property Ctl3D; -{$endif LCL} - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property Font; - property FullRepaint; - property InnerWidth; -{$ifndef LCL} - property Locked; -{$endif LCL} - property ParentBiDiMode; - property ParentColor; -{$ifndef LCL} - property ParentCtl3D; -{$endif LCL} - property ParentFont; - property ParentShowHint; - property PopupMenu; - property RowCount; - property ShowHint; - property TabOrder; - property TabStop; - property UseDockManager default True; - property Visible; -{$ifndef LCL} - property OnCanResize; -{$endif LCL} - property OnClick; - property OnConstrainedResize; - property OnContextPopup; - property OnDblClick; - property OnDragDrop; - property OnDragOver; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnGetSiteInfo; - property OnMouseDown; - property OnMouseMove; - property OnMouseUp; - property OnPaintPage: TBegaMetaFilePageEvent read FOnPaintPage write FOnPaintPage; - property OnResize; - property OnStartDrag; - property OnUpdatePreview; - end; - -{$endif NoMetaFile} -implementation -{$ifndef NoMetaFile} - -uses -{$ifdef UseVCLStyles} - System.Types, - System.UITypes, - Vcl.Themes, -{$endif} - MetaFilePrinter; - -{ TBegaCustomPreviewPanel } - -//- BG ----------------------------------------------------------- 05.11.2006 -- -constructor TBegaCustomPreviewPanel.Create(AOwner: TComponent); -begin - inherited; - FColumnCount := 1; - FRowCount := 1; - FInnerWidth := 4; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -destructor TBegaCustomPreviewPanel.Destroy; -begin - inherited; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -procedure TBegaCustomPreviewPanel.doUpdatePreview(var Width, - Height: Integer); -begin - if assigned(FOnUpdatePreview) then - FOnUpdatePreview(self, Width, Height); -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -function TBegaCustomPreviewPanel.getColumnWidth(Column: Integer): Integer; -var - Row: Integer; - Cell: TControl; -begin - Result := FColumnWidth; - if Result = 0 then - for Row := 0 to RowCount - 1 do - begin - Cell := Cells[Column, Row]; - if Cell <> nil then - Result := max(Result, Cell.Width); - end; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -function TBegaCustomPreviewPanel.getRowCount: Integer; -begin - Result := FRowCount; - if Result <= 0 then - begin - Result := CellCount; - if Result > 0 then - Result := (Result - 1) div FColumnCount + 1; - end; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -function TBegaCustomPreviewPanel.getRowHeight(Row: Integer): Integer; -var - Column: Integer; - Cell: TControl; -begin - Result := FRowHeight; - if Result = 0 then - for Column := 0 to ColumnCount - 1 do - begin - Cell := Cells[Column, Row]; - if Cell <> nil then - Result := max(Result, Cell.Height); - end; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -function TBegaCustomPreviewPanel.indexOfCell(Column, - Row: Integer): Integer; -begin - Result := FColumnCount * Row + Column; -end; - -//- BG ----------------------------------------------------------- 06.11.2006 -- -procedure TBegaCustomPreviewPanel.setColumnCount(const Value: Integer); -begin - if FColumnCount <> Value then - begin - FColumnCount := Value; - updatePreview; - invalidate; - end; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -procedure TBegaCustomPreviewPanel.setColumnWidth(const Value: Integer); -begin - if setColumnWidthIfNew(Value) then - begin - updatePreview; - invalidate; - end; -end; - -//- BG ----------------------------------------------------------- 06.11.2006 -- -function TBegaCustomPreviewPanel.setColumnWidthIfNew( - const Value: Integer): Boolean; -begin - Result := FColumnWidth <> Value; - if Result then - begin - FColumnWidth := Value; - updateColumnWidth; - end; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -procedure TBegaCustomPreviewPanel.setInnerWidth(const Value: Integer); -begin - if FInnerWidth <> Value then - begin - FInnerWidth := Value; - updatePreview; - invalidate; - end; -end; - -//- BG ----------------------------------------------------------- 08.11.2006 -- -procedure TBegaCustomPreviewPanel.setRowCount(const Value: Integer); -begin - if FRowCount <> Value then - begin - FRowCount := Value; - updatePreview; - invalidate; - end; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -procedure TBegaCustomPreviewPanel.setRowHeight(const Value: Integer); -begin - if setRowHeightIfNew(Value) then - begin - updatePreview; - invalidate; - end; -end; - -//- BG ----------------------------------------------------------- 06.11.2006 -- -function TBegaCustomPreviewPanel.setRowHeightIfNew(const Value: Integer): Boolean; -begin - Result := FRowHeight <> Value; - if Result then - begin - FRowHeight := Value; - updateRowHeight; - end; -end; - -//- BG ----------------------------------------------------------- 06.11.2006 -- -procedure TBegaCustomPreviewPanel.updateColumnWidth; -var - Column, Row: Integer; - Cell: TControl; -begin - for Row := 0 to RowCount - 1 do - for Column := 0 to ColumnCount - 1 do - begin - Cell := Cells[Column, Row]; - if Cell <> nil then - Cell.Width := FColumnWidth; - end; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -procedure TBegaCustomPreviewPanel.updatePreview; -var - Column: Integer; - Row: Integer; - CellTop: Integer; - Cell: TControl; - CellLeft: array of Integer; - NewWidth: Integer; - NewHeight: Integer; -begin - if (ColumnCount > 0) and (RowCount > 0) then - begin - // pre-calc Left of columns - setLength(CellLeft, ColumnCount); - CellLeft[0] := BorderWidth; - for Column := 0 to ColumnCount - 2 do - CellLeft[Column + 1] := CellLeft[Column] + ColumnWidth[Column] + InnerWidth; - // re-calc Left and Top of all cells - CellTop := BorderWidth; - for Row := 0 to RowCount - 1 do - begin - for Column := 0 to ColumnCount - 1 do - begin - Cell := Cells[Column, Row]; - Cell.Top := CellTop; - Cell.Left := CellLeft[Column]; - end; - inc(CellTop, RowHeight[Row] + InnerWidth); - end; - Column := ColumnCount - 1; - NewWidth := CellLeft[Column] + ColumnWidth[Column] + BorderWidth; - NewHeight := CellTop + BorderWidth - InnerWidth; - doUpdatePreview(NewWidth, NewHeight); - Width := NewWidth; - Height := NewHeight; - end; -end; - -//- BG ----------------------------------------------------------- 06.11.2006 -- -procedure TBegaCustomPreviewPanel.updatePreview(NewCommonColumnWidth, - NewCommonRowHeight: Integer); -var - IsNew: Boolean; -begin - IsNew := False; - if setColumnWidthIfNew(NewCommonColumnWidth) then - IsNew := True; - if setRowHeightIfNew(NewCommonRowHeight) then - IsNew := True; - if IsNew then - updatePreview; - invalidate; -end; - -//- BG ----------------------------------------------------------- 06.11.2006 -- -procedure TBegaCustomPreviewPanel.updateRowHeight; -var - Column, Row: Integer; - Cell: TControl; -begin - for Row := 0 to RowCount - 1 do - for Column := 0 to ColumnCount - 1 do - begin - Cell := Cells[Column, Row]; - if Cell <> nil then - Cell.Height := FRowHeight; - end; -end; - -{ TBegaCellPreviewPanel } - -//- BG ----------------------------------------------------------- 05.11.2006 -- -constructor TBegaCellPreviewPanel.Create(AOwner: TComponent); -begin - inherited; - FCells := TList.Create; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -destructor TBegaCellPreviewPanel.Destroy; -begin - FCells.free; - inherited; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -function TBegaCellPreviewPanel.getCell(Column, Row: Integer): TControl; -var - Index: Integer; -begin - Index := indexOfCell(Column, Row); - if Index >= FCells.Count then - FCells.Count := Index + 1; - Result := FCells[Index]; - if Result = nil then - begin - Result := createCell(Column, Row); - FCells[Index] := Result; - end; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -function TBegaCellPreviewPanel.getCellCount: Integer; -begin - Result := FCells.Count; -end; - -//- BG ----------------------------------------------------------- 08.11.2006 -- -function TBegaCellPreviewPanel.getItem(Index: Integer): TControl; -begin - Result := FCells[Index]; -end; - -{ TBegaMetafilePreviewCell } - -//- BG ----------------------------------------------------------- 05.11.2006 -- -constructor TBegaMetafilePreviewCell.Create(AOwner: TComponent); -begin - inherited Create(AOwner); - ControlStyle := ControlStyle + [csReplicatable]; - Width := 340; - Height := 440; -end; - -//- BG ----------------------------------------------------------- 06.11.2006 -- -procedure TBegaMetafilePreviewCell.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); -var - P: TPoint; -begin - P := ClientToParent(Point(X, Y)); - TBegaMetafilePreviewPanel(Owner).MouseDown(Button, Shift, P.X, P.Y); -end; - -//- BG ----------------------------------------------------------- 06.11.2006 -- -procedure TBegaMetafilePreviewCell.MouseMove(Shift: TShiftState; X, Y: Integer); -var - P: TPoint; -begin - P := ClientToParent(Point(X, Y)); - TBegaMetafilePreviewPanel(Owner).MouseMove(Shift, P.X, P.Y); -end; - -//- BG ----------------------------------------------------------- 06.11.2006 -- -procedure TBegaMetafilePreviewCell.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); -var - P: TPoint; -begin - P := ClientToParent(Point(X, Y)); - TBegaMetafilePreviewPanel(Owner).MouseUp(Button, Shift, P.X, P.Y); -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -procedure TBegaMetafilePreviewCell.Paint; -var - Page: TMetaFile; - MFPrinter: TBegaMetaFilePrinter; - Rect: TBegaRect; -begin - MFPrinter := TBegaMetafilePreviewPanel(Owner).MFPrinter; - if (csDesigning in ComponentState) or (MFPrinter = nil) then - with Canvas do - begin - Pen.Style := psDash; - Brush.Style := bsClear; - Rectangle(0, 0, Width, Height); - end - else - begin - Rect := MFPrinter.PaperArea; - SetMapMode(Canvas.Handle, MM_ANISOTROPIC); - SetWindowExtEx(Canvas.Handle, Rect.Width, Rect.Height, nil); - SetWindowOrgEx(Canvas.Handle, -Rect.Left, -Rect.Top, nil); - SetViewportExtEx(Canvas.Handle, Width, Height, nil); - SetViewportOrgEx(Canvas.Handle, Left, Top, nil); - if (Tag >= 0) and (Tag < MFPrinter.PageNumber) then - begin - Page := MFPrinter.MetaFiles[Tag]; - if Page <> nil then - begin - Canvas.Draw(0, 0, Page); - TBegaMetafilePreviewPanel(Owner).doPaintPage(self); - end; - end; - end; -end; - -{ TBegaMetafilePreviewPanel } - -//- BG ----------------------------------------------------------- 05.11.2006 -- -function TBegaMetafilePreviewPanel.createCell(Column, Row: Integer): TControl; -begin - Result := TBegaMetafilePreviewCell.Create(self); - Result.Parent := self; - Result.Tag := indexOfCell(Column, Row) + FirstPage; - if FColumnWidth > 0 then - Result.Width := FColumnWidth; - if FRowHeight > 0 then - Result.Height := FRowHeight; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -procedure TBegaMetafilePreviewPanel.doPaintPage(Cell: TBegaMetafilePreviewCell); -begin - if assigned(FOnPaintPage) then - FOnPaintPage(self, Cell.Canvas, Cell.Tag); -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -function TBegaMetafilePreviewPanel.getCellCount: Integer; -begin - if FMFPrinter <> nil then - Result := min(max(FMFPrinter.PageNumber - FirstPage, 0), RowCount * ColumnCount) - else - Result := inherited getCellCount; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -procedure TBegaMetafilePreviewPanel.Paint; -begin - inherited; -end; - -//- BG ----------------------------------------------------------- 08.11.2006 -- -procedure TBegaMetafilePreviewPanel.setFirstPage(const Value: Integer); -begin - if FFirstPage <> Value then - begin - FFirstPage := Value; - updatePreview; - invalidate; - end; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -procedure TBegaMetafilePreviewPanel.setMFPrinter( - const Value: TBegaMetaFilePrinter); -begin - if FMFPrinter <> Value then - begin - FMFPrinter := Value; - invalidate; - end; -end; - -//- BG ----------------------------------------------------------- 08.11.2006 -- -procedure TBegaMetafilePreviewPanel.updatePreview; -var - Index: Integer; -begin - for Index := 0 to min(CellCount, FCells.Count) - 1 do - Items[Index].Tag := Index + FirstPage; - for Index := FCells.Count - 1 downto CellCount do - begin - Items[Index].free; - FCells.delete(Index); - end; - inherited; -end; - -{$endif NoMetaFile} -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/BegaScrollBox.pas b/CORE/Source/Plugins/Htmlviewer/source/BegaScrollBox.pas deleted file mode 100644 index 265bb5c92..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/BegaScrollBox.pas +++ /dev/null @@ -1,1252 +0,0 @@ -{------------------------------------------------------------------------------- -Copyright (C) 2006-2014 by Bernd Gabriel. - -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. --------------------------------------------------------------------------------} - -{$include htmlcons.inc} - -unit BegaScrollBox; - -interface -{$ifndef NoFlatScrollbars} - -uses -{$ifdef UseVCLStyles} - Vcl.Themes, -{$endif} - Classes, SysUtils, Messages, -{$ifdef LCL} - LclIntf, LclType, LMessages, - HtmlMisc, -{$else} - FlatSB, -{$endif LCL} -{$ifdef MSWindows} - Windows, - CommCtrl, - MultiMon, -{$endif MSWindows} - vcl.Controls, vcl.ExtCtrls, vcl.Forms, vcl.Graphics, Math, vcl.Menus, - TypInfo; - -type - TBegaScrollingWinClientSize = (csCurrent, csWithoutBar, csWithBar); - - TBegaScrollingWinControl = class; - - TBegaScrollBar = class(TPersistent) - private - FControl: TBegaScrollingWinControl; - FIncrement: TScrollBarInc; - FPageIncrement: TScrollbarInc; - // - FRange: Integer; - FPosition: Integer; - FMaxPos: Integer; - // - FKind: TScrollBarKind; - FMargin: Word; - FVisible: Boolean; - FTracking: Boolean; - FScaled: Boolean; - FSmooth: Boolean; - FDelay: Integer; - FButtonSize: Integer; - FColor: TColor; - FParentColor: Boolean; - FSize: Integer; - FStyle: TScrollBarStyle; - FThumbSize: Integer; - FPageDiv: Integer; - FLineDiv: Integer; - FUpdateNeeded: Boolean; - constructor Create(AControl: TBegaScrollingWinControl; AKind: TScrollBarKind); - procedure CalcAutoRange; - function ControlSize(ControlSB, AssumeSB: Boolean): Integer; overload; - procedure DoSetRange(Value: Integer); - function GetScrollPos: Integer; - function NeedsScrollBarVisible: Boolean; - function IsIncrementStored: Boolean; - procedure ScrollMessage(var Msg: TWMScroll); - procedure SetButtonSize(Value: Integer); - procedure SetColor(Value: TColor); - procedure SetParentColor(Value: Boolean); - procedure SetPosition(Value: Integer); - procedure SetRange(Value: Integer); - procedure SetSize(Value: Integer); - procedure SetStyle(Value: TScrollBarStyle); - procedure SetThumbSize(Value: Integer); - procedure SetVisible(Value: Boolean); - function IsRangeStored: Boolean; - procedure Update(ControlSB, AssumeSB: Boolean); - public - function ControlSize(Which: TBegaScrollingWinClientSize): Integer; overload; - function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean; virtual; - function IsScrollBarVisible: Boolean; - procedure Assign(Source: TPersistent); override; - procedure ChangeBiDiPosition; - property Kind: TScrollBarKind read FKind; - property ScrollPos: Integer read GetScrollPos; - published - property ButtonSize: Integer read FButtonSize write SetButtonSize default 0; - property Color: TColor read FColor write SetColor default clBtnHighlight; - property Increment: TScrollBarInc read FIncrement write FIncrement stored IsIncrementStored default 8; - property Margin: Word read FMargin write FMargin default 0; - property ParentColor: Boolean read FParentColor write SetParentColor default True; - property Range: Integer read FRange write SetRange stored IsRangeStored default 0; - property Position: Integer read FPosition write SetPosition default 0; - property Smooth: Boolean read FSmooth write FSmooth default False; - property Size: Integer read FSize write SetSize default 0; - property Style: TScrollBarStyle read FStyle write SetStyle default ssRegular; - property ThumbSize: Integer read FThumbSize write SetThumbSize default 0; - property Tracking: Boolean read FTracking write FTracking default False; - property Visible: Boolean read FVisible write SetVisible default True; - end; - - TBegaScrollingWinControl = class(TWinControl) - {$ifdef UseVCLStyles} - strict private - class destructor Destroy; - class constructor Create; - {$endif} - private - FAutoRangeCount: Integer; - FAutoScroll: Boolean; - FHorzScrollBar: TBegaScrollBar; - FUpdatingScrollBars: Boolean; - FVertScrollBar: TBegaScrollBar; - FPanningEnabled: Boolean; - FPanning: Boolean; - FPanningStart: TPoint; - procedure CalcAutoRange; - procedure ScaleScrollBars(M, D: Integer); - procedure SetAutoScroll(Value: Boolean); - procedure SetHorzScrollBar(Value: TBegaScrollBar); - procedure SetVertScrollBar(Value: TBegaScrollBar); - procedure UpdateScrollBars; - procedure WMSize(var Message: TWMSize); message WM_SIZE; - procedure WMHScroll(var Message: TWMHScroll); message WM_HSCROLL; - procedure WMVScroll(var Message: TWMVScroll); message WM_VSCROLL; - procedure CMBiDiModeChanged(var Message: TMessage); message CM_BIDIMODECHANGED; - function GetMaxScroll: TPoint; - protected - function AutoScrollEnabled: Boolean; virtual; - function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean; override; - procedure AdjustClientRect(var Rect: TRect); override; - procedure AlignControls(AControl: TControl; var ARect: TRect); override; - procedure AutoScrollInView(AControl: TControl); virtual; - procedure ChangeScale(M, D: Integer); override; - procedure CreateParams(var Params: TCreateParams); override; - procedure CreateWnd; override; - procedure DoFlipChildren; override; - procedure Resizing(State: TWindowState); virtual; - property AutoScroll: Boolean read FAutoScroll write SetAutoScroll default True; - property PanningEnabled: Boolean read FPanningEnabled write FPanningEnabled default True; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - function isPanning: Boolean; virtual; - procedure DisableAutoRange; - procedure EnableAutoRange; - procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer); override; - procedure MouseMove(Shift: TShiftState; X: Integer; Y: Integer); override; - procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer); override; - procedure ScrollInView(AControl: TControl); - published - property HorzScrollBar: TBegaScrollBar read FHorzScrollBar write SetHorzScrollBar; - property VertScrollBar: TBegaScrollBar read FVertScrollBar write SetVertScrollBar; - end; - {$ifdef UseVCLStyles} - TBegaScrollingWinControlStyleHook = class(TScrollingStyleHook) - strict protected - procedure WndProc(var Message: TMessage); override; - public - constructor Create(AControl: TWinControl); override; - end; - - {$endif} - TBegaScrollBox = class(TBegaScrollingWinControl) - private - FBorderStyle: TBorderStyle; - procedure SetBorderStyle(Value: TBorderStyle); -// procedure WMNCHitTest(var Message: TMessage); message WM_NCHITTEST; -{$ifndef LCL} - procedure CMCtl3DChanged(var Message: TMessage); message CM_CTL3DCHANGED; -{$endif LCL} - protected - procedure CreateParams(var Params: TCreateParams); override; - public - constructor Create(AOwner: TComponent); override; - published - property Align; - property Anchors; - property AutoScroll; - property AutoSize; -{$ifndef LCL} - property BevelEdges; - property BevelInner; - property BevelOuter; - property BevelKind; - property BevelWidth; -{$endif LCL} - property BiDiMode; - property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsSingle; - property Constraints; - property DockSite; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property Color nodefault; -{$ifndef LCL} - property Ctl3D; -{$endif LCL} - property Font; - property PanningEnabled; - property ParentBiDiMode; - property ParentColor; -{$ifndef LCL} - property ParentCtl3D; -{$endif LCL} - property ParentFont; - property ParentShowHint; - property PopupMenu; - property ShowHint; - property TabOrder; - property TabStop; - property Visible; -{$ifndef LCL} - property OnCanResize; -{$endif LCL} - property OnClick; - property OnConstrainedResize; - property OnContextPopup; - property OnDblClick; - property OnDockDrop; - property OnDockOver; - property OnDragDrop; - property OnDragOver; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnKeyDown; - property OnKeyUp; - property OnGetSiteInfo; - property OnMouseDown; - property OnMouseMove; - property OnMouseUp; - property OnMouseWheel; - property OnMouseWheelDown; - property OnMouseWheelUp; - property OnResize; - property OnStartDock; - property OnStartDrag; - property OnUnDock; - end; - - EBegaScrollBoxEnumException = class(Exception) - public - constructor createEnum(EnumType: PTypeInfo; const Value); - end; - -{$endif NoFlatScrollbars} -implementation -{$ifndef NoFlatScrollbars} - - {$ifdef UseVCLStyles} - uses - {$ifndef HasSystemUITypes} - Vcl.Styles, - {$endif} - System.UITypes; - {$endif} - -{ TBegaScrollBar } - -constructor TBegaScrollBar.Create(AControl: TBegaScrollingWinControl; AKind: TScrollBarKind); -begin - inherited Create; - FControl := AControl; - FKind := AKind; - FPageIncrement := 80; - FIncrement := FPageIncrement div 10; - FVisible := True; - FDelay := 10; - FLineDiv := 4; - FPageDiv := 12; - FColor := clBtnHighlight; - FParentColor := True; - FUpdateNeeded := True; -end; - -function TBegaScrollBar.IsIncrementStored: Boolean; -begin - Result := not Smooth; -end; - -procedure TBegaScrollBar.Assign(Source: TPersistent); -begin - if Source is TBegaScrollBar then - begin - Visible := TBegaScrollBar(Source).Visible; - Range := TBegaScrollBar(Source).Range; - Position := TBegaScrollBar(Source).Position; - Increment := TBegaScrollBar(Source).Increment; - Exit; - end; - inherited Assign(Source); -end; - -procedure TBegaScrollBar.ChangeBiDiPosition; -begin - if Kind = sbHorizontal then - if IsScrollBarVisible then - if not FControl.UseRightToLeftScrollBar then - Position := 0 - else - Position := Range; -end; - -procedure TBegaScrollBar.CalcAutoRange; -var - I: Integer; - NewMin, NewWidth: Integer; - - procedure processLeftTop(ALeftTop, AWidthHeight: Integer); - var - Size: Integer; - begin - Size := AWidthHeight + math.max(ALeftTop, 0); - if NewMin > ALeftTop then NewMin := ALeftTop; - if NewWidth < Size then NewWidth := Size; - end; - - procedure processRightBottom(AWidthHeight: Integer); - begin - if NewWidth < AWidthHeight then NewWidth := AWidthHeight; - end; - - procedure ProcessHorz(Control: TControl); - begin - if Control.Visible then - case Control.Align of - alLeft: processLeftTop(Control.Left, Control.Width); - alRight: processRightBottom(Control.Width); - alNone: - if Control.Anchors * [akLeft, akRight] = [akLeft] then - processLeftTop(Control.Left, Control.Width) - else if Control.Anchors * [akLeft, akRight] = [akRight] then - processRightBottom(Control.Width); - end; - end; - - procedure ProcessVert(Control: TControl); - begin - if Control.Visible then - case Control.Align of - alTop: processLeftTop(Control.Top, Control.Height); - alBottom: processRightBottom(Control.Height); - alNone: - if Control.Anchors * [akTop, akBottom] = [akTop] then - processLeftTop(Control.Top, Control.Height) - else if Control.Anchors * [akTop, akBottom] = [akBottom] then - processRightBottom(Control.Height); - end; - end; -var - NeedScrollBar: Boolean; - MaxSize, NewSize, NewMax: Integer; -begin - if FControl.FAutoScroll then - begin - if FControl.AutoScrollEnabled then - begin - MaxSize := ControlSize(False, False); - NewMin := 0; - NewWidth := MaxSize; - for I := 0 to FControl.ControlCount - 1 do - if Kind = sbHorizontal then - ProcessHorz(FControl.Controls[I]) - else - ProcessVert(FControl.Controls[I]); - if NewMin > 0 then - NewMin := 0; - NewMax := NewMin + NewWidth; - NeedScrollBar := (NewMin < 0) or (NewMax > MaxSize); - NewSize := ControlSize(False, NeedScrollBar); - if NewMax < NewSize then - NewMax := NewSize; - FPosition := -NewMin; - DoSetRange(NewMax - NewMin); - end - else - DoSetRange(0); - end; -end; - -function TBegaScrollBar.IsScrollBarVisible: Boolean; -var - Style: Longint; -begin - Style := WS_HSCROLL; - if Kind = sbVertical then Style := WS_VSCROLL; - Result := (Visible) and - (GetWindowLong(FControl.Handle, GWL_STYLE) and Style <> 0); -end; - -function TBegaScrollBar.ControlSize(ControlSB, AssumeSB: Boolean): Integer; -var - BorderAdjust: Integer; - - function ScrollBarVisible(Code: Word): Boolean; - var - Style: Longint; - begin - Style := WS_HSCROLL; - if Code = SB_VERT then Style := WS_VSCROLL; - Result := GetWindowLong(FControl.Handle, GWL_STYLE) and Style <> 0; - end; - - function Adjustment(Code, Metric: Word): Integer; - begin - Result := 0; - if not ControlSB then - if AssumeSB and not ScrollBarVisible(Code) then - Result := -(GetSystemMetrics(Metric) - BorderAdjust) - else if not AssumeSB and ScrollBarVisible(Code) then - Result := GetSystemMetrics(Metric) - BorderAdjust; - end; - -begin - BorderAdjust := Integer(GetWindowLong(FControl.Handle, GWL_STYLE) and (WS_BORDER or WS_THICKFRAME) <> 0); - if Kind = sbVertical then - Result := FControl.ClientHeight + Adjustment(SB_HORZ, SM_CXHSCROLL) - else - Result := FControl.ClientWidth + Adjustment(SB_VERT, SM_CYVSCROLL); -end; - -//- BG ----------------------------------------------------------- 22.01.2006 -- -function TBegaScrollBar.ControlSize( - Which: TBegaScrollingWinClientSize): Integer; -begin - case Which of - csCurrent: Result := ControlSize(True, False); - csWithoutBar: Result := ControlSize(False, False); - csWithBar: Result := ControlSize(False, True); - else - raise EBegaScrollBoxEnumException.createEnum(TypeInfo(TBegaScrollingWinClientSize), Which); - end; -end; - -function TBegaScrollBar.GetScrollPos: Integer; -begin - Result := 0; - if Visible then Result := Position; -end; - -function TBegaScrollBar.NeedsScrollBarVisible: Boolean; -begin - Result := FRange > ControlSize(False, False); -end; - -procedure TBegaScrollBar.ScrollMessage(var Msg: TWMScroll); -var - Incr, FinalIncr, Count: Integer; - CurrentTime, StartTime, ElapsedTime: Longint; - - function GetRealScrollPosition: Integer; - var - SI: TScrollInfo; - Code: Integer; - begin - SI.cbSize := SizeOf(TScrollInfo); - SI.fMask := SIF_TRACKPOS; - Code := SB_HORZ; - if FKind = sbVertical then Code := SB_VERT; - Result := Msg.Pos; - if FlatSB_GetScrollInfo(FControl.Handle, Code, SI) then - Result := SI.nTrackPos; - end; - -begin - with Msg do - begin - if FSmooth and (ScrollCode in [SB_LINEUP, SB_LINEDOWN, SB_PAGEUP, SB_PAGEDOWN]) then - begin - case ScrollCode of - SB_LINEUP, SB_LINEDOWN: - begin - Incr := FIncrement div FLineDiv; - FinalIncr := FIncrement mod FLineDiv; - Count := FLineDiv; - end; - SB_PAGEUP, SB_PAGEDOWN: - begin - Incr := FPageIncrement; - FinalIncr := Incr mod FPageDiv; - Incr := Incr div FPageDiv; - Count := FPageDiv; - end; - else - Count := 0; - Incr := 0; - FinalIncr := 0; - end; - CurrentTime := 0; - while Count > 0 do - begin - StartTime := GetCurrentTime; - ElapsedTime := StartTime - CurrentTime; - if ElapsedTime < FDelay then Sleep(FDelay - ElapsedTime); - CurrentTime := StartTime; - case ScrollCode of - SB_LINEUP: SetPosition(FPosition - Incr); - SB_LINEDOWN: SetPosition(FPosition + Incr); - SB_PAGEUP: SetPosition(FPosition - Incr); - SB_PAGEDOWN: SetPosition(FPosition + Incr); - end; - FControl.Update; - Dec(Count); - end; - if FinalIncr > 0 then - begin - case ScrollCode of - SB_LINEUP: SetPosition(FPosition - FinalIncr); - SB_LINEDOWN: SetPosition(FPosition + FinalIncr); - SB_PAGEUP: SetPosition(FPosition - FinalIncr); - SB_PAGEDOWN: SetPosition(FPosition + FinalIncr); - end; - end; - end - else - case ScrollCode of - SB_LINEUP: SetPosition(FPosition - FIncrement); - SB_LINEDOWN: SetPosition(FPosition + FIncrement); - SB_PAGEUP: SetPosition(FPosition - ControlSize(True, False)); - SB_PAGEDOWN: SetPosition(FPosition + ControlSize(True, False)); - SB_THUMBPOSITION: - if FRange > 32767 then - SetPosition(GetRealScrollPosition) else - SetPosition(Pos); - SB_THUMBTRACK: - if Tracking then - if FRange > 32767 then - SetPosition(GetRealScrollPosition) else - SetPosition(Pos); - SB_TOP: SetPosition(0); - SB_BOTTOM: SetPosition(FMaxPos); - SB_ENDSCROLL: begin end; - end; - end; -end; - -procedure TBegaScrollBar.SetButtonSize(Value: Integer); -const - SysConsts: array[TScrollBarKind] of Integer = (SM_CXHSCROLL, SM_CXVSCROLL); -var - NewValue: Integer; -begin - if Value <> ButtonSize then - begin - NewValue := Value; - if NewValue = 0 then - Value := GetSystemMetrics(SysConsts[Kind]); - FButtonSize := Value; - FUpdateNeeded := True; - FControl.UpdateScrollBars; - if NewValue = 0 then - FButtonSize := 0; - end; -end; - -procedure TBegaScrollBar.SetColor(Value: TColor); -begin - if Value <> Color then - begin - FColor := Value; - FParentColor := False; - FUpdateNeeded := True; - FControl.UpdateScrollBars; - end; -end; - -procedure TBegaScrollBar.SetParentColor(Value: Boolean); -begin - if ParentColor <> Value then - begin - FParentColor := Value; - if Value then Color := clBtnHighlight; - end; -end; - -procedure TBegaScrollBar.SetPosition(Value: Integer); -var - Code: Word; - Form: TCustomForm; - Delta: Integer; -begin - if csReading in FControl.ComponentState then - FPosition := Value - else - begin - if Value < 0 then - Value := 0 - else if Value > FMaxPos then - Value := FMaxPos; - if Kind = sbHorizontal then - Code := SB_HORZ - else - Code := SB_VERT; - if Value <> FPosition then - begin - Delta := FPosition - Value; - if Kind = sbHorizontal then - FControl.ScrollBy(Delta, 0) - else - FControl.ScrollBy(0, Delta); - if csDesigning in FControl.ComponentState then - begin - Form := GetParentForm(FControl); - if (Form <> nil) and (Form.Designer <> nil) then - Form.Designer.Modified; - end; - FPosition := Value; - end; - if FlatSB_GetScrollPos(FControl.Handle, Code) <> FPosition then - FlatSB_SetScrollPos(FControl.Handle, Code, FPosition, True); - end; -end; - -procedure TBegaScrollBar.SetSize(Value: Integer); -const - SysConsts: array[TScrollBarKind] of Integer = (SM_CYHSCROLL, SM_CYVSCROLL); -var - NewValue: Integer; -begin - if Value <> Size then - begin - NewValue := Value; - if NewValue = 0 then - Value := GetSystemMetrics(SysConsts[Kind]); - FSize := Value; - FUpdateNeeded := True; - FControl.UpdateScrollBars; - if NewValue = 0 then - FSize := 0; - end; -end; - -procedure TBegaScrollBar.SetStyle(Value: TScrollBarStyle); -begin - if Style <> Value then - begin - FStyle := Value; - FUpdateNeeded := True; - FControl.UpdateScrollBars; - end; -end; - -procedure TBegaScrollBar.SetThumbSize(Value: Integer); -begin - if Value <> ThumbSize then - begin - FThumbSize := Value; - FUpdateNeeded := True; - FControl.UpdateScrollBars; - end; -end; - -procedure TBegaScrollBar.DoSetRange(Value: Integer); -begin - FRange := Value; - if FRange < 0 then - FRange := 0; - FControl.UpdateScrollBars; -end; - -function TBegaScrollBar.IsRangeStored: Boolean; -begin - Result := not FControl.AutoScroll; -end; - -procedure TBegaScrollBar.SetVisible(Value: Boolean); -begin - FVisible := Value; - FControl.UpdateScrollBars; -end; - -procedure TBegaScrollBar.Update(ControlSB, AssumeSB: Boolean); -type - TPropKind = (pkStyle, pkButtonSize, pkThumbSize, pkSize, pkBkColor); -const - Props: array[TScrollBarKind, TPropKind] of Integer = ( - { Horizontal } - (WSB_PROP_HSTYLE, WSB_PROP_CXHSCROLL, WSB_PROP_CXHTHUMB, WSB_PROP_CYHSCROLL, - WSB_PROP_HBKGCOLOR), - { Vertical } - (WSB_PROP_VSTYLE, WSB_PROP_CYVSCROLL, WSB_PROP_CYVTHUMB, WSB_PROP_CXVSCROLL, - WSB_PROP_VBKGCOLOR)); -// Kinds: array[TScrollBarKind] of Integer = (WSB_PROP_HSTYLE, WSB_PROP_VSTYLE); - Styles: array[TScrollBarStyle] of Integer = (FSB_REGULAR_MODE, - FSB_ENCARTA_MODE, FSB_FLAT_MODE); - Code: array[TScrollBarKind] of Word = (SB_HORZ, SB_VERT); -var - ScrollInfo: TScrollInfo; - - procedure UpdateScrollProperties(Redraw: Boolean); - begin - FlatSB_SetScrollProp(FControl.Handle, Props[Kind, pkStyle], Styles[Style], Redraw); - if ButtonSize > 0 then - FlatSB_SetScrollProp(FControl.Handle, Props[Kind, pkButtonSize], ButtonSize, False); - if ThumbSize > 0 then - FlatSB_SetScrollProp(FControl.Handle, Props[Kind, pkThumbSize], ThumbSize, False); - if Size > 0 then - FlatSB_SetScrollProp(FControl.Handle, Props[Kind, pkSize], Size, False); - FlatSB_SetScrollProp(FControl.Handle, Props[Kind, pkBkColor], - ColorToRGB(Color), False); - end; -var - BarSize: Integer; -begin - if Visible then - begin - BarSize := ControlSize(ControlSB, AssumeSB); - if BarSize > FRange then - BarSize := FRange; - end - else - BarSize := FRange; - FMaxPos := FRange - BarSize; - ScrollInfo.cbSize := SizeOf(ScrollInfo); - ScrollInfo.fMask := SIF_ALL; - ScrollInfo.nMin := 0; - if FMaxPos > 0 then - ScrollInfo.nMax := FRange - else - ScrollInfo.nMax := 0; - ScrollInfo.nPage := BarSize + 1; - ScrollInfo.nPos := FPosition; - ScrollInfo.nTrackPos := FPosition; - UpdateScrollProperties(FUpdateNeeded); - FUpdateNeeded := False; - FlatSB_SetScrollInfo(FControl.Handle, Code[Kind], ScrollInfo, True); - SetPosition(FPosition); - FPageIncrement := (ControlSize(True, False) * 9) div 10; - if Smooth then FIncrement := FPageIncrement div 10; -end; - -//- BG ----------------------------------------------------------- 21.01.2006 -- -procedure TBegaScrollBar.SetRange(Value: Integer); -begin - FControl.FAutoScroll := False; - FScaled := True; - DoSetRange(Value); -end; - -//- BG ----------------------------------------------------------- 22.02.2006 -- -function TBegaScrollBar.DoMouseWheel(Shift: TShiftState; - WheelDelta: Integer; MousePos: TPoint): Boolean; -begin - Result := Visible; - Position := Position - WheelDelta; -end; - -{ TBegaScrollingWinControl } - -constructor TBegaScrollingWinControl.Create(AOwner: TComponent); -begin - inherited Create(AOwner); - FHorzScrollBar := TBegaScrollBar.Create(Self, sbHorizontal); - FVertScrollBar := TBegaScrollBar.Create(Self, sbVertical); - FAutoScroll := True; - FPanningEnabled := True; -end; - -destructor TBegaScrollingWinControl.Destroy; -begin - FHorzScrollBar.Free; - FVertScrollBar.Free; - inherited Destroy; -end; - -procedure TBegaScrollingWinControl.CreateParams(var Params: TCreateParams); -begin - inherited CreateParams(Params); - with Params.WindowClass do - style := style and not (CS_HREDRAW or CS_VREDRAW); -end; - -procedure TBegaScrollingWinControl.CreateWnd; -begin - inherited CreateWnd; - //! Scroll bars don't move to the Left side of a TBegaScrollingWinControl when the - //! WS_EX_LeftScrollBar flag is set and InitializeFlatSB is called. - //! A call to UnInitializeFlatSB does nothing. - if not SysLocale.MiddleEast and - not CheckWin32Version(5, 1) then - InitializeFlatSB(Handle); - UpdateScrollBars; -end; - -procedure TBegaScrollingWinControl.AlignControls(AControl: TControl; var ARect: TRect); -begin - CalcAutoRange; - inherited AlignControls(AControl, ARect); -end; - -function TBegaScrollingWinControl.AutoScrollEnabled: Boolean; -begin - Result := not AutoSize and not (DockSite and UseDockManager); -end; - -procedure TBegaScrollingWinControl.DoFlipChildren; -var - Loop: Integer; - TheWidth: Integer; - ScrollBarActive: Boolean; - FlippedList: TList; -begin - FlippedList := TList.Create; - try - TheWidth := ClientWidth; - with HorzScrollBar do begin - ScrollBarActive := (IsScrollBarVisible) and (TheWidth < Range); - if ScrollBarActive then - begin - TheWidth := Range; - Position := 0; - end; - end; - - for Loop := 0 to ControlCount - 1 do with Controls[Loop] do - begin - FlippedList.Add(Controls[Loop]); - Left := TheWidth - Width - Left; - end; - - { Allow controls that have associations to realign themselves } - for Loop := 0 to FlippedList.Count - 1 do - TControl(FlippedList[Loop]).Perform(CM_ALLCHILDRENFLIPPED, 0, 0); - - if ScrollBarActive then - HorzScrollBar.ChangeBiDiPosition; - finally - FlippedList.Free; - end; -end; - -procedure TBegaScrollingWinControl.CalcAutoRange; -begin - if FAutoRangeCount <= 0 then - begin - HorzScrollBar.CalcAutoRange; - VertScrollBar.CalcAutoRange; - end; -end; - -procedure TBegaScrollingWinControl.SetAutoScroll(Value: Boolean); -begin - if FAutoScroll <> Value then - begin - FAutoScroll := Value; - if Value then CalcAutoRange else - begin - HorzScrollBar.setRange(0); - VertScrollBar.setRange(0); - end; - end; -end; - -procedure TBegaScrollingWinControl.SetHorzScrollBar(Value: TBegaScrollBar); -begin - FHorzScrollBar.Assign(Value); -end; - -procedure TBegaScrollingWinControl.SetVertScrollBar(Value: TBegaScrollBar); -begin - FVertScrollBar.Assign(Value); -end; - -procedure TBegaScrollingWinControl.UpdateScrollBars; -begin - if not FUpdatingScrollBars and HandleAllocated then - try - FUpdatingScrollBars := True; - if FVertScrollBar.NeedsScrollBarVisible then - begin - FHorzScrollBar.Update(False, True); - FVertScrollBar.Update(True, False); - end - else if FHorzScrollBar.NeedsScrollBarVisible then - begin - FVertScrollBar.Update(False, True); - FHorzScrollBar.Update(True, False); - end - else - begin - FVertScrollBar.Update(False, False); - FHorzScrollBar.Update(True, False); - end; - finally - FUpdatingScrollBars := False; - end; -end; - -procedure TBegaScrollingWinControl.AutoScrollInView(AControl: TControl); -begin - if (AControl <> nil) and not (csLoading in AControl.ComponentState) and - not (csLoading in ComponentState) then - ScrollInView(AControl); -end; - -procedure TBegaScrollingWinControl.DisableAutoRange; -begin - Inc(FAutoRangeCount); -end; - -procedure TBegaScrollingWinControl.EnableAutoRange; -begin - if FAutoRangeCount > 0 then - begin - Dec(FAutoRangeCount); - if (FAutoRangeCount = 0) and (FHorzScrollBar.Visible or - FVertScrollBar.Visible) then CalcAutoRange; - end; -end; - -procedure TBegaScrollingWinControl.ScrollInView(AControl: TControl); -var - Rect: TRect; -begin - if AControl = nil then Exit; - Rect := AControl.ClientRect; - Dec(Rect.Left, HorzScrollBar.Margin); - Inc(Rect.Right, HorzScrollBar.Margin); - Dec(Rect.Top, VertScrollBar.Margin); - Inc(Rect.Bottom, VertScrollBar.Margin); - Rect.TopLeft := ScreenToClient(AControl.ClientToScreen(Rect.TopLeft)); - Rect.BottomRight := ScreenToClient(AControl.ClientToScreen(Rect.BottomRight)); - if Rect.Left < 0 then - with HorzScrollBar do Position := Position + Rect.Left - else if Rect.Right > ClientWidth then - begin - if Rect.Right - Rect.Left > ClientWidth then - Rect.Right := Rect.Left + ClientWidth; - with HorzScrollBar do Position := Position + Rect.Right - ClientWidth; - end; - if Rect.Top < 0 then - with VertScrollBar do Position := Position + Rect.Top - else if Rect.Bottom > ClientHeight then - begin - if Rect.Bottom - Rect.Top > ClientHeight then - Rect.Bottom := Rect.Top + ClientHeight; - with VertScrollBar do Position := Position + Rect.Bottom - ClientHeight; - end; -end; - -procedure TBegaScrollingWinControl.ScaleScrollBars(M, D: Integer); -begin - if M <> D then - begin - if not (csLoading in ComponentState) then - begin - HorzScrollBar.FScaled := True; - VertScrollBar.FScaled := True; - end; - HorzScrollBar.Position := 0; - VertScrollBar.Position := 0; - if not FAutoScroll then - begin - with HorzScrollBar do if FScaled then Range := MulDiv(Range, M, D); - with VertScrollBar do if FScaled then Range := MulDiv(Range, M, D); - end; - end; - HorzScrollBar.FScaled := False; - VertScrollBar.FScaled := False; -end; - -procedure TBegaScrollingWinControl.ChangeScale(M, D: Integer); -begin - ScaleScrollBars(M, D); - inherited ChangeScale(M, D); -end; - -procedure TBegaScrollingWinControl.Resizing(State: TWindowState); -begin - // Overridden by TCustomFrame -end; - -procedure TBegaScrollingWinControl.WMSize(var Message: TWMSize); -var - NewState: TWindowState; -begin - Inc(FAutoRangeCount); - try - inherited; - NewState := wsNormal; - case Message.SizeType of - SIZENORMAL: NewState := wsNormal; - SIZEICONIC: NewState := wsMinimized; - SIZEFULLSCREEN: NewState := wsMaximized; - end; - Resizing(NewState); - finally - Dec(FAutoRangeCount); - end; - FUpdatingScrollBars := True; - try - CalcAutoRange; - finally - FUpdatingScrollBars := False; - end; - if FHorzScrollBar.Visible or FVertScrollBar.Visible then - UpdateScrollBars; -end; - -procedure TBegaScrollingWinControl.WMHScroll(var Message: TWMHScroll); -begin - if (Message.ScrollBar = 0) and FHorzScrollBar.Visible then - FHorzScrollBar.ScrollMessage(Message) else - inherited; -end; - -procedure TBegaScrollingWinControl.WMVScroll(var Message: TWMVScroll); -begin - if (Message.ScrollBar = 0) and FVertScrollBar.Visible then - FVertScrollBar.ScrollMessage(Message) else - inherited; -end; - -procedure TBegaScrollingWinControl.AdjustClientRect(var Rect: TRect); -begin - Rect := Bounds(-HorzScrollBar.Position, -VertScrollBar.Position, - Max(HorzScrollBar.Range, ClientWidth), - Max(VertScrollBar.Range, ClientHeight)); - inherited AdjustClientRect(Rect); -end; - -procedure TBegaScrollingWinControl.CMBiDiModeChanged(var Message: TMessage); -var - Save: Integer; -begin - Save := Message.WParam; - try - { prevent inherited from calling Invalidate & RecreateWnd } - if not (Self is TBegaScrollBox) then Message.wParam := 1; - inherited; - finally - Message.wParam := Save; - end; - if HandleAllocated then - begin - HorzScrollBar.ChangeBiDiPosition; - UpdateScrollBars; - end; -end; - -//- BG ----------------------------------------------------------- 22.01.2006 -- -function TBegaScrollingWinControl.DoMouseWheel(Shift: TShiftState; - WheelDelta: Integer; MousePos: TPoint): Boolean; -begin - Result := inherited DoMouseWheel(Shift, WheelDelta, MousePos); - if not Result and not (ssAlt in Shift) then - Result := VertScrollBar.DoMouseWheel(Shift, WheelDelta, MousePos); - if not Result then - Result := HorzScrollBar.DoMouseWheel(Shift, WheelDelta, MousePos); -end; - -//- BG ----------------------------------------------------------- 13.07.2006 -- -function TBegaScrollingWinControl.isPanning: Boolean; -begin - Result := FPanning; -end; - -//- BG ----------------------------------------------------------- 13.07.2006 -- -procedure TBegaScrollingWinControl.MouseDown(Button: TMouseButton; - Shift: TShiftState; X, Y: Integer); -begin - if FPanningEnabled and (Shift * [ssShift, ssAlt, ssCtrl] = []) then - begin - FPanning := True; - FPanningStart.X := X; - FPanningStart.Y := Y; - end - else - inherited; -end; - -//-- BG ---------------------------------------------------------- 29.07.2013 -- -function TBegaScrollingWinControl.GetMaxScroll(): TPoint; -var - I: Integer; - Control: TControl; -begin - // Do not scroll topest leftest corner of all child controls into my client rect. - Result.X := 0; - Result.Y := 0; - for I := 0 to ControlCount - 1 do - begin - Control := Controls[I]; - Result.X := Max(Result.X, -Control.Left); - Result.Y := Max(Result.Y, -Control.Top); - end; -end; - -//- BG ----------------------------------------------------------- 13.07.2006 -- -procedure TBegaScrollingWinControl.MouseMove(Shift: TShiftState; X, Y: Integer); -var - Scroll: TPoint; -begin - if FPanning then - begin - Scroll := GetMaxScroll; - Scroll.X := Min(Scroll.X, X - FPanningStart.X); - Scroll.Y := Min(Scroll.Y, Y - FPanningStart.Y); - ScrollBy(Scroll.X, Scroll.Y); - FPanningStart.X := X; - FPanningStart.Y := Y; - end - else - inherited; -end; - -//- BG ----------------------------------------------------------- 13.07.2006 -- -procedure TBegaScrollingWinControl.MouseUp(Button: TMouseButton; - Shift: TShiftState; X, Y: Integer); -var - Scroll: TPoint; -begin - if FPanning then - begin - Scroll := GetMaxScroll; - Scroll.X := Min(Scroll.X, X - FPanningStart.X); - Scroll.Y := Min(Scroll.Y, Y - FPanningStart.Y); - ScrollBy(Scroll.X, Scroll.Y); - FPanning := False; - end - else - inherited; -end; - - {$ifdef UseVCLStyles} -type - TWinControlClassHook = class(TWinControl); - -class constructor TBegaScrollingWinControl.Create; -{Workaround for an issue calling TCustomStyleEngine.RegisterStyleHook in Delphi XE2. -It turns out that an abstract method TCustomStyleEngine.Notification was being called -by TCustomStyleEngine.UnRegisterStyleHook . This could cause the program to raise an -Abstract Method exception when exiting. This is the exact same issue as described -at http://code.google.com/p/virtual-treeview/issues/detail?id=345 . -} -begin - {$ifdef HasSystemUITypes} - TCustomStyleEngine.RegisterStyleHook(TBegaScrollingWinControl, TBegaScrollingWinControlStyleHook); - {$else} - TStyleEngine.RegisterStyleHook(TBegaScrollingWinControl, TBegaScrollingWinControlStyleHook); - {$endif} -end; - -class destructor TBegaScrollingWinControl.Destroy; -begin - {$ifdef HasSystemUITypes} - TCustomStyleEngine.UnRegisterStyleHook(TBegaScrollingWinControl, TBegaScrollingWinControlStyleHook); - {$else} - TStyleEngine.UnRegisterStyleHook(TBegaScrollingWinControl, TBegaScrollingWinControlStyleHook); - {$endif} -end; - -procedure TBegaScrollingWinControlStyleHook.WndProc(var Message: TMessage); -begin - // Reserved for potential updates - inherited; -end; - -constructor TBegaScrollingWinControlStyleHook.Create(AControl: TWinControl); -begin - inherited; - OverrideEraseBkgnd := True; - {$ifdef has_StyleElements} - if seClient in Control.StyleElements then - Brush.Color := StyleServices.GetStyleColor(scPanel) - else - Brush.Color := TWinControlClassHook(Control).Color; - {$else} - Brush.Color := StyleServices.GetStyleColor(scListBox); - {$Endif} -end; - - {$endif} - -{ TBegaScrollBox } - -constructor TBegaScrollBox.Create(AOwner: TComponent); -begin - inherited Create(AOwner); - ControlStyle := [csAcceptsControls, csCaptureMouse, csClickEvents, - csSetCaption, csDoubleClicks]; - Width := 185; - Height := 41; - FBorderStyle := bsSingle; -end; - -procedure TBegaScrollBox.CreateParams(var Params: TCreateParams); -const - BorderStyles: array[TBorderStyle] of DWORD = (0, WS_BORDER); -begin - inherited CreateParams(Params); - with Params do - begin - Style := Style or BorderStyles[FBorderStyle]; - if NewStyleControls {$ifndef LCL} and Ctl3D {$endif} and (FBorderStyle = bsSingle) then - begin - Style := Style and not WS_BORDER; - ExStyle := ExStyle or WS_EX_CLIENTEDGE; - end; - end; -end; - -procedure TBegaScrollBox.SetBorderStyle(Value: TBorderStyle); -begin - if Value <> FBorderStyle then - begin - FBorderStyle := Value; - RecreateWnd {$ifdef LCL}(Self){$endif}; - end; -end; - -{$ifndef LCL} -procedure TBegaScrollBox.CMCtl3DChanged(var Message: TMessage); -begin - if NewStyleControls and (FBorderStyle = bsSingle) then RecreateWnd; - inherited; -end; -{$endif} - -{ EBegaScrollBoxEnumException } - -//- BG ----------------------------------------------------------- 23.01.2005 -- -constructor EBegaScrollBoxEnumException.createEnum(EnumType: PTypeInfo; const Value); -begin - inherited createFmt('unsupported: %s.%s', [EnumType.Name, GetEnumName(EnumType, integer(Value))]); -end; - -{$endif NoFlatScrollbars} -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/BegaZoom.pas b/CORE/Source/Plugins/Htmlviewer/source/BegaZoom.pas deleted file mode 100644 index 607997960..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/BegaZoom.pas +++ /dev/null @@ -1,242 +0,0 @@ -{------------------------------------------------------------------------------- -Copyright (C) 2006-2012 by Bernd Gabriel. - -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. --------------------------------------------------------------------------------} - -{$include htmlcons.inc} - -unit BegaZoom; - -interface -{$ifndef NoFlatScrollbars} - -uses - Classes, vcl.Controls, vcl.ExtCtrls, Math, Types, - // own units - BegaScrollBox; - -type - TBegaZoomMode = ( - zmFitToPage, - zmFitToHeight, - zmFitToWidth, - zm25, zm50, zm75, - zm100, zm125, zm150, - zm200, zm300, zm400, - zmCustom); - - TBegaZoomModes = Set of TBegaZoomMode; - TBegaZoomEvent = procedure(Sender: TObject; ZoomTo: Double) of object; - - //- BG --------------------------------------------------------- 05.11.2006 -- - TBegaZoomingScrollBox = class(TBegaScrollBox) - private - FZoom: Double; - FOnZoomBy: TBegaZoomEvent; - FOnZoomTo: TBegaZoomEvent; - protected - function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean; override; - property OnZoomBy: TBegaZoomEvent read FOnZoomBy write FOnZoomBy; - property OnZoomTo: TBegaZoomEvent read FOnZoomTo write FOnZoomTo; - property ZoomFactor: Double read FZoom; - procedure doZoomBy(ZoomBy: Double; Around: TPoint); virtual; - procedure doZoomTo(ZoomTo: Double; Width, Height, BoxWidth, BoxHeight: Integer); virtual; - public - constructor Create(AOwner: TComponent); override; - procedure zoomBy(Zoom: Double; Around: TPoint); - procedure zoomTo(Zoom: Double; Width, Height: Integer); - procedure zoomToFitIntoBox(Width, Height: Integer); - end; - - //- BG --------------------------------------------------------- 23.01.2006 -- - TBegaZoomBox = class(TBegaZoomingScrollBox) - private - function getZoomedControl: TControl; - protected - property ZoomedControl: TControl read getZoomedControl; - procedure doZoomBy(ZoomBy: Double; Around: TPoint); override; - procedure doZoomTo(ZoomTo: Double; Width, Height, BoxWidth, BoxHeight: Integer); override; - published - property OnZoomBy; - property OnZoomTo; - property ZoomFactor; - end; - -procedure begaZoomControlAroundPoint(ZoomedControl: TControl; Zoom: Double; Around: TPoint); -function begaZoomFactorToMode(Factor: Double): TBegaZoomMode; - -{$endif NoFlatScrollbars} -implementation -{$ifndef NoFlatScrollbars} - -//- BG ----------------------------------------------------------- 12.11.2006 -- -procedure begaZoomControlAroundPoint(ZoomedControl: TControl; Zoom: Double; Around: TPoint); -// zoom control around a fixed point (e.g. where mouse clicked). -var - Size: TPoint; - IPos: TPoint; -begin - Size.X := round(ZoomedControl.Width * Zoom); - Size.Y := round(ZoomedControl.Height * Zoom); - IPos.X := round(Around.X - (Around.X - ZoomedControl.Left) * Zoom); - IPos.Y := round(Around.Y - (Around.Y - ZoomedControl.Top) * Zoom); - ZoomedControl.setBounds(IPos.X, IPos.Y, Size.X, Size.Y); -end; - -//- BG ----------------------------------------------------------- 12.11.2006 -- -function begaZoomFactorToMode(Factor: Double): TBegaZoomMode; -begin - case round(Factor * 100) of - 25: Result := zm25; - 50: Result := zm50; - 75: Result := zm25; - 100: Result := zm100; - 125: Result := zm125; - 150: Result := zm150; - 200: Result := zm200; - 300: Result := zm300; - 400: Result := zm400; - else - Result := zmCustom; - end; -end; - -{ TBegaZoomingScrollBox } - -//- BG ----------------------------------------------------------- 11.11.2006 -- -constructor TBegaZoomingScrollBox.Create(AOwner: TComponent); -begin - inherited; - FZoom := 1.0; -end; - -//- BG ----------------------------------------------------------- 12.07.2006 -- -function TBegaZoomingScrollBox.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; - MousePos: TPoint): Boolean; -begin - if Shift * [ssShift, ssAlt, ssCtrl] = [ssCtrl] then - begin - Result := inherited DoMouseWheel(Shift, WheelDelta, MousePos); - if not Result and not (ssAlt in Shift) then - Result := VertScrollBar.DoMouseWheel(Shift, WheelDelta, MousePos); - if not Result then - Result := HorzScrollBar.DoMouseWheel(Shift, WheelDelta, MousePos); - end - else - begin - if WheelDelta > 0 then - zoomBy(1.11111111111111111111111, ScreenToClient(Mouse.CursorPos)) - else - zoomBy(0.9, ScreenToClient(Mouse.CursorPos)); - Result := true; - end; -end; - -//- BG ----------------------------------------------------------- 12.11.2006 -- -procedure TBegaZoomingScrollBox.doZoomBy(ZoomBy: Double; Around: TPoint); -begin - if assigned(FOnZoomBy) then - FOnZoomBy(self, FZoom); -end; - -//- BG ----------------------------------------------------------- 12.11.2006 -- -procedure TBegaZoomingScrollBox.doZoomTo(ZoomTo: Double; Width, Height, - BoxWidth, BoxHeight: Integer); -begin - if assigned(FOnZoomTo) then - FOnZoomTo(self, FZoom); -end; - -//- BG ----------------------------------------------------------- 23.01.2006 -- -procedure TBegaZoomingScrollBox.zoomBy(Zoom: Double; Around: TPoint); -begin - FZoom := FZoom * Zoom; - doZoomBy(Zoom, Around); -end; - -//- BG ----------------------------------------------------------- 23.01.2006 -- -procedure TBegaZoomingScrollBox.zoomTo(Zoom: Double; Width, Height: Integer); -var - BoxWidth, BoxHeight: Integer; -begin - FZoom := Zoom; - // calc width - Width := trunc(FZoom * Width); - BoxWidth := HorzScrollBar.ControlSize(csWithoutBar); - if Width > BoxWidth then - BoxWidth := HorzScrollBar.ControlSize(csWithBar); - // calc height - Height := trunc(FZoom * Height); - BoxHeight := VertScrollBar.ControlSize(csWithoutBar); - if Height > BoxHeight then - BoxHeight := VertScrollBar.ControlSize(csWithBar); - // do zoom - doZoomTo(FZoom, Width, Height, BoxWidth, BoxHeight); -end; - -//- BG ----------------------------------------------------------- 23.01.2006 -- -procedure TBegaZoomingScrollBox.zoomToFitIntoBox(Width, Height: Integer); -var - BoxWidth, BoxHeight: Integer; -begin - if (Width > 0) and (Height > 0) then - begin - BoxWidth := HorzScrollBar.ControlSize(csWithoutBar); - BoxHeight := VertScrollBar.ControlSize(csWithoutBar); - FZoom := min(BoxWidth/Width, BoxHeight/Height); - Width := trunc(FZoom * Width); - Height := trunc(FZoom * Height); - doZoomTo(FZoom, Width, Height, BoxWidth, BoxHeight); - end; -end; - -{ TBegaZoomBox } - -//- BG ----------------------------------------------------------- 05.11.2006 -- -procedure TBegaZoomBox.doZoomBy(ZoomBy: Double; Around: TPoint); -begin - inherited; - begaZoomControlAroundPoint(ZoomedControl, ZoomBy, Around); - if ZoomedControl is TImage then - TImage(ZoomedControl).Stretch := True; -end; - -//- BG ----------------------------------------------------------- 05.11.2006 -- -procedure TBegaZoomBox.doZoomTo(ZoomTo: Double; Width, Height, BoxWidth, BoxHeight: Integer); -begin - inherited; - if ZoomedControl is TImage then - TImage(ZoomedControl).Stretch := ZoomTo <> 1.0; - ZoomedControl.setBounds( - (BoxWidth - Width) div 2, - (BoxHeight - Height) div 2, - Width, Height); -end; - -//- BG ----------------------------------------------------------- 23.01.2006 -- -function TBegaZoomBox.getZoomedControl: TControl; -begin - if ControlCount > 0 then - Result := Controls[0] - else - Result := nil; -end; - -{$endif NoFlatScrollbars} -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/BuffConv.pas b/CORE/Source/Plugins/Htmlviewer/source/BuffConv.pas deleted file mode 100644 index c86fdbf6c..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/BuffConv.pas +++ /dev/null @@ -1,2037 +0,0 @@ -{ -HtmlViewer Version 11.7 -Copyright (c) 2010-2016 by Bernd Gabriel - -This source module is based on code of CodeChangerDecode.pas written by SchwarzKopf-M (SchwarzKopf-M@yandex.ru) -and the source code library libiconv, which is published under the GNU Library General Public License. - -Thanks to SchwarzKopf-M for his extensive work. - -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. - -Note that the source modules HTMLGIF1.PAS and DITHERUNIT.PAS -are covered by separate copyright notices located in those modules. -} - -//This is the original copyright notice in CodeChangerDecode.pas - -//This is charset Windows-1251: -//Ìîäóëü ïåðåêîäèðîâêè òåêñòà ÿâëÿåòñÿ ñâîáîäíî ðàñïðîñòðàíÿåìûì è ðàñïðîñòðàíÿåòñÿ "Êàê åñòü". -//Ïðè ìîäèôèêàöèè èëè ÷àñòè÷íîì èñïîëüçîâàíèè èñõîäíîãî êîäà ññûëêè -// íà îðèãèíàëüíûé ìîäóëü îáÿçàòåëüíû. -//Àâòîðñêîå ïðàâî îñòàâëÿþ çà ñîáîé - SchwarzKopf-M (SchwarzKopf-M@yandex.ru). -// äàííîì ìîäóëå èñïîëüçóåòñÿ èíôîðìàöèÿ íàéäåííàÿ â Èíòåðíåòå -// áåç íàðóøåíèÿ èñõîäíûõ àâòîðñêèõ ïðàâ. -//Äëÿ ïåðåêîäèðîâêè íåêîòîðûõ àçèàòñêèõ ÿçûêîâ èñïîëüçîâàëàñü âîëüíàÿ -// èíòåðïðåòàöèÿ èñõîäíûõ êîäîâ áèáëèîòåêè libiconv. -// -//Ñïåöèàëüíî äëÿ HTMLViewer (http://code.google.com/p/thtmlviewer) - -// Translated by "http://translate.google.de/#ru|en|" it is: -// Text conversion module is freeware and is distributed "as is". -// If you modify or partial use of source code links -// To the original module is required. -// Copyright reserve the - SchwarzKopf-M (SchwarzKopf-M@yandex.ru). -// This module uses the information found on the Internet -// Without affecting the original copyright holder. -// For the conversion of some Asian languages ??used in freestyle -// Interpretation of the source code library libiconv. -// -// Especially for HTMLViewer (http://code.google.com/p/thtmlviewer) - -{$I htmlcons.inc} - -unit BuffConv; - -interface - -uses -{$ifdef MSWindows} - Windows, -{$endif} -{$ifdef LCL} - LclIntf, LclType, -{$endif} - SysUtils, - BuffConvArrays, - HtmlGlobals, - HtmlBuffer; - -type - - // BG, 06.10.2012: converts UTF7 to unicode. - TBuffConvUTF7 = class(TBuffConverter) - private - State: Byte; - protected - procedure Assign(Source: TBuffConverter); override; - public - function NextChar: TBuffChar; override; - end; - - // BG, 26.09.2012: converts UTF8 to unicode. - TBuffConvUTF8 = class(TBuffConverter) - public - function NextChar: TBuffChar; override; - end; - - // BG, 28.01.2013: converts several single byte code pages using an AnsiCharMap to unicode. - TBuffConvSingleByteMap = class(TBuffConverter) - private - FMap: ThtAnsiCharMap; - procedure UpdateMap; - protected - procedure Assign(Source: TBuffConverter); override; - public - procedure AfterConstruction; override; - function NextChar: TBuffChar; override; - end; - - // BG, 02.10.2012: converts several single byte code pages using an AnsiCharHighMap to unicode. - TBuffConvHighMap = class(TBuffConverter) - private - FMap: ThtAnsiCharHighMap; - procedure UpdateMap; - protected - procedure Assign(Source: TBuffConverter); override; - public - procedure AfterConstruction; override; - function NextChar: TBuffChar; override; - end; - - // BG, 02.10.2012: converts the single byte code of ISO 8859 using an AnsiCharIsoMap to unicode. - TBuffConvIsoMap = class(TBuffConverter) - private - FMap: ThtAnsiCharISOMap; - procedure UpdateMap; - protected - procedure Assign(Source: TBuffConverter); override; - public - procedure AfterConstruction; override; - function NextChar: TBuffChar; override; - end; - - TBuffBaseConverter = class(TBuffConverter) - protected - function ASCIIDecodeChar(c1: Byte): TBuffChar; - function CP922EstonianDecodeChar(c1: Byte): TBuffChar; - function GB2312DecodeChar(c1, c2: Byte): TBuffChar; - function GBKDecodeChar(c1, c2: Byte): TBuffChar; - function ISO8859_11DecodeChar(c1: Byte): TBuffChar; - function ISO8859_15DecodeChar(c1: Byte): TBuffChar; - function ISO8859_5DecodeChar(c1: Byte): TBuffChar; - function ISO8859_6DecodeChar(c1: Byte): TBuffChar; - function ISO8859_7DecodeChar(c1: Byte): TBuffChar; - function ISO8859_8DecodeChar(c1: Byte): TBuffChar; - function ISO8859_9DecodeChar(c1: Byte): TBuffChar; - function JIS_X0201DecodeChar(c1: Byte): TBuffChar; - function JIS_X0208DecodeChar(c1, c2: Byte): TBuffChar; - function JIS_X0212DecodeChar(c1, c2: Byte): TBuffChar; - function KSC5601DecodeChar(c1, c2: Byte): TBuffChar; - function Latin1EuroDecodeChar(c1: Byte): TBuffChar; - function MultiByteToWideCharDecodeChar(c1: Byte): TBuffChar; - end; - - // BG, 02.10.2012: converts several single byte code pages using one of the *DecoderChar functions to unicode. - TBuffSingleByteDecoder = function(c1: Byte): TBuffChar of object; - TBuffConvSingleByte = class(TBuffBaseConverter) - private - FDecoder: TBuffSingleByteDecoder; - procedure UpdateDecoder; - protected - procedure Assign(Source: TBuffConverter); override; - public - procedure AfterConstruction; override; - function NextChar: TBuffChar; override; - end; - - // BG, 02.10.2012: converts several single byte code pages using one of the *DecoderChar functions to unicode. - TBuffDoubleByteDecoder = function(c1, c2: Byte): TBuffChar of object; - TBuffConvDoubleByte = class(TBuffBaseConverter) - private - FDecoder: TBuffDoubleByteDecoder; - procedure UpdateDecoder; - protected - procedure Assign(Source: TBuffConverter); override; - public - procedure AfterConstruction; override; - function NextChar: TBuffChar; override; - end; - - // BG, 26.09.2012: converts shift-jis (codepages 932, 943) to unicode. - TBuffConvShiftJis932 = class(TBuffConverter) - public - function NextChar: TBuffChar; override; - end; - - // BG, 03.10.2012: converts simplified Chinese (PRC, Singapore) / Chinese simplified (GB2312) to unicode. - TBuffConvIBM936 = class(TBuffBaseConverter) - public - function NextChar: TBuffChar; override; - end; - - // BG, 04.10.2012: converts hangeul (codepage 949 to unicode. - TBuffConvHangeul949 = class(TBuffBaseConverter) - public - function NextChar: TBuffChar; override; - end; - - // BG, 04.10.2012: converts Traditional Chinese (code page 950) to unicode. - TBuffConvBig5CP950 = class(TBuffConverter) - public - function NextChar: TBuffChar; override; - end; - - TBuffConvGB18030 = class(TBuffBaseConverter) - public - function NextChar: TBuffChar; override; - end; - - TBuffConvEUC_JP = class(TBuffBaseConverter) - public - function NextChar: TBuffChar; override; - end; - - TBuffConvISO2022CN = class(TBuffBaseConverter) - private - CNState1: (CNSTATE_ASCII, CNSTATE_TWOBYTE); - CNState2: (CNSTATE2_NONE, STATE2_DESIGNATED_GB2312, STATE2_DESIGNATED_CNS11643_1); - CNState3: (CNSTATE3_NONE, STATE3_DESIGNATED_CNS11643_2); - function CNS11643_1DecodeChar(c1, c2: Word): TBuffChar; - function CNS11643_2DecodeChar(c1, c2: Word): TBuffChar; - protected - procedure Assign(Source: TBuffConverter); override; - public - function NextChar: TBuffChar; override; - end; - - // BG, 27.09.2012: converts stateful ISO-2022-JP, -1, -2 (codepage 50220) to unicode. - TBuffConvISO2022JP = class(TBuffBaseConverter) - private - JPState: ( - JPS_ASCII, - JPS_JISX0201ROMAN, - JPS_JISX0208, - JPS_JISX0212, - JPS_GB2312, - JPS_KSC5601, - JPS_8859_1, - JPS_8859_7); - protected - procedure Assign(Source: TBuffConverter); override; - public - function NextChar: TBuffChar; override; - end; - - TBuffConvISO2022KR = class(TBuffBaseConverter) - private - KRState1: (KRSTATE_ASCII, KRSTATE_TWOBYTE); - KRState2: (KRSTATE2_NONE, STATE2_DESIGNATED_KSC5601); - protected - procedure Assign(Source: TBuffConverter); override; - public - function NextChar: TBuffChar; override; - end; - -implementation - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -function TBuffBaseConverter.MultiByteToWideCharDecodeChar(c1: Byte): TBuffChar; -begin - case c1 of - $00: Result := TBuffChar(c1); - else -{$ifdef MSWindows} - MultiByteToWideChar(FCodePage, 0, PAnsiChar(@c1), 1, @Result, 1) -{$else} - raise Exception.Create('function MultiByteToWideCharDecodeChar() not implemented.'); -{$endif MSWindows} - - end; -end; - -//-- BG ---------------------------------------------------------- 02.10.2012 -- -function TBuffBaseConverter.ASCIIDecodeChar(c1: Byte): TBuffChar; -begin - case c1 of - $00..$7F: Result := TBuffChar(c1); - else - Result := TBuffChar($FFFD); - end; -end; - -//-- BG ---------------------------------------------------------- 02.10.2012 -- -function TBuffBaseConverter.GB2312DecodeChar(c1, c2: Byte): TBuffChar; -var - i: Integer; -begin - case c1 of - $21..$29, $30..$77: - case c2 of - $21..$7E: - begin - i := 94 * (c1 - $21) + (c2 - $21); - case i of - 0.. 830: Result := GB2312_1Map[i]; - 1410..8177: Result := GB2312_2Map[i - 1410]; - else - Result := TBuffChar($FFFD); - end; - end; - else - Result := TBuffChar($FFFD); - end; - else - Result := TBuffChar($FFFD); - end; -end; - -//-- BG ---------------------------------------------------------- 06.10.2012 -- -function TBuffBaseConverter.GBKDecodeChar(c1, c2: Byte): TBuffChar; - - function Offset(cmul, c1, c2: Word): Integer; - begin - case c2 of - $40..$7E: Result := cmul * (c1 - $81) + (c2 - $40); - $80..$FE: Result := cmul * (c1 - $81) + (c2 - $41); - else - Result := MaxInt; - end; - end; - -var - i: Integer; -begin - case c1 of - $81..$A0: - begin - Result := GBKE_1Map[Offset(190, c1, c2)]; - Exit; - end; - - $A1: - case c2 of - $A4: Result := TBuffChar($00B7); - $AA: Result := TBuffChar($2014); - else - Result := GB2312DecodeChar(c1 - $80, c2 - $80); - end; - - $A2: - case c2 of - $A1..$AA: Result := TBuffChar($2170 + (c2 - $A1)); - else - Result := GB2312DecodeChar(c1 - $80, c2 - $80); - end; - else - Result := GB2312DecodeChar(c1 - $80, c2 - $80); - end; - if Result <> TBuffChar(#$FFFD) then - Exit; - - case c1 of - $A6, $A8: - begin - i := Offset(190, c1, c2); - case i of - 7189..7210: Result := CP936E_1Map[i - 7189]; - 7532..7537: Result := CP936E_2Map[i - 7532]; - end; - if Result <> TBuffChar(#$FFFD) then - exit; - end; - end; - - case c1 of - $A8..$FE: - begin - i := Offset(96, c1, c2); - case i of - 3744..12015: Result := GBKE_2Map[i - 3744]; - end; - if Result <> TBuffChar(#$FFFD) then - exit; - end; - end; - - case c1 of - $A1..$A2: - case c2 of - $40..$7E: Result := TBuffChar($E4C6 + 96 * (c1 - $81) + (c2 - $40)); - $80..$A0: Result := TBuffChar($E4C6 + 96 * (c1 - $A1) + (c2 - $41)); - end; - - $AA..$AF, $F8..$FE: - case c2 of - $A1..$F7: Result := TBuffChar($E000 + 94 * (c1 - $AA) + (c2 - $A1)); - $F8..$FE: Result := TBuffChar($E000 + 94 * (c1 - $F2) + (c2 - $A1)); - end; - end; -end; - -//-- BG ---------------------------------------------------------- 04.10.2012 -- -function TBuffBaseConverter.JIS_X0201DecodeChar(c1: Byte): TBuffChar; -begin - case c1 of - $5C: Result := #$00A5; - $7E: Result := #$203E; - $A1..$DF: Result := TBuffChar(c1 + $FEC0); - else - Result := TBuffChar($FFFD); - end; -end; - -//-- BG ---------------------------------------------------------- 04.10.2012 -- -function TBuffBaseConverter.JIS_X0208DecodeChar(c1, c2: Byte): TBuffChar; -var - i: Integer; -begin - case c1 of - $21..$27, $30..$73: - case c2 of - $21..$7E: - begin - i := 94 * (c1 - $21) + (c2 - $21); - case i of - 0.. 689: Result := JIS_X0208_1Map[i]; - 1410..7807: Result := JIS_X0208_2Map[i - 1410]; - else - Result := TBuffChar($FFFD); - end; - end; - else - Result := TBuffChar($FFFD); - end; - else - Result := TBuffChar($FFFD); - end; -end; - -//-- BG ---------------------------------------------------------- 04.10.2012 -- -function TBuffBaseConverter.JIS_X0212DecodeChar(c1, c2: Byte): TBuffChar; -var - i: Integer; -begin - case c1 of - $22, $26..$27, $29..$2B, $30..$6D: - case c2 of - $21..$7E: - begin - i := 94 * (c1 - $21) + (c2 - $21); - case i of - 0.. 174: Result := JIS_X0212_1Map[i - 94]; - 470.. 657: Result := JIS_X0212_2Map[i - 470]; - 752..1026: Result := JIS_X0212_3Map[i - 752]; - 1410..7210: Result := JIS_X0212_4Map[i - 1410]; - else - Result := TBuffChar($FFFD); - end; - end; - else - Result := TBuffChar($FFFD); - end; - else - Result := TBuffChar($FFFD); - end; -end; - -//-- BG ---------------------------------------------------------- 02.10.2012 -- -function TBuffBaseConverter.KSC5601DecodeChar(c1, c2: Byte): TBuffChar; -var - i: Integer; -begin - case c1 of - $21..$2C, $30..$48, $4A..$7D: - case c2 of - $21..$7E: - begin - i := 94 * (c1 - $21) + (c2 - $21); - case i of - 0..1114: Result := KSC5601_1Map[i]; - 1410..3759: Result := KSC5601_2Map[i - 1410]; - 3854..8741: Result := KSC5601_3Map[i - 3854]; - else - Result := TBuffChar($FFFD); - end; - end; - else - Result := TBuffChar($FFFD); - end; - else - Result := TBuffChar($FFFD); - end; -end; - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -function TBuffBaseConverter.ISO8859_5DecodeChar(c1: Byte): TBuffChar; -begin - case c1 of - $00..$A0, $AD: Result := TBuffChar(c1); - $F0 : Result := #$2116; - $FD : Result := #$00A7; - else - Result := TBuffChar(c1 + $0360); - end; -end; - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -function TBuffBaseConverter.ISO8859_6DecodeChar(c1: Byte): TBuffChar; -begin - case c1 of - $00..$A0, $A4, $AD : Result := TBuffChar(c1); - $AC, $BB, $BF, $C1..$DA, $E0..$F2: Result := TBuffChar(c1 + $0580); - else - Result := TBuffChar($FFFD); - end; -end; - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -function TBuffBaseConverter.ISO8859_7DecodeChar(c1: Byte): TBuffChar; -begin - case c1 of - $00..$A0, $A6..$A9, $AB..$AD, - $B0..$B3, $B7, $BB, $BD: Result := TBuffChar(c1); - $A1 : Result := #$2018; - $A2 : Result := #$2019; - $AF : Result := #$2015; - $D2, $FF: Result := #$FFFF; - else - Result := TBuffChar(c1 + $02D0); - end; -end; - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -function TBuffBaseConverter.ISO8859_8DecodeChar(c1: Byte): TBuffChar; -begin - case c1 of - $00..$A0, $A2..$A9, $AB..$AE, - $B0..$B9, $BB..$BE: Result := TBuffChar(c1); - $AA : Result := #$00D7; - $AF : Result := #$203E; - $BA : Result := #$00F7; - $DF : Result := #$2017; - $E0..$FA: Result := TBuffChar(c1 + $04E0); - else - Result := TBuffChar($FFFD); - end; -end; - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -function TBuffBaseConverter.ISO8859_9DecodeChar(c1: Byte): TBuffChar; -begin - case c1 of - $D0: Result := #$011E; - $DD: Result := #$0130; - $DE: Result := #$015E; - $F0: Result := #$011F; - $FD: Result := #$0131; - $FE: Result := #$015F; - else - Result := TBuffChar(c1); - end; -end; - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -function TBuffBaseConverter.ISO8859_11DecodeChar(c1: Byte): TBuffChar; -begin - case c1 of - $00..$A0: Result := TBuffChar(c1); - $A1..$DA, - $DF..$FB: Result := TBuffChar(c1 + $0D60); - else - Result := TBuffChar($FFFD); - end; -end; - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -function TBuffBaseConverter.ISO8859_15DecodeChar(c1: Byte): TBuffChar; -begin - case c1 of - $A4: Result := #$20AC; - $A6: Result := #$00A6; - $A8: Result := #$0161; - $B4: Result := #$017D; - $B8: Result := #$017E; - $BC: Result := #$0152; - $BD: Result := #$0153; - $BE: Result := #$0178; - else - Result := TBuffChar(c1); - end; -end; - -//-- BG ---------------------------------------------------------- 03.10.2012 -- -function TBuffBaseConverter.Latin1EuroDecodeChar(c1: Byte): TBuffChar; -begin - case c1 of - $00..$7F: Result := TBuffChar(c1); - $D5: Result := #$20AC; - else - Result := CP850Map[c1]; - end; -end; - -//-- BG ---------------------------------------------------------- 03.10.2012 -- -function TBuffBaseConverter.CP922EstonianDecodeChar(c1: Byte): TBuffChar; -begin - case c1 of - $A0..$AF: Result := CP922_1Map[c1 - $A0]; - $D0..$DF: Result := CP922_2Map[c1 - $D0]; - $F0..$FF: Result := CP922_3Map[c1 - $F0]; - else - Result := TBuffChar(c1); - end; -end; - -{ TBuffConvSingleByte } - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -procedure TBuffConvSingleByte.AfterConstruction; -begin - inherited; - UpdateDecoder; -end; - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -procedure TBuffConvSingleByte.Assign(Source: TBuffConverter); -begin - inherited; - UpdateDecoder; -end; - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -function TBuffConvSingleByte.NextChar: TBuffChar; -begin - Result := FDecoder(GetNext); -end; - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -procedure TBuffConvSingleByte.UpdateDecoder; -begin - case FCodePage of - 858: FDecoder := Latin1EuroDecodeChar; - 922: FDecoder := CP922EstonianDecodeChar; - 28595: FDecoder := ISO8859_5DecodeChar; - 28596: FDecoder := ISO8859_6DecodeChar; - 28597: FDecoder := ISO8859_7DecodeChar; - 28598: FDecoder := ISO8859_8DecodeChar; - 28599: FDecoder := ISO8859_9DecodeChar; - 28601: FDecoder := ISO8859_11DecodeChar; - 28605: FDecoder := ISO8859_15DecodeChar; - else - FDecoder := MultiByteToWideCharDecodeChar; - end; -end; - -{ TBuffConvDoubleByte } - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -procedure TBuffConvDoubleByte.AfterConstruction; -begin - inherited; - UpdateDecoder; -end; - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -procedure TBuffConvDoubleByte.Assign(Source: TBuffConverter); -begin - inherited; - UpdateDecoder; -end; - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -function TBuffConvDoubleByte.NextChar: TBuffChar; -var - c1: Word; -begin - c1 := GetNext; - case c1 of - $00..$80: Result := TBuffChar(c1); - $A1..$FE: Result := FDecoder(c1 - $80, GetNext - $80); - else - Result := TBuffChar($FFFD); - end; -end; - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -procedure TBuffConvDoubleByte.UpdateDecoder; -begin - case FCodePage of - 51936: FDecoder := GB2312DecodeChar; - 51949: FDecoder := KSC5601DecodeChar; - end; -end; - -{ TBuffConvUTF8 } - -//-- BG ---------------------------------------------------------- 26.09.2012 -- -function TBuffConvUTF8.NextChar: TBuffChar; -const - MaxChar: LongWord = 65535; // "Not A Character" -var - Buffer: LongWord; - Chr, Cnt: Word; - - function NextByte: Boolean; - begin - Chr := GetNext; - Inc(Cnt); - Result := (Chr and $C0) = $80; - Buffer := (Buffer shl 6) + (Chr and $3F); - end; - - procedure Failed; - begin - if Chr = 0 then - Buffer := 0 - else - Buffer := MaxChar; - Dec(FPos.BytePtr, Cnt); - end; - -begin - Buffer := GetNext; - case Buffer of - $00..$7F: // 1 byte, 7 bits - ; - - $C0..$DF: // 2 bytes, 11 bits - begin - Buffer := Buffer and $1F; - Cnt := 0; - if not NextByte then - Failed; // invalid - end; - - $E0..$EF: // 3 bytes, 16 bits - begin - Buffer := Buffer and $0F; - Cnt := 0; - if not (NextByte and NextByte) then - Failed; // invalid - end; - - $F0..$F7: // 4 bytes, 21 bits - begin - Buffer := Buffer and $07; - Cnt := 0; - if not (NextByte and NextByte and NextByte) then - Failed // invalid - else if Buffer > MaxChar then - Buffer := MaxChar; - end; - - $F8..$FB: // 5 bytes, 26 bits - begin - Buffer := Buffer and $03; - Cnt := 0; - if not (NextByte and NextByte and NextByte and NextByte) then - Failed // invalid - else if Buffer > MaxChar then - Buffer := MaxChar; - end; - - $FC..$FD: // 6 bytes, 31 bits - begin - Buffer := Buffer and $01; - Cnt := 0; - if not (NextByte and NextByte and NextByte and NextByte and NextByte) then - Failed // invalid - else if Buffer > MaxChar then - Buffer := MaxChar; - end; - - else - // $80..$BF, // invalid - // $FE..$FF: - Buffer := MaxChar; - end; - Result := TBuffChar(Buffer); -end; - -{ TBuffConvSingleByteMap } - -//-- BG ---------------------------------------------------------- 28.01.2013 -- -procedure TBuffConvSingleByteMap.AfterConstruction; -begin - inherited; - UpdateMap; -end; - -//-- BG ---------------------------------------------------------- 28.01.2013 -- -procedure TBuffConvSingleByteMap.Assign(Source: TBuffConverter); -begin - inherited; - UpdateMap; -end; - -//-- BG ---------------------------------------------------------- 28.01.2013 -- -function TBuffConvSingleByteMap.NextChar: TBuffChar; -begin - Result := FMap[GetNext]; -end; - -//-- BG ---------------------------------------------------------- 28.01.2013 -- -procedure TBuffConvSingleByteMap.UpdateMap; -begin - case CodePage of - 29001: FMap := CP29001; - end; -end; - -{ TBuffConvHighMap } - -//-- BG ---------------------------------------------------------- 02.10.2012 -- -procedure TBuffConvHighMap.AfterConstruction; -begin - inherited; - UpdateMap; -end; - -//-- BG ---------------------------------------------------------- 02.10.2012 -- -procedure TBuffConvHighMap.Assign(Source: TBuffConverter); -begin - inherited; - UpdateMap; -end; - -//-- BG ---------------------------------------------------------- 02.10.2012 -- -function TBuffConvHighMap.NextChar: TBuffChar; -begin - Result := TBuffChar(GetNext); - case Ord(Result) of - $80..$FF: Result := FMap[Ord(Result)]; - end; -end; - -//-- BG ---------------------------------------------------------- 02.10.2012 -- -procedure TBuffConvHighMap.UpdateMap; -begin - case CodePage of - 437: FMap := CP437Map; - 708: FMap := Windows708Map; - 737: FMap := Windows737Map; - 775: FMap := Windows775Map; - 850: FMap := CP850Map; - 852: FMap := CP852Map; - 855: FMap := CP855Map; - 857: FMap := CP857Map; - 860: FMap := IBM860Map; - 861: FMap := CP861Map; - 862: FMap := CP862Map; - 863: FMap := CP863Map; - 864: FMap := Windows864Map; - 865: FMap := CP865Map; - 866: FMap := CP866Map; - 869: FMap := CP869Map; - 874: FMap := Windows874Map; - 1250: FMap := CP1250Map; - 1251: FMap := CP1251Map; - 1252: FMap := CP1252Map; - 1253: FMap := CP1253Map; - 1254: FMap := CP1254Map; - 1255: FMap := CP1255Map; - 1256: FMap := CP1256Map; - 1257: FMap := CP1257Map; - 1258: FMap := CP1258Map; - 10000: FMap := MacRomanMap; - 10004: FMap := MacArabicMap; - 10005: FMap := MacHebrewMap; - 10006: FMap := MacGreekMap; - 10007: FMap := MacCyrillicMap; - 10010: FMap := MacRomaniaMap; - 10017: FMap := MacUkraineMap; - 10021: FMap := MacThaiMap; - 10029: FMap := MacCentralEuropeMap; - 10079: FMap := MacIcelandicMap; - 10081: FMap := MacTurkishMap; - 10082: FMap := MacCroatianMap; - 20866: FMap := KOI8_RMap; - end; -end; - -{ TBuffConvIsoMap } - -//-- BG ---------------------------------------------------------- 04.10.2012 -- -procedure TBuffConvIsoMap.AfterConstruction; -begin - inherited; - UpdateMap; -end; - -//-- BG ---------------------------------------------------------- 04.10.2012 -- -procedure TBuffConvIsoMap.Assign(Source: TBuffConverter); -begin - inherited; - UpdateMap; -end; - -//-- BG ---------------------------------------------------------- 04.10.2012 -- -function TBuffConvIsoMap.NextChar: TBuffChar; -begin - Result := TBuffChar(GetNext); - case Ord(Result) of - $A0..$FF: Result := FMap[Ord(Result)]; - end; -end; - -//-- BG ---------------------------------------------------------- 04.10.2012 -- -procedure TBuffConvIsoMap.UpdateMap; -begin - case CodePage of - 28592: FMap := ISO8859_2Map; - 28593: FMap := ISO8859_3Map; - 28594: FMap := ISO8859_4Map; - 28600: FMap := ISO8859_10Map; - 28603: FMap := ISO8859_13Map; - 28604: FMap := ISO8859_14Map; - 28606: FMap := ISO8859_16Map; - end; -end; - -{ TBuffConvShiftJis932 } - -//-- BG ---------------------------------------------------------- 02.10.2012 -- -function TBuffConvShiftJis932.NextChar: TBuffChar; -var c1, c2, t1, t2, i, a, b: Word; - WC: TBuffChar; -begin - c1 := GetNext; - Result := TBuffChar(c1); - case c1 of - $00..$80: ; - // done above: Result := TBuffChar(c1); - - $A1..$DF: - Result := TBuffChar(c1 + $FEC0); - - $81..$86, $88..$9F, $E0..$EA: - begin - c2 := GetNext; - case c2 of - $40..$7E, $80..$FC: - begin - if c1 < $E0 then - t1 := c1 - $81 - else - t1 := c1 - $C1; - - if c2 < $80 then - t2 := c2 - $40 - else - t2 := c2 - $41; - - if t2 < $5E then - begin - c1 := 2 * t1 + 0 + $21; - c2 := t2 + $21; - end - else - begin - c1 := 2 * t1 + 1 + $21; - c2 := t2 - $5E + $21; - end; - - case c1 of - $21..$28, $30..$74: - case c2 of - $21..$7E: - begin - i := 94 * (c1 - $21) + (c2 - $21); - WC := #$FFFD; - if i < 1410 then - begin - if i < 690 then - WC := JIS_X0208_1Map[i]; - end - else - begin - if i < 7808 then - WC := JIS_X0208_2Map[i - 1410]; - end; - if WC <> #$FFFD then - Result := WC; - end; - end; - end; - end; - end; - end; - - $87, $ED..$EE, $FA..$FC: - begin - c2 := GetNext; - case c2 of - $40..$7E, $80..$FC: - begin - if c1 >= $E0 then - a := $C1 - else - a := $81; - - if c2 >= $80 then - b := $41 - else - b := $40; - - i := 188 * (c1 - a) + (c2 - b); - WC := #$FFFD; - if i < 8272 then - begin - if i < 1220 then - WC := CP932E_1Map[i - 1128]; - end - else if i < 10716 then - begin - if i < 8648 then - WC := CP932E_2Map[i - 8272] - end - else - begin - if i < 11104 then - WC := CP932E_3Map[i - 10716]; - end; - if WC <> #$FFFD then - Result := WC; - end; - end; - end; - - $F0..$F9: - begin - c2 := GetNext; - case c2 of - $40..$7E: Result := TBuffChar($E000 + 188 * (c1 - $F0) + (c2 - $40)); - $80..$FC: Result := TBuffChar($E000 + 188 * (c1 - $F0) + (c2 - $41)); - end; - end; - end; -end; - -{ TBuffConvIBM936 } - -//-- BG ---------------------------------------------------------- 03.10.2012 -- -function TBuffConvIBM936.NextChar: TBuffChar; -var - c1: Word; -begin - c1 := GetNext; - case c1 of - $00..$7F: Result := TBuffChar(c1); - $80: Result := TBuffChar($20AC); - else - // two byte code - Result := GBKDecodeChar(c1, GetNext); - end; -end; - -{ TBuffConvHangeul949 } - -//-- BG ---------------------------------------------------------- 04.10.2012 -- -function TBuffConvHangeul949.NextChar: TBuffChar; - - function UHC1Decode(row, col: Integer): TBuffChar; - var - I: Integer; - begin - i := 178 * row + col; - if i < 5696 then - begin - if col >= 89 then - Result := TBuffChar(UHC_1_1Map[2 * row + 1] + UHC_1_2Map[i]) - else - Result := TBuffChar(UHC_1_1Map[2 * row] + UHC_1_2Map[i]) - end - else - Result := #$FFFD; - end; - - function UHC2Decode(row, col: Integer): TBuffChar; - var - I: Integer; - begin - i := 84 * row + col; - if i < 3126 then - begin - if col >= 42 then - Result := TBuffChar(UHC_2_1Map[2 * row + 1] + UHC_2_2Map[i]) - else - Result := TBuffChar(UHC_2_1Map[2 * row] + UHC_2_2Map[i]) - end - else - Result := #$FFFD; - end; - - function KSC5601Decode(c1, c2: Integer): TBuffChar; - begin - Result := KSC5601DecodeChar(c1 - $80, c2 - $80); - end; - -var - c1, c2: Word; -begin - c1 := GetNext; - case c1 of - $00..$7F: Result := TBuffChar(c1); - - $81..$A0: - begin - c2 := GetNext; - case c2 of - $40..$5A: Result := UHC1Decode(c1 - $81, c2 - $41); - $61..$7A: Result := UHC1Decode(c1 - $81, c2 - $47); - $81..$FE: Result := UHC1Decode(c1 - $81, c2 - $4D); - else - Result := TBuffChar($FFFD); - end; - end; - - $A1..$C5: - begin - c2 := GetNext; - case c2 of - $40..$5A: Result := UHC2Decode(c1 - $A1, c2 - $41); - $61..$7A: Result := UHC2Decode(c1 - $A1, c2 - $47); - $81..$A0: Result := UHC2Decode(c1 - $A1, c2 - $4D); - - $A1..$E7, - $E9..$FE: Result := KSC5601Decode(c1, c2); - - $E8: - if c1 <> $A2 then - Result := KSC5601Decode(c1, c2) - else - Result := TBuffChar($FFFD); - - else - Result := TBuffChar($FFFD); - end; - end; - - $C6..$FD: - begin - c2 := GetNext; - Result := KSC5601Decode(c1, c2); - end; - - $FE: - begin - c2 := GetNext; - Result := TBuffChar($E000 + (c2 - $A1)); - end; - - else - Result := TBuffChar($FFFD); - end; -end; - -{ TBuffConvBig5CP950 } - -//-- BG ---------------------------------------------------------- 04.10.2012 -- -function TBuffConvBig5CP950.NextChar: TBuffChar; - - function CP950Decode1(row, col: Integer): TBuffChar; - var - i: Integer; - begin - i := 157 * row + col; - Result := CP950Map[i]; - end; - - function BIG5Decode(row, col: Integer): TBuffChar; - var - i: Integer; - begin - i := 157 * row + col; - case i of - 0.. 6120: Result := BIG5_1Map[i]; - 6280..13931: Result := BIG5_2Map[i - 6280]; - else - Result := TBuffChar($FFFD); - end; - end; - -var - c1, c2, cc: Word; -begin - c1 := GetNext; - case c1 of - $00..$7F: Result := TBuffChar(c1); // ANSI/ASCII - $80, $FF: Result := TBuffChar($FFFD); // undefined - $81..$A0: Result := TBuffChar($FFFD); // private - - $A1..$A2: - begin - c2 := GetNext; - case c2 of - $40..$7E: Result := CP950Decode1(c1 - $A1, c2 - $40); - $A1..$FE: Result := CP950Decode1(c1 - $A1, c2 - $62); - else - Result := TBuffChar($FFFD); - end; - end; - - $A3..$F9: - begin - c2 := GetNext; - cc := c1 shl 8 + c2; - case cc of - $A3E1: Result := TBuffChar($20AC); // Euro sign - $C6A1..$C6FE, - $C800..$C8FE: Result := TBuffChar($FFFD); // private - $F9D6..$F9FE: Result := CP950EMap[c2 - $D6]; - $F9FF..$FEFE: Result := TBuffChar($FFFD); // private - else - case c2 of - $40..$7E: Result := BIG5Decode(c1 - $A1, c2 - $40); - $A1..$FE: Result := BIG5Decode(c1 - $A1, c2 - $62); - else - Result := TBuffChar($FFFD); - end; - end; - end; - else - Result := TBuffChar($FFFD); - end; -end; - -{ TBuffConvEUC_JP } - -function TBuffConvEUC_JP.NextChar: TBuffChar; -var - c1, c2, c3: Word; -begin - c1 := GetNext; - case c1 of - $00..$7F: Result := TBuffChar(c1); // ANSI/ASCII - - $8E: - begin - // two byte code - c2 := GetNext; - case c2 of - $A1..$DF: Result := JIS_X0201DecodeChar(c2); - else - Result := TBuffChar($FFFD); - end; - end; - - $8F: - begin - // three byte code - c2 := GetNext; - c3 := GetNext; - case c2 of - $A1..$F4: - case c3 of - $A1..$FE: Result := JIS_X0212DecodeChar(c2 - $80, c3 - $80); - else - Result := TBuffChar($FFFD); - end; - - $F5..$FE: - case c3 of - $A1..$FE: Result := TBuffChar($E3AC + 94 * (c2 - $F5) + (c3 - $A1)); - else - Result := TBuffChar($FFFD); - end; - else - Result := TBuffChar($FFFD); - end; - end; - - $A1..$F4: - begin - // two byte code - c2 := GetNext; - Result := JIS_X0208DecodeChar(c1 - $80, c2 - $80); - end; - - $F5..$FE: - begin - // two byte code - c2 := GetNext; - case c2 of - $A1..$FE: Result := TBuffChar($E000 + 94 * (c1 - $F5) + (c2 - $A1)); - else - Result := TBuffChar($FFFD); - end; - end; - - else - // $80..$A0, $FF: - Result := TBuffChar($FFFD); - end; -end; - -{ TBuffConvISO2022CN } - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -procedure TBuffConvISO2022CN.Assign(Source: TBuffConverter); -var - Src: TBuffConvISO2022CN absolute Source; -begin - inherited; - if Source is TBuffConvISO2022CN then - begin - CNState1 := Src.CNState1; - CNState2 := Src.CNState2; - CNState3 := Src.CNState3; - end - else - begin - CNState1 := CNSTATE_ASCII; - CNState2 := CNSTATE2_NONE; - CNState3 := CNSTATE3_NONE; - end; -end; - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -function TBuffConvISO2022CN.CNS11643_1DecodeChar(c1, c2: Word): TBuffChar; -var - i: Integer; -begin - case c1 of - $21..$27, $42, $44..$7D: - begin - case c2 of - $21..$7E: - begin - i := 94 * (Ord(c1) - $21) + (Ord(c2) - $21); - case i of - 0.. 499: Result := CNS11643_1_1Map[i]; - 571: Result := TBuffChar($4EA0); - 578: Result := TBuffChar($51AB); - 583: Result := TBuffChar($52F9); - 3102..3134: Result := CNS11643_1_2Map[i - 3102]; - 3290..8690: Result := CNS11643_1_3Map[i - 3290]; - else - Result := TBuffChar(#$FFFD); - end; - end; - else - Result := TBuffChar(#$FFFD); - end; - end; - else - Result := TBuffChar(#$FFFD); - end; -end; - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -function TBuffConvISO2022CN.CNS11643_2DecodeChar(c1, c2: Word): TBuffChar; -var - i: Integer; -begin - case c1 of - $21..$72: - case c2 of - $21..$7E: - begin - i := 94 * (c1 - $21) + (c2 - $21); - if i < 7650 then - Result := CNS11643_2Map[i] - else - Result := TBuffChar(#$FFFD); - end; - else - Result := TBuffChar(#$FFFD); - end; - else - Result := TBuffChar(#$FFFD); - end; -end; - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -function TBuffConvISO2022CN.NextChar: TBuffChar; -var - c1, c2: Word; - Pos: PAnsiChar; -begin - repeat - c1 := GetNext; - case c1 of - $1B: - if FEnd.AnsiChr - FPos.AnsiChr >= 2 then - begin - Pos := FPos.AnsiChr; - case TBuffChar(GetNext) of - '$': - case TBuffChar(GetNext) of - ')': - case TBuffChar(GetNext) of - 'A': - begin - CNState2 := STATE2_DESIGNATED_GB2312; - Continue; - end; - - 'G': - begin - CNState2 := STATE2_DESIGNATED_CNS11643_1; - Continue; - end; - end; - - '*': - case TBuffChar(GetNext) of - 'H': - begin - CNState3 := STATE3_DESIGNATED_CNS11643_2; - Continue; - end; - end; - end; - - 'N': - case CNState3 of - - CNSTATE3_NONE: - Break; - - STATE3_DESIGNATED_CNS11643_2: - begin - // do not use both GetNexts as parameters. You don't know which parameter is processed first! - c2 := GetNext; - Result := CNS11643_2DecodeChar(c2, GetNext); - Exit; - end; - - end; - end; - FPos.AnsiChr := Pos; - end; - - $0E: - begin - if (CNState2 <> STATE2_DESIGNATED_GB2312) and (CNState2 <> STATE2_DESIGNATED_CNS11643_1) then - Break; - CNState1 := CNSTATE_TWOBYTE; - Continue; - end; - - $0F: - begin - CNState1 := CNSTATE_ASCII; - Continue; - end; - - end; - break; - until false; - - case CNState1 of - CNSTATE_ASCII: - begin - Result := ASCIIDecodeChar(c1); - case Result of - #$000A, #$000D: - begin - CNState2 := CNSTATE2_NONE; - CNState3 := CNSTATE3_NONE; - end; - end; - end; - - CNSTATE_TWOBYTE: - begin - c2 := GetNext; - case CNState2 of - STATE2_DESIGNATED_GB2312: Result := GB2312DecodeChar(c1, c2); - STATE2_DESIGNATED_CNS11643_1: Result := CNS11643_1DecodeChar(c1, c2); - else - Result := TBuffChar(#$FFFD); - end; - end; - else - Result := TBuffChar(#$FFFD); - end; -end; - -{ TBuffConvISO2022KR } - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -procedure TBuffConvISO2022KR.Assign(Source: TBuffConverter); -var - Src: TBuffConvISO2022KR absolute Source; -begin - inherited; - if Source is TBuffConvISO2022KR then - begin - KRState1 := Src.KRState1; - KRState2 := Src.KRState2; - end - else - begin - KRState1 := KRSTATE_ASCII; - KRState2 := KRSTATE2_NONE; - end; -end; - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -function TBuffConvISO2022KR.NextChar: TBuffChar; -var - c1: Word; - Pos: PAnsiChar; -begin - repeat - c1 := GetNext; - case c1 of - $1B: - if FEnd.AnsiChr - FPos.AnsiChr >= 2 then - begin - Pos := FPos.AnsiChr; - case TBuffChar(GetNext) of - '$': - case TBuffChar(GetNext) of - ')': - case TBuffChar(GetNext) of - 'C': - begin - KRState2 := STATE2_DESIGNATED_KSC5601; - Continue; - end; - end; - end; - end; - FPos.AnsiChr := Pos; - end; - - $0E: - begin - if KRState2 <> STATE2_DESIGNATED_KSC5601 then - Break; - KRState1 := KRSTATE_TWOBYTE; - Continue; - end; - - $0F: - begin - KRState1 := KRSTATE_ASCII; - Continue; - end; - - end; - Break; - until False; - - case KRState1 of - KRSTATE_ASCII: - begin - Result := ASCIIDecodeChar(c1); - case Result of - #$000A, #$000D: - KRState2 := KRSTATE2_NONE; - end; - end; - - KRSTATE_TWOBYTE: - begin - if KRState2 <> STATE2_DESIGNATED_KSC5601 then - begin - Result := TBuffChar(#$FFFD); - Exit; - end; - Result := KSC5601DecodeChar(c1, GetNext); - end; - else - Result := TBuffChar(#$FFFD); - end; -end; - -{ TBuffConvISO2022JP } - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -procedure TBuffConvISO2022JP.Assign(Source: TBuffConverter); -var - Src: TBuffConvISO2022JP absolute Source; -begin - inherited; - if Source is TBuffConvISO2022JP then - JPState := Src.JPState; -end; - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -function TBuffConvISO2022JP.NextChar: TBuffChar; -var - c1: Word; - Pos: PAnsiChar; -begin - repeat - c1 := GetNext; - case c1 of - $1B: - if FEnd.AnsiChr - FPos.AnsiChr >= 2 then - begin - Pos := FPos.AnsiChr; - case TBuffChar(GetNext) of - '(': - case TBuffChar(GetNext) of - 'B': - begin - JPState := JPS_ASCII; - Continue; - end; - - 'J': - begin - JPState := JPS_JISX0201ROMAN; - Continue; - end; - end; - - '$': - case TBuffChar(GetNext) of - '@', 'B': - begin - JPState := JPS_JISX0208; - Continue; - end; - - 'A': - begin - JPState := JPS_GB2312; - Continue; - end; - - '(': - case TBuffChar(GetNext) of - 'C': - begin - JPState := JPS_KSC5601; - Continue; - end; - - 'D': - begin - JPState := JPS_JISX0212; - Continue; - end; - end; - end; - - '.': - case TBuffChar(GetNext) of - 'A': - begin - JPState := JPS_8859_1; - Continue; - end; - - 'F': - begin - JPState := JPS_8859_7; - Continue; - end; - end; - - end; - FPos.AnsiChr := Pos; - end; - end; - Break; - until False; - - case JPState of - JPS_ASCII: Result := ASCIIDecodeChar(c1); - JPS_8859_1: Result := TBuffChar(c1); - JPS_8859_7: Result := ISO8859_7DecodeChar(c1); - JPS_JISX0201ROMAN: Result := JIS_X0201DecodeChar(c1); - JPS_JISX0208: Result := JIS_X0208DecodeChar(c1, GetNext); - JPS_JISX0212: Result := JIS_X0212DecodeChar(c1, GetNext); - JPS_KSC5601: Result := KSC5601DecodeChar(c1, GetNext); - JPS_GB2312: Result := GB2312DecodeChar(c1, GetNext); - else - Result := TBuffChar($FFFD); - end; -end; - -//-- BG ---------------------------------------------------------- 06.10.2012 -- -function TBuffConvGB18030.NextChar: TBuffChar; - - function GB18030ExtDecode(row, col: Integer): TBuffChar; - var - i: Integer; - begin - i := 190 * row + col; - case i of - 6432: Result := #$20AC; - 7536: Result := #$01F9; - 7672..7684: Result := GB18030Ext_2uni_pagea9[i-7672]; - 23750..23844: Result := GB18030Ext_2uni_pagefe[i-23750]; - else - Result := TBuffChar($FFFD); - end; - end; - - function GB18030Uni1DecodeChar(c1, c2, c3, c4: Byte): TBuffChar; - var - i: Integer; - k, k1, k2: Byte; - begin - case c4 of - $30..$39: - begin - i := (((c1 - $81) * 10 + (c2 - $30)) * 126 + (c3 - $81)) * 10 + (c4 - $30); - case i of - 0..39419: - begin - k1 := 0; - k2 := 193; - while k1 < k2 do - begin - k := (k1 + k2) div 2; - if i <= GB18030Uni_charset2uni_ranges[k shl 1 + 1] then - k2 := k - else if i >= GB18030Uni_charset2uni_ranges[k shl 1 + 2] then - k1 := k + 1 - else - begin - Result := TBuffChar($FFFD); - exit; - end; - end; - Result := TBuffChar(i + gb18030uni_ranges[k1]); - end; - else - Result := TBuffChar($FFFD); - end; - end; - else - Result := TBuffChar($FFFD); - end; - end; - -{$ifdef TBuffChar_Has_At_Least_3_Bytes} - function GB18030Uni2DecodeChar(c1, c2, c3, c4: Byte): TBuffChar; - var - i: Integer; - begin - case c4 of - $30..$39: - begin - i := (((c1 - $90) * 10 + (c2 - $30)) * 126 + (c3 - $81)) * 10 + (c4 - $30); - if (i >= 0) and (i < $100000) then - Result := TBuffChar($10000 + i) - else - Result := TBuffChar($FFFD); - end; - else - Result := TBuffChar($FFFD); - end; - end; -{$endif TBuffChar_Has_At_Least_3_Bytes} - -var - c1, c2, c3, c4: Word; -begin - c1 := GetNext; -{$ifdef TBuffChar_Has_At_Least_3_Bytes} - c2 := 0; - c3 := 0; - c4 := 0; -{$endif TBuffChar_Has_At_Least_3_Bytes} - case c1 of - $00..$7F: Result := ASCIIDecodeChar(c1); - - $81..$84: - begin - // Code set 2 (remainder of Unicode U+0000..U+FFFF) - c2 := GetNext; - case c2 of - $30..$39: - begin - c3 := GetNext; - case c3 of - $81..$FE: - begin - c4 := GetNext; - Result := GB18030Uni1DecodeChar(c1, c2, c3, c4); - end; - else - Result := TBuffChar($FFFD); - end; - end; - else - Result := TBuffChar($FFFD); - end; - end; - - $A2, $A8..$A9, $FE: - begin - // Code set 1 (GBK extended) - c2 := GetNext; - case c2 of - $40..$7E: Result := GB18030ExtDecode(c1 - $81, c2 - $40); - $80..$FE: Result := GB18030ExtDecode(c1 - $81, c2 - $41); - else - Result := TBuffChar($FFFD); - end; - end; - - else - // Code set 1 (GBK extended) - Result := GBKDecodeChar(c1, GetNext); - end; - -{$ifdef TBuffChar_Has_At_Least_3_Bytes} - if Result <> TBuffChar($FFFD) then - exit; - - { Code set 3 (Unicode U+10000..U+10FFFF) } - case c1 of - $90..$E3: - begin - if c2 = 0 then - c2 := GetNext; - case c2 of - $30..$39: - begin - if c3 = 0 then - c3 := GetNext; - case c3 of - $81..$FE: - begin - if c4 = 0 then - c4 := GetNext; - Result := GB18030Uni2DecodeChar(c1, c2, c3, c4); - end; - else - Result := TBuffChar($FFFD); - end; - end; - end; - end; - end; -{$endif TBuffChar_Has_At_Least_3_Bytes} -end; - -{ TBuffConvUTF7 } - -//-- BG ---------------------------------------------------------- 05.10.2012 -- -procedure TBuffConvUTF7.Assign(Source: TBuffConverter); -var - Src: TBuffConvUTF7 absolute Source; -begin - inherited; - if Source is TBuffConvUTF7 then - begin - State := Src.State; - end - else - begin - State := 0; - end; -end; - -//-- BG ---------------------------------------------------------- 06.10.2012 -- -function TBuffConvUTF7.NextChar: TBuffChar; -// Specification: RFC 2152 (and old RFC 1641, RFC 1642) -// The original Base64 encoding is defined in RFC 2045. - - // Set of direct characters: - // A-Z a-z 0-9 ' ( ) , - . / : ? space tab lf cr - function IsDirect(ch: Byte): Boolean; {$ifdef UseInline} inline; {$endif} - const - Tab: array [0..15] of Byte = ( - $00, $26, $00, $00, $81, $f3, $ff, $87, - $fe, $ff, $ff, $07, $fe, $ff, $ff, $07); - begin - Result := (ch < 128) and (((Tab[ch shr 3] shr (ch and 7)) and 1) <> 0); - end; - - // Set of direct and optional direct characters: - // A-Z a-z 0-9 ' ( ) , - . / : ? space tab lf cr - // ! " # $ % & * ; < = > @ [ ] ^ _ ` { | } - function IsXDirect(ch: Byte): Boolean; {$ifdef UseInline} inline; {$endif} - const - Tab: array [0..15] of Byte = ( - $00, $26, $00, $00, $ff, $f7, $ff, $ff, - $ff, $ff, $ff, $ef, $ff, $ff, $ff, $3f); - begin - Result := (ch < 128) and (((Tab[ch shr 3] shr (ch and 7)) and 1) <> 0); - end; - - // Set of base64 characters, extended: - // A-Z a-z 0-9 + / - - function IsXBase64(ch: Byte): Boolean; {$ifdef UseInline} inline; {$endif} - const - Tab: array [0..15] of Byte = ( - $00, $00, $00, $00, $00, $a8, $ff, $03, - $fe, $ff, $ff, $07, $fe, $ff, $ff, $07); - begin - Result := (ch < 128) and (((Tab[ch shr 3] shr (ch and 7)) and 1) <> 0); - end; - -label - active, inactive, none; -var - c1, c2: Byte; - wc: Cardinal; - base64state: Byte; - kmax: Cardinal; // number of payload bytes to read - k: Cardinal; // number of payload bytes already read - base64count: Cardinal; // number of base64 bytes already read - i: Cardinal; -{$ifdef TBuffChar_Has_At_Least_3_Bytes} - wc1, wc2: Cardinal; -{$endif TBuffChar_Has_At_Least_3_Bytes} -begin - c1 := GetNext; - if (state and 3) <> 0 then - goto active - else - goto inactive; - -inactive: - // Here (state & 3) == 0 - if c1 = 0 then - goto none; - - if IsXDirect(c1) then - begin - Result := TBuffChar(c1); - exit; - end; - if c1 = Ord('+') then - begin - c2 := GetNext; - if c2 = Ord('-') then - begin - Result := TBuffChar(c1); - exit; - end; - c1 := c2; - state := 1; - goto active; - end; - Result := TBuffChar($FFFD); -exit; - -active: - // base64 encoding active - wc := 0; - base64state := State; - kmax := 2; - k := 0; - base64count := 0; - i := 0; // valium for the compiler - while c1 <> 0 do - begin - case c1 of - Ord('A')..Ord('Z'): i := c1 - Ord('A'); - Ord('a')..Ord('z'): i := c1 - Ord('a') + 26; - Ord('0')..Ord('9'): i := c1 - Ord('0') + 52; - Ord('+'): i := 62; - Ord('/'): i := 63; - else - // c terminates base64 encoding - if (base64state and Cardinal(-4)) <> 0 then - begin - Result := TBuffChar($FFFD); // data must be 0, otherwise illegal - State := 0; - exit; - end; - if base64count <> 0 then - begin - Result := TBuffChar($FFFD); // partial UTF-16 characters are invalid - State := 0; - exit; - end; - - if c1 = Ord('-') then - c1 := GetNext; - state := 0; - goto inactive; - end; - //s++; - Inc(base64count); - //* read 6 bits: 0 <= i < 64 */ - case base64state and 3 of - 1: // inside base64, no pending bits - begin - base64state := i shl 2; - end; - - 0: // inside base64, 6 bits remain from 1st byte - begin - wc := (wc shl 8) or (base64state and Cardinal(-4)) or (i shr 4); - Inc(k); - base64state := ((i and 15) shl 4) or 2; - end; - - 2: // inside base64, 4 bits remain from 2nd byte - begin - wc := (wc shl 8) or (base64state and Cardinal(-4)) or (i shr 2); - Inc(k); - base64state := ((i and 3) shl 6) or 3; - end; - - 3: // inside base64, 2 bits remain from 3rd byte - begin - wc := (wc shl 8) or (base64state and Cardinal(-4)) or i; - Inc(k); - base64state := 1; - end; - end; - if k = kmax then - begin - // UTF-16: When we see a High Surrogate, we must also decode the following Low Surrogate. - if (kmax = 2) and (wc >= $D800) and (wc <= $DBFF) then - kmax := 4 - else - break; - end; - if base64count <= 0 then - goto none; - c1 := GetNext; - if c1 = 0 then - goto none; - end; - - // Here k = kmax > 0, hence base64count > 0. - if (base64state and 3) = 0 then - Result := TBuffChar($FFFD) - else if kmax = 4 then -{$ifdef TBuffChar_Has_At_Least_3_Bytes} - begin - wc1 := wc shr 16; - wc2 := wc and 0xffff; - if not ((wc1 >= $D800) and (wc1 < $DC00)) then - Result := TBuffChar($FFFD) - else if not ((wc2 >= $DC00) and (wc2 < $E000)) then - Result := TBuffChar($FFFD) - else - Result := $10000 + ((wc1 - $D800) shl 10) + (wc2 - $DC00); - end -{$else TBuffChar_Has_At_Least_3_Bytes} - Result := TBuffChar($FFFD) -{$endif TBuffChar_Has_At_Least_3_Bytes} - else - Result := TBuffChar(wc); - State := base64state; -exit; - -none: - if c1 = 0 then - Result := TBuffChar(0) - else - Result := TBuffChar($FFFD); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/BuffConvArrays.pas b/CORE/Source/Plugins/Htmlviewer/source/BuffConvArrays.pas deleted file mode 100644 index 819d1ebb9..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/BuffConvArrays.pas +++ /dev/null @@ -1,12237 +0,0 @@ -{ -HtmlViewer Version 11.7 -Copyright (c) 2013-2016 by Bernd Gabriel - -This source module is adopted from CodeChangerDecodeMatrix.pas -written by SchwarzKopf-M (SchwarzKopf-M@yandex.ru). - -Thanks to SchwarzKopf-M for his extensive work. - -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. - -Note that the source modules HTMLGIF1.PAS and DITHERUNIT.PAS -are covered by separate copyright notices located in those modules. -} - -//This is the original copyright notice in CodeChangerDecodeMatrix.pas - -//This is charset Windows-1251: -//Ìîäóëü ïåðåêîäèðîâêè òåêñòà ÿâëÿåòñÿ ñâîáîäíî ðàñïðîñòðàíÿåìûì è ðàñïðîñòðàíÿåòñÿ "Êàê åñòü". -//Ïðè ìîäèôèêàöèè èëè ÷àñòè÷íîì èñïîëüçîâàíèè èñõîäíîãî êîäà ññûëêè -// íà îðèãèíàëüíûé ìîäóëü îáÿçàòåëüíû. -//Àâòîðñêîå ïðàâî îñòàâëÿþ çà ñîáîé - SchwarzKopf-M (SchwarzKopf-M@yandex.ru). -// äàííîì ìîäóëå èñïîëüçóåòñÿ èíôîðìàöèÿ íàéäåííàÿ â Èíòåðíåòå -// áåç íàðóøåíèÿ èñõîäíûõ àâòîðñêèõ ïðàâ. -//Äëÿ ïåðåêîäèðîâêè íåêîòîðûõ àçèàòñêèõ ÿçûêîâ èñïîëüçîâàëàñü âîëüíàÿ -// èíòåðïðåòàöèÿ èñõîäíûõ êîäîâ áèáëèîòåêè libiconv. -// -//Ñïåöèàëüíî äëÿ HTMLViewer (http://code.google.com/p/thtmlviewer) - -// Translated by "http://translate.google.de/#ru|en|" it is: -// Text conversion module is freeware and is distributed "as is". -// If you modify or partial use of source code links -// To the original module is required. -// Copyright reserve the - SchwarzKopf-M (SchwarzKopf-M@yandex.ru). -// This module uses the information found on the Internet -// Without affecting the original copyright holder. -// For the conversion of some Asian languages ??used in freestyle -// Interpretation of the source code library libiconv. -// -// Especially for HTMLViewer (http://code.google.com/p/thtmlviewer) - -{.$I htmlcons.inc} - -unit BuffConvArrays; - -interface - -uses - HtmlBuffer; - -type - ThtAnsiCharMap = array[Byte] of TBuffChar; - ThtAnsiCharHighMap = array[$80..$FF] of TBuffChar; - ThtAnsiCharISOMap = array[$A0..$FF] of TBuffChar; - -const - Windows708Map: ThtAnsiCharHighMap = ( - #$2502, #$2524, #$00E9, #$00E2, #$2561, #$00E0, #$2562, #$00E7, - #$00EA, #$00EB, #$00E8, #$00EF, #$00EE, #$2556, #$2555, #$2563, - #$2551, #$2557, #$255D, #$00F4, #$255C, #$255B, #$00FB, #$00F9, - #$2510, #$2514, #$009A, #$009B, #$009C, #$009D, #$009E, #$009F, - #$F8C1, #$2534, #$252C, #$251C, #$00A4, #$2500, #$253C, #$255E, - #$255F, #$255A, #$2554, #$2569, #$060C, #$2566, #$00AB, #$00BB, - #$2591, #$2592, #$2593, #$2560, #$2550, #$256C, #$2567, #$2568, - #$2564, #$2565, #$2559, #$061B, #$2558, #$2552, #$2553, #$061F, - #$256B, #$0621, #$0622, #$0623, #$0624, #$0625, #$0626, #$0627, - #$0628, #$0629, #$062A, #$062B, #$062C, #$062D, #$062E, #$062F, - #$0630, #$0631, #$0632, #$0633, #$0634, #$0635, #$0636, #$0637, - #$0638, #$0639, #$063A, #$2588, #$2584, #$258C, #$2590, #$2580, - #$0640, #$0641, #$0642, #$0643, #$0644, #$0645, #$0646, #$0647, - #$0648, #$0649, #$064A, #$064B, #$064C, #$064D, #$064E, #$064F, - #$0650, #$0651, #$0652, #$F8C2, #$F8C3, #$F8C4, #$F8C5, #$F8C6, - #$F8C7, #$256A, #$2518, #$250C, #$00B5, #$00A3, #$25A0, #$00A0); - Windows737Map: ThtAnsiCharHighMap = ( - #$0391, #$0392, #$0393, #$0394, #$0395, #$0396, #$0397, #$0398, - #$0399, #$039A, #$039B, #$039C, #$039D, #$039E, #$039F, #$03A0, - #$03A1, #$03A3, #$03A4, #$03A5, #$03A6, #$03A7, #$03A8, #$03A9, - #$03B1, #$03B2, #$03B3, #$03B4, #$03B5, #$03B6, #$03B7, #$03B8, - #$03B9, #$03BA, #$03BB, #$03BC, #$03BD, #$03BE, #$03BF, #$03C0, - #$03C1, #$03C3, #$03C2, #$03C4, #$03C5, #$03C6, #$03C7, #$03C8, - #$2591, #$2592, #$2593, #$2502, #$2524, #$2561, #$2562, #$2556, - #$2555, #$2563, #$2551, #$2557, #$255D, #$255C, #$255B, #$2510, - #$2514, #$2534, #$252C, #$251C, #$2500, #$253C, #$255E, #$255F, - #$255A, #$2554, #$2569, #$2566, #$2560, #$2550, #$256C, #$2567, - #$2568, #$2564, #$2565, #$2559, #$2558, #$2552, #$2553, #$256B, - #$256A, #$2518, #$250C, #$2588, #$2584, #$258C, #$2590, #$2580, - #$03C9, #$03AC, #$03AD, #$03AE, #$03CA, #$03AF, #$03CC, #$03CD, - #$03CB, #$03CE, #$0386, #$0388, #$0389, #$038A, #$038C, #$038E, - #$038F, #$00B1, #$2265, #$2264, #$03AA, #$03AB, #$00F7, #$2248, - #$00B0, #$2219, #$00B7, #$221A, #$207F, #$00B2, #$25A0, #$00A0); - Windows775Map: ThtAnsiCharHighMap = ( - #$0106, #$00FC, #$00E9, #$0101, #$00E4, #$0123, #$00E5, #$0107, - #$0142, #$0113, #$0156, #$0157, #$012B, #$0179, #$00C4, #$00C5, - #$00C9, #$00E6, #$00C6, #$014D, #$00F6, #$0122, #$00A2, #$015A, - #$015B, #$00D6, #$00DC, #$00F8, #$00A3, #$00D8, #$00D7, #$00A4, - #$0100, #$012A, #$00F3, #$017B, #$017C, #$017A, #$201D, #$00A6, - #$00A9, #$00AE, #$00AC, #$00BD, #$00BC, #$0141, #$00AB, #$00BB, - #$2591, #$2592, #$2593, #$2502, #$2524, #$0104, #$010C, #$0118, - #$0116, #$2563, #$2551, #$2557, #$255D, #$012E, #$0160, #$2510, - #$2514, #$2534, #$252C, #$251C, #$2500, #$253C, #$0172, #$016A, - #$255A, #$2554, #$2569, #$2566, #$2560, #$2550, #$256C, #$017D, - #$0105, #$010D, #$0119, #$0117, #$012F, #$0161, #$0173, #$016B, - #$017E, #$2518, #$250C, #$2588, #$2584, #$258C, #$2590, #$2580, - #$00D3, #$00DF, #$014C, #$0143, #$00F5, #$00D5, #$00B5, #$0144, - #$0136, #$0137, #$013B, #$013C, #$0146, #$0112, #$0145, #$2019, - #$00AD, #$00B1, #$201C, #$00BE, #$00B6, #$00A7, #$00F7, #$201E, - #$00B0, #$2219, #$00B7, #$00B9, #$00B3, #$00B2, #$25A0, #$00A0); - Windows864Map: ThtAnsiCharHighMap = ( - #$00B0, #$00B7, #$2219, #$221A, #$2592, #$2500, #$2502, #$253C, - #$2524, #$252C, #$251C, #$2534, #$2510, #$250C, #$2514, #$2518, - #$03B2, #$221E, #$03C6, #$00B1, #$00BD, #$00BC, #$2248, #$00AB, - #$00BB, #$FEF7, #$FEF8, #$009B, #$009C, #$FEFB, #$FEFC, #$009F, - #$00A0, #$00AD, #$FE82, #$00A3, #$00A4, #$FE84, #$F8BE, #$F8BF, - #$FE8E, #$FE8F, #$FE95, #$FE99, #$060C, #$FE9D, #$FEA1, #$FEA5, - #$0660, #$0661, #$0662, #$0663, #$0664, #$0665, #$0666, #$0667, - #$0668, #$0669, #$FED1, #$061B, #$FEB1, #$FEB5, #$FEB9, #$061F, - #$00A2, #$FE80, #$FE81, #$FE83, #$FE85, #$FECA, #$FE8B, #$FE8D, - #$FE91, #$FE93, #$FE97, #$FE9B, #$FE9F, #$FEA3, #$FEA7, #$FEA9, - #$FEAB, #$FEAD, #$FEAF, #$FEB3, #$FEB7, #$FEBB, #$FEBF, #$FEC1, - #$FEC5, #$FECB, #$FECF, #$00A6, #$00AC, #$00F7, #$00D7, #$FEC9, - #$0640, #$FED3, #$FED7, #$FEDB, #$FEDF, #$FEE3, #$FEE7, #$FEEB, - #$FEED, #$FEEF, #$FEF3, #$FEBD, #$FECC, #$FECE, #$FECD, #$FEE1, - #$FE7D, #$0651, #$FEE5, #$FEE9, #$FEEC, #$FEF0, #$FEF2, #$FED0, - #$FED5, #$FEF5, #$FEF6, #$FEDD, #$FED9, #$FEF1, #$25A0, #$F8C0); - Windows874Map: ThtAnsiCharHighMap = ( - #$20AC, #$0081, #$0082, #$0083, #$0084, #$2026, #$0086, #$0087, - #$0088, #$0089, #$008A, #$008B, #$008C, #$008D, #$008E, #$008F, - #$0090, #$2018, #$2019, #$201C, #$201D, #$2022, #$2013, #$2014, - #$0098, #$0099, #$009A, #$009B, #$009C, #$009D, #$009E, #$009F, - #$00A0, #$0E01, #$0E02, #$0E03, #$0E04, #$0E05, #$0E06, #$0E07, - #$0E08, #$0E09, #$0E0A, #$0E0B, #$0E0C, #$0E0D, #$0E0E, #$0E0F, - #$0E10, #$0E11, #$0E12, #$0E13, #$0E14, #$0E15, #$0E16, #$0E17, - #$0E18, #$0E19, #$0E1A, #$0E1B, #$0E1C, #$0E1D, #$0E1E, #$0E1F, - #$0E20, #$0E21, #$0E22, #$0E23, #$0E24, #$0E25, #$0E26, #$0E27, - #$0E28, #$0E29, #$0E2A, #$0E2B, #$0E2C, #$0E2D, #$0E2E, #$0E2F, - #$0E30, #$0E31, #$0E32, #$0E33, #$0E34, #$0E35, #$0E36, #$0E37, - #$0E38, #$0E39, #$0E3A, #$F8C1, #$F8C2, #$F8C3, #$F8C4, #$0E3F, - #$0E40, #$0E41, #$0E42, #$0E43, #$0E44, #$0E45, #$0E46, #$0E47, - #$0E48, #$0E49, #$0E4A, #$0E4B, #$0E4C, #$0E4D, #$0E4E, #$0E4F, - #$0E50, #$0E51, #$0E52, #$0E53, #$0E54, #$0E55, #$0E56, #$0E57, - #$0E58, #$0E59, #$0E5A, #$0E5B, #$F8C5, #$F8C6, #$F8C7, #$F8C8); - CP437Map: ThtAnsiCharHighMap = ( - #$00C7, #$00FC, #$00E9, #$00E2, #$00E4, #$00E0, #$00E5, #$00E7, - #$00EA, #$00EB, #$00E8, #$00EF, #$00EE, #$00EC, #$00C4, #$00C5, - #$00C9, #$00E6, #$00C6, #$00F4, #$00F6, #$00F2, #$00FB, #$00F9, - #$00FF, #$00D6, #$00DC, #$00A2, #$00A3, #$00A5, #$20A7, #$0192, - #$00E1, #$00ED, #$00F3, #$00FA, #$00F1, #$00D1, #$00AA, #$00BA, - #$00BF, #$2310, #$00AC, #$00BD, #$00BC, #$00A1, #$00AB, #$00BB, - #$2591, #$2592, #$2593, #$2502, #$2524, #$2561, #$2562, #$2556, - #$2555, #$2563, #$2551, #$2557, #$255D, #$255C, #$255B, #$2510, - #$2514, #$2534, #$252C, #$251C, #$2500, #$253C, #$255E, #$255F, - #$255A, #$2554, #$2569, #$2566, #$2560, #$2550, #$256C, #$2567, - #$2568, #$2564, #$2565, #$2559, #$2558, #$2552, #$2553, #$256B, - #$256A, #$2518, #$250C, #$2588, #$2584, #$258C, #$2590, #$2580, - #$03B1, #$00DF, #$0393, #$03C0, #$03A3, #$03C3, #$00B5, #$03C4, - #$03A6, #$0398, #$03A9, #$03B4, #$221E, #$03C6, #$03B5, #$2229, - #$2261, #$00B1, #$2265, #$2264, #$2320, #$2321, #$00F7, #$2248, - #$00B0, #$2219, #$00B7, #$221A, #$207F, #$00B2, #$25A0, #$00A0); - CP850Map: ThtAnsiCharHighMap = ( - #$00C7, #$00FC, #$00E9, #$00E2, #$00E4, #$00E0, #$00E5, #$00E7, - #$00EA, #$00EB, #$00E8, #$00EF, #$00EE, #$00EC, #$00C4, #$00C5, - #$00C9, #$00E6, #$00C6, #$00F4, #$00F6, #$00F2, #$00FB, #$00F9, - #$00FF, #$00D6, #$00DC, #$00F8, #$00A3, #$00D8, #$00D7, #$0192, - #$00E1, #$00ED, #$00F3, #$00FA, #$00F1, #$00D1, #$00AA, #$00BA, - #$00BF, #$00AE, #$00AC, #$00BD, #$00BC, #$00A1, #$00AB, #$00BB, - #$2591, #$2592, #$2593, #$2502, #$2524, #$00C1, #$00C2, #$00C0, - #$00A9, #$2563, #$2551, #$2557, #$255D, #$00A2, #$00A5, #$2510, - #$2514, #$2534, #$252C, #$251C, #$2500, #$253C, #$00E3, #$00C3, - #$255A, #$2554, #$2569, #$2566, #$2560, #$2550, #$256C, #$00A4, - #$00F0, #$00D0, #$00CA, #$00CB, #$00C8, #$0131, #$00CD, #$00CE, - #$00CF, #$2518, #$250C, #$2588, #$2584, #$00A6, #$00CC, #$2580, - #$00D3, #$00DF, #$00D4, #$00D2, #$00F5, #$00D5, #$00B5, #$00FE, - #$00DE, #$00DA, #$00DB, #$00D9, #$00FD, #$00DD, #$00AF, #$00B4, - #$00AD, #$00B1, #$2017, #$00BE, #$00B6, #$00A7, #$00F7, #$00B8, - #$00B0, #$00A8, #$00B7, #$00B9, #$00B3, #$00B2, #$25A0, #$00A0); - CP852Map: ThtAnsiCharHighMap = ( - #$00C7, #$00FC, #$00E9, #$00E2, #$00E4, #$016F, #$0107, #$00E7, - #$0142, #$00EB, #$0150, #$0151, #$00EE, #$0179, #$00C4, #$0106, - #$00C9, #$0139, #$013A, #$00F4, #$00F6, #$013D, #$013E, #$015A, - #$015B, #$00D6, #$00DC, #$0164, #$0165, #$0141, #$00D7, #$010D, - #$00E1, #$00ED, #$00F3, #$00FA, #$0104, #$0105, #$017D, #$017E, - #$0118, #$0119, #$00AC, #$017A, #$010C, #$015F, #$00AB, #$00BB, - #$2591, #$2592, #$2593, #$2502, #$2524, #$00C1, #$00C2, #$011A, - #$015E, #$2563, #$2551, #$2557, #$255D, #$017B, #$017C, #$2510, - #$2514, #$2534, #$252C, #$251C, #$2500, #$253C, #$0102, #$0103, - #$255A, #$2554, #$2569, #$2566, #$2560, #$2550, #$256C, #$00A4, - #$0111, #$0110, #$010E, #$00CB, #$010F, #$0147, #$00CD, #$00CE, - #$011B, #$2518, #$250C, #$2588, #$2584, #$0162, #$016E, #$2580, - #$00D3, #$00DF, #$00D4, #$0143, #$0144, #$0148, #$0160, #$0161, - #$0154, #$00DA, #$0155, #$0170, #$00FD, #$00DD, #$0163, #$00B4, - #$00AD, #$02DD, #$02DB, #$02C7, #$02D8, #$00A7, #$00F7, #$00B8, - #$00B0, #$00A8, #$02D9, #$0171, #$0158, #$0159, #$25A0, #$00A0); - CP855Map: ThtAnsiCharHighMap = ( - #$0452, #$0402, #$0453, #$0403, #$0451, #$0401, #$0454, #$0404, - #$0455, #$0405, #$0456, #$0406, #$0457, #$0407, #$0458, #$0408, - #$0459, #$0409, #$045A, #$040A, #$045B, #$040B, #$045C, #$040C, - #$045E, #$040E, #$045F, #$040F, #$044E, #$042E, #$044A, #$042A, - #$0430, #$0410, #$0431, #$0411, #$0446, #$0426, #$0434, #$0414, - #$0435, #$0415, #$0444, #$0424, #$0433, #$0413, #$00AB, #$00BB, - #$2591, #$2592, #$2593, #$2502, #$2524, #$0445, #$0425, #$0438, - #$0418, #$2563, #$2551, #$2557, #$255D, #$0439, #$0419, #$2510, - #$2514, #$2534, #$252C, #$251C, #$2500, #$253C, #$043A, #$041A, - #$255A, #$2554, #$2569, #$2566, #$2560, #$2550, #$256C, #$00A4, - #$043B, #$041B, #$043C, #$041C, #$043D, #$041D, #$043E, #$041E, - #$043F, #$2518, #$250C, #$2588, #$2584, #$041F, #$044F, #$2580, - #$042F, #$0440, #$0420, #$0441, #$0421, #$0442, #$0422, #$0443, - #$0423, #$0436, #$0416, #$0432, #$0412, #$044C, #$042C, #$2116, - #$00AD, #$044B, #$042B, #$0437, #$0417, #$0448, #$0428, #$044D, - #$042D, #$0449, #$0429, #$0447, #$0427, #$00A7, #$25A0, #$00A0); - CP857Map: ThtAnsiCharHighMap = ( - #$00C7, #$00FC, #$00E9, #$00E2, #$00E4, #$00E0, #$00E5, #$00E7, - #$00EA, #$00EB, #$00E8, #$00EF, #$00EE, #$0131, #$00C4, #$00C5, - #$00C9, #$00E6, #$00C6, #$00F4, #$00F6, #$00F2, #$00FB, #$00F9, - #$0130, #$00D6, #$00DC, #$00F8, #$00A3, #$00D8, #$015E, #$015F, - #$00E1, #$00ED, #$00F3, #$00FA, #$00F1, #$00D1, #$011E, #$011F, - #$00BF, #$00AE, #$00AC, #$00BD, #$00BC, #$00A1, #$00AB, #$00BB, - #$2591, #$2592, #$2593, #$2502, #$2524, #$00C1, #$00C2, #$00C0, - #$00A9, #$2563, #$2551, #$2557, #$255D, #$00A2, #$00A5, #$2510, - #$2514, #$2534, #$252C, #$251C, #$2500, #$253C, #$00E3, #$00C3, - #$255A, #$2554, #$2569, #$2566, #$2560, #$2550, #$256C, #$00A4, - #$00BA, #$00AA, #$00CA, #$00CB, #$00C8, #$F8BB, #$00CD, #$00CE, - #$00CF, #$2518, #$250C, #$2588, #$2584, #$00A6, #$00CC, #$2580, - #$00D3, #$00DF, #$00D4, #$00D2, #$00F5, #$00D5, #$00B5, #$F8BC, - #$00D7, #$00DA, #$00DB, #$00D9, #$00EC, #$00FF, #$00AF, #$00B4, - #$00AD, #$00B1, #$F8BD, #$00BE, #$00B6, #$00A7, #$00F7, #$00B8, - #$00B0, #$00A8, #$00B7, #$00B9, #$00B3, #$00B2, #$25A0, #$00A0); - CP865Map: ThtAnsiCharHighMap = ( - #$00C7, #$00FC, #$00E9, #$00E2, #$00E4, #$00E0, #$00E5, #$00E7, - #$00EA, #$00EB, #$00E8, #$00EF, #$00EE, #$00EC, #$00C4, #$00C5, - #$00C9, #$00E6, #$00C6, #$00F4, #$00F6, #$00F2, #$00FB, #$00F9, - #$00FF, #$00D6, #$00DC, #$00F8, #$00A3, #$00D8, #$20A7, #$0192, - #$00E1, #$00ED, #$00F3, #$00FA, #$00F1, #$00D1, #$00AA, #$00BA, - #$00BF, #$2310, #$00AC, #$00BD, #$00BC, #$00A1, #$00AB, #$00A4, - #$2591, #$2592, #$2593, #$2502, #$2524, #$2561, #$2562, #$2556, - #$2555, #$2563, #$2551, #$2557, #$255D, #$255C, #$255B, #$2510, - #$2514, #$2534, #$252C, #$251C, #$2500, #$253C, #$255E, #$255F, - #$255A, #$2554, #$2569, #$2566, #$2560, #$2550, #$256C, #$2567, - #$2568, #$2564, #$2565, #$2559, #$2558, #$2552, #$2553, #$256B, - #$256A, #$2518, #$250C, #$2588, #$2584, #$258C, #$2590, #$2580, - #$03B1, #$00DF, #$0393, #$03C0, #$03A3, #$03C3, #$00B5, #$03C4, - #$03A6, #$0398, #$03A9, #$03B4, #$221E, #$03C6, #$03B5, #$2229, - #$2261, #$00B1, #$2265, #$2264, #$2320, #$2321, #$00F7, #$2248, - #$00B0, #$2219, #$00B7, #$221A, #$207F, #$00B2, #$25A0, #$00A0); - CP866Map: ThtAnsiCharHighMap = ( - #$0410, #$0411, #$0412, #$0413, #$0414, #$0415, #$0416, #$0417, - #$0418, #$0419, #$041A, #$041B, #$041C, #$041D, #$041E, #$041F, - #$0420, #$0421, #$0422, #$0423, #$0424, #$0425, #$0426, #$0427, - #$0428, #$0429, #$042A, #$042B, #$042C, #$042D, #$042E, #$042F, - #$0430, #$0431, #$0432, #$0433, #$0434, #$0435, #$0436, #$0437, - #$0438, #$0439, #$043A, #$043B, #$043C, #$043D, #$043E, #$043F, - #$2591, #$2592, #$2593, #$2502, #$2524, #$2561, #$2562, #$2556, - #$2555, #$2563, #$2551, #$2557, #$255D, #$255C, #$255B, #$2510, - #$2514, #$2534, #$252C, #$251C, #$2500, #$253C, #$255E, #$255F, - #$255A, #$2554, #$2569, #$2566, #$2560, #$2550, #$256C, #$2567, - #$2568, #$2564, #$2565, #$2559, #$2558, #$2552, #$2553, #$256B, - #$256A, #$2518, #$250C, #$2588, #$2584, #$258C, #$2590, #$2580, - #$0440, #$0441, #$0442, #$0443, #$0444, #$0445, #$0446, #$0447, - #$0448, #$0449, #$044A, #$044B, #$044C, #$044D, #$044E, #$044F, - #$0401, #$0451, #$0404, #$0454, #$0407, #$0457, #$040E, #$045E, - #$00B0, #$2219, #$00B7, #$221A, #$2116, #$00A4, #$25A0, #$00A0); - CP869Map: ThtAnsiCharHighMap = ( - #$FFFF, #$FFFF, #$FFFF, #$FFFF, #$FFFF, #$FFFF, #$0386, #$FFFF, - #$00B7, #$00AC, #$00A6, #$2018, #$2019, #$0388, #$2015, #$0389, - #$038A, #$03AA, #$038C, #$FFFF, #$FFFF, #$038E, #$03AB, #$00A9, - #$038F, #$00B2, #$00B3, #$03AC, #$00A3, #$03AD, #$03AE, #$03AF, - #$03CA, #$0390, #$03CC, #$03CD, #$0391, #$0392, #$0393, #$0394, - #$0395, #$0396, #$0397, #$00BD, #$0398, #$0399, #$00AB, #$00BB, - #$2591, #$2592, #$2593, #$2502, #$2524, #$039A, #$039B, #$039C, - #$039D, #$2563, #$2551, #$2557, #$255D, #$039E, #$039F, #$2510, - #$2514, #$2534, #$252C, #$251C, #$2500, #$253C, #$03A0, #$03A1, - #$255A, #$2554, #$2569, #$2566, #$2560, #$2550, #$256C, #$03A3, - #$03A4, #$03A5, #$03A6, #$03A7, #$03A8, #$03A9, #$03B1, #$03B2, - #$03B3, #$2518, #$250C, #$2588, #$2584, #$03B4, #$03B5, #$2580, - #$03B6, #$03B7, #$03B8, #$03B9, #$03BA, #$03BB, #$03BC, #$03BD, - #$03BE, #$03BF, #$03C0, #$03C1, #$03C3, #$03C2, #$03C4, #$0384, - #$00AD, #$00B1, #$03C5, #$03C6, #$03C7, #$00A7, #$03C8, #$0385, - #$00B0, #$00A8, #$03C9, #$03CB, #$03B0, #$03CE, #$25A0, #$00A0); - CP922_1Map: array[0..15] of TBuffChar = ( - #$00A0, #$00A1, #$00A2, #$00A3, #$00A4, #$00A5, #$00A6, #$00A7, - #$00A8, #$00A9, #$00AA, #$00AB, #$00AC, #$00AD, #$00AE, #$203E); - CP922_2Map: array[0..15] of TBuffChar = ( - #$0160, #$00D1, #$00D2, #$00D3, #$00D4, #$00D5, #$00D6, #$00D7, - #$00D8, #$00D9, #$00DA, #$00DB, #$00DC, #$00DD, #$017D, #$00DF); - CP922_3Map: array[0..15] of TBuffChar = ( - #$0161, #$00F1, #$00F2, #$00F3, #$00F4, #$00F5, #$00F6, #$00F7, - #$00F8, #$00F9, #$00FA, #$00FB, #$00FC, #$00FD, #$017E, #$00FF); - CP1124Map: array[0..95] of TBuffChar = ( - #$00A0, #$0401, #$0402, #$0490, #$0404, #$0405, #$0406, #$0407, - #$0408, #$0409, #$040A, #$040B, #$040C, #$00AD, #$040E, #$040F, - #$0410, #$0411, #$0412, #$0413, #$0414, #$0415, #$0416, #$0417, - #$0418, #$0419, #$041A, #$041B, #$041C, #$041D, #$041E, #$041F, - #$0420, #$0421, #$0422, #$0423, #$0424, #$0425, #$0426, #$0427, - #$0428, #$0429, #$042A, #$042B, #$042C, #$042D, #$042E, #$042F, - #$0430, #$0431, #$0432, #$0433, #$0434, #$0435, #$0436, #$0437, - #$0438, #$0439, #$043A, #$043B, #$043C, #$043D, #$043E, #$043F, - #$0440, #$0441, #$0442, #$0443, #$0444, #$0445, #$0446, #$0447, - #$0448, #$0449, #$044A, #$044B, #$044C, #$044D, #$044E, #$044F, - #$2116, #$0451, #$0452, #$0491, #$0454, #$0455, #$0456, #$0457, - #$0458, #$0459, #$045A, #$045B, #$045C, #$00A7, #$045E, #$045F); - CP1125Map: array[0..79] of TBuffChar = ( - #$2591, #$2592, #$2593, #$2502, #$2524, #$2561, #$2562, #$2556, - #$2555, #$2563, #$2551, #$2557, #$255D, #$255C, #$255B, #$2510, - #$2514, #$2534, #$252C, #$251C, #$2500, #$253C, #$255E, #$255F, - #$255A, #$2554, #$2569, #$2566, #$2560, #$2550, #$256C, #$2567, - #$2568, #$2564, #$2565, #$2559, #$2558, #$2552, #$2553, #$256B, - #$256A, #$2518, #$250C, #$2588, #$2584, #$258C, #$2590, #$2580, - #$0440, #$0441, #$0442, #$0443, #$0444, #$0445, #$0446, #$0447, - #$0448, #$0449, #$044A, #$044B, #$044C, #$044D, #$044E, #$044F, - #$0401, #$0451, #$0490, #$0491, #$0404, #$0454, #$0406, #$0456, - #$0407, #$0457, #$00B7, #$221A, #$2116, #$00A4, #$25A0, #$00A0); - CP1129Map: array[0..95] of TBuffChar = ( - #$00A0, #$00A1, #$00A2, #$00A3, #$00A4, #$00A5, #$00A6, #$00A7, - #$0153, #$00A9, #$00AA, #$00AB, #$00AC, #$00AD, #$00AE, #$00AF, - #$00B0, #$00B1, #$00B2, #$00B3, #$0178, #$00B5, #$00B6, #$00B7, - #$0152, #$00B9, #$00BA, #$00BB, #$00BC, #$00BD, #$00BE, #$00BF, - #$00C0, #$00C1, #$00C2, #$0102, #$00C4, #$00C5, #$00C6, #$00C7, - #$00C8, #$00C9, #$00CA, #$00CB, #$0300, #$00CD, #$00CE, #$00CF, - #$0110, #$00D1, #$0309, #$00D3, #$00D4, #$01A0, #$00D6, #$00D7, - #$00D8, #$00D9, #$00DA, #$00DB, #$00DC, #$01AF, #$0303, #$00DF, - #$00E0, #$00E1, #$00E2, #$0103, #$00E4, #$00E5, #$00E6, #$00E7, - #$00E8, #$00E9, #$00EA, #$00EB, #$0301, #$00ED, #$00EE, #$00EF, - #$0111, #$00F1, #$0323, #$00F3, #$00F4, #$01A1, #$00F6, #$00F7, - #$00F8, #$00F9, #$00FA, #$00FB, #$00FC, #$01B0, #$20AB, #$00FF); - CP1250Map: ThtAnsiCharHighMap = ( - #$20AC, #$FFFD, #$201A, #$FFFD, #$201E, #$2026, #$2020, #$2021, - #$FFFD, #$2030, #$0160, #$2039, #$015A, #$0164, #$017D, #$0179, - #$FFFD, #$2018, #$2019, #$201C, #$201D, #$2022, #$2013, #$2014, - #$FFFD, #$2122, #$0161, #$203A, #$015B, #$0165, #$017E, #$017A, - #$00A0, #$02C7, #$02D8, #$0141, #$00A4, #$0104, #$00A6, #$00A7, - #$00A8, #$00A9, #$015E, #$00AB, #$00AC, #$00AD, #$00AE, #$017B, - #$00B0, #$00B1, #$02DB, #$0142, #$00B4, #$00B5, #$00B6, #$00B7, - #$00B8, #$0105, #$015F, #$00BB, #$013D, #$02DD, #$013E, #$017C, - #$0154, #$00C1, #$00C2, #$0102, #$00C4, #$0139, #$0106, #$00C7, - #$010C, #$00C9, #$0118, #$00CB, #$011A, #$00CD, #$00CE, #$010E, - #$0110, #$0143, #$0147, #$00D3, #$00D4, #$0150, #$00D6, #$00D7, - #$0158, #$016E, #$00DA, #$0170, #$00DC, #$00DD, #$0162, #$00DF, - #$0155, #$00E1, #$00E2, #$0103, #$00E4, #$013A, #$0107, #$00E7, - #$010D, #$00E9, #$0119, #$00EB, #$011B, #$00ED, #$00EE, #$010F, - #$0111, #$0144, #$0148, #$00F3, #$00F4, #$0151, #$00F6, #$00F7, - #$0159, #$016F, #$00FA, #$0171, #$00FC, #$00FD, #$0163, #$02D9); - CP1251Map: ThtAnsiCharHighMap = ( - #$0402, #$0403, #$201A, #$0453, #$201E, #$2026, #$2020, #$2021, - #$20AC, #$2030, #$0409, #$2039, #$040A, #$040C, #$040B, #$040F, - #$0452, #$2018, #$2019, #$201C, #$201D, #$2022, #$2013, #$2014, - #$FFFD, #$2122, #$0459, #$203A, #$045A, #$045C, #$045B, #$045F, - #$00A0, #$040E, #$045E, #$0408, #$00A4, #$0490, #$00A6, #$00A7, - #$0401, #$00A9, #$0404, #$00AB, #$00AC, #$00AD, #$00AE, #$0407, - #$00B0, #$00B1, #$0406, #$0456, #$0491, #$00B5, #$00B6, #$00B7, - #$0451, #$2116, #$0454, #$00BB, #$0458, #$0405, #$0455, #$0457, - #$0410, #$0411, #$0412, #$0413, #$0414, #$0415, #$0416, #$0417, - #$0418, #$0419, #$041A, #$041B, #$041C, #$041D, #$041E, #$041F, - #$0420, #$0421, #$0422, #$0423, #$0424, #$0425, #$0426, #$0427, - #$0428, #$0429, #$042A, #$042B, #$042C, #$042D, #$042E, #$042F, - #$0430, #$0431, #$0432, #$0433, #$0434, #$0435, #$0436, #$0437, - #$0438, #$0439, #$043A, #$043B, #$043C, #$043D, #$043E, #$043F, - #$0440, #$0441, #$0442, #$0443, #$0444, #$0445, #$0446, #$0447, - #$0448, #$0449, #$044A, #$044B, #$044C, #$044D, #$044E, #$044F); - CP1252Map: ThtAnsiCharHighMap = ( - #$20AC, #$FFFD, #$201A, #$0192, #$201E, #$2026, #$2020, #$2021, - #$02C6, #$2030, #$0160, #$2039, #$0152, #$FFFD, #$017D, #$FFFD, - #$FFFD, #$2018, #$2019, #$201C, #$201D, #$2022, #$2013, #$2014, - #$02DC, #$2122, #$0161, #$203A, #$0153, #$FFFD, #$017E, #$0178, - #$00A0, #$00A1, #$00A2, #$00A3, #$00A4, #$00A5, #$00A6, #$00A7, - #$00A8, #$00A9, #$00AA, #$00AB, #$00AC, #$00AD, #$00AE, #$00AF, - #$00B0, #$00B1, #$00B2, #$00B3, #$00B4, #$00B5, #$00B6, #$00B7, - #$00B8, #$00B9, #$00BA, #$00BB, #$00BC, #$00BD, #$00BE, #$00BF, - #$00C0, #$00C1, #$00C2, #$00C3, #$00C4, #$00C5, #$00C6, #$00C7, - #$00C8, #$00C9, #$00CA, #$00CB, #$00CC, #$00CD, #$00CE, #$00CF, - #$00D0, #$00D1, #$00D2, #$00D3, #$00D4, #$00D5, #$00D6, #$00D7, - #$00D8, #$00D9, #$00DA, #$00DB, #$00DC, #$00DD, #$00DE, #$00DF, - #$00E0, #$00E1, #$00E2, #$00E3, #$00E4, #$00E5, #$00E6, #$00E7, - #$00E8, #$00E9, #$00EA, #$00EB, #$00EC, #$00ED, #$00EE, #$00EF, - #$00F0, #$00F1, #$00F2, #$00F3, #$00F4, #$00F5, #$00F6, #$00F7, - #$00F8, #$00F9, #$00FA, #$00FB, #$00FC, #$00FD, #$00FE, #$00FF); - CP1253Map: ThtAnsiCharHighMap = ( - #$20AC, #$FFFD, #$201A, #$0192, #$201E, #$2026, #$2020, #$2021, - #$FFFD, #$2030, #$FFFD, #$2039, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$2018, #$2019, #$201C, #$201D, #$2022, #$2013, #$2014, - #$FFFD, #$2122, #$FFFD, #$203A, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$00A0, #$0385, #$0386, #$00A3, #$00A4, #$00A5, #$00A6, #$00A7, - #$00A8, #$00A9, #$FFFD, #$00AB, #$00AC, #$00AD, #$00AE, #$2015, - #$00B0, #$00B1, #$00B2, #$00B3, #$0384, #$00B5, #$00B6, #$00B7, - #$0388, #$0389, #$038A, #$00BB, #$038C, #$00BD, #$038E, #$038F, - #$0390, #$0391, #$0392, #$0393, #$0394, #$0395, #$0396, #$0397, - #$0398, #$0399, #$039A, #$039B, #$039C, #$039D, #$039E, #$039F, - #$03A0, #$03A1, #$FFFD, #$03A3, #$03A4, #$03A5, #$03A6, #$03A7, - #$03A8, #$03A9, #$03AA, #$03AB, #$03AC, #$03AD, #$03AE, #$03AF, - #$03B0, #$03B1, #$03B2, #$03B3, #$03B4, #$03B5, #$03B6, #$03B7, - #$03B8, #$03B9, #$03BA, #$03BB, #$03BC, #$03BD, #$03BE, #$03BF, - #$03C0, #$03C1, #$03C2, #$03C3, #$03C4, #$03C5, #$03C6, #$03C7, - #$03C8, #$03C9, #$03CA, #$03CB, #$03CC, #$03CD, #$03CE, #$FFFD); - CP1254Map: ThtAnsiCharHighMap = ( - #$20AC, #$FFFD, #$201A, #$0192, #$201E, #$2026, #$2020, #$2021, - #$02C6, #$2030, #$0160, #$2039, #$0152, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$2018, #$2019, #$201C, #$201D, #$2022, #$2013, #$2014, - #$02DC, #$2122, #$0161, #$203A, #$0153, #$FFFD, #$FFFD, #$0178, - #$00A0, #$00A1, #$00A2, #$00A3, #$00A4, #$00A5, #$00A6, #$00A7, - #$00A8, #$00A9, #$00AA, #$00AB, #$00AC, #$00AD, #$00AE, #$00AF, - #$00B0, #$00B1, #$00B2, #$00B3, #$00B4, #$00B5, #$00B6, #$00B7, - #$00B8, #$00B9, #$00BA, #$00BB, #$00BC, #$00BD, #$00BE, #$00BF, - #$00C0, #$00C1, #$00C2, #$00C3, #$00C4, #$00C5, #$00C6, #$00C7, - #$00C8, #$00C9, #$00CA, #$00CB, #$00CC, #$00CD, #$00CE, #$00CF, - #$011E, #$00D1, #$00D2, #$00D3, #$00D4, #$00D5, #$00D6, #$00D7, - #$00D8, #$00D9, #$00DA, #$00DB, #$00DC, #$0130, #$015E, #$00DF, - #$00E0, #$00E1, #$00E2, #$00E3, #$00E4, #$00E5, #$00E6, #$00E7, - #$00E8, #$00E9, #$00EA, #$00EB, #$00EC, #$00ED, #$00EE, #$00EF, - #$011F, #$00F1, #$00F2, #$00F3, #$00F4, #$00F5, #$00F6, #$00F7, - #$00F8, #$00F9, #$00FA, #$00FB, #$00FC, #$0131, #$015F, #$00FF); - CP1255Map: ThtAnsiCharHighMap = ( - #$20AC, #$FFFD, #$201A, #$0192, #$201E, #$2026, #$2020, #$2021, - #$02C6, #$2030, #$FFFD, #$2039, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$2018, #$2019, #$201C, #$201D, #$2022, #$2013, #$2014, - #$02DC, #$2122, #$FFFD, #$203A, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$00A0, #$00A1, #$00A2, #$00A3, #$20AA, #$00A5, #$00A6, #$00A7, - #$00A8, #$00A9, #$00D7, #$00AB, #$00AC, #$00AD, #$00AE, #$00AF, - #$00B0, #$00B1, #$00B2, #$00B3, #$00B4, #$00B5, #$00B6, #$00B7, - #$00B8, #$00B9, #$00F7, #$00BB, #$00BC, #$00BD, #$00BE, #$00BF, - #$05B0, #$05B1, #$05B2, #$05B3, #$05B4, #$05B5, #$05B6, #$05B7, - #$05B8, #$05B9, #$FFFD, #$05BB, #$05BC, #$05BD, #$05BE, #$05BF, - #$05C0, #$05C1, #$05C2, #$05C3, #$05F0, #$05F1, #$05F2, #$05F3, - #$05F4, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$05D0, #$05D1, #$05D2, #$05D3, #$05D4, #$05D5, #$05D6, #$05D7, - #$05D8, #$05D9, #$05DA, #$05DB, #$05DC, #$05DD, #$05DE, #$05DF, - #$05E0, #$05E1, #$05E2, #$05E3, #$05E4, #$05E5, #$05E6, #$05E7, - #$05E8, #$05E9, #$05EA, #$FFFD, #$FFFD, #$200E, #$200F, #$FFFD); - CP1256Map: ThtAnsiCharHighMap = ( - #$20AC, #$067E, #$201A, #$0192, #$201E, #$2026, #$2020, #$2021, - #$02C6, #$2030, #$0679, #$2039, #$0152, #$0686, #$0698, #$0688, - #$06AF, #$2018, #$2019, #$201C, #$201D, #$2022, #$2013, #$2014, - #$06A9, #$2122, #$0691, #$203A, #$0153, #$200C, #$200D, #$06BA, - #$00A0, #$060C, #$00A2, #$00A3, #$00A4, #$00A5, #$00A6, #$00A7, - #$00A8, #$00A9, #$06BE, #$00AB, #$00AC, #$00AD, #$00AE, #$00AF, - #$00B0, #$00B1, #$00B2, #$00B3, #$00B4, #$00B5, #$00B6, #$00B7, - #$00B8, #$00B9, #$061B, #$00BB, #$00BC, #$00BD, #$00BE, #$061F, - #$06C1, #$0621, #$0622, #$0623, #$0624, #$0625, #$0626, #$0627, - #$0628, #$0629, #$062A, #$062B, #$062C, #$062D, #$062E, #$062F, - #$0630, #$0631, #$0632, #$0633, #$0634, #$0635, #$0636, #$00D7, - #$0637, #$0638, #$0639, #$063A, #$0640, #$0641, #$0642, #$0643, - #$00E0, #$0644, #$00E2, #$0645, #$0646, #$0647, #$0648, #$00E7, - #$00E8, #$00E9, #$00EA, #$00EB, #$0649, #$064A, #$00EE, #$00EF, - #$064B, #$064C, #$064D, #$064E, #$00F4, #$064F, #$0650, #$00F7, - #$0651, #$00F9, #$0652, #$00FB, #$00FC, #$200E, #$200F, #$06D2); - CP1257Map: ThtAnsiCharHighMap = ( - #$20AC, #$FFFD, #$201A, #$FFFD, #$201E, #$2026, #$2020, #$2021, - #$FFFD, #$2030, #$FFFD, #$2039, #$FFFD, #$00A8, #$02C7, #$00B8, - #$FFFD, #$2018, #$2019, #$201C, #$201D, #$2022, #$2013, #$2014, - #$FFFD, #$2122, #$FFFD, #$203A, #$FFFD, #$00AF, #$02DB, #$FFFD, - #$00A0, #$FFFD, #$00A2, #$00A3, #$00A4, #$FFFD, #$00A6, #$00A7, - #$00D8, #$00A9, #$0156, #$00AB, #$00AC, #$00AD, #$00AE, #$00C6, - #$00B0, #$00B1, #$00B2, #$00B3, #$00B4, #$00B5, #$00B6, #$00B7, - #$00F8, #$00B9, #$0157, #$00BB, #$00BC, #$00BD, #$00BE, #$00E6, - #$0104, #$012E, #$0100, #$0106, #$00C4, #$00C5, #$0118, #$0112, - #$010C, #$00C9, #$0179, #$0116, #$0122, #$0136, #$012A, #$013B, - #$0160, #$0143, #$0145, #$00D3, #$014C, #$00D5, #$00D6, #$00D7, - #$0172, #$0141, #$015A, #$016A, #$00DC, #$017B, #$017D, #$00DF, - #$0105, #$012F, #$0101, #$0107, #$00E4, #$00E5, #$0119, #$0113, - #$010D, #$00E9, #$017A, #$0117, #$0123, #$0137, #$012B, #$013C, - #$0161, #$0144, #$0146, #$00F3, #$014D, #$00F5, #$00F6, #$00F7, - #$0173, #$0142, #$015B, #$016B, #$00FC, #$017C, #$017E, #$02D9); - CP1258Map: ThtAnsiCharHighMap = ( - #$20AC, #$FFFD, #$201A, #$0192, #$201E, #$2026, #$2020, #$2021, - #$02C6, #$2030, #$FFFD, #$2039, #$0152, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$2018, #$2019, #$201C, #$201D, #$2022, #$2013, #$2014, - #$02DC, #$2122, #$FFFD, #$203A, #$0153, #$FFFD, #$FFFD, #$0178, - #$00A0, #$00A1, #$00A2, #$00A3, #$00A4, #$00A5, #$00A6, #$00A7, - #$00A8, #$00A9, #$00AA, #$00AB, #$00AC, #$00AD, #$00AE, #$00AF, - #$00B0, #$00B1, #$00B2, #$00B3, #$00B4, #$00B5, #$00B6, #$00B7, - #$00B8, #$00B9, #$00BA, #$00BB, #$00BC, #$00BD, #$00BE, #$00BF, - #$00C0, #$00C1, #$00C2, #$0102, #$00C4, #$00C5, #$00C6, #$00C7, - #$00C8, #$00C9, #$00CA, #$00CB, #$0300, #$00CD, #$00CE, #$00CF, - #$0110, #$00D1, #$0309, #$00D3, #$00D4, #$01A0, #$00D6, #$00D7, - #$00D8, #$00D9, #$00DA, #$00DB, #$00DC, #$01AF, #$0303, #$00DF, - #$00E0, #$00E1, #$00E2, #$0103, #$00E4, #$00E5, #$00E6, #$00E7, - #$00E8, #$00E9, #$00EA, #$00EB, #$0301, #$00ED, #$00EE, #$00EF, - #$0111, #$00F1, #$0323, #$00F3, #$00F4, #$01A1, #$00F6, #$00F7, - #$00F8, #$00F9, #$00FA, #$00FB, #$00FC, #$01B0, #$20AB, #$00FF); - IBM860Map: ThtAnsiCharHighMap = ( - #$00C7, #$00FC, #$00E9, #$00E2, #$00E3, #$00E0, #$00C1, #$00E7, - #$00EA, #$00CA, #$00E8, #$00CD, #$00D4, #$00EC, #$00C3, #$00C2, - #$00C9, #$00C0, #$00C8, #$00F4, #$00F5, #$00F2, #$00DA, #$00F9, - #$00CC, #$00D5, #$00DC, #$00A2, #$00A3, #$00D9, #$20A7, #$00D3, - #$00E1, #$00ED, #$00F3, #$00FA, #$00F1, #$00D1, #$00AA, #$00BA, - #$00BF, #$00D2, #$00AC, #$00BD, #$00BC, #$00A1, #$00AB, #$00BB, - #$2591, #$2592, #$2593, #$2502, #$2524, #$2561, #$2562, #$2556, - #$2555, #$2563, #$2551, #$2557, #$255D, #$255C, #$255B, #$2510, - #$2514, #$2534, #$252C, #$251C, #$2500, #$253C, #$255E, #$255F, - #$255A, #$2554, #$2569, #$2566, #$2560, #$2550, #$256C, #$2567, - #$2568, #$2564, #$2565, #$2559, #$2558, #$2552, #$2553, #$256B, - #$256A, #$2518, #$250C, #$2588, #$2584, #$258C, #$2590, #$2580, - #$03B1, #$00DF, #$0393, #$03C0, #$03A3, #$03C3, #$00B5, #$03C4, - #$03A6, #$0398, #$03A9, #$03B4, #$221E, #$03C6, #$03B5, #$2229, - #$2261, #$00B1, #$2265, #$2264, #$2320, #$2321, #$00F7, #$2248, - #$00B0, #$2219, #$00B7, #$221A, #$207F, #$00B2, #$25A0, #$00A0); - CP861Map: ThtAnsiCharHighMap = ( - #$00C7, #$00FC, #$00E9, #$00E2, #$00E4, #$00E0, #$00E5, #$00E7, - #$00EA, #$00EB, #$00E8, #$00D0, #$00F0, #$00DE, #$00C4, #$00C5, - #$00C9, #$00E6, #$00C6, #$00F4, #$00F6, #$00FE, #$00FB, #$00DD, - #$00FD, #$00D6, #$00DC, #$00F8, #$00A3, #$00D8, #$20A7, #$0192, - #$00E1, #$00ED, #$00F3, #$00FA, #$00C1, #$00CD, #$00D3, #$00DA, - #$00BF, #$2310, #$00AC, #$00BD, #$00BC, #$00A1, #$00AB, #$00BB, - #$2591, #$2592, #$2593, #$2502, #$2524, #$2561, #$2562, #$2556, - #$2555, #$2563, #$2551, #$2557, #$255D, #$255C, #$255B, #$2510, - #$2514, #$2534, #$252C, #$251C, #$2500, #$253C, #$255E, #$255F, - #$255A, #$2554, #$2569, #$2566, #$2560, #$2550, #$256C, #$2567, - #$2568, #$2564, #$2565, #$2559, #$2558, #$2552, #$2553, #$256B, - #$256A, #$2518, #$250C, #$2588, #$2584, #$258C, #$2590, #$2580, - #$03B1, #$00DF, #$0393, #$03C0, #$03A3, #$03C3, #$00B5, #$03C4, - #$03A6, #$0398, #$03A9, #$03B4, #$221E, #$03C6, #$03B5, #$2229, - #$2261, #$00B1, #$2265, #$2264, #$2320, #$2321, #$00F7, #$2248, - #$00B0, #$2219, #$00B7, #$221A, #$207F, #$00B2, #$25A0, #$00A0); - CP862Map: ThtAnsiCharHighMap = ( - #$05D0, #$05D1, #$05D2, #$05D3, #$05D4, #$05D5, #$05D6, #$05D7, - #$05D8, #$05D9, #$05DA, #$05DB, #$05DC, #$05DD, #$05DE, #$05DF, - #$05E0, #$05E1, #$05E2, #$05E3, #$05E4, #$05E5, #$05E6, #$05E7, - #$05E8, #$05E9, #$05EA, #$00A2, #$00A3, #$00A5, #$20A7, #$0192, - #$00E1, #$00ED, #$00F3, #$00FA, #$00F1, #$00D1, #$00AA, #$00BA, - #$00BF, #$2310, #$00AC, #$00BD, #$00BC, #$00A1, #$00AB, #$00BB, - #$2591, #$2592, #$2593, #$2502, #$2524, #$2561, #$2562, #$2556, - #$2555, #$2563, #$2551, #$2557, #$255D, #$255C, #$255B, #$2510, - #$2514, #$2534, #$252C, #$251C, #$2500, #$253C, #$255E, #$255F, - #$255A, #$2554, #$2569, #$2566, #$2560, #$2550, #$256C, #$2567, - #$2568, #$2564, #$2565, #$2559, #$2558, #$2552, #$2553, #$256B, - #$256A, #$2518, #$250C, #$2588, #$2584, #$258C, #$2590, #$2580, - #$03B1, #$00DF, #$0393, #$03C0, #$03A3, #$03C3, #$00B5, #$03C4, - #$03A6, #$0398, #$03A9, #$03B4, #$221E, #$03C6, #$03B5, #$2229, - #$2261, #$00B1, #$2265, #$2264, #$2320, #$2321, #$00F7, #$2248, - #$00B0, #$2219, #$00B7, #$221A, #$207F, #$00B2, #$25A0, #$00A0); - CP863Map: ThtAnsiCharHighMap = ( - #$00C7, #$00FC, #$00E9, #$00E2, #$00C2, #$00E0, #$00B6, #$00E7, - #$00EA, #$00EB, #$00E8, #$00EF, #$00EE, #$2017, #$00C0, #$00A7, - #$00C9, #$00C8, #$00CA, #$00F4, #$00CB, #$00CF, #$00FB, #$00F9, - #$00A4, #$00D4, #$00DC, #$00A2, #$00A3, #$00D9, #$00DB, #$0192, - #$00A6, #$00B4, #$00F3, #$00FA, #$00A8, #$00B8, #$00B3, #$00AF, - #$00CE, #$2310, #$00AC, #$00BD, #$00BC, #$00BE, #$00AB, #$00BB, - #$2591, #$2592, #$2593, #$2502, #$2524, #$2561, #$2562, #$2556, - #$2555, #$2563, #$2551, #$2557, #$255D, #$255C, #$255B, #$2510, - #$2514, #$2534, #$252C, #$251C, #$2500, #$253C, #$255E, #$255F, - #$255A, #$2554, #$2569, #$2566, #$2560, #$2550, #$256C, #$2567, - #$2568, #$2564, #$2565, #$2559, #$2558, #$2552, #$2553, #$256B, - #$256A, #$2518, #$250C, #$2588, #$2584, #$258C, #$2590, #$2580, - #$03B1, #$00DF, #$0393, #$03C0, #$03A3, #$03C3, #$00B5, #$03C4, - #$03A6, #$0398, #$03A9, #$03B4, #$221E, #$03C6, #$03B5, #$2229, - #$2261, #$00B1, #$2265, #$2264, #$2320, #$2321, #$00F7, #$2248, - #$00B0, #$2219, #$00B7, #$221A, #$207F, #$00B2, #$25A0, #$00A0); - IBM864Map: array[$25..$FF] of TBuffChar = ( - #$FFFF, #$0026, #$0027, #$0028, #$0029, #$002A, #$002B, #$002C, - #$002D, #$002E, #$002F, #$0030, #$0031, #$0032, #$0033, #$0034, - #$0035, #$0036, #$0037, #$0038, #$0039, #$003A, #$003B, #$003C, - #$003D, #$003E, #$003F, #$0040, #$0041, #$0042, #$0043, #$0044, - #$0045, #$0046, #$0047, #$0048, #$0049, #$004A, #$004B, #$004C, - #$004D, #$004E, #$004F, #$0050, #$0051, #$0052, #$0053, #$0054, - #$0055, #$0056, #$0057, #$0058, #$0059, #$005A, #$005B, #$005C, - #$005D, #$005E, #$005F, #$0060, #$0061, #$0062, #$0063, #$0064, - #$0065, #$0066, #$0067, #$0068, #$0069, #$006A, #$006B, #$006C, - #$006D, #$006E, #$006F, #$0070, #$0071, #$0072, #$0073, #$0074, - #$0075, #$0076, #$0077, #$0078, #$0079, #$007A, #$007B, #$007C, - #$007D, #$007E, #$007F, #$00B0, #$00B7, #$2219, #$221A, #$2592, - #$2500, #$2502, #$253C, #$2524, #$252C, #$251C, #$2534, #$2510, - #$250C, #$2514, #$2518, #$03B2, #$221E, #$03C6, #$00B1, #$00BD, - #$00BC, #$2248, #$00AB, #$00BB, #$FEF7, #$FEF8, #$FFFF, #$FFFF, - #$FEFB, #$FEFC, #$FFFF, #$00A0, #$00AD, #$FE82, #$00A3, #$00A4, - #$FE84, #$FFFF, #$FFFF, #$FE8E, #$FE8F, #$FE95, #$FE99, #$060C, - #$FE9D, #$FEA1, #$FEA5, #$0660, #$0661, #$0662, #$0663, #$0664, - #$0665, #$0666, #$0667, #$0668, #$0669, #$FED1, #$061B, #$FEB1, - #$FEB5, #$FEB9, #$061F, #$00A2, #$FFFF, #$FFFF, #$FFFF, #$FFFF, - #$FECA, #$FFFF, #$FE8D, #$FE91, #$FE93, #$FE97, #$FE9B, #$FE9F, - #$FEA3, #$FEA7, #$FEA9, #$FEAB, #$FEAD, #$FEAF, #$FEB3, #$FEB7, - #$FEBB, #$FEBF, #$FEC1, #$FEC5, #$FECB, #$FECF, #$00A6, #$00AC, - #$00F7, #$00D7, #$FEC9, #$0640, #$FED3, #$FED7, #$FEDB, #$FEDF, - #$FEE3, #$FEE7, #$FEEB, #$FEED, #$FEEF, #$FEF3, #$FEBD, #$FECC, - #$FECE, #$FECD, #$FEE1, #$FE7D, #$0651, #$FEE5, #$FEE9, #$FEEC, - #$FEF0, #$FEF2, #$FED0, #$FED5, #$FEF5, #$FEF6, #$FEDD, #$FED9, - #$FEF1, #$25A0, #$FFFF); - CP932E_1Map: array[0..91] of TBuffChar = ( - #$2460, #$2461, #$2462, #$2463, #$2464, #$2465, #$2466, #$2467, - #$2468, #$2469, #$246A, #$246B, #$246C, #$246D, #$246E, #$246F, - #$2470, #$2471, #$2472, #$2473, #$2160, #$2161, #$2162, #$2163, - #$2164, #$2165, #$2166, #$2167, #$2168, #$2169, #$FFFD, #$3349, - #$3314, #$3322, #$334D, #$3318, #$3327, #$3303, #$3336, #$3351, - #$3357, #$330D, #$3326, #$3323, #$332B, #$334A, #$333B, #$339C, - #$339D, #$339E, #$338E, #$338F, #$33C4, #$33A1, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$337B, #$301D, - #$301F, #$2116, #$33CD, #$2121, #$32A4, #$32A5, #$32A6, #$32A7, - #$32A8, #$3231, #$3232, #$3239, #$337E, #$337D, #$337C, #$2252, - #$2261, #$222B, #$222E, #$2211, #$221A, #$22A5, #$2220, #$221F, - #$22BF, #$2235, #$2229, #$222A); - CP932E_2Map: array[0..375] of TBuffChar = ( - #$7E8A, #$891C, #$9348, #$9288, #$84DC, #$4FC9, #$70BB, #$6631, - #$68C8, #$92F9, #$66FB, #$5F45, #$4E28, #$4EE1, #$4EFC, #$4F00, - #$4F03, #$4F39, #$4F56, #$4F92, #$4F8A, #$4F9A, #$4F94, #$4FCD, - #$5040, #$5022, #$4FFF, #$501E, #$5046, #$5070, #$5042, #$5094, - #$50F4, #$50D8, #$514A, #$5164, #$519D, #$51BE, #$51EC, #$5215, - #$529C, #$52A6, #$52C0, #$52DB, #$5300, #$5307, #$5324, #$5372, - #$5393, #$53B2, #$53DD, #$FA0E, #$549C, #$548A, #$54A9, #$54FF, - #$5586, #$5759, #$5765, #$57AC, #$57C8, #$57C7, #$FA0F, #$FA10, - #$589E, #$58B2, #$590B, #$5953, #$595B, #$595D, #$5963, #$59A4, - #$59BA, #$5B56, #$5BC0, #$752F, #$5BD8, #$5BEC, #$5C1E, #$5CA6, - #$5CBA, #$5CF5, #$5D27, #$5D53, #$FA11, #$5D42, #$5D6D, #$5DB8, - #$5DB9, #$5DD0, #$5F21, #$5F34, #$5F67, #$5FB7, #$5FDE, #$605D, - #$6085, #$608A, #$60DE, #$60D5, #$6120, #$60F2, #$6111, #$6137, - #$6130, #$6198, #$6213, #$62A6, #$63F5, #$6460, #$649D, #$64CE, - #$654E, #$6600, #$6615, #$663B, #$6609, #$662E, #$661E, #$6624, - #$6665, #$6657, #$6659, #$FA12, #$6673, #$6699, #$66A0, #$66B2, - #$66BF, #$66FA, #$670E, #$F929, #$6766, #$67BB, #$6852, #$67C0, - #$6801, #$6844, #$68CF, #$FA13, #$6968, #$FA14, #$6998, #$69E2, - #$6A30, #$6A6B, #$6A46, #$6A73, #$6A7E, #$6AE2, #$6AE4, #$6BD6, - #$6C3F, #$6C5C, #$6C86, #$6C6F, #$6CDA, #$6D04, #$6D87, #$6D6F, - #$6D96, #$6DAC, #$6DCF, #$6DF8, #$6DF2, #$6DFC, #$6E39, #$6E5C, - #$6E27, #$6E3C, #$6EBF, #$6F88, #$6FB5, #$6FF5, #$7005, #$7007, - #$7028, #$7085, #$70AB, #$710F, #$7104, #$715C, #$7146, #$7147, - #$FA15, #$71C1, #$71FE, #$72B1, - #$72BE, #$7324, #$FA16, #$7377, #$73BD, #$73C9, #$73D6, #$73E3, - #$73D2, #$7407, #$73F5, #$7426, #$742A, #$7429, #$742E, #$7462, - #$7489, #$749F, #$7501, #$756F, #$7682, #$769C, #$769E, #$769B, - #$76A6, #$FA17, #$7746, #$52AF, #$7821, #$784E, #$7864, #$787A, - #$7930, #$FA18, #$FA19, #$FA1A, #$7994, #$FA1B, #$799B, #$7AD1, - #$7AE7, #$FA1C, #$7AEB, #$7B9E, #$FA1D, #$7D48, #$7D5C, #$7DB7, - #$7DA0, #$7DD6, #$7E52, #$7F47, #$7FA1, #$FA1E, #$8301, #$8362, - #$837F, #$83C7, #$83F6, #$8448, #$84B4, #$8553, #$8559, #$856B, - #$FA1F, #$85B0, #$FA20, #$FA21, #$8807, #$88F5, #$8A12, #$8A37, - #$8A79, #$8AA7, #$8ABE, #$8ADF, #$FA22, #$8AF6, #$8B53, #$8B7F, - #$8CF0, #$8CF4, #$8D12, #$8D76, #$FA23, #$8ECF, #$FA24, #$FA25, - #$9067, #$90DE, #$FA26, #$9115, #$9127, #$91DA, #$91D7, #$91DE, - #$91ED, #$91EE, #$91E4, #$91E5, #$9206, #$9210, #$920A, #$923A, - #$9240, #$923C, #$924E, #$9259, #$9251, #$9239, #$9267, #$92A7, - #$9277, #$9278, #$92E7, #$92D7, #$92D9, #$92D0, #$FA27, #$92D5, - #$92E0, #$92D3, #$9325, #$9321, #$92FB, #$FA28, #$931E, #$92FF, - #$931D, #$9302, #$9370, #$9357, #$93A4, #$93C6, #$93DE, #$93F8, - #$9431, #$9445, #$9448, #$9592, #$F9DC, #$FA29, #$969D, #$96AF, - #$9733, #$973B, #$9743, #$974D, #$974F, #$9751, #$9755, #$9857, - #$9865, #$FA2A, #$FA2B, #$9927, #$FA2C, #$999E, #$9A4E, #$9AD9, - #$9ADC, #$9B75, #$9B72, #$9B8F, #$9BB1, #$9BBB, #$9C00, #$9D70, - #$9D6B, #$FA2D, #$9E19, #$9ED1, #$FFFD, #$FFFD, #$2170, #$2171, - #$2172, #$2173, #$2174, #$2175, #$2176, #$2177, #$2178, #$2179, - #$FFE2, #$FFE4, #$FF07, #$FF02); - CP932E_3Map: array[0..387] of TBuffChar = ( - #$2170, #$2171, #$2172, #$2173, #$2174, #$2175, #$2176, #$2177, - #$2178, #$2179, #$2160, #$2161, #$2162, #$2163, #$2164, #$2165, - #$2166, #$2167, #$2168, #$2169, #$FFE2, #$FFE4, #$FF07, #$FF02, - #$3231, #$2116, #$2121, #$2235, #$7E8A, #$891C, #$9348, #$9288, - #$84DC, #$4FC9, #$70BB, #$6631, #$68C8, #$92F9, #$66FB, #$5F45, - #$4E28, #$4EE1, #$4EFC, #$4F00, #$4F03, #$4F39, #$4F56, #$4F92, - #$4F8A, #$4F9A, #$4F94, #$4FCD, #$5040, #$5022, #$4FFF, #$501E, - #$5046, #$5070, #$5042, #$5094, #$50F4, #$50D8, #$514A, #$5164, - #$519D, #$51BE, #$51EC, #$5215, #$529C, #$52A6, #$52C0, #$52DB, - #$5300, #$5307, #$5324, #$5372, #$5393, #$53B2, #$53DD, #$FA0E, - #$549C, #$548A, #$54A9, #$54FF, #$5586, #$5759, #$5765, #$57AC, - #$57C8, #$57C7, #$FA0F, #$FA10, #$589E, #$58B2, #$590B, #$5953, - #$595B, #$595D, #$5963, #$59A4, #$59BA, #$5B56, #$5BC0, #$752F, - #$5BD8, #$5BEC, #$5C1E, #$5CA6, #$5CBA, #$5CF5, #$5D27, #$5D53, - #$FA11, #$5D42, #$5D6D, #$5DB8, #$5DB9, #$5DD0, #$5F21, #$5F34, - #$5F67, #$5FB7, #$5FDE, #$605D, #$6085, #$608A, #$60DE, #$60D5, - #$6120, #$60F2, #$6111, #$6137, #$6130, #$6198, #$6213, #$62A6, - #$63F5, #$6460, #$649D, #$64CE, #$654E, #$6600, #$6615, #$663B, - #$6609, #$662E, #$661E, #$6624, #$6665, #$6657, #$6659, #$FA12, - #$6673, #$6699, #$66A0, #$66B2, #$66BF, #$66FA, #$670E, #$F929, - #$6766, #$67BB, #$6852, #$67C0, #$6801, #$6844, #$68CF, #$FA13, - #$6968, #$FA14, #$6998, #$69E2, #$6A30, #$6A6B, #$6A46, #$6A73, - #$6A7E, #$6AE2, #$6AE4, #$6BD6, #$6C3F, #$6C5C, #$6C86, #$6C6F, - #$6CDA, #$6D04, #$6D87, #$6D6F, - #$6D96, #$6DAC, #$6DCF, #$6DF8, #$6DF2, #$6DFC, #$6E39, #$6E5C, - #$6E27, #$6E3C, #$6EBF, #$6F88, #$6FB5, #$6FF5, #$7005, #$7007, - #$7028, #$7085, #$70AB, #$710F, #$7104, #$715C, #$7146, #$7147, - #$FA15, #$71C1, #$71FE, #$72B1, #$72BE, #$7324, #$FA16, #$7377, - #$73BD, #$73C9, #$73D6, #$73E3, #$73D2, #$7407, #$73F5, #$7426, - #$742A, #$7429, #$742E, #$7462, #$7489, #$749F, #$7501, #$756F, - #$7682, #$769C, #$769E, #$769B, #$76A6, #$FA17, #$7746, #$52AF, - #$7821, #$784E, #$7864, #$787A, #$7930, #$FA18, #$FA19, #$FA1A, - #$7994, #$FA1B, #$799B, #$7AD1, #$7AE7, #$FA1C, #$7AEB, #$7B9E, - #$FA1D, #$7D48, #$7D5C, #$7DB7, #$7DA0, #$7DD6, #$7E52, #$7F47, - #$7FA1, #$FA1E, #$8301, #$8362, #$837F, #$83C7, #$83F6, #$8448, - #$84B4, #$8553, #$8559, #$856B, #$FA1F, #$85B0, #$FA20, #$FA21, - #$8807, #$88F5, #$8A12, #$8A37, #$8A79, #$8AA7, #$8ABE, #$8ADF, - #$FA22, #$8AF6, #$8B53, #$8B7F, #$8CF0, #$8CF4, #$8D12, #$8D76, - #$FA23, #$8ECF, #$FA24, #$FA25, #$9067, #$90DE, #$FA26, #$9115, - #$9127, #$91DA, #$91D7, #$91DE, #$91ED, #$91EE, #$91E4, #$91E5, - #$9206, #$9210, #$920A, #$923A, #$9240, #$923C, #$924E, #$9259, - #$9251, #$9239, #$9267, #$92A7, #$9277, #$9278, #$92E7, #$92D7, - #$92D9, #$92D0, #$FA27, #$92D5, #$92E0, #$92D3, #$9325, #$9321, - #$92FB, #$FA28, #$931E, #$92FF, #$931D, #$9302, #$9370, #$9357, - #$93A4, #$93C6, #$93DE, #$93F8, #$9431, #$9445, #$9448, #$9592, - #$F9DC, #$FA29, #$969D, #$96AF, #$9733, #$973B, #$9743, #$974D, - #$974F, #$9751, #$9755, #$9857, #$9865, #$FA2A, #$FA2B, #$9927, - #$FA2C, #$999E, #$9A4E, #$9AD9, - #$9ADC, #$9B75, #$9B72, #$9B8F, #$9BB1, #$9BBB, #$9C00, #$9D70, - #$9D6B, #$FA2D, #$9E19, #$9ED1); - CP936E_1Map: array[0..21] of TBuffChar = ( - #$FE35, #$FE36, #$FE39, #$FE3A, #$FE3F, #$FE40, #$FE3D, #$FE3E, - #$FE41, #$FE42, #$FE43, #$FE44, #$FFFD, #$FFFD, #$FE3B, #$FE3C, - #$FE37, #$FE38, #$FE31, #$FFFD, #$FE33, #$FE34); - CP936E_2Map: array[0..5] of TBuffChar = ( - #$0251, #$FFFD, #$0144, #$0148, #$FFFD, #$0261); - CP950Map: array[0..313] of TBuffChar = ( - #$3000, #$FF0C, #$3001, #$3002, #$FF0E, #$2027, #$FF1B, #$FF1A, - #$FF1F, #$FF01, #$FE30, #$2026, #$2025, #$FE50, #$FE51, #$FE52, - #$00B7, #$FE54, #$FE55, #$FE56, #$FE57, #$FF5C, #$2013, #$FE31, - #$2014, #$FE33, #$2574, #$FE34, #$FE4F, #$FF08, #$FF09, #$FE35, - #$FE36, #$FF5B, #$FF5D, #$FE37, #$FE38, #$3014, #$3015, #$FE39, - #$FE3A, #$3010, #$3011, #$FE3B, #$FE3C, #$300A, #$300B, #$FE3D, - #$FE3E, #$3008, #$3009, #$FE3F, #$FE40, #$300C, #$300D, #$FE41, - #$FE42, #$300E, #$300F, #$FE43, #$FE44, #$FE59, #$FE5A, #$FE5B, - #$FE5C, #$FE5D, #$FE5E, #$2018, #$2019, #$201C, #$201D, #$301D, - #$301E, #$2035, #$2032, #$FF03, #$FF06, #$FF0A, #$203B, #$00A7, - #$3003, #$25CB, #$25CF, #$25B3, #$25B2, #$25CE, #$2606, #$2605, - #$25C7, #$25C6, #$25A1, #$25A0, #$25BD, #$25BC, #$32A3, #$2105, - #$00AF, #$FFE3, #$FF3F, #$02CD, #$FE49, #$FE4A, #$FE4D, #$FE4E, - #$FE4B, #$FE4C, #$FE5F, #$FE60, #$FE61, #$FF0B, #$FF0D, #$00D7, - #$00F7, #$00B1, #$221A, #$FF1C, #$FF1E, #$FF1D, #$2266, #$2267, - #$2260, #$221E, #$2252, #$2261, #$FE62, #$FE63, #$FE64, #$FE65, - #$FE66, #$FF5E, #$2229, #$222A, #$22A5, #$2220, #$221F, #$22BF, - #$33D2, #$33D1, #$222B, #$222E, #$2235, #$2234, #$2640, #$2642, - #$2295, #$2299, #$2191, #$2193, #$2190, #$2192, #$2196, #$2197, - #$2199, #$2198, #$2225, #$2223, #$FF0F, - #$FF3C, #$2215, #$FE68, #$FF04, #$FFE5, #$3012, #$FFE0, #$FFE1, - #$FF05, #$FF20, #$2103, #$2109, #$FE69, #$FE6A, #$FE6B, #$33D5, - #$339C, #$339D, #$339E, #$33CE, #$33A1, #$338E, #$338F, #$33C4, - #$00B0, #$5159, #$515B, #$515E, #$515D, #$5161, #$5163, #$55E7, - #$74E9, #$7CCE, #$2581, #$2582, #$2583, #$2584, #$2585, #$2586, - #$2587, #$2588, #$258F, #$258E, #$258D, #$258C, #$258B, #$258A, - #$2589, #$253C, #$2534, #$252C, #$2524, #$251C, #$2594, #$2500, - #$2502, #$2595, #$250C, #$2510, #$2514, #$2518, #$256D, #$256E, - #$2570, #$256F, #$2550, #$255E, #$256A, #$2561, #$25E2, #$25E3, - #$25E5, #$25E4, #$2571, #$2572, #$2573, #$FF10, #$FF11, #$FF12, - #$FF13, #$FF14, #$FF15, #$FF16, #$FF17, #$FF18, #$FF19, #$2160, - #$2161, #$2162, #$2163, #$2164, #$2165, #$2166, #$2167, #$2168, - #$2169, #$3021, #$3022, #$3023, #$3024, #$3025, #$3026, #$3027, - #$3028, #$3029, #$5341, #$5344, #$5345, #$FF21, #$FF22, #$FF23, - #$FF24, #$FF25, #$FF26, #$FF27, #$FF28, #$FF29, #$FF2A, #$FF2B, - #$FF2C, #$FF2D, #$FF2E, #$FF2F, #$FF30, #$FF31, #$FF32, #$FF33, - #$FF34, #$FF35, #$FF36, #$FF37, #$FF38, #$FF39, #$FF3A, #$FF41, - #$FF42, #$FF43, #$FF44, #$FF45, #$FF46, #$FF47, #$FF48, #$FF49, - #$FF4A, #$FF4B, #$FF4C, #$FF4D, #$FF4E, #$FF4F, #$FF50, #$FF51, - #$FF52, #$FF53, #$FF54, #$FF55, #$FF56); - CP950EMap: array[0..157 - 116 - 1] of TBuffChar = ( - #$7881, #$92B9, #$88CF, #$58BB, - #$6052, #$7CA7, #$5AFA, #$2554, #$2566, #$2557, #$2560, #$256C, - #$2563, #$255A, #$2569, #$255D, #$2552, #$2564, #$2555, #$255E, - #$256A, #$2561, #$2558, #$2567, #$255B, #$2553, #$2565, #$2556, - #$255F, #$256B, #$2562, #$2559, #$2568, #$255C, #$2551, #$2550, - #$256D, #$256E, #$2570, #$256F, #$2593); - MacCentralEuropeMap: ThtAnsiCharHighMap = ( - #$00C4, #$0100, #$0101, #$00C9, #$0104, #$00D6, #$00DC, #$00E1, - #$0105, #$010C, #$00E4, #$010D, #$0106, #$0107, #$00E9, #$0179, - #$017A, #$010E, #$00ED, #$010F, #$0112, #$0113, #$0116, #$00F3, - #$0117, #$00F4, #$00F6, #$00F5, #$00FA, #$011A, #$011B, #$00FC, - #$2020, #$00B0, #$0118, #$00A3, #$00A7, #$2022, #$00B6, #$00DF, - #$00AE, #$00A9, #$2122, #$0119, #$00A8, #$2260, #$0123, #$012E, - #$012F, #$012A, #$2264, #$2265, #$012B, #$0136, #$2202, #$2211, - #$0142, #$013B, #$013C, #$013D, #$013E, #$0139, #$013A, #$0145, - #$0146, #$0143, #$00AC, #$221A, #$0144, #$0147, #$2206, #$00AB, - #$00BB, #$2026, #$00A0, #$0148, #$0150, #$00D5, #$0151, #$014C, - #$2013, #$2014, #$201C, #$201D, #$2018, #$2019, #$00F7, #$25CA, - #$014D, #$0154, #$0155, #$0158, #$2039, #$203A, #$0159, #$0156, - #$0157, #$0160, #$201A, #$201E, #$0161, #$015A, #$015B, #$00C1, - #$0164, #$0165, #$00CD, #$017D, #$017E, #$016A, #$00D3, #$00D4, - #$016B, #$016E, #$00DA, #$016F, #$0170, #$0171, #$0172, #$0173, - #$00DD, #$00FD, #$0137, #$017B, #$0141, #$017C, #$0122, #$02C7); - MacRomanMap: ThtAnsiCharHighMap = ( - #$00C4, #$00C5, #$00C7, #$00C9, #$00D1, #$00D6, #$00DC, #$00E1, - #$00E0, #$00E2, #$00E4, #$00E3, #$00E5, #$00E7, #$00E9, #$00E8, - #$00EA, #$00EB, #$00ED, #$00EC, #$00EE, #$00EF, #$00F1, #$00F3, - #$00F2, #$00F4, #$00F6, #$00F5, #$00FA, #$00F9, #$00FB, #$00FC, - #$2020, #$00B0, #$00A2, #$00A3, #$00A7, #$2022, #$00B6, #$00DF, - #$00AE, #$00A9, #$2122, #$00B4, #$00A8, #$2260, #$00C6, #$00D8, - #$221E, #$00B1, #$2264, #$2265, #$00A5, #$00B5, #$2202, #$2211, - #$220F, #$03C0, #$222B, #$00AA, #$00BA, #$2126, #$00E6, #$00F8, - #$00BF, #$00A1, #$00AC, #$221A, #$0192, #$2248, #$2206, #$00AB, - #$00BB, #$2026, #$00A0, #$00C0, #$00C3, #$00D5, #$0152, #$0153, - #$2013, #$2014, #$201C, #$201D, #$2018, #$2019, #$00F7, #$25CA, - #$00FF, #$0178, #$2044, #$00A4, #$2039, #$203A, #$FB01, #$FB02, - #$2021, #$00B7, #$201A, #$201E, #$2030, #$00C2, #$00CA, #$00C1, - #$00CB, #$00C8, #$00CD, #$00CE, #$00CF, #$00CC, #$00D3, #$00D4, - #$FFFF, #$00D2, #$00DA, #$00DB, #$00D9, #$0131, #$02C6, #$02DC, - #$00AF, #$02D8, #$02D9, #$02DA, #$00B8, #$02DD, #$02DB, #$02C7); - MacCyrillicMap: ThtAnsiCharHighMap = ( - #$0410, #$0411, #$0412, #$0413, #$0414, #$0415, #$0416, #$0417, - #$0418, #$0419, #$041A, #$041B, #$041C, #$041D, #$041E, #$041F, - #$0420, #$0421, #$0422, #$0423, #$0424, #$0425, #$0426, #$0427, - #$0428, #$0429, #$042A, #$042B, #$042C, #$042D, #$042E, #$042F, - #$2020, #$00B0, #$00A2, #$00A3, #$00A7, #$2022, #$00B6, #$0406, - #$00AE, #$00A9, #$2122, #$0402, #$0452, #$2260, #$0403, #$0453, - #$221E, #$00B1, #$2264, #$2265, #$0456, #$00B5, #$2202, #$0408, - #$0404, #$0454, #$0407, #$0457, #$0409, #$0459, #$040A, #$045A, - #$0458, #$0405, #$00AC, #$221A, #$0192, #$2248, #$2206, #$00AB, - #$00BB, #$2026, #$00A0, #$040B, #$045B, #$040C, #$045C, #$0455, - #$2013, #$2014, #$201C, #$201D, #$2018, #$2019, #$00F7, #$201E, - #$040E, #$045E, #$040F, #$045F, #$2116, #$0401, #$0451, #$044F, - #$0430, #$0431, #$0432, #$0433, #$0434, #$0435, #$0436, #$0437, - #$0438, #$0439, #$043A, #$043B, #$043C, #$043D, #$043E, #$043F, - #$0440, #$0441, #$0442, #$0443, #$0444, #$0445, #$0446, #$0447, - #$0448, #$0449, #$044A, #$044B, #$044C, #$044D, #$044E, #$00A4); - MacGreekMap: ThtAnsiCharHighMap = ( - #$00C4, #$00B9, #$00B2, #$00C9, #$00B3, #$00D6, #$00DC, #$0385, - #$00E0, #$00E2, #$00E4, #$0384, #$00A8, #$00E7, #$00E9, #$00E8, - #$00EA, #$00EB, #$00A3, #$2122, #$00EE, #$00EF, #$2022, #$00BD, - #$2030, #$00F4, #$00F6, #$00A6, #$00AD, #$00F9, #$00FB, #$00FC, - #$2020, #$0393, #$0394, #$0398, #$039B, #$039E, #$03A0, #$00DF, - #$00AE, #$00A9, #$03A3, #$03AA, #$00A7, #$2260, #$00B0, #$0387, - #$0391, #$00B1, #$2264, #$2265, #$00A5, #$0392, #$0395, #$0396, - #$0397, #$0399, #$039A, #$039C, #$03A6, #$03AB, #$03A8, #$03A9, - #$03AC, #$039D, #$00AC, #$039F, #$03A1, #$2248, #$03A4, #$00AB, - #$00BB, #$2026, #$00A0, #$03A5, #$03A7, #$0386, #$0388, #$0153, - #$2013, #$2015, #$201C, #$201D, #$2018, #$2019, #$00F7, #$0389, - #$038A, #$038C, #$038E, #$03AD, #$03AE, #$03AF, #$03CC, #$038F, - #$03CD, #$03B1, #$03B2, #$03C8, #$03B4, #$03B5, #$03C6, #$03B3, - #$03B7, #$03B9, #$03BE, #$03BA, #$03BB, #$03BC, #$03BD, #$03BF, - #$03C0, #$03CE, #$03C1, #$03C3, #$03C4, #$03B8, #$03C9, #$03C2, - #$03C7, #$03C5, #$03B6, #$03CA, #$03CB, #$0390, #$03B0, #$FFFF); - MacIcelandicMap: ThtAnsiCharHighMap = ( - #$00C4, #$00C5, #$00C7, #$00C9, #$00D1, #$00D6, #$00DC, #$00E1, - #$00E0, #$00E2, #$00E4, #$00E3, #$00E5, #$00E7, #$00E9, #$00E8, - #$00EA, #$00EB, #$00ED, #$00EC, #$00EE, #$00EF, #$00F1, #$00F3, - #$00F2, #$00F4, #$00F6, #$00F5, #$00FA, #$00F9, #$00FB, #$00FC, - #$00DD, #$00B0, #$00A2, #$00A3, #$00A7, #$2022, #$00B6, #$00DF, - #$00AE, #$00A9, #$2122, #$00B4, #$00A8, #$2260, #$00C6, #$00D8, - #$221E, #$00B1, #$2264, #$2265, #$00A5, #$00B5, #$2202, #$2211, - #$220F, #$03C0, #$222B, #$00AA, #$00BA, #$2126, #$00E6, #$00F8, - #$00BF, #$00A1, #$00AC, #$221A, #$0192, #$2248, #$2206, #$00AB, - #$00BB, #$2026, #$00A0, #$00C0, #$00C3, #$00D5, #$0152, #$0153, - #$2013, #$2014, #$201C, #$201D, #$2018, #$2019, #$00F7, #$25CA, - #$00FF, #$0178, #$2044, #$00A4, #$00D0, #$00F0, #$00DE, #$00FE, - #$00FD, #$00B7, #$201A, #$201E, #$2030, #$00C2, #$00CA, #$00C1, - #$00CB, #$00C8, #$00CD, #$00CE, #$00CF, #$00CC, #$00D3, #$00D4, - #$FFFF, #$00D2, #$00DA, #$00DB, #$00D9, #$0131, #$02C6, #$02DC, - #$00AF, #$02D8, #$02D9, #$02DA, #$00B8, #$02DD, #$02DB, #$02C7); - MacTurkishMap: ThtAnsiCharHighMap = ( - #$00C4, #$00C5, #$00C7, #$00C9, #$00D1, #$00D6, #$00DC, #$00E1, - #$00E0, #$00E2, #$00E4, #$00E3, #$00E5, #$00E7, #$00E9, #$00E8, - #$00EA, #$00EB, #$00ED, #$00EC, #$00EE, #$00EF, #$00F1, #$00F3, - #$00F2, #$00F4, #$00F6, #$00F5, #$00FA, #$00F9, #$00FB, #$00FC, - #$2020, #$00B0, #$00A2, #$00A3, #$00A7, #$2022, #$00B6, #$00DF, - #$00AE, #$00A9, #$2122, #$00B4, #$00A8, #$2260, #$00C6, #$00D8, - #$221E, #$00B1, #$2264, #$2265, #$00A5, #$00B5, #$2202, #$2211, - #$220F, #$03C0, #$222B, #$00AA, #$00BA, #$2126, #$00E6, #$00F8, - #$00BF, #$00A1, #$00AC, #$221A, #$0192, #$2248, #$2206, #$00AB, - #$00BB, #$2026, #$00A0, #$00C0, #$00C3, #$00D5, #$0152, #$0153, - #$2013, #$2014, #$201C, #$201D, #$2018, #$2019, #$00F7, #$25CA, - #$00FF, #$0178, #$011E, #$011F, #$0130, #$0131, #$015E, #$015F, - #$2021, #$00B7, #$201A, #$201E, #$2030, #$00C2, #$00CA, #$00C1, - #$00CB, #$00C8, #$00CD, #$00CE, #$00CF, #$00CC, #$00D3, #$00D4, - #$FFFF, #$00D2, #$00DA, #$00DB, #$00D9, #$FFFF, #$02C6, #$02DC, - #$00AF, #$02D8, #$02D9, #$02DA, #$00B8, #$02DD, #$02DB, #$02C7); - MacArabicMap: ThtAnsiCharHighMap = ( - #$00C4, #$00A0, #$00C7, #$00C9, #$00D1, #$00D6, #$00DC, #$00E1, - #$00E0, #$00E2, #$00E4, #$06BA, #$00AB, #$00E7, #$00E9, #$00E8, - #$00EA, #$00EB, #$00ED, #$2026, #$00EE, #$00EF, #$00F1, #$00F3, - #$00BB, #$00F4, #$00F6, #$00F7, #$00FA, #$00F9, #$00FB, #$00FC, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$066A, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$060C, #$FFFD, #$FFFD, #$FFFD, - #$0660, #$0661, #$0662, #$0663, #$0664, #$0665, #$0666, #$0667, - #$0668, #$0669, #$FFFD, #$061B, #$FFFD, #$FFFD, #$FFFD, #$061F, - #$066D, #$0621, #$0622, #$0623, #$0624, #$0625, #$0626, #$0627, - #$0628, #$0629, #$062A, #$062B, #$062C, #$062D, #$062E, #$062F, - #$0630, #$0631, #$0632, #$0633, #$0634, #$0635, #$0636, #$0637, - #$0638, #$0639, #$063A, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$0640, #$0641, #$0642, #$0643, #$0644, #$0645, #$0646, #$0647, - #$0648, #$0649, #$064A, #$064B, #$064C, #$064D, #$064E, #$064F, - #$0650, #$0651, #$0652, #$067E, #$0679, #$0686, #$06D5, #$06A4, - #$06AF, #$0688, #$0691, #$FFFD, #$FFFD, #$FFFD, #$0698, #$06D2); - MacCroatianMap: ThtAnsiCharHighMap = ( - #$00C4, #$00C5, #$00C7, #$00C9, #$00D1, #$00D6, #$00DC, #$00E1, - #$00E0, #$00E2, #$00E4, #$00E3, #$00E5, #$00E7, #$00E9, #$00E8, - #$00EA, #$00EB, #$00ED, #$00EC, #$00EE, #$00EF, #$00F1, #$00F3, - #$00F2, #$00F4, #$00F6, #$00F5, #$00FA, #$00F9, #$00FB, #$00FC, - #$2020, #$00B0, #$00A2, #$00A3, #$00A7, #$2022, #$00B6, #$00DF, - #$00AE, #$0160, #$2122, #$00B4, #$00A8, #$2260, #$017D, #$00D8, - #$221E, #$00B1, #$2264, #$2265, #$2206, #$00B5, #$2202, #$2211, - #$220F, #$0161, #$222B, #$00AA, #$00BA, #$2126, #$017E, #$00F8, - #$00BF, #$00A1, #$00AC, #$221A, #$0192, #$2248, #$0106, #$00AB, - #$010C, #$2026, #$00A0, #$00C0, #$00C3, #$00D5, #$0152, #$0153, - #$0110, #$2014, #$201C, #$201D, #$2018, #$2019, #$00F7, #$25CA, - #$FFFD, #$00A9, #$2044, #$00A4, #$2039, #$203A, #$00C6, #$00BB, - #$2013, #$00B7, #$201A, #$201E, #$2030, #$00C2, #$0107, #$00C1, - #$010D, #$00C8, #$00CD, #$00CE, #$00CF, #$00CC, #$00D3, #$00D4, - #$0111, #$00D2, #$00DA, #$00DB, #$00D9, #$0131, #$02C6, #$02DC, - #$00AF, #$03C0, #$00CB, #$02DA, #$00B8, #$00CA, #$00E6, #$02C7); - MacHebrewMap: ThtAnsiCharHighMap = ( - #$00C4, #$FB1F, #$00C7, #$00C9, #$00D1, #$00D6, #$00DC, #$00E1, - #$00E0, #$00E2, #$00E4, #$00E3, #$00E5, #$00E7, #$00E9, #$00E8, - #$00EA, #$00EB, #$00ED, #$00EC, #$00EE, #$00EF, #$00F1, #$00F3, - #$00F2, #$00F4, #$00F6, #$00F5, #$00FA, #$00F9, #$00FB, #$00FC, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$20AA, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$201E, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$05BC, #$FB4B, - #$FB35, #$2026, #$00A0, #$05B8, #$05B7, #$05B5, #$05B6, #$05B4, - #$2013, #$2014, #$201C, #$201D, #$2018, #$2019, #$FB2A, #$FB2B, - #$05BF, #$05B0, #$05B2, #$05B1, #$05BB, #$05B9, #$FFFD, #$05B3, - #$05D0, #$05D1, #$05D2, #$05D3, #$05D4, #$05D5, #$05D6, #$05D7, - #$05D8, #$05D9, #$05DA, #$05DB, #$05DC, #$05DD, #$05DE, #$05DF, - #$05E0, #$05E1, #$05E2, #$05E3, #$05E4, #$05E5, #$05E6, #$05E7, - #$05E8, #$05E9, #$05EA, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD); - MacRomaniaMap: ThtAnsiCharHighMap = ( - #$00C4, #$00C5, #$00C7, #$00C9, #$00D1, #$00D6, #$00DC, #$00E1, - #$00E0, #$00E2, #$00E4, #$00E3, #$00E5, #$00E7, #$00E9, #$00E8, - #$00EA, #$00EB, #$00ED, #$00EC, #$00EE, #$00EF, #$00F1, #$00F3, - #$00F2, #$00F4, #$00F6, #$00F5, #$00FA, #$00F9, #$00FB, #$00FC, - #$2020, #$00B0, #$00A2, #$00A3, #$00A7, #$2022, #$00B6, #$00DF, - #$00AE, #$00A9, #$2122, #$00B4, #$00A8, #$2260, #$0102, #$015E, - #$221E, #$00B1, #$2264, #$2265, #$00A5, #$00B5, #$2202, #$2211, - #$220F, #$03C0, #$222B, #$00AA, #$00BA, #$2126, #$0103, #$015F, - #$00BF, #$00A1, #$00AC, #$221A, #$0192, #$2248, #$2206, #$00AB, - #$00BB, #$2026, #$00A0, #$00C0, #$00C3, #$00D5, #$0152, #$0153, - #$2013, #$2014, #$201C, #$201D, #$2018, #$2019, #$00F7, #$25CA, - #$00FF, #$0178, #$2044, #$00A4, #$2039, #$203A, #$0162, #$0163, - #$2021, #$00B7, #$201A, #$201E, #$2030, #$00C2, #$00CA, #$00C1, - #$00CB, #$00C8, #$00CD, #$00CE, #$00CF, #$00CC, #$00D3, #$00D4, - #$FFFD, #$00D2, #$00DA, #$00DB, #$00D9, #$0131, #$02C6, #$02DC, - #$00AF, #$02D8, #$02D9, #$02DA, #$00B8, #$02DD, #$02DB, #$02C7); - MacThaiMap: ThtAnsiCharHighMap = ( - #$00AB, #$00BB, #$2026, #$F88C, #$F88F, #$F892, #$F895, #$F898, - #$F88B, #$F88E, #$F891, #$F894, #$F897, #$201C, #$201D, #$F899, - #$FFFD, #$2022, #$F884, #$F889, #$F885, #$F886, #$F887, #$F888, - #$F88A, #$F88D, #$F890, #$F893, #$F896, #$2018, #$2019, #$FFFD, - #$00A0, #$0E01, #$0E02, #$0E03, #$0E04, #$0E05, #$0E06, #$0E07, - #$0E08, #$0E09, #$0E0A, #$0E0B, #$0E0C, #$0E0D, #$0E0E, #$0E0F, - #$0E10, #$0E11, #$0E12, #$0E13, #$0E14, #$0E15, #$0E16, #$0E17, - #$0E18, #$0E19, #$0E1A, #$0E1B, #$0E1C, #$0E1D, #$0E1E, #$0E1F, - #$0E20, #$0E21, #$0E22, #$0E23, #$0E24, #$0E25, #$0E26, #$0E27, - #$0E28, #$0E29, #$0E2A, #$0E2B, #$0E2C, #$0E2D, #$0E2E, #$0E2F, - #$0E30, #$0E31, #$0E32, #$0E33, #$0E34, #$0E35, #$0E36, #$0E37, - #$0E38, #$0E39, #$0E3A, #$FEFF, #$200B, #$2013, #$2014, #$0E3F, - #$0E40, #$0E41, #$0E42, #$0E43, #$0E44, #$0E45, #$0E46, #$0E47, - #$0E48, #$0E49, #$0E4A, #$0E4B, #$0E4C, #$0E4D, #$2122, #$0E4F, - #$0E50, #$0E51, #$0E52, #$0E53, #$0E54, #$0E55, #$0E56, #$0E57, - #$0E58, #$0E59, #$00AE, #$00A9, #$FFFD, #$FFFD, #$FFFD, #$FFFD); - MacUkraineMap: ThtAnsiCharHighMap = ( - #$0410, #$0411, #$0412, #$0413, #$0414, #$0415, #$0416, #$0417, - #$0418, #$0419, #$041A, #$041B, #$041C, #$041D, #$041E, #$041F, - #$0420, #$0421, #$0422, #$0423, #$0424, #$0425, #$0426, #$0427, - #$0428, #$0429, #$042A, #$042B, #$042C, #$042D, #$042E, #$042F, - #$2020, #$00B0, #$0490, #$00A3, #$00A7, #$2022, #$00B6, #$0406, - #$00AE, #$00A9, #$2122, #$0402, #$0452, #$2260, #$0403, #$0453, - #$221E, #$00B1, #$2264, #$2265, #$0456, #$00B5, #$0491, #$0408, - #$0404, #$0454, #$0407, #$0457, #$0409, #$0459, #$040A, #$045A, - #$0458, #$0405, #$00AC, #$221A, #$0192, #$2248, #$2206, #$00AB, - #$00BB, #$2026, #$00A0, #$040B, #$045B, #$040C, #$045C, #$0455, - #$2013, #$2014, #$201C, #$201D, #$2018, #$2019, #$00F7, #$201E, - #$040E, #$045E, #$040F, #$045F, #$2116, #$0401, #$0451, #$044F, - #$0430, #$0431, #$0432, #$0433, #$0434, #$0435, #$0436, #$0437, - #$0438, #$0439, #$043A, #$043B, #$043C, #$043D, #$043E, #$043F, - #$0440, #$0441, #$0442, #$0443, #$0444, #$0445, #$0446, #$0447, - #$0448, #$0449, #$044A, #$044B, #$044C, #$044D, #$044E, #$00A4); - CP29001: ThtAnsiCharMap = ( - #$0000, #$0386, #$0388, #$0389, #$038A, #$038C, #$038E, #$00B0, - #$25D8, #$25CB, #$25D9, #$2642, #$2640, #$266A, #$266C, #$263C, - #$25B6, #$25C0, #$2195, #$203C, #$00B6, #$00A7, #$00A3, #$038F, - #$2191, #$2193, #$2192, #$2190, #$00CB, #$2194, #$25B2, #$25BC, - #$0020, #$0021, #$0022, #$0023, #$0024, #$0025, #$0026, #$0027, - #$0028, #$0029, #$002A, #$002B, #$002C, #$002D, #$002E, #$002F, - #$0030, #$0031, #$0032, #$0033, #$0034, #$0035, #$0036, #$0037, - #$0038, #$0039, #$003A, #$003B, #$003C, #$003D, #$003E, #$003F, - #$0040, #$0041, #$0042, #$0043, #$0044, #$0045, #$0046, #$0047, - #$0048, #$0049, #$004A, #$004B, #$004C, #$004D, #$004E, #$004F, - #$0050, #$0051, #$0052, #$0053, #$0054, #$0055, #$0056, #$0057, - #$0058, #$0059, #$005A, #$005B, #$005C, #$005D, #$005E, #$005F, - #$0060, #$0061, #$0062, #$0063, #$0064, #$0065, #$0066, #$0067, - #$0068, #$0069, #$006A, #$006B, #$006C, #$006D, #$006E, #$006F, - #$0070, #$0071, #$0072, #$0073, #$0074, #$0075, #$0076, #$0077, - #$0078, #$0079, #$007A, #$007B, #$007C, #$007D, #$007E, #$007F, - #$00C7, #$00FC, #$00E9, #$00E2, #$00E4, #$00E0, #$00E5, #$00E7, - #$00EA, #$00EB, #$00E8, #$00EF, #$00EE, #$00EC, #$00C4, #$00C5, - #$00C9, #$00E6, #$00C6, #$00F4, #$00F6, #$00F2, #$00FB, #$00F9, - #$0391, #$00D6, #$00DC, #$00F8, #$03B1, #$00D8, #$03AC, #$0392, - #$00E1, #$00ED, #$00F3, #$00FA, #$00F1, #$00D1, #$03B2, #$0393, - #$03B3, #$0394, #$03B4, #$0395, #$03B5, #$03AD, #$0396, #$03B6, - #$0397, #$03B7, #$03AE, #$2502, #$00AA, #$00C1, #$00C2, #$00C0, - #$0398, #$03B8, #$2551, #$2557, #$255D, #$0399, #$03AA, #$2510, - #$2514, #$00BA, #$00A1, #$00BF, #$2500, #$0384, #$00E3, #$00C3, - #$255A, #$2554, #$03B9, #$03AF, #$03CA, #$2550, #$0390, #$039A, - #$03BA, #$039B, #$00CA, #$03BB, #$039C, #$03BC, #$00CD, #$039D, - #$03BD, #$2518, #$250C, #$039E, #$03BE, #$039F, #$03BF, #$03CC, - #$00D3, #$00DF, #$00D4, #$03A0, #$00F5, #$00D5, #$03C0, #$03A1, - #$03C1, #$00DA, #$03A3, #$03C2, #$03C3, #$03A4, #$03C4, #$03A5, - #$03AB, #$03C5, #$03CD, #$03CB, #$03B0, #$03A6, #$03C6, #$03A7, - #$03C7, #$03A8, #$0387, #$03C8, #$03A9, #$03C9, #$03CE, #$F8FF); - KOI8_RMap: ThtAnsiCharHighMap = ( - #$2500, #$2502, #$250C, #$2510, #$2514, #$2518, #$251C, #$2524, - #$252C, #$2534, #$253C, #$2580, #$2584, #$2588, #$258C, #$2590, - #$2591, #$2592, #$2593, #$2320, #$25A0, #$2219, #$221A, #$2248, - #$2264, #$2265, #$00A0, #$2321, #$00B0, #$00B2, #$00B7, #$00F7, - #$2550, #$2551, #$2552, #$0451, #$2553, #$2554, #$2555, #$2556, - #$2557, #$2558, #$2559, #$255A, #$255B, #$255C, #$255D, #$255E, - #$255F, #$2560, #$2561, #$0401, #$2562, #$2563, #$2564, #$2565, - #$2566, #$2567, #$2568, #$2569, #$256A, #$256B, #$256C, #$00A9, - #$044E, #$0430, #$0431, #$0446, #$0434, #$0435, #$0444, #$0433, - #$0445, #$0438, #$0439, #$043A, #$043B, #$043C, #$043D, #$043E, - #$043F, #$044F, #$0440, #$0441, #$0442, #$0443, #$0436, #$0432, - #$044C, #$044B, #$0437, #$0448, #$044D, #$0449, #$0447, #$044A, - #$042E, #$0410, #$0411, #$0426, #$0414, #$0415, #$0424, #$0413, - #$0425, #$0418, #$0419, #$041A, #$041B, #$041C, #$041D, #$041E, - #$041F, #$042F, #$0420, #$0421, #$0422, #$0423, #$0416, #$0412, - #$042C, #$042B, #$0417, #$0428, #$042D, #$0429, #$0427, #$042A); - KOI8_TMap: ThtAnsiCharHighMap = ( - #$049B, #$0493, #$201A, #$0492, #$201E, #$2026, #$2020, #$2021, - #$FFFD, #$2030, #$04B3, #$2039, #$04B2, #$04B7, #$04B6, #$FFFD, - #$049A, #$2018, #$2019, #$201C, #$201D, #$2022, #$2013, #$2014, - #$FFFD, #$2122, #$FFFD, #$203A, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$04EF, #$04EE, #$0451, #$00A4, #$04E3, #$00A6, #$00A7, - #$FFFD, #$FFFD, #$FFFD, #$00AB, #$00AC, #$00AD, #$00AE, #$FFFD, - #$00B0, #$00B1, #$00B2, #$0401, #$FFFD, #$04E2, #$00B6, #$00B7, - #$FFFD, #$2116, #$FFFD, #$00BB, #$FFFD, #$FFFD, #$FFFD, #$00A9, - #$044E, #$0430, #$0431, #$0446, #$0434, #$0435, #$0444, #$0433, - #$0445, #$0438, #$0439, #$043A, #$043B, #$043C, #$043D, #$043E, - #$043F, #$044F, #$0440, #$0441, #$0442, #$0443, #$0436, #$0432, - #$044C, #$044B, #$0437, #$0448, #$044D, #$0449, #$0447, #$044A, - #$042E, #$0410, #$0411, #$0426, #$0414, #$0415, #$0424, #$0413, - #$0425, #$0418, #$0419, #$041A, #$041B, #$041C, #$041D, #$041E, - #$041F, #$042F, #$0420, #$0421, #$0422, #$0423, #$0416, #$0412, - #$042C, #$042B, #$0417, #$0428, #$042D, #$0429, #$0427, #$042A); - GB2312_1Map: array[0..830] of TBuffChar = ( - #$3000, #$3001, #$3002, #$30FB, #$02C9, #$02C7, #$00A8, #$3003, - #$3005, #$2015, #$FF5E, #$2016, #$2026, #$2018, #$2019, #$201C, - #$201D, #$3014, #$3015, #$3008, #$3009, #$300A, #$300B, #$300C, - #$300D, #$300E, #$300F, #$3016, #$3017, #$3010, #$3011, #$00B1, - #$00D7, #$00F7, #$2236, #$2227, #$2228, #$2211, #$220F, #$222A, - #$2229, #$2208, #$2237, #$221A, #$22A5, #$2225, #$2220, #$2312, - #$2299, #$222B, #$222E, #$2261, #$224C, #$2248, #$223D, #$221D, - #$2260, #$226E, #$226F, #$2264, #$2265, #$221E, #$2235, #$2234, - #$2642, #$2640, #$00B0, #$2032, #$2033, #$2103, #$FF04, #$00A4, - #$FFE0, #$FFE1, #$2030, #$00A7, #$2116, #$2606, #$2605, #$25CB, - #$25CF, #$25CE, #$25C7, #$25C6, #$25A1, #$25A0, #$25B3, #$25B2, - #$203B, #$2192, #$2190, #$2191, #$2193, #$3013, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$2488, #$2489, #$248A, #$248B, #$248C, #$248D, #$248E, #$248F, - #$2490, #$2491, #$2492, #$2493, #$2494, #$2495, #$2496, #$2497, - #$2498, #$2499, #$249A, #$249B, #$2474, #$2475, #$2476, #$2477, - #$2478, #$2479, #$247A, #$247B, #$247C, #$247D, #$247E, #$247F, - #$2480, #$2481, #$2482, #$2483, #$2484, #$2485, #$2486, #$2487, - #$2460, #$2461, #$2462, #$2463, #$2464, #$2465, #$2466, #$2467, - #$2468, #$2469, #$FFFD, #$FFFD, #$3220, #$3221, #$3222, #$3223, - #$3224, #$3225, #$3226, #$3227, #$3228, #$3229, #$FFFD, #$FFFD, - #$2160, #$2161, #$2162, #$2163, #$2164, #$2165, #$2166, #$2167, - #$2168, #$2169, #$216A, #$216B, #$FFFD, #$FFFD, - #$FF01, #$FF02, #$FF03, #$FFE5, #$FF05, #$FF06, #$FF07, #$FF08, - #$FF09, #$FF0A, #$FF0B, #$FF0C, #$FF0D, #$FF0E, #$FF0F, #$FF10, - #$FF11, #$FF12, #$FF13, #$FF14, #$FF15, #$FF16, #$FF17, #$FF18, - #$FF19, #$FF1A, #$FF1B, #$FF1C, #$FF1D, #$FF1E, #$FF1F, #$FF20, - #$FF21, #$FF22, #$FF23, #$FF24, #$FF25, #$FF26, #$FF27, #$FF28, - #$FF29, #$FF2A, #$FF2B, #$FF2C, #$FF2D, #$FF2E, #$FF2F, #$FF30, - #$FF31, #$FF32, #$FF33, #$FF34, #$FF35, #$FF36, #$FF37, #$FF38, - #$FF39, #$FF3A, #$FF3B, #$FF3C, #$FF3D, #$FF3E, #$FF3F, #$FF40, - #$FF41, #$FF42, #$FF43, #$FF44, #$FF45, #$FF46, #$FF47, #$FF48, - #$FF49, #$FF4A, #$FF4B, #$FF4C, #$FF4D, #$FF4E, #$FF4F, #$FF50, - #$FF51, #$FF52, #$FF53, #$FF54, #$FF55, #$FF56, #$FF57, #$FF58, - #$FF59, #$FF5A, #$FF5B, #$FF5C, #$FF5D, #$FFE3, - #$3041, #$3042, #$3043, #$3044, #$3045, #$3046, #$3047, #$3048, - #$3049, #$304A, #$304B, #$304C, #$304D, #$304E, #$304F, #$3050, - #$3051, #$3052, #$3053, #$3054, #$3055, #$3056, #$3057, #$3058, - #$3059, #$305A, #$305B, #$305C, #$305D, #$305E, #$305F, #$3060, - #$3061, #$3062, #$3063, #$3064, #$3065, #$3066, #$3067, #$3068, - #$3069, #$306A, #$306B, #$306C, #$306D, #$306E, #$306F, #$3070, - #$3071, #$3072, #$3073, #$3074, #$3075, #$3076, #$3077, #$3078, - #$3079, #$307A, #$307B, #$307C, #$307D, #$307E, #$307F, #$3080, - #$3081, #$3082, #$3083, #$3084, #$3085, #$3086, #$3087, #$3088, - #$3089, #$308A, #$308B, #$308C, #$308D, #$308E, #$308F, #$3090, - #$3091, #$3092, #$3093, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$30A1, #$30A2, #$30A3, #$30A4, #$30A5, #$30A6, #$30A7, #$30A8, - #$30A9, #$30AA, #$30AB, #$30AC, #$30AD, #$30AE, #$30AF, #$30B0, - #$30B1, #$30B2, #$30B3, #$30B4, #$30B5, #$30B6, #$30B7, #$30B8, - #$30B9, #$30BA, #$30BB, #$30BC, #$30BD, #$30BE, #$30BF, #$30C0, - #$30C1, #$30C2, #$30C3, #$30C4, #$30C5, #$30C6, #$30C7, #$30C8, - #$30C9, #$30CA, #$30CB, #$30CC, #$30CD, #$30CE, #$30CF, #$30D0, - #$30D1, #$30D2, #$30D3, #$30D4, #$30D5, #$30D6, #$30D7, #$30D8, - #$30D9, #$30DA, #$30DB, #$30DC, #$30DD, #$30DE, #$30DF, #$30E0, - #$30E1, #$30E2, #$30E3, #$30E4, #$30E5, #$30E6, #$30E7, #$30E8, - #$30E9, #$30EA, #$30EB, #$30EC, #$30ED, #$30EE, #$30EF, #$30F0, - #$30F1, #$30F2, #$30F3, #$30F4, #$30F5, #$30F6, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$0391, #$0392, #$0393, #$0394, #$0395, #$0396, #$0397, #$0398, - #$0399, #$039A, #$039B, #$039C, #$039D, #$039E, #$039F, #$03A0, - #$03A1, #$03A3, #$03A4, #$03A5, #$03A6, #$03A7, #$03A8, #$03A9, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$03B1, #$03B2, #$03B3, #$03B4, #$03B5, #$03B6, #$03B7, #$03B8, - #$03B9, #$03BA, #$03BB, #$03BC, #$03BD, #$03BE, #$03BF, #$03C0, - #$03C1, #$03C3, #$03C4, #$03C5, #$03C6, #$03C7, #$03C8, #$03C9, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$0410, #$0411, #$0412, #$0413, #$0414, #$0415, #$0401, #$0416, - #$0417, #$0418, #$0419, #$041A, #$041B, #$041C, #$041D, #$041E, - #$041F, #$0420, #$0421, #$0422, #$0423, #$0424, #$0425, #$0426, - #$0427, #$0428, #$0429, #$042A, #$042B, #$042C, #$042D, #$042E, - #$042F, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$0430, #$0431, #$0432, #$0433, #$0434, #$0435, #$0451, #$0436, - #$0437, #$0438, #$0439, #$043A, #$043B, #$043C, #$043D, #$043E, - #$043F, #$0440, #$0441, #$0442, #$0443, #$0444, #$0445, #$0446, - #$0447, #$0448, #$0449, #$044A, #$044B, #$044C, #$044D, #$044E, - #$044F, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$0101, #$00E1, #$01CE, #$00E0, #$0113, #$00E9, #$011B, #$00E8, - #$012B, #$00ED, #$01D0, #$00EC, #$014D, #$00F3, #$01D2, #$00F2, - #$016B, #$00FA, #$01D4, #$00F9, #$01D6, #$01D8, #$01DA, #$01DC, - #$00FC, #$00EA, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$3105, #$3106, #$3107, #$3108, - #$3109, #$310A, #$310B, #$310C, #$310D, #$310E, #$310F, #$3110, - #$3111, #$3112, #$3113, #$3114, #$3115, #$3116, #$3117, #$3118, - #$3119, #$311A, #$311B, #$311C, #$311D, #$311E, #$311F, #$3120, - #$3121, #$3122, #$3123, #$3124, #$3125, #$3126, #$3127, #$3128, - #$3129, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$2500, #$2501, #$2502, #$2503, #$2504, - #$2505, #$2506, #$2507, #$2508, #$2509, #$250A, #$250B, #$250C, - #$250D, #$250E, #$250F, #$2510, #$2511, #$2512, #$2513, #$2514, - #$2515, #$2516, #$2517, #$2518, #$2519, #$251A, #$251B, #$251C, - #$251D, #$251E, #$251F, #$2520, #$2521, #$2522, #$2523, #$2524, - #$2525, #$2526, #$2527, #$2528, #$2529, #$252A, #$252B, #$252C, - #$252D, #$252E, #$252F, #$2530, #$2531, #$2532, #$2533, #$2534, - #$2535, #$2536, #$2537, #$2538, #$2539, #$253A, #$253B, #$253C, - #$253D, #$253E, #$253F, #$2540, #$2541, #$2542, #$2543, #$2544, - #$2545, #$2546, #$2547, #$2548, #$2549, #$254A, #$254B); - GB2312_2Map: array[0..6767] of TBuffChar = ( - #$554A, #$963F, #$57C3, #$6328, #$54CE, #$5509, #$54C0, #$7691, - #$764C, #$853C, #$77EE, #$827E, #$788D, #$7231, #$9698, #$978D, - #$6C28, #$5B89, #$4FFA, #$6309, #$6697, #$5CB8, #$80FA, #$6848, - #$80AE, #$6602, #$76CE, #$51F9, #$6556, #$71AC, #$7FF1, #$8884, - #$50B2, #$5965, #$61CA, #$6FB3, #$82AD, #$634C, #$6252, #$53ED, - #$5427, #$7B06, #$516B, #$75A4, #$5DF4, #$62D4, #$8DCB, #$9776, - #$628A, #$8019, #$575D, #$9738, #$7F62, #$7238, #$767D, #$67CF, - #$767E, #$6446, #$4F70, #$8D25, #$62DC, #$7A17, #$6591, #$73ED, - #$642C, #$6273, #$822C, #$9881, #$677F, #$7248, #$626E, #$62CC, - #$4F34, #$74E3, #$534A, #$529E, #$7ECA, #$90A6, #$5E2E, #$6886, - #$699C, #$8180, #$7ED1, #$68D2, #$78C5, #$868C, #$9551, #$508D, - #$8C24, #$82DE, #$80DE, #$5305, #$8912, #$5265, - #$8584, #$96F9, #$4FDD, #$5821, #$9971, #$5B9D, #$62B1, #$62A5, - #$66B4, #$8C79, #$9C8D, #$7206, #$676F, #$7891, #$60B2, #$5351, - #$5317, #$8F88, #$80CC, #$8D1D, #$94A1, #$500D, #$72C8, #$5907, - #$60EB, #$7119, #$88AB, #$5954, #$82EF, #$672C, #$7B28, #$5D29, - #$7EF7, #$752D, #$6CF5, #$8E66, #$8FF8, #$903C, #$9F3B, #$6BD4, - #$9119, #$7B14, #$5F7C, #$78A7, #$84D6, #$853D, #$6BD5, #$6BD9, - #$6BD6, #$5E01, #$5E87, #$75F9, #$95ED, #$655D, #$5F0A, #$5FC5, - #$8F9F, #$58C1, #$81C2, #$907F, #$965B, #$97AD, #$8FB9, #$7F16, - #$8D2C, #$6241, #$4FBF, #$53D8, #$535E, #$8FA8, #$8FA9, #$8FAB, - #$904D, #$6807, #$5F6A, #$8198, #$8868, #$9CD6, #$618B, #$522B, - #$762A, #$5F6C, #$658C, #$6FD2, #$6EE8, #$5BBE, #$6448, #$5175, - #$51B0, #$67C4, #$4E19, #$79C9, #$997C, #$70B3, - #$75C5, #$5E76, #$73BB, #$83E0, #$64AD, #$62E8, #$94B5, #$6CE2, - #$535A, #$52C3, #$640F, #$94C2, #$7B94, #$4F2F, #$5E1B, #$8236, - #$8116, #$818A, #$6E24, #$6CCA, #$9A73, #$6355, #$535C, #$54FA, - #$8865, #$57E0, #$4E0D, #$5E03, #$6B65, #$7C3F, #$90E8, #$6016, - #$64E6, #$731C, #$88C1, #$6750, #$624D, #$8D22, #$776C, #$8E29, - #$91C7, #$5F69, #$83DC, #$8521, #$9910, #$53C2, #$8695, #$6B8B, - #$60ED, #$60E8, #$707F, #$82CD, #$8231, #$4ED3, #$6CA7, #$85CF, - #$64CD, #$7CD9, #$69FD, #$66F9, #$8349, #$5395, #$7B56, #$4FA7, - #$518C, #$6D4B, #$5C42, #$8E6D, #$63D2, #$53C9, #$832C, #$8336, - #$67E5, #$78B4, #$643D, #$5BDF, #$5C94, #$5DEE, #$8BE7, #$62C6, - #$67F4, #$8C7A, #$6400, #$63BA, #$8749, #$998B, #$8C17, #$7F20, - #$94F2, #$4EA7, #$9610, #$98A4, #$660C, #$7316, - #$573A, #$5C1D, #$5E38, #$957F, #$507F, #$80A0, #$5382, #$655E, - #$7545, #$5531, #$5021, #$8D85, #$6284, #$949E, #$671D, #$5632, - #$6F6E, #$5DE2, #$5435, #$7092, #$8F66, #$626F, #$64A4, #$63A3, - #$5F7B, #$6F88, #$90F4, #$81E3, #$8FB0, #$5C18, #$6668, #$5FF1, - #$6C89, #$9648, #$8D81, #$886C, #$6491, #$79F0, #$57CE, #$6A59, - #$6210, #$5448, #$4E58, #$7A0B, #$60E9, #$6F84, #$8BDA, #$627F, - #$901E, #$9A8B, #$79E4, #$5403, #$75F4, #$6301, #$5319, #$6C60, - #$8FDF, #$5F1B, #$9A70, #$803B, #$9F7F, #$4F88, #$5C3A, #$8D64, - #$7FC5, #$65A5, #$70BD, #$5145, #$51B2, #$866B, #$5D07, #$5BA0, - #$62BD, #$916C, #$7574, #$8E0C, #$7A20, #$6101, #$7B79, #$4EC7, - #$7EF8, #$7785, #$4E11, #$81ED, #$521D, #$51FA, #$6A71, #$53A8, - #$8E87, #$9504, #$96CF, #$6EC1, #$9664, #$695A, - #$7840, #$50A8, #$77D7, #$6410, #$89E6, #$5904, #$63E3, #$5DDD, - #$7A7F, #$693D, #$4F20, #$8239, #$5598, #$4E32, #$75AE, #$7A97, - #$5E62, #$5E8A, #$95EF, #$521B, #$5439, #$708A, #$6376, #$9524, - #$5782, #$6625, #$693F, #$9187, #$5507, #$6DF3, #$7EAF, #$8822, - #$6233, #$7EF0, #$75B5, #$8328, #$78C1, #$96CC, #$8F9E, #$6148, - #$74F7, #$8BCD, #$6B64, #$523A, #$8D50, #$6B21, #$806A, #$8471, - #$56F1, #$5306, #$4ECE, #$4E1B, #$51D1, #$7C97, #$918B, #$7C07, - #$4FC3, #$8E7F, #$7BE1, #$7A9C, #$6467, #$5D14, #$50AC, #$8106, - #$7601, #$7CB9, #$6DEC, #$7FE0, #$6751, #$5B58, #$5BF8, #$78CB, - #$64AE, #$6413, #$63AA, #$632B, #$9519, #$642D, #$8FBE, #$7B54, - #$7629, #$6253, #$5927, #$5446, #$6B79, #$50A3, #$6234, #$5E26, - #$6B86, #$4EE3, #$8D37, #$888B, #$5F85, #$902E, - #$6020, #$803D, #$62C5, #$4E39, #$5355, #$90F8, #$63B8, #$80C6, - #$65E6, #$6C2E, #$4F46, #$60EE, #$6DE1, #$8BDE, #$5F39, #$86CB, - #$5F53, #$6321, #$515A, #$8361, #$6863, #$5200, #$6363, #$8E48, - #$5012, #$5C9B, #$7977, #$5BFC, #$5230, #$7A3B, #$60BC, #$9053, - #$76D7, #$5FB7, #$5F97, #$7684, #$8E6C, #$706F, #$767B, #$7B49, - #$77AA, #$51F3, #$9093, #$5824, #$4F4E, #$6EF4, #$8FEA, #$654C, - #$7B1B, #$72C4, #$6DA4, #$7FDF, #$5AE1, #$62B5, #$5E95, #$5730, - #$8482, #$7B2C, #$5E1D, #$5F1F, #$9012, #$7F14, #$98A0, #$6382, - #$6EC7, #$7898, #$70B9, #$5178, #$975B, #$57AB, #$7535, #$4F43, - #$7538, #$5E97, #$60E6, #$5960, #$6DC0, #$6BBF, #$7889, #$53FC, - #$96D5, #$51CB, #$5201, #$6389, #$540A, #$9493, #$8C03, #$8DCC, - #$7239, #$789F, #$8776, #$8FED, #$8C0D, #$53E0, - #$4E01, #$76EF, #$53EE, #$9489, #$9876, #$9F0E, #$952D, #$5B9A, - #$8BA2, #$4E22, #$4E1C, #$51AC, #$8463, #$61C2, #$52A8, #$680B, - #$4F97, #$606B, #$51BB, #$6D1E, #$515C, #$6296, #$6597, #$9661, - #$8C46, #$9017, #$75D8, #$90FD, #$7763, #$6BD2, #$728A, #$72EC, - #$8BFB, #$5835, #$7779, #$8D4C, #$675C, #$9540, #$809A, #$5EA6, - #$6E21, #$5992, #$7AEF, #$77ED, #$953B, #$6BB5, #$65AD, #$7F0E, - #$5806, #$5151, #$961F, #$5BF9, #$58A9, #$5428, #$8E72, #$6566, - #$987F, #$56E4, #$949D, #$76FE, #$9041, #$6387, #$54C6, #$591A, - #$593A, #$579B, #$8EB2, #$6735, #$8DFA, #$8235, #$5241, #$60F0, - #$5815, #$86FE, #$5CE8, #$9E45, #$4FC4, #$989D, #$8BB9, #$5A25, - #$6076, #$5384, #$627C, #$904F, #$9102, #$997F, #$6069, #$800C, - #$513F, #$8033, #$5C14, #$9975, #$6D31, #$4E8C, - #$8D30, #$53D1, #$7F5A, #$7B4F, #$4F10, #$4E4F, #$9600, #$6CD5, - #$73D0, #$85E9, #$5E06, #$756A, #$7FFB, #$6A0A, #$77FE, #$9492, - #$7E41, #$51E1, #$70E6, #$53CD, #$8FD4, #$8303, #$8D29, #$72AF, - #$996D, #$6CDB, #$574A, #$82B3, #$65B9, #$80AA, #$623F, #$9632, - #$59A8, #$4EFF, #$8BBF, #$7EBA, #$653E, #$83F2, #$975E, #$5561, - #$98DE, #$80A5, #$532A, #$8BFD, #$5420, #$80BA, #$5E9F, #$6CB8, - #$8D39, #$82AC, #$915A, #$5429, #$6C1B, #$5206, #$7EB7, #$575F, - #$711A, #$6C7E, #$7C89, #$594B, #$4EFD, #$5FFF, #$6124, #$7CAA, - #$4E30, #$5C01, #$67AB, #$8702, #$5CF0, #$950B, #$98CE, #$75AF, - #$70FD, #$9022, #$51AF, #$7F1D, #$8BBD, #$5949, #$51E4, #$4F5B, - #$5426, #$592B, #$6577, #$80A4, #$5B75, #$6276, #$62C2, #$8F90, - #$5E45, #$6C1F, #$7B26, #$4F0F, #$4FD8, #$670D, - #$6D6E, #$6DAA, #$798F, #$88B1, #$5F17, #$752B, #$629A, #$8F85, - #$4FEF, #$91DC, #$65A7, #$812F, #$8151, #$5E9C, #$8150, #$8D74, - #$526F, #$8986, #$8D4B, #$590D, #$5085, #$4ED8, #$961C, #$7236, - #$8179, #$8D1F, #$5BCC, #$8BA3, #$9644, #$5987, #$7F1A, #$5490, - #$5676, #$560E, #$8BE5, #$6539, #$6982, #$9499, #$76D6, #$6E89, - #$5E72, #$7518, #$6746, #$67D1, #$7AFF, #$809D, #$8D76, #$611F, - #$79C6, #$6562, #$8D63, #$5188, #$521A, #$94A2, #$7F38, #$809B, - #$7EB2, #$5C97, #$6E2F, #$6760, #$7BD9, #$768B, #$9AD8, #$818F, - #$7F94, #$7CD5, #$641E, #$9550, #$7A3F, #$544A, #$54E5, #$6B4C, - #$6401, #$6208, #$9E3D, #$80F3, #$7599, #$5272, #$9769, #$845B, - #$683C, #$86E4, #$9601, #$9694, #$94EC, #$4E2A, #$5404, #$7ED9, - #$6839, #$8DDF, #$8015, #$66F4, #$5E9A, #$7FB9, - #$57C2, #$803F, #$6897, #$5DE5, #$653B, #$529F, #$606D, #$9F9A, - #$4F9B, #$8EAC, #$516C, #$5BAB, #$5F13, #$5DE9, #$6C5E, #$62F1, - #$8D21, #$5171, #$94A9, #$52FE, #$6C9F, #$82DF, #$72D7, #$57A2, - #$6784, #$8D2D, #$591F, #$8F9C, #$83C7, #$5495, #$7B8D, #$4F30, - #$6CBD, #$5B64, #$59D1, #$9F13, #$53E4, #$86CA, #$9AA8, #$8C37, - #$80A1, #$6545, #$987E, #$56FA, #$96C7, #$522E, #$74DC, #$5250, - #$5BE1, #$6302, #$8902, #$4E56, #$62D0, #$602A, #$68FA, #$5173, - #$5B98, #$51A0, #$89C2, #$7BA1, #$9986, #$7F50, #$60EF, #$704C, - #$8D2F, #$5149, #$5E7F, #$901B, #$7470, #$89C4, #$572D, #$7845, - #$5F52, #$9F9F, #$95FA, #$8F68, #$9B3C, #$8BE1, #$7678, #$6842, - #$67DC, #$8DEA, #$8D35, #$523D, #$8F8A, #$6EDA, #$68CD, #$9505, - #$90ED, #$56FD, #$679C, #$88F9, #$8FC7, #$54C8, - #$9AB8, #$5B69, #$6D77, #$6C26, #$4EA5, #$5BB3, #$9A87, #$9163, - #$61A8, #$90AF, #$97E9, #$542B, #$6DB5, #$5BD2, #$51FD, #$558A, - #$7F55, #$7FF0, #$64BC, #$634D, #$65F1, #$61BE, #$608D, #$710A, - #$6C57, #$6C49, #$592F, #$676D, #$822A, #$58D5, #$568E, #$8C6A, - #$6BEB, #$90DD, #$597D, #$8017, #$53F7, #$6D69, #$5475, #$559D, - #$8377, #$83CF, #$6838, #$79BE, #$548C, #$4F55, #$5408, #$76D2, - #$8C89, #$9602, #$6CB3, #$6DB8, #$8D6B, #$8910, #$9E64, #$8D3A, - #$563F, #$9ED1, #$75D5, #$5F88, #$72E0, #$6068, #$54FC, #$4EA8, - #$6A2A, #$8861, #$6052, #$8F70, #$54C4, #$70D8, #$8679, #$9E3F, - #$6D2A, #$5B8F, #$5F18, #$7EA2, #$5589, #$4FAF, #$7334, #$543C, - #$539A, #$5019, #$540E, #$547C, #$4E4E, #$5FFD, #$745A, #$58F6, - #$846B, #$80E1, #$8774, #$72D0, #$7CCA, #$6E56, - #$5F27, #$864E, #$552C, #$62A4, #$4E92, #$6CAA, #$6237, #$82B1, - #$54D7, #$534E, #$733E, #$6ED1, #$753B, #$5212, #$5316, #$8BDD, - #$69D0, #$5F8A, #$6000, #$6DEE, #$574F, #$6B22, #$73AF, #$6853, - #$8FD8, #$7F13, #$6362, #$60A3, #$5524, #$75EA, #$8C62, #$7115, - #$6DA3, #$5BA6, #$5E7B, #$8352, #$614C, #$9EC4, #$78FA, #$8757, - #$7C27, #$7687, #$51F0, #$60F6, #$714C, #$6643, #$5E4C, #$604D, - #$8C0E, #$7070, #$6325, #$8F89, #$5FBD, #$6062, #$86D4, #$56DE, - #$6BC1, #$6094, #$6167, #$5349, #$60E0, #$6666, #$8D3F, #$79FD, - #$4F1A, #$70E9, #$6C47, #$8BB3, #$8BF2, #$7ED8, #$8364, #$660F, - #$5A5A, #$9B42, #$6D51, #$6DF7, #$8C41, #$6D3B, #$4F19, #$706B, - #$83B7, #$6216, #$60D1, #$970D, #$8D27, #$7978, #$51FB, #$573E, - #$57FA, #$673A, #$7578, #$7A3D, #$79EF, #$7B95, - #$808C, #$9965, #$8FF9, #$6FC0, #$8BA5, #$9E21, #$59EC, #$7EE9, - #$7F09, #$5409, #$6781, #$68D8, #$8F91, #$7C4D, #$96C6, #$53CA, - #$6025, #$75BE, #$6C72, #$5373, #$5AC9, #$7EA7, #$6324, #$51E0, - #$810A, #$5DF1, #$84DF, #$6280, #$5180, #$5B63, #$4F0E, #$796D, - #$5242, #$60B8, #$6D4E, #$5BC4, #$5BC2, #$8BA1, #$8BB0, #$65E2, - #$5FCC, #$9645, #$5993, #$7EE7, #$7EAA, #$5609, #$67B7, #$5939, - #$4F73, #$5BB6, #$52A0, #$835A, #$988A, #$8D3E, #$7532, #$94BE, - #$5047, #$7A3C, #$4EF7, #$67B6, #$9A7E, #$5AC1, #$6B7C, #$76D1, - #$575A, #$5C16, #$7B3A, #$95F4, #$714E, #$517C, #$80A9, #$8270, - #$5978, #$7F04, #$8327, #$68C0, #$67EC, #$78B1, #$7877, #$62E3, - #$6361, #$7B80, #$4FED, #$526A, #$51CF, #$8350, #$69DB, #$9274, - #$8DF5, #$8D31, #$89C1, #$952E, #$7BAD, #$4EF6, - #$5065, #$8230, #$5251, #$996F, #$6E10, #$6E85, #$6DA7, #$5EFA, - #$50F5, #$59DC, #$5C06, #$6D46, #$6C5F, #$7586, #$848B, #$6868, - #$5956, #$8BB2, #$5320, #$9171, #$964D, #$8549, #$6912, #$7901, - #$7126, #$80F6, #$4EA4, #$90CA, #$6D47, #$9A84, #$5A07, #$56BC, - #$6405, #$94F0, #$77EB, #$4FA5, #$811A, #$72E1, #$89D2, #$997A, - #$7F34, #$7EDE, #$527F, #$6559, #$9175, #$8F7F, #$8F83, #$53EB, - #$7A96, #$63ED, #$63A5, #$7686, #$79F8, #$8857, #$9636, #$622A, - #$52AB, #$8282, #$6854, #$6770, #$6377, #$776B, #$7AED, #$6D01, - #$7ED3, #$89E3, #$59D0, #$6212, #$85C9, #$82A5, #$754C, #$501F, - #$4ECB, #$75A5, #$8BEB, #$5C4A, #$5DFE, #$7B4B, #$65A4, #$91D1, - #$4ECA, #$6D25, #$895F, #$7D27, #$9526, #$4EC5, #$8C28, #$8FDB, - #$9773, #$664B, #$7981, #$8FD1, #$70EC, #$6D78, - #$5C3D, #$52B2, #$8346, #$5162, #$830E, #$775B, #$6676, #$9CB8, - #$4EAC, #$60CA, #$7CBE, #$7CB3, #$7ECF, #$4E95, #$8B66, #$666F, - #$9888, #$9759, #$5883, #$656C, #$955C, #$5F84, #$75C9, #$9756, - #$7ADF, #$7ADE, #$51C0, #$70AF, #$7A98, #$63EA, #$7A76, #$7EA0, - #$7396, #$97ED, #$4E45, #$7078, #$4E5D, #$9152, #$53A9, #$6551, - #$65E7, #$81FC, #$8205, #$548E, #$5C31, #$759A, #$97A0, #$62D8, - #$72D9, #$75BD, #$5C45, #$9A79, #$83CA, #$5C40, #$5480, #$77E9, - #$4E3E, #$6CAE, #$805A, #$62D2, #$636E, #$5DE8, #$5177, #$8DDD, - #$8E1E, #$952F, #$4FF1, #$53E5, #$60E7, #$70AC, #$5267, #$6350, - #$9E43, #$5A1F, #$5026, #$7737, #$5377, #$7EE2, #$6485, #$652B, - #$6289, #$6398, #$5014, #$7235, #$89C9, #$51B3, #$8BC0, #$7EDD, - #$5747, #$83CC, #$94A7, #$519B, #$541B, #$5CFB, - #$4FCA, #$7AE3, #$6D5A, #$90E1, #$9A8F, #$5580, #$5496, #$5361, - #$54AF, #$5F00, #$63E9, #$6977, #$51EF, #$6168, #$520A, #$582A, - #$52D8, #$574E, #$780D, #$770B, #$5EB7, #$6177, #$7CE0, #$625B, - #$6297, #$4EA2, #$7095, #$8003, #$62F7, #$70E4, #$9760, #$5777, - #$82DB, #$67EF, #$68F5, #$78D5, #$9897, #$79D1, #$58F3, #$54B3, - #$53EF, #$6E34, #$514B, #$523B, #$5BA2, #$8BFE, #$80AF, #$5543, - #$57A6, #$6073, #$5751, #$542D, #$7A7A, #$6050, #$5B54, #$63A7, - #$62A0, #$53E3, #$6263, #$5BC7, #$67AF, #$54ED, #$7A9F, #$82E6, - #$9177, #$5E93, #$88E4, #$5938, #$57AE, #$630E, #$8DE8, #$80EF, - #$5757, #$7B77, #$4FA9, #$5FEB, #$5BBD, #$6B3E, #$5321, #$7B50, - #$72C2, #$6846, #$77FF, #$7736, #$65F7, #$51B5, #$4E8F, #$76D4, - #$5CBF, #$7AA5, #$8475, #$594E, #$9B41, #$5080, - #$9988, #$6127, #$6E83, #$5764, #$6606, #$6346, #$56F0, #$62EC, - #$6269, #$5ED3, #$9614, #$5783, #$62C9, #$5587, #$8721, #$814A, - #$8FA3, #$5566, #$83B1, #$6765, #$8D56, #$84DD, #$5A6A, #$680F, - #$62E6, #$7BEE, #$9611, #$5170, #$6F9C, #$8C30, #$63FD, #$89C8, - #$61D2, #$7F06, #$70C2, #$6EE5, #$7405, #$6994, #$72FC, #$5ECA, - #$90CE, #$6717, #$6D6A, #$635E, #$52B3, #$7262, #$8001, #$4F6C, - #$59E5, #$916A, #$70D9, #$6D9D, #$52D2, #$4E50, #$96F7, #$956D, - #$857E, #$78CA, #$7D2F, #$5121, #$5792, #$64C2, #$808B, #$7C7B, - #$6CEA, #$68F1, #$695E, #$51B7, #$5398, #$68A8, #$7281, #$9ECE, - #$7BF1, #$72F8, #$79BB, #$6F13, #$7406, #$674E, #$91CC, #$9CA4, - #$793C, #$8389, #$8354, #$540F, #$6817, #$4E3D, #$5389, #$52B1, - #$783E, #$5386, #$5229, #$5088, #$4F8B, #$4FD0, - #$75E2, #$7ACB, #$7C92, #$6CA5, #$96B6, #$529B, #$7483, #$54E9, - #$4FE9, #$8054, #$83B2, #$8FDE, #$9570, #$5EC9, #$601C, #$6D9F, - #$5E18, #$655B, #$8138, #$94FE, #$604B, #$70BC, #$7EC3, #$7CAE, - #$51C9, #$6881, #$7CB1, #$826F, #$4E24, #$8F86, #$91CF, #$667E, - #$4EAE, #$8C05, #$64A9, #$804A, #$50DA, #$7597, #$71CE, #$5BE5, - #$8FBD, #$6F66, #$4E86, #$6482, #$9563, #$5ED6, #$6599, #$5217, - #$88C2, #$70C8, #$52A3, #$730E, #$7433, #$6797, #$78F7, #$9716, - #$4E34, #$90BB, #$9CDE, #$6DCB, #$51DB, #$8D41, #$541D, #$62CE, - #$73B2, #$83F1, #$96F6, #$9F84, #$94C3, #$4F36, #$7F9A, #$51CC, - #$7075, #$9675, #$5CAD, #$9886, #$53E6, #$4EE4, #$6E9C, #$7409, - #$69B4, #$786B, #$998F, #$7559, #$5218, #$7624, #$6D41, #$67F3, - #$516D, #$9F99, #$804B, #$5499, #$7B3C, #$7ABF, - #$9686, #$5784, #$62E2, #$9647, #$697C, #$5A04, #$6402, #$7BD3, - #$6F0F, #$964B, #$82A6, #$5362, #$9885, #$5E90, #$7089, #$63B3, - #$5364, #$864F, #$9C81, #$9E93, #$788C, #$9732, #$8DEF, #$8D42, - #$9E7F, #$6F5E, #$7984, #$5F55, #$9646, #$622E, #$9A74, #$5415, - #$94DD, #$4FA3, #$65C5, #$5C65, #$5C61, #$7F15, #$8651, #$6C2F, - #$5F8B, #$7387, #$6EE4, #$7EFF, #$5CE6, #$631B, #$5B6A, #$6EE6, - #$5375, #$4E71, #$63A0, #$7565, #$62A1, #$8F6E, #$4F26, #$4ED1, - #$6CA6, #$7EB6, #$8BBA, #$841D, #$87BA, #$7F57, #$903B, #$9523, - #$7BA9, #$9AA1, #$88F8, #$843D, #$6D1B, #$9A86, #$7EDC, #$5988, - #$9EBB, #$739B, #$7801, #$8682, #$9A6C, #$9A82, #$561B, #$5417, - #$57CB, #$4E70, #$9EA6, #$5356, #$8FC8, #$8109, #$7792, #$9992, - #$86EE, #$6EE1, #$8513, #$66FC, #$6162, #$6F2B, - #$8C29, #$8292, #$832B, #$76F2, #$6C13, #$5FD9, #$83BD, #$732B, - #$8305, #$951A, #$6BDB, #$77DB, #$94C6, #$536F, #$8302, #$5192, - #$5E3D, #$8C8C, #$8D38, #$4E48, #$73AB, #$679A, #$6885, #$9176, - #$9709, #$7164, #$6CA1, #$7709, #$5A92, #$9541, #$6BCF, #$7F8E, - #$6627, #$5BD0, #$59B9, #$5A9A, #$95E8, #$95F7, #$4EEC, #$840C, - #$8499, #$6AAC, #$76DF, #$9530, #$731B, #$68A6, #$5B5F, #$772F, - #$919A, #$9761, #$7CDC, #$8FF7, #$8C1C, #$5F25, #$7C73, #$79D8, - #$89C5, #$6CCC, #$871C, #$5BC6, #$5E42, #$68C9, #$7720, #$7EF5, - #$5195, #$514D, #$52C9, #$5A29, #$7F05, #$9762, #$82D7, #$63CF, - #$7784, #$85D0, #$79D2, #$6E3A, #$5E99, #$5999, #$8511, #$706D, - #$6C11, #$62BF, #$76BF, #$654F, #$60AF, #$95FD, #$660E, #$879F, - #$9E23, #$94ED, #$540D, #$547D, #$8C2C, #$6478, - #$6479, #$8611, #$6A21, #$819C, #$78E8, #$6469, #$9B54, #$62B9, - #$672B, #$83AB, #$58A8, #$9ED8, #$6CAB, #$6F20, #$5BDE, #$964C, - #$8C0B, #$725F, #$67D0, #$62C7, #$7261, #$4EA9, #$59C6, #$6BCD, - #$5893, #$66AE, #$5E55, #$52DF, #$6155, #$6728, #$76EE, #$7766, - #$7267, #$7A46, #$62FF, #$54EA, #$5450, #$94A0, #$90A3, #$5A1C, - #$7EB3, #$6C16, #$4E43, #$5976, #$8010, #$5948, #$5357, #$7537, - #$96BE, #$56CA, #$6320, #$8111, #$607C, #$95F9, #$6DD6, #$5462, - #$9981, #$5185, #$5AE9, #$80FD, #$59AE, #$9713, #$502A, #$6CE5, - #$5C3C, #$62DF, #$4F60, #$533F, #$817B, #$9006, #$6EBA, #$852B, - #$62C8, #$5E74, #$78BE, #$64B5, #$637B, #$5FF5, #$5A18, #$917F, - #$9E1F, #$5C3F, #$634F, #$8042, #$5B7D, #$556E, #$954A, #$954D, - #$6D85, #$60A8, #$67E0, #$72DE, #$51DD, #$5B81, - #$62E7, #$6CDE, #$725B, #$626D, #$94AE, #$7EBD, #$8113, #$6D53, - #$519C, #$5F04, #$5974, #$52AA, #$6012, #$5973, #$6696, #$8650, - #$759F, #$632A, #$61E6, #$7CEF, #$8BFA, #$54E6, #$6B27, #$9E25, - #$6BB4, #$85D5, #$5455, #$5076, #$6CA4, #$556A, #$8DB4, #$722C, - #$5E15, #$6015, #$7436, #$62CD, #$6392, #$724C, #$5F98, #$6E43, - #$6D3E, #$6500, #$6F58, #$76D8, #$78D0, #$76FC, #$7554, #$5224, - #$53DB, #$4E53, #$5E9E, #$65C1, #$802A, #$80D6, #$629B, #$5486, - #$5228, #$70AE, #$888D, #$8DD1, #$6CE1, #$5478, #$80DA, #$57F9, - #$88F4, #$8D54, #$966A, #$914D, #$4F69, #$6C9B, #$55B7, #$76C6, - #$7830, #$62A8, #$70F9, #$6F8E, #$5F6D, #$84EC, #$68DA, #$787C, - #$7BF7, #$81A8, #$670B, #$9E4F, #$6367, #$78B0, #$576F, #$7812, - #$9739, #$6279, #$62AB, #$5288, #$7435, #$6BD7, - #$5564, #$813E, #$75B2, #$76AE, #$5339, #$75DE, #$50FB, #$5C41, - #$8B6C, #$7BC7, #$504F, #$7247, #$9A97, #$98D8, #$6F02, #$74E2, - #$7968, #$6487, #$77A5, #$62FC, #$9891, #$8D2B, #$54C1, #$8058, - #$4E52, #$576A, #$82F9, #$840D, #$5E73, #$51ED, #$74F6, #$8BC4, - #$5C4F, #$5761, #$6CFC, #$9887, #$5A46, #$7834, #$9B44, #$8FEB, - #$7C95, #$5256, #$6251, #$94FA, #$4EC6, #$8386, #$8461, #$83E9, - #$84B2, #$57D4, #$6734, #$5703, #$666E, #$6D66, #$8C31, #$66DD, - #$7011, #$671F, #$6B3A, #$6816, #$621A, #$59BB, #$4E03, #$51C4, - #$6F06, #$67D2, #$6C8F, #$5176, #$68CB, #$5947, #$6B67, #$7566, - #$5D0E, #$8110, #$9F50, #$65D7, #$7948, #$7941, #$9A91, #$8D77, - #$5C82, #$4E5E, #$4F01, #$542F, #$5951, #$780C, #$5668, #$6C14, - #$8FC4, #$5F03, #$6C7D, #$6CE3, #$8BAB, #$6390, - #$6070, #$6D3D, #$7275, #$6266, #$948E, #$94C5, #$5343, #$8FC1, - #$7B7E, #$4EDF, #$8C26, #$4E7E, #$9ED4, #$94B1, #$94B3, #$524D, - #$6F5C, #$9063, #$6D45, #$8C34, #$5811, #$5D4C, #$6B20, #$6B49, - #$67AA, #$545B, #$8154, #$7F8C, #$5899, #$8537, #$5F3A, #$62A2, - #$6A47, #$9539, #$6572, #$6084, #$6865, #$77A7, #$4E54, #$4FA8, - #$5DE7, #$9798, #$64AC, #$7FD8, #$5CED, #$4FCF, #$7A8D, #$5207, - #$8304, #$4E14, #$602F, #$7A83, #$94A6, #$4FB5, #$4EB2, #$79E6, - #$7434, #$52E4, #$82B9, #$64D2, #$79BD, #$5BDD, #$6C81, #$9752, - #$8F7B, #$6C22, #$503E, #$537F, #$6E05, #$64CE, #$6674, #$6C30, - #$60C5, #$9877, #$8BF7, #$5E86, #$743C, #$7A77, #$79CB, #$4E18, - #$90B1, #$7403, #$6C42, #$56DA, #$914B, #$6CC5, #$8D8B, #$533A, - #$86C6, #$66F2, #$8EAF, #$5C48, #$9A71, #$6E20, - #$53D6, #$5A36, #$9F8B, #$8DA3, #$53BB, #$5708, #$98A7, #$6743, - #$919B, #$6CC9, #$5168, #$75CA, #$62F3, #$72AC, #$5238, #$529D, - #$7F3A, #$7094, #$7638, #$5374, #$9E4A, #$69B7, #$786E, #$96C0, - #$88D9, #$7FA4, #$7136, #$71C3, #$5189, #$67D3, #$74E4, #$58E4, - #$6518, #$56B7, #$8BA9, #$9976, #$6270, #$7ED5, #$60F9, #$70ED, - #$58EC, #$4EC1, #$4EBA, #$5FCD, #$97E7, #$4EFB, #$8BA4, #$5203, - #$598A, #$7EAB, #$6254, #$4ECD, #$65E5, #$620E, #$8338, #$84C9, - #$8363, #$878D, #$7194, #$6EB6, #$5BB9, #$7ED2, #$5197, #$63C9, - #$67D4, #$8089, #$8339, #$8815, #$5112, #$5B7A, #$5982, #$8FB1, - #$4E73, #$6C5D, #$5165, #$8925, #$8F6F, #$962E, #$854A, #$745E, - #$9510, #$95F0, #$6DA6, #$82E5, #$5F31, #$6492, #$6D12, #$8428, - #$816E, #$9CC3, #$585E, #$8D5B, #$4E09, #$53C1, - #$4F1E, #$6563, #$6851, #$55D3, #$4E27, #$6414, #$9A9A, #$626B, - #$5AC2, #$745F, #$8272, #$6DA9, #$68EE, #$50E7, #$838E, #$7802, - #$6740, #$5239, #$6C99, #$7EB1, #$50BB, #$5565, #$715E, #$7B5B, - #$6652, #$73CA, #$82EB, #$6749, #$5C71, #$5220, #$717D, #$886B, - #$95EA, #$9655, #$64C5, #$8D61, #$81B3, #$5584, #$6C55, #$6247, - #$7F2E, #$5892, #$4F24, #$5546, #$8D4F, #$664C, #$4E0A, #$5C1A, - #$88F3, #$68A2, #$634E, #$7A0D, #$70E7, #$828D, #$52FA, #$97F6, - #$5C11, #$54E8, #$90B5, #$7ECD, #$5962, #$8D4A, #$86C7, #$820C, - #$820D, #$8D66, #$6444, #$5C04, #$6151, #$6D89, #$793E, #$8BBE, - #$7837, #$7533, #$547B, #$4F38, #$8EAB, #$6DF1, #$5A20, #$7EC5, - #$795E, #$6C88, #$5BA1, #$5A76, #$751A, #$80BE, #$614E, #$6E17, - #$58F0, #$751F, #$7525, #$7272, #$5347, #$7EF3, - #$7701, #$76DB, #$5269, #$80DC, #$5723, #$5E08, #$5931, #$72EE, - #$65BD, #$6E7F, #$8BD7, #$5C38, #$8671, #$5341, #$77F3, #$62FE, - #$65F6, #$4EC0, #$98DF, #$8680, #$5B9E, #$8BC6, #$53F2, #$77E2, - #$4F7F, #$5C4E, #$9A76, #$59CB, #$5F0F, #$793A, #$58EB, #$4E16, - #$67FF, #$4E8B, #$62ED, #$8A93, #$901D, #$52BF, #$662F, #$55DC, - #$566C, #$9002, #$4ED5, #$4F8D, #$91CA, #$9970, #$6C0F, #$5E02, - #$6043, #$5BA4, #$89C6, #$8BD5, #$6536, #$624B, #$9996, #$5B88, - #$5BFF, #$6388, #$552E, #$53D7, #$7626, #$517D, #$852C, #$67A2, - #$68B3, #$6B8A, #$6292, #$8F93, #$53D4, #$8212, #$6DD1, #$758F, - #$4E66, #$8D4E, #$5B70, #$719F, #$85AF, #$6691, #$66D9, #$7F72, - #$8700, #$9ECD, #$9F20, #$5C5E, #$672F, #$8FF0, #$6811, #$675F, - #$620D, #$7AD6, #$5885, #$5EB6, #$6570, #$6F31, - #$6055, #$5237, #$800D, #$6454, #$8870, #$7529, #$5E05, #$6813, - #$62F4, #$971C, #$53CC, #$723D, #$8C01, #$6C34, #$7761, #$7A0E, - #$542E, #$77AC, #$987A, #$821C, #$8BF4, #$7855, #$6714, #$70C1, - #$65AF, #$6495, #$5636, #$601D, #$79C1, #$53F8, #$4E1D, #$6B7B, - #$8086, #$5BFA, #$55E3, #$56DB, #$4F3A, #$4F3C, #$9972, #$5DF3, - #$677E, #$8038, #$6002, #$9882, #$9001, #$5B8B, #$8BBC, #$8BF5, - #$641C, #$8258, #$64DE, #$55FD, #$82CF, #$9165, #$4FD7, #$7D20, - #$901F, #$7C9F, #$50F3, #$5851, #$6EAF, #$5BBF, #$8BC9, #$8083, - #$9178, #$849C, #$7B97, #$867D, #$968B, #$968F, #$7EE5, #$9AD3, - #$788E, #$5C81, #$7A57, #$9042, #$96A7, #$795F, #$5B59, #$635F, - #$7B0B, #$84D1, #$68AD, #$5506, #$7F29, #$7410, #$7D22, #$9501, - #$6240, #$584C, #$4ED6, #$5B83, #$5979, #$5854, - #$736D, #$631E, #$8E4B, #$8E0F, #$80CE, #$82D4, #$62AC, #$53F0, - #$6CF0, #$915E, #$592A, #$6001, #$6C70, #$574D, #$644A, #$8D2A, - #$762B, #$6EE9, #$575B, #$6A80, #$75F0, #$6F6D, #$8C2D, #$8C08, - #$5766, #$6BEF, #$8892, #$78B3, #$63A2, #$53F9, #$70AD, #$6C64, - #$5858, #$642A, #$5802, #$68E0, #$819B, #$5510, #$7CD6, #$5018, - #$8EBA, #$6DCC, #$8D9F, #$70EB, #$638F, #$6D9B, #$6ED4, #$7EE6, - #$8404, #$6843, #$9003, #$6DD8, #$9676, #$8BA8, #$5957, #$7279, - #$85E4, #$817E, #$75BC, #$8A8A, #$68AF, #$5254, #$8E22, #$9511, - #$63D0, #$9898, #$8E44, #$557C, #$4F53, #$66FF, #$568F, #$60D5, - #$6D95, #$5243, #$5C49, #$5929, #$6DFB, #$586B, #$7530, #$751C, - #$606C, #$8214, #$8146, #$6311, #$6761, #$8FE2, #$773A, #$8DF3, - #$8D34, #$94C1, #$5E16, #$5385, #$542C, #$70C3, - #$6C40, #$5EF7, #$505C, #$4EAD, #$5EAD, #$633A, #$8247, #$901A, - #$6850, #$916E, #$77B3, #$540C, #$94DC, #$5F64, #$7AE5, #$6876, - #$6345, #$7B52, #$7EDF, #$75DB, #$5077, #$6295, #$5934, #$900F, - #$51F8, #$79C3, #$7A81, #$56FE, #$5F92, #$9014, #$6D82, #$5C60, - #$571F, #$5410, #$5154, #$6E4D, #$56E2, #$63A8, #$9893, #$817F, - #$8715, #$892A, #$9000, #$541E, #$5C6F, #$81C0, #$62D6, #$6258, - #$8131, #$9E35, #$9640, #$9A6E, #$9A7C, #$692D, #$59A5, #$62D3, - #$553E, #$6316, #$54C7, #$86D9, #$6D3C, #$5A03, #$74E6, #$889C, - #$6B6A, #$5916, #$8C4C, #$5F2F, #$6E7E, #$73A9, #$987D, #$4E38, - #$70F7, #$5B8C, #$7897, #$633D, #$665A, #$7696, #$60CB, #$5B9B, - #$5A49, #$4E07, #$8155, #$6C6A, #$738B, #$4EA1, #$6789, #$7F51, - #$5F80, #$65FA, #$671B, #$5FD8, #$5984, #$5A01, - #$5DCD, #$5FAE, #$5371, #$97E6, #$8FDD, #$6845, #$56F4, #$552F, - #$60DF, #$4E3A, #$6F4D, #$7EF4, #$82C7, #$840E, #$59D4, #$4F1F, - #$4F2A, #$5C3E, #$7EAC, #$672A, #$851A, #$5473, #$754F, #$80C3, - #$5582, #$9B4F, #$4F4D, #$6E2D, #$8C13, #$5C09, #$6170, #$536B, - #$761F, #$6E29, #$868A, #$6587, #$95FB, #$7EB9, #$543B, #$7A33, - #$7D0A, #$95EE, #$55E1, #$7FC1, #$74EE, #$631D, #$8717, #$6DA1, - #$7A9D, #$6211, #$65A1, #$5367, #$63E1, #$6C83, #$5DEB, #$545C, - #$94A8, #$4E4C, #$6C61, #$8BEC, #$5C4B, #$65E0, #$829C, #$68A7, - #$543E, #$5434, #$6BCB, #$6B66, #$4E94, #$6342, #$5348, #$821E, - #$4F0D, #$4FAE, #$575E, #$620A, #$96FE, #$6664, #$7269, #$52FF, - #$52A1, #$609F, #$8BEF, #$6614, #$7199, #$6790, #$897F, #$7852, - #$77FD, #$6670, #$563B, #$5438, #$9521, #$727A, - #$7A00, #$606F, #$5E0C, #$6089, #$819D, #$5915, #$60DC, #$7184, - #$70EF, #$6EAA, #$6C50, #$7280, #$6A84, #$88AD, #$5E2D, #$4E60, - #$5AB3, #$559C, #$94E3, #$6D17, #$7CFB, #$9699, #$620F, #$7EC6, - #$778E, #$867E, #$5323, #$971E, #$8F96, #$6687, #$5CE1, #$4FA0, - #$72ED, #$4E0B, #$53A6, #$590F, #$5413, #$6380, #$9528, #$5148, - #$4ED9, #$9C9C, #$7EA4, #$54B8, #$8D24, #$8854, #$8237, #$95F2, - #$6D8E, #$5F26, #$5ACC, #$663E, #$9669, #$73B0, #$732E, #$53BF, - #$817A, #$9985, #$7FA1, #$5BAA, #$9677, #$9650, #$7EBF, #$76F8, - #$53A2, #$9576, #$9999, #$7BB1, #$8944, #$6E58, #$4E61, #$7FD4, - #$7965, #$8BE6, #$60F3, #$54CD, #$4EAB, #$9879, #$5DF7, #$6A61, - #$50CF, #$5411, #$8C61, #$8427, #$785D, #$9704, #$524A, #$54EE, - #$56A3, #$9500, #$6D88, #$5BB5, #$6DC6, #$6653, - #$5C0F, #$5B5D, #$6821, #$8096, #$5578, #$7B11, #$6548, #$6954, - #$4E9B, #$6B47, #$874E, #$978B, #$534F, #$631F, #$643A, #$90AA, - #$659C, #$80C1, #$8C10, #$5199, #$68B0, #$5378, #$87F9, #$61C8, - #$6CC4, #$6CFB, #$8C22, #$5C51, #$85AA, #$82AF, #$950C, #$6B23, - #$8F9B, #$65B0, #$5FFB, #$5FC3, #$4FE1, #$8845, #$661F, #$8165, - #$7329, #$60FA, #$5174, #$5211, #$578B, #$5F62, #$90A2, #$884C, - #$9192, #$5E78, #$674F, #$6027, #$59D3, #$5144, #$51F6, #$80F8, - #$5308, #$6C79, #$96C4, #$718A, #$4F11, #$4FEE, #$7F9E, #$673D, - #$55C5, #$9508, #$79C0, #$8896, #$7EE3, #$589F, #$620C, #$9700, - #$865A, #$5618, #$987B, #$5F90, #$8BB8, #$84C4, #$9157, #$53D9, - #$65ED, #$5E8F, #$755C, #$6064, #$7D6E, #$5A7F, #$7EEA, #$7EED, - #$8F69, #$55A7, #$5BA3, #$60AC, #$65CB, #$7384, - #$9009, #$7663, #$7729, #$7EDA, #$9774, #$859B, #$5B66, #$7A74, - #$96EA, #$8840, #$52CB, #$718F, #$5FAA, #$65EC, #$8BE2, #$5BFB, - #$9A6F, #$5DE1, #$6B89, #$6C5B, #$8BAD, #$8BAF, #$900A, #$8FC5, - #$538B, #$62BC, #$9E26, #$9E2D, #$5440, #$4E2B, #$82BD, #$7259, - #$869C, #$5D16, #$8859, #$6DAF, #$96C5, #$54D1, #$4E9A, #$8BB6, - #$7109, #$54BD, #$9609, #$70DF, #$6DF9, #$76D0, #$4E25, #$7814, - #$8712, #$5CA9, #$5EF6, #$8A00, #$989C, #$960E, #$708E, #$6CBF, - #$5944, #$63A9, #$773C, #$884D, #$6F14, #$8273, #$5830, #$71D5, - #$538C, #$781A, #$96C1, #$5501, #$5F66, #$7130, #$5BB4, #$8C1A, - #$9A8C, #$6B83, #$592E, #$9E2F, #$79E7, #$6768, #$626C, #$4F6F, - #$75A1, #$7F8A, #$6D0B, #$9633, #$6C27, #$4EF0, #$75D2, #$517B, - #$6837, #$6F3E, #$9080, #$8170, #$5996, #$7476, - #$6447, #$5C27, #$9065, #$7A91, #$8C23, #$59DA, #$54AC, #$8200, - #$836F, #$8981, #$8000, #$6930, #$564E, #$8036, #$7237, #$91CE, - #$51B6, #$4E5F, #$9875, #$6396, #$4E1A, #$53F6, #$66F3, #$814B, - #$591C, #$6DB2, #$4E00, #$58F9, #$533B, #$63D6, #$94F1, #$4F9D, - #$4F0A, #$8863, #$9890, #$5937, #$9057, #$79FB, #$4EEA, #$80F0, - #$7591, #$6C82, #$5B9C, #$59E8, #$5F5D, #$6905, #$8681, #$501A, - #$5DF2, #$4E59, #$77E3, #$4EE5, #$827A, #$6291, #$6613, #$9091, - #$5C79, #$4EBF, #$5F79, #$81C6, #$9038, #$8084, #$75AB, #$4EA6, - #$88D4, #$610F, #$6BC5, #$5FC6, #$4E49, #$76CA, #$6EA2, #$8BE3, - #$8BAE, #$8C0A, #$8BD1, #$5F02, #$7FFC, #$7FCC, #$7ECE, #$8335, - #$836B, #$56E0, #$6BB7, #$97F3, #$9634, #$59FB, #$541F, #$94F6, - #$6DEB, #$5BC5, #$996E, #$5C39, #$5F15, #$9690, - #$5370, #$82F1, #$6A31, #$5A74, #$9E70, #$5E94, #$7F28, #$83B9, - #$8424, #$8425, #$8367, #$8747, #$8FCE, #$8D62, #$76C8, #$5F71, - #$9896, #$786C, #$6620, #$54DF, #$62E5, #$4F63, #$81C3, #$75C8, - #$5EB8, #$96CD, #$8E0A, #$86F9, #$548F, #$6CF3, #$6D8C, #$6C38, - #$607F, #$52C7, #$7528, #$5E7D, #$4F18, #$60A0, #$5FE7, #$5C24, - #$7531, #$90AE, #$94C0, #$72B9, #$6CB9, #$6E38, #$9149, #$6709, - #$53CB, #$53F3, #$4F51, #$91C9, #$8BF1, #$53C8, #$5E7C, #$8FC2, - #$6DE4, #$4E8E, #$76C2, #$6986, #$865E, #$611A, #$8206, #$4F59, - #$4FDE, #$903E, #$9C7C, #$6109, #$6E1D, #$6E14, #$9685, #$4E88, - #$5A31, #$96E8, #$4E0E, #$5C7F, #$79B9, #$5B87, #$8BED, #$7FBD, - #$7389, #$57DF, #$828B, #$90C1, #$5401, #$9047, #$55BB, #$5CEA, - #$5FA1, #$6108, #$6B32, #$72F1, #$80B2, #$8A89, - #$6D74, #$5BD3, #$88D5, #$9884, #$8C6B, #$9A6D, #$9E33, #$6E0A, - #$51A4, #$5143, #$57A3, #$8881, #$539F, #$63F4, #$8F95, #$56ED, - #$5458, #$5706, #$733F, #$6E90, #$7F18, #$8FDC, #$82D1, #$613F, - #$6028, #$9662, #$66F0, #$7EA6, #$8D8A, #$8DC3, #$94A5, #$5CB3, - #$7CA4, #$6708, #$60A6, #$9605, #$8018, #$4E91, #$90E7, #$5300, - #$9668, #$5141, #$8FD0, #$8574, #$915D, #$6655, #$97F5, #$5B55, - #$531D, #$7838, #$6742, #$683D, #$54C9, #$707E, #$5BB0, #$8F7D, - #$518D, #$5728, #$54B1, #$6512, #$6682, #$8D5E, #$8D43, #$810F, - #$846C, #$906D, #$7CDF, #$51FF, #$85FB, #$67A3, #$65E9, #$6FA1, - #$86A4, #$8E81, #$566A, #$9020, #$7682, #$7076, #$71E5, #$8D23, - #$62E9, #$5219, #$6CFD, #$8D3C, #$600E, #$589E, #$618E, #$66FE, - #$8D60, #$624E, #$55B3, #$6E23, #$672D, #$8F67, - #$94E1, #$95F8, #$7728, #$6805, #$69A8, #$548B, #$4E4D, #$70B8, - #$8BC8, #$6458, #$658B, #$5B85, #$7A84, #$503A, #$5BE8, #$77BB, - #$6BE1, #$8A79, #$7C98, #$6CBE, #$76CF, #$65A9, #$8F97, #$5D2D, - #$5C55, #$8638, #$6808, #$5360, #$6218, #$7AD9, #$6E5B, #$7EFD, - #$6A1F, #$7AE0, #$5F70, #$6F33, #$5F20, #$638C, #$6DA8, #$6756, - #$4E08, #$5E10, #$8D26, #$4ED7, #$80C0, #$7634, #$969C, #$62DB, - #$662D, #$627E, #$6CBC, #$8D75, #$7167, #$7F69, #$5146, #$8087, - #$53EC, #$906E, #$6298, #$54F2, #$86F0, #$8F99, #$8005, #$9517, - #$8517, #$8FD9, #$6D59, #$73CD, #$659F, #$771F, #$7504, #$7827, - #$81FB, #$8D1E, #$9488, #$4FA6, #$6795, #$75B9, #$8BCA, #$9707, - #$632F, #$9547, #$9635, #$84B8, #$6323, #$7741, #$5F81, #$72F0, - #$4E89, #$6014, #$6574, #$62EF, #$6B63, #$653F, - #$5E27, #$75C7, #$90D1, #$8BC1, #$829D, #$679D, #$652F, #$5431, - #$8718, #$77E5, #$80A2, #$8102, #$6C41, #$4E4B, #$7EC7, #$804C, - #$76F4, #$690D, #$6B96, #$6267, #$503C, #$4F84, #$5740, #$6307, - #$6B62, #$8DBE, #$53EA, #$65E8, #$7EB8, #$5FD7, #$631A, #$63B7, - #$81F3, #$81F4, #$7F6E, #$5E1C, #$5CD9, #$5236, #$667A, #$79E9, - #$7A1A, #$8D28, #$7099, #$75D4, #$6EDE, #$6CBB, #$7A92, #$4E2D, - #$76C5, #$5FE0, #$949F, #$8877, #$7EC8, #$79CD, #$80BF, #$91CD, - #$4EF2, #$4F17, #$821F, #$5468, #$5DDE, #$6D32, #$8BCC, #$7CA5, - #$8F74, #$8098, #$5E1A, #$5492, #$76B1, #$5B99, #$663C, #$9AA4, - #$73E0, #$682A, #$86DB, #$6731, #$732A, #$8BF8, #$8BDB, #$9010, - #$7AF9, #$70DB, #$716E, #$62C4, #$77A9, #$5631, #$4E3B, #$8457, - #$67F1, #$52A9, #$86C0, #$8D2E, #$94F8, #$7B51, - #$4F4F, #$6CE8, #$795D, #$9A7B, #$6293, #$722A, #$62FD, #$4E13, - #$7816, #$8F6C, #$64B0, #$8D5A, #$7BC6, #$6869, #$5E84, #$88C5, - #$5986, #$649E, #$58EE, #$72B6, #$690E, #$9525, #$8FFD, #$8D58, - #$5760, #$7F00, #$8C06, #$51C6, #$6349, #$62D9, #$5353, #$684C, - #$7422, #$8301, #$914C, #$5544, #$7740, #$707C, #$6D4A, #$5179, - #$54A8, #$8D44, #$59FF, #$6ECB, #$6DC4, #$5B5C, #$7D2B, #$4ED4, - #$7C7D, #$6ED3, #$5B50, #$81EA, #$6E0D, #$5B57, #$9B03, #$68D5, - #$8E2A, #$5B97, #$7EFC, #$603B, #$7EB5, #$90B9, #$8D70, #$594F, - #$63CD, #$79DF, #$8DB3, #$5352, #$65CF, #$7956, #$8BC5, #$963B, - #$7EC4, #$94BB, #$7E82, #$5634, #$9189, #$6700, #$7F6A, #$5C0A, - #$9075, #$6628, #$5DE6, #$4F50, #$67DE, #$505A, #$4F5C, #$5750, - #$5EA7, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$4E8D, #$4E0C, #$5140, #$4E10, #$5EFF, #$5345, #$4E15, #$4E98, - #$4E1E, #$9B32, #$5B6C, #$5669, #$4E28, #$79BA, #$4E3F, #$5315, - #$4E47, #$592D, #$723B, #$536E, #$6C10, #$56DF, #$80E4, #$9997, - #$6BD3, #$777E, #$9F17, #$4E36, #$4E9F, #$9F10, #$4E5C, #$4E69, - #$4E93, #$8288, #$5B5B, #$556C, #$560F, #$4EC4, #$538D, #$539D, - #$53A3, #$53A5, #$53AE, #$9765, #$8D5D, #$531A, #$53F5, #$5326, - #$532E, #$533E, #$8D5C, #$5366, #$5363, #$5202, #$5208, #$520E, - #$522D, #$5233, #$523F, #$5240, #$524C, #$525E, #$5261, #$525C, - #$84AF, #$527D, #$5282, #$5281, #$5290, #$5293, #$5182, #$7F54, - #$4EBB, #$4EC3, #$4EC9, #$4EC2, #$4EE8, #$4EE1, #$4EEB, #$4EDE, - #$4F1B, #$4EF3, #$4F22, #$4F64, #$4EF5, #$4F25, #$4F27, #$4F09, - #$4F2B, #$4F5E, #$4F67, #$6538, #$4F5A, #$4F5D, - #$4F5F, #$4F57, #$4F32, #$4F3D, #$4F76, #$4F74, #$4F91, #$4F89, - #$4F83, #$4F8F, #$4F7E, #$4F7B, #$4FAA, #$4F7C, #$4FAC, #$4F94, - #$4FE6, #$4FE8, #$4FEA, #$4FC5, #$4FDA, #$4FE3, #$4FDC, #$4FD1, - #$4FDF, #$4FF8, #$5029, #$504C, #$4FF3, #$502C, #$500F, #$502E, - #$502D, #$4FFE, #$501C, #$500C, #$5025, #$5028, #$507E, #$5043, - #$5055, #$5048, #$504E, #$506C, #$507B, #$50A5, #$50A7, #$50A9, - #$50BA, #$50D6, #$5106, #$50ED, #$50EC, #$50E6, #$50EE, #$5107, - #$510B, #$4EDD, #$6C3D, #$4F58, #$4F65, #$4FCE, #$9FA0, #$6C46, - #$7C74, #$516E, #$5DFD, #$9EC9, #$9998, #$5181, #$5914, #$52F9, - #$530D, #$8A07, #$5310, #$51EB, #$5919, #$5155, #$4EA0, #$5156, - #$4EB3, #$886E, #$88A4, #$4EB5, #$8114, #$88D2, #$7980, #$5B34, - #$8803, #$7FB8, #$51AB, #$51B1, #$51BD, #$51BC, - #$51C7, #$5196, #$51A2, #$51A5, #$8BA0, #$8BA6, #$8BA7, #$8BAA, - #$8BB4, #$8BB5, #$8BB7, #$8BC2, #$8BC3, #$8BCB, #$8BCF, #$8BCE, - #$8BD2, #$8BD3, #$8BD4, #$8BD6, #$8BD8, #$8BD9, #$8BDC, #$8BDF, - #$8BE0, #$8BE4, #$8BE8, #$8BE9, #$8BEE, #$8BF0, #$8BF3, #$8BF6, - #$8BF9, #$8BFC, #$8BFF, #$8C00, #$8C02, #$8C04, #$8C07, #$8C0C, - #$8C0F, #$8C11, #$8C12, #$8C14, #$8C15, #$8C16, #$8C19, #$8C1B, - #$8C18, #$8C1D, #$8C1F, #$8C20, #$8C21, #$8C25, #$8C27, #$8C2A, - #$8C2B, #$8C2E, #$8C2F, #$8C32, #$8C33, #$8C35, #$8C36, #$5369, - #$537A, #$961D, #$9622, #$9621, #$9631, #$962A, #$963D, #$963C, - #$9642, #$9649, #$9654, #$965F, #$9667, #$966C, #$9672, #$9674, - #$9688, #$968D, #$9697, #$96B0, #$9097, #$909B, #$909D, #$9099, - #$90AC, #$90A1, #$90B4, #$90B3, #$90B6, #$90BA, - #$90B8, #$90B0, #$90CF, #$90C5, #$90BE, #$90D0, #$90C4, #$90C7, - #$90D3, #$90E6, #$90E2, #$90DC, #$90D7, #$90DB, #$90EB, #$90EF, - #$90FE, #$9104, #$9122, #$911E, #$9123, #$9131, #$912F, #$9139, - #$9143, #$9146, #$520D, #$5942, #$52A2, #$52AC, #$52AD, #$52BE, - #$54FF, #$52D0, #$52D6, #$52F0, #$53DF, #$71EE, #$77CD, #$5EF4, - #$51F5, #$51FC, #$9B2F, #$53B6, #$5F01, #$755A, #$5DEF, #$574C, - #$57A9, #$57A1, #$587E, #$58BC, #$58C5, #$58D1, #$5729, #$572C, - #$572A, #$5733, #$5739, #$572E, #$572F, #$575C, #$573B, #$5742, - #$5769, #$5785, #$576B, #$5786, #$577C, #$577B, #$5768, #$576D, - #$5776, #$5773, #$57AD, #$57A4, #$578C, #$57B2, #$57CF, #$57A7, - #$57B4, #$5793, #$57A0, #$57D5, #$57D8, #$57DA, #$57D9, #$57D2, - #$57B8, #$57F4, #$57EF, #$57F8, #$57E4, #$57DD, - #$580B, #$580D, #$57FD, #$57ED, #$5800, #$581E, #$5819, #$5844, - #$5820, #$5865, #$586C, #$5881, #$5889, #$589A, #$5880, #$99A8, - #$9F19, #$61FF, #$8279, #$827D, #$827F, #$828F, #$828A, #$82A8, - #$8284, #$828E, #$8291, #$8297, #$8299, #$82AB, #$82B8, #$82BE, - #$82B0, #$82C8, #$82CA, #$82E3, #$8298, #$82B7, #$82AE, #$82CB, - #$82CC, #$82C1, #$82A9, #$82B4, #$82A1, #$82AA, #$829F, #$82C4, - #$82CE, #$82A4, #$82E1, #$8309, #$82F7, #$82E4, #$830F, #$8307, - #$82DC, #$82F4, #$82D2, #$82D8, #$830C, #$82FB, #$82D3, #$8311, - #$831A, #$8306, #$8314, #$8315, #$82E0, #$82D5, #$831C, #$8351, - #$835B, #$835C, #$8308, #$8392, #$833C, #$8334, #$8331, #$839B, - #$835E, #$832F, #$834F, #$8347, #$8343, #$835F, #$8340, #$8317, - #$8360, #$832D, #$833A, #$8333, #$8366, #$8365, - #$8368, #$831B, #$8369, #$836C, #$836A, #$836D, #$836E, #$83B0, - #$8378, #$83B3, #$83B4, #$83A0, #$83AA, #$8393, #$839C, #$8385, - #$837C, #$83B6, #$83A9, #$837D, #$83B8, #$837B, #$8398, #$839E, - #$83A8, #$83BA, #$83BC, #$83C1, #$8401, #$83E5, #$83D8, #$5807, - #$8418, #$840B, #$83DD, #$83FD, #$83D6, #$841C, #$8438, #$8411, - #$8406, #$83D4, #$83DF, #$840F, #$8403, #$83F8, #$83F9, #$83EA, - #$83C5, #$83C0, #$8426, #$83F0, #$83E1, #$845C, #$8451, #$845A, - #$8459, #$8473, #$8487, #$8488, #$847A, #$8489, #$8478, #$843C, - #$8446, #$8469, #$8476, #$848C, #$848E, #$8431, #$846D, #$84C1, - #$84CD, #$84D0, #$84E6, #$84BD, #$84D3, #$84CA, #$84BF, #$84BA, - #$84E0, #$84A1, #$84B9, #$84B4, #$8497, #$84E5, #$84E3, #$850C, - #$750D, #$8538, #$84F0, #$8539, #$851F, #$853A, - #$8556, #$853B, #$84FF, #$84FC, #$8559, #$8548, #$8568, #$8564, - #$855E, #$857A, #$77A2, #$8543, #$8572, #$857B, #$85A4, #$85A8, - #$8587, #$858F, #$8579, #$85AE, #$859C, #$8585, #$85B9, #$85B7, - #$85B0, #$85D3, #$85C1, #$85DC, #$85FF, #$8627, #$8605, #$8629, - #$8616, #$863C, #$5EFE, #$5F08, #$593C, #$5941, #$8037, #$5955, - #$595A, #$5958, #$530F, #$5C22, #$5C25, #$5C2C, #$5C34, #$624C, - #$626A, #$629F, #$62BB, #$62CA, #$62DA, #$62D7, #$62EE, #$6322, - #$62F6, #$6339, #$634B, #$6343, #$63AD, #$63F6, #$6371, #$637A, - #$638E, #$63B4, #$636D, #$63AC, #$638A, #$6369, #$63AE, #$63BC, - #$63F2, #$63F8, #$63E0, #$63FF, #$63C4, #$63DE, #$63CE, #$6452, - #$63C6, #$63BE, #$6445, #$6441, #$640B, #$641B, #$6420, #$640C, - #$6426, #$6421, #$645E, #$6484, #$646D, #$6496, - #$647A, #$64B7, #$64B8, #$6499, #$64BA, #$64C0, #$64D0, #$64D7, - #$64E4, #$64E2, #$6509, #$6525, #$652E, #$5F0B, #$5FD2, #$7519, - #$5F11, #$535F, #$53F1, #$53FD, #$53E9, #$53E8, #$53FB, #$5412, - #$5416, #$5406, #$544B, #$5452, #$5453, #$5454, #$5456, #$5443, - #$5421, #$5457, #$5459, #$5423, #$5432, #$5482, #$5494, #$5477, - #$5471, #$5464, #$549A, #$549B, #$5484, #$5476, #$5466, #$549D, - #$54D0, #$54AD, #$54C2, #$54B4, #$54D2, #$54A7, #$54A6, #$54D3, - #$54D4, #$5472, #$54A3, #$54D5, #$54BB, #$54BF, #$54CC, #$54D9, - #$54DA, #$54DC, #$54A9, #$54AA, #$54A4, #$54DD, #$54CF, #$54DE, - #$551B, #$54E7, #$5520, #$54FD, #$5514, #$54F3, #$5522, #$5523, - #$550F, #$5511, #$5527, #$552A, #$5567, #$558F, #$55B5, #$5549, - #$556D, #$5541, #$5555, #$553F, #$5550, #$553C, - #$5537, #$5556, #$5575, #$5576, #$5577, #$5533, #$5530, #$555C, - #$558B, #$55D2, #$5583, #$55B1, #$55B9, #$5588, #$5581, #$559F, - #$557E, #$55D6, #$5591, #$557B, #$55DF, #$55BD, #$55BE, #$5594, - #$5599, #$55EA, #$55F7, #$55C9, #$561F, #$55D1, #$55EB, #$55EC, - #$55D4, #$55E6, #$55DD, #$55C4, #$55EF, #$55E5, #$55F2, #$55F3, - #$55CC, #$55CD, #$55E8, #$55F5, #$55E4, #$8F94, #$561E, #$5608, - #$560C, #$5601, #$5624, #$5623, #$55FE, #$5600, #$5627, #$562D, - #$5658, #$5639, #$5657, #$562C, #$564D, #$5662, #$5659, #$565C, - #$564C, #$5654, #$5686, #$5664, #$5671, #$566B, #$567B, #$567C, - #$5685, #$5693, #$56AF, #$56D4, #$56D7, #$56DD, #$56E1, #$56F5, - #$56EB, #$56F9, #$56FF, #$5704, #$570A, #$5709, #$571C, #$5E0F, - #$5E19, #$5E14, #$5E11, #$5E31, #$5E3B, #$5E3C, - #$5E37, #$5E44, #$5E54, #$5E5B, #$5E5E, #$5E61, #$5C8C, #$5C7A, - #$5C8D, #$5C90, #$5C96, #$5C88, #$5C98, #$5C99, #$5C91, #$5C9A, - #$5C9C, #$5CB5, #$5CA2, #$5CBD, #$5CAC, #$5CAB, #$5CB1, #$5CA3, - #$5CC1, #$5CB7, #$5CC4, #$5CD2, #$5CE4, #$5CCB, #$5CE5, #$5D02, - #$5D03, #$5D27, #$5D26, #$5D2E, #$5D24, #$5D1E, #$5D06, #$5D1B, - #$5D58, #$5D3E, #$5D34, #$5D3D, #$5D6C, #$5D5B, #$5D6F, #$5D5D, - #$5D6B, #$5D4B, #$5D4A, #$5D69, #$5D74, #$5D82, #$5D99, #$5D9D, - #$8C73, #$5DB7, #$5DC5, #$5F73, #$5F77, #$5F82, #$5F87, #$5F89, - #$5F8C, #$5F95, #$5F99, #$5F9C, #$5FA8, #$5FAD, #$5FB5, #$5FBC, - #$8862, #$5F61, #$72AD, #$72B0, #$72B4, #$72B7, #$72B8, #$72C3, - #$72C1, #$72CE, #$72CD, #$72D2, #$72E8, #$72EF, #$72E9, #$72F2, - #$72F4, #$72F7, #$7301, #$72F3, #$7303, #$72FA, - #$72FB, #$7317, #$7313, #$7321, #$730A, #$731E, #$731D, #$7315, - #$7322, #$7339, #$7325, #$732C, #$7338, #$7331, #$7350, #$734D, - #$7357, #$7360, #$736C, #$736F, #$737E, #$821B, #$5925, #$98E7, - #$5924, #$5902, #$9963, #$9967, #$9968, #$9969, #$996A, #$996B, - #$996C, #$9974, #$9977, #$997D, #$9980, #$9984, #$9987, #$998A, - #$998D, #$9990, #$9991, #$9993, #$9994, #$9995, #$5E80, #$5E91, - #$5E8B, #$5E96, #$5EA5, #$5EA0, #$5EB9, #$5EB5, #$5EBE, #$5EB3, - #$8D53, #$5ED2, #$5ED1, #$5EDB, #$5EE8, #$5EEA, #$81BA, #$5FC4, - #$5FC9, #$5FD6, #$5FCF, #$6003, #$5FEE, #$6004, #$5FE1, #$5FE4, - #$5FFE, #$6005, #$6006, #$5FEA, #$5FED, #$5FF8, #$6019, #$6035, - #$6026, #$601B, #$600F, #$600D, #$6029, #$602B, #$600A, #$603F, - #$6021, #$6078, #$6079, #$607B, #$607A, #$6042, - #$606A, #$607D, #$6096, #$609A, #$60AD, #$609D, #$6083, #$6092, - #$608C, #$609B, #$60EC, #$60BB, #$60B1, #$60DD, #$60D8, #$60C6, - #$60DA, #$60B4, #$6120, #$6126, #$6115, #$6123, #$60F4, #$6100, - #$610E, #$612B, #$614A, #$6175, #$61AC, #$6194, #$61A7, #$61B7, - #$61D4, #$61F5, #$5FDD, #$96B3, #$95E9, #$95EB, #$95F1, #$95F3, - #$95F5, #$95F6, #$95FC, #$95FE, #$9603, #$9604, #$9606, #$9608, - #$960A, #$960B, #$960C, #$960D, #$960F, #$9612, #$9615, #$9616, - #$9617, #$9619, #$961A, #$4E2C, #$723F, #$6215, #$6C35, #$6C54, - #$6C5C, #$6C4A, #$6CA3, #$6C85, #$6C90, #$6C94, #$6C8C, #$6C68, - #$6C69, #$6C74, #$6C76, #$6C86, #$6CA9, #$6CD0, #$6CD4, #$6CAD, - #$6CF7, #$6CF8, #$6CF1, #$6CD7, #$6CB2, #$6CE0, #$6CD6, #$6CFA, - #$6CEB, #$6CEE, #$6CB1, #$6CD3, #$6CEF, #$6CFE, - #$6D39, #$6D27, #$6D0C, #$6D43, #$6D48, #$6D07, #$6D04, #$6D19, - #$6D0E, #$6D2B, #$6D4D, #$6D2E, #$6D35, #$6D1A, #$6D4F, #$6D52, - #$6D54, #$6D33, #$6D91, #$6D6F, #$6D9E, #$6DA0, #$6D5E, #$6D93, - #$6D94, #$6D5C, #$6D60, #$6D7C, #$6D63, #$6E1A, #$6DC7, #$6DC5, - #$6DDE, #$6E0E, #$6DBF, #$6DE0, #$6E11, #$6DE6, #$6DDD, #$6DD9, - #$6E16, #$6DAB, #$6E0C, #$6DAE, #$6E2B, #$6E6E, #$6E4E, #$6E6B, - #$6EB2, #$6E5F, #$6E86, #$6E53, #$6E54, #$6E32, #$6E25, #$6E44, - #$6EDF, #$6EB1, #$6E98, #$6EE0, #$6F2D, #$6EE2, #$6EA5, #$6EA7, - #$6EBD, #$6EBB, #$6EB7, #$6ED7, #$6EB4, #$6ECF, #$6E8F, #$6EC2, - #$6E9F, #$6F62, #$6F46, #$6F47, #$6F24, #$6F15, #$6EF9, #$6F2F, - #$6F36, #$6F4B, #$6F74, #$6F2A, #$6F09, #$6F29, #$6F89, #$6F8D, - #$6F8C, #$6F78, #$6F72, #$6F7C, #$6F7A, #$6FD1, - #$6FC9, #$6FA7, #$6FB9, #$6FB6, #$6FC2, #$6FE1, #$6FEE, #$6FDE, - #$6FE0, #$6FEF, #$701A, #$7023, #$701B, #$7039, #$7035, #$704F, - #$705E, #$5B80, #$5B84, #$5B95, #$5B93, #$5BA5, #$5BB8, #$752F, - #$9A9E, #$6434, #$5BE4, #$5BEE, #$8930, #$5BF0, #$8E47, #$8B07, - #$8FB6, #$8FD3, #$8FD5, #$8FE5, #$8FEE, #$8FE4, #$8FE9, #$8FE6, - #$8FF3, #$8FE8, #$9005, #$9004, #$900B, #$9026, #$9011, #$900D, - #$9016, #$9021, #$9035, #$9036, #$902D, #$902F, #$9044, #$9051, - #$9052, #$9050, #$9068, #$9058, #$9062, #$905B, #$66B9, #$9074, - #$907D, #$9082, #$9088, #$9083, #$908B, #$5F50, #$5F57, #$5F56, - #$5F58, #$5C3B, #$54AB, #$5C50, #$5C59, #$5B71, #$5C63, #$5C66, - #$7FBC, #$5F2A, #$5F29, #$5F2D, #$8274, #$5F3C, #$9B3B, #$5C6E, - #$5981, #$5983, #$598D, #$59A9, #$59AA, #$59A3, - #$5997, #$59CA, #$59AB, #$599E, #$59A4, #$59D2, #$59B2, #$59AF, - #$59D7, #$59BE, #$5A05, #$5A06, #$59DD, #$5A08, #$59E3, #$59D8, - #$59F9, #$5A0C, #$5A09, #$5A32, #$5A34, #$5A11, #$5A23, #$5A13, - #$5A40, #$5A67, #$5A4A, #$5A55, #$5A3C, #$5A62, #$5A75, #$80EC, - #$5AAA, #$5A9B, #$5A77, #$5A7A, #$5ABE, #$5AEB, #$5AB2, #$5AD2, - #$5AD4, #$5AB8, #$5AE0, #$5AE3, #$5AF1, #$5AD6, #$5AE6, #$5AD8, - #$5ADC, #$5B09, #$5B17, #$5B16, #$5B32, #$5B37, #$5B40, #$5C15, - #$5C1C, #$5B5A, #$5B65, #$5B73, #$5B51, #$5B53, #$5B62, #$9A75, - #$9A77, #$9A78, #$9A7A, #$9A7F, #$9A7D, #$9A80, #$9A81, #$9A85, - #$9A88, #$9A8A, #$9A90, #$9A92, #$9A93, #$9A96, #$9A98, #$9A9B, - #$9A9C, #$9A9D, #$9A9F, #$9AA0, #$9AA2, #$9AA3, #$9AA5, #$9AA7, - #$7E9F, #$7EA1, #$7EA3, #$7EA5, #$7EA8, #$7EA9, - #$7EAD, #$7EB0, #$7EBE, #$7EC0, #$7EC1, #$7EC2, #$7EC9, #$7ECB, - #$7ECC, #$7ED0, #$7ED4, #$7ED7, #$7EDB, #$7EE0, #$7EE1, #$7EE8, - #$7EEB, #$7EEE, #$7EEF, #$7EF1, #$7EF2, #$7F0D, #$7EF6, #$7EFA, - #$7EFB, #$7EFE, #$7F01, #$7F02, #$7F03, #$7F07, #$7F08, #$7F0B, - #$7F0C, #$7F0F, #$7F11, #$7F12, #$7F17, #$7F19, #$7F1C, #$7F1B, - #$7F1F, #$7F21, #$7F22, #$7F23, #$7F24, #$7F25, #$7F26, #$7F27, - #$7F2A, #$7F2B, #$7F2C, #$7F2D, #$7F2F, #$7F30, #$7F31, #$7F32, - #$7F33, #$7F35, #$5E7A, #$757F, #$5DDB, #$753E, #$9095, #$738E, - #$7391, #$73AE, #$73A2, #$739F, #$73CF, #$73C2, #$73D1, #$73B7, - #$73B3, #$73C0, #$73C9, #$73C8, #$73E5, #$73D9, #$987C, #$740A, - #$73E9, #$73E7, #$73DE, #$73BA, #$73F2, #$740F, #$742A, #$745B, - #$7426, #$7425, #$7428, #$7430, #$742E, #$742C, - #$741B, #$741A, #$7441, #$745C, #$7457, #$7455, #$7459, #$7477, - #$746D, #$747E, #$749C, #$748E, #$7480, #$7481, #$7487, #$748B, - #$749E, #$74A8, #$74A9, #$7490, #$74A7, #$74D2, #$74BA, #$97EA, - #$97EB, #$97EC, #$674C, #$6753, #$675E, #$6748, #$6769, #$67A5, - #$6787, #$676A, #$6773, #$6798, #$67A7, #$6775, #$67A8, #$679E, - #$67AD, #$678B, #$6777, #$677C, #$67F0, #$6809, #$67D8, #$680A, - #$67E9, #$67B0, #$680C, #$67D9, #$67B5, #$67DA, #$67B3, #$67DD, - #$6800, #$67C3, #$67B8, #$67E2, #$680E, #$67C1, #$67FD, #$6832, - #$6833, #$6860, #$6861, #$684E, #$6862, #$6844, #$6864, #$6883, - #$681D, #$6855, #$6866, #$6841, #$6867, #$6840, #$683E, #$684A, - #$6849, #$6829, #$68B5, #$688F, #$6874, #$6877, #$6893, #$686B, - #$68C2, #$696E, #$68FC, #$691F, #$6920, #$68F9, - #$6924, #$68F0, #$690B, #$6901, #$6957, #$68E3, #$6910, #$6971, - #$6939, #$6960, #$6942, #$695D, #$6984, #$696B, #$6980, #$6998, - #$6978, #$6934, #$69CC, #$6987, #$6988, #$69CE, #$6989, #$6966, - #$6963, #$6979, #$699B, #$69A7, #$69BB, #$69AB, #$69AD, #$69D4, - #$69B1, #$69C1, #$69CA, #$69DF, #$6995, #$69E0, #$698D, #$69FF, - #$6A2F, #$69ED, #$6A17, #$6A18, #$6A65, #$69F2, #$6A44, #$6A3E, - #$6AA0, #$6A50, #$6A5B, #$6A35, #$6A8E, #$6A79, #$6A3D, #$6A28, - #$6A58, #$6A7C, #$6A91, #$6A90, #$6AA9, #$6A97, #$6AAB, #$7337, - #$7352, #$6B81, #$6B82, #$6B87, #$6B84, #$6B92, #$6B93, #$6B8D, - #$6B9A, #$6B9B, #$6BA1, #$6BAA, #$8F6B, #$8F6D, #$8F71, #$8F72, - #$8F73, #$8F75, #$8F76, #$8F78, #$8F77, #$8F79, #$8F7A, #$8F7C, - #$8F7E, #$8F81, #$8F82, #$8F84, #$8F87, #$8F8B, - #$8F8D, #$8F8E, #$8F8F, #$8F98, #$8F9A, #$8ECE, #$620B, #$6217, - #$621B, #$621F, #$6222, #$6221, #$6225, #$6224, #$622C, #$81E7, - #$74EF, #$74F4, #$74FF, #$750F, #$7511, #$7513, #$6534, #$65EE, - #$65EF, #$65F0, #$660A, #$6619, #$6772, #$6603, #$6615, #$6600, - #$7085, #$66F7, #$661D, #$6634, #$6631, #$6636, #$6635, #$8006, - #$665F, #$6654, #$6641, #$664F, #$6656, #$6661, #$6657, #$6677, - #$6684, #$668C, #$66A7, #$669D, #$66BE, #$66DB, #$66DC, #$66E6, - #$66E9, #$8D32, #$8D33, #$8D36, #$8D3B, #$8D3D, #$8D40, #$8D45, - #$8D46, #$8D48, #$8D49, #$8D47, #$8D4D, #$8D55, #$8D59, #$89C7, - #$89CA, #$89CB, #$89CC, #$89CE, #$89CF, #$89D0, #$89D1, #$726E, - #$729F, #$725D, #$7266, #$726F, #$727E, #$727F, #$7284, #$728B, - #$728D, #$728F, #$7292, #$6308, #$6332, #$63B0, - #$643F, #$64D8, #$8004, #$6BEA, #$6BF3, #$6BFD, #$6BF5, #$6BF9, - #$6C05, #$6C07, #$6C06, #$6C0D, #$6C15, #$6C18, #$6C19, #$6C1A, - #$6C21, #$6C29, #$6C24, #$6C2A, #$6C32, #$6535, #$6555, #$656B, - #$724D, #$7252, #$7256, #$7230, #$8662, #$5216, #$809F, #$809C, - #$8093, #$80BC, #$670A, #$80BD, #$80B1, #$80AB, #$80AD, #$80B4, - #$80B7, #$80E7, #$80E8, #$80E9, #$80EA, #$80DB, #$80C2, #$80C4, - #$80D9, #$80CD, #$80D7, #$6710, #$80DD, #$80EB, #$80F1, #$80F4, - #$80ED, #$810D, #$810E, #$80F2, #$80FC, #$6715, #$8112, #$8C5A, - #$8136, #$811E, #$812C, #$8118, #$8132, #$8148, #$814C, #$8153, - #$8174, #$8159, #$815A, #$8171, #$8160, #$8169, #$817C, #$817D, - #$816D, #$8167, #$584D, #$5AB5, #$8188, #$8182, #$8191, #$6ED5, - #$81A3, #$81AA, #$81CC, #$6726, #$81CA, #$81BB, - #$81C1, #$81A6, #$6B24, #$6B37, #$6B39, #$6B43, #$6B46, #$6B59, - #$98D1, #$98D2, #$98D3, #$98D5, #$98D9, #$98DA, #$6BB3, #$5F40, - #$6BC2, #$89F3, #$6590, #$9F51, #$6593, #$65BC, #$65C6, #$65C4, - #$65C3, #$65CC, #$65CE, #$65D2, #$65D6, #$7080, #$709C, #$7096, - #$709D, #$70BB, #$70C0, #$70B7, #$70AB, #$70B1, #$70E8, #$70CA, - #$7110, #$7113, #$7116, #$712F, #$7131, #$7173, #$715C, #$7168, - #$7145, #$7172, #$714A, #$7178, #$717A, #$7198, #$71B3, #$71B5, - #$71A8, #$71A0, #$71E0, #$71D4, #$71E7, #$71F9, #$721D, #$7228, - #$706C, #$7118, #$7166, #$71B9, #$623E, #$623D, #$6243, #$6248, - #$6249, #$793B, #$7940, #$7946, #$7949, #$795B, #$795C, #$7953, - #$795A, #$7962, #$7957, #$7960, #$796F, #$7967, #$797A, #$7985, - #$798A, #$799A, #$79A7, #$79B3, #$5FD1, #$5FD0, - #$603C, #$605D, #$605A, #$6067, #$6041, #$6059, #$6063, #$60AB, - #$6106, #$610D, #$615D, #$61A9, #$619D, #$61CB, #$61D1, #$6206, - #$8080, #$807F, #$6C93, #$6CF6, #$6DFC, #$77F6, #$77F8, #$7800, - #$7809, #$7817, #$7818, #$7811, #$65AB, #$782D, #$781C, #$781D, - #$7839, #$783A, #$783B, #$781F, #$783C, #$7825, #$782C, #$7823, - #$7829, #$784E, #$786D, #$7856, #$7857, #$7826, #$7850, #$7847, - #$784C, #$786A, #$789B, #$7893, #$789A, #$7887, #$789C, #$78A1, - #$78A3, #$78B2, #$78B9, #$78A5, #$78D4, #$78D9, #$78C9, #$78EC, - #$78F2, #$7905, #$78F4, #$7913, #$7924, #$791E, #$7934, #$9F9B, - #$9EF9, #$9EFB, #$9EFC, #$76F1, #$7704, #$770D, #$76F9, #$7707, - #$7708, #$771A, #$7722, #$7719, #$772D, #$7726, #$7735, #$7738, - #$7750, #$7751, #$7747, #$7743, #$775A, #$7768, - #$7762, #$7765, #$777F, #$778D, #$777D, #$7780, #$778C, #$7791, - #$779F, #$77A0, #$77B0, #$77B5, #$77BD, #$753A, #$7540, #$754E, - #$754B, #$7548, #$755B, #$7572, #$7579, #$7583, #$7F58, #$7F61, - #$7F5F, #$8A48, #$7F68, #$7F74, #$7F71, #$7F79, #$7F81, #$7F7E, - #$76CD, #$76E5, #$8832, #$9485, #$9486, #$9487, #$948B, #$948A, - #$948C, #$948D, #$948F, #$9490, #$9494, #$9497, #$9495, #$949A, - #$949B, #$949C, #$94A3, #$94A4, #$94AB, #$94AA, #$94AD, #$94AC, - #$94AF, #$94B0, #$94B2, #$94B4, #$94B6, #$94B7, #$94B8, #$94B9, - #$94BA, #$94BC, #$94BD, #$94BF, #$94C4, #$94C8, #$94C9, #$94CA, - #$94CB, #$94CC, #$94CD, #$94CE, #$94D0, #$94D1, #$94D2, #$94D5, - #$94D6, #$94D7, #$94D9, #$94D8, #$94DB, #$94DE, #$94DF, #$94E0, - #$94E2, #$94E4, #$94E5, #$94E7, #$94E8, #$94EA, - #$94E9, #$94EB, #$94EE, #$94EF, #$94F3, #$94F4, #$94F5, #$94F7, - #$94F9, #$94FC, #$94FD, #$94FF, #$9503, #$9502, #$9506, #$9507, - #$9509, #$950A, #$950D, #$950E, #$950F, #$9512, #$9513, #$9514, - #$9515, #$9516, #$9518, #$951B, #$951D, #$951E, #$951F, #$9522, - #$952A, #$952B, #$9529, #$952C, #$9531, #$9532, #$9534, #$9536, - #$9537, #$9538, #$953C, #$953E, #$953F, #$9542, #$9535, #$9544, - #$9545, #$9546, #$9549, #$954C, #$954E, #$954F, #$9552, #$9553, - #$9554, #$9556, #$9557, #$9558, #$9559, #$955B, #$955E, #$955F, - #$955D, #$9561, #$9562, #$9564, #$9565, #$9566, #$9567, #$9568, - #$9569, #$956A, #$956B, #$956C, #$956F, #$9571, #$9572, #$9573, - #$953A, #$77E7, #$77EC, #$96C9, #$79D5, #$79ED, #$79E3, #$79EB, - #$7A06, #$5D47, #$7A03, #$7A02, #$7A1E, #$7A14, - #$7A39, #$7A37, #$7A51, #$9ECF, #$99A5, #$7A70, #$7688, #$768E, - #$7693, #$7699, #$76A4, #$74DE, #$74E0, #$752C, #$9E20, #$9E22, - #$9E28, #$9E29, #$9E2A, #$9E2B, #$9E2C, #$9E32, #$9E31, #$9E36, - #$9E38, #$9E37, #$9E39, #$9E3A, #$9E3E, #$9E41, #$9E42, #$9E44, - #$9E46, #$9E47, #$9E48, #$9E49, #$9E4B, #$9E4C, #$9E4E, #$9E51, - #$9E55, #$9E57, #$9E5A, #$9E5B, #$9E5C, #$9E5E, #$9E63, #$9E66, - #$9E67, #$9E68, #$9E69, #$9E6A, #$9E6B, #$9E6C, #$9E71, #$9E6D, - #$9E73, #$7592, #$7594, #$7596, #$75A0, #$759D, #$75AC, #$75A3, - #$75B3, #$75B4, #$75B8, #$75C4, #$75B1, #$75B0, #$75C3, #$75C2, - #$75D6, #$75CD, #$75E3, #$75E8, #$75E6, #$75E4, #$75EB, #$75E7, - #$7603, #$75F1, #$75FC, #$75FF, #$7610, #$7600, #$7605, #$760C, - #$7617, #$760A, #$7625, #$7618, #$7615, #$7619, - #$761B, #$763C, #$7622, #$7620, #$7640, #$762D, #$7630, #$763F, - #$7635, #$7643, #$763E, #$7633, #$764D, #$765E, #$7654, #$765C, - #$7656, #$766B, #$766F, #$7FCA, #$7AE6, #$7A78, #$7A79, #$7A80, - #$7A86, #$7A88, #$7A95, #$7AA6, #$7AA0, #$7AAC, #$7AA8, #$7AAD, - #$7AB3, #$8864, #$8869, #$8872, #$887D, #$887F, #$8882, #$88A2, - #$88C6, #$88B7, #$88BC, #$88C9, #$88E2, #$88CE, #$88E3, #$88E5, - #$88F1, #$891A, #$88FC, #$88E8, #$88FE, #$88F0, #$8921, #$8919, - #$8913, #$891B, #$890A, #$8934, #$892B, #$8936, #$8941, #$8966, - #$897B, #$758B, #$80E5, #$76B2, #$76B4, #$77DC, #$8012, #$8014, - #$8016, #$801C, #$8020, #$8022, #$8025, #$8026, #$8027, #$8029, - #$8028, #$8031, #$800B, #$8035, #$8043, #$8046, #$804D, #$8052, - #$8069, #$8071, #$8983, #$9878, #$9880, #$9883, - #$9889, #$988C, #$988D, #$988F, #$9894, #$989A, #$989B, #$989E, - #$989F, #$98A1, #$98A2, #$98A5, #$98A6, #$864D, #$8654, #$866C, - #$866E, #$867F, #$867A, #$867C, #$867B, #$86A8, #$868D, #$868B, - #$86AC, #$869D, #$86A7, #$86A3, #$86AA, #$8693, #$86A9, #$86B6, - #$86C4, #$86B5, #$86CE, #$86B0, #$86BA, #$86B1, #$86AF, #$86C9, - #$86CF, #$86B4, #$86E9, #$86F1, #$86F2, #$86ED, #$86F3, #$86D0, - #$8713, #$86DE, #$86F4, #$86DF, #$86D8, #$86D1, #$8703, #$8707, - #$86F8, #$8708, #$870A, #$870D, #$8709, #$8723, #$873B, #$871E, - #$8725, #$872E, #$871A, #$873E, #$8748, #$8734, #$8731, #$8729, - #$8737, #$873F, #$8782, #$8722, #$877D, #$877E, #$877B, #$8760, - #$8770, #$874C, #$876E, #$878B, #$8753, #$8763, #$877C, #$8764, - #$8759, #$8765, #$8793, #$87AF, #$87A8, #$87D2, - #$87C6, #$8788, #$8785, #$87AD, #$8797, #$8783, #$87AB, #$87E5, - #$87AC, #$87B5, #$87B3, #$87CB, #$87D3, #$87BD, #$87D1, #$87C0, - #$87CA, #$87DB, #$87EA, #$87E0, #$87EE, #$8816, #$8813, #$87FE, - #$880A, #$881B, #$8821, #$8839, #$883C, #$7F36, #$7F42, #$7F44, - #$7F45, #$8210, #$7AFA, #$7AFD, #$7B08, #$7B03, #$7B04, #$7B15, - #$7B0A, #$7B2B, #$7B0F, #$7B47, #$7B38, #$7B2A, #$7B19, #$7B2E, - #$7B31, #$7B20, #$7B25, #$7B24, #$7B33, #$7B3E, #$7B1E, #$7B58, - #$7B5A, #$7B45, #$7B75, #$7B4C, #$7B5D, #$7B60, #$7B6E, #$7B7B, - #$7B62, #$7B72, #$7B71, #$7B90, #$7BA6, #$7BA7, #$7BB8, #$7BAC, - #$7B9D, #$7BA8, #$7B85, #$7BAA, #$7B9C, #$7BA2, #$7BAB, #$7BB4, - #$7BD1, #$7BC1, #$7BCC, #$7BDD, #$7BDA, #$7BE5, #$7BE6, #$7BEA, - #$7C0C, #$7BFE, #$7BFC, #$7C0F, #$7C16, #$7C0B, - #$7C1F, #$7C2A, #$7C26, #$7C38, #$7C41, #$7C40, #$81FE, #$8201, - #$8202, #$8204, #$81EC, #$8844, #$8221, #$8222, #$8223, #$822D, - #$822F, #$8228, #$822B, #$8238, #$823B, #$8233, #$8234, #$823E, - #$8244, #$8249, #$824B, #$824F, #$825A, #$825F, #$8268, #$887E, - #$8885, #$8888, #$88D8, #$88DF, #$895E, #$7F9D, #$7F9F, #$7FA7, - #$7FAF, #$7FB0, #$7FB2, #$7C7C, #$6549, #$7C91, #$7C9D, #$7C9C, - #$7C9E, #$7CA2, #$7CB2, #$7CBC, #$7CBD, #$7CC1, #$7CC7, #$7CCC, - #$7CCD, #$7CC8, #$7CC5, #$7CD7, #$7CE8, #$826E, #$66A8, #$7FBF, - #$7FCE, #$7FD5, #$7FE5, #$7FE1, #$7FE6, #$7FE9, #$7FEE, #$7FF3, - #$7CF8, #$7D77, #$7DA6, #$7DAE, #$7E47, #$7E9B, #$9EB8, #$9EB4, - #$8D73, #$8D84, #$8D94, #$8D91, #$8DB1, #$8D67, #$8D6D, #$8C47, - #$8C49, #$914A, #$9150, #$914E, #$914F, #$9164, - #$9162, #$9161, #$9170, #$9169, #$916F, #$917D, #$917E, #$9172, - #$9174, #$9179, #$918C, #$9185, #$9190, #$918D, #$9191, #$91A2, - #$91A3, #$91AA, #$91AD, #$91AE, #$91AF, #$91B5, #$91B4, #$91BA, - #$8C55, #$9E7E, #$8DB8, #$8DEB, #$8E05, #$8E59, #$8E69, #$8DB5, - #$8DBF, #$8DBC, #$8DBA, #$8DC4, #$8DD6, #$8DD7, #$8DDA, #$8DDE, - #$8DCE, #$8DCF, #$8DDB, #$8DC6, #$8DEC, #$8DF7, #$8DF8, #$8DE3, - #$8DF9, #$8DFB, #$8DE4, #$8E09, #$8DFD, #$8E14, #$8E1D, #$8E1F, - #$8E2C, #$8E2E, #$8E23, #$8E2F, #$8E3A, #$8E40, #$8E39, #$8E35, - #$8E3D, #$8E31, #$8E49, #$8E41, #$8E42, #$8E51, #$8E52, #$8E4A, - #$8E70, #$8E76, #$8E7C, #$8E6F, #$8E74, #$8E85, #$8E8F, #$8E94, - #$8E90, #$8E9C, #$8E9E, #$8C78, #$8C82, #$8C8A, #$8C85, #$8C98, - #$8C94, #$659B, #$89D6, #$89DE, #$89DA, #$89DC, - #$89E5, #$89EB, #$89EF, #$8A3E, #$8B26, #$9753, #$96E9, #$96F3, - #$96EF, #$9706, #$9701, #$9708, #$970F, #$970E, #$972A, #$972D, - #$9730, #$973E, #$9F80, #$9F83, #$9F85, #$9F86, #$9F87, #$9F88, - #$9F89, #$9F8A, #$9F8C, #$9EFE, #$9F0B, #$9F0D, #$96B9, #$96BC, - #$96BD, #$96CE, #$96D2, #$77BF, #$96E0, #$928E, #$92AE, #$92C8, - #$933E, #$936A, #$93CA, #$938F, #$943E, #$946B, #$9C7F, #$9C82, - #$9C85, #$9C86, #$9C87, #$9C88, #$7A23, #$9C8B, #$9C8E, #$9C90, - #$9C91, #$9C92, #$9C94, #$9C95, #$9C9A, #$9C9B, #$9C9E, #$9C9F, - #$9CA0, #$9CA1, #$9CA2, #$9CA3, #$9CA5, #$9CA6, #$9CA7, #$9CA8, - #$9CA9, #$9CAB, #$9CAD, #$9CAE, #$9CB0, #$9CB1, #$9CB2, #$9CB3, - #$9CB4, #$9CB5, #$9CB6, #$9CB7, #$9CBA, #$9CBB, #$9CBC, #$9CBD, - #$9CC4, #$9CC5, #$9CC6, #$9CC7, #$9CCA, #$9CCB, - #$9CCC, #$9CCD, #$9CCE, #$9CCF, #$9CD0, #$9CD3, #$9CD4, #$9CD5, - #$9CD7, #$9CD8, #$9CD9, #$9CDC, #$9CDD, #$9CDF, #$9CE2, #$977C, - #$9785, #$9791, #$9792, #$9794, #$97AF, #$97AB, #$97A3, #$97B2, - #$97B4, #$9AB1, #$9AB0, #$9AB7, #$9E58, #$9AB6, #$9ABA, #$9ABC, - #$9AC1, #$9AC0, #$9AC5, #$9AC2, #$9ACB, #$9ACC, #$9AD1, #$9B45, - #$9B43, #$9B47, #$9B49, #$9B48, #$9B4D, #$9B51, #$98E8, #$990D, - #$992E, #$9955, #$9954, #$9ADF, #$9AE1, #$9AE6, #$9AEF, #$9AEB, - #$9AFB, #$9AED, #$9AF9, #$9B08, #$9B0F, #$9B13, #$9B1F, #$9B23, - #$9EBD, #$9EBE, #$7E3B, #$9E82, #$9E87, #$9E88, #$9E8B, #$9E92, - #$93D6, #$9E9D, #$9E9F, #$9EDB, #$9EDC, #$9EDD, #$9EE0, #$9EDF, - #$9EE2, #$9EE9, #$9EE7, #$9EE5, #$9EEA, #$9EEF, #$9F22, #$9F2C, - #$9F2F, #$9F39, #$9F37, #$9F3D, #$9F3E, #$9F44); - KSC5601_1Map: array[0..1114] of TBuffChar = ( - #$3000, #$3001, #$3002, #$00B7, #$2025, #$2026, #$00A8, #$3003, - #$00AD, #$2015, #$2225, #$FF3C, #$223C, #$2018, #$2019, #$201C, - #$201D, #$3014, #$3015, #$3008, #$3009, #$300A, #$300B, #$300C, - #$300D, #$300E, #$300F, #$3010, #$3011, #$00B1, #$00D7, #$00F7, - #$2260, #$2264, #$2265, #$221E, #$2234, #$00B0, #$2032, #$2033, - #$2103, #$212B, #$FFE0, #$FFE1, #$FFE5, #$2642, #$2640, #$2220, - #$22A5, #$2312, #$2202, #$2207, #$2261, #$2252, #$00A7, #$203B, - #$2606, #$2605, #$25CB, #$25CF, #$25CE, #$25C7, #$25C6, #$25A1, - #$25A0, #$25B3, #$25B2, #$25BD, #$25BC, #$2192, #$2190, #$2191, - #$2193, #$2194, #$3013, #$226A, #$226B, #$221A, #$223D, #$221D, - #$2235, #$222B, #$222C, #$2208, #$220B, #$2286, #$2287, #$2282, - #$2283, #$222A, #$2229, #$2227, #$2228, #$FFE2, - #$21D2, #$21D4, #$2200, #$2203, #$00B4, #$FF5E, #$02C7, #$02D8, - #$02DD, #$02DA, #$02D9, #$00B8, #$02DB, #$00A1, #$00BF, #$02D0, - #$222E, #$2211, #$220F, #$00A4, #$2109, #$2030, #$25C1, #$25C0, - #$25B7, #$25B6, #$2664, #$2660, #$2661, #$2665, #$2667, #$2663, - #$2299, #$25C8, #$25A3, #$25D0, #$25D1, #$2592, #$25A4, #$25A5, - #$25A8, #$25A7, #$25A6, #$25A9, #$2668, #$260F, #$260E, #$261C, - #$261E, #$00B6, #$2020, #$2021, #$2195, #$2197, #$2199, #$2196, - #$2198, #$266D, #$2669, #$266A, #$266C, #$327F, #$321C, #$2116, - #$33C7, #$2122, #$33C2, #$33D8, #$2121, #$20AC, #$00AE, #$327E, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FF01, #$FF02, #$FF03, #$FF04, #$FF05, #$FF06, #$FF07, #$FF08, - #$FF09, #$FF0A, #$FF0B, #$FF0C, #$FF0D, #$FF0E, #$FF0F, #$FF10, - #$FF11, #$FF12, #$FF13, #$FF14, #$FF15, #$FF16, #$FF17, #$FF18, - #$FF19, #$FF1A, #$FF1B, #$FF1C, #$FF1D, #$FF1E, #$FF1F, #$FF20, - #$FF21, #$FF22, #$FF23, #$FF24, #$FF25, #$FF26, #$FF27, #$FF28, - #$FF29, #$FF2A, #$FF2B, #$FF2C, #$FF2D, #$FF2E, #$FF2F, #$FF30, - #$FF31, #$FF32, #$FF33, #$FF34, #$FF35, #$FF36, #$FF37, #$FF38, - #$FF39, #$FF3A, #$FF3B, #$FFE6, #$FF3D, #$FF3E, #$FF3F, #$FF40, - #$FF41, #$FF42, #$FF43, #$FF44, #$FF45, #$FF46, #$FF47, #$FF48, - #$FF49, #$FF4A, #$FF4B, #$FF4C, #$FF4D, #$FF4E, #$FF4F, #$FF50, - #$FF51, #$FF52, #$FF53, #$FF54, #$FF55, #$FF56, #$FF57, #$FF58, - #$FF59, #$FF5A, #$FF5B, #$FF5C, #$FF5D, #$FFE3, - #$3131, #$3132, #$3133, #$3134, #$3135, #$3136, #$3137, #$3138, - #$3139, #$313A, #$313B, #$313C, #$313D, #$313E, #$313F, #$3140, - #$3141, #$3142, #$3143, #$3144, #$3145, #$3146, #$3147, #$3148, - #$3149, #$314A, #$314B, #$314C, #$314D, #$314E, #$314F, #$3150, - #$3151, #$3152, #$3153, #$3154, #$3155, #$3156, #$3157, #$3158, - #$3159, #$315A, #$315B, #$315C, #$315D, #$315E, #$315F, #$3160, - #$3161, #$3162, #$3163, #$3164, #$3165, #$3166, #$3167, #$3168, - #$3169, #$316A, #$316B, #$316C, #$316D, #$316E, #$316F, #$3170, - #$3171, #$3172, #$3173, #$3174, #$3175, #$3176, #$3177, #$3178, - #$3179, #$317A, #$317B, #$317C, #$317D, #$317E, #$317F, #$3180, - #$3181, #$3182, #$3183, #$3184, #$3185, #$3186, #$3187, #$3188, - #$3189, #$318A, #$318B, #$318C, #$318D, #$318E, - #$2170, #$2171, #$2172, #$2173, #$2174, #$2175, #$2176, #$2177, - #$2178, #$2179, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$2160, - #$2161, #$2162, #$2163, #$2164, #$2165, #$2166, #$2167, #$2168, - #$2169, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$0391, #$0392, #$0393, #$0394, #$0395, #$0396, #$0397, #$0398, - #$0399, #$039A, #$039B, #$039C, #$039D, #$039E, #$039F, #$03A0, - #$03A1, #$03A3, #$03A4, #$03A5, #$03A6, #$03A7, #$03A8, #$03A9, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$03B1, #$03B2, #$03B3, #$03B4, #$03B5, #$03B6, #$03B7, #$03B8, - #$03B9, #$03BA, #$03BB, #$03BC, #$03BD, #$03BE, #$03BF, #$03C0, - #$03C1, #$03C3, #$03C4, #$03C5, #$03C6, #$03C7, #$03C8, #$03C9, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$2500, #$2502, #$250C, #$2510, #$2518, #$2514, #$251C, #$252C, - #$2524, #$2534, #$253C, #$2501, #$2503, #$250F, #$2513, #$251B, - #$2517, #$2523, #$2533, #$252B, #$253B, #$254B, #$2520, #$252F, - #$2528, #$2537, #$253F, #$251D, #$2530, #$2525, #$2538, #$2542, - #$2512, #$2511, #$251A, #$2519, #$2516, #$2515, #$250E, #$250D, - #$251E, #$251F, #$2521, #$2522, #$2526, #$2527, #$2529, #$252A, - #$252D, #$252E, #$2531, #$2532, #$2535, #$2536, #$2539, #$253A, - #$253D, #$253E, #$2540, #$2541, #$2543, #$2544, #$2545, #$2546, - #$2547, #$2548, #$2549, #$254A, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$3395, #$3396, #$3397, #$2113, #$3398, #$33C4, #$33A3, #$33A4, - #$33A5, #$33A6, #$3399, #$339A, #$339B, #$339C, #$339D, #$339E, - #$339F, #$33A0, #$33A1, #$33A2, #$33CA, #$338D, #$338E, #$338F, - #$33CF, #$3388, #$3389, #$33C8, #$33A7, #$33A8, #$33B0, #$33B1, - #$33B2, #$33B3, #$33B4, #$33B5, #$33B6, #$33B7, #$33B8, #$33B9, - #$3380, #$3381, #$3382, #$3383, #$3384, #$33BA, #$33BB, #$33BC, - #$33BD, #$33BE, #$33BF, #$3390, #$3391, #$3392, #$3393, #$3394, - #$2126, #$33C0, #$33C1, #$338A, #$338B, #$338C, #$33D6, #$33C5, - #$33AD, #$33AE, #$33AF, #$33DB, #$33A9, #$33AA, #$33AB, #$33AC, - #$33DD, #$33D0, #$33D3, #$33C3, #$33C9, #$33DC, #$33C6, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$00C6, #$00D0, #$00AA, #$0126, #$FFFD, #$0132, #$FFFD, #$013F, - #$0141, #$00D8, #$0152, #$00BA, #$00DE, #$0166, #$014A, #$FFFD, - #$3260, #$3261, #$3262, #$3263, #$3264, #$3265, #$3266, #$3267, - #$3268, #$3269, #$326A, #$326B, #$326C, #$326D, #$326E, #$326F, - #$3270, #$3271, #$3272, #$3273, #$3274, #$3275, #$3276, #$3277, - #$3278, #$3279, #$327A, #$327B, #$24D0, #$24D1, #$24D2, #$24D3, - #$24D4, #$24D5, #$24D6, #$24D7, #$24D8, #$24D9, #$24DA, #$24DB, - #$24DC, #$24DD, #$24DE, #$24DF, #$24E0, #$24E1, #$24E2, #$24E3, - #$24E4, #$24E5, #$24E6, #$24E7, #$24E8, #$24E9, #$2460, #$2461, - #$2462, #$2463, #$2464, #$2465, #$2466, #$2467, #$2468, #$2469, - #$246A, #$246B, #$246C, #$246D, #$246E, #$00BD, #$2153, #$2154, - #$00BC, #$00BE, #$215B, #$215C, #$215D, #$215E, - #$00E6, #$0111, #$00F0, #$0127, #$0131, #$0133, #$0138, #$0140, - #$0142, #$00F8, #$0153, #$00DF, #$00FE, #$0167, #$014B, #$0149, - #$3200, #$3201, #$3202, #$3203, #$3204, #$3205, #$3206, #$3207, - #$3208, #$3209, #$320A, #$320B, #$320C, #$320D, #$320E, #$320F, - #$3210, #$3211, #$3212, #$3213, #$3214, #$3215, #$3216, #$3217, - #$3218, #$3219, #$321A, #$321B, #$249C, #$249D, #$249E, #$249F, - #$24A0, #$24A1, #$24A2, #$24A3, #$24A4, #$24A5, #$24A6, #$24A7, - #$24A8, #$24A9, #$24AA, #$24AB, #$24AC, #$24AD, #$24AE, #$24AF, - #$24B0, #$24B1, #$24B2, #$24B3, #$24B4, #$24B5, #$2474, #$2475, - #$2476, #$2477, #$2478, #$2479, #$247A, #$247B, #$247C, #$247D, - #$247E, #$247F, #$2480, #$2481, #$2482, #$00B9, #$00B2, #$00B3, - #$2074, #$207F, #$2081, #$2082, #$2083, #$2084, - #$3041, #$3042, #$3043, #$3044, #$3045, #$3046, #$3047, #$3048, - #$3049, #$304A, #$304B, #$304C, #$304D, #$304E, #$304F, #$3050, - #$3051, #$3052, #$3053, #$3054, #$3055, #$3056, #$3057, #$3058, - #$3059, #$305A, #$305B, #$305C, #$305D, #$305E, #$305F, #$3060, - #$3061, #$3062, #$3063, #$3064, #$3065, #$3066, #$3067, #$3068, - #$3069, #$306A, #$306B, #$306C, #$306D, #$306E, #$306F, #$3070, - #$3071, #$3072, #$3073, #$3074, #$3075, #$3076, #$3077, #$3078, - #$3079, #$307A, #$307B, #$307C, #$307D, #$307E, #$307F, #$3080, - #$3081, #$3082, #$3083, #$3084, #$3085, #$3086, #$3087, #$3088, - #$3089, #$308A, #$308B, #$308C, #$308D, #$308E, #$308F, #$3090, - #$3091, #$3092, #$3093, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$30A1, #$30A2, #$30A3, #$30A4, #$30A5, #$30A6, #$30A7, #$30A8, - #$30A9, #$30AA, #$30AB, #$30AC, #$30AD, #$30AE, #$30AF, #$30B0, - #$30B1, #$30B2, #$30B3, #$30B4, #$30B5, #$30B6, #$30B7, #$30B8, - #$30B9, #$30BA, #$30BB, #$30BC, #$30BD, #$30BE, #$30BF, #$30C0, - #$30C1, #$30C2, #$30C3, #$30C4, #$30C5, #$30C6, #$30C7, #$30C8, - #$30C9, #$30CA, #$30CB, #$30CC, #$30CD, #$30CE, #$30CF, #$30D0, - #$30D1, #$30D2, #$30D3, #$30D4, #$30D5, #$30D6, #$30D7, #$30D8, - #$30D9, #$30DA, #$30DB, #$30DC, #$30DD, #$30DE, #$30DF, #$30E0, - #$30E1, #$30E2, #$30E3, #$30E4, #$30E5, #$30E6, #$30E7, #$30E8, - #$30E9, #$30EA, #$30EB, #$30EC, #$30ED, #$30EE, #$30EF, #$30F0, - #$30F1, #$30F2, #$30F3, #$30F4, #$30F5, #$30F6, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$0410, #$0411, #$0412, #$0413, #$0414, #$0415, #$0401, #$0416, - #$0417, #$0418, #$0419, #$041A, #$041B, #$041C, #$041D, #$041E, - #$041F, #$0420, #$0421, #$0422, #$0423, #$0424, #$0425, #$0426, - #$0427, #$0428, #$0429, #$042A, #$042B, #$042C, #$042D, #$042E, - #$042F, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$0430, #$0431, #$0432, #$0433, #$0434, #$0435, #$0451, #$0436, - #$0437, #$0438, #$0439, #$043A, #$043B, #$043C, #$043D, #$043E, - #$043F, #$0440, #$0441, #$0442, #$0443, #$0444, #$0445, #$0446, - #$0447, #$0448, #$0449, #$044A, #$044B, #$044C, #$044D, #$044E, - #$044F); - KSC5601_2Map: array[0..2349] of TBuffChar = ( - #$AC00, #$AC01, #$AC04, #$AC07, #$AC08, #$AC09, #$AC0A, #$AC10, - #$AC11, #$AC12, #$AC13, #$AC14, #$AC15, #$AC16, #$AC17, #$AC19, - #$AC1A, #$AC1B, #$AC1C, #$AC1D, #$AC20, #$AC24, #$AC2C, #$AC2D, - #$AC2F, #$AC30, #$AC31, #$AC38, #$AC39, #$AC3C, #$AC40, #$AC4B, - #$AC4D, #$AC54, #$AC58, #$AC5C, #$AC70, #$AC71, #$AC74, #$AC77, - #$AC78, #$AC7A, #$AC80, #$AC81, #$AC83, #$AC84, #$AC85, #$AC86, - #$AC89, #$AC8A, #$AC8B, #$AC8C, #$AC90, #$AC94, #$AC9C, #$AC9D, - #$AC9F, #$ACA0, #$ACA1, #$ACA8, #$ACA9, #$ACAA, #$ACAC, #$ACAF, - #$ACB0, #$ACB8, #$ACB9, #$ACBB, #$ACBC, #$ACBD, #$ACC1, #$ACC4, - #$ACC8, #$ACCC, #$ACD5, #$ACD7, #$ACE0, #$ACE1, #$ACE4, #$ACE7, - #$ACE8, #$ACEA, #$ACEC, #$ACEF, #$ACF0, #$ACF1, #$ACF3, #$ACF5, - #$ACF6, #$ACFC, #$ACFD, #$AD00, #$AD04, #$AD06, - #$AD0C, #$AD0D, #$AD0F, #$AD11, #$AD18, #$AD1C, #$AD20, #$AD29, - #$AD2C, #$AD2D, #$AD34, #$AD35, #$AD38, #$AD3C, #$AD44, #$AD45, - #$AD47, #$AD49, #$AD50, #$AD54, #$AD58, #$AD61, #$AD63, #$AD6C, - #$AD6D, #$AD70, #$AD73, #$AD74, #$AD75, #$AD76, #$AD7B, #$AD7C, - #$AD7D, #$AD7F, #$AD81, #$AD82, #$AD88, #$AD89, #$AD8C, #$AD90, - #$AD9C, #$AD9D, #$ADA4, #$ADB7, #$ADC0, #$ADC1, #$ADC4, #$ADC8, - #$ADD0, #$ADD1, #$ADD3, #$ADDC, #$ADE0, #$ADE4, #$ADF8, #$ADF9, - #$ADFC, #$ADFF, #$AE00, #$AE01, #$AE08, #$AE09, #$AE0B, #$AE0D, - #$AE14, #$AE30, #$AE31, #$AE34, #$AE37, #$AE38, #$AE3A, #$AE40, - #$AE41, #$AE43, #$AE45, #$AE46, #$AE4A, #$AE4C, #$AE4D, #$AE4E, - #$AE50, #$AE54, #$AE56, #$AE5C, #$AE5D, #$AE5F, #$AE60, #$AE61, - #$AE65, #$AE68, #$AE69, #$AE6C, #$AE70, #$AE78, - #$AE79, #$AE7B, #$AE7C, #$AE7D, #$AE84, #$AE85, #$AE8C, #$AEBC, - #$AEBD, #$AEBE, #$AEC0, #$AEC4, #$AECC, #$AECD, #$AECF, #$AED0, - #$AED1, #$AED8, #$AED9, #$AEDC, #$AEE8, #$AEEB, #$AEED, #$AEF4, - #$AEF8, #$AEFC, #$AF07, #$AF08, #$AF0D, #$AF10, #$AF2C, #$AF2D, - #$AF30, #$AF32, #$AF34, #$AF3C, #$AF3D, #$AF3F, #$AF41, #$AF42, - #$AF43, #$AF48, #$AF49, #$AF50, #$AF5C, #$AF5D, #$AF64, #$AF65, - #$AF79, #$AF80, #$AF84, #$AF88, #$AF90, #$AF91, #$AF95, #$AF9C, - #$AFB8, #$AFB9, #$AFBC, #$AFC0, #$AFC7, #$AFC8, #$AFC9, #$AFCB, - #$AFCD, #$AFCE, #$AFD4, #$AFDC, #$AFE8, #$AFE9, #$AFF0, #$AFF1, - #$AFF4, #$AFF8, #$B000, #$B001, #$B004, #$B00C, #$B010, #$B014, - #$B01C, #$B01D, #$B028, #$B044, #$B045, #$B048, #$B04A, #$B04C, - #$B04E, #$B053, #$B054, #$B055, #$B057, #$B059, - #$B05D, #$B07C, #$B07D, #$B080, #$B084, #$B08C, #$B08D, #$B08F, - #$B091, #$B098, #$B099, #$B09A, #$B09C, #$B09F, #$B0A0, #$B0A1, - #$B0A2, #$B0A8, #$B0A9, #$B0AB, #$B0AC, #$B0AD, #$B0AE, #$B0AF, - #$B0B1, #$B0B3, #$B0B4, #$B0B5, #$B0B8, #$B0BC, #$B0C4, #$B0C5, - #$B0C7, #$B0C8, #$B0C9, #$B0D0, #$B0D1, #$B0D4, #$B0D8, #$B0E0, - #$B0E5, #$B108, #$B109, #$B10B, #$B10C, #$B110, #$B112, #$B113, - #$B118, #$B119, #$B11B, #$B11C, #$B11D, #$B123, #$B124, #$B125, - #$B128, #$B12C, #$B134, #$B135, #$B137, #$B138, #$B139, #$B140, - #$B141, #$B144, #$B148, #$B150, #$B151, #$B154, #$B155, #$B158, - #$B15C, #$B160, #$B178, #$B179, #$B17C, #$B180, #$B182, #$B188, - #$B189, #$B18B, #$B18D, #$B192, #$B193, #$B194, #$B198, #$B19C, - #$B1A8, #$B1CC, #$B1D0, #$B1D4, #$B1DC, #$B1DD, - #$B1DF, #$B1E8, #$B1E9, #$B1EC, #$B1F0, #$B1F9, #$B1FB, #$B1FD, - #$B204, #$B205, #$B208, #$B20B, #$B20C, #$B214, #$B215, #$B217, - #$B219, #$B220, #$B234, #$B23C, #$B258, #$B25C, #$B260, #$B268, - #$B269, #$B274, #$B275, #$B27C, #$B284, #$B285, #$B289, #$B290, - #$B291, #$B294, #$B298, #$B299, #$B29A, #$B2A0, #$B2A1, #$B2A3, - #$B2A5, #$B2A6, #$B2AA, #$B2AC, #$B2B0, #$B2B4, #$B2C8, #$B2C9, - #$B2CC, #$B2D0, #$B2D2, #$B2D8, #$B2D9, #$B2DB, #$B2DD, #$B2E2, - #$B2E4, #$B2E5, #$B2E6, #$B2E8, #$B2EB, #$B2EC, #$B2ED, #$B2EE, - #$B2EF, #$B2F3, #$B2F4, #$B2F5, #$B2F7, #$B2F8, #$B2F9, #$B2FA, - #$B2FB, #$B2FF, #$B300, #$B301, #$B304, #$B308, #$B310, #$B311, - #$B313, #$B314, #$B315, #$B31C, #$B354, #$B355, #$B356, #$B358, - #$B35B, #$B35C, #$B35E, #$B35F, #$B364, #$B365, - #$B367, #$B369, #$B36B, #$B36E, #$B370, #$B371, #$B374, #$B378, - #$B380, #$B381, #$B383, #$B384, #$B385, #$B38C, #$B390, #$B394, - #$B3A0, #$B3A1, #$B3A8, #$B3AC, #$B3C4, #$B3C5, #$B3C8, #$B3CB, - #$B3CC, #$B3CE, #$B3D0, #$B3D4, #$B3D5, #$B3D7, #$B3D9, #$B3DB, - #$B3DD, #$B3E0, #$B3E4, #$B3E8, #$B3FC, #$B410, #$B418, #$B41C, - #$B420, #$B428, #$B429, #$B42B, #$B434, #$B450, #$B451, #$B454, - #$B458, #$B460, #$B461, #$B463, #$B465, #$B46C, #$B480, #$B488, - #$B49D, #$B4A4, #$B4A8, #$B4AC, #$B4B5, #$B4B7, #$B4B9, #$B4C0, - #$B4C4, #$B4C8, #$B4D0, #$B4D5, #$B4DC, #$B4DD, #$B4E0, #$B4E3, - #$B4E4, #$B4E6, #$B4EC, #$B4ED, #$B4EF, #$B4F1, #$B4F8, #$B514, - #$B515, #$B518, #$B51B, #$B51C, #$B524, #$B525, #$B527, #$B528, - #$B529, #$B52A, #$B530, #$B531, #$B534, #$B538, - #$B540, #$B541, #$B543, #$B544, #$B545, #$B54B, #$B54C, #$B54D, - #$B550, #$B554, #$B55C, #$B55D, #$B55F, #$B560, #$B561, #$B5A0, - #$B5A1, #$B5A4, #$B5A8, #$B5AA, #$B5AB, #$B5B0, #$B5B1, #$B5B3, - #$B5B4, #$B5B5, #$B5BB, #$B5BC, #$B5BD, #$B5C0, #$B5C4, #$B5CC, - #$B5CD, #$B5CF, #$B5D0, #$B5D1, #$B5D8, #$B5EC, #$B610, #$B611, - #$B614, #$B618, #$B625, #$B62C, #$B634, #$B648, #$B664, #$B668, - #$B69C, #$B69D, #$B6A0, #$B6A4, #$B6AB, #$B6AC, #$B6B1, #$B6D4, - #$B6F0, #$B6F4, #$B6F8, #$B700, #$B701, #$B705, #$B728, #$B729, - #$B72C, #$B72F, #$B730, #$B738, #$B739, #$B73B, #$B744, #$B748, - #$B74C, #$B754, #$B755, #$B760, #$B764, #$B768, #$B770, #$B771, - #$B773, #$B775, #$B77C, #$B77D, #$B780, #$B784, #$B78C, #$B78D, - #$B78F, #$B790, #$B791, #$B792, #$B796, #$B797, - #$B798, #$B799, #$B79C, #$B7A0, #$B7A8, #$B7A9, #$B7AB, #$B7AC, - #$B7AD, #$B7B4, #$B7B5, #$B7B8, #$B7C7, #$B7C9, #$B7EC, #$B7ED, - #$B7F0, #$B7F4, #$B7FC, #$B7FD, #$B7FF, #$B800, #$B801, #$B807, - #$B808, #$B809, #$B80C, #$B810, #$B818, #$B819, #$B81B, #$B81D, - #$B824, #$B825, #$B828, #$B82C, #$B834, #$B835, #$B837, #$B838, - #$B839, #$B840, #$B844, #$B851, #$B853, #$B85C, #$B85D, #$B860, - #$B864, #$B86C, #$B86D, #$B86F, #$B871, #$B878, #$B87C, #$B88D, - #$B8A8, #$B8B0, #$B8B4, #$B8B8, #$B8C0, #$B8C1, #$B8C3, #$B8C5, - #$B8CC, #$B8D0, #$B8D4, #$B8DD, #$B8DF, #$B8E1, #$B8E8, #$B8E9, - #$B8EC, #$B8F0, #$B8F8, #$B8F9, #$B8FB, #$B8FD, #$B904, #$B918, - #$B920, #$B93C, #$B93D, #$B940, #$B944, #$B94C, #$B94F, #$B951, - #$B958, #$B959, #$B95C, #$B960, #$B968, #$B969, - #$B96B, #$B96D, #$B974, #$B975, #$B978, #$B97C, #$B984, #$B985, - #$B987, #$B989, #$B98A, #$B98D, #$B98E, #$B9AC, #$B9AD, #$B9B0, - #$B9B4, #$B9BC, #$B9BD, #$B9BF, #$B9C1, #$B9C8, #$B9C9, #$B9CC, - #$B9CE, #$B9CF, #$B9D0, #$B9D1, #$B9D2, #$B9D8, #$B9D9, #$B9DB, - #$B9DD, #$B9DE, #$B9E1, #$B9E3, #$B9E4, #$B9E5, #$B9E8, #$B9EC, - #$B9F4, #$B9F5, #$B9F7, #$B9F8, #$B9F9, #$B9FA, #$BA00, #$BA01, - #$BA08, #$BA15, #$BA38, #$BA39, #$BA3C, #$BA40, #$BA42, #$BA48, - #$BA49, #$BA4B, #$BA4D, #$BA4E, #$BA53, #$BA54, #$BA55, #$BA58, - #$BA5C, #$BA64, #$BA65, #$BA67, #$BA68, #$BA69, #$BA70, #$BA71, - #$BA74, #$BA78, #$BA83, #$BA84, #$BA85, #$BA87, #$BA8C, #$BAA8, - #$BAA9, #$BAAB, #$BAAC, #$BAB0, #$BAB2, #$BAB8, #$BAB9, #$BABB, - #$BABD, #$BAC4, #$BAC8, #$BAD8, #$BAD9, #$BAFC, - #$BB00, #$BB04, #$BB0D, #$BB0F, #$BB11, #$BB18, #$BB1C, #$BB20, - #$BB29, #$BB2B, #$BB34, #$BB35, #$BB36, #$BB38, #$BB3B, #$BB3C, - #$BB3D, #$BB3E, #$BB44, #$BB45, #$BB47, #$BB49, #$BB4D, #$BB4F, - #$BB50, #$BB54, #$BB58, #$BB61, #$BB63, #$BB6C, #$BB88, #$BB8C, - #$BB90, #$BBA4, #$BBA8, #$BBAC, #$BBB4, #$BBB7, #$BBC0, #$BBC4, - #$BBC8, #$BBD0, #$BBD3, #$BBF8, #$BBF9, #$BBFC, #$BBFF, #$BC00, - #$BC02, #$BC08, #$BC09, #$BC0B, #$BC0C, #$BC0D, #$BC0F, #$BC11, - #$BC14, #$BC15, #$BC16, #$BC17, #$BC18, #$BC1B, #$BC1C, #$BC1D, - #$BC1E, #$BC1F, #$BC24, #$BC25, #$BC27, #$BC29, #$BC2D, #$BC30, - #$BC31, #$BC34, #$BC38, #$BC40, #$BC41, #$BC43, #$BC44, #$BC45, - #$BC49, #$BC4C, #$BC4D, #$BC50, #$BC5D, #$BC84, #$BC85, #$BC88, - #$BC8B, #$BC8C, #$BC8E, #$BC94, #$BC95, #$BC97, - #$BC99, #$BC9A, #$BCA0, #$BCA1, #$BCA4, #$BCA7, #$BCA8, #$BCB0, - #$BCB1, #$BCB3, #$BCB4, #$BCB5, #$BCBC, #$BCBD, #$BCC0, #$BCC4, - #$BCCD, #$BCCF, #$BCD0, #$BCD1, #$BCD5, #$BCD8, #$BCDC, #$BCF4, - #$BCF5, #$BCF6, #$BCF8, #$BCFC, #$BD04, #$BD05, #$BD07, #$BD09, - #$BD10, #$BD14, #$BD24, #$BD2C, #$BD40, #$BD48, #$BD49, #$BD4C, - #$BD50, #$BD58, #$BD59, #$BD64, #$BD68, #$BD80, #$BD81, #$BD84, - #$BD87, #$BD88, #$BD89, #$BD8A, #$BD90, #$BD91, #$BD93, #$BD95, - #$BD99, #$BD9A, #$BD9C, #$BDA4, #$BDB0, #$BDB8, #$BDD4, #$BDD5, - #$BDD8, #$BDDC, #$BDE9, #$BDF0, #$BDF4, #$BDF8, #$BE00, #$BE03, - #$BE05, #$BE0C, #$BE0D, #$BE10, #$BE14, #$BE1C, #$BE1D, #$BE1F, - #$BE44, #$BE45, #$BE48, #$BE4C, #$BE4E, #$BE54, #$BE55, #$BE57, - #$BE59, #$BE5A, #$BE5B, #$BE60, #$BE61, #$BE64, - #$BE68, #$BE6A, #$BE70, #$BE71, #$BE73, #$BE74, #$BE75, #$BE7B, - #$BE7C, #$BE7D, #$BE80, #$BE84, #$BE8C, #$BE8D, #$BE8F, #$BE90, - #$BE91, #$BE98, #$BE99, #$BEA8, #$BED0, #$BED1, #$BED4, #$BED7, - #$BED8, #$BEE0, #$BEE3, #$BEE4, #$BEE5, #$BEEC, #$BF01, #$BF08, - #$BF09, #$BF18, #$BF19, #$BF1B, #$BF1C, #$BF1D, #$BF40, #$BF41, - #$BF44, #$BF48, #$BF50, #$BF51, #$BF55, #$BF94, #$BFB0, #$BFC5, - #$BFCC, #$BFCD, #$BFD0, #$BFD4, #$BFDC, #$BFDF, #$BFE1, #$C03C, - #$C051, #$C058, #$C05C, #$C060, #$C068, #$C069, #$C090, #$C091, - #$C094, #$C098, #$C0A0, #$C0A1, #$C0A3, #$C0A5, #$C0AC, #$C0AD, - #$C0AF, #$C0B0, #$C0B3, #$C0B4, #$C0B5, #$C0B6, #$C0BC, #$C0BD, - #$C0BF, #$C0C0, #$C0C1, #$C0C5, #$C0C8, #$C0C9, #$C0CC, #$C0D0, - #$C0D8, #$C0D9, #$C0DB, #$C0DC, #$C0DD, #$C0E4, - #$C0E5, #$C0E8, #$C0EC, #$C0F4, #$C0F5, #$C0F7, #$C0F9, #$C100, - #$C104, #$C108, #$C110, #$C115, #$C11C, #$C11D, #$C11E, #$C11F, - #$C120, #$C123, #$C124, #$C126, #$C127, #$C12C, #$C12D, #$C12F, - #$C130, #$C131, #$C136, #$C138, #$C139, #$C13C, #$C140, #$C148, - #$C149, #$C14B, #$C14C, #$C14D, #$C154, #$C155, #$C158, #$C15C, - #$C164, #$C165, #$C167, #$C168, #$C169, #$C170, #$C174, #$C178, - #$C185, #$C18C, #$C18D, #$C18E, #$C190, #$C194, #$C196, #$C19C, - #$C19D, #$C19F, #$C1A1, #$C1A5, #$C1A8, #$C1A9, #$C1AC, #$C1B0, - #$C1BD, #$C1C4, #$C1C8, #$C1CC, #$C1D4, #$C1D7, #$C1D8, #$C1E0, - #$C1E4, #$C1E8, #$C1F0, #$C1F1, #$C1F3, #$C1FC, #$C1FD, #$C200, - #$C204, #$C20C, #$C20D, #$C20F, #$C211, #$C218, #$C219, #$C21C, - #$C21F, #$C220, #$C228, #$C229, #$C22B, #$C22D, - #$C22F, #$C231, #$C232, #$C234, #$C248, #$C250, #$C251, #$C254, - #$C258, #$C260, #$C265, #$C26C, #$C26D, #$C270, #$C274, #$C27C, - #$C27D, #$C27F, #$C281, #$C288, #$C289, #$C290, #$C298, #$C29B, - #$C29D, #$C2A4, #$C2A5, #$C2A8, #$C2AC, #$C2AD, #$C2B4, #$C2B5, - #$C2B7, #$C2B9, #$C2DC, #$C2DD, #$C2E0, #$C2E3, #$C2E4, #$C2EB, - #$C2EC, #$C2ED, #$C2EF, #$C2F1, #$C2F6, #$C2F8, #$C2F9, #$C2FB, - #$C2FC, #$C300, #$C308, #$C309, #$C30C, #$C30D, #$C313, #$C314, - #$C315, #$C318, #$C31C, #$C324, #$C325, #$C328, #$C329, #$C345, - #$C368, #$C369, #$C36C, #$C370, #$C372, #$C378, #$C379, #$C37C, - #$C37D, #$C384, #$C388, #$C38C, #$C3C0, #$C3D8, #$C3D9, #$C3DC, - #$C3DF, #$C3E0, #$C3E2, #$C3E8, #$C3E9, #$C3ED, #$C3F4, #$C3F5, - #$C3F8, #$C408, #$C410, #$C424, #$C42C, #$C430, - #$C434, #$C43C, #$C43D, #$C448, #$C464, #$C465, #$C468, #$C46C, - #$C474, #$C475, #$C479, #$C480, #$C494, #$C49C, #$C4B8, #$C4BC, - #$C4E9, #$C4F0, #$C4F1, #$C4F4, #$C4F8, #$C4FA, #$C4FF, #$C500, - #$C501, #$C50C, #$C510, #$C514, #$C51C, #$C528, #$C529, #$C52C, - #$C530, #$C538, #$C539, #$C53B, #$C53D, #$C544, #$C545, #$C548, - #$C549, #$C54A, #$C54C, #$C54D, #$C54E, #$C553, #$C554, #$C555, - #$C557, #$C558, #$C559, #$C55D, #$C55E, #$C560, #$C561, #$C564, - #$C568, #$C570, #$C571, #$C573, #$C574, #$C575, #$C57C, #$C57D, - #$C580, #$C584, #$C587, #$C58C, #$C58D, #$C58F, #$C591, #$C595, - #$C597, #$C598, #$C59C, #$C5A0, #$C5A9, #$C5B4, #$C5B5, #$C5B8, - #$C5B9, #$C5BB, #$C5BC, #$C5BD, #$C5BE, #$C5C4, #$C5C5, #$C5C6, - #$C5C7, #$C5C8, #$C5C9, #$C5CA, #$C5CC, #$C5CE, - #$C5D0, #$C5D1, #$C5D4, #$C5D8, #$C5E0, #$C5E1, #$C5E3, #$C5E5, - #$C5EC, #$C5ED, #$C5EE, #$C5F0, #$C5F4, #$C5F6, #$C5F7, #$C5FC, - #$C5FD, #$C5FE, #$C5FF, #$C600, #$C601, #$C605, #$C606, #$C607, - #$C608, #$C60C, #$C610, #$C618, #$C619, #$C61B, #$C61C, #$C624, - #$C625, #$C628, #$C62C, #$C62D, #$C62E, #$C630, #$C633, #$C634, - #$C635, #$C637, #$C639, #$C63B, #$C640, #$C641, #$C644, #$C648, - #$C650, #$C651, #$C653, #$C654, #$C655, #$C65C, #$C65D, #$C660, - #$C66C, #$C66F, #$C671, #$C678, #$C679, #$C67C, #$C680, #$C688, - #$C689, #$C68B, #$C68D, #$C694, #$C695, #$C698, #$C69C, #$C6A4, - #$C6A5, #$C6A7, #$C6A9, #$C6B0, #$C6B1, #$C6B4, #$C6B8, #$C6B9, - #$C6BA, #$C6C0, #$C6C1, #$C6C3, #$C6C5, #$C6CC, #$C6CD, #$C6D0, - #$C6D4, #$C6DC, #$C6DD, #$C6E0, #$C6E1, #$C6E8, - #$C6E9, #$C6EC, #$C6F0, #$C6F8, #$C6F9, #$C6FD, #$C704, #$C705, - #$C708, #$C70C, #$C714, #$C715, #$C717, #$C719, #$C720, #$C721, - #$C724, #$C728, #$C730, #$C731, #$C733, #$C735, #$C737, #$C73C, - #$C73D, #$C740, #$C744, #$C74A, #$C74C, #$C74D, #$C74F, #$C751, - #$C752, #$C753, #$C754, #$C755, #$C756, #$C757, #$C758, #$C75C, - #$C760, #$C768, #$C76B, #$C774, #$C775, #$C778, #$C77C, #$C77D, - #$C77E, #$C783, #$C784, #$C785, #$C787, #$C788, #$C789, #$C78A, - #$C78E, #$C790, #$C791, #$C794, #$C796, #$C797, #$C798, #$C79A, - #$C7A0, #$C7A1, #$C7A3, #$C7A4, #$C7A5, #$C7A6, #$C7AC, #$C7AD, - #$C7B0, #$C7B4, #$C7BC, #$C7BD, #$C7BF, #$C7C0, #$C7C1, #$C7C8, - #$C7C9, #$C7CC, #$C7CE, #$C7D0, #$C7D8, #$C7DD, #$C7E4, #$C7E8, - #$C7EC, #$C800, #$C801, #$C804, #$C808, #$C80A, - #$C810, #$C811, #$C813, #$C815, #$C816, #$C81C, #$C81D, #$C820, - #$C824, #$C82C, #$C82D, #$C82F, #$C831, #$C838, #$C83C, #$C840, - #$C848, #$C849, #$C84C, #$C84D, #$C854, #$C870, #$C871, #$C874, - #$C878, #$C87A, #$C880, #$C881, #$C883, #$C885, #$C886, #$C887, - #$C88B, #$C88C, #$C88D, #$C894, #$C89D, #$C89F, #$C8A1, #$C8A8, - #$C8BC, #$C8BD, #$C8C4, #$C8C8, #$C8CC, #$C8D4, #$C8D5, #$C8D7, - #$C8D9, #$C8E0, #$C8E1, #$C8E4, #$C8F5, #$C8FC, #$C8FD, #$C900, - #$C904, #$C905, #$C906, #$C90C, #$C90D, #$C90F, #$C911, #$C918, - #$C92C, #$C934, #$C950, #$C951, #$C954, #$C958, #$C960, #$C961, - #$C963, #$C96C, #$C970, #$C974, #$C97C, #$C988, #$C989, #$C98C, - #$C990, #$C998, #$C999, #$C99B, #$C99D, #$C9C0, #$C9C1, #$C9C4, - #$C9C7, #$C9C8, #$C9CA, #$C9D0, #$C9D1, #$C9D3, - #$C9D5, #$C9D6, #$C9D9, #$C9DA, #$C9DC, #$C9DD, #$C9E0, #$C9E2, - #$C9E4, #$C9E7, #$C9EC, #$C9ED, #$C9EF, #$C9F0, #$C9F1, #$C9F8, - #$C9F9, #$C9FC, #$CA00, #$CA08, #$CA09, #$CA0B, #$CA0C, #$CA0D, - #$CA14, #$CA18, #$CA29, #$CA4C, #$CA4D, #$CA50, #$CA54, #$CA5C, - #$CA5D, #$CA5F, #$CA60, #$CA61, #$CA68, #$CA7D, #$CA84, #$CA98, - #$CABC, #$CABD, #$CAC0, #$CAC4, #$CACC, #$CACD, #$CACF, #$CAD1, - #$CAD3, #$CAD8, #$CAD9, #$CAE0, #$CAEC, #$CAF4, #$CB08, #$CB10, - #$CB14, #$CB18, #$CB20, #$CB21, #$CB41, #$CB48, #$CB49, #$CB4C, - #$CB50, #$CB58, #$CB59, #$CB5D, #$CB64, #$CB78, #$CB79, #$CB9C, - #$CBB8, #$CBD4, #$CBE4, #$CBE7, #$CBE9, #$CC0C, #$CC0D, #$CC10, - #$CC14, #$CC1C, #$CC1D, #$CC21, #$CC22, #$CC27, #$CC28, #$CC29, - #$CC2C, #$CC2E, #$CC30, #$CC38, #$CC39, #$CC3B, - #$CC3C, #$CC3D, #$CC3E, #$CC44, #$CC45, #$CC48, #$CC4C, #$CC54, - #$CC55, #$CC57, #$CC58, #$CC59, #$CC60, #$CC64, #$CC66, #$CC68, - #$CC70, #$CC75, #$CC98, #$CC99, #$CC9C, #$CCA0, #$CCA8, #$CCA9, - #$CCAB, #$CCAC, #$CCAD, #$CCB4, #$CCB5, #$CCB8, #$CCBC, #$CCC4, - #$CCC5, #$CCC7, #$CCC9, #$CCD0, #$CCD4, #$CCE4, #$CCEC, #$CCF0, - #$CD01, #$CD08, #$CD09, #$CD0C, #$CD10, #$CD18, #$CD19, #$CD1B, - #$CD1D, #$CD24, #$CD28, #$CD2C, #$CD39, #$CD5C, #$CD60, #$CD64, - #$CD6C, #$CD6D, #$CD6F, #$CD71, #$CD78, #$CD88, #$CD94, #$CD95, - #$CD98, #$CD9C, #$CDA4, #$CDA5, #$CDA7, #$CDA9, #$CDB0, #$CDC4, - #$CDCC, #$CDD0, #$CDE8, #$CDEC, #$CDF0, #$CDF8, #$CDF9, #$CDFB, - #$CDFD, #$CE04, #$CE08, #$CE0C, #$CE14, #$CE19, #$CE20, #$CE21, - #$CE24, #$CE28, #$CE30, #$CE31, #$CE33, #$CE35, - #$CE58, #$CE59, #$CE5C, #$CE5F, #$CE60, #$CE61, #$CE68, #$CE69, - #$CE6B, #$CE6D, #$CE74, #$CE75, #$CE78, #$CE7C, #$CE84, #$CE85, - #$CE87, #$CE89, #$CE90, #$CE91, #$CE94, #$CE98, #$CEA0, #$CEA1, - #$CEA3, #$CEA4, #$CEA5, #$CEAC, #$CEAD, #$CEC1, #$CEE4, #$CEE5, - #$CEE8, #$CEEB, #$CEEC, #$CEF4, #$CEF5, #$CEF7, #$CEF8, #$CEF9, - #$CF00, #$CF01, #$CF04, #$CF08, #$CF10, #$CF11, #$CF13, #$CF15, - #$CF1C, #$CF20, #$CF24, #$CF2C, #$CF2D, #$CF2F, #$CF30, #$CF31, - #$CF38, #$CF54, #$CF55, #$CF58, #$CF5C, #$CF64, #$CF65, #$CF67, - #$CF69, #$CF70, #$CF71, #$CF74, #$CF78, #$CF80, #$CF85, #$CF8C, - #$CFA1, #$CFA8, #$CFB0, #$CFC4, #$CFE0, #$CFE1, #$CFE4, #$CFE8, - #$CFF0, #$CFF1, #$CFF3, #$CFF5, #$CFFC, #$D000, #$D004, #$D011, - #$D018, #$D02D, #$D034, #$D035, #$D038, #$D03C, - #$D044, #$D045, #$D047, #$D049, #$D050, #$D054, #$D058, #$D060, - #$D06C, #$D06D, #$D070, #$D074, #$D07C, #$D07D, #$D081, #$D0A4, - #$D0A5, #$D0A8, #$D0AC, #$D0B4, #$D0B5, #$D0B7, #$D0B9, #$D0C0, - #$D0C1, #$D0C4, #$D0C8, #$D0C9, #$D0D0, #$D0D1, #$D0D3, #$D0D4, - #$D0D5, #$D0DC, #$D0DD, #$D0E0, #$D0E4, #$D0EC, #$D0ED, #$D0EF, - #$D0F0, #$D0F1, #$D0F8, #$D10D, #$D130, #$D131, #$D134, #$D138, - #$D13A, #$D140, #$D141, #$D143, #$D144, #$D145, #$D14C, #$D14D, - #$D150, #$D154, #$D15C, #$D15D, #$D15F, #$D161, #$D168, #$D16C, - #$D17C, #$D184, #$D188, #$D1A0, #$D1A1, #$D1A4, #$D1A8, #$D1B0, - #$D1B1, #$D1B3, #$D1B5, #$D1BA, #$D1BC, #$D1C0, #$D1D8, #$D1F4, - #$D1F8, #$D207, #$D209, #$D210, #$D22C, #$D22D, #$D230, #$D234, - #$D23C, #$D23D, #$D23F, #$D241, #$D248, #$D25C, - #$D264, #$D280, #$D281, #$D284, #$D288, #$D290, #$D291, #$D295, - #$D29C, #$D2A0, #$D2A4, #$D2AC, #$D2B1, #$D2B8, #$D2B9, #$D2BC, - #$D2BF, #$D2C0, #$D2C2, #$D2C8, #$D2C9, #$D2CB, #$D2D4, #$D2D8, - #$D2DC, #$D2E4, #$D2E5, #$D2F0, #$D2F1, #$D2F4, #$D2F8, #$D300, - #$D301, #$D303, #$D305, #$D30C, #$D30D, #$D30E, #$D310, #$D314, - #$D316, #$D31C, #$D31D, #$D31F, #$D320, #$D321, #$D325, #$D328, - #$D329, #$D32C, #$D330, #$D338, #$D339, #$D33B, #$D33C, #$D33D, - #$D344, #$D345, #$D37C, #$D37D, #$D380, #$D384, #$D38C, #$D38D, - #$D38F, #$D390, #$D391, #$D398, #$D399, #$D39C, #$D3A0, #$D3A8, - #$D3A9, #$D3AB, #$D3AD, #$D3B4, #$D3B8, #$D3BC, #$D3C4, #$D3C5, - #$D3C8, #$D3C9, #$D3D0, #$D3D8, #$D3E1, #$D3E3, #$D3EC, #$D3ED, - #$D3F0, #$D3F4, #$D3FC, #$D3FD, #$D3FF, #$D401, - #$D408, #$D41D, #$D440, #$D444, #$D45C, #$D460, #$D464, #$D46D, - #$D46F, #$D478, #$D479, #$D47C, #$D47F, #$D480, #$D482, #$D488, - #$D489, #$D48B, #$D48D, #$D494, #$D4A9, #$D4CC, #$D4D0, #$D4D4, - #$D4DC, #$D4DF, #$D4E8, #$D4EC, #$D4F0, #$D4F8, #$D4FB, #$D4FD, - #$D504, #$D508, #$D50C, #$D514, #$D515, #$D517, #$D53C, #$D53D, - #$D540, #$D544, #$D54C, #$D54D, #$D54F, #$D551, #$D558, #$D559, - #$D55C, #$D560, #$D565, #$D568, #$D569, #$D56B, #$D56D, #$D574, - #$D575, #$D578, #$D57C, #$D584, #$D585, #$D587, #$D588, #$D589, - #$D590, #$D5A5, #$D5C8, #$D5C9, #$D5CC, #$D5D0, #$D5D2, #$D5D8, - #$D5D9, #$D5DB, #$D5DD, #$D5E4, #$D5E5, #$D5E8, #$D5EC, #$D5F4, - #$D5F5, #$D5F7, #$D5F9, #$D600, #$D601, #$D604, #$D608, #$D610, - #$D611, #$D613, #$D614, #$D615, #$D61C, #$D620, - #$D624, #$D62D, #$D638, #$D639, #$D63C, #$D640, #$D645, #$D648, - #$D649, #$D64B, #$D64D, #$D651, #$D654, #$D655, #$D658, #$D65C, - #$D667, #$D669, #$D670, #$D671, #$D674, #$D683, #$D685, #$D68C, - #$D68D, #$D690, #$D694, #$D69D, #$D69F, #$D6A1, #$D6A8, #$D6AC, - #$D6B0, #$D6B9, #$D6BB, #$D6C4, #$D6C5, #$D6C8, #$D6CC, #$D6D1, - #$D6D4, #$D6D7, #$D6D9, #$D6E0, #$D6E4, #$D6E8, #$D6F0, #$D6F5, - #$D6FC, #$D6FD, #$D700, #$D704, #$D711, #$D718, #$D719, #$D71C, - #$D720, #$D728, #$D729, #$D72B, #$D72D, #$D734, #$D735, #$D738, - #$D73C, #$D744, #$D747, #$D749, #$D750, #$D751, #$D754, #$D756, - #$D757, #$D758, #$D759, #$D760, #$D761, #$D763, #$D765, #$D769, - #$D76C, #$D770, #$D774, #$D77C, #$D77D, #$D781, #$D788, #$D789, - #$D78C, #$D790, #$D798, #$D799, #$D79B, #$D79D); - KSC5601_3Map: array[0..4887] of TBuffChar = ( - #$4F3D, #$4F73, #$5047, #$50F9, #$52A0, #$53EF, #$5475, #$54E5, - #$5609, #$5AC1, #$5BB6, #$6687, #$67B6, #$67B7, #$67EF, #$6B4C, - #$73C2, #$75C2, #$7A3C, #$82DB, #$8304, #$8857, #$8888, #$8A36, - #$8CC8, #$8DCF, #$8EFB, #$8FE6, #$99D5, #$523B, #$5374, #$5404, - #$606A, #$6164, #$6BBC, #$73CF, #$811A, #$89BA, #$89D2, #$95A3, - #$4F83, #$520A, #$58BE, #$5978, #$59E6, #$5E72, #$5E79, #$61C7, - #$63C0, #$6746, #$67EC, #$687F, #$6F97, #$764E, #$770B, #$78F5, - #$7A08, #$7AFF, #$7C21, #$809D, #$826E, #$8271, #$8AEB, #$9593, - #$4E6B, #$559D, #$66F7, #$6E34, #$78A3, #$7AED, #$845B, #$8910, - #$874E, #$97A8, #$52D8, #$574E, #$582A, #$5D4C, #$611F, #$61BE, - #$6221, #$6562, #$67D1, #$6A44, #$6E1B, #$7518, #$75B3, #$76E3, - #$77B0, #$7D3A, #$90AF, #$9451, #$9452, #$9F95, - #$5323, #$5CAC, #$7532, #$80DB, #$9240, #$9598, #$525B, #$5808, - #$59DC, #$5CA1, #$5D17, #$5EB7, #$5F3A, #$5F4A, #$6177, #$6C5F, - #$757A, #$7586, #$7CE0, #$7D73, #$7DB1, #$7F8C, #$8154, #$8221, - #$8591, #$8941, #$8B1B, #$92FC, #$964D, #$9C47, #$4ECB, #$4EF7, - #$500B, #$51F1, #$584F, #$6137, #$613E, #$6168, #$6539, #$69EA, - #$6F11, #$75A5, #$7686, #$76D6, #$7B87, #$82A5, #$84CB, #$F900, - #$93A7, #$958B, #$5580, #$5BA2, #$5751, #$F901, #$7CB3, #$7FB9, - #$91B5, #$5028, #$53BB, #$5C45, #$5DE8, #$62D2, #$636E, #$64DA, - #$64E7, #$6E20, #$70AC, #$795B, #$8DDD, #$8E1E, #$F902, #$907D, - #$9245, #$92F8, #$4E7E, #$4EF6, #$5065, #$5DFE, #$5EFA, #$6106, - #$6957, #$8171, #$8654, #$8E47, #$9375, #$9A2B, #$4E5E, #$5091, - #$6770, #$6840, #$5109, #$528D, #$5292, #$6AA2, - #$77BC, #$9210, #$9ED4, #$52AB, #$602F, #$8FF2, #$5048, #$61A9, - #$63ED, #$64CA, #$683C, #$6A84, #$6FC0, #$8188, #$89A1, #$9694, - #$5805, #$727D, #$72AC, #$7504, #$7D79, #$7E6D, #$80A9, #$898B, - #$8B74, #$9063, #$9D51, #$6289, #$6C7A, #$6F54, #$7D50, #$7F3A, - #$8A23, #$517C, #$614A, #$7B9D, #$8B19, #$9257, #$938C, #$4EAC, - #$4FD3, #$501E, #$50BE, #$5106, #$52C1, #$52CD, #$537F, #$5770, - #$5883, #$5E9A, #$5F91, #$6176, #$61AC, #$64CE, #$656C, #$666F, - #$66BB, #$66F4, #$6897, #$6D87, #$7085, #$70F1, #$749F, #$74A5, - #$74CA, #$75D9, #$786C, #$78EC, #$7ADF, #$7AF6, #$7D45, #$7D93, - #$8015, #$803F, #$811B, #$8396, #$8B66, #$8F15, #$9015, #$93E1, - #$9803, #$9838, #$9A5A, #$9BE8, #$4FC2, #$5553, #$583A, #$5951, - #$5B63, #$5C46, #$60B8, #$6212, #$6842, #$68B0, - #$68E8, #$6EAA, #$754C, #$7678, #$78CE, #$7A3D, #$7CFB, #$7E6B, - #$7E7C, #$8A08, #$8AA1, #$8C3F, #$968E, #$9DC4, #$53E4, #$53E9, - #$544A, #$5471, #$56FA, #$59D1, #$5B64, #$5C3B, #$5EAB, #$62F7, - #$6537, #$6545, #$6572, #$66A0, #$67AF, #$69C1, #$6CBD, #$75FC, - #$7690, #$777E, #$7A3F, #$7F94, #$8003, #$80A1, #$818F, #$82E6, - #$82FD, #$83F0, #$85C1, #$8831, #$88B4, #$8AA5, #$F903, #$8F9C, - #$932E, #$96C7, #$9867, #$9AD8, #$9F13, #$54ED, #$659B, #$66F2, - #$688F, #$7A40, #$8C37, #$9D60, #$56F0, #$5764, #$5D11, #$6606, - #$68B1, #$68CD, #$6EFE, #$7428, #$889E, #$9BE4, #$6C68, #$F904, - #$9AA8, #$4F9B, #$516C, #$5171, #$529F, #$5B54, #$5DE5, #$6050, - #$606D, #$62F1, #$63A7, #$653B, #$73D9, #$7A7A, #$86A3, #$8CA2, - #$978F, #$4E32, #$5BE1, #$6208, #$679C, #$74DC, - #$79D1, #$83D3, #$8A87, #$8AB2, #$8DE8, #$904E, #$934B, #$9846, - #$5ED3, #$69E8, #$85FF, #$90ED, #$F905, #$51A0, #$5B98, #$5BEC, - #$6163, #$68FA, #$6B3E, #$704C, #$742F, #$74D8, #$7BA1, #$7F50, - #$83C5, #$89C0, #$8CAB, #$95DC, #$9928, #$522E, #$605D, #$62EC, - #$9002, #$4F8A, #$5149, #$5321, #$58D9, #$5EE3, #$66E0, #$6D38, - #$709A, #$72C2, #$73D6, #$7B50, #$80F1, #$945B, #$5366, #$639B, - #$7F6B, #$4E56, #$5080, #$584A, #$58DE, #$602A, #$6127, #$62D0, - #$69D0, #$9B41, #$5B8F, #$7D18, #$80B1, #$8F5F, #$4EA4, #$50D1, - #$54AC, #$55AC, #$5B0C, #$5DA0, #$5DE7, #$652A, #$654E, #$6821, - #$6A4B, #$72E1, #$768E, #$77EF, #$7D5E, #$7FF9, #$81A0, #$854E, - #$86DF, #$8F03, #$8F4E, #$90CA, #$9903, #$9A55, #$9BAB, #$4E18, - #$4E45, #$4E5D, #$4EC7, #$4FF1, #$5177, #$52FE, - #$5340, #$53E3, #$53E5, #$548E, #$5614, #$5775, #$57A2, #$5BC7, - #$5D87, #$5ED0, #$61FC, #$62D8, #$6551, #$67B8, #$67E9, #$69CB, - #$6B50, #$6BC6, #$6BEC, #$6C42, #$6E9D, #$7078, #$72D7, #$7396, - #$7403, #$77BF, #$77E9, #$7A76, #$7D7F, #$8009, #$81FC, #$8205, - #$820A, #$82DF, #$8862, #$8B33, #$8CFC, #$8EC0, #$9011, #$90B1, - #$9264, #$92B6, #$99D2, #$9A45, #$9CE9, #$9DD7, #$9F9C, #$570B, - #$5C40, #$83CA, #$97A0, #$97AB, #$9EB4, #$541B, #$7A98, #$7FA4, - #$88D9, #$8ECD, #$90E1, #$5800, #$5C48, #$6398, #$7A9F, #$5BAE, - #$5F13, #$7A79, #$7AAE, #$828E, #$8EAC, #$5026, #$5238, #$52F8, - #$5377, #$5708, #$62F3, #$6372, #$6B0A, #$6DC3, #$7737, #$53A5, - #$7357, #$8568, #$8E76, #$95D5, #$673A, #$6AC3, #$6F70, #$8A6D, - #$8ECC, #$994B, #$F906, #$6677, #$6B78, #$8CB4, - #$9B3C, #$F907, #$53EB, #$572D, #$594E, #$63C6, #$69FB, #$73EA, - #$7845, #$7ABA, #$7AC5, #$7CFE, #$8475, #$898F, #$8D73, #$9035, - #$95A8, #$52FB, #$5747, #$7547, #$7B60, #$83CC, #$921E, #$F908, - #$6A58, #$514B, #$524B, #$5287, #$621F, #$68D8, #$6975, #$9699, - #$50C5, #$52A4, #$52E4, #$61C3, #$65A4, #$6839, #$69FF, #$747E, - #$7B4B, #$82B9, #$83EB, #$89B2, #$8B39, #$8FD1, #$9949, #$F909, - #$4ECA, #$5997, #$64D2, #$6611, #$6A8E, #$7434, #$7981, #$79BD, - #$82A9, #$887E, #$887F, #$895F, #$F90A, #$9326, #$4F0B, #$53CA, - #$6025, #$6271, #$6C72, #$7D1A, #$7D66, #$4E98, #$5162, #$77DC, - #$80AF, #$4F01, #$4F0E, #$5176, #$5180, #$55DC, #$5668, #$573B, - #$57FA, #$57FC, #$5914, #$5947, #$5993, #$5BC4, #$5C90, #$5D0E, - #$5DF1, #$5E7E, #$5FCC, #$6280, #$65D7, #$65E3, - #$671E, #$671F, #$675E, #$68CB, #$68C4, #$6A5F, #$6B3A, #$6C23, - #$6C7D, #$6C82, #$6DC7, #$7398, #$7426, #$742A, #$7482, #$74A3, - #$7578, #$757F, #$7881, #$78EF, #$7941, #$7947, #$7948, #$797A, - #$7B95, #$7D00, #$7DBA, #$7F88, #$8006, #$802D, #$808C, #$8A18, - #$8B4F, #$8C48, #$8D77, #$9321, #$9324, #$98E2, #$9951, #$9A0E, - #$9A0F, #$9A65, #$9E92, #$7DCA, #$4F76, #$5409, #$62EE, #$6854, - #$91D1, #$55AB, #$513A, #$F90B, #$F90C, #$5A1C, #$61E6, #$F90D, - #$62CF, #$62FF, #$F90E, #$F90F, #$F910, #$F911, #$F912, #$F913, - #$90A3, #$F914, #$F915, #$F916, #$F917, #$F918, #$8AFE, #$F919, - #$F91A, #$F91B, #$F91C, #$6696, #$F91D, #$7156, #$F91E, #$F91F, - #$96E3, #$F920, #$634F, #$637A, #$5357, #$F921, #$678F, #$6960, - #$6E73, #$F922, #$7537, #$F923, #$F924, #$F925, - #$7D0D, #$F926, #$F927, #$8872, #$56CA, #$5A18, #$F928, #$F929, - #$F92A, #$F92B, #$F92C, #$4E43, #$F92D, #$5167, #$5948, #$67F0, - #$8010, #$F92E, #$5973, #$5E74, #$649A, #$79CA, #$5FF5, #$606C, - #$62C8, #$637B, #$5BE7, #$5BD7, #$52AA, #$F92F, #$5974, #$5F29, - #$6012, #$F930, #$F931, #$F932, #$7459, #$F933, #$F934, #$F935, - #$F936, #$F937, #$F938, #$99D1, #$F939, #$F93A, #$F93B, #$F93C, - #$F93D, #$F93E, #$F93F, #$F940, #$F941, #$F942, #$F943, #$6FC3, - #$F944, #$F945, #$81BF, #$8FB2, #$60F1, #$F946, #$F947, #$8166, - #$F948, #$F949, #$5C3F, #$F94A, #$F94B, #$F94C, #$F94D, #$F94E, - #$F94F, #$F950, #$F951, #$5AE9, #$8A25, #$677B, #$7D10, #$F952, - #$F953, #$F954, #$F955, #$F956, #$F957, #$80FD, #$F958, #$F959, - #$5C3C, #$6CE5, #$533F, #$6EBA, #$591A, #$8336, - #$4E39, #$4EB6, #$4F46, #$55AE, #$5718, #$58C7, #$5F56, #$65B7, - #$65E6, #$6A80, #$6BB5, #$6E4D, #$77ED, #$7AEF, #$7C1E, #$7DDE, - #$86CB, #$8892, #$9132, #$935B, #$64BB, #$6FBE, #$737A, #$75B8, - #$9054, #$5556, #$574D, #$61BA, #$64D4, #$66C7, #$6DE1, #$6E5B, - #$6F6D, #$6FB9, #$75F0, #$8043, #$81BD, #$8541, #$8983, #$8AC7, - #$8B5A, #$931F, #$6C93, #$7553, #$7B54, #$8E0F, #$905D, #$5510, - #$5802, #$5858, #$5E62, #$6207, #$649E, #$68E0, #$7576, #$7CD6, - #$87B3, #$9EE8, #$4EE3, #$5788, #$576E, #$5927, #$5C0D, #$5CB1, - #$5E36, #$5F85, #$6234, #$64E1, #$73B3, #$81FA, #$888B, #$8CB8, - #$968A, #$9EDB, #$5B85, #$5FB7, #$60B3, #$5012, #$5200, #$5230, - #$5716, #$5835, #$5857, #$5C0E, #$5C60, #$5CF6, #$5D8B, #$5EA6, - #$5F92, #$60BC, #$6311, #$6389, #$6417, #$6843, - #$68F9, #$6AC2, #$6DD8, #$6E21, #$6ED4, #$6FE4, #$71FE, #$76DC, - #$7779, #$79B1, #$7A3B, #$8404, #$89A9, #$8CED, #$8DF3, #$8E48, - #$9003, #$9014, #$9053, #$90FD, #$934D, #$9676, #$97DC, #$6BD2, - #$7006, #$7258, #$72A2, #$7368, #$7763, #$79BF, #$7BE4, #$7E9B, - #$8B80, #$58A9, #$60C7, #$6566, #$65FD, #$66BE, #$6C8C, #$711E, - #$71C9, #$8C5A, #$9813, #$4E6D, #$7A81, #$4EDD, #$51AC, #$51CD, - #$52D5, #$540C, #$61A7, #$6771, #$6850, #$68DF, #$6D1E, #$6F7C, - #$75BC, #$77B3, #$7AE5, #$80F4, #$8463, #$9285, #$515C, #$6597, - #$675C, #$6793, #$75D8, #$7AC7, #$8373, #$F95A, #$8C46, #$9017, - #$982D, #$5C6F, #$81C0, #$829A, #$9041, #$906F, #$920D, #$5F97, - #$5D9D, #$6A59, #$71C8, #$767B, #$7B49, #$85E4, #$8B04, #$9127, - #$9A30, #$5587, #$61F6, #$F95B, #$7669, #$7F85, - #$863F, #$87BA, #$88F8, #$908F, #$F95C, #$6D1B, #$70D9, #$73DE, - #$7D61, #$843D, #$F95D, #$916A, #$99F1, #$F95E, #$4E82, #$5375, - #$6B04, #$6B12, #$703E, #$721B, #$862D, #$9E1E, #$524C, #$8FA3, - #$5D50, #$64E5, #$652C, #$6B16, #$6FEB, #$7C43, #$7E9C, #$85CD, - #$8964, #$89BD, #$62C9, #$81D8, #$881F, #$5ECA, #$6717, #$6D6A, - #$72FC, #$7405, #$746F, #$8782, #$90DE, #$4F86, #$5D0D, #$5FA0, - #$840A, #$51B7, #$63A0, #$7565, #$4EAE, #$5006, #$5169, #$51C9, - #$6881, #$6A11, #$7CAE, #$7CB1, #$7CE7, #$826F, #$8AD2, #$8F1B, - #$91CF, #$4FB6, #$5137, #$52F5, #$5442, #$5EEC, #$616E, #$623E, - #$65C5, #$6ADA, #$6FFE, #$792A, #$85DC, #$8823, #$95AD, #$9A62, - #$9A6A, #$9E97, #$9ECE, #$529B, #$66C6, #$6B77, #$701D, #$792B, - #$8F62, #$9742, #$6190, #$6200, #$6523, #$6F23, - #$7149, #$7489, #$7DF4, #$806F, #$84EE, #$8F26, #$9023, #$934A, - #$51BD, #$5217, #$52A3, #$6D0C, #$70C8, #$88C2, #$5EC9, #$6582, - #$6BAE, #$6FC2, #$7C3E, #$7375, #$4EE4, #$4F36, #$56F9, #$F95F, - #$5CBA, #$5DBA, #$601C, #$73B2, #$7B2D, #$7F9A, #$7FCE, #$8046, - #$901E, #$9234, #$96F6, #$9748, #$9818, #$9F61, #$4F8B, #$6FA7, - #$79AE, #$91B4, #$96B7, #$52DE, #$F960, #$6488, #$64C4, #$6AD3, - #$6F5E, #$7018, #$7210, #$76E7, #$8001, #$8606, #$865C, #$8DEF, - #$8F05, #$9732, #$9B6F, #$9DFA, #$9E75, #$788C, #$797F, #$7DA0, - #$83C9, #$9304, #$9E7F, #$9E93, #$8AD6, #$58DF, #$5F04, #$6727, - #$7027, #$74CF, #$7C60, #$807E, #$5121, #$7028, #$7262, #$78CA, - #$8CC2, #$8CDA, #$8CF4, #$96F7, #$4E86, #$50DA, #$5BEE, #$5ED6, - #$6599, #$71CE, #$7642, #$77AD, #$804A, #$84FC, - #$907C, #$9B27, #$9F8D, #$58D8, #$5A41, #$5C62, #$6A13, #$6DDA, - #$6F0F, #$763B, #$7D2F, #$7E37, #$851E, #$8938, #$93E4, #$964B, - #$5289, #$65D2, #$67F3, #$69B4, #$6D41, #$6E9C, #$700F, #$7409, - #$7460, #$7559, #$7624, #$786B, #$8B2C, #$985E, #$516D, #$622E, - #$9678, #$4F96, #$502B, #$5D19, #$6DEA, #$7DB8, #$8F2A, #$5F8B, - #$6144, #$6817, #$F961, #$9686, #$52D2, #$808B, #$51DC, #$51CC, - #$695E, #$7A1C, #$7DBE, #$83F1, #$9675, #$4FDA, #$5229, #$5398, - #$540F, #$550E, #$5C65, #$60A7, #$674E, #$68A8, #$6D6C, #$7281, - #$72F8, #$7406, #$7483, #$F962, #$75E2, #$7C6C, #$7F79, #$7FB8, - #$8389, #$88CF, #$88E1, #$91CC, #$91D0, #$96E2, #$9BC9, #$541D, - #$6F7E, #$71D0, #$7498, #$85FA, #$8EAA, #$96A3, #$9C57, #$9E9F, - #$6797, #$6DCB, #$7433, #$81E8, #$9716, #$782C, - #$7ACB, #$7B20, #$7C92, #$6469, #$746A, #$75F2, #$78BC, #$78E8, - #$99AC, #$9B54, #$9EBB, #$5BDE, #$5E55, #$6F20, #$819C, #$83AB, - #$9088, #$4E07, #$534D, #$5A29, #$5DD2, #$5F4E, #$6162, #$633D, - #$6669, #$66FC, #$6EFF, #$6F2B, #$7063, #$779E, #$842C, #$8513, - #$883B, #$8F13, #$9945, #$9C3B, #$551C, #$62B9, #$672B, #$6CAB, - #$8309, #$896A, #$977A, #$4EA1, #$5984, #$5FD8, #$5FD9, #$671B, - #$7DB2, #$7F54, #$8292, #$832B, #$83BD, #$8F1E, #$9099, #$57CB, - #$59B9, #$5A92, #$5BD0, #$6627, #$679A, #$6885, #$6BCF, #$7164, - #$7F75, #$8CB7, #$8CE3, #$9081, #$9B45, #$8108, #$8C8A, #$964C, - #$9A40, #$9EA5, #$5B5F, #$6C13, #$731B, #$76F2, #$76DF, #$840C, - #$51AA, #$8993, #$514D, #$5195, #$52C9, #$68C9, #$6C94, #$7704, - #$7720, #$7DBF, #$7DEC, #$9762, #$9EB5, #$6EC5, - #$8511, #$51A5, #$540D, #$547D, #$660E, #$669D, #$6927, #$6E9F, - #$76BF, #$7791, #$8317, #$84C2, #$879F, #$9169, #$9298, #$9CF4, - #$8882, #$4FAE, #$5192, #$52DF, #$59C6, #$5E3D, #$6155, #$6478, - #$6479, #$66AE, #$67D0, #$6A21, #$6BCD, #$6BDB, #$725F, #$7261, - #$7441, #$7738, #$77DB, #$8017, #$82BC, #$8305, #$8B00, #$8B28, - #$8C8C, #$6728, #$6C90, #$7267, #$76EE, #$7766, #$7A46, #$9DA9, - #$6B7F, #$6C92, #$5922, #$6726, #$8499, #$536F, #$5893, #$5999, - #$5EDF, #$63CF, #$6634, #$6773, #$6E3A, #$732B, #$7AD7, #$82D7, - #$9328, #$52D9, #$5DEB, #$61AE, #$61CB, #$620A, #$62C7, #$64AB, - #$65E0, #$6959, #$6B66, #$6BCB, #$7121, #$73F7, #$755D, #$7E46, - #$821E, #$8302, #$856A, #$8AA3, #$8CBF, #$9727, #$9D61, #$58A8, - #$9ED8, #$5011, #$520E, #$543B, #$554F, #$6587, - #$6C76, #$7D0A, #$7D0B, #$805E, #$868A, #$9580, #$96EF, #$52FF, - #$6C95, #$7269, #$5473, #$5A9A, #$5C3E, #$5D4B, #$5F4C, #$5FAE, - #$672A, #$68B6, #$6963, #$6E3C, #$6E44, #$7709, #$7C73, #$7F8E, - #$8587, #$8B0E, #$8FF7, #$9761, #$9EF4, #$5CB7, #$60B6, #$610D, - #$61AB, #$654F, #$65FB, #$65FC, #$6C11, #$6CEF, #$739F, #$73C9, - #$7DE1, #$9594, #$5BC6, #$871C, #$8B10, #$525D, #$535A, #$62CD, - #$640F, #$64B2, #$6734, #$6A38, #$6CCA, #$73C0, #$749E, #$7B94, - #$7C95, #$7E1B, #$818A, #$8236, #$8584, #$8FEB, #$96F9, #$99C1, - #$4F34, #$534A, #$53CD, #$53DB, #$62CC, #$642C, #$6500, #$6591, - #$69C3, #$6CEE, #$6F58, #$73ED, #$7554, #$7622, #$76E4, #$76FC, - #$78D0, #$78FB, #$792C, #$7D46, #$822C, #$87E0, #$8FD4, #$9812, - #$98EF, #$52C3, #$62D4, #$64A5, #$6E24, #$6F51, - #$767C, #$8DCB, #$91B1, #$9262, #$9AEE, #$9B43, #$5023, #$508D, - #$574A, #$59A8, #$5C28, #$5E47, #$5F77, #$623F, #$653E, #$65B9, - #$65C1, #$6609, #$678B, #$699C, #$6EC2, #$78C5, #$7D21, #$80AA, - #$8180, #$822B, #$82B3, #$84A1, #$868C, #$8A2A, #$8B17, #$90A6, - #$9632, #$9F90, #$500D, #$4FF3, #$F963, #$57F9, #$5F98, #$62DC, - #$6392, #$676F, #$6E43, #$7119, #$76C3, #$80CC, #$80DA, #$88F4, - #$88F5, #$8919, #$8CE0, #$8F29, #$914D, #$966A, #$4F2F, #$4F70, - #$5E1B, #$67CF, #$6822, #$767D, #$767E, #$9B44, #$5E61, #$6A0A, - #$7169, #$71D4, #$756A, #$F964, #$7E41, #$8543, #$85E9, #$98DC, - #$4F10, #$7B4F, #$7F70, #$95A5, #$51E1, #$5E06, #$68B5, #$6C3E, - #$6C4E, #$6CDB, #$72AF, #$7BC4, #$8303, #$6CD5, #$743A, #$50FB, - #$5288, #$58C1, #$64D8, #$6A97, #$74A7, #$7656, - #$78A7, #$8617, #$95E2, #$9739, #$F965, #$535E, #$5F01, #$8B8A, - #$8FA8, #$8FAF, #$908A, #$5225, #$77A5, #$9C49, #$9F08, #$4E19, - #$5002, #$5175, #$5C5B, #$5E77, #$661E, #$663A, #$67C4, #$68C5, - #$70B3, #$7501, #$75C5, #$79C9, #$7ADD, #$8F27, #$9920, #$9A08, - #$4FDD, #$5821, #$5831, #$5BF6, #$666E, #$6B65, #$6D11, #$6E7A, - #$6F7D, #$73E4, #$752B, #$83E9, #$88DC, #$8913, #$8B5C, #$8F14, - #$4F0F, #$50D5, #$5310, #$535C, #$5B93, #$5FA9, #$670D, #$798F, - #$8179, #$832F, #$8514, #$8907, #$8986, #$8F39, #$8F3B, #$99A5, - #$9C12, #$672C, #$4E76, #$4FF8, #$5949, #$5C01, #$5CEF, #$5CF0, - #$6367, #$68D2, #$70FD, #$71A2, #$742B, #$7E2B, #$84EC, #$8702, - #$9022, #$92D2, #$9CF3, #$4E0D, #$4ED8, #$4FEF, #$5085, #$5256, - #$526F, #$5426, #$5490, #$57E0, #$592B, #$5A66, - #$5B5A, #$5B75, #$5BCC, #$5E9C, #$F966, #$6276, #$6577, #$65A7, - #$6D6E, #$6EA5, #$7236, #$7B26, #$7C3F, #$7F36, #$8150, #$8151, - #$819A, #$8240, #$8299, #$83A9, #$8A03, #$8CA0, #$8CE6, #$8CFB, - #$8D74, #$8DBA, #$90E8, #$91DC, #$961C, #$9644, #$99D9, #$9CE7, - #$5317, #$5206, #$5429, #$5674, #$58B3, #$5954, #$596E, #$5FFF, - #$61A4, #$626E, #$6610, #$6C7E, #$711A, #$76C6, #$7C89, #$7CDE, - #$7D1B, #$82AC, #$8CC1, #$96F0, #$F967, #$4F5B, #$5F17, #$5F7F, - #$62C2, #$5D29, #$670B, #$68DA, #$787C, #$7E43, #$9D6C, #$4E15, - #$5099, #$5315, #$532A, #$5351, #$5983, #$5A62, #$5E87, #$60B2, - #$618A, #$6249, #$6279, #$6590, #$6787, #$69A7, #$6BD4, #$6BD6, - #$6BD7, #$6BD8, #$6CB8, #$F968, #$7435, #$75FA, #$7812, #$7891, - #$79D5, #$79D8, #$7C83, #$7DCB, #$7FE1, #$80A5, - #$813E, #$81C2, #$83F2, #$871A, #$88E8, #$8AB9, #$8B6C, #$8CBB, - #$9119, #$975E, #$98DB, #$9F3B, #$56AC, #$5B2A, #$5F6C, #$658C, - #$6AB3, #$6BAF, #$6D5C, #$6FF1, #$7015, #$725D, #$73AD, #$8CA7, - #$8CD3, #$983B, #$6191, #$6C37, #$8058, #$9A01, #$4E4D, #$4E8B, - #$4E9B, #$4ED5, #$4F3A, #$4F3C, #$4F7F, #$4FDF, #$50FF, #$53F2, - #$53F8, #$5506, #$55E3, #$56DB, #$58EB, #$5962, #$5A11, #$5BEB, - #$5BFA, #$5C04, #$5DF3, #$5E2B, #$5F99, #$601D, #$6368, #$659C, - #$65AF, #$67F6, #$67FB, #$68AD, #$6B7B, #$6C99, #$6CD7, #$6E23, - #$7009, #$7345, #$7802, #$793E, #$7940, #$7960, #$79C1, #$7BE9, - #$7D17, #$7D72, #$8086, #$820D, #$838E, #$84D1, #$86C7, #$88DF, - #$8A50, #$8A5E, #$8B1D, #$8CDC, #$8D66, #$8FAD, #$90AA, #$98FC, - #$99DF, #$9E9D, #$524A, #$F969, #$6714, #$F96A, - #$5098, #$522A, #$5C71, #$6563, #$6C55, #$73CA, #$7523, #$759D, - #$7B97, #$849C, #$9178, #$9730, #$4E77, #$6492, #$6BBA, #$715E, - #$85A9, #$4E09, #$F96B, #$6749, #$68EE, #$6E17, #$829F, #$8518, - #$886B, #$63F7, #$6F81, #$9212, #$98AF, #$4E0A, #$50B7, #$50CF, - #$511F, #$5546, #$55AA, #$5617, #$5B40, #$5C19, #$5CE0, #$5E38, - #$5E8A, #$5EA0, #$5EC2, #$60F3, #$6851, #$6A61, #$6E58, #$723D, - #$7240, #$72C0, #$76F8, #$7965, #$7BB1, #$7FD4, #$88F3, #$89F4, - #$8A73, #$8C61, #$8CDE, #$971C, #$585E, #$74BD, #$8CFD, #$55C7, - #$F96C, #$7A61, #$7D22, #$8272, #$7272, #$751F, #$7525, #$F96D, - #$7B19, #$5885, #$58FB, #$5DBC, #$5E8F, #$5EB6, #$5F90, #$6055, - #$6292, #$637F, #$654D, #$6691, #$66D9, #$66F8, #$6816, #$68F2, - #$7280, #$745E, #$7B6E, #$7D6E, #$7DD6, #$7F72, - #$80E5, #$8212, #$85AF, #$897F, #$8A93, #$901D, #$92E4, #$9ECD, - #$9F20, #$5915, #$596D, #$5E2D, #$60DC, #$6614, #$6673, #$6790, - #$6C50, #$6DC5, #$6F5F, #$77F3, #$78A9, #$84C6, #$91CB, #$932B, - #$4ED9, #$50CA, #$5148, #$5584, #$5B0B, #$5BA3, #$6247, #$657E, - #$65CB, #$6E32, #$717D, #$7401, #$7444, #$7487, #$74BF, #$766C, - #$79AA, #$7DDA, #$7E55, #$7FA8, #$817A, #$81B3, #$8239, #$861A, - #$87EC, #$8A75, #$8DE3, #$9078, #$9291, #$9425, #$994D, #$9BAE, - #$5368, #$5C51, #$6954, #$6CC4, #$6D29, #$6E2B, #$820C, #$859B, - #$893B, #$8A2D, #$8AAA, #$96EA, #$9F67, #$5261, #$66B9, #$6BB2, - #$7E96, #$87FE, #$8D0D, #$9583, #$965D, #$651D, #$6D89, #$71EE, - #$F96E, #$57CE, #$59D3, #$5BAC, #$6027, #$60FA, #$6210, #$661F, - #$665F, #$7329, #$73F9, #$76DB, #$7701, #$7B6C, - #$8056, #$8072, #$8165, #$8AA0, #$9192, #$4E16, #$52E2, #$6B72, - #$6D17, #$7A05, #$7B39, #$7D30, #$F96F, #$8CB0, #$53EC, #$562F, - #$5851, #$5BB5, #$5C0F, #$5C11, #$5DE2, #$6240, #$6383, #$6414, - #$662D, #$68B3, #$6CBC, #$6D88, #$6EAF, #$701F, #$70A4, #$71D2, - #$7526, #$758F, #$758E, #$7619, #$7B11, #$7BE0, #$7C2B, #$7D20, - #$7D39, #$852C, #$856D, #$8607, #$8A34, #$900D, #$9061, #$90B5, - #$92B7, #$97F6, #$9A37, #$4FD7, #$5C6C, #$675F, #$6D91, #$7C9F, - #$7E8C, #$8B16, #$8D16, #$901F, #$5B6B, #$5DFD, #$640D, #$84C0, - #$905C, #$98E1, #$7387, #$5B8B, #$609A, #$677E, #$6DDE, #$8A1F, - #$8AA6, #$9001, #$980C, #$5237, #$F970, #$7051, #$788E, #$9396, - #$8870, #$91D7, #$4FEE, #$53D7, #$55FD, #$56DA, #$5782, #$58FD, - #$5AC2, #$5B88, #$5CAB, #$5CC0, #$5E25, #$6101, - #$620D, #$624B, #$6388, #$641C, #$6536, #$6578, #$6A39, #$6B8A, - #$6C34, #$6D19, #$6F31, #$71E7, #$72E9, #$7378, #$7407, #$74B2, - #$7626, #$7761, #$79C0, #$7A57, #$7AEA, #$7CB9, #$7D8F, #$7DAC, - #$7E61, #$7F9E, #$8129, #$8331, #$8490, #$84DA, #$85EA, #$8896, - #$8AB0, #$8B90, #$8F38, #$9042, #$9083, #$916C, #$9296, #$92B9, - #$968B, #$96A7, #$96A8, #$96D6, #$9700, #$9808, #$9996, #$9AD3, - #$9B1A, #$53D4, #$587E, #$5919, #$5B70, #$5BBF, #$6DD1, #$6F5A, - #$719F, #$7421, #$74B9, #$8085, #$83FD, #$5DE1, #$5F87, #$5FAA, - #$6042, #$65EC, #$6812, #$696F, #$6A53, #$6B89, #$6D35, #$6DF3, - #$73E3, #$76FE, #$77AC, #$7B4D, #$7D14, #$8123, #$821C, #$8340, - #$84F4, #$8563, #$8A62, #$8AC4, #$9187, #$931E, #$9806, #$99B4, - #$620C, #$8853, #$8FF0, #$9265, #$5D07, #$5D27, - #$5D69, #$745F, #$819D, #$8768, #$6FD5, #$62FE, #$7FD2, #$8936, - #$8972, #$4E1E, #$4E58, #$50E7, #$52DD, #$5347, #$627F, #$6607, - #$7E69, #$8805, #$965E, #$4F8D, #$5319, #$5636, #$59CB, #$5AA4, - #$5C38, #$5C4E, #$5C4D, #$5E02, #$5F11, #$6043, #$65BD, #$662F, - #$6642, #$67BE, #$67F4, #$731C, #$77E2, #$793A, #$7FC5, #$8494, - #$84CD, #$8996, #$8A66, #$8A69, #$8AE1, #$8C55, #$8C7A, #$57F4, - #$5BD4, #$5F0F, #$606F, #$62ED, #$690D, #$6B96, #$6E5C, #$7184, - #$7BD2, #$8755, #$8B58, #$8EFE, #$98DF, #$98FE, #$4F38, #$4F81, - #$4FE1, #$547B, #$5A20, #$5BB8, #$613C, #$65B0, #$6668, #$71FC, - #$7533, #$795E, #$7D33, #$814E, #$81E3, #$8398, #$85AA, #$85CE, - #$8703, #$8A0A, #$8EAB, #$8F9B, #$F971, #$8FC5, #$5931, #$5BA4, - #$5BE6, #$6089, #$5BE9, #$5C0B, #$5FC3, #$6C81, - #$F972, #$6DF1, #$700B, #$751A, #$82AF, #$8AF6, #$4EC0, #$5341, - #$F973, #$96D9, #$6C0F, #$4E9E, #$4FC4, #$5152, #$555E, #$5A25, - #$5CE8, #$6211, #$7259, #$82BD, #$83AA, #$86FE, #$8859, #$8A1D, - #$963F, #$96C5, #$9913, #$9D09, #$9D5D, #$580A, #$5CB3, #$5DBD, - #$5E44, #$60E1, #$6115, #$63E1, #$6A02, #$6E25, #$9102, #$9354, - #$984E, #$9C10, #$9F77, #$5B89, #$5CB8, #$6309, #$664F, #$6848, - #$773C, #$96C1, #$978D, #$9854, #$9B9F, #$65A1, #$8B01, #$8ECB, - #$95BC, #$5535, #$5CA9, #$5DD6, #$5EB5, #$6697, #$764C, #$83F4, - #$95C7, #$58D3, #$62BC, #$72CE, #$9D28, #$4EF0, #$592E, #$600F, - #$663B, #$6B83, #$79E7, #$9D26, #$5393, #$54C0, #$57C3, #$5D16, - #$611B, #$66D6, #$6DAF, #$788D, #$827E, #$9698, #$9744, #$5384, - #$627C, #$6396, #$6DB2, #$7E0A, #$814B, #$984D, - #$6AFB, #$7F4C, #$9DAF, #$9E1A, #$4E5F, #$503B, #$51B6, #$591C, - #$60F9, #$63F6, #$6930, #$723A, #$8036, #$F974, #$91CE, #$5F31, - #$F975, #$F976, #$7D04, #$82E5, #$846F, #$84BB, #$85E5, #$8E8D, - #$F977, #$4F6F, #$F978, #$F979, #$58E4, #$5B43, #$6059, #$63DA, - #$6518, #$656D, #$6698, #$F97A, #$694A, #$6A23, #$6D0B, #$7001, - #$716C, #$75D2, #$760D, #$79B3, #$7A70, #$F97B, #$7F8A, #$F97C, - #$8944, #$F97D, #$8B93, #$91C0, #$967D, #$F97E, #$990A, #$5704, - #$5FA1, #$65BC, #$6F01, #$7600, #$79A6, #$8A9E, #$99AD, #$9B5A, - #$9F6C, #$5104, #$61B6, #$6291, #$6A8D, #$81C6, #$5043, #$5830, - #$5F66, #$7109, #$8A00, #$8AFA, #$5B7C, #$8616, #$4FFA, #$513C, - #$56B4, #$5944, #$63A9, #$6DF9, #$5DAA, #$696D, #$5186, #$4E88, - #$4F59, #$F97F, #$F980, #$F981, #$5982, #$F982, - #$F983, #$6B5F, #$6C5D, #$F984, #$74B5, #$7916, #$F985, #$8207, - #$8245, #$8339, #$8F3F, #$8F5D, #$F986, #$9918, #$F987, #$F988, - #$F989, #$4EA6, #$F98A, #$57DF, #$5F79, #$6613, #$F98B, #$F98C, - #$75AB, #$7E79, #$8B6F, #$F98D, #$9006, #$9A5B, #$56A5, #$5827, - #$59F8, #$5A1F, #$5BB4, #$F98E, #$5EF6, #$F98F, #$F990, #$6350, - #$633B, #$F991, #$693D, #$6C87, #$6CBF, #$6D8E, #$6D93, #$6DF5, - #$6F14, #$F992, #$70DF, #$7136, #$7159, #$F993, #$71C3, #$71D5, - #$F994, #$784F, #$786F, #$F995, #$7B75, #$7DE3, #$F996, #$7E2F, - #$F997, #$884D, #$8EDF, #$F998, #$F999, #$F99A, #$925B, #$F99B, - #$9CF6, #$F99C, #$F99D, #$F99E, #$6085, #$6D85, #$F99F, #$71B1, - #$F9A0, #$F9A1, #$95B1, #$53AD, #$F9A2, #$F9A3, #$F9A4, #$67D3, - #$F9A5, #$708E, #$7130, #$7430, #$8276, #$82D2, - #$F9A6, #$95BB, #$9AE5, #$9E7D, #$66C4, #$F9A7, #$71C1, #$8449, - #$F9A8, #$F9A9, #$584B, #$F9AA, #$F9AB, #$5DB8, #$5F71, #$F9AC, - #$6620, #$668E, #$6979, #$69AE, #$6C38, #$6CF3, #$6E36, #$6F41, - #$6FDA, #$701B, #$702F, #$7150, #$71DF, #$7370, #$F9AD, #$745B, - #$F9AE, #$74D4, #$76C8, #$7A4E, #$7E93, #$F9AF, #$F9B0, #$82F1, - #$8A60, #$8FCE, #$F9B1, #$9348, #$F9B2, #$9719, #$F9B3, #$F9B4, - #$4E42, #$502A, #$F9B5, #$5208, #$53E1, #$66F3, #$6C6D, #$6FCA, - #$730A, #$777F, #$7A62, #$82AE, #$85DD, #$8602, #$F9B6, #$88D4, - #$8A63, #$8B7D, #$8C6B, #$F9B7, #$92B3, #$F9B8, #$9713, #$9810, - #$4E94, #$4F0D, #$4FC9, #$50B2, #$5348, #$543E, #$5433, #$55DA, - #$5862, #$58BA, #$5967, #$5A1B, #$5BE4, #$609F, #$F9B9, #$61CA, - #$6556, #$65FF, #$6664, #$68A7, #$6C5A, #$6FB3, - #$70CF, #$71AC, #$7352, #$7B7D, #$8708, #$8AA4, #$9C32, #$9F07, - #$5C4B, #$6C83, #$7344, #$7389, #$923A, #$6EAB, #$7465, #$761F, - #$7A69, #$7E15, #$860A, #$5140, #$58C5, #$64C1, #$74EE, #$7515, - #$7670, #$7FC1, #$9095, #$96CD, #$9954, #$6E26, #$74E6, #$7AA9, - #$7AAA, #$81E5, #$86D9, #$8778, #$8A1B, #$5A49, #$5B8C, #$5B9B, - #$68A1, #$6900, #$6D63, #$73A9, #$7413, #$742C, #$7897, #$7DE9, - #$7FEB, #$8118, #$8155, #$839E, #$8C4C, #$962E, #$9811, #$66F0, - #$5F80, #$65FA, #$6789, #$6C6A, #$738B, #$502D, #$5A03, #$6B6A, - #$77EE, #$5916, #$5D6C, #$5DCD, #$7325, #$754F, #$F9BA, #$F9BB, - #$50E5, #$51F9, #$582F, #$592D, #$5996, #$59DA, #$5BE5, #$F9BC, - #$F9BD, #$5DA2, #$62D7, #$6416, #$6493, #$64FE, #$F9BE, #$66DC, - #$F9BF, #$6A48, #$F9C0, #$71FF, #$7464, #$F9C1, - #$7A88, #$7AAF, #$7E47, #$7E5E, #$8000, #$8170, #$F9C2, #$87EF, - #$8981, #$8B20, #$9059, #$F9C3, #$9080, #$9952, #$617E, #$6B32, - #$6D74, #$7E1F, #$8925, #$8FB1, #$4FD1, #$50AD, #$5197, #$52C7, - #$57C7, #$5889, #$5BB9, #$5EB8, #$6142, #$6995, #$6D8C, #$6E67, - #$6EB6, #$7194, #$7462, #$7528, #$752C, #$8073, #$8338, #$84C9, - #$8E0A, #$9394, #$93DE, #$F9C4, #$4E8E, #$4F51, #$5076, #$512A, - #$53C8, #$53CB, #$53F3, #$5B87, #$5BD3, #$5C24, #$611A, #$6182, - #$65F4, #$725B, #$7397, #$7440, #$76C2, #$7950, #$7991, #$79B9, - #$7D06, #$7FBD, #$828B, #$85D5, #$865E, #$8FC2, #$9047, #$90F5, - #$91EA, #$9685, #$96E8, #$96E9, #$52D6, #$5F67, #$65ED, #$6631, - #$682F, #$715C, #$7A36, #$90C1, #$980A, #$4E91, #$F9C5, #$6A52, - #$6B9E, #$6F90, #$7189, #$8018, #$82B8, #$8553, - #$904B, #$9695, #$96F2, #$97FB, #$851A, #$9B31, #$4E90, #$718A, - #$96C4, #$5143, #$539F, #$54E1, #$5713, #$5712, #$57A3, #$5A9B, - #$5AC4, #$5BC3, #$6028, #$613F, #$63F4, #$6C85, #$6D39, #$6E72, - #$6E90, #$7230, #$733F, #$7457, #$82D1, #$8881, #$8F45, #$9060, - #$F9C6, #$9662, #$9858, #$9D1B, #$6708, #$8D8A, #$925E, #$4F4D, - #$5049, #$50DE, #$5371, #$570D, #$59D4, #$5A01, #$5C09, #$6170, - #$6690, #$6E2D, #$7232, #$744B, #$7DEF, #$80C3, #$840E, #$8466, - #$853F, #$875F, #$885B, #$8918, #$8B02, #$9055, #$97CB, #$9B4F, - #$4E73, #$4F91, #$5112, #$516A, #$F9C7, #$552F, #$55A9, #$5B7A, - #$5BA5, #$5E7C, #$5E7D, #$5EBE, #$60A0, #$60DF, #$6108, #$6109, - #$63C4, #$6538, #$6709, #$F9C8, #$67D4, #$67DA, #$F9C9, #$6961, - #$6962, #$6CB9, #$6D27, #$F9CA, #$6E38, #$F9CB, - #$6FE1, #$7336, #$7337, #$F9CC, #$745C, #$7531, #$F9CD, #$7652, - #$F9CE, #$F9CF, #$7DAD, #$81FE, #$8438, #$88D5, #$8A98, #$8ADB, - #$8AED, #$8E30, #$8E42, #$904A, #$903E, #$907A, #$9149, #$91C9, - #$936E, #$F9D0, #$F9D1, #$5809, #$F9D2, #$6BD3, #$8089, #$80B2, - #$F9D3, #$F9D4, #$5141, #$596B, #$5C39, #$F9D5, #$F9D6, #$6F64, - #$73A7, #$80E4, #$8D07, #$F9D7, #$9217, #$958F, #$F9D8, #$F9D9, - #$F9DA, #$F9DB, #$807F, #$620E, #$701C, #$7D68, #$878D, #$F9DC, - #$57A0, #$6069, #$6147, #$6BB7, #$8ABE, #$9280, #$96B1, #$4E59, - #$541F, #$6DEB, #$852D, #$9670, #$97F3, #$98EE, #$63D6, #$6CE3, - #$9091, #$51DD, #$61C9, #$81BA, #$9DF9, #$4F9D, #$501A, #$5100, - #$5B9C, #$610F, #$61FF, #$64EC, #$6905, #$6BC5, #$7591, #$77E3, - #$7FA9, #$8264, #$858F, #$87FB, #$8863, #$8ABC, - #$8B70, #$91AB, #$4E8C, #$4EE5, #$4F0A, #$F9DD, #$F9DE, #$5937, - #$59E8, #$F9DF, #$5DF2, #$5F1B, #$5F5B, #$6021, #$F9E0, #$F9E1, - #$F9E2, #$F9E3, #$723E, #$73E5, #$F9E4, #$7570, #$75CD, #$F9E5, - #$79FB, #$F9E6, #$800C, #$8033, #$8084, #$82E1, #$8351, #$F9E7, - #$F9E8, #$8CBD, #$8CB3, #$9087, #$F9E9, #$F9EA, #$98F4, #$990C, - #$F9EB, #$F9EC, #$7037, #$76CA, #$7FCA, #$7FCC, #$7FFC, #$8B1A, - #$4EBA, #$4EC1, #$5203, #$5370, #$F9ED, #$54BD, #$56E0, #$59FB, - #$5BC5, #$5F15, #$5FCD, #$6E6E, #$F9EE, #$F9EF, #$7D6A, #$8335, - #$F9F0, #$8693, #$8A8D, #$F9F1, #$976D, #$9777, #$F9F2, #$F9F3, - #$4E00, #$4F5A, #$4F7E, #$58F9, #$65E5, #$6EA2, #$9038, #$93B0, - #$99B9, #$4EFB, #$58EC, #$598A, #$59D9, #$6041, #$F9F4, #$F9F5, - #$7A14, #$F9F6, #$834F, #$8CC3, #$5165, #$5344, - #$F9F7, #$F9F8, #$F9F9, #$4ECD, #$5269, #$5B55, #$82BF, #$4ED4, - #$523A, #$54A8, #$59C9, #$59FF, #$5B50, #$5B57, #$5B5C, #$6063, - #$6148, #$6ECB, #$7099, #$716E, #$7386, #$74F7, #$75B5, #$78C1, - #$7D2B, #$8005, #$81EA, #$8328, #$8517, #$85C9, #$8AEE, #$8CC7, - #$96CC, #$4F5C, #$52FA, #$56BC, #$65AB, #$6628, #$707C, #$70B8, - #$7235, #$7DBD, #$828D, #$914C, #$96C0, #$9D72, #$5B71, #$68E7, - #$6B98, #$6F7A, #$76DE, #$5C91, #$66AB, #$6F5B, #$7BB4, #$7C2A, - #$8836, #$96DC, #$4E08, #$4ED7, #$5320, #$5834, #$58BB, #$58EF, - #$596C, #$5C07, #$5E33, #$5E84, #$5F35, #$638C, #$66B2, #$6756, - #$6A1F, #$6AA3, #$6B0C, #$6F3F, #$7246, #$F9FA, #$7350, #$748B, - #$7AE0, #$7CA7, #$8178, #$81DF, #$81E7, #$838A, #$846C, #$8523, - #$8594, #$85CF, #$88DD, #$8D13, #$91AC, #$9577, - #$969C, #$518D, #$54C9, #$5728, #$5BB0, #$624D, #$6750, #$683D, - #$6893, #$6E3D, #$6ED3, #$707D, #$7E21, #$88C1, #$8CA1, #$8F09, - #$9F4B, #$9F4E, #$722D, #$7B8F, #$8ACD, #$931A, #$4F47, #$4F4E, - #$5132, #$5480, #$59D0, #$5E95, #$62B5, #$6775, #$696E, #$6A17, - #$6CAE, #$6E1A, #$72D9, #$732A, #$75BD, #$7BB8, #$7D35, #$82E7, - #$83F9, #$8457, #$85F7, #$8A5B, #$8CAF, #$8E87, #$9019, #$90B8, - #$96CE, #$9F5F, #$52E3, #$540A, #$5AE1, #$5BC2, #$6458, #$6575, - #$6EF4, #$72C4, #$F9FB, #$7684, #$7A4D, #$7B1B, #$7C4D, #$7E3E, - #$7FDF, #$837B, #$8B2B, #$8CCA, #$8D64, #$8DE1, #$8E5F, #$8FEA, - #$8FF9, #$9069, #$93D1, #$4F43, #$4F7A, #$50B3, #$5168, #$5178, - #$524D, #$526A, #$5861, #$587C, #$5960, #$5C08, #$5C55, #$5EDB, - #$609B, #$6230, #$6813, #$6BBF, #$6C08, #$6FB1, - #$714E, #$7420, #$7530, #$7538, #$7551, #$7672, #$7B4C, #$7B8B, - #$7BAD, #$7BC6, #$7E8F, #$8A6E, #$8F3E, #$8F49, #$923F, #$9293, - #$9322, #$942B, #$96FB, #$985A, #$986B, #$991E, #$5207, #$622A, - #$6298, #$6D59, #$7664, #$7ACA, #$7BC0, #$7D76, #$5360, #$5CBE, - #$5E97, #$6F38, #$70B9, #$7C98, #$9711, #$9B8E, #$9EDE, #$63A5, - #$647A, #$8776, #$4E01, #$4E95, #$4EAD, #$505C, #$5075, #$5448, - #$59C3, #$5B9A, #$5E40, #$5EAD, #$5EF7, #$5F81, #$60C5, #$633A, - #$653F, #$6574, #$65CC, #$6676, #$6678, #$67FE, #$6968, #$6A89, - #$6B63, #$6C40, #$6DC0, #$6DE8, #$6E1F, #$6E5E, #$701E, #$70A1, - #$738E, #$73FD, #$753A, #$775B, #$7887, #$798E, #$7A0B, #$7A7D, - #$7CBE, #$7D8E, #$8247, #$8A02, #$8AEA, #$8C9E, #$912D, #$914A, - #$91D8, #$9266, #$92CC, #$9320, #$9706, #$9756, - #$975C, #$9802, #$9F0E, #$5236, #$5291, #$557C, #$5824, #$5E1D, - #$5F1F, #$608C, #$63D0, #$68AF, #$6FDF, #$796D, #$7B2C, #$81CD, - #$85BA, #$88FD, #$8AF8, #$8E44, #$918D, #$9664, #$969B, #$973D, - #$984C, #$9F4A, #$4FCE, #$5146, #$51CB, #$52A9, #$5632, #$5F14, - #$5F6B, #$63AA, #$64CD, #$65E9, #$6641, #$66FA, #$66F9, #$671D, - #$689D, #$68D7, #$69FD, #$6F15, #$6F6E, #$7167, #$71E5, #$722A, - #$74AA, #$773A, #$7956, #$795A, #$79DF, #$7A20, #$7A95, #$7C97, - #$7CDF, #$7D44, #$7E70, #$8087, #$85FB, #$86A4, #$8A54, #$8ABF, - #$8D99, #$8E81, #$9020, #$906D, #$91E3, #$963B, #$96D5, #$9CE5, - #$65CF, #$7C07, #$8DB3, #$93C3, #$5B58, #$5C0A, #$5352, #$62D9, - #$731D, #$5027, #$5B97, #$5F9E, #$60B0, #$616B, #$68D5, #$6DD9, - #$742E, #$7A2E, #$7D42, #$7D9C, #$7E31, #$816B, - #$8E2A, #$8E35, #$937E, #$9418, #$4F50, #$5750, #$5DE6, #$5EA7, - #$632B, #$7F6A, #$4E3B, #$4F4F, #$4F8F, #$505A, #$59DD, #$80C4, - #$546A, #$5468, #$55FE, #$594F, #$5B99, #$5DDE, #$5EDA, #$665D, - #$6731, #$67F1, #$682A, #$6CE8, #$6D32, #$6E4A, #$6F8D, #$70B7, - #$73E0, #$7587, #$7C4C, #$7D02, #$7D2C, #$7DA2, #$821F, #$86DB, - #$8A3B, #$8A85, #$8D70, #$8E8A, #$8F33, #$9031, #$914E, #$9152, - #$9444, #$99D0, #$7AF9, #$7CA5, #$4FCA, #$5101, #$51C6, #$57C8, - #$5BEF, #$5CFB, #$6659, #$6A3D, #$6D5A, #$6E96, #$6FEC, #$710C, - #$756F, #$7AE3, #$8822, #$9021, #$9075, #$96CB, #$99FF, #$8301, - #$4E2D, #$4EF2, #$8846, #$91CD, #$537D, #$6ADB, #$696B, #$6C41, - #$847A, #$589E, #$618E, #$66FE, #$62EF, #$70DD, #$7511, #$75C7, - #$7E52, #$84B8, #$8B49, #$8D08, #$4E4B, #$53EA, - #$54AB, #$5730, #$5740, #$5FD7, #$6301, #$6307, #$646F, #$652F, - #$65E8, #$667A, #$679D, #$67B3, #$6B62, #$6C60, #$6C9A, #$6F2C, - #$77E5, #$7825, #$7949, #$7957, #$7D19, #$80A2, #$8102, #$81F3, - #$829D, #$82B7, #$8718, #$8A8C, #$F9FC, #$8D04, #$8DBE, #$9072, - #$76F4, #$7A19, #$7A37, #$7E54, #$8077, #$5507, #$55D4, #$5875, - #$632F, #$6422, #$6649, #$664B, #$686D, #$699B, #$6B84, #$6D25, - #$6EB1, #$73CD, #$7468, #$74A1, #$755B, #$75B9, #$76E1, #$771E, - #$778B, #$79E6, #$7E09, #$7E1D, #$81FB, #$852F, #$8897, #$8A3A, - #$8CD1, #$8EEB, #$8FB0, #$9032, #$93AD, #$9663, #$9673, #$9707, - #$4F84, #$53F1, #$59EA, #$5AC9, #$5E19, #$684E, #$74C6, #$75BE, - #$79E9, #$7A92, #$81A3, #$86ED, #$8CEA, #$8DCC, #$8FED, #$659F, - #$6715, #$F9FD, #$57F7, #$6F57, #$7DDD, #$8F2F, - #$93F6, #$96C6, #$5FB5, #$61F2, #$6F84, #$4E14, #$4F98, #$501F, - #$53C9, #$55DF, #$5D6F, #$5DEE, #$6B21, #$6B64, #$78CB, #$7B9A, - #$F9FE, #$8E49, #$8ECA, #$906E, #$6349, #$643E, #$7740, #$7A84, - #$932F, #$947F, #$9F6A, #$64B0, #$6FAF, #$71E6, #$74A8, #$74DA, - #$7AC4, #$7C12, #$7E82, #$7CB2, #$7E98, #$8B9A, #$8D0A, #$947D, - #$9910, #$994C, #$5239, #$5BDF, #$64E6, #$672D, #$7D2E, #$50ED, - #$53C3, #$5879, #$6158, #$6159, #$61FA, #$65AC, #$7AD9, #$8B92, - #$8B96, #$5009, #$5021, #$5275, #$5531, #$5A3C, #$5EE0, #$5F70, - #$6134, #$655E, #$660C, #$6636, #$66A2, #$69CD, #$6EC4, #$6F32, - #$7316, #$7621, #$7A93, #$8139, #$8259, #$83D6, #$84BC, #$50B5, - #$57F0, #$5BC0, #$5BE8, #$5F69, #$63A1, #$7826, #$7DB5, #$83DC, - #$8521, #$91C7, #$91F5, #$518A, #$67F5, #$7B56, - #$8CAC, #$51C4, #$59BB, #$60BD, #$8655, #$501C, #$F9FF, #$5254, - #$5C3A, #$617D, #$621A, #$62D3, #$64F2, #$65A5, #$6ECC, #$7620, - #$810A, #$8E60, #$965F, #$96BB, #$4EDF, #$5343, #$5598, #$5929, - #$5DDD, #$64C5, #$6CC9, #$6DFA, #$7394, #$7A7F, #$821B, #$85A6, - #$8CE4, #$8E10, #$9077, #$91E7, #$95E1, #$9621, #$97C6, #$51F8, - #$54F2, #$5586, #$5FB9, #$64A4, #$6F88, #$7DB4, #$8F1F, #$8F4D, - #$9435, #$50C9, #$5C16, #$6CBE, #$6DFB, #$751B, #$77BB, #$7C3D, - #$7C64, #$8A79, #$8AC2, #$581E, #$59BE, #$5E16, #$6377, #$7252, - #$758A, #$776B, #$8ADC, #$8CBC, #$8F12, #$5EF3, #$6674, #$6DF8, - #$807D, #$83C1, #$8ACB, #$9751, #$9BD6, #$FA00, #$5243, #$66FF, - #$6D95, #$6EEF, #$7DE0, #$8AE6, #$902E, #$905E, #$9AD4, #$521D, - #$527F, #$54E8, #$6194, #$6284, #$62DB, #$68A2, - #$6912, #$695A, #$6A35, #$7092, #$7126, #$785D, #$7901, #$790E, - #$79D2, #$7A0D, #$8096, #$8278, #$82D5, #$8349, #$8549, #$8C82, - #$8D85, #$9162, #$918B, #$91AE, #$4FC3, #$56D1, #$71ED, #$77D7, - #$8700, #$89F8, #$5BF8, #$5FD6, #$6751, #$90A8, #$53E2, #$585A, - #$5BF5, #$60A4, #$6181, #$6460, #$7E3D, #$8070, #$8525, #$9283, - #$64AE, #$50AC, #$5D14, #$6700, #$589C, #$62BD, #$63A8, #$690E, - #$6978, #$6A1E, #$6E6B, #$76BA, #$79CB, #$82BB, #$8429, #$8ACF, - #$8DA8, #$8FFD, #$9112, #$914B, #$919C, #$9310, #$9318, #$939A, - #$96DB, #$9A36, #$9C0D, #$4E11, #$755C, #$795D, #$7AFA, #$7B51, - #$7BC9, #$7E2E, #$84C4, #$8E59, #$8E74, #$8EF8, #$9010, #$6625, - #$693F, #$7443, #$51FA, #$672E, #$9EDC, #$5145, #$5FE0, #$6C96, - #$87F2, #$885D, #$8877, #$60B4, #$81B5, #$8403, - #$8D05, #$53D6, #$5439, #$5634, #$5A36, #$5C31, #$708A, #$7FE0, - #$805A, #$8106, #$81ED, #$8DA3, #$9189, #$9A5F, #$9DF2, #$5074, - #$4EC4, #$53A0, #$60FB, #$6E2C, #$5C64, #$4F88, #$5024, #$55E4, - #$5CD9, #$5E5F, #$6065, #$6894, #$6CBB, #$6DC4, #$71BE, #$75D4, - #$75F4, #$7661, #$7A1A, #$7A49, #$7DC7, #$7DFB, #$7F6E, #$81F4, - #$86A9, #$8F1C, #$96C9, #$99B3, #$9F52, #$5247, #$52C5, #$98ED, - #$89AA, #$4E03, #$67D2, #$6F06, #$4FB5, #$5BE2, #$6795, #$6C88, - #$6D78, #$741B, #$7827, #$91DD, #$937C, #$87C4, #$79E4, #$7A31, - #$5FEB, #$4ED6, #$54A4, #$553E, #$58AE, #$59A5, #$60F0, #$6253, - #$62D6, #$6736, #$6955, #$8235, #$9640, #$99B1, #$99DD, #$502C, - #$5353, #$5544, #$577C, #$FA01, #$6258, #$FA02, #$64E2, #$666B, - #$67DD, #$6FC1, #$6FEF, #$7422, #$7438, #$8A17, - #$9438, #$5451, #$5606, #$5766, #$5F48, #$619A, #$6B4E, #$7058, - #$70AD, #$7DBB, #$8A95, #$596A, #$812B, #$63A2, #$7708, #$803D, - #$8CAA, #$5854, #$642D, #$69BB, #$5B95, #$5E11, #$6E6F, #$FA03, - #$8569, #$514C, #$53F0, #$592A, #$6020, #$614B, #$6B86, #$6C70, - #$6CF0, #$7B1E, #$80CE, #$82D4, #$8DC6, #$90B0, #$98B1, #$FA04, - #$64C7, #$6FA4, #$6491, #$6504, #$514E, #$5410, #$571F, #$8A0E, - #$615F, #$6876, #$FA05, #$75DB, #$7B52, #$7D71, #$901A, #$5806, - #$69CC, #$817F, #$892A, #$9000, #$9839, #$5078, #$5957, #$59AC, - #$6295, #$900F, #$9B2A, #$615D, #$7279, #$95D6, #$5761, #$5A46, - #$5DF4, #$628A, #$64AD, #$64FA, #$6777, #$6CE2, #$6D3E, #$722C, - #$7436, #$7834, #$7F77, #$82AD, #$8DDB, #$9817, #$5224, #$5742, - #$677F, #$7248, #$74E3, #$8CA9, #$8FA6, #$9211, - #$962A, #$516B, #$53ED, #$634C, #$4F69, #$5504, #$6096, #$6557, - #$6C9B, #$6D7F, #$724C, #$72FD, #$7A17, #$8987, #$8C9D, #$5F6D, - #$6F8E, #$70F9, #$81A8, #$610E, #$4FBF, #$504F, #$6241, #$7247, - #$7BC7, #$7DE8, #$7FE9, #$904D, #$97AD, #$9A19, #$8CB6, #$576A, - #$5E73, #$67B0, #$840D, #$8A55, #$5420, #$5B16, #$5E63, #$5EE2, - #$5F0A, #$6583, #$80BA, #$853D, #$9589, #$965B, #$4F48, #$5305, - #$530D, #$530F, #$5486, #$54FA, #$5703, #$5E03, #$6016, #$629B, - #$62B1, #$6355, #$FA06, #$6CE1, #$6D66, #$75B1, #$7832, #$80DE, - #$812F, #$82DE, #$8461, #$84B2, #$888D, #$8912, #$900B, #$92EA, - #$98FD, #$9B91, #$5E45, #$66B4, #$66DD, #$7011, #$7206, #$FA07, - #$4FF5, #$527D, #$5F6A, #$6153, #$6753, #$6A19, #$6F02, #$74E2, - #$7968, #$8868, #$8C79, #$98C7, #$98C4, #$9A43, - #$54C1, #$7A1F, #$6953, #$8AF7, #$8C4A, #$98A8, #$99AE, #$5F7C, - #$62AB, #$75B2, #$76AE, #$88AB, #$907F, #$9642, #$5339, #$5F3C, - #$5FC5, #$6CCC, #$73CC, #$7562, #$758B, #$7B46, #$82FE, #$999D, - #$4E4F, #$903C, #$4E0B, #$4F55, #$53A6, #$590F, #$5EC8, #$6630, - #$6CB3, #$7455, #$8377, #$8766, #$8CC0, #$9050, #$971E, #$9C15, - #$58D1, #$5B78, #$8650, #$8B14, #$9DB4, #$5BD2, #$6068, #$608D, - #$65F1, #$6C57, #$6F22, #$6FA3, #$701A, #$7F55, #$7FF0, #$9591, - #$9592, #$9650, #$97D3, #$5272, #$8F44, #$51FD, #$542B, #$54B8, - #$5563, #$558A, #$6ABB, #$6DB5, #$7DD8, #$8266, #$929C, #$9677, - #$9E79, #$5408, #$54C8, #$76D2, #$86E4, #$95A4, #$95D4, #$965C, - #$4EA2, #$4F09, #$59EE, #$5AE6, #$5DF7, #$6052, #$6297, #$676D, - #$6841, #$6C86, #$6E2F, #$7F38, #$809B, #$822A, - #$FA08, #$FA09, #$9805, #$4EA5, #$5055, #$54B3, #$5793, #$595A, - #$5B69, #$5BB3, #$61C8, #$6977, #$6D77, #$7023, #$87F9, #$89E3, - #$8A72, #$8AE7, #$9082, #$99ED, #$9AB8, #$52BE, #$6838, #$5016, - #$5E78, #$674F, #$8347, #$884C, #$4EAB, #$5411, #$56AE, #$73E6, - #$9115, #$97FF, #$9909, #$9957, #$9999, #$5653, #$589F, #$865B, - #$8A31, #$61B2, #$6AF6, #$737B, #$8ED2, #$6B47, #$96AA, #$9A57, - #$5955, #$7200, #$8D6B, #$9769, #$4FD4, #$5CF4, #$5F26, #$61F8, - #$665B, #$6CEB, #$70AB, #$7384, #$73B9, #$73FE, #$7729, #$774D, - #$7D43, #$7D62, #$7E23, #$8237, #$8852, #$FA0A, #$8CE2, #$9249, - #$986F, #$5B51, #$7A74, #$8840, #$9801, #$5ACC, #$4FE0, #$5354, - #$593E, #$5CFD, #$633E, #$6D79, #$72F9, #$8105, #$8107, #$83A2, - #$92CF, #$9830, #$4EA8, #$5144, #$5211, #$578B, - #$5F62, #$6CC2, #$6ECE, #$7005, #$7050, #$70AF, #$7192, #$73E9, - #$7469, #$834A, #$87A2, #$8861, #$9008, #$90A2, #$93A3, #$99A8, - #$516E, #$5F57, #$60E0, #$6167, #$66B3, #$8559, #$8E4A, #$91AF, - #$978B, #$4E4E, #$4E92, #$547C, #$58D5, #$58FA, #$597D, #$5CB5, - #$5F27, #$6236, #$6248, #$660A, #$6667, #$6BEB, #$6D69, #$6DCF, - #$6E56, #$6EF8, #$6F94, #$6FE0, #$6FE9, #$705D, #$72D0, #$7425, - #$745A, #$74E0, #$7693, #$795C, #$7CCA, #$7E1E, #$80E1, #$82A6, - #$846B, #$84BF, #$864E, #$865F, #$8774, #$8B77, #$8C6A, #$93AC, - #$9800, #$9865, #$60D1, #$6216, #$9177, #$5A5A, #$660F, #$6DF7, - #$6E3E, #$743F, #$9B42, #$5FFD, #$60DA, #$7B0F, #$54C4, #$5F18, - #$6C5E, #$6CD3, #$6D2A, #$70D8, #$7D05, #$8679, #$8A0C, #$9D3B, - #$5316, #$548C, #$5B05, #$6A3A, #$706B, #$7575, - #$798D, #$79BE, #$82B1, #$83EF, #$8A71, #$8B41, #$8CA8, #$9774, - #$FA0B, #$64F4, #$652B, #$78BA, #$78BB, #$7A6B, #$4E38, #$559A, - #$5950, #$5BA6, #$5E7B, #$60A3, #$63DB, #$6B61, #$6665, #$6853, - #$6E19, #$7165, #$74B0, #$7D08, #$9084, #$9A69, #$9C25, #$6D3B, - #$6ED1, #$733E, #$8C41, #$95CA, #$51F0, #$5E4C, #$5FA8, #$604D, - #$60F6, #$6130, #$614C, #$6643, #$6644, #$69A5, #$6CC1, #$6E5F, - #$6EC9, #$6F62, #$714C, #$749C, #$7687, #$7BC1, #$7C27, #$8352, - #$8757, #$9051, #$968D, #$9EC3, #$532F, #$56DE, #$5EFB, #$5F8A, - #$6062, #$6094, #$61F7, #$6666, #$6703, #$6A9C, #$6DEE, #$6FAE, - #$7070, #$736A, #$7E6A, #$81BE, #$8334, #$86D4, #$8AA8, #$8CC4, - #$5283, #$7372, #$5B96, #$6A6B, #$9404, #$54EE, #$5686, #$5B5D, - #$6548, #$6585, #$66C9, #$689F, #$6D8D, #$6DC6, - #$723B, #$80B4, #$9175, #$9A4D, #$4FAF, #$5019, #$539A, #$540E, - #$543C, #$5589, #$55C5, #$5E3F, #$5F8C, #$673D, #$7166, #$73DD, - #$9005, #$52DB, #$52F3, #$5864, #$58CE, #$7104, #$718F, #$71FB, - #$85B0, #$8A13, #$6688, #$85A8, #$55A7, #$6684, #$714A, #$8431, - #$5349, #$5599, #$6BC1, #$5F59, #$5FBD, #$63EE, #$6689, #$7147, - #$8AF1, #$8F1D, #$9EBE, #$4F11, #$643A, #$70CB, #$7566, #$8667, - #$6064, #$8B4E, #$9DF8, #$5147, #$51F6, #$5308, #$6D36, #$80F8, - #$9ED1, #$6615, #$6B23, #$7098, #$75D5, #$5403, #$5C79, #$7D07, - #$8A16, #$6B20, #$6B3D, #$6B46, #$5438, #$6070, #$6D3D, #$7FD5, - #$8208, #$50D6, #$51DE, #$559C, #$566B, #$56CD, #$59EC, #$5B09, - #$5E0C, #$6199, #$6198, #$6231, #$665E, #$66E6, #$7199, #$71B9, - #$71BA, #$72A7, #$79A7, #$7A00, #$7FB2, #$8A70); - ISO8859_2Map: ThtAnsiCharISOMap = ( - #$00A0, #$0104, #$02D8, #$0141, #$00A4, #$013D, #$015A, #$00A7, - #$00A8, #$0160, #$015E, #$0164, #$0179, #$00AD, #$017D, #$017B, - #$00B0, #$0105, #$02DB, #$0142, #$00B4, #$013E, #$015B, #$02C7, - #$00B8, #$0161, #$015F, #$0165, #$017A, #$02DD, #$017E, #$017C, - #$0154, #$00C1, #$00C2, #$0102, #$00C4, #$0139, #$0106, #$00C7, - #$010C, #$00C9, #$0118, #$00CB, #$011A, #$00CD, #$00CE, #$010E, - #$0110, #$0143, #$0147, #$00D3, #$00D4, #$0150, #$00D6, #$00D7, - #$0158, #$016E, #$00DA, #$0170, #$00DC, #$00DD, #$0162, #$00DF, - #$0155, #$00E1, #$00E2, #$0103, #$00E4, #$013A, #$0107, #$00E7, - #$010D, #$00E9, #$0119, #$00EB, #$011B, #$00ED, #$00EE, #$010F, - #$0111, #$0144, #$0148, #$00F3, #$00F4, #$0151, #$00F6, #$00F7, - #$0159, #$016F, #$00FA, #$0171, #$00FC, #$00FD, #$0163, #$02D9); - ISO8859_3Map: ThtAnsiCharISOMap = ( - #$00A0, #$0126, #$02D8, #$00A3, #$00A4, #$FFFF, #$0124, #$00A7, - #$00A8, #$0130, #$015E, #$011E, #$0134, #$00AD, #$FFFF, #$017B, - #$00B0, #$0127, #$00B2, #$00B3, #$00B4, #$00B5, #$0125, #$00B7, - #$00B8, #$0131, #$015F, #$011F, #$0135, #$00BD, #$FFFF, #$017C, - #$00C0, #$00C1, #$00C2, #$FFFF, #$00C4, #$010A, #$0108, #$00C7, - #$00C8, #$00C9, #$00CA, #$00CB, #$00CC, #$00CD, #$00CE, #$00CF, - #$FFFF, #$00D1, #$00D2, #$00D3, #$00D4, #$0120, #$00D6, #$00D7, - #$011C, #$00D9, #$00DA, #$00DB, #$00DC, #$016C, #$015C, #$00DF, - #$00E0, #$00E1, #$00E2, #$FFFF, #$00E4, #$010B, #$0109, #$00E7, - #$00E8, #$00E9, #$00EA, #$00EB, #$00EC, #$00ED, #$00EE, #$00EF, - #$FFFF, #$00F1, #$00F2, #$00F3, #$00F4, #$0121, #$00F6, #$00F7, - #$011D, #$00F9, #$00FA, #$00FB, #$00FC, #$016D, #$015D, #$02D9); - ISO8859_4Map: ThtAnsiCharISOMap = ( - #$00A0, #$0104, #$0138, #$0156, #$00A4, #$0128, #$013B, #$00A7, - #$00A8, #$0160, #$0112, #$0122, #$0166, #$00AD, #$017D, #$00AF, - #$00B0, #$0105, #$02DB, #$0157, #$00B4, #$0129, #$013C, #$02C7, - #$00B8, #$0161, #$0113, #$0123, #$0167, #$014A, #$017E, #$014B, - #$0100, #$00C1, #$00C2, #$00C3, #$00C4, #$00C5, #$00C6, #$012E, - #$010C, #$00C9, #$0118, #$00CB, #$0116, #$00CD, #$00CE, #$012A, - #$0110, #$0145, #$014C, #$0136, #$00D4, #$00D5, #$00D6, #$00D7, - #$00D8, #$0172, #$00DA, #$00DB, #$00DC, #$0168, #$016A, #$00DF, - #$0101, #$00E1, #$00E2, #$00E3, #$00E4, #$00E5, #$00E6, #$012F, - #$010D, #$00E9, #$0119, #$00EB, #$0117, #$00ED, #$00EE, #$012B, - #$0111, #$0146, #$014D, #$0137, #$00F4, #$00F5, #$00F6, #$00F7, - #$00F8, #$0173, #$00FA, #$00FB, #$00FC, #$0169, #$016B, #$02D9); - ISO8859_10Map: ThtAnsiCharISOMap = ( - #$00A0, #$0104, #$0112, #$0122, #$012A, #$0128, #$0136, #$00A7, - #$013B, #$0110, #$0160, #$0166, #$017D, #$00AD, #$016A, #$014A, - #$00B0, #$0105, #$0113, #$0123, #$012B, #$0129, #$0137, #$00B7, - #$013C, #$0111, #$0161, #$0167, #$017E, #$2014, #$016B, #$014B, - #$0100, #$00C1, #$00C2, #$00C3, #$00C4, #$00C5, #$00C6, #$012E, - #$010C, #$00C9, #$0118, #$00CB, #$0116, #$00CD, #$00CE, #$00CF, - #$00D0, #$0145, #$014C, #$00D3, #$00D4, #$00D5, #$00D6, #$0168, - #$00D8, #$0172, #$00DA, #$00DB, #$00DC, #$00DD, #$00DE, #$00DF, - #$0101, #$00E1, #$00E2, #$00E3, #$00E4, #$00E5, #$00E6, #$012F, - #$010D, #$00E9, #$0119, #$00EB, #$0117, #$00ED, #$00EE, #$00EF, - #$00F0, #$0146, #$014D, #$00F3, #$00F4, #$00F5, #$00F6, #$0169, - #$00F8, #$0173, #$00FA, #$00FB, #$00FC, #$00FD, #$00FE, #$0138); - ISO8859_13Map: ThtAnsiCharISOMap = ( - #$00A0, #$201D, #$00A2, #$00A3, #$00A4, #$201E, #$00A6, #$00A7, - #$00D8, #$00A9, #$0156, #$00AB, #$00AC, #$00AD, #$00AE, #$00C6, - #$00B0, #$00B1, #$00B2, #$00B3, #$201C, #$00B5, #$00B6, #$00B7, - #$00F8, #$00B9, #$0157, #$00BB, #$00BC, #$00BD, #$00BE, #$00E6, - #$0104, #$012E, #$0100, #$0106, #$00C4, #$00C5, #$0118, #$0112, - #$010C, #$00C9, #$0179, #$0116, #$0122, #$0136, #$012A, #$013B, - #$0160, #$0143, #$0145, #$00D3, #$014C, #$00D5, #$00D6, #$00D7, - #$0172, #$0141, #$015A, #$016A, #$00DC, #$017B, #$017D, #$00DF, - #$0105, #$012F, #$0101, #$0107, #$00E4, #$00E5, #$0119, #$0113, - #$010D, #$00E9, #$017A, #$0117, #$0123, #$0137, #$012B, #$013C, - #$0161, #$0144, #$0146, #$00F3, #$014D, #$00F5, #$00F6, #$00F7, - #$0173, #$0142, #$015B, #$016B, #$00FC, #$017B, #$017E, #$2019); - ISO8859_14Map: ThtAnsiCharISOMap = ( - #$00A0, #$1E02, #$1E03, #$00A3, #$010A, #$010B, #$1E0A, #$00A7, - #$1E80, #$00A9, #$1E82, #$1E0B, #$1EF2, #$00AD, #$00AE, #$0178, - #$1E1E, #$1E1F, #$0120, #$0121, #$1E40, #$1E41, #$00B6, #$1E56, - #$1E81, #$1E57, #$1E83, #$1E60, #$1EF3, #$1E84, #$1E85, #$1E61, - #$00C0, #$00C1, #$00C2, #$00C3, #$00C4, #$00C5, #$00C6, #$00C7, - #$00C8, #$00C9, #$00CA, #$00CB, #$00CC, #$00CD, #$00CE, #$00CF, - #$0174, #$00D1, #$00D2, #$00D3, #$00D4, #$00D5, #$00D6, #$1E6A, - #$00D8, #$00D9, #$00DA, #$00DB, #$00DC, #$00DD, #$0176, #$00DF, - #$00E0, #$00E1, #$00E2, #$00E3, #$00E4, #$00E5, #$00E6, #$00E7, - #$00E8, #$00E9, #$00EA, #$00EB, #$00EC, #$00ED, #$00EE, #$00EF, - #$0175, #$00F1, #$00F2, #$00F3, #$00F4, #$00F5, #$00F6, #$1E6B, - #$00F8, #$00F9, #$00FA, #$00FB, #$00FC, #$00FD, #$0177, #$00FF); - ISO8859_16Map: ThtAnsiCharISOMap = ( - #$00A0, #$0104, #$0105, #$0141, #$20AC, #$201E, #$0160, #$00A7, - #$0161, #$00A9, #$0218, #$00AB, #$0179, #$00AD, #$017A, #$017B, - #$00B0, #$00B1, #$010C, #$0142, #$017D, #$201D, #$00B6, #$00B7, - #$017E, #$010D, #$0219, #$00BB, #$0152, #$0153, #$0178, #$017C, - #$00C0, #$00C1, #$00C2, #$0102, #$00C4, #$0106, #$00C6, #$00C7, - #$00C8, #$00C9, #$00CA, #$00CB, #$00CC, #$00CD, #$00CE, #$00CF, - #$0110, #$0143, #$00D2, #$00D3, #$00D4, #$0150, #$00D6, #$015A, - #$0170, #$00D9, #$00DA, #$00DB, #$00DC, #$0118, #$021A, #$00DF, - #$00E0, #$00E1, #$00E2, #$0103, #$00E4, #$0107, #$00E6, #$00E7, - #$00E8, #$00E9, #$00EA, #$00EB, #$00EC, #$00ED, #$00EE, #$00EF, - #$0111, #$0144, #$00F2, #$00F3, #$00F4, #$0151, #$00F6, #$015B, - #$0171, #$00F9, #$00FA, #$00FB, #$00FC, #$0119, #$021B, #$00FF); - BIG5_1Map: array[0..6120] of TBuffChar = ( - #$3000, #$FF0C, #$3001, #$3002, #$FF0E, #$2022, #$FF1B, #$FF1A, - #$FF1F, #$FF01, #$FE30, #$2026, #$2025, #$FE50, #$FF64, #$FE52, - #$00B7, #$FE54, #$FE55, #$FE56, #$FE57, #$FF5C, #$2013, #$FE31, - #$2014, #$FE33, #$FFFD, #$FE34, #$FE4F, #$FF08, #$FF09, #$FE35, - #$FE36, #$FF5B, #$FF5D, #$FE37, #$FE38, #$3014, #$3015, #$FE39, - #$FE3A, #$3010, #$3011, #$FE3B, #$FE3C, #$300A, #$300B, #$FE3D, - #$FE3E, #$3008, #$3009, #$FE3F, #$FE40, #$300C, #$300D, #$FE41, - #$FE42, #$300E, #$300F, #$FE43, #$FE44, #$FE59, #$FE5A, #$FE5B, - #$FE5C, #$FE5D, #$FE5E, #$2018, #$2019, #$201C, #$201D, #$301D, - #$301E, #$2035, #$2032, #$FF03, #$FF06, #$FF0A, #$203B, #$00A7, - #$3003, #$25CB, #$25CF, #$25B3, #$25B2, #$25CE, #$2606, #$2605, - #$25C7, #$25C6, #$25A1, #$25A0, #$25BD, #$25BC, #$32A3, #$2105, - #$203E, #$FFFD, #$FF3F, #$FFFD, #$FE49, #$FE4A, #$FE4D, #$FE4E, - #$FE4B, #$FE4C, #$FE5F, #$FE60, #$FE61, #$FF0B, #$FF0D, #$00D7, - #$00F7, #$00B1, #$221A, #$FF1C, #$FF1E, #$FF1D, #$2266, #$2267, - #$2260, #$221E, #$2252, #$2261, #$FE62, #$FE63, #$FE64, #$FE65, - #$FE66, #$223C, #$2229, #$222A, #$22A5, #$2220, #$221F, #$22BF, - #$33D2, #$33D1, #$222B, #$222E, #$2235, #$2234, #$2640, #$2642, - #$2641, #$2609, #$2191, #$2193, #$2190, #$2192, #$2196, #$2197, - #$2199, #$2198, #$2225, #$2223, #$FFFD, - #$FFFD, #$FF0F, #$FF3C, #$FF04, #$00A5, #$3012, #$00A2, #$00A3, - #$FF05, #$FF20, #$2103, #$2109, #$FE69, #$FE6A, #$FE6B, #$33D5, - #$339C, #$339D, #$339E, #$33CE, #$33A1, #$338E, #$338F, #$33C4, - #$00B0, #$5159, #$515B, #$515E, #$515D, #$5161, #$5163, #$55E7, - #$74E9, #$7CCE, #$2581, #$2582, #$2583, #$2584, #$2585, #$2586, - #$2587, #$2588, #$258F, #$258E, #$258D, #$258C, #$258B, #$258A, - #$2589, #$253C, #$2534, #$252C, #$2524, #$251C, #$2594, #$2500, - #$2502, #$2595, #$250C, #$2510, #$2514, #$2518, #$256D, #$256E, - #$2570, #$256F, #$2550, #$255E, #$256A, #$2561, #$25E2, #$25E3, - #$25E5, #$25E4, #$2571, #$2572, #$2573, #$FF10, #$FF11, #$FF12, - #$FF13, #$FF14, #$FF15, #$FF16, #$FF17, #$FF18, #$FF19, #$2160, - #$2161, #$2162, #$2163, #$2164, #$2165, #$2166, #$2167, #$2168, - #$2169, #$3021, #$3022, #$3023, #$3024, #$3025, #$3026, #$3027, - #$3028, #$3029, #$FFFD, #$5344, #$FFFD, #$FF21, #$FF22, #$FF23, - #$FF24, #$FF25, #$FF26, #$FF27, #$FF28, #$FF29, #$FF2A, #$FF2B, - #$FF2C, #$FF2D, #$FF2E, #$FF2F, #$FF30, #$FF31, #$FF32, #$FF33, - #$FF34, #$FF35, #$FF36, #$FF37, #$FF38, #$FF39, #$FF3A, #$FF41, - #$FF42, #$FF43, #$FF44, #$FF45, #$FF46, #$FF47, #$FF48, #$FF49, - #$FF4A, #$FF4B, #$FF4C, #$FF4D, #$FF4E, #$FF4F, #$FF50, #$FF51, - #$FF52, #$FF53, #$FF54, #$FF55, #$FF56, - #$FF57, #$FF58, #$FF59, #$FF5A, #$0391, #$0392, #$0393, #$0394, - #$0395, #$0396, #$0397, #$0398, #$0399, #$039A, #$039B, #$039C, - #$039D, #$039E, #$039F, #$03A0, #$03A1, #$03A3, #$03A4, #$03A5, - #$03A6, #$03A7, #$03A8, #$03A9, #$03B1, #$03B2, #$03B3, #$03B4, - #$03B5, #$03B6, #$03B7, #$03B8, #$03B9, #$03BA, #$03BB, #$03BC, - #$03BD, #$03BE, #$03BF, #$03C0, #$03C1, #$03C3, #$03C4, #$03C5, - #$03C6, #$03C7, #$03C8, #$03C9, #$3105, #$3106, #$3107, #$3108, - #$3109, #$310A, #$310B, #$310C, #$310D, #$310E, #$310F, #$3110, - #$3111, #$3112, #$3113, #$3114, #$3115, #$3116, #$3117, #$3118, - #$3119, #$311A, #$311B, #$311C, #$311D, #$311E, #$311F, #$3120, - #$3121, #$3122, #$3123, #$3124, #$3125, #$3126, #$3127, #$3128, - #$3129, #$02D9, #$02C9, #$02CA, #$02C7, #$02CB, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$4E00, #$4E59, #$4E01, #$4E03, #$4E43, #$4E5D, #$4E86, #$4E8C, - #$4EBA, #$513F, #$5165, #$516B, #$51E0, #$5200, #$5201, #$529B, - #$5315, #$5341, #$535C, #$53C8, #$4E09, #$4E0B, #$4E08, #$4E0A, - #$4E2B, #$4E38, #$51E1, #$4E45, #$4E48, #$4E5F, #$4E5E, #$4E8E, - #$4EA1, #$5140, #$5203, #$52FA, #$5343, #$53C9, #$53E3, #$571F, - #$58EB, #$5915, #$5927, #$5973, #$5B50, #$5B51, #$5B53, #$5BF8, - #$5C0F, #$5C22, #$5C38, #$5C71, #$5DDD, #$5DE5, #$5DF1, #$5DF2, - #$5DF3, #$5DFE, #$5E72, #$5EFE, #$5F0B, #$5F13, #$624D, #$4E11, - #$4E10, #$4E0D, #$4E2D, #$4E30, #$4E39, #$4E4B, #$5C39, #$4E88, - #$4E91, #$4E95, #$4E92, #$4E94, #$4EA2, #$4EC1, #$4EC0, #$4EC3, - #$4EC6, #$4EC7, #$4ECD, #$4ECA, #$4ECB, #$4EC4, #$5143, #$5141, - #$5167, #$516D, #$516E, #$516C, #$5197, #$51F6, #$5206, #$5207, - #$5208, #$52FB, #$52FE, #$52FF, #$5316, #$5339, #$5348, #$5347, - #$5345, #$535E, #$5384, #$53CB, #$53CA, #$53CD, #$58EC, #$5929, - #$592B, #$592A, #$592D, #$5B54, #$5C11, #$5C24, #$5C3A, #$5C6F, - #$5DF4, #$5E7B, #$5EFF, #$5F14, #$5F15, #$5FC3, #$6208, #$6236, - #$624B, #$624E, #$652F, #$6587, #$6597, #$65A4, #$65B9, #$65E5, - #$66F0, #$6708, #$6728, #$6B20, #$6B62, #$6B79, #$6BCB, #$6BD4, - #$6BDB, #$6C0F, #$6C34, #$706B, #$722A, #$7236, #$723B, #$7247, - #$7259, #$725B, #$72AC, #$738B, #$4E19, - #$4E16, #$4E15, #$4E14, #$4E18, #$4E3B, #$4E4D, #$4E4F, #$4E4E, - #$4EE5, #$4ED8, #$4ED4, #$4ED5, #$4ED6, #$4ED7, #$4EE3, #$4EE4, - #$4ED9, #$4EDE, #$5145, #$5144, #$5189, #$518A, #$51AC, #$51F9, - #$51FA, #$51F8, #$520A, #$52A0, #$529F, #$5305, #$5306, #$5317, - #$531D, #$4EDF, #$534A, #$5349, #$5361, #$5360, #$536F, #$536E, - #$53BB, #$53EF, #$53E4, #$53F3, #$53EC, #$53EE, #$53E9, #$53E8, - #$53FC, #$53F8, #$53F5, #$53EB, #$53E6, #$53EA, #$53F2, #$53F1, - #$53F0, #$53E5, #$53ED, #$53FB, #$56DB, #$56DA, #$5916, #$592E, - #$5931, #$5974, #$5976, #$5B55, #$5B83, #$5C3C, #$5DE8, #$5DE7, - #$5DE6, #$5E02, #$5E03, #$5E73, #$5E7C, #$5F01, #$5F18, #$5F17, - #$5FC5, #$620A, #$6253, #$6254, #$6252, #$6251, #$65A5, #$65E6, - #$672E, #$672C, #$672A, #$672B, #$672D, #$6B63, #$6BCD, #$6C11, - #$6C10, #$6C38, #$6C41, #$6C40, #$6C3E, #$72AF, #$7384, #$7389, - #$74DC, #$74E6, #$7518, #$751F, #$7528, #$7529, #$7530, #$7531, - #$7532, #$7533, #$758B, #$767D, #$76AE, #$76BF, #$76EE, #$77DB, - #$77E2, #$77F3, #$793A, #$79BE, #$7A74, #$7ACB, #$4E1E, #$4E1F, - #$4E52, #$4E53, #$4E69, #$4E99, #$4EA4, #$4EA6, #$4EA5, #$4EFF, - #$4F09, #$4F19, #$4F0A, #$4F15, #$4F0D, #$4F10, #$4F11, #$4F0F, - #$4EF2, #$4EF6, #$4EFB, #$4EF0, #$4EF3, #$4EFD, #$4F01, #$4F0B, - #$5149, #$5147, #$5146, #$5148, #$5168, - #$5171, #$518D, #$51B0, #$5217, #$5211, #$5212, #$520E, #$5216, - #$52A3, #$5308, #$5321, #$5320, #$5370, #$5371, #$5409, #$540F, - #$540C, #$540A, #$5410, #$5401, #$540B, #$5404, #$5411, #$540D, - #$5408, #$5403, #$540E, #$5406, #$5412, #$56E0, #$56DE, #$56DD, - #$5733, #$5730, #$5728, #$572D, #$572C, #$572F, #$5729, #$5919, - #$591A, #$5937, #$5938, #$5984, #$5978, #$5983, #$597D, #$5979, - #$5982, #$5981, #$5B57, #$5B58, #$5B87, #$5B88, #$5B85, #$5B89, - #$5BFA, #$5C16, #$5C79, #$5DDE, #$5E06, #$5E76, #$5E74, #$5F0F, - #$5F1B, #$5FD9, #$5FD6, #$620E, #$620C, #$620D, #$6210, #$6263, - #$625B, #$6258, #$6536, #$65E9, #$65E8, #$65EC, #$65ED, #$66F2, - #$66F3, #$6709, #$673D, #$6734, #$6731, #$6735, #$6B21, #$6B64, - #$6B7B, #$6C16, #$6C5D, #$6C57, #$6C59, #$6C5F, #$6C60, #$6C50, - #$6C55, #$6C61, #$6C5B, #$6C4D, #$6C4E, #$7070, #$725F, #$725D, - #$767E, #$7AF9, #$7C73, #$7CF8, #$7F36, #$7F8A, #$7FBD, #$8001, - #$8003, #$800C, #$8012, #$8033, #$807F, #$8089, #$808B, #$808C, - #$81E3, #$81EA, #$81F3, #$81FC, #$820C, #$821B, #$821F, #$826E, - #$8272, #$827E, #$866B, #$8840, #$884C, #$8863, #$897F, #$9621, - #$4E32, #$4EA8, #$4F4D, #$4F4F, #$4F47, #$4F57, #$4F5E, #$4F34, - #$4F5B, #$4F55, #$4F30, #$4F50, #$4F51, #$4F3D, #$4F3A, #$4F38, - #$4F43, #$4F54, #$4F3C, #$4F46, #$4F63, - #$4F5C, #$4F60, #$4F2F, #$4F4E, #$4F36, #$4F59, #$4F5D, #$4F48, - #$4F5A, #$514C, #$514B, #$514D, #$5175, #$51B6, #$51B7, #$5225, - #$5224, #$5229, #$522A, #$5228, #$52AB, #$52A9, #$52AA, #$52AC, - #$5323, #$5373, #$5375, #$541D, #$542D, #$541E, #$543E, #$5426, - #$544E, #$5427, #$5446, #$5443, #$5433, #$5448, #$5442, #$541B, - #$5429, #$544A, #$5439, #$543B, #$5438, #$542E, #$5435, #$5436, - #$5420, #$543C, #$5440, #$5431, #$542B, #$541F, #$542C, #$56EA, - #$56F0, #$56E4, #$56EB, #$574A, #$5751, #$5740, #$574D, #$5747, - #$574E, #$573E, #$5750, #$574F, #$573B, #$58EF, #$593E, #$599D, - #$5992, #$59A8, #$599E, #$59A3, #$5999, #$5996, #$598D, #$59A4, - #$5993, #$598A, #$59A5, #$5B5D, #$5B5C, #$5B5A, #$5B5B, #$5B8C, - #$5B8B, #$5B8F, #$5C2C, #$5C40, #$5C41, #$5C3F, #$5C3E, #$5C90, - #$5C91, #$5C94, #$5C8C, #$5DEB, #$5E0C, #$5E8F, #$5E87, #$5E8A, - #$5EF7, #$5F04, #$5F1F, #$5F64, #$5F62, #$5F77, #$5F79, #$5FD8, - #$5FCC, #$5FD7, #$5FCD, #$5FF1, #$5FEB, #$5FF8, #$5FEA, #$6212, - #$6211, #$6284, #$6297, #$6296, #$6280, #$6276, #$6289, #$626D, - #$628A, #$627C, #$627E, #$6279, #$6273, #$6292, #$626F, #$6298, - #$626E, #$6295, #$6293, #$6291, #$6286, #$6539, #$653B, #$6538, - #$65F1, #$66F4, #$675F, #$674E, #$674F, #$6750, #$6751, #$675C, - #$6756, #$675E, #$6749, #$6746, #$6760, - #$6753, #$6757, #$6B65, #$6BCF, #$6C42, #$6C5E, #$6C99, #$6C81, - #$6C88, #$6C89, #$6C85, #$6C9B, #$6C6A, #$6C7A, #$6C90, #$6C70, - #$6C8C, #$6C68, #$6C96, #$6C92, #$6C7D, #$6C83, #$6C72, #$6C7E, - #$6C74, #$6C86, #$6C76, #$6C8D, #$6C94, #$6C98, #$6C82, #$7076, - #$707C, #$707D, #$7078, #$7262, #$7261, #$7260, #$72C4, #$72C2, - #$7396, #$752C, #$752B, #$7537, #$7538, #$7682, #$76EF, #$77E3, - #$79C1, #$79C0, #$79BF, #$7A76, #$7CFB, #$7F55, #$8096, #$8093, - #$809D, #$8098, #$809B, #$809A, #$80B2, #$826F, #$8292, #$828B, - #$828D, #$898B, #$89D2, #$8A00, #$8C37, #$8C46, #$8C55, #$8C9D, - #$8D64, #$8D70, #$8DB3, #$8EAB, #$8ECA, #$8F9B, #$8FB0, #$8FC2, - #$8FC6, #$8FC5, #$8FC4, #$5DE1, #$9091, #$90A2, #$90AA, #$90A6, - #$90A3, #$9149, #$91C6, #$91CC, #$9632, #$962E, #$9631, #$962A, - #$962C, #$4E26, #$4E56, #$4E73, #$4E8B, #$4E9B, #$4E9E, #$4EAB, - #$4EAC, #$4F6F, #$4F9D, #$4F8D, #$4F73, #$4F7F, #$4F6C, #$4F9B, - #$4F8B, #$4F86, #$4F83, #$4F70, #$4F75, #$4F88, #$4F69, #$4F7B, - #$4F96, #$4F7E, #$4F8F, #$4F91, #$4F7A, #$5154, #$5152, #$5155, - #$5169, #$5177, #$5176, #$5178, #$51BD, #$51FD, #$523B, #$5238, - #$5237, #$523A, #$5230, #$522E, #$5236, #$5241, #$52BE, #$52BB, - #$5352, #$5354, #$5353, #$5351, #$5366, #$5377, #$5378, #$5379, - #$53D6, #$53D4, #$53D7, #$5473, #$5475, - #$5496, #$5478, #$5495, #$5480, #$547B, #$5477, #$5484, #$5492, - #$5486, #$547C, #$5490, #$5471, #$5476, #$548C, #$549A, #$5462, - #$5468, #$548B, #$547D, #$548E, #$56FA, #$5783, #$5777, #$576A, - #$5769, #$5761, #$5766, #$5764, #$577C, #$591C, #$5949, #$5947, - #$5948, #$5944, #$5954, #$59BE, #$59BB, #$59D4, #$59B9, #$59AE, - #$59D1, #$59C6, #$59D0, #$59CD, #$59CB, #$59D3, #$59CA, #$59AF, - #$59B3, #$59D2, #$59C5, #$5B5F, #$5B64, #$5B63, #$5B97, #$5B9A, - #$5B98, #$5B9C, #$5B99, #$5B9B, #$5C1A, #$5C48, #$5C45, #$5C46, - #$5CB7, #$5CA1, #$5CB8, #$5CA9, #$5CAB, #$5CB1, #$5CB3, #$5E18, - #$5E1A, #$5E16, #$5E15, #$5E1B, #$5E11, #$5E78, #$5E9A, #$5E97, - #$5E9C, #$5E95, #$5E96, #$5EF6, #$5F26, #$5F27, #$5F29, #$5F80, - #$5F81, #$5F7F, #$5F7C, #$5FDD, #$5FE0, #$5FFD, #$5FF5, #$5FFF, - #$600F, #$6014, #$602F, #$6035, #$6016, #$602A, #$6015, #$6021, - #$6027, #$6029, #$602B, #$601B, #$6216, #$6215, #$623F, #$623E, - #$6240, #$627F, #$62C9, #$62CC, #$62C4, #$62BF, #$62C2, #$62B9, - #$62D2, #$62DB, #$62AB, #$62D3, #$62D4, #$62CB, #$62C8, #$62A8, - #$62BD, #$62BC, #$62D0, #$62D9, #$62C7, #$62CD, #$62B5, #$62DA, - #$62B1, #$62D8, #$62D6, #$62D7, #$62C6, #$62AC, #$62CE, #$653E, - #$65A7, #$65BC, #$65FA, #$6614, #$6613, #$660C, #$6606, #$6602, - #$660E, #$6600, #$660F, #$6615, #$660A, - #$6607, #$670D, #$670B, #$676D, #$678B, #$6795, #$6771, #$679C, - #$6773, #$6777, #$6787, #$679D, #$6797, #$676F, #$6770, #$677F, - #$6789, #$677E, #$6790, #$6775, #$679A, #$6793, #$677C, #$676A, - #$6772, #$6B23, #$6B66, #$6B67, #$6B7F, #$6C13, #$6C1B, #$6CE3, - #$6CE8, #$6CF3, #$6CB1, #$6CCC, #$6CE5, #$6CB3, #$6CBD, #$6CBE, - #$6CBC, #$6CE2, #$6CAB, #$6CD5, #$6CD3, #$6CB8, #$6CC4, #$6CB9, - #$6CC1, #$6CAE, #$6CD7, #$6CC5, #$6CF1, #$6CBF, #$6CBB, #$6CE1, - #$6CDB, #$6CCA, #$6CAC, #$6CEF, #$6CDC, #$6CD6, #$6CE0, #$7095, - #$708E, #$7092, #$708A, #$7099, #$722C, #$722D, #$7238, #$7248, - #$7267, #$7269, #$72C0, #$72CE, #$72D9, #$72D7, #$72D0, #$73A9, - #$73A8, #$739F, #$73AB, #$73A5, #$753D, #$759D, #$7599, #$759A, - #$7684, #$76C2, #$76F2, #$76F4, #$77E5, #$77FD, #$793E, #$7940, - #$7941, #$79C9, #$79C8, #$7A7A, #$7A79, #$7AFA, #$7CFE, #$7F54, - #$7F8C, #$7F8B, #$8005, #$80BA, #$80A5, #$80A2, #$80B1, #$80A1, - #$80AB, #$80A9, #$80B4, #$80AA, #$80AF, #$81E5, #$81FE, #$820D, - #$82B3, #$829D, #$8299, #$82AD, #$82BD, #$829F, #$82B9, #$82B1, - #$82AC, #$82A5, #$82AF, #$82B8, #$82A3, #$82B0, #$82BE, #$82B7, - #$864E, #$8671, #$521D, #$8868, #$8ECB, #$8FCE, #$8FD4, #$8FD1, - #$90B5, #$90B8, #$90B1, #$90B6, #$91C7, #$91D1, #$9577, #$9580, - #$961C, #$9640, #$963F, #$963B, #$9644, - #$9642, #$96B9, #$96E8, #$9752, #$975E, #$4E9F, #$4EAD, #$4EAE, - #$4FE1, #$4FB5, #$4FAF, #$4FBF, #$4FE0, #$4FD1, #$4FCF, #$4FDD, - #$4FC3, #$4FB6, #$4FD8, #$4FDF, #$4FCA, #$4FD7, #$4FAE, #$4FD0, - #$4FC4, #$4FC2, #$4FDA, #$4FCE, #$4FDE, #$4FB7, #$5157, #$5192, - #$5191, #$51A0, #$524E, #$5243, #$524A, #$524D, #$524C, #$524B, - #$5247, #$52C7, #$52C9, #$52C3, #$52C1, #$530D, #$5357, #$537B, - #$539A, #$53DB, #$54AC, #$54C0, #$54A8, #$54CE, #$54C9, #$54B8, - #$54A6, #$54B3, #$54C7, #$54C2, #$54BD, #$54AA, #$54C1, #$54C4, - #$54C8, #$54AF, #$54AB, #$54B1, #$54BB, #$54A9, #$54A7, #$54BF, - #$56FF, #$5782, #$578B, #$57A0, #$57A3, #$57A2, #$57CE, #$57AE, - #$5793, #$5955, #$5951, #$594F, #$594E, #$5950, #$59DC, #$59D8, - #$59FF, #$59E3, #$59E8, #$5A03, #$59E5, #$59EA, #$59DA, #$59E6, - #$5A01, #$59FB, #$5B69, #$5BA3, #$5BA6, #$5BA4, #$5BA2, #$5BA5, - #$5C01, #$5C4E, #$5C4F, #$5C4D, #$5C4B, #$5CD9, #$5CD2, #$5DF7, - #$5E1D, #$5E25, #$5E1F, #$5E7D, #$5EA0, #$5EA6, #$5EFA, #$5F08, - #$5F2D, #$5F65, #$5F88, #$5F85, #$5F8A, #$5F8B, #$5F87, #$5F8C, - #$5F89, #$6012, #$601D, #$6020, #$6025, #$600E, #$6028, #$604D, - #$6070, #$6068, #$6062, #$6046, #$6043, #$606C, #$606B, #$606A, - #$6064, #$6241, #$62DC, #$6316, #$6309, #$62FC, #$62ED, #$6301, - #$62EE, #$62FD, #$6307, #$62F1, #$62F7, - #$62EF, #$62EC, #$62FE, #$62F4, #$6311, #$6302, #$653F, #$6545, - #$65AB, #$65BD, #$65E2, #$6625, #$662D, #$6620, #$6627, #$662F, - #$661F, #$6628, #$6631, #$6624, #$66F7, #$67FF, #$67D3, #$67F1, - #$67D4, #$67D0, #$67EC, #$67B6, #$67AF, #$67F5, #$67E9, #$67EF, - #$67C4, #$67D1, #$67B4, #$67DA, #$67E5, #$67B8, #$67CF, #$67DE, - #$67F3, #$67B0, #$67D9, #$67E2, #$67DD, #$67D2, #$6B6A, #$6B83, - #$6B86, #$6BB5, #$6BD2, #$6BD7, #$6C1F, #$6CC9, #$6D0B, #$6D32, - #$6D2A, #$6D41, #$6D25, #$6D0C, #$6D31, #$6D1E, #$6D17, #$6D3B, - #$6D3D, #$6D3E, #$6D36, #$6D1B, #$6CF5, #$6D39, #$6D27, #$6D38, - #$6D29, #$6D2E, #$6D35, #$6D0E, #$6D2B, #$70AB, #$70BA, #$70B3, - #$70AC, #$70AF, #$70AD, #$70B8, #$70AE, #$70A4, #$7230, #$7272, - #$726F, #$7274, #$72E9, #$72E0, #$72E1, #$73B7, #$73CA, #$73BB, - #$73B2, #$73CD, #$73C0, #$73B3, #$751A, #$752D, #$754F, #$754C, - #$754E, #$754B, #$75AB, #$75A4, #$75A5, #$75A2, #$75A3, #$7678, - #$7686, #$7687, #$7688, #$76C8, #$76C6, #$76C3, #$76C5, #$7701, - #$76F9, #$76F8, #$7709, #$770B, #$76FE, #$76FC, #$7707, #$77DC, - #$7802, #$7814, #$780C, #$780D, #$7946, #$7949, #$7948, #$7947, - #$79B9, #$79BA, #$79D1, #$79D2, #$79CB, #$7A7F, #$7A81, #$7AFF, - #$7AFD, #$7C7D, #$7D02, #$7D05, #$7D00, #$7D09, #$7D07, #$7D04, - #$7D06, #$7F38, #$7F8E, #$7FBF, #$8004, - #$8010, #$800D, #$8011, #$8036, #$80D6, #$80E5, #$80DA, #$80C3, - #$80C4, #$80CC, #$80E1, #$80DB, #$80CE, #$80DE, #$80E4, #$80DD, - #$81F4, #$8222, #$82E7, #$8303, #$8305, #$82E3, #$82DB, #$82E6, - #$8304, #$82E5, #$8302, #$8309, #$82D2, #$82D7, #$82F1, #$8301, - #$82DC, #$82D4, #$82D1, #$82DE, #$82D3, #$82DF, #$82EF, #$8306, - #$8650, #$8679, #$867B, #$867A, #$884D, #$886B, #$8981, #$89D4, - #$8A08, #$8A02, #$8A03, #$8C9E, #$8CA0, #$8D74, #$8D73, #$8DB4, - #$8ECD, #$8ECC, #$8FF0, #$8FE6, #$8FE2, #$8FEA, #$8FE5, #$8FED, - #$8FEB, #$8FE4, #$8FE8, #$90CA, #$90CE, #$90C1, #$90C3, #$914B, - #$914A, #$91CD, #$9582, #$9650, #$964B, #$964C, #$964D, #$9762, - #$9769, #$97CB, #$97ED, #$97F3, #$9801, #$98A8, #$98DB, #$98DF, - #$9996, #$9999, #$4E58, #$4EB3, #$500C, #$500D, #$5023, #$4FEF, - #$5026, #$5025, #$4FF8, #$5029, #$5016, #$5006, #$503C, #$501F, - #$501A, #$5012, #$5011, #$4FFA, #$5000, #$5014, #$5028, #$4FF1, - #$5021, #$500B, #$5019, #$5018, #$4FF3, #$4FEE, #$502D, #$502A, - #$4FFE, #$502B, #$5009, #$517C, #$51A4, #$51A5, #$51A2, #$51CD, - #$51CC, #$51C6, #$51CB, #$5256, #$525C, #$5254, #$525B, #$525D, - #$532A, #$537F, #$539F, #$539D, #$53DF, #$54E8, #$5510, #$5501, - #$5537, #$54FC, #$54E5, #$54F2, #$5506, #$54FA, #$5514, #$54E9, - #$54ED, #$54E1, #$5509, #$54EE, #$54EA, - #$54E6, #$5527, #$5507, #$54FD, #$550F, #$5703, #$5704, #$57C2, - #$57D4, #$57CB, #$57C3, #$5809, #$590F, #$5957, #$5958, #$595A, - #$5A11, #$5A18, #$5A1C, #$5A1F, #$5A1B, #$5A13, #$59EC, #$5A20, - #$5A23, #$5A29, #$5A25, #$5A0C, #$5A09, #$5B6B, #$5C58, #$5BB0, - #$5BB3, #$5BB6, #$5BB4, #$5BAE, #$5BB5, #$5BB9, #$5BB8, #$5C04, - #$5C51, #$5C55, #$5C50, #$5CED, #$5CFD, #$5CFB, #$5CEA, #$5CE8, - #$5CF0, #$5CF6, #$5D01, #$5CF4, #$5DEE, #$5E2D, #$5E2B, #$5EAB, - #$5EAD, #$5EA7, #$5F31, #$5F92, #$5F91, #$5F90, #$6059, #$6063, - #$6065, #$6050, #$6055, #$606D, #$6069, #$606F, #$6084, #$609F, - #$609A, #$608D, #$6094, #$608C, #$6085, #$6096, #$6247, #$62F3, - #$6308, #$62FF, #$634E, #$633E, #$632F, #$6355, #$6342, #$6346, - #$634F, #$6349, #$633A, #$6350, #$633D, #$632A, #$632B, #$6328, - #$634D, #$634C, #$6548, #$6549, #$6599, #$65C1, #$65C5, #$6642, - #$6649, #$664F, #$6643, #$6652, #$664C, #$6645, #$6641, #$66F8, - #$6714, #$6715, #$6717, #$6821, #$6838, #$6848, #$6846, #$6853, - #$6839, #$6842, #$6854, #$6829, #$68B3, #$6817, #$684C, #$6851, - #$683D, #$67F4, #$6850, #$6840, #$683C, #$6843, #$682A, #$6845, - #$6813, #$6818, #$6841, #$6B8A, #$6B89, #$6BB7, #$6C23, #$6C27, - #$6C28, #$6C26, #$6C24, #$6CF0, #$6D6A, #$6D95, #$6D88, #$6D87, - #$6D66, #$6D78, #$6D77, #$6D59, #$6D93, - #$6D6C, #$6D89, #$6D6E, #$6D5A, #$6D74, #$6D69, #$6D8C, #$6D8A, - #$6D79, #$6D85, #$6D65, #$6D94, #$70CA, #$70D8, #$70E4, #$70D9, - #$70C8, #$70CF, #$7239, #$7279, #$72FC, #$72F9, #$72FD, #$72F8, - #$72F7, #$7386, #$73ED, #$7409, #$73EE, #$73E0, #$73EA, #$73DE, - #$7554, #$755D, #$755C, #$755A, #$7559, #$75BE, #$75C5, #$75C7, - #$75B2, #$75B3, #$75BD, #$75BC, #$75B9, #$75C2, #$75B8, #$768B, - #$76B0, #$76CA, #$76CD, #$76CE, #$7729, #$771F, #$7720, #$7728, - #$77E9, #$7830, #$7827, #$7838, #$781D, #$7834, #$7837, #$7825, - #$782D, #$7820, #$781F, #$7832, #$7955, #$7950, #$7960, #$795F, - #$7956, #$795E, #$795D, #$7957, #$795A, #$79E4, #$79E3, #$79E7, - #$79DF, #$79E6, #$79E9, #$79D8, #$7A84, #$7A88, #$7AD9, #$7B06, - #$7B11, #$7C89, #$7D21, #$7D17, #$7D0B, #$7D0A, #$7D20, #$7D22, - #$7D14, #$7D10, #$7D15, #$7D1A, #$7D1C, #$7D0D, #$7D19, #$7D1B, - #$7F3A, #$7F5F, #$7F94, #$7FC5, #$7FC1, #$8006, #$8018, #$8015, - #$8019, #$8017, #$803D, #$803F, #$80F1, #$8102, #$80F0, #$8105, - #$80ED, #$80F4, #$8106, #$80F8, #$80F3, #$8108, #$80FD, #$810A, - #$80FC, #$80EF, #$81ED, #$81EC, #$8200, #$8210, #$822A, #$822B, - #$8228, #$822C, #$82BB, #$832B, #$8352, #$8354, #$834A, #$8338, - #$8350, #$8349, #$8335, #$8334, #$834F, #$8332, #$8339, #$8336, - #$8317, #$8340, #$8331, #$8328, #$8343, - #$8654, #$868A, #$86AA, #$8693, #$86A4, #$86A9, #$868C, #$86A3, - #$869C, #$8870, #$8877, #$8881, #$8882, #$887D, #$8879, #$8A18, - #$8A10, #$8A0E, #$8A0C, #$8A15, #$8A0A, #$8A17, #$8A13, #$8A16, - #$8A0F, #$8A11, #$8C48, #$8C7A, #$8C79, #$8CA1, #$8CA2, #$8D77, - #$8EAC, #$8ED2, #$8ED4, #$8ECF, #$8FB1, #$9001, #$9006, #$8FF7, - #$9000, #$8FFA, #$8FF4, #$9003, #$8FFD, #$9005, #$8FF8, #$9095, - #$90E1, #$90DD, #$90E2, #$9152, #$914D, #$914C, #$91D8, #$91DD, - #$91D7, #$91DC, #$91D9, #$9583, #$9662, #$9663, #$9661, #$965B, - #$965D, #$9664, #$9658, #$965E, #$96BB, #$98E2, #$99AC, #$9AA8, - #$9AD8, #$9B25, #$9B32, #$9B3C, #$4E7E, #$507A, #$507D, #$505C, - #$5047, #$5043, #$504C, #$505A, #$5049, #$5065, #$5076, #$504E, - #$5055, #$5075, #$5074, #$5077, #$504F, #$500F, #$506F, #$506D, - #$515C, #$5195, #$51F0, #$526A, #$526F, #$52D2, #$52D9, #$52D8, - #$52D5, #$5310, #$530F, #$5319, #$533F, #$5340, #$533E, #$53C3, - #$66FC, #$5546, #$556A, #$5566, #$5544, #$555E, #$5561, #$5543, - #$554A, #$5531, #$5556, #$554F, #$5555, #$552F, #$5564, #$5538, - #$552E, #$555C, #$552C, #$5563, #$5533, #$5541, #$5557, #$5708, - #$570B, #$5709, #$57DF, #$5805, #$580A, #$5806, #$57E0, #$57E4, - #$57FA, #$5802, #$5835, #$57F7, #$57F9, #$5920, #$5962, #$5A36, - #$5A41, #$5A49, #$5A66, #$5A6A, #$5A40, - #$5A3C, #$5A62, #$5A5A, #$5A46, #$5A4A, #$5B70, #$5BC7, #$5BC5, - #$5BC4, #$5BC2, #$5BBF, #$5BC6, #$5C09, #$5C08, #$5C07, #$5C60, - #$5C5C, #$5C5D, #$5D07, #$5D06, #$5D0E, #$5D1B, #$5D16, #$5D22, - #$5D11, #$5D29, #$5D14, #$5D19, #$5D24, #$5D27, #$5D17, #$5DE2, - #$5E38, #$5E36, #$5E33, #$5E37, #$5EB7, #$5EB8, #$5EB6, #$5EB5, - #$5EBE, #$5F35, #$5F37, #$5F57, #$5F6C, #$5F69, #$5F6B, #$5F97, - #$5F99, #$5F9E, #$5F98, #$5FA1, #$5FA0, #$5F9C, #$607F, #$60A3, - #$6089, #$60A0, #$60A8, #$60CB, #$60B4, #$60E6, #$60BD, #$60C5, - #$60BB, #$60B5, #$60DC, #$60BC, #$60D8, #$60D5, #$60C6, #$60DF, - #$60B8, #$60DA, #$60C7, #$621A, #$621B, #$6248, #$63A0, #$63A7, - #$6372, #$6396, #$63A2, #$63A5, #$6377, #$6367, #$6398, #$63AA, - #$6371, #$63A9, #$6389, #$6383, #$639B, #$636B, #$63A8, #$6384, - #$6388, #$6399, #$63A1, #$63AC, #$6392, #$638F, #$6380, #$637B, - #$6369, #$6368, #$637A, #$655D, #$6556, #$6551, #$6559, #$6557, - #$555F, #$654F, #$6558, #$6555, #$6554, #$659C, #$659B, #$65AC, - #$65CF, #$65CB, #$65CC, #$65CE, #$665D, #$665A, #$6664, #$6668, - #$6666, #$665E, #$66F9, #$52D7, #$671B, #$6881, #$68AF, #$68A2, - #$6893, #$68B5, #$687F, #$6876, #$68B1, #$68A7, #$6897, #$68B0, - #$6883, #$68C4, #$68AD, #$6886, #$6885, #$6894, #$689D, #$68A8, - #$689F, #$68A1, #$6882, #$6B32, #$6BBA, - #$6BEB, #$6BEC, #$6C2B, #$6D8E, #$6DBC, #$6DF3, #$6DD9, #$6DB2, - #$6DE1, #$6DCC, #$6DE4, #$6DFB, #$6DFA, #$6E05, #$6DC7, #$6DCB, - #$6DAF, #$6DD1, #$6DAE, #$6DDE, #$6DF9, #$6DB8, #$6DF7, #$6DF5, - #$6DC5, #$6DD2, #$6E1A, #$6DB5, #$6DDA, #$6DEB, #$6DD8, #$6DEA, - #$6DF1, #$6DEE, #$6DE8, #$6DC6, #$6DC4, #$6DAA, #$6DEC, #$6DBF, - #$6DE6, #$70F9, #$7109, #$710A, #$70FD, #$70EF, #$723D, #$727D, - #$7281, #$731C, #$731B, #$7316, #$7313, #$7319, #$7387, #$7405, - #$740A, #$7403, #$7406, #$73FE, #$740D, #$74E0, #$74F6, #$74F7, - #$751C, #$7522, #$7565, #$7566, #$7562, #$7570, #$758F, #$75D4, - #$75D5, #$75B5, #$75CA, #$75CD, #$768E, #$76D4, #$76D2, #$76DB, - #$7737, #$773E, #$773C, #$7736, #$7738, #$773A, #$786B, #$7843, - #$784E, #$7965, #$7968, #$796D, #$79FB, #$7A92, #$7A95, #$7B20, - #$7B28, #$7B1B, #$7B2C, #$7B26, #$7B19, #$7B1E, #$7B2E, #$7C92, - #$7C97, #$7C95, #$7D46, #$7D43, #$7D71, #$7D2E, #$7D39, #$7D3C, - #$7D40, #$7D30, #$7D33, #$7D44, #$7D2F, #$7D42, #$7D32, #$7D31, - #$7F3D, #$7F9E, #$7F9A, #$7FCC, #$7FCE, #$7FD2, #$801C, #$804A, - #$8046, #$812F, #$8116, #$8123, #$812B, #$8129, #$8130, #$8124, - #$8202, #$8235, #$8237, #$8236, #$8239, #$838E, #$839E, #$8398, - #$8378, #$83A2, #$8396, #$83BD, #$83AB, #$8392, #$838A, #$8393, - #$8389, #$83A0, #$8377, #$837B, #$837C, - #$8386, #$83A7, #$8655, #$5F6A, #$86C7, #$86C0, #$86B6, #$86C4, - #$86B5, #$86C6, #$86CB, #$86B1, #$86AF, #$86C9, #$8853, #$889E, - #$8888, #$88AB, #$8892, #$8896, #$888D, #$888B, #$8993, #$898F, - #$8A2A, #$8A1D, #$8A23, #$8A25, #$8A31, #$8A2D, #$8A1F, #$8A1B, - #$8A22, #$8C49, #$8C5A, #$8CA9, #$8CAC, #$8CAB, #$8CA8, #$8CAA, - #$8CA7, #$8D67, #$8D66, #$8DBE, #$8DBA, #$8EDB, #$8EDF, #$9019, - #$900D, #$901A, #$9017, #$9023, #$901F, #$901D, #$9010, #$9015, - #$901E, #$9020, #$900F, #$9022, #$9016, #$901B, #$9014, #$90E8, - #$90ED, #$90FD, #$9157, #$91CE, #$91F5, #$91E6, #$91E3, #$91E7, - #$91ED, #$91E9, #$9589, #$966A, #$9675, #$9673, #$9678, #$9670, - #$9674, #$9676, #$9677, #$966C, #$96C0, #$96EA, #$96E9, #$7AE0, - #$7ADF, #$9802, #$9803, #$9B5A, #$9CE5, #$9E75, #$9E7F, #$9EA5, - #$9EBB, #$50A2, #$508D, #$5085, #$5099, #$5091, #$5080, #$5096, - #$5098, #$509A, #$6700, #$51F1, #$5272, #$5274, #$5275, #$5269, - #$52DE, #$52DD, #$52DB, #$535A, #$53A5, #$557B, #$5580, #$55A7, - #$557C, #$558A, #$559D, #$5598, #$5582, #$559C, #$55AA, #$5594, - #$5587, #$558B, #$5583, #$55B3, #$55AE, #$559F, #$553E, #$55B2, - #$559A, #$55BB, #$55AC, #$55B1, #$557E, #$5589, #$55AB, #$5599, - #$570D, #$582F, #$582A, #$5834, #$5824, #$5830, #$5831, #$5821, - #$581D, #$5820, #$58F9, #$58FA, #$5960, - #$5A77, #$5A9A, #$5A7F, #$5A92, #$5A9B, #$5AA7, #$5B73, #$5B71, - #$5BD2, #$5BCC, #$5BD3, #$5BD0, #$5C0A, #$5C0B, #$5C31, #$5D4C, - #$5D50, #$5D34, #$5D47, #$5DFD, #$5E45, #$5E3D, #$5E40, #$5E43, - #$5E7E, #$5ECA, #$5EC1, #$5EC2, #$5EC4, #$5F3C, #$5F6D, #$5FA9, - #$5FAA, #$5FA8, #$60D1, #$60E1, #$60B2, #$60B6, #$60E0, #$611C, - #$6123, #$60FA, #$6115, #$60F0, #$60FB, #$60F4, #$6168, #$60F1, - #$610E, #$60F6, #$6109, #$6100, #$6112, #$621F, #$6249, #$63A3, - #$638C, #$63CF, #$63C0, #$63E9, #$63C9, #$63C6, #$63CD, #$63D2, - #$63E3, #$63D0, #$63E1, #$63D6, #$63ED, #$63EE, #$6376, #$63F4, - #$63EA, #$63DB, #$6452, #$63DA, #$63F9, #$655E, #$6566, #$6562, - #$6563, #$6591, #$6590, #$65AF, #$666E, #$6670, #$6674, #$6676, - #$666F, #$6691, #$667A, #$667E, #$6677, #$66FE, #$66FF, #$671F, - #$671D, #$68FA, #$68D5, #$68E0, #$68D8, #$68D7, #$6905, #$68DF, - #$68F5, #$68EE, #$68E7, #$68F9, #$68D2, #$68F2, #$68E3, #$68CB, - #$68CD, #$690D, #$6912, #$690E, #$68C9, #$68DA, #$696E, #$68FB, - #$6B3E, #$6B3A, #$6B3D, #$6B98, #$6B96, #$6BBC, #$6BEF, #$6C2E, - #$6C2F, #$6C2C, #$6E2F, #$6E38, #$6E54, #$6E21, #$6E32, #$6E67, - #$6E4A, #$6E20, #$6E25, #$6E23, #$6E1B, #$6E5B, #$6E58, #$6E24, - #$6E56, #$6E6E, #$6E2D, #$6E26, #$6E6F, #$6E34, #$6E4D, #$6E3A, - #$6E2C, #$6E43, #$6E1D, #$6E3E, #$6ECB, - #$6E89, #$6E19, #$6E4E, #$6E63, #$6E44, #$6E72, #$6E69, #$6E5F, - #$7119, #$711A, #$7126, #$7130, #$7121, #$7136, #$716E, #$711C, - #$724C, #$7284, #$7280, #$7336, #$7325, #$7334, #$7329, #$743A, - #$742A, #$7433, #$7422, #$7425, #$7435, #$7436, #$7434, #$742F, - #$741B, #$7426, #$7428, #$7525, #$7526, #$756B, #$756A, #$75E2, - #$75DB, #$75E3, #$75D9, #$75D8, #$75DE, #$75E0, #$767B, #$767C, - #$7696, #$7693, #$76B4, #$76DC, #$774F, #$77ED, #$785D, #$786C, - #$786F, #$7A0D, #$7A08, #$7A0B, #$7A05, #$7A00, #$7A98, #$7A97, - #$7A96, #$7AE5, #$7AE3, #$7B49, #$7B56, #$7B46, #$7B50, #$7B52, - #$7B54, #$7B4D, #$7B4B, #$7B4F, #$7B51, #$7C9F, #$7CA5, #$7D5E, - #$7D50, #$7D68, #$7D55, #$7D2B, #$7D6E, #$7D72, #$7D61, #$7D66, - #$7D62, #$7D70, #$7D73, #$5584, #$7FD4, #$7FD5, #$800B, #$8052, - #$8085, #$8155, #$8154, #$814B, #$8151, #$814E, #$8139, #$8146, - #$813E, #$814C, #$8153, #$8174, #$8212, #$821C, #$83E9, #$8403, - #$83F8, #$840D, #$83E0, #$83C5, #$840B, #$83C1, #$83EF, #$83F1, - #$83F4, #$8457, #$840A, #$83F0, #$840C, #$83CC, #$83FD, #$83F2, - #$83CA, #$8438, #$840E, #$8404, #$83DC, #$8407, #$83D4, #$83DF, - #$865B, #$86DF, #$86D9, #$86ED, #$86D4, #$86DB, #$86E4, #$86D0, - #$86DE, #$8857, #$88C1, #$88C2, #$88B1, #$8983, #$8996, #$8A3B, - #$8A60, #$8A55, #$8A5E, #$8A3C, #$8A41, - #$8A54, #$8A5B, #$8A50, #$8A46, #$8A34, #$8A3A, #$8A36, #$8A56, - #$8C61, #$8C82, #$8CAF, #$8CBC, #$8CB3, #$8CBD, #$8CC1, #$8CBB, - #$8CC0, #$8CB4, #$8CB7, #$8CB6, #$8CBF, #$8CB8, #$8D8A, #$8D85, - #$8D81, #$8DCE, #$8DDD, #$8DCB, #$8DDA, #$8DD1, #$8DCC, #$8DDB, - #$8DC6, #$8EFB, #$8EF8, #$8EFC, #$8F9C, #$902E, #$9035, #$9031, - #$9038, #$9032, #$9036, #$9102, #$90F5, #$9109, #$90FE, #$9163, - #$9165, #$91CF, #$9214, #$9215, #$9223, #$9209, #$921E, #$920D, - #$9210, #$9207, #$9211, #$9594, #$958F, #$958B, #$9591, #$9593, - #$9592, #$958E, #$968A, #$968E, #$968B, #$967D, #$9685, #$9686, - #$968D, #$9672, #$9684, #$96C1, #$96C5, #$96C4, #$96C6, #$96C7, - #$96EF, #$96F2, #$97CC, #$9805, #$9806, #$9808, #$98E7, #$98EA, - #$98EF, #$98E9, #$98F2, #$98ED, #$99AE, #$99AD, #$9EC3, #$9ECD, - #$9ED1, #$4E82, #$50AD, #$50B5, #$50B2, #$50B3, #$50C5, #$50BE, - #$50AC, #$50B7, #$50BB, #$50AF, #$50C7, #$527F, #$5277, #$527D, - #$52DF, #$52E6, #$52E4, #$52E2, #$52E3, #$532F, #$55DF, #$55E8, - #$55D3, #$55E6, #$55CE, #$55DC, #$55C7, #$55D1, #$55E3, #$55E4, - #$55EF, #$55DA, #$55E1, #$55C5, #$55C6, #$55E5, #$55C9, #$5712, - #$5713, #$585E, #$5851, #$5858, #$5857, #$585A, #$5854, #$586B, - #$584C, #$586D, #$584A, #$5862, #$5852, #$584B, #$5967, #$5AC1, - #$5AC9, #$5ACC, #$5ABE, #$5ABD, #$5ABC, - #$5AB3, #$5AC2, #$5AB2, #$5D69, #$5D6F, #$5E4C, #$5E79, #$5EC9, - #$5EC8, #$5F12, #$5F59, #$5FAC, #$5FAE, #$611A, #$610F, #$6148, - #$611F, #$60F3, #$611B, #$60F9, #$6101, #$6108, #$614E, #$614C, - #$6144, #$614D, #$613E, #$6134, #$6127, #$610D, #$6106, #$6137, - #$6221, #$6222, #$6413, #$643E, #$641E, #$642A, #$642D, #$643D, - #$642C, #$640F, #$641C, #$6414, #$640D, #$6436, #$6416, #$6417, - #$6406, #$656C, #$659F, #$65B0, #$6697, #$6689, #$6687, #$6688, - #$6696, #$6684, #$6698, #$668D, #$6703, #$6994, #$696D, #$695A, - #$6977, #$6960, #$6954, #$6975, #$6930, #$6982, #$694A, #$6968, - #$696B, #$695E, #$6953, #$6979, #$6986, #$695D, #$6963, #$695B, - #$6B47, #$6B72, #$6BC0, #$6BBF, #$6BD3, #$6BFD, #$6EA2, #$6EAF, - #$6ED3, #$6EB6, #$6EC2, #$6E90, #$6E9D, #$6EC7, #$6EC5, #$6EA5, - #$6E98, #$6EBC, #$6EBA, #$6EAB, #$6ED1, #$6E96, #$6E9C, #$6EC4, - #$6ED4, #$6EAA, #$6EA7, #$6EB4, #$714E, #$7159, #$7169, #$7164, - #$7149, #$7167, #$715C, #$716C, #$7166, #$714C, #$7165, #$715E, - #$7146, #$7168, #$7156, #$723A, #$7252, #$7337, #$7345, #$733F, - #$733E, #$746F, #$745A, #$7455, #$745F, #$745E, #$7441, #$743F, - #$7459, #$745B, #$745C, #$7576, #$7578, #$7600, #$75F0, #$7601, - #$75F2, #$75F1, #$75FA, #$75FF, #$75F4, #$75F3, #$76DE, #$76DF, - #$775B, #$776B, #$7766, #$775E, #$7763, - #$7779, #$776A, #$776C, #$775C, #$7765, #$7768, #$7762, #$77EE, - #$788E, #$78B0, #$7897, #$7898, #$788C, #$7889, #$787C, #$7891, - #$7893, #$787F, #$797A, #$797F, #$7981, #$842C, #$79BD, #$7A1C, - #$7A1A, #$7A20, #$7A14, #$7A1F, #$7A1E, #$7A9F, #$7AA0, #$7B77, - #$7BC0, #$7B60, #$7B6E, #$7B67, #$7CB1, #$7CB3, #$7CB5, #$7D93, - #$7D79, #$7D91, #$7D81, #$7D8F, #$7D5B, #$7F6E, #$7F69, #$7F6A, - #$7F72, #$7FA9, #$7FA8, #$7FA4, #$8056, #$8058, #$8086, #$8084, - #$8171, #$8170, #$8178, #$8165, #$816E, #$8173, #$816B, #$8179, - #$817A, #$8166, #$8205, #$8247, #$8482, #$8477, #$843D, #$8431, - #$8475, #$8466, #$846B, #$8449, #$846C, #$845B, #$843C, #$8435, - #$8461, #$8463, #$8469, #$846D, #$8446, #$865E, #$865C, #$865F, - #$86F9, #$8713, #$8708, #$8707, #$8700, #$86FE, #$86FB, #$8702, - #$8703, #$8706, #$870A, #$8859, #$88DF, #$88D4, #$88D9, #$88DC, - #$88D8, #$88DD, #$88E1, #$88CA, #$88D5, #$88D2, #$899C, #$89E3, - #$8A6B, #$8A72, #$8A73, #$8A66, #$8A69, #$8A70, #$8A87, #$8A7C, - #$8A63, #$8AA0, #$8A71, #$8A85, #$8A6D, #$8A62, #$8A6E, #$8A6C, - #$8A79, #$8A7B, #$8A3E, #$8A68, #$8C62, #$8C8A, #$8C89, #$8CCA, - #$8CC7, #$8CC8, #$8CC4, #$8CB2, #$8CC3, #$8CC2, #$8CC5, #$8DE1, - #$8DDF, #$8DE8, #$8DEF, #$8DF3, #$8DFA, #$8DEA, #$8DE4, #$8DE6, - #$8EB2, #$8F03, #$8F09, #$8EFE, #$8F0A, - #$8F9F, #$8FB2, #$904B, #$904A, #$9053, #$9042, #$9054, #$903C, - #$9055, #$9050, #$9047, #$904F, #$904E, #$904D, #$9051, #$903E, - #$9041, #$9112, #$9117, #$916C, #$916A, #$9169, #$91C9, #$9237, - #$9257, #$9238, #$923D, #$9240, #$923E, #$925B, #$924B, #$9264, - #$9251, #$9234, #$9249, #$924D, #$9245, #$9239, #$923F, #$925A, - #$9598, #$9698, #$9694, #$9695, #$96CD, #$96CB, #$96C9, #$96CA, - #$96F7, #$96FB, #$96F9, #$96F6, #$9756, #$9774, #$9776, #$9810, - #$9811, #$9813, #$980A, #$9812, #$980C, #$98FC, #$98F4, #$98FD, - #$98FE, #$99B3, #$99B1, #$99B4, #$9AE1, #$9CE9, #$9E82, #$9F0E, - #$9F13, #$9F20, #$50E7, #$50EE, #$50E5, #$50D6, #$50ED, #$50DA, - #$50D5, #$50CF, #$50D1, #$50F1, #$50CE, #$50E9, #$5162, #$51F3, - #$5283, #$5282, #$5331, #$53AD, #$55FE, #$5600, #$561B, #$5617, - #$55FD, #$5614, #$5606, #$5609, #$560D, #$560E, #$55F7, #$5616, - #$561F, #$5608, #$5610, #$55F6, #$5718, #$5716, #$5875, #$587E, - #$5883, #$5893, #$588A, #$5879, #$5885, #$587D, #$58FD, #$5925, - #$5922, #$5924, #$596A, #$5969, #$5AE1, #$5AE6, #$5AE9, #$5AD7, - #$5AD6, #$5AD8, #$5AE3, #$5B75, #$5BDE, #$5BE7, #$5BE1, #$5BE5, - #$5BE6, #$5BE8, #$5BE2, #$5BE4, #$5BDF, #$5C0D, #$5C62, #$5D84, - #$5D87, #$5E5B, #$5E63, #$5E55, #$5E57, #$5E54, #$5ED3, #$5ED6, - #$5F0A, #$5F46, #$5F70, #$5FB9, #$6147, - #$613F, #$614B, #$6177, #$6162, #$6163, #$615F, #$615A, #$6158, - #$6175, #$622A, #$6487, #$6458, #$6454, #$64A4, #$6478, #$645F, - #$647A, #$6451, #$6467, #$6434, #$646D, #$647B, #$6572, #$65A1, - #$65D7, #$65D6, #$66A2, #$66A8, #$669D, #$699C, #$69A8, #$6995, - #$69C1, #$69AE, #$69D3, #$69CB, #$699B, #$69B7, #$69BB, #$69AB, - #$69B4, #$69D0, #$69CD, #$69AD, #$69CC, #$69A6, #$69C3, #$69A3, - #$6B49, #$6B4C, #$6C33, #$6F33, #$6F14, #$6EFE, #$6F13, #$6EF4, - #$6F29, #$6F3E, #$6F20, #$6F2C, #$6F0F, #$6F02, #$6F22, #$6EFF, - #$6EEF, #$6F06, #$6F31, #$6F38, #$6F32, #$6F23, #$6F15, #$6F2B, - #$6F2F, #$6F88, #$6F2A, #$6EEC, #$6F01, #$6EF2, #$6ECC, #$6EF7, - #$7194, #$7199, #$717D, #$718A, #$7184, #$7192, #$723E, #$7292, - #$7296, #$7344, #$7350, #$7464, #$7463, #$746A, #$7470, #$746D, - #$7504, #$7591, #$7627, #$760D, #$760B, #$7609, #$7613, #$76E1, - #$76E3, #$7784, #$777D, #$777F, #$7761, #$78C1, #$789F, #$78A7, - #$78B3, #$78A9, #$78A3, #$798E, #$798F, #$798D, #$7A2E, #$7A31, - #$7AAA, #$7AA9, #$7AED, #$7AEF, #$7BA1, #$7B95, #$7B8B, #$7B75, - #$7B97, #$7B9D, #$7B94, #$7B8F, #$7BB8, #$7B87, #$7B84, #$7CB9, - #$7CBD, #$7CBE, #$7DBB, #$7DB0, #$7D9C, #$7DBD, #$7DBE, #$7DA0, - #$7DCA, #$7DB4, #$7DB2, #$7DB1, #$7DBA, #$7DA2, #$7DBF, #$7DB5, - #$7DB8, #$7DAD, #$7DD2, #$7DC7, #$7DAC, - #$7F70, #$7FE0, #$7FE1, #$7FDF, #$805E, #$805A, #$8087, #$8150, - #$8180, #$818F, #$8188, #$818A, #$817F, #$8182, #$81E7, #$81FA, - #$8207, #$8214, #$821E, #$824B, #$84C9, #$84BF, #$84C6, #$84C4, - #$8499, #$849E, #$84B2, #$849C, #$84CB, #$84B8, #$84C0, #$84D3, - #$8490, #$84BC, #$84D1, #$84CA, #$873F, #$871C, #$873B, #$8722, - #$8725, #$8734, #$8718, #$8755, #$8737, #$8729, #$88F3, #$8902, - #$88F4, #$88F9, #$88F8, #$88FD, #$88E8, #$891A, #$88EF, #$8AA6, - #$8A8C, #$8A9E, #$8AA3, #$8A8D, #$8AA1, #$8A93, #$8AA4, #$8AAA, - #$8AA5, #$8AA8, #$8A98, #$8A91, #$8A9A, #$8AA7, #$8C6A, #$8C8D, - #$8C8C, #$8CD3, #$8CD1, #$8CD2, #$8D6B, #$8D99, #$8D95, #$8DFC, - #$8F14, #$8F12, #$8F15, #$8F13, #$8FA3, #$9060, #$9058, #$905C, - #$9063, #$9059, #$905E, #$9062, #$905D, #$905B, #$9119, #$9118, - #$911E, #$9175, #$9178, #$9177, #$9174, #$9278, #$9280, #$9285, - #$9298, #$9296, #$927B, #$9293, #$929C, #$92A8, #$927C, #$9291, - #$95A1, #$95A8, #$95A9, #$95A3, #$95A5, #$95A4, #$9699, #$969C, - #$969B, #$96CC, #$96D2, #$9700, #$977C, #$9785, #$97F6, #$9817, - #$9818, #$98AF, #$98B1, #$9903, #$9905, #$990C, #$9909, #$99C1, - #$9AAF, #$9AB0, #$9AE6, #$9B41, #$9B42, #$9CF4, #$9CF6, #$9CF3, - #$9EBC, #$9F3B, #$9F4A, #$5104, #$5100, #$50FB, #$50F5, #$50F9, - #$5102, #$5108, #$5109, #$5105, #$51DC, - #$5287, #$5288, #$5289, #$528D, #$528A, #$52F0, #$53B2, #$562E, - #$563B, #$5639, #$5632, #$563F, #$5634, #$5629, #$5653, #$564E, - #$5657, #$5674, #$5636, #$562F, #$5630, #$5880, #$589F, #$589E, - #$58B3, #$589C, #$58AE, #$58A9, #$58A6, #$596D, #$5B09, #$5AFB, - #$5B0B, #$5AF5, #$5B0C, #$5B08, #$5BEE, #$5BEC, #$5BE9, #$5BEB, - #$5C64, #$5C65, #$5D9D, #$5D94, #$5E62, #$5E5F, #$5E61, #$5EE2, - #$5EDA, #$5EDF, #$5EDD, #$5EE3, #$5EE0, #$5F48, #$5F71, #$5FB7, - #$5FB5, #$6176, #$6167, #$616E, #$615D, #$6155, #$6182, #$617C, - #$6170, #$616B, #$617E, #$61A7, #$6190, #$61AB, #$618E, #$61AC, - #$619A, #$61A4, #$6194, #$61AE, #$622E, #$6469, #$646F, #$6479, - #$649E, #$64B2, #$6488, #$6490, #$64B0, #$64A5, #$6493, #$6495, - #$64A9, #$6492, #$64AE, #$64AD, #$64AB, #$649A, #$64AC, #$6499, - #$64A2, #$64B3, #$6575, #$6577, #$6578, #$66AE, #$66AB, #$66B4, - #$66B1, #$6A23, #$6A1F, #$69E8, #$6A01, #$6A1E, #$6A19, #$69FD, - #$6A21, #$6A13, #$6A0A, #$69F3, #$6A02, #$6A05, #$69ED, #$6A11, - #$6B50, #$6B4E, #$6BA4, #$6BC5, #$6BC6, #$6F3F, #$6F7C, #$6F84, - #$6F51, #$6F66, #$6F54, #$6F86, #$6F6D, #$6F5B, #$6F78, #$6F6E, - #$6F8E, #$6F7A, #$6F70, #$6F64, #$6F97, #$6F58, #$6ED5, #$6F6F, - #$6F60, #$6F5F, #$719F, #$71AC, #$71B1, #$71A8, #$7256, #$729B, - #$734E, #$7357, #$7469, #$748B, #$7483, - #$747E, #$7480, #$757F, #$7620, #$7629, #$761F, #$7624, #$7626, - #$7621, #$7622, #$769A, #$76BA, #$76E4, #$778E, #$7787, #$778C, - #$7791, #$778B, #$78CB, #$78C5, #$78BA, #$78CA, #$78BE, #$78D5, - #$78BC, #$78D0, #$7A3F, #$7A3C, #$7A40, #$7A3D, #$7A37, #$7A3B, - #$7AAF, #$7AAE, #$7BAD, #$7BB1, #$7BC4, #$7BB4, #$7BC6, #$7BC7, - #$7BC1, #$7BA0, #$7BCC, #$7CCA, #$7DE0, #$7DF4, #$7DEF, #$7DFB, - #$7DD8, #$7DEC, #$7DDD, #$7DE8, #$7DE3, #$7DDA, #$7DDE, #$7DE9, - #$7D9E, #$7DD9, #$7DF2, #$7DF9, #$7F75, #$7F77, #$7FAF, #$7FE9, - #$8026, #$819B, #$819C, #$819D, #$81A0, #$819A, #$8198, #$8517, - #$853D, #$851A, #$84EE, #$852C, #$852D, #$8513, #$8511, #$8523, - #$8521, #$8514, #$84EC, #$8525, #$84FF, #$8506, #$8782, #$8774, - #$8776, #$8760, #$8766, #$8778, #$8768, #$8759, #$8757, #$874C, - #$8753, #$885B, #$885D, #$8910, #$8907, #$8912, #$8913, #$8915, - #$890A, #$8ABC, #$8AD2, #$8AC7, #$8AC4, #$8A95, #$8ACB, #$8AF8, - #$8AB2, #$8AC9, #$8AC2, #$8ABF, #$8AB0, #$8AD6, #$8ACD, #$8AB6, - #$8AB9, #$8ADB, #$8C4C, #$8C4E, #$8C6C, #$8CE0, #$8CDE, #$8CE6, - #$8CE4, #$8CEC, #$8CED, #$8CE2, #$8CE3, #$8CDC, #$8CEA, #$8CE1, - #$8D6D, #$8D9F, #$8DA3, #$8E2B, #$8E10, #$8E1D, #$8E22, #$8E0F, - #$8E29, #$8E1F, #$8E21, #$8E1E, #$8EBA, #$8F1D, #$8F1B, #$8F1F, - #$8F29, #$8F26, #$8F2A, #$8F1C, #$8F1E, - #$8F25, #$9069, #$906E, #$9068, #$906D, #$9077, #$9130, #$912D, - #$9127, #$9131, #$9187, #$9189, #$918B, #$9183, #$92C5, #$92BB, - #$92B7, #$92EA, #$92AC, #$92E4, #$92C1, #$92B3, #$92BC, #$92D2, - #$92C7, #$92F0, #$92B2, #$95AD, #$95B1, #$9704, #$9706, #$9707, - #$9709, #$9760, #$978D, #$978B, #$978F, #$9821, #$982B, #$981C, - #$98B3, #$990A, #$9913, #$9912, #$9918, #$99DD, #$99D0, #$99DF, - #$99DB, #$99D1, #$99D5, #$99D2, #$99D9, #$9AB7, #$9AEE, #$9AEF, - #$9B27, #$9B45, #$9B44, #$9B77, #$9B6F, #$9D06, #$9D09, #$9D03, - #$9EA9, #$9EBE, #$9ECE, #$58A8, #$9F52, #$5112, #$5118, #$5114, - #$5110, #$5115, #$5180, #$51AA, #$51DD, #$5291, #$5293, #$52F3, - #$5659, #$566B, #$5679, #$5669, #$5664, #$5678, #$566A, #$5668, - #$5665, #$5671, #$566F, #$566C, #$5662, #$5676, #$58C1, #$58BE, - #$58C7, #$58C5, #$596E, #$5B1D, #$5B34, #$5B78, #$5BF0, #$5C0E, - #$5F4A, #$61B2, #$6191, #$61A9, #$618A, #$61CD, #$61B6, #$61BE, - #$61CA, #$61C8, #$6230, #$64C5, #$64C1, #$64CB, #$64BB, #$64BC, - #$64DA, #$64C4, #$64C7, #$64C2, #$64CD, #$64BF, #$64D2, #$64D4, - #$64BE, #$6574, #$66C6, #$66C9, #$66B9, #$66C4, #$66C7, #$66B8, - #$6A3D, #$6A38, #$6A3A, #$6A59, #$6A6B, #$6A58, #$6A39, #$6A44, - #$6A62, #$6A61, #$6A4B, #$6A47, #$6A35, #$6A5F, #$6A48, #$6B59, - #$6B77, #$6C05, #$6FC2, #$6FB1, #$6FA1, - #$6FC3, #$6FA4, #$6FC1, #$6FA7, #$6FB3, #$6FC0, #$6FB9, #$6FB6, - #$6FA6, #$6FA0, #$6FB4, #$71BE, #$71C9, #$71D0, #$71D2, #$71C8, - #$71D5, #$71B9, #$71CE, #$71D9, #$71DC, #$71C3, #$71C4, #$7368, - #$749C, #$74A3, #$7498, #$749F, #$749E, #$74E2, #$750C, #$750D, - #$7634, #$7638, #$763A, #$76E7, #$76E5, #$77A0, #$779E, #$779F, - #$77A5, #$78E8, #$78DA, #$78EC, #$78E7, #$79A6, #$7A4D, #$7A4E, - #$7A46, #$7A4C, #$7A4B, #$7ABA, #$7BD9, #$7C11, #$7BC9, #$7BE4, - #$7BDB, #$7BE1, #$7BE9, #$7BE6, #$7CD5, #$7CD6, #$7E0A, #$7E11, - #$7E08, #$7E1B, #$7E23, #$7E1E, #$7E1D, #$7E09, #$7E10, #$7F79, - #$7FB2, #$7FF0, #$7FF1, #$7FEE, #$8028, #$81B3, #$81A9, #$81A8, - #$81FB, #$8208, #$8258, #$8259, #$854A, #$8559, #$8548, #$8568, - #$8569, #$8543, #$8549, #$856D, #$856A, #$855E, #$8783, #$879F, - #$879E, #$87A2, #$878D, #$8861, #$892A, #$8932, #$8925, #$892B, - #$8921, #$89AA, #$89A6, #$8AE6, #$8AFA, #$8AEB, #$8AF1, #$8B00, - #$8ADC, #$8AE7, #$8AEE, #$8AFE, #$8B01, #$8B02, #$8AF7, #$8AED, - #$8AF3, #$8AF6, #$8AFC, #$8C6B, #$8C6D, #$8C93, #$8CF4, #$8E44, - #$8E31, #$8E34, #$8E42, #$8E39, #$8E35, #$8F3B, #$8F2F, #$8F38, - #$8F33, #$8FA8, #$8FA6, #$9075, #$9074, #$9078, #$9072, #$907C, - #$907A, #$9134, #$9192, #$9320, #$9336, #$92F8, #$9333, #$932F, - #$9322, #$92FC, #$932B, #$9304, #$931A, - #$9310, #$9326, #$9321, #$9315, #$932E, #$9319, #$95BB, #$96A7, - #$96A8, #$96AA, #$96D5, #$970E, #$9711, #$9716, #$970D, #$9713, - #$970F, #$975B, #$975C, #$9766, #$9798, #$9830, #$9838, #$983B, - #$9837, #$982D, #$9839, #$9824, #$9910, #$9928, #$991E, #$991B, - #$9921, #$991A, #$99ED, #$99E2, #$99F1, #$9AB8, #$9ABC, #$9AFB, - #$9AED, #$9B28, #$9B91, #$9D15, #$9D23, #$9D26, #$9D28, #$9D12, - #$9D1B, #$9ED8, #$9ED4, #$9F8D, #$9F9C, #$512A, #$511F, #$5121, - #$5132, #$52F5, #$568E, #$5680, #$5690, #$5685, #$5687, #$568F, - #$58D5, #$58D3, #$58D1, #$58CE, #$5B30, #$5B2A, #$5B24, #$5B7A, - #$5C37, #$5C68, #$5DBC, #$5DBA, #$5DBD, #$5DB8, #$5E6B, #$5F4C, - #$5FBD, #$61C9, #$61C2, #$61C7, #$61E6, #$61CB, #$6232, #$6234, - #$64CE, #$64CA, #$64D8, #$64E0, #$64F0, #$64E6, #$64EC, #$64F1, - #$64E2, #$64ED, #$6582, #$6583, #$66D9, #$66D6, #$6A80, #$6A94, - #$6A84, #$6AA2, #$6A9C, #$6ADB, #$6AA3, #$6A7E, #$6A97, #$6A90, - #$6AA0, #$6B5C, #$6BAE, #$6BDA, #$6C08, #$6FD8, #$6FF1, #$6FDF, - #$6FE0, #$6FDB, #$6FE4, #$6FEB, #$6FEF, #$6F80, #$6FEC, #$6FE1, - #$6FE9, #$6FD5, #$6FEE, #$6FF0, #$71E7, #$71DF, #$71EE, #$71E6, - #$71E5, #$71ED, #$71EC, #$71F4, #$71E0, #$7235, #$7246, #$7370, - #$7372, #$74A9, #$74B0, #$74A6, #$74A8, #$7646, #$7642, #$764C, - #$76EA, #$77B3, #$77AA, #$77B0, #$77AC, - #$77A7, #$77AD, #$77EF, #$78F7, #$78FA, #$78F4, #$78EF, #$7901, - #$79A7, #$79AA, #$7A57, #$7ABF, #$7C07, #$7C0D, #$7BFE, #$7BF7, - #$7C0C, #$7BE0, #$7CE0, #$7CDC, #$7CDE, #$7CE2, #$7CDF, #$7CD9, - #$7CDD, #$7E2E, #$7E3E, #$7E46, #$7E37, #$7E32, #$7E43, #$7E2B, - #$7E3D, #$7E31, #$7E45, #$7E41, #$7E34, #$7E39, #$7E48, #$7E35, - #$7E3F, #$7E2F, #$7F44, #$7FF3, #$7FFC, #$8071, #$8072, #$8070, - #$806F, #$8073, #$81C6, #$81C3, #$81BA, #$81C2, #$81C0, #$81BF, - #$81BD, #$81C9, #$81BE, #$81E8, #$8209, #$8271, #$85AA, #$8584, - #$857E, #$859C, #$8591, #$8594, #$85AF, #$859B, #$8587, #$85A8, - #$858A, #$8667, #$87C0, #$87D1, #$87B3, #$87D2, #$87C6, #$87AB, - #$87BB, #$87BA, #$87C8, #$87CB, #$893B, #$8936, #$8944, #$8938, - #$893D, #$89AC, #$8B0E, #$8B17, #$8B19, #$8B1B, #$8B0A, #$8B20, - #$8B1D, #$8B04, #$8B10, #$8C41, #$8C3F, #$8C73, #$8CFA, #$8CFD, - #$8CFC, #$8CF8, #$8CFB, #$8DA8, #$8E49, #$8E4B, #$8E48, #$8E4A, - #$8F44, #$8F3E, #$8F42, #$8F45, #$8F3F, #$907F, #$907D, #$9084, - #$9081, #$9082, #$9080, #$9139, #$91A3, #$919E, #$919C, #$934D, - #$9382, #$9328, #$9375, #$934A, #$9365, #$934B, #$9318, #$937E, - #$936C, #$935B, #$9370, #$935A, #$9354, #$95CA, #$95CB, #$95CC, - #$95C8, #$95C6, #$96B1, #$96B8, #$96D6, #$971C, #$971E, #$97A0, - #$97D3, #$9846, #$98B6, #$9935, #$9A01, - #$99FF, #$9BAE, #$9BAB, #$9BAA, #$9BAD, #$9D3B, #$9D3F, #$9E8B, - #$9ECF, #$9EDE, #$9EDC, #$9EDD, #$9EDB, #$9F3E, #$9F4B, #$53E2, - #$5695, #$56AE, #$58D9, #$58D8, #$5B38, #$5F5D, #$61E3, #$6233, - #$64F4, #$64F2, #$64FE, #$6506, #$64FA, #$64FB, #$64F7, #$65B7, - #$66DC, #$6726, #$6AB3, #$6AAC, #$6AC3, #$6ABB, #$6AB8, #$6AC2, - #$6AAE, #$6AAF, #$6B5F, #$6B78, #$6BAF, #$7009, #$700B, #$6FFE, - #$7006, #$6FFA, #$7011, #$700F, #$71FB, #$71FC, #$71FE, #$71F8, - #$7377, #$7375, #$74A7, #$74BF, #$7515, #$7656, #$7658, #$7652, - #$77BD, #$77BF, #$77BB, #$77BC, #$790E, #$79AE, #$7A61, #$7A62, - #$7A60, #$7AC4, #$7AC5, #$7C2B, #$7C27, #$7C2A, #$7C1E, #$7C23, - #$7C21, #$7CE7, #$7E54, #$7E55, #$7E5E, #$7E5A, #$7E61, #$7E52, - #$7E59, #$7F48, #$7FF9, #$7FFB, #$8077, #$8076, #$81CD, #$81CF, - #$820A, #$85CF, #$85A9, #$85CD, #$85D0, #$85C9, #$85B0, #$85BA, - #$85B9, #$85A6, #$87EF, #$87EC, #$87F2, #$87E0, #$8986, #$89B2, - #$89F4, #$8B28, #$8B39, #$8B2C, #$8B2B, #$8C50, #$8D05, #$8E59, - #$8E63, #$8E66, #$8E64, #$8E5F, #$8E55, #$8EC0, #$8F49, #$8F4D, - #$9087, #$9083, #$9088, #$91AB, #$91AC, #$91D0, #$9394, #$938A, - #$9396, #$93A2, #$93B3, #$93AE, #$93AC, #$93B0, #$9398, #$939A, - #$9397, #$95D4, #$95D6, #$95D0, #$95D5, #$96E2, #$96DC, #$96D9, - #$96DB, #$96DE, #$9724, #$97A3, #$97A6, - #$97AD, #$97F9, #$984D, #$984F, #$984C, #$984E, #$9853, #$98BA, - #$993E, #$993F, #$993D, #$992E, #$99A5, #$9A0E, #$9AC1, #$9B03, - #$9B06, #$9B4F, #$9B4E, #$9B4D, #$9BCA, #$9BC9, #$9BFD, #$9BC8, - #$9BC0, #$9D51, #$9D5D, #$9D60, #$9EE0, #$9F15, #$9F2C, #$5133, - #$56A5, #$58DE, #$58DF, #$58E2, #$5BF5, #$9F90, #$5EEC, #$61F2, - #$61F7, #$61F6, #$61F5, #$6500, #$650F, #$66E0, #$66DD, #$6AE5, - #$6ADD, #$6ADA, #$6AD3, #$701B, #$701F, #$7028, #$701A, #$701D, - #$7015, #$7018, #$7206, #$720D, #$7258, #$72A2, #$7378, #$737A, - #$74BD, #$74CA, #$74E3, #$7587, #$7586, #$765F, #$7661, #$77C7, - #$7919, #$79B1, #$7A6B, #$7A69, #$7C3E, #$7C3F, #$7C38, #$7C3D, - #$7C37, #$7C40, #$7E6B, #$7E6D, #$7E79, #$7E69, #$7E6A, #$7F85, - #$7E73, #$7FB6, #$7FB9, #$7FB8, #$81D8, #$85E9, #$85DD, #$85EA, - #$85D5, #$85E4, #$85E5, #$85F7, #$87FB, #$8805, #$880D, #$87F9, - #$87FE, #$8960, #$895F, #$8956, #$895E, #$8B41, #$8B5C, #$8B58, - #$8B49, #$8B5A, #$8B4E, #$8B4F, #$8B46, #$8B59, #$8D08, #$8D0A, - #$8E7C, #$8E72, #$8E87, #$8E76, #$8E6C, #$8E7A, #$8E74, #$8F54, - #$8F4E, #$8FAD, #$908A, #$908B, #$91B1, #$91AE, #$93E1, #$93D1, - #$93DF, #$93C3, #$93C8, #$93DC, #$93DD, #$93D6, #$93E2, #$93CD, - #$93D8, #$93E4, #$93D7, #$93E8, #$95DC, #$96B4, #$96E3, #$972A, - #$9727, #$9761, #$97DC, #$97FB, #$985E, - #$9858, #$985B, #$98BC, #$9945, #$9949, #$9A16, #$9A19, #$9B0D, - #$9BE8, #$9BE7, #$9BD6, #$9BDB, #$9D89, #$9D61, #$9D72, #$9D6A, - #$9D6C, #$9E92, #$9E97, #$9E93, #$9EB4, #$52F8, #$56A8, #$56B7, - #$56B6, #$56B4, #$56BC, #$58E4, #$5B40, #$5B43, #$5B7D, #$5BF6, - #$5DC9, #$61F8, #$61FA, #$6518, #$6514, #$6519, #$66E6, #$6727, - #$6AEC, #$703E, #$7030, #$7032, #$7210, #$737B, #$74CF, #$7662, - #$7665, #$7926, #$792A, #$792C, #$792B, #$7AC7, #$7AF6, #$7C4C, - #$7C43, #$7C4D, #$7CEF, #$7CF0, #$8FAE, #$7E7D, #$7E7C, #$7E82, - #$7F4C, #$8000, #$81DA, #$8266, #$85FB, #$85F9, #$8611, #$85FA, - #$8606, #$860B, #$8607, #$860A, #$8814, #$8815, #$8964, #$89BA, - #$89F8, #$8B70, #$8B6C, #$8B66, #$8B6F, #$8B5F, #$8B6B, #$8D0F, - #$8D0D, #$8E89, #$8E81, #$8E85, #$8E82, #$91B4, #$91CB, #$9418, - #$9403, #$93FD, #$95E1, #$9730, #$98C4, #$9952, #$9951, #$99A8, - #$9A2B, #$9A30, #$9A37, #$9A35, #$9C13, #$9C0D, #$9E79, #$9EB5, - #$9EE8, #$9F2F, #$9F5F, #$9F63, #$9F61, #$5137, #$5138, #$56C1, - #$56C0, #$56C2, #$5914, #$5C6C, #$5DCD, #$61FC, #$61FE, #$651D, - #$651C, #$6595, #$66E9, #$6AFB, #$6B04, #$6AFA, #$6BB2, #$704C, - #$721B, #$72A7, #$74D6, #$74D4, #$7669, #$77D3, #$7C50, #$7E8F, - #$7E8C, #$7FBC, #$8617, #$862D, #$861A, #$8823, #$8822, #$8821, - #$881F, #$896A, #$896C, #$89BD, #$8B74, - #$8B77, #$8B7D, #$8D13, #$8E8A, #$8E8D, #$8E8B, #$8F5F, #$8FAF, - #$91BA, #$942E, #$9433, #$9435, #$943A, #$9438, #$9432, #$942B, - #$95E2, #$9738, #$9739, #$9732, #$97FF, #$9867, #$9865, #$9957, - #$9A45, #$9A43, #$9A40, #$9A3E, #$9ACF, #$9B54, #$9B51, #$9C2D, - #$9C25, #$9DAF, #$9DB4, #$9DC2, #$9DB8, #$9E9D, #$9EEF, #$9F19, - #$9F5C, #$9F66, #$9F67, #$513C, #$513B, #$56C8, #$56CA, #$56C9, - #$5B7F, #$5DD4, #$5DD2, #$5F4E, #$61FF, #$6524, #$6B0A, #$6B61, - #$7051, #$7058, #$7380, #$74E4, #$758A, #$766E, #$766C, #$79B3, - #$7C60, #$7C5F, #$807E, #$807D, #$81DF, #$8972, #$896F, #$89FC, - #$8B80, #$8D16, #$8D17, #$8E91, #$8E93, #$8F61, #$9148, #$9444, - #$9451, #$9452, #$973D, #$973E, #$97C3, #$97C1, #$986B, #$9955, - #$9A55, #$9A4D, #$9AD2, #$9B1A, #$9C49, #$9C31, #$9C3E, #$9C3B, - #$9DD3, #$9DD7, #$9F34, #$9F6C, #$9F6A, #$9F94, #$56CC, #$5DD6, - #$6200, #$6523, #$652B, #$652A, #$66EC, #$6B10, #$74DA, #$7ACA, - #$7C64, #$7C63, #$7C65, #$7E93, #$7E96, #$7E94, #$81E2, #$8638, - #$863F, #$8831, #$8B8A, #$9090, #$908F, #$9463, #$9460, #$9464, - #$9768, #$986F, #$995C, #$9A5A, #$9A5B, #$9A57, #$9AD3, #$9AD4, - #$9AD1, #$9C54, #$9C57, #$9C56, #$9DE5, #$9E9F, #$9EF4, #$56D1, - #$58E9, #$652C, #$705E, #$7671, #$7672, #$77D7, #$7F50, #$7F88, - #$8836, #$8839, #$8862, #$8B93, #$8B92, - #$8B96, #$8277, #$8D1B, #$91C0, #$946A, #$9742, #$9748, #$9744, - #$97C6, #$9870, #$9A5F, #$9B22, #$9B58, #$9C5F, #$9DF9, #$9DFA, - #$9E7C, #$9E7D, #$9F07, #$9F77, #$9F72, #$5EF3, #$6B16, #$7063, - #$7C6C, #$7C6E, #$883B, #$89C0, #$8EA1, #$91C1, #$9472, #$9470, - #$9871, #$995E, #$9AD6, #$9B23, #$9ECC, #$7064, #$77DA, #$8B9A, - #$9477, #$97C9, #$9A62, #$9A65, #$7E9C, #$8B9C, #$8EAA, #$91C5, - #$947D, #$947E, #$947C, #$9C77, #$9C78, #$9EF7, #$8C54, #$947F, - #$9E1A, #$7228, #$9A6A, #$9B31, #$9E1B, #$9E1E, #$7C72, #$30FE, - #$309D, #$309E, #$3005, #$3041, #$3042, #$3043, #$3044, #$3045, - #$3046, #$3047, #$3048, #$3049, #$304A, #$304B, #$304C, #$304D, - #$304E, #$304F, #$3050, #$3051, #$3052, #$3053, #$3054, #$3055, - #$3056, #$3057, #$3058, #$3059, #$305A, #$305B, #$305C, #$305D, - #$305E, #$305F, #$3060, #$3061, #$3062, #$3063, #$3064, #$3065, - #$3066, #$3067, #$3068, #$3069, #$306A, #$306B, #$306C, #$306D, - #$306E, #$306F, #$3070, #$3071, #$3072, #$3073, #$3074, #$3075, - #$3076, #$3077, #$3078, #$3079, #$307A, #$307B, #$307C, #$307D, - #$307E, #$307F, #$3080, #$3081, #$3082, #$3083, #$3084, #$3085, - #$3086, #$3087, #$3088, #$3089, #$308A, #$308B, #$308C, #$308D, - #$308E, #$308F, #$3090, #$3091, #$3092, #$3093, #$30A1, #$30A2, - #$30A3, #$30A4, #$30A5, #$30A6, #$30A7, - #$30A8, #$30A9, #$30AA, #$30AB, #$30AC, #$30AD, #$30AE, #$30AF, - #$30B0, #$30B1, #$30B2, #$30B3, #$30B4, #$30B5, #$30B6, #$30B7, - #$30B8, #$30B9, #$30BA, #$30BB, #$30BC, #$30BD, #$30BE, #$30BF, - #$30C0, #$30C1, #$30C2, #$30C3, #$30C4, #$30C5, #$30C6, #$30C7, - #$30C8, #$30C9, #$30CA, #$30CB, #$30CC, #$30CD, #$30CE, #$30CF, - #$30D0, #$30D1, #$30D2, #$30D3, #$30D4, #$30D5, #$30D6, #$30D7, - #$30D8, #$30D9, #$30DA, #$30DB, #$30DC, #$30DD, #$30DE, #$30DF, - #$30E0, #$30E1, #$30E2, #$30E3, #$30E4, #$30E5, #$30E6, #$30E7, - #$30E8, #$30E9, #$30EA, #$30EB, #$30EC, #$30ED, #$30EE, #$30EF, - #$30F0, #$30F1, #$30F2, #$30F3, #$30F4, #$30F5, #$30F6, #$0414, - #$0415, #$0401, #$0416, #$0417, #$0418, #$0419, #$041A, #$041B, - #$041C, #$0423, #$0424, #$0425, #$0426, #$0427, #$0428, #$0429, - #$042A, #$042B, #$042C, #$042D, #$042E, #$042F, #$0430, #$0431, - #$0432, #$0433, #$0434, #$0435, #$0451, #$0436, #$0437, #$0438, - #$0439, #$043A, #$043B, #$043C, #$043D, #$043E, #$043F, #$0440, - #$0441, #$0442, #$0443, #$0444, #$0445, #$0446, #$0447, #$0448, - #$0449, #$044A, #$044B, #$044C, #$044D, #$044E, #$044F, #$2460, - #$2461, #$2462, #$2463, #$2464, #$2465, #$2466, #$2467, #$2468, - #$2469, #$2474, #$2475, #$2476, #$2477, #$2478, #$2479, #$247A, - #$247B, #$247C, #$247D); - BIG5_2Map: array[0..7651] of TBuffChar = ( - #$4E42, #$4E5C, #$51F5, #$531A, #$5382, #$4E07, #$4E0C, #$4E47, - #$4E8D, #$56D7, #$FA0C, #$5C6E, #$5F73, #$4E0F, #$5187, #$4E0E, - #$4E2E, #$4E93, #$4EC2, #$4EC9, #$4EC8, #$5198, #$52FC, #$536C, - #$53B9, #$5720, #$5903, #$592C, #$5C10, #$5DFF, #$65E1, #$6BB3, - #$6BCC, #$6C14, #$723F, #$4E31, #$4E3C, #$4EE8, #$4EDC, #$4EE9, - #$4EE1, #$4EDD, #$4EDA, #$520C, #$531C, #$534C, #$5722, #$5723, - #$5917, #$592F, #$5B81, #$5B84, #$5C12, #$5C3B, #$5C74, #$5C73, - #$5E04, #$5E80, #$5E82, #$5FC9, #$6209, #$6250, #$6C15, #$6C36, - #$6C43, #$6C3F, #$6C3B, #$72AE, #$72B0, #$738A, #$79B8, #$808A, - #$961E, #$4F0E, #$4F18, #$4F2C, #$4EF5, #$4F14, #$4EF1, #$4F00, - #$4EF7, #$4F08, #$4F1D, #$4F02, #$4F05, #$4F22, #$4F13, #$4F04, - #$4EF4, #$4F12, #$51B1, #$5213, #$5209, #$5210, #$52A6, #$5322, - #$531F, #$534D, #$538A, #$5407, #$56E1, #$56DF, #$572E, #$572A, - #$5734, #$593C, #$5980, #$597C, #$5985, #$597B, #$597E, #$5977, - #$597F, #$5B56, #$5C15, #$5C25, #$5C7C, #$5C7A, #$5C7B, #$5C7E, - #$5DDF, #$5E75, #$5E84, #$5F02, #$5F1A, #$5F74, #$5FD5, #$5FD4, - #$5FCF, #$625C, #$625E, #$6264, #$6261, #$6266, #$6262, #$6259, - #$6260, #$625A, #$6265, #$65EF, #$65EE, #$673E, #$6739, #$6738, - #$673B, #$673A, #$673F, #$673C, #$6733, #$6C18, #$6C46, #$6C52, - #$6C5C, #$6C4F, #$6C4A, #$6C54, #$6C4B, - #$6C4C, #$7071, #$725E, #$72B4, #$72B5, #$738E, #$752A, #$767F, - #$7A75, #$7F51, #$8278, #$827C, #$8280, #$827D, #$827F, #$864D, - #$897E, #$9099, #$9097, #$9098, #$909B, #$9094, #$9622, #$9624, - #$9620, #$9623, #$4F56, #$4F3B, #$4F62, #$4F49, #$4F53, #$4F64, - #$4F3E, #$4F67, #$4F52, #$4F5F, #$4F41, #$4F58, #$4F2D, #$4F33, - #$4F3F, #$4F61, #$518F, #$51B9, #$521C, #$521E, #$5221, #$52AD, - #$52AE, #$5309, #$5363, #$5372, #$538E, #$538F, #$5430, #$5437, - #$542A, #$5454, #$5445, #$5419, #$541C, #$5425, #$5418, #$543D, - #$544F, #$5441, #$5428, #$5424, #$5447, #$56EE, #$56E7, #$56E5, - #$5741, #$5745, #$574C, #$5749, #$574B, #$5752, #$5906, #$5940, - #$59A6, #$5998, #$59A0, #$5997, #$598E, #$59A2, #$5990, #$598F, - #$59A7, #$59A1, #$5B8E, #$5B92, #$5C28, #$5C2A, #$5C8D, #$5C8F, - #$5C88, #$5C8B, #$5C89, #$5C92, #$5C8A, #$5C86, #$5C93, #$5C95, - #$5DE0, #$5E0A, #$5E0E, #$5E8B, #$5E89, #$5E8C, #$5E88, #$5E8D, - #$5F05, #$5F1D, #$5F78, #$5F76, #$5FD2, #$5FD1, #$5FD0, #$5FED, - #$5FE8, #$5FEE, #$5FF3, #$5FE1, #$5FE4, #$5FE3, #$5FFA, #$5FEF, - #$5FF7, #$5FFB, #$6000, #$5FF4, #$623A, #$6283, #$628C, #$628E, - #$628F, #$6294, #$6287, #$6271, #$627B, #$627A, #$6270, #$6281, - #$6288, #$6277, #$627D, #$6272, #$6274, #$6537, #$65F0, #$65F4, - #$65F3, #$65F2, #$65F5, #$6745, #$6747, - #$6759, #$6755, #$674C, #$6748, #$675D, #$674D, #$675A, #$674B, - #$6BD0, #$6C19, #$6C1A, #$6C78, #$6C67, #$6C6B, #$6C84, #$6C8B, - #$6C8F, #$6C71, #$6C6F, #$6C69, #$6C9A, #$6C6D, #$6C87, #$6C95, - #$6C9C, #$6C66, #$6C73, #$6C65, #$6C7B, #$6C8E, #$7074, #$707A, - #$7263, #$72BF, #$72BD, #$72C3, #$72C6, #$72C1, #$72BA, #$72C5, - #$7395, #$7397, #$7393, #$7394, #$7392, #$753A, #$7539, #$7594, - #$7595, #$7681, #$793D, #$8034, #$8095, #$8099, #$8090, #$8092, - #$809C, #$8290, #$828F, #$8285, #$828E, #$8291, #$8293, #$828A, - #$8283, #$8284, #$8C78, #$8FC9, #$8FBF, #$909F, #$90A1, #$90A5, - #$909E, #$90A7, #$90A0, #$9630, #$9628, #$962F, #$962D, #$4E33, - #$4F98, #$4F7C, #$4F85, #$4F7D, #$4F80, #$4F87, #$4F76, #$4F74, - #$4F89, #$4F84, #$4F77, #$4F4C, #$4F97, #$4F6A, #$4F9A, #$4F79, - #$4F81, #$4F78, #$4F90, #$4F9C, #$4F94, #$4F9E, #$4F92, #$4F82, - #$4F95, #$4F6B, #$4F6E, #$519E, #$51BC, #$51BE, #$5235, #$5232, - #$5233, #$5246, #$5231, #$52BC, #$530A, #$530B, #$533C, #$5392, - #$5394, #$5487, #$547F, #$5481, #$5491, #$5482, #$5488, #$546B, - #$547A, #$547E, #$5465, #$546C, #$5474, #$5466, #$548D, #$546F, - #$5461, #$5460, #$5498, #$5463, #$5467, #$5464, #$56F7, #$56F9, - #$576F, #$5772, #$576D, #$576B, #$5771, #$5770, #$5776, #$5780, - #$5775, #$577B, #$5773, #$5774, #$5762, - #$5768, #$577D, #$590C, #$5945, #$59B5, #$59BA, #$59CF, #$59CE, - #$59B2, #$59CC, #$59C1, #$59B6, #$59BC, #$59C3, #$59D6, #$59B1, - #$59BD, #$59C0, #$59C8, #$59B4, #$59C7, #$5B62, #$5B65, #$5B93, - #$5B95, #$5C44, #$5C47, #$5CAE, #$5CA4, #$5CA0, #$5CB5, #$5CAF, - #$5CA8, #$5CAC, #$5C9F, #$5CA3, #$5CAD, #$5CA2, #$5CAA, #$5CA7, - #$5C9D, #$5CA5, #$5CB6, #$5CB0, #$5CA6, #$5E17, #$5E14, #$5E19, - #$5F28, #$5F22, #$5F23, #$5F24, #$5F54, #$5F82, #$5F7E, #$5F7D, - #$5FDE, #$5FE5, #$602D, #$6026, #$6019, #$6032, #$600B, #$6034, - #$600A, #$6017, #$6033, #$601A, #$601E, #$602C, #$6022, #$600D, - #$6010, #$602E, #$6013, #$6011, #$600C, #$6009, #$601C, #$6214, - #$623D, #$62AD, #$62B4, #$62D1, #$62BE, #$62AA, #$62B6, #$62CA, - #$62AE, #$62B3, #$62AF, #$62BB, #$62A9, #$62B0, #$62B8, #$653D, - #$65A8, #$65BB, #$6609, #$65FC, #$6604, #$6612, #$6608, #$65FB, - #$6603, #$660B, #$660D, #$6605, #$65FD, #$6611, #$6610, #$66F6, - #$670A, #$6785, #$676C, #$678E, #$6792, #$6776, #$677B, #$6798, - #$6786, #$6784, #$6774, #$678D, #$678C, #$677A, #$679F, #$6791, - #$6799, #$6783, #$677D, #$6781, #$6778, #$6779, #$6794, #$6B25, - #$6B80, #$6B7E, #$6BDE, #$6C1D, #$6C93, #$6CEC, #$6CEB, #$6CEE, - #$6CD9, #$6CB6, #$6CD4, #$6CAD, #$6CE7, #$6CB7, #$6CD0, #$6CC2, - #$6CBA, #$6CC3, #$6CC6, #$6CED, #$6CF2, - #$6CD2, #$6CDD, #$6CB4, #$6C8A, #$6C9D, #$6C80, #$6CDE, #$6CC0, - #$6D30, #$6CCD, #$6CC7, #$6CB0, #$6CF9, #$6CCF, #$6CE9, #$6CD1, - #$7094, #$7098, #$7085, #$7093, #$7086, #$7084, #$7091, #$7096, - #$7082, #$709A, #$7083, #$726A, #$72D6, #$72CB, #$72D8, #$72C9, - #$72DC, #$72D2, #$72D4, #$72DA, #$72CC, #$72D1, #$73A4, #$73A1, - #$73AD, #$73A6, #$73A2, #$73A0, #$73AC, #$739D, #$74DD, #$74E8, - #$753F, #$7540, #$753E, #$758C, #$7598, #$76AF, #$76F3, #$76F1, - #$76F0, #$76F5, #$77F8, #$77FC, #$77F9, #$77FB, #$77FA, #$77F7, - #$7942, #$793F, #$79C5, #$7A78, #$7A7B, #$7AFB, #$7C75, #$7CFD, - #$8035, #$808F, #$80AE, #$80A3, #$80B8, #$80B5, #$80AD, #$8220, - #$82A0, #$82C0, #$82AB, #$829A, #$8298, #$829B, #$82B5, #$82A7, - #$82AE, #$82BC, #$829E, #$82BA, #$82B4, #$82A8, #$82A1, #$82A9, - #$82C2, #$82A4, #$82C3, #$82B6, #$82A2, #$8670, #$866F, #$866D, - #$866E, #$8C56, #$8FD2, #$8FCB, #$8FD3, #$8FCD, #$8FD6, #$8FD5, - #$8FD7, #$90B2, #$90B4, #$90AF, #$90B3, #$90B0, #$9639, #$963D, - #$963C, #$963A, #$9643, #$4FCD, #$4FC5, #$4FD3, #$4FB2, #$4FC9, - #$4FCB, #$4FC1, #$4FD4, #$4FDC, #$4FD9, #$4FBB, #$4FB3, #$4FDB, - #$4FC7, #$4FD6, #$4FBA, #$4FC0, #$4FB9, #$4FEC, #$5244, #$5249, - #$52C0, #$52C2, #$533D, #$537C, #$5397, #$5396, #$5399, #$5398, - #$54BA, #$54A1, #$54AD, #$54A5, #$54CF, - #$54C3, #$830D, #$54B7, #$54AE, #$54D6, #$54B6, #$54C5, #$54C6, - #$54A0, #$5470, #$54BC, #$54A2, #$54BE, #$5472, #$54DE, #$54B0, - #$57B5, #$579E, #$579F, #$57A4, #$578C, #$5797, #$579D, #$579B, - #$5794, #$5798, #$578F, #$5799, #$57A5, #$579A, #$5795, #$58F4, - #$590D, #$5953, #$59E1, #$59DE, #$59EE, #$5A00, #$59F1, #$59DD, - #$59FA, #$59FD, #$59FC, #$59F6, #$59E4, #$59F2, #$59F7, #$59DB, - #$59E9, #$59F3, #$59F5, #$59E0, #$59FE, #$59F4, #$59ED, #$5BA8, - #$5C4C, #$5CD0, #$5CD8, #$5CCC, #$5CD7, #$5CCB, #$5CDB, #$5CDE, - #$5CDA, #$5CC9, #$5CC7, #$5CCA, #$5CD6, #$5CD3, #$5CD4, #$5CCF, - #$5CC8, #$5CC6, #$5CCE, #$5CDF, #$5CF8, #$5DF9, #$5E21, #$5E22, - #$5E23, #$5E20, #$5E24, #$5EB0, #$5EA4, #$5EA2, #$5E9B, #$5EA3, - #$5EA5, #$5F07, #$5F2E, #$5F56, #$5F86, #$6037, #$6039, #$6054, - #$6072, #$605E, #$6045, #$6053, #$6047, #$6049, #$605B, #$604C, - #$6040, #$6042, #$605F, #$6024, #$6044, #$6058, #$6066, #$606E, - #$6242, #$6243, #$62CF, #$630D, #$630B, #$62F5, #$630E, #$6303, - #$62EB, #$62F9, #$630F, #$630C, #$62F8, #$62F6, #$6300, #$6313, - #$6314, #$62FA, #$6315, #$62FB, #$62F0, #$6541, #$6543, #$65AA, - #$65BF, #$6636, #$6621, #$6632, #$6635, #$661C, #$6626, #$6622, - #$6633, #$662B, #$663A, #$661D, #$6634, #$6639, #$662E, #$670F, - #$6710, #$67C1, #$67F2, #$67C8, #$67BA, - #$67DC, #$67BB, #$67F8, #$67D8, #$67C0, #$67B7, #$67C5, #$67EB, - #$67E4, #$67DF, #$67B5, #$67CD, #$67B3, #$67F7, #$67F6, #$67EE, - #$67E3, #$67C2, #$67B9, #$67CE, #$67E7, #$67F0, #$67B2, #$67FC, - #$67C6, #$67ED, #$67CC, #$67AE, #$67E6, #$67DB, #$67FA, #$67C9, - #$67CA, #$67C3, #$67EA, #$67CB, #$6B28, #$6B82, #$6B84, #$6BB6, - #$6BD6, #$6BD8, #$6BE0, #$6C20, #$6C21, #$6D28, #$6D34, #$6D2D, - #$6D1F, #$6D3C, #$6D3F, #$6D12, #$6D0A, #$6CDA, #$6D33, #$6D04, - #$6D19, #$6D3A, #$6D1A, #$6D11, #$6D00, #$6D1D, #$6D42, #$6D01, - #$6D18, #$6D37, #$6D03, #$6D0F, #$6D40, #$6D07, #$6D20, #$6D2C, - #$6D08, #$6D22, #$6D09, #$6D10, #$70B7, #$709F, #$70BE, #$70B1, - #$70B0, #$70A1, #$70B4, #$70B5, #$70A9, #$7241, #$7249, #$724A, - #$726C, #$7270, #$7273, #$726E, #$72CA, #$72E4, #$72E8, #$72EB, - #$72DF, #$72EA, #$72E6, #$72E3, #$7385, #$73CC, #$73C2, #$73C8, - #$73C5, #$73B9, #$73B6, #$73B5, #$73B4, #$73EB, #$73BF, #$73C7, - #$73BE, #$73C3, #$73C6, #$73B8, #$73CB, #$74EC, #$74EE, #$752E, - #$7547, #$7548, #$75A7, #$75AA, #$7679, #$76C4, #$7708, #$7703, - #$7704, #$7705, #$770A, #$76F7, #$76FB, #$76FA, #$77E7, #$77E8, - #$7806, #$7811, #$7812, #$7805, #$7810, #$780F, #$780E, #$7809, - #$7803, #$7813, #$794A, #$794C, #$794B, #$7945, #$7944, #$79D5, - #$79CD, #$79CF, #$79D6, #$79CE, #$7A80, - #$7A7E, #$7AD1, #$7B00, #$7B01, #$7C7A, #$7C78, #$7C79, #$7C7F, - #$7C80, #$7C81, #$7D03, #$7D08, #$7D01, #$7F58, #$7F91, #$7F8D, - #$7FBE, #$8007, #$800E, #$800F, #$8014, #$8037, #$80D8, #$80C7, - #$80E0, #$80D1, #$80C8, #$80C2, #$80D0, #$80C5, #$80E3, #$80D9, - #$80DC, #$80CA, #$80D5, #$80C9, #$80CF, #$80D7, #$80E6, #$80CD, - #$81FF, #$8221, #$8294, #$82D9, #$82FE, #$82F9, #$8307, #$82E8, - #$8300, #$82D5, #$833A, #$82EB, #$82D6, #$82F4, #$82EC, #$82E1, - #$82F2, #$82F5, #$830C, #$82FB, #$82F6, #$82F0, #$82EA, #$82E4, - #$82E0, #$82FA, #$82F3, #$82ED, #$8677, #$8674, #$867C, #$8673, - #$8841, #$884E, #$8867, #$886A, #$8869, #$89D3, #$8A04, #$8A07, - #$8D72, #$8FE3, #$8FE1, #$8FEE, #$8FE0, #$90F1, #$90BD, #$90BF, - #$90D5, #$90C5, #$90BE, #$90C7, #$90CB, #$90C8, #$91D4, #$91D3, - #$9654, #$964F, #$9651, #$9653, #$964A, #$964E, #$501E, #$5005, - #$5007, #$5013, #$5022, #$5030, #$501B, #$4FF5, #$4FF4, #$5033, - #$5037, #$502C, #$4FF6, #$4FF7, #$5017, #$501C, #$5020, #$5027, - #$5035, #$502F, #$5031, #$500E, #$515A, #$5194, #$5193, #$51CA, - #$51C4, #$51C5, #$51C8, #$51CE, #$5261, #$525A, #$5252, #$525E, - #$525F, #$5255, #$5262, #$52CD, #$530E, #$539E, #$5526, #$54E2, - #$5517, #$5512, #$54E7, #$54F3, #$54E4, #$551A, #$54FF, #$5504, - #$5508, #$54EB, #$5511, #$5505, #$54F1, - #$550A, #$54FB, #$54F7, #$54F8, #$54E0, #$550E, #$5503, #$550B, - #$5701, #$5702, #$57CC, #$5832, #$57D5, #$57D2, #$57BA, #$57C6, - #$57BD, #$57BC, #$57B8, #$57B6, #$57BF, #$57C7, #$57D0, #$57B9, - #$57C1, #$590E, #$594A, #$5A19, #$5A16, #$5A2D, #$5A2E, #$5A15, - #$5A0F, #$5A17, #$5A0A, #$5A1E, #$5A33, #$5B6C, #$5BA7, #$5BAD, - #$5BAC, #$5C03, #$5C56, #$5C54, #$5CEC, #$5CFF, #$5CEE, #$5CF1, - #$5CF7, #$5D00, #$5CF9, #$5E29, #$5E28, #$5EA8, #$5EAE, #$5EAA, - #$5EAC, #$5F33, #$5F30, #$5F67, #$605D, #$605A, #$6067, #$6041, - #$60A2, #$6088, #$6080, #$6092, #$6081, #$609D, #$6083, #$6095, - #$609B, #$6097, #$6087, #$609C, #$608E, #$6219, #$6246, #$62F2, - #$6310, #$6356, #$632C, #$6344, #$6345, #$6336, #$6343, #$63E4, - #$6339, #$634B, #$634A, #$633C, #$6329, #$6341, #$6334, #$6358, - #$6354, #$6359, #$632D, #$6347, #$6333, #$635A, #$6351, #$6338, - #$6357, #$6340, #$6348, #$654A, #$6546, #$65C6, #$65C3, #$65C4, - #$65C2, #$664A, #$665F, #$6647, #$6651, #$6712, #$6713, #$681F, - #$681A, #$6849, #$6832, #$6833, #$683B, #$684B, #$684F, #$6816, - #$6831, #$681C, #$6835, #$682B, #$682D, #$682F, #$684E, #$6844, - #$6834, #$681D, #$6812, #$6814, #$6826, #$6828, #$682E, #$684D, - #$683A, #$6825, #$6820, #$6B2C, #$6B2F, #$6B2D, #$6B31, #$6B34, - #$6B6D, #$8082, #$6B88, #$6BE6, #$6BE4, - #$6BE8, #$6BE3, #$6BE2, #$6BE7, #$6C25, #$6D7A, #$6D63, #$6D64, - #$6D76, #$6D0D, #$6D61, #$6D92, #$6D58, #$6D62, #$6D6D, #$6D6F, - #$6D91, #$6D8D, #$6DEF, #$6D7F, #$6D86, #$6D5E, #$6D67, #$6D60, - #$6D97, #$6D70, #$6D7C, #$6D5F, #$6D82, #$6D98, #$6D2F, #$6D68, - #$6D8B, #$6D7E, #$6D80, #$6D84, #$6D16, #$6D83, #$6D7B, #$6D7D, - #$6D75, #$6D90, #$70DC, #$70D3, #$70D1, #$70DD, #$70CB, #$7F39, - #$70E2, #$70D7, #$70D2, #$70DE, #$70E0, #$70D4, #$70CD, #$70C5, - #$70C6, #$70C7, #$70DA, #$70CE, #$70E1, #$7242, #$7278, #$7277, - #$7276, #$7300, #$72FA, #$72F4, #$72FE, #$72F6, #$72F3, #$72FB, - #$7301, #$73D3, #$73D9, #$73E5, #$73D6, #$73BC, #$73E7, #$73E3, - #$73E9, #$73DC, #$73D2, #$73DB, #$73D4, #$73DD, #$73DA, #$73D7, - #$73D8, #$73E8, #$74DE, #$74DF, #$74F4, #$74F5, #$7521, #$755B, - #$755F, #$75B0, #$75C1, #$75BB, #$75C4, #$75C0, #$75BF, #$75B6, - #$75BA, #$768A, #$76C9, #$771D, #$771B, #$7710, #$7713, #$7712, - #$7723, #$7711, #$7715, #$7719, #$771A, #$7722, #$7727, #$7823, - #$782C, #$7822, #$7835, #$782F, #$7828, #$782E, #$782B, #$7821, - #$7829, #$7833, #$782A, #$7831, #$7954, #$795B, #$794F, #$795C, - #$7953, #$7952, #$7951, #$79EB, #$79EC, #$79E0, #$79EE, #$79ED, - #$79EA, #$79DC, #$79DE, #$79DD, #$7A86, #$7A89, #$7A85, #$7A8B, - #$7A8C, #$7A8A, #$7A87, #$7AD8, #$7B10, - #$7B04, #$7B13, #$7B05, #$7B0F, #$7B08, #$7B0A, #$7B0E, #$7B09, - #$7B12, #$7C84, #$7C91, #$7C8A, #$7C8C, #$7C88, #$7C8D, #$7C85, - #$7D1E, #$7D1D, #$7D11, #$7D0E, #$7D18, #$7D16, #$7D13, #$7D1F, - #$7D12, #$7D0F, #$7D0C, #$7F5C, #$7F61, #$7F5E, #$7F60, #$7F5D, - #$7F5B, #$7F96, #$7F92, #$7FC3, #$7FC2, #$7FC0, #$8016, #$803E, - #$8039, #$80FA, #$80F2, #$80F9, #$80F5, #$8101, #$80FB, #$8100, - #$8201, #$822F, #$8225, #$8333, #$832D, #$8344, #$8319, #$8351, - #$8325, #$8356, #$833F, #$8341, #$8326, #$831C, #$8322, #$8342, - #$834E, #$831B, #$832A, #$8308, #$833C, #$834D, #$8316, #$8324, - #$8320, #$8337, #$832F, #$8329, #$8347, #$8345, #$834C, #$8353, - #$831E, #$832C, #$834B, #$8327, #$8348, #$8653, #$8652, #$86A2, - #$86A8, #$8696, #$868D, #$8691, #$869E, #$8687, #$8697, #$8686, - #$868B, #$869A, #$8685, #$86A5, #$8699, #$86A1, #$86A7, #$8695, - #$8698, #$868E, #$869D, #$8690, #$8694, #$8843, #$8844, #$886D, - #$8875, #$8876, #$8872, #$8880, #$8871, #$887F, #$886F, #$8883, - #$887E, #$8874, #$887C, #$8A12, #$8C47, #$8C57, #$8C7B, #$8CA4, - #$8CA3, #$8D76, #$8D78, #$8DB5, #$8DB7, #$8DB6, #$8ED1, #$8ED3, - #$8FFE, #$8FF5, #$9002, #$8FFF, #$8FFB, #$9004, #$8FFC, #$8FF6, - #$90D6, #$90E0, #$90D9, #$90DA, #$90E3, #$90DF, #$90E5, #$90D8, - #$90DB, #$90D7, #$90DC, #$90E4, #$9150, - #$914E, #$914F, #$91D5, #$91E2, #$91DA, #$965C, #$965F, #$96BC, - #$98E3, #$9ADF, #$9B2F, #$4E7F, #$5070, #$506A, #$5061, #$505E, - #$5060, #$5053, #$504B, #$505D, #$5072, #$5048, #$504D, #$5041, - #$505B, #$504A, #$5062, #$5015, #$5045, #$505F, #$5069, #$506B, - #$5063, #$5064, #$5046, #$5040, #$506E, #$5073, #$5057, #$5051, - #$51D0, #$526B, #$526D, #$526C, #$526E, #$52D6, #$52D3, #$532D, - #$539C, #$5575, #$5576, #$553C, #$554D, #$5550, #$5534, #$552A, - #$5551, #$5562, #$5536, #$5535, #$5530, #$5552, #$5545, #$550C, - #$5532, #$5565, #$554E, #$5539, #$5548, #$552D, #$553B, #$5540, - #$554B, #$570A, #$5707, #$57FB, #$5814, #$57E2, #$57F6, #$57DC, - #$57F4, #$5800, #$57ED, #$57FD, #$5808, #$57F8, #$580B, #$57F3, - #$57CF, #$5807, #$57EE, #$57E3, #$57F2, #$57E5, #$57EC, #$57E1, - #$580E, #$57FC, #$5810, #$57E7, #$5801, #$580C, #$57F1, #$57E9, - #$57F0, #$580D, #$5804, #$595C, #$5A60, #$5A58, #$5A55, #$5A67, - #$5A5E, #$5A38, #$5A35, #$5A6D, #$5A50, #$5A5F, #$5A65, #$5A6C, - #$5A53, #$5A64, #$5A57, #$5A43, #$5A5D, #$5A52, #$5A44, #$5A5B, - #$5A48, #$5A8E, #$5A3E, #$5A4D, #$5A39, #$5A4C, #$5A70, #$5A69, - #$5A47, #$5A51, #$5A56, #$5A42, #$5A5C, #$5B72, #$5B6E, #$5BC1, - #$5BC0, #$5C59, #$5D1E, #$5D0B, #$5D1D, #$5D1A, #$5D20, #$5D0C, - #$5D28, #$5D0D, #$5D26, #$5D25, #$5D0F, - #$5D30, #$5D12, #$5D23, #$5D1F, #$5D2E, #$5E3E, #$5E34, #$5EB1, - #$5EB4, #$5EB9, #$5EB2, #$5EB3, #$5F36, #$5F38, #$5F9B, #$5F96, - #$5F9F, #$608A, #$6090, #$6086, #$60BE, #$60B0, #$60BA, #$60D3, - #$60D4, #$60CF, #$60E4, #$60D9, #$60DD, #$60C8, #$60B1, #$60DB, - #$60B7, #$60CA, #$60BF, #$60C3, #$60CD, #$60C0, #$6332, #$6365, - #$638A, #$6382, #$637D, #$63BD, #$639E, #$63AD, #$639D, #$6397, - #$63AB, #$638E, #$636F, #$6387, #$6390, #$636E, #$63AF, #$6375, - #$639C, #$636D, #$63AE, #$637C, #$63A4, #$633B, #$639F, #$6378, - #$6385, #$6381, #$6391, #$638D, #$6370, #$6553, #$65CD, #$6665, - #$6661, #$665B, #$6659, #$665C, #$6662, #$6718, #$6879, #$6887, - #$6890, #$689C, #$686D, #$686E, #$68AE, #$68AB, #$6956, #$686F, - #$68A3, #$68AC, #$68A9, #$6875, #$6874, #$68B2, #$688F, #$6877, - #$6892, #$687C, #$686B, #$6872, #$68AA, #$6880, #$6871, #$687E, - #$689B, #$6896, #$688B, #$68A0, #$6889, #$68A4, #$6878, #$687B, - #$6891, #$688C, #$688A, #$687D, #$6B36, #$6B33, #$6B37, #$6B38, - #$6B91, #$6B8F, #$6B8D, #$6B8E, #$6B8C, #$6C2A, #$6DC0, #$6DAB, - #$6DB4, #$6DB3, #$6E74, #$6DAC, #$6DE9, #$6DE2, #$6DB7, #$6DF6, - #$6DD4, #$6E00, #$6DC8, #$6DE0, #$6DDF, #$6DD6, #$6DBE, #$6DE5, - #$6DDC, #$6DDD, #$6DDB, #$6DF4, #$6DCA, #$6DBD, #$6DED, #$6DF0, - #$6DBA, #$6DD5, #$6DC2, #$6DCF, #$6DC9, - #$6DD0, #$6DF2, #$6DD3, #$6DFD, #$6DD7, #$6DCD, #$6DE3, #$6DBB, - #$70FA, #$710D, #$70F7, #$7117, #$70F4, #$710C, #$70F0, #$7104, - #$70F3, #$7110, #$70FC, #$70FF, #$7106, #$7113, #$7100, #$70F8, - #$70F6, #$710B, #$7102, #$710E, #$727E, #$727B, #$727C, #$727F, - #$731D, #$7317, #$7307, #$7311, #$7318, #$730A, #$7308, #$72FF, - #$730F, #$731E, #$7388, #$73F6, #$73F8, #$73F5, #$7404, #$7401, - #$73FD, #$7407, #$7400, #$73FA, #$73FC, #$73FF, #$740C, #$740B, - #$73F4, #$7408, #$7564, #$7563, #$75CE, #$75D2, #$75CF, #$75CB, - #$75CC, #$75D1, #$75D0, #$768F, #$7689, #$76D3, #$7739, #$772F, - #$772D, #$7731, #$7732, #$7734, #$7733, #$773D, #$7725, #$773B, - #$7735, #$7848, #$7852, #$7849, #$784D, #$784A, #$784C, #$7826, - #$7845, #$7850, #$7964, #$7967, #$7969, #$796A, #$7963, #$796B, - #$7961, #$79BB, #$79FA, #$79F8, #$79F6, #$79F7, #$7A8F, #$7A94, - #$7A90, #$7B35, #$7B47, #$7B34, #$7B25, #$7B30, #$7B22, #$7B24, - #$7B33, #$7B18, #$7B2A, #$7B1D, #$7B31, #$7B2B, #$7B2D, #$7B2F, - #$7B32, #$7B38, #$7B1A, #$7B23, #$7C94, #$7C98, #$7C96, #$7CA3, - #$7D35, #$7D3D, #$7D38, #$7D36, #$7D3A, #$7D45, #$7D2C, #$7D29, - #$7D41, #$7D47, #$7D3E, #$7D3F, #$7D4A, #$7D3B, #$7D28, #$7F63, - #$7F95, #$7F9C, #$7F9D, #$7F9B, #$7FCA, #$7FCB, #$7FCD, #$7FD0, - #$7FD1, #$7FC7, #$7FCF, #$7FC9, #$801F, - #$801E, #$801B, #$8047, #$8043, #$8048, #$8118, #$8125, #$8119, - #$811B, #$812D, #$811F, #$812C, #$811E, #$8121, #$8115, #$8127, - #$811D, #$8122, #$8211, #$8238, #$8233, #$823A, #$8234, #$8232, - #$8274, #$8390, #$83A3, #$83A8, #$838D, #$837A, #$8373, #$83A4, - #$8374, #$838F, #$8381, #$8395, #$8399, #$8375, #$8394, #$83A9, - #$837D, #$8383, #$838C, #$839D, #$839B, #$83AA, #$838B, #$837E, - #$83A5, #$83AF, #$8388, #$8397, #$83B0, #$837F, #$83A6, #$8387, - #$83AE, #$8376, #$839A, #$8659, #$8656, #$86BF, #$86B7, #$86C2, - #$86C1, #$86C5, #$86BA, #$86B0, #$86C8, #$86B9, #$86B3, #$86B8, - #$86CC, #$86B4, #$86BB, #$86BC, #$86C3, #$86BD, #$86BE, #$8852, - #$8889, #$8895, #$88A8, #$88A2, #$88AA, #$889A, #$8891, #$88A1, - #$889F, #$8898, #$88A7, #$8899, #$889B, #$8897, #$88A4, #$88AC, - #$888C, #$8893, #$888E, #$8982, #$89D6, #$89D9, #$89D5, #$8A30, - #$8A27, #$8A2C, #$8A1E, #$8C39, #$8C3B, #$8C5C, #$8C5D, #$8C7D, - #$8CA5, #$8D7D, #$8D7B, #$8D79, #$8DBC, #$8DC2, #$8DB9, #$8DBF, - #$8DC1, #$8ED8, #$8EDE, #$8EDD, #$8EDC, #$8ED7, #$8EE0, #$8EE1, - #$9024, #$900B, #$9011, #$901C, #$900C, #$9021, #$90EF, #$90EA, - #$90F0, #$90F4, #$90F2, #$90F3, #$90D4, #$90EB, #$90EC, #$90E9, - #$9156, #$9158, #$915A, #$9153, #$9155, #$91EC, #$91F4, #$91F1, - #$91F3, #$91F8, #$91E4, #$91F9, #$91EA, - #$91EB, #$91F7, #$91E8, #$91EE, #$957A, #$9586, #$9588, #$967C, - #$966D, #$966B, #$9671, #$966F, #$96BF, #$976A, #$9804, #$98E5, - #$9997, #$509B, #$5095, #$5094, #$509E, #$508B, #$50A3, #$5083, - #$508C, #$508E, #$509D, #$5068, #$509C, #$5092, #$5082, #$5087, - #$515F, #$51D4, #$5312, #$5311, #$53A4, #$53A7, #$5591, #$55A8, - #$55A5, #$55AD, #$5577, #$5645, #$55A2, #$5593, #$5588, #$558F, - #$55B5, #$5581, #$55A3, #$5592, #$55A4, #$557D, #$558C, #$55A6, - #$557F, #$5595, #$55A1, #$558E, #$570C, #$5829, #$5837, #$5819, - #$581E, #$5827, #$5823, #$5828, #$57F5, #$5848, #$5825, #$581C, - #$581B, #$5833, #$583F, #$5836, #$582E, #$5839, #$5838, #$582D, - #$582C, #$583B, #$5961, #$5AAF, #$5A94, #$5A9F, #$5A7A, #$5AA2, - #$5A9E, #$5A78, #$5AA6, #$5A7C, #$5AA5, #$5AAC, #$5A95, #$5AAE, - #$5A37, #$5A84, #$5A8A, #$5A97, #$5A83, #$5A8B, #$5AA9, #$5A7B, - #$5A7D, #$5A8C, #$5A9C, #$5A8F, #$5A93, #$5A9D, #$5BEA, #$5BCD, - #$5BCB, #$5BD4, #$5BD1, #$5BCA, #$5BCE, #$5C0C, #$5C30, #$5D37, - #$5D43, #$5D6B, #$5D41, #$5D4B, #$5D3F, #$5D35, #$5D51, #$5D4E, - #$5D55, #$5D33, #$5D3A, #$5D52, #$5D3D, #$5D31, #$5D59, #$5D42, - #$5D39, #$5D49, #$5D38, #$5D3C, #$5D32, #$5D36, #$5D40, #$5D45, - #$5E44, #$5E41, #$5F58, #$5FA6, #$5FA5, #$5FAB, #$60C9, #$60B9, - #$60CC, #$60E2, #$60CE, #$60C4, #$6114, - #$60F2, #$610A, #$6116, #$6105, #$60F5, #$6113, #$60F8, #$60FC, - #$60FE, #$60C1, #$6103, #$6118, #$611D, #$6110, #$60FF, #$6104, - #$610B, #$624A, #$6394, #$63B1, #$63B0, #$63CE, #$63E5, #$63E8, - #$63EF, #$63C3, #$649D, #$63F3, #$63CA, #$63E0, #$63F6, #$63D5, - #$63F2, #$63F5, #$6461, #$63DF, #$63BE, #$63DD, #$63DC, #$63C4, - #$63D8, #$63D3, #$63C2, #$63C7, #$63CC, #$63CB, #$63C8, #$63F0, - #$63D7, #$63D9, #$6532, #$6567, #$656A, #$6564, #$655C, #$6568, - #$6565, #$658C, #$659D, #$659E, #$65AE, #$65D0, #$65D2, #$667C, - #$666C, #$667B, #$6680, #$6671, #$6679, #$666A, #$6672, #$6701, - #$690C, #$68D3, #$6904, #$68DC, #$692A, #$68EC, #$68EA, #$68F1, - #$690F, #$68D6, #$68F7, #$68EB, #$68E4, #$68F6, #$6913, #$6910, - #$68F3, #$68E1, #$6907, #$68CC, #$6908, #$6970, #$68B4, #$6911, - #$68EF, #$68C6, #$6914, #$68F8, #$68D0, #$68FD, #$68FC, #$68E8, - #$690B, #$690A, #$6917, #$68CE, #$68C8, #$68DD, #$68DE, #$68E6, - #$68F4, #$68D1, #$6906, #$68D4, #$68E9, #$6915, #$6925, #$68C7, - #$6B39, #$6B3B, #$6B3F, #$6B3C, #$6B94, #$6B97, #$6B99, #$6B95, - #$6BBD, #$6BF0, #$6BF2, #$6BF3, #$6C30, #$6DFC, #$6E46, #$6E47, - #$6E1F, #$6E49, #$6E88, #$6E3C, #$6E3D, #$6E45, #$6E62, #$6E2B, - #$6E3F, #$6E41, #$6E5D, #$6E73, #$6E1C, #$6E33, #$6E4B, #$6E40, - #$6E51, #$6E3B, #$6E03, #$6E2E, #$6E5E, - #$6E68, #$6E5C, #$6E61, #$6E31, #$6E28, #$6E60, #$6E71, #$6E6B, - #$6E39, #$6E22, #$6E30, #$6E53, #$6E65, #$6E27, #$6E78, #$6E64, - #$6E77, #$6E55, #$6E79, #$6E52, #$6E66, #$6E35, #$6E36, #$6E5A, - #$7120, #$711E, #$712F, #$70FB, #$712E, #$7131, #$7123, #$7125, - #$7122, #$7132, #$711F, #$7128, #$713A, #$711B, #$724B, #$725A, - #$7288, #$7289, #$7286, #$7285, #$728B, #$7312, #$730B, #$7330, - #$7322, #$7331, #$7333, #$7327, #$7332, #$732D, #$7326, #$7323, - #$7335, #$730C, #$742E, #$742C, #$7430, #$742B, #$7416, #$741A, - #$7421, #$742D, #$7431, #$7424, #$7423, #$741D, #$7429, #$7420, - #$7432, #$74FB, #$752F, #$756F, #$756C, #$75E7, #$75DA, #$75E1, - #$75E6, #$75DD, #$75DF, #$75E4, #$75D7, #$7695, #$7692, #$76DA, - #$7746, #$7747, #$7744, #$774D, #$7745, #$774A, #$774E, #$774B, - #$774C, #$77DE, #$77EC, #$7860, #$7864, #$7865, #$785C, #$786D, - #$7871, #$786A, #$786E, #$7870, #$7869, #$7868, #$785E, #$7862, - #$7974, #$7973, #$7972, #$7970, #$7A02, #$7A0A, #$7A03, #$7A0C, - #$7A04, #$7A99, #$7AE6, #$7AE4, #$7B4A, #$7B3B, #$7B44, #$7B48, - #$7B4C, #$7B4E, #$7B40, #$7B58, #$7B45, #$7CA2, #$7C9E, #$7CA8, - #$7CA1, #$7D58, #$7D6F, #$7D63, #$7D53, #$7D56, #$7D67, #$7D6A, - #$7D4F, #$7D6D, #$7D5C, #$7D6B, #$7D52, #$7D54, #$7D69, #$7D51, - #$7D5F, #$7D4E, #$7F3E, #$7F3F, #$7F65, - #$7F66, #$7FA2, #$7FA0, #$7FA1, #$7FD7, #$8051, #$804F, #$8050, - #$80FE, #$80D4, #$8143, #$814A, #$8152, #$814F, #$8147, #$813D, - #$814D, #$813A, #$81E6, #$81EE, #$81F7, #$81F8, #$81F9, #$8204, - #$823C, #$823D, #$823F, #$8275, #$833B, #$83CF, #$83F9, #$8423, - #$83C0, #$83E8, #$8412, #$83E7, #$83E4, #$83FC, #$83F6, #$8410, - #$83C6, #$83C8, #$83EB, #$83E3, #$83BF, #$8401, #$83DD, #$83E5, - #$83D8, #$83FF, #$83E1, #$83CB, #$83CE, #$83D6, #$83F5, #$83C9, - #$8409, #$840F, #$83DE, #$8411, #$8406, #$83C2, #$83F3, #$83D5, - #$83FA, #$83C7, #$83D1, #$83EA, #$8413, #$83C3, #$83EC, #$83EE, - #$83C4, #$83FB, #$83D7, #$83E2, #$841B, #$83DB, #$83FE, #$86D8, - #$86E2, #$86E6, #$86D3, #$86E3, #$86DA, #$86EA, #$86DD, #$86EB, - #$86DC, #$86EC, #$86E9, #$86D7, #$86E8, #$86D1, #$8848, #$8856, - #$8855, #$88BA, #$88D7, #$88B9, #$88B8, #$88C0, #$88BE, #$88B6, - #$88BC, #$88B7, #$88BD, #$88B2, #$8901, #$88C9, #$8995, #$8998, - #$8997, #$89DD, #$89DA, #$89DB, #$8A4E, #$8A4D, #$8A39, #$8A59, - #$8A40, #$8A57, #$8A58, #$8A44, #$8A45, #$8A52, #$8A48, #$8A51, - #$8A4A, #$8A4C, #$8A4F, #$8C5F, #$8C81, #$8C80, #$8CBA, #$8CBE, - #$8CB0, #$8CB9, #$8CB5, #$8D84, #$8D80, #$8D89, #$8DD8, #$8DD3, - #$8DCD, #$8DC7, #$8DD6, #$8DDC, #$8DCF, #$8DD5, #$8DD9, #$8DC8, - #$8DD7, #$8DC5, #$8EEF, #$8EF7, #$8EFA, - #$8EF9, #$8EE6, #$8EEE, #$8EE5, #$8EF5, #$8EE7, #$8EE8, #$8EF6, - #$8EEB, #$8EF1, #$8EEC, #$8EF4, #$8EE9, #$902D, #$9034, #$902F, - #$9106, #$912C, #$9104, #$90FF, #$90FC, #$9108, #$90F9, #$90FB, - #$9101, #$9100, #$9107, #$9105, #$9103, #$9161, #$9164, #$915F, - #$9162, #$9160, #$9201, #$920A, #$9225, #$9203, #$921A, #$9226, - #$920F, #$920C, #$9200, #$9212, #$91FF, #$91FD, #$9206, #$9204, - #$9227, #$9202, #$921C, #$9224, #$9219, #$9217, #$9205, #$9216, - #$957B, #$958D, #$958C, #$9590, #$9687, #$967E, #$9688, #$9689, - #$9683, #$9680, #$96C2, #$96C8, #$96C3, #$96F1, #$96F0, #$976C, - #$9770, #$976E, #$9807, #$98A9, #$98EB, #$9CE6, #$9EF9, #$4E83, - #$4E84, #$4EB6, #$50BD, #$50BF, #$50C6, #$50AE, #$50C4, #$50CA, - #$50B4, #$50C8, #$50C2, #$50B0, #$50C1, #$50BA, #$50B1, #$50CB, - #$50C9, #$50B6, #$50B8, #$51D7, #$527A, #$5278, #$527B, #$527C, - #$55C3, #$55DB, #$55CC, #$55D0, #$55CB, #$55CA, #$55DD, #$55C0, - #$55D4, #$55C4, #$55E9, #$55BF, #$55D2, #$558D, #$55CF, #$55D5, - #$55E2, #$55D6, #$55C8, #$55F2, #$55CD, #$55D9, #$55C2, #$5714, - #$5853, #$5868, #$5864, #$584F, #$584D, #$5849, #$586F, #$5855, - #$584E, #$585D, #$5859, #$5865, #$585B, #$583D, #$5863, #$5871, - #$58FC, #$5AC7, #$5AC4, #$5ACB, #$5ABA, #$5AB8, #$5AB1, #$5AB5, - #$5AB0, #$5ABF, #$5AC8, #$5ABB, #$5AC6, - #$5AB7, #$5AC0, #$5ACA, #$5AB4, #$5AB6, #$5ACD, #$5AB9, #$5A90, - #$5BD6, #$5BD8, #$5BD9, #$5C1F, #$5C33, #$5D71, #$5D63, #$5D4A, - #$5D65, #$5D72, #$5D6C, #$5D5E, #$5D68, #$5D67, #$5D62, #$5DF0, - #$5E4F, #$5E4E, #$5E4A, #$5E4D, #$5E4B, #$5EC5, #$5ECC, #$5EC6, - #$5ECB, #$5EC7, #$5F40, #$5FAF, #$5FAD, #$60F7, #$6149, #$614A, - #$612B, #$6145, #$6136, #$6132, #$612E, #$6146, #$612F, #$614F, - #$6129, #$6140, #$6220, #$9168, #$6223, #$6225, #$6224, #$63C5, - #$63F1, #$63EB, #$6410, #$6412, #$6409, #$6420, #$6424, #$6433, - #$6443, #$641F, #$6415, #$6418, #$6439, #$6437, #$6422, #$6423, - #$640C, #$6426, #$6430, #$6428, #$6441, #$6435, #$642F, #$640A, - #$641A, #$6440, #$6425, #$6427, #$640B, #$63E7, #$641B, #$642E, - #$6421, #$640E, #$656F, #$6592, #$65D3, #$6686, #$668C, #$6695, - #$6690, #$668B, #$668A, #$6699, #$6694, #$6678, #$6720, #$6966, - #$695F, #$6938, #$694E, #$6962, #$6971, #$693F, #$6945, #$696A, - #$6939, #$6942, #$6957, #$6959, #$697A, #$6948, #$6949, #$6935, - #$696C, #$6933, #$693D, #$6965, #$68F0, #$6978, #$6934, #$6969, - #$6940, #$696F, #$6944, #$6976, #$6958, #$6941, #$6974, #$694C, - #$693B, #$694B, #$6937, #$695C, #$694F, #$6951, #$6932, #$6952, - #$692F, #$697B, #$693C, #$6B46, #$6B45, #$6B43, #$6B42, #$6B48, - #$6B41, #$6B9B, #$FA0D, #$6BFB, #$6BFC, - #$6BF9, #$6BF7, #$6BF8, #$6E9B, #$6ED6, #$6EC8, #$6E8F, #$6EC0, - #$6E9F, #$6E93, #$6E94, #$6EA0, #$6EB1, #$6EB9, #$6EC6, #$6ED2, - #$6EBD, #$6EC1, #$6E9E, #$6EC9, #$6EB7, #$6EB0, #$6ECD, #$6EA6, - #$6ECF, #$6EB2, #$6EBE, #$6EC3, #$6EDC, #$6ED8, #$6E99, #$6E92, - #$6E8E, #$6E8D, #$6EA4, #$6EA1, #$6EBF, #$6EB3, #$6ED0, #$6ECA, - #$6E97, #$6EAE, #$6EA3, #$7147, #$7154, #$7152, #$7163, #$7160, - #$7141, #$715D, #$7162, #$7172, #$7178, #$716A, #$7161, #$7142, - #$7158, #$7143, #$714B, #$7170, #$715F, #$7150, #$7153, #$7144, - #$714D, #$715A, #$724F, #$728D, #$728C, #$7291, #$7290, #$728E, - #$733C, #$7342, #$733B, #$733A, #$7340, #$734A, #$7349, #$7444, - #$744A, #$744B, #$7452, #$7451, #$7457, #$7440, #$744F, #$7450, - #$744E, #$7442, #$7446, #$744D, #$7454, #$74E1, #$74FF, #$74FE, - #$74FD, #$751D, #$7579, #$7577, #$6983, #$75EF, #$760F, #$7603, - #$75F7, #$75FE, #$75FC, #$75F9, #$75F8, #$7610, #$75FB, #$75F6, - #$75ED, #$75F5, #$75FD, #$7699, #$76B5, #$76DD, #$7755, #$775F, - #$7760, #$7752, #$7756, #$775A, #$7769, #$7767, #$7754, #$7759, - #$776D, #$77E0, #$7887, #$789A, #$7894, #$788F, #$7884, #$7895, - #$7885, #$7886, #$78A1, #$7883, #$7879, #$7899, #$7880, #$7896, - #$787B, #$797C, #$7982, #$797D, #$7979, #$7A11, #$7A18, #$7A19, - #$7A12, #$7A17, #$7A15, #$7A22, #$7A13, - #$7A1B, #$7A10, #$7AA3, #$7AA2, #$7A9E, #$7AEB, #$7B66, #$7B64, - #$7B6D, #$7B74, #$7B69, #$7B72, #$7B65, #$7B73, #$7B71, #$7B70, - #$7B61, #$7B78, #$7B76, #$7B63, #$7CB2, #$7CB4, #$7CAF, #$7D88, - #$7D86, #$7D80, #$7D8D, #$7D7F, #$7D85, #$7D7A, #$7D8E, #$7D7B, - #$7D83, #$7D7C, #$7D8C, #$7D94, #$7D84, #$7D7D, #$7D92, #$7F6D, - #$7F6B, #$7F67, #$7F68, #$7F6C, #$7FA6, #$7FA5, #$7FA7, #$7FDB, - #$7FDC, #$8021, #$8164, #$8160, #$8177, #$815C, #$8169, #$815B, - #$8162, #$8172, #$6721, #$815E, #$8176, #$8167, #$816F, #$8144, - #$8161, #$821D, #$8249, #$8244, #$8240, #$8242, #$8245, #$84F1, - #$843F, #$8456, #$8476, #$8479, #$848F, #$848D, #$8465, #$8451, - #$8440, #$8486, #$8467, #$8430, #$844D, #$847D, #$845A, #$8459, - #$8474, #$8473, #$845D, #$8507, #$845E, #$8437, #$843A, #$8434, - #$847A, #$8443, #$8478, #$8432, #$8445, #$8429, #$83D9, #$844B, - #$842F, #$8442, #$842D, #$845F, #$8470, #$8439, #$844E, #$844C, - #$8452, #$846F, #$84C5, #$848E, #$843B, #$8447, #$8436, #$8433, - #$8468, #$847E, #$8444, #$842B, #$8460, #$8454, #$846E, #$8450, - #$870B, #$8704, #$86F7, #$870C, #$86FA, #$86D6, #$86F5, #$874D, - #$86F8, #$870E, #$8709, #$8701, #$86F6, #$870D, #$8705, #$88D6, - #$88CB, #$88CD, #$88CE, #$88DE, #$88DB, #$88DA, #$88CC, #$88D0, - #$8985, #$899B, #$89DF, #$89E5, #$89E4, - #$89E1, #$89E0, #$89E2, #$89DC, #$89E6, #$8A76, #$8A86, #$8A7F, - #$8A61, #$8A3F, #$8A77, #$8A82, #$8A84, #$8A75, #$8A83, #$8A81, - #$8A74, #$8A7A, #$8C3C, #$8C4B, #$8C4A, #$8C65, #$8C64, #$8C66, - #$8C86, #$8C84, #$8C85, #$8CCC, #$8D68, #$8D69, #$8D91, #$8D8C, - #$8D8E, #$8D8F, #$8D8D, #$8D93, #$8D94, #$8D90, #$8D92, #$8DF0, - #$8DE0, #$8DEC, #$8DF1, #$8DEE, #$8DD0, #$8DE9, #$8DE3, #$8DE2, - #$8DE7, #$8DF2, #$8DEB, #$8DF4, #$8F06, #$8EFF, #$8F01, #$8F00, - #$8F05, #$8F07, #$8F08, #$8F02, #$8F0B, #$9052, #$903F, #$9044, - #$9049, #$903D, #$9110, #$910D, #$910F, #$9111, #$9116, #$9114, - #$910B, #$910E, #$916E, #$916F, #$9248, #$9252, #$9230, #$923A, - #$9266, #$9233, #$9265, #$925E, #$9283, #$922E, #$924A, #$9246, - #$926D, #$926C, #$924F, #$9260, #$9267, #$926F, #$9236, #$9261, - #$9270, #$9231, #$9254, #$9263, #$9250, #$9272, #$924E, #$9253, - #$924C, #$9256, #$9232, #$959F, #$959C, #$959E, #$959B, #$9692, - #$9693, #$9691, #$9697, #$96CE, #$96FA, #$96FD, #$96F8, #$96F5, - #$9773, #$9777, #$9778, #$9772, #$980F, #$980D, #$980E, #$98AC, - #$98F6, #$98F9, #$99AF, #$99B2, #$99B0, #$99B5, #$9AAD, #$9AAB, - #$9B5B, #$9CEA, #$9CED, #$9CE7, #$9E80, #$9EFD, #$50E6, #$50D4, - #$50D7, #$50E8, #$50F3, #$50DB, #$50EA, #$50DD, #$50E4, #$50D3, - #$50EC, #$50F0, #$50EF, #$50E3, #$50E0, - #$51D8, #$5280, #$5281, #$52E9, #$52EB, #$5330, #$53AC, #$5627, - #$5615, #$560C, #$5612, #$55FC, #$560F, #$561C, #$5601, #$5613, - #$5602, #$55FA, #$561D, #$5604, #$55FF, #$55F9, #$5889, #$587C, - #$5890, #$5898, #$5886, #$5881, #$587F, #$5874, #$588B, #$587A, - #$5887, #$5891, #$588E, #$5876, #$5882, #$5888, #$587B, #$5894, - #$588F, #$58FE, #$596B, #$5ADC, #$5AEE, #$5AE5, #$5AD5, #$5AEA, - #$5ADA, #$5AED, #$5AEB, #$5AF3, #$5AE2, #$5AE0, #$5ADB, #$5AEC, - #$5ADE, #$5ADD, #$5AD9, #$5AE8, #$5ADF, #$5B77, #$5BE0, #$5BE3, - #$5C63, #$5D82, #$5D80, #$5D7D, #$5D86, #$5D7A, #$5D81, #$5D77, - #$5D8A, #$5D89, #$5D88, #$5D7E, #$5D7C, #$5D8D, #$5D79, #$5D7F, - #$5E58, #$5E59, #$5E53, #$5ED8, #$5ED1, #$5ED7, #$5ECE, #$5EDC, - #$5ED5, #$5ED9, #$5ED2, #$5ED4, #$5F44, #$5F43, #$5F6F, #$5FB6, - #$612C, #$6128, #$6141, #$615E, #$6171, #$6173, #$6152, #$6153, - #$6172, #$616C, #$6180, #$6174, #$6154, #$617A, #$615B, #$6165, - #$613B, #$616A, #$6161, #$6156, #$6229, #$6227, #$622B, #$642B, - #$644D, #$645B, #$645D, #$6474, #$6476, #$6472, #$6473, #$647D, - #$6475, #$6466, #$64A6, #$644E, #$6482, #$645E, #$645C, #$644B, - #$6453, #$6460, #$6450, #$647F, #$643F, #$646C, #$646B, #$6459, - #$6465, #$6477, #$6573, #$65A0, #$66A1, #$66A0, #$669F, #$6705, - #$6704, #$6722, #$69B1, #$69B6, #$69C9, - #$69A0, #$69CE, #$6996, #$69B0, #$69AC, #$69BC, #$6991, #$6999, - #$698E, #$69A7, #$698D, #$69A9, #$69BE, #$69AF, #$69BF, #$69C4, - #$69BD, #$69A4, #$69D4, #$69B9, #$69CA, #$699A, #$69CF, #$69B3, - #$6993, #$69AA, #$69A1, #$699E, #$69D9, #$6997, #$6990, #$69C2, - #$69B5, #$69A5, #$69C6, #$6B4A, #$6B4D, #$6B4B, #$6B9E, #$6B9F, - #$6BA0, #$6BC3, #$6BC4, #$6BFE, #$6ECE, #$6EF5, #$6EF1, #$6F03, - #$6F25, #$6EF8, #$6F37, #$6EFB, #$6F2E, #$6F09, #$6F4E, #$6F19, - #$6F1A, #$6F27, #$6F18, #$6F3B, #$6F12, #$6EED, #$6F0A, #$6F36, - #$6F73, #$6EF9, #$6EEE, #$6F2D, #$6F40, #$6F30, #$6F3C, #$6F35, - #$6EEB, #$6F07, #$6F0E, #$6F43, #$6F05, #$6EFD, #$6EF6, #$6F39, - #$6F1C, #$6EFC, #$6F3A, #$6F1F, #$6F0D, #$6F1E, #$6F08, #$6F21, - #$7187, #$7190, #$7189, #$7180, #$7185, #$7182, #$718F, #$717B, - #$7186, #$7181, #$7197, #$7244, #$7253, #$7297, #$7295, #$7293, - #$7343, #$734D, #$7351, #$734C, #$7462, #$7473, #$7471, #$7475, - #$7472, #$7467, #$746E, #$7500, #$7502, #$7503, #$757D, #$7590, - #$7616, #$7608, #$760C, #$7615, #$7611, #$760A, #$7614, #$76B8, - #$7781, #$777C, #$7785, #$7782, #$776E, #$7780, #$776F, #$777E, - #$7783, #$78B2, #$78AA, #$78B4, #$78AD, #$78A8, #$787E, #$78AB, - #$789E, #$78A5, #$78A0, #$78AC, #$78A2, #$78A4, #$7998, #$798A, - #$798B, #$7996, #$7995, #$7994, #$7993, - #$7997, #$7988, #$7992, #$7990, #$7A2B, #$7A4A, #$7A30, #$7A2F, - #$7A28, #$7A26, #$7AA8, #$7AAB, #$7AAC, #$7AEE, #$7B88, #$7B9C, - #$7B8A, #$7B91, #$7B90, #$7B96, #$7B8D, #$7B8C, #$7B9B, #$7B8E, - #$7B85, #$7B98, #$5284, #$7B99, #$7BA4, #$7B82, #$7CBB, #$7CBF, - #$7CBC, #$7CBA, #$7DA7, #$7DB7, #$7DC2, #$7DA3, #$7DAA, #$7DC1, - #$7DC0, #$7DC5, #$7D9D, #$7DCE, #$7DC4, #$7DC6, #$7DCB, #$7DCC, - #$7DAF, #$7DB9, #$7D96, #$7DBC, #$7D9F, #$7DA6, #$7DAE, #$7DA9, - #$7DA1, #$7DC9, #$7F73, #$7FE2, #$7FE3, #$7FE5, #$7FDE, #$8024, - #$805D, #$805C, #$8189, #$8186, #$8183, #$8187, #$818D, #$818C, - #$818B, #$8215, #$8497, #$84A4, #$84A1, #$849F, #$84BA, #$84CE, - #$84C2, #$84AC, #$84AE, #$84AB, #$84B9, #$84B4, #$84C1, #$84CD, - #$84AA, #$849A, #$84B1, #$84D0, #$849D, #$84A7, #$84BB, #$84A2, - #$8494, #$84C7, #$84CC, #$849B, #$84A9, #$84AF, #$84A8, #$84D6, - #$8498, #$84B6, #$84CF, #$84A0, #$84D7, #$84D4, #$84D2, #$84DB, - #$84B0, #$8491, #$8661, #$8733, #$8723, #$8728, #$876B, #$8740, - #$872E, #$871E, #$8721, #$8719, #$871B, #$8743, #$872C, #$8741, - #$873E, #$8746, #$8720, #$8732, #$872A, #$872D, #$873C, #$8712, - #$873A, #$8731, #$8735, #$8742, #$8726, #$8727, #$8738, #$8724, - #$871A, #$8730, #$8711, #$88F7, #$88E7, #$88F1, #$88F2, #$88FA, - #$88FE, #$88EE, #$88FC, #$88F6, #$88FB, - #$88F0, #$88EC, #$88EB, #$899D, #$89A1, #$899F, #$899E, #$89E9, - #$89EB, #$89E8, #$8AAB, #$8A99, #$8A8B, #$8A92, #$8A8F, #$8A96, - #$8C3D, #$8C68, #$8C69, #$8CD5, #$8CCF, #$8CD7, #$8D96, #$8E09, - #$8E02, #$8DFF, #$8E0D, #$8DFD, #$8E0A, #$8E03, #$8E07, #$8E06, - #$8E05, #$8DFE, #$8E00, #$8E04, #$8F10, #$8F11, #$8F0E, #$8F0D, - #$9123, #$911C, #$9120, #$9122, #$911F, #$911D, #$911A, #$9124, - #$9121, #$911B, #$917A, #$9172, #$9179, #$9173, #$92A5, #$92A4, - #$9276, #$929B, #$927A, #$92A0, #$9294, #$92AA, #$928D, #$92A6, - #$929A, #$92AB, #$9279, #$9297, #$927F, #$92A3, #$92EE, #$928E, - #$9282, #$9295, #$92A2, #$927D, #$9288, #$92A1, #$928A, #$9286, - #$928C, #$9299, #$92A7, #$927E, #$9287, #$92A9, #$929D, #$928B, - #$922D, #$969E, #$96A1, #$96FF, #$9758, #$977D, #$977A, #$977E, - #$9783, #$9780, #$9782, #$977B, #$9784, #$9781, #$977F, #$97CE, - #$97CD, #$9816, #$98AD, #$98AE, #$9902, #$9900, #$9907, #$999D, - #$999C, #$99C3, #$99B9, #$99BB, #$99BA, #$99C2, #$99BD, #$99C7, - #$9AB1, #$9AE3, #$9AE7, #$9B3E, #$9B3F, #$9B60, #$9B61, #$9B5F, - #$9CF1, #$9CF2, #$9CF5, #$9EA7, #$50FF, #$5103, #$5130, #$50F8, - #$5106, #$5107, #$50F6, #$50FE, #$510B, #$510C, #$50FD, #$510A, - #$528B, #$528C, #$52F1, #$52EF, #$5648, #$5642, #$564C, #$5635, - #$5641, #$564A, #$5649, #$5646, #$5658, - #$565A, #$5640, #$5633, #$563D, #$562C, #$563E, #$5638, #$562A, - #$563A, #$571A, #$58AB, #$589D, #$58B1, #$58A0, #$58A3, #$58AF, - #$58AC, #$58A5, #$58A1, #$58FF, #$5AFF, #$5AF4, #$5AFD, #$5AF7, - #$5AF6, #$5B03, #$5AF8, #$5B02, #$5AF9, #$5B01, #$5B07, #$5B05, - #$5B0F, #$5C67, #$5D99, #$5D97, #$5D9F, #$5D92, #$5DA2, #$5D93, - #$5D95, #$5DA0, #$5D9C, #$5DA1, #$5D9A, #$5D9E, #$5E69, #$5E5D, - #$5E60, #$5E5C, #$7DF3, #$5EDB, #$5EDE, #$5EE1, #$5F49, #$5FB2, - #$618B, #$6183, #$6179, #$61B1, #$61B0, #$61A2, #$6189, #$619B, - #$6193, #$61AF, #$61AD, #$619F, #$6192, #$61AA, #$61A1, #$618D, - #$6166, #$61B3, #$622D, #$646E, #$6470, #$6496, #$64A0, #$6485, - #$6497, #$649C, #$648F, #$648B, #$648A, #$648C, #$64A3, #$649F, - #$6468, #$64B1, #$6498, #$6576, #$657A, #$6579, #$657B, #$65B2, - #$65B3, #$66B5, #$66B0, #$66A9, #$66B2, #$66B7, #$66AA, #$66AF, - #$6A00, #$6A06, #$6A17, #$69E5, #$69F8, #$6A15, #$69F1, #$69E4, - #$6A20, #$69FF, #$69EC, #$69E2, #$6A1B, #$6A1D, #$69FE, #$6A27, - #$69F2, #$69EE, #$6A14, #$69F7, #$69E7, #$6A40, #$6A08, #$69E6, - #$69FB, #$6A0D, #$69FC, #$69EB, #$6A09, #$6A04, #$6A18, #$6A25, - #$6A0F, #$69F6, #$6A26, #$6A07, #$69F4, #$6A16, #$6B51, #$6BA5, - #$6BA3, #$6BA2, #$6BA6, #$6C01, #$6C00, #$6BFF, #$6C02, #$6F41, - #$6F26, #$6F7E, #$6F87, #$6FC6, #$6F92, - #$6F8D, #$6F89, #$6F8C, #$6F62, #$6F4F, #$6F85, #$6F5A, #$6F96, - #$6F76, #$6F6C, #$6F82, #$6F55, #$6F72, #$6F52, #$6F50, #$6F57, - #$6F94, #$6F93, #$6F5D, #$6F00, #$6F61, #$6F6B, #$6F7D, #$6F67, - #$6F90, #$6F53, #$6F8B, #$6F69, #$6F7F, #$6F95, #$6F63, #$6F77, - #$6F6A, #$6F7B, #$71B2, #$71AF, #$719B, #$71B0, #$71A0, #$719A, - #$71A9, #$71B5, #$719D, #$71A5, #$719E, #$71A4, #$71A1, #$71AA, - #$719C, #$71A7, #$71B3, #$7298, #$729A, #$7358, #$7352, #$735E, - #$735F, #$7360, #$735D, #$735B, #$7361, #$735A, #$7359, #$7362, - #$7487, #$7489, #$748A, #$7486, #$7481, #$747D, #$7485, #$7488, - #$747C, #$7479, #$7508, #$7507, #$757E, #$7625, #$761E, #$7619, - #$761D, #$761C, #$7623, #$761A, #$7628, #$761B, #$769C, #$769D, - #$769E, #$769B, #$778D, #$778F, #$7789, #$7788, #$78CD, #$78BB, - #$78CF, #$78CC, #$78D1, #$78CE, #$78D4, #$78C8, #$78C3, #$78C4, - #$78C9, #$799A, #$79A1, #$79A0, #$799C, #$79A2, #$799B, #$6B76, - #$7A39, #$7AB2, #$7AB4, #$7AB3, #$7BB7, #$7BCB, #$7BBE, #$7BAC, - #$7BCE, #$7BAF, #$7BB9, #$7BCA, #$7BB5, #$7CC5, #$7CC8, #$7CCC, - #$7CCB, #$7DF7, #$7DDB, #$7DEA, #$7DE7, #$7DD7, #$7DE1, #$7E03, - #$7DFA, #$7DE6, #$7DF6, #$7DF1, #$7DF0, #$7DEE, #$7DDF, #$7F76, - #$7FAC, #$7FB0, #$7FAD, #$7FED, #$7FEB, #$7FEA, #$7FEC, #$7FE6, - #$7FE8, #$8064, #$8067, #$81A3, #$819F, - #$819E, #$8195, #$81A2, #$8199, #$8197, #$8216, #$824F, #$8253, - #$8252, #$8250, #$824E, #$8251, #$8524, #$853B, #$850F, #$8500, - #$8529, #$850E, #$8509, #$850D, #$851F, #$850A, #$8527, #$851C, - #$84FB, #$852B, #$84FA, #$8508, #$850C, #$84F4, #$852A, #$84F2, - #$8515, #$84F7, #$84EB, #$84F3, #$84FC, #$8512, #$84EA, #$84E9, - #$8516, #$84FE, #$8528, #$851D, #$852E, #$8502, #$84FD, #$851E, - #$84F6, #$8531, #$8526, #$84E7, #$84E8, #$84F0, #$84EF, #$84F9, - #$8518, #$8520, #$8530, #$850B, #$8519, #$852F, #$8662, #$8756, - #$8763, #$8764, #$8777, #$87E1, #$8773, #$8758, #$8754, #$875B, - #$8752, #$8761, #$875A, #$8751, #$875E, #$876D, #$876A, #$8750, - #$874E, #$875F, #$875D, #$876F, #$876C, #$877A, #$876E, #$875C, - #$8765, #$874F, #$877B, #$8775, #$8762, #$8767, #$8769, #$885A, - #$8905, #$890C, #$8914, #$890B, #$8917, #$8918, #$8919, #$8906, - #$8916, #$8911, #$890E, #$8909, #$89A2, #$89A4, #$89A3, #$89ED, - #$89F0, #$89EC, #$8ACF, #$8AC6, #$8AB8, #$8AD3, #$8AD1, #$8AD4, - #$8AD5, #$8ABB, #$8AD7, #$8ABE, #$8AC0, #$8AC5, #$8AD8, #$8AC3, - #$8ABA, #$8ABD, #$8AD9, #$8C3E, #$8C4D, #$8C8F, #$8CE5, #$8CDF, - #$8CD9, #$8CE8, #$8CDA, #$8CDD, #$8CE7, #$8DA0, #$8D9C, #$8DA1, - #$8D9B, #$8E20, #$8E23, #$8E25, #$8E24, #$8E2E, #$8E15, #$8E1B, - #$8E16, #$8E11, #$8E19, #$8E26, #$8E27, - #$8E14, #$8E12, #$8E18, #$8E13, #$8E1C, #$8E17, #$8E1A, #$8F2C, - #$8F24, #$8F18, #$8F1A, #$8F20, #$8F23, #$8F16, #$8F17, #$9073, - #$9070, #$906F, #$9067, #$906B, #$912F, #$912B, #$9129, #$912A, - #$9132, #$9126, #$912E, #$9185, #$9186, #$918A, #$9181, #$9182, - #$9184, #$9180, #$92D0, #$92C3, #$92C4, #$92C0, #$92D9, #$92B6, - #$92CF, #$92F1, #$92DF, #$92D8, #$92E9, #$92D7, #$92DD, #$92CC, - #$92EF, #$92C2, #$92E8, #$92CA, #$92C8, #$92CE, #$92E6, #$92CD, - #$92D5, #$92C9, #$92E0, #$92DE, #$92E7, #$92D1, #$92D3, #$92B5, - #$92E1, #$92C6, #$92B4, #$957C, #$95AC, #$95AB, #$95AE, #$95B0, - #$96A4, #$96A2, #$96D3, #$9705, #$9708, #$9702, #$975A, #$978A, - #$978E, #$9788, #$97D0, #$97CF, #$981E, #$981D, #$9826, #$9829, - #$9828, #$9820, #$981B, #$9827, #$98B2, #$9908, #$98FA, #$9911, - #$9914, #$9916, #$9917, #$9915, #$99DC, #$99CD, #$99CF, #$99D3, - #$99D4, #$99CE, #$99C9, #$99D6, #$99D8, #$99CB, #$99D7, #$99CC, - #$9AB3, #$9AEC, #$9AEB, #$9AF3, #$9AF2, #$9AF1, #$9B46, #$9B43, - #$9B67, #$9B74, #$9B71, #$9B66, #$9B76, #$9B75, #$9B70, #$9B68, - #$9B64, #$9B6C, #$9CFC, #$9CFA, #$9CFD, #$9CFF, #$9CF7, #$9D07, - #$9D00, #$9CF9, #$9CFB, #$9D08, #$9D05, #$9D04, #$9E83, #$9ED3, - #$9F0F, #$9F10, #$511C, #$5113, #$5117, #$511A, #$5111, #$51DE, - #$5334, #$53E1, #$5670, #$5660, #$566E, - #$5673, #$5666, #$5663, #$566D, #$5672, #$565E, #$5677, #$571C, - #$571B, #$58C8, #$58BD, #$58C9, #$58BF, #$58BA, #$58C2, #$58BC, - #$58C6, #$5B17, #$5B19, #$5B1B, #$5B21, #$5B14, #$5B13, #$5B10, - #$5B16, #$5B28, #$5B1A, #$5B20, #$5B1E, #$5BEF, #$5DAC, #$5DB1, - #$5DA9, #$5DA7, #$5DB5, #$5DB0, #$5DAE, #$5DAA, #$5DA8, #$5DB2, - #$5DAD, #$5DAF, #$5DB4, #$5E67, #$5E68, #$5E66, #$5E6F, #$5EE9, - #$5EE7, #$5EE6, #$5EE8, #$5EE5, #$5F4B, #$5FBC, #$619D, #$61A8, - #$6196, #$61C5, #$61B4, #$61C6, #$61C1, #$61CC, #$61BA, #$61BF, - #$61B8, #$618C, #$64D7, #$64D6, #$64D0, #$64CF, #$64C9, #$64BD, - #$6489, #$64C3, #$64DB, #$64F3, #$64D9, #$6533, #$657F, #$657C, - #$65A2, #$66C8, #$66BE, #$66C0, #$66CA, #$66CB, #$66CF, #$66BD, - #$66BB, #$66BA, #$66CC, #$6723, #$6A34, #$6A66, #$6A49, #$6A67, - #$6A32, #$6A68, #$6A3E, #$6A5D, #$6A6D, #$6A76, #$6A5B, #$6A51, - #$6A28, #$6A5A, #$6A3B, #$6A3F, #$6A41, #$6A6A, #$6A64, #$6A50, - #$6A4F, #$6A54, #$6A6F, #$6A69, #$6A60, #$6A3C, #$6A5E, #$6A56, - #$6A55, #$6A4D, #$6A4E, #$6A46, #$6B55, #$6B54, #$6B56, #$6BA7, - #$6BAA, #$6BAB, #$6BC8, #$6BC7, #$6C04, #$6C03, #$6C06, #$6FAD, - #$6FCB, #$6FA3, #$6FC7, #$6FBC, #$6FCE, #$6FC8, #$6F5E, #$6FC4, - #$6FBD, #$6F9E, #$6FCA, #$6FA8, #$7004, #$6FA5, #$6FAE, #$6FBA, - #$6FAC, #$6FAA, #$6FCF, #$6FBF, #$6FB8, - #$6FA2, #$6FC9, #$6FAB, #$6FCD, #$6FAF, #$6FB2, #$6FB0, #$71C5, - #$71C2, #$71BF, #$71B8, #$71D6, #$71C0, #$71C1, #$71CB, #$71D4, - #$71CA, #$71C7, #$71CF, #$71BD, #$71D8, #$71BC, #$71C6, #$71DA, - #$71DB, #$729D, #$729E, #$7369, #$7366, #$7367, #$736C, #$7365, - #$736B, #$736A, #$747F, #$749A, #$74A0, #$7494, #$7492, #$7495, - #$74A1, #$750B, #$7580, #$762F, #$762D, #$7631, #$763D, #$7633, - #$763C, #$7635, #$7632, #$7630, #$76BB, #$76E6, #$779A, #$779D, - #$77A1, #$779C, #$779B, #$77A2, #$77A3, #$7795, #$7799, #$7797, - #$78DD, #$78E9, #$78E5, #$78EA, #$78DE, #$78E3, #$78DB, #$78E1, - #$78E2, #$78ED, #$78DF, #$78E0, #$79A4, #$7A44, #$7A48, #$7A47, - #$7AB6, #$7AB8, #$7AB5, #$7AB1, #$7AB7, #$7BDE, #$7BE3, #$7BE7, - #$7BDD, #$7BD5, #$7BE5, #$7BDA, #$7BE8, #$7BF9, #$7BD4, #$7BEA, - #$7BE2, #$7BDC, #$7BEB, #$7BD8, #$7BDF, #$7CD2, #$7CD4, #$7CD7, - #$7CD0, #$7CD1, #$7E12, #$7E21, #$7E17, #$7E0C, #$7E1F, #$7E20, - #$7E13, #$7E0E, #$7E1C, #$7E15, #$7E1A, #$7E22, #$7E0B, #$7E0F, - #$7E16, #$7E0D, #$7E14, #$7E25, #$7E24, #$7F43, #$7F7B, #$7F7C, - #$7F7A, #$7FB1, #$7FEF, #$802A, #$8029, #$806C, #$81B1, #$81A6, - #$81AE, #$81B9, #$81B5, #$81AB, #$81B0, #$81AC, #$81B4, #$81B2, - #$81B7, #$81A7, #$81F2, #$8255, #$8256, #$8257, #$8556, #$8545, - #$856B, #$854D, #$8553, #$8561, #$8558, - #$8540, #$8546, #$8564, #$8541, #$8562, #$8544, #$8551, #$8547, - #$8563, #$853E, #$855B, #$8571, #$854E, #$856E, #$8575, #$8555, - #$8567, #$8560, #$858C, #$8566, #$855D, #$8554, #$8565, #$856C, - #$8663, #$8665, #$8664, #$879B, #$878F, #$8797, #$8793, #$8792, - #$8788, #$8781, #$8796, #$8798, #$8779, #$8787, #$87A3, #$8785, - #$8790, #$8791, #$879D, #$8784, #$8794, #$879C, #$879A, #$8789, - #$891E, #$8926, #$8930, #$892D, #$892E, #$8927, #$8931, #$8922, - #$8929, #$8923, #$892F, #$892C, #$891F, #$89F1, #$8AE0, #$8AE2, - #$8AF2, #$8AF4, #$8AF5, #$8ADD, #$8B14, #$8AE4, #$8ADF, #$8AF0, - #$8AC8, #$8ADE, #$8AE1, #$8AE8, #$8AFF, #$8AEF, #$8AFB, #$8C91, - #$8C92, #$8C90, #$8CF5, #$8CEE, #$8CF1, #$8CF0, #$8CF3, #$8D6C, - #$8D6E, #$8DA5, #$8DA7, #$8E33, #$8E3E, #$8E38, #$8E40, #$8E45, - #$8E36, #$8E3C, #$8E3D, #$8E41, #$8E30, #$8E3F, #$8EBD, #$8F36, - #$8F2E, #$8F35, #$8F32, #$8F39, #$8F37, #$8F34, #$9076, #$9079, - #$907B, #$9086, #$90FA, #$9133, #$9135, #$9136, #$9193, #$9190, - #$9191, #$918D, #$918F, #$9327, #$931E, #$9308, #$931F, #$9306, - #$930F, #$937A, #$9338, #$933C, #$931B, #$9323, #$9312, #$9301, - #$9346, #$932D, #$930E, #$930D, #$92CB, #$931D, #$92FA, #$9325, - #$9313, #$92F9, #$92F7, #$9334, #$9302, #$9324, #$92FF, #$9329, - #$9339, #$9335, #$932A, #$9314, #$930C, - #$930B, #$92FE, #$9309, #$9300, #$92FB, #$9316, #$95BC, #$95CD, - #$95BE, #$95B9, #$95BA, #$95B6, #$95BF, #$95B5, #$95BD, #$96A9, - #$96D4, #$970B, #$9712, #$9710, #$9799, #$9797, #$9794, #$97F0, - #$97F8, #$9835, #$982F, #$9832, #$9924, #$991F, #$9927, #$9929, - #$999E, #$99EE, #$99EC, #$99E5, #$99E4, #$99F0, #$99E3, #$99EA, - #$99E9, #$99E7, #$9AB9, #$9ABF, #$9AB4, #$9ABB, #$9AF6, #$9AFA, - #$9AF9, #$9AF7, #$9B33, #$9B80, #$9B85, #$9B87, #$9B7C, #$9B7E, - #$9B7B, #$9B82, #$9B93, #$9B92, #$9B90, #$9B7A, #$9B95, #$9B7D, - #$9B88, #$9D25, #$9D17, #$9D20, #$9D1E, #$9D14, #$9D29, #$9D1D, - #$9D18, #$9D22, #$9D10, #$9D19, #$9D1F, #$9E88, #$9E86, #$9E87, - #$9EAE, #$9EAD, #$9ED5, #$9ED6, #$9EFA, #$9F12, #$9F3D, #$5126, - #$5125, #$5122, #$5124, #$5120, #$5129, #$52F4, #$5693, #$568C, - #$568D, #$5686, #$5684, #$5683, #$567E, #$5682, #$567F, #$5681, - #$58D6, #$58D4, #$58CF, #$58D2, #$5B2D, #$5B25, #$5B32, #$5B23, - #$5B2C, #$5B27, #$5B26, #$5B2F, #$5B2E, #$5B7B, #$5BF1, #$5BF2, - #$5DB7, #$5E6C, #$5E6A, #$5FBE, #$5FBB, #$61C3, #$61B5, #$61BC, - #$61E7, #$61E0, #$61E5, #$61E4, #$61E8, #$61DE, #$64EF, #$64E9, - #$64E3, #$64EB, #$64E4, #$64E8, #$6581, #$6580, #$65B6, #$65DA, - #$66D2, #$6A8D, #$6A96, #$6A81, #$6AA5, #$6A89, #$6A9F, #$6A9B, - #$6AA1, #$6A9E, #$6A87, #$6A93, #$6A8E, - #$6A95, #$6A83, #$6AA8, #$6AA4, #$6A91, #$6A7F, #$6AA6, #$6A9A, - #$6A85, #$6A8C, #$6A92, #$6B5B, #$6BAD, #$6C09, #$6FCC, #$6FA9, - #$6FF4, #$6FD4, #$6FE3, #$6FDC, #$6FED, #$6FE7, #$6FE6, #$6FDE, - #$6FF2, #$6FDD, #$6FE2, #$6FE8, #$71E1, #$71F1, #$71E8, #$71F2, - #$71E4, #$71F0, #$71E2, #$7373, #$736E, #$736F, #$7497, #$74B2, - #$74AB, #$7490, #$74AA, #$74AD, #$74B1, #$74A5, #$74AF, #$7510, - #$7511, #$7512, #$750F, #$7584, #$7643, #$7648, #$7649, #$7647, - #$76A4, #$76E9, #$77B5, #$77AB, #$77B2, #$77B7, #$77B6, #$77B4, - #$77B1, #$77A8, #$77F0, #$78F3, #$78FD, #$7902, #$78FB, #$78FC, - #$78F2, #$7905, #$78F9, #$78FE, #$7904, #$79AB, #$79A8, #$7A5C, - #$7A5B, #$7A56, #$7A58, #$7A54, #$7A5A, #$7ABE, #$7AC0, #$7AC1, - #$7C05, #$7C0F, #$7BF2, #$7C00, #$7BFF, #$7BFB, #$7C0E, #$7BF4, - #$7C0B, #$7BF3, #$7C02, #$7C09, #$7C03, #$7C01, #$7BF8, #$7BFD, - #$7C06, #$7BF0, #$7BF1, #$7C10, #$7C0A, #$7CE8, #$7E2D, #$7E3C, - #$7E42, #$7E33, #$9848, #$7E38, #$7E2A, #$7E49, #$7E40, #$7E47, - #$7E29, #$7E4C, #$7E30, #$7E3B, #$7E36, #$7E44, #$7E3A, #$7F45, - #$7F7F, #$7F7E, #$7F7D, #$7FF4, #$7FF2, #$802C, #$81BB, #$81C4, - #$81CC, #$81CA, #$81C5, #$81C7, #$81BC, #$81E9, #$825B, #$825A, - #$825C, #$8583, #$8580, #$858F, #$85A7, #$8595, #$85A0, #$858B, - #$85A3, #$857B, #$85A4, #$859A, #$859E, - #$8577, #$857C, #$8589, #$85A1, #$857A, #$8578, #$8557, #$858E, - #$8596, #$8586, #$858D, #$8599, #$859D, #$8581, #$85A2, #$8582, - #$8588, #$8585, #$8579, #$8576, #$8598, #$8590, #$859F, #$8668, - #$87BE, #$87AA, #$87AD, #$87C5, #$87B0, #$87AC, #$87B9, #$87B5, - #$87BC, #$87AE, #$87C9, #$87C3, #$87C2, #$87CC, #$87B7, #$87AF, - #$87C4, #$87CA, #$87B4, #$87B6, #$87BF, #$87B8, #$87BD, #$87DE, - #$87B2, #$8935, #$8933, #$893C, #$893E, #$8941, #$8952, #$8937, - #$8942, #$89AD, #$89AF, #$89AE, #$89F2, #$89F3, #$8B1E, #$8B18, - #$8B16, #$8B11, #$8B05, #$8B0B, #$8B22, #$8B0F, #$8B12, #$8B15, - #$8B07, #$8B0D, #$8B08, #$8B06, #$8B1C, #$8B13, #$8B1A, #$8C4F, - #$8C70, #$8C72, #$8C71, #$8C6F, #$8C95, #$8C94, #$8CF9, #$8D6F, - #$8E4E, #$8E4D, #$8E53, #$8E50, #$8E4C, #$8E47, #$8F43, #$8F40, - #$9085, #$907E, #$9138, #$919A, #$91A2, #$919B, #$9199, #$919F, - #$91A1, #$919D, #$91A0, #$93A1, #$9383, #$93AF, #$9364, #$9356, - #$9347, #$937C, #$9358, #$935C, #$9376, #$9349, #$9350, #$9351, - #$9360, #$936D, #$938F, #$934C, #$936A, #$9379, #$9357, #$9355, - #$9352, #$934F, #$9371, #$9377, #$937B, #$9361, #$935E, #$9363, - #$9367, #$9380, #$934E, #$9359, #$95C7, #$95C0, #$95C9, #$95C3, - #$95C5, #$95B7, #$96AE, #$96B0, #$96AC, #$9720, #$971F, #$9718, - #$971D, #$9719, #$979A, #$97A1, #$979C, - #$979E, #$979D, #$97D5, #$97D4, #$97F1, #$9841, #$9844, #$984A, - #$9849, #$9845, #$9843, #$9925, #$992B, #$992C, #$992A, #$9933, - #$9932, #$992F, #$992D, #$9931, #$9930, #$9998, #$99A3, #$99A1, - #$9A02, #$99FA, #$99F4, #$99F7, #$99F9, #$99F8, #$99F6, #$99FB, - #$99FD, #$99FE, #$99FC, #$9A03, #$9ABE, #$9AFE, #$9AFD, #$9B01, - #$9AFC, #$9B48, #$9B9A, #$9BA8, #$9B9E, #$9B9B, #$9BA6, #$9BA1, - #$9BA5, #$9BA4, #$9B86, #$9BA2, #$9BA0, #$9BAF, #$9D33, #$9D41, - #$9D67, #$9D36, #$9D2E, #$9D2F, #$9D31, #$9D38, #$9D30, #$9D45, - #$9D42, #$9D43, #$9D3E, #$9D37, #$9D40, #$9D3D, #$7FF5, #$9D2D, - #$9E8A, #$9E89, #$9E8D, #$9EB0, #$9EC8, #$9EDA, #$9EFB, #$9EFF, - #$9F24, #$9F23, #$9F22, #$9F54, #$9FA0, #$5131, #$512D, #$512E, - #$5698, #$569C, #$5697, #$569A, #$569D, #$5699, #$5970, #$5B3C, - #$5C69, #$5C6A, #$5DC0, #$5E6D, #$5E6E, #$61D8, #$61DF, #$61ED, - #$61EE, #$61F1, #$61EA, #$61F0, #$61EB, #$61D6, #$61E9, #$64FF, - #$6504, #$64FD, #$64F8, #$6501, #$6503, #$64FC, #$6594, #$65DB, - #$66DA, #$66DB, #$66D8, #$6AC5, #$6AB9, #$6ABD, #$6AE1, #$6AC6, - #$6ABA, #$6AB6, #$6AB7, #$6AC7, #$6AB4, #$6AAD, #$6B5E, #$6BC9, - #$6C0B, #$7007, #$700C, #$700D, #$7001, #$7005, #$7014, #$700E, - #$6FFF, #$7000, #$6FFB, #$7026, #$6FFC, #$6FF7, #$700A, #$7201, - #$71FF, #$71F9, #$7203, #$71FD, #$7376, - #$74B8, #$74C0, #$74B5, #$74C1, #$74BE, #$74B6, #$74BB, #$74C2, - #$7514, #$7513, #$765C, #$7664, #$7659, #$7650, #$7653, #$7657, - #$765A, #$76A6, #$76BD, #$76EC, #$77C2, #$77BA, #$78FF, #$790C, - #$7913, #$7914, #$7909, #$7910, #$7912, #$7911, #$79AD, #$79AC, - #$7A5F, #$7C1C, #$7C29, #$7C19, #$7C20, #$7C1F, #$7C2D, #$7C1D, - #$7C26, #$7C28, #$7C22, #$7C25, #$7C30, #$7E5C, #$7E50, #$7E56, - #$7E63, #$7E58, #$7E62, #$7E5F, #$7E51, #$7E60, #$7E57, #$7E53, - #$7FB5, #$7FB3, #$7FF7, #$7FF8, #$8075, #$81D1, #$81D2, #$81D0, - #$825F, #$825E, #$85B4, #$85C6, #$85C0, #$85C3, #$85C2, #$85B3, - #$85B5, #$85BD, #$85C7, #$85C4, #$85BF, #$85CB, #$85CE, #$85C8, - #$85C5, #$85B1, #$85B6, #$85D2, #$8624, #$85B8, #$85B7, #$85BE, - #$8669, #$87E7, #$87E6, #$87E2, #$87DB, #$87EB, #$87EA, #$87E5, - #$87DF, #$87F3, #$87E4, #$87D4, #$87DC, #$87D3, #$87ED, #$87D8, - #$87E3, #$87A4, #$87D7, #$87D9, #$8801, #$87F4, #$87E8, #$87DD, - #$8953, #$894B, #$894F, #$894C, #$8946, #$8950, #$8951, #$8949, - #$8B2A, #$8B27, #$8B23, #$8B33, #$8B30, #$8B35, #$8B47, #$8B2F, - #$8B3C, #$8B3E, #$8B31, #$8B25, #$8B37, #$8B26, #$8B36, #$8B2E, - #$8B24, #$8B3B, #$8B3D, #$8B3A, #$8C42, #$8C75, #$8C99, #$8C98, - #$8C97, #$8CFE, #$8D04, #$8D02, #$8D00, #$8E5C, #$8E62, #$8E60, - #$8E57, #$8E56, #$8E5E, #$8E65, #$8E67, - #$8E5B, #$8E5A, #$8E61, #$8E5D, #$8E69, #$8E54, #$8F46, #$8F47, - #$8F48, #$8F4B, #$9128, #$913A, #$913B, #$913E, #$91A8, #$91A5, - #$91A7, #$91AF, #$91AA, #$93B5, #$938C, #$9392, #$93B7, #$939B, - #$939D, #$9389, #$93A7, #$938E, #$93AA, #$939E, #$93A6, #$9395, - #$9388, #$9399, #$939F, #$938D, #$93B1, #$9391, #$93B2, #$93A4, - #$93A8, #$93B4, #$93A3, #$93A5, #$95D2, #$95D3, #$95D1, #$96B3, - #$96D7, #$96DA, #$5DC2, #$96DF, #$96D8, #$96DD, #$9723, #$9722, - #$9725, #$97AC, #$97AE, #$97A8, #$97AB, #$97A4, #$97AA, #$97A2, - #$97A5, #$97D7, #$97D9, #$97D6, #$97D8, #$97FA, #$9850, #$9851, - #$9852, #$98B8, #$9941, #$993C, #$993A, #$9A0F, #$9A0B, #$9A09, - #$9A0D, #$9A04, #$9A11, #$9A0A, #$9A05, #$9A07, #$9A06, #$9AC0, - #$9ADC, #$9B08, #$9B04, #$9B05, #$9B29, #$9B35, #$9B4A, #$9B4C, - #$9B4B, #$9BC7, #$9BC6, #$9BC3, #$9BBF, #$9BC1, #$9BB5, #$9BB8, - #$9BD3, #$9BB6, #$9BC4, #$9BB9, #$9BBD, #$9D5C, #$9D53, #$9D4F, - #$9D4A, #$9D5B, #$9D4B, #$9D59, #$9D56, #$9D4C, #$9D57, #$9D52, - #$9D54, #$9D5F, #$9D58, #$9D5A, #$9E8E, #$9E8C, #$9EDF, #$9F01, - #$9F00, #$9F16, #$9F25, #$9F2B, #$9F2A, #$9F29, #$9F28, #$9F4C, - #$9F55, #$5134, #$5135, #$5296, #$52F7, #$53B4, #$56AB, #$56AD, - #$56A6, #$56A7, #$56AA, #$56AC, #$58DA, #$58DD, #$58DB, #$5912, - #$5B3D, #$5B3E, #$5B3F, #$5DC3, #$5E70, - #$5FBF, #$61FB, #$6507, #$6510, #$650D, #$6509, #$650C, #$650E, - #$6584, #$65DE, #$65DD, #$66DE, #$6AE7, #$6AE0, #$6ACC, #$6AD1, - #$6AD9, #$6ACB, #$6ADF, #$6ADC, #$6AD0, #$6AEB, #$6ACF, #$6ACD, - #$6ADE, #$6B60, #$6BB0, #$6C0C, #$7019, #$7027, #$7020, #$7016, - #$702B, #$7021, #$7022, #$7023, #$7029, #$7017, #$7024, #$701C, - #$702A, #$720C, #$720A, #$7207, #$7202, #$7205, #$72A5, #$72A6, - #$72A4, #$72A3, #$72A1, #$74CB, #$74C5, #$74B7, #$74C3, #$7516, - #$7660, #$77C9, #$77CA, #$77C4, #$77F1, #$791D, #$791B, #$7921, - #$791C, #$7917, #$791E, #$79B0, #$7A67, #$7A68, #$7C33, #$7C3C, - #$7C39, #$7C2C, #$7C3B, #$7CEC, #$7CEA, #$7E76, #$7E75, #$7E78, - #$7E70, #$7E77, #$7E6F, #$7E7A, #$7E72, #$7E74, #$7E68, #$7F4B, - #$7F4A, #$7F83, #$7F86, #$7FB7, #$7FFD, #$7FFE, #$8078, #$81D7, - #$81D5, #$8264, #$8261, #$8263, #$85EB, #$85F1, #$85ED, #$85D9, - #$85E1, #$85E8, #$85DA, #$85D7, #$85EC, #$85F2, #$85F8, #$85D8, - #$85DF, #$85E3, #$85DC, #$85D1, #$85F0, #$85E6, #$85EF, #$85DE, - #$85E2, #$8800, #$87FA, #$8803, #$87F6, #$87F7, #$8809, #$880C, - #$880B, #$8806, #$87FC, #$8808, #$87FF, #$880A, #$8802, #$8962, - #$895A, #$895B, #$8957, #$8961, #$895C, #$8958, #$895D, #$8959, - #$8988, #$89B7, #$89B6, #$89F6, #$8B50, #$8B48, #$8B4A, #$8B40, - #$8B53, #$8B56, #$8B54, #$8B4B, #$8B55, - #$8B51, #$8B42, #$8B52, #$8B57, #$8C43, #$8C77, #$8C76, #$8C9A, - #$8D06, #$8D07, #$8D09, #$8DAC, #$8DAA, #$8DAD, #$8DAB, #$8E6D, - #$8E78, #$8E73, #$8E6A, #$8E6F, #$8E7B, #$8EC2, #$8F52, #$8F51, - #$8F4F, #$8F50, #$8F53, #$8FB4, #$9140, #$913F, #$91B0, #$91AD, - #$93DE, #$93C7, #$93CF, #$93C2, #$93DA, #$93D0, #$93F9, #$93EC, - #$93CC, #$93D9, #$93A9, #$93E6, #$93CA, #$93D4, #$93EE, #$93E3, - #$93D5, #$93C4, #$93CE, #$93C0, #$93D2, #$93E7, #$957D, #$95DA, - #$95DB, #$96E1, #$9729, #$972B, #$972C, #$9728, #$9726, #$97B3, - #$97B7, #$97B6, #$97DD, #$97DE, #$97DF, #$985C, #$9859, #$985D, - #$9857, #$98BF, #$98BD, #$98BB, #$98BE, #$9948, #$9947, #$9943, - #$99A6, #$99A7, #$9A1A, #$9A15, #$9A25, #$9A1D, #$9A24, #$9A1B, - #$9A22, #$9A20, #$9A27, #$9A23, #$9A1E, #$9A1C, #$9A14, #$9AC2, - #$9B0B, #$9B0A, #$9B0E, #$9B0C, #$9B37, #$9BEA, #$9BEB, #$9BE0, - #$9BDE, #$9BE4, #$9BE6, #$9BE2, #$9BF0, #$9BD4, #$9BD7, #$9BEC, - #$9BDC, #$9BD9, #$9BE5, #$9BD5, #$9BE1, #$9BDA, #$9D77, #$9D81, - #$9D8A, #$9D84, #$9D88, #$9D71, #$9D80, #$9D78, #$9D86, #$9D8B, - #$9D8C, #$9D7D, #$9D6B, #$9D74, #$9D75, #$9D70, #$9D69, #$9D85, - #$9D73, #$9D7B, #$9D82, #$9D6F, #$9D79, #$9D7F, #$9D87, #$9D68, - #$9E94, #$9E91, #$9EC0, #$9EFC, #$9F2D, #$9F40, #$9F41, #$9F4D, - #$9F56, #$9F57, #$9F58, #$5337, #$56B2, - #$56B5, #$56B3, #$58E3, #$5B45, #$5DC6, #$5DC7, #$5EEE, #$5EEF, - #$5FC0, #$5FC1, #$61F9, #$6517, #$6516, #$6515, #$6513, #$65DF, - #$66E8, #$66E3, #$66E4, #$6AF3, #$6AF0, #$6AEA, #$6AE8, #$6AF9, - #$6AF1, #$6AEE, #$6AEF, #$703C, #$7035, #$702F, #$7037, #$7034, - #$7031, #$7042, #$7038, #$703F, #$703A, #$7039, #$7040, #$703B, - #$7033, #$7041, #$7213, #$7214, #$72A8, #$737D, #$737C, #$74BA, - #$76AB, #$76AA, #$76BE, #$76ED, #$77CC, #$77CE, #$77CF, #$77CD, - #$77F2, #$7925, #$7923, #$7927, #$7928, #$7924, #$7929, #$79B2, - #$7A6E, #$7A6C, #$7A6D, #$7AF7, #$7C49, #$7C48, #$7C4A, #$7C47, - #$7C45, #$7CEE, #$7E7B, #$7E7E, #$7E81, #$7E80, #$7FBA, #$7FFF, - #$8079, #$81DB, #$81D9, #$820B, #$8268, #$8269, #$8622, #$85FF, - #$8601, #$85FE, #$861B, #$8600, #$85F6, #$8604, #$8609, #$8605, - #$860C, #$85FD, #$8819, #$8810, #$8811, #$8817, #$8813, #$8816, - #$8963, #$8966, #$89B9, #$89F7, #$8B60, #$8B6A, #$8B5D, #$8B68, - #$8B63, #$8B65, #$8B67, #$8B6D, #$8DAE, #$8E86, #$8E88, #$8E84, - #$8F59, #$8F56, #$8F57, #$8F55, #$8F58, #$8F5A, #$908D, #$9143, - #$9141, #$91B7, #$91B5, #$91B2, #$91B3, #$940B, #$9413, #$93FB, - #$9420, #$940F, #$9414, #$93FE, #$9415, #$9410, #$9428, #$9419, - #$940D, #$93F5, #$9400, #$93F7, #$9407, #$940E, #$9416, #$9412, - #$93FA, #$9409, #$93F8, #$940A, #$93FF, - #$93FC, #$940C, #$93F6, #$9411, #$9406, #$95DE, #$95E0, #$95DF, - #$972E, #$972F, #$97B9, #$97BB, #$97FD, #$97FE, #$9860, #$9862, - #$9863, #$985F, #$98C1, #$98C2, #$9950, #$994E, #$9959, #$994C, - #$994B, #$9953, #$9A32, #$9A34, #$9A31, #$9A2C, #$9A2A, #$9A36, - #$9A29, #$9A2E, #$9A38, #$9A2D, #$9AC7, #$9ACA, #$9AC6, #$9B10, - #$9B12, #$9B11, #$9C0B, #$9C08, #$9BF7, #$9C05, #$9C12, #$9BF8, - #$9C40, #$9C07, #$9C0E, #$9C06, #$9C17, #$9C14, #$9C09, #$9D9F, - #$9D99, #$9DA4, #$9D9D, #$9D92, #$9D98, #$9D90, #$9D9B, #$9DA0, - #$9D94, #$9D9C, #$9DAA, #$9D97, #$9DA1, #$9D9A, #$9DA2, #$9DA8, - #$9D9E, #$9DA3, #$9DBF, #$9DA9, #$9D96, #$9DA6, #$9DA7, #$9E99, - #$9E9B, #$9E9A, #$9EE5, #$9EE4, #$9EE7, #$9EE6, #$9F30, #$9F2E, - #$9F5B, #$9F60, #$9F5E, #$9F5D, #$9F59, #$9F91, #$513A, #$5139, - #$5298, #$5297, #$56C3, #$56BD, #$56BE, #$5B48, #$5B47, #$5DCB, - #$5DCF, #$5EF1, #$61FD, #$651B, #$6B02, #$6AFC, #$6B03, #$6AF8, - #$6B00, #$7043, #$7044, #$704A, #$7048, #$7049, #$7045, #$7046, - #$721D, #$721A, #$7219, #$737E, #$7517, #$766A, #$77D0, #$792D, - #$7931, #$792F, #$7C54, #$7C53, #$7CF2, #$7E8A, #$7E87, #$7E88, - #$7E8B, #$7E86, #$7E8D, #$7F4D, #$7FBB, #$8030, #$81DD, #$8618, - #$862A, #$8626, #$861F, #$8623, #$861C, #$8619, #$8627, #$862E, - #$8621, #$8620, #$8629, #$861E, #$8625, - #$8829, #$881D, #$881B, #$8820, #$8824, #$881C, #$882B, #$884A, - #$896D, #$8969, #$896E, #$896B, #$89FA, #$8B79, #$8B78, #$8B45, - #$8B7A, #$8B7B, #$8D10, #$8D14, #$8DAF, #$8E8E, #$8E8C, #$8F5E, - #$8F5B, #$8F5D, #$9146, #$9144, #$9145, #$91B9, #$943F, #$943B, - #$9436, #$9429, #$943D, #$943C, #$9430, #$9439, #$942A, #$9437, - #$942C, #$9440, #$9431, #$95E5, #$95E4, #$95E3, #$9735, #$973A, - #$97BF, #$97E1, #$9864, #$98C9, #$98C6, #$98C0, #$9958, #$9956, - #$9A39, #$9A3D, #$9A46, #$9A44, #$9A42, #$9A41, #$9A3A, #$9A3F, - #$9ACD, #$9B15, #$9B17, #$9B18, #$9B16, #$9B3A, #$9B52, #$9C2B, - #$9C1D, #$9C1C, #$9C2C, #$9C23, #$9C28, #$9C29, #$9C24, #$9C21, - #$9DB7, #$9DB6, #$9DBC, #$9DC1, #$9DC7, #$9DCA, #$9DCF, #$9DBE, - #$9DC5, #$9DC3, #$9DBB, #$9DB5, #$9DCE, #$9DB9, #$9DBA, #$9DAC, - #$9DC8, #$9DB1, #$9DAD, #$9DCC, #$9DB3, #$9DCD, #$9DB2, #$9E7A, - #$9E9C, #$9EEB, #$9EEE, #$9EED, #$9F1B, #$9F18, #$9F1A, #$9F31, - #$9F4E, #$9F65, #$9F64, #$9F92, #$4EB9, #$56C6, #$56C5, #$56CB, - #$5971, #$5B4B, #$5B4C, #$5DD5, #$5DD1, #$5EF2, #$6521, #$6520, - #$6526, #$6522, #$6B0B, #$6B08, #$6B09, #$6C0D, #$7055, #$7056, - #$7057, #$7052, #$721E, #$721F, #$72A9, #$737F, #$74D8, #$74D5, - #$74D9, #$74D7, #$766D, #$76AD, #$7935, #$79B4, #$7A70, #$7A71, - #$7C57, #$7C5C, #$7C59, #$7C5B, #$7C5A, - #$7CF4, #$7CF1, #$7E91, #$7F4F, #$7F87, #$81DE, #$826B, #$8634, - #$8635, #$8633, #$862C, #$8632, #$8636, #$882C, #$8828, #$8826, - #$882A, #$8825, #$8971, #$89BF, #$89BE, #$89FB, #$8B7E, #$8B84, - #$8B82, #$8B86, #$8B85, #$8B7F, #$8D15, #$8E95, #$8E94, #$8E9A, - #$8E92, #$8E90, #$8E96, #$8E97, #$8F60, #$8F62, #$9147, #$944C, - #$9450, #$944A, #$944B, #$944F, #$9447, #$9445, #$9448, #$9449, - #$9446, #$973F, #$97E3, #$986A, #$9869, #$98CB, #$9954, #$995B, - #$9A4E, #$9A53, #$9A54, #$9A4C, #$9A4F, #$9A48, #$9A4A, #$9A49, - #$9A52, #$9A50, #$9AD0, #$9B19, #$9B2B, #$9B3B, #$9B56, #$9B55, - #$9C46, #$9C48, #$9C3F, #$9C44, #$9C39, #$9C33, #$9C41, #$9C3C, - #$9C37, #$9C34, #$9C32, #$9C3D, #$9C36, #$9DDB, #$9DD2, #$9DDE, - #$9DDA, #$9DCB, #$9DD0, #$9DDC, #$9DD1, #$9DDF, #$9DE9, #$9DD9, - #$9DD8, #$9DD6, #$9DF5, #$9DD5, #$9DDD, #$9EB6, #$9EF0, #$9F35, - #$9F33, #$9F32, #$9F42, #$9F6B, #$9F95, #$9FA2, #$513D, #$5299, - #$58E8, #$58E7, #$5972, #$5B4D, #$5DD8, #$882F, #$5F4F, #$6201, - #$6203, #$6204, #$6529, #$6525, #$6596, #$66EB, #$6B11, #$6B12, - #$6B0F, #$6BCA, #$705B, #$705A, #$7222, #$7382, #$7381, #$7383, - #$7670, #$77D4, #$7C67, #$7C66, #$7E95, #$826C, #$863A, #$8640, - #$8639, #$863C, #$8631, #$863B, #$863E, #$8830, #$8832, #$882E, - #$8833, #$8976, #$8974, #$8973, #$89FE, - #$8B8C, #$8B8E, #$8B8B, #$8B88, #$8C45, #$8D19, #$8E98, #$8F64, - #$8F63, #$91BC, #$9462, #$9455, #$945D, #$9457, #$945E, #$97C4, - #$97C5, #$9800, #$9A56, #$9A59, #$9B1E, #$9B1F, #$9B20, #$9C52, - #$9C58, #$9C50, #$9C4A, #$9C4D, #$9C4B, #$9C55, #$9C59, #$9C4C, - #$9C4E, #$9DFB, #$9DF7, #$9DEF, #$9DE3, #$9DEB, #$9DF8, #$9DE4, - #$9DF6, #$9DE1, #$9DEE, #$9DE6, #$9DF2, #$9DF0, #$9DE2, #$9DEC, - #$9DF4, #$9DF3, #$9DE8, #$9DED, #$9EC2, #$9ED0, #$9EF2, #$9EF3, - #$9F06, #$9F1C, #$9F38, #$9F37, #$9F36, #$9F43, #$9F4F, #$9F71, - #$9F70, #$9F6E, #$9F6F, #$56D3, #$56CD, #$5B4E, #$5C6D, #$652D, - #$66ED, #$66EE, #$6B13, #$705F, #$7061, #$705D, #$7060, #$7223, - #$74DB, #$74E5, #$77D5, #$7938, #$79B7, #$79B6, #$7C6A, #$7E97, - #$7F89, #$826D, #$8643, #$8838, #$8837, #$8835, #$884B, #$8B94, - #$8B95, #$8E9E, #$8E9F, #$8EA0, #$8E9D, #$91BE, #$91BD, #$91C2, - #$946B, #$9468, #$9469, #$96E5, #$9746, #$9743, #$9747, #$97C7, - #$97E5, #$9A5E, #$9AD5, #$9B59, #$9C63, #$9C67, #$9C66, #$9C62, - #$9C5E, #$9C60, #$9E02, #$9DFE, #$9E07, #$9E03, #$9E06, #$9E05, - #$9E00, #$9E01, #$9E09, #$9DFF, #$9DFD, #$9E04, #$9EA0, #$9F1E, - #$9F46, #$9F74, #$9F75, #$9F76, #$56D4, #$652E, #$65B8, #$6B18, - #$6B19, #$6B17, #$6B1A, #$7062, #$7226, #$72AA, #$77D8, #$77D9, - #$7939, #$7C69, #$7C6B, #$7CF6, #$7E9A, - #$7E98, #$7E9B, #$7E99, #$81E0, #$81E1, #$8646, #$8647, #$8648, - #$8979, #$897A, #$897C, #$897B, #$89FF, #$8B98, #$8B99, #$8EA5, - #$8EA4, #$8EA3, #$946E, #$946D, #$946F, #$9471, #$9473, #$9749, - #$9872, #$995F, #$9C68, #$9C6E, #$9C6D, #$9E0B, #$9E0D, #$9E10, - #$9E0F, #$9E12, #$9E11, #$9EA1, #$9EF5, #$9F09, #$9F47, #$9F78, - #$9F7B, #$9F7A, #$9F79, #$571E, #$7066, #$7C6F, #$883C, #$8DB2, - #$8EA6, #$91C3, #$9474, #$9478, #$9476, #$9475, #$9A60, #$9C74, - #$9C73, #$9C71, #$9C75, #$9E14, #$9E13, #$9EF6, #$9F0A, #$9FA4, - #$7068, #$7065, #$7CF7, #$866A, #$883E, #$883D, #$883F, #$8B9E, - #$8C9C, #$8EA9, #$8EC9, #$974B, #$9873, #$9874, #$98CC, #$9961, - #$99AB, #$9A64, #$9A66, #$9A67, #$9B24, #$9E15, #$9E17, #$9F48, - #$6207, #$6B1E, #$7227, #$864C, #$8EA8, #$9482, #$9480, #$9481, - #$9A69, #$9A68, #$9B2E, #$9E19, #$7229, #$864B, #$8B9F, #$9483, - #$9C79, #$9EB7, #$7675, #$9A6B, #$9C7A, #$9E1D, #$7069, #$706A, - #$9EA4, #$9F7E, #$9F49, #$9F98); - HKSCS_1Map: array[0..626] of TBuffChar = ( - #$7E43, #$7E44, #$7E45, #$7E46, #$7E47, #$7E48, #$7E49, #$7E4A, - #$7E4B, #$7E4C, #$7E4D, #$7E4E, #$7E4F, #$7E50, #$7E51, #$7E52, - #$7E53, #$7E54, #$7E55, #$7E56, #$7E57, #$7E58, #$0080, #$0041, - #$010D, #$0040, #$0092, #$0049, #$009A, #$0048, #$00CC, #$0053, - #$0111, #$0052, #$7E65, #$02BE, #$7E67, #$02C0, #$004A, #$0081, - #$0061, #$010E, #$0060, #$0151, #$0093, #$0069, #$009B, #$0068, - #$00AB, #$006D, #$0110, #$006C, #$00CD, #$0073, #$0112, #$0072, - #$00EB, #$007A, #$0114, #$0079, #$0116, #$0118, #$011A, #$011C, - #$007C, #$7E84, #$02BF, #$7E86, #$02C1, #$006A, #$0161, #$7E8A, - #$7E8B, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$EA69, #$7EE1, #$81BD, #$36CA, #$81BD, #$81BD, #$1FFD, #$405D, - #$6D8E, #$629F, #$81BD, #$81BD, #$D3B5, #$3651, #$20DA, #$20E8, - #$2168, #$2316, #$2334, #$235C, #$23A4, #$2461, #$2468, #$24FB, - #$250E, #$2591, #$2598, #$28A2, #$2AB0, #$2AC4, #$2AC7, #$2AF2, - #$2AF4, #$2D26, #$2D5E, #$2D5F, #$2E5A, #$3046, #$31FB, #$3749, - #$39BE, #$39C4, #$3A25, #$3F0E, #$423C, #$46B5, #$5024, #$502C, - #$503A, #$5047, #$504F, #$505F, #$5086, #$50B7, #$53FA, #$544F, - #$54EF, #$5B06, #$5CFE, #$5D22, #$6066, #$6067, #$606E, #$4591, - #$4E7C, #$4F4D, #$3B06, #$4C49, #$23E7, #$81BD, #$81BD, #$81BD, - #$81BD, #$624C, #$4A38, #$621E, #$523C, #$81BD, #$5E0B, #$5276, - #$7F30, #$81BD, #$81BD, #$521F, #$6F07, #$1F0D, #$6E09, #$6E4C, - #$1E7E, #$7F39, #$CFCE, #$6E4A, #$7F3C, #$0881, #$81BD, #$401A, - #$53BE, #$4699, #$81BD, #$1B91, #$6B2C, #$6B4F, #$6FD9, #$4B07, - #$7F48, #$970A, #$86D0, #$7F4B, #$1FE4, #$2041, #$2040, #$2047, - #$207F, #$20AB, #$20F7, #$070C, #$217D, #$10C8, #$21C3, #$2248, - #$073D, #$0753, #$0765, #$2346, #$2AC5, #$239B, #$23BC, #$23C5, - #$2049, #$2439, #$2450, #$24E7, #$0887, #$2569, #$0811, #$2570, - #$0813, #$2582, #$25E3, #$082D, #$0832, #$0941, #$2653, #$2663, - #$2674, #$2679, #$2690, #$26AF, #$26D8, #$26E3, #$26E8, #$0858, - #$26FF, #$0865, #$087F, #$2797, #$0885, - #$7F7D, #$26E5, #$81BD, #$8A42, #$7F81, #$7F82, #$2750, #$A186, - #$0CAC, #$8481, #$5F46, #$B8F8, #$7F89, #$12D3, #$D87E, #$48FA, - #$7F8D, #$0CF4, #$1A55, #$7F90, #$CA72, #$B92A, #$369D, #$7F94, - #$8CF4, #$8AD5, #$8E34, #$364D, #$5F7E, #$7F9A, #$7F9B, #$7F9C, - #$7F9D, #$D996, #$B293, #$81BD, #$8B06, #$7FA2, #$D8A9, #$1A74, - #$7FA5, #$7FA6, #$6B72, #$0D27, #$7FA9, #$126D, #$07C6, #$BB87, - #$7FAD, #$7FAE, #$7FAF, #$6DAE, #$68D5, #$81BD, #$1659, #$C465, - #$3674, #$26A3, #$7FB7, #$7FB8, #$8DB7, #$0CBB, #$8DAF, #$7FBC, - #$7FBD, #$7FBE, #$36AA, #$7FC0, #$8A43, #$5F68, #$99E1, #$DF0C, - #$7FC5, #$81BD, #$1A8B, #$7FC8, #$127A, #$2A33, #$7FCB, #$81BD, - #$7FCD, #$863C, #$7FCF, #$7FD0, #$7FD1, #$2739, #$133B, #$163A, - #$81BD, #$1CF4, #$7FD7, #$7FD8, #$532A, #$69B5, #$7FDB, #$3539, - #$0CBE, #$9DB5, #$5EC0, #$2861, #$363C, #$10C3, #$81BD, #$7FE4, - #$8B89, #$9FCF, #$7FE7, #$81BD, #$8E08, #$7FEA, #$0C52, #$0CC6, - #$7FED, #$0838, #$7FEF, #$9907, #$2812, #$8CB1, #$7FF3, #$7FF4, - #$077C, #$3DFD, #$7FF7, #$81BD, #$81BD, #$7FFA, #$7FFB, #$7FFC, - #$7FFD, #$E00D, #$8BFA, #$8000, #$8001, #$5113, #$8003, #$9E03, - #$9F39, #$08BB, #$BB23, #$8008, #$8CCD, #$8C2A, #$1213, #$8CB0, - #$8B07, #$800E, #$800F, #$81BD, #$8C2B, #$8012, #$8B08, #$8E00, - #$8E7D, #$1279, #$9CD6, #$35F2, #$8CED, - #$A674, #$D2F9, #$A08E, #$8B3E, #$8B3F, #$A111, #$A115, #$0CD8, - #$8022, #$8E07, #$8CAE, #$8025, #$CB50, #$8027, #$8028, #$8029, - #$666A, #$268C, #$5444, #$2779, #$81BD, #$E783, #$6CE6, #$6B76, - #$D3DE, #$8033, #$42C0, #$52ED, #$526C, #$2DDC, #$C772, #$52B4, - #$0A57, #$251F, #$D87D, #$6276, #$8C7A, #$8B8F, #$8BF7, #$8C7B, - #$089D, #$B92B, #$08C9, #$8AD6, #$286F, #$9DF5, #$8E09, #$8B90, - #$8BF8, #$8DB8, #$8E88, #$D947, #$90D5, #$8BF9, #$B950, #$A264, - #$2C14, #$8D5D, #$8D5E, #$8E35, #$8E36, #$295C, #$8B91, #$D354, - #$D9CD, #$8CF5, #$8BFB, #$BAFE, #$09C3, #$8CF6, #$8EC0, #$BB98, - #$8062, #$8063, #$93FA, #$8065, #$8066, #$2A59, #$2428, #$08DA, - #$806A, #$4D32, #$2D28, #$1A80, #$1D6C, #$6F67, #$1C67, #$6CDF, - #$6C4D, #$C0B4, #$A43D, #$27BB, #$08B2, #$2849, #$1FE8, #$2AC2, - #$807A, #$807B, #$6811, #$807D, #$201B, #$207B, #$07FE, #$2DE3, - #$3111, #$3184, #$0BBA, #$340C, #$36F5, #$3D3A, #$3DF5, #$3DFA, - #$41EC, #$43AB, #$1FEC, #$442D, #$808E, #$50D2, #$4ABB, #$4E79, - #$50D3, #$8093, #$0781, #$81BD, #$8096, #$5182, #$5200, #$8099, - #$809A, #$251D, #$59A4, #$5B01, #$809E, #$5CE0, #$5E1D, #$6545, - #$6638, #$663F, #$66A8, #$80A5, #$68A6, #$6935, #$698E, #$699E, - #$6A23, #$80AB, #$6D3C, #$6E5F, #$6F04, #$3D2F, #$6FDC, #$1FF7, - #$80B2, #$66DD, #$33F7, #$6562); - HKSCS_2Map: array[0..3139] of TBuffChar = ( - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$2EFE, #$2F08, #$2F16, #$107C, #$0ACF, #$2F64, #$2F79, #$0AE0, - #$0AF8, #$3002, #$307D, #$30E5, #$3143, #$0BC8, #$0BD4, #$0BFF, - #$0C0D, #$3297, #$32FD, #$2EA5, #$0C49, #$3377, #$3379, #$338F, - #$0C78, #$33EC, #$3450, #$34A5, #$34D8, #$0CB8, #$2871, #$0CC3, - #$35A2, #$35BB, #$35C7, #$361A, #$0D0B, #$3680, #$2ED5, #$27E1, - #$6FDF, #$0D57, #$3746, #$0D7D, #$37BF, #$3813, #$0DB2, #$3852, - #$0DE2, #$38D6, #$0E02, #$3964, #$39C0, #$0E18, #$3A0A, #$3A44, - #$0E32, #$0E31, #$0E3B, #$3AC9, #$3B03, #$43DC, #$3B24, #$3B5F, - #$3B45, #$0E7C, #$3B96, #$0E9D, #$3C25, #$3C34, #$3C31, #$3C42, - #$0EAC, #$3C59, #$0EB2, #$3C6B, #$3C75, #$3C94, #$3CB6, #$3D41, - #$3D81, #$3DAA, #$3E35, #$3E6A, #$0F4B, #$3EC2, #$3EC6, #$3EE6, - #$3F41, #$0F6F, #$3F64, #$3F71, #$3F95, #$3F98, #$3FA9, #$4006, - #$DD80, #$403B, #$4062, #$405A, #$6FBF, #$4068, #$4069, #$40A4, - #$40B4, #$0FC6, #$AD01, #$4101, #$413E, #$0FEA, #$0FF5, #$4337, - #$2E59, #$100A, #$41AC, #$1011, #$41D0, #$41D4, #$41EF, #$41FF, - #$4209, #$8465, #$1641, #$08B1, #$80F0, - #$7311, #$297E, #$CE93, #$42BE, #$BEE0, #$090E, #$3B62, #$DFA9, - #$2D34, #$4BC9, #$BF61, #$E359, #$4BE5, #$4BFD, #$BFEC, #$4C3B, - #$4C30, #$4C42, #$4C43, #$4351, #$7325, #$144A, #$4C5A, #$4C5D, - #$4C6A, #$146F, #$2672, #$C141, #$4C8B, #$4CD5, #$4CA9, #$7330, - #$C1FE, #$4D22, #$4CEF, #$551C, #$C0F4, #$CC7F, #$4D50, #$55A1, - #$4D12, #$81BD, #$ADB0, #$102D, #$C1A5, #$5612, #$4D7A, #$81BD, - #$4DB5, #$C1C1, #$4DC4, #$4E03, #$7345, #$4E26, #$383D, #$B338, - #$4E49, #$4E47, #$4E66, #$4DF4, #$4E73, #$4E75, #$81BD, #$4FE7, - #$179D, #$CE04, #$4EDD, #$CE96, #$460D, #$4F09, #$4F2B, #$42B5, - #$4F33, #$81BD, #$AE17, #$C3E9, #$4F64, #$0F93, #$4F75, #$93B9, - #$4F65, #$7362, #$81BD, #$C4A1, #$C4DA, #$4FEE, #$5012, #$15AB, - #$652C, #$4FA7, #$50C0, #$50C1, #$50C7, #$4AB6, #$C5D0, #$6AA1, - #$5117, #$C611, #$5123, #$9221, #$8228, #$17DC, #$A9A6, #$1783, - #$DA3A, #$517A, #$C6C9, #$81BD, #$5188, #$519D, #$81BD, #$51AF, - #$7381, #$7382, #$51BB, #$51BC, #$51E1, #$7386, #$1C09, #$C7E6, - #$7389, #$C868, #$38E5, #$5227, #$DE08, #$5287, #$529A, #$2A70, - #$9D36, #$3E3F, #$C6D8, #$7394, #$36A7, #$7396, #$5398, #$941E, - #$3C13, #$B6A5, #$B6D5, #$16FA, #$53A9, #$739E, #$CAD2, #$73A0, - #$21B9, #$917D, #$5662, #$54E2, #$CB0A, #$B5E7, #$A770, #$9333, - #$ABF8, #$542A, #$3ADB, #$EBD4, #$145B, - #$56CB, #$5450, #$549A, #$8B96, #$9374, #$0981, #$73B4, #$A79A, - #$53FB, #$5462, #$5498, #$AC4B, #$CD63, #$73BB, #$CB97, #$A80E, - #$103F, #$549D, #$27AC, #$5505, #$178B, #$CD65, #$552C, #$81BD, - #$5553, #$073E, #$CE94, #$3C17, #$56DA, #$0756, #$CE02, #$73CD, - #$55D8, #$73CF, #$55F1, #$1053, #$1764, #$3C67, #$55CA, #$73D5, - #$4AD8, #$81BD, #$CB96, #$CE37, #$CE03, #$565E, #$81BD, #$5511, - #$1720, #$5613, #$5664, #$73E1, #$14C0, #$C1C0, #$17C3, #$56B4, - #$2CB2, #$73E7, #$17A7, #$56F3, #$1796, #$397F, #$5756, #$DBE5, - #$DBFB, #$5701, #$73F0, #$5742, #$73F2, #$D08D, #$73F4, #$17EA, - #$5768, #$0908, #$9462, #$25B7, #$D1DA, #$57BE, #$58B1, #$E878, - #$592E, #$A0E7, #$58F1, #$591A, #$594F, #$2821, #$57AC, #$3A16, - #$188F, #$5985, #$5986, #$D2A0, #$ABB9, #$D2A4, #$599E, #$59DC, - #$18DB, #$59F4, #$59F5, #$3581, #$5A05, #$48F7, #$D38F, #$5AC7, - #$5ACA, #$81BD, #$81BD, #$5AE7, #$5AFC, #$DDE5, #$5B27, #$D4A4, - #$D5BD, #$5BDC, #$4913, #$62BE, #$5BD0, #$D559, #$4C69, #$D63A, - #$7426, #$1993, #$D638, #$42FC, #$5C4C, #$5C5F, #$BC30, #$BCA5, - #$5C7F, #$5C8C, #$5C8D, #$5BE9, #$B6BA, #$5CD0, #$5CDB, #$5BEF, - #$7436, #$1895, #$598F, #$5D9B, #$D714, #$D74F, #$EC14, #$09E5, - #$D713, #$5DD6, #$D758, #$D77D, #$5E12, #$5E03, #$94D0, #$5DDB, - #$41DC, #$5E11, #$7448, #$1150, #$81BD, - #$5EA9, #$D802, #$744D, #$B5CA, #$0E3C, #$7450, #$D0CC, #$4C67, - #$5FAD, #$5FB6, #$5FC3, #$6394, #$6019, #$602D, #$DA65, #$DA92, - #$60A5, #$63C3, #$E9DF, #$8910, #$60B3, #$1BAA, #$DD9E, #$DB3D, - #$ABBB, #$30B8, #$A522, #$60F9, #$7467, #$7468, #$7469, #$9AA5, - #$0C40, #$CE97, #$6137, #$DB3C, #$D5BE, #$6161, #$DB6C, #$DBCB, - #$61A8, #$7474, #$61C4, #$DC66, #$61AE, #$81BD, #$6227, #$0DB0, - #$6269, #$6284, #$4E2C, #$DCF3, #$9789, #$62CE, #$3E5F, #$6301, - #$6322, #$BCF9, #$81BD, #$DE86, #$AADB, #$DECC, #$BD1B, #$748A, - #$63EC, #$642B, #$DEA1, #$DFAB, #$420F, #$2C83, #$DEA2, #$DEA5, - #$1BE5, #$6304, #$DFAC, #$DFF9, #$DFBF, #$6433, #$651B, #$5FBC, - #$6645, #$6666, #$64E6, #$6660, #$4176, #$1539, #$74A1, #$DC58, - #$8F7C, #$AC2E, #$1C5F, #$3DDC, #$673B, #$6756, #$13EC, #$6763, - #$CE95, #$339A, #$6776, #$4A75, #$DEA0, #$677D, #$258C, #$1C21, - #$CCB8, #$83B4, #$C690, #$E1AF, #$E1E5, #$B711, #$94D5, #$A5CA, - #$67F1, #$5782, #$67F6, #$1C8F, #$17BD, #$1805, #$74C1, #$41F5, - #$2D01, #$67DB, #$81BD, #$74C6, #$6817, #$2D0A, #$E2AB, #$681F, - #$64E5, #$2290, #$A3B7, #$A3BC, #$6849, #$685F, #$6871, #$687E, - #$6880, #$6892, #$68A0, #$BC6C, #$68AE, #$459C, #$E2F3, #$81BD, - #$68B5, #$E2DD, #$74DD, #$1D11, #$68F4, #$68F3, #$690B, #$6926, - #$0DCE, #$D135, #$0FD1, #$8730, #$AF1C, - #$BE46, #$698A, #$6977, #$6988, #$6987, #$1D3F, #$CD27, #$9293, - #$2770, #$69A1, #$69A6, #$69AC, #$6438, #$69F9, #$B669, #$1DB2, - #$E417, #$E4C5, #$6AB5, #$6ACC, #$6AFB, #$6AD0, #$6B18, #$BE65, - #$0984, #$E1B1, #$E5D5, #$6BA0, #$6BA2, #$E585, #$6BB4, #$1E4E, - #$6BD4, #$6BED, #$DBC0, #$21F4, #$6BF4, #$CA28, #$0B83, #$A37D, - #$6C10, #$6C00, #$E67E, #$2C05, #$9423, #$6C4E, #$B00B, #$6CC2, - #$6CBF, #$6CCC, #$E728, #$6E14, #$E837, #$E912, #$751E, #$E861, - #$E8A3, #$E95F, #$6DBE, #$6DC3, #$7524, #$6E4E, #$3A48, #$6E04, - #$7528, #$E913, #$E9A0, #$94FB, #$E9B3, #$6D79, #$752E, #$752F, - #$6ED0, #$6ED5, #$6EDE, #$6EE2, #$1F74, #$6EEA, #$6EEF, #$B124, - #$6F01, #$0E20, #$0CA5, #$0F9D, #$20F2, #$0A7E, #$DFEB, #$6F42, - #$6F48, #$1DD6, #$64E4, #$CD62, #$6F57, #$81BD, #$6F79, #$285F, - #$284A, #$6F85, #$6A78, #$E18B, #$68B2, #$55FF, #$6FA2, #$6FA9, - #$4C5C, #$6FCE, #$4396, #$1DFE, #$B5B5, #$B5FB, #$42F7, #$B638, - #$B108, #$B691, #$451E, #$DF9A, #$94BA, #$4B1F, #$DD3E, #$E0B6, - #$6429, #$64B3, #$DE04, #$63AC, #$6441, #$648B, #$DD2C, #$B279, - #$4397, #$116B, #$48F2, #$4BC3, #$4250, #$756D, #$B1B8, #$42FE, - #$7570, #$4223, #$947E, #$A7D9, #$1147, #$9445, #$BC2F, #$93B8, - #$09E2, #$92BB, #$757A, #$09A1, #$9334, #$757D, #$C34B, #$09E3, - #$9280, #$291B, #$B665, #$90BE, #$7584, - #$9086, #$9136, #$5683, #$A8E6, #$81BD, #$55D5, #$758B, #$D125, - #$AC31, #$BC9C, #$ACBB, #$D012, #$1774, #$A92E, #$E55D, #$CEE6, - #$39B9, #$09F3, #$0ED5, #$1067, #$2A2C, #$759A, #$39D0, #$12D7, - #$A97F, #$759E, #$AE4B, #$75A0, #$CC21, #$268B, #$285E, #$C831, - #$2852, #$75A6, #$89A8, #$8B8D, #$6486, #$75AA, #$645C, #$20B8, - #$22EB, #$0AD9, #$B1F6, #$207C, #$85A5, #$84BF, #$210B, #$214A, - #$BD91, #$2C28, #$82EB, #$850B, #$0C59, #$844A, #$8554, #$06F5, - #$20E9, #$8400, #$E133, #$83B5, #$5C1A, #$75C2, #$2058, #$228D, - #$22CD, #$2162, #$20C3, #$75C8, #$AC4A, #$2102, #$21EE, #$222C, - #$2241, #$218C, #$21A5, #$2218, #$22BC, #$81BD, #$81BD, #$81BD, - #$81BD, #$3FF6, #$A7D5, #$75D8, #$AC7F, #$3F32, #$9444, #$AC49, - #$2368, #$2383, #$86E0, #$175D, #$85E3, #$85D2, #$85D1, #$5E7A, - #$DE5C, #$874E, #$2419, #$2464, #$8833, #$24A1, #$81BD, #$18FA, - #$430C, #$B14C, #$8A20, #$B5EC, #$75F1, #$3B91, #$8B9D, #$81BD, - #$115E, #$4619, #$4594, #$45D6, #$4518, #$1DCE, #$B6FC, #$AE4D, - #$2590, #$0844, #$438F, #$AE89, #$2774, #$8485, #$268D, #$89C6, - #$28DD, #$631D, #$67B4, #$6426, #$299D, #$294D, #$293F, #$08FE, - #$2A8B, #$2C59, #$DE06, #$92BA, #$932F, #$92D0, #$2BEC, #$2B78, - #$634F, #$2C3E, #$2C8F, #$2BD2, #$7619, #$95B3, #$9421, #$761C, - #$09B5, #$3EC5, #$45C3, #$2BE1, #$C2C3, - #$2C41, #$DF97, #$8553, #$64A0, #$460C, #$9003, #$4285, #$1BF2, - #$64C8, #$DDBB, #$647D, #$0A60, #$2DDE, #$2E5E, #$301E, #$3008, - #$9556, #$953C, #$AA6E, #$308D, #$2D0F, #$94C3, #$94C4, #$09C1, - #$9460, #$099D, #$92BE, #$0993, #$52AA, #$DE07, #$96FA, #$A6F2, - #$DD68, #$30CC, #$30CE, #$94E7, #$7646, #$2C2B, #$92FB, #$2D04, - #$5754, #$D2BD, #$59A0, #$323E, #$9E60, #$9C6B, #$319B, #$1138, - #$9C2F, #$9C3E, #$7654, #$CF33, #$3380, #$81FE, #$8206, #$9C5B, - #$3359, #$3358, #$3235, #$A15B, #$A1C7, #$B414, #$7660, #$3631, - #$B3A5, #$A06A, #$0CE9, #$A022, #$A6D0, #$E4AA, #$A2F8, #$34F7, - #$766A, #$3676, #$34F1, #$3591, #$B623, #$A227, #$3464, #$A161, - #$35FB, #$372B, #$3B32, #$0EB4, #$A38E, #$A56D, #$B5C9, #$A56B, - #$26CD, #$A5A0, #$9499, #$767D, #$388E, #$A549, #$7680, #$0DA0, - #$1410, #$BCC4, #$DEE2, #$BCCF, #$92BC, #$BC9B, #$BC25, #$4A6E, - #$A403, #$93EA, #$A4F4, #$0724, #$768E, #$A442, #$B089, #$384E, - #$CD24, #$382B, #$1DD3, #$37F0, #$D470, #$7697, #$3823, #$A592, - #$A5A1, #$37DE, #$BF32, #$0B91, #$769E, #$A9FC, #$0E59, #$A9E2, - #$A67E, #$4650, #$0E56, #$394F, #$B36A, #$3A76, #$39DE, #$0E84, - #$3C7E, #$0B23, #$AA15, #$B247, #$3BF3, #$3C12, #$3C89, #$3CC5, - #$94D2, #$36D1, #$3A58, #$3C0C, #$0E97, #$3C3A, #$3D17, #$AD80, - #$AADA, #$6460, #$63B2, #$DFAA, #$DE8B, - #$6349, #$76C0, #$DD9C, #$6527, #$3F65, #$408B, #$76C5, #$81BD, - #$AD3F, #$100F, #$3F84, #$ADFC, #$2BFD, #$3F8A, #$2A07, #$3EE4, - #$49C2, #$42BB, #$B0DA, #$B036, #$4271, #$43D0, #$4407, #$4414, - #$B48F, #$B465, #$2339, #$B6E4, #$86EB, #$45FA, #$ACB8, #$76DE, - #$76DF, #$B557, #$C3A1, #$1186, #$1131, #$B71F, #$DFE3, #$ACF5, - #$3267, #$1173, #$464C, #$45BC, #$6447, #$45B7, #$171F, #$CDAA, - #$17D1, #$4703, #$11E3, #$B859, #$B886, #$11D8, #$46D5, #$47F3, - #$EA86, #$0DD9, #$45E8, #$DE8C, #$B5EB, #$B5CE, #$0DBB, #$104D, - #$B68E, #$117F, #$7701, #$B533, #$62BA, #$28F2, #$6402, #$DEA3, - #$9424, #$229F, #$BB61, #$BB27, #$48F8, #$A4F2, #$488E, #$488F, - #$48FB, #$B3D7, #$A9C1, #$0D1E, #$7713, #$45B8, #$461B, #$113F, - #$B6FA, #$B707, #$1348, #$B6D6, #$C52E, #$63C7, #$BCC1, #$499E, - #$4A0D, #$4A08, #$4A52, #$4550, #$4AD9, #$D3C1, #$7725, #$138E, - #$81BD, #$5616, #$4B25, #$3BED, #$ACBA, #$4BBA, #$4B74, #$13EE, - #$92A6, #$13B2, #$62F5, #$4B71, #$8B0C, #$B5CC, #$83D9, #$ABBA, - #$932E, #$0857, #$272B, #$0830, #$096A, #$8314, #$773D, #$4C62, - #$2C19, #$9D35, #$7741, #$C01C, #$2BCD, #$839B, #$4A70, #$2BEA, - #$C106, #$4C7E, #$1479, #$4DDD, #$4DED, #$1491, #$C0F3, #$C2FC, - #$C2E6, #$4E4D, #$B639, #$7752, #$4E0E, #$4DFC, #$4E2E, #$3C72, - #$4F5C, #$4F87, #$4F53, #$50CE, #$C5A1, - #$C4DC, #$775D, #$4F17, #$C2C2, #$14EA, #$7761, #$8856, #$3996, - #$820E, #$A80F, #$2984, #$C692, #$7768, #$B5A2, #$515D, #$4CA7, - #$87EC, #$C069, #$C243, #$4C8C, #$C28E, #$6AA6, #$5785, #$6B23, - #$3BDC, #$7775, #$0CA2, #$B637, #$C7AD, #$6ADF, #$777A, #$5600, - #$D0E7, #$777D, #$176A, #$52B7, #$1682, #$5246, #$5289, #$52C2, - #$C8F4, #$6983, #$CAC2, #$53E2, #$53E5, #$CAD1, #$55D3, #$CD67, - #$5750, #$D15B, #$2C46, #$13FF, #$7790, #$2CEB, #$9461, #$2CA4, - #$9498, #$57E0, #$5868, #$7797, #$596D, #$D222, #$2BC2, #$59AE, - #$2105, #$59C7, #$59FF, #$5A26, #$5AA5, #$5A8D, #$BDC3, #$5A94, - #$D405, #$D404, #$77A6, #$DF99, #$DF5C, #$DDB9, #$112D, #$5623, - #$1975, #$194F, #$0AB2, #$5B7D, #$5B5C, #$E308, #$310D, #$62EB, - #$77B4, #$3794, #$42A9, #$4244, #$9405, #$6DAD, #$5D9F, #$5DE9, - #$D79C, #$2B5A, #$4943, #$2BB0, #$15EE, #$0994, #$5F2A, #$5FA7, - #$B7C9, #$6030, #$604A, #$1574, #$3E18, #$413B, #$9AA1, #$1B1B, - #$40F9, #$400B, #$939A, #$6CA9, #$0975, #$B56F, #$61BB, #$81BD, - #$2731, #$1B86, #$627B, #$64C4, #$DE0B, #$12E2, #$77DA, #$64E7, - #$DFDD, #$77DD, #$5665, #$5B6B, #$6659, #$6667, #$6657, #$6656, - #$E074, #$45C5, #$1142, #$B53F, #$77E8, #$77E9, #$1167, #$A4E5, - #$674F, #$77ED, #$E0E6, #$E0E5, #$114C, #$77F1, #$B6B8, #$ADAE, - #$4592, #$45EB, #$117C, #$6801, #$E1B0, - #$3A07, #$1C9D, #$77FB, #$77FC, #$81BD, #$6428, #$DD49, #$7800, - #$DEEF, #$C67E, #$637A, #$2CD1, #$5CA9, #$1BBC, #$4579, #$AFDB, - #$685B, #$6831, #$69F8, #$780C, #$2F81, #$DF85, #$B6F2, #$68DF, - #$E35A, #$63B6, #$7813, #$62A5, #$1740, #$DF10, #$B6A7, #$DF24, - #$699C, #$DE05, #$1180, #$62EA, #$1BA5, #$5594, #$69FB, #$6A0D, - #$7821, #$107D, #$6A5B, #$1DAF, #$6A6A, #$6B1C, #$DF25, #$7828, - #$3C4F, #$6AE1, #$2CBE, #$6AEF, #$782D, #$1DD0, #$782F, #$6A7C, - #$1DFD, #$1DD7, #$643D, #$2A32, #$9002, #$29E2, #$B5F8, #$9168, - #$49C4, #$9D5F, #$ABB8, #$3A85, #$0FFD, #$6518, #$0BE7, #$3310, - #$9DC1, #$9F6B, #$32C7, #$6D0F, #$6D13, #$6D3B, #$6CF5, #$6CD0, - #$6C3F, #$6C8F, #$E6ED, #$6C5F, #$784D, #$E87E, #$6D61, #$1EEE, - #$AEC4, #$6E58, #$1EF0, #$6D4C, #$7855, #$7856, #$E873, #$E4EF, - #$6DE5, #$563D, #$785B, #$CF9F, #$785D, #$573C, #$17B3, #$CD64, - #$CE44, #$CDB0, #$55A0, #$572E, #$7865, #$AA17, #$C424, #$4B62, - #$A7DC, #$A880, #$1BAD, #$B61E, #$0FE2, #$649B, #$637E, #$6408, - #$83FF, #$4A39, #$6337, #$650D, #$21A4, #$0700, #$6164, #$BC9D, - #$49BD, #$49D4, #$4A36, #$49CB, #$9317, #$A489, #$B581, #$095A, - #$2132, #$415A, #$4159, #$81BD, #$419E, #$25D4, #$7887, #$297B, - #$2AB3, #$294A, #$6D56, #$2997, #$42B4, #$076F, #$788F, #$436B, - #$7891, #$BA17, #$81BD, #$9375, #$DE09, - #$32CC, #$2C8E, #$2BCB, #$153C, #$B248, #$09EC, #$1DBB, #$DDBC, - #$647B, #$6478, #$9496, #$78A1, #$55F2, #$CCC0, #$78A4, #$B0BA, - #$A0E6, #$B181, #$2B54, #$ABB7, #$C881, #$4F28, #$C4DB, #$C464, - #$B5F9, #$B5CB, #$DDBA, #$63A5, #$4562, #$1169, #$4634, #$DF23, - #$945F, #$1161, #$B6F3, #$3C98, #$4573, #$457B, #$1156, #$B67E, - #$B6D4, #$9399, #$B6A6, #$84E7, #$78C2, #$78C3, #$45C8, #$B556, - #$4225, #$B5B6, #$6344, #$4566, #$641F, #$863E, #$63F1, #$78CD, - #$DDD6, #$6446, #$DFA7, #$BD15, #$1BB5, #$DE42, #$42EB, #$78D5, - #$78D6, #$2864, #$871A, #$78D9, #$78DA, #$26C2, #$4B44, #$93BA, - #$4F7E, #$9282, #$B690, #$78E1, #$17AE, #$64C1, #$09CA, #$78E5, - #$B5ED, #$2B70, #$947F, #$9443, #$D244, #$2C61, #$09A2, #$AB5B, - #$0970, #$631F, #$2C39, #$DE41, #$9422, #$6434, #$0F4D, #$8974, - #$1CD6, #$0C4A, #$22B4, #$0FE9, #$0FCC, #$905C, #$42F5, #$157B, - #$78FE, #$3F8F, #$E1E4, #$176B, #$3F17, #$D7CF, #$41E7, #$3E6F, - #$0F56, #$ADAD, #$AC2D, #$3F82, #$408C, #$0FEF, #$8535, #$46D1, - #$097C, #$0788, #$1900, #$115A, #$1AF1, #$2B84, #$632E, #$1BBE, - #$6041, #$7917, #$7918, #$29D2, #$2988, #$0996, #$90D2, #$427E, - #$B122, #$791F, #$A323, #$8FB0, #$9AFD, #$3A79, #$3B27, #$7925, - #$A725, #$D674, #$A91F, #$DE43, #$AA16, #$792B, #$B81F, #$3BDA, - #$A8ED, #$CCB7, #$55BE, #$175F, #$174E, - #$CD26, #$7934, #$CC82, #$CF9E, #$4097, #$D0C9, #$54BD, #$92FA, - #$556D, #$CC80, #$D013, #$939B, #$2B49, #$2C42, #$9373, #$2C21, - #$2C31, #$94C5, #$AFBC, #$09ED, #$2BAF, #$92FC, #$0987, #$430E, - #$6450, #$385A, #$B065, #$2C2E, #$2BEB, #$7950, #$3BEB, #$ACB9, - #$D3B6, #$B21B, #$B08A, #$429D, #$B019, #$DDA1, #$2170, #$CD28, - #$2E82, #$B28E, #$D7CD, #$B17D, #$3BCC, #$B016, #$9004, #$4226, - #$42B3, #$B1A9, #$1025, #$3E9F, #$7967, #$B68F, #$4FE5, #$2BAB, - #$2EEF, #$1073, #$311C, #$796E, #$796F, #$4F24, #$55A6, #$2645, - #$7973, #$A5C0, #$8354, #$293E, #$7977, #$8719, #$1265, #$797A, - #$797B, #$4183, #$797D, #$2F30, #$450F, #$4E53, #$DE19, #$7982, - #$2188, #$5167, #$444D, #$4490, #$D5F4, #$44B8, #$44B9, #$BE36, - #$44C1, #$44C8, #$1129, #$D618, #$616C, #$4375, #$7991, #$4561, - #$5376, #$114A, #$488C, #$1151, #$3E62, #$28BD, #$4599, #$459E, - #$459F, #$1162, #$1170, #$1174, #$117A, #$4653, #$118E, #$11D3, - #$46C2, #$46ED, #$46F2, #$470D, #$11FC, #$4748, #$475C, #$1240, - #$47CD, #$1257, #$47F4, #$125C, #$47FA, #$B9DC, #$4308, #$27E3, - #$5AC0, #$2A29, #$129D, #$48C3, #$12B9, #$3921, #$12C5, #$089B, - #$4918, #$12EA, #$12EF, #$2E1E, #$493E, #$494B, #$2AB2, #$4998, - #$4239, #$499C, #$1328, #$49B9, #$49C7, #$49D1, #$49E6, #$55C8, - #$79CB, #$4AB3, #$39C3, #$4AB2, #$1383, - #$1389, #$4B11, #$4B19, #$60BB, #$4B86, #$60BC, #$13E7, #$4C11, - #$1432, #$4C3C, #$53F9, #$1444, #$4C4F, #$4C5B, #$144F, #$1FE1, - #$4CE2, #$4CEC, #$4CFB, #$4D92, #$4D9B, #$14E0, #$14FA, #$4DFB, - #$4E1C, #$150C, #$4E38, #$1514, #$4E6D, #$6093, #$4240, #$8ACF, - #$4F4F, #$4F54, #$4F50, #$4F7D, #$512E, #$5134, #$441F, #$1617, - #$51A0, #$51A5, #$4CB9, #$51AE, #$51B1, #$51D4, #$104C, #$2974, - #$4220, #$5237, #$5269, #$166D, #$528C, #$44AA, #$528E, #$5292, - #$46E0, #$5294, #$1681, #$0DF9, #$52D6, #$52D9, #$52DA, #$1693, - #$29FA, #$52FC, #$5304, #$16A5, #$5313, #$16AD, #$5325, #$29AF, - #$5341, #$5364, #$53D4, #$170F, #$5426, #$53F6, #$544A, #$5458, - #$547F, #$1730, #$54D7, #$6729, #$3B4A, #$5585, #$4275, #$55E4, - #$32A3, #$5608, #$1784, #$563E, #$5661, #$5678, #$5690, #$56B8, - #$56D2, #$17BB, #$56EF, #$56F0, #$5720, #$17F7, #$57B2, #$57D2, - #$57F2, #$582F, #$6705, #$58CB, #$1886, #$1897, #$59EE, #$5A3F, - #$5A64, #$5A87, #$5AD1, #$D4E7, #$5B69, #$5B78, #$5BD4, #$5BF4, - #$5D51, #$5DD4, #$5DF2, #$5E1C, #$1A18, #$2A1F, #$5EC3, #$1A6D, - #$20AE, #$5F3A, #$2798, #$2914, #$5F71, #$27B5, #$5FB0, #$1AB7, - #$5FCE, #$5FE2, #$5FE4, #$5FED, #$5FF2, #$60B7, #$60C1, #$60CA, - #$60CC, #$6133, #$6A84, #$1B2D, #$69A0, #$62D3, #$1B9E, #$62E8, - #$6318, #$632B, #$6371, #$636E, #$637F, - #$63A3, #$63AB, #$63B3, #$63B4, #$63BD, #$6403, #$6444, #$646D, - #$1BC5, #$1BD1, #$6EFF, #$64D7, #$24C1, #$64DD, #$64ED, #$64FE, - #$1BEA, #$6514, #$6539, #$65ED, #$6662, #$1C27, #$66B4, #$66F3, - #$1C65, #$3960, #$1CA4, #$6800, #$1CB5, #$6872, #$6882, #$2814, - #$1D24, #$32A8, #$6979, #$1D59, #$69B1, #$2A04, #$69CE, #$69D9, - #$2374, #$69DC, #$69F7, #$6A02, #$6A1D, #$6A22, #$1DB0, #$6A85, - #$1DDD, #$6AFC, #$6BCF, #$4C03, #$6C29, #$6C41, #$6C9D, #$6CB1, - #$6CB4, #$1EAD, #$6CE0, #$0A2F, #$7A29, #$6D89, #$6CFA, #$6F3E, - #$2810, #$6DD3, #$6DFD, #$6E00, #$6E3C, #$65B6, #$60B6, #$6EBB, - #$6EEC, #$6EF1, #$6EFD, #$6F06, #$659C, #$6F22, #$6F31, #$6F38, - #$4C48, #$6F84, #$7A3F, #$7A40, #$7A41, #$3ADA, #$6583, #$2B6C, - #$7A45, #$2A00, #$6581, #$0A79, #$7A49, #$7A4A, #$7A4B, #$7A4C, - #$2917, #$42F3, #$7A4F, #$7A50, #$7A51, #$262A, #$7A53, #$7A54, - #$265E, #$7A56, #$7A57, #$8A53, #$7A59, #$7A5A, #$32A7, #$7A5C, - #$283A, #$7A5E, #$7A5F, #$7A60, #$7A61, #$7A62, #$7A63, #$3B15, - #$6CEF, #$58E5, #$7A67, #$8B8E, #$7A69, #$7A6A, #$8CAD, #$7A6C, - #$2DE0, #$7A6E, #$2FCB, #$7A70, #$7A71, #$8DB6, #$38DE, #$8DBB, - #$7A75, #$7A76, #$0907, #$7A78, #$7A79, #$7A7A, #$7A7B, #$2524, - #$562D, #$8FE3, #$7A7F, #$7A80, #$5CC1, #$7A82, #$7A83, #$7A84, - #$7A85, #$2038, #$423B, #$7A88, #$7A89, - #$7A8A, #$7A8B, #$7A8C, #$7A8D, #$7A8E, #$7A8F, #$3483, #$97D5, - #$7A92, #$4318, #$3A15, #$7A95, #$3BA9, #$0988, #$9A7C, #$7A99, - #$7A9A, #$7A9B, #$7A9C, #$7A9D, #$547D, #$7A9F, #$7AA0, #$9FD5, - #$5AE5, #$7AA3, #$60A0, #$7AA5, #$6878, #$7AA7, #$6907, #$6B7D, - #$7AAA, #$81BD, #$7AAC, #$7AAD, #$7AAE, #$A1C8, #$7AB0, #$7AB1, - #$7AB2, #$7AB3, #$7AB4, #$7AB5, #$7AB6, #$7AB7, #$7AB8, #$7AB9, - #$3171, #$3808, #$387F, #$7ABD, #$7ABE, #$7ABF, #$81BD, #$B5FA, - #$81BD, #$7AC3, #$7AC4, #$81BD, #$8486, #$2A75, #$38CE, #$3AD8, - #$7ACA, #$D317, #$C3A2, #$7ACD, #$7ACE, #$D2BE, #$98DA, #$1B50, - #$1CF8, #$7AD3, #$DE5A, #$7AD5, #$7AD6, #$ADFB, #$7AD8, #$B156, - #$7ADA, #$7ADB, #$2392, #$8711, #$2B5F, #$97A8, #$0E7E, #$AB3F, - #$7AE2, #$7AE3, #$2948, #$7AE5, #$0C5B, #$7AE7, #$7AE8, #$7AE9, - #$0A22, #$9A03, #$5C9E, #$DF0E, #$81BD, #$7AEF, #$7AF0, #$7AF1, - #$4389, #$7AF3, #$8A78, #$2B25, #$7AF6, #$7AF7, #$87B9, #$5FDA, - #$7AFA, #$244F, #$28FF, #$42F1, #$7AFE, #$7AFF, #$7B00, #$B6E7, - #$277C, #$7B03, #$BC6E, #$CB52, #$81BD, #$0733, #$7B08, #$D2F2, - #$7B0A, #$1998, #$7B0C, #$BCA6, #$BEC7, #$B57F, #$7B10, #$2226, - #$07BB, #$7B13, #$81BD, #$7B15, #$19FC, #$DD08, #$C02E, #$7B19, - #$C146, #$7B1B, #$2961, #$42D1, #$81BD, #$7B1F, #$D692, #$6156, - #$7B22, #$BA1A, #$5CA2, #$7B25, #$7B26, - #$2F1B, #$CBF7, #$81BD, #$7B2A, #$7B2B, #$5C2A, #$B636, #$7B2E, - #$ADAF, #$C712, #$1E00, #$7B32, #$7B33, #$9D5B, #$6525, #$BEE1, - #$3355, #$2BE7, #$EB8D, #$81BD, #$2879, #$B2E1, #$7B3D, #$202A, - #$7B3F, #$6716, #$3F4F, #$CCBD, #$08D8, #$5AB7, #$7B45, #$C96E, - #$C691, #$C95E, #$81BD, #$7B4A, #$4CC2, #$7B4C, #$88D1, #$7B4E, - #$81BD, #$7B50, #$4BC5, #$81BD, #$CA7A, #$6AE6, #$7B55, #$091F, - #$7B57, #$7B58, #$4B03, #$7B5A, #$7B5B, #$2EEC, #$7B5D, #$81BD, - #$7B5F, #$1950, #$7B61, #$46BB, #$59A5, #$7B64, #$2A76, #$09DC, - #$9C0D, #$7B68, #$7B69, #$0F14, #$7B6B, #$7B6C, #$6341, #$99BA, - #$7B6F, #$63F0, #$D1A6, #$7B72, #$3DF9, #$655F, #$7B75, #$8C78, - #$5967, #$5A35, #$7B79, #$7B7A, #$9371, #$4038, #$B66A, #$7B7E, - #$0C64, #$0979, #$81BD, #$81BD, #$17BF, #$3876, #$E62D, #$E464, - #$5A83, #$7B88, #$7B89, #$2896, #$135F, #$91CA, #$0C61, #$A96F, - #$7B8F, #$9085, #$432D, #$54E6, #$7B93, #$E268, #$81BD, #$1EF7, - #$D06F, #$DD6B, #$7B99, #$7B9A, #$7B9B, #$7B9C, #$AF3A, #$4CC3, - #$4AFE, #$D809, #$4135, #$EA1F, #$3BC3, #$7BA4, #$2562, #$7BA6, - #$647F, #$39F6, #$681D, #$D92F, #$7BAB, #$CA35, #$90AD, #$A4EF, - #$7BAF, #$2F45, #$DFF0, #$7BB2, #$28D5, #$68E3, #$DD09, #$2F6B, - #$B5C8, #$377E, #$3B95, #$2592, #$B6E5, #$AD41, #$0ED1, #$38F6, - #$7BBF, #$D8B4, #$D8EE, #$9861, #$7BC3, - #$7BC4, #$7BC5, #$7BC6, #$7BC7, #$7BC8, #$7BC9, #$088A, #$7BCB, - #$DC2A, #$1B7A, #$35A6, #$7BCF, #$4988, #$6315, #$7BD2, #$1672, - #$7BD4, #$165F, #$7BD6, #$7BD7, #$7BD8, #$2BB8, #$7BDA, #$81BD, - #$7BDC, #$7BDD, #$81BD, #$E210, #$7BE0, #$1077, #$7BE2, #$7BE3, - #$60D0, #$440F, #$284B, #$7BE7, #$E3E9, #$7BE9, #$7BEA, #$7BEB, - #$7BEC, #$7BED, #$E52A, #$7BEF, #$7BF0, #$E58E, #$7BF2, #$7BF3, - #$501F, #$7BF5, #$E7E3, #$1EE4, #$6607, #$7BF9, #$4322, #$7BFB, - #$1F91, #$6112, #$7BFE, #$1F9C, #$8A9C, #$60BE, #$2781, #$60BA, - #$7C04, #$60B9, #$B6D3, #$1789, #$4FFF, #$40D6, #$3C71, #$20AA, - #$07A4, #$DEEC, #$7C0E, #$09FA, #$5F80, #$93B5, #$7C12, #$DF2C, - #$DF59, #$7C15, #$C82F, #$106B, #$D315, #$AAF7, #$BD75, #$BF96, - #$205A, #$C2C1, #$C598, #$287F, #$8BED, #$5F0E, #$2D2D, #$AC48, - #$B81E, #$359E, #$81BD, #$93B6, #$943B, #$36F0, #$27ED, #$C18A, - #$25DA, #$BBD1, #$1046, #$7C2F, #$1EBD, #$27E2, #$27DE, #$50C9, - #$C318, #$2B35, #$7C36, #$58B0, #$1FDC, #$8D2A, #$8B09, #$A8FA, - #$5297, #$6D9E, #$5E18, #$47BB, #$6D05, #$47CE, #$4939, #$6405, - #$25F2, #$52C8, #$5477, #$27E5, #$52B2, #$5598, #$523D, #$27AA, - #$4AE2, #$2803, #$25D6, #$7C4F, #$088E, #$27C5, #$27B1, #$38B1, - #$D9E2, #$08ED, #$46B4, #$27B0, #$277A, #$2657, #$2732, #$8A41, - #$7C5C, #$3090, #$BAC8, #$8BF6, #$7C60, - #$7C61, #$6EEB, #$4EDA, #$279E, #$8DB5, #$345D, #$682D, #$2654, - #$5DCD, #$4376, #$6236, #$35BC, #$3579, #$35BE, #$2729, #$7C70, - #$6D32, #$7C72, #$235A, #$079F, #$8B67, #$2367, #$260D, #$26DE, - #$26D3, #$47E6, #$5F2D, #$7C7C, #$4731, #$5236, #$5944, #$58C6, - #$5A07, #$5336, #$559C, #$8E01, #$176C, #$4484, #$B446, #$2D50, - #$548B, #$C993, #$283B, #$9D34, #$D6EF, #$AF63, #$D733, #$CE90, - #$7C91, #$6230, #$8F19, #$62C8, #$AB3C, #$EAE9, #$8C2C, #$8C79, - #$43E6, #$9662, #$19CE, #$BA42, #$7C9D, #$8D2B, #$137A, #$6D1D, - #$36DF, #$A260, #$1B73, #$7CA4, #$E6BC, #$8D2C, #$8B8A, #$81BD, - #$7CA9, #$8D2D, #$81BD, #$7CAC, #$8EC7, #$4323, #$500E, #$6D90, - #$1FDA, #$1FC4, #$0837, #$2CCD, #$3E72, #$2527, #$096C, #$0C9C, - #$253D, #$0965, #$7CBB, #$2A5A, #$B76E, #$53AD, #$260B, #$296A, - #$7CC1, #$88B9, #$81BD, #$0D12, #$9B65, #$44F4, #$E76C, #$1F49, - #$6CAD, #$AB3E, #$E7F0, #$1E9B, #$BA29, #$E39E, #$7CCF, #$55DC, - #$ABB6, #$7CD2, #$C8F3, #$A960, #$34EE, #$4EA5, #$ACB7, #$AC2C, - #$0CEA, #$6108, #$248C, #$10F4, #$093A, #$1869, #$7CDF, #$47C0, - #$2CB0, #$8C36, #$49FA, #$1A36, #$2A67, #$133F, #$283C, #$6C4B, - #$2F34, #$47D4, #$7CEB, #$6EC5, #$1F21, #$81BD, #$0ABB, #$32D9, - #$A3DA, #$B1B2, #$81BD, #$281D, #$8FA9, #$2967, #$B5A3, #$7CF8, - #$23F4, #$D06E, #$086D, #$81BD, #$6DBC, - #$4DD6, #$6BF9, #$299E, #$932C, #$2E13, #$3693, #$7D04, #$7D05, - #$D124, #$57ED, #$7D08, #$CD22, #$B722, #$7D0B, #$81BD, #$23BE, - #$7D0E, #$2F4E, #$67C3, #$9711, #$6EC1, #$614C, #$4C9F, #$6BC2, - #$2E91, #$4D23, #$3428, #$34F5, #$6BBF, #$4D4F, #$6BEA, #$4DFE, - #$81BD, #$4DC2, #$4E06, #$6CD5, #$4D7C, #$6BC9, #$81BD, #$6CDB, - #$B57E, #$6F9A, #$2733, #$2D83, #$21BD, #$6ED8, #$21B2, #$2420, - #$1086, #$2491, #$2927, #$2216, #$2B77, #$2FD2, #$6888, #$6DEB, - #$605C, #$2629, #$6874, #$6A00, #$687A, #$24EC, #$32F0, #$3AEC, - #$259A, #$6CCA, #$6D42, #$1E7B, #$6701, #$3B40, #$2266, #$46C6, - #$932D, #$6A9A, #$2433, #$81BD, #$6219, #$6741, #$621C, #$81BD, - #$6211, #$7D4F, #$353F, #$CD23, #$3C8A, #$27D1, #$624E, #$46FA, - #$3445, #$853C, #$44CF, #$4DF0, #$7D5A, #$AB3D, #$81BD, #$B559, - #$4856, #$6C5D, #$1FEA, #$8AD4, #$553E, #$5982, #$81BD, #$2E0A, - #$3B80, #$81BD, #$293A, #$23DF, #$2FB5, #$208E, #$3DF1, #$7D6D, - #$20F9, #$265C, #$269A, #$245A, #$5E82, #$08BE, #$81BD, #$08B3, - #$81BD, #$3D12, #$623C, #$6FE5, #$6C57, #$68EE, #$6974, #$6B7A, - #$6EE8, #$6EC4, #$42FA, #$4C94, #$81BD, #$3DBA, #$5958, #$50F8, - #$81BD, #$27E0, #$7D88, #$5F77, #$6F93, #$81BD, #$5ED4, #$5F4F, - #$6E5C, #$5F01, #$3442, #$DA7D, #$5F28, #$5F75, #$4C53, #$B6B7, - #$4BBE, #$4A58, #$3EAA, #$5BA7, #$4787, - #$DE1A, #$6F66, #$3E8E, #$5916, #$4743, #$E9F2, #$49D3, #$EB00, - #$5E0C, #$4462, #$44F1, #$5C6D, #$4482, #$4671, #$5DEB, #$B6FB, - #$576F, #$317A, #$59E0, #$1737, #$81BD, #$93FB, #$CDC5, #$81BD, - #$5BBE, #$9BDB, #$81BD, #$32BD, #$47E7, #$6B97, #$6D84, #$642E, - #$6C4F, #$5935, #$81BD, #$81BD, #$5DF7, #$44AC, #$67E1, #$6C70, - #$0896, #$4432, #$1E47, #$4DD1, #$6A0A, #$C4D9, #$3319, #$1E44, - #$6ED6, #$333D, #$81BD, #$291F, #$332F, #$3466, #$33F9, #$81BD, - #$0D1C, #$33A2, #$256A, #$A675, #$3524, #$39C2, #$0892, #$2F17, - #$DF82, #$60DA, #$7DDD, #$81BD, #$2299, #$9686, #$4A86, #$24F2, - #$66F8, #$8CBB, #$12E5, #$81BD, #$497E, #$81BD, #$4E42, #$7DEA, - #$4E5A, #$4BAD, #$51E6, #$51E3, #$4ECD, #$4685, #$4672, #$5AD4, - #$539A, #$38CC, #$51E2, #$D246, #$51DB, #$4670, #$5283, #$48A4, - #$5AC9, #$C90C, #$46D3, #$CE91, #$58E9, #$590E, #$5348, #$58CC, - #$5B89, #$5DAD, #$5C83, #$48AB, #$4678, #$565A, #$08F5, #$3B72, - #$5EA6, #$81BD, #$5AE9, #$81BD, #$3F79, #$5901, #$ADD1, #$4667, - #$105B, #$42F6, #$3264, #$335C, #$0F51, #$81BD, #$3237, #$81BD, - #$50F1, #$DEED, #$81BD, #$32A9, #$1DBE, #$23E0, #$0ED8, #$AB07, - #$C317, #$D316, #$7E25, #$9504, #$8FFE, #$E4C3, #$CD9C, #$D06D, - #$2E81, #$C52D, #$DDCF, #$A8B7, #$826E, #$7E30, #$B98E, #$17E2, - #$2CDF, #$7E34, #$6F90, #$6EE6, #$7E37); - HKSCS_3Map: array[0..470] of TBuffChar = ( - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$0420, - #$0421, #$0422, #$0423, #$0424, #$0425, #$0426, #$0427, #$0428, - #$0429, #$0434, #$0435, #$0436, #$0437, #$0438, #$0439, #$043A, - #$043B, #$043C, #$043D, #$0370, #$0371, #$0372, #$0373, #$0374, - #$0375, #$0376, #$0377, #$0378, #$0379, #$1FF6, #$1FFF, #$2045, - #$2060, #$2342, #$2356, #$236B, #$24B9, #$24F8, #$2529, #$2576, - #$2ACA, #$2D40, #$2F9B, #$0573, #$303F, #$81BD, #$3110, #$3121, - #$36F4, #$81BD, #$4712, #$81BD, #$60B5, #$81BD, #$0028, #$01C6, - #$067D, #$067E, #$061D, #$061E, #$81BD, #$81BD, #$0585, #$0586, - #$0587, #$067C, #$817B, #$817D, #$04BD, #$05C1, #$05C2, #$05C3, - #$05C4, #$05C5, #$05C6, #$05C7, #$05C8, #$05C9, #$05CA, #$05CB, - #$05CC, #$05CD, #$05CE, #$05CF, #$05D0, #$05D1, #$05D2, #$05D3, - #$05D4, #$05D5, #$05D6, #$05D7, #$05D8, - #$05D9, #$05DA, #$05DB, #$05DC, #$05DD, #$05DE, #$05DF, #$05E0, - #$05E1, #$05E2, #$05E3, #$05E4, #$05E5, #$05E6, #$05E7, #$05E8, - #$05E9, #$05EA, #$05EB, #$05EC, #$05ED, #$05EE, #$05EF, #$05F0, - #$05F1, #$05F2, #$05F3, #$05F4, #$05F5, #$05F6, #$05F7, #$05F8, - #$05F9, #$05FA, #$05FB, #$05FC, #$05FD, #$05FE, #$05FF, #$0600, - #$0601, #$0602, #$0603, #$0604, #$0605, #$0606, #$0607, #$0608, - #$0609, #$060A, #$060B, #$060C, #$060D, #$060E, #$060F, #$0610, - #$0611, #$0612, #$0613, #$0621, #$0622, #$0623, #$0624, #$0625, - #$0626, #$0627, #$0628, #$0629, #$062A, #$062B, #$062C, #$062D, - #$062E, #$062F, #$0630, #$0631, #$0632, #$0633, #$0634, #$0635, - #$0636, #$0637, #$0638, #$0639, #$063A, #$063B, #$063C, #$063D, - #$063E, #$063F, #$0640, #$0641, #$0642, #$0643, #$0644, #$0645, - #$0646, #$0647, #$0648, #$0649, #$064A, #$064B, #$064C, #$064D, - #$064E, #$064F, #$0650, #$0651, #$0652, #$0653, #$0654, #$0655, - #$0656, #$0657, #$0658, #$0659, #$065A, #$065B, #$065C, #$065D, - #$065E, #$065F, #$0660, #$0661, #$0662, #$0663, #$0664, #$0665, - #$0666, #$0667, #$0668, #$0669, #$066A, #$066B, #$066C, #$066D, - #$066E, #$066F, #$0670, #$0671, #$0672, #$0673, #$0674, #$0675, - #$0676, #$0210, #$0211, #$0212, #$0213, #$0214, #$0215, #$0201, - #$0216, #$0217, #$0218, #$0219, #$021A, - #$021B, #$021C, #$021D, #$021E, #$021F, #$0220, #$0221, #$0222, - #$0223, #$0224, #$0225, #$0226, #$0227, #$0228, #$0229, #$022A, - #$022B, #$022C, #$022D, #$022E, #$022F, #$0230, #$0231, #$0232, - #$0233, #$0234, #$0235, #$0251, #$0236, #$0237, #$0238, #$0239, - #$023A, #$023B, #$023C, #$023D, #$023E, #$023F, #$0240, #$0241, - #$0242, #$0243, #$0244, #$0245, #$0246, #$0247, #$0248, #$0249, - #$024A, #$024B, #$024C, #$024D, #$024E, #$024F, #$03E7, #$03B8, - #$03B9, #$8125, #$8126, #$201A, #$8128, #$23C2, #$812A, #$812B, - #$2348, #$812D, #$812E, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81A2, #$81A4, #$8147, #$8142, #$06B1, - #$0316, #$0321, #$061B, #$061C, #$04C0, #$04C4, #$04C6, #$04C7, - #$04C8, #$04CA, #$04CC, #$04CD, #$04D5, #$04DC, #$04DD, #$04E5, - #$04E7, #$04EA, #$04EC, #$04EE, #$04F6, #$04FC, #$04FE, #$0506, - #$050A, #$050C, #$050D, #$050F, #$0516, #$0517, #$051E, #$0523, - #$81BD, #$81BD, #$81BD, #$0183, #$0150, #$015B, #$0154, #$0175, - #$00D3, #$0078, #$00CB, #$018A, #$016A); - HKSCS_4Map: array[0..941] of TBuffChar = ( - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, #$81BD, - #$81BD, #$81BD, #$81BD, #$81BD, #$4A01, #$6379, #$5A0F, #$2A7B, - #$3212, #$4E27, #$2CBA, #$0454, #$0466, #$0457, #$0460, #$046C, - #$0463, #$045A, #$0469, #$045D, #$0452, #$0464, #$0455, #$045E, - #$046A, #$0461, #$0458, #$0467, #$045B, #$0453, #$0465, #$0456, - #$045F, #$046B, #$0462, #$0459, #$0468, #$045C, #$0451, #$0450, - #$046D, #$046E, #$0470, #$046F, #$81AD, - #$8647, #$639B, #$86DF, #$7003, #$56CC, #$1535, #$456F, #$2375, - #$0909, #$B582, #$DDA4, #$6404, #$959B, #$546E, #$AB08, #$49BC, - #$3904, #$349F, #$B573, #$DD6A, #$83E0, #$CBB3, #$9005, #$216B, - #$7018, #$21C8, #$CD29, #$701B, #$A840, #$B6F1, #$9BD3, #$81BD, - #$84BE, #$3164, #$84C0, #$8487, #$405B, #$855F, #$81BD, #$22C1, - #$073A, #$22CE, #$692C, #$0A03, #$5596, #$702D, #$85C7, #$2320, - #$A634, #$232A, #$89FF, #$993C, #$8425, #$9BF0, #$868E, #$A4F3, - #$7038, #$2D42, #$58BD, #$86B3, #$AAD9, #$2372, #$2378, #$6D74, - #$2389, #$238F, #$2391, #$0F5C, #$2393, #$B6E6, #$2373, #$23A2, - #$2502, #$23AD, #$554D, #$3AFE, #$704C, #$313B, #$23CB, #$23E6, - #$23FC, #$2475, #$2417, #$2454, #$2479, #$2485, #$4D95, #$56C2, - #$24A0, #$574D, #$705A, #$81BD, #$DE9E, #$2709, #$4059, #$AD40, - #$8894, #$ADAC, #$24F3, #$81BD, #$89E2, #$3E8B, #$92E6, #$39DB, - #$4555, #$320A, #$112A, #$0B8C, #$92A8, #$435D, #$1722, #$252D, - #$2534, #$DC2B, #$253E, #$81BD, #$9196, #$91D3, #$4966, #$2553, - #$DE5B, #$2560, #$256B, #$256E, #$4527, #$BEB2, #$11D9, #$451C, - #$2581, #$2585, #$3E09, #$2009, #$29BE, #$2599, #$0D6B, #$898F, - #$25A0, #$ADAB, #$A263, #$25B6, #$8A77, #$25D3, #$41F9, #$26EB, - #$3817, #$3F1B, #$262D, #$CB53, #$7094, #$271D, #$264F, #$2664, - #$1A26, #$7099, #$709A, #$1034, #$8B0D, - #$DD7C, #$9CD8, #$2707, #$1F2D, #$25EF, #$4597, #$2746, #$2769, - #$81BD, #$9497, #$ADFA, #$17D2, #$B1F5, #$3873, #$8DF4, #$27F7, - #$388D, #$A54A, #$3864, #$386D, #$280D, #$280F, #$4A71, #$28B1, - #$6847, #$25BE, #$28C0, #$28AF, #$28AD, #$DF26, #$08E3, #$8F4F, - #$2906, #$AF65, #$3E2E, #$420B, #$2902, #$0971, #$CC7E, #$29A6, - #$70C5, #$29C3, #$90D4, #$B123, #$29E6, #$B7B5, #$2A1C, #$2A6A, - #$0821, #$2AA0, #$2A9C, #$70D0, #$2ABB, #$2DBF, #$2903, #$E8D0, - #$B038, #$6493, #$0861, #$2ADF, #$3A66, #$0983, #$3FD9, #$91FE, - #$2BE4, #$2713, #$9252, #$5685, #$2B89, #$8B0E, #$CC81, #$CD2A, - #$939C, #$2B99, #$93BB, #$9372, #$CD66, #$3F31, #$93E8, #$9295, - #$2BB9, #$CE05, #$2C6B, #$2C23, #$09A6, #$70F2, #$81BD, #$09C8, - #$2C56, #$45E5, #$2C93, #$CF61, #$70F9, #$1005, #$94D1, #$09F2, - #$70FD, #$3043, #$2490, #$2D36, #$3748, #$2D3C, #$D50E, #$1284, - #$1ADD, #$7106, #$2D95, #$3320, #$7109, #$710A, #$86A5, #$2DB3, - #$2D5D, #$1F50, #$2DC5, #$9604, #$2DD3, #$454E, #$2DD4, #$9665, - #$CB28, #$2E09, #$1B5D, #$2E45, #$2EA9, #$2EAF, #$2F4B, #$9739, - #$9777, #$2ED0, #$2ED8, #$2F06, #$97A4, #$2E7A, #$2F97, #$547C, - #$0AED, #$B541, #$9889, #$99B3, #$5407, #$0AF6, #$0E82, #$2FEE, - #$3C4A, #$81BD, #$303A, #$7130, #$8AD3, #$2566, #$2077, #$81BD, - #$2568, #$9331, #$2FC9, #$30B4, #$DAC2, - #$30B9, #$30BB, #$0B60, #$30BC, #$39FE, #$64DB, #$30CD, #$8301, - #$EB54, #$0D9E, #$1B2E, #$903A, #$30FA, #$C988, #$9B10, #$81BD, - #$9B71, #$3123, #$687D, #$CE2E, #$3132, #$6400, #$7150, #$3167, - #$2F76, #$0FDF, #$7154, #$982A, #$D0B8, #$9CA8, #$6296, #$83DE, - #$DDE9, #$31F1, #$3845, #$715D, #$0C23, #$1047, #$08F9, #$2950, - #$9DF4, #$4AF1, #$10C0, #$325E, #$81BD, #$3273, #$7168, #$B5CF, - #$716A, #$4624, #$22A1, #$2C60, #$3324, #$55A4, #$3302, #$7171, - #$CE92, #$3341, #$23B4, #$7175, #$3347, #$2D6A, #$AD77, #$9E5F, - #$3393, #$DF5D, #$E51D, #$3390, #$0BF2, #$9F80, #$9EC1, #$31E3, - #$331C, #$36DE, #$354B, #$8298, #$3485, #$9330, #$3495, #$A28D, - #$352C, #$B61F, #$0CD7, #$35F8, #$35B8, #$718F, #$93BC, #$81BD, - #$410A, #$A2B6, #$68D4, #$AE4C, #$BE5D, #$36A1, #$36A5, #$653B, - #$0D26, #$35FA, #$0D17, #$370D, #$4096, #$B668, #$B663, #$3745, - #$372D, #$371F, #$A37E, #$3775, #$B580, #$1D77, #$3791, #$1358, - #$93E9, #$37A0, #$37A3, #$319F, #$A680, #$37D8, #$A4B7, #$A4B8, - #$3804, #$A464, #$A465, #$380B, #$8BF5, #$3827, #$BB26, #$3833, - #$81BD, #$71BB, #$A4F1, #$DBB4, #$A488, #$BBD3, #$4945, #$9EF7, - #$6A64, #$38C2, #$B15C, #$B661, #$0DEB, #$3BBA, #$AA02, #$81BD, - #$3927, #$3922, #$71CC, #$71CD, #$3997, #$1769, #$39E2, #$3FD0, - #$62FC, #$39C1, #$A666, #$CD60, #$3A1D, - #$71D7, #$3BA1, #$3BCB, #$DE9F, #$3B33, #$3A83, #$A80D, #$3AC1, - #$3AC0, #$0FB2, #$0CC1, #$A87C, #$0E40, #$396C, #$3B21, #$DE0A, - #$157C, #$3AF6, #$3B58, #$0E61, #$8509, #$54E3, #$2250, #$3BB9, - #$71EF, #$996A, #$3C05, #$71F2, #$3C5D, #$0EB3, #$3971, #$3C88, - #$E25C, #$0ECD, #$3CDD, #$71FA, #$329E, #$3CF5, #$3D34, #$71FE, - #$4035, #$AA5B, #$84F5, #$7202, #$0A00, #$25E1, #$AA9A, #$3DA1, - #$ACBC, #$3D9C, #$3DF7, #$9B8B, #$720B, #$CB51, #$3E1A, #$53A6, - #$3E39, #$ABBC, #$1745, #$ABBD, #$AF64, #$B54C, #$B540, #$AB09, - #$09A5, #$0F6B, #$7219, #$6C43, #$A4B9, #$721C, #$510F, #$39F7, - #$CD25, #$CD61, #$CDAB, #$3F56, #$3F1C, #$3FFC, #$4084, #$B5BF, - #$7227, #$CE32, #$56B3, #$CF34, #$2387, #$81BD, #$81BD, #$55AE, - #$DEE1, #$81BD, #$AC2F, #$45D3, #$AD42, #$4B4C, #$3FCF, #$2C51, - #$A34B, #$4178, #$09CD, #$411D, #$AC30, #$407A, #$9117, #$ADFD, - #$17D5, #$64B0, #$40C4, #$40DC, #$0FCE, #$40F4, #$7245, #$0FBB, - #$411F, #$AF04, #$4153, #$724A, #$AF15, #$ADF9, #$C220, #$724E, - #$AEFF, #$239F, #$AF16, #$AF17, #$AF00, #$C55D, #$41CB, #$41FE, - #$4227, #$4201, #$424C, #$4255, #$4256, #$425F, #$1384, #$1068, - #$4334, #$4316, #$B037, #$42AB, #$42C5, #$2C48, #$42CA, #$81BD, - #$2E5C, #$B125, #$42CF, #$6422, #$726B, #$42AC, #$B21A, #$B667, - #$B662, #$433A, #$DFA8, #$423D, #$438E, - #$6502, #$4395, #$2AD1, #$6503, #$43A4, #$6401, #$727A, #$43AE, - #$43C0, #$B5B4, #$3A7D, #$43D5, #$43D7, #$10D5, #$7282, #$39CD, - #$40BD, #$4402, #$81BD, #$44AB, #$B4E3, #$DCAB, #$1B6D, #$DC84, - #$44A8, #$44AE, #$454F, #$452A, #$7290, #$CAAE, #$4549, #$45C9, - #$AFA2, #$92A7, #$B664, #$37E3, #$0985, #$B5F7, #$B5CD, #$729B, - #$4577, #$4595, #$3AC3, #$B666, #$45B9, #$72A1, #$1157, #$81BD, - #$9EAD, #$45E0, #$E132, #$45C7, #$4564, #$45F6, #$5539, #$45EC, - #$09F0, #$45F4, #$64B1, #$3BEC, #$4602, #$1BD3, #$72B2, #$AF1F, - #$B6B9, #$DF4F, #$2D06, #$72B7, #$945E, #$4648, #$9548, #$468E, - #$81BD, #$469E, #$E159, #$95CB, #$2D97, #$72C1, #$6445, #$46CD, - #$46CA, #$46E7, #$46EE, #$BA02, #$1184, #$72C9, #$470E, #$45DD, - #$471E, #$4734, #$4782, #$47AC, #$47D1, #$47CF, #$47EF, #$47F6, - #$72D4, #$4810, #$536F, #$0AB8, #$C9D1, #$C9CE, #$4821, #$4825, - #$4837, #$484C, #$CF5F, #$55E2, #$BA9D, #$BAFD, #$72E2, #$489E, - #$48A6, #$48C0, #$366F, #$BB60, #$48D8, #$A56C, #$492F, #$72EB, - #$72EC, #$9281, #$4974, #$81BD, #$72F0, #$72F1, #$3A8A, #$4A2F, - #$4A47, #$4A53, #$6765, #$4AAE, #$BD20, #$4A57, #$4AB4, #$4A31, - #$D2CC, #$60B8, #$59C4, #$DEEB, #$7300, #$9C5C, #$4B06, #$5A40, - #$3AC2, #$4B00, #$BF17, #$4B1D, #$D639, #$4ABC, #$4B29, #$3FAA, - #$D0E6, #$1128, #$4B46, #$E20D, #$4B54); - HKSCS_5Map: array[0..944] of Integer = ( - $00080, $000C0, $00100, $00140, $001C0, $00240, $00280, $002C0, - $00400, $00440, $01E80, $01EC0, $02100, $02140, $02180, $021C0, - $02440, $02540, $02700, $02E80, $02EC0, $02F00, $03000, $03040, - $03080, $030C0, $03200, $03400, $03440, $03480, $034C0, $03500, - $03540, $03580, $035C0, $03600, $03640, $03680, $036C0, $03700, - $03740, $03780, $037C0, $03800, $03840, $03880, $038C0, $03900, - $03940, $03980, $039C0, $03A00, $03A40, $03A80, $03AC0, $03B00, - $03B40, $03B80, $03BC0, $03C00, $03C40, $03CC0, $03D00, $03D40, - $03D80, $03DC0, $03E00, $03E40, $03E80, $03EC0, $03F00, $03F40, - $03F80, $03FC0, $04000, $04040, $04080, $040C0, $04100, $04140, - $04180, $041C0, $04200, $04240, $04280, $042C0, $04300, $04340, - $04380, $043C0, $04400, $04440, $04480, $044C0, $04500, $04540, - $04580, $045C0, $04600, $04640, $04680, $046C0, $04700, $04740, - $04780, $047C0, $04800, $04840, $04880, $048C0, $04900, $04940, - $04980, $049C0, $04A00, $04A80, $04AC0, $04B00, $04B40, $04B80, - $04BC0, $04C00, $04C40, $04C80, $04CC0, $04D00, $04D80, $04E00, - $04E40, $04E80, $04EC0, $04F00, $04F40, $04F80, $04FC0, $05000, - $05040, $05080, $050C0, $05100, $05140, $05180, $051C0, $05200, - $05240, $05280, $052C0, $05300, $05340, $05380, $053C0, $05400, - $05440, $05480, $054C0, $05500, $05540, $05580, $055C0, $05600, - $05640, $05680, $056C0, $05700, $05740, $05780, $057C0, $05800, - $05840, $05880, $058C0, $05900, $05940, $05980, $059C0, $05A00, - $05A40, $05A80, $05AC0, $05B00, $05B40, $05B80, $05BC0, $05C00, - $05C40, $05C80, $05CC0, $05D00, $05D40, $05D80, $05DC0, $05E00, - $05E40, $05E80, $05EC0, $05F00, $05F40, $05F80, $05FC0, $06000, - $06040, $06080, $060C0, $06100, $06140, $06180, $061C0, $06200, - $06240, $06280, $062C0, $06300, $06340, $06380, $063C0, $06400, - $06440, $06480, $064C0, $06500, $06540, $06580, $065C0, $06600, - $06640, $06680, $066C0, $06700, $06740, $06780, $067C0, $06800, - $06840, $06880, $068C0, $06900, $06940, $06980, $069C0, $06A00, - $06A40, $06A80, $06AC0, $06B00, $06B40, $06B80, $06BC0, $06C00, - $06C40, $06C80, $06CC0, $06D00, $06D40, $06D80, $06E00, $06E40, - $06E80, $06EC0, $06F00, $06F40, $06F80, $06FC0, $07000, $07040, - $07080, $070C0, $07100, $07140, $07180, $071C0, $07200, $07240, - $07280, $072C0, $07300, $07340, $07380, $073C0, $07400, $07440, - $07480, $074C0, $07500, $07540, $07580, $075C0, $07600, $07640, - $07680, $076C0, $07700, $07740, $07780, $077C0, $07800, $07840, - $07880, $078C0, $07900, $07940, $07980, $079C0, $07A00, $07A40, - $07A80, $07AC0, $07B00, $07B40, $07B80, $07BC0, $07C00, $07C40, - $07C80, $07CC0, $07D00, $07D40, $07D80, $07DC0, $07E00, $07E40, - $07E80, $07EC0, $07F00, $07F40, $07F80, $07FC0, $08000, $08040, - $08080, $080C0, $08100, $08140, $08180, $081C0, $08200, $08240, - $08280, $082C0, $08300, $08340, $08380, $083C0, $08400, $08440, - $08480, $084C0, $08500, $08540, $085C0, $08600, $08640, $08680, - $086C0, $08700, $08740, $08780, $087C0, $08800, $08840, $08880, - $088C0, $08900, $08940, $08980, $089C0, $08A00, $08A40, $08A80, - $08AC0, $08B00, $08B40, $08B80, $08BC0, $08C40, $08C80, $08CC0, - $08D00, $08D40, $08D80, $08DC0, $08E00, $08E40, $08E80, $08EC0, - $08F00, $08F40, $08F80, $08FC0, $09000, $09040, $09080, $090C0, - $09140, $09180, $091C0, $09200, $09240, $09280, $092C0, $09300, - $09340, $09380, $093C0, $09400, $09440, $09480, $094C0, $09500, - $09540, $09580, $095C0, $09600, $09640, $09680, $096C0, $09700, - $09740, $09780, $097C0, $09800, $09840, $09880, $098C0, $09900, - $09940, $09980, $099C0, $09A00, $09A40, $09A80, $09AC0, $09B00, - $09B40, $09B80, $09BC0, $09C00, $09C40, $09D00, $09D40, $09D80, - $09DC0, $09E00, $09E40, $09E80, $09EC0, $09F00, $09F40, $09F80, - $0E000, $0E040, $0E080, $0E0C0, $0E100, $0E140, $0E180, $0E1C0, - $0E200, $0E240, $0E280, $0E2C0, $0E300, $0E340, $0E380, $0E3C0, - $0E400, $0E440, $0E480, $0E4C0, $0E500, $0E540, $0E580, $0E5C0, - $0E600, $0E640, $0E680, $0E6C0, $0E700, $0E740, $0E780, $0E7C0, - $0E800, $0E840, $0E880, $0E8C0, $0E900, $0E940, $0E980, $0E9C0, - $0EA80, $0EAC0, $0EB00, $0EB40, $0EB80, $0EBC0, $0EC00, $0EC40, - $0EC80, $0ECC0, $0ED00, $0ED40, $0ED80, $0EDC0, $0EE00, $0EE40, - $0EE80, $0F300, $0F340, $0F380, $0F3C0, $0F400, $0F440, $0F480, - $0F4C0, $0F500, $0F540, $0F680, $0F7C0, $0FF00, $0FFC0, $20000, - $20040, $200C0, $20100, $20180, $201C0, $20200, $20240, $20280, - $202C0, $20300, $20340, $20380, $203C0, $20400, $20440, $20480, - $204C0, $20540, $20580, $205C0, $20600, $20700, $20740, $20800, - $20840, $20900, $20940, $20A00, $20A40, $20A80, $20B80, $20BC0, - $20C00, $20C40, $20C80, $20CC0, $20D40, $20D80, $20E00, $20E40, - $20E80, $20EC0, $20F00, $20F80, $20FC0, $21000, $21040, $21080, - $210C0, $21100, $21140, $21180, $211C0, $21240, $21280, $212C0, - $21300, $21380, $213C0, $21440, $21480, $214C0, $21580, $21600, - $21640, $21680, $216C0, $21700, $21740, $21780, $217C0, $21800, - $21840, $21880, $218C0, $21900, $21940, $21980, $219C0, $21A40, - $21B40, $21C80, $21D40, $21D80, $21DC0, $21E00, $21E80, $21EC0, - $21F40, $21F80, $22040, $22080, $220C0, $22100, $22140, $22180, - $221C0, $22240, $22300, $22380, $223C0, $22440, $22480, $22500, - $22580, $22600, $22640, $22680, $226C0, $22700, $22740, $22780, - $22800, $22840, $22880, $228C0, $22900, $22940, $22980, $22AC0, - $22B00, $22B40, $22BC0, $22C00, $22C40, $22C80, $22CC0, $22D00, - $22D40, $22D80, $22E00, $22E40, $22FC0, $23040, $23080, $230C0, - $23100, $23180, $231C0, $23200, $23240, $23280, $232C0, $23300, - $23380, $233C0, $23400, $23440, $234C0, $23500, $23540, $23580, - $235C0, $23600, $23640, $23680, $236C0, $23700, $23740, $23780, - $237C0, $23AC0, $23B40, $23C80, $23CC0, $23D40, $23D80, $23DC0, - $23E00, $23E80, $23EC0, $23F00, $23F40, $23F80, $23FC0, $24000, - $24040, $24080, $240C0, $24100, $24140, $24180, $241C0, $24200, - $24240, $24280, $242C0, $24300, $24340, $24380, $243C0, $24400, - $24440, $24480, $244C0, $24500, $24540, $24600, $24640, $24680, - $246C0, $24700, $24780, $24800, $248C0, $24900, $24940, $24980, - $249C0, $24A00, $24A40, $24A80, $24AC0, $24B40, $24BC0, $24C00, - $24C80, $24CC0, $24D00, $24D80, $24DC0, $24E40, $24F00, $24F40, - $24F80, $24FC0, $25080, $25140, $251C0, $25200, $252C0, $25300, - $25400, $25440, $25540, $25580, $255C0, $25600, $25640, $25680, - $256C0, $25700, $25740, $257C0, $25840, $258C0, $25940, $25980, - $25A80, $25AC0, $25B40, $25B80, $25BC0, $25C00, $25C40, $25CC0, - $25D00, $25D40, $25E00, $25E80, $25EC0, $25F40, $25FC0, $26000, - $26040, $26080, $26100, $26140, $26180, $261C0, $26240, $262C0, - $26340, $26380, $26400, $26480, $26500, $26540, $26580, $26600, - $26680, $266C0, $26740, $26780, $267C0, $26840, $26880, $26900, - $26980, $269C0, $26A00, $26A40, $26B00, $26B40, $26B80, $26BC0, - $26C00, $26C40, $26C80, $26CC0, $26D00, $26D80, $26DC0, $26E00, - $26E40, $26E80, $26EC0, $26F00, $26F40, $26F80, $26FC0, $27000, - $27040, $27080, $270C0, $27100, $27140, $27200, $272C0, $27380, - $27400, $27480, $275C0, $27600, $27640, $27680, $27700, $27740, - $27780, $27840, $27900, $27940, $27A00, $27A40, $27A80, $27AC0, - $27B00, $27BC0, $27C00, $27D00, $27D40, $27D80, $27DC0, $27E40, - $28000, $28080, $280C0, $28100, $28140, $28200, $28240, $282C0, - $28300, $28340, $28400, $28480, $28500, $28540, $285C0, $28600, - $28680, $286C0, $28800, $28900, $28940, $28980, $289C0, $28A00, - $28A40, $28A80, $28AC0, $28B00, $28B40, $28B80, $28BC0, $28C00, - $28CC0, $28D00, $28E00, $28E40, $28E80, $28EC0, $29080, $290C0, - $29100, $29180, $291C0, $29400, $29440, $294C0, $29580, $295C0, - $29840, $29880, $298C0, $29900, $29940, $29980, $29B00, $29BC0, - $29C80, $29D00, $29D40, $29E00, $29E40, $29E80, $29EC0, $29F00, - $29F80, $2A0C0, $2A100, $2A140, $2A180, $2A1C0, $2A200, $2A280, - $2A2C0, $2A380, $2A5C0, $2A680, $2F840, $2F880, $2F8C0, $2F980, - $2F9C0); - JIS_X0208_1Map: array[0..689] of TBuffChar = ( - #$3000, #$3001, #$3002, #$FF0C, #$FF0E, #$30FB, #$FF1A, #$FF1B, - #$FF1F, #$FF01, #$309B, #$309C, #$00B4, #$FF40, #$00A8, #$FF3E, - #$FFE3, #$FF3F, #$30FD, #$30FE, #$309D, #$309E, #$3003, #$4EDD, - #$3005, #$3006, #$3007, #$30FC, #$2015, #$2010, #$FF0F, #$FF3C, - #$301C, #$2016, #$FF5C, #$2026, #$2025, #$2018, #$2019, #$201C, - #$201D, #$FF08, #$FF09, #$3014, #$3015, #$FF3B, #$FF3D, #$FF5B, - #$FF5D, #$3008, #$3009, #$300A, #$300B, #$300C, #$300D, #$300E, - #$300F, #$3010, #$3011, #$FF0B, #$2212, #$00B1, #$00D7, #$00F7, - #$FF1D, #$2260, #$FF1C, #$FF1E, #$2266, #$2267, #$221E, #$2234, - #$2642, #$2640, #$00B0, #$2032, #$2033, #$2103, #$FFE5, #$FF04, - #$00A2, #$00A3, #$FF05, #$FF03, #$FF06, #$FF0A, #$FF20, #$00A7, - #$2606, #$2605, #$25CB, #$25CF, #$25CE, #$25C7, - #$25C6, #$25A1, #$25A0, #$25B3, #$25B2, #$25BD, #$25BC, #$203B, - #$3012, #$2192, #$2190, #$2191, #$2193, #$3013, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$2208, #$220B, #$2286, #$2287, #$2282, #$2283, #$222A, - #$2229, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$2227, #$2228, #$00AC, #$21D2, #$21D4, #$2200, #$2203, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$2220, #$22A5, #$2312, #$2202, #$2207, - #$2261, #$2252, #$226A, #$226B, #$221A, #$223D, #$221D, #$2235, - #$222B, #$222C, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$212B, #$2030, #$266F, #$266D, #$266A, #$2020, #$2021, - #$00B6, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$25EF, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FF10, - #$FF11, #$FF12, #$FF13, #$FF14, #$FF15, #$FF16, #$FF17, #$FF18, - #$FF19, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FF21, #$FF22, #$FF23, #$FF24, #$FF25, #$FF26, #$FF27, #$FF28, - #$FF29, #$FF2A, #$FF2B, #$FF2C, #$FF2D, #$FF2E, #$FF2F, #$FF30, - #$FF31, #$FF32, #$FF33, #$FF34, #$FF35, #$FF36, #$FF37, #$FF38, - #$FF39, #$FF3A, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FF41, #$FF42, #$FF43, #$FF44, #$FF45, #$FF46, #$FF47, #$FF48, - #$FF49, #$FF4A, #$FF4B, #$FF4C, #$FF4D, #$FF4E, #$FF4F, #$FF50, - #$FF51, #$FF52, #$FF53, #$FF54, #$FF55, #$FF56, #$FF57, #$FF58, - #$FF59, #$FF5A, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$3041, #$3042, #$3043, #$3044, #$3045, #$3046, #$3047, #$3048, - #$3049, #$304A, #$304B, #$304C, #$304D, #$304E, #$304F, #$3050, - #$3051, #$3052, #$3053, #$3054, #$3055, #$3056, #$3057, #$3058, - #$3059, #$305A, #$305B, #$305C, #$305D, #$305E, #$305F, #$3060, - #$3061, #$3062, #$3063, #$3064, #$3065, #$3066, #$3067, #$3068, - #$3069, #$306A, #$306B, #$306C, #$306D, #$306E, #$306F, #$3070, - #$3071, #$3072, #$3073, #$3074, #$3075, #$3076, #$3077, #$3078, - #$3079, #$307A, #$307B, #$307C, #$307D, #$307E, #$307F, #$3080, - #$3081, #$3082, #$3083, #$3084, #$3085, #$3086, #$3087, #$3088, - #$3089, #$308A, #$308B, #$308C, #$308D, #$308E, #$308F, #$3090, - #$3091, #$3092, #$3093, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$30A1, #$30A2, #$30A3, #$30A4, #$30A5, #$30A6, #$30A7, #$30A8, - #$30A9, #$30AA, #$30AB, #$30AC, #$30AD, #$30AE, #$30AF, #$30B0, - #$30B1, #$30B2, #$30B3, #$30B4, #$30B5, #$30B6, #$30B7, #$30B8, - #$30B9, #$30BA, #$30BB, #$30BC, #$30BD, #$30BE, #$30BF, #$30C0, - #$30C1, #$30C2, #$30C3, #$30C4, #$30C5, #$30C6, #$30C7, #$30C8, - #$30C9, #$30CA, #$30CB, #$30CC, #$30CD, #$30CE, #$30CF, #$30D0, - #$30D1, #$30D2, #$30D3, #$30D4, #$30D5, #$30D6, #$30D7, #$30D8, - #$30D9, #$30DA, #$30DB, #$30DC, #$30DD, #$30DE, #$30DF, #$30E0, - #$30E1, #$30E2, #$30E3, #$30E4, #$30E5, #$30E6, #$30E7, #$30E8, - #$30E9, #$30EA, #$30EB, #$30EC, #$30ED, #$30EE, #$30EF, #$30F0, - #$30F1, #$30F2, #$30F3, #$30F4, #$30F5, #$30F6, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$0391, #$0392, #$0393, #$0394, #$0395, #$0396, #$0397, #$0398, - #$0399, #$039A, #$039B, #$039C, #$039D, #$039E, #$039F, #$03A0, - #$03A1, #$03A3, #$03A4, #$03A5, #$03A6, #$03A7, #$03A8, #$03A9, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$03B1, #$03B2, #$03B3, #$03B4, #$03B5, #$03B6, #$03B7, #$03B8, - #$03B9, #$03BA, #$03BB, #$03BC, #$03BD, #$03BE, #$03BF, #$03C0, - #$03C1, #$03C3, #$03C4, #$03C5, #$03C6, #$03C7, #$03C8, #$03C9, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$0410, #$0411, #$0412, #$0413, #$0414, #$0415, #$0401, #$0416, - #$0417, #$0418, #$0419, #$041A, #$041B, #$041C, #$041D, #$041E, - #$041F, #$0420, #$0421, #$0422, #$0423, #$0424, #$0425, #$0426, - #$0427, #$0428, #$0429, #$042A, #$042B, #$042C, #$042D, #$042E, - #$042F, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$0430, #$0431, #$0432, #$0433, #$0434, #$0435, #$0451, #$0436, - #$0437, #$0438, #$0439, #$043A, #$043B, #$043C, #$043D, #$043E, - #$043F, #$0440, #$0441, #$0442, #$0443, #$0444, #$0445, #$0446, - #$0447, #$0448, #$0449, #$044A, #$044B, #$044C, #$044D, #$044E, - #$044F, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$2500, #$2502, #$250C, #$2510, #$2518, #$2514, #$251C, #$252C, - #$2524, #$2534, #$253C, #$2501, #$2503, #$250F, #$2513, #$251B, - #$2517, #$2523, #$2533, #$252B, #$253B, #$254B, #$2520, #$252F, - #$2528, #$2537, #$253F, #$251D, #$2530, #$2525, #$2538, #$2542); - JIS_X0208_2Map: array[0..6397] of TBuffChar = ( - #$4E9C, #$5516, #$5A03, #$963F, #$54C0, #$611B, #$6328, #$59F6, - #$9022, #$8475, #$831C, #$7A50, #$60AA, #$63E1, #$6E25, #$65ED, - #$8466, #$82A6, #$9BF5, #$6893, #$5727, #$65A1, #$6271, #$5B9B, - #$59D0, #$867B, #$98F4, #$7D62, #$7DBE, #$9B8E, #$6216, #$7C9F, - #$88B7, #$5B89, #$5EB5, #$6309, #$6697, #$6848, #$95C7, #$978D, - #$674F, #$4EE5, #$4F0A, #$4F4D, #$4F9D, #$5049, #$56F2, #$5937, - #$59D4, #$5A01, #$5C09, #$60DF, #$610F, #$6170, #$6613, #$6905, - #$70BA, #$754F, #$7570, #$79FB, #$7DAD, #$7DEF, #$80C3, #$840E, - #$8863, #$8B02, #$9055, #$907A, #$533B, #$4E95, #$4EA5, #$57DF, - #$80B2, #$90C1, #$78EF, #$4E00, #$58F1, #$6EA2, #$9038, #$7A32, - #$8328, #$828B, #$9C2F, #$5141, #$5370, #$54BD, #$54E1, #$56E0, - #$59FB, #$5F15, #$98F2, #$6DEB, #$80E4, #$852D, - #$9662, #$9670, #$96A0, #$97FB, #$540B, #$53F3, #$5B87, #$70CF, - #$7FBD, #$8FC2, #$96E8, #$536F, #$9D5C, #$7ABA, #$4E11, #$7893, - #$81FC, #$6E26, #$5618, #$5504, #$6B1D, #$851A, #$9C3B, #$59E5, - #$53A9, #$6D66, #$74DC, #$958F, #$5642, #$4E91, #$904B, #$96F2, - #$834F, #$990C, #$53E1, #$55B6, #$5B30, #$5F71, #$6620, #$66F3, - #$6804, #$6C38, #$6CF3, #$6D29, #$745B, #$76C8, #$7A4E, #$9834, - #$82F1, #$885B, #$8A60, #$92ED, #$6DB2, #$75AB, #$76CA, #$99C5, - #$60A6, #$8B01, #$8D8A, #$95B2, #$698E, #$53AD, #$5186, #$5712, - #$5830, #$5944, #$5BB4, #$5EF6, #$6028, #$63A9, #$63F4, #$6CBF, - #$6F14, #$708E, #$7114, #$7159, #$71D5, #$733F, #$7E01, #$8276, - #$82D1, #$8597, #$9060, #$925B, #$9D1B, #$5869, #$65BC, #$6C5A, - #$7525, #$51F9, #$592E, #$5965, #$5F80, #$5FDC, - #$62BC, #$65FA, #$6A2A, #$6B27, #$6BB4, #$738B, #$7FC1, #$8956, - #$9D2C, #$9D0E, #$9EC4, #$5CA1, #$6C96, #$837B, #$5104, #$5C4B, - #$61B6, #$81C6, #$6876, #$7261, #$4E59, #$4FFA, #$5378, #$6069, - #$6E29, #$7A4F, #$97F3, #$4E0B, #$5316, #$4EEE, #$4F55, #$4F3D, - #$4FA1, #$4F73, #$52A0, #$53EF, #$5609, #$590F, #$5AC1, #$5BB6, - #$5BE1, #$79D1, #$6687, #$679C, #$67B6, #$6B4C, #$6CB3, #$706B, - #$73C2, #$798D, #$79BE, #$7A3C, #$7B87, #$82B1, #$82DB, #$8304, - #$8377, #$83EF, #$83D3, #$8766, #$8AB2, #$5629, #$8CA8, #$8FE6, - #$904E, #$971E, #$868A, #$4FC4, #$5CE8, #$6211, #$7259, #$753B, - #$81E5, #$82BD, #$86FE, #$8CC0, #$96C5, #$9913, #$99D5, #$4ECB, - #$4F1A, #$89E3, #$56DE, #$584A, #$58CA, #$5EFB, #$5FEB, #$602A, - #$6094, #$6062, #$61D0, #$6212, #$62D0, #$6539, - #$9B41, #$6666, #$68B0, #$6D77, #$7070, #$754C, #$7686, #$7D75, - #$82A5, #$87F9, #$958B, #$968E, #$8C9D, #$51F1, #$52BE, #$5916, - #$54B3, #$5BB3, #$5D16, #$6168, #$6982, #$6DAF, #$788D, #$84CB, - #$8857, #$8A72, #$93A7, #$9AB8, #$6D6C, #$99A8, #$86D9, #$57A3, - #$67FF, #$86CE, #$920E, #$5283, #$5687, #$5404, #$5ED3, #$62E1, - #$64B9, #$683C, #$6838, #$6BBB, #$7372, #$78BA, #$7A6B, #$899A, - #$89D2, #$8D6B, #$8F03, #$90ED, #$95A3, #$9694, #$9769, #$5B66, - #$5CB3, #$697D, #$984D, #$984E, #$639B, #$7B20, #$6A2B, #$6A7F, - #$68B6, #$9C0D, #$6F5F, #$5272, #$559D, #$6070, #$62EC, #$6D3B, - #$6E07, #$6ED1, #$845B, #$8910, #$8F44, #$4E14, #$9C39, #$53F6, - #$691B, #$6A3A, #$9784, #$682A, #$515C, #$7AC3, #$84B2, #$91DC, - #$938C, #$565B, #$9D28, #$6822, #$8305, #$8431, - #$7CA5, #$5208, #$82C5, #$74E6, #$4E7E, #$4F83, #$51A0, #$5BD2, - #$520A, #$52D8, #$52E7, #$5DFB, #$559A, #$582A, #$59E6, #$5B8C, - #$5B98, #$5BDB, #$5E72, #$5E79, #$60A3, #$611F, #$6163, #$61BE, - #$63DB, #$6562, #$67D1, #$6853, #$68FA, #$6B3E, #$6B53, #$6C57, - #$6F22, #$6F97, #$6F45, #$74B0, #$7518, #$76E3, #$770B, #$7AFF, - #$7BA1, #$7C21, #$7DE9, #$7F36, #$7FF0, #$809D, #$8266, #$839E, - #$89B3, #$8ACC, #$8CAB, #$9084, #$9451, #$9593, #$9591, #$95A2, - #$9665, #$97D3, #$9928, #$8218, #$4E38, #$542B, #$5CB8, #$5DCC, - #$73A9, #$764C, #$773C, #$5CA9, #$7FEB, #$8D0B, #$96C1, #$9811, - #$9854, #$9858, #$4F01, #$4F0E, #$5371, #$559C, #$5668, #$57FA, - #$5947, #$5B09, #$5BC4, #$5C90, #$5E0C, #$5E7E, #$5FCC, #$63EE, - #$673A, #$65D7, #$65E2, #$671F, #$68CB, #$68C4, - #$6A5F, #$5E30, #$6BC5, #$6C17, #$6C7D, #$757F, #$7948, #$5B63, - #$7A00, #$7D00, #$5FBD, #$898F, #$8A18, #$8CB4, #$8D77, #$8ECC, - #$8F1D, #$98E2, #$9A0E, #$9B3C, #$4E80, #$507D, #$5100, #$5993, - #$5B9C, #$622F, #$6280, #$64EC, #$6B3A, #$72A0, #$7591, #$7947, - #$7FA9, #$87FB, #$8ABC, #$8B70, #$63AC, #$83CA, #$97A0, #$5409, - #$5403, #$55AB, #$6854, #$6A58, #$8A70, #$7827, #$6775, #$9ECD, - #$5374, #$5BA2, #$811A, #$8650, #$9006, #$4E18, #$4E45, #$4EC7, - #$4F11, #$53CA, #$5438, #$5BAE, #$5F13, #$6025, #$6551, #$673D, - #$6C42, #$6C72, #$6CE3, #$7078, #$7403, #$7A76, #$7AAE, #$7B08, - #$7D1A, #$7CFE, #$7D66, #$65E7, #$725B, #$53BB, #$5C45, #$5DE8, - #$62D2, #$62E0, #$6319, #$6E20, #$865A, #$8A31, #$8DDD, #$92F8, - #$6F01, #$79A6, #$9B5A, #$4EA8, #$4EAB, #$4EAC, - #$4F9B, #$4FA0, #$50D1, #$5147, #$7AF6, #$5171, #$51F6, #$5354, - #$5321, #$537F, #$53EB, #$55AC, #$5883, #$5CE1, #$5F37, #$5F4A, - #$602F, #$6050, #$606D, #$631F, #$6559, #$6A4B, #$6CC1, #$72C2, - #$72ED, #$77EF, #$80F8, #$8105, #$8208, #$854E, #$90F7, #$93E1, - #$97FF, #$9957, #$9A5A, #$4EF0, #$51DD, #$5C2D, #$6681, #$696D, - #$5C40, #$66F2, #$6975, #$7389, #$6850, #$7C81, #$50C5, #$52E4, - #$5747, #$5DFE, #$9326, #$65A4, #$6B23, #$6B3D, #$7434, #$7981, - #$79BD, #$7B4B, #$7DCA, #$82B9, #$83CC, #$887F, #$895F, #$8B39, - #$8FD1, #$91D1, #$541F, #$9280, #$4E5D, #$5036, #$53E5, #$533A, - #$72D7, #$7396, #$77E9, #$82E6, #$8EAF, #$99C6, #$99C8, #$99D2, - #$5177, #$611A, #$865E, #$55B0, #$7A7A, #$5076, #$5BD3, #$9047, - #$9685, #$4E32, #$6ADB, #$91E7, #$5C51, #$5C48, - #$6398, #$7A9F, #$6C93, #$9774, #$8F61, #$7AAA, #$718A, #$9688, - #$7C82, #$6817, #$7E70, #$6851, #$936C, #$52F2, #$541B, #$85AB, - #$8A13, #$7FA4, #$8ECD, #$90E1, #$5366, #$8888, #$7941, #$4FC2, - #$50BE, #$5211, #$5144, #$5553, #$572D, #$73EA, #$578B, #$5951, - #$5F62, #$5F84, #$6075, #$6176, #$6167, #$61A9, #$63B2, #$643A, - #$656C, #$666F, #$6842, #$6E13, #$7566, #$7A3D, #$7CFB, #$7D4C, - #$7D99, #$7E4B, #$7F6B, #$830E, #$834A, #$86CD, #$8A08, #$8A63, - #$8B66, #$8EFD, #$981A, #$9D8F, #$82B8, #$8FCE, #$9BE8, #$5287, - #$621F, #$6483, #$6FC0, #$9699, #$6841, #$5091, #$6B20, #$6C7A, - #$6F54, #$7A74, #$7D50, #$8840, #$8A23, #$6708, #$4EF6, #$5039, - #$5026, #$5065, #$517C, #$5238, #$5263, #$55A7, #$570F, #$5805, - #$5ACC, #$5EFA, #$61B2, #$61F8, #$62F3, #$6372, - #$691C, #$6A29, #$727D, #$72AC, #$732E, #$7814, #$786F, #$7D79, - #$770C, #$80A9, #$898B, #$8B19, #$8CE2, #$8ED2, #$9063, #$9375, - #$967A, #$9855, #$9A13, #$9E78, #$5143, #$539F, #$53B3, #$5E7B, - #$5F26, #$6E1B, #$6E90, #$7384, #$73FE, #$7D43, #$8237, #$8A00, - #$8AFA, #$9650, #$4E4E, #$500B, #$53E4, #$547C, #$56FA, #$59D1, - #$5B64, #$5DF1, #$5EAB, #$5F27, #$6238, #$6545, #$67AF, #$6E56, - #$72D0, #$7CCA, #$88B4, #$80A1, #$80E1, #$83F0, #$864E, #$8A87, - #$8DE8, #$9237, #$96C7, #$9867, #$9F13, #$4E94, #$4E92, #$4F0D, - #$5348, #$5449, #$543E, #$5A2F, #$5F8C, #$5FA1, #$609F, #$68A7, - #$6A8E, #$745A, #$7881, #$8A9E, #$8AA4, #$8B77, #$9190, #$4E5E, - #$9BC9, #$4EA4, #$4F7C, #$4FAF, #$5019, #$5016, #$5149, #$516C, - #$529F, #$52B9, #$52FE, #$539A, #$53E3, #$5411, - #$540E, #$5589, #$5751, #$57A2, #$597D, #$5B54, #$5B5D, #$5B8F, - #$5DE5, #$5DE7, #$5DF7, #$5E78, #$5E83, #$5E9A, #$5EB7, #$5F18, - #$6052, #$614C, #$6297, #$62D8, #$63A7, #$653B, #$6602, #$6643, - #$66F4, #$676D, #$6821, #$6897, #$69CB, #$6C5F, #$6D2A, #$6D69, - #$6E2F, #$6E9D, #$7532, #$7687, #$786C, #$7A3F, #$7CE0, #$7D05, - #$7D18, #$7D5E, #$7DB1, #$8015, #$8003, #$80AF, #$80B1, #$8154, - #$818F, #$822A, #$8352, #$884C, #$8861, #$8B1B, #$8CA2, #$8CFC, - #$90CA, #$9175, #$9271, #$783F, #$92FC, #$95A4, #$964D, #$9805, - #$9999, #$9AD8, #$9D3B, #$525B, #$52AB, #$53F7, #$5408, #$58D5, - #$62F7, #$6FE0, #$8C6A, #$8F5F, #$9EB9, #$514B, #$523B, #$544A, - #$56FD, #$7A40, #$9177, #$9D60, #$9ED2, #$7344, #$6F09, #$8170, - #$7511, #$5FFD, #$60DA, #$9AA8, #$72DB, #$8FBC, - #$6B64, #$9803, #$4ECA, #$56F0, #$5764, #$58BE, #$5A5A, #$6068, - #$61C7, #$660F, #$6606, #$6839, #$68B1, #$6DF7, #$75D5, #$7D3A, - #$826E, #$9B42, #$4E9B, #$4F50, #$53C9, #$5506, #$5D6F, #$5DE6, - #$5DEE, #$67FB, #$6C99, #$7473, #$7802, #$8A50, #$9396, #$88DF, - #$5750, #$5EA7, #$632B, #$50B5, #$50AC, #$518D, #$6700, #$54C9, - #$585E, #$59BB, #$5BB0, #$5F69, #$624D, #$63A1, #$683D, #$6B73, - #$6E08, #$707D, #$91C7, #$7280, #$7815, #$7826, #$796D, #$658E, - #$7D30, #$83DC, #$88C1, #$8F09, #$969B, #$5264, #$5728, #$6750, - #$7F6A, #$8CA1, #$51B4, #$5742, #$962A, #$583A, #$698A, #$80B4, - #$54B2, #$5D0E, #$57FC, #$7895, #$9DFA, #$4F5C, #$524A, #$548B, - #$643E, #$6628, #$6714, #$67F5, #$7A84, #$7B56, #$7D22, #$932F, - #$685C, #$9BAD, #$7B39, #$5319, #$518A, #$5237, - #$5BDF, #$62F6, #$64AE, #$64E6, #$672D, #$6BBA, #$85A9, #$96D1, - #$7690, #$9BD6, #$634C, #$9306, #$9BAB, #$76BF, #$6652, #$4E09, - #$5098, #$53C2, #$5C71, #$60E8, #$6492, #$6563, #$685F, #$71E6, - #$73CA, #$7523, #$7B97, #$7E82, #$8695, #$8B83, #$8CDB, #$9178, - #$9910, #$65AC, #$66AB, #$6B8B, #$4ED5, #$4ED4, #$4F3A, #$4F7F, - #$523A, #$53F8, #$53F2, #$55E3, #$56DB, #$58EB, #$59CB, #$59C9, - #$59FF, #$5B50, #$5C4D, #$5E02, #$5E2B, #$5FD7, #$601D, #$6307, - #$652F, #$5B5C, #$65AF, #$65BD, #$65E8, #$679D, #$6B62, #$6B7B, - #$6C0F, #$7345, #$7949, #$79C1, #$7CF8, #$7D19, #$7D2B, #$80A2, - #$8102, #$81F3, #$8996, #$8A5E, #$8A69, #$8A66, #$8A8C, #$8AEE, - #$8CC7, #$8CDC, #$96CC, #$98FC, #$6B6F, #$4E8B, #$4F3C, #$4F8D, - #$5150, #$5B57, #$5BFA, #$6148, #$6301, #$6642, - #$6B21, #$6ECB, #$6CBB, #$723E, #$74BD, #$75D4, #$78C1, #$793A, - #$800C, #$8033, #$81EA, #$8494, #$8F9E, #$6C50, #$9E7F, #$5F0F, - #$8B58, #$9D2B, #$7AFA, #$8EF8, #$5B8D, #$96EB, #$4E03, #$53F1, - #$57F7, #$5931, #$5AC9, #$5BA4, #$6089, #$6E7F, #$6F06, #$75BE, - #$8CEA, #$5B9F, #$8500, #$7BE0, #$5072, #$67F4, #$829D, #$5C61, - #$854A, #$7E1E, #$820E, #$5199, #$5C04, #$6368, #$8D66, #$659C, - #$716E, #$793E, #$7D17, #$8005, #$8B1D, #$8ECA, #$906E, #$86C7, - #$90AA, #$501F, #$52FA, #$5C3A, #$6753, #$707C, #$7235, #$914C, - #$91C8, #$932B, #$82E5, #$5BC2, #$5F31, #$60F9, #$4E3B, #$53D6, - #$5B88, #$624B, #$6731, #$6B8A, #$72E9, #$73E0, #$7A2E, #$816B, - #$8DA3, #$9152, #$9996, #$5112, #$53D7, #$546A, #$5BFF, #$6388, - #$6A39, #$7DAC, #$9700, #$56DA, #$53CE, #$5468, - #$5B97, #$5C31, #$5DDE, #$4FEE, #$6101, #$62FE, #$6D32, #$79C0, - #$79CB, #$7D42, #$7E4D, #$7FD2, #$81ED, #$821F, #$8490, #$8846, - #$8972, #$8B90, #$8E74, #$8F2F, #$9031, #$914B, #$916C, #$96C6, - #$919C, #$4EC0, #$4F4F, #$5145, #$5341, #$5F93, #$620E, #$67D4, - #$6C41, #$6E0B, #$7363, #$7E26, #$91CD, #$9283, #$53D4, #$5919, - #$5BBF, #$6DD1, #$795D, #$7E2E, #$7C9B, #$587E, #$719F, #$51FA, - #$8853, #$8FF0, #$4FCA, #$5CFB, #$6625, #$77AC, #$7AE3, #$821C, - #$99FF, #$51C6, #$5FAA, #$65EC, #$696F, #$6B89, #$6DF3, #$6E96, - #$6F64, #$76FE, #$7D14, #$5DE1, #$9075, #$9187, #$9806, #$51E6, - #$521D, #$6240, #$6691, #$66D9, #$6E1A, #$5EB6, #$7DD2, #$7F72, - #$66F8, #$85AF, #$85F7, #$8AF8, #$52A9, #$53D9, #$5973, #$5E8F, - #$5F90, #$6055, #$92E4, #$9664, #$50B7, #$511F, - #$52DD, #$5320, #$5347, #$53EC, #$54E8, #$5546, #$5531, #$5617, - #$5968, #$59BE, #$5A3C, #$5BB5, #$5C06, #$5C0F, #$5C11, #$5C1A, - #$5E84, #$5E8A, #$5EE0, #$5F70, #$627F, #$6284, #$62DB, #$638C, - #$6377, #$6607, #$660C, #$662D, #$6676, #$677E, #$68A2, #$6A1F, - #$6A35, #$6CBC, #$6D88, #$6E09, #$6E58, #$713C, #$7126, #$7167, - #$75C7, #$7701, #$785D, #$7901, #$7965, #$79F0, #$7AE0, #$7B11, - #$7CA7, #$7D39, #$8096, #$83D6, #$848B, #$8549, #$885D, #$88F3, - #$8A1F, #$8A3C, #$8A54, #$8A73, #$8C61, #$8CDE, #$91A4, #$9266, - #$937E, #$9418, #$969C, #$9798, #$4E0A, #$4E08, #$4E1E, #$4E57, - #$5197, #$5270, #$57CE, #$5834, #$58CC, #$5B22, #$5E38, #$60C5, - #$64FE, #$6761, #$6756, #$6D44, #$72B6, #$7573, #$7A63, #$84B8, - #$8B72, #$91B8, #$9320, #$5631, #$57F4, #$98FE, - #$62ED, #$690D, #$6B96, #$71ED, #$7E54, #$8077, #$8272, #$89E6, - #$98DF, #$8755, #$8FB1, #$5C3B, #$4F38, #$4FE1, #$4FB5, #$5507, - #$5A20, #$5BDD, #$5BE9, #$5FC3, #$614E, #$632F, #$65B0, #$664B, - #$68EE, #$699B, #$6D78, #$6DF1, #$7533, #$75B9, #$771F, #$795E, - #$79E6, #$7D33, #$81E3, #$82AF, #$85AA, #$89AA, #$8A3A, #$8EAB, - #$8F9B, #$9032, #$91DD, #$9707, #$4EBA, #$4EC1, #$5203, #$5875, - #$58EC, #$5C0B, #$751A, #$5C3D, #$814E, #$8A0A, #$8FC5, #$9663, - #$976D, #$7B25, #$8ACF, #$9808, #$9162, #$56F3, #$53A8, #$9017, - #$5439, #$5782, #$5E25, #$63A8, #$6C34, #$708A, #$7761, #$7C8B, - #$7FE0, #$8870, #$9042, #$9154, #$9310, #$9318, #$968F, #$745E, - #$9AC4, #$5D07, #$5D69, #$6570, #$67A2, #$8DA8, #$96DB, #$636E, - #$6749, #$6919, #$83C5, #$9817, #$96C0, #$88FE, - #$6F84, #$647A, #$5BF8, #$4E16, #$702C, #$755D, #$662F, #$51C4, - #$5236, #$52E2, #$59D3, #$5F81, #$6027, #$6210, #$653F, #$6574, - #$661F, #$6674, #$68F2, #$6816, #$6B63, #$6E05, #$7272, #$751F, - #$76DB, #$7CBE, #$8056, #$58F0, #$88FD, #$897F, #$8AA0, #$8A93, - #$8ACB, #$901D, #$9192, #$9752, #$9759, #$6589, #$7A0E, #$8106, - #$96BB, #$5E2D, #$60DC, #$621A, #$65A5, #$6614, #$6790, #$77F3, - #$7A4D, #$7C4D, #$7E3E, #$810A, #$8CAC, #$8D64, #$8DE1, #$8E5F, - #$78A9, #$5207, #$62D9, #$63A5, #$6442, #$6298, #$8A2D, #$7A83, - #$7BC0, #$8AAC, #$96EA, #$7D76, #$820C, #$8749, #$4ED9, #$5148, - #$5343, #$5360, #$5BA3, #$5C02, #$5C16, #$5DDD, #$6226, #$6247, - #$64B0, #$6813, #$6834, #$6CC9, #$6D45, #$6D17, #$67D3, #$6F5C, - #$714E, #$717D, #$65CB, #$7A7F, #$7BAD, #$7DDA, - #$7E4A, #$7FA8, #$817A, #$821B, #$8239, #$85A6, #$8A6E, #$8CCE, - #$8DF5, #$9078, #$9077, #$92AD, #$9291, #$9583, #$9BAE, #$524D, - #$5584, #$6F38, #$7136, #$5168, #$7985, #$7E55, #$81B3, #$7CCE, - #$564C, #$5851, #$5CA8, #$63AA, #$66FE, #$66FD, #$695A, #$72D9, - #$758F, #$758E, #$790E, #$7956, #$79DF, #$7C97, #$7D20, #$7D44, - #$8607, #$8A34, #$963B, #$9061, #$9F20, #$50E7, #$5275, #$53CC, - #$53E2, #$5009, #$55AA, #$58EE, #$594F, #$723D, #$5B8B, #$5C64, - #$531D, #$60E3, #$60F3, #$635C, #$6383, #$633F, #$63BB, #$64CD, - #$65E9, #$66F9, #$5DE3, #$69CD, #$69FD, #$6F15, #$71E5, #$4E89, - #$75E9, #$76F8, #$7A93, #$7CDF, #$7DCF, #$7D9C, #$8061, #$8349, - #$8358, #$846C, #$84BC, #$85FB, #$88C5, #$8D70, #$9001, #$906D, - #$9397, #$971C, #$9A12, #$50CF, #$5897, #$618E, - #$81D3, #$8535, #$8D08, #$9020, #$4FC3, #$5074, #$5247, #$5373, - #$606F, #$6349, #$675F, #$6E2C, #$8DB3, #$901F, #$4FD7, #$5C5E, - #$8CCA, #$65CF, #$7D9A, #$5352, #$8896, #$5176, #$63C3, #$5B58, - #$5B6B, #$5C0A, #$640D, #$6751, #$905C, #$4ED6, #$591A, #$592A, - #$6C70, #$8A51, #$553E, #$5815, #$59A5, #$60F0, #$6253, #$67C1, - #$8235, #$6955, #$9640, #$99C4, #$9A28, #$4F53, #$5806, #$5BFE, - #$8010, #$5CB1, #$5E2F, #$5F85, #$6020, #$614B, #$6234, #$66FF, - #$6CF0, #$6EDE, #$80CE, #$817F, #$82D4, #$888B, #$8CB8, #$9000, - #$902E, #$968A, #$9EDB, #$9BDB, #$4EE3, #$53F0, #$5927, #$7B2C, - #$918D, #$984C, #$9DF9, #$6EDD, #$7027, #$5353, #$5544, #$5B85, - #$6258, #$629E, #$62D3, #$6CA2, #$6FEF, #$7422, #$8A17, #$9438, - #$6FC1, #$8AFE, #$8338, #$51E7, #$86F8, #$53EA, - #$53E9, #$4F46, #$9054, #$8FB0, #$596A, #$8131, #$5DFD, #$7AEA, - #$8FBF, #$68DA, #$8C37, #$72F8, #$9C48, #$6A3D, #$8AB0, #$4E39, - #$5358, #$5606, #$5766, #$62C5, #$63A2, #$65E6, #$6B4E, #$6DE1, - #$6E5B, #$70AD, #$77ED, #$7AEF, #$7BAA, #$7DBB, #$803D, #$80C6, - #$86CB, #$8A95, #$935B, #$56E3, #$58C7, #$5F3E, #$65AD, #$6696, - #$6A80, #$6BB5, #$7537, #$8AC7, #$5024, #$77E5, #$5730, #$5F1B, - #$6065, #$667A, #$6C60, #$75F4, #$7A1A, #$7F6E, #$81F4, #$8718, - #$9045, #$99B3, #$7BC9, #$755C, #$7AF9, #$7B51, #$84C4, #$9010, - #$79E9, #$7A92, #$8336, #$5AE1, #$7740, #$4E2D, #$4EF2, #$5B99, - #$5FE0, #$62BD, #$663C, #$67F1, #$6CE8, #$866B, #$8877, #$8A3B, - #$914E, #$92F3, #$99D0, #$6A17, #$7026, #$732A, #$82E7, #$8457, - #$8CAF, #$4E01, #$5146, #$51CB, #$558B, #$5BF5, - #$5E16, #$5E33, #$5E81, #$5F14, #$5F35, #$5F6B, #$5FB4, #$61F2, - #$6311, #$66A2, #$671D, #$6F6E, #$7252, #$753A, #$773A, #$8074, - #$8139, #$8178, #$8776, #$8ABF, #$8ADC, #$8D85, #$8DF3, #$929A, - #$9577, #$9802, #$9CE5, #$52C5, #$6357, #$76F4, #$6715, #$6C88, - #$73CD, #$8CC3, #$93AE, #$9673, #$6D25, #$589C, #$690E, #$69CC, - #$8FFD, #$939A, #$75DB, #$901A, #$585A, #$6802, #$63B4, #$69FB, - #$4F43, #$6F2C, #$67D8, #$8FBB, #$8526, #$7DB4, #$9354, #$693F, - #$6F70, #$576A, #$58F7, #$5B2C, #$7D2C, #$722A, #$540A, #$91E3, - #$9DB4, #$4EAD, #$4F4E, #$505C, #$5075, #$5243, #$8C9E, #$5448, - #$5824, #$5B9A, #$5E1D, #$5E95, #$5EAD, #$5EF7, #$5F1F, #$608C, - #$62B5, #$633A, #$63D0, #$68AF, #$6C40, #$7887, #$798E, #$7A0B, - #$7DE0, #$8247, #$8A02, #$8AE6, #$8E44, #$9013, - #$90B8, #$912D, #$91D8, #$9F0E, #$6CE5, #$6458, #$64E2, #$6575, - #$6EF4, #$7684, #$7B1B, #$9069, #$93D1, #$6EBA, #$54F2, #$5FB9, - #$64A4, #$8F4D, #$8FED, #$9244, #$5178, #$586B, #$5929, #$5C55, - #$5E97, #$6DFB, #$7E8F, #$751C, #$8CBC, #$8EE2, #$985B, #$70B9, - #$4F1D, #$6BBF, #$6FB1, #$7530, #$96FB, #$514E, #$5410, #$5835, - #$5857, #$59AC, #$5C60, #$5F92, #$6597, #$675C, #$6E21, #$767B, - #$83DF, #$8CED, #$9014, #$90FD, #$934D, #$7825, #$783A, #$52AA, - #$5EA6, #$571F, #$5974, #$6012, #$5012, #$515A, #$51AC, #$51CD, - #$5200, #$5510, #$5854, #$5858, #$5957, #$5B95, #$5CF6, #$5D8B, - #$60BC, #$6295, #$642D, #$6771, #$6843, #$68BC, #$68DF, #$76D7, - #$6DD8, #$6E6F, #$6D9B, #$706F, #$71C8, #$5F53, #$75D8, #$7977, - #$7B49, #$7B54, #$7B52, #$7CD6, #$7D71, #$5230, - #$8463, #$8569, #$85E4, #$8A0E, #$8B04, #$8C46, #$8E0F, #$9003, - #$900F, #$9419, #$9676, #$982D, #$9A30, #$95D8, #$50CD, #$52D5, - #$540C, #$5802, #$5C0E, #$61A7, #$649E, #$6D1E, #$77B3, #$7AE5, - #$80F4, #$8404, #$9053, #$9285, #$5CE0, #$9D07, #$533F, #$5F97, - #$5FB3, #$6D9C, #$7279, #$7763, #$79BF, #$7BE4, #$6BD2, #$72EC, - #$8AAD, #$6803, #$6A61, #$51F8, #$7A81, #$6934, #$5C4A, #$9CF6, - #$82EB, #$5BC5, #$9149, #$701E, #$5678, #$5C6F, #$60C7, #$6566, - #$6C8C, #$8C5A, #$9041, #$9813, #$5451, #$66C7, #$920D, #$5948, - #$90A3, #$5185, #$4E4D, #$51EA, #$8599, #$8B0E, #$7058, #$637A, - #$934B, #$6962, #$99B4, #$7E04, #$7577, #$5357, #$6960, #$8EDF, - #$96E3, #$6C5D, #$4E8C, #$5C3C, #$5F10, #$8FE9, #$5302, #$8CD1, - #$8089, #$8679, #$5EFF, #$65E5, #$4E73, #$5165, - #$5982, #$5C3F, #$97EE, #$4EFB, #$598A, #$5FCD, #$8A8D, #$6FE1, - #$79B0, #$7962, #$5BE7, #$8471, #$732B, #$71B1, #$5E74, #$5FF5, - #$637B, #$649A, #$71C3, #$7C98, #$4E43, #$5EFC, #$4E4B, #$57DC, - #$56A2, #$60A9, #$6FC3, #$7D0D, #$80FD, #$8133, #$81BF, #$8FB2, - #$8997, #$86A4, #$5DF4, #$628A, #$64AD, #$8987, #$6777, #$6CE2, - #$6D3E, #$7436, #$7834, #$5A46, #$7F75, #$82AD, #$99AC, #$4FF3, - #$5EC3, #$62DD, #$6392, #$6557, #$676F, #$76C3, #$724C, #$80CC, - #$80BA, #$8F29, #$914D, #$500D, #$57F9, #$5A92, #$6885, #$6973, - #$7164, #$72FD, #$8CB7, #$58F2, #$8CE0, #$966A, #$9019, #$877F, - #$79E4, #$77E7, #$8429, #$4F2F, #$5265, #$535A, #$62CD, #$67CF, - #$6CCA, #$767D, #$7B94, #$7C95, #$8236, #$8584, #$8FEB, #$66DD, - #$6F20, #$7206, #$7E1B, #$83AB, #$99C1, #$9EA6, - #$51FD, #$7BB1, #$7872, #$7BB8, #$8087, #$7B48, #$6AE8, #$5E61, - #$808C, #$7551, #$7560, #$516B, #$9262, #$6E8C, #$767A, #$9197, - #$9AEA, #$4F10, #$7F70, #$629C, #$7B4F, #$95A5, #$9CE9, #$567A, - #$5859, #$86E4, #$96BC, #$4F34, #$5224, #$534A, #$53CD, #$53DB, - #$5E06, #$642C, #$6591, #$677F, #$6C3E, #$6C4E, #$7248, #$72AF, - #$73ED, #$7554, #$7E41, #$822C, #$85E9, #$8CA9, #$7BC4, #$91C6, - #$7169, #$9812, #$98EF, #$633D, #$6669, #$756A, #$76E4, #$78D0, - #$8543, #$86EE, #$532A, #$5351, #$5426, #$5983, #$5E87, #$5F7C, - #$60B2, #$6249, #$6279, #$62AB, #$6590, #$6BD4, #$6CCC, #$75B2, - #$76AE, #$7891, #$79D8, #$7DCB, #$7F77, #$80A5, #$88AB, #$8AB9, - #$8CBB, #$907F, #$975E, #$98DB, #$6A0B, #$7C38, #$5099, #$5C3E, - #$5FAE, #$6787, #$6BD8, #$7435, #$7709, #$7F8E, - #$9F3B, #$67CA, #$7A17, #$5339, #$758B, #$9AED, #$5F66, #$819D, - #$83F1, #$8098, #$5F3C, #$5FC5, #$7562, #$7B46, #$903C, #$6867, - #$59EB, #$5A9B, #$7D10, #$767E, #$8B2C, #$4FF5, #$5F6A, #$6A19, - #$6C37, #$6F02, #$74E2, #$7968, #$8868, #$8A55, #$8C79, #$5EDF, - #$63CF, #$75C5, #$79D2, #$82D7, #$9328, #$92F2, #$849C, #$86ED, - #$9C2D, #$54C1, #$5F6C, #$658C, #$6D5C, #$7015, #$8CA7, #$8CD3, - #$983B, #$654F, #$74F6, #$4E0D, #$4ED8, #$57E0, #$592B, #$5A66, - #$5BCC, #$51A8, #$5E03, #$5E9C, #$6016, #$6276, #$6577, #$65A7, - #$666E, #$6D6E, #$7236, #$7B26, #$8150, #$819A, #$8299, #$8B5C, - #$8CA0, #$8CE6, #$8D74, #$961C, #$9644, #$4FAE, #$64AB, #$6B66, - #$821E, #$8461, #$856A, #$90E8, #$5C01, #$6953, #$98A8, #$847A, - #$8557, #$4F0F, #$526F, #$5FA9, #$5E45, #$670D, - #$798F, #$8179, #$8907, #$8986, #$6DF5, #$5F17, #$6255, #$6CB8, - #$4ECF, #$7269, #$9B92, #$5206, #$543B, #$5674, #$58B3, #$61A4, - #$626E, #$711A, #$596E, #$7C89, #$7CDE, #$7D1B, #$96F0, #$6587, - #$805E, #$4E19, #$4F75, #$5175, #$5840, #$5E63, #$5E73, #$5F0A, - #$67C4, #$4E26, #$853D, #$9589, #$965B, #$7C73, #$9801, #$50FB, - #$58C1, #$7656, #$78A7, #$5225, #$77A5, #$8511, #$7B86, #$504F, - #$5909, #$7247, #$7BC7, #$7DE8, #$8FBA, #$8FD4, #$904D, #$4FBF, - #$52C9, #$5A29, #$5F01, #$97AD, #$4FDD, #$8217, #$92EA, #$5703, - #$6355, #$6B69, #$752B, #$88DC, #$8F14, #$7A42, #$52DF, #$5893, - #$6155, #$620A, #$66AE, #$6BCD, #$7C3F, #$83E9, #$5023, #$4FF8, - #$5305, #$5446, #$5831, #$5949, #$5B9D, #$5CF0, #$5CEF, #$5D29, - #$5E96, #$62B1, #$6367, #$653E, #$65B9, #$670B, - #$6CD5, #$6CE1, #$70F9, #$7832, #$7E2B, #$80DE, #$82B3, #$840C, - #$84EC, #$8702, #$8912, #$8A2A, #$8C4A, #$90A6, #$92D2, #$98FD, - #$9CF3, #$9D6C, #$4E4F, #$4EA1, #$508D, #$5256, #$574A, #$59A8, - #$5E3D, #$5FD8, #$5FD9, #$623F, #$66B4, #$671B, #$67D0, #$68D2, - #$5192, #$7D21, #$80AA, #$81A8, #$8B00, #$8C8C, #$8CBF, #$927E, - #$9632, #$5420, #$982C, #$5317, #$50D5, #$535C, #$58A8, #$64B2, - #$6734, #$7267, #$7766, #$7A46, #$91E6, #$52C3, #$6CA1, #$6B86, - #$5800, #$5E4C, #$5954, #$672C, #$7FFB, #$51E1, #$76C6, #$6469, - #$78E8, #$9B54, #$9EBB, #$57CB, #$59B9, #$6627, #$679A, #$6BCE, - #$54E9, #$69D9, #$5E55, #$819C, #$6795, #$9BAA, #$67FE, #$9C52, - #$685D, #$4EA6, #$4FE3, #$53C8, #$62B9, #$672B, #$6CAB, #$8FC4, - #$4FAD, #$7E6D, #$9EBF, #$4E07, #$6162, #$6E80, - #$6F2B, #$8513, #$5473, #$672A, #$9B45, #$5DF3, #$7B95, #$5CAC, - #$5BC6, #$871C, #$6E4A, #$84D1, #$7A14, #$8108, #$5999, #$7C8D, - #$6C11, #$7720, #$52D9, #$5922, #$7121, #$725F, #$77DB, #$9727, - #$9D61, #$690B, #$5A7F, #$5A18, #$51A5, #$540D, #$547D, #$660E, - #$76DF, #$8FF7, #$9298, #$9CF4, #$59EA, #$725D, #$6EC5, #$514D, - #$68C9, #$7DBF, #$7DEC, #$9762, #$9EBA, #$6478, #$6A21, #$8302, - #$5984, #$5B5F, #$6BDB, #$731B, #$76F2, #$7DB2, #$8017, #$8499, - #$5132, #$6728, #$9ED9, #$76EE, #$6762, #$52FF, #$9905, #$5C24, - #$623B, #$7C7E, #$8CB0, #$554F, #$60B6, #$7D0B, #$9580, #$5301, - #$4E5F, #$51B6, #$591C, #$723A, #$8036, #$91CE, #$5F25, #$77E2, - #$5384, #$5F79, #$7D04, #$85AC, #$8A33, #$8E8D, #$9756, #$67F3, - #$85AE, #$9453, #$6109, #$6108, #$6CB9, #$7652, - #$8AED, #$8F38, #$552F, #$4F51, #$512A, #$52C7, #$53CB, #$5BA5, - #$5E7D, #$60A0, #$6182, #$63D6, #$6709, #$67DA, #$6E67, #$6D8C, - #$7336, #$7337, #$7531, #$7950, #$88D5, #$8A98, #$904A, #$9091, - #$90F5, #$96C4, #$878D, #$5915, #$4E88, #$4F59, #$4E0E, #$8A89, - #$8F3F, #$9810, #$50AD, #$5E7C, #$5996, #$5BB9, #$5EB8, #$63DA, - #$63FA, #$64C1, #$66DC, #$694A, #$69D8, #$6D0B, #$6EB6, #$7194, - #$7528, #$7AAF, #$7F8A, #$8000, #$8449, #$84C9, #$8981, #$8B21, - #$8E0A, #$9065, #$967D, #$990A, #$617E, #$6291, #$6B32, #$6C83, - #$6D74, #$7FCC, #$7FFC, #$6DC0, #$7F85, #$87BA, #$88F8, #$6765, - #$83B1, #$983C, #$96F7, #$6D1B, #$7D61, #$843D, #$916A, #$4E71, - #$5375, #$5D50, #$6B04, #$6FEB, #$85CD, #$862D, #$89A7, #$5229, - #$540F, #$5C65, #$674E, #$68A8, #$7406, #$7483, - #$75E2, #$88CF, #$88E1, #$91CC, #$96E2, #$9678, #$5F8B, #$7387, - #$7ACB, #$844E, #$63A0, #$7565, #$5289, #$6D41, #$6E9C, #$7409, - #$7559, #$786B, #$7C92, #$9686, #$7ADC, #$9F8D, #$4FB6, #$616E, - #$65C5, #$865C, #$4E86, #$4EAE, #$50DA, #$4E21, #$51CC, #$5BEE, - #$6599, #$6881, #$6DBC, #$731F, #$7642, #$77AD, #$7A1C, #$7CE7, - #$826F, #$8AD2, #$907C, #$91CF, #$9675, #$9818, #$529B, #$7DD1, - #$502B, #$5398, #$6797, #$6DCB, #$71D0, #$7433, #$81E8, #$8F2A, - #$96A3, #$9C57, #$9E9F, #$7460, #$5841, #$6D99, #$7D2F, #$985E, - #$4EE4, #$4F36, #$4F8B, #$51B7, #$52B1, #$5DBA, #$601C, #$73B2, - #$793C, #$82D3, #$9234, #$96B7, #$96F6, #$970A, #$9E97, #$9F62, - #$66A6, #$6B74, #$5217, #$52A3, #$70C8, #$88C2, #$5EC9, #$604B, - #$6190, #$6F23, #$7149, #$7C3E, #$7DF4, #$806F, - #$84EE, #$9023, #$932C, #$5442, #$9B6F, #$6AD3, #$7089, #$8CC2, - #$8DEF, #$9732, #$52B4, #$5A41, #$5ECA, #$5F04, #$6717, #$697C, - #$6994, #$6D6A, #$6F0F, #$7262, #$72FC, #$7BED, #$8001, #$807E, - #$874B, #$90CE, #$516D, #$9E93, #$7984, #$808B, #$9332, #$8AD6, - #$502D, #$548C, #$8A71, #$6B6A, #$8CC4, #$8107, #$60D1, #$67A0, - #$9DF2, #$4E99, #$4E98, #$9C10, #$8A6B, #$85C1, #$8568, #$6900, - #$6E7E, #$7897, #$8155, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$5F0C, #$4E10, #$4E15, #$4E2A, #$4E31, #$4E36, #$4E3C, #$4E3F, - #$4E42, #$4E56, #$4E58, #$4E82, #$4E85, #$8C6B, #$4E8A, #$8212, - #$5F0D, #$4E8E, #$4E9E, #$4E9F, #$4EA0, #$4EA2, #$4EB0, #$4EB3, - #$4EB6, #$4ECE, #$4ECD, #$4EC4, #$4EC6, #$4EC2, #$4ED7, #$4EDE, - #$4EED, #$4EDF, #$4EF7, #$4F09, #$4F5A, #$4F30, #$4F5B, #$4F5D, - #$4F57, #$4F47, #$4F76, #$4F88, #$4F8F, #$4F98, #$4F7B, #$4F69, - #$4F70, #$4F91, #$4F6F, #$4F86, #$4F96, #$5118, #$4FD4, #$4FDF, - #$4FCE, #$4FD8, #$4FDB, #$4FD1, #$4FDA, #$4FD0, #$4FE4, #$4FE5, - #$501A, #$5028, #$5014, #$502A, #$5025, #$5005, #$4F1C, #$4FF6, - #$5021, #$5029, #$502C, #$4FFE, #$4FEF, #$5011, #$5006, #$5043, - #$5047, #$6703, #$5055, #$5050, #$5048, #$505A, #$5056, #$506C, - #$5078, #$5080, #$509A, #$5085, #$50B4, #$50B2, - #$50C9, #$50CA, #$50B3, #$50C2, #$50D6, #$50DE, #$50E5, #$50ED, - #$50E3, #$50EE, #$50F9, #$50F5, #$5109, #$5101, #$5102, #$5116, - #$5115, #$5114, #$511A, #$5121, #$513A, #$5137, #$513C, #$513B, - #$513F, #$5140, #$5152, #$514C, #$5154, #$5162, #$7AF8, #$5169, - #$516A, #$516E, #$5180, #$5182, #$56D8, #$518C, #$5189, #$518F, - #$5191, #$5193, #$5195, #$5196, #$51A4, #$51A6, #$51A2, #$51A9, - #$51AA, #$51AB, #$51B3, #$51B1, #$51B2, #$51B0, #$51B5, #$51BD, - #$51C5, #$51C9, #$51DB, #$51E0, #$8655, #$51E9, #$51ED, #$51F0, - #$51F5, #$51FE, #$5204, #$520B, #$5214, #$520E, #$5227, #$522A, - #$522E, #$5233, #$5239, #$524F, #$5244, #$524B, #$524C, #$525E, - #$5254, #$526A, #$5274, #$5269, #$5273, #$527F, #$527D, #$528D, - #$5294, #$5292, #$5271, #$5288, #$5291, #$8FA8, - #$8FA7, #$52AC, #$52AD, #$52BC, #$52B5, #$52C1, #$52CD, #$52D7, - #$52DE, #$52E3, #$52E6, #$98ED, #$52E0, #$52F3, #$52F5, #$52F8, - #$52F9, #$5306, #$5308, #$7538, #$530D, #$5310, #$530F, #$5315, - #$531A, #$5323, #$532F, #$5331, #$5333, #$5338, #$5340, #$5346, - #$5345, #$4E17, #$5349, #$534D, #$51D6, #$535E, #$5369, #$536E, - #$5918, #$537B, #$5377, #$5382, #$5396, #$53A0, #$53A6, #$53A5, - #$53AE, #$53B0, #$53B6, #$53C3, #$7C12, #$96D9, #$53DF, #$66FC, - #$71EE, #$53EE, #$53E8, #$53ED, #$53FA, #$5401, #$543D, #$5440, - #$542C, #$542D, #$543C, #$542E, #$5436, #$5429, #$541D, #$544E, - #$548F, #$5475, #$548E, #$545F, #$5471, #$5477, #$5470, #$5492, - #$547B, #$5480, #$5476, #$5484, #$5490, #$5486, #$54C7, #$54A2, - #$54B8, #$54A5, #$54AC, #$54C4, #$54C8, #$54A8, - #$54AB, #$54C2, #$54A4, #$54BE, #$54BC, #$54D8, #$54E5, #$54E6, - #$550F, #$5514, #$54FD, #$54EE, #$54ED, #$54FA, #$54E2, #$5539, - #$5540, #$5563, #$554C, #$552E, #$555C, #$5545, #$5556, #$5557, - #$5538, #$5533, #$555D, #$5599, #$5580, #$54AF, #$558A, #$559F, - #$557B, #$557E, #$5598, #$559E, #$55AE, #$557C, #$5583, #$55A9, - #$5587, #$55A8, #$55DA, #$55C5, #$55DF, #$55C4, #$55DC, #$55E4, - #$55D4, #$5614, #$55F7, #$5616, #$55FE, #$55FD, #$561B, #$55F9, - #$564E, #$5650, #$71DF, #$5634, #$5636, #$5632, #$5638, #$566B, - #$5664, #$562F, #$566C, #$566A, #$5686, #$5680, #$568A, #$56A0, - #$5694, #$568F, #$56A5, #$56AE, #$56B6, #$56B4, #$56C2, #$56BC, - #$56C1, #$56C3, #$56C0, #$56C8, #$56CE, #$56D1, #$56D3, #$56D7, - #$56EE, #$56F9, #$5700, #$56FF, #$5704, #$5709, - #$5708, #$570B, #$570D, #$5713, #$5718, #$5716, #$55C7, #$571C, - #$5726, #$5737, #$5738, #$574E, #$573B, #$5740, #$574F, #$5769, - #$57C0, #$5788, #$5761, #$577F, #$5789, #$5793, #$57A0, #$57B3, - #$57A4, #$57AA, #$57B0, #$57C3, #$57C6, #$57D4, #$57D2, #$57D3, - #$580A, #$57D6, #$57E3, #$580B, #$5819, #$581D, #$5872, #$5821, - #$5862, #$584B, #$5870, #$6BC0, #$5852, #$583D, #$5879, #$5885, - #$58B9, #$589F, #$58AB, #$58BA, #$58DE, #$58BB, #$58B8, #$58AE, - #$58C5, #$58D3, #$58D1, #$58D7, #$58D9, #$58D8, #$58E5, #$58DC, - #$58E4, #$58DF, #$58EF, #$58FA, #$58F9, #$58FB, #$58FC, #$58FD, - #$5902, #$590A, #$5910, #$591B, #$68A6, #$5925, #$592C, #$592D, - #$5932, #$5938, #$593E, #$7AD2, #$5955, #$5950, #$594E, #$595A, - #$5958, #$5962, #$5960, #$5967, #$596C, #$5969, - #$5978, #$5981, #$599D, #$4F5E, #$4FAB, #$59A3, #$59B2, #$59C6, - #$59E8, #$59DC, #$598D, #$59D9, #$59DA, #$5A25, #$5A1F, #$5A11, - #$5A1C, #$5A09, #$5A1A, #$5A40, #$5A6C, #$5A49, #$5A35, #$5A36, - #$5A62, #$5A6A, #$5A9A, #$5ABC, #$5ABE, #$5ACB, #$5AC2, #$5ABD, - #$5AE3, #$5AD7, #$5AE6, #$5AE9, #$5AD6, #$5AFA, #$5AFB, #$5B0C, - #$5B0B, #$5B16, #$5B32, #$5AD0, #$5B2A, #$5B36, #$5B3E, #$5B43, - #$5B45, #$5B40, #$5B51, #$5B55, #$5B5A, #$5B5B, #$5B65, #$5B69, - #$5B70, #$5B73, #$5B75, #$5B78, #$6588, #$5B7A, #$5B80, #$5B83, - #$5BA6, #$5BB8, #$5BC3, #$5BC7, #$5BC9, #$5BD4, #$5BD0, #$5BE4, - #$5BE6, #$5BE2, #$5BDE, #$5BE5, #$5BEB, #$5BF0, #$5BF6, #$5BF3, - #$5C05, #$5C07, #$5C08, #$5C0D, #$5C13, #$5C20, #$5C22, #$5C28, - #$5C38, #$5C39, #$5C41, #$5C46, #$5C4E, #$5C53, - #$5C50, #$5C4F, #$5B71, #$5C6C, #$5C6E, #$4E62, #$5C76, #$5C79, - #$5C8C, #$5C91, #$5C94, #$599B, #$5CAB, #$5CBB, #$5CB6, #$5CBC, - #$5CB7, #$5CC5, #$5CBE, #$5CC7, #$5CD9, #$5CE9, #$5CFD, #$5CFA, - #$5CED, #$5D8C, #$5CEA, #$5D0B, #$5D15, #$5D17, #$5D5C, #$5D1F, - #$5D1B, #$5D11, #$5D14, #$5D22, #$5D1A, #$5D19, #$5D18, #$5D4C, - #$5D52, #$5D4E, #$5D4B, #$5D6C, #$5D73, #$5D76, #$5D87, #$5D84, - #$5D82, #$5DA2, #$5D9D, #$5DAC, #$5DAE, #$5DBD, #$5D90, #$5DB7, - #$5DBC, #$5DC9, #$5DCD, #$5DD3, #$5DD2, #$5DD6, #$5DDB, #$5DEB, - #$5DF2, #$5DF5, #$5E0B, #$5E1A, #$5E19, #$5E11, #$5E1B, #$5E36, - #$5E37, #$5E44, #$5E43, #$5E40, #$5E4E, #$5E57, #$5E54, #$5E5F, - #$5E62, #$5E64, #$5E47, #$5E75, #$5E76, #$5E7A, #$9EBC, #$5E7F, - #$5EA0, #$5EC1, #$5EC2, #$5EC8, #$5ED0, #$5ECF, - #$5ED6, #$5EE3, #$5EDD, #$5EDA, #$5EDB, #$5EE2, #$5EE1, #$5EE8, - #$5EE9, #$5EEC, #$5EF1, #$5EF3, #$5EF0, #$5EF4, #$5EF8, #$5EFE, - #$5F03, #$5F09, #$5F5D, #$5F5C, #$5F0B, #$5F11, #$5F16, #$5F29, - #$5F2D, #$5F38, #$5F41, #$5F48, #$5F4C, #$5F4E, #$5F2F, #$5F51, - #$5F56, #$5F57, #$5F59, #$5F61, #$5F6D, #$5F73, #$5F77, #$5F83, - #$5F82, #$5F7F, #$5F8A, #$5F88, #$5F91, #$5F87, #$5F9E, #$5F99, - #$5F98, #$5FA0, #$5FA8, #$5FAD, #$5FBC, #$5FD6, #$5FFB, #$5FE4, - #$5FF8, #$5FF1, #$5FDD, #$60B3, #$5FFF, #$6021, #$6060, #$6019, - #$6010, #$6029, #$600E, #$6031, #$601B, #$6015, #$602B, #$6026, - #$600F, #$603A, #$605A, #$6041, #$606A, #$6077, #$605F, #$604A, - #$6046, #$604D, #$6063, #$6043, #$6064, #$6042, #$606C, #$606B, - #$6059, #$6081, #$608D, #$60E7, #$6083, #$609A, - #$6084, #$609B, #$6096, #$6097, #$6092, #$60A7, #$608B, #$60E1, - #$60B8, #$60E0, #$60D3, #$60B4, #$5FF0, #$60BD, #$60C6, #$60B5, - #$60D8, #$614D, #$6115, #$6106, #$60F6, #$60F7, #$6100, #$60F4, - #$60FA, #$6103, #$6121, #$60FB, #$60F1, #$610D, #$610E, #$6147, - #$613E, #$6128, #$6127, #$614A, #$613F, #$613C, #$612C, #$6134, - #$613D, #$6142, #$6144, #$6173, #$6177, #$6158, #$6159, #$615A, - #$616B, #$6174, #$616F, #$6165, #$6171, #$615F, #$615D, #$6153, - #$6175, #$6199, #$6196, #$6187, #$61AC, #$6194, #$619A, #$618A, - #$6191, #$61AB, #$61AE, #$61CC, #$61CA, #$61C9, #$61F7, #$61C8, - #$61C3, #$61C6, #$61BA, #$61CB, #$7F79, #$61CD, #$61E6, #$61E3, - #$61F6, #$61FA, #$61F4, #$61FF, #$61FD, #$61FC, #$61FE, #$6200, - #$6208, #$6209, #$620D, #$620C, #$6214, #$621B, - #$621E, #$6221, #$622A, #$622E, #$6230, #$6232, #$6233, #$6241, - #$624E, #$625E, #$6263, #$625B, #$6260, #$6268, #$627C, #$6282, - #$6289, #$627E, #$6292, #$6293, #$6296, #$62D4, #$6283, #$6294, - #$62D7, #$62D1, #$62BB, #$62CF, #$62FF, #$62C6, #$64D4, #$62C8, - #$62DC, #$62CC, #$62CA, #$62C2, #$62C7, #$629B, #$62C9, #$630C, - #$62EE, #$62F1, #$6327, #$6302, #$6308, #$62EF, #$62F5, #$6350, - #$633E, #$634D, #$641C, #$634F, #$6396, #$638E, #$6380, #$63AB, - #$6376, #$63A3, #$638F, #$6389, #$639F, #$63B5, #$636B, #$6369, - #$63BE, #$63E9, #$63C0, #$63C6, #$63E3, #$63C9, #$63D2, #$63F6, - #$63C4, #$6416, #$6434, #$6406, #$6413, #$6426, #$6436, #$651D, - #$6417, #$6428, #$640F, #$6467, #$646F, #$6476, #$644E, #$652A, - #$6495, #$6493, #$64A5, #$64A9, #$6488, #$64BC, - #$64DA, #$64D2, #$64C5, #$64C7, #$64BB, #$64D8, #$64C2, #$64F1, - #$64E7, #$8209, #$64E0, #$64E1, #$62AC, #$64E3, #$64EF, #$652C, - #$64F6, #$64F4, #$64F2, #$64FA, #$6500, #$64FD, #$6518, #$651C, - #$6505, #$6524, #$6523, #$652B, #$6534, #$6535, #$6537, #$6536, - #$6538, #$754B, #$6548, #$6556, #$6555, #$654D, #$6558, #$655E, - #$655D, #$6572, #$6578, #$6582, #$6583, #$8B8A, #$659B, #$659F, - #$65AB, #$65B7, #$65C3, #$65C6, #$65C1, #$65C4, #$65CC, #$65D2, - #$65DB, #$65D9, #$65E0, #$65E1, #$65F1, #$6772, #$660A, #$6603, - #$65FB, #$6773, #$6635, #$6636, #$6634, #$661C, #$664F, #$6644, - #$6649, #$6641, #$665E, #$665D, #$6664, #$6667, #$6668, #$665F, - #$6662, #$6670, #$6683, #$6688, #$668E, #$6689, #$6684, #$6698, - #$669D, #$66C1, #$66B9, #$66C9, #$66BE, #$66BC, - #$66C4, #$66B8, #$66D6, #$66DA, #$66E0, #$663F, #$66E6, #$66E9, - #$66F0, #$66F5, #$66F7, #$670F, #$6716, #$671E, #$6726, #$6727, - #$9738, #$672E, #$673F, #$6736, #$6741, #$6738, #$6737, #$6746, - #$675E, #$6760, #$6759, #$6763, #$6764, #$6789, #$6770, #$67A9, - #$677C, #$676A, #$678C, #$678B, #$67A6, #$67A1, #$6785, #$67B7, - #$67EF, #$67B4, #$67EC, #$67B3, #$67E9, #$67B8, #$67E4, #$67DE, - #$67DD, #$67E2, #$67EE, #$67B9, #$67CE, #$67C6, #$67E7, #$6A9C, - #$681E, #$6846, #$6829, #$6840, #$684D, #$6832, #$684E, #$68B3, - #$682B, #$6859, #$6863, #$6877, #$687F, #$689F, #$688F, #$68AD, - #$6894, #$689D, #$689B, #$6883, #$6AAE, #$68B9, #$6874, #$68B5, - #$68A0, #$68BA, #$690F, #$688D, #$687E, #$6901, #$68CA, #$6908, - #$68D8, #$6922, #$6926, #$68E1, #$690C, #$68CD, - #$68D4, #$68E7, #$68D5, #$6936, #$6912, #$6904, #$68D7, #$68E3, - #$6925, #$68F9, #$68E0, #$68EF, #$6928, #$692A, #$691A, #$6923, - #$6921, #$68C6, #$6979, #$6977, #$695C, #$6978, #$696B, #$6954, - #$697E, #$696E, #$6939, #$6974, #$693D, #$6959, #$6930, #$6961, - #$695E, #$695D, #$6981, #$696A, #$69B2, #$69AE, #$69D0, #$69BF, - #$69C1, #$69D3, #$69BE, #$69CE, #$5BE8, #$69CA, #$69DD, #$69BB, - #$69C3, #$69A7, #$6A2E, #$6991, #$69A0, #$699C, #$6995, #$69B4, - #$69DE, #$69E8, #$6A02, #$6A1B, #$69FF, #$6B0A, #$69F9, #$69F2, - #$69E7, #$6A05, #$69B1, #$6A1E, #$69ED, #$6A14, #$69EB, #$6A0A, - #$6A12, #$6AC1, #$6A23, #$6A13, #$6A44, #$6A0C, #$6A72, #$6A36, - #$6A78, #$6A47, #$6A62, #$6A59, #$6A66, #$6A48, #$6A38, #$6A22, - #$6A90, #$6A8D, #$6AA0, #$6A84, #$6AA2, #$6AA3, - #$6A97, #$8617, #$6ABB, #$6AC3, #$6AC2, #$6AB8, #$6AB3, #$6AAC, - #$6ADE, #$6AD1, #$6ADF, #$6AAA, #$6ADA, #$6AEA, #$6AFB, #$6B05, - #$8616, #$6AFA, #$6B12, #$6B16, #$9B31, #$6B1F, #$6B38, #$6B37, - #$76DC, #$6B39, #$98EE, #$6B47, #$6B43, #$6B49, #$6B50, #$6B59, - #$6B54, #$6B5B, #$6B5F, #$6B61, #$6B78, #$6B79, #$6B7F, #$6B80, - #$6B84, #$6B83, #$6B8D, #$6B98, #$6B95, #$6B9E, #$6BA4, #$6BAA, - #$6BAB, #$6BAF, #$6BB2, #$6BB1, #$6BB3, #$6BB7, #$6BBC, #$6BC6, - #$6BCB, #$6BD3, #$6BDF, #$6BEC, #$6BEB, #$6BF3, #$6BEF, #$9EBE, - #$6C08, #$6C13, #$6C14, #$6C1B, #$6C24, #$6C23, #$6C5E, #$6C55, - #$6C62, #$6C6A, #$6C82, #$6C8D, #$6C9A, #$6C81, #$6C9B, #$6C7E, - #$6C68, #$6C73, #$6C92, #$6C90, #$6CC4, #$6CF1, #$6CD3, #$6CBD, - #$6CD7, #$6CC5, #$6CDD, #$6CAE, #$6CB1, #$6CBE, - #$6CBA, #$6CDB, #$6CEF, #$6CD9, #$6CEA, #$6D1F, #$884D, #$6D36, - #$6D2B, #$6D3D, #$6D38, #$6D19, #$6D35, #$6D33, #$6D12, #$6D0C, - #$6D63, #$6D93, #$6D64, #$6D5A, #$6D79, #$6D59, #$6D8E, #$6D95, - #$6FE4, #$6D85, #$6DF9, #$6E15, #$6E0A, #$6DB5, #$6DC7, #$6DE6, - #$6DB8, #$6DC6, #$6DEC, #$6DDE, #$6DCC, #$6DE8, #$6DD2, #$6DC5, - #$6DFA, #$6DD9, #$6DE4, #$6DD5, #$6DEA, #$6DEE, #$6E2D, #$6E6E, - #$6E2E, #$6E19, #$6E72, #$6E5F, #$6E3E, #$6E23, #$6E6B, #$6E2B, - #$6E76, #$6E4D, #$6E1F, #$6E43, #$6E3A, #$6E4E, #$6E24, #$6EFF, - #$6E1D, #$6E38, #$6E82, #$6EAA, #$6E98, #$6EC9, #$6EB7, #$6ED3, - #$6EBD, #$6EAF, #$6EC4, #$6EB2, #$6ED4, #$6ED5, #$6E8F, #$6EA5, - #$6EC2, #$6E9F, #$6F41, #$6F11, #$704C, #$6EEC, #$6EF8, #$6EFE, - #$6F3F, #$6EF2, #$6F31, #$6EEF, #$6F32, #$6ECC, - #$6F3E, #$6F13, #$6EF7, #$6F86, #$6F7A, #$6F78, #$6F81, #$6F80, - #$6F6F, #$6F5B, #$6FF3, #$6F6D, #$6F82, #$6F7C, #$6F58, #$6F8E, - #$6F91, #$6FC2, #$6F66, #$6FB3, #$6FA3, #$6FA1, #$6FA4, #$6FB9, - #$6FC6, #$6FAA, #$6FDF, #$6FD5, #$6FEC, #$6FD4, #$6FD8, #$6FF1, - #$6FEE, #$6FDB, #$7009, #$700B, #$6FFA, #$7011, #$7001, #$700F, - #$6FFE, #$701B, #$701A, #$6F74, #$701D, #$7018, #$701F, #$7030, - #$703E, #$7032, #$7051, #$7063, #$7099, #$7092, #$70AF, #$70F1, - #$70AC, #$70B8, #$70B3, #$70AE, #$70DF, #$70CB, #$70DD, #$70D9, - #$7109, #$70FD, #$711C, #$7119, #$7165, #$7155, #$7188, #$7166, - #$7162, #$714C, #$7156, #$716C, #$718F, #$71FB, #$7184, #$7195, - #$71A8, #$71AC, #$71D7, #$71B9, #$71BE, #$71D2, #$71C9, #$71D4, - #$71CE, #$71E0, #$71EC, #$71E7, #$71F5, #$71FC, - #$71F9, #$71FF, #$720D, #$7210, #$721B, #$7228, #$722D, #$722C, - #$7230, #$7232, #$723B, #$723C, #$723F, #$7240, #$7246, #$724B, - #$7258, #$7274, #$727E, #$7282, #$7281, #$7287, #$7292, #$7296, - #$72A2, #$72A7, #$72B9, #$72B2, #$72C3, #$72C6, #$72C4, #$72CE, - #$72D2, #$72E2, #$72E0, #$72E1, #$72F9, #$72F7, #$500F, #$7317, - #$730A, #$731C, #$7316, #$731D, #$7334, #$732F, #$7329, #$7325, - #$733E, #$734E, #$734F, #$9ED8, #$7357, #$736A, #$7368, #$7370, - #$7378, #$7375, #$737B, #$737A, #$73C8, #$73B3, #$73CE, #$73BB, - #$73C0, #$73E5, #$73EE, #$73DE, #$74A2, #$7405, #$746F, #$7425, - #$73F8, #$7432, #$743A, #$7455, #$743F, #$745F, #$7459, #$7441, - #$745C, #$7469, #$7470, #$7463, #$746A, #$7476, #$747E, #$748B, - #$749E, #$74A7, #$74CA, #$74CF, #$74D4, #$73F1, - #$74E0, #$74E3, #$74E7, #$74E9, #$74EE, #$74F2, #$74F0, #$74F1, - #$74F8, #$74F7, #$7504, #$7503, #$7505, #$750C, #$750E, #$750D, - #$7515, #$7513, #$751E, #$7526, #$752C, #$753C, #$7544, #$754D, - #$754A, #$7549, #$755B, #$7546, #$755A, #$7569, #$7564, #$7567, - #$756B, #$756D, #$7578, #$7576, #$7586, #$7587, #$7574, #$758A, - #$7589, #$7582, #$7594, #$759A, #$759D, #$75A5, #$75A3, #$75C2, - #$75B3, #$75C3, #$75B5, #$75BD, #$75B8, #$75BC, #$75B1, #$75CD, - #$75CA, #$75D2, #$75D9, #$75E3, #$75DE, #$75FE, #$75FF, #$75FC, - #$7601, #$75F0, #$75FA, #$75F2, #$75F3, #$760B, #$760D, #$7609, - #$761F, #$7627, #$7620, #$7621, #$7622, #$7624, #$7634, #$7630, - #$763B, #$7647, #$7648, #$7646, #$765C, #$7658, #$7661, #$7662, - #$7668, #$7669, #$766A, #$7667, #$766C, #$7670, - #$7672, #$7676, #$7678, #$767C, #$7680, #$7683, #$7688, #$768B, - #$768E, #$7696, #$7693, #$7699, #$769A, #$76B0, #$76B4, #$76B8, - #$76B9, #$76BA, #$76C2, #$76CD, #$76D6, #$76D2, #$76DE, #$76E1, - #$76E5, #$76E7, #$76EA, #$862F, #$76FB, #$7708, #$7707, #$7704, - #$7729, #$7724, #$771E, #$7725, #$7726, #$771B, #$7737, #$7738, - #$7747, #$775A, #$7768, #$776B, #$775B, #$7765, #$777F, #$777E, - #$7779, #$778E, #$778B, #$7791, #$77A0, #$779E, #$77B0, #$77B6, - #$77B9, #$77BF, #$77BC, #$77BD, #$77BB, #$77C7, #$77CD, #$77D7, - #$77DA, #$77DC, #$77E3, #$77EE, #$77FC, #$780C, #$7812, #$7926, - #$7820, #$792A, #$7845, #$788E, #$7874, #$7886, #$787C, #$789A, - #$788C, #$78A3, #$78B5, #$78AA, #$78AF, #$78D1, #$78C6, #$78CB, - #$78D4, #$78BE, #$78BC, #$78C5, #$78CA, #$78EC, - #$78E7, #$78DA, #$78FD, #$78F4, #$7907, #$7912, #$7911, #$7919, - #$792C, #$792B, #$7940, #$7960, #$7957, #$795F, #$795A, #$7955, - #$7953, #$797A, #$797F, #$798A, #$799D, #$79A7, #$9F4B, #$79AA, - #$79AE, #$79B3, #$79B9, #$79BA, #$79C9, #$79D5, #$79E7, #$79EC, - #$79E1, #$79E3, #$7A08, #$7A0D, #$7A18, #$7A19, #$7A20, #$7A1F, - #$7980, #$7A31, #$7A3B, #$7A3E, #$7A37, #$7A43, #$7A57, #$7A49, - #$7A61, #$7A62, #$7A69, #$9F9D, #$7A70, #$7A79, #$7A7D, #$7A88, - #$7A97, #$7A95, #$7A98, #$7A96, #$7AA9, #$7AC8, #$7AB0, #$7AB6, - #$7AC5, #$7AC4, #$7ABF, #$9083, #$7AC7, #$7ACA, #$7ACD, #$7ACF, - #$7AD5, #$7AD3, #$7AD9, #$7ADA, #$7ADD, #$7AE1, #$7AE2, #$7AE6, - #$7AED, #$7AF0, #$7B02, #$7B0F, #$7B0A, #$7B06, #$7B33, #$7B18, - #$7B19, #$7B1E, #$7B35, #$7B28, #$7B36, #$7B50, - #$7B7A, #$7B04, #$7B4D, #$7B0B, #$7B4C, #$7B45, #$7B75, #$7B65, - #$7B74, #$7B67, #$7B70, #$7B71, #$7B6C, #$7B6E, #$7B9D, #$7B98, - #$7B9F, #$7B8D, #$7B9C, #$7B9A, #$7B8B, #$7B92, #$7B8F, #$7B5D, - #$7B99, #$7BCB, #$7BC1, #$7BCC, #$7BCF, #$7BB4, #$7BC6, #$7BDD, - #$7BE9, #$7C11, #$7C14, #$7BE6, #$7BE5, #$7C60, #$7C00, #$7C07, - #$7C13, #$7BF3, #$7BF7, #$7C17, #$7C0D, #$7BF6, #$7C23, #$7C27, - #$7C2A, #$7C1F, #$7C37, #$7C2B, #$7C3D, #$7C4C, #$7C43, #$7C54, - #$7C4F, #$7C40, #$7C50, #$7C58, #$7C5F, #$7C64, #$7C56, #$7C65, - #$7C6C, #$7C75, #$7C83, #$7C90, #$7CA4, #$7CAD, #$7CA2, #$7CAB, - #$7CA1, #$7CA8, #$7CB3, #$7CB2, #$7CB1, #$7CAE, #$7CB9, #$7CBD, - #$7CC0, #$7CC5, #$7CC2, #$7CD8, #$7CD2, #$7CDC, #$7CE2, #$9B3B, - #$7CEF, #$7CF2, #$7CF4, #$7CF6, #$7CFA, #$7D06, - #$7D02, #$7D1C, #$7D15, #$7D0A, #$7D45, #$7D4B, #$7D2E, #$7D32, - #$7D3F, #$7D35, #$7D46, #$7D73, #$7D56, #$7D4E, #$7D72, #$7D68, - #$7D6E, #$7D4F, #$7D63, #$7D93, #$7D89, #$7D5B, #$7D8F, #$7D7D, - #$7D9B, #$7DBA, #$7DAE, #$7DA3, #$7DB5, #$7DC7, #$7DBD, #$7DAB, - #$7E3D, #$7DA2, #$7DAF, #$7DDC, #$7DB8, #$7D9F, #$7DB0, #$7DD8, - #$7DDD, #$7DE4, #$7DDE, #$7DFB, #$7DF2, #$7DE1, #$7E05, #$7E0A, - #$7E23, #$7E21, #$7E12, #$7E31, #$7E1F, #$7E09, #$7E0B, #$7E22, - #$7E46, #$7E66, #$7E3B, #$7E35, #$7E39, #$7E43, #$7E37, #$7E32, - #$7E3A, #$7E67, #$7E5D, #$7E56, #$7E5E, #$7E59, #$7E5A, #$7E79, - #$7E6A, #$7E69, #$7E7C, #$7E7B, #$7E83, #$7DD5, #$7E7D, #$8FAE, - #$7E7F, #$7E88, #$7E89, #$7E8C, #$7E92, #$7E90, #$7E93, #$7E94, - #$7E96, #$7E8E, #$7E9B, #$7E9C, #$7F38, #$7F3A, - #$7F45, #$7F4C, #$7F4D, #$7F4E, #$7F50, #$7F51, #$7F55, #$7F54, - #$7F58, #$7F5F, #$7F60, #$7F68, #$7F69, #$7F67, #$7F78, #$7F82, - #$7F86, #$7F83, #$7F88, #$7F87, #$7F8C, #$7F94, #$7F9E, #$7F9D, - #$7F9A, #$7FA3, #$7FAF, #$7FB2, #$7FB9, #$7FAE, #$7FB6, #$7FB8, - #$8B71, #$7FC5, #$7FC6, #$7FCA, #$7FD5, #$7FD4, #$7FE1, #$7FE6, - #$7FE9, #$7FF3, #$7FF9, #$98DC, #$8006, #$8004, #$800B, #$8012, - #$8018, #$8019, #$801C, #$8021, #$8028, #$803F, #$803B, #$804A, - #$8046, #$8052, #$8058, #$805A, #$805F, #$8062, #$8068, #$8073, - #$8072, #$8070, #$8076, #$8079, #$807D, #$807F, #$8084, #$8086, - #$8085, #$809B, #$8093, #$809A, #$80AD, #$5190, #$80AC, #$80DB, - #$80E5, #$80D9, #$80DD, #$80C4, #$80DA, #$80D6, #$8109, #$80EF, - #$80F1, #$811B, #$8129, #$8123, #$812F, #$814B, - #$968B, #$8146, #$813E, #$8153, #$8151, #$80FC, #$8171, #$816E, - #$8165, #$8166, #$8174, #$8183, #$8188, #$818A, #$8180, #$8182, - #$81A0, #$8195, #$81A4, #$81A3, #$815F, #$8193, #$81A9, #$81B0, - #$81B5, #$81BE, #$81B8, #$81BD, #$81C0, #$81C2, #$81BA, #$81C9, - #$81CD, #$81D1, #$81D9, #$81D8, #$81C8, #$81DA, #$81DF, #$81E0, - #$81E7, #$81FA, #$81FB, #$81FE, #$8201, #$8202, #$8205, #$8207, - #$820A, #$820D, #$8210, #$8216, #$8229, #$822B, #$8238, #$8233, - #$8240, #$8259, #$8258, #$825D, #$825A, #$825F, #$8264, #$8262, - #$8268, #$826A, #$826B, #$822E, #$8271, #$8277, #$8278, #$827E, - #$828D, #$8292, #$82AB, #$829F, #$82BB, #$82AC, #$82E1, #$82E3, - #$82DF, #$82D2, #$82F4, #$82F3, #$82FA, #$8393, #$8303, #$82FB, - #$82F9, #$82DE, #$8306, #$82DC, #$8309, #$82D9, - #$8335, #$8334, #$8316, #$8332, #$8331, #$8340, #$8339, #$8350, - #$8345, #$832F, #$832B, #$8317, #$8318, #$8385, #$839A, #$83AA, - #$839F, #$83A2, #$8396, #$8323, #$838E, #$8387, #$838A, #$837C, - #$83B5, #$8373, #$8375, #$83A0, #$8389, #$83A8, #$83F4, #$8413, - #$83EB, #$83CE, #$83FD, #$8403, #$83D8, #$840B, #$83C1, #$83F7, - #$8407, #$83E0, #$83F2, #$840D, #$8422, #$8420, #$83BD, #$8438, - #$8506, #$83FB, #$846D, #$842A, #$843C, #$855A, #$8484, #$8477, - #$846B, #$84AD, #$846E, #$8482, #$8469, #$8446, #$842C, #$846F, - #$8479, #$8435, #$84CA, #$8462, #$84B9, #$84BF, #$849F, #$84D9, - #$84CD, #$84BB, #$84DA, #$84D0, #$84C1, #$84C6, #$84D6, #$84A1, - #$8521, #$84FF, #$84F4, #$8517, #$8518, #$852C, #$851F, #$8515, - #$8514, #$84FC, #$8540, #$8563, #$8558, #$8548, - #$8541, #$8602, #$854B, #$8555, #$8580, #$85A4, #$8588, #$8591, - #$858A, #$85A8, #$856D, #$8594, #$859B, #$85EA, #$8587, #$859C, - #$8577, #$857E, #$8590, #$85C9, #$85BA, #$85CF, #$85B9, #$85D0, - #$85D5, #$85DD, #$85E5, #$85DC, #$85F9, #$860A, #$8613, #$860B, - #$85FE, #$85FA, #$8606, #$8622, #$861A, #$8630, #$863F, #$864D, - #$4E55, #$8654, #$865F, #$8667, #$8671, #$8693, #$86A3, #$86A9, - #$86AA, #$868B, #$868C, #$86B6, #$86AF, #$86C4, #$86C6, #$86B0, - #$86C9, #$8823, #$86AB, #$86D4, #$86DE, #$86E9, #$86EC, #$86DF, - #$86DB, #$86EF, #$8712, #$8706, #$8708, #$8700, #$8703, #$86FB, - #$8711, #$8709, #$870D, #$86F9, #$870A, #$8734, #$873F, #$8737, - #$873B, #$8725, #$8729, #$871A, #$8760, #$875F, #$8778, #$874C, - #$874E, #$8774, #$8757, #$8768, #$876E, #$8759, - #$8753, #$8763, #$876A, #$8805, #$87A2, #$879F, #$8782, #$87AF, - #$87CB, #$87BD, #$87C0, #$87D0, #$96D6, #$87AB, #$87C4, #$87B3, - #$87C7, #$87C6, #$87BB, #$87EF, #$87F2, #$87E0, #$880F, #$880D, - #$87FE, #$87F6, #$87F7, #$880E, #$87D2, #$8811, #$8816, #$8815, - #$8822, #$8821, #$8831, #$8836, #$8839, #$8827, #$883B, #$8844, - #$8842, #$8852, #$8859, #$885E, #$8862, #$886B, #$8881, #$887E, - #$889E, #$8875, #$887D, #$88B5, #$8872, #$8882, #$8897, #$8892, - #$88AE, #$8899, #$88A2, #$888D, #$88A4, #$88B0, #$88BF, #$88B1, - #$88C3, #$88C4, #$88D4, #$88D8, #$88D9, #$88DD, #$88F9, #$8902, - #$88FC, #$88F4, #$88E8, #$88F2, #$8904, #$890C, #$890A, #$8913, - #$8943, #$891E, #$8925, #$892A, #$892B, #$8941, #$8944, #$893B, - #$8936, #$8938, #$894C, #$891D, #$8960, #$895E, - #$8966, #$8964, #$896D, #$896A, #$896F, #$8974, #$8977, #$897E, - #$8983, #$8988, #$898A, #$8993, #$8998, #$89A1, #$89A9, #$89A6, - #$89AC, #$89AF, #$89B2, #$89BA, #$89BD, #$89BF, #$89C0, #$89DA, - #$89DC, #$89DD, #$89E7, #$89F4, #$89F8, #$8A03, #$8A16, #$8A10, - #$8A0C, #$8A1B, #$8A1D, #$8A25, #$8A36, #$8A41, #$8A5B, #$8A52, - #$8A46, #$8A48, #$8A7C, #$8A6D, #$8A6C, #$8A62, #$8A85, #$8A82, - #$8A84, #$8AA8, #$8AA1, #$8A91, #$8AA5, #$8AA6, #$8A9A, #$8AA3, - #$8AC4, #$8ACD, #$8AC2, #$8ADA, #$8AEB, #$8AF3, #$8AE7, #$8AE4, - #$8AF1, #$8B14, #$8AE0, #$8AE2, #$8AF7, #$8ADE, #$8ADB, #$8B0C, - #$8B07, #$8B1A, #$8AE1, #$8B16, #$8B10, #$8B17, #$8B20, #$8B33, - #$97AB, #$8B26, #$8B2B, #$8B3E, #$8B28, #$8B41, #$8B4C, #$8B4F, - #$8B4E, #$8B49, #$8B56, #$8B5B, #$8B5A, #$8B6B, - #$8B5F, #$8B6C, #$8B6F, #$8B74, #$8B7D, #$8B80, #$8B8C, #$8B8E, - #$8B92, #$8B93, #$8B96, #$8B99, #$8B9A, #$8C3A, #$8C41, #$8C3F, - #$8C48, #$8C4C, #$8C4E, #$8C50, #$8C55, #$8C62, #$8C6C, #$8C78, - #$8C7A, #$8C82, #$8C89, #$8C85, #$8C8A, #$8C8D, #$8C8E, #$8C94, - #$8C7C, #$8C98, #$621D, #$8CAD, #$8CAA, #$8CBD, #$8CB2, #$8CB3, - #$8CAE, #$8CB6, #$8CC8, #$8CC1, #$8CE4, #$8CE3, #$8CDA, #$8CFD, - #$8CFA, #$8CFB, #$8D04, #$8D05, #$8D0A, #$8D07, #$8D0F, #$8D0D, - #$8D10, #$9F4E, #$8D13, #$8CCD, #$8D14, #$8D16, #$8D67, #$8D6D, - #$8D71, #$8D73, #$8D81, #$8D99, #$8DC2, #$8DBE, #$8DBA, #$8DCF, - #$8DDA, #$8DD6, #$8DCC, #$8DDB, #$8DCB, #$8DEA, #$8DEB, #$8DDF, - #$8DE3, #$8DFC, #$8E08, #$8E09, #$8DFF, #$8E1D, #$8E1E, #$8E10, - #$8E1F, #$8E42, #$8E35, #$8E30, #$8E34, #$8E4A, - #$8E47, #$8E49, #$8E4C, #$8E50, #$8E48, #$8E59, #$8E64, #$8E60, - #$8E2A, #$8E63, #$8E55, #$8E76, #$8E72, #$8E7C, #$8E81, #$8E87, - #$8E85, #$8E84, #$8E8B, #$8E8A, #$8E93, #$8E91, #$8E94, #$8E99, - #$8EAA, #$8EA1, #$8EAC, #$8EB0, #$8EC6, #$8EB1, #$8EBE, #$8EC5, - #$8EC8, #$8ECB, #$8EDB, #$8EE3, #$8EFC, #$8EFB, #$8EEB, #$8EFE, - #$8F0A, #$8F05, #$8F15, #$8F12, #$8F19, #$8F13, #$8F1C, #$8F1F, - #$8F1B, #$8F0C, #$8F26, #$8F33, #$8F3B, #$8F39, #$8F45, #$8F42, - #$8F3E, #$8F4C, #$8F49, #$8F46, #$8F4E, #$8F57, #$8F5C, #$8F62, - #$8F63, #$8F64, #$8F9C, #$8F9F, #$8FA3, #$8FAD, #$8FAF, #$8FB7, - #$8FDA, #$8FE5, #$8FE2, #$8FEA, #$8FEF, #$9087, #$8FF4, #$9005, - #$8FF9, #$8FFA, #$9011, #$9015, #$9021, #$900D, #$901E, #$9016, - #$900B, #$9027, #$9036, #$9035, #$9039, #$8FF8, - #$904F, #$9050, #$9051, #$9052, #$900E, #$9049, #$903E, #$9056, - #$9058, #$905E, #$9068, #$906F, #$9076, #$96A8, #$9072, #$9082, - #$907D, #$9081, #$9080, #$908A, #$9089, #$908F, #$90A8, #$90AF, - #$90B1, #$90B5, #$90E2, #$90E4, #$6248, #$90DB, #$9102, #$9112, - #$9119, #$9132, #$9130, #$914A, #$9156, #$9158, #$9163, #$9165, - #$9169, #$9173, #$9172, #$918B, #$9189, #$9182, #$91A2, #$91AB, - #$91AF, #$91AA, #$91B5, #$91B4, #$91BA, #$91C0, #$91C1, #$91C9, - #$91CB, #$91D0, #$91D6, #$91DF, #$91E1, #$91DB, #$91FC, #$91F5, - #$91F6, #$921E, #$91FF, #$9214, #$922C, #$9215, #$9211, #$925E, - #$9257, #$9245, #$9249, #$9264, #$9248, #$9295, #$923F, #$924B, - #$9250, #$929C, #$9296, #$9293, #$929B, #$925A, #$92CF, #$92B9, - #$92B7, #$92E9, #$930F, #$92FA, #$9344, #$932E, - #$9319, #$9322, #$931A, #$9323, #$933A, #$9335, #$933B, #$935C, - #$9360, #$937C, #$936E, #$9356, #$93B0, #$93AC, #$93AD, #$9394, - #$93B9, #$93D6, #$93D7, #$93E8, #$93E5, #$93D8, #$93C3, #$93DD, - #$93D0, #$93C8, #$93E4, #$941A, #$9414, #$9413, #$9403, #$9407, - #$9410, #$9436, #$942B, #$9435, #$9421, #$943A, #$9441, #$9452, - #$9444, #$945B, #$9460, #$9462, #$945E, #$946A, #$9229, #$9470, - #$9475, #$9477, #$947D, #$945A, #$947C, #$947E, #$9481, #$947F, - #$9582, #$9587, #$958A, #$9594, #$9596, #$9598, #$9599, #$95A0, - #$95A8, #$95A7, #$95AD, #$95BC, #$95BB, #$95B9, #$95BE, #$95CA, - #$6FF6, #$95C3, #$95CD, #$95CC, #$95D5, #$95D4, #$95D6, #$95DC, - #$95E1, #$95E5, #$95E2, #$9621, #$9628, #$962E, #$962F, #$9642, - #$964C, #$964F, #$964B, #$9677, #$965C, #$965E, - #$965D, #$965F, #$9666, #$9672, #$966C, #$968D, #$9698, #$9695, - #$9697, #$96AA, #$96A7, #$96B1, #$96B2, #$96B0, #$96B4, #$96B6, - #$96B8, #$96B9, #$96CE, #$96CB, #$96C9, #$96CD, #$894D, #$96DC, - #$970D, #$96D5, #$96F9, #$9704, #$9706, #$9708, #$9713, #$970E, - #$9711, #$970F, #$9716, #$9719, #$9724, #$972A, #$9730, #$9739, - #$973D, #$973E, #$9744, #$9746, #$9748, #$9742, #$9749, #$975C, - #$9760, #$9764, #$9766, #$9768, #$52D2, #$976B, #$9771, #$9779, - #$9785, #$977C, #$9781, #$977A, #$9786, #$978B, #$978F, #$9790, - #$979C, #$97A8, #$97A6, #$97A3, #$97B3, #$97B4, #$97C3, #$97C6, - #$97C8, #$97CB, #$97DC, #$97ED, #$9F4F, #$97F2, #$7ADF, #$97F6, - #$97F5, #$980F, #$980C, #$9838, #$9824, #$9821, #$9837, #$983D, - #$9846, #$984F, #$984B, #$986B, #$986F, #$9870, - #$9871, #$9874, #$9873, #$98AA, #$98AF, #$98B1, #$98B6, #$98C4, - #$98C3, #$98C6, #$98E9, #$98EB, #$9903, #$9909, #$9912, #$9914, - #$9918, #$9921, #$991D, #$991E, #$9924, #$9920, #$992C, #$992E, - #$993D, #$993E, #$9942, #$9949, #$9945, #$9950, #$994B, #$9951, - #$9952, #$994C, #$9955, #$9997, #$9998, #$99A5, #$99AD, #$99AE, - #$99BC, #$99DF, #$99DB, #$99DD, #$99D8, #$99D1, #$99ED, #$99EE, - #$99F1, #$99F2, #$99FB, #$99F8, #$9A01, #$9A0F, #$9A05, #$99E2, - #$9A19, #$9A2B, #$9A37, #$9A45, #$9A42, #$9A40, #$9A43, #$9A3E, - #$9A55, #$9A4D, #$9A5B, #$9A57, #$9A5F, #$9A62, #$9A65, #$9A64, - #$9A69, #$9A6B, #$9A6A, #$9AAD, #$9AB0, #$9ABC, #$9AC0, #$9ACF, - #$9AD1, #$9AD3, #$9AD4, #$9ADE, #$9ADF, #$9AE2, #$9AE3, #$9AE6, - #$9AEF, #$9AEB, #$9AEE, #$9AF4, #$9AF1, #$9AF7, - #$9AFB, #$9B06, #$9B18, #$9B1A, #$9B1F, #$9B22, #$9B23, #$9B25, - #$9B27, #$9B28, #$9B29, #$9B2A, #$9B2E, #$9B2F, #$9B32, #$9B44, - #$9B43, #$9B4F, #$9B4D, #$9B4E, #$9B51, #$9B58, #$9B74, #$9B93, - #$9B83, #$9B91, #$9B96, #$9B97, #$9B9F, #$9BA0, #$9BA8, #$9BB4, - #$9BC0, #$9BCA, #$9BB9, #$9BC6, #$9BCF, #$9BD1, #$9BD2, #$9BE3, - #$9BE2, #$9BE4, #$9BD4, #$9BE1, #$9C3A, #$9BF2, #$9BF1, #$9BF0, - #$9C15, #$9C14, #$9C09, #$9C13, #$9C0C, #$9C06, #$9C08, #$9C12, - #$9C0A, #$9C04, #$9C2E, #$9C1B, #$9C25, #$9C24, #$9C21, #$9C30, - #$9C47, #$9C32, #$9C46, #$9C3E, #$9C5A, #$9C60, #$9C67, #$9C76, - #$9C78, #$9CE7, #$9CEC, #$9CF0, #$9D09, #$9D08, #$9CEB, #$9D03, - #$9D06, #$9D2A, #$9D26, #$9DAF, #$9D23, #$9D1F, #$9D44, #$9D15, - #$9D12, #$9D41, #$9D3F, #$9D3E, #$9D46, #$9D48, - #$9D5D, #$9D5E, #$9D64, #$9D51, #$9D50, #$9D59, #$9D72, #$9D89, - #$9D87, #$9DAB, #$9D6F, #$9D7A, #$9D9A, #$9DA4, #$9DA9, #$9DB2, - #$9DC4, #$9DC1, #$9DBB, #$9DB8, #$9DBA, #$9DC6, #$9DCF, #$9DC2, - #$9DD9, #$9DD3, #$9DF8, #$9DE6, #$9DED, #$9DEF, #$9DFD, #$9E1A, - #$9E1B, #$9E1E, #$9E75, #$9E79, #$9E7D, #$9E81, #$9E88, #$9E8B, - #$9E8C, #$9E92, #$9E95, #$9E91, #$9E9D, #$9EA5, #$9EA9, #$9EB8, - #$9EAA, #$9EAD, #$9761, #$9ECC, #$9ECE, #$9ECF, #$9ED0, #$9ED4, - #$9EDC, #$9EDE, #$9EDD, #$9EE0, #$9EE5, #$9EE8, #$9EEF, #$9EF4, - #$9EF6, #$9EF7, #$9EF9, #$9EFB, #$9EFC, #$9EFD, #$9F07, #$9F08, - #$76B7, #$9F15, #$9F21, #$9F2C, #$9F3E, #$9F4A, #$9F52, #$9F54, - #$9F63, #$9F5F, #$9F60, #$9F61, #$9F66, #$9F67, #$9F6C, #$9F6A, - #$9F77, #$9F72, #$9F76, #$9F95, #$9F9C, #$9FA0, - #$582F, #$69C7, #$9059, #$7464, #$51DC, #$7199); - GBKE_1Map: array[0..6079] of TBuffChar = ( - #$4E02, #$4E04, #$4E05, #$4E06, #$4E0F, #$4E12, #$4E17, #$4E1F, - #$4E20, #$4E21, #$4E23, #$4E26, #$4E29, #$4E2E, #$4E2F, #$4E31, - #$4E33, #$4E35, #$4E37, #$4E3C, #$4E40, #$4E41, #$4E42, #$4E44, - #$4E46, #$4E4A, #$4E51, #$4E55, #$4E57, #$4E5A, #$4E5B, #$4E62, - #$4E63, #$4E64, #$4E65, #$4E67, #$4E68, #$4E6A, #$4E6B, #$4E6C, - #$4E6D, #$4E6E, #$4E6F, #$4E72, #$4E74, #$4E75, #$4E76, #$4E77, - #$4E78, #$4E79, #$4E7A, #$4E7B, #$4E7C, #$4E7D, #$4E7F, #$4E80, - #$4E81, #$4E82, #$4E83, #$4E84, #$4E85, #$4E87, #$4E8A, #$4E90, - #$4E96, #$4E97, #$4E99, #$4E9C, #$4E9D, #$4E9E, #$4EA3, #$4EAA, - #$4EAF, #$4EB0, #$4EB1, #$4EB4, #$4EB6, #$4EB7, #$4EB8, #$4EB9, - #$4EBC, #$4EBD, #$4EBE, #$4EC8, #$4ECC, #$4ECF, #$4ED0, #$4ED2, - #$4EDA, #$4EDB, #$4EDC, #$4EE0, #$4EE2, #$4EE6, #$4EE7, #$4EE9, - #$4EED, #$4EEE, #$4EEF, #$4EF1, #$4EF4, #$4EF8, #$4EF9, #$4EFA, - #$4EFC, #$4EFE, #$4F00, #$4F02, #$4F03, #$4F04, #$4F05, #$4F06, - #$4F07, #$4F08, #$4F0B, #$4F0C, #$4F12, #$4F13, #$4F14, #$4F15, - #$4F16, #$4F1C, #$4F1D, #$4F21, #$4F23, #$4F28, #$4F29, #$4F2C, - #$4F2D, #$4F2E, #$4F31, #$4F33, #$4F35, #$4F37, #$4F39, #$4F3B, - #$4F3E, #$4F3F, #$4F40, #$4F41, #$4F42, #$4F44, #$4F45, #$4F47, - #$4F48, #$4F49, #$4F4A, #$4F4B, #$4F4C, #$4F52, #$4F54, #$4F56, - #$4F61, #$4F62, #$4F66, #$4F68, #$4F6A, #$4F6B, #$4F6D, #$4F6E, - #$4F71, #$4F72, #$4F75, #$4F77, #$4F78, #$4F79, #$4F7A, #$4F7D, - #$4F80, #$4F81, #$4F82, #$4F85, #$4F86, #$4F87, #$4F8A, #$4F8C, - #$4F8E, #$4F90, #$4F92, #$4F93, #$4F95, #$4F96, #$4F98, #$4F99, - #$4F9A, #$4F9C, #$4F9E, #$4F9F, #$4FA1, #$4FA2, - #$4FA4, #$4FAB, #$4FAD, #$4FB0, #$4FB1, #$4FB2, #$4FB3, #$4FB4, - #$4FB6, #$4FB7, #$4FB8, #$4FB9, #$4FBA, #$4FBB, #$4FBC, #$4FBD, - #$4FBE, #$4FC0, #$4FC1, #$4FC2, #$4FC6, #$4FC7, #$4FC8, #$4FC9, - #$4FCB, #$4FCC, #$4FCD, #$4FD2, #$4FD3, #$4FD4, #$4FD5, #$4FD6, - #$4FD9, #$4FDB, #$4FE0, #$4FE2, #$4FE4, #$4FE5, #$4FE7, #$4FEB, - #$4FEC, #$4FF0, #$4FF2, #$4FF4, #$4FF5, #$4FF6, #$4FF7, #$4FF9, - #$4FFB, #$4FFC, #$4FFD, #$4FFF, #$5000, #$5001, #$5002, #$5003, - #$5004, #$5005, #$5006, #$5007, #$5008, #$5009, #$500A, #$500B, - #$500E, #$5010, #$5011, #$5013, #$5015, #$5016, #$5017, #$501B, - #$501D, #$501E, #$5020, #$5022, #$5023, #$5024, #$5027, #$502B, - #$502F, #$5030, #$5031, #$5032, #$5033, #$5034, #$5035, #$5036, - #$5037, #$5038, #$5039, #$503B, #$503D, #$503F, #$5040, #$5041, - #$5042, #$5044, #$5045, #$5046, #$5049, #$504A, #$504B, #$504D, - #$5050, #$5051, #$5052, #$5053, #$5054, #$5056, #$5057, #$5058, - #$5059, #$505B, #$505D, #$505E, #$505F, #$5060, #$5061, #$5062, - #$5063, #$5064, #$5066, #$5067, #$5068, #$5069, #$506A, #$506B, - #$506D, #$506E, #$506F, #$5070, #$5071, #$5072, #$5073, #$5074, - #$5075, #$5078, #$5079, #$507A, #$507C, #$507D, #$5081, #$5082, - #$5083, #$5084, #$5086, #$5087, #$5089, #$508A, #$508B, #$508C, - #$508E, #$508F, #$5090, #$5091, #$5092, #$5093, #$5094, #$5095, - #$5096, #$5097, #$5098, #$5099, #$509A, #$509B, #$509C, #$509D, - #$509E, #$509F, #$50A0, #$50A1, #$50A2, #$50A4, #$50A6, #$50AA, - #$50AB, #$50AD, #$50AE, #$50AF, #$50B0, #$50B1, #$50B3, #$50B4, - #$50B5, #$50B6, #$50B7, #$50B8, #$50B9, #$50BC, - #$50BD, #$50BE, #$50BF, #$50C0, #$50C1, #$50C2, #$50C3, #$50C4, - #$50C5, #$50C6, #$50C7, #$50C8, #$50C9, #$50CA, #$50CB, #$50CC, - #$50CD, #$50CE, #$50D0, #$50D1, #$50D2, #$50D3, #$50D4, #$50D5, - #$50D7, #$50D8, #$50D9, #$50DB, #$50DC, #$50DD, #$50DE, #$50DF, - #$50E0, #$50E1, #$50E2, #$50E3, #$50E4, #$50E5, #$50E8, #$50E9, - #$50EA, #$50EB, #$50EF, #$50F0, #$50F1, #$50F2, #$50F4, #$50F6, - #$50F7, #$50F8, #$50F9, #$50FA, #$50FC, #$50FD, #$50FE, #$50FF, - #$5100, #$5101, #$5102, #$5103, #$5104, #$5105, #$5108, #$5109, - #$510A, #$510C, #$510D, #$510E, #$510F, #$5110, #$5111, #$5113, - #$5114, #$5115, #$5116, #$5117, #$5118, #$5119, #$511A, #$511B, - #$511C, #$511D, #$511E, #$511F, #$5120, #$5122, #$5123, #$5124, - #$5125, #$5126, #$5127, #$5128, #$5129, #$512A, #$512B, #$512C, - #$512D, #$512E, #$512F, #$5130, #$5131, #$5132, #$5133, #$5134, - #$5135, #$5136, #$5137, #$5138, #$5139, #$513A, #$513B, #$513C, - #$513D, #$513E, #$5142, #$5147, #$514A, #$514C, #$514E, #$514F, - #$5150, #$5152, #$5153, #$5157, #$5158, #$5159, #$515B, #$515D, - #$515E, #$515F, #$5160, #$5161, #$5163, #$5164, #$5166, #$5167, - #$5169, #$516A, #$516F, #$5172, #$517A, #$517E, #$517F, #$5183, - #$5184, #$5186, #$5187, #$518A, #$518B, #$518E, #$518F, #$5190, - #$5191, #$5193, #$5194, #$5198, #$519A, #$519D, #$519E, #$519F, - #$51A1, #$51A3, #$51A6, #$51A7, #$51A8, #$51A9, #$51AA, #$51AD, - #$51AE, #$51B4, #$51B8, #$51B9, #$51BA, #$51BE, #$51BF, #$51C1, - #$51C2, #$51C3, #$51C5, #$51C8, #$51CA, #$51CD, #$51CE, #$51D0, - #$51D2, #$51D3, #$51D4, #$51D5, #$51D6, #$51D7, - #$51D8, #$51D9, #$51DA, #$51DC, #$51DE, #$51DF, #$51E2, #$51E3, - #$51E5, #$51E6, #$51E7, #$51E8, #$51E9, #$51EA, #$51EC, #$51EE, - #$51F1, #$51F2, #$51F4, #$51F7, #$51FE, #$5204, #$5205, #$5209, - #$520B, #$520C, #$520F, #$5210, #$5213, #$5214, #$5215, #$521C, - #$521E, #$521F, #$5221, #$5222, #$5223, #$5225, #$5226, #$5227, - #$522A, #$522C, #$522F, #$5231, #$5232, #$5234, #$5235, #$523C, - #$523E, #$5244, #$5245, #$5246, #$5247, #$5248, #$5249, #$524B, - #$524E, #$524F, #$5252, #$5253, #$5255, #$5257, #$5258, #$5259, - #$525A, #$525B, #$525D, #$525F, #$5260, #$5262, #$5263, #$5264, - #$5266, #$5268, #$526B, #$526C, #$526D, #$526E, #$5270, #$5271, - #$5273, #$5274, #$5275, #$5276, #$5277, #$5278, #$5279, #$527A, - #$527B, #$527C, #$527E, #$5280, #$5283, #$5284, #$5285, #$5286, - #$5287, #$5289, #$528A, #$528B, #$528C, #$528D, #$528E, #$528F, - #$5291, #$5292, #$5294, #$5295, #$5296, #$5297, #$5298, #$5299, - #$529A, #$529C, #$52A4, #$52A5, #$52A6, #$52A7, #$52AE, #$52AF, - #$52B0, #$52B4, #$52B5, #$52B6, #$52B7, #$52B8, #$52B9, #$52BA, - #$52BB, #$52BC, #$52BD, #$52C0, #$52C1, #$52C2, #$52C4, #$52C5, - #$52C6, #$52C8, #$52CA, #$52CC, #$52CD, #$52CE, #$52CF, #$52D1, - #$52D3, #$52D4, #$52D5, #$52D7, #$52D9, #$52DA, #$52DB, #$52DC, - #$52DD, #$52DE, #$52E0, #$52E1, #$52E2, #$52E3, #$52E5, #$52E6, - #$52E7, #$52E8, #$52E9, #$52EA, #$52EB, #$52EC, #$52ED, #$52EE, - #$52EF, #$52F1, #$52F2, #$52F3, #$52F4, #$52F5, #$52F6, #$52F7, - #$52F8, #$52FB, #$52FC, #$52FD, #$5301, #$5302, #$5303, #$5304, - #$5307, #$5309, #$530A, #$530B, #$530C, #$530E, - #$5311, #$5312, #$5313, #$5314, #$5318, #$531B, #$531C, #$531E, - #$531F, #$5322, #$5324, #$5325, #$5327, #$5328, #$5329, #$532B, - #$532C, #$532D, #$532F, #$5330, #$5331, #$5332, #$5333, #$5334, - #$5335, #$5336, #$5337, #$5338, #$533C, #$533D, #$5340, #$5342, - #$5344, #$5346, #$534B, #$534C, #$534D, #$5350, #$5354, #$5358, - #$5359, #$535B, #$535D, #$5365, #$5368, #$536A, #$536C, #$536D, - #$5372, #$5376, #$5379, #$537B, #$537C, #$537D, #$537E, #$5380, - #$5381, #$5383, #$5387, #$5388, #$538A, #$538E, #$538F, #$5390, - #$5391, #$5392, #$5393, #$5394, #$5396, #$5397, #$5399, #$539B, - #$539C, #$539E, #$53A0, #$53A1, #$53A4, #$53A7, #$53AA, #$53AB, - #$53AC, #$53AD, #$53AF, #$53B0, #$53B1, #$53B2, #$53B3, #$53B4, - #$53B5, #$53B7, #$53B8, #$53B9, #$53BA, #$53BC, #$53BD, #$53BE, - #$53C0, #$53C3, #$53C4, #$53C5, #$53C6, #$53C7, #$53CE, #$53CF, - #$53D0, #$53D2, #$53D3, #$53D5, #$53DA, #$53DC, #$53DD, #$53DE, - #$53E1, #$53E2, #$53E7, #$53F4, #$53FA, #$53FE, #$53FF, #$5400, - #$5402, #$5405, #$5407, #$540B, #$5414, #$5418, #$5419, #$541A, - #$541C, #$5422, #$5424, #$5425, #$542A, #$5430, #$5433, #$5436, - #$5437, #$543A, #$543D, #$543F, #$5441, #$5442, #$5444, #$5445, - #$5447, #$5449, #$544C, #$544D, #$544E, #$544F, #$5451, #$545A, - #$545D, #$545E, #$545F, #$5460, #$5461, #$5463, #$5465, #$5467, - #$5469, #$546A, #$546B, #$546C, #$546D, #$546E, #$546F, #$5470, - #$5474, #$5479, #$547A, #$547E, #$547F, #$5481, #$5483, #$5485, - #$5487, #$5488, #$5489, #$548A, #$548D, #$5491, #$5493, #$5497, - #$5498, #$549C, #$549E, #$549F, #$54A0, #$54A1, - #$54A2, #$54A5, #$54AE, #$54B0, #$54B2, #$54B5, #$54B6, #$54B7, - #$54B9, #$54BA, #$54BC, #$54BE, #$54C3, #$54C5, #$54CA, #$54CB, - #$54D6, #$54D8, #$54DB, #$54E0, #$54E1, #$54E2, #$54E3, #$54E4, - #$54EB, #$54EC, #$54EF, #$54F0, #$54F1, #$54F4, #$54F5, #$54F6, - #$54F7, #$54F8, #$54F9, #$54FB, #$54FE, #$5500, #$5502, #$5503, - #$5504, #$5505, #$5508, #$550A, #$550B, #$550C, #$550D, #$550E, - #$5512, #$5513, #$5515, #$5516, #$5517, #$5518, #$5519, #$551A, - #$551C, #$551D, #$551E, #$551F, #$5521, #$5525, #$5526, #$5528, - #$5529, #$552B, #$552D, #$5532, #$5534, #$5535, #$5536, #$5538, - #$5539, #$553A, #$553B, #$553D, #$5540, #$5542, #$5545, #$5547, - #$5548, #$554B, #$554C, #$554D, #$554E, #$554F, #$5551, #$5552, - #$5553, #$5554, #$5557, #$5558, #$5559, #$555A, #$555B, #$555D, - #$555E, #$555F, #$5560, #$5562, #$5563, #$5568, #$5569, #$556B, - #$556F, #$5570, #$5571, #$5572, #$5573, #$5574, #$5579, #$557A, - #$557D, #$557F, #$5585, #$5586, #$558C, #$558D, #$558E, #$5590, - #$5592, #$5593, #$5595, #$5596, #$5597, #$559A, #$559B, #$559E, - #$55A0, #$55A1, #$55A2, #$55A3, #$55A4, #$55A5, #$55A6, #$55A8, - #$55A9, #$55AA, #$55AB, #$55AC, #$55AD, #$55AE, #$55AF, #$55B0, - #$55B2, #$55B4, #$55B6, #$55B8, #$55BA, #$55BC, #$55BF, #$55C0, - #$55C1, #$55C2, #$55C3, #$55C6, #$55C7, #$55C8, #$55CA, #$55CB, - #$55CE, #$55CF, #$55D0, #$55D5, #$55D7, #$55D8, #$55D9, #$55DA, - #$55DB, #$55DE, #$55E0, #$55E2, #$55E7, #$55E9, #$55ED, #$55EE, - #$55F0, #$55F1, #$55F4, #$55F6, #$55F8, #$55F9, #$55FA, #$55FB, - #$55FC, #$55FF, #$5602, #$5603, #$5604, #$5605, - #$5606, #$5607, #$560A, #$560B, #$560D, #$5610, #$5611, #$5612, - #$5613, #$5614, #$5615, #$5616, #$5617, #$5619, #$561A, #$561C, - #$561D, #$5620, #$5621, #$5622, #$5625, #$5626, #$5628, #$5629, - #$562A, #$562B, #$562E, #$562F, #$5630, #$5633, #$5635, #$5637, - #$5638, #$563A, #$563C, #$563D, #$563E, #$5640, #$5641, #$5642, - #$5643, #$5644, #$5645, #$5646, #$5647, #$5648, #$5649, #$564A, - #$564B, #$564F, #$5650, #$5651, #$5652, #$5653, #$5655, #$5656, - #$565A, #$565B, #$565D, #$565E, #$565F, #$5660, #$5661, #$5663, - #$5665, #$5666, #$5667, #$566D, #$566E, #$566F, #$5670, #$5672, - #$5673, #$5674, #$5675, #$5677, #$5678, #$5679, #$567A, #$567D, - #$567E, #$567F, #$5680, #$5681, #$5682, #$5683, #$5684, #$5687, - #$5688, #$5689, #$568A, #$568B, #$568C, #$568D, #$5690, #$5691, - #$5692, #$5694, #$5695, #$5696, #$5697, #$5698, #$5699, #$569A, - #$569B, #$569C, #$569D, #$569E, #$569F, #$56A0, #$56A1, #$56A2, - #$56A4, #$56A5, #$56A6, #$56A7, #$56A8, #$56A9, #$56AA, #$56AB, - #$56AC, #$56AD, #$56AE, #$56B0, #$56B1, #$56B2, #$56B3, #$56B4, - #$56B5, #$56B6, #$56B8, #$56B9, #$56BA, #$56BB, #$56BD, #$56BE, - #$56BF, #$56C0, #$56C1, #$56C2, #$56C3, #$56C4, #$56C5, #$56C6, - #$56C7, #$56C8, #$56C9, #$56CB, #$56CC, #$56CD, #$56CE, #$56CF, - #$56D0, #$56D1, #$56D2, #$56D3, #$56D5, #$56D6, #$56D8, #$56D9, - #$56DC, #$56E3, #$56E5, #$56E6, #$56E7, #$56E8, #$56E9, #$56EA, - #$56EC, #$56EE, #$56EF, #$56F2, #$56F3, #$56F6, #$56F7, #$56F8, - #$56FB, #$56FC, #$5700, #$5701, #$5702, #$5705, #$5707, #$570B, - #$570C, #$570D, #$570E, #$570F, #$5710, #$5711, - #$5712, #$5713, #$5714, #$5715, #$5716, #$5717, #$5718, #$5719, - #$571A, #$571B, #$571D, #$571E, #$5720, #$5721, #$5722, #$5724, - #$5725, #$5726, #$5727, #$572B, #$5731, #$5732, #$5734, #$5735, - #$5736, #$5737, #$5738, #$573C, #$573D, #$573F, #$5741, #$5743, - #$5744, #$5745, #$5746, #$5748, #$5749, #$574B, #$5752, #$5753, - #$5754, #$5755, #$5756, #$5758, #$5759, #$5762, #$5763, #$5765, - #$5767, #$576C, #$576E, #$5770, #$5771, #$5772, #$5774, #$5775, - #$5778, #$5779, #$577A, #$577D, #$577E, #$577F, #$5780, #$5781, - #$5787, #$5788, #$5789, #$578A, #$578D, #$578E, #$578F, #$5790, - #$5791, #$5794, #$5795, #$5796, #$5797, #$5798, #$5799, #$579A, - #$579C, #$579D, #$579E, #$579F, #$57A5, #$57A8, #$57AA, #$57AC, - #$57AF, #$57B0, #$57B1, #$57B3, #$57B5, #$57B6, #$57B7, #$57B9, - #$57BA, #$57BB, #$57BC, #$57BD, #$57BE, #$57BF, #$57C0, #$57C1, - #$57C4, #$57C5, #$57C6, #$57C7, #$57C8, #$57C9, #$57CA, #$57CC, - #$57CD, #$57D0, #$57D1, #$57D3, #$57D6, #$57D7, #$57DB, #$57DC, - #$57DE, #$57E1, #$57E2, #$57E3, #$57E5, #$57E6, #$57E7, #$57E8, - #$57E9, #$57EA, #$57EB, #$57EC, #$57EE, #$57F0, #$57F1, #$57F2, - #$57F3, #$57F5, #$57F6, #$57F7, #$57FB, #$57FC, #$57FE, #$57FF, - #$5801, #$5803, #$5804, #$5805, #$5808, #$5809, #$580A, #$580C, - #$580E, #$580F, #$5810, #$5812, #$5813, #$5814, #$5816, #$5817, - #$5818, #$581A, #$581B, #$581C, #$581D, #$581F, #$5822, #$5823, - #$5825, #$5826, #$5827, #$5828, #$5829, #$582B, #$582C, #$582D, - #$582E, #$582F, #$5831, #$5832, #$5833, #$5834, #$5836, #$5837, - #$5838, #$5839, #$583A, #$583B, #$583C, #$583D, - #$583E, #$583F, #$5840, #$5841, #$5842, #$5843, #$5845, #$5846, - #$5847, #$5848, #$5849, #$584A, #$584B, #$584E, #$584F, #$5850, - #$5852, #$5853, #$5855, #$5856, #$5857, #$5859, #$585A, #$585B, - #$585C, #$585D, #$585F, #$5860, #$5861, #$5862, #$5863, #$5864, - #$5866, #$5867, #$5868, #$5869, #$586A, #$586D, #$586E, #$586F, - #$5870, #$5871, #$5872, #$5873, #$5874, #$5875, #$5876, #$5877, - #$5878, #$5879, #$587A, #$587B, #$587C, #$587D, #$587F, #$5882, - #$5884, #$5886, #$5887, #$5888, #$588A, #$588B, #$588C, #$588D, - #$588E, #$588F, #$5890, #$5891, #$5894, #$5895, #$5896, #$5897, - #$5898, #$589B, #$589C, #$589D, #$58A0, #$58A1, #$58A2, #$58A3, - #$58A4, #$58A5, #$58A6, #$58A7, #$58AA, #$58AB, #$58AC, #$58AD, - #$58AE, #$58AF, #$58B0, #$58B1, #$58B2, #$58B3, #$58B4, #$58B5, - #$58B6, #$58B7, #$58B8, #$58B9, #$58BA, #$58BB, #$58BD, #$58BE, - #$58BF, #$58C0, #$58C2, #$58C3, #$58C4, #$58C6, #$58C7, #$58C8, - #$58C9, #$58CA, #$58CB, #$58CC, #$58CD, #$58CE, #$58CF, #$58D0, - #$58D2, #$58D3, #$58D4, #$58D6, #$58D7, #$58D8, #$58D9, #$58DA, - #$58DB, #$58DC, #$58DD, #$58DE, #$58DF, #$58E0, #$58E1, #$58E2, - #$58E3, #$58E5, #$58E6, #$58E7, #$58E8, #$58E9, #$58EA, #$58ED, - #$58EF, #$58F1, #$58F2, #$58F4, #$58F5, #$58F7, #$58F8, #$58FA, - #$58FB, #$58FC, #$58FD, #$58FE, #$58FF, #$5900, #$5901, #$5903, - #$5905, #$5906, #$5908, #$5909, #$590A, #$590B, #$590C, #$590E, - #$5910, #$5911, #$5912, #$5913, #$5917, #$5918, #$591B, #$591D, - #$591E, #$5920, #$5921, #$5922, #$5923, #$5926, #$5928, #$592C, - #$5930, #$5932, #$5933, #$5935, #$5936, #$593B, - #$593D, #$593E, #$593F, #$5940, #$5943, #$5945, #$5946, #$594A, - #$594C, #$594D, #$5950, #$5952, #$5953, #$5959, #$595B, #$595C, - #$595D, #$595E, #$595F, #$5961, #$5963, #$5964, #$5966, #$5967, - #$5968, #$5969, #$596A, #$596B, #$596C, #$596D, #$596E, #$596F, - #$5970, #$5971, #$5972, #$5975, #$5977, #$597A, #$597B, #$597C, - #$597E, #$597F, #$5980, #$5985, #$5989, #$598B, #$598C, #$598E, - #$598F, #$5990, #$5991, #$5994, #$5995, #$5998, #$599A, #$599B, - #$599C, #$599D, #$599F, #$59A0, #$59A1, #$59A2, #$59A6, #$59A7, - #$59AC, #$59AD, #$59B0, #$59B1, #$59B3, #$59B4, #$59B5, #$59B6, - #$59B7, #$59B8, #$59BA, #$59BC, #$59BD, #$59BF, #$59C0, #$59C1, - #$59C2, #$59C3, #$59C4, #$59C5, #$59C7, #$59C8, #$59C9, #$59CC, - #$59CD, #$59CE, #$59CF, #$59D5, #$59D6, #$59D9, #$59DB, #$59DE, - #$59DF, #$59E0, #$59E1, #$59E2, #$59E4, #$59E6, #$59E7, #$59E9, - #$59EA, #$59EB, #$59ED, #$59EE, #$59EF, #$59F0, #$59F1, #$59F2, - #$59F3, #$59F4, #$59F5, #$59F6, #$59F7, #$59F8, #$59FA, #$59FC, - #$59FD, #$59FE, #$5A00, #$5A02, #$5A0A, #$5A0B, #$5A0D, #$5A0E, - #$5A0F, #$5A10, #$5A12, #$5A14, #$5A15, #$5A16, #$5A17, #$5A19, - #$5A1A, #$5A1B, #$5A1D, #$5A1E, #$5A21, #$5A22, #$5A24, #$5A26, - #$5A27, #$5A28, #$5A2A, #$5A2B, #$5A2C, #$5A2D, #$5A2E, #$5A2F, - #$5A30, #$5A33, #$5A35, #$5A37, #$5A38, #$5A39, #$5A3A, #$5A3B, - #$5A3D, #$5A3E, #$5A3F, #$5A41, #$5A42, #$5A43, #$5A44, #$5A45, - #$5A47, #$5A48, #$5A4B, #$5A4C, #$5A4D, #$5A4E, #$5A4F, #$5A50, - #$5A51, #$5A52, #$5A53, #$5A54, #$5A56, #$5A57, #$5A58, #$5A59, - #$5A5B, #$5A5C, #$5A5D, #$5A5E, #$5A5F, #$5A60, - #$5A61, #$5A63, #$5A64, #$5A65, #$5A66, #$5A68, #$5A69, #$5A6B, - #$5A6C, #$5A6D, #$5A6E, #$5A6F, #$5A70, #$5A71, #$5A72, #$5A73, - #$5A78, #$5A79, #$5A7B, #$5A7C, #$5A7D, #$5A7E, #$5A80, #$5A81, - #$5A82, #$5A83, #$5A84, #$5A85, #$5A86, #$5A87, #$5A88, #$5A89, - #$5A8A, #$5A8B, #$5A8C, #$5A8D, #$5A8E, #$5A8F, #$5A90, #$5A91, - #$5A93, #$5A94, #$5A95, #$5A96, #$5A97, #$5A98, #$5A99, #$5A9C, - #$5A9D, #$5A9E, #$5A9F, #$5AA0, #$5AA1, #$5AA2, #$5AA3, #$5AA4, - #$5AA5, #$5AA6, #$5AA7, #$5AA8, #$5AA9, #$5AAB, #$5AAC, #$5AAD, - #$5AAE, #$5AAF, #$5AB0, #$5AB1, #$5AB4, #$5AB6, #$5AB7, #$5AB9, - #$5ABA, #$5ABB, #$5ABC, #$5ABD, #$5ABF, #$5AC0, #$5AC3, #$5AC4, - #$5AC5, #$5AC6, #$5AC7, #$5AC8, #$5ACA, #$5ACB, #$5ACD, #$5ACE, - #$5ACF, #$5AD0, #$5AD1, #$5AD3, #$5AD5, #$5AD7, #$5AD9, #$5ADA, - #$5ADB, #$5ADD, #$5ADE, #$5ADF, #$5AE2, #$5AE4, #$5AE5, #$5AE7, - #$5AE8, #$5AEA, #$5AEC, #$5AED, #$5AEE, #$5AEF, #$5AF0, #$5AF2, - #$5AF3, #$5AF4, #$5AF5, #$5AF6, #$5AF7, #$5AF8, #$5AF9, #$5AFA, - #$5AFB, #$5AFC, #$5AFD, #$5AFE, #$5AFF, #$5B00, #$5B01, #$5B02, - #$5B03, #$5B04, #$5B05, #$5B06, #$5B07, #$5B08, #$5B0A, #$5B0B, - #$5B0C, #$5B0D, #$5B0E, #$5B0F, #$5B10, #$5B11, #$5B12, #$5B13, - #$5B14, #$5B15, #$5B18, #$5B19, #$5B1A, #$5B1B, #$5B1C, #$5B1D, - #$5B1E, #$5B1F, #$5B20, #$5B21, #$5B22, #$5B23, #$5B24, #$5B25, - #$5B26, #$5B27, #$5B28, #$5B29, #$5B2A, #$5B2B, #$5B2C, #$5B2D, - #$5B2E, #$5B2F, #$5B30, #$5B31, #$5B33, #$5B35, #$5B36, #$5B38, - #$5B39, #$5B3A, #$5B3B, #$5B3C, #$5B3D, #$5B3E, #$5B3F, #$5B41, - #$5B42, #$5B43, #$5B44, #$5B45, #$5B46, #$5B47, - #$5B48, #$5B49, #$5B4A, #$5B4B, #$5B4C, #$5B4D, #$5B4E, #$5B4F, - #$5B52, #$5B56, #$5B5E, #$5B60, #$5B61, #$5B67, #$5B68, #$5B6B, - #$5B6D, #$5B6E, #$5B6F, #$5B72, #$5B74, #$5B76, #$5B77, #$5B78, - #$5B79, #$5B7B, #$5B7C, #$5B7E, #$5B7F, #$5B82, #$5B86, #$5B8A, - #$5B8D, #$5B8E, #$5B90, #$5B91, #$5B92, #$5B94, #$5B96, #$5B9F, - #$5BA7, #$5BA8, #$5BA9, #$5BAC, #$5BAD, #$5BAE, #$5BAF, #$5BB1, - #$5BB2, #$5BB7, #$5BBA, #$5BBB, #$5BBC, #$5BC0, #$5BC1, #$5BC3, - #$5BC8, #$5BC9, #$5BCA, #$5BCB, #$5BCD, #$5BCE, #$5BCF, #$5BD1, - #$5BD4, #$5BD5, #$5BD6, #$5BD7, #$5BD8, #$5BD9, #$5BDA, #$5BDB, - #$5BDC, #$5BE0, #$5BE2, #$5BE3, #$5BE6, #$5BE7, #$5BE9, #$5BEA, - #$5BEB, #$5BEC, #$5BED, #$5BEF, #$5BF1, #$5BF2, #$5BF3, #$5BF4, - #$5BF5, #$5BF6, #$5BF7, #$5BFD, #$5BFE, #$5C00, #$5C02, #$5C03, - #$5C05, #$5C07, #$5C08, #$5C0B, #$5C0C, #$5C0D, #$5C0E, #$5C10, - #$5C12, #$5C13, #$5C17, #$5C19, #$5C1B, #$5C1E, #$5C1F, #$5C20, - #$5C21, #$5C23, #$5C26, #$5C28, #$5C29, #$5C2A, #$5C2B, #$5C2D, - #$5C2E, #$5C2F, #$5C30, #$5C32, #$5C33, #$5C35, #$5C36, #$5C37, - #$5C43, #$5C44, #$5C46, #$5C47, #$5C4C, #$5C4D, #$5C52, #$5C53, - #$5C54, #$5C56, #$5C57, #$5C58, #$5C5A, #$5C5B, #$5C5C, #$5C5D, - #$5C5F, #$5C62, #$5C64, #$5C67, #$5C68, #$5C69, #$5C6A, #$5C6B, - #$5C6C, #$5C6D, #$5C70, #$5C72, #$5C73, #$5C74, #$5C75, #$5C76, - #$5C77, #$5C78, #$5C7B, #$5C7C, #$5C7D, #$5C7E, #$5C80, #$5C83, - #$5C84, #$5C85, #$5C86, #$5C87, #$5C89, #$5C8A, #$5C8B, #$5C8E, - #$5C8F, #$5C92, #$5C93, #$5C95, #$5C9D, #$5C9E, #$5C9F, #$5CA0, - #$5CA1, #$5CA4, #$5CA5, #$5CA6, #$5CA7, #$5CA8, - #$5CAA, #$5CAE, #$5CAF, #$5CB0, #$5CB2, #$5CB4, #$5CB6, #$5CB9, - #$5CBA, #$5CBB, #$5CBC, #$5CBE, #$5CC0, #$5CC2, #$5CC3, #$5CC5, - #$5CC6, #$5CC7, #$5CC8, #$5CC9, #$5CCA, #$5CCC, #$5CCD, #$5CCE, - #$5CCF, #$5CD0, #$5CD1, #$5CD3, #$5CD4, #$5CD5, #$5CD6, #$5CD7, - #$5CD8, #$5CDA, #$5CDB, #$5CDC, #$5CDD, #$5CDE, #$5CDF, #$5CE0, - #$5CE2, #$5CE3, #$5CE7, #$5CE9, #$5CEB, #$5CEC, #$5CEE, #$5CEF, - #$5CF1, #$5CF2, #$5CF3, #$5CF4, #$5CF5, #$5CF6, #$5CF7, #$5CF8, - #$5CF9, #$5CFA, #$5CFC, #$5CFD, #$5CFE, #$5CFF, #$5D00, #$5D01, - #$5D04, #$5D05, #$5D08, #$5D09, #$5D0A, #$5D0B, #$5D0C, #$5D0D, - #$5D0F, #$5D10, #$5D11, #$5D12, #$5D13, #$5D15, #$5D17, #$5D18, - #$5D19, #$5D1A, #$5D1C, #$5D1D, #$5D1F, #$5D20, #$5D21, #$5D22, - #$5D23, #$5D25, #$5D28, #$5D2A, #$5D2B, #$5D2C, #$5D2F, #$5D30, - #$5D31, #$5D32, #$5D33, #$5D35, #$5D36, #$5D37, #$5D38, #$5D39, - #$5D3A, #$5D3B, #$5D3C, #$5D3F, #$5D40, #$5D41, #$5D42, #$5D43, - #$5D44, #$5D45, #$5D46, #$5D48, #$5D49, #$5D4D, #$5D4E, #$5D4F, - #$5D50, #$5D51, #$5D52, #$5D53, #$5D54, #$5D55, #$5D56, #$5D57, - #$5D59, #$5D5A, #$5D5C, #$5D5E, #$5D5F, #$5D60, #$5D61, #$5D62, - #$5D63, #$5D64, #$5D65, #$5D66, #$5D67, #$5D68, #$5D6A, #$5D6D, - #$5D6E, #$5D70, #$5D71, #$5D72, #$5D73, #$5D75, #$5D76, #$5D77, - #$5D78, #$5D79, #$5D7A, #$5D7B, #$5D7C, #$5D7D, #$5D7E, #$5D7F, - #$5D80, #$5D81, #$5D83, #$5D84, #$5D85, #$5D86, #$5D87, #$5D88, - #$5D89, #$5D8A, #$5D8B, #$5D8C, #$5D8D, #$5D8E, #$5D8F, #$5D90, - #$5D91, #$5D92, #$5D93, #$5D94, #$5D95, #$5D96, #$5D97, #$5D98, - #$5D9A, #$5D9B, #$5D9C, #$5D9E, #$5D9F, #$5DA0, - #$5DA1, #$5DA2, #$5DA3, #$5DA4, #$5DA5, #$5DA6, #$5DA7, #$5DA8, - #$5DA9, #$5DAA, #$5DAB, #$5DAC, #$5DAD, #$5DAE, #$5DAF, #$5DB0, - #$5DB1, #$5DB2, #$5DB3, #$5DB4, #$5DB5, #$5DB6, #$5DB8, #$5DB9, - #$5DBA, #$5DBB, #$5DBC, #$5DBD, #$5DBE, #$5DBF, #$5DC0, #$5DC1, - #$5DC2, #$5DC3, #$5DC4, #$5DC6, #$5DC7, #$5DC8, #$5DC9, #$5DCA, - #$5DCB, #$5DCC, #$5DCE, #$5DCF, #$5DD0, #$5DD1, #$5DD2, #$5DD3, - #$5DD4, #$5DD5, #$5DD6, #$5DD7, #$5DD8, #$5DD9, #$5DDA, #$5DDC, - #$5DDF, #$5DE0, #$5DE3, #$5DE4, #$5DEA, #$5DEC, #$5DED, #$5DF0, - #$5DF5, #$5DF6, #$5DF8, #$5DF9, #$5DFA, #$5DFB, #$5DFC, #$5DFF, - #$5E00, #$5E04, #$5E07, #$5E09, #$5E0A, #$5E0B, #$5E0D, #$5E0E, - #$5E12, #$5E13, #$5E17, #$5E1E, #$5E1F, #$5E20, #$5E21, #$5E22, - #$5E23, #$5E24, #$5E25, #$5E28, #$5E29, #$5E2A, #$5E2B, #$5E2C, - #$5E2F, #$5E30, #$5E32, #$5E33, #$5E34, #$5E35, #$5E36, #$5E39, - #$5E3A, #$5E3E, #$5E3F, #$5E40, #$5E41, #$5E43, #$5E46, #$5E47, - #$5E48, #$5E49, #$5E4A, #$5E4B, #$5E4D, #$5E4E, #$5E4F, #$5E50, - #$5E51, #$5E52, #$5E53, #$5E56, #$5E57, #$5E58, #$5E59, #$5E5A, - #$5E5C, #$5E5D, #$5E5F, #$5E60, #$5E63, #$5E64, #$5E65, #$5E66, - #$5E67, #$5E68, #$5E69, #$5E6A, #$5E6B, #$5E6C, #$5E6D, #$5E6E, - #$5E6F, #$5E70, #$5E71, #$5E75, #$5E77, #$5E79, #$5E7E, #$5E81, - #$5E82, #$5E83, #$5E85, #$5E88, #$5E89, #$5E8C, #$5E8D, #$5E8E, - #$5E92, #$5E98, #$5E9B, #$5E9D, #$5EA1, #$5EA2, #$5EA3, #$5EA4, - #$5EA8, #$5EA9, #$5EAA, #$5EAB, #$5EAC, #$5EAE, #$5EAF, #$5EB0, - #$5EB1, #$5EB2, #$5EB4, #$5EBA, #$5EBB, #$5EBC, #$5EBD, #$5EBF, - #$5EC0, #$5EC1, #$5EC2, #$5EC3, #$5EC4, #$5EC5, - #$5EC6, #$5EC7, #$5EC8, #$5ECB, #$5ECC, #$5ECD, #$5ECE, #$5ECF, - #$5ED0, #$5ED4, #$5ED5, #$5ED7, #$5ED8, #$5ED9, #$5EDA, #$5EDC, - #$5EDD, #$5EDE, #$5EDF, #$5EE0, #$5EE1, #$5EE2, #$5EE3, #$5EE4, - #$5EE5, #$5EE6, #$5EE7, #$5EE9, #$5EEB, #$5EEC, #$5EED, #$5EEE, - #$5EEF, #$5EF0, #$5EF1, #$5EF2, #$5EF3, #$5EF5, #$5EF8, #$5EF9, - #$5EFB, #$5EFC, #$5EFD, #$5F05, #$5F06, #$5F07, #$5F09, #$5F0C, - #$5F0D, #$5F0E, #$5F10, #$5F12, #$5F14, #$5F16, #$5F19, #$5F1A, - #$5F1C, #$5F1D, #$5F1E, #$5F21, #$5F22, #$5F23, #$5F24, #$5F28, - #$5F2B, #$5F2C, #$5F2E, #$5F30, #$5F32, #$5F33, #$5F34, #$5F35, - #$5F36, #$5F37, #$5F38, #$5F3B, #$5F3D, #$5F3E, #$5F3F, #$5F41, - #$5F42, #$5F43, #$5F44, #$5F45, #$5F46, #$5F47, #$5F48, #$5F49, - #$5F4A, #$5F4B, #$5F4C, #$5F4D, #$5F4E, #$5F4F, #$5F51, #$5F54, - #$5F59, #$5F5A, #$5F5B, #$5F5C, #$5F5E, #$5F5F, #$5F60, #$5F63, - #$5F65, #$5F67, #$5F68, #$5F6B, #$5F6E, #$5F6F, #$5F72, #$5F74, - #$5F75, #$5F76, #$5F78, #$5F7A, #$5F7D, #$5F7E, #$5F7F, #$5F83, - #$5F86, #$5F8D, #$5F8E, #$5F8F, #$5F91, #$5F93, #$5F94, #$5F96, - #$5F9A, #$5F9B, #$5F9D, #$5F9E, #$5F9F, #$5FA0, #$5FA2, #$5FA3, - #$5FA4, #$5FA5, #$5FA6, #$5FA7, #$5FA9, #$5FAB, #$5FAC, #$5FAF, - #$5FB0, #$5FB1, #$5FB2, #$5FB3, #$5FB4, #$5FB6, #$5FB8, #$5FB9, - #$5FBA, #$5FBB, #$5FBE, #$5FBF, #$5FC0, #$5FC1, #$5FC2, #$5FC7, - #$5FC8, #$5FCA, #$5FCB, #$5FCE, #$5FD3, #$5FD4, #$5FD5, #$5FDA, - #$5FDB, #$5FDC, #$5FDE, #$5FDF, #$5FE2, #$5FE3, #$5FE5, #$5FE6, - #$5FE8, #$5FE9, #$5FEC, #$5FEF, #$5FF0, #$5FF2, #$5FF3, #$5FF4, - #$5FF6, #$5FF7, #$5FF9, #$5FFA, #$5FFC, #$6007, - #$6008, #$6009, #$600B, #$600C, #$6010, #$6011, #$6013, #$6017, - #$6018, #$601A, #$601E, #$601F, #$6022, #$6023, #$6024, #$602C, - #$602D, #$602E, #$6030, #$6031, #$6032, #$6033, #$6034, #$6036, - #$6037, #$6038, #$6039, #$603A, #$603D, #$603E, #$6040, #$6044, - #$6045, #$6046, #$6047, #$6048, #$6049, #$604A, #$604C, #$604E, - #$604F, #$6051, #$6053, #$6054, #$6056, #$6057, #$6058, #$605B, - #$605C, #$605E, #$605F, #$6060, #$6061, #$6065, #$6066, #$606E, - #$6071, #$6072, #$6074, #$6075, #$6077, #$607E, #$6080, #$6081, - #$6082, #$6085, #$6086, #$6087, #$6088, #$608A, #$608B, #$608E, - #$608F, #$6090, #$6091, #$6093, #$6095, #$6097, #$6098, #$6099, - #$609C, #$609E, #$60A1, #$60A2, #$60A4, #$60A5, #$60A7, #$60A9, - #$60AA, #$60AE, #$60B0, #$60B3, #$60B5, #$60B6, #$60B7, #$60B9, - #$60BA, #$60BD, #$60BE, #$60BF, #$60C0, #$60C1, #$60C2, #$60C3, - #$60C4, #$60C7, #$60C8, #$60C9, #$60CC, #$60CD, #$60CE, #$60CF, - #$60D0, #$60D2, #$60D3, #$60D4, #$60D6, #$60D7, #$60D9, #$60DB, - #$60DE, #$60E1, #$60E2, #$60E3, #$60E4, #$60E5, #$60EA, #$60F1, - #$60F2, #$60F5, #$60F7, #$60F8, #$60FB, #$60FC, #$60FD, #$60FE, - #$60FF, #$6102, #$6103, #$6104, #$6105, #$6107, #$610A, #$610B, - #$610C, #$6110, #$6111, #$6112, #$6113, #$6114, #$6116, #$6117, - #$6118, #$6119, #$611B, #$611C, #$611D, #$611E, #$6121, #$6122, - #$6125, #$6128, #$6129, #$612A, #$612C, #$612D, #$612E, #$612F, - #$6130, #$6131, #$6132, #$6133, #$6134, #$6135, #$6136, #$6137, - #$6138, #$6139, #$613A, #$613B, #$613C, #$613D, #$613E, #$6140, - #$6141, #$6142, #$6143, #$6144, #$6145, #$6146, - #$6147, #$6149, #$614B, #$614D, #$614F, #$6150, #$6152, #$6153, - #$6154, #$6156, #$6157, #$6158, #$6159, #$615A, #$615B, #$615C, - #$615E, #$615F, #$6160, #$6161, #$6163, #$6164, #$6165, #$6166, - #$6169, #$616A, #$616B, #$616C, #$616D, #$616E, #$616F, #$6171, - #$6172, #$6173, #$6174, #$6176, #$6178, #$6179, #$617A, #$617B, - #$617C, #$617D, #$617E, #$617F, #$6180, #$6181, #$6182, #$6183, - #$6184, #$6185, #$6186, #$6187, #$6188, #$6189, #$618A, #$618C, - #$618D, #$618F, #$6190, #$6191, #$6192, #$6193, #$6195, #$6196, - #$6197, #$6198, #$6199, #$619A, #$619B, #$619C, #$619E, #$619F, - #$61A0, #$61A1, #$61A2, #$61A3, #$61A4, #$61A5, #$61A6, #$61AA, - #$61AB, #$61AD, #$61AE, #$61AF, #$61B0, #$61B1, #$61B2, #$61B3, - #$61B4, #$61B5, #$61B6, #$61B8, #$61B9, #$61BA, #$61BB, #$61BC, - #$61BD, #$61BF, #$61C0, #$61C1, #$61C3, #$61C4, #$61C5, #$61C6, - #$61C7, #$61C9, #$61CC, #$61CD, #$61CE, #$61CF, #$61D0, #$61D3, - #$61D5, #$61D6, #$61D7, #$61D8, #$61D9, #$61DA, #$61DB, #$61DC, - #$61DD, #$61DE, #$61DF, #$61E0, #$61E1, #$61E2, #$61E3, #$61E4, - #$61E5, #$61E7, #$61E8, #$61E9, #$61EA, #$61EB, #$61EC, #$61ED, - #$61EE, #$61EF, #$61F0, #$61F1, #$61F2, #$61F3, #$61F4, #$61F6, - #$61F7, #$61F8, #$61F9, #$61FA, #$61FB, #$61FC, #$61FD, #$61FE, - #$6200, #$6201, #$6202, #$6203, #$6204, #$6205, #$6207, #$6209, - #$6213, #$6214, #$6219, #$621C, #$621D, #$621E, #$6220, #$6223, - #$6226, #$6227, #$6228, #$6229, #$622B, #$622D, #$622F, #$6230, - #$6231, #$6232, #$6235, #$6236, #$6238, #$6239, #$623A, #$623B, - #$623C, #$6242, #$6244, #$6245, #$6246, #$624A, - #$624F, #$6250, #$6255, #$6256, #$6257, #$6259, #$625A, #$625C, - #$625D, #$625E, #$625F, #$6260, #$6261, #$6262, #$6264, #$6265, - #$6268, #$6271, #$6272, #$6274, #$6275, #$6277, #$6278, #$627A, - #$627B, #$627D, #$6281, #$6282, #$6283, #$6285, #$6286, #$6287, - #$6288, #$628B, #$628C, #$628D, #$628E, #$628F, #$6290, #$6294, - #$6299, #$629C, #$629D, #$629E, #$62A3, #$62A6, #$62A7, #$62A9, - #$62AA, #$62AD, #$62AE, #$62AF, #$62B0, #$62B2, #$62B3, #$62B4, - #$62B6, #$62B7, #$62B8, #$62BA, #$62BE, #$62C0, #$62C1, #$62C3, - #$62CB, #$62CF, #$62D1, #$62D5, #$62DD, #$62DE, #$62E0, #$62E1, - #$62E4, #$62EA, #$62EB, #$62F0, #$62F2, #$62F5, #$62F8, #$62F9, - #$62FA, #$62FB, #$6300, #$6303, #$6304, #$6305, #$6306, #$630A, - #$630B, #$630C, #$630D, #$630F, #$6310, #$6312, #$6313, #$6314, - #$6315, #$6317, #$6318, #$6319, #$631C, #$6326, #$6327, #$6329, - #$632C, #$632D, #$632E, #$6330, #$6331, #$6333, #$6334, #$6335, - #$6336, #$6337, #$6338, #$633B, #$633C, #$633E, #$633F, #$6340, - #$6341, #$6344, #$6347, #$6348, #$634A, #$6351, #$6352, #$6353, - #$6354, #$6356, #$6357, #$6358, #$6359, #$635A, #$635B, #$635C, - #$635D, #$6360, #$6364, #$6365, #$6366, #$6368, #$636A, #$636B, - #$636C, #$636F, #$6370, #$6372, #$6373, #$6374, #$6375, #$6378, - #$6379, #$637C, #$637D, #$637E, #$637F, #$6381, #$6383, #$6384, - #$6385, #$6386, #$638B, #$638D, #$6391, #$6393, #$6394, #$6395, - #$6397, #$6399, #$639A, #$639B, #$639C, #$639D, #$639E, #$639F, - #$63A1, #$63A4, #$63A6, #$63AB, #$63AF, #$63B1, #$63B2, #$63B5, - #$63B6, #$63B9, #$63BB, #$63BD, #$63BF, #$63C0, - #$63C1, #$63C2, #$63C3, #$63C5, #$63C7, #$63C8, #$63CA, #$63CB, - #$63CC, #$63D1, #$63D3, #$63D4, #$63D5, #$63D7, #$63D8, #$63D9, - #$63DA, #$63DB, #$63DC, #$63DD, #$63DF, #$63E2, #$63E4, #$63E5, - #$63E6, #$63E7, #$63E8, #$63EB, #$63EC, #$63EE, #$63EF, #$63F0, - #$63F1, #$63F3, #$63F5, #$63F7, #$63F9, #$63FA, #$63FB, #$63FC, - #$63FE, #$6403, #$6404, #$6406, #$6407, #$6408, #$6409, #$640A, - #$640D, #$640E, #$6411, #$6412, #$6415, #$6416, #$6417, #$6418, - #$6419, #$641A, #$641D, #$641F, #$6422, #$6423, #$6424, #$6425, - #$6427, #$6428, #$6429, #$642B, #$642E, #$642F, #$6430, #$6431, - #$6432, #$6433, #$6435, #$6436, #$6437, #$6438, #$6439, #$643B, - #$643C, #$643E, #$6440, #$6442, #$6443, #$6449, #$644B, #$644C, - #$644D, #$644E, #$644F, #$6450, #$6451, #$6453, #$6455, #$6456, - #$6457, #$6459, #$645A, #$645B, #$645C, #$645D, #$645F, #$6460, - #$6461, #$6462, #$6463, #$6464, #$6465, #$6466, #$6468, #$646A, - #$646B, #$646C, #$646E, #$646F, #$6470, #$6471, #$6472, #$6473, - #$6474, #$6475, #$6476, #$6477, #$647B, #$647C, #$647D, #$647E, - #$647F, #$6480, #$6481, #$6483, #$6486, #$6488, #$6489, #$648A, - #$648B, #$648C, #$648D, #$648E, #$648F, #$6490, #$6493, #$6494, - #$6497, #$6498, #$649A, #$649B, #$649C, #$649D, #$649F, #$64A0, - #$64A1, #$64A2, #$64A3, #$64A5, #$64A6, #$64A7, #$64A8, #$64AA, - #$64AB, #$64AF, #$64B1, #$64B2, #$64B3, #$64B4, #$64B6, #$64B9, - #$64BB, #$64BD, #$64BE, #$64BF, #$64C1, #$64C3, #$64C4, #$64C6, - #$64C7, #$64C8, #$64C9, #$64CA, #$64CB, #$64CC, #$64CF, #$64D1, - #$64D3, #$64D4, #$64D5, #$64D6, #$64D9, #$64DA, - #$64DB, #$64DC, #$64DD, #$64DF, #$64E0, #$64E1, #$64E3, #$64E5, - #$64E7, #$64E8, #$64E9, #$64EA, #$64EB, #$64EC, #$64ED, #$64EE, - #$64EF, #$64F0, #$64F1, #$64F2, #$64F3, #$64F4, #$64F5, #$64F6, - #$64F7, #$64F8, #$64F9, #$64FA, #$64FB, #$64FC, #$64FD, #$64FE, - #$64FF, #$6501, #$6502, #$6503, #$6504, #$6505, #$6506, #$6507, - #$6508, #$650A, #$650B, #$650C, #$650D, #$650E, #$650F, #$6510, - #$6511, #$6513, #$6514, #$6515, #$6516, #$6517, #$6519, #$651A, - #$651B, #$651C, #$651D, #$651E, #$651F, #$6520, #$6521, #$6522, - #$6523, #$6524, #$6526, #$6527, #$6528, #$6529, #$652A, #$652C, - #$652D, #$6530, #$6531, #$6532, #$6533, #$6537, #$653A, #$653C, - #$653D, #$6540, #$6541, #$6542, #$6543, #$6544, #$6546, #$6547, - #$654A, #$654B, #$654D, #$654E, #$6550, #$6552, #$6553, #$6554, - #$6557, #$6558, #$655A, #$655C, #$655F, #$6560, #$6561, #$6564, - #$6565, #$6567, #$6568, #$6569, #$656A, #$656D, #$656E, #$656F, - #$6571, #$6573, #$6575, #$6576, #$6578, #$6579, #$657A, #$657B, - #$657C, #$657D, #$657E, #$657F, #$6580, #$6581, #$6582, #$6583, - #$6584, #$6585, #$6586, #$6588, #$6589, #$658A, #$658D, #$658E, - #$658F, #$6592, #$6594, #$6595, #$6596, #$6598, #$659A, #$659D, - #$659E, #$65A0, #$65A2, #$65A3, #$65A6, #$65A8, #$65AA, #$65AC, - #$65AE, #$65B1, #$65B2, #$65B3, #$65B4, #$65B5, #$65B6, #$65B7, - #$65B8, #$65BA, #$65BB, #$65BE, #$65BF, #$65C0, #$65C2, #$65C7, - #$65C8, #$65C9, #$65CA, #$65CD, #$65D0, #$65D1, #$65D3, #$65D4, - #$65D5, #$65D8, #$65D9, #$65DA, #$65DB, #$65DC, #$65DD, #$65DE, - #$65DF, #$65E1, #$65E3, #$65E4, #$65EA, #$65EB, - #$65F2, #$65F3, #$65F4, #$65F5, #$65F8, #$65F9, #$65FB, #$65FC, - #$65FD, #$65FE, #$65FF, #$6601, #$6604, #$6605, #$6607, #$6608, - #$6609, #$660B, #$660D, #$6610, #$6611, #$6612, #$6616, #$6617, - #$6618, #$661A, #$661B, #$661C, #$661E, #$6621, #$6622, #$6623, - #$6624, #$6626, #$6629, #$662A, #$662B, #$662C, #$662E, #$6630, - #$6632, #$6633, #$6637, #$6638, #$6639, #$663A, #$663B, #$663D, - #$663F, #$6640, #$6642, #$6644, #$6645, #$6646, #$6647, #$6648, - #$6649, #$664A, #$664D, #$664E, #$6650, #$6651, #$6658, #$6659, - #$665B, #$665C, #$665D, #$665E, #$6660, #$6662, #$6663, #$6665, - #$6667, #$6669, #$666A, #$666B, #$666C, #$666D, #$6671, #$6672, - #$6673, #$6675, #$6678, #$6679, #$667B, #$667C, #$667D, #$667F, - #$6680, #$6681, #$6683, #$6685, #$6686, #$6688, #$6689, #$668A, - #$668B, #$668D, #$668E, #$668F, #$6690, #$6692, #$6693, #$6694, - #$6695, #$6698, #$6699, #$669A, #$669B, #$669C, #$669E, #$669F, - #$66A0, #$66A1, #$66A2, #$66A3, #$66A4, #$66A5, #$66A6, #$66A9, - #$66AA, #$66AB, #$66AC, #$66AD, #$66AF, #$66B0, #$66B1, #$66B2, - #$66B3, #$66B5, #$66B6, #$66B7, #$66B8, #$66BA, #$66BB, #$66BC, - #$66BD, #$66BF, #$66C0, #$66C1, #$66C2, #$66C3, #$66C4, #$66C5, - #$66C6, #$66C7, #$66C8, #$66C9, #$66CA, #$66CB, #$66CC, #$66CD, - #$66CE, #$66CF, #$66D0, #$66D1, #$66D2, #$66D3, #$66D4, #$66D5, - #$66D6, #$66D7, #$66D8, #$66DA, #$66DE, #$66DF, #$66E0, #$66E1, - #$66E2, #$66E3, #$66E4, #$66E5, #$66E7, #$66E8, #$66EA, #$66EB, - #$66EC, #$66ED, #$66EE, #$66EF, #$66F1, #$66F5, #$66F6, #$66F8, - #$66FA, #$66FB, #$66FD, #$6701, #$6702, #$6703, - #$6704, #$6705, #$6706, #$6707, #$670C, #$670E, #$670F, #$6711, - #$6712, #$6713, #$6716, #$6718, #$6719, #$671A, #$671C, #$671E, - #$6720, #$6721, #$6722, #$6723, #$6724, #$6725, #$6727, #$6729, - #$672E, #$6730, #$6732, #$6733, #$6736, #$6737, #$6738, #$6739, - #$673B, #$673C, #$673E, #$673F, #$6741, #$6744, #$6745, #$6747, - #$674A, #$674B, #$674D, #$6752, #$6754, #$6755, #$6757, #$6758, - #$6759, #$675A, #$675B, #$675D, #$6762, #$6763, #$6764, #$6766, - #$6767, #$676B, #$676C, #$676E, #$6771, #$6774, #$6776, #$6778, - #$6779, #$677A, #$677B, #$677D, #$6780, #$6782, #$6783, #$6785, - #$6786, #$6788, #$678A, #$678C, #$678D, #$678E, #$678F, #$6791, - #$6792, #$6793, #$6794, #$6796, #$6799, #$679B, #$679F, #$67A0, - #$67A1, #$67A4, #$67A6, #$67A9, #$67AC, #$67AE, #$67B1, #$67B2, - #$67B4, #$67B9, #$67BA, #$67BB, #$67BC, #$67BD, #$67BE, #$67BF, - #$67C0, #$67C2, #$67C5, #$67C6, #$67C7, #$67C8, #$67C9, #$67CA, - #$67CB, #$67CC, #$67CD, #$67CE, #$67D5, #$67D6, #$67D7, #$67DB, - #$67DF, #$67E1, #$67E3, #$67E4, #$67E6, #$67E7, #$67E8, #$67EA, - #$67EB, #$67ED, #$67EE, #$67F2, #$67F5, #$67F6, #$67F7, #$67F8, - #$67F9, #$67FA, #$67FB, #$67FC, #$67FE, #$6801, #$6802, #$6803, - #$6804, #$6806, #$680D, #$6810, #$6812, #$6814, #$6815, #$6818, - #$6819, #$681A, #$681B, #$681C, #$681E, #$681F, #$6820, #$6822, - #$6823, #$6824, #$6825, #$6826, #$6827, #$6828, #$682B, #$682C, - #$682D, #$682E, #$682F, #$6830, #$6831, #$6834, #$6835, #$6836, - #$683A, #$683B, #$683F, #$6847, #$684B, #$684D, #$684F, #$6852, - #$6856, #$6857, #$6858, #$6859, #$685A, #$685B, - #$685C, #$685D, #$685E, #$685F, #$686A, #$686C, #$686D, #$686E, - #$686F, #$6870, #$6871, #$6872, #$6873, #$6875, #$6878, #$6879, - #$687A, #$687B, #$687C, #$687D, #$687E, #$687F, #$6880, #$6882, - #$6884, #$6887, #$6888, #$6889, #$688A, #$688B, #$688C, #$688D, - #$688E, #$6890, #$6891, #$6892, #$6894, #$6895, #$6896, #$6898, - #$6899, #$689A, #$689B, #$689C, #$689D, #$689E, #$689F, #$68A0, - #$68A1, #$68A3, #$68A4, #$68A5, #$68A9, #$68AA, #$68AB, #$68AC, - #$68AE, #$68B1, #$68B2, #$68B4, #$68B6, #$68B7, #$68B8, #$68B9, - #$68BA, #$68BB, #$68BC, #$68BD, #$68BE, #$68BF, #$68C1, #$68C3, - #$68C4, #$68C5, #$68C6, #$68C7, #$68C8, #$68CA, #$68CC, #$68CE, - #$68CF, #$68D0, #$68D1, #$68D3, #$68D4, #$68D6, #$68D7, #$68D9, - #$68DB, #$68DC, #$68DD, #$68DE, #$68DF, #$68E1, #$68E2, #$68E4, - #$68E5, #$68E6, #$68E7, #$68E8, #$68E9, #$68EA, #$68EB, #$68EC, - #$68ED, #$68EF, #$68F2, #$68F3, #$68F4, #$68F6, #$68F7, #$68F8, - #$68FB, #$68FD, #$68FE, #$68FF, #$6900, #$6902, #$6903, #$6904, - #$6906, #$6907, #$6908, #$6909, #$690A, #$690C, #$690F, #$6911, - #$6913, #$6914, #$6915, #$6916, #$6917, #$6918, #$6919, #$691A, - #$691B, #$691C, #$691D, #$691E, #$6921, #$6922, #$6923, #$6925, - #$6926, #$6927, #$6928, #$6929, #$692A, #$692B, #$692C, #$692E, - #$692F, #$6931, #$6932, #$6933, #$6935, #$6936, #$6937, #$6938, - #$693A, #$693B, #$693C, #$693E, #$6940, #$6941, #$6943, #$6944, - #$6945, #$6946, #$6947, #$6948, #$6949, #$694A, #$694B, #$694C, - #$694D, #$694E, #$694F, #$6950, #$6951, #$6952, #$6953, #$6955, - #$6956, #$6958, #$6959, #$695B, #$695C, #$695F, - #$6961, #$6962, #$6964, #$6965, #$6967, #$6968, #$6969, #$696A, - #$696C, #$696D, #$696F, #$6970, #$6972, #$6973, #$6974, #$6975, - #$6976, #$697A, #$697B, #$697D, #$697E, #$697F, #$6981, #$6983, - #$6985, #$698A, #$698B, #$698C, #$698E, #$698F, #$6990, #$6991, - #$6992, #$6993, #$6996, #$6997, #$6999, #$699A, #$699D, #$699E, - #$699F, #$69A0, #$69A1, #$69A2, #$69A3, #$69A4, #$69A5, #$69A6, - #$69A9, #$69AA, #$69AC, #$69AE, #$69AF, #$69B0, #$69B2, #$69B3, - #$69B5, #$69B6, #$69B8, #$69B9, #$69BA, #$69BC, #$69BD, #$69BE, - #$69BF, #$69C0, #$69C2, #$69C3, #$69C4, #$69C5, #$69C6, #$69C7, - #$69C8, #$69C9, #$69CB, #$69CD, #$69CF, #$69D1, #$69D2, #$69D3, - #$69D5, #$69D6, #$69D7, #$69D8, #$69D9, #$69DA, #$69DC, #$69DD, - #$69DE, #$69E1, #$69E2, #$69E3, #$69E4, #$69E5, #$69E6, #$69E7, - #$69E8, #$69E9, #$69EA, #$69EB, #$69EC, #$69EE, #$69EF, #$69F0, - #$69F1, #$69F3, #$69F4, #$69F5, #$69F6, #$69F7, #$69F8, #$69F9, - #$69FA, #$69FB, #$69FC, #$69FE, #$6A00, #$6A01, #$6A02, #$6A03, - #$6A04, #$6A05, #$6A06, #$6A07, #$6A08, #$6A09, #$6A0B, #$6A0C, - #$6A0D, #$6A0E, #$6A0F, #$6A10, #$6A11, #$6A12, #$6A13, #$6A14, - #$6A15, #$6A16, #$6A19, #$6A1A, #$6A1B, #$6A1C, #$6A1D, #$6A1E, - #$6A20, #$6A22, #$6A23, #$6A24, #$6A25, #$6A26, #$6A27, #$6A29, - #$6A2B, #$6A2C, #$6A2D, #$6A2E, #$6A30, #$6A32, #$6A33, #$6A34, - #$6A36, #$6A37, #$6A38, #$6A39, #$6A3A, #$6A3B, #$6A3C, #$6A3F, - #$6A40, #$6A41, #$6A42, #$6A43, #$6A45, #$6A46, #$6A48, #$6A49, - #$6A4A, #$6A4B, #$6A4C, #$6A4D, #$6A4E, #$6A4F, #$6A51, #$6A52, - #$6A53, #$6A54, #$6A55, #$6A56, #$6A57, #$6A5A, - #$6A5C, #$6A5D, #$6A5E, #$6A5F, #$6A60, #$6A62, #$6A63, #$6A64, - #$6A66, #$6A67, #$6A68, #$6A69, #$6A6A, #$6A6B, #$6A6C, #$6A6D, - #$6A6E, #$6A6F, #$6A70, #$6A72, #$6A73, #$6A74, #$6A75, #$6A76, - #$6A77, #$6A78, #$6A7A, #$6A7B, #$6A7D, #$6A7E, #$6A7F, #$6A81, - #$6A82, #$6A83, #$6A85, #$6A86, #$6A87, #$6A88, #$6A89, #$6A8A, - #$6A8B, #$6A8C, #$6A8D, #$6A8F, #$6A92, #$6A93, #$6A94, #$6A95, - #$6A96, #$6A98, #$6A99, #$6A9A, #$6A9B, #$6A9C, #$6A9D, #$6A9E, - #$6A9F, #$6AA1, #$6AA2, #$6AA3, #$6AA4, #$6AA5, #$6AA6, #$6AA7, - #$6AA8, #$6AAA, #$6AAD, #$6AAE, #$6AAF, #$6AB0, #$6AB1, #$6AB2, - #$6AB3, #$6AB4, #$6AB5, #$6AB6, #$6AB7, #$6AB8, #$6AB9, #$6ABA, - #$6ABB, #$6ABC, #$6ABD, #$6ABE, #$6ABF, #$6AC0, #$6AC1, #$6AC2, - #$6AC3, #$6AC4, #$6AC5, #$6AC6, #$6AC7, #$6AC8, #$6AC9, #$6ACA, - #$6ACB, #$6ACC, #$6ACD, #$6ACE, #$6ACF, #$6AD0, #$6AD1, #$6AD2, - #$6AD3, #$6AD4, #$6AD5, #$6AD6, #$6AD7, #$6AD8, #$6AD9, #$6ADA, - #$6ADB, #$6ADC, #$6ADD, #$6ADE, #$6ADF, #$6AE0, #$6AE1, #$6AE2, - #$6AE3, #$6AE4, #$6AE5, #$6AE6, #$6AE7, #$6AE8, #$6AE9, #$6AEA, - #$6AEB, #$6AEC, #$6AED, #$6AEE, #$6AEF, #$6AF0, #$6AF1, #$6AF2, - #$6AF3, #$6AF4, #$6AF5, #$6AF6, #$6AF7, #$6AF8, #$6AF9, #$6AFA, - #$6AFB, #$6AFC, #$6AFD, #$6AFE, #$6AFF, #$6B00, #$6B01, #$6B02, - #$6B03, #$6B04, #$6B05, #$6B06, #$6B07, #$6B08, #$6B09, #$6B0A, - #$6B0B, #$6B0C, #$6B0D, #$6B0E, #$6B0F, #$6B10, #$6B11, #$6B12, - #$6B13, #$6B14, #$6B15, #$6B16, #$6B17, #$6B18, #$6B19, #$6B1A, - #$6B1B, #$6B1C, #$6B1D, #$6B1E, #$6B1F, #$6B25, #$6B26, #$6B28, - #$6B29, #$6B2A, #$6B2B, #$6B2C, #$6B2D, #$6B2E, - #$6B2F, #$6B30, #$6B31, #$6B33, #$6B34, #$6B35, #$6B36, #$6B38, - #$6B3B, #$6B3C, #$6B3D, #$6B3F, #$6B40, #$6B41, #$6B42, #$6B44, - #$6B45, #$6B48, #$6B4A, #$6B4B, #$6B4D, #$6B4E, #$6B4F, #$6B50, - #$6B51, #$6B52, #$6B53, #$6B54, #$6B55, #$6B56, #$6B57, #$6B58, - #$6B5A, #$6B5B, #$6B5C, #$6B5D, #$6B5E, #$6B5F, #$6B60, #$6B61, - #$6B68, #$6B69, #$6B6B, #$6B6C, #$6B6D, #$6B6E, #$6B6F, #$6B70, - #$6B71, #$6B72, #$6B73, #$6B74, #$6B75, #$6B76, #$6B77, #$6B78, - #$6B7A, #$6B7D, #$6B7E, #$6B7F, #$6B80, #$6B85, #$6B88, #$6B8C, - #$6B8E, #$6B8F, #$6B90, #$6B91, #$6B94, #$6B95, #$6B97, #$6B98, - #$6B99, #$6B9C, #$6B9D, #$6B9E, #$6B9F, #$6BA0, #$6BA2, #$6BA3, - #$6BA4, #$6BA5, #$6BA6, #$6BA7, #$6BA8, #$6BA9, #$6BAB, #$6BAC, - #$6BAD, #$6BAE, #$6BAF, #$6BB0, #$6BB1, #$6BB2, #$6BB6, #$6BB8, - #$6BB9, #$6BBA, #$6BBB, #$6BBC, #$6BBD, #$6BBE, #$6BC0, #$6BC3, - #$6BC4, #$6BC6, #$6BC7, #$6BC8, #$6BC9, #$6BCA, #$6BCC, #$6BCE, - #$6BD0, #$6BD1, #$6BD8, #$6BDA, #$6BDC, #$6BDD, #$6BDE, #$6BDF, - #$6BE0, #$6BE2, #$6BE3, #$6BE4, #$6BE5, #$6BE6, #$6BE7, #$6BE8, - #$6BE9, #$6BEC, #$6BED, #$6BEE, #$6BF0, #$6BF1, #$6BF2, #$6BF4, - #$6BF6, #$6BF7, #$6BF8, #$6BFA, #$6BFB, #$6BFC, #$6BFE, #$6BFF, - #$6C00, #$6C01, #$6C02, #$6C03, #$6C04, #$6C08, #$6C09, #$6C0A, - #$6C0B, #$6C0C, #$6C0E, #$6C12, #$6C17, #$6C1C, #$6C1D, #$6C1E, - #$6C20, #$6C23, #$6C25, #$6C2B, #$6C2C, #$6C2D, #$6C31, #$6C33, - #$6C36, #$6C37, #$6C39, #$6C3A, #$6C3B, #$6C3C, #$6C3E, #$6C3F, - #$6C43, #$6C44, #$6C45, #$6C48, #$6C4B, #$6C4C, #$6C4D, #$6C4E, - #$6C4F, #$6C51, #$6C52, #$6C53, #$6C56, #$6C58, - #$6C59, #$6C5A, #$6C62, #$6C63, #$6C65, #$6C66, #$6C67, #$6C6B, - #$6C6C, #$6C6D, #$6C6E, #$6C6F, #$6C71, #$6C73, #$6C75, #$6C77, - #$6C78, #$6C7A, #$6C7B, #$6C7C, #$6C7F, #$6C80, #$6C84, #$6C87, - #$6C8A, #$6C8B, #$6C8D, #$6C8E, #$6C91, #$6C92, #$6C95, #$6C96, - #$6C97, #$6C98, #$6C9A, #$6C9C, #$6C9D, #$6C9E, #$6CA0, #$6CA2, - #$6CA8, #$6CAC, #$6CAF, #$6CB0, #$6CB4, #$6CB5, #$6CB6, #$6CB7, - #$6CBA, #$6CC0, #$6CC1, #$6CC2, #$6CC3, #$6CC6, #$6CC7, #$6CC8, - #$6CCB, #$6CCD, #$6CCE, #$6CCF, #$6CD1, #$6CD2, #$6CD8, #$6CD9, - #$6CDA, #$6CDC, #$6CDD, #$6CDF, #$6CE4, #$6CE6, #$6CE7, #$6CE9, - #$6CEC, #$6CED, #$6CF2, #$6CF4, #$6CF9, #$6CFF, #$6D00, #$6D02, - #$6D03, #$6D05, #$6D06, #$6D08, #$6D09, #$6D0A, #$6D0D, #$6D0F, - #$6D10, #$6D11, #$6D13, #$6D14, #$6D15, #$6D16, #$6D18, #$6D1C, - #$6D1D, #$6D1F, #$6D20, #$6D21, #$6D22, #$6D23, #$6D24, #$6D26, - #$6D28, #$6D29, #$6D2C, #$6D2D, #$6D2F, #$6D30, #$6D34, #$6D36, - #$6D37, #$6D38, #$6D3A, #$6D3F, #$6D40, #$6D42, #$6D44, #$6D49, - #$6D4C, #$6D50, #$6D55, #$6D56, #$6D57, #$6D58, #$6D5B, #$6D5D, - #$6D5F, #$6D61, #$6D62, #$6D64, #$6D65, #$6D67, #$6D68, #$6D6B, - #$6D6C, #$6D6D, #$6D70, #$6D71, #$6D72, #$6D73, #$6D75, #$6D76, - #$6D79, #$6D7A, #$6D7B, #$6D7D, #$6D7E, #$6D7F, #$6D80, #$6D81, - #$6D83, #$6D84, #$6D86, #$6D87, #$6D8A, #$6D8B, #$6D8D, #$6D8F, - #$6D90, #$6D92, #$6D96, #$6D97, #$6D98, #$6D99, #$6D9A, #$6D9C, - #$6DA2, #$6DA5, #$6DAC, #$6DAD, #$6DB0, #$6DB1, #$6DB3, #$6DB4, - #$6DB6, #$6DB7, #$6DB9, #$6DBA, #$6DBB, #$6DBC, #$6DBD, #$6DBE, - #$6DC1, #$6DC2, #$6DC3, #$6DC8, #$6DC9, #$6DCA, - #$6DCD, #$6DCE, #$6DCF, #$6DD0, #$6DD2, #$6DD3, #$6DD4, #$6DD5, - #$6DD7, #$6DDA, #$6DDB, #$6DDC, #$6DDF, #$6DE2, #$6DE3, #$6DE5, - #$6DE7, #$6DE8, #$6DE9, #$6DEA, #$6DED, #$6DEF, #$6DF0, #$6DF2, - #$6DF4, #$6DF5, #$6DF6, #$6DF8, #$6DFA, #$6DFD, #$6DFE, #$6DFF, - #$6E00, #$6E01, #$6E02, #$6E03, #$6E04, #$6E06, #$6E07, #$6E08, - #$6E09, #$6E0B, #$6E0F, #$6E12, #$6E13, #$6E15, #$6E18, #$6E19, - #$6E1B, #$6E1C, #$6E1E, #$6E1F, #$6E22, #$6E26, #$6E27, #$6E28, - #$6E2A, #$6E2C, #$6E2E, #$6E30, #$6E31, #$6E33, #$6E35, #$6E36, - #$6E37, #$6E39, #$6E3B, #$6E3C, #$6E3D, #$6E3E, #$6E3F, #$6E40, - #$6E41, #$6E42, #$6E45, #$6E46, #$6E47, #$6E48, #$6E49, #$6E4A, - #$6E4B, #$6E4C, #$6E4F, #$6E50, #$6E51, #$6E52, #$6E55, #$6E57, - #$6E59, #$6E5A, #$6E5C, #$6E5D, #$6E5E, #$6E60, #$6E61, #$6E62, - #$6E63, #$6E64, #$6E65, #$6E66, #$6E67, #$6E68, #$6E69, #$6E6A, - #$6E6C, #$6E6D, #$6E6F, #$6E70, #$6E71, #$6E72, #$6E73, #$6E74, - #$6E75, #$6E76, #$6E77, #$6E78, #$6E79, #$6E7A, #$6E7B, #$6E7C, - #$6E7D, #$6E80, #$6E81, #$6E82, #$6E84, #$6E87, #$6E88, #$6E8A, - #$6E8B, #$6E8C, #$6E8D, #$6E8E, #$6E91, #$6E92, #$6E93, #$6E94, - #$6E95, #$6E96, #$6E97, #$6E99, #$6E9A, #$6E9B, #$6E9D, #$6E9E, - #$6EA0, #$6EA1, #$6EA3, #$6EA4, #$6EA6, #$6EA8, #$6EA9, #$6EAB, - #$6EAC, #$6EAD, #$6EAE, #$6EB0, #$6EB3, #$6EB5, #$6EB8, #$6EB9, - #$6EBC, #$6EBE, #$6EBF, #$6EC0, #$6EC3, #$6EC4, #$6EC5, #$6EC6, - #$6EC8, #$6EC9, #$6ECA, #$6ECC, #$6ECD, #$6ECE, #$6ED0, #$6ED2, - #$6ED6, #$6ED8, #$6ED9, #$6EDB, #$6EDC, #$6EDD, #$6EE3, #$6EE7, - #$6EEA, #$6EEB, #$6EEC, #$6EED, #$6EEE, #$6EEF, - #$6EF0, #$6EF1, #$6EF2, #$6EF3, #$6EF5, #$6EF6, #$6EF7, #$6EF8, - #$6EFA, #$6EFB, #$6EFC, #$6EFD, #$6EFE, #$6EFF, #$6F00, #$6F01, - #$6F03, #$6F04, #$6F05, #$6F07, #$6F08, #$6F0A, #$6F0B, #$6F0C, - #$6F0D, #$6F0E, #$6F10, #$6F11, #$6F12, #$6F16, #$6F17, #$6F18, - #$6F19, #$6F1A, #$6F1B, #$6F1C, #$6F1D, #$6F1E, #$6F1F, #$6F21, - #$6F22, #$6F23, #$6F25, #$6F26, #$6F27, #$6F28, #$6F2C, #$6F2E, - #$6F30, #$6F32, #$6F34, #$6F35, #$6F37, #$6F38, #$6F39, #$6F3A, - #$6F3B, #$6F3C, #$6F3D, #$6F3F, #$6F40, #$6F41, #$6F42, #$6F43, - #$6F44, #$6F45, #$6F48, #$6F49, #$6F4A, #$6F4C, #$6F4E, #$6F4F, - #$6F50, #$6F51, #$6F52, #$6F53, #$6F54, #$6F55, #$6F56, #$6F57, - #$6F59, #$6F5A, #$6F5B, #$6F5D, #$6F5F, #$6F60, #$6F61, #$6F63, - #$6F64, #$6F65, #$6F67, #$6F68, #$6F69, #$6F6A, #$6F6B, #$6F6C, - #$6F6F, #$6F70, #$6F71, #$6F73, #$6F75, #$6F76, #$6F77, #$6F79, - #$6F7B, #$6F7D, #$6F7E, #$6F7F, #$6F80, #$6F81, #$6F82, #$6F83, - #$6F85, #$6F86, #$6F87, #$6F8A, #$6F8B, #$6F8F, #$6F90, #$6F91, - #$6F92, #$6F93, #$6F94, #$6F95, #$6F96, #$6F97, #$6F98, #$6F99, - #$6F9A, #$6F9B, #$6F9D, #$6F9E, #$6F9F, #$6FA0, #$6FA2, #$6FA3, - #$6FA4, #$6FA5, #$6FA6, #$6FA8, #$6FA9, #$6FAA, #$6FAB, #$6FAC, - #$6FAD, #$6FAE, #$6FAF, #$6FB0, #$6FB1, #$6FB2, #$6FB4, #$6FB5, - #$6FB7, #$6FB8, #$6FBA, #$6FBB, #$6FBC, #$6FBD, #$6FBE, #$6FBF, - #$6FC1, #$6FC3, #$6FC4, #$6FC5, #$6FC6, #$6FC7, #$6FC8, #$6FCA, - #$6FCB, #$6FCC, #$6FCD, #$6FCE, #$6FCF, #$6FD0, #$6FD3, #$6FD4, - #$6FD5, #$6FD6, #$6FD7, #$6FD8, #$6FD9, #$6FDA, #$6FDB, #$6FDC, - #$6FDD, #$6FDF, #$6FE2, #$6FE3, #$6FE4, #$6FE5, - #$6FE6, #$6FE7, #$6FE8, #$6FE9, #$6FEA, #$6FEB, #$6FEC, #$6FED, - #$6FF0, #$6FF1, #$6FF2, #$6FF3, #$6FF4, #$6FF5, #$6FF6, #$6FF7, - #$6FF8, #$6FF9, #$6FFA, #$6FFB, #$6FFC, #$6FFD, #$6FFE, #$6FFF, - #$7000, #$7001, #$7002, #$7003, #$7004, #$7005, #$7006, #$7007, - #$7008, #$7009, #$700A, #$700B, #$700C, #$700D, #$700E, #$700F, - #$7010, #$7012, #$7013, #$7014, #$7015, #$7016, #$7017, #$7018, - #$7019, #$701C, #$701D, #$701E, #$701F, #$7020, #$7021, #$7022, - #$7024, #$7025, #$7026, #$7027, #$7028, #$7029, #$702A, #$702B, - #$702C, #$702D, #$702E, #$702F, #$7030, #$7031, #$7032, #$7033, - #$7034, #$7036, #$7037, #$7038, #$703A, #$703B, #$703C, #$703D, - #$703E, #$703F, #$7040, #$7041, #$7042, #$7043, #$7044, #$7045, - #$7046, #$7047, #$7048, #$7049, #$704A, #$704B, #$704D, #$704E, - #$7050, #$7051, #$7052, #$7053, #$7054, #$7055, #$7056, #$7057, - #$7058, #$7059, #$705A, #$705B, #$705C, #$705D, #$705F, #$7060, - #$7061, #$7062, #$7063, #$7064, #$7065, #$7066, #$7067, #$7068, - #$7069, #$706A, #$706E, #$7071, #$7072, #$7073, #$7074, #$7077, - #$7079, #$707A, #$707B, #$707D, #$7081, #$7082, #$7083, #$7084, - #$7086, #$7087, #$7088, #$708B, #$708C, #$708D, #$708F, #$7090, - #$7091, #$7093, #$7097, #$7098, #$709A, #$709B, #$709E, #$709F, - #$70A0, #$70A1, #$70A2, #$70A3, #$70A4, #$70A5, #$70A6, #$70A7, - #$70A8, #$70A9, #$70AA, #$70B0, #$70B2, #$70B4, #$70B5, #$70B6, - #$70BA, #$70BE, #$70BF, #$70C4, #$70C5, #$70C6, #$70C7, #$70C9, - #$70CB, #$70CC, #$70CD, #$70CE, #$70CF, #$70D0, #$70D1, #$70D2, - #$70D3, #$70D4, #$70D5, #$70D6, #$70D7, #$70DA, - #$70DC, #$70DD, #$70DE, #$70E0, #$70E1, #$70E2, #$70E3, #$70E5, - #$70EA, #$70EE, #$70F0, #$70F1, #$70F2, #$70F3, #$70F4, #$70F5, - #$70F6, #$70F8, #$70FA, #$70FB, #$70FC, #$70FE, #$70FF, #$7100, - #$7101, #$7102, #$7103, #$7104, #$7105, #$7106, #$7107, #$7108, - #$710B, #$710C, #$710D, #$710E, #$710F, #$7111, #$7112, #$7114, - #$7117, #$711B, #$711C, #$711D, #$711E, #$711F, #$7120, #$7121, - #$7122, #$7123, #$7124, #$7125, #$7127, #$7128, #$7129, #$712A, - #$712B, #$712C, #$712D, #$712E, #$7132, #$7133, #$7134, #$7135, - #$7137, #$7138, #$7139, #$713A, #$713B, #$713C, #$713D, #$713E, - #$713F, #$7140, #$7141, #$7142, #$7143, #$7144, #$7146, #$7147, - #$7148, #$7149, #$714B, #$714D, #$714F, #$7150, #$7151, #$7152, - #$7153, #$7154, #$7155, #$7156, #$7157, #$7158, #$7159, #$715A, - #$715B, #$715D, #$715F, #$7160, #$7161, #$7162, #$7163, #$7165, - #$7169, #$716A, #$716B, #$716C, #$716D, #$716F, #$7170, #$7171, - #$7174, #$7175, #$7176, #$7177, #$7179, #$717B, #$717C, #$717E, - #$717F, #$7180, #$7181, #$7182, #$7183, #$7185, #$7186, #$7187, - #$7188, #$7189, #$718B, #$718C, #$718D, #$718E, #$7190, #$7191, - #$7192, #$7193, #$7195, #$7196, #$7197, #$719A, #$719B, #$719C, - #$719D, #$719E, #$71A1, #$71A2, #$71A3, #$71A4, #$71A5, #$71A6, - #$71A7, #$71A9, #$71AA, #$71AB, #$71AD, #$71AE, #$71AF, #$71B0, - #$71B1, #$71B2, #$71B4, #$71B6, #$71B7, #$71B8, #$71BA, #$71BB, - #$71BC, #$71BD, #$71BE, #$71BF, #$71C0, #$71C1, #$71C2, #$71C4, - #$71C5, #$71C6, #$71C7, #$71C8, #$71C9, #$71CA, #$71CB, #$71CC, - #$71CD, #$71CF, #$71D0, #$71D1, #$71D2, #$71D3, - #$71D6, #$71D7, #$71D8, #$71D9, #$71DA, #$71DB, #$71DC, #$71DD, - #$71DE, #$71DF, #$71E1, #$71E2, #$71E3, #$71E4, #$71E6, #$71E8, - #$71E9, #$71EA, #$71EB, #$71EC, #$71ED, #$71EF, #$71F0, #$71F1, - #$71F2, #$71F3, #$71F4, #$71F5, #$71F6, #$71F7, #$71F8, #$71FA, - #$71FB, #$71FC, #$71FD, #$71FE, #$71FF, #$7200, #$7201, #$7202, - #$7203, #$7204, #$7205, #$7207, #$7208, #$7209, #$720A, #$720B, - #$720C, #$720D, #$720E, #$720F, #$7210, #$7211, #$7212, #$7213, - #$7214, #$7215, #$7216, #$7217, #$7218, #$7219, #$721A, #$721B, - #$721C, #$721E, #$721F, #$7220, #$7221, #$7222, #$7223, #$7224, - #$7225, #$7226, #$7227, #$7229, #$722B, #$722D, #$722E, #$722F, - #$7232, #$7233, #$7234, #$723A, #$723C, #$723E, #$7240, #$7241, - #$7242, #$7243, #$7244, #$7245, #$7246, #$7249, #$724A, #$724B, - #$724E, #$724F, #$7250, #$7251, #$7253, #$7254, #$7255, #$7257, - #$7258, #$725A, #$725C, #$725E, #$7260, #$7263, #$7264, #$7265, - #$7268, #$726A, #$726B, #$726C, #$726D, #$7270, #$7271, #$7273, - #$7274, #$7276, #$7277, #$7278, #$727B, #$727C, #$727D, #$7282, - #$7283, #$7285, #$7286, #$7287, #$7288, #$7289, #$728C, #$728E, - #$7290, #$7291, #$7293, #$7294, #$7295, #$7296, #$7297, #$7298, - #$7299, #$729A, #$729B, #$729C, #$729D, #$729E, #$72A0, #$72A1, - #$72A2, #$72A3, #$72A4, #$72A5, #$72A6, #$72A7, #$72A8, #$72A9, - #$72AA, #$72AB, #$72AE, #$72B1, #$72B2, #$72B3, #$72B5, #$72BA, - #$72BB, #$72BC, #$72BD, #$72BE, #$72BF, #$72C0, #$72C5, #$72C6, - #$72C7, #$72C9, #$72CA, #$72CB, #$72CC, #$72CF, #$72D1, #$72D3, - #$72D4, #$72D5, #$72D6, #$72D8, #$72DA, #$72DB); - GBKE_2Map: array[0..8271] of TBuffChar = ( - #$02CA, #$02CB, #$02D9, #$2013, #$2015, #$2025, #$2035, #$2105, - #$2109, #$2196, #$2197, #$2198, #$2199, #$2215, #$221F, #$2223, - #$2252, #$2266, #$2267, #$22BF, #$2550, #$2551, #$2552, #$2553, - #$2554, #$2555, #$2556, #$2557, #$2558, #$2559, #$255A, #$255B, - #$255C, #$255D, #$255E, #$255F, #$2560, #$2561, #$2562, #$2563, - #$2564, #$2565, #$2566, #$2567, #$2568, #$2569, #$256A, #$256B, - #$256C, #$256D, #$256E, #$256F, #$2570, #$2571, #$2572, #$2573, - #$2581, #$2582, #$2583, #$2584, #$2585, #$2586, #$2587, #$2588, - #$2589, #$258A, #$258B, #$258C, #$258D, #$258E, #$258F, #$2593, - #$2594, #$2595, #$25BC, #$25BD, #$25E2, #$25E3, #$25E4, #$25E5, - #$2609, #$2295, #$3012, #$301D, #$301E, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$3021, #$3022, #$3023, #$3024, #$3025, #$3026, #$3027, #$3028, - #$3029, #$32A3, #$338E, #$338F, #$339C, #$339D, #$339E, #$33A1, - #$33C4, #$33CE, #$33D1, #$33D2, #$33D5, #$FE30, #$FFE2, #$FFE4, - #$FFFD, #$2121, #$3231, #$FFFD, #$2010, #$FFFD, #$FFFD, #$FFFD, - #$30FC, #$309B, #$309C, #$30FD, #$30FE, #$3006, #$309D, #$309E, - #$FE49, #$FE4A, #$FE4B, #$FE4C, #$FE4D, #$FE4E, #$FE4F, #$FE50, - #$FE51, #$FE52, #$FE54, #$FE55, #$FE56, #$FE57, #$FE59, #$FE5A, - #$FE5B, #$FE5C, #$FE5D, #$FE5E, #$FE5F, #$FE60, #$FE61, #$FE62, - #$FE63, #$FE64, #$FE65, #$FE66, #$FE68, #$FE69, #$FE6A, #$FE6B, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$3007, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$72DC, #$72DD, #$72DF, #$72E2, #$72E3, #$72E4, #$72E5, #$72E6, - #$72E7, #$72EA, #$72EB, #$72F5, #$72F6, #$72F9, #$72FD, #$72FE, - #$72FF, #$7300, #$7302, #$7304, #$7305, #$7306, #$7307, #$7308, - #$7309, #$730B, #$730C, #$730D, #$730F, #$7310, #$7311, #$7312, - #$7314, #$7318, #$7319, #$731A, #$731F, #$7320, #$7323, #$7324, - #$7326, #$7327, #$7328, #$732D, #$732F, #$7330, #$7332, #$7333, - #$7335, #$7336, #$733A, #$733B, #$733C, #$733D, #$7340, #$7341, - #$7342, #$7343, #$7344, #$7345, #$7346, #$7347, #$7348, #$7349, - #$734A, #$734B, #$734C, #$734E, #$734F, #$7351, #$7353, #$7354, - #$7355, #$7356, #$7358, #$7359, #$735A, #$735B, #$735C, #$735D, - #$735E, #$735F, #$7361, #$7362, #$7363, #$7364, #$7365, #$7366, - #$7367, #$7368, #$7369, #$736A, #$736B, #$736E, #$7370, #$7371, - #$7372, #$7373, #$7374, #$7375, #$7376, #$7377, #$7378, #$7379, - #$737A, #$737B, #$737C, #$737D, #$737F, #$7380, #$7381, #$7382, - #$7383, #$7385, #$7386, #$7388, #$738A, #$738C, #$738D, #$738F, - #$7390, #$7392, #$7393, #$7394, #$7395, #$7397, #$7398, #$7399, - #$739A, #$739C, #$739D, #$739E, #$73A0, #$73A1, #$73A3, #$73A4, - #$73A5, #$73A6, #$73A7, #$73A8, #$73AA, #$73AC, #$73AD, #$73B1, - #$73B4, #$73B5, #$73B6, #$73B8, #$73B9, #$73BC, #$73BD, #$73BE, - #$73BF, #$73C1, #$73C3, #$73C4, #$73C5, #$73C6, #$73C7, #$73CB, - #$73CC, #$73CE, #$73D2, #$73D3, #$73D4, #$73D5, #$73D6, #$73D7, - #$73D8, #$73DA, #$73DB, #$73DC, #$73DD, #$73DF, #$73E1, #$73E2, - #$73E3, #$73E4, #$73E6, #$73E8, #$73EA, #$73EB, #$73EC, #$73EE, - #$73EF, #$73F0, #$73F1, #$73F3, #$73F4, #$73F5, #$73F6, #$73F7, - #$73F8, #$73F9, #$73FA, #$73FB, #$73FC, #$73FD, #$73FE, #$73FF, - #$7400, #$7401, #$7402, #$7404, #$7407, #$7408, #$740B, #$740C, - #$740D, #$740E, #$7411, #$7412, #$7413, #$7414, #$7415, #$7416, - #$7417, #$7418, #$7419, #$741C, #$741D, #$741E, #$741F, #$7420, - #$7421, #$7423, #$7424, #$7427, #$7429, #$742B, #$742D, #$742F, - #$7431, #$7432, #$7437, #$7438, #$7439, #$743A, #$743B, #$743D, - #$743E, #$743F, #$7440, #$7442, #$7443, #$7444, #$7445, #$7446, - #$7447, #$7448, #$7449, #$744A, #$744B, #$744C, #$744D, #$744E, - #$744F, #$7450, #$7451, #$7452, #$7453, #$7454, #$7456, #$7458, - #$745D, #$7460, #$7461, #$7462, #$7463, #$7464, #$7465, #$7466, - #$7467, #$7468, #$7469, #$746A, #$746B, #$746C, #$746E, #$746F, - #$7471, #$7472, #$7473, #$7474, #$7475, #$7478, #$7479, #$747A, - #$747B, #$747C, #$747D, #$747F, #$7482, #$7484, #$7485, #$7486, - #$7488, #$7489, #$748A, #$748C, #$748D, #$748F, #$7491, #$7492, - #$7493, #$7494, #$7495, #$7496, #$7497, #$7498, #$7499, #$749A, - #$749B, #$749D, #$749F, #$74A0, #$74A1, #$74A2, #$74A3, #$74A4, - #$74A5, #$74A6, #$74AA, #$74AB, #$74AC, #$74AD, #$74AE, #$74AF, - #$74B0, #$74B1, #$74B2, #$74B3, #$74B4, #$74B5, #$74B6, #$74B7, - #$74B8, #$74B9, #$74BB, #$74BC, #$74BD, #$74BE, #$74BF, #$74C0, - #$74C1, #$74C2, #$74C3, #$74C4, #$74C5, #$74C6, #$74C7, #$74C8, - #$74C9, #$74CA, #$74CB, #$74CC, #$74CD, #$74CE, #$74CF, #$74D0, - #$74D1, #$74D3, #$74D4, #$74D5, #$74D6, #$74D7, #$74D8, #$74D9, - #$74DA, #$74DB, #$74DD, #$74DF, #$74E1, #$74E5, #$74E7, #$74E8, - #$74E9, #$74EA, #$74EB, #$74EC, #$74ED, #$74F0, #$74F1, #$74F2, - #$74F3, #$74F5, #$74F8, #$74F9, #$74FA, #$74FB, #$74FC, #$74FD, - #$74FE, #$7500, #$7501, #$7502, #$7503, #$7505, #$7506, #$7507, - #$7508, #$7509, #$750A, #$750B, #$750C, #$750E, #$7510, #$7512, - #$7514, #$7515, #$7516, #$7517, #$751B, #$751D, #$751E, #$7520, - #$7521, #$7522, #$7523, #$7524, #$7526, #$7527, #$752A, #$752E, - #$7534, #$7536, #$7539, #$753C, #$753D, #$753F, #$7541, #$7542, - #$7543, #$7544, #$7546, #$7547, #$7549, #$754A, #$754D, #$7550, - #$7551, #$7552, #$7553, #$7555, #$7556, #$7557, #$7558, #$755D, - #$755E, #$755F, #$7560, #$7561, #$7562, #$7563, #$7564, #$7567, - #$7568, #$7569, #$756B, #$756C, #$756D, #$756E, #$756F, #$7570, - #$7571, #$7573, #$7575, #$7576, #$7577, #$757A, #$757B, #$757C, - #$757D, #$757E, #$7580, #$7581, #$7582, #$7584, #$7585, #$7587, - #$7588, #$7589, #$758A, #$758C, #$758D, #$758E, #$7590, #$7593, - #$7595, #$7598, #$759B, #$759C, #$759E, #$75A2, #$75A6, #$75A7, - #$75A8, #$75A9, #$75AA, #$75AD, #$75B6, #$75B7, #$75BA, #$75BB, - #$75BF, #$75C0, #$75C1, #$75C6, #$75CB, #$75CC, #$75CE, #$75CF, - #$75D0, #$75D1, #$75D3, #$75D7, #$75D9, #$75DA, #$75DC, #$75DD, - #$75DF, #$75E0, #$75E1, #$75E5, #$75E9, #$75EC, #$75ED, #$75EE, - #$75EF, #$75F2, #$75F3, #$75F5, #$75F6, #$75F7, #$75F8, #$75FA, - #$75FB, #$75FD, #$75FE, #$7602, #$7604, #$7606, #$7607, #$7608, - #$7609, #$760B, #$760D, #$760E, #$760F, #$7611, #$7612, #$7613, - #$7614, #$7616, #$761A, #$761C, #$761D, #$761E, #$7621, #$7623, - #$7627, #$7628, #$762C, #$762E, #$762F, #$7631, #$7632, #$7636, - #$7637, #$7639, #$763A, #$763B, #$763D, #$7641, #$7642, #$7644, - #$7645, #$7646, #$7647, #$7648, #$7649, #$764A, #$764B, #$764E, - #$764F, #$7650, #$7651, #$7652, #$7653, #$7655, #$7657, #$7658, - #$7659, #$765A, #$765B, #$765D, #$765F, #$7660, #$7661, #$7662, - #$7664, #$7665, #$7666, #$7667, #$7668, #$7669, #$766A, #$766C, - #$766D, #$766E, #$7670, #$7671, #$7672, #$7673, #$7674, #$7675, - #$7676, #$7677, #$7679, #$767A, #$767C, #$767F, #$7680, #$7681, - #$7683, #$7685, #$7689, #$768A, #$768C, #$768D, #$768F, #$7690, - #$7692, #$7694, #$7695, #$7697, #$7698, #$769A, #$769B, #$769C, - #$769D, #$769E, #$769F, #$76A0, #$76A1, #$76A2, #$76A3, #$76A5, - #$76A6, #$76A7, #$76A8, #$76A9, #$76AA, #$76AB, #$76AC, #$76AD, - #$76AF, #$76B0, #$76B3, #$76B5, #$76B6, #$76B7, #$76B8, #$76B9, - #$76BA, #$76BB, #$76BC, #$76BD, #$76BE, #$76C0, #$76C1, #$76C3, - #$76C4, #$76C7, #$76C9, #$76CB, #$76CC, #$76D3, #$76D5, #$76D9, - #$76DA, #$76DC, #$76DD, #$76DE, #$76E0, #$76E1, #$76E2, #$76E3, - #$76E4, #$76E6, #$76E7, #$76E8, #$76E9, #$76EA, #$76EB, #$76EC, - #$76ED, #$76F0, #$76F3, #$76F5, #$76F6, #$76F7, #$76FA, #$76FB, - #$76FD, #$76FF, #$7700, #$7702, #$7703, #$7705, #$7706, #$770A, - #$770C, #$770E, #$770F, #$7710, #$7711, #$7712, #$7713, #$7714, - #$7715, #$7716, #$7717, #$7718, #$771B, #$771C, #$771D, #$771E, - #$7721, #$7723, #$7724, #$7725, #$7727, #$772A, #$772B, #$772C, - #$772E, #$7730, #$7731, #$7732, #$7733, #$7734, #$7739, #$773B, - #$773D, #$773E, #$773F, #$7742, #$7744, #$7745, #$7746, #$7748, - #$7749, #$774A, #$774B, #$774C, #$774D, #$774E, #$774F, #$7752, - #$7753, #$7754, #$7755, #$7756, #$7757, #$7758, #$7759, #$775C, - #$775D, #$775E, #$775F, #$7760, #$7764, #$7767, #$7769, #$776A, - #$776D, #$776E, #$776F, #$7770, #$7771, #$7772, #$7773, #$7774, - #$7775, #$7776, #$7777, #$7778, #$777A, #$777B, #$777C, #$7781, - #$7782, #$7783, #$7786, #$7787, #$7788, #$7789, #$778A, #$778B, - #$778F, #$7790, #$7793, #$7794, #$7795, #$7796, #$7797, #$7798, - #$7799, #$779A, #$779B, #$779C, #$779D, #$779E, #$77A1, #$77A3, - #$77A4, #$77A6, #$77A8, #$77AB, #$77AD, #$77AE, #$77AF, #$77B1, - #$77B2, #$77B4, #$77B6, #$77B7, #$77B8, #$77B9, #$77BA, #$77BC, - #$77BE, #$77C0, #$77C1, #$77C2, #$77C3, #$77C4, #$77C5, #$77C6, - #$77C7, #$77C8, #$77C9, #$77CA, #$77CB, #$77CC, #$77CE, #$77CF, - #$77D0, #$77D1, #$77D2, #$77D3, #$77D4, #$77D5, #$77D6, #$77D8, - #$77D9, #$77DA, #$77DD, #$77DE, #$77DF, #$77E0, #$77E1, #$77E4, - #$77E6, #$77E8, #$77EA, #$77EF, #$77F0, #$77F1, #$77F2, #$77F4, - #$77F5, #$77F7, #$77F9, #$77FA, #$77FB, #$77FC, #$7803, #$7804, - #$7805, #$7806, #$7807, #$7808, #$780A, #$780B, #$780E, #$780F, - #$7810, #$7813, #$7815, #$7819, #$781B, #$781E, #$7820, #$7821, - #$7822, #$7824, #$7828, #$782A, #$782B, #$782E, #$782F, #$7831, - #$7832, #$7833, #$7835, #$7836, #$783D, #$783F, #$7841, #$7842, - #$7843, #$7844, #$7846, #$7848, #$7849, #$784A, #$784B, #$784D, - #$784F, #$7851, #$7853, #$7854, #$7858, #$7859, #$785A, #$785B, - #$785C, #$785E, #$785F, #$7860, #$7861, #$7862, #$7863, #$7864, - #$7865, #$7866, #$7867, #$7868, #$7869, #$786F, #$7870, #$7871, - #$7872, #$7873, #$7874, #$7875, #$7876, #$7878, #$7879, #$787A, - #$787B, #$787D, #$787E, #$787F, #$7880, #$7881, #$7882, #$7883, - #$7884, #$7885, #$7886, #$7888, #$788A, #$788B, #$788F, #$7890, - #$7892, #$7894, #$7895, #$7896, #$7899, #$789D, #$789E, #$78A0, - #$78A2, #$78A4, #$78A6, #$78A8, #$78A9, #$78AA, #$78AB, #$78AC, - #$78AD, #$78AE, #$78AF, #$78B5, #$78B6, #$78B7, #$78B8, #$78BA, - #$78BB, #$78BC, #$78BD, #$78BF, #$78C0, #$78C2, #$78C3, #$78C4, - #$78C6, #$78C7, #$78C8, #$78CC, #$78CD, #$78CE, #$78CF, #$78D1, - #$78D2, #$78D3, #$78D6, #$78D7, #$78D8, #$78DA, #$78DB, #$78DC, - #$78DD, #$78DE, #$78DF, #$78E0, #$78E1, #$78E2, #$78E3, #$78E4, - #$78E5, #$78E6, #$78E7, #$78E9, #$78EA, #$78EB, #$78ED, #$78EE, - #$78EF, #$78F0, #$78F1, #$78F3, #$78F5, #$78F6, #$78F8, #$78F9, - #$78FB, #$78FC, #$78FD, #$78FE, #$78FF, #$7900, #$7902, #$7903, - #$7904, #$7906, #$7907, #$7908, #$7909, #$790A, #$790B, #$790C, - #$790D, #$790E, #$790F, #$7910, #$7911, #$7912, #$7914, #$7915, - #$7916, #$7917, #$7918, #$7919, #$791A, #$791B, #$791C, #$791D, - #$791F, #$7920, #$7921, #$7922, #$7923, #$7925, #$7926, #$7927, - #$7928, #$7929, #$792A, #$792B, #$792C, #$792D, #$792E, #$792F, - #$7930, #$7931, #$7932, #$7933, #$7935, #$7936, #$7937, #$7938, - #$7939, #$793D, #$793F, #$7942, #$7943, #$7944, #$7945, #$7947, - #$794A, #$794B, #$794C, #$794D, #$794E, #$794F, #$7950, #$7951, - #$7952, #$7954, #$7955, #$7958, #$7959, #$7961, #$7963, #$7964, - #$7966, #$7969, #$796A, #$796B, #$796C, #$796E, #$7970, #$7971, - #$7972, #$7973, #$7974, #$7975, #$7976, #$7979, #$797B, #$797C, - #$797D, #$797E, #$797F, #$7982, #$7983, #$7986, #$7987, #$7988, - #$7989, #$798B, #$798C, #$798D, #$798E, #$7990, #$7991, #$7992, - #$7993, #$7994, #$7995, #$7996, #$7997, #$7998, #$7999, #$799B, - #$799C, #$799D, #$799E, #$799F, #$79A0, #$79A1, #$79A2, #$79A3, - #$79A4, #$79A5, #$79A6, #$79A8, #$79A9, #$79AA, #$79AB, #$79AC, - #$79AD, #$79AE, #$79AF, #$79B0, #$79B1, #$79B2, #$79B4, #$79B5, - #$79B6, #$79B7, #$79B8, #$79BC, #$79BF, #$79C2, #$79C4, #$79C5, - #$79C7, #$79C8, #$79CA, #$79CC, #$79CE, #$79CF, #$79D0, #$79D3, - #$79D4, #$79D6, #$79D7, #$79D9, #$79DA, #$79DB, #$79DC, #$79DD, - #$79DE, #$79E0, #$79E1, #$79E2, #$79E5, #$79E8, #$79EA, #$79EC, - #$79EE, #$79F1, #$79F2, #$79F3, #$79F4, #$79F5, #$79F6, #$79F7, - #$79F9, #$79FA, #$79FC, #$79FE, #$79FF, #$7A01, #$7A04, #$7A05, - #$7A07, #$7A08, #$7A09, #$7A0A, #$7A0C, #$7A0F, #$7A10, #$7A11, - #$7A12, #$7A13, #$7A15, #$7A16, #$7A18, #$7A19, #$7A1B, #$7A1C, - #$7A1D, #$7A1F, #$7A21, #$7A22, #$7A24, #$7A25, #$7A26, #$7A27, - #$7A28, #$7A29, #$7A2A, #$7A2B, #$7A2C, #$7A2D, #$7A2E, #$7A2F, - #$7A30, #$7A31, #$7A32, #$7A34, #$7A35, #$7A36, #$7A38, #$7A3A, - #$7A3E, #$7A40, #$7A41, #$7A42, #$7A43, #$7A44, #$7A45, #$7A47, - #$7A48, #$7A49, #$7A4A, #$7A4B, #$7A4C, #$7A4D, #$7A4E, #$7A4F, - #$7A50, #$7A52, #$7A53, #$7A54, #$7A55, #$7A56, #$7A58, #$7A59, - #$7A5A, #$7A5B, #$7A5C, #$7A5D, #$7A5E, #$7A5F, #$7A60, #$7A61, - #$7A62, #$7A63, #$7A64, #$7A65, #$7A66, #$7A67, #$7A68, #$7A69, - #$7A6A, #$7A6B, #$7A6C, #$7A6D, #$7A6E, #$7A6F, #$7A71, #$7A72, - #$7A73, #$7A75, #$7A7B, #$7A7C, #$7A7D, #$7A7E, #$7A82, #$7A85, - #$7A87, #$7A89, #$7A8A, #$7A8B, #$7A8C, #$7A8E, #$7A8F, #$7A90, - #$7A93, #$7A94, #$7A99, #$7A9A, #$7A9B, #$7A9E, #$7AA1, #$7AA2, - #$7AA3, #$7AA4, #$7AA7, #$7AA9, #$7AAA, #$7AAB, #$7AAE, #$7AAF, - #$7AB0, #$7AB1, #$7AB2, #$7AB4, #$7AB5, #$7AB6, #$7AB7, #$7AB8, - #$7AB9, #$7ABA, #$7ABB, #$7ABC, #$7ABD, #$7ABE, #$7AC0, #$7AC1, - #$7AC2, #$7AC3, #$7AC4, #$7AC5, #$7AC6, #$7AC7, #$7AC8, #$7AC9, - #$7ACA, #$7ACC, #$7ACD, #$7ACE, #$7ACF, #$7AD0, #$7AD1, #$7AD2, - #$7AD3, #$7AD4, #$7AD5, #$7AD7, #$7AD8, #$7ADA, #$7ADB, #$7ADC, - #$7ADD, #$7AE1, #$7AE2, #$7AE4, #$7AE7, #$7AE8, #$7AE9, #$7AEA, - #$7AEB, #$7AEC, #$7AEE, #$7AF0, #$7AF1, #$7AF2, #$7AF3, #$7AF4, - #$7AF5, #$7AF6, #$7AF7, #$7AF8, #$7AFB, #$7AFC, #$7AFE, #$7B00, - #$7B01, #$7B02, #$7B05, #$7B07, #$7B09, #$7B0C, #$7B0D, #$7B0E, - #$7B10, #$7B12, #$7B13, #$7B16, #$7B17, #$7B18, #$7B1A, #$7B1C, - #$7B1D, #$7B1F, #$7B21, #$7B22, #$7B23, #$7B27, #$7B29, #$7B2D, - #$7B2F, #$7B30, #$7B32, #$7B34, #$7B35, #$7B36, #$7B37, #$7B39, - #$7B3B, #$7B3D, #$7B3F, #$7B40, #$7B41, #$7B42, #$7B43, #$7B44, - #$7B46, #$7B48, #$7B4A, #$7B4D, #$7B4E, #$7B53, #$7B55, #$7B57, - #$7B59, #$7B5C, #$7B5E, #$7B5F, #$7B61, #$7B63, #$7B64, #$7B65, - #$7B66, #$7B67, #$7B68, #$7B69, #$7B6A, #$7B6B, #$7B6C, #$7B6D, - #$7B6F, #$7B70, #$7B73, #$7B74, #$7B76, #$7B78, #$7B7A, #$7B7C, - #$7B7D, #$7B7F, #$7B81, #$7B82, #$7B83, #$7B84, #$7B86, #$7B87, - #$7B88, #$7B89, #$7B8A, #$7B8B, #$7B8C, #$7B8E, #$7B8F, #$7B91, - #$7B92, #$7B93, #$7B96, #$7B98, #$7B99, #$7B9A, #$7B9B, #$7B9E, - #$7B9F, #$7BA0, #$7BA3, #$7BA4, #$7BA5, #$7BAE, #$7BAF, #$7BB0, - #$7BB2, #$7BB3, #$7BB5, #$7BB6, #$7BB7, #$7BB9, #$7BBA, #$7BBB, - #$7BBC, #$7BBD, #$7BBE, #$7BBF, #$7BC0, #$7BC2, #$7BC3, #$7BC4, - #$7BC5, #$7BC8, #$7BC9, #$7BCA, #$7BCB, #$7BCD, #$7BCE, #$7BCF, - #$7BD0, #$7BD2, #$7BD4, #$7BD5, #$7BD6, #$7BD7, #$7BD8, #$7BDB, - #$7BDC, #$7BDE, #$7BDF, #$7BE0, #$7BE2, #$7BE3, #$7BE4, #$7BE7, - #$7BE8, #$7BE9, #$7BEB, #$7BEC, #$7BED, #$7BEF, #$7BF0, #$7BF2, - #$7BF3, #$7BF4, #$7BF5, #$7BF6, #$7BF8, #$7BF9, #$7BFA, #$7BFB, - #$7BFD, #$7BFF, #$7C00, #$7C01, #$7C02, #$7C03, #$7C04, #$7C05, - #$7C06, #$7C08, #$7C09, #$7C0A, #$7C0D, #$7C0E, #$7C10, #$7C11, - #$7C12, #$7C13, #$7C14, #$7C15, #$7C17, #$7C18, #$7C19, #$7C1A, - #$7C1B, #$7C1C, #$7C1D, #$7C1E, #$7C20, #$7C21, #$7C22, #$7C23, - #$7C24, #$7C25, #$7C28, #$7C29, #$7C2B, #$7C2C, #$7C2D, #$7C2E, - #$7C2F, #$7C30, #$7C31, #$7C32, #$7C33, #$7C34, #$7C35, #$7C36, - #$7C37, #$7C39, #$7C3A, #$7C3B, #$7C3C, #$7C3D, #$7C3E, #$7C42, - #$7C43, #$7C44, #$7C45, #$7C46, #$7C47, #$7C48, #$7C49, #$7C4A, - #$7C4B, #$7C4C, #$7C4E, #$7C4F, #$7C50, #$7C51, #$7C52, #$7C53, - #$7C54, #$7C55, #$7C56, #$7C57, #$7C58, #$7C59, #$7C5A, #$7C5B, - #$7C5C, #$7C5D, #$7C5E, #$7C5F, #$7C60, #$7C61, #$7C62, #$7C63, - #$7C64, #$7C65, #$7C66, #$7C67, #$7C68, #$7C69, #$7C6A, #$7C6B, - #$7C6C, #$7C6D, #$7C6E, #$7C6F, #$7C70, #$7C71, #$7C72, #$7C75, - #$7C76, #$7C77, #$7C78, #$7C79, #$7C7A, #$7C7E, #$7C7F, #$7C80, - #$7C81, #$7C82, #$7C83, #$7C84, #$7C85, #$7C86, #$7C87, #$7C88, - #$7C8A, #$7C8B, #$7C8C, #$7C8D, #$7C8E, #$7C8F, #$7C90, #$7C93, - #$7C94, #$7C96, #$7C99, #$7C9A, #$7C9B, #$7CA0, #$7CA1, #$7CA3, - #$7CA6, #$7CA7, #$7CA8, #$7CA9, #$7CAB, #$7CAC, #$7CAD, #$7CAF, - #$7CB0, #$7CB4, #$7CB5, #$7CB6, #$7CB7, #$7CB8, #$7CBA, #$7CBB, - #$7CBF, #$7CC0, #$7CC2, #$7CC3, #$7CC4, #$7CC6, #$7CC9, #$7CCB, - #$7CCE, #$7CCF, #$7CD0, #$7CD1, #$7CD2, #$7CD3, #$7CD4, #$7CD8, - #$7CDA, #$7CDB, #$7CDD, #$7CDE, #$7CE1, #$7CE2, #$7CE3, #$7CE4, - #$7CE5, #$7CE6, #$7CE7, #$7CE9, #$7CEA, #$7CEB, #$7CEC, #$7CED, - #$7CEE, #$7CF0, #$7CF1, #$7CF2, #$7CF3, #$7CF4, #$7CF5, #$7CF6, - #$7CF7, #$7CF9, #$7CFA, #$7CFC, #$7CFD, #$7CFE, #$7CFF, #$7D00, - #$7D01, #$7D02, #$7D03, #$7D04, #$7D05, #$7D06, #$7D07, #$7D08, - #$7D09, #$7D0B, #$7D0C, #$7D0D, #$7D0E, #$7D0F, #$7D10, #$7D11, - #$7D12, #$7D13, #$7D14, #$7D15, #$7D16, #$7D17, #$7D18, #$7D19, - #$7D1A, #$7D1B, #$7D1C, #$7D1D, #$7D1E, #$7D1F, #$7D21, #$7D23, - #$7D24, #$7D25, #$7D26, #$7D28, #$7D29, #$7D2A, #$7D2C, #$7D2D, - #$7D2E, #$7D30, #$7D31, #$7D32, #$7D33, #$7D34, #$7D35, #$7D36, - #$7D37, #$7D38, #$7D39, #$7D3A, #$7D3B, #$7D3C, #$7D3D, #$7D3E, - #$7D3F, #$7D40, #$7D41, #$7D42, #$7D43, #$7D44, #$7D45, #$7D46, - #$7D47, #$7D48, #$7D49, #$7D4A, #$7D4B, #$7D4C, #$7D4D, #$7D4E, - #$7D4F, #$7D50, #$7D51, #$7D52, #$7D53, #$7D54, #$7D55, #$7D56, - #$7D57, #$7D58, #$7D59, #$7D5A, #$7D5B, #$7D5C, #$7D5D, #$7D5E, - #$7D5F, #$7D60, #$7D61, #$7D62, #$7D63, #$7D64, #$7D65, #$7D66, - #$7D67, #$7D68, #$7D69, #$7D6A, #$7D6B, #$7D6C, #$7D6D, #$7D6F, - #$7D70, #$7D71, #$7D72, #$7D73, #$7D74, #$7D75, #$7D76, #$7D78, - #$7D79, #$7D7A, #$7D7B, #$7D7C, #$7D7D, #$7D7E, #$7D7F, #$7D80, - #$7D81, #$7D82, #$7D83, #$7D84, #$7D85, #$7D86, #$7D87, #$7D88, - #$7D89, #$7D8A, #$7D8B, #$7D8C, #$7D8D, #$7D8E, #$7D8F, #$7D90, - #$7D91, #$7D92, #$7D93, #$7D94, #$7D95, #$7D96, #$7D97, #$7D98, - #$7D99, #$7D9A, #$7D9B, #$7D9C, #$7D9D, #$7D9E, #$7D9F, #$7DA0, - #$7DA1, #$7DA2, #$7DA3, #$7DA4, #$7DA5, #$7DA7, #$7DA8, #$7DA9, - #$7DAA, #$7DAB, #$7DAC, #$7DAD, #$7DAF, #$7DB0, #$7DB1, #$7DB2, - #$7DB3, #$7DB4, #$7DB5, #$7DB6, #$7DB7, #$7DB8, #$7DB9, #$7DBA, - #$7DBB, #$7DBC, #$7DBD, #$7DBE, #$7DBF, #$7DC0, #$7DC1, #$7DC2, - #$7DC3, #$7DC4, #$7DC5, #$7DC6, #$7DC7, #$7DC8, #$7DC9, #$7DCA, - #$7DCB, #$7DCC, #$7DCD, #$7DCE, #$7DCF, #$7DD0, #$7DD1, #$7DD2, - #$7DD3, #$7DD4, #$7DD5, #$7DD6, #$7DD7, #$7DD8, #$7DD9, #$7DDA, - #$7DDB, #$7DDC, #$7DDD, #$7DDE, #$7DDF, #$7DE0, #$7DE1, #$7DE2, - #$7DE3, #$7DE4, #$7DE5, #$7DE6, #$7DE7, #$7DE8, #$7DE9, #$7DEA, - #$7DEB, #$7DEC, #$7DED, #$7DEE, #$7DEF, #$7DF0, #$7DF1, #$7DF2, - #$7DF3, #$7DF4, #$7DF5, #$7DF6, #$7DF7, #$7DF8, #$7DF9, #$7DFA, - #$7DFB, #$7DFC, #$7DFD, #$7DFE, #$7DFF, #$7E00, #$7E01, #$7E02, - #$7E03, #$7E04, #$7E05, #$7E06, #$7E07, #$7E08, #$7E09, #$7E0A, - #$7E0B, #$7E0C, #$7E0D, #$7E0E, #$7E0F, #$7E10, #$7E11, #$7E12, - #$7E13, #$7E14, #$7E15, #$7E16, #$7E17, #$7E18, #$7E19, #$7E1A, - #$7E1B, #$7E1C, #$7E1D, #$7E1E, #$7E1F, #$7E20, #$7E21, #$7E22, - #$7E23, #$7E24, #$7E25, #$7E26, #$7E27, #$7E28, #$7E29, #$7E2A, - #$7E2B, #$7E2C, #$7E2D, #$7E2E, #$7E2F, #$7E30, #$7E31, #$7E32, - #$7E33, #$7E34, #$7E35, #$7E36, #$7E37, #$7E38, #$7E39, #$7E3A, - #$7E3C, #$7E3D, #$7E3E, #$7E3F, #$7E40, #$7E42, #$7E43, #$7E44, - #$7E45, #$7E46, #$7E48, #$7E49, #$7E4A, #$7E4B, #$7E4C, #$7E4D, - #$7E4E, #$7E4F, #$7E50, #$7E51, #$7E52, #$7E53, #$7E54, #$7E55, - #$7E56, #$7E57, #$7E58, #$7E59, #$7E5A, #$7E5B, #$7E5C, #$7E5D, - #$7E5E, #$7E5F, #$7E60, #$7E61, #$7E62, #$7E63, #$7E64, #$7E65, - #$7E66, #$7E67, #$7E68, #$7E69, #$7E6A, #$7E6B, #$7E6C, #$7E6D, - #$7E6E, #$7E6F, #$7E70, #$7E71, #$7E72, #$7E73, #$7E74, #$7E75, - #$7E76, #$7E77, #$7E78, #$7E79, #$7E7A, #$7E7B, #$7E7C, #$7E7D, - #$7E7E, #$7E7F, #$7E80, #$7E81, #$7E83, #$7E84, #$7E85, #$7E86, - #$7E87, #$7E88, #$7E89, #$7E8A, #$7E8B, #$7E8C, #$7E8D, #$7E8E, - #$7E8F, #$7E90, #$7E91, #$7E92, #$7E93, #$7E94, #$7E95, #$7E96, - #$7E97, #$7E98, #$7E99, #$7E9A, #$7E9C, #$7E9D, #$7E9E, #$7EAE, - #$7EB4, #$7EBB, #$7EBC, #$7ED6, #$7EE4, #$7EEC, #$7EF9, #$7F0A, - #$7F10, #$7F1E, #$7F37, #$7F39, #$7F3B, #$7F3C, #$7F3D, #$7F3E, - #$7F3F, #$7F40, #$7F41, #$7F43, #$7F46, #$7F47, #$7F48, #$7F49, - #$7F4A, #$7F4B, #$7F4C, #$7F4D, #$7F4E, #$7F4F, #$7F52, #$7F53, - #$7F56, #$7F59, #$7F5B, #$7F5C, #$7F5D, #$7F5E, #$7F60, #$7F63, - #$7F64, #$7F65, #$7F66, #$7F67, #$7F6B, #$7F6C, #$7F6D, #$7F6F, - #$7F70, #$7F73, #$7F75, #$7F76, #$7F77, #$7F78, #$7F7A, #$7F7B, - #$7F7C, #$7F7D, #$7F7F, #$7F80, #$7F82, #$7F83, #$7F84, #$7F85, - #$7F86, #$7F87, #$7F88, #$7F89, #$7F8B, #$7F8D, #$7F8F, #$7F90, - #$7F91, #$7F92, #$7F93, #$7F95, #$7F96, #$7F97, #$7F98, #$7F99, - #$7F9B, #$7F9C, #$7FA0, #$7FA2, #$7FA3, #$7FA5, #$7FA6, #$7FA8, - #$7FA9, #$7FAA, #$7FAB, #$7FAC, #$7FAD, #$7FAE, #$7FB1, #$7FB3, - #$7FB4, #$7FB5, #$7FB6, #$7FB7, #$7FBA, #$7FBB, #$7FBE, #$7FC0, - #$7FC2, #$7FC3, #$7FC4, #$7FC6, #$7FC7, #$7FC8, #$7FC9, #$7FCB, - #$7FCD, #$7FCF, #$7FD0, #$7FD1, #$7FD2, #$7FD3, #$7FD6, #$7FD7, - #$7FD9, #$7FDA, #$7FDB, #$7FDC, #$7FDD, #$7FDE, #$7FE2, #$7FE3, - #$7FE4, #$7FE7, #$7FE8, #$7FEA, #$7FEB, #$7FEC, #$7FED, #$7FEF, - #$7FF2, #$7FF4, #$7FF5, #$7FF6, #$7FF7, #$7FF8, #$7FF9, #$7FFA, - #$7FFD, #$7FFE, #$7FFF, #$8002, #$8007, #$8008, #$8009, #$800A, - #$800E, #$800F, #$8011, #$8013, #$801A, #$801B, #$801D, #$801E, - #$801F, #$8021, #$8023, #$8024, #$802B, #$802C, #$802D, #$802E, - #$802F, #$8030, #$8032, #$8034, #$8039, #$803A, #$803C, #$803E, - #$8040, #$8041, #$8044, #$8045, #$8047, #$8048, #$8049, #$804E, - #$804F, #$8050, #$8051, #$8053, #$8055, #$8056, #$8057, #$8059, - #$805B, #$805C, #$805D, #$805E, #$805F, #$8060, #$8061, #$8062, - #$8063, #$8064, #$8065, #$8066, #$8067, #$8068, #$806B, #$806C, - #$806D, #$806E, #$806F, #$8070, #$8072, #$8073, #$8074, #$8075, - #$8076, #$8077, #$8078, #$8079, #$807A, #$807B, #$807C, #$807D, - #$807E, #$8081, #$8082, #$8085, #$8088, #$808A, #$808D, #$808E, - #$808F, #$8090, #$8091, #$8092, #$8094, #$8095, #$8097, #$8099, - #$809E, #$80A3, #$80A6, #$80A7, #$80A8, #$80AC, #$80B0, #$80B3, - #$80B5, #$80B6, #$80B8, #$80B9, #$80BB, #$80C5, #$80C7, #$80C8, - #$80C9, #$80CA, #$80CB, #$80CF, #$80D0, #$80D1, #$80D2, #$80D3, - #$80D4, #$80D5, #$80D8, #$80DF, #$80E0, #$80E2, #$80E3, #$80E6, - #$80EE, #$80F5, #$80F7, #$80F9, #$80FB, #$80FE, #$80FF, #$8100, - #$8101, #$8103, #$8104, #$8105, #$8107, #$8108, #$810B, #$810C, - #$8115, #$8117, #$8119, #$811B, #$811C, #$811D, #$811F, #$8120, - #$8121, #$8122, #$8123, #$8124, #$8125, #$8126, #$8127, #$8128, - #$8129, #$812A, #$812B, #$812D, #$812E, #$8130, #$8133, #$8134, - #$8135, #$8137, #$8139, #$813A, #$813B, #$813C, #$813D, #$813F, - #$8140, #$8141, #$8142, #$8143, #$8144, #$8145, #$8147, #$8149, - #$814D, #$814E, #$814F, #$8152, #$8156, #$8157, #$8158, #$815B, - #$815C, #$815D, #$815E, #$815F, #$8161, #$8162, #$8163, #$8164, - #$8166, #$8168, #$816A, #$816B, #$816C, #$816F, #$8172, #$8173, - #$8175, #$8176, #$8177, #$8178, #$8181, #$8183, #$8184, #$8185, - #$8186, #$8187, #$8189, #$818B, #$818C, #$818D, #$818E, #$8190, - #$8192, #$8193, #$8194, #$8195, #$8196, #$8197, #$8199, #$819A, - #$819E, #$819F, #$81A0, #$81A1, #$81A2, #$81A4, #$81A5, #$81A7, - #$81A9, #$81AB, #$81AC, #$81AD, #$81AE, #$81AF, #$81B0, #$81B1, - #$81B2, #$81B4, #$81B5, #$81B6, #$81B7, #$81B8, #$81B9, #$81BC, - #$81BD, #$81BE, #$81BF, #$81C4, #$81C5, #$81C7, #$81C8, #$81C9, - #$81CB, #$81CD, #$81CE, #$81CF, #$81D0, #$81D1, #$81D2, #$81D3, - #$81D4, #$81D5, #$81D6, #$81D7, #$81D8, #$81D9, #$81DA, #$81DB, - #$81DC, #$81DD, #$81DE, #$81DF, #$81E0, #$81E1, #$81E2, #$81E4, - #$81E5, #$81E6, #$81E8, #$81E9, #$81EB, #$81EE, #$81EF, #$81F0, - #$81F1, #$81F2, #$81F5, #$81F6, #$81F7, #$81F8, #$81F9, #$81FA, - #$81FD, #$81FF, #$8203, #$8207, #$8208, #$8209, #$820A, #$820B, - #$820E, #$820F, #$8211, #$8213, #$8215, #$8216, #$8217, #$8218, - #$8219, #$821A, #$821D, #$8220, #$8224, #$8225, #$8226, #$8227, - #$8229, #$822E, #$8232, #$823A, #$823C, #$823D, #$823F, #$8240, - #$8241, #$8242, #$8243, #$8245, #$8246, #$8248, #$824A, #$824C, - #$824D, #$824E, #$8250, #$8251, #$8252, #$8253, #$8254, #$8255, - #$8256, #$8257, #$8259, #$825B, #$825C, #$825D, #$825E, #$8260, - #$8261, #$8262, #$8263, #$8264, #$8265, #$8266, #$8267, #$8269, - #$826A, #$826B, #$826C, #$826D, #$8271, #$8275, #$8276, #$8277, - #$8278, #$827B, #$827C, #$8280, #$8281, #$8283, #$8285, #$8286, - #$8287, #$8289, #$828C, #$8290, #$8293, #$8294, #$8295, #$8296, - #$829A, #$829B, #$829E, #$82A0, #$82A2, #$82A3, #$82A7, #$82B2, - #$82B5, #$82B6, #$82BA, #$82BB, #$82BC, #$82BF, #$82C0, #$82C2, - #$82C3, #$82C5, #$82C6, #$82C9, #$82D0, #$82D6, #$82D9, #$82DA, - #$82DD, #$82E2, #$82E7, #$82E8, #$82E9, #$82EA, #$82EC, #$82ED, - #$82EE, #$82F0, #$82F2, #$82F3, #$82F5, #$82F6, #$82F8, #$82FA, - #$82FC, #$82FD, #$82FE, #$82FF, #$8300, #$830A, #$830B, #$830D, - #$8310, #$8312, #$8313, #$8316, #$8318, #$8319, #$831D, #$831E, - #$831F, #$8320, #$8321, #$8322, #$8323, #$8324, #$8325, #$8326, - #$8329, #$832A, #$832E, #$8330, #$8332, #$8337, #$833B, #$833D, - #$833E, #$833F, #$8341, #$8342, #$8344, #$8345, #$8348, #$834A, - #$834B, #$834C, #$834D, #$834E, #$8353, #$8355, #$8356, #$8357, - #$8358, #$8359, #$835D, #$8362, #$8370, #$8371, #$8372, #$8373, - #$8374, #$8375, #$8376, #$8379, #$837A, #$837E, #$837F, #$8380, - #$8381, #$8382, #$8383, #$8384, #$8387, #$8388, #$838A, #$838B, - #$838C, #$838D, #$838F, #$8390, #$8391, #$8394, #$8395, #$8396, - #$8397, #$8399, #$839A, #$839D, #$839F, #$83A1, #$83A2, #$83A3, - #$83A4, #$83A5, #$83A6, #$83A7, #$83AC, #$83AD, #$83AE, #$83AF, - #$83B5, #$83BB, #$83BE, #$83BF, #$83C2, #$83C3, #$83C4, #$83C6, - #$83C8, #$83C9, #$83CB, #$83CD, #$83CE, #$83D0, #$83D1, #$83D2, - #$83D3, #$83D5, #$83D7, #$83D9, #$83DA, #$83DB, #$83DE, #$83E2, - #$83E3, #$83E4, #$83E6, #$83E7, #$83E8, #$83EB, #$83EC, #$83ED, - #$83EE, #$83EF, #$83F3, #$83F4, #$83F5, #$83F6, #$83F7, #$83FA, - #$83FB, #$83FC, #$83FE, #$83FF, #$8400, #$8402, #$8405, #$8407, - #$8408, #$8409, #$840A, #$8410, #$8412, #$8413, #$8414, #$8415, - #$8416, #$8417, #$8419, #$841A, #$841B, #$841E, #$841F, #$8420, - #$8421, #$8422, #$8423, #$8429, #$842A, #$842B, #$842C, #$842D, - #$842E, #$842F, #$8430, #$8432, #$8433, #$8434, #$8435, #$8436, - #$8437, #$8439, #$843A, #$843B, #$843E, #$843F, #$8440, #$8441, - #$8442, #$8443, #$8444, #$8445, #$8447, #$8448, #$8449, #$844A, - #$844B, #$844C, #$844D, #$844E, #$844F, #$8450, #$8452, #$8453, - #$8454, #$8455, #$8456, #$8458, #$845D, #$845E, #$845F, #$8460, - #$8462, #$8464, #$8465, #$8466, #$8467, #$8468, #$846A, #$846E, - #$846F, #$8470, #$8472, #$8474, #$8477, #$8479, #$847B, #$847C, - #$847D, #$847E, #$847F, #$8480, #$8481, #$8483, #$8484, #$8485, - #$8486, #$848A, #$848D, #$848F, #$8490, #$8491, #$8492, #$8493, - #$8494, #$8495, #$8496, #$8498, #$849A, #$849B, #$849D, #$849E, - #$849F, #$84A0, #$84A2, #$84A3, #$84A4, #$84A5, #$84A6, #$84A7, - #$84A8, #$84A9, #$84AA, #$84AB, #$84AC, #$84AD, #$84AE, #$84B0, - #$84B1, #$84B3, #$84B5, #$84B6, #$84B7, #$84BB, #$84BC, #$84BE, - #$84C0, #$84C2, #$84C3, #$84C5, #$84C6, #$84C7, #$84C8, #$84CB, - #$84CC, #$84CE, #$84CF, #$84D2, #$84D4, #$84D5, #$84D7, #$84D8, - #$84D9, #$84DA, #$84DB, #$84DC, #$84DE, #$84E1, #$84E2, #$84E4, - #$84E7, #$84E8, #$84E9, #$84EA, #$84EB, #$84ED, #$84EE, #$84EF, - #$84F1, #$84F2, #$84F3, #$84F4, #$84F5, #$84F6, #$84F7, #$84F8, - #$84F9, #$84FA, #$84FB, #$84FD, #$84FE, #$8500, #$8501, #$8502, - #$8503, #$8504, #$8505, #$8506, #$8507, #$8508, #$8509, #$850A, - #$850B, #$850D, #$850E, #$850F, #$8510, #$8512, #$8514, #$8515, - #$8516, #$8518, #$8519, #$851B, #$851C, #$851D, #$851E, #$8520, - #$8522, #$8523, #$8524, #$8525, #$8526, #$8527, #$8528, #$8529, - #$852A, #$852D, #$852E, #$852F, #$8530, #$8531, #$8532, #$8533, - #$8534, #$8535, #$8536, #$853E, #$853F, #$8540, #$8541, #$8542, - #$8544, #$8545, #$8546, #$8547, #$854B, #$854C, #$854D, #$854E, - #$854F, #$8550, #$8551, #$8552, #$8553, #$8554, #$8555, #$8557, - #$8558, #$855A, #$855B, #$855C, #$855D, #$855F, #$8560, #$8561, - #$8562, #$8563, #$8565, #$8566, #$8567, #$8569, #$856A, #$856B, - #$856C, #$856D, #$856E, #$856F, #$8570, #$8571, #$8573, #$8575, - #$8576, #$8577, #$8578, #$857C, #$857D, #$857F, #$8580, #$8581, - #$8582, #$8583, #$8586, #$8588, #$8589, #$858A, #$858B, #$858C, - #$858D, #$858E, #$8590, #$8591, #$8592, #$8593, #$8594, #$8595, - #$8596, #$8597, #$8598, #$8599, #$859A, #$859D, #$859E, #$859F, - #$85A0, #$85A1, #$85A2, #$85A3, #$85A5, #$85A6, #$85A7, #$85A9, - #$85AB, #$85AC, #$85AD, #$85B1, #$85B2, #$85B3, #$85B4, #$85B5, - #$85B6, #$85B8, #$85BA, #$85BB, #$85BC, #$85BD, #$85BE, #$85BF, - #$85C0, #$85C2, #$85C3, #$85C4, #$85C5, #$85C6, #$85C7, #$85C8, - #$85CA, #$85CB, #$85CC, #$85CD, #$85CE, #$85D1, #$85D2, #$85D4, - #$85D6, #$85D7, #$85D8, #$85D9, #$85DA, #$85DB, #$85DD, #$85DE, - #$85DF, #$85E0, #$85E1, #$85E2, #$85E3, #$85E5, #$85E6, #$85E7, - #$85E8, #$85EA, #$85EB, #$85EC, #$85ED, #$85EE, #$85EF, #$85F0, - #$85F1, #$85F2, #$85F3, #$85F4, #$85F5, #$85F6, #$85F7, #$85F8, - #$85F9, #$85FA, #$85FC, #$85FD, #$85FE, #$8600, #$8601, #$8602, - #$8603, #$8604, #$8606, #$8607, #$8608, #$8609, #$860A, #$860B, - #$860C, #$860D, #$860E, #$860F, #$8610, #$8612, #$8613, #$8614, - #$8615, #$8617, #$8618, #$8619, #$861A, #$861B, #$861C, #$861D, - #$861E, #$861F, #$8620, #$8621, #$8622, #$8623, #$8624, #$8625, - #$8626, #$8628, #$862A, #$862B, #$862C, #$862D, #$862E, #$862F, - #$8630, #$8631, #$8632, #$8633, #$8634, #$8635, #$8636, #$8637, - #$8639, #$863A, #$863B, #$863D, #$863E, #$863F, #$8640, #$8641, - #$8642, #$8643, #$8644, #$8645, #$8646, #$8647, #$8648, #$8649, - #$864A, #$864B, #$864C, #$8652, #$8653, #$8655, #$8656, #$8657, - #$8658, #$8659, #$865B, #$865C, #$865D, #$865F, #$8660, #$8661, - #$8663, #$8664, #$8665, #$8666, #$8667, #$8668, #$8669, #$866A, - #$866D, #$866F, #$8670, #$8672, #$8673, #$8674, #$8675, #$8676, - #$8677, #$8678, #$8683, #$8684, #$8685, #$8686, #$8687, #$8688, - #$8689, #$868E, #$868F, #$8690, #$8691, #$8692, #$8694, #$8696, - #$8697, #$8698, #$8699, #$869A, #$869B, #$869E, #$869F, #$86A0, - #$86A1, #$86A2, #$86A5, #$86A6, #$86AB, #$86AD, #$86AE, #$86B2, - #$86B3, #$86B7, #$86B8, #$86B9, #$86BB, #$86BC, #$86BD, #$86BE, - #$86BF, #$86C1, #$86C2, #$86C3, #$86C5, #$86C8, #$86CC, #$86CD, - #$86D2, #$86D3, #$86D5, #$86D6, #$86D7, #$86DA, #$86DC, #$86DD, - #$86E0, #$86E1, #$86E2, #$86E3, #$86E5, #$86E6, #$86E7, #$86E8, - #$86EA, #$86EB, #$86EC, #$86EF, #$86F5, #$86F6, #$86F7, #$86FA, - #$86FB, #$86FC, #$86FD, #$86FF, #$8701, #$8704, #$8705, #$8706, - #$870B, #$870C, #$870E, #$870F, #$8710, #$8711, #$8714, #$8716, - #$8719, #$871B, #$871D, #$871F, #$8720, #$8724, #$8726, #$8727, - #$8728, #$872A, #$872B, #$872C, #$872D, #$872F, #$8730, #$8732, - #$8733, #$8735, #$8736, #$8738, #$8739, #$873A, #$873C, #$873D, - #$8740, #$8741, #$8742, #$8743, #$8744, #$8745, #$8746, #$874A, - #$874B, #$874D, #$874F, #$8750, #$8751, #$8752, #$8754, #$8755, - #$8756, #$8758, #$875A, #$875B, #$875C, #$875D, #$875E, #$875F, - #$8761, #$8762, #$8766, #$8767, #$8768, #$8769, #$876A, #$876B, - #$876C, #$876D, #$876F, #$8771, #$8772, #$8773, #$8775, #$8777, - #$8778, #$8779, #$877A, #$877F, #$8780, #$8781, #$8784, #$8786, - #$8787, #$8789, #$878A, #$878C, #$878E, #$878F, #$8790, #$8791, - #$8792, #$8794, #$8795, #$8796, #$8798, #$8799, #$879A, #$879B, - #$879C, #$879D, #$879E, #$87A0, #$87A1, #$87A2, #$87A3, #$87A4, - #$87A5, #$87A6, #$87A7, #$87A9, #$87AA, #$87AE, #$87B0, #$87B1, - #$87B2, #$87B4, #$87B6, #$87B7, #$87B8, #$87B9, #$87BB, #$87BC, - #$87BE, #$87BF, #$87C1, #$87C2, #$87C3, #$87C4, #$87C5, #$87C7, - #$87C8, #$87C9, #$87CC, #$87CD, #$87CE, #$87CF, #$87D0, #$87D4, - #$87D5, #$87D6, #$87D7, #$87D8, #$87D9, #$87DA, #$87DC, #$87DD, - #$87DE, #$87DF, #$87E1, #$87E2, #$87E3, #$87E4, #$87E6, #$87E7, - #$87E8, #$87E9, #$87EB, #$87EC, #$87ED, #$87EF, #$87F0, #$87F1, - #$87F2, #$87F3, #$87F4, #$87F5, #$87F6, #$87F7, #$87F8, #$87FA, - #$87FB, #$87FC, #$87FD, #$87FF, #$8800, #$8801, #$8802, #$8804, - #$8805, #$8806, #$8807, #$8808, #$8809, #$880B, #$880C, #$880D, - #$880E, #$880F, #$8810, #$8811, #$8812, #$8814, #$8817, #$8818, - #$8819, #$881A, #$881C, #$881D, #$881E, #$881F, #$8820, #$8823, - #$8824, #$8825, #$8826, #$8827, #$8828, #$8829, #$882A, #$882B, - #$882C, #$882D, #$882E, #$882F, #$8830, #$8831, #$8833, #$8834, - #$8835, #$8836, #$8837, #$8838, #$883A, #$883B, #$883D, #$883E, - #$883F, #$8841, #$8842, #$8843, #$8846, #$8847, #$8848, #$8849, - #$884A, #$884B, #$884E, #$884F, #$8850, #$8851, #$8852, #$8853, - #$8855, #$8856, #$8858, #$885A, #$885B, #$885C, #$885D, #$885E, - #$885F, #$8860, #$8866, #$8867, #$886A, #$886D, #$886F, #$8871, - #$8873, #$8874, #$8875, #$8876, #$8878, #$8879, #$887A, #$887B, - #$887C, #$8880, #$8883, #$8886, #$8887, #$8889, #$888A, #$888C, - #$888E, #$888F, #$8890, #$8891, #$8893, #$8894, #$8895, #$8897, - #$8898, #$8899, #$889A, #$889B, #$889D, #$889E, #$889F, #$88A0, - #$88A1, #$88A3, #$88A5, #$88A6, #$88A7, #$88A8, #$88A9, #$88AA, - #$88AC, #$88AE, #$88AF, #$88B0, #$88B2, #$88B3, #$88B4, #$88B5, - #$88B6, #$88B8, #$88B9, #$88BA, #$88BB, #$88BD, #$88BE, #$88BF, - #$88C0, #$88C3, #$88C4, #$88C7, #$88C8, #$88CA, #$88CB, #$88CC, - #$88CD, #$88CF, #$88D0, #$88D1, #$88D3, #$88D6, #$88D7, #$88DA, - #$88DB, #$88DC, #$88DD, #$88DE, #$88E0, #$88E1, #$88E6, #$88E7, - #$88E9, #$88EA, #$88EB, #$88EC, #$88ED, #$88EE, #$88EF, #$88F2, - #$88F5, #$88F6, #$88F7, #$88FA, #$88FB, #$88FD, #$88FF, #$8900, - #$8901, #$8903, #$8904, #$8905, #$8906, #$8907, #$8908, #$8909, - #$890B, #$890C, #$890D, #$890E, #$890F, #$8911, #$8914, #$8915, - #$8916, #$8917, #$8918, #$891C, #$891D, #$891E, #$891F, #$8920, - #$8922, #$8923, #$8924, #$8926, #$8927, #$8928, #$8929, #$892C, - #$892D, #$892E, #$892F, #$8931, #$8932, #$8933, #$8935, #$8937, - #$8938, #$8939, #$893A, #$893B, #$893C, #$893D, #$893E, #$893F, - #$8940, #$8942, #$8943, #$8945, #$8946, #$8947, #$8948, #$8949, - #$894A, #$894B, #$894C, #$894D, #$894E, #$894F, #$8950, #$8951, - #$8952, #$8953, #$8954, #$8955, #$8956, #$8957, #$8958, #$8959, - #$895A, #$895B, #$895C, #$895D, #$8960, #$8961, #$8962, #$8963, - #$8964, #$8965, #$8967, #$8968, #$8969, #$896A, #$896B, #$896C, - #$896D, #$896E, #$896F, #$8970, #$8971, #$8972, #$8973, #$8974, - #$8975, #$8976, #$8977, #$8978, #$8979, #$897A, #$897C, #$897D, - #$897E, #$8980, #$8982, #$8984, #$8985, #$8987, #$8988, #$8989, - #$898A, #$898B, #$898C, #$898D, #$898E, #$898F, #$8990, #$8991, - #$8992, #$8993, #$8994, #$8995, #$8996, #$8997, #$8998, #$8999, - #$899A, #$899B, #$899C, #$899D, #$899E, #$899F, #$89A0, #$89A1, - #$89A2, #$89A3, #$89A4, #$89A5, #$89A6, #$89A7, #$89A8, #$89A9, - #$89AA, #$89AB, #$89AC, #$89AD, #$89AE, #$89AF, #$89B0, #$89B1, - #$89B2, #$89B3, #$89B4, #$89B5, #$89B6, #$89B7, #$89B8, #$89B9, - #$89BA, #$89BB, #$89BC, #$89BD, #$89BE, #$89BF, #$89C0, #$89C3, - #$89CD, #$89D3, #$89D4, #$89D5, #$89D7, #$89D8, #$89D9, #$89DB, - #$89DD, #$89DF, #$89E0, #$89E1, #$89E2, #$89E4, #$89E7, #$89E8, - #$89E9, #$89EA, #$89EC, #$89ED, #$89EE, #$89F0, #$89F1, #$89F2, - #$89F4, #$89F5, #$89F6, #$89F7, #$89F8, #$89F9, #$89FA, #$89FB, - #$89FC, #$89FD, #$89FE, #$89FF, #$8A01, #$8A02, #$8A03, #$8A04, - #$8A05, #$8A06, #$8A08, #$8A09, #$8A0A, #$8A0B, #$8A0C, #$8A0D, - #$8A0E, #$8A0F, #$8A10, #$8A11, #$8A12, #$8A13, #$8A14, #$8A15, - #$8A16, #$8A17, #$8A18, #$8A19, #$8A1A, #$8A1B, #$8A1C, #$8A1D, - #$8A1E, #$8A1F, #$8A20, #$8A21, #$8A22, #$8A23, #$8A24, #$8A25, - #$8A26, #$8A27, #$8A28, #$8A29, #$8A2A, #$8A2B, #$8A2C, #$8A2D, - #$8A2E, #$8A2F, #$8A30, #$8A31, #$8A32, #$8A33, #$8A34, #$8A35, - #$8A36, #$8A37, #$8A38, #$8A39, #$8A3A, #$8A3B, #$8A3C, #$8A3D, - #$8A3F, #$8A40, #$8A41, #$8A42, #$8A43, #$8A44, #$8A45, #$8A46, - #$8A47, #$8A49, #$8A4A, #$8A4B, #$8A4C, #$8A4D, #$8A4E, #$8A4F, - #$8A50, #$8A51, #$8A52, #$8A53, #$8A54, #$8A55, #$8A56, #$8A57, - #$8A58, #$8A59, #$8A5A, #$8A5B, #$8A5C, #$8A5D, #$8A5E, #$8A5F, - #$8A60, #$8A61, #$8A62, #$8A63, #$8A64, #$8A65, #$8A66, #$8A67, - #$8A68, #$8A69, #$8A6A, #$8A6B, #$8A6C, #$8A6D, #$8A6E, #$8A6F, - #$8A70, #$8A71, #$8A72, #$8A73, #$8A74, #$8A75, #$8A76, #$8A77, - #$8A78, #$8A7A, #$8A7B, #$8A7C, #$8A7D, #$8A7E, #$8A7F, #$8A80, - #$8A81, #$8A82, #$8A83, #$8A84, #$8A85, #$8A86, #$8A87, #$8A88, - #$8A8B, #$8A8C, #$8A8D, #$8A8E, #$8A8F, #$8A90, #$8A91, #$8A92, - #$8A94, #$8A95, #$8A96, #$8A97, #$8A98, #$8A99, #$8A9A, #$8A9B, - #$8A9C, #$8A9D, #$8A9E, #$8A9F, #$8AA0, #$8AA1, #$8AA2, #$8AA3, - #$8AA4, #$8AA5, #$8AA6, #$8AA7, #$8AA8, #$8AA9, #$8AAA, #$8AAB, - #$8AAC, #$8AAD, #$8AAE, #$8AAF, #$8AB0, #$8AB1, #$8AB2, #$8AB3, - #$8AB4, #$8AB5, #$8AB6, #$8AB7, #$8AB8, #$8AB9, #$8ABA, #$8ABB, - #$8ABC, #$8ABD, #$8ABE, #$8ABF, #$8AC0, #$8AC1, #$8AC2, #$8AC3, - #$8AC4, #$8AC5, #$8AC6, #$8AC7, #$8AC8, #$8AC9, #$8ACA, #$8ACB, - #$8ACC, #$8ACD, #$8ACE, #$8ACF, #$8AD0, #$8AD1, #$8AD2, #$8AD3, - #$8AD4, #$8AD5, #$8AD6, #$8AD7, #$8AD8, #$8AD9, #$8ADA, #$8ADB, - #$8ADC, #$8ADD, #$8ADE, #$8ADF, #$8AE0, #$8AE1, #$8AE2, #$8AE3, - #$8AE4, #$8AE5, #$8AE6, #$8AE7, #$8AE8, #$8AE9, #$8AEA, #$8AEB, - #$8AEC, #$8AED, #$8AEE, #$8AEF, #$8AF0, #$8AF1, #$8AF2, #$8AF3, - #$8AF4, #$8AF5, #$8AF6, #$8AF7, #$8AF8, #$8AF9, #$8AFA, #$8AFB, - #$8AFC, #$8AFD, #$8AFE, #$8AFF, #$8B00, #$8B01, #$8B02, #$8B03, - #$8B04, #$8B05, #$8B06, #$8B08, #$8B09, #$8B0A, #$8B0B, #$8B0C, - #$8B0D, #$8B0E, #$8B0F, #$8B10, #$8B11, #$8B12, #$8B13, #$8B14, - #$8B15, #$8B16, #$8B17, #$8B18, #$8B19, #$8B1A, #$8B1B, #$8B1C, - #$8B1D, #$8B1E, #$8B1F, #$8B20, #$8B21, #$8B22, #$8B23, #$8B24, - #$8B25, #$8B27, #$8B28, #$8B29, #$8B2A, #$8B2B, #$8B2C, #$8B2D, - #$8B2E, #$8B2F, #$8B30, #$8B31, #$8B32, #$8B33, #$8B34, #$8B35, - #$8B36, #$8B37, #$8B38, #$8B39, #$8B3A, #$8B3B, #$8B3C, #$8B3D, - #$8B3E, #$8B3F, #$8B40, #$8B41, #$8B42, #$8B43, #$8B44, #$8B45, - #$8B46, #$8B47, #$8B48, #$8B49, #$8B4A, #$8B4B, #$8B4C, #$8B4D, - #$8B4E, #$8B4F, #$8B50, #$8B51, #$8B52, #$8B53, #$8B54, #$8B55, - #$8B56, #$8B57, #$8B58, #$8B59, #$8B5A, #$8B5B, #$8B5C, #$8B5D, - #$8B5E, #$8B5F, #$8B60, #$8B61, #$8B62, #$8B63, #$8B64, #$8B65, - #$8B67, #$8B68, #$8B69, #$8B6A, #$8B6B, #$8B6D, #$8B6E, #$8B6F, - #$8B70, #$8B71, #$8B72, #$8B73, #$8B74, #$8B75, #$8B76, #$8B77, - #$8B78, #$8B79, #$8B7A, #$8B7B, #$8B7C, #$8B7D, #$8B7E, #$8B7F, - #$8B80, #$8B81, #$8B82, #$8B83, #$8B84, #$8B85, #$8B86, #$8B87, - #$8B88, #$8B89, #$8B8A, #$8B8B, #$8B8C, #$8B8D, #$8B8E, #$8B8F, - #$8B90, #$8B91, #$8B92, #$8B93, #$8B94, #$8B95, #$8B96, #$8B97, - #$8B98, #$8B99, #$8B9A, #$8B9B, #$8B9C, #$8B9D, #$8B9E, #$8B9F, - #$8BAC, #$8BB1, #$8BBB, #$8BC7, #$8BD0, #$8BEA, #$8C09, #$8C1E, - #$8C38, #$8C39, #$8C3A, #$8C3B, #$8C3C, #$8C3D, #$8C3E, #$8C3F, - #$8C40, #$8C42, #$8C43, #$8C44, #$8C45, #$8C48, #$8C4A, #$8C4B, - #$8C4D, #$8C4E, #$8C4F, #$8C50, #$8C51, #$8C52, #$8C53, #$8C54, - #$8C56, #$8C57, #$8C58, #$8C59, #$8C5B, #$8C5C, #$8C5D, #$8C5E, - #$8C5F, #$8C60, #$8C63, #$8C64, #$8C65, #$8C66, #$8C67, #$8C68, - #$8C69, #$8C6C, #$8C6D, #$8C6E, #$8C6F, #$8C70, #$8C71, #$8C72, - #$8C74, #$8C75, #$8C76, #$8C77, #$8C7B, #$8C7C, #$8C7D, #$8C7E, - #$8C7F, #$8C80, #$8C81, #$8C83, #$8C84, #$8C86, #$8C87, #$8C88, - #$8C8B, #$8C8D, #$8C8E, #$8C8F, #$8C90, #$8C91, #$8C92, #$8C93, - #$8C95, #$8C96, #$8C97, #$8C99, #$8C9A, #$8C9B, #$8C9C, #$8C9D, - #$8C9E, #$8C9F, #$8CA0, #$8CA1, #$8CA2, #$8CA3, #$8CA4, #$8CA5, - #$8CA6, #$8CA7, #$8CA8, #$8CA9, #$8CAA, #$8CAB, #$8CAC, #$8CAD, - #$8CAE, #$8CAF, #$8CB0, #$8CB1, #$8CB2, #$8CB3, #$8CB4, #$8CB5, - #$8CB6, #$8CB7, #$8CB8, #$8CB9, #$8CBA, #$8CBB, #$8CBC, #$8CBD, - #$8CBE, #$8CBF, #$8CC0, #$8CC1, #$8CC2, #$8CC3, #$8CC4, #$8CC5, - #$8CC6, #$8CC7, #$8CC8, #$8CC9, #$8CCA, #$8CCB, #$8CCC, #$8CCD, - #$8CCE, #$8CCF, #$8CD0, #$8CD1, #$8CD2, #$8CD3, #$8CD4, #$8CD5, - #$8CD6, #$8CD7, #$8CD8, #$8CD9, #$8CDA, #$8CDB, #$8CDC, #$8CDD, - #$8CDE, #$8CDF, #$8CE0, #$8CE1, #$8CE2, #$8CE3, #$8CE4, #$8CE5, - #$8CE6, #$8CE7, #$8CE8, #$8CE9, #$8CEA, #$8CEB, #$8CEC, #$8CED, - #$8CEE, #$8CEF, #$8CF0, #$8CF1, #$8CF2, #$8CF3, #$8CF4, #$8CF5, - #$8CF6, #$8CF7, #$8CF8, #$8CF9, #$8CFA, #$8CFB, #$8CFC, #$8CFD, - #$8CFE, #$8CFF, #$8D00, #$8D01, #$8D02, #$8D03, #$8D04, #$8D05, - #$8D06, #$8D07, #$8D08, #$8D09, #$8D0A, #$8D0B, #$8D0C, #$8D0D, - #$8D0E, #$8D0F, #$8D10, #$8D11, #$8D12, #$8D13, #$8D14, #$8D15, - #$8D16, #$8D17, #$8D18, #$8D19, #$8D1A, #$8D1B, #$8D1C, #$8D20, - #$8D51, #$8D52, #$8D57, #$8D5F, #$8D65, #$8D68, #$8D69, #$8D6A, - #$8D6C, #$8D6E, #$8D6F, #$8D71, #$8D72, #$8D78, #$8D79, #$8D7A, - #$8D7B, #$8D7C, #$8D7D, #$8D7E, #$8D7F, #$8D80, #$8D82, #$8D83, - #$8D86, #$8D87, #$8D88, #$8D89, #$8D8C, #$8D8D, #$8D8E, #$8D8F, - #$8D90, #$8D92, #$8D93, #$8D95, #$8D96, #$8D97, #$8D98, #$8D99, - #$8D9A, #$8D9B, #$8D9C, #$8D9D, #$8D9E, #$8DA0, #$8DA1, #$8DA2, - #$8DA4, #$8DA5, #$8DA6, #$8DA7, #$8DA8, #$8DA9, #$8DAA, #$8DAB, - #$8DAC, #$8DAD, #$8DAE, #$8DAF, #$8DB0, #$8DB2, #$8DB6, #$8DB7, - #$8DB9, #$8DBB, #$8DBD, #$8DC0, #$8DC1, #$8DC2, #$8DC5, #$8DC7, - #$8DC8, #$8DC9, #$8DCA, #$8DCD, #$8DD0, #$8DD2, #$8DD3, #$8DD4, - #$8DD5, #$8DD8, #$8DD9, #$8DDC, #$8DE0, #$8DE1, #$8DE2, #$8DE5, - #$8DE6, #$8DE7, #$8DE9, #$8DED, #$8DEE, #$8DF0, #$8DF1, #$8DF2, - #$8DF4, #$8DF6, #$8DFC, #$8DFE, #$8DFF, #$8E00, #$8E01, #$8E02, - #$8E03, #$8E04, #$8E06, #$8E07, #$8E08, #$8E0B, #$8E0D, #$8E0E, - #$8E10, #$8E11, #$8E12, #$8E13, #$8E15, #$8E16, #$8E17, #$8E18, - #$8E19, #$8E1A, #$8E1B, #$8E1C, #$8E20, #$8E21, #$8E24, #$8E25, - #$8E26, #$8E27, #$8E28, #$8E2B, #$8E2D, #$8E30, #$8E32, #$8E33, - #$8E34, #$8E36, #$8E37, #$8E38, #$8E3B, #$8E3C, #$8E3E, #$8E3F, - #$8E43, #$8E45, #$8E46, #$8E4C, #$8E4D, #$8E4E, #$8E4F, #$8E50, - #$8E53, #$8E54, #$8E55, #$8E56, #$8E57, #$8E58, #$8E5A, #$8E5B, - #$8E5C, #$8E5D, #$8E5E, #$8E5F, #$8E60, #$8E61, #$8E62, #$8E63, - #$8E64, #$8E65, #$8E67, #$8E68, #$8E6A, #$8E6B, #$8E6E, #$8E71, - #$8E73, #$8E75, #$8E77, #$8E78, #$8E79, #$8E7A, #$8E7B, #$8E7D, - #$8E7E, #$8E80, #$8E82, #$8E83, #$8E84, #$8E86, #$8E88, #$8E89, - #$8E8A, #$8E8B, #$8E8C, #$8E8D, #$8E8E, #$8E91, #$8E92, #$8E93, - #$8E95, #$8E96, #$8E97, #$8E98, #$8E99, #$8E9A, #$8E9B, #$8E9D, - #$8E9F, #$8EA0, #$8EA1, #$8EA2, #$8EA3, #$8EA4, #$8EA5, #$8EA6, - #$8EA7, #$8EA8, #$8EA9, #$8EAA, #$8EAD, #$8EAE, #$8EB0, #$8EB1, - #$8EB3, #$8EB4, #$8EB5, #$8EB6, #$8EB7, #$8EB8, #$8EB9, #$8EBB, - #$8EBC, #$8EBD, #$8EBE, #$8EBF, #$8EC0, #$8EC1, #$8EC2, #$8EC3, - #$8EC4, #$8EC5, #$8EC6, #$8EC7, #$8EC8, #$8EC9, #$8ECA, #$8ECB, - #$8ECC, #$8ECD, #$8ECF, #$8ED0, #$8ED1, #$8ED2, #$8ED3, #$8ED4, - #$8ED5, #$8ED6, #$8ED7, #$8ED8, #$8ED9, #$8EDA, #$8EDB, #$8EDC, - #$8EDD, #$8EDE, #$8EDF, #$8EE0, #$8EE1, #$8EE2, #$8EE3, #$8EE4, - #$8EE5, #$8EE6, #$8EE7, #$8EE8, #$8EE9, #$8EEA, #$8EEB, #$8EEC, - #$8EED, #$8EEE, #$8EEF, #$8EF0, #$8EF1, #$8EF2, #$8EF3, #$8EF4, - #$8EF5, #$8EF6, #$8EF7, #$8EF8, #$8EF9, #$8EFA, #$8EFB, #$8EFC, - #$8EFD, #$8EFE, #$8EFF, #$8F00, #$8F01, #$8F02, #$8F03, #$8F04, - #$8F05, #$8F06, #$8F07, #$8F08, #$8F09, #$8F0A, #$8F0B, #$8F0C, - #$8F0D, #$8F0E, #$8F0F, #$8F10, #$8F11, #$8F12, #$8F13, #$8F14, - #$8F15, #$8F16, #$8F17, #$8F18, #$8F19, #$8F1A, #$8F1B, #$8F1C, - #$8F1D, #$8F1E, #$8F1F, #$8F20, #$8F21, #$8F22, #$8F23, #$8F24, - #$8F25, #$8F26, #$8F27, #$8F28, #$8F29, #$8F2A, #$8F2B, #$8F2C, - #$8F2D, #$8F2E, #$8F2F, #$8F30, #$8F31, #$8F32, #$8F33, #$8F34, - #$8F35, #$8F36, #$8F37, #$8F38, #$8F39, #$8F3A, #$8F3B, #$8F3C, - #$8F3D, #$8F3E, #$8F3F, #$8F40, #$8F41, #$8F42, #$8F43, #$8F44, - #$8F45, #$8F46, #$8F47, #$8F48, #$8F49, #$8F4A, #$8F4B, #$8F4C, - #$8F4D, #$8F4E, #$8F4F, #$8F50, #$8F51, #$8F52, #$8F53, #$8F54, - #$8F55, #$8F56, #$8F57, #$8F58, #$8F59, #$8F5A, #$8F5B, #$8F5C, - #$8F5D, #$8F5E, #$8F5F, #$8F60, #$8F61, #$8F62, #$8F63, #$8F64, - #$8F65, #$8F6A, #$8F80, #$8F8C, #$8F92, #$8F9D, #$8FA0, #$8FA1, - #$8FA2, #$8FA4, #$8FA5, #$8FA6, #$8FA7, #$8FAA, #$8FAC, #$8FAD, - #$8FAE, #$8FAF, #$8FB2, #$8FB3, #$8FB4, #$8FB5, #$8FB7, #$8FB8, - #$8FBA, #$8FBB, #$8FBC, #$8FBF, #$8FC0, #$8FC3, #$8FC6, #$8FC9, - #$8FCA, #$8FCB, #$8FCC, #$8FCD, #$8FCF, #$8FD2, #$8FD6, #$8FD7, - #$8FDA, #$8FE0, #$8FE1, #$8FE3, #$8FE7, #$8FEC, #$8FEF, #$8FF1, - #$8FF2, #$8FF4, #$8FF5, #$8FF6, #$8FFA, #$8FFB, #$8FFC, #$8FFE, - #$8FFF, #$9007, #$9008, #$900C, #$900E, #$9013, #$9015, #$9018, - #$9019, #$901C, #$9023, #$9024, #$9025, #$9027, #$9028, #$9029, - #$902A, #$902B, #$902C, #$9030, #$9031, #$9032, #$9033, #$9034, - #$9037, #$9039, #$903A, #$903D, #$903F, #$9040, #$9043, #$9045, - #$9046, #$9048, #$9049, #$904A, #$904B, #$904C, #$904E, #$9054, - #$9055, #$9056, #$9059, #$905A, #$905C, #$905D, #$905E, #$905F, - #$9060, #$9061, #$9064, #$9066, #$9067, #$9069, #$906A, #$906B, - #$906C, #$906F, #$9070, #$9071, #$9072, #$9073, #$9076, #$9077, - #$9078, #$9079, #$907A, #$907B, #$907C, #$907E, #$9081, #$9084, - #$9085, #$9086, #$9087, #$9089, #$908A, #$908C, #$908D, #$908E, - #$908F, #$9090, #$9092, #$9094, #$9096, #$9098, #$909A, #$909C, - #$909E, #$909F, #$90A0, #$90A4, #$90A5, #$90A7, #$90A8, #$90A9, - #$90AB, #$90AD, #$90B2, #$90B7, #$90BC, #$90BD, #$90BF, #$90C0, - #$90C2, #$90C3, #$90C6, #$90C8, #$90C9, #$90CB, #$90CC, #$90CD, - #$90D2, #$90D4, #$90D5, #$90D6, #$90D8, #$90D9, #$90DA, #$90DE, - #$90DF, #$90E0, #$90E3, #$90E4, #$90E5, #$90E9, #$90EA, #$90EC, - #$90EE, #$90F0, #$90F1, #$90F2, #$90F3, #$90F5, #$90F6, #$90F7, - #$90F9, #$90FA, #$90FB, #$90FC, #$90FF, #$9100, #$9101, #$9103, - #$9105, #$9106, #$9107, #$9108, #$9109, #$910A, #$910B, #$910C, - #$910D, #$910E, #$910F, #$9110, #$9111, #$9112, #$9113, #$9114, - #$9115, #$9116, #$9117, #$9118, #$911A, #$911B, #$911C, #$911D, - #$911F, #$9120, #$9121, #$9124, #$9125, #$9126, #$9127, #$9128, - #$9129, #$912A, #$912B, #$912C, #$912D, #$912E, #$9130, #$9132, - #$9133, #$9134, #$9135, #$9136, #$9137, #$9138, #$913A, #$913B, - #$913C, #$913D, #$913E, #$913F, #$9140, #$9141, #$9142, #$9144, - #$9145, #$9147, #$9148, #$9151, #$9153, #$9154, #$9155, #$9156, - #$9158, #$9159, #$915B, #$915C, #$915F, #$9160, #$9166, #$9167, - #$9168, #$916B, #$916D, #$9173, #$917A, #$917B, #$917C, #$9180, - #$9181, #$9182, #$9183, #$9184, #$9186, #$9188, #$918A, #$918E, - #$918F, #$9193, #$9194, #$9195, #$9196, #$9197, #$9198, #$9199, - #$919C, #$919D, #$919E, #$919F, #$91A0, #$91A1, #$91A4, #$91A5, - #$91A6, #$91A7, #$91A8, #$91A9, #$91AB, #$91AC, #$91B0, #$91B1, - #$91B2, #$91B3, #$91B6, #$91B7, #$91B8, #$91B9, #$91BB, #$91BC, - #$91BD, #$91BE, #$91BF, #$91C0, #$91C1, #$91C2, #$91C3, #$91C4, - #$91C5, #$91C6, #$91C8, #$91CB, #$91D0, #$91D2, #$91D3, #$91D4, - #$91D5, #$91D6, #$91D7, #$91D8, #$91D9, #$91DA, #$91DB, #$91DD, - #$91DE, #$91DF, #$91E0, #$91E1, #$91E2, #$91E3, #$91E4, #$91E5, - #$91E6, #$91E7, #$91E8, #$91E9, #$91EA, #$91EB, #$91EC, #$91ED, - #$91EE, #$91EF, #$91F0, #$91F1, #$91F2, #$91F3, #$91F4, #$91F5, - #$91F6, #$91F7, #$91F8, #$91F9, #$91FA, #$91FB, #$91FC, #$91FD, - #$91FE, #$91FF, #$9200, #$9201, #$9202, #$9203, #$9204, #$9205, - #$9206, #$9207, #$9208, #$9209, #$920A, #$920B, #$920C, #$920D, - #$920E, #$920F, #$9210, #$9211, #$9212, #$9213, #$9214, #$9215, - #$9216, #$9217, #$9218, #$9219, #$921A, #$921B, #$921C, #$921D, - #$921E, #$921F, #$9220, #$9221, #$9222, #$9223, #$9224, #$9225, - #$9226, #$9227, #$9228, #$9229, #$922A, #$922B, #$922C, #$922D, - #$922E, #$922F, #$9230, #$9231, #$9232, #$9233, #$9234, #$9235, - #$9236, #$9237, #$9238, #$9239, #$923A, #$923B, #$923C, #$923D, - #$923E, #$923F, #$9240, #$9241, #$9242, #$9243, #$9244, #$9245, - #$9246, #$9247, #$9248, #$9249, #$924A, #$924B, #$924C, #$924D, - #$924E, #$924F, #$9250, #$9251, #$9252, #$9253, #$9254, #$9255, - #$9256, #$9257, #$9258, #$9259, #$925A, #$925B, #$925C, #$925D, - #$925E, #$925F, #$9260, #$9261, #$9262, #$9263, #$9264, #$9265, - #$9266, #$9267, #$9268, #$9269, #$926A, #$926B, #$926C, #$926D, - #$926E, #$926F, #$9270, #$9271, #$9272, #$9273, #$9275, #$9276, - #$9277, #$9278, #$9279, #$927A, #$927B, #$927C, #$927D, #$927E, - #$927F, #$9280, #$9281, #$9282, #$9283, #$9284, #$9285, #$9286, - #$9287, #$9288, #$9289, #$928A, #$928B, #$928C, #$928D, #$928F, - #$9290, #$9291, #$9292, #$9293, #$9294, #$9295, #$9296, #$9297, - #$9298, #$9299, #$929A, #$929B, #$929C, #$929D, #$929E, #$929F, - #$92A0, #$92A1, #$92A2, #$92A3, #$92A4, #$92A5, #$92A6, #$92A7, - #$92A8, #$92A9, #$92AA, #$92AB, #$92AC, #$92AD, #$92AF, #$92B0, - #$92B1, #$92B2, #$92B3, #$92B4, #$92B5, #$92B6, #$92B7, #$92B8, - #$92B9, #$92BA, #$92BB, #$92BC, #$92BD, #$92BE, #$92BF, #$92C0, - #$92C1, #$92C2, #$92C3, #$92C4, #$92C5, #$92C6, #$92C7, #$92C9, - #$92CA, #$92CB, #$92CC, #$92CD, #$92CE, #$92CF, #$92D0, #$92D1, - #$92D2, #$92D3, #$92D4, #$92D5, #$92D6, #$92D7, #$92D8, #$92D9, - #$92DA, #$92DB, #$92DC, #$92DD, #$92DE, #$92DF, #$92E0, #$92E1, - #$92E2, #$92E3, #$92E4, #$92E5, #$92E6, #$92E7, #$92E8, #$92E9, - #$92EA, #$92EB, #$92EC, #$92ED, #$92EE, #$92EF, #$92F0, #$92F1, - #$92F2, #$92F3, #$92F4, #$92F5, #$92F6, #$92F7, #$92F8, #$92F9, - #$92FA, #$92FB, #$92FC, #$92FD, #$92FE, #$92FF, #$9300, #$9301, - #$9302, #$9303, #$9304, #$9305, #$9306, #$9307, #$9308, #$9309, - #$930A, #$930B, #$930C, #$930D, #$930E, #$930F, #$9310, #$9311, - #$9312, #$9313, #$9314, #$9315, #$9316, #$9317, #$9318, #$9319, - #$931A, #$931B, #$931C, #$931D, #$931E, #$931F, #$9320, #$9321, - #$9322, #$9323, #$9324, #$9325, #$9326, #$9327, #$9328, #$9329, - #$932A, #$932B, #$932C, #$932D, #$932E, #$932F, #$9330, #$9331, - #$9332, #$9333, #$9334, #$9335, #$9336, #$9337, #$9338, #$9339, - #$933A, #$933B, #$933C, #$933D, #$933F, #$9340, #$9341, #$9342, - #$9343, #$9344, #$9345, #$9346, #$9347, #$9348, #$9349, #$934A, - #$934B, #$934C, #$934D, #$934E, #$934F, #$9350, #$9351, #$9352, - #$9353, #$9354, #$9355, #$9356, #$9357, #$9358, #$9359, #$935A, - #$935B, #$935C, #$935D, #$935E, #$935F, #$9360, #$9361, #$9362, - #$9363, #$9364, #$9365, #$9366, #$9367, #$9368, #$9369, #$936B, - #$936C, #$936D, #$936E, #$936F, #$9370, #$9371, #$9372, #$9373, - #$9374, #$9375, #$9376, #$9377, #$9378, #$9379, #$937A, #$937B, - #$937C, #$937D, #$937E, #$937F, #$9380, #$9381, #$9382, #$9383, - #$9384, #$9385, #$9386, #$9387, #$9388, #$9389, #$938A, #$938B, - #$938C, #$938D, #$938E, #$9390, #$9391, #$9392, #$9393, #$9394, - #$9395, #$9396, #$9397, #$9398, #$9399, #$939A, #$939B, #$939C, - #$939D, #$939E, #$939F, #$93A0, #$93A1, #$93A2, #$93A3, #$93A4, - #$93A5, #$93A6, #$93A7, #$93A8, #$93A9, #$93AA, #$93AB, #$93AC, - #$93AD, #$93AE, #$93AF, #$93B0, #$93B1, #$93B2, #$93B3, #$93B4, - #$93B5, #$93B6, #$93B7, #$93B8, #$93B9, #$93BA, #$93BB, #$93BC, - #$93BD, #$93BE, #$93BF, #$93C0, #$93C1, #$93C2, #$93C3, #$93C4, - #$93C5, #$93C6, #$93C7, #$93C8, #$93C9, #$93CB, #$93CC, #$93CD, - #$93CE, #$93CF, #$93D0, #$93D1, #$93D2, #$93D3, #$93D4, #$93D5, - #$93D7, #$93D8, #$93D9, #$93DA, #$93DB, #$93DC, #$93DD, #$93DE, - #$93DF, #$93E0, #$93E1, #$93E2, #$93E3, #$93E4, #$93E5, #$93E6, - #$93E7, #$93E8, #$93E9, #$93EA, #$93EB, #$93EC, #$93ED, #$93EE, - #$93EF, #$93F0, #$93F1, #$93F2, #$93F3, #$93F4, #$93F5, #$93F6, - #$93F7, #$93F8, #$93F9, #$93FA, #$93FB, #$93FC, #$93FD, #$93FE, - #$93FF, #$9400, #$9401, #$9402, #$9403, #$9404, #$9405, #$9406, - #$9407, #$9408, #$9409, #$940A, #$940B, #$940C, #$940D, #$940E, - #$940F, #$9410, #$9411, #$9412, #$9413, #$9414, #$9415, #$9416, - #$9417, #$9418, #$9419, #$941A, #$941B, #$941C, #$941D, #$941E, - #$941F, #$9420, #$9421, #$9422, #$9423, #$9424, #$9425, #$9426, - #$9427, #$9428, #$9429, #$942A, #$942B, #$942C, #$942D, #$942E, - #$942F, #$9430, #$9431, #$9432, #$9433, #$9434, #$9435, #$9436, - #$9437, #$9438, #$9439, #$943A, #$943B, #$943C, #$943D, #$943F, - #$9440, #$9441, #$9442, #$9443, #$9444, #$9445, #$9446, #$9447, - #$9448, #$9449, #$944A, #$944B, #$944C, #$944D, #$944E, #$944F, - #$9450, #$9451, #$9452, #$9453, #$9454, #$9455, #$9456, #$9457, - #$9458, #$9459, #$945A, #$945B, #$945C, #$945D, #$945E, #$945F, - #$9460, #$9461, #$9462, #$9463, #$9464, #$9465, #$9466, #$9467, - #$9468, #$9469, #$946A, #$946C, #$946D, #$946E, #$946F, #$9470, - #$9471, #$9472, #$9473, #$9474, #$9475, #$9476, #$9477, #$9478, - #$9479, #$947A, #$947B, #$947C, #$947D, #$947E, #$947F, #$9480, - #$9481, #$9482, #$9483, #$9484, #$9491, #$9496, #$9498, #$94C7, - #$94CF, #$94D3, #$94D4, #$94DA, #$94E6, #$94FB, #$951C, #$9520, - #$9527, #$9533, #$953D, #$9543, #$9548, #$954B, #$9555, #$955A, - #$9560, #$956E, #$9574, #$9575, #$9577, #$9578, #$9579, #$957A, - #$957B, #$957C, #$957D, #$957E, #$9580, #$9581, #$9582, #$9583, - #$9584, #$9585, #$9586, #$9587, #$9588, #$9589, #$958A, #$958B, - #$958C, #$958D, #$958E, #$958F, #$9590, #$9591, #$9592, #$9593, - #$9594, #$9595, #$9596, #$9597, #$9598, #$9599, #$959A, #$959B, - #$959C, #$959D, #$959E, #$959F, #$95A0, #$95A1, #$95A2, #$95A3, - #$95A4, #$95A5, #$95A6, #$95A7, #$95A8, #$95A9, #$95AA, #$95AB, - #$95AC, #$95AD, #$95AE, #$95AF, #$95B0, #$95B1, #$95B2, #$95B3, - #$95B4, #$95B5, #$95B6, #$95B7, #$95B8, #$95B9, #$95BA, #$95BB, - #$95BC, #$95BD, #$95BE, #$95BF, #$95C0, #$95C1, #$95C2, #$95C3, - #$95C4, #$95C5, #$95C6, #$95C7, #$95C8, #$95C9, #$95CA, #$95CB, - #$95CC, #$95CD, #$95CE, #$95CF, #$95D0, #$95D1, #$95D2, #$95D3, - #$95D4, #$95D5, #$95D6, #$95D7, #$95D8, #$95D9, #$95DA, #$95DB, - #$95DC, #$95DD, #$95DE, #$95DF, #$95E0, #$95E1, #$95E2, #$95E3, - #$95E4, #$95E5, #$95E6, #$95E7, #$95EC, #$95FF, #$9607, #$9613, - #$9618, #$961B, #$961E, #$9620, #$9623, #$9624, #$9625, #$9626, - #$9627, #$9628, #$9629, #$962B, #$962C, #$962D, #$962F, #$9630, - #$9637, #$9638, #$9639, #$963A, #$963E, #$9641, #$9643, #$964A, - #$964E, #$964F, #$9651, #$9652, #$9653, #$9656, #$9657, #$9658, - #$9659, #$965A, #$965C, #$965D, #$965E, #$9660, #$9663, #$9665, - #$9666, #$966B, #$966D, #$966E, #$966F, #$9670, #$9671, #$9673, - #$9678, #$9679, #$967A, #$967B, #$967C, #$967D, #$967E, #$967F, - #$9680, #$9681, #$9682, #$9683, #$9684, #$9687, #$9689, #$968A, - #$968C, #$968E, #$9691, #$9692, #$9693, #$9695, #$9696, #$969A, - #$969B, #$969D, #$969E, #$969F, #$96A0, #$96A1, #$96A2, #$96A3, - #$96A4, #$96A5, #$96A6, #$96A8, #$96A9, #$96AA, #$96AB, #$96AC, - #$96AD, #$96AE, #$96AF, #$96B1, #$96B2, #$96B4, #$96B5, #$96B7, - #$96B8, #$96BA, #$96BB, #$96BF, #$96C2, #$96C3, #$96C8, #$96CA, - #$96CB, #$96D0, #$96D1, #$96D3, #$96D4, #$96D6, #$96D7, #$96D8, - #$96D9, #$96DA, #$96DB, #$96DC, #$96DD, #$96DE, #$96DF, #$96E1, - #$96E2, #$96E3, #$96E4, #$96E5, #$96E6, #$96E7, #$96EB, #$96EC, - #$96ED, #$96EE, #$96F0, #$96F1, #$96F2, #$96F4, #$96F5, #$96F8, - #$96FA, #$96FB, #$96FC, #$96FD, #$96FF, #$9702, #$9703, #$9705, - #$970A, #$970B, #$970C, #$9710, #$9711, #$9712, #$9714, #$9715, - #$9717, #$9718, #$9719, #$971A, #$971B, #$971D, #$971F, #$9720, - #$9721, #$9722, #$9723, #$9724, #$9725, #$9726, #$9727, #$9728, - #$9729, #$972B, #$972C, #$972E, #$972F, #$9731, #$9733, #$9734, - #$9735, #$9736, #$9737, #$973A, #$973B, #$973C, #$973D, #$973F, - #$9740, #$9741, #$9742, #$9743, #$9744, #$9745, #$9746, #$9747, - #$9748, #$9749, #$974A, #$974B, #$974C, #$974D, #$974E, #$974F, - #$9750, #$9751, #$9754, #$9755, #$9757, #$9758, #$975A, #$975C, - #$975D, #$975F, #$9763, #$9764, #$9766, #$9767, #$9768, #$976A, - #$976B, #$976C, #$976D, #$976E, #$976F, #$9770, #$9771, #$9772, - #$9775, #$9777, #$9778, #$9779, #$977A, #$977B, #$977D, #$977E, - #$977F, #$9780, #$9781, #$9782, #$9783, #$9784, #$9786, #$9787, - #$9788, #$9789, #$978A, #$978C, #$978E, #$978F, #$9790, #$9793, - #$9795, #$9796, #$9797, #$9799, #$979A, #$979B, #$979C, #$979D, - #$979E, #$979F, #$97A1, #$97A2, #$97A4, #$97A5, #$97A6, #$97A7, - #$97A8, #$97A9, #$97AA, #$97AC, #$97AE, #$97B0, #$97B1, #$97B3, - #$97B5, #$97B6, #$97B7, #$97B8, #$97B9, #$97BA, #$97BB, #$97BC, - #$97BD, #$97BE, #$97BF, #$97C0, #$97C1, #$97C2, #$97C3, #$97C4, - #$97C5, #$97C6, #$97C7, #$97C8, #$97C9, #$97CA, #$97CB, #$97CC, - #$97CD, #$97CE, #$97CF, #$97D0, #$97D1, #$97D2, #$97D3, #$97D4, - #$97D5, #$97D6, #$97D7, #$97D8, #$97D9, #$97DA, #$97DB, #$97DC, - #$97DD, #$97DE, #$97DF, #$97E0, #$97E1, #$97E2, #$97E3, #$97E4, - #$97E5, #$97E8, #$97EE, #$97EF, #$97F0, #$97F1, #$97F2, #$97F4, - #$97F7, #$97F8, #$97F9, #$97FA, #$97FB, #$97FC, #$97FD, #$97FE, - #$97FF, #$9800, #$9801, #$9802, #$9803, #$9804, #$9805, #$9806, - #$9807, #$9808, #$9809, #$980A, #$980B, #$980C, #$980D, #$980E, - #$980F, #$9810, #$9811, #$9812, #$9813, #$9814, #$9815, #$9816, - #$9817, #$9818, #$9819, #$981A, #$981B, #$981C, #$981D, #$981E, - #$981F, #$9820, #$9821, #$9822, #$9823, #$9824, #$9825, #$9826, - #$9827, #$9828, #$9829, #$982A, #$982B, #$982C, #$982D, #$982E, - #$982F, #$9830, #$9831, #$9832, #$9833, #$9834, #$9835, #$9836, - #$9837, #$9838, #$9839, #$983A, #$983B, #$983C, #$983D, #$983E, - #$983F, #$9840, #$9841, #$9842, #$9843, #$9844, #$9845, #$9846, - #$9847, #$9848, #$9849, #$984A, #$984B, #$984C, #$984D, #$984E, - #$984F, #$9850, #$9851, #$9852, #$9853, #$9854, #$9855, #$9856, - #$9857, #$9858, #$9859, #$985A, #$985B, #$985C, #$985D, #$985E, - #$985F, #$9860, #$9861, #$9862, #$9863, #$9864, #$9865, #$9866, - #$9867, #$9868, #$9869, #$986A, #$986B, #$986C, #$986D, #$986E, - #$986F, #$9870, #$9871, #$9872, #$9873, #$9874, #$988B, #$988E, - #$9892, #$9895, #$9899, #$98A3, #$98A8, #$98A9, #$98AA, #$98AB, - #$98AC, #$98AD, #$98AE, #$98AF, #$98B0, #$98B1, #$98B2, #$98B3, - #$98B4, #$98B5, #$98B6, #$98B7, #$98B8, #$98B9, #$98BA, #$98BB, - #$98BC, #$98BD, #$98BE, #$98BF, #$98C0, #$98C1, #$98C2, #$98C3, - #$98C4, #$98C5, #$98C6, #$98C7, #$98C8, #$98C9, #$98CA, #$98CB, - #$98CC, #$98CD, #$98CF, #$98D0, #$98D4, #$98D6, #$98D7, #$98DB, - #$98DC, #$98DD, #$98E0, #$98E1, #$98E2, #$98E3, #$98E4, #$98E5, - #$98E6, #$98E9, #$98EA, #$98EB, #$98EC, #$98ED, #$98EE, #$98EF, - #$98F0, #$98F1, #$98F2, #$98F3, #$98F4, #$98F5, #$98F6, #$98F7, - #$98F8, #$98F9, #$98FA, #$98FB, #$98FC, #$98FD, #$98FE, #$98FF, - #$9900, #$9901, #$9902, #$9903, #$9904, #$9905, #$9906, #$9907, - #$9908, #$9909, #$990A, #$990B, #$990C, #$990E, #$990F, #$9911, - #$9912, #$9913, #$9914, #$9915, #$9916, #$9917, #$9918, #$9919, - #$991A, #$991B, #$991C, #$991D, #$991E, #$991F, #$9920, #$9921, - #$9922, #$9923, #$9924, #$9925, #$9926, #$9927, #$9928, #$9929, - #$992A, #$992B, #$992C, #$992D, #$992F, #$9930, #$9931, #$9932, - #$9933, #$9934, #$9935, #$9936, #$9937, #$9938, #$9939, #$993A, - #$993B, #$993C, #$993D, #$993E, #$993F, #$9940, #$9941, #$9942, - #$9943, #$9944, #$9945, #$9946, #$9947, #$9948, #$9949, #$994A, - #$994B, #$994C, #$994D, #$994E, #$994F, #$9950, #$9951, #$9952, - #$9953, #$9956, #$9957, #$9958, #$9959, #$995A, #$995B, #$995C, - #$995D, #$995E, #$995F, #$9960, #$9961, #$9962, #$9964, #$9966, - #$9973, #$9978, #$9979, #$997B, #$997E, #$9982, #$9983, #$9989, - #$998C, #$998E, #$999A, #$999B, #$999C, #$999D, #$999E, #$999F, - #$99A0, #$99A1, #$99A2, #$99A3, #$99A4, #$99A6, #$99A7, #$99A9, - #$99AA, #$99AB, #$99AC, #$99AD, #$99AE, #$99AF, #$99B0, #$99B1, - #$99B2, #$99B3, #$99B4, #$99B5, #$99B6, #$99B7, #$99B8, #$99B9, - #$99BA, #$99BB, #$99BC, #$99BD, #$99BE, #$99BF, #$99C0, #$99C1, - #$99C2, #$99C3, #$99C4, #$99C5, #$99C6, #$99C7, #$99C8, #$99C9, - #$99CA, #$99CB, #$99CC, #$99CD, #$99CE, #$99CF, #$99D0, #$99D1, - #$99D2, #$99D3, #$99D4, #$99D5, #$99D6, #$99D7, #$99D8, #$99D9, - #$99DA, #$99DB, #$99DC, #$99DD, #$99DE, #$99DF, #$99E0, #$99E1, - #$99E2, #$99E3, #$99E4, #$99E5, #$99E6, #$99E7, #$99E8, #$99E9, - #$99EA, #$99EB, #$99EC, #$99ED, #$99EE, #$99EF, #$99F0, #$99F1, - #$99F2, #$99F3, #$99F4, #$99F5, #$99F6, #$99F7, #$99F8, #$99F9, - #$99FA, #$99FB, #$99FC, #$99FD, #$99FE, #$99FF, #$9A00, #$9A01, - #$9A02, #$9A03, #$9A04, #$9A05, #$9A06, #$9A07, #$9A08, #$9A09, - #$9A0A, #$9A0B, #$9A0C, #$9A0D, #$9A0E, #$9A0F, #$9A10, #$9A11, - #$9A12, #$9A13, #$9A14, #$9A15, #$9A16, #$9A17, #$9A18, #$9A19, - #$9A1A, #$9A1B, #$9A1C, #$9A1D, #$9A1E, #$9A1F, #$9A20, #$9A21, - #$9A22, #$9A23, #$9A24, #$9A25, #$9A26, #$9A27, #$9A28, #$9A29, - #$9A2A, #$9A2B, #$9A2C, #$9A2D, #$9A2E, #$9A2F, #$9A30, #$9A31, - #$9A32, #$9A33, #$9A34, #$9A35, #$9A36, #$9A37, #$9A38, #$9A39, - #$9A3A, #$9A3B, #$9A3C, #$9A3D, #$9A3E, #$9A3F, #$9A40, #$9A41, - #$9A42, #$9A43, #$9A44, #$9A45, #$9A46, #$9A47, #$9A48, #$9A49, - #$9A4A, #$9A4B, #$9A4C, #$9A4D, #$9A4E, #$9A4F, #$9A50, #$9A51, - #$9A52, #$9A53, #$9A54, #$9A55, #$9A56, #$9A57, #$9A58, #$9A59, - #$9A5A, #$9A5B, #$9A5C, #$9A5D, #$9A5E, #$9A5F, #$9A60, #$9A61, - #$9A62, #$9A63, #$9A64, #$9A65, #$9A66, #$9A67, #$9A68, #$9A69, - #$9A6A, #$9A6B, #$9A72, #$9A83, #$9A89, #$9A8D, #$9A8E, #$9A94, - #$9A95, #$9A99, #$9AA6, #$9AA9, #$9AAA, #$9AAB, #$9AAC, #$9AAD, - #$9AAE, #$9AAF, #$9AB2, #$9AB3, #$9AB4, #$9AB5, #$9AB9, #$9ABB, - #$9ABD, #$9ABE, #$9ABF, #$9AC3, #$9AC4, #$9AC6, #$9AC7, #$9AC8, - #$9AC9, #$9ACA, #$9ACD, #$9ACE, #$9ACF, #$9AD0, #$9AD2, #$9AD4, - #$9AD5, #$9AD6, #$9AD7, #$9AD9, #$9ADA, #$9ADB, #$9ADC, #$9ADD, - #$9ADE, #$9AE0, #$9AE2, #$9AE3, #$9AE4, #$9AE5, #$9AE7, #$9AE8, - #$9AE9, #$9AEA, #$9AEC, #$9AEE, #$9AF0, #$9AF1, #$9AF2, #$9AF3, - #$9AF4, #$9AF5, #$9AF6, #$9AF7, #$9AF8, #$9AFA, #$9AFC, #$9AFD, - #$9AFE, #$9AFF, #$9B00, #$9B01, #$9B02, #$9B04, #$9B05, #$9B06, - #$9B07, #$9B09, #$9B0A, #$9B0B, #$9B0C, #$9B0D, #$9B0E, #$9B10, - #$9B11, #$9B12, #$9B14, #$9B15, #$9B16, #$9B17, #$9B18, #$9B19, - #$9B1A, #$9B1B, #$9B1C, #$9B1D, #$9B1E, #$9B20, #$9B21, #$9B22, - #$9B24, #$9B25, #$9B26, #$9B27, #$9B28, #$9B29, #$9B2A, #$9B2B, - #$9B2C, #$9B2D, #$9B2E, #$9B30, #$9B31, #$9B33, #$9B34, #$9B35, - #$9B36, #$9B37, #$9B38, #$9B39, #$9B3A, #$9B3D, #$9B3E, #$9B3F, - #$9B40, #$9B46, #$9B4A, #$9B4B, #$9B4C, #$9B4E, #$9B50, #$9B52, - #$9B53, #$9B55, #$9B56, #$9B57, #$9B58, #$9B59, #$9B5A, #$9B5B, - #$9B5C, #$9B5D, #$9B5E, #$9B5F, #$9B60, #$9B61, #$9B62, #$9B63, - #$9B64, #$9B65, #$9B66, #$9B67, #$9B68, #$9B69, #$9B6A, #$9B6B, - #$9B6C, #$9B6D, #$9B6E, #$9B6F, #$9B70, #$9B71, #$9B72, #$9B73, - #$9B74, #$9B75, #$9B76, #$9B77, #$9B78, #$9B79, #$9B7A, #$9B7B, - #$9B7C, #$9B7D, #$9B7E, #$9B7F, #$9B80, #$9B81, #$9B82, #$9B83, - #$9B84, #$9B85, #$9B86, #$9B87, #$9B88, #$9B89, #$9B8A, #$9B8B, - #$9B8C, #$9B8D, #$9B8E, #$9B8F, #$9B90, #$9B91, #$9B92, #$9B93, - #$9B94, #$9B95, #$9B96, #$9B97, #$9B98, #$9B99, #$9B9A, #$9B9B, - #$9B9C, #$9B9D, #$9B9E, #$9B9F, #$9BA0, #$9BA1, #$9BA2, #$9BA3, - #$9BA4, #$9BA5, #$9BA6, #$9BA7, #$9BA8, #$9BA9, #$9BAA, #$9BAB, - #$9BAC, #$9BAD, #$9BAE, #$9BAF, #$9BB0, #$9BB1, #$9BB2, #$9BB3, - #$9BB4, #$9BB5, #$9BB6, #$9BB7, #$9BB8, #$9BB9, #$9BBA, #$9BBB, - #$9BBC, #$9BBD, #$9BBE, #$9BBF, #$9BC0, #$9BC1, #$9BC2, #$9BC3, - #$9BC4, #$9BC5, #$9BC6, #$9BC7, #$9BC8, #$9BC9, #$9BCA, #$9BCB, - #$9BCC, #$9BCD, #$9BCE, #$9BCF, #$9BD0, #$9BD1, #$9BD2, #$9BD3, - #$9BD4, #$9BD5, #$9BD6, #$9BD7, #$9BD8, #$9BD9, #$9BDA, #$9BDB, - #$9BDC, #$9BDD, #$9BDE, #$9BDF, #$9BE0, #$9BE1, #$9BE2, #$9BE3, - #$9BE4, #$9BE5, #$9BE6, #$9BE7, #$9BE8, #$9BE9, #$9BEA, #$9BEB, - #$9BEC, #$9BED, #$9BEE, #$9BEF, #$9BF0, #$9BF1, #$9BF2, #$9BF3, - #$9BF4, #$9BF5, #$9BF6, #$9BF7, #$9BF8, #$9BF9, #$9BFA, #$9BFB, - #$9BFC, #$9BFD, #$9BFE, #$9BFF, #$9C00, #$9C01, #$9C02, #$9C03, - #$9C04, #$9C05, #$9C06, #$9C07, #$9C08, #$9C09, #$9C0A, #$9C0B, - #$9C0C, #$9C0D, #$9C0E, #$9C0F, #$9C10, #$9C11, #$9C12, #$9C13, - #$9C14, #$9C15, #$9C16, #$9C17, #$9C18, #$9C19, #$9C1A, #$9C1B, - #$9C1C, #$9C1D, #$9C1E, #$9C1F, #$9C20, #$9C21, #$9C22, #$9C23, - #$9C24, #$9C25, #$9C26, #$9C27, #$9C28, #$9C29, #$9C2A, #$9C2B, - #$9C2C, #$9C2D, #$9C2E, #$9C2F, #$9C30, #$9C31, #$9C32, #$9C33, - #$9C34, #$9C35, #$9C36, #$9C37, #$9C38, #$9C39, #$9C3A, #$9C3B, - #$9C3C, #$9C3D, #$9C3E, #$9C3F, #$9C40, #$9C41, #$9C42, #$9C43, - #$9C44, #$9C45, #$9C46, #$9C47, #$9C48, #$9C49, #$9C4A, #$9C4B, - #$9C4C, #$9C4D, #$9C4E, #$9C4F, #$9C50, #$9C51, #$9C52, #$9C53, - #$9C54, #$9C55, #$9C56, #$9C57, #$9C58, #$9C59, #$9C5A, #$9C5B, - #$9C5C, #$9C5D, #$9C5E, #$9C5F, #$9C60, #$9C61, #$9C62, #$9C63, - #$9C64, #$9C65, #$9C66, #$9C67, #$9C68, #$9C69, #$9C6A, #$9C6B, - #$9C6C, #$9C6D, #$9C6E, #$9C6F, #$9C70, #$9C71, #$9C72, #$9C73, - #$9C74, #$9C75, #$9C76, #$9C77, #$9C78, #$9C79, #$9C7A, #$9C7B, - #$9C7D, #$9C7E, #$9C80, #$9C83, #$9C84, #$9C89, #$9C8A, #$9C8C, - #$9C8F, #$9C93, #$9C96, #$9C97, #$9C98, #$9C99, #$9C9D, #$9CAA, - #$9CAC, #$9CAF, #$9CB9, #$9CBE, #$9CBF, #$9CC0, #$9CC1, #$9CC2, - #$9CC8, #$9CC9, #$9CD1, #$9CD2, #$9CDA, #$9CDB, #$9CE0, #$9CE1, - #$9CE3, #$9CE4, #$9CE5, #$9CE6, #$9CE7, #$9CE8, #$9CE9, #$9CEA, - #$9CEB, #$9CEC, #$9CED, #$9CEE, #$9CEF, #$9CF0, #$9CF1, #$9CF2, - #$9CF3, #$9CF4, #$9CF5, #$9CF6, #$9CF7, #$9CF8, #$9CF9, #$9CFA, - #$9CFB, #$9CFC, #$9CFD, #$9CFE, #$9CFF, #$9D00, #$9D01, #$9D02, - #$9D03, #$9D04, #$9D05, #$9D06, #$9D07, #$9D08, #$9D09, #$9D0A, - #$9D0B, #$9D0C, #$9D0D, #$9D0E, #$9D0F, #$9D10, #$9D11, #$9D12, - #$9D13, #$9D14, #$9D15, #$9D16, #$9D17, #$9D18, #$9D19, #$9D1A, - #$9D1B, #$9D1C, #$9D1D, #$9D1E, #$9D1F, #$9D20, #$9D21, #$9D22, - #$9D23, #$9D24, #$9D25, #$9D26, #$9D27, #$9D28, #$9D29, #$9D2A, - #$9D2B, #$9D2C, #$9D2D, #$9D2E, #$9D2F, #$9D30, #$9D31, #$9D32, - #$9D33, #$9D34, #$9D35, #$9D36, #$9D37, #$9D38, #$9D39, #$9D3A, - #$9D3B, #$9D3C, #$9D3D, #$9D3E, #$9D3F, #$9D40, #$9D41, #$9D42, - #$9D43, #$9D44, #$9D45, #$9D46, #$9D47, #$9D48, #$9D49, #$9D4A, - #$9D4B, #$9D4C, #$9D4D, #$9D4E, #$9D4F, #$9D50, #$9D51, #$9D52, - #$9D53, #$9D54, #$9D55, #$9D56, #$9D57, #$9D58, #$9D59, #$9D5A, - #$9D5B, #$9D5C, #$9D5D, #$9D5E, #$9D5F, #$9D60, #$9D61, #$9D62, - #$9D63, #$9D64, #$9D65, #$9D66, #$9D67, #$9D68, #$9D69, #$9D6A, - #$9D6B, #$9D6C, #$9D6D, #$9D6E, #$9D6F, #$9D70, #$9D71, #$9D72, - #$9D73, #$9D74, #$9D75, #$9D76, #$9D77, #$9D78, #$9D79, #$9D7A, - #$9D7B, #$9D7C, #$9D7D, #$9D7E, #$9D7F, #$9D80, #$9D81, #$9D82, - #$9D83, #$9D84, #$9D85, #$9D86, #$9D87, #$9D88, #$9D89, #$9D8A, - #$9D8B, #$9D8C, #$9D8D, #$9D8E, #$9D8F, #$9D90, #$9D91, #$9D92, - #$9D93, #$9D94, #$9D95, #$9D96, #$9D97, #$9D98, #$9D99, #$9D9A, - #$9D9B, #$9D9C, #$9D9D, #$9D9E, #$9D9F, #$9DA0, #$9DA1, #$9DA2, - #$9DA3, #$9DA4, #$9DA5, #$9DA6, #$9DA7, #$9DA8, #$9DA9, #$9DAA, - #$9DAB, #$9DAC, #$9DAD, #$9DAE, #$9DAF, #$9DB0, #$9DB1, #$9DB2, - #$9DB3, #$9DB4, #$9DB5, #$9DB6, #$9DB7, #$9DB8, #$9DB9, #$9DBA, - #$9DBB, #$9DBC, #$9DBD, #$9DBE, #$9DBF, #$9DC0, #$9DC1, #$9DC2, - #$9DC3, #$9DC4, #$9DC5, #$9DC6, #$9DC7, #$9DC8, #$9DC9, #$9DCA, - #$9DCB, #$9DCC, #$9DCD, #$9DCE, #$9DCF, #$9DD0, #$9DD1, #$9DD2, - #$9DD3, #$9DD4, #$9DD5, #$9DD6, #$9DD7, #$9DD8, #$9DD9, #$9DDA, - #$9DDB, #$9DDC, #$9DDD, #$9DDE, #$9DDF, #$9DE0, #$9DE1, #$9DE2, - #$9DE3, #$9DE4, #$9DE5, #$9DE6, #$9DE7, #$9DE8, #$9DE9, #$9DEA, - #$9DEB, #$9DEC, #$9DED, #$9DEE, #$9DEF, #$9DF0, #$9DF1, #$9DF2, - #$9DF3, #$9DF4, #$9DF5, #$9DF6, #$9DF7, #$9DF8, #$9DF9, #$9DFA, - #$9DFB, #$9DFC, #$9DFD, #$9DFE, #$9DFF, #$9E00, #$9E01, #$9E02, - #$9E03, #$9E04, #$9E05, #$9E06, #$9E07, #$9E08, #$9E09, #$9E0A, - #$9E0B, #$9E0C, #$9E0D, #$9E0E, #$9E0F, #$9E10, #$9E11, #$9E12, - #$9E13, #$9E14, #$9E15, #$9E16, #$9E17, #$9E18, #$9E19, #$9E1A, - #$9E1B, #$9E1C, #$9E1D, #$9E1E, #$9E24, #$9E27, #$9E2E, #$9E30, - #$9E34, #$9E3B, #$9E3C, #$9E40, #$9E4D, #$9E50, #$9E52, #$9E53, - #$9E54, #$9E56, #$9E59, #$9E5D, #$9E5F, #$9E60, #$9E61, #$9E62, - #$9E65, #$9E6E, #$9E6F, #$9E72, #$9E74, #$9E75, #$9E76, #$9E77, - #$9E78, #$9E79, #$9E7A, #$9E7B, #$9E7C, #$9E7D, #$9E80, #$9E81, - #$9E83, #$9E84, #$9E85, #$9E86, #$9E89, #$9E8A, #$9E8C, #$9E8D, - #$9E8E, #$9E8F, #$9E90, #$9E91, #$9E94, #$9E95, #$9E96, #$9E97, - #$9E98, #$9E99, #$9E9A, #$9E9B, #$9E9C, #$9E9E, #$9EA0, #$9EA1, - #$9EA2, #$9EA3, #$9EA4, #$9EA5, #$9EA7, #$9EA8, #$9EA9, #$9EAA, - #$9EAB, #$9EAC, #$9EAD, #$9EAE, #$9EAF, #$9EB0, #$9EB1, #$9EB2, - #$9EB3, #$9EB5, #$9EB6, #$9EB7, #$9EB9, #$9EBA, #$9EBC, #$9EBF, - #$9EC0, #$9EC1, #$9EC2, #$9EC3, #$9EC5, #$9EC6, #$9EC7, #$9EC8, - #$9ECA, #$9ECB, #$9ECC, #$9ED0, #$9ED2, #$9ED3, #$9ED5, #$9ED6, - #$9ED7, #$9ED9, #$9EDA, #$9EDE, #$9EE1, #$9EE3, #$9EE4, #$9EE6, - #$9EE8, #$9EEB, #$9EEC, #$9EED, #$9EEE, #$9EF0, #$9EF1, #$9EF2, - #$9EF3, #$9EF4, #$9EF5, #$9EF6, #$9EF7, #$9EF8, #$9EFA, #$9EFD, - #$9EFF, #$9F00, #$9F01, #$9F02, #$9F03, #$9F04, #$9F05, #$9F06, - #$9F07, #$9F08, #$9F09, #$9F0A, #$9F0C, #$9F0F, #$9F11, #$9F12, - #$9F14, #$9F15, #$9F16, #$9F18, #$9F1A, #$9F1B, #$9F1C, #$9F1D, - #$9F1E, #$9F1F, #$9F21, #$9F23, #$9F24, #$9F25, #$9F26, #$9F27, - #$9F28, #$9F29, #$9F2A, #$9F2B, #$9F2D, #$9F2E, #$9F30, #$9F31, - #$9F32, #$9F33, #$9F34, #$9F35, #$9F36, #$9F38, #$9F3A, #$9F3C, - #$9F3F, #$9F40, #$9F41, #$9F42, #$9F43, #$9F45, #$9F46, #$9F47, - #$9F48, #$9F49, #$9F4A, #$9F4B, #$9F4C, #$9F4D, #$9F4E, #$9F4F, - #$9F52, #$9F53, #$9F54, #$9F55, #$9F56, #$9F57, #$9F58, #$9F59, - #$9F5A, #$9F5B, #$9F5C, #$9F5D, #$9F5E, #$9F5F, #$9F60, #$9F61, - #$9F62, #$9F63, #$9F64, #$9F65, #$9F66, #$9F67, #$9F68, #$9F69, - #$9F6A, #$9F6B, #$9F6C, #$9F6D, #$9F6E, #$9F6F, #$9F70, #$9F71, - #$9F72, #$9F73, #$9F74, #$9F75, #$9F76, #$9F77, #$9F78, #$9F79, - #$9F7A, #$9F7B, #$9F7C, #$9F7D, #$9F7E, #$9F81, #$9F82, #$9F8D, - #$9F8E, #$9F8F, #$9F90, #$9F91, #$9F92, #$9F93, #$9F94, #$9F95, - #$9F96, #$9F97, #$9F98, #$9F9C, #$9F9D, #$9F9E, #$9FA1, #$9FA2, - #$9FA3, #$9FA4, #$9FA5, #$F92C, #$F979, #$F995, #$F9E7, #$F9F1, - #$FA0C, #$FA0D, #$FA0E, #$FA0F, #$FA11, #$FA13, #$FA14, #$FA18, - #$FA1F, #$FA20, #$FA21, #$FA23, #$FA24, #$FA27, #$FA28, #$FA29); - JIS_X0212_1Map: array[0..80] of TBuffChar = ( - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$02D8, #$02C7, - #$00B8, #$02D9, #$02DD, #$00AF, #$02DB, #$02DA, #$FF5E, #$0384, - #$0385, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$00A1, #$00A6, #$00BF, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$00BA, #$00AA, #$00A9, #$00AE, #$2122, #$00A4, - #$2116); - JIS_X0212_2Map: array[0..187] of TBuffChar = ( - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$0386, #$0388, #$0389, #$038A, #$03AA, #$FFFD, #$038C, #$FFFD, - #$038E, #$03AB, #$FFFD, #$038F, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$03AC, #$03AD, #$03AE, #$03AF, #$03CA, #$0390, #$03CC, #$03C2, - #$03CD, #$03CB, #$03B0, #$03CE, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$0402, #$0403, #$0404, #$0405, #$0406, #$0407, #$0408, - #$0409, #$040A, #$040B, #$040C, #$040E, #$040F, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$0452, #$0453, #$0454, #$0455, #$0456, #$0457, #$0458, - #$0459, #$045A, #$045B, #$045C, #$045E, #$045F); - JIS_X0212_3Map: array[0..274] of TBuffChar = ( - #$00C6, #$0110, #$FFFD, #$0126, #$FFFD, #$0132, #$FFFD, #$0141, - #$013F, #$FFFD, #$014A, #$00D8, #$0152, #$FFFD, #$0166, #$00DE, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$00E6, #$0111, #$00F0, #$0127, #$0131, #$0133, #$0138, #$0142, - #$0140, #$0149, #$014B, #$00F8, #$0153, #$00DF, #$0167, #$00FE, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$00C1, #$00C0, #$00C4, #$00C2, #$0102, #$01CD, #$0100, #$0104, - #$00C5, #$00C3, #$0106, #$0108, #$010C, #$00C7, #$010A, #$010E, - #$00C9, #$00C8, #$00CB, #$00CA, #$011A, #$0116, #$0112, #$0118, - #$FFFD, #$011C, #$011E, #$0122, #$0120, #$0124, #$00CD, #$00CC, - #$00CF, #$00CE, #$01CF, #$0130, #$012A, #$012E, #$0128, #$0134, - #$0136, #$0139, #$013D, #$013B, #$0143, #$0147, #$0145, #$00D1, - #$00D3, #$00D2, #$00D6, #$00D4, #$01D1, #$0150, #$014C, #$00D5, - #$0154, #$0158, #$0156, #$015A, #$015C, #$0160, #$015E, #$0164, - #$0162, #$00DA, #$00D9, #$00DC, #$00DB, #$016C, #$01D3, #$0170, - #$016A, #$0172, #$016E, #$0168, #$01D7, #$01DB, #$01D9, #$01D5, - #$0174, #$00DD, #$0178, #$0176, #$0179, #$017D, #$017B, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$00E1, #$00E0, #$00E4, #$00E2, #$0103, #$01CE, #$0101, #$0105, - #$00E5, #$00E3, #$0107, #$0109, #$010D, #$00E7, #$010B, #$010F, - #$00E9, #$00E8, #$00EB, #$00EA, #$011B, #$0117, #$0113, #$0119, - #$01F5, #$011D, #$011F, #$FFFD, #$0121, #$0125, #$00ED, #$00EC, - #$00EF, #$00EE, #$01D0, #$FFFD, #$012B, #$012F, #$0129, #$0135, - #$0137, #$013A, #$013E, #$013C, #$0144, #$0148, #$0146, #$00F1, - #$00F3, #$00F2, #$00F6, #$00F4, #$01D2, #$0151, #$014D, #$00F5, - #$0155, #$0159, #$0157, #$015B, #$015D, #$0161, #$015F, #$0165, - #$0163, #$00FA, #$00F9, #$00FC, #$00FB, #$016D, #$01D4, #$0171, - #$016B, #$0173, #$016F, #$0169, #$01D8, #$01DC, #$01DA, #$01D6, - #$0175, #$00FD, #$00FF, #$0177, #$017A, #$017E, #$017C); - JIS_X0212_4Map: array[0..5800] of TBuffChar = ( - #$4E02, #$4E04, #$4E05, #$4E0C, #$4E12, #$4E1F, #$4E23, #$4E24, - #$4E28, #$4E2B, #$4E2E, #$4E2F, #$4E30, #$4E35, #$4E40, #$4E41, - #$4E44, #$4E47, #$4E51, #$4E5A, #$4E5C, #$4E63, #$4E68, #$4E69, - #$4E74, #$4E75, #$4E79, #$4E7F, #$4E8D, #$4E96, #$4E97, #$4E9D, - #$4EAF, #$4EB9, #$4EC3, #$4ED0, #$4EDA, #$4EDB, #$4EE0, #$4EE1, - #$4EE2, #$4EE8, #$4EEF, #$4EF1, #$4EF3, #$4EF5, #$4EFD, #$4EFE, - #$4EFF, #$4F00, #$4F02, #$4F03, #$4F08, #$4F0B, #$4F0C, #$4F12, - #$4F15, #$4F16, #$4F17, #$4F19, #$4F2E, #$4F31, #$4F60, #$4F33, - #$4F35, #$4F37, #$4F39, #$4F3B, #$4F3E, #$4F40, #$4F42, #$4F48, - #$4F49, #$4F4B, #$4F4C, #$4F52, #$4F54, #$4F56, #$4F58, #$4F5F, - #$4F63, #$4F6A, #$4F6C, #$4F6E, #$4F71, #$4F77, #$4F78, #$4F79, - #$4F7A, #$4F7D, #$4F7E, #$4F81, #$4F82, #$4F84, - #$4F85, #$4F89, #$4F8A, #$4F8C, #$4F8E, #$4F90, #$4F92, #$4F93, - #$4F94, #$4F97, #$4F99, #$4F9A, #$4F9E, #$4F9F, #$4FB2, #$4FB7, - #$4FB9, #$4FBB, #$4FBC, #$4FBD, #$4FBE, #$4FC0, #$4FC1, #$4FC5, - #$4FC6, #$4FC8, #$4FC9, #$4FCB, #$4FCC, #$4FCD, #$4FCF, #$4FD2, - #$4FDC, #$4FE0, #$4FE2, #$4FF0, #$4FF2, #$4FFC, #$4FFD, #$4FFF, - #$5000, #$5001, #$5004, #$5007, #$500A, #$500C, #$500E, #$5010, - #$5013, #$5017, #$5018, #$501B, #$501C, #$501D, #$501E, #$5022, - #$5027, #$502E, #$5030, #$5032, #$5033, #$5035, #$5040, #$5041, - #$5042, #$5045, #$5046, #$504A, #$504C, #$504E, #$5051, #$5052, - #$5053, #$5057, #$5059, #$505F, #$5060, #$5062, #$5063, #$5066, - #$5067, #$506A, #$506D, #$5070, #$5071, #$503B, #$5081, #$5083, - #$5084, #$5086, #$508A, #$508E, #$508F, #$5090, - #$5092, #$5093, #$5094, #$5096, #$509B, #$509C, #$509E, #$509F, - #$50A0, #$50A1, #$50A2, #$50AA, #$50AF, #$50B0, #$50B9, #$50BA, - #$50BD, #$50C0, #$50C3, #$50C4, #$50C7, #$50CC, #$50CE, #$50D0, - #$50D3, #$50D4, #$50D8, #$50DC, #$50DD, #$50DF, #$50E2, #$50E4, - #$50E6, #$50E8, #$50E9, #$50EF, #$50F1, #$50F6, #$50FA, #$50FE, - #$5103, #$5106, #$5107, #$5108, #$510B, #$510C, #$510D, #$510E, - #$50F2, #$5110, #$5117, #$5119, #$511B, #$511C, #$511D, #$511E, - #$5123, #$5127, #$5128, #$512C, #$512D, #$512F, #$5131, #$5133, - #$5134, #$5135, #$5138, #$5139, #$5142, #$514A, #$514F, #$5153, - #$5155, #$5157, #$5158, #$515F, #$5164, #$5166, #$517E, #$5183, - #$5184, #$518B, #$518E, #$5198, #$519D, #$51A1, #$51A3, #$51AD, - #$51B8, #$51BA, #$51BC, #$51BE, #$51BF, #$51C2, - #$51C8, #$51CF, #$51D1, #$51D2, #$51D3, #$51D5, #$51D8, #$51DE, - #$51E2, #$51E5, #$51EE, #$51F2, #$51F3, #$51F4, #$51F7, #$5201, - #$5202, #$5205, #$5212, #$5213, #$5215, #$5216, #$5218, #$5222, - #$5228, #$5231, #$5232, #$5235, #$523C, #$5245, #$5249, #$5255, - #$5257, #$5258, #$525A, #$525C, #$525F, #$5260, #$5261, #$5266, - #$526E, #$5277, #$5278, #$5279, #$5280, #$5282, #$5285, #$528A, - #$528C, #$5293, #$5295, #$5296, #$5297, #$5298, #$529A, #$529C, - #$52A4, #$52A5, #$52A6, #$52A7, #$52AF, #$52B0, #$52B6, #$52B7, - #$52B8, #$52BA, #$52BB, #$52BD, #$52C0, #$52C4, #$52C6, #$52C8, - #$52CC, #$52CF, #$52D1, #$52D4, #$52D6, #$52DB, #$52DC, #$52E1, - #$52E5, #$52E8, #$52E9, #$52EA, #$52EC, #$52F0, #$52F1, #$52F4, - #$52F6, #$52F7, #$5300, #$5303, #$530A, #$530B, - #$530C, #$5311, #$5313, #$5318, #$531B, #$531C, #$531E, #$531F, - #$5325, #$5327, #$5328, #$5329, #$532B, #$532C, #$532D, #$5330, - #$5332, #$5335, #$533C, #$533D, #$533E, #$5342, #$534C, #$534B, - #$5359, #$535B, #$5361, #$5363, #$5365, #$536C, #$536D, #$5372, - #$5379, #$537E, #$5383, #$5387, #$5388, #$538E, #$5393, #$5394, - #$5399, #$539D, #$53A1, #$53A4, #$53AA, #$53AB, #$53AF, #$53B2, - #$53B4, #$53B5, #$53B7, #$53B8, #$53BA, #$53BD, #$53C0, #$53C5, - #$53CF, #$53D2, #$53D3, #$53D5, #$53DA, #$53DD, #$53DE, #$53E0, - #$53E6, #$53E7, #$53F5, #$5402, #$5413, #$541A, #$5421, #$5427, - #$5428, #$542A, #$542F, #$5431, #$5434, #$5435, #$5443, #$5444, - #$5447, #$544D, #$544F, #$545E, #$5462, #$5464, #$5466, #$5467, - #$5469, #$546B, #$546D, #$546E, #$5474, #$547F, - #$5481, #$5483, #$5485, #$5488, #$5489, #$548D, #$5491, #$5495, - #$5496, #$549C, #$549F, #$54A1, #$54A6, #$54A7, #$54A9, #$54AA, - #$54AD, #$54AE, #$54B1, #$54B7, #$54B9, #$54BA, #$54BB, #$54BF, - #$54C6, #$54CA, #$54CD, #$54CE, #$54E0, #$54EA, #$54EC, #$54EF, - #$54F6, #$54FC, #$54FE, #$54FF, #$5500, #$5501, #$5505, #$5508, - #$5509, #$550C, #$550D, #$550E, #$5515, #$552A, #$552B, #$5532, - #$5535, #$5536, #$553B, #$553C, #$553D, #$5541, #$5547, #$5549, - #$554A, #$554D, #$5550, #$5551, #$5558, #$555A, #$555B, #$555E, - #$5560, #$5561, #$5564, #$5566, #$557F, #$5581, #$5582, #$5586, - #$5588, #$558E, #$558F, #$5591, #$5592, #$5593, #$5594, #$5597, - #$55A3, #$55A4, #$55AD, #$55B2, #$55BF, #$55C1, #$55C3, #$55C6, - #$55C9, #$55CB, #$55CC, #$55CE, #$55D1, #$55D2, - #$55D3, #$55D7, #$55D8, #$55DB, #$55DE, #$55E2, #$55E9, #$55F6, - #$55FF, #$5605, #$5608, #$560A, #$560D, #$560E, #$560F, #$5610, - #$5611, #$5612, #$5619, #$562C, #$5630, #$5633, #$5635, #$5637, - #$5639, #$563B, #$563C, #$563D, #$563F, #$5640, #$5641, #$5643, - #$5644, #$5646, #$5649, #$564B, #$564D, #$564F, #$5654, #$565E, - #$5660, #$5661, #$5662, #$5663, #$5666, #$5669, #$566D, #$566F, - #$5671, #$5672, #$5675, #$5684, #$5685, #$5688, #$568B, #$568C, - #$5695, #$5699, #$569A, #$569D, #$569E, #$569F, #$56A6, #$56A7, - #$56A8, #$56A9, #$56AB, #$56AC, #$56AD, #$56B1, #$56B3, #$56B7, - #$56BE, #$56C5, #$56C9, #$56CA, #$56CB, #$56CF, #$56D0, #$56CC, - #$56CD, #$56D9, #$56DC, #$56DD, #$56DF, #$56E1, #$56E4, #$56E5, - #$56E6, #$56E7, #$56E8, #$56F1, #$56EB, #$56ED, - #$56F6, #$56F7, #$5701, #$5702, #$5707, #$570A, #$570C, #$5711, - #$5715, #$571A, #$571B, #$571D, #$5720, #$5722, #$5723, #$5724, - #$5725, #$5729, #$572A, #$572C, #$572E, #$572F, #$5733, #$5734, - #$573D, #$573E, #$573F, #$5745, #$5746, #$574C, #$574D, #$5752, - #$5762, #$5765, #$5767, #$5768, #$576B, #$576D, #$576E, #$576F, - #$5770, #$5771, #$5773, #$5774, #$5775, #$5777, #$5779, #$577A, - #$577B, #$577C, #$577E, #$5781, #$5783, #$578C, #$5794, #$5797, - #$5799, #$579A, #$579C, #$579D, #$579E, #$579F, #$57A1, #$5795, - #$57A7, #$57A8, #$57A9, #$57AC, #$57B8, #$57BD, #$57C7, #$57C8, - #$57CC, #$57CF, #$57D5, #$57DD, #$57DE, #$57E4, #$57E6, #$57E7, - #$57E9, #$57ED, #$57F0, #$57F5, #$57F6, #$57F8, #$57FD, #$57FE, - #$57FF, #$5803, #$5804, #$5808, #$5809, #$57E1, - #$580C, #$580D, #$581B, #$581E, #$581F, #$5820, #$5826, #$5827, - #$582D, #$5832, #$5839, #$583F, #$5849, #$584C, #$584D, #$584F, - #$5850, #$5855, #$585F, #$5861, #$5864, #$5867, #$5868, #$5878, - #$587C, #$587F, #$5880, #$5881, #$5887, #$5888, #$5889, #$588A, - #$588C, #$588D, #$588F, #$5890, #$5894, #$5896, #$589D, #$58A0, - #$58A1, #$58A2, #$58A6, #$58A9, #$58B1, #$58B2, #$58C4, #$58BC, - #$58C2, #$58C8, #$58CD, #$58CE, #$58D0, #$58D2, #$58D4, #$58D6, - #$58DA, #$58DD, #$58E1, #$58E2, #$58E9, #$58F3, #$5905, #$5906, - #$590B, #$590C, #$5912, #$5913, #$5914, #$8641, #$591D, #$5921, - #$5923, #$5924, #$5928, #$592F, #$5930, #$5933, #$5935, #$5936, - #$593F, #$5943, #$5946, #$5952, #$5953, #$5959, #$595B, #$595D, - #$595E, #$595F, #$5961, #$5963, #$596B, #$596D, - #$596F, #$5972, #$5975, #$5976, #$5979, #$597B, #$597C, #$598B, - #$598C, #$598E, #$5992, #$5995, #$5997, #$599F, #$59A4, #$59A7, - #$59AD, #$59AE, #$59AF, #$59B0, #$59B3, #$59B7, #$59BA, #$59BC, - #$59C1, #$59C3, #$59C4, #$59C8, #$59CA, #$59CD, #$59D2, #$59DD, - #$59DE, #$59DF, #$59E3, #$59E4, #$59E7, #$59EE, #$59EF, #$59F1, - #$59F2, #$59F4, #$59F7, #$5A00, #$5A04, #$5A0C, #$5A0D, #$5A0E, - #$5A12, #$5A13, #$5A1E, #$5A23, #$5A24, #$5A27, #$5A28, #$5A2A, - #$5A2D, #$5A30, #$5A44, #$5A45, #$5A47, #$5A48, #$5A4C, #$5A50, - #$5A55, #$5A5E, #$5A63, #$5A65, #$5A67, #$5A6D, #$5A77, #$5A7A, - #$5A7B, #$5A7E, #$5A8B, #$5A90, #$5A93, #$5A96, #$5A99, #$5A9C, - #$5A9E, #$5A9F, #$5AA0, #$5AA2, #$5AA7, #$5AAC, #$5AB1, #$5AB2, - #$5AB3, #$5AB5, #$5AB8, #$5ABA, #$5ABB, #$5ABF, - #$5AC4, #$5AC6, #$5AC8, #$5ACF, #$5ADA, #$5ADC, #$5AE0, #$5AE5, - #$5AEA, #$5AEE, #$5AF5, #$5AF6, #$5AFD, #$5B00, #$5B01, #$5B08, - #$5B17, #$5B34, #$5B19, #$5B1B, #$5B1D, #$5B21, #$5B25, #$5B2D, - #$5B38, #$5B41, #$5B4B, #$5B4C, #$5B52, #$5B56, #$5B5E, #$5B68, - #$5B6E, #$5B6F, #$5B7C, #$5B7D, #$5B7E, #$5B7F, #$5B81, #$5B84, - #$5B86, #$5B8A, #$5B8E, #$5B90, #$5B91, #$5B93, #$5B94, #$5B96, - #$5BA8, #$5BA9, #$5BAC, #$5BAD, #$5BAF, #$5BB1, #$5BB2, #$5BB7, - #$5BBA, #$5BBC, #$5BC0, #$5BC1, #$5BCD, #$5BCF, #$5BD6, #$5BD7, - #$5BD8, #$5BD9, #$5BDA, #$5BE0, #$5BEF, #$5BF1, #$5BF4, #$5BFD, - #$5C0C, #$5C17, #$5C1E, #$5C1F, #$5C23, #$5C26, #$5C29, #$5C2B, - #$5C2C, #$5C2E, #$5C30, #$5C32, #$5C35, #$5C36, #$5C59, #$5C5A, - #$5C5C, #$5C62, #$5C63, #$5C67, #$5C68, #$5C69, - #$5C6D, #$5C70, #$5C74, #$5C75, #$5C7A, #$5C7B, #$5C7C, #$5C7D, - #$5C87, #$5C88, #$5C8A, #$5C8F, #$5C92, #$5C9D, #$5C9F, #$5CA0, - #$5CA2, #$5CA3, #$5CA6, #$5CAA, #$5CB2, #$5CB4, #$5CB5, #$5CBA, - #$5CC9, #$5CCB, #$5CD2, #$5CDD, #$5CD7, #$5CEE, #$5CF1, #$5CF2, - #$5CF4, #$5D01, #$5D06, #$5D0D, #$5D12, #$5D2B, #$5D23, #$5D24, - #$5D26, #$5D27, #$5D31, #$5D34, #$5D39, #$5D3D, #$5D3F, #$5D42, - #$5D43, #$5D46, #$5D48, #$5D55, #$5D51, #$5D59, #$5D4A, #$5D5F, - #$5D60, #$5D61, #$5D62, #$5D64, #$5D6A, #$5D6D, #$5D70, #$5D79, - #$5D7A, #$5D7E, #$5D7F, #$5D81, #$5D83, #$5D88, #$5D8A, #$5D92, - #$5D93, #$5D94, #$5D95, #$5D99, #$5D9B, #$5D9F, #$5DA0, #$5DA7, - #$5DAB, #$5DB0, #$5DB4, #$5DB8, #$5DB9, #$5DC3, #$5DC7, #$5DCB, - #$5DD0, #$5DCE, #$5DD8, #$5DD9, #$5DE0, #$5DE4, - #$5DE9, #$5DF8, #$5DF9, #$5E00, #$5E07, #$5E0D, #$5E12, #$5E14, - #$5E15, #$5E18, #$5E1F, #$5E20, #$5E2E, #$5E28, #$5E32, #$5E35, - #$5E3E, #$5E4B, #$5E50, #$5E49, #$5E51, #$5E56, #$5E58, #$5E5B, - #$5E5C, #$5E5E, #$5E68, #$5E6A, #$5E6B, #$5E6C, #$5E6D, #$5E6E, - #$5E70, #$5E80, #$5E8B, #$5E8E, #$5EA2, #$5EA4, #$5EA5, #$5EA8, - #$5EAA, #$5EAC, #$5EB1, #$5EB3, #$5EBD, #$5EBE, #$5EBF, #$5EC6, - #$5ECC, #$5ECB, #$5ECE, #$5ED1, #$5ED2, #$5ED4, #$5ED5, #$5EDC, - #$5EDE, #$5EE5, #$5EEB, #$5F02, #$5F06, #$5F07, #$5F08, #$5F0E, - #$5F19, #$5F1C, #$5F1D, #$5F21, #$5F22, #$5F23, #$5F24, #$5F28, - #$5F2B, #$5F2C, #$5F2E, #$5F30, #$5F34, #$5F36, #$5F3B, #$5F3D, - #$5F3F, #$5F40, #$5F44, #$5F45, #$5F47, #$5F4D, #$5F50, #$5F54, - #$5F58, #$5F5B, #$5F60, #$5F63, #$5F64, #$5F67, - #$5F6F, #$5F72, #$5F74, #$5F75, #$5F78, #$5F7A, #$5F7D, #$5F7E, - #$5F89, #$5F8D, #$5F8F, #$5F96, #$5F9C, #$5F9D, #$5FA2, #$5FA7, - #$5FAB, #$5FA4, #$5FAC, #$5FAF, #$5FB0, #$5FB1, #$5FB8, #$5FC4, - #$5FC7, #$5FC8, #$5FC9, #$5FCB, #$5FD0, #$5FD1, #$5FD2, #$5FD3, - #$5FD4, #$5FDE, #$5FE1, #$5FE2, #$5FE8, #$5FE9, #$5FEA, #$5FEC, - #$5FED, #$5FEE, #$5FEF, #$5FF2, #$5FF3, #$5FF6, #$5FFA, #$5FFC, - #$6007, #$600A, #$600D, #$6013, #$6014, #$6017, #$6018, #$601A, - #$601F, #$6024, #$602D, #$6033, #$6035, #$6040, #$6047, #$6048, - #$6049, #$604C, #$6051, #$6054, #$6056, #$6057, #$605D, #$6061, - #$6067, #$6071, #$607E, #$607F, #$6082, #$6086, #$6088, #$608A, - #$608E, #$6091, #$6093, #$6095, #$6098, #$609D, #$609E, #$60A2, - #$60A4, #$60A5, #$60A8, #$60B0, #$60B1, #$60B7, - #$60BB, #$60BE, #$60C2, #$60C4, #$60C8, #$60C9, #$60CA, #$60CB, - #$60CE, #$60CF, #$60D4, #$60D5, #$60D9, #$60DB, #$60DD, #$60DE, - #$60E2, #$60E5, #$60F2, #$60F5, #$60F8, #$60FC, #$60FD, #$6102, - #$6107, #$610A, #$610C, #$6110, #$6111, #$6112, #$6113, #$6114, - #$6116, #$6117, #$6119, #$611C, #$611E, #$6122, #$612A, #$612B, - #$6130, #$6131, #$6135, #$6136, #$6137, #$6139, #$6141, #$6145, - #$6146, #$6149, #$615E, #$6160, #$616C, #$6172, #$6178, #$617B, - #$617C, #$617F, #$6180, #$6181, #$6183, #$6184, #$618B, #$618D, - #$6192, #$6193, #$6197, #$6198, #$619C, #$619D, #$619F, #$61A0, - #$61A5, #$61A8, #$61AA, #$61AD, #$61B8, #$61B9, #$61BC, #$61C0, - #$61C1, #$61C2, #$61CE, #$61CF, #$61D5, #$61DC, #$61DD, #$61DE, - #$61DF, #$61E1, #$61E2, #$61E7, #$61E9, #$61E5, - #$61EC, #$61ED, #$61EF, #$6201, #$6203, #$6204, #$6207, #$6213, - #$6215, #$621C, #$6220, #$6222, #$6223, #$6227, #$6229, #$622B, - #$6239, #$623D, #$6242, #$6243, #$6244, #$6246, #$624C, #$6250, - #$6251, #$6252, #$6254, #$6256, #$625A, #$625C, #$6264, #$626D, - #$626F, #$6273, #$627A, #$627D, #$628D, #$628E, #$628F, #$6290, - #$62A6, #$62A8, #$62B3, #$62B6, #$62B7, #$62BA, #$62BE, #$62BF, - #$62C4, #$62CE, #$62D5, #$62D6, #$62DA, #$62EA, #$62F2, #$62F4, - #$62FC, #$62FD, #$6303, #$6304, #$630A, #$630B, #$630D, #$6310, - #$6313, #$6316, #$6318, #$6329, #$632A, #$632D, #$6335, #$6336, - #$6339, #$633C, #$6341, #$6342, #$6343, #$6344, #$6346, #$634A, - #$634B, #$634E, #$6352, #$6353, #$6354, #$6358, #$635B, #$6365, - #$6366, #$636C, #$636D, #$6371, #$6374, #$6375, - #$6378, #$637C, #$637D, #$637F, #$6382, #$6384, #$6387, #$638A, - #$6390, #$6394, #$6395, #$6399, #$639A, #$639E, #$63A4, #$63A6, - #$63AD, #$63AE, #$63AF, #$63BD, #$63C1, #$63C5, #$63C8, #$63CE, - #$63D1, #$63D3, #$63D4, #$63D5, #$63DC, #$63E0, #$63E5, #$63EA, - #$63EC, #$63F2, #$63F3, #$63F5, #$63F8, #$63F9, #$6409, #$640A, - #$6410, #$6412, #$6414, #$6418, #$641E, #$6420, #$6422, #$6424, - #$6425, #$6429, #$642A, #$642F, #$6430, #$6435, #$643D, #$643F, - #$644B, #$644F, #$6451, #$6452, #$6453, #$6454, #$645A, #$645B, - #$645C, #$645D, #$645F, #$6460, #$6461, #$6463, #$646D, #$6473, - #$6474, #$647B, #$647D, #$6485, #$6487, #$648F, #$6490, #$6491, - #$6498, #$6499, #$649B, #$649D, #$649F, #$64A1, #$64A3, #$64A6, - #$64A8, #$64AC, #$64B3, #$64BD, #$64BE, #$64BF, - #$64C4, #$64C9, #$64CA, #$64CB, #$64CC, #$64CE, #$64D0, #$64D1, - #$64D5, #$64D7, #$64E4, #$64E5, #$64E9, #$64EA, #$64ED, #$64F0, - #$64F5, #$64F7, #$64FB, #$64FF, #$6501, #$6504, #$6508, #$6509, - #$650A, #$650F, #$6513, #$6514, #$6516, #$6519, #$651B, #$651E, - #$651F, #$6522, #$6526, #$6529, #$652E, #$6531, #$653A, #$653C, - #$653D, #$6543, #$6547, #$6549, #$6550, #$6552, #$6554, #$655F, - #$6560, #$6567, #$656B, #$657A, #$657D, #$6581, #$6585, #$658A, - #$6592, #$6595, #$6598, #$659D, #$65A0, #$65A3, #$65A6, #$65AE, - #$65B2, #$65B3, #$65B4, #$65BF, #$65C2, #$65C8, #$65C9, #$65CE, - #$65D0, #$65D4, #$65D6, #$65D8, #$65DF, #$65F0, #$65F2, #$65F4, - #$65F5, #$65F9, #$65FE, #$65FF, #$6600, #$6604, #$6608, #$6609, - #$660D, #$6611, #$6612, #$6615, #$6616, #$661D, - #$661E, #$6621, #$6622, #$6623, #$6624, #$6626, #$6629, #$662A, - #$662B, #$662C, #$662E, #$6630, #$6631, #$6633, #$6639, #$6637, - #$6640, #$6645, #$6646, #$664A, #$664C, #$6651, #$664E, #$6657, - #$6658, #$6659, #$665B, #$665C, #$6660, #$6661, #$66FB, #$666A, - #$666B, #$666C, #$667E, #$6673, #$6675, #$667F, #$6677, #$6678, - #$6679, #$667B, #$6680, #$667C, #$668B, #$668C, #$668D, #$6690, - #$6692, #$6699, #$669A, #$669B, #$669C, #$669F, #$66A0, #$66A4, - #$66AD, #$66B1, #$66B2, #$66B5, #$66BB, #$66BF, #$66C0, #$66C2, - #$66C3, #$66C8, #$66CC, #$66CE, #$66CF, #$66D4, #$66DB, #$66DF, - #$66E8, #$66EB, #$66EC, #$66EE, #$66FA, #$6705, #$6707, #$670E, - #$6713, #$6719, #$671C, #$6720, #$6722, #$6733, #$673E, #$6745, - #$6747, #$6748, #$674C, #$6754, #$6755, #$675D, - #$6766, #$676C, #$676E, #$6774, #$6776, #$677B, #$6781, #$6784, - #$678E, #$678F, #$6791, #$6793, #$6796, #$6798, #$6799, #$679B, - #$67B0, #$67B1, #$67B2, #$67B5, #$67BB, #$67BC, #$67BD, #$67F9, - #$67C0, #$67C2, #$67C3, #$67C5, #$67C8, #$67C9, #$67D2, #$67D7, - #$67D9, #$67DC, #$67E1, #$67E6, #$67F0, #$67F2, #$67F6, #$67F7, - #$6852, #$6814, #$6819, #$681D, #$681F, #$6828, #$6827, #$682C, - #$682D, #$682F, #$6830, #$6831, #$6833, #$683B, #$683F, #$6844, - #$6845, #$684A, #$684C, #$6855, #$6857, #$6858, #$685B, #$686B, - #$686E, #$686F, #$6870, #$6871, #$6872, #$6875, #$6879, #$687A, - #$687B, #$687C, #$6882, #$6884, #$6886, #$6888, #$6896, #$6898, - #$689A, #$689C, #$68A1, #$68A3, #$68A5, #$68A9, #$68AA, #$68AE, - #$68B2, #$68BB, #$68C5, #$68C8, #$68CC, #$68CF, - #$68D0, #$68D1, #$68D3, #$68D6, #$68D9, #$68DC, #$68DD, #$68E5, - #$68E8, #$68EA, #$68EB, #$68EC, #$68ED, #$68F0, #$68F1, #$68F5, - #$68F6, #$68FB, #$68FC, #$68FD, #$6906, #$6909, #$690A, #$6910, - #$6911, #$6913, #$6916, #$6917, #$6931, #$6933, #$6935, #$6938, - #$693B, #$6942, #$6945, #$6949, #$694E, #$6957, #$695B, #$6963, - #$6964, #$6965, #$6966, #$6968, #$6969, #$696C, #$6970, #$6971, - #$6972, #$697A, #$697B, #$697F, #$6980, #$698D, #$6992, #$6996, - #$6998, #$69A1, #$69A5, #$69A6, #$69A8, #$69AB, #$69AD, #$69AF, - #$69B7, #$69B8, #$69BA, #$69BC, #$69C5, #$69C8, #$69D1, #$69D6, - #$69D7, #$69E2, #$69E5, #$69EE, #$69EF, #$69F1, #$69F3, #$69F5, - #$69FE, #$6A00, #$6A01, #$6A03, #$6A0F, #$6A11, #$6A15, #$6A1A, - #$6A1D, #$6A20, #$6A24, #$6A28, #$6A30, #$6A32, - #$6A34, #$6A37, #$6A3B, #$6A3E, #$6A3F, #$6A45, #$6A46, #$6A49, - #$6A4A, #$6A4E, #$6A50, #$6A51, #$6A52, #$6A55, #$6A56, #$6A5B, - #$6A64, #$6A67, #$6A6A, #$6A71, #$6A73, #$6A7E, #$6A81, #$6A83, - #$6A86, #$6A87, #$6A89, #$6A8B, #$6A91, #$6A9B, #$6A9D, #$6A9E, - #$6A9F, #$6AA5, #$6AAB, #$6AAF, #$6AB0, #$6AB1, #$6AB4, #$6ABD, - #$6ABE, #$6ABF, #$6AC6, #$6AC9, #$6AC8, #$6ACC, #$6AD0, #$6AD4, - #$6AD5, #$6AD6, #$6ADC, #$6ADD, #$6AE4, #$6AE7, #$6AEC, #$6AF0, - #$6AF1, #$6AF2, #$6AFC, #$6AFD, #$6B02, #$6B03, #$6B06, #$6B07, - #$6B09, #$6B0F, #$6B10, #$6B11, #$6B17, #$6B1B, #$6B1E, #$6B24, - #$6B28, #$6B2B, #$6B2C, #$6B2F, #$6B35, #$6B36, #$6B3B, #$6B3F, - #$6B46, #$6B4A, #$6B4D, #$6B52, #$6B56, #$6B58, #$6B5D, #$6B60, - #$6B67, #$6B6B, #$6B6E, #$6B70, #$6B75, #$6B7D, - #$6B7E, #$6B82, #$6B85, #$6B97, #$6B9B, #$6B9F, #$6BA0, #$6BA2, - #$6BA3, #$6BA8, #$6BA9, #$6BAC, #$6BAD, #$6BAE, #$6BB0, #$6BB8, - #$6BB9, #$6BBD, #$6BBE, #$6BC3, #$6BC4, #$6BC9, #$6BCC, #$6BD6, - #$6BDA, #$6BE1, #$6BE3, #$6BE6, #$6BE7, #$6BEE, #$6BF1, #$6BF7, - #$6BF9, #$6BFF, #$6C02, #$6C04, #$6C05, #$6C09, #$6C0D, #$6C0E, - #$6C10, #$6C12, #$6C19, #$6C1F, #$6C26, #$6C27, #$6C28, #$6C2C, - #$6C2E, #$6C33, #$6C35, #$6C36, #$6C3A, #$6C3B, #$6C3F, #$6C4A, - #$6C4B, #$6C4D, #$6C4F, #$6C52, #$6C54, #$6C59, #$6C5B, #$6C5C, - #$6C6B, #$6C6D, #$6C6F, #$6C74, #$6C76, #$6C78, #$6C79, #$6C7B, - #$6C85, #$6C86, #$6C87, #$6C89, #$6C94, #$6C95, #$6C97, #$6C98, - #$6C9C, #$6C9F, #$6CB0, #$6CB2, #$6CB4, #$6CC2, #$6CC6, #$6CCD, - #$6CCF, #$6CD0, #$6CD1, #$6CD2, #$6CD4, #$6CD6, - #$6CDA, #$6CDC, #$6CE0, #$6CE7, #$6CE9, #$6CEB, #$6CEC, #$6CEE, - #$6CF2, #$6CF4, #$6D04, #$6D07, #$6D0A, #$6D0E, #$6D0F, #$6D11, - #$6D13, #$6D1A, #$6D26, #$6D27, #$6D28, #$6C67, #$6D2E, #$6D2F, - #$6D31, #$6D39, #$6D3C, #$6D3F, #$6D57, #$6D5E, #$6D5F, #$6D61, - #$6D65, #$6D67, #$6D6F, #$6D70, #$6D7C, #$6D82, #$6D87, #$6D91, - #$6D92, #$6D94, #$6D96, #$6D97, #$6D98, #$6DAA, #$6DAC, #$6DB4, - #$6DB7, #$6DB9, #$6DBD, #$6DBF, #$6DC4, #$6DC8, #$6DCA, #$6DCE, - #$6DCF, #$6DD6, #$6DDB, #$6DDD, #$6DDF, #$6DE0, #$6DE2, #$6DE5, - #$6DE9, #$6DEF, #$6DF0, #$6DF4, #$6DF6, #$6DFC, #$6E00, #$6E04, - #$6E1E, #$6E22, #$6E27, #$6E32, #$6E36, #$6E39, #$6E3B, #$6E3C, - #$6E44, #$6E45, #$6E48, #$6E49, #$6E4B, #$6E4F, #$6E51, #$6E52, - #$6E53, #$6E54, #$6E57, #$6E5C, #$6E5D, #$6E5E, - #$6E62, #$6E63, #$6E68, #$6E73, #$6E7B, #$6E7D, #$6E8D, #$6E93, - #$6E99, #$6EA0, #$6EA7, #$6EAD, #$6EAE, #$6EB1, #$6EB3, #$6EBB, - #$6EBF, #$6EC0, #$6EC1, #$6EC3, #$6EC7, #$6EC8, #$6ECA, #$6ECD, - #$6ECE, #$6ECF, #$6EEB, #$6EED, #$6EEE, #$6EF9, #$6EFB, #$6EFD, - #$6F04, #$6F08, #$6F0A, #$6F0C, #$6F0D, #$6F16, #$6F18, #$6F1A, - #$6F1B, #$6F26, #$6F29, #$6F2A, #$6F2F, #$6F30, #$6F33, #$6F36, - #$6F3B, #$6F3C, #$6F2D, #$6F4F, #$6F51, #$6F52, #$6F53, #$6F57, - #$6F59, #$6F5A, #$6F5D, #$6F5E, #$6F61, #$6F62, #$6F68, #$6F6C, - #$6F7D, #$6F7E, #$6F83, #$6F87, #$6F88, #$6F8B, #$6F8C, #$6F8D, - #$6F90, #$6F92, #$6F93, #$6F94, #$6F96, #$6F9A, #$6F9F, #$6FA0, - #$6FA5, #$6FA6, #$6FA7, #$6FA8, #$6FAE, #$6FAF, #$6FB0, #$6FB5, - #$6FB6, #$6FBC, #$6FC5, #$6FC7, #$6FC8, #$6FCA, - #$6FDA, #$6FDE, #$6FE8, #$6FE9, #$6FF0, #$6FF5, #$6FF9, #$6FFC, - #$6FFD, #$7000, #$7005, #$7006, #$7007, #$700D, #$7017, #$7020, - #$7023, #$702F, #$7034, #$7037, #$7039, #$703C, #$7043, #$7044, - #$7048, #$7049, #$704A, #$704B, #$7054, #$7055, #$705D, #$705E, - #$704E, #$7064, #$7065, #$706C, #$706E, #$7075, #$7076, #$707E, - #$7081, #$7085, #$7086, #$7094, #$7095, #$7096, #$7097, #$7098, - #$709B, #$70A4, #$70AB, #$70B0, #$70B1, #$70B4, #$70B7, #$70CA, - #$70D1, #$70D3, #$70D4, #$70D5, #$70D6, #$70D8, #$70DC, #$70E4, - #$70FA, #$7103, #$7104, #$7105, #$7106, #$7107, #$710B, #$710C, - #$710F, #$711E, #$7120, #$712B, #$712D, #$712F, #$7130, #$7131, - #$7138, #$7141, #$7145, #$7146, #$7147, #$714A, #$714B, #$7150, - #$7152, #$7157, #$715A, #$715C, #$715E, #$7160, - #$7168, #$7179, #$7180, #$7185, #$7187, #$718C, #$7192, #$719A, - #$719B, #$71A0, #$71A2, #$71AF, #$71B0, #$71B2, #$71B3, #$71BA, - #$71BF, #$71C0, #$71C1, #$71C4, #$71CB, #$71CC, #$71D3, #$71D6, - #$71D9, #$71DA, #$71DC, #$71F8, #$71FE, #$7200, #$7207, #$7208, - #$7209, #$7213, #$7217, #$721A, #$721D, #$721F, #$7224, #$722B, - #$722F, #$7234, #$7238, #$7239, #$7241, #$7242, #$7243, #$7245, - #$724E, #$724F, #$7250, #$7253, #$7255, #$7256, #$725A, #$725C, - #$725E, #$7260, #$7263, #$7268, #$726B, #$726E, #$726F, #$7271, - #$7277, #$7278, #$727B, #$727C, #$727F, #$7284, #$7289, #$728D, - #$728E, #$7293, #$729B, #$72A8, #$72AD, #$72AE, #$72B1, #$72B4, - #$72BE, #$72C1, #$72C7, #$72C9, #$72CC, #$72D5, #$72D6, #$72D8, - #$72DF, #$72E5, #$72F3, #$72F4, #$72FA, #$72FB, - #$72FE, #$7302, #$7304, #$7305, #$7307, #$730B, #$730D, #$7312, - #$7313, #$7318, #$7319, #$731E, #$7322, #$7324, #$7327, #$7328, - #$732C, #$7331, #$7332, #$7335, #$733A, #$733B, #$733D, #$7343, - #$734D, #$7350, #$7352, #$7356, #$7358, #$735D, #$735E, #$735F, - #$7360, #$7366, #$7367, #$7369, #$736B, #$736C, #$736E, #$736F, - #$7371, #$7377, #$7379, #$737C, #$7380, #$7381, #$7383, #$7385, - #$7386, #$738E, #$7390, #$7393, #$7395, #$7397, #$7398, #$739C, - #$739E, #$739F, #$73A0, #$73A2, #$73A5, #$73A6, #$73AA, #$73AB, - #$73AD, #$73B5, #$73B7, #$73B9, #$73BC, #$73BD, #$73BF, #$73C5, - #$73C6, #$73C9, #$73CB, #$73CC, #$73CF, #$73D2, #$73D3, #$73D6, - #$73D9, #$73DD, #$73E1, #$73E3, #$73E6, #$73E7, #$73E9, #$73F4, - #$73F5, #$73F7, #$73F9, #$73FA, #$73FB, #$73FD, - #$73FF, #$7400, #$7401, #$7404, #$7407, #$740A, #$7411, #$741A, - #$741B, #$7424, #$7426, #$7428, #$7429, #$742A, #$742B, #$742C, - #$742D, #$742E, #$742F, #$7430, #$7431, #$7439, #$7440, #$7443, - #$7444, #$7446, #$7447, #$744B, #$744D, #$7451, #$7452, #$7457, - #$745D, #$7462, #$7466, #$7467, #$7468, #$746B, #$746D, #$746E, - #$7471, #$7472, #$7480, #$7481, #$7485, #$7486, #$7487, #$7489, - #$748F, #$7490, #$7491, #$7492, #$7498, #$7499, #$749A, #$749C, - #$749F, #$74A0, #$74A1, #$74A3, #$74A6, #$74A8, #$74A9, #$74AA, - #$74AB, #$74AE, #$74AF, #$74B1, #$74B2, #$74B5, #$74B9, #$74BB, - #$74BF, #$74C8, #$74C9, #$74CC, #$74D0, #$74D3, #$74D8, #$74DA, - #$74DB, #$74DE, #$74DF, #$74E4, #$74E8, #$74EA, #$74EB, #$74EF, - #$74F4, #$74FA, #$74FB, #$74FC, #$74FF, #$7506, - #$7512, #$7516, #$7517, #$7520, #$7521, #$7524, #$7527, #$7529, - #$752A, #$752F, #$7536, #$7539, #$753D, #$753E, #$753F, #$7540, - #$7543, #$7547, #$7548, #$754E, #$7550, #$7552, #$7557, #$755E, - #$755F, #$7561, #$756F, #$7571, #$7579, #$757A, #$757B, #$757C, - #$757D, #$757E, #$7581, #$7585, #$7590, #$7592, #$7593, #$7595, - #$7599, #$759C, #$75A2, #$75A4, #$75B4, #$75BA, #$75BF, #$75C0, - #$75C1, #$75C4, #$75C6, #$75CC, #$75CE, #$75CF, #$75D7, #$75DC, - #$75DF, #$75E0, #$75E1, #$75E4, #$75E7, #$75EC, #$75EE, #$75EF, - #$75F1, #$75F9, #$7600, #$7602, #$7603, #$7604, #$7607, #$7608, - #$760A, #$760C, #$760F, #$7612, #$7613, #$7615, #$7616, #$7619, - #$761B, #$761C, #$761D, #$761E, #$7623, #$7625, #$7626, #$7629, - #$762D, #$7632, #$7633, #$7635, #$7638, #$7639, - #$763A, #$763C, #$764A, #$7640, #$7641, #$7643, #$7644, #$7645, - #$7649, #$764B, #$7655, #$7659, #$765F, #$7664, #$7665, #$766D, - #$766E, #$766F, #$7671, #$7674, #$7681, #$7685, #$768C, #$768D, - #$7695, #$769B, #$769C, #$769D, #$769F, #$76A0, #$76A2, #$76A3, - #$76A4, #$76A5, #$76A6, #$76A7, #$76A8, #$76AA, #$76AD, #$76BD, - #$76C1, #$76C5, #$76C9, #$76CB, #$76CC, #$76CE, #$76D4, #$76D9, - #$76E0, #$76E6, #$76E8, #$76EC, #$76F0, #$76F1, #$76F6, #$76F9, - #$76FC, #$7700, #$7706, #$770A, #$770E, #$7712, #$7714, #$7715, - #$7717, #$7719, #$771A, #$771C, #$7722, #$7728, #$772D, #$772E, - #$772F, #$7734, #$7735, #$7736, #$7739, #$773D, #$773E, #$7742, - #$7745, #$7746, #$774A, #$774D, #$774E, #$774F, #$7752, #$7756, - #$7757, #$775C, #$775E, #$775F, #$7760, #$7762, - #$7764, #$7767, #$776A, #$776C, #$7770, #$7772, #$7773, #$7774, - #$777A, #$777D, #$7780, #$7784, #$778C, #$778D, #$7794, #$7795, - #$7796, #$779A, #$779F, #$77A2, #$77A7, #$77AA, #$77AE, #$77AF, - #$77B1, #$77B5, #$77BE, #$77C3, #$77C9, #$77D1, #$77D2, #$77D5, - #$77D9, #$77DE, #$77DF, #$77E0, #$77E4, #$77E6, #$77EA, #$77EC, - #$77F0, #$77F1, #$77F4, #$77F8, #$77FB, #$7805, #$7806, #$7809, - #$780D, #$780E, #$7811, #$781D, #$7821, #$7822, #$7823, #$782D, - #$782E, #$7830, #$7835, #$7837, #$7843, #$7844, #$7847, #$7848, - #$784C, #$784E, #$7852, #$785C, #$785E, #$7860, #$7861, #$7863, - #$7864, #$7868, #$786A, #$786E, #$787A, #$787E, #$788A, #$788F, - #$7894, #$7898, #$78A1, #$789D, #$789E, #$789F, #$78A4, #$78A8, - #$78AC, #$78AD, #$78B0, #$78B1, #$78B2, #$78B3, - #$78BB, #$78BD, #$78BF, #$78C7, #$78C8, #$78C9, #$78CC, #$78CE, - #$78D2, #$78D3, #$78D5, #$78D6, #$78E4, #$78DB, #$78DF, #$78E0, - #$78E1, #$78E6, #$78EA, #$78F2, #$78F3, #$7900, #$78F6, #$78F7, - #$78FA, #$78FB, #$78FF, #$7906, #$790C, #$7910, #$791A, #$791C, - #$791E, #$791F, #$7920, #$7925, #$7927, #$7929, #$792D, #$7931, - #$7934, #$7935, #$793B, #$793D, #$793F, #$7944, #$7945, #$7946, - #$794A, #$794B, #$794F, #$7951, #$7954, #$7958, #$795B, #$795C, - #$7967, #$7969, #$796B, #$7972, #$7979, #$797B, #$797C, #$797E, - #$798B, #$798C, #$7991, #$7993, #$7994, #$7995, #$7996, #$7998, - #$799B, #$799C, #$79A1, #$79A8, #$79A9, #$79AB, #$79AF, #$79B1, - #$79B4, #$79B8, #$79BB, #$79C2, #$79C4, #$79C7, #$79C8, #$79CA, - #$79CF, #$79D4, #$79D6, #$79DA, #$79DD, #$79DE, - #$79E0, #$79E2, #$79E5, #$79EA, #$79EB, #$79ED, #$79F1, #$79F8, - #$79FC, #$7A02, #$7A03, #$7A07, #$7A09, #$7A0A, #$7A0C, #$7A11, - #$7A15, #$7A1B, #$7A1E, #$7A21, #$7A27, #$7A2B, #$7A2D, #$7A2F, - #$7A30, #$7A34, #$7A35, #$7A38, #$7A39, #$7A3A, #$7A44, #$7A45, - #$7A47, #$7A48, #$7A4C, #$7A55, #$7A56, #$7A59, #$7A5C, #$7A5D, - #$7A5F, #$7A60, #$7A65, #$7A67, #$7A6A, #$7A6D, #$7A75, #$7A78, - #$7A7E, #$7A80, #$7A82, #$7A85, #$7A86, #$7A8A, #$7A8B, #$7A90, - #$7A91, #$7A94, #$7A9E, #$7AA0, #$7AA3, #$7AAC, #$7AB3, #$7AB5, - #$7AB9, #$7ABB, #$7ABC, #$7AC6, #$7AC9, #$7ACC, #$7ACE, #$7AD1, - #$7ADB, #$7AE8, #$7AE9, #$7AEB, #$7AEC, #$7AF1, #$7AF4, #$7AFB, - #$7AFD, #$7AFE, #$7B07, #$7B14, #$7B1F, #$7B23, #$7B27, #$7B29, - #$7B2A, #$7B2B, #$7B2D, #$7B2E, #$7B2F, #$7B30, - #$7B31, #$7B34, #$7B3D, #$7B3F, #$7B40, #$7B41, #$7B47, #$7B4E, - #$7B55, #$7B60, #$7B64, #$7B66, #$7B69, #$7B6A, #$7B6D, #$7B6F, - #$7B72, #$7B73, #$7B77, #$7B84, #$7B89, #$7B8E, #$7B90, #$7B91, - #$7B96, #$7B9B, #$7B9E, #$7BA0, #$7BA5, #$7BAC, #$7BAF, #$7BB0, - #$7BB2, #$7BB5, #$7BB6, #$7BBA, #$7BBB, #$7BBC, #$7BBD, #$7BC2, - #$7BC5, #$7BC8, #$7BCA, #$7BD4, #$7BD6, #$7BD7, #$7BD9, #$7BDA, - #$7BDB, #$7BE8, #$7BEA, #$7BF2, #$7BF4, #$7BF5, #$7BF8, #$7BF9, - #$7BFA, #$7BFC, #$7BFE, #$7C01, #$7C02, #$7C03, #$7C04, #$7C06, - #$7C09, #$7C0B, #$7C0C, #$7C0E, #$7C0F, #$7C19, #$7C1B, #$7C20, - #$7C25, #$7C26, #$7C28, #$7C2C, #$7C31, #$7C33, #$7C34, #$7C36, - #$7C39, #$7C3A, #$7C46, #$7C4A, #$7C55, #$7C51, #$7C52, #$7C53, - #$7C59, #$7C5A, #$7C5B, #$7C5C, #$7C5D, #$7C5E, - #$7C61, #$7C63, #$7C67, #$7C69, #$7C6D, #$7C6E, #$7C70, #$7C72, - #$7C79, #$7C7C, #$7C7D, #$7C86, #$7C87, #$7C8F, #$7C94, #$7C9E, - #$7CA0, #$7CA6, #$7CB0, #$7CB6, #$7CB7, #$7CBA, #$7CBB, #$7CBC, - #$7CBF, #$7CC4, #$7CC7, #$7CC8, #$7CC9, #$7CCD, #$7CCF, #$7CD3, - #$7CD4, #$7CD5, #$7CD7, #$7CD9, #$7CDA, #$7CDD, #$7CE6, #$7CE9, - #$7CEB, #$7CF5, #$7D03, #$7D07, #$7D08, #$7D09, #$7D0F, #$7D11, - #$7D12, #$7D13, #$7D16, #$7D1D, #$7D1E, #$7D23, #$7D26, #$7D2A, - #$7D2D, #$7D31, #$7D3C, #$7D3D, #$7D3E, #$7D40, #$7D41, #$7D47, - #$7D48, #$7D4D, #$7D51, #$7D53, #$7D57, #$7D59, #$7D5A, #$7D5C, - #$7D5D, #$7D65, #$7D67, #$7D6A, #$7D70, #$7D78, #$7D7A, #$7D7B, - #$7D7F, #$7D81, #$7D82, #$7D83, #$7D85, #$7D86, #$7D88, #$7D8B, - #$7D8C, #$7D8D, #$7D91, #$7D96, #$7D97, #$7D9D, - #$7D9E, #$7DA6, #$7DA7, #$7DAA, #$7DB3, #$7DB6, #$7DB7, #$7DB9, - #$7DC2, #$7DC3, #$7DC4, #$7DC5, #$7DC6, #$7DCC, #$7DCD, #$7DCE, - #$7DD7, #$7DD9, #$7E00, #$7DE2, #$7DE5, #$7DE6, #$7DEA, #$7DEB, - #$7DED, #$7DF1, #$7DF5, #$7DF6, #$7DF9, #$7DFA, #$7E08, #$7E10, - #$7E11, #$7E15, #$7E17, #$7E1C, #$7E1D, #$7E20, #$7E27, #$7E28, - #$7E2C, #$7E2D, #$7E2F, #$7E33, #$7E36, #$7E3F, #$7E44, #$7E45, - #$7E47, #$7E4E, #$7E50, #$7E52, #$7E58, #$7E5F, #$7E61, #$7E62, - #$7E65, #$7E6B, #$7E6E, #$7E6F, #$7E73, #$7E78, #$7E7E, #$7E81, - #$7E86, #$7E87, #$7E8A, #$7E8D, #$7E91, #$7E95, #$7E98, #$7E9A, - #$7E9D, #$7E9E, #$7F3C, #$7F3B, #$7F3D, #$7F3E, #$7F3F, #$7F43, - #$7F44, #$7F47, #$7F4F, #$7F52, #$7F53, #$7F5B, #$7F5C, #$7F5D, - #$7F61, #$7F63, #$7F64, #$7F65, #$7F66, #$7F6D, - #$7F71, #$7F7D, #$7F7E, #$7F7F, #$7F80, #$7F8B, #$7F8D, #$7F8F, - #$7F90, #$7F91, #$7F96, #$7F97, #$7F9C, #$7FA1, #$7FA2, #$7FA6, - #$7FAA, #$7FAD, #$7FB4, #$7FBC, #$7FBF, #$7FC0, #$7FC3, #$7FC8, - #$7FCE, #$7FCF, #$7FDB, #$7FDF, #$7FE3, #$7FE5, #$7FE8, #$7FEC, - #$7FEE, #$7FEF, #$7FF2, #$7FFA, #$7FFD, #$7FFE, #$7FFF, #$8007, - #$8008, #$800A, #$800D, #$800E, #$800F, #$8011, #$8013, #$8014, - #$8016, #$801D, #$801E, #$801F, #$8020, #$8024, #$8026, #$802C, - #$802E, #$8030, #$8034, #$8035, #$8037, #$8039, #$803A, #$803C, - #$803E, #$8040, #$8044, #$8060, #$8064, #$8066, #$806D, #$8071, - #$8075, #$8081, #$8088, #$808E, #$809C, #$809E, #$80A6, #$80A7, - #$80AB, #$80B8, #$80B9, #$80C8, #$80CD, #$80CF, #$80D2, #$80D4, - #$80D5, #$80D7, #$80D8, #$80E0, #$80ED, #$80EE, - #$80F0, #$80F2, #$80F3, #$80F6, #$80F9, #$80FA, #$80FE, #$8103, - #$810B, #$8116, #$8117, #$8118, #$811C, #$811E, #$8120, #$8124, - #$8127, #$812C, #$8130, #$8135, #$813A, #$813C, #$8145, #$8147, - #$814A, #$814C, #$8152, #$8157, #$8160, #$8161, #$8167, #$8168, - #$8169, #$816D, #$816F, #$8177, #$8181, #$8190, #$8184, #$8185, - #$8186, #$818B, #$818E, #$8196, #$8198, #$819B, #$819E, #$81A2, - #$81AE, #$81B2, #$81B4, #$81BB, #$81CB, #$81C3, #$81C5, #$81CA, - #$81CE, #$81CF, #$81D5, #$81D7, #$81DB, #$81DD, #$81DE, #$81E1, - #$81E4, #$81EB, #$81EC, #$81F0, #$81F1, #$81F2, #$81F5, #$81F6, - #$81F8, #$81F9, #$81FD, #$81FF, #$8200, #$8203, #$820F, #$8213, - #$8214, #$8219, #$821A, #$821D, #$8221, #$8222, #$8228, #$8232, - #$8234, #$823A, #$8243, #$8244, #$8245, #$8246, - #$824B, #$824E, #$824F, #$8251, #$8256, #$825C, #$8260, #$8263, - #$8267, #$826D, #$8274, #$827B, #$827D, #$827F, #$8280, #$8281, - #$8283, #$8284, #$8287, #$8289, #$828A, #$828E, #$8291, #$8294, - #$8296, #$8298, #$829A, #$829B, #$82A0, #$82A1, #$82A3, #$82A4, - #$82A7, #$82A8, #$82A9, #$82AA, #$82AE, #$82B0, #$82B2, #$82B4, - #$82B7, #$82BA, #$82BC, #$82BE, #$82BF, #$82C6, #$82D0, #$82D5, - #$82DA, #$82E0, #$82E2, #$82E4, #$82E8, #$82EA, #$82ED, #$82EF, - #$82F6, #$82F7, #$82FD, #$82FE, #$8300, #$8301, #$8307, #$8308, - #$830A, #$830B, #$8354, #$831B, #$831D, #$831E, #$831F, #$8321, - #$8322, #$832C, #$832D, #$832E, #$8330, #$8333, #$8337, #$833A, - #$833C, #$833D, #$8342, #$8343, #$8344, #$8347, #$834D, #$834E, - #$8351, #$8355, #$8356, #$8357, #$8370, #$8378, - #$837D, #$837F, #$8380, #$8382, #$8384, #$8386, #$838D, #$8392, - #$8394, #$8395, #$8398, #$8399, #$839B, #$839C, #$839D, #$83A6, - #$83A7, #$83A9, #$83AC, #$83BE, #$83BF, #$83C0, #$83C7, #$83C9, - #$83CF, #$83D0, #$83D1, #$83D4, #$83DD, #$8353, #$83E8, #$83EA, - #$83F6, #$83F8, #$83F9, #$83FC, #$8401, #$8406, #$840A, #$840F, - #$8411, #$8415, #$8419, #$83AD, #$842F, #$8439, #$8445, #$8447, - #$8448, #$844A, #$844D, #$844F, #$8451, #$8452, #$8456, #$8458, - #$8459, #$845A, #$845C, #$8460, #$8464, #$8465, #$8467, #$846A, - #$8470, #$8473, #$8474, #$8476, #$8478, #$847C, #$847D, #$8481, - #$8485, #$8492, #$8493, #$8495, #$849E, #$84A6, #$84A8, #$84A9, - #$84AA, #$84AF, #$84B1, #$84B4, #$84BA, #$84BD, #$84BE, #$84C0, - #$84C2, #$84C7, #$84C8, #$84CC, #$84CF, #$84D3, - #$84DC, #$84E7, #$84EA, #$84EF, #$84F0, #$84F1, #$84F2, #$84F7, - #$8532, #$84FA, #$84FB, #$84FD, #$8502, #$8503, #$8507, #$850C, - #$850E, #$8510, #$851C, #$851E, #$8522, #$8523, #$8524, #$8525, - #$8527, #$852A, #$852B, #$852F, #$8533, #$8534, #$8536, #$853F, - #$8546, #$854F, #$8550, #$8551, #$8552, #$8553, #$8556, #$8559, - #$855C, #$855D, #$855E, #$855F, #$8560, #$8561, #$8562, #$8564, - #$856B, #$856F, #$8579, #$857A, #$857B, #$857D, #$857F, #$8581, - #$8585, #$8586, #$8589, #$858B, #$858C, #$858F, #$8593, #$8598, - #$859D, #$859F, #$85A0, #$85A2, #$85A5, #$85A7, #$85B4, #$85B6, - #$85B7, #$85B8, #$85BC, #$85BD, #$85BE, #$85BF, #$85C2, #$85C7, - #$85CA, #$85CB, #$85CE, #$85AD, #$85D8, #$85DA, #$85DF, #$85E0, - #$85E6, #$85E8, #$85ED, #$85F3, #$85F6, #$85FC, - #$85FF, #$8600, #$8604, #$8605, #$860D, #$860E, #$8610, #$8611, - #$8612, #$8618, #$8619, #$861B, #$861E, #$8621, #$8627, #$8629, - #$8636, #$8638, #$863A, #$863C, #$863D, #$8640, #$8642, #$8646, - #$8652, #$8653, #$8656, #$8657, #$8658, #$8659, #$865D, #$8660, - #$8661, #$8662, #$8663, #$8664, #$8669, #$866C, #$866F, #$8675, - #$8676, #$8677, #$867A, #$868D, #$8691, #$8696, #$8698, #$869A, - #$869C, #$86A1, #$86A6, #$86A7, #$86A8, #$86AD, #$86B1, #$86B3, - #$86B4, #$86B5, #$86B7, #$86B8, #$86B9, #$86BF, #$86C0, #$86C1, - #$86C3, #$86C5, #$86D1, #$86D2, #$86D5, #$86D7, #$86DA, #$86DC, - #$86E0, #$86E3, #$86E5, #$86E7, #$8688, #$86FA, #$86FC, #$86FD, - #$8704, #$8705, #$8707, #$870B, #$870E, #$870F, #$8710, #$8713, - #$8714, #$8719, #$871E, #$871F, #$8721, #$8723, - #$8728, #$872E, #$872F, #$8731, #$8732, #$8739, #$873A, #$873C, - #$873D, #$873E, #$8740, #$8743, #$8745, #$874D, #$8758, #$875D, - #$8761, #$8764, #$8765, #$876F, #$8771, #$8772, #$877B, #$8783, - #$8784, #$8785, #$8786, #$8787, #$8788, #$8789, #$878B, #$878C, - #$8790, #$8793, #$8795, #$8797, #$8798, #$8799, #$879E, #$87A0, - #$87A3, #$87A7, #$87AC, #$87AD, #$87AE, #$87B1, #$87B5, #$87BE, - #$87BF, #$87C1, #$87C8, #$87C9, #$87CA, #$87CE, #$87D5, #$87D6, - #$87D9, #$87DA, #$87DC, #$87DF, #$87E2, #$87E3, #$87E4, #$87EA, - #$87EB, #$87ED, #$87F1, #$87F3, #$87F8, #$87FA, #$87FF, #$8801, - #$8803, #$8806, #$8809, #$880A, #$880B, #$8810, #$8819, #$8812, - #$8813, #$8814, #$8818, #$881A, #$881B, #$881C, #$881E, #$881F, - #$8828, #$882D, #$882E, #$8830, #$8832, #$8835, - #$883A, #$883C, #$8841, #$8843, #$8845, #$8848, #$8849, #$884A, - #$884B, #$884E, #$8851, #$8855, #$8856, #$8858, #$885A, #$885C, - #$885F, #$8860, #$8864, #$8869, #$8871, #$8879, #$887B, #$8880, - #$8898, #$889A, #$889B, #$889C, #$889F, #$88A0, #$88A8, #$88AA, - #$88BA, #$88BD, #$88BE, #$88C0, #$88CA, #$88CB, #$88CC, #$88CD, - #$88CE, #$88D1, #$88D2, #$88D3, #$88DB, #$88DE, #$88E7, #$88EF, - #$88F0, #$88F1, #$88F5, #$88F7, #$8901, #$8906, #$890D, #$890E, - #$890F, #$8915, #$8916, #$8918, #$8919, #$891A, #$891C, #$8920, - #$8926, #$8927, #$8928, #$8930, #$8931, #$8932, #$8935, #$8939, - #$893A, #$893E, #$8940, #$8942, #$8945, #$8946, #$8949, #$894F, - #$8952, #$8957, #$895A, #$895B, #$895C, #$8961, #$8962, #$8963, - #$896B, #$896E, #$8970, #$8973, #$8975, #$897A, - #$897B, #$897C, #$897D, #$8989, #$898D, #$8990, #$8994, #$8995, - #$899B, #$899C, #$899F, #$89A0, #$89A5, #$89B0, #$89B4, #$89B5, - #$89B6, #$89B7, #$89BC, #$89D4, #$89D5, #$89D6, #$89D7, #$89D8, - #$89E5, #$89E9, #$89EB, #$89ED, #$89F1, #$89F3, #$89F6, #$89F9, - #$89FD, #$89FF, #$8A04, #$8A05, #$8A07, #$8A0F, #$8A11, #$8A12, - #$8A14, #$8A15, #$8A1E, #$8A20, #$8A22, #$8A24, #$8A26, #$8A2B, - #$8A2C, #$8A2F, #$8A35, #$8A37, #$8A3D, #$8A3E, #$8A40, #$8A43, - #$8A45, #$8A47, #$8A49, #$8A4D, #$8A4E, #$8A53, #$8A56, #$8A57, - #$8A58, #$8A5C, #$8A5D, #$8A61, #$8A65, #$8A67, #$8A75, #$8A76, - #$8A77, #$8A79, #$8A7A, #$8A7B, #$8A7E, #$8A7F, #$8A80, #$8A83, - #$8A86, #$8A8B, #$8A8F, #$8A90, #$8A92, #$8A96, #$8A97, #$8A99, - #$8A9F, #$8AA7, #$8AA9, #$8AAE, #$8AAF, #$8AB3, - #$8AB6, #$8AB7, #$8ABB, #$8ABE, #$8AC3, #$8AC6, #$8AC8, #$8AC9, - #$8ACA, #$8AD1, #$8AD3, #$8AD4, #$8AD5, #$8AD7, #$8ADD, #$8ADF, - #$8AEC, #$8AF0, #$8AF4, #$8AF5, #$8AF6, #$8AFC, #$8AFF, #$8B05, - #$8B06, #$8B0B, #$8B11, #$8B1C, #$8B1E, #$8B1F, #$8B0A, #$8B2D, - #$8B30, #$8B37, #$8B3C, #$8B42, #$8B43, #$8B44, #$8B45, #$8B46, - #$8B48, #$8B52, #$8B53, #$8B54, #$8B59, #$8B4D, #$8B5E, #$8B63, - #$8B6D, #$8B76, #$8B78, #$8B79, #$8B7C, #$8B7E, #$8B81, #$8B84, - #$8B85, #$8B8B, #$8B8D, #$8B8F, #$8B94, #$8B95, #$8B9C, #$8B9E, - #$8B9F, #$8C38, #$8C39, #$8C3D, #$8C3E, #$8C45, #$8C47, #$8C49, - #$8C4B, #$8C4F, #$8C51, #$8C53, #$8C54, #$8C57, #$8C58, #$8C5B, - #$8C5D, #$8C59, #$8C63, #$8C64, #$8C66, #$8C68, #$8C69, #$8C6D, - #$8C73, #$8C75, #$8C76, #$8C7B, #$8C7E, #$8C86, - #$8C87, #$8C8B, #$8C90, #$8C92, #$8C93, #$8C99, #$8C9B, #$8C9C, - #$8CA4, #$8CB9, #$8CBA, #$8CC5, #$8CC6, #$8CC9, #$8CCB, #$8CCF, - #$8CD6, #$8CD5, #$8CD9, #$8CDD, #$8CE1, #$8CE8, #$8CEC, #$8CEF, - #$8CF0, #$8CF2, #$8CF5, #$8CF7, #$8CF8, #$8CFE, #$8CFF, #$8D01, - #$8D03, #$8D09, #$8D12, #$8D17, #$8D1B, #$8D65, #$8D69, #$8D6C, - #$8D6E, #$8D7F, #$8D82, #$8D84, #$8D88, #$8D8D, #$8D90, #$8D91, - #$8D95, #$8D9E, #$8D9F, #$8DA0, #$8DA6, #$8DAB, #$8DAC, #$8DAF, - #$8DB2, #$8DB5, #$8DB7, #$8DB9, #$8DBB, #$8DC0, #$8DC5, #$8DC6, - #$8DC7, #$8DC8, #$8DCA, #$8DCE, #$8DD1, #$8DD4, #$8DD5, #$8DD7, - #$8DD9, #$8DE4, #$8DE5, #$8DE7, #$8DEC, #$8DF0, #$8DBC, #$8DF1, - #$8DF2, #$8DF4, #$8DFD, #$8E01, #$8E04, #$8E05, #$8E06, #$8E0B, - #$8E11, #$8E14, #$8E16, #$8E20, #$8E21, #$8E22, - #$8E23, #$8E26, #$8E27, #$8E31, #$8E33, #$8E36, #$8E37, #$8E38, - #$8E39, #$8E3D, #$8E40, #$8E41, #$8E4B, #$8E4D, #$8E4E, #$8E4F, - #$8E54, #$8E5B, #$8E5C, #$8E5D, #$8E5E, #$8E61, #$8E62, #$8E69, - #$8E6C, #$8E6D, #$8E6F, #$8E70, #$8E71, #$8E79, #$8E7A, #$8E7B, - #$8E82, #$8E83, #$8E89, #$8E90, #$8E92, #$8E95, #$8E9A, #$8E9B, - #$8E9D, #$8E9E, #$8EA2, #$8EA7, #$8EA9, #$8EAD, #$8EAE, #$8EB3, - #$8EB5, #$8EBA, #$8EBB, #$8EC0, #$8EC1, #$8EC3, #$8EC4, #$8EC7, - #$8ECF, #$8ED1, #$8ED4, #$8EDC, #$8EE8, #$8EEE, #$8EF0, #$8EF1, - #$8EF7, #$8EF9, #$8EFA, #$8EED, #$8F00, #$8F02, #$8F07, #$8F08, - #$8F0F, #$8F10, #$8F16, #$8F17, #$8F18, #$8F1E, #$8F20, #$8F21, - #$8F23, #$8F25, #$8F27, #$8F28, #$8F2C, #$8F2D, #$8F2E, #$8F34, - #$8F35, #$8F36, #$8F37, #$8F3A, #$8F40, #$8F41, - #$8F43, #$8F47, #$8F4F, #$8F51, #$8F52, #$8F53, #$8F54, #$8F55, - #$8F58, #$8F5D, #$8F5E, #$8F65, #$8F9D, #$8FA0, #$8FA1, #$8FA4, - #$8FA5, #$8FA6, #$8FB5, #$8FB6, #$8FB8, #$8FBE, #$8FC0, #$8FC1, - #$8FC6, #$8FCA, #$8FCB, #$8FCD, #$8FD0, #$8FD2, #$8FD3, #$8FD5, - #$8FE0, #$8FE3, #$8FE4, #$8FE8, #$8FEE, #$8FF1, #$8FF5, #$8FF6, - #$8FFB, #$8FFE, #$9002, #$9004, #$9008, #$900C, #$9018, #$901B, - #$9028, #$9029, #$902F, #$902A, #$902C, #$902D, #$9033, #$9034, - #$9037, #$903F, #$9043, #$9044, #$904C, #$905B, #$905D, #$9062, - #$9066, #$9067, #$906C, #$9070, #$9074, #$9079, #$9085, #$9088, - #$908B, #$908C, #$908E, #$9090, #$9095, #$9097, #$9098, #$9099, - #$909B, #$90A0, #$90A1, #$90A2, #$90A5, #$90B0, #$90B2, #$90B3, - #$90B4, #$90B6, #$90BD, #$90CC, #$90BE, #$90C3, - #$90C4, #$90C5, #$90C7, #$90C8, #$90D5, #$90D7, #$90D8, #$90D9, - #$90DC, #$90DD, #$90DF, #$90E5, #$90D2, #$90F6, #$90EB, #$90EF, - #$90F0, #$90F4, #$90FE, #$90FF, #$9100, #$9104, #$9105, #$9106, - #$9108, #$910D, #$9110, #$9114, #$9116, #$9117, #$9118, #$911A, - #$911C, #$911E, #$9120, #$9125, #$9122, #$9123, #$9127, #$9129, - #$912E, #$912F, #$9131, #$9134, #$9136, #$9137, #$9139, #$913A, - #$913C, #$913D, #$9143, #$9147, #$9148, #$914F, #$9153, #$9157, - #$9159, #$915A, #$915B, #$9161, #$9164, #$9167, #$916D, #$9174, - #$9179, #$917A, #$917B, #$9181, #$9183, #$9185, #$9186, #$918A, - #$918E, #$9191, #$9193, #$9194, #$9195, #$9198, #$919E, #$91A1, - #$91A6, #$91A8, #$91AC, #$91AD, #$91AE, #$91B0, #$91B1, #$91B2, - #$91B3, #$91B6, #$91BB, #$91BC, #$91BD, #$91BF, - #$91C2, #$91C3, #$91C5, #$91D3, #$91D4, #$91D7, #$91D9, #$91DA, - #$91DE, #$91E4, #$91E5, #$91E9, #$91EA, #$91EC, #$91ED, #$91EE, - #$91EF, #$91F0, #$91F1, #$91F7, #$91F9, #$91FB, #$91FD, #$9200, - #$9201, #$9204, #$9205, #$9206, #$9207, #$9209, #$920A, #$920C, - #$9210, #$9212, #$9213, #$9216, #$9218, #$921C, #$921D, #$9223, - #$9224, #$9225, #$9226, #$9228, #$922E, #$922F, #$9230, #$9233, - #$9235, #$9236, #$9238, #$9239, #$923A, #$923C, #$923E, #$9240, - #$9242, #$9243, #$9246, #$9247, #$924A, #$924D, #$924E, #$924F, - #$9251, #$9258, #$9259, #$925C, #$925D, #$9260, #$9261, #$9265, - #$9267, #$9268, #$9269, #$926E, #$926F, #$9270, #$9275, #$9276, - #$9277, #$9278, #$9279, #$927B, #$927C, #$927D, #$927F, #$9288, - #$9289, #$928A, #$928D, #$928E, #$9292, #$9297, - #$9299, #$929F, #$92A0, #$92A4, #$92A5, #$92A7, #$92A8, #$92AB, - #$92AF, #$92B2, #$92B6, #$92B8, #$92BA, #$92BB, #$92BC, #$92BD, - #$92BF, #$92C0, #$92C1, #$92C2, #$92C3, #$92C5, #$92C6, #$92C7, - #$92C8, #$92CB, #$92CC, #$92CD, #$92CE, #$92D0, #$92D3, #$92D5, - #$92D7, #$92D8, #$92D9, #$92DC, #$92DD, #$92DF, #$92E0, #$92E1, - #$92E3, #$92E5, #$92E7, #$92E8, #$92EC, #$92EE, #$92F0, #$92F9, - #$92FB, #$92FF, #$9300, #$9302, #$9308, #$930D, #$9311, #$9314, - #$9315, #$931C, #$931D, #$931E, #$931F, #$9321, #$9324, #$9325, - #$9327, #$9329, #$932A, #$9333, #$9334, #$9336, #$9337, #$9347, - #$9348, #$9349, #$9350, #$9351, #$9352, #$9355, #$9357, #$9358, - #$935A, #$935E, #$9364, #$9365, #$9367, #$9369, #$936A, #$936D, - #$936F, #$9370, #$9371, #$9373, #$9374, #$9376, - #$937A, #$937D, #$937F, #$9380, #$9381, #$9382, #$9388, #$938A, - #$938B, #$938D, #$938F, #$9392, #$9395, #$9398, #$939B, #$939E, - #$93A1, #$93A3, #$93A4, #$93A6, #$93A8, #$93AB, #$93B4, #$93B5, - #$93B6, #$93BA, #$93A9, #$93C1, #$93C4, #$93C5, #$93C6, #$93C7, - #$93C9, #$93CA, #$93CB, #$93CC, #$93CD, #$93D3, #$93D9, #$93DC, - #$93DE, #$93DF, #$93E2, #$93E6, #$93E7, #$93F9, #$93F7, #$93F8, - #$93FA, #$93FB, #$93FD, #$9401, #$9402, #$9404, #$9408, #$9409, - #$940D, #$940E, #$940F, #$9415, #$9416, #$9417, #$941F, #$942E, - #$942F, #$9431, #$9432, #$9433, #$9434, #$943B, #$943F, #$943D, - #$9443, #$9445, #$9448, #$944A, #$944C, #$9455, #$9459, #$945C, - #$945F, #$9461, #$9463, #$9468, #$946B, #$946D, #$946E, #$946F, - #$9471, #$9472, #$9484, #$9483, #$9578, #$9579, - #$957E, #$9584, #$9588, #$958C, #$958D, #$958E, #$959D, #$959E, - #$959F, #$95A1, #$95A6, #$95A9, #$95AB, #$95AC, #$95B4, #$95B6, - #$95BA, #$95BD, #$95BF, #$95C6, #$95C8, #$95C9, #$95CB, #$95D0, - #$95D1, #$95D2, #$95D3, #$95D9, #$95DA, #$95DD, #$95DE, #$95DF, - #$95E0, #$95E4, #$95E6, #$961D, #$961E, #$9622, #$9624, #$9625, - #$9626, #$962C, #$9631, #$9633, #$9637, #$9638, #$9639, #$963A, - #$963C, #$963D, #$9641, #$9652, #$9654, #$9656, #$9657, #$9658, - #$9661, #$966E, #$9674, #$967B, #$967C, #$967E, #$967F, #$9681, - #$9682, #$9683, #$9684, #$9689, #$9691, #$9696, #$969A, #$969D, - #$969F, #$96A4, #$96A5, #$96A6, #$96A9, #$96AE, #$96AF, #$96B3, - #$96BA, #$96CA, #$96D2, #$5DB2, #$96D8, #$96DA, #$96DD, #$96DE, - #$96DF, #$96E9, #$96EF, #$96F1, #$96FA, #$9702, - #$9703, #$9705, #$9709, #$971A, #$971B, #$971D, #$9721, #$9722, - #$9723, #$9728, #$9731, #$9733, #$9741, #$9743, #$974A, #$974E, - #$974F, #$9755, #$9757, #$9758, #$975A, #$975B, #$9763, #$9767, - #$976A, #$976E, #$9773, #$9776, #$9777, #$9778, #$977B, #$977D, - #$977F, #$9780, #$9789, #$9795, #$9796, #$9797, #$9799, #$979A, - #$979E, #$979F, #$97A2, #$97AC, #$97AE, #$97B1, #$97B2, #$97B5, - #$97B6, #$97B8, #$97B9, #$97BA, #$97BC, #$97BE, #$97BF, #$97C1, - #$97C4, #$97C5, #$97C7, #$97C9, #$97CA, #$97CC, #$97CD, #$97CE, - #$97D0, #$97D1, #$97D4, #$97D7, #$97D8, #$97D9, #$97DD, #$97DE, - #$97E0, #$97DB, #$97E1, #$97E4, #$97EF, #$97F1, #$97F4, #$97F7, - #$97F8, #$97FA, #$9807, #$980A, #$9819, #$980D, #$980E, #$9814, - #$9816, #$981C, #$981E, #$9820, #$9823, #$9826, - #$982B, #$982E, #$982F, #$9830, #$9832, #$9833, #$9835, #$9825, - #$983E, #$9844, #$9847, #$984A, #$9851, #$9852, #$9853, #$9856, - #$9857, #$9859, #$985A, #$9862, #$9863, #$9865, #$9866, #$986A, - #$986C, #$98AB, #$98AD, #$98AE, #$98B0, #$98B4, #$98B7, #$98B8, - #$98BA, #$98BB, #$98BF, #$98C2, #$98C5, #$98C8, #$98CC, #$98E1, - #$98E3, #$98E5, #$98E6, #$98E7, #$98EA, #$98F3, #$98F6, #$9902, - #$9907, #$9908, #$9911, #$9915, #$9916, #$9917, #$991A, #$991B, - #$991C, #$991F, #$9922, #$9926, #$9927, #$992B, #$9931, #$9932, - #$9933, #$9934, #$9935, #$9939, #$993A, #$993B, #$993C, #$9940, - #$9941, #$9946, #$9947, #$9948, #$994D, #$994E, #$9954, #$9958, - #$9959, #$995B, #$995C, #$995E, #$995F, #$9960, #$999B, #$999D, - #$999F, #$99A6, #$99B0, #$99B1, #$99B2, #$99B5, - #$99B9, #$99BA, #$99BD, #$99BF, #$99C3, #$99C9, #$99D3, #$99D4, - #$99D9, #$99DA, #$99DC, #$99DE, #$99E7, #$99EA, #$99EB, #$99EC, - #$99F0, #$99F4, #$99F5, #$99F9, #$99FD, #$99FE, #$9A02, #$9A03, - #$9A04, #$9A0B, #$9A0C, #$9A10, #$9A11, #$9A16, #$9A1E, #$9A20, - #$9A22, #$9A23, #$9A24, #$9A27, #$9A2D, #$9A2E, #$9A33, #$9A35, - #$9A36, #$9A38, #$9A47, #$9A41, #$9A44, #$9A4A, #$9A4B, #$9A4C, - #$9A4E, #$9A51, #$9A54, #$9A56, #$9A5D, #$9AAA, #$9AAC, #$9AAE, - #$9AAF, #$9AB2, #$9AB4, #$9AB5, #$9AB6, #$9AB9, #$9ABB, #$9ABE, - #$9ABF, #$9AC1, #$9AC3, #$9AC6, #$9AC8, #$9ACE, #$9AD0, #$9AD2, - #$9AD5, #$9AD6, #$9AD7, #$9ADB, #$9ADC, #$9AE0, #$9AE4, #$9AE5, - #$9AE7, #$9AE9, #$9AEC, #$9AF2, #$9AF3, #$9AF5, #$9AF9, #$9AFA, - #$9AFD, #$9AFF, #$9B00, #$9B01, #$9B02, #$9B03, - #$9B04, #$9B05, #$9B08, #$9B09, #$9B0B, #$9B0C, #$9B0D, #$9B0E, - #$9B10, #$9B12, #$9B16, #$9B19, #$9B1B, #$9B1C, #$9B20, #$9B26, - #$9B2B, #$9B2D, #$9B33, #$9B34, #$9B35, #$9B37, #$9B39, #$9B3A, - #$9B3D, #$9B48, #$9B4B, #$9B4C, #$9B55, #$9B56, #$9B57, #$9B5B, - #$9B5E, #$9B61, #$9B63, #$9B65, #$9B66, #$9B68, #$9B6A, #$9B6B, - #$9B6C, #$9B6D, #$9B6E, #$9B73, #$9B75, #$9B77, #$9B78, #$9B79, - #$9B7F, #$9B80, #$9B84, #$9B85, #$9B86, #$9B87, #$9B89, #$9B8A, - #$9B8B, #$9B8D, #$9B8F, #$9B90, #$9B94, #$9B9A, #$9B9D, #$9B9E, - #$9BA6, #$9BA7, #$9BA9, #$9BAC, #$9BB0, #$9BB1, #$9BB2, #$9BB7, - #$9BB8, #$9BBB, #$9BBC, #$9BBE, #$9BBF, #$9BC1, #$9BC7, #$9BC8, - #$9BCE, #$9BD0, #$9BD7, #$9BD8, #$9BDD, #$9BDF, #$9BE5, #$9BE7, - #$9BEA, #$9BEB, #$9BEF, #$9BF3, #$9BF7, #$9BF8, - #$9BF9, #$9BFA, #$9BFD, #$9BFF, #$9C00, #$9C02, #$9C0B, #$9C0F, - #$9C11, #$9C16, #$9C18, #$9C19, #$9C1A, #$9C1C, #$9C1E, #$9C22, - #$9C23, #$9C26, #$9C27, #$9C28, #$9C29, #$9C2A, #$9C31, #$9C35, - #$9C36, #$9C37, #$9C3D, #$9C41, #$9C43, #$9C44, #$9C45, #$9C49, - #$9C4A, #$9C4E, #$9C4F, #$9C50, #$9C53, #$9C54, #$9C56, #$9C58, - #$9C5B, #$9C5D, #$9C5E, #$9C5F, #$9C63, #$9C69, #$9C6A, #$9C5C, - #$9C6B, #$9C68, #$9C6E, #$9C70, #$9C72, #$9C75, #$9C77, #$9C7B, - #$9CE6, #$9CF2, #$9CF7, #$9CF9, #$9D0B, #$9D02, #$9D11, #$9D17, - #$9D18, #$9D1C, #$9D1D, #$9D1E, #$9D2F, #$9D30, #$9D32, #$9D33, - #$9D34, #$9D3A, #$9D3C, #$9D45, #$9D3D, #$9D42, #$9D43, #$9D47, - #$9D4A, #$9D53, #$9D54, #$9D5F, #$9D63, #$9D62, #$9D65, #$9D69, - #$9D6A, #$9D6B, #$9D70, #$9D76, #$9D77, #$9D7B, - #$9D7C, #$9D7E, #$9D83, #$9D84, #$9D86, #$9D8A, #$9D8D, #$9D8E, - #$9D92, #$9D93, #$9D95, #$9D96, #$9D97, #$9D98, #$9DA1, #$9DAA, - #$9DAC, #$9DAE, #$9DB1, #$9DB5, #$9DB9, #$9DBC, #$9DBF, #$9DC3, - #$9DC7, #$9DC9, #$9DCA, #$9DD4, #$9DD5, #$9DD6, #$9DD7, #$9DDA, - #$9DDE, #$9DDF, #$9DE0, #$9DE5, #$9DE7, #$9DE9, #$9DEB, #$9DEE, - #$9DF0, #$9DF3, #$9DF4, #$9DFE, #$9E0A, #$9E02, #$9E07, #$9E0E, - #$9E10, #$9E11, #$9E12, #$9E15, #$9E16, #$9E19, #$9E1C, #$9E1D, - #$9E7A, #$9E7B, #$9E7C, #$9E80, #$9E82, #$9E83, #$9E84, #$9E85, - #$9E87, #$9E8E, #$9E8F, #$9E96, #$9E98, #$9E9B, #$9E9E, #$9EA4, - #$9EA8, #$9EAC, #$9EAE, #$9EAF, #$9EB0, #$9EB3, #$9EB4, #$9EB5, - #$9EC6, #$9EC8, #$9ECB, #$9ED5, #$9EDF, #$9EE4, #$9EE7, #$9EEC, - #$9EED, #$9EEE, #$9EF0, #$9EF1, #$9EF2, #$9EF5, - #$9EF8, #$9EFF, #$9F02, #$9F03, #$9F09, #$9F0F, #$9F10, #$9F11, - #$9F12, #$9F14, #$9F16, #$9F17, #$9F19, #$9F1A, #$9F1B, #$9F1F, - #$9F22, #$9F26, #$9F2A, #$9F2B, #$9F2F, #$9F31, #$9F32, #$9F34, - #$9F37, #$9F39, #$9F3A, #$9F3C, #$9F3D, #$9F3F, #$9F41, #$9F43, - #$9F44, #$9F45, #$9F46, #$9F47, #$9F53, #$9F55, #$9F56, #$9F57, - #$9F58, #$9F5A, #$9F5D, #$9F5E, #$9F68, #$9F69, #$9F6D, #$9F6E, - #$9F6F, #$9F70, #$9F71, #$9F73, #$9F75, #$9F7A, #$9F7D, #$9F8F, - #$9F90, #$9F91, #$9F92, #$9F94, #$9F96, #$9F97, #$9F9E, #$9FA1, - #$9FA2, #$9FA3, #$9FA5); - CNS11643_1_1Map: array[0..499] of TBuffChar = ( - #$3000, #$FF0C, #$3001, #$3002, #$FF0E, #$30FB, #$FF1B, #$FF1A, - #$FF1F, #$FF01, #$FE30, #$2026, #$2025, #$FE50, #$FE51, #$FE52, - #$00B7, #$FE54, #$FE55, #$FE56, #$FE57, #$FE31, #$2014, #$FE32, - #$2013, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FF08, #$FF09, #$FE35, - #$FE36, #$FF5B, #$FF5D, #$FE37, #$FE38, #$3014, #$3015, #$FE39, - #$FE3A, #$3010, #$3011, #$FE3B, #$FE3C, #$300A, #$300B, #$FE3D, - #$FE3E, #$3008, #$3009, #$FE3F, #$FE40, #$300C, #$300D, #$FE41, - #$FE42, #$300E, #$300F, #$FE43, #$FE44, #$FE59, #$FE5A, #$FE5B, - #$FE5C, #$FE5D, #$FE5E, #$2018, #$2019, #$201C, #$201D, #$301D, - #$301E, #$2032, #$2035, #$FF03, #$FF06, #$FF0A, #$203B, #$00A7, - #$3003, #$25CB, #$25CF, #$25B3, #$25B2, #$25CE, #$2606, #$2605, - #$25C7, #$25C6, #$25A1, #$25A0, #$25BD, #$25BC, - #$32A3, #$2105, #$203E, #$FFFD, #$FF3F, #$FFFD, #$FE49, #$FE4A, - #$FE4D, #$FE4E, #$FE4B, #$FE4C, #$FE5F, #$FE60, #$FE61, #$FF0B, - #$FF0D, #$00D7, #$00F7, #$00B1, #$221A, #$FF1C, #$FF1E, #$FF1D, - #$2266, #$2267, #$2260, #$221E, #$2252, #$2261, #$FE62, #$FE63, - #$FE64, #$FE66, #$FE65, #$223C, #$2229, #$222A, #$22A5, #$2220, - #$221F, #$22BF, #$33D2, #$33D1, #$222B, #$222E, #$2235, #$2234, - #$2640, #$2642, #$2641, #$2609, #$2191, #$2193, #$2192, #$2190, - #$2196, #$2197, #$2199, #$2198, #$2016, #$FF5C, #$FF0F, #$FF3C, - #$2215, #$FE68, #$FF04, #$FFE5, #$3012, #$FFE0, #$FFE1, #$FF05, - #$FF20, #$2103, #$2109, #$FE69, #$FE6A, #$FE6B, #$33D5, #$339C, - #$339D, #$339E, #$33CE, #$33A1, #$338E, #$338F, #$33C4, #$00B0, - #$5159, #$515B, #$515E, #$515D, #$5161, #$5163, - #$55E7, #$74E9, #$7CCE, #$2581, #$2582, #$2583, #$2584, #$2585, - #$2586, #$2587, #$2588, #$258F, #$258E, #$258D, #$258C, #$258B, - #$258A, #$2589, #$253C, #$2534, #$252C, #$2524, #$251C, #$2594, - #$2500, #$2502, #$2595, #$250C, #$2510, #$2514, #$2518, #$256D, - #$256E, #$2570, #$256F, #$2550, #$255E, #$256A, #$2561, #$25E2, - #$25E3, #$25E5, #$25E4, #$2571, #$2572, #$2573, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FF10, #$FF11, #$FF12, #$FF13, #$FF14, #$FF15, #$FF16, #$FF17, - #$FF18, #$FF19, #$2160, #$2161, #$2162, #$2163, #$2164, #$2165, - #$2166, #$2167, #$2168, #$2169, #$3021, #$3022, #$3023, #$3024, - #$3025, #$3026, #$3027, #$3028, #$3029, #$FFFD, #$5344, #$FFFD, - #$FF21, #$FF22, #$FF23, #$FF24, #$FF25, #$FF26, #$FF27, #$FF28, - #$FF29, #$FF2A, #$FF2B, #$FF2C, #$FF2D, #$FF2E, #$FF2F, #$FF30, - #$FF31, #$FF32, #$FF33, #$FF34, #$FF35, #$FF36, #$FF37, #$FF38, - #$FF39, #$FF3A, #$FF41, #$FF42, #$FF43, #$FF44, #$FF45, #$FF46, - #$FF47, #$FF48, #$FF49, #$FF4A, #$FF4B, #$FF4C, #$FF4D, #$FF4E, - #$FF4F, #$FF50, #$FF51, #$FF52, #$FF53, #$FF54, #$FF55, #$FF56, - #$FF57, #$FF58, #$FF59, #$FF5A, #$0391, #$0392, #$0393, #$0394, - #$0395, #$0396, #$0397, #$0398, #$0399, #$039A, - #$039B, #$039C, #$039D, #$039E, #$039F, #$03A0, #$03A1, #$03A3, - #$03A4, #$03A5, #$03A6, #$03A7, #$03A8, #$03A9, #$03B1, #$03B2, - #$03B3, #$03B4, #$03B5, #$03B6, #$03B7, #$03B8, #$03B9, #$03BA, - #$03BB, #$03BC, #$03BD, #$03BE, #$03BF, #$03C0, #$03C1, #$03C3, - #$03C4, #$03C5, #$03C6, #$03C7, #$03C8, #$03C9, #$3105, #$3106, - #$3107, #$3108, #$3109, #$310A, #$310B, #$310C, #$310D, #$310E, - #$310F, #$3110, #$3111, #$3112, #$3113, #$3114, #$3115, #$3116, - #$3117, #$3118, #$3119, #$311A, #$311B, #$311C, #$311D, #$311E, - #$311F, #$3120, #$3121, #$3122, #$3123, #$3124, #$3125, #$3126, - #$3127, #$3128, #$3129, #$02D9, #$02C9, #$02CA, #$02C7, #$02CB, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, #$FFFD, - #$2460, #$2461, #$2462, #$2463, #$2464, #$2465, #$2466, #$2467, - #$2468, #$2469, #$2474, #$2475, #$2476, #$2477, #$2478, #$2479, - #$247A, #$247B, #$247C, #$247D, #$2170, #$2171, #$2172, #$2173, - #$2174, #$2175, #$2176, #$2177, #$2178, #$2179); - CNS11643_1_2Map: array[0..32] of TBuffChar = ( - #$2400, #$2401, #$2402, #$2403, #$2404, #$2405, #$2406, #$2407, - #$2408, #$2409, #$240A, #$240B, #$240C, #$240D, #$240E, #$240F, - #$2410, #$2411, #$2412, #$2413, #$2414, #$2415, #$2416, #$2417, - #$2418, #$2419, #$241A, #$241B, #$241C, #$241D, #$241E, #$241F, - #$2421); - CNS11643_1_3Map: array[0..5400] of TBuffChar = ( - #$4E00, #$4E59, #$4E01, #$4E03, #$4E43, #$4E5D, #$4E86, #$4E8C, - #$4EBA, #$513F, #$5165, #$516B, #$51E0, #$5200, #$5201, #$529B, - #$5315, #$5341, #$535C, #$53C8, #$4E09, #$4E0B, #$4E08, #$4E0A, - #$4E2B, #$4E38, #$51E1, #$4E45, #$4E48, #$4E5F, #$4E5E, #$4E8E, - #$4EA1, #$5140, #$5203, #$52FA, #$5343, #$53C9, #$53E3, #$571F, - #$58EB, #$5915, #$5927, #$5973, #$5B50, #$5B51, #$5B53, #$5BF8, - #$5C0F, #$5C22, #$5C38, #$5C71, #$5DDD, #$5DE5, #$5DF1, #$5DF2, - #$5DF3, #$5DFE, #$5E72, #$5EFE, #$5F0B, #$5F13, #$624D, #$4E11, - #$4E10, #$4E0D, #$4E2D, #$4E30, #$4E39, #$4E4B, #$5C39, #$4E88, - #$4E91, #$4E95, #$4E92, #$4E94, #$4EA2, #$4EC1, #$4EC0, #$4EC3, - #$4EC6, #$4EC7, #$4ECD, #$4ECA, #$4ECB, #$4EC4, #$5143, #$5141, - #$5167, #$516D, #$516E, #$516C, #$5197, #$51F6, - #$5206, #$5207, #$5208, #$52FB, #$52FE, #$52FF, #$5316, #$5339, - #$5348, #$5347, #$5345, #$535E, #$5384, #$53CB, #$53CA, #$53CD, - #$58EC, #$5929, #$592B, #$592A, #$592D, #$5B54, #$5C11, #$5C24, - #$5C3A, #$5C6F, #$5DF4, #$5E7B, #$5EFF, #$5F14, #$5F15, #$5FC3, - #$6208, #$6236, #$624B, #$624E, #$652F, #$6587, #$6597, #$65A4, - #$65B9, #$65E5, #$66F0, #$6708, #$6728, #$6B20, #$6B62, #$6B79, - #$6BCB, #$6BD4, #$6BDB, #$6C0F, #$6C34, #$706B, #$722A, #$7236, - #$723B, #$7247, #$7259, #$725B, #$72AC, #$738B, #$4E19, #$4E16, - #$4E15, #$4E14, #$4E18, #$4E3B, #$4E4D, #$4E4F, #$4E4E, #$4EE5, - #$4ED8, #$4ED4, #$4ED5, #$4ED6, #$4ED7, #$4EE3, #$4EE4, #$4ED9, - #$4EDE, #$5145, #$5144, #$5189, #$518A, #$51AC, #$51F9, #$51FA, - #$51F8, #$520A, #$52A0, #$529F, #$5305, #$5306, - #$5317, #$531D, #$4EDF, #$534A, #$5349, #$5361, #$5360, #$536F, - #$536E, #$53BB, #$53EF, #$53E4, #$53F3, #$53EC, #$53EE, #$53E9, - #$53E8, #$53FC, #$53F8, #$53F5, #$53EB, #$53E6, #$53EA, #$53F2, - #$53F1, #$53F0, #$53E5, #$53ED, #$53FB, #$56DB, #$56DA, #$5916, - #$592E, #$5931, #$5974, #$5976, #$5B55, #$5B83, #$5C3C, #$5DE8, - #$5DE7, #$5DE6, #$5E02, #$5E03, #$5E73, #$5E7C, #$5F01, #$5F18, - #$5F17, #$5FC5, #$620A, #$6253, #$6254, #$6252, #$6251, #$65A5, - #$65E6, #$672E, #$672C, #$672A, #$672B, #$672D, #$6B63, #$6BCD, - #$6C11, #$6C10, #$6C38, #$6C41, #$6C40, #$6C3E, #$72AF, #$7384, - #$7389, #$74DC, #$74E6, #$7518, #$751F, #$7528, #$7529, #$7530, - #$7531, #$7532, #$7533, #$758B, #$767D, #$76AE, #$76BF, #$76EE, - #$77DB, #$77E2, #$77F3, #$793A, #$79BE, #$7A74, - #$7ACB, #$4E1E, #$4E1F, #$4E52, #$4E53, #$4E69, #$4E99, #$4EA4, - #$4EA6, #$4EA5, #$4EFF, #$4F09, #$4F19, #$4F0A, #$4F15, #$4F0D, - #$4F10, #$4F11, #$4F0F, #$4EF2, #$4EF6, #$4EFB, #$4EF0, #$4EF3, - #$4EFD, #$4F01, #$4F0B, #$5149, #$5147, #$5146, #$5148, #$5168, - #$5171, #$518D, #$51B0, #$5217, #$5211, #$5212, #$520E, #$5216, - #$52A3, #$5308, #$5321, #$5320, #$5370, #$5371, #$5409, #$540F, - #$540C, #$540A, #$5410, #$5401, #$540B, #$5404, #$5411, #$540D, - #$5408, #$5403, #$540E, #$5406, #$5412, #$56E0, #$56DE, #$56DD, - #$5733, #$5730, #$5728, #$572D, #$572C, #$572F, #$5729, #$5919, - #$591A, #$5937, #$5938, #$5984, #$5978, #$5983, #$597D, #$5979, - #$5982, #$5981, #$5B57, #$5B58, #$5B87, #$5B88, #$5B85, #$5B89, - #$5BFA, #$5C16, #$5C79, #$5DDE, #$5E06, #$5E76, - #$5E74, #$5F0F, #$5F1B, #$5FD9, #$5FD6, #$620E, #$620C, #$620D, - #$6210, #$6263, #$625B, #$6258, #$6536, #$65E9, #$65E8, #$65EC, - #$65ED, #$66F2, #$66F3, #$6709, #$673D, #$6734, #$6731, #$6735, - #$6B21, #$6B64, #$6B7B, #$6C16, #$6C5D, #$6C57, #$6C59, #$6C5F, - #$6C60, #$6C50, #$6C55, #$6C61, #$6C5B, #$6C4D, #$6C4E, #$7070, - #$725F, #$725D, #$767E, #$7AF9, #$7C73, #$7CF8, #$7F36, #$7F8A, - #$7FBD, #$8001, #$8003, #$800C, #$8012, #$8033, #$807F, #$8089, - #$808B, #$808C, #$81E3, #$81EA, #$81F3, #$81FC, #$820C, #$821B, - #$821F, #$826E, #$8272, #$827E, #$866B, #$8840, #$884C, #$8863, - #$897F, #$9621, #$4E32, #$4EA8, #$4F4D, #$4F4F, #$4F47, #$4F57, - #$4F5E, #$4F34, #$4F5B, #$4F55, #$4F30, #$4F50, #$4F51, #$4F3D, - #$4F3A, #$4F38, #$4F43, #$4F54, #$4F3C, #$4F46, - #$4F63, #$4F5C, #$4F60, #$4F2F, #$4F4E, #$4F36, #$4F59, #$4F5D, - #$4F48, #$4F5A, #$514C, #$514B, #$514D, #$5175, #$51B6, #$51B7, - #$5225, #$5224, #$5229, #$522A, #$5228, #$52AB, #$52A9, #$52AA, - #$52AC, #$5323, #$5373, #$5375, #$541D, #$542D, #$541E, #$543E, - #$5426, #$544E, #$5427, #$5446, #$5443, #$5433, #$5448, #$5442, - #$541B, #$5429, #$544A, #$5439, #$543B, #$5438, #$542E, #$5435, - #$5436, #$5420, #$543C, #$5440, #$5431, #$542B, #$541F, #$542C, - #$56EA, #$56F0, #$56E4, #$56EB, #$574A, #$5751, #$5740, #$574D, - #$5747, #$574E, #$573E, #$5750, #$574F, #$573B, #$58EF, #$593E, - #$599D, #$5992, #$59A8, #$599E, #$59A3, #$5999, #$5996, #$598D, - #$59A4, #$5993, #$598A, #$59A5, #$5B5D, #$5B5C, #$5B5A, #$5B5B, - #$5B8C, #$5B8B, #$5B8F, #$5C2C, #$5C40, #$5C41, - #$5C3F, #$5C3E, #$5C90, #$5C91, #$5C94, #$5C8C, #$5DEB, #$5E0C, - #$5E8F, #$5E87, #$5E8A, #$5EF7, #$5F04, #$5F1F, #$5F64, #$5F62, - #$5F77, #$5F79, #$5FD8, #$5FCC, #$5FD7, #$5FCD, #$5FF1, #$5FEB, - #$5FF8, #$5FEA, #$6212, #$6211, #$6284, #$6297, #$6296, #$6280, - #$6276, #$6289, #$626D, #$628A, #$627C, #$627E, #$6279, #$6273, - #$6292, #$626F, #$6298, #$626E, #$6295, #$6293, #$6291, #$6286, - #$6539, #$653B, #$6538, #$65F1, #$66F4, #$675F, #$674E, #$674F, - #$6750, #$6751, #$675C, #$6756, #$675E, #$6749, #$6746, #$6760, - #$6753, #$6757, #$6B65, #$6BCF, #$6C42, #$6C5E, #$6C99, #$6C81, - #$6C88, #$6C89, #$6C85, #$6C9B, #$6C6A, #$6C7A, #$6C90, #$6C70, - #$6C8C, #$6C68, #$6C96, #$6C92, #$6C7D, #$6C83, #$6C72, #$6C7E, - #$6C74, #$6C86, #$6C76, #$6C8D, #$6C94, #$6C98, - #$6C82, #$7076, #$707C, #$707D, #$7078, #$7262, #$7261, #$7260, - #$72C4, #$72C2, #$7396, #$752C, #$752B, #$7537, #$7538, #$7682, - #$76EF, #$77E3, #$79C1, #$79C0, #$79BF, #$7A76, #$7CFB, #$7F55, - #$8096, #$8093, #$809D, #$8098, #$809B, #$809A, #$80B2, #$826F, - #$8292, #$828B, #$828D, #$898B, #$89D2, #$8A00, #$8C37, #$8C46, - #$8C55, #$8C9D, #$8D64, #$8D70, #$8DB3, #$8EAB, #$8ECA, #$8F9B, - #$8FB0, #$8FC2, #$8FC6, #$8FC5, #$8FC4, #$5DE1, #$9091, #$90A2, - #$90AA, #$90A6, #$90A3, #$9149, #$91C6, #$91CC, #$9632, #$962E, - #$9631, #$962A, #$962C, #$4E26, #$4E56, #$4E73, #$4E8B, #$4E9B, - #$4E9E, #$4EAB, #$4EAC, #$4F6F, #$4F9D, #$4F8D, #$4F73, #$4F7F, - #$4F6C, #$4F9B, #$4F8B, #$4F86, #$4F83, #$4F70, #$4F75, #$4F88, - #$4F69, #$4F7B, #$4F96, #$4F7E, #$4F8F, #$4F91, - #$4F7A, #$5154, #$5152, #$5155, #$5169, #$5177, #$5176, #$5178, - #$51BD, #$51FD, #$523B, #$5238, #$5237, #$523A, #$5230, #$522E, - #$5236, #$5241, #$52BE, #$52BB, #$5352, #$5354, #$5353, #$5351, - #$5366, #$5377, #$5378, #$5379, #$53D6, #$53D4, #$53D7, #$5473, - #$5475, #$5496, #$5478, #$5495, #$5480, #$547B, #$5477, #$5484, - #$5492, #$5486, #$547C, #$5490, #$5471, #$5476, #$548C, #$549A, - #$5462, #$5468, #$548B, #$547D, #$548E, #$56FA, #$5783, #$5777, - #$576A, #$5769, #$5761, #$5766, #$5764, #$577C, #$591C, #$5949, - #$5947, #$5948, #$5944, #$5954, #$59BE, #$59BB, #$59D4, #$59B9, - #$59AE, #$59D1, #$59C6, #$59D0, #$59CD, #$59CB, #$59D3, #$59CA, - #$59AF, #$59B3, #$59D2, #$59C5, #$5B5F, #$5B64, #$5B63, #$5B97, - #$5B9A, #$5B98, #$5B9C, #$5B99, #$5B9B, #$5C1A, - #$5C48, #$5C45, #$5C46, #$5CB7, #$5CA1, #$5CB8, #$5CA9, #$5CAB, - #$5CB1, #$5CB3, #$5E18, #$5E1A, #$5E16, #$5E15, #$5E1B, #$5E11, - #$5E78, #$5E9A, #$5E97, #$5E9C, #$5E95, #$5E96, #$5EF6, #$5F26, - #$5F27, #$5F29, #$5F80, #$5F81, #$5F7F, #$5F7C, #$5FDD, #$5FE0, - #$5FFD, #$5FF5, #$5FFF, #$600F, #$6014, #$602F, #$6035, #$6016, - #$602A, #$6015, #$6021, #$6027, #$6029, #$602B, #$601B, #$6216, - #$6215, #$623F, #$623E, #$6240, #$627F, #$62C9, #$62CC, #$62C4, - #$62BF, #$62C2, #$62B9, #$62D2, #$62DB, #$62AB, #$62D3, #$62D4, - #$62CB, #$62C8, #$62A8, #$62BD, #$62BC, #$62D0, #$62D9, #$62C7, - #$62CD, #$62B5, #$62DA, #$62B1, #$62D8, #$62D6, #$62D7, #$62C6, - #$62AC, #$62CE, #$653E, #$65A7, #$65BC, #$65FA, #$6614, #$6613, - #$660C, #$6606, #$6602, #$660E, #$6600, #$660F, - #$6615, #$660A, #$6607, #$670D, #$670B, #$676D, #$678B, #$6795, - #$6771, #$679C, #$6773, #$6777, #$6787, #$679D, #$6797, #$676F, - #$6770, #$677F, #$6789, #$677E, #$6790, #$6775, #$679A, #$6793, - #$677C, #$676A, #$6772, #$6B23, #$6B66, #$6B67, #$6B7F, #$6C13, - #$6C1B, #$6CE3, #$6CE8, #$6CF3, #$6CB1, #$6CCC, #$6CE5, #$6CB3, - #$6CBD, #$6CBE, #$6CBC, #$6CE2, #$6CAB, #$6CD5, #$6CD3, #$6CB8, - #$6CC4, #$6CB9, #$6CC1, #$6CAE, #$6CD7, #$6CC5, #$6CF1, #$6CBF, - #$6CBB, #$6CE1, #$6CDB, #$6CCA, #$6CAC, #$6CEF, #$6CDC, #$6CD6, - #$6CE0, #$7095, #$708E, #$7092, #$708A, #$7099, #$722C, #$722D, - #$7238, #$7248, #$7267, #$7269, #$72C0, #$72CE, #$72D9, #$72D7, - #$72D0, #$73A9, #$73A8, #$739F, #$73AB, #$73A5, #$753D, #$759D, - #$7599, #$759A, #$7684, #$76C2, #$76F2, #$76F4, - #$77E5, #$77FD, #$793E, #$7940, #$7941, #$79C9, #$79C8, #$7A7A, - #$7A79, #$7AFA, #$7CFE, #$7F54, #$7F8C, #$7F8B, #$8005, #$80BA, - #$80A5, #$80A2, #$80B1, #$80A1, #$80AB, #$80A9, #$80B4, #$80AA, - #$80AF, #$81E5, #$81FE, #$820D, #$82B3, #$829D, #$8299, #$82AD, - #$82BD, #$829F, #$82B9, #$82B1, #$82AC, #$82A5, #$82AF, #$82B8, - #$82A3, #$82B0, #$82BE, #$82B7, #$864E, #$8671, #$521D, #$8868, - #$8ECB, #$8FCE, #$8FD4, #$8FD1, #$90B5, #$90B8, #$90B1, #$90B6, - #$91C7, #$91D1, #$9577, #$9580, #$961C, #$9640, #$963F, #$963B, - #$9644, #$9642, #$96B9, #$96E8, #$9752, #$975E, #$4E9F, #$4EAD, - #$4EAE, #$4FE1, #$4FB5, #$4FAF, #$4FBF, #$4FE0, #$4FD1, #$4FCF, - #$4FDD, #$4FC3, #$4FB6, #$4FD8, #$4FDF, #$4FCA, #$4FD7, #$4FAE, - #$4FD0, #$4FC4, #$4FC2, #$4FDA, #$4FCE, #$4FDE, - #$4FB7, #$5157, #$5192, #$5191, #$51A0, #$524E, #$5243, #$524A, - #$524D, #$524C, #$524B, #$5247, #$52C7, #$52C9, #$52C3, #$52C1, - #$530D, #$5357, #$537B, #$539A, #$53DB, #$54AC, #$54C0, #$54A8, - #$54CE, #$54C9, #$54B8, #$54A6, #$54B3, #$54C7, #$54C2, #$54BD, - #$54AA, #$54C1, #$54C4, #$54C8, #$54AF, #$54AB, #$54B1, #$54BB, - #$54A9, #$54A7, #$54BF, #$56FF, #$5782, #$578B, #$57A0, #$57A3, - #$57A2, #$57CE, #$57AE, #$5793, #$5955, #$5951, #$594F, #$594E, - #$5950, #$59DC, #$59D8, #$59FF, #$59E3, #$59E8, #$5A03, #$59E5, - #$59EA, #$59DA, #$59E6, #$5A01, #$59FB, #$5B69, #$5BA3, #$5BA6, - #$5BA4, #$5BA2, #$5BA5, #$5C01, #$5C4E, #$5C4F, #$5C4D, #$5C4B, - #$5CD9, #$5CD2, #$5DF7, #$5E1D, #$5E25, #$5E1F, #$5E7D, #$5EA0, - #$5EA6, #$5EFA, #$5F08, #$5F2D, #$5F65, #$5F88, - #$5F85, #$5F8A, #$5F8B, #$5F87, #$5F8C, #$5F89, #$6012, #$601D, - #$6020, #$6025, #$600E, #$6028, #$604D, #$6070, #$6068, #$6062, - #$6046, #$6043, #$606C, #$606B, #$606A, #$6064, #$6241, #$62DC, - #$6316, #$6309, #$62FC, #$62ED, #$6301, #$62EE, #$62FD, #$6307, - #$62F1, #$62F7, #$62EF, #$62EC, #$62FE, #$62F4, #$6311, #$6302, - #$653F, #$6545, #$65AB, #$65BD, #$65E2, #$6625, #$662D, #$6620, - #$6627, #$662F, #$661F, #$6628, #$6631, #$6624, #$66F7, #$67FF, - #$67D3, #$67F1, #$67D4, #$67D0, #$67EC, #$67B6, #$67AF, #$67F5, - #$67E9, #$67EF, #$67C4, #$67D1, #$67B4, #$67DA, #$67E5, #$67B8, - #$67CF, #$67DE, #$67F3, #$67B0, #$67D9, #$67E2, #$67DD, #$67D2, - #$6B6A, #$6B83, #$6B86, #$6BB5, #$6BD2, #$6BD7, #$6C1F, #$6CC9, - #$6D0B, #$6D32, #$6D2A, #$6D41, #$6D25, #$6D0C, - #$6D31, #$6D1E, #$6D17, #$6D3B, #$6D3D, #$6D3E, #$6D36, #$6D1B, - #$6CF5, #$6D39, #$6D27, #$6D38, #$6D29, #$6D2E, #$6D35, #$6D0E, - #$6D2B, #$70AB, #$70BA, #$70B3, #$70AC, #$70AF, #$70AD, #$70B8, - #$70AE, #$70A4, #$7230, #$7272, #$726F, #$7274, #$72E9, #$72E0, - #$72E1, #$73B7, #$73CA, #$73BB, #$73B2, #$73CD, #$73C0, #$73B3, - #$751A, #$752D, #$754F, #$754C, #$754E, #$754B, #$75AB, #$75A4, - #$75A5, #$75A2, #$75A3, #$7678, #$7686, #$7687, #$7688, #$76C8, - #$76C6, #$76C3, #$76C5, #$7701, #$76F9, #$76F8, #$7709, #$770B, - #$76FE, #$76FC, #$7707, #$77DC, #$7802, #$7814, #$780C, #$780D, - #$7946, #$7949, #$7948, #$7947, #$79B9, #$79BA, #$79D1, #$79D2, - #$79CB, #$7A7F, #$7A81, #$7AFF, #$7AFD, #$7C7D, #$7D02, #$7D05, - #$7D00, #$7D09, #$7D07, #$7D04, #$7D06, #$7F38, - #$7F8E, #$7FBF, #$8010, #$800D, #$8011, #$8036, #$80D6, #$80E5, - #$80DA, #$80C3, #$80C4, #$80CC, #$80E1, #$80DB, #$80CE, #$80DE, - #$80E4, #$80DD, #$81F4, #$8222, #$82E7, #$8303, #$8305, #$82E3, - #$82DB, #$82E6, #$8304, #$82E5, #$8302, #$8309, #$82D2, #$82D7, - #$82F1, #$8301, #$82DC, #$82D4, #$82D1, #$82DE, #$82D3, #$82DF, - #$82EF, #$8306, #$8650, #$8679, #$867B, #$867A, #$884D, #$886B, - #$8981, #$89D4, #$8A08, #$8A02, #$8A03, #$8C9E, #$8CA0, #$8D74, - #$8D73, #$8DB4, #$8ECD, #$8ECC, #$8FF0, #$8FE6, #$8FE2, #$8FEA, - #$8FE5, #$8FED, #$8FEB, #$8FE4, #$8FE8, #$90CA, #$90CE, #$90C1, - #$90C3, #$914B, #$914A, #$91CD, #$9582, #$9650, #$964B, #$964C, - #$964D, #$9762, #$9769, #$97CB, #$97ED, #$97F3, #$9801, #$98A8, - #$98DB, #$98DF, #$9996, #$9999, #$4E58, #$4EB3, - #$500C, #$500D, #$5023, #$4FEF, #$5026, #$5025, #$4FF8, #$5029, - #$5016, #$5006, #$503C, #$501F, #$501A, #$5012, #$5011, #$4FFA, - #$5000, #$5014, #$5028, #$4FF1, #$5021, #$500B, #$5019, #$5018, - #$4FF3, #$4FEE, #$502D, #$502A, #$4FFE, #$502B, #$5009, #$517C, - #$51A4, #$51A5, #$51A2, #$51CD, #$51CC, #$51C6, #$51CB, #$5256, - #$525C, #$5254, #$525B, #$525D, #$532A, #$537F, #$539F, #$539D, - #$53DF, #$54E8, #$5510, #$5501, #$5537, #$54FC, #$54E5, #$54F2, - #$5506, #$54FA, #$5514, #$54E9, #$54ED, #$54E1, #$5509, #$54EE, - #$54EA, #$54E6, #$5527, #$5507, #$54FD, #$550F, #$5703, #$5704, - #$57C2, #$57D4, #$57CB, #$57C3, #$5809, #$590F, #$5957, #$5958, - #$595A, #$5A11, #$5A18, #$5A1C, #$5A1F, #$5A1B, #$5A13, #$59EC, - #$5A20, #$5A23, #$5A29, #$5A25, #$5A0C, #$5A09, - #$5B6B, #$5C58, #$5BB0, #$5BB3, #$5BB6, #$5BB4, #$5BAE, #$5BB5, - #$5BB9, #$5BB8, #$5C04, #$5C51, #$5C55, #$5C50, #$5CED, #$5CFD, - #$5CFB, #$5CEA, #$5CE8, #$5CF0, #$5CF6, #$5D01, #$5CF4, #$5DEE, - #$5E2D, #$5E2B, #$5EAB, #$5EAD, #$5EA7, #$5F31, #$5F92, #$5F91, - #$5F90, #$6059, #$6063, #$6065, #$6050, #$6055, #$606D, #$6069, - #$606F, #$6084, #$609F, #$609A, #$608D, #$6094, #$608C, #$6085, - #$6096, #$6247, #$62F3, #$6308, #$62FF, #$634E, #$633E, #$632F, - #$6355, #$6342, #$6346, #$634F, #$6349, #$633A, #$6350, #$633D, - #$632A, #$632B, #$6328, #$634D, #$634C, #$6548, #$6549, #$6599, - #$65C1, #$65C5, #$6642, #$6649, #$664F, #$6643, #$6652, #$664C, - #$6645, #$6641, #$66F8, #$6714, #$6715, #$6717, #$6821, #$6838, - #$6848, #$6846, #$6853, #$6839, #$6842, #$6854, - #$6829, #$68B3, #$6817, #$684C, #$6851, #$683D, #$67F4, #$6850, - #$6840, #$683C, #$6843, #$682A, #$6845, #$6813, #$6818, #$6841, - #$6B8A, #$6B89, #$6BB7, #$6C23, #$6C27, #$6C28, #$6C26, #$6C24, - #$6CF0, #$6D6A, #$6D95, #$6D88, #$6D87, #$6D66, #$6D78, #$6D77, - #$6D59, #$6D93, #$6D6C, #$6D89, #$6D6E, #$6D5A, #$6D74, #$6D69, - #$6D8C, #$6D8A, #$6D79, #$6D85, #$6D65, #$6D94, #$70CA, #$70D8, - #$70E4, #$70D9, #$70C8, #$70CF, #$7239, #$7279, #$72FC, #$72F9, - #$72FD, #$72F8, #$72F7, #$7386, #$73ED, #$7409, #$73EE, #$73E0, - #$73EA, #$73DE, #$7554, #$755D, #$755C, #$755A, #$7559, #$75BE, - #$75C5, #$75C7, #$75B2, #$75B3, #$75BD, #$75BC, #$75B9, #$75C2, - #$75B8, #$768B, #$76B0, #$76CA, #$76CD, #$76CE, #$7729, #$771F, - #$7720, #$7728, #$77E9, #$7830, #$7827, #$7838, - #$781D, #$7834, #$7837, #$7825, #$782D, #$7820, #$781F, #$7832, - #$7955, #$7950, #$7960, #$795F, #$7956, #$795E, #$795D, #$7957, - #$795A, #$79E4, #$79E3, #$79E7, #$79DF, #$79E6, #$79E9, #$79D8, - #$7A84, #$7A88, #$7AD9, #$7B06, #$7B11, #$7C89, #$7D21, #$7D17, - #$7D0B, #$7D0A, #$7D20, #$7D22, #$7D14, #$7D10, #$7D15, #$7D1A, - #$7D1C, #$7D0D, #$7D19, #$7D1B, #$7F3A, #$7F5F, #$7F94, #$7FC5, - #$7FC1, #$8006, #$8004, #$8018, #$8015, #$8019, #$8017, #$803D, - #$803F, #$80F1, #$8102, #$80F0, #$8105, #$80ED, #$80F4, #$8106, - #$80F8, #$80F3, #$8108, #$80FD, #$810A, #$80FC, #$80EF, #$81ED, - #$81EC, #$8200, #$8210, #$822A, #$822B, #$8228, #$822C, #$82BB, - #$832B, #$8352, #$8354, #$834A, #$8338, #$8350, #$8349, #$8335, - #$8334, #$834F, #$8332, #$8339, #$8336, #$8317, - #$8340, #$8331, #$8328, #$8343, #$8654, #$868A, #$86AA, #$8693, - #$86A4, #$86A9, #$868C, #$86A3, #$869C, #$8870, #$8877, #$8881, - #$8882, #$887D, #$8879, #$8A18, #$8A10, #$8A0E, #$8A0C, #$8A15, - #$8A0A, #$8A17, #$8A13, #$8A16, #$8A0F, #$8A11, #$8C48, #$8C7A, - #$8C79, #$8CA1, #$8CA2, #$8D77, #$8EAC, #$8ED2, #$8ED4, #$8ECF, - #$8FB1, #$9001, #$9006, #$8FF7, #$9000, #$8FFA, #$8FF4, #$9003, - #$8FFD, #$9005, #$8FF8, #$9095, #$90E1, #$90DD, #$90E2, #$9152, - #$914D, #$914C, #$91D8, #$91DD, #$91D7, #$91DC, #$91D9, #$9583, - #$9662, #$9663, #$9661, #$965B, #$965D, #$9664, #$9658, #$965E, - #$96BB, #$98E2, #$99AC, #$9AA8, #$9AD8, #$9B25, #$9B32, #$9B3C, - #$4E7E, #$507A, #$507D, #$505C, #$5047, #$5043, #$504C, #$505A, - #$5049, #$5065, #$5076, #$504E, #$5055, #$5075, - #$5074, #$5077, #$504F, #$500F, #$506F, #$506D, #$515C, #$5195, - #$51F0, #$526A, #$526F, #$52D2, #$52D9, #$52D8, #$52D5, #$5310, - #$530F, #$5319, #$533F, #$5340, #$533E, #$53C3, #$66FC, #$5546, - #$556A, #$5566, #$5544, #$555E, #$5561, #$5543, #$554A, #$5531, - #$5556, #$554F, #$5555, #$552F, #$5564, #$5538, #$552E, #$555C, - #$552C, #$5563, #$5533, #$5541, #$5557, #$5708, #$570B, #$5709, - #$57DF, #$5805, #$580A, #$5806, #$57E0, #$57E4, #$57FA, #$5802, - #$5835, #$57F7, #$57F9, #$5920, #$5962, #$5A36, #$5A41, #$5A49, - #$5A66, #$5A6A, #$5A40, #$5A3C, #$5A62, #$5A5A, #$5A46, #$5A4A, - #$5B70, #$5BC7, #$5BC5, #$5BC4, #$5BC2, #$5BBF, #$5BC6, #$5C09, - #$5C08, #$5C07, #$5C60, #$5C5C, #$5C5D, #$5D07, #$5D06, #$5D0E, - #$5D1B, #$5D16, #$5D22, #$5D11, #$5D29, #$5D14, - #$5D19, #$5D24, #$5D27, #$5D17, #$5DE2, #$5E38, #$5E36, #$5E33, - #$5E37, #$5EB7, #$5EB8, #$5EB6, #$5EB5, #$5EBE, #$5F35, #$5F37, - #$5F57, #$5F6C, #$5F69, #$5F6B, #$5F97, #$5F99, #$5F9E, #$5F98, - #$5FA1, #$5FA0, #$5F9C, #$607F, #$60A3, #$6089, #$60A0, #$60A8, - #$60CB, #$60B4, #$60E6, #$60BD, #$60C5, #$60BB, #$60B5, #$60DC, - #$60BC, #$60D8, #$60D5, #$60C6, #$60DF, #$60B8, #$60DA, #$60C7, - #$621A, #$621B, #$6248, #$63A0, #$63A7, #$6372, #$6396, #$63A2, - #$63A5, #$6377, #$6367, #$6398, #$63AA, #$6371, #$63A9, #$6389, - #$6383, #$639B, #$636B, #$63A8, #$6384, #$6388, #$6399, #$63A1, - #$63AC, #$6392, #$638F, #$6380, #$637B, #$6369, #$6368, #$637A, - #$655D, #$6556, #$6551, #$6559, #$6557, #$555F, #$654F, #$6558, - #$6555, #$6554, #$659C, #$659B, #$65AC, #$65CF, - #$65CB, #$65CC, #$65CE, #$665D, #$665A, #$6664, #$6668, #$6666, - #$665E, #$66F9, #$52D7, #$671B, #$6881, #$68AF, #$68A2, #$6893, - #$68B5, #$687F, #$6876, #$68B1, #$68A7, #$6897, #$68B0, #$6883, - #$68C4, #$68AD, #$6886, #$6885, #$6894, #$689D, #$68A8, #$689F, - #$68A1, #$6882, #$6B32, #$6BBA, #$6BEB, #$6BEC, #$6C2B, #$6D8E, - #$6DBC, #$6DF3, #$6DD9, #$6DB2, #$6DE1, #$6DCC, #$6DE4, #$6DFB, - #$6DFA, #$6E05, #$6DC7, #$6DCB, #$6DAF, #$6DD1, #$6DAE, #$6DDE, - #$6DF9, #$6DB8, #$6DF7, #$6DF5, #$6DC5, #$6DD2, #$6E1A, #$6DB5, - #$6DDA, #$6DEB, #$6DD8, #$6DEA, #$6DF1, #$6DEE, #$6DE8, #$6DC6, - #$6DC4, #$6DAA, #$6DEC, #$6DBF, #$6DE6, #$70F9, #$7109, #$710A, - #$70FD, #$70EF, #$723D, #$727D, #$7281, #$731C, #$731B, #$7316, - #$7313, #$7319, #$7387, #$7405, #$740A, #$7403, - #$7406, #$73FE, #$740D, #$74E0, #$74F6, #$74F7, #$751C, #$7522, - #$7565, #$7566, #$7562, #$7570, #$758F, #$75D4, #$75D5, #$75B5, - #$75CA, #$75CD, #$768E, #$76D4, #$76D2, #$76DB, #$7737, #$773E, - #$773C, #$7736, #$7738, #$773A, #$786B, #$7843, #$784E, #$7965, - #$7968, #$796D, #$79FB, #$7A92, #$7A95, #$7B20, #$7B28, #$7B1B, - #$7B2C, #$7B26, #$7B19, #$7B1E, #$7B2E, #$7C92, #$7C97, #$7C95, - #$7D46, #$7D43, #$7D71, #$7D2E, #$7D39, #$7D3C, #$7D40, #$7D30, - #$7D33, #$7D44, #$7D2F, #$7D42, #$7D32, #$7D31, #$7F3D, #$7F9E, - #$7F9A, #$7FCC, #$7FCE, #$7FD2, #$801C, #$804A, #$8046, #$812F, - #$8116, #$8123, #$812B, #$8129, #$8130, #$8124, #$8202, #$8235, - #$8237, #$8236, #$8239, #$838E, #$839E, #$8398, #$8378, #$83A2, - #$8396, #$83BD, #$83AB, #$8392, #$838A, #$8393, - #$8389, #$83A0, #$8377, #$837B, #$837C, #$8386, #$83A7, #$8655, - #$5F6A, #$86C7, #$86C0, #$86B6, #$86C4, #$86B5, #$86C6, #$86CB, - #$86B1, #$86AF, #$86C9, #$8853, #$889E, #$8888, #$88AB, #$8892, - #$8896, #$888D, #$888B, #$8993, #$898F, #$8A2A, #$8A1D, #$8A23, - #$8A25, #$8A31, #$8A2D, #$8A1F, #$8A1B, #$8A22, #$8C49, #$8C5A, - #$8CA9, #$8CAC, #$8CAB, #$8CA8, #$8CAA, #$8CA7, #$8D67, #$8D66, - #$8DBE, #$8DBA, #$8EDB, #$8EDF, #$9019, #$900D, #$901A, #$9017, - #$9023, #$901F, #$901D, #$9010, #$9015, #$901E, #$9020, #$900F, - #$9022, #$9016, #$901B, #$9014, #$90E8, #$90ED, #$90FD, #$9157, - #$91CE, #$91F5, #$91E6, #$91E3, #$91E7, #$91ED, #$91E9, #$9589, - #$966A, #$9675, #$9673, #$9678, #$9670, #$9674, #$9676, #$9677, - #$966C, #$96C0, #$96EA, #$96E9, #$7AE0, #$7ADF, - #$9802, #$9803, #$9B5A, #$9CE5, #$9E75, #$9E7F, #$9EA5, #$9EBB, - #$50A2, #$508D, #$5085, #$5099, #$5091, #$5080, #$5096, #$5098, - #$509A, #$6700, #$51F1, #$5272, #$5274, #$5275, #$5269, #$52DE, - #$52DD, #$52DB, #$535A, #$53A5, #$557B, #$5580, #$55A7, #$557C, - #$558A, #$559D, #$5598, #$5582, #$559C, #$55AA, #$5594, #$5587, - #$558B, #$5583, #$55B3, #$55AE, #$559F, #$553E, #$55B2, #$559A, - #$55BB, #$55AC, #$55B1, #$557E, #$5589, #$55AB, #$5599, #$570D, - #$582F, #$582A, #$5834, #$5824, #$5830, #$5831, #$5821, #$581D, - #$5820, #$58F9, #$58FA, #$5960, #$5A77, #$5A9A, #$5A7F, #$5A92, - #$5A9B, #$5AA7, #$5B73, #$5B71, #$5BD2, #$5BCC, #$5BD3, #$5BD0, - #$5C0A, #$5C0B, #$5C31, #$5D4C, #$5D50, #$5D34, #$5D47, #$5DFD, - #$5E45, #$5E3D, #$5E40, #$5E43, #$5E7E, #$5ECA, - #$5EC1, #$5EC2, #$5EC4, #$5F3C, #$5F6D, #$5FA9, #$5FAA, #$5FA8, - #$60D1, #$60E1, #$60B2, #$60B6, #$60E0, #$611C, #$6123, #$60FA, - #$6115, #$60F0, #$60FB, #$60F4, #$6168, #$60F1, #$610E, #$60F6, - #$6109, #$6100, #$6112, #$621F, #$6249, #$63A3, #$638C, #$63CF, - #$63C0, #$63E9, #$63C9, #$63C6, #$63CD, #$63D2, #$63E3, #$63D0, - #$63E1, #$63D6, #$63ED, #$63EE, #$6376, #$63F4, #$63EA, #$63DB, - #$6452, #$63DA, #$63F9, #$655E, #$6566, #$6562, #$6563, #$6591, - #$6590, #$65AF, #$666E, #$6670, #$6674, #$6676, #$666F, #$6691, - #$667A, #$667E, #$6677, #$66FE, #$66FF, #$671F, #$671D, #$68FA, - #$68D5, #$68E0, #$68D8, #$68D7, #$6905, #$68DF, #$68F5, #$68EE, - #$68E7, #$68F9, #$68D2, #$68F2, #$68E3, #$68CB, #$68CD, #$690D, - #$6912, #$690E, #$68C9, #$68DA, #$696E, #$68FB, - #$6B3E, #$6B3A, #$6B3D, #$6B98, #$6B96, #$6BBC, #$6BEF, #$6C2E, - #$6C2F, #$6C2C, #$6E2F, #$6E38, #$6E54, #$6E21, #$6E32, #$6E67, - #$6E4A, #$6E20, #$6E25, #$6E23, #$6E1B, #$6E5B, #$6E58, #$6E24, - #$6E56, #$6E6E, #$6E2D, #$6E26, #$6E6F, #$6E34, #$6E4D, #$6E3A, - #$6E2C, #$6E43, #$6E1D, #$6E3E, #$6ECB, #$6E89, #$6E19, #$6E4E, - #$6E63, #$6E44, #$6E72, #$6E69, #$6E5F, #$7119, #$711A, #$7126, - #$7130, #$7121, #$7136, #$716E, #$711C, #$724C, #$7284, #$7280, - #$7336, #$7325, #$7334, #$7329, #$743A, #$742A, #$7433, #$7422, - #$7425, #$7435, #$7436, #$7434, #$742F, #$741B, #$7426, #$7428, - #$7525, #$7526, #$756B, #$756A, #$75E2, #$75DB, #$75E3, #$75D9, - #$75D8, #$75DE, #$75E0, #$767B, #$767C, #$7696, #$7693, #$76B4, - #$76DC, #$774F, #$77ED, #$785D, #$786C, #$786F, - #$7A0D, #$7A08, #$7A0B, #$7A05, #$7A00, #$7A98, #$7A97, #$7A96, - #$7AE5, #$7AE3, #$7B49, #$7B56, #$7B46, #$7B50, #$7B52, #$7B54, - #$7B4D, #$7B4B, #$7B4F, #$7B51, #$7C9F, #$7CA5, #$7D5E, #$7D50, - #$7D68, #$7D55, #$7D2B, #$7D6E, #$7D72, #$7D61, #$7D66, #$7D62, - #$7D70, #$7D73, #$5584, #$7FD4, #$7FD5, #$800B, #$8052, #$8085, - #$8155, #$8154, #$814B, #$8151, #$814E, #$8139, #$8146, #$813E, - #$814C, #$8153, #$8174, #$8212, #$821C, #$83E9, #$8403, #$83F8, - #$840D, #$83E0, #$83C5, #$840B, #$83C1, #$83EF, #$83F1, #$83F4, - #$8457, #$840A, #$83F0, #$840C, #$83CC, #$83FD, #$83F2, #$83CA, - #$8438, #$840E, #$8404, #$83DC, #$8407, #$83D4, #$83DF, #$865B, - #$86DF, #$86D9, #$86ED, #$86D4, #$86DB, #$86E4, #$86D0, #$86DE, - #$8857, #$88C1, #$88C2, #$88B1, #$8983, #$8996, - #$8A3B, #$8A60, #$8A55, #$8A5E, #$8A3C, #$8A41, #$8A54, #$8A5B, - #$8A50, #$8A46, #$8A34, #$8A3A, #$8A36, #$8A56, #$8C61, #$8C82, - #$8CAF, #$8CBC, #$8CB3, #$8CBD, #$8CC1, #$8CBB, #$8CC0, #$8CB4, - #$8CB7, #$8CB6, #$8CBF, #$8CB8, #$8D8A, #$8D85, #$8D81, #$8DCE, - #$8DDD, #$8DCB, #$8DDA, #$8DD1, #$8DCC, #$8DDB, #$8DC6, #$8EFB, - #$8EF8, #$8EFC, #$8F9C, #$902E, #$9035, #$9031, #$9038, #$9032, - #$9036, #$9102, #$90F5, #$9109, #$90FE, #$9163, #$9165, #$91CF, - #$9214, #$9215, #$9223, #$9209, #$921E, #$920D, #$9210, #$9207, - #$9211, #$9594, #$958F, #$958B, #$9591, #$9593, #$9592, #$958E, - #$968A, #$968E, #$968B, #$967D, #$9685, #$9686, #$968D, #$9672, - #$9684, #$96C1, #$96C5, #$96C4, #$96C6, #$96C7, #$96EF, #$96F2, - #$97CC, #$9805, #$9806, #$9808, #$98E7, #$98EA, - #$98EF, #$98E9, #$98F2, #$98ED, #$99AE, #$99AD, #$9EC3, #$9ECD, - #$9ED1, #$4E82, #$50AD, #$50B5, #$50B2, #$50B3, #$50C5, #$50BE, - #$50AC, #$50B7, #$50BB, #$50AF, #$50C7, #$527F, #$5277, #$527D, - #$52DF, #$52E6, #$52E4, #$52E2, #$52E3, #$532F, #$55DF, #$55E8, - #$55D3, #$55E6, #$55CE, #$55DC, #$55C7, #$55D1, #$55E3, #$55E4, - #$55EF, #$55DA, #$55E1, #$55C5, #$55C6, #$55E5, #$55C9, #$5712, - #$5713, #$585E, #$5851, #$5858, #$5857, #$585A, #$5854, #$586B, - #$584C, #$586D, #$584A, #$5862, #$5852, #$584B, #$5967, #$5AC1, - #$5AC9, #$5ACC, #$5ABE, #$5ABD, #$5ABC, #$5AB3, #$5AC2, #$5AB2, - #$5D69, #$5D6F, #$5E4C, #$5E79, #$5EC9, #$5EC8, #$5F12, #$5F59, - #$5FAC, #$5FAE, #$611A, #$610F, #$6148, #$611F, #$60F3, #$611B, - #$60F9, #$6101, #$6108, #$614E, #$614C, #$6144, - #$614D, #$613E, #$6134, #$6127, #$610D, #$6106, #$6137, #$6221, - #$6222, #$6413, #$643E, #$641E, #$642A, #$642D, #$643D, #$642C, - #$640F, #$641C, #$6414, #$640D, #$6436, #$6416, #$6417, #$6406, - #$656C, #$659F, #$65B0, #$6697, #$6689, #$6687, #$6688, #$6696, - #$6684, #$6698, #$668D, #$6703, #$6994, #$696D, #$695A, #$6977, - #$6960, #$6954, #$6975, #$6930, #$6982, #$694A, #$6968, #$696B, - #$695E, #$6953, #$6979, #$6986, #$695D, #$6963, #$695B, #$6B47, - #$6B72, #$6BC0, #$6BBF, #$6BD3, #$6BFD, #$6EA2, #$6EAF, #$6ED3, - #$6EB6, #$6EC2, #$6E90, #$6E9D, #$6EC7, #$6EC5, #$6EA5, #$6E98, - #$6EBC, #$6EBA, #$6EAB, #$6ED1, #$6E96, #$6E9C, #$6EC4, #$6ED4, - #$6EAA, #$6EA7, #$6EB4, #$714E, #$7159, #$7169, #$7164, #$7149, - #$7167, #$715C, #$716C, #$7166, #$714C, #$7165, - #$715E, #$7146, #$7168, #$7156, #$723A, #$7252, #$7337, #$7345, - #$733F, #$733E, #$746F, #$745A, #$7455, #$745F, #$745E, #$7441, - #$743F, #$7459, #$745B, #$745C, #$7576, #$7578, #$7600, #$75F0, - #$7601, #$75F2, #$75F1, #$75FA, #$75FF, #$75F4, #$75F3, #$76DE, - #$76DF, #$775B, #$776B, #$7766, #$775E, #$7763, #$7779, #$776A, - #$776C, #$775C, #$7765, #$7768, #$7762, #$77EE, #$788E, #$78B0, - #$7897, #$7898, #$788C, #$7889, #$787C, #$7891, #$7893, #$787F, - #$797A, #$797F, #$7981, #$842C, #$79BD, #$7A1C, #$7A1A, #$7A20, - #$7A14, #$7A1F, #$7A1E, #$7A9F, #$7AA0, #$7B77, #$7BC0, #$7B60, - #$7B6E, #$7B67, #$7CB1, #$7CB3, #$7CB5, #$7D93, #$7D79, #$7D91, - #$7D81, #$7D8F, #$7D5B, #$7F6E, #$7F69, #$7F6A, #$7F72, #$7FA9, - #$7FA8, #$7FA4, #$8056, #$8058, #$8086, #$8084, - #$8171, #$8170, #$8178, #$8165, #$816E, #$8173, #$816B, #$8179, - #$817A, #$8166, #$8205, #$8247, #$8482, #$8477, #$843D, #$8431, - #$8475, #$8466, #$846B, #$8449, #$846C, #$845B, #$843C, #$8435, - #$8461, #$8463, #$8469, #$846D, #$8446, #$865E, #$865C, #$865F, - #$86F9, #$8713, #$8708, #$8707, #$8700, #$86FE, #$86FB, #$8702, - #$8703, #$8706, #$870A, #$8859, #$88DF, #$88D4, #$88D9, #$88DC, - #$88D8, #$88DD, #$88E1, #$88CA, #$88D5, #$88D2, #$899C, #$89E3, - #$8A6B, #$8A72, #$8A73, #$8A66, #$8A69, #$8A70, #$8A87, #$8A7C, - #$8A63, #$8AA0, #$8A71, #$8A85, #$8A6D, #$8A62, #$8A6E, #$8A6C, - #$8A79, #$8A7B, #$8A3E, #$8A68, #$8C62, #$8C8A, #$8C89, #$8CCA, - #$8CC7, #$8CC8, #$8CC4, #$8CB2, #$8CC3, #$8CC2, #$8CC5, #$8DE1, - #$8DDF, #$8DE8, #$8DEF, #$8DF3, #$8DFA, #$8DEA, - #$8DE4, #$8DE6, #$8EB2, #$8F03, #$8F09, #$8EFE, #$8F0A, #$8F9F, - #$8FB2, #$904B, #$904A, #$9053, #$9042, #$9054, #$903C, #$9055, - #$9050, #$9047, #$904F, #$904E, #$904D, #$9051, #$903E, #$9041, - #$9112, #$9117, #$916C, #$916A, #$9169, #$91C9, #$9237, #$9257, - #$9238, #$923D, #$9240, #$923E, #$925B, #$924B, #$9264, #$9251, - #$9234, #$9249, #$924D, #$9245, #$9239, #$923F, #$925A, #$9598, - #$9698, #$9694, #$9695, #$96CD, #$96CB, #$96C9, #$96CA, #$96F7, - #$96FB, #$96F9, #$96F6, #$9756, #$9774, #$9776, #$9810, #$9811, - #$9813, #$980A, #$9812, #$980C, #$98FC, #$98F4, #$98FD, #$98FE, - #$99B3, #$99B1, #$99B4, #$9AE1, #$9CE9, #$9E82, #$9F0E, #$9F13, - #$9F20, #$50E7, #$50EE, #$50E5, #$50D6, #$50ED, #$50DA, #$50D5, - #$50CF, #$50D1, #$50F1, #$50CE, #$50E9, #$5162, - #$51F3, #$5283, #$5282, #$5331, #$53AD, #$55FE, #$5600, #$561B, - #$5617, #$55FD, #$5614, #$5606, #$5609, #$560D, #$560E, #$55F7, - #$5616, #$561F, #$5608, #$5610, #$55F6, #$5718, #$5716, #$5875, - #$587E, #$5883, #$5893, #$588A, #$5879, #$5885, #$587D, #$58FD, - #$5925, #$5922, #$5924, #$596A, #$5969, #$5AE1, #$5AE6, #$5AE9, - #$5AD7, #$5AD6, #$5AD8, #$5AE3, #$5B75, #$5BDE, #$5BE7, #$5BE1, - #$5BE5, #$5BE6, #$5BE8, #$5BE2, #$5BE4, #$5BDF, #$5C0D, #$5C62, - #$5D84, #$5D87, #$5E5B, #$5E63, #$5E55, #$5E57, #$5E54, #$5ED3, - #$5ED6, #$5F0A, #$5F46, #$5F70, #$5FB9, #$6147, #$613F, #$614B, - #$6177, #$6162, #$6163, #$615F, #$615A, #$6158, #$6175, #$622A, - #$6487, #$6458, #$6454, #$64A4, #$6478, #$645F, #$647A, #$6451, - #$6467, #$6434, #$646D, #$647B, #$6572, #$65A1, - #$65D7, #$65D6, #$66A2, #$66A8, #$669D, #$699C, #$69A8, #$6995, - #$69C1, #$69AE, #$69D3, #$69CB, #$699B, #$69B7, #$69BB, #$69AB, - #$69B4, #$69D0, #$69CD, #$69AD, #$69CC, #$69A6, #$69C3, #$69A3, - #$6B49, #$6B4C, #$6C33, #$6F33, #$6F14, #$6EFE, #$6F13, #$6EF4, - #$6F29, #$6F3E, #$6F20, #$6F2C, #$6F0F, #$6F02, #$6F22, #$6EFF, - #$6EEF, #$6F06, #$6F31, #$6F38, #$6F32, #$6F23, #$6F15, #$6F2B, - #$6F2F, #$6F88, #$6F2A, #$6EEC, #$6F01, #$6EF2, #$6ECC, #$6EF7, - #$7194, #$7199, #$717D, #$718A, #$7184, #$7192, #$723E, #$7292, - #$7296, #$7344, #$7350, #$7464, #$7463, #$746A, #$7470, #$746D, - #$7504, #$7591, #$7627, #$760D, #$760B, #$7609, #$7613, #$76E1, - #$76E3, #$7784, #$777D, #$777F, #$7761, #$78C1, #$789F, #$78A7, - #$78B3, #$78A9, #$78A3, #$798E, #$798F, #$798D, - #$7A2E, #$7A31, #$7AAA, #$7AA9, #$7AED, #$7AEF, #$7BA1, #$7B95, - #$7B8B, #$7B75, #$7B97, #$7B9D, #$7B94, #$7B8F, #$7BB8, #$7B87, - #$7B84, #$7CB9, #$7CBD, #$7CBE, #$7DBB, #$7DB0, #$7D9C, #$7DBD, - #$7DBE, #$7DA0, #$7DCA, #$7DB4, #$7DB2, #$7DB1, #$7DBA, #$7DA2, - #$7DBF, #$7DB5, #$7DB8, #$7DAD, #$7DD2, #$7DC7, #$7DAC, #$7F70, - #$7FE0, #$7FE1, #$7FDF, #$805E, #$805A, #$8087, #$8150, #$8180, - #$818F, #$8188, #$818A, #$817F, #$8182, #$81E7, #$81FA, #$8207, - #$8214, #$821E, #$824B, #$84C9, #$84BF, #$84C6, #$84C4, #$8499, - #$849E, #$84B2, #$849C, #$84CB, #$84B8, #$84C0, #$84D3, #$8490, - #$84BC, #$84D1, #$84CA, #$873F, #$871C, #$873B, #$8722, #$8725, - #$8734, #$8718, #$8755, #$8737, #$8729, #$88F3, #$8902, #$88F4, - #$88F9, #$88F8, #$88FD, #$88E8, #$891A, #$88EF, - #$8AA6, #$8A8C, #$8A9E, #$8AA3, #$8A8D, #$8AA1, #$8A93, #$8AA4, - #$8AAA, #$8AA5, #$8AA8, #$8A98, #$8A91, #$8A9A, #$8AA7, #$8C6A, - #$8C8D, #$8C8C, #$8CD3, #$8CD1, #$8CD2, #$8D6B, #$8D99, #$8D95, - #$8DFC, #$8F14, #$8F12, #$8F15, #$8F13, #$8FA3, #$9060, #$9058, - #$905C, #$9063, #$9059, #$905E, #$9062, #$905D, #$905B, #$9119, - #$9118, #$911E, #$9175, #$9178, #$9177, #$9174, #$9278, #$92AC, - #$9280, #$9285, #$9298, #$9296, #$927B, #$9293, #$929C, #$92A8, - #$927C, #$9291, #$95A1, #$95A8, #$95A9, #$95A3, #$95A5, #$95A4, - #$9699, #$969C, #$969B, #$96CC, #$96D2, #$9700, #$977C, #$9785, - #$97F6, #$9817, #$9818, #$98AF, #$98B1, #$9903, #$9905, #$990C, - #$9909, #$99C1, #$9AAF, #$9AB0, #$9AE6, #$9B41, #$9B42, #$9CF4, - #$9CF6, #$9CF3, #$9EBC, #$9F3B, #$9F4A, #$5104, - #$5100, #$50FB, #$50F5, #$50F9, #$5102, #$5108, #$5109, #$5105, - #$51DC, #$5287, #$5288, #$5289, #$528D, #$528A, #$52F0, #$53B2, - #$562E, #$563B, #$5639, #$5632, #$563F, #$5634, #$5629, #$5653, - #$564E, #$5657, #$5674, #$5636, #$562F, #$5630, #$5880, #$589F, - #$589E, #$58B3, #$589C, #$58AE, #$58A9, #$58A6, #$596D, #$5B09, - #$5AFB, #$5B0B, #$5AF5, #$5B0C, #$5B08, #$5BEE, #$5BEC, #$5BE9, - #$5BEB, #$5C64, #$5C65, #$5D9D, #$5D94, #$5E62, #$5E5F, #$5E61, - #$5EE2, #$5EDA, #$5EDF, #$5EDD, #$5EE3, #$5EE0, #$5F48, #$5F71, - #$5FB7, #$5FB5, #$6176, #$6167, #$616E, #$615D, #$6155, #$6182, - #$617C, #$6170, #$616B, #$617E, #$61A7, #$6190, #$61AB, #$618E, - #$61AC, #$619A, #$61A4, #$6194, #$61AE, #$622E, #$6469, #$646F, - #$6479, #$649E, #$64B2, #$6488, #$6490, #$64B0, - #$64A5, #$6493, #$6495, #$64A9, #$6492, #$64AE, #$64AD, #$64AB, - #$649A, #$64AC, #$6499, #$64A2, #$64B3, #$6575, #$6577, #$6578, - #$66AE, #$66AB, #$66B4, #$66B1, #$6A23, #$6A1F, #$69E8, #$6A01, - #$6A1E, #$6A19, #$69FD, #$6A21, #$6A13, #$6A0A, #$69F3, #$6A02, - #$6A05, #$69ED, #$6A11, #$6B50, #$6B4E, #$6BA4, #$6BC5, #$6BC6, - #$6F3F, #$6F7C, #$6F84, #$6F51, #$6F66, #$6F54, #$6F86, #$6F6D, - #$6F5B, #$6F78, #$6F6E, #$6F8E, #$6F7A, #$6F70, #$6F64, #$6F97, - #$6F58, #$6ED5, #$6F6F, #$6F60, #$6F5F, #$719F, #$71AC, #$71B1, - #$71A8, #$7256, #$729B, #$734E, #$7357, #$7469, #$748B, #$7483, - #$747E, #$7480, #$757F, #$7620, #$7629, #$761F, #$7624, #$7626, - #$7621, #$7622, #$769A, #$76BA, #$76E4, #$778E, #$7787, #$778C, - #$7791, #$778B, #$78CB, #$78C5, #$78BA, #$78CA, - #$78BE, #$78D5, #$78BC, #$78D0, #$7A3F, #$7A3C, #$7A40, #$7A3D, - #$7A37, #$7A3B, #$7AAF, #$7AAE, #$7BAD, #$7BB1, #$7BC4, #$7BB4, - #$7BC6, #$7BC7, #$7BC1, #$7BA0, #$7BCC, #$7CCA, #$7DE0, #$7DF4, - #$7DEF, #$7DFB, #$7DD8, #$7DEC, #$7DDD, #$7DE8, #$7DE3, #$7DDA, - #$7DDE, #$7DE9, #$7D9E, #$7DD9, #$7DF2, #$7DF9, #$7F75, #$7F77, - #$7FAF, #$7FE9, #$8026, #$819B, #$819C, #$819D, #$81A0, #$819A, - #$8198, #$8517, #$853D, #$851A, #$84EE, #$852C, #$852D, #$8513, - #$8511, #$8523, #$8521, #$8514, #$84EC, #$8525, #$84FF, #$8506, - #$8782, #$8774, #$8776, #$8760, #$8766, #$8778, #$8768, #$8759, - #$8757, #$874C, #$8753, #$885B, #$885D, #$8910, #$8907, #$8912, - #$8913, #$8915, #$890A, #$8ABC, #$8AD2, #$8AC7, #$8AC4, #$8A95, - #$8ACB, #$8AF8, #$8AB2, #$8AC9, #$8AC2, #$8ABF, - #$8AB0, #$8AD6, #$8ACD, #$8AB6, #$8AB9, #$8ADB, #$8C4C, #$8C4E, - #$8C6C, #$8CE0, #$8CDE, #$8CE6, #$8CE4, #$8CEC, #$8CED, #$8CE2, - #$8CE3, #$8CDC, #$8CEA, #$8CE1, #$8D6D, #$8D9F, #$8DA3, #$8E2B, - #$8E10, #$8E1D, #$8E22, #$8E0F, #$8E29, #$8E1F, #$8E21, #$8E1E, - #$8EBA, #$8F1D, #$8F1B, #$8F1F, #$8F29, #$8F26, #$8F2A, #$8F1C, - #$8F1E, #$8F25, #$9069, #$906E, #$9068, #$906D, #$9077, #$9130, - #$912D, #$9127, #$9131, #$9187, #$9189, #$918B, #$9183, #$92C5, - #$92BB, #$92B7, #$92EA, #$92E4, #$92C1, #$92B3, #$92BC, #$92D2, - #$92C7, #$92F0, #$92B2, #$95AD, #$95B1, #$9704, #$9706, #$9707, - #$9709, #$9760, #$978D, #$978B, #$978F, #$9821, #$982B, #$981C, - #$98B3, #$990A, #$9913, #$9912, #$9918, #$99DD, #$99D0, #$99DF, - #$99DB, #$99D1, #$99D5, #$99D2, #$99D9, #$9AB7, - #$9AEE, #$9AEF, #$9B27, #$9B45, #$9B44, #$9B77, #$9B6F, #$9D06, - #$9D09, #$9D03, #$9EA9, #$9EBE, #$9ECE, #$58A8, #$9F52, #$5112, - #$5118, #$5114, #$5110, #$5115, #$5180, #$51AA, #$51DD, #$5291, - #$5293, #$52F3, #$5659, #$566B, #$5679, #$5669, #$5664, #$5678, - #$566A, #$5668, #$5665, #$5671, #$566F, #$566C, #$5662, #$5676, - #$58C1, #$58BE, #$58C7, #$58C5, #$596E, #$5B1D, #$5B34, #$5B78, - #$5BF0, #$5C0E, #$5F4A, #$61B2, #$6191, #$61A9, #$618A, #$61CD, - #$61B6, #$61BE, #$61CA, #$61C8, #$6230, #$64C5, #$64C1, #$64CB, - #$64BB, #$64BC, #$64DA, #$64C4, #$64C7, #$64C2, #$64CD, #$64BF, - #$64D2, #$64D4, #$64BE, #$6574, #$66C6, #$66C9, #$66B9, #$66C4, - #$66C7, #$66B8, #$6A3D, #$6A38, #$6A3A, #$6A59, #$6A6B, #$6A58, - #$6A39, #$6A44, #$6A62, #$6A61, #$6A4B, #$6A47, - #$6A35, #$6A5F, #$6A48, #$6B59, #$6B77, #$6C05, #$6FC2, #$6FB1, - #$6FA1, #$6FC3, #$6FA4, #$6FC1, #$6FA7, #$6FB3, #$6FC0, #$6FB9, - #$6FB6, #$6FA6, #$6FA0, #$6FB4, #$71BE, #$71C9, #$71D0, #$71D2, - #$71C8, #$71D5, #$71B9, #$71CE, #$71D9, #$71DC, #$71C3, #$71C4, - #$7368, #$749C, #$74A3, #$7498, #$749F, #$749E, #$74E2, #$750C, - #$750D, #$7634, #$7638, #$763A, #$76E7, #$76E5, #$77A0, #$779E, - #$779F, #$77A5, #$78E8, #$78DA, #$78EC, #$78E7, #$79A6, #$7A4D, - #$7A4E, #$7A46, #$7A4C, #$7A4B, #$7ABA, #$7BD9, #$7C11, #$7BC9, - #$7BE4, #$7BDB, #$7BE1, #$7BE9, #$7BE6, #$7CD5, #$7CD6, #$7E0A, - #$7E11, #$7E08, #$7E1B, #$7E23, #$7E1E, #$7E1D, #$7E09, #$7E10, - #$7F79, #$7FB2, #$7FF0, #$7FF1, #$7FEE, #$8028, #$81B3, #$81A9, - #$81A8, #$81FB, #$8208, #$8258, #$8259, #$854A, - #$8559, #$8548, #$8568, #$8569, #$8543, #$8549, #$856D, #$856A, - #$855E, #$8783, #$879F, #$879E, #$87A2, #$878D, #$8861, #$892A, - #$8932, #$8925, #$892B, #$8921, #$89AA, #$89A6, #$8AE6, #$8AFA, - #$8AEB, #$8AF1, #$8B00, #$8ADC, #$8AE7, #$8AEE, #$8AFE, #$8B01, - #$8B02, #$8AF7, #$8AED, #$8AF3, #$8AF6, #$8AFC, #$8C6B, #$8C6D, - #$8C93, #$8CF4, #$8E44, #$8E31, #$8E34, #$8E42, #$8E39, #$8E35, - #$8F3B, #$8F2F, #$8F38, #$8F33, #$8FA8, #$8FA6, #$9075, #$9074, - #$9078, #$9072, #$907C, #$907A, #$9134, #$9192, #$9320, #$9336, - #$92F8, #$9333, #$932F, #$9322, #$92FC, #$932B, #$9304, #$931A, - #$9310, #$9326, #$9321, #$9315, #$932E, #$9319, #$95BB, #$96A7, - #$96A8, #$96AA, #$96D5, #$970E, #$9711, #$9716, #$970D, #$9713, - #$970F, #$975B, #$975C, #$9766, #$9798, #$9830, - #$9838, #$983B, #$9837, #$982D, #$9839, #$9824, #$9910, #$9928, - #$991E, #$991B, #$9921, #$991A, #$99ED, #$99E2, #$99F1, #$9AB8, - #$9ABC, #$9AFB, #$9AED, #$9B28, #$9B91, #$9D15, #$9D23, #$9D26, - #$9D28, #$9D12, #$9D1B, #$9ED8, #$9ED4, #$9F8D, #$9F9C, #$512A, - #$511F, #$5121, #$5132, #$52F5, #$568E, #$5680, #$5690, #$5685, - #$5687, #$568F, #$58D5, #$58D3, #$58D1, #$58CE, #$5B30, #$5B2A, - #$5B24, #$5B7A, #$5C37, #$5C68, #$5DBC, #$5DBA, #$5DBD, #$5DB8, - #$5E6B, #$5F4C, #$5FBD, #$61C9, #$61C2, #$61C7, #$61E6, #$61CB, - #$6232, #$6234, #$64CE, #$64CA, #$64D8, #$64E0, #$64F0, #$64E6, - #$64EC, #$64F1, #$64E2, #$64ED, #$6582, #$6583, #$66D9, #$66D6, - #$6A80, #$6A94, #$6A84, #$6AA2, #$6A9C, #$6ADB, #$6AA3, #$6A7E, - #$6A97, #$6A90, #$6AA0, #$6B5C, #$6BAE, #$6BDA, - #$6C08, #$6FD8, #$6FF1, #$6FDF, #$6FE0, #$6FDB, #$6FE4, #$6FEB, - #$6FEF, #$6F80, #$6FEC, #$6FE1, #$6FE9, #$6FD5, #$6FEE, #$6FF0, - #$71E7, #$71DF, #$71EE, #$71E6, #$71E5, #$71ED, #$71EC, #$71F4, - #$71E0, #$7235, #$7246, #$7370, #$7372, #$74A9, #$74B0, #$74A6, - #$74A8, #$7646, #$7642, #$764C, #$76EA, #$77B3, #$77AA, #$77B0, - #$77AC, #$77A7, #$77AD, #$77EF, #$78F7, #$78FA, #$78F4, #$78EF, - #$7901, #$79A7, #$79AA, #$7A57, #$7ABF, #$7C07, #$7C0D, #$7BFE, - #$7BF7, #$7C0C, #$7BE0, #$7CE0, #$7CDC, #$7CDE, #$7CE2, #$7CDF, - #$7CD9, #$7CDD, #$7E2E, #$7E3E, #$7E46, #$7E37, #$7E32, #$7E43, - #$7E2B, #$7E3D, #$7E31, #$7E45, #$7E41, #$7E34, #$7E39, #$7E48, - #$7E35, #$7E3F, #$7E2F, #$7F44, #$7FF3, #$7FFC, #$8071, #$8072, - #$8070, #$806F, #$8073, #$81C6, #$81C3, #$81BA, - #$81C2, #$81C0, #$81BF, #$81BD, #$81C9, #$81BE, #$81E8, #$8209, - #$8271, #$85AA, #$8584, #$857E, #$859C, #$8591, #$8594, #$85AF, - #$859B, #$8587, #$85A8, #$858A, #$85A6, #$8667, #$87C0, #$87D1, - #$87B3, #$87D2, #$87C6, #$87AB, #$87BB, #$87BA, #$87C8, #$87CB, - #$893B, #$8936, #$8944, #$8938, #$893D, #$89AC, #$8B0E, #$8B17, - #$8B19, #$8B1B, #$8B0A, #$8B20, #$8B1D, #$8B04, #$8B10, #$8C41, - #$8C3F, #$8C73, #$8CFA, #$8CFD, #$8CFC, #$8CF8, #$8CFB, #$8DA8, - #$8E49, #$8E4B, #$8E48, #$8E4A, #$8F44, #$8F3E, #$8F42, #$8F45, - #$8F3F, #$907F, #$907D, #$9084, #$9081, #$9082, #$9080, #$9139, - #$91A3, #$919E, #$919C, #$934D, #$9382, #$9328, #$9375, #$934A, - #$9365, #$934B, #$9318, #$937E, #$936C, #$935B, #$9370, #$935A, - #$9354, #$95CA, #$95CB, #$95CC, #$95C8, #$95C6, - #$96B1, #$96B8, #$96D6, #$971C, #$971E, #$97A0, #$97D3, #$9846, - #$98B6, #$9935, #$9A01, #$99FF, #$9BAE, #$9BAB, #$9BAA, #$9BAD, - #$9D3B, #$9D3F, #$9E8B, #$9ECF, #$9EDE, #$9EDC, #$9EDD, #$9EDB, - #$9F3E, #$9F4B, #$53E2, #$5695, #$56AE, #$58D9, #$58D8, #$5B38, - #$5F5E, #$61E3, #$6233, #$64F4, #$64F2, #$64FE, #$6506, #$64FA, - #$64FB, #$64F7, #$65B7, #$66DC, #$6726, #$6AB3, #$6AAC, #$6AC3, - #$6ABB, #$6AB8, #$6AC2, #$6AAE, #$6AAF, #$6B5F, #$6B78, #$6BAF, - #$7009, #$700B, #$6FFE, #$7006, #$6FFA, #$7011, #$700F, #$71FB, - #$71FC, #$71FE, #$71F8, #$7377, #$7375, #$74A7, #$74BF, #$7515, - #$7656, #$7658, #$7652, #$77BD, #$77BF, #$77BB, #$77BC, #$790E, - #$79AE, #$7A61, #$7A62, #$7A60, #$7AC4, #$7AC5, #$7C2B, #$7C27, - #$7C2A, #$7C1E, #$7C23, #$7C21, #$7CE7, #$7E54, - #$7E55, #$7E5E, #$7E5A, #$7E61, #$7E52, #$7E59, #$7F48, #$7FF9, - #$7FFB, #$8077, #$8076, #$81CD, #$81CF, #$820A, #$85CF, #$85A9, - #$85CD, #$85D0, #$85C9, #$85B0, #$85BA, #$85B9, #$87EF, #$87EC, - #$87F2, #$87E0, #$8986, #$89B2, #$89F4, #$8B28, #$8B39, #$8B2C, - #$8B2B, #$8C50, #$8D05, #$8E59, #$8E63, #$8E66, #$8E64, #$8E5F, - #$8E55, #$8EC0, #$8F49, #$8F4D, #$9087, #$9083, #$9088, #$91AB, - #$91AC, #$91D0, #$9394, #$938A, #$9396, #$93A2, #$93B3, #$93AE, - #$93AC, #$93B0, #$9398, #$939A, #$9397, #$95D4, #$95D6, #$95D0, - #$95D5, #$96E2, #$96DC, #$96D9, #$96DB, #$96DE, #$9724, #$97A3, - #$97A6, #$97AD, #$97F9, #$984D, #$984F, #$984C, #$984E, #$9853, - #$98BA, #$993E, #$993F, #$993D, #$992E, #$99A5, #$9A0E, #$9AC1, - #$9B03, #$9B06, #$9B4F, #$9B4E, #$9B4D, #$9BCA, - #$9BC9, #$9BFD, #$9BC8, #$9BC0, #$9D51, #$9D5D, #$9D60, #$9EE0, - #$9F15, #$9F2C, #$5133, #$56A5, #$56A8, #$58DE, #$58DF, #$58E2, - #$5BF5, #$9F90, #$5EEC, #$61F2, #$61F7, #$61F6, #$61F5, #$6500, - #$650F, #$66E0, #$66DD, #$6AE5, #$6ADD, #$6ADA, #$6AD3, #$701B, - #$701F, #$7028, #$701A, #$701D, #$7015, #$7018, #$7206, #$720D, - #$7258, #$72A2, #$7378, #$737A, #$74BD, #$74CA, #$74E3, #$7587, - #$7586, #$765F, #$7661, #$77C7, #$7919, #$79B1, #$7A6B, #$7A69, - #$7C3E, #$7C3F, #$7C38, #$7C3D, #$7C37, #$7C40, #$7E6B, #$7E6D, - #$7E79, #$7E69, #$7E6A, #$7E73, #$7F85, #$7FB6, #$7FB9, #$7FB8, - #$81D8, #$85E9, #$85DD, #$85EA, #$85D5, #$85E4, #$85E5, #$85F7, - #$87FB, #$8805, #$880D, #$87F9, #$87FE, #$8960, #$895F, #$8956, - #$895E, #$8B41, #$8B5C, #$8B58, #$8B49, #$8B5A, - #$8B4E, #$8B4F, #$8B46, #$8B59, #$8D08, #$8D0A, #$8E7C, #$8E72, - #$8E87, #$8E76, #$8E6C, #$8E7A, #$8E74, #$8F54, #$8F4E, #$8FAD, - #$908A, #$908B, #$91B1, #$91AE, #$93E1, #$93D1, #$93DF, #$93C3, - #$93C8, #$93DC, #$93DD, #$93D6, #$93E2, #$93CD, #$93D8, #$93E4, - #$93D7, #$93E8, #$95DC, #$96B4, #$96E3, #$972A, #$9727, #$9761, - #$97DC, #$97FB, #$985E, #$9858, #$985B, #$98BC, #$9945, #$9949, - #$9A16, #$9A19, #$9B0D, #$9BE8, #$9BE7, #$9BD6, #$9BDB, #$9D89, - #$9D61, #$9D72, #$9D6A, #$9D6C, #$9E92, #$9E97, #$9E93, #$9EB4, - #$52F8, #$56B7, #$56B6, #$56B4, #$56BC, #$58E4, #$5B40, #$5B43, - #$5B7D, #$5BF6, #$5DC9, #$61F8, #$61FA, #$6518, #$6514, #$6519, - #$66E6, #$6727, #$6AEC, #$703E, #$7030, #$7032, #$7210, #$737B, - #$74CF, #$7662, #$7665, #$7926, #$792A, #$792C, - #$792B, #$7AC7, #$7AF6, #$7C4C, #$7C43, #$7C4D, #$7CEF, #$7CF0, - #$8FAE, #$7E7D, #$7E7C, #$7E82, #$7F4C, #$8000, #$81DA, #$8266, - #$85FB, #$85F9, #$8611, #$85FA, #$8606, #$860B, #$8607, #$860A, - #$8814, #$8815, #$8964, #$89BA, #$89F8, #$8B70, #$8B6C, #$8B66, - #$8B6F, #$8B5F, #$8B6B, #$8D0F, #$8D0D, #$8E89, #$8E81, #$8E85, - #$8E82, #$91B4, #$91CB, #$9418, #$9403, #$93FD, #$95E1, #$9730, - #$98C4, #$9952, #$9951, #$99A8, #$9A2B, #$9A30, #$9A37, #$9A35, - #$9C13, #$9C0D, #$9E79, #$9EB5, #$9EE8, #$9F2F, #$9F5F, #$9F63, - #$9F61, #$5137, #$5138, #$56C1, #$56C0, #$56C2, #$5914, #$5C6C, - #$5DCD, #$61FC, #$61FE, #$651D, #$651C, #$6595, #$66E9, #$6AFB, - #$6B04, #$6AFA, #$6BB2, #$704C, #$721B, #$72A7, #$74D6, #$74D4, - #$7669, #$77D3, #$7C50, #$7E8F, #$7E8C, #$7FBC, - #$8617, #$862D, #$861A, #$8823, #$8822, #$8821, #$881F, #$896A, - #$896C, #$89BD, #$8B74, #$8B77, #$8B7D, #$8D13, #$8E8A, #$8E8D, - #$8E8B, #$8F5F, #$8FAF, #$91BA, #$942E, #$9433, #$9435, #$943A, - #$9438, #$9432, #$942B, #$95E2, #$9738, #$9739, #$9732, #$97FF, - #$9867, #$9865, #$9957, #$9A45, #$9A43, #$9A40, #$9A3E, #$9ACF, - #$9B54, #$9B51, #$9C2D, #$9C25, #$9DAF, #$9DB4, #$9DC2, #$9DB8, - #$9E9D, #$9EEF, #$9F19, #$9F5C, #$9F66, #$9F67, #$513C, #$513B, - #$56C8, #$56CA, #$56C9, #$5B7F, #$5DD4, #$5DD2, #$5F4E, #$61FF, - #$6524, #$6B0A, #$6B61, #$7051, #$7058, #$7380, #$74E4, #$758A, - #$766E, #$766C, #$79B3, #$7C60, #$7C5F, #$807E, #$807D, #$81DF, - #$8972, #$896F, #$89FC, #$8B80, #$8D16, #$8D17, #$8E91, #$8E93, - #$8F61, #$9148, #$9444, #$9451, #$9452, #$973D, - #$973E, #$97C3, #$97C1, #$986B, #$9955, #$9A55, #$9A4D, #$9AD2, - #$9B1A, #$9C49, #$9C31, #$9C3E, #$9C3B, #$9DD3, #$9DD7, #$9F34, - #$9F6C, #$9F6A, #$9F94, #$56CC, #$5DD6, #$6200, #$6523, #$652B, - #$652A, #$66EC, #$6B10, #$74DA, #$7ACA, #$7C64, #$7C63, #$7C65, - #$7E93, #$7E96, #$7E94, #$81E2, #$8638, #$863F, #$8831, #$8B8A, - #$9090, #$908F, #$9463, #$9460, #$9464, #$9768, #$986F, #$995C, - #$9A5A, #$9A5B, #$9A57, #$9AD3, #$9AD4, #$9AD1, #$9C54, #$9C57, - #$9C56, #$9DE5, #$9E9F, #$9EF4, #$56D1, #$58E9, #$652C, #$705E, - #$7671, #$7672, #$77D7, #$7F50, #$7F88, #$8836, #$8839, #$8862, - #$8B93, #$8B92, #$8B96, #$8277, #$8D1B, #$91C0, #$946A, #$9742, - #$9748, #$9744, #$97C6, #$9870, #$9A5F, #$9B22, #$9B58, #$9C5F, - #$9DF9, #$9DFA, #$9E7C, #$9E7D, #$9F07, #$9F77, - #$9F72, #$5EF3, #$6B16, #$7063, #$7C6C, #$7C6E, #$883B, #$89C0, - #$8EA1, #$91C1, #$9472, #$9470, #$9871, #$995E, #$9AD6, #$9B23, - #$9ECC, #$7064, #$77DA, #$8B9A, #$9477, #$97C9, #$9A62, #$9A65, - #$7E9C, #$8B9C, #$8EAA, #$91C5, #$947D, #$947E, #$947C, #$9C77, - #$9C78, #$9EF7, #$8C54, #$947F, #$9E1A, #$7228, #$9A6A, #$9B31, - #$9E1B, #$9E1E, #$7C72); - CNS11643_2Map: array[0..7649] of TBuffChar = ( - #$4E42, #$4E5C, #$51F5, #$531A, #$5382, #$4E07, #$4E0C, #$4E47, - #$4E8D, #$56D7, #$5C6E, #$5F73, #$4E0F, #$5187, #$4E0E, #$4E2E, - #$4E93, #$4EC2, #$4EC9, #$4EC8, #$5198, #$52FC, #$536C, #$53B9, - #$5720, #$5903, #$592C, #$5C10, #$5DFF, #$65E1, #$6BB3, #$6BCC, - #$6C14, #$723F, #$4E31, #$4E3C, #$4EE8, #$4EDC, #$4EE9, #$4EE1, - #$4EDD, #$4EDA, #$520C, #$5209, #$531C, #$534C, #$5722, #$5723, - #$5917, #$592F, #$5B81, #$5B84, #$5C12, #$5C3B, #$5C74, #$5C73, - #$5E04, #$5E80, #$5E82, #$5FC9, #$6209, #$6250, #$6C15, #$6C36, - #$6C43, #$6C3F, #$6C3B, #$72AE, #$72B0, #$738A, #$79B8, #$808A, - #$961E, #$4F0E, #$4F18, #$4F2C, #$4EF5, #$4F14, #$4EF1, #$4F00, - #$4EF7, #$4F08, #$4F1D, #$4F02, #$4F05, #$4F22, #$4F13, #$4F04, - #$4EF4, #$4F12, #$51B1, #$5213, #$5210, #$52A6, - #$5322, #$531F, #$534D, #$538A, #$5407, #$56E1, #$56DF, #$572E, - #$572A, #$5734, #$593C, #$5980, #$597C, #$5985, #$597B, #$597E, - #$5977, #$597F, #$5B56, #$5C15, #$5C25, #$5C7C, #$5C7A, #$5C7B, - #$5C7E, #$5DDF, #$5E75, #$5E84, #$5F02, #$5F1A, #$5F74, #$5FD5, - #$5FD4, #$5FCF, #$625C, #$625E, #$6264, #$6261, #$6266, #$6262, - #$6259, #$6260, #$625A, #$6265, #$6537, #$65EF, #$65EE, #$673E, - #$6739, #$6738, #$673B, #$673A, #$673F, #$673C, #$6733, #$6C18, - #$6C46, #$6C52, #$6C5C, #$6C4F, #$6C4A, #$6C54, #$6C4B, #$6C4C, - #$7071, #$725E, #$72B4, #$72B5, #$738E, #$752A, #$767F, #$7A75, - #$7F51, #$8278, #$827C, #$8280, #$827D, #$827F, #$864D, #$897E, - #$9099, #$9097, #$9098, #$909B, #$9094, #$9622, #$9624, #$9620, - #$9623, #$4F56, #$4F3B, #$4F62, #$4F49, #$4F53, - #$4F64, #$4F3E, #$4F67, #$4F52, #$4F5F, #$4F41, #$4F58, #$4F2D, - #$4F33, #$4F3F, #$4F61, #$518F, #$51B9, #$521C, #$521E, #$5221, - #$52AD, #$52AE, #$5309, #$5363, #$5372, #$538E, #$538F, #$5430, - #$5437, #$542A, #$5454, #$5445, #$5419, #$541C, #$5425, #$5418, - #$543D, #$544F, #$5441, #$5428, #$5424, #$5447, #$56EE, #$56E7, - #$56E5, #$5741, #$5745, #$574C, #$5749, #$574B, #$5752, #$5906, - #$5940, #$59A6, #$5998, #$59A0, #$5997, #$598E, #$59A2, #$5990, - #$598F, #$59A7, #$59A1, #$5B8E, #$5B92, #$5C28, #$5C2A, #$5C8D, - #$5C8F, #$5C88, #$5C8B, #$5C89, #$5C92, #$5C8A, #$5C86, #$5C93, - #$5C95, #$5DE0, #$5E0A, #$5E0E, #$5E8B, #$5E89, #$5E8C, #$5E88, - #$5E8D, #$5F05, #$5F1D, #$5F78, #$5F76, #$5FD2, #$5FD1, #$5FD0, - #$5FED, #$5FE8, #$5FEE, #$5FF3, #$5FE1, #$5FE4, - #$5FE3, #$5FFA, #$5FEF, #$5FF7, #$5FFB, #$6000, #$5FF4, #$623A, - #$6283, #$628C, #$628E, #$628F, #$6294, #$6287, #$6271, #$627B, - #$627A, #$6270, #$6281, #$6288, #$6277, #$627D, #$6272, #$6274, - #$65F0, #$65F4, #$65F3, #$65F2, #$65F5, #$6745, #$6747, #$6759, - #$6755, #$674C, #$6748, #$675D, #$674D, #$675A, #$674B, #$6BD0, - #$6C19, #$6C1A, #$6C78, #$6C67, #$6C6B, #$6C84, #$6C8B, #$6C8F, - #$6C71, #$6C6F, #$6C69, #$6C9A, #$6C6D, #$6C87, #$6C95, #$6C9C, - #$6C66, #$6C73, #$6C65, #$6C7B, #$6C8E, #$7074, #$707A, #$7263, - #$72BF, #$72BD, #$72C3, #$72C6, #$72C1, #$72BA, #$72C5, #$7395, - #$7397, #$7393, #$7394, #$7392, #$753A, #$7539, #$7594, #$7595, - #$7681, #$793D, #$8034, #$8095, #$8099, #$8090, #$8092, #$809C, - #$8290, #$828F, #$8285, #$828E, #$8291, #$8293, - #$828A, #$8283, #$8284, #$8C78, #$8FC9, #$8FBF, #$909F, #$90A1, - #$90A5, #$909E, #$90A7, #$90A0, #$9630, #$9628, #$962F, #$962D, - #$4E33, #$4F98, #$4F7C, #$4F85, #$4F7D, #$4F80, #$4F87, #$4F76, - #$4F74, #$4F89, #$4F84, #$4F77, #$4F4C, #$4F97, #$4F6A, #$4F9A, - #$4F79, #$4F81, #$4F78, #$4F90, #$4F9C, #$4F94, #$4F9E, #$4F92, - #$4F82, #$4F95, #$4F6B, #$4F6E, #$519E, #$51BC, #$51BE, #$5235, - #$5232, #$5233, #$5246, #$5231, #$52BC, #$530A, #$530B, #$533C, - #$5392, #$5394, #$5487, #$547F, #$5481, #$5491, #$5482, #$5488, - #$546B, #$547A, #$547E, #$5465, #$546C, #$5474, #$5466, #$548D, - #$546F, #$5461, #$5460, #$5498, #$5463, #$5467, #$5464, #$56F7, - #$56F9, #$576F, #$5772, #$576D, #$576B, #$5771, #$5770, #$5776, - #$5780, #$5775, #$577B, #$5773, #$5774, #$5762, - #$5768, #$577D, #$590C, #$5945, #$59B5, #$59BA, #$59CF, #$59CE, - #$59B2, #$59CC, #$59C1, #$59B6, #$59BC, #$59C3, #$59D6, #$59B1, - #$59BD, #$59C0, #$59C8, #$59B4, #$59C7, #$5B62, #$5B65, #$5B93, - #$5B95, #$5C44, #$5C47, #$5CAE, #$5CA4, #$5CA0, #$5CB5, #$5CAF, - #$5CA8, #$5CAC, #$5C9F, #$5CA3, #$5CAD, #$5CA2, #$5CAA, #$5CA7, - #$5C9D, #$5CA5, #$5CB6, #$5CB0, #$5CA6, #$5E17, #$5E14, #$5E19, - #$5F28, #$5F22, #$5F23, #$5F24, #$5F54, #$5F82, #$5F7E, #$5F7D, - #$5FDE, #$5FE5, #$602D, #$6026, #$6019, #$6032, #$600B, #$6034, - #$600A, #$6017, #$6033, #$601A, #$601E, #$602C, #$6022, #$600D, - #$6010, #$602E, #$6013, #$6011, #$600C, #$6009, #$601C, #$6214, - #$623D, #$62AD, #$62B4, #$62D1, #$62BE, #$62AA, #$62B6, #$62CA, - #$62AE, #$62B3, #$62AF, #$62BB, #$62A9, #$62B0, - #$62B8, #$653D, #$65A8, #$65BB, #$6609, #$65FC, #$6604, #$6612, - #$6608, #$65FB, #$6603, #$660B, #$660D, #$6605, #$65FD, #$6611, - #$6610, #$66F6, #$670A, #$6785, #$676C, #$678E, #$6792, #$6776, - #$677B, #$6798, #$6786, #$6784, #$6774, #$678D, #$678C, #$677A, - #$679F, #$6791, #$6799, #$6783, #$677D, #$6781, #$6778, #$6779, - #$6794, #$6B25, #$6B80, #$6B7E, #$6BDE, #$6C1D, #$6C93, #$6CEC, - #$6CEB, #$6CEE, #$6CD9, #$6CB6, #$6CD4, #$6CAD, #$6CE7, #$6CB7, - #$6CD0, #$6CC2, #$6CBA, #$6CC3, #$6CC6, #$6CED, #$6CF2, #$6CD2, - #$6CDD, #$6CB4, #$6C8A, #$6C9D, #$6C80, #$6CDE, #$6CC0, #$6D30, - #$6CCD, #$6CC7, #$6CB0, #$6CF9, #$6CCF, #$6CE9, #$6CD1, #$7094, - #$7098, #$7085, #$7093, #$7086, #$7084, #$7091, #$7096, #$7082, - #$709A, #$7083, #$726A, #$72D6, #$72CB, #$72D8, - #$72C9, #$72DC, #$72D2, #$72D4, #$72DA, #$72CC, #$72D1, #$73A4, - #$73A1, #$73AD, #$73A6, #$73A2, #$73A0, #$73AC, #$739D, #$74DD, - #$74E8, #$753F, #$7540, #$753E, #$758C, #$7598, #$76AF, #$76F3, - #$76F1, #$76F0, #$76F5, #$77F8, #$77FC, #$77F9, #$77FB, #$77FA, - #$77F7, #$7942, #$793F, #$79C5, #$7A78, #$7A7B, #$7AFB, #$7C75, - #$7CFD, #$8035, #$808F, #$80AE, #$80A3, #$80B8, #$80B5, #$80AD, - #$8220, #$82A0, #$82C0, #$82AB, #$829A, #$8298, #$829B, #$82B5, - #$82A7, #$82AE, #$82BC, #$829E, #$82BA, #$82B4, #$82A8, #$82A1, - #$82A9, #$82C2, #$82A4, #$82C3, #$82B6, #$82A2, #$8670, #$866F, - #$866D, #$866E, #$8C56, #$8FD2, #$8FCB, #$8FD3, #$8FCD, #$8FD6, - #$8FD5, #$8FD7, #$90B2, #$90B4, #$90AF, #$90B3, #$90B0, #$9639, - #$963D, #$963C, #$963A, #$9643, #$4FCD, #$4FC5, - #$4FD3, #$4FB2, #$4FC9, #$4FCB, #$4FC1, #$4FD4, #$4FDC, #$4FD9, - #$4FBB, #$4FB3, #$4FDB, #$4FC7, #$4FD6, #$4FBA, #$4FC0, #$4FB9, - #$4FEC, #$5244, #$5249, #$52C0, #$52C2, #$533D, #$537C, #$5397, - #$5396, #$5399, #$5398, #$54BA, #$54A1, #$54AD, #$54A5, #$54CF, - #$54C3, #$830D, #$54B7, #$54AE, #$54D6, #$54B6, #$54C5, #$54C6, - #$54A0, #$5470, #$54BC, #$54A2, #$54BE, #$5472, #$54DE, #$54B0, - #$57B5, #$579E, #$579F, #$57A4, #$578C, #$5797, #$579D, #$579B, - #$5794, #$5798, #$578F, #$5799, #$57A5, #$579A, #$5795, #$58F4, - #$590D, #$5953, #$59E1, #$59DE, #$59EE, #$5A00, #$59F1, #$59DD, - #$59FA, #$59FD, #$59FC, #$59F6, #$59E4, #$59F2, #$59F7, #$59DB, - #$59E9, #$59F3, #$59F5, #$59E0, #$59FE, #$59F4, #$59ED, #$5BA8, - #$5C4C, #$5CD0, #$5CD8, #$5CCC, #$5CD7, #$5CCB, - #$5CDB, #$5CDE, #$5CDA, #$5CC9, #$5CC7, #$5CCA, #$5CD6, #$5CD3, - #$5CD4, #$5CCF, #$5CC8, #$5CC6, #$5CCE, #$5CDF, #$5CF8, #$5DF9, - #$5E21, #$5E22, #$5E23, #$5E20, #$5E24, #$5EB0, #$5EA4, #$5EA2, - #$5E9B, #$5EA3, #$5EA5, #$5F07, #$5F2E, #$5F56, #$5F86, #$6037, - #$6039, #$6054, #$6072, #$605E, #$6045, #$6053, #$6047, #$6049, - #$605B, #$604C, #$6040, #$6042, #$605F, #$6024, #$6044, #$6058, - #$6066, #$606E, #$6242, #$6243, #$62CF, #$630D, #$630B, #$62F5, - #$630E, #$6303, #$62EB, #$62F9, #$630F, #$630C, #$62F8, #$62F6, - #$6300, #$6313, #$6314, #$62FA, #$6315, #$62FB, #$62F0, #$6541, - #$6543, #$65AA, #$65BF, #$6636, #$6621, #$6632, #$6635, #$661C, - #$6626, #$6622, #$6633, #$662B, #$663A, #$661D, #$6634, #$6639, - #$662E, #$670F, #$6710, #$67C1, #$67F2, #$67C8, - #$67BA, #$67DC, #$67BB, #$67F8, #$67D8, #$67C0, #$67B7, #$67C5, - #$67EB, #$67E4, #$67DF, #$67B5, #$67CD, #$67B3, #$67F7, #$67F6, - #$67EE, #$67E3, #$67C2, #$67B9, #$67CE, #$67E7, #$67F0, #$67B2, - #$67FC, #$67C6, #$67ED, #$67CC, #$67AE, #$67E6, #$67DB, #$67FA, - #$67C9, #$67CA, #$67C3, #$67EA, #$67CB, #$6B28, #$6B82, #$6B84, - #$6BB6, #$6BD6, #$6BD8, #$6BE0, #$6C20, #$6C21, #$6D28, #$6D34, - #$6D2D, #$6D1F, #$6D3C, #$6D3F, #$6D12, #$6D0A, #$6CDA, #$6D33, - #$6D04, #$6D19, #$6D3A, #$6D1A, #$6D11, #$6D00, #$6D1D, #$6D42, - #$6D01, #$6D18, #$6D37, #$6D03, #$6D0F, #$6D40, #$6D07, #$6D20, - #$6D2C, #$6D08, #$6D22, #$6D09, #$6D10, #$70B7, #$709F, #$70BE, - #$70B1, #$70B0, #$70A1, #$70B4, #$70B5, #$70A9, #$7241, #$7249, - #$724A, #$726C, #$7270, #$7273, #$726E, #$72CA, - #$72E4, #$72E8, #$72EB, #$72DF, #$72EA, #$72E6, #$72E3, #$7385, - #$73CC, #$73C2, #$73C8, #$73C5, #$73B9, #$73B6, #$73B5, #$73B4, - #$73EB, #$73BF, #$73C7, #$73BE, #$73C3, #$73C6, #$73B8, #$73CB, - #$74EC, #$74EE, #$752E, #$7547, #$7548, #$75A7, #$75AA, #$7679, - #$76C4, #$7708, #$7703, #$7704, #$7705, #$770A, #$76F7, #$76FB, - #$76FA, #$77E7, #$77E8, #$7806, #$7811, #$7812, #$7805, #$7810, - #$780F, #$780E, #$7809, #$7803, #$7813, #$794A, #$794C, #$794B, - #$7945, #$7944, #$79D5, #$79CD, #$79CF, #$79D6, #$79CE, #$7A80, - #$7A7E, #$7AD1, #$7B00, #$7B01, #$7C7A, #$7C78, #$7C79, #$7C7F, - #$7C80, #$7C81, #$7D03, #$7D08, #$7D01, #$7F58, #$7F91, #$7F8D, - #$7FBE, #$8007, #$800E, #$800F, #$8014, #$8037, #$80D8, #$80C7, - #$80E0, #$80D1, #$80C8, #$80C2, #$80D0, #$80C5, - #$80E3, #$80D9, #$80DC, #$80CA, #$80D5, #$80C9, #$80CF, #$80D7, - #$80E6, #$80CD, #$81FF, #$8221, #$8294, #$82D9, #$82FE, #$82F9, - #$8307, #$82E8, #$8300, #$82D5, #$833A, #$82EB, #$82D6, #$82F4, - #$82EC, #$82E1, #$82F2, #$82F5, #$830C, #$82FB, #$82F6, #$82F0, - #$82EA, #$82E4, #$82E0, #$82FA, #$82F3, #$82ED, #$8677, #$8674, - #$867C, #$8673, #$8841, #$884E, #$8867, #$886A, #$8869, #$89D3, - #$8A04, #$8A07, #$8D72, #$8FE3, #$8FE1, #$8FEE, #$8FE0, #$90F1, - #$90BD, #$90BF, #$90D5, #$90C5, #$90BE, #$90C7, #$90CB, #$90C8, - #$91D4, #$91D3, #$9654, #$964F, #$9651, #$9653, #$964A, #$964E, - #$501E, #$5005, #$5007, #$5013, #$5022, #$5030, #$501B, #$4FF5, - #$4FF4, #$5033, #$5037, #$502C, #$4FF6, #$4FF7, #$5017, #$501C, - #$5020, #$5027, #$5035, #$502F, #$5031, #$500E, - #$515A, #$5194, #$5193, #$51CA, #$51C4, #$51C5, #$51C8, #$51CE, - #$5261, #$525A, #$5252, #$525E, #$525F, #$5255, #$5262, #$52CD, - #$530E, #$539E, #$5526, #$54E2, #$5517, #$5512, #$54E7, #$54F3, - #$54E4, #$551A, #$54FF, #$5504, #$5508, #$54EB, #$5511, #$5505, - #$54F1, #$550A, #$54FB, #$54F7, #$54F8, #$54E0, #$550E, #$5503, - #$550B, #$5701, #$5702, #$57CC, #$5832, #$57D5, #$57D2, #$57BA, - #$57C6, #$57BD, #$57BC, #$57B8, #$57B6, #$57BF, #$57C7, #$57D0, - #$57B9, #$57C1, #$590E, #$594A, #$5A19, #$5A16, #$5A2D, #$5A2E, - #$5A15, #$5A0F, #$5A17, #$5A0A, #$5A1E, #$5A33, #$5B6C, #$5BA7, - #$5BAD, #$5BAC, #$5C03, #$5C56, #$5C54, #$5CEC, #$5CFF, #$5CEE, - #$5CF1, #$5CF7, #$5D00, #$5CF9, #$5E29, #$5E28, #$5EA8, #$5EAE, - #$5EAA, #$5EAC, #$5F33, #$5F30, #$5F67, #$605D, - #$605A, #$6067, #$6041, #$60A2, #$6088, #$6080, #$6092, #$6081, - #$609D, #$6083, #$6095, #$609B, #$6097, #$6087, #$609C, #$608E, - #$6219, #$6246, #$62F2, #$6310, #$6356, #$632C, #$6344, #$6345, - #$6336, #$6343, #$63E4, #$6339, #$634B, #$634A, #$633C, #$6329, - #$6341, #$6334, #$6358, #$6354, #$6359, #$632D, #$6347, #$6333, - #$635A, #$6351, #$6338, #$6357, #$6340, #$6348, #$654A, #$6546, - #$65C6, #$65C3, #$65C4, #$65C2, #$664A, #$665F, #$6647, #$6651, - #$6712, #$6713, #$681F, #$681A, #$6849, #$6832, #$6833, #$683B, - #$684B, #$684F, #$6816, #$6831, #$681C, #$6835, #$682B, #$682D, - #$682F, #$684E, #$6844, #$6834, #$681D, #$6812, #$6814, #$6826, - #$6828, #$682E, #$684D, #$683A, #$6825, #$6820, #$6B2C, #$6B2F, - #$6B2D, #$6B31, #$6B34, #$6B6D, #$8082, #$6B88, - #$6BE6, #$6BE4, #$6BE8, #$6BE3, #$6BE2, #$6BE7, #$6C25, #$6D7A, - #$6D63, #$6D64, #$6D76, #$6D0D, #$6D61, #$6D92, #$6D58, #$6D62, - #$6D6D, #$6D6F, #$6D91, #$6D8D, #$6DEF, #$6D7F, #$6D86, #$6D5E, - #$6D67, #$6D60, #$6D97, #$6D70, #$6D7C, #$6D5F, #$6D82, #$6D98, - #$6D2F, #$6D68, #$6D8B, #$6D7E, #$6D80, #$6D84, #$6D16, #$6D83, - #$6D7B, #$6D7D, #$6D75, #$6D90, #$70DC, #$70D3, #$70D1, #$70DD, - #$70CB, #$7F39, #$70E2, #$70D7, #$70D2, #$70DE, #$70E0, #$70D4, - #$70CD, #$70C5, #$70C6, #$70C7, #$70DA, #$70CE, #$70E1, #$7242, - #$7278, #$7277, #$7276, #$7300, #$72FA, #$72F4, #$72FE, #$72F6, - #$72F3, #$72FB, #$7301, #$73D3, #$73D9, #$73E5, #$73D6, #$73BC, - #$73E7, #$73E3, #$73E9, #$73DC, #$73D2, #$73DB, #$73D4, #$73DD, - #$73DA, #$73D7, #$73D8, #$73E8, #$74DE, #$74DF, - #$74F4, #$74F5, #$7521, #$755B, #$755F, #$75B0, #$75C1, #$75BB, - #$75C4, #$75C0, #$75BF, #$75B6, #$75BA, #$768A, #$76C9, #$771D, - #$771B, #$7710, #$7713, #$7712, #$7723, #$7711, #$7715, #$7719, - #$771A, #$7722, #$7727, #$7823, #$782C, #$7822, #$7835, #$782F, - #$7828, #$782E, #$782B, #$7821, #$7829, #$7833, #$782A, #$7831, - #$7954, #$795B, #$794F, #$795C, #$7953, #$7952, #$7951, #$79EB, - #$79EC, #$79E0, #$79EE, #$79ED, #$79EA, #$79DC, #$79DE, #$79DD, - #$7A86, #$7A89, #$7A85, #$7A8B, #$7A8C, #$7A8A, #$7A87, #$7AD8, - #$7B10, #$7B04, #$7B13, #$7B05, #$7B0F, #$7B08, #$7B0A, #$7B0E, - #$7B09, #$7B12, #$7C84, #$7C91, #$7C8A, #$7C8C, #$7C88, #$7C8D, - #$7C85, #$7D1E, #$7D1D, #$7D11, #$7D0E, #$7D18, #$7D16, #$7D13, - #$7D1F, #$7D12, #$7D0F, #$7D0C, #$7F5C, #$7F61, - #$7F5E, #$7F60, #$7F5D, #$7F5B, #$7F96, #$7F92, #$7FC3, #$7FC2, - #$7FC0, #$8016, #$803E, #$8039, #$80FA, #$80F2, #$80F9, #$80F5, - #$8101, #$80FB, #$8100, #$8201, #$822F, #$8225, #$8333, #$832D, - #$8344, #$8319, #$8351, #$8325, #$8356, #$833F, #$8341, #$8326, - #$831C, #$8322, #$8342, #$834E, #$831B, #$832A, #$8308, #$833C, - #$834D, #$8316, #$8324, #$8320, #$8337, #$832F, #$8329, #$8347, - #$8345, #$834C, #$8353, #$831E, #$832C, #$834B, #$8327, #$8348, - #$8653, #$8652, #$86A2, #$86A8, #$8696, #$868D, #$8691, #$869E, - #$8687, #$8697, #$8686, #$868B, #$869A, #$8685, #$86A5, #$8699, - #$86A1, #$86A7, #$8695, #$8698, #$868E, #$869D, #$8690, #$8694, - #$8843, #$8844, #$886D, #$8875, #$8876, #$8872, #$8880, #$8871, - #$887F, #$886F, #$8883, #$887E, #$8874, #$887C, - #$8A12, #$8C47, #$8C57, #$8C7B, #$8CA4, #$8CA3, #$8D76, #$8D78, - #$8DB5, #$8DB7, #$8DB6, #$8ED1, #$8ED3, #$8FFE, #$8FF5, #$9002, - #$8FFF, #$8FFB, #$9004, #$8FFC, #$8FF6, #$90D6, #$90E0, #$90D9, - #$90DA, #$90E3, #$90DF, #$90E5, #$90D8, #$90DB, #$90D7, #$90DC, - #$90E4, #$9150, #$914E, #$914F, #$91D5, #$91E2, #$91DA, #$965C, - #$965F, #$96BC, #$98E3, #$9ADF, #$9B2F, #$4E7F, #$5070, #$506A, - #$5061, #$505E, #$5060, #$5053, #$504B, #$505D, #$5072, #$5048, - #$504D, #$5041, #$505B, #$504A, #$5062, #$5015, #$5045, #$505F, - #$5069, #$506B, #$5063, #$5064, #$5046, #$5040, #$506E, #$5073, - #$5057, #$5051, #$51D0, #$526B, #$526D, #$526C, #$526E, #$52D6, - #$52D3, #$532D, #$539C, #$5575, #$5576, #$553C, #$554D, #$5550, - #$5534, #$552A, #$5551, #$5562, #$5536, #$5535, - #$5530, #$5552, #$5545, #$550C, #$5532, #$5565, #$554E, #$5539, - #$5548, #$552D, #$553B, #$5540, #$554B, #$570A, #$5707, #$57FB, - #$5814, #$57E2, #$57F6, #$57DC, #$57F4, #$5800, #$57ED, #$57FD, - #$5808, #$57F8, #$580B, #$57F3, #$57CF, #$5807, #$57EE, #$57E3, - #$57F2, #$57E5, #$57EC, #$57E1, #$580E, #$57FC, #$5810, #$57E7, - #$5801, #$580C, #$57F1, #$57E9, #$57F0, #$580D, #$5804, #$595C, - #$5A60, #$5A58, #$5A55, #$5A67, #$5A5E, #$5A38, #$5A35, #$5A6D, - #$5A50, #$5A5F, #$5A65, #$5A6C, #$5A53, #$5A64, #$5A57, #$5A43, - #$5A5D, #$5A52, #$5A44, #$5A5B, #$5A48, #$5A8E, #$5A3E, #$5A4D, - #$5A39, #$5A4C, #$5A70, #$5A69, #$5A47, #$5A51, #$5A56, #$5A42, - #$5A5C, #$5B72, #$5B6E, #$5BC1, #$5BC0, #$5C59, #$5D1E, #$5D0B, - #$5D1D, #$5D1A, #$5D20, #$5D0C, #$5D28, #$5D0D, - #$5D26, #$5D25, #$5D0F, #$5D30, #$5D12, #$5D23, #$5D1F, #$5D2E, - #$5E3E, #$5E34, #$5EB1, #$5EB4, #$5EB9, #$5EB2, #$5EB3, #$5F36, - #$5F38, #$5F9B, #$5F96, #$5F9F, #$608A, #$6090, #$6086, #$60BE, - #$60B0, #$60BA, #$60D3, #$60D4, #$60CF, #$60E4, #$60D9, #$60DD, - #$60C8, #$60B1, #$60DB, #$60B7, #$60CA, #$60BF, #$60C3, #$60CD, - #$60C0, #$6332, #$6365, #$638A, #$6382, #$637D, #$63BD, #$639E, - #$63AD, #$639D, #$6397, #$63AB, #$638E, #$636F, #$6387, #$6390, - #$636E, #$63AF, #$6375, #$639C, #$636D, #$63AE, #$637C, #$63A4, - #$633B, #$639F, #$6378, #$6385, #$6381, #$6391, #$638D, #$6370, - #$6553, #$65CD, #$6665, #$6661, #$665B, #$6659, #$665C, #$6662, - #$6718, #$6879, #$6887, #$6890, #$689C, #$686D, #$686E, #$68AE, - #$68AB, #$6956, #$686F, #$68A3, #$68AC, #$68A9, - #$6875, #$6874, #$68B2, #$688F, #$6877, #$6892, #$687C, #$686B, - #$6872, #$68AA, #$6880, #$6871, #$687E, #$689B, #$6896, #$688B, - #$68A0, #$6889, #$68A4, #$6878, #$687B, #$6891, #$688C, #$688A, - #$687D, #$6B36, #$6B33, #$6B37, #$6B38, #$6B91, #$6B8F, #$6B8D, - #$6B8E, #$6B8C, #$6C2A, #$6DC0, #$6DAB, #$6DB4, #$6DB3, #$6E74, - #$6DAC, #$6DE9, #$6DE2, #$6DB7, #$6DF6, #$6DD4, #$6E00, #$6DC8, - #$6DE0, #$6DDF, #$6DD6, #$6DBE, #$6DE5, #$6DDC, #$6DDD, #$6DDB, - #$6DF4, #$6DCA, #$6DBD, #$6DED, #$6DF0, #$6DBA, #$6DD5, #$6DC2, - #$6DCF, #$6DC9, #$6DD0, #$6DF2, #$6DD3, #$6DFD, #$6DD7, #$6DCD, - #$6DE3, #$6DBB, #$70FA, #$710D, #$70F7, #$7117, #$70F4, #$710C, - #$70F0, #$7104, #$70F3, #$7110, #$70FC, #$70FF, #$7106, #$7113, - #$7100, #$70F8, #$70F6, #$710B, #$7102, #$710E, - #$727E, #$727B, #$727C, #$727F, #$731D, #$7317, #$7307, #$7311, - #$7318, #$730A, #$7308, #$72FF, #$730F, #$731E, #$7388, #$73F6, - #$73F8, #$73F5, #$7404, #$7401, #$73FD, #$7407, #$7400, #$73FA, - #$73FC, #$73FF, #$740C, #$740B, #$73F4, #$7408, #$7564, #$7563, - #$75CE, #$75D2, #$75CF, #$75CB, #$75CC, #$75D1, #$75D0, #$768F, - #$7689, #$76D3, #$7739, #$772F, #$772D, #$7731, #$7732, #$7734, - #$7733, #$773D, #$7725, #$773B, #$7735, #$7848, #$7852, #$7849, - #$784D, #$784A, #$784C, #$7826, #$7845, #$7850, #$7964, #$7967, - #$7969, #$796A, #$7963, #$796B, #$7961, #$79BB, #$79FA, #$79F8, - #$79F6, #$79F7, #$7A8F, #$7A94, #$7A90, #$7B35, #$7B3B, #$7B34, - #$7B25, #$7B30, #$7B22, #$7B24, #$7B33, #$7B18, #$7B2A, #$7B1D, - #$7B31, #$7B2B, #$7B2D, #$7B2F, #$7B32, #$7B38, - #$7B1A, #$7B23, #$7C94, #$7C98, #$7C96, #$7CA3, #$7D35, #$7D3D, - #$7D38, #$7D36, #$7D3A, #$7D45, #$7D2C, #$7D29, #$7D41, #$7D47, - #$7D3E, #$7D3F, #$7D4A, #$7D3B, #$7D28, #$7F63, #$7F95, #$7F9C, - #$7F9D, #$7F9B, #$7FCA, #$7FCB, #$7FCD, #$7FD0, #$7FD1, #$7FC7, - #$7FCF, #$7FC9, #$801F, #$801E, #$801B, #$8047, #$8043, #$8048, - #$8118, #$8125, #$8119, #$811B, #$812D, #$811F, #$812C, #$811E, - #$8121, #$8115, #$8127, #$811D, #$8122, #$8211, #$8238, #$8233, - #$823A, #$8234, #$8232, #$8274, #$8390, #$83A3, #$83A8, #$838D, - #$837A, #$8373, #$83A4, #$8374, #$838F, #$8381, #$8395, #$8399, - #$8375, #$8394, #$83A9, #$837D, #$8383, #$838C, #$839D, #$839B, - #$83AA, #$838B, #$837E, #$83A5, #$83AF, #$8388, #$8397, #$83B0, - #$837F, #$83A6, #$8387, #$83AE, #$8376, #$8659, - #$8656, #$86BF, #$86B7, #$86C2, #$86C1, #$86C5, #$86BA, #$86B0, - #$86C8, #$86B9, #$86B3, #$86B8, #$86CC, #$86B4, #$86BB, #$86BC, - #$86C3, #$86BD, #$86BE, #$8852, #$8889, #$8895, #$88A8, #$88A2, - #$88AA, #$889A, #$8891, #$88A1, #$889F, #$8898, #$88A7, #$8899, - #$889B, #$8897, #$88A4, #$88AC, #$888C, #$8893, #$888E, #$8982, - #$89D6, #$89D9, #$89D5, #$8A30, #$8A27, #$8A2C, #$8A1E, #$8C39, - #$8C3B, #$8C5C, #$8C5D, #$8C7D, #$8CA5, #$8D7D, #$8D7B, #$8D79, - #$8DBC, #$8DC2, #$8DB9, #$8DBF, #$8DC1, #$8ED8, #$8EDE, #$8EDD, - #$8EDC, #$8ED7, #$8EE0, #$8EE1, #$9024, #$900B, #$9011, #$901C, - #$900C, #$9021, #$90EF, #$90EA, #$90F0, #$90F4, #$90F2, #$90F3, - #$90D4, #$90EB, #$90EC, #$90E9, #$9156, #$9158, #$915A, #$9153, - #$9155, #$91EC, #$91F4, #$91F1, #$91F3, #$91F8, - #$91E4, #$91F9, #$91EA, #$91EB, #$91F7, #$91E8, #$91EE, #$957A, - #$9586, #$9588, #$967C, #$966D, #$966B, #$9671, #$966F, #$96BF, - #$976A, #$9804, #$98E5, #$9997, #$509B, #$5095, #$5094, #$509E, - #$508B, #$50A3, #$5083, #$508C, #$508E, #$509D, #$5068, #$509C, - #$5092, #$5082, #$5087, #$515F, #$51D4, #$5312, #$5311, #$53A4, - #$53A7, #$5591, #$55A8, #$55A5, #$55AD, #$5577, #$5645, #$55A2, - #$5593, #$5588, #$558F, #$55B5, #$5581, #$55A3, #$5592, #$55A4, - #$557D, #$558C, #$55A6, #$557F, #$5595, #$55A1, #$558E, #$570C, - #$5829, #$5837, #$5819, #$581E, #$5827, #$5823, #$5828, #$57F5, - #$5848, #$5825, #$581C, #$581B, #$5833, #$583F, #$5836, #$582E, - #$5839, #$5838, #$582D, #$582C, #$583B, #$5961, #$5AAF, #$5A94, - #$5A9F, #$5A7A, #$5AA2, #$5A9E, #$5A78, #$5AA6, - #$5A7C, #$5AA5, #$5AAC, #$5A95, #$5AAE, #$5A37, #$5A84, #$5A8A, - #$5A97, #$5A83, #$5A8B, #$5AA9, #$5A7B, #$5A7D, #$5A8C, #$5A9C, - #$5A8F, #$5A93, #$5A9D, #$5BEA, #$5BCD, #$5BCB, #$5BD4, #$5BD1, - #$5BCA, #$5BCE, #$5C0C, #$5C30, #$5D37, #$5D43, #$5D6B, #$5D41, - #$5D4B, #$5D3F, #$5D35, #$5D51, #$5D4E, #$5D55, #$5D33, #$5D3A, - #$5D52, #$5D3D, #$5D31, #$5D59, #$5D42, #$5D39, #$5D49, #$5D38, - #$5D3C, #$5D32, #$5D36, #$5D40, #$5D45, #$5E44, #$5E41, #$5F58, - #$5FA6, #$5FA5, #$5FAB, #$60C9, #$60B9, #$60CC, #$60E2, #$60CE, - #$60C4, #$6114, #$60F2, #$610A, #$6116, #$6105, #$60F5, #$6113, - #$60F8, #$60FC, #$60FE, #$60C1, #$6103, #$6118, #$611D, #$6110, - #$60FF, #$6104, #$610B, #$624A, #$6394, #$63B1, #$63B0, #$63CE, - #$63E5, #$63E8, #$63EF, #$63C3, #$649D, #$63F3, - #$63CA, #$63E0, #$63F6, #$63D5, #$63F2, #$63F5, #$6461, #$63DF, - #$63BE, #$63DD, #$63DC, #$63C4, #$63D8, #$63D3, #$63C2, #$63C7, - #$63CC, #$63CB, #$63C8, #$63F0, #$63D7, #$63D9, #$6532, #$6567, - #$656A, #$6564, #$655C, #$6568, #$6565, #$658C, #$659D, #$659E, - #$65AE, #$65D0, #$65D2, #$667C, #$666C, #$667B, #$6680, #$6671, - #$6679, #$666A, #$6672, #$6701, #$690C, #$68D3, #$6904, #$68DC, - #$692A, #$68EC, #$68EA, #$68F1, #$690F, #$68D6, #$68F7, #$68EB, - #$68E4, #$68F6, #$6913, #$6910, #$68F3, #$68E1, #$6907, #$68CC, - #$6908, #$6970, #$68B4, #$6911, #$68EF, #$68C6, #$6914, #$68F8, - #$68D0, #$68FD, #$68FC, #$68E8, #$690B, #$690A, #$6917, #$68CE, - #$68C8, #$68DD, #$68DE, #$68E6, #$68F4, #$68D1, #$6906, #$68D4, - #$68E9, #$6915, #$6925, #$68C7, #$6B39, #$6B3B, - #$6B3F, #$6B3C, #$6B94, #$6B97, #$6B99, #$6B95, #$6BBD, #$6BF0, - #$6BF2, #$6BF3, #$6C30, #$6DFC, #$6E46, #$6E47, #$6E1F, #$6E49, - #$6E88, #$6E3C, #$6E3D, #$6E45, #$6E62, #$6E2B, #$6E3F, #$6E41, - #$6E5D, #$6E73, #$6E1C, #$6E33, #$6E4B, #$6E40, #$6E51, #$6E3B, - #$6E03, #$6E2E, #$6E5E, #$6E68, #$6E5C, #$6E61, #$6E31, #$6E28, - #$6E60, #$6E71, #$6E6B, #$6E39, #$6E22, #$6E30, #$6E53, #$6E65, - #$6E27, #$6E78, #$6E64, #$6E77, #$6E55, #$6E79, #$6E52, #$6E66, - #$6E35, #$6E36, #$6E5A, #$7120, #$711E, #$712F, #$70FB, #$712E, - #$7131, #$7123, #$7125, #$7122, #$7132, #$711F, #$7128, #$713A, - #$711B, #$724B, #$725A, #$7288, #$7289, #$7286, #$7285, #$728B, - #$7312, #$730B, #$7330, #$7322, #$7331, #$7333, #$7327, #$7332, - #$732D, #$7326, #$7323, #$7335, #$730C, #$742E, - #$742C, #$7430, #$742B, #$7416, #$741A, #$7421, #$742D, #$7431, - #$7424, #$7423, #$741D, #$7429, #$7420, #$7432, #$74FB, #$752F, - #$756F, #$756C, #$75E7, #$75DA, #$75E1, #$75E6, #$75DD, #$75DF, - #$75E4, #$75D7, #$7695, #$7692, #$76DA, #$7746, #$7747, #$7744, - #$774D, #$7745, #$774A, #$774E, #$774B, #$774C, #$77DE, #$77EC, - #$7860, #$7864, #$7865, #$785C, #$786D, #$7871, #$786A, #$786E, - #$7870, #$7869, #$7868, #$785E, #$7862, #$7974, #$7973, #$7972, - #$7970, #$7A02, #$7A0A, #$7A03, #$7A0C, #$7A04, #$7A99, #$7AE6, - #$7AE4, #$7B4A, #$7B47, #$7B44, #$7B48, #$7B4C, #$7B4E, #$7B40, - #$7B58, #$7B45, #$7CA2, #$7C9E, #$7CA8, #$7CA1, #$7D58, #$7D6F, - #$7D63, #$7D53, #$7D56, #$7D67, #$7D6A, #$7D4F, #$7D6D, #$7D5C, - #$7D6B, #$7D52, #$7D54, #$7D69, #$7D51, #$7D5F, - #$7D4E, #$7F3E, #$7F3F, #$7F65, #$7F66, #$7FA2, #$7FA0, #$7FA1, - #$7FD7, #$8051, #$804F, #$8050, #$80FE, #$80D4, #$8143, #$814A, - #$8152, #$814F, #$8147, #$813D, #$814D, #$813A, #$81E6, #$81EE, - #$81F7, #$81F8, #$81F9, #$8204, #$823C, #$823D, #$823F, #$8275, - #$833B, #$83CF, #$83F9, #$8423, #$83C0, #$83E8, #$8412, #$83E7, - #$83E4, #$83FC, #$83F6, #$8410, #$83C6, #$83C8, #$83EB, #$83E3, - #$83BF, #$8401, #$83DD, #$83E5, #$83D8, #$83FF, #$83E1, #$83CB, - #$83CE, #$83D6, #$83F5, #$83C9, #$8409, #$840F, #$83DE, #$8411, - #$8406, #$83C2, #$83F3, #$83D5, #$83FA, #$83C7, #$83D1, #$83EA, - #$8413, #$839A, #$83C3, #$83EC, #$83EE, #$83C4, #$83FB, #$83D7, - #$83E2, #$841B, #$83DB, #$83FE, #$86D8, #$86E2, #$86E6, #$86D3, - #$86E3, #$86DA, #$86EA, #$86DD, #$86EB, #$86DC, - #$86EC, #$86E9, #$86D7, #$86E8, #$86D1, #$8848, #$8856, #$8855, - #$88BA, #$88D7, #$88B9, #$88B8, #$88C0, #$88BE, #$88B6, #$88BC, - #$88B7, #$88BD, #$88B2, #$8901, #$88C9, #$8995, #$8998, #$8997, - #$89DD, #$89DA, #$89DB, #$8A4E, #$8A4D, #$8A39, #$8A59, #$8A40, - #$8A57, #$8A58, #$8A44, #$8A45, #$8A52, #$8A48, #$8A51, #$8A4A, - #$8A4C, #$8A4F, #$8C5F, #$8C81, #$8C80, #$8CBA, #$8CBE, #$8CB0, - #$8CB9, #$8CB5, #$8D84, #$8D80, #$8D89, #$8DD8, #$8DD3, #$8DCD, - #$8DC7, #$8DD6, #$8DDC, #$8DCF, #$8DD5, #$8DD9, #$8DC8, #$8DD7, - #$8DC5, #$8EEF, #$8EF7, #$8EFA, #$8EF9, #$8EE6, #$8EEE, #$8EE5, - #$8EF5, #$8EE7, #$8EE8, #$8EF6, #$8EEB, #$8EF1, #$8EEC, #$8EF4, - #$8EE9, #$902D, #$9034, #$902F, #$9106, #$912C, #$9104, #$90FF, - #$90FC, #$9108, #$90F9, #$90FB, #$9101, #$9100, - #$9107, #$9105, #$9103, #$9161, #$9164, #$915F, #$9162, #$9160, - #$9201, #$920A, #$9225, #$9203, #$921A, #$9226, #$920F, #$920C, - #$9200, #$9212, #$91FF, #$91FD, #$9206, #$9204, #$9227, #$9202, - #$921C, #$9224, #$9219, #$9217, #$9205, #$9216, #$957B, #$958D, - #$958C, #$9590, #$9687, #$967E, #$9688, #$9689, #$9683, #$9680, - #$96C2, #$96C8, #$96C3, #$96F1, #$96F0, #$976C, #$9770, #$976E, - #$9807, #$98A9, #$98EB, #$9CE6, #$9EF9, #$4E83, #$4E84, #$4EB6, - #$50BD, #$50BF, #$50C6, #$50AE, #$50C4, #$50CA, #$50B4, #$50C8, - #$50C2, #$50B0, #$50C1, #$50BA, #$50B1, #$50CB, #$50C9, #$50B6, - #$50B8, #$51D7, #$527A, #$5278, #$527B, #$527C, #$55C3, #$55DB, - #$55CC, #$55D0, #$55CB, #$55CA, #$55DD, #$55C0, #$55D4, #$55C4, - #$55E9, #$55BF, #$55D2, #$558D, #$55CF, #$55D5, - #$55E2, #$55D6, #$55C8, #$55F2, #$55CD, #$55D9, #$55C2, #$5714, - #$5853, #$5868, #$5864, #$584F, #$584D, #$5849, #$586F, #$5855, - #$584E, #$585D, #$5859, #$5865, #$585B, #$583D, #$5863, #$5871, - #$58FC, #$5AC7, #$5AC4, #$5ACB, #$5ABA, #$5AB8, #$5AB1, #$5AB5, - #$5AB0, #$5ABF, #$5AC8, #$5ABB, #$5AC6, #$5AB7, #$5AC0, #$5ACA, - #$5AB4, #$5AB6, #$5ACD, #$5AB9, #$5A90, #$5BD6, #$5BD8, #$5BD9, - #$5C1F, #$5C33, #$5D71, #$5D63, #$5D4A, #$5D65, #$5D72, #$5D6C, - #$5D5E, #$5D68, #$5D67, #$5D62, #$5DF0, #$5E4F, #$5E4E, #$5E4A, - #$5E4D, #$5E4B, #$5EC5, #$5ECC, #$5EC6, #$5ECB, #$5EC7, #$5F40, - #$5FAF, #$5FAD, #$60F7, #$6149, #$614A, #$612B, #$6145, #$6136, - #$6132, #$612E, #$6146, #$612F, #$614F, #$6129, #$6140, #$6220, - #$9168, #$6223, #$6225, #$6224, #$63C5, #$63F1, - #$63EB, #$6410, #$6412, #$6409, #$6420, #$6424, #$6433, #$6443, - #$641F, #$6415, #$6418, #$6439, #$6437, #$6422, #$6423, #$640C, - #$6426, #$6430, #$6428, #$6441, #$6435, #$642F, #$640A, #$641A, - #$6440, #$6425, #$6427, #$640B, #$63E7, #$641B, #$642E, #$6421, - #$640E, #$656F, #$6592, #$65D3, #$6686, #$668C, #$6695, #$6690, - #$668B, #$668A, #$6699, #$6694, #$6678, #$6720, #$6966, #$695F, - #$6938, #$694E, #$6962, #$6971, #$693F, #$6945, #$696A, #$6939, - #$6942, #$6957, #$6959, #$697A, #$6948, #$6949, #$6935, #$696C, - #$6933, #$693D, #$6965, #$68F0, #$6978, #$6934, #$6969, #$6940, - #$696F, #$6944, #$6976, #$6958, #$6941, #$6974, #$694C, #$693B, - #$694B, #$6937, #$695C, #$694F, #$6951, #$6932, #$6952, #$692F, - #$697B, #$693C, #$6B46, #$6B45, #$6B43, #$6B42, - #$6B48, #$6B41, #$6B9B, #$6BFB, #$6BFC, #$6BF9, #$6BF7, #$6BF8, - #$6E9B, #$6ED6, #$6EC8, #$6E8F, #$6EC0, #$6E9F, #$6E93, #$6E94, - #$6EA0, #$6EB1, #$6EB9, #$6EC6, #$6ED2, #$6EBD, #$6EC1, #$6E9E, - #$6EC9, #$6EB7, #$6EB0, #$6ECD, #$6EA6, #$6ECF, #$6EB2, #$6EBE, - #$6EC3, #$6EDC, #$6ED8, #$6E99, #$6E92, #$6E8E, #$6E8D, #$6EA4, - #$6EA1, #$6EBF, #$6EB3, #$6ED0, #$6ECA, #$6E97, #$6EAE, #$6EA3, - #$7147, #$7154, #$7152, #$7163, #$7160, #$7141, #$715D, #$7162, - #$7172, #$7178, #$716A, #$7161, #$7142, #$7158, #$7143, #$714B, - #$7170, #$715F, #$7150, #$7153, #$7144, #$714D, #$715A, #$724F, - #$728D, #$728C, #$7291, #$7290, #$728E, #$733C, #$7342, #$733B, - #$733A, #$7340, #$734A, #$7349, #$7444, #$744A, #$744B, #$7452, - #$7451, #$7457, #$7440, #$744F, #$7450, #$744E, - #$7442, #$7446, #$744D, #$7454, #$74E1, #$74FF, #$74FE, #$74FD, - #$751D, #$7579, #$7577, #$6983, #$75EF, #$760F, #$7603, #$75F7, - #$75FE, #$75FC, #$75F9, #$75F8, #$7610, #$75FB, #$75F6, #$75ED, - #$75F5, #$75FD, #$7699, #$76B5, #$76DD, #$7755, #$775F, #$7760, - #$7752, #$7756, #$775A, #$7769, #$7767, #$7754, #$7759, #$776D, - #$77E0, #$7887, #$789A, #$7894, #$788F, #$7884, #$7895, #$7885, - #$7886, #$78A1, #$7883, #$7879, #$7899, #$7880, #$7896, #$787B, - #$797C, #$7982, #$797D, #$7979, #$7A11, #$7A18, #$7A19, #$7A12, - #$7A17, #$7A15, #$7A22, #$7A13, #$7A1B, #$7A10, #$7AA3, #$7AA2, - #$7A9E, #$7AEB, #$7B66, #$7B64, #$7B6D, #$7B74, #$7B69, #$7B72, - #$7B65, #$7B73, #$7B71, #$7B70, #$7B61, #$7B78, #$7B76, #$7B63, - #$7CB2, #$7CB4, #$7CAF, #$7D88, #$7D86, #$7D80, - #$7D8D, #$7D7F, #$7D85, #$7D7A, #$7D8E, #$7D7B, #$7D83, #$7D7C, - #$7D8C, #$7D94, #$7D84, #$7D7D, #$7D92, #$7F6D, #$7F6B, #$7F67, - #$7F68, #$7F6C, #$7FA6, #$7FA5, #$7FA7, #$7FDB, #$7FDC, #$8021, - #$8164, #$8160, #$8177, #$815C, #$8169, #$815B, #$8162, #$8172, - #$6721, #$815E, #$8176, #$8167, #$816F, #$8144, #$8161, #$821D, - #$8249, #$8244, #$8240, #$8242, #$8245, #$84F1, #$843F, #$8456, - #$8476, #$8479, #$848F, #$848D, #$8465, #$8451, #$8440, #$8486, - #$8467, #$8430, #$844D, #$847D, #$845A, #$8459, #$8474, #$8473, - #$845D, #$8507, #$845E, #$8437, #$843A, #$8434, #$847A, #$8443, - #$8478, #$8432, #$8445, #$8429, #$83D9, #$844B, #$842F, #$8442, - #$842D, #$845F, #$8470, #$8439, #$844E, #$844C, #$8452, #$846F, - #$84C5, #$848E, #$843B, #$8447, #$8436, #$8433, - #$8468, #$847E, #$8444, #$842B, #$8460, #$8454, #$846E, #$8450, - #$870B, #$8704, #$86F7, #$870C, #$86FA, #$86D6, #$86F5, #$874D, - #$86F8, #$870E, #$8709, #$8701, #$86F6, #$870D, #$8705, #$88D6, - #$88CB, #$88CD, #$88CE, #$88DE, #$88DB, #$88DA, #$88CC, #$88D0, - #$8985, #$899B, #$89DF, #$89E5, #$89E4, #$89E1, #$89E0, #$89E2, - #$89DC, #$89E6, #$8A76, #$8A86, #$8A7F, #$8A61, #$8A3F, #$8A77, - #$8A82, #$8A84, #$8A75, #$8A83, #$8A81, #$8A74, #$8A7A, #$8C3C, - #$8C4B, #$8C4A, #$8C65, #$8C64, #$8C66, #$8C86, #$8C84, #$8C85, - #$8CCC, #$8D68, #$8D69, #$8D91, #$8D8C, #$8D8E, #$8D8F, #$8D8D, - #$8D93, #$8D94, #$8D90, #$8D92, #$8DF0, #$8DE0, #$8DEC, #$8DF1, - #$8DEE, #$8DD0, #$8DE9, #$8DE3, #$8DE2, #$8DE7, #$8DF2, #$8DEB, - #$8DF4, #$8F06, #$8EFF, #$8F01, #$8F00, #$8F05, - #$8F07, #$8F08, #$8F02, #$8F0B, #$9052, #$903F, #$9044, #$9049, - #$903D, #$9110, #$910D, #$910F, #$9111, #$9116, #$9114, #$910B, - #$910E, #$916E, #$916F, #$9248, #$9252, #$9230, #$923A, #$9266, - #$9233, #$9265, #$925E, #$9283, #$922E, #$924A, #$9246, #$926D, - #$926C, #$924F, #$9260, #$9267, #$926F, #$9236, #$9261, #$9270, - #$9231, #$9254, #$9263, #$9250, #$9272, #$924E, #$9253, #$924C, - #$9256, #$9232, #$959F, #$959C, #$959E, #$959B, #$9692, #$9693, - #$9691, #$9697, #$96CE, #$96FA, #$96FD, #$96F8, #$96F5, #$9773, - #$9777, #$9778, #$9772, #$980F, #$980D, #$980E, #$98AC, #$98F6, - #$98F9, #$99AF, #$99B2, #$99B0, #$99B5, #$9AAD, #$9AAB, #$9B5B, - #$9CEA, #$9CED, #$9CE7, #$9E80, #$9EFD, #$50E6, #$50D4, #$50D7, - #$50E8, #$50F3, #$50DB, #$50EA, #$50DD, #$50E4, - #$50D3, #$50EC, #$50F0, #$50EF, #$50E3, #$50E0, #$51D8, #$5280, - #$5281, #$52E9, #$52EB, #$5330, #$53AC, #$5627, #$5615, #$560C, - #$5612, #$55FC, #$560F, #$561C, #$5601, #$5613, #$5602, #$55FA, - #$561D, #$5604, #$55FF, #$55F9, #$5889, #$587C, #$5890, #$5898, - #$5886, #$5881, #$587F, #$5874, #$588B, #$587A, #$5887, #$5891, - #$588E, #$5876, #$5882, #$5888, #$587B, #$5894, #$588F, #$58FE, - #$596B, #$5ADC, #$5AEE, #$5AE5, #$5AD5, #$5AEA, #$5ADA, #$5AED, - #$5AEB, #$5AF3, #$5AE2, #$5AE0, #$5ADB, #$5AEC, #$5ADE, #$5ADD, - #$5AD9, #$5AE8, #$5ADF, #$5B77, #$5BE0, #$5BE3, #$5C63, #$5D82, - #$5D80, #$5D7D, #$5D86, #$5D7A, #$5D81, #$5D77, #$5D8A, #$5D89, - #$5D88, #$5D7E, #$5D7C, #$5D8D, #$5D79, #$5D7F, #$5E58, #$5E59, - #$5E53, #$5ED8, #$5ED1, #$5ED7, #$5ECE, #$5EDC, - #$5ED5, #$5ED9, #$5ED2, #$5ED4, #$5F44, #$5F43, #$5F6F, #$5FB6, - #$612C, #$6128, #$6141, #$615E, #$6171, #$6173, #$6152, #$6153, - #$6172, #$616C, #$6180, #$6174, #$6154, #$617A, #$615B, #$6165, - #$613B, #$616A, #$6161, #$6156, #$6229, #$6227, #$622B, #$642B, - #$644D, #$645B, #$645D, #$6474, #$6476, #$6472, #$6473, #$647D, - #$6475, #$6466, #$64A6, #$644E, #$6482, #$645E, #$645C, #$644B, - #$6453, #$6460, #$6450, #$647F, #$643F, #$646C, #$646B, #$6459, - #$6465, #$6477, #$6573, #$65A0, #$66A1, #$66A0, #$669F, #$6705, - #$6704, #$6722, #$69B1, #$69B6, #$69C9, #$69A0, #$69CE, #$6996, - #$69B0, #$69AC, #$69BC, #$6991, #$6999, #$698E, #$69A7, #$698D, - #$69A9, #$69BE, #$69AF, #$69BF, #$69C4, #$69BD, #$69A4, #$69D4, - #$69B9, #$69CA, #$699A, #$69CF, #$69B3, #$6993, - #$69AA, #$69A1, #$699E, #$69D9, #$6997, #$6990, #$69C2, #$69B5, - #$69A5, #$69C6, #$6B4A, #$6B4D, #$6B4B, #$6B9E, #$6B9F, #$6BA0, - #$6BC3, #$6BC4, #$6BFE, #$6ECE, #$6EF5, #$6EF1, #$6F03, #$6F25, - #$6EF8, #$6F37, #$6EFB, #$6F2E, #$6F09, #$6F4E, #$6F19, #$6F1A, - #$6F27, #$6F18, #$6F3B, #$6F12, #$6EED, #$6F0A, #$6F36, #$6F73, - #$6EF9, #$6EEE, #$6F2D, #$6F40, #$6F30, #$6F3C, #$6F35, #$6EEB, - #$6F07, #$6F0E, #$6F43, #$6F05, #$6EFD, #$6EF6, #$6F39, #$6F1C, - #$6EFC, #$6F3A, #$6F1F, #$6F0D, #$6F1E, #$6F08, #$6F21, #$7187, - #$7190, #$7189, #$7180, #$7185, #$7182, #$718F, #$717B, #$7186, - #$7181, #$7197, #$7244, #$7253, #$7297, #$7295, #$7293, #$7343, - #$734D, #$7351, #$734C, #$7462, #$7473, #$7471, #$7475, #$7472, - #$7467, #$746E, #$7500, #$7502, #$7503, #$757D, - #$7590, #$7616, #$7608, #$760C, #$7615, #$7611, #$760A, #$7614, - #$76B8, #$7781, #$777C, #$7785, #$7782, #$776E, #$7780, #$776F, - #$777E, #$7783, #$78B2, #$78AA, #$78B4, #$78AD, #$78A8, #$787E, - #$78AB, #$789E, #$78A5, #$78A0, #$78AC, #$78A2, #$78A4, #$7998, - #$798A, #$798B, #$7996, #$7995, #$7994, #$7993, #$7997, #$7988, - #$7992, #$7990, #$7A2B, #$7A4A, #$7A30, #$7A2F, #$7A28, #$7A26, - #$7AA8, #$7AAB, #$7AAC, #$7AEE, #$7B88, #$7B9C, #$7B8A, #$7B91, - #$7B90, #$7B96, #$7B8D, #$7B8C, #$7B9B, #$7B8E, #$7B85, #$7B98, - #$5284, #$7B99, #$7BA4, #$7B82, #$7CBB, #$7CBF, #$7CBC, #$7CBA, - #$7DA7, #$7DB7, #$7DC2, #$7DA3, #$7DAA, #$7DC1, #$7DC0, #$7DC5, - #$7D9D, #$7DCE, #$7DC4, #$7DC6, #$7DCB, #$7DCC, #$7DAF, #$7DB9, - #$7D96, #$7DBC, #$7D9F, #$7DA6, #$7DAE, #$7DA9, - #$7DA1, #$7DC9, #$7F73, #$7FE2, #$7FE3, #$7FE5, #$7FDE, #$8024, - #$805D, #$805C, #$8189, #$8186, #$8183, #$8187, #$818D, #$818C, - #$818B, #$8215, #$8497, #$84A4, #$84A1, #$849F, #$84BA, #$84CE, - #$84C2, #$84AC, #$84AE, #$84AB, #$84B9, #$84B4, #$84C1, #$84CD, - #$84AA, #$849A, #$84B1, #$84D0, #$849D, #$84A7, #$84BB, #$84A2, - #$8494, #$84C7, #$84CC, #$849B, #$84A9, #$84AF, #$84A8, #$84D6, - #$8498, #$84B6, #$84CF, #$84A0, #$84D7, #$84D4, #$84D2, #$84DB, - #$84B0, #$8491, #$8661, #$8733, #$8723, #$8728, #$876B, #$8740, - #$872E, #$871E, #$8721, #$8719, #$871B, #$8743, #$872C, #$8741, - #$873E, #$8746, #$8720, #$8732, #$872A, #$872D, #$873C, #$8712, - #$873A, #$8731, #$8735, #$8742, #$8726, #$8727, #$8738, #$8724, - #$871A, #$8730, #$8711, #$88F7, #$88E7, #$88F1, - #$88F2, #$88FA, #$88FE, #$88EE, #$88FC, #$88F6, #$88FB, #$88F0, - #$88EC, #$88EB, #$899D, #$89A1, #$899F, #$899E, #$89E9, #$89EB, - #$89E8, #$8AAB, #$8A99, #$8A8B, #$8A92, #$8A8F, #$8A96, #$8C3D, - #$8C68, #$8C69, #$8CD5, #$8CCF, #$8CD7, #$8D96, #$8E09, #$8E02, - #$8DFF, #$8E0D, #$8DFD, #$8E0A, #$8E03, #$8E07, #$8E06, #$8E05, - #$8DFE, #$8E00, #$8E04, #$8F10, #$8F11, #$8F0E, #$8F0D, #$9123, - #$911C, #$9120, #$9122, #$911F, #$911D, #$911A, #$9124, #$9121, - #$911B, #$917A, #$9172, #$9179, #$9173, #$92A5, #$92A4, #$9276, - #$929B, #$927A, #$92A0, #$9294, #$92AA, #$928D, #$92A6, #$929A, - #$92AB, #$9279, #$9297, #$927F, #$92A3, #$92EE, #$928E, #$9282, - #$9295, #$92A2, #$927D, #$9288, #$92A1, #$928A, #$9286, #$928C, - #$9299, #$92A7, #$927E, #$9287, #$92A9, #$929D, - #$928B, #$922D, #$969E, #$96A1, #$96FF, #$9758, #$977D, #$977A, - #$977E, #$9783, #$9780, #$9782, #$977B, #$9784, #$9781, #$977F, - #$97CE, #$97CD, #$9816, #$98AD, #$98AE, #$9902, #$9900, #$9907, - #$999D, #$999C, #$99C3, #$99B9, #$99BB, #$99BA, #$99C2, #$99BD, - #$99C7, #$9AB1, #$9AE3, #$9AE7, #$9B3E, #$9B3F, #$9B60, #$9B61, - #$9B5F, #$9CF1, #$9CF2, #$9CF5, #$9EA7, #$50FF, #$5103, #$5130, - #$50F8, #$5106, #$5107, #$50F6, #$50FE, #$510B, #$510C, #$50FD, - #$510A, #$528B, #$528C, #$52F1, #$52EF, #$5648, #$5642, #$564C, - #$5635, #$5641, #$564A, #$5649, #$5646, #$5658, #$565A, #$5640, - #$5633, #$563D, #$562C, #$563E, #$5638, #$562A, #$563A, #$571A, - #$58AB, #$589D, #$58B1, #$58A0, #$58A3, #$58AF, #$58AC, #$58A5, - #$58A1, #$58FF, #$5AFF, #$5AF4, #$5AFD, #$5AF7, - #$5AF6, #$5B03, #$5AF8, #$5B02, #$5AF9, #$5B01, #$5B07, #$5B05, - #$5B0F, #$5C67, #$5D99, #$5D97, #$5D9F, #$5D92, #$5DA2, #$5D93, - #$5D95, #$5DA0, #$5D9C, #$5DA1, #$5D9A, #$5D9E, #$5E69, #$5E5D, - #$5E60, #$5E5C, #$7DF3, #$5EDB, #$5EDE, #$5EE1, #$5F49, #$5FB2, - #$618B, #$6183, #$6179, #$61B1, #$61B0, #$61A2, #$6189, #$619B, - #$6193, #$61AF, #$61AD, #$619F, #$6192, #$61AA, #$61A1, #$618D, - #$6166, #$61B3, #$622D, #$646E, #$6470, #$6496, #$64A0, #$6485, - #$6497, #$649C, #$648F, #$648B, #$648A, #$648C, #$64A3, #$649F, - #$6468, #$64B1, #$6498, #$6576, #$657A, #$6579, #$657B, #$65B2, - #$65B3, #$66B5, #$66B0, #$66A9, #$66B2, #$66B7, #$66AA, #$66AF, - #$6A00, #$6A06, #$6A17, #$69E5, #$69F8, #$6A15, #$69F1, #$69E4, - #$6A20, #$69FF, #$69EC, #$69E2, #$6A1B, #$6A1D, - #$69FE, #$6A27, #$69F2, #$69EE, #$6A14, #$69F7, #$69E7, #$6A40, - #$6A08, #$69E6, #$69FB, #$6A0D, #$69FC, #$69EB, #$6A09, #$6A04, - #$6A18, #$6A25, #$6A0F, #$69F6, #$6A26, #$6A07, #$69F4, #$6A16, - #$6B51, #$6BA5, #$6BA3, #$6BA2, #$6BA6, #$6C01, #$6C00, #$6BFF, - #$6C02, #$6F41, #$6F26, #$6F7E, #$6F87, #$6FC6, #$6F92, #$6F8D, - #$6F89, #$6F8C, #$6F62, #$6F4F, #$6F85, #$6F5A, #$6F96, #$6F76, - #$6F6C, #$6F82, #$6F55, #$6F72, #$6F52, #$6F50, #$6F57, #$6F94, - #$6F93, #$6F5D, #$6F00, #$6F61, #$6F6B, #$6F7D, #$6F67, #$6F90, - #$6F53, #$6F8B, #$6F69, #$6F7F, #$6F95, #$6F63, #$6F77, #$6F6A, - #$6F7B, #$71B2, #$71AF, #$719B, #$71B0, #$71A0, #$719A, #$71A9, - #$71B5, #$719D, #$71A5, #$719E, #$71A4, #$71A1, #$71AA, #$719C, - #$71A7, #$71B3, #$7298, #$729A, #$7358, #$7352, - #$735E, #$735F, #$7360, #$735D, #$735B, #$7361, #$735A, #$7359, - #$7362, #$7487, #$7489, #$748A, #$7486, #$7481, #$747D, #$7485, - #$7488, #$747C, #$7479, #$7508, #$7507, #$757E, #$7625, #$761E, - #$7619, #$761D, #$761C, #$7623, #$761A, #$7628, #$761B, #$769C, - #$769D, #$769E, #$769B, #$778D, #$778F, #$7789, #$7788, #$78CD, - #$78BB, #$78CF, #$78CC, #$78D1, #$78CE, #$78D4, #$78C8, #$78C3, - #$78C4, #$78C9, #$799A, #$79A1, #$79A0, #$799C, #$79A2, #$799B, - #$6B76, #$7A39, #$7AB2, #$7AB4, #$7AB3, #$7BB7, #$7BCB, #$7BBE, - #$7BAC, #$7BCE, #$7BAF, #$7BB9, #$7BCA, #$7BB5, #$7CC5, #$7CC8, - #$7CCC, #$7CCB, #$7DF7, #$7DDB, #$7DEA, #$7DE7, #$7DD7, #$7DE1, - #$7E03, #$7DFA, #$7DE6, #$7DF6, #$7DF1, #$7DF0, #$7DEE, #$7DDF, - #$7F76, #$7FAC, #$7FB0, #$7FAD, #$7FED, #$7FEB, - #$7FEA, #$7FEC, #$7FE6, #$7FE8, #$8064, #$8067, #$81A3, #$819F, - #$819E, #$8195, #$81A2, #$8199, #$8197, #$8216, #$824F, #$8253, - #$8252, #$8250, #$824E, #$8251, #$8524, #$853B, #$850F, #$8500, - #$8529, #$850E, #$8509, #$850D, #$851F, #$850A, #$8527, #$851C, - #$84FB, #$852B, #$84FA, #$8508, #$850C, #$84F4, #$852A, #$84F2, - #$8515, #$84F7, #$84EB, #$84F3, #$84FC, #$8512, #$84EA, #$84E9, - #$8516, #$84FE, #$8528, #$851D, #$852E, #$8502, #$84FD, #$851E, - #$84F6, #$8531, #$8526, #$84E7, #$84E8, #$84F0, #$84EF, #$84F9, - #$8518, #$8520, #$8530, #$850B, #$8519, #$852F, #$8662, #$8756, - #$8763, #$8764, #$8777, #$87E1, #$8773, #$8758, #$8754, #$875B, - #$8752, #$8761, #$875A, #$8751, #$875E, #$876D, #$876A, #$8750, - #$874E, #$875F, #$875D, #$876F, #$876C, #$877A, - #$876E, #$875C, #$8765, #$874F, #$877B, #$8775, #$8762, #$8767, - #$8769, #$885A, #$8905, #$890C, #$8914, #$890B, #$8917, #$8918, - #$8919, #$8906, #$8916, #$8911, #$890E, #$8909, #$89A2, #$89A4, - #$89A3, #$89ED, #$89F0, #$89EC, #$8ACF, #$8AC6, #$8AB8, #$8AD3, - #$8AD1, #$8AD4, #$8AD5, #$8ABB, #$8AD7, #$8ABE, #$8AC0, #$8AC5, - #$8AD8, #$8AC3, #$8ABA, #$8ABD, #$8AD9, #$8C3E, #$8C4D, #$8C8F, - #$8CE5, #$8CDF, #$8CD9, #$8CE8, #$8CDA, #$8CDD, #$8CE7, #$8DA0, - #$8D9C, #$8DA1, #$8D9B, #$8E20, #$8E23, #$8E25, #$8E24, #$8E2E, - #$8E15, #$8E1B, #$8E16, #$8E11, #$8E19, #$8E26, #$8E27, #$8E14, - #$8E12, #$8E18, #$8E13, #$8E1C, #$8E17, #$8E1A, #$8F2C, #$8F24, - #$8F18, #$8F1A, #$8F20, #$8F23, #$8F16, #$8F17, #$9073, #$9070, - #$906F, #$9067, #$906B, #$912F, #$912B, #$9129, - #$912A, #$9132, #$9126, #$912E, #$9185, #$9186, #$918A, #$9181, - #$9182, #$9184, #$9180, #$92D0, #$92C3, #$92C4, #$92C0, #$92D9, - #$92B6, #$92CF, #$92F1, #$92DF, #$92D8, #$92E9, #$92D7, #$92DD, - #$92CC, #$92EF, #$92C2, #$92E8, #$92CA, #$92C8, #$92CE, #$92E6, - #$92CD, #$92D5, #$92C9, #$92E0, #$92DE, #$92E7, #$92D1, #$92D3, - #$92B5, #$92E1, #$9325, #$92C6, #$92B4, #$957C, #$95AC, #$95AB, - #$95AE, #$95B0, #$96A4, #$96A2, #$96D3, #$9705, #$9708, #$9702, - #$975A, #$978A, #$978E, #$9788, #$97D0, #$97CF, #$981E, #$981D, - #$9826, #$9829, #$9828, #$9820, #$981B, #$9827, #$98B2, #$9908, - #$98FA, #$9911, #$9914, #$9916, #$9917, #$9915, #$99DC, #$99CD, - #$99CF, #$99D3, #$99D4, #$99CE, #$99C9, #$99D6, #$99D8, #$99CB, - #$99D7, #$99CC, #$9AB3, #$9AEC, #$9AEB, #$9AF3, - #$9AF2, #$9AF1, #$9B46, #$9B43, #$9B67, #$9B74, #$9B71, #$9B66, - #$9B76, #$9B75, #$9B70, #$9B68, #$9B64, #$9B6C, #$9CFC, #$9CFA, - #$9CFD, #$9CFF, #$9CF7, #$9D07, #$9D00, #$9CF9, #$9CFB, #$9D08, - #$9D05, #$9D04, #$9E83, #$9ED3, #$9F0F, #$9F10, #$511C, #$5113, - #$5117, #$511A, #$5111, #$51DE, #$5334, #$53E1, #$5670, #$5660, - #$566E, #$5673, #$5666, #$5663, #$566D, #$5672, #$565E, #$5677, - #$571C, #$571B, #$58C8, #$58BD, #$58C9, #$58BF, #$58BA, #$58C2, - #$58BC, #$58C6, #$5B17, #$5B19, #$5B1B, #$5B21, #$5B14, #$5B13, - #$5B10, #$5B16, #$5B28, #$5B1A, #$5B20, #$5B1E, #$5BEF, #$5DAC, - #$5DB1, #$5DA9, #$5DA7, #$5DB5, #$5DB0, #$5DAE, #$5DAA, #$5DA8, - #$5DB2, #$5DAD, #$5DAF, #$5DB4, #$5E67, #$5E68, #$5E66, #$5E6F, - #$5EE9, #$5EE7, #$5EE6, #$5EE8, #$5EE5, #$5F4B, - #$5FBC, #$5FBB, #$619D, #$61A8, #$6196, #$61C5, #$61B4, #$61C6, - #$61C1, #$61CC, #$61BA, #$61BF, #$61B8, #$618C, #$64D7, #$64D6, - #$64D0, #$64CF, #$64C9, #$64BD, #$6489, #$64C3, #$64DB, #$64F3, - #$64D9, #$6533, #$657F, #$657C, #$65A2, #$66C8, #$66BE, #$66C0, - #$66CA, #$66CB, #$66CF, #$66BD, #$66BB, #$66BA, #$66CC, #$6723, - #$6A34, #$6A66, #$6A49, #$6A67, #$6A32, #$6A68, #$6A3E, #$6A5D, - #$6A6D, #$6A76, #$6A5B, #$6A51, #$6A28, #$6A5A, #$6A3B, #$6A3F, - #$6A41, #$6A6A, #$6A64, #$6A50, #$6A4F, #$6A54, #$6A6F, #$6A69, - #$6A60, #$6A3C, #$6A5E, #$6A56, #$6A55, #$6A4D, #$6A4E, #$6A46, - #$6B55, #$6B54, #$6B56, #$6BA7, #$6BAA, #$6BAB, #$6BC8, #$6BC7, - #$6C04, #$6C03, #$6C06, #$6FAD, #$6FCB, #$6FA3, #$6FC7, #$6FBC, - #$6FCE, #$6FC8, #$6F5E, #$6FC4, #$6FBD, #$6F9E, - #$6FCA, #$6FA8, #$7004, #$6FA5, #$6FAE, #$6FBA, #$6FAC, #$6FAA, - #$6FCF, #$6FBF, #$6FB8, #$6FA2, #$6FC9, #$6FAB, #$6FCD, #$6FAF, - #$6FB2, #$6FB0, #$71C5, #$71C2, #$71BF, #$71B8, #$71D6, #$71C0, - #$71C1, #$71CB, #$71D4, #$71CA, #$71C7, #$71CF, #$71BD, #$71D8, - #$71BC, #$71C6, #$71DA, #$71DB, #$729D, #$729E, #$7369, #$7366, - #$7367, #$736C, #$7365, #$736B, #$736A, #$747F, #$749A, #$74A0, - #$7494, #$7492, #$7495, #$74A1, #$750B, #$7580, #$762F, #$762D, - #$7631, #$763D, #$7633, #$763C, #$7635, #$7632, #$7630, #$76BB, - #$76E6, #$779A, #$779D, #$77A1, #$779C, #$779B, #$77A2, #$77A3, - #$7795, #$7799, #$7797, #$78DD, #$78E9, #$78E5, #$78EA, #$78DE, - #$78E3, #$78DB, #$78E1, #$78E2, #$78ED, #$78DF, #$78E0, #$79A4, - #$7A44, #$7A48, #$7A47, #$7AB6, #$7AB8, #$7AB5, - #$7AB1, #$7AB7, #$7BDE, #$7BE3, #$7BE7, #$7BDD, #$7BD5, #$7BE5, - #$7BDA, #$7BE8, #$7BF9, #$7BD4, #$7BEA, #$7BE2, #$7BDC, #$7BEB, - #$7BD8, #$7BDF, #$7CD2, #$7CD4, #$7CD7, #$7CD0, #$7CD1, #$7E12, - #$7E21, #$7E17, #$7E0C, #$7E1F, #$7E20, #$7E13, #$7E0E, #$7E1C, - #$7E15, #$7E1A, #$7E22, #$7E0B, #$7E0F, #$7E16, #$7E0D, #$7E14, - #$7E25, #$7E24, #$7F43, #$7F7B, #$7F7C, #$7F7A, #$7FB1, #$7FEF, - #$802A, #$8029, #$806C, #$81B1, #$81A6, #$81AE, #$81B9, #$81B5, - #$81AB, #$81B0, #$81AC, #$81B4, #$81B2, #$81B7, #$81A7, #$81F2, - #$8255, #$8256, #$8257, #$8556, #$8545, #$856B, #$854D, #$8553, - #$8561, #$8558, #$8540, #$8546, #$8564, #$8541, #$8562, #$8544, - #$8551, #$8547, #$8563, #$853E, #$855B, #$8571, #$854E, #$856E, - #$8575, #$8555, #$8567, #$8560, #$858C, #$8566, - #$855D, #$8554, #$8565, #$856C, #$8663, #$8665, #$8664, #$87A4, - #$879B, #$878F, #$8797, #$8793, #$8792, #$8788, #$8781, #$8796, - #$8798, #$8779, #$8787, #$87A3, #$8785, #$8790, #$8791, #$879D, - #$8784, #$8794, #$879C, #$879A, #$8789, #$891E, #$8926, #$8930, - #$892D, #$892E, #$8927, #$8931, #$8922, #$8929, #$8923, #$892F, - #$892C, #$891F, #$89F1, #$8AE0, #$8AE2, #$8AF2, #$8AF4, #$8AF5, - #$8ADD, #$8B14, #$8AE4, #$8ADF, #$8AF0, #$8AC8, #$8ADE, #$8AE1, - #$8AE8, #$8AFF, #$8AEF, #$8AFB, #$8C91, #$8C92, #$8C90, #$8CF5, - #$8CEE, #$8CF1, #$8CF0, #$8CF3, #$8D6C, #$8D6E, #$8DA5, #$8DA7, - #$8E33, #$8E3E, #$8E38, #$8E40, #$8E45, #$8E36, #$8E3C, #$8E3D, - #$8E41, #$8E30, #$8E3F, #$8EBD, #$8F36, #$8F2E, #$8F35, #$8F32, - #$8F39, #$8F37, #$8F34, #$9076, #$9079, #$907B, - #$9086, #$90FA, #$9133, #$9135, #$9136, #$9193, #$9190, #$9191, - #$918D, #$918F, #$9327, #$931E, #$9308, #$931F, #$9306, #$930F, - #$937A, #$9338, #$933C, #$931B, #$9323, #$9312, #$9301, #$9346, - #$932D, #$930E, #$930D, #$92CB, #$931D, #$92FA, #$9313, #$92F9, - #$92F7, #$9334, #$9302, #$9324, #$92FF, #$9329, #$9339, #$9335, - #$932A, #$9314, #$930C, #$930B, #$92FE, #$9309, #$9300, #$92FB, - #$9316, #$95BC, #$95CD, #$95BE, #$95B9, #$95BA, #$95B6, #$95BF, - #$95B5, #$95BD, #$96A9, #$96D4, #$970B, #$9712, #$9710, #$9799, - #$9797, #$9794, #$97F0, #$97F8, #$9835, #$982F, #$9832, #$9924, - #$991F, #$9927, #$9929, #$999E, #$99EE, #$99EC, #$99E5, #$99E4, - #$99F0, #$99E3, #$99EA, #$99E9, #$99E7, #$9AB9, #$9ABF, #$9AB4, - #$9ABB, #$9AF6, #$9AFA, #$9AF9, #$9AF7, #$9B33, - #$9B80, #$9B85, #$9B87, #$9B7C, #$9B7E, #$9B7B, #$9B82, #$9B93, - #$9B92, #$9B90, #$9B7A, #$9B95, #$9B7D, #$9B88, #$9D25, #$9D17, - #$9D20, #$9D1E, #$9D14, #$9D29, #$9D1D, #$9D18, #$9D22, #$9D10, - #$9D19, #$9D1F, #$9E88, #$9E86, #$9E87, #$9EAE, #$9EAD, #$9ED5, - #$9ED6, #$9EFA, #$9F12, #$9F3D, #$5126, #$5125, #$5122, #$5124, - #$5120, #$5129, #$52F4, #$5693, #$568C, #$568D, #$5686, #$5684, - #$5683, #$567E, #$5682, #$567F, #$5681, #$58D6, #$58D4, #$58CF, - #$58D2, #$5B2D, #$5B25, #$5B32, #$5B23, #$5B2C, #$5B27, #$5B26, - #$5B2F, #$5B2E, #$5B7B, #$5BF1, #$5BF2, #$5DB7, #$5E6C, #$5E6A, - #$5FBE, #$61C3, #$61B5, #$61BC, #$61E7, #$61E0, #$61E5, #$61E4, - #$61E8, #$61DE, #$64EF, #$64E9, #$64E3, #$64EB, #$64E4, #$64E8, - #$6581, #$6580, #$65B6, #$65DA, #$66D2, #$6A8D, - #$6A96, #$6A81, #$6AA5, #$6A89, #$6A9F, #$6A9B, #$6AA1, #$6A9E, - #$6A87, #$6A93, #$6A8E, #$6A95, #$6A83, #$6AA8, #$6AA4, #$6A91, - #$6A7F, #$6AA6, #$6A9A, #$6A85, #$6A8C, #$6A92, #$6B5B, #$6BAD, - #$6C09, #$6FCC, #$6FA9, #$6FF4, #$6FD4, #$6FE3, #$6FDC, #$6FED, - #$6FE7, #$6FE6, #$6FDE, #$6FF2, #$6FDD, #$6FE2, #$6FE8, #$71E1, - #$71F1, #$71E8, #$71F2, #$71E4, #$71F0, #$71E2, #$7373, #$736E, - #$736F, #$7497, #$74B2, #$74AB, #$7490, #$74AA, #$74AD, #$74B1, - #$74A5, #$74AF, #$7510, #$7511, #$7512, #$750F, #$7584, #$7643, - #$7648, #$7649, #$7647, #$76A4, #$76E9, #$77B5, #$77AB, #$77B2, - #$77B7, #$77B6, #$77B4, #$77B1, #$77A8, #$77F0, #$78F3, #$78FD, - #$7902, #$78FB, #$78FC, #$78FF, #$78F2, #$7905, #$78F9, #$78FE, - #$7904, #$79AB, #$79A8, #$7A5C, #$7A5B, #$7A56, - #$7A58, #$7A54, #$7A5A, #$7ABE, #$7AC0, #$7AC1, #$7C05, #$7C0F, - #$7BF2, #$7C00, #$7BFF, #$7BFB, #$7C0E, #$7BF4, #$7C0B, #$7BF3, - #$7C02, #$7C09, #$7C03, #$7C01, #$7BF8, #$7BFD, #$7C06, #$7BF0, - #$7BF1, #$7C10, #$7C0A, #$7CE8, #$7E2D, #$7E3C, #$7E42, #$7E33, - #$9848, #$7E38, #$7E2A, #$7E49, #$7E40, #$7E47, #$7E29, #$7E4C, - #$7E30, #$7E3B, #$7E36, #$7E44, #$7E3A, #$7F45, #$7F7F, #$7F7E, - #$7F7D, #$7FF4, #$7FF2, #$802C, #$81BB, #$81C4, #$81CC, #$81CA, - #$81C5, #$81C7, #$81BC, #$81E9, #$825B, #$825A, #$825C, #$8583, - #$8580, #$858F, #$85A7, #$8595, #$85A0, #$858B, #$85A3, #$857B, - #$85A4, #$859A, #$859E, #$8577, #$857C, #$8589, #$85A1, #$857A, - #$8578, #$8557, #$858E, #$8596, #$8586, #$858D, #$8599, #$859D, - #$8581, #$85A2, #$8582, #$8588, #$8585, #$8579, - #$8576, #$8598, #$8590, #$859F, #$8668, #$87BE, #$87AA, #$87AD, - #$87C5, #$87B0, #$87AC, #$87B9, #$87B5, #$87BC, #$87AE, #$87C9, - #$87C3, #$87C2, #$87CC, #$87B7, #$87AF, #$87C4, #$87CA, #$87B4, - #$87B6, #$87BF, #$87B8, #$87BD, #$87DE, #$87B2, #$8935, #$8933, - #$893C, #$893E, #$8941, #$8952, #$8937, #$8942, #$89AD, #$89AF, - #$89AE, #$89F2, #$89F3, #$8B1E, #$8B18, #$8B16, #$8B11, #$8B05, - #$8B0B, #$8B22, #$8B0F, #$8B12, #$8B15, #$8B07, #$8B0D, #$8B08, - #$8B06, #$8B1C, #$8B13, #$8B1A, #$8C4F, #$8C70, #$8C72, #$8C71, - #$8C6F, #$8C95, #$8C94, #$8CF9, #$8D6F, #$8E4E, #$8E4D, #$8E53, - #$8E50, #$8E4C, #$8E47, #$8F43, #$8F40, #$9085, #$907E, #$9138, - #$919A, #$91A2, #$919B, #$9199, #$919F, #$91A1, #$919D, #$91A0, - #$93A1, #$9383, #$93AF, #$9364, #$9356, #$9347, - #$937C, #$9358, #$935C, #$9376, #$9349, #$9350, #$9351, #$9360, - #$936D, #$938F, #$934C, #$936A, #$9379, #$9357, #$9355, #$9352, - #$934F, #$9371, #$9377, #$937B, #$9361, #$935E, #$9363, #$9367, - #$934E, #$9359, #$95C7, #$95C0, #$95C9, #$95C3, #$95C5, #$95B7, - #$96AE, #$96B0, #$96AC, #$9720, #$971F, #$9718, #$971D, #$9719, - #$979A, #$97A1, #$979C, #$979E, #$979D, #$97D5, #$97D4, #$97F1, - #$9841, #$9844, #$984A, #$9849, #$9845, #$9843, #$9925, #$992B, - #$992C, #$992A, #$9933, #$9932, #$992F, #$992D, #$9931, #$9930, - #$9998, #$99A3, #$99A1, #$9A02, #$99FA, #$99F4, #$99F7, #$99F9, - #$99F8, #$99F6, #$99FB, #$99FD, #$99FE, #$99FC, #$9A03, #$9ABE, - #$9AFE, #$9AFD, #$9B01, #$9AFC, #$9B48, #$9B9A, #$9BA8, #$9B9E, - #$9B9B, #$9BA6, #$9BA1, #$9BA5, #$9BA4, #$9B86, - #$9BA2, #$9BA0, #$9BAF, #$9D33, #$9D41, #$9D67, #$9D36, #$9D2E, - #$9D2F, #$9D31, #$9D38, #$9D30, #$9D45, #$9D42, #$9D43, #$9D3E, - #$9D37, #$9D40, #$9D3D, #$7FF5, #$9D2D, #$9E8A, #$9E89, #$9E8D, - #$9EB0, #$9EC8, #$9EDA, #$9EFB, #$9EFF, #$9F24, #$9F23, #$9F22, - #$9F54, #$9FA0, #$5131, #$512D, #$512E, #$5698, #$569C, #$5697, - #$569A, #$569D, #$5699, #$5970, #$5B3C, #$5C69, #$5C6A, #$5DC0, - #$5E6D, #$5E6E, #$61D8, #$61DF, #$61ED, #$61EE, #$61F1, #$61EA, - #$61F0, #$61EB, #$61D6, #$61E9, #$64FF, #$6504, #$64FD, #$64F8, - #$6501, #$6503, #$64FC, #$6594, #$65DB, #$66DA, #$66DB, #$66D8, - #$6AC5, #$6AB9, #$6ABD, #$6AE1, #$6AC6, #$6ABA, #$6AB6, #$6AB7, - #$6AC7, #$6AB4, #$6AAD, #$6B5E, #$6BC9, #$6C0B, #$7007, #$700C, - #$700D, #$7001, #$7005, #$7014, #$700E, #$6FFF, - #$7000, #$6FFB, #$7026, #$6FFC, #$6FF7, #$700A, #$7201, #$71FF, - #$71F9, #$7203, #$71FD, #$7376, #$74B8, #$74C0, #$74B5, #$74C1, - #$74BE, #$74B6, #$74BB, #$74C2, #$7514, #$7513, #$765C, #$7664, - #$7659, #$7650, #$7653, #$7657, #$765A, #$76A6, #$76BD, #$76EC, - #$77C2, #$77BA, #$790C, #$7913, #$7914, #$7909, #$7910, #$7912, - #$7911, #$79AD, #$79AC, #$7A5F, #$7C1C, #$7C29, #$7C19, #$7C20, - #$7C1F, #$7C2D, #$7C1D, #$7C26, #$7C28, #$7C22, #$7C25, #$7C30, - #$7E5C, #$7E50, #$7E56, #$7E63, #$7E58, #$7E62, #$7E5F, #$7E51, - #$7E60, #$7E57, #$7E53, #$7FB5, #$7FB3, #$7FF7, #$7FF8, #$8075, - #$81D1, #$81D2, #$81D0, #$825F, #$825E, #$85B4, #$85C6, #$85C0, - #$85C3, #$85C2, #$85B3, #$85B5, #$85BD, #$85C7, #$85C4, #$85BF, - #$85CB, #$85CE, #$85C8, #$85C5, #$85B1, #$85B6, - #$85D2, #$8624, #$85B8, #$85B7, #$85BE, #$8669, #$87E7, #$87E6, - #$87E2, #$87DB, #$87EB, #$87EA, #$87E5, #$87DF, #$87F3, #$87E4, - #$87D4, #$87DC, #$87D3, #$87ED, #$87D8, #$87E3, #$87D7, #$87D9, - #$8801, #$87F4, #$87E8, #$87DD, #$8953, #$894B, #$894F, #$894C, - #$8946, #$8950, #$8951, #$8949, #$8B2A, #$8B27, #$8B23, #$8B33, - #$8B30, #$8B35, #$8B47, #$8B2F, #$8B3C, #$8B3E, #$8B31, #$8B25, - #$8B37, #$8B26, #$8B36, #$8B2E, #$8B24, #$8B3B, #$8B3D, #$8B3A, - #$8C42, #$8C75, #$8C99, #$8C98, #$8C97, #$8CFE, #$8D04, #$8D02, - #$8D00, #$8E5C, #$8E62, #$8E60, #$8E57, #$8E56, #$8E5E, #$8E65, - #$8E67, #$8E5B, #$8E5A, #$8E61, #$8E5D, #$8E69, #$8E54, #$8F46, - #$8F47, #$8F48, #$8F4B, #$9128, #$913A, #$913B, #$913E, #$91A8, - #$91A5, #$91A7, #$91AF, #$91AA, #$93B5, #$938C, - #$9392, #$93B7, #$939B, #$939D, #$9389, #$93A7, #$938E, #$93AA, - #$939E, #$93A6, #$9395, #$9388, #$9399, #$939F, #$9380, #$938D, - #$93B1, #$9391, #$93B2, #$93A4, #$93A8, #$93B4, #$93A3, #$95D2, - #$95D3, #$95D1, #$96B3, #$96D7, #$96DA, #$5DC2, #$96DF, #$96D8, - #$96DD, #$9723, #$9722, #$9725, #$97AC, #$97AE, #$97A8, #$97AB, - #$97A4, #$97AA, #$97A2, #$97A5, #$97D7, #$97D9, #$97D6, #$97D8, - #$97FA, #$9850, #$9851, #$9852, #$98B8, #$9941, #$993C, #$993A, - #$9A0F, #$9A0B, #$9A09, #$9A0D, #$9A04, #$9A11, #$9A0A, #$9A05, - #$9A07, #$9A06, #$9AC0, #$9ADC, #$9B08, #$9B04, #$9B05, #$9B29, - #$9B35, #$9B4A, #$9B4C, #$9B4B, #$9BC7, #$9BC6, #$9BC3, #$9BBF, - #$9BC1, #$9BB5, #$9BB8, #$9BD3, #$9BB6, #$9BC4, #$9BB9, #$9BBD, - #$9D5C, #$9D53, #$9D4F, #$9D4A, #$9D5B, #$9D4B, - #$9D59, #$9D56, #$9D4C, #$9D57, #$9D52, #$9D54, #$9D5F, #$9D58, - #$9D5A, #$9E8E, #$9E8C, #$9EDF, #$9F01, #$9F00, #$9F16, #$9F25, - #$9F2B, #$9F2A, #$9F29, #$9F28, #$9F4C, #$9F55, #$5134, #$5135, - #$5296, #$52F7, #$53B4, #$56AB, #$56AD, #$56A6, #$56A7, #$56AA, - #$56AC, #$58DA, #$58DD, #$58DB, #$5912, #$5B3D, #$5B3E, #$5B3F, - #$5DC3, #$5E70, #$5FBF, #$61FB, #$6507, #$6510, #$650D, #$6509, - #$650C, #$650E, #$6584, #$65DE, #$65DD, #$66DE, #$6AE7, #$6AE0, - #$6ACC, #$6AD1, #$6AD9, #$6ACB, #$6ADF, #$6ADC, #$6AD0, #$6AEB, - #$6ACF, #$6ACD, #$6ADE, #$6B60, #$6BB0, #$6C0C, #$7019, #$7027, - #$7020, #$7016, #$702B, #$7021, #$7022, #$7023, #$7029, #$7017, - #$7024, #$701C, #$720C, #$720A, #$7207, #$7202, #$7205, #$72A5, - #$72A6, #$72A4, #$72A3, #$72A1, #$74CB, #$74C5, - #$74B7, #$74C3, #$7516, #$7660, #$77C9, #$77CA, #$77C4, #$77F1, - #$791D, #$791B, #$7921, #$791C, #$7917, #$791E, #$79B0, #$7A67, - #$7A68, #$7C33, #$7C3C, #$7C39, #$7C2C, #$7C3B, #$7CEC, #$7CEA, - #$7E76, #$7E75, #$7E78, #$7E70, #$7E77, #$7E6F, #$7E7A, #$7E72, - #$7E74, #$7E68, #$7F4B, #$7F4A, #$7F83, #$7F86, #$7FB7, #$7FFD, - #$7FFE, #$8078, #$81D7, #$81D5, #$820B, #$8264, #$8261, #$8263, - #$85EB, #$85F1, #$85ED, #$85D9, #$85E1, #$85E8, #$85DA, #$85D7, - #$85EC, #$85F2, #$85F8, #$85D8, #$85DF, #$85E3, #$85DC, #$85D1, - #$85F0, #$85E6, #$85EF, #$85DE, #$85E2, #$8800, #$87FA, #$8803, - #$87F6, #$87F7, #$8809, #$880C, #$880B, #$8806, #$87FC, #$8808, - #$87FF, #$880A, #$8802, #$8962, #$895A, #$895B, #$8957, #$8961, - #$895C, #$8958, #$895D, #$8959, #$8988, #$89B7, - #$89B6, #$89F6, #$8B50, #$8B48, #$8B4A, #$8B40, #$8B53, #$8B56, - #$8B54, #$8B4B, #$8B55, #$8B51, #$8B42, #$8B52, #$8B57, #$8C43, - #$8C77, #$8C76, #$8C9A, #$8D06, #$8D07, #$8D09, #$8DAC, #$8DAA, - #$8DAD, #$8DAB, #$8E6D, #$8E78, #$8E73, #$8E6A, #$8E6F, #$8E7B, - #$8EC2, #$8F52, #$8F51, #$8F4F, #$8F50, #$8F53, #$8FB4, #$9140, - #$913F, #$91B0, #$91AD, #$93DE, #$93C7, #$93CF, #$93C2, #$93DA, - #$93D0, #$93F9, #$93EC, #$93CC, #$93D9, #$93A9, #$93E6, #$93CA, - #$93D4, #$93EE, #$93E3, #$93D5, #$93C4, #$93CE, #$93C0, #$93D2, - #$93A5, #$93E7, #$957D, #$95DA, #$95DB, #$96E1, #$9729, #$972B, - #$972C, #$9728, #$9726, #$97B3, #$97B7, #$97B6, #$97DD, #$97DE, - #$97DF, #$985C, #$9859, #$985D, #$9857, #$98BF, #$98BD, #$98BB, - #$98BE, #$9948, #$9947, #$9943, #$99A6, #$99A7, - #$9A1A, #$9A15, #$9A25, #$9A1D, #$9A24, #$9A1B, #$9A22, #$9A20, - #$9A27, #$9A23, #$9A1E, #$9A1C, #$9A14, #$9AC2, #$9B0B, #$9B0A, - #$9B0E, #$9B0C, #$9B37, #$9BEA, #$9BEB, #$9BE0, #$9BDE, #$9BE4, - #$9BE6, #$9BE2, #$9BF0, #$9BD4, #$9BD7, #$9BEC, #$9BDC, #$9BD9, - #$9BE5, #$9BD5, #$9BE1, #$9BDA, #$9D77, #$9D81, #$9D8A, #$9D84, - #$9D88, #$9D71, #$9D80, #$9D78, #$9D86, #$9D8B, #$9D8C, #$9D7D, - #$9D6B, #$9D74, #$9D75, #$9D70, #$9D69, #$9D85, #$9D73, #$9D7B, - #$9D82, #$9D6F, #$9D79, #$9D7F, #$9D87, #$9D68, #$9E94, #$9E91, - #$9EC0, #$9EFC, #$9F2D, #$9F40, #$9F41, #$9F4D, #$9F56, #$9F57, - #$9F58, #$5337, #$56B2, #$56B5, #$56B3, #$58E3, #$5B45, #$5DC6, - #$5DC7, #$5EEE, #$5EEF, #$5FC0, #$5FC1, #$61F9, #$6517, #$6516, - #$6515, #$6513, #$65DF, #$66E8, #$66E3, #$66E4, - #$6AF3, #$6AF0, #$6AEA, #$6AE8, #$6AF9, #$6AF1, #$6AEE, #$6AEF, - #$703C, #$7035, #$702F, #$7037, #$7034, #$7031, #$7042, #$7038, - #$703F, #$703A, #$7039, #$702A, #$7040, #$703B, #$7033, #$7041, - #$7213, #$7214, #$72A8, #$737D, #$737C, #$74BA, #$76AB, #$76AA, - #$76BE, #$76ED, #$77CC, #$77CE, #$77CF, #$77CD, #$77F2, #$7925, - #$7923, #$7927, #$7928, #$7924, #$7929, #$79B2, #$7A6E, #$7A6C, - #$7A6D, #$7AF7, #$7C49, #$7C48, #$7C4A, #$7C47, #$7C45, #$7CEE, - #$7E7B, #$7E7E, #$7E81, #$7E80, #$7FBA, #$7FFF, #$8079, #$81DB, - #$81D9, #$8268, #$8269, #$8622, #$85FF, #$8601, #$85FE, #$861B, - #$8600, #$85F6, #$8604, #$8609, #$8605, #$860C, #$85FD, #$8819, - #$8810, #$8811, #$8817, #$8813, #$8816, #$8963, #$8966, #$89B9, - #$89F7, #$8B60, #$8B6A, #$8B5D, #$8B68, #$8B63, - #$8B65, #$8B67, #$8B6D, #$8DAE, #$8E86, #$8E88, #$8E84, #$8F59, - #$8F56, #$8F57, #$8F55, #$8F58, #$8F5A, #$908D, #$9143, #$9141, - #$91B7, #$91B5, #$91B2, #$91B3, #$940B, #$9413, #$93FB, #$9420, - #$940F, #$9414, #$93FE, #$9415, #$9410, #$9428, #$9419, #$940D, - #$93F5, #$9400, #$93F7, #$9407, #$940E, #$9416, #$9412, #$93FA, - #$9409, #$93F8, #$943C, #$940A, #$93FF, #$93FC, #$940C, #$93F6, - #$9411, #$9406, #$95DE, #$95E0, #$95DF, #$972E, #$972F, #$97B9, - #$97BB, #$97FD, #$97FE, #$9860, #$9862, #$9863, #$985F, #$98C1, - #$98C2, #$9950, #$994E, #$9959, #$994C, #$994B, #$9953, #$9A32, - #$9A34, #$9A31, #$9A2C, #$9A2A, #$9A36, #$9A29, #$9A2E, #$9A38, - #$9A2D, #$9AC7, #$9ACA, #$9AC6, #$9B10, #$9B12, #$9B11, #$9C0B, - #$9C08, #$9BF7, #$9C05, #$9C12, #$9BF8, #$9C40, - #$9C07, #$9C0E, #$9C06, #$9C17, #$9C14, #$9C09, #$9D9F, #$9D99, - #$9DA4, #$9D9D, #$9D92, #$9D98, #$9D90, #$9D9B, #$9DA0, #$9D94, - #$9D9C, #$9DAA, #$9D97, #$9DA1, #$9D9A, #$9DA2, #$9DA8, #$9D9E, - #$9DA3, #$9DBF, #$9DA9, #$9D96, #$9DA6, #$9DA7, #$9E99, #$9E9B, - #$9E9A, #$9EE5, #$9EE4, #$9EE7, #$9EE6, #$9F30, #$9F2E, #$9F5B, - #$9F60, #$9F5E, #$9F5D, #$9F59, #$9F91, #$513A, #$5139, #$5298, - #$5297, #$56C3, #$56BD, #$56BE, #$5B48, #$5B47, #$5DCB, #$5DCF, - #$5EF1, #$61FD, #$651B, #$6B02, #$6AFC, #$6B03, #$6AF8, #$6B00, - #$7043, #$7044, #$704A, #$7048, #$7049, #$7045, #$7046, #$721D, - #$721A, #$7219, #$737E, #$7517, #$766A, #$77D0, #$792D, #$7931, - #$792F, #$7C54, #$7C53, #$7CF2, #$7E8A, #$7E87, #$7E88, #$7E8B, - #$7E86, #$7E8D, #$7F4D, #$7FBB, #$8030, #$81DD, - #$8618, #$862A, #$8626, #$861F, #$8623, #$861C, #$8619, #$8627, - #$862E, #$8621, #$8620, #$8629, #$861E, #$8625, #$8829, #$881D, - #$881B, #$8820, #$8824, #$881C, #$882B, #$884A, #$896D, #$8969, - #$896E, #$896B, #$89FA, #$8B79, #$8B78, #$8B45, #$8B7A, #$8B7B, - #$8D10, #$8D14, #$8DAF, #$8E8E, #$8E8C, #$8F5E, #$8F5B, #$8F5D, - #$9146, #$9144, #$9145, #$91B9, #$943F, #$943B, #$9436, #$9429, - #$943D, #$9430, #$9439, #$942A, #$9437, #$942C, #$9440, #$9431, - #$95E5, #$95E4, #$95E3, #$9735, #$973A, #$97BF, #$97E1, #$9864, - #$98C9, #$98C6, #$98C0, #$9958, #$9956, #$9A39, #$9A3D, #$9A46, - #$9A44, #$9A42, #$9A41, #$9A3A, #$9A3F, #$9ACD, #$9B15, #$9B17, - #$9B18, #$9B16, #$9B3A, #$9B52, #$9C2B, #$9C1D, #$9C1C, #$9C2C, - #$9C23, #$9C28, #$9C29, #$9C24, #$9C21, #$9DB7, - #$9DB6, #$9DBC, #$9DC1, #$9DC7, #$9DCA, #$9DCF, #$9DBE, #$9DC5, - #$9DC3, #$9DBB, #$9DB5, #$9DCE, #$9DB9, #$9DBA, #$9DAC, #$9DC8, - #$9DB1, #$9DAD, #$9DCC, #$9DB3, #$9DCD, #$9DB2, #$9E7A, #$9E9C, - #$9EEB, #$9EEE, #$9EED, #$9F1B, #$9F18, #$9F1A, #$9F31, #$9F4E, - #$9F65, #$9F64, #$9F92, #$4EB9, #$56C6, #$56C5, #$56CB, #$5971, - #$5B4B, #$5B4C, #$5DD5, #$5DD1, #$5EF2, #$6521, #$6520, #$6526, - #$6522, #$6B0B, #$6B08, #$6B09, #$6C0D, #$7055, #$7056, #$7057, - #$7052, #$721E, #$721F, #$72A9, #$737F, #$74D8, #$74D5, #$74D9, - #$74D7, #$766D, #$76AD, #$7935, #$79B4, #$7A70, #$7A71, #$7C57, - #$7C5C, #$7C59, #$7C5B, #$7C5A, #$7CF4, #$7CF1, #$7E91, #$7F4F, - #$7F87, #$81DE, #$826B, #$8634, #$8635, #$8633, #$862C, #$8632, - #$8636, #$882C, #$8828, #$8826, #$882A, #$8825, - #$8971, #$89BF, #$89BE, #$89FB, #$8B7E, #$8B84, #$8B82, #$8B86, - #$8B85, #$8B7F, #$8D15, #$8E95, #$8E94, #$8E9A, #$8E92, #$8E90, - #$8E96, #$8E97, #$8F60, #$8F62, #$9147, #$944C, #$9450, #$944A, - #$944B, #$944F, #$9447, #$9445, #$9448, #$9449, #$9446, #$973F, - #$97E3, #$986A, #$9869, #$98CB, #$9954, #$995B, #$9A4E, #$9A53, - #$9A54, #$9A4C, #$9A4F, #$9A48, #$9A4A, #$9A49, #$9A52, #$9A50, - #$9AD0, #$9B19, #$9B2B, #$9B3B, #$9B56, #$9B55, #$9C46, #$9C48, - #$9C3F, #$9C44, #$9C39, #$9C33, #$9C41, #$9C3C, #$9C37, #$9C34, - #$9C32, #$9C3D, #$9C36, #$9DDB, #$9DD2, #$9DDE, #$9DDA, #$9DCB, - #$9DD0, #$9DDC, #$9DD1, #$9DDF, #$9DE9, #$9DD9, #$9DD8, #$9DD6, - #$9DF5, #$9DD5, #$9DDD, #$9EB6, #$9EF0, #$9F35, #$9F33, #$9F32, - #$9F42, #$9F6B, #$9F95, #$9FA2, #$513D, #$5299, - #$58E8, #$58E7, #$5972, #$5B4D, #$5DD8, #$882F, #$5F4F, #$6201, - #$6203, #$6204, #$6529, #$6525, #$6596, #$66EB, #$6B11, #$6B12, - #$6B0F, #$6BCA, #$705B, #$705A, #$7222, #$7382, #$7381, #$7383, - #$7670, #$77D4, #$7C67, #$7C66, #$7E95, #$826C, #$863A, #$8640, - #$8639, #$863C, #$8631, #$863B, #$863E, #$8830, #$8832, #$882E, - #$8833, #$8976, #$8974, #$8973, #$89FE, #$8B8C, #$8B8E, #$8B8B, - #$8B88, #$8C45, #$8D19, #$8E98, #$8F64, #$8F63, #$91BC, #$9462, - #$9455, #$945D, #$9457, #$945E, #$97C4, #$97C5, #$9800, #$9A56, - #$9A59, #$9B1E, #$9B1F, #$9B20, #$9C52, #$9C58, #$9C50, #$9C4A, - #$9C4D, #$9C4B, #$9C55, #$9C59, #$9C4C, #$9C4E, #$9DFB, #$9DF7, - #$9DEF, #$9DE3, #$9DEB, #$9DF8, #$9DE4, #$9DF6, #$9DE1, #$9DEE, - #$9DE6, #$9DF2, #$9DF0, #$9DE2, #$9DEC, #$9DF4, - #$9DF3, #$9DE8, #$9DED, #$9EC2, #$9ED0, #$9EF2, #$9EF3, #$9F06, - #$9F1C, #$9F38, #$9F37, #$9F36, #$9F43, #$9F4F, #$9F71, #$9F70, - #$9F6E, #$9F6F, #$56D3, #$56CD, #$5B4E, #$5C6D, #$652D, #$66ED, - #$66EE, #$6B13, #$705F, #$7061, #$705D, #$7060, #$7223, #$74DB, - #$74E5, #$77D5, #$7938, #$79B7, #$79B6, #$7C6A, #$7E97, #$7F89, - #$826D, #$8643, #$8838, #$8837, #$8835, #$884B, #$8B94, #$8B95, - #$8E9E, #$8E9F, #$8EA0, #$8E9D, #$91BE, #$91BD, #$91C2, #$946B, - #$9468, #$9469, #$96E5, #$9746, #$9743, #$9747, #$97C7, #$97E5, - #$9A5E, #$9AD5, #$9B59, #$9C63, #$9C67, #$9C66, #$9C62, #$9C5E, - #$9C60, #$9E02, #$9DFE, #$9E07, #$9E03, #$9E06, #$9E05, #$9E00, - #$9E01, #$9E09, #$9DFF, #$9DFD, #$9E04, #$9EA0, #$9F1E, #$9F46, - #$9F74, #$9F75, #$9F76, #$56D4, #$652E, #$65B8, - #$6B18, #$6B19, #$6B17, #$6B1A, #$7062, #$7226, #$72AA, #$77D8, - #$77D9, #$7939, #$7C69, #$7C6B, #$7CF6, #$7E9A, #$7E98, #$7E9B, - #$7E99, #$81E0, #$81E1, #$8646, #$8647, #$8648, #$8979, #$897A, - #$897C, #$897B, #$89FF, #$8B98, #$8B99, #$8EA5, #$8EA4, #$8EA3, - #$946E, #$946D, #$946F, #$9471, #$9473, #$9749, #$9872, #$995F, - #$9C68, #$9C6E, #$9C6D, #$9E0B, #$9E0D, #$9E10, #$9E0F, #$9E12, - #$9E11, #$9EA1, #$9EF5, #$9F09, #$9F47, #$9F78, #$9F7B, #$9F7A, - #$9F79, #$571E, #$7066, #$7C6F, #$883C, #$8DB2, #$8EA6, #$91C3, - #$9474, #$9478, #$9476, #$9475, #$9A60, #$9B2E, #$9C74, #$9C73, - #$9C71, #$9C75, #$9E14, #$9E13, #$9EF6, #$9F0A, #$9FA4, #$7068, - #$7065, #$7CF7, #$866A, #$883E, #$883D, #$883F, #$8B9E, #$8C9C, - #$8EA9, #$8EC9, #$974B, #$9873, #$9874, #$98CC, - #$9961, #$99AB, #$9A64, #$9A66, #$9A67, #$9B24, #$9E15, #$9E17, - #$9F48, #$6207, #$6B1E, #$7227, #$864C, #$8EA8, #$9482, #$9480, - #$9481, #$9A69, #$9A68, #$9E19, #$864B, #$8B9F, #$9483, #$9C79, - #$9EB7, #$7675, #$9A6B, #$9C7A, #$9E1D, #$7069, #$706A, #$7229, - #$9EA4, #$9F7E, #$9F49, #$9F98); - - UHC_1_1Map: array[0..75] of Word = ( - $C8A5, $C8D8, $C910, $C93E, $C971, $C9A5, $C9DE, $CA1C, - $CA47, $CA7B, $CAA8, $CADD, $CB0B, $CB3A, $CB6D, $CB99, - $CBC5, $CBF3, $CC25, $CC67, $CC94, $CCCF, $CCFE, $CD34, - $CD61, $CD92, $CDC6, $CDF5, $CE2C, $CE5D, $CE9A, $CECC, - $CF02, $CF3B, $CF6D, $CF9E, $CFCC, $CFFF, $D02E, $D064, - $D095, $D0CC, $D105, $D132, $D16E, $D19B, $D1D0, $D1FD, - $D22A, $D25E, $D28D, $D2C5, $D2FB, $D33E, $D36A, $D3A1, - $D3D7, $D40D, $D438, $D467, $D49E, $D4C9, $D4FE, $D52E, - $D564, $D59D, $D5CA, $D606, $D63D, $D677, $D6AB, $D6E2, - $D715, $D74E, $D78D, $FFFD); - UHC_1_2Map: array[0..3125] of Byte = ( - $00, $01, $02, $04, $05, $06, $07, $08, - $09, $0A, $0B, $0C, $0D, $0E, $0F, $10, - $11, $12, $13, $14, $15, $16, $19, $1A, - $1B, $1C, $1D, $1E, $20, $21, $22, $24, - $25, $26, $28, $29, $2A, $2B, $2C, $2D, - $2E, $31, $00, $02, $03, $04, $05, $06, - $07, $0A, $0B, $0D, $0E, $0F, $10, $11, - $12, $13, $14, $15, $16, $17, $18, $19, - $1A, $1B, $1C, $1E, $1F, $20, $21, $22, - $23, $26, $27, $29, $2A, $2B, $2F, $30, - $31, $32, $33, $36, - $00, $02, $03, $04, $05, $06, $07, $09, - $0A, $0B, $0C, $0D, $0E, $0F, $10, $11, - $12, $13, $14, $15, $16, $17, $18, $19, - $1A, $1B, $1D, $1E, $1F, $20, $21, $22, - $23, $25, $26, $27, $28, $29, $2A, $2B, - $2C, $2D, $00, $01, $02, $03, $04, $05, - $06, $07, $08, $09, $0A, $0B, $0C, $0D, - $0E, $0F, $10, $11, $14, $15, $17, $18, - $19, $1B, $1C, $1D, $1E, $1F, $20, $21, - $24, $26, $27, $28, $29, $2A, $2B, $2C, - $2D, $2F, $30, $31, - $00, $01, $02, $04, $05, $06, $07, $08, - $09, $0A, $0C, $0D, $0E, $0F, $10, $11, - $12, $13, $14, $15, $16, $19, $1A, $1C, - $1D, $1E, $20, $21, $22, $23, $24, $25, - $26, $29, $2B, $2D, $2E, $2F, $30, $31, - $32, $33, $00, $01, $02, $03, $04, $05, - $06, $07, $08, $09, $0A, $0B, $0C, $0D, - $0E, $0F, $10, $11, $12, $13, $14, $15, - $16, $17, $18, $19, $1A, $1D, $1E, $20, - $21, $24, $26, $27, $28, $29, $2A, $2D, - $2F, $32, $33, $36, - $00, $01, $03, $05, $07, $08, $0A, $0B, - $0C, $0D, $10, $14, $15, $16, $17, $18, - $19, $1C, $1D, $1F, $20, $21, $23, $24, - $25, $26, $27, $28, $29, $2C, $30, $31, - $32, $33, $34, $35, $37, $38, $39, $3B, - $3C, $3D, $00, $01, $02, $03, $04, $05, - $06, $07, $08, $09, $0A, $0B, $0C, $0E, - $0F, $10, $11, $12, $13, $14, $15, $16, - $17, $18, $19, $1A, $1B, $1C, $1D, $1E, - $1F, $20, $21, $22, $23, $24, $25, $26, - $27, $28, $29, $2A, - $00, $01, $02, $03, $04, $07, $08, $0A, - $0B, $0C, $0E, $0F, $10, $11, $12, $13, - $14, $17, $1B, $1C, $1D, $1E, $1F, $20, - $22, $23, $24, $25, $26, $27, $28, $29, - $2A, $2B, $2C, $2D, $2E, $2F, $30, $31, - $32, $33, $00, $01, $03, $04, $05, $06, - $07, $08, $0A, $0B, $0C, $0D, $0E, $0F, - $10, $11, $12, $13, $14, $15, $16, $17, - $18, $19, $1A, $1B, $1C, $1E, $1F, $20, - $21, $22, $23, $24, $25, $26, $27, $28, - $29, $2A, $2B, $2C, - $00, $01, $02, $03, $04, $05, $06, $07, - $08, $09, $0A, $0B, $0C, $0D, $0E, $0F, - $10, $11, $12, $13, $16, $17, $19, $1A, - $1B, $1D, $1E, $1F, $20, $21, $22, $23, - $26, $28, $2A, $2C, $2D, $2E, $2F, $32, - $33, $34, $00, $01, $02, $04, $05, $06, - $07, $08, $09, $0A, $0B, $0C, $0D, $0E, - $10, $11, $12, $13, $14, $15, $16, $18, - $19, $1A, $1B, $1C, $1D, $1E, $1F, $20, - $21, $22, $23, $24, $25, $26, $27, $28, - $29, $2A, $2C, $2D, - $00, $01, $02, $03, $04, $06, $07, $08, - $0A, $0B, $0C, $0E, $0F, $10, $11, $12, - $13, $14, $17, $18, $19, $1A, $1B, $1C, - $1D, $1E, $1F, $20, $21, $22, $23, $24, - $25, $26, $27, $28, $29, $2A, $2B, $2C, - $2D, $2E, $00, $01, $02, $03, $04, $05, - $06, $08, $09, $0A, $0B, $0C, $0D, $10, - $11, $13, $14, $15, $17, $18, $19, $1A, - $1B, $1C, $1D, $20, $21, $22, $24, $25, - $26, $27, $28, $29, $2B, $2C, $2D, $2E, - $2F, $30, $31, $32, - $00, $01, $02, $03, $04, $05, $06, $07, - $08, $09, $0A, $0D, $0E, $0F, $10, $11, - $12, $13, $14, $15, $16, $17, $18, $19, - $1A, $1B, $1C, $1D, $1E, $1F, $20, $21, - $22, $23, $24, $25, $26, $27, $28, $29, - $2A, $2B, $00, $01, $02, $04, $05, $06, - $07, $08, $09, $0A, $0B, $0C, $0D, $0E, - $0F, $10, $11, $12, $13, $14, $15, $16, - $17, $18, $19, $1A, $1B, $1C, $1D, $1E, - $20, $21, $22, $23, $24, $25, $26, $27, - $28, $29, $2A, $2B, - $00, $01, $02, $03, $04, $05, $06, $07, - $08, $09, $0A, $0B, $0C, $0D, $0E, $10, - $11, $12, $13, $14, $15, $16, $17, $18, - $19, $1A, $1B, $1C, $1D, $1E, $20, $21, - $23, $25, $26, $27, $28, $29, $2A, $2B, - $2C, $2D, $00, $01, $02, $03, $04, $05, - $06, $07, $08, $09, $0A, $0B, $0C, $0D, - $0E, $0F, $10, $11, $12, $13, $14, $15, - $16, $17, $18, $1B, $1C, $1E, $1F, $20, - $22, $23, $24, $25, $26, $27, $28, $2B, - $2C, $2D, $30, $31, - $00, $01, $05, $06, $08, $0A, $0C, $0D, - $0E, $0F, $10, $11, $12, $15, $1A, $1B, - $1C, $1D, $1E, $21, $22, $24, $25, $26, - $28, $29, $2A, $2B, $2C, $2D, $2E, $31, - $35, $36, $37, $38, $39, $3A, $3C, $3D, - $3E, $40, $00, $02, $03, $04, $05, $06, - $07, $08, $0A, $0B, $0C, $0D, $0F, $10, - $11, $12, $13, $14, $15, $16, $17, $18, - $19, $1A, $1B, $1C, $1D, $1E, $1F, $20, - $21, $22, $23, $24, $25, $26, $27, $28, - $29, $2A, $2B, $2C, - $00, $01, $02, $03, $06, $07, $09, $0A, - $0B, $0D, $0E, $0F, $10, $11, $12, $13, - $16, $1A, $1B, $1C, $1D, $1E, $1F, $22, - $23, $25, $26, $27, $29, $2A, $2B, $2C, - $2D, $2E, $2F, $32, $34, $36, $37, $38, - $39, $3A, $00, $02, $03, $04, $06, $07, - $08, $09, $0A, $0B, $0C, $0D, $0E, $0F, - $10, $11, $12, $13, $14, $16, $17, $18, - $19, $1A, $1B, $1C, $1E, $1F, $20, $22, - $23, $24, $25, $26, $27, $28, $29, $2A, - $2B, $2C, $2D, $2E, - $00, $01, $02, $04, $05, $06, $07, $08, - $09, $0C, $0D, $0F, $10, $11, $13, $14, - $15, $16, $17, $18, $19, $1C, $1E, $20, - $21, $22, $23, $24, $25, $27, $28, $29, - $2B, $2C, $2D, $2F, $30, $31, $32, $33, - $34, $35, $00, $01, $02, $03, $04, $06, - $07, $08, $09, $0A, $0B, $0C, $0D, $0E, - $0F, $10, $11, $12, $13, $14, $15, $16, - $17, $18, $19, $1A, $1B, $1C, $1D, $1E, - $1F, $20, $21, $22, $23, $24, $25, $26, - $27, $29, $2A, $2B, - $00, $01, $02, $04, $05, $06, $07, $08, - $09, $0A, $0D, $0F, $11, $12, $13, $14, - $15, $16, $18, $19, $1A, $1B, $1C, $1D, - $1E, $1F, $20, $21, $22, $23, $24, $25, - $26, $28, $29, $2A, $2B, $2C, $2D, $2E, - $2F, $30, $00, $01, $04, $05, $07, $08, - $09, $0B, $0C, $0D, $0E, $0F, $10, $11, - $14, $16, $18, $19, $1A, $1B, $1C, $1D, - $1F, $20, $21, $22, $23, $24, $25, $26, - $27, $28, $29, $2A, $2B, $2C, $2D, $2E, - $2F, $30, $31, $33, - $00, $01, $02, $03, $04, $05, $07, $08, - $09, $0B, $0C, $0D, $0E, $0F, $10, $11, - $12, $13, $14, $15, $16, $17, $18, $19, - $1A, $1B, $1C, $1D, $1E, $1F, $20, $21, - $23, $24, $25, $27, $28, $29, $2B, $2C, - $2D, $2E, $00, $01, $02, $05, $07, $09, - $0A, $0B, $0C, $0D, $0E, $10, $11, $12, - $14, $15, $16, $18, $19, $1A, $1B, $1C, - $1D, $1E, $20, $21, $22, $23, $25, $26, - $27, $28, $29, $2A, $2D, $2E, $30, $31, - $32, $34, $35, $36, - $00, $01, $02, $03, $06, $08, $0A, $0B, - $0C, $0D, $0E, $0F, $10, $11, $12, $13, - $14, $15, $16, $17, $18, $19, $1A, $1B, - $1C, $1D, $1E, $1F, $20, $21, $22, $23, - $24, $25, $26, $27, $28, $29, $2A, $2B, - $2E, $2F, $00, $01, $05, $06, $07, $08, - $09, $0A, $0D, $0F, $11, $12, $13, $14, - $15, $16, $19, $1A, $1C, $1D, $1E, $20, - $21, $22, $23, $24, $25, $26, $29, $2B, - $2D, $2E, $2F, $30, $31, $32, $35, $36, - $38, $39, $3A, $3C, - $00, $01, $02, $03, $04, $05, $08, $0C, - $0D, $0E, $0F, $10, $11, $14, $15, $16, - $17, $18, $19, $1A, $1B, $1C, $1D, $1E, - $1F, $20, $21, $22, $23, $24, $25, $26, - $28, $29, $2A, $2B, $2C, $2D, $2E, $2F, - $30, $31, $00, $01, $02, $03, $04, $05, - $06, $07, $08, $09, $0A, $0B, $0C, $0D, - $0E, $0F, $10, $11, $12, $13, $14, $15, - $16, $17, $1A, $1B, $1D, $1E, $21, $22, - $23, $24, $25, $26, $27, $2A, $2E, $2F, - $30, $31, $32, $33, - $00, $01, $03, $04, $05, $07, $08, $09, - $0A, $0B, $0C, $0D, $10, $12, $14, $15, - $16, $17, $18, $19, $1B, $1C, $1D, $1F, - $20, $21, $23, $24, $25, $26, $27, $28, - $29, $2C, $30, $31, $32, $33, $34, $35, - $37, $38, $00, $01, $02, $03, $04, $05, - $06, $07, $08, $09, $0A, $0B, $0C, $0D, - $0E, $0F, $10, $11, $12, $13, $14, $15, - $16, $17, $18, $1B, $1C, $1E, $1F, $20, - $22, $23, $24, $25, $26, $27, $28, $2B, - $2D, $2F, $30, $31, - $00, $01, $02, $05, $06, $08, $09, $0A, - $0C, $0D, $0E, $0F, $10, $11, $12, $14, - $15, $16, $17, $19, $1A, $1B, $1C, $1D, - $1E, $20, $21, $22, $23, $24, $25, $26, - $27, $28, $29, $2A, $2B, $2C, $2D, $2E, - $2F, $30, $00, $01, $02, $04, $05, $06, - $07, $08, $09, $0B, $0C, $0D, $0E, $0F, - $10, $11, $13, $14, $15, $16, $17, $18, - $19, $1A, $1B, $1C, $1D, $1E, $1F, $20, - $21, $22, $23, $24, $25, $27, $28, $29, - $2A, $2B, $2C, $2D, - $00, $01, $02, $03, $04, $05, $06, $07, - $08, $09, $0A, $0B, $0C, $0D, $0E, $0F, - $10, $11, $12, $13, $16, $17, $19, $1A, - $1B, $1D, $1E, $1F, $20, $21, $22, $23, - $26, $28, $2A, $2B, $2C, $2D, $2E, $2F, - $31, $32, $00, $02, $03, $04, $06, $07, - $08, $09, $0A, $0B, $0C, $0D, $0E, $0F, - $10, $11, $13, $14, $15, $16, $17, $18, - $1A, $1B, $1C, $1D, $1E, $1F, $20, $21, - $22, $23, $24, $25, $26, $27, $28, $29, - $2A, $2B, $2C, $2D, - $00, $01, $02, $03, $04, $05, $08, $09, - $0B, $0C, $0D, $0F, $10, $11, $12, $13, - $14, $15, $18, $1A, $1C, $1D, $1E, $1F, - $20, $21, $23, $24, $25, $27, $28, $29, - $2B, $2C, $2D, $2E, $2F, $30, $31, $33, - $34, $35, $00, $01, $02, $03, $04, $05, - $06, $07, $0A, $0B, $0D, $0E, $0F, $11, - $12, $13, $14, $15, $16, $17, $1A, $1B, - $1C, $1E, $1F, $20, $21, $22, $23, $24, - $25, $26, $27, $28, $29, $2A, $2B, $2C, - $2D, $2E, $2F, $30, - $00, $01, $02, $03, $04, $05, $06, $07, - $08, $09, $0A, $0B, $0C, $0D, $0E, $11, - $12, $14, $15, $16, $18, $19, $1A, $1B, - $1C, $1D, $1E, $21, $23, $25, $26, $27, - $28, $29, $2A, $2D, $2E, $30, $31, $32, - $35, $36, $00, $01, $02, $03, $06, $0A, - $0B, $0C, $0D, $0E, $0F, $12, $13, $15, - $16, $17, $19, $1A, $1B, $1C, $1D, $1E, - $1F, $22, $26, $27, $28, $29, $2A, $2B, - $2D, $2E, $2F, $30, $31, $32, $33, $34, - $35, $36, $37, $38, - $00, $01, $02, $03, $04, $05, $06, $07, - $09, $0A, $0B, $0C, $0D, $0E, $0F, $10, - $11, $12, $13, $14, $15, $16, $17, $18, - $19, $1A, $1B, $1C, $1D, $1E, $1F, $20, - $21, $22, $23, $24, $25, $26, $27, $28, - $29, $2A, $00, $01, $03, $04, $05, $07, - $09, $0A, $0B, $0C, $0D, $10, $14, $15, - $16, $17, $18, $19, $1C, $1D, $1F, $20, - $21, $23, $24, $25, $26, $27, $28, $29, - $2C, $2E, $30, $31, $32, $33, $34, $35, - $37, $38, $39, $3B, - $00, $01, $02, $03, $04, $05, $06, $07, - $08, $09, $0A, $0B, $0C, $0D, $0F, $10, - $11, $12, $13, $14, $15, $17, $18, $19, - $1B, $1C, $1D, $1E, $1F, $20, $21, $22, - $23, $24, $25, $26, $27, $28, $29, $2A, - $2B, $2C, $00, $01, $02, $03, $04, $07, - $08, $0A, $0B, $0C, $0E, $0F, $10, $11, - $12, $13, $14, $17, $19, $1B, $1C, $1D, - $1E, $20, $22, $23, $24, $26, $27, $28, - $29, $2A, $2B, $2C, $2D, $2E, $2F, $30, - $31, $32, $33, $34, - $00, $01, $02, $03, $04, $05, $06, $07, - $09, $0A, $0B, $0C, $0D, $0E, $0F, $10, - $11, $12, $13, $14, $15, $16, $17, $18, - $19, $1A, $1B, $1C, $1D, $1E, $1F, $20, - $21, $22, $23, $25, $26, $27, $29, $2A, - $2B, $2C, $00, $01, $02, $03, $04, $05, - $06, $07, $08, $09, $0B, $0D, $0E, $0F, - $10, $11, $12, $14, $15, $16, $17, $18, - $19, $1A, $1B, $1C, $1D, $1E, $1F, $20, - $21, $22, $23, $24, $25, $26, $27, $28, - $29, $2A, $2B, $2C, - $00, $01, $04, $05, $07, $08, $09, $0B, - $0C, $0D, $0E, $0F, $10, $11, $14, $16, - $18, $19, $1A, $1B, $1C, $1D, $1F, $20, - $21, $22, $23, $24, $25, $26, $27, $28, - $29, $2A, $2B, $2C, $2D, $2E, $2F, $30, - $31, $33, $00, $01, $02, $03, $04, $05, - $07, $08, $09, $0A, $0B, $0C, $0D, $0E, - $0F, $10, $11, $12, $13, $14, $15, $16, - $17, $18, $19, $1A, $1B, $1C, $1D, $1E, - $1F, $20, $21, $24, $25, $27, $28, $29, - $2B, $2C, $2D, $2E, - $00, $01, $02, $05, $06, $07, $09, $0A, - $0B, $0C, $0D, $0E, $10, $11, $12, $14, - $15, $16, $18, $19, $1A, $1B, $1C, $1D, - $1E, $20, $21, $22, $23, $25, $26, $27, - $28, $29, $2A, $2D, $2E, $30, $31, $34, - $36, $37, $00, $01, $02, $05, $07, $08, - $09, $0A, $0B, $0C, $0D, $0E, $10, $11, - $12, $14, $15, $16, $18, $19, $1A, $1B, - $1C, $1D, $1E, $21, $22, $23, $24, $25, - $26, $27, $28, $29, $2A, $2D, $2E, $30, - $31, $32, $34, $35, - $00, $01, $02, $03, $04, $07, $09, $0B, - $0C, $0D, $0E, $0F, $10, $14, $16, $17, - $18, $1A, $1C, $1D, $1E, $1F, $20, $23, - $27, $28, $29, $2B, $2C, $2F, $30, $32, - $33, $34, $36, $37, $38, $39, $3A, $3B, - $3C, $3F, $00, $01, $02, $03, $04, $05, - $08, $09, $0A, $0B, $0C, $0D, $0E, $0F, - $10, $11, $12, $13, $14, $15, $16, $17, - $18, $19, $1A, $1B, $1C, $1D, $1E, $1F, - $20, $21, $22, $23, $24, $25, $26, $27, - $28, $29, $2A, $2B, - $00, $01, $02, $03, $04, $05, $06, $07, - $08, $09, $0A, $0B, $0C, $0D, $0E, $0F, - $10, $11, $14, $15, $17, $18, $19, $1B, - $1C, $1D, $1E, $1F, $20, $21, $24, $28, - $29, $2A, $2B, $2C, $2D, $30, $31, $33, - $34, $35, $00, $01, $02, $03, $04, $05, - $06, $09, $0B, $0D, $0E, $0F, $10, $11, - $12, $14, $15, $16, $18, $19, $1A, $1C, - $1D, $1E, $1F, $20, $21, $22, $25, $26, - $29, $2A, $2B, $2C, $2D, $2E, $30, $31, - $32, $33, $34, $35, - $00, $02, $03, $04, $05, $06, $07, $08, - $09, $0B, $0D, $0E, $0F, $10, $11, $12, - $13, $14, $17, $18, $1A, $1B, $1C, $1E, - $1F, $20, $21, $22, $23, $24, $27, $29, - $2B, $2C, $2D, $2E, $2F, $30, $32, $33, - $34, $35, $00, $01, $02, $03, $04, $05, - $06, $07, $08, $09, $0A, $0B, $0C, $0D, - $0E, $0F, $11, $12, $13, $14, $15, $16, - $17, $18, $19, $1A, $1B, $1C, $1D, $1E, - $1F, $20, $21, $22, $23, $24, $25, $26, - $27, $28, $29, $2A, - $00, $01, $02, $03, $04, $05, $06, $07, - $09, $0A, $0B, $0D, $0E, $0F, $10, $11, - $12, $13, $14, $15, $16, $17, $18, $19, - $1A, $1B, $1C, $1D, $1E, $1F, $20, $21, - $22, $23, $25, $26, $27, $29, $2A, $2B, - $2D, $2E, $00, $01, $02, $03, $04, $05, - $07, $09, $0A, $0B, $0C, $0D, $0E, $0F, - $10, $13, $14, $16, $17, $1A, $1C, $1D, - $1E, $1F, $20, $23, $25, $27, $28, $29, - $2A, $2B, $2C, $2E, $2F, $30, $31, $32, - $33, $34, $35, $36, - $00, $01, $02, $03, $04, $05, $06, $07, - $08, $09, $0A, $0C, $0D, $0E, $0F, $10, - $11, $12, $13, $14, $15, $16, $17, $18, - $19, $1A, $1B, $1C, $1D, $1E, $1F, $20, - $21, $22, $23, $24, $25, $26, $27, $28, - $29, $2A, $00, $01, $02, $04, $05, $06, - $08, $09, $0A, $0C, $0D, $0E, $0F, $10, - $11, $12, $14, $15, $17, $18, $19, $1A, - $1B, $1C, $1D, $1E, $20, $21, $22, $24, - $25, $26, $28, $29, $2A, $2B, $2C, $2D, - $2E, $30, $31, $33, - $00, $01, $02, $03, $04, $05, $07, $08, - $09, $0B, $0C, $0D, $0F, $10, $11, $12, - $13, $14, $15, $18, $1A, $1B, $1C, $1D, - $1E, $1F, $20, $21, $22, $23, $24, $25, - $26, $27, $28, $29, $2A, $2B, $2C, $2D, - $2E, $2F, $00, $01, $02, $03, $04, $05, - $06, $07, $08, $09, $0A, $0B, $0C, $0D, - $10, $11, $13, $14, $15, $17, $18, $19, - $1A, $1B, $1C, $1D, $20, $22, $24, $25, - $26, $27, $28, $29, $2C, $2D, $2F, $30, - $31, $33, $34, $35, - $00, $02, $03, $06, $08, $0A, $0B, $0C, - $0D, $0E, $0F, $12, $13, $15, $16, $17, - $19, $1A, $1B, $1C, $1D, $1E, $1F, $22, - $26, $27, $28, $29, $2A, $2B, $2D, $2E, - $2F, $30, $31, $32, $33, $34, $35, $36, - $37, $38, $00, $01, $02, $03, $04, $05, - $06, $07, $09, $0A, $0B, $0C, $0D, $0E, - $0F, $10, $11, $12, $13, $14, $15, $16, - $17, $18, $19, $1A, $1B, $1C, $1D, $1E, - $1F, $20, $21, $22, $23, $24, $25, $26, - $27, $28, $29, $2A, - $00, $01, $03, $04, $05, $07, $09, $0A, - $0B, $0C, $0D, $10, $12, $14, $15, $16, - $17, $18, $19, $1C, $1D, $1F, $20, $21, - $23, $24, $25, $26, $27, $28, $29, $2C, - $2E, $30, $31, $32, $33, $34, $35, $38, - $39, $3B, $00, $01, $03, $04, $05, $06, - $07, $08, $09, $0C, $10, $11, $12, $13, - $14, $15, $17, $18, $19, $1B, $1C, $1D, - $1F, $20, $21, $22, $23, $24, $25, $26, - $28, $29, $2A, $2B, $2C, $2D, $2E, $2F, - $30, $31, $34, $35, - $00, $01, $02, $04, $05, $06, $07, $09, - $0A, $0D, $0F, $11, $12, $13, $15, $16, - $19, $1A, $1C, $1D, $1E, $20, $21, $22, - $23, $24, $25, $26, $27, $28, $29, $2B, - $2D, $2E, $2F, $30, $31, $32, $35, $36, - $38, $39, $00, $01, $02, $03, $04, $05, - $06, $07, $08, $09, $0A, $0B, $0D, $0F, - $10, $11, $12, $13, $14, $17, $18, $1A, - $1B, $1C, $1E, $1F, $20, $21, $22, $23, - $24, $25, $27, $29, $2B, $2C, $2D, $2E, - $2F, $30, $32, $33, - $00, $02, $03, $04, $06, $07, $08, $09, - $0A, $0B, $0C, $0D, $0F, $11, $12, $13, - $14, $15, $16, $17, $18, $1B, $1C, $1E, - $1F, $20, $22, $23, $24, $25, $27, $28, - $2A, $2B, $2D, $2F, $30, $31, $32, $33, - $34, $36, $00, $01, $03, $04, $05, $07, - $08, $09, $0A, $0B, $0C, $0D, $0F, $10, - $11, $12, $14, $15, $16, $17, $18, $19, - $1C, $1D, $1F, $20, $21, $23, $24, $25, - $26, $27, $28, $29, $2A, $2B, $2C, $2D, - $2E, $30, $31, $32, - $00, $01, $02, $05, $06, $08, $09, $0A, - $0C, $0D, $0E, $0F, $10, $11, $12, $15, - $17, $19, $1A, $1B, $1C, $1D, $1E, $21, - $22, $24, $25, $26, $28, $29, $2A, $2B, - $2C, $2D, $2E, $30, $31, $33, $35, $36, - $37, $38, $00, $01, $04, $05, $07, $0C, - $0D, $0E, $0F, $10, $11, $14, $16, $18, - $19, $1A, $1C, $1D, $1F, $20, $21, $23, - $24, $25, $27, $28, $29, $2A, $2B, $2C, - $2D, $30, $31, $32, $34, $35, $36, $37, - $38, $39, $3C, $3D, - $00, $01, $02, $04, $05, $06, $07, $08, - $09, $0A, $0D, $0F, $11, $12, $13, $14, - $15, $16); - UHC_2_1Map: array[0..63] of Word = ( - $AC02, $AC8D, $AD14, $AD91, $ADFA, $AE7A, $AEE6, $AF57, - $AFBF, $B030, $B0A5, $B122, $B19E, $B207, $B26F, $B2F0, - $B366, $B3E1, $B445, $B4AD, $B51E, $B590, $B600, $B661, - $B6C3, $B723, $B79F, $B811, $B885, $B8F1, $B95A, $B9D4, - $BA47, $BAC2, $BB28, $BB9A, $BC03, $BC80, $BCFE, $BD67, - $BDD2, $BE3D, $BEB8, $BF23, $BF83, $BFE6, $C040, $C0A7, - $C132, $C1B1, $C224, $C297, $C310, $C37A, $C3DB, $C446, - $C4AA, $C50F, $C596, $C626, $C6A8, $C726, $C7B8, $C832); - UHC_2_2Map: array[0..5695] of Byte = ( - $00, $01, $03, $04, $09, $0A, $0B, $0C, - $0D, $16, $1C, $1D, $1F, $20, $21, $23, - $24, $25, $26, $27, $28, $29, $2C, $30, - $31, $32, $33, $34, $35, $38, $39, $3B, - $3C, $3D, $3F, $40, $41, $42, $43, $44, - $45, $46, $47, $48, $4A, $4C, $4D, $4E, - $4F, $50, $51, $53, $54, $55, $57, $58, - $59, $5B, $5C, $5D, $5E, $5F, $60, $61, - $62, $63, $64, $65, $66, $67, $68, $69, - $6A, $6B, $6C, $6D, $70, $71, $73, $74, - $77, $79, $7A, $7B, $7C, $7D, $80, $85, - $86, $00, $01, $02, $04, $05, $06, $08, - $09, $0A, $0B, $0C, $0D, $0E, $11, $15, - $16, $17, $18, $19, $1A, $1E, $20, $21, - $24, $25, $26, $27, $28, $29, $2A, $2D, - $31, $32, $33, $35, $36, $38, $39, $3A, - $3C, $3D, $3E, $40, $41, $42, $43, $44, - $45, $46, $47, $49, $4B, $4C, $4D, $4E, - $4F, $50, $51, $52, $55, $56, $58, $59, - $5C, $5E, $60, $61, $65, $67, $6A, $6B, - $6C, $6D, $6E, $71, $72, $74, $75, $76, - $78, $7A, $7B, $7C, $7D, $7E, $81, $83, - $85, $86, - $00, $01, $02, $03, $05, $06, $07, $09, - $0A, $0B, $0D, $0E, $0F, $10, $11, $12, - $13, $14, $16, $17, $1A, $1B, $1C, $1D, - $1E, $1F, $22, $23, $25, $26, $27, $29, - $2A, $2B, $2C, $2D, $2E, $2F, $32, $34, - $36, $37, $38, $39, $3A, $3B, $3D, $3E, - $3F, $41, $42, $43, $45, $46, $47, $48, - $49, $4A, $4B, $4C, $4E, $50, $51, $52, - $53, $54, $55, $56, $57, $5A, $5B, $5D, - $5E, $63, $64, $65, $66, $6A, $6C, $6F, - $70, $71, $72, $73, $76, $77, $79, $7A, - $7B, $00, $01, $02, $03, $04, $05, $06, - $07, $08, $09, $0A, $0D, $0E, $0F, $10, - $11, $12, $14, $15, $16, $17, $18, $19, - $1A, $1B, $1C, $1D, $1E, $1F, $20, $21, - $22, $23, $24, $25, $27, $28, $29, $2A, - $2B, $2C, $2D, $2E, $31, $32, $34, $35, - $36, $38, $39, $3A, $3B, $3C, $3D, $3E, - $41, $43, $44, $45, $46, $47, $48, $49, - $4A, $4C, $4D, $4E, $50, $51, $52, $54, - $55, $56, $57, $58, $59, $5A, $5B, $5C, - $5D, $5E, $5F, $60, $61, $62, $63, $64, - $65, $66, - $00, $01, $03, $04, $08, $09, $0A, $0B, - $0C, $0D, $10, $12, $14, $15, $16, $17, - $18, $19, $1B, $1C, $1D, $1E, $1F, $20, - $21, $22, $23, $24, $25, $26, $27, $28, - $29, $2A, $2B, $2C, $2D, $2E, $2F, $30, - $31, $32, $33, $34, $35, $38, $39, $3B, - $3C, $3F, $41, $42, $43, $44, $45, $48, - $4A, $4D, $4E, $4F, $51, $55, $57, $58, - $59, $5B, $5D, $5E, $5F, $60, $61, $64, - $68, $69, $6A, $6C, $6D, $70, $71, $73, - $74, $75, $77, $78, $79, $7A, $7B, $7C, - $7D, $00, $04, $05, $06, $07, $08, $09, - $0C, $0D, $0E, $0F, $10, $11, $13, $14, - $15, $16, $17, $18, $19, $1A, $1B, $1C, - $1D, $1E, $1F, $20, $21, $22, $23, $24, - $25, $26, $27, $28, $29, $2A, $2B, $2C, - $2D, $2E, $2F, $30, $31, $32, $33, $34, - $35, $36, $37, $38, $39, $3A, $3B, $3C, - $3D, $3E, $3F, $40, $41, $45, $47, $48, - $49, $4B, $4C, $4D, $4E, $4F, $50, $51, - $54, $58, $59, $5A, $5B, $5C, $5D, $60, - $61, $63, $64, $65, $66, $67, $68, $69, - $6A, $6B, - $00, $01, $03, $04, $06, $08, $09, $0A, - $0B, $0C, $0D, $0F, $10, $11, $13, $14, - $15, $17, $18, $19, $1A, $1B, $1C, $1D, - $1E, $1F, $20, $23, $24, $25, $26, $28, - $29, $2B, $2C, $2D, $2E, $2F, $30, $31, - $32, $33, $34, $35, $36, $37, $38, $39, - $3A, $3B, $3C, $3D, $3E, $3F, $40, $41, - $42, $43, $44, $45, $48, $49, $4B, $4D, - $4F, $50, $51, $52, $53, $54, $55, $58, - $5A, $5E, $5F, $60, $61, $64, $65, $66, - $67, $68, $69, $6B, $6C, $6D, $6E, $6F, - $70, $00, $01, $02, $03, $04, $07, $08, - $09, $0A, $0B, $0C, $0F, $10, $11, $12, - $13, $14, $15, $16, $17, $18, $19, $1A, - $1B, $1C, $1D, $1E, $1F, $20, $21, $23, - $24, $25, $26, $27, $28, $2A, $2B, $2C, - $2E, $2F, $30, $32, $33, $34, $35, $36, - $37, $38, $3B, $3C, $3D, $3F, $40, $41, - $42, $43, $44, $46, $47, $48, $49, $4A, - $4B, $4C, $4D, $4E, $4F, $50, $51, $52, - $53, $54, $55, $56, $57, $58, $59, $5A, - $5B, $5C, $5D, $5E, $5F, $60, $63, $64, - $66, $67, - $00, $02, $03, $04, $05, $06, $07, $0B, - $0D, $10, $11, $12, $13, $14, $16, $17, - $18, $19, $1A, $1B, $1C, $1E, $1F, $20, - $21, $22, $23, $24, $25, $26, $27, $28, - $2B, $2C, $2D, $2E, $2F, $30, $33, $34, - $36, $37, $38, $3A, $3B, $3C, $3D, $3E, - $3F, $40, $43, $44, $46, $47, $48, $49, - $4A, $4B, $4C, $4E, $4F, $50, $52, $53, - $54, $56, $57, $58, $59, $5A, $5B, $5C, - $5F, $60, $61, $62, $63, $64, $65, $66, - $67, $68, $6A, $6B, $6C, $6D, $6E, $6F, - $70, $00, $01, $02, $03, $04, $05, $06, - $07, $08, $09, $0A, $0B, $0C, $0D, $0E, - $0F, $10, $11, $12, $13, $16, $17, $19, - $1B, $1D, $1F, $20, $21, $22, $26, $28, - $2A, $2B, $2C, $2E, $2F, $30, $31, $32, - $33, $34, $35, $36, $37, $38, $39, $3A, - $3B, $3C, $3D, $3E, $3F, $40, $41, $42, - $43, $44, $45, $46, $47, $48, $49, $4A, - $4B, $4E, $4F, $51, $52, $53, $55, $56, - $57, $58, $59, $5A, $5B, $5E, $60, $62, - $63, $64, $65, $66, $67, $6B, $6D, $6E, - $73, $74, - $00, $01, $02, $05, $0B, $0D, $11, $12, - $14, $15, $16, $18, $19, $1A, $1B, $1C, - $1D, $1E, $21, $25, $26, $27, $28, $29, - $2A, $2D, $2E, $30, $31, $32, $34, $35, - $36, $37, $38, $39, $3A, $3C, $3D, $3E, - $3F, $41, $42, $43, $44, $45, $46, $47, - $48, $49, $4A, $4B, $4C, $4D, $4E, $4F, - $50, $51, $52, $53, $54, $55, $56, $57, - $58, $59, $5A, $5B, $5C, $5D, $5E, $5F, - $60, $61, $62, $65, $68, $69, $6A, $6C, - $6F, $70, $71, $72, $75, $79, $7A, $7B, - $7C, $00, $04, $05, $07, $08, $09, $0B, - $0C, $0D, $0E, $0F, $10, $11, $14, $18, - $19, $1A, $1B, $1C, $1D, $20, $21, $23, - $24, $25, $27, $28, $29, $2A, $2B, $2C, - $2D, $30, $31, $34, $35, $37, $38, $39, - $3B, $3C, $3D, $3F, $40, $41, $42, $43, - $44, $45, $46, $47, $48, $49, $4A, $4B, - $4C, $4D, $4E, $4F, $50, $51, $52, $53, - $54, $55, $58, $59, $5B, $5C, $5D, $5F, - $61, $62, $63, $64, $65, $68, $6A, $6C, - $6D, $6E, $6F, $73, $74, $75, $77, $78, - $79, $7B, - $00, $01, $02, $03, $04, $05, $06, $07, - $08, $09, $0B, $0C, $0D, $0E, $0F, $10, - $11, $12, $13, $14, $15, $16, $17, $18, - $19, $1A, $1B, $1C, $1D, $1E, $1F, $20, - $21, $22, $23, $24, $25, $26, $27, $28, - $29, $2A, $2B, $2C, $2D, $2F, $30, $31, - $33, $34, $35, $37, $38, $39, $3A, $3B, - $3C, $3D, $40, $42, $43, $44, $45, $46, - $47, $48, $49, $4C, $4D, $4F, $50, $51, - $53, $54, $55, $56, $57, $58, $59, $5A, - $5C, $5E, $60, $61, $62, $63, $64, $65, - $68, $00, $02, $03, $06, $07, $08, $09, - $0A, $0B, $0C, $0F, $11, $13, $14, $15, - $16, $17, $18, $1A, $1B, $1C, $1D, $1E, - $1F, $20, $21, $22, $23, $24, $25, $26, - $27, $28, $29, $2A, $2B, $2C, $2E, $2F, - $30, $31, $32, $33, $34, $36, $37, $38, - $39, $3A, $3B, $3C, $3D, $3E, $3F, $40, - $41, $42, $43, $44, $45, $46, $47, $48, - $49, $4A, $4B, $4C, $4D, $4E, $4F, $50, - $52, $53, $54, $56, $57, $58, $5A, $5B, - $5C, $5D, $5E, $5F, $60, $63, $64, $65, - $66, $67, - $00, $01, $02, $03, $04, $07, $08, $09, - $0A, $0B, $0C, $0E, $0F, $10, $11, $12, - $13, $14, $17, $18, $19, $1B, $1C, $1D, - $1E, $1F, $20, $23, $24, $26, $27, $28, - $2C, $2D, $2E, $2F, $30, $33, $35, $38, - $39, $3A, $3C, $3E, $3F, $40, $42, $43, - $44, $46, $47, $48, $49, $4A, $4B, $4C, - $4D, $4E, $4F, $50, $51, $52, $53, $54, - $55, $56, $57, $58, $5B, $5C, $5E, $5F, - $60, $62, $64, $65, $66, $67, $68, $6B, - $6D, $6F, $70, $71, $72, $74, $78, $7A, - $7B, $00, $01, $02, $06, $0C, $0D, $0E, - $12, $13, $15, $16, $17, $19, $1A, $1B, - $1C, $1D, $1E, $1F, $22, $26, $27, $28, - $29, $2A, $2B, $2D, $2E, $2F, $30, $31, - $32, $33, $34, $35, $36, $37, $38, $39, - $3A, $3B, $3C, $3D, $3E, $3F, $40, $41, - $42, $43, $44, $45, $46, $47, $48, $49, - $4A, $4B, $4C, $4D, $4E, $4F, $50, $51, - $52, $53, $54, $55, $56, $57, $58, $59, - $5A, $5B, $5C, $5D, $5E, $5F, $60, $61, - $62, $63, $67, $69, $6A, $6D, $70, $71, - $72, $73, - $00, $02, $04, $06, $07, $09, $0C, $0D, - $0F, $10, $11, $13, $14, $15, $16, $17, - $18, $19, $1C, $20, $21, $22, $23, $24, - $25, $27, $28, $29, $2B, $2C, $2D, $2F, - $30, $31, $32, $33, $34, $35, $36, $37, - $38, $39, $3C, $3D, $3E, $3F, $40, $41, - $43, $44, $45, $47, $48, $49, $4A, $4B, - $4C, $4D, $4E, $4F, $50, $51, $52, $53, - $54, $55, $56, $57, $58, $59, $5A, $5B, - $5C, $5D, $60, $61, $63, $64, $67, $69, - $6B, $6C, $6D, $70, $72, $74, $76, $78, - $79, $00, $01, $02, $04, $05, $06, $08, - $09, $0A, $0B, $0C, $0D, $0E, $0F, $10, - $11, $12, $13, $14, $15, $16, $17, $18, - $19, $1A, $1C, $1D, $1E, $1F, $20, $21, - $22, $23, $24, $25, $26, $27, $28, $29, - $2A, $2B, $2C, $2D, $2E, $30, $31, $32, - $33, $34, $35, $36, $38, $39, $3A, $3C, - $3D, $3E, $40, $41, $42, $43, $44, $45, - $46, $49, $4B, $4C, $4D, $4E, $4F, $50, - $51, $52, $54, $55, $56, $57, $58, $59, - $5A, $5B, $5C, $5D, $5E, $5F, $60, $61, - $62, $63, - $00, $01, $02, $03, $04, $05, $06, $07, - $08, $09, $0A, $0D, $0E, $10, $11, $12, - $14, $15, $16, $17, $18, $19, $1A, $1D, - $1F, $21, $22, $23, $24, $25, $26, $28, - $29, $2A, $2B, $2C, $2D, $2E, $2F, $30, - $31, $32, $33, $34, $35, $36, $37, $38, - $39, $3A, $3C, $3D, $3E, $3F, $40, $41, - $42, $44, $45, $46, $47, $48, $49, $4A, - $4B, $4C, $4D, $4E, $4F, $50, $51, $52, - $53, $54, $55, $56, $57, $59, $5A, $5B, - $5C, $5D, $5E, $60, $61, $62, $64, $65, - $66, $00, $01, $02, $03, $04, $05, $06, - $07, $09, $0B, $0D, $0E, $0F, $10, $11, - $12, $14, $15, $16, $18, $19, $1A, $1C, - $1D, $1E, $1F, $20, $21, $22, $24, $25, - $26, $27, $29, $2A, $2B, $2C, $2D, $2E, - $31, $32, $34, $35, $38, $3A, $3B, $3C, - $3D, $3E, $41, $43, $45, $46, $47, $48, - $49, $4A, $4C, $4D, $4E, $4F, $50, $51, - $52, $53, $54, $55, $56, $57, $58, $59, - $5A, $5B, $5C, $5D, $5E, $5F, $60, $61, - $62, $63, $64, $65, $66, $69, $6A, $6C, - $6D, $70, - $00, $01, $02, $03, $04, $05, $08, $0D, - $0E, $0F, $10, $11, $14, $15, $17, $18, - $19, $1B, $1C, $1D, $1E, $1F, $20, $21, - $24, $28, $29, $2A, $2B, $2C, $30, $31, - $33, $34, $35, $37, $38, $39, $3A, $3B, - $3C, $3D, $40, $44, $45, $46, $47, $48, - $49, $4A, $4B, $4C, $4D, $4E, $4F, $50, - $51, $52, $53, $54, $55, $56, $57, $58, - $59, $5A, $5B, $5C, $5D, $5E, $5F, $60, - $61, $62, $63, $64, $65, $66, $67, $68, - $69, $6A, $6B, $6C, $6D, $6E, $6F, $70, - $71, $00, $01, $02, $03, $04, $05, $06, - $07, $08, $09, $0A, $0B, $0C, $0D, $0E, - $0F, $12, $13, $15, $16, $17, $19, $1C, - $1D, $1E, $1F, $22, $26, $27, $28, $29, - $2A, $2E, $2F, $31, $32, $33, $35, $36, - $37, $38, $39, $3A, $3B, $3E, $42, $43, - $44, $45, $46, $47, $49, $4A, $4B, $4C, - $4D, $4E, $4F, $50, $51, $52, $53, $54, - $55, $56, $57, $58, $59, $5A, $5B, $5D, - $5E, $5F, $60, $61, $62, $63, $64, $65, - $66, $67, $68, $69, $6A, $6B, $6C, $6D, - $6E, $6F, - $00, $01, $02, $03, $04, $05, $06, $07, - $08, $09, $0A, $0B, $0C, $0D, $0E, $0F, - $12, $13, $15, $16, $17, $19, $1A, $1B, - $1C, $1D, $1E, $1F, $20, $21, $22, $23, - $24, $26, $27, $28, $29, $2A, $2B, $2D, - $2E, $2F, $30, $31, $32, $33, $35, $36, - $37, $38, $39, $3A, $3B, $3C, $3D, $3E, - $3F, $40, $41, $42, $43, $44, $45, $46, - $47, $49, $4A, $4B, $4C, $4D, $4E, $4F, - $50, $51, $52, $53, $54, $55, $56, $57, - $58, $59, $5A, $5B, $5C, $5D, $5E, $5F, - $60, $00, $01, $02, $04, $05, $06, $08, - $09, $0A, $0B, $0C, $0D, $0E, $0F, $10, - $11, $12, $13, $14, $15, $16, $17, $18, - $19, $1A, $1B, $1C, $1D, $1E, $1F, $20, - $21, $22, $23, $24, $25, $26, $27, $28, - $29, $2A, $2B, $2C, $2D, $2E, $2F, $30, - $31, $32, $33, $34, $35, $36, $37, $38, - $39, $3A, $3D, $3E, $40, $41, $42, $44, - $45, $46, $47, $48, $49, $4C, $4D, $4E, - $4F, $51, $52, $53, $54, $55, $56, $57, - $58, $59, $5A, $5B, $5C, $5D, $5E, $5F, - $60, $61, - $00, $01, $02, $03, $04, $05, $06, $07, - $08, $09, $0A, $0B, $0C, $0D, $0E, $0F, - $10, $12, $13, $14, $15, $16, $17, $18, - $19, $1A, $1B, $1C, $1D, $1E, $1F, $20, - $21, $22, $23, $24, $25, $26, $27, $28, - $29, $2A, $2B, $2C, $2E, $2F, $30, $32, - $33, $34, $36, $37, $38, $39, $3A, $3B, - $3C, $3F, $40, $41, $43, $44, $45, $46, - $47, $48, $49, $4A, $4B, $4C, $4D, $4E, - $4F, $50, $51, $52, $53, $54, $55, $56, - $57, $58, $59, $5A, $5B, $5C, $5D, $5E, - $5F, $00, $01, $02, $03, $04, $07, $08, - $0A, $0B, $0E, $0F, $10, $11, $12, $13, - $14, $17, $19, $1A, $1B, $1C, $1D, $1E, - $1F, $20, $22, $23, $24, $26, $27, $28, - $2A, $2B, $2C, $2D, $2E, $2F, $30, $33, - $34, $35, $36, $37, $38, $39, $3A, $3B, - $3C, $3E, $3F, $40, $42, $43, $44, $46, - $47, $48, $49, $4A, $4B, $4C, $4F, $51, - $53, $54, $55, $56, $57, $58, $5B, $5C, - $5E, $5F, $60, $62, $63, $64, $65, $66, - $67, $68, $6B, $70, $71, $72, $77, $78, - $7A, $7B, - $00, $02, $03, $04, $05, $06, $07, $08, - $0B, $0F, $10, $11, $12, $13, $14, $17, - $18, $1A, $1B, $1C, $1D, $1E, $1F, $20, - $21, $22, $23, $24, $25, $26, $27, $29, - $2B, $2C, $2D, $2E, $2F, $30, $31, $32, - $33, $34, $35, $36, $37, $38, $39, $3A, - $3B, $3C, $3D, $3E, $3F, $40, $41, $42, - $43, $44, $45, $46, $47, $48, $49, $4A, - $4B, $4C, $4F, $50, $52, $53, $54, $56, - $57, $58, $59, $5A, $5B, $5C, $5F, $63, - $64, $65, $66, $67, $6B, $6C, $6E, $6F, - $70, $00, $01, $02, $03, $04, $05, $06, - $09, $0B, $0D, $0E, $0F, $10, $11, $12, - $15, $16, $18, $19, $1A, $1C, $1D, $1E, - $1F, $20, $21, $22, $25, $29, $2A, $2B, - $2C, $2D, $2E, $30, $31, $32, $34, $35, - $36, $37, $38, $39, $3A, $3B, $3C, $3D, - $3E, $3F, $41, $43, $44, $45, $46, $47, - $48, $49, $4A, $4D, $4E, $50, $51, $52, - $54, $55, $56, $57, $58, $59, $5A, $5D, - $5F, $61, $62, $63, $64, $65, $66, $68, - $69, $6A, $6C, $6D, $6E, $6F, $70, $71, - $72, $73, - $00, $01, $02, $03, $04, $05, $06, $07, - $09, $0A, $0B, $0C, $0D, $0E, $0F, $10, - $11, $12, $13, $14, $15, $16, $17, $18, - $19, $1A, $1B, $1C, $1D, $1E, $1F, $20, - $21, $22, $24, $25, $26, $27, $28, $29, - $2A, $2C, $2D, $2E, $30, $31, $32, $34, - $35, $36, $37, $38, $39, $3A, $3D, $3F, - $41, $42, $43, $44, $45, $46, $48, $49, - $4A, $4C, $4D, $4E, $50, $51, $52, $53, - $54, $55, $56, $57, $59, $5B, $5D, $5E, - $5F, $60, $61, $62, $65, $66, $68, $69, - $6A, $00, $01, $02, $03, $04, $05, $06, - $09, $0B, $0D, $0E, $0F, $10, $11, $12, - $14, $15, $16, $17, $18, $19, $1A, $1B, - $1C, $1D, $1E, $1F, $20, $21, $22, $23, - $24, $25, $26, $28, $29, $2A, $2B, $2C, - $2D, $2E, $30, $31, $32, $33, $34, $35, - $36, $37, $38, $39, $3A, $3B, $3C, $3D, - $3E, $3F, $40, $41, $42, $43, $44, $45, - $46, $47, $48, $49, $4A, $4D, $4E, $50, - $51, $52, $54, $55, $56, $57, $58, $59, - $5A, $5C, $5D, $5F, $61, $62, $63, $64, - $65, $66, - $00, $01, $03, $04, $05, $07, $08, $09, - $0A, $0B, $0C, $0D, $10, $12, $14, $15, - $16, $17, $18, $19, $1C, $1D, $1F, $20, - $21, $23, $24, $25, $26, $27, $28, $29, - $2C, $2E, $31, $32, $35, $36, $37, $38, - $39, $3A, $3B, $3C, $3D, $3E, $3F, $40, - $41, $42, $43, $44, $45, $46, $47, $48, - $49, $4A, $4B, $4C, $4D, $4E, $4F, $50, - $51, $54, $55, $57, $58, $59, $5B, $5C, - $5D, $5E, $5F, $60, $61, $64, $66, $68, - $69, $6A, $6B, $6C, $6D, $70, $71, $73, - $79, $00, $01, $02, $03, $06, $08, $0B, - $0C, $0E, $12, $13, $15, $16, $17, $19, - $1A, $1B, $1C, $1D, $1E, $1F, $22, $27, - $28, $29, $2A, $2B, $2E, $2F, $30, $31, - $32, $33, $35, $36, $37, $38, $39, $3A, - $3B, $3C, $3D, $3E, $3F, $40, $42, $43, - $44, $45, $46, $47, $48, $49, $4A, $4B, - $4C, $4D, $4E, $4F, $50, $51, $52, $53, - $54, $55, $56, $57, $58, $59, $5A, $5B, - $5C, $5D, $5E, $5F, $60, $61, $62, $63, - $66, $67, $69, $6A, $6B, $6D, $6F, $70, - $71, $72, - $00, $03, $05, $08, $09, $0A, $0B, $0F, - $10, $12, $13, $14, $16, $17, $18, $19, - $1A, $1B, $1C, $1F, $23, $24, $25, $26, - $27, $28, $2B, $2C, $2E, $2F, $30, $32, - $33, $34, $35, $36, $37, $38, $39, $3A, - $3B, $3F, $41, $42, $43, $44, $46, $47, - $48, $49, $4A, $4B, $4C, $4D, $4E, $4F, - $50, $51, $52, $53, $54, $55, $56, $57, - $58, $59, $5A, $5B, $5C, $5D, $5E, $5F, - $60, $63, $66, $67, $68, $6A, $6C, $6D, - $6E, $6F, $70, $73, $75, $77, $78, $79, - $7A, $00, $01, $03, $04, $05, $07, $08, - $09, $0A, $0B, $0C, $0D, $0E, $0F, $10, - $11, $12, $13, $14, $15, $18, $19, $1A, - $1B, $1C, $1D, $1E, $1F, $20, $21, $22, - $23, $24, $25, $26, $27, $28, $29, $2A, - $2B, $2C, $2D, $2E, $2F, $30, $31, $32, - $33, $34, $35, $36, $37, $38, $39, $3B, - $3C, $3D, $3F, $40, $41, $43, $44, $45, - $46, $47, $48, $49, $4A, $4C, $4E, $50, - $51, $52, $53, $54, $55, $57, $58, $59, - $5B, $5C, $5D, $5F, $60, $61, $62, $63, - $64, $65, - $00, $02, $04, $05, $06, $07, $08, $09, - $0A, $0B, $0F, $11, $12, $17, $18, $19, - $1A, $1B, $1E, $20, $22, $23, $24, $26, - $29, $2A, $2B, $2D, $2E, $2F, $31, $32, - $33, $34, $35, $36, $37, $38, $3A, $3C, - $3D, $3E, $3F, $40, $41, $42, $43, $45, - $46, $47, $48, $49, $4A, $4B, $4C, $4D, - $4E, $4F, $50, $51, $52, $53, $54, $55, - $56, $57, $58, $59, $5A, $5B, $5C, $5D, - $5E, $5F, $61, $62, $63, $65, $66, $67, - $69, $6A, $6B, $6C, $6D, $6E, $6F, $70, - $71, $00, $01, $02, $03, $04, $05, $06, - $07, $08, $09, $0B, $0C, $0D, $0F, $10, - $11, $13, $14, $15, $16, $17, $18, $19, - $1B, $1C, $1E, $1F, $20, $21, $22, $23, - $24, $25, $27, $28, $29, $2B, $2C, $2D, - $2F, $30, $31, $32, $33, $34, $35, $37, - $38, $3A, $3B, $3C, $3D, $3E, $3F, $40, - $41, $42, $43, $44, $45, $46, $47, $48, - $49, $4A, $4B, $4C, $4D, $4E, $4F, $50, - $51, $52, $53, $54, $55, $56, $57, $58, - $59, $5A, $5B, $5C, $5D, $60, $61, $63, - $64, $67, - $00, $01, $02, $03, $04, $07, $0B, $0D, - $0F, $10, $16, $17, $1D, $1E, $1F, $20, - $23, $25, $27, $28, $29, $2B, $2C, $2F, - $30, $32, $33, $34, $36, $37, $38, $39, - $3A, $3B, $3C, $3F, $43, $44, $45, $47, - $48, $4B, $4C, $4E, $4F, $50, $51, $52, - $53, $54, $55, $56, $57, $58, $59, $5B, - $5C, $5D, $5E, $5F, $60, $61, $62, $63, - $64, $65, $66, $67, $68, $69, $6A, $6B, - $6C, $6D, $6E, $6F, $70, $71, $72, $73, - $74, $75, $76, $77, $78, $79, $7A, $7B, - $7C, $00, $01, $02, $03, $06, $07, $09, - $0A, $0D, $0F, $10, $11, $12, $13, $16, - $18, $1B, $1C, $1D, $1E, $1F, $22, $23, - $25, $26, $29, $2A, $2B, $2C, $2D, $2E, - $2F, $32, $36, $37, $38, $39, $3A, $3B, - $3E, $3F, $41, $42, $43, $45, $46, $47, - $48, $49, $4A, $4B, $4C, $4E, $52, $53, - $54, $56, $57, $59, $5A, $5B, $5D, $5E, - $5F, $60, $61, $62, $63, $64, $65, $66, - $67, $68, $69, $6A, $6B, $6C, $6D, $6E, - $6F, $70, $71, $72, $73, $77, $79, $7A, - $7B, $7D, - $00, $01, $02, $03, $04, $05, $08, $0A, - $0C, $0D, $0E, $0F, $10, $11, $13, $14, - $15, $17, $18, $19, $1A, $1B, $1C, $1D, - $1E, $1F, $20, $21, $22, $23, $24, $25, - $27, $28, $29, $2A, $2B, $2C, $2D, $2F, - $30, $31, $32, $33, $34, $35, $36, $37, - $38, $39, $3A, $3B, $3C, $3D, $3E, $3F, - $40, $41, $43, $44, $45, $46, $47, $48, - $49, $4C, $4D, $4F, $50, $51, $53, $54, - $55, $56, $57, $58, $59, $5C, $5D, $5E, - $5F, $60, $61, $62, $63, $64, $65, $67, - $68, $00, $02, $03, $04, $05, $06, $07, - $08, $09, $0A, $0B, $0C, $0D, $0E, $0F, - $10, $11, $12, $13, $14, $15, $16, $17, - $18, $1B, $1C, $1E, $1F, $24, $25, $26, - $27, $28, $2B, $2D, $2F, $30, $31, $34, - $36, $37, $38, $39, $3A, $3B, $3C, $3E, - $3F, $40, $41, $42, $43, $44, $45, $46, - $47, $48, $4A, $4B, $4C, $4D, $4E, $4F, - $50, $52, $53, $54, $55, $56, $57, $58, - $59, $5A, $5B, $5C, $5D, $5E, $5F, $60, - $61, $62, $63, $64, $65, $66, $67, $68, - $69, $6A, - $00, $01, $04, $05, $07, $08, $09, $0B, - $0C, $0D, $0E, $0F, $10, $11, $12, $13, - $14, $15, $16, $18, $19, $1A, $1B, $1C, - $1D, $1F, $20, $21, $23, $24, $25, $27, - $28, $29, $2A, $2B, $2C, $2D, $2F, $30, - $32, $34, $35, $36, $37, $38, $39, $3C, - $3D, $3F, $40, $41, $43, $44, $45, $46, - $47, $48, $49, $4C, $4E, $4F, $50, $51, - $52, $53, $54, $55, $56, $57, $58, $59, - $5A, $5B, $5C, $5D, $5E, $5F, $60, $61, - $62, $63, $64, $65, $66, $67, $68, $69, - $6A, $00, $01, $02, $03, $04, $05, $06, - $09, $0A, $0C, $0D, $0E, $10, $12, $13, - $14, $15, $16, $19, $1B, $1F, $20, $21, - $22, $25, $26, $28, $29, $2A, $2C, $2E, - $2F, $30, $31, $32, $35, $39, $3A, $3B, - $3C, $3D, $41, $42, $44, $45, $46, $48, - $49, $4A, $4B, $4C, $4D, $4E, $51, $55, - $56, $57, $58, $59, $5A, $5D, $5E, $5F, - $60, $61, $62, $63, $64, $65, $66, $67, - $68, $69, $6A, $6C, $6D, $6E, $6F, $70, - $71, $72, $73, $74, $75, $76, $77, $78, - $79, $7A, - $00, $01, $02, $03, $04, $05, $06, $07, - $08, $09, $0A, $0B, $0C, $0D, $0E, $0F, - $10, $11, $12, $13, $14, $15, $16, $17, - $1A, $1B, $1D, $1E, $21, $22, $23, $24, - $25, $26, $27, $29, $2A, $2E, $2F, $30, - $31, $32, $33, $35, $36, $37, $38, $39, - $3A, $3B, $3C, $3D, $3E, $3F, $40, $41, - $42, $43, $44, $45, $46, $47, $48, $4A, - $4B, $4C, $4D, $4E, $4F, $52, $53, $54, - $55, $56, $57, $58, $59, $5A, $5B, $5C, - $5D, $5E, $5F, $62, $66, $67, $68, $69, - $6A, $00, $01, $02, $03, $04, $05, $06, - $07, $08, $09, $0A, $0B, $0C, $0D, $0E, - $0F, $10, $11, $12, $13, $14, $15, $16, - $17, $18, $19, $1A, $1B, $1C, $1F, $20, - $22, $23, $24, $26, $27, $28, $29, $2A, - $2B, $2C, $2F, $30, $31, $33, $34, $35, - $36, $37, $38, $39, $3A, $3B, $3C, $3D, - $3E, $3F, $40, $41, $42, $43, $44, $45, - $46, $47, $48, $49, $4A, $4B, $4C, $4D, - $4E, $4F, $50, $51, $52, $53, $54, $55, - $56, $57, $58, $59, $5A, $5B, $5C, $5D, - $5E, $5F, - $00, $01, $02, $03, $04, $05, $06, $07, - $08, $09, $0A, $0B, $0C, $0D, $0E, $0F, - $10, $12, $13, $14, $15, $16, $17, $18, - $19, $1A, $1B, $1C, $1D, $1E, $1F, $20, - $21, $22, $23, $24, $25, $26, $27, $28, - $29, $2A, $2B, $2C, $2E, $2F, $30, $31, - $32, $33, $34, $35, $36, $37, $38, $39, - $3A, $3B, $3C, $3D, $3E, $3F, $40, $41, - $43, $44, $45, $46, $47, $48, $4B, $4C, - $4E, $4F, $50, $52, $53, $54, $55, $56, - $57, $58, $5A, $5B, $5D, $5F, $60, $61, - $62, $00, $01, $02, $03, $04, $05, $06, - $07, $08, $09, $0A, $0B, $0C, $0D, $0E, - $0F, $10, $11, $12, $13, $14, $15, $16, - $17, $18, $19, $1A, $1B, $1C, $1D, $1E, - $1F, $20, $21, $22, $23, $24, $25, $26, - $27, $28, $29, $2A, $2B, $2C, $2D, $2E, - $2F, $30, $31, $32, $33, $34, $35, $36, - $37, $38, $39, $3A, $3B, $3C, $3D, $3E, - $3F, $40, $41, $42, $43, $44, $45, $46, - $47, $48, $49, $4A, $4B, $4C, $4D, $4E, - $4F, $50, $51, $52, $53, $54, $55, $57, - $58, $59, - $00, $01, $02, $03, $04, $05, $06, $07, - $08, $09, $0A, $0B, $0C, $0D, $0E, $0F, - $10, $12, $13, $14, $15, $16, $17, $19, - $1A, $1B, $1D, $1E, $1F, $21, $22, $23, - $24, $25, $26, $27, $2A, $2B, $2C, $2D, - $2E, $2F, $30, $31, $32, $33, $34, $35, - $36, $37, $38, $39, $3A, $3B, $3C, $3D, - $3E, $3F, $40, $41, $42, $43, $44, $45, - $46, $47, $48, $49, $4A, $4B, $4C, $4D, - $4E, $4F, $52, $53, $55, $56, $57, $59, - $5A, $5B, $5C, $5D, $5E, $5F, $62, $64, - $66, $00, $01, $02, $03, $04, $07, $0A, - $0B, $10, $11, $12, $13, $14, $17, $1B, - $1C, $1D, $1F, $20, $23, $24, $26, $27, - $28, $2A, $2B, $2C, $2D, $2E, $2F, $30, - $33, $37, $38, $39, $3A, $3B, $3C, $3F, - $40, $42, $43, $44, $46, $47, $48, $49, - $4A, $4B, $4C, $4F, $51, $53, $54, $55, - $56, $57, $58, $5A, $5B, $5C, $5E, $5F, - $60, $62, $63, $64, $65, $66, $67, $68, - $6A, $6B, $6C, $6D, $6F, $70, $71, $72, - $73, $74, $7A, $7B, $7E, $81, $82, $83, - $84, $87, - $00, $01, $02, $03, $05, $08, $09, $0B, - $0C, $0D, $0F, $10, $11, $12, $13, $14, - $15, $18, $1C, $1D, $1E, $1F, $20, $21, - $24, $25, $27, $28, $29, $2B, $2C, $2D, - $2E, $2F, $30, $31, $34, $38, $39, $3A, - $3B, $3C, $3D, $3F, $40, $41, $43, $44, - $45, $47, $48, $49, $4A, $4B, $4C, $4D, - $4E, $4F, $50, $51, $52, $54, $55, $56, - $57, $58, $59, $5D, $5F, $60, $61, $63, - $65, $66, $67, $68, $69, $6C, $6E, $70, - $71, $72, $74, $75, $78, $79, $7B, $7C, - $7D, $00, $01, $02, $03, $04, $05, $06, - $07, $08, $09, $0A, $0B, $0D, $0E, $0F, - $10, $11, $12, $14, $15, $16, $18, $19, - $1A, $1C, $1D, $1E, $1F, $20, $21, $22, - $24, $25, $28, $29, $2A, $2B, $2C, $2D, - $2E, $30, $31, $32, $34, $35, $36, $38, - $39, $3A, $3B, $3C, $3D, $3E, $41, $43, - $44, $45, $46, $47, $48, $49, $4A, $4D, - $4E, $50, $51, $52, $54, $55, $56, $57, - $58, $59, $5A, $5D, $5F, $61, $62, $63, - $64, $65, $66, $69, $6A, $6C, $6D, $70, - $71, $72, - $00, $01, $02, $03, $06, $08, $0A, $0C, - $0F, $11, $12, $13, $14, $15, $16, $17, - $18, $19, $1A, $1B, $1C, $1D, $1E, $1F, - $20, $21, $22, $23, $25, $26, $27, $28, - $29, $2A, $2B, $2E, $2F, $31, $32, $33, - $35, $36, $37, $38, $39, $3A, $3B, $3D, - $3E, $3F, $40, $42, $43, $44, $45, $46, - $47, $4A, $4B, $4D, $4E, $4F, $51, $52, - $53, $54, $55, $56, $57, $5A, $5C, $5E, - $5F, $60, $61, $62, $63, $66, $67, $68, - $69, $6A, $6B, $6D, $6E, $6F, $70, $71, - $72, $00, $02, $03, $05, $07, $08, $09, - $0A, $0B, $0C, $0F, $10, $12, $13, $14, - $17, $18, $19, $1A, $1B, $1C, $1F, $21, - $23, $24, $25, $26, $27, $28, $29, $2A, - $2B, $2C, $2D, $2E, $2F, $30, $31, $32, - $33, $34, $35, $36, $37, $38, $39, $3A, - $3B, $3C, $3D, $3E, $3F, $40, $41, $42, - $43, $44, $47, $48, $4A, $4B, $4E, $4F, - $50, $51, $52, $53, $57, $59, $5B, $5C, - $5D, $5E, $60, $63, $66, $67, $68, $6A, - $6B, $6C, $6D, $6E, $6F, $70, $73, $74, - $77, $78, - $00, $01, $02, $06, $07, $09, $0A, $0B, - $0D, $0E, $0F, $10, $11, $12, $13, $16, - $17, $1A, $1B, $1C, $1D, $1E, $1F, $20, - $21, $22, $23, $24, $25, $26, $27, $28, - $29, $2A, $2B, $2C, $2D, $2E, $2F, $30, - $31, $32, $33, $34, $36, $37, $38, $39, - $3A, $3B, $3C, $3D, $3E, $3F, $40, $41, - $42, $43, $44, $45, $46, $47, $48, $49, - $4A, $4B, $4C, $4D, $4E, $4F, $50, $51, - $52, $53, $54, $55, $56, $57, $5A, $5B, - $5D, $5E, $5F, $61, $63, $64, $65, $66, - $67, $00, $01, $04, $05, $06, $07, $08, - $09, $0B, $0C, $0D, $0F, $10, $11, $13, - $14, $15, $16, $17, $18, $19, $1A, $1B, - $1C, $1D, $1E, $1F, $20, $21, $22, $23, - $24, $25, $26, $27, $28, $29, $2A, $2B, - $2C, $2D, $2E, $2F, $30, $31, $32, $33, - $34, $35, $36, $37, $38, $39, $3A, $3B, - $3C, $3D, $3E, $3F, $40, $41, $42, $43, - $44, $45, $47, $48, $49, $4A, $4B, $4C, - $4D, $4E, $4F, $50, $51, $52, $53, $54, - $55, $56, $57, $58, $59, $5A, $5B, $5C, - $5D, $60, - $00, $02, $03, $06, $08, $09, $0A, $0B, - $0C, $0F, $10, $11, $13, $14, $15, $16, - $17, $18, $1B, $1C, $1E, $1F, $20, $21, - $22, $23, $24, $25, $26, $27, $28, $29, - $2A, $2B, $2C, $2E, $2F, $30, $31, $32, - $33, $34, $36, $37, $38, $39, $3A, $3B, - $3C, $3D, $3E, $3F, $40, $41, $42, $43, - $44, $45, $46, $47, $48, $4A, $4B, $4C, - $4D, $4E, $4F, $50, $52, $53, $54, $56, - $57, $58, $5A, $5B, $5C, $5D, $5E, $5F, - $60, $63, $64, $65, $66, $67, $68, $69, - $6A, $00, $01, $03, $04, $05, $06, $07, - $08, $09, $0A, $0B, $0C, $0D, $0E, $0F, - $10, $11, $12, $13, $14, $15, $16, $17, - $18, $19, $1A, $1B, $1C, $1D, $20, $21, - $23, $24, $25, $27, $28, $29, $2A, $2B, - $2C, $2D, $30, $31, $32, $34, $35, $36, - $37, $38, $39, $3B, $3C, $3D, $3E, $3F, - $40, $41, $42, $43, $44, $45, $46, $47, - $48, $49, $4A, $4B, $4C, $4D, $4F, $50, - $51, $52, $53, $54, $55, $57, $58, $59, - $5A, $5B, $5C, $5D, $5E, $5F, $60, $61, - $62, $63, - $00, $01, $02, $03, $04, $05, $06, $07, - $08, $09, $0A, $0B, $0C, $0D, $0F, $10, - $11, $13, $14, $15, $16, $17, $18, $19, - $1A, $1B, $1C, $1D, $1E, $1F, $20, $21, - $22, $23, $24, $25, $26, $27, $28, $29, - $2A, $2B, $2C, $2D, $2E, $2F, $30, $31, - $32, $33, $34, $35, $36, $37, $38, $39, - $3A, $3B, $3C, $3D, $3E, $40, $41, $42, - $43, $44, $45, $48, $49, $4B, $4C, $4D, - $4F, $51, $52, $53, $54, $58, $59, $5A, - $5B, $5C, $5D, $5E, $5F, $60, $61, $63, - $64, $00, $02, $03, $04, $06, $07, $08, - $09, $0A, $0B, $0C, $0E, $0F, $10, $11, - $12, $13, $14, $15, $16, $17, $18, $1B, - $1C, $1E, $1F, $20, $22, $23, $24, $25, - $26, $27, $28, $2B, $2D, $2F, $30, $31, - $32, $33, $34, $37, $38, $3C, $40, $41, - $42, $43, $47, $4B, $4C, $4D, $50, $53, - $54, $56, $57, $58, $5A, $5B, $5C, $5D, - $5E, $5F, $60, $63, $67, $68, $69, $6A, - $6B, $6C, $6F, $70, $72, $73, $74, $76, - $77, $79, $7A, $7B, $7C, $7F, $81, $83, - $84, $85, - $00, $03, $04, $05, $07, $08, $09, $0B, - $0C, $0D, $0E, $0F, $10, $11, $12, $14, - $15, $16, $17, $18, $19, $1A, $1B, $1C, - $1D, $20, $21, $24, $29, $2A, $2B, $2C, - $2D, $35, $37, $39, $3C, $3D, $3F, $40, - $41, $43, $44, $45, $46, $47, $48, $49, - $4C, $4E, $50, $51, $52, $53, $54, $55, - $59, $5B, $5C, $5D, $5F, $62, $63, $64, - $65, $6C, $6D, $6E, $73, $74, $75, $77, - $78, $79, $7B, $7C, $7D, $7E, $7F, $80, - $81, $84, $87, $88, $89, $8A, $8B, $8C, - $8D, $00, $01, $03, $04, $05, $09, $0B, - $0C, $10, $12, $14, $16, $17, $18, $19, - $1C, $1D, $1F, $20, $21, $23, $24, $25, - $26, $27, $28, $29, $2C, $30, $31, $32, - $33, $34, $35, $38, $39, $3B, $3C, $3D, - $3E, $3F, $40, $41, $42, $43, $44, $45, - $47, $48, $4A, $4C, $4D, $4E, $4F, $50, - $51, $54, $55, $57, $58, $59, $5B, $5C, - $5D, $5E, $5F, $60, $61, $64, $66, $68, - $69, $6A, $6B, $6C, $6D, $70, $71, $73, - $74, $75, $77, $78, $79, $7A, $7B, $7C, - $7D, $80, - $00, $02, $03, $04, $05, $06, $07, $0A, - $0B, $0D, $0E, $0F, $13, $14, $15, $16, - $17, $1A, $1C, $1E, $1F, $20, $21, $22, - $23, $26, $27, $29, $2A, $2B, $2D, $2E, - $2F, $30, $31, $32, $33, $36, $37, $3A, - $3B, $3C, $3D, $3E, $3F, $42, $43, $45, - $46, $47, $49, $4A, $4B, $4C, $4D, $4E, - $4F, $52, $53, $54, $56, $57, $58, $59, - $5A, $5B, $5E, $5F, $61, $62, $63, $65, - $66, $67, $68, $69, $6A, $6B, $6E, $70, - $72, $73, $74, $75, $76, $77, $7A, $7B, - $7D, $00, $01, $03, $04, $05, $06, $07, - $08, $09, $0C, $0E, $10, $12, $13, $14, - $15, $18, $19, $1B, $1C, $1D, $1F, $20, - $21, $22, $23, $25, $28, $2A, $33, $34, - $35, $37, $38, $39, $3B, $3C, $3D, $3E, - $3F, $40, $41, $43, $44, $46, $47, $48, - $49, $4A, $4B, $4C, $4D, $50, $51, $53, - $54, $55, $59, $5A, $5B, $5C, $60, $65, - $66, $67, $69, $6C, $6D, $6F, $73, $75, - $76, $77, $78, $79, $7C, $81, $82, $83, - $84, $85, $88, $89, $8B, $8C, $8D, $8F, - $90, $91, - $00, $01, $02, $03, $06, $0A, $0B, $0C, - $0D, $0E, $0F, $12, $13, $15, $17, $19, - $1A, $1B, $1C, $1D, $1E, $1F, $21, $22, - $23, $24, $26, $27, $28, $29, $2A, $2B, - $2D, $2E, $2F, $31, $32, $33, $35, $36, - $37, $38, $39, $3A, $3B, $3C, $3D, $3E, - $3F, $40, $41, $42, $43, $44, $45, $46, - $47, $4A, $4B, $4D, $4E, $4F, $51, $53, - $54, $55, $56, $57, $5A, $5C, $5F, $60, - $61, $62, $63, $66, $67, $69, $6A, $6B, - $6D, $6E, $6F, $70, $71, $72, $73, $76, - $78, $00, $01, $02, $03, $04, $05, $07, - $08, $09, $0B, $0C, $0D, $0F, $10, $11, - $12, $13, $14, $15, $18, $19, $1C, $1D, - $1E, $1F, $20, $21, $23, $24, $25, $26, - $27, $28, $29, $2A, $2B, $2C, $2D, $2E, - $2F, $30, $31, $32, $33, $34, $35, $36, - $37, $38, $39, $3A, $3B, $3C, $3D, $40, - $41, $43, $44, $45, $47, $49, $4A, $4B, - $4C, $4D, $50, $52, $56, $57, $58, $5C, - $5D, $5E, $5F, $60, $61, $63, $64, $65, - $66, $67, $68, $69, $6A, $6C, $6E, $70, - $71, $72); - GB18030Ext_2uni_pagea9: array [0..12] of TBuffChar = ( - // $a9 - #$303e, #$2ff0, #$2ff1, #$2ff2, #$2ff3, #$2ff4, #$2ff5, #$2ff6, - #$2ff7, #$2ff8, #$2ff9, #$2ffa, #$2ffb - ); - GB18030Ext_2uni_pagefe: array[0..94] of TBuffChar = ( - // #$fe - #$fffd, #$fffd, #$fffd, #$fffd, #$fffd, #$fffd, #$fffd, #$fffd, - #$fffd, #$fffd, #$fffd, #$fffd, #$fffd, #$fffd, #$fffd, #$fffd, - #$2e81, #$fffd, #$fffd, #$fffd, #$2e84, #$3473, #$3447, #$2e88, - #$2e8b, #$fffd, #$359e, #$361a, #$360e, #$2e8c, #$2e97, #$396e, - #$3918, #$fffd, #$39cf, #$39df, #$3a73, #$39d0, #$fffd, #$fffd, - #$3b4e, #$3c6e, #$3ce0, #$2ea7, #$fffd, #$fffd, #$2eaa, #$4056, - #$415f, #$2eae, #$4337, #$2eb3, #$2eb6, #$2eb7, #$fffd, #$43b1, - #$43ac, #$2ebb, #$43dd, #$44d6, #$4661, #$464c, #$fffd, #$4723, - #$4729, #$477c, #$478d, #$2eca, #$4947, #$497a, #$497d, #$4982, - #$4983, #$4985, #$4986, #$499f, #$499b, #$49b7, #$49b6, #$fffd, - #$fffd, #$4ca3, #$4c9f, #$4ca0, #$4ca1, #$4c77, #$4ca2, #$4d13, - #$4d14, #$4d15, #$4d16, #$4d17, #$4d18, #$4d19, #$4dae - ); - GB18030Uni_ranges: array [0..193] of Integer = ( - 128, 129, 131, 133, 134, 135, 137, 140, - 142, 144, 145, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, - 168, 171, 172, 189, 196, 213, 220, 221, - 285, 286, 287, 291, 293, 295, 297, 298, - 300, 301, 302, 303, 304, 305, 306, 307, - 308, 320, 330, 334, 338, 339, 340, 341, - 342, 343, 347, 348, 349, 354, 355, 359, - 360, 361, 362, 363, 365, 369, 371, 372, - 373, 374, 375, 376, 386, 426, 502, 538, - 553, 556, 558, 560, 562, 564, 565, 567, - 571, 573, 574, 575, 576, 577, 578, 579, - 581, 582, 583, 584, 585, 586, 588, 589, - 590, 602, 606, 625, 627, 636, 637, 720, - 724, 810, 813, 850, 860, 861, 862, 864, - 867, 868, 869, 870, 872, 873, 874, 875, - 876, 877, 878, 879, 880, 882, 883, 884, - 885, 886, 887, 888, 889, 890, 891, 892, - 893, 894, 895, 896, 897, 898, 899, 900, - 901, 902, 903, 905, 907, 908, 909, 911, - 912, 917, 924, 925, 21827, 25943, 25944, 25945, - 25946, 25947, 25948, 25952, 25953, 25955, 25956, 25959, - 25961, 25964, 25966, 25984, 25994, 25998, 26012, 26016, - 26110, 26116 - ); - GB18030Uni_charset2uni_ranges: array[0..387] of Integer = ( - $0000, $0023, $0024, $0025, $0026, $002c, $002d, $0031, - $0032, $0050, $0051, $0058, $0059, $005e, $005f, $005f, - $0060, $0063, $0064, $0066, $0067, $0067, $0068, $0068, - $0069, $006c, $006d, $007d, $007e, $0084, $0085, $0093, - $0094, $00ab, $00ac, $00ae, $00af, $00b2, $00b3, $00cf, - $00d0, $0131, $0132, $0132, $0133, $0133, $0134, $0134, - $0135, $0135, $0136, $0136, $0137, $0137, $0138, $0138, - $0139, $0154, $0155, $01ab, $01ac, $01ba, $01bb, $021f, - $0220, $0220, $0221, $022d, $022e, $02e4, $02e5, $02e5, - $02e6, $02ec, $02ed, $02ed, $02ee, $0324, $0325, $0332, - $0333, $0333, $0334, $1ef1, $1ef2, $1ef3, $1ef4, $1ef4, - $1ef5, $1ef6, $1ef7, $1efd, $1efe, $1f06, $1f07, $1f07, - $1f08, $1f08, $1f09, $1f0d, $1f0e, $1f7d, $1f7e, $1fd3, - $1fd4, $1fd4, $1fd5, $1fd7, $1fd8, $1fe3, $1fe4, $1fed, - $1fee, $202b, $202c, $202f, $2030, $2045, $2046, $2047, - $2048, $20b5, $20b6, $20bb, $20bc, $20bc, $20bd, $20bf, - $20c0, $20c3, $20c4, $20c5, $20c6, $20c7, $20c8, $20c8, - $20c9, $20c9, $20ca, $20cb, $20cc, $20d0, $20d1, $20d5, - $20d6, $20df, $20e0, $20e2, $20e3, $20e7, $20e8, $20f4, - $20f5, $20f6, $20f7, $20fc, $20fd, $2121, $2122, $2124, - $2125, $212f, $2130, $2148, $2149, $219a, $219b, $22e7, - $22e8, $22f1, $22f2, $2355, $2356, $2359, $235a, $2366, - $2367, $2369, $236a, $2373, $2374, $2383, $2384, $238b, - $238c, $2393, $2394, $2396, $2397, $2398, $2399, $23aa, - $23ab, $23c9, $23ca, $23cb, $23cc, $2401, $2402, $2402, - $2403, $2c40, $2c41, $2c42, $2c43, $2c45, $2c46, $2c47, - $2c48, $2c51, $2c52, $2c60, $2c61, $2c62, $2c63, $2c65, - $2c66, $2c69, $2c6a, $2c6b, $2c6c, $2c6e, $2c6f, $2c7c, - $2c7d, $2da1, $2da2, $2da5, $2da6, $2da6, $2da7, $2dab, - $2dac, $2dad, $2dae, $2dc1, $2dc2, $2dc3, $2dc4, $2dca, - $2dcb, $2dcc, $2dcd, $2dd1, $2dd2, $2dd7, $2dd8, $2ecd, - $2ece, $2ed4, $2ed5, $2f45, $2f46, $302f, $3030, $303b, - $303c, $303d, $303e, $305f, $3060, $3068, $3069, $306a, - $306b, $306c, $306d, $30dd, $30de, $3108, $3109, $3232, - $3233, $32a1, $32a2, $32ac, $32ad, $35a9, $35aa, $35fe, - $35ff, $365e, $365f, $366c, $366d, $36ff, $3700, $37d9, - $37da, $38f8, $38f9, $3969, $396a, $3cde, $3cdf, $3de6, - $3de7, $3fbd, $3fbe, $4031, $4032, $4035, $4036, $4060, - $4061, $4158, $4159, $42cd, $42ce, $42e1, $42e2, $43a2, - $43a3, $43a7, $43a8, $43f9, $43fa, $4409, $440a, $45c2, - $45c3, $45f4, $45f5, $45f6, $45f7, $45fa, $45fb, $45fb, - $45fc, $460f, $4610, $4612, $4613, $4628, $4629, $48e7, - $48e8, $490e, $490f, $497d, $497e, $4a11, $4a12, $4a62, - $4a63, $82bc, $830e, $93d4, $93d5, $9420, $9421, $943b, - $943c, $948c, $948d, $9495, $9496, $94af, $94b0, $94b0, - $94b1, $94b1, $94b2, $94b4, $94b5, $94ba, $94bb, $94bb, - $94bc, $94bd, $94be, $98c3, $98c4, $98c4, $98c5, $98c8, - $98c9, $98c9, $98ca, $98ca, $98cb, $98cb, $98cc, $9960, - $9961, $99e1, $99e2, $99fb - ); - -implementation - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/DitherUnit.pas b/CORE/Source/Plugins/Htmlviewer/source/DitherUnit.pas deleted file mode 100644 index c3dd0a9b8..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/DitherUnit.pas +++ /dev/null @@ -1,1785 +0,0 @@ - -{***************************************************************} -{* DitherUnit.PAS *} -{* *} -{* Thanks to Anders Melander, anders@melander.dk, for the *} -{* color dithering code in this module. This code was *} -{* extracted from his excellent TGifImage.pas unit. *} -{* *} -{* *} -{* Bugs introduced by Dave Baldwin *} -{***************************************************************} - - -// Copyright (c) 1997,98 Anders Melander. // -// All rights reserved. // -// // -//////////////////////////////////////////////////////////////////////////////// -// // -// This software is copyrighted as noted above. It may be freely copied, // -// modified, and redistributed, provided that the copyright notice(s) is // -// preserved on all copies. // -// // -// TGIFImage is freeware and I would like it to remain so. This means that it // -// may not be bundled with commercial libraries or sold as shareware. You are // -// welcome to use it in commercial and shareware applications providing you // -// do not charge for the functionality provided by TGIFImage. // -// If you are in doubt, please contact me and I will explain this. // -// // -// There is no warranty or other guarantee of fitness for this software, it // -// is provided solely "as is". Bug reports or fixes may be sent to the // -// author, who may or may not act on them as he desires. // -// // -// If you redistribute this code in binary form (i.e. as a library or linked // -// into an application), the accompanying documentation should state that // -// "this software is based, in part, on the work of Anders Melander" or words // -// to that effect. // -// // -// If you modify this software, you should include a notice in the revision // -// history in the history.txt file giving the date and the name of the person // -// performing the modification and a brief description of the modification. // -// // - -unit DitherUnit; - -{$I htmlcons.inc} - -interface - -{$ifNdef LCL} - {$DEFINE PIXELFORMAT_TOO_SLOW} -{$endif} - -//////////////////////////////////////////////////////////////////////////////// -// -// Determine Delphi and C++ Builder version -// -//////////////////////////////////////////////////////////////////////////////// - -// Delphi 2.x -{$IFDEF VER90} -Error: This module not used with Delphi 2 -{$ENDIF} - -// Delphi 3.x -{$IFDEF VER100} -{$DEFINE VER10x} -{$ENDIF} - -// C++ Builder 3.x -{$IFDEF VER110} -{$DEFINE VER10x} -{$DEFINE VER11_PLUS} -{$DEFINE D4_BCB3} -{$ENDIF} - -// Delphi 4.x -{$IFDEF VER120} -{$DEFINE VER10x} -{$DEFINE VER11_PLUS} -{$DEFINE D4_BCB3} -{$ENDIF} - -{$IFDEF Ver130} {Delphi 5} -{$DEFINE VER10x} -{$DEFINE VER11_PLUS} -{$DEFINE D4_BCB3} -{$ENDIF} - -{$IFDEF ver125} {C++Builder 4} -{$DEFINE VER11_PLUS} -{$DEFINE D4_BCB3} -{$ENDIF} - -//////////////////////////////////////////////////////////////////////////////// -// -// External dependecies -// -//////////////////////////////////////////////////////////////////////////////// -uses -{$ifdef LCL} - LclIntf, LclType, //LMessages, -{$else} - Windows, -{$endif} - SysUtils, vcl.Graphics, Classes, HtmlGlobals; - -function GetBitmap(Source: TPersistent): ThtBitmap; {LDB} - -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -// -// Implementation -// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -implementation - -{$if defined(DEBUG) or defined(DEBUG_DITHERPERFORMANCE)} -uses -{$ifend} -{$IFDEF DEBUG} - vcl.dialogs -{$ENDIF} -//BG, 01.09.2009: ifdef added: -{$IFDEF DEBUG_DITHERPERFORMANCE} - mmsystem, // timeGetTime() - messages -{$ENDIF} -{$if defined(DEBUG) or defined(DEBUG_DITHERPERFORMANCE)} - ; -{$ifend} - -//////////////////////////////////////////////////////////////////////////////// -// -// Error messages -// -//////////////////////////////////////////////////////////////////////////////// -resourcestring - // GIF Error messages - //BG, 01.09.2009: unused: sOutOfData = 'Premature end of data'; -{$IFDEF PIXELFORMAT_TOO_SLOW} - sOutOfMemDIB = 'Failed to allocate memory for GIF DIB'; - sDIBCreate = 'Failed to create DIB from Bitmap'; - sNoDIB = 'Image has no DIB'; - SScanLine = 'Scan line index out of range'; -{$ENDIF PIXELFORMAT_TOO_SLOW} - sInvalidBitmap = 'Bitmap image is not valid'; - SInvalidPixelFormat = 'Invalid pixel format'; - -//////////////////////////////////////////////////////////////////////////////// -// -// Misc constants and support types -// -//////////////////////////////////////////////////////////////////////////////// -type - // TGIFImage mostly throws exceptions of type GIFException - GIFException = class(EInvalidGraphic); - - // Color reduction methods - TColorReduction = - (rmNone, // Do not perform color reduction - rmWindows20, // Reduce to the Windows 20 color system palette - rmWindows256, // Reduce to the Windows 256 color halftone palette (Only works in 256 color display mode) - rmNetscape, // Reduce to the Netscape 216 color palette - rmMyPalette, - rmQuantizeWindows // Reduce to optimal 256 color windows palette - ); - TDitherMode = - (dmNearest, // Nearest color matching w/o error correction - dmFloydSteinberg // Floyd Steinberg Error Diffusion dithering - // dmOrdered, // Ordered dither - // dmCustom // Custom palette - ); - -//////////////////////////////////////////////////////////////////////////////// -// -// Utility routines -// -//////////////////////////////////////////////////////////////////////////////// -// // WebPalette creates a 216 color uniform palette a.k.a. the Netscape Palette -// function WebPalette: HPalette; -// -// // ReduceColors -// // Map colors in a bitmap to their nearest representation in a palette using -// // the methods specified by the ColorReduction and DitherMode parameters. -// // The ReductionBits parameter specifies the desired number of colors (bits -// // per pixel) when the reduction method is rmQuantize. -// function ReduceColors(Bitmap: TBitmap; ColorReduction: TColorReduction; -// DitherMode: TDitherMode): TBitmap; - -function WebPalette: HPalette; -type - TLogWebPalette = packed record - palVersion: word; - palNumEntries: word; - PalEntries: array[0..5, 0..5, 0..5] of TPaletteEntry; - end; -var - r, g, b: byte; - LogWebPalette: TLogWebPalette; - LogPalette: TLogpalette absolute LogWebPalette; // Stupid typecast -begin - with LogWebPalette do - begin - palVersion := $0300; - palNumEntries := 216; - for r := 0 to 5 do - for g := 0 to 5 do - for b := 0 to 5 do - begin - with PalEntries[r, g, b] do - begin - peRed := 51 * r; - peGreen := 51 * g; - peBlue := 51 * b; - peFlags := 0; - end; - end; - end; - Result := CreatePalette(Logpalette); -end; - -(* -** Raise error condition -*) - -procedure Error(msg: string); - - function ReturnAddr: Pointer; -{$ifdef LCL} - begin - Result := nil; // ToDo: Fix it. Why is there assy? -{$else} - asm // From classes.pas - MOV EAX,[EBP+4] // sysutils.pas says [EBP-4] ! -{$endif} - end; - -begin - raise GIFException.Create(msg) at ReturnAddr; -end; - -// Round to arbitrary number of bits - -function AlignBit(Bits, BitsPerPixel, Alignment: Cardinal): Cardinal; -begin - Dec(Alignment); - Result := ((Bits * BitsPerPixel) + Alignment) and not Alignment; - Result := Result shr 3; -end; - -//type -// TPixelFormats = set of TPixelFormat; - -// -------------------------- -// InitializeBitmapInfoHeader -// -------------------------- -// Fills a TBitmapInfoHeader with the values of a bitmap when converted to a -// DIB of a specified PixelFormat. -// -// Parameters: -// Bitmap The handle of the source bitmap. -// Info The TBitmapInfoHeader buffer that will receive the values. -// PixelFormat The pixel format of the destination DIB. -// -{$IFDEF D4_BCB3} - // Disable optimization to circumvent D4/BCB3 optimizer bug -{$IFOPT O+} -{$DEFINE O_PLUS} -{$O-} -{$ENDIF} -{$ENDIF} - -procedure InitializeBitmapInfoHeader(Bitmap: HBITMAP; var Info: TBitmapInfoHeader; - PixelFormat: TPixelFormat); -// From graphics.pas, "optimized" for our use -var - DIB: TDIBSection; - Bytes: Integer; -begin - FillChar(DIB, sizeof(DIB), 0); - Bytes := GetObject(Bitmap, SizeOf(DIB), @DIB); - if (Bytes = 0) then - Error(sInvalidBitmap); - - if (Bytes >= (sizeof(DIB.dsbm) + sizeof(DIB.dsbmih))) and - (DIB.dsbmih.biSize >= sizeof(DIB.dsbmih)) then - Info := DIB.dsbmih - else - begin - FillChar(Info, sizeof(Info), 0); - with Info, DIB.dsbm do - begin - biSize := SizeOf(Info); - biWidth := bmWidth; - biHeight := bmHeight; - end; - end; - case PixelFormat of - pf1bit: Info.biBitCount := 1; - pf4bit: Info.biBitCount := 4; - pf8bit: Info.biBitCount := 8; - pf24bit: Info.biBitCount := 24; - else - Error(sInvalidPixelFormat); - // Info.biBitCount := DIB.dsbm.bmBitsPixel * DIB.dsbm.bmPlanes; - end; - Info.biPlanes := 1; - Info.biSizeImage := AlignBit(Info.biWidth, Info.biBitCount, 32) * Cardinal(abs(Info.biHeight)); -end; -{$IFDEF O_PLUS} -{$O+} -{$UNDEF O_PLUS} -{$ENDIF} - -// ------------------- -// InternalGetDIBSizes -// ------------------- -// Calculates the buffer sizes nescessary for convertion of a bitmap to a DIB -// of a specified PixelFormat. -// See the GetDIBSizes API function for more info. -// -// Parameters: -// Bitmap The handle of the source bitmap. -// InfoHeaderSize -// The returned size of a buffer that will receive the DIB's -// TBitmapInfo structure. -// ImageSize The returned size of a buffer that will receive the DIB's -// pixel data. -// PixelFormat The pixel format of the destination DIB. -// - -procedure InternalGetDIBSizes(Bitmap: HBITMAP; var InfoHeaderSize: Integer; - var ImageSize: longInt; PixelFormat: TPixelFormat); -// From graphics.pas, "optimized" for our use -var - Info: TBitmapInfoHeader; -begin - InitializeBitmapInfoHeader(Bitmap, Info, PixelFormat); - // Check for palette device format - if (Info.biBitCount > 8) then - begin - // Header but no palette - InfoHeaderSize := SizeOf(TBitmapInfoHeader); - if ((Info.biCompression and BI_BITFIELDS) <> 0) then - Inc(InfoHeaderSize, 12); - end - else - // Header and palette - InfoHeaderSize := SizeOf(TBitmapInfoHeader) + SizeOf(TRGBQuad) * (1 shl Info.biBitCount); - ImageSize := Info.biSizeImage; -end; - -// -------------- -// InternalGetDIB -// -------------- -// Converts a bitmap to a DIB of a specified PixelFormat. -// -// Parameters: -// Bitmap The handle of the source bitmap. -// Pal The handle of the source palette. -// BitmapInfo The buffer that will receive the DIB's TBitmapInfo structure. -// A buffer of sufficient size must have been allocated prior to -// calling this function. -// Bits The buffer that will receive the DIB's pixel data. -// A buffer of sufficient size must have been allocated prior to -// calling this function. -// PixelFormat The pixel format of the destination DIB. -// -// Returns: -// True on success, False on failure. -// -// Note: The InternalGetDIBSizes function can be used to calculate the -// nescessary sizes of the BitmapInfo and Bits buffers. -// - -function InternalGetDIB(Bitmap: HBITMAP; Palette: HPALETTE; - var BitmapInfo; var Bits; PixelFormat: TPixelFormat): Boolean; -// From graphics.pas, "optimized" for our use -var - OldPal: HPALETTE; - DC: HDC; -begin - InitializeBitmapInfoHeader(Bitmap, TBitmapInfoHeader(BitmapInfo), PixelFormat); - OldPal := 0; - DC := CreateCompatibleDC(0); - try - if (Palette <> 0) then - begin - OldPal := SelectPalette(DC, Palette, False); - RealizePalette(DC); - end; - Result := (GetDIBits(DC, Bitmap, 0, abs(TBitmapInfoHeader(BitmapInfo).biHeight), - @Bits, TBitmapInfo(BitmapInfo), DIB_RGB_COLORS) <> 0); - finally - if (OldPal <> 0) then - SelectPalette(DC, OldPal, False); - DeleteDC(DC); - end; -end; - -// -------------- -// GetPixelFormat -// -------------- -// Returns the current pixel format of a bitmap. -// -// Replacement for delphi 3 TBitmap.PixelFormat getter. -// -// Parameters: -// Bitmap The bitmap which pixel format is returned. -// -// Returns: -// The PixelFormat of the bitmap -// - -function GetPixelFormat(Bitmap: TBitmap): TPixelFormat; -begin - Result := Bitmap.PixelFormat; -end; - -// -------------- -// SetPixelFormat -// -------------- -// Changes the pixel format of a TBitmap. -// -// Replacement for delphi 3 TBitmap.PixelFormat setter. -// The returned TBitmap will always be a DIB. -// -// Note: Under Delphi 3.x this function will leak a palette handle each time it -// converts a TBitmap to pf8bit format! -// If possible, use SafeSetPixelFormat instead to avoid this. -// -// Parameters: -// Bitmap The bitmap to modify. -// PixelFormat The pixel format to convert to. -// - -procedure SetPixelFormat(Bitmap: TBitmap; PixelFormat: TPixelFormat); -begin - Bitmap.PixelFormat := PixelFormat; -end; - -// ------------------ -// SafeSetPixelFormat -// ------------------ -// Changes the pixel format of a TBitmap but doesn't preserve the contents. -// -// Replacement for delphi 3 TBitmap.PixelFormat setter. -// The returned TBitmap will always be an empty DIB of the same size as the -// original bitmap. -// -// This function is used to avoid the palette handle leak that SetPixelFormat -// and TBitmap.PixelFormat suffers from. -// -// Parameters: -// Bitmap The bitmap to modify. -// PixelFormat The pixel format to convert to. - -{$IFDEF VER11_PLUS} - -procedure SafeSetPixelFormat(Bitmap: TBitmap; PixelFormat: TPixelFormat); -begin - Bitmap.PixelFormat := PixelFormat; -end; -{$ELSE} - -var - pf8BitBitmap: TBitmap = nil; - -procedure SafeSetPixelFormat(Bitmap: TBitmap; PixelFormat: TPixelFormat); -var - Width, - Height: integer; -begin - if (PixelFormat = pf8bit) then - begin - // Solution to "TBitmap.PixelFormat := pf8bit" leak by Greg Chapman - if (pf8BitBitmap = nil) then - begin - // Create a "template" bitmap - // The bitmap is deleted in the finalization section of the unit. - pf8BitBitmap := TBitmap.Create; - // Convert template to pf8bit format - // This will leak 1 palette handle, but only once - pf8BitBitmap.PixelFormat := pf8Bit; - end; - // Store the size of the original bitmap - Width := Bitmap.Width; - Height := Bitmap.Height; - // Convert to pf8bit format by copying template - Bitmap.Assign(pf8BitBitmap); - // Restore the original size - Bitmap.Width := Width; - Bitmap.Height := Height; - end - else - // This is safe since only pf8bit leaks - Bitmap.PixelFormat := PixelFormat; -end; -{$ENDIF} - - -//////////////////////////////////////////////////////////////////////////////// -// -// TDIB Class -// -// These classes gives read and write access to TBitmap's pixel data -// independantly of the Delphi version used. -// -//////////////////////////////////////////////////////////////////////////////// -type - TDIB = class(TObject) - private - FBitmap: TBitmap; - FPixelFormat: TPixelFormat; - function GetScanline(Row: integer): pointer; virtual; abstract; - public - constructor Create(ABitmap: TBitmap; APixelFormat: TPixelFormat); virtual; - property Scanline[Row: integer]: pointer read GetScanline; - property Bitmap: TBitmap read FBitmap; - end; - - TDIBReader = class(TDIB) - protected - function GetScanline(Row: integer): pointer; override; - public - constructor Create(ABitmap: TBitmap; APixelFormat: TPixelFormat); override; - destructor Destroy; override; - end; - - TDIBWriter = class(TDIB) - private -{$IFDEF PIXELFORMAT_TOO_SLOW} - FDIBInfo: PBitmapInfo; - FDIBBits: pointer; - FDIBInfoSize: integer; - FDIBBitsSize: longInt; -{$ENDIF} - protected - procedure CreateDIB; - procedure FreeDIB; - procedure NeedDIB; - function GetScanline(Row: integer): pointer; override; - public - constructor Create(ABitmap: TBitmap; APixelFormat: TPixelFormat); override; - destructor Destroy; override; - procedure UpdateBitmap; - end; - -//////////////////////////////////////////////////////////////////////////////// - -constructor TDIB.Create(ABitmap: TBitmap; APixelFormat: TPixelFormat); -begin - inherited Create; - FBitmap := ABitmap; - FPixelFormat := APixelFormat; -end; - -//////////////////////////////////////////////////////////////////////////////// - -constructor TDIBReader.Create(ABitmap: TBitmap; APixelFormat: TPixelFormat); -begin - inherited Create(ABitmap, APixelFormat); - SetPixelFormat(FBitmap, FPixelFormat); -end; - -destructor TDIBReader.Destroy; -begin - inherited Destroy; -end; - -function TDIBReader.GetScanline(Row: integer): pointer; -begin -{$ifdef FPC_TODO} - Result := nil; -{$else} - Result := FBitmap.ScanLine[Row]; -{$endif} -end; - -//////////////////////////////////////////////////////////////////////////////// - -constructor TDIBWriter.Create(ABitmap: TBitmap; APixelFormat: TPixelFormat); -{$IFNDEF PIXELFORMAT_TOO_SLOW} -var - SavePalette: HPalette; -{$ENDIF} -begin - inherited Create(ABitmap, APixelFormat); -{$IFNDEF PIXELFORMAT_TOO_SLOW} - SavePalette := FBitmap.ReleasePalette; - try - SafeSetPixelFormat(FBitmap, FPixelFormat); - finally - FBitmap.Palette := SavePalette; - end; -{$ELSE PIXELFORMAT_TOO_SLOW} - FDIBInfo := nil; - FDIBBits := nil; -{$ENDIF PIXELFORMAT_TOO_SLOW} -end; - -destructor TDIBWriter.Destroy; -begin - UpdateBitmap; - FreeDIB; - inherited Destroy; -end; - -function TDIBWriter.GetScanline(Row: integer): pointer; -begin -{$IFDEF PIXELFORMAT_TOO_SLOW} - NeedDIB; - - if (FDIBBits = nil) then - Error(sNoDIB); - with FDIBInfo^.bmiHeader do - begin - if (Row < 0) or (Row >= FBitmap.Height) then - raise EInvalidGraphicOperation.Create(SScanLine); - GDIFlush; - - if biHeight > 0 then // bottom-up DIB - Row := biHeight - Row - 1; - Result := PByte(Cardinal(FDIBBits) + Cardinal(Row) * AlignBit(biWidth, biBitCount, 32)); - end; -{$ELSE PIXELFORMAT_TOO_SLOW} -{$ifdef LCL} - Result := nil; // ToDo: Find replacement of FBitmap.ScanLine for LCL -{$else LCL} - Result := FBitmap.ScanLine[Row]; -{$endif LCL} -{$ENDIF PIXELFORMAT_TOO_SLOW} -end; - -procedure TDIBWriter.CreateDIB; -{$IFDEF PIXELFORMAT_TOO_SLOW} -var - SrcColors, - DstColors: WORD; - - procedure ByteSwapColors(var Colors; Count: Integer); - // convert RGB to BGR and vice-versa. TRGBQuad <-> TPaletteEntry -{$IFDEF WIN32} - // From Delphi 3.02 graphics.pas - // There is a bug in the ByteSwapColors from Delphi 3.0 - var - SysInfo: TSystemInfo; - begin - GetSystemInfo(SysInfo); - asm - MOV EDX, Colors - MOV ECX, Count - DEC ECX - JS @@END - LEA EAX, SysInfo - CMP [EAX].TSystemInfo.wProcessorLevel, 3 - JE @@386 - @@1: MOV EAX, [EDX+ECX*4] - BSWAP EAX - SHR EAX,8 - MOV [EDX+ECX*4],EAX - DEC ECX - JNS @@1 - JMP @@END - @@386: - PUSH EBX - @@2: XOR EBX,EBX - MOV EAX, [EDX+ECX*4] - MOV BH, AL - MOV BL, AH - SHR EAX,16 - SHL EBX,8 - MOV BL, AL - MOV [EDX+ECX*4],EBX - DEC ECX - JNS @@2 - POP EBX - @@END: - end; -{$ENDIF WIN32} -{$IFDEF WIN64} - // From Delphi XE2 Vcl.Graphics unit - // Copyright(c) 1995-2011 Embarcadero Technologies, Inc. - var - C: PDWORD; - Color: DWORD; - I: Integer; - begin - C := @Colors; - I := 0; - while I < Count do - begin - Color := C^; - C^ := (Byte(Color shr 16) or (Word(Color) shr 8) shl 8) or - (Byte(Word(Color)) shl 16); - Inc(I); - Inc(C); - end; -{$ENDIF WIN64} - end; -{$ENDIF PIXELFORMAT_TOO_SLOW} -begin -{$IFDEF PIXELFORMAT_TOO_SLOW} - if (FBitmap.Handle = 0) then - Error(sInvalidBitmap); - - FreeDIB; - - // Get header- and pixel data size - InternalGetDIBSizes(FBitmap.Handle, FDIBInfoSize, FDIBBitsSize, FPixelFormat); - - // Allocate TBitmapInfo structure - GetMem(FDIBInfo, FDIBInfoSize); - try - // Allocate pixel buffer - FDIBBits := GlobalAllocPtr(GMEM_MOVEABLE, FDIBBitsSize); - if (FDIBBits = nil) then - raise EOutOfMemory.Create(sOutOfMemDIB); - // Get pixel data - if not (InternalGetDIB(FBitmap.Handle, FBitmap.Palette, FDIBInfo^, FDIBBits^, FPixelFormat)) then - Error(sDIBCreate); - - if (FPixelFormat <= pf8bit) then - begin - // Find number of colors defined by palette - if (FBitmap.Palette = 0) or - (GetObject(FBitmap.Palette, sizeof(SrcColors), @SrcColors) = 0) or - (SrcColors = 0) then - exit; - // Determine how many colors there are room for in DIB header - DstColors := FDIBInfo^.bmiHeader.biClrUsed; - if (DstColors = 0) then - DstColors := 1 shl FDIBInfo^.bmiHeader.biBitCount; - // Don't copy any more colors than there are room for - if (DstColors <> 0) and (DstColors < SrcColors) then - SrcColors := DstColors; - - // Copy all colors... - GetPaletteEntries(FBitmap.Palette, 0, SrcColors, FDIBInfo^.bmiColors[0]); - // ...and convert BGR to RGB - ByteSwapColors(FDIBInfo^.bmiColors[0], SrcColors); - - // Finally zero any unused entried - if (SrcColors < DstColors) then - FillChar(pointer(LongInt(@FDIBInfo^.bmiColors) + SizeOf(TRGBQuad) * SrcColors)^, - DstColors - SrcColors, 0); - end; - - except - FreeDIB; - raise; - end; -{$ENDIF PIXELFORMAT_TOO_SLOW} -end; - -procedure TDIBWriter.FreeDIB; -begin -{$IFDEF PIXELFORMAT_TOO_SLOW} - if (FDIBInfo <> nil) then - FreeMem(FDIBInfo); - if (FDIBBits <> nil) then - GlobalFreePtr(FDIBBits); - FDIBInfo := nil; - FDIBBits := nil; -{$ENDIF} -end; - -procedure TDIBWriter.NeedDIB; -begin -{$IFDEF PIXELFORMAT_TOO_SLOW} - if (FDIBBits = nil) then - CreateDIB; -{$ENDIF} -end; - -// Convert the DIB created by CreateDIB back to a TBitmap - -procedure TDIBWriter.UpdateBitmap; -{$IFDEF PIXELFORMAT_TOO_SLOW} -var - Stream: TMemoryStream; - FileSize: longInt; - BitmapFileHeader: TBitmapFileHeader; -{$ENDIF} -begin -{$IFDEF PIXELFORMAT_TOO_SLOW} - if (FDIBInfo = nil) or (FDIBBits = nil) then - exit; - Stream := TMemoryStream.Create; - try - // Make room in stream for a TBitmapInfo and pixel data - FileSize := sizeof(TBitmapFileHeader) + FDIBInfoSize + FDIBBitsSize; - Stream.SetSize(FileSize); - // Initialize file header - FillChar(BitmapFileHeader, sizeof(TBitmapFileHeader), 0); - with BitmapFileHeader do - begin - bfType := $4D42; // 'BM' = Windows BMP signature - bfSize := FileSize; // File size (not needed) - bfOffBits := sizeof(TBitmapFileHeader) + FDIBInfoSize; // Offset of pixel data - end; - // Save file header - Stream.Write(BitmapFileHeader, sizeof(TBitmapFileHeader)); - // Save TBitmapInfo structure - Stream.Write(FDIBInfo^, FDIBInfoSize); - // Save pixel data - Stream.Write(FDIBBits^, FDIBBitsSize); - - // Rewind and load DIB into bitmap - Stream.Position := 0; - FBitmap.LoadFromStream(Stream); - finally - Stream.Free; - end; -{$ENDIF} -end; - -//////////////////////////////////////////////////////////////////////////////// -// -// Color Mapping -// -//////////////////////////////////////////////////////////////////////////////// -type - TColorLookup = class(TObject) - private - FColors: integer; - function Lookup(Red, Green, Blue: BYTE; var R, G, B: BYTE): Byte; virtual; abstract; - public - constructor Create(Palette: hPalette); virtual; - property Colors: integer read FColors; - end; - - //PRGBQuadArray = ^TRGBQuadArray; // From Delphi 3 graphics.pas - TRGBQuadArray = array[Byte] of TRGBQuad; // From Delphi 3 graphics.pas - - //BGRArray = array[0..0] of TRGBTriple; - //PBGRArray = ^BGRArray; - - ThtPalArray = array[byte] of TPaletteEntry; - PhtPalArray = ^ThtPalArray; - - // TFastColorLookup implements a simple but reasonably fast generic color - // mapper. It trades precision for speed by reducing the size of the color - // space. - // Using a class instead of inline code results in a speed penalty of - // approx. 15% but reduces the complexity of the color reduction routines that - // uses it. If bitmap to GIF conversion speed is really important to you, the - // implementation can easily be inlined again. - TInverseLookup = array[0..1 shl 15 - 1] of SmallInt; - PInverseLookup = ^TInverseLookup; - - TFastColorLookup = class(TColorLookup) - private - FPaletteEntries: PhtPalArray; - FInverseLookup: PInverseLookup; - public - constructor Create(Palette: hPalette); override; - destructor Destroy; override; - function Lookup(Red, Green, Blue: BYTE; var R, G, B: BYTE): Byte; override; - end; - - // TNetscapeColorLookup maps colors to the netscape 6*6*6 color cube. - TNetscapeColorLookup = class(TColorLookup) - public - constructor Create(Palette: hPalette); override; - function Lookup(Red, Green, Blue: BYTE; var R, G, B: BYTE): Byte; override; - end; - -constructor TColorLookup.Create(Palette: hPalette); -begin - inherited Create; -end; - -constructor TFastColorLookup.Create(Palette: hPalette); -var - i: integer; - InverseIndex: integer; -begin - inherited Create(Palette); - - GetMem(FPaletteEntries, sizeof(TPaletteEntry) * 256); - FColors := GetPaletteEntries(Palette, 0, 256, FPaletteEntries^); - - New(FInverseLookup); - for i := low(TInverseLookup) to high(TInverseLookup) do - FInverseLookup^[i] := -1; - - // Premap palette colors - if (FColors > 0) then - for i := 0 to FColors - 1 do - with FPaletteEntries^[i] do - begin - InverseIndex := (peRed shr 3) or ((peGreen and $F8) shl 2) or ((peBlue and $F8) shl 7); - if (FInverseLookup^[InverseIndex] = -1) then - FInverseLookup^[InverseIndex] := i; - end; -end; - -destructor TFastColorLookup.Destroy; -begin - if (FPaletteEntries <> nil) then - FreeMem(FPaletteEntries); - if (FInverseLookup <> nil) then - Dispose(FInverseLookup); - - inherited Destroy; -end; - -// Map color to arbitrary palette - -function TFastColorLookup.Lookup(Red, Green, Blue: BYTE; var R, G, B: BYTE): Byte; -var - i: integer; - InverseIndex: integer; - Delta, - MinDelta, - MinColor: integer; -begin - // Reduce color space with 3 bits in each dimension - InverseIndex := (Red shr 3) or ((Green and $F8) shl 2) or ((Blue and $F8) shl 7); - - if (FInverseLookup^[InverseIndex] <> -1) then - Result := Byte(FInverseLookup^[InverseIndex]) - else - begin - // Sequential scan for nearest color to minimize euclidian distance - MinDelta := 3 * (256 * 256); - MinColor := 0; - for i := 0 to FColors - 1 do - with FPaletteEntries[i] do - begin - Delta := ABS(peRed - Red) + ABS(peGreen - Green) + ABS(peBlue - Blue); - if (Delta < MinDelta) then - begin - MinDelta := Delta; - MinColor := i; - end; - end; - Result := Byte(MinColor); - FInverseLookup^[InverseIndex] := MinColor; - end; - - with FPaletteEntries^[ord(Result)] do - begin - R := peRed; - G := peGreen; - B := peBlue; - end; -end; - -constructor TNetscapeColorLookup.Create(Palette: hPalette); -begin - inherited Create(Palette); - FColors := 6 * 6 * 6; // This better be true or something is wrong -end; - -// Map color to netscape 6*6*6 color cube - -function TNetscapeColorLookup.Lookup(Red, Green, Blue: BYTE; var R, G, B: BYTE): Byte; -begin - R := (Red + 3) div 51; - G := (Green + 3) div 51; - B := (Blue + 3) div 51; - Result := Byte(B + 6 * G + 36 * R); - R := R * 51; - G := G * 51; - B := B * 51; -end; - - -//////////////////////////////////////////////////////////////////////////////// -// -// Dithering engine -// -//////////////////////////////////////////////////////////////////////////////// -type - TDitherEngine = class - protected - FDirection: integer; - FColumn: integer; - FLookup: TColorLookup; - Width: integer; - public - constructor Create(AWidth: integer; Lookup: TColorLookup); virtual; - function Dither(Red, Green, Blue: BYTE; var R, G, B: BYTE): Byte; virtual; - procedure NextLine; virtual; - - property Direction: integer read FDirection; - property Column: integer read FColumn; - end; - - // Note: TErrorTerm does only *need* to be 16 bits wide, but since - // it is *much* faster to use native machine words (32 bit), we sacrifice - // some bytes (a lot actually) to improve performance. - TErrorTerm = Integer; - TErrors = array[0..0] of TErrorTerm; - PErrors = ^TErrors; - - TFloydSteinbergEngine = class(TDitherEngine) - private - ErrorsR, - ErrorsG, - ErrorsB: PErrors; - ErrorR, - ErrorG, - ErrorB: PErrors; - CurrentErrorR, // Current error or pixel value - CurrentErrorG, - CurrentErrorB, - BelowErrorR, // Error for pixel below current - BelowErrorG, - BelowErrorB, - BelowPrevErrorR, // Error for pixel below previous pixel - BelowPrevErrorG, - BelowPrevErrorB: TErrorTerm; - - public - constructor Create(AWidth: integer; Lookup: TColorLookup); override; - destructor Destroy; override; - function Dither(Red, Green, Blue: BYTE; var R, G, B: BYTE): Byte; override; - procedure NextLine; override; - end; - -constructor TDitherEngine.Create(AWidth: integer; Lookup: TColorLookup); -begin - inherited Create; - - FLookup := Lookup; - Width := AWidth; - - FDirection := 1; - FColumn := 0; -end; - -function TDitherEngine.Dither(Red, Green, Blue: BYTE; var R, G, B: BYTE): Byte; -begin - // Map color to palette - Result := FLookup.Lookup(Red, Green, Blue, R, G, B); - inc(FColumn, FDirection); -end; - -procedure TDitherEngine.NextLine; -begin - FDirection := -FDirection; - if (FDirection = 1) then - FColumn := 0 - else - FColumn := Width - 1; -end; - -constructor TFloydSteinbergEngine.Create(AWidth: integer; Lookup: TColorLookup); -begin - inherited Create(AWidth, Lookup); - - // The Error arrays has (columns + 2) entries; the extra entry at - // each end saves us from special-casing the first and last pixels. - // We can get away with a single array (holding one row's worth of errors) - // by using it to store the current row's errors at pixel columns not yet - // processed, but the next row's errors at columns already processed. We - // need only a few extra variables to hold the errors immediately around the - // current column. (If we are lucky, those variables are in registers, but - // even if not, they're probably cheaper to access than array elements are.) - GetMem(ErrorsR, sizeof(TErrorTerm) * (Width + 2)); - GetMem(ErrorsG, sizeof(TErrorTerm) * (Width + 2)); - GetMem(ErrorsB, sizeof(TErrorTerm) * (Width + 2)); - FillChar(ErrorsR^, sizeof(TErrorTerm) * (Width + 2), 0); - FillChar(ErrorsG^, sizeof(TErrorTerm) * (Width + 2), 0); - FillChar(ErrorsB^, sizeof(TErrorTerm) * (Width + 2), 0); - ErrorR := ErrorsR; - ErrorG := ErrorsG; - ErrorB := ErrorsB; - CurrentErrorR := 0; - CurrentErrorG := CurrentErrorR; - CurrentErrorB := CurrentErrorR; - BelowErrorR := CurrentErrorR; - BelowErrorG := CurrentErrorR; - BelowErrorB := CurrentErrorR; - BelowPrevErrorR := CurrentErrorR; - BelowPrevErrorG := CurrentErrorR; - BelowPrevErrorB := CurrentErrorR; -end; - -destructor TFloydSteinbergEngine.Destroy; -begin - FreeMem(ErrorsR); - FreeMem(ErrorsG); - FreeMem(ErrorsB); - inherited Destroy; -end; - -{$IFOPT R+} -{$DEFINE R_PLUS} -{$RANGECHECKS OFF} -{$ENDIF} - -function TFloydSteinbergEngine.Dither(Red, Green, Blue: BYTE; var R, G, B: BYTE): Byte; -var - BelowNextError: TErrorTerm; - Delta: TErrorTerm; -begin - CurrentErrorR := Red + (CurrentErrorR + ErrorR[FDirection] + 8) div 16; - if (CurrentErrorR < 0) then - CurrentErrorR := 0 - else if (CurrentErrorR > 255) then - CurrentErrorR := 255; - - CurrentErrorG := Green + (CurrentErrorG + ErrorG[FDirection] + 8) div 16; - if (CurrentErrorG < 0) then - CurrentErrorG := 0 - else if (CurrentErrorG > 255) then - CurrentErrorG := 255; - - CurrentErrorB := Blue + (CurrentErrorB + ErrorB[FDirection] + 8) div 16; - if (CurrentErrorB < 0) then - CurrentErrorB := 0 - else if (CurrentErrorB > 255) then - CurrentErrorB := 255; - - // Map color to palette - Result := inherited Dither(CurrentErrorR, CurrentErrorG, CurrentErrorB, R, G, B); - - // Propagate Floyd-Steinberg error terms. - // Errors are accumulated into the error arrays, at a resolution of - // 1/16th of a pixel count. The error at a given pixel is propagated - // to its not-yet-processed neighbors using the standard F-S fractions, - // ... (here) 7/16 - // 3/16 5/16 1/16 - // We work left-to-right on even rows, right-to-left on odd rows. - - // Red component - CurrentErrorR := CurrentErrorR - R; - BelowNextError := CurrentErrorR; // Error * 1 - - Delta := CurrentErrorR * 2; - CurrentErrorR := CurrentErrorR + Delta; - ErrorR[0] := BelowPrevErrorR + CurrentErrorR; // Error * 3 - - CurrentErrorR := CurrentErrorR + Delta; - BelowPrevErrorR := BelowErrorR + CurrentErrorR; // Error * 5 - - BelowErrorR := BelowNextError; // Error * 1 - - CurrentErrorR := CurrentErrorR + Delta; // Error * 7 - - // Green component - CurrentErrorG := CurrentErrorG - G; - BelowNextError := CurrentErrorG; // Error * 1 - - Delta := CurrentErrorG * 2; - CurrentErrorG := CurrentErrorG + Delta; - ErrorG[0] := BelowPrevErrorG + CurrentErrorG; // Error * 3 - - CurrentErrorG := CurrentErrorG + Delta; - BelowPrevErrorG := BelowErrorG + CurrentErrorG; // Error * 5 - - BelowErrorG := BelowNextError; // Error * 1 - - CurrentErrorG := CurrentErrorG + Delta; // Error * 7 - - // Blue component - CurrentErrorB := CurrentErrorB - B; - BelowNextError := CurrentErrorB; // Error * 1 - - Delta := CurrentErrorB * 2; - CurrentErrorB := CurrentErrorB + Delta; - ErrorB[0] := BelowPrevErrorB + CurrentErrorB; // Error * 3 - - CurrentErrorB := CurrentErrorB + Delta; - BelowPrevErrorB := BelowErrorB + CurrentErrorB; // Error * 5 - - BelowErrorB := BelowNextError; // Error * 1 - - CurrentErrorB := CurrentErrorB + Delta; // Error * 7 - - // Move on to next column - if (FDirection = 1) then - begin - inc(ErrorR); - inc(ErrorG); - inc(ErrorB); - end - else - begin - dec(ErrorR); - dec(ErrorG); - dec(ErrorB); - end; -end; -{$IFDEF R_PLUS} -{$RANGECHECKS ON} -{$UNDEF R_PLUS} -{$ENDIF} - -{$IFOPT R+} -{$DEFINE R_PLUS} -{$RANGECHECKS OFF} -{$ENDIF} - -procedure TFloydSteinbergEngine.NextLine; -begin - ErrorR[0] := BelowPrevErrorR; - ErrorG[0] := BelowPrevErrorG; - ErrorB[0] := BelowPrevErrorB; - - // Note: The optimizer produces better code for this construct: - // a := 0; b := a; c := a; - // compared to this construct: - // a := 0; b := 0; c := 0; - CurrentErrorR := 0; - CurrentErrorG := CurrentErrorR; - CurrentErrorB := CurrentErrorG; - BelowErrorR := CurrentErrorG; - BelowErrorG := CurrentErrorG; - BelowErrorB := CurrentErrorG; - BelowPrevErrorR := CurrentErrorG; - BelowPrevErrorG := CurrentErrorG; - BelowPrevErrorB := CurrentErrorG; - - inherited NextLine; - - if (FDirection = 1) then - begin - ErrorR := ErrorsR; - ErrorG := ErrorsG; - ErrorB := ErrorsB; - end - else - begin - ErrorR := @ErrorsR[Width + 1]; - ErrorG := @ErrorsG[Width + 1]; - ErrorB := @ErrorsB[Width + 1]; - end; -end; -{$IFDEF R_PLUS} -{$RANGECHECKS ON} -{$UNDEF R_PLUS} -{$ENDIF} - -//////////////////////////////////////////////////////////////////////////////// -// -// Octree Color Quantization Engine -// -//////////////////////////////////////////////////////////////////////////////// -// Adapted from Earl F. Glynn's ColorQuantizationLibrary, March 1998 -//////////////////////////////////////////////////////////////////////////////// -type - TOctreeNode = class; // Forward definition so TReducibleNodes can be declared - - TReducibleNodes = array[0..7] of TOctreeNode; - - TOctreeNode = class(TObject) - public - IsLeaf: Boolean; - PixelCount: integer; - RedSum: integer; - GreenSum: integer; - BlueSum: integer; - Next: TOctreeNode; - Child: TReducibleNodes; - - constructor Create(Level: integer; ColorBits: integer; var LeafCount: integer; - var ReducibleNodes: TReducibleNodes); - destructor Destroy; override; - end; - - TColorQuantizer = class(TObject) - private - FTree: TOctreeNode; - FLeafCount: integer; - FReducibleNodes: TReducibleNodes; - FMaxColors: integer; - FColorBits: integer; - - protected - procedure AddColor(var Node: TOctreeNode; r, g, b: byte; ColorBits: integer; - Level: integer; var LeafCount: integer; var ReducibleNodes: TReducibleNodes); - procedure DeleteTree(var Node: TOctreeNode); - procedure GetPaletteColors(const Node: TOctreeNode; - var RGBQuadArray: TRGBQuadArray; var Index: integer); - procedure ReduceTree(ColorBits: integer; var LeafCount: integer; - var ReducibleNodes: TReducibleNodes); - - public - constructor Create(MaxColors: integer; ColorBits: integer); - destructor Destroy; override; - - procedure GetColorTable(var RGBQuadArray: TRGBQuadArray); - function ProcessImage(const DIB: TDIBReader): boolean; - - property ColorCount: integer read FLeafCount; - end; - -constructor TOctreeNode.Create(Level: integer; ColorBits: integer; - var LeafCount: integer; var ReducibleNodes: TReducibleNodes); -var - i: integer; -begin - PixelCount := 0; - RedSum := 0; - GreenSum := 0; - BlueSum := 0; - for i := Low(Child) to High(Child) do - Child[i] := nil; - - IsLeaf := (Level = ColorBits); - if (IsLeaf) then - begin - Next := nil; - inc(LeafCount); - end - else - begin - Next := ReducibleNodes[Level]; - ReducibleNodes[Level] := self; - end; -end; - -destructor TOctreeNode.Destroy; -var - i: integer; -begin - for i := High(Child) downto Low(Child) do - Child[i].Free; -end; - -constructor TColorQuantizer.Create(MaxColors: integer; ColorBits: integer); -var - i: integer; -begin - ASSERT(ColorBits <= 8, 'ColorBits must be 8 or less'); - - FTree := nil; - FLeafCount := 0; - - // Initialize all nodes even though only ColorBits+1 of them are needed - for i := Low(FReducibleNodes) to High(FReducibleNodes) do - FReducibleNodes[i] := nil; - - FMaxColors := MaxColors; - FColorBits := ColorBits; -end; - -destructor TColorQuantizer.Destroy; -begin - if (FTree <> nil) then - DeleteTree(FTree); -end; - -procedure TColorQuantizer.GetColorTable(var RGBQuadArray: TRGBQuadArray); -var - Index: integer; -begin - Index := 0; - GetPaletteColors(FTree, RGBQuadArray, Index); -end; - -// Handles passed to ProcessImage should refer to DIB sections, not DDBs. -// In certain cases, specifically when it's called upon to process 1, 4, or -// 8-bit per pixel images on systems with palettized display adapters, -// ProcessImage can produce incorrect results if it's passed a handle to a -// DDB. - -function TColorQuantizer.ProcessImage(const DIB: TDIBReader): boolean; -var - i, - j: integer; - ScanLine: pointer; - Pixel: PRGBTriple; -begin - Result := True; - - for j := 0 to DIB.Bitmap.Height - 1 do - begin - Scanline := DIB.Scanline[j]; - Pixel := ScanLine; - for i := 0 to DIB.Bitmap.Width - 1 do - begin - with Pixel^ do - AddColor(FTree, rgbtRed, rgbtGreen, rgbtBlue, - FColorBits, 0, FLeafCount, FReducibleNodes); - - while FLeafCount > FMaxColors do - ReduceTree(FColorbits, FLeafCount, FReducibleNodes); - inc(Pixel); - end; - end; -end; - -procedure TColorQuantizer.AddColor(var Node: TOctreeNode; r, g, b: byte; - ColorBits: integer; Level: integer; var LeafCount: integer; - var ReducibleNodes: TReducibleNodes); -const - Mask: array[0..7] of BYTE = ($80, $40, $20, $10, $08, $04, $02, $01); -var - Index: integer; - Shift: integer; -begin - // If the node doesn't exist, create it. - if (Node = nil) then - Node := TOctreeNode.Create(Level, ColorBits, LeafCount, ReducibleNodes); - - if (Node.IsLeaf) then - begin - inc(Node.PixelCount); - inc(Node.RedSum, r); - inc(Node.GreenSum, g); - inc(Node.BlueSum, b); - end - else - begin - // Recurse a level deeper if the node is not a leaf. - Shift := 7 - Level; - - Index := (((r and mask[Level]) shr Shift) shl 2) or - (((g and mask[Level]) shr Shift) shl 1) or - ((b and mask[Level]) shr Shift); - AddColor(Node.Child[Index], r, g, b, ColorBits, Level + 1, LeafCount, ReducibleNodes); - end; -end; - -procedure TColorQuantizer.DeleteTree(var Node: TOctreeNode); -var - i: integer; -begin - for i := High(TReducibleNodes) downto Low(TReducibleNodes) do - if (Node.Child[i] <> nil) then - DeleteTree(Node.Child[i]); - - Node.Free; - Node := nil; -end; - -procedure TColorQuantizer.GetPaletteColors(const Node: TOctreeNode; - var RGBQuadArray: TRGBQuadArray; var Index: integer); -var - i: integer; -begin - if (Node.IsLeaf) then - begin - with RGBQuadArray[Index] do - begin - if (Node.PixelCount <> 0) then - begin - rgbRed := BYTE(Node.RedSum div Node.PixelCount); - rgbGreen := BYTE(Node.GreenSum div Node.PixelCount); - rgbBlue := BYTE(Node.BlueSum div Node.PixelCount); - end - else - begin - rgbRed := 0; - rgbGreen := 0; - rgbBlue := 0; - end; - rgbReserved := 0; - end; - inc(Index); - end - else - begin - for i := Low(Node.Child) to High(Node.Child) do - if (Node.Child[i] <> nil) then - GetPaletteColors(Node.Child[i], RGBQuadArray, Index); - end; -end; - -procedure TColorQuantizer.ReduceTree(ColorBits: integer; var LeafCount: integer; - var ReducibleNodes: TReducibleNodes); -var - RedSum, - GreenSum, - BlueSum: integer; - Children: integer; - i: integer; - Node: TOctreeNode; -begin - // Find the deepest level containing at least one reducible node - i := Colorbits - 1; - while (i > 0) and (ReducibleNodes[i] = nil) do - dec(i); - - // Reduce the node most recently added to the list at level i. - Node := ReducibleNodes[i]; - ReducibleNodes[i] := Node.Next; - - RedSum := 0; - GreenSum := 0; - BlueSum := 0; - Children := 0; - - for i := Low(ReducibleNodes) to High(ReducibleNodes) do - if (Node.Child[i] <> nil) then - begin - inc(RedSum, Node.Child[i].RedSum); - inc(GreenSum, Node.Child[i].GreenSum); - inc(BlueSum, Node.Child[i].BlueSum); - inc(Node.PixelCount, Node.Child[i].PixelCount); - Node.Child[i].Free; - Node.Child[i] := nil; - inc(Children); - end; - - Node.IsLeaf := TRUE; - Node.RedSum := RedSum; - Node.GreenSum := GreenSum; - Node.BlueSum := BlueSum; - dec(LeafCount, Children - 1); -end; - -//////////////////////////////////////////////////////////////////////////////// -// -// Octree Color Quantization Wrapper -// -//////////////////////////////////////////////////////////////////////////////// -// Adapted from Earl F. Glynn's PaletteLibrary, March 1998 -//////////////////////////////////////////////////////////////////////////////// - -// Wrapper for internal use - uses TDIBReader for bitmap access - -function doCreateOptimizedPaletteForSingleBitmap(const DIB: TDIBReader; - Colors, ColorBits: integer; Windows: boolean): hPalette; -var - SystemPalette: HPalette; - ColorQuantizer: TColorQuantizer; - i: integer; - LogicalPalette: TMaxLogPalette; - RGBQuadArray: TRGBQuadArray; - Offset: integer; -begin - LogicalPalette.palVersion := $0300; - LogicalPalette.palNumEntries := Colors; - - if (Windows) then - begin - // Get the windows 20 color system palette - SystemPalette := GetStockObject(DEFAULT_PALETTE); - GetPaletteEntries(SystemPalette, 0, 10, LogicalPalette.palPalEntry[0]); - GetPaletteEntries(SystemPalette, 10, 10, LogicalPalette.palPalEntry[245]); - Colors := 236; - Offset := 10; - LogicalPalette.palNumEntries := 256; - end - else - Offset := 0; - - // Normally for 24-bit images, use ColorBits of 5 or 6. For 8-bit images - // use ColorBits = 8. - ColorQuantizer := TColorQuantizer.Create(Colors, ColorBits); - try - ColorQuantizer.ProcessImage(DIB); - ColorQuantizer.GetColorTable(RGBQuadArray); - finally - ColorQuantizer.Free; - end; - - for i := 0 to Colors - 1 do - with LogicalPalette.palPalEntry[i + Offset] do - begin - peRed := RGBQuadArray[i].rgbRed; - peGreen := RGBQuadArray[i].rgbGreen; - peBlue := RGBQuadArray[i].rgbBlue; - peFlags := RGBQuadArray[i].rgbReserved; - end; - Result := CreatePalette(pLogPalette(@LogicalPalette)^); -end; - -function CreateOptimizedPaletteForSingleBitmap(const Bitmap: TBitmap; - Colors, ColorBits: integer; Windows: boolean): hPalette; -var - DIB: TDIBReader; -begin - DIB := TDIBReader.Create(Bitmap, pf24bit); - try - Result := doCreateOptimizedPaletteForSingleBitmap(DIB, Colors, ColorBits, Windows); - finally - DIB.Free; - end; -end; - -//////////////////////////////////////////////////////////////////////////////// -// -// Color reduction -// -//////////////////////////////////////////////////////////////////////////////// -{$IFOPT R+} -{$DEFINE R_PLUS} -{$RANGECHECKS OFF} -{$ENDIF} - -function ReduceColors(Bitmap: TBitmap; ColorReduction: TColorReduction; - DitherMode: TDitherMode): ThtBitmap; -var - Palette: hPalette; - ColorLookup: TColorLookup; - Ditherer: TDitherEngine; - Row: Integer; - DIBResult: TDIBWriter; - DIBSource: TDIBReader; - SrcScanLine, - Src: PRGBTriple; - DstScanLine, - Dst: PByte; - BGR: TRGBTriple; -{$IFDEF DEBUG_DITHERPERFORMANCE} - TimeStart, - TimeStop: DWORD; -{$ENDIF} - - -begin -{$IFDEF DEBUG_DITHERPERFORMANCE} - timeBeginPeriod(5); - TimeStart := timeGetTime; -{$ENDIF} - - Result := ThtBitmap.Create; - try - - if (ColorReduction = rmNone) then - begin - Result.Assign(Bitmap); - SetPixelFormat(Result, pf24bit); - exit; - end; - - // Set bitmap width and height - Result.Width := Bitmap.Width; - Result.Height := Bitmap.Height; - - // Set the bitmap pixel format - SafeSetPixelFormat(Result, pf8bit); - Result.Palette := 0; - - ColorLookup := nil; - Ditherer := nil; - DIBResult := nil; - DIBSource := nil; - Palette := 0; - try // Protect above resources - - // Dithering and color mapper only supports 24 bit bitmaps, - // so we have convert the source bitmap to the appropiate format. - DIBSource := TDIBReader.Create(Bitmap, pf24bit); - - try - // Create a palette based on current options - case (ColorReduction) of - rmQuantizeWindows: - Palette := CreateOptimizedPaletteForSingleBitmap(Bitmap, 256, 8, True); - rmNetscape: - Palette := WebPalette; - rmMyPalette: - Palette := CopyPalette(ThePalette); - rmWindows20: - Palette := GetStockObject(DEFAULT_PALETTE); - else - exit; - end; - - Result.Palette := Palette; - - case (ColorReduction) of - // For some strange reason my fast and dirty color lookup - // is more precise that Windows GetNearestPaletteIndex... - rmNetscape: - ColorLookup := TNetscapeColorLookup.Create(Palette); - else - ColorLookup := TFastColorLookup.Create(Palette); - end; - - // Nothing to do if palette doesn't contain any colors - if (ColorLookup.Colors = 0) then - exit; - - // Create a ditherer based on current options - case (DitherMode) of - dmNearest: - Ditherer := TDitherEngine.Create(Bitmap.Width, ColorLookup); - dmFloydSteinberg: - Ditherer := TFloydSteinbergEngine.Create(Bitmap.Width, ColorLookup); - else - exit; - end; - - // The processed bitmap is returned in pf8bit format - DIBResult := TDIBWriter.Create(Result, pf8bit); - - // Process the image - Row := 0; - while (Row < Bitmap.Height) do - begin - SrcScanline := DIBSource.ScanLine[Row]; - DstScanline := DIBResult.ScanLine[Row]; - Src := PtrAdd(SrcScanLine, Ditherer.Column * sizeof(TRGBTriple)); - Dst := PtrAdd(DstScanLine, Ditherer.Column); - - while (Ditherer.Column < Ditherer.Width) and (Ditherer.Column >= 0) do - begin - BGR := Src^; - // Dither and map a single pixel - Dst^ := Ditherer.Dither(BGR.rgbtRed, BGR.rgbtGreen, BGR.rgbtBlue, - BGR.rgbtRed, BGR.rgbtGreen, BGR.rgbtBlue); - - inc(Src, Ditherer.Direction); - inc(Dst, Ditherer.Direction); - end; - - Inc(Row); - Ditherer.NextLine; - end; - except - Result.ReleasePalette; - if (Palette <> 0) then - DeleteObject(Palette); - raise; - end; - finally - if (ColorLookup <> nil) then - ColorLookup.Free; - if (Ditherer <> nil) then - Ditherer.Free; - if (DIBResult <> nil) then - DIBResult.Free; - if (DIBSource <> nil) then - DIBSource.Free; - end; - except - Result.Free; - raise; - end; - -{$IFDEF DEBUG_DITHERPERFORMANCE} - TimeStop := timeGetTime; - ShowMessage(format('Dithered %d pixels in %d mS, Rate %d pixels/mS (%d pixels/S)', - [Bitmap.Height * Bitmap.Width, TimeStop - TimeStart, - MulDiv(Bitmap.Height, Bitmap.Width, TimeStop - TimeStart + 1), - MulDiv(Bitmap.Height, Bitmap.Width * 1000, TimeStop - TimeStart + 1)])); - timeEndPeriod(5); -{$ENDIF} -end; -{$IFDEF R_PLUS} -{$RANGECHECKS ON} -{$UNDEF R_PLUS} -{$ENDIF} - -function GetBitmap(Source: TPersistent): ThtBitmap; -var - PixelFormat: TPixelFormat; - FBitmap: ThtBitmap; - ColorReduction: TColorReduction; - DitherMode: TDitherMode; - -begin - Result := nil; - if Source is TBitmap then {should always be} - begin - if (TBitmap(Source).Empty) then - exit; - PixelFormat := GetPixelFormat(TBitmap(Source)); - if (PixelFormat > pfDevice) then - begin - if ColorBits >= 8 then - ColorReduction := rmMyPalette - else - ColorReduction := rmWindows20; - DitherMode := dmFloydSteinberg; - // Convert image to 8 bits/pixel or less - FBitmap := ReduceColors(TBitmap(Source), ColorReduction, DitherMode); - end - else - begin - // Create new bitmap and copy - FBitmap := ThtBitmap.Create; - FBitmap.Assign(TBitmap(Source)); - end; - if Source is ThtBitmap then - begin - FBitmap.WithTransparentMask := ThtBitmap(Source).WithTransparentMask; - FBitmap.Mask := ThtBitmap(Source).Mask; - end; - Result := FBitmap; - end; -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/FramBrwz.pas b/CORE/Source/Plugins/Htmlviewer/source/FramBrwz.pas deleted file mode 100644 index 1671c628d..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/FramBrwz.pas +++ /dev/null @@ -1,1250 +0,0 @@ -{ -Version 11.7 -Copyright (c) 1995-2008 by L. David Baldwin -Copyright (c) 2008-2010 by HtmlViewer Team -Copyright (c) 2011-2016 by Bernd Gabriel - -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. - -Note that the source modules HTMLGIF1.PAS and DITHERUNIT.PAS -are covered by separate copyright notices located in those modules. -} - -{$I htmlcons.inc} - -unit FramBrwz; - -interface - -uses -{$ifdef LCL} - LclIntf, LclType, //LMessages, HtmlMisc, -{$else} - Windows, -{$endif} - SysUtils, Classes, {Messages,} vcl.Controls, vcl.ExtCtrls, - HtmlGlobals, - HtmlBuffer, - HtmlSubs, - HtmlView, - Htmlun2, - //ReadHTML, - URLSubs, - FramView; - -type - TGetPostRequestEvent = procedure(Sender: TObject; IsGet: Boolean; const URL, Query: ThtString; - Reload: Boolean; var NewURL: ThtString; var DocType: ThtmlFileType; var Stream: TStream) of object; - - TGetPostRequestExEvent = procedure(Sender: TObject; IsGet: Boolean; const URL, Query, EncType, Referer: ThtString; - Reload: Boolean; var NewURL: ThtString; var DocType: ThtmlFileType; var Stream: TStream) of object; - - TbrFormSubmitEvent = procedure(Sender: TObject; Viewer: THtmlViewer; - const Action, Target, EncType, Method: ThtString; Results: ThtStringList; var Handled: Boolean) of object; - - TbrFrameSet = class; - TbrSubFrameSet = class; - - TbrFrame = class(TViewerFrameBase) {TbrFrame holds a THtmlViewer or TbrSubFrameSet} - private - URLBase: ThtString; - TheStream: TStream; - TheStreamType: ThtmlFileType; - protected - function ExpandSourceName(const Base, Path, S: ThtString): ThtString; override; - function FrameSet: TbrSubFrameSet; {$ifdef UseInline} inline; {$endif} - function GetSubFrameSetClass: TSubFrameSetClass; override; - function MasterSet: TbrFrameSet; {$ifdef UseInline} inline; {$endif} - procedure CreateViewer; override; - procedure frLoadFromBrzFile(const URL, Dest, Query, EncType, Referer: ThtString; Bump, IsGet, Reload: Boolean); - procedure frLoadFromFile(const FName, Dest: ThtString; Bump, Reload: Boolean); override; - procedure RefreshEvent(Sender: TObject; Delay: Integer; const URL: ThtString); override; - procedure RefreshTimerTimer(Sender: TObject); override; - procedure URLExpandName(Sender: TObject; const SRC: ThtString; var Rslt: ThtString); - public - procedure LoadFiles; override; - procedure ReLoadFiles(APosition: LongInt); override; - end; - - TbrSubFrameSet = class(TSubFrameSetBase) {can contain one or more TbrFrames and/or TSubFrameSets} - private - URLBase: ThtString; - protected - function GetFrameClass: TViewerFrameClass; override; - procedure RefreshTimerTimer(Sender: Tobject); override; - public - constructor CreateIt(AOwner: TComponent; Master: TFrameSetBase); override; - end; - - TFrameBrowser = class; - - TbrFrameSet = class(TFrameSetBase) {only one of these showing, others may be held as History} - private - URLBase: ThtString; - protected - function FrameViewer: TFrameBrowser; {$ifdef UseInline} inline; {$endif} - function GetFrameClass: TViewerFrameClass; override; - function MasterSet: TbrFrameSet; {$ifdef UseInline} inline; {$endif} - function RequestEvent: Boolean; override; - procedure RefreshTimerTimer(Sender: TObject); override; - procedure LoadFromBrzFile(Stream: TStream; StreamType: ThtmlFileType; const URL, Dest: ThtString); - end; - - TFrameBrowser = class(TFVBase) - private - FOnFormSubmit: TbrFormSubmitEvent; - FOnGetPostRequest: TGetPostRequestEvent; - FOnGetPostRequestEx: TGetPostRequestExEvent; - FEncodePostArgs: Boolean; - InFormSubmit: Boolean; - function CurbrFrameSet: TbrFrameSet; {$ifdef UseInline} inline; {$endif} {the TbrFrameSet being displayed} - procedure LoadURLInternal(const URL, Dest, Query, EncType, Referer: ThtString; IsGet, Reload: Boolean); - protected - function GetFrameSetClass: TFrameSetClass; override; - function GetSubFrameSetClass: TSubFrameSetClass; override; - procedure AssertCanPostRequest(const URL: ThtString); virtual; - procedure CheckVisitedLinks; override; - procedure DoFormSubmitEvent(Sender: TObject; const Action, Target, EncType, Method: ThtString; Results: ThtStringList); override; - procedure DoURLRequest(Sender: TObject; const SRC: ThtString; var Stream: TStream); override; - procedure HotSpotCovered(Sender: TObject; const SRC: ThtString); override; - procedure PostRequest( - Sender: TObject; - IsGet: Boolean; - const Source, Query, EncType, Referer: ThtString; - Reload: Boolean; - out NewURL: ThtString; - out DocType: ThtmlFileType; - out Stream: TStream); virtual; - public - constructor Create(AOwner: TComponent); override; - constructor CreateCopy(Owner: TComponent; Source: TViewerBase); override; - function GetViewerUrlBase(Viewer: THtmlViewer): ThtString; - procedure GetPostQuery(const URL, Query, EncType: ThtString; IsGet: Boolean); - procedure HotSpotClick(Sender: TObject; const AnURL: ThtString; var Handled: Boolean); override; - procedure Load(const SRC: ThtString); override; - procedure LoadFromFile(const Name: ThtString); override; - procedure LoadURL(const URL: ThtString); - property EncodePostArgs: Boolean read FEncodePostArgs write FEncodePostArgs; - published - property OnGetPostRequest: TGetPostRequestEvent read FOnGetPostRequest write FOnGetPostRequest; - property OnGetPostRequestEx: TGetPostRequestExEvent read FOnGetPostRequestEx write FOnGetPostRequestEx; - property OnFormSubmit: TbrFormSubmitEvent read FOnFormSubmit write FOnFormSubmit; - end; - -implementation -{$ifdef Compiler24_Plus} -uses System.Types; -{$endif} - -function ConvDosToHTML(const Name: ThtString): ThtString; forward; - -{----------------TbrFrame.CreateIt} - -//-- BG ---------------------------------------------------------- 03.01.2010 -- -function TbrFrame.ExpandSourceName(const Base, Path, S: ThtString): ThtString; -begin - Result := ConvDosToHTML(S); - if Pos(':/', Result) <> 0 then - URLBase := URLSubs.GetURLBase(Result) {get new base} - else if Base <> '' then - begin - Result := CombineURL(Base, Result); - URLBase := Base; - end - else - begin - if LOwner is TbrFrameSet then - URLBase := (LOwner as TbrFrameSet).URLBase - else - URLBase := (LOwner as TbrSubFrameSet).URLBase; - Result := CombineURL(URLBase, Result); - end; -end; - -//-- BG ---------------------------------------------------------- 04.01.2010 -- -function TbrFrame.FrameSet: TbrSubFrameSet; -begin - Result := TbrSubFrameSet(inherited FrameSet); -end; - -//-- BG ---------------------------------------------------------- 04.01.2010 -- -function TbrFrame.GetSubFrameSetClass: TSubFrameSetClass; -begin - Result := TbrSubFrameSet; -end; - -//-- BG ---------------------------------------------------------- 03.01.2010 -- -function TbrFrame.MasterSet: TbrFrameSet; -begin - Result := TbrFrameSet(inherited MasterSet); -end; - -procedure TbrFrame.RefreshEvent(Sender: TObject; Delay: Integer; const URL: ThtString); -var - Ext: ThtString; -begin - if not (fvMetaRefresh in MasterSet.FrameViewer.fvOptions) then - Exit; - Ext := Lowercase(GetURLExtension(URL)); - if (Ext = 'exe') or (Ext = 'zip') then - Exit; - if URL = '' then - NextFile := Source - else if not IsFullURL(URL) then - NextFile := CombineURL(URLBase, URL) //URLBase + URL - else - NextFile := URL; - if not Assigned(RefreshTimer) then - RefreshTimer := TTimer.Create(Self); - RefreshTimer.OnTimer := RefreshTimerTimer; - RefreshTimer.Interval := Delay * 1000; - RefreshTimer.Enabled := True; -end; - -procedure TbrFrame.RefreshTimerTimer(Sender: TObject); -var - S, D: ThtString; -begin - RefreshTimer.Enabled := False; - if Unloaded then - Exit; - if not IsFullUrl(NextFile) then - NextFile := CombineURL(UrlBase, NextFile); - - SplitDest(NextFile, S, D); - if (MasterSet.Viewers.Count = 1) then {load a new FrameSet} - MasterSet.FrameViewer.LoadURLInternal(S, D, '', '', '', True, True) - else - frLoadFromBrzFile(S, D, '', '', '', True, True, True); -end; - -procedure TbrFrame.CreateViewer; -begin - inherited CreateViewer; - Viewer.OnExpandName := UrlExpandName; -end; - -{----------------TbrFrame.LoadFiles} - -procedure TbrFrame.LoadFiles; -var - I: Integer; - Upper, Lower: Boolean; - NewURL: ThtString; - Doc: TBuffer; -begin - if (Source <> '') and (MasterSet.NestLevel < 4) then - begin - if not Assigned(TheStream) then - begin - NewURL := ''; - MasterSet.FrameViewer.PostRequest(Self, True, Source, '', '', '', False, NewURL, TheStreamType, TheStream); - if NewURL <> '' then - Source := NewURL; - end; - URLBase := URLSubs.GetURLBase(Source); - Inc(MasterSet.NestLevel); - try - try - if TheStream <> nil then - begin - TheStream.Position := 0; - Doc := TBuffer.Create(TheStream, Source); - end - else - Doc := nil; - try - if ( (TheStreamType = HTMLType) or (TheStreamType = XHtmlType ) ) and MasterSet.FrameViewer.IsFrame(Doc) then - begin - FFrameSet := TbrSubFrameSet.CreateIt(Self, MasterSet); - FrameSet.Align := alClient; - FrameSet.Visible := False; - InsertControl(FrameSet); - FrameSet.SendToBack; - FrameSet.Visible := True; - MasterSet.FrameViewer.ParseFrame(FrameSet, Doc, Source, FrameSet.HandleMeta); -{$ifndef LCL} - BevelOuter := bvNone; -{$endif} - frBumpHistory1(Source, 0); - with FrameSet do - begin - for I := 0 to List.Count - 1 do - List[I].LoadFiles; - CheckNoresize(Lower, Upper); - if FRefreshDelay > 0 then - SetRefreshTimer; - end; - end - else - begin - CreateViewer; - Viewer.Base := MasterSet.FBase; - Viewer.LoadFromStream(TheStream, Source, TheStreamType); - Viewer.PositionTo(Destination); - frBumpHistory1(Source, Viewer.Position); - end; - finally - Doc.Free; - end; - except - on E: Exception do - begin - FreeAndNil(FFrameSet); - if not Assigned(Viewer) then - CreateViewer; - Viewer.LoadFromString( - '

    Error Can''t load ' + Source + - '

    Cause: ' + ThtString(E.Message)); {load an error message} - end; - end; - finally - Dec(MasterSet.NestLevel); - end; - end - else - begin {so blank area will perform like the TFrameBrowser} - OnMouseDown := MasterSet.FrameViewer.OnMouseDown; - OnMouseMove := MasterSet.FrameViewer.OnMouseMove; - OnMouseUp := MasterSet.FrameViewer.OnMouseUp; - OnMouseWheel := MasterSet.FrameViewer.OnMouseWheel; - OnMouseWheelUp := MasterSet.FrameViewer.OnMouseWheelUp; - OnMouseWheelDown := MasterSet.FrameViewer.OnMouseWheelDown; - end; -end; - -{----------------TbrFrame.ReloadFiles} - -procedure TbrFrame.ReloadFiles(APosition: LongInt); -var - I: Integer; - Upper, Lower: Boolean; - Dummy: ThtString; -begin - if Source <> '' then - if FrameSet <> nil then - begin - with FrameSet do - begin - for I := 0 to List.Count - 1 do - List[I].ReloadFiles(APosition); - CheckNoResize(Lower, Upper); - end; - end - else if Assigned(Viewer) then - begin - Viewer.Base := MasterSet.FBase; {only effective if no Base to be read} - try - MasterSet.FrameViewer.PostRequest(Self, True, Source, '', '', '', True, Dummy, TheStreamType, TheStream); - Viewer.LoadFromStream(TheStream, Source, TheStreamType); - if APosition < 0 then - Viewer.Position := ViewerPosition - else - Viewer.Position := APosition; {its History Position} - Viewer.FormData := ViewerFormData; - ViewerFormData.Free; - ViewerFormData := nil; - except - on E: Exception do - Viewer.LoadFromString( - '

    Error Can''t load ' + Source + - '

    Cause: ' + ThtString(E.Message)); {load an error message} - end; - end; - Unloaded := False; -end; - -{----------------TbrFrame.frLoadFromBrzFile} - -procedure TbrFrame.frLoadFromBrzFile(const URL, Dest, Query, EncType, Referer: ThtString; Bump, IsGet, Reload: Boolean); -{URL is full URL here, has been seperated from Destination} -var - OldPos: LongInt; - HS, S, S1, OldTitle, OldName, OldBase: ThtString; - OldFormData: TFormData; - SameName: Boolean; - OldViewer: THtmlViewer; - OldFrameSet: TbrSubFrameSet; - Upper, Lower, FrameFile: Boolean; - Item: TFrameBase; - I: Integer; - Doc: TBuffer; -begin - if Assigned(RefreshTimer) then - RefreshTimer.Enabled := False; - OldName := Source; - OldBase := URLBase; - S := URL; - if S = '' then - S := OldName - else - URLBase := URLSubs.GetURLBase(S); {get new base} - HS := S; - SameName := htCompareText(S, OldName) = 0; -{if SameName, will not have to reload anything unless Reload set} - - if not SameName or Reload then - begin - if Assigned(Viewer) and Assigned(MasterSet.FrameViewer.OnViewerClear) then - MasterSet.FrameViewer.OnViewerClear(Viewer); - MasterSet.FrameViewer.PostRequest(Self, IsGet, S, Query, EncType, Referer, Reload, S1, TheStreamType, TheStream); - if S1 <> '' then - begin - S := S1; - URLBase := URLSubs.GetURLBase(S); - end; - Source := S; - end; - - try - //TheString := StreamToString(TheStream); - if TheStream <> nil then - begin - TheStream.Position := 0; - Doc := TBuffer.Create(TheStream) - end - else - Doc := nil; - try - if not SameName then - FrameFile := (TheStreamType = HTMLType) and MasterSet.FrameViewer.IsFrame(Doc) - else - FrameFile := not Assigned(Viewer); - if SameName and not Reload then - if Assigned(Viewer) then - begin - OldPos := Viewer.Position; - Viewer.PositionTo(Dest); - MasterSet.FrameViewer.AddVisitedLink(URL + Dest); - if Bump and (Viewer.Position <> OldPos) then - {Viewer to Viewer} - frBumpHistory(HS, Viewer.Position, OldPos, nil); - end - else - begin - with FrameSet do - for I := 0 to List.Count - 1 do - begin - Item := TFrameBase(List.Items[I]); - if (Item is TbrFrame) then - with TbrFrame(Item) do - if htCompareText(Source, OrigSource) <> 0 then - frLoadFromBrzFile(OrigSource, '', '', '', '', True, True, False); - end; - Exit; - end - else if Assigned(Viewer) and not FrameFile then {not samename or samename and reload} - begin {Viewer already assigned and it's not a Frame file} - OldPos := Viewer.Position; - OldTitle := Viewer.DocumentTitle; - if Bump and not SameName and (MasterSet.Viewers.Count > 1) then - OldFormData := Viewer.FormData - else - OldFormData := nil; - try - Viewer.Base := MasterSet.FBase; - Viewer.LoadFromStream(TheStream, Source, TheStreamType); - Viewer.PositionTo(Dest); - MasterSet.FrameViewer.AddVisitedLink(URL + Dest); - if not samename then - begin {don't bump history on a forced reload} - if MasterSet.Viewers.Count > 1 then - begin - if Bump then - {Viewer to Viewer} - frBumpHistory(HS, Viewer.Position, OldPos, OldFormData) - else - OldFormData.Free; - end - else if (MasterSet.Viewers.Count = 1) and Bump then - {a single viewer situation, bump the history here} - with MasterSet do - begin - FCurrentFile := Source; - FTitle := Viewer.DocumentTitle; - FBase := Viewer.Base; - FBaseTarget := Viewer.BaseTarget; - FrameViewer.BumpHistory1(OldName, OldTitle, OldPos, HTMLType); - end; - end; - except - OldFormData.Free; - raise; - end; - end - else - begin {Viewer is not assigned or it is a Frame File} - {keep the old viewer or frameset around (free later) to minimize blink} - OldViewer := Viewer; FViewer := nil; - OldFrameSet := FrameSet; FFrameSet := nil; - if OldFrameSet <> nil then - OldFrameSet.ClearFrameNames; - if FrameFile then - begin {it's a frame file} - FFrameSet := TbrSubFrameSet.CreateIt(Self, MasterSet); - FrameSet.URLBase := URLBase; - FrameSet.Align := alClient; - FrameSet.Visible := False; - InsertControl(FrameSet); - FrameSet.SendToBack; {to prevent blink} - FrameSet.Visible := True; - MasterSet.FrameViewer.ParseFrame(FrameSet, Doc, Source, FrameSet.HandleMeta); - MasterSet.FrameViewer.AddVisitedLink(URL); -{$ifndef LCL} - BevelOuter := bvNone; -{$endif} - with FrameSet do - begin - for I := 0 to List.Count - 1 do - List[I].LoadFiles; - CheckNoresize(Lower, Upper); - if FRefreshDelay > 0 then - SetRefreshTimer; - end; - if Assigned(OldViewer) then - frBumpHistory(HS, 0, OldViewer.Position, OldViewer.FormData) - else - frBumpHistory(S, 0, 0, nil); - end - else - begin {not a frame file but needs a viewer} - CreateViewer; - Viewer.Base := MasterSet.FBase; - Viewer.LoadFromStream(TheStream, Source, TheStreamType); - Viewer.PositionTo(Dest); - MasterSet.FrameViewer.AddVisitedLink(URL + Dest); - {FrameSet to Viewer} - frBumpHistory(HS, Viewer.Position, 0, nil); - end; - if FrameSet <> nil then - with FrameSet do - begin - with ClientRect do - InitializeDimensions(Left, Top, Right - Left, Bottom - Top); - CalcSizes(nil); - end; - if Assigned(Viewer) then - begin -{$ifndef LCL} - if MasterSet.BorderSize = 0 then - BevelOuter := bvNone - else - begin - BevelOuter := bvLowered; - BevelWidth := MasterSet.BorderSize; - end; -{$endif} - if (Dest <> '') then - Viewer.PositionTo(Dest); - end; - if Assigned(OldViewer) then - begin - MasterSet.Viewers.Remove(OldViewer); - if MasterSet.FActive = OldViewer then - MasterSet.FActive := nil; - OldViewer.Free; - end - else if Assigned(OldFrameSet) then - begin - OldFrameSet.UnloadFiles; - OldFrameSet.Visible := False; - end; - Invalidate; - end; - finally - Doc.Free; - end; - except - Source := OldName; - URLBase := OldBase; - raise; - end; -end; - -procedure TbrFrame.frLoadFromFile(const FName, Dest: ThtString; Bump, Reload: Boolean); -begin - frLoadFromBrzFile(FName, Dest, '', '', Viewer.CurrentFile, Bump, True, Reload); -end; - -function ConvDosToHTML(const Name: ThtString): ThtString; -{if Name is a Dos filename, convert it to HTML. Add the file:// if it is a full path filename} -begin - Result := Name; - if Pos('\', Result) > 0 then - begin - Result := DosToHTML(Result); - if IsAbsolutePath(Name) then {UNC path or something like c:\....} - Result := 'file:///' + Result; - end; -end; - -{----------------TbrFrame.URLExpandName} - -procedure TbrFrame.URLExpandName(Sender: TObject; const SRC: ThtString; var Rslt: ThtString); -var - S: ThtString; - Viewer: THtmlViewer; -begin - S := ConvDosToHTML(SRC); - if not IsFullUrl(S) then - begin - Viewer := Sender as THtmlViewer; - if Pos('//', SRC) = 1 then - S := 'http:' + S - else if Viewer.Base <> '' then - Rslt := CombineURL(ConvDosToHTML(Viewer.Base), S) - else - Rslt := CombineURL(UrlBase, S); - end - else - Rslt := S; -end; - -{----------------TbrSubFrameSet.CreateIt} - -constructor TbrSubFrameSet.CreateIt(AOwner: TComponent; Master: TFrameSetBase); -begin - inherited CreateIt(AOwner, Master); - if (AOwner is TbrFrame) then - URLBase := TbrFrame(AOwner).URLBase - else if (AOwner is TbrFrameSet) then - URLBase := TbrFrameSet(AOwner).URLBase - else if (AOwner is TbrSubFrameSet) then - URLBase := TbrSubFrameSet(AOwner).URLBase; -end; - -//-- BG ---------------------------------------------------------- 04.01.2010 -- -function TbrSubFrameSet.GetFrameClass: TViewerFrameClass; -begin - Result := TbrFrame; -end; - -{----------------TbrSubFrameSet.RefreshTimerTimer} - -procedure TbrSubFrameSet.RefreshTimerTimer(Sender: Tobject); -var - S, D: ThtString; -begin - RefreshTimer.Enabled := False; - if Unloaded then - Exit; - if Owner is TbrFrame then - begin - SplitDest(NextFile, S, D); - TbrFrame(Owner).frLoadFromBrzFile(S, D, '', '', '', True, True, True) - end; -end; - -//-- BG ---------------------------------------------------------- 03.01.2010 -- -function TbrFrameSet.FrameViewer: TFrameBrowser; -begin - Result := TFrameBrowser(inherited FrameViewer); -end; - -//-- BG ---------------------------------------------------------- 04.01.2010 -- -function TbrFrameSet.GetFrameClass: TViewerFrameClass; -begin - Result := TbrFrame; -end; - -//-- BG ---------------------------------------------------------- 04.01.2010 -- -function TbrFrameSet.MasterSet: TbrFrameSet; -begin - Result := TbrFrameSet(inherited MasterSet); -end; - -procedure TbrFrameSet.RefreshTimerTimer(Sender: Tobject); -var - S, D: ThtString; -begin - RefreshTimer.Enabled := False; - if Self = MasterSet.FrameViewer.CurFrameSet then - begin - SplitDest(NextFile, S, D); - FrameViewer.LoadURLInternal(S, D, '', '', '', True, True); - end; -end; - -//-- BG ---------------------------------------------------------- 04.01.2010 -- -function TbrFrameSet.RequestEvent: Boolean; -begin - Result := True; -end; - -{----------------TbrFrameSet.LoadFromBrzFile} - -procedure TbrFrameSet.LoadFromBrzFile(Stream: TStream; StreamType: ThtmlFileType; - const URL, Dest: ThtString); -var - I: Integer; - Frame: TbrFrame; - Lower, Upper: Boolean; - Doc: TBuffer; -begin - Clear; - NestLevel := 0; - FCurrentFile := URL; - Stream.Position := 0; - Doc := TBuffer.Create(Stream, Url); - try - if ( (StreamType = XHtmlType) or (StreamType = HTMLType) ) and MasterSet.FrameViewer.IsFrame(Doc) then - begin {it's a Frameset html file} - MasterSet.FrameViewer.ParseFrame(Self, Doc, Url, HandleMeta); - for I := 0 to List.Count - 1 do - List[I].LoadFiles; - CalcSizes(Self); - CheckNoresize(Lower, Upper); - if FRefreshDelay > 0 then - SetRefreshTimer; - end - else - begin {it's a non frame file} - Frame := TbrFrame(AddFrame(nil, '')); - Frame.Source := URL; - Frame.TheStream := Stream; - Frame.TheStreamType := StreamType; - Frame.Destination := Dest; - Parsed('', '', ''); - CalcSizes(Self); - Frame.LoadFiles; - FTitle := Frame.Viewer.DocumentTitle; - FBase := Frame.Viewer.Base; - FBaseTarget := Frame.Viewer.BaseTarget; - end; - finally - Doc.Free; - end; -end; - -{----------------TFrameBrowser.Create} - -constructor TFrameBrowser.Create(AOwner: TComponent); -begin - inherited; - FEncodePostArgs := True; -end; - -//-- BG ---------------------------------------------------------- 25.11.2011 -- -constructor TFrameBrowser.CreateCopy(Owner: TComponent; Source: TViewerBase); -var - Viewer: TFrameBrowser absolute Source; -begin - inherited; - if Source is TFrameBrowser then - begin - OnGetPostRequest := Viewer.OnGetPostRequest; - OnGetPostRequestEx := Viewer.OnGetPostRequestEx; - OnFormSubmit := Viewer.OnFormSubmit; - end; -end; - -//-- BG ---------------------------------------------------------- 24.11.2011 -- -procedure TFrameBrowser.Load(const SRC: ThtString); -begin - inherited; - LoadUrl(SRC); -end; - -//-- BG ---------------------------------------------------------- 24.09.2010 -- -procedure TFrameBrowser.LoadFromFile(const Name: ThtString); -begin - LoadUrl('file://' + DosToHTML(Name)); -end; - -{----------------TFrameBrowser.LoadURL} - -procedure TFrameBrowser.LoadURL(const URL: ThtString); -var - S, D: ThtString; -begin - if not Processing then - begin - SplitDest(Normalize(URL), S, D); - LoadURLInternal(S, D, '', '', '', True, False); - end; -end; - -{----------------TFrameBrowser.GetPostQuery} - -procedure TFrameBrowser.GetPostQuery(const URL, Query, EncType: ThtString; IsGet: Boolean); -var - S, D: ThtString; -begin - if not Processing then - begin - SplitDest(Normalize(URL), S, D); - LoadURLInternal(S, D, Query, EncType, '', IsGet, True); - end; -end; - -//-- BG ---------------------------------------------------------- 05.01.2010 -- -function TFrameBrowser.GetFrameSetClass: TFrameSetClass; -begin - Result := TbrFrameSet; -end; - -//-- BG ---------------------------------------------------------- 04.01.2010 -- -function TFrameBrowser.GetSubFrameSetClass: TSubFrameSetClass; -begin - Result := TbrSubFrameSet; -end; - -{----------------TFrameBrowser.LoadURLInternal} - -procedure TFrameBrowser.LoadURLInternal(const URL, Dest, Query, EncType, Referer: ThtString; - IsGet, Reload: Boolean); -var - OldFrameSet: TbrFrameSet; - OldFile, S, S1: ThtString; - OldPos: LongInt; - Tmp: TObject; - SameName: Boolean; - Stream: TStream; - StreamType: ThtmlFileType; - I: Integer; -begin - AssertCanPostRequest(URL); - BeginProcessing; - IOResult; {remove any pending file errors} - S := URL; - try - OldFile := CurbrFrameSet.FCurrentFile; - ProcessList.Clear; - if Assigned(OnSoundRequest) then - OnSoundRequest(Self, '', 0, True); - SameName := htCompareText(OldFile, S) = 0; - if not SameName then - begin - if Assigned(OnViewerClear) then - for I := 0 to CurbrFrameSet.Viewers.Count - 1 do - OnViewerClear(CurbrFrameSet.Viewers[I]); - OldFrameSet := CurbrFrameSet; - FCurFrameSet := TbrFrameSet.Create(Self); - CurFrameSet.Align := alClient; - CurFrameSet.visible := False; - InsertControl(CurbrFrameSet); - CurFrameSet.SendToBack; - CurFrameSet.Visible := True; - - try - S1 := ''; - PostRequest(Self, IsGet, S, Query, EncType, Referer, Reload, S1, StreamType, Stream); - if not Assigned(Stream) then - raise EhtLoadError.CreateFmt('Can''t locate ''%s''.', [S]); - if S1 <> '' then - S := S1; - - if Pos(':', S) <> 0 then - CurbrFrameSet.URLBase := URLSubs.GetURLBase(S) - else - begin - CurbrFrameSet.URLBase := OldFrameSet.URLBase; - S := CombineURL(CurbrFrameSet.URLBase, S); - end; - - CurbrFrameSet.LoadFromBrzFile(Stream, StreamType, S, Dest); - except - RemoveControl(CurbrFrameSet); - CurbrFrameSet.Free; - FCurFrameSet := OldFrameSet; - raise; - end; - - OldPos := 0; - if (OldFrameSet.Viewers.Count = 1) then - begin - Tmp := OldFrameSet.Viewers[0]; - if Tmp is THtmlViewer then - OldPos := THtmlViewer(Tmp).Position; - end; - OldFrameSet.UnloadFiles; - CurbrFrameSet.Visible := True; - CurbrFrameSet.BringToFront; - BumpHistory(OldFrameSet, OldPos); - end - else - begin {Same name} - OldPos := 0; - if (CurbrFrameSet.Viewers.Count = 1) then - begin - Tmp := CurbrFrameSet.Viewers[0]; - if Tmp is THtmlViewer then - OldPos := THtmlViewer(Tmp).Position; - end; - PostRequest(Self, IsGet, S, Query, EncType, Referer, Reload, S1, StreamType, Stream); - if not Assigned(Stream) then - raise EhtLoadError.CreateFmt('Can''t locate cache file ''%s''.', [S]); - - if S1 <> '' then - begin - S := S1; - if Pos(':', S) <> 0 then - CurbrFrameSet.URLBase := URLSubs.GetURLBase(S); - end; - - (CurbrFrameSet as TbrFrameSet).LoadFromBrzFile(Stream, StreamType, S, Dest); - BumpHistory2(OldPos); {not executed if exception occurs} - end; - AddVisitedLink(URL+Dest); - finally - EndProcessing; - end; -end; - -//-- BG ---------------------------------------------------------- 23.09.2010 -- -// concentrate all FOnGetPostRequest* calls here: -procedure TFrameBrowser.PostRequest(Sender: TObject; IsGet: Boolean; const Source, Query, EncType, - Referer: ThtString; Reload: Boolean; out NewURL: ThtString; out DocType: ThtmlFileType; - out Stream: TStream); -begin - NewURL := ''; - DocType := OtherType; - Stream := nil; - if Assigned(FOnGetPostRequestEx) then - FOnGetPostRequestEx(Self, IsGet, Source, Query, EncType, Referer, Reload, NewURL, DocType, Stream) - else if Assigned(FOnGetPostRequest) then - FOnGetPostRequest(Self, IsGet, Source, Query, Reload, NewURL, DocType, Stream) - else if Copy(Source, 1, 7) = 'file://' then - begin - DocType := GetFileType(Source); - if DocType <> OtherType then - begin - Stream := TMemoryStream.Create; - TMemoryStream(Stream).LoadFromFile(HTMLToDos(Source)); - end; - end; -end; - -{----------------TFrameBrowser.HotSpotClick} - -procedure TFrameBrowser.HotSpotClick(Sender: TObject; const AnURL: ThtString; var Handled: Boolean); -var - I: Integer; - Viewer: THtmlViewer; - FrameTarget: TFrameBase; - S, Dest, FullUrl, Target: ThtString; -begin - Handled := Processing; - if Handled then - Exit; - - Viewer := Sender as THtmlViewer; - Target := GetViewerTarget(Viewer); - FLinkAttributes.Text := Viewer.LinkAttributes.Text; - FLinkText := Viewer.LinkText; - - SplitDest(AnURL, S, Dest); - S := ConvDosToHTML(S); - if S = '' then - FullUrl := (Viewer.FrameOwner as TbrFrame).Source - else if IsFullURL(S) then - FullUrl := S - else if Viewer.Base <> '' then - FullUrl := CombineURL(ConvDosToHTML(Viewer.Base), S) - else - FullUrl := CombineURL((Viewer.FrameOwner as TbrFrame).URLBase, S); - FullUrl := Normalize(FullUrl); // ANGUS - - Handled := HotSpotClickHandled(FullUrl + Dest, Target); - if not Handled then - begin - Handled := True; - I := -1; - if (Target = '') or (htCompareText(Target, '_self') = 0) then {no target or _self target} - begin - FrameTarget := Viewer.FrameOwner as TbrFrame; - if not Assigned(FrameTarget) then - Exit; - end - else if CurbrFrameSet.FrameNames.Find(Target, I) then - FrameTarget := CurbrFrameSet.FrameNames.Objects[I] as TFrameBase - else if htCompareText(Target, '_top') = 0 then - FrameTarget := CurbrFrameSet - else if htCompareText(Target, '_parent') = 0 then - begin - FrameTarget := (Viewer.FrameOwner as TbrFrame).Owner as TFrameBase; - while Assigned(FrameTarget) and not (FrameTarget is TbrFrame) - and not (FrameTarget is TbrFrameSet) do - FrameTarget := FrameTarget.Owner as TFrameBase; - end - else - begin - if Assigned(OnBlankWindowRequest) then - begin - AddVisitedLink(FullUrl + Dest); - CheckVisitedLinks; - OnBlankWindowRequest(Self, Target, FullUrl + Dest); - Handled := True; - end - else - Handled := Target <> ''; {true if can't find target window} - Exit; - end; - - FURL := AnURL; - BeginProcessing; - if (FrameTarget is TbrFrame) and (CurbrFrameSet.Viewers.Count = 1) and (S <> '') - and (htCompareText(S, CurbrFrameSet.FCurrentFile) <> 0) then - FrameTarget := CurbrFrameSet; {force a new FrameSet on name change} - try - if FrameTarget is TbrFrame then - TbrFrame(FrameTarget).frLoadFromBrzFile(FullUrl, Dest, '', '', Viewer.CurrentFile, True, True, False) - else if FrameTarget is TbrFrameSet then - LoadURLInternal(FullUrl, Dest, '', '', Viewer.CurrentFile, True, False); - AddVisitedLink(FullUrl + Dest); - CheckVisitedLinks; - finally - EndProcessing; - end; - end; -end; - -{----------------TFrameBrowser.HotSpotCovered} - -procedure TFrameBrowser.HotSpotCovered(Sender: TObject; const SRC: ThtString); -var - S, Dest, FullUrl: ThtString; - Viewer: THtmlViewer; -begin - if Assigned(OnHotSpotTargetCovered) then - begin - Viewer := Sender as THtmlViewer; - SplitDest(SRC, S, Dest); - S := ConvDosToHTML(S); {convert DOS names} - if IsFullURL(S) or (Src = '') then - FullUrl := S - else - begin - if Viewer.Base <> '' then - FullUrl := CombineURL(ConvDosToHTML(Viewer.Base), S) - else - FullUrl := CombineURL((Viewer.FrameOwner as TbrFrame).URLBase, S); - end; - FLinkText := Viewer.LinkText; - FLinkAttributes.Text := Viewer.LinkAttributes.Text; - OnHotSpotTargetCovered(Sender, (Sender as THtmlViewer).Target, FullUrl + Dest); - end; -end; - -//-- BG ---------------------------------------------------------- 04.01.2010 -- -function TFrameBrowser.CurbrFrameSet: TbrFrameSet; -begin - Result := TbrFrameSet(CurFrameSet); -end; - -{----------------TFrameBrowser.DoFormSubmitEvent} - -procedure TFrameBrowser.DoFormSubmitEvent(Sender: TObject; const Action, Target, EncType, - Method: ThtString; Results: ThtStringList); -var - S, Dest, Query: ThtString; - FrameTarget: TFrameBase; - I: Integer; - Viewer: THtmlViewer; - UserHandled, IsGet: Boolean; - - function AssembleQuery: ThtString; - var - S1: ThtString; - I, J: Integer; - - function Encode(const S: ThtString): ThtString; - var - Ch: ThtChar; - I: Integer; - begin {convert odd chars into %xx -- does not handle the '=' sign yet} - Result := ''; - for I := 1 to Length(S) do - begin - Ch := S[I]; - case Ch of - ' ': - htAppendChr(Result, '+'); - - 'a'..'z', - 'A'..'Z', - '0'..'9', - '=', '_', - '-', '.', - '*', '@': - htAppendChr(Result, Ch); - else - htAppendChr(Result, '%'); - htAppendStr(Result, IntToHex(Ord(Ch), 2)); - end; - end; - end; - - begin - Result := ''; - for I := 0 to Results.Count - 1 do - begin - if FEncodePostArgs then - begin {form a ThtString from the TStringList using '+' for spaces and '&' for separaters} - S1 := Encode(Results[I]); - J := Pos(' ', S1); - while J > 0 do - begin - S1[J] := '+'; - J := Pos(' ', S1); - end; - end - else - S1 := Trim(Results[I]); {No encoding done} - if I <> 0 then - Result := Result + '&'; - Result := Result + S1; - end; - Results.Free; - end; - -begin - if InFormSubmit then - Exit; - InFormSubmit := True; - try - {see if the application wants to handle this event} - UserHandled := false; - Viewer := (Sender as THtmlViewer); - if Assigned(FOnFormSubmit) then - FOnFormSubmit(Self, Viewer, Action, Target, EncType, Method, Results, UserHandled); - if not UserHandled then - begin - Query := AssembleQuery; - I := -1; - - if (Target = '') or (htCompareText(Target, '_self') = 0) then {no target or _self target} - FrameTarget := Viewer.FrameOwner as TbrFrame - else if CurbrFrameSet.FrameNames.Find(Target, I) then - FrameTarget := (CurbrFrameSet.FrameNames.Objects[I] as TbrFrame) - else if htCompareText(Target, '_top') = 0 then - FrameTarget := CurbrFrameSet - else if htCompareText(Target, '_parent') = 0 then - begin - FrameTarget := (Viewer.FrameOwner as TbrFrame).Owner as TFrameBase; - while Assigned(FrameTarget) and not (FrameTarget is TbrFrame) - and not (FrameTarget is TbrFrameSet) do - FrameTarget := FrameTarget.Owner as TFrameBase; - end - else - begin - if Assigned(OnBlankWindowRequest) then - OnBlankWindowRequest(Self, Target, Action + '?' + Query); - Exit; - end; - - S := Action; - I := Pos('#', S); - if I >= 1 then - begin - Dest := System.Copy(S, I, Length(S) - I + 1); {local destination} - S := System.Copy(S, 1, I - 1); {the file name} - end - else - Dest := ''; {no local destination} - - BeginProcessing; - try - if (FrameTarget is TbrFrame) and (CurbrFrameSet.Viewers.Count = 1) and (S <> '') - and (htCompareText(S, CurbrFrameSet.FCurrentFile) <> 0) then - FrameTarget := CurbrFrameSet; {force a new FrameSet on name change} - if S = '' then - S := (Viewer.FrameOwner as TbrFrame).Source - else if not IsFullURL(S) then - S := CombineURL((Viewer.FrameOwner as TbrFrame).URLBase, S); - IsGet := htCompareText(Method, 'get') = 0; - if FrameTarget is TbrFrame then - TbrFrame(FrameTarget).frLoadFromBrzFile(S, Dest, Query, EncType, Viewer.CurrentFile, True, IsGet, True) - else if FrameTarget is TbrFrameSet then - LoadURLInternal(S, Dest, Query, EncType, Viewer.CurrentFile, IsGet, True); - finally - EndProcessing; - end; - end; - finally - InFormSubmit := False; - end; -end; - -procedure TFrameBrowser.DoURLRequest(Sender: TObject; const SRC: ThtString; var Stream: TStream); -var - NewURL: ThtString; - DocType: ThtmlFileType; -begin - PostRequest(Sender, True, SRC, '', '', '', False, NewURL, DocType, Stream); -end; - -{----------------TFrameBrowser.GetViewerUrlBase} - -function TFrameBrowser.GetViewerUrlBase(Viewer: THtmlViewer): ThtString; -var - Frame: TbrFrame; -begin - try - Frame := Viewer.FrameOwner as TbrFrame; - Result := Frame.UrlBase; - except - Result := ''; - end; -end; - -//-- BG ---------------------------------------------------------- 23.03.2012 -- -procedure TFrameBrowser.AssertCanPostRequest(const URL: ThtString); -begin - if not htSameText(Copy(URL, 1, 7), 'file://') then - if not Assigned(FOnGetPostRequest) and not Assigned(FOnGetPostRequestEx) then - raise Exception.Create('Don''t know how to load an URL. Neither OnGetPostRequest nor OnGetPostRequestEx event handler defined.'); -end; - -{----------------TFrameBrowser.CheckVisitedLinks} - -procedure TFrameBrowser.CheckVisitedLinks; -var - I, J, K: Integer; - S, S1: ThtString; - Viewer: THtmlViewer; -begin - if VisitedMaxCount = 0 then - Exit; - for K := 0 to CurbrFrameSet.Viewers.Count - 1 do - begin - Viewer := THtmlViewer(CurbrFrameSet.Viewers[K]); - for I := 0 to Visited.Count - 1 do - begin - S := Visited[I]; - for J := 0 to Viewer.LinkList.Count - 1 do - with Viewer.LinkList[J] do - begin - if Url <> '' then - begin - if IsFullURL(Url) then - S1 := Url - else if Url[1] = '#' then - S1 := TbrFrame(Viewer.FrameOwner).Source + Url - else - S1 := CombineURL(TbrFrame(Viewer.FrameOwner).UrlBase, Url); - if htCompareText(S, S1) = 0 then - Visited := True; - end; - end; - end; - Viewer.Invalidate; - end; -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/FrameViewerReg.pas b/CORE/Source/Plugins/Htmlviewer/source/FrameViewerReg.pas deleted file mode 100644 index 1d9d37244..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/FrameViewerReg.pas +++ /dev/null @@ -1,83 +0,0 @@ -{ -Version 11.7 -Copyright (c) 1995-2008 by L. David Baldwin -Copyright (c) 2008-2014 by HtmlViewer Team -Copyright (c) 2015-2016 by Bernd Gabriel - -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. - -Note that the source modules HTMLGIF1.PAS and DITHERUNIT.PAS -are covered by separate copyright notices located in those modules. -} - -{$I htmlcons.inc} - -unit FrameViewerReg; - -interface - -uses -{$ifdef LCL} - LResources, -{$else} -{$endif} - Classes, -{$ifndef UseOldPreviewForm} - BegaPreview, - BegaPreviewForm, - BegaPreviewPanel, - BegaScrollBox, - BegaZoom, -{$endif} - UrlConn, - HtmlView, - FramView, - FramBrwz; - -procedure Register; - -implementation - -procedure Register; -begin - RegisterComponents('REST Dataware - Html FrameViewer', [ - {$ifndef UseOldPreviewForm} - {$ifndef NoMetaFile} - {$ifndef NoFlatScrollbars} - TBegaMetafilePreviewPanel, - TBegaPreviewFrame, - TBegaScrollBox, - TBegaZoomBox, - TBegaCustomPrintPreviewForm, - {$endif} - {$endif} -{$endif} - ThtConnectionManager, - ThtFileConnector, - ThtResourceConnector, - THtmlViewer, - TFrameViewer, - TFrameBrowser]); -end; - -{$ifdef LCL} -initialization -{$I htmlcomp.lrs} -{$endif} - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/GDIPL2A.pas b/CORE/Source/Plugins/Htmlviewer/source/GDIPL2A.pas deleted file mode 100644 index 14d596fbb..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/GDIPL2A.pas +++ /dev/null @@ -1,698 +0,0 @@ -{ -Version 11.7 -Copyright (c) 1995-2008 by L. David Baldwin -Copyright (c) 2008-2016 by HtmlViewer Team - -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. - -Note that the source modules HTMLGIF1.PAS and DITHERUNIT.PAS -are covered by separate copyright notices located in those modules. -} -{ - NOTICE: Conditional symbols control code emitted by this unit: - - NoGDIPlus: This units produces code only, if conditional symbol NoGDIPlus is not defined. - - HasGDIPlus: This unit uses the compiler's GDI units, if conditional symbol HasGDIPlus is defined - else the API to GdiPlus.dll is implemented inside this unit. - - Define or undefine these symbols in htmlcons.inc. -} - -{$I htmlcons.inc} - -unit GDIPL2A; - -interface -{$ifndef NoGDIPlus} - -uses -{$ifdef HasGDIPlus} - GDIPAPI, -{$endif} -{$ifdef LCL} - LCLType, -{$endif} - Windows, ActiveX, SysUtils, vcl.Graphics, Classes, vcl.ClipBrd, - HtmlGlobals; - -var - GDIPlusActive: Boolean; - -{$ifndef HasGDIPlus} -type - //types for GDIPlus API - GpGraphics = Pointer; - GpImage = Pointer; - GpBitmap = Pointer; - GpStatus = Integer; - PixelFormat = Integer; - GpImageAttributes = Pointer; - -const - NotImplemented: GpStatus = 6; -{$endif} - -type - - { ThtGpImage } - - ThtGpImage = class(ThtGraphic) - private - FWidth, FHeight: Cardinal; - FFilename: string; - FBitmap: TBitmap; - protected - fHandle: GpImage; - function GetEmpty: Boolean; override; - function GetHeight: Integer; override; - function GetWidth: Integer; override; - procedure Draw(ACanvas: TCanvas; const Rect: TRect); override; - procedure SetHeight(Value: Integer); override; - procedure SetWidth(Value: Integer); override; - public - destructor Destroy; override; - - function GetBitmap: TBitmap; -{$ifdef LCL} - procedure LoadFromClipboardFormat(FormatID: TClipboardFormat); override; - procedure SaveToClipboardFormat(FormatID: TClipboardFormat); override; -{$else} - procedure LoadFromClipboardFormat(AFormat: Word; AData: THandle; APalette: HPALETTE); override; - procedure SaveToClipboardFormat(var AFormat: Word; var AData: THandle; var APalette: HPALETTE); override; -{$endif} - procedure LoadFromFile(const Filename: String{; TmpFile: boolean = False}); override; - procedure LoadFromStream(IStr: IStream); reintroduce; overload; - procedure LoadFromStream(Stream: TStream); overload; override; - procedure SaveToFile(const Filename: string); override; - procedure SaveToStream(Stream: TStream); override; - end; - - ThtGpGraphics = class; - - ThtGpBitmap = class(ThtGpImage) - public - constructor Create(); overload; override; - constructor Create(W, H: integer); reintroduce; overload; - constructor Create(W, H: integer; Graphics: ThtGpGraphics); reintroduce; overload; - function GetPixel(X, Y: integer): DWord; - procedure SetPixel(X, Y: integer; Color: DWord); - end; - - ThtGpGraphics = class(TObject) // like TCanvas - private - fGraphics: GpGraphics; - procedure DrawSmallStretchedImage(Image: THtGPImage; X, Y, Width, Height: Integer); - public - constructor Create(Handle: HDC); overload; - constructor Create(Image: ThtGpImage); overload; - destructor Destroy; override; - procedure DrawImage(Image: ThtGpImage; X, Y: Integer); overload; - procedure DrawImage(Image: ThtGpImage; X, Y, Width, Height: Integer); overload; - procedure DrawImage(Image: ThtGpImage; x, y, srcx, srcy, srcwidth, srcheight: integer); overload; - procedure DrawImage(Image: ThtGpImage; dx, dy, dw, dh, sx, sy, sw, sh: integer); overload; - procedure Clear(Color: Cardinal); - procedure ScaleTransform(sx, sy: Single); - end; - -procedure CheckInitGDIPlus; -procedure CheckExitGDIPlus; - -{$endif NoGDIPlus} -implementation -{$ifndef NoGDIPlus} - -{$ifdef HasGDIPlus} - uses - GDIPOBJ, GDIPUTIL; -{$else HasGDIPlus} - const - GdiPlusLib = 'GdiPlus.dll'; - UnitPixel = 2; - MatrixOrderPrepend = 0; - Ok : GpStatus = 0; - - type - ARGB = DWORD; -// GpColor = ARGB; - NotificationHookProc = function (out token : ULONG) : GpStatus stdcall; - NotificationUnhookProc = procedure (token : ULONG) stdcall; - - DebugEventLevel = Integer; - DebugEventProc = procedure (level : DebugEventLevel; message_ : PChar) stdcall; - - GdiplusStartupInput = packed record - GdiplusVersion : DWORD; // Must be 1 (or 2 for the Ex version) - DebugEventCallback : DebugEventProc; // Ignored on free builds - SuppressBackgroundThread : BOOL; // FALSE unless you're prepared to call the hook/unhook functions properly - SuppressExternalCodecs : BOOL; // FALSE unless you want GDI+ only to use its internal image codecs. - end; - TGdiplusStartupInput = GdiplusStartupInput; - PGdiplusStartupInput = ^TGdiplusStartupInput; - - GdiplusStartupOutput = record - NotificationHook : NotificationHookProc; - NotificationUnhook : NotificationUnhookProc; - end; - TGdiplusStartupOutput = GdiplusStartupOutput; - PGdiplusStartupOutput = ^TGdiplusStartupOutput; - - GpUnit = Integer; //enumeration - GpMatrixOrder = Integer; -// InterpolationMode = Integer; -// TInterpolationMode = InterpolationMode; -// PGpImageAttributes = Pointer; - ImageAbort = function : BOOL stdcall; - DrawImageAbort = ImageAbort; - - //TRectF = record - // X: Single; - // Y: Single; - // Width: Single; - // Height: Single; - //end; - - //ImageCodecInfo = packed record - // Clsid: TGUID; - // FormatID: TGUID; - // CodecName: PWCHAR; - // DllName: PWCHAR; - // FormatDescription: PWCHAR; - // FilenameExtension: PWCHAR; - // MimeType: PWCHAR; - // Flags: DWORD; - // Version: DWORD; - // SigCount: DWORD; - // SigSize: DWORD; - // SigPattern: PBYTE; - // SigMask: PBYTE; - //end; - //TImageCodecInfo = ImageCodecInfo; - //PImageCodecInfo = ^TImageCodecInfo; - -const - PixelFormatIndexed = $00010000; // Indexes into a palette - PixelFormatGDI = $00020000; // Is a GDI-supported format - PixelFormatAlpha = $00040000; // Has an alpha component - //PixelFormatPAlpha = $00080000; // Pre-multiplied alpha - PixelFormatExtended = $00100000; // Extended color 16 bits/channel - PixelFormatCanonical = $00200000; - - //PixelFormatUndefined = 0; - //PixelFormatDontCare = 0; - // - //PixelFormat1bppIndexed = (1 or ( 1 shl 8) or PixelFormatIndexed or PixelFormatGDI); - //PixelFormat4bppIndexed = (2 or ( 4 shl 8) or PixelFormatIndexed or PixelFormatGDI); - //PixelFormat8bppIndexed = (3 or ( 8 shl 8) or PixelFormatIndexed or PixelFormatGDI); - //PixelFormat16bppGrayScale = (4 or (16 shl 8) or PixelFormatExtended); - //PixelFormat16bppRGB555 = (5 or (16 shl 8) or PixelFormatGDI); - //PixelFormat16bppRGB565 = (6 or (16 shl 8) or PixelFormatGDI); - //PixelFormat16bppARGB1555 = (7 or (16 shl 8) or PixelFormatAlpha or PixelFormatGDI); - //PixelFormat24bppRGB = (8 or (24 shl 8) or PixelFormatGDI); - //PixelFormat32bppRGB = (9 or (32 shl 8) or PixelFormatGDI); - PixelFormat32bppARGB = (10 or (32 shl 8) or PixelFormatAlpha or PixelFormatGDI or PixelFormatCanonical); - //PixelFormat32bppPARGB = (11 or (32 shl 8) or PixelFormatAlpha or PixelFormatPAlpha or PixelFormatGDI); - //PixelFormat48bppRGB = (12 or (48 shl 8) or PixelFormatExtended); - //PixelFormat64bppARGB = (13 or (64 shl 8) or PixelFormatAlpha or PixelFormatCanonical or PixelFormatExtended); - //PixelFormat64bppPARGB = (14 or (64 shl 8) or PixelFormatAlpha or PixelFormatPAlpha or PixelFormatExtended); - //PixelFormat32bppCMYK = (15 or (32 shl 8)); - //PixelFormatMax = 16; - - var - GdiplusStartup: function(out Token: ULONG; const Input : PGdiplusStartupInput; const Output: PGdiplusStartupOutput): GpStatus stdcall; - GdiplusShutdown: procedure(Token: ULONG) stdcall; - // GpGraphics methods - GdipCreateFromHDC: function(hdc: HDC; out Graphics: GpGraphics): GpStatus stdcall; - GdipScaleWorldTransform: function(graphics: GpGraphics; sx, sy: Single; order: GpMatrixOrder): GpStatus stdcall; - - //GdipGetInterpolationMode: function(graphics: GpGraphics; var interpolationMode: TInterpolationMode): GpStatus stdcall; - //GdipSetInterpolationMode: function(graphics: GpGraphics; interpolationMode: TInterpolationMode): GpStatus stdcall; - - GdipGraphicsClear: function(Graphics: GpGraphics; Color: ARGB): GpStatus stdcall; - GdipDeleteGraphics: function(Graphics: GpGraphics): GpStatus stdcall; - - // GpBitmap methods - - //GdipCreateBitmapFromStream: function(stream: ISTREAM; out bitmap: GpBitmap): GpStatus stdcall; - GdipCreateBitmapFromScan0: function(width, height, stride: Integer; pixelformat: PixelFormat; scan0: Pointer; out bitmap: GpBitmap): GpStatus stdcall; - GdipCreateBitmapFromGraphics: function(width, height: Integer; target: GpGraphics; out bitmap: GpBitmap): GpStatus; stdcall; - //GdipCreateHBITMAPFromBitmap: function(bitmap: GpBitmap; out hbmReturn: HBITMAP; background: TARGB): GpStatus stdcall; - - GdipBitmapGetPixel: function(bitmap: GpBitmap; x, y: Integer; var color: ARGB): GpStatus; stdcall; - GdipBitmapSetPixel: function(bitmap: GpBitmap; x, y: Integer; color: ARGB): GpStatus stdcall; - - // GpImage methods - - GdipLoadImageFromFile: function(const FileName: PWideChar; out Image: GpImage): GpStatus stdcall; - GdipLoadImageFromStream: function(stream: ISTREAM; out image: GpImage): GpStatus stdcall; - - GdipGetImageWidth: function(Image: GpImage; var Width: Cardinal): GpStatus stdcall; - GdipGetImageHeight: function(Image: GpImage; var Height: Cardinal): GpStatus stdcall; - - GdipDisposeImage: function(Image: GpImage): GpStatus stdcall; - - // GpGraphics and GpImage methods - - GdipGetImageGraphicsContext: function(Image: GpImage; out graphics: GpGraphics): GpStatus stdcall; - - //GdipDrawImageI: function(Graphics : GpGraphics; Image : PGpImage; X, Y: Integer): GpStatus stdcall; - GdipDrawImageRectI: function(graphics: GpGraphics; image: GpImage; x, y, width, height: Integer): GPSTATUS; stdcall; - GdipDrawImageRectRectI: function(graphics: GpGraphics; image: GpImage; - dstx, dsty, dstwidth, dstheight, srcx, srcy, srcwidth, srcheight : Integer; - srcUnit : GpUnit; imageAttributes: GpImageAttributes; - callback: DrawImageAbort; callbackData: Pointer): GpStatus; stdcall; - - GdipDrawImagePointRect: function(graphics: GpGraphics; image: GpImage; x, y, srcX, srcY, srcWidth, srcHeight: Single; srcUnit: GpUnit): GpStatus; stdcall; - - //-- BG ---------------------------------------------------------- 18.08.2013 -- - function GetStatus(AErr: GpStatus): String; - begin - Result := Format('%d', [AErr]); - end; - -function GetPixelFormatSize(const pixfmt : PixelFormat) : Cardinal; {$ifdef UseInline} inline; {$endif} -begin - Result := (pixfmt shr 8) and $ff; -end; - -function IsIndexedPixelFormat(const pixfmt : PixelFormat) : Boolean; {$ifdef UseInline} inline; {$endif} -begin - Result := (pixfmt and PixelFormatIndexed) <> 0; -end; - -function IsAlphaPixelFormat(const pixfmt : PixelFormat) : Boolean; {$ifdef UseInline} inline; {$endif} -begin - Result := (pixfmt and PixelFormatAlpha) <> 0; -end; - -function IsExtendedPixelFormat(const pixfmt : PixelFormat) : Boolean; {$ifdef UseInline} inline; {$endif} -begin - Result := (pixfmt and PixelFormatExtended) <> 0; -end; - -function IsCanonicalPixelFormat(const pixfmt : PixelFormat) : Boolean; {$ifdef UseInline} inline; {$endif} -begin - Result := (pixfmt and PixelFormatCanonical) <> 0; -end; - -{$endif HasGDIPlus} - -type - EGDIPlus = class(Exception); - -resourcestring - SGDIError = '%s GDI error %s'; - SCannotCreateGraphics = 'Can''t Create Graphics.'; - -procedure GDICheck(const AProc : String; const AErr : GpStatus); -begin - if AErr <> Ok then - raise EGDIPlus.CreateFmt(SGDIError, [AProc, GetStatus(AErr)]); -end; - -{ ThtGpGraphics } - -constructor ThtGpGraphics.Create(Handle: HDC); -begin - inherited Create; - GDICheck(SCannotCreateGraphics, GdipCreateFromHDC(Handle, fGraphics)); -end; - -constructor ThtGpGraphics.Create(Image: ThtGpImage); -begin - inherited Create; - GDICheck(SCannotCreateGraphics, GdipGetImageGraphicsContext(Image.fHandle, fGraphics)); -end; - -destructor ThtGpGraphics.Destroy; -begin - if fGraphics <> nil then - {GDICheck('ThtGpGraphics.Destroy',} GdipDeleteGraphics(fGraphics) {)}; - inherited; -end; - -procedure ThtGpGraphics.DrawImage(Image: THtGPImage; X, Y, Width, Height: Integer); -begin - if ((Image.Width <= 10) and (Width > Image.Width)) or ((Image.Height <= 10) and (Height > Image.Height)) then - DrawSmallStretchedImage(Image, X, Y, Width, Height) - else - //BG, 22.11.2016: calling GdipDrawImageRectI() tents to skip the right and bottom parts of the image. - //GDICheck('ThtGpGraphics.DrawImage', GdipDrawImageRectI(fGraphics, Image.fHandle, X, Y, Width, Height)); - DrawImage(Image, X, Y, Width, Height, 0, 0, Image.Width + 1, Image.Height + 1); -end; - -procedure ThtGpGraphics.DrawSmallStretchedImage(Image: THtGPImage; X, Y, Width, Height: Integer); -{when a small image is getting enlarged, add a row and column to it copying - the last row/column to the new row/column. This gives much better interpolation.} -//const -// NearestNeighbor = 5; -var - g1, g2: ThtGpGraphics; - BM1, BM2: ThtGpBitmap; - W, H: integer; -begin - {new bitmap with extra row and column} - W := Image.Width + 1; - H := Image.Height + 1; - BM1 := THtGpBitmap.Create(W, H); - g1 := THtGpGraphics.Create(BM1); - try - {draw the original image to BM1} - g1.DrawImage(Image, 0, 0); - {copy the additional column inside BM1} - g1.DrawImage(BM1, W - 1, 0, 1, H - 1, W - 2, 0, 1, H - 1); - {copy the additional row incl. additional pixel inside BM1} - g1.DrawImage(BM1, 0, H - 1, W, 1, 0, H - 2, W, 1); - BM2 := ThtGpBitmap.Create(Width, Height); - g2 := ThtGpGraphics.Create(BM2); - try - // BG, 25.12.2011: Issue 59: Image scaling error - // - With InterpolationMode = NearestNeighbor only 50% of the stretch is visible. - // - Not setting it stretches the small image to the full width/height. - // GdipSetInterpolationMode(g2.fGraphics, NearestNeighbor); - {now draw the image stretched where needed} - g2.DrawImage(BM1, 0, 0, Width, Height, 0, 0, Image.Width, Image.Height); - DrawImage(BM2, X, Y); {now draw the stretched image} - finally - g2.Free; - BM2.Free; - end; - finally - g1.Free; - BM1.Free; - end; -end; - -procedure ThtGpGraphics.DrawImage(Image: THtGPImage; X, Y: Integer); -begin - GDICheck('ThtGpGraphics.DrawImage', GdipDrawImageRectI(fGraphics, Image.fHandle, X, Y, Image.Width, Image.Height)); -end; - -procedure THtGPGraphics.DrawImage(Image: ThtGpImage; x, y, - srcx, srcy, srcwidth, srcheight: integer); -begin - GDICheck('ThtGpGraphics.DrawImage',GdipDrawImagePointRect(fGraphics, Image.fHandle, x, y, - srcx, srcy, srcwidth, srcheight, UnitPixel)); -end; - -procedure THtGPGraphics.DrawImage(Image: ThtGpImage; dx, dy, dw, dh, sx, sy, sw, sh: integer); -begin - GDICheck('ThtGpGraphics.DrawImage', GdipDrawImageRectRectI(fGraphics, Image.fHandle, dx, dy, dw, dh, - sx, sy, sw, sh, UnitPixel, nil, nil, nil)); -end; - -procedure ThtGpGraphics.Clear(Color: Cardinal); -begin - GDICheck('ThtGpGraphics.Clear', GdipGraphicsClear(fGraphics, Color)); -end; - -procedure THtGPGraphics.ScaleTransform(sx, sy: Single); -begin - GDICheck('ThtGpGraphics.DrawImage', GdipScaleWorldTransform(fGraphics, sx, sy, MatrixOrderPrepend)); -end; - -{ ThtGpImage } - -destructor ThtGpImage.Destroy; -begin - fBitmap.Free; - if fHandle <> nil then - GdipDisposeImage(fHandle); - if Length(fFilename) > 0 then - DeleteFile(fFilename); - inherited; -end; - -procedure ThtGpImage.Draw(ACanvas: TCanvas; const Rect: TRect); -var - g: ThtGpGraphics; -begin - g := ThtGpGraphics.Create(ACanvas.Handle); - try - g.DrawImage(Self, Rect.Left, Rect.Top, Rect.Right - Rect.Left, Rect.Bottom - Rect.Top, 0, 0, Width, Height); - finally - g.Free; - end; -end; - -function ThtGpImage.GetHeight: Integer; -begin - if fHeight = 0 then - GDICheck('ThtGpImage.GetHeight', GdipGetImageHeight(fHandle, fHeight)); - Result := fHeight; -end; - -function ThtGpImage.GetWidth: Integer; -begin - if fWidth = 0 then - GDICheck('ThtGpImage.GetWidth', GdipGetImageWidth(fHandle, fWidth)); - Result := fWidth; -end; - -//-- BG ---------------------------------------------------------- 31.08.2015 -- -procedure ThtGpImage.LoadFromClipboardFormat( -{$ifdef LCL} - FormatID: TClipboardFormat -{$else} - AFormat: Word; AData: THandle; APalette: HPALETTE -{$endif} -); -begin - GDICheck('ThtGpImage.LoadFromClipboardFormat', NotImplemented ); -end; - -procedure ThtGpImage.LoadFromFile(const Filename: String); -var - err: GpStatus; -begin - err := GdipLoadImageFromFile(PWideChar(WideString(FileName)), fHandle); - if err <> Ok then - if GetLastError = 2 then - raise EGDIPlus.CreateFmt('Image file "%s" not found. GDI error %s', [FileName, GetStatus(err)]) - else - raise EGDIPlus.CreateFmt('Can''t load image file "%s". GDI error %s', [FileName, GetStatus(err)]); -// if TmpFile then - fFilename := Filename; -end; - -procedure ThtGpImage.LoadFromStream(IStr: IStream); -begin - GDICheck('Can''t load image stream.', GdipLoadImageFromStream(IStr, fHandle)); -end; - -//-- BG ---------------------------------------------------------- 01.04.2012 -- -procedure ThtGpImage.LoadFromStream(Stream: TStream); -// thanks to Sérgio Alexandre for this method. -var - Handle: HGLOBAL; - Ptr: Pointer absolute Handle; - IStr: IStream; -begin - Handle := GlobalAlloc(GPTR, Stream.Size); - if Handle <> 0 then - begin - Stream.Read(Ptr^, Stream.Size); - CreateStreamOnHGlobal(Handle, True, IStr); - LoadFromStream(IStr); - end; -end; - -//-- BG ---------------------------------------------------------- 31.08.2015 -- -procedure ThtGpImage.SaveToClipboardFormat( -{$ifdef LCL} - FormatID: TClipboardFormat -{$else} - var AFormat: Word; var AData: THandle; var APalette: HPALETTE -{$endif} -); -begin - GDICheck('ThtGpImage.SaveToClipboardFormat', NotImplemented ); -end; - -//-- BG ---------------------------------------------------------- 31.08.2015 -- -procedure ThtGpImage.SaveToFile(const Filename: string); -begin - GDICheck('Can''t save to file', NotImplemented {GdipSaveImageToFile(fhandle, PWideChar(FileName), , )} ); -end; - -//-- BG ---------------------------------------------------------- 31.08.2015 -- -procedure ThtGpImage.SaveToStream(Stream: TStream); -begin - GDICheck('Can''t save to stream', NotImplemented {GdipSaveImageToStream(fhandle, IStreamOfStream, , )} ); -end; - -//-- BG ---------------------------------------------------------- 31.08.2015 -- -procedure ThtGpImage.SetHeight(Value: Integer); -begin - GDICheck('ThtGpImage.SetHeight', NotImplemented ); -end; - -//-- BG ---------------------------------------------------------- 31.08.2015 -- -procedure ThtGpImage.SetWidth(Value: Integer); -begin - GDICheck('ThtGpImage.SetWidth', NotImplemented ); -end; - -function ThtGpImage.GetBitmap: TBitmap; -var - g: ThtGpGraphics; -begin - if fBitmap = nil then - fBitmap := TBitmap.Create; - Result := fBitmap; - Result.Width := GetWidth; - Result.Height := GetHeight; - PatBlt(Result.Canvas.Handle, 0, 0, Result.Width, Result.Height, Whiteness); - g := ThtGpGraphics.Create(Result.Canvas.Handle); - g.DrawImage(Self, 0, 0, Result.Width, Result.Height); - g.Free; -end; - -function ThtGpImage.GetEmpty: Boolean; -begin - Result := fHandle = nil; -end; - -constructor ThtGpBitmap.Create; -begin - inherited Create; -end; - -constructor ThtGpBitmap.Create(W, H: integer); -begin - inherited Create; - GDICheck(Format('Can''t create bitmap of size %d x %d.', [W, H]), GdipCreateBitmapFromScan0(W, H, 0, PixelFormat32bppARGB, nil, fHandle)); -end; - -constructor ThtGpBitmap.Create(W, H: integer; Graphics: ThtGpGraphics); -begin - inherited Create; - GDICheck(Format('Can''t create bitmap of size %d x %d from graphics.', [W, H]), GdipCreateBitmapFromGraphics(W, H, Graphics.fGraphics, fHandle)); -end; - -//procedure ThtGpBitmap.LoadFromStream(IStr: IStream); -//begin -// GDICheck('Can''t create bitmap from stream.', GdipCreateBitmapFromStream(IStr, fHandle)); -//end; -// -////-- BG ---------------------------------------------------------- 01.04.2012 -- -//procedure ThtGpBitmap.LoadFromStream(Stream: TStream); -//begin -// LoadFromStream(IStreamFromStream(Stream)); -//end; - -function ThtGpBitmap.GetPixel(X, Y: integer): DWord; -begin - GDICheck('ThtGpBitmap.GetPixel', GdipBitmapGetPixel(fHandle, X, Y, Result)); -end; - -procedure ThtGpBitmap.SetPixel(X, Y: integer; Color: DWord); -begin - GDICheck('ThtGpBitmap.SetPixel', GdipBitmapSetPixel(fHandle, X, Y, Color)); -end; - -var - GDIPlusCount: integer; -{$IFdef Compiler27_Plus} // SYDNEY - InitToken: NativeUInt; -{$ELSE} - InitToken: DWord; -{$endif} - Startup: GdiplusStartupInput; -{$ifndef HasGDIPlus} - LibHandle: THandle; -{$endif} - -procedure CheckInitGDIPlus; -var - Err: GpStatus; -begin - if GDIPlusCount = 0 then - begin -{$ifndef HasGDIPlus} - LibHandle := LoadLibrary(GdiPlusLib); - if LibHandle <> 0 then - begin - @GdiplusStartup := GetProcAddress(LibHandle, 'GdiplusStartup'); - @GdiplusShutdown := GetProcAddress(LibHandle, 'GdiplusShutdown'); - @GdipDeleteGraphics := GetProcAddress(LibHandle, 'GdipDeleteGraphics'); - @GdipCreateFromHDC := GetProcAddress(LibHandle, 'GdipCreateFromHDC'); - //@GdipDrawImageI := GetProcAddress(LibHandle, 'GdipDrawImageI'); - @GdipDrawImageRectI := GetProcAddress(LibHandle, 'GdipDrawImageRectI'); - @GdipLoadImageFromFile := GetProcAddress(LibHandle, 'GdipLoadImageFromFile'); - @GdipLoadImageFromStream := GetProcAddress(LibHandle, 'GdipLoadImageFromStream'); - //@GdipCreateBitmapFromStream := GetProcAddress(LibHandle, 'GdipCreateBitmapFromStream'); - @GdipDisposeImage := GetProcAddress(LibHandle, 'GdipDisposeImage'); - @GdipGetImageWidth := GetProcAddress(LibHandle, 'GdipGetImageWidth'); - @GdipGetImageHeight := GetProcAddress(LibHandle, 'GdipGetImageHeight'); - @GdipGetImageGraphicsContext := GetProcAddress(LibHandle, 'GdipGetImageGraphicsContext'); - @GdipGraphicsClear := GetProcAddress(LibHandle, 'GdipGraphicsClear'); - @GdipCreateBitmapFromScan0 := GetProcAddress(LibHandle, 'GdipCreateBitmapFromScan0'); - @GdipDrawImagePointRect := GetProcAddress(LibHandle, 'GdipDrawImagePointRect'); - @GdipScaleWorldTransform := GetProcAddress(LibHandle, 'GdipScaleWorldTransform'); - @GdipCreateBitmapFromGraphics := GetProcAddress(LibHandle, 'GdipCreateBitmapFromGraphics'); - @GdipBitmapGetPixel := GetProcAddress(LibHandle, 'GdipBitmapGetPixel'); - @GdipDrawImageRectRectI := GetProcAddress(LibHandle, 'GdipDrawImageRectRectI'); - //@GdipCreateHBITMAPFromBitmap := GetProcAddress(LibHandle, 'GdipCreateHBITMAPFromBitmap'); - - //@GdipSetInterpolationMode := GetProcAddress(LibHandle, 'GdipSetInterpolationMode'); - //@GdipGetInterpolationMode := GetProcAddress(LibHandle, 'GdipGetInterpolationMode'); - @GdipBitmapSetPixel := GetProcAddress(LibHandle, 'GdipBitmapSetPixel'); - - FillChar(Startup, sizeof(Startup), 0); - Startup.GdiplusVersion := 1; - Err := GdiPlusStartup(InitToken, @Startup, nil); - GDIPlusActive := Err = Ok; - if not GDIPlusActive then - begin - FreeLibrary(LibHandle); - Libhandle := 0; - end; - end; -{$else} - FillChar(Startup, sizeof(Startup), 0); - Startup.GdiplusVersion := 1; - Err := GdiPlusStartup(InitToken, @Startup, nil); - GDIPlusActive := Err = Ok; -{$endif HasGDIPlus} - end; - Inc(GDIPlusCount); -end; - -procedure CheckExitGDIPlus; -begin - Dec(GDIPlusCount); - if GDIPlusCount = 0 then - begin - if GDIPlusActive then - begin - GdiplusShutdown(InitToken); - GDIPlusActive := False; - end; -{$ifndef HasGDIPlus} - if LibHandle <> 0 then - begin - FreeLibrary(LibHandle); - LibHandle := 0; - end; -{$endif HasGDIPlus} - end; -end; - -{$endif NoGDIPlus} -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/HSLUtils.pas b/CORE/Source/Plugins/Htmlviewer/source/HSLUtils.pas deleted file mode 100644 index ad1de33c4..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/HSLUtils.pas +++ /dev/null @@ -1,247 +0,0 @@ -{ -Version 11.3 -Copyright 2012 by J. Peter Mugaas - -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. - -Note that the source modules HTMLGIF1.PAS and DITHERUNIT.PAS -are covered by separate copyright notices located in those modules. -} -//------------------------------------------------------------------------------ -// -// HSL - RGB colour model conversions -// -// These four functions can be used to convert between the RGB and HSL colour -// models. RGB values are represented using the 0-255 Windows convention and -// always encapsulated in a TColor 32 bit value. HSL values are available as -// either 0 to 1 floating point (double) values or as a 0 to a defined integer -// value. The colour common dialog box uses 0 to 240 by example. -// -// The code is based on that found (in C) on: -// -// http:/www.r2m.com/win-developer-faq/graphics/8.html -// -// Grahame Marsh 12 October 1997 -// -// Freeware - you get it for free, I take nothing, I make no promises! -// -// Please feel free to contact me: grahame.s.marsh@corp.courtaulds.co.uk -// -// Revison History: -// Version 1.00 - initial release 12-10-1997 -// -//------------------------------------------------------------------------------ - -{Additions from J. Peter Mugaas -release: 2-16-2012 -} -unit HSLUtils; - -interface - -uses -{$ifdef MSWindows} - Windows, -{$else MSWindows} - Types, -{$endif MSWindows} - vcl.Graphics; - -var - HSLRange: integer = 240; - -// convert a HSL value into a RGB in a TColor -// HSL values are 0.0 to 1.0 double -function HSLtoRGB (H, S, L: double): TColor; overload; -function HSLtoRGB (H : Integer; S, L: double): TColor; overload; -function HSLtoRGB (H, S, L: Integer): TColor; overload; - -// convert a HSL value into a RGB in a TColor -// SL values are 0 to the HSLRange variable -// H value is to HSLRange-1 -function HSLRangeToRGB (H, S, L : integer): TColor; - -// convert a RGB value (as TColor) into HSL -// HSL values are 0.0 to 1.0 double -procedure RGBtoHSL (RGB: TColor; var H, S, L : double); - -// convert a RGB value (as TColor) into HSL -// SL values are 0 to the HSLRange variable -// H value is to HSLRange-1 -procedure RGBtoHSLRange (RGB: TColor; var H, S, L : integer); - -implementation -{$ifdef MSWindows} -{$else MSWindows} -function GetRValue(RGB: TColor): Byte; -begin - Result := Byte(RGB); -end; - -function GetGValue(RGB: TColor): Byte; -begin - Result := Byte(RGB shr 8); -end; - -function GetBValue(RGB: TColor): Byte; -begin - Result := Byte(RGB shr 16); -end; - -function RGB(R, G, B: Cardinal): TColor; -begin - Result := R + G shl 8 + LongWord(b) shl 16; -end; - -{$endif MSWindows} - -function HSLtoRGB (H, S, L: double): TColor; -var - M1, M2: double; - - function HueToColourValue (Hue: double) : byte; - var - V : double; - begin - if Hue < 0 then - Hue := Hue + 1 - else - if Hue > 1 then - Hue := Hue - 1; - - if 6 * Hue < 1 then - V := M1 + (M2 - M1) * Hue * 6 - else - if 2 * Hue < 1 then - V := M2 - else - if 3 * Hue < 2 then - V := M1 + (M2 - M1) * (2/3 - Hue) * 6 - else - V := M1; - Result := round (255 * V) - end; - -var - R, G, B: byte; -begin - if S = 0 then - begin - R := round (255 * L); - G := R; - B := R - end else begin - if L <= 0.5 then - M2 := L * (1 + S) - else - M2 := L + S - L * S; - M1 := 2 * L - M2; - R := HueToColourValue (H + 1/3); - G := HueToColourValue (H); - B := HueToColourValue (H - 1/3) - end; - - Result := RGB (R, G, B) -end; - -function HSLtoRGB (H : Integer; S, L: double): TColor; overload; -begin - Result := HSLtoRGB( H / 360, S, L); -end; - -function HSLtoRGB (H, S, L: Integer): TColor; overload; -begin - Result := HSLtoRGB(H,S / 100, L / 100); -end; - -function HSLRangeToRGB (H, S, L : integer): TColor; -begin - Result := HSLToRGB (H / (HSLRange-1), S / HSLRange, L / HSLRange) -end; - -// Convert RGB value (0-255 range) into HSL value (0-1 values) - -procedure RGBtoHSL (RGB: TColor; var H, S, L : double); - - function Max (a, b : double): double; - begin - if a > b then - Result := a - else - Result := b - end; - - function Min (a, b : double): double; - begin - if a < b then - Result := a - else - Result := b - end; - -var - R, G, B, D, Cmax, Cmin: double; -begin - R := GetRValue (RGB) / 255; - G := GetGValue (RGB) / 255; - B := GetBValue (RGB) / 255; - Cmax := Max (R, Max (G, B)); - Cmin := Min (R, Min (G, B)); - -// calculate luminosity - L := (Cmax + Cmin) / 2; - - if Cmax = Cmin then // it's grey - begin - H := 0; // it's actually undefined - S := 0 - end else begin - D := Cmax - Cmin; - -// calculate Saturation - if L < 0.5 then - S := D / (Cmax + Cmin) - else - S := D / (2 - Cmax - Cmin); - -// calculate Hue - if R = Cmax then - H := (G - B) / D - else - if G = Cmax then - H := 2 + (B - R) /D - else - H := 4 + (R - G) / D; - - H := H / 6; - if H < 0 then - H := H + 1 - end -end; - -procedure RGBtoHSLRange (RGB: TColor; var H, S, L : integer); -var - Hd, Sd, Ld: double; -begin - RGBtoHSL (RGB, Hd, Sd, Ld); - H := round (Hd * (HSLRange-1)); - S := round (Sd * HSLRange); - L := round (Ld * HSLRange); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/HTMLCompEdit.pas b/CORE/Source/Plugins/Htmlviewer/source/HTMLCompEdit.pas deleted file mode 100644 index 51fcfaa4c..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/HTMLCompEdit.pas +++ /dev/null @@ -1,96 +0,0 @@ -{ -Version 11 -Copyright (c) 1995-2008 by L. David Baldwin, 2008-2010 by HtmlViewer Team - -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. - -Note that the source modules HTMLGIF1.PAS and DITHERUNIT.PAS -are covered by separate copyright notices located in those modules. -} - -{$I htmlcons.inc} - -unit HTMLCompEdit; - -interface - -uses - SysUtils, Windows, Messages, Classes, vcl.Controls, vcl.StdCtrls, - vcl.Dialogs, vcl.ExtCtrls, - DesignIntf, DesignWindows, DesignEditors; - -type - - THtComponentEditor = class(TComponentEditor) - function GetVerbCount: Integer; override; - function GetVerb(index: Integer): string; override; - procedure ExecuteVerb(index: Integer); override; - end; - - THTMLEditor = class(THtComponentEditor) - end; - - TFMVEditor = class(THtComponentEditor) - end; - - TFMBEditor = class(THtComponentEditor) - end; - -procedure Register; - -implementation - -uses - htmlview, htmlun2, framview, frambrwz; - -procedure Register; -begin - RegisterComponentEditor(THTMLViewer, THTMLEditor); - RegisterComponentEditor(TFrameViewer, TFMVEditor); - RegisterComponentEditor(TFrameBrowser, TFMBEditor); -end; - -{ THtComponentEditor } - -function THtComponentEditor.GetVerbCount: integer; -begin - Result := 1; -end; - -function THtComponentEditor.GetVerb(index: Integer): string; -begin - Result := 'About...'; -end; - -procedure THtComponentEditor.ExecuteVerb(index: integer); -begin - MessageDlg( - GetComponent.ClassName + ', Version (V) ' + VersionNo + #13#13 + - 'Copyright (C) 2011-2012 by the HtmlViewer Project Team'#13 + - ' Bernd Gabriel'#13 + - ' J. Peter Mugaas'#13#13 + - 'Copyright (C) 2008-2010 by the HtmlViewer Project Team'#13 + - ' Patrick van Logchem'#13 + - ' Sebastian Zierer'#13 + - ' Arvid Winkelsdorf'#13 + - ' Bernd Gabriel'#13#13 + - 'Copyright (C) 1995-2008 by L. David Baldwin', - mtInformation, [mbOk], 0); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/HTMLGif2.pas b/CORE/Source/Plugins/Htmlviewer/source/HTMLGif2.pas deleted file mode 100644 index 6a6915c41..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/HTMLGif2.pas +++ /dev/null @@ -1,370 +0,0 @@ -{ -Version 11.7 -Copyright (c) 1995-2008 by L. David Baldwin -Copyright (c) 2008-2010 by HtmlViewer Team -Copyright (c) 2011-2016 by Bernd Gabriel - -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. - -Note that the source modules HTMLGIF1.PAS and DITHERUNIT.PAS -are covered by separate copyright notices located in those modules. -} - -{$I htmlcons.inc} - -unit HTMLGif2; - -interface - -uses -{$ifdef LCL} - LclIntf, IntfGraphics, FpImage, LclType, HtmlMisc, -{$else} - Windows, mmSystem, -{$endif} - SysUtils, Classes, vcl.Graphics, vcl.Controls, vcl.ExtCtrls, Math, - HtmlGlobals, htmlgif1; - -type - - TDisposalType = ( - dtUndefined, {Take no action} - dtDoNothing, {Leave graphic, next frame goes on top of it} - dtToBackground, {Restore original background for next frame} - dtToPrevious); {Restore image as it existed before this frame} - - TgfFrame = class - private - { private declarations } - frLeft: Integer; - frTop: Integer; - frWidth: Integer; - frHeight: Integer; - - frDelay: Integer; - frDisposalMethod: TDisposalType; - TheEnd: boolean; {end of what gets copied} - - public - constructor Create; - constructor CreateCopy(Item: TgfFrame); - destructor Destroy; override; - end; - - TgfFrameList = class(TList) - private - function GetFrame(I: integer): TgfFrame; - public - {note: Frames is 1 based, goes from [1..Count]} - property Frames[I: integer]: TgfFrame read GetFrame; default; - end; - - { TGIFImage } - - TGIFImage = class(ThtBitmap) - private - FAnimated: Boolean; - FImageWidth: Integer; - FImageHeight: Integer; - FCurrentFrame: Integer; - FNumFrames: Integer; - FNumIterations: Integer; - FTransparent: Boolean; - FVisible: Boolean; - - TheEnd: Boolean; {copy to here} - - FAnimate: Boolean; - FStretchedRect: TRect; - WasDisposal: TDisposalType; - - Strip: ThtBitmap; - Frames: TgfFrameList; - - CurrentIteration: Integer; - LastTime: DWord; - CurrentInterval: DWord; - - procedure SetAnimate(AAnimate: Boolean); - procedure SetCurrentFrame(AFrame: Integer); - - procedure NextFrame(OldFrame: Integer); - procedure SetTransparent(AValue: Boolean); - - public - ShowIt: Boolean; - IsCopy: Boolean; {set if this is a copy of one in Cache} - - constructor Create; override; - constructor CreateCopy(Item: TGIFImage); - destructor Destroy; override; - - procedure LoadFromStream(Stream: TStream); override; - - procedure Draw(Canvas: TCanvas; const ARect: TRect); override; - - property IsAnimated: Boolean read FAnimated; - property IsTransparent: Boolean read FTransparent write SetTransparent; - property NumFrames: Integer read FNumFrames; - property NumIterations: Integer read FNumIterations; - - procedure CheckTime(WinControl: TWinControl); - - property Animate: Boolean read FAnimate write SetAnimate; - property CurrentFrame: Integer read FCurrentFrame write SetCurrentFrame; - property Visible: Boolean read FVisible write FVisible; - end; - -implementation - -{----------------TgfFrame.Create} - -constructor TgfFrame.Create; -begin - inherited Create; -end; - -constructor TgfFrame.CreateCopy(Item: TgfFrame); -begin - inherited Create; - System.Move(Item.frLeft, frLeft, PtrSub(@TheEnd, @frLeft)); -end; - -{----------------TgfFrame.Destroy} - -destructor TgfFrame.Destroy; -begin - inherited Destroy; -end; - -{----------------TGIFImage.Create} - -constructor TGIFImage.Create; -begin - inherited Create; - FVisible := True; - FCurrentFrame := 1; - Frames := TgfFrameList.Create; - CurrentIteration := 1; -end; - -constructor TGIFImage.CreateCopy(Item: TGIFImage); -var - I: integer; -begin - inherited Create; - Assign(Item); - FImageWidth := Item.FImageWidth; - FImageHeight := Item.FImageHeight; - System.Move(Item.FAnimated, FAnimated, PtrSub(@TheEnd, @FAnimated)); - IsCopy := True; - - Strip := ThtBitmap.Create; - Strip.Assign(Item.Strip); - - Frames := TgfFrameList.Create; - for I := 1 to FNumFrames do - Frames.Add(TgfFrame.CreateCopy(Item.Frames[I])); - FCurrentFrame := 1; - CurrentIteration := 1; - if FAnimated then - WasDisposal := dtToBackground; -end; - -{----------------TGIFImage.Destroy} - -destructor TGIFImage.Destroy; -var - I: Integer; -begin - for I := Frames.Count downto 1 do - Frames[I].Free; - Frames.Free; - Strip.Free; - inherited Destroy; -end; - -{----------------TGIFImage.Draw} - -procedure TGIFImage.Draw(Canvas: TCanvas; const ARect: TRect); -var - SRect: TRect; - ALeft: integer; -begin - if FVisible and (FNumFrames > 0) then - begin - FStretchedRect := ARect; - with Frames[FCurrentFrame] do - begin - ALeft := (FCurrentFrame - 1) * Width; - SRect := Rect(ALeft, 0, ALeft + Width, Height); {current frame location in Strip bitmap} - end; - - Canvas.CopyMode := cmSrcCopy; - {draw the correct portion of the strip} - SetStretchBltMode(Canvas.Handle, ColorOnColor); - Strip.StretchDraw(Canvas, FStretchedRect, SRect); - end; -end; - -{----------------TGifImage.CheckTime} - -procedure TGIFImage.CheckTime(WinControl: TWinControl); -var - ThisTime: DWord; -begin - if not FAnimate then - Exit; - - ThisTime := timeGetTime; - if ThisTime - LastTime < CurrentInterval then - Exit; - - LastTime := ThisTime; - - if (FCurrentFrame = FNumFrames) then - begin - if (FNumIterations > 0) and (CurrentIteration >= FNumIterations) then - begin - SetAnimate(False); - Exit; - end; - Inc(CurrentIteration); - end; - NextFrame(FCurrentFrame); - Inc(FCurrentFrame); - if (FCurrentFrame > FNumFrames) or (FCurrentFrame <= 0) then - FCurrentFrame := 1; - - InvalidateRect(WinControl.Handle, @FStretchedRect, True); - - CurrentInterval := Max(Frames[FCurrentFrame].frDelay, 1); -end; - -{----------------TGIFImage.SetAnimate} - -procedure TGIFImage.SetAnimate(AAnimate: Boolean); -begin - if AAnimate = FAnimate then - Exit; - - FAnimate := AAnimate; - if AAnimate and (FNumFrames > 1) then - begin - CurrentInterval := Max(Frames[FCurrentFrame].frDelay, 1); - LastTime := timeGetTime; - end; -end; - -{----------------TGIFImage.SetCurrentFrame} - -procedure TGIFImage.SetCurrentFrame(AFrame: Integer); -begin - if AFrame = FCurrentFrame then - Exit; - - NextFrame(FCurrentFrame); - if AFrame > FNumFrames then - FCurrentFrame := 1 - else if AFrame < 1 then - FCurrentFrame := FNumFrames - else - FCurrentFrame := AFrame; - if FAnimated then - WasDisposal := dtToBackground; -end; - -//-- BG ---------------------------------------------------------- 27.08.2015 -- -procedure TGIFImage.LoadFromStream(Stream: TStream); -var - AGif: TGif; - Frame: TgfFrame; - I: integer; -begin - AGif := TGif.Create; - try - AGif.LoadFromStream(Stream); - - FNumFrames := AGif.ImageCount; - FAnimated := FNumFrames > 1; - FImageWidth := AGif.Width; - FImageHeight := AGif.Height; - FNumIterations := AGif.LoopCount; - if FNumIterations < 0 then {-1 means no loop block} - FNumIterations := 1 - else if FNumIterations > 0 then - Inc(FNumIterations); {apparently this is the convention} - FTransparent := AGif.Transparent; - - Strip := AGif.GetStripBitmap(); - if Strip.Palette <> 0 then - DeleteObject(Strip.ReleasePalette); - Strip.Palette := CopyPalette(ThePalette); - - for I := 0 to FNumFrames - 1 do - begin - Frame := TgfFrame.Create; - try - Frame.frDisposalMethod := TDisposalType(AGif.ImageDisposal[I]); - Frame.frLeft := AGif.ImageLeft[I]; - Frame.frTop := AGif.ImageTop[I]; - Frame.frWidth := AGif.ImageWidth[I]; - Frame.frHeight := AGif.ImageHeight[I]; - Frame.frDelay := Max(30, AGif.ImageDelay[I] * 10); - except - Frame.Free; - raise; - end; - Frames.Add(Frame); - end; - if IsAnimated then - WasDisposal := dtToBackground; - finally - AGif.Free; - end; - - inherited Assign(Strip); - Width := FImageWidth; - Transparent := False; -end; - -{----------------TGIFImage.NextFrame} - -procedure TGIFImage.NextFrame(OldFrame: Integer); -begin - WasDisposal := Frames[OldFrame].frDisposalMethod; -end; - -procedure TGIFImage.SetTransparent(AValue: Boolean); -begin - if FTransparent=AValue then - Exit; - FTransparent:=AValue; - if FMask = nil then - FMask := TBitmap.Create; -end; - -{----------------TgfFrameList.GetFrame} - -function TgfFrameList.GetFrame(I: integer): TgfFrame; -begin - Assert((I <= Count) and (I >= 1), 'Frame index out of range'); - Result := TgfFrame(Items[I - 1]); -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/HTMLSubs.pas b/CORE/Source/Plugins/Htmlviewer/source/HTMLSubs.pas deleted file mode 100644 index 74efd2011..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/HTMLSubs.pas +++ /dev/null @@ -1,16451 +0,0 @@ -{ -Version 11.8 -Copyright (c) 1995-2008 by L. David Baldwin -Copyright (c) 2008-2017 by HtmlViewer Team - -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. - -Note that the source modules HTMLGIF1.PAS and DITHERUNIT.PAS -are covered by separate copyright notices located in those modules. -} - -{$I htmlcons.inc} - -{ -This module is comprised mostly of the various Section object definitions. -As the HTML document is parsed, it is divided up into sections. Some sections -are quite simple, like TParagraphSpace. Others are more complex such as -TSection which can hold a complete paragraph. - -The HTML document is then stored as a list of type ThtDocument, of the various sections. - -Closely related to ThtDocument is TCell. TCell holds the list of sections for -each cell in a Table (the THtmlTable section). In this way each table cell may -contain a document of it's own. - -The Section objects each store relevant data for the section such as the text, -fonts, images, and other info needed for formating. - -Each Section object is responsible for its own formated layout. The layout is -done in the DrawLogic method. Layout for the whole document is done in the -ThtDocument.DoLogic method which essentially just calls all the Section -DrawLogic's. It's only necessary to call ThtDocument.DoLogic when a new -layout is required (when the document is loaded or when its width changes). - -Each Section is also responsible for drawing itself (its Draw method). The -whole document is drawn with the ThtDocument.Draw method. -} - -unit HTMLSubs; - -{-$define DO_BLOCK_INLINE} -{$ifdef DO_BLOCK_INLINE} -{$endif} - -//TODO -oBG, 15.03.2014: support display:inline -{-$define DO_PD_INLINE} -//TODO -oBG, 15.03.2014: support display:inline -{$ifdef DO_PD_INLINE} -{$endif} - -interface - -uses - {$ifdef UseInline} - HtmlCaches, - {$endif} -{$ifdef VCL} - Windows, - {$ifndef Compiler28_Plus} - EncdDecd, - {$endif} -{$endif} - Messages, vcl.Graphics, vcl.Controls, vcl.ExtCtrls, Classes, SysUtils, Variants, vcl.Forms, Math, Contnrs, vcl.ComCtrls, -{$ifdef LCL} - LclIntf, LclType, Types, HtmlMisc, -{$endif} - HtmlGlobals, - HtmlFonts, - StyleTypes, - HtmlImages, // use before HTMLUn2, as both define a TGetImageEvent, but we need the one of HTMLUn2 here. - HTMLUn2, - HtmlBuffer, - HtmlSymb, - StyleUn, - HTMLGif2; - -type - TBlock = class; - TSection = class; - TCellBasic = class; - ThtDocument = class; - -//------------------------------------------------------------------------------ -// TFontObj, contains an atomic font info for a part of a section. -// TFontList, contains and owns all font infos of a section -// TLinkList, references but does not own all link infos of a document. The objects are still owned by their sections. -//------------------------------------------------------------------------------ - - ThtTabControl = class(TWinControl) - private - procedure WMGetDlgCode(var Message: TMessage); message WM_GETDLGCODE; - protected - property OnEnter; - property OnExit; - property TabStop; - property OnKeyUp; - public - destructor Destroy; override; - end; - - TFontList = class; - - TFontObj = class(TFontObjBase) {font information} - // BG, 10.08.2013: deprecated - // Is used to handle the link states, but the full range of CSS - // properties can be applied to :link, :hover, :visited, etc. - // - private -{$IFNDEF NoTabLink} - FSection: TSection; // only used if NoTabLink is not defined. -{$ENDIF} - FVisited, FHover: Boolean; - Title: ThtString; - FYValue: Integer; - Active: Boolean; - procedure SetVisited(Value: Boolean); - procedure SetHover(Value: Boolean); - function GetURL: ThtString; - procedure SetAllHovers(List: TFontList; Value: Boolean); - procedure CreateFIArray; -{$IFNDEF NoTabLink} - procedure EnterEvent(Sender: TObject); - procedure ExitEvent(Sender: TObject); - procedure CreateTabControl(TabIndex: Integer); - procedure AKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); - procedure AssignY(Y: Integer); -{$ENDIF} - function GetFontInfoIndex: FIIndex; - property FontInfoIndex: FIIndex read GetFontInfoIndex; - public - Pos: Integer; {0..Len Index where font takes effect} - TheFont: ThtFont; - FIArray: TFontInfoArray; - FontHeight, {tmHeight+tmExternalLeading} - tmHeight, - tmMaxCharWidth, - Overhang, - Descent: Integer; - SScript: ThtAlignmentStyle; - TabControl: ThtTabControl; - constructor Create(ASection: TSection; F: ThtFont; Position: Integer); - constructor CreateCopy(ASection: TSection; T: TFontObj); - destructor Destroy; override; - procedure ReplaceFont(F: ThtFont); - procedure ConvertFont(const FI: ThtFontInfo); - procedure FontChanged; - function GetOverhang: Integer; - function GetHeight(var Desc: Integer): Integer; - - property URL: ThtString read GetURL; - property Visited: Boolean read FVisited write SetVisited; - property Hover: Boolean read FHover write SetHover; - property DrawYY: Integer read FYValue; - end; - - // BG, 10.02.2013: owns its objects. - TFontList = class(TFontObjBaseList) {a list of TFontObj's} - private - function GetFont(Index: Integer): TFontObj; {$ifdef UseInline} inline; {$endif} - public - constructor CreateCopy(ASection: TSection; T: TFontList); - function GetFontAt(Posn: Integer; out OHang: Integer): ThtFont; -// function GetFontCountAt(Posn, Leng: Integer): Integer; - function GetFontObjAt(Posn: Integer): TFontObj; overload; - function GetFontObjAt(Posn, Leng: Integer; out Obj: TFontObj): Integer; overload; - procedure Decrement(N: Integer; Document: ThtDocument); - property Items[Index: Integer]: TFontObj read GetFont; default; - end; - - // BG, 10.02.2013: does not own its font objects. - TLinkList = class(TFontList) - public - constructor Create; - end; - -//------------------------------------------------------------------------------ -// THtmlNode is base class for all objects in the HTML document tree. -//------------------------------------------------------------------------------ - - THtmlNode = class(TIDObject) - private - FDocument: ThtDocument; // the document it belongs to - FOwnerBlock: TBlock; // the parental block it is placed in - FOwnerCell: TCellBasic; // the parent's child list it is placed in - //FIds: ThtStringArray; - //FClasses: ThtStringArray; - FAttributes: TAttributeList; - FProperties: TProperties; - FDisplay: ThtDisplayStyle; // how it is displayed - FEmSize, FExSize: Integer; - - function GetSymbol(): TElemSymb; - function GetAttribute(const Name: ThtString): ThtString; - function GetContainingBlock: TBlock; virtual; - function GetProperty(PropIndex: ThtPropIndices): Variant; - function GetContainingBox: TRect; - - function GetClearSpace(IMgr: TIndentManager; Y: Integer): Integer; - - protected - FPositioning: ThtBoxPositionStyle; - FPositions: ThtRectIntegers; // in Pixels - FFloating: ThtAlignmentStyle; - FClearing: ThtClearStyle; - FIndent: Integer; {Indentation of floating object relative to Draw-X} - - procedure GetVMarginArray(var MArray: ThtVMarginArray); - - function TryGetClear(var Clear: ThtClearStyle): Boolean; virtual; - function CalcDisplayExtern: ThtDisplayStyle; virtual; - function CalcDisplayIntern: ThtDisplayStyle; virtual; - function FindAttribute(const Name: ThtString; out Attribute: TAttribute): Boolean; overload; -// function FindAttribute(NameSy: TAttrSymb; out Attribute: TAttribute): Boolean; overload; -// function GetChild(Index: Integer): THtmlNode; virtual; -// function GetParent: TBlock; virtual; -// function GetPseudos: TPseudos; virtual; - function IsCopy: Boolean; virtual; - property ContainingBlock: TBlock read GetContainingBlock; - property ContainingBox: TRect read GetContainingBox; - public - constructor Create(Parent: TCellBasic; Attributes: TAttributeList; Properties: TProperties; const ID: ThtString); - constructor CreateCopy(Parent: TCellBasic; Source: THtmlNode); virtual; - destructor Destroy; override; - - //constructor Create(Parent: THtmlNode; Tag: TElemSymb; Attributes: TAttributeList; const Properties: TResultingProperties); - function IsInFlow: Boolean; {$ifdef UseInline} inline; {$endif} - function IndexOf(Child: THtmlNode): Integer; virtual; - procedure AfterConstruction; override; - //function IsMatching(Selector: TSelector): Boolean; - property Symbol: TElemSymb read GetSymbol; -// property Parent: TBlock read GetParent; -// property Children[Index: Integer]: THtmlNode read GetChild; default; - property OwnerBlock: TBlock read FOwnerBlock; //BG, 07.02.2011: public for reading document structure (see issue 24). Renamed from MyBlock to Owner to clarify the relation. - property OwnerCell: TCellBasic read FOwnerCell write FOwnerCell; - property Document: ThtDocument read FDocument; - property Display: ThtDisplayStyle read FDisplay write FDisplay; - property EmSize: Integer read FEmSize write FEmSize; - property ExSize: Integer read FExSize write FExSize; - property AttributeValue[const AttrName: ThtString]: ThtString read GetAttribute; - property PropertyValue[PropIndex: ThtPropIndices]: Variant read GetProperty; - end; - -//------------------------------------------------------------------------------ -// TSectionBase, the abstract base class for all document sections -//------------------------------------------------------------------------------ -// Each block is a section (see TBlock and its derivates) and a series of text -// and non block building "inline" tags is held in a section (see TSection) -// -// Base class for TSection, TBlock, THtmlTable, TPage and THorzLine -//------------------------------------------------------------------------------ - - TSectionBase = class(THtmlNode) - protected - function GetYPosition: Integer; override; - procedure SetDocument(List: ThtDocument); - public - // source buffer reference - StartCurs: Integer; // where the section starts in the source buffer. - Len: Integer; // number of bytes in source buffer the section represents. - // Z coordinates are calculated in Create() - ZIndex: Integer; - // Y coordinates calculated in DrawLogic1() are still valid in Draw1() - YDraw: Integer; // where the section starts. - DrawTop: Integer; // where the border starts. In case of a block this is YDraw + MarginTop - ContentTop: Integer; // where the content starts. In case of a block this is YDraw + MarginTop + BorderTopWidth + PaddingTop - ContentBot: Integer; // where the section ends. In case of a block this is Block.ClientContentBot + PaddingBottom + BorderBottomWidth + MarginBottom - DrawBot: Integer; // where the border ends. In case of a block this is Max(Block.ClientContentBot, MyCell.tcDrawBot) + PaddingBottom + BorderBottomWidth - SectionHeight: Integer; // pixel height of section. = ContentBot - YDraw - DrawHeight: Integer; // floating image may overhang. = Max(ContentBot, DrawBot) - YDraw - // X coordinates calculated in DrawLogic1() may be shifted in Draw1(), if section is centered or right aligned - DrawRect: TRect; // where the section border starts and the content ends relative to document origin (upper left corner) - // DrawRect is calculated in DrawLogic1 or Draw1 and used in PtInDrawRect() - TagClass: ThtString; {debugging aid} - - constructor Create(Parent: TCellBasic; Attributes: TAttributeList; Properties: TProperties; const TheId, TheClass: ThtString); overload; - constructor Create(Parent: TCellBasic; Attributes: TAttributeList; Properties: TProperties); overload; - constructor CreateCopy(Parent: TCellBasic; Source: THtmlNode); override; - function CursorToXY(Canvas: TCanvas; Cursor: Integer; var X, Y: Integer): Boolean; virtual; - function DrawLogic1(Canvas: TCanvas; X, Y, XRef, YRef, AWidth, AHeight, BlHt: Integer; IMgr: TIndentManager; var MaxWidth, Curs: Integer): Integer; virtual; - function Draw1(Canvas: TCanvas; const ARect: TRect; IMgr: TIndentManager; X, XRef, YRef: Integer): Integer; virtual; - function FindCursor(Canvas: TCanvas; X, Y: Integer; out XR, YR, CaretHt: Integer; out Intext: Boolean): Integer; virtual; - function FindDocPos(SourcePos: Integer; Prev: Boolean): Integer; virtual; - function FindSourcePos(DocPos: Integer): Integer; virtual; - function FindString(From: Integer; const ToFind: UnicodeString; MatchCase: Boolean): Integer; virtual; - function FindStringR(From: Integer; const ToFind: UnicodeString; MatchCase: Boolean): Integer; virtual; - function GetChAtPos(Pos: Integer; out Ch: WideChar; out Obj: TSectionBase): Boolean; virtual; - function GetURL(Canvas: TCanvas; X, Y: Integer; out UrlTarg: TUrlTarget; out FormControl: TIDObject{TImageFormControlObj}; out ATitle: ThtString): ThtguResultType; virtual; - function PtInObject(X, Y: Integer; out Obj: TObject; out IX, IY: Integer): Boolean; virtual; - function PtInDrawRect(X, Y: Integer; var IX, IY: Integer): Boolean; virtual; - procedure AddSectionsToList; virtual; - procedure CopySelectedText; virtual; - procedure MinMaxWidth(Canvas: TCanvas; out Min, Max: Integer); virtual; - end; - - TSectionBaseList = class(TObjectList) - private - function GetItem(Index: Integer): TSectionBase; {$ifdef UseInline} inline; {$endif} - public - function PtInObject(X, Y: Integer; var Obj: TObject; var IX, IY: Integer): Boolean; - function CursorToXY(Canvas: TCanvas; Cursor: Integer; var X, Y: Integer): Boolean; virtual; - function FindDocPos(SourcePos: Integer; Prev: Boolean): Integer; virtual; - property Items[Index: Integer]: TSectionBase read GetItem; default; - end; - -//------------------------------------------------------------------------------ -// TFloatingObj, an inline block for floating blocks. -//------------------------------------------------------------------------------ - - TBlockBase = class(TSectionBase) - public - - constructor Create(Parent: TCellBasic; Position: Integer; Attributes: TAttributeList; Prop: TProperties); - constructor CreateCopy(Parent: TCellBasic; Source: THtmlNode); override; - - property Positioning: ThtBoxPositionStyle read FPositioning; - property Positions: ThtRectIntegers read FPositions; // in Pixels - property Floating: ThtAlignmentStyle read FFloating; - property Indent: Integer read FIndent; {Indentation of floated object} - end; - - TFloatingObj = class(TBlockBase) - protected - // begin copy by move() - // source buffer reference - VertAlign: ThtAlignmentStyle; - HSpaceL, HSpaceR: Integer; {horizontal extra space} - VSpaceT, VSpaceB: Integer; {vertical extra space} - PercentWidth: Boolean; {if width is percent} - PercentHeight: Boolean; {if height is percent} - // end copy by move() - - function Clone(Parent: TCellBasic): TFloatingObj; - function GetClientHeight: Integer; virtual; abstract; - function GetClientWidth: Integer; virtual; abstract; - procedure SetClientHeight(Value: Integer); virtual; abstract; - procedure SetClientWidth(Value: Integer); virtual; abstract; - public - DrawYY: Integer; // where the object starts. - DrawXX: Integer; // where the object starts. - constructor Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties); - constructor CreateCopy(Parent: TCellBasic; Source: THtmlNode); override; - function DrawLogic1(Canvas: TCanvas; X, Y, XRef, YRef, AWidth, AHeight, BlHt: Integer; IMgr: TIndentManager; var MaxWidth, Curs: Integer): Integer; override; - function Draw1(Canvas: TCanvas; const ARect: TRect; IMgr: TIndentManager; X, XRef, YRef: Integer): Integer; override; - function GetYPosition: Integer; override; - procedure DrawLogicInline(Canvas: TCanvas; FO: TFontObj; AvailableWidth, AvailableHeight: Integer); virtual; abstract; - procedure DrawInline(Canvas: TCanvas; X, Y, YBaseline: Integer; FO: TFontObj); virtual; abstract; - property ClientHeight: Integer read GetClientHeight write SetClientHeight; - property ClientWidth: Integer read GetClientWidth write SetClientWidth; - function TotalHeight: Integer; {$ifdef UseInline} inline; {$endif} - function TotalWidth: Integer; {$ifdef UseInline} inline; {$endif} - end; - TFloatingObjClass = class of TFloatingObj; - - TImageObj = class; - - TFloatingObjList = class(TObjectList) {a list of TFloatingObj's} - private - function GetItem(Index: Integer): TFloatingObj; {$ifdef UseInline} inline; {$endif} - procedure SetItem(Index: Integer; const Item: TFloatingObj); {$ifdef UseInline} inline; {$endif} - public - constructor CreateCopy(Parent: TCellBasic; T: TFloatingObjList); - procedure Decrement(N: Integer); {$ifdef UseInline} inline; {$endif} - function FindObject(Posn: Integer): TFloatingObj; {$ifdef UseInline} inline; {$endif} - // GetObjectAt() returns number of positions from Posn to next object. If it returns 0, Obj is at Posn. - function GetObjectAt(Posn: Integer; out Obj): Integer; - function PtInImage(X, Y: Integer; out IX, IY, Posn: Integer; out AMap, UMap: Boolean; out MapItem: TMapItem; out ImageObj: TImageObj): Boolean; - function PtInObject(X, Y: Integer; out Obj: TObject; out IX, IY: Integer): Boolean; - property Items[Index: Integer]: TFloatingObj read GetItem write SetItem; default; - end; - -//------------------------------------------------------------------------------ -// TCellBasic, the base class for content -//------------------------------------------------------------------------------ -// Base class for table cells, block content and the entire document -//------------------------------------------------------------------------------ - -//BG, 02.12.2013: handling display:inline is too complex in this class structure, where TSection is both home of a couple -// of HTML elements, the renderer and the rendering results (in the ThtLineRecs). -// -// A straight forward rendering would require overall Lines collecting the text of all consecutive inline level elements -// no matter where it is defined in the document tree. -// -// //BG, 01.12.2013: handle display:inline -// //This list mixes up block elements and autogenerated anonymous blocks for consecutive inline level elements based on -// // TInlineSection. All objects based on TInlineSection are owned (and therefore freed) by this list all other kind of -// // objects are assumed to be referenced and thus are not freed. -// TRenderSectionBaseList = class(TSectionBaseList) -// protected -// procedure Notify(Ptr: Pointer; Action: TListNotification); override; -// end; - - TCellBasic = class(TSectionBaseList) {a list of sections and blocks} - private - FDocument: ThtDocument; // the document it belongs to - FOwnerBlock: TBlock; // the parental block it is placed in -// FRenderList: TRenderSectionBaseList; //BG, 01.12.2013: The list of block level elements to render. Filled in DoLogic() - protected - function CalcDisplayExtern: ThtDisplayStyle; // returns either pdInline or pdBlock - public - // source buffer reference - StartCurs: Integer; // where the section starts in the source buffer. - Len: Integer; // number of bytes in source buffer the section represents. - // - IMgr: TIndentManager; // Each element displayed as a block needs an indent manager. - BkGnd: Boolean; - BkColor: TColor; - // Y coordinates calculated in DrawLogic() are still valid in Draw1() - //YValue: Integer; // vertical position at top of cell. As this is a simple container, YValue is same as Self[0].YDraw. - tcDrawTop: Integer; - tcContentBot: Integer; - tcDrawBot: Integer; - - constructor Create(Parent: TBlock); - constructor CreateCopy(Parent: TBlock; T: TCellBasic); - destructor Destroy; override; - - function CheckLastBottomMargin: Boolean; - function DoLogic(Canvas: TCanvas; Y, Width, AHeight, BlHt: Integer; var ScrollWidth, Curs: Integer): Integer; virtual; - function Draw(Canvas: TCanvas; ARect: TRect; ClipWidth, X, Y, XRef, YRef: Integer): Integer; virtual; - function FindCursor(Canvas: TCanvas; X: Integer; Y: Integer; out XR, YR, Ht: Integer; out Intext: Boolean): Integer; - function FindSourcePos(DocPos: Integer): Integer; - function FindString(From: Integer; const ToFind: UnicodeString; MatchCase: Boolean): Integer; - function FindStringR(From: Integer; const ToFind: UnicodeString; MatchCase: Boolean): Integer; - function GetChAtPos(Pos: Integer; out Ch: WideChar; out Obj: TSectionBase): Boolean; - function GetURL(Canvas: TCanvas; X, Y: Integer; out UrlTarg: TUrlTarget; out FormControl: TIDObject {TImageFormControlObj}; out ATitle: ThtString): ThtguResultType; virtual; - function IsCopy: Boolean; - procedure Add(Item: TSectionBase; TagIndex: Integer); overload; - procedure Add(var Section: TSection; TagIndex: Integer); overload; - procedure AddSectionsToList; - procedure CopySelectedText; -{$ifdef UseFormTree} - procedure FormTree(const Indent: ThtString; var Tree: ThtString); -{$endif UseFormTree} - procedure MinMaxWidth(Canvas: TCanvas; out Min, Max: Integer); virtual; - property Document: ThtDocument read FDocument; {the ThtDocument that holds the whole document} - property OwnerBlock: TBlock read FOwnerBlock; - end; - - TCell = class(TCellBasic) - private - DrawYY: Integer; - public - constructor Create(Parent: TBlock); - constructor CreateCopy(Parent: TBlock; T: TCellBasic); - destructor Destroy; override; - function DoLogic(Canvas: TCanvas; Y, Width, AHeight, BlHt: Integer; var ScrollWidth, Curs: Integer): Integer; override; - function Draw(Canvas: TCanvas; ARect: TRect; ClipWidth, X, Y, XRef, YRef: Integer): Integer; override; - end; - -//------------------------------------------------------------------------------ -// TSizeableObj is base class for floating objects TImageObj, TFrameOBj and TPanelObj. -// -// These objects may appear in text flow or attribute ALIGN or style FLOAT or -// style POSITION may push them out of the flow floating to the left or right -// side or anywhere else in the containing block or even fixed in the viewport -// resp. on printed pages. -//------------------------------------------------------------------------------ - - TSizeableObj = class(TFloatingObj) - private - FAlt: ThtString; {the alt= attribute} - FClientHeight: Integer; {does not include VSpace} - FClientWidth: Integer; {does not include HSpace} - public - ClientSizeKnown: Boolean; {know size of image} - SpecWidth: Integer; {as specified by tag} - SpecHeight: Integer; {as specified by tag} - Title: ThtString; - protected - procedure CalcSize(AvailableWidth, AvailableHeight, SetWidth, SetHeight: Integer; IsClientSizeSpecified: Boolean); - function GetClientHeight: Integer; override; - function GetClientWidth: Integer; override; - procedure SetClientHeight(Value: Integer); override; - procedure SetClientWidth(Value: Integer); override; - public - NoBorder: Boolean; {set if don't want blue border} - BorderWidth: Integer; - MargArray: ThtMarginArray; - constructor Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties); - constructor CreateCopy(Parent: TCellBasic; Source: THtmlNode); override; - constructor SimpleCreate(Parent: TCellBasic); - function PtInDrawRect(X, Y: Integer; var IX, IY: Integer): Boolean; override; - procedure DrawLogicInline(Canvas: TCanvas; FO: TFontObj; AvailableWidth, AvailableHeight: Integer); override; - procedure DrawInline(Canvas: TCanvas; X, Y, YBaseline: Integer; FO: TFontObj); override; - procedure ProcessProperties(Prop: TProperties); - procedure SetAlt(CodePage: Integer; const Value: ThtString); - property Alt: ThtString read FAlt; - end; - - TSizeableObjList = class(TFloatingObjList) {a list of TImageObj's, TPanelObj's , and TFrameObj's} - end; - - - // base class for inline panel, frame and progress node - TControlObj = class(TSizeableObj) - protected - SetWidth, SetHeight: Integer; - function GetBackgroundColor: TColor; virtual; - function GetControl: TWinControl; virtual; abstract; - property ClientControl: TWinControl read GetControl; - property BackgroundColor: TColor read GetBackgroundColor; - public - ShowIt: Boolean; - procedure DrawLogicInline(Canvas: TCanvas; FO: TFontObj; AvailableWidth, AvailableHeight: Integer); override; - procedure DrawInline(Canvas: TCanvas; X, Y, YBaseline: Integer; FO: TFontObj); override; - end; - - - // inline panel (object) node - TPanelObj = class(TControlObj) - protected - function GetBackgroundColor: TColor; override; - function GetControl: TWinControl; override; - public - Panel, OPanel: ThvPanel; - OSender: TObject; - PanelPrintEvent: TPanelPrintEvent; - FUserData: TObject; - FMyPanelObj: TPanelObj; - constructor Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties; ObjectTag: Boolean); - constructor CreateCopy(Parent: TCellBasic; Source: THtmlNode); override; - destructor Destroy; override; - procedure DrawInline(Canvas: TCanvas; X, Y, YBaseline: Integer; FO: TFontObj); override; - end; - - TPanelObjList = class(TObjectList) - private - function Get(Index: Integer): TPanelObj; {$ifdef UseInline} inline; {$endif} - public - property Items[Index: Integer]: TPanelObj read Get; default; - end; - - // inline frame node - TFrameObj = class(TControlObj) - private - FViewer: TViewerBase; - FSource, FUrl: ThtString; - frMarginWidth: Integer; - frMarginHeight: Integer; - NoScroll: Boolean; - procedure CreateFrame; - procedure UpdateFrame; - protected - function GetBackgroundColor: TColor; override; - function GetControl: TWinControl; override; - public - constructor Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties); - constructor CreateCopy(Parent: TCellBasic; Source: THtmlNode); override; - destructor Destroy; override; - procedure DrawInline(Canvas: TCanvas; X, Y: Integer; YBaseline: Integer; FO: TFontObj); override; - end; - - // inline progress (object) node - TProgressObj = class(TControlObj) - protected - function GetControl: TWinControl; override; - public - Progress: ThvProgressBar; - constructor Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties; ObjectTag: Boolean); - constructor CreateCopy(Parent: TCellBasic; Source: THtmlNode); override; - destructor Destroy; override; - procedure DrawInline(Canvas: TCanvas; X, Y, YBaseline: Integer; FO: TFontObj); override; - end; - - // inline meter (object) node - TMeterObj = class(TControlObj) - protected - function GetControl: TWinControl; override; - public - Meter: ThvMeter; - constructor Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties; ObjectTag: Boolean); - constructor CreateCopy(Parent: TCellBasic; Source: THtmlNode); override; - destructor Destroy; override; - procedure DrawInline(Canvas: TCanvas; X, Y, YBaseline: Integer; FO: TFontObj); override; - end; - - - ThtHover = (hvOff, hvOverUp, hvOverDown); - - TImageFormControlObj = class; - - // inline image node - TImageObj = class(TSizeableObj) - private - FSource: ThtString; - FImage: ThtImage; - OrigImage: ThtImage; {same as above unless swapped} - Transparent: ThtImageTransparency; {None, Lower Left Corner, or Transp GIF} - FHover: ThtHover; - FHoverImage: Boolean; - AltHeight, AltWidth: Integer; - function GetGraphic: TGraphic; - procedure SetHover(Value: ThtHover); - procedure DoDraw(Canvas: TCanvas; XX, Y: Integer; ddImage: ThtImage); - public - ObjHeight, ObjWidth: Integer; {width as drawn} - IsMap, UseMap: Boolean; - MapName: ThtString; - MyFormControl: TImageFormControlObj; {if an , font for document} - - OnBackgroundChange: TNotifyEvent; - BackgroundImage: ThtImage; - BackgroundImagePosition: PtPositionRec; - BackgroundImageName: ThtString; {name of background bitmap} - BackgroundImageLoaded: Boolean; {if background bitmap is loaded} - HtmlFormList: THtmlFormList; - AniList: ThtImageList; {list of all animated Images} - SubmitForm: TFormSubmitEvent; - ScriptEvent: TScriptEvent; - PanelCreateEvent: TPanelCreateEvent; - PanelDestroyEvent: TPanelDestroyEvent; - PanelPrintEvent: TPanelPrintEvent; - PageBottom: Integer; - PageShortened: Boolean; - MapList: ThtMap; {holds list of client maps, TMapItems} - Timer: TTimer; {for animated GIFs} - FormControlList: TFormControlObjList; {List of all TFormControlObj's in this SectionList} - PanelList: TPanelObjList; {List of all TPanelObj's in this SectionList} - MissingImages: ThtStringList; {images to be supplied later} - ControlEnterEvent: TNotifyEvent; - LinkList: TLinkList; {List of links (TFontObj's)} - ActiveLink: TFontObj; - LinksActive: Boolean; - ActiveImage: TImageObj; - ShowDummyCaret: Boolean; - Styles: THtmlStyleList; {the stylesheet} - DrawList: TDrawList; - FirstLineHtPtr: PInteger; - IDNameList: TIDObjectList; - PositionList: TSectionBaseList; - ImageCache: ThtImageCache; - SectionCount: Integer; - CycleNumber: Integer; - ProgressStart: Integer; - IsCopy: Boolean; {set when printing or making bitmap/metafile} - NoOutput: Boolean; - TabOrderList: TStringList; - FirstPageItem: Boolean; - StopTab: Boolean; - InlineList: TObjectList; {actually TInlineList, a list of ThtInlineRec's} - TableNestLevel: Integer; - InLogic2: Boolean; - LinkDrawnEvent: TLinkDrawnEvent; - LinkPage: Integer; - PrintingTable: THtmlTable; - ScaleX, ScaleY: single; - SkipDraw: Boolean; - FNoBreak : Boolean; - FCurrentStyle: TFontStyles; - FCurrentForm : THtmlForm; - constructor Create(Owner: THtmlViewerBase; APaintPanel: TWinControl); - constructor CreateCopy(T: ThtDocument); - destructor Destroy; override; - function AddChPosObjectToIDNameList(const S: ThtString; Pos: Integer): Integer; {$ifdef UseInline} inline; {$endif} - function CursorToXY(Canvas: TCanvas; Cursor: Integer; var X, Y: Integer): Boolean; override; - function DoLogic(Canvas: TCanvas; Y: Integer; Width, AHeight, BlHt: Integer; var ScrollWidth, Curs: Integer): Integer; override; - function Draw(Canvas: TCanvas; ARect: TRect; ClipWidth, X: Integer; Y, XRef, YRef: Integer): Integer; override; - function FindDocPos(SourcePos: Integer; Prev: Boolean): Integer; override; - function FindSectionAtPosition(Pos: Integer; out TopPos, Index: Integer): TSectionBase; - procedure GetFormControlData(FormData: TFormData); - function GetSelLength: Integer; - function GetSelTextBuf(Buffer: PWideChar; BufSize: Integer): Integer; - function GetTheImage(const BMName: ThtString; var Transparent: ThtImageTransparency; out FromCache, Delay: Boolean): ThtImage; - function GetURL(Canvas: TCanvas; X, Y: Integer; out UrlTarg: TUrlTarget; out FormControl: TIDObject {TImageFormControlObj}; out ATitle: ThtString): ThtguResultType; override; - procedure CancelActives; - procedure CheckGIFList(Sender: TObject); - procedure Clear; override; - procedure ClearLists; - procedure GetBackgroundImage; - procedure HideControls; - procedure InsertImage(const Src: ThtString; Stream: TStream; out Reformat: Boolean); overload; - procedure InsertImage(const Src: ThtString; Bitmap: TBitmap; Color: TColor; Transparent: ThtImageTransparency; OwnsBitmap: Boolean; out Reformat: Boolean); overload; - procedure LButtonDown(Down: Boolean); - procedure ProcessInlines(SIndex: Integer; Prop: TProperties; Start: Boolean); - procedure SetBackground(ABackground: TColor); - procedure SetBackgroundImage(const Name: ThtString; const APrec: PtPositionRec); - procedure SetFormControlData(FormData: TFormData); - procedure SetYOffset(Y: Integer); - procedure SetFonts(const Name, PreName: ThtString; ASize: Integer; - AColor, AHotSpot, AVisitedColor, AActiveColor, ABackground: TColor; LnksActive, LinkUnderLine: Boolean; - ACodePage: TBuffCodePage; ACharSet: TFontCharSet; MarginHeight, MarginWidth: Integer); - property UseQuirksMode : Boolean read FUseQuirksMode write FUseQuirksMode; - property PropStack : THtmlPropStack read FPropStack write FPropStack; - - property NoBreak : Boolean read FNoBreak write FNoBreak; {set when in } - property ViewPort: TRect read GetViewPort; {ViewPort is the APaintPanel's client rect, except while printing} - property PageArea: TRect write SetPageArea; {is the ViewPort while printing, set by THtmlViewer.Print} - - {$ifdef has_StyleElements} - property StyleElements : TStyleElements read FStyleElements write SetStyleElements; - {$endif} - property CurrentStyle: TFontStyles read FCurrentStyle write FCurrentStyle; {as set by , , etc.} - property CurrentForm : THtmlForm read FCurrentForm write FCurrentForm; - end; - -//------------------------------------------------------------------------------ -// some more base sections -//------------------------------------------------------------------------------ - - TLineBreak = class(TSectionBase) - protected - function TryGetClear(var Clear: ThtClearStyle): Boolean; override; - end; - - TPage = class(TSectionBase) - public - constructor Create(Parent: TCellBasic; Attributes: TAttributeList; Properties: TProperties); - function Draw1(Canvas: TCanvas; const ARect: TRect; IMgr: TIndentManager; X, XRef, YRef: Integer): Integer; override; - end; - - THorzLine = class(TSectionBase) {a horizontal line,


    } - public - VSize: Integer; - Color: TColor; - Align: ThtJustify; - UseDefBorder: Boolean; - NoShade: Boolean; - BkGnd: Boolean; - Width, Indent: Integer; - - constructor Create(Parent: TCellBasic; L: TAttributeList; Prop: TProperties); - constructor CreateCopy(Parent: TCellBasic; Source: THtmlNode); override; - procedure CopySelectedText; override; - function DrawLogic1(Canvas: TCanvas; X, Y, XRef, YRef, AWidth, AHeight, BlHt: Integer; IMgr: TIndentManager; var MaxWidth, Curs: Integer): Integer; override; - function Draw1(Canvas: TCanvas; const ARect: TRect; IMgr: TIndentManager; X, XRef, YRef: Integer): Integer; override; - end; - - TPreFormated = class(TSection) -// {section for preformated,
    }
    -//  public
    -//    procedure ProcessText(TagIndex: Integer); override;
    -//    function DrawLogic(Canvas: TCanvas; X, Y, XRef, YRef, AWidth, AHeight, BlHt: Integer; IMgr: TIndentManager;
    -//      var MaxWidth, Curs: Integer): Integer; override;
    -//    procedure MinMaxWidth(Canvas: TCanvas; out Min, Max: Integer); override;
    -  end;
    -
    -var
    -  WaitStream: TMemoryStream;
    -  ErrorStream: TMemoryStream;
    -  WaitBitmap: TBitmap;
    -  ErrorBitmap: TBitmap;
    -{$ifdef UNICODE}
    -{$else}
    -  UnicodeControls: Boolean;
    -{$endif}
    -
    -implementation
    -
    -uses
    -{$ifdef UseVCLStyles}
    -  System.Types,
    -  System.UITypes,
    -  Vcl.Themes,
    -{$endif}
    -{$if defined(JPM_DEBUGGING)
    -  or defined(JPM_DEBUGGING_CREATE)
    -  or defined(JPM_DEBUGGING_LOGIC)
    -}
    - CodeSiteLogging,
    -{$ifend}
    -{$IFNDEF NoGDIPlus}
    -  GDIPL2A,
    -{$ENDIF}
    -  HtmlView,
    -{$ifdef Compiler28_Plus}
    - System.NetEncoding,
    -{$endif}
    -  Htmlsbs1;
    -
    -
    -//-- BG ---------------------------------------------------------- 14.01.2012 --
    -function Sum(const Arr: TIntArray; StartIndex, EndIndex: Integer): Integer; overload;
    - {$ifdef UseInline} inline; {$endif}
    -// Return sum of array elements from StartIndex to EndIndex.
    -var
    -  I: Integer;
    -begin
    -  Result := 0;
    -  for I := StartIndex to EndIndex do
    -    Inc(Result, Arr[I]);
    -end;
    -
    -//-- BG ---------------------------------------------------------- 14.01.2012 --
    -function Sum(const Arr: TIntArray): Integer; overload;
    - {$ifdef UseInline} inline; {$endif}
    -// Return sum of all array elements.
    -begin
    -  Result := Sum(Arr, Low(Arr), High(Arr));
    -end;
    -
    -//-- BG ---------------------------------------------------------- 14.01.2012 --
    -function Sum(const Arr: TIntegerPerWidthType; StartIndex, EndIndex: TWidthType): Integer; overload;
    - {$ifdef UseInline} inline; {$endif}
    -// Return sum of array elements from StartIndex to EndIndex.
    -var
    -  I: TWidthType;
    -begin
    -  Result := 0;
    -  for I := StartIndex to EndIndex do
    -    Inc(Result, Arr[I]);
    -end;
    -
    -//-- BG ---------------------------------------------------------- 14.01.2012 --
    -function Sum(const Arr: TIntegerPerWidthType): Integer; overload;
    - {$ifdef UseInline} inline; {$endif}
    -// Return sum of all array elements.
    -begin
    -  Result := Sum(Arr, Low(Arr), High(Arr));
    -end;
    -
    -//-- BG ---------------------------------------------------------- 17.01.2012 --
    -function SubArray(const Arr, Minus: TIntArray): TIntArray; overload;
    - {$ifdef UseInline} inline; {$endif}
    -// Return array with differences per index.
    -var
    -  I: Integer;
    -begin
    -  Result := Copy(Arr);
    -  for I := 0 to Min(High(Result), High(Minus)) do
    -    Dec(Result[I], Minus[I]);
    -end;
    -
    -//-- BG ---------------------------------------------------------- 16.01.2012 --
    -procedure SetArray(var Arr: TIntArray; Value, StartIndex, EndIndex: Integer); overload;
    - {$ifdef UseInline} inline; {$endif}
    -var
    -  I: Integer;
    -begin
    -  for I := StartIndex to EndIndex do
    -    Arr[I] := Value;
    -end;
    -
    -//-- BG ---------------------------------------------------------- 16.01.2012 --
    -procedure SetArray(var Arr: TIntArray; Value: Integer); overload;
    - {$ifdef UseInline} inline; {$endif}
    -begin
    -  SetArray(Arr, Value, Low(Arr), High(Arr));
    -end;
    -
    -//-- BG ---------------------------------------------------------- 16.01.2012 --
    -procedure SetArray(var Arr: TIntegerPerWidthType; Value: Integer); overload;
    - {$ifdef UseInline} inline; {$endif}
    -var
    -  I: TWidthType;
    -begin
    -  for I := Low(TWidthType) to High(TWidthType) do
    -    Arr[I] := Value;
    -end;
    -
    -//-- BG ---------------------------------------------------------- 18.01.2012 --
    -procedure CountsPerType(
    -  out CountsPerType: TIntegerPerWidthType;
    -  const ColumnSpecs: TWidthTypeArray;
    -  StartIndex, EndIndex: Integer);
    - {$ifdef UseInline} inline; {$endif}
    -var
    -  I: Integer;
    -begin
    -  SetArray(CountsPerType, 0);
    -  for I := StartIndex to EndIndex do
    -    Inc(CountsPerType[ColumnSpecs[I]]);
    -end;
    -
    -//-- BG ---------------------------------------------------------- 19.01.2012 --
    -function SumOfType(
    -  WidthType: TWidthType;
    -  const ColumnSpecs: TWidthTypeArray;
    -  const Widths: TIntArray;
    -  StartIndex, EndIndex: Integer): Integer;
    -  {$ifdef UseInline} inline; {$endif}
    -var
    -  I: Integer;
    -begin
    -  Result := 0;
    -  for I := StartIndex to EndIndex do
    -    if ColumnSpecs[I] = WidthType then
    -      Inc(Result, Widths[I]);
    -end;
    -
    -//-- BG ---------------------------------------------------------- 17.06.2012 --
    -function SumOfNotType(
    -  WidthType: TWidthType;
    -  const ColumnSpecs: TWidthTypeArray;
    -  const Widths: TIntArray;
    -  StartIndex, EndIndex: Integer): Integer;
    -  {$ifdef UseInline} inline; {$endif}
    -var
    -  I: Integer;
    -begin
    -  Result := 0;
    -  for I := StartIndex to EndIndex do
    -    if ColumnSpecs[I] <> WidthType then
    -      Inc(Result, Widths[I]);
    -end;
    -
    -procedure InitializeFontSizes(Size: Integer);
    -   {$ifdef UseInline} inline; {$endif}
    -var
    -  I: Integer;
    -begin
    -  for I := 1 to 7 do
    -  begin
    -    FontConv[I] := FontConvBase[I] * Size / 12.0;
    -    PreFontConv[I] := PreFontConvBase[I] * Size / 12.0;
    -  end;
    -end;
    -
    -{ THtmlNode }
    -
    -//-- BG ---------------------------------------------------------- 24.03.2011 --
    -procedure THtmlNode.AfterConstruction;
    -begin
    -  inherited AfterConstruction;
    -  if (Length(ID) > 0) and (Document <> nil) and (Document.IDNameList <> nil) then
    -    Document.IDNameList.AddObject(ID, Self);
    -end;
    -
    -//-- BG ---------------------------------------------------------- 07.09.2013 --
    -function THtmlNode.CalcDisplayExtern: ThtDisplayStyle;
    -begin
    -  case FDisplay of
    -    pdInlineBlock,
    -    pdInlineTable:
    -      Result := pdInline;
    -  else
    -    Result := FDisplay;
    -  end;
    -end;
    -
    -//-- BG ---------------------------------------------------------- 07.09.2013 --
    -function THtmlNode.CalcDisplayIntern: ThtDisplayStyle;
    -begin
    -  case FDisplay of
    -    pdInlineTable:
    -      Result := pdTable;
    -
    -    pdInlineBlock:
    -      Result := pdBlock;
    -  else
    -    Result := FDisplay;
    -  end;
    -end;
    -
    -//-- BG ---------------------------------------------------------- 24.03.2011 --
    -constructor THtmlNode.Create(Parent: TCellBasic; Attributes: TAttributeList; Properties: TProperties; const ID: ThtString);
    -var
    -  MargArrayO: ThtVMarginArray;
    -  MargArray: ThtMarginArray;
    -  Cd: ThtConvData;
    -begin
    -  inherited Create(ID);
    -  FOwnerCell := Parent;
    -  if FOwnerCell <> nil then
    -  begin
    -    FOwnerBlock := FOwnerCell.OwnerBlock;
    -    FDocument := FOwnerCell.Document;
    -  end;
    -  if Attributes <> nil then
    -    FAttributes := Attributes.Clone;
    -  if Properties <> nil then
    -    FProperties := Properties.Clone;
    -// defaults are set automatically as Ord() of these defaults is 0:
    -//  FDisplay := pdUnassigned;
    -//  FFloating := aNone;
    -//  FPositioning := posStatic;
    -  TryGetClear(FClearing);
    -
    -  if FProperties <> nil then
    -  begin
    -    FDisplay := FProperties.Display;
    -    FPositioning := FProperties.GetPosition;
    -    if not FProperties.GetFloat(FFloating) or (FPositioning in [posAbsolute, posFixed]) then
    -      FFloating := ANone;
    -    FProperties.GetVMarginArray(MargArrayO);
    -    FEmSize := FProperties.EmSize;
    -    FExSize := FProperties.ExSize;
    -    CD := ConvData(100, 100, FEmSize, FExSize, 0);
    -    ConvMargProp(piTop   , MargArrayO, CD, MargArray);
    -    ConvMargProp(piLeft  , MargArrayO, CD, MargArray);
    -    ConvMargProp(piRight , MargArrayO, CD, MargArray);
    -    ConvMargProp(piBottom, MargArrayO, CD, MargArray);
    -    FPositions[reTop   ] := MargArray[piTop   ];
    -    FPositions[reLeft  ] := MargArray[piLeft  ];
    -    FPositions[reRight ] := MargArray[piRight ];
    -    FPositions[reBottom] := MargArray[piBottom];
    -  end;
    -end;
    -
    -//-- BG ---------------------------------------------------------- 24.03.2011 --
    -constructor THtmlNode.CreateCopy(Parent: TCellBasic; Source: THtmlNode);
    -begin
    -  inherited Create( Source.HtmlId );
    -  FOwnerCell := Parent;
    -  begin
    -    FOwnerBlock := FOwnerCell.OwnerBlock;
    -    FDocument   := FOwnerCell.Document;
    -  end;
    -  FAttributes   := Source.FAttributes;
    -  FProperties   := Source.FProperties;
    -  FClearing     := Source.FClearing;
    -  FDisplay      := Source.FDisplay;
    -  FPositioning  := Source.FPositioning;
    -  FPositions    := Source.FPositions;
    -  FFloating     := Source.FFloating;
    -  FIndent       := Source.FIndent;
    -end;
    -
    -//-- BG ---------------------------------------------------------- 21.10.2016 --
    -destructor THtmlNode.Destroy;
    -begin
    -  if not IsCopy then
    -  begin
    -    FAttributes.Free;
    -    FProperties.Free;
    -  end;
    -  inherited;
    -end;
    -
    -//-- BG ---------------------------------------------------------- 24.02.2016 --
    -function THtmlNode.TryGetClear(var Clear: ThtClearStyle): Boolean;
    -begin
    -  Result := False;
    -  if FProperties <> nil then
    -    Result := FProperties.GetClear(Clear);
    -end;
    -
    -//-- BG ---------------------------------------------------------- 24.02.2016 --
    -function TSection.TryGetClear(var Clear: ThtClearStyle): Boolean;
    -var
    -  T: TAttribute;
    -begin
    -  T := nil;
    -  Result := inherited TryGetClear(Clear);
    -  if not Result then
    -    if FAttributes <> nil then
    -      if FAttributes.Find(ClearSy, T) then
    -        Result := TryStrToClearStyle(LowerCase(T.Name), Clear);
    -end;
    -
    -////-- BG ---------------------------------------------------------- 23.03.2011 --
    -//function THtmlNode.FindAttribute(NameSy: TAttrSymb; out Attribute: TAttribute): Boolean;
    -//begin
    -//  Attribute := nil;
    -//  Result := (FAttributes <> nil) and FAttributes.Find(NameSy, Attribute);
    -//end;
    -
    -//-- BG ---------------------------------------------------------- 24.03.2011 --
    -function THtmlNode.FindAttribute(const Name: ThtString; out Attribute: TAttribute): Boolean;
    -begin
    -  Attribute := nil;
    -  Result := (FAttributes <> nil) and FAttributes.Find(Name, Attribute);
    -end;
    -
    -//-- BG ---------------------------------------------------------- 28.10.2015 --
    -function THtmlNode.GetAttribute(const Name: ThtString): ThtString;
    -var
    -  Attribute: TAttribute;
    -begin
    -  if FindAttribute(Name, Attribute) then
    -    Result := Attribute.Name
    -  else
    -    SetLength(Result, 0);
    -end;
    -
    -//-- BG ---------------------------------------------------------- 24.02.2016 --
    -function THtmlNode.GetClearSpace(IMgr: TIndentManager; Y: Integer): Integer;
    -var
    -  CL, CR: Integer;
    -begin
    -  Result := 0;
    -  if FClearing <> clrNone then
    -  begin {may need to move down past floating image}
    -    IMgr.GetClearY(CL, CR);
    -    case FClearing of
    -      clrLeft:   Result := Max(0, CL - Y - 1);
    -      clrRight:  Result := Max(0, CR - Y - 1);
    -      clrBoth:   Result := Max(CL - Y - 1, Max(0, CR - Y - 1));
    -    end;
    -  end;
    -end;
    -
    -//-- BG ---------------------------------------------------------- 14.02.2016 --
    -function THtmlNode.GetContainingBlock: TBlock;
    -begin
    -  // if Result is nil, containing block is the viewport resp. page area
    -  case FPositioning of
    -    posFixed:
    -      Result := nil;
    -
    -    posAbsolute:
    -    begin
    -      Result := OwnerBlock;
    -      while (Result <> nil) and not (Result.Positioning in [posAbsolute, posRelative, posFixed]) do
    -        Result := Result.OwnerBlock;
    -    end;
    -
    -  else
    -    Result := OwnerBlock;
    -  end;
    -end;
    -
    -//-- BG ---------------------------------------------------------- 14.02.2016 --
    -function THtmlNode.GetContainingBox: TRect;
    -var
    -  ContainingBlock: TBlock;
    -begin
    -  ContainingBlock := GetContainingBlock;
    -  if ContainingBlock <> nil then
    -  begin
    -    Result.Left := ContainingBlock.LeftP;
    -    Result.Top  := ContainingBlock.TopP;
    -    Result.Right := Result.Left + ContainingBlock.ContentWidth;
    -    Result.Bottom := Result.Top + ContainingBlock.MyCell.tcContentBot - ContainingBlock.MyCell.tcDrawTop;
    -  end
    -  else
    -    Result := FDocument.ViewPort;
    -end;
    -
    -//-- BG ---------------------------------------------------------- 14.02.2016 --
    -function THtmlNode.GetProperty(PropIndex: ThtPropIndices): Variant;
    -begin
    -  if FProperties <> nil then
    -    Result := FProperties.Props[PropIndex]
    -  else
    -    Result := Unassigned;
    -end;
    -
    -////-- BG ---------------------------------------------------------- 24.03.2011 --
    -//function THtmlNode.GetChild(Index: Integer): THtmlNode;
    -//begin
    -//  Result := nil; //TODO -oBG, 24.03.2011
    -//end;
    -
    -////-- BG ---------------------------------------------------------- 23.03.2011 --
    -//function THtmlNode.GetParent: TBlock;
    -//begin
    -//  Result := FOwnerBlock;
    -//end;
    -
    -//-- BG ---------------------------------------------------------- 04.08.2013 --
    -function THtmlNode.GetSymbol: TElemSymb;
    -begin
    -  Result := FProperties.PropSym;
    -end;
    -
    -//-- BG ---------------------------------------------------------- 21.09.2016 --
    -procedure THtmlNode.GetVMarginArray(var MArray: ThtVMarginArray);
    -begin
    -  FProperties.GetVMarginArray(MArray);
    -end;
    -
    -//function THtmlNode.GetPseudos: TPseudos;
    -//begin
    -//  Result := []; //TODO -oBG, 24.03.2011
    -//end;
    -
    -//-- BG ---------------------------------------------------------- 24.03.2011 --
    -function THtmlNode.IndexOf(Child: THtmlNode): Integer;
    -begin
    -  Result := -1; //TODO -oBG, 24.03.2011
    -end;
    -
    -//-- BG ---------------------------------------------------------- 04.08.2013 --
    -function THtmlNode.IsCopy: Boolean;
    -begin
    -  Result := Document.IsCopy;
    -end;
    -
    -//-- BG ---------------------------------------------------------- 13.02.2016 --
    -function THtmlNode.IsInFlow: Boolean;
    -begin
    -  Result := not (FFloating in [aLeft, aRight]) and not (FPositioning in [posAbsolute, posFixed]);
    -end;
    -
    -////-- BG ---------------------------------------------------------- 23.03.2011 --
    -//function THtmlNode.IsMatching(Selector: TSelector): Boolean;
    -//
    -//  function IsMatchingSimple: Boolean;
    -//
    -//    function IncludesStringArray(S, F: ThtStringArray): Boolean;
    -//    var
    -//      I: Integer;
    -//    begin
    -//      Result := Length(S) <= Length(F);
    -//      if not Result then
    -//        exit;
    -//      for I := Low(S) to High(S) do
    -//        if IndexOfString(F, S[I]) < 0 then
    -//          exit;
    -//      Result := True;
    -//    end;
    -//
    -//  var
    -//    Index: Integer;
    -//    Attribute: TAttribute;
    -//    Match: TAttributeMatch;
    -//    S: TSymbol;
    -//  begin
    -//    Result := False;
    -//
    -//    // http://www.w3.org/TR/2010/WD-CSS2-20101207/selector.html
    -//    // If all conditions in the selector are true for a certain element, the selector matches the element.
    -//
    -//    if Selector.Pseudos <> [] then
    -//      if not (Selector.Pseudos >= GetPseudos) then
    -//        exit;
    -//
    -//    // a loop about tags? there is one or none tag in the selector.
    -//    for Index := Low(Selector.Tags) to High(Selector.Tags) do
    -//      if TryStrToReservedWord(Selector.Tags[Index], S) then
    -//        if S <> FTag then
    -//          exit;
    -//
    -//    // a loop about ids? CSS 2.1 allows more than 1 ID, but most browsers do not support them.
    -//    if not IncludesStringArray(Selector.Ids, FIds) then
    -//      exit;
    -//
    -//    if not IncludesStringArray(Selector.Classes, FClasses) then
    -//      exit;
    -//
    -//    for Index := 0 to Selector.AttributeMatchesCount - 1 do
    -//    begin
    -//      Match := Selector.AttributeMatches[Index];
    -//      if not FindAttribute(Match.Name, Attribute) then
    -//        exit;
    -//      case Match.Oper of
    -//        //no more checks here. Attribute it set! amoSet: ;       // [name] : matches, if attr is set and has any value.
    -//
    -//        amoEquals:     // [name=value] : matches, if attr equals value.
    -//          if htCompareStr(Match.Value, Attribute.AsString) <> 0 then
    -//            break;
    -//
    -//        amoContains:   // [name~=value] : matches, if attr is a white space separated list of values and value is one of these values.
    -//          if PosX(Match.Value + ' ', Attribute.AsString + ' ', 1) = 0 then
    -//            break;
    -//
    -//        amoStartsWith: // [name|=value] : matches, if attr equals value or starts with value immediately followed by a hyphen.
    -//          if PosX(Match.Value + '-', Attribute.AsString + '-', 1) <> 1 then
    -//            break;
    -//        end;
    -//      end;
    -//
    -//    Result := True;
    -//  end;
    -//
    -//  function IsChild(Selector: TSelector): Boolean;
    -//  var
    -//    P: THtmlNode;
    -//  begin
    -//    P := Parent;
    -//    Result := (P <> nil) and P.IsMatching(Selector);
    -//  end;
    -//
    -//  function IsDescendant(Selector: TSelector): Boolean;
    -//  var
    -//    Node: THtmlNode;
    -//  begin
    -//    Result := False;
    -//    Node := Parent;
    -//    while Node <> nil do
    -//    begin
    -//      Result := Node.IsMatching(Selector);
    -//      if Result then
    -//        break;
    -//      Node := Node.Parent;
    -//    end;
    -//  end;
    -//
    -//  function IsFollower(Selector: TSelector): Boolean;
    -//  var
    -//    P: THtmlNode;
    -//    I: Integer;
    -//  begin
    -//    P := Parent;
    -//    Result := P <> nil;
    -//    if Result then
    -//    begin
    -//      I := P.IndexOf(Self);
    -//      if I > 0 then
    -//        Result := P[I - 1].IsMatching(Selector);
    -//    end;
    -//  end;
    -//
    -//begin
    -//  Result := IsMatchingSimple;
    -//  if Result then
    -//    if Selector is TCombinedSelector then
    -//      case TCombinedSelector(Selector).Combinator of
    -//        scChild:      Result := IsChild(TCombinedSelector(Selector).LeftHand);
    -//        scDescendant: Result := IsDescendant(TCombinedSelector(Selector).LeftHand);
    -//        scFollower:   Result := IsFollower(TCombinedSelector(Selector).LeftHand);
    -//      end;
    -//end;
    -
    -
    -{ TFontObj }
    -
    -type
    -  TSectionClass = class of TSectionBase;
    -  EProcessError = class(Exception);
    -
    -type
    -  ThtInlineRec = class
    -  private
    -    StartB, EndB, IDB, StartBDoc, EndBDoc: Integer;
    -    MargArray: ThtMarginArray;
    -  end;
    -
    -  TInlineList = class(TObjectList) {a list of ThtInlineRec's}
    -  private
    -    NeedsConverting: Boolean;
    -    Owner: ThtDocument;
    -    procedure AdjustValues;
    -    function Get(Index: Integer): ThtInlineRec; {$ifdef UseInline} inline; {$endif}
    -    function GetStartB(I: Integer): Integer;
    -    function GetEndB(I: Integer): Integer;
    -  public
    -    constructor Create(AnOwner: ThtDocument);
    -    procedure Clear; override;
    -    property Items[Index: Integer]: ThtInlineRec read Get; default;
    -    property StartB[I: Integer]: Integer read GetStartB;
    -    property EndB[I: Integer]: Integer read GetEndB;
    -  end;
    -
    -constructor TFontObj.Create(ASection: TSection; F: ThtFont; Position: Integer);
    -begin
    -  inherited Create;
    -{$ifndef NoTabLink}
    -  FSection := ASection;
    -{$endif}
    -  TheFont := ThtFont.Create;
    -  TheFont.Assign(F);
    -  Pos := Position;
    -  UrlTarget := TUrlTarget.Create;
    -  FontChanged;
    -end;
    -
    -{$ifndef NoTabLink}
    -
    -procedure TFontObj.EnterEvent(Sender: TObject);
    -var
    -  List: TFontList;
    -  I, J: Integer;
    -begin
    -  Active := True;
    -{Make adjacent fonts in this link active also}
    -  List := FSection.Document.LinkList;
    -  I := List.IndexOf(Self);
    -  if I >= 0 then
    -    for J := I + 1 to List.Count - 1 do
    -      if (Self.UrlTarget.ID = List[J].UrlTarget.ID) then
    -        List[J].Active := True
    -      else
    -        Break;
    -  FSection.Document.ControlEnterEvent(Self);
    -end;
    -
    -procedure TFontObj.ExitEvent(Sender: TObject);
    -var
    -  List: TFontList;
    -  I, J: Integer;
    -begin
    -  Active := False;
    -{Make adjacent fonts in this link inactive also}
    -  List := FSection.Document.LinkList;
    -  I := List.IndexOf(Self);
    -  if I >= 0 then
    -    for J := I + 1 to List.Count - 1 do
    -      if (Self.UrlTarget.ID = List[J].UrlTarget.ID) then
    -        List[J].Active := False
    -      else
    -        Break;
    -  FSection.Document.PPanel.Invalidate;
    -end;
    -
    -procedure TFontObj.AssignY(Y: Integer);
    -var
    -  List: TFontList;
    -  I, J: Integer;
    -begin
    -  if UrlTarget.Url = '' then
    -    Exit;
    -  if Assigned(TabControl) then
    -    FYValue := Y
    -  else
    -  begin {Look back for the TFontObj with the TabControl}
    -    List := FSection.Document.LinkList;
    -    if List <> nil then
    -    begin
    -      I := List.IndexOf(Self);
    -      if I >= 0 then
    -        for J := I - 1 downto 0 do
    -          if (Self.UrlTarget.ID = List[J].UrlTarget.ID) then
    -          begin
    -            if Assigned(List[J].TabControl) then
    -            begin
    -              List[J].FYValue := Y;
    -              break;
    -            end;
    -          end
    -          else
    -            Break;
    -    end;
    -  end;
    -end;
    -
    -procedure TFontObj.AKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    -var
    -  Viewer: THtmlViewer;
    -begin
    -  Viewer := THtmlViewer(FSection.Document.TheOwner);
    -  if (Key = vk_Return) then
    -  begin
    -    Viewer.Url := UrlTarget.Url;
    -    Viewer.Target := UrlTarget.Target;
    -    Viewer.LinkAttributes.Text := UrlTarget.Attr;
    -    Viewer.LinkText := Viewer.GetTextByIndices(UrlTarget.Start, UrlTarget.Last);
    -    Viewer.TriggerUrlAction; {call to UrlAction via message}
    -  end
    -  else {send other keys to THtmlViewer}
    -    Viewer.KeyDown(Key, Shift);
    -end;
    -
    -procedure TFontObj.CreateTabControl(TabIndex: Integer);
    -var
    -  PntPanel: TWinControl; //TPaintPanel;
    -  I, J: Integer;
    -  List: TFontList;
    -begin
    -  if Assigned(TabControl) then
    -    Exit;
    -  {Look back for the TFontObj with the TabControl}
    -  List := FSection.Document.LinkList;
    -  I := List.IndexOf(Self);
    -  if I >= 0 then
    -    for J := I - 1 downto 0 do
    -      if (Self.UrlTarget.ID = List[J].UrlTarget.ID) then
    -        if Assigned(List[J].TabControl) then
    -          Exit;
    -
    -  PntPanel := FSection.Document.PPanel;
    -  TabControl := ThtTabcontrol.Create(PntPanel);
    -  TabControl.Left := -4000; {so will be invisible until placed}
    -  TabControl.Width := 1;
    -  TabControl.Height := 1;
    -  TabControl.TabStop := True;
    -  TabControl.OnEnter := EnterEvent;
    -  TabControl.OnExit := ExitEvent;
    -  TabControl.OnKeyDown := AKeyDown;
    -  TabControl.Parent := PntPanel;
    -
    -  if TabIndex > 0 then
    -  {Adding leading 0's to the number ThtString allows it to be sorted numerically,
    -   and the Count takes care of duplicates}
    -    with FSection.Document.TabOrderList do
    -      AddObject(Format('%.5d%.3d', [TabIndex, Count]), TabControl);
    -end;
    -{$ENDIF}
    -
    -procedure TFontObj.CreateFIArray;
    -begin
    -  if not Assigned(FIArray) then
    -    FIArray := TFontInfoArray.Create;
    -end;
    -
    -procedure TFontObj.ReplaceFont(F: ThtFont);
    -begin
    -  TheFont.Assign(F);
    -  FontChanged;
    -end;
    -
    -procedure TFontObj.ConvertFont(const FI: ThtFontInfo);
    -begin
    -  TheFont.Assign(FI);
    -  FontChanged;
    -end;
    -
    -constructor TFontObj.CreateCopy(ASection: TSection; T: TFontObj);
    -begin
    -  inherited Create;
    -{$ifndef NoTabLink}
    -  FSection := ASection;
    -{$endif}
    -  Pos := T.Pos;
    -  SScript := T.SScript;
    -  TheFont := ThtFont.Create;
    -  TheFont.Assign(T.TheFont);
    -  if Assigned(T.FIArray) then
    -    ConvertFont(T.FIArray.Ar[LFont]);
    -  UrlTarget := TUrlTarget.Create;
    -  UrlTarget.Assign(T.UrlTarget);
    -  FontChanged;
    -end;
    -
    -destructor TFontObj.Destroy;
    -var Index: Integer;
    -begin
    -  FIArray.Free;
    -  TheFont.Free;
    -  UrlTarget.Free;
    -  if FSection <> nil then
    -    if FSection.Document <> nil then
    -      if FSection.Document.TabOrderList <> nil then
    -        with FSection.Document.TabOrderList do
    -        begin
    -          Index := IndexOfObject(TabControl);
    -          if Index >= 0 then
    -            Delete(Index);
    -        end;
    -  TabControl.Free;
    -  inherited Destroy;
    -end;
    -
    -procedure TFontObj.SetVisited(Value: Boolean);
    -begin
    -  if Value <> FVisited then
    -  begin
    -    FVisited := Value;
    -    ConvertFont(FIArray.Ar[FontInfoIndex]);
    -    FontChanged;
    -  end;
    -end;
    -
    -procedure TFontObj.SetHover(Value: Boolean);
    -begin
    -  if Value <> FHover then
    -  begin
    -    FHover := Value;
    -    ConvertFont(FIArray.Ar[FontInfoIndex]);
    -    FontChanged;
    -  end;
    -end;
    -
    -procedure TFontObj.SetAllHovers(List: TFontList; Value: Boolean);
    -{Set/Reset Hover on this item and all adjacent item with the same URL}
    -var
    -  I, J: Integer;
    -begin
    -  SetHover(Value);
    -  I := List.IndexOf(Self);
    -  if I >= 0 then
    -  begin
    -    J := I + 1;
    -    while (J < List.Count) and (Self.UrlTarget.ID = List[J].UrlTarget.ID) do
    -    begin
    -      List[J].Hover := Value;
    -      Inc(J);
    -    end;
    -    J := I - 1;
    -    while (J >= 0) and (Self.UrlTarget.ID = List[J].UrlTarget.ID) do
    -    begin
    -      List[J].Hover := Value;
    -      Dec(J);
    -    end;
    -  end;
    -end;
    -
    -function TFontObj.GetURL: ThtString;
    -begin
    -  try
    -    Result := UrlTarget.Url;
    -  except
    -    Result := '';
    -{$IFDEF DebugIt}
    -    //ShowMessage('Bad TFontObj, htmlsubs.pas, TFontObj.GetUrl');
    -{$ENDIF}
    -  end;
    -end;
    -
    -procedure TFontObj.FontChanged;
    -begin
    -  tmHeight := TheFont.tmHeight;
    -  tmMaxCharWidth := TheFont.tmMaxCharWidth;
    -  FontHeight := TheFont.tmHeight + TheFont.tmExternalLeading;
    -  Descent := TheFont.tmDescent;
    -  if fsItalic in TheFont.Style then {estimated overhang}
    -    Overhang := TheFont.tmheight div 10
    -  else
    -    Overhang := 0;
    -  TheFont.Charset := TheFont.tmCharset;
    -end;
    -
    -function TFontObj.GetOverhang: Integer;
    -begin
    -  Result := Overhang;
    -end;
    -
    -//-- BG ---------------------------------------------------------- 17.06.2012 --
    -function TFontObj.GetFontInfoIndex: FIIndex;
    -begin
    -  if Visited then
    -    if Hover then
    -      Result := HVFont
    -    else
    -      Result := VFont
    -  else
    -    if Hover then
    -      Result := HLFont
    -    else
    -      Result := LFont;
    -end;
    -
    -function TFontObj.GetHeight(var Desc: Integer): Integer;
    -begin
    -  Desc := Descent;
    -  Result := FontHeight;
    -end;
    -
    -constructor TFontList.CreateCopy(ASection: TSection; T: TFontList);
    -var
    -  I: Integer;
    -begin
    -  inherited create;
    -  for I := 0 to T.Count - 1 do
    -    Add(TFontObj.CreateCopy(ASection, T.Items[I]));
    -end;
    -
    -//-- BG ---------------------------------------------------------- 10.02.2013 --
    -function TFontList.GetFont(Index: Integer): TFontObj;
    -begin
    -  Result := inherited Get(Index);
    -end;
    -
    -function TFontList.GetFontAt(Posn: Integer; out OHang: Integer): ThtFont;
    -{given a character index, find the font that's effective there}
    -var
    -  I, PosX: Integer;
    -  F: TFontObj;
    -begin
    -  I := 0;
    -  PosX := 0;
    -  while (I < Count) do
    -  begin
    -    PosX := Items[I].Pos;
    -    Inc(I);
    -    if PosX >= Posn then
    -      Break;
    -  end;
    -  Dec(I);
    -  if PosX > Posn then
    -    Dec(I);
    -  F := Items[I];
    -  OHang := F.Overhang;
    -  Result := F.TheFont;
    -end;
    -
    -//-- BG ---------------------------------------------------------- 25.08.2013 --
    -function TFontList.GetFontObjAt(Posn, Leng: Integer; out Obj: TFontObj): Integer;
    -{Given a position, returns the FontObj which applies there and the number of chars before the font changes}
    -var
    -  I: Integer;
    -begin
    -  I := Count;
    -  while I > 0 do
    -  begin
    -    Dec(I);
    -    Obj := Items[I];
    -    if Obj.Pos <= Posn then
    -    begin
    -      Result := Leng - Posn;
    -      Exit;
    -    end;
    -    Leng := Obj.Pos;
    -  end;
    -  Obj := nil;
    -  Result := Leng - Posn;
    -end;
    -
    -{----------------TFontList.GetFontObjAt}
    -
    -function TFontList.GetFontObjAt(Posn: Integer): TFontObj;
    -{Given a position, returns the FontObj which applies there}
    -var
    -  I: Integer;
    -begin
    -  I := Count;
    -  while I > 0 do
    -  begin
    -    Dec(I);
    -    Result := Items[I];
    -    if Result.Pos <= Posn then
    -      Exit;
    -  end;
    -  Result := nil;
    -end;
    -
    -{----------------TFontList.Decrement}
    -
    -procedure TFontList.Decrement(N: Integer; Document: ThtDocument);
    -{called when a character is removed to change the Position figure}
    -var
    -  I, J: Integer;
    -  FO, FO1: TFontObj;
    -begin
    -  I := 0;
    -  while I < Count do
    -  begin
    -    FO := Items[I];
    -    if FO.Pos > N then
    -      Dec(FO.Pos);
    -    if (I > 0) and (Items[I - 1].Pos = FO.Pos) then
    -    begin
    -      FO1 := Items[I - 1];
    -      J := Document.LinkList.IndexOf(FO1);
    -      if J >= 0 then
    -        Document.LinkList.Delete(J);
    -{$IFNDEF NoTabLink}
    -      if Assigned(FO1.TabControl) then
    -        if FO.UrlTarget.Id = FO1.UrlTarget.ID then
    -        begin {if the same link, transfer the TabControl to the survivor}
    -          FO.TabControl := FO1.TabControl;
    -          FO.TabControl.OnEnter := FO.EnterEvent;
    -          FO.TabControl.OnExit := FO.ExitEvent;
    -          FO1.TabControl := nil;
    -        end
    -        else
    -        begin {remove the TabControl from the TabOrderList}
    -          J := Document.TabOrderList.IndexOfObject(FO1.TabControl);
    -          if J >= 0 then
    -            Document.TabOrderList.Delete(J);
    -        end;
    -{$ENDIF}
    -      Delete(I - 1);
    -    end
    -    else
    -      Inc(I);
    -  end;
    -end;
    -
    -{ TLinkList }
    -
    -//-- BG ---------------------------------------------------------- 10.02.2013 --
    -constructor TLinkList.Create;
    -begin
    -  inherited Create(False);
    -end;
    -
    -{ TImageObj.Create }
    -
    -constructor TImageObj.Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties);
    -var
    -  I: Integer;
    -  S: ThtString;
    -  T: TAttribute;
    -begin
    -  inherited Create(Parent,Position,L,Prop);
    -  for I := 0 to L.Count - 1 do
    -    with L[I] do
    -      case Which of
    -        SrcSy:
    -          FSource := htTrim(Name);
    -
    -        AltSy:
    -          begin
    -            SetAlt(CodePage, Name);
    -            Title := Alt;
    -          end;
    -
    -        BorderSy:
    -          begin
    -            BorderWidth := Min(Max(0, Value), 10);
    -//            if not Prop.HasBorderWidth then
    -//              Prop.BorderWidth := Min(Max(0, Value), 10);
    -//            if not Prop.HasBorderStyle then
    -//              Prop.BorderStyle := bssSolid;
    -          end;
    -
    -        IsMapSy:
    -          IsMap := True;
    -
    -        UseMapSy:
    -          begin
    -            UseMap := True;
    -            S := htUpperCase(htTrim(Name));
    -            if (Length(S) > 1) and (S[1] = '#') then
    -              System.Delete(S, 1, 1);
    -            MapName := S;
    -          end;
    -
    -        TranspSy:
    -          Transparent := itrLLCorner;
    -
    -        ActiveSy:
    -          FHoverImage := True;
    -
    -        NameSy:
    -          Document.IDNameList.AddObject(Name, Self);
    -      end;
    -
    -  NoBorder := (BorderWidth = 0) and (not Prop.HasBorderStyle or not Prop.HasBorderWidth);
    -  T := nil;
    -  if L.Find(TitleSy, T) then
    -    Title := T.Name; {has higher priority than Alt loaded above}
    -end;
    -
    -constructor TImageObj.SimpleCreate(Parent: TCellBasic; const AnURL: ThtString);
    -begin
    -  inherited SimpleCreate(Parent);
    -  FSource := AnURL;
    -end;
    -
    -constructor TImageObj.CreateCopy(Parent: TCellBasic; Source: THtmlNode);
    -var
    -  T: TImageObj absolute Source;
    -begin
    -  inherited CreateCopy(Parent,Source);
    -  AltHeight := T.AltHeight;
    -  AltWidth := T.AltWidth;
    -  FHover := T.FHover;
    -  FHoverImage := T.FHoverImage;
    -  FImage := T.Image;
    -  FSource := T.FSource;
    -  IsMap := T.IsMap;
    -  MapName := T.MapName;
    -  Missing := T.Missing;
    -  ObjHeight := T.ObjHeight;
    -  ObjWidth := T.ObjWidth;
    -  OrigImage := T.OrigImage;
    -  Swapped := T.Swapped;
    -  Transparent := T.Transparent;
    -  UseMap := T.UseMap;
    -end;
    -
    -destructor TImageObj.Destroy;
    -begin
    -  if not IsCopy then
    -  begin
    -    if (Source <> '') and Assigned(OrigImage) then
    -      Document.ImageCache.DecUsage(htUpperCase(htTrim(Source)));
    -    if (Image is ThtGifImage) and ThtGifImage(Image).Gif.IsCopy then
    -      Image.Free;
    -  end;
    -  inherited Destroy;
    -end;
    -
    -function TImageObj.GetGraphic: TGraphic;
    -begin
    -  if (Image = nil) or (Image = ErrorImage) then
    -    Result := nil
    -  else
    -    Result := Image.Graphic;
    -end;
    -
    -procedure TImageObj.SetHover(Value: ThtHover);
    -begin
    -  if (Value <> FHover) and FHoverImage and (Image is ThtGifImage) then
    -    with ThtGifImage(Image).Gif do
    -    begin
    -      if Value <> hvOff then
    -        case NumFrames of
    -          2: CurrentFrame := 2;
    -          3: if Value = hvOverDown then
    -              CurrentFrame := 3
    -            else
    -              CurrentFrame := 2;
    -        else
    -          begin
    -            Animate := True;
    -            Document.AniList.Add(Image);
    -          end;
    -        end
    -      else
    -      begin
    -        Animate := False;
    -        if NumFrames <= 3 then
    -          CurrentFrame := 1;
    -        Document.AniList.Remove(Image);
    -      end;
    -      FHover := Value;
    -      Document.PPanel.Invalidate;
    -    end;
    -end;
    -
    -{----------------TImageObj.ReplaceImage}
    -
    -procedure TImageObj.ReplaceImage(NewImage: TStream);
    -var
    -  TmpImage: ThtImage;
    -  I: Integer;
    -begin
    -  try
    -    Transparent := itrNone;
    -    TmpImage := LoadImageFromStream(NewImage, Transparent);
    -    if Assigned(TmpImage) then
    -    begin
    -      // remove current image
    -      Document.AniList.Remove(FImage);
    -      if not Swapped then
    -      begin
    -        {OrigImage is left in cache and kept}
    -        Swapped := True;
    -      end
    -      else {swapped already}
    -      begin
    -        FImage.Free;
    -      end;
    -
    -      // set new image
    -      FImage := TmpImage;
    -      if FImage.IsAnimated then
    -      begin
    -        if not FHoverImage then
    -        begin
    -          FImage.Animate := True;
    -          Document.AniList.Add(FImage);
    -        end
    -        else
    -        begin
    -          FImage.Animate := False;
    -          SetHover(hvOff);
    -        end;
    -      end;
    -
    -      if Missing then
    -      begin {if waiting for image, no longer want it}
    -        with Document.MissingImages do
    -          for I := 0 to count - 1 do
    -            if Objects[I] = Self then
    -            begin
    -              Delete(I);
    -              break;
    -            end;
    -        Missing := False;
    -      end;
    -
    -      Document.PPanel.Invalidate;
    -    end;
    -  except
    -    // replacing image failed
    -  end;
    -end;
    -
    -{----------------TImageObj.InsertImage}
    -
    -function TImageObj.InsertImage(const UName: ThtString; Error: Boolean; out Reformat: Boolean): Boolean;
    -var
    -  TmpImage: ThtImage;
    -  FromCache, DelayDummy: Boolean;
    -begin
    -  Result := False;
    -  Reformat := False;
    -  if FImage = DefImage then
    -  begin
    -    Result := True;
    -    if Error then
    -      FImage := ErrorImage
    -    else
    -    begin
    -      TmpImage := Document.GetTheImage(UName, Transparent, FromCache, DelayDummy);
    -      if TmpImage = nil then
    -        Exit;
    -
    -      if TmpImage.IsAnimated then
    -      begin
    -        if FromCache then {it would be}
    -          FImage := TmpImage.Clone {it's in Cache already, make copy}
    -        else
    -          FImage := TmpImage;
    -        if not FHoverImage then
    -        begin
    -          FImage.Animate := True;
    -          Document.AniList.Add(FImage);
    -          if Assigned(Document.Timer) then
    -            Document.Timer.Enabled := True;
    -        end
    -        else
    -          FImage.Animate := False;
    -      end
    -      else
    -        FImage := TmpImage;
    -      OrigImage := TmpImage;
    -    end;
    -    Missing := False;
    -
    -    if not ClientSizeKnown then
    -      Reformat := True; {need to get the dimensions}
    -  end;
    -end;
    -
    -{----------------TImageObj.DrawLogic}
    -
    -procedure TImageObj.DrawLogicInline(Canvas: TCanvas; FO: TFontObj; AvailableWidth, AvailableHeight: Integer);
    -{calculate the height and width}
    -var
    -  TmpImage: ThtImage;
    -  ViewImages, FromCache: Boolean;
    -  Rslt: ThtString;
    -  ARect: TRect;
    -  SubstImage: Boolean;
    -  HasBlueBox: Boolean;
    -  UName: ThtString;
    -begin
    -  ViewImages := Document.ShowImages;
    -  case FDisplay of
    -    pdNone:
    -    begin
    -      ObjHeight := 0;
    -      ObjWidth := 0;
    -
    -      ClientHeight := ObjHeight;
    -      ClientWidth := ObjWidth;
    -      Exit;
    -    end;
    -  end;
    -
    -  if ViewImages then
    -  begin
    -    if FImage = nil then
    -    begin
    -      TmpImage := nil;
    -      UName := htTrim(FSource);
    -      if UName <> '' then
    -      begin
    -        if not Assigned(Document.GetBitmap) and not Assigned(Document.GetImage) then
    -          FSource := htTrim(Document.TheOwner.HtmlExpandFilename(FSource))
    -        else if Assigned(Document.OnExpandName) then
    -        begin
    -          Document.OnExpandName(Document.TheOwner, FSource, Rslt);
    -          FSource := htTrim(Rslt);
    -        end;
    -        if Document.MissingImages.IndexOf(FSource) = -1 then
    -          TmpImage := Document.GetTheImage(FSource, Transparent, FromCache, Missing)
    -        else
    -          Missing := True; {already in list, don't request it again}
    -      end;
    -
    -      if TmpImage = nil then
    -      begin
    -        if Missing then
    -        begin
    -          FImage := DefImage;
    -          Document.MissingImages.AddObject(FSource, Self); {add it even if it's there already}
    -        end
    -        else
    -        begin
    -          FImage := ErrorImage;
    -        end;
    -      end
    -      else if TmpImage.IsAnimated then
    -      begin
    -        if FromCache then
    -          FImage := TmpImage.Clone {it's in Cache already, make copy}
    -        else
    -          FImage := TmpImage;
    -        if not FHoverImage then
    -        begin
    -          FImage.Animate := True;
    -          Document.AniList.Add(FImage);
    -          if Assigned(Document.Timer) then
    -            Document.Timer.Enabled := True;
    -        end
    -        else
    -          FImage.Animate := False;
    -      end
    -      else
    -        FImage := TmpImage;
    -      OrigImage := TmpImage;
    -    end;
    -  end
    -  else
    -    FImage := DefImage;
    -
    -  SubstImage := (Image = ErrorImage) or (Image = DefImage);
    -
    -  HasBlueBox := not NoBorder and Assigned(FO) and (FO.URLTarget.Url <> '');
    -  if HasBlueBox then
    -    BorderWidth := Max(1, BorderWidth);
    -
    -  if not ClientSizeKnown or PercentWidth or PercentHeight then
    -  begin
    -    CalcSize(AvailableWidth, AvailableHeight, Image.Width, Image.Height, not SubstImage);
    -    ObjWidth  := ClientWidth; // - MargArray[BorderLeftWidth] - MargArray[BorderRightWidth];
    -    ObjHeight := ClientHeight;// - MargArray[BorderTopWidth] - MargArray[BorderBottomWidth];
    -  end;
    -
    -  if not ViewImages or SubstImage then
    -  begin
    -    if not SubstImage and ((SpecWidth >= 0) or (SpecHeight >= 0)) then
    -    begin {size to whatever is specified}
    -      AltWidth := ObjWidth;
    -      AltHeight := ObjHeight;
    -    end
    -    else
    -    begin
    -      if FAlt <> '' then {Alt text and no size specified, take as much space as necessary}
    -      begin
    -        Canvas.Font.Name := FontSans; {use same font as in Draw}
    -        Canvas.Font.Size := 8;
    -        ARect := Rect(0, 0, 0, 0);
    -        DrawTextW(Canvas.Handle, PWideChar(FAlt + CRLF), -1, ARect, DT_CALCRECT);
    -        with ARect do
    -        begin
    -          AltWidth := Right + 16 + 8 + 2;
    -          AltHeight := Max(16 + 8, Bottom);
    -        end;
    -      end
    -      else
    -      begin {no Alt text and no size specified}
    -        AltWidth := Max(ObjWidth, 16 + 8);
    -        AltHeight := Max(ObjHeight, 16 + 8);
    -      end;
    -      ClientHeight := AltHeight;
    -      ClientWidth  := AltWidth;
    -    end;
    -  end;
    -
    -
    -  DrawRect.Left := DrawXX;
    -  DrawRect.Top := DrawYY;
    -  DrawRect.Right := DrawRect.Left + ClientWidth;
    -  DrawRect.Bottom := DrawRect.Top + ClientHeight;
    -end;
    -
    -{----------------TImageObj.DoDraw}
    -//var
    -//  LastExceptionMessage: String;
    -//  LastDdImage: ThtImage;
    -procedure TImageObj.DoDraw(Canvas: TCanvas; XX, Y: Integer; ddImage: ThtImage);
    -{Y relative to top of display here}
    -var
    -  W, H: Integer;
    -begin
    -  if (ddImage = ErrorImage) or (ddImage = DefImage) then
    -  begin
    -    W := ddImage.Width;
    -    H := ddImage.Height;
    -  end
    -  else if ddImage = nil then
    -    exit
    -  else
    -  begin
    -    W := ObjWidth;
    -    H := ObjHeight;
    -  end;
    -  try
    -    // Yunqa.de removed: ddImage.Transp := Transparent;
    -    if (W > 0) and (H > 0) then
    -      if IsCopy then
    -        ddImage.Print(Canvas, XX, Y, W, H, clWhite)
    -      else
    -        ddImage.Draw(Canvas, XX, Y, W, H);
    -  except
    -    //on E: Exception do
    -    //begin
    -    //  LastExceptionMessage := E.Message;
    -    //  LastDdImage := ddImage;
    -    //end;
    -  end;
    -end;
    -
    -{----------------TImageObj.Draw}
    -
    -//-- BG ---------------------------------------------------------- 12.06.2010 --
    -procedure GetRaisedColors(SectionList: ThtDocument; Canvas: TCanvas; out Light, Dark: TColor);  {$ifdef UseInline} inline; {$endif}
    - {$ifdef UseInline} inline; {$endif}
    -var
    -  White, BlackBorder: Boolean;
    -begin
    -  BlackBorder := SectionList.Printing and SectionList.PrintMonoBlack and
    -    (GetDeviceCaps(Canvas.Handle, BITSPIXEL) = 1) and (GetDeviceCaps(Canvas.Handle, PLANES) = 1);
    -  if BlackBorder then
    -  begin
    -    Light := clBlack;
    -    Dark := clBlack;
    -  end
    -  else
    -  begin
    -    White := SectionList.Printing or (ThemedColor(SectionList.Background{$ifdef has_StyleElements},seFont in SectionList.StyleElements{$endif}) = clWhite);
    -    Dark := ThemedColor(clBtnShadow{$ifdef has_StyleElements},seFont in SectionList.StyleElements{$endif} );
    -    if White then
    -      Light := clSilver
    -    else
    -      Light := ThemedColor(clBtnHighLight{$ifdef has_StyleElements},seFont in SectionList.StyleElements{$endif});
    -  end;
    -end;
    -
    -//BG, 15.10.2010: issue 28: Borland C++ Builder does not accept an array as a result of a function.
    -// Thus move htStyles and htColors from HtmlUn2.pas to HtmlSubs.pas the only unit where they are used
    -
    -function htStyles(P0, P1, P2, P3: ThtBorderStyle): ThtBorderStyleArray;
    - {$ifdef UseInline} inline; {$endif}
    -begin
    -  Result[0] := P0;
    -  Result[1] := P1;
    -  Result[2] := P2;
    -  Result[3] := P3;
    -end;
    -
    -function htColors(C0, C1, C2, C3: TColor): ThtColorArray;
    - {$ifdef UseInline} inline; {$endif}
    -begin
    -  Result[0] := C0;
    -  Result[1] := C1;
    -  Result[2] := C2;
    -  Result[3] := C3;
    -end;
    -
    -//-- BG ---------------------------------------------------------- 12.06.2010 --
    -function htRaisedColors(Light, Dark: TColor; Raised: Boolean): ThtColorArray; overload;
    -  {$ifdef UseInline} inline; {$endif}
    -begin
    -  if Raised then
    -    Result := htColors(Light, Light, Dark, Dark)
    -  else
    -    Result := htColors(Dark, Dark, Light, Light);
    -end;
    -
    -//-- BG ---------------------------------------------------------- 12.06.2010 --
    -function htRaisedColors(SectionList: ThtDocument; Canvas: TCanvas; Raised: Boolean): ThtColorArray; overload;
    -  {$ifdef UseInline} inline; {$endif}
    -var
    -  Light, Dark: TColor;
    -begin
    -  GetRaisedColors(SectionList, Canvas, Light, Dark);
    -  Result := htRaisedColors(Light, Dark, Raised);
    -end;
    -
    -//-- BG ---------------------------------------------------------- 12.06.2010 --
    -procedure RaisedRectColor(Canvas: TCanvas;
    -  const ORect, IRect: TRect;
    -  const Colors: ThtColorArray;
    -  Styles: ThtBorderStyleArray); overload;
    -  {$ifdef UseInline} inline; {$endif}
    -{Draws colored raised or lowered rectangles for table borders}
    -begin
    -  DrawBorder(Canvas, ORect, IRect, Colors, Styles, clNone, False{$ifdef has_StyleElements},[seClient,seFont,seBorder]{$endif});
    -end;
    -
    -procedure RaisedRect(SectionList: ThtDocument; Canvas: TCanvas;
    -  X1, Y1, X2, Y2: Integer;
    -  Raised: Boolean;
    -  W: Integer);
    -  {$ifdef UseInline} inline; {$endif}
    -{Draws raised or lowered rectangles for table borders}
    -begin
    -  RaisedRectColor(Canvas,
    -    Rect(X1, Y1, X2, Y2),
    -    Rect(X1 + W, Y1 + W, X2 - W, Y2 - W),
    -    htRaisedColors(SectionList, Canvas, Raised),
    -    htStyles(bssSolid, bssSolid, bssSolid, bssSolid));
    -end;
    -
    -procedure TImageObj.DrawInline(Canvas: TCanvas; X, Y, YBaseline: Integer; FO: TFontObj);
    -var
    -  TmpImage: ThtImage;
    -  MiddleAlignTop: Integer;
    -  ViewImages: Boolean;
    -  SubstImage: Boolean;
    -  Ofst: Integer;
    -  SaveColor: TColor;
    -  ARect: TRect;
    -//  SaveWidth: Integer;
    -//  SaveStyle: TPenStyle;
    -  YY: Integer;
    -//  ORect, IRect: TRect;
    -{$ifdef has_StyleElements}
    -  LStyle : TStyleElements;
    -{$endif}
    -begin
    -  ViewImages := Document.ShowImages;
    -  Dec(Y, Document.YOff);
    -  Dec(YBaseLine, Document.YOff);
    -{$ifdef has_StyleElements}
    -  LStyle := Document.StyleElements;
    -{$endif}
    -
    -  if ViewImages then
    -    TmpImage := Image
    -  else
    -    TmpImage := DefImage;
    -  SubstImage := not ViewImages or (TmpImage = ErrorImage) or (TmpImage = DefImage); {substitute image}
    -
    -  with Canvas do
    -  begin
    -    Brush.Style := bsClear;
    -    Font.Size := 8;
    -    Font.Name := FontSans; {make this a property?}
    -    Font.Style := Font.Style - [fsBold];
    -  end;
    -
    -  if SubstImage then
    -    Ofst := 4
    -  else
    -    Ofst := 0;
    -
    -  if VertAlign = AMiddle then
    -    MiddleAlignTop := YBaseLine + FO.Descent - (FO.tmHeight div 2) - ((ClientHeight - VSpaceT + VSpaceB) div 2)
    -  else
    -    MiddleAlignTop := 0; {not used}
    -
    -  DrawXX := X;
    -  DrawYY := Y;
    -  if Floating = ANone then
    -  begin
    -    case Positioning of
    -      posAbsolute:
    -      begin
    -        ARect := ContainingBox;
    -        if not IsAuto(Positions[reLeft]) then DrawXX := Positions[reLeft] + ARect.Left;
    -        if not IsAuto(Positions[reTop ]) then DrawYY := Positions[reTop ] + ARect.Top;
    -      end;
    -
    -      posFixed:
    -      begin
    -        ARect := FDocument.ViewPort;
    -        if not IsAuto(Positions[reLeft]) then DrawXX := Positions[reLeft] + ARect.Left;
    -        if not IsAuto(Positions[reTop ]) then DrawYY := Positions[reTop ] + ARect.Top;
    -      end;
    -
    -    else
    -      case VertAlign of
    -        ATop, ANone:
    -          DrawYY := Y + VSpaceT;
    -        AMiddle:
    -          DrawYY := MiddleAlignTop;
    -        ABottom, ABaseline:
    -          DrawYY := YBaseLine - ClientHeight - VSpaceB;
    -      end;
    -
    -      if Positioning = posRelative then
    -      begin
    -        if not IsAuto(Positions[reLeft]) then Inc(DrawXX, Positions[reLeft]);
    -        if not IsAuto(Positions[reTop ]) then Inc(DrawYY, Positions[reTop ]);
    -      end;
    -
    -    end;
    -//    if MargArray[BorderLeftWidth] > 0 then
    -//      Inc(DrawXX, MargArray[BorderLeftWidth]);
    -//    if MargArray[BorderTopWidth] > 0 then
    -//      Inc(DrawYY, MargArray[BorderTopWidth]);
    -  end;
    -
    -  if not SubstImage or ((AltHeight >= 16 + 8) and (AltWidth >= 16 + 8)) then
    -    Self.DoDraw(Canvas, DrawXX + Ofst, DrawYY + Ofst, TmpImage);
    -  Inc(DrawYY, Document.YOff);
    -
    -  DrawRect.Left := DrawXX;
    -  DrawRect.Top := DrawYY;
    -  DrawRect.Right := DrawRect.Left + ClientWidth;
    -  DrawRect.Bottom := DrawRect.Top + ClientHeight;
    -
    -  SetTextAlign(Canvas.Handle, TA_Top);
    -  if SubstImage and (BorderWidth = 0) then
    -  begin
    -    Canvas.Font.Color := ThemedColor(FO.TheFont.Color{$ifdef has_StyleElements},seFont in LStyle  {$endif});
    -  {calc the offset from the image's base to the alt= text baseline}
    -    case VertAlign of
    -      ATop, ANone:
    -        begin
    -          if FAlt <> '' then
    -            WrapTextW(         Canvas, X + 24, Y + Ofst                              , X + AltWidth - 2, Y + AltHeight - 1, FAlt);
    -          RaisedRect(Document, Canvas, X     , Y                                     , X + AltWidth    , Y + AltHeight    , False, 1);
    -        end;
    -      AMiddle:
    -        begin {MiddleAlignTop is always initialized}
    -          if FAlt <> '' then
    -            WrapTextW(         Canvas, X + 24, MiddleAlignTop + Ofst                 , X + AltWidth - 2, MiddleAlignTop + AltHeight - 1, FAlt);
    -          RaisedRect(Document, Canvas, X     , MiddleAlignTop                        , X + AltWidth    , MiddleAlignTop + AltHeight    , False, 1);
    -        end;
    -      ABottom, ABaseline:
    -        begin
    -          if FAlt <> '' then
    -            WrapTextW(         Canvas, X + 24, YBaseLine - AltHeight + Ofst - VSpaceB, X + AltWidth - 2, YBaseLine - VSpaceB - 1, FAlt);
    -          RaisedRect(Document, Canvas, X     , YBaseLine - AltHeight        - VSpaceB, X + AltWidth    , YBaseLine - VSpaceB    , False, 1);
    -        end;
    -    end;
    -  end;
    -
    -  if (MargArray[BorderTopWidth] > 0) or (MargArray[BorderRightWidth] > 0) or (MargArray[BorderBottomWidth] > 0) or (MargArray[BorderLeftWidth] > 0) then
    -    with Canvas do
    -    begin
    -//      SaveColor := Pen.Color;
    -//      SaveWidth := Pen.Width;
    -//      SaveStyle := Pen.Style;
    -      Font.Color := ThemedColor(FO.TheFont.Color{$ifdef has_StyleElements},seFont in Document.StyleElements {$endif});
    -//      Pen.Color := Font.Color;
    -//      Pen.Width := BorderSize;
    -//      Pen.Style := psInsideFrame;
    -      try
    -        if (FAlt <> '') and SubstImage then
    -        begin
    -          {output Alt message}
    -          YY := DrawYY - Document.YOff;
    -          case VertAlign of
    -            ATop, ANone:
    -              WrapTextW(Canvas, DrawXX + 24, YY + Ofst, DrawXX + AltWidth - 2, YY + AltHeight - 1, FAlt);
    -            AMiddle:
    -              WrapTextW(Canvas, DrawXX + 24, YY + Ofst, DrawXX + AltWidth - 2, YY + AltHeight - 1, FAlt);
    -            ABottom, ABaseline:
    -              WrapTextW(Canvas, DrawXX + 24, YY + Ofst, DrawXX + AltWidth - 2, YY + AltHeight - 1, FAlt);
    -          end;
    -        end;
    -
    -//        {draw border}
    -//        ORect := Rect(DrawXX, DrawYY, X + ClientWidth, DrawYY + ClientHeight);
    -//        IRect.Left   := ORect.Left   + MargArray[BorderLeftWidth  ];
    -//        IRect.Top    := ORect.Top    + MargArray[BorderTopWidth   ];
    -//        IRect.Right  := ORect.Right  - MargArray[BorderRightWidth ];
    -//        IRect.Bottom := ORect.Bottom - MargArray[BorderBottomWidth];
    -//        DrawBorder(Canvas, ORect, IRect,
    -//          htColors(MargArray[BorderLeftColor], MargArray[BorderTopColor], MargArray[BorderRightColor], MargArray[BorderBottomColor]),
    -//          htStyles(ThtBorderStyle(MargArray[BorderLeftStyle]), ThtBorderStyle(MargArray[BorderTopStyle]), ThtBorderStyle(MargArray[BorderRightStyle]), ThtBorderStyle(MargArray[BorderBottomStyle])),
    -//          MargArray[BackgroundColor], Document.Printing{$ifdef has_StyleElements}, Document.StyleElements {$endif})
    -      finally
    -//        Pen.Color := SaveColor;
    -//        Pen.Width := SaveWidth;
    -//        Pen.Style := SaveStyle;
    -      end;
    -    end;
    -
    -  if (Assigned(MyFormControl) and MyFormControl.Active or FO.Active) or
    -    IsCopy and Assigned(Document.LinkDrawnEvent) and (FO.UrlTarget.Url <> '')
    -  then
    -    with Canvas do
    -    begin
    -      SaveColor := SetTextColor(Handle, clBlack);
    -      Brush.Color := clWhite;
    -      case VertAlign of
    -        ATop, ANone:
    -          ARect := Rect(X, Y + VSpaceT, X + ClientWidth, Y + VSpaceT + ClientHeight);
    -        AMiddle:
    -          ARect := Rect(X, MiddleAlignTop, X + ClientWidth, MiddleAlignTop + ClientHeight);
    -        ABottom, ABaseline:
    -          ARect := Rect(X, YBaseLine - ClientHeight - VSpaceB, X + ClientWidth, YBaseLine - VSpaceB);
    -      end;
    -      if not IsCopy then
    -      begin
    -        if Document.TheOwner.ShowFocusRect then //MK20091107
    -          Canvas.DrawFocusRect(ARect);  {draw focus box}
    -      end
    -      else
    -        Document.LinkDrawnEvent(Document.TheOwner, Document.LinkPage,
    -          FO.UrlTarget.Url, FO.UrlTarget.Target, ARect);
    -      SetTextColor(handle, SaveColor);
    -    end;
    -end;
    -
    -{----------------THtmlForm.Create}
    -
    -constructor THtmlForm.Create(AMasterList: ThtDocument; L: TAttributeList);
    -var
    -  I: Integer;
    -begin
    -  inherited Create;
    -  Document := AMasterList;
    -  AMasterList.HtmlFormList.Add(Self);
    -  Method := 'Get';
    -  if Assigned(L) then
    -    for I := 0 to L.Count - 1 do
    -      with L[I] do
    -        case Which of
    -          MethodSy: Method := Name;
    -          ActionSy: Action := Name;
    -          TargetSy: Target := Name;
    -          EncTypeSy: EncType := Name;
    -        end;
    -  ControlList := TFormControlObjList.Create(True);
    -end;
    -
    -destructor THtmlForm.Destroy;
    -begin
    -  ControlList.Free;
    -  inherited Destroy;
    -end;
    -
    -procedure THtmlForm.InsertControl(Ctrl: TFormControlObj);
    -begin
    -  ControlList.Add(Ctrl);
    -  if not (Ctrl is THiddenFormControlObj) then
    -    Inc(NonHiddenCount);
    -end;
    -
    -procedure THtmlForm.DoRadios(Radio: TRadioButtonFormControlObj);
    -var
    -  S: ThtString;
    -  Ctrl: TFormControlObj;
    -  RadioButton: TRadioButtonFormControlObj absolute Ctrl;
    -  I: Integer;
    -begin
    -  if Radio.FName <> '' then
    -  begin
    -    S := Radio.FName;
    -    for I := 0 to ControlList.Count - 1 do
    -    begin
    -      Ctrl := ControlList[I];
    -      if (Ctrl is TRadioButtonFormControlObj) and (Ctrl <> Radio) then
    -        if htCompareText(RadioButton.FName, S) = 0 then
    -        begin
    -          RadioButton.Checked := False;
    -          RadioButton.TabStop := False; {first check turns off other tabstops}
    -          RadioButton.DoOnChange;
    -        end;
    -    end;
    -  end;
    -end;
    -
    -procedure THtmlForm.AKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    -var
    -  S: ThtString;
    -  Ctrl: TFormControlObj;
    -  I: Integer;
    -  B: Boolean;
    -begin
    -  if (Key in [vk_up, vk_down, vk_left, vk_right]) and (Sender is TFormRadioButton) then
    -  begin
    -    S := TFormRadioButton(Sender).IDName;
    -    B := False;
    -    if Key in [vk_up, vk_left] then
    -      for I := ControlList.Count - 1 downto 0 do
    -      begin
    -        Ctrl := ControlList[I];
    -        if (Ctrl is TRadioButtonFormControlObj) and htSameText(Ctrl.FName, S) then
    -        begin
    -          if B then
    -          begin
    -            ControlList[I].TheControl.SetFocus;
    -            break;
    -          end;
    -          if Ctrl.TheControl = Sender then
    -            B := True
    -        end;
    -      end
    -    else
    -      for I := 0 to ControlList.Count - 1 do
    -      begin
    -        Ctrl := ControlList[I];
    -        if (Ctrl is TRadioButtonFormControlObj) and htSameText(Ctrl.FName, S) then
    -        begin
    -          if B then
    -          begin
    -            ControlList[I].TheControl.SetFocus;
    -            break;
    -          end;
    -          if Ctrl.TheControl = Sender then
    -            B := True
    -        end;
    -      end;
    -  end
    -  else {send other keys to THtmlViewer}
    -    Document.TheOwner.KeyDown(Key, Shift);
    -end;
    -
    -procedure THtmlForm.ResetControls;
    -var
    -  I: Integer;
    -begin
    -  for I := 0 to ControlList.Count - 1 do
    -    TFormControlObj(ControlList.Items[I]).ResetToValue;
    -end;
    -
    -procedure THtmlForm.ControlKeyPress(Sender: TObject; var Key: Char);
    -begin
    -  if (Sender is ThtEdit) then
    -    if (Key = #13) then
    -    begin
    -      SubmitTheForm('');
    -      Key := #0;
    -    end;
    -end;
    -
    -function THtmlForm.GetFormSubmission: ThtStringList;
    -var
    -  I, J: Integer;
    -  S: ThtString;
    -begin
    -  Result := ThtStringList.Create;
    -  for I := 0 to ControlList.Count - 1 do
    -    with ControlList[I] do
    -    begin
    -      J := 0;
    -      while GetSubmission(J, S) do
    -      begin
    -        if S <> '' then
    -          Result.Add(S);
    -        Inc(J);
    -      end;
    -    end;
    -end;
    -
    -procedure THtmlForm.SubmitTheForm(const ButtonSubmission: ThtString);
    -var
    -  I, J: Integer;
    -  SL: ThtStringList;
    -  S: ThtString;
    -begin
    -  if Assigned(Document.SubmitForm) then
    -  begin
    -    SL := ThtStringList.Create;
    -    for I := 0 to ControlList.Count - 1 do
    -      with TFormControlObj(ControlList.Items[I]) do
    -      begin
    -        J := 0;
    -        if not Disabled then
    -          while GetSubmission(J, S) do
    -          begin
    -            if S <> '' then
    -              SL.Add(S);
    -            Inc(J);
    -          end;
    -      end;
    -    if ButtonSubmission <> '' then
    -      SL.Add(ButtonSubmission);
    -    Document.SubmitForm(Document.TheOwner, Action, Target, EncType, Method, SL);
    -  end;
    -end;
    -
    -procedure THtmlForm.SetFormData(SL: ThtStringList);
    -var
    -  I, J, K, Index: Integer;
    -  Value: ThtString;
    -  FormControl: TFormControlObj;
    -begin
    -  for I := 0 to ControlList.Count - 1 do
    -  begin
    -    FormControl := TFormControlObj(ControlList[I]);
    -    FormControl.SetDataInit;
    -    Index := 0;
    -    for J := 0 to SL.Count - 1 do
    -      if htCompareText(FormControl.FName, SL.Names[J]) = 0 then
    -      begin
    -        K := Pos('=', SL[J]);
    -        if K > 0 then
    -        begin
    -          Value := Copy(SL[J], K + 1, Length(SL[J]) - K);
    -          FormControl.SetData(Index, Value);
    -          Inc(Index);
    -        end;
    -      end;
    -  end;
    -end;
    -
    -procedure THtmlForm.SetSizes(Canvas: TCanvas);
    -var
    -  I: Integer;
    -begin
    -  for I := 0 to ControlList.Count - 1 do
    -    TFormControlObj(ControlList.Items[I]).SetHeightWidth(Canvas);
    -end;
    -
    -{----------------TFormControlObj.Create}
    -
    -constructor TFormControlObj.Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties);
    -var
    -  I: Integer;
    -begin
    -  inherited Create(Parent,Position,L,Prop);
    -  StartCurs := Position;
    -  if not Assigned(Document.CurrentForm) then {maybe someone forgot the 
    tag} - Document.CurrentForm := THtmlForm.Create(Document, nil); - Document.FormControlList.Add(Self); - MyForm := Document.CurrentForm; - for I := 0 to L.Count - 1 do - with L[I] do - case Which of - ValueSy: Self.Value := Name; - NameSy: Self.FName := Name; - IDSy: FID := Name; - OnClickSy: OnClickMessage := Name; - OnFocusSy: OnFocusMessage := Name; - OnBlurSy: OnBlurMessage := Name; - OnChangeSy: OnChangeMessage := Name; - TitleSy: FTitle := Name; - DisabledSy: Disabled := (Lowercase(Name) <> 'no') and (Name <> '0'); - ReadonlySy: ReadOnly := True; - - TabIndexSy: - if Value > 0 then - {Adding leading 0's to the number ThtString allows it to be sorted numerically, - and the Count takes care of duplicates} - with Document.TabOrderList do - AddObject(Format('%.5d%.3d', [Value, Count]), Self); - - end; - - //FAttributeList := L.CreateStringList; - VertAlign := ABottom; {ABaseline set individually} - MyForm.InsertControl(Self); -end; - -constructor TFormControlObj.CreateCopy(Parent: TCellBasic; Source: THtmlNode); -var - T: TFormControlObj absolute Source; -begin - inherited CreateCopy(Parent,Source); - System.Move(T.MyForm, MyForm, PtrSub(@ShowIt, @MyForm)); - FId := T.FID; - FName := T.FName; -end; - -destructor TFormControlObj.Destroy; -begin - //FAttributeList.Free; - PaintBitmap.Free; - inherited Destroy; -end; - -procedure TFormControlObj.HandleMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); -begin - Document.TheOwner.ControlMouseMove(Self, Shift, X, Y); -end; - -//-- BG ---------------------------------------------------------- 15.01.2011 -- -procedure TFormControlObj.Hide; -begin - TheControl.Hide; -end; - -//-- BG ---------------------------------------------------------- 16.01.2011 -- -function TFormControlObj.IsHidden: Boolean; -begin - Result := False; -end; - -procedure TFormControlObj.ProcessProperties(Prop: TProperties); -var - MargArrayO: ThtVMarginArray; - MargArray: ThtMarginArray; -begin - Prop.GetVMarginArray(MargArrayO); - EmSize := Prop.EmSize; - ExSize := Prop.ExSize; - PercentWidth := (VarIsStr(MargArrayO[piWidth])) and (System.Pos('%', MargArrayO[piWidth]) > 0); - ConvInlineMargArray(MargArrayO, 100, 200, EmSize, ExSize, 4, MargArray); - - VSpaceT := 1; - VSpaceB := 1; - - if MargArray[MarginLeft] <> IntNull then - HSpaceL := MargArray[MarginLeft]; - if MargArray[MarginRight] <> IntNull then - HSpaceR := MargArray[MarginRight]; - if MargArray[MarginTop] <> IntNull then - VSpaceT := MargArray[MarginTop]; - if MargArray[MarginBottom] <> IntNull then - VSpaceB := MargArray[MarginBottom]; - if Prop.HasBorderStyle then - begin - Inc(HSpaceL, MargArray[BorderLeftWidth]); - Inc(HSpaceR, MargArray[BorderRightWidth]); - BordT := MargArray[BorderTopWidth]; - BordB := MargArray[BorderBottomWidth]; - Inc(VSpaceT, BordT); - Inc(VSpaceB, BordB); - end; - - if MargArray[piWidth] > 0 then {excludes IntNull and Auto} - if PercentWidth then - begin - if MargArray[piWidth] <= 100 then - FWidth := MargArray[piWidth] - else - PercentWidth := False; - end - else - FWidth := MargArray[piWidth]; - if MargArray[piHeight] > 0 then - FHeight := MargArray[piHeight] - BordT - BordB; - Prop.GetVertAlign(VertAlign); - Prop.GetFloat(FFloating); - - BkColor := Prop.GetBackgroundColor; -end; - -procedure TFormControlObj.EnterEvent(Sender: TObject); -{Once form control entered, insure all form controls are tab active} -begin - if IsCopy then - Exit; - Active := True; - Document.PPanel.Invalidate; - Document.ControlEnterEvent(Self); -{$IFNDEF FastRadio} - Document.FormControlList.ActivateTabbing; -{$ENDIF} - if Assigned(Document.ObjectFocus) and (OnFocusMessage <> '') then - Document.ObjectFocus(Document.TheOwner, Self, OnFocusMessage); - if OnChangeMessage <> '' then - SaveContents; -end; - -procedure TFormControlObj.SaveContents; -{Save the current value to see if it has changed when focus is lost} -begin -end; - -procedure TFormControlObj.ExitEvent(Sender: TObject); -begin -{$IFNDEF FastRadio} - Document.AdjustFormControls; -{$ENDIF} - Active := False; - if OnChangeMessage <> '' then - DoOnChange; - if Assigned(Document.ObjectBlur) and (OnBlurMessage <> '') then - Document.ObjectBlur(Document.TheOwner, Self, OnBlurMessage); - Document.PPanel.Invalidate; -end; - -procedure TFormControlObj.DoOnChange; -begin -end; - -procedure TFormControlObj.DrawInline1(Canvas: TCanvas; X1, Y1: Integer); -begin - if not IsCopy then - begin - Show; - Left := X1; - Top := Y1; - end; -end; - -//-- BG ---------------------------------------------------------- 16.09.2013 -- -procedure TFormControlObj.DrawInline(Canvas: TCanvas; X, Y, YBaseline: Integer; FO: TFontObj); -begin - DrawInline1(Canvas, X, Y); -end; - -//-- BG ---------------------------------------------------------- 28.08.2013 -- -procedure TFormControlObj.DrawLogicInline(Canvas: TCanvas; FO: TFontObj; AvailableWidth, AvailableHeight: Integer); -begin -// inherited DrawLogicInline(Canvas,FO,AvailableWidth,AvailableHeight); - if PercentWidth then - ClientWidth := Max(10, Min(MulDiv(FWidth, AvailableWidth, 100), AvailableWidth - HSpaceL - HSpaceR)); - if PercentHeight then - ClientHeight := Max(10, Min(MulDiv(FWidth, AvailableHeight, 100), AvailableHeight - VSpaceT - VSpaceB)); -end; - -procedure TFormControlObj.ResetToValue; -begin -end; - -function TFormControlObj.GetSubmission(Index: Integer; out S: ThtString): Boolean; -begin - Result := False; -end; - -procedure TFormControlObj.FormControlClick(Sender: TObject); -begin - if Assigned(Document.ObjectClick) then - Document.ObjectClick(Document.TheOwner, Self, OnClickMessage); -end; - -//-- BG ---------------------------------------------------------- 16.01.2011 -- -function TFormControlObj.GetClientHeight: Integer; -begin - Result := TheControl.Height; -end; - -//-- BG ---------------------------------------------------------- 16.01.2011 -- -function TFormControlObj.GetClientLeft: Integer; -begin - Result := TheControl.Left; -end; - -//-- BG ---------------------------------------------------------- 15.01.2011 -- -function TFormControlObj.GetTabOrder: Integer; -begin - Result := TheControl.TabOrder; -end; - -//-- BG ---------------------------------------------------------- 15.01.2011 -- -function TFormControlObj.GetTabStop: Boolean; -begin - Result := TheControl.TabStop; -end; - -//-- BG ---------------------------------------------------------- 16.01.2011 -- -function TFormControlObj.GetClientTop: Integer; -begin - Result := TheControl.Top; -end; - -//-- BG ---------------------------------------------------------- 16.01.2011 -- -function TFormControlObj.GetClientWidth: Integer; -begin - Result := TheControl.Width; -end; - -procedure TFormControlObj.SetDataInit; -begin -end; - -procedure TFormControlObj.SetData(Index: Integer; const V: ThtString); -begin -end; - -//-- BG ---------------------------------------------------------- 16.01.2011 -- -procedure TFormControlObj.SetClientHeight(Value: Integer); -begin - TheControl.Height := Value; -end; - -procedure TFormControlObj.SetHeightWidth(Canvas: TCanvas); -begin -end; - -//-- BG ---------------------------------------------------------- 16.01.2011 -- -procedure TFormControlObj.SetClientLeft(Value: Integer); -begin - TheControl.Left := Value; -end; - -//-- BG ---------------------------------------------------------- 15.01.2011 -- -procedure TFormControlObj.SetTabOrder(Value: Integer); -begin - TheControl.TabOrder := Value; -end; - -//-- BG ---------------------------------------------------------- 15.01.2011 -- -procedure TFormControlObj.SetTabStop(Value: Boolean); -begin - TheControl.TabStop := Value; -end; - -//-- BG ---------------------------------------------------------- 16.01.2011 -- -procedure TFormControlObj.SetClientTop(Value: Integer); -begin - TheControl.Top := Value; -end; - -{----------------TImageFormControlObj.Create} - -constructor TImageFormControlObj.Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties); -var - PntPanel: TWinControl; //TPaintPanel; -begin - inherited Create(Parent,Position,L,Prop); - XPos := -1; {so a button press won't submit image data} - - PntPanel := Document.PPanel; - FControl := ThtButton.Create(PntPanel); - with FControl do - begin - Left := -4000; {so will be invisible until placed} - Width := 1; - Height := 1; - OnEnter := EnterEvent; - OnExit := ExitEvent; - OnClick := ImageClick; - Enabled := not Disabled; - {$ifdef has_StyleElements} - StyleElements := Document.StyleElements; - {$endif} - end; - FControl.Parent := PntPanel; -end; - -procedure TImageFormControlObj.ProcessProperties(Prop: TProperties); -begin - MyImage.ProcessProperties(Prop); -end; - -procedure TImageFormControlObj.ImageClick(Sender: TObject); -begin - if FControl.CanFocus then - FControl.SetFocus; - FormControlClick(Self); - XPos := XTmp; YPos := YTmp; - if not Disabled then - MyForm.SubmitTheForm(''); -end; - -//-- BG ---------------------------------------------------------- 15.01.2011 -- -constructor TImageFormControlObj.CreateCopy(Parent: TCellBasic; Source: THtmlNode); -var - T: TImageFormControlObj absolute Source; -begin - inherited CreateCopy(Parent,Source); - FControl := T.FControl; - MyImage := T.MyImage; -end; - -destructor TImageFormControlObj.Destroy; -begin - if not IsCopy then - begin - FControl.Parent := nil; - FControl.Free; - // TODO: BG, 29.08.2013: ... and MyImage??? Who owns it??? - end; - inherited Destroy; -end; - -//-- BG ---------------------------------------------------------- 16.01.2011 -- -function TImageFormControlObj.GetControl: TWinControl; -begin - Result := FControl; -end; - -function TImageFormControlObj.GetSubmission(Index: Integer; out S: ThtString): Boolean; -begin - Result := (Index <= 1) and (XPos >= 0); - if Result then - begin - S := ''; - if FName <> '' then - S := FName + '.'; - if Index = 0 then - S := S + 'x=' + IntToStr(XPos) - else - begin {index = 1} - S := S + 'y=' + IntToStr(YPos); - XPos := -1; - end; - end; -end; - -{----------------TRadioButtonFormControlObj.Create} - -constructor TRadioButtonFormControlObj.Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties); -var - T: TAttribute; - PntPanel: TWinControl; //TPaintPanel; - Ctrl: TFormControlObj; - RadioButtonFormControlObj: TRadioButtonFormControlObj absolute Ctrl; - I: Integer; - SetTabStop: Boolean; -begin - //TODO -oBG, 24.03.2011: what is ACell? Child or Parent? - // I think it is parent and is used to address the co-radiobuttons - inherited Create(Parent,Position,L,Prop); - //xMyCell := ACell; - PntPanel := Document.PPanel; - FControl := TFormRadioButton.Create(PntPanel); - VertAlign := ABaseline; - T := nil; - if L.Find(CheckedSy, T) then - IsChecked := True; - with FControl do - begin - Left := -4000; {so will be invisible until placed} - if Screen.PixelsPerInch > 100 then - begin - Width := 16; - Height := 16; - end - else - begin - Width := 13; - Height := 14; - end; - IDName := Self.FName; - OnEnter := EnterEvent; - OnExit := ExitEvent; - OnKeyDown := MyForm.AKeyDown; - OnMouseMove := HandleMouseMove; - Enabled := not Disabled; - Parent := PntPanel; {must precede Checked assignment} - - {The Tabstop for the first radiobutton in a group will be set in case no - radiobuttons that follow are checked. This insures that the tab key can - access the group} - SetTabStop := True; - {Examine all other radiobuttons in this group (same FName)} - for I := 0 to MyForm.ControlList.Count - 1 do - begin - Ctrl := TFormControlObj(MyForm.ControlList.Items[I]); - if (Ctrl is TRadioButtonFormControlObj) and (RadioButtonFormControlObj.FControl <> FControl) then {skip the current radiobutton} - if htCompareText(Ctrl.Name, Name) = 0 then {same group} - if not IsChecked then - begin - {if the current radiobutton is not checked and there are other radio buttons, - then the tabstop will not be set for the current radio button since it - is not the first} - SetTabStop := False; - Break; - end - else - begin - {if the current radio button is checked, then uncheck all the others and - make sure no others have tabstop set} - RadioButtonFormControlObj.IsChecked := False; - RadioButtonFormControlObj.Checked := False; - RadioButtonFormControlObj.TabStop := False; - end; - end; - if not IsChecked then - TabStop := SetTabStop; - Checked := IsChecked; {must precede setting OnClick} - OnClick := RadioClick; - {$ifdef has_StyleElements} - StyleElements := Document.StyleElements; - {$endif} - end; -end; - -//-- BG ---------------------------------------------------------- 16.01.2011 -- -function TRadioButtonFormControlObj.GetColor: TColor; -begin - Result := FControl.Color; -end; - -//-- BG ---------------------------------------------------------- 16.01.2011 -- -function TRadioButtonFormControlObj.GetControl: TWinControl; -begin - Result := FControl; -end; - -procedure TRadioButtonFormControlObj.RadioClick(Sender: TObject); -begin - MyForm.DoRadios(Self); - FormControlClick(Self); -end; - -procedure TRadioButtonFormControlObj.ResetToValue; -begin - Checked := IsChecked; -end; - -procedure TRadioButtonFormControlObj.DrawInline1(Canvas: TCanvas; X1, Y1: Integer); -var - OldStyle: TPenStyle; - OldWidth, XW, YH, XC, YC: Integer; - OldColor, OldBrushColor: TColor; - OldBrushStyle: TBrushStyle; - MonoBlack: Boolean; -begin - inherited DrawInline1(Canvas,X1,Y1); - if IsCopy then - with Canvas do - begin - XW := X1 + 14; - YH := Y1 + 14; - OldStyle := Pen.Style; - OldWidth := Pen.Width; - OldBrushStyle := Brush.Style; - OldBrushColor := Brush.Color; - MonoBlack := Document.PrintMonoBlack and (GetDeviceCaps(Handle, BITSPIXEL) = 1) and - (GetDeviceCaps(Handle, PLANES) = 1); - if Disabled and not MonoBlack then - Brush.Color := ThemedColor(clBtnFace {$ifdef has_StyleElements},seClient in Document.StyleElements{$endif}) - else - Brush.Color := clWhite; - Pen.Color := clWhite; - Ellipse(X1, Y1, XW, YH); - - Pen.Style := psInsideFrame; - if MonoBlack then - begin - Pen.Width := 1; - Pen.Color := clBlack; - end - else - begin - Pen.Width := 2; - Pen.Color := ThemedColor(clBtnShadow {$ifdef has_StyleElements},seClient in Document.StyleElements{$endif}); - end; - Arc(X1, Y1, XW, YH, XW, Y1, X1, YH); - if not MonoBlack then - Pen.Color := ThemedColor(clBtnHighlight{$ifdef has_StyleElements},seClient in Document.StyleElements{$endif});//clSilver; - Arc(X1, Y1, XW, YH, X1, YH, XW, Y1); - if Checked then - begin - Pen.Color := clBlack; - OldColor := Brush.Color; - Brush.Color := clBlack; - Brush.Style := bsSolid; - XC := X1 + 7; - YC := Y1 + 7; - Ellipse(XC - 2, YC - 2, XC + 2, YC + 2); - Brush.Color := OldColor; - end; - Pen.Width := OldWidth; - Pen.Style := OldStyle; - Brush.Color := OldBrushColor; - Brush.Style := OldBrushStyle; - end - else - begin - if OwnerCell.BkGnd then - Color := OwnerCell.BkColor - else - Color := Document.Background; - if Active and Document.TheOwner.ShowFocusRect then //MK20091107 - begin - Canvas.Brush.Color := clWhite; - if Screen.PixelsPerInch > 100 then - Canvas.DrawFocusRect(Rect(Left - 2, Top - 2, Left + 18, Top + 18)) - else - Canvas.DrawFocusRect(Rect(Left - 3, Top - 2, Left + 16, Top + 16)); - end; - end; -end; - -//-- BG ---------------------------------------------------------- 15.01.2011 -- -function TRadioButtonFormControlObj.getChecked: Boolean; -begin - Result := FControl.Checked; -end; - -function TRadioButtonFormControlObj.GetSubmission(Index: Integer; out S: ThtString): Boolean; -begin - Result := (Index = 0) and Checked; - if Result then - S := FName + '=' + Value; -end; - -procedure TRadioButtonFormControlObj.SetData(Index: Integer; const V: ThtString); -begin - if htCompareText(V, Value) = 0 then - Checked := True; -end; - -procedure TRadioButtonFormControlObj.SaveContents; -{Save the current value to see if it has changed when focus is lost} -begin - WasChecked := Checked; -end; - -//-- BG ---------------------------------------------------------- 15.01.2011 -- -procedure TRadioButtonFormControlObj.SetChecked(Value: Boolean); -begin - FControl.Checked := Value; -end; - -//-- BG ---------------------------------------------------------- 16.01.2011 -- -procedure TRadioButtonFormControlObj.SetColor(const Value: TColor); -begin - FControl.Color := Value; -end; - -//-- BG ---------------------------------------------------------- 30.08.2013 -- -constructor TRadioButtonFormControlObj.CreateCopy(Parent: TCellBasic; Source: THtmlNode); -var - T: TRadioButtonFormControlObj absolute Source; -begin - inherited CreateCopy(Parent,Source); - FControl := T.FControl; - WasChecked := T.WasChecked; - IsChecked := T.IsChecked; -end; - -//-- BG ---------------------------------------------------------- 15.01.2011 -- -destructor TRadioButtonFormControlObj.Destroy; -begin - if not IsCopy then - begin - FControl.Parent := nil; - FControl.Free; - end; - inherited Destroy; -end; - -procedure TRadioButtonFormControlObj.DoOnChange; -begin - if Checked <> WasChecked then - if Assigned(Document.ObjectChange) then - Document.ObjectChange(Document.TheOwner, Self, OnChangeMessage); -end; - -{----------------TCellBasic.Create} - -constructor TCellBasic.Create(Parent: TBlock); -begin -{$IFDEF JPM_DEBUGGING_CREATE} - CodeSite.EnterMethod(Self,'TCellBasic.Create'); -{$ENDIF} - inherited Create; - FOwnerBlock := Parent; - if FOwnerBlock <> nil then - FDocument := FOwnerBlock.Document; -// FRenderList := TRenderSectionBaseList.Create(false); -{$IFDEF JPM_DEBUGGING_CREATE} - CodeSite.ExitMethod(Self,'TCellBasic.Create'); -{$ENDIF} -end; - -{----------------TCellBasic.CreateCopy} - -constructor TCellBasic.CreateCopy(Parent: TBlock; T: TCellBasic); -var - I: Integer; - Tmp, Tmp1: TSectionBase; -begin - inherited Create; - FOwnerBlock := Parent; - if FOwnerBlock <> nil then - FDocument := FOwnerBlock.Document; - for I := 0 to T.Count - 1 do - begin - Tmp := T.Items[I]; - Tmp1 := TSectionClass(Tmp.ClassType).CreateCopy(Self, Tmp); - Add(Tmp1, 0); - end; -// FRenderList := TRenderSectionBaseList.Create(false); -end; - -//-- BG ---------------------------------------------------------- 01.12.2013 -- -destructor TCellBasic.Destroy; -begin -// FRenderList.Free; - inherited; -end; - -{----------------TCellBasic.Add} - -procedure TCellBasic.Add(Item: TSectionBase; TagIndex: Integer); -var - Section: TSection absolute Item; -begin - if Assigned(Item) then - begin - if Item is TSection then - Add(Section, TagIndex) - else - inherited Add(Item); - Item.SetDocument(Document); - end; -end; - -//-- BG ---------------------------------------------------------- 14.01.2015 -- -procedure TCellBasic.Add(var Section: TSection; TagIndex: Integer); -begin - if Assigned(Section) then - begin - if Length(Section.XP) <> 0 then - begin - Section.ProcessText(TagIndex); - if not (Section.WhiteSpaceStyle in [wsPre, wsPreWrap, wsPreLine]) and (Section.Len = 0) - and not Section.AnchorName and (Section.FClearing = clrNone) then - begin - Section.CheckFree; - FreeAndNil(Section); {discard empty TSections that aren't anchors} - Exit; - end; - end; - inherited Add(Section); - Section.SetDocument(Document); - end; -end; - -//-- BG ---------------------------------------------------------- 07.09.2013 -- -function TCellBasic.CalcDisplayExtern: ThtDisplayStyle; -var - I: Integer; -begin - // a list of elements is displayed inline, if all elements' are displayed inline. - for I := Count - 1 downto 0 do - if Items[i].CalcDisplayExtern <> pdInline then - begin - Result := pdBlock; - Exit; - end; - Result := pdInline; -end; - -function TCellBasic.CheckLastBottomMargin: Boolean; -{Look at the last item in this cell. If its bottom margin was set to Auto, - set it to 0} -var - TB: TSectionBase; - I: Integer; - Done: Boolean; -begin - Result := False; - I := Count - 1; {find the preceding block that isn't absolute positioning} - Done := False; - while (I >= 0) and not Done do - begin - TB := Items[I]; - if (TB is TBlock) and (TBlock(TB).Positioning <> PosAbsolute) then - Done := True - else - Dec(I); - end; - if I >= 0 then - begin - TB := Items[I]; - if TB is TBlock then - begin - with TBlock(TB) do - if BottomAuto then - begin - MargArray[MarginBottom] := 0; - Result := True; - end; - if TB is TBlockLI then - Result := TBlockLI(TB).MyCell.CheckLastBottomMargin; - end; - end; -end; - -{----------------TCellBasic.GetURL} - -function TCellBasic.GetURL(Canvas: TCanvas; X, Y: Integer; - out UrlTarg: TUrlTarget; out FormControl: TIDObject {TImageFormControlObj}; - out ATitle: ThtString): ThtguResultType; -{Y is absolute} -var - I: Integer; -begin - Result := []; - FormControl := nil; - UrlTarg := nil; - for I := 0 to Count - 1 do - begin - with Items[I] do - begin - // BG, 01.04.2013: cannot reduce workload via DrawTop/DrawBot as - // absolutely positioned children may reside beyond these margins. - //if (Y >= DrawTop) and (Y < DrawBot) then - //begin - Result := GetURL(Canvas, X, Y, UrlTarg, FormControl, ATitle); - if Result <> [] then - Exit; - //end; - end; - end; -end; - -//-- BG ---------------------------------------------------------- 04.08.2013 -- -function TCellBasic.IsCopy: Boolean; -begin - Result := Document.IsCopy; -end; - -{----------------TCellBasic.FindCursor} - -function TCellBasic.FindCursor(Canvas: TCanvas; X, Y: Integer; - out XR, YR, Ht: Integer; out Intext: Boolean): Integer; -var - I: Integer; -begin - for I := 0 to Count - 1 do - begin - with Items[I] do - begin - // BG, 01.04.2013: cannot reduce workload via DrawTop/DrawBot as - // absolutely positioned children may reside beyond these margins. - //if (Y >= DrawTop) and (Y < DrawBot) then - //begin - Result := Items[I].FindCursor(Canvas, X, Y, XR, YR, Ht, InText); - if Result >= 0 then - Exit; - //end; - end; - end; - Result := -1; -end; - -procedure TCellBasic.AddSectionsToList; -var - I: Integer; -begin - for I := 0 to Count - 1 do - Items[I].AddSectionsToList; -end; - -{----------------TCellBasic.FindString} - -function TCellBasic.FindString(From: Integer; const ToFind: UnicodeString; MatchCase: Boolean): Integer; -var - I: Integer; -begin - Result := -1; - for I := 0 to Count - 1 do - begin - Result := Items[I].FindString(From, ToFind, MatchCase); - if Result >= 0 then - Break; - end; -end; - -{----------------TCellBasic.FindStringR} - -function TCellBasic.FindStringR(From: Integer; const ToFind: UnicodeString; MatchCase: Boolean): Integer; -var - I: Integer; -begin - Result := -1; - for I := Count - 1 downto 0 do - begin - Result := Items[I].FindStringR(From, ToFind, MatchCase); - if Result >= 0 then - Break; - end; -end; - -{----------------TCellBasic.FindSourcePos} - -function TCellBasic.FindSourcePos(DocPos: Integer): Integer; -var - I: Integer; -begin - Result := -1; - for I := 0 to Count - 1 do - begin - Result := Items[I].FindSourcePos(DocPos); - if Result >= 0 then - Break; - end; -end; - -{$ifdef UseFormTree} -procedure TCellBasic.FormTree(const Indent: ThtString; var Tree: ThtString); -var - I: Integer; - Item: TSectionBase; -begin - for I := 0 to Count - 1 do - begin - Item := Items[I]; - if Item is TBlock then - TBlock(Item).FormTree(Indent, Tree) - else if Item is TSection then - Tree := Tree + Indent + Copy(TSection(Item).BuffS, 1, 10) + CrChar + LfChar - else - Tree := Tree + Indent + '----'^M^J; - end; -end; -{$endif UseFormTree} - -{----------------TCellBasic.GetChAtPos} - -function TCellBasic.GetChAtPos(Pos: Integer; out Ch: WideChar; out Obj: TSectionBase): Boolean; -var - I: Integer; -begin - Result := False; - if (Pos >= StartCurs) and (Pos <= StartCurs + Len) then - for I := 0 to Count - 1 do - begin - Result := TSectionBase(Items[I]).GetChAtPos(Pos, Ch, Obj); - if Result then - Break; - end; -end; - -{----------------TCellBasic.CopySelectedText} - -procedure TCellBasic.CopySelectedText; -var - I: Integer; - SLE, SLB: Integer; -begin - if not Assigned(Document) then - Exit; {dummy cell} - SLB := Document.SelB; - SLE := Document.SelE; - if SLE <= SLB then - Exit; {nothing to do} - - for I := 0 to Count - 1 do - with Items[I] do - begin - if (SLB >= StartCurs + Len) then - Continue; - if (SLE <= StartCurs) then - Break; - CopySelectedText; - end; -end; - -{----------------TCellBasic.DoLogic} - -function TCellBasic.DoLogic(Canvas: TCanvas; Y, Width, AHeight, BlHt: Integer; - var ScrollWidth: Integer; var Curs: Integer): Integer; -{Do the entire layout of the cell or document. Return the total cell or document pixel height} -var - I, Sw, TheCount: Integer; - H: Integer; -// InlineSection: TInlineSection; -// Item: TSectionBase; -begin -{$IFDEF JPM_DEBUGGING_LOGIC} - CodeSite.EnterMethod(Self, Format('TCellBasic.DoLogic, %d Items', [Count])); - CodeSite.SendFmtMsg('Y = [%d]',[Y]); - CodeSite.SendFmtMsg('Width = [%d]',[Width]); - CodeSite.SendFmtMsg('AHeight = [%d]',[AHeight]); - CodeSite.SendFmtMsg('BlHt = [%d]',[BlHt]); - CodeSite.SendFmtMsg('ScrollWidth = [%d]',[ScrollWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.AddSeparator; -{$ENDIF} - -//TODO -oBG, 15.03.2014: support display:inline -{$ifdef DO_PD_INLINE} -// //TODO -oBG, 24.06.2012: merge sections with display=inline etc. -// //TODO -oBG, 30.11.2013: To be more precise: -// // Reading the HTML file must produce the actual document tree rather than preprocessing inline elements to TSections. -// // -// // The Renderer (DoLogic()/DrawLogic()) must produce a processing list. In the list consecutive elements of all child -// // levels with display=inline are gathered in the (anonymous) TInlineSection element while block-level elements are -// // added to the processing list directly. This ends up in a list of block level elements, just like TCellBasic has -// // been before property Display was introduced. -// // -// // Actually TInlineSection is intended to collect content of TSections of consecutive inline elements and must draw -// // borders and background of the inlined elements. -// InlineSection := nil; -// FRenderList.Clear; -// for I := 0 to Count - 1 do -// begin -// Item := Items[I]; -// if Item.CalcDisplayExtern = pdInline then -// begin -// if InlineSection = nil then -// begin -// InlineSection := TInlineSection.Create(Self); -// FRenderList.Add(InlineSection); -// end; -// if Item is TSection then -// InlineSection.AddElement(TSection(Item)); -// end -// else -// begin -// InlineSection := nil; -// FRenderList.Add(Items[I]); -// end; -// end; -{$endif} - - StartCurs := Curs; - H := 0; - ScrollWidth := 0; - TheCount := Count; - I := 0; - while I < TheCount do - begin - try - Sw := 0; - Inc(H, Items[I].DrawLogic1(Canvas, 0, Y + H, 0, 0, Width, AHeight, BlHt, IMgr, Sw, Curs)); - ScrollWidth := Max(ScrollWidth, Sw); - Inc(I); - except - on E: EProcessError do - begin - // Yunqa.de - Don't want message dialog for individual errors. - // Yunqa.de MessageDlg(e.Message, mtError, [mbOK], 0); - Delete(I); - Dec(TheCount); - end; - end; - end; - Len := Curs - StartCurs; - Result := H; -{$IFDEF JPM_DEBUGGING_LOGIC} - CodeSite.SendFmtMsg('ScrollWidth = [%d]',[ScrollWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.SendFmtMsg('Result = [%d]',[Result]); - CodeSite.ExitMethod(Self,'TCellBasic.DoLogic'); -{$ENDIF} -end; - -{----------------TCellBasic.MinMaxWidth} - -procedure TCellBasic.MinMaxWidth(Canvas: TCanvas; out Min, Max: Integer); -{Find the Width the cell would take if no wordwrap, Max, and the width if wrapped - at largest word, Min} -var - I, Mn, Mx: Integer; -begin -{$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'TCellBasic.MinMaxWidth'); - try -{$ENDIF} - Max := 0; Min := 0; - for I := 0 to Count - 1 do - begin - Items[I].MinMaxWidth(Canvas, Mn, Mx); - Max := Math.Max(Max, Mx); - Min := Math.Max(Min, Mn); - end; -{$IFDEF JPM_DEBUGGING} - finally - CodeSite.ExitMethod(Self, Format('TCellBasic.MinMaxWidth %d .. %d', [Min, Max])); - end; -{$ENDIF} -end; - -{----------------TCellBasic.Draw} - -function TCellBasic.Draw(Canvas: TCanvas; ARect: TRect; ClipWidth, X: Integer; Y, XRef, YRef: Integer): Integer; -{draw the document or cell. Note: individual sections not in ARect don't bother - drawing} -var - I: Integer; - H: Integer; -begin - H := Y; - for I := 0 to Count - 1 do - H := Items[I].Draw1(Canvas, ARect, IMgr, X, XRef, YRef); - Result := H; -end; - -{----------------TBlock.Create} - -constructor TBlock.Create(Parent: TCellBasic; Attributes: TAttributeList; Prop: TProperties); -var - S: ThtString; -begin - {$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,Format('TBlock.Create "%s"', [TagClass])); - {$IFDEF JPM_DEBUGGING_STYLES} - StyleUn.LogProperties(Prop,'Prop'); - CodeSite.AddSeparator; - {$ENDIF} - {$ENDIF} - inherited Create(Parent, 0, Attributes, Prop); - MyCell := TBlockCell.Create(Self); - DrawList := TSectionBaseList.Create(False); - - if Document.UseQuirksMode and (Self is TTableBlock) then - Prop.GetVMarginArrayDefBorder(MargArrayO, clSilver) - else - Prop.GetVMarginArray(MargArrayO); - HasBorderStyle := Prop.HasBorderStyle; - FGColor := Prop.Props[Color]; - - BlockTitle := Prop.PropTitle; - if not (Self is TBodyBlock) and not (Self is TTableAndCaptionBlock) - and Prop.GetBackgroundImage(S) and (S <> '') then - begin {body handles its own image} - BGImage := TImageObj.SimpleCreate(MyCell, S); - Prop.GetBackgroundPos(EmSize, ExSize, PRec); - end; - - Visibility := Prop.GetVisibility; - Prop.GetPageBreaks(BreakBefore, BreakAfter, KeepIntact); - if Positioning <> posStatic then - begin - ZIndex := 10 * Prop.GetZIndex; - if (Positioning = posAbsolute) and (ZIndex = 0) then - ZIndex := 1; {abs on top unless otherwise specified} - end; - if (Floating in [ALeft, ARight]) and (ZIndex = 0) then - ZIndex := 1; - if not IsInFlow then - begin - MyIMgr := TIndentManager.Create; - MyCell.IMgr := MyIMgr; - end; - if not (Self is TTableBlock) and not (Self is TTableAndCaptionBlock) then - CollapseAdjoiningMargins; - HideOverflow := Prop.IsOverflowHidden; - if Prop.Props[TextAlign] = 'right' then - Justify := Right - else if Prop.Props[TextAlign] = 'center' then - Justify := Centered - else - Justify := Left; - {$IFDEF JPM_DEBUGGING} - CodeSite.ExitMethod(Self,Format('TBlock.Create "%s"', [TagClass])); - {$ENDIF} -end; - -//-- BG ---------------------------------------------------------- 17.05.2014 -- -function Collapse(A, B: Integer): Integer; {$ifdef UseInline} inline; {$endif} -begin - if A >= 0 then - if B >= 0 then - Result := Max(A, B) - else - Result := A + B - else - if B >= 0 then - Result := B + A - else - Result := Min(A, B); -end; - -procedure TBlock.CollapseAdjoiningMargins; -{adjacent vertical margins need to be reduced} -var - TopAuto: Boolean; - TB: TSectionBase; - Block: TBlock absolute TB; - LastMargin, I: Integer; - Tag: TElemSymb; - CD: ThtConvData; -begin - CD := ConvData(100, 100 {width and height not known at this point}, EmSize, ExSize, BorderWidth); - ConvVertMargins(MargArrayO, CD, MargArray); - TopAuto := MarginTop in CD.IsAutoParagraph; - BottomAuto := MarginBottom in CD.IsAutoParagraph; - if (MargArray[PaddingTop] <> 0) or (MargArray[BorderTopWidth] <> 0) then {do nothing} - else if Positioning = posAbsolute then - begin - if TopAuto then - MargArray[MarginTop] := 0; - end - else if Floating in [ALeft, ARight] then {do nothing} - else if Display = pdNone then {do nothing} - else - begin - TB := nil; - I := OwnerCell.Count - 1; {find the preceding block that isn't absolute positioning} - while I >= 0 do - begin - TB := OwnerCell[I]; - if TB.Display <> pdNone then - if not (TB is TBlock) or (TBlock(TB).Positioning <> PosAbsolute) then - break; - Dec(I); - end; - - if OwnerCell.OwnerBlock <> nil then - Tag := OwnerCell.OwnerBlock.Symbol - else - Tag := OtherChar; - if I < 0 then - begin {no previous non absolute block, remove any Auto paragraph space} - case Tag of - BodySy: - MargArray[MarginTop] := Max(0, MargArray[MarginTop] - OwnerBlock.MargArray[MarginTop]); - else - if TopAuto then - MargArray[MarginTop] := 0; - end; - end - else - begin - if ((TB is TTableBlock) or (TB is TTableAndCaptionBlock)) and (TBlock(TB).Floating in [ALeft, ARight]) and TopAuto then - MargArray[MarginTop] := 0 - else if TB is TBlock then - begin - if Block.Positioning = posStatic then - begin - LastMargin := Block.MargArray[MarginBottom]; - Block.MargArray[MarginBottom] := 0; - MargArray[MarginTop] := Collapse(LastMargin, MargArray[MarginTop]); - end - end - else if (Tag = LISy) and TopAuto and (Symbol in [ULSy, OLSy]) then - MargArray[MarginTop] := 0; {removes space from nested lists} - end; - end; -end; - -//-- BG ---------------------------------------------------------- 16.05.2014 -- -procedure TBlock.CollapseNestedMargins; -var - TB: TSectionBase; - Block: TBlock absolute TB; - I, J, M: Integer; -begin - if (OwnerCell <> Document) and (MargArray[piHeight] = 0) and (MargArray[piMinHeight] = 0) then - begin - J := 0; - if MargArray[BorderTopWidth] = 0 then - begin - // collapse with first sectionbase, if it is an in-flow block. - - // find block to collapse - while J < MyCell.Count do - begin - TB := MyCell[J]; - if TB.Display <> pdNone then - if not (TB is TBlock) or ((Block.Positioning <> PosAbsolute) and (Block.Floating = aNone)) then - break; - Inc(J); - end; - - if J < MyCell.Count then - begin - if (TB is TBlock) and (Block.Positioning = posStatic) then - begin - // collapse margins, if it has no top padding - if (Block.MargArray[PaddingTop] = 0) then - begin - M := Block.MargArray[MarginTop]; - Block.MargArray[MarginTop] := 0; - MargArray[MarginTop] := Collapse(MargArray[MarginTop], M); - end; - end; - end; - end; - - if MargArray[BorderBottomWidth] = 0 then - begin - // collapse with last sectionbase, if it is an in-flow block. - - // find block to collapse - I := MyCell.Count - 1; - while I >= J do - begin - TB := MyCell[I]; - if TB.Display <> pdNone then - if not (TB is TBlock) or ((Block.Positioning <> PosAbsolute) and (Block.Floating = aNone)) then - break; - Dec(I); - end; - - if I >= 0 then - begin - if (TB is TBlock) and (Block.Positioning = posStatic) then - begin - // collapse margins, if it has no bottom padding - if (Block.MargArray[PaddingBottom] = 0) then - begin - M := Block.MargArray[MarginBottom]; - Block.MargArray[MarginBottom] := 0; - MargArray[MarginBottom] := Collapse(MargArray[MarginBottom], M); - end; - end; - end; - end; - end; -end; - -//-- BG ---------------------------------------------------------- 09.10.2010 -- -procedure TBlock.ContentMinMaxWidth(Canvas: TCanvas; out Min, Max: Integer); -begin -{$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self, Format('TBlock.ContentMinMaxWidth TagClass = [%s]', [TagClass])); - try -{$ENDIF} - - MyCell.MinMaxWidth(Canvas, Min, Max); - -{$IFDEF JPM_DEBUGGING} - finally - CodeSite.ExitMethod(Self, Format('TBlock.ContentMinMaxWidth %d .. %d', [Min, Max])); - end; -{$ENDIF} -end; - -//-- BG ---------------------------------------------------------- 06.10.2010 -- -procedure TBlock.ConvMargArray(BaseWidth, BaseHeight: Integer; out AutoCount: Integer); -begin -{$IFDEF JPM_DEBUGGING_CONV} - CodeSite.EnterMethod(Self,'TBlock.ConvMargArray'); - CodeSite.SendFmtMsg('Self.TagClass = [%s]',[TagClass ]); - CodeSite.AddSeparator; -{$ENDIF} - - StyleUn.ConvMargArray(MargArrayO, BaseWidth, BaseHeight, EmSize, ExSize, BorderWidth, AutoCount, MargArray); - -{$IFDEF JPM_DEBUGGING_CONV} - CodeSite.ExitMethod(Self,'TBlock.ConvMargArray'); -{$ENDIF} -end; - -{----------------TBlock.CreateCopy} - -constructor TBlock.CreateCopy(Parent: TCellBasic; Source: THtmlNode); -var - T: TBlock absolute Source; -begin - inherited CreateCopy(Parent,Source); - System.Move(T.MargArray, MargArray, PtrSub(@Converted, @MargArray) + Sizeof(Converted)); - MyCell := TBlockCell.CreateCopy(Self, T.MyCell); - DrawList := TSectionBaseList.Create(False); - if Assigned(T.BGImage) and Document.PrintTableBackground then - BGImage := TImageObj.CreateCopy(MyCell, T.BGImage); - MargArrayO := T.MargArrayO; - if not IsInFlow then - begin - MyIMgr := TIndentManager.Create; - MyCell.IMgr := MyIMgr; - end; - BlockTitle := T.BlockTitle; // Thanks to Nagy Ervin. -end; - -destructor TBlock.Destroy; -begin - BGImage.Free; - TiledImage.Free; - if MyIMgr <> nil then - begin - MyCell.IMgr := nil; - FreeAndNil(MyIMgr); - end; - FreeAndNil(MyCell); - DrawList.Free; - inherited Destroy; -end; - -procedure TBlock.MinMaxWidth(Canvas: TCanvas; out Min, Max: Integer); -var - MinCell, MaxCell: Integer; - LeftSide, RightSide, AutoCount: Integer; -begin -{$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self, Format('TBlock.MinMaxWidth TagClass = [%s]', [TagClass])); - try -{$ENDIF} - - if (Display = pdNone) or (Positioning in [PosAbsolute, posFixed]) then - begin - Min := 0; - Max := 0; - Exit; - end; - -{$ifdef DO_BLOCK_INLINE} - if Display = pdInline then - begin - inherited MinMaxWidth(Canvas,Min,Max); - exit; - end; -{$endif} - - ConvMargArray(0, 400, AutoCount); - //HideOverflow := HideOverflow and (MargArray[piWidth] <> Auto) and (MargArray[piWidth] > 20); - if HideOverflow and (MargArray[piWidth] <> Auto) and (MargArray[piWidth] > 20) then - begin - MinCell := MargArray[piWidth]; - MaxCell := MinCell; - end - else - ContentMinMaxWidth(Canvas, MinCell, MaxCell); - if MargArray[MarginLeft] = Auto then - MargArray[MarginLeft] := 0; - if MargArray[MarginRight] = Auto then - MargArray[MarginRight] := 0; - if MargArray[piWidth] = Auto then - MargArray[piWidth] := 0; - LeftSide := MargArray[MarginLeft] + MargArray[BorderLeftWidth] + MargArray[PaddingLeft]; - RightSide := MargArray[MarginRight] + MargArray[BorderRightWidth] + MargArray[PaddingRight]; - if MargArray[piWidth] > 0 then - begin - Min := MargArray[piWidth] + LeftSide + RightSide; - Max := Min; - end - else - begin - Min := Math.Max(MinCell, MargArray[piWidth]) + LeftSide + RightSide; - Max := Math.Max(MaxCell, MargArray[piWidth]) + LeftSide + RightSide; - end; - if (MargArray[piMinWidth] > 0) and (MargArray[piMinWidth] > Min) then - Min := MargArray[piMinWidth]; - if (MargArray[piMaxWidth] > 0) and (MargArray[piMaxWidth] < Max) then - Max := MargArray[piMaxWidth]; - -{$IFDEF JPM_DEBUGGING} - finally - CodeSite.ExitMethod(Self, Format('TBlock.MinMaxWidth %d .. %d', [Min, Max])); - end; -{$ENDIF} -end; - -{----------------TBlock.GetURL} - -function TBlock.GetURL(Canvas: TCanvas; X, Y: Integer; - out UrlTarg: TUrlTarget; out FormControl: TIDObject {TImageFormControlObj}; out ATitle: ThtString): ThtguResultType; -begin - UrlTarg := nil; - FormControl := nil; - case Display of - pdNone: Result := []; -{$ifdef DO_BLOCK_INLINE} - pdInline: Result := inherited GetURL(Canvas, X, Y, UrlTarg, FormControl, ATitle); -{$endif} - else - Result := MyCell.GetURL(Canvas, X, Y, UrlTarg, FormControl, ATitle); - if not (guTitle in Result) and (BlockTitle <> '') and PtInRect(MyRect, Point(X, Y - Document.YOFF)) then - begin - ATitle := BlockTitle; - Include(Result, guTitle); - end; - end; -end; - -{----------------TBlock.FindString} - -function TBlock.FindString(From: Integer; const ToFind: UnicodeString; MatchCase: Boolean): Integer; -begin - case Display of - pdNone: Result := -1; -{$ifdef DO_BLOCK_INLINE} - pdInline: Result := inherited FindString(From, ToFind, MatchCase); -{$endif} - else - Result := MyCell.FindString(From, ToFind, MatchCase); - end; -end; - -{----------------TBlock.FindStringR} - -function TBlock.FindStringR(From: Integer; const ToFind: UnicodeString; MatchCase: Boolean): Integer; -begin - case Display of - pdNone: Result := -1; -{$ifdef DO_BLOCK_INLINE} - pdInline: Result := inherited FindStringR(From, ToFind, MatchCase); -{$endif} - else - Result := MyCell.FindStringR(From, ToFind, MatchCase); - end; -end; - -{----------------TBlock.FindCursor} - -function TBlock.FindCursor(Canvas: TCanvas; X, Y: Integer; out XR, YR, CaretHt: Integer; out Intext: Boolean): Integer; -var - I: Integer; -begin - case Display of - pdNone: Result := -1; -{$ifdef DO_BLOCK_INLINE} - pdInline: Result := inherited FindCursor(Canvas, X, Y, XR, YR, CaretHt, Intext); -{$endif} - else - {check this in z order} - Result := -1; - with DrawList do - for I := Count - 1 downto 0 do - with Items[I] do - begin - // BG, 01.04.2013: cannot reduce workload via DrawTop/DrawBot as - // absolutely positioned children may reside beyond these margins. - //if (Y >= DrawTop) and (Y < DrawBot) then - //begin - Result := FindCursor(Canvas, X, Y, XR, YR, CaretHt, Intext); - if Result >= 0 then - Exit; - //end; - end; - end; -end; - -procedure TBlock.AddSectionsToList; -begin - MyCell.AddSectionsToList; -end; - -{----------------TBlock.PtInObject} - -function TBlock.PtInObject(X, Y: Integer; out Obj: TObject; out IX, IY: Integer): Boolean; -{Y is absolute} -var - I: Integer; -begin - case Display of - pdNone: - begin - Result := False; - Exit; - end; - - else - {check this in z order} - for I := DrawList.Count - 1 downto 0 do - if DrawList.Items[I].PtInObject(X, Y, Obj, IX, IY) then - begin - Result := True; - Exit; - end; - - end; - - Result := inherited PtInObject(X, Y, Obj, IX, IY); -end; - -{----------------TBlock.GetChAtPos} - -function TBlock.GetChAtPos(Pos: Integer; out Ch: WideChar; out Obj: TSectionBase): Boolean; -begin - Obj := nil; - case Display of - pdNone: Result := False; -{$ifdef DO_BLOCK_INLINE} - pdInline: Result := inherited GetChAtPos(Pos, Ch, Obj); -{$endif} - else - Result := MyCell.GetChAtPos(Pos, Ch, Obj); - end; -end; - -//-- BG ---------------------------------------------------------- 30.11.2013 -- -function TBlock.CalcDisplayExtern: ThtDisplayStyle; -begin - Result := inherited CalcDisplayExtern; - case Result of - pdInline: - Result := MyCell.CalcDisplayExtern; - end; -end; - -//-- BG ---------------------------------------------------------- 07.09.2013 -- -function TBlock.CalcDisplayIntern: ThtDisplayStyle; -begin - Result := inherited CalcDisplayIntern; -// case Result of -// pdNone:; -// else -// //Result := MyCell.CalcDisplayExtern; -// end; -end; - -function TBlock.CursorToXY(Canvas: TCanvas; Cursor: Integer; var X, Y: Integer): Boolean; -begin - case Display of - pdNone: Result := False; -{$ifdef DO_BLOCK_INLINE} - pdInline: Result := inherited CursorToXY(Canvas, Cursor, X, Y); -{$endif} - else - Result := MyCell.CursorToXY(Canvas, Cursor, X, Y); - end; -end; - -function TBlock.FindDocPos(SourcePos: Integer; Prev: Boolean): Integer; -begin - case Display of - pdNone: Result := -1; -{$ifdef DO_BLOCK_INLINE} - pdInline: Result := inherited FindDocPos(SourcePos, Prev); -{$endif} - else - Result := MyCell.FindDocPos(SourcePos, Prev); - end; -end; - -function TBlock.FindSourcePos(DocPos: Integer): Integer; -begin - case Display of - pdNone: Result := -1; -{$ifdef DO_BLOCK_INLINE} - pdInline: Result := inherited FindSourcePos(DocPos); -{$endif} - else - Result := MyCell.FindSourcePos(DocPos); - end; -end; - -procedure TBlock.CopySelectedText; -begin - case Display of - pdNone:; -{$ifdef DO_BLOCK_INLINE} - pdInline: inherited CopySelectedText; -{$endif} - else - MyCell.CopySelectedText; - if (Symbol = PSy) and (Document.SelE > MyCell.StartCurs + MyCell.Len) then - Document.CB.AddTextCR('', 0); - end; -end; - -{----------------TBlock.FindWidth} - -function TBlock.FindWidth(Canvas: TCanvas; AWidth, AHeight, AutoCount: Integer): Integer; -var - Marg2: Integer; - MinWidth, MaxWidth: Integer; - - function BordPad: Integer; - begin - Result := MargArray[BorderLeftWidth] + MargArray[BorderRightWidth] + - MargArray[PaddingLeft] + MargArray[PaddingRight]; - end; - - function BordWidth: Integer; - begin - Result := MargArray[BorderLeftWidth] + MargArray[BorderRightWidth] + - MargArray[PaddingLeft] + MargArray[PaddingRight] + - MargArray[MarginLeft] + MargArray[MarginRight]; - end; - - procedure CalcWidth; - begin - if Positioning = posAbsolute then - begin - if (MargArray[piLeft] = Auto) and (MargArray[piRight] <> Auto) then - MargArray[piWidth] := MaxWidth - else - MargArray[piWidth] := Max(MinWidth, AWidth - BordWidth - LeftP); - end - else if (Floating in [ALeft, ARight]) then - MargArray[piWidth] := Min(MaxWidth, AWidth - BordWidth) - else - MargArray[piWidth] := Max(MinWidth, AWidth - BordWidth); - end; - - procedure CalcMargRt; - begin - MargArray[MarginRight] := Max(0, AWidth - BordPad - MargArray[MarginLeft] - MargArray[piWidth]); - end; - - procedure CalcMargLf; - begin - MargArray[MarginLeft] := Max(0, AWidth - BordPad - MargArray[MarginRight] - MargArray[piWidth]); - end; - -begin -{$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'TBlock.FindWidth'); - CodeSite.SendFmtMsg('AWidth = [%d]',[AWidth]); - CodeSite.SendFmtMsg('AHeight = [%d]',[AHeight]); - CodeSite.SendFmtMsg('AutoCount = [%d]',[AutoCount]); - CodeSite.SendFmtMsg('Self.TagClass = [%s]',[TagClass ]); - CodeSite.AddSeparator; -{$ENDIF} - - ContentMinMaxWidth(Canvas, MinWidth, MaxWidth); - //HideOverflow := HideOverflow and (MargArray[piWidth] <> Auto) and (MargArray[piWidth] > 20); - case AutoCount of - 0: - begin - if (Justify in [centered, Right]) and (Positioning = posStatic) - and not (Floating in [ALeft, ARight]) and - (MargArray[MarginLeft] = 0) and (MargArray[MarginRight] = 0) then - begin - ApplyBoxWidthSettings(MargArray,MinWidth,MaxWidth,Document.UseQuirksMode); - Marg2 := Max(0, AWidth - MargArray[piWidth] - BordPad); - case Justify of - centered: - begin - MargArray[MarginLeft] := Marg2 div 2; - MargArray[MarginRight] := Marg2 div 2; - end; - right: - MargArray[MarginLeft] := Marg2; - end; - end; - end; - - 1: - if MargArray[piWidth] = Auto then begin - ApplyBoxWidthSettings(MargArray,MinWidth,MaxWidth,Document.UseQuirksMode); - CalcWidth; - end - else - begin - if MargArray[MarginRight] = Auto then - if (Floating in [ALeft, ARight]) then - MargArray[MarginRight] := 0 - else - CalcMargRt - else - CalcMargLf; - end; - - 2: - if MargArray[piWidth] = Auto then - begin - if MargArray[MarginLeft] = Auto then - MargArray[MarginLeft] := 0 - else - MargArray[MarginRight] := 0; - ApplyBoxWidthSettings(MargArray,MinWidth,MaxWidth,Document.UseQuirksMode); - CalcWidth; - end - else - begin - Marg2 := Max(0, AWidth - MargArray[piWidth] - BordPad); - MargArray[MarginLeft] := Marg2 div 2; - MargArray[MarginRight] := Marg2 - MargArray[MarginLeft]; - end; - - 3: - begin - MargArray[MarginLeft] := 0; - MargArray[MarginRight] := 0; - ApplyBoxWidthSettings(MargArray,MinWidth,MaxWidth,Document.UseQuirksMode); - CalcWidth; - end; - end; - Result := MargArray[piWidth]; - -{$IFDEF JPM_DEBUGGING} - CodeSite.SendFmtMsg('Result = [%d]',[Result]); - CodeSite.ExitMethod(Self,'TBlock.FindWidth'); -{$ENDIF} -end; - -{----------------TBlock.DrawLogic} - -function TBlock.DrawLogic1(Canvas: TCanvas; X, Y, XRef, YRef, AWidth, AHeight, BlHt: Integer; IMgr: TIndentManager; - var MaxWidth, Curs: Integer): Integer; -var - ScrollWidth, YClear: Integer; - LIndex, RIndex: Integer; - SaveID: TObject; - TotalWidth, LeftWidths, RightWidths, MiscWidths: Integer; - AutoCount: Integer; - BlockHeight: Integer; - IB, Xin: Integer; - - function GetClientContentBot(ClientContentBot: Integer): Integer; - var - H: Integer; - begin - H := MargArray[piHeight]; - if not VarIsIntNull(MargArrayO[piHeight]) then - if Pos('%', VarToStr(MargArrayO[piHeight])) > 0 then - H := LengthConv(MargArrayO[piHeight], False, ContainingBox.Bottom - ContainingBox.Top, EmSize, ExSize, 0); - Result := Max(H, Max(ContentTop, ClientContentBot)); - end; - - procedure DrawLogicAsBlock; - var - LIndent, RIndent: Integer; - ARect: TRect; - begin - YDraw := Y; - Xin := X; - ClearAddOn := GetClearSpace(IMgr, Y); - StartCurs := Curs; - MaxWidth := AWidth; - - ConvMargArray(AWidth, AHeight, AutoCount); - HasBorderStyle := - (ThtBorderStyle(MargArray[BorderTopStyle]) <> bssNone) or - (ThtBorderStyle(MargArray[BorderRightStyle]) <> bssNone) or - (ThtBorderStyle(MargArray[BorderBottomStyle]) <> bssNone) or - (ThtBorderStyle(MargArray[BorderLeftStyle]) <> bssNone); - - ApplyBoxSettings(MargArray, Document.UseQuirksMode); - ContentWidth := FindWidth(Canvas, AWidth, AHeight, AutoCount); - LeftWidths := MargArray[MarginLeft] + MargArray[PaddingLeft] + MargArray[BorderLeftWidth]; - RightWidths := MargArray[MarginRight] + MargArray[PaddingRight] + MargArray[BorderRightWidth]; - MiscWidths := LeftWidths + RightWidths; - TotalWidth := MiscWidths + ContentWidth; - - case Positioning of - posAbsolute: - ARect := ContainingBox; - - posFixed: - ARect := Document.ViewPort; - end; - - FIndent := LeftWidths; - TopP := 0; - LeftP := 0; - case Positioning of - posAbsolute, - posFixed: - begin - if not IsAuto(Positions[reLeft]) then - X := ARect.Left + Positions[reLeft] - else if not IsAuto(Positions[reRight]) and not IsAuto(MargArray[piWidth]) then - X := ARect.Right - Positions[reRight] - MargArray[piWidth]; - LeftP := X; - - if not IsAuto(Positions[reTop]) then - Y := ARect.Top + Positions[reTop] - else if not IsAuto(Positions[reBottom]) and not IsAuto(MargArray[piHeight]) then - Y := ARect.Bottom - Positions[reBottom] - MargArray[piHeight]; - TopP := Y; - - DrawTop := TopP + Max(0, MargArray[MarginTop]); {Border top} - end; - else - if Positioning = posRelative then - begin - if not IsAuto(Positions[reLeft]) then Inc(LeftP, Positions[reLeft]); - if not IsAuto(Positions[reTop ]) then Inc(TopP, Positions[reTop ]); - end; - - case Floating of - ALeft: - begin - YClear := Y; - LIndent := IMgr.AlignLeft(YClear, TotalWidth); - FIndent := LIndent + LeftWidths - X; - end; - - ARight: - begin - YClear := Y; - RIndent := IMgr.AlignRight(YClear, TotalWidth); - FIndent := RIndent + LeftWidths - X; - end; - else - YClear := Y + ClearAddon; - end; - DrawTop := YClear + Max(0, MargArray[MarginTop]); {Border top} - end; - Inc(X, FIndent); - - ContentTop := DrawTop + MargArray[PaddingTop] + MargArray[BorderTopWidth]; - - if not IsInFlow then - begin - RefIMgr := IMgr; - if MyCell.IMgr = nil then - begin - MyIMgr := TIndentManager.Create; - MyCell.IMgr := MyIMgr; - end; - IMgr := MyCell.IMgr; - IMgr.Init(0, ContentWidth); - end - else - begin - MyCell.IMgr := IMgr; - end; - - SaveID := IMgr.CurrentID; - IMgr.CurrentID := Self; - - LIndex := IMgr.SetLeftIndent(X, YClear); - RIndex := IMgr.SetRightIndent(X + ContentWidth, YClear); - - if MargArray[piHeight] > 0 then - BlockHeight := MargArray[piHeight] - else if AHeight > 0 then - BlockHeight := AHeight - else - BlockHeight := BlHt; - - case Positioning of - posRelative: - begin - MyCell.DoLogicX(Canvas, - X, - ContentTop + TopP, - XRef, - ContentTop + TopP, - ContentWidth, MargArray[piHeight], BlockHeight, ScrollWidth, Curs); - MaxWidth := ScrollWidth + MiscWidths - MargArray[MarginRight] + LeftP - Xin; - ClientContentBot := GetClientContentBot(MyCell.tcContentBot - TopP); - end; - - posAbsolute: - begin - MyCell.DoLogicX(Canvas, - X, - ContentTop, - XRef + LeftP + MargArray[MarginLeft] + MargArray[BorderLeftWidth], - YRef + TopP + MargArray[MarginTop] + MargArray[BorderTopWidth], - ContentWidth, MargArray[piHeight], BlockHeight, ScrollWidth, Curs); - MaxWidth := ScrollWidth + MiscWidths - MargArray[MarginRight] + LeftP - Xin; - ClientContentBot := GetClientContentBot(MyCell.tcContentBot); - IB := IMgr.ImageBottom; {check for image overhang} - if IB > ClientContentBot then - ClientContentBot := IB; - end; - - posFixed: - begin - MyCell.DoLogicX(Canvas, - X, - ContentTop, - XRef + LeftP + MargArray[MarginLeft] + MargArray[BorderLeftWidth], - YRef + TopP + MargArray[MarginTop] + MargArray[BorderTopWidth], - ContentWidth, MargArray[piHeight], BlockHeight, ScrollWidth, Curs); - MaxWidth := ScrollWidth + MiscWidths - MargArray[MarginRight] + LeftP - Xin; - ClientContentBot := GetClientContentBot(MyCell.tcContentBot); - IB := IMgr.ImageBottom; {check for image overhang} - if IB > ClientContentBot then - ClientContentBot := IB; - end; - - else - MyCell.DoLogicX(Canvas, - X, - ContentTop, - XRef, - YRef, - ContentWidth, MargArray[piHeight], BlockHeight, ScrollWidth, Curs); - MaxWidth := Indent + ScrollWidth + RightWidths; - ClientContentBot := GetClientContentBot(MyCell.tcContentBot); - end; - Len := Curs - StartCurs; - - ContentBot := ClientContentBot + MargArray[PaddingBottom] + MargArray[BorderBottomWidth] + MargArray[MarginBottom]; - if ContentBot = ContentTop then - if IsInFlow then - begin - // no content, hide top margin - DrawTop := YClear; - ContentTop := DrawTop; - ClientContentBot := ContentTop; - ContentBot := ClientContentBot; - end; - - DrawBot := Max(ClientContentBot, MyCell.tcDrawBot) + MargArray[PaddingBottom] + MargArray[BorderBottomWidth]; - - Result := ContentBot - Y; - - if Assigned(BGImage) and Document.ShowImages then - begin - BGImage.DrawLogicInline(Canvas, nil, 100, 0); - if BGImage.Image = ErrorImage then - begin - FreeAndNil(BGImage); - NeedDoImageStuff := False; - end - else - begin - BGImage.ClientSizeKnown := True; {won't need reformat on InsertImage} - NeedDoImageStuff := True; - end; - end; - SectionHeight := Result; - IMgr.FreeLeftIndentRec(LIndex); - IMgr.FreeRightIndentRec(RIndex); - if not IsInFlow then - begin - case Positioning of - posAbsolute, - posFixed: - DrawHeight := 0 - else - DrawHeight := 0; //SectionHeight; - case Floating of - ALeft: RefIMgr.AddLeft(YClear, ContentBot, TotalWidth); - ARight: RefIMgr.AddRight(YClear, ContentBot, TotalWidth); - end; - end; - //SectionHeight := 0; - Result := 0; - end - else - begin - DrawHeight := IMgr.ImageBottom - Y; {in case image overhangs} - if DrawHeight < SectionHeight then - DrawHeight := SectionHeight; - end; - IMgr.CurrentID := SaveID; - if DrawList.Count = 0 then - DrawSort; - - //>-- DZ - DrawRect.Left := X - FIndent + MargArray[MarginLeft]; - DrawRect.Top := DrawTop; - DrawRect.Right := DrawRect.Left + ContentWidth; - DrawRect.Bottom := DrawRect.Top + SectionHeight; - end; - - procedure DrawLogicInline; - begin - //TODO -oBG, 15.03.2014: draw logic inline - DrawLogicAsBlock; - //DrawRect.Right := DrawRect.Left + MyCell.TextWidth; - end; - - procedure Invisible; - begin - SectionHeight := 0; - DrawHeight := 0; - ContentBot := 0; - DrawBot := 0; - MaxWidth := 0; - Result := 0; - - //>-- DZ - DrawRect.Left := X; - DrawRect.Top := DrawTop; - DrawRect.Right := DrawRect.Left + ContentWidth; - DrawRect.Bottom := DrawRect.Top + SectionHeight; - end; - -begin {TBlock.DrawLogic1} -{$IFDEF JPM_DEBUGGING_LOGIC} - CodeSite.EnterMethod(Self,Format('TBlock.DrawLogic1 "%s"', [TagClass])); - CodeSite.SendFmtMsg('AWidth, AHeight = [%4d, %4d]', [AWidth, AHeight]); -{$IFDEF JPM_DEBUGGING_LOGIC1} - CodeSite.SendFmtMsg('X, XRef = [%4d, %4d]', [X, XRef]); - CodeSite.SendFmtMsg('Y, YRef = [%4d, %4d]', [Y, YRef]); - CodeSite.SendFmtMsg('BlHt = [%d]',[BlHt]); - if Assigned(IMgr) then begin - CodeSite.SendFmtMsg('IMgr.LfEdge = [%d]',[ IMgr.LfEdge ] ); - CodeSite.SendFmtMsg('IMgr.Width = [%d]',[ IMgr.Width ] ); - CodeSite.SendFmtMsg('IMgr.ClipWidth = [%d]',[ IMgr.ClipWidth ] ); - end else begin - CodeSite.SendMsg('IMgr = nil'); - end; - CodeSite.SendFmtMsg('MaxWidth = [%d]',[MaxWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.AddSeparator; -{$ENDIF} -{$ENDIF} - case CalcDisplayIntern of - - pdInline: - DrawLogicInline; - - pdNone: - Invisible; - else -// pdBlock: -// pdTable: - DrawLogicAsBlock; - end; -{$IFDEF JPM_DEBUGGING_LOGIC} -{$IFDEF JPM_DEBUGGING_LOGIC1} - if Assigned(IMgr) then begin - CodeSite.SendFmtMsg('IMgr.LfEdge = [%d]',[ IMgr.LfEdge ] ); - CodeSite.SendFmtMsg('IMgr.Width = [%d]',[ IMgr.Width ] ); - CodeSite.SendFmtMsg('IMgr.ClipWidth = [%d]',[ IMgr.ClipWidth ] ); - end else begin - CodeSite.SendMsg('IMgr = nil'); - end; -{$ENDIF} - CodeSite.SendFmtMsg('MaxWidth = [%d]',[MaxWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.SendFmtMsg('Result = [%d]',[Result]); - CodeSite.ExitMethod(Self,'TBlock.DrawLogic1'); -{$ENDIF} -end; - -{----------------TBlock.DrawSort} - -procedure TBlock.DrawSort; -var - I, ZeroIndx, EndZeroIndx, SBZIndex: Integer; - SB: TSectionBase; - - procedure InsertSB(I1, I2: Integer); - var - J: Integer; - Inserted: Boolean; - begin - Inserted := False; - for J := I1 to I2 - 1 do - if SBZIndex < DrawList[J].ZIndex then - begin - DrawList.Insert(J, SB); - Inserted := True; - Break; - end; - if not Inserted then - DrawList.Insert(I2, SB); - end; - -begin - ZeroIndx := 0; - EndZeroIndx := 0; - for I := 0 to MyCell.Count - 1 do - begin - SB := MyCell.Items[I]; - SB.FOwnerBlock := Self; - SBZIndex := SB.ZIndex; - if SBZIndex < 0 then - begin - InsertSB(0, ZeroIndx); - Inc(ZeroIndx); - Inc(EndZeroIndx); - end - else if SBZIndex = 0 then {most items go here} - begin - DrawList.Insert(EndZeroIndx, SB); - Inc(EndZeroIndx); - end - else - InsertSB(EndZeroIndx, DrawList.Count); - end; -end; - -{----------------TBlock.Draw1} - -function TBlock.Draw1(Canvas: TCanvas; const ARect: TRect; IMgr: TIndentManager; X, XRef, YRef: Integer): Integer; - - procedure DrawAsBlock; - var - Y, YO: Integer; - HeightNeeded, Spacing: Integer; - begin - Y := YDraw; - YO := Y - Document.YOff; - Result := Y + SectionHeight; - - if Visibility = viHidden then - Exit; - - if Document.SkipDraw then - begin - Document.SkipDraw := False; - Exit; - end; - - if Document.Printing and (Positioning <> posAbsolute) then - begin - if BreakBefore and not Document.FirstPageItem then - begin - if ARect.Top + Document.YOff < YDraw + MargArray[MarginTop] then {page-break-before} - begin - if YDraw + MargArray[MarginTop] < Document.PageBottom then - Document.PageBottom := YDraw + MargArray[MarginTop]; - Document.SkipDraw := True; {prevents next block from drawing a line} - Exit; - end; - end - else if KeepIntact then - begin - {if we're printing and block won't fit on this page and block will fit on - next page, then don't do block now} - if (YO > ARect.Top) and (Y + DrawHeight > Document.PageBottom) and - (DrawHeight - MargArray[MarginTop] < ARect.Bottom - ARect.Top) then - begin - if Y + MargArray[MarginTop] < Document.PageBottom then - Document.PageBottom := Y + MargArray[MarginTop]; - Exit; - end; - end - else if BreakAfter then - begin - if ARect.Top + Document.YOff < Result then {page-break-after} - if Result < Document.PageBottom then - Document.PageBottom := Result; - end - else if Self is TTableBlock and not TTableBlock(Self).Table.HeadOrFoot then {ordinary tables} - {if we're printing and - we're 2/3 down page and table won't fit on this page and table will fit on - next page, then don't do table now} - begin - if (YO > ARect.Top + ((ARect.Bottom - ARect.Top) * 2) div 3) and - (Y + DrawHeight > Document.PageBottom) and - (DrawHeight < ARect.Bottom - ARect.Top) then - begin - if Y + MargArray[MarginTop] < Document.PageBottom then - Document.PageBottom := Y + MargArray[MarginTop]; - Exit; - end; - end - else if Self is TTableBlock then {try to avoid just a header and footer at page break} - with TTableBlock(Self).Table do - if HeadOrFoot and (Document.TableNestLevel = 0) - and ((Document.PrintingTable = nil) or - (Document.PrintingTable = TTableBlock(Self).Table)) then - begin - Spacing := CellSpacingVert div 2; - HeightNeeded := HeaderHeight + FootHeight + Rows.Items[HeaderRowCount].RowHeight; - if (YO > ARect.Top) and (Y + HeightNeeded > Document.PageBottom) and - (HeightNeeded < ARect.Bottom - ARect.Top) then - begin {will go on next page} - if Y + Spacing < Document.PageBottom then - begin - Document.PageShortened := True; - Document.PageBottom := Y + Spacing; - end; - Exit; - end; - end; - - end; - - case Positioning of - posRelative: - DrawBlock(Canvas, ARect, IMgr, X + LeftP, Y + TopP, XRef, YRef); - - posAbsolute: - DrawBlock(Canvas, ARect, IMgr, LeftP, TopP, 0, 0); - - posFixed: - DrawBlock(Canvas, ARect, IMgr, LeftP, TopP, 0, 0); - - else - if Floating in [ALeft, ARight] then - DrawBlock(Canvas, ARect, IMgr, X, Y, XRef, YRef) - else - DrawBlock(Canvas, ARect, IMgr, X, Y, XRef, YRef); - end; - end; - - procedure DrawInline; - begin - DrawAsBlock; - end; - -begin - case CalcDisplayIntern of - - pdInline: - DrawInline; - - pdNone: - Result := 0; - - else -// pdBlock: -// pdTable: - DrawAsBlock; - end; -end; - -{----------------TBlock.DrawBlock} - -procedure TBlock.DrawBlock(Canvas: TCanvas; const ARect: TRect; - IMgr: TIndentManager; X, Y, XRef, YRef: Integer); - -var - YOffset: Integer; - XR, YB, RefX, RefY, TmpHt: Integer; - SaveID: TObject; - ImgOK, HasBackgroundColor: Boolean; - IT, IH, FT, IW: Integer; - Rgn, SaveRgn, SaveRgn1: HRgn; - OpenRgn: Boolean; - PdRect, CnRect: TRect; // padding rect, content rect - NegativeMargins: Boolean; -begin - if Document.Printing and not Document.PrintBackground then - NeedDoImageStuff := False; - YOffset := Document.YOff; - - case Floating of - ALeft, ARight: - begin - //X := IMgr.LfEdge + Indent; - X := X + Indent; - RefX := X - MargArray[PaddingLeft] - MargArray[BorderLeftWidth]; - XR := X + ContentWidth + MargArray[PaddingRight] + MargArray[BorderRightWidth]; - RefY := DrawTop; - YB := ContentBot - MargArray[MarginBottom]; - end; - else -// BG, 08.09.2013: inline vs block: -// X of centered blocks may differ from (DrawRect.Left - MargArray[MarginLeft]) calculated in DrawLogic1(). - RefX := X + MargArray[MarginLeft]; - X := X + Indent; -// RefX := DrawRect.Left; -// X := RefX - MargArray[MarginLeft] + Indent; - XR := X + ContentWidth + MargArray[PaddingRight] + MargArray[BorderRightWidth]; {current right edge} - RefY := Y + ClearAddon + MargArray[MarginTop]; - YB := ContentBot - MargArray[MarginBottom]; - case Positioning of - posRelative: - Inc(YB, TopP); - - end; - end; - - // MyRect is the outmost rectangle of this block incl. border and padding but without margins in screen coordinates. - case Positioning of - posFixed: - MyRect := Rect(RefX, RefY, XR, YB); - else - MyRect := Rect(RefX, RefY - YOffset, XR, YB - YOffset); - end; - - // PdRect is the border rectangle of this block incl. padding in screen coordinates - PdRect.Left := MyRect.Left + MargArray[BorderLeftWidth]; - PdRect.Top := MyRect.Top + MargArray[BorderTopWidth]; - PdRect.Right := MyRect.Right - MargArray[BorderRightWidth]; - PdRect.Bottom := MyRect.Bottom - MargArray[BorderBottomWidth]; - - // CnRect is the content rectangle of this block in screen coordinates - CnRect.Left := PdRect.Left + MargArray[PaddingLeft]; - CnRect.Top := PdRect.Top + MargArray[PaddingTop]; - CnRect.Right := PdRect.Right - MargArray[PaddingRight]; - CnRect.Bottom := PdRect.Bottom - MargArray[PaddingBottom]; - - //>-- DZ - DrawRect.Top := MyRect.Top + YOffset; - DrawRect.Left := MyRect.Left; - DrawRect.Bottom := MyRect.Bottom + YOffset; - DrawRect.Right := MyRect.Right; - - IT := Max(0, ARect.Top - 2 - PdRect.Top); - FT := Max(PdRect.Top, ARect.Top - 2); {top of area drawn, screen coordinates} - IH := Min(PdRect.Bottom, ARect.Bottom) - FT; {height of area actually drawn} - IW := PdRect.Right - PdRect.Left; - - NegativeMargins := (MargArray[MarginLeft] < 0) or (MargArray[MarginTop] < 0) or (MargArray[MarginBottom] < 0) or (MargArray[MarginRight] < 0); - SaveRgn1 := 0; - OpenRgn := ((Positioning <> PosStatic) or NegativeMargins) and (Document.TableNestLevel > 0); - if OpenRgn then - begin - SaveRgn1 := CreateRectRgn(0, 0, 1, 1); - case GetClipRgn(Canvas.Handle, SaveRgn1) of - -1, // failed to get the clip region - 0: // there is no clip region - begin - DeleteObject(SaveRgn1); - SaveRgn1 := 0; - end; - else - //1: got the clip region - SelectClipRgn(Canvas.Handle, 0); - end; - end; - try - if (MyRect.Top <= ARect.Bottom) and (MyRect.Bottom >= ARect.Top) then - begin - HasBackgroundColor := MargArray[BackgroundColor] <> clNone; - try - if NeedDoImageStuff and Assigned(BGImage) and (BGImage.Image <> DefImage) then - begin - if BGImage.Image = ErrorImage then {Skip the background image} - FreeAndNil(BGImage) - else - try - if Floating in [ALeft, ARight] then - TmpHt := DrawBot - ContentTop + MargArray[PaddingTop] + MargArray[PaddingBottom] - else - TmpHt := ClientContentBot - ContentTop + MargArray[PaddingTop] + MargArray[PaddingBottom]; - - BgImage.Image.TileImage( PRec, - MargArray[PaddingLeft] + ContentWidth + MargArray[PaddingRight], TmpHt, - TiledImage, NoMask); - if IsCopy then - TiledImage.Bitmap.HandleType := bmDIB; - except {bad image, get rid of it} - FreeAndNil(BGImage); - FreeAndNil(TiledImage); - end; - NeedDoImageStuff := False; - end; - - if Document.NoOutput then - exit; - - ImgOK := not NeedDoImageStuff and (BGImage <> nil) and (BGImage.Image <> DefImage) and (TiledImage <> nil) and Document.ShowImages; - - if HasBackgroundColor {and (not Document.Printing or Document.PrintBackground)} then - begin {color the Padding Region} - Canvas.Brush.Style := bsSolid; - Canvas.Brush.Color := ThemedColor(MargArray[BackgroundColor]{$ifdef has_StyleElements},seClient in Document.StyleElements{$endif}) or PalRelative; - end - else - Canvas.Brush.Style := bsClear; - - if ImgOK then - if not IsCopy then - TiledImage.DrawUnstretched(Canvas, PdRect.Left, FT, IW, IH, 0, IT, HasBackgroundColor ) - else - TiledImage.PrintUnstretched(Canvas, PdRect.Left, FT, IW, IH, 0, IT, HasBackgroundColor and Document.PrintBackground ) - else - if not Document.Printing or Document.PrintBackground then - Canvas.FillRect(Rect(PdRect.Left, FT, PdRect.Right, FT + IH)); - except - end; - end; - - if HideOverflow then - begin - Rgn := 0; - SaveRgn := 0; - if Floating = ANone then - GetClippingRgn(Canvas, CnRect, Document.Printing, Rgn, SaveRgn) - else - GetClippingRgn(Canvas, PdRect, Document.Printing, Rgn, SaveRgn); - SelectClipRgn(Canvas.Handle, Rgn); - end; - try - SaveID := IMgr.CurrentID; - Imgr.CurrentID := Self; - case Positioning of - posRelative: - DrawTheList(Canvas, ARect, ContentWidth, X, - RefX + MargArray[BorderLeftWidth] + MargArray[PaddingLeft], - Y + MargArray[MarginTop] + MargArray[BorderTopWidth] + MargArray[PaddingTop]); - - posAbsolute: - DrawTheList(Canvas, ARect, ContentWidth, X, - RefX + MargArray[BorderLeftWidth], - Y + MargArray[MarginTop] + MargArray[BorderTopWidth]); - - posFixed: - DrawTheList(Canvas, ARect, ContentWidth, X, - PdRect.Left, - PdRect.Top); - else - DrawTheList(Canvas, ARect, ContentWidth, X, XRef, YRef); - end; - Imgr.CurrentID := SaveID; - finally - if HideOverflow then {restore any previous clip region} - begin - SelectClipRgn(Canvas.Handle, SaveRgn); - DeleteObject(Rgn); - if SaveRgn <> 0 then - DeleteObject(SaveRgn); - end; - end; - DrawBlockBorder(Canvas, MyRect, PdRect); - finally - if SaveRgn1 <> 0 then - begin - SelectClipRgn(Canvas.Handle, SaveRgn1); - DeleteObject(SaveRgn1); - end; - end; -end; - -procedure TBlock.DrawBlockBorder(Canvas: TCanvas; const ORect, IRect: TRect); -begin - if HasBorderStyle then - if (ORect.Left <> IRect.Left) or (ORect.Top <> IRect.Top) or (ORect.Right <> IRect.Right) or (ORect.Bottom <> IRect.Bottom) then - DrawBorder(Canvas, ORect, IRect, - htColors(MargArray[BorderLeftColor], MargArray[BorderTopColor], MargArray[BorderRightColor], MargArray[BorderBottomColor]), - htStyles(ThtBorderStyle(MargArray[BorderLeftStyle]), ThtBorderStyle(MargArray[BorderTopStyle]), ThtBorderStyle(MargArray[BorderRightStyle]), ThtBorderStyle(MargArray[BorderBottomStyle])), - MargArray[BackgroundColor], Document.Printing{$ifdef has_StyleElements}, Document.StyleElements {$endif}) -end; - -procedure TBlock.DrawTheList(Canvas: TCanvas; const ARect: TRect; ClipWidth, X, XRef, YRef: Integer); -{draw the list sorted by Z order.} -var - I: Integer; - SaveID: TObject; -begin - if not IsInFlow then - with MyCell do - begin - SaveID := IMgr.CurrentID; - IMgr.Reset(RefIMgr.LfEdge); - IMgr.ClipWidth := ClipWidth; - IMgr.CurrentID := SaveID; - end - else - MyCell.IMgr.ClipWidth := ClipWidth; - for I := 0 to DrawList.Count - 1 do - DrawList[I].Draw1(Canvas, ARect, MyCell.IMgr, X, XRef, YRef); -end; - -{$ifdef UseFormTree} -procedure TBlock.FormTree(const Indent: ThtString; var Tree: ThtString); -var - MyIndent: ThtString; - TM, BM: ThtString; -begin - MyIndent := Indent + ' '; - TM := IntToStr(MargArray[MarginTop]); - BM := IntToStr(MargArray[MarginBottom]); - Tree := Tree + Indent + TagClass + ' ' + TM + ' ' + BM + CrChar + LfChar; - MyCell.FormTree(MyIndent, Tree); -end; -{$endif UseFormTree} - -//-- BG ---------------------------------------------------------- 24.08.2010 -- -function TBlock.GetBorderWidth: Integer; -begin - Result := 3; -end; - -{----------------TTableAndCaptionBlock.Create} - -constructor TTableAndCaptionBlock.Create( - Parent: TCellBasic; Attributes: TAttributeList; Prop: TProperties; ATableBlock: TTableBlock); -var - I: Integer; -begin - {$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'TTableAndCaptionBlock.Create'); - {$ENDIF} - inherited Create(Parent, Attributes, Prop); - TableBlock := ATableBlock; - Justify := TableBlock.Justify; - - for I := 0 to Attributes.Count - 1 do - with Attributes[I] do - case Which of - AlignSy: - if htCompareText(Name, 'CENTER') = 0 then - Justify := Centered - else if htCompareText(Name, 'LEFT') = 0 then - begin - if FFloating = ANone then - FFloating := ALeft; - end - else if htCompareText(Name, 'RIGHT') = 0 then - begin - if FFloating = ANone then - FFloating := ARight; - end; - end; - TableID := Attributes.TheID; - -{CollapseMargins has already been called by TableBlock, copy the results here} - MargArray[MarginTop] := TableBlock.MargArray[MarginTop]; - MargArray[MarginBottom] := TableBlock.MargArray[MarginBottom]; - - TagClass := 'TableAndCaption.'; - {$IFDEF JPM_DEBUGGING} - CodeSite.ExitMethod(Self,'TTableAndCaptionBlock.Create'); - {$ENDIF} -end; - -{----------------TTableAndCaptionBlock.CancelUsage} - -procedure TTableAndCaptionBlock.CancelUsage; -{called when it's found that this block isn't needed (no caption)} -begin -{assign the ID back to the Table} - if TableID <> '' then - Document.IDNameList.AddObject(TableID, TableBlock); -end; - -{----------------TTableAndCaptionBlock.CreateCopy} - -constructor TTableAndCaptionBlock.CreateCopy(OwnerCell: TCellBasic; Source: THtmlNode); -var - T: TTableAndCaptionBlock absolute Source; - Item: TObject; - I1, I2: Integer; -begin - inherited CreateCopy(OwnerCell,Source); - TopCaption := T.TopCaption; - Justify := T.Justify; - TagClass := 'TableAndCaption.'; - I1 := Ord(TopCaption); - I2 := Ord(not TopCaption); - Item := MyCell.Items[I2]; - FCaptionBlock := (Item as TBlock); - Item := MyCell.Items[I1]; - TableBlock := (Item as TTableBlock); -end; - -procedure TTableAndCaptionBlock.SetCaptionBlock(Value: TBlock); -begin - FCaptionBlock := Value; - TableBlock.HasCaption := True; -end; - -{----------------TTableAndCaptionBlock.FindWidth} - -function TTableAndCaptionBlock.FindWidth(Canvas: TCanvas; AWidth, AHeight, AutoCount: Integer): Integer; -var - Mx, Mn, FWidth: Integer; -begin -{$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'TTableAndCaptionBlock.FindWidth'); - CodeSite.SendFmtMsg('AWidth = [%d]',[AWidth]); - CodeSite.SendFmtMsg('AHeight = [%d]',[AHeight]); - CodeSite.SendFmtMsg('AutoCount = [%d]',[AutoCount]); - CodeSite.AddSeparator; -{$ENDIF} - HasBorderStyle := False; //bssNone; {has no border} - MargArray[BorderLeftWidth] := 0; - MargArray[BorderTopWidth] := 0; - MargArray[BorderRightWidth] := 0; - MargArray[BorderBottomWidth] := 0; - MargArray[PaddingLeft] := 0; - MargArray[PaddingTop] := 0; - MargArray[PaddingRight] := 0; - MargArray[PaddingBottom] := 0; - MargArray[BackgroundColor] := clNone; - - TableBlock.FFloating := ANone; - TableBlock.Table.Float := False; - - CaptionBlock.MinMaxWidth(Canvas, Mn, Mx); - FWidth := TableBlock.FindWidth1(Canvas, AWidth, MargArray[MarginLeft] + MargArray[MarginRight]); - Result := Max(FWidth, Mn); - if (Result < AWidth) and (MargArray[MarginLeft] = 0) and (MargArray[MarginRight] = 0) then - case Justify of - Centered: - MargArray[MarginLeft] := (AWidth - Result) div 2; - Right: - MargArray[MarginLeft] := AWidth - Result; - end; - TableBlock.Justify := Centered; -{$IFDEF JPM_DEBUGGING} - CodeSite.SendFmtMsg('Result = [%d]',[Result]); - CodeSite.ExitMethod(Self,'TTableAndCaptionBlock.FindWidth'); -{$ENDIF} -end; - -{----------------TTableAndCaptionBlock.MinMaxWidth} - -procedure TTableAndCaptionBlock.MinMaxWidth(Canvas: TCanvas; out Min, Max: Integer); -var - Mx, Mn, MxTable, MnTable: Integer; -begin -{$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self, Format('TTableAndCaptionBlock.MinMaxWidth TagClass = [%s]', [TagClass])); - try -{$ENDIF} - TableBlock.MinMaxWidth(Canvas, MnTable, MxTable); - FCaptionBlock.MinMaxWidth(Canvas, Mn, Mx); - Min := Math.Max(MnTable, Mn); - Max := Math.Max(MxTable, Mn); -{$IFDEF JPM_DEBUGGING} - finally - CodeSite.ExitMethod(Self, Format('TTableAndCaptionBlock.MinMaxWidth %d .. %d', [Min, Max])); - end; -{$ENDIF} -end; - -function TTableAndCaptionBlock.FindDocPos(SourcePos: Integer; Prev: Boolean): Integer; -begin - if not Prev then - begin - Result := FCaptionBlock.FindDocPos(SourcePos, Prev); - if Result < 0 then - Result := TableBlock.FindDocPos(SourcePos, Prev); - end - else {Prev, iterate backwards} - begin - Result := TableBlock.FindDocPos(SourcePos, Prev); - if Result < 0 then - Result := FCaptionBlock.FindDocPos(SourcePos, Prev); - end; -end; - -{----------------TTableBlock.Create} - -constructor TTableBlock.Create(Parent: TCellBasic; Attr: TAttributeList; Prop: TProperties; TableLevel: Integer); -var - I, AutoCount: Integer; - BorderWidth: Integer; - Percent: Boolean; - TheProps, MyProps: TProperties; -begin - {$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'TTableBlock.Create'); - {$ENDIF} - - Table := THtmlTable.Create(Self, Parent, Attr, Prop); - - // BG, 20.01.2013: translate table attributes to block property defaults: - MyProps := TProperties.CreateCopy(Prop); - TheProps := MyProps; - try - if Table.BorderColor <> clNone then - MyProps.SetPropertyDefaults([BorderBottomColor, BorderRightColor, BorderTopColor, BorderLeftColor], Table.BorderColor) - else - begin - if Table.HasBorderWidthAttr then - MyProps.SetPropertyDefaults([BorderBottomColor, BorderRightColor, BorderTopColor, BorderLeftColor], clGray) - else - MyProps.SetPropertyDefaults([BorderBottomColor, BorderRightColor, BorderTopColor, BorderLeftColor], clNone); - end; - - MyProps.SetPropertyDefault(BorderSpacingHorz, Table.CellSpacingHorz); - MyProps.SetPropertyDefault(BorderSpacingVert, Table.CellSpacingVert); - - if Table.HasBorderWidthAttr then - MyProps.SetPropertyDefaults([BorderBottomWidth, BorderRightWidth, BorderTopWidth, BorderLeftWidth], Table.brdWidthAttr); - - case Table.Frame of - tfBox, tfBorder: - MyProps.SetPropertyDefaults([BorderBottomStyle, BorderRightStyle, BorderTopStyle, BorderLeftStyle], bssOutset); - - tfHSides: - begin - MyProps.SetPropertyDefaults([BorderTopStyle, BorderBottomStyle], bssSolid); - MyProps.SetPropertyDefaults([BorderLeftStyle, BorderRightStyle], bssNone); - end; - - tfVSides: - begin - MyProps.SetPropertyDefaults([BorderTopStyle, BorderBottomStyle], bssNone); - MyProps.SetPropertyDefaults([BorderLeftStyle, BorderRightStyle], bssSolid); - end; - - tfAbove: - begin - MyProps.SetPropertyDefault(BorderTopStyle, bssSolid); - MyProps.SetPropertyDefaults([BorderBottomStyle, BorderRightStyle, BorderLeftStyle], bssNone); - end; - - tfBelow: - begin - MyProps.SetPropertyDefault(BorderBottomStyle, bssSolid); - MyProps.SetPropertyDefaults([BorderRightStyle, BorderTopStyle, BorderLeftStyle], bssNone); - end; - - tfLhs: - begin - MyProps.SetPropertyDefault(BorderLeftStyle, bssSolid); - MyProps.SetPropertyDefaults([BorderBottomStyle, BorderRightStyle, BorderTopStyle], bssNone); - end; - - tfRhs: - begin - MyProps.SetPropertyDefault(BorderRightStyle, bssSolid); - MyProps.SetPropertyDefaults([BorderBottomStyle, BorderTopStyle, BorderLeftStyle], bssNone); - end; - else - if Table.HasBorderWidthAttr then - if Table.brdWidthAttr > 0 then - MyProps.SetPropertyDefaults([BorderBottomStyle, BorderRightStyle, BorderTopStyle, BorderLeftStyle], bssOutset) - else - MyProps.SetPropertyDefaults([BorderBottomStyle, BorderRightStyle, BorderTopStyle, BorderLeftStyle], bssNone); - end; - - inherited Create(Parent, Attr, TheProps); - finally - MyProps.Free; - end; - - Justify := NoJustify; - - for I := 0 to Attr.Count - 1 do - with Attr[I] do - case Which of - - AlignSy: - if htCompareText(Name, 'CENTER') = 0 then - Justify := Centered - else if htCompareText(Name, 'LEFT') = 0 then - begin -//TODO: BG, 14.07.2013: The table block is not floating, but justified! - if FFloating = ANone then - FFloating := ALeft; -// Justify := Left; - end - else if htCompareText(Name, 'RIGHT') = 0 then - begin -//TODO: BG, 14.07.2013: The table block is not floating, but justified! - if FFloating = ANone then - FFloating := ARight; -// Justify := Right; - end; - - BGColorSy: - BkGnd := TryStrToColor(Name, False, BkColor); - - BackgroundSy: - if not Assigned(BGImage) then - begin - BGImage := TImageObj.SimpleCreate(MyCell, Name); - PRec.X.PosType := bpDim; - PRec.X.Value := 0; - PRec.X.RepeatD := True; - PRec.Y := PRec.X; - end; - - HSpaceSy: HSpace := Min(40, Abs(Value)); - - VSpaceSy: VSpace := Min(200, Abs(Value)); - - WidthSy: - if Pos('%', Name) > 0 then - begin - if (Value > 0) and (Value <= 100) then - WidthAttr := Value * 10; - AsPercent := True; - end - else - WidthAttr := Value; - - HeightSy: - if (VarType(MargArrayO[piHeight]) in VarInt) and (MargArrayO[piHeight] = IntNull) then - MargArrayO[piHeight] := Name; - end; - - if Table.BorderWidth > 0 then - BorderWidth := Table.BorderWidth - else - BorderWidth := 3; - -{need to see if width is defined in style} - Percent := (VarIsStr(MargArrayO[piWidth])) and (Pos('%', MargArrayO[piWidth]) > 0); - StyleUn.ConvMargArray(MargArrayO, 100, 0, EmSize, ExSize, BorderWidth, AutoCount, MargArray); - if MargArray[piWidth] > 0 then - begin - if Percent then - begin - AsPercent := True; - WidthAttr := Min(1000, MargArray[piWidth] * 10); - end - else - begin - WidthAttr := MargArray[piWidth]; - {By custom (not by specs), tables handle CSS Width property differently. The - Width includes the padding and border.} - MargArray[piWidth] := WidthAttr - MargArray[BorderLeftWidth] - MargArray[BorderRightWidth] - - MargArray[PaddingLeft] - MargArray[PaddingRight]; - MargArrayO[piWidth] := MargArray[piWidth]; - AsPercent := False; - end; - end; - - CollapseAdjoiningMargins; - Table.Float := Floating in [ALeft, ARight]; - if Table.Float and (ZIndex = 0) then - ZIndex := 1; - {$IFDEF JPM_DEBUGGING} - CodeSite.ExitMethod(Self,'TTableBlock.Create'); - {$ENDIF} -end; - -{----------------TTableBlock.CreateCopy} - -constructor TTableBlock.CreateCopy(OwnerCell: TCellBasic; Source: THtmlNode); -var - T: TTableBlock absolute Source; - Item: TObject; -begin - inherited CreateCopy(OwnerCell,Source); - System.Move(T.WidthAttr, WidthAttr, PtrSub(@Justify, @WidthAttr) + Sizeof(Justify)); - Item := MyCell.Items[0]; - Table := Item as THtmlTable; -end; - -{----------------TTableBlock.MinMaxWidth} - -procedure TTableBlock.MinMaxWidth(Canvas: TCanvas; out Min, Max: Integer); -var - TmpWidth: Integer; -begin -{$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self, Format('TTableBlock.MinMaxWidth TagClass = [%s]', [TagClass])); - try -{$ENDIF} - if AsPercent then - TmpWidth := 0 - else - TmpWidth := Math.Max(0, WidthAttr - MargArray[BorderLeftWidth] - MargArray[BorderRightWidth] - - MargArray[PaddingLeft] - MargArray[PaddingRight]); - Table.tblWidthAttr := TmpWidth; - inherited MinMaxWidth(Canvas, Min, Max); - if TmpWidth > 0 then - begin - Min := Math.Max(Min, TmpWidth); - Max := Min; - end; -{$IFDEF JPM_DEBUGGING} - finally - CodeSite.ExitMethod(Self, Format('TTableBlock.MinMaxWidth %d .. %d', [Min, Max])); - end; -{$ENDIF} -end; - -{----------------TTableBlock.FindWidth1} - -function TTableBlock.FindWidth1(Canvas: TCanvas; AWidth, ExtMarg: Integer): Integer; -{called by TTableAndCaptionBlock to assist in it's FindWidth Calculation. - This method is called before TTableBlockFindWidth but is called only if there - is a caption on the table. AWidth is the full width available to the - TTableAndCaptionBlock.} -var - PaddingAndBorder: Integer; - Min, Max, Allow: Integer; -begin - MargArray[MarginLeft] := 0; - MargArray[MarginRight] := 0; - MargArray[MarginTop] := 0; - MargArray[MarginBottom] := 0; - - PaddingAndBorder := - MargArray[BorderLeftWidth] + MargArray[PaddingLeft] + - MargArray[BorderRightWidth] + MargArray[PaddingRight]; - Table.tblWidthAttr := 0; - if WidthAttr > 0 then - begin - if AsPercent then - Result := Math.Min(MulDiv(AWidth, WidthAttr, 1000), AWidth - ExtMarg) - else - Result := WidthAttr; - Result := Result - PaddingAndBorder; - Table.tblWidthAttr := Result; - Table.MinMaxWidth(Canvas, Min, Max); - Result := Math.Max(Min, Result); - Table.tblWidthAttr := Result; - end - else - begin - Table.MinMaxWidth(Canvas, Min, Max); - Allow := AWidth - PaddingAndBorder; - if Max <= Allow then - Result := Max - else if Min >= Allow then - Result := Min - else - Result := Allow; - end; - Result := Result + PaddingAndBorder; -end; - -//-- BG ---------------------------------------------------------- 24.08.2010 -- -function TTableBlock.GetBorderWidth: Integer; -begin - Result := Table.BorderWidth; - if Result = 0 then - Result := 3; -end; - -{----------------TTableBlock.FindWidth} - -function TTableBlock.FindWidth(Canvas: TCanvas; AWidth, AHeight, AutoCount: Integer): Integer; -var - LeftSide, RightSide: Integer; - Min, Max, M, P: Integer; -begin - if not HasCaption then - begin - inherited FindWidth(Canvas, AWidth, AHeight, AUtoCount); -// if MargArray[MarginLeft] = Auto then -// MargArray[MarginLeft] := 0; -// if MargArray[MarginRight] = Auto then -// MargArray[MarginRight] := 0; -// -// if Floating in [ALeft, ARight] then -// begin -// if MargArray[MarginLeft] = 0 then -// MargArray[MarginLeft] := HSpace; -// if MargArray[MarginRight] = 0 then -// MargArray[MarginRight] := HSpace; -// if MargArray[MarginTop] = 0 then -// MargArray[MarginTop] := VSpace; -// if MargArray[MarginBottom] = 0 then -// MargArray[MarginBottom] := VSpace; -// end; - end - else - begin - MargArray[MarginLeft] := 0; - MargArray[MarginRight] := 0; - end; - - if BkGnd and (MargArray[BackgroundColor] = clNone) then - MargArray[BackgroundColor] := BkColor; - Table.FBkGnd := (MargArray[BackgroundColor] <> clNone) and not Assigned(BGImage); - Table.FBkColor := MargArray[BackgroundColor]; {to be passed on to cells} - - LeftSide := MargArray[MarginLeft] + MargArray[PaddingLeft] + MargArray[BorderLeftWidth]; - RightSide := MargArray[MarginRight] + MargArray[PaddingRight] + MargArray[BorderRightWidth]; - - if not HasCaption then - Table.tblWidthAttr := 0; - if WidthAttr > 0 then - begin - if not HasCaption then {already done if HasCaption} - begin - if AsPercent then - Result := MulDiv(AWidth, WidthAttr, 1000) - LeftSide - RightSide - else - Result := WidthAttr - (MargArray[PaddingLeft] + MargArray[BorderLeftWidth] + MargArray[PaddingRight] + MargArray[BorderRightWidth]); - Table.tblWidthAttr := Result; - Table.MinMaxWidth(Canvas, Min, Max); - Table.tblWidthAttr := Math.Max(Min, Math.Min(Max, Result)); - end; - Result := Table.tblWidthAttr; - end - else - begin - Result := AWidth - LeftSide - RightSide; - Table.MinMaxWidth(Canvas, Min, Max); - P := Math.Min(Sum(Table.Percents), 1000); - if P > 0 then - begin - P := MulDiv(Result, P, 1000); - Min := Math.Max(Min, P); - Max := Math.Max(Max, P); - end; - if Result > Max then - Result := Max - else if Result < Min then - Result := Min; - end; - MargArray[piWidth] := Result; - - if (MargArray[MarginLeft] = 0) and (MargArray[MarginRight] = 0) and (Result + LeftSide + RightSide < AWidth) then - begin - M := AWidth - LeftSide - Result - RightSide; - case Justify of - Centered: - begin - MargArray[MarginLeft] := M div 2; - MargArray[MarginRight] := M - MargArray[MarginLeft]; - end; - - Right: - MargArray[MarginLeft] := M; - - Left: - MargArray[MarginRight] := M; - - end; - end; -end; - -function TTableBlock.DrawLogic1(Canvas: TCanvas; X, Y, XRef, YRef, AWidth, AHeight, BlHt: Integer; IMgr: TIndentManager; - var MaxWidth, Curs: Integer): Integer; -var - X1, Tmp: Integer; -begin -{$IFDEF JPM_DEBUGGING_LOGIC} - CodeSite.EnterMethod(Self, Format('TTableBlock.DrawLogic1 TagClass = [%s]', [Self.TagClass] )); -{$IFDEF JPM_DEBUGGING_LOGIC1} - CodeSite.SendFmtMsg('X, XRef = [%4d, %4d]', [X, XRef]); - CodeSite.SendFmtMsg('Y, YRef = [%4d, %4d]', [Y, YRef]); - CodeSite.SendFmtMsg('AWidth = [%d]',[AWidth]); - CodeSite.SendFmtMsg('AHeight = [%d]',[AHeight]); - CodeSite.SendFmtMsg('BlHt = [%d]',[BlHt]); - if Assigned(IMgr) then begin - CodeSite.SendFmtMsg('IMgr.LfEdge = [%d]',[ IMgr.LfEdge ] ); - CodeSite.SendFmtMsg('IMgr.Width = [%d]',[ IMgr.Width ] ); - CodeSite.SendFmtMsg('IMgr.ClipWidth = [%d]',[ IMgr.ClipWidth ] ); - end else begin - CodeSite.SendMsg('IMgr = nil'); - end; - CodeSite.SendFmtMsg('MaxWidth = [%d]',[MaxWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.AddSeparator; -{$ENDIF} -{$ENDIF} - if not (Floating in [ALeft, ARight]) then - begin - Tmp := X; - X := Max(Tmp, IMgr.LeftIndent(Y)); - TableIndent := X - Tmp; - X1 := Min(Tmp + AWidth, IMgr.RightSide(Y)); - AWidth := X1 - X; - end; - Result := inherited DrawLogic1(Canvas, X, Y, XRef, YRef, AWidth, AHeight, BlHt, IMgr, MaxWidth, Curs); -{$IFDEF JPM_DEBUGGING_LOGIC} -{$IFDEF JPM_DEBUGGING_LOGIC1} - if Assigned(IMgr) then begin - CodeSite.SendFmtMsg('IMgr.LfEdge = [%d]',[ IMgr.LfEdge ] ); - CodeSite.SendFmtMsg('IMgr.Width = [%d]',[ IMgr.Width ] ); - CodeSite.SendFmtMsg('IMgr.ClipWidth = [%d]',[ IMgr.ClipWidth ] ); - end else begin - CodeSite.SendMsg('IMgr = nil'); - end; -{$ENDIF} - CodeSite.SendFmtMsg('MaxWidth = [%d]',[MaxWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.SendFmtMsg('Result = [%d]',[Result]); - CodeSite.ExitMethod(Self,'TTableBlock.DrawLogic1'); -{$ENDIF} -end; - -function TTableBlock.Draw1(Canvas: TCanvas; const ARect: TRect; IMgr: TIndentManager; X, XRef, YRef: Integer): Integer; -begin - X := X + TableIndent; - Result := inherited Draw1(Canvas, ARect, IMgr, X, XRef, YRef); -end; - -procedure TTableBlock.AddSectionsToList; -begin {Sections in Table not added only table itself} - Document.PositionList.Add(Table); -end; - -constructor THRBlock.CreateCopy(OwnerCell: TCellBasic; Source: THtmlNode); -var - T: THRBlock absolute Source; -begin - inherited CreateCopy(OwnerCell,Source); - Align := T.Align; -end; - -{----------------THRBlock.FindWidth} - -function THRBlock.FindWidth(Canvas: TCanvas; AWidth, AHeight, AutoCount: Integer): Integer; -var - LeftSide, RightSide, SWidth: Integer; - Diff: Integer; -begin -{$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'THRBlock.FindWidth'); - CodeSite.SendFmtMsg('Self.TagClass = [%s]',[TagClass ]); - - CodeSite.SendFmtMsg('AWidth = [%d]',[AWidth]); - CodeSite.SendFmtMsg('AHeight = [%d]',[AHeight]); - CodeSite.SendFmtMsg('AutoCount = [%d]',[AutoCount]); - CodeSite.AddSeparator; -{$ENDIF} - - if Positioning = posAbsolute then - Align := Left; - LeftSide := MargArray[MarginLeft] + MargArray[PaddingLeft] + MargArray[BorderLeftWidth]; - RightSide := MargArray[MarginRight] + MargArray[PaddingRight] + MargArray[BorderRightWidth]; - SWidth := MargArray[piWidth]; - - if SWidth > 0 then - Result := Min(SWidth, AWidth - LeftSide - RightSide) - else - Result := Max(15, AWidth - LeftSide - RightSide); - MargArray[piWidth] := Result; -{note that above could be inherited; if LeftSide and Rightside were fields -of TBlock} - - if Align <> Left then - begin - Diff := AWidth - Result - LeftSide - RightSide; - if Diff > 0 then - case Align of - Centered: Inc(MargArray[MarginLeft], Diff div 2); - Right: Inc(MargArray[MarginLeft], Diff); - end; - end; - if not IsCopy then - THorzline(MyHRule).VSize := MargArray[piHeight]; - -{$IFDEF JPM_DEBUGGING} - CodeSite.SendFmtMsg('Result = [%d]',[Result]); - CodeSite.ExitMethod(Self,'THRBlock.FindWidth'); -{$ENDIF} -end; - -{----------------TBlockLI.Create} - -constructor TBlockLI.Create(Parent: TCellBasic; Attributes: TAttributeList; Prop: TProperties; - Sy: TElemSymb; APlain: Boolean; AIndexType: ThtChar; AListNumb, ListLevel: Integer); -var - Tmp: ThtBulletStyle; - S: ThtString; -begin - inherited Create(Parent, Attributes, Prop); - - Tmp := Prop.GetListStyleType; - if Tmp <> lbBlank then - FListStyleType := Tmp; - case Sy of - - UlSy, DirSy, MenuSy: - begin - FListType := Unordered; - if APlain or (Display = pdInline) then - FListStyleType := lbNone - else - if Tmp = lbBlank then - case AIndexType of // type="disc|circle|square" - 'd': FListStyleType := lbDisc; - 'c': FListStyleType := lbCircle; - 's': FListStyleType := lbSquare; - else - case ListLevel mod 3 of - 1: FListStyleType := lbDisc; - 2: FListStyleType := lbCircle; - 0: FListStyleType := lbSquare; - end; - end; - end; - - OLSy: - begin - FListType := Ordered; - if Tmp = lbBlank then - case AIndexType of - 'a': FListStyleType := lbLowerAlpha; - 'A': FListStyleType := lbUpperAlpha; - 'i': FListStyleType := lbLowerRoman; - 'I': FListStyleType := lbUpperRoman; - else - FListStyleType := lbDecimal; - end; - end; - - DLSy: - FListType := Definition; - else - FListType := liAlone; - if Tmp = lbBlank then - FListStyleType := lbDisc; - if (VarType(MargArrayO[MarginLeft]) in varInt) and - ((MargArrayO[MarginLeft] = IntNull) or (MargArrayO[MarginLeft] = 0)) then - MargArrayO[MarginLeft] := 16; - end; - - if (VarType(MargArrayO[MarginLeft]) in varInt) and (MargArrayO[MarginLeft] = IntNull) then - case Sy of - - OLSy, ULSy, DirSy, MenuSy, DLSy: - MargArrayO[MarginLeft] := 0; - - else - MargArrayO[MarginLeft] := ListIndent; - end; - - FListNumb := AListNumb; - FListFont := ThtFont.Create; - FListFont.Assign(Prop.Font); - - S := Prop.GetListStyleImage; - if S <> '' then - Image := TImageObj.SimpleCreate(MyCell, S); -end; - -constructor TBlockLI.CreateCopy(OwnerCell: TCellBasic; Source: THtmlNode); -var - T: TBlockLI absolute Source; -begin - inherited CreateCopy(OwnerCell,Source); - FListType := T.FListType; - FListNumb := T.FListNumb; - FListStyleType := T.FListStyleType; - if Assigned(T.Image) then - Image := TImageObj.CreateCopy(MyCell, T.Image); - FListFont := ThtFont.Create; - FListFont.Assign(T.ListFont); -end; - -destructor TBlockLI.Destroy; -begin - ListFont.Free; - Image.Free; - inherited Destroy; -end; - -function TBlockLI.DrawLogic1(Canvas: TCanvas; X, Y, XRef, YRef, AWidth, AHeight, BlHt: Integer; IMgr: TIndentManager; - var MaxWidth, Curs: Integer): Integer; -begin -{$IFDEF JPM_DEBUGGING_LOGIC} - CodeSite.EnterMethod(Self,'TBlockLI.DrawLogic1'); - CodeSite.SendFmtMsg('Self.TagClass = [%s]', [Self.TagClass] ); - - CodeSite.SendFmtMsg('X, XRef = [%4d, %4d]', [X, XRef]); - CodeSite.SendFmtMsg('Y, YRef = [%4d, %4d]', [Y, YRef]); - CodeSite.SendFmtMsg('AWidth = [%d]',[AWidth]); - CodeSite.SendFmtMsg('AHeight = [%d]',[AHeight]); - CodeSite.SendFmtMsg('BlHt = [%d]',[BlHt]); - if Assigned(IMgr) then begin - CodeSite.SendFmtMsg('IMgr.LfEdge = [%d]',[ IMgr.LfEdge ] ); - CodeSite.SendFmtMsg('IMgr.Width = [%d]',[ IMgr.Width ] ); - CodeSite.SendFmtMsg('IMgr.ClipWidth = [%d]',[ IMgr.ClipWidth ] ); - end else begin - CodeSite.SendMsg('IMgr = nil'); - end; - CodeSite.SendFmtMsg('MaxWidth = [%d]',[MaxWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.AddSeparator; -{$ENDIF} - if Assigned(Image) then - begin - Image.DrawLogicInline(Canvas, nil, 100, 0); - if Image.Image = ErrorImage then - FreeAndNil(Image); - end; - Document.FirstLineHtPtr := @FirstLineHt; - FirstLineHt := 0; - try - Result := inherited DrawLogic1(Canvas, X, Y, XRef, YRef, AWidth, AHeight, BlHt, IMgr, MaxWidth, Curs); - finally - Document.FirstLineHtPtr := nil; - end; -{$IFDEF JPM_DEBUGGING_LOGIC} - if Assigned(IMgr) then begin - CodeSite.SendFmtMsg('IMgr.LfEdge = [%d]',[ IMgr.LfEdge ] ); - CodeSite.SendFmtMsg('IMgr.Width = [%d]',[ IMgr.Width ] ); - CodeSite.SendFmtMsg('IMgr.ClipWidth = [%d]',[ IMgr.ClipWidth ] ); - end else begin - CodeSite.SendMsg('IMgr = nil'); - end; - CodeSite.SendFmtMsg('MaxWidth = [%d]',[MaxWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.SendFmtMsg('Result = [%d]',[Result]); - CodeSite.ExitMethod(Self,'TBlockLI.DrawLogic1'); -{$ENDIF} -end; - -//-- BG ---------------------------------------------------------- 31.01.2012 -- -procedure TBlockLI.SetListFont(const Value: TFont); -begin - FListFont.Assign(Value); -end; - -{----------------TBlockLI.Draw} - -function TBlockLI.Draw1(Canvas: TCanvas; const ARect: TRect; IMgr: TIndentManager; X, XRef, YRef: Integer): Integer; - -const - MaxNumb = 26; - LowerAlpha: string = 'abcdefghijklmnopqrstuvwxyz'; - HigherAlpha: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - LowerRoman: array[1..MaxNumb] of string = ('i', 'ii', 'iii', 'iv', 'v', 'vi', - 'vii', 'viii', 'ix', 'x', 'xi', 'xii', 'xiii', 'xiv', 'xv', 'xvi', 'xvii', - 'xviii', 'xix', 'xx', 'xxi', 'xxii', 'xxiii', 'xxiv', 'xxv', 'xxvi'); - HigherRoman: array[1..MaxNumb] of string = ('I', 'II', 'III', 'IV', 'V', 'VI', - 'VII', 'VIII', 'IX', 'X', 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', - 'XVIII', 'XIX', 'XX', 'XXI', 'XXII', 'XXIII', 'XXIV', 'XXV', 'XXVI'); -var - NStr: string; - BkMode, TAlign: Integer; - PenColor, BrushColor: TColor; - PenStyle: TPenStyle; - BrushStyle: TBrushStyle; - YB, AlphaNumb: Integer; - -begin - Result := inherited Draw1(Canvas, ARect, IMgr, X, XRef, YRef); - - X := X + Indent; - - if FirstLineHt > 0 then - begin - YB := FirstLineHt - Document.YOff; - if (YB < ARect.Top - 50) or (YB > ARect.Bottom + 50) then - Exit; - if Assigned(Image) and (Image.Image <> DefImage) and Document.ShowImages then - Image.DoDraw(Canvas, X - 16, YB - Image.ObjHeight, Image.Image) - else if not (ListType in [None, Definition]) then - begin - if ListStyleType in [lbDecimal, lbLowerAlpha, lbLowerRoman, lbUpperAlpha, lbUpperRoman] then - begin - AlphaNumb := Min(ListNumb, MaxNumb); - case ListStyleType of - lbLowerAlpha: NStr := LowerAlpha[AlphaNumb]; - lbUpperAlpha: NStr := HigherAlpha[AlphaNumb]; - lbLowerRoman: NStr := LowerRoman[AlphaNumb]; - lbUpperRoman: NStr := HigherRoman[AlphaNumb]; - else - NStr := IntToStr(ListNumb); - end; - Canvas.Font := ListFont; - Canvas.Font.Color := ThemedColor(ListFont.Color{$ifdef has_StyleElements},seFont in Document.StyleElements{$endif}); - NStr := NStr + '.'; - BkMode := SetBkMode(Canvas.Handle, Transparent); - TAlign := SetTextAlign(Canvas.Handle, TA_BASELINE); - Canvas.TextOut(X - 10 - Canvas.TextWidth(NStr), YB, NStr); - SetTextAlign(Canvas.Handle, TAlign); - SetBkMode(Canvas.Handle, BkMode); - end - else if (ListStyleType in [lbCircle, lbDisc, lbSquare]) then - with Canvas do - begin - PenColor := Pen.Color; - PenStyle := Pen.Style; - Pen.Color := ThemedColor(ListFont.Color{$ifdef has_StyleElements},seFont in Document.StyleElements{$endif}); - Pen.Style := psSolid; - BrushStyle := Brush.Style; - BrushColor := Brush.Color; - Brush.Style := bsSolid; - Brush.Color := ThemedColor(ListFont.Color{$ifdef has_StyleElements},seFont in Document.StyleElements{$endif}); - case ListStyleType of - lbCircle: - begin - Brush.Style := bsClear; - Circle(Canvas,X - 16, YB, 7); - end; - lbDisc: - Circle(Canvas,X - 15, YB - 1, 5); - lbSquare: Rectangle(X - 15, YB - 6, X - 10, YB - 1); - end; - Brush.Color := BrushColor; - Brush.Style := BrushStyle; - Pen.Color := PenColor; - Pen.Style := PenStyle; - end; - end; - end; -end; - -{----------------TBodyBlock.Create} - -constructor TBodyBlock.Create(Parent: TCellBasic; Attributes: TAttributeList; Prop: TProperties); -var - PRec: PtPositionRec; - Image: ThtString; - Val: TColor; -begin - {$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'TBodyBlock.Create'); - {$IFDEF JPM_DEBUGGING_STYLES} - StyleUn.LogProperties(Prop,'Prop'); - CodeSite.AddSeparator; - {$ENDIF} - {$ENDIF} - inherited Create(Parent,Attributes,Prop); - FPositioning := PosStatic; {7.28} - Prop.GetBackgroundPos(0, 0, PRec); - if Prop.GetBackgroundImage(Image) and (Image <> '') then - Document.SetBackgroundImage(Image, PRec); - Val := Prop.GetBackgroundColor; - if Val <> clNone then - Document.SetBackGround(Val or PalRelative); - {$IFDEF JPM_DEBUGGING} - CodeSite.ExitMethod(Self,'TBodyBlock.Create'); - {$ENDIF} -end; - -{----------------TBodyBlock.GetURL} - -function TBodyBlock.GetURL(Canvas: TCanvas; X, Y: Integer; - out UrlTarg: TUrlTarget; out FormControl: TIDObject {TImageFormControlObj}; - out ATitle: ThtString): ThtguResultType; -begin - Result := MyCell.GetURL(Canvas, X, Y, UrlTarg, FormControl, ATitle); - if not (guTitle in Result) and (BlockTitle <> '') then - begin - ATitle := BlockTitle; - Include(Result, guTitle); - end; -end; - -{----------------TBodyBlock.DrawLogic} - -function TBodyBlock.DrawLogic1(Canvas: TCanvas; X, Y, XRef, YRef, AWidth, AHeight, BlHt: Integer; IMgr: TIndentManager; - var MaxWidth, Curs: Integer): Integer; -var - ScrollWidth: Integer; - Lindex, RIndex, AutoCount: Integer; - SaveID: TObject; - ClientContentBot: Integer; -begin - {$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'TBodyBlock.DrawLogic1'); - CodeSite.SendFmtMsg('Self.TagClass = [%s]', [Self.TagClass] ); - CodeSite.SendFmtMsg('X, XRef = [%4d, %4d]', [X, XRef]); - CodeSite.SendFmtMsg('Y, YRef = [%4d, %4d]', [Y, YRef]); - CodeSite.SendFmtMsg('AWidth = [%d]',[AWidth]); - CodeSite.SendFmtMsg('AHeight = [%d]',[AHeight]); - CodeSite.SendFmtMsg('BlHt = [%d]',[BlHt]); - if Assigned(IMgr) then begin - CodeSite.SendFmtMsg('IMgr.LfEdge = [%d]',[ IMgr.LfEdge ] ); - CodeSite.SendFmtMsg('IMgr.Width = [%d]',[ IMgr.Width ] ); - CodeSite.SendFmtMsg('IMgr.ClipWidth = [%d]',[ IMgr.ClipWidth ] ); - end else begin - CodeSite.SendMsg('IMgr = nil'); - end; - CodeSite.SendFmtMsg('MaxWidth = [%d]',[MaxWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.AddSeparator; - {$ENDIF} - YDraw := Y; - StartCurs := Curs; - StyleUn.ConvMargArray(MargArrayO, AWidth, AHeight, EmSize, ExSize, BorderWidth, AutoCount, MargArray); - if IsAuto(MargArray[MarginLeft]) then MargArray[MarginLeft] := 0; - if IsAuto(MargArray[MarginRight]) then MargArray[MarginRight] := 0; - ApplyBoxSettings(MargArray,Document.UseQuirksMode); - - X := MargArray[MarginLeft] + MargArray[PaddingLeft] + MargArray[BorderLeftWidth]; - ContentWidth := IMgr.Width - (X + MargArray[MarginRight] + MargArray[PaddingRight] + MargArray[BorderRightWidth]); - - DrawTop := MargArray[MarginTop]; - - MyCell.IMgr := IMgr; - - SaveID := IMgr.CurrentID; - Imgr.CurrentID := Self; - LIndex := IMgr.SetLeftIndent(X, Y); - RIndex := IMgr.SetRightIndent(X + ContentWidth, Y); - - ContentTop := Y + MargArray[MarginTop] + MargArray[PaddingTop] + MargArray[BorderTopWidth]; - MyCell.DoLogicX(Canvas, X, ContentTop, 0, 0, ContentWidth, - AHeight - MargArray[MarginTop] - MargArray[MarginBottom], BlHt, ScrollWidth, Curs); - - Len := Curs - StartCurs; - - ClientContentBot := Max(ContentTop, MyCell.tcContentBot); - ContentBot := ClientContentBot + MargArray[PaddingBottom] + MargArray[BorderBottomWidth] + MargArray[MarginBottom]; - DrawBot := Max(ClientContentBot, MyCell.tcDrawBot) + MargArray[PaddingBottom] + MargArray[BorderBottomWidth]; - - MyCell.tcDrawTop := 0; - MyCell.tcContentBot := 999000; - - Result := DrawBot + MargArray[MarginBottom] - Y; - SectionHeight := Result; - IMgr.FreeLeftIndentRec(LIndex); - IMgr.FreeRightIndentRec(RIndex); - DrawHeight := IMgr.ImageBottom - Y; {in case image overhangs} - Imgr.CurrentID := SaveID; - if DrawHeight < SectionHeight then - DrawHeight := SectionHeight; - MaxWidth := Max(IMgr.Width, Max(ScrollWidth, ContentWidth) + MargArray[MarginLeft] + MargArray[MarginRight]); - if DrawList.Count = 0 then - DrawSort; - {$IFDEF JPM_DEBUGGING} - if Assigned(IMgr) then begin - CodeSite.SendFmtMsg('IMgr.LfEdge = [%d]',[ IMgr.LfEdge ] ); - CodeSite.SendFmtMsg('IMgr.Width = [%d]',[ IMgr.Width ] ); - CodeSite.SendFmtMsg('IMgr.ClipWidth = [%d]',[ IMgr.ClipWidth ] ); - end else begin - CodeSite.SendMsg('IMgr = nil'); - end; - CodeSite.SendFmtMsg('MaxWidth = [%d]',[MaxWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.SendFmtMsg('Result = [%d]',[Result]); - CodeSite.ExitMethod(Self,'TBodyBlock.DrawLogic1'); - {$ENDIF} -end; - -{----------------TBodyBlock.Draw} - -function TBodyBlock.Draw1(Canvas: TCanvas; const ARect: TRect; IMgr: TIndentManager; X, XRef, YRef: Integer): Integer; -var - SaveID: TObject; - Y: Integer; -begin - Y := YDraw; - Result := Y + SectionHeight; - - X := IMgr.LfEdge + MargArray[MarginLeft] + MargArray[BorderLeftWidth] + MargArray[PaddingLeft]; - SaveID := IMgr.CurrentID; - Imgr.CurrentID := Self; - DrawTheList(Canvas, ARect, ContentWidth, X, IMgr.LfEdge, 0); - Imgr.CurrentID := SaveID; - - //>-- DZ - DrawRect.Top := Y; - DrawRect.Left := X; - DrawRect.Right := DrawRect.Left + ContentWidth; - DrawRect.Bottom := DrawRect.Top + DrawHeight; -end; - -{ ThtDocument } - -//-- BG ---------------------------------------------------------- 04.03.2011 -- -// moving from TIDObjectList to ThtDocument removed field OwnerList from TIDObjectList -function ThtDocument.AddChPosObjectToIDNameList(const S: ThtString; Pos: Integer): Integer; -begin - Result := IDNameList.AddObject(S, TChPosObj.Create(Self, Pos)); -end; - -constructor ThtDocument.Create(Owner: THtmlViewerBase; APaintPanel: TWinControl); -begin - FDocument := Self; - inherited Create(nil); - {$ifdef has_StyleElements} - FStyleElements := Owner.StyleElements; - {$Endif} - FPropStack := THtmlPropStack.Create; - TheOwner := Owner; - PPanel := APaintPanel; - IDNameList := TIDObjectList.Create; //(Self); - HtmlFormList := THtmlFormList.Create; - AniList := ThtImageList.Create(False); - MapList := ThtMap.Create; - FormControlList := TFormControlObjList.Create(False); - MissingImages := ThtStringList.Create; - MissingImages.Sorted := False; - LinkList := TLinkList.Create; - PanelList := TPanelObjList.Create(False); - Styles := THtmlStyleList.Create(Self); - DrawList := TDrawList.Create; - PositionList := TSectionBaseList.Create(False); - TabOrderList := TStringList.Create; - TabOrderList.Sorted := True; - TabOrderList.Duplicates := dupAccept; - InLineList := TInlineList.Create(Self); - ScaleX := 1.0; - ScaleY := 1.0; -end; - -//------------------------------------------------------------------------------ -constructor ThtDocument.CreateCopy(T: ThtDocument); -begin - PrintTableBackground := T.PrintTableBackground; - PrintBackground := T.PrintBackground; - ImageCache := T.ImageCache; {same list} - InlineList := T.InlineList; {same list} - IsCopy := True; - System.Move(T.ShowImages, ShowImages, PtrSub(@Background, @ShowImages) + Sizeof(Integer)); - PreFontName := T.PreFontName; - HtmlFormList := THtmlFormList.Create; {no copy of list made} - AniList := ThtImageList.Create(False); - MapList := ThtMap.Create; - MissingImages := ThtStringList.Create; - PanelList := TPanelObjList.Create(False); - DrawList := TDrawList.Create; - FDocument := Self; - inherited CreateCopy(nil, T); - ScaleX := 1.0; - ScaleY := 1.0; - - UseQuirksMode := T.UseQuirksMode; - {$ifdef has_StyleElements} - StyleElements := T.StyleElements; - {$Endif} -end; - -destructor ThtDocument.Destroy; -begin - inherited Destroy; // Yunqa.de: Destroy calls Clear, so do this first. - IDNameList.Free; - HtmlFormList.Free; - MapList.Free; - AniList.Free; - Timer.Free; - FormControlList.Free; - MissingImages.Free; - LinkList.Free; - PanelList.Free; - Styles.Free; - DrawList.Free; - PositionList.Free; - TabOrderList.Free; - if not IsCopy then - InlineList.Free; - FPropStack.Free; -end; - -{$ifdef has_StyleElements} -procedure ThtDocument.SetStyleElements(const AValue : TStyleElements); -begin - if AValue <> FStyleElements then - begin - FStyleElements := AValue; - Self.UpdateStyleElements; - end; -end; - -procedure ThtDocument.UpdateStyleElements; -var - i: Integer; -begin - if FormControlList <> nil then - for i := 0 to FormControlList.Count - 1 do - FormControlList[i].TheControl.StyleElements := FStyleElements; -end; -{$endif} - -function ThtDocument.GetURL(Canvas: TCanvas; X, Y: Integer; - out UrlTarg: TUrlTarget; out FormControl: TIDObject {TImageFormControlObj}; - out ATitle: ThtString): ThtguResultType; -var - OldLink: TFontObj; - OldImage: TImageObj; -begin - OldLink := ActiveLink; - OldImage := ActiveImage; - ActiveLink := nil; - ActiveImage := nil; - Result := inherited GetUrl(Canvas, X, Y, UrlTarg, FormControl, ATitle); - if LinksActive and (ActiveLink <> OldLink) then - begin - if OldLink <> nil then - OldLink.SetAllHovers(LinkList, False); - if ActiveLink <> nil then - ActiveLink.SetAllHovers(LinkList, True); - PPanel.Invalidate; - end; - if (ActiveImage <> OldImage) then - begin - if OldImage <> nil then - OldImage.Hover := hvOff; - end; - if ActiveImage <> nil then - if Word(GetKeyState(VK_LBUTTON)) and $8000 <> 0 then - ActiveImage.Hover := hvOverDown - else - ActiveImage.Hover := hvOverUp; -end; - -//-- BG ---------------------------------------------------------- 14.02.2016 -- -function ThtDocument.GetViewPort: TRect; -begin - if Printing then - Result := FPageArea - else - Result := PPanel.ClientRect; -end; - -procedure ThtDocument.LButtonDown(Down: Boolean); -{called from htmlview.pas when left mouse button depressed} -begin - if ActiveImage <> nil then - begin - if Down then - ActiveImage.Hover := hvOverDown - else - ActiveImage.Hover := hvOverUp; - PPanel.Invalidate; - end; -end; - -procedure ThtDocument.CancelActives; -begin - if Assigned(ActiveLink) or Assigned(ActiveImage) then - PPanel.Invalidate; - if Assigned(ActiveLink) then - begin - ActiveLink.SetAllHovers(LinkList, False); - ActiveLink := nil; - end; - if Assigned(ActiveImage) then - begin - ActiveImage.Hover := hvOff; - ActiveImage := nil; - end; -end; - -procedure ThtDocument.CheckGIFList(Sender: TObject); -var - IsAniGifBackground: Boolean; - I: Integer; - Frame: Integer; - Image: ThtImage; -begin - if IsCopy then - Exit; - Frame := 0; - IsAniGifBackground := BackgroundImage is ThtGifImage; - if IsAniGifBackground then - begin - IsAniGifBackground := ThtGifImage(BackgroundImage).Gif.Animate; - if IsAniGifBackground then - Frame := ThtGifImage(BackgroundImage).Gif.CurrentFrame; - end; - - for I := 0 to AniList.Count - 1 do - begin - Image := AniList[I]; - if Image is ThtGifImage then - with ThtGifImage(Image).Gif do - if ShowIt then - CheckTime(PPanel); - end; - - if IsAniGifBackground then - if Frame <> ThtGifImage(BackgroundImage).Gif.CurrentFrame then - PPanel.Invalidate; - Timer.Interval := 40; -end; - -procedure ThtDocument.HideControls; -var - I, J: Integer; -begin - {After next Draw, hide all formcontrols that aren't to be shown} - for I := 0 to HtmlFormList.Count - 1 do - with HtmlFormList[I] do - for J := 0 to ControlList.Count - 1 do - ControlList[J].ShowIt := False; - for I := 0 to PanelList.Count - 1 do - PanelList[I].ShowIt := False; {same for panels} -end; - -procedure ThtDocument.SetYOffset(Y: Integer); -begin - YOff := Y; - YOffChange := True; - HideControls; -end; - -procedure ThtDocument.Clear; -begin - if not IsCopy then - begin - IDNameList.Clear; - PositionList.Clear; - TInlineList(InlineList).Clear; - end; - BackgroundImage := nil; - if BackgroundImageLoaded and (BackgroundImageName <> '') then - ImageCache.DecUsage(BackgroundImageName); - BackgroundImageName := ''; - BackgroundImageLoaded := False; - AniList.Clear; - FreeAndNil(Timer); - SelB := 0; - SelE := 0; - MapList.Clear; - MissingImages.Clear; - if Assigned(LinkList) then - LinkList.Clear; - ActiveLink := nil; - ActiveImage := nil; - PanelList.Clear; - if not IsCopy then begin - Styles.Clear; - Styles.UseQuirksMode := Self.UseQuirksMode; - end; - if Assigned(TabOrderList) then - TabOrderList.Clear; - inherited Clear; - HtmlFormList.Clear; - if Assigned(FormControlList) then - FormControlList.Clear; -end; - -procedure ThtDocument.ClearLists; -{called from DoBody to clear some things when starting over} -begin - PanelList.Clear; - if Assigned(FormControlList) then - FormControlList.Clear; -end; - -//-- BG ---------------------------------------------------------- 03.06.2012 -- -// extracted from CopyToClipboardAsText(), GetSelLength() and GetSelTextBuf(). -function ThtDocument.CopyToBuffer(Buffer: TSelTextCount): Integer; -var - I: Integer; -begin - CB := Buffer; - try - for I := 0 to Count - 1 do - begin - with Items[I] do - begin - if SelB >= StartCurs + Len then - Continue; - if SelE <= StartCurs then - Break; - CopySelectedText; - end; - end; - Result := CB.Terminate; - finally - FreeAndNil(CB); - end; -end; - -function ThtDocument.GetSelLength: Integer; -begin - if SelE > SelB then - Result := CopyToBuffer(TSelTextCount.Create) - else - Result := 0; {nothing to do} -end; - -//------------------------------------------------------------------------------ -function ThtDocument.GetSelTextBuf(Buffer: PWideChar; BufSize: Integer): Integer; -begin - if SelE > SelB then - Result := CopyToBuffer(TSelTextBuf.Create(Buffer, BufSize)) - else - begin - if BufSize >= 1 then - begin - Buffer[0] := #0; - Result := 1; - end - else - Result := 0; - end; -end; - -//------------------------------------------------------------------------------ -function ThtDocument.DoLogic(Canvas: TCanvas; Y: Integer; Width, AHeight, BlHt: Integer; - var ScrollWidth, Curs: Integer): Integer; -var - I, J: Integer; - Image: ThtImage; - Obj: TObject; -begin - {$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'ThtDocument.DoLogic'); - {$ENDIF} - Inc(CycleNumber); - TableNestLevel := 0; - InLogic2 := False; - if Assigned(Timer) then - Timer.Enabled := False; - for I := 0 to HtmlFormList.Count - 1 do - HtmlFormList[I].SetSizes(Canvas); - SetTextJustification(Canvas.Handle, 0, 0); - TInlineList(InlineList).NeedsConverting := True; - -{set up the tab order for form controls according to the TabIndex attributes} - if Assigned(TabOrderList) and (TabOrderList.Count > 0) then - begin - J := 0; {tab order starts with 0} - for I := 0 to TabOrderList.Count - 1 do {list is sorted into proper order} - begin - Obj := TabOrderList.Objects[I]; - if Obj is TFormControlObj then - begin - TFormControlObj(Obj).TabOrder := J; - Inc(J); - end - else if Obj is ThtTabControl then - begin - ThtTabControl(Obj).TabOrder := J; - Inc(J); - end - else - Assert(False, 'Unexpected item in TabOrderList'); - end; - TabOrderList.Clear; {only need do this once} - end; - - Result := inherited DoLogic(Canvas, Y, Width, AHeight, BlHt, ScrollWidth, Curs); - - for I := 0 to AniList.Count - 1 do - begin - Image := AniList[I]; - if Image is ThtGifImage then - with ThtGifImage(Image).Gif do - begin - ShowIt := False; // when gif is drawn, it will set it to true again. Avoids animating invisible gifs. - Animate := False; {starts iteration count from 1} - if not Self.IsCopy then - Animate := True; - end; - end; - if not IsCopy and not Assigned(Timer) then - begin - Timer := TTimer.Create(TheOwner); - Timer.Interval := 50; - Timer.OnTimer := CheckGIFList; - end; - if Assigned(Timer) then - Timer.Enabled := AniList.Count >= 1; - AdjustFormControls; - if not IsCopy and (PositionList.Count = 0) then - begin - AddSectionsToList; - end; - {$IFDEF JPM_DEBUGGING} - CodeSite.ExitMethod(Self,'ThtDocument.DoLogic'); - {$ENDIF} -end; - -//-- BG ---------------------------------------------------------- 11.09.2010 -- -procedure ThtDocument.AddSectionsToPositionList(Sections: TSectionBase); -begin - inherited; - PositionList.Add(Sections); -end; - -procedure ThtDocument.AdjustFormControls; -var - Control: TControl; - Showing: Boolean; - -{$IFNDEF FastRadio} - function ActiveInList: Boolean; {see if active control is a form control} - var - Control: TWinControl; - I: Integer; - begin - Result := False; - Control := Screen.ActiveControl; - for I := 0 to FormControlList.Count - 1 do - if FormControlList.Items[I].TheControl = Control then - begin - Result := True; - Break; - end; - end; -{$ENDIF} - -begin - if IsCopy or (FormControlList.Count = 0) then - Exit; - with FormControlList do -{$IFNDEF FastRadio} - if not ActiveInList then - DeactivateTabbing - else -{$ENDIF} - begin - Control := TheOwner; {THtmlViewer} - repeat - Showing := Control.Visible; - Control := Control.Parent; - until not Showing or not Assigned(Control); - if Showing then - ActivateTabbing; - end; -end; - -//------------------------------------------------------------------------------ -function ThtDocument.Draw(Canvas: TCanvas; ARect: TRect; ClipWidth, X: Integer; - Y, XRef, YRef: Integer): Integer; -var - OldPal: HPalette; - I: Integer; -begin - PageBottom := ARect.Bottom + YOff; - PageShortened := False; - FirstPageItem := True; - TableNestLevel := 0; - SkipDraw := False; - - if Assigned(Timer) then - Timer.Enabled := False; - if (BackgroundImage is ThtGifImage) and not IsCopy then - ThtGifImage(BackgroundImage).Gif.ShowIt := True; - if (ColorBits <= 8) then - begin - OldPal := SelectPalette(Canvas.Handle, ThePalette, True); - RealizePalette(Canvas.Handle); - end - else - OldPal := 0; - DrawList.Clear; - try - Result := inherited Draw(Canvas, ARect, ClipWidth, X, Y, XRef, YRef); - DrawList.DrawImages; - DrawList.Clear; - finally - if OldPal <> 0 then - SelectPalette(Canvas.Handle, OldPal, True); - end; - if YOffChange then - begin - AdjustFormControls; - {Hide all TPanelObj's that aren't displayed} - for I := 0 to PanelList.Count - 1 do - with PanelList[I] do - if not ShowIt then - Panel.Hide; - end; - if YOffChange or XOffChange then - begin -{$ifdef LCL} - PPanel.Invalidate; -{$endif} - XOffChange := False; - YOffChange := False; - end; - if Assigned(Timer) then - Timer.Enabled := AniList.Count >= 1; -end; - -procedure ThtDocument.SetFonts(const Name, PreName: ThtString; ASize: Integer; - AColor, AHotSpot, AVisitedColor, AActiveColor, ABackground: TColor; LnksActive, LinkUnderLine: Boolean; - ACodePage: TBuffCodePage; ACharSet: TFontCharSet; MarginHeight, MarginWidth: Integer); -begin - Styles.Initialize(Name, PreName, ASize, AColor, AHotspot, AVisitedColor, - AActiveColor, LinkUnderLine, ACodePage, ACharSet, MarginHeight, MarginWidth); - InitializeFontSizes(ASize); - PreFontName := PreName; - HotSpotColor := AHotSpot; - LinkVisitedColor := AVisitedColor; - LinkActiveColor := AActiveColor; - LinksActive := LnksActive; - SetBackground(ABackground); -end; - -procedure ThtDocument.SetBackground(ABackground: TColor); -begin - Background := ABackground; - if Assigned(OnBackGroundChange) then - OnBackgroundChange(Self); -end; - -procedure ThtDocument.SetBackgroundImage(const Name: ThtString; const APrec: PtPositionRec); -begin - BackgroundImage := nil; - BackgroundImageName := Name; - BackgroundImageLoaded := False; - BackgroundImagePosition := APrec; -end; - -//------------------------------------------------------------------------------ -procedure ThtDocument.InsertMissingImage(const UName: ThtString; J: Integer; Error: Boolean; out Reformat: Boolean); -var - Rformat: Boolean; - Obj: TObject; -begin - Reformat := False; - while J >= 0 do - begin - Obj := MissingImages.Objects[J]; - if Obj = Self then - begin - if not IsCopy and not Error then - begin - BackgroundImageLoaded := False; {the background image, set to load} - GetBackgroundImage(); - end; - end - else if Obj is TImageObj then - begin - TImageObj(Obj).InsertImage(UName, Error, Rformat); - Reformat := Reformat or Rformat; - end; - MissingImages.Delete(J); - J := MissingImages.IndexOf(UName); - end; -end; - -//------------------------------------------------------------------------------ -procedure ThtDocument.InsertImage(const Src: ThtString; Stream: TStream; out Reformat: Boolean); -var - UName: ThtString; - I, J: Integer; - Image: ThtImage; - Error: Boolean; - Obj: TObject; - Transparent: ThtImageTransparency; -begin - Image := nil; - Error := False; - Reformat := False; - UName := htTrim(Src); - I := ImageCache.IndexOf(UName); {first see if the bitmap is already loaded} - J := MissingImages.IndexOf(UName); {see if it's in missing image list} - if (I = -1) and (J >= 0) then - begin - Transparent := itrNone; - Obj := MissingImages.Objects[J]; - if (Obj is TImageObj) then - begin - Transparent := TImageObj(Obj).Transparent; - end; - Image := LoadImageFromStream(Stream, Transparent); - if Image <> nil then {put in Cache} - begin - ImageCache.AddObject(UName, Image); {put new bitmap in list} - ImageCache.DecUsage(UName); {this does not count as being used yet} - end - else - Error := True; {bad stream or Nil} - end; - - if (I >= 0) or (Image <> nil) or Error then {a valid image in the Cache or Bad stream} - InsertMissingImage(UName, J, Error, Reformat); -end; - -//-- BG ---------------------------------------------------------- 10.01.2015 -- -procedure ThtDocument.InsertImage(const Src: ThtString; Bitmap: TBitmap; Color: TColor; Transparent: ThtImageTransparency; OwnsBitmap: Boolean; out Reformat: Boolean); -var - UName: ThtString; - I, J: Integer; - Image: ThtImage; - Error: Boolean; -begin - Image := nil; - Error := False; - Reformat := False; - UName := htUpperCase(htTrim(Src)); - I := ImageCache.IndexOf(UName); {first see if the bitmap is already loaded} - J := MissingImages.IndexOf(UName); {see if it's in missing image list} - if (I = -1) and (J >= 0) then - begin - if Bitmap <> nil then - begin - if Color <> -1 then - Transparent := itrIntrinsic; - Image := ThtBitmapImage.Create(Bitmap, Transparent, Color, OwnsBitmap); - end; - - if Image <> nil then {put in Cache} - begin - ImageCache.AddObject(UName, Image); {put new bitmap in list} - ImageCache.DecUsage(UName); {this does not count as being used yet} - end - else - Error := True; {bad stream or Nil} - end; - - if (I >= 0) or Assigned(Image) or Error then {a valid image in the Cache or Bad stream} - InsertMissingImage(UName, J, Error, Reformat); -end; - -//------------------------------------------------------------------------------ -function ThtDocument.GetTheImage(const BMName: ThtString; var Transparent: ThtImageTransparency; out FromCache, Delay: Boolean): ThtImage; -{Transparent may be set to itrNone or itrLLCorner on entry but may discover it's itrIntrinsic here} - - procedure GetTheBitmap; - {Note: bitmaps gotten by OnBitmapRequest are on "loan". We do not destroy them} - var - Color: TColor; - Bitmap: TBitmap; - begin - if Assigned(GetBitmap) then - begin {the OnBitmapRequest event} - Bitmap := nil; - Color := -1; - GetBitmap(TheOwner, BMName, Bitmap, Color); - if Bitmap = WaitBitmap then - Delay := True - else if Bitmap = ErrorBitmap then - Result := nil - else if Bitmap <> nil then - begin - if Color <> -1 then - Transparent := itrIntrinsic; - try - Result := ThtBitmapImage.Create(Bitmap, Transparent, Color, False); - finally - if Assigned(GottenBitmap) then - GottenBitmap(TheOwner, BMName, Bitmap, Color); - end; - end; - end; - end; - - procedure GetTheStream; - {Note: streams gotten by OnImageRequest are on "loan". We do not destroy them} - var - Stream: TStream; - begin - if Assigned(GetImage) then - begin {the OnImageRequest} - Stream := nil; - GetImage(TheOwner, BMName, Stream); - if Stream = WaitStream then - Delay := True - else if Stream = ErrorStream then - Result := nil - else if Stream <> nil then - begin - try - Result := LoadImageFromStream(Stream, Transparent); - finally - if Assigned(GottenImage) then - GottenImage(TheOwner, BMName, Stream); - end; - end; - end; - end; - - procedure GetTheBase64(Name: ThtString); - var - I: Integer; - Source: TStream; - Stream: TStream; - begin - I := Pos(';base64,', Name); - if I >= 11 then - begin - // Firefox 11 saves multiline inline images by writing %0A for the linefeeds. - // BTW: Internet Explorer 9 shows but does not save inline images at all. - // Using StringReplace() here is a quick and dirty hack. - // Better decode %encoded attribute values while reading the attributes. - Name := StringReplace(Name, '%0A', #$0A, [rfReplaceAll]); - Source := TStringStream.Create(Copy(Name, I + 8, MaxInt)); - try - Stream := TMemoryStream.Create; - try - {$IFDEF Compiler28_Plus} - TNetEncoding.Base64.Decode(Source, Stream); - {$ELSE} - DecodeStream(Source, Stream); - {$ENDIF} - Result := LoadImageFromStream(Stream, Transparent); - finally - Stream.Free; - end; - finally - Source.Free; - end; - end; - end; - - procedure GetTheFile(Name: ThtString); - var - Stream: TStream; - begin - Name := TheOwner.HtmlExpandFilename(Name); - if FileExists(Name) then - begin - Stream := TFileStream.Create(Name, fmOpenRead or fmShareDenyWrite); - try - Result := LoadImageFromStream(Stream, Transparent); - finally - Stream.Free; - end; - end; - end; - -var - UName, Name: ThtString; - I: Integer; -begin - Result := nil; - Delay := False; - FromCache := False; - if BMName <> '' then - begin - Name := htTrim(BMName); - //UName := htUpperCase(Name); - UName := Name; - I := ImageCache.IndexOf(UName); {first see if the bitmap is already loaded} - if I >= 0 then - begin {yes, handle the case where the image is already loaded} - Result := ImageCache.GetImage(I); - FromCache := True; - end - else - begin - {The image is not loaded yet, need to get it} - if Copy(Name, 1, 11) = 'data:image/' then - GetTheBase64(Name) - else - begin - GetTheBitmap; - if (Result = nil) and not Delay then - GetTheStream; - if (Result = nil) and not Delay then - GetTheFile(BMName); - end; - - if Result <> nil then {put in Image List for use later also} - ImageCache.AddObject(UName, Result); {put new image in list} - end; - end; -end; - -//------------------------------------------------------------------------------ -function ThtDocument.FindSectionAtPosition(Pos: Integer; out TopPos, Index: Integer): TSectionBase; -var - I: Integer; -begin - for I := PositionList.Count - 1 downto 0 do - begin - Result := PositionList[I]; - if Result.YPosition <= Pos then - begin - TopPos := Result.YPosition; - Index := I; - Exit; - end; - end; - Result := nil; -end; - -procedure ThtDocument.GetBackgroundImage; -var - Dummy1: ThtImageTransparency; - FromCache, Delay: Boolean; - Rslt: ThtString; - I: Integer; - UName: ThtString; -begin - UName := htTrim(BackgroundImageName); - if ShowImages and (UName <> '') then - if BackgroundImage = nil then - begin - if BackgroundImageLoaded then - begin - I := ImageCache.IndexOf(UName); {first see if the bitmap is already loaded} - if I >= 0 then - BackgroundImage := ImageCache.GetImage(I); - end - else - begin - Dummy1 := itrNone; - if not Assigned(GetBitmap) and not Assigned(GetImage) then - BackgroundImageName := TheOwner.HtmlExpandFilename(BackgroundImageName) - else if Assigned(OnExpandName) then - begin - OnExpandName(TheOwner, BackgroundImageName, Rslt); - BackgroundImageName := Rslt; - end; - BackgroundImage := GetTheImage(BackgroundImageName, Dummy1, FromCache, Delay); {might be Nil} - if Delay then - MissingImages.AddObject(htTrim(BackgroundImageName), Self); - BackgroundImageLoaded := True; - end; - if (BackgroundImage <> nil) and not IsCopy then - if BackgroundImage.IsAnimated then - begin - AniList.Add(BackgroundImage); - BackgroundImage.Animate := True; - end; - end; -end; - -//------------------------------------------------------------------------------ -procedure ThtDocument.GetFormControlData(FormData: TFormData); -var - I: Integer; -begin - for I := 0 to HtmlFormList.Count - 1 do - FormData.Add(HtmlFormList[I].GetFormSubmission); -end; - -procedure ThtDocument.SetFormControlData(FormData: TFormData); -var - I: Integer; -begin - try - for I := 0 to Min(FormData.Count, HtmlFormList.Count) - 1 do - HtmlFormList[I].SetFormData(FormData[I]); - except - end; -end; - -//-- BG ---------------------------------------------------------- 14.02.2016 -- -procedure ThtDocument.SetPageArea(const Value: TRect); -begin - FPageArea := Value; -end; - -//------------------------------------------------------------------------------ -function ThtDocument.FindDocPos(SourcePos: Integer; Prev: Boolean): Integer; -begin - Result := inherited FindDocPos(SourcePos, Prev); - if Result < 0 then {if not found return 1 past last ThtChar} - Result := Len; -end; - -//------------------------------------------------------------------------------ -function ThtDocument.CursorToXY(Canvas: TCanvas; Cursor: Integer; var X, Y: Integer): Boolean; -var - Beyond: Boolean; -begin - Beyond := Cursor >= Len; - if Beyond then - Cursor := Len - 1; - Result := inherited CursorToXY(Canvas, Cursor, X, Y); - if Beyond then - X := X + 15; -end; - -procedure ThtDocument.ProcessInlines(SIndex: Integer; Prop: TProperties; Start: Boolean); -{called when an inline property is found to specify a border} -var - I, EmSize, ExSize: Integer; - Result: ThtInlineRec; - MargArrayO: ThtVMarginArray; - Dummy1: Integer; -begin - {$ifdef JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'ThtDocument.ProcessInlines'); - {$endif} - with TInlineList(InlineList) do - begin - if Start then - begin {this is for border start} - Result := ThtInlineRec.Create; - Add(Result); - with Result do - begin - StartBDoc := SIndex; {Source index for border start} - IDB := Prop.ID; {property ID} - EndB := 999999; {end isn't known yet} - Prop.GetVMarginArray(MargArrayO); - EmSize := Prop.EmSize; - ExSize := Prop.ExSize; - ConvMargArray(MargArrayO, 200, 200, EmSize, ExSize, 0{4}, Dummy1, MargArray); - end; - end - else {this call has end information} - for I := Count - 1 downto 0 do {the record we want is probably the last one} - begin - Result := Items[I]; - if Prop.ID = Result.IDB then {check the ID to make sure} - begin - Result.EndBDoc := SIndex; {the source position of the border end} - Break; - end; - end; - end; - {$ifdef JPM_DEBUGGING} - CodeSite.ExitMethod(Self,'ThtDocument.ProcessInlines'); - {$endif} -end; - -{----------------TInlineList.Create} - -constructor TInlineList.Create(AnOwner: ThtDocument); -begin - inherited Create; - Owner := AnOwner; - NeedsConverting := True; -end; - -procedure TInlineList.Clear; -begin - inherited Clear; - NeedsConverting := True; -end; - -procedure TInlineList.AdjustValues; -{convert all the list data from source ThtChar positions to display ThtChar positions} -var - I: Integer; -begin - for I := 0 to Count - 1 do - with Items[I] do - begin - StartB := Owner.FindDocPos(StartBDoc, False); - EndB := Owner.FindDocPos(EndBDoc, False); - if StartB = EndB then - Dec(StartB); {this takes care of images, form controls} - end; - NeedsConverting := False; -end; - -function TInlineList.GetStartB(I: Integer): Integer; -begin - if NeedsConverting then - AdjustValues; - if (I < Count) and (I >= 0) then - Result := Items[I].StartB - else - Result := 99999999; -end; - -//-- BG ---------------------------------------------------------- 06.10.2016 -- -function TInlineList.Get(Index: Integer): ThtInlineRec; -begin - Result := inherited Get(Index); -end; - -function TInlineList.GetEndB(I: Integer): Integer; -begin - if NeedsConverting then - AdjustValues; - if (I < Count) and (I >= 0) then - Result := Items[I].EndB - else - Result := 99999999; -end; - -{ TCellObjBase } - -//-- BG ---------------------------------------------------------- 19.02.2013 -- -procedure TCellObjBase.AssignTo(Destin: TCellObjBase); -begin - Move(FColSpan, Destin.FColSpan, PtrSub(@FSpecHt, @FColSpan) + sizeof(FSpecHt) ); -end; - -{ TDummyCellObj } - -//-- BG ---------------------------------------------------------- 19.02.2013 -- -function TDummyCellObj.Clone(Parent: TBlock): TCellObjBase; -begin - Result := TDummyCellObj.Create(RowSpan); - AssignTo(Result); -end; - -//-- BG ---------------------------------------------------------- 19.02.2013 -- -constructor TDummyCellObj.Create(RSpan: Integer); -begin - inherited Create; - FColSpan := 0; - FRowSpan := RSpan; -end; - -//-- BG ---------------------------------------------------------- 19.02.2013 -- -procedure TDummyCellObj.Draw(Canvas: TCanvas; const ARect: TRect; X, Y, CellSpacingHorz, CellSpacingVert: Integer; Border: Boolean; Light, - Dark: TColor); -begin - //abstract: inherited Draw(Canvas,ARect,X,Y,CellSpacing,Border,Light,Dark); -end; - -//-- BG ---------------------------------------------------------- 19.02.2013 -- -procedure TDummyCellObj.DrawLogic2(Canvas: TCanvas; Y, CellSpacingHorz,CellSpacingVert: Integer; var Curs: Integer); -begin - //abstract: inherited DrawLogic2(Canvas,Y,CellSpacing,Curs); -end; - -//-- BG ---------------------------------------------------------- 19.02.2013 -- -function TDummyCellObj.GetCell: TCellObjCell; -begin - Result := nil; -end; - -{ TCellObj } - -//-- BG ---------------------------------------------------------- 19.02.2013 -- -procedure TCellObj.AssignTo(Destin: TCellObjBase); -var - CellObj: TCellObj absolute Destin; -begin - inherited AssignTo(Destin); - if Destin is TCellObj then - begin - Move(FWd, CellObj.FWd, PtrSub(@FCell, @FWd)); - - if CellObj.Cell.Document.PrintTableBackground then - begin - CellObj.Cell.BkGnd := Cell.BkGnd; - CellObj.Cell.BkColor := Cell.BkColor; - if Assigned(BGImage) then - // TODO: BG, 26.08.2013: is this correct? - CellObj.BGImage := TImageObj.CreateCopy(CellObj.Cell, BGImage); - end - else - CellObj.Cell.BkGnd := False; - CellObj.MargArrayO := MargArrayO; - CellObj.MargArray := MargArray; - end; -end; - -//-- BG ---------------------------------------------------------- 19.02.2013 -- -function TCellObj.Clone(Parent: TBlock): TCellObjBase; -begin - Result := TCellObj.CreateCopy(Parent, Self); -end; - -constructor TCellObj.Create(Parent: TTableBlock; AVAlign: ThtAlignmentStyle; Attr: TAttributeList; Prop: TProperties); -{Note: on entry Attr and Prop may be Nil when dummy cells are being created} -var - I, AutoCount: Integer; - Color: TColor; - BackgroundImage: ThtString; - Algn: ThtAlignmentStyle; -begin - {$ifdef JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'TCellObj.Create'); - {$endif} - inherited Create; - FCell := TCellObjCell.Create(Parent); - if Assigned(Prop) then - Cell.Title := Prop.PropTitle; - ColSpan := 1; - RowSpan := 1; - VAlign := AVAlign; - if Assigned(Attr) then - for I := 0 to Attr.Count - 1 do - with Attr[I] do - case Which of - ColSpanSy: - if Value > 1 then - ColSpan := Value; - - RowSpanSy: - if Value > 1 then - RowSpan := Value; - - WidthSy: - if Value >= 0 then - FSpecWd := ToSpecWidth(Value, Name); - - HeightSy: - if Value >= 0 then - FSpecHt := ToSpecWidth(Value, Name); - - BGColorSy: - Cell.BkGnd := TryStrToColor(Name, False, Cell.BkColor); - - BackgroundSy: - BackgroundImage := Name; - - HRefSy: - Cell.Url := Name; - - TargetSy: - Cell.Target := Name; - - end; - - if Assigned(Prop) then - begin {Caption does not have Prop} - if Prop.GetVertAlign(Algn) and (Algn in [Atop, AMiddle, ABottom]) then - Valign := Algn; - if Parent.Document.UseQuirksMode then - Prop.GetVMarginArrayDefBorder(MargArrayO, clSilver) - else - Prop.GetVMarginArray(MargArrayO); - EmSize := Prop.EmSize; - ExSize := Prop.ExSize; - ConvMargArray(MargArrayO, 100, 0, EmSize, ExSize, 0, AutoCount, MargArray); - if VarIsStr(MargArrayO[piWidth]) and (MargArray[piWidth] >= 0) then - FSpecWd := ToSpecWidth(MargArray[piWidth], MargArrayO[piWidth]); - if VarIsStr(MargArrayO[piHeight]) and (MargArray[piHeight] >= 0) then - FSpecHt := ToSpecWidth(MargArray[piHeight], MargArrayO[piHeight]); - - Color := Prop.GetBackgroundColor; - if Color <> clNone then - begin - Cell.BkGnd := True; - Cell.BkColor := Color; - end; - Prop.GetBackgroundImage(BackgroundImage); {'none' will change ThtString to empty} - if BackgroundImage <> '' then - begin - BGImage := TImageObj.SimpleCreate(Cell, BackgroundImage); - Prop.GetBackgroundPos(EmSize, ExSize, FPRec); - end; - - {In the following, Padding widths in percent aren't accepted} - ConvMargArrayForCellPadding(MargArrayO, EmSize, ExSize, MargArray); - FPad.Top := MargArray[PaddingTop]; - FPad.Right := MargArray[PaddingRight]; - FPad.Bottom := MargArray[PaddingBottom]; - FPad.Left := MargArray[PaddingLeft]; - - HasBorderStyle := False; - if ThtBorderStyle(MargArray[BorderTopStyle]) <> bssNone then - begin - HasBorderStyle := True; - FBrd.Top := MargArray[BorderTopWidth]; - end; - if ThtBorderStyle(MargArray[BorderRightStyle]) <> bssNone then - begin - HasBorderStyle := True; - FBrd.Right := MargArray[BorderRightWidth]; - end; - if ThtBorderStyle(MargArray[BorderBottomStyle]) <> bssNone then - begin - HasBorderStyle := True; - FBrd.Bottom := MargArray[BorderBottomWidth]; - end; - if ThtBorderStyle(MargArray[BorderLeftStyle]) <> bssNone then - begin - HasBorderStyle := True; - FBrd.Left := MargArray[BorderLeftWidth]; - end; - - Prop.GetPageBreaks(BreakBefore, BreakAfter, KeepIntact); - ShowEmptyCells := Prop.ShowEmptyCells; - HideOverflow := Prop.IsOverflowHidden; - end; - {$ifdef JPM_DEBUGGING} - CodeSite.ExitMethod(Self,'TCellObj.Create'); - {$endif} -end; - -constructor TCellObj.CreateCopy(Parent: TBlock; T: TCellObj); -begin - inherited Create; - FCell := TCellObjCell.CreateCopy(Parent, T.Cell); - T.AssignTo(Self); -end; - -destructor TCellObj.Destroy; -begin - Cell.Free; - BGImage.Free; - TiledImage.Free; - inherited Destroy; -end; - -//-- BG ---------------------------------------------------------- 08.01.2012 -- -function TCellObj.GetBorderBottom: Integer; -begin - Result := FBrd.Bottom; -end; - -//-- BG ---------------------------------------------------------- 08.01.2012 -- -function TCellObj.GetBorderLeft: Integer; -begin - Result := FBrd.Left; -end; - -//-- BG ---------------------------------------------------------- 08.01.2012 -- -function TCellObj.GetBorderRight: Integer; -begin - Result := FBrd.Right; -end; - -//-- BG ---------------------------------------------------------- 08.01.2012 -- -function TCellObj.GetBorderTop: Integer; -begin - Result := FBrd.Top; -end; - -//-- BG ---------------------------------------------------------- 19.02.2013 -- -function TCellObj.GetCell: TCellObjCell; -begin - Result := FCell; -end; - -//-- BG ---------------------------------------------------------- 08.01.2012 -- -function TCellObj.GetPaddingBottom: Integer; -begin - Result := FPad.Bottom; -end; - -//-- BG ---------------------------------------------------------- 08.01.2012 -- -function TCellObj.GetPaddingLeft: Integer; -begin - Result := FPad.Left; -end; - -//-- BG ---------------------------------------------------------- 08.01.2012 -- -function TCellObj.GetPaddingRight: Integer; -begin - Result := FPad.Right; -end; - -//-- BG ---------------------------------------------------------- 08.01.2012 -- -function TCellObj.GetPaddingTop: Integer; -begin - Result := FPad.Top; -end; - -{----------------TCellObj.InitializeCell} - -procedure TCellObj.Initialize(TablePadding: Integer; const BkImageName: ThtString; - const APRec: PtPositionRec; Border: Boolean); -begin - if FPad.Top < 0 then - FPad.Top := TablePadding; - if FPad.Right < 0 then - FPad.Right := TablePadding; - if FPad.Bottom < 0 then - FPad.Bottom := TablePadding; - if FPad.Left < 0 then - FPad.Left := TablePadding; - if Border and not HasBorderStyle then // (BorderStyle = bssNone) then - begin - FBrd.Left := Max(1, FBrd.Left); - FBrd.Right := Max(1, FBrd.Right); - FBrd.Top := Max(1, FBrd.Top); - FBrd.Bottom := Max(1, FBrd.Bottom); - end; - HzSpace := FPad.Left + FBrd.Left + FBrd.Right + FPad.Right; - VrSpace := FPad.Top + FBrd.Top + FBrd.Bottom + FPad.Bottom; - - if (BkImageName <> '') and not Assigned(BGImage) then - begin - BGImage := TImageObj.SimpleCreate(Cell, BkImageName); - PRec := APrec; - end; -end; - -{----------------TCellObj.DrawLogic2} - -procedure TCellObj.DrawLogic2(Canvas: TCanvas; Y, CellSpacingHorz, CellSpacingVert: Integer; var Curs: Integer); -var - Dummy: Integer; - Tmp: Integer; -begin - {$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'TCellObj.DrawLogic2'); - CodeSite.SendFmtMsg('Y = [%d]',[Y]); - CodeSite.SendFmtMsg('CellSpacing = [%d,%d]',[CellSpacingHorz, CellSpacingVert]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.AddSeparator; - {$ENDIF} - if Cell.Count > 0 then - begin - Tmp := Ht - VSize - (VrSpace + CellSpacingVert); - case VAlign of - ATop: YIndent := 0; - AMiddle: YIndent := Tmp div 2; - ABottom, ABaseline: YIndent := Tmp; - end; - Dummy := 0; - Cell.DoLogic(Canvas, Y + FPad.Top + FBrd.Top + CellSpacingVert + YIndent, Wd - (HzSpace + CellSpacingHorz), - Ht - VrSpace - CellSpacingVert, 0, Dummy, Curs); - end; - if Assigned(BGImage) and Cell.Document.ShowImages then - begin - BGImage.DrawLogicInline(Canvas, nil, 100, 0); - if BGImage.Image = ErrorImage then - FreeAndNil(BGImage) - else - begin - BGImage.ClientSizeKnown := True; {won't need reformat on InsertImage} - NeedDoImageStuff := True; - end; - end; - {$IFDEF JPM_DEBUGGING} - CodeSite.ExitMethod(Self,'TCellObj.DrawLogic2'); - {$ENDIF} -end; - -{----------------TCellObj.Draw} - -procedure TCellObj.Draw(Canvas: TCanvas; const ARect: TRect; X, Y, CellSpacingHorz, CellSpacingVert: Integer; - Border: Boolean; Light, Dark: TColor); -var - YO: Integer; - BL, BT, BR, BB, PL, PT, PR, PB: Integer; - ImgOK: Boolean; - IT, IH, FT, Rslt: Integer; - Rgn, SaveRgn: HRgn; - Point: TPoint; - SizeV, SizeW: TSize; - HF, VF: double; - BRect: TRect; - IsVisible: Boolean; -begin - YO := Y - Cell.Document.YOff; - - BL := X + CellSpacingHorz; {Border left and right} - BR := X + Wd; - PL := BL + FBrd.Left; {Padding left and right} - PR := BR - FBrd.Right; - - BT := YO + CellSpacingVert; {Border Top and Bottom} - BB := YO + Ht; - PT := BT + FBrd.Top; {Padding Top and Bottom} - PB := BB - FBrd.Bottom; - - IT := Max(0, ARect.Top - 2 - PT); - FT := Max(PT, ARect.Top - 2); {top of area drawn, screen coordinates} - IH := Min(PB - FT, ARect.Bottom - FT); {height of area actually drawn} - - Cell.MyRect := Rect(BL, BT, BR, BB); - if not (BT <= ARect.Bottom) and (BB >= ARect.Top) then - Exit; - - try - if NeedDoImageStuff then - begin - if BGImage = nil then - NeedDoImageStuff := False - else if BGImage.Image <> DefImage then - begin - if BGImage.Image = ErrorImage then {Skip the background image} - FreeAndNil(BGImage) - else - try - BGImage.Image.TileImage( PRec, Wd - CellSpacingHorz, Ht - CellSpacingVert, TiledImage, NoMask); - if Cell.IsCopy then - TiledImage.Bitmap.HandleType := bmDIB; - except {bad image, get rid of it} - FreeAndNil(BGImage); - FreeAndNil(TiledImage); - end; - NeedDoImageStuff := False; - end; - end; - - ImgOK := not NeedDoImageStuff and Assigned(BGImage) and (BGImage.Image <> DefImage) and Cell.Document.ShowImages; - - if Cell.BkGnd then - begin - Canvas.Brush.Color := ThemedColor(Cell.BkColor {$ifdef has_StyleElements},seClient in Cell.Document.StyleElements{$endif}) or PalRelative; - Canvas.Brush.Style := bsSolid; - if not Cell.IsCopy or not ImgOK then - begin - {slip under border to fill gap when printing} - BRect := Rect(PL, FT, PR, FT + IH); - if not HasBorderStyle then // BorderStyle = bssNone then - begin - if MargArray[BorderLeftWidth] > 0 then - Dec(BRect.Left); - if MargArray[BorderTopWidth] > 0 then - Dec(BRect.Top); - if MargArray[BorderRightWidth] > 0 then - Inc(BRect.Right); - if MargArray[BorderBottomWidth] > 0 then - Inc(BRect.Bottom); - end - else - if Border then - InflateRect(BRect, 1, 1); - Canvas.FillRect(BRect); - end; - end; - - if ImgOK and (TiledImage <> nil) then - begin - if not Cell.IsCopy then - TiledImage.DrawUnstretched(Canvas, PL, FT, Pr - PL, IH, 0, IT, Cell.BkGnd) - else - TiledImage.PrintUnstretched(Canvas, PL, FT, Pr - PL, IH, 0, IT, Cell.BkGnd) - ; - end; - except - end; - - IsVisible := (YO < ARect.Bottom + 200) and (YO + Ht > -200); - try - if IsVisible and (Cell.Count > 0) then - begin - Rslt := 0; - Rgn := 0; - SaveRgn := 0; - if HideOverflow then - begin - {clip cell contents to prevent overflow. First check to see if there is - already a clip region} - SaveRgn := CreateRectRgn(0, 0, 1, 1); - Rslt := GetClipRgn(Canvas.Handle, SaveRgn); {Rslt = 1 for existing region, 0 for none} - {Form the region for this cell} - GetWindowOrgEx(Canvas.Handle, Point); {when scrolling or animated Gifs, canvas may not start at X=0, Y=0} - if not Cell.Document.Printing then - if IsWin95 then - Rgn := CreateRectRgn(BL - Point.X, Max(BT - Point.Y, -32000), BR - Point.X, Min(BB - Point.Y, 32000)) - else - Rgn := CreateRectRgn(BL - Point.X, BT - Point.Y, BR - Point.X, BB - Point.Y) - else - begin - GetViewportExtEx(Canvas.Handle, SizeV); - GetWindowExtEx(Canvas.Handle, SizeW); - HF := (SizeV.cx / SizeW.cx); {Horizontal adjustment factor} - VF := (SizeV.cy / SizeW.cy); {Vertical adjustment factor} - if IsWin95 then - Rgn := CreateRectRgn(Round(HF * (BL - Point.X) - 1), Max(Round(VF * (BT - Point.Y) - 1), -32000), Round(HF * (X + Wd - Point.X) + 1), Min(Round(VF * (YO + Ht - Point.Y)), 32000)) - else - Rgn := CreateRectRgn(Round(HF * (BL - Point.X) - 1), Round(VF * (BT - Point.Y) - 1), Round(HF * (X + Wd - Point.X) + 1), Round(VF * (YO + Ht - Point.Y))); - end; - if Rslt = 1 then {if there was a region, use the intersection with this region} - CombineRgn(Rgn, Rgn, SaveRgn, Rgn_And); - SelectClipRgn(Canvas.Handle, Rgn); - end; - try - Cell.Draw(Canvas, ARect, Wd - HzSpace - CellSpacingHorz, - X + FPad.Left + FBrd.Left + CellSpacingHorz, - Y + FPad.Top + FBrd.Top + YIndent, ARect.Left, 0); {possibly should be IRgn.LfEdge} - finally - if HideOverflow then - begin - if Rslt = 1 then {restore any previous clip region} - SelectClipRgn(Canvas.Handle, SaveRgn) - else - SelectClipRgn(Canvas.Handle, 0); - DeleteObject(Rgn); - DeleteObject(SaveRgn); - end; - end; - end; - except - end; - - Cell.DrawYY := Y; - if IsVisible and ((Cell.Count > 0) or ShowEmptyCells) then - try - DrawBorder(Canvas, Rect(BL, BT, BR, BB), Rect(PL, PT, PR, PB), - htColors(MargArray[BorderLeftColor], MargArray[BorderTopColor], MargArray[BorderRightColor], MargArray[BorderBottomColor]), - htStyles(ThtBorderStyle(MargArray[BorderLeftStyle]), ThtBorderStyle(MargArray[BorderTopStyle]), ThtBorderStyle(MargArray[BorderRightStyle]), ThtBorderStyle(MargArray[BorderBottomStyle])), - MargArray[BackgroundColor], Cell.Document.Printing{$ifdef has_StyleElements},Cell.Document.StyleElements{$endif}); - except - end; -end; - -//-- BG ---------------------------------------------------------- 08.01.2012 -- -procedure TCellObj.SetBorderBottom(const Value: Integer); -begin - FBrd.Bottom := Value; -end; - -//-- BG ---------------------------------------------------------- 08.01.2012 -- -procedure TCellObj.SetBorderLeft(const Value: Integer); -begin - FBrd.Left := Value; -end; - -//-- BG ---------------------------------------------------------- 08.01.2012 -- -procedure TCellObj.SetBorderRight(const Value: Integer); -begin - FBrd.Right := Value; -end; - -//-- BG ---------------------------------------------------------- 08.01.2012 -- -procedure TCellObj.SetBorderTop(const Value: Integer); -begin - FBrd.Top := Value; -end; - -//-- BG ---------------------------------------------------------- 08.01.2012 -- -procedure TCellObj.SetPaddingBottom(const Value: Integer); -begin - FPad.Bottom := Value; -end; - -//-- BG ---------------------------------------------------------- 08.01.2012 -- -procedure TCellObj.SetPaddingLeft(const Value: Integer); -begin - FPad.Left := Value; -end; - -//-- BG ---------------------------------------------------------- 08.01.2012 -- -procedure TCellObj.SetPaddingRight(const Value: Integer); -begin - FPad.Right := Value; -end; - -//-- BG ---------------------------------------------------------- 08.01.2012 -- -procedure TCellObj.SetPaddingTop(const Value: Integer); -begin - FPad.Top := Value; -end; - -{----------------TCellList.Create} - -constructor TCellList.Create(Attr: TAttributeList; Prop: TProperties); -var - I: Integer; - Color: TColor; -begin - inherited Create; - if Assigned(Attr) then - for I := 0 to Attr.Count - 1 do - with Attr[I] do - case Which of - BGColorSy: - BkGnd := TryStrToColor(Name, False, BkColor); - BackgroundSy: - BkImage := Name; - HeightSy: - SpecRowHeight := ToSpecWidth(Max(0, Min(Value, 100)), Name); - end; - if Assigned(Prop) then - begin - Color := Prop.GetBackgroundColor; - if Color <> clNone then - begin - BkGnd := True; - BkColor := Color; - end; - Prop.GetBackgroundImage(BkImage); {'none' will change ThtString to empty} - if BkImage <> '' then - Prop.GetBackgroundPos(Prop.EmSize, Prop.ExSize, APRec); - Prop.GetPageBreaks(BreakBefore, BreakAfter, KeepIntact); - end; -end; - -{----------------TCellList.CreateCopy} - -constructor TCellList.CreateCopy(Parent: TBlock; T: TCellList); -var - I: Integer; -begin - inherited Create; - BreakBefore := T.BreakBefore; - BreakAfter := T.BreakAfter; - KeepIntact := T.KeepIntact; - RowType := T.Rowtype; - for I := 0 to T.Count - 1 do - if Assigned(T[I]) then - Add(T[I].Clone(Parent)) - else - Add(nil); -end; - -procedure TCellList.Add(CellObjBase: TCellObjBase); -var - CellObj: TCellObj absolute CellObjBase; -begin - inherited Add(CellObjBase); - if CellObjBase is TCellObj then - begin - BreakBefore := BreakBefore or CellObj.BreakBefore; - BreakAfter := BreakAfter or CellObj.BreakAfter; - KeepIntact := KeepIntact or CellObj.KeepIntact; - case SpecRowHeight.VType of - wtPercent: - case CellObj.FSpecHt.VType of - wtPercent: - if CellObj.FSpecHt.Value < SpecRowHeight.Value then - CellObj.FSpecHt.Value := SpecRowHeight.Value; - - wtNone, - wtRelative: // percentage is stronger - CellObj.FSpecHt := SpecRowHeight; - - else - // keep specified absolute value - end; - - wtRelative: - case CellObj.FSpecHt.VType of - wtPercent: ; // percentage is stronger - - wtNone: - CellObj.FSpecHt := SpecRowHeight; - - wtRelative: - if CellObj.FSpecHt.Value < SpecRowHeight.Value then - CellObj.FSpecHt.Value := SpecRowHeight.Value; - else - // keep specified absolute value - end; - - wtAbsolute: - case CellObj.FSpecHt.VType of - wtAbsolute: - if CellObj.FSpecHt.Value < SpecRowHeight.Value then - CellObj.FSpecHt.Value := SpecRowHeight.Value; - else - // absolute value is stronger - CellObj.FSpecHt := SpecRowHeight; - end; - end; - end; -end; - -{----------------TCellList.Initialize} - -procedure TCellList.Initialize; -var - I: Integer; -begin - if BkGnd then - for I := 0 to Count - 1 do - if Items[I] is TCellObj then - with TCellObj(Items[I]).Cell do - if not BkGnd then - begin - BkGnd := True; - BkColor := Self.BkColor; - end; -end; - -{----------------TCellList.DrawLogic1} - -function TCellList.DrawLogicA(Canvas: TCanvas; const Widths: TIntArray; Span, CellSpacingHorz,CellSpacingVert, AHeight, Rows: Integer; - out Desired: Integer; out Spec, More: Boolean): Integer; -{Find vertical size of each cell, Row height of this row. But final Y position - is not known at this time. - Rows is number rows in table. - AHeight is for calculating percentage heights} -var - I, Dummy: Integer; - DummyCurs, GuessHt: Integer; -begin - Result := 0; - Desired := 0; - Spec := False; - DummyCurs := 0; - More := False; - for I := 0 to Count - 1 do - begin - if Items[I] is TCellObj then - with TCellObj(Items[I]) do - if ColSpan > 0 then {skip the dummy cells} - begin - Wd := Sum(Widths, I, I + ColSpan - 1); {accumulate column widths} - if Span = RowSpan then - begin - Dummy := 0; - case SpecHt.VType of - wtAbsolute: - GuessHt := Trunc(SpecHt.Value); - - wtPercent: - GuessHt := Trunc(SpecHt.Value * AHeight / 1000.0); - else - GuessHt := 0; - end; - - if (GuessHt = 0) and (Rows = 1) then - GuessHt := AHeight; - - VSize := Cell.DoLogic(Canvas, 0, Wd - HzSpace - CellSpacingHorz, Max(0, GuessHt - VrSpace), 0, Dummy, DummyCurs); - Result := Max(Result, VSize + VrSpace); - - case SpecHt.VType of - wtAbsolute: - begin - Result := Max(Result, Max(VSize, Trunc(SpecHt.Value))); - Spec := True; - end; - - wtPercent: - begin - Desired := Max(Desired, GuessHt); - Spec := True; - end; - end; - end - else if RowSpan > Span then - More := True; - end; - end; - Desired := Max(Result, Desired); -end; - -{----------------TCellList.DrawLogicB} - -procedure TCellList.DrawLogicB(Canvas: TCanvas; Y, CellSpacingHorz, CellSpacingVert: Integer; var Curs: Integer); -{Calc Y indents. Set up Y positions of all cells.} -var - I: Integer; - CellObj: TCellObjBase; -begin -{$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'TCellObj.DrawLogicB'); - CodeSite.SendFmtMsg('Y = [%d]',[Y]); - CodeSite.SendFmtMsg('CellSpacing = [%d,%d]',[CellSpacingHorz, CellSpacingVert]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.AddSeparator; -{$ENDIF} - for I := 0 to Count - 1 do - begin - CellObj := Items[I]; - if (CellObj <> nil) and (CellObj.ColSpan > 0) and (CellObj.RowSpan > 0) then - CellObj.DrawLogic2(Canvas, Y, CellSpacingHorz,CellSpacingVert, Curs); - end; -{$IFDEF JPM_DEBUGGING} - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.ExitMethod(Self,'TCellObj.DrawLogicB'); -{$ENDIF} -end; - -//-- BG ---------------------------------------------------------- 12.09.2010 -- -function TCellList.GetCellObj(Index: Integer): TCellObjBase; -begin - Result := inherited Get(Index); -end; - -{----------------TCellList.Draw} - -function TCellList.Draw(Canvas: TCanvas; Document: ThtDocument; const ARect: TRect; const Widths: TIntArray; - X, Y, YOffset, CellSpacingHorz,CellSpacingVert: Integer; Border: Boolean; Light, Dark: TColor; MyRow: Integer): Integer; -var - I, SpacingVert: Integer; - YO: Integer; - CellObj: TCellObjBase; -begin - YO := Y - YOffset; - Result := RowHeight + Y; - SpacingVert := CellSpacingVert div 2; - - with Document do {check CSS page break properties} - if Printing then - if BreakBefore then - begin - if YO > ARect.Top then {page-break-before} - begin - if Y + SpacingVert < PageBottom then - begin - PageShortened := True; - PageBottom := Y + SpacingVert; - end; - Exit; - end; - end - else if KeepIntact then - begin - {Try to fit this RowSpan on a page by itself} - if (YO > ARect.Top) and (Y + RowSpanHeight > PageBottom) and - (RowSpanHeight < ARect.Bottom - ARect.Top) then - begin - if Y < PageBottom then - begin - PageShortened := True; - PageBottom := Y; - end; - Exit; - end - else if (YO > ARect.Top) and (Y + RowHeight > PageBottom) and - (RowHeight < ARect.Bottom - ARect.Top) then - begin - if Y + SpacingVert < PageBottom then - begin - PageShortened := True; - PageBottom := Y + SpacingVert; - end; - Exit; - end; - end - else if BreakAfter then - if ARect.Top + YOff < Result then {page-break-after} - if Result + SpacingVert < PageBottom then - begin - PageShortened := True; - PageBottom := Result + SpacingVert; - end; - - with Document do {avoid splitting any small rows} - if Printing and (RowSpanHeight <= 100) and - (Y + RowSpanHeight > PageBottom) then - begin - if Y < PageBottom then - begin - PageShortened := True; - PageBottom := Y; - end; - Exit; - end; - - if (YO + RowSpanHeight >= ARect.Top) and (YO < ARect.Bottom) and - (not Document.Printing or (Y < Document.PageBottom)) then - for I := 0 to Count - 1 do - begin - CellObj := Items[I]; - if (CellObj <> nil) and (CellObj.ColSpan > 0) and (CellObj.RowSpan > 0) then - CellObj.Draw(Canvas, ARect, X, Y, CellSpacingHorz,CellSpacingVert, Border, Light, Dark); - X := X + Widths[I]; - end; -end; - -//-- BG ---------------------------------------------------------- 09.02.2013 -- -function TryStrToTableFrame(const Str: ThtString; var Frame: TTableFrame): Boolean; - {$ifdef UseInline} inline; {$endif} -var - Upr: ThtString; -begin - Upr := htUpperCase(Str); - Result := True; - if htCompareStr(Upr, 'VOID') = 0 then - Frame := tfVoid - else if htCompareStr(Upr, 'ABOVE') = 0 then - Frame := tfAbove - else if htCompareStr(Upr, 'BELOW') = 0 then - Frame := tfBelow - else if htCompareStr(Upr, 'HSIDES') = 0 then - Frame := tfHSides - else if htCompareStr(Upr, 'LHS') = 0 then - Frame := tfLhs - else if htCompareStr(Upr, 'RHS') = 0 then - Frame := tfRhs - else if htCompareStr(Upr, 'VSIDES') = 0 then - Frame := tfVSides - else if htCompareStr(Upr, 'BOX') = 0 then - Frame := tfBox - else if htCompareStr(Upr, 'BORDER') = 0 then - Frame := tfBorder - else - Result := False; -end; - -//-- BG ---------------------------------------------------------- 09.02.2013 -- -function TryStrToTableRules(const Str: ThtString; var Rules: TTableRules): Boolean; - {$ifdef UseInline} inline; {$endif} -var - Upr: ThtString; -begin - Upr := htUpperCase(Str); - Result := True; - if htCompareStr(Upr, 'NONE') = 0 then - Rules := trNone - else if htCompareStr(Upr, 'GROUPS') = 0 then - Rules := trGroups - else if htCompareStr(Upr, 'ROWS') = 0 then - Rules := trRows - else if htCompareStr(Upr, 'COLS') = 0 then - Rules := trCols - else if htCompareStr(Upr, 'ALL') = 0 then - Rules := trAll - else - Result := False; -end; - -{----------------THtmlTable.Create} - -constructor THtmlTable.Create(OwnerTableBlock: TTableBlock; Parent: TCellBasic; Attr: TAttributeList; Prop: TProperties); -var - I: Integer; - A: TAttribute; -begin - inherited Create(Parent, Attr, Prop); - FOwnerTableBlock := OwnerTableBlock; - if FDisplay = pdUnassigned then - FDisplay := pdTable; - Rows := TRowList.Create; - - FCellPadding := 1; - FCellSpacingHorz := 2; - FCellSpacingVert := 2; - BorderColor := clBtnFace; - BorderColorLight := clBtnHighLight; - BorderColorDark := clBtnShadow; - - // BG, 20.01.2013: process BorderSy before FrameSy and RulesSy as it implies defaults. - A := nil; - HasBorderWidthAttr := Attr.Find(BorderSy, A); - if HasBorderWidthAttr then - begin - //BG, 15.10.2010: issue 5: set border width only, if style does not set any border width: - if A.Name = '' then - BorderWidth := 1 - else - BorderWidth := Min(100, Max(0, A.Value)); {Border=0 is no border} - brdWidthAttr := BorderWidth; - - if BorderWidth <> 0 then - begin - Frame := tfBorder; - Rules := trAll; - end - else - begin - Frame := tfVoid; - Rules := trNone; - end; - end; - - for I := 0 to Attr.Count - 1 do - with Attr[I] do - case Which of - FrameAttrSy: - TryStrToTableFrame(Name, Frame); - - RulesSy: - TryStrToTableRules(Name, Rules); - - CellSpacingSy: - begin - FCellSpacingHorz := Min(40, Max(-1, Value)); - FCellSpacingVert := CellSpacingHorz; - end; - - CellPaddingSy: - FCellPadding := Min(50, Max(0, Value)); - - BorderColorSy: - TryStrToColor(Name, False, BorderColor); - - BorderColorLightSy: - TryStrToColor(Name, False, BorderColorLight); - - BorderColorDarkSy: - TryStrToColor(Name, False, BorderColorDark); - end; - if Prop.Collapse then - begin - FCellSpacingHorz := -1; - FCellSpacingVert := -1; - end - else if Prop.HasBorderSpacing then - begin - FCellSpacingHorz := Prop.GetBorderSpacingHorz; - FCellSpacingVert := Prop.GetBorderSpacingVert; - end; -end; - -{----------------THtmlTable.CreateCopy} - -constructor THtmlTable.CreateCopy(OwnerCell: TCellBasic; Source: THtmlNode); -var - I: Integer; - HtmlTable: THtmlTable absolute Source; -begin - inherited CreateCopy(OwnerCell,Source); - FOwnerTableBlock := OwnerCell.FOwnerBlock as TTableBlock; - Rows := TRowList.Create; - for I := 0 to HtmlTable.Rows.Count - 1 do - Rows.Add(TCellList.CreateCopy(OwnerCell.OwnerBlock, HtmlTable.Rows[I])); - - Move(HtmlTable.Initialized, Initialized, PtrSub(@EndList, @Initialized)); - Rules := HtmlTable.Rules; - BorderWidth := HtmlTable.BorderWidth; - BorderColor := HtmlTable.BorderColor; - - SetLength(Widths, NumCols); - SetLength(MaxWidths, NumCols); - SetLength(MinWidths, NumCols); - SetLength(Percents, NumCols); - SetLength(Multis, NumCols); - SetLength(ColumnSpecs, NumCols); - - if HtmlTable.FColSpecs <> nil then - begin - FColSpecs := TColSpecList.Create; - for I := 0 to HtmlTable.FColSpecs.Count - 1 do - FColSpecs.Add(TColSpec.CreateCopy(HtmlTable.FColSpecs[I])); - end; - - if Document.PrintTableBackground then - begin - FBkGnd := HtmlTable.BkGnd; - FBkColor := HtmlTable.BkColor; - end - else - FBkGnd := False; - TablePartRec := TTablePartRec.Create; - TablePartRec.TablePart := Normal; -end; - -{----------------THtmlTable.Destroy} - -destructor THtmlTable.Destroy; -begin - Rows.Free; - TablePartRec.Free; - FreeAndNil(FColSpecs); - inherited Destroy; -end; - -{----------------THtmlTable.DoColumns} - -procedure THtmlTable.DoColumns(Count: Integer; const SpecWidth: TSpecWidth; VAlign: ThtAlignmentStyle; const Align: ThtString); -{add the / info to the Cols list} -var - I: Integer; -begin - if FColSpecs = nil then - FColSpecs := TColSpecList.Create; - Count := Min(Count, 10000); - for I := 0 to Count - 1 do - FColSpecs.Add(TColSpec.Create(SpecWidth, Align, VAlign)); -end; - -{----------------THtmlTable.AddDummyCells} - -procedure THtmlTable.Initialize; - - function DummyCell(RSpan: Integer): TCellObjBase; - begin - Result := TDummyCellObj.Create(RSpan); -// if BkGnd then {transfer bgcolor to cell if no Table image} -// begin -// Result.Cell.BkGnd := True; -// Result.Cell.BkColor := BkColor; -// end; - end; - - procedure AddDummyCellsForColSpansAndInitializeCells; - var - Cl, Rw, RowCount, K: Integer; - Row: TCellList; - CellObjBase: TCellObjBase; - CellObj: TCellObj absolute CellObjBase; - begin - {initialize cells and put dummy cells in rows to make up for ColSpan > 1} - NumCols := 0; - RowCount := Rows.Count; - for Rw := 0 to RowCount - 1 do - begin - Row := Rows[Rw]; - Row.Initialize; - for Cl := Row.Count - 1 downto 0 do - begin - CellObjBase := Row[Cl]; - CellObj.Initialize(CellPadding, Row.BkImage, Row.APRec, Self.BorderWidth > 0); - if BkGnd and not CellObj.Cell.BkGnd then {transfer bgcolor to cells if no Table image} - begin - CellObj.Cell.BkGnd := True; - CellObj.Cell.BkColor := BkColor; - end; - CellObj.RowSpan := Min(CellObj.RowSpan, RowCount - Rw); {So can't extend beyond table} - for K := Cl + 1 to Cl + CellObj.ColSpan - 1 do - if CellObj.RowSpan > 1 then - Row.Insert(K, DummyCell(CellObj.RowSpan)) {these could be - Nil also except they're needed for expansion in the next section} - else - Row.Insert(K, DummyCell(1)); - end; - NumCols := Max(NumCols, Row.Count); {temporary # cols} - end; - end; - - procedure AddDummyCellsForRowSpans; - var - Cl, Rw, RowCount, K: Integer; - Row: TCellList; - CellObj: TCellObjBase; - begin - RowCount := Rows.Count; - for Cl := 0 to NumCols - 1 do - for Rw := 0 to RowCount - 1 do - begin - Row := Rows[Rw]; - if Row.Count > Cl then - begin - CellObj := Row[Cl]; - if CellObj <> nil then - begin - CellObj.RowSpan := Min(CellObj.RowSpan, RowCount - Rw); {practical limit} - if CellObj.RowSpan > 1 then - for K := Rw + 1 to Rw + CellObj.RowSpan - 1 do - begin {insert dummy cells in following rows if RowSpan > 1} - while Rows[K].Count < Cl do {add padding if row is short} - Rows[K].Add(DummyCell(0)); - if Rows[K].Count < NumCols then // in an invalid table definition spanned cells may overlap and thus required dummies could be present, yet. - Rows[K].Insert(Cl, DummyCell(0)); - end; - end; - end; - end; - - NumCols := 0; - for Rw := 0 to Rows.Count - 1 do - NumCols := Max(NumCols, Rows[Rw].Count); - end; - - procedure AddDummyCellsForUnequalRowLengths; - var - Cl: Integer; - CellObj: TCellObjBase; - Row: TCellList; - - function IsLastCellOfRow(): Boolean; - begin - // Is Row[Cl] resp. CellObj a cell in this row? (Cl >= 0) - // With respect to rowspans from previous rows is it the last one? (Cl + CellObj.ColSpan >= NumCols) - Result := (Cl >= 0) and (Cl + CellObj.ColSpan >= Row.Count); - end; - - var - Rw, I: Integer; - begin - Rw := 0; - while Rw < Rows.Count do - begin - Row := Rows[Rw]; - Cl := -1; - if Row.Count < NumCols then - begin - // this row is too short - - // find the spanning column - Cl := Row.Count - 1; - while Cl >= 0 do - begin - CellObj := Row[Cl]; - if CellObj.ColSpan > 0 then - break; - Dec(Cl); - end; - - if IsLastCellOfRow then - // add missing cells - for I := Row.Count to NumCols - 1 do - Row.Add(DummyCell(1)); - end; - - // continue with next row not spanned by this cell. - if (Cl >= 0) and (CellObj.RowSpan > 0) then - Inc(Rw, CellObj.RowSpan) - else - Inc(Rw); - end; - end; - -var - Cl, Rw, MaxColSpan, MaxRowSpan: Integer; - Row: TCellList; - CellObj: TCellObjBase; -begin - if not Initialized then - begin - AddDummyCellsForColSpansAndInitializeCells; - AddDummyCellsForRowSpans; - AddDummyCellsForUnequalRowLengths; - - for Rw := 0 to Rows.Count - 1 do - begin - MaxRowSpan := Rows.Count - Rw; - Row := Rows[Rw]; - for Cl := 0 to Row.Count - 1 do - begin - MaxColSpan := NumCols - Cl; - CellObj := Row[Cl]; - - // Reduce excessive colspans. - if CellObj.ColSpan > MaxColSpan then - CellObj.ColSpan := MaxColSpan; - - // Reduce excessive rowspans. - if CellObj.RowSpan > MaxRowSpan then - CellObj.RowSpan := MaxRowSpan; - end; - end; - - SetLength(Widths, NumCols); - SetLength(MaxWidths, NumCols); - SetLength(MinWidths, NumCols); - SetLength(Percents, NumCols); - SetLength(Multis, NumCols); - SetLength(ColumnSpecs, NumCols); - - Initialized := True; - end; {if not ListsProcessed} -end; - -procedure THtmlTable.IncreaseWidthsByWidth(WidthType: TWidthType; var Widths: TIntArray; - StartIndex, EndIndex, Required, Spanned, Count: Integer); -// Increases width of spanned columns relative to given widths. -var - I, OldWidth, NewWidth: Integer; -begin - OldWidth := 0; - NewWidth := 0; - for I := EndIndex downto StartIndex do - if ColumnSpecs[I] = WidthType then - if Count > 1 then - begin - // building sum of all processed columns avoids rounding errors. - Inc(OldWidth, Widths[I]); - Widths[I] := MulDiv(OldWidth, Required, Spanned) - NewWidth; - Inc(NewWidth, Widths[I]); - Dec(Count); - end - else - begin - // The remaining pixels are the new first column's width. - Widths[I] := Required - NewWidth; - break; - end; -end; - -procedure THtmlTable.IncreaseWidthsByPercentage(var Widths: TIntArray; - StartIndex, EndIndex, Required, Spanned, Percent, Count: Integer); -// Increases width of spanned columns relative to given percentage. -var - Excess, AddedExcess, AddedPercent, I, Add: Integer; -begin - Excess := Required - Spanned; - AddedExcess := 0; - AddedPercent := 0; - for I := EndIndex downto StartIndex do - if ColumnSpecs[I] = wtPercent then - if Count > 1 then - begin - Inc(AddedPercent, Percents[I]); - Add := MulDiv(Excess, AddedPercent, Percent) - AddedExcess; - Inc(Widths[I], Add); - Inc(AddedExcess, Add); - Dec(Count); - end - else - begin - // add the remaining pixels to the first column's width. - Inc(Widths[I], Excess - AddedExcess); - break; - end; -end; - -procedure THtmlTable.IncreaseWidthsByMinMaxDelta(WidthType: TWidthType; var Widths: TIntArray; - StartIndex, EndIndex, Excess, DeltaWidth, Count: Integer; const Deltas: TIntArray); -// Increases width of spanned columns relative to difference between min and max widths. -var - AddedExcess, AddedDelta, I, Add: Integer; - WidthSum, K, Remaining: Integer; -begin - AddedExcess := 0; - AddedDelta := 0; - for I := EndIndex downto StartIndex do - if ColumnSpecs[I] = WidthType then - if Count > 1 then - begin - Inc(AddedDelta, Deltas[I]); - Add := MulDiv(Excess, AddedDelta, DeltaWidth) - AddedExcess; - Inc(Widths[I], Add); - Inc(AddedExcess, Add); - Dec(Count); - end - else - begin - // BG, 16.11.2013: thanks to Andreas Hausladen for spreading Excess: - if WidthType = wtNone then - begin - WidthSum := 0; - for K := EndIndex downto StartIndex do - if ColumnSpecs[K] = WidthType then - Inc(WidthSum, Widths[K] + Deltas[K]); - - // spread the remaining pixels to all columns by their width percentage - Remaining := (Excess - AddedExcess) - DeltaWidth; - if (Remaining > 0) and (WidthSum > 0) then // wrong display is better than crash - begin - for K := EndIndex downto StartIndex + 1 do - begin - if ColumnSpecs[K] = WidthType then - begin - Add := ((Widths[K] + Deltas[K]) * Remaining) div WidthSum; - Inc(Widths[K], Add); - Inc(AddedExcess, Add); - end; - end; - end; - end; - - // add the remaining pixels to the first column's width. - Inc(Widths[I], Excess - AddedExcess); - break; - end; -end; - -procedure THtmlTable.IncreaseWidthsRelatively( - var Widths: TIntArray; - StartIndex, EndIndex, Required, SpannedMultis: Integer; ExactRelation: Boolean); -// Increases width of spanned columns according to relative columns specification. -// Does not touch columns specified by percentage or absolutely. -var - RequiredWidthFactor: Double; - Count, I, AddedWidth, AddedMulti: Integer; -begin - // Some columns might have Multi=0. Don't widen these. Thus remove their width from Required. - // Some columns might be wider than required. Widen all columns to preserve the relations. - RequiredWidthFactor := 0; - Count := 0; - for I := EndIndex downto StartIndex do - if ColumnSpecs[I] = wtRelative then - if Multis[I] > 0 then - begin - Inc(Count); - if ExactRelation then - RequiredWidthFactor := Max(RequiredWidthFactor, Widths[I] / Multis[I]); - end - else - begin - Dec(Required, Widths[I]); - end; - - RequiredWidthFactor := Max(RequiredWidthFactor, Required / SpannedMultis); // 100 times width of 1*. - Required := Min(Required, Trunc(RequiredWidthFactor * SpannedMultis)); // don't exceed given requirement. - // building sum of all processed columns to reduce rounding errors. - AddedWidth := 0; - AddedMulti := 0; - for I := EndIndex downto StartIndex do - if (ColumnSpecs[I] = wtRelative) and (Multis[I] > 0) then - if Count > 1 then - begin - Inc(AddedMulti, Multis[I]); - Widths[I] := Trunc(AddedMulti * RequiredWidthFactor) - AddedWidth; - Inc(AddedWidth, Widths[I]); - Dec(Count); - end - else - begin - // The remaining pixels are the new first column's width. - Widths[I] := Required - AddedWidth; - break; - end; -end; - -procedure THtmlTable.IncreaseWidthsEvenly(WidthType: TWidthType; var Widths: TIntArray; - StartIndex, EndIndex, Required, Spanned, Count: Integer); -// Increases width of spanned columns of given type evenly. -var - RemainingWidth, I: Integer; -begin - RemainingWidth := Required; - for I := EndIndex downto StartIndex do - if ColumnSpecs[I] = WidthType then - if Count > 1 then - begin - Dec(Count); - // MulDiv for each column instead of 1 precalculated width for all columns avoids round off errors. - Widths[I] := MulDiv(Widths[I], Required, Spanned); - Dec(RemainingWidth, Widths[I]); - end - else - begin - // add the remaining pixels to the first column's width. - Widths[I] := RemainingWidth; - break; - end; -end; - -{----------------THtmlTable.GetWidths} - -procedure THtmlTable.GetMinMaxWidths(Canvas: TCanvas); -// calculate MaxWidths and MinWidths of all columns. - - procedure UpdateColumnSpec(var Counts: TIntegerPerWidthType; var OldType: TWidthType; NewType: TWidthType); - begin - // update to stonger spec only: - case NewType of - wtAbsolute: if OldType in [wtAbsolute] then Exit; - wtPercent: if OldType in [wtAbsolute, wtPercent] then Exit; - wtRelative: if OldType in [wtAbsolute, wtPercent, wtRelative] then Exit; - else - // wtNone: - Exit; - end; - - // at this point: NewType is stronger than OldType - Dec(Counts[OldType]); - Inc(Counts[NewType]); - OldType := NewType; - end; - - procedure UpdateRelativeWidths(var Widths: TIntArray; const ColumnSpecs: TWidthTypeArray; StartIndex, EndIndex: Integer); - // Increases width of spanned columns according to relative columns specification. - // Does not touch columns specified by percentage or absolutely. - var - RequiredWidthFactor, Count, Multi, I, Required, AddedWidth, AddedMulti: Integer; - begin - // Some columns might be wider than required. Widen all columns to preserve the relations. - RequiredWidthFactor := 100; - Count := 0; - Multi := 0; - for I := EndIndex downto StartIndex do - if (ColumnSpecs[I] = wtRelative) and (Multis[I] > 0) then - begin - Inc(Count); - Inc(Multi, Multis[I]); - RequiredWidthFactor := Max(RequiredWidthFactor, MulDiv(Widths[I], 100, Multis[I])); - end; - - Required := MulDiv(RequiredWidthFactor, Multi, 100); - // building sum of all processed columns to reduce rounding errors. - AddedWidth := 0; - AddedMulti := 0; - for I := EndIndex downto StartIndex do - if (ColumnSpecs[I] = wtRelative) and (Multis[I] > 0) then - if Count > 1 then - begin - Inc(AddedMulti, Multis[I]); - Widths[I] := MulDiv(AddedMulti, RequiredWidthFactor, 100) - AddedWidth; - Inc(AddedWidth, Widths[I]); - Dec(Count); - end - else - begin - // add the remaining pixels to the first column's width. - Widths[I] := Required - AddedWidth; - break; - end; - end; - -var - // calculated values: - CellSpec: TWidthType; - CellMin, CellMax, CellPercent, CellRel: Integer; - SpannedMin, SpannedMax, SpannedMultis, SpannedPercents: Integer; - SpannedCounts: TIntegerPerWidthType; - - procedure IncreaseMinMaxWidthsEvenly(WidthType: TWidthType; StartIndex, EndIndex: Integer); - var - Untouched, I: Integer; - begin - if CellMin > SpannedMin then - begin - Untouched := SumOfNotType(WidthType, ColumnSpecs, MinWidths, StartIndex, EndIndex); - IncreaseWidthsEvenly(WidthType, MinWidths, StartIndex, EndIndex, CellMin - Untouched, SpannedMin - Untouched, SpannedCounts[WidthType]); - end; - if CellMax > SpannedMax then - begin - Untouched := SumOfNotType(WidthType, ColumnSpecs, MinWidths, StartIndex, EndIndex); - IncreaseWidthsEvenly(WidthType, MaxWidths, StartIndex, EndIndex, CellMax - Untouched, SpannedMax - Untouched, SpannedCounts[WidthType]); - end; - - // Prevent MinWidths from getting larger than MaxWidths, otherwise the calculation goes crazy - for I := StartIndex to EndIndex do - if MinWidths[I] > MaxWidths[I] then - MaxWidths[I] := MinWidths[I]; - end; - - procedure IncreaseMinMaxWidthsByMinMaxDelta(WidthType: TWidthType; StartIndex, EndIndex: Integer); - var - Deltas: TIntArray; - I: Integer; - begin - Deltas := SubArray(MaxWidths, MinWidths); - if CellMin > SpannedMin then - IncreaseWidthsByMinMaxDelta(WidthType, MinWidths, StartIndex, EndIndex, CellMin - SpannedMin, SpannedMax - SpannedMin, SpannedCounts[WidthType], Deltas); - if CellMax > SpannedMax then - IncreaseWidthsByMinMaxDelta(WidthType, MaxWidths, StartIndex, EndIndex, CellMax - SpannedMax, SpannedMax - SpannedMin, SpannedCounts[WidthType], Deltas); - - // Prevent MinWidths from getting larger than MaxWidths, otherwise the calculation goes crazy - for I := StartIndex to EndIndex do - if MinWidths[I] > MaxWidths[I] then - MaxWidths[I] := MinWidths[I]; - end; - -var - // - I, J, K, Span, EndIndex: Integer; - Cells: TCellList; - CellObj: TCellObjBase; - MaxSpans: TIntArray; - MaxSpan: Integer; - MultiCount: Integer; -begin - // initialize default widths - SetArray(ColumnCounts, 0); - if FColSpecs <> nil then - J := FColSpecs.Count - else - J := 0; - MultiCount := 0; - for I := 0 to NumCols - 1 do - begin - MinWidths[I] := 0; - MaxWidths[I] := 0; - Percents[I] := 0; - Multis[I] := 0; - ColumnSpecs[I] := wtNone; - if I < J then - with FColSpecs[I].FWidth do - begin - ColumnSpecs[I] := VType; - Inc(ColumnCounts[VType]); - case VType of - wtAbsolute: - begin - MinWidths[I] := Value; - MaxWidths[I] := Value; - end; - - wtPercent: - Percents[I] := Value; - - wtRelative: - begin - Multis[I] := Value; - if Value > 0 then - Inc(MultiCount); - end; - end; - end; - end; - - //SetLength(Heights, 0); - Span := 1; - - //BG, 29.01.2011: data for loop termination and to speed up looping through - // very large tables with large spans. - // A table with 77 rows and 265 columns and a MaxSpan of 265 in 2 rows - // was processed in 3 seconds before the tuning and 80ms afterwards. - MaxSpan := 1; - SetLength(MaxSpans, Rows.Count); - SetArray(MaxSpans, MaxSpan); - repeat - for J := 0 to Rows.Count - 1 do - begin - //BG, 29.01.2011: tuning: process rows only, if there is at least 1 cell to process left. - if Span > MaxSpans[J] then - continue; - - Cells := Rows[J]; - //BG, 29.01.2011: tuning: process up to cells only, if there is at least 1 cell to process left. - for I := 0 to Cells.Count - Span do - begin - CellObj := Cells[I]; - if CellObj = nil then - continue; - - if CellObj.ColSpan = Span then - begin - // get min and max width of this cell: - CellObj.Cell.MinMaxWidth(Canvas, CellMin, CellMax); - CellPercent := 0; - CellRel := 0; - with CellObj.SpecWd do - begin - CellSpec := VType; - case VType of - wtPercent: - CellPercent := Value; - - wtAbsolute: - begin - // BG, 07.10.2012: issue 55: wrong CellMax calculation - //CellMin := Max(CellMin, Value); // CellMin should be at least the given absolute value - //CellMax := Min(CellMax, Value); // CellMax should be at most the given absolute value - CellMax := Value; // CellMax should be at most the given absolute value - CellMax := Max(CellMax, CellMin); // CellMax should be at least CellMin - end; - - wtRelative: - CellRel := Value; - end; - end; - Inc(CellMin, CellSpacingHorz + CellObj.HzSpace); - Inc(CellMax, CellSpacingHorz + CellObj.HzSpace); - - if Span = 1 then - begin - MinWidths[I] := Max(MinWidths[I], CellMin); - MaxWidths[I] := Max(MaxWidths[I], CellMax); - Percents[I] := Max(Percents[I], CellPercent); {collect percents} - Multis[I] := Max(Multis[I], CellRel); - UpdateColumnSpec(ColumnCounts, ColumnSpecs[I], CellSpec); - end - else - begin - EndIndex := I + Span - 1; - - // Get current min and max width of spanned columns. - SpannedMin := Sum(MinWidths, I, EndIndex); - SpannedMax := Sum(MaxWidths, I, EndIndex); - - if (CellMin > SpannedMin) or (CellMax > SpannedMax) then - begin - { As spanning cell is wider than sum of spanned columns, we must widen the spanned columns. - - How to add the excessive width: - a) If cell spans columns without any width specifications, then spread excessive width evenly to these columns. - b) If cell spans columns with relative specifications, then spread excessive width according - to relative width values to these columns. - c) If cell spans columns with precentage specifications, then spread excessive width relative - to percentages to these columns. - d) If cell spans columns with absolute specifications only, then spread excessive width relative - to difference between MinWidth and MaxWidth to all columns. - - see also: - - http://www.w3.org/TR/html401/struct/tables.html - - http://www.w3.org/TR/html401/appendix/notes.html#h-B.5.2 - Notice: - - Fixed Layout: experiments showed that IExplore and Firefox *do* respect width attributes of and - even if there was a definition although W3C specified differently. - } - CountsPerType(SpannedCounts, ColumnSpecs, I, EndIndex); - - if CellPercent > 0 then - begin - SpannedPercents := SumOfType(wtPercent, ColumnSpecs, Percents, I, EndIndex); - if SpannedPercents > CellPercent then - continue; - - // BG, 05.02.2012: spread excessive percentage over unspecified columns: - if SpannedCounts[wtNone] > 0 then - begin - // a) There is at least 1 column without any width constraint: Widen this/these. - IncreaseWidthsEvenly(wtNone, Percents, I, EndIndex, CellPercent - SpannedPercents, 0, SpannedCounts[wtNone]); - for K := I to EndIndex do - ColumnSpecs[K] := wtPercent; - continue; - end - end; - - if SpannedCounts[wtNone] > 0 then - begin - // a) There is at least 1 column without any width constraint: Widen this/these. - IncreaseMinMaxWidthsEvenly(wtNone, I, EndIndex); - end - else if SpannedCounts[wtRelative] > 0 then - begin - // b) There is at least 1 column with relative width: Widen this/these. - SpannedMultis := SumOfType(wtRelative, ColumnSpecs, Multis, I, EndIndex); - if SpannedMultis > 0 then - begin - if CellMin > SpannedMin then - IncreaseWidthsRelatively(MinWidths, I, EndIndex, CellMin, SpannedMultis, True); - if CellMax > SpannedMax then - IncreaseWidthsRelatively(MaxWidths, I, EndIndex, CellMax, SpannedMultis, True); - end - else if SpannedMax > SpannedMin then - begin - // All spanned columns are at 0*. - // Widen columns proportional to difference between yet evaluated min and max width. - // This ought to fill the table with least height requirements. - IncreaseMinMaxWidthsByMinMaxDelta(wtRelative, I, EndIndex); - end - else - begin - // All spanned columns are at 0* and minimum = maximum. Spread excess evenly. - IncreaseMinMaxWidthsEvenly(wtRelative, I, EndIndex); - end; - end - else if SpannedCounts[wtPercent] > 0 then - begin - // c) There is at least 1 column with percentage width: Widen this/these. - if SpannedMax > SpannedMin then - begin - // Widen columns proportional to difference between yet evaluated min and max width. - // This ought to fill the table with least height requirements. - IncreaseMinMaxWidthsByMinMaxDelta(wtPercent, I, EndIndex); - end - else - begin - SpannedPercents := SumOfType(wtPercent, ColumnSpecs, Percents, I, EndIndex); - if SpannedPercents > 0 then - begin - // Spread excess to columns proportionally to their percentages. - // This ought to keep smaller columns small. - if CellMin > SpannedMin then - IncreaseWidthsByPercentage(MinWidths, I, EndIndex, CellMin, SpannedMin, SpannedPercents, SpannedCounts[wtPercent]); - if CellMax > SpannedMax then - IncreaseWidthsByPercentage(MaxWidths, I, EndIndex, CellMax, SpannedMax, SpannedPercents, SpannedCounts[wtPercent]); - end - else - begin - // All spanned columns are at 0% and minimum = maximum. Spread excess evenly. - IncreaseMinMaxWidthsEvenly(wtPercent, I, EndIndex); - end; - end; - end - else - begin - // d) All columns have absolute widths: Widen these. - IncreaseMinMaxWidthsEvenly(wtAbsolute, I, EndIndex); - end; - end; - end; - end - else - begin - //BG, 29.01.2011: at this point: CellObj.ColSpan <> Span - if Span = 1 then - begin - //BG, 29.01.2011: at this point: in the first loop with a CellObj.ColSpan > 1. - - // Collect data for termination and tuning. - if MaxSpans[J] < CellObj.ColSpan then - begin - MaxSpans[J] := CellObj.ColSpan; // data for tuning - if MaxSpan < MaxSpans[J] then - MaxSpan := MaxSpans[J]; // data for termination - end; - end; - end; - end; - end; - Inc(Span); - until Span > MaxSpan; - - if MultiCount > 0 then - begin - UpdateRelativeWidths(MinWidths, ColumnSpecs, 0, NumCols - 1); - UpdateRelativeWidths(MaxWidths, ColumnSpecs, 0, NumCols - 1); - end; -end; - -{----------------THtmlTable.MinMaxWidth} - -procedure THtmlTable.MinMaxWidth(Canvas: TCanvas; out Min, Max: Integer); -begin - Initialize; {in case it hasn't been done} - GetMinMaxWidths(Canvas); - Min := Math.Max(Sum(MinWidths) + CellSpacingHorz, tblWidthAttr); - Max := Math.Max(Sum(MaxWidths) + CellSpacingHorz, tblWidthAttr); - - if FOwnerTableBlock.MargArray[piMinWidth] > 0 then - begin - Min := Math.Max(Min, FOwnerTableBlock.MargArray[piMinWidth]); - Max := Math.Max(Max, FOwnerTableBlock.MargArray[piMinWidth]); - end; - - if FOwnerTableBlock.MargArray[piMaxWidth] > 0 then - begin - Min := Math.Min(Min, FOwnerTableBlock.MargArray[piMaxWidth]); - Max := Math.Min(Max, FOwnerTableBlock.MargArray[piMaxWidth]); - end; -end; - -{----------------THtmlTable.DrawLogic} - -function THtmlTable.DrawLogic1(Canvas: TCanvas; X, Y, XRef, YRef, AWidth, AHeight, BlHt: Integer; IMgr: TIndentManager; - var MaxWidth, Curs: Integer): Integer; - - function FindTableWidth: Integer; - - procedure IncreaseWidths(WidthType: TWidthType; MinWidth, NewWidth, Count: Integer); - var - Deltas: TIntArray; - D, W: Integer; - begin - Deltas := SubArray(MaxWidths, MinWidths); - D := SumOfType(WidthType, ColumnSpecs, Deltas, 0, NumCols - 1); - if D <> 0 then - IncreaseWidthsByMinMaxDelta(WidthType, Widths, 0, NumCols - 1, NewWidth - MinWidth, D, Count, Deltas) - else - begin - W := SumOfType(WidthType, ColumnSpecs, Widths, 0, NumCols -1); - IncreaseWidthsByWidth(WidthType, Widths, 0, NumCols - 1, NewWidth - MinWidth + W, W, Count); - end; - end; - - procedure CalcPercentDeltas(var PercentDeltas: TIntArray; NewWidth: Integer); - var - I: Integer; - Percent, PercentDelta: Integer; - begin - Percent := Max(1000, Sum(Percents)); - for I := NumCols - 1 downto 0 do - if ColumnSpecs[I] = wtPercent then - begin - PercentDelta := Trunc(1000 * (Percents[I] / Percent - MinWidths[I] / NewWidth)); - if PercentDelta > 0 then - PercentDeltas[I] := PercentDelta; - end; - end; - - procedure IncreaseWidthsByPercentage(var Widths: TIntArray; - const PercentDeltas: TIntArray; - StartIndex, EndIndex, Required, Spanned, Percent, Count: Integer); - // Increases width of columns relative to given percentages. - var - Excess, AddedExcess, AddedPercent, I, Add, MaxColWidth, SpecPercent: Integer; - begin - SpecPercent := Max(1000, Sum(Percents)); - Excess := Required - Spanned; - AddedExcess := 0; - AddedPercent := 0; - for I := EndIndex downto StartIndex do - if (ColumnSpecs[I] = wtPercent) and (PercentDeltas[I] > 0) then - if Count > 1 then - begin - Inc(AddedPercent, PercentDeltas[I]); - Add := MulDiv(Excess, AddedPercent, Percent) - AddedExcess; - MaxColWidth := MulDiv(Required, Percents[I], SpecPercent); - Widths[I] := Min(Widths[I] + Add, MaxColWidth); - Inc(AddedExcess, Add); - Dec(Count); - end - else - begin - // add the remaining pixels to the first column's width. - Add := Excess - AddedExcess; - MaxColWidth := MulDiv(Required, Percents[I], SpecPercent); - Widths[I] := Min(Widths[I] + Add, MaxColWidth); - break; - end; - end; - - var - Specified: Boolean; - NewWidth, MaxWidth, MinWidth, D, W, I: Integer; - Counts: TIntegerPerWidthType; - PercentDeltas: TIntArray; - PercentAbove0Count: Integer; - PercentDeltaAbove0Count: Integer; - begin - Specified := tblWidthAttr > 0; - if Specified then - NewWidth := tblWidthAttr - else - NewWidth := IMgr.RightSide(Y) - IMgr.LeftIndent(Y); - Dec(NewWidth, CellSpacingHorz); - - Initialize; - - {Figure the width of each column} - GetMinMaxWidths(Canvas); - - MinWidth := Sum(MinWidths); - if FOwnerTableBlock.MargArray[piMinWidth] > 0 then - MinWidth := Max(MinWidth, FOwnerTableBlock.MargArray[piMinWidth]); - - MaxWidth := Sum(MaxWidths); - if FOwnerTableBlock.MargArray[piMaxWidth] > 0 then - MaxWidth := Min(MaxWidth, FOwnerTableBlock.MargArray[piMaxWidth]); - - {fill in the Widths array} - if MinWidth > NewWidth then - // The minimum table width is too wide. Thus use minimum widths, table might expand. - Widths := Copy(MinWidths) - else - begin - // Table fits into NewWidth. - - Counts[wtPercent] := 0; - PercentAbove0Count := 0; - for I := 0 to NumCols - 1 do - if ColumnSpecs[I] = wtPercent then - begin - Inc(Counts[wtPercent]); - if Percents[I] > 0 then - Inc(PercentAbove0Count); - end; - - Widths := Copy(MinWidths); - - // As minimum widths fit into table try to preserve given absolute widths: - Counts[wtAbsolute] := 0; - W := 0; - for I := 0 to NumCols - 1 do - begin - case ColumnSpecs[I] of - wtAbsolute: - begin - Widths[i] := MaxWidths[i]; - Inc(Counts[wtAbsolute]); - end; - end; - Inc(W, Widths[i]); - end; - - if W > NewWidth then - begin - // Given absolute widths plus minimum widths of other columns do not fit into table! - // Thus reduce the absolute widths as less as possible: - - IncreaseWidths(wtAbsolute, W, NewWidth, Counts[wtAbsolute]); - end - else - begin - if (PercentAbove0Count > 0) and (NewWidth > 0) then - begin - // Calculate widths with respect to percentage specifications. - // Don't shrink Column i below MinWidth[i]! Therefor spread exessive space - // trying to fit the percentage demands. - // If there are more than 100% percent reduce linearly to 100% (including - // the corresponding percentages of the MinWidth of all other columns). - SetLength(PercentDeltas, NumCols); - CalcPercentDeltas(PercentDeltas, NewWidth); - - PercentDeltaAbove0Count := 0; - for I := 0 to NumCols - 1 do - if PercentDeltas[I] > 0 then - Inc(PercentDeltaAbove0Count); - - IncreaseWidthsByPercentage(Widths, PercentDeltas, 0, NumCols - 1, NewWidth, MinWidth, Sum(PercentDeltas), PercentDeltaAbove0Count); - end; - MinWidth := Sum(Widths); - - if MinWidth > NewWidth then - // Table (NewWidth) is too small for given percentage specifications. - // Shrink percentage columns to fit exactly into NewWidth. All other columns are at minimum. - IncreaseWidths(wtPercent, MinWidth, NewWidth, Counts[wtPercent]) - else if not Specified and (MaxWidth <= NewWidth) then - // Table width not specified and maximum widths fits into available width, table might be smaller than NewWidth - Widths := Copy(MaxWidths) - else if MinWidth < NewWidth then - begin - // Expand columns to fit exactly into NewWidth. - // Prefer widening columns without or with relative specification. - CountsPerType(Counts, ColumnSpecs, 0, NumCols - 1); - - if Counts[wtNone] > 0 then - begin - // a) There is at least 1 column without any width constraint: modify this/these. - IncreaseWidths(wtNone, MinWidth, NewWidth, Counts[wtNone]); - end - else if Counts[wtRelative] > 0 then - begin - // b) There is at least 1 column with relative width: modify this/these. - W := NewWidth - MinWidth; - D := SumOfType(wtRelative, ColumnSpecs, Widths, 0, NumCols - 1); - IncreaseWidthsRelatively(Widths, 0, NumCols - 1, D + W, Sum(Multis), False); - end - else if Counts[wtPercent] > 0 then - begin - // c) There is at least 1 column with percentage width: modify this/these. - IncreaseWidths(wtPercent, MinWidth, NewWidth, Counts[wtPercent]); - end - else - begin - // d) All columns have absolute widths: modify relative to current width. - IncreaseWidths(wtAbsolute, MinWidth, NewWidth, Counts[wtAbsolute]); - end; - end; - end; - end; - {Return Table Width} - Result := CellSpacingHorz + Sum(Widths); - end; - - function FindTableHeight: Integer; - - procedure FindRowHeights(Canvas: TCanvas; AHeight: Integer); - var - I, J, K, H, Span, TotalMinHt, TotalDesHt, AvailHt, AddOn, Sum, AddedOn, Desired, UnSpec: Integer; - More, Mr, IsSpeced: Boolean; - MinHts, DesiredHts: TIntArray; - SpecHts: array of Boolean; - F: double; - begin - if Rows.Count = 0 then - Exit; - - Dec(AHeight, CellSpacingVert); {calculated heights will include one cellspacing each, - this removes that last odd cellspacing} - SetLength(Heights, Rows.Count); - SetLength(DesiredHts, Rows.Count); - SetLength(MinHts, Rows.Count); - SetLength(SpecHts, Rows.Count); - for I := 0 to Rows.Count - 1 do - begin - Heights[I] := 0; - DesiredHts[I] := 0; - MinHts[I] := 0; - SpecHts[I] := False; - end; - {Find the height of each row allowing for RowSpans} - Span := 1; - More := True; - AvailHt := Max(0, AHeight - Rows.Count * CellSpacingVert); - while More do - begin - More := False; - for J := 0 to Rows.Count - 1 do - with Rows[J] do - begin - if J + Span > Rows.Count then - Break; {otherwise will overlap} - H := DrawLogicA(Canvas, Widths, Span, CellSpacingHorz, CellSpacingVert, AvailHt, Rows.Count, Desired, IsSpeced, Mr) + CellSpacingVert; - Inc(Desired, CellspacingVert); - More := More or Mr; - if Span = 1 then - begin - MinHts[J] := H; - DesiredHts[J] := Desired; - SpecHts[J] := SpecHts[J] or IsSpeced; - end - else if H > CellspacingVert then {if H=Cellspacing then no rowspan for this span} - begin - TotalMinHt := 0; {sum up the heights so far for the rows involved} - TotalDesHt := 0; - for K := J to J + Span - 1 do - begin - Inc(TotalMinHt, MinHts[K]); - Inc(TotalDesHt, DesiredHts[K]); - SpecHts[K] := SpecHts[K] or IsSpeced; - end; - if H > TotalMinHt then {apportion the excess over the rows} - begin - Addon := ((H - TotalMinHt) div Span); - AddedOn := 0; - for K := J to J + Span - 1 do - begin - Inc(MinHts[K], Addon); - Inc(AddedOn, Addon); - end; - Inc(MinHts[J + Span - 1], (H - TotalMinHt) - AddedOn); {make up for round off error} - end; - if Desired > TotalDesHt then {apportion the excess over the rows} - begin - Addon := ((Desired - TotalDesHt) div Span); - AddedOn := 0; - for K := J to J + Span - 1 do - begin - Inc(DesiredHts[K], Addon); - Inc(AddedOn, Addon); - end; - Inc(DesiredHts[J + Span - 1], (Desired - TotalDesHt) - AddedOn); {make up for round off error} - end; - end; - end; - Inc(Span); - end; - - TotalMinHt := 0; - TotalDesHt := 0; - UnSpec := 0; - for I := 0 to Rows.Count - 1 do - begin - Inc(TotalMinHt, MinHts[I]); - Inc(TotalDesHt, DesiredHts[I]); - if not SpecHts[I] then - Inc(UnSpec); - end; - - if TotalMinHt >= AHeight then - Heights := Copy(MinHts) - else if TotalDesHt < AHeight then - begin - if UnSpec > 0 then - begin {expand the unspeced rows to fit} - Heights := Copy(DesiredHts); - Addon := (AHeight - TotalDesHt) div UnSpec; - Sum := 0; - for I := 0 to Rows.Count - 1 do - if not SpecHts[I] then - begin - Dec(UnSpec); - if UnSpec > 0 then - begin - Inc(Heights[I], AddOn); - Inc(Sum, Addon); - end - else - begin {last item, complete everything} - Inc(Heights[I], AHeight - TotalDesHt - Sum); - Break; - end; - end; - end - else if TotalDesHt > 0 then - begin {expand desired hts to fit} - Sum := 0; - F := AHeight / TotalDesHt; - for I := 0 to Rows.Count - 2 do - begin - Heights[I] := Round(F * DesiredHts[I]); - Inc(Sum, Heights[I]); - end; - Heights[Rows.Count - 1] := AHeight - Sum; {last row is the difference} - end - end - else if TotalDesHt - TotalMinHt <> 0 then - begin - Sum := 0; - F := (AHeight - TotalMinHt) / (TotalDesHt - TotalMinHt); - for I := 0 to Rows.Count - 2 do - begin - Heights[I] := MinHts[I] + Round(F * (DesiredHts[I] - MinHts[I])); - Inc(Sum, Heights[I]); - end; - Heights[Rows.Count - 1] := AHeight - Sum; - end; - end; - - var - I, J, K: Integer; - CellObj: TCellObj; - HasBody: Boolean; - begin - // Find Row Heights - if (CycleNumber <> Document.CycleNumber) or (Length(Heights) = 0) then - FindRowHeights(Canvas, AHeight) - //else if Document.InLogic2 and (Document.TableNestLevel <= 10) then - // FindRowHeights(Canvas, AHeight) - ; - - Result := 0; - HeaderHeight := 0; - HeaderRowCount := 0; - FootHeight := 0; - FootStartRow := -1; - HasBody := False; - for J := 0 to Rows.Count - 1 do - with Rows[J] do - begin - RowHeight := Heights[J]; - case RowType of - THead: - begin - Inc(HeaderRowCount); - Inc(HeaderHeight, RowHeight); - end; - - TFoot: - begin - if FootStartRow = -1 then - begin - FootStartRow := J; - FootOffset := Result; - end; - Inc(FootHeight, RowHeight); - end; - - TBody: - HasBody := True; - end; - RowSpanHeight := 0; - Inc(Result, RowHeight); - for I := 0 to Count - 1 do - if Items[I] is TCellObj then - begin - CellObj := TCellObj(Items[I]); - with CellObj do - begin {find the actual height, Ht, of each cell} - FHt := 0; - for K := J to Min(J + RowSpan - 1, Rows.Count - 1) do - Inc(FHt, Heights[K]); - if RowSpanHeight < FHt then - RowSpanHeight := FHt; - end; - end; - {DrawLogicB is only called in nested tables if the outer table is calling DrawLogic2} - if Document.TableNestLevel = 1 then - Document.InLogic2 := True; - try - if Document.InLogic2 then - DrawLogicB(Canvas, Y, CellSpacingHorz,CellSpacingVert, Curs); - finally - if Document.TableNestLevel = 1 then - Document.InLogic2 := False; - end; - Inc(Y, RowHeight); - end; - HeadOrFoot := ((HeaderHeight > 0) or (FootHeight > 0)) and HasBody; - Inc(Result, CellSpacingVert); - end; - - procedure DrawLogicYIndent; - var - J: Integer; - begin - for J := 0 to Rows.Count - 1 do - with Rows[J] do - begin - RowHeight := Heights[J]; - {DrawLogicB is only called in nested tables if the outer table is calling DrawLogic2} - DrawLogicB(Canvas, Y, CellSpacingHorz,CellSpacingVert, Curs); - Inc(Y, RowHeight); - end; - end; - -var - TopY: Integer; - FirstLinePtr: PInteger; -begin {THtmlTable.DrawLogic} -{$IFDEF JPM_DEBUGGING_LOGIC} - CodeSite.EnterMethod(Self, Format('THtmlTable.DrawLogic1 "%s"', [TagClass])); - CodeSite.SendFmtMsg('AWidth, AHeight = [%4d, %4d]', [AWidth, AHeight]); -{$IFDEF JPM_DEBUGGING_LOGIC1} - CodeSite.SendFmtMsg('X, XRef = [%4d, %4d]', [X, XRef]); - CodeSite.SendFmtMsg('Y, YRef = [%4d, %4d]', [Y, YRef]); - CodeSite.SendFmtMsg('BlHt = [%d]',[BlHt]); - if Assigned(IMgr) then begin - CodeSite.SendFmtMsg('IMgr.LfEdge = [%d]',[ IMgr.LfEdge ] ); - CodeSite.SendFmtMsg('IMgr.Width = [%d]',[ IMgr.Width ] ); - CodeSite.SendFmtMsg('IMgr.ClipWidth = [%d]',[ IMgr.ClipWidth ] ); - end else begin - CodeSite.SendMsg('IMgr = nil'); - end; - CodeSite.SendFmtMsg('MaxWidth = [%d]',[MaxWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); -{$ENDIF} -{$ENDIF} - Inc(Document.TableNestLevel); - try - if (CycleNumber <> Document.CycleNumber) or (YDraw <> Y) or (ContentTop <> Y) or (DrawTop <> Y) or (StartCurs <> Curs) or (Length(Heights) = 0) - then - begin - YDraw := Y; - TopY := Y; - ContentTop := Y; - DrawTop := Y; - StartCurs := Curs; - if Assigned(Document.FirstLineHtPtr) and {used for List items} - (Document.FirstLineHtPtr^ = 0) then - FirstLinePtr := Document.FirstLineHtPtr {save for later} - else - FirstLinePtr := nil; - - TableWidth := FindTableWidth; -{$ifdef JPM_DEBUGGING_LOGIC} - CodeSite.SendFmtMsg('Found TableWidth = %d', [TableWidth]); -{$endif} - TableHeight := FindTableHeight; -{$ifdef JPM_DEBUGGING_LOGIC} - CodeSite.SendFmtMsg('Found TableHeight = %d', [TableHeight]); -{$endif} - // Notice: SectionHeight = TableHeight - Len := Curs - StartCurs; - DrawHeight := TableHeight; - ContentBot := TopY + TableHeight; - DrawBot := TopY + DrawHeight; - - try - if Assigned(FirstLinePtr) then - FirstLinePtr^ := YDraw + SectionHeight; - except - end; - - CycleNumber := Document.CycleNumber; - end - else - begin - if Document.TableNestLevel = 1 then - Document.InLogic2 := True; - try - if Document.InLogic2 then - DrawLogicYIndent - else - Curs := StartCurs + Len; - finally - if Document.TableNestLevel = 1 then - Document.InLogic2 := False; - end; -{$ifdef JPM_DEBUGGING_LOGIC} - CodeSite.SendFmtMsg('Stored TableWidth = %d, TableHeight = %d', [TableWidth, TableHeight]); -{$endif} - end; - finally - MaxWidth := TableWidth; - Result := TableHeight; - Dec(Document.TableNestLevel); -{$ifdef JPM_DEBUGGING_LOGIC} -{$ifdef JPM_DEBUGGING_LOGIC1} - if Assigned(IMgr) then - begin - CodeSite.SendFmtMsg('IMgr.LfEdge = [%d]',[ IMgr.LfEdge ] ); - CodeSite.SendFmtMsg('IMgr.Width = [%d]',[ IMgr.Width ] ); - CodeSite.SendFmtMsg('IMgr.ClipWidth = [%d]',[ IMgr.ClipWidth ] ); - end - else - begin - CodeSite.SendMsg('IMgr = nil'); - end; -{$ENDIF} - CodeSite.SendFmtMsg('MaxWidth = [%d]',[MaxWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.SendFmtMsg('Result = [%d]',[Result]); - CodeSite.ExitMethod(Self, Format('THtmlTable.DrawLogic1 "%s"', [TagClass])); -{$ENDIF} - end; -end; - -{----------------THtmlTable.Draw} - -function THtmlTable.Draw1(Canvas: TCanvas; const ARect: TRect; IMgr: TIndentManager; X, XRef, YRef: Integer): Integer; - - procedure DrawTable(XX, YY, YOffset: Integer); - var - I: Integer; - begin - for I := 0 to Rows.Count - 1 do - YY := Rows[I].Draw(Canvas, Document, ARect, Widths, - XX, YY, YOffset, CellSpacingHorz,CellSpacingVert, BorderWidth > 0, BorderColorLight, - BorderColorDark, I); - end; - - procedure DrawTableP(XX, YY, YOffset: Integer); - {Printing table with thead and/or tfoot} - var - TopBorder, BottomBorder: Integer; - SavePageBottom: Integer; - Spacing, HeightNeeded: Integer; - - procedure DrawNormal; - var - Y, I: Integer; - begin - Y := YY; - Document.PrintingTable := Self; - if Document.PageBottom - Y >= TableHeight + BottomBorder then - begin - for I := 0 to Rows.Count - 1 do {do whole table now} - YY := Rows[I].Draw(Canvas, Document, ARect, Widths, - XX, YY, YOffset, CellSpacingHorz,CellSpacingVert, BorderWidth > 0, BorderColorLight, - BorderColorDark, I); - Document.PrintingTable := nil; - end - else - begin {see if enough room on this page for header, 1 row, footer} - if HeadOrFoot then - begin - Spacing := CellSpacingVert div 2; - HeightNeeded := HeaderHeight + FootHeight + Rows[HeaderRowCount].RowHeight; - if (Y - YOffset > ARect.Top) and (Y + HeightNeeded > Document.PageBottom) and - (HeightNeeded < ARect.Bottom - ARect.Top) then - begin {not enough room, start table on next page} - if YY + Spacing < Document.PageBottom then - begin - Document.PageShortened := True; - Document.PageBottom := YY + Spacing; - end; - exit; - end; - end; - {start table. it will not be complete and will go to next page} - SavePageBottom := Document.PageBottom; - Document.PageBottom := SavePageBottom - FootHeight - CellspacingVert - BottomBorder - 5; {a little to spare} - for I := 0 to Rows.Count - 1 do {do part of table} - YY := Rows[I].Draw(Canvas, Document, ARect, Widths, - XX, YY, YOffset, CellSpacingHorz, CellSpacingVert, BorderWidth > 0, BorderColorLight, - BorderColorDark, I); - BodyBreak := Document.PageBottom; - if FootStartRow >= 0 then - begin - TablePartRec.TablePart := DoFoot; - TablePartRec.PartStart := Y + FootOffset; - TablePartRec.PartHeight := FootHeight + Max(2 * CellspacingVert, CellspacingVert + 1) + BottomBorder; - Document.TheOwner.TablePartRec := TablePartRec; - end - else if HeaderHeight > 0 then - begin {will do header next} - //Document.PageBottom := SavePageBottom; - TablePartRec.TablePart := DoHead; - TablePartRec.PartStart := Y - TopBorder; - TablePartRec.PartHeight := HeaderHeight + TopBorder; - Document.TheOwner.TablePartRec := TablePartRec; - end; - Document.TheOwner.TablePartRec := TablePartRec; - end; - end; - - procedure DrawBody1; - var - Y, I: Integer; - begin - Y := YY; - if Document.PageBottom > Y + TableHeight + BottomBorder then - begin {can complete table now} - for I := 0 to Rows.Count - 1 do {do remainder of table now} - YY := Rows[I].Draw(Canvas, Document, ARect, Widths, - XX, YY, YOffset, CellSpacingHorz, CellSpacingVert, BorderWidth > 0, BorderColorLight, - BorderColorDark, I); - Document.TheOwner.TablePartRec.TablePart := Normal; - end - else - begin {will do part of the table now} - {Leave room for foot later} - Document.PageBottom := Document.PageBottom - FootHeight + Max(CellspacingVert, 1) - BottomBorder; - for I := 0 to Rows.Count - 1 do - YY := Rows[I].Draw(Canvas, Document, ARect, Widths, - XX, YY, YOffset, CellSpacingHorz, CellSpacingVert, BorderWidth > 0, BorderColorLight, - BorderColorDark, I); - BodyBreak := Document.PageBottom; - if FootStartRow >= 0 then - begin - TablePartRec.TablePart := DoFoot; - TablePartRec.PartStart := Y + FootOffset; - TablePartRec.PartHeight := FootHeight + Max(2 * CellspacingVert, CellspacingVert + 1) + BottomBorder; - Document.TheOwner.TablePartRec := TablePartRec; - end - else if HeaderHeight > 0 then - begin - TablePartRec.TablePart := DoHead; - TablePartRec.PartStart := Y - TopBorder; - TablePartRec.PartHeight := HeaderHeight + TopBorder; - Document.TheOwner.TablePartRec := TablePartRec; - end; - Document.TheOwner.TablePartRec := TablePartRec; - end; - end; - - procedure DrawBody2; - var - Y, I: Integer; - begin - Y := YY; - if Document.PageBottom > Y + TableHeight + BottomBorder then - begin - for I := 0 to Rows.Count - 1 do {do remainder of table now} - YY := Rows[I].Draw(Canvas, Document, ARect, Widths, - XX, YY, YOffset, CellSpacingHorz,CellSpacingVert, BorderWidth > 0, BorderColorLight, - BorderColorDark, I); - Document.TheOwner.TablePartRec.TablePart := Normal; - Document.PrintingTable := nil; - end - else - begin - SavePageBottom := Document.PageBottom; - for I := 0 to Rows.Count - 1 do {do part of table} - YY := Rows[I].Draw(Canvas, Document, ARect, Widths, - XX, YY, YOffset, CellSpacingHorz,CellSpacingVert, BorderWidth > 0, BorderColorLight, - BorderColorDark, I); - BodyBreak := Document.PageBottom; - if FootStartRow >= 0 then - begin - TablePartRec.TablePart := DoFoot; - TablePartRec.PartStart := Y + FootOffset; - TablePartRec.PartHeight := FootHeight + Max(2 * CellspacingVert, CellspacingVert + 1) + BottomBorder; - Document.TheOwner.TablePartRec := TablePartRec; - end - else if HeaderHeight > 0 then - begin - Document.PageBottom := SavePageBottom; - TablePartRec.TablePart := DoHead; - TablePartRec.PartStart := Y - TopBorder; - TablePartRec.PartHeight := HeaderHeight + TopBorder; - Document.TheOwner.TablePartRec := TablePartRec; - end; - Document.TheOwner.TablePartRec := TablePartRec; - end; - end; - - procedure DrawFoot; - var - Y, I: Integer; - begin - Y := YY; - YY := TablePartRec.PartStart; - if FootStartRow >= 0 then - for I := FootStartRow to Rows.Count - 1 do - YY := Rows[I].Draw(Canvas, Document, ARect, Widths, - XX, YY, YOffset, CellSpacingHorz, CellSpacingVert, BorderWidth > 0, BorderColorLight, - BorderColorDark, I); - if HeaderHeight > 0 then - begin - TablePartRec.TablePart := DoHead; - TablePartRec.PartStart := Y - TopBorder; - TablePartRec.PartHeight := HeaderHeight + TopBorder; - end - else - begin {No THead} - TablePartRec.TablePart := DoBody3; - TablePartRec.PartStart := BodyBreak - 1; - TablePartRec.FootHeight := FootHeight + Max(CellspacingVert, 1); - end; - Document.TheOwner.TablePartRec := TablePartRec; - end; - - procedure DrawHead; - var - I: Integer; - begin - for I := 0 to HeaderRowCount - 1 do - YY := Rows[I].Draw(Canvas, Document, ARect, Widths, - XX, YY, YOffset, CellSpacingHorz,CellSpacingVert, BorderWidth > 0, BorderColorLight, - BorderColorDark, I); - TablePartRec.TablePart := DoBody1; - TablePartRec.PartStart := BodyBreak - 1; - TablePartRec.FootHeight := FootHeight + Max(CellspacingVert, 1) + BottomBorder; - Document.TheOwner.TablePartRec := TablePartRec; - end; - - begin - if TTableBlock(OwnerBlock).TableBorder then - begin - TopBorder := BorderWidth; - BottomBorder := BorderWidth; - end - else - begin - TopBorder := OwnerBlock.MargArray[BorderTopWidth]; - BottomBorder := OwnerBlock.MargArray[BorderBottomWidth]; - end; - - case TablePartRec.TablePart of - Normal: DrawNormal; - DoBody1: DrawBody1; - DoBody2: DrawBody2; - DoFoot: DrawFoot; - DoHead: DrawHead; - end; - end; - -var - Y, YO, YOffset: Integer; -begin - Inc(Document.TableNestLevel); - try - Y := YDraw; - Result := Y + SectionHeight; - YOffset := Document.YOff; - YO := Y - YOffset; - - DrawX := X; - - //>-- DZ - DrawRect.Top := Y; - DrawRect.Left := X; - DrawRect.Right := DrawRect.Left + TableWidth; - DrawRect.Bottom := DrawRect.Top + DrawHeight; - //DrawY := Y; - - if (YO + DrawHeight >= ARect.Top) and (YO < ARect.Bottom) or Document.Printing then - if Document.Printing and (Document.TableNestLevel = 1) - and HeadOrFoot and (Y < Document.PageBottom) - and ((Document.PrintingTable = nil) or (Document.PrintingTable = Self)) - then - DrawTableP(X, Y, YOffset) - else - DrawTable(X, Y, YOffset); - finally - Dec(Document.TableNestLevel); - end; -end; - -{----------------THtmlTable.GetURL} - -function THtmlTable.GetURL(Canvas: TCanvas; X, Y: Integer; - out UrlTarg: TUrlTarget; out FormControl: TIDObject {TImageFormControlObj}; - out ATitle: ThtString): ThtguResultType; - - function GetTableURL(X: Integer; Y: Integer): ThtguResultType; - var - I, J, XX: Integer; - Row: TCellList; - CellObj: TCellObj; - begin - for J := 0 to Rows.Count - 1 do - begin - Row := Rows[J]; - XX := DrawX; - for I := 0 to Row.Count - 1 do - begin - if Row[I] is TCellObj then - begin - CellObj := TCellObj(Row[I]); - if (X >= XX) and (X < XX + CellObj.Wd) and (Y >= CellObj.Cell.DrawYY) and (Y < CellObj.Cell.DrawYY + CellObj.Ht) then - begin - Result := CellObj.Cell.GetUrl(Canvas, X, Y, UrlTarg, FormControl, ATitle); - Exit; - end; - end; - Inc(XX, Widths[I]); - end; - end; - Result := []; - end; - -begin - UrlTarg := nil; - FormControl := nil; - if (Y >= ContentTop) and (Y < ContentBot) and (X >= DrawX) and (X <= TableWidth + DrawX) then - Result := GetTableURL(X, Y) - else - Result := []; -end; - -{----------------THtmlTable.PtInObject} - -function THtmlTable.PtInObject(X, Y: Integer; out Obj: TObject; out IX, IY: Integer): Boolean; - - function GetTableObj(X: Integer; Y: Integer): Boolean; - var - I, J, XX: Integer; - Row: TCellList; - CellObj: TCellObj; - begin - for J := 0 to Rows.Count - 1 do - begin - Row := Rows[J]; - XX := DrawX; - for I := 0 to Row.Count - 1 do - begin - if Row[I] is TCellObj then - begin - CellObj := TCellObj(Row[I]); - if (X >= XX) and (X < XX + CellObj.Wd) and (Y >= CellObj.Cell.DrawYY) and (Y < CellObj.Cell.DrawYY + CellObj.Ht) then - begin - Result := CellObj.Cell.PtInObject(X, Y, Obj, IX, IY); - Exit; - end; - end; - Inc(XX, Widths[I]); - end; - end; - Result := False; - end; - -begin - if (Y >= ContentTop) and (Y < ContentBot) and (X >= DrawX) and (X <= TableWidth + DrawX) and GetTableObj(X, Y) then - Result := True - else - Result := inherited PtInObject(X, Y, Obj, IX, IY); -end; - -{----------------THtmlTable.FindCursor} - -function THtmlTable.FindCursor(Canvas: TCanvas; X, Y: Integer; - out XR, YR, CaretHt: Integer; out Intext: Boolean): Integer; - - function GetTableCursor(X, Y: Integer; out XR, YR, CaretHt: Integer; out Intext: Boolean): Integer; - var - I, J, XX: Integer; - Row: TCellList; - CellObj: TCellObj; - begin - for J := 0 to Rows.Count - 1 do - begin - Row := Rows[J]; - XX := DrawX; - for I := 0 to Row.Count - 1 do - begin - if Row[I] is TCellObj then - begin - CellObj := TCellObj(Row[I]); - if (X >= XX) and (X < XX + CellObj.Wd) and (Y >= CellObj.Cell.DrawYY) and (Y < CellObj.Cell.DrawYY + CellObj.Ht) then - begin - Result := CellObj.Cell.FindCursor(Canvas, X, Y, XR, YR, CaretHt, InText); - if Result >= 0 then - Exit; - end; - end; - Inc(XX, Widths[I]); - end; - end; - Result := -1; - end; - -begin - if (Y >= ContentTop) and (Y < ContentBot) and (X >= DrawX) and (X <= TableWidth + DrawX) then - Result := GetTableCursor(X, Y, XR, YR, CaretHt, InText) - else - Result := -1; -end; - -{----------------THtmlTable.CursorToXY} - -function THtmlTable.CursorToXY(Canvas: TCanvas; Cursor: Integer; var X, Y: Integer): Boolean; -{note: returned X value is not correct here but it isn't used} -var - I, J: Integer; - Row: TCellList; -begin - if (len > 0) and (Cursor >= StartCurs) and (Cursor < StartCurs + Len) then - for J := 0 to Rows.Count - 1 do - begin - Row := Rows[J]; - for I := 0 to Row.Count - 1 do - begin - if Row[I] is TCellObj then - begin - Result := TCellObj(Row[I]).Cell.CursorToXy(Canvas, Cursor, X, Y); - if Result then - Exit; - end; - end; - end; - - Result := False; -end; - -{----------------THtmlTable.GetChAtPos} - -function THtmlTable.GetChAtPos(Pos: Integer; out Ch: WideChar; out Obj: TSectionBase): Boolean; -var - I, J: Integer; - Row: TCellList; -begin - Obj := nil; - if (len > 0) and (Pos >= StartCurs) and (Pos < StartCurs + Len) then - for J := 0 to Rows.Count - 1 do - begin - Row := Rows[J]; - for I := 0 to Row.Count - 1 do - begin - if Row[I] is TCellObj then - begin - Result := TCellObj(Row[I]).Cell.GetChAtPos(Pos, Ch, Obj); - if Result then - Exit; - end; - end; - end; - - Result := False; -end; - -{----------------THtmlTable.FindString} - -function THtmlTable.FindString(From: Integer; const ToFind: UnicodeString; MatchCase: Boolean): Integer; -var - I, J: Integer; - Row: TCellList; -begin - for J := 0 to Rows.Count - 1 do - begin - Row := Rows[J]; - for I := 0 to Row.Count - 1 do - begin - if Row[I] is TCellObj then - begin - Result := TCellObj(Row[I]).Cell.FindString(From, ToFind, MatchCase); - if Result >= 0 then - Exit; - end; - end; - end; - Result := -1; -end; - -{----------------THtmlTable.FindStringR} - -function THtmlTable.FindStringR(From: Integer; const ToFind: UnicodeString; MatchCase: Boolean): Integer; -var - I, J: Integer; - Row: TCellList; -begin - for J := Rows.Count - 1 downto 0 do - begin - Row := Rows[J]; - for I := Row.Count - 1 downto 0 do - begin - if Row[I] is TCellObj then - begin - Result := TCellObj(Row[I]).Cell.FindStringR(From, ToFind, MatchCase); - if Result >= 0 then - Exit; - end; - end; - end; - Result := -1; -end; - -{----------------THtmlTable.FindSourcePos} - -function THtmlTable.FindSourcePos(DocPos: Integer): Integer; -var - I, J: Integer; - Row: TCellList; -begin - for J := 0 to Rows.Count - 1 do - begin - Row := Rows[J]; - for I := 0 to Row.Count - 1 do - begin - if Row[I] is TCellObj then - begin - Result := TCellObj(Row[I]).Cell.FindSourcePos(DocPos); - if Result >= 0 then - Exit; - end; - end; - end; - Result := -1; -end; - -{----------------THtmlTable.FindDocPos} - -function THtmlTable.FindDocPos(SourcePos: Integer; Prev: Boolean): Integer; -var - I, J: Integer; - Row: TCellList; -begin - if not Prev then - for J := 0 to Rows.Count - 1 do - begin - Row := Rows[J]; - if Row <> nil then - for I := 0 to Row.Count - 1 do - begin - if Row[I] is TCellObj then - begin - Result := TCellObj(Row[I]).Cell.FindDocPos(SourcePos, Prev); - if Result >= 0 then - Exit; - end; - end; - end - else {Prev , iterate in reverse} - for J := Rows.Count - 1 downto 0 do - begin - Row := Rows[J]; - if Row <> nil then - for I := Row.Count - 1 downto 0 do - begin - if Row[I] is TCellObj then - begin - Result := TCellObj(Row[I]).Cell.FindDocPos(SourcePos, Prev); - if Result >= 0 then - Exit; - end; - end; - end; - Result := -1; -end; - -{----------------THtmlTable.CopySelectedText} - -procedure THtmlTable.CopySelectedText; -var - I, J: Integer; - Row: TCellList; -begin - for J := 0 to Rows.Count - 1 do - begin - Row := Rows[J]; - for I := 0 to Row.Count - 1 do - if Row[I] is TCellObj then - TCellObj(Row[I]).Cell.CopySelectedText; - end; -end; - -//-- BG ---------------------------------------------------------- 01.12.2013 -- -constructor TSection.Create(Parent: TCellBasic); -begin - inherited Create(Parent, nil, nil); - FDisplay := pdInline; // A section is always inline as the section is intended to handle consecutive inline elements. - FBuff := PWideChar(BuffS); - Fonts := TFontList.Create; - Images := TSizeableObjList.Create; - FormControls := TFormControlObjList.Create(False); - Lines := TLineRecList.Create; -end; - -{----------------TSection.Create} - -constructor TSection.Create(Parent: TCellBasic; Attr: TAttributeList; Prop: TProperties; AnURL: TUrlTarget; FirstItem: Boolean); -var - FO: TFontObj; -// T: TAttribute; - S, C: ThtString; -// Clr: ThtClearStyle; - Percent: Boolean; -begin -{$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'TSection.Create'); -{$IFDEF JPM_DEBUGGING_STYLES} - StyleUn.LogProperties(Prop,'Prop'); - CodeSite.AddSeparator; -{$ENDIF} -{$ENDIF} - if Attr <> nil then - begin - S := Attr.TheID; - C := Attr.TheClass; - end; - inherited Create(Parent, Attr, Prop, S, C); - if FDisplay = pdUnassigned then - FDisplay := pdInline; - FBuff := PWideChar(BuffS); - Fonts := TFontList.Create; - Images := TSizeableObjList.Create; - FormControls := TFormControlObjList.Create(False); - Lines := TLineRecList.Create; - - FO := TFontObj.Create(Self, Prop.Font, 0); - FO.Title := Prop.PropTitle; - if Assigned(AnURL) and (Length(AnURL.Url) > 0) then - begin - FO.CreateFIArray; - Prop.GetFontInfo(FO.FIArray); - FO.ConvertFont(FO.FIArray.Ar[LFont]); - FO.UrlTarget.Assign(AnUrl); - Document.LinkList.Add(FO); -{$IFNDEF NoTabLink} - if not Document.StopTab then - FO.CreateTabControl(AnUrl.TabIndex); -{$ENDIF} - end; - Fonts.Add(FO); - - LineHeight := Prop.GetLineHeight(Abs(FO.TheFont.Height)); - if FirstItem then - begin - FirstLineIndent := Prop.GetTextIndent(Percent); - if Percent then - FLPercent := Min(FirstLineIndent, 90); - end; - - if Prop.Props[TextAlign] = 'right' then - Justify := Right - else if Prop.Props[TextAlign] = 'center' then - Justify := Centered - else if Prop.Props[TextAlign] = 'justify' then - Justify := FullJustify - else - Justify := Left; - - BreakWord := Prop.Props[WordWrap] = 'break-word'; - - if Self is TPreFormated then - WhiteSpaceStyle := wsPre - else if Document.NoBreak then - WhiteSpaceStyle := wsNoWrap - else - WhiteSpaceStyle := wsNormal; - if VarIsOrdinal(Prop.Props[piWhiteSpace]) then - WhiteSpaceStyle := ThtWhiteSpaceStyle(Prop.Props[piWhiteSpace]) - else if VarIsStr(Prop.Props[piWhiteSpace]) then - begin - if not TryStrToWhiteSpace(Prop.Props[piWhiteSpace],WhiteSpaceStyle) then - begin - end; -// if Prop.Props[piWhiteSpace] = 'pre' then -// WhiteSpaceStyle := wsPre -// else if Prop.Props[piWhiteSpace] = 'nowrap' then -// WhiteSpaceStyle := wsNoWrap -// else if Prop.Props[piWhiteSpace] = 'pre-wrap' then -// WhiteSpaceStyle := wsPreWrap -// else if Prop.Props[piWhiteSpace] = 'pre-line' then -// WhiteSpaceStyle := wsPreLine -// else if Prop.Props[piWhiteSpace] = 'normal' then - // WhiteSpaceStyle := wsNormal; - end; -{$IFDEF JPM_DEBUGGING} - CodeSite.ExitMethod(Self,'TSection.Create'); -{$ENDIF} -end; - -{----------------TSection.CreateCopy} - -constructor TSection.CreateCopy(Parent: TCellBasic; Source: THtmlNode); -var - T: TSection absolute Source; -begin - inherited CreateCopy(Parent,Source); - Len := T.Len; - BuffS := T.BuffS; - SetLength(BuffS, Length(BuffS)); - FBuff := PWideChar(BuffS); - Brk := T.Brk; - Fonts := TFontList.CreateCopy(Self, T.Fonts); - //TODO -oBG, 24.03.2011: TSection has no Cell, but owns images. Thus Parent must be a THtmlNode. - // and ThtDocument should become a TBodyBlock instead of a SectionList. - Images := TSizeableObjList.CreateCopy(Parent {must be Self}, T.Images); - FormControls := TFormControlObjList.CreateCopy(Parent, T.FormControls); - Lines := TLineRecList.Create; - Justify := T.Justify; - LineHeight := T.LineHeight; - FirstLineIndent := T.FirstLineIndent; - FLPercent := T.FLPercent; - BreakWord := T.BreakWord; - WhiteSpaceStyle := T.WhiteSpaceStyle; -end; - -{----------------TSection.Destroy} - -destructor TSection.Destroy; -var - i: Integer; -begin - { Yunqa.de: Do not leave references to deleted font objects in the - HtmlViewer's link list. Otherwise TURLTarget.SetLast might see an access - violation. } - if Document <> nil then - if Document.LinkList <> nil then - for i := 0 to Fonts.Count - 1 do - Document.LinkList.Remove(Fonts[i]); - - SIndexList.Free; - Lines.Free; - FormControls.Free; - Images.Free; - Fonts.Free; - inherited Destroy; -end; - -procedure TSection.CheckFree; -var - I, J: Integer; -begin - if not Assigned(Self) then - Exit; - if Assigned(Document) then - begin - {Check to see that there isn't a TFontObj in LinkList} - if Assigned(Document.LinkList) then - for I := 0 to Fonts.Count - 1 do - begin - J := Document.LinkList.IndexOf(Fonts[I]); - if J >= 0 then - Document.LinkList.Delete(J); - end; - {Remove Self from IDNameList if there} - if Assigned(Document.IDNameList) then - with Document.IDNameList do - begin - I := IndexOfObject(Self); - if I > -1 then - Delete(I); - end; - end; -end; - -{----------------TSection.AddChar} - -procedure TSection.AddChar(C: WideChar; Index: Integer); -var - Tok: TTokenObj; -begin - Tok := TTokenObj.Create; - Tok.AddUnicodeChar(C, Index); - AddTokenObj(Tok); - Tok.Free; -end; - -function TSection.GetIndexObj(I: Integer): ThtIndexObj; -begin - Result := SIndexList[I]; -end; - -procedure TSection.AddOpBrk; -var - L: Integer; -begin - L := Length(Brk); - if L > 0 then - Brk[L - 1] := twOptional; -end; - -{----------------TSection.AddTokenObj} - -procedure TSection.AddTokenObj(T: TTokenObj); -var - L, I, J: Integer; - C: ThtTextWrap; - St, StU: ThtString; - Small: Boolean; - LastProps: TProperties; -begin - if T.Count = 0 then - Exit; - - { Yunqa.de: Simple hack to support } - LastProps := Document.PropStack.Last; - if (LastProps.Display = pdNone) and (LastProps.PropSym in [ - SpanSy, NoBrSy, WbrSy, FontSy, BSy, ISy, SSy, StrikeSy, USy, SubSy, SupSy, BigSy, SmallSy, TTSy, - EmSy, StrongSy, CodeSy, KbdSy, SampSy, DelSy, InsSy, CiteSy, VarSy, MarkSy, TimeSy, ASy]) - then - Exit; - - case LastProps.GetTextTransform of - txUpper: - St := htUpperCase(T.S); - txLower: - St := htLowerCase(T.S); - else - St := T.S; - end; - - L := Len + T.Count; - if Length(XP) < L + 3 then - Allocate(L + 500); {L+3 to permit additions later} - - // add positions in source - Move(T.I[1], XP[Len], T.Count * Sizeof(Integer)); - - // BG, 31.08.2011: added: WhiteSpaceStyle - if Document.NoBreak or (WhiteSpaceStyle in [wsPre, wsPreLine, wsNoWrap]) then - C := twNo - else - C := twYes; - - J := Length(Brk); - SetLength(Brk, J + T.Count); - for I := J to J + T.Count - 1 do - Brk[I] := C; - - if LastProps.GetFontVariant = 'small-caps' then - begin - StU := htUpperCase(St); - BuffS := BuffS + StU; - Small := False; - for I := 1 to Length(St) do - begin - case St[I] of - WideChar(' '), WideChar('0')..WideChar('9'): - {no font changes for these chars} - ; - else - if not Small then - begin - if StU[I] <> St[I] then - begin {St[I] was lower case} - Document.PropStack.PushNewProp(SmallSy, nil, nil); {change to smaller font} - ChangeFont(Document.PropStack.Last); - Small := True; - end; - end - else if StU[I] = St[I] then - begin {St[I] was uppercase and Small is set} - Document.PropStack.PopAProp(SmallSy); - ChangeFont(Document.PropStack.Last); - Small := False; - end; - end; - Inc(Len); - end; - if Small then {change back to regular font} - begin - Document.PropStack.PopAProp(SmallSy); - ChangeFont(Document.PropStack.Last); - end; - end - else - begin - BuffS := BuffS + St; - Len := L; - end; - FBuff := PWideChar(BuffS); -end; - -{----------------TSection.ProcessText} - -procedure TSection.ProcessText(TagIndex: Integer); -const - Shy = #173; {soft hyphen} -var - I: Integer; - FO: TFontObj; - - procedure Remove(I: Integer); - var L: Integer; - begin - L := Length(BuffS) - I; - if L > 0 then - Move(XP[I], XP[I - 1], L * Sizeof(Integer)); - L := Length(Brk) - I; - if L > 0 then - Move(Brk[I], Brk[I - 1], L * Sizeof(ThtTextWrap)); - SetLength(Brk, Length(Brk) - 1); - System.Delete(BuffS, I, 1); - FormControls.Decrement(I - 1); - Fonts.Decrement(I - 1, Document); - Images.Decrement(I - 1); - end; - -begin - if WhiteSpaceStyle in [wsPre] then - begin - FO := TFontObj(Fonts.Items[Fonts.Count - 1]); {keep font the same for inserted space} - if FO.Pos = Length(BuffS) then - Inc(FO.Pos); - BuffS := BuffS + ' '; - Allocate(Length(BuffS) + 500); - XP[Length(BuffS) - 1] := XP[Length(BuffS) - 2] + 1; - end - else - begin - while (Length(BuffS) > 0) and (BuffS[1] = ' ') do - Remove(1); - - I := WidePos(Shy, BuffS); - while I > 0 do - begin - Remove(I); - if (I > 1) and (Brk[I - 2] <> twNo) then - Brk[I - 2] := twSoft; - I := WidePos(Shy, BuffS); - end; - - if WhiteSpaceStyle in [wsNormal, wsNoWrap, wsPreLine] then - begin - while (Length(BuffS) > 0) and (BuffS[1] = ' ') do - Remove(1); - - I := WidePos(' ', BuffS); - while I > 0 do - begin - if Brk[I - 1] = twNo then - Remove(I) - else - Remove(I + 1); - I := WidePos(' ', BuffS); - end; - - {After floating images at start, delete an annoying space} - for I := Length(BuffS) - 1 downto 1 do - if (BuffS[I] = ImgPan) and (Images.FindObject(I - 1).Floating in [ALeft, ARight]) - and (BuffS[I + 1] = ' ') then - Remove(I + 1); - - I := WidePos(UnicodeString(' '#8), BuffS); {#8 is break char} - while I > 0 do - begin - Remove(I); - I := WidePos(UnicodeString(' '#8), BuffS); - end; - - I := WidePos(UnicodeString(#8' '), BuffS); - while I > 0 do - begin - Remove(I + 1); - I := WidePos(UnicodeString(#8' '), BuffS); - end; - - if (Length(BuffS) > 1) and (BuffS[Length(BuffS)] = #8) then - Remove(Length(BuffS)); - - if (Length(BuffS) > 1) and (BuffS[Length(BuffS)] = ' ') then - Remove(Length(BuffS)); - - if (BuffS <> #8) and (Length(BuffS) > 0) and (BuffS[Length(BuffS)] <> ' ') then - begin - FO := TFontObj(Fonts.Items[Fonts.Count - 1]); {keep font the same for inserted space} - if FO.Pos = Length(BuffS) then - Inc(FO.Pos); - BuffS := BuffS + ' '; - XP[Length(BuffS) - 1] := TagIndex; - end; - end; - end; - Finish; -end; - -{----------------TSection.Finish} - -procedure TSection.Finish; -{complete some things after all information added} -var - Last, I: Integer; - IO: ThtIndexObj; -begin - FBuff := PWideChar(BuffS); - Len := Length(BuffS); - if Len > 0 then - begin - SetLength(Brk, Length(Brk) + 1); - Brk[Length(Brk) - 1] := twYes; - - if not IsCopy then - begin - Last := 0; {to prevent warning msg} - SIndexList := ThtIndexObjList.Create; - for I := 0 to Len - 1 do - begin - if (I = 0) or (XP[I] <> Last + 1) then - begin - IO := ThtIndexObj.Create; - IO.Pos := I; - IO.Index := XP[I]; - SIndexList.Add(IO); - end; - Last := XP[I]; - end; - SetLength(XP, 0); - end; - - Inc(Document.SectionCount); - SectionNumber := Document.SectionCount; - end; -end; - -{----------------TSection.Allocate} - -procedure TSection.Allocate(N: Integer); -begin - if Length(XP) < N then - SetLength(XP, N); -end; - -{----------------TSection.ChangeFont} - -procedure TSection.ChangeFont(Prop: TProperties); -var - FO: TFontObj; - LastUrl: TUrlTarget; - Align: ThtAlignmentStyle; -begin - FO := Fonts[Fonts.Count - 1]; - LastUrl := FO.UrlTarget; - if FO.Pos = Len then - FO.ReplaceFont(Prop.Font) {fontobj already at this position, modify it} - else - begin - FO := TFontObj.Create(Self, Prop.Font, Len); - FO.URLTarget.Assign(LastUrl); - Fonts.Add(FO); - end; - FO.Title := Prop.PropTitle; - if LastUrl.Url <> '' then - begin - FO.CreateFIArray; - Prop.GetFontInfo(FO.FIArray); - FO.ConvertFont(FO.FIArray.Ar[LFont]); - if Document.LinkList.IndexOf(FO) = -1 then - Document.LinkList.Add(FO); - end; - if Prop.GetVertAlign(Align) and (Align in [ASub, ASuper]) then - FO.SScript := Align - else - FO.SScript := ANone; -end; - -{----------------------TSection.HRef} - -procedure TSection.HRef(IsHRef: Boolean; List: ThtDocument; AnURL: TUrlTarget; - Attributes: TAttributeList; Prop: TProperties); -var - FO: TFontObj; - Align: ThtAlignmentStyle; -begin - FO := Fonts[Fonts.Count - 1]; - if FO.Pos = Len then - FO.ReplaceFont(Prop.Font) {fontobj already at this position, modify it} - else - begin - FO := TFontObj.Create(Self, Prop.Font, Len); - Fonts.Add(FO); - end; - - if IsHRef then - begin - FO.CreateFIArray; - Prop.GetFontInfo(FO.FIArray); - FO.ConvertFont(FO.FIArray.Ar[LFont]); - if Document.LinkList.IndexOf(FO) = -1 then - Document.LinkList.Add(FO); -{$IFNDEF NoTabLink} - if not Document.StopTab then - FO.CreateTabControl(AnUrl.TabIndex); -{$ENDIF} - end - else if Assigned(FO.FIArray) then - begin - FO.FIArray.Free; - FO.FIArray := nil; - end; - FO.UrlTarget.Assign(AnUrl); - if Prop.GetVertAlign(Align) and (Align in [ASub, ASuper]) then - FO.SScript := Align - else - FO.SScript := ANone; -end; - -//-- BG ---------------------------------------------------------- 12.11.2011 -- -function TSection.AddFrame(L: TAttributeList; ACell: TCellBasic; Index: Integer; Prop: TProperties): TFrameObj; -begin - Result := TFrameObj.Create(ACell, Len, L, Prop); - Images.Add(Result); - AddChar(ImgPan, Index); {marker for iframe} -end; - -function TSection.AddImage(L: TAttributeList; ACell: TCellBasic; Index: Integer; Prop: TProperties): TImageObj; -begin - Result := TImageObj.Create(ACell, Len, L, Prop); - Images.Add(Result); - AddChar(ImgPan, Index); {marker for image} -end; - -function TSection.AddPanel(L: TAttributeList; ACell: TCellBasic; Index: Integer; Prop: TProperties): TPanelObj; -begin - Result := TPanelObj.Create(ACell, Len, L, Prop, False); - Images.Add(Result); - AddChar(ImgPan, Index); {marker for panel} -end; - -function TSection.AddProgress(L: TAttributeList; ACell: TCellBasic; Index: Integer; Prop: TProperties): TProgressObj; -begin - Result := TProgressObj.Create(ACell, Len, L, Prop, False); - Images.Add(Result); - AddChar(ImgPan, Index); {marker for progress} -end; - -function TSection.AddMeter(L: TAttributeList; ACell: TCellBasic; Index: Integer; Prop: TProperties): TMeterObj; -begin - Result := TMeterObj.Create(ACell, Len, L, Prop, False); - Images.Add(Result); - AddChar(ImgPan, Index); {marker for progress} -end; - -function TSection.CreatePanel(L: TAttributeList; ACell: TCellBasic; Prop: TProperties): TPanelObj; -{Used by object tag} -begin - Result := TPanelObj.Create(ACell, Len, L, Prop, True); -end; - -procedure TSection.AddPanel1(PO: TPanelObj; Index: Integer); -{Used for Object Tag} -begin - Images.Add(PO); - AddChar(ImgPan, Index); {marker for panel} -end; - -{----------------TSection.AddFormControl} - -function TSection.AddFormControl(Which: TElemSymb; AMasterList: ThtDocument; - L: TAttributeList; ACell: TCellBasic; Index: Integer; - Prop: TProperties): TFormControlObj; -var - T: TAttribute; - FCO: TFormControlObj; - S: ThtString; - IO: TImageObj; - ButtonControl: TButtonFormControlObj; - FCT: (fctUnknown, fctImage, fctFile); -begin - S := ''; - FCT := fctUnknown; - case Which of - InputSy: - begin - FCO := nil; - T := nil; - if L.Find(TypeSy, T) then - begin - S := LowerCase(T.Name); - if (S = 'submit') or (S = 'reset') or (S = 'button') then - FCO := TButtonFormControlObj.Create(ACell, Len, L, Prop) - else if S = 'radio' then - FCO := TRadioButtonFormControlObj.Create(ACell, Len, L, Prop) - else if S = 'checkbox' then - FCO := TCheckBoxFormControlObj.Create(ACell, Len, L, Prop) - else if S = 'hidden' then - FCO := THiddenFormControlObj.Create(ACell, Len, L, Prop) - else if S = 'image' then - begin - FCT := fctImage; - FCO := TImageFormControlObj.Create(ACell, Len, L, Prop); - end - else if S = 'file' then - begin - FCT := fctFile; - FCO := TEditFormControlObj.Create(ACell, Len, L, Prop); - end; - end; - if FCO = nil then - FCO := TEditFormControlObj.Create(ACell, Len, L, Prop); - end; - - SelectSy: - begin - if L.Find(MultipleSy, T) or L.Find(SizeSy, T) and (T.Value > 1) then - FCO := TListBoxFormControlObj.Create(ACell, Len, L, Prop) - else - FCO := TComboFormControlObj.Create(ACell, Len, L, Prop); - end; - else - FCO := TTextAreaFormControlObj.Create(ACell, Len, L, Prop); - end; - - case FCT of - - fctImage: - begin - IO := AddImage(L, ACell, Index, Prop); {leave out of FormControlList} - IO.MyFormControl := TImageFormControlObj(FCO); - TImageFormControlObj(FCO).MyImage := IO; - end; - - fctFile: - begin - FormControls.Add(FCO); - AddChar(FmCtl, Index); {marker for FormControl} - Brk[Len - 1] := twNo; {don't allow break between these two controls} - ButtonControl := TButtonFormControlObj.Create(ACell, Len, L, Prop); - ButtonControl.MyEdit := TEditFormControlObj(FCO); - FormControls.Add(ButtonControl); - {the following fixup puts the ID on the TEdit and deletes it from the Button} - if L.TheID <> '' then - Document.IDNameList.AddObject(L.TheID, FCO); - FCO.Value := ''; {value attribute should not show in TEdit} - TEditFormControlObj(FCO).Text := ''; - AddChar(FmCtl, Index); - Brk[Len - 1] := twNo; - end; - - else - FormControls.Add(FCO); - AddChar(FmCtl, Index); {marker for FormControl} - end; - - if Prop.HasBorderStyle then {start of inline border} - Document.ProcessInlines(Index, Prop, True); -{$ifdef has_StyleElements} - if FCO.GetControl <> nil then begin - FCO.GetControl.StyleElements := AMasterList.StyleElements; - end; -{$endif} - Result := FCO; -end; - -{----------------TSection.FindCountThatFits} - -function TSection.FindCountThatFits(Canvas: TCanvas; Width: Integer; Start: PWideChar; Max: Integer): Integer; -{Given a width, find the count of chars (<= Max) which will fit allowing for - font changes. Line wrapping will be done later} -//BG, 06.02.2011: Why are there 2 methods and why can't GetURL and FindCursor use the formatting results of DrawLogic? -// TSection.FindCountThatFits1() is used in TSection.DrawLogic(). -// TSection.FindCountThatFits() is used in TSection.GetURL() and TSection.FindCursor(). -var - Cnt, XX, YY, I, J, J1, J2, J3: Integer; - Picture: Boolean; - FlObj: TFloatingObj; //TSizeableObj; - FcObj: TFloatingObj; //TFormControlObj; - FO: TFontObj; - Extent: TSize; -const - OldStart: PWideChar = nil; - OldResult: Integer = 0; - OldWidth: Integer = 0; - -begin - if (Width = OldWidth) and (Start = OldStart) then - begin - Result := OldResult; - Exit; - end; - OldStart := Start; - OldWidth := Width; - Cnt := 0; - XX := 0; - YY := 0; - while True do - begin - //Fonts.GetFontAt(Start - Buff, OHang).AssignToCanvas(Canvas); - J1 := Fonts.GetFontObjAt(Start - Buff, Len, FO); - FO.TheFont.AssignToCanvas(Canvas); - J2 := Images.GetObjectAt(Start - Buff, FlObj); - J3 := FormControls.GetObjectAt(Start - Buff, FcObj); - if (J2 = 0) or (J3 = 0) then - begin - if J2 <> 0 then - FlObj := FcObj; - I := 1; J := 1; - Picture := True; - if FlObj.IsInFlow then - begin - Inc(XX, FlObj.TotalWidth); - if XX > Width then - break; - end; - end - else - begin - Picture := False; - J := Min(J1, J2); - J := Min(J, J3); - I := FitText(Canvas.Handle, Start, J, Width - XX, Extent); - end; - - if Cnt + I >= Max then {I has been initialized} - begin - Cnt := Max; - Break; - end - else - Inc(Cnt, I); - - if not Picture then - begin - if (I < J) or (I = 0) then - Break; - XX := XX + Extent.cx; - YY := Math.Max(YY, Extent.cy); - end; - - Inc(Start, I); - end; - Result := Cnt; - OldResult := Result; -end; - -function WrapChar(C: WideChar): Boolean; - {$ifdef UseInline} inline; {$endif} -begin - Result := Ord(C) >= $3000; -end; - -//-- BG ---------------------------------------------------------- 27.01.2012 -- -function CanWrapAfter(C: WideChar): Boolean; - {$ifdef UseInline} inline; {$endif} -begin - case C of - WideChar('-'), WideChar('/'), WideChar('?'): - Result := True - else - Result := False; - end; -end; - -//-- BG ---------------------------------------------------------- 20.09.2010 -- -function CanWrap(C: WideChar): Boolean; - {$ifdef UseInline} inline; {$endif} -begin - case C of - WideChar(' '), WideChar('-'), WideChar('/'), WideChar('?'), ImgPan, FmCtl, BrkCh: - Result := True - else - Result := WrapChar(C); - end; -end; - -{----------------TSection.MinMaxWidth} - -procedure TSection.MinMaxWidth(Canvas: TCanvas; out Min, Max: Integer); -{Min is the width the section would occupy when wrapped as tightly as possible. - Max, the width if no wrapping were used.} - - procedure MinMaxWidthOfBlocks(Objects: TFloatingObjList); - var - I: Integer; - Obj: TFloatingObj; - begin - for I := 0 to Objects.Count - 1 do {call drawlogic for all the objects} - begin - Obj := Objects[I]; - Obj.DrawLogicInline(Canvas, Fonts.GetFontObjAt(Obj.StartCurs), 0, 0); - if not Obj.PercentWidth then - begin - if Obj.Positioning in [posAbsolute, posFixed] then - begin - // does not affect the block width - Brk[Obj.StartCurs] := twYes; {allow break after positioned object} - end - else if Obj.Floating in [ALeft, ARight] then - begin - Inc(Max, Obj.TotalWidth); - Brk[Obj.StartCurs] := twYes; {allow break after floating object} - Min := Math.Max(Min, Obj.TotalWidth); - end - else - Min := Math.Max(Min, Obj.ClientWidth); - end; - end; - end; - -var - SoftHyphen: Boolean; - - function FindTextWidthB(Canvas: TCanvas; Start: PWideChar; N: Integer; RemoveSpaces: Boolean): TSize; - begin - Result := FindTextSize(Canvas, Start, N, RemoveSpaces); - if Start = Buff then - if FLPercent = 0 then {not a percent} - Inc(Result.cx, FirstLineIndent) - else - Result.cx := (100 * Result.cx) div (100 - FLPercent); - if SoftHyphen then - Inc(Result.cx, Canvas.TextWidth('-')); - end; - -var - I, FloatMin: Integer; - P, P1: PWideChar; -begin - Min := 0; - Max := 0; - if Len = 0 then - Exit; - - if not BreakWord and (WhiteSpaceStyle in [wsPre, wsNoWrap]) then - begin - if StoredMax.cx = 0 then - begin - StoredMax := FindTextSize(Canvas, Buff, Len - 1, False); - Max := StoredMax.cx; - end - else - Max := StoredMax.cx; - Min := Math.Min(MaxHScroll, Max); - Exit; - end; - -{$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self, 'TSection.MinMaxWidth'); -{$ENDIF} - if (StoredMin.cx > 0) and (Images.Count = 0) then - begin - Min := StoredMin.cx; - Max := StoredMax.cx; -{$IFDEF JPM_DEBUGGING} - CodeSite.ExitMethod(Self, Format('TSection.MinMaxWidth Stored %d .. %d', [Min, Max])); -{$ENDIF} - Exit; - end; - - MinMaxWidthOfBlocks(Images); - MinMaxWidthOfBlocks(FormControls); - FloatMin := Min; - - SoftHyphen := False; - P := Buff; - P1 := StrScanW(P, BrkCh); {look for break char} - while Assigned(P1) do - begin - Max := Math.Max(Max, FindTextWidthB(Canvas, P, P1 - P, False).cx); - P := P1 + 1; - P1 := StrScanW(P, BrkCh); - end; - P1 := StrScanW(P, #0); {look for the end} - Inc(Max, FindTextWidthB(Canvas, P, P1 - P, True).cx); // + FloatMin; - - P := Buff; - if not BreakWord then - begin - while P^ = ' ' do - Inc(P); - P1 := P; - I := P1 - Buff + 1; - while P^ <> #0 do - {find the next string of chars that can't be wrapped} - begin - SoftHyphen := False; - if CanWrap(P1^) and (Brk[I - 1] = twYes) then - begin - Inc(P1); - Inc(I); - end - else - begin - repeat - Inc(P1); - Inc(I); - case Brk[I - 2] of - twSoft, twOptional: - break; - end; - until (P1^ = #0) or (CanWrap(P1^) and (Brk[I - 1] = twYes)); - SoftHyphen := Brk[I - 2] = twSoft; - if CanWrapAfter(P1^) then - begin - Inc(P1); - Inc(I); - end; - end; - Min := Math.Max(Min, FindTextWidthB(Canvas, P, P1 - P, True).cx); - while True do - case P1^ of - WideChar(' '), ImgPan, FmCtl, BrkCh: - begin - Inc(P1); - Inc(I); - end; - else - break; - end; - P := P1; - end; - end - else - while P^ <> #0 do - begin - Min := Math.Max(Min, FindTextWidthB(Canvas, P, 1, True).cx); - Inc(P); - end; - - Min := Math.Max(FloatMin, Min); - StoredMin.cx := Min; - StoredMax.cx := Max; - StoredMin.cy := 0; - StoredMax.cy := 0; -{$IFDEF JPM_DEBUGGING} - CodeSite.ExitMethod(Self, Format('TSection.MinMaxWidth %d .. %d', [Min, Max])); -{$ENDIF} -end; - -{----------------TSection.FindTextWidth} - -function TSection.FindTextSize(Canvas: TCanvas; Start: PWideChar; N: Integer; RemoveSpaces: Boolean): TSize; -{find actual line width of N chars starting at Start. If RemoveSpaces set, - don't count spaces on right end} -var - I, J, J1: Integer; - FlObj: TFloatingObj; //TSizeableObj; - FcObj: TFloatingObj; //TFormControlObj; - FO: TFontObj; -begin -{$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'TSection.FindTextWidth'); -{$ENDIF} - Result.cx := 0; - Result.cy := 0; - if RemoveSpaces then - while True do - case (Start + N - 1)^ of - SpcChar, - BrkCh: - Dec(N); {remove spaces on end} - else - break; - end; - while N > 0 do - begin - J := Images.GetObjectAt(Start - Buff, FlObj); - J1 := FormControls.GetObjectAt(Start - Buff, FcObj); - if (J = 0) or (J1 = 0) then {it's an image or a form control} - begin - {Here we count floating images as 1 ThtChar but do not include their width, - This is required for the call in FindCursor} - if J <> 0 then - FlObj := FcObj; - if FlObj.IsInFlow then - begin - Inc(Result.cx, FlObj.TotalWidth); - Result.cy := Max(Result.cy, FlObj.TotalHeight); - end; - Dec(N); {image counts as one ThtChar} - Inc(Start); - end - else - begin - //Fonts.GetFontAt(Start - Buff, OHang).AssignToCanvas(Canvas); - I := Min(J, J1); - I := Min(I, Min(Fonts.GetFontObjAt(Start - Buff, Len, FO), N)); - FO.TheFont.AssignToCanvas(Canvas); - //Assert(I > 0, 'I less than or = 0 in FindTextWidth'); - with GetTextExtent(Canvas.Handle, Start, I) do - begin - Inc(Result.cx, cx + FO.Overhang); - Result.cy := Max(Result.cy, cy); - end; - if I = 0 then - Break; - Dec(N, I); - Inc(Start, I); - end; - end; - {$IFDEF JPM_DEBUGGING} - CodeSite.ExitMethod(Self, Format('TSection.FindTextWidth w = %d, h = %d', [Result.cx, Result.cy])); - {$ENDIF} -end; - -{----------------TSection.FindTextWidthA} - -function TSection.FindTextWidthA(Canvas: TCanvas; Start: PWideChar; N: Integer): Integer; -{find actual line width of N chars starting at Start. - BG: The only difference to FindTextWidth is the '- OHang' when incrementing the result.} -var - I, J, J1: Integer; - FlObj: TFloatingObj; //TSizeableObj; - FcObj: TFloatingObj; //TFormControlObj; - FO: TFontObj; -begin - Result := 0; - while N > 0 do - begin - J := Images.GetObjectAt(Start - Buff, FlObj); - J1 := FormControls.GetObjectAt(Start - Buff, FcObj); - if (J = 0) or (J1 = 0) then {it's an image or a form control} - begin - {Here we count floating images as 1 ThtChar but do not include their width, - This is required for the call in FindCursor} - if J <> 0 then - FlObj := FcObj; - if FlObj.IsInFlow then - Inc(Result, FlObj.TotalWidth); - Dec(N); {image counts as one ThtChar} - Inc(Start); - end - else - begin - I := Min(Min(J, J1), Min(Fonts.GetFontObjAt(Start - Buff, Len, FO), N)); - FO.TheFont.AssignToCanvas(Canvas); - Assert(I > 0, 'I less than or = 0 in FindTextWidthA'); - Inc(Result, GetTextExtent(Canvas.Handle, Start, I).cx - FO.Overhang); - if I = 0 then - Break; - Dec(N, I); - Inc(Start, I); - end; - end; -end; - -{----------------TSection.DrawLogic} - -function TSection.DrawLogic1(Canvas: TCanvas; X, Y, XRef, YRef, AWidth, AHeight, BlHt: Integer; IMgr: TIndentManager; - var MaxWidth, Curs: Integer): Integer; -{returns height of the section} - - function FindCountThatFits1(Canvas: TCanvas; Start: PWideChar; MaxChars, X, Y: Integer; - IMgr: TIndentManager; var ImgY, ImgHt: Integer; var DoneFlObjPos: PWideChar): Integer; - {Given a width, find the count of chars (<= Max) which will fit allowing for font changes. - Line wrapping will be done later} - //BG, 06.02.2011: Why are there 2 methods and why can't GetURL and FindCursor use the formatting results of DrawLogic? - // FindCountThatFits1() is part of TSection.DrawLogic() and fills IMgr with the embedded floating objects. - // TSection.FindCountThatFits() is used in TSection.GetURL() and TSection.FindCursor(). - - - type - TResultCode = (rsOk, rsContinue, rsBreak); - - function DrawLogicOfObject(FlObj: TFloatingObj; var XX, YY, Width, Cnt, FloatingImageCount: Integer): TResultCode; - var - X1, X2, W, H: Integer; - begin - Result := rsOk; - if FlObj.Floating in [ALeft, ARight] then - begin - if Start > DoneFlObjPos then - begin - ImgY := Max(Y, ImgY); - W := FlObj.TotalWidth; - H := FlObj.TotalHeight; - case FlObj.Floating of - ALeft: - begin - FlObj.FIndent := IMgr.AlignLeft(ImgY, W) + FlObj.HSpaceL; - IMgr.AddLeft(ImgY, ImgY + H, W); - end; - - ARight: - begin - FlObj.FIndent := IMgr.AlignRight(ImgY, W) + FlObj.HSpaceL; - IMgr.AddRight(ImgY, ImgY + H, W); - end; - end; - FlObj.DrawXX := FlObj.FIndent; - FlObj.DrawYY := ImgY + FlObj.VSpaceT; - ImgHt := Max(ImgHt, H); - DoneFlObjPos := Start; - - // go on with the line: - X1 := IMgr.LeftIndent(Y); - X2 := IMgr.RightSide(Y); - Width := X2 - X1; - Inc(FloatingImageCount); - if Cnt >= FloatingImageCount then - Result := rsContinue; - end; - end - else if not (FlObj.Positioning in [posAbsolute, posFixed]) then - begin - ImgHt := Max(ImgHt, FlObj.TotalHeight); - Inc(XX, FlObj.TotalWidth); - if XX > Width then - Result := rsBreak; - end; - end; - - var - Cnt, - I, // number of fitting chars - J, // number of chars up to next font change or object - J1, // number of chars up to next font change - J2, // number of chars up to next image - J3, // number of chars up to next form control - X1, X2, Width, D, H: Integer; - XX: Integer; // current width of row in pixels (== current horizontal position). - YY: Integer; // current height of row in pixels. - Picture: Boolean; - FlObj: TFloatingObj; //TSizeableObj; - FcObj: TFloatingObj; //TFormControlObj; - FO: TFontObj; - BrChr, TheStart: PWideChar; - //Font, - LastFont: ThtFont; - Save: TSize; - FoundBreak: Boolean; - HyphenWidth: Integer; - FloatingImageCount: Integer; - InitialFloatingLeftCount: Integer; - InitialFloatingRightCount: Integer; - begin - LastFont := nil; - TheStart := Start; - ImgHt := 0; - InitialFloatingLeftCount := IMgr.L.Count; - InitialFloatingRightCount := IMgr.R.Count; - - BrChr := StrScanW(TheStart, BrkCh); {see if a break char} - FoundBreak := Assigned(BrChr) and (BrChr - TheStart < MaxChars); - if FoundBreak then - begin - MaxChars := BrChr - TheStart; - if MaxChars = 0 then - begin - Result := 1; - Exit; {single character fits} - end; - end; - - X1 := IMgr.LeftIndent(Y); - if Start = Buff then - Inc(X1, FirstLineIndent); - X2 := IMgr.RightSide(Y); - Width := X2 - X1; - - if (Start = Buff) and (Images.Count = 0) and (FormControls.Count = 0) then - if Fonts.GetFontObjAt(0, Len, FO) = Len then - if MaxChars * Fonts[0].tmMaxCharWidth <= Width then {try a shortcut} - begin {it will all fit} - Result := MaxChars; - if FoundBreak then - Inc(Result); - Exit; - end; - - FloatingImageCount := -1; - Cnt := 0; - XX := 0; - YY := 0; - while True do - begin - J1 := Min(Fonts.GetFontObjAt(Start - Buff, Len, FO), MaxChars - Cnt); - if FO.TheFont <> LastFont then {may not have to load font} - begin - LastFont := FO.TheFont; - LastFont.AssignToCanvas(Canvas); - end; - J2 := Images.GetObjectAt(Start - Buff, FlObj); - J3 := FormControls.GetObjectAt(Start - Buff, FcObj); - if (J2 = 0) or (J3 = 0) then - begin {next is an object} - if J2 <> 0 then - FlObj := FcObj; - I := 1; - J := 1; - Picture := True; - case DrawLogicOfObject(FlObj, XX, YY, Width, Cnt, FloatingImageCount) of - rsContinue: - begin - // after an object floating to the left or right, we must retry to - // fit the remaining space between the floating objects. - Start := TheStart; - Cnt := 0; - XX := 0; - continue; - end; - - rsBreak: - break; - end; - end - else - begin - Picture := False; - J := Min(J1, J2); - J := Min(J, J3); - I := FitText(Canvas.Handle, Start, J, Width - XX, Save); - if (I > 0) and (Brk[TheStart - Buff + Cnt + I - 1] = twSoft) then - begin {a hyphen could go here} - HyphenWidth := Canvas.TextWidth('-'); - if XX + Save.cx + HyphenWidth > Width then - Dec(I); - end; - end; - - if Cnt + I >= MaxChars then - begin - Cnt := MaxChars; - Break; - end - else - Inc(Cnt, I); - - if not Picture then {it's a text block} - begin - if I < J then - Break; - XX := XX + Save.cx; - YY := Math.Max(YY, Save.cy); - end; - - Inc(Start, I); - end; - Result := Cnt; - - if FoundBreak and (Cnt = MaxChars) then - Inc(Result); - - // adjust floating objects top position, in case they have been moved down and line height has been changed. - H := YY; //Max(YY, ImgHt); - IMgr.AdjustY(InitialFloatingLeftCount, InitialFloatingRightCount, Y, H); - - D := 0; - for I := 0 to Images.Count - 1 do - with Images[I] do - if Floating in [ALeft, ARight] then - if DrawYY > Y + VSpaceT then - begin - if DrawYY < Y + H + VSpaceT then - D := Y + H + VSpaceT - DrawYY; - Inc(DrawYY, D); - end; - - D := 0; - for I := 0 to FormControls.Count - 1 do - with FormControls[I] do - if Floating in [ALeft, ARight] then - if DrawYY > Y + VSpaceT then - begin - if DrawYY < Y + H + VSpaceT then - D := Y + H + VSpaceT - DrawYY; // FYValue; - Inc(DrawYY, D); - end; - end; - - procedure DoDrawLogic; - - procedure DrawLogicOfObjects(Objects: TFloatingObjList; Width: Integer); - var - I: Integer; - Obj: TFloatingObj; - begin - for I := 0 to Objects.Count - 1 do {call drawlogic for all the objects} - begin - Obj := Objects[I]; - Obj.DrawLogicInline(Canvas, Fonts.GetFontObjAt(Obj.StartCurs), 0, 0); - // BG, 28.08.2011: - if OwnerBlock.HideOverflow then - begin - if Obj.ClientWidth > Width then - Obj.ClientWidth := Width; - end - else - MaxWidth := Max(MaxWidth, Obj.ClientWidth); {HScrollBar for wide images} - end; - end; - - var - PStart, Last: PWideChar; - ImgHt: Integer; - Finished: Boolean; - LR: ThtLineRec; - AccumImgBot: Integer; - - procedure LineComplete(NN: Integer); - var - I, J, DHt, Desc, Tmp, TmpRt, Cnt, H, SB, SA: Integer; - FO: TFontObj; - Align: ThtAlignmentStyle; - NoChar: Boolean; - P: PWideChar; - FlObj: TFloatingObj; //TSizeableObj; - FcObj: TFloatingObj; //TFormControlObj; - LRTextWidth: Integer; - OHang: Integer; - - function FindSpaces: Integer; - var - I: Integer; - begin - Result := 0; - for I := 0 to NN - 2 do {-2 so as not to count end spaces} - if ((PStart + I)^ = ' ') or ((PStart + I)^ = #160) then - Inc(Result); - end; - - begin - DHt := 0; {for the fonts on this line get the maximum height} - Cnt := 0; - Desc := 0; - P := PStart; - if (NN = 1) and (P^ = BrkCh) then - NoChar := False - else - begin - NoChar := True; - for I := 0 to NN - 1 do - begin - case P^ of - FmCtl, ImgPan, BrkCh:; - else - if not ((P = Last) and (Last^ = ' ')) then - begin {check for the no character case} - NoChar := False; - Break; - end; - end; - Inc(P); - end; - end; - - Align := ANone; - if not NoChar then - begin - repeat - J := Fonts.GetFontObjAt(PStart - Buff + Cnt, Len, FO); - Tmp := FO.GetHeight(Desc); - DHt := Max(DHt, Tmp); - LR.Descent := Max(LR.Descent, Desc); - Inc(Cnt, J); - until Cnt >= NN; - Align := FO.SScript; - end; - - {if there are images or line-height, then maybe they add extra space} - SB := 0; // vertical space before DHt / Text - SA := 0; // vertical space after DHt / Text - if not NoChar then - begin - if LineHeight > DHt then - begin - // BG, 28.08.2011: too much space below an image: SA and SB depend on Align: - case Align of - aTop: - SA := LineHeight - DHt; - - aMiddle: - begin - SB := (LineHeight - DHt) div 2; - SA := (LineHeight - DHt) - SB; - end; - else -// aNone, -// aBaseline, -// aBottom: - SB := LineHeight - DHt; - end; - end - else if LineHeight >= 0 then - begin - SB := (LineHeight - DHt) div 2; - SA := (LineHeight - DHt) - SB; - end; - end; - - Cnt := 0; - repeat - Inc(Cnt, Images.GetObjectAt(PStart - Buff + Cnt, FlObj)); - if Cnt < NN then - begin - H := FlObj.TotalHeight; - if FlObj.Floating = ANone then - begin - FlObj.DrawYY := Y; {approx y dimension} - if (FLObj is TImageObj) and Assigned(TImageObj(FLObj).MyFormControl) then - TImageObj(FLObj).MyFormControl.DrawYY := Y; // FYValue := Y; - if not (FlObj.Positioning in [posAbsolute, posFixed]) then - begin - case FlObj.VertAlign of - aTop: - SA := Max(SA, H - DHt); - - aMiddle: - begin - if DHt = 0 then - begin - DHt := Fonts.GetFontObjAt(PStart - Buff).GetHeight(Desc); - LR.Descent := Desc; - end; - Tmp := (H - DHt) div 2; - SA := Max(SA, Tmp); - SB := Max(SB, (H - DHt - Tmp)); - end; - aBaseline, - aBottom: - SB := Max(SB, H - (DHt - LR.Descent)); - end; - end; - end; - end; - Inc(Cnt); {to skip by the image} - until Cnt >= NN; - - Cnt := 0; {now check on form controls} - repeat - Inc(Cnt, FormControls.GetObjectAt(PStart - Buff + Cnt, FcObj)); - if Cnt < NN then - begin - H := FcObj.TotalHeight; - if FcObj.Floating = ANone then - begin - case FcObj.VertAlign of - ATop: - SA := Max(SA, H - Dht); - AMiddle: - begin - Tmp := (FcObj.ClientHeight - DHt) div 2; - SA := Max(SA, Tmp + FcObj.VSpaceB); - SB := Max(SB, (FcObj.ClientHeight - DHt - Tmp + FcObj.VSpaceT)); - end; - ABaseline: - SB := Max(SB, H - (DHt - LR.Descent)); - ABottom: - SB := Max(SB, H - DHt); - end; - if not IsCopy then - FcObj.DrawYY := Y; //FYValue := Y; - end; - end; - Inc(Cnt); {to skip by the control} - until Cnt >= NN; - - {$IFNDEF NoTabLink} - Cnt := 0; {now check URLs} - repeat - Inc(Cnt, Fonts.GetFontObjAt(PStart - Buff + Cnt, Len, FO)); - FO.AssignY(Y); - until Cnt >= NN; - {$ENDIF} - - LR.Start := PStart; - LR.LineHt := DHt; - LR.Ln := NN; - if Brk[PStart - Buff + NN - 1] = twSoft then {see if there is a soft hyphen on the end} - LR.Shy := True; - TmpRt := IMgr.RightSide(Y); - Tmp := IMgr.LeftIndent(Y); - if PStart = Buff then - Inc(Tmp, FirstLineIndent); - - LRTextWidth := FindTextSize(Canvas, PStart, NN, True).cx; - if LR.Shy then - begin {take into account the width of the hyphen} - Fonts.GetFontAt(PStart - Buff + NN - 1, OHang).AssignToCanvas(Canvas); - Inc(LRTextWidth, Canvas.TextWidth('-')); - end; - TextWidth := Max(TextWidth, LRTextWidth); - case Justify of - Left: LR.LineIndent := Tmp - X; - Centered: LR.LineIndent := (TmpRt + Tmp - LRTextWidth) div 2 - X; - Right: LR.LineIndent := TmpRt - X - LRTextWidth; - else - {Justify = FullJustify} - LR.LineIndent := Tmp - X; - if not Finished then - begin - LR.Extra := TmpRt - Tmp - LRTextWidth; - LR.Spaces := FindSpaces; - end; - end; - LR.DrawWidth := TmpRt - Tmp; - LR.SpaceBefore := LR.SpaceBefore + SB; - LR.SpaceAfter := SA; - Lines.Add(LR); - Inc(PStart, NN); - SectionHeight := SectionHeight + DHt + SA + LR.SpaceBefore; - Tmp := DHt + SA + SB; - Inc(Y, Tmp); - LR.LineImgHt := Max(Tmp, ImgHt); - end; - - var - P: PWideChar; - MaxChars: Integer; - N, NN, Width, I: Integer; - Tmp: Integer; - Obj: TFloatingObj; - TopY, HtRef: Integer; - //Ctrl: TFormControlObj; - //BG, 06.02.2011: floating objects: - PDoneFlObj: PWideChar; - YDoneFlObj: Integer; - begin {DoDrawLogic} - SectionHeight := 0; - AccumImgBot := 0; - TopY := Y; - PStart := Buff; - Last := Buff + Len - 1; - if Len = 0 then - begin - Result := GetClearSpace(IMgr, Y); - DrawHeight := Result; - SectionHeight := Result; - ContentBot := Y + Result; - DrawBot := ContentBot; - MaxWidth := 0; - DrawWidth := 0; - - DrawRect.Left := X; - DrawRect.Top := DrawTop; - DrawRect.Right := DrawRect.Left + DrawWidth; - DrawRect.Bottom := DrawBot; - Exit; - end; - if FLPercent <> 0 then - FirstLineIndent := (FLPercent * AWidth) div 100; {percentage calculated} - Finished := False; - DrawWidth := IMgr.RightSide(Y) - X; - Width := Min(IMgr.RightSide(Y) - IMgr.LeftIndent(Y), AWidth); - MaxWidth := Width; - if AHeight = 0 then - HtRef := BlHt - else - HtRef := AHeight; - - for I := 0 to Images.Count - 1 do {call drawlogic for all the images} - begin - Obj := Images[I]; - Obj.DrawLogicInline(Canvas, Fonts.GetFontObjAt(Obj.StartCurs), Width, HtRef); - // BG, 28.08.2011: - if OwnerBlock.HideOverflow then - begin - if Obj.ClientWidth > Width then - Obj.ClientWidth := Width; - end - else - MaxWidth := Max(MaxWidth, Obj.ClientWidth); {HScrollBar for wide images} - end; - - for I := 0 to FormControls.Count - 1 do - begin - Obj := FormControls[I]; - Obj.DrawLogicInline(Canvas, Fonts.GetFontObjAt(Obj.StartCurs), Width, HtRef); - // BG, 28.08.2011: - if OwnerBlock.HideOverflow then - begin - if Obj.ClientWidth > Width then - Obj.ClientWidth := Width; - end - else - MaxWidth := Max(MaxWidth, Obj.ClientWidth); - end; - - YDoneFlObj := Y; - PDoneFlObj := PStart - 1; - while not Finished do - begin - MaxChars := Last - PStart + 1; - if MaxChars <= 0 then - Break; - LR := ThtLineRec.Create(Document); {a new line} - if Lines.Count = 0 then - begin {may need to move down past floating image} - Tmp := GetClearSpace(IMgr, Y); - if Tmp > 0 then - begin - LR.LineHt := Tmp; - Inc(SectionHeight, Tmp); - LR.Ln := 0; - LR.Start := PStart; - Inc(Y, Tmp); - Lines.Add(LR); - LR := ThtLineRec.Create(Document); - end; - end; - - ImgHt := 0; - NN := 0; - if (WhiteSpaceStyle in [wsPre, wsPreLine, wsNoWrap]) and not BreakWord then - N := MaxChars - else - begin - NN := FindCountThatFits1(Canvas, PStart, MaxChars, X, Y, IMgr, YDoneFlObj, ImgHt, PDoneFlObj); - N := Max(NN, 1); {N = at least 1} - end; - - AccumImgBot := Max(AccumImgBot, Y + ImgHt); - if NN = 0 then {if nothing fits, see if we can move down} - Tmp := IMgr.GetNextWiderY(Y) - Y - else - Tmp := 0; - if Tmp > 0 then - begin - //BG, 24.01.2010: do not move down images or trailing spaces. - P := PStart + N - 1; {the last ThtChar that fits} - if ((P^ = SpcChar) {or (P^ = FmCtl,} or (P^ = ImgPan) or WrapChar(P^)) and (Brk[P - Buff] <> twNo) or (P^ = BrkCh) then - begin {move past spaces so as not to print any on next line} - while (N < MaxChars) and ((P + 1)^ = ' ') do - begin - Inc(P); - Inc(N); - end; - Finished := N >= MaxChars; - LineComplete(N); - end - else - begin {move down to where it's wider} - LR.LineHt := Tmp; - Inc(SectionHeight, Tmp); - LR.Ln := 0; - LR.Start := PStart; - Inc(Y, Tmp); - Lines.Add(LR); - end - end {else can't move down or don't have to} - else if N = MaxChars then - begin {Do the remainder} - Finished := True; - LineComplete(N); - end - else - begin - P := PStart + N - 1; {the last ThtChar that fits} - if ((P^ = SpcChar) or (P^ = FmCtl) or (p^ = ImgPan) or WrapChar(P^)) and (Brk[P - Buff] <> twNo) or (P^ = BrkCh) then - begin {move past spaces so as not to print any on next line} - while (N < MaxChars) and ((P + 1)^ = ' ') do - begin - Inc(P); - Inc(N); - end; - Finished := N >= MaxChars; - LineComplete(N); - end - else if (N < MaxChars) and ((P + 1)^ = ' ') and (Brk[P - Buff + 1] <> twNo) then - begin - repeat - Inc(P); - Inc(N); {pass the space} - until (N >= MaxChars) or ((P + 1)^ <> ' '); - Finished := N >= MaxChars; - LineComplete(N); - end - else if (N < MaxChars) and (((P + 1)^ = FmCtl) or ((P + 1)^ = ImgPan)) and (Brk[PStart - Buff + N - 1] <> twNo) then {an image or control} - begin - Finished := False; - LineComplete(N); - end - else - begin - {non space, wrap it by backing off to previous wrappable char} - while P > PStart do - begin - case Brk[P - Buff] of - twNo: ; - - twSoft, - twOptional: - break; - - else - if CanWrap(P^) or WrapChar((P + 1)^) then - break; // can wrap after this or before next char. - end; - Dec(P); - end; - - if (P = PStart) and ((not ((P^ = FmCtl) or (P^ = ImgPan))) or (Brk[PStart - Buff] = twNo)) then - begin - {no space found, forget the wrap, write the whole word and any spaces found after it} - if BreakWord then - LineComplete(N) - else - begin - P := PStart + N - 1; - - while (P <> Last) and not CanWrapAfter(P^) and not (Brk[P - Buff] in [twSoft, twOptional]) - do - begin - case Brk[P - Buff + 1] of - twNo: ; // must not wrap after this char. - else - case (P + 1)^ of - ' ', FmCtl, ImgPan, BrkCh: - break; // can wrap before this char. - else - if WrapChar((P + 1)^) then - break; // can wrap before this char. - end; - end; - Inc(P); - end; - - while (P <> Last) and ((P + 1)^ = ' ') do - begin - Inc(P); - end; - if (P <> Last) and ((P + 1)^ = BrkCh) then - Inc(P); - {Line is too long, add spacer line to where it's clear} - Tmp := IMgr.GetNextWiderY(Y) - Y; - if Tmp > 0 then - begin - LR.LineHt := Tmp; - Inc(SectionHeight, Tmp); - LR.Ln := 0; - LR.Start := PStart; - Inc(Y, Tmp); - Lines.Add(LR); - end - else - begin {line is too long but do it anyway} - MaxWidth := Max(MaxWidth, FindTextSize(Canvas, PStart, P - PStart + 1, True).cx); - Finished := P = Last; - LineComplete(P - PStart + 1); - end; - end - end - else - begin {found space} - while (P + 1)^ = ' ' do - begin - if P = Last then - begin - Inc(P); - Dec(P); - end; - Inc(P); - end; - LineComplete(P - PStart + 1); - end; - end; - end; - end; - Curs := StartCurs + Len; - - if Assigned(Document.FirstLineHtPtr) and (Lines.Count > 0) then {used for List items} - with Lines[0] do - if (Document.FirstLineHtPtr^ = 0) then - Document.FirstLineHtPtr^ := YDraw + LineHt - Descent + SpaceBefore; - - DrawHeight := AccumImgBot - TopY; {in case image overhangs} - if DrawHeight < SectionHeight then - DrawHeight := SectionHeight; - Result := SectionHeight; - ContentBot := TopY + SectionHeight; - DrawBot := TopY + DrawHeight; - with Document do - begin - if not IsCopy and (SectionNumber mod 50 = 0) and (ThisCycle <> CycleNumber) - and (SectionCount > 0) then - TheOwner.htProgress(ProgressStart + ((100 - ProgressStart) * SectionNumber) div SectionCount); - ThisCycle := CycleNumber; {only once per cycle} - end; - - // BG, 28.08.2011: - if OwnerBlock.HideOverflow then - if MaxWidth > Width then - MaxWidth := Width; - - DrawRect.Left := X; - DrawRect.Top := DrawTop; - DrawRect.Right := DrawRect.Left + MaxWidth; - DrawRect.Bottom := DrawBot; - end; { DoDrawLogic} - -var - Dummy: Integer; - Save: Integer; -begin {TSection.DrawLogic} -{$IFDEF JPM_DEBUGGING_LOGIC} - CodeSite.EnterMethod(Self,'TSection.DrawLogic1'); -{$IFDEF JPM_DEBUGGING_LOGIC1} - CodeSite.SendFmtMsg('X, XRef = [%4d, %4d]', [X, XRef]); - CodeSite.SendFmtMsg('Y, YRef = [%4d, %4d]', [Y, YRef]); - CodeSite.SendFmtMsg('AWidth = [%d]',[AWidth]); - CodeSite.SendFmtMsg('AHeight = [%d]',[AHeight]); - CodeSite.SendFmtMsg('BlHt = [%d]',[BlHt]); - if Assigned(IMgr) then - begin - CodeSite.SendFmtMsg('IMgr.LfEdge = [%d]',[ IMgr.LfEdge ] ); - CodeSite.SendFmtMsg('IMgr.Width = [%d]',[ IMgr.Width ] ); - CodeSite.SendFmtMsg('IMgr.ClipWidth = [%d]',[ IMgr.ClipWidth ] ); - end - else - begin - CodeSite.SendMsg('IMgr = nil'); - end; - CodeSite.SendFmtMsg('MaxWidth = [%d]',[MaxWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.AddSeparator; -{$ENDIF} -{$ENDIF} - - YDraw := Y; - DrawTop := Y; - ContentTop := Y; - StartCurs := Curs; - Lines.Clear; - TextWidth := 0; - - if WhiteSpaceStyle in [wsPre, wsNoWrap] then - begin - if Len = 0 then - begin - Result := Fonts.GetFontObjAt(0).FontHeight; - SectionHeight := Result; - MaxWidth := 0; - DrawHeight := Result; - ContentBot := Y + Result; - DrawBot := ContentBot; - - DrawRect.Left := X; - DrawRect.Top := DrawTop; - DrawRect.Right := DrawRect.Left + MaxWidth; - DrawRect.Bottom := DrawRect.Top + SectionHeight; - exit; - end; - - if not BreakWord then - begin - {call with large width to prevent wrapping} - Save := IMgr.Width; - IMgr.Width := 32000; - DoDrawLogic; - IMgr.Width := Save; - MinMaxWidth(Canvas, Dummy, MaxWidth); {return MaxWidth} - DrawRect.Right := DrawRect.Left + MaxWidth; - exit; - end; - end; - - DoDrawLogic; - -{$IFDEF JPM_DEBUGGING_LOGIC} -{$IFDEF JPM_DEBUGGING_LOGIC1} - if Assigned(IMgr) then begin - CodeSite.SendFmtMsg('IMgr.LfEdge = [%d]',[ IMgr.LfEdge ] ); - CodeSite.SendFmtMsg('IMgr.Width = [%d]',[ IMgr.Width ] ); - CodeSite.SendFmtMsg('IMgr.ClipWidth = [%d]',[ IMgr.ClipWidth ] ); - end else begin - CodeSite.SendMsg('IMgr = nil'); - end; -{$ENDIF} - CodeSite.SendFmtMsg('MaxWidth = [%d]',[MaxWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.SendFmtMsg('Result = [%d]',[Result]); - CodeSite.ExitMethod(Self,'TSection.DrawLogic1'); -{$ENDIF} -end; - -{----------------TSection.CheckForInlines} - -procedure TSection.CheckForInlines(LR: ThtLineRec); -{called before each line is drawn the first time to check if there are any - inline borders in the line} -var - I: Integer; - BR: ThtBorderRec; - StartBI, EndBI, LineStart: Integer; -begin - with LR do - begin - FirstDraw := False; {this will turn it off if there is no inline border action in this line} - with TInlineList(Document.InlineList) do - for I := 0 to Count - 1 do {look thru the inlinelist} - begin - StartBI := StartB[I]; - EndBI := EndB[I]; - LineStart := StartCurs + (Start - Buff); {offset from Section start to Line start} - if (EndBI > LineStart) and (StartBI < LineStart + Ln) then - begin {it's in this line} - if not Assigned(BorderList) then - begin - BorderList := ThtBorderRecList.Create; - FirstDraw := True; {there will be more processing needed} - end; - BR := ThtBorderRec.Create; - BorderList.Add(BR); - with BR do - begin - BR.MargArray := Items[I].MargArray; {get border data} - if StartBI < LineStart then - begin - OpenStart := True; {continuation of border on line above, end is open} - BStart := Start - Buff; {start of this line} - end - else - begin - OpenStart := False; - BStart := StartBI - StartCurs; {start is in this line} - end; - if EndBI > LineStart + Ln then - begin - OpenEnd := True; {will continue on next line, end is open} - BEnd := Start - Buff + Ln; - end - else - begin - OpenEnd := False; - BEnd := EndBI - StartCurs; {end is in this line} - end; - end; - end; - end; - end; -end; - -{----------------TSection.Draw} - -function TSection.Draw1(Canvas: TCanvas; const ARect: TRect; - IMgr: TIndentManager; X, XRef, YRef: Integer): Integer; -var - MySelB, MySelE: Integer; - YOffset, Y, Desc: Integer; - - //>-- DZ 19.09.2012 - procedure AdjustDrawRect( aTop, aLeft, aWidth, aHeight: Integer ); overload; - begin - //dec( aTop, Document.YOff ); - - if DrawRect.Top > aTop then - DrawRect.Top:= aTop; - - if DrawRect.Left > aLeft then - DrawRect.Left:= aLeft; - - if DrawRect.Right < aLeft + aWidth then - DrawRect.Right:= aLeft + aWidth; - - if DrawRect.Bottom < aTop + aHeight then - DrawRect.Bottom:= aTop + aHeight; - end; - - //>-- DZ 19.09.2012 - procedure AdjustDrawRect( const aRect: TRect ); overload; - begin - AdjustDrawRect( aRect.Top, aRect.Left, aRect.Right - aRect.Left, aRect.Bottom - aRect.Top ); - end; - - procedure DrawTheText(LineNo: Integer); - var - I, J, J1, J2, J3, J4, - Addon, TopP, BottomP, LeftT, Tmp, K: Integer; - FlObj: TFloatingObj; - FcObj: TFormControlObj; - FO: TFontObj; - ARect: TRect; - Inverted, NewCP: Boolean; - ForeColor, BackColor: TColor; - BkMode: Integer; - CPx, CPy, CP1x: Integer; - BR: ThtBorderRec; - LR: ThtLineRec; - Start: PWideChar; - Cnt, Descent: Integer; - St: ThtString; - - function AddHyphen(P: PWideChar; N: Integer): ThtString; - var - I: Integer; - begin - SetLength(Result, N + 1); - for I := 1 to N do - Result[I] := P[I - 1]; - Result[N + 1] := ThtChar('-'); - end; - - function ChkInversion(Start: PWideChar; out Count: Integer): Boolean; - var - LongCount, C: Integer; - begin - Result := False; - C := Start - Buff; - Count := 32000; - if IsCopy then - Exit; - if (MySelE < MySelB) or ((MySelE = MySelB) and - not Document.ShowDummyCaret) then - Exit; - if (MySelB <= C) and (MySelE > C) then - begin - Result := True; - LongCount := MySelE - C; - end - else if MySelB > C then - LongCount := MySelB - C - else - LongCount := 32000; - if LongCount > 32000 then - Count := 32000 - else - Count := LongCount; - end; - - begin {Y is at bottom of line here} - LR := Lines[LineNo]; - Start := LR.Start; - Cnt := LR.Ln; - Descent := LR.Descent; - - NewCP := True; - CPy := Y + LR.DrawY; //Todo: Someone needs to find a sensible default value. - CPx := X + LR.LineIndent; - CP1x := CPx; - LR.DrawY := Y - LR.LineHt; - LR.DrawXX := CPx; - AdjustDrawRect( LR.DrawY, LR.DrawXX, LR.DrawWidth, LR.LineHt ); //>-- DZ 19.09.2012 - while Cnt > 0 do - begin - I := 1; - J1 := Fonts.GetFontObjAt(Start - Buff, Len, FO) - 1; - J2 := Images.GetObjectAt(Start - Buff, FlObj) - 1; - J4 := FormControls.GetObjectAt(Start - Buff, FcObj) - 1; - - {if an inline border, find it's boundaries} - if LR.FirstDraw and Assigned(LR.BorderList) then - for K := 0 to LR.BorderList.Count - 1 do {may be several inline borders} - begin - BR := LR.BorderList[K]; - if (Start - Buff = BR.BStart) then - begin {this is it's start} - BR.bRect.Top := Y - FO.GetHeight(Desc) - Descent + Desc + 1; - BR.bRect.Left := CPx; - BR.bRect.Bottom := Y - Descent + Desc; - end - else if (Start - Buff = BR.BEnd) and (BR.bRect.Right = 0) then - BR.bRect.Right := CPx {this is it's end} - else if (Start - Buff > BR.BStart) and (Start - Buff < BR.BEnd) then - begin {this is position within boundary, it's top or bottom may enlarge} - BR.bRect.Top := Min(BR.bRect.Top, Y - FO.GetHeight(Desc) - Descent + Desc + 1); - BR.bRect.Bottom := Max(BR.bRect.Bottom, Y - Descent + Desc); - end; - end; - - FO.TheFont.AssignToCanvas(Canvas); - ForeColor := Canvas.Font.Color; - BackColor := FO.TheFont.bgColor; - if ForeColor <> clNone then - ForeColor := ThemedColor(ForeColor{$ifdef has_StyleElements},seFont in Document.StyleElements{$endif}); - if BackColor <> clNone then - BackColor := ThemedColor(BackColor{$ifdef has_StyleElements},seFont in Document.StyleElements{$endif}); - Canvas.Font.Color := ForeColor; - if J2 = -1 then - begin {it's an image or panel} - if FlObj is TImageObj then - begin - if FlObj.Floating in [ALeft, ARight] then - begin - //BG, 02.03.2011: Document is the Document, thus we must - // feed it with document coordinates: X,Y is in document coordinates, - // but might not be the coordinates of the upper left corner of the - // containing block, the origin of the Obj's coordinates. If each block - // had its own IMgr and nested blocks had nested IMgrs with coordinates - // relative to the containing block, the document coordinates of an inner - // block were the sum of all LfEdges of the containing blocks. - // - // correct x-position for floating images: IMgr.LfEdge + Obj.Indent - if not LR.FirstDraw then - Document.DrawList.AddImage(TImageObj(FlObj), Canvas, - IMgr.LfEdge + FlObj.FIndent, FlObj.DrawYY, Y - Descent, FO) - else if Assigned(LR.BorderList) then - {if a boundary is on a floating image, remove it} - for K := LR.BorderList.Count - 1 downto 0 do - begin - BR := LR.BorderList[K]; - if (Start - Buff = BR.BStart) and (BR.BEnd = BR.BStart + 1) then - LR.BorderList.Delete(K); - end; - end - else - begin - SetTextJustification(Canvas.Handle, 0, 0); -// if OwnerBlock <> nil then -// FlObj.Positioning := OwnerBlock.Positioning -// else -// FlObj.Positioning := posStatic; - TImageObj(FlObj).DrawInline(Canvas, CPx + FlObj.HSpaceL, LR.DrawY, Y - Descent, FO); - {see if there's an inline border for the image} - if LR.FirstDraw and Assigned(LR.BorderList) then - for K := 0 to LR.BorderList.Count - 1 do - begin - BR := LR.BorderList[K]; - if (Start - Buff >= BR.BStart) and (Start - Buff <= BR.BEnd) then - begin {there is a border here, find the image dimensions} - TopP := 0; - if not (FlObj.Positioning in [posAbsolute, posFixed]) then - begin - case FlObj.VertAlign of - - ATop, ANone: - TopP := Y - LR.LineHt + FlObj.VSpaceT; - - AMiddle: - TopP := Y - Descent + FO.Descent - FO.tmHeight div 2 - (FlObj.ClientHeight - FlObj.VSpaceT + FlObj.VSpaceB) div 2; - - ABottom, ABaseline: - TopP := Y - Descent - FlObj.VSpaceB - FlObj.ClientHeight; - - end; - BottomP := TopP + FlObj.ClientHeight; - - if Start - Buff = BR.BStart then - begin {border starts at image} - BR.bRect.Top := TopP; - BR.bRect.Left := CPx + FlObj.HSpaceL; - if BR.BEnd = BR.BStart + 1 then {border ends with image also, rt side set by image width} - BR.bRect.Right := BR.bRect.Left + FlObj.ClientWidth; - BR.bRect.Bottom := BottomP; - end - else if Start - Buff <> BR.BEnd then - begin {image is included in border and may effect the border top and bottom} - BR.bRect.Top := Min(BR.bRect.Top, TopP); - BR.bRect.Bottom := Max(BR.bRect.Bottom, BottomP); - end; - end; - end; - end; - - if not (FlObj.Positioning in [posAbsolute, posFixed]) then - begin - CPx := CPx + FlObj.TotalWidth; - NewCP := True; - end; - end; - end - else - begin {it's a Panel or Frame} - if FlObj is TControlObj then - TControlObj(FlObj).ShowIt := True; - if FlObj.Floating in [ALeft, ARight] then - begin - LeftT := IMgr.LfEdge + FlObj.FIndent; - TopP := FlObj.DrawYY; - {check for border. For floating panel, remove it} - if LR.FirstDraw and Assigned(LR.BorderList) then - for K := LR.BorderList.Count - 1 downto 0 do - begin - BR := LR.BorderList[K]; - if (Start - Buff = BR.BStart) and (BR.BEnd = BR.BStart + 1) then - LR.BorderList.Delete(K); - end; - end - else - begin - LeftT := CPx + FlObj.HSpaceL; - case FlObj.VertAlign of - ANone, - ATop: TopP := Y - LR.LineHt + FlObj.VSpaceT; - - AMiddle: TopP := Y - FO.tmHeight div 2 - (FlObj.ClientHeight - FlObj.VSpaceT + FlObj.VSpaceB) div 2; - - ABottom, - ABaseline: TopP := Y - Descent - FlObj.ClientHeight - FlObj.VSpaceB; - else - TopP := 0; {to eliminate warning msg} - end; - {Check for border on inline panel} - if LR.FirstDraw and Assigned(LR.BorderList) then - for K := 0 to LR.BorderList.Count - 1 do - begin - BR := LR.BorderList[K]; - if (Start - Buff >= BR.BStart) and (Start - Buff <= BR.BEnd) then - begin - if (Start - Buff = BR.BStart) then - begin {border starts on panel} - BR.bRect.Top := TopP; - BR.bRect.Left := CPx + FlObj.HSpaceL; - if BR.BEnd = BR.BStart + 1 then {border also ends with panel} - BR.bRect.Right := BR.bRect.Left + FlObj.ClientWidth; - BR.bRect.Bottom := TopP + FlObj.ClientHeight; - end - else if Start - Buff = BR.BEnd then - else - begin {Panel is included in border, may effect top and bottom} - BR.bRect.Top := Min(BR.bRect.Top, TopP); - BR.bRect.Bottom := Max(BR.bRect.Bottom, TopP + FlObj.ClientHeight); - end; - end; - end; - Inc(CPx, FlObj.TotalWidth); - NewCP := True; - end; - - FlObj.DrawInline(Canvas, LeftT, TopP - YOffset, TopP - YOffset - Descent, FO); - - end; - end - else if J4 = -1 then - begin {it's a form control} - if not FcObj.Hidden then - begin - FcObj.ShowIt := True; - if FcObj.Floating in [ALeft, ARight] then - begin - LeftT := IMgr.LfEdge + FcObj.Indent; - TopP := FcObj.DrawYY - YOffset; - {check for border. For floating panel, remove it} - if LR.FirstDraw and Assigned(LR.BorderList) then - for K := LR.BorderList.Count - 1 downto 0 do - begin - BR := LR.BorderList[K]; - if (Start - Buff = BR.BStart) and (BR.BEnd = BR.BStart + 1) then - LR.BorderList.Delete(K); - end; - end - else - begin - LeftT := CPx + FcObj.HSpaceL; - case FcObj.VertAlign of - ANone, - ATop: TopP := LR.DrawY + FcObj.VSpaceT - YOffset; - AMiddle: TopP := Y - ((LR.LineHt + FcObj.ClientHeight) div 2) - YOffset; - ABaseline: TopP := Y - FcObj.ClientHeight - FcObj.VSpaceB - Descent - YOffset; {sits on baseline} - ABottom: TopP := Y - FcObj.ClientHeight - FcObj.VSpaceB - YOffset; - else - TopP := Y; {never get here} - end; - if FcObj is TRadioButtonFormControlObj then - Inc(Topp, 2) - else if FcObj is TCheckBoxFormControlObj then - Inc(Topp, 1); - - {Check for border} - if LR.FirstDraw and Assigned(LR.BorderList) then - for K := 0 to LR.BorderList.Count - 1 do - begin - BR := LR.BorderList[K]; - if (Start - Buff >= BR.BStart) and (Start - Buff <= BR.BEnd) then - begin - if (Start - Buff = BR.BStart) then - begin {border starts with Form control} - BR.bRect.Top := ToPP + YOffSet; - BR.bRect.Left := CPx + FcObj.HSpaceL; - if BR.BEnd = BR.BStart + 1 then {border is confined to form control} - BR.bRect.Right := BR.bRect.Left + FcObj.ClientWidth; - BR.bRect.Bottom := TopP + YOffSet + FcObj.ClientHeight; - end - else if Start - Buff = BR.BEnd then - else - begin {form control is included in border} - BR.bRect.Top := Min(BR.bRect.Top, ToPP + YOffSet); - BR.bRect.Bottom := Max(BR.bRect.Bottom, TopP + YOffSet + FcObj.ClientHeight); - end; - end; - end; - end; - - FcObj.DrawInline(Canvas, LeftT, TopP, TopP - Descent, FO); - - if not (FcObj.Floating in [ALeft, ARight]) then - begin - Inc(CPx, FcObj.TotalWidth); - NewCP := True; - end; - end; - end - else - begin - J := Min(J1, J2); - J := Min(J, J4); - Inverted := ChkInversion(Start, J3); - J := Min(J, J3 - 1); - I := Min(Cnt, J + 1); - - BkMode := Opaque; - if Inverted then - begin - if BackColor = clNone then - Canvas.Font.Color := ForeColor xor $FFFFFF - else - Canvas.Font.Color := BackColor; - BackColor := ForeColor; - end - else - if BackColor = clNone then - BkMode := Transparent; - - if BkMode = Opaque then - begin - Canvas.Brush.Color := BackColor; - Canvas.Brush.Style := bsSolid; -{$ifdef LCLgtk2} - // background is missing if Canvas.Brush.Color = GetBkColor(Canvas.Handle) - if Canvas.Brush.Color = GetBkColor(Canvas.Handle) then - Canvas.Brush.Color := Canvas.Brush.Color xor $010101; -{$endif} - end - else - Canvas.Brush.Style := bsClear; - SetBkMode(Canvas.Handle, BkMode); - - if Document.Printing then - begin - if Document.PrintMonoBlack and - (GetDeviceCaps(Canvas.Handle, NumColors) in [0..2]) then - begin - if Canvas.Font.Color <> clWhite then - Canvas.Font.Color := clBlack; {Print black} - end; - if not Document.PrintTableBackground then - begin - if (Canvas.Font.Color and $E0E0) = $E0E0 then - Canvas.Font.Color := $2A0A0A0; {too near white or yellow, make it gray} - end; - end; - - SetTextAlign(Canvas.Handle, TA_BaseLine); - {figure any offset for subscript or superscript} - with FO do - if SScript = ANone then - Addon := 0 - else if SScript = ASuper then - Addon := -(FontHeight div 3) - else - Addon := Descent div 2 + 1; - NewCP := NewCP or (Addon <> 0); - {calc a new CP if required} - if NewCP then - begin - CPy := Y - Descent + Addon - YOffset; - NewCP := Addon <> 0; - end; - - if not Document.NoOutput then - begin - Tmp := I; - if Cnt - I <= 0 then - case (Start + I - 1)^ of - ' ', BrkCh: - Dec(Tmp); {at end of line, don't show space or break} - end; - if (WhiteSpaceStyle in [wsPre, wsPreLine, wsNoWrap]) and not OwnerBlock.HideOverflow then - begin {so will clip in Table cells} - ARect := Rect(IMgr.LfEdge, Y - LR.LineHt - LR.SpaceBefore - YOffset, X + IMgr.ClipWidth, Y - YOffset + 1); - ExtTextOutW(Canvas.Handle, CPx, CPy, ETO_CLIPPED, @ARect, Start, Tmp, nil); - CP1x := CPx + GetTextExtent(Canvas.Handle, Start, Tmp).cx; - end - else - begin - if LR.Spaces = 0 then - SetTextJustification(Canvas.Handle, 0, 0) - else - SetTextJustification(Canvas.Handle, LR.Extra, LR.Spaces); - if not IsWin95 then {use TextOutW} - begin - if (Cnt - I <= 0) and LR.Shy then - begin - St := AddHyphen(Start, Tmp); - TextOutW(Canvas.Handle, CPx, CPy, PWideChar(St), Length(St)); - CP1x := CPx + GetTextExtent(Canvas.Handle, PWideChar(St), Length(St)).cx; - end - else - begin - TextOutW(Canvas.Handle, CPx, CPy, Start, Tmp); - CP1x := CPx + GetTextExtent(Canvas.Handle, Start, Tmp).cx; - end - end - else - begin {Win95} - {Win95 has bug which extends text underline for proportional font in TextOutW. - Use clipping to clip the extra underline.} - CP1x := CPx + GetTextExtent(Canvas.Handle, Start, Tmp).cx; - ARect := Rect(CPx, Y - LR.LineHt - LR.SpaceBefore - YOffset, CP1x, Y - YOffset + 1); - ExtTextOutW(Canvas.Handle, CPx, CPy, ETO_CLIPPED, @ARect, Start, Tmp, nil) - end; - end; - {Put in a dummy caret to show character position} - if Document.ShowDummyCaret and not Inverted - and (MySelB = Start - Buff) then - begin - Canvas.Pen.Color := Canvas.Font.Color; - Tmp := Y - Descent + FO.Descent + Addon - YOffset; - Canvas.Brush.Color := clWhite; - Canvas.Rectangle(CPx, Tmp, CPx + 1, Tmp - FO.FontHeight); - end; - end; - - if FO.Active or IsCopy and Assigned(Document.LinkDrawnEvent) - and (FO.UrlTarget.Url <> '') then - begin - Tmp := Y - Descent + FO.Descent + Addon - YOffset; - ARect := Rect(CPx, Tmp - FO.FontHeight, CP1x + 1, Tmp); - if FO.Active then - begin - Canvas.Font.Color := clBlack; {black font needed for DrawFocusRect} - Canvas.Handle; {Dummy call needed to make Delphi add font color change to handle} - if Document.TheOwner.ShowFocusRect then //MK20091107 - Canvas.DrawFocusRect(ARect); - end; - if Assigned(Document.LinkDrawnEvent) then - Document.LinkDrawnEvent(Document.TheOwner, Document.LinkPage, - FO.UrlTarget.Url, FO.UrlTarget.Target, ARect); - end; - CPx := CP1x; - - {the following puts a dummy caret at the very end of text if it should be there} - if Document.ShowDummyCaret and not Inverted - and ((MySelB = Len) and (Document.SelB = Document.Len)) - and (Cnt = I) and (LineNo = Lines.Count - 1) then - begin - Canvas.Pen.Color := Canvas.Font.Color; - Tmp := Y - Descent + FO.Descent + Addon - YOffset; - Canvas.Brush.Color := clWhite; - Canvas.Rectangle(CPx, Tmp, CPx + 1, Tmp - FO.FontHeight); - end; - - end; - Dec(Cnt, I); - Inc(Start, I); - end; - SetTextJustification(Canvas.Handle, 0, 0); - {at the end of this line. see if there are open borders which need right side set} - if LR.FirstDraw and Assigned(LR.BorderList) then - for K := 0 to LR.BorderList.Count - 1 do - begin - BR := LR.BorderList[K]; - if BR.OpenEnd or (BR.BRect.Right = 0) then - BR.BRect.Right := CPx; - - AdjustDrawRect(BR.bRect); //>-- DZ 19.09.2012 - end; - end; - - procedure DoDraw(I: Integer); - {draw the Ith line in this section} - var - BR: ThtBorderRec; - K: Integer; - XOffset: Integer; - begin - with Lines[I] do - begin - Inc(Y, LineHt + SpaceBefore); - if FirstDraw then - begin {see if any inline borders in this line} - CheckForInlines(Lines[I]); - if FirstDraw then {if there are, need a first pass to get boundaries} - begin - FirstX := X; - DrawTheText(I); - end; - end; - XOffset := X - FirstX; - FirstDraw := False; - Drawn := True; - if Assigned(BorderList) then {draw any borders found in this line} - for K := 0 to BorderList.Count - 1 do - begin - BR := BorderList[K]; - BR.DrawTheBorder(Canvas, XOffset, YOffSet, Document.Printing{$ifdef has_StyleElements}, Document.StyleElements{$endif}); - end; - DrawTheText(I); {draw the text, etc., in this line} - Inc(Y, SpaceAfter); - end; - Document.FirstPageItem := False; - end; - -var - I: Integer; - DC: HDC; -begin {TSection.Draw} - Y := YDraw; - Result := Y + SectionHeight; - - if (OwnerBlock <> nil) and (OwnerBlock.Positioning = posFixed) then - YOffset := 0 - else - YOffset := Document.YOff; - -{Only draw if will be in display rectangle} - if (Len > 0) and (Y - YOffset + DrawHeight + 40 >= ARect.Top) and (Y - YOffset - 40 < ARect.Bottom) then - begin - DC := Canvas.Handle; - SetTextAlign(DC, TA_BaseLine); - - MySelB := Document.SelB - StartCurs; - MySelE := Document.SelE - StartCurs; - for I := 0 to Lines.Count - 1 do - if Document.Printing then - with Lines[I] do - begin - if (Y + LineImgHt <= Document.PageBottom) then - begin - if (Y - YOffSet + LineImgHt - 1 > ARect.Top) then - DoDraw(I) - else - Inc(Y, SpaceBefore + LineHt + SpaceAfter); - end - else if (LineImgHt >= ARect.Bottom - ARect.Top) or Document.PageShortened then - DoDraw(I) - else - begin - if (OwnerBlock <> nil) and (OwnerBlock.Positioning = posAbsolute) then - DoDraw(I) - else if Y < Document.PageBottom then - Document.PageBottom := Y; {Dont' print, don't want partial line} - end; - end - else - with Lines[I] do - if ((Y - YOffset + LineImgHt + 40 >= ARect.Top) and (Y - YOffset - 40 < ARect.Bottom)) then - DoDraw(I) - else {do not completely draw extremely long paragraphs} - Inc(Y, SpaceBefore + LineHt + SpaceAfter); - end; -end; - -{----------------TSection.CopySelectedText} - -procedure TSection.CopySelectedText; -var - I, Strt, X1, X2: Integer; - MySelB, MySelE: Integer; - TextAdded: Boolean; -begin - TextAdded := False; - MySelB := Document.SelB - StartCurs; - MySelE := Document.SelE - StartCurs; - for I := 0 to Lines.Count - 1 do - with Lines.Items[I] do - begin - Strt := Start - Buff; - if (MySelE <= Strt) or (MySelB > Strt + Ln) then - Continue; - if MySelB - Strt > 0 then - X1 := MySelB - Strt - else - X1 := 0; - if MySelE - Strt < Ln then - X2 := MySelE - Strt - else - X2 := Ln; - if (I = Lines.Count - 1) and (X2 = Ln) then - Dec(X2); - Document.CB.AddText(Start + X1, X2 - X1); - // Something was copied. Possibly add CR. - TextAdded := True; - end; - if (MySelE > Len) and TextAdded then - Document.CB.AddTextCR('', 0); -end; - -{----------------TSection.PtInObject} - -function TSection.PtInObject(X, Y: Integer; out Obj: TObject; out IX, IY: Integer): Boolean; -{Y is distance from start of section} -begin - if Images.PtInObject(X, Y, Obj, IX, IY) then - Result := True - else - Result := inherited PtInObject(X, Y, Obj, IX, IY); -end; - -{----------------TSection.GetURL} - -function TSection.GetURL(Canvas: TCanvas; X, Y: Integer; - out UrlTarg: TUrlTarget; out FormControl: TIDObject{TImageFormControlObj}; - out ATitle: ThtString): ThtguResultType; - {Y is absolute} -var - I, L, Width, IX, IY, Posn: Integer; - FO: TFontObj; - LR: ThtLineRec; - IMap, UMap: Boolean; - MapItem: TMapItem; - ImageObj: TImageObj; - Tmp: ThtString; - - function MakeCopy(UrlTarget: TUrlTarget): TUrlTarget; - begin - Result := TUrlTarget.Create; - Result.Assign(UrlTarget); - end; - -begin - Result := []; - UrlTarg := nil; - FormControl := nil; -{First, check to see if in an image} - if (Images.Count > 0) and Images.PtInImage(X, Y, IX, IY, Posn, IMap, UMap, MapItem, ImageObj) then - begin - if ImageObj.Title <> '' then - begin - ATitle := ImageObj.Title; - Include(Result, guTitle); - end - else if ImageObj.Alt <> '' then - begin - ATitle := ImageObj.Alt; - Include(Result, guTitle); - end; - Document.ActiveImage := ImageObj; - if Assigned(ImageObj.MyFormControl) then - begin - FormControl := ImageObj.MyFormControl; - Include(Result, guControl); - TImageFormControlObj(FormControl).XTmp := IX; - TImageFormControlObj(FormControl).YTmp := IY; - end - else if UMap then - begin - if MapItem.GetURL(IX, IY, UrlTarg, Tmp) then - begin - Include(Result, guUrl); - if Tmp <> '' then - begin - ATitle := Tmp; - Include(Result, guTitle); - end; - end; - end - else - begin - FO := Fonts.GetFontObjAt(Posn); - if (FO.UrlTarget.Url <> '') then - begin {found an URL} - Include(Result, guUrl); - UrlTarg := MakeCopy(FO.UrlTarget); - Document.ActiveLink := FO; - if IMap then - UrlTarg.Url := UrlTarg.Url + '?' + IntToStr(IX) + ',' + IntToStr(IY); - end; - end; - end - else - begin - I := 0; - LR := nil; - with Lines do - begin - while I < Count do - begin - LR := Lines[I]; - if (Y > LR.DrawY) and (Y <= LR.DrawY + LR.LineHt) and LR.Drawn then - Break; - Inc(I); - end; - if I >= Count then - Exit; - end; - with LR do - begin - if X < DrawXX then - Exit; - Width := X - DrawXX; - if Spaces > 0 then - SetTextJustification(Canvas.Handle, Extra, Spaces); - L := FindCountThatFits(Canvas, Width, Start, Ln); - if Spaces > 0 then - SetTextJustification(Canvas.Handle, 0, 0); - if L >= Ln then - Exit; - FO := Fonts.GetFontObjAt(L + (Start - Buff)); - if (FO.UrlTarget.Url <> '') then {found an URL} - if not ((Start + L)^ = ImgPan) then {an image here would be in HSpace area} - begin - Include(Result, guUrl); - UrlTarg := MakeCopy(FO.UrlTarget); - Document.ActiveLink := FO; - end; - if (FO.Title <> '') then {found a Title} - if not ((Start + L)^ = ImgPan) then {an image here would be in HSpace area} - begin - ATitle := FO.Title; - Include(Result, guTitle); - end; - end; - end; -end; - -{----------------TSection.FindCursor} - -function TSection.FindCursor(Canvas: TCanvas; X, Y: Integer; - out XR, YR, CaretHt: Integer; out Intext: Boolean): Integer; -{Given an X, Y, find the character position and the resulting XR, YR position - for a caret along with its height, CaretHt. Coordinates are relative to this - section} -var - I, H, L, Width, TotalHt, L1, W, Delta, OHang: Integer; - LR: ThtLineRec; - -begin - Result := -1; - I := 0; H := ContentTop; L1 := 0; - if H >= Y then - Exit; - LR := nil; - while I < Lines.Count do - begin - LR := Lines[I]; - with LR do - TotalHt := LineHt + SpaceBefore + SpaceAfter; - if H + TotalHt > Y then - Break; - Inc(H, TotalHt); - Inc(I); - Inc(L1, LR.Ln); {L1 accumulates ThtChar count of previous lines} - end; - if (I >= Lines.Count) then - Exit; - - with LR do - begin - if X > LR.DrawXX + LR.DrawWidth then - Exit; - if X < LR.DrawXX - 10 then - Exit; - InText := True; - CaretHt := LineHt; - YR := H + SpaceBefore; - if X < DrawXX then - begin - Result := L1 + StartCurs; - InText := False; - Exit; - end; - Width := X - DrawXX; - if (Justify = FullJustify) and (Spaces > 0) then - SetTextJustification(Canvas.Handle, Extra, Spaces); - L := FindCountThatFits(Canvas, Width, Start, Ln); - W := FindTextSize(Canvas, Start, L, False).cx; - XR := DrawXX + W; - if L < Ln then - begin {check to see if passed 1/2 character mark} - Fonts.GetFontAt(L1 + L, OHang).AssignToCanvas(Canvas); - Delta := FindTextWidthA(Canvas, Start + L, 1); - if Width > W + (Delta div 2) then - begin - Inc(L); - Inc(XR, Delta); - end; - end - else - InText := False; - Result := L + L1 + StartCurs; - if Justify = FullJustify then - SetTextJustification(Canvas.Handle, 0, 0); - end; -end; - -{----------------TSection.FindString} - -function TSection.FindString(From: Integer; const ToFind: UnicodeString; MatchCase: Boolean): Integer; -{find the first occurance of the ThtString, ToFind, with a cursor value >= From. - ToFind is in lower case if MatchCase is False. ToFind is known to have a length of at least one. -} -var - P: PWideChar; - I: Integer; - ToSearch: UnicodeString; - -begin - Result := -1; - if (Len = 0) or (From >= StartCurs + Len) then - Exit; - if From < StartCurs then - I := 0 - else - I := From - StartCurs; - - if MatchCase then - ToSearch := BuffS - else - ToSearch := htLowerCase(BuffS); {ToFind already lower case} - - P := StrPosW(PWideChar(ToSearch) + I, PWideChar(ToFind)); - if Assigned(P) then - Result := StartCurs + (P - PWideChar(ToSearch)); -end; - -{----------------TSection.FindStringR} - -function TSection.FindStringR(From: Integer; const ToFind: UnicodeString; MatchCase: Boolean): Integer; -{find the first occurance of the ThtString, ToFind, with a cursor value <= to From. - ToFind is in lower case if MatchCase is False. ToFind is known to have a length of at least one. -} -var - P: PWideChar; - ToFindLen: word; - ToMatch, ToSearch: UnicodeString; - -begin - Result := -1; - if (Len = 0) or (From < StartCurs) then - Exit; - ToFindLen := Length(ToFind); - if (Len < ToFindLen) or (From - StartCurs + 1 < ToFindLen) then - Exit; - - if From >= StartCurs + Len then - ToSearch := BuffS {search all of BuffS} - else - ToSearch := Copy(BuffS, 1, From - StartCurs); {Search smaller part} - if not MatchCase then - ToSearch := htLowerCase(ToSearch); {ToFind already lower case} - -{search backwards for the end ThtChar of ToFind} - P := StrRScanW(PWideChar(ToSearch), ToFind[ToFindLen]); - while Assigned(P) and (P - PWideChar(ToSearch) + 1 >= ToFindLen) do - begin - {pick out a ThtString of proper length from end ThtChar to see if it matches} - SetString(ToMatch, P - ToFindLen + 1, ToFindLen); - if WideSameStr1(ToFind, ToMatch) then - begin {matches, return the cursor position} - Result := StartCurs + (P - ToFindLen + 1 - PWideChar(ToSearch)); - Exit; - end; - {doesn't match, shorten ThtString to search for next search} - ToSearch := Copy(ToSearch, 1, P - PWideChar(ToSearch)); - {and search backwards for end ThtChar again} - P := StrRScanW(PWideChar(ToSearch), ToFind[ToFindLen]); - end; -end; - -{----------------TSection.FindSourcePos} - -function TSection.FindSourcePos(DocPos: Integer): Integer; -var - I: Integer; - IO: ThtIndexObj; -begin - Result := -1; - if (Len = 0) or (DocPos >= StartCurs + Len) then - Exit; - - for I := SIndexList.Count - 1 downto 0 do - begin - IO := PosIndex[I]; - if IO.Pos <= DocPos - StartCurs then - begin - Result := IO.Index + DocPos - StartCurs - IO.Pos; - break; - end; - end; -end; - -{----------------TSection.FindDocPos} - -function TSection.FindDocPos(SourcePos: Integer; Prev: Boolean): Integer; -{for a given Source position, find the nearest document position either Next or - previous} -var - I: Integer; - IO, IOPrev: ThtIndexObj; -begin - Result := -1; - if Len = 0 then - Exit; - - if not Prev then - begin - I := SIndexList.Count - 1; - IO := PosIndex[I]; - if SourcePos > IO.Index + (Len - 1) - IO.Pos then - Exit; {beyond this section} - - IOPrev := PosIndex[0]; - if SourcePos <= IOPrev.Index then - begin {in this section but before the start of Document text} - Result := StartCurs; - Exit; - end; - - for I := 1 to SIndexList.Count - 1 do - begin - IO := PosIndex[I]; - if (SourcePos >= IOPrev.Index) and (SourcePos < IO.Index) then - begin {between IOprev and IO} - if SourcePos - IOPrev.Index + IOPrev.Pos < IO.Pos then - Result := StartCurs + IOPrev.Pos + (SourcePos - IOPrev.Index) - else - Result := StartCurs + IO.Pos; - Exit; - end; - IOPrev := IO; - end; - {after the last ThtIndexObj in list} - Result := StartCurs + IOPrev.Pos + (SourcePos - IOPrev.Index); - end - else {prev -- we're iterating from the end of ThtDocument} - begin - IOPrev := PosIndex[0]; - if SourcePos < IOPrev.Index then - Exit; {before this section} - - I := SIndexList.Count - 1; - IO := PosIndex[I]; - if SourcePos > IO.Index + (Len - 1) - IO.Pos then - begin {SourcePos is after the end of this section} - Result := StartCurs + (Len - 1); - Exit; - end; - - for I := 1 to SIndexList.Count - 1 do - begin - IO := PosIndex[I]; - if (SourcePos >= IOPrev.Index) and (SourcePos < IO.Index) then - begin {between IOprev and IO} - if SourcePos - IOPrev.Index + IOPrev.Pos < IO.Pos then - Result := StartCurs + IOPrev.Pos + (SourcePos - IOPrev.Index) - else - Result := StartCurs + IO.Pos - 1; - Exit; - end; - IOPrev := IO; - end; - {after the last ThtIndexObj in list} - Result := StartCurs + IOPrev.Pos + (SourcePos - IOPrev.Index); - end; -end; - -{----------------TSection.CursorToXY} - -function TSection.CursorToXY(Canvas: TCanvas; Cursor: Integer; var X, Y: Integer): Boolean; -var - I, Curs: Integer; - LR: ThtLineRec; -begin - Result := False; - if (Len = 0) or (Cursor > StartCurs + Len) then - Exit; - - I := 0; - LR := nil; - Curs := Cursor - StartCurs; - Y := ContentTop; - with Lines do - begin - while I < Count do - begin - LR := Lines[I]; - with LR do - begin - if Curs < Ln then - Break; - Inc(Y, LineHt + SpaceBefore + SpaceAfter); - Dec(Curs, Ln); - end; - Inc(I); - end; - if I >= Count then - Exit; - end; - if Assigned(Canvas) then - begin - if LR.Spaces > 0 then - SetTextJustification(Canvas.Handle, LR.Extra, LR.Spaces); - X := LR.DrawXX + FindTextSize(Canvas, LR.Start, Curs, False).cx; - if LR.Spaces > 0 then - SetTextJustification(Canvas.Handle, 0, 0); - end - else - X := LR.DrawXX; - Result := True; -end; - -{----------------TSection.GetChAtPos} - -function TSection.GetChAtPos(Pos: Integer; out Ch: WideChar; out Obj: TSectionBase): Boolean; -begin - Result := False; - if (Len = 0) or (Pos < StartCurs) or (Pos >= StartCurs + Len) then - Exit; - Ch := Buff[Pos - StartCurs]; - Obj := Self; - Result := True; -end; - -{----------------TPanelObj.Create} - -constructor TPanelObj.Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties; ObjectTag: Boolean); -var - PntPanel: TWinControl; //TPaintPanel; - I: Integer; - Source, AName, AType: ThtString; -begin - inherited Create(Parent, Position, L, Prop); - VertAlign := ABottom; {default} - FFloating := ANone; - PntPanel := {TPaintPanel(}Document.PPanel{)}; - Panel := ThvPanel.Create(PntPanel); - Panel.Left := -4000; - Panel.Parent := PntPanel; - with Panel do - begin - FMyPanelObj := Self; - Top := -4000; - Height := 20; - Width := 30; - BevelOuter := bvNone; - BorderStyle := bsSingle; - Color := clWhite; - FVisible := True; -{$ifndef LCL} - Ctl3D := False; - ParentCtl3D := False; -{$endif} - ParentFont := False; -{$ifdef has_StyleElements} - Panel.StyleElements := Document.StyleElements; -{$endif} - end; - - if not PercentWidth and (SpecWidth > 0) then - Panel.Width := SpecWidth; - - if not PercentHeight and (SpecHeight > 0) then - Panel.Height := SpecHeight; - - for I := 0 to L.Count - 1 do - with L[I] do - case Which of - SrcSy: - Source := Name; - - NameSy: - begin - AName := Name; - try - Panel.Name := Name; - except {duplicate name will be ignored} - end; - end; - - AltSy: - begin - SetAlt(CodePage, Name); - Title := Alt; {use Alt as default Title} - end; - - BorderSy: - begin - NoBorder := Value = 0; - BorderWidth := Min(Max(0, Value), 10); - end; - - TypeSy: - AType := Name; - end; - - with Panel do - begin - Caption := ''; - if not ObjectTag and Assigned(Document.PanelCreateEvent) then - Document.PanelCreateEvent(Document.TheOwner, AName, AType, Source, Panel); - SetWidth := Width; - SetHeight := Height; - end; - Document.PanelList.Add(Self); -end; - -constructor TPanelObj.CreateCopy(Parent: TCellBasic; Source: THtmlNode); -var - T: TPanelObj absolute Source; -begin - inherited CreateCopy(Parent,Source); - Panel := ThvPanel.Create(nil); - with T.Panel do - Panel.SetBounds(Left, Top, Width, Height); - Panel.FVisible := T.Panel.FVisible; - Panel.Color := T.Panel.Color; - Panel.Parent := Document.PPanel; - SetHeight := T.SetHeight; - SetWidth := T.SetWidth; - OPanel := T.Panel; {save these for printing} - OSender := T.Document.TheOwner; - PanelPrintEvent := T.Document.PanelPrintEvent; -end; - -destructor TPanelObj.Destroy; -begin - if Assigned(Document) and Assigned(Document.PanelDestroyEvent) then - Document.PanelDestroyEvent(Document.TheOwner, Panel); - Panel.Free; - inherited Destroy; -end; - -procedure TPanelObj.DrawInline(Canvas: TCanvas; X, Y, YBaseline: Integer; FO: TFontObj); -var - Bitmap: TBitmap; - OldHeight, OldWidth: Integer; -begin - inherited DrawInline(Canvas,X,Y,YBaseline,FO); - if IsCopy then - begin - if Panel.FVisible then - begin - if Assigned(PanelPrintEvent) then - begin - Bitmap := TBitmap.Create; - OldHeight := Opanel.Height; - OldWidth := Opanel.Width; - try - Bitmap.Height := ClientHeight; - Bitmap.Width := ClientWidth; - OPanel.SetBounds(OPanel.Left, OPanel.Top, ClientWidth, ClientHeight); - PanelPrintEvent(OSender, OPanel, Bitmap); - PrintBitmap(Canvas, X, Y, ClientWidth, ClientHeight, Bitmap); - finally - OPanel.SetBounds(OPanel.Left, OPanel.Top, OldWidth, OldHeight); - end; - end; - end; - end - else - begin - if Panel.FVisible then - Panel.Show - else - Panel.Hide; - end; -end; - -//-- BG ---------------------------------------------------------- 15.12.2011 -- -function TPanelObj.GetBackgroundColor: TColor; -begin - if Panel <> nil then - Result := Panel.Color - else - Result := inherited GetBackgroundColor; -end; - -//-- BG ---------------------------------------------------------- 16.11.2011 -- -function TPanelObj.GetControl: TWinControl; -begin - Result := Panel; -end; - -{----------------TProgressObj.Create} - -constructor TProgressObj.Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties; ObjectTag: Boolean); -var - PntPanel: TWinControl; //TPaintPanel; - I: Integer; - PositionSet: Boolean; -begin - inherited Create(Parent, Position, L, Prop); - PositionSet := false; - VertAlign := ABottom; {default} - FFloating := ANone; - PntPanel := Document.PPanel; - Progress := ThvProgressBar.Create(PntPanel); - with Progress do - begin - Left := -4000; - Top := -4000; - Parent := PntPanel; - Max := 100; // making sure this is the default - Smooth := true; - Height := 20; - Width := 100; - Visible := True; -{$ifdef has_StyleElements} - StyleElements := Document.StyleElements; // TODO: does this work? Cannot see in Delphi 6 -{$endif} - end; - - if not PercentWidth and (SpecWidth > 0) then - Progress.Width := SpecWidth; - - if not PercentHeight and (SpecHeight > 0) then - Progress.Height := SpecHeight; - - for I := 0 to L.Count - 1 do - with L[I] do - case Which of - MaxSy: - Progress.Max := StrToIntDef( string(Name), 100 ); - - ValueSy: - begin - Progress.Position := StrToIntDef( string(Name), 0 ); - PositionSet := true; - end; - end; - - SetWidth := Progress.Width; - SetHeight := Progress.Height; - - // if the value attribute is not set, then the progressbar goes to the indeterminate state 'pbstMarquee'. - if PositionSet then - Progress.Style := pbstNormal - else - Progress.Style := pbstMarquee; -end; - -constructor TProgressObj.CreateCopy(Parent: TCellBasic; Source: THtmlNode); -var - T: TProgressObj absolute Source; -begin - inherited CreateCopy(Parent,Source); - Progress := ThvProgressBar.Create(nil); - with T.Progress do - Progress.SetBounds(Left, Top, Width, Height); - Progress.Visible := T.Progress.Visible; - Progress.Parent := Document.PPanel; - Progress.Max := T.Progress.Max; - Progress.Position := T.Progress.Position; - SetHeight := T.SetHeight; - SetWidth := T.SetWidth; -end; - -destructor TProgressObj.Destroy; -begin - Progress.Free; - inherited Destroy; -end; - -procedure TProgressObj.DrawInline(Canvas: TCanvas; X, Y, YBaseline: Integer; FO: TFontObj); -begin - inherited DrawInline(Canvas,X,Y,YBaseline,FO); - - if Progress.Visible then - Progress.Show - else - Progress.Hide; -end; - -function TProgressObj.GetControl: TWinControl; -begin - Result := Progress; -end; - - -{----------------TMeterObj.Create} - -constructor TMeterObj.Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties; ObjectTag: Boolean); -var - PntPanel: TWinControl; //TPaintPanel; - I: Integer; - //PositionSet: Boolean; -begin - inherited Create(Parent, Position, L, Prop); - //PositionSet := false; - VertAlign := ABottom; {default} - FFloating := ANone; - PntPanel := Document.PPanel; - Meter := ThvMeter.Create(PntPanel); - with Meter do - begin - Left := -4000; - Top := -4000; - Parent := PntPanel; - Max := 100; // making sure this is the default - Smooth := true; - Height := 20; - Width := 100; - Visible := True; -{$ifdef has_StyleElements} - StyleElements := Document.StyleElements; // TODO: does this work? Cannot see in Delphi 6 -{$endif} - end; - - if not PercentWidth and (SpecWidth > 0) then - Meter.Width := SpecWidth; - - if not PercentHeight and (SpecHeight > 0) then - Meter.Height := SpecHeight; - - for I := 0 to L.Count - 1 do - with L[I] do - case Which of - HighSy: - Meter.High := StrToIntDef( string(Name), 100 ); - - LowSy: - Meter.Low := StrToIntDef( string(Name), 0 ); - - MaxSy: - Meter.Max := StrToIntDef( string(Name), 100 ); - - MinSy: - Meter.Min := StrToIntDef( string(Name), 0 ); - - OptimumSy: - Meter.Optimum := StrToIntDef( string(Name), 50 ); - - ValueSy: - begin - Meter.Position := StrToIntDef( string(Name), 0 ); - //PositionSet := true; - end; - end; - - SetWidth := Meter.Width; - SetHeight := Meter.Height; - - - Meter.Style := pbstNormal; -end; - -constructor TMeterObj.CreateCopy(Parent: TCellBasic; Source: THtmlNode); -var - T: TMeterObj absolute Source; -begin - inherited CreateCopy(Parent,Source); - Meter := ThvMeter.Create(nil); - with T.Meter do - Meter.SetBounds(Left, Top, Width, Height); - Meter.Visible := T.Meter.Visible; - Meter.Parent := Document.PPanel; - Meter.Max := T.Meter.Max; - Meter.Position := T.Meter.Position; - SetHeight := T.SetHeight; - SetWidth := T.SetWidth; -end; - -destructor TMeterObj.Destroy; -begin - Meter.Free; - inherited Destroy; -end; - -procedure TMeterObj.DrawInline(Canvas: TCanvas; X, Y, YBaseline: Integer; FO: TFontObj); -begin - inherited DrawInline(Canvas,X,Y,YBaseline,FO); - - if Meter.Visible then - Meter.Show - else - Meter.Hide; -end; - -function TMeterObj.GetControl: TWinControl; -begin - Result := Meter; -end; - - - -{----------------TCell.Create} - -constructor TCell.Create(Parent: TBlock); -begin - {$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'TCell.Create'); - {$ENDIF} - inherited Create(Parent); - IMgr := TIndentManager.Create; - {$IFDEF JPM_DEBUGGING} - CodeSite.ExitMethod(Self,'TCell.Create'); - {$ENDIF} -end; - -{----------------TCell.CreateCopy} - -constructor TCell.CreateCopy(Parent: TBlock; T: TCellBasic); -begin - inherited CreateCopy(Parent, T); - IMgr := TIndentManager.Create; -end; - -destructor TCell.Destroy; -begin - IMgr.Free; - inherited Destroy; -end; - -{----------------TCell.DoLogic} - -function TCell.DoLogic(Canvas: TCanvas; Y: Integer; Width, AHeight, BlHt: Integer; - var ScrollWidth, Curs: Integer): Integer; -{Do the entire layout of the cell or document. Return the total document pixel height} -var - IB: Integer; - LIndex, RIndex: Integer; - SaveID: TObject; -begin -{$IFDEF JPM_DEBUGGING_LOGIC} - CodeSite.EnterMethod(Self,'TCell.DoLogic'); - CodeSite.SendFmtMsg('Y = [%d]',[Y]); - CodeSite.SendFmtMsg('Width = [%d]',[Width]); - CodeSite.SendFmtMsg('AHeight = [%d]',[AHeight]); - CodeSite.SendFmtMsg('BlHt = [%d]',[BlHt]); - CodeSite.SendFmtMsg('Cur = [%d]',[Curs]); - CodeSite.SendFmtMsg('ScrollWidth = [%d]',[ScrollWidth]); - CodeSite.AddSeparator; -{$ENDIF} - IMgr.Init(0, Width); - SaveID := IMgr.CurrentID; - IMgr.CurrentID := Self; - - LIndex := IMgr.SetLeftIndent(0, Y); - RIndex := IMgr.SetRightIndent(0 + Width, Y); - - Result := inherited DoLogic(Canvas, Y, Width, AHeight, BlHt, ScrollWidth, Curs); - - IMgr.FreeLeftIndentRec(LIndex); - IMgr.FreeRightIndentRec(RIndex); - IB := IMgr.ImageBottom - Y; //YValue; {check for image overhang} - IMgr.CurrentID := SaveID; - if IB > Result then - Result := IB; -{$IFDEF JPM_DEBUGGING_LOGIC} - CodeSite.SendFmtMsg('Result = [%d]',[Result]); - CodeSite.ExitMethod(Self,'TCell.DoLogic'); -{$ENDIF} -end; - -{----------------TCell.Draw} - -function TCell.Draw(Canvas: TCanvas; ARect: TRect; ClipWidth, X, Y, XRef, YRef: Integer): Integer; -{draw the document or cell. Note: individual sections not in ARect don't bother drawing} -begin - IMgr.Reset(X); - IMgr.ClipWidth := ClipWidth; - DrawYY := Y; {This is overridden in TCellObj.Draw} - Result := inherited Draw(Canvas, ARect, ClipWidth, X, Y, XRef, YRef); -end; - -{----------------TCellObjCell.CreateCopy} - -constructor TCellObjCell.CreateCopy(Parent: TBlock; T: TCellObjCell); -begin - inherited CreateCopy(Parent, T); - MyRect := T.MyRect; -end; - -{----------------TCellObjCell.GetUrl} - -function TCellObjCell.GetURL(Canvas: TCanvas; X, Y: Integer; out UrlTarg: TUrlTarget; - out FormControl: TIDObject{TImageFormControlObj}; out ATitle: ThtString): ThtguResultType; -{Y is absolute} -begin - Result := inherited GetUrl(Canvas, X, Y, UrlTarg, FormControl, ATitle); - if PtInRect(MyRect, Point(X, Y - Document.YOFF)) then - begin - if (not (guTitle in Result)) and (Title <> '') then - begin - ATitle := Title; - Include(Result, guTitle); - end; - if (not (guUrl in Result)) and (Url <> '') then - begin - UrlTarg := TUrlTarget.Create; - UrlTarg.URL := Url; - UrlTarg.Target := Target; - Include(Result, guUrl); - end; - end; -end; - -{ TBlockCell } - -function TBlockCell.DoLogicX(Canvas: TCanvas; X, Y, XRef, YRef, Width, AHeight, BlHt: Integer; - out ScrollWidth: Integer; var Curs: Integer): Integer; -{Do the entire layout of the this cell. Return the total pixel height} - - function DoBlockLogic: Integer; - // Returns CellHeight - var - I, Sw, Tmp: Integer; - SB: TSectionBase; - begin - Result := 0; - for I := 0 to Count - 1 do - begin - SB := Items[I]; - Sw := 0; - Tmp := SB.DrawLogic1(Canvas, X, Y + Result, XRef, YRef, Width, AHeight, BlHt, IMgr, Sw, Curs); - Inc(Result, Tmp); - if OwnerBlock.HideOverflow then - ScrollWidth := Width - else - ScrollWidth := Max(ScrollWidth, Sw); - if SB is TSection then - TextWidth := Max(TextWidth, TSection(SB).TextWidth); - if not (SB is TBlock) or (TBlock(SB).Positioning <> posAbsolute) then - tcContentBot := Max(tcContentBot, SB.ContentBot); - tcDrawTop := Min(tcDrawTop, SB.DrawTop); - tcDrawBot := Max(tcDrawBot, SB.DrawBot); - end; - end; - -//TODO -oBG, 15.03.2014: support display:inline -{$ifdef DO_PD_INLINE} -// function DoInlineLogic: Integer; -// // Returns CellHeight -// var -// I, Sw, Tmp: Integer; -// LineSize: TSize; -// SB: TSectionBase; -// SC: TSection; -// begin -// Result := 0; -// LineSize.cx := 0; -// LineSize.cy := 0; -// for I := 0 to Count - 1 do -// begin -// SB := Items[I]; -// if SB is TSection then -// SC := TSection(SB) -// else -// SC := nil; -// Tmp := SB.DrawLogic1(Canvas, X + LineSize.cx, Y + Result, XRef, YRef, Width, AHeight, BlHt, IMgr, Sw, Curs); -// if (SC <> nil) {and (SC.WhiteSpaceStyle in [wsPre, wsNoWrap])} then -// begin -// // Each section accumulates elements up to complete lines. -// Inc(Result, Tmp); -// if OwnerBlock.HideOverflow then -// ScrollWidth := Width -// else -// ScrollWidth := Max(ScrollWidth, Sw); -// TextWidth := Max(TextWidth, TSection(SB).TextWidth); -// end -// else -// begin -// if LineSize.cy < Tmp then -// LineSize.cy := Tmp; -// Inc(LineSize.cx, SB.DrawRect.Right - SB.DrawRect.Left); -// if LineSize.cx > Width then -// begin -// Inc(Result, LineSize.cy); -// if OwnerBlock.HideOverflow then -// ScrollWidth := Width -// else -// ScrollWidth := Max(ScrollWidth, LineSize.cx); -// if TextWidth < LineSize.cx then -// TextWidth := LineSize.cx; -// LineSize.cx := 0; -// LineSize.cy := 0; -// end; -// end; -// if not (SB is TBlock) or (TBlock(SB).Positioning <> posAbsolute) then -// tcContentBot := Max(tcContentBot, SB.ContentBot); -// tcDrawTop := Min(tcDrawTop, SB.DrawTop); -// tcDrawBot := Max(tcDrawBot, SB.DrawBot); -// end; -// Inc(Result, LineSize.cy); -// end; -{$endif} - -begin - {$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'TBlockCell.DoLogicX'); - CodeSite.SendFmtMsg('Y = [%d]',[Y]); - CodeSite.SendFmtMsg('Width = [%d]',[Width]); - CodeSite.SendFmtMsg('AHeight = [%d]',[AHeight]); - CodeSite.SendFmtMsg('BlHt = [%d]',[BlHt]); - CodeSite.SendFmtMsg('Cur = [%d]',[Curs]); - CodeSite.SendFmtMsg('ScrollWidth = [%d]',[ScrollWidth]); - CodeSite.AddSeparator; - {$ENDIF} -// YValue := Y; - StartCurs := Curs; - - ScrollWidth := 0; - TextWidth := 0; - tcContentBot := 0; - tcDrawTop := 990000; - tcDrawBot := 0; - -//TODO -oBG, 15.03.2014: support display:inline -{$ifdef DO_PD_INLINE} - if CalcDisplayExtern = pdInline then - CellHeight := DoInlineLogic - else -{$endif} - CellHeight := DoBlockLogic; - - Len := Curs - StartCurs; - Result := CellHeight; - {$IFDEF JPM_DEBUGGING} - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.SendFmtMsg('Result = [%d]',[Result]); - CodeSite.ExitMethod(Self,'TBlockCell.DoLogicX'); - {$ENDIF} -end; - - -{ TDrawList } - -type - TImageRec = class(TObject) - public - AObj: TImageObj; - ACanvas: TCanvas; - AX, AY: Integer; - AYBaseline: Integer; - AFO: TFontObj; - end; - -procedure TDrawList.AddImage(Obj: TImageObj; Canvas: TCanvas; X, Y, YBaseline: Integer; FO: TFontObj); -var - Result: TImageRec; -begin - Result := TImageRec.Create; - Result.AObj := Obj; - Result.ACanvas := Canvas; - Result.AX := X; - Result.AY := Y; - Result.AYBaseline := YBaseline; - Result.AFO := FO; - Add(Result); -end; - -procedure TDrawList.DrawImages; -var - I: Integer; - Item: TObject; -begin - I := 0; - while I < Count do {note: Count may increase during this operation} - begin - Item := Items[I]; - if (Item is TImageRec) then - with TImageRec(Item) do - AObj.DrawInline(ACanvas, AX, AY, AYBaseline, AFO); - Inc(I); - end; -end; - -{----------------TFormRadioButton.GetChecked:} - -function TFormRadioButton.GetChecked: Boolean; -begin - Result := FChecked; -end; - -procedure TFormRadioButton.CreateWnd; -begin - inherited CreateWnd; - inherited SetChecked(FChecked); -end; - -procedure TFormRadioButton.SetChecked(Value: Boolean); -begin - if GetKeyState(VK_TAB) < 0 then {ignore if tab key down} - Exit; - if FChecked <> Value then - begin - FChecked := Value; - TabStop := Value; - inherited SetChecked(FChecked); - end; -end; - -procedure TFormRadioButton.WMGetDlgCode(var Message: TMessage); -begin - Message.Result := DLGC_WantArrows; {else don't get the arrow keys} -end; - -{----------------ThtTabcontrol.Destroy} - -destructor ThtTabControl.Destroy; -var - ParentForm: TCustomForm; -begin - // if this control was focused, return focus to the parent - if Focused then - begin - ParentForm := GetParentForm(Self); - if Assigned(ParentForm) then - ParentForm.ActiveControl := Self.Parent; - end; - inherited Destroy; -end; - -procedure ThtTabcontrol.WMGetDlgCode(var Message: TMessage); -begin - Message.Result := DLGC_WantArrows; {this to eat the arrow keys} -end; - -{----------------ThtLineRec.Create} - -constructor ThtLineRec.Create(SL: ThtDocument); -begin - inherited Create; - if SL.InlineList.Count > 0 then - FirstDraw := True; -end; - -procedure ThtLineRec.Clear; -begin - FreeAndNil(BorderList); -end; - -destructor ThtLineRec.Destroy; -begin - BorderList.Free; - inherited Destroy; -end; - -{----------------ThtBorderRec.DrawTheBorder} - -procedure ThtBorderRec.DrawTheBorder(Canvas: TCanvas; XOffset, YOffSet: Integer; Printing: Boolean - {$ifdef has_StyleElements}; const AStyleElements : TStyleElements {$endif}); -var - IRect, ORect: TRect; -begin - IRect := BRect; - Dec(IRect.Top, YOffSet); - Dec(IRect.Bottom, YOffSet); - Inc(IRect.Left, XOffset); - Inc(IRect.Right, XOffset); - if OpenStart then - MargArray[BorderLeftStyle] := ord(bssNone); - if OpenEnd then - MargArray[BorderRightStyle] := ord(bssNone); - - if MargArray[BackgroundColor] <> clNone then - begin - Canvas.Brush.Color := ThemedColor(MargArray[BackgroundColor]{$ifdef has_StyleElements},seClient in AStyleElements{$endif}) or PalRelative; - Canvas.Brush.Style := bsSolid; - Canvas.FillRect(IRect); - end; - - ORect.Left := IRect.Left - MargArray[BorderLeftWidth]; - ORect.Top := IRect.Top - MargArray[BorderTopWidth]; - ORect.Right := IRect.Right + MargArray[BorderRightWidth]; - ORect.Bottom := IRect.Bottom + MargArray[BorderBottomWidth]; - - DrawBorder(Canvas, ORect, IRect, - htColors(MargArray[BorderLeftColor], MargArray[BorderTopColor], MargArray[BorderRightColor], MargArray[BorderBottomColor]), - htStyles(ThtBorderStyle(MargArray[BorderLeftStyle]), ThtBorderStyle(MargArray[BorderTopStyle]), ThtBorderStyle(MargArray[BorderRightStyle]), ThtBorderStyle(MargArray[BorderBottomStyle])), - MargArray[BackgroundColor], Printing{$ifdef has_StyleElements},AStyleElements{$endif}) -end; - -{----------------TPage.Draw1} - -constructor TPage.Create(Parent: TCellBasic; Attributes: TAttributeList; Properties: TProperties); -begin - inherited Create(Parent, Attributes, Properties); - if FDisplay = pdUnassigned then - FDisplay := pdBlock; -end; - -function TPage.Draw1(Canvas: TCanvas; const ARect: TRect; IMgr: TIndentManager; X, XRef, YRef: Integer): Integer; -var - YOffset, Y: Integer; -begin - Result := inherited Draw1(Canvas, ARect, Imgr, X, XRef, YRef); - if Document.Printing then - begin - Y := YDraw; - YOffset := Document.YOff; - if (Y - YOffset > ARect.Top + 5) and (Y - YOffset < ARect.Bottom) and (Y < Document.PageBottom) then - Document.PageBottom := Y; - end; -end; - -{----------------THorzLine.Create} - -constructor THorzLine.Create(Parent: TCellBasic; L: TAttributeList; Prop: TProperties); -var - LwName: ThtString; - I: Integer; - TmpColor: TColor; -begin - inherited Create(Parent, L, Prop); - if FDisplay = pdUnassigned then - FDisplay := pdBlock; - VSize := 2; - Align := Centered; - Color := clNone; - for I := 0 to L.Count - 1 do - with L[I] do - case Which of - SizeSy: if (Value > 0) and (Value <= 20) then - begin - VSize := Value; - end; - WidthSy: - if Value > 0 then - if Pos('%', Name) > 0 then - begin - if (Value <= 100) then - Prop.Assign(IntToStr(Value) + '%', piWidth); - end - else - Prop.Assign(Value, piWidth); - ColorSy: if TryStrToColor(Name, False, Color) then - Prop.Assign(Color, StyleUn.Color); - AlignSy: - begin - LwName := Lowercase(Name); - if LwName = 'left' then - Align := Left - else if LwName = 'right' then - Align := Right; - end; - NoShadeSy: NoShade := True; - end; - UseDefBorder := not Prop.BorderStyleNotBlank; - Prop.Assign(VSize, piHeight); {assigns if no property exists yet} - TmpColor := Prop.GetOriginalForegroundColor; - if TmpColor <> clNone then - Color := TmpColor; - with Prop do - if (VarIsStr(Props[TextAlign])) and Originals[TextAlign] then - if Props[TextAlign] = 'left' then - Align := Left - else if Props[TextAlign] = 'right' then - Align := Right - else if Props[TextAlign] = 'center' then - Align := Centered; -end; - -constructor THorzLine.CreateCopy(Parent: TCellBasic; Source: THtmlNode); -var - T: THorzLine absolute Source; -begin - inherited CreateCopy(Parent,Source); - System.Move(T.VSize, VSize, PtrSub(@BkGnd, @VSize) + Sizeof(BkGnd)); -end; - -procedure THorzLine.CopySelectedText; -begin - Document.CB.AddTextCR('', 0); -end; - -function THorzLine.DrawLogic1(Canvas: TCanvas; X, Y, XRef, YRef, AWidth, AHeight, BlHt: Integer; IMgr: TIndentManager; - var MaxWidth: Integer; var Curs: Integer): Integer; -begin - {$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'THorzLine.DrawLogic1'); - CodeSite.SendFmtMsg('X, XRef = [%4d, %4d]', [X, XRef]); - CodeSite.SendFmtMsg('Y, YRef = [%4d, %4d]', [Y, YRef]); - CodeSite.SendFmtMsg('AWidth = [%d]',[AWidth]); - CodeSite.SendFmtMsg('AHeight = [%d]',[AHeight]); - CodeSite.SendFmtMsg('BlHt = [%d]',[BlHt]); - if Assigned(IMgr) then begin - CodeSite.SendFmtMsg('IMgr.LfEdge = [%d]',[ IMgr.LfEdge ] ); - CodeSite.SendFmtMsg('IMgr.Width = [%d]',[ IMgr.Width ] ); - CodeSite.SendFmtMsg('IMgr.ClipWidth = [%d]',[ IMgr.ClipWidth ] ); - end else begin - CodeSite.SendMsg('IMgr = nil'); - end; - CodeSite.SendFmtMsg('MaxWidth = [%d]',[MaxWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.AddSeparator; - {$ENDIF} - YDraw := Y; - StartCurs := Curs; -{Note: VSize gets updated in THRBlock.FindWidth} - ContentTop := Y; - DrawTop := Y; - Indent := Max(0, IMgr.LeftIndent(Y) - X); - Width := Min(AWidth, IMgr.RightSide(Y) - X) - Indent; - MaxWidth := Width; - SectionHeight := VSize; - DrawHeight := SectionHeight; - ContentBot := Y + SectionHeight; - DrawBot := Y + DrawHeight; - Result := SectionHeight; - {$IFDEF JPM_DEBUGGING} - if Assigned(IMgr) then begin - CodeSite.SendFmtMsg('IMgr.LfEdge = [%d]',[ IMgr.LfEdge ] ); - CodeSite.SendFmtMsg('IMgr.Width = [%d]',[ IMgr.Width ] ); - CodeSite.SendFmtMsg('IMgr.ClipWidth = [%d]',[ IMgr.ClipWidth ] ); - end else begin - CodeSite.SendMsg('IMgr = nil'); - end; - CodeSite.SendFmtMsg('MaxWidth = [%d]',[MaxWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.SendFmtMsg('Result = [%d]',[Result]); - CodeSite.ExitMethod(Self,'THorzLine.DrawLogic1'); - {$ENDIF} -end; - -{----------------THorzLine.Draw} - -function THorzLine.Draw1(Canvas: TCanvas; const ARect: TRect; IMgr: TIndentManager; X, XRef, YRef: Integer): Integer; -var - XR: Integer; - YT, YO, Y: Integer; - White, BlackBorder: Boolean; -begin - Y := YDraw; - Result := inherited Draw1(Canvas, ARect, IMgr, X, XRef, YRef); - YO := Y - Document.YOff; - if (YO + SectionHeight >= ARect.Top) and (YO < ARect.Bottom) and (not Document.Printing or (Y < Document.PageBottom)) then - with Canvas do - begin - Inc(X, Indent); - YT := YO; - XR := X + Width - 1; - if Color <> clNone then - begin - Brush.Color := ThemedColor(Color {$ifdef has_StyleElements},seClient in Document.StyleElements{$endif}) or $2000000; - Brush.Style := bsSolid; - FillRect(Rect(X, YT, XR + 1, YT + VSize)); - end - else - begin - if UseDefBorder then begin - with Document do - begin - White := Printing or (ThemedColor(Background{$ifdef has_StyleElements},seFont in Document.StyleElements{$endif}) = clWhite); - BlackBorder := NoShade or (Printing and (GetDeviceCaps(Handle, BITSPIXEL) = 1) and (GetDeviceCaps(Handle, PLANES) = 1)); - end; - if BlackBorder then - Pen.Color := clBlack - else if White then - Pen.Color := clSilver - else - Pen.Color := ThemedColor(clBtnHighLight {$ifdef has_StyleElements},seClient in Document.StyleElements{$endif}); - MoveTo(XR, YT); - LineTo(XR, YT + VSize - 1); - LineTo(X, YT + VSize - 1); - if BlackBorder then - Pen.Color := clBlack - else - Pen.Color := ThemedColor(clBtnShadow{$ifdef has_StyleElements},seFont in Document.StyleElements{$endif}); - LineTo(X, YT); - LineTo(XR, YT); - end; - end; - Document.FirstPageItem := False; {items after this will not be first on page} - end; -end; - -{ THtmlPropStack } - -{ Add a TProperties to the PropStack. } -procedure THtmlPropStack.PushNewProp(Sym: TElemSymb; Properties: TProperties; Attributes: TAttributeList; const APseudo: ThtString = ''); -var - NewProp: TProperties; - Tag: ThtString; -begin - Tag := SymbToStr(Sym); - NewProp := TProperties.Create(Self, Document.UseQuirksMode); - NewProp.PropSym := Sym; - NewProp.Inherit(Tag, Last); - Add(NewProp); - NewProp.Combine(Document.Styles, Sym, Tag, APseudo, Properties, Attributes, Count - 1); -end; - -procedure THtmlPropStack.PopProp; -{pop and free a TProperties from the Prop stack} -var - TopIndex: Integer; -begin - TopIndex := Count - 1; - if TopIndex > 0 then - Delete(TopIndex); -end; - -procedure THtmlPropStack.PopAProp(Sym: TElemSymb); -{pop and free a TProperties from the Prop stack. It should be on top but in - case of a nesting error, find it anyway} -var - I, J: Integer; -begin - for I := Count - 1 downto 1 do - if Items[I].PropSym = Sym then - begin - if Items[I].HasBorderStyle then - {this would be the end of an inline border} - Document.ProcessInlines(SIndex, Items[I], False); - Delete(I); - if I > 1 then {update any stack items which follow the deleted one} - for J := I to Count - 1 do - Items[J].Update(Items[J - 1], Document.Styles, J); - Break; - end; -end; - -//-- BG ---------------------------------------------------------- 12.09.2010 -- -constructor THtmlStyleList.Create(AMasterList: ThtDocument); -begin - inherited Create; - Document := AMasterList; - Self.FUseQuirksMode := Document.UseQuirksMode; -end; - -//-- BG ---------------------------------------------------------- 08.03.2011 -- -procedure THtmlStyleList.SetLinksActive(Value: Boolean); -begin -// inherited SetLinksActive(Value); - Document.LinksActive := Value; -end; - -{ TFieldsetBlock } - -//-- BG ---------------------------------------------------------- 09.10.2010 -- -procedure TFieldsetBlock.ContentMinMaxWidth(Canvas: TCanvas; out Min, Max: Integer); -var - LegendMin, LegendMax: Integer; - ContentMin, ContentMax: Integer; -begin - Legend.MinMaxWidth(Canvas, LegendMin, LegendMax); - inherited ContentMinMaxWidth(Canvas, ContentMin, ContentMax); - Min := Math.Max(ContentMin, LegendMin); - Max := Math.Max(ContentMax, LegendMax); -end; - -//-- BG ---------------------------------------------------------- 06.10.2010 -- -procedure TFieldsetBlock.ConvMargArray(BaseWidth, BaseHeight: Integer; out AutoCount: Integer); -var - PaddTop, Delta: Integer; -begin - inherited ConvMargArray(BaseWidth, BaseHeight,AutoCount); - MargArray[MarginTop] := VMargToMarg(MargArrayO[MarginTop], False, BaseHeight, EmSize, ExSize, 10); - Delta := Legend.CellHeight - (MargArray[MarginTop] + MargArray[BorderTopWidth] + MargArray[PaddingTop]); - if Delta > 0 then - begin - PaddTop := Delta div 2; - MargArray[MarginTop] := MargArray[MarginTop] + Delta - PaddTop; - MargArray[PaddingTop] := MargArray[PaddingTop] + PaddTop; - end; -end; - -//-- BG ---------------------------------------------------------- 05.10.2010 -- -constructor TFieldsetBlock.Create(Parent: TCellBasic; Attributes: TAttributeList; Prop: TProperties); -var - Index: ThtPropIndices; -begin - inherited Create(Parent,Attributes,Prop); - HasBorderStyle := True; - for Index := BorderTopStyle to BorderLeftStyle do - if VarIsIntNull(MargArrayO[Index]) or VarIsEmpty(MargArrayO[Index]) then - MargArrayO[Index] := bssSolid; - for Index := BorderTopColor to BorderLeftColor do - if VarIsIntNull(MargArrayO[Index]) or VarIsEmpty(MargArrayO[Index]) then - MargArrayO[Index] := RGB(165, 172, 178); - for Index := BorderTopWidth to BorderLeftWidth do - if VarIsIntNull(MargArrayO[Index]) or VarIsEmpty(MargArrayO[Index]) then - MargArrayO[Index] := 1; -// for Index := MarginTop to MarginLeft do -// if VarIsIntNull(MargArrayO[Index]) or VarIsEmpty(MargArrayO[Index]) then -// MargArrayO[Index] := 10; - for Index := PaddingTop to PaddingLeft do - if VarIsIntNull(MargArrayO[Index]) or VarIsEmpty(MargArrayO[Index]) then - MargArrayO[Index] := 10; - FLegend := TBlockCell.Create(Self); -end; - -//-- BG ---------------------------------------------------------- 05.10.2010 -- -constructor TFieldsetBlock.CreateCopy(Parent: TCellBasic; Source: THtmlNode); -var - T: TFieldsetBlock absolute Source; -begin - inherited CreateCopy(Parent,Source); - FLegend := TBlockCell.CreateCopy(Self, T.FLegend); -end; - -//-- BG ---------------------------------------------------------- 05.10.2010 -- -destructor TFieldsetBlock.Destroy; -begin - FLegend.Free; - inherited Destroy; -end; - -//-- BG ---------------------------------------------------------- 06.10.2010 -- -function TFieldsetBlock.Draw1(Canvas: TCanvas; const ARect: TRect; IMgr: TIndentManager; X, XRef, YRef: Integer): Integer; -var - Rect: TRect; -begin - case Display of - pdNone: Result := 0; - else - Rect.Left := X + MargArray[MarginLeft] + MargArray[BorderLeftWidth] + MargArray[PaddingLeft] - 2; - Rect.Right := Rect.Left + Legend.TextWidth + 4; - Rect.Top := YDraw - Document.YOff; - Rect.Bottom := Rect.Top + Legend.CellHeight; - Legend.Draw(Canvas, ARect, ContentWidth, Rect.Left + 2, YDraw, XRef, YRef); - Rect := CalcClipRect(Canvas, Rect, Document.Printing); - ExcludeClipRect(Canvas.Handle, Rect.Left, Rect.Top, Rect.Right, Rect.Bottom); - Result := inherited Draw1(Canvas, ARect, IMgr, X, XRef, YRef); - end; -end; - -//-- BG ---------------------------------------------------------- 05.10.2010 -- -function TFieldsetBlock.DrawLogic1(Canvas: TCanvas; X, Y, XRef, YRef, AWidth, AHeight, BlHt: Integer; - IMgr: TIndentManager; var MaxWidth, Curs: Integer): Integer; -var - BorderWidth: TRect; - AutoCount, BlockHeight, ScrollWidth, L, LI, RI: Integer; - SaveID: TObject; -begin - {$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'TBlock.DrawLogic1'); - CodeSite.SendFmtMsg('Self.TagClass = [%s]', [Self.TagClass] ); - CodeSite.SendFmtMsg('X, XRef = [%4d, %4d]', [X, XRef]); - CodeSite.SendFmtMsg('Y, YRef = [%4d, %4d]', [Y, YRef]); - CodeSite.SendFmtMsg('AWidth = [%d]',[AWidth]); - CodeSite.SendFmtMsg('AHeight = [%d]',[AHeight]); - CodeSite.SendFmtMsg('BlHt = [%d]',[BlHt]); - if Assigned(IMgr) then begin - CodeSite.SendFmtMsg('IMgr.LfEdge = [%d]',[ IMgr.LfEdge ] ); - CodeSite.SendFmtMsg('IMgr.Width = [%d]',[ IMgr.Width ] ); - CodeSite.SendFmtMsg('IMgr.ClipWidth = [%d]',[ IMgr.ClipWidth ] ); - end else begin - CodeSite.SendMsg('IMgr = nil'); - end; - CodeSite.SendFmtMsg('MaxWidth = [%d]',[MaxWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.AddSeparator; - {$ENDIF} - case Display of - - pdNone: - begin - SectionHeight := 0; - DrawHeight := 0; - ContentBot := 0; - DrawBot := 0; - MaxWidth := 0; - Result := 0; - end; - - else - StyleUn.ConvMargArray(MargArrayO, AWidth, AHeight, EmSize, ExSize, self.BorderWidth, AutoCount, MargArray); - StyleUn.ApplyBoxSettings(MargArray,Document.UseQuirksMode); - BorderWidth.Left := MargArray[MarginLeft] + MargArray[BorderLeftWidth] + MargArray[PaddingLeft]; - BorderWidth.Right := MargArray[MarginRight] + MargArray[BorderRightWidth] + MargArray[PaddingRight]; - BorderWidth.Top := MargArray[MarginTop] + MargArray[BorderTopWidth] + MargArray[PaddingTop]; - if MargArray[piHeight] > 0 then - BlockHeight := MargArray[piHeight] - else if AHeight > 0 then - BlockHeight := AHeight - else - BlockHeight := BlHt; - - L := X + BorderWidth.Left; - ContentWidth := AWidth - BorderWidth.Left - BorderWidth.Right; - - SaveID := IMgr.CurrentID; - IMgr.CurrentID := Self; - Legend.IMgr := IMgr; - LI := IMgr.SetLeftIndent(L, Y); - RI := IMgr.SetRightIndent(L + ContentWidth, Y); - Legend.DoLogicX(Canvas, X + BorderWidth.Left, Y, XRef, YRef, ContentWidth, MargArray[piHeight], BlockHeight, ScrollWidth, Curs); - IMgr.FreeLeftIndentRec(LI); - IMgr.FreeRightIndentRec(RI); - IMgr.CurrentID := SaveID; - - Result := inherited DrawLogic1(Canvas, X, Y, XRef, YRef, AWidth, AHeight, BlHt, IMgr, MaxWidth, Curs); - end; - {$IFDEF JPM_DEBUGGING} - if Assigned(IMgr) then begin - CodeSite.SendFmtMsg('IMgr.LfEdge = [%d]',[ IMgr.LfEdge ] ); - CodeSite.SendFmtMsg('IMgr.Width = [%d]',[ IMgr.Width ] ); - CodeSite.SendFmtMsg('IMgr.ClipWidth = [%d]',[ IMgr.ClipWidth ] ); - end else begin - CodeSite.SendMsg('IMgr = nil'); - end; - CodeSite.SendFmtMsg('MaxWidth = [%d]',[MaxWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.SendFmtMsg('Result = [%d]',[Result]); - CodeSite.ExitMethod(Self,'TBlock.DrawLogic1'); - {$ENDIF} -end; - - -procedure TFormControlObj.SetValue(const Value: ThtString); -begin - FValue := Value; -end; - -//-- BG ---------------------------------------------------------- 16.01.2011 -- -procedure TFormControlObj.SetClientWidth(Value: Integer); -begin - TheControl.Width := Value; -end; - -//-- BG ---------------------------------------------------------- 16.01.2011 -- -procedure TFormControlObj.Show; -begin - TheControl.Show; -end; - -{ TFormControlObjList } - -//-- BG ---------------------------------------------------------- 15.01.2011 -- -procedure TFormControlObjList.ActivateTabbing; -var - I: Integer; -begin - for I := 0 to Count - 1 do - with Items[I] do - if not ShowIt and (TheControl <> nil) then - begin - TheControl.Show; {makes it tab active} - TheControl.Left := -4000; {even if it can't be seen} - end; -end; - -//-- BG ---------------------------------------------------------- 15.01.2011 -- -procedure TFormControlObjList.DeactivateTabbing; -var - I: Integer; -begin - for I := 0 to Count - 1 do - with Items[I] do - if not ShowIt and (TheControl <> nil) then - TheControl.Hide; {hides and turns off tabs} -end; - -//-- BG ---------------------------------------------------------- 15.01.2011 -- -function TFormControlObjList.GetItem(Index: Integer): TFormControlObj; -begin - Result := Get(Index); -end; - -{ TSizeableObj } - -//-- BG ---------------------------------------------------------- 12.11.2011 -- -procedure TSizeableObj.CalcSize(AvailableWidth, AvailableHeight, SetWidth, SetHeight: Integer; IsClientSizeSpecified: Boolean); -// Extracted from TPanelObj.DrawLogic() and TImageObj.DrawLogic() -begin - if PercentWidth then - begin - ClientWidth := MulDiv(AvailableWidth, SpecWidth, 100); - if SpecHeight > 0 then - if PercentHeight then - ClientHeight := MulDiv(AvailableHeight, SpecHeight, 100) - else - ClientHeight := SpecHeight - else - ClientHeight := MulDiv(ClientWidth, SetHeight, SetWidth); - end - else if PercentHeight then - begin - ClientHeight := MulDiv(AvailableHeight, SpecHeight, 100); - if SpecWidth > 0 then - ClientWidth := SpecWidth - else - ClientWidth := MulDiv(ClientHeight, SetWidth, SetHeight); - end - else if (SpecWidth > 0) and (SpecHeight > 0) then - begin {Both width and height specified} - ClientHeight := SpecHeight; - ClientWidth := SpecWidth; - ClientSizeKnown := True; - end - else if SpecHeight > 0 then - begin - ClientHeight := SpecHeight; - ClientWidth := MulDiv(SpecHeight, SetWidth, SetHeight); - ClientSizeKnown := IsClientSizeSpecified; - end - else if SpecWidth > 0 then - begin - ClientWidth := SpecWidth; - ClientHeight := MulDiv(SpecWidth, SetHeight, SetWidth); - ClientSizeKnown := IsClientSizeSpecified; - end - else - begin {neither height and width specified} - ClientHeight := SetHeight; - ClientWidth := SetWidth; - ClientSizeKnown := IsClientSizeSpecified; - end; -end; - -//-- BG ---------------------------------------------------------- 12.11.2011 -- -constructor TSizeableObj.Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties); -var - I: Integer; - NewHSpace: Integer; - NewVSpace: Integer; - S: ThtString; -begin - inherited Create(Parent,Position,L,Prop); - NewHSpace := -1; - NewVSpace := -1; - SpecHeight := -1; - SpecWidth := -1; - - for I := 0 to L.Count - 1 do - with L[I] do - case Which of - - HeightSy: - begin - if System.Pos('%', Name) = 0 then - begin - SpecHeight := Value; - end - else if (Value >= 0) and (Value <= 100) then - begin - SpecHeight := Value; - PercentHeight := True; - end; - end; - - WidthSy: - if System.Pos('%', Name) = 0 then - begin - SpecWidth := Value; - end - else if (Value >= 0) and (Value <= 100) then - begin - SpecWidth := Value; - PercentWidth := True; - end; - - HSpaceSy: - NewHSpace := Min(40, Abs(Value)); - - VSpaceSy: - NewVSpace := Min(40, Abs(Value)); - - AlignSy: - begin - S := htUpperCase(htTrim(Name)); - if S = 'TOP' then - VertAlign := ATop - else if (S = 'MIDDLE') or (S = 'ABSMIDDLE') then - VertAlign := AMiddle - else if S = 'LEFT' then - begin - VertAlign := ANone; - FFloating := ALeft; - end - else if S = 'RIGHT' then - begin - VertAlign := ANone; - FFloating := ARight; - end; - end; - end; - - if NewVSpace >= 0 then - begin - VSpaceT := NewVSpace; - VSpaceB := VSpaceT; - end; - - if NewHSpace >= 0 then - begin - HSpaceL := NewHSpace; - HSpaceR := HSpaceL; - end - else - begin - HSpaceR := HSpaceL; - if Self.Document.UseQuirksMode then - begin - case Floating of - ALeft : - begin - HSpaceL := 0; - HSpaceR := ImageSpace; - end; - ARight : - begin - HSpaceL := ImageSpace; - HSpaceR := 0; - end; - end; - end; - end; - -end; - -constructor TSizeableObj.CreateCopy(Parent: TCellBasic; Source: THtmlNode); -var - T: TSizeableObj absolute Source; -begin - inherited CreateCopy(Parent,Source); - BorderWidth := T.BorderWidth; - FAlt := T.FAlt; - FClientHeight := T.FClientHeight; - FClientWidth := T.FClientWidth; - ClientSizeKnown := T.ClientSizeKnown; - NoBorder := T.NoBorder; - SpecHeight := T.SpecHeight; - SpecWidth := T.SpecWidth; - Title := T.Title; -end; - -//-- BG ---------------------------------------------------------- 30.08.2013 -- -procedure TSizeableObj.DrawInline(Canvas: TCanvas; X, Y, YBaseline: Integer; FO: TFontObj); -begin - if not IsCopy then - begin - DrawXX := X; - DrawYY := Y; - end; -end; - -//-- BG ---------------------------------------------------------- 21.09.2016 -- -procedure TSizeableObj.DrawLogicInline(Canvas: TCanvas; FO: TFontObj; - AvailableWidth, AvailableHeight: Integer); -begin - -end; - -//-- BG ---------------------------------------------------------- 06.08.2013 -- -function TSizeableObj.GetClientHeight: Integer; -begin - Result := FClientHeight; -end; - -//-- BG ---------------------------------------------------------- 06.08.2013 -- -function TSizeableObj.GetClientWidth: Integer; -begin - Result := FClientWidth; -end; - -procedure TSizeableObj.ProcessProperties(Prop: TProperties); -const - DummyHtWd = 200; -var - MargArrayO: ThtVMarginArray; - Align: ThtAlignmentStyle; -begin - if Prop.GetVertAlign(Align) then - VertAlign := Align; - if Prop.GetFloat(Align) and (Align <> ANone) then - begin -// if HSpaceR = 0 then -// begin {default is different for Align = left/right} -// HSpaceR := ImageSpace; -// HSpaceL := ImageSpace; -// end; - VertAlign := ANone; - FFloating := Align; - end; - if Title = '' then {a Title attribute will have higher priority than inherited} - Title := Prop.PropTitle; - Prop.GetVMarginArray(MargArrayO); - EmSize := Prop.EmSize; - ExSize := Prop.ExSize; - ConvInlineMargArray(MargArrayO, DummyHtWd, DummyHtWd, EmSize, ExSize, BorderWidth, MargArray); - - if MargArray[MarginLeft] <> IntNull then - HSpaceL := MargArray[MarginLeft]; - if MargArray[MarginRight] <> IntNull then - HSpaceR := MargArray[MarginRight]; - if MargArray[MarginTop] <> IntNull then - VSpaceT := MargArray[MarginTop]; - if MargArray[MarginBottom] <> IntNull then - VSpaceB := MargArray[MarginBottom]; - - if MargArray[piWidth] <> IntNull then - begin - PercentWidth := False; - if MargArray[piWidth] <> Auto then - if (VarIsStr(MargArrayO[piWidth])) - and (System.Pos('%', MargArrayO[piWidth]) > 0) then - begin - PercentWidth := True; - SpecWidth := MulDiv(MargArray[piWidth], 100, DummyHtWd); - end - else - SpecWidth := MargArray[piWidth]; - end; - if MargArray[piHeight] <> IntNull then - begin - PercentHeight := False; - if MargArray[piHeight] <> Auto then - if (VarIsStr(MargArrayO[piHeight])) - and (System.Pos('%', MargArrayO[piHeight]) > 0) then - begin - PercentHeight := True; - SpecHeight := MulDiv(MargArray[piHeight], 100, DummyHtWd); - end - else - SpecHeight := MargArray[piHeight]; - end; - - if Prop.GetVertAlign(Align) then - VertAlign := Align; - if Prop.GetFloat(Align) and (Align <> ANone) then - FFloating := Align; - - if Prop.BorderStyleNotBlank then - begin - NoBorder := True; {will have inline border instead} - BorderWidth := 0; - end - else if Prop.HasBorderStyle then - begin - Inc(HSpaceL, MargArray[BorderLeftWidth]); - Inc(HSpaceR, MargArray[BorderRightWidth]); - Inc(VSpaceT, MargArray[BorderTopWidth]); - Inc(VSpaceB, MargArray[BorderBottomWidth]); - end; -end; - -//-- BG ---------------------------------------------------------- 14.10.2012 -- -function TSizeableObj.PtInDrawRect(X, Y: Integer; var IX, IY: Integer): Boolean; -var - XO, YO, W, H: Integer; -begin - if DrawRect.Left <> 999999999 then - Result := inherited PtInDrawRect(X, Y, IX, IY) - else - begin - // BG, 31.08.2013: deprecated. Method in base class does the same, doesn't it? - XO := X - DrawXX; {these are actual image, box if any is outside} - YO := Y - DrawYY; - W := ClientWidth - 2 * BorderWidth; - H := ClientHeight - 2 * BorderWidth; - Result := (XO >= 0) and (XO < W) and (YO >= 0) and (YO < H); - if Result then - begin - IX := XO; - IY := YO; - end; - end; -end; - -//-- BG ---------------------------------------------------------- 30.11.2010 -- -procedure TSizeableObj.SetAlt(CodePage: Integer; const Value: ThtString); -begin - FAlt := Value; - while Length(FAlt) > 0 do - case FAlt[Length(FAlt)] of - CrChar, LfChar: - Delete(FAlt, Length(FAlt), 1); - else - break; - end; -end; - -//-- BG ---------------------------------------------------------- 31.08.2013 -- -procedure TSizeableObj.SetClientHeight(Value: Integer); -begin - FClientHeight := Value; -end; - -//-- BG ---------------------------------------------------------- 31.08.2013 -- -procedure TSizeableObj.SetClientWidth(Value: Integer); -begin - FClientWidth := Value; -end; - -//-- BG ---------------------------------------------------------- 12.11.2011 -- -constructor TSizeableObj.SimpleCreate(Parent: TCellBasic); -begin - inherited Create(Parent, 0, nil, nil); - VertAlign := ABottom; {default} - NoBorder := True; - BorderWidth := 0; - SpecHeight := -1; - SpecWidth := -1; -end; - -{ TSectionBase } - -//-- BG ---------------------------------------------------------- 20.09.2009 -- -constructor TSectionBase.Create(Parent: TCellBasic; Attributes: TAttributeList; Properties: TProperties); -var - TheId, TheClass: ThtString; -begin - if Properties <> nil then - begin - TheID := Properties.PropID; - TheClass := Properties.PropClass; - end - else if Attributes <> nil then - begin - TheId := Attributes.TheId; - TheClass := Attributes.TheClass; - end; - Create(Parent, Attributes, Properties, TheId, TheClass); -end; - -//-- BG ---------------------------------------------------------- 20.09.2009 -- -constructor TSectionBase.Create(Parent: TCellBasic; Attributes: TAttributeList; Properties: TProperties; const TheId, TheClass: ThtString); -begin - inherited Create(Parent, Attributes, Properties, TheId); - if Properties <> nil then - begin - TagClass := Properties.PropTag; - end; - htAppendStr(TagClass, '.' + TheClass + '#' + TheId); - - ContentTop := 999999999; {large number in case it has Display: none; } - - DrawRect.Top := 999999999; - DrawRect.Left := 999999999; - DrawRect.Bottom := 0; - DrawRect.Right := 0; -end; - -constructor TSectionBase.CreateCopy(Parent: TCellBasic; Source: THtmlNode); -var - T: TSectionBase absolute Source; -begin - inherited CreateCopy(Parent,Source); - StartCurs := T.StartCurs; - Len := T.Len; - SectionHeight := T.SectionHeight; - ZIndex := T.ZIndex; -end; - -procedure TSectionBase.CopySelectedText; -begin -end; - -function TSectionBase.GetYPosition: Integer; -begin - Result := ContentTop; -end; - -function TSectionBase.DrawLogic1(Canvas: TCanvas; X, Y, XRef, YRef, AWidth, AHeight, BlHt: Integer; IMgr: TIndentManager; - var MaxWidth, Curs: Integer): Integer; -// Computes all coordinates of the section. -// -// Normal sections, absolutely positioned blocks and floating blocks start at given (X,Y) relative to document origin. -// Table cells start at given (X,Y) coordinates relative to the outmost containing block. -// -// Returns the nominal height of the section (without overhanging floating blocks) -var - ClearAddon: Integer; -begin -{$IFDEF JPM_DEBUGGING} - CodeSite.EnterMethod(Self,'TSectionBase.DrawLogic1'); - CodeSite.SendFmtMsg('X, XRef = [%4d, %4d]', [X, XRef]); - CodeSite.SendFmtMsg('Y, YRef = [%4d, %4d]', [Y, YRef]); - CodeSite.SendFmtMsg('AWidth = [%d]',[AWidth]); - CodeSite.SendFmtMsg('AHeight = [%d]',[AHeight]); - CodeSite.SendFmtMsg('BlHt = [%d]',[BlHt]); - if Assigned(IMgr) then - begin - CodeSite.SendFmtMsg('IMgr.LfEdge = [%d]',[ IMgr.LfEdge ] ); - CodeSite.SendFmtMsg('IMgr.Width = [%d]',[ IMgr.Width ] ); - CodeSite.SendFmtMsg('IMgr.ClipWidth = [%d]',[ IMgr.ClipWidth ] ); - end - else - begin - CodeSite.SendMsg('IMgr = nil'); - end; - CodeSite.SendFmtMsg('MaxWidth = [%d]',[MaxWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.AddSeparator; -{$ENDIF} - - case FDisplay of - pdNone: - ClearAddon := 0; - else - ClearAddon := GetClearSpace(IMgr, Y); - end; - - StartCurs := Curs; - Len := 0; - MaxWidth := 0; - SectionHeight := 0; - DrawHeight := SectionHeight; - YDraw := Y + ClearAddon; - - ContentTop := YDraw; - ContentBot := ContentTop + SectionHeight; - - DrawTop := YDraw; - DrawBot := DrawTop + DrawHeight; - - Result := ContentBot - Y; - - //>-- DZ - DrawRect.Top := DrawTop; - DrawRect.Left := X; - DrawRect.Right := DrawRect.Left + MaxWidth; - DrawRect.Bottom := DrawBot; -{$IFDEF JPM_DEBUGGING} - if Assigned(IMgr) then - begin - CodeSite.SendFmtMsg('IMgr.LfEdge = [%d]',[ IMgr.LfEdge ] ); - CodeSite.SendFmtMsg('IMgr.Width = [%d]',[ IMgr.Width ] ); - CodeSite.SendFmtMsg('IMgr.ClipWidth = [%d]',[ IMgr.ClipWidth ] ); - end - else - begin - CodeSite.SendMsg('IMgr = nil'); - end; - CodeSite.SendFmtMsg('MaxWidth = [%d]',[MaxWidth]); - CodeSite.SendFmtMsg('Curs = [%d]',[Curs]); - CodeSite.SendFmtMsg('Result = [%d]',[Result]); - CodeSite.ExitMethod(Self,'TSectionBase.DrawLogic1'); -{$ENDIF} -end; - -function TSectionBase.Draw1(Canvas: TCanvas; const ARect: TRect; IMgr: TIndentManager; X, XRef, YRef: Integer): Integer; -// returns the pixel row, where the section ends. -begin - Result := YDraw + SectionHeight; -end; - -function TSectionBase.GetURL(Canvas: TCanvas; X, Y: Integer; - out UrlTarg: TUrlTarget; out FormControl: TIDObject{TImageFormControlObj}; - out ATitle: ThtString): ThtguResultType; -begin - Result := []; - UrlTarg := nil; - FormControl := nil; -end; - -//-- BG ---------------------------------------------------------- 14.10.2012 -- -function TSectionBase.PtInDrawRect(X, Y: Integer; var IX, IY: Integer): Boolean; -// inspired by >-- DZ 19.09.2012 -begin - case Display of - pdNone: - Result := False; - else - // BG, 14.10.2012: why isn't there a Document.XOff representing the horizontal scroll position? - // Dec(X, Document.XOff); - //Dec(Y, Document.YOff); - Result := (X >= DrawRect.Left) and (X < DrawRect.Right) and (Y >= DrawRect.Top) and (Y < DrawRect.Bottom); - if Result then - begin - IX := X - DrawRect.Left; - IY := Y - DrawRect.Top; - end; - end; -end; - -//-- BG ---------------------------------------------------------- 14.10.2012 -- -function TSectionBase.PtInObject(X, Y: Integer; out Obj: TObject; out IX, IY: Integer): Boolean; -begin - Result := PtInDrawRect(X, Y, IX, IY); - if Result then - Obj := Self; -end; - -function TSectionBase.FindCursor(Canvas: TCanvas; X, Y: Integer; out XR, YR, CaretHt: Integer; out Intext: Boolean): Integer; -begin - Result := -1; - InText := False; -end; - -function TSectionBase.FindString(From: Integer; const ToFind: UnicodeString; MatchCase: Boolean): Integer; -begin - Result := -1; -end; - -function TSectionBase.FindStringR(From: Integer; const ToFind: UnicodeString; MatchCase: Boolean): Integer; -begin - Result := -1; -end; - -function TSectionBase.FindSourcePos(DocPos: Integer): Integer; -begin - Result := -1; -end; - -function TSectionBase.FindDocPos(SourcePos: Integer; Prev: Boolean): Integer; -begin - Result := -1; -end; - -function TSectionBase.CursorToXY(Canvas: TCanvas; Cursor: Integer; var X, Y: Integer): Boolean; -begin - Result := False; -end; - -function TSectionBase.GetChAtPos(Pos: Integer; out Ch: WideChar; out Obj: TSectionBase): Boolean; -begin - Result := False; - Ch := #0; - Obj := nil; -end; - -procedure TSectionBase.SetDocument(List: ThtDocument); -begin - FDocument := List; -end; - -procedure TSectionBase.MinMaxWidth(Canvas: TCanvas; out Min, Max: Integer); -begin - Min := 0; - Max := 0; -end; - -procedure TSectionBase.AddSectionsToList; -begin - Document.addSectionsToPositionList(Self); -end; - -{ TSectionBaseList } - -function TSectionBaseList.CursorToXY(Canvas: TCanvas; Cursor: Integer; var X, Y: Integer): Boolean; -var - I: Integer; -begin - Result := False; - for I := 0 to Count - 1 do - begin - Result := Items[I].CursorToXY(Canvas, Cursor, X, Y); - if Result then - Break; - end; -end; - -function TSectionBaseList.FindDocPos(SourcePos: Integer; Prev: Boolean): Integer; -var - I: Integer; -begin - Result := -1; - if not Prev then - for I := 0 to Count - 1 do - begin - Result := Items[I].FindDocPos(SourcePos, Prev); - if Result >= 0 then - Break; - end - else {Prev, iterate backwards} - for I := Count - 1 downto 0 do - begin - Result := Items[I].FindDocPos(SourcePos, Prev); - if Result >= 0 then - Break; - end -end; - -function TSectionBaseList.GetItem(Index: Integer): TSectionBase; -begin - Result := inherited Get(Index); -end; - -function TSectionBaseList.PtInObject(X, Y: Integer; var Obj: TObject; var IX, IY: Integer): Boolean; -{Y is absolute} -var - I: Integer; -begin - for I := 0 to Count - 1 do - if Items[I].PtInObject(X, Y, Obj, IX, IY) then - begin - Result := True; - Exit; - end; - Result := False; -end; - -{ TChPosObj } - -//-- BG ---------------------------------------------------------- 04.03.2011 -- -constructor TChPosObj.Create(Document: ThtDocument; Pos: Integer); -begin - inherited Create(''); - FChPos := Pos; - FDocument := Document; -end; - -//-- BG ---------------------------------------------------------- 06.03.2011 -- -function TChPosObj.FreeMe: Boolean; -begin - Result := True; -end; - -function TChPosObj.GetYPosition: Integer; -var - Pos, X, Y: Integer; -begin - Pos := Document.FindDocPos(ChPos, False); - if Document.CursorToXY(nil, Pos, X, Y) then - Result := Y - else - Result := 0; -end; - -{ TControlObj } - -//-- BG ---------------------------------------------------------- 12.11.2011 -- -procedure TControlObj.DrawInline(Canvas: TCanvas; X, Y, YBaseline: Integer; FO: TFontObj); -var - OldBrushStyle: TBrushStyle; - OldBrushColor: TColor; - OldPenColor: TColor; - SaveFont: TFont; -begin - inherited DrawInline(Canvas,X,Y,YBaseline,FO); - if IsCopy then - begin - OldBrushStyle := Canvas.Brush.Style; {save style first} - OldBrushColor := Canvas.Brush.Color; - OldPenColor := Canvas.Pen.Color; - Canvas.Pen.Color := ThemedColor(FO.TheFont.Color {$ifdef has_StyleElements},seFont in Document.StyleElements{$endif} ); - Canvas.Brush.Color := ThemedColor(BackgroundColor {$ifdef has_StyleElements},seClient in Document.StyleElements{$endif}); - Canvas.Brush.Style := bsSolid; - try - // paint a rectangular placeholder - Canvas.Rectangle(X, Y, X + ClientWidth, Y + ClientHeight); - if FAlt <> '' then - begin - // show the alternative text. - SaveFont := TFont.Create; - try - SaveFont.Assign(Canvas.Font); - Canvas.Font.Size := 8; - Canvas.Font.Name := FontSans; - WrapTextW(Canvas, X + 5, Y + 5, X + ClientWidth - 5, Y + ClientHeight - 5, FAlt); - finally - Canvas.Font := SaveFont; - SaveFont.Free; - end; - end; - finally - Canvas.Brush.Color := OldBrushColor; - Canvas.Brush.Style := OldBrushStyle; {style after color as color changes style} - Canvas.Pen.Color := OldPenColor; - end; - end - else - begin - ClientControl.Left := X; - ClientControl.Top := Y; - end; -end; - -procedure TControlObj.DrawLogicInline(Canvas: TCanvas; FO: TFontObj; AvailableWidth, AvailableHeight: Integer); -var - Control: TControl; -begin - if not ClientSizeKnown or PercentWidth or PercentHeight then - begin - CalcSize(AvailableWidth, AvailableHeight, SetWidth, SetHeight, True); - if not IsCopy then - if (ClientWidth > 0) and (ClientHeight > 0) then - begin - Control := ClientControl; - if Control <> nil then - Control.SetBounds(Control.Left, Control.Top, ClientWidth, ClientHeight); - end; - end; -end; - -//-- BG ---------------------------------------------------------- 15.12.2011 -- -function TControlObj.GetBackgroundColor: TColor; -begin - Result := clNone; -end; - -{ TFrameObj } - -//-- BG ---------------------------------------------------------- 12.11.2011 -- -constructor TFrameObj.Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties); -var - I: Integer; -begin - inherited Create(Parent,Position,L,Prop); - for I := 0 to L.Count - 1 do - with L[I] do - case Which of - SrcSy: - FSource := htTrim(Name); - - AltSy: - SetAlt(CodePage, Name); - - FrameBorderSy: - NoBorder := Value = 0; - - MarginWidthSy: - frMarginWidth := Value; - - MarginHeightSy: - frMarginHeight := Value; - - ScrollingSy: - NoScroll := htCompareText(Name, 'NO') = 0; {auto and yes work the same} - - end; - - CreateFrame; - try - UpdateFrame; - except - end; - SetWidth := FViewer.Width; - SetHeight := FViewer.Height; -end; - -//-- BG ---------------------------------------------------------- 12.11.2011 -- -constructor TFrameObj.CreateCopy(Parent: TCellBasic; Source: THtmlNode); -var - T: TFrameObj absolute Source; -begin - inherited CreateCopy(Parent,Source); - FSource := T.FSource; - frMarginWidth := T.frMarginWidth; - frMarginHeight := T.frMarginHeight; - NoScroll := T.NoScroll; - CreateFrame; -end; - -//-- BG ---------------------------------------------------------- 13.11.2011 -- -procedure TFrameObj.CreateFrame; -// Create a THtmlViewer, TFrameViewer or TFrameBrowser depending on host component. -var - PaintPanel: TPaintPanel; - HtmlViewer: THtmlViewer; -begin - PaintPanel := TPaintPanel(Document.PPanel); - HtmlViewer := PaintPanel.ParentViewer; - FViewer := HtmlViewer.CreateIFrameControl; - FViewer.Parent := PaintPanel; - if FSource <> '' then - begin - if Assigned(HtmlViewer.OnExpandName) then - HtmlViewer.OnExpandName(HtmlViewer, FSource, FUrl) - else - FUrl := HtmlViewer.HtmlExpandFilename(FSource); - end; -end; - -//-- BG ---------------------------------------------------------- 12.11.2011 -- -destructor TFrameObj.Destroy; -begin - FreeAndNil(FViewer); - inherited Destroy; -end; - -//-- BG ---------------------------------------------------------- 16.11.2011 -- -procedure TFrameObj.DrawInline(Canvas: TCanvas; X, Y, YBaseline: Integer; FO: TFontObj); -var - HtmlViewer: THtmlViewer; - Bitmap: TBitmap; -begin - // BG, 11.12.2011: frames aren't printable. - if FViewer is THtmlViewer then - begin - HtmlViewer := THtmlViewer(FViewer); - Bitmap := TBitmap.Create; - try - Bitmap.HandleType := bmDIB; - Bitmap.PixelFormat := pf24Bit; - Bitmap.Width := ClientWidth; - Bitmap.Height := ClientHeight; - HtmlViewer.Draw( - Bitmap.Canvas, - HtmlViewer.VScrollBar.Position, - HtmlViewer.Width, - ClientWidth, - ClientHeight); - PrintBitmap(Canvas, X, Y, ClientWidth, ClientHeight, Bitmap); - //Bitmap.SaveToFile(Format('C:\temp\%x.bmp', [Integer(Self)])); - finally - Bitmap.Free; - end; - end - else - inherited DrawInline(Canvas,X,Y,YBaseline,FO); -end; - -//-- BG ---------------------------------------------------------- 15.12.2011 -- -function TFrameObj.GetBackgroundColor: TColor; -begin - if FViewer <> nil then - Result := FViewer.DefBackground - else - Result := inherited GetBackgroundColor; -end; - -//-- BG ---------------------------------------------------------- 16.11.2011 -- -function TFrameObj.GetControl: TWinControl; -begin - Result := FViewer; -end; - -//-- BG ---------------------------------------------------------- 14.11.2011 -- -procedure TFrameObj.UpdateFrame; -var - LCurrentStyle: TFontStyles; {as set by , , etc.} - LCurrentForm: THtmlForm; - LPropStack: THtmlPropStack; - LNoBreak: Boolean; {set when in } -begin - if FUrl <> '' then - begin - LCurrentForm := Document.CurrentForm; - LCurrentStyle := Document.CurrentStyle; - LNoBreak := Document.NoBreak; - LPropStack := Document.PropStack; - Document.PropStack := THtmlPropStack.Create; - try - FViewer.Load(FUrl); - finally - Document.PropStack.Free; - Document.PropStack := LPropStack; - Document.CurrentForm := LCurrentForm; - Document.CurrentStyle := LCurrentStyle; - Document.NoBreak := LNoBreak; - end; - end; -end; - -{ TRowList } - -//-- BG ---------------------------------------------------------- 26.12.2011 -- -function TRowList.GetItem(Index: Integer): TCellList; -begin - Result := Get(Index); -end; - -{ TColSpecList } - -//-- BG ---------------------------------------------------------- 26.12.2011 -- -function TColSpecList.GetItem(Index: Integer): TColSpec; -begin - Result := Get(Index); -end; - -{ TColSpec } - -//-- BG ---------------------------------------------------------- 12.01.2012 -- -constructor TColSpec.Create(const Width: TSpecWidth; Align: ThtString; VAlign: ThtAlignmentStyle); -begin - inherited Create; - FWidth := Width; - FAlign := Align; - FVAlign := VAlign; -end; - -//-- BG ---------------------------------------------------------- 27.01.2012 -- -constructor TColSpec.CreateCopy(const ColSpec: TColSpec); -begin - Create(ColSpec.FWidth, ColSpec.FAlign, ColSpec.FVAlign); -end; - -{ TFloatingObj } - -//-- BG ---------------------------------------------------------- 12.11.2011 -- -function TFloatingObj.Clone(Parent: TCellBasic): TFloatingObj; -begin - Result := TFloatingObjClass(ClassType).CreateCopy(Parent, Self); -end; - -//-- BG ---------------------------------------------------------- 04.08.2013 -- -constructor TFloatingObj.Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties); -begin - inherited Create(Parent,Position,L,Prop); - StartCurs := Position; - VertAlign := ABottom; {default} -end; - -//-- BG ---------------------------------------------------------- 04.08.2013 -- -constructor TFloatingObj.CreateCopy(Parent: TCellBasic; Source: THtmlNode); -var - T: TFloatingObj absolute Source; -begin - inherited CreateCopy(Parent,Source); - System.Move(T.VertAlign, VertAlign, PtrSub(@PercentHeight, @VertAlign) + SizeOf(PercentHeight)); - DrawXX := T.DrawXX; - DrawYY := T.DrawYY; -end; - -//-- BG ---------------------------------------------------------- 08.09.2013 -- -function TFloatingObj.Draw1(Canvas: TCanvas; const ARect: TRect; IMgr: TIndentManager; X, XRef, YRef: Integer): Integer; -begin - Result := ContentBot; -end; - -//-- BG ---------------------------------------------------------- 08.09.2013 -- -function TFloatingObj.DrawLogic1(Canvas: TCanvas; X, Y, XRef, YRef, AWidth, AHeight, BlHt: Integer; IMgr: TIndentManager; - var MaxWidth, Curs: Integer): Integer; -begin - if Positioning in [posAbsolute, posFixed] then - Result := 0 - else - Result := SectionHeight; -end; - -//-- BG ---------------------------------------------------------- 14.02.2016 -- -function TFloatingObj.GetYPosition: Integer; -begin - Result := DrawYY; -end; - -//-- BG ---------------------------------------------------------- 02.03.2011 -- -function TFloatingObj.TotalHeight: Integer; -begin - Result := VSpaceT + ClientHeight + VSpaceB; -end; - -//-- BG ---------------------------------------------------------- 02.03.2011 -- -function TFloatingObj.TotalWidth: Integer; -begin - Result := HSpaceL + ClientWidth + HSpaceR; -end; - -{ TFloatingObjList } - -//-- BG ---------------------------------------------------------- 05.08.2013 -- -constructor TFloatingObjList.CreateCopy(Parent: TCellBasic; T: TFloatingObjList); -var - I: Integer; -begin - inherited Create; - if T <> nil then - for I := 0 to T.Count - 1 do - Add(T.Items[I].Clone(Parent)); -end; - -//-- BG ---------------------------------------------------------- 07.08.2013 -- -procedure TFloatingObjList.Decrement(N: Integer); -{called when a character is removed to change the Position figure} -var - I: Integer; -begin - for I := Count - 1 downto 0 do - with Items[I] do - if StartCurs > N then - Dec(StartCurs) - else - break; -end; - -//-- BG ---------------------------------------------------------- 07.08.2013 -- -function TFloatingObjList.FindObject(Posn: Integer): TFloatingObj; -{find the object at a given character position} -begin - if GetObjectAt(Posn, Result) <> 0 then - Result := nil; -end; - -//-- BG ---------------------------------------------------------- 07.08.2013 -- -function TFloatingObjList.GetItem(Index: Integer): TFloatingObj; -begin - Result := Get(Index); -end; - -//-- BG ---------------------------------------------------------- 05.08.2013 -- -function TFloatingObjList.GetObjectAt(Posn: Integer; out Obj): Integer; -var - I: Integer; -begin - for I := 0 to Count - 1 do - begin - Result := Items[I].StartCurs - Posn; - if Result >= 0 then - begin - TFloatingObj(Obj) := Items[I]; - Exit; - end; - end; - - TFloatingObj(Obj) := nil; - Result := 99999999; -end; - -//-- BG ---------------------------------------------------------- 05.08.2013 -- -function TFloatingObjList.PtInImage(X, Y: Integer; out IX, IY, Posn: Integer; out AMap, UMap: Boolean; out MapItem: TMapItem; out ImageObj: TImageObj): Boolean; - - function FindMap(const MapList: ThtMap; const MapName: ThtString): Boolean; - var - I: Integer; - begin - Result := False; - for I := 0 to MapList.Count - 1 do - begin - MapItem := MapList[I]; - if MapItem.MapName = MapName then - begin - Result := True; - break; - end; - end; - end; - -var - I: Integer; - Obj: TObject; - ImgObj: TImageObj absolute Obj; -begin - Result := False; - for I := 0 to Count - 1 do - begin - Obj := Items[I]; - if Obj is TImageObj then - begin - if ImgObj.PtInDrawRect(X, Y, IX, IY) then - begin - Result := True; - AMap := ImgObj.IsMap; - Posn := ImgObj.StartCurs; - UMap := False; - ImageObj := ImgObj; - if ImgObj.UseMap then - UMap := FindMap(ImgObj.Document.MapList, ImgObj.MapName); - break; - end; - end; - end; -end; - -//-- BG ---------------------------------------------------------- 05.08.2013 -- -function TFloatingObjList.PtInObject(X, Y: Integer; out Obj: TObject; out IX, IY: Integer): Boolean; -var - I: Integer; - Item: TFloatingObj; -begin - for I := 0 to Count - 1 do - begin - Item := Items[I]; - if Item.PtInDrawRect(X, Y, IX, IY) then - begin - Obj := Item; - Result := True; - Exit; - end; - end; - Result := False; -end; - -//-- BG ---------------------------------------------------------- 07.08.2013 -- -procedure TFloatingObjList.SetItem(Index: Integer; const Item: TFloatingObj); -begin - Put(Index, Item); -end; - -{ TBlockBase } - -//-- BG ---------------------------------------------------------- 31.08.2013 -- -constructor TBlockBase.Create(Parent: TCellBasic; Position: Integer; Attributes: TAttributeList; Prop: TProperties); -begin - inherited Create(Parent, Attributes, Prop); - if FDisplay = pdUnassigned then - FDisplay := pdBlock; - StartCurs := Position; -end; - -//-- BG ---------------------------------------------------------- 31.08.2013 -- -constructor TBlockBase.CreateCopy(Parent: TCellBasic; Source: THtmlNode); -//var -// T: TBlockBase absolute Source; -begin - inherited CreateCopy(Parent,Source); -end; - -//{ TRenderSectionBaseList } -// -////-- BG ---------------------------------------------------------- 01.12.2013 -- -//procedure TRenderSectionBaseList.Notify(Ptr: Pointer; Action: TListNotification); -//var -// Obj: TObject absolute Ptr; -//begin -// inherited; -// if (Action = lnDeleted) and (Obj is TInlineSection) then -// Obj.Free; -//end; -// -//{ TInlineSection } -// -////-- BG ---------------------------------------------------------- 01.12.2013 -- -//procedure TInlineSection.AddElement(Section: TSection); -//var -// I: Integer; -//begin -// // append Buff, Fonts, Images and FormControls -// BuffS := Buffs + Section.BuffS; -// Buff := PWideChar(Buffs); -// -// for I := 0 to Section.Fonts.Count - 1 do -// Fonts.Add(TFontObj.CreateCopy(Section, Section.Fonts[I])); -// -// for I := 0 to Section.Images.Count - 1 do -// Images.Add(Section.Images[I].Clone(Section.Images[I].OwnerCell)); -// -// for I := 0 to Section.FormControls.Count - 1 do -// FormControls.Add(Section.FormControls[I].Clone(Section.FormControls[I].OwnerCell)); -//end; -// -////-- BG ---------------------------------------------------------- 01.12.2013 -- -//constructor TInlineSection.Create(Parent: TCellBasic); -//begin -// inherited Create(Parent); -//end; - -//-- BG ---------------------------------------------------------- 24.02.2016 -- - -{ TLineBreak } - -//-- BG ---------------------------------------------------------- 24.02.2016 -- -function TLineBreak.TryGetClear(var Clear: ThtClearStyle): Boolean; -var - T: TAttribute; -begin - Result := inherited TryGetClear(Clear); - if not Result then - if FAttributes <> nil then - begin - T := nil; - if FAttributes.Find(ClearSy, T) then - Result := TryStrToClearStyle(LowerCase(T.Name), Clear); - end; -end; - -{ ThtIndexObjList } - -//-- BG ---------------------------------------------------------- 06.10.2016 -- -function ThtIndexObjList.Get(Index: Integer): ThtIndexObj; -begin - Result := inherited Get(Index); -end; - -{ ThtBorderRecList } - -//-- BG ---------------------------------------------------------- 06.10.2016 -- -function ThtBorderRecList.Get(Index: Integer): ThtBorderRec; -begin - Result := inherited Get(Index); -end; - -{ TLineRecList } - -//-- BG ---------------------------------------------------------- 06.10.2016 -- -function TLineRecList.Get(Index: Integer): ThtLineRec; -begin - Result := inherited Get(Index); -end; - -{ THtmlFormList } - -//-- BG ---------------------------------------------------------- 06.10.2016 -- -function THtmlFormList.Get(Index: Integer): THtmlForm; -begin - Result := inherited Get(Index); -end; - -{ TFormData } - -//-- BG ---------------------------------------------------------- 06.10.2016 -- -function TFormData.Get(Index: Integer): ThtStringList; -begin - Result := inherited Get(Index); -end; - -{ TPanelObjList } - -//-- BG ---------------------------------------------------------- 06.10.2016 -- -function TPanelObjList.Get(Index: Integer): TPanelObj; -begin - Result := inherited Get(Index); -end; - -initialization -{$ifdef UNICODE} -{$else} - {$ifdef UseElPack} - UnicodeControls := True; - {$endif} - - {$ifdef UseTNT} - UnicodeControls := not IsWin32Platform; - {$endif} -{$endif} - WaitStream := TMemoryStream.Create; - ErrorStream := TMemoryStream.Create; - WaitBitmap := TBitmap.Create; - ErrorBitmap := TBitmap.Create; -finalization - ErrorBitmap.Free; - WaitBitmap.Free; - ErrorStream.Free; - WaitStream.Free; -end. - diff --git a/CORE/Source/Plugins/Htmlviewer/source/HTMLUn2.pas b/CORE/Source/Plugins/Htmlviewer/source/HTMLUn2.pas deleted file mode 100644 index 50b14312b..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/HTMLUn2.pas +++ /dev/null @@ -1,3600 +0,0 @@ -{ -Version 11.8 -Copyright (c) 1995-2008 by L. David Baldwin -Copyright (c) 2008-2017 by HtmlViewer Team - -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. - -Note that the source modules HTMLGIF1.PAS and DITHERUNIT.PAS -are covered by separate copyright notices located in those modules. -} - -{$I htmlcons.inc} - -unit HTMLUn2; - -interface - -uses -{$ifdef UseInline} - Math, -{$endif} -{$ifdef LCL} - LclIntf, IntfGraphics, FpImage, LclType, LResources, LMessages, HtmlMisc, -{$else} - Windows, -{$endif} - SysUtils, Contnrs, Classes, vcl.Graphics, vcl.ClipBrd, vcl.Controls, vcl.ExtCtrls, Messages, Variants, Types, vcl.ComCtrls, -{$ifdef Compiler20_Plus} - CommCtrl, -{$endif} -{$ifndef NoGDIPlus} - GDIPL2A, -{$endif} -{$ifdef METAFILEMISSING} - MetaFilePrinter, -{$endif} - HtmlBuffer, - HTMLGif2, - HtmlGlobals, - HtmlImages, - StyleTypes, - HtmlSymb; - -const - VersionNo = '11.8'; - MaxHScroll = 100000; {max horizontal display in pixels} - Tokenleng = 300; - TopLim = -200; {drawing limits} - BotLim = 5000; - FmCtl = WideChar(#2); - ImgPan = WideChar(#4); - BrkCh = WideChar(#8); - htDefFontName = 'Serif'; - htDefPreFontName = 'Monospace'; - - -type - THtQuirksMode = (qmDetect, qmStandards, qmQuirks); - - // BG, 26.12.2011: - TWidthType = ( - wtNone, - wtAbsolute, - wtPercent, - wtRelative); - - // BG, 26.12.2011: - TSpecWidth = record - Value: Integer; - VType: TWidthType; // treat wtNone like "0*" (Value = 0.0, CType = wtRelative) - end; - - ThtJustify = (NoJustify, Left, Centered, Right, FullJustify); - TRowType = (THead, TBody, TFoot); - -//------------------------------------------------------------------------------ -// tag attributes -//------------------------------------------------------------------------------ - - TAttribute = class {holds a tag attribute} - public - Which: TAttrSymb; {symbol of attribute such as HrefSy} - WhichName: ThtString; - Value: Integer; {numeric value if appropriate} - DblValue: Double; {numeric value if appropriate} - Name: ThtString; {ThtString (mixed case), value after '=' sign} - CodePage: Integer; - constructor Create(ASym: TAttrSymb; const AValue: Double; const NameStr, ValueStr: ThtString; ACodePage: Integer); - constructor CreateCopy(ASource: TAttribute); - property AsString: ThtString read Name; - property AsInteger: Integer read Value; - property AsDouble: Double read DblValue; - end; - - TAttributeList = class(TObjectList) {a list of tag attributes,(TAttributes)} - private - SaveID: ThtString; - function GetClass: ThtString; - function GetID: ThtString; - function GetTitle: ThtString; - function GetAttribute(Index: Integer): TAttribute; {$ifdef UseInline} inline; {$endif} - public - constructor CreateCopy(ASource: TAttributeList); - function Clone: TAttributeList; virtual; - procedure Clear; override; - function Find(const Name: ThtString; var T: TAttribute): Boolean; overload; {$ifdef UseInline} inline; {$endif} - function Find(Sy: TAttrSymb; var T: TAttribute): Boolean; overload; {$ifdef UseInline} inline; {$endif} - function CreateStringList: ThtStringList; - property TheClass: ThtString read GetClass; - property TheID: ThtString read GetID; - property TheTitle: ThtString read GetTitle; - property Items[Index: Integer]: TAttribute read GetAttribute; default; - end; - -//------------------------------------------------------------------------------ -// copy to clipboard support -//------------------------------------------------------------------------------ - - TSelTextCount = class - private - Buffer: PWideChar; - BufferLeng: Integer; - Leng: Integer; - public - procedure AddText(P: PWideChar; Size: Integer); virtual; - procedure AddTextCR(P: PWideChar; Size: Integer); {$ifdef UseInline} inline; {$endif} - function Terminate: Integer; virtual; - end; - - TSelTextBuf = class(TSelTextCount) - public - constructor Create(ABuffer: PWideChar; Size: Integer); - procedure AddText(P: PWideChar; Size: Integer); override; - function Terminate: Integer; override; - end; - -//------------------------------------------------------------------------------ -// -//------------------------------------------------------------------------------ - - TFontObjBaseList = class; - - {holds start and end point of URL text} - TutText = record //BG, 03.03.2011: changed to record. no need to use a class - Start: Integer; - Last: Integer; - end; - - TUrlTarget = class - public - URL: ThtString; - Target: ThtString; - ID: Integer; - Attr: ThtString; - utText: TutText; - TabIndex: Integer; - constructor Create; - destructor Destroy; override; - procedure Assign(const AnUrl, ATarget: ThtString; L: TAttributeList; AStart: Integer); overload; - procedure Assign(const UT: TUrlTarget); overload; - procedure Clear; - procedure SetLast(List: TFontObjBaseList; ALast: Integer); - property Start: Integer read utText.Start; - property Last: Integer read utText.Last; - end; - - // BG, 31.12.2011: - TMapArea = class - private - FHRef: ThtString; - FRegion: HRGN; - FTarget: ThtString; - FTitle: ThtString; - public - destructor Destroy; override; - function PtInArea(X, Y: Integer): Boolean; - property HRef: ThtString read FHRef; - property Target: ThtString read FTarget; - property Title: ThtString read FTitle; - end; - - // BG, 31.12.2011: - TMapAreaList = class(TObjectList) - private - function GetArea(Index: Integer): TMapArea; {$ifdef UseInline} inline; {$endif} - public - property Items[Index: Integer]: TMapArea read GetArea; default; - end; - - TMapItem = class {holds a client map info} - private - FAreas: TMapAreaList; - public - MapName: ThtString; - constructor Create; - destructor Destroy; override; - function GetURL(X, Y: Integer; var URLTarg: TURLTarget; var ATitle: ThtString): boolean; - procedure AddArea(Attrib: TAttributeList); - end; - - ThtMap = class(TObjectList) - private - function Get(Index: Integer): TMapItem; {$ifdef UseInline} inline; {$endif} - public - property Items[Index: Integer]: TMapItem read Get; default; - end; - - TFontObjBase = class {font information} - public - UrlTarget: TUrlTarget; - end; - - TFontObjBaseList = class(TObjectList) - private - function GetBase(Index: Integer): TFontObjBase; {$ifdef UseInline} inline; {$endif} - public - property Items[Index: Integer]: TFontObjBase read GetBase; default; - end; - -//------------------------------------------------------------------------------ -// indentation manager -//------------------------------------------------------------------------------ - - TIndentRec = class - public - X: Integer; // left or right indentation relative to LfEdge. - YT: Integer; // top Y inclusive coordinate for this record relative to document top. - YB: Integer; // bottom Y exclusive coordinate for this record relative to document top. - ID: TObject; // block level indicator for this record, 0 for not applicable - end; - - TIndentRecList = class(TObjectList) - private - function Get(Index: Integer): TIndentRec; {$ifdef UseInline} inline; {$endif} - public - property Items[Index: Integer]: TIndentRec read Get; default; - end; - - TIndentManager = class - private - function LeftEdge(Y: Integer): Integer; - function RightEdge(Y: Integer): Integer; - public - LfEdge: Integer; // left edge of the block content area. - // TCell.DoLogic calculates with LfEdge = 0. - // TCell.Draw then may shift the block by setting LfEdge to X. - Width: Integer; // width of the block content area. - ClipWidth: Integer; // clip width ??? - L: TIndentRecList; // list of left side indentations of type IndentRec. - R: TIndentRecList; // list of right side indentations of type IndentRec. - CurrentID: TObject; // the current block level (a TBlock pointer) - LTopMin: Integer; - RTopMin: Integer; - public - constructor Create; - destructor Destroy; override; - function AddLeft(YT, YB, W: Integer): TIndentRec; - function AddRight(YT, YB, W: Integer): TIndentRec; - function AlignLeft(var Y: Integer; W: Integer): Integer; - function AlignRight(var Y: Integer; W: Integer): Integer; - function GetNextWiderY(Y: Integer): Integer; - function ImageBottom: Integer; - function LeftIndent(Y: Integer): Integer; - function RightSide(Y: Integer): Integer; - function SetLeftIndent(XLeft, Y: Integer): Integer; - function SetRightIndent(XRight, Y: Integer): Integer; - procedure FreeLeftIndentRec(I: Integer); - procedure FreeRightIndentRec(I: Integer); - procedure GetClearY(out CL, CR: Integer); - procedure Init(Lf, Wd: Integer); - procedure Reset(Lf: Integer); - // AdjustY() is called after an inline row has been produced. If floating objects have been moved - // down before the actual height of the entire row was computed, their Y coordinates aren't too - // small now. AdjustY() moves them down below given Y + Height. - procedure AdjustY(FirstLeftIndex, FirstRightIndex, Y, Height: Integer); - end; - -//------------------------------------------------------------------------------ -// parser -//------------------------------------------------------------------------------ - - {Simplified variant of TokenObj, to temporarily keep a ThtString of unicode - characters along with their original indices.} - - { TCharCollection } - - TCharCollection = class - private - FChars: ThtString; - FIndices: array of Integer; - FCurrentIndex: Integer; - function GetSize: Integer; - function GetAsString: ThtString; - function GetCapacity: Integer; - procedure SetCapacity(NewCapacity: Integer); - public - constructor Create; - procedure Add(C: ThtChar; Index: Integer); overload; - procedure Add(const S: ThtString; Index: Integer); overload; - procedure Clear; -// procedure Concat(T: TCharCollection); - - property AsString: ThtString read GetAsString; - property Capacity: Integer read GetCapacity write SetCapacity; - property Size: Integer read GetSize; - end; - - { TokenObj } - - TTokenObj = class - private - St: UnicodeString; - StringOK: boolean; - FCount: Integer; - function GetCapacity: Integer; - function GetString: UnicodeString; - procedure SetCapacity(NewCapacity: Integer); - public - C: array of ThtChar; - I: array of Integer; - constructor Create; - procedure AddUnicodeChar(Ch: WideChar; Ind: Integer); - procedure AddString(S: TCharCollection); - procedure Clear; -// procedure Concat(T: TokenObj); -// procedure Remove(N: Integer); -// procedure Replace(N: Integer; Ch: ThtChar); - - property Capacity: Integer read GetCapacity write SetCapacity; - property Count: Integer read FCount; - property S: UnicodeString read GetString; - end; - -//------------------------------------------------------------------------------ -// TIDObject is base class for all tag objects. -//------------------------------------------------------------------------------ -// If they have an ID, the parser puts them into the HtmlViewer's IDNameList, -// a TIDObjectList, where they can be obtained from by ID. -// Their Y coordinates can be retrieved and HtmlViewer can scroll to them. -// -// Most descendants are objects representing an HTML tag, except TChPosObj. -//------------------------------------------------------------------------------ - - TIDObject = class - private - function GetId(): ThtString; //>-- DZ - protected - FHtmlId: ThtString; //>-- DZ real ID from HTML if any - FGlobalId: ThtString; //>-- DZ global unique ID - - function GetYPosition: Integer; virtual; abstract; - function FreeMe: Boolean; virtual; // some objects the TIDObjectsList owns, some others not. - public - constructor Create(const AHtmlID: ThtString); - procedure AfterConstruction(); override;//>-- DZ - - property YPosition: Integer read GetYPosition; - property Id: ThtString read GetId; //>-- DZ if FhtmlId then FglobalId will be returned as result - property HtmlId: ThtString read FHtmlId; //>-- DZ - property GlobalId: ThtString read FGlobalId; //>-- DZ - end; - - //BG, 04.03.2011: TIDNameList renamed to TIDObjectList and used TObject changed to TIDObject. - TIDObjectList = class(ThtStringList) - private - function GetObject(Index: Integer): TIDObject; reintroduce; - public - constructor Create; - destructor Destroy; override; - function AddObject(const S: ThtString; AObject: TIDObject): Integer; reintroduce; - procedure Clear; override; - property Objects[Index: Integer]: TIDObject read GetObject; default; - end; - - ThtColorArray = packed array[0..3] of TColor; - ThtBorderStyleArray = packed array[0..3] of ThtBorderStyle; - -//BG, 11.09.2010: moved to this unit to reduce circular dependencies: - - ThtguResultType = set of (guUrl, guControl, guTitle); - -//------------------------------------------------------------------------------ -// ThvPanel is base class for panels held in TPanelObj -//------------------------------------------------------------------------------ - - ThvPanel = class(TPanel) - public - FVisible: boolean; - procedure SetVisible(Value: boolean); - property Visible: boolean read FVisible write SetVisible default True; - end; - - TPanelCreateEvent = procedure(Sender: TObject; const AName, AType, SRC: ThtString; Panel: ThvPanel) of object; - TPanelDestroyEvent = procedure(Sender: TObject; Panel: ThvPanel) of object; - TPanelPrintEvent = procedure(Sender: TObject; Panel: ThvPanel; const Bitmap: TBitmap) of object; - TObjectTagEvent = procedure(Sender: TObject; Panel: ThvPanel; const Attributes, Params: ThtStringList; var WantPanel: boolean) of object; - TObjectClickEvent = procedure(Sender, Obj: TObject; const OnClick: ThtString) of object; - ThtObjectEvent = procedure(Sender, Obj: TObject; const Attribute: ThtString) of object; - -{$ifndef Compiler20_Plus} -const - PBS_MARQUEE = $08; - PBM_SETBARCOLOR = WM_USER+9; - PBM_SETMARQUEE = WM_USER+10; - PBM_GETBARCOLOR = WM_USER+14; - -type - TProgressBarStyle = (pbstNormal, pbstMarquee); - - ThvProgressBar = class(TProgressBar) - private - FStyle: TProgressBarStyle; - procedure SetStyle(Value: TProgressBarStyle); - protected - procedure CreateParams(var Params: TCreateParams); override; - published - property Style: TProgressBarStyle read FStyle write SetStyle; - end; -{$else} - ThvProgressBar = TProgressBar; -{$endif} - - // While the meter is not a progressbar, it is the closest control to what is required. - // There are a few downsides to the Windows ProgressBar: - // - it animates to the value instead of jumping there. This is fixed by overriding the Position property. - // - Under Theming the progress bar animates a glowing swish that cannot be turned off. - // This class also allows the user to define a color for when the bar is < low and one for > high. - // This matches other browsers implementations - ThvMeter = class(ThvProgressBar) - private - FLow: double; - FHigh: double; - FOptimum: double; // This is only for reference and has not affect on the color - FLowColor: TColor; - FHighColor: TColor; - - procedure SetPosition(Value: Integer); - function GetPosition: Integer; - procedure UpdateColor; - protected - procedure SetLow(const value: double); virtual; - procedure SetHigh(const value: double); virtual; - procedure SetOptimum(const value: double); virtual; - procedure SetLowColor(const value: TColor); virtual; - procedure SetHighColor(const value: TColor); virtual; - public - constructor Create(AOwner: TComponent); override; - property Position: Integer read GetPosition write SetPosition default 0; - - property Low: double read FLow write SetLow; - property High: double read FHigh write SetHigh; - property Optimum: double read FOptimum write SetOptimum; - - property LowColor: TColor read FLowColor write SetLowColor; - property HighColor: TColor read FHighColor write SetHighColor; - end; - - - -//------------------------------------------------------------------------------ -// ThtControlBase is base class for TViewerBase and TFrameBase -//------------------------------------------------------------------------------ - - ThtControlBase = class(TWinControl); - -//------------------------------------------------------------------------------ -// TViewerBase is base class for THtmlViewer and TFrameViewer -//------------------------------------------------------------------------------ - - TGetStreamEvent = procedure(Sender: TObject; const SRC: ThtString; var Stream: TStream) of object; - TGottenStreamEvent = TGetStreamEvent; - THotSpotTargetClickEvent = procedure(Sender: TObject; const Target, URL: ThtString; var Handled: boolean) of object; - THotSpotTargetEvent = procedure(Sender: TObject; const Target, URL: ThtString) of object; - ThtProgressEvent = procedure(Sender: TObject; Stage: TProgressStage; PercentDone: Integer) of object; - TImageClickEvent = procedure(Sender, Obj: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) of object; - TImageOverEvent = procedure(Sender, Obj: TObject; Shift: TShiftState; X, Y: Integer) of object; - TIncludeType = procedure(Sender: TObject; const Command: ThtString; Params: ThtStrings; out IncludedDocument: TBuffer) of object; - TLinkType = procedure(Sender: TObject; const Rel, Rev, Href: ThtString) of object; - TMetaType = procedure(Sender: TObject; const HttpEq, Name, Content: ThtString) of object; - TPagePrinted = procedure(Sender: TObject; Canvas: TCanvas; NumPage, W, H: Integer; var StopPrinting: Boolean) of object; - TParseEvent = procedure(Sender: TObject; var Source: TBuffer) of object; - TProcessingEvent = procedure(Sender: TObject; ProcessingOn: Boolean) of object; - TScriptEvent = procedure(Sender: TObject; const Name, ContentType, Src, Script: ThtString) of object; - TSoundType = procedure(Sender: TObject; const SRC: ThtString; Loop: Integer; Terminate: boolean) of object; - THTMLViewPrinted = TNotifyEvent; - THTMLViewPrinting = procedure(Sender: TObject; var StopPrinting: Boolean) of object; - TLinkDrawnEvent = procedure(Sender: TObject; Page: Integer; const Url, Target: ThtString; ARect: TRect) of object; - TFileBrowseEvent = procedure(Sender, Obj: TObject; var S: ThtString) of object; - TGetBitmapEvent = procedure(Sender: TObject; const SRC: ThtString; var Bitmap: TBitmap; var Color: TColor) of object; - TGottenBitmapEvent = TGetBitmapEvent; - TGetImageEvent = procedure(Sender: TObject; const SRC: ThtString; var Stream: TStream) of object; - TGottenImageEvent = TGetImageEvent; - TFormSubmitEvent = procedure(Sender: TObject; const Action, Target, EncType, Method: ThtString; Results: ThtStringList) of object; - - TViewerBase = class(ThtControlBase) - private - FBackGround, FHotSpotColor, FVisitedColor, FOverColor: TColor; - FCharset: TFontCharset; - FCodePage: TBuffCodePage; - FFontColor: TColor; - FFontName, FPreFontName: TFontName; - FFontSize: Integer; - FHistoryMaxCount, FImageCacheCount, FVisitedMaxCount: Integer; - FLoadCursor: TCursor; - FMarginWidth, FMarginHeight: Integer; - FNoSelect: Boolean; - FPrintMarginLeft, FPrintMarginRight, FPrintMarginTop, FPrintMarginBottom: Double; - FPrintMaxHPages: Integer; - FPrintScale: Double; - FServerRoot: ThtString; - // - FOnBitmapRequest: TGetBitmapEvent; - FOnBitmapRequested: TGottenBitmapEvent; - FOnDragDrop: TDragDropEvent; - FOnDragOver: TDragOverEvent; - FOnHistoryChange: TNotifyEvent; - FOnHotSpotTargetClick: THotSpotTargetClickEvent; - FOnHotSpotTargetCovered: THotSpotTargetEvent; - FOnImageClick: TImageClickEvent; - FOnImageOver: TImageOverEvent; - FOnImageRequest: TGetImageEvent; - FOnImageRequested: TGottenImageEvent; - FOnInclude: TIncludeType; - FOnLink: TLinkType; - FOnMeta: TMetaType; - FOnMouseDouble: TMouseEvent; - FOnObjectBlur: ThtObjectEvent; - FOnObjectChange: ThtObjectEvent; - FOnObjectClick: TObjectClickEvent; - FOnObjectFocus: ThtObjectEvent; - FOnObjectTag: TObjectTagEvent; - FOnPanelCreate: TPanelCreateEvent; - FOnPanelDestroy: TPanelDestroyEvent; - FOnPanelPrint: TPanelPrintEvent; - FOnParseBegin: TParseEvent; - FOnParseEnd: TNotifyEvent; - FOnPrinted: THTMLViewPrinted; - FOnPrintHeader, FOnPrintFooter: TPagePrinted; - FOnPrinting: THTMLViewPrinting; - FOnProcessing: TProcessingEvent; - FOnProgress: ThtProgressEvent; - FOnScript: TScriptEvent; - FOnSoundRequest: TSoundType; - FQuirksMode : THtQuirksMode; - function StoreFontName: Boolean; - function StorePreFontName: Boolean; - protected - {$ifdef has_StyleElements} - procedure UpdateStyleElements; override; - {$endif} - function GetUseQuirksMode: Boolean; virtual; abstract; - procedure SetQuirksMode(const AValue: THtQuirksMode); virtual; - procedure SetActiveColor(const Value: TColor); virtual; - procedure SetCharset(const Value: TFontCharset); virtual; - procedure SetCodePage(const Value: Integer); virtual; - procedure SetDefBackground(const Value: TColor); virtual; - procedure SetFontColor(const Value: TColor); virtual; - procedure SetFontName(const Value: TFontName); virtual; - procedure SetFontSize(const Value: Integer); virtual; - procedure SetHistoryMaxCount(const Value: Integer); virtual; - procedure SetHotSpotColor(const Value: TColor); virtual; - procedure SetImageCacheCount(const Value: Integer); virtual; - procedure SetLoadCursor(const Value: TCursor); virtual; - procedure SetMarginHeight(const Value: Integer); virtual; - procedure SetMarginWidth(const Value: Integer); virtual; - procedure SetNoSelect(const Value: Boolean); virtual; - procedure SetOnBitmapRequest(const Value: TGetBitmapEvent); virtual; - procedure SetOnBitmapRequested(const Value: TGottenBitmapEvent); virtual; - procedure SetOnDragDrop(const Value: TDragDropEvent); virtual; - procedure SetOnDragOver(const Value: TDragOverEvent); virtual; - procedure SetOnHistoryChange(const Value: TNotifyEvent); virtual; - procedure SetOnHotSpotTargetClick(const Value: THotSpotTargetClickEvent); virtual; - procedure SetOnHotSpotTargetCovered(const Value: THotSpotTargetEvent); virtual; - procedure SetOnImageClick(const Value: TImageClickEvent); virtual; - procedure SetOnImageOver(const Value: TImageOverEvent); virtual; - procedure SetOnImageRequest(const Value: TGetImageEvent); virtual; - procedure SetOnImageRequested(const Value: TGottenImageEvent); virtual; - procedure SetOnInclude(const Handler: TIncludeType); virtual; - procedure SetOnLink(const Handler: TLinkType); virtual; - procedure SetOnMeta(const Value: TMetaType); virtual; - procedure SetOnMouseDouble(const Value: TMouseEvent); virtual; - procedure SetOnObjectBlur(const Value: ThtObjectEvent); virtual; - procedure SetOnObjectChange(const Value: ThtObjectEvent); virtual; - procedure SetOnObjectClick(const Value: TObjectClickEvent); virtual; - procedure SetOnObjectFocus(const Value: ThtObjectEvent); virtual; - procedure SetOnObjectTag(const Value: TObjectTagEvent); virtual; - procedure SetOnPanelCreate(const Value: TPanelCreateEvent); virtual; - procedure SetOnPanelDestroy(const Value: TPanelDestroyEvent); virtual; - procedure SetOnPanelPrint(const Value: TPanelPrintEvent); virtual; - procedure SetOnParseBegin(const Value: TParseEvent); virtual; - procedure SetOnParseEnd(const Value: TNotifyEvent); virtual; - procedure SetOnPrinted(const Value: THTMLViewPrinted); virtual; - procedure SetOnPrintFooter(const Value: TPagePrinted); virtual; - procedure SetOnPrintHeader(const Value: TPagePrinted); virtual; - procedure SetOnPrinting(const Value: THTMLViewPrinting); virtual; - procedure SetOnProcessing(const Value: TProcessingEvent); virtual; - procedure SetOnProgress(const Value: ThtProgressEvent); virtual; - procedure SetOnScript(const Handler: TScriptEvent); virtual; - procedure SetOnSoundRequest(const Handler: TSoundType); virtual; - procedure SetPreFontName(const Value: TFontName); virtual; - procedure SetPrintMarginBottom(const Value: Double); virtual; - procedure SetPrintMarginLeft(const Value: Double); virtual; - procedure SetPrintMarginRight(const Value: Double); virtual; - procedure SetPrintMarginTop(const Value: Double); virtual; - procedure SetPrintMaxHPages(const Value: Integer); virtual; - procedure SetPrintScale(const Value: Double); virtual; - procedure SetServerRoot(const Value: ThtString); virtual; - procedure SetVisitedColor(const Value: TColor); virtual; - procedure SetVisitedMaxCount(const Value: Integer); virtual; - procedure ViewerDragDrop(Sender, Source: TObject; X, Y: Integer); - procedure ViewerDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); - public - constructor Create(AOwner: TComponent); override; - constructor CreateCopy(Owner: TComponent; Source: TViewerBase); virtual; - // Load(Url): Url might be an absolute Url or an absolute PathName or a relative Url/PathName. - procedure Load(const Url: ThtString); virtual; abstract; - // HtmlExpandFilename(Filename, CurrentFilename): Try to get the absolute pathname of the given filename in the local filesystem - function HtmlExpandFilename(const Filename: ThtString; const CurrentFilename: ThtString = ''): ThtString; virtual; abstract; - property QuirksMode : THtQuirksMode read FQuirksMode write SetQuirksMode default qmStandards; - // set to determine if child objects should be in "quirks" mode - property UseQuirksMode: Boolean read GetUseQuirksMode; - property CodePage: Integer read FCodePage write SetCodePage; - property CharSet: TFontCharset read FCharSet write SetCharset; - property DefBackground: TColor read FBackground write SetDefBackground default clBtnFace; - property DefFontColor: TColor read FFontColor write SetFontColor default clBtnText; - property DefFontName: TFontName read FFontName write SetFontName stored StoreFontName; - property DefFontSize: Integer read FFontSize write SetFontSize default 12; - property DefHotSpotColor: TColor read FHotSpotColor write SetHotSpotColor default clBlue; - property DefOverLinkColor: TColor read FOverColor write SetActiveColor default clBlue; - property DefPreFontName: TFontName read FPreFontName write SetPreFontName stored StorePreFontName; - property DefVisitedLinkColor: TColor read FVisitedColor write SetVisitedColor default clPurple; - property HistoryMaxCount: Integer read FHistoryMaxCount write SetHistoryMaxCount; - property ImageCacheCount: Integer read FImageCacheCount write SetImageCacheCount default 5; - property LoadCursor: TCursor read FLoadCursor write SetLoadCursor default crHourGlass; - property MarginHeight: Integer read FMarginHeight write SetMarginHeight default 5; - property MarginWidth: Integer read FMarginWidth write SetMarginWidth default 10; - property NoSelect: Boolean read FNoSelect write SetNoSelect; - property PrintMarginBottom: Double read FPrintMarginBottom write SetPrintMarginBottom; - property PrintMarginLeft: Double read FPrintMarginLeft write SetPrintMarginLeft; - property PrintMarginRight: Double read FPrintMarginRight write SetPrintMarginRight; - property PrintMarginTop: Double read FPrintMarginTop write SetPrintMarginTop; - property PrintMaxHPages: Integer read FPrintMaxHPages write SetPrintMaxHPages default 2; - property PrintScale: Double read FPrintScale write SetPrintScale; - property ServerRoot: ThtString read FServerRoot write SetServerRoot; - property VisitedMaxCount: Integer read FVisitedMaxCount write SetVisitedMaxCount default 50; - // - property OnBitmapRequest: TGetBitmapEvent read FOnBitmapRequest write SetOnBitmapRequest; - property OnBitmapRequested: TGottenBitmapEvent read FOnBitmapRequested write SetOnBitmapRequested; - property OnDragDrop: TDragDropEvent read FOnDragDrop write SetOnDragDrop; - property OnDragOver: TDragOverEvent read FOnDragOver write SetOnDragOver; - property OnHistoryChange: TNotifyEvent read FOnHistoryChange write SetOnHistoryChange; - property OnHotSpotTargetClick: THotSpotTargetClickEvent read FOnHotSpotTargetClick write SetOnHotSpotTargetClick; - property OnHotSpotTargetCovered: THotSpotTargetEvent read FOnHotSpotTargetCovered write SetOnHotSpotTargetCovered; - property OnImageClick: TImageClickEvent read FOnImageClick write SetOnImageClick; - property OnImageOver: TImageOverEvent read FOnImageOver write SetOnImageOver; - property OnImageRequest: TGetImageEvent read FOnImageRequest write SetOnImageRequest; - property OnImageRequested: TGottenImageEvent read FOnImageRequested write SetOnImageRequested; - property OnInclude: TIncludeType read FOnInclude write SetOnInclude; - property OnLink: TLinkType read FOnLink write SetOnLink; - property OnMeta: TMetaType read FOnMeta write SetOnMeta; - property OnMouseDouble: TMouseEvent read FOnMouseDouble write SetOnMouseDouble; - property OnObjectBlur: ThtObjectEvent read FOnObjectBlur write SetOnObjectBlur; - property OnObjectChange: ThtObjectEvent read FOnObjectChange write SetOnObjectChange; - property OnObjectClick: TObjectClickEvent read FOnObjectClick write SetOnObjectClick; - property OnObjectFocus: ThtObjectEvent read FOnObjectFocus write SetOnObjectFocus; - property OnObjectTag: TObjectTagEvent read FOnObjectTag write SetOnObjectTag; - property OnPanelCreate: TPanelCreateEvent read FOnPanelCreate write SetOnPanelCreate; - property OnPanelDestroy: TPanelDestroyEvent read FOnPanelDestroy write SetOnPanelDestroy; - property OnPanelPrint: TPanelPrintEvent read FOnPanelPrint write SetOnPanelPrint; - property OnParseBegin: TParseEvent read FOnParseBegin write SetOnParseBegin; - property OnParseEnd: TNotifyEvent read FOnParseEnd write SetOnParseEnd; - property OnPrinted: THTMLViewPrinted read FOnPrinted write SetOnPrinted; - property OnPrintFooter: TPagePrinted read FOnPrintFooter write SetOnPrintFooter; - property OnPrintHeader: TPagePrinted read FOnPrintHeader write SetOnPrintHeader; - property OnPrinting: THTMLViewPrinting read FOnPrinting write SetOnPrinting; - property OnProcessing: TProcessingEvent read FOnProcessing write SetOnProcessing; - property OnProgress: ThtProgressEvent read FOnProgress write SetOnProgress; - property OnScript: TScriptEvent read FOnScript write SetOnScript; - property OnSoundRequest: TSoundType read FOnSoundRequest write SetOnSoundRequest; - published - {$ifdef has_StyleElements} - property StyleElements; - {$endif} - end; - - TViewerBaseClass = class of TViewerBase; - - TTablePartType = (Normal, DoHead, DoBody1, DoBody2, DoBody3, DoFoot); - TTablePartRec = class - public - TablePart: TTablePartType; - PartStart: Integer; - PartHeight: Integer; - FootHeight: Integer; - end; - - THtmlViewerBase = class(TViewerBase) - public - TablePartRec: TTablePartRec; - function ShowFocusRect: Boolean; virtual; abstract; - procedure ControlMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); virtual; abstract; - procedure htProgress(Percent: Integer); virtual; abstract; - procedure KeyDown(var Key: Word; Shift: TShiftState); override; - end; - - TFrameViewerBase = class(TViewerBase) - private - procedure wmerase(var msg: TMessage); message WM_ERASEBKGND; - public - function CreateSubFrameSet(FrameSet: TObject): TObject; virtual; abstract; - procedure AddFrame(FrameSet: TObject; Attr: TAttributeList; const FName: ThtString); virtual; abstract; - procedure DoAttributes(FrameSet: TObject; Attr: TAttributeList); virtual; abstract; - end; - -//------------------------------------------------------------------------------ -// string methods -//------------------------------------------------------------------------------ - -function StrLenW(Str: PWideChar): Cardinal; -function StrPosW(Str, SubStr: PWideChar): PWideChar; -function StrScanW(const Str: PWideChar; Chr: WideChar): PWideChar; -function StrRScanW(const Str: PWideChar; Chr: WideChar): PWideChar; -function WidePos(SubStr, S: UnicodeString): Integer; -//function WideTrim(const S: UnicodeString): UnicodeString; deprecated; // use HtmlGlobals.htTrim() instead -//function WideUpperCase1(const S: UnicodeString): UnicodeString; {$ifdef UNICODE} inline; {$endif} deprecated; // use HtmlGlobals.htUppercase() instead -//function WideLowerCase1(const S: UnicodeString): UnicodeString; {$ifdef UNICODE} inline; {$endif}deprecated; // use HtmlGlobals.htLowercase() instead -function WideSameText1(const S1, S2: UnicodeString): boolean; {$ifdef UseInline} inline; {$endif} -function WideSameStr1(const S1, S2: UnicodeString): boolean; {$ifdef UseInline} inline; {$endif} - -//function WideStringToMultibyte(CodePage: Integer; W: UnicodeString): AnsiString; - -function FitText(DC: HDC; S: PWideChar; Max, Width: Integer; out Extent: TSize): Integer; -function GetTextExtent(DC: HDC; P: PWideChar; N: Integer): TSize; -procedure WrapTextW(Canvas: TCanvas; X1, Y1, X2, Y2: Integer; S: UnicodeString); - -//------------------------------------------------------------------------------ -// misc. methods -//------------------------------------------------------------------------------ - -// BG, 26.12.2011: new type TSpecWidth -function SpecWidth(Value: Integer; VType: TWidthType): TSpecWidth; -function ToSpecWidth(AsInteger: Integer; AsString: string): TSpecWidth; - -//------------------------------------------------------------------------------ -// canvas methods -//------------------------------------------------------------------------------ - -function CalcClipRect(Canvas: TCanvas; const Rect: TRect; Printing: boolean): TRect; -procedure GetClippingRgn(Canvas: TCanvas; const ARect: TRect; Printing: boolean; var Rgn, SaveRgn: HRgn); - -procedure FillRectWhite(Canvas: TCanvas; X1, Y1, X2, Y2: Integer; Color: TColor {$ifdef has_StyleElements};const AStyleElements : TStyleElements{$endif}); -procedure DrawFormControlRect(Canvas: TCanvas; X1, Y1, X2, Y2: Integer; Raised, PrintMonoBlack, Disabled: boolean; Color: TColor - {$ifdef has_StyleElements};const AStyleElements : TStyleElements{$endif}); -procedure DrawBorder(Canvas: TCanvas; ORect, IRect: TRect; const C: ThtColorArray; - const S: ThtBorderStyleArray; BGround: TColor; Print: boolean - {$ifdef has_StyleElements};const AStyleElements : TStyleElements{$endif}); - -type - THtBorderPointArray = array[0..3] of TPoint; - -implementation - -uses - vcl.Forms, {$ifndef UseInline} Math, {$endif} - {$ifdef UseVCLStyles} - Vcl.Themes, - {$endif} - {$ifdef HasSystemUITypes} - System.UITypes, - {$endif} - {$ifndef FPC_TODO}vcl.Imaging.jpeg, {$endif} - {$IFDEF UNICODE} vcl.Imaging.PngImage, {$ENDIF} - DitherUnit, StylePars; - -type - EGDIPlus = class(Exception); - -{$ifdef UseGlobalObjectId} -var - GlobalObjectIdPrefix: ThtString; - GlobalObjectIdCount: Cardinal; //>-- DZ, counter for TIDObject.FGlobalId -{$endif} - -{$ifdef UseASMx86} - -function StrLenW(Str: PWideChar): Cardinal; -// returns number of characters in a ThtString excluding the null terminator -asm - MOV EDX, EDI - MOV EDI, EAX - MOV ECX, 0FFFFFFFFH - XOR AX, AX - REPNE SCASW - MOV EAX, 0FFFFFFFEH - SUB EAX, ECX - MOV EDI, EDX -end; - -function StrPosW(Str, SubStr: PWideChar): PWideChar; -// returns a pointer to the first occurance of SubStr in Str -asm - PUSH EDI - PUSH ESI - PUSH EBX - OR EAX, EAX - JZ @@2 - OR EDX, EDX - JZ @@2 - MOV EBX, EAX - MOV EDI, EDX - XOR AX, AX - MOV ECX, 0FFFFFFFFH - REPNE SCASW - NOT ECX - DEC ECX - JZ @@2 - MOV ESI, ECX - MOV EDI, EBX - MOV ECX, 0FFFFFFFFH - REPNE SCASW - NOT ECX - SUB ECX, ESI - JBE @@2 - MOV EDI, EBX - LEA EBX, [ESI - 1] -@@1: - MOV ESI, EDX - LODSW - REPNE SCASW - JNE @@2 - MOV EAX, ECX - PUSH EDI - MOV ECX, EBX - REPE CMPSW - POP EDI - MOV ECX, EAX - JNE @@1 - LEA EAX, [EDI - 2] - JMP @@3 - -@@2: - XOR EAX, EAX -@@3: - POP EBX - POP ESI - POP EDI -end; - -function StrRScanW(const Str: PWideChar; Chr: WideChar): PWideChar; assembler; -asm - PUSH EDI - MOV EDI,Str - MOV ECX,0FFFFFFFFH - XOR AX,AX - REPNE SCASW - NOT ECX - STD - DEC EDI - DEC EDI - MOV AX,Chr - REPNE SCASW - MOV EAX,0 - JNE @@1 - MOV EAX,EDI - INC EAX - INC EAX -@@1: CLD - POP EDI -end; - -function StrScanW(const Str: PWideChar; Chr: WideChar): PWideChar; assembler; -asm - PUSH EDI - PUSH EAX - MOV EDI,Str - MOV ECX,$FFFFFFFF - XOR AX,AX - REPNE SCASW - NOT ECX - POP EDI - MOV AX,Chr - REPNE SCASW - MOV EAX,0 - JNE @@1 - MOV EAX,EDI - DEC EAX - DEC EAX -@@1: POP EDI -end; - -{$else} - -// Pascal-ized equivalents of assembler functions. -function StrLenW(Str: PWideChar): Cardinal; - {$ifdef UseInline} inline; {$endif} -begin - Result := 0; - if Str <> nil then - while Str[Result] <> #0 do - Inc(Result); -end; - -function StrPosW(Str, SubStr: PWideChar): PWideChar; - {$ifdef UseInline} inline; {$endif} -var - StrPos : PWideChar; - SubstrPos : PWideChar; -begin - if SubStr^ = #0 then // Make sure substring not null string - begin - Result := nil; - Exit; - end; - Result := Str; - while Result^ <> #0 do // Until reach end of string - begin - StrPos := Result; - SubstrPos := SubStr; - while SubstrPos^ <> #0 do // Until reach end of substring - begin - if StrPos^ <> SubstrPos^ then // No point in continuing? - Break; - StrPos := StrPos + 1; - SubstrPos := SubstrPos + 1; - end; - if SubstrPos^ = #0 then // Break because reached end of substring? - Exit; - Result := Result + 1; - end; - Result := nil; -end; - -function StrRScanW(const Str: PWideChar; Chr: WideChar): PWideChar; - {$ifdef UseInline} inline; {$endif} -begin - Result := StrScanW(Str, #0); - if Chr = #0 then // Null-terminating char considered part of string. - Exit; - while Result <> Str do - begin - Result := Result - 1; - if Result^ = Chr then - Exit; - end; - Result := nil; -end; - -function StrScanW(const Str: PWideChar; Chr: WideChar): PWideChar; - {$ifdef UseInline} inline; {$endif} -begin - Result := Str; - while Result^ <> #0 do - begin - if Result^ = Chr then - Exit; - Result := Result + 1; - end; - if Chr = #0 then - Exit; // Null-terminating char considered part of string. See call - // searching for #0 to find end of string. - Result := nil; -end; - -{$endif} - - -{----------------FitText} - -function FitText(DC: HDC; S: PWideChar; Max, Width: Integer; out Extent: TSize): Integer; - {$ifdef UseInline} inline; {$endif} -{return count <= Max which fits in Width. Return X, the extent of chars that fit} -var - Ints: array of Integer; - L, H, I: Integer; -begin - Extent.cx := 0; - Extent.cy := 0; - Result := 0; - if (Width <= 0) or (Max = 0) then - Exit; - - if not IsWin32Platform then - begin - SetLength(Ints, Max); - if GetTextExtentExPointW(DC, S, Max, Width, @Result, @Ints[0], Extent) then - if Result > 0 then - Extent.cx := Ints[Result - 1] - else - Extent.cx := 0; - end - else {GetTextExtentExPointW not available in win98, 95} - begin {optimize this by looking for Max to fit first -- it usually does} - L := 0; - H := Max; - I := H; - while L <= H do - begin - GetTextExtentPoint32W(DC, S, I, Extent); - if Extent.cx < Width then - L := I + 1 - else - H := I - 1; - if Extent.cx = Width then - Break; - I := (L + H) shr 1; - end; - Result := I; - end; -end; - -{----------------WidePos} - -function WidePos(SubStr, S: UnicodeString): Integer; - {$ifdef UseInline} inline; {$endif} -// Unicode equivalent for Pos() function. -var - P: PWideChar; -begin - P := StrPosW(PWideChar(S), PWideChar(SubStr)); - if P = nil then - Result := 0 - else - Result := P - PWideChar(S) + 1; -end; - -//{----------------WideUpperCase1} -// -//{$ifdef UNICODE} -// -//function WideUpperCase1(const S: UnicodeString): UnicodeString; -//begin -// Result := WideUpperCase(S); -//end; -// -//function WideLowerCase1(const S: UnicodeString): UnicodeString; -//begin -// Result := WideLowerCase(S); -//end; -// -//{$else} -// -//function WideUpperCase1(const S: UnicodeString): UnicodeString; -//var -// Len, NewLen: Integer; -// Tmp: string; -//begin -// Len := Length(S); -// if not IsWin32Platform then -// begin -// SetString(Result, PWideChar(S), Len); -// if Len > 0 then -// CharUpperBuffW(Pointer(Result), Len); -// end -// else -// begin {win95,98,ME} -// SetLength(Tmp, 2 * Len); -// NewLen := WideCharToMultiByte(CP_ACP, 0, PWideChar(S), Len, PChar(Tmp), 2 * Len, nil, nil); -// SetLength(Tmp, NewLen); -// Tmp := AnsiUppercase(Tmp); -// SetLength(Result, Len); -// MultibyteToWideChar(CP_ACP, 0, PChar(Tmp), NewLen, PWideChar(Result), Len); -// end; -//end; -// -//function WideLowerCase1(const S: UnicodeString): UnicodeString; -//var -// Len, NewLen: Integer; -// Tmp: string; -//begin -// Len := Length(S); -// if not IsWin32Platform then -// begin -// SetString(Result, PWideChar(S), Len); -// if Len > 0 then -// CharLowerBuffW(Pointer(Result), Len); -// end -// else -// begin {win95,98,ME} -// SetLength(Tmp, 2 * Len); -// NewLen := WideCharToMultiByte(CP_ACP, 0, PWideChar(S), Len, PChar(Tmp), 2 * Len, nil, nil); -// SetLength(Tmp, NewLen); -// Tmp := AnsiLowercase(Tmp); -// SetLength(Result, Len); -// MultibyteToWideChar(CP_ACP, 0, PChar(Tmp), NewLen, PWideChar(Result), Len); -// end; -//end; -// -//{$endif} - -function WideSameText1(const S1, S2: UnicodeString): boolean; - {$ifdef UseInline} inline; {$endif} -begin - Result := htUpperCase(S1) = htUpperCase(S2); -end; - -function WideSameStr1(const S1, S2: UnicodeString): boolean; - {$ifdef UseInline} inline; {$endif} -begin - Result := S1 = S2; -end; - -//-- BG ---------------------------------------------------------- 06.10.2010 -- -function ScaleRect(const Rect: TRect; ScaleX, ScaleY: Double): TRect; - {$ifdef UseInline} inline; {$endif} -begin - Result.Left := Round(Rect.Left * ScaleX); - Result.Right := Round(Rect.Right * ScaleX); - Result.Top := Round(Rect.Top * ScaleY); - Result.Bottom := Round(Rect.Bottom * ScaleY); -end; - -//-- BG ---------------------------------------------------------- 06.10.2010 -- -function CalcClipRect(Canvas: TCanvas; const Rect: TRect; Printing: boolean): TRect; - {$ifdef UseInline} inline; {$endif} -var - Point: TPoint; - SizeV, SizeW: TSize; -begin - GetWindowOrgEx(Canvas.Handle, Point); {when scrolling or animated Gifs, canvas may not start at X=0, Y=0} - Result := Rect; - OffsetRect(Result, -Point.X, -Point.Y); - if Printing then - begin - GetViewportExtEx(Canvas.Handle, SizeV); - GetWindowExtEx(Canvas.Handle, SizeW); - Result := ScaleRect(Result, SizeV.cx / SizeW.cx, SizeV.cy / SizeW.cy); - end; -end; - -procedure GetClippingRgn(Canvas: TCanvas; const ARect: TRect; Printing: boolean; var Rgn, SaveRgn: HRgn); - {$ifdef UseInline} inline; {$endif} -var - Point: TPoint; - SizeV, SizeW: TSize; - HF, VF: double; - Rslt: Integer; -begin -{find a clipregion to prevent overflow. First check to see if there is - already a clip region. Return the old region, SaveRgn, (or 0) so it can be - restored later.} - SaveRgn := CreateRectRgn(0, 0, 1, 1); - Rslt := GetClipRgn(Canvas.Handle, SaveRgn); {Rslt = 1 for existing region, 0 for none} - if Rslt = 0 then - begin - DeleteObject(SaveRgn); - SaveRgn := 0; - end; -{Form the region} - GetWindowOrgEx(Canvas.Handle, Point); {when scrolling or animated Gifs, canvas may not start at X=0, Y=0} - with ARect do - if not Printing then - Rgn := CreateRectRgn(Left - Point.X, Top - Point.Y, Right - Point.X, Bottom - Point.Y) - else - begin - GetViewportExtEx(Canvas.Handle, SizeV); - GetWindowExtEx(Canvas.Handle, SizeW); - HF := (SizeV.cx / SizeW.cx); {Horizontal adjustment factor} - VF := (SizeV.cy / SizeW.cy); {Vertical adjustment factor} - Rgn := CreateRectRgn(Round(HF * (Left - Point.X)), Round(VF * (Top - Point.Y)), Round(HF * (Right - Point.X)), Round(VF * (Bottom - Point.Y))); - end; - if Rslt = 1 then {if there was a region, use the intersection with this region} - CombineRgn(Rgn, Rgn, SaveRgn, Rgn_And); -end; - -function WideTrim(const S: UnicodeString): UnicodeString; - {$ifdef UseInline} inline; {$endif} -var - I, L: Integer; -begin - L := Length(S); - I := 1; - while (I <= L) and (S[I] <= ' ') do - Inc(I); - if I > L then - Result := '' - else - begin - while S[L] <= ' ' do - Dec(L); - Result := Copy(S, I, L - I + 1); - end; -end; - -procedure WrapTextW(Canvas: TCanvas; X1, Y1, X2, Y2: Integer; S: UnicodeString); - {$ifdef UseInline} inline; {$endif} -{Wraps text in a clipping rectangle. Font must be set on entry} -var - ARect: TRect; - TAlign: Integer; -begin - TAlign := SetTextAlign(Canvas.Handle, TA_Top or TA_Left); - ARect := Rect(X1, Y1, X2, Y2); - DrawTextW(Canvas.Handle, PWideChar(S), Length(S), ARect, DT_Wordbreak); - SetTextAlign(Canvas.Handle, TAlign); -end; - -function GetTextExtent(DC: HDC; P: PWideChar; N: Integer): TSize; - {$ifdef UseInline} inline; {$endif} -var - Dummy: Integer; -begin - if not IsWin32Platform then - GetTextExtentExPointW(DC, P, N, 0, @Dummy, nil, Result) - else - GetTextExtentPoint32W(DC, P, N, Result); {win95, 98 ME} -end; - -procedure FillRectWhite(Canvas: TCanvas; X1, Y1, X2, Y2: Integer; Color: TColor - {$ifdef has_StyleElements};const AStyleElements : TStyleElements{$endif}); - {$ifdef UseInline} inline; {$endif} -var - OldBrushStyle: TBrushStyle; - OldBrushColor: TColor; -begin - with Canvas do - begin - OldBrushStyle := Brush.Style; {save style first} - OldBrushColor := Brush.Color; - Brush.Color := ThemedColor(Color - {$ifdef has_StyleElements},seClient in AStyleElements{$endif}); - Brush.Style := bsSolid; - FillRect(Rect(X1, Y1, X2, Y2)); - Brush.Color := OldBrushColor; - Brush.Style := OldBrushStyle; {style after color as color changes style} - end; -end; - -{$ifdef has_StyleElements} -procedure DrawFormControlRect(Canvas: TCanvas; X1, Y1, X2, Y2: Integer; Raised, PrintMonoBlack, Disabled: boolean; Color: TColor; - const AStyleElements : TStyleElements); -{$else} -procedure DrawFormControlRect(Canvas: TCanvas; X1, Y1, X2, Y2: Integer; Raised, PrintMonoBlack, Disabled: boolean; Color: TColor); -{$endif} - {$ifdef UseInline} inline; {$endif} -{Draws lowered rectangles for form control printing} -var - OldStyle: TPenStyle; - OldWid: Integer; - OldBrushStyle: TBrushStyle; - OldBrushColor: TColor; - MonoBlack: boolean; -begin - with Canvas do - begin - MonoBlack := PrintMonoBlack and (GetDeviceCaps(Handle, BITSPIXEL) = 1) and - (GetDeviceCaps(Handle, PLANES) = 1); - Dec(X2); Dec(Y2); - OldWid := Pen.Width; - OldStyle := Pen.Style; - OldBrushStyle := Brush.Style; {save style first} - OldBrushColor := Brush.Color; - if not MonoBlack then - begin - if Disabled then - Brush.Color := ThemedColor(clBtnFace{$ifdef has_StyleElements},seClient in AStyleElements{$endif}) - else - Brush.Color := ThemedColor(color{$ifdef has_StyleElements},seClient in AStyleElements{$endif}); - end - else - Brush.Color := clBlack;//color; - Brush.Style := bsSolid; - FillRect(Rect(X1, Y1, X2, Y2)); - Brush.Color := OldBrushColor; - Brush.Style := OldBrushStyle; {style after color as color changes style} - - Pen.Style := psInsideFrame; - if MonoBlack then - begin - Pen.Width := 1; - Pen.Color := clBlack; - end - else - begin - Pen.Width := 2; - if Raised then - Pen.Color := ThemedColor(clBtnHighlight{$ifdef has_StyleElements},seClient in AStyleElements{$endif})//clSilver - else - Pen.Color := ThemedColor(clBtnShadow{$ifdef has_StyleElements},seClient in AStyleElements{$endif}); - end; - MoveTo(X1, Y2); - LineTo(X1, Y1); - LineTo(X2, Y1); - if not MonoBlack then - begin - if Raised then - Pen.Color := ThemedColor(clBtnShadow{$ifdef has_StyleElements},seClient in AStyleElements{$endif}) - else - Pen.Color := ThemedColor(clBtnHighlight{$ifdef has_StyleElements},seClient in AStyleElements{$endif});//clSilver; - end - else - Pen.Color := clSilver; - LineTo(X2, Y2); - LineTo(X1, Y2); - Pen.Style := OldStyle; - Pen.Width := OldWid; - end; -end; - -{$IFDEF Ver90} - -procedure Assert(B: boolean; const S: ThtString); -begin {dummy Assert for Delphi 2} -end; -{$ENDIF} - -//-- BG ---------------------------------------------------------- 26.12.2011 -- -function SpecWidth(Value: Integer; VType: TWidthType): TSpecWidth; - {$ifdef UseInline} inline; {$endif} -begin - Result.Value := Value; - Result.VType := VType; -end; - -//-- BG ---------------------------------------------------------- 26.12.2011 -- -function ToSpecWidth(AsInteger: Integer; AsString: string): TSpecWidth; -// Return a TSpecWidth prepared with values given in AsInteger *and* AsString. -// AsString is used to evaluate the type while AsInteger is used to evaluate the value. -// BG, 26.12.2011: Currently percentage is still converted to permille as done before Value became type Integer. - {$ifdef UseInline} inline; {$endif} -begin - if Pos('%', AsString) > 0 then - begin - Result.Value := Min(100, AsInteger) * 10; - Result.VType := wtPercent; - end - else if Pos('*', AsString) > 0 then // this is not specified for , . Only and support it officially. - begin - Result.Value := AsInteger; - Result.VType := wtRelative; - end - else - begin - Result.Value := AsInteger; - Result.VType := wtAbsolute; - end; -end; - -{ TAttribute } - -constructor TAttribute.Create(ASym: TAttrSymb; const AValue: Double; const NameStr, ValueStr: ThtString; ACodePage: Integer); -begin - inherited Create; - Which := ASym; - DblValue := AValue; - Value := Trunc(AValue); - WhichName := NameStr; - Name := ValueStr; - CodePage := ACodePage; -end; - -//-- BG ---------------------------------------------------------- 27.01.2013 -- -constructor TAttribute.CreateCopy(ASource: TAttribute); -begin - inherited Create; - Which := ASource.Which; - WhichName := ASource.WhichName; - Value := ASource.Value; - DblValue := ASource.DblValue; - Name := ASource.Name; - CodePage := ASource.CodePage; -end; - -{----------------TAttributeList} - -procedure TAttributeList.Clear; -begin - inherited Clear; - SaveID := ''; -end; - -//-- BG ---------------------------------------------------------- 21.10.2016 -- -function TAttributeList.Clone: TAttributeList; -begin - Result := TAttributeList.CreateCopy(Self); -end; - -//-- BG ---------------------------------------------------------- 27.01.2013 -- -constructor TAttributeList.CreateCopy(ASource: TAttributeList); -var - I: Integer; -begin - inherited Create; - if ASource <> nil then - for I := 0 to ASource.Count - 1 do - Add(TAttribute.CreateCopy(ASource[I])); -end; - -function TAttributeList.CreateStringList: ThtStringList; -var - I: Integer; -begin - Result := ThtStringList.Create; - for I := 0 to Count - 1 do - with Items[I] do - Result.Add(WhichName + '=' + Name); -end; - -function TAttributeList.Find(const Name: ThtString; var T: TAttribute): Boolean; -var - I: Integer; -begin - for I := 0 to Count - 1 do - if Items[I].WhichName = Name then - begin - Result := True; - T := Items[I]; - Exit; - end; - Result := False; -end; - -function TAttributeList.Find(Sy: TAttrSymb; var T: TAttribute): Boolean; -var - I: Integer; -begin - for I := 0 to Count - 1 do - if Items[I].Which = Sy then - begin - Result := True; - T := Items[I]; - Exit; - end; - Result := False; -end; - -function TAttributeList.GetAttribute(Index: Integer): TAttribute; -begin - Result := Get(Index); -end; - -function TAttributeList.GetClass: ThtString; -var - T: TAttribute; - S: ThtString; - I: Integer; -begin - Result := ''; - T := nil; - if Find(ClassSy, T) then - begin - S := Lowercase(Trim(T.Name)); - I := Pos(' ', S); - if I <= 0 then {a single class name} - Result := S - else - begin {multiple class names. Format as "class1.class2.class3"} - repeat - Result := Result + '.' + System.Copy(S, 1, I - 1); - System.Delete(S, 1, I); - S := Trim(S); - I := Pos(' ', S); - until I <= 0; - Result := Result + '.' + S; - Result := SortContextualItems(Result); {put in standard multiple order} - System.Delete(Result, 1, 1); {remove initial '.'} - end; - end; -end; - -function TAttributeList.GetID: ThtString; -var - T: TAttribute; -begin - Result := SaveID; - T := nil; - if (Result = '') and Find(IDSy, T) then - begin - Result := Lowercase(T.Name); - SaveID := Result; - end; -end; - -function TAttributeList.GetTitle: ThtString; -var - T: TAttribute; -begin - T := nil; - if Find(TitleSy, T) then - Result := T.Name - else - Result := ''; -end; - -{----------------TUrlTarget.Create} - -constructor TUrlTarget.Create; -begin - inherited Create; - //utText := TutText.Create; - utText.Start := -1; - utText.Last := -1; -end; - -destructor TUrlTarget.Destroy; -begin - //FreeAndNil(utText); - inherited Destroy; -end; - -var - Sequence: Integer = 10; - -procedure TUrlTarget.Assign(const AnUrl, ATarget: ThtString; L: TAttributeList; AStart: Integer); -var - SL: ThtStringList; -begin - Url := AnUrl; - Target := ATarget; - ID := Sequence; - Inc(Sequence); - utText.Start := AStart; - SL := L.CreateStringList; - try - Attr := SL.Text; - finally - SL.Free; - end; -end; - -procedure TUrlTarget.Assign(const UT: TUrlTarget); -begin - Url := UT.Url; - Target := UT.Target; - ID := UT.ID; - TabIndex := UT.TabIndex; - Attr := UT.Attr; - utText.Start := UT.utText.Start; - utText.Last := UT.utText.Last; -end; - -procedure TUrlTarget.Clear; -begin - Url := ''; - Target := ''; - ID := 0; - TabIndex := 0; - Attr := ''; - utText.Start := -1; - utText.Last := -1; -end; - -procedure TUrlTarget.SetLast(List: TFontObjBaseList; ALast: Integer); -var - I: Integer; -begin - utText.Last := ALast; - if List.Count > 0 then - for I := List.Count - 1 downto 0 do - if ID = List[I].UrlTarget.ID then - List[I].UrlTarget.utText.Last := ALast - else - Break; -end; - -{----------------TSelTextCount} - -procedure TSelTextCount.AddText(P: PWideChar; Size: Integer); -var - I: Integer; -begin - for I := 0 to Size - 1 do - case P[I] of - {ImgPan and FmCtl used to mark images, form controls} - FmCtl, ImgPan:; - else - Inc(Leng); - end; -end; - -procedure TSelTextCount.AddTextCR(P: PWideChar; Size: Integer); -begin - AddText(P, Size); - AddText(#13#10, 2); -end; - -function TSelTextCount.Terminate: Integer; -begin - Result := Leng; -end; - -{----------------SelTextBuf.Create} - -constructor TSelTextBuf.Create(ABuffer: PWideChar; Size: Integer); -begin - inherited Create; - Buffer := ABuffer; - BufferLeng := Size; -end; - -procedure TSelTextBuf.AddText(P: PWideChar; Size: Integer); -var - SizeM1: Integer; - I: Integer; -begin - SizeM1 := BufferLeng - 1; - for I := 0 to Size - 1 do - case P[I] of - {ImgPan and FmCtl used to mark images, form controls} - FmCtl, ImgPan, BrkCh:; - else - if Leng < SizeM1 then - begin - Buffer[Leng] := P[I]; - Inc(Leng); - end; - end; -end; - -function TSelTextBuf.Terminate: Integer; -begin - Buffer[Leng] := #0; - Result := Leng + 1; -end; - -{ TMapArea } - -//-- BG ---------------------------------------------------------- 25.06.2014 -- -destructor TMapArea.Destroy; -begin - if FRegion <> 0 then - DeleteObject(FRegion); - inherited; -end; - -//-- BG ---------------------------------------------------------- 31.12.2011 -- -function TMapArea.PtInArea(X, Y: Integer): Boolean; -begin - Result := PtInRegion(FRegion, X, Y); -end; - -{ TMapAreaList } - -//-- BG ---------------------------------------------------------- 31.12.2011 -- -function TMapAreaList.GetArea(Index: Integer): TMapArea; -begin - Result := Get(Index); -end; - -{ TMapItem } - -constructor TMapItem.Create; -begin - inherited Create; - FAreas := TMapAreaList.Create; -end; - -destructor TMapItem.Destroy; -begin - FAreas.Free; - inherited Destroy; -end; - -function TMapItem.GetURL(X, Y: Integer; var URLTarg: TUrlTarget; var ATitle: ThtString): boolean; -var - I: Integer; - Area: TMapArea; -begin - Result := False; - URLTarg := nil; - for I := 0 to FAreas.Count - 1 do - begin - Area := FAreas[I]; - if Area.PtInArea(X, Y) then - begin - if Area.HRef <> '' then {could be NoHRef} - begin - URLTarg := TUrlTarget.Create; - URLTarg.URL := Area.HRef; - URLTarg.Target := Area.Target; - ATitle := Area.Title; - Result := True; - end; - Exit; - end; - end; -end; - -procedure TMapItem.AddArea(Attrib: TAttributeList); -const - MAXCNT = 300; - - function GetSubStr(var S: ThtString): ThtString; - var - J, K: Integer; - begin - J := Pos(',', S); - K := Pos(' ', S); {for non comma situations (bad syntax)} - if (J > 0) and ((K = 0) or (K > J)) then - begin - Result := copy(S, 1, J - 1); - Delete(S, 1, J); - end - else if K > 0 then - begin - Result := copy(S, 1, K - 1); - Delete(S, 1, K); - end - else - begin - Result := Trim(S); - S := ''; - end; - while (Length(S) > 0) and ((S[1] = ',') or (S[1] = ' ')) do - Delete(S, 1, 1); - end; - -var - S, S1: ThtString; - I, Cnt, Rad: Integer; - Nm: ThtString; - Coords: array[0..MAXCNT] of Integer; - Rect: TRect absolute Coords; - Shape: (shRect, shCircle, shPoly, shDefault); - Area: TMapArea; -begin -// if FAreas.Count >= 1000 then -// Exit; - Area := TMapArea.Create; - try - Shape := shRect; - Cnt := 0; - for I := 0 to Attrib.Count - 1 do - with Attrib[I] do - case Which of - HRefSy: - Area.FHRef := Name; - - TargetSy: - Area.FTarget := Name; - - TitleSy: - Area.FTitle := Name; - - NoHrefSy: - Area.FHRef := ''; - - CoordsSy: - begin - Cnt := 0; - S := Trim(Name); - S1 := GetSubStr(S); - while (S1 <> '') and (Cnt <= MAXCNT) do - begin - Coords[Cnt] := StrToIntDef(S1, 0); - S1 := GetSubStr(S); - Inc(Cnt); - end; - end; - - ShapeSy: - begin - Nm := copy(Lowercase(Name), 1, 4); - if (Nm = 'circ') or (Nm = 'circle') then - Shape := shCircle - else if (Nm = 'poly') or (Nm = 'polygon') then - Shape := shPoly - else if (Nm = 'rect') or (Nm = 'rectangle') then - Shape := shRect; - end; - end; - - case Shape of - shRect: - begin - if Cnt < 4 then - Exit; - Inc(Coords[2]); - Inc(Coords[3]); - Area.FRegion := CreateRectRgnIndirect(Rect); - end; - - shCircle: - begin - if Cnt < 3 then - Exit; - Rad := Coords[2]; - Dec(Coords[0], Rad); - Dec(Coords[1], Rad); - Coords[2] := Coords[0] + 2 * Rad + 1; - Coords[3] := Coords[1] + 2 * Rad + 1; - Area.FRegion := CreateEllipticRgnIndirect(Rect); - end; - - shPoly: - begin - if Cnt < 6 then - Exit; -{$ifdef LCL} - Area.FRegion := CreatePolygonRgn(PPoint(@Coords[0]), Cnt div 2, Winding); -{$else} - Area.FRegion := CreatePolygonRgn(Coords, Cnt div 2, Winding); -{$endif} - end; - end; - if Area.FRegion <> 0 then - begin - FAreas.Add(Area); - Area := nil; - end; - finally - Area.Free; - end; -end; - - -{ TIndentManager } - -constructor TIndentManager.Create; -begin - inherited Create; - R := TIndentRecList.Create; - L := TIndentRecList.Create; -end; - -destructor TIndentManager.Destroy; -begin - R.Free; - L.Free; - inherited Destroy; -end; - -//-- BG ---------------------------------------------------------- 05.02.2011 -- -function TIndentManager.AddLeft(YT, YB, W: Integer): TIndentRec; -// For a floating block, update the left edge information. -begin - Result := TIndentRec.Create; - Result.YT := YT; - Result.YB := YB; - Result.X := LeftEdge(YT) + W; - L.Add(Result); - LTopMin := YT; -end; - -//-- BG ---------------------------------------------------------- 05.02.2011 -- -function TIndentManager.AddRight(YT, YB, W: Integer): TIndentRec; -// For a floating block, update the right edge information. -begin - Result := TIndentRec.Create; - Result.YT := YT; - Result.YB := YB; - Result.X := RightEdge(YT) - W; - R.Add(Result); - RTopMin := YT; -end; - -//-- BG ---------------------------------------------------------- 12.08.2013 -- -procedure TIndentManager.AdjustY(FirstLeftIndex, FirstRightIndex, Y, Height: Integer); -var - I, D: Integer; - IR: TIndentRec; -begin - D := 0; - for I := FirstLeftIndex to L.Count - 1 do - begin - IR := L[I]; - if IR.YT > Y then - begin - if IR.YT < Y + Height then - D := Y + Height - IR.YT; - Inc(IR.YT, D); - Inc(IR.YB, D); - end; - end; - - D := 0; - for I := FirstRightIndex to R.Count - 1 do - begin - IR := R[I]; - if IR.YT > Y then - begin - if IR.YT < Y + Height then - D := Y + Height - IR.YT; - Inc(IR.YT, D); - Inc(IR.YB, D); - end; - end; -end; - -{----------------TIndentManager.Reset} - -//-- BG ---------------------------------------------------------- 23.02.2011 -- -procedure TIndentManager.Init(Lf, Wd: Integer); -begin - LfEdge := Lf; - Width := Wd; - R.Clear; - L.Clear; - LTopMin := 0; - RTopMin := 0; - CurrentID := nil; -end; - -procedure TIndentManager.Reset(Lf: Integer); -begin - LfEdge := Lf; - CurrentID := nil; -end; - -const - BigY = 9999999; - -//-- BG ---------------------------------------------------------- 23.02.2011 -- -function TIndentManager.LeftEdge(Y: Integer): Integer; -// Returns the right most left indentation at Y relative to LfEdge. -// If there are no left indentations at Y, returns 0. -var - I: Integer; - IR: TIndentRec; - MinX: Integer; -begin - Result := -MaxInt; - MinX := 0; - for I := 0 to L.Count - 1 do - begin - IR := L[I]; - if (Y >= IR.YT) and (Y < IR.YB) and (Result < IR.X) then - if (IR.ID = nil) or (IR.ID = CurrentID) then - Result := IR.X; - if IR.ID = CurrentID then - MinX := IR.X; - end; - if Result = -MaxInt then - Result := MinX; -end; - -//-- BG ---------------------------------------------------------- 23.02.2011 -- -function TIndentManager.LeftIndent(Y: Integer): Integer; -// Returns the right most left indentation at Y relative to block. -// If there are no left indentations at Y, returns LfEdge. -begin - Result := LeftEdge(Y) + LfEdge; -end; - -//-- BG ---------------------------------------------------------- 23.02.2011 -- -function TIndentManager.RightEdge(Y: Integer): Integer; -// Returns the left most right indentation at Y relative LfEdge. -// If there are no indentations at Y, returns Width. -var - I: Integer; - IR: TIndentRec; - MinX: Integer; -begin - Result := MaxInt; - for I := 0 to R.Count - 1 do - begin - IR := R[I]; - if (Y >= IR.YT) and (Y < IR.YB) and (Result > IR.X) then - if (IR.ID = nil) or (IR.ID = CurrentID) then - Result := IR.X; - end; - if Result = MaxInt then - begin - //BG, 01.03.2011: Issue 77: Error of the elements - MinX := 0; - for I := L.Count - 1 downto 0 do - begin - IR := L[I]; - if IR.ID = CurrentID then - begin - MinX := IR.X; - break; - end; - end; - Result := Width + MinX; - end; -end; - -//-- BG ---------------------------------------------------------- 23.02.2011 -- -function TIndentManager.RightSide(Y: Integer): Integer; -// Returns the left most right indentation at Y relative to block. -// If there are no indentations at Y, returns Width + LfEdge. -begin - Result := RightEdge(Y) + LfEdge; -end; - -function TIndentManager.ImageBottom: Integer; -// Returns the bottom of the last floating image. -var - I: Integer; -begin - Result := 0; - for I := 0 to L.Count - 1 do - with L[I] do - if (ID = nil) and (YB > Result) then - Result := YB; - for I := 0 to R.Count - 1 do - with R[I] do - if (ID = nil) and (YB > Result) then - Result := YB; -end; - -procedure TIndentManager.GetClearY(out CL, CR: Integer); -{returns the left and right Y values which will clear image margins} -var - I: Integer; -begin - CL := -1; - for I := 0 to L.Count - 1 do - with L[I] do - if (ID = nil) and (YB > CL) then - CL := YB; - CR := -1; - for I := 0 to R.Count - 1 do - with R[I] do - if (ID = nil) and (YB > CR) then - CR := YB; - Inc(CL); - Inc(CR); -end; - -//-- BG ---------------------------------------------------------- 06.02.2011 -- -function TIndentManager.AlignLeft(var Y: Integer; W: Integer): Integer; -// Find an available area to the left at or below Y with a width of W pixels. -// -// Returns the absolute X position of the found area. -// On return Y may be adjusted to a larger value if at original Y there is not -// enough width W. -var - I, CL, CR, LX, RX, XL, XR, YY, MinX: Integer; -begin - Y := Max(Y, LTopMin); - Result := LeftEdge(Y); - if Result + W > RightEdge(Y) then - begin - // too wide, must find a wider place below: - YY := Y; - MinX := 0; - - CL := Y; - XL := Result; // valium for the compiler - for I := L.Count - 1 downto 0 do - with L[I] do - begin - if ID = CurrentID then - begin - MinX := X; - break; - end; - if (ID = nil) and (YB > Y) and ((YB < CL) or (CL = Y)) then - begin - if X = LeftEdge(YB - 1) then - begin - // This is the right most left indentation - LX := LeftEdge(YB); - RX := RightEdge(YB) - W; - if YY < YB then - YY := YB; - if RX >= LX then - begin - CL := YB; - XL := LX; - end; - end; - end; - end; - - CR := Y; - XR := Result; // valium for the compiler - for I := R.Count - 1 downto 0 do - with R[I] do - begin - if ID = CurrentID then - break; - if (ID = nil) and (YB > Y) and ((YB < CR) or (CR = Y)) then - begin - if X = RightEdge(YB - 1) then - begin - // This is the left most right indentation - LX := LeftEdge(YB); - RX := RightEdge(YB) - W; - if YY < YB then - YY := YB; - if RX >= LX then - begin - CR := YB; - XR := LX; - end; - end; - end; - end; - - if CL = Y then - begin - if CR = Y then - begin - // no better place found, just append at the end. - Y := YY; - Result := MinX; - end - else - begin - Y := CR; - Result := XR; - end - end - else if CR = Y then - begin - Y := CL; - Result := XL; - end - else if CL < CR then - begin - Y := CL; - Result := XL; - end - else - begin - Y := CR; - Result := XR; - end; - end; - Inc(Result, LfEdge); -end; - -function TIndentManager.AlignRight(var Y: Integer; W: Integer): Integer; -// Find an available area to the right at or below Y with a width of W pixels. -// -// Returns the absolute X position of the found area. -// On return Y may be adjusted to a larger value if at original Y there is not -// enough width W. -var - I, CL, CR, LX, RX, XL, XR, YY, MaxX: Integer; -begin - Y := Max(Y, RTopMin); - Result := RightEdge(Y) - W; - if Result < LeftEdge(Y) then - begin - // too wide, must find a wider place below: - YY := Y; - MaxX := Width - W; - - CL := Y; - XL := Result; // valium for the compiler - for I := L.Count - 1 downto 0 do - with L[I] do - begin - if ID = CurrentID then - break; - if (ID = nil) and (YB > Y) and ((YB < CL) or (CL = Y)) then - begin - if X = LeftEdge(YB - 1) then - begin - // This is the right most left indentation - LX := LeftEdge(YB); - RX := RightEdge(YB) - W; - if YY < YB then - YY := YB; - if RX >= LX then - begin - CL := YB; - XL := RX; - end; - end; - end; - end; - - CR := Y; - XR := Result; // valium for the compiler - for I := R.Count - 1 downto 0 do - with R[I] do - begin - if ID = CurrentID then - begin - MaxX := X - W; - break; - end; - if (ID = nil) and (YB > Y) and ((YB < CR) or (CR = Y)) then - begin - if X = RightEdge(YB - 1) then - begin - // This is the left most right indentation - LX := LeftEdge(YB); - RX := RightEdge(YB) - W; - if YY < YB then - YY := YB; - if RX >= LX then - begin - CR := YB; - XR := RX; - end; - end; - end; - end; - - if CL = Y then - begin - if CR = Y then - begin - // no better place found, just append at the end. - Y := YY; - Result := MaxX; - end - else - begin - Y := CR; - Result := XR; - end - end - else if CR = Y then - begin - Y := CL; - Result := XL; - end - else if CL < CR then - begin - Y := CL; - Result := XL; - end - else - begin - Y := CR; - Result := XR; - end; - end; - Inc(Result, LfEdge); -end; - -function TIndentManager.GetNextWiderY(Y: Integer): Integer; -{returns the next Y value which offers a wider space or Y if none} -var - I, CL, CR: Integer; -begin - CL := Y; - for I := 0 to L.Count - 1 do - with L[I] do - if not Assigned(ID) and (YB > Y) and ((YB < CL) or (CL = Y)) then - CL := YB; - CR := Y; - for I := 0 to R.Count - 1 do - with R[I] do - if not Assigned(ID) and (YB > Y) and ((YB < CR) or (CR = Y)) then - CR := YB; - if CL = Y then - Result := CR - else if CR = Y then - Result := CL - else - Result := Min(CL, CR); -end; - -function TIndentManager.SetLeftIndent(XLeft, Y: Integer): Integer; -var - IR: TIndentRec; -begin - IR := TIndentRec.Create; - with IR do - begin - YT := Y; - YB := BigY; - X := XLeft; - ID := CurrentID; - end; - Result := L.Add(IR); -end; - -function TIndentManager.SetRightIndent(XRight, Y: Integer): Integer; -var - IR: TIndentRec; -begin - IR := TIndentRec.Create; - with IR do - begin - YT := Y; - YB := BigY; - X := XRight; - ID := CurrentID; - end; - Result := R.Add(IR); -end; - -procedure TIndentManager.FreeLeftIndentRec(I: Integer); -begin - L.Delete(I); -end; - -procedure TIndentManager.FreeRightIndentRec(I: Integer); -begin - R.Delete(I); -end; - -function CopyPalette(Source: hPalette): hPalette; - {$ifdef UseInline} inline; {$endif} -var - LP: ^TLogPalette; - NumEntries: Integer; -begin - Result := 0; - if ColorBits > 8 then - Exit; - GetMem(LP, Sizeof(TLogPalette) + 256 * Sizeof(TPaletteEntry)); - try - with LP^ do - begin - palVersion := $300; - palNumEntries := 256; - NumEntries := GetPaletteEntries(Source, 0, 256, palPalEntry); - if NumEntries > 0 then - begin - palNumEntries := NumEntries; - Result := CreatePalette(LP^); - end; - end; - finally - FreeMem(LP, Sizeof(TLogPalette) + 256 * Sizeof(TPaletteEntry)); - end; -end; - -//function InSet(W: WideChar; S: SetOfChar): boolean; -//begin -// if Ord(W) > 255 then -// Result := False -// else -// Result := ThtChar(W) in S; -//end; - -{----------------TCharCollection.GetAsString:} - -function TCharCollection.GetAsString: ThtString; -begin - Result := Copy(FChars, 1, FCurrentIndex); -end; - -function TCharCollection.GetCapacity: Integer; -begin - Result := Length(FChars); -end; - -function TCharCollection.GetSize: Integer; -begin - Result := FCurrentIndex; -end; - -constructor TCharCollection.Create; -begin - inherited; - FCurrentIndex := 0; - Capacity := TokenLeng; -end; - -procedure TCharCollection.SetCapacity(NewCapacity: Integer); -begin - if NewCapacity <> Capacity then - begin - SetLength(FChars, NewCapacity); - SetLength(FIndices, NewCapacity + 1); - end; -end; - -procedure TCharCollection.Add(C: ThtChar; Index: Integer); -begin - Inc(FCurrentIndex); - if Capacity <= FCurrentIndex then - Capacity := Capacity + 50; - FIndices[FCurrentIndex] := Index; - FChars[FCurrentIndex] := C; -end; - -procedure TCharCollection.Add(const S: ThtString; Index: Integer); -var - K, L: Integer; -begin - L := Length(S); - if L > 0 then - begin - K := FCurrentIndex + L; - if Capacity <= K then - Capacity := K + 50; - Move(S[1], FChars[FCurrentIndex + 1], L * SizeOf(ThtChar)); - while FCurrentIndex < K do - begin - Inc(FCurrentIndex); - FIndices[FCurrentIndex] := Index; - end; - end; -end; - -procedure TCharCollection.Clear; -begin - FCurrentIndex := 0; - SetLength(FChars, 0); -end; - -//procedure TCharCollection.Concat(T: TCharCollection); -//var -// K: Integer; -//begin -// K := FCurrentIndex + T.FCurrentIndex; -// if Capacity <= K then -// Capacity := K + 50; -// Move(T.FChars[1], FChars[FCurrentIndex + 1], T.FCurrentIndex * SizeOf(ThtChar)); //@@@ Tiburon: todo test -// Move(T.FIndices[1], FIndices[FCurrentIndex + 1], T.FCurrentIndex * Sizeof(Integer)); -// FCurrentIndex := K; -//end; - -{ TokenObj } - -constructor TTokenObj.Create; -begin - inherited; - Capacity := TokenLeng; - FCount := 0; - St := ''; - StringOK := True; -end; - -procedure TTokenObj.AddUnicodeChar(Ch: WideChar; Ind: Integer); -{Ch must be Unicode in this method} -begin - if Capacity <= Count then - Capacity := Capacity + 50; - Inc(FCount); - C[Count] := Ch; - I[Count] := Ind; - StringOK := False; -end; - -procedure TTokenObj.Clear; -begin - FCount := 0; - St := ''; - StringOK := True; -end; - -procedure TTokenObj.AddString(S: TCharCollection); -var - K: Integer; -begin - K := Count + S.FCurrentIndex; - if Capacity <= K then - Capacity := K + 50; - Move(S.FChars[1], C[Count + 1], S.FCurrentIndex * Sizeof(ThtChar)); - Move(S.FIndices[1], I[Count + 1], S.FCurrentIndex * Sizeof(Integer)); - FCount := K; - StringOK := False; -end; - -//procedure TokenObj.Concat(T: TokenObj); -//var -// K: Integer; -//begin -// K := Count + T.Count; -// if Capacity <= K then -// Capacity := K + 50; -// Move(T.C[1], C[Count + 1], T.Count * Sizeof(ThtChar)); -// Move(T.I[1], I[Count + 1], T.Count * Sizeof(Integer)); -// FCount := K; -// StringOK := False; -//end; -// -//procedure TokenObj.Remove(N: Integer); -//begin {remove a single character} -// if N <= Count then -// begin -// if N < Count then -// begin -// Move(C[N + 1], C[N], (Count - N) * Sizeof(ThtChar)); -// Move(I[N + 1], I[N], (Count - N) * Sizeof(Integer)); -// end; -// if StringOK then -// Delete(St, N, 1); -// Dec(FCount); -// end; -//end; -// -//procedure TokenObj.Replace(N: Integer; Ch: ThtChar); -//begin {replace a single character} -// if N <= Count then -// begin -// C[N] := Ch; -// if StringOK then -// St[N] := Ch; -// end; -//end; - -function TTokenObj.GetCapacity: Integer; -begin - Result := Length(C) - 1; -end; - -//-- BG ---------------------------------------------------------- 20.01.2011 -- -procedure TTokenObj.SetCapacity(NewCapacity: Integer); -begin - if NewCapacity <> Capacity then - begin - SetLength(C, NewCapacity + 1); - SetLength(I, NewCapacity + 1); - if NewCapacity < Count then - begin - FCount := NewCapacity; - if StringOK then - St := Copy(St, 1, Count); - end; - end; -end; - -function TTokenObj.GetString: UnicodeString; -begin - if not StringOK then - begin - SetLength(St, Count); - if Count > 0 then - Move(C[1], St[1], SizeOf(WideChar) * Count); - StringOK := True; - end; - Result := St; -end; - -{----------------TIDObjectList} - -function TIDObjectList.AddObject(const S: ThtString; AObject: TIDObject): Integer; -var - I: Integer; - O: TIdObject; -begin - I := -1; - if Find(S, I) then - begin - try - O := Objects[I]; - if O.FreeMe then - O.Free; - except - end; - Delete(I); - end; - Result := inherited AddObject(S, AObject); -end; - -procedure TIDObjectList.Clear; -var - I: Integer; - O: TIdObject; -begin - for I := 0 to Count - 1 do - try - O := Objects[I]; - if O.FreeMe then - O.Free; - except - end; - inherited Clear; -end; - -constructor TIDObjectList.Create; -begin - inherited Create; - Sorted := True; -end; - -destructor TIDObjectList.Destroy; -begin - Clear; - inherited -end; - -//-- BG ---------------------------------------------------------- 04.03.2011 -- -function TIDObjectList.GetObject(Index: Integer): TIDObject; -begin - Result := TIDObject(inherited GetObject(Index)); -end; - - - -//function Points(P0, P1, P2, P3: TPoint): THtBorderPointArray; -//begin -// Result[0] := P0; -// Result[1] := P1; -// Result[2] := P2; -// Result[3] := P3; -//end; - -// BG, 17.04.2013: Color of DrawOnePolygon() must be a real RGB or palette value. Themed or system colors are not supported! -procedure DrawOnePolygon(Canvas: TCanvas; P: THtBorderPointArray; Color: TColor; Side: byte; Printing: Boolean); - {$ifdef UseInline} inline; {$endif} -{Here we draw a 4 sided polygon (by filling a region). This represents one - side (or part of a side) of a border. - For single pixel thickness, drawing is done by lines for better printing} -//BG, 22.08.2010: in print preview results are better without the single pixel exception. -//type -// SideArray = array[0..3, 1..4] of Integer; -//const -// AD: SideArray = ((0, 1, 0, 3), -// (0, 1, 1, 1), -// (2, 0, 2, 1), -// (1, 3, 3, 3)); -// AP: SideArray = ((0, 1, 0, 3), -// (0, 1, 2, 1), -// (2, 0, 2, 2), -// (1, 3, 3, 3)); -var - R: HRgn; -// OldWidth: Integer; -// OldStyle: TPenStyle; -// OldColor: TColor; -// Thickness: Integer; -// P1, P2: TPoint; -// I: SideArray; -begin -// if Side in [0, 2] then -// Thickness := Abs(P[2].X - P[1].X) -// else -// Thickness := Abs(P[1].Y - P[2].Y); -// if Thickness = 1 then -// begin -// with Canvas do -// begin -// OldColor := Pen.Color; -// OldStyle := Pen.Style; -// OldWidth := Pen.Width; -// Pen.Color := Color; -// Pen.Style := psSolid; -// Pen.Width := 1; -// if Printing then -// I := AP -// else -// I := AD; -// P1 := Point(P[I[Side, 1]].X, P[I[Side, 2]].Y); -// P2 := Point(P[I[Side, 3]].X, P[I[Side, 4]].Y); -// MoveTo(P1.X, P1.Y); -// LineTo(P2.X, P2.Y); -// Pen.Width := OldWidth; -// Pen.Style := OldStyle; -// Pen.Color := OldColor; -// end; -// end -// else - begin - R := CreatePolygonRgn(P, 4, Alternate); - try - with Canvas do - begin - Brush.Style := bsSolid; - Brush.Color := Color; - FillRgn(Handle, R, Brush.Handle); - end; - finally - DeleteObject(R); - end; - end; -end; - -{----------------DrawBorder} - {$ifdef has_StyleElements} - -procedure DrawBorder(Canvas: TCanvas; ORect, IRect: TRect; const C: ThtColorArray; - const S: ThtBorderStyleArray; BGround: TColor; Print: boolean; - const AStyleElements : TStyleElements); - - {$else} -procedure DrawBorder(Canvas: TCanvas; ORect, IRect: TRect; const C: ThtColorArray; - const S: ThtBorderStyleArray; BGround: TColor; Print: boolean); - {$endif} - {$ifdef UseInline} inline; {$endif} -{Draw the 4 sides of a border. The sides may be of different styles or colors. - The side indices, 0,1,2,3, represent left, top, right, bottom. - ORect is the outside rectangle of the border, IRect the inside Rectangle. - BGround is the background color used for the bssDouble style} -var - PO, PI, PM, P1, P2, Bnd: THtBorderPointArray; - I: Integer; - Cl, Color: TColor; - MRect: TRect; - lb: TLogBrush; - Pn, OldPn: HPen; - W, D: array[0..3] of Integer; - InPath: boolean; - PenType, Start: Integer; - StyleSet: set of ThtBorderStyle; - OuterRegion, InnerRegion: HRGN; - Brush: TBrush; - -begin -{Limit the borders to somewhat more than the screen size} - - ORect.Bottom := Min(ORect.Bottom, BotLim); - ORect.Top := Max(ORect.Top, TopLim); - IRect.Bottom := Min(IRect.Bottom, BotLim); - IRect.Top := Max(IRect.Top, TopLim); - -{Widths are needed for Dashed, Dotted, and Double} - W[0] := IRect.Left - Orect.Left; - W[1] := IRect.Top - Orect.Top; - W[2] := ORect.Right - IRect.Right; - W[3] := ORect.Bottom - IRect.Bottom; - if (W[0] = 0) and (W[1] = 0) and (W[2] = 0) and (W[3] = 0) then - exit; - -{Find out what style types are represented in this border} - StyleSet := []; - for I := 0 to 3 do - Include(StyleSet, S[I]); - -{find the outside and inside corner points for the border segments} - with ORect do - begin - PO[0] := Point(Left, Bottom); - PO[1] := TopLeft; - PO[2] := Point(Right, Top); - PO[3] := BottomRight; - end; - with IRect do - begin - PI[0] := Point(Left, Bottom); - PI[1] := TopLeft; - PI[2] := Point(Right, Top); - PI[3] := BottomRight; - end; - -{Points midway between the outer and inner rectangle are needed for - ridge, groove, dashed, dotted styles} - if [bssRidge, bssGroove, bssDotted, bssDashed] * StyleSet <> [] then - begin - MRect := Rect((ORect.Left + IRect.Left) div 2, (ORect.Top + IRect.Top) div 2, - (ORect.Right + IRect.Right) div 2, (ORect.Bottom + IRect.Bottom) div 2); - with MRect do - begin - PM[0] := Point(Left, Bottom); - PM[1] := TopLeft; - PM[2] := Point(Right, Top); - PM[3] := BottomRight; - end; - end; - -{the Double style needs the space between inner and outer rectangles divided - into three parts} - if bssDouble in StyleSet then - begin - for I := 0 to 3 do - begin - D[I] := W[I] div 3; - if W[I] mod 3 = 2 then - Inc(D[I]); - end; - - with ORect do - MRect := Rect(Left + D[0], Top + D[1], Right - D[2], Bottom - D[3]); - - with MRect do - begin - P1[0] := Point(Left, Bottom); - P1[1] := TopLeft; - P1[2] := Point(Right, Top); - P1[3] := BottomRight; - end; - - with IRect do - MRect := Rect(Left - D[0], Top - D[1], Right + D[2], Bottom + D[3]); - - with MRect do - begin - P2[0] := Point(Left, Bottom); - P2[1] := TopLeft; - P2[2] := Point(Right, Top); - P2[3] := BottomRight; - end; - end; - -{double, dotted, dashed styles need a background fill} - if (BGround <> clNone) and ([bssDouble, bssDotted, bssDashed] * StyleSet <> []) then - begin - with ORect do - OuterRegion := CreateRectRgn(Left, Top, Right, Bottom); - with IRect do - InnerRegion := CreateRectRgn(Left, Top, Right, Bottom); - CombineRgn(OuterRegion, OuterRegion, InnerRegion, RGN_DIFF); - Brush := TBrush.Create; - try - Brush.Color := ThemedColor(BGround{$ifdef has_StyleElements},seClient in AStyleElements{$endif}) or PalRelative; - Brush.Style := bsSolid; - FillRgn(Canvas.Handle, OuterRegion, Brush.Handle); - finally - Brush.Free; - DeleteObject(OuterRegion); - DeleteObject(InnerRegion); - end; - end; - - InPath := False; - Pn := 0; - OldPn := 0; - Start := 0; - - try - for I := 0 to 3 do - begin - Color := ThemedColor(C[I]{$ifdef has_StyleElements},seClient in AStyleElements{$endif}); - case S[I] of - bssSolid, bssInset, bssOutset: - begin - Bnd[0] := PO[I]; - Bnd[1] := PO[(I + 1) mod 4]; - Bnd[2] := PI[(I + 1) mod 4]; - Bnd[3] := PI[I]; - case S[I] of - bssInset: - if I in [0, 1] then - Color := Darker(Color) - else - Color := Lighter(Color); - - bssOutset: - if I in [2, 3] then - Color := Darker(Color) - else - Color := Lighter(Color); - end; - DrawOnePolygon(Canvas, Bnd, Color or PalRelative, I, Print); - end; - - bssRidge, bssGroove: - begin {ridge or groove} - Cl := Color; - Bnd[0] := PO[I]; - Bnd[1] := PO[(I + 1) mod 4]; - Bnd[2] := PM[(I + 1) mod 4]; - Bnd[3] := PM[I]; - case S[I] of - bssGroove: - if I in [0, 1] then - Color := Darker(Color) - else - Color := Lighter(Color); - - bssRidge: - if I in [2, 3] then - Color := Darker(Color) - else - Color := Lighter(Color); - end; - DrawOnePolygon(Canvas, Bnd, Color or PalRelative, I, Print); - - Color := Cl; - Bnd[0] := PM[I]; - Bnd[1] := PM[(I + 1) mod 4]; - Bnd[2] := PI[(I + 1) mod 4]; - Bnd[3] := PI[I]; - case S[I] of - bssRidge: - if I in [0, 1] then - Color := Darker(Color) - else - Color := Lighter(Color); - - bssGroove: - if (I in [2, 3]) then - Color := Darker(Color) - else - Color := Lighter(Color); - end; - DrawOnePolygon(Canvas, Bnd, Color or PalRelative, I, Print); - end; - - bssDouble: - begin - Color := Color or PalRelative; - - Bnd[0] := PO[I]; - Bnd[1] := PO[(I + 1) mod 4]; - Bnd[2] := P1[(I + 1) mod 4]; - Bnd[3] := P1[I]; - DrawOnePolygon(Canvas, Bnd, Color, I, Print); - - Bnd[0] := P2[I]; - Bnd[1] := P2[(I + 1) mod 4]; - Bnd[2] := PI[(I + 1) mod 4]; - Bnd[3] := PI[I]; - DrawOnePolygon(Canvas, Bnd, Color, I, Print); - end; - - bssDashed, bssDotted: - begin - if not InPath then - begin - lb.lbStyle := BS_SOLID; - lb.lbColor := Color or PalRelative; - lb.lbHatch := 0; - if S[I] = bssDotted then - PenType := PS_Dot or ps_EndCap_Round - else - PenType := PS_Dash or ps_EndCap_Square; - Pn := ExtCreatePen(PS_GEOMETRIC or PenType or ps_Join_Miter, W[I], lb, 0, nil); - OldPn := SelectObject(Canvas.Handle, Pn); - BeginPath(Canvas.Handle); - MoveToEx(Canvas.Handle, PM[I].x, PM[I].y, nil); - Start := I; - InPath := True; - end; - LineTo(Canvas.Handle, PM[(I + 1) mod 4].x, PM[(I + 1) mod 4].y); - if (I = 3) or (S[I + 1] <> S[I]) or (C[I + 1] <> C[I]) or (W[I + 1] <> W[I]) then - begin - if (I = 3) and (Start = 0) then - CloseFigure(Canvas.Handle); {it's a closed path} - EndPath(Canvas.Handle); - StrokePath(Canvas.Handle); - SelectObject(Canvas.Handle, OldPn); - DeleteObject(Pn); - Pn := 0; - InPath := False; - end; - end; - end; - end; - finally - if Pn <> 0 then - begin - SelectObject(Canvas.Handle, OldPn); - DeleteObject(Pn); - end; - end; -end; - -{ TViewerBase } - -//-- BG ---------------------------------------------------------- 24.11.2011 -- -constructor TViewerBase.Create(AOwner: TComponent); -begin - inherited; - PrintMarginLeft := 2.0; - PrintMarginRight := 2.0; - PrintMarginTop := 2.0; - PrintMarginBottom := 2.0; - PrintMaxHPages := 2; - PrintScale := 1.0; - Charset := DEFAULT_CHARSET; - MarginHeight := 5; - MarginWidth := 10; - DefBackground := clBtnFace; - DefFontColor := clBtnText; - DefHotSpotColor := clBlue; - DefOverLinkColor := clBlue; - DefVisitedLinkColor := clPurple; - VisitedMaxCount := 50; - DefFontSize := 12; - DefFontName := htDefFontName; - DefPreFontName := htDefPreFontName; - ImageCacheCount := 5; - QuirksMode := qmStandards; - LoadCursor := crHourGlass; -{$ifdef HasGestures} - Touch.InteractiveGestureOptions := [igoPanSingleFingerHorizontal, igoPanSingleFingerVertical, igoPanInertia]; - Touch.InteractiveGestures := [igPan]; -{$endif} -end; - -//-- BG ---------------------------------------------------------- 16.11.2011 -- -constructor TViewerBase.CreateCopy(Owner: TComponent; Source: TViewerBase); -begin - Create(Owner); - - Charset := Source.Charset; - CodePage := Source.CodePage; - DefBackGround := Source.DefBackGround; - DefFontColor := Source.DefFontColor; - DefFontName := Source.DefFontName; - DefFontSize := Source.DefFontSize; - DefHotSpotColor := Source.DefHotSpotColor; - DefOverLinkColor := Source.DefOverLinkColor; - DefPreFontName := Source.DefPreFontName; - DefVisitedLinkColor := Source.DefVisitedLinkColor; - LoadCursor := Source.LoadCursor; - NoSelect := Source.NoSelect; - ServerRoot := Source.ServerRoot; - - MarginHeight := Source.MarginHeight; - MarginWidth := Source.MarginWidth; - PrintMarginBottom := Source.PrintMarginBottom; - PrintMarginLeft := Source.PrintMarginLeft; - PrintMarginRight := Source.PrintMarginRight; - PrintMarginTop := Source.PrintMarginTop; - PrintMaxHPages := Source.PrintMaxHPages; - PrintScale := Source.PrintScale; - FQuirksMode := Source.QuirksMode; - HistoryMaxCount := Source.HistoryMaxCount; - ImageCacheCount := Source.ImageCacheCount; - VisitedMaxCount := Source.VisitedMaxCount; - - OnBitmapRequest := Source.OnBitmapRequest; - OnDragDrop := Source.OnDragDrop; - OnDragOver := Source.OnDragOver; - OnHistoryChange := Source.OnHistoryChange; - OnHotSpotTargetClick := Source.OnHotSpotTargetClick; - OnHotSpotTargetCovered := Source.OnHotSpotTargetCovered; - OnImageClick := Source.OnImageClick; - OnImageOver := Source.OnImageOver; - OnImageRequest := Source.OnImageRequest; - OnImageRequested := Source.OnImageRequested; - OnInclude := Source.OnInclude; - OnLink := Source.OnLink; - OnMeta := Source.OnMeta; - OnMouseDouble := Source.OnMouseDouble; - OnObjectBlur := Source.OnObjectBlur; - OnObjectChange := Source.OnObjectChange; - OnObjectClick := Source.OnObjectClick; - OnObjectFocus := Source.OnObjectFocus; - OnObjectTag := Source.OnObjectTag; - OnObjectTag := Source.OnObjectTag; - OnPanelCreate := Source.OnPanelCreate; - OnPanelDestroy := Source.OnPanelDestroy; - OnPanelPrint := Source.OnPanelPrint; - OnParseBegin := Source.OnParseBegin; - OnParseEnd := Source.OnParseEnd; - OnPrinted := Source.OnPrinted; - OnPrintFooter := Source.OnPrintFooter; - OnPrintHeader := Source.OnPrintHeader; - OnPrinting := Source.OnPrinting; - OnProcessing := Source.OnProcessing; - OnProgress := Source.OnProgress; - OnScript := Source.OnScript; - OnSoundRequest := Source.OnSoundRequest; - - Cursor := Cursor; - OnKeyDown := OnKeyDown; - OnKeyPress := OnKeyPress; - OnKeyUp := OnKeyUp; - OnMouseDown := OnMouseDown; - OnMouseMove := OnMouseMove; - OnMouseUp := OnMouseUp; - -{$ifdef HasGestures} - Touch := Source.Touch; - OnGesture := Source.OnGesture; -{$endif} -end; - -procedure TViewerBase.SetActiveColor(const Value: TColor); -begin - FOverColor := Value; -end; - -procedure TViewerBase.SetCharset(const Value: TFontCharset); -begin - FCharSet := Value; -end; - -procedure TViewerBase.SetCodePage(const Value: Integer); -begin - FCodePage := Value; -end; - -procedure TViewerBase.SetDefBackground(const Value: TColor); -begin - FBackground := Value; -end; - -procedure TViewerBase.SetOnBitmapRequest(const Value: TGetBitmapEvent); -begin - FOnBitmapRequest := Value; -end; - -procedure TViewerBase.SetOnBitmapRequested(const Value: TGottenBitmapEvent); -begin - FOnBitmapRequested := Value; -end; - -procedure TViewerBase.SetOnDragDrop(const Value: TDragDropEvent); -begin - FOnDragDrop := Value; -end; - -procedure TViewerBase.SetOnDragOver(const Value: TDragOverEvent); -begin - FOnDragOver := Value; -end; - -procedure TViewerBase.SetFontColor(const Value: TColor); -begin - FFontColor := Value; -end; - -procedure TViewerBase.SetFontName(const Value: TFontName); -begin - FFontName := Value; -end; - -procedure TViewerBase.SetFontSize(const Value: Integer); -begin - FFontSize := Value; -end; - -procedure TViewerBase.SetHistoryMaxCount(const Value: Integer); -begin - FHistoryMaxCount := Value; -end; - -procedure TViewerBase.SetHotSpotColor(const Value: TColor); -begin - FHotSpotColor := Value; -end; - -procedure TViewerBase.SetImageCacheCount(const Value: Integer); -begin - FImageCacheCount := Value; -end; - -procedure TViewerBase.SetLoadCursor(const Value: TCursor); -begin - FLoadCursor := Value; -end; - -procedure TViewerBase.SetMarginHeight(const Value: Integer); -begin - FMarginHeight := Value; -end; - -procedure TViewerBase.SetMarginWidth(const Value: Integer); -begin - FMarginWidth := Value; -end; - -procedure TViewerBase.SetNoSelect(const Value: Boolean); -begin - FNoSelect := Value; -end; - -//-- BG ---------------------------------------------------------- 05.01.2010 -- -procedure TViewerBase.SetOnHistoryChange(const Value: TNotifyEvent); -begin - FOnHistoryChange := Value; -end; - -procedure TViewerBase.SetOnHotSpotTargetClick(const Value: THotSpotTargetClickEvent); -begin - FOnHotSpotTargetClick := Value; -end; - -procedure TViewerBase.SetOnHotSpotTargetCovered(const Value: THotSpotTargetEvent); -begin - FOnHotSpotTargetCovered := Value; -end; - -procedure TViewerBase.SetOnImageClick(const Value: TImageClickEvent); -begin - FOnImageClick := Value; -end; - -procedure TViewerBase.SetOnImageOver(const Value: TImageOverEvent); -begin - FOnImageOver := Value; -end; - -procedure TViewerBase.SetOnImageRequest(const Value: TGetImageEvent); -begin - FOnImageRequest := Value; -end; - -procedure TViewerBase.SetOnImageRequested(const Value: TGottenImageEvent); -begin - FOnImageRequested := Value; -end; - -procedure TViewerBase.SetOnInclude(const Handler: TIncludeType); -begin - FOnInclude := Handler; -end; - -//-- BG ---------------------------------------------------------- 05.01.2010 -- -procedure TViewerBase.SetOnLink(const Handler: TLinkType); -begin - FOnLink := Handler; -end; - -procedure TViewerBase.SetOnMeta(const Value: TMetaType); -begin - FOnMeta := Value; -end; - -procedure TViewerBase.SetOnMouseDouble(const Value: TMouseEvent); -begin - FOnMouseDouble := Value; -end; - -procedure TViewerBase.SetOnObjectBlur(const Value: ThtObjectEvent); -begin - FOnObjectBlur := Value; -end; - -procedure TViewerBase.SetOnObjectChange(const Value: ThtObjectEvent); -begin - FOnObjectChange := Value; -end; - -procedure TViewerBase.SetOnObjectClick(const Value: TObjectClickEvent); -begin - FOnObjectClick := Value; -end; - -procedure TViewerBase.SetOnObjectFocus(const Value: ThtObjectEvent); -begin - FOnObjectFocus := Value; -end; - -procedure TViewerBase.SetOnObjectTag(const Value: TObjectTagEvent); -begin - FOnObjectTag := Value; -end; - -procedure TViewerBase.SetOnPanelCreate(const Value: TPanelCreateEvent); -begin - FOnPanelCreate := Value; -end; - -procedure TViewerBase.SetOnPanelDestroy(const Value: TPanelDestroyEvent); -begin - FOnPanelDestroy := Value; -end; - -procedure TViewerBase.SetOnPanelPrint(const Value: TPanelPrintEvent); -begin - FOnPanelPrint := Value; -end; - -procedure TViewerBase.SetOnParseBegin(const Value: TParseEvent); -begin - FOnParseBegin := Value; -end; - -procedure TViewerBase.SetOnParseEnd(const Value: TNotifyEvent); -begin - FOnParseEnd := Value; -end; - -procedure TViewerBase.SetOnPrinted(const Value: THTMLViewPrinted); -begin - FOnPrinted := Value; -end; - -procedure TViewerBase.SetOnPrintFooter(const Value: TPagePrinted); -begin - FOnPrintFooter := Value; -end; - -procedure TViewerBase.SetOnPrintHeader(const Value: TPagePrinted); -begin - FOnPrintHeader := Value; -end; - -procedure TViewerBase.SetOnPrinting(const Value: THTMLViewPrinting); -begin - FOnPrinting := Value; -end; - -procedure TViewerBase.SetOnProcessing(const Value: TProcessingEvent); -begin - FOnProcessing := Value; -end; - -procedure TViewerBase.SetOnProgress(const Value: ThtProgressEvent); -begin - FOnProgress := Value; -end; - -//-- BG ---------------------------------------------------------- 05.01.2010 -- -procedure TViewerBase.SetOnScript(const Handler: TScriptEvent); -begin - FOnScript := Handler; -end; - -//-- BG ---------------------------------------------------------- 05.01.2010 -- -procedure TViewerBase.SetOnSoundRequest(const Handler: TSoundType); -begin - FOnSoundRequest := Handler; -end; - -procedure TViewerBase.SetPreFontName(const Value: TFontName); -begin - FPreFontName := Value; -end; - -procedure TViewerBase.SetPrintMarginBottom(const Value: Double); -begin - FPrintMarginBottom := Value; -end; - -procedure TViewerBase.SetPrintMarginLeft(const Value: Double); -begin - FPrintMarginLeft := Value; -end; - -procedure TViewerBase.SetPrintMarginRight(const Value: Double); -begin - FPrintMarginRight := Value; -end; - -procedure TViewerBase.SetPrintMarginTop(const Value: Double); -begin - FPrintMarginTop := Value; -end; - -procedure TViewerBase.SetPrintMaxHPages(const Value: Integer); -begin - FPrintMaxHPages := Value; -end; - -procedure TViewerBase.SetPrintScale(const Value: Double); -begin - FPrintScale := Value; -end; - -procedure TViewerBase.SetQuirksMode(const AValue: THtQuirksMode); -begin - FQuirksMode := AValue; -end; - -procedure TViewerBase.SetServerRoot(const Value: ThtString); -begin - FServerRoot := ExcludeTrailingPathDelimiter(Trim(Value)); -end; - -procedure TViewerBase.SetVisitedColor(const Value: TColor); -begin - FVisitedColor := Value; -end; - -procedure TViewerBase.SetVisitedMaxCount(const Value: Integer); -begin - FVisitedMaxCount := Value; -end; - -function TViewerBase.StoreFontName: Boolean; -begin - Result := FFontName <> htDefFontName; -end; - -function TViewerBase.StorePreFontName: Boolean; -begin - Result := FPreFontName <> htDefPreFontName; -end; - -procedure TViewerBase.ViewerDragDrop(Sender, Source: TObject; X, Y: Integer); -begin - if Assigned(OnDragDrop) then - OnDragDrop(Self, Source, X, Y); -end; - -procedure TViewerBase.ViewerDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); -begin - if Assigned(OnDragOver) then - OnDragOver(Self, Source, X, Y, State, Accept); -end; - -{$ifdef has_StyleElements} -procedure TViewerBase.UpdateStyleElements; -begin - inherited UpdateStyleElements; -end; -{$endif} - -{ THtmlViewerBase } - -//-- BG ---------------------------------------------------------- 12.09.2010 -- -procedure THtmlViewerBase.KeyDown(var Key: Word; Shift: TShiftState); -begin - // just to make it public. - inherited; -end; - -{ TFrameViewerBase } - -procedure TFrameViewerBase.wmerase(var msg: TMessage); -begin - msg.result := 1; -end; - -{ TIDObject } - -//-- BG ---------------------------------------------------------- 06.03.2011 -- -function TIDObject.FreeMe: Boolean; -begin - Result := False; -end; - -//>-- DZ 18.09.2011 -constructor TIDObject.Create(const AHtmlId: ThtString); -begin - inherited Create; - FHtmlID:= Trim(AHtmlId); -end; - -procedure TIDObject.AfterConstruction(); -begin - inherited AfterConstruction; -{$ifdef UseGlobalObjectId} - Inc(GlobalObjectIdCount); - FGlobalId := GlobalObjectIdPrefix + IntToStr(GlobalObjectIdCount); -{$endif} -end; - -function TIDObject.GetId(): ThtString; -begin - Result := FHtmlId; -{$ifdef UseGlobalObjectId} - if Length(Result) = 0 then - Result := FGlobalId; -{$endif} -end; -//<-- DZ - -{ ThvPanel } - -procedure ThvPanel.SetVisible(Value: boolean); -begin - if Value <> FVisible then - begin - FVisible := Value; - if FVisible then - Show - else - Hide; - end; -end; - -{ ThvProgressBar } - -{$ifndef Compiler20_Plus} -procedure ThvProgressBar.CreateParams(var Params: TCreateParams); -begin - inherited; - - if FStyle = pbstMarquee then - Params.Style := Params.Style or PBS_MARQUEE; -end; - -procedure ThvProgressBar.SetStyle(Value: TProgressBarStyle); -begin - if FStyle <> Value then - begin - FStyle := Value; - - // need to recreate so we set the Params.Style before sending the message -{$ifdef LCL} - RecreateWnd(Self); -{$else} - RecreateWnd; -{$endif} - - case Value of - pbstNormal: SendMessage(Self.Handle, PBM_SETMARQUEE, 0, 0); // switch off marquee animation - pbstMarquee: SendMessage(Self.Handle, PBM_SETMARQUEE, 1, 100); // switch on marquee animation - end; - end; -end; -{$endif} - -{ ThvMeter } - -constructor ThvMeter.Create(AOwner: TComponent); -begin - inherited; - - FLowColor := clRed; // default color - FHighColor := clYellow; // default color - FLow := MinDouble; // wont show unless set - FHigh := MaxDouble; // wont show unless set - FOptimum := 50; -end; - -// GetPosition and SetPosition are called from an overridden Position -// property which allows us to set the position in a way which stops animation -function ThvMeter.GetPosition: Integer; -begin - result := inherited Position; -end; - -procedure ThvMeter.SetPosition(Value: Integer); -begin - if Value = inherited Position then - Exit ; - - // In Vista +, the progress bar only animates on incrementing the position. - // Therefore, we set the value 1 greater and subtract 1, therefore "jumping" to the position. - // And Therefore, making it look more like a meter, than a progressbar - if value < Max then - begin - inherited Position := value + 1; - inherited Position := value; - end - else - begin - Max := Max + 1; - inherited Position := Max; - inherited Position := value; - Max := Max - 1; - end; - - UpdateColor; -end; - -procedure ThvMeter.UpdateColor; -var - position: Integer; -begin - position := GetPosition; - - // This only works if theming is switched off as Windows does not - // change the color. The best you could do is change the state. - // Also, if you switch the values and go to low/high then back to "normal/original" range, it does not switch the color back. - // I do not know how to make it return to the normal color, so chose blue - if position < FLow then - SendMessage(Handle, PBM_SETBARCOLOR, 0, ColorToRGB(FLowColor)) - else if position > FHigh then - SendMessage(Handle, PBM_SETBARCOLOR, 0, ColorToRGB(FHighColor)) - else - SendMessage(Handle, PBM_SETBARCOLOR, 0, ColorToRGB(clBlue)); -end; - -procedure ThvMeter.SetLow(const value: double); -begin - if value = FLow then - Exit; - - if (value > Min) and (value < FHigh) and (value < Max) then - FLow := value; - - UpdateColor; -end; -procedure ThvMeter.SetHigh(const value: double); -begin - if value = FHigh then - Exit; - - if (value < Max) and (value > FLow) and (value > Min) then - FHigh := value; - - UpdateColor; -end; -procedure ThvMeter.SetOptimum(const value: double); -begin - if value = FOptimum then - FOptimum := value; - - // no need to update color as Optimum value has no affect on color - //UpdateColor; -end; - -procedure ThvMeter.SetLowColor(const value: TColor); -begin - if FLowColor = value then - Exit; - - FLowColor := value; - - UpdateColor; -end; -procedure ThvMeter.SetHighColor(const value: TColor); -begin - if FHighColor = value then - Exit; - - FHighColor := value; - - UpdateColor; -end; - - -{ TIndentRecList } - -//-- BG ---------------------------------------------------------- 06.10.2016 -- -function TIndentRecList.Get(Index: Integer): TIndentRec; -begin - Result := inherited Get(Index); -end; - -{ ThtMap } - -//-- BG ---------------------------------------------------------- 06.10.2016 -- -function ThtMap.Get(Index: Integer): TMapItem; -begin - Result := inherited Get(Index); -end; - -{ TFontObjBaseList } - -//-- BG ---------------------------------------------------------- 06.10.2016 -- -function TFontObjBaseList.GetBase(Index: Integer): TFontObjBase; -begin - Result := inherited Get(Index); -end; - -initialization -{$ifdef UseGlobalObjectId} - GlobalObjectIdPrefix := 'GOID-'; - GlobalObjectIdCount := 0; //>-- DZ -{$endif} -end. - diff --git a/CORE/Source/Plugins/Htmlviewer/source/HtmlBuffer.pas b/CORE/Source/Plugins/Htmlviewer/source/HtmlBuffer.pas deleted file mode 100644 index 7a35c9533..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/HtmlBuffer.pas +++ /dev/null @@ -1,1762 +0,0 @@ -{ -HtmlViewer Version 11.7 -Copyright (c) 2010-2016 by Bernd Gabriel - -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. - -Note that the source modules HTMLGIF1.PAS and DITHERUNIT.PAS -are covered by separate copyright notices located in those modules. -} - -{$I htmlcons.inc} - -unit HtmlBuffer; - -interface - -{Important: Be sure to list LclType after SysUtils and Classes - in order to use LclType's THandle declaration (32 or 64 bits) - rather than THandle in SysUtils and Classes (=System.THandle, - which apparently is always 32 bits).} -uses -{$ifdef LCL} - Classes, SysUtils, - LclIntf, LclType, HtmlMisc, -{$else} - Windows, - Classes, SysUtils, -{$endif} - vcl.Graphics, -{$ifdef UNICODE} - AnsiStrings, -{$endif} - // - HtmlGlobals; - -type - EConversionError = class(Exception); - - TBuffCodePage = LongInt; - TBuffCharSet = SmallInt; // slightly more than a TFontCharset. - - TBuffChar = ThtChar; // the type of a wide char - PBuffChar = PhtChar; - TBuffString = ThtString; // the type of a wide string - TBuffStringList = ThtStringList; // the type of a wide string - - TBuffPointer = record - case Integer of - 0: (BytePtr: PByte;); - 1: (WordPtr: PWord;); - 2: (AnsiChr: PAnsiChar;); - 3: (WideChr: PWideChar;); - end; - - TBuffConverter = class - protected - FPos, FEnd: TBuffPointer; - FCodePage, FInitalCodePage: TBuffCodePage; - function GetNext: Word; - procedure Assign(Source: TBuffConverter); virtual; - public - constructor Create(CurrPtr, EndPtr: TBuffPointer; CodePage, InitalCodePage: TBuffCodePage); virtual; - constructor CreateCopy(Source: TBuffConverter); overload; - - function NextChar: TBuffChar; virtual; - function PeekChar: TBuffChar; - function AsString: TBuffString; virtual; - property CodePage: TBuffCodePage read FCodePage; - end; - TBuffConverterClass = class of TBuffConverter; - - TBuffArray = array of Byte; - TBuffArray4 = array [0..3] of Byte; - - // BG, 11.11.2011: Issue 93: LoadStrings failure - TBufferState = set of ( - bsFixedCodePage // ignore writing to property CodePage. - // Helps to ignore , - // if buffer is an already converted TBuffString. - ); - - // BG, 17.12.2010: helps converting any kind of stream to WideChars. - // - // Although loading files via ThtStringList.LoadFromFile(FileName) produces WideChars, - // these WideChars may not be coded correctly, if the file is not a unicode file. - // For those cases you can apply a CodePage to the TBuffString versions of Convert()/Create(). - // Or you can used the PByte versions with the InitialCodePage parameters and set InitialCodePage to CP_UTF16LE. - // - // Avoid passing such raw ThtStringList.Text to HtmlViewer. - // HtmlViewer assumes correct unicode in ThtString. - // You MUST convert it before passing it to HtmlViewer: HtmlViewer.LoadFromString(TBuffer.Convert(StringList.Text, CodePage)); - // Or you let HtmlViewer load it from file or a TFileStream. - // - TBuffer = class - private - FBuffer: TBuffArray; - FStart: TBuffPointer; - FEnd: TBuffPointer; - FName: TBuffString; - FConverter: TBuffConverter; - FState: TBufferState; - FBomLength: Cardinal; - - function GetCodePage: TBuffCodePage; {$ifdef UseInline} inline; {$endif} - function GetPosition: Integer; {$ifdef UseInline} inline; {$endif} - procedure DetectCodePage; - procedure Reset; - procedure SetCodePage(Value: TBuffCodePage); {$ifdef UseInline} inline; {$endif} - procedure SetCodePages(Value, Initial: TBuffCodePage); - procedure SetPosition(const Value: Integer); {$ifdef UseInline} inline; {$endif} - procedure SetStream(Stream: TStream); {$ifdef UseInline} inline; {$endif} - public - class function Convert(Text: PByte; ByteCount: Integer; CodePage, InitialCodePage: TBuffCodePage): TBuffString; overload; {$ifdef UseInline} inline; {$endif} - class function Convert(Text: PByte; ByteCount: Integer; CodePage: TBuffCodePage): TBuffString; overload; {$ifdef UseInline} inline; {$endif} - class function Convert(const Text: TBuffString; CodePage: TBuffCodePage): TBuffString; overload; {$ifdef UseInline} inline; {$endif} - constructor Create(const Doc: TBuffer); overload; - constructor Create(Stream: TStream; CodePage: TBuffCodePage; Name: TBuffString = ''); overload; - constructor Create(Stream: TStream; Name: TBuffString = ''); overload; - constructor Create(Text: PByte; ByteCount: Integer; CodePage, InitialCodePage: TBuffCodePage; const Name: TBuffString = ''); overload; - constructor Create(Text: PByte; ByteCount: Integer; CodePage: TBuffCodePage; const Name: TBuffString = ''); overload; - constructor Create(const Text: TBuffString; CodePage: TBuffCodePage; const Name: TBuffString = ''); overload; - constructor Create(const Text: TBuffString; const Name: TBuffString = ''; CodePage: TBuffCodePage = CP_UTF16LE); overload; - destructor Destroy; override; - function AsString: TBuffString; {$ifdef UseInline} inline; {$endif} - function GetString(FromIndex, UntilIndex: Integer): TBuffString; - function NextChar: TBuffChar; {$ifdef UseInline} inline; {$endif} - function PeekChar: TBuffChar; {$ifdef UseInline} inline; {$endif} - function Size: Integer; {$ifdef UseInline} inline; {$endif} - procedure Assign(Source: TBuffer); virtual; - procedure AssignTo(Destin: TObject); virtual; - property CodePage: TBuffCodePage read GetCodePage write SetCodePage; - property Name: TBuffString read FName; - property Position: Integer read GetPosition write SetPosition; - property BomLength: Cardinal read FBomLength; - end; - -// BG, 13.10.2012: Code Page Management -// -// You can register your own code page to unicode converters or unregister your own or predefined converters. -// Registering an existing converter again updates it. -// -// As each code page may have any number of aliases there are 2 sets of un-/register methods. -// One to register a code page name to code page number mappings and -// one to register the converter. - -// Add a name of a code page. Code pages can have many names, but each name names one code page only: -procedure RegisterCodePageName(const CodePageName: TBuffString; CodePage: TBuffCodePage); -// Remove a name of a code page: -procedure UnregisterCodePageName(const CodePageName: TBuffString); -// Get code page by name: -function StrToCodePage(const CodePageName: TBuffString): TBuffCodePage; - -// Add a code page to unicode converter. Only one converter per code page is allowed, -// but a converter may handle more than one code page: -procedure RegisterCodePageToUnicodeConverter( - CodePage: TBuffCodePage; Converter: TBuffConverterClass; - const ConverterName: TBuffString = ''; CharSet: TBuffCharSet = UNKNOWN_CHARSET); -// Remove a code page to unicode converter: -procedure UnregisterCodePageToUnicodeConverter(CodePage: TBuffCodePage); -// Get charset of code page: -function CodePageToCharSet(CodePage: TBuffCodePage): TBuffCharSet; - -implementation - -uses - BuffConv; - -type - - TBuffConvInfo = class - private - FName: TBuffString; - FCodePage: TBuffCodePage; - FCharSet: TBuffCharSet; - FConverter: TBuffConverterClass; - public - constructor Create(CodePage: TBuffCodePage; CharSet: TBuffCharSet; Converter: TBuffConverterClass; const Name: TBuffString); - property CharSet: TBuffCharSet read FCharSet; - property CodePage: TBuffCodePage read FCodePage; - property Converter: TBuffConverterClass read FConverter; - property Name: TBuffString read FName; - end; - - TBuffConvInfoList = class(TList) - private - FSorted: Boolean; - function GetItem(Index: Integer): TBuffConvInfo; - protected - procedure Notify(Ptr: Pointer; Action: TListNotification); override; - public - constructor Create; - procedure Add(Item: TBuffConvInfo); - function Find(CodePage: TBuffCodePage): Integer; - procedure Sort; - property Items[Index: Integer]: TBuffConvInfo read GetItem; default; - property Sorted: Boolean read FSorted; - end; - - TBuffCodePageName = class - private - FName: TBuffString; - FCodePage: TBuffCodePage; - public - constructor Create(Name: TBuffString; CodePage: TBuffCodePage); - property CodePage: TBuffCodePage read FCodePage; - property Name: TBuffString read FName; - end; - - TBuffCodePageNameList = class(TBuffStringList) - private - function GetItem(Index: Integer): TBuffCodePageName; - public - constructor Create; - destructor Destroy; override; - procedure Add(Info: TBuffCodePageName); reintroduce; - function IndexOf(const S: TBuffString): Integer; override; - property Items[Index: Integer]: TBuffCodePageName read GetItem; default; - end; - -//-- BG ---------------------------------------------------------- 22.12.2010 -- -var - VFinalizing: Boolean; - VConvertersByCodePage: TBuffConvInfoList; - VCodePagesByName: TBuffCodePageNameList; - -//-- BG ---------------------------------------------------------- 12.10.2012 -- -function GetCodePageNameList: TBuffCodePageNameList; -begin - if (VCodePagesByName = nil) and not VFinalizing then - VCodePagesByName := TBuffCodePageNameList.Create; - Result := VCodePagesByName; -end; - -//-- BG ---------------------------------------------------------- 12.10.2012 -- -procedure RegisterCodePageName(const CodePageName: TBuffString; CodePage: TBuffCodePage); -var - CodePagesByName: TBuffCodePageNameList; -begin - CodePagesByName := GetCodePageNameList; - if CodePagesByName <> nil then - CodePagesByName.Add(TBuffCodePageName.Create(CodePageName, CodePage)); -end; - -//-- BG ---------------------------------------------------------- 12.10.2012 -- -procedure UnregisterCodePageName(const CodePageName: TBuffString); -var - CodePagesByName: TBuffCodePageNameList; - Index: Integer; -begin - CodePagesByName := GetCodePageNameList; - if CodePagesByName <> nil then - begin - Index := -1; - if not CodePagesByName.Find(CodePageName, Index) then - Index := CodePagesByName.IndexOf(CodePageName); - if Index >= 0 then - begin - CodePagesByName[Index].Free; - CodePagesByName.Delete(Index); - end; - end; -end; - -//-- BG ---------------------------------------------------------- 22.12.2010 -- -function StrToCodePageInfo(const CodePageName: TBuffString): TBuffCodePageName; -var - CodePagesByName: TBuffCodePageNameList; - Index: Integer; -begin - CodePagesByName := GetCodePageNameList; - Result := nil; - if CodePagesByName <> nil then - begin - Index := -1; - if not CodePagesByName.Find(CodePageName, Index) then - Index := CodePagesByName.IndexOf(CodePageName); - if Index >= 0 then - Result := CodePagesByName[Index]; - end; -end; - -//-- BG ---------------------------------------------------------- 12.10.2012 -- -function StrToCodePage(const CodePageName: TBuffString): TBuffCodePage; -var - Info: TBuffCodePageName; -begin - Info := StrToCodePageInfo(CodePageName); - if Info <> nil then - Result := Info.CodePage - else - Result := CP_UNKNOWN; -end; - -//-- BG ---------------------------------------------------------- 12.10.2012 -- -function GetConvInfoList: TBuffConvInfoList; -begin - if (VConvertersByCodePage = nil) and not VFinalizing then - VConvertersByCodePage := TBuffConvInfoList.Create; - Result := VConvertersByCodePage; -end; - -//-- BG ---------------------------------------------------------- 12.10.2012 -- -procedure RegisterCodePageToUnicodeConverter( - CodePage: TBuffCodePage; Converter: TBuffConverterClass; - const ConverterName: TBuffString = ''; CharSet: TBuffCharSet = UNKNOWN_CHARSET); -var - Index: Integer; - CodePageInfos: TBuffConvInfoList; - CodePageInfo: TBuffConvInfo; -begin - CodePageInfos := GetConvInfoList; - if CodePageInfos <> nil then - begin - Index := CodePageInfos.Find(CodePage); - if Index >= 0 then - begin - // update existing code page - CodePageInfo := CodePageInfos[Index]; - CodePageInfo.FName := ConverterName; - CodePageInfo.FCharSet := CharSet; - CodePageInfo.FConverter := Converter; - end - else - // Add new code page - CodePageInfos.Add(TBuffConvInfo.Create(CodePage, CharSet, Converter, ConverterName)); - end; -end; - -//-- BG ---------------------------------------------------------- 12.10.2012 -- -procedure UnregisterCodePageToUnicodeConverter(CodePage: TBuffCodePage); -var - Index: Integer; - CodePageInfos: TBuffConvInfoList; -begin - CodePageInfos := GetConvInfoList; - if CodePageInfos <> nil then - begin - Index := CodePageInfos.Find(CodePage); - if Index >= 0 then - CodePageInfos.Delete(Index); - end; -end; - -//-- BG ---------------------------------------------------------- 14.12.2010 -- -function CodePageToCharSet(CodePage: TBuffCodePage): TBuffCharSet; -var - Index: Integer; - CodePageInfos: TBuffConvInfoList; -begin - Result := UNKNOWN_CHARSET; - CodePageInfos := GetConvInfoList; - if CodePageInfos <> nil then - begin - Index := CodePageInfos.Find(CodePage); - if Index >= 0 then - Result := CodePageInfos[Index].CharSet; - end; - - if Result = UNKNOWN_CHARSET then - //raise EConversionError.CreateFmt('Don''t know equivalent char set for code page %d.', [CodePage]); - Result := DEFAULT_CHARSET; -end; - -//-- BG ---------------------------------------------------------- 15.07.2012 -- -function StrNCmpA(Str1, Str2: PAnsiChar; N: Integer): Integer; -var - StrEnd: PAnsiChar; -begin - StrEnd := Str1 + N; - while Str1 < StrEnd do - begin - Result := Ord(Str1^) - Ord(Str2^); - if (Result <> 0) or (Str1^ = #0) then - Exit; - Inc(Str1); - Inc(Str2); - end; - Result := 0; -end; - -//-- BG ---------------------------------------------------------- 15.07.2012 -- -function StrNPosA(Str, SubStr: PAnsiChar; N: Integer): PAnsiChar; -// returns a pointer to the first occurrence of SubStr in the first N chars of Str. -// Finds SubStr only, if the entire SubStr is within the first N chars. -// Example: -// StrNPosA('expression', 'press', 7) finds pointer to 'pression' while -// StrNPosA('expression', 'press', 6) retuns nil, as 'press' is not in the first 6 chars ('expres'). -var - L: Integer; - StrEnd: PAnsiChar; -begin - StrEnd := SubStr; - while StrEnd^ <> #0 do - Inc(StrEnd); - L := StrEnd - SubStr; - if L > 0 then // Make sure substring not null string and SubStr fits into Str at all. - begin - Result := Str; - StrEnd := Str + N - L; - while (Result < StrEnd) and (Result^ <> #0) do - begin - if StrNCmpA(Result, SubStr, L) = 0 then - Exit; - Inc(Result); - end; - end; - Result := nil; -end; - -{ TBuffConvInfo } - -//-- BG ---------------------------------------------------------- 12.10.2012 -- -constructor TBuffConvInfo.Create(CodePage: TBuffCodePage; CharSet: TBuffCharSet; Converter: TBuffConverterClass; const Name: TBuffString); -begin - inherited Create; - FName := Name; - FCodePage := CodePage; - FCharSet := CharSet; - FConverter := Converter; -end; - -{ TBuffConvInfoList } - -function CompareConvInfo(Item1, Item2: Pointer): Integer; -var - Info1: TBuffConvInfo absolute Item1; - Info2: TBuffConvInfo absolute Item2; -begin - Result := Info1.CodePage - Info2.CodePage; -end; - -//-- BG ---------------------------------------------------------- 12.10.2012 -- -procedure TBuffConvInfoList.Add(Item: TBuffConvInfo); -begin - inherited Add(Item); -end; - -//-- BG ---------------------------------------------------------- 12.10.2012 -- -constructor TBuffConvInfoList.Create; -begin - inherited Create; - Add(TBuffConvInfo.Create(CP_UNKNOWN, UNKNOWN_CHARSET, TBuffConvSingleByte, 'Unknown')); - Add(TBuffConvInfo.Create( CP_ACP, DEFAULT_CHARSET, TBuffConvSingleByte, 'Default ANSI CP')); - Add(TBuffConvInfo.Create( CP_OEMCP, OEM_CHARSET, TBuffConvSingleByte, 'Default OEM CP')); - Add(TBuffConvInfo.Create( CP_MACCP, MAC_CHARSET, TBuffConvSingleByte, 'Default MAC CP')); - Add(TBuffConvInfo.Create( 37, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC US-Canada')); - Add(TBuffConvInfo.Create( 437, ANSI_CHARSET, TBuffConvHighMap, 'OEM United States')); - Add(TBuffConvInfo.Create( 500, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC International')); - Add(TBuffConvInfo.Create( 708, ARABIC_CHARSET, TBuffConvHighMap, 'Arabic (ASMO 708)')); - Add(TBuffConvInfo.Create( 709, ARABIC_CHARSET, TBuffConvSingleByte, 'Arabic (ASMO-449+, BCON V4)')); - Add(TBuffConvInfo.Create( 710, ARABIC_CHARSET, TBuffConvSingleByte, 'Arabic - Transparent Arabic')); - Add(TBuffConvInfo.Create( 720, ARABIC_CHARSET, TBuffConvSingleByte, 'Arabic (Transparent ASMO); Arabic (DOS)')); - Add(TBuffConvInfo.Create( 737, GREEK_CHARSET, TBuffConvHighMap, 'OEM Greek (formerly 437G); Greek (DOS)')); - Add(TBuffConvInfo.Create( 775, BALTIC_CHARSET, TBuffConvHighMap, 'OEM Baltic; Baltic (DOS)')); - Add(TBuffConvInfo.Create( 850, ANSI_CHARSET, TBuffConvHighMap, 'OEM Multilingual Latin 1; Western European (DOS)')); - Add(TBuffConvInfo.Create( 852, EASTEUROPE_CHARSET, TBuffConvHighMap, 'OEM Latin 2; Central European (DOS)')); - Add(TBuffConvInfo.Create( 855, RUSSIAN_CHARSET, TBuffConvHighMap, 'OEM Cyrillic (primarily Russian)')); - Add(TBuffConvInfo.Create( 857, TURKISH_CHARSET, TBuffConvHighMap, 'OEM Turkish; Turkish (DOS)')); - Add(TBuffConvInfo.Create( 858, ANSI_CHARSET, TBuffConvSingleByte, 'OEM Multilingual Latin 1 + Euro symbol')); - Add(TBuffConvInfo.Create( 860, ANSI_CHARSET, TBuffConvHighMap, 'OEM Portuguese; Portuguese (DOS)')); - Add(TBuffConvInfo.Create( 861, ANSI_CHARSET, TBuffConvHighMap, 'OEM Icelandic; Icelandic (DOS)')); - Add(TBuffConvInfo.Create( 862, HEBREW_CHARSET, TBuffConvHighMap, 'OEM Hebrew; Hebrew (DOS)')); - Add(TBuffConvInfo.Create( 863, ANSI_CHARSET, TBuffConvHighMap, 'OEM French Canadian; French Canadian (DOS)')); - Add(TBuffConvInfo.Create( 864, ARABIC_CHARSET, TBuffConvHighMap, 'OEM Arabic; Arabic (864)')); - Add(TBuffConvInfo.Create( 865, ANSI_CHARSET, TBuffConvHighMap, 'OEM Nordic; Nordic (DOS)')); - Add(TBuffConvInfo.Create( 866, RUSSIAN_CHARSET, TBuffConvHighMap, 'OEM Russian; Cyrillic (DOS)')); - Add(TBuffConvInfo.Create( 869, GREEK_CHARSET, TBuffConvHighMap, 'OEM Modern Greek; Greek, Modern (DOS)')); - Add(TBuffConvInfo.Create( 870, EASTEUROPE_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2')); - Add(TBuffConvInfo.Create( 874, THAI_CHARSET, TBuffConvHighMap, 'ANSI/OEM Thai (same as 28605, ISO 8859-15); Thai (Windows)')); - Add(TBuffConvInfo.Create( 875, GREEK_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Greek Modern')); - Add(TBuffConvInfo.Create( 922, BALTIC_CHARSET, TBuffConvSingleByte, 'ANSI/OEM Estonian (DOS)')); - Add(TBuffConvInfo.Create( 932, SHIFTJIS_CHARSET, TBuffConvShiftJis932, 'ANSI/OEM Japanese; Japanese (Shift-JIS)')); - Add(TBuffConvInfo.Create( 936, GB2312_CHARSET, TBuffConvIBM936, 'ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312)')); - Add(TBuffConvInfo.Create( 943, SHIFTJIS_CHARSET, TBuffConvShiftJis932, 'ANSI/OEM Japanese (Shift-JIS)')); - Add(TBuffConvInfo.Create( 949, HANGEUL_CHARSET, TBuffConvHangeul949, 'ANSI/OEM Korean (Unified Hangul Code)')); - Add(TBuffConvInfo.Create( 950, CHINESEBIG5_CHARSET, TBuffConvBig5CP950, 'ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5)')); - Add(TBuffConvInfo.Create( 1026, TURKISH_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Turkish (Latin 5)')); - Add(TBuffConvInfo.Create( 1047, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Latin 1/Open System')); - Add(TBuffConvInfo.Create( 1140, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro)')); - Add(TBuffConvInfo.Create( 1141, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Germany (20273 + Euro symbol); IBM EBCDIC (Germany-Euro)')); - Add(TBuffConvInfo.Create( 1142, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Denmark-Norway (20277 + Euro symbol); IBM EBCDIC (Denmark-Norway-Euro)')); - Add(TBuffConvInfo.Create( 1143, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Finland-Sweden (20278 + Euro symbol); IBM EBCDIC (Finland-Sweden-Euro)')); - Add(TBuffConvInfo.Create( 1144, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Italy (20280 + Euro symbol); IBM EBCDIC (Italy-Euro)')); - Add(TBuffConvInfo.Create( 1145, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Latin America-Spain (20284 + Euro symbol); IBM EBCDIC (Spain-Euro)')); - Add(TBuffConvInfo.Create( 1146, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC United Kingdom (20285 + Euro symbol); IBM EBCDIC (UK-Euro)')); - Add(TBuffConvInfo.Create( 1147, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC France (20297 + Euro symbol); IBM EBCDIC (France-Euro)')); - Add(TBuffConvInfo.Create( 1148, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC International (500 + Euro symbol); IBM EBCDIC (International-Euro)')); - Add(TBuffConvInfo.Create( 1149, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Icelandic (20871 + Euro symbol); IBM EBCDIC (Icelandic-Euro)')); - Add(TBuffConvInfo.Create( 1200, DEFAULT_CHARSET, TBuffConverter, 'Unicode UTF-16, little endian byte order (BMP of ISO 10646); available only to managed applications')); - Add(TBuffConvInfo.Create( 1201, DEFAULT_CHARSET, TBuffConverter, 'Unicode UTF-16, big endian byte order; available only to managed applications')); - Add(TBuffConvInfo.Create( 1250, EASTEUROPE_CHARSET, TBuffConvHighMap, 'ANSI Central European; Central European (Windows)')); - Add(TBuffConvInfo.Create( 1251, RUSSIAN_CHARSET, TBuffConvHighMap, 'ANSI Cyrillic; Cyrillic (Windows)')); - Add(TBuffConvInfo.Create( 1252, ANSI_CHARSET, TBuffConvHighMap, 'ANSI Latin 1; Western European (Windows)')); - Add(TBuffConvInfo.Create( 1253, GREEK_CHARSET, TBuffConvHighMap, 'ANSI Greek; Greek (Windows)')); - Add(TBuffConvInfo.Create( 1254, TURKISH_CHARSET, TBuffConvHighMap, 'ANSI Turkish; Turkish (Windows)')); - Add(TBuffConvInfo.Create( 1255, HEBREW_CHARSET, TBuffConvHighMap, 'ANSI Hebrew; Hebrew (Windows)')); - Add(TBuffConvInfo.Create( 1256, ARABIC_CHARSET, TBuffConvHighMap, 'ANSI Arabic; Arabic (Windows)')); - Add(TBuffConvInfo.Create( 1257, BALTIC_CHARSET, TBuffConvHighMap, 'ANSI Baltic; Baltic (Windows)')); - Add(TBuffConvInfo.Create( 1258, VIETNAMESE_CHARSET, TBuffConvHighMap, 'ANSI/OEM Vietnamese; Vietnamese (Windows)')); - Add(TBuffConvInfo.Create( 1361, JOHAB_CHARSET, TBuffConvSingleByte, 'Korean (Johab)')); - Add(TBuffConvInfo.Create( 10000, ANSI_CHARSET, TBuffConvHighMap, 'MAC Roman; Western European (Mac)')); - Add(TBuffConvInfo.Create( 10001, SHIFTJIS_CHARSET, TBuffConvSingleByte, 'Japanese (Mac)')); - Add(TBuffConvInfo.Create( 10002, CHINESEBIG5_CHARSET, TBuffConvSingleByte, 'MAC Traditional Chinese (Big5); Chinese Traditional (Mac)')); - Add(TBuffConvInfo.Create( 10003, HANGEUL_CHARSET, TBuffConvSingleByte, 'Korean (Mac)')); - Add(TBuffConvInfo.Create( 10004, ARABIC_CHARSET, TBuffConvHighMap, 'Arabic (Mac)')); - Add(TBuffConvInfo.Create( 10005, HEBREW_CHARSET, TBuffConvHighMap, 'Hebrew (Mac)')); - Add(TBuffConvInfo.Create( 10006, GREEK_CHARSET, TBuffConvHighMap, 'Greek (Mac)')); - Add(TBuffConvInfo.Create( 10007, RUSSIAN_CHARSET, TBuffConvHighMap, 'Cyrillic (Mac)')); - Add(TBuffConvInfo.Create( 10008, GB2312_CHARSET, TBuffConvSingleByte, 'MAC Simplified Chinese (GB 2312); Chinese Simplified (Mac)')); - Add(TBuffConvInfo.Create( 10010, EASTEUROPE_CHARSET, TBuffConvHighMap, 'Romanian (Mac)')); - Add(TBuffConvInfo.Create( 10017, RUSSIAN_CHARSET, TBuffConvHighMap, 'Ukrainian (Mac)')); - Add(TBuffConvInfo.Create( 10021, THAI_CHARSET, TBuffConvHighMap, 'Thai (Mac)')); - Add(TBuffConvInfo.Create( 10029, EASTEUROPE_CHARSET, TBuffConvHighMap, 'MAC Latin 2; Central European (Mac)')); - Add(TBuffConvInfo.Create( 10079, ANSI_CHARSET, TBuffConvHighMap, 'Icelandic (Mac)')); - Add(TBuffConvInfo.Create( 10081, TURKISH_CHARSET, TBuffConvHighMap, 'Turkish (Mac)')); - Add(TBuffConvInfo.Create( 10082, EASTEUROPE_CHARSET, TBuffConvHighMap, 'Croatian (Mac)')); - Add(TBuffConvInfo.Create( 12000, DEFAULT_CHARSET, TBuffConvSingleByte, 'Unicode UTF-32, little endian byte order; available only to managed applications')); - Add(TBuffConvInfo.Create( 12001, DEFAULT_CHARSET, TBuffConvSingleByte, 'Unicode UTF-32, big endian byte order; available only to managed applications')); - Add(TBuffConvInfo.Create( 20000, CHINESEBIG5_CHARSET, TBuffConvSingleByte, 'CNS Taiwan; Chinese Traditional (CNS)')); - Add(TBuffConvInfo.Create( 20001, CHINESEBIG5_CHARSET, TBuffConvSingleByte, 'TCA Taiwan')); - Add(TBuffConvInfo.Create( 20002, CHINESEBIG5_CHARSET, TBuffConvSingleByte, 'Eten Taiwan; Chinese Traditional (Eten)')); - Add(TBuffConvInfo.Create( 20003, CHINESEBIG5_CHARSET, TBuffConvSingleByte, 'IBM5550 Taiwan')); - Add(TBuffConvInfo.Create( 20004, CHINESEBIG5_CHARSET, TBuffConvSingleByte, 'TeleText Taiwan')); - Add(TBuffConvInfo.Create( 20005, CHINESEBIG5_CHARSET, TBuffConvSingleByte, 'Wang Taiwan')); - Add(TBuffConvInfo.Create( 20105, ANSI_CHARSET, TBuffConvSingleByte, 'IA5 (IRV International Alphabet No. 5, 7-bit); Western European (IA5)')); - Add(TBuffConvInfo.Create( 20106, ANSI_CHARSET, TBuffConvSingleByte, 'IA5 German (7-bit)')); - Add(TBuffConvInfo.Create( 20107, ANSI_CHARSET, TBuffConvSingleByte, 'IA5 Swedish (7-bit)')); - Add(TBuffConvInfo.Create( 20108, ANSI_CHARSET, TBuffConvSingleByte, 'IA5 Norwegian (7-bit)')); - Add(TBuffConvInfo.Create( 20127, ANSI_CHARSET, TBuffConvSingleByte, 'US-ASCII (7-bit)')); - Add(TBuffConvInfo.Create( 20261, ANSI_CHARSET, TBuffConvSingleByte, 'T.61')); - Add(TBuffConvInfo.Create( 20269, ANSI_CHARSET, TBuffConvSingleByte, 'ISO 6937 Non-Spacing Accent')); - Add(TBuffConvInfo.Create( 20273, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Germany')); - Add(TBuffConvInfo.Create( 20277, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Denmark-Norway')); - Add(TBuffConvInfo.Create( 20278, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Finland-Sweden')); - Add(TBuffConvInfo.Create( 20280, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Italy')); - Add(TBuffConvInfo.Create( 20284, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Latin America-Spain')); - Add(TBuffConvInfo.Create( 20285, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC United Kingdom')); - Add(TBuffConvInfo.Create( 20290, SHIFTJIS_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Japanese Katakana Extended')); - Add(TBuffConvInfo.Create( 20297, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC France')); - Add(TBuffConvInfo.Create( 20420, ARABIC_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Arabic')); - Add(TBuffConvInfo.Create( 20423, GREEK_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Greek')); - Add(TBuffConvInfo.Create( 20424, HEBREW_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Hebrew')); - Add(TBuffConvInfo.Create( 20833, HANGEUL_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Korean Extended')); - Add(TBuffConvInfo.Create( 20838, THAI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Thai')); - Add(TBuffConvInfo.Create( 20866, RUSSIAN_CHARSET, TBuffConvHighMap, 'Russian (KOI8-R); Cyrillic (KOI8-R)')); - Add(TBuffConvInfo.Create( 20871, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Icelandic')); - Add(TBuffConvInfo.Create( 20880, RUSSIAN_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Cyrillic Russian')); - Add(TBuffConvInfo.Create( 20905, TURKISH_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Turkish')); - Add(TBuffConvInfo.Create( 20924, ANSI_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Latin 1/Open System (1047 + Euro symbol)')); - Add(TBuffConvInfo.Create( 20932, SHIFTJIS_CHARSET, TBuffConvSingleByte, 'Japanese (JIS 0208-1990 and 0121-1990)')); - Add(TBuffConvInfo.Create( 20936, GB2312_CHARSET, TBuffConvSingleByte, 'Simplified Chinese (GB2312); Chinese Simplified (GB2312-80)')); - Add(TBuffConvInfo.Create( 20949, HANGEUL_CHARSET, TBuffConvSingleByte, 'Korean Wansung')); - Add(TBuffConvInfo.Create( 21025, RUSSIAN_CHARSET, TBuffConvSingleByte, 'IBM EBCDIC Cyrillic Serbian-Bulgarian')); - Add(TBuffConvInfo.Create( 21027, UNKNOWN_CHARSET, TBuffConvSingleByte, '(deprecated)')); - Add(TBuffConvInfo.Create( 21866, RUSSIAN_CHARSET, TBuffConvSingleByte, 'Ukrainian (KOI8-U); Cyrillic (KOI8-U)')); - Add(TBuffConvInfo.Create( 28591, ANSI_CHARSET, TBuffConverter, 'ISO 8859-1 Latin 1; Western European (ISO)')); - Add(TBuffConvInfo.Create( 28592, EASTEUROPE_CHARSET, TBuffConvIsoMap, 'ISO 8859-2 Latin 2; Central European; Central European (ISO)')); - Add(TBuffConvInfo.Create( 28593, ANSI_CHARSET, TBuffConvIsoMap, 'ISO 8859-3 Latin 3; Southern European')); - Add(TBuffConvInfo.Create( 28594, ANSI_CHARSET, TBuffConvIsoMap, 'ISO 8859-4 Latin 4; Northern European')); - Add(TBuffConvInfo.Create( 28595, RUSSIAN_CHARSET, TBuffConvSingleByte, 'ISO 8859-5 Cyrillic')); - Add(TBuffConvInfo.Create( 28596, ARABIC_CHARSET, TBuffConvSingleByte, 'ISO 8859-6 Arabic')); - Add(TBuffConvInfo.Create( 28597, GREEK_CHARSET, TBuffConvSingleByte, 'ISO 8859-7 Greek')); - Add(TBuffConvInfo.Create( 28598, HEBREW_CHARSET, TBuffConvSingleByte, 'ISO 8859-8 Hebrew; Hebrew (ISO-Visual)')); - Add(TBuffConvInfo.Create( 28599, TURKISH_CHARSET, TBuffConvSingleByte, 'ISO 8859-9 Turkish')); - Add(TBuffConvInfo.Create( 28600, ANSI_CHARSET, TBuffConvIsoMap, 'ISO 8859-10 Latin 6; Nordic')); - Add(TBuffConvInfo.Create( 28601, THAI_CHARSET, TBuffConvSingleByte, 'ISO 8859-11 Thai')); - Add(TBuffConvInfo.Create( 28603, BALTIC_CHARSET, TBuffConvIsoMap, 'ISO 8859-13 Latin 7; Baltic')); - Add(TBuffConvInfo.Create( 28604, ANSI_CHARSET, TBuffConvIsoMap, 'ISO 8859-14 Latin 8; Celtic')); - Add(TBuffConvInfo.Create( 28605, ANSI_CHARSET, TBuffConvSingleByte, 'ISO 8859-15 Latin 9; Western European')); - Add(TBuffConvInfo.Create( 28606, ANSI_CHARSET, TBuffConvIsoMap, 'ISO 8859-16 Latin 10; South Eastern European')); - Add(TBuffConvInfo.Create( 29001, ANSI_CHARSET, TBuffConvSingleByteMap, 'Europa 3')); - Add(TBuffConvInfo.Create( 38598, HEBREW_CHARSET, TBuffConvSingleByte, 'ISO 8859-8 Hebrew; Hebrew (ISO-Logical)')); - Add(TBuffConvInfo.Create( 50220, SHIFTJIS_CHARSET, TBuffConvISO2022JP, 'ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS)')); - Add(TBuffConvInfo.Create( 50221, SHIFTJIS_CHARSET, TBuffConvISO2022JP, 'ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow 1 byte Kana)')); - Add(TBuffConvInfo.Create( 50222, SHIFTJIS_CHARSET, TBuffConvISO2022JP, 'ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte Kana - SO/SI)')); - Add(TBuffConvInfo.Create( 50225, HANGEUL_CHARSET, TBuffConvISO2022KR, 'ISO 2022 Korean')); - Add(TBuffConvInfo.Create( 50227, GB2312_CHARSET, TBuffConvISO2022CN, 'ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022)')); - Add(TBuffConvInfo.Create( 50229, CHINESEBIG5_CHARSET, TBuffConvSingleByte, 'ISO 2022 Traditional Chinese')); - Add(TBuffConvInfo.Create( 50930, SHIFTJIS_CHARSET, TBuffConvSingleByte, 'EBCDIC Japanese (Katakana) Extended')); - Add(TBuffConvInfo.Create( 50931, ANSI_CHARSET, TBuffConvSingleByte, 'EBCDIC US-Canada and Japanese')); - Add(TBuffConvInfo.Create( 50933, HANGEUL_CHARSET, TBuffConvSingleByte, 'EBCDIC Korean Extended and Korean')); - Add(TBuffConvInfo.Create( 50935, GB2312_CHARSET, TBuffConvSingleByte, 'EBCDIC Simplified Chinese Extended and Simplified Chinese')); - Add(TBuffConvInfo.Create( 50936, GB2312_CHARSET, TBuffConvSingleByte, 'EBCDIC Simplified Chinese')); - Add(TBuffConvInfo.Create( 50937, CHINESEBIG5_CHARSET, TBuffConvSingleByte, 'EBCDIC US-Canada and Traditional Chinese')); - Add(TBuffConvInfo.Create( 50939, SHIFTJIS_CHARSET, TBuffConvSingleByte, 'EBCDIC Japanese (Latin) Extended and Japanese')); - Add(TBuffConvInfo.Create( 51932, SHIFTJIS_CHARSET, TBuffConvEUC_JP, 'EUC Japanese')); - Add(TBuffConvInfo.Create( 51936, GB2312_CHARSET, TBuffConvDoubleByte, 'EUC Simplified Chinese; Chinese Simplified (EUC)')); - Add(TBuffConvInfo.Create( 51949, HANGEUL_CHARSET, TBuffConvDoubleByte, 'EUC Korean')); - Add(TBuffConvInfo.Create( 51950, CHINESEBIG5_CHARSET, TBuffConvBig5CP950, 'EUC Traditional Chinese')); - Add(TBuffConvInfo.Create( 52936, GB2312_CHARSET, TBuffConvSingleByte, 'HZ-GB2312 Simplified Chinese; Chinese Simplified (HZ)')); - Add(TBuffConvInfo.Create( 54936, GB2312_CHARSET, TBuffConvGB18030, 'Windows XP and later: GB18030 Simplified Chinese (4 byte); Chinese Simplified (GB18030)')); - Add(TBuffConvInfo.Create( 57002, UNKNOWN_CHARSET, TBuffConvSingleByte, 'ISCII Devanagari')); - Add(TBuffConvInfo.Create( 57003, UNKNOWN_CHARSET, TBuffConvSingleByte, 'ISCII Bengali')); - Add(TBuffConvInfo.Create( 57004, UNKNOWN_CHARSET, TBuffConvSingleByte, 'ISCII Tamil')); - Add(TBuffConvInfo.Create( 57005, UNKNOWN_CHARSET, TBuffConvSingleByte, 'ISCII Telugu')); - Add(TBuffConvInfo.Create( 57006, UNKNOWN_CHARSET, TBuffConvSingleByte, 'ISCII Assamese')); - Add(TBuffConvInfo.Create( 57007, UNKNOWN_CHARSET, TBuffConvSingleByte, 'ISCII Oriya')); - Add(TBuffConvInfo.Create( 57008, UNKNOWN_CHARSET, TBuffConvSingleByte, 'ISCII Kannada')); - Add(TBuffConvInfo.Create( 57009, UNKNOWN_CHARSET, TBuffConvSingleByte, 'ISCII Malayalam')); - Add(TBuffConvInfo.Create( 57010, UNKNOWN_CHARSET, TBuffConvSingleByte, 'ISCII Gujarati')); - Add(TBuffConvInfo.Create( 57011, UNKNOWN_CHARSET, TBuffConvSingleByte, 'ISCII Punjabi')); - Add(TBuffConvInfo.Create( 65000, DEFAULT_CHARSET, TBuffConvUTF7, 'Unicode (UTF-7)')); - Add(TBuffConvInfo.Create( 65001, DEFAULT_CHARSET, TBuffConvUTF8, 'Unicode (UTF-8)')); -end; - -//-- BG ---------------------------------------------------------- 12.10.2012 -- -function TBuffConvInfoList.Find(CodePage: TBuffCodePage): Integer; -var - Low, Index: Integer; -begin - Result := Count; - if not Sorted then - Sort; - Low := 0; - while Low < Result do - begin - Index := (Low + Result) shr 1; - if Items[Index].CodePage < CodePage then - Low := Index + 1 - else - Result := Index; - end; - if Items[Result].CodePage <> CodePage then - Result := -1; -end; - -//-- BG ---------------------------------------------------------- 12.10.2012 -- -function TBuffConvInfoList.GetItem(Index: Integer): TBuffConvInfo; -begin - Result := Get(Index); -end; - -//-- BG ---------------------------------------------------------- 12.10.2012 -- -procedure TBuffConvInfoList.Notify(Ptr: Pointer; Action: TListNotification); -begin - inherited; - case Action of - lnAdded: FSorted := False; - lnDeleted: TBuffConvInfo(Ptr).Free; - end; -end; - -//-- BG ---------------------------------------------------------- 12.10.2012 -- -procedure TBuffConvInfoList.Sort; -begin - inherited Sort(CompareConvInfo); - FSorted := True; -end; - -{ TBuffCodePageName } - -//-- BG ---------------------------------------------------------- 22.12.2010 -- -constructor TBuffCodePageName.Create(Name: TBuffString; CodePage: TBuffCodePage); -begin - inherited Create; - FName := Name; - FCodePage := CodePage; -end; - -{ TBuffCodePageNameList } - -//-- BG ---------------------------------------------------------- 22.12.2010 -- -procedure TBuffCodePageNameList.Add(Info: TBuffCodePageName); -begin - AddObject(Info.FName, Info); -end; - -//-- BG ---------------------------------------------------------- 22.12.2010 -- -constructor TBuffCodePageNameList.Create; -// The official CharSet definitions: -// http://www.iana.org/assignments/character-sets -// http://www.iana.org/assignments/ianacharset-mib -begin - inherited Create; - BeginUpdate; - try - Add(TBuffCodePageName.Create('708', 708)); //708 - Add(TBuffCodePageName.Create('asmo-708', 708)); //708 - - Add(TBuffCodePageName.Create('737', 737)); //737 - Add(TBuffCodePageName.Create('ibm737', 737)); //737 - Add(TBuffCodePageName.Create('cp437', 737)); //737 - Add(TBuffCodePageName.Create('cspc8codepage437', 737)); //737 - - Add(TBuffCodePageName.Create('775', 775)); //775 - Add(TBuffCodePageName.Create('ibm775', 775)); //775 - Add(TBuffCodePageName.Create('cp775', 775)); //775 - Add(TBuffCodePageName.Create('cspc775baltic', 775)); //775 - - Add(TBuffCodePageName.Create('850', 850)); //850 - Add(TBuffCodePageName.Create('ibm850', 850)); //850 - Add(TBuffCodePageName.Create('cp850', 850)); //850 - Add(TBuffCodePageName.Create('cspc850multilingual', 850)); //850 - - Add(TBuffCodePageName.Create('852', 852)); //852 - Add(TBuffCodePageName.Create('ibm852', 852)); //852 - Add(TBuffCodePageName.Create('cp852', 852)); //852 - Add(TBuffCodePageName.Create('cspcp852', 852)); //852 - - Add(TBuffCodePageName.Create('855', 855)); //855 - Add(TBuffCodePageName.Create('ibm855', 855)); //855 - Add(TBuffCodePageName.Create('cp855', 855)); //855 - Add(TBuffCodePageName.Create('csibm855', 855)); //855 - - Add(TBuffCodePageName.Create('857', 857)); //857 - Add(TBuffCodePageName.Create('ibm857', 857)); //857 - Add(TBuffCodePageName.Create('cp857', 857)); //857 - Add(TBuffCodePageName.Create('csibm857', 857)); //857 - - Add(TBuffCodePageName.Create('858', 858)); //858 - Add(TBuffCodePageName.Create('ibm00858', 858)); //858 - Add(TBuffCodePageName.Create('cp858', 858)); //858 - Add(TBuffCodePageName.Create('ccsid00858', 858)); //858 - Add(TBuffCodePageName.Create('cp00858', 858)); //858 - Add(TBuffCodePageName.Create('pc-multilingual-850+euro', 858)); //858 - - Add(TBuffCodePageName.Create('860', 860)); //860 - Add(TBuffCodePageName.Create('ibm860', 860)); //860 - Add(TBuffCodePageName.Create('cp860', 860)); //860 - Add(TBuffCodePageName.Create('csibm860', 860)); //860 - - Add(TBuffCodePageName.Create('861', 861)); //861 - Add(TBuffCodePageName.Create('ibm861', 861)); //861 - Add(TBuffCodePageName.Create('cp861', 861)); //861 - Add(TBuffCodePageName.Create('csibm861', 861)); //861 - Add(TBuffCodePageName.Create('cp-is', 861)); //861 - - Add(TBuffCodePageName.Create('862', 862)); //862 - Add(TBuffCodePageName.Create('ibm862', 862)); //862 - Add(TBuffCodePageName.Create('cp862', 862)); //862 - Add(TBuffCodePageName.Create('cspc862latinhebrew', 862)); //862 - - Add(TBuffCodePageName.Create('863', 863)); //863 - Add(TBuffCodePageName.Create('ibm863', 863)); //863 - Add(TBuffCodePageName.Create('cp863', 863)); //863 - Add(TBuffCodePageName.Create('csibm863', 863)); //863 - - Add(TBuffCodePageName.Create('864', 864)); //864 - Add(TBuffCodePageName.Create('ibm864', 864)); //864 - Add(TBuffCodePageName.Create('cp864', 864)); //864 - Add(TBuffCodePageName.Create('csibm864', 864)); //864 - - Add(TBuffCodePageName.Create('865', 865)); //865 - Add(TBuffCodePageName.Create('ibm865', 865)); //865 - Add(TBuffCodePageName.Create('cp865', 865)); //865 - Add(TBuffCodePageName.Create('csibm865', 865)); //865 - - Add(TBuffCodePageName.Create('866', 866)); //866 - Add(TBuffCodePageName.Create('ibm866', 866)); //866 - Add(TBuffCodePageName.Create('cp866', 866)); //866 - Add(TBuffCodePageName.Create('csibm866', 866)); //866 - - Add(TBuffCodePageName.Create('869', 869)); //869 - Add(TBuffCodePageName.Create('ibm869', 869)); //869 - Add(TBuffCodePageName.Create('cp869', 869)); //869 - Add(TBuffCodePageName.Create('cp-gr', 869)); //869 - Add(TBuffCodePageName.Create('csibm869', 869)); //869 - - Add(TBuffCodePageName.Create('874', 874)); //874 - Add(TBuffCodePageName.Create('windows-874', 874)); //874 - Add(TBuffCodePageName.Create('dos-874', 874)); //874 - Add(TBuffCodePageName.Create('cp874', 874)); //874 - Add(TBuffCodePageName.Create('thai', 874)); //874 - Add(TBuffCodePageName.Create('tis-620', 874)); //874 - Add(TBuffCodePageName.Create('tis620', 874)); //874 - - Add(TBuffCodePageName.Create('922', 922)); //922 - Add(TBuffCodePageName.Create('cp922', 922)); //922 - - Add(TBuffCodePageName.Create('932', 932)); //932 - Add(TBuffCodePageName.Create('ms_kanji', 932)); //932 - Add(TBuffCodePageName.Create('csshiftjis', 932)); //932 - Add(TBuffCodePageName.Create('cswindows31j', 932)); //932 - Add(TBuffCodePageName.Create('shift-jis', 932)); //932 - Add(TBuffCodePageName.Create('shift_jis', 932)); //932 - Add(TBuffCodePageName.Create('shiftjis', 932)); //932 - Add(TBuffCodePageName.Create('x-ms-cp932', 932)); //932 - Add(TBuffCodePageName.Create('ms932', 932)); //932 - Add(TBuffCodePageName.Create('cp932', 932)); //932 - Add(TBuffCodePageName.Create('x-sjis', 932)); //932 - - Add(TBuffCodePageName.Create('936', 936)); //936 - Add(TBuffCodePageName.Create('gbk', 936)); //936 - Add(TBuffCodePageName.Create('cp936', 936)); //936 - Add(TBuffCodePageName.Create('ms936', 936)); //936 - Add(TBuffCodePageName.Create('windows-936', 936)); //936 - Add(TBuffCodePageName.Create('chinese', 936)); //936 - - Add(TBuffCodePageName.Create('943', 943)); //943 - Add(TBuffCodePageName.Create('cp943', 943)); //943 - - Add(TBuffCodePageName.Create('949', 949)); //949 - Add(TBuffCodePageName.Create('cp949', 949)); //949 - Add(TBuffCodePageName.Create('unc', 949)); //949 - Add(TBuffCodePageName.Create('ks_c_5601-1987', 949)); //949 - Add(TBuffCodePageName.Create('iso-ir-149', 949)); //949 - Add(TBuffCodePageName.Create('ks_c_5601-1989', 949)); //949 - Add(TBuffCodePageName.Create('ksc_5601', 949)); //949 - Add(TBuffCodePageName.Create('ksc5601', 949)); //949 - Add(TBuffCodePageName.Create('ks_c_5601', 949)); //949 - Add(TBuffCodePageName.Create('korean', 949)); //949 - Add(TBuffCodePageName.Create('csksc56011987', 949)); //949 - Add(TBuffCodePageName.Create('5601', 949)); //949 - Add(TBuffCodePageName.Create('hangeul', 949)); //949 - - Add(TBuffCodePageName.Create('950', 950)); //950 - Add(TBuffCodePageName.Create('cp950', 950)); //950 - Add(TBuffCodePageName.Create('big5', 950)); //950 - Add(TBuffCodePageName.Create('big-5', 950)); //950 - Add(TBuffCodePageName.Create('csbig5', 950)); //950 - Add(TBuffCodePageName.Create('cn-big5', 950)); //950 - Add(TBuffCodePageName.Create('x-x-big5', 950)); //950 - Add(TBuffCodePageName.Create('ms950', 950)); //950 - Add(TBuffCodePageName.Create('big5-hkscs', 950)); //950 - Add(TBuffCodePageName.Create('big-five', 950)); //950 - Add(TBuffCodePageName.Create('bigfive', 950)); //950 - - Add(TBuffCodePageName.Create('utf-16le', 1200)); //1200 - Add(TBuffCodePageName.Create('utf16le', 1200)); //1200 - Add(TBuffCodePageName.Create('unicode', 1200)); //1200 - Add(TBuffCodePageName.Create('utf-16', 1200)); //1200 - - Add(TBuffCodePageName.Create('utf-16be', 1201)); //1201 - Add(TBuffCodePageName.Create('utf16be', 1201)); //1201 - Add(TBuffCodePageName.Create('unicodefffe', 1201)); //1201 - - Add(TBuffCodePageName.Create('1250', 1250)); //1250 - Add(TBuffCodePageName.Create('x-cp1250', 1250)); //1250 - Add(TBuffCodePageName.Create('cp-1250', 1250)); //1250 - Add(TBuffCodePageName.Create('cp1250', 1250)); //1250 - Add(TBuffCodePageName.Create('ms-ee', 1250)); //1250 - Add(TBuffCodePageName.Create('windows-1250', 1250)); //1250 - Add(TBuffCodePageName.Create('easteurope', 1250)); //1250 - - Add(TBuffCodePageName.Create('1251', 1251)); //1251 - Add(TBuffCodePageName.Create('x-cp1251', 1251)); //1251 - Add(TBuffCodePageName.Create('cp-1251', 1251)); //1251 - Add(TBuffCodePageName.Create('cp1251', 1251)); //1251 - Add(TBuffCodePageName.Create('ms-cyr', 1251)); //1251 - Add(TBuffCodePageName.Create('ms-cyrl', 1251)); //1251 - Add(TBuffCodePageName.Create('win-1251', 1251)); //1251 - Add(TBuffCodePageName.Create('win1251', 1251)); //1251 - Add(TBuffCodePageName.Create('windows-1251', 1251)); //1251 - Add(TBuffCodePageName.Create('russian', 1251)); //1251 - - Add(TBuffCodePageName.Create('1252', 1252)); //1252 - Add(TBuffCodePageName.Create('windows-1252', 1252)); //1252 - Add(TBuffCodePageName.Create('cp1252', 1252)); //1252 - Add(TBuffCodePageName.Create('cp-1252', 1252)); //1252 - Add(TBuffCodePageName.Create('x-ansi', 1252)); //1252 - Add(TBuffCodePageName.Create('ms-ansi', 1252)); //1252 - Add(TBuffCodePageName.Create('ansi', 1252)); //1252 - - Add(TBuffCodePageName.Create('1253', 1253)); //1253 - Add(TBuffCodePageName.Create('windows-1253', 1253)); //1253 - Add(TBuffCodePageName.Create('cp-1253', 1253)); //1253 - Add(TBuffCodePageName.Create('cp1253', 1253)); //1253 - Add(TBuffCodePageName.Create('ms-greek', 1253)); //1253 - - Add(TBuffCodePageName.Create('1254', 1254)); //1254 - Add(TBuffCodePageName.Create('windows-1254', 1254)); //1254 - Add(TBuffCodePageName.Create('cp-1254', 1254)); //1254 - Add(TBuffCodePageName.Create('cp1254', 1254)); //1254 - Add(TBuffCodePageName.Create('ms-turk', 1254)); //1254 - Add(TBuffCodePageName.Create('turkish', 1254)); //1254 - - Add(TBuffCodePageName.Create('1255', 1255)); //1255 - Add(TBuffCodePageName.Create('windows-1255', 1255)); //1255 - Add(TBuffCodePageName.Create('cp-1255', 1255)); //1255 - Add(TBuffCodePageName.Create('cp1255', 1255)); //1255 - Add(TBuffCodePageName.Create('ms-hebr', 1255)); //1255 - - Add(TBuffCodePageName.Create('1256', 1256)); //1256 - Add(TBuffCodePageName.Create('windows-1256', 1256)); //1256 - Add(TBuffCodePageName.Create('cp1256', 1256)); //1256 - Add(TBuffCodePageName.Create('cp-1256', 1256)); //1256 - Add(TBuffCodePageName.Create('ms-arab', 1256)); //1256 - - Add(TBuffCodePageName.Create('1257', 1257)); //1257 - Add(TBuffCodePageName.Create('windows-1257', 1257)); //1257 - Add(TBuffCodePageName.Create('cp-1257', 1257)); //1257 - Add(TBuffCodePageName.Create('cp1257', 1257)); //1257 - Add(TBuffCodePageName.Create('winbaltrim', 1257)); //1257 - - Add(TBuffCodePageName.Create('1258', 1258)); //1258 - Add(TBuffCodePageName.Create('windows-1258', 1258)); //1258 - Add(TBuffCodePageName.Create('cp-1258', 1258)); //1258 - Add(TBuffCodePageName.Create('cp1258', 1258)); //1258 - Add(TBuffCodePageName.Create('vietnamese', 1258)); //1258 - - Add(TBuffCodePageName.Create('johab', 1361)); //1361 - Add(TBuffCodePageName.Create('cp1361', 1361)); //1361 - - Add(TBuffCodePageName.Create('macintosh', 10000)); //10000 - Add(TBuffCodePageName.Create('csmacintosh', 10000)); //10000 - Add(TBuffCodePageName.Create('mac', 10000)); //10000 - Add(TBuffCodePageName.Create('macroman', 10000)); //10000 - - Add(TBuffCodePageName.Create('x-mac-arabic', 10004)); //10004 - - Add(TBuffCodePageName.Create('x-mac-hebrew', 10005)); //10005 - - Add(TBuffCodePageName.Create('x-mac-greek', 10006)); //10006 - - Add(TBuffCodePageName.Create('x-mac-cyrillic', 10007)); //10007 - Add(TBuffCodePageName.Create('maccyrillic', 10007)); //10007 - - Add(TBuffCodePageName.Create('x-mac-romanian', 10010)); //10010 - - Add(TBuffCodePageName.Create('x-mac-ukrainian', 10017)); //10017 - - Add(TBuffCodePageName.Create('x-mac-thai', 10021)); //10021 - - Add(TBuffCodePageName.Create('x-mac-ce', 10029)); //10029 - Add(TBuffCodePageName.Create('cmac', 10029)); //10029 - Add(TBuffCodePageName.Create('macce', 10029)); //10029 - Add(TBuffCodePageName.Create('maccentraleurope', 10029)); //10029 - - Add(TBuffCodePageName.Create('x-mac-icelandic', 10079)); //10079 - - Add(TBuffCodePageName.Create('x-mac-turkish', 10081)); //10081 - - Add(TBuffCodePageName.Create('x-mac-croatian', 10082)); //10082 - - Add(TBuffCodePageName.Create('us-ascii', 20127)); //20127 - Add(TBuffCodePageName.Create('ansi_x3.4-1968', 20127)); //20127 - Add(TBuffCodePageName.Create('iso-ir-6', 20127)); //20127 - Add(TBuffCodePageName.Create('ansi_x3.4-1986', 20127)); //20127 - Add(TBuffCodePageName.Create('iso_646.irv:1991', 20127)); //20127 - Add(TBuffCodePageName.Create('ascii', 20127)); //20127 - Add(TBuffCodePageName.Create('iso646-us', 20127)); //20127 - Add(TBuffCodePageName.Create('us', 20127)); //20127 - Add(TBuffCodePageName.Create('ibm367', 20127)); //20127 - Add(TBuffCodePageName.Create('cp367', 20127)); //20127 - Add(TBuffCodePageName.Create('csascii', 20127)); //20127 - Add(TBuffCodePageName.Create('iso-ir-6us', 20127)); //20127 - - Add(TBuffCodePageName.Create('koi8-r', 20866)); //20866 - Add(TBuffCodePageName.Create('cskoi8r', 20866)); //20866 - Add(TBuffCodePageName.Create('koi', 20866)); //20866 - Add(TBuffCodePageName.Create('koi8', 20866)); //20866 - Add(TBuffCodePageName.Create('koi8r', 20866)); //20866 - - Add(TBuffCodePageName.Create('koi8-u', 21866)); //21866 - Add(TBuffCodePageName.Create('cskoi8u', 21866)); //21866 - Add(TBuffCodePageName.Create('koi8u', 21866)); //21866 - Add(TBuffCodePageName.Create('koi8-ru', 21866)); //21866 - - Add(TBuffCodePageName.Create('iso-8859-1', 28591)); //28591 - Add(TBuffCodePageName.Create('cp819', 28591)); //28591 - Add(TBuffCodePageName.Create('ibm819', 28591)); //28591 - Add(TBuffCodePageName.Create('latin1', 28591)); //28591 - Add(TBuffCodePageName.Create('latin-1', 28591)); //28591 - Add(TBuffCodePageName.Create('iso_8859-1:1987', 28591)); //28591 - Add(TBuffCodePageName.Create('iso-ir-100', 28591)); //28591 - Add(TBuffCodePageName.Create('iso_8859-1', 28591)); //28591 - Add(TBuffCodePageName.Create('l1', 28591)); //28591 - Add(TBuffCodePageName.Create('csisolatin1', 28591)); //28591 - Add(TBuffCodePageName.Create('iso8859-1', 28591)); //28591 - Add(TBuffCodePageName.Create('iso 8859-1', 28591)); //28591 - - Add(TBuffCodePageName.Create('iso-8859-2', 28592)); //28592 - Add(TBuffCodePageName.Create('iso_8859-2:1987', 28592)); //28592 - Add(TBuffCodePageName.Create('iso-ir-101', 28592)); //28592 - Add(TBuffCodePageName.Create('iso_8859-2', 28592)); //28592 - Add(TBuffCodePageName.Create('latin2', 28592)); //28592 - Add(TBuffCodePageName.Create('latin-2', 28592)); //28592 - Add(TBuffCodePageName.Create('l2', 28592)); //28592 - Add(TBuffCodePageName.Create('csisolatin2', 28592)); //28592 - Add(TBuffCodePageName.Create('iso8859-2', 28592)); //28592 - Add(TBuffCodePageName.Create('iso 8859-2', 28592)); //28592 - - Add(TBuffCodePageName.Create('iso-8859-3', 28593)); //28593 - Add(TBuffCodePageName.Create('iso_8859-3:1988', 28593)); //28593 - Add(TBuffCodePageName.Create('iso-ir-109', 28593)); //28593 - Add(TBuffCodePageName.Create('iso_8859-3', 28593)); //28593 - Add(TBuffCodePageName.Create('latin3', 28593)); //28593 - Add(TBuffCodePageName.Create('latin-3', 28593)); //28593 - Add(TBuffCodePageName.Create('l3', 28593)); //28593 - Add(TBuffCodePageName.Create('csisolatin3', 28593)); //28593 - Add(TBuffCodePageName.Create('iso 8859-3', 28593)); //28593 - Add(TBuffCodePageName.Create('iso8859-3', 28593)); //28593 - - Add(TBuffCodePageName.Create('iso-8859-4', 28594)); //28594 - Add(TBuffCodePageName.Create('iso_8859-4:1988', 28594)); //28594 - Add(TBuffCodePageName.Create('iso-ir-110', 28594)); //28594 - Add(TBuffCodePageName.Create('iso_8859-4', 28594)); //28594 - Add(TBuffCodePageName.Create('latin4', 28594)); //28594 - Add(TBuffCodePageName.Create('latin-4', 28594)); //28594 - Add(TBuffCodePageName.Create('l4', 28594)); //28594 - Add(TBuffCodePageName.Create('csisolatin4', 28594)); //28594 - Add(TBuffCodePageName.Create('iso 8859-4', 28594)); //28594 - Add(TBuffCodePageName.Create('iso8859-4', 28594)); //28594 - - Add(TBuffCodePageName.Create('iso-8859-5', 28595)); //28595 - Add(TBuffCodePageName.Create('iso_8859-5:1988', 28595)); //28595 - Add(TBuffCodePageName.Create('iso-ir-144', 28595)); //28595 - Add(TBuffCodePageName.Create('iso_8859-5', 28595)); //28595 - Add(TBuffCodePageName.Create('cyrillic', 28595)); //28595 - Add(TBuffCodePageName.Create('csisolatincyrillic', 28595)); //28595 - Add(TBuffCodePageName.Create('l5', 28595)); //28595 - Add(TBuffCodePageName.Create('iso 8859-5', 28595)); //28595 - Add(TBuffCodePageName.Create('iso8859-5', 28595)); //28595 - - Add(TBuffCodePageName.Create('iso-8859-6', 28596)); //28596 - Add(TBuffCodePageName.Create('iso_8859-6:1987', 28596)); //28596 - Add(TBuffCodePageName.Create('arabic', 28596)); //28596 - Add(TBuffCodePageName.Create('csisolatinarabic', 28596)); //28596 - Add(TBuffCodePageName.Create('ecma-114', 28596)); //28596 - Add(TBuffCodePageName.Create('iso_8859-6', 28596)); //28596 - Add(TBuffCodePageName.Create('iso-ir-127', 28596)); //28596 - Add(TBuffCodePageName.Create('iso 8859-6', 28596)); //28596 - Add(TBuffCodePageName.Create('iso8859-6', 28596)); //28596 - - Add(TBuffCodePageName.Create('iso-8859-7', 28597)); //28597 - Add(TBuffCodePageName.Create('iso_8859-7:1987', 28597)); //28597 - Add(TBuffCodePageName.Create('iso-ir-126', 28597)); //28597 - Add(TBuffCodePageName.Create('iso_8859-7', 28597)); //28597 - Add(TBuffCodePageName.Create('elot_928', 28597)); //28597 - Add(TBuffCodePageName.Create('ecma-118', 28597)); //28597 - Add(TBuffCodePageName.Create('greek', 28597)); //28597 - Add(TBuffCodePageName.Create('greek8', 28597)); //28597 - Add(TBuffCodePageName.Create('csisolatingreek', 28597)); //28597 - Add(TBuffCodePageName.Create('iso 8859-7', 28597)); //28597 - Add(TBuffCodePageName.Create('iso8859-7', 28597)); //28597 - - Add(TBuffCodePageName.Create('iso-8859-8', 28598)); //28598 - Add(TBuffCodePageName.Create('iso_8859-8:1988', 28598)); //28598 - Add(TBuffCodePageName.Create('iso-ir-138', 28598)); //28598 - Add(TBuffCodePageName.Create('iso_8859-8', 28598)); //28598 - Add(TBuffCodePageName.Create('hebrew', 28598)); //28598 - Add(TBuffCodePageName.Create('csisolatinhebrew', 28598)); //28598 - Add(TBuffCodePageName.Create('visual', 28598)); //28598 - Add(TBuffCodePageName.Create('iso 8859-8', 28598)); //28598 - Add(TBuffCodePageName.Create('iso8859-8', 28598)); //28598 - - Add(TBuffCodePageName.Create('iso-8859-9', 28599)); //28599 - Add(TBuffCodePageName.Create('iso_8859-9:1989', 28599)); //28599 - Add(TBuffCodePageName.Create('iso-ir-148', 28599)); //28599 - Add(TBuffCodePageName.Create('iso_8859-9', 28599)); //28599 - Add(TBuffCodePageName.Create('latin5', 28599)); //28599 - Add(TBuffCodePageName.Create('latin-5', 28599)); //28599 - Add(TBuffCodePageName.Create('l5', 28599)); //28599 - Add(TBuffCodePageName.Create('csisolatin5', 28599)); //28599 - Add(TBuffCodePageName.Create('iso 8859-9', 28599)); //28599 - Add(TBuffCodePageName.Create('iso8859-9', 28599)); //28599 - - Add(TBuffCodePageName.Create('iso-8859-10', 28600)); //28600 - Add(TBuffCodePageName.Create('iso-ir-157', 28600)); //28600 - Add(TBuffCodePageName.Create('l6', 28600)); //28600 - Add(TBuffCodePageName.Create('iso_8859-10:1992', 28600)); //28600 - Add(TBuffCodePageName.Create('csisolatin6', 28600)); //28600 - Add(TBuffCodePageName.Create('iso 8859-10', 28600)); //28600 - Add(TBuffCodePageName.Create('iso8859-10', 28600)); //28600 - Add(TBuffCodePageName.Create('iso_8859-10', 28600)); //28600 - Add(TBuffCodePageName.Create('latin6', 28600)); //28600 - Add(TBuffCodePageName.Create('latin-6', 28600)); //28600 - - Add(TBuffCodePageName.Create('iso-8859-11', 28601)); //28601 - Add(TBuffCodePageName.Create('iso 8859-11', 28601)); //28601 - Add(TBuffCodePageName.Create('iso8859-11', 28601)); //28601 - Add(TBuffCodePageName.Create('iso_8859-11', 28601)); //28601 - Add(TBuffCodePageName.Create('iso_8859-11:1992', 28601)); //28601 - Add(TBuffCodePageName.Create('tactis', 28601)); //28601 - - Add(TBuffCodePageName.Create('iso-8859-13', 28603)); //28603 - Add(TBuffCodePageName.Create('iso 8859-13', 28603)); //28603 - Add(TBuffCodePageName.Create('iso-ir-179', 28603)); //28603 - Add(TBuffCodePageName.Create('iso8859-13', 28603)); //28603 - Add(TBuffCodePageName.Create('iso_8859-13', 28603)); //28603 - Add(TBuffCodePageName.Create('l7', 28603)); //28603 - Add(TBuffCodePageName.Create('latin7', 28603)); //28603 - Add(TBuffCodePageName.Create('latin-7', 28603)); //28603 - - Add(TBuffCodePageName.Create('iso-8859-14', 28604)); //28604 - Add(TBuffCodePageName.Create('iso 8859-14', 28604)); //28604 - Add(TBuffCodePageName.Create('iso-ir-199', 28604)); //28604 - Add(TBuffCodePageName.Create('iso8859-14', 28604)); //28604 - Add(TBuffCodePageName.Create('iso_8859-14', 28604)); //28604 - Add(TBuffCodePageName.Create('iso_8859-14:1998', 28604)); //28604 - Add(TBuffCodePageName.Create('l8', 28604)); //28604 - Add(TBuffCodePageName.Create('latin8', 28604)); //28604 - Add(TBuffCodePageName.Create('latin-8', 28604)); //28604 - Add(TBuffCodePageName.Create('iso-celtic', 28604)); //28604 - - Add(TBuffCodePageName.Create('iso-8859-15', 28605)); //28605 - Add(TBuffCodePageName.Create('iso_8859-15', 28605)); //28605 - Add(TBuffCodePageName.Create('latin-9', 28605)); //28605 - Add(TBuffCodePageName.Create('latin9', 28605)); //28605 - Add(TBuffCodePageName.Create('l9', 28605)); //28605 - Add(TBuffCodePageName.Create('iso 8859-15', 28605)); //28605 - Add(TBuffCodePageName.Create('iso-ir-203', 28605)); //28605 - Add(TBuffCodePageName.Create('iso8859-15', 28605)); //28605 - Add(TBuffCodePageName.Create('iso_8859-15:1998', 28605)); //28605 - Add(TBuffCodePageName.Create('latin-0', 28605)); //28605 - Add(TBuffCodePageName.Create('latin0', 28605)); //28605 - - Add(TBuffCodePageName.Create('iso-8859-16', 28606)); //28606 - Add(TBuffCodePageName.Create('iso 8859-16', 28606)); //28606 - Add(TBuffCodePageName.Create('iso-ir-226', 28606)); //28606 - Add(TBuffCodePageName.Create('iso8859-16', 28606)); //28606 - Add(TBuffCodePageName.Create('iso_8859-16', 28606)); //28606 - Add(TBuffCodePageName.Create('iso_8859-16:2000', 28606)); //28606 - Add(TBuffCodePageName.Create('latin10', 28606)); //28606 - - Add(TBuffCodePageName.Create('iso-2022-jp', 50220)); //50220 - Add(TBuffCodePageName.Create('iso 2022-jp', 50220)); //50220 - Add(TBuffCodePageName.Create('csiso2022jp', 50220)); //50220 - - Add(TBuffCodePageName.Create('iso-2022-jp-1', 50222)); //50222 - Add(TBuffCodePageName.Create('_iso-2022-jp$sio', 50222)); //50222 - - Add(TBuffCodePageName.Create('iso-2022-kr', 50225)); //50225 - Add(TBuffCodePageName.Create('csiso2022kr', 50225)); //50225 - - Add(TBuffCodePageName.Create('iso-2022-cn', 50227)); //50227 - Add(TBuffCodePageName.Create('csiso2022cn', 50227)); //50227 - Add(TBuffCodePageName.Create('x-cp50227', 50227)); //50227 - - Add(TBuffCodePageName.Create('euc-jp', 51932)); //51932 - Add(TBuffCodePageName.Create('eucjp', 51932)); //51932 - Add(TBuffCodePageName.Create('cseucjp', 51932)); //51932 - Add(TBuffCodePageName.Create('euc_jp', 51932)); //51932 - Add(TBuffCodePageName.Create('cseucpkdfmtjapanese', 51932)); //51932 - Add(TBuffCodePageName.Create('x-euc', 51932)); //51932 - Add(TBuffCodePageName.Create('x-euc-jp', 51932)); //51932 - - Add(TBuffCodePageName.Create('cn-gb', 51936)); //51936 - Add(TBuffCodePageName.Create('euc-cn', 51936)); //51936 - Add(TBuffCodePageName.Create('euc_cn', 51936)); //51936 - Add(TBuffCodePageName.Create('euccn', 51936)); //51936 - Add(TBuffCodePageName.Create('csgb2312', 51936)); //51936 - Add(TBuffCodePageName.Create('gb2312', 51936)); //51936 - Add(TBuffCodePageName.Create('gb_2312-80', 51936)); //51936 - Add(TBuffCodePageName.Create('x-cp20936', 51936)); //51936 - Add(TBuffCodePageName.Create('csiso58gb231280', 51936)); //51936 - Add(TBuffCodePageName.Create('iso-ir-58', 51936)); //51936 - - Add(TBuffCodePageName.Create('euc-kr', 51949)); //51949 - Add(TBuffCodePageName.Create('euc_kr', 51949)); //51949 - Add(TBuffCodePageName.Create('cseuckr', 51949)); //51949 - Add(TBuffCodePageName.Create('euckr', 51949)); //51949 - - Add(TBuffCodePageName.Create('gb18030', 54936)); //54936 - Add(TBuffCodePageName.Create('gb-18030', 54936)); //54936 - - Add(TBuffCodePageName.Create('utf-7', 65000)); //65000 - Add(TBuffCodePageName.Create('csunicode11utf7', 65000)); //65000 - Add(TBuffCodePageName.Create('unicode-1-1-utf-7', 65000)); //65000 - Add(TBuffCodePageName.Create('x-unicode-2-0-utf-7', 65000)); //65000 - - Add(TBuffCodePageName.Create('utf-8', 65001)); //65001 - Add(TBuffCodePageName.Create('utf8', 65001)); //65001 - Add(TBuffCodePageName.Create('unicode-1-1-utf-8', 65001)); //65001 - Add(TBuffCodePageName.Create('unicode-2-0-utf-8', 65001)); //65001 - Add(TBuffCodePageName.Create('x-unicode-2-0-utf-8', 65001)); //65001 - -// Add(TBuffCodePageName.Create('koi8-t', CP_UNKNOWN)); //-5 - - Add(TBuffCodePageName.Create('default', CP_ACP)); -// BG, 11.10.2012: too many compiler versions do not declare CP_SYMBOL. Do we actually need it? -// Add(TBuffCodePageName.Create('symbol', CP_SYMBOL)); - Add(TBuffCodePageName.Create('oem', CP_OEMCP)); - - CaseSensitive := False; - Sort; - finally - EndUpdate; - end; -end; - -//-- BG ---------------------------------------------------------- 08.01.2011 -- -destructor TBuffCodePageNameList.Destroy; -var - I: Integer; -begin - //BG, 08.01.2011: Issue 48: Memory leaks in HTMLBuffer.pas - // free the objects. Unlike Guilleaumes idea to set TStringList.OwnsObjects to True, we - // must free the objects on our own, as OwnsObjects is a property added in Delphi 2009. - BeginUpdate; - try - for I := Count - 1 downto 0 do - Objects[I].Free; - finally - EndUpdate; - end; - inherited; -end; - -//-- BG ---------------------------------------------------------- 22.12.2010 -- -function TBuffCodePageNameList.GetItem(Index: Integer): TBuffCodePageName; -begin - Result := TBuffCodePageName(Objects[Index]); -end; - -//-- BG ---------------------------------------------------------- 22.12.2010 -- -function TBuffCodePageNameList.IndexOf(const S: TBuffString): Integer; -var - LS: TBuffString; -begin - Result := inherited IndexOf(S); - if Result = -1 then - begin - LS := htLowerCase(S); - Result := Count - 1; - while (Result >= 0) and (Pos(Strings[Result], LS) = 0) do - Dec(Result); - end; -end; - -{ TBuffConverter } - -//-- BG ---------------------------------------------------------- 02.10.2012 -- -procedure TBuffConverter.Assign(Source: TBuffConverter); -begin - FPos := Source.FPos; - FEnd := Source.FEnd; - FCodePage := Source.FCodePage; - FInitalCodePage := Source.FInitalCodePage; -end; - -//-- BG ---------------------------------------------------------- 02.10.2012 -- -function TBuffConverter.AsString: TBuffString; -var - Bytes, Chars: Integer; - OldPos: PByte; -begin - Bytes := FEnd.AnsiChr - FPos.AnsiChr; - if (FCodePage = CP_UTF16LE) and (FInitalCodePage = CP_UTF16LE) then - begin - SetLength(Result, Bytes div 2); - System.Move(FPos.BytePtr^, Result[1], Bytes); - end - else - begin - Chars := 0; - if Bytes > 0 then - begin - SetLength(Result, Bytes); - OldPos := FPos.BytePtr; - try - repeat - Inc(Chars); - Result[Chars] := NextChar; - if Result[Chars] = #0 then - begin - Dec(Chars); - break; - end; - until FPos.AnsiChr >= FEnd.AnsiChr; - finally - FPos.BytePtr := OldPos; - end; - end; - SetLength(Result, Chars); - end; -end; - -//-- BG ---------------------------------------------------------- 26.09.2012 -- -constructor TBuffConverter.Create(CurrPtr, EndPtr: TBuffPointer; CodePage, InitalCodePage: TBuffCodePage); -begin - inherited Create; - FPos := CurrPtr; - FEnd := EndPtr; - FCodePage := CodePage; - FInitalCodePage := InitalCodePage; -end; - -//-- BG ---------------------------------------------------------- 26.09.2012 -- -constructor TBuffConverter.CreateCopy(Source: TBuffConverter); -begin - inherited Create; - Assign(Source); -end; - -//-- BG ---------------------------------------------------------- 26.09.2012 -- -function TBuffConverter.GetNext: Word; - - procedure SwapBytes(var Chr: Word); - var - Bytes: array[0..1] of Byte absolute Chr; - B: Byte; - begin - B := Bytes[0]; - Bytes[0]:= Bytes[1]; - Bytes[1] := B; - end; - -begin - // Issue 50: THTMLViewer.LoadStrings does not seem to work - // Creating the buffer from wide-/unicodestring may contain incorrectly - // converted characters of a single byte codepage though. After changing the - // codepage to the correct single byte codepage, the first or second character - // read is a #0 (namely the high byte of the previous WideChar). - // - // And #0 represents the end of the buffer. - // - // Thus always use the initial codepage for reading the appropriate number - // of bytes of a character in the correct byte order from buffer. - if FPos.AnsiChr < FEnd.AnsiChr then - case FInitalCodePage of - CP_UTF16LE: - begin - Result := FPos.WordPtr^; - Inc(FPos.BytePtr, sizeof(Word)); - end; - - CP_UTF16BE: - begin - Result := FPos.WordPtr^; - Inc(FPos.BytePtr, sizeof(Word)); - SwapBytes(Result); - end; - else - Result := FPos.BytePtr^; - Inc(FPos.BytePtr, sizeof(Byte)); - end - else - Result := 0; -end; - -//-- BG ---------------------------------------------------------- 26.09.2012 -- -function TBuffConverter.NextChar: TBuffChar; -begin - Result := TBuffChar(GetNext); -end; - -//-- BG ---------------------------------------------------------- 26.09.2012 -- -function TBuffConverter.PeekChar: TBuffChar; -var - Clone: TBuffConverter; - TheClass: TClass; -begin - TheClass := ClassType; - Clone := TBuffConverterClass(TheClass).CreateCopy(Self); - try - Result := Clone.NextChar; - finally - Clone.Free; - end; -end; - -{ TBuffer } - -procedure TBuffer.Assign(Source: TBuffer); -begin - FBuffer := Copy(Source.FBuffer); - Reset; - Inc(FStart.AnsiChr, Source.FStart.AnsiChr - PAnsiChar(Source.FBuffer)); - FName := Source.FName; - FConverter := TBuffConverterClass(Source.FConverter.ClassType).Create(FStart, FEnd, Source.FConverter.FCodePage, Source.FConverter.FInitalCodePage); - FState := Source.FState; - FBomLength := Source.FBomLength; -end; - -//-- BG ---------------------------------------------------------- 27.12.2010 -- -procedure TBuffer.AssignTo(Destin: TObject); -var - DstMem: TMemoryStream absolute Destin; -begin - if DstMem is TMemoryStream then - begin - DstMem.SetSize(Size); - System.Move(FBuffer[0], DstMem.Memory^, Size); - end; -end; - -//-- BG ---------------------------------------------------------- 26.09.2012 -- -function TBuffer.AsString: TBuffString; -begin - Result := FConverter.AsString; -end; - -//-- BG ---------------------------------------------------------- 14.12.2010 -- -constructor TBuffer.Create(Stream: TStream; Name: TBuffString = ''); -begin - inherited Create; - SetStream(Stream); - FName := Name; - DetectCodePage; -end; - -//-- BG ---------------------------------------------------------- 14.12.2010 -- -constructor TBuffer.Create(Stream: TStream; CodePage: TBuffCodePage; Name: TBuffString = ''); -begin - inherited Create; - SetStream(Stream); - FName := Name; - SetCodePage(CodePage); -end; - -//-- BG ---------------------------------------------------------- 17.12.2010 -- -constructor TBuffer.Create(const Text: TBuffString; const Name: TBuffString = ''; CodePage: TBuffCodePage = CP_UTF16LE); -var - I: Integer; -begin - inherited Create; - I := Length(Text) * sizeof(TBuffChar); - SetLength(FBuffer, I + sizeof(TBuffChar)); - if I > 0 then - Move(Text[1], FBuffer[0], I); - PBuffChar(@FBuffer[I])^ := TBuffChar(0); - Reset; - FName := Name; - SetCodePages(CodePage, CP_UTF16LE); - Include(FState, bsFixedCodePage); -end; - -//-- BG ---------------------------------------------------------- 29.10.2012 -- -constructor TBuffer.Create(const Doc: TBuffer); -begin - inherited Create; - Assign(Doc); -end; - -//-- BG ---------------------------------------------------------- 17.12.2010 -- -constructor TBuffer.Create(const Text: TBuffString; CodePage: TBuffCodePage; const Name: TBuffString = ''); -begin - Create(Text, Name, CodePage); -end; - -//-- BG ---------------------------------------------------------- 17.12.2010 -- -constructor TBuffer.Create(Text: PByte; ByteCount: Integer; CodePage: TBuffCodePage; const Name: TBuffString = ''); -begin - Create(Text, ByteCount, CodePage, CodePage, Name); -end; - -//-- BG ---------------------------------------------------------- 17.12.2010 -- -constructor TBuffer.Create(Text: PByte; ByteCount: Integer; CodePage, InitialCodePage: TBuffCodePage; const Name: TBuffString = ''); -var - I: Integer; -begin - inherited Create; - I := ByteCount; - SetLength(FBuffer, I + sizeof(TBuffChar)); - Move(Text^, FBuffer[0], I); - PBuffChar(@FBuffer[I])^ := TBuffChar(0); - Reset; - FName := Name; - SetCodePages(CodePage, InitialCodePage); -end; - -//-- BG ---------------------------------------------------------- 06.12.2011 -- -class function TBuffer.Convert(const Text: TBuffString; CodePage: TBuffCodePage): TBuffString; -var - Buffer: TBuffer; -begin - Buffer := TBuffer.Create(Text, CodePage); - try - Result := Buffer.AsString; - finally - Buffer.Free; - end; -end; - -//-- BG ---------------------------------------------------------- 06.12.2011 -- -class function TBuffer.Convert(Text: PByte; ByteCount: Integer; CodePage: TBuffCodePage): TBuffString; -var - Buffer: TBuffer; -begin - Buffer := TBuffer.Create(Text, ByteCount, CodePage); - try - Result := Buffer.AsString; - finally - Buffer.Free; - end; -end; - -//-- BG ---------------------------------------------------------- 06.12.2011 -- -class function TBuffer.Convert(Text: PByte; ByteCount: Integer; CodePage, InitialCodePage: TBuffCodePage): TBuffString; -var - Buffer: TBuffer; -begin - Buffer := TBuffer.Create(Text, ByteCount, CodePage, InitialCodePage); - try - Result := Buffer.AsString; - finally - Buffer.Free; - end; -end; - -//-- BG ---------------------------------------------------------- 14.12.2010 -- -destructor TBuffer.Destroy; -begin - FConverter.Free; - inherited; -end; - -procedure TBuffer.DetectCodePage; -var - ByteCount: Integer; - - function IsIso2022JP: boolean; - {look for iso-2022-jp Japanese file} - const - EscSequence: array [0..3] of PAnsiChar = (#$1b'$@'#0, #$1b'$B'#0, #$1b'(J'#0, #$1b'(B'#0); - var - I, J, K, L: PAnsiChar; - begin - Result := False; - I := StrNPosA(FStart.AnsiChr, EscSequence[0], ByteCount); {look for starting sequence} - J := StrNPosA(FStart.AnsiChr, EscSequence[1], ByteCount); - if I < J then - I := J; - if I <> nil then - begin {now look for ending sequence after the start} - K := StrNPosA(I, EscSequence[2], ByteCount); - L := StrNPosA(I, EscSequence[3], ByteCount); - if K < L then - K := L; {pick a positive value} - if K <> nil then {start and end sequence found} - Result := True; - end; - end; - -begin - FreeAndNil(FConverter); - ByteCount := FEnd.AnsiChr - FStart.AnsiChr; - if ByteCount >= 2 then - begin - // a preamble of up to 3 bytes might tell us the file encoding: - case FStart.WordPtr^ of - $FEFF: - begin - // this is little endian unicode - Inc(FStart.WordPtr); - CodePage := CP_UTF16LE; - Include(FState, bsFixedCodePage); - // TODO: if followed by $0000, this is UTF-32-LE - FBomLength := 2; - Exit; - end; - - $FFFE: - begin - // this is big endian unicode - // swap the 2 bytes of one char. - Inc(FStart.WordPtr); - CodePage := CP_UTF16BE; - Include(FState, bsFixedCodePage); - // TODO: if followed by $0000, this is UTF-32-3412 - FBomLength := 2; - Exit; - end; - - $BBEF: - if ByteCount >= 3 then - begin - Inc(FStart.WordPtr); - if FStart.BytePtr^ = $BF then - begin - // this is UTF-8 - Inc(FStart.BytePtr); - CodePage := CP_UTF8; - Include(FState, bsFixedCodePage); - FBomLength := 3; - Exit; - end; - Dec(FStart.WordPtr); - end; - - //TODO: - { - $0000: - if followed by $FFFE, this is UTF-32-BE - if followed by $FEFF, this is UTF-32-2143 - } - end; - - if (FStart.WordPtr^ and $00FF) = 0 then - begin - if (FStart.WordPtr^ and $FF00) <> 0 then - begin - CodePage := CP_UTF16BE; - Include(FState, bsFixedCodePage); - Exit; - end; - end - else - begin - if (FStart.WordPtr^ and $FF00) = 0 then - begin - CodePage := CP_UTF16LE; - Include(FState, bsFixedCodePage); - Exit; - end; - end; - end; - if IsIso2022JP then - begin - CodePage := CP_ISO2022JP; - Include(FState, bsFixedCodePage); - Exit; - end; - // no preamble: this is most probably a 1-byte per character code. -{$ifdef LCL} - if htExpectsUTF8 then - CodePage := CP_UTF8 - else -{$endif} - CodePage := CP_ACP; -end; - -//-- BG ---------------------------------------------------------- 26.09.2012 -- -function TBuffer.GetCodePage: TBuffCodePage; -begin - if FConverter <> nil then - Result := FConverter.CodePage - else - Result := CP_UNKNOWN; -end; - -//-- BG ---------------------------------------------------------- 16.12.2010 -- -function TBuffer.GetPosition: Integer; -begin - Result := FConverter.FPos.AnsiChr - PAnsiChar(FBuffer); -end; - -//-- BG ---------------------------------------------------------- 31.01.2011 -- -function TBuffer.GetString(FromIndex, UntilIndex: Integer): TBuffString; -var - OldPos, I: Integer; -begin - SetLength(Result, UntilIndex - FromIndex); - if Length(Result) > 0 then - begin - OldPos := Position; - try - I := 0; - Position := FromIndex; - while Position < UntilIndex do - begin - Inc(I); - Result[I] := NextChar; - end; - SetLength(Result, I); - finally - Position := OldPos; - end; - end; -end; - -//-- BG ---------------------------------------------------------- 26.09.2012 -- -function TBuffer.NextChar: TBuffChar; -begin - Result := FConverter.NextChar; -end; - -//-- BG ---------------------------------------------------------- 26.09.2012 -- -function TBuffer.PeekChar: TBuffChar; -begin - Result := FConverter.PeekChar; -end; - -//-- BG ---------------------------------------------------------- 16.12.2010 -- -procedure TBuffer.Reset; -begin - FStart.AnsiChr := PAnsiChar(FBuffer); - FEnd.AnsiChr := FStart.AnsiChr + Size; -end; - -//-- BG --------------------------------------------------------- 11.11.2011 -- -procedure TBuffer.SetCodePage(Value: TBuffCodePage); -begin - if bsFixedCodePage in FState then - exit; - - if FConverter = nil then - SetCodePages(Value, Value) - else - SetCodePages(Value, FConverter.FInitalCodePage); -end; - -//-- BG ---------------------------------------------------------- 13.10.2012 -- -procedure TBuffer.SetCodePages(Value, Initial: TBuffCodePage); -var - Index: Integer; - OldConverter: TBuffConverter; - CodePageInfos: TBuffConvInfoList; -begin - CodePageInfos := GetConvInfoList; - if CodePageInfos <> nil then - begin - if FConverter = nil then - begin - // setting CodePage for the first time: - Index := CodePageInfos.Find(Value); - if Index < 0 then - Index := CodePageInfos.Find(CP_UNKNOWN); - FConverter := CodePageInfos[Index].Converter.Create(FStart, FEnd, Value, Initial) - end - else - begin - // setting CodePage again: - if FConverter.CodePage = Value then - // same CodePage again. Nothing to do. - exit; - - // Change the CodePage. Keep common internal states including InitialCodePage. - OldConverter := FConverter; - OldConverter.FCodePage := Value; // set new code page to old converter. CreateCopy will set it to the new converter. - OldConverter.FInitalCodePage := Initial; - Index := CodePageInfos.Find(Value); - if Index < 0 then - Index := CodePageInfos.Find(CP_UNKNOWN); - FConverter := CodePageInfos[Index].Converter.CreateCopy(OldConverter); - OldConverter.Free; - end; - end; -end; - -//-- BG ---------------------------------------------------------- 16.12.2010 -- -procedure TBuffer.SetPosition(const Value: Integer); -begin - FConverter.FPos.AnsiChr := PAnsiChar(FBuffer) + Value; -end; - -//-- BG ---------------------------------------------------------- 16.12.2010 -- -procedure TBuffer.SetStream(Stream: TStream); -var - I: Integer; -begin - I := Stream.Size - Stream.Position; - SetLength(FBuffer, I + sizeof(TBuffChar)); - //BG, 25.02.2011: Issue 74: Range check error when creating a buffer for the empty stream - // Do not read from empty/exhausted stream: - if I > 0 then - Stream.Read(FBuffer[0], I); - PBuffChar(@FBuffer[I])^ := TBuffChar(0); - Reset; -end; - -//-- BG ---------------------------------------------------------- 16.12.2010 -- -function TBuffer.Size: Integer; -begin - Result := Length(FBuffer) - sizeof(TBuffChar); -end; - -initialization -finalization -// GDG - VFinalizing := True; - FreeAndNil(VCodePagesByName); - FreeAndNil(VConvertersByCodePage); -end. - - diff --git a/CORE/Source/Plugins/Htmlviewer/source/HtmlCaches.pas b/CORE/Source/Plugins/Htmlviewer/source/HtmlCaches.pas deleted file mode 100644 index 81e4ddf8f..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/HtmlCaches.pas +++ /dev/null @@ -1,223 +0,0 @@ -{ -Version 12 -Copyright (c) 1995-2008 by L. David Baldwin, -Copyright (c) 2008-2010 by HtmlViewer Team -Copyright (c) 2011-2012 by Bernd Gabriel - -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. - -Note that the source modules HTMLGIF1.PAS and DITHERUNIT.PAS -are covered by separate copyright notices located in those modules. -} - -{$I htmlcons.inc} - -unit HtmlCaches; - -interface - -uses - SysUtils, - HtmlGlobals; - -type - - //BG, 30.04.2011: - ThtCachable = class(TObject) - private - AccessCount: Integer; - UsageCount: Integer; {how many times in use} - public - destructor Destroy; override; - procedure BeginUse; - procedure EndUse; - end; - - -//------------------------------------------------------------------------------ -// ThtCache is the cache, that holds the above cacheable items. -//------------------------------------------------------------------------------ - - ThtCache = class(ThtStringList) - private - FMaxCache: Integer; - function GetObject(Index: Integer): ThtCachable; reintroduce; - protected - function GetCachable(I: Integer): ThtCachable; {$ifdef UseInline} inline; {$endif} - property Objects[Index: Integer]: ThtCachable read GetObject; - public - constructor Create; - destructor Destroy; override; - function AddObject(const S: ThtString; AObject: ThtCachable): Integer; reintroduce; - procedure BumpAndCheck; - procedure Clear; override; - procedure DecUsage(const S: ThtString); - procedure IncUsage(const S: ThtString); - procedure PurgeCache; - procedure SetCacheCount(N: Integer); - property MaxCache: Integer read FMaxCache; - end; - -implementation - -{ ThtCachable } - -//-- BG ---------------------------------------------------------- 16.04.2011 -- -procedure ThtCachable.BeginUse; -begin - Inc(UsageCount); -end; - -//-- BG ---------------------------------------------------------- 16.04.2011 -- -destructor ThtCachable.Destroy; -begin - Assert(UsageCount = 0, 'Freeing cached ' + ClassName + ' that''s still in use ' + IntToStr(UsageCount) + ' time/s.' ); - inherited; -end; - -//-- BG ---------------------------------------------------------- 16.04.2011 -- -procedure ThtCachable.EndUse; -begin - Dec(UsageCount); - Assert(UsageCount >= 0, 'Cached ' + ClassName + ' usage count < 0'); -end; - -{ ThtCache } - -//------------------------------------------------------------------------------ -function ThtCache.AddObject(const S: ThtString; AObject: ThtCachable): Integer; -begin - Result := inherited AddObject(S, AObject); - Inc(AObject.UsageCount); -end; - -//------------------------------------------------------------------------------ -procedure ThtCache.BumpAndCheck; -var - I: Integer; - Tmp: ThtCachable; -begin - for I := Count - 1 downto 0 do - begin - Tmp := Objects[I]; - Inc(Tmp.AccessCount); - if (Tmp.AccessCount > FMaxCache) and (Tmp.UsageCount <= 0) then - begin - Delete(I); - Tmp.Free; {the ThtCachable} - end; - end; -end; - -//------------------------------------------------------------------------------ -procedure ThtCache.Clear; -var - I: Integer; -begin - for I := 0 to Count - 1 do - Objects[I].Free; - inherited Clear; -end; - -//------------------------------------------------------------------------------ -constructor ThtCache.Create; -begin - inherited Create; - FMaxCache := 100; - Sorted := True; -end; - -//------------------------------------------------------------------------------ -procedure ThtCache.DecUsage(const S: ThtString); -var - I: Integer; -begin - I := IndexOf(S); - if I >= 0 then - Objects[I].EndUse; -end; - -//------------------------------------------------------------------------------ -destructor ThtCache.Destroy; -begin - Clear; - inherited Destroy; -end; - -//------------------------------------------------------------------------------ -function ThtCache.GetCachable(I: Integer): ThtCachable; -begin - Result := Objects[I]; - if Result <> nil then - begin - Result.AccessCount := 0; - Inc(Result.UsageCount); - end; -end; - -//-- BG ---------------------------------------------------------- 06.03.2011 -- -function ThtCache.GetObject(Index: Integer): ThtCachable; -begin - Result := ThtCachable(inherited GetObject(Index)); -end; - -//------------------------------------------------------------------------------ -procedure ThtCache.IncUsage(const S: ThtString); -var - I: Integer; -begin - I := IndexOf(S); - if I >= 0 then - Objects[I].BeginUse; -end; - -//------------------------------------------------------------------------------ -procedure ThtCache.PurgeCache; -var - I: Integer; - Tmp: ThtCachable; -begin - for I := Count - 1 downto 0 do - begin - Tmp := Objects[I]; - if (Tmp.UsageCount <= 0) then - begin - Delete(I); - Tmp.Free; {the ThtCachable} - end; - end; -end; - -//------------------------------------------------------------------------------ -procedure ThtCache.SetCacheCount(N: Integer); -var - I: Integer; -begin - for I := Count - 1 downto 0 do - with Objects[I] do - begin - if (AccessCount > N) and (UsageCount <= 0) then - begin - Delete(I); - Free; - end; - end; - FMaxCache := N; -end; - -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/HtmlFonts.pas b/CORE/Source/Plugins/Htmlviewer/source/HtmlFonts.pas deleted file mode 100644 index 6e397951f..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/HtmlFonts.pas +++ /dev/null @@ -1,330 +0,0 @@ -{ -Version 11.7 -Copyright (c) 1995-2008 by L. David Baldwin -Copyright (c) 2008-2016 by HtmlViewer Team - -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. - -Note that the source modules HTMLGIF1.PAS and DITHERUNIT.PAS -are covered by separate copyright notices located in those modules. -} - -{$I htmlcons.inc} - -unit HtmlFonts; - -interface - -uses -{$ifdef UseVCLStyles} - System.Types, - System.UITypes, - Vcl.Themes, -{$endif} -{$ifdef LCL} - LclIntf, LclType, -{$else} - {$ifdef MSWindows} - Windows, - {$endif} -{$endif} - SysUtils, - vcl.Graphics, Classes, vcl.Forms, Contnrs, Variants, - // - HtmlGlobals, - StyleTypes; - -type - ThtFontInfo = record - iName: ThtString; - iSize: Double; - iStyle: TFontStyles; - iColor: TColor; - ibgColor: TColor; - iCharSet: TFontCharSet; - iCharExtra: Variant; - iWeight: Integer; - end; - - // link state - FIIndex = ( - LFont, // initial link - VFont, // visited link - HLFont, // hovered link - HVFont // hovered visited link - ); - - TFontInfoArray = class - public - Ar: array[LFont..HVFont] of ThtFontInfo; - procedure Assign(Source: TFontInfoArray); - end; - - ThtFont = class(TFont) - public - bgColor: TColor; - tmHeight: Integer; - tmDescent: Integer; - tmExternalLeading: Integer; - tmAveCharWidth: Integer; - tmMaxCharWidth: Integer; - tmCharset: Integer; - CharExtra: Integer; - EmSize: Integer; - ExSize: Integer; - constructor Create; {$ifdef LCL} override; {$endif} - procedure Assign(const Info: ThtFontInfo); reintroduce; overload; - procedure Assign(Source: TPersistent); overload; override; - procedure AssignToCanvas(Canvas: TCanvas); - end; - - ThtFontCache = class - private - FFontsByName: ThtStringList; - procedure Add(Font: ThtFont); - function Find(const FontInfo: ThtFontInfo): ThtFont; - public - constructor Create; - destructor Destroy; override; - function GetFontLike(var Font: ThtFontInfo): ThtFont; - end; - -function AllMyFonts: ThtFontCache; - -implementation - -var - VFontCache: ThtFontCache; - -//-- BG ---------------------------------------------------------- 02.05.2011 -- -function AllMyFonts: ThtFontCache; -// do not inline as it would required to move local var to interface section. {$ifndef UseInline} inline; {$endif} -begin - if VFontCache = nil then - VFontCache := ThtFontCache.Create; - Result := VFontCache; -end; - -{ TFontInfoArray } - -procedure TFontInfoArray.Assign(Source: TFontInfoArray); -var - I: FIIndex; -begin - for I := LFont to HVFont do - Ar[I] := Source.Ar[I]; -end; - -{----------------TMyFont.Assign} - -procedure ThtFont.Assign(Source: TPersistent); -begin - if Source is ThtFont then - begin - bgColor := ThtFont(Source).bgColor; - tmHeight := ThtFont(Source).tmHeight; - tmDescent := ThtFont(Source).tmDescent; - tmExternalLeading := ThtFont(Source).tmExternalLeading; - tmAveCharWidth := ThtFont(Source).tmAveCharWidth; - tmMaxCharWidth := ThtFont(Source).tmMaxCharWidth; - tmCharset := ThtFont(Source).tmCharset; - CharExtra := ThtFont(Source).CharExtra; - EmSize := ThtFont(Source).EmSize; - ExSize := ThtFont(Source).ExSize; - end; - inherited Assign(Source); -end; - -//-- BG ---------------------------------------------------------- 12.03.2011 -- -procedure ThtFont.Assign(const Info: ThtFontInfo); -begin - Name := Info.iName; - Height := -Round(Info.iSize * Screen.PixelsPerInch / 72); - Style := Info.iStyle; - bgColor := Info.ibgColor; - Color := Info.iColor; - CharSet := Info.iCharSet; -end; - -procedure ThtFont.AssignToCanvas(Canvas: TCanvas); -begin - Canvas.Font := Self; -{$ifdef Windows} - SetTextCharacterExtra(Canvas.Handle, CharExtra); -{$endif} -end; - -constructor ThtFont.Create; -begin - inherited; - Charset := DEFAULT_CHARSET; -end; - -{ TMyFontCache } - -//-- BG ---------------------------------------------------------- 30.01.2011 -- -procedure ThtFontCache.Add(Font: ThtFont); -var - I: Integer; - FontName: ThtString; -begin - FontName := htLowerCase(Font.Name); - I := -1; - if not FFontsByName.Find(FontName, I) then - begin - I := FFontsByName.Add(FontName); - FFontsByName.Objects[I] := TObjectList.Create(True); - end; - TObjectList(FFontsByName.Objects[I]).Add(Font); -end; - -//-- BG ---------------------------------------------------------- 30.01.2011 -- -constructor ThtFontCache.Create; -begin - inherited; - FFontsByName := ThtStringList.Create; - FFontsByName.Sorted := True; -end; - -//-- BG ---------------------------------------------------------- 30.01.2011 -- -destructor ThtFontCache.Destroy; -var - I: Integer; -begin - for I := 0 to FFontsByName.Count - 1 do - FFontsByName.Objects[I].Free; - FFontsByName.Free; - inherited; -end; - -//-- BG ---------------------------------------------------------- 30.01.2011 -- -function ThtFontCache.Find(const FontInfo: ThtFontInfo): ThtFont; -var - iHeight: Integer; - - function SameFonts(F1: ThtFont): Boolean; - begin - if F1.Height = iHeight then - if F1.Style = FontInfo.iStyle then - if F1.Charset = FontInfo.iCharset then - begin - Result := True; - exit; - end; - Result := False; - end; - -var - I: Integer; - Fonts: TObjectList; -begin - I := -1; - if FFontsByName.Find(htLowerCase(FontInfo.iName), I) then - begin - iHeight := -Round(FontInfo.iSize * Screen.PixelsPerInch / 72.0); - Fonts := TObjectList(FFontsByName.Objects[I]); - for I := 0 to Fonts.Count - 1 do - begin - Result := ThtFont(Fonts[I]); - if SameFonts(Result) then - exit; - end; - end; - Result := nil; -end; - -//-- BG ---------------------------------------------------------- 30.01.2011 -- -function ThtFontCache.GetFontLike(var Font: ThtFontInfo): ThtFont; -var - SameFont: ThtFont; - Save: HFONT; - SaveCharSet: TFontCharSet; - tm: TTextmetric; - DC: HDC; - V: Variant; -begin - SameFont := Find(Font); - if SameFont = nil then - begin - SameFont := ThtFont.Create; - SameFont.Name := Font.iName; - SameFont.Height := -Round(Font.iSize * Screen.PixelsPerInch / 72); - SameFont.Style := Font.iStyle; - SameFont.Charset := Font.iCharSet; - Add(SameFont); - - // If this is a Symbol charset, then keep it that way. - // To check the font's real charset, use Default_Charset - SaveCharSet := SameFont.CharSet; - SameFont.CharSet := DEFAULT_CHARSET; - DC := GetDC(0); - try - Save := SelectObject(DC, SameFont.Handle); - try - GetTextMetrics(DC, tm); - finally - SelectObject(DC, Save); - end; - if tm.tmCharset = Symbol_Charset then - SameFont.Charset := Symbol_CharSet - else - SameFont.Charset := SaveCharSet; - {now get the info on the finalized font} - if SameFont.Charset <> Default_Charset then {else already have the textmetrics} - begin - Save := SelectObject(DC, SameFont.Handle); - try - GetTextMetrics(DC, tm); - finally - SelectObject(DC, Save); - end; - end; - finally - ReleaseDC(0, DC); - end; - {calculate EmSize with current font rather than inherited} - SameFont.EmSize := tm.tmHeight - tm.tmInternalLeading; - SameFont.ExSize := SameFont.EmSize div 2; {apparently correlates with what browsers are doing} - SameFont.tmHeight := tm.tmHeight; - SameFont.tmDescent := tm.tmDescent; - SameFont.tmExternalLeading := tm.tmExternalLeading; - SameFont.tmMaxCharWidth := tm.tmMaxCharWidth; - SameFont.tmAveCharWidth := tm.tmAveCharWidth; - SameFont.tmCharset := tm.tmCharset; - end; - - Result := ThtFont.Create; - Result.Assign(SameFont); - Result.bgColor := Font.ibgColor; - Result.Color := Font.iColor; - - V := Font.iCharExtra; - if VarType(V) in VarInt then - Result.CharExtra := V - else if VarIsStr(V) then - if V <> 'normal' then - begin - Result.CharExtra := Round(StrToLength(V, False, Result.EmSize, Result.EmSize, 0)); - Font.iCharExtra := Result.CharExtra; - end; -end; - -initialization -finalization - FreeAndNil(VFontCache); -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/HtmlGlobals.pas b/CORE/Source/Plugins/Htmlviewer/source/HtmlGlobals.pas deleted file mode 100644 index dad93f470..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/HtmlGlobals.pas +++ /dev/null @@ -1,1713 +0,0 @@ -{ -Version 11.7 -Copyright (c) 2008-2016 by HtmlViewer Team - -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. - -Note that the source modules HTMLGIF1.PAS and DITHERUNIT.PAS -are covered by separate copyright notices located in those modules. -} - -unit HtmlGlobals; - -{$I htmlcons.inc} - -interface - -uses -{$ifdef HasSystemUITypes} - System.UITypes, -{$endif} -{$ifdef UseVCLStyles} - Vcl.Themes, -{$endif} -{$ifdef MSWINDOWS} - Windows, -{$endif} - Classes, SysUtils, vcl.Graphics, vcl.Controls, -{$ifdef LCL} - LclIntf, LclType, LCLVersion, Types, Messages, - StdCtrls, Buttons, Forms, Base64, Dialogs, Process, - HtmlMisc, - WideStringsLcl, - {$ifdef DebugIt} - {$message 'HtmlViewer uses LCL standard controls.'} - {$endif} -{$else} - vcl.Consts, StrUtils, vcl.StdCtrls, ShellAPI, - {$ifdef UseTNT} - {$ifdef DebugIt} - {$message 'HtmlViewer uses TNT unicode controls.'} - {$endif} - Messages, - TntControls, - TntStdCtrls, - {$ifdef Compiler18_Plus} - WideStrings, - {$else} - TntWideStrings, - {$endif} - TntClasses, - {$else UseTNT} - {$ifdef DebugIt} - {$message 'HtmlViewer uses VCL standard controls.'} - {$endif} - vcl.Buttons, - Messages, - {$ifdef Compiler18_Plus} - WideStrings, - {$else} - TntWideStrings, - TntClasses, - {$endif} - {$endif UseTNT} -{$endif} - vcl.Clipbrd, - Math; - -const -{$ifndef LCL} - lcl_fullversion = 0; - fpc_fullversion = 0; -{$endif} -{$ifndef MSWindows} - //Charsets defined in unit Windows: - ANSI_CHARSET = 0; - DEFAULT_CHARSET = 1; - SYMBOL_CHARSET = 2; - SHIFTJIS_CHARSET = 128; - HANGEUL_CHARSET = 129; - //JOHAB_CHARSET = 130; - GB2312_CHARSET = 134; - CHINESEBIG5_CHARSET = 136; - GREEK_CHARSET = 161; - TURKISH_CHARSET = 162; - //VIETNAMESE_CHARSET = 163; - HEBREW_CHARSET = 177; - ARABIC_CHARSET = 178; - RUSSIAN_CHARSET = 204; - THAI_CHARSET = 222; - EASTEUROPE_CHARSET = 238; - OEM_CHARSET = 255; -{$endif MSWindows} - // more charset constants - UNKNOWN_CHARSET = -1; - - // some more codepage constants - CP_UNKNOWN = -1; - CP_UTF16LE = 1200; - CP_UTF16BE = 1201; - CP_ISO2022JP = 50220; - - -type -{$IFNDEF DOTNET} - {$IFNDEF FPC} - {$ifndef PtrInt_defined} - {$define PtrInt_defined} - //needed so that in FreePascal, we can use pointers of different sizes - {$IFDEF WIN32} - PtrInt = LongInt; - PtrUInt = LongWord; - {$ENDIF} - {$IFDEF WIN64} - PtrInt = Int64; - PtrUInt = Int64; - {$ENDIF} - //NOTE: The code below asumes a 32bit Linux architecture (such as target i386-linux) - {$IFDEF KYLIX} - PtrInt = LongInt; - PtrUInt = LongWord; - {$ENDIF} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -{$ifdef DebugIt} - {$ifdef UNICODE} - {$message 'Compiler uses unicode by default.'} - {$else} - {$message 'Compiler uses single byte chars by default.'} - {$endif} - - {$message 'HtmlViewer uses unicode.'} -{$endif} - -{$ifdef FPC} -{$else} - {$ifdef Compiler18_Plus} - {$else} - TWideStringList = class(TTntStringList); - {$endif} -{$endif} -{$ifdef UNICODE} - ThtChar = Char; - ThtString = string; - ThtStrings = TStrings; - ThtStringList = TStringList; - PhtChar = PChar; -{$else} -{$if fpc_fullversion < 30000} - UnicodeString = WideString; -{$ifend} - ThtChar = WideChar; - ThtString = WideString; - ThtStrings = TWideStrings; - ThtStringList = TWideStringList; - PhtChar = PWideChar; -{$endif} - ThtCharArray = array of ThtChar; - ThtStringArray = array of ThtString; - ThtIntegerArray = array of Integer; - - ThtEdit = class({$ifdef UseTNT} TTntEdit {$else} TEdit {$endif}) - protected - procedure KeyDown(var Key: Word; Shift: TShiftState); override; -{$ifndef TEditHasTextHint} - private - FTextHint: ThtString; - FCanvas : TControlCanvas; - procedure WMPaint(var Message: TWMPaint); message WM_PAINT; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - property TextHint: ThtString read FTextHint write FTextHint; -{$endif} - end; - - ThtComboBox = class({$ifdef UseTNT} TTntComboBox {$else} TComboBox {$endif}) -{$ifndef TComboBoxHasTextHint} - private - FTextHint: ThtString; - FCanvas : TControlCanvas; - procedure WMPaint(var Message: TWMPaint); message WM_PAINT; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - property TextHint: ThtString read FTextHint write FTextHint; -{$endif} - end; - - {Hack solution based on: - http://stackoverflow.com/questions/1465845/cuetext-equivalent-for-a-tmemo - } - ThtMemo = class({$ifdef UseTNT} TTntMemo {$else} TMemo {$endif}) - private - FTextHint: TStrings; - FCanvas : TControlCanvas; - FMaxLength : Integer; - procedure SetMaxLength(const AValue: Integer); - procedure WMPaint(var Message: TWMPaint); message WM_PAINT; - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - property TextHint: TStrings read FTextHint {write FTextHint}; // BG, 29.07.2013: "write FTextHint" would produce memory leaks!!! - property MaxLength: Integer read FMaxLength write SetMaxLength; - end; - -{$ifdef UseTNT} - ThtButton = TTntButton; - ThtMemoBase = TTntMemo; - ThtListbox = TTntListBox; - ThtCheckBox = TTntCheckBox; - ThtRadioButton = TTntRadioButton; - ThtHintWindow = TTntHintWindow; -{$else} - ThtButton = TBitBtn; //BG, 25.12.2010: TBitBtn uses correct charset, but TButton does not. - ThtListbox = TListbox; - ThtCheckBox = TCheckBox; - ThtRadioButton = TRadioButton; - ThtHintWindow = THintWindow; -{$endif} - -{$ifdef HasSystemUITypes} - ThtScrollStyle = System.UITypes.TScrollStyle; -{$else} - ThtScrollStyle = TScrollStyle; -{$endif} - - //BG, 10.12.2010: don't add virtual methods or fields. It is only used to access protected stuff of TCanvas. - ThtCanvas = class(TCanvas) - public - procedure htTextRect(const Rect: TRect; X, Y: Integer; const Text: ThtString); - end; - - ThtGraphic = class(TGraphic) -{$ifdef LCL} - private - FTransparent: Boolean; - protected - function GetTransparent: Boolean; override; - procedure SetTransparent(Value: Boolean); override; -{$endif} - end; - - { ThtBitmap } - - ThtBitmap = class(TBitmap) - private - procedure SetMask(AValue: TBitmap); - function GetMask: TBitmap; - procedure SetTransparentMask(AValue: Boolean); - protected - FMask: TBitmap; - FTransparent: boolean; - public - constructor Create(WithTransparentMask: Boolean = False); overload; - destructor Destroy; override; - procedure Assign(Source: TPersistent); override; - procedure Draw(ACanvas: TCanvas; const Rect: TRect); override; - procedure StretchDraw(ACanvas: TCanvas; const DestRect, SrcRect: TRect); - property Mask: TBitmap read GetMask write SetMask; - property WithTransparentMask: Boolean read FTransparent write SetTransparentMask; - end; - -const - EofChar = ThtChar(#0); - TabChar = ThtChar(#9); - LfChar = ThtChar(#10); - FfChar = ThtChar(#12); - CrChar = ThtChar(#13); - SpcChar = ThtChar(' '); - DotChar = ThtChar('.'); - LessChar = ThtChar('<'); - MinusChar = ThtChar('-'); - GreaterChar = ThtChar('>'); - PercentChar = ThtChar('%'); - AmperChar = ThtChar('&'); - StarChar = ThtChar('*'); - CrLf = ThtString(#13#10); - CrLfTab = ThtString(#13#10#9); - NullRect: TRect = (Left: 0; Top: 0; Right: 0; Bottom: 0); - -{$ifdef MSWindows} - FontSerif = ThtString('Times New Roman'); - FontMono = ThtString('Courier New'); - FontSans = ThtString('Arial'); - FontCursive = ThtString('Lucida Handwriting'); - FontHelvet = ThtString('Arial'); -{$endif} -{$ifdef Linux} - FontSerif = ThtString('Serif'); - FontMono = ThtString('Monospace'); - FontSans = ThtString('Sans'); - FontHelvet = ThtString('Sans'); - FontCursive = ThtString('Sans'); -{$endif} - -{$ifdef LCL} -const - HWND_MESSAGE = HWND(-3); - - //ANSI_CHARSET = 0; // ANSI charset (Windows-1252) - //DEFAULT_CHARSET = 1; - //SYMBOL_CHARSET = 2; - MAC_CHARSET = 77; - //SHIFTJIS_CHARSET = 128; // Shift JIS charset (Windows-932) - //HANGEUL_CHARSET = 129; // Hangeul charset (Windows-949) - JOHAB_CHARSET = 130; // Johab charset (Windows-1361) - //GB2312_CHARSET = 134; // GB2312 charset (Windows-936) - //CHINESEBIG5_CHARSET = 136; // Chinese Big5 charset (Windows-950) - //GREEK_CHARSET = 161; // Greek charset (Windows-1253) - //TURKISH_CHARSET = 162; // Turkish charset (Windows-1254) - VIETNAMESE_CHARSET = 163; // Vietnamese charset (Windows-1258) - //HEBREW_CHARSET = 177; // Hebrew charset (Windows-1255) - //ARABIC_CHARSET = 178; // Arabic charset (Windows-1256) - //BALTIC_CHARSET = 186; // Baltic charset (Windows-1257) - //RUSSIAN_CHARSET = 204; // Cyrillic charset (Windows-1251) - //THAI_CHARSET = 222; // Thai charset (Windows-874) - //EASTEUROPE_CHARSET = 238; // Eastern european charset (Windows-1250) - //OEM_CHARSET = 255; - -const - { Global Memory Flags } - - GMEM_FIXED = 0; - {$EXTERNALSYM GMEM_FIXED} - GMEM_MOVEABLE = 2; - {$EXTERNALSYM GMEM_MOVEABLE} - GMEM_NOCOMPACT = $10; - {$EXTERNALSYM GMEM_NOCOMPACT} - GMEM_NODISCARD = $20; - {$EXTERNALSYM GMEM_NODISCARD} - GMEM_ZEROINIT = $40; - {$EXTERNALSYM GMEM_ZEROINIT} - GMEM_MODIFY = $80; - {$EXTERNALSYM GMEM_MODIFY} - GMEM_DISCARDABLE = $100; - {$EXTERNALSYM GMEM_DISCARDABLE} - GMEM_NOT_BANKED = $1000; - {$EXTERNALSYM GMEM_NOT_BANKED} - GMEM_SHARE = $2000; - {$EXTERNALSYM GMEM_SHARE} - GMEM_DDESHARE = $2000; - {$EXTERNALSYM GMEM_DDESHARE} - GMEM_NOTIFY = $4000; - {$EXTERNALSYM GMEM_NOTIFY} - GMEM_LOWER = GMEM_NOT_BANKED; - {$EXTERNALSYM GMEM_LOWER} - GMEM_VALID_FLAGS = 32626; - {$EXTERNALSYM GMEM_VALID_FLAGS} - GMEM_INVALID_HANDLE = $8000; - {$EXTERNALSYM GMEM_INVALID_HANDLE} - - GHND = GMEM_MOVEABLE or GMEM_ZEROINIT; - {$EXTERNALSYM GHND} - GPTR = GMEM_FIXED or GMEM_ZEROINIT; - {$EXTERNALSYM GPTR} - - // device caps - {$EXTERNALSYM SHADEBLENDCAPS} - SHADEBLENDCAPS = 45; - {$EXTERNALSYM SB_CONST_ALPHA} - SB_CONST_ALPHA = 1; - -{ -const - HeapAllocFlags = GMEM_MOVEABLE; - -type - // missing in unit Graphics - TProgressStage = ( - psStarting, - psRunning, - psEnding - ); -} - -procedure DecodeStream(Input, Output: TStream); - -function PromptForFileName(var AFileName: string; const AFilter: string = ''; - const ADefaultExt: string = ''; const ATitle: string = ''; - const AInitialDir: string = ''; SaveDialog: Boolean = False): Boolean; - -{$else} - -// Open a document with the default application associated with it in the system -function OpenDocument(const APath: ThtString): Boolean; - -{$endif} - -function StartProcess(const ApplicationName, Params: string; ShowWindow: Word = SW_SHOW): Boolean; - -{$ifndef Compiler17_Plus} -type - TBytes = array of byte; -{$endif} - -var - IsWin95: Boolean; - IsWin32Platform: Boolean; {win95, 98, ME} - ColorBits: Byte; - ThePalette: HPalette; {the rainbow palette for 256 colors} - PalRelative: integer; - -const -{DarkerColors and LighterColors need to be in the interface section for inlining to work.} - DarkerColors: array [0..255] of Byte = ( - 0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9, - 10, 11, 11, 12, 13, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 19, - 20, 21, 21, 22, 23, 23, 24, 24, 25, 26, 26, 27, 28, 28, 29, 29, - 30, 31, 31, 32, 33, 33, 34, 35, 35, 36, 36, 37, 38, 38, 39, 40, - 40, 41, 41, 42, 43, 43, 44, 45, 45, 46, 46, 47, 48, 48, 49, 50, - 50, 51, 51, 52, 53, 53, 54, 55, 55, 56, 56, 57, 58, 58, 59, 60, - 60, 61, 61, 62, 63, 63, 64, 65, 65, 66, 67, 67, 68, 68, 69, 70, - 70, 71, 72, 72, 73, 73, 74, 75, 75, 76, 77, 77, 78, 78, 79, 80, - 80, 81, 82, 82, 83, 83, 84, 85, 85, 86, 87, 87, 88, 88, 89, 90, - 90, 91, 92, 92, 93, 93, 94, 95, 95, 96, 97, 97, 98, 99, 99, 100, - 100, 101, 102, 102, 103, 104, 104, 105, 105, 106, 107, 107, 108, 109, 109, 110, - 110, 111, 112, 112, 113, 114, 114, 115, 115, 116, 117, 117, 118, 119, 119, 120, - 120, 121, 122, 122, 123, 124, 124, 125, 125, 126, 127, 127, 128, 129, 129, 130, - 131, 131, 132, 132, 133, 134, 134, 135, 136, 136, 137, 137, 138, 139, 139, 140, - 141, 141, 142, 142, 143, 144, 144, 145, 146, 146, 147, 147, 148, 149, 149, 150, - 151, 151, 152, 152, 153, 154, 154, 155, 156, 156, 157, 157, 158, 159, 159, 160 - ); - LighterColors: array [0..255] of Byte = ( - 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135, - 136, 136, 137, 137, 138, 138, 139, 139, 140, 140, 141, 141, 142, 142, 143, 143, - 144, 144, 145, 145, 146, 146, 147, 147, 148, 148, 149, 149, 150, 150, 151, 151, - 152, 152, 153, 153, 154, 154, 155, 155, 156, 156, 157, 157, 158, 158, 159, 159, - 160, 160, 161, 161, 162, 162, 163, 163, 164, 164, 165, 165, 166, 166, 167, 167, - 168, 168, 169, 169, 170, 170, 171, 171, 172, 172, 173, 173, 174, 174, 175, 175, - 176, 176, 177, 177, 178, 178, 179, 179, 180, 180, 181, 181, 182, 182, 183, 183, - 184, 184, 185, 185, 186, 186, 187, 187, 188, 188, 189, 189, 190, 190, 191, 191, - 192, 192, 193, 193, 194, 194, 195, 195, 196, 196, 197, 197, 198, 198, 199, 199, - 200, 200, 201, 201, 202, 202, 203, 203, 204, 204, 205, 205, 206, 206, 207, 207, - 208, 208, 209, 209, 210, 210, 211, 211, 212, 212, 213, 213, 214, 214, 215, 215, - 216, 216, 217, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222, 222, 223, 223, - 224, 224, 225, 225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231, - 232, 232, 233, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239, 239, - 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247, 247, - 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255 - ); - -{$if not declared(CopyPalette)} -{$define CopyPaletteMissing} -function CopyPalette(Palette: HPALETTE): HPALETTE; -{$ifend} - -function TransparentStretchBlt(DstDC: HDC; DstX, DstY, DstW, DstH: Integer; - SrcDC: HDC; SrcX, SrcY, SrcW, SrcH: Integer; MaskDC: HDC; MaskX, - MaskY: Integer): Boolean; - -procedure htAppendChr(var Dest: ThtString; C: ThtChar); {$ifdef UseInline} inline; {$endif} -procedure htAppendStr(var Dest: ThtString; const S: ThtString); {$ifdef UseInline} inline; {$endif} -procedure htSetString(var Dest: ThtString; Chr: PhtChar; Len: Integer); {$ifdef UseInline} inline; {$endif} -function htCompareStr(const S1, S2: ThtString): Integer; {$ifdef UseInline} inline; {$endif} -function htCompareText(const S1, S2: ThtString): Integer; {$ifdef UseInline} inline; {$endif} -function htSameText(const S1, S2: ThtString): Boolean; {$ifdef UseInline} inline; {$endif} -function htLowerCase(const Str: ThtString): ThtString; {$ifdef UseInline} inline; {$endif} -function htTrim(const Str: ThtString): ThtString; {$ifdef UseInline} inline; {$endif} -function htUpperCase(const Str: ThtString): ThtString; {$ifdef UseInline} inline; {$endif} -// htPos(SubStr, S, Offst): find substring in S starting at Offset: (formerly known as PosX) -function htPos(const SubStr, S: ThtString; Offset: Integer = 1): Integer; - -function IsAlpha(Ch: ThtChar): Boolean; {$ifdef UseInline} inline; {$endif} -function IsDigit(Ch: ThtChar): Boolean; {$ifdef UseInline} inline; {$endif} -function RemoveQuotes(const S: ThtString): ThtString; - -function htStringArrayToStr(const StrArray: ThtStringArray; Separator: ThtChar): ThtString; -function htSameStringArray(const A1, A2: ThtStringArray): Boolean; -procedure htSortStringArray(A: ThtStringArray); - -//{$ifdef UnitConstsMissing} -//const -// SOutOfResources = 'Out of system resources'; -// SInvalidBitmap = 'Bitmap image is not valid'; -// SScanLine = 'Scan line index out of range'; -//{$endif} - -function PtrSub(P1, P2: Pointer): Integer; {$ifdef UseInline} inline; {$endif} -function PtrAdd(P1: Pointer; Offset: Integer): Pointer; {$ifdef UseInline} inline; {$endif} -procedure PtrInc(var P1; Offset: Integer); {$ifdef UseInline} inline; {$endif} - -// BG, 17.04.2013: Color of Darker() and Lighter() must be RGB or palette values. Themed or system colors are not supported! -function Darker(Color : TColor): TColor; {$ifdef UseInline} inline; {$endif} -function Lighter(Color : TColor): TColor; {$ifdef UseInline} inline; {$endif} - -//code movements from HTMLSubs -function FindSpaces(PStart : PWideChar; const ACount : Integer) : Integer; {$ifdef UseInline} inline; {$endif} -procedure InitFullBg(var FullBG : vcl.Graphics.TBitmap; const W, H: Integer; const AIsCopy : Boolean); {$ifdef UseInline} inline; {$endif} -procedure Circle(ACanvas : TCanvas; const X, Y, Rad: Integer); {$ifdef UseInline} inline; {$endif} - -//alpha blend determination for Printers only -function CanPrintAlpha(ADC : HDC) : Boolean; {$ifdef UseInline} inline; {$endif} - -procedure GetTSize(DC: HDC; P : PWideChar; N : Integer; out VSize : TSize); {$ifdef UseInline} inline; {$endif} - -function ThemedColor(const AColor : TColor - {$ifdef has_StyleElements};const AUseThemes : Boolean{$endif} - ): TColor; {$ifdef UseInline} inline; {$endif} //overload; - -function TextEndsWith(const SubStr, S : ThtString) : Boolean; {$ifdef UseInline} inline; {$endif} -function TextStartsWith(const SubStr, S : ThtString) : Boolean; {$ifdef UseInline} inline; {$endif} - -procedure CopyToClipBoardAsHtml(const Str: UTF8String); -procedure CopyToClipBoardAsText(const Str: ThtString); - -implementation - -{$ifndef TEditHasTextHint} -constructor ThtEdit.Create(AOwner: TComponent); -begin - inherited; - FCanvas := TControlCanvas.Create; -// FTextHintFont := TFont.Create; -// FTextHintFont.Color := clGrayText; - FCanvas.Control := Self; -end; - -destructor ThtEdit.Destroy; -begin -// FreeAndNil(FTextHintFont); - FreeAndNil(FCanvas); - inherited; -end; - -procedure ThtEdit.WMPaint(var Message: TWMPaint); -begin - inherited; - if (Text = '') and (not Focused) then - begin - FCanvas.Handle := Message.DC; - FCanvas.Font := Font;//FTextHintFont; - FCanvas.Font.Color := clGrayText; - FCanvas.TextOut(1, 1, FTextHint); - end; -end; -{$endif} - -{$ifndef TComboBoxHasTextHint} -constructor ThtComboBox.Create(AOwner: TComponent); -begin - inherited; - FCanvas := TControlCanvas.Create; -// FTextHintFont := TFont.Create; -// FTextHintFont.Color := clGrayText; - FCanvas.Control := Self; -end; - -destructor ThtComboBox.Destroy; -begin -// FreeAndNil(FTextHintFont); - FreeAndNil(FCanvas); - inherited; -end; - -procedure ThtComboBox.WMPaint(var Message: TWMPaint); -begin - inherited; - if (Text = '') and (not Focused) then - begin - FCanvas.Handle := Message.DC; - FCanvas.Font := Font;//FTextHintFont; - FCanvas.Font.Color := clGrayText; - FCanvas.TextOut(1, 1, FTextHint); - end; -end; -{$endif} - -constructor THtMemo.Create(AOwner: TComponent); -begin - inherited; - FTextHint := TStringList.Create; - FCanvas := TControlCanvas.Create; -// FTextHintFont := TFont.Create; -// FTextHintFont.Color := clGrayText; - TControlCanvas(FCanvas).Control := Self; - FMaxLength := 0; -end; - -destructor THtMemo.Destroy; -begin -// FreeAndNil(FTextHintFont); - FreeAndNil(FCanvas); - FTextHint.Clear; - FreeAndNil(FTextHint); - inherited; -end; - -procedure THtMemo.WMPaint(var Message: TWMPaint); -Var - i : integer; - TextHeight : Integer; -begin - inherited; - if (Text = '') and (not Focused) then - begin - FCanvas.Handle := Message.DC; - FCanvas.Font := Font;//FTextHintFont; - FCanvas.Font.Color := clGrayText; - TextHeight := FCanvas.TextHeight('MLZ'); //Dummy Text to determine Height - for i := 0 to FTextHint.Count - 1 do - FCanvas.TextOut(1, 1+(i*TextHeight), FTextHint[i]); - end; -end; - -procedure THtMemo.SetMaxLength(const AValue : Integer); -begin - if AValue <> FMaxLength then begin - FMaxLength := AValue; - SendMessage(Handle, EM_LIMITTEXT, AValue, 0); - end; -end; - -{$ifdef has_StyleElements} -function ThemedColor(const AColor : TColor; const AUseThemes : Boolean): TColor; {$ifdef UseInline} inline; {$endif} overload; -begin - if AUseThemes and TStyleManager.IsCustomStyleActive then begin - Result := StyleServices.GetSystemColor(AColor); - end else begin - Result := AColor; - end; - Result := ColorToRGB(Result); -end; -{$else} - -function ThemedColor(const AColor : TColor): TColor; - {$ifdef UseInline} inline; {$endif} -begin -{$ifdef UseVCLStyles} - if TStyleManager.IsCustomStyleActive then begin - Result := StyleServices.GetSystemColor(AColor); - end else begin - Result := AColor; - end; - Result := ColorToRGB(Result); -{$else} - Result := ColorToRGB(AColor); -{$endif} -end; -{$endif} - -procedure GetTSize(DC: HDC; P : PWideChar; N : Integer; out VSize : TSize); - {$ifdef UseInline} inline; {$endif} -var - Dummy: Integer; -begin - VSize.cx := 0; - VSize.cy := 0; - if not IsWin32Platform then - GetTextExtentExPointW(DC, P, N, 0, @Dummy, nil, VSize) - else - GetTextExtentPoint32W(DC, P, N, VSize); {win95, 98 ME} -end; - -function CanPrintAlpha(ADC : HDC) : Boolean; {$ifdef UseInline} inline; {$endif} -begin - Result := GetDeviceCaps(ADC,SHADEBLENDCAPS) and SB_CONST_ALPHA > 0; -end; - -function Darker(Color : TColor): TColor; {$ifdef UseInline} inline; {$endif} - {find a somewhat darker color for shading purposes} -var - Red, Green, Blue: Byte; -begin - Result := ColorToRGB(Color); //ThemedColor(Color{$ifdef has_StyleElements},AUseThemes{$endif}); - Red := DarkerColors[Byte(Result )]; - Green := DarkerColors[Byte(Result shr 8)]; - Blue := DarkerColors[Byte(Result shr 16)]; - Result := RGB(Red, Green, Blue); -end; - -function Lighter(Color : TColor) : TColor; {$ifdef UseInline} inline; {$endif} -{find a somewhat lighter color for shading purposes} -var - Red, Green, Blue: Byte; -begin - Result := ColorToRGB(Color); // ThemedColor(Color{$ifdef has_StyleElements},AUseThemes{$endif}); - Red := LighterColors[Byte(Result )]; - Green := LighterColors[Byte(Result shr 8)]; - Blue := LighterColors[Byte(Result shr 16)]; - Result := RGB(Red, Green, Blue); -end; - -function FindSpaces(PStart : PWideChar; const ACount : Integer) : Integer; - {$ifdef UseInline} inline; {$endif} -var - I: Integer; -begin - Result := 0; - for I := 0 to ACount - 2 do {-2 so as not to count end spaces} - if ((PStart + I)^ = ' ') or ((PStart + I)^ = #160) then - Inc(Result); -end; - -procedure InitFullBg(var FullBG : vcl.Graphics.TBitmap; const W, H: Integer; const AIsCopy : Boolean); - {$ifdef UseInline} inline; {$endif} -begin - if not Assigned(FullBG) then - begin - FullBG := vcl.Graphics.TBitmap.Create; - if AIsCopy then - begin - FullBG.HandleType := bmDIB; - if ColorBits <= 8 then - FullBG.Palette := CopyPalette(ThePalette); - end; - end; - FullBG.Width := Max(W,2); - FullBG.Height := Max(H,2); -end; - -procedure Circle(ACanvas : TCanvas; const X, Y, Rad: Integer); - {$ifdef UseInline} inline; {$endif} -begin - ACanvas.Ellipse(X, Y - Rad, X + Rad, Y); -end; - -//-- BG ------------------------------------------------------------------------ -function PtrSub(P1, P2: Pointer): Integer; - {$ifdef UseInline} inline; {$endif} -begin -{$ifdef FPC} - Result := P1 - P2; -{$else} - Result := PAnsiChar(P1) - PAnsiChar(P2); -{$endif} -end; - -//-- BG ------------------------------------------------------------------------ -function PtrAdd(P1: Pointer; Offset: Integer): Pointer; - {$ifdef UseInline} inline; {$endif} -begin -{$ifdef FPC} - Result := P1 + Offset; -{$else} - Result := PAnsiChar(P1) + Offset; -{$endif} -end; - -//-- BG ------------------------------------------------------------------------ -procedure PtrInc(var P1; Offset: Integer); - {$ifdef UseInline} inline; {$endif} -begin -{$ifdef FPC} - Inc(PAnsiChar(P1), Offset); -{$else} - Inc(PAnsiChar(P1), Offset); -{$endif} -end; - -procedure CalcPalette(DC: HDC); - {$ifdef UseInline} inline; {$endif} -{calculate a rainbow palette, one with equally spaced colors} -const - Values: array[0..5] of integer = (55, 115, 165, 205, 235, 255); -var - LP: ^TLogPalette; - I, J, K, Sub: integer; -begin - GetMem(LP, Sizeof(TLogPalette) + 256 * Sizeof(TPaletteEntry)); - try - with LP^ do - begin - palVersion := $300; - palNumEntries := 256; - GetSystemPaletteEntries(DC, 0, 256, palPalEntry); - Sub := 10; {start at entry 10} - for I := 0 to 5 do - for J := 0 to 5 do - for K := 0 to 5 do - if not ((I = 5) and (J = 5) and (K = 5)) then {skip the white} - with palPalEntry[Sub] do - begin - peBlue := Values[I]; - peGreen := Values[J]; - peRed := Values[K]; - peFlags := 0; - Inc(Sub); - end; - for I := 1 to 24 do - if not (I in [7, 15, 21]) then {these would be duplicates} - with palPalEntry[Sub] do - begin - peBlue := 130 + 5 * I; - peGreen := 130 + 5 * I; - peRed := 130 + 5 * I; - peFlags := 0; - Inc(Sub); - end; - Sub := 245; - with palPalEntry[Sub] do - begin - peBlue := 254; - peGreen := 255; - peRed := 255; - peFlags := 0; - end; - ThePalette := CreatePalette(LP^); - end; - finally - FreeMem(LP, Sizeof(TLogPalette) + 256 * Sizeof(TPaletteEntry)); - end; -end; - -{$ifdef CopyPaletteMissing} -// ----------- -// CopyPalette -// ----------- -// Copies a HPALETTE. -// -// Copied from D3 graphics.pas. This is declared private in some old versions -// of Delphi 2 and is missing in Lazarus Component Library (LCL), so we have -// to implement it here to support those versions. -// -// Parameters: -// Palette The palette to copy. -// -// Returns: -// The handle to a new palette. -// -function CopyPalette(Palette: HPALETTE): HPALETTE; - {$ifdef UseInline} inline; {$endif} -var - PaletteSize: Integer; - LogPal: TMaxLogPalette; -begin - Result := 0; - if Palette = 0 then Exit; - PaletteSize := 0; - if GetObject(Palette, SizeOf(PaletteSize), @PaletteSize) = 0 then Exit; - if PaletteSize = 0 then Exit; - with LogPal do - begin - palVersion := $0300; - palNumEntries := PaletteSize; - GetPaletteEntries(Palette, 0, PaletteSize, palPalEntry); - end; - Result := CreatePalette(PLogPalette(@LogPal)^); -end; -{$endif CopyPaletteMissing} - -const - SOutOfResources = 'Out of system resources'; -var - SystemPalette16: HPalette; // 16 color palette that maps to the system palette - -procedure OutOfResources; -begin - raise EOutOfResources.Create(SOutOfResources); -end; - -procedure GDIError; -{$ifndef LCL} -var - ErrorCode: Integer; - Buf: array [Byte] of Char; -begin - ErrorCode := GetLastError; - if (ErrorCode <> 0) and (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nil, - ErrorCode, LOCALE_USER_DEFAULT, Buf, sizeof(Buf), nil) <> 0) then - raise EOutOfResources.Create(Buf) - else -{$else} -begin -{$endif} - OutOfResources; -end; - -function GDICheck(Value: PtrUInt): PtrUInt; -begin - if Value = 0 then GDIError; - Result := Value; -end; - -function TransparentStretchBlt(DstDC: HDC; DstX, DstY, DstW, DstH: Integer; - SrcDC: HDC; SrcX, SrcY, SrcW, SrcH: Integer; MaskDC: HDC; MaskX, - MaskY: Integer): Boolean; -const - ROP_DstCopy = $00AA0029; -var - MemDC: HDC; - MemBmp: HBITMAP; - SaveObj: HGDIOBJ; - crText, crBack: TColorRef; - SavePal: HPALETTE; -begin - Result := True; -{$ifdef MSWindows} - if (Win32Platform = VER_PLATFORM_WIN32_NT) and (SrcW = DstW) and (SrcH = DstH) then - begin - MemBmp := GDICheck(CreateCompatibleBitmap(SrcDC, 1, 1)); - MemBmp := SelectObject(MaskDC, MemBmp); - try - MaskBlt( - DstDC, DstX, DstY, DstW, DstH, - SrcDC, SrcX, SrcY, - MemBmp, MaskX, MaskY, - MakeRop4(ROP_DstCopy, SrcCopy)); - finally - MemBmp := SelectObject(MaskDC, MemBmp); - DeleteObject(MemBmp); - end; - Exit; - end; -{$endif} - MemDC := GDICheck(CreateCompatibleDC(DstDC)); - try - MemBmp := GDICheck(CreateCompatibleBitmap(SrcDC, SrcW, SrcH)); - SaveObj := SelectObject(MemDC, MemBmp); - SavePal := SelectPalette(SrcDC, SystemPalette16, False); - try - SelectPalette(SrcDC, SavePal, False); - if SavePal <> 0 then - SavePal := SelectPalette(MemDC, SavePal, True) - else - SavePal := SelectPalette(MemDC, SystemPalette16, True); - RealizePalette(MemDC); - - { Mask out the transparent colored pixels of the source } - BitBlt(MemDC, 0, 0, SrcW, SrcH, MaskDC, MaskX, MaskY, SrcCopy); - BitBlt(MemDC, 0, 0, SrcW, SrcH, SrcDC, SrcX, SrcY, SrcErase); - - { Punch out a black hole in the background where the source image will go} - crText := SetTextColor(DstDC, $0); - crBack := SetBkColor(DstDC, $FFFFFF); - StretchBlt(DstDC, DstX, DstY, DstW, DstH, MaskDC, MaskX, MaskY, SrcW, SrcH, SrcAnd); - SetTextColor(DstDC, crText); - SetBkColor(DstDC, crBack); - - StretchBlt(DstDC, DstX, DstY, DstW, DstH, MemDC, 0, 0, SrcW, SrcH, SrcInvert); - finally - SelectPalette(MemDC, SavePal, False); - SelectObject(MemDC, SaveObj); - DeleteObject(MemBmp); - end; - finally - DeleteDC(MemDC); - end; -end; - -//-- BG ---------------------------------------------------------- 27.03.2011 -- -procedure htAppendChr(var Dest: ThtString; C: ThtChar); - {$ifdef UseInline} inline; {$endif} -begin - SetLength(Dest, Length(Dest) + 1); - Dest[Length(Dest)] := C; -end; - -//-- BG ---------------------------------------------------------- 27.03.2011 -- -procedure htAppendStr(var Dest: ThtString; const S: ThtString); - {$ifdef UseInline} inline; {$endif} -var - L, N: Integer; -begin - L := Length(S); - if L > 0 then - begin - N := Length(Dest); - SetLength(Dest, N + L); - Move(S[1], Dest[N + 1], L * sizeof(ThtChar)); - end; -end; - -//-- BG ---------------------------------------------------------- 20.03.2011 -- -function htCompareStr(const S1, S2: ThtString): Integer; - {$ifdef UseInline} inline; {$endif} -begin -{$ifdef UNICODE} - Result := CompareStr(S1, S2); -{$else} - Result := WideCompareStr(S1, S2); -{$endif} -end; - -//-- BG ---------------------------------------------------------- 10.12.2010 -- -function htCompareText(const S1, S2: ThtString): Integer; - {$ifdef UseInline} inline; {$endif} -begin -{$ifdef UNICODE} - Result := CompareText(S1, S2); -{$else} - Result := WideCompareText(S1, S2); -{$endif} -end; - -//-- BG ---------------------------------------------------------- 10.10.2016 -- -function htSameText(const S1, S2: ThtString): Boolean; - {$ifdef UseInline} inline; {$endif} -begin - Result := htCompareText(S1, S2) = 0; -end; - -//-- BG ---------------------------------------------------------- 22.10.2016 -- -function htStringArrayToStr(const StrArray: ThtStringArray; Separator: ThtChar): ThtString; -var - I: Integer; -begin - SetLength(Result, 0); - for I := Low(StrArray) to high(StrArray) do - begin - if Length(Result) > 0 then - htAppendChr(Result, Separator); - htAppendStr(Result, StrArray[I]); - end; -end; - -//-- BG ---------------------------------------------------------- 20.03.2011 -- -function htSameStringArray(const A1, A2: ThtStringArray): Boolean; -var - I, N: Integer; -begin - N := Length(A1); - Result := N = Length(A2); - if Result then - for I := 0 To N - 1 do - if htCompareStr(A1[I], A2[I]) <> 0 then - begin - Result := False; - break; - end; -end; - -//-- BG ---------------------------------------------------------- 20.03.2011 -- -procedure htSortStringArray(A: ThtStringArray); - - procedure QuickSort(L, R: Integer); - var - I, J: Integer; - P, T: ThtString; - begin - repeat - I := L; - J := R; - P := A[(L + R) shr 1]; - repeat - while htCompareStr(A[I], P) < 0 do - Inc(I); - while htCompareStr(A[J], P) > 0 do - Dec(J); - if I <= J then - begin - T := A[I]; - A[I] := A[J]; - A[J] := T; - Inc(I); - Dec(J); - end; - until I > J; - if L < J then - QuickSort(L, J); - L := I; - until I >= R; - end; - -begin - if length(A) > 1 then - QuickSort(Low(A), High(A)); -end; - -//-- BG ---------------------------------------------------------- 28.01.2011 -- -function htLowerCase(const Str: ThtString): ThtString; - {$ifdef UseInline} inline; {$endif} -begin -{$ifdef UNICODE} - // LowerCase() converts 7bit chars only while AnsiLowerCase() converts UnicodeStrings correctly. - // Actually it does the same as we do in the $else part except for Linux. - Result := AnsiLowerCase(Str); -{$else} - Result := WideLowerCase(Str); -{$endif} -end; - -//-- BG ---------------------------------------------------------- 27.03.2011 -- -procedure htSetString(var Dest: ThtString; Chr: PhtChar; Len: Integer); - {$ifdef UseInline} inline; {$endif} -begin -{$ifdef UNICODE} - SetString(Dest, Chr, Len); -{$else} - SetLength(Dest, Len); - Move(Chr^, Dest[1], Len * sizeof(ThtChar)); -{$endif} -end; - -//-- BG ---------------------------------------------------------- 09.08.2011 -- -function htTrim(const Str: ThtString): ThtString; - {$ifdef UseInline} inline; {$endif} -begin - Result := Trim(Str); -end; - -//-- BG ---------------------------------------------------------- 28.01.2011 -- -function htUpperCase(const Str: ThtString): ThtString; - {$ifdef UseInline} inline; {$endif} -begin - {$ifdef UNICODE} - // UpperCase() converts 7bit chars only while AnsiUpperCase() converts UnicodeStrings correctly. - // Actually it does the same as we do in the $else part except for Linux. - Result := AnsiUpperCase(Str); - {$else} - Result := WideUpperCase(Str); - {$endif} -end; - -//-- BG ---------------------------------------------------------- 21.08.2011 -- -function IsAlpha(Ch: ThtChar): Boolean; {$ifdef UseInline} inline; {$endif} -begin - case Ch of - 'a'..'z', 'A'..'Z': - Result := True; - else - Result := False; - end; -end; - -//-- BG ---------------------------------------------------------- 21.08.2011 -- -function IsDigit(Ch: ThtChar): Boolean; {$ifdef UseInline} inline; {$endif} -begin - case Ch of - '0'..'9': - Result := True; - else - Result := False; - end; -end; - -{----------------RemoveQuotes} - -function RemoveQuotes(const S: ThtString): ThtString; - {$ifdef UseInline} inline; {$endif} -{if ThtString is a quoted ThtString, remove the quotes (either ' or ")} -begin - Result := S; - if Length(Result) >= 2 then - begin - case Result[1] of - '"', '''': - if Result[Length(Result)] = Result[1] then - Result := Copy(Result, 2, Length(Result) - 2); - end; - end; -end; - -function htPos(const SubStr, S: ThtString; Offset: Integer = 1): Integer; - {$ifdef UseInline} inline; {$endif} -{find substring in S starting at Offset} -var - S1: ThtString; - I: Integer; -begin - if Offset <= 1 then - Result := Pos(SubStr, S) - else - begin - S1 := Copy(S, Offset, Length(S) - Offset + 1); - I := Pos(SubStr, S1); - if I > 0 then - Result := I + Offset - 1 - else - Result := 0; - end; -end; - -function TextStartsWith(const SubStr, S : ThtString) : Boolean; - {$ifdef UseInline} inline; {$endif} -begin - Result := Copy(S,1,Length(SubStr)) = SubStr; -end; - -function TextEndsWith(const SubStr, S : ThtString) : Boolean; - {$ifdef UseInline} inline; {$endif} -var l : Integer; -begin - l := Length(SubStr); - Result := Copy(S,Length(S)-l+1,l) = SubStr; -end; - -{ ThtEdit } - -procedure ThtEdit.KeyDown(var Key: Word; Shift: TShiftState); -begin - if (Key = Ord('A')) and ([ssCtrl] = Shift) then - SelectAll; -end; - -{ ThtCanvas } - -procedure ThtCanvas.htTextRect(const Rect: TRect; X, Y: Integer; const Text: ThtString); -{$ifdef LCL} -{$else} -var - Options: Longint; -{$endif LCL} -begin -{$ifdef LCL} - inherited TextRect(Rect, X, Y, Utf8Encode(Text)); -{$else} - Changing; - RequiredState([csHandleValid, csFontValid, csBrushValid]); - Options := ETO_CLIPPED or TextFlags; - if Brush.Style <> bsClear then - Options := Options or ETO_OPAQUE; - if ((TextFlags and ETO_RTLREADING) <> 0) and - (CanvasOrientation = coRightToLeft) then Inc(X, TextWidth(Text) + 1); - Windows.ExtTextOutW(Handle, X, Y, Options, @Rect, PWideChar(Text), Length(Text), nil); - Changed; -{$endif LCL} -end; - -{$ifdef LCL} - -procedure DecodeStream(Input, Output: TStream); -const - BufferSize = 999; -var - Decoder: TBase64DecodingStream; - Buffer: array[1..BufferSize] of Byte; - Count: LongInt; - I, J: Integer; -begin - I := 0; - J := 0; - Decoder := TBase64DecodingStream.Create(Input, bdmMIME); - try - Decoder.Reset; - repeat - Count := Decoder.Read(Buffer[1], BufferSize); - Output.Write(Buffer[1], Count); - Inc(I); - Inc(J, Count); - until Count < BufferSize; - finally - Decoder.Free; - end; -end; - -function PromptForFileName(var AFileName: string; const AFilter: string = ''; - const ADefaultExt: string = ''; const ATitle: string = ''; - const AInitialDir: string = ''; SaveDialog: Boolean = False): Boolean; -var - Dialog: TOpenDialog; -begin - if SaveDialog then - begin - Dialog := TSaveDialog.Create(nil); - Dialog.Options := Dialog.Options + [ofOverwritePrompt]; - end - else - Dialog := TOpenDialog.Create(nil); - with Dialog do - try - Title := ATitle; - if Length(Title) = 0 then - if SaveDialog then - Title := 'Select Filename' - else - Title := 'Select File'; - Filter := AFilter; - if Length(Filter) = 0 then - Filter := 'Any File (*.*)|*.*'; - DefaultExt := ADefaultExt; - InitialDir := AInitialDir; - FileName := AFileName; - Result := Execute; - if Result then - AFileName := FileName; - finally - Free; - end; -end; - -{$else} - -// Open a document with the default application associated with it in the system -function OpenDocument(const APath: ThtString): Boolean; -begin - Result := ShellExecuteW(0, nil, PWideChar(APath), nil, nil, SW_SHOWNORMAL) > 32; -end; - -{$endif LCL} - -function StartProcess(const ApplicationName, Params: string; ShowWindow: Word): Boolean; -{$ifdef LCL} -var - Process: TProcess; - I: Integer; -begin - // uses TProcess although Lazarus documentation prefers RunCommand - // as RunCommand does not start an asynchronous process. - Process := TProcess.Create(nil); - try - Process.Executable := ApplicationName; - Process.Parameters.Add(Params); - Process.InheritHandles := False; - Process.ShowWindow := swoShow; - - // Copy default environment variables - // including DISPLAY variable for GUI application to work - for I := 1 to GetEnvironmentVariableCount do - Process.Environment.Add(GetEnvironmentString(I)); - - Process.Execute; - Result := True; - finally - Process.Free; - end; -end; -{$else} -var - si: TStartupInfo; - pi: TProcessInformation; - CommandLine: string; -begin - FillMemory(@si, SizeOf(si), 0); - FillMemory(@pi, SizeOf(pi), 0); - si.cb := SizeOf(si); - si.dwFlags := STARTF_USESHOWWINDOW; - si.wShowWindow := ShowWindow; - CommandLine := ApplicationName; - if Pos(' ', CommandLine) > 0 then - CommandLine := '"' + CommandLine + '"'; - if Length(Params) > 0 then - CommandLine := CommandLine + ' ' + Params; - UniqueString(CommandLine); - Result := CreateProcess(PChar(ApplicationName), PChar(CommandLine), nil, nil, False, 0, nil, nil, si, pi); - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); -end; -{$endif} - -//-- BG ---------------------------------------------------------- 26.09.2016 -- -procedure CopyToClipBoardAsHtml(const Str: UTF8String); -// Put SOURCE on the clipboard, using FORMAT as the clipboard format -const - HtmlClipboardFormat = 'HTML Format'; -var - CF_HTML: UINT; - Len: Integer; -{$ifdef LCL} - Str1: UTF8String; -{$else} - Mem: HGLOBAL; - Buf: PAnsiChar; -{$endif} -begin - CF_HTML := RegisterClipboardFormat(HtmlClipboardFormat); {not sure this is necessary} - Len := Length(Str); -{$ifdef LCL} - Str1 := Str; - Clipboard.AddFormat(CF_HTML, Str1[1], Len); -{$else} - Mem := GlobalAlloc(GMEM_DDESHARE + GMEM_MOVEABLE, Len + 1); - try - Buf := GlobalLock(Mem); - try - Move(Str[1], Buf[0], Len); - Buf[Len] := #0; - SetClipboardData(CF_HTML, Mem); - finally - GlobalUnlock(Mem); - end; - except - GlobalFree(Mem); - end; -{$endif} -end; - -//-- BG ---------------------------------------------------------- 26.09.2016 -- -procedure CopyToClipboardAsText(const Str: ThtString); -{$ifdef LCL} -var - Utf8: Utf8String; -begin - Utf8 := Utf8Encode(Str); - Clipboard.AsText := Utf8; -end; -{$else} -var - Len: Integer; - Mem: HGLOBAL; - Wuf: PWideChar; -begin - Len := Length(Str); - Mem := GlobalAlloc(GMEM_DDESHARE + GMEM_MOVEABLE, (Len + 1) * SizeOf(WideChar)); - try - Wuf := GlobalLock(Mem); - try - Move(Str[1], Wuf[0], Len * SizeOf(WideChar)); - Wuf[Len] := #0; - // BG, 28.06.2012: use API method. The vcl clipboard does not support multiple formats. - SetClipboardData(CF_UNICODETEXT, Mem); - finally - GlobalUnlock(Mem); - end; - except - GlobalFree(Mem); - end; -end; -{$endif} - -{ ThtGraphic } - -{$ifdef LCL} -//-- BG ---------------------------------------------------------- 10.10.2016 -- -function ThtGraphic.GetTransparent: Boolean; -begin - Result := FTransparent; -end; - -//-- BG ---------------------------------------------------------- 10.10.2016 -- -procedure ThtGraphic.SetTransparent(Value: Boolean); -begin - if FTransparent <> Value then - begin - FTransparent := Value; - Changed(Self); - end; -end; -{$endif} - -{ ThtBitmap } - -function ThtBitmap.GetMask: TBitmap; -{This returns mask for frame 1. Content is black, background is white} -begin - if not FTransparent then - Result := nil - else - Result := FMask; -end; - -procedure ThtBitmap.SetTransparentMask(AValue: Boolean); -begin - if FTransparent <> AValue then - begin - FTransparent := AValue; - if not FTransparent then - FreeAndNil(FMask) - else if FMask = nil then - begin - FMask := ThtBitmap.Create; - FMask.TransparentMode := tmFixed; - FMask.TransparentColor := clNone; - end; - end; -end; - -constructor ThtBitmap.Create(WithTransparentMask: Boolean); -begin - inherited Create; - SetTransparentMask( WithTransparentMask ); -end; - -procedure ThtBitmap.Assign(Source: TPersistent); -var - htSource: ThtBitmap absolute Source; -begin - {$ifdef LCL} - // LCL didn't copy PixelFormat before SVN-33344 (2011-11-05) - if Source is TCustomBitmap then - PixelFormat := TCustomBitmap(Source).PixelFormat; - {$endif} - inherited; - if Source is ThtBitmap then - begin - FTransparent := htSource.FTransparent; - SetMask(htSource.FMask); - end; -end; - -destructor ThtBitmap.Destroy; -begin - FMask.Free; - inherited; -end; - -procedure ThtBitmap.SetMask(AValue: TBitmap); -begin - if AValue = nil then - FreeAndNil(FMask) - else - begin - if FMask = nil then - begin - FMask := ThtBitmap.Create; - FMask.TransparentMode := tmFixed; - FMask.TransparentColor := clNone; - end; - FMask.Assign(AValue); - end; -end; - -procedure ThtBitmap.Draw(ACanvas: TCanvas; const Rect: TRect); -{$ifdef LCL} -var - UseMaskHandle: HBitmap; - SrcDC: hDC; - DestDC: hDC; -begin - if (Width=0) or (Height=0) - then Exit; - - BitmapHandleNeeded; - if not BitmapHandleAllocated then Exit; - - if WithTransparentMask then - UseMaskHandle := FMask.Handle - else - UseMaskHandle := 0; - - SrcDC := Canvas.GetUpdatedHandle([csHandleValid]); - ACanvas.Changing; - DestDC := ACanvas.GetUpdatedHandle([csHandleValid]); - StretchMaskBlt( - DestDC, Rect.Left, Rect.Top, Rect.Right - Rect.Left, Rect.Bottom - Rect.Top, - SrcDC, 0, 0, Width, Height, - UseMaskHandle, 0, 0, ACanvas.CopyMode); - ACanvas.Changed; -end; -{$else LCL} -var - OldPalette: HPalette; - RestorePalette: Boolean; - DoHalftone: Boolean; - Pt: TPoint; - BPP: Integer; -begin - with Rect do - begin - PaletteNeeded; - OldPalette := 0; - RestorePalette := False; - - if Palette <> 0 then - begin - OldPalette := SelectPalette(ACanvas.Handle, Palette, True); - RealizePalette(ACanvas.Handle); - RestorePalette := True; - end; - BPP := GetDeviceCaps(ACanvas.Handle, BITSPIXEL) * - GetDeviceCaps(ACanvas.Handle, PLANES); - DoHalftone := (BPP <= 8) and (PixelFormat in [pf15bit, pf16bit, pf24bit]); - if DoHalftone then - begin - GetBrushOrgEx(ACanvas.Handle, pt); - SetStretchBltMode(ACanvas.Handle, HALFTONE); - SetBrushOrgEx(ACanvas.Handle, pt.x, pt.y, @pt); - end - else if not Monochrome then - SetStretchBltMode(ACanvas.Handle, STRETCH_DELETESCANS); - try - if FTransparent then - TransparentStretchBlt( - ACanvas.Handle, Left, Top, Right - Left, Bottom - Top, - Canvas.Handle, 0, 0, Width, Height, - FMask.Canvas.Handle, 0, 0) {LDB} - else - StretchBlt( - ACanvas.Handle, Left, Top, Right - Left, Bottom - Top, - Canvas.Handle, 0, 0, Width, Height, - ACanvas.CopyMode); - finally - if RestorePalette then - SelectPalette(ACanvas.Handle, OldPalette, True); - end; - end; -end; -{$endif LCL} - -procedure ThtBitmap.StretchDraw(ACanvas: TCanvas; const DestRect, SrcRect: TRect); -{Draw parts of this bitmap on ACanvas} -{$ifdef LCL} -var - UseMaskHandle: HBitmap; - SrcDC: hDC; - DestDC: hDC; -begin - if (Width=0) or (Height=0) - then Exit; - - BitmapHandleNeeded; - if not BitmapHandleAllocated then Exit; - - if WithTransparentMask then - UseMaskHandle := FMask.Handle - else - UseMaskHandle := 0; - - SrcDC := Canvas.GetUpdatedHandle([csHandleValid]); - ACanvas.Changing; - DestDC := ACanvas.GetUpdatedHandle([csHandleValid]); - StretchMaskBlt( - DestDC, DestRect.Left, DestRect.Top, DestRect.Right - DestRect.Left, DestRect.Bottom - DestRect.Top, - SrcDC, SrcRect.Left, SrcRect.Top, SrcRect.Right - SrcRect.Left, SrcRect.Bottom - SrcRect.Top, - UseMaskHandle, SrcRect.Left, SrcRect.Top, ACanvas.CopyMode); - ACanvas.Changed; -end; -{$else LCL} -var - OldPalette: HPalette; - RestorePalette: Boolean; - DoHalftone: Boolean; - Pt: TPoint; - BPP: Integer; -begin - with DestRect do - begin - PaletteNeeded; - OldPalette := 0; - RestorePalette := False; - - if Palette <> 0 then - begin - OldPalette := SelectPalette(ACanvas.Handle, Palette, True); - RealizePalette(ACanvas.Handle); - RestorePalette := True; - end; - BPP := GetDeviceCaps(ACanvas.Handle, BITSPIXEL) * - GetDeviceCaps(ACanvas.Handle, PLANES); - DoHalftone := (BPP <= 8) and (PixelFormat in [pf15bit, pf16bit, pf24bit]); - if DoHalftone then - begin - GetBrushOrgEx(ACanvas.Handle, pt); - SetStretchBltMode(ACanvas.Handle, HALFTONE); - SetBrushOrgEx(ACanvas.Handle, pt.x, pt.y, @pt); - end - else if not Monochrome then - SetStretchBltMode(ACanvas.Handle, STRETCH_DELETESCANS); - try - if FTransparent then - TransparentStretchBlt( - ACanvas.Handle, Left, Top, Right - Left, Bottom - Top, - Canvas.Handle, SrcRect.Left, SrcRect.Top, SrcRect.Right - SrcRect.Left, SrcRect.Bottom - SrcRect.Top, - FMask.Canvas.Handle, SrcRect.Left, SrcRect.Top) {LDB} - else - StretchBlt( - ACanvas.Handle, Left, Top, Right - Left, Bottom - Top, - Canvas.Handle, SrcRect.Left, SrcRect.Top, SrcRect.Right - SrcRect.Left, SrcRect.Bottom - SrcRect.Top, - ACanvas.CopyMode); - finally - if RestorePalette then - SelectPalette(ACanvas.Handle, OldPalette, True); - end; - end; -end; -{$endif LCL} - -{ initialization } - -var - DC: HDC; - -initialization - DC := GetDC(0); - try - ColorBits := GetDeviceCaps(DC, BitsPixel) * GetDeviceCaps(DC, Planes); - - if ColorBits <= 4 then - ColorBits := 4 - else if ColorBits <= 8 then - ColorBits := 8 - else - ColorBits := 24; - - ThePalette := 0; - if ColorBits = 8 then - CalcPalette(DC); - if ColorBits <= 8 then {use Palette Relative bit only when Palettes used} - PalRelative := $2000000 - else - PalRelative := 0; - finally - ReleaseDC(0, DC); - end; - -{$ifdef TransparentStretchBltMissing} - // Note: This doesn't return the same palette as the Delphi 3 system palette - // since the true system palette contains 20 entries and the Delphi 3 system - // palette only contains 16. - // For our purpose this doesn't matter since we do not care about the actual - // colors (or their number) in the palette. - // Stock objects doesn't have to be deleted. - SystemPalette16 := GetStockObject(DEFAULT_PALETTE); -{$endif} - -{$ifdef FPC} - IsWin95 := False; // Use the same always with FPC - IsWin32Platform := False; -{$else} - IsWin95 := (Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and (Win32MinorVersion in [0..9]); - IsWin32Platform := Win32Platform = VER_PLATFORM_WIN32_WINDOWS; -{$endif FPC} -finalization - if ThePalette <> 0 then - DeleteObject(ThePalette); -end. - diff --git a/CORE/Source/Plugins/Htmlviewer/source/HtmlImages.pas b/CORE/Source/Plugins/Htmlviewer/source/HtmlImages.pas deleted file mode 100644 index b67a69f75..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/HtmlImages.pas +++ /dev/null @@ -1,2631 +0,0 @@ -{ -Version 11.7 -Copyright (c) 1995-2008 by L. David Baldwin, -Copyright (c) 2008-2016 by HtmlViewer Team - -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. - -Note that the source modules HTMLGIF1.PAS and DITHERUNIT.PAS -are covered by separate copyright notices located in those modules. -} - -{$I htmlcons.inc} - -unit HtmlImages; - -interface - -uses - SysUtils, Classes, -{$ifdef LCL} - LclIntf, IntfGraphics, FpImage, LclType, LResources, LMessages, HtmlMisc, -{$else} - Windows, vcl.Imaging.Jpeg, -{$endif} - Contnrs, vcl.Graphics, vcl.Forms, vcl.Controls, - //Messages, - //Variants, - Types, - Math, -{$ifndef NoGDIPlus} - GDIPL2A, -{$endif} -{$ifdef METAFILEMISSING} - MetaFilePrinter, -{$endif} - URLSubs, - HtmlCaches, - HtmlGlobals, - HTMLGif2, - StyleTypes, -{$ifdef Compiler20_Plus} - vcl.Imaging.PngImage, -{$endif} - DitherUnit; - -const - HandCursor = crHandPoint; //10101; - OldThickIBeamCursor = 2; - UpDownCursor = 10103; - UpOnlyCursor = 10104; - DownOnlyCursor = 10105; -{$ifdef LCL} -{$else} - DefaultBitmap = 1002; - ErrBitmap = 1001; - ErrBitmapMask = 1005; - Hand_Cursor = 1003; - ThickIBeam_Cursor = 1006; -{$endif} - -type - -//------------------------------------------------------------------------------ -// ThtImage is an image wrapper. -//------------------------------------------------------------------------------ -// It is used in place of any bitmap / image type used in HtmlViewer < 11. -// Currently it supports ThtBitmap, (animated) TGifImage, TGpImage or ThtMetafile -// It replaces the unspecific TgpObject and TBitmapItem of the old image cache. -//------------------------------------------------------------------------------ - - ThtImageTransparency = (itrNone, itrIntrinsic, itrLLCorner); - - //BG, 09.04.2011 - ThtImage = class(ThtCachable) - protected - function GetBitmap: TBitmap; virtual; abstract; - function GetGraphic: TGraphic; virtual; - function GetImageHeight: Integer; virtual; abstract; - function GetImageWidth: Integer; virtual; abstract; - function GetMask: TBitmap; virtual; abstract; - function GetAnimate: Boolean; virtual; - procedure SetAnimate(const Value: Boolean); virtual; - - function EnlargeBitmap(Bitmap: TBitmap; W, H: Integer): TBitmap; virtual; - function EnlargeImage(W, H: Integer): ThtImage; virtual; - public - Transp: ThtImageTransparency; {identifies what the mask is for} - constructor Create(Tr: ThtImageTransparency); overload; - function Clone: ThtImage; virtual; - - procedure TileImage(PRec: PtPositionRec; DstW, DstH: Integer; var TiledImage: ThtImage; var NoMask: Boolean); virtual; - - procedure Draw(Canvas: TCanvas; X, Y, W, H: Integer); virtual; - procedure Print(Canvas: TCanvas; X, Y, W, H: Integer; BgColor: TColor); virtual; - procedure DrawTiled(Canvas: TCanvas; XStart, YStart, XEnd, YEnd, W, H: Integer); virtual; - procedure PrintTiled(Canvas: TCanvas; XStart, YStart, XEnd, YEnd, W, H: Integer; BgColor: TColor); virtual; - // used to draw/print background images. - // BG, 06.09.2015: Currently only ThtBitmapImage and ThtGdipImage implement these methods. - procedure DrawUnstretched(Canvas: TCanvas; X, Y, W, H, SrcX, SrcY: Integer; FillBackground: Boolean); virtual; - procedure PrintUnstretched(Canvas: TCanvas; X, Y, W, H, SrcX, SrcY: Integer; FillBackground: Boolean); virtual; - - function IsAnimated: Boolean; virtual; - property Bitmap: TBitmap read GetBitmap; - property Mask: TBitmap read GetMask; - property Graphic: TGraphic read GetGraphic; - property Height: Integer read GetImageHeight; - property Width: Integer read GetImageWidth; - property Animate: Boolean read GetAnimate write SetAnimate; - end; - - ThtImageList = class(TObjectList) - private - function Get(Index: Integer): ThtImage; {$ifdef UseInline} inline; {$endif} - public - property Items[Index: Integer]: ThtImage read Get; default; - end; - - TGetImageEvent = function(Sender: TObject; const Url: ThtString): ThtImage of object; - -//------------------------------------------------------------------------------ -// ThtImageCache is the image cache, that holds the above image wrappers. -//------------------------------------------------------------------------------ - - ThtImageCache = class(ThtCache) - {a list of image filenames and their ThtImages} - public - constructor Create; - destructor Destroy; override; - function AddObject(const S: ThtString; AObject: ThtImage): Integer; reintroduce; {$ifdef UseInline} inline; {$endif} - // InsertImage(): Get the proper Index by using Find(). - procedure InsertImage(Index: Integer; const S: ThtString; AObject: ThtImage); {$ifdef UseInline} inline; {$endif} - function GetImage(I: Integer): ThtImage; {$ifdef UseInline} inline; {$endif} - end; - -//------------------------------------------------------------------------------ -// always supported image kinds: bitmap and (animated) gif. -//------------------------------------------------------------------------------ -// optionally supported image kinds: -// if NoGDIPlus is not defined: png, tiff, ico, cur, ... -// if NoMetafile is not defined: metafile, -//------------------------------------------------------------------------------ - - //BG, 11.01.2015: remember bitmap etc. until it is inserted: - ThtBitmapToInsert = class - public - Bitmap: TBitmap; - Color: TColor; - Transp: ThtImageTransparency; - OwnsBitmap: Boolean; - constructor Create(AImage: TBitmap; ATransp: ThtImageTransparency; AColor: TColor; AOwnsBitmap: Boolean = True); overload; - end; - - //BG, 09.04.2011 - ThtBitmapImage = class(ThtImage) - private - Bitmap, Mask: TBitmap; - OwnsBitmap, OwnsMask: Boolean; - protected - function GetBitmap: TBitmap; override; - function GetImageHeight: Integer; override; - function GetImageWidth: Integer; override; - function GetMask: TBitmap; override; - public - constructor Create(AImage: ThtBitmap; Tr: ThtImageTransparency; AOwnsBitmap: Boolean = True); overload; - constructor Create(AImage, AMask: TBitmap; Tr: ThtImageTransparency; AOwnsBitmap: Boolean = True; AOwnsMask: Boolean = True); overload; - constructor Create(AImage: TBitmap; Tr: ThtImageTransparency; Color: TColor; AOwnsBitmap: Boolean = True); overload; - destructor Destroy; override; - procedure Print(Canvas: TCanvas; X, Y, W, H: Integer; BgColor: TColor); override; - procedure DrawUnstretched(Canvas: TCanvas; X, Y, W, H, SrcX, SrcY: Integer; FillBackground: Boolean); override; - procedure PrintUnstretched(Canvas: TCanvas; X, Y, W, H, SrcX, SrcY: Integer; FillBackground: Boolean); override; - end; - - //BG, 09.04.2011 - ThtGifImage = class(ThtImage) - private - FGif: TGifImage; - protected - function GetBitmap: TBitmap; override; - function GetImageHeight: Integer; override; - function GetImageWidth: Integer; override; - function GetMask: TBitmap; override; - function GetAnimate: Boolean; override; - procedure SetAnimate(const Value: Boolean); override; - public - constructor Create(AImage: TGifImage); overload; - destructor Destroy; override; - function Clone: ThtImage; override; - function IsAnimated: Boolean; override; - procedure Draw(Canvas: TCanvas; X, Y, W, H: Integer); override; - property Gif: TGifImage read FGif; - end; - -{$ifndef NoGDIPlus} - //BG, 09.04.2011 - //BG, 18.05.2014: GDIPlus can handle image kinds: PNG, TIFF, JPEG, ICO, EMF, WMF, EXIF, BMP, GIF (not animated) - ThtGdipImage = class(ThtImage) - private - Gpi: ThtGpImage; - protected - function GetBitmap: TBitmap; override; - function GetImageHeight: Integer; override; - function GetImageWidth: Integer; override; - function GetMask: TBitmap; override; - public - constructor Create(AImage: ThtGpImage); overload; - destructor Destroy; override; - procedure Draw(Canvas: TCanvas; X, Y, W, H: Integer); override; - procedure DrawTiled(Canvas: TCanvas; XStart, YStart, XEnd, YEnd, W, H: Integer); override; - procedure Print(Canvas: TCanvas; X, Y, W, H: Integer; BgColor: TColor); override; - - procedure DrawUnstretched(Canvas: TCanvas; X, Y, W, H, SrcX, SrcY: Integer; FillBackground: Boolean); override; - procedure PrintUnstretched(Canvas: TCanvas; X, Y, W, H, SrcX, SrcY: Integer; FillBackground: Boolean); override; - end; -{$endif !NoGDIPlus} - -//------------------------------------------------------------------------------ -// ThtGraphicImage: support for all TGraphics without own TBitmap, e.g. meta files -//------------------------------------------------------------------------------ - - //BG, 09.04.2011 - ThtGraphicImage = class(ThtImage) - private - FGraphic: TGraphic; - FImage: ThtBitmapImage; - procedure Construct; deprecated; - protected - function GetBitmap: TBitmap; override; - function GetGraphic: TGraphic; override; - function GetImageHeight: Integer; override; - function GetImageWidth: Integer; override; - function GetMask: TBitmap; override; - public - constructor Create(AGraphic: TGraphic); overload; - destructor Destroy; override; - end; - -//------------------------------------------------------------------------------ -// ThtImageLoader is the base class for image loaders, that the global function -// LoadImageFromStream() uses to load images of various kinds. -// -// HtmlViewer components use LoadImageFromStream() to load images. -// -// You may derive your own image loader from this class to support further -// image file formats. Your loader must load the images into a derivate of -// the ThtImage declared above. -//------------------------------------------------------------------------------ - -type - //BG, 24.08.2015: - ThtImageLoader = class - private - FSupportedKinds: TStringList; - FSupportedExts: TStringList; - protected - // AddSupportedKinds adds one kind with a comma separated list of file extensions - // e.g.: AddSupportedKinds('Bitmaps', '*.bmp,*.dib') - procedure AddSupportedKinds(const KindName, Extensions: string); overload; - - // AddSupportedKinds() adds all supported kinds using the above AddSupportedKinds(). - procedure AddSupportedKinds; overload; virtual; - public - constructor Create; virtual; - destructor Destroy; override; - - function LoadGraphicFromStream(Stream: TStream; Transparent: ThtImageTransparency): TGraphic; virtual; - function LoadImageFromStream(Stream: TStream; Transparent: ThtImageTransparency): ThtImage; virtual; - // Filter returns a file dialog filter compliant string of supported image types - function GetFilter(const AllKinds: string): string; - end; - -// SetImageLoader() sets a global image loader. -// The loader will be freed during finalization or by setting another loader. -procedure SetImageLoader(AImageLoader: ThtImageLoader); - -// GetImageLoader() gets the global image loader. If no image loader has been -// set yet, a ThtImageLoader is created. -function GetImageLoader(): ThtImageLoader; - -// LoadImageFromStream() tries to load an image from stream using the currently -// set global image loader. -// -// The HtmlViewer components use LoadImageFromStream() to load images from streams. -function LoadImageFromStream(Stream: TStream; Transparent: ThtImageTransparency): ThtImage; - -//------------------------------------------------------------------------------ -// image methods -//------------------------------------------------------------------------------ - -function EnlargeImage(Image: TBitmap; W, H: Integer): TBitmap; - -procedure PrintBitmap(Canvas: TCanvas; X, Y, W, H: Integer; Bitmap: TBitmap); -procedure PrintTransparentBitmap3(Canvas: TCanvas; X, Y, NewW, NewH: Integer; Bitmap, Mask: TBitmap; YI, HI: Integer); - -function GetClipRegion(Canvas: TCanvas): Integer; - -procedure DrawBackground(ACanvas: TCanvas; ARect: TRect; XStart, YStart, XLast, YLast: Integer; - Image: ThtImage; BW, BH: Integer; BGColor: TColor); -{draw the background color and any tiled images on it} -{ARect, the cliprect, drawing outside this will not show but images may overhang - XStart, YStart are first image position already calculated for the cliprect and parameters. - XLast, YLast Tiling stops here. - BW, BH bitmap dimensions. -} - -//procedure DoImageStuff(IW, IH: Integer; BGImage: ThtImage; -// PRec: PtPositionRec; var TiledImage: ThtImage; var NoMask: boolean); -//{Set up for the background image. Allow for tiling, and transparency -// BGImage is the image -// PRec describes the location and tiling -// IW, IH, the width and height of the background -//} - - -{$IFNDEF NoGDIPlus} -procedure DrawGpImage(Handle: HDC; Image: ThtGpImage; DestX, DestY: Integer); overload; -procedure DrawGpImage(Handle: HDC; Image: ThtGpImage; DestX, DestY, SrcX, SrcY, SrcW, SrcH: Integer); overload; -procedure StretchDrawGpImage(Handle: HDC; Image: ThtGpImage; DestX, DestY, DestW, DestH: Integer); -procedure PrintGpImageDirect(Handle: HDC; Image: ThtGpImage; DestX, DestY: Integer; ScaleX: single = 1.0; ScaleY: single = 1.0); -procedure StretchPrintGpImageDirect(Handle: HDC; Image: ThtGpImage; DestX, DestY, DestW, DestH: Integer; ScaleX, ScaleY: Single); -procedure StretchPrintGpImageOnColor(Canvas: TCanvas; Image: ThtGpImage; DestX, DestY, DestW, DestH: Integer; Color: TColor = clWhite); -{$ENDIF NoGDIPlus} - -//------------------------------------------------------------------------------ - -var - DefBitMap, ErrorBitMap, ErrorBitmapMask: TBitMap; - DefImage: ThtBitmapImage; - ErrorImage: ThtBitmapImage; - -implementation - -var - ImageLoader: ThtImageLoader; - -//------------------------------------------------------------------------------ -// device independent bitmap wrapper -//------------------------------------------------------------------------------ - -type - - TDib = class(TObject) - private - Info: PBitmapInfoHeader; - InfoSize: Integer; - Image: Pointer; - ImageSize: Integer; - FHandle: HGLOBAL; - procedure InitializeBitmapInfoHeader(Bitmap: HBITMAP); - procedure GetDIBX(DC: HDC; Bitmap: HBITMAP; Palette: HPALETTE); - procedure Allocate(Size: Integer); - procedure DeAllocate; - public - constructor CreateDIB(DC: HDC; Bitmap: TBitmap); - destructor Destroy; override; - function CreateDIBmp: hBitmap; - procedure DrawDIB(DC: HDC; X, Y, W, H: Integer; ROP: DWord); - end; - -//------------------------------------------------------------------------------ - -{ Try to recognize image type by reading the image header at Stream position. - Return image type or itNone if not recognized. - - Do not reset stream position when done; this is left to the caller - which knows better how to interpret the results. } -type - ThtImageFormat = (itNone, itBmp, itIco, itCur, itGif, itPng, itJpg, itTiff, itMeta); - -function KindOfImage(const Stream: TStream): ThtImageFormat; -type - THeaderRec = record - case Integer of - 0: (c: Cardinal); - 1: (w: Word); - 2: (EMF: record - Type_: Cardinal; - Size: Cardinal; - Bounds: array[0..15] of Byte; - Frame: array[0..15] of Byte; - RecordSignature: Cardinal; - end); - 3: (WMF: record - Type_: Word; - HeaderSize: Word; - Version: Word; - end); - 4: (TIFF: record - ID: Word; - Version: Word; - end); - end; -var - Header: THeaderRec; - n: Integer; -begin - Assert(Assigned(Stream)); - - n := Stream.Read(Header, SizeOf(Header)); - if n >= SizeOf(Header.c) then - begin - - case Header.c of - $00000001: - { Windows Enhanced Metafile Specs & Info: - * https://msdn.microsoft.com/en-us/library/cc230635.aspx } - if (n >= SizeOf (Header.Emf)) and (Header.EMF.RecordSignature = $464D4520) then - begin - Result := itMeta; - Exit; - end; - - $00010000: begin Result := itIco ; Exit; end; - $00020000: begin Result := itCur ; Exit; end; - $002A4949: begin Result := itTiff; Exit; end; // .TIFF little endian (II - Intel). - $2A004D4D: begin Result := itTiff; Exit; end; // .TIFF big endian (MM - Motorola). - $38464947: begin Result := itGif ; Exit; end; - $474E5089: begin Result := itPng ; Exit; end; - - { Windows Metafile with WmfPlaceableFileHeader - * https://msdn.microsoft.com/en-us/library/windows/desktop/ms534075%28v=vs.85%29.aspx } - $9AC6CDD7: begin Result := itMeta; Exit; end; - end; - - case Header.w of - $0001, $0002: - { Windows Metafile Specs & Info: - * https://msdn.microsoft.com/en-us/library/cc250418.aspx - * https://www.symantec.com/avcenter/reference/inside.the.windows.meta.file.format.pdf - - NOTICE: with NoGDIPlus defined Vcl.Graphics.TMetaFile should handle this kind of stream - but since Delphi 4 it does not recognize WMF metafiles without a WmfPlaceableFileHeader - which starts with magic number $9AC6CDD7 and is detected in the case above. - } - if (n >= SizeOf(Header.WMF)) and - (Header.Wmf.HeaderSize = 9) then - case Header.Wmf.Version of - $0100, $0300: - begin - Result := itMeta; - Exit; - end; - end; - - $4D42: begin Result := itBmp; Exit; end; - $D8FF: begin Result := itJpg; Exit; end; - end; - end; - - Result := itNone; -end; - -function ConvertImage(Bitmap: ThtBitmap): ThtBitmap; -{convert bitmap into a form for BitBlt later} - - function DIBConvert: ThtBitmap; - var - DC: HDC; - DIB: TDib; - OldBmp: HBitmap; - OldPal: HPalette; - Hnd: HBitmap; - begin - DC := CreateCompatibleDC(0); - OldBmp := SelectObject(DC, Bitmap.Handle); - OldPal := SelectPalette(DC, ThePalette, False); - RealizePalette(DC); - DIB := TDib.CreateDIB(DC, Bitmap); - Hnd := DIB.CreateDIBmp; - DIB.Free; - SelectPalette(DC, OldPal, False); - SelectObject(DC, OldBmp); - DeleteDC(DC); - Result := ThtBitmap.Create(Bitmap.WithTransparentMask); - Result.Mask := Bitmap.Mask; - Bitmap.Free; - Result.Handle := Hnd; - if (ColorBits = 8) and (Result.Palette = 0) then - Result.Palette := CopyPalette(ThePalette); - end; - -begin - if not Assigned(Bitmap) then - begin - Result := nil; - Exit; - end; - - if ColorBits > 8 then - begin - if Bitmap.PixelFormat <= pf8bit then - Result := DIBConvert - else - Result := Bitmap; - Exit; - end; - - if Bitmap.HandleType = bmDIB then - begin - Result := GetBitmap(Bitmap); - Bitmap.Free; - Exit; - end; - Result := DIBConvert; -end; - -{----------------GetImageAndMaskFromStream} - -function GetImageMask(Image: TBitmap; ColorValid: boolean; AColor: TColor): TBitmap; -begin - Result := nil; - try - if ColorValid then - Image.TransparentColor := AColor; {color has already been selected} - {else the transparent color is the lower left pixel of the bitmap} - - Image.Transparent := True; - - Result := TBitmap.Create; - Result.Handle := Image.ReleaseMaskHandle; - Image.Transparent := False; - except - FreeAndNil(Result); - end; -end; - -//-- BG ---------------------------------------------------------- 24.08.2015 -- -procedure SetImageLoader(AImageLoader: ThtImageLoader); -begin - if ImageLoader <> AImageLoader then - begin - ImageLoader.Free; - ImageLoader := AImageLoader; - end; -end; - -//-- BG ---------------------------------------------------------- 24.08.2015 -- -function GetImageLoader(): ThtImageLoader; -begin - if ImageLoader = nil then - ImageLoader := ThtImageLoader.Create; - Result := ImageLoader; -end; - -//-- BG ---------------------------------------------------------- 24.08.2015 -- -function LoadImageFromStream(Stream: TStream; Transparent: ThtImageTransparency): ThtImage; -begin - Result := GetImageLoader.LoadImageFromStream(Stream, Transparent); -end; - -//-- BG ---------------------------------------------------------- 24.08.2015 -- -procedure ThtImageLoader.AddSupportedKinds(const KindName, Extensions: string); -var - I: Integer; - Exts, SupportedExts: TStringList; -begin - Exts := TStringList.Create; - try - Exts.CommaText := Extensions; - - for I := 0 to Exts.Count - 1 do - begin - if FSupportedExts.IndexOf(Exts[I]) < 0 then - FSupportedExts.Add(Exts[I]); - end; - - I := FSupportedKinds.IndexOf(KindName); - if I >= 0 then - begin - SupportedExts := TStringList(FSupportedKinds.Objects[I]); - for I := 0 to Exts.Count - 1 do - begin - if SupportedExts.IndexOf(Exts[I]) < 0 then - SupportedExts.Add(Exts[I]); - end; - end - else - begin - // new entry - FSupportedKinds.AddObject(KindName, Exts); - Exts := nil; - end; - finally - Exts.Free; - end; -end; - -//-- BG ---------------------------------------------------------- 24.08.2015 -- -procedure ThtImageLoader.AddSupportedKinds; -begin - - AddSupportedKinds('Bitmaps', 'bmp'); - AddSupportedKinds('Graphics Interchange Format', 'gif'); - AddSupportedKinds('JPEG', 'jpg,jpeg'); -{$if defined(LCL) or defined(Compiler20_Plus) } - AddSupportedKinds('Portable Network Graphics', 'png'); -{$ifend} -{$ifndef NoGDIPlus} - AddSupportedKinds('Portable Network Graphics', 'png'); - AddSupportedKinds('Tagged Image Files', 'tif,tiff'); - AddSupportedKinds('Icons', 'ico'); - AddSupportedKinds('Cursors', 'cur'); - AddSupportedKinds('Windows Metafiles', 'wmf,emf'); -{$endif} -{$ifndef NoMetafile} - AddSupportedKinds('Windows Metafiles', 'wmf,emf'); -{$endif} -end; - -//-- BG ---------------------------------------------------------- 24.08.2015 -- -constructor ThtImageLoader.Create; -begin - inherited; - FSupportedKinds := TStringList.Create; - FSupportedExts := TStringList.Create; - AddSupportedKinds; -end; - -//-- BG ---------------------------------------------------------- 24.08.2015 -- -destructor ThtImageLoader.Destroy; -var - I: Integer; -begin - FSupportedExts.Free; - for i := 0 to FSupportedKinds.Count - 1 do - FSupportedKinds.Objects[I].Free; - FSupportedKinds.Free; - inherited; -end; - -//-- BG ---------------------------------------------------------- 24.08.2015 -- -function ThtImageLoader.GetFilter(const AllKinds: string): string; -var - Files: TStringList; - Filters: TStringList; - - procedure AddFilter(const Name: string; Exts: TStrings); - var - I: Integer; - begin - Files.Clear; - for I := 0 to Exts.Count - 1 do - Files.Add('*.' + Exts[I]); - Files.Delimiter := ','; - Filters.Add( Name + ' (' + Files.DelimitedText + ')' ); - Files.Delimiter := ';'; - Filters.Add( Files.DelimitedText ); - end; - -var - I: Integer; - -begin - Filters := TStringList.Create; - Files := TStringList.Create; -{$ifdef HasStrictDelimiter} - Files.StrictDelimiter := True; -{$endif} - try - if Length(AllKinds) > 0 then - AddFilter( AllKinds, FSupportedExts ); - - for I := 0 to FSupportedKinds.Count - 1 do - AddFilter( FSupportedKinds[I], TStringList(FSupportedKinds.Objects[I]) ); - - Filters.Delimiter := '|'; -{$ifdef HasStrictDelimiter} - Filters.StrictDelimiter := True; - Result := Filters.DelimitedText; -{$else} - SetLength(Result, 0); - for I := 0 to Filters.Count - 1 do - Result := Result + Filters[I] + '|'; - SetLength(Result, Length(Result) - 1); -{$endif} - - finally - Files.Free; - Filters.Free; - end; -end; - -//-- BG ---------------------------------------------------------- 26.08.2015 -- -function ThtImageLoader.LoadGraphicFromStream(Stream: TStream; Transparent: ThtImageTransparency): TGraphic; -var - ImageFormat: ThtImageFormat; -begin - Result := nil; - if not Assigned(Stream) then - Exit; - - try - Stream.Seek(0, soFromBeginning); // Seek is faster than Position. - ImageFormat := KindOfImage(Stream); - if ImageFormat = itNone then - Exit; - - Stream.Seek(0, soFromBeginning); // Seek is faster than Position. - -{$ifndef NoGDIPlus} - if GDIPlusActive then - // as GDI+ is available, try it first to load images as it renders images nicer. - try - case ImageFormat of - // GDI+ does not support animated GIFs: - itGif: ; - - // GDI+ does not support transparency for bitmaps - itBmp: if Transparent = itrNone then Result := ThtGpImage.Create; - - // GDI+ does not support lower left corner transparency for icons and cursors: - itCur, - itIco: if Transparent <> itrLLCorner then Result := ThtGpImage.Create; - else - Result := ThtGpImage.Create; - end; - except - // just continue without image... - end; -{$endif !NoGDIPlus} - - if Result = nil then - case ImageFormat of - itCur, - itIco: Result := TIcon.Create; - itBmp: Result := TBitmap.Create; - itGif: Result := TGifImage.Create; - itJpg: Result := TJPEGImage.Create; -{$ifndef NoMetafile} - itMeta: Result := TMetafile.Create; -{$endif} -{$ifdef Compiler20_Plus} - itPng: Result := TPngImage.Create; -{$endif} - end; - - if Result <> nil then - Result.LoadFromStream(Stream); - - except - FreeAndNil(Result); - end; -end; - -//-- BG ---------------------------------------------------------- 26.09.2010 -- -function ThtImageLoader.LoadImageFromStream(Stream: TStream; Transparent: ThtImageTransparency): ThtImage; -// extracted from ThtDocument.GetTheBitmap(), ThtDocument.InsertImage(), and ThtDocument.ReplaceImage() - - procedure LoadMeta; -{$ifndef NoMetafile} - var - Meta: TMetaFile; - begin - Meta := TMetafile.Create; - try - Meta.LoadFromStream(Stream); - except - Meta.Free; - raise; - end; - Result := ThtGraphicImage.Create(Meta); -{$else} - begin -{$endif NoMetafile} - end; - -{$ifndef NoGDIPlus} - procedure LoadGdipImage; - var - Image: ThtGpImage; - begin - Image := ThtGpImage.Create; - try - Image.LoadFromStream(Stream); - Result := ThtGdipImage.Create(Image); - except - Image.Free; - raise; - end; - end; -{$endif !NoGDIPlus} - - procedure LoadGif; - var - Gif: TGifImage; - begin - Gif := TGifImage.Create; - Gif.LoadFromStream(Stream); - if Gif.IsAnimated then - Result := ThtGifImage.Create(Gif) - else - begin - if Gif.IsTransparent then - Transparent := itrIntrinsic; - Result := ThtBitmapImage.Create(Gif, Transparent); - end; - end; - -var - Bitmap: ThtBitmap; - - procedure LoadPng; -{$ifdef LCL} - var - pngImage: TPortableNetworkGraphic; - begin - pngImage := TPortableNetworkGraphic.Create; - try - pngImage.LoadFromStream(Stream); - if ColorBits <= 8 then - pngImage.PixelFormat := pf8bit - else - pngImage.PixelFormat := pf24bit; - - Bitmap := ThtBitmap.Create(pngImage.MaskHandleAllocated); - Bitmap.Assign(pngImage); - if pngImage.MaskHandleAllocated then - begin - Bitmap.Mask.LoadFromBitmapHandles(pngImage.MaskHandle, 0); - Transparent := itrIntrinsic; - end - else - Transparent := itrNone; - finally - pngImage.Free; - end; -{$else} - begin -{$endif} - end; - - procedure LoadJpeg; - var - jpImage: TJpegImage; - begin - jpImage := TJpegImage.Create; - try - jpImage.LoadFromStream(Stream); - if ColorBits <= 8 then - begin - jpImage.PixelFormat := {$ifdef LCL} pf8bit {$else} jf8bit {$endif}; - if not jpImage.GrayScale and (ColorBits = 8) then - jpImage.Palette := CopyPalette(ThePalette); - end - else - jpImage.PixelFormat := {$ifdef LCL} pf24bit {$else} jf24bit {$endif}; - Bitmap := ThtBitmap.Create; - Bitmap.Assign(jpImage); - Transparent := itrNone; - finally - jpImage.Free; - end; - end; - - procedure LoadIco; - var - Icon: TIcon; - IconInfo: TIconInfo; - begin - Icon := TIcon.Create; - try - Icon.LoadFromStream(Stream); -{$ifdef MSWindows} - if GetIconInfo(Icon.Handle, {$ifdef LCL}@{$endif} IconInfo) then - begin - Bitmap := ThtBitmap.Create(Transparent <> itrLLCorner); - Bitmap.Handle := IconInfo.hbmColor; - if Transparent <> itrLLCorner then - begin - Bitmap.Mask.Handle := IconInfo.hbmMask; - Transparent := itrIntrinsic; - end; - end; -{$else} - Bitmap := ThtBitmap.Create(Transparent <> itrLLCorner); - Bitmap.LoadFromBitmapHandles(Icon.BitmapHandle, 0); - if Transparent <> itrLLCorner then - begin - Bitmap.Mask.LoadFromBitmapHandles(Icon.MaskHandle, 0); - Transparent := itrIntrinsic; - end; -{$endif} - finally - Icon.Free; - end; - end; - - procedure LoadBmp; - begin - Bitmap := ThtBitmap.Create; - Bitmap.LoadFromStream(Stream); - end; - -var - ImageFormat: ThtImageFormat; - Mask: TBitmap; -begin - Result := nil; - if not Assigned(Stream) then - Exit; - - Bitmap := nil; - try - Stream.Seek(0, soFromBeginning); // Seek is faster than Position. - ImageFormat := KindOfImage(Stream); - if ImageFormat = itNone then - Exit; - - Stream.Seek(0, soFromBeginning); // Seek is faster than Position. - -{$ifndef NoGDIPlus} - if GDIPlusActive then - // as GDI+ is available, try it first to load images as it renders images nicer. - try - case ImageFormat of - // GDI+ does not support animated GIFs: - itGif: ; - - // GDI+ does not support transparency for bitmaps - itBmp: if Transparent = itrNone then LoadGdipImage; - - // GDI+ does not support lower left corner transparency for icons and cursors: - itCur, - itIco: if Transparent <> itrLLCorner then LoadGdipImage; - else - LoadGdipImage; - end; - except - // just continue without image... - end; -{$endif !NoGDIPlus} - - if Result = nil then - case ImageFormat of - itCur, - itIco: LoadIco; - itBmp: LoadBmp; - itGif: LoadGif; - itJpg: LoadJpeg; - itMeta: LoadMeta; - itPng: LoadPng; - end; - - if Bitmap <> nil then - begin - Mask := nil; - if Bitmap.Mask = nil then - if Transparent = itrLLCorner then - Mask := GetImageMask(Bitmap, False, 0); - Bitmap := ConvertImage(Bitmap); - if Mask <> nil then - begin - Bitmap.WithTransparentMask := True; - Bitmap.Mask := Mask; - Mask.Free; - end; - Result := ThtBitmapImage.Create(Bitmap, Transparent); - end; - - except - Bitmap.Free; - FreeAndNil(Result); - end; -end; - -{ Regions } - -//-- BG ---------------------------------------------------------- 13.04.2011 -- -function GetClipRegion(Canvas: TCanvas): Integer; -// returns 0, if canvas is unclipped, else handle of region -begin - Result := CreateRectRgn(0, 0, 1, 1); - if GetClipRgn(Canvas.Handle, Result) = 0 then - begin - {0 = region does not exists} - DeleteObject(Result); - Result := 0; - end; -end; - - -{----------------BitmapToRegion} - -function BitmapToRegion(ABmp: TBitmap; XForm: PXForm; TransparentColor: TColor): HRGN; -{Find a Region corresponding to the non-transparent area of a bitmap. - - Thanks to Felipe Machado. See http://www.delphi3000.com/ - Minor modifications made.} -const - AllocUnit = 100; -type - PRectArray = ^TRectArray; - TRectArray = array[0..(MaxInt div SizeOf(TRect)) - 1] of TRect; -var - pr: PRectArray; // used to access the rects array of RgnData by index - h: HRGN; // Handles to regions - RgnData: PRgnData; // Pointer to structure RGNDATA used to create regions - lr, lg, lb: Byte; // values for lowest and hightest trans. colors - x, y, x0: Integer; // coordinates of current rect of visible pixels - maxRects: Cardinal; // Number of rects to realloc memory by chunks of AllocUnit -{$ifdef LCL} - bmp: TLazIntfImage; - b: TFpColor; -{$else} - b: PByteArray; // used to easy the task of testing the byte pixels (R,G,B) - ScanLinePtr: Pointer; // Pointer to current ScanLine being scanned - ScanLineInc: Integer; // Offset to next bitmap scanline (can be negative) - bmp: TBitmap; -{$endif} -begin - Result := 0; - lr := GetRValue(TransparentColor); - lg := GetGValue(TransparentColor); - lb := GetBValue(TransparentColor); - { ensures that the pixel format is 32-bits per pixel } -{$ifdef LCL} - bmp := TLazIntfImage.Create(0,0); - try - bmp.LoadFromBitmap(ABmp.Handle, 0); - { alloc initial region data } - maxRects := AllocUnit; - GetMem(RgnData, SizeOf(TRgnDataHeader) + (SizeOf(TRect) * maxRects)); - FillChar(RgnData^, SizeOf(TRgnDataHeader) + (SizeOf(TRect) * maxRects), 0); - try - with RgnData^.rdh do - begin - dwSize := SizeOf(TRgnDataHeader); - iType := RDH_RECTANGLES; - nCount := 0; - nRgnSize := 0; - SetRect(rcBound, MAXLONG, MAXLONG, 0, 0); - end; - { scan each bitmap row - the orientation doesn't matter (Bottom-up or not) } - for y := 0 to bmp.Height - 1 do - begin - x := 0; - while x < bmp.Width do - begin - x0 := x; - while x < bmp.Width do - begin - b := bmp[x,y]; - if (b.red = lr) and (b.green = lg) and (b.blue = lb) then - Break; // pixel is transparent - Inc(x); - end; - { test to see if we have a non-transparent area in the image } - if x > x0 then - begin - { increase RgnData by AllocUnit rects if we exceeds maxRects } - if RgnData^.rdh.nCount >= maxRects then - begin - Inc(maxRects, AllocUnit); - ReallocMem(RgnData, SizeOf(TRgnDataHeader) + (SizeOf(TRect) * MaxRects)); - pr := @RgnData^.Buffer; - FillChar(pr^[maxRects - AllocUnit], AllocUnit * SizeOf(TRect), 0); - end; - { Add the rect (x0, y)-(x, y+1) as a new visible area in the region } - pr := @RgnData^.Buffer; // Buffer is an array of rects - with RgnData^.rdh do - begin - SetRect(pr[nCount], x0, y, x, y + 1); - { adjust the bound rectangle of the region if we are "out-of-bounds" } - if x0 < rcBound.Left then - rcBound.Left := x0; - if y < rcBound.Top then - rcBound.Top := y; - if x > rcBound.Right then - rcBound.Right := x; - if y + 1 > rcBound.Bottom then - rcBound.Bottom := y + 1; - Inc(nCount); - end; - end; // if x > x0 - { Need to create the region by muliple calls to ExtCreateRegion, 'cause } - { it will fail on Windows 98 if the number of rectangles is too large } - if RgnData^.rdh.nCount = 2000 then - begin - h := ExtCreateRegion(XForm, SizeOf(TRgnDataHeader) + (SizeOf(TRect) * maxRects), RgnData^); - if Result > 0 then - begin // Expand the current region - CombineRgn(Result, Result, h, RGN_OR); - DeleteObject(h); - end - else // First region, assign it to Result - Result := h; - RgnData^.rdh.nCount := 0; - SetRect(RgnData^.rdh.rcBound, MAXLONG, MAXLONG, 0, 0); - end; - Inc(x); - end; // scan every sample byte of the image - end; - { need to call ExCreateRegion one more time because we could have left } - { a RgnData with less than 2000 rects, so it wasn't yet created/combined } - if RgnData^.rdh.nCount > 0 then {LDB 0 Count causes exception and abort in Win98} - h := ExtCreateRegion(XForm, SizeOf(TRgnDataHeader) + (SizeOf(TRect) * MaxRects), RgnData^) - else - h := 0; - if Result > 0 then - begin - CombineRgn(Result, Result, h, RGN_OR); - DeleteObject(h); - end - else - Result := h; - finally - FreeMem(RgnData, SizeOf(TRgnDataHeader) + (SizeOf(TRect) * MaxRects)); - end; - finally - bmp.Free; - end; -{$else} - bmp := TBitmap.Create; - try - bmp.Assign(ABmp); - bmp.PixelFormat := pf32bit; - { alloc initial region data } - maxRects := AllocUnit; - GetMem(RgnData, SizeOf(TRgnDataHeader) + (SizeOf(TRect) * maxRects)); - FillChar(RgnData^, SizeOf(TRgnDataHeader) + (SizeOf(TRect) * maxRects), 0); - try - with RgnData^.rdh do - begin - dwSize := SizeOf(TRgnDataHeader); - iType := RDH_RECTANGLES; - nCount := 0; - nRgnSize := 0; - SetRect(rcBound, MAXLONG, MAXLONG, 0, 0); - end; - { scan each bitmap row - the orientation doesn't matter (Bottom-up or not) } - ScanLinePtr := bmp.ScanLine[0]; - if bmp.Height > 1 then - ScanLineInc := PtrSub(bmp.ScanLine[1], ScanLinePtr) - else - ScanLineInc := 0; - for y := 0 to bmp.Height - 1 do - begin - x := 0; - while x < bmp.Width do - begin - x0 := x; - while x < bmp.Width do - begin - b := @PByteArray(ScanLinePtr)[x * SizeOf(TRGBQuad)]; - // BGR-RGB: Windows 32bpp BMPs are made of BGRa quads (not RGBa) - if (b[2] = lr) and (b[1] = lg) and (b[0] = lb) then - Break; // pixel is transparent - Inc(x); - end; - { test to see if we have a non-transparent area in the image } - if x > x0 then - begin - { increase RgnData by AllocUnit rects if we exceeds maxRects } - if RgnData^.rdh.nCount >= maxRects then - begin - Inc(maxRects, AllocUnit); - ReallocMem(RgnData, SizeOf(TRgnDataHeader) + (SizeOf(TRect) * MaxRects)); - pr := @RgnData^.Buffer; - FillChar(pr^[maxRects - AllocUnit], AllocUnit * SizeOf(TRect), 0); - end; - { Add the rect (x0, y)-(x, y+1) as a new visible area in the region } - pr := @RgnData^.Buffer; // Buffer is an array of rects - with RgnData^.rdh do - begin - SetRect(pr[nCount], x0, y, x, y + 1); - { adjust the bound rectangle of the region if we are "out-of-bounds" } - if x0 < rcBound.Left then - rcBound.Left := x0; - if y < rcBound.Top then - rcBound.Top := y; - if x > rcBound.Right then - rcBound.Right := x; - if y + 1 > rcBound.Bottom then - rcBound.Bottom := y + 1; - Inc(nCount); - end; - end; // if x > x0 - { Need to create the region by muliple calls to ExtCreateRegion, 'cause } - { it will fail on Windows 98 if the number of rectangles is too large } - if RgnData^.rdh.nCount = 2000 then - begin - h := ExtCreateRegion(XForm, SizeOf(TRgnDataHeader) + (SizeOf(TRect) * maxRects), RgnData^); - if Result > 0 then - begin // Expand the current region - CombineRgn(Result, Result, h, RGN_OR); - DeleteObject(h); - end - else // First region, assign it to Result - Result := h; - RgnData^.rdh.nCount := 0; - SetRect(RgnData^.rdh.rcBound, MAXLONG, MAXLONG, 0, 0); - end; - Inc(x); - end; // scan every sample byte of the image - PtrInc(ScanLinePtr, ScanLineInc); - end; - { need to call ExCreateRegion one more time because we could have left } - { a RgnData with less than 2000 rects, so it wasn't yet created/combined } - if RgnData^.rdh.nCount > 0 then {LDB 0 Count causes exception and abort in Win98} - h := ExtCreateRegion(XForm, SizeOf(TRgnDataHeader) + (SizeOf(TRect) * MaxRects), RgnData^) - else - h := 0; - if Result > 0 then - begin - CombineRgn(Result, Result, h, RGN_OR); - DeleteObject(h); - end - else - Result := h; - finally - FreeMem(RgnData, SizeOf(TRgnDataHeader) + (SizeOf(TRect) * MaxRects)); - end; - finally - bmp.Free; - end; -{$endif} -end; - -{----------------DrawBackground} - -procedure DrawBackground(ACanvas: TCanvas; ARect: TRect; XStart, YStart, XLast, YLast: Integer; - Image: ThtImage; BW, BH: Integer; BGColor: TColor); -{draw the background color and any tiled images on it} -{ARect, the cliprect, drawing outside this will not show but images may overhang - XStart, YStart are first image position already calculated for the cliprect and parameters. - XLast, YLast Tiling stops here. - BW, BH bitmap dimensions. -} -var - OldBrush: HBrush; - OldPal: HPalette; - DC: HDC; - OldBack, OldFore: TColorRef; -begin - DC := ACanvas.handle; - if DC <> 0 then - begin - OldPal := SelectPalette(DC, ThePalette, False); - RealizePalette(DC); - ACanvas.Brush.Color :=BGColor;// ThemedColor(BGColor {$ifdef has_StyleElements},seClient in AStyleElements{$endif}) or PalRelative; - OldBrush := SelectObject(DC, ACanvas.Brush.Handle); - OldBack := SetBkColor(DC, clWhite); - OldFore := SetTextColor(DC, clBlack); - try - ACanvas.FillRect(ARect); {background color} - if Image <> nil then {tile the animated gif} - Image.DrawTiled(ACanvas, XStart, YStart, XLast, YLast, BW, BH); - finally - SelectObject(DC, OldBrush); - SelectPalette(DC, OldPal, False); - RealizePalette(DC); - SetBkColor(DC, OldBack); - SetTextColor(DC, OldFore); - end; - end; -end; - -//BG, 07.04.2011: same as CalcBackgroundLocationAndTiling plus DrawBackground ? -////TODO: let the better version win, but keep it in 2 separate methods for THtmlViewer. -//procedure DoImageStuff(IW, IH: Integer; BGImage: ThtImage; PRec: PtPositionRec; var TiledImage: ThtImage; var NoMask: boolean); -//{Set up for the background image. Allow for tiling, and transparency -// BGImage is the image -// PRec describes the location and tiling -// IW, IH, the width and height of the background -//} -//var -// OW, OH: Integer; -// X, XX, Y, X2, Y2: Integer; -// -////---------------------------------------------------------- -////these methods fill the TiledImage and TiledMask. -// -// procedure Tile(Bitmap, Mask: TBitmap; W, H: Integer); -// begin -// repeat {tile BGImage in the various dc's} -// XX := X; -// repeat -// TiledImage.Bitmap.Canvas.Draw(XX, Y, Bitmap); -// if Mask <> nil then -// TiledImage.Mask.Canvas.Draw(XX, Y, Mask) -// else if not NoMask then -// PatBlt(TiledImage.Mask.Canvas.Handle, XX, Y, Bitmap.Width, Bitmap.Height, Blackness); -// Inc(XX, Bitmap.Width); -// until XX >= X2; -// Inc(Y, Bitmap.Height); -// until Y >= Y2; -// end; -// -// procedure Enlarge; -// var -// TheBitmap, TheMask: TBitmap; -// NewBitmap, NewMask: TBitmap; -// begin -// TheBitmap := BGImage.Bitmap; -// TheMask := BGImage.Mask; -// -// NewBitmap := EnlargeImage(TheBitmap, X2 - X + 1, Y2 - Y + 1); -// try -// if TheMask <> nil then -// NewMask := EnlargeImage(TheMask, X2 - X + 1, Y2 - Y + 1) -// else -// NewMask := nil; -// -// try -// Tile(NewBitmap, NewMask, X2 - X + 1, Y2 - Y + 1); -// finally -// NewMask.Free; -// end; -// finally -// NewBitmap.Free; -// end; -// end; -// -//{$IFNDEF NoGDIPlus} -// procedure TileGpImage(Image: ThtGdipImage; W, H: Cardinal); -// var -// ImW, ImH: Integer; -// graphics: ThtGpGraphics; -// begin -// if Assigned(TiledImage) then -// if (IW <> TiledImage.Width) or (IH <> TiledImage.Height) then -// FreeAndNil(TiledImage); -// if TiledImage = nil then -// TiledImage := ThtGdipImage.Create( ThtGpBitmap.Create(IW, IH) ); -// -// ImW := Image.Width; -// ImH := Image.Height; -// try -// graphics := ThtGpGraphics.Create(ThtGpImage(TiledImage)); -// try -// graphics.Clear(clBlack); {clear to transparent black} -// repeat {tile Image in the various dc's} -// XX := X; -// repeat -// graphics.DrawImage(Image.Gpi, XX, Y, Image.Width, Image.Height); -// Inc(XX, ImW); -// until XX >= X2; -// Inc(Y, ImH); -// until Y >= Y2; -// except -// end; -// graphics.Free; -// except -// end; -// end; -//{$ENDIF !NoGDIPlus} -// -//var -// TiledBitmap, TiledMask: TBitmap; -//begin -// if (IW = 0) or (IH = 0) then -// exit; -// -// OW := BGImage.Width; -// OH := BGImage.Height; -// -//{compute the location and tiling of BGImage in the background} -// with PRec.X do -// begin -// X := GetPositionInRange(PosType, Value, IW - OW); -// AdjustForTiling(RepeatD, 0, IW, OW, X, X2); -// end; -// with PRec.Y do -// begin -// Y := GetPositionInRange(PosType, Value, IH - OH); -// AdjustForTiling(RepeatD, 0, IH, OH, Y, Y2); -// end; -// -// NoMask := not Assigned(BGImage.Mask) and PRec.X.RepeatD and PRec.Y.RepeatD; -// -// if (OW = 1) or (OH = 1) then -// begin -// {in case a 1 pixel bitmap is being tiled. EnlargeImage returns a TBitmap regardless of BgImage type.} -// Enlarge; -// end -// else -//{$IFNDEF NoGDIPlus} -// if BGImage is ThtGdipImage then -// begin -// {TiledImage becomes a ThtGdipBitmap as well} -// -// TileGpImage(ThtGdipImage(BGImage), OW, OH); -// end -// else -//{$ENDIF !NoGDIPlus} -// begin -// {TiledImage becomes a ThtBitmapImage} -// if TiledImage = nil then -// begin -// TiledBitmap := TBitmap.Create; -// TiledBitmap.Palette := CopyPalette(ThePalette); -// TiledBitmap.Height := IH; -// TiledBitmap.Width := IW; -// PatBlt(TiledBitmap.Canvas.Handle, 0, 0, IW, IH, Blackness); -// -// if not NoMask then -// begin -// TiledMask := TBitmap.Create; -// TiledMask.Monochrome := True; -// TiledMask.Height := IH; -// TiledMask.Width := IW; -// if BGImage.Mask = nil then -// PatBlt(TiledMask.Canvas.Handle, 0, 0, IW, IH, Whiteness); -// end -// else -// TiledMask := nil; -// -// TiledImage := ThtBitmapImage.Create(TiledBitmap, TiledMask, BGImage.Transp); -// end; -// Tile(BGImage.Bitmap, BGImage.Mask, OW, OH); -// end; -//end; - -{ TgpObject } - -function EnlargeImage(Image: TBitmap; W, H: Integer): TBitmap; -{enlarge 1 pixel images for tiling. Returns a TBitmap regardless of Image type} -begin - Result := TBitmap.Create; - Result.Assign(Image); - if Image.Width = 1 then - Result.Width := Min(100, W) - else - Result.Width := Image.Width; - if Image.Height = 1 then - Result.Height := Min(100, H) - else - Result.Height := Image.Height; - Result.Canvas.StretchDraw(Rect(0, 0, Result.Width, Result.Height), Image); -end; - -{----------------PrintBitmap} - -{$ifdef LCL} -{$else} -type - ThtAllocRec = class(TObject) - public - Ptr: Pointer; - ASize: Integer; - AHandle: HGLOBAL; - end; -{$endif} - -procedure PrintBitmap(Canvas: TCanvas; X, Y, W, H: Integer; Bitmap: TBitmap); -{Y relative to top of display here} - -{$ifdef LCL} -begin - Canvas.StretchDraw(Rect(X, Y, X + W, Y + H), Bitmap); -end; -{$else} - - function Allocate(Size: Integer): ThtAllocRec; - begin - Result := ThtAllocRec.Create; - with Result do - begin - ASize := Size; - if Size < $FF00 then - GetMem(Ptr, Size) - else - begin - AHandle := GlobalAlloc(HeapAllocFlags, Size); - if AHandle = 0 then - Abort; - Ptr := GlobalLock(AHandle); - end; - end; - end; - - procedure DeAllocate(AR: ThtAllocRec); - begin - with AR do - if ASize < $FF00 then - Freemem(Ptr, ASize) - else - begin - GlobalUnlock(AHandle); - GlobalFree(AHandle); - end; - AR.Free; - end; - -var - OldPal: HPalette; - DC: HDC; - Info: PBitmapInfo; - Image: ThtAllocRec; - ImageSize: DWord; - InfoSize: DWord; - -begin - if (Bitmap = nil) or (Bitmap.Handle = 0) then - Exit; - DC := Canvas.Handle; - try - GetDIBSizes(Bitmap.Handle, InfoSize, ImageSize); - GetMem(Info, InfoSize); - try - Image := Allocate(ImageSize); - OldPal := SelectPalette(DC, ThePalette, False); - try - GetDIB(Bitmap.Handle, ThePalette, Info^, Image.Ptr^); - RealizePalette(DC); - with Info^.bmiHeader do - StretchDIBits(DC, X, Y, W, H, 0, 0, biWidth, biHeight, Image.Ptr, Info^, DIB_RGB_COLORS, SRCCOPY); - finally - DeAllocate(Image); - SelectPalette(DC, OldPal, False); - end; - finally - FreeMem(Info, InfoSize); - end; - except - end; -end; -{$endif} - -{----------------PrintTransparentBitmap3} - -procedure PrintTransparentBitmap3(Canvas: TCanvas; X, Y, NewW, NewH: Integer; - Bitmap, Mask: TBitmap; YI, HI: Integer); -{Y relative to top of display here} -{This routine prints transparently on complex background by printing through a clip region} -{X, Y are point where upper left corner will be printed. - NewW, NewH are the Width and Height of the output (possibly stretched) - Vertically only a portion of the Bitmap, Mask may be printed starting at - Y=YI in the bitmap and a height of HI -} -var - DC: HDC; - Rgn, OldRgn: HRGN; - Rslt: Integer; - XForm: TXForm; - SizeV, SizeW: TSize; - HF, VF: double; - ABitmap, AMask: TBitmap; - BitmapCopy: boolean; - Origin: TPoint; //BG, 29.08.2009: window origin for correct mask translation -begin -{the following converts the black masked area in the image to white. This may look - better in WPTools which currently doesn't handle the masking} - if (Bitmap.Handle = 0) or (HI <= 0) or (Bitmap.Width <= 0) then - Exit; - BitmapCopy := Bitmap.Height <> HI; - try - if BitmapCopy then - begin - ABitmap := TBitmap.Create; - AMask := TBitmap.Create; - end - else - begin - ABitmap := Bitmap; - AMask := Mask; - end; - try - if BitmapCopy then - begin - Abitmap.Assign(Bitmap); - ABitmap.Height := HI; - BitBlt(ABitmap.Canvas.Handle, 0, 0, Bitmap.Width, HI, Bitmap.Canvas.Handle, 0, YI, SrcCopy); - AMask.Assign(Mask); - AMask.Height := HI; - BitBlt(AMask.Canvas.Handle, 0, 0, AMask.Width, HI, Mask.Canvas.Handle, 0, YI, SrcCopy); - end; - - SetBkColor(ABitmap.Canvas.Handle, clWhite); - SetTextColor(ABitmap.Canvas.Handle, clBlack); - BitBlt(ABitmap.Canvas.Handle, 0, 0, Bitmap.Width, HI, AMask.Canvas.Handle, 0, 0, SRCPAINT); - - DC := Canvas.Handle; - {calculate a transform for the clip region as it may be a different size than - the mask and needs to be positioned on the canvas.} - GetViewportExtEx(DC, SizeV); - GetWindowExtEx(DC, SizeW); - GetWindowOrgEx(DC, Origin); //BG, 29.08.2009: get origin for correct mask translation - - HF := (SizeV.cx / SizeW.cx); {Horizontal adjustment factor} - VF := (SizeV.cy / SizeW.cy); {Vertical adjustment factor} - - XForm.eM11 := HF * (NewW / Bitmap.Width); - XForm.eM12 := 0; - XForm.eM21 := 0; - XForm.eM22 := VF * (NewH / HI); - XForm.edx := HF * (X - Origin.X); //BG, 29.08.2009: subtract origin - XForm.edy := VF * Y; - - {Find the region for the white area of the Mask} - Rgn := BitmapToRegion(AMask, @XForm, $FFFFFF); - if Rgn <> 0 then {else nothing to output--this would be unusual} - begin - OldRgn := CreateRectRgn(0, 0, 1, 1); {a valid region is needed for the next call} - Rslt := GetClipRgn(DC, OldRgn); {save the Old clip region} - try - if Rslt = 1 then - CombineRgn(Rgn, Rgn, OldRgn, RGN_AND); - SelectClipRgn(DC, Rgn); - PrintBitmap(Canvas, X, Y, NewW, NewH, ABitmap); - finally - if Rslt = 1 then - SelectClipRgn(DC, OldRgn) - else - SelectClipRgn(DC, 0); - DeleteObject(Rgn); - DeleteObject(OldRgn); - end; - end; - finally - if BitmapCopy then - begin - ABitmap.Free; - AMask.Free; - end; - end; - except - end; -end; - -{$IFNDEF NoGDIPlus} - -procedure DrawGpImage(Handle: HDC; Image: ThtGpImage; DestX, DestY: Integer); -{Draws the entire image as specified at the point specified} -var - g: ThtGpGraphics; -begin - g := ThtGpGraphics.Create(Handle); - try - g.DrawImage(Image, DestX, DestY, Image.Width, Image.Height); - except - end; - g.Free; -end; - -procedure DrawGpImage(Handle: HDC; Image: ThtGpImage; DestX, DestY, - SrcX, SrcY, SrcW, SrcH: Integer); -{Draw a portion of the image at DestX, DestY. No stretching} -var - g: ThtGpGraphics; -begin - g := ThtGpGraphics.Create(Handle); - try - g.DrawImage(Image, DestX, DestY, SrcX, SrcY, SrcW, SrcH); - except - end; - g.Free; -end; - -procedure StretchDrawGpImage(Handle: HDC; Image: ThtGpImage; DestX, DestY, - DestW, DestH: Integer); -{Draws the entire image in the rectangle specified} -var - g: ThtGpGraphics; -begin - g := ThtGpGraphics.Create(Handle); - try - g.DrawImage(Image, DestX, DestY, DestW, DestH); - except - end; - g.Free; -end; - -procedure StretchPrintGpImageDirect(Handle: HDC; Image: ThtGpImage; - DestX, DestY, DestW, DestH: Integer; - ScaleX, ScaleY: single); -{Prints the entire image at the point specified with the height and width specified} -var - g: ThtGpGraphics; -begin - g := ThtGpGraphics.Create(Handle); - try - g.ScaleTransform(ScaleX, ScaleY); - g.DrawImage(Image, DestX, DestY, DestW, DestH); - except - end; - g.Free; -end; - -procedure StretchPrintGpImageOnColor(Canvas: TCanvas; Image: ThtGpImage; - DestX, DestY, DestW, DestH: Integer; Color: TColor = clWhite); -var - g: ThtGpGraphics; - bg: TBitmap; -begin {Draw image on white background first, then print} - bg := TBitmap.Create; - bg.Width := ThtGpImage(Image).Width; - bg.Height := ThtGpImage(Image).Height; - bg.Canvas.Brush.Color := Color; - bg.Canvas.FillRect(Rect(0, 0, bg.Width, bg.Height)); - g := ThtGpGraphics.Create(bg.Canvas.Handle); - g.DrawImage(ThtGpImage(Image), 0, 0, bg.Width, bg.Height); - g.Free; - Canvas.StretchDraw(Rect(DestX, DestY, DestX + DestW, DestY + DestH), bg); - bg.Free; -end; - -procedure PrintGpImageDirect(Handle: HDC; Image: ThtGpImage; DestX, DestY: Integer; - ScaleX, ScaleY: single); -{Prints the entire image as specified at the point specified} -var - g: ThtGpGraphics; -begin - g := ThtGpGraphics.Create(Handle); - try - g.ScaleTransform(ScaleX, ScaleY); - g.DrawImage(Image, DestX, DestY, Image.Width, Image.Height); - except - end; - g.Free; -end; - -{$ENDIF NoGDIPlus} - -{ TDib } - -constructor TDib.CreateDIB(DC: HDC; Bitmap: TBitmap); -{given a TBitmap, construct a device independent bitmap} -var - ImgSize: DWord; -begin - InitializeBitmapInfoHeader(Bitmap.Handle); - ImgSize := Info^.biSizeImage; - Allocate(ImgSize); - try - GetDIBX(DC, Bitmap.Handle, Bitmap.Palette); - except - DeAllocate; - raise; - end; -end; - -destructor TDib.Destroy; -begin - DeAllocate; - inherited Destroy; -end; - -procedure TDib.Allocate(Size: Integer); -begin - ImageSize := Size; - if Size < $FF00 then - GetMem(Image, Size) - else - begin - FHandle := GlobalAlloc(HeapAllocFlags, Size); - if FHandle = 0 then - ABort; - Image := GlobalLock(FHandle); - end; -end; - -procedure TDib.DeAllocate; -begin - if ImageSize > 0 then - begin - if ImageSize < $FF00 then - Freemem(Image, ImageSize) - else - begin - GlobalUnlock(FHandle); - GlobalFree(FHandle); - end; - ImageSize := 0; - end; - if InfoSize > 0 then - begin - FreeMem(Info, InfoSize); - InfoSize := 0; - end; -end; - -procedure TDib.InitializeBitmapInfoHeader(Bitmap: HBITMAP); -var - BM: {$ifdef LCL} LclType.Bitmap {$else} Windows.TBitmap {$endif}; - BitCount: Integer; - - function WidthBytes(I: Integer): Integer; - begin - Result := ((I + 31) div 32) * 4; - end; - -begin - GetObject(Bitmap, SizeOf(BM), @BM); - BitCount := BM.bmBitsPixel * BM.bmPlanes; - if BitCount > 8 then - InfoSize := SizeOf(TBitmapInfoHeader) - else - InfoSize := SizeOf(TBitmapInfoHeader) + SizeOf(TRGBQuad) * (1 shl BitCount); - GetMem(Info, InfoSize); - - with Info^ do - begin - biSize := SizeOf(TBitmapInfoHeader); - biWidth := BM.bmWidth; - biHeight := BM.bmHeight; - biBitCount := BM.bmBitsPixel * BM.bmPlanes; - biPlanes := 1; - biXPelsPerMeter := 0; - biYPelsPerMeter := 0; - biClrUsed := 0; - biClrImportant := 0; - biCompression := BI_RGB; - if biBitCount in [16, 32] then - biBitCount := 24; - biSizeImage := WidthBytes(biWidth * biBitCount) * biHeight; - end; -end; - -procedure TDib.GetDIBX(DC: HDC; Bitmap: HBITMAP; Palette: HPALETTE); -var - OldPal: HPALETTE; - Rslt: Integer; - bmInfo: PBitmapInfo; -begin - OldPal := 0; - if Palette <> 0 then - begin - OldPal := SelectPalette(DC, Palette, False); - RealizePalette(DC); - end; - bmInfo := PBitmapInfo(Info); - Rslt := GetDIBits(DC, Bitmap, 0, Info^.biHeight, Image, bmInfo^, DIB_RGB_COLORS); - if OldPal <> 0 then - SelectPalette(DC, OldPal, False); - if Rslt = 0 then - begin - OutofMemoryError; - end; -end; - -procedure TDib.DrawDIB(DC: HDC; X, Y, W, H: Integer; ROP: DWord); -var - bmInfo: PBitmapInfo; -begin - bmInfo := PBitmapInfo(Info); - with Info^ do - StretchDIBits(DC, X, Y, W, H, 0, 0, biWidth, biHeight, Image, - bmInfo^, DIB_RGB_COLORS, ROP); -end; - -function TDib.CreateDIBmp: hBitmap; -var - bmInfo: PBitmapInfo; - DC: HDC; - OldPal: HPalette; -begin - bmInfo := PBitmapInfo(Info); - DC := GetDC(0); - OldPal := SelectPalette(DC, ThePalette, False); - RealizePalette(DC); - try - Result := CreateDIBitmap(DC, bmInfo^.bmiHeader, CBM_INIT, Image, - bmInfo^, DIB_RGB_COLORS); - finally - SelectPalette(DC, OldPal, False); - ReleaseDC(0, DC); - end; -end; - -{ ThtImage } - -//-- BG ---------------------------------------------------------- 02.09.2015 -- -function ThtImage.Clone: ThtImage; -begin - // currently only animated images need to be cloneable! - Result := nil; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -constructor ThtImage.Create(Tr: ThtImageTransparency); -begin - inherited Create; - Transp := Tr; -end; - -//-- BG ---------------------------------------------------------- 31.08.2015 -- -procedure ThtImage.Draw(Canvas: TCanvas; X, Y, W, H: Integer); -begin - if Graphic <> nil then - Canvas.StretchDraw(Rect(X, Y, X + W, Y + H), Graphic); -end; - -//-- BG ---------------------------------------------------------- 06.09.2015 -- -procedure ThtImage.DrawUnstretched(Canvas: TCanvas; X, Y, W, H, SrcX, SrcY: Integer; FillBackground: Boolean); -begin - //TODO -oBG, 06.09.2015: draw any kind of image unstretched -end; - -//-- BG ---------------------------------------------------------- 06.09.2015 -- -function ThtImage.EnlargeBitmap(Bitmap: TBitmap; W, H: Integer): TBitmap; -{enlarge 1 pixel images for tiling. Returns a TBitmap regardless of Image type} -begin - if Bitmap = nil then - Result := nil - else - begin - Result := ThtBitmap.Create; - Result.Assign(Bitmap); - if Result.Width = 1 then - Result.Width := Min(100, W); - if Result.Height = 1 then - Result.Height := Min(100, H); - Result.Canvas.StretchDraw(Rect(0, 0, Result.Width, Result.Height), Bitmap); - end; -end; - -//-- BG ---------------------------------------------------------- 06.09.2015 -- -function ThtImage.EnlargeImage(W, H: Integer): ThtImage; -begin - Result := ThtBitmapImage.Create( - EnlargeBitmap(Bitmap, W, H), - EnlargeBitmap(Mask , W, H), Transp); -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -procedure ThtImage.DrawTiled(Canvas: TCanvas; XStart, YStart, XEnd, YEnd, W, H: Integer); -var - X, Y: Integer; -begin - Y := YStart; - while Y < YEnd do - begin - X := XStart; - while X < XEnd do - begin - Draw(Canvas, X, Y, W, H); - Inc(X, W); - end; - Inc(Y, H); - end; -end; - -//-- BG ---------------------------------------------------------- 02.09.2015 -- -function ThtImage.GetAnimate: Boolean; -begin - Result := False; -end; - -//-- BG ---------------------------------------------------------- 10.04.2011 -- -function ThtImage.GetGraphic: TGraphic; -begin - Result := GetBitmap; -end; - -//-- BG ---------------------------------------------------------- 02.09.2015 -- -function ThtImage.IsAnimated: Boolean; -begin - Result := False; -end; - -//-- BG ---------------------------------------------------------- 31.08.2015 -- -procedure ThtImage.Print(Canvas: TCanvas; X, Y, W, H: Integer; BgColor: TColor); -begin - if Graphic <> nil then - Canvas.StretchDraw(Rect(X, Y, X + W, Y + H), Graphic); -end; - -//-- BG ---------------------------------------------------------- 10.04.2011 -- -procedure ThtImage.PrintTiled(Canvas: TCanvas; XStart, YStart, XEnd, YEnd, W, H: Integer; BgColor: TColor); -var - X, Y: Integer; -begin - Y := YStart; - while Y < YEnd do - begin - X := XStart; - while X < XEnd do - begin - Print(Canvas, X, Y, W, H, BgColor); - Inc(X, W); - end; - Inc(Y, H); - end; -end; - -//-- BG ---------------------------------------------------------- 06.09.2015 -- -procedure ThtImage.PrintUnstretched(Canvas: TCanvas; X, Y, W, H, SrcX, SrcY: Integer; FillBackground: Boolean); -begin - //TODO -oBG, 06.09.2015: print any kind of image unstretched -end; - -//-- BG ---------------------------------------------------------- 02.09.2015 -- -procedure ThtImage.SetAnimate(const Value: Boolean); -begin - // do nothing as base class is not animated -end; - -//-- BG ---------------------------------------------------------- 06.09.2015 -- -procedure ThtImage.TileImage(PRec: PtPositionRec; DstW, DstH: Integer; var TiledImage: ThtImage; var NoMask: Boolean); -{EnlargeImage returns a ThtBitmapImage in TiledImage regardless of Self type. Descendants may return other types} - - procedure Enlarge(W, H: Integer); - var - LargerImage: ThtImage; - begin - LargerImage := EnlargeImage(W + 1, H + 1); - try - LargerImage.TileImage(PRec, DstW, DstH, TiledImage, NoMask); - finally - LargerImage.Free; - end; - end; - -var - OW, OH, IW, IH: Integer; - X, XX, Y, X2, Y2: Integer; - - procedure ValidateTiledImage; - var - TiledBitmap, TiledMask: TBitmap; - begin - {TiledImage becomes a ThtBitmapImage} - if TiledImage = nil then - begin - TiledBitmap := TBitmap.Create; - TiledBitmap.Palette := CopyPalette(ThePalette); - TiledBitmap.Height := IH; - TiledBitmap.Width := IW; - PatBlt(TiledBitmap.Canvas.Handle, 0, 0, IW, IH, Blackness); - - if not NoMask then - begin - TiledMask := TBitmap.Create; - TiledMask.Monochrome := True; - TiledMask.Height := IH; - TiledMask.Width := IW; - if Mask = nil then - PatBlt(TiledMask.Canvas.Handle, 0, 0, IW, IH, Whiteness); - end - else - TiledMask := nil; - - TiledImage := ThtBitmapImage.Create(TiledBitmap, TiledMask, Transp); - end; - end; - - procedure Tile(W, H: Integer); - begin - - repeat {tile BGImage in the various dc's} - XX := X; - repeat - TiledImage.Bitmap.Canvas.Draw(XX, Y, Bitmap); - if Mask <> nil then - TiledImage.Mask.Canvas.Draw(XX, Y, Mask) - else if not NoMask then - PatBlt(TiledImage.Mask.Canvas.Handle, XX, Y, Bitmap.Width, Bitmap.Height, Blackness); - Inc(XX, Bitmap.Width); - until XX >= X2; - Inc(Y, Bitmap.Height); - until Y >= Y2; - end; - -begin - IW := DstW; - IH := DstH; - OW := Width; - OH := Height; - - if (IW = 0) or (IH = 0) then - begin - FreeAndNil(TiledImage); - NoMask := True; - end - else if (OW = 1) or (OH = 1) then - begin - {in case a 1 pixel bitmap is being tiled} - Enlarge(IW, IH); - end - else - begin - {compute the location and tiling of BGImage in the background} - with PRec.X do - begin - X := GetPositionInRange(PosType, Value, IW - OW); - AdjustForTiling(RepeatD, 0, IW, OW, X, X2); - end; - with PRec.Y do - begin - Y := GetPositionInRange(PosType, Value, IH - OH); - AdjustForTiling(RepeatD, 0, IH, OH, Y, Y2); - end; - - NoMask := not Assigned(Mask) and PRec.X.RepeatD and PRec.Y.RepeatD; - - ValidateTiledImage; - Tile(OW, OH); - end; -end; - -{ ThtBitmapImage } - -//-- BG ---------------------------------------------------------- 29.09.2015 -- -constructor ThtBitmapImage.Create(AImage: ThtBitmap; Tr: ThtImageTransparency; AOwnsBitmap: Boolean); -begin - if AImage = nil then - raise EInvalidImage.Create('ThtBitmapImage requires an image'); - inherited Create(Tr); - Bitmap := AImage; - OwnsBitmap := AOwnsBitmap; - Mask := AImage.Mask; - OwnsMask := False; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -constructor ThtBitmapImage.Create(AImage, AMask: TBitmap; Tr: ThtImageTransparency; AOwnsBitmap, AOwnsMask: Boolean); -begin - if AImage = nil then - raise EInvalidImage.Create('ThtBitmapImage requires an image'); - inherited Create(Tr); - Bitmap := AImage; - OwnsBitmap := AOwnsBitmap; - Mask := AMask; - OwnsMask := AOwnsMask; -end; - -//-- BG ---------------------------------------------------------- 10.01.2015 -- -constructor ThtBitmapImage.Create(AImage: TBitmap; Tr: ThtImageTransparency; Color: TColor; AOwnsBitmap: Boolean); -begin - if AImage = nil then - raise EInvalidImage.Create('ThtBitmapImage requires an image'); - inherited Create(Tr); - Bitmap := AImage; - OwnsBitmap := AOwnsBitmap; - case Transp of - itrIntrinsic: Mask := GetImageMask(Bitmap, True, Color); - itrLLCorner: Mask := GetImageMask(Bitmap, False, Color); - end; -end; - -destructor ThtBitmapImage.Destroy; -begin - if OwnsBitmap then - Bitmap.Free; - if OwnsMask then - Mask.Free; - inherited; -end; - -//-- BG ---------------------------------------------------------- 06.09.2015 -- -procedure ThtBitmapImage.DrawUnstretched(Canvas: TCanvas; X, Y, W, H, SrcX, SrcY: Integer; FillBackground: Boolean); -var - FullBG: TBitmap; -begin - if Bitmap = nil then - Exit; - if (Mask = nil) or (Transp = itrNone) then - BitBlt(Canvas.Handle, X, Y, W, H, Bitmap.Canvas.Handle, SrcX, SrcY, SRCCOPY) - else - begin - FullBG := nil; - InitFullBG(FullBG, W, H, False); - try - if FillBackground then - begin - FullBG.Canvas.Brush := Canvas.Brush; - FullBG.Canvas.FillRect( Rect(0, 0, W, H)); - end - else - BitBlt(FullBG.Canvas.Handle, 0, 0, W, H, Canvas.Handle, X, Y, SRCCOPY ); - - BitBlt(FullBG.Canvas.Handle, 0, 0, W, H, Bitmap.Canvas.Handle, 0, SrcY, SRCINVERT ); - BitBlt(FullBG.Canvas.Handle, 0, 0, W, H, Mask.Canvas.Handle, 0, SrcY, SRCAND ); - BitBlt(FullBG.Canvas.Handle, 0, 0, W, H, Bitmap.Canvas.Handle, 0, SrcY, SRCPAINT ); - - BitBlt( Canvas.Handle, X, Y, W, H, FullBG.Canvas.Handle, 0, 0, SRCCOPY ); - finally - FullBG.Free; - end; - end; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -function ThtBitmapImage.GetBitmap: TBitmap; -begin - Result := Bitmap; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -function ThtBitmapImage.GetImageHeight: Integer; -begin - if Bitmap <> nil then - Result := Bitmap.Height - else - Result := 0; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -function ThtBitmapImage.GetImageWidth: Integer; -begin - if Bitmap <> nil then - Result := Bitmap.Width - else - Result := 0; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -function ThtBitmapImage.GetMask: TBitmap; -begin - Result := Mask; -end; - -//-- BG ---------------------------------------------------------- 31.08.2015 -- -procedure ThtBitmapImage.Print(Canvas: TCanvas; X, Y, W, H: Integer; BgColor: TColor); -begin - if Transp = itrNone then - inherited - else if Mask = nil then - PrintBitmap(Canvas, X, Y, W, H, Bitmap) - else - PrintTransparentBitmap3(Canvas, X, Y, W, H, Bitmap, Mask, 0, Bitmap.Height); -end; - -//-- BG ---------------------------------------------------------- 06.09.2015 -- -procedure ThtBitmapImage.PrintUnstretched(Canvas: TCanvas; X, Y, W, H, SrcX, SrcY: Integer; FillBackground: Boolean); -var - FullBG: TBitmap; -begin - if Bitmap = nil then - Exit; - if (Mask = nil) or (Transp = itrNone) then - PrintBitmap(Canvas, X, Y, W, H, Bitmap) - else if FillBackground then - begin - FullBG := nil; - InitFullBG(FullBG, W, H, True); - try - FullBG.Canvas.Brush := Canvas.Brush; - FullBG.Canvas.FillRect( Rect(0, 0, W, H)); - - BitBlt(FullBG.Canvas.Handle, 0, 0, W, H, Bitmap.Canvas.Handle, 0, SrcY, SRCINVERT ); - BitBlt(FullBG.Canvas.Handle, 0, 0, W, H, Mask.Canvas.Handle, 0, SrcY, SRCAND ); - BitBlt(FullBG.Canvas.Handle, 0, 0, W, H, Bitmap.Canvas.Handle, 0, SrcY, SRCPAINT ); - - PrintBitmap(Canvas, X, Y, W, H, FullBG); - finally - FullBG.Free; - end; - end - else - PrintTransparentBitmap3(Canvas, X, Y, W, H, Bitmap, Mask, SrcY, H); -end; - -{ ThtGifImage } - -//-- BG ---------------------------------------------------------- 11.04.2011 -- -function ThtGifImage.Clone: ThtImage; -begin - Result := ThtGifImage.Create(TGIFImage.CreateCopy(Gif)); -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -constructor ThtGifImage.Create(AImage: TGifImage); -begin - inherited Create(itrIntrinsic); - FGif := AImage; -end; - -//-- BG ---------------------------------------------------------- 10.04.2011 -- -destructor ThtGifImage.Destroy; -begin - FGif.Free; - inherited; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -procedure ThtGifImage.Draw(Canvas: TCanvas; X, Y, W, H: Integer); -begin - Gif.ShowIt := True; // animate it - //Gif.Draw(Canvas, Rect(X, Y, X + W, Y + H)); - inherited; -end; - -//-- BG ---------------------------------------------------------- 02.09.2015 -- -function ThtGifImage.GetAnimate: Boolean; -begin - Result := Gif.Animate; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -function ThtGifImage.GetBitmap: TBitmap; -begin - Result := Gif; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -function ThtGifImage.GetImageHeight: Integer; -begin - Result := Gif.Height; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -function ThtGifImage.GetImageWidth: Integer; -begin - Result := Gif.Width; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -function ThtGifImage.GetMask: TBitmap; -begin - Result := Gif.Mask; -end; - -//-- BG ---------------------------------------------------------- 02.09.2015 -- -function ThtGifImage.IsAnimated: Boolean; -begin - Result := Gif.IsAnimated; -end; - -//-- BG ---------------------------------------------------------- 02.09.2015 -- -procedure ThtGifImage.SetAnimate(const Value: Boolean); -begin - Gif.Animate := Value; -end; - -{$IFNDEF NoGDIPlus} - -{ ThtGdipImage } - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -constructor ThtGdipImage.Create(AImage: ThtGpImage); -begin - inherited Create(itrIntrinsic); - Gpi := AImage; -end; - -//-- BG ---------------------------------------------------------- 10.04.2011 -- -destructor ThtGdipImage.Destroy; -begin - Gpi.Free; - inherited; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -procedure ThtGdipImage.Draw(Canvas: TCanvas; X, Y, W, H: Integer); -var - Graphics: ThtGpGraphics; -begin - Graphics := ThtGpGraphics.Create(Canvas.Handle); - try - Graphics.DrawImage(Gpi, X, Y, W, H); - finally - Graphics.Free; - end; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -procedure ThtGdipImage.DrawTiled(Canvas: TCanvas; XStart, YStart, XEnd, YEnd, W, H: Integer); -var - X, Y: Integer; - Graphics: ThtGpGraphics; -begin - Y := YStart; - Graphics := ThtGpGraphics.Create(Canvas.Handle); - try - while Y < YEnd do - begin - X := XStart; - while X < XEnd do - begin - Graphics.DrawImage(Gpi, X, Y, W, H); - Inc(X, W); - end; - Inc(Y, H); - end; - finally - Graphics.Free; - end; -end; - -//-- BG ---------------------------------------------------------- 06.09.2015 -- -procedure ThtGdipImage.DrawUnstretched(Canvas: TCanvas; X, Y, W, H, SrcX, SrcY: Integer; FillBackground: Boolean); -begin - DrawGpImage(Canvas.Handle, Gpi, X, Y, SrcX, SrcY, W, H); -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -function ThtGdipImage.GetBitmap: TBitmap; -begin - Result := Gpi.GetBitmap; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -function ThtGdipImage.GetImageHeight: Integer; -begin - Result := Gpi.Height; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -function ThtGdipImage.GetImageWidth: Integer; -begin - Result := Gpi.Width; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -function ThtGdipImage.GetMask: TBitmap; -begin - Result := nil; -end; - -//-- BG ---------------------------------------------------------- 10.04.2011 -- -procedure ThtGdipImage.Print(Canvas: TCanvas; X, Y, W, H: Integer; BgColor: TColor); -begin - StretchPrintGpImageOnColor(Canvas, Gpi, X, Y, W, H, BGColor); -end; - -//-- BG ---------------------------------------------------------- 06.09.2015 -- -procedure ThtGdipImage.PrintUnstretched(Canvas: TCanvas; X, Y, W, H, SrcX, SrcY: Integer; FillBackground: Boolean); -var - FullBG: TBitmap; -begin - if FillBackground then - begin - FullBG := nil; - InitFullBG(FullBG, W, H, True); - try - FullBG.Canvas.Brush := Canvas.Brush; - FullBG.Canvas.FillRect(Rect(0, 0, W, H)); - - DrawGpImage(FullBg.Canvas.Handle, Gpi, 0, 0); - - PrintBitmap(Canvas, X, Y, W, H, FullBG); - finally - FullBG.Free; - end; - end - else - PrintGpImageDirect(Canvas.Handle, Gpi, X, Y{, Document.ScaleX, Document.ScaleY}); - -end; - -{$ENDIF NoGDIPlus} - -{ ThtGraphicImage } - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -constructor ThtGraphicImage.Create(AGraphic: TGraphic); -begin - inherited Create(itrNone); - FGraphic := AGraphic; -end; - -//-- BG ---------------------------------------------------------- 10.04.2011 -- -destructor ThtGraphicImage.Destroy; -begin - FImage.Free; - FGraphic.Free; - inherited; -end; - -procedure ThtGraphicImage.Construct; -var - Tmp: TBitmap; - pe: TPaletteEntry; - Color: TColor; - FBitmap: TBitmap; -begin - if not Assigned(FImage) then - begin - FBitmap := TBitmap.Create; - try - FBitmap.Width := Width; - FBitmap.Height := Height; - PatBlt(FBitmap.Canvas.Handle, 0, 0, Width, Height, Blackness); - FBitmap.Canvas.Draw(0, 0, FGraphic); - - Tmp := TBitmap.Create; - try - Tmp.Width := Width; - Tmp.Height := Height; - Tmp.PixelFormat := pf8Bit; - {pick an odd color from the palette to represent the background color, - one not likely in the metafile} - GetPaletteEntries(Tmp.Palette, 115, 1, pe); - Color := pe.peBlue shl 16 or pe.peGreen shl 8 or pe.peRed; - Tmp.Canvas.Brush.Color := Color; - Tmp.Canvas.FillRect(Rect(0, 0, Width, Height)); - Tmp.Canvas.Draw(0, 0, FGraphic); - - FImage := ThtBitmapImage.Create(FBitmap, GetImageMask(Tmp, False, Color), itrLLCorner); - finally - Tmp.Free; - end; - except - FreeAndNil(FBitmap); - end; - end; -end; - -////-- BG ---------------------------------------------------------- 09.04.2011 -- -//procedure ThtGraphicImage.Draw(Canvas: TCanvas; X, Y, W, H: Integer); -//begin -// Canvas.StretchDraw(Rect(X, Y, X + W, Y + H), FGraphic); -//end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -function ThtGraphicImage.GetBitmap: TBitmap; -begin - Construct; - Result := FImage.Bitmap; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -function ThtGraphicImage.GetGraphic: TGraphic; -begin - Result := FGraphic; -end; - -function ThtGraphicImage.GetImageHeight: Integer; -begin - Result := FGraphic.Height; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -function ThtGraphicImage.GetImageWidth: Integer; -begin - Result := FGraphic.Width; -end; - -//-- BG ---------------------------------------------------------- 09.04.2011 -- -function ThtGraphicImage.GetMask: TBitmap; -begin - Construct; - Result := FImage.Mask; -end; - -{ ThtImageCache } - -//------------------------------------------------------------------------------ -constructor ThtImageCache.Create; -begin - inherited Create; - {$IFNDEF NoGDIPlus} - CheckInitGDIPlus; - {$ENDIF NoGDIPlus} -end; - -//------------------------------------------------------------------------------ -destructor ThtImageCache.Destroy; -begin - {$IFNDEF NoGDIPlus} - // must exit GDI after freeing images in clear! - Clear; - CheckExitGDIPlus; - {$ENDIF NoGDIPlus} - inherited Destroy; -end; - -//------------------------------------------------------------------------------ -function ThtImageCache.AddObject(const S: ThtString; AObject: ThtImage): Integer; -begin - Result := inherited AddObject(S, AObject); -end; - -//-- BG ---------------------------------------------------------- 11.04.2011 -- -function ThtImageCache.GetImage(I: Integer): ThtImage; -begin - Result := ThtImage(inherited GetCachable(I)); -end; - -//-- BG ---------------------------------------------------------- 19.08.2011 -- -procedure ThtImageCache.InsertImage(Index: Integer; const S: ThtString; AObject: ThtImage); -begin - InsertItem(Index, S, AObject); -end; - -{ ThtBitmapToInsert } - -constructor ThtBitmapToInsert.Create(AImage: TBitmap; ATransp: ThtImageTransparency; AColor: TColor; AOwnsBitmap: Boolean); -begin - Bitmap := AImage; - Color := AColor; - Transp := ATransp; - OwnsBitmap := AOwnsBitmap; -end; - -{ ThtImageList } - -//-- BG ---------------------------------------------------------- 06.10.2016 -- -function ThtImageList.Get(Index: Integer): ThtImage; -begin - Result := inherited Get(Index); -end; - -initialization - DefBitMap := TBitmap.Create; - ErrorBitMap := TBitmap.Create; - ErrorBitMapMask := TBitmap.Create; -{$ifdef LCL} - {$I htmlun2.lrs} - DefBitMap.LoadFromLazarusResource('DefaultBitmap'); - ErrorBitMap.LoadFromLazarusResource('ErrBitmap'); - ErrorBitMapMask.LoadFromLazarusResource('ErrBitmapMask'); - Screen.Cursors[HandCursor] := LoadCursorFromLazarusResource('Hand_Cursor'); - Screen.Cursors[UpDownCursor] := LoadCursorFromLazarusResource('UPDOWNCURSOR'); - Screen.Cursors[UpOnlyCursor] := LoadCursorFromLazarusResource('UPONLYCURSOR'); - Screen.Cursors[DownOnlyCursor] := LoadCursorFromLazarusResource('DOWNONLYCURSOR'); -{$else} - {$R Html32.res} - DefBitMap.Handle := LoadBitmap(HInstance, MakeIntResource(DefaultBitmap)); - ErrorBitMap.Handle := LoadBitmap(HInstance, MakeIntResource(ErrBitmap)); - ErrorBitMapMask.Handle := LoadBitmap(HInstance, MakeIntResource(ErrBitmapMask)); - Screen.Cursors[HandCursor] := LoadCursor(HInstance, MakeIntResource(Hand_Cursor)); - Screen.Cursors[UpDownCursor] := LoadCursor(HInstance, 'UPDOWNCURSOR'); - Screen.Cursors[UpOnlyCursor] := LoadCursor(HInstance, 'UPONLYCURSOR'); - Screen.Cursors[DownOnlyCursor] := LoadCursor(HInstance, 'DOWNONLYCURSOR'); -{$endif} - - DefImage := ThtBitmapImage.Create(DefBitmap, nil, itrNone); - ErrorImage := ThtBitmapImage.Create(ErrorBitmap, ErrorBitmapMask, itrLLCorner); -// ImageLoader := nil; -finalization - ImageLoader.Free; - ErrorImage.Free; - DefImage.Free; -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/HtmlSymb.pas b/CORE/Source/Plugins/Htmlviewer/source/HtmlSymb.pas deleted file mode 100644 index aa95b3605..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/HtmlSymb.pas +++ /dev/null @@ -1,926 +0,0 @@ -{ -Version 11.7 -Copyright (c) 2014-2016 by HtmlViewer Team - -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. - -Note that the source modules HTMLGIF1.PAS and DITHERUNIT.PAS -are covered by separate copyright notices located in those modules. -} - -{$I htmlcons.inc} - -unit HtmlSymb; - -interface - -uses -{$ifdef MSWINDOWS} - Windows, SysUtils, -{$endif} - HtmlGlobals; - -type - TElemSymb = ( - OtherChar, CommandSy, StringSy {was TextSy}, EolSy, EofSy, - - { doc type tags } - XmlSy, DocTypeSy, - - { html elements } - - HtmlSy, HeadSy, - HtmlEndSy, HeadEndSy, - - { frame set elements } - - FrameSetSy, FrameSetEndSy, - FrameSy, - NoFramesSy, NoFramesEndSy, - - { metadata elements } - - TitleElemSy, TitleEndSy, - BaseSy, - LinkElemSy, - MetaSy, - StyleSy, StyleEndSy, - ScriptSy, ScriptEndSy, - - { misc elements } - - BaseFontSy, - BgSoundSy, - - HRSy, - BRSy, - - ImageSy, - PanelSy, - IFrameSy, IFrameEndSy, - ProgressSy, ProgressEndSy, - MeterSy, MeterEndSy, - - MapSy, MapEndSy, - AreaSy, - - PageSy, - - ObjectSy, ObjectEndSy, - ParamSy, - - { inline elements } - - SpanSy, NoBrSy, - SpanEndSy, NoBrEndSy, - - WbrSy, - - FontSy, BSy, ISy, SSy, StrikeSy, USy, SubSy, SupSy, BigSy, SmallSy, TTSy, - FontEndSy, BEndSy, IEndSy, SEndSy, StrikeEndSy, UEndSy, SubEndSy, SupEndSy, BigEndSy, SmallEndSy, TTEndSy, - - EmSy, StrongSy, CodeSy, KbdSy, SampSy, CiteSy, VarSy, AbbrSy, AcronymSy, DfnSy, - EmEndSy, StrongEndSy, CodeEndSy, KbdEndSy, SampEndSy, CiteEndSy, VarEndSy, AbbrEndSy, AcronymEndSy, DfnEndSy, - - DelSy, InsSy, MarkSy, TimeSy, - DelEndSy, InsEndSy, MarkEndSy, TimeEndSy, - - ASy, - AEndSy, - - { block elements } - - BodySy, PSy, DivSy, CenterSy, - BodyEndSy, PEndSy, DivEndSy, CenterEndSy, - - ArticleSy, SectionSy, MainSy, NavSy, AsideSy, - ArticleEndSy, SectionEndSy, MainEndSy, NavEndSy, AsideEndSy, - - {Keep order} H1Sy, H2Sy, H3Sy, H4Sy, H5Sy, H6Sy, {end order} - {Keep order} H1EndSy, H2EndSy, H3EndSy, H4EndSy, H5EndSy, H6EndSy, {end order} - - HGroupSy, HeaderSy, FooterSy, AddressSy, BlockQuoteSy, PreSy, - HGroupEndSy, HeaderEndSy, FooterEndSy, AddressEndSy, BlockQuoteEndSy, PreEndSy, - - OLSy, LISy, ULSy, DirSy, MenuSy, DLSy, DDSy, DTSy, - OLEndSy, LIEndSy, ULEndSy, DirEndSy, MenuEndSy, DLEndSy, DDEndSy, DTEndSy, - - liAloneSy, - - { table elements } - - TableSy, TableEndSy, - ColGroupSy, ColGroupEndSy, ColSy, - CaptionSy, CaptionEndSy, - THeadSy, TBodySy, TFootSy, - THeadEndSy, TBodyEndSy, TFootEndSy, - TRSy, TREndSy, - THSy, TDSy, - THEndSy, TDEndSy, - - { form elements } - - FormSy, FormEndSy, - FieldsetSy, FieldsetEndSy, - LegendSy, LegendEndSy, - LabelSy, LabelEndSy, - TextAreaSy, SelectSy, OptionSy, ButtonSy, ButtonEndSy, InputSy, - TextAreaEndSy, SelectEndSy, OptionEndSy - ); - TElemSymbSet = set of TElemSymb; - - TAttrSymb = ( - OtherAttribute, - ActionSy, - ActiveSy, - AlignSy, - AltSy, - BackgroundSy, - BGColorSy, - BGPropertiesSy, - BorderSy, - BorderColorSy, - BorderColorDarkSy, - BorderColorLightSy, - CellPaddingSy, - CellSpacingSy, - CharSetSy, - CheckBoxSy, - CheckedSy, - ClassSy, - ClearSy, - ColorSy, - ColsSy, - ColSpanSy, - ContentSy, - CoordsSy, - DisabledSy, - EncodingSy, - EncTypeSy, - FaceSy, - FrameAttrSy, - FrameBorderSy, - HeightSy, - HighSy, - HrefSy, - HSpaceSy, - HttpEqSy, - IDSy, - IsMapSy, - LabelAttrSy, - LanguageSy, - LeftMarginSy, - LinkSy, - LoopSy, - LowSy, - MarginHeightSy, - MarginWidthSy, - MaxSy, - MaxLengthSy, - MediaSy, - MethodSy, - MinSy, - MultipleSy, - NameSy, - NoHrefSy, - NoResizeSy, - NoShadeSy, - NoWrapSy, - OLinkSy, - OnBlurSy, - OnChangeSy, - OnClickSy, - OnFocusSy, - OptimumSy, - PlaceholderSy, - PlainSy, - RadioSy, - RatioSy, - ReadonlySy, - RelSy, - RevSy, - RowsSy, - RowSpanSy, - RulesSy, - ScrollingSy, - SelectedSy, - ShapeSy, - SizeSy, - SpanAttrSy, - SpellCheckSy, - SrcSy, - StartSy, - StyleAttrSy, - TabIndexSy, - TargetSy, - TextSy, - TitleSy, - TopMarginSy, - TranspSy, - TypeSy, - UseMapSy, - VAlignSy, - ValueSy, - VersionSy, - VLinkSy, - VSpaceSy, - WidthSy, - WrapSy); - TAttrSymbSet = set of TAttrSymb; - - PEntity = ^TEntity; - TEntity = record - Name: ThtString; - Value: Integer; - end; - - PResWord = ^TResWord; - TResWord = record - Name: ThtString; - Symbol: TElemSymb; - EndSym: TElemSymb; // CommandSy == no end symbol - end; - - PSymbol = ^TSymbolRec; - TSymbolRec = record - Name: ThtString; - Value: TAttrSymb; - end; - -var - Entities: ThtStringList; - ElementNames: ThtStringList; - AttributeNames: ThtStringList; - -procedure SetSymbolName(Sy: TElemSymb; Name: ThtString); overload; -procedure SetSymbolName(Sy: TAttrSymb; Name: ThtString); overload; -function SymbToStr(Sy: TElemSymb): ThtString; overload; -function SymbToStr(Sy: TAttrSymb): ThtString; overload; -function EndSymbToStr(Sy: TElemSymb): ThtString; -function EndSymbToSymb(Sy: TElemSymb): TElemSymb; -function EndSymbFromSymb(Sy: TElemSymb): TElemSymb; - -implementation - -var - ElementNamesIndex: array [TElemSymb] of Integer; - ElemSymbolNames: array [TElemSymb] of ThtString; - - AttrSymbolNames: array [TAttrSymb] of ThtString; - -procedure SetSymbolName(Sy: TElemSymb; Name: ThtString); overload; -begin - Name := htLowerCase(Name); - if ElemSymbolNames[Sy] <> '' then - assert(ElemSymbolNames[Sy] = Name, 'Different names for same element symbol!'); - ElemSymbolNames[Sy] := Name; -end; - -procedure SetSymbolName(Sy: TAttrSymb; Name: ThtString); overload; -begin - Name := htLowerCase(Name); - if AttrSymbolNames[Sy] <> '' then - assert(AttrSymbolNames[Sy] = Name, 'Different names for same attribute symbol!'); - AttrSymbolNames[Sy] := Name; -end; - -function SymbToStr(Sy: TElemSymb): ThtString; -begin - Result := ElemSymbolNames[Sy]; -end; - -function SymbToStr(Sy: TAttrSymb): ThtString; -begin - Result := AttrSymbolNames[Sy]; -end; - -function EndSymbToStr(Sy: TElemSymb): ThtString; -begin - Result := ElemSymbolNames[Sy]; -end; - -function EndSymbToSymb(Sy: TElemSymb): TElemSymb; -var - I: Integer; -begin - I := ElementNamesIndex[Sy]; - if I >= 0 then - Result := PResWord(ElementNames.Objects[I]).Symbol - else - Result := CommandSy; // no match -end; - -function EndSymbFromSymb(Sy: TElemSymb): TElemSymb; -var - I: Integer; -begin - I := ElementNamesIndex[Sy]; - if I >= 0 then - Result := PResWord(ElementNames.Objects[I]).EndSym - else - Result := CommandSy; // no match -end; - -procedure InitEntities; -const - // Taken from http://www.w3.org/TR/REC-html40/sgml/entities.html. - // Note: the entities will be sorted into a ThtStringList to make binary search possible. - EntityDefinitions: array[1..253] of TEntity = ( - // ISO 8859-1 characters - (Name: 'nbsp'; Value: 160), // no-break space = non-breaking space, U+00A0 ISOnum - (Name: 'iexcl'; Value: 161), // inverted exclamation mark, U+00A1 ISOnum - (Name: 'cent'; Value: 162), // cent sign, U+00A2 ISOnum - (Name: 'pound'; Value: 163), // pound sign, U+00A3 ISOnum - (Name: 'curren'; Value: 164), // currency sign, U+00A4 ISOnum - (Name: 'yen'; Value: 165), // yen sign = yuan sign, U+00A5 ISOnum - (Name: 'brvbar'; Value: 166), // broken bar = broken vertical bar, U+00A6 ISOnum - (Name: 'sect'; Value: 167), // section sign, U+00A7 ISOnum - (Name: 'uml'; Value: 168), // diaeresis = spacing diaeresis, U+00A8 ISOdia - (Name: 'copy'; Value: 169), // copyright sign, U+00A9 ISOnum - (Name: 'ordf'; Value: 170), // feminine ordinal indicator, U+00AA ISOnum - (Name: 'laquo'; Value: 171), // left-pointing double angle quotation mark = left pointing guillemet, U+00AB ISOnum - (Name: 'not'; Value: 172), // not sign, U+00AC ISOnum - (Name: 'shy'; Value: 173), // soft hyphen = discretionary hyphen, U+00AD ISOnum - (Name: 'reg'; Value: 174), // registered sign = registered trade mark sign, U+00AE ISOnum - (Name: 'macr'; Value: 175), // macron = spacing macron = overline = APL overbar, U+00AF ISOdia - (Name: 'deg'; Value: 176), // degree sign, U+00B0 ISOnum - (Name: 'plusmn'; Value: 177), // plus-minus sign = plus-or-minus sign, U+00B1 ISOnum - (Name: 'sup2'; Value: 178), // superscript two = superscript digit two = squared, U+00B2 ISOnum - (Name: 'sup3'; Value: 179), // superscript three = superscript digit three = cubed, U+00B3 ISOnum - (Name: 'acute'; Value: 180), // acute accent = spacing acute, U+00B4 ISOdia - (Name: 'micro'; Value: 181), // micro sign, U+00B5 ISOnum - (Name: 'para'; Value: 182), // pilcrow sign = paragraph sign, U+00B6 ISOnum - (Name: 'middot'; Value: 183), // middle dot = Georgian comma = Greek middle dot, U+00B7 ISOnum - (Name: 'cedil'; Value: 184), // cedilla = spacing cedilla, U+00B8 ISOdia - (Name: 'sup1'; Value: 185), // superscript one = superscript digit one, U+00B9 ISOnum - (Name: 'ordm'; Value: 186), // masculine ordinal indicator, U+00BA ISOnum - (Name: 'raquo'; Value: 187), // right-pointing double angle quotation mark = right pointing guillemet, U+00BB ISOnum - (Name: 'frac14'; Value: 188), // vulgar fraction one quarter = fraction one quarter, U+00BC ISOnum - (Name: 'frac12'; Value: 189), // vulgar fraction one half = fraction one half, U+00BD ISOnum - (Name: 'frac34'; Value: 190), // vulgar fraction three quarters = fraction three quarters, U+00BE ISOnum - (Name: 'iquest'; Value: 191), // inverted question mark = turned question mark, U+00BF ISOnum - (Name: 'Agrave'; Value: 192), // latin capital letter A with grave = latin capital letter A grave, U+00C0 ISOlat1 - (Name: 'Aacute'; Value: 193), // latin capital letter A with acute, U+00C1 ISOlat1 - (Name: 'Acirc'; Value: 194), // latin capital letter A with circumflex, U+00C2 ISOlat1 - (Name: 'Atilde'; Value: 195), // latin capital letter A with tilde, U+00C3 ISOlat1 - (Name: 'Auml'; Value: 196), // latin capital letter A with diaeresis, U+00C4 ISOlat1 - (Name: 'Aring'; Value: 197), // latin capital letter A with ring above = latin capital letter A ring, U+00C5 ISOlat1 - (Name: 'AElig'; Value: 198), // latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1 - (Name: 'Ccedil'; Value: 199), // latin capital letter C with cedilla, U+00C7 ISOlat1 - (Name: 'Egrave'; Value: 200), // latin capital letter E with grave, U+00C8 ISOlat1 - (Name: 'Eacute'; Value: 201), // latin capital letter E with acute, U+00C9 ISOlat1 - (Name: 'Ecirc'; Value: 202), // latin capital letter E with circumflex, U+00CA ISOlat1 - (Name: 'Euml'; Value: 203), // latin capital letter E with diaeresis, U+00CB ISOlat1 - (Name: 'Igrave'; Value: 204), // latin capital letter I with grave, U+00CC ISOlat1 - (Name: 'Iacute'; Value: 205), // latin capital letter I with acute, U+00CD ISOlat1 - (Name: 'Icirc'; Value: 206), // latin capital letter I with circumflex, U+00CE ISOlat1 - (Name: 'Iuml'; Value: 207), // latin capital letter I with diaeresis, U+00CF ISOlat1 - (Name: 'ETH'; Value: 208), // latin capital letter ETH, U+00D0 ISOlat1 - (Name: 'Ntilde'; Value: 209), // latin capital letter N with tilde, U+00D1 ISOlat1 - (Name: 'Ograve'; Value: 210), // latin capital letter O with grave, U+00D2 ISOlat1 - (Name: 'Oacute'; Value: 211), // latin capital letter O with acute, U+00D3 ISOlat1 - (Name: 'Ocirc'; Value: 212), // latin capital letter O with circumflex, U+00D4 ISOlat1 - (Name: 'Otilde'; Value: 213), // latin capital letter O with tilde, U+00D5 ISOlat1 - (Name: 'Ouml'; Value: 214), // latin capital letter O with diaeresis, U+00D6 ISOlat1 - (Name: 'times'; Value: 215), // multiplication sign, U+00D7 ISOnum - (Name: 'Oslash'; Value: 216), // latin capital letter O with stroke = latin capital letter O slash, U+00D8 ISOlat1 - (Name: 'Ugrave'; Value: 217), // latin capital letter U with grave, U+00D9 ISOlat1 - (Name: 'Uacute'; Value: 218), // latin capital letter U with acute, U+00DA ISOlat1 - (Name: 'Ucirc'; Value: 219), // latin capital letter U with circumflex, U+00DB ISOlat1 - (Name: 'Uuml'; Value: 220), // latin capital letter U with diaeresis, U+00DC ISOlat1 - (Name: 'Yacute'; Value: 221), // latin capital letter Y with acute, U+00DD ISOlat1 - (Name: 'THORN'; Value: 222), // latin capital letter THORN, U+00DE ISOlat1 - (Name: 'szlig'; Value: 223), // latin small letter sharp s = ess-zed, U+00DF ISOlat1 - (Name: 'agrave'; Value: 224), // latin small letter a with grave = latin small letter a grave, U+00E0 ISOlat1 - (Name: 'aacute'; Value: 225), // latin small letter a with acute, U+00E1 ISOlat1 - (Name: 'acirc'; Value: 226), // latin small letter a with circumflex, U+00E2 ISOlat1 - (Name: 'atilde'; Value: 227), // latin small letter a with tilde, U+00E3 ISOlat1 - (Name: 'auml'; Value: 228), // latin small letter a with diaeresis, U+00E4 ISOlat1 - (Name: 'aring'; Value: 229), // latin small letter a with ring above = latin small letter a ring, U+00E5 ISOlat1 - (Name: 'aelig'; Value: 230), // latin small letter ae = latin small ligature ae, U+00E6 ISOlat1 - (Name: 'ccedil'; Value: 231), // latin small letter c with cedilla, U+00E7 ISOlat1 - (Name: 'egrave'; Value: 232), // latin small letter e with grave, U+00E8 ISOlat1 - (Name: 'eacute'; Value: 233), // latin small letter e with acute, U+00E9 ISOlat1 - (Name: 'ecirc'; Value: 234), // latin small letter e with circumflex, U+00EA ISOlat1 - (Name: 'euml'; Value: 235), // latin small letter e with diaeresis, U+00EB ISOlat1 - (Name: 'igrave'; Value: 236), // latin small letter i with grave, U+00EC ISOlat1 - (Name: 'iacute'; Value: 237), // latin small letter i with acute, U+00ED ISOlat1 - (Name: 'icirc'; Value: 238), // latin small letter i with circumflex, U+00EE ISOlat1 - (Name: 'iuml'; Value: 239), // latin small letter i with diaeresis, U+00EF ISOlat1 - (Name: 'eth'; Value: 240), // latin small letter eth, U+00F0 ISOlat1 - (Name: 'ntilde'; Value: 241), // latin small letter n with tilde, U+00F1 ISOlat1 - (Name: 'ograve'; Value: 242), // latin small letter o with grave, U+00F2 ISOlat1 - (Name: 'oacute'; Value: 243), // latin small letter o with acute, U+00F3 ISOlat1 - (Name: 'ocirc'; Value: 244), // latin small letter o with circumflex, U+00F4 ISOlat1 - (Name: 'otilde'; Value: 245), // latin small letter o with tilde, U+00F5 ISOlat1 - (Name: 'ouml'; Value: 246), // latin small letter o with diaeresis, U+00F6 ISOlat1 - (Name: 'divide'; Value: 247), // division sign, U+00F7 ISOnum - (Name: 'oslash'; Value: 248), // latin small letter o with stroke, = latin small letter o slash, U+00F8 ISOlat1 - (Name: 'ugrave'; Value: 249), // latin small letter u with grave, U+00F9 ISOlat1 - (Name: 'uacute'; Value: 250), // latin small letter u with acute, U+00FA ISOlat1 - (Name: 'ucirc'; Value: 251), // latin small letter u with circumflex, U+00FB ISOlat1 - (Name: 'uuml'; Value: 252), // latin small letter u with diaeresis, U+00FC ISOlat1 - (Name: 'yacute'; Value: 253), // latin small letter y with acute, U+00FD ISOlat1 - (Name: 'thorn'; Value: 254), // latin small letter thorn, U+00FE ISOlat1 - (Name: 'yuml'; Value: 255), // latin small letter y with diaeresis, U+00FF ISOlat1 - - // symbols, mathematical symbols, and Greek letters - // Latin Extended-B - (Name: 'fnof'; Value: 402), // latin small f with hook = function = florin, U+0192 ISOtech - - // Greek - (Name: 'Alpha'; Value: 913), // greek capital letter alpha, U+0391 - (Name: 'Beta'; Value: 914), // greek capital letter beta, U+0392 - (Name: 'Gamma'; Value: 915), // greek capital letter gamma, U+0393 ISOgrk3 - (Name: 'Delta'; Value: 916), // greek capital letter delta, U+0394 ISOgrk3 - (Name: 'Epsilon'; Value: 917), // greek capital letter epsilon, U+0395 - (Name: 'Zeta'; Value: 918), // greek capital letter zeta, U+0396 - (Name: 'Eta'; Value: 919), // greek capital letter eta, U+0397 - (Name: 'Theta'; Value: 920), // greek capital letter theta, U+0398 ISOgrk3 - (Name: 'Iota'; Value: 921), // greek capital letter iota, U+0399 - (Name: 'Kappa'; Value: 922), // greek capital letter kappa, U+039A - (Name: 'Lambda'; Value: 923), // greek capital letter lambda, U+039B ISOgrk3 - (Name: 'Mu'; Value: 924), // greek capital letter mu, U+039C - (Name: 'Nu'; Value: 925), // greek capital letter nu, U+039D - (Name: 'Xi'; Value: 926), // greek capital letter xi, U+039E ISOgrk3 - (Name: 'Omicron'; Value: 927), // greek capital letter omicron, U+039F - (Name: 'Pi'; Value: 928), // greek capital letter pi, U+03A0 ISOgrk3 - (Name: 'Rho'; Value: 929), // greek capital letter rho, U+03A1 - (Name: 'Sigma'; Value: 931), // greek capital letter sigma, U+03A3 ISOgrk3, - // there is no Sigmaf, and no U+03A2 character either - (Name: 'Tau'; Value: 932), // greek capital letter tau, U+03A4 - (Name: 'Upsilon'; Value: 933), // greek capital letter upsilon, U+03A5 ISOgrk3 - (Name: 'Phi'; Value: 934), // greek capital letter phi, U+03A6 ISOgrk3 - (Name: 'Chi'; Value: 935), // greek capital letter chi, U+03A7 - (Name: 'Psi'; Value: 936), // greek capital letter psi, U+03A8 ISOgrk3 - (Name: 'Omega'; Value: 937), // greek capital letter omega, U+03A9 ISOgrk3 - (Name: 'alpha'; Value: 945), // greek small letter alpha, U+03B1 ISOgrk3 - (Name: 'beta'; Value: 946), // greek small letter beta, U+03B2 ISOgrk3 - (Name: 'gamma'; Value: 947), // greek small letter gamma, U+03B3 ISOgrk3 - (Name: 'delta'; Value: 948), // greek small letter delta, U+03B4 ISOgrk3 - (Name: 'epsilon'; Value: 949), // greek small letter epsilon, U+03B5 ISOgrk3 - (Name: 'zeta'; Value: 950), // greek small letter zeta, U+03B6 ISOgrk3 - (Name: 'eta'; Value: 951), // greek small letter eta, U+03B7 ISOgrk3 - (Name: 'theta'; Value: 952), // greek small letter theta, U+03B8 ISOgrk3 - (Name: 'iota'; Value: 953), // greek small letter iota, U+03B9 ISOgrk3 - (Name: 'kappa'; Value: 954), // greek small letter kappa, U+03BA ISOgrk3 - (Name: 'lambda'; Value: 955), // greek small letter lambda, U+03BB ISOgrk3 - (Name: 'mu'; Value: 956), // greek small letter mu, U+03BC ISOgrk3 - (Name: 'nu'; Value: 957), // greek small letter nu, U+03BD ISOgrk3 - (Name: 'xi'; Value: 958), // greek small letter xi, U+03BE ISOgrk3 - (Name: 'omicron'; Value: 959), // greek small letter omicron, U+03BF NEW - (Name: 'pi'; Value: 960), // greek small letter pi, U+03C0 ISOgrk3 - (Name: 'rho'; Value: 961), // greek small letter rho, U+03C1 ISOgrk3 - (Name: 'sigmaf'; Value: 962), // greek small letter final sigma, U+03C2 ISOgrk3 - (Name: 'sigma'; Value: 963), // greek small letter sigma, U+03C3 ISOgrk3 - (Name: 'tau'; Value: 964), // greek small letter tau, U+03C4 ISOgrk3 - (Name: 'upsilon'; Value: 965), // greek small letter upsilon, U+03C5 ISOgrk3 - (Name: 'phi'; Value: 966), // greek small letter phi, U+03C6 ISOgrk3 - (Name: 'chi'; Value: 967), // greek small letter chi, U+03C7 ISOgrk3 - (Name: 'psi'; Value: 968), // greek small letter psi, U+03C8 ISOgrk3 - (Name: 'omega'; Value: 969), // greek small letter omega, U+03C9 ISOgrk3 - (Name: 'thetasym'; Value: 977), // greek small letter theta symbol, U+03D1 NEW - (Name: 'upsih'; Value: 978), // greek upsilon with hook symbol, U+03D2 NEW - (Name: 'piv'; Value: 982), // greek pi symbol, U+03D6 ISOgrk3 - // General Punctuation - (Name: 'apos'; Value: 8217), // curly apostrophe, - (Name: 'bull'; Value: 8226), // bullet = black small circle, U+2022 ISOpub, - // bullet is NOT the same as bullet operator, U+2219 - (Name: 'hellip'; Value: 8230), // horizontal ellipsis = three dot leader, U+2026 ISOpub - (Name: 'prime'; Value: 8242), // prime = minutes = feet, U+2032 ISOtech - (Name: 'Prime'; Value: 8243), // double prime = seconds = inches, U+2033 ISOtech - (Name: 'oline'; Value: 8254), // overline = spacing overscore, U+203E NEW - (Name: 'frasl'; Value: 8260), // fraction slash, U+2044 NEW - // Letterlike Symbols - (Name: 'weierp'; Value: 8472), // script capital P = power set = Weierstrass p, U+2118 ISOamso - (Name: 'image'; Value: 8465), // blackletter capital I = imaginary part, U+2111 ISOamso - (Name: 'real'; Value: 8476), // blackletter capital R = real part symbol, U+211C ISOamso - (Name: 'trade'; Value: 8482), // trade mark sign, U+2122 ISOnum - (Name: 'alefsym'; Value: 8501), // alef symbol = first transfinite cardinal, U+2135 NEW - // alef symbol is NOT the same as hebrew letter alef, U+05D0 although the same - // glyph could be used to depict both characters - // Arrows - (Name: 'larr'; Value: 8592), // leftwards arrow, U+2190 ISOnum - (Name: 'uarr'; Value: 8593), // upwards arrow, U+2191 ISOnu - (Name: 'rarr'; Value: 8594), // rightwards arrow, U+2192 ISOnum - (Name: 'darr'; Value: 8595), // downwards arrow, U+2193 ISOnum - (Name: 'harr'; Value: 8596), // left right arrow, U+2194 ISOamsa - (Name: 'crarr'; Value: 8629), // downwards arrow with corner leftwards = carriage return, U+21B5 NEW - (Name: 'lArr'; Value: 8656), // leftwards double arrow, U+21D0 ISOtech - // ISO 10646 does not say that lArr is the same as the 'is implied by' arrow but - // also does not have any other charater for that function. So ? lArr can be used - // for 'is implied by' as ISOtech sugg - (Name: 'uArr'; Value: 8657), // upwards double arrow, U+21D1 ISOamsa - (Name: 'rArr'; Value: 8658), // rightwards double arrow, U+21D2 ISOtech - // ISO 10646 does not say this is the 'implies' character but does not have another - // character with this function so ? rArr can be used for 'implies' as ISOtech suggests - (Name: 'dArr'; Value: 8659), // downwards double arrow, U+21D3 ISOamsa - (Name: 'hArr'; Value: 8660), // left right double arrow, U+21D4 ISOamsa - // Mathematical Operators - (Name: 'forall'; Value: 8704), // for all, U+2200 ISOtech - (Name: 'part'; Value: 8706), // partial differential, U+2202 ISOtech - (Name: 'exist'; Value: 8707), // there exists, U+2203 ISOtech - (Name: 'empty'; Value: 8709), // empty set = null set = diameter, U+2205 ISOamso - (Name: 'nabla'; Value: 8711), // nabla = backward difference, U+2207 ISOtech - (Name: 'isin'; Value: 8712), // element of, U+2208 ISOtech - (Name: 'notin'; Value: 8713), // not an element of, U+2209 ISOtech - (Name: 'ni'; Value: 8715), // contains as member, U+220B ISOtech - (Name: 'prod'; Value: 8719), // n-ary product = product sign, U+220F ISOamsb - // prod is NOT the same character as U+03A0 'greek capital letter pi' though the - // same glyph might be used for both - (Name: 'sum'; Value: 8721), // n-ary sumation, U+2211 ISOamsb - // sum is NOT the same character as U+03A3 'greek capital letter sigma' though the - // same glyph might be used for both - (Name: 'minus'; Value: 8722), // minus sign, U+2212 ISOtech - (Name: 'lowast'; Value: 8727), // asterisk operator, U+2217 ISOtech - (Name: 'radic'; Value: 8730), // square root = radical sign, U+221A ISOtech - (Name: 'prop'; Value: 8733), // proportional to, U+221D ISOtech - (Name: 'infin'; Value: 8734), // infinity, U+221E ISOtech - (Name: 'ang'; Value: 8736), // angle, U+2220 ISOamso - (Name: 'and'; Value: 8743), // logical and = wedge, U+2227 ISOtech - (Name: 'or'; Value: 8744), // logical or = vee, U+2228 ISOtech - (Name: 'cap'; Value: 8745), // intersection = cap, U+2229 ISOtech - (Name: 'cup'; Value: 8746), // union = cup, U+222A ISOtech - (Name: 'int'; Value: 8747), // integral, U+222B ISOtech - (Name: 'there4'; Value: 8756), // therefore, U+2234 ISOtech - (Name: 'sim'; Value: 8764), // tilde operator = varies with = similar to, U+223C ISOtech - // tilde operator is NOT the same character as the tilde, U+007E, although the same - // glyph might be used to represent both - (Name: 'cong'; Value: 8773), // approximately equal to, U+2245 ISOtech - (Name: 'asymp'; Value: 8776), // almost equal to = asymptotic to, U+2248 ISOamsr - (Name: 'ne'; Value: 8800), // not equal to, U+2260 ISOtech - (Name: 'equiv'; Value: 8801), // identical to, U+2261 ISOtech - (Name: 'le'; Value: 8804), // less-than or equal to, U+2264 ISOtech - (Name: 'ge'; Value: 8805), // greater-than or equal to, U+2265 ISOtech - (Name: 'sub'; Value: 8834), // subset of, U+2282 ISOtech - (Name: 'sup'; Value: 8835), // superset of, U+2283 ISOtech - // note that nsup, 'not a superset of, U+2283' is not covered by the Symbol font - // encoding and is not included. - (Name: 'nsub'; Value: 8836), // not a subset of, U+2284 ISOamsn - (Name: 'sube'; Value: 8838), // subset of or equal to, U+2286 ISOtech - (Name: 'supe'; Value: 8839), // superset of or equal to, U+2287 ISOtech - (Name: 'oplus'; Value: 8853), // circled plus = direct sum, U+2295 ISOamsb - (Name: 'otimes'; Value: 8855), // circled times = vector product, U+2297 ISOamsb - (Name: 'perp'; Value: 8869), // up tack = orthogonal to = perpendicular, U+22A5 ISOtech - (Name: 'sdot'; Value: 8901), // dot operator, U+22C5 ISOamsb - // dot operator is NOT the same character as U+00B7 middle dot - // Miscellaneous Technical - (Name: 'lceil'; Value: 8968), // left ceiling = apl upstile, U+2308 ISOamsc - (Name: 'rceil'; Value: 8969), // right ceiling, U+2309 ISOamsc - (Name: 'lfloor'; Value: 8970), // left floor = apl downstile, U+230A ISOamsc - (Name: 'rfloor'; Value: 8971), // right floor, U+230B ISOamsc - (Name: 'lang'; Value: 9001), // left-pointing angle bracket = bra, U+2329 ISOtech - // lang is NOT the same character as U+003C 'less than' or U+2039 'single - // left-pointing angle quotation mark' - (Name: 'rang'; Value: 9002), // right-pointing angle bracket = ket, U+232A ISOtech - // rang is NOT the same character as U+003E 'greater than' or U+203A 'single - // right-pointing angle quotation mark' - // Geometric Shapes - (Name: 'loz'; Value: 9674), // lozenge, U+25CA ISOpub - // Miscellaneous Symbols - (Name: 'spades'; Value: 9824), // black spade suit, U+2660 ISOpub - // black here seems to mean filled as opposed to hollow - (Name: 'clubs'; Value: 9827), // black club suit = shamrock, U+2663 ISOpub - (Name: 'hearts'; Value: 9829), // black heart suit = valentine, U+2665 ISOpub - (Name: 'diams'; Value: 9830), // black diamond suit, U+2666 ISOpub - - // markup-significant and internationalization characters - // C0 Controls and Basic Latin - (Name: 'quot'; Value: 34), // quotation mark = APL quote, U+0022 ISOnum - (Name: 'amp'; Value: 38), // ampersand, U+0026 ISOnum - (Name: 'lt'; Value: 60), // less-than sign, U+003C ISOnum - (Name: 'gt'; Value: 62), // greater-than sign, U+003E ISOnum - // Latin Extended-A - (Name: 'OElig'; Value: 338), // latin capital ligature OE, U+0152 ISOlat2 - (Name: 'oelig'; Value: 339), // latin small ligature oe, U+0153 ISOlat2 - // ligature is a misnomer, this is a separate character in some languages - (Name: 'Scaron'; Value: 352), // latin capital letter S with caron, U+0160 ISOlat2 - (Name: 'scaron'; Value: 353), // latin small letter s with caron, U+0161 ISOlat2 - (Name: 'Yuml'; Value: 376), // latin capital letter Y with diaeresis, U+0178 ISOlat2 - // Spacing Modifier Letters - (Name: 'circ'; Value: 710), // modifier letter circumflex accent, U+02C6 ISOpub - (Name: 'tilde'; Value: 732), // small tilde, U+02DC ISOdia - // General Punctuation - (Name: 'ensp'; Value: 8194), // en space, U+2002 ISOpub - (Name: 'emsp'; Value: 8195), // em space, U+2003 ISOpub - (Name: 'thinsp'; Value: 8201), // thin space, U+2009 ISOpub - (Name: 'zwnj'; Value: 8204), // zero width non-joiner, U+200C NEW RFC 2070 - (Name: 'zwj'; Value: 8205), // zero width joiner, U+200D NEW RFC 2070 - (Name: 'lrm'; Value: 8206), // left-to-right mark, U+200E NEW RFC 2070 - (Name: 'rlm'; Value: 8207), // right-to-left mark, U+200F NEW RFC 2070 - (Name: 'ndash'; Value: 8211), // en dash, U+2013 ISOpub - (Name: 'mdash'; Value: 8212), // em dash, U+2014 ISOpub - (Name: 'lsquo'; Value: 8216), // left single quotation mark, U+2018 ISOnum - (Name: 'rsquo'; Value: 8217), // right single quotation mark, U+2019 ISOnum - (Name: 'sbquo'; Value: 8218), // single low-9 quotation mark, U+201A NEW - (Name: 'ldquo'; Value: 8220), // left double quotation mark, U+201C ISOnum - (Name: 'rdquo'; Value: 8221), // right double quotation mark, U+201D ISOnum - (Name: 'bdquo'; Value: 8222), // double low-9 quotation mark, U+201E NEW - (Name: 'dagger'; Value: 8224), // dagger, U+2020 ISOpub - (Name: 'Dagger'; Value: 8225), // double dagger, U+2021 ISOpub - (Name: 'permil'; Value: 8240), // per mille sign, U+2030 ISOtech - (Name: 'lsaquo'; Value: 8249), // single left-pointing angle quotation mark, U+2039 ISO proposed - // lsaquo is proposed but not yet ISO standardized - (Name: 'rsaquo'; Value: 8250), // single right-pointing angle quotation mark, U+203A ISO proposed - // rsaquo is proposed but not yet ISO standardized - (Name: 'euro'; Value: 8364)); // euro sign, U+20AC NEW -var - I: Integer; -begin - // Put the Entities into a sorted StringList for faster access. - if Entities = nil then - begin - Entities := ThtStringList.Create; - Entities.CaseSensitive := True; - for I := low(EntityDefinitions) to high(EntityDefinitions) do - Entities.AddObject(EntityDefinitions[I].Name, @EntityDefinitions[I]); - Entities.Sort; - end; -end; - - -procedure InitElements; -const - ElementDefinitions: array[1..104] of TResWord = ( - (Name: '?XML'; Symbol: XmlSy; EndSym: CommandSy), - (Name: '!DOCTYPE'; Symbol: DocTypeSy; EndSym: CommandSy), - {HTML} - (Name: 'HTML'; Symbol: HtmlSy; EndSym: HtmlEndSy), - (Name: 'TITLE'; Symbol: TitleElemSy; EndSym: TitleEndSy), - (Name: 'BODY'; Symbol: BodySy; EndSym: BodyEndSy), - (Name: 'HEAD'; Symbol: HeadSy; EndSym: HeadEndSy), - (Name: 'B'; Symbol: BSy; EndSym: BEndSy), - (Name: 'I'; Symbol: ISy; EndSym: IEndSy), - (Name: 'H1'; Symbol: H1Sy; EndSym: H1EndSy), - (Name: 'H2'; Symbol: H2Sy; EndSym: H2EndSy), - (Name: 'H3'; Symbol: H3Sy; EndSym: H3EndSy), - (Name: 'H4'; Symbol: H4Sy; EndSym: H4EndSy), - (Name: 'H5'; Symbol: H5Sy; EndSym: H5EndSy), - (Name: 'H6'; Symbol: H6Sy; EndSym: H6EndSy), - (Name: 'EM'; Symbol: EmSy; EndSym: EmEndSy), - (Name: 'STRONG'; Symbol: StrongSy; EndSym: StrongEndSy), - (Name: 'U'; Symbol: USy; EndSym: UEndSy), - // - (Name: 'INS'; Symbol: InsSy; EndSym: InsEndSy), - (Name: 'DEL'; Symbol: DelSy; EndSym: DelEndSy), - // - (Name: 'CITE'; Symbol: CiteSy; EndSym: CiteEndSy), - (Name: 'VAR'; Symbol: VarSy; EndSym: VarEndSy), - (Name: 'ABBR'; Symbol: AbbrSy; EndSym: AbbrEndSy), - (Name: 'ACRONYM'; Symbol: AcronymSy; EndSym: AcronymEndSy), - (Name: 'DFN'; Symbol: DfnSy; EndSym: DfnEndSy), - - (Name: 'TT'; Symbol: TTSy; EndSym: TTEndSy), - (Name: 'CODE'; Symbol: CodeSy; EndSym: CodeEndSy), - (Name: 'KBD'; Symbol: KbdSy; EndSym: KbdEndSy), - (Name: 'SAMP'; Symbol: SampSy; EndSym: SampEndSy), - (Name: 'OL'; Symbol: OLSy; EndSym: OLEndSy), - (Name: 'UL'; Symbol: ULSy; EndSym: ULEndSy), - (Name: 'DIR'; Symbol: DirSy; EndSym: DirEndSy), - (Name: 'MENU'; Symbol: MenuSy; EndSym: MenuEndSy), - (Name: 'DL'; Symbol: DLSy; EndSym: DLEndSy), - (Name: 'A'; Symbol: ASy; EndSym: AEndSy), - (Name: 'ADDRESS'; Symbol: AddressSy; EndSym: AddressEndSy), - (Name: 'BLOCKQUOTE'; Symbol: BlockQuoteSy; EndSym: BlockQuoteEndSy), - (Name: 'PRE'; Symbol: PreSy; EndSym: PreEndSy), - (Name: 'CENTER'; Symbol: CenterSy; EndSym: CenterEndSy), - (Name: 'TABLE'; Symbol: TableSy; EndSym: TableEndSy), - (Name: 'TD'; Symbol: TDsy; EndSym: TDEndSy), - (Name: 'TH'; Symbol: THSy; EndSym: THEndSy), - (Name: 'CAPTION'; Symbol: CaptionSy; EndSym: CaptionEndSy), - (Name: 'FORM'; Symbol: FormSy; EndSym: FormEndSy), - (Name: 'TEXTAREA'; Symbol: TextAreaSy; EndSym: TextAreaEndSy), - (Name: 'SELECT'; Symbol: SelectSy; EndSym: SelectEndSy), - (Name: 'OPTION'; Symbol: OptionSy; EndSym: OptionEndSy), - (Name: 'FONT'; Symbol: FontSy; EndSym: FontEndSy), - (Name: 'SUB'; Symbol: SubSy; EndSym: SubEndSy), - (Name: 'SUP'; Symbol: SupSy; EndSym: SupEndSy), - (Name: 'BIG'; Symbol: BigSy; EndSym: BigEndSy), - (Name: 'SMALL'; Symbol: SmallSy; EndSym: SmallEndSy), - (Name: 'P'; Symbol: PSy; EndSym: PEndSy), - (Name: 'MAP'; Symbol: MapSy; EndSym: MapEndSy), - (Name: 'FRAMESET'; Symbol: FrameSetSy; EndSym: FrameSetEndSy), - (Name: 'NOFRAMES'; Symbol: NoFramesSy; EndSym: NoFramesEndSy), - (Name: 'SCRIPT'; Symbol: ScriptSy; EndSym: ScriptEndSy), - (Name: 'DIV'; Symbol: DivSy; EndSym: DivEndSy), - (Name: 'S'; Symbol: SSy; EndSym: SEndSy), - (Name: 'STRIKE'; Symbol: StrikeSy; EndSym: StrikeEndSy), - (Name: 'TR'; Symbol: TRSy; EndSym: TREndSy), - (Name: 'NOBR'; Symbol: NoBrSy; EndSym: NoBrEndSy), - (Name: 'STYLE'; Symbol: StyleSy; EndSym: StyleEndSy), - (Name: 'SPAN'; Symbol: SpanSy; EndSym: SpanEndSy), - (Name: 'COLGROUP'; Symbol: ColGroupSy; EndSym: ColGroupEndSy), - (Name: 'LABEL'; Symbol: LabelSy; EndSym: LabelEndSy), - (Name: 'THEAD'; Symbol: THeadSy; EndSym: THeadEndSy), - (Name: 'TBODY'; Symbol: TBodySy; EndSym: TBodyEndSy), - (Name: 'TFOOT'; Symbol: TFootSy; EndSym: TFootEndSy), - (Name: 'OBJECT'; Symbol: ObjectSy; EndSym: ObjectEndSy), - (Name: 'DD'; Symbol: DDSy; EndSym: DDEndSy), - (Name: 'DT'; Symbol: DTSy; EndSym: DTEndSy), - (Name: 'LI'; Symbol: LISy; EndSym: LIEndSy), - (Name: 'FIELDSET'; Symbol: FieldsetSy; EndSym: FieldsetEndSy), - (Name: 'LEGEND'; Symbol: LegendSy; EndSym: LegendEndSy), - (Name: 'BR'; Symbol: BRSy; EndSym: CommandSy), - (Name: 'HR'; Symbol: HRSy; EndSym: CommandSy), - (Name: 'IMG'; Symbol: ImageSy; EndSym: CommandSy), - (Name: 'IFRAME'; Symbol: IFrameSy; EndSym: IFrameEndSy), - (Name: 'BASE'; Symbol: BaseSy; EndSym: CommandSy), - (Name: 'BUTTON'; Symbol: ButtonSy; EndSym: ButtonEndSy), - (Name: 'INPUT'; Symbol: InputSy; EndSym: CommandSy), - (Name: 'BASEFONT'; Symbol: BaseFontSy; EndSym: CommandSy), - (Name: 'AREA'; Symbol: AreaSy; EndSym: CommandSy), - (Name: 'FRAME'; Symbol: FrameSy; EndSym: CommandSy), - (Name: 'PAGE'; Symbol: PageSy; EndSym: CommandSy), - (Name: 'BGSOUND'; Symbol: BgSoundSy; EndSym: CommandSy), - (Name: 'META'; Symbol: MetaSy; EndSym: CommandSy), - (Name: 'PANEL'; Symbol: PanelSy; EndSym: CommandSy), - (Name: 'WBR'; Symbol: WbrSy; EndSym: CommandSy), - (Name: 'LINK'; Symbol: LinkElemSy; EndSym: CommandSy), - (Name: 'COL'; Symbol: ColSy; EndSym: CommandSy), - (Name: 'PARAM'; Symbol: ParamSy; EndSym: CommandSy), - {HTML5 } - (Name: 'MAIN'; Symbol: MainSy; EndSym: MainEndSy), - (Name: 'HEADER'; Symbol: HeaderSy; EndSym: HeaderEndSy), - (Name: 'SECTION'; Symbol: SectionSy; EndSym: SectionEndSy), - (Name: 'NAV'; Symbol: NavSy; EndSym: NavEndSy), - (Name: 'ARTICLE'; Symbol: ArticleSy; EndSym: ArticleEndSy), - (Name: 'ASIDE'; Symbol: AsideSy; EndSym: AsideEndSy), - (Name: 'FOOTER'; Symbol: FooterSy; EndSym: FooterEndSy), - (Name: 'HGROUP'; Symbol: HGroupSy; EndSym: HGroupEndSy), - (Name: 'MARK'; Symbol: MarkSy; EndSym: MarkEndSy), - (Name: 'TIME'; Symbol: TimeSy; EndSym: TimeEndSy), - (Name: 'PROGRESS'; Symbol: ProgressSy; EndSym: ProgressEndSy), - (Name: 'METER'; Symbol: MeterSy; EndSym: MeterEndSy)); -var - I: Integer; - P: PResWord; - S: TElemSymb; -begin - // Put the Attributes into a sorted StringList for faster access. - if ElementNames = nil then - begin - ElementNames := ThtStringList.Create; - ElementNames.CaseSensitive := True; - for I := low(ElementDefinitions) to high(ElementDefinitions) do - ElementNames.AddObject(ElementDefinitions[I].Name, @ElementDefinitions[I]); - ElementNames.Sort; - - // initialize ElementNamesIndex and ElemSymbolNames - for S := low(TElemSymb) to high(TElemSymb) do - ElementNamesIndex[S] := -1; - for I := 0 to ElementNames.Count - 1 do - begin - P := PResWord(ElementNames.Objects[I]); - ElementNamesIndex[P.Symbol] := I; - SetSymbolName(P.Symbol, P.Name); - if P.EndSym <> CommandSy then - begin - ElementNamesIndex[P.EndSym] := I; - SetSymbolName(P.EndSym, P.Name); - end; - end; - end; -end; - - -procedure InitAttributes; -const - AttribDefinitions: array[1..95] of TSymbolRec = ( - (Name: 'ACTION'; Value: ActionSy), - (Name: 'ACTIVE'; Value: ActiveSy), - (Name: 'ALIGN'; Value: AlignSy), - (Name: 'ALT'; Value: AltSy), - (Name: 'BACKGROUND'; Value: BackgroundSy), - (Name: 'BGCOLOR'; Value: BGColorSy), - (Name: 'BGPROPERTIES'; Value: BGPropertiesSy), - (Name: 'BORDER'; Value: BorderSy), - (Name: 'BORDERCOLOR'; Value: BorderColorSy), - (Name: 'BORDERCOLORDARK'; Value: BorderColorDarkSy), - (Name: 'BORDERCOLORLIGHT'; Value: BorderColorLightSy), - (Name: 'CELLPADDING'; Value: CellPaddingSy), - (Name: 'CELLSPACING'; Value: CellSpacingSy), - (Name: 'CHARSET'; Value: CharSetSy), - (Name: 'CHECKBOX'; Value: CheckBoxSy), - (Name: 'CHECKED'; Value: CheckedSy), - (Name: 'CLASS'; Value: ClassSy), - (Name: 'CLEAR'; Value: ClearSy), - (Name: 'COLOR'; Value: ColorSy), - (Name: 'COLS'; Value: ColsSy), - (Name: 'COLSPAN'; Value: ColSpanSy), - (Name: 'CONTENT'; Value: ContentSy), - (Name: 'COORDS'; Value: CoordsSy), - (Name: 'DISABLED'; Value: DisabledSy), - (Name: 'ENCODING'; Value: EncodingSy), - (Name: 'ENCTYPE'; Value: EncTypeSy), - (Name: 'FACE'; Value: FaceSy), - (Name: 'FRAME'; Value: FrameAttrSy), - (Name: 'FRAMEBORDER'; Value: FrameBorderSy), - (Name: 'HEIGHT'; Value: HeightSy), - (Name: 'HIGH'; Value: HighSy), - (Name: 'HREF'; Value: HrefSy), - (Name: 'HSPACE'; Value: HSpaceSy), - (Name: 'HTTP-EQUIV'; Value: HttpEqSy), - (Name: 'ID'; Value: IDSy), - (Name: 'ISMAP'; Value: IsMapSy), - (Name: 'LABEL'; Value: LabelAttrSy), - (Name: 'LANGUAGE'; Value: LanguageSy), - (Name: 'LEFTMARGIN'; Value: LeftMarginSy), - (Name: 'LINK'; Value: LinkSy), - (Name: 'LOOP'; Value: LoopSy), - (Name: 'LOW'; Value: LowSy), - (Name: 'MARGINHEIGHT'; Value: MarginHeightSy), - (Name: 'MARGINWIDTH'; Value: MarginWidthSy), - (Name: 'MAX'; Value: MaxSy), - (Name: 'MAXLENGTH'; Value: MaxLengthSy), - (Name: 'MEDIA'; Value: MediaSy), - (Name: 'METHOD'; Value: MethodSy), - (Name: 'MIN'; Value: MinSy), - (Name: 'MULTIPLE'; Value: MultipleSy), - (Name: 'NAME'; Value: NameSy), - (Name: 'NOHREF'; Value: NoHrefSy), - (Name: 'NORESIZE'; Value: NoResizeSy), - (Name: 'NOSHADE'; Value: NoShadeSy), - (Name: 'NOWRAP'; Value: NoWrapSy), - (Name: 'OLINK'; Value: OLinkSy), - (Name: 'ONBLUR'; Value: OnBlurSy), - (Name: 'ONCHANGE'; Value: OnChangeSy), - (Name: 'ONCLICK'; Value: OnClickSy), - (Name: 'ONFOCUS'; Value: OnFocusSy), - (Name: 'OPTIMUM'; Value: OptimumSy), - (Name: 'PLACEHOLDER'; Value: PlaceholderSy), - (Name: 'PLAIN'; Value: PlainSy), - (Name: 'RADIO'; Value: RadioSy), - (Name: 'RATIO'; Value: RatioSy), - (Name: 'READONLY'; Value: ReadonlySy), - (Name: 'REL'; Value: RelSy), - (Name: 'REV'; Value: RevSy), - (Name: 'ROWS'; Value: RowsSy), - (Name: 'ROWSPAN'; Value: RowSpanSy), - (Name: 'RULES'; Value: RulesSy), - (Name: 'SCROLLING'; Value: ScrollingSy), - (Name: 'SELECTED'; Value: SelectedSy), - (Name: 'SHAPE'; Value: ShapeSy), - (Name: 'SIZE'; Value: SizeSy), - (Name: 'SPAN'; Value: SpanAttrSy), - (Name: 'SPELLCHECK'; Value: spellcheckSy), - (Name: 'SRC'; Value: SrcSy), - (Name: 'START'; Value: StartSy), - (Name: 'STYLE'; Value: StyleAttrSy), - (Name: 'TABINDEX'; Value: TabIndexSy), - (Name: 'TARGET'; Value: TargetSy), - (Name: 'TEXT'; Value: TextSy), - (Name: 'TITLE'; Value: TitleSy), - (Name: 'TOPMARGIN'; Value: TopMarginSy), - (Name: 'TRANSP'; Value: TranspSy), - (Name: 'TYPE'; Value: TypeSy), - (Name: 'USEMAP'; Value: UseMapSy), - (Name: 'VALIGN'; Value: VAlignSy), - (Name: 'VALUE'; Value: ValueSy), - (Name: 'VERSION'; Value: VersionSy), - (Name: 'VLINK'; Value: VLinkSy), - (Name: 'VSPACE'; Value: VSpaceSy), - (Name: 'WIDTH'; Value: WidthSy), - (Name: 'WRAP'; Value: WrapSy)); -var - I: Integer; - P: PSymbol; -begin - // Put the Attributes into a sorted StringList for faster access. - if AttributeNames = nil then - begin - AttributeNames := ThtStringList.Create; - AttributeNames.CaseSensitive := True; - for I := low(AttribDefinitions) to high(AttribDefinitions) do - begin - P := @AttribDefinitions[I]; - AttributeNames.AddObject(P.Name, Pointer(P)); - SetSymbolName(P.Value, P.Name); - end; - AttributeNames.Sort; - end; -end; - -initialization - InitEntities; - InitAttributes; - InitElements; -finalization - Entities.Free; - AttributeNames.Free; - ElementNames.Free; -end. diff --git a/CORE/Source/Plugins/Htmlviewer/source/Htmlsbs1.pas b/CORE/Source/Plugins/Htmlviewer/source/Htmlsbs1.pas deleted file mode 100644 index b842d6935..000000000 --- a/CORE/Source/Plugins/Htmlviewer/source/Htmlsbs1.pas +++ /dev/null @@ -1,1728 +0,0 @@ -{ -Version 11.7 -Copyright (c) 1995-2008 by L. David Baldwin, -Copyright (c) 2008-2016 by HtmlViewer Team - -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. - -Note that the source modules HTMLGIF1.PAS and DITHERUNIT.PAS -are covered by separate copyright notices located in those modules. -} - -{$I htmlcons.inc} - -unit Htmlsbs1; - -interface - -uses -{$ifdef VCL} - Windows, -{$endif} - Messages, -{$ifdef LCL} - LclIntf, LclType, Types, LclProc, HtmlMisc, -{$endif} -{$ifdef scrollbarInClasses} - System.Classes, -{$else} - Classes, -{$endif} - vcl.Graphics, vcl.Controls, - // - HtmlGlobals, - HtmlImages, - HtmlFonts, - HtmlSymb, - HTMLUn2, - HTMLSubs, - StyleTypes, - StyleUn; - -type - TTypedFormControlObj = class(TFormControlObj) - protected - FInputType : THtString; - public - constructor Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties); override; - constructor CreateCopy(Parent: TCellBasic; Source: THtmlNode); override; - property InputType : THtString read FInputType; - end; - - THiddenFormControlObj = class(TFormControlObj) - protected - function GetControl: TWinControl; override; - function GetClientHeight: Integer; override; - function GetClientLeft: Integer; override; - function GetTabOrder: Integer; override; - function GetTabStop: Boolean; override; - function GetClientTop: Integer; override; - function GetClientWidth: Integer; override; - function IsHidden: Boolean; override; - procedure SetClientHeight(Value: Integer); override; - procedure SetClientLeft(Value: Integer); override; - procedure SetTabOrder(Value: Integer); override; - procedure SetTabStop(Value: Boolean); override; - procedure SetClientTop(Value: Integer); override; - procedure SetClientWidth(Value: Integer); override; - public - function GetSubmission(Index: Integer; out S: ThtString): Boolean; override; - procedure Hide; override; - procedure SetData(Index: Integer; const V: ThtString); override; - procedure Show; override; - end; - - TEditBaseFormControlObj = class(TTypedFormControlObj) - protected - FPlaceholder : ThtString; - FSpellCheck : Boolean; - FMaxLength : Integer; - public - constructor Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties); override; - constructor CreateCopy(Parent: TCellBasic; Source: THtmlNode); override; - property Placeholder : ThtString read FPlaceholder; - property SpellCheck : Boolean read FSpellCheck; - property MaxLength : Integer read FMaxLength; - end; - - TEditFormControlObj = class(TEditBaseFormControlObj) - private - FControl: ThtEdit; - EnterContents: ThtString; - tmAveCharWidth: Integer; - - function getText: ThtString; - procedure setText(const Value: ThtString); - protected - function GetControl: TWinControl; override; - procedure DoOnChange; override; - procedure SaveContents; override; - public - EditSize: Integer; - constructor Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties); override; - constructor CreateCopy(Parent: TCellBasic; Source: THtmlNode); override; - destructor Destroy; override; - function GetSubmission(Index: Integer; out S: ThtString): Boolean; override; - procedure DrawInline1(Canvas: TCanvas; X1, Y1: Integer); override; - procedure ProcessProperties(Prop: TProperties); override; - procedure ResetToValue; override; - procedure SetData(Index: Integer; const V: ThtString); override; - procedure SetHeightWidth(Canvas: TCanvas); override; - property Text: ThtString read getText write setText; - end; - - TWhichType = (Submit, ResetB, Button, Browse); - - TButtonFormControlObj = class(TTypedFormControlObj) - private - FControl: ThtButton; - protected - function GetControl: TWinControl; override; - public - Which: TWhichType; - MyEdit: TEditFormControlObj; - constructor Create(Parent: TCellBasic; Position: Integer; L: TAttributeList; Prop: TProperties); override; - constructor CreateCopy(Parent: TCellBasic; Source: THtmlNode); override; - destructor Destroy; override; - procedure ButtonClick(Sender: TObject); - procedure DrawInline1(Canvas: TCanvas; X1, Y1: Integer); override; - procedure SetHeightWidth(Canvas: TCanvas); override; - end; - - TOptionObj = class(TObject) {used by TListBoxFormControlObj for

    <body> attributes

+ /// Gets the name of the new window. This window can be created via `window.open(url, windowName)`, + /// where the windowName parameter corresponds to `Name` property. + /// If no windowName is passed to `window.open`, then the `Name` property + /// will be set to an empty string. Additionally, if window is opened through other means, + /// such as `...` or ``, + /// then the `Name` property will be set accordingly. In the case of target=_blank, + /// the `Name` property will be an empty string. + /// Opening a window via ctrl+clicking a link would result in the `Name` property + /// being set to an empty string. + ///